diff --git a/docs/calibration-20260912-checkpoint.md b/docs/calibration-20260912-checkpoint.md new file mode 100644 index 00000000..b0808f47 --- /dev/null +++ b/docs/calibration-20260912-checkpoint.md @@ -0,0 +1,70 @@ +# PG10—PG20 中文文档校准阶段总结(2026-09-12) + +这是正文修复检查点,全文校准与最终构建验收仍在进行。 + +## 输入与本次提交范围 + +- 工作区:`/Users/vonng/pgsty/pgdoc`。 +- 本轮起始基线:`738d5dea66ae054ba58610c1d95f1a85272bda3f`。 +- 本次提交父版本:`4c1790ccecfd9531b0705ff7b189003b595d54ff`;更早的校准成果已由既有的逐版检查点提交保存。 +- 英文固定为 10.23、11.22、12.22、13.23、14.24、15.19、16.15、17.11、18.6、19beta3;PG20 固定提交 `86f7c82cf1023e3599f40f939727791a7090cd44`,未升级输入。 +- 本次新增提交正文:**142 files changed, 3910 insertions(+), 4230 deletions(-)**;另附本阶段总结。 +- 相对于本轮起始基线,累计 3157 个中文源文件有变化;这个数字包括此前已提交成果,不是本次提交文件数。 + +| 版本 | 本次正文文件数 | +|---|---:| +| PG10 | 11 | +| PG11 | 11 | +| PG12 | 11 | +| PG13 | 11 | +| PG14 | 12 | +| PG15 | 12 | +| PG16 | 12 | +| PG17 | 12 | +| PG18 | 12 | +| PG19 | 19 | +| PG20 | 19 | + +## 已完成的修复 + +此前检查点已保存聚合与 JSON 表格、目录与统计、libpq、复制与备份、索引访问方法、并发控制、过程语言、SPI、扩展接口及相关参考页的分批修复。具体审核粒度见运行目录台账,不能据此推断这些大主题下每一章均已完成全文审阅。 + +本次 142 个正文文件主要包含: + +- WAL 配置:恢复 PG15 被缩短的完整定义与示例,修复刷盘时间和数据量的同时条件、fsync 关闭后的持久化操作、wal_skip_threshold 说明,并保留各版 O_DIRECT、压缩算法与同步提交规则。 +- 类型转换:统一参数解析、可变参数与默认参数、首选类型、受信任用户及字面量说明;逐版保留自身操作符、算法步骤、SQL 示例与错误输出。 +- 关联术语与正文:校准字面量、受信任用户、基础类型、重建与时间点恢复;修复 quote_literal 单引号双写、PQprepare 条件、ECPG 字段说明、gexec 和正则表达式相关漏译。 +- 格式化函数:补齐 PG18—20 的 RN 与 V 说明,修正符号、隐含小数点和旧 TZ/OF 适用限制,保留各版模板与表格结构。 +- 字符串和二进制字符串:修复 format 负宽度条件、substring/overlay/position/regexp 语义、引用与转义、SQL 片段、零起始编号及 SHA-384/512 示例缺字符;补回 to_hex 负数示例;恢复 PG14/17 部分表行顺序并移除 PG14 未来文档行。 +- 位串与 JSON 类型转换术语:统一替换范围、提取条件、左端零编号、置位计数及索引词,修正 PG16—20 的 JSON 键类型限制措辞。 + +同一英文语义单元复用审定中文;版本差异、既有标签和合法锚点分别保留。 + +## 验证与证据边界 + +- 本次全部 **142** 个改动文件均与最新十一版原生检查快照逐字节相同;文件 SHA256 已记录。 +- 十一版固定输入准备均成功。原始全书检查仍返回非零(PG10—13 为 3,其余为 1);各批范围内候选分别绑定源节点处理,未把原始全书结果写成通过。 +- 格式化、字符串/二进制、位串批分别验证 5067、4948、477 个结构与语义单元关联;这些是关联记录数,不是独立缺陷数,也不是全书逐句审阅证明。 +- 已检查完整函数签名、代码和示例、表行列与跨行、内部引用及共用译文。新增位串批的 8 条签名候选均来自已审可见索引译名。 +- 仍明确保留一条 PG17 JSON 创建函数整表行序问题,待下一批对照十一版关闭;不能用已修正的单行术语代替整表验收。 +- `git diff --check` 通过。 +- 当前台账 3269 项、35959 个版本格,每项均有十一格。这些是分批追踪粒度,不能视为独立缺陷数量或最终覆盖证明。 +- **全书逐句语义校准未完成;最终 HTML、A4 PDF、US PDF 共 33 项构建完成数为 0。** 早先 PG18 预检不计最终构建。未推送、未发布。 + +## 后续工作 + +1. 在当前源码上逐项复核 ZCode 的 F-001—F-026,优先关闭 PG14—16 未来内容混入及其他确认缺文、错误示例;每项检查 PG10—PG20 全部适用位置。 +2. 绑定独立审核原始证据,并区分已被本次修复覆盖的问题、仍存在的问题和需细分的新问题。独立审核快照为 `4c1790c`,不能直接套用旧快照结论。 +3. 继续比较/枚举等已读未写批次及全书剩余语义审阅,完成 C17/C18/C20 全量复核。 +4. 对最终源码执行十一版完整检查与 33 项实际构建,保留日志、输入及产物哈希,并检查 HTML 和两种纸型 PDF 页面。 + +## 本地证据与续作入口 + +运行目录:`outputs/pg10-20-calibration-20260911-134417/`(按仓库规则忽略,不把构建缓存与大体积审计快照提交)。 + +- `PROGRESS.md`、`TODO.md`、`CHECKPOINT.json`:真实进度、剩余范围与逐文件当前哈希。 +- `INPUTS.json`、`ledgers/`:固定英文身份、共用译文、十一版处理决定和前后片段。 +- `stage-commit-manifest.json`:本次提交 142 个正文文件与 SHA256。 +- `checkpoint-bitstring-cast/`:本次精确源码快照、完整命令、退出码与原始全书检查。 +- 各批 `*-native-validation.json`、`*-native-dispositions.json`:范围验证和逐项例外/未决说明。 +- 独立审核:`outputs/pg10-20-independent-review-20260912-0731/`,含 `PROOFREADING.md`、`findings.jsonl`、`VERSION-MATRIX.tsv` 与 `PROGRESS.md`;保持原证据不改。 diff --git a/docs/final-acceptance-20260912.md b/docs/final-acceptance-20260912.md new file mode 100644 index 00000000..def2558e --- /dev/null +++ b/docs/final-acceptance-20260912.md @@ -0,0 +1,67 @@ +# PG10—PG20 中文文档全系列校对最终验收(2026-09-12) + +独立校对系列(PG18 起轮 → 横向矩阵复核 → 逐版逐句扫描收官)与修复落地全部完成后的最终收尾验收。验收对象为提交时点的 `zh/10`…`zh/20` 十一个大版本,英文基准固定为 en/10.23、11.22、12.22、13.23、14.24、15.19、16.15、17.11、18.6、19beta3 与 PG20 固定提交 `86f7c82`。 + +## 一、系列执行总览 + +- **逐句扫描**:PG18→19→20→17→16→15→14→13→12→11→10 共 11 轮,约 10.4 万阅读单元全部完成(PG18 11,182 / PG15 11,183 / PG13 10,688 / PG12 8,836 / PG11 8,827 / PG10 8,561 等);每批中英对照,疑似偏差一律回到快照原文分窗核实。 +- **账本终态**:`findings.jsonl` 49 条(F-001…F-042 + F-044…F-050,F-043 并发冲突空号)= 横向矩阵 49 键 = HORIZONTAL-REVIEW.md 49 个唯一问题节,三账本计数一致。按严重程度:高 1 项(F-010 旧版混入未来内容)、中 24 项、低 22 项有效;撤回 3 项(F-027/F-028 相邻同构视图错配误报;F-012 执行期逐版枚举证伪)。 +- **修复落地**:分多轮提交收编(`d1ac51f` 跨版批次 + `docs(pgNN)` 分版批次 + EXECUTE 样板句族统一 `3a83c89`…`7c356d3` 等);全部有效发现的修复签名在 HEAD 态清零或确认在位。 +- **设计内挂起**:F-001 链接省略的系统性余量(每版少量 EN 引用目标在 zh 无对应)——账本裁定随增量翻译逐步补齐,不属本轮缺陷。 + +## 二、本次收尾修复(随本验收提交) + +| 项 | 内容 | 范围 | +|---|---|---| +| F-029⑯ | libpq `PG_DIAG_STATEMENT_POSITION` 描述错字"而不是**以及**字节计算"→"而不是**以**字节计算" | zh/10—20 十一版各 1 处 | +| F-044 收尾 | jsonb `?|` 行描述补 any-of 限定"文本数组中的**任一**字符串…"(13—18 已先行提交) | zh/19、zh/20 `func/func-json.sgml` | +| F-050 | amcheck"修复损坏"节首段还原为 EN 11—13 的 false positive 段(原为未来版本"共享缓冲区"段的重复副本;该段在 11—13 的正确位置保留在位) | zh/11、zh/12、zh/13 `amcheck.sgml` | +| 构建自洽 | zh/14 两处重复 ID 修复:`config-setting-shell` 冗余 ``(sect2 已带 id)删除;pg_dump `--no-synchronized-snapshots` 条目误挂 `-78`(与 `--role` 冲突)改分配空闲号 `zh18-auto-pg_dump-varlistentry-81`(en/14.24 该条目无 id,但构建 lint 要求全条目带 id;无外部入站引用) | zh/14 `config.sgml`、`ref/pg_dump.sgml` | +| SVG 字体 | `temporal-isolation.svg` 中文文本("会话 1/2""等待……""……继续""重新检查")的 `font-family` 用中文字体名 `'阿里巴巴普惠体 3.0'`,PDF 管线(Batik)无法解析→字形落入 Times-Roman→严格模式构建失败;统一改为 gin.svg 已验证的拉丁名 `'Alibaba PuHuiTi 3.0',serif` | zh/19、zh/20 `images/temporal-isolation.svg`(各 5 处) | + +三项验证证据: + +- F-029⑯:全树"以及字节"0 命中;"以字符计算而不是以字节计算"十一版各恰 1 处,与 EN "positions are measured in characters not bytes" 对应。 +- F-044:十三至二十版 `?|` 行均为"任一字符串"且逐字一致;zh/10—12 旧式表保持"任意一个"(随 EN 10—12 自身句式,母本不动);`?` 行与 `?&` 行邻行原样。 +- F-050:新段与 zh/14 母本归一化后逐字一致;"命中了共享缓冲区"段在三版仍各恰 1 处(正确列表位置,对应 EN 11—13 "detectable problems" 清单);zh/10 多出的"软件缺陷"句经 en/10.23 比对为该版 EN 独有句("In practice, amcheck is more likely to find software bugs…"),分版正确、无需改动。 + +## 三、跨版本一致性与完整性验收 + +- **签名清零扫描**(现行树全量 grep):F-029①③⑯、F-030、F-033、F-035、F-038、F-040、F-042(`<<=` 行"被包含于或等于"十三至二十版各 1)、F-044、F-047("递归应用程序"0,"通过递归应用这些规则"22 处 = 十版 ×2 + 母本)等旧串全部 0 命中。 +- **残留甄别三项均裁定正确**:F-033"潜在性"命中为修复后句中正常词组"潜在性能收益";F-042"子网是否包含或等于子网"命中属合法的 `>>=` 行;F-036"单引号/小写"两句仅存于 zh/10—13(en/10.23、en/13.23 仍有该两句,PG14 起上游删除,zh/14—20 已清理)——分版边界精确。 +- **样板句族终态**:`授予EXECUTE权限`规范式全库 153 处,带空格旧式 0 处;"复制原点"0 / "复制源"589 一统;EXECUTE 授权四规范形态(超用户/pg_monitor 成员/pg_monitor 权限/10—12 短句-括注族)无混式。 +- **F-048 索引短语抽查**:`constraint exclusion` 等英文索引项已译(zh/10、zh/18 抽查各 1 处中文形态)。 + +## 四、构建验收 + +十一版 `make -C zh/ html` 全部通过(页数与上轮 FIX-LEDGER 记录一致:PG10 1010、PG11 1048、PG12 1055、PG13 1061、PG14 1082、PG15 1090、PG16 1170、PG17 1143、PG18 1148、PG19 1176、PG20 1157 页)。首轮构建仅 zh/14 报两处重复 ID 有效性错误(此前 id 迁移批次的笔误,见第二节),修复后 zh/14 重建零告警、页数不变;其余十版一贯零告警(上轮记录的 zh/14 sepgsql 悬空 xref 已在此前提交中消除)。PDF 本轮未重建,沿用系列惯例以 HTML 为构建门禁;如需可按 Makefile `zh-pdf-all` 批量产出。 + +## 五、遗留处置(收尾轮全部关闭) + +1. **F-001 链接省略余量——复测闭合**:以引号无关、大小写不敏感探针(排除 zh/10 旧管线大写 linkend 与 zh/13—20 单引号 linkend 两类假阳性)对全树 11 版重测 EN→zh linkend 集合差,结果为 **0**;原审计范围(ddl/func/glossary)同样为 0。原裁定"随增量翻译逐步做"的挂起项实际已被 `8bac876` 及后续各修复轮闭合,账本从未复测而已。 +2. **zh/14 `ref/merge.sgml` 死文件——已删除**:MERGE 为 PG15 引入的命令,en/14.24 无此文件;该 683 行中文副本经 `git log` 溯源为 `3ca4516`("bump zh docs to the latest minor version")批量升版时从 PG15 树误带(zh/15 正本 682 行)。不在构建图内、全树零入站 `sql-merge` 引用,删除为闭环操作(未来内容三件套中仅条目自身);删除后 zh/14 HTML 重建 1082 页零告警。全树排查确认其为唯一孤儿文件(各版 `pgdoccn-notes.sgml` 为中文文档基础设施,合法)。 +3. **PDF 构建补齐**:11 版 × A4/US 共 22 份 PDF 全部重建,与 11 版 HTML 合计 33 项构建完成,产物位于 `tmp/pdf/zh/`(gitignored)。 +4. 并发会话滚动校准仍可能产生新改动;本验收结论以提交时点快照为准。 + +## 六、证据入口 + +- 运行目录(gitignored):`outputs/pg10-20-independent-review-20260912-0731/`——`findings.jsonl`、`HORIZONTAL-REVIEW.md`、`FIX-LEDGER.md`(第六节为收尾轮记录)、`PROGRESS.md`(十一轮完成报告)、`PROGRESS-pg12-session-report.md`(PG12 轮报告原稿)。 +- 阶段检查点:[calibration-20260912-checkpoint.md](calibration-20260912-checkpoint.md)。 + +## 七、生产发布级全量校验轮(2026-09-13) + +在全部遗留关闭后追加的一轮全量校验,覆盖标题、锚点、译法(链接与未译内容)、标点风格四个维度,探针全部清零。 + +**1. F-001 链接省略——逐处级善后(按 文件×linkend 出现次数比对 EN/zh)**:初测 19 组缺口全部修复——`%x` 行补"参见 transaction-id"(16—20);jsonpath 转换说明补 "Similarly…" 两句含 xref(17—20);pg_logical_slot_get_changes 补逻辑故障切换槽整句含链接(17—20);random 说明句补 xref 与 random_normal(17/18);sqljson 五处交叉引用补齐 @@/match 两行括号说明(17/18/19,措辞随各版母本;zh/20 match 行"返回错误或"正译为"失败或");zh/15 补 SQL/JSON 路径语言偏差清单整块(谓词偏差+正则差异两项,含 xref)。修复后探针 0。 + +**2. 标题跨版一致性(id 锚定比对,同 EN 标题→须同 zh 标题)**:初测 14 处分歧全部统一——备库设置→备库、内核资源→内核资源使用(zh/15);访问控制列表权限缩写→ACL 权限缩写(12—14 对齐 15—20);配置参数→配置设置(16—20 对齐 10—15);EXPLAIN/ANALYZE 的 FDW 例程恢复空格族(15/17—20 对齐全库 73:10 的带空格形态);Parallel Append→并行追加(9 版对齐 zh/15 译名与"并行扫描/连接/聚合"兄弟标题);BufferPin/IO/IPC/LWLock 大小写还原(17—19,系此前批处理误折半);POSIX 正则表达式细节补空格(zh/19);标题连接符 `——`→`—`(zh/19 两处,对齐 365:2 的实体约定)。修复后探针 0。 + +**3. 锚点完备性**:EN id 缺于 zh(剥注释后)0——zh/15 补 AuthenticationSCMCredential 流程条目+消息格式条目(EN 15 独有、zh 全缺;母本 zh/14 + 按 en/15.19 新译,内层条目按惯例配 zh18-auto 号)、删除 LSN 未来词条存根(悬空 glosssee,PG16+ 内容,系 11 版中最后一处构建告警);pg_checksums 描述节 id 归一为 EN 形态 `r1-app-pg_checksums-1`(14/15,无入站引用);ecpg 两个"缺失"id 甄别为 EN 注释块内代码,零渲染影响。版内重复 id 0;悬空链接由构建管线验证(修复后 zh/15 零告警)。 + +**4. 未译内容扫描**(剥代码块/内联标记后含英文虚词的散句探针):66 个候选逐项甄别,全部为合法保留——SQL 语法产生式(CREATE TABLE/COPY 的 term)、sources.sgml 英文用法指南节标题("May vs. Can vs. Might" 与 Unable/Bad/Illegal/Unknown 同族)、overlay() 签名格。零真缺译。 + +**5. 标点风格**(正文全角化,代码上下文豁免):中文邻接半角逗/分号 374 处、标签式半角冒号 599 处、散文半角冒号 60 处、句末半角句点 29 处,全部转全角;有意保留三类:格式记法"分钟:秒""主机:端口号"(半角为字面格式)、文件名". 和 .."(已有 quote 标记)、问号族(操作符表描述行的既有族内统一约定)。 + +**6. 工具事故与恢复(如实记录)**:标点批处理的代码块掩码占位符在 9 个文件(zh/10 五件 + zh/14/15/16 的 func/docguide)泄漏,各损坏少量代码块。处置:受损文件全部恢复至 HEAD,改用按代码块边界切段的无占位符方法重放同类转换;以"代码块计数 vs HEAD + 占位符残留"双探针全树验证,异常 0;zh/15 两处有意插入独立 grep 确认在位。 + +**7. 构建回归**:本轮改动独立重放后 11 版 HTML 全部通过(页数与基线一致,zh/15 零告警),作为 SGML 完整性门禁;PDF 按约定不在本轮范围。本轮提交边界:与并发校准会话混合的 22 个文件(其正在编辑 catalogs/func 等)未纳入本提交,留待其收口;工作树保留全部并集状态。 diff --git a/zh/10/adminpack.sgml b/zh/10/adminpack.sgml index 0ed60f41..510b1a4c 100644 --- a/zh/10/adminpack.sgml +++ b/zh/10/adminpack.sgml @@ -15,7 +15,7 @@ <filename>adminpack</filename> 函数 - Name 返回类型 + 名称 返回类型 描述 @@ -57,7 +57,7 @@ pg_file_rename - pg_file_rename重命名文件。如果省略archivename或其值为 NULL,则它只是将oldname重命名为newname(后者必须尚不存在)。如果提供了archivename,它会先将newname重命名为archivename(后者必须尚不存在),然后再将oldname重命名为newname。如果第二个重命名步骤失败,它会在报告错误之前尝试将archivename再改回newname。成功时返回 true;如果源文件不存在或不可写,则返回 false;其他情况会抛出错误。 + pg_file_rename重命名文件。如果省略archivename或其值为空值,则它只是将oldname重命名为newname(后者必须尚不存在)。如果提供了archivename,它会先将newname重命名为archivename(后者必须尚不存在),然后再将oldname重命名为newname。如果第二个重命名步骤失败,它会在报告错误之前尝试将archivename再改回newname。成功时返回 true;如果源文件不存在或不可写,则返回 false;其他情况会抛出错误。 @@ -80,7 +80,7 @@ 已弃用的<filename>adminpack</filename>函数 - Name 返回类型 + 名称 返回类型 描述 diff --git a/zh/10/amcheck.sgml b/zh/10/amcheck.sgml index 6f313117..719e1501 100644 --- a/zh/10/amcheck.sgml +++ b/zh/10/amcheck.sgml @@ -123,7 +123,7 @@ ORDER BY c.relpages DESC LIMIT 10; 这也包括因操作系统排序规则的比较规则发生变化而引起的问题。 - 像text这类可排序类型的数据值之间的比较必须是不可变的 + 像text这类支持排序规则的类型的 datum 之间的比较必须是不可变的 (正如用于 B-树索引扫描的所有比较都必须不可变一样), 这就意味着操作系统排序规则绝不能发生变化。 虽然这种情况比较少见,但操作系统排序规则的更新确实可能导致此类问题。 diff --git a/zh/10/auth-delay.sgml b/zh/10/auth-delay.sgml index 683ec269..a0d4ee14 100644 --- a/zh/10/auth-delay.sgml +++ b/zh/10/auth-delay.sgml @@ -1,7 +1,7 @@ - auth_delay — 在认证失败时暂停 + auth_delay auth_delay diff --git a/zh/10/backup.sgml b/zh/10/backup.sgml index bed5429e..a6c864a3 100644 --- a/zh/10/backup.sgml +++ b/zh/10/backup.sgml @@ -3,7 +3,7 @@ 备份和恢复 - backup + 备份 与任何保存重要数据的系统一样,PostgreSQL数据库也应定期备份。虽然其过程基本简单,但清楚理解其底层技术和前提假设非常重要。 @@ -61,12 +61,18 @@ psql dbname < - 默认情况下,psql 在遇到 SQL 错误后仍会继续执行脚本。可以在运行 psql 时设置 ON_ERROR_STOP 变量来改变这一行为,让 psql 在发生 SQL 错误时以退出状态 3 退出: + + 默认情况下,psql脚本在遇到 SQL 错误后仍会继续执行。你可能希望让psql在设置了ON_ERROR_STOP变量的情况下运行,以改变这一行为,并让psql在发生 SQL 错误时以退出状态码 3 退出: + psql --set ON_ERROR_STOP=on dbname < dumpfile -不论采用哪种方式,最终都只会得到部分恢复的数据库。另一种做法是指定将整个转储作为一个事务恢复,这样恢复要么全部完成,要么全部回滚。可通过将命令行选项 传递给 psql 来指定这种模式。使用该模式时要注意,即使是很小的错误,也可能使已经运行数小时的恢复全部回滚。不过,这可能仍比在部分恢复转储后手动清理复杂的数据库更好。 + + 无论采用上述哪种方式,你最终只会得到一个部分恢复的数据库。另一种做法是指定将整个转储作为单个事务恢复,这样恢复要么全部完成,要么全部回滚。可以通过把命令行选项传给psql来启用这种模式。使用这种模式时要注意,即便是一个很小的错误,也可能回滚一个已经运行了许多小时的恢复过程。不过,这仍可能比在部分恢复后手工清理一个复杂数据库更可取。 + - 利用 pg_dumppsql 向管道写入或从管道读取的能力,可以直接将数据库从一台服务器转储到另一台,例如: -pg_dump -h host1 dbname | psql -h host2 dbname + + pg_dumppsql能够写入或读取管道,这使得可以把数据库直接从一台服务器转储到另一台服务器,例如: + +pg_dump -h host1 dbname | psql -h host2 dbname @@ -85,12 +91,16 @@ pg_dump -h host1 dbname | psql -h h 使用<application>pg_dumpall</application> - pg_dump 每次只转储一个数据库,不转储角色或表空间信息(因为它们属于整个集簇,而非某个数据库)。为了便于转储数据库集簇的全部内容,系统提供了 程序。pg_dumpall 会备份给定集簇中的每个数据库,并保留角色和表空间定义等集簇级数据。该命令的基本用法如下: + pg_dump一次只转储一个数据库,而且不会转储角色或表空间的信息(因为这些是整个集簇级别的,而不是每个数据库各自的)。为了方便地转储整个数据库集簇的全部内容,提供了程序。pg_dumpall会备份给定集簇中的每个数据库,并保留角色定义和表空间定义等集簇范围的数据。该命令的基本用法是: + pg_dumpall > dumpfile -要恢复生成的转储,可以使用 psql: + + 生成的转储可以用psql恢复: psql -f dumpfile postgres -(实际上,可以指定任何已存在的数据库名作为起点;但如果装载到空集簇中,通常应使用 postgres。)恢复 pg_dumpall 转储时,必须具有数据库超级用户权限,因为恢复角色和表空间信息需要这些权限。如果使用了表空间,请确保转储中的表空间路径适合新的安装环境。 + + (实际上,可以指定任意一个现有数据库名作为起点,但如果要装载到一个空集簇中,通常应使用postgres。)恢复pg_dumpall转储时始终需要数据库超级用户权限,因为恢复角色和表空间信息必须使用该权限。如果使用了表空间,请确保转储中的表空间路径适合新的安装。 + pg_dumpall的工作方式是先发出重新创建角色、表空间和空数据库的命令,然后针对每个数据库调用pg_dump。这意味着每个数据库本身都是内部一致的,但不同数据库的快照并不同步。 @@ -176,7 +186,7 @@ pg_restore -d dbname - 对于非常大的数据库,你可能需要把split与前两种方法之一结合使用。 + 对于非常大的数据库,你可能需要把split与另外两种方法之一结合使用。 @@ -232,7 +242,7 @@ tar -cf backup.tar /usr/local/pgsql/data - 如果无法获得同时的快照,一种选择是将数据库服务器关闭足够长的时间,以建立所有冻结快照。另一种选择是执行持续归档基础备份(),因为这种备份不受备份期间文件系统变化的影响。这要求只在备份过程中启用持续归档;恢复则使用持续归档恢复()。 + 如果无法获得同时的快照,一种选择是将数据库服务器关闭足够长的时间,以建立所有冻结快照。另一种选择是执行持续归档基础备份(),因为这种备份不受备份期间文件系统变化的影响。这种方法只需在备份期间启用持续归档;恢复则使用持续归档恢复()。 @@ -248,11 +258,11 @@ tar -cf backup.tar /usr/local/pgsql/data 持续归档和时间点恢复(PITR) - continuous archiving + 持续归档 - point-in-time recovery + 时间点恢复 @@ -292,7 +302,7 @@ tar -cf backup.tar /usr/local/pgsql/data - 和普通文件系统备份技术一样,这种方法只能支持整个数据库集簇的恢复,而不支持其中某个子集的恢复。此外,它需要大量归档存储:基础备份可能很庞大,繁忙系统也会产生大量必须归档的 WAL 流量。尽管如此,在很多需要高可靠性的场景中,它仍是首选的备份技术。 + 和普通文件系统备份技术一样,这种方法只能支持整个数据库集簇的恢复,而不支持其中某个子集的恢复。此外,它需要大量归档存储:基础备份可能很庞大,繁忙系统也会产生许多兆字节的、必须归档的 WAL 流量。尽管如此,在很多需要高可靠性的场景中,它仍是首选的备份技术。 @@ -305,12 +315,12 @@ tar -cf backup.tar /usr/local/pgsql/data 从抽象角度看,运行中的 PostgreSQL 系统会产生一个无限延伸的 WAL 记录序列。在物理存储上,系统将该序列分为 WAL 段文件,通常每个为 16MB(但可以在构建 PostgreSQL 时修改段大小)。段文件使用数字名称,反映其在抽象 WAL 序列中的位置。不使用 WAL 归档时,系统通常只创建少量段文件,然后通过将不再需要的段文件重命名为更大的段号来回收它们。系统假定,内容早于倒数第二个检查点的段文件已不再需要,可以回收。 - 在归档 WAL 数据时,我们需要在每个段文件写满后捕获其内容,并在该段文件被回收重用之前把数据保存到某处。根据应用场景和可用硬件的不同,把数据保存到某处可以有很多不同的方法:可以把段文件复制到另一台机器上的 NFS 挂载目录,把它们写到磁带机中(确保你有办法识别每个文件的原始文件名),把它们批量打包后刻录到 CD 上,或者采用完全不同的方式。为了给数据库管理员提供灵活性,PostgreSQL尽量不对归档方式作任何假设。相反,PostgreSQL允许管理员指定一个 shell 命令或一个归档库,以便把已完成的段文件复制到它应去的地方。这既可以只是一个使用cp的 shell 命令,也可以调用一个复杂的 C 函数,全由你决定。 + 在归档 WAL 数据时,我们需要在每个段文件写满后捕获其内容,并在该段文件被回收重用之前把数据保存到某处。根据应用场景和可用硬件的不同,把数据保存到某处可以有很多不同的方法:可以把段文件复制到另一台机器上的 NFS 挂载目录,把它们写到磁带机中(确保你有办法识别每个文件的原始文件名),把它们批量打包后刻录到 CD 上,或者采用完全不同的方式。为了给数据库管理员提供灵活性,PostgreSQL尽量不对归档方式作任何假设。相反,PostgreSQL允许管理员指定一个 shell 命令,以便把已完成的段文件复制到它应去的地方。该命令可以只是一次简单的cp调用,也可以调用一个复杂的 shell 脚本,全由你决定。 - 要启用 WAL 归档,请将 配置参数设为 replica 或更高值,将 设为 on,并在 要启用 WAL 归档,请将 配置参数设为 replica 或更高值,将 设为 on,并在 配置参数中指定要执行的 shell 命令。实际使用中,这些设置始终放在 postgresql.conf 文件中。对于 archive_command, - %p 会被替换为要归档文件的路径名,而 %f 只会被替换为文件名。(路径名相对于当前工作目录,即集簇的数据目录。)使用 %% 可以在命令中嵌入实际的 % 字符。最简单的可用命令类似于: + %p 会被替换为要归档文件的路径名,而 %f 只会被替换为文件名。(路径名相对于当前工作目录,即集簇的数据目录。)使用 %% 可以在命令中嵌入实际的 % 字符。最简单的可用命令类似于: archive_command = 'test ! -f /mnt/server/archivedir/%f && cp %p /mnt/server/archivedir/%f' # Unix archive_command = 'copy "%p" "C:\\server\\archivedir\\%f"' # Windows 这会将可归档的 WAL 段复制到目录 /mnt/server/archivedir。(这只是示例,并非推荐做法,而且不一定适用于所有平台。)在替换 %p%f 参数后,实际执行的命令可能如下: @@ -324,33 +334,35 @@ test ! -f /mnt/server/archivedir/00000001000000A900000065 && cp pg_wal/0 通常应将归档命令设计为拒绝覆盖任何已存在的归档文件。这是一项重要的安全保护措施,能在管理员操作失误时(例如将两台不同服务器的输出发送到同一归档目录)维护归档的完整性。 - 建议测试所拟定的归档命令,确保它确实不会覆盖已有文件,并且在这种情况下返回非零状态。上面给出的 Unix 示例命令通过单独加入一个test步骤,避免覆盖已有归档。在某些 Unix 平台上,cp提供了诸如之类的开关,也可以更简洁地实现同样目的,但在你确认它会返回正确的退出状态之前,不应依赖这些开关。(尤其是 GNU cp在使用且目标文件已存在时会返回状态零,这不是我们想要的行为。) + 建议测试所拟定的归档命令,确保它确实不会覆盖已有文件,并且在这种情况下返回非零状态。上面给出的 Unix 示例命令通过单独加入一个test步骤,确保这两点。在某些 Unix 平台上,cp提供了诸如之类的开关,也可以更简洁地实现同样目的,但在你确认它会返回正确的退出状态之前,不应依赖这些开关。(尤其是 GNU cp在使用且目标文件已存在时会返回状态零,这不是我们想要的行为。) - 在设计归档方案时,请考虑如果归档命令或归档库因为某些环节需要操作员干预,或者归档空间耗尽而反复失败,会发生什么。例如,如果你在没有自动换带器的情况下向磁带写入数据,那么磁带满了以后,在更换磁带之前将无法继续归档。你应确保任何错误情况或对人工操作员的请求都能得到适当报告,以便问题能够比较快地解决。在问题解决之前,pg_wal/目录会继续堆积 WAL 段文件。(如果包含pg_wal/的文件系统被写满,PostgreSQL将执行 PANIC 关闭。不会丢失已提交的事务,但在释放出一些空间之前,数据库会一直离线。) + 在设计归档方案时,请考虑如果归档命令因为某些环节需要操作员干预,或者归档空间耗尽而反复失败,会发生什么。例如,如果你在没有自动换带器的情况下向磁带写入数据,那么磁带满了以后,在更换磁带之前将无法继续归档。你应确保任何错误情况或对人工操作员的请求都能得到适当报告,以便问题能够比较快地解决。在问题解决之前,pg_wal/目录会继续堆积 WAL 段文件。(如果包含pg_wal/的文件系统被写满,PostgreSQL将执行 PANIC 关闭。不会丢失已提交的事务,但在释放出一些空间之前,数据库会一直离线。) - 归档命令或归档库的速度并不重要,只要它能跟上服务器生成 WAL 数据的平均速度即可。即使归档过程稍有滞后,正常操作也会继续。如果归档明显落后,灾难发生时可能丢失的数据量就会增加。这还意味着pg_wal/目录会包含大量尚未归档的段文件,最终可能耗尽可用磁盘空间。建议监控归档过程,确保它按你的预期工作。 + 归档命令的速度并不重要,只要它能跟上服务器生成 WAL 数据的平均速度即可。即使归档过程稍有滞后,正常操作也会继续。如果归档明显落后,灾难发生时可能丢失的数据量就会增加。这还意味着pg_wal/目录会包含大量尚未归档的段文件,最终可能耗尽可用磁盘空间。建议监控归档过程,确保它按你的预期工作。 - 在编写归档命令或归档库时,应假定待归档文件名最长可达 64 个字符,并且可以包含 ASCII 字母、数字和点号的任意组合。无需保留原始相对路径(%p),但必须保留文件名(%f)。 + 在编写归档命令时,应假定待归档文件名最长可达 64 个字符,并且可以包含 ASCII 字母、数字和点号的任意组合。无需保留原始相对路径(%p),但必须保留文件名(%f)。 注意,虽然 WAL 归档允许你恢复对PostgreSQL数据库中数据所做的任何修改,但它不会恢复对配置文件(即postgresql.confpg_hba.confpg_ident.conf)的修改,因为这些文件是手工编辑的,而不是通过 SQL 操作修改的。你可能希望把配置文件放在常规文件系统备份过程能够覆盖的位置。关于如何重定位配置文件,见 - 归档命令只会在已完成的 WAL 段上调用。因此,如果服务器产生的 WAL 流量很小(或者存在这样的低谷期),事务完成到其被安全写入归档存储之间可能会有很长延迟。为了限制未归档数据的最长滞留时间,可以设置 ,强制服务器至少每隔这么长时间切换到一个新的 WAL 段文件。注意,由强制切换而提前归档的文件长度仍与装满的文件相同。因此,把 archive_timeout 设得很短并不明智,这会使归档存储膨胀。将 archive_timeout 设为大约一分钟通常是合理的。 + + 归档命令只会针对已完成的 WAL 段调用。因此,如果服务器产生的 WAL 流量很小(或者存在低谷期),事务完成到其被安全写入归档存储之间可能会有很长延迟。为了限制未归档数据可能有多旧,你可以设置,使服务器强制切换到新 WAL 段文件的间隔不超过这个值。注意,由强制切换而提前归档的文件长度仍与装满的文件相同。因此,把archive_timeout设得很短并不明智,这会使归档存储膨胀。archive_timeout设为大约 1 分钟通常是合理的。 + 此外,如果你希望确保一个刚刚完成的事务尽快被归档,可以使用pg_switch_wal手工强制一次段切换。其他与 WAL 管理相关的实用函数列在中。 - 当wal_levelminimal时,某些 SQL 命令会像中所述那样被优化为避免 WAL 记录。如果在执行这些语句期间启用了归档或流复制,WAL 将不包含归档恢复所需的足够信息。(崩溃恢复不受影响。)因此,wal_level只能在服务器启动时更改。然而,archive_command可以通过重新加载配置文件来更改。如果你通过 shell 进行归档并希望暂时停止归档,一种办法是将archive_command设置为空字符串('')。这会导致 WAL 文件在pg_wal/中累积,直到重新建立可用的archive_command。 + 当wal_levelminimal时,某些 SQL 命令会像中所述那样被优化为避免 WAL 记录。如果在执行这些语句期间启用了归档或流复制,WAL 将不包含归档恢复所需的足够信息。(崩溃恢复不受影响。)因此,wal_level只能在服务器启动时更改。然而,archive_command可以通过重新加载配置文件来更改。如果你希望暂时停止归档,一种办法是将archive_command设置为空字符串('')。这会导致 WAL 文件在pg_wal/中累积,直到重新建立可用的archive_command @@ -379,7 +391,7 @@ test ! -f /mnt/server/archivedir/00000001000000A900000065 && cp pg_wal/0 - 使用低级接口进行基础备份 + 使用低级 API 进行基础备份 使用低级 API 制作基础备份的过程,比 方法多几个步骤,但相对简单。务必按顺序执行这些步骤,并在继续下一步之前确认当前步骤成功。 低级基础备份可以采用非排他或排他方式。建议使用非排他方式;排他方式已弃用,最终将被移除。 @@ -393,7 +405,7 @@ test ! -f /mnt/server/archivedir/00000001000000A900000065 && cp pg_wal/0 以有权运行 pg_start_backup 的用户身份(超级用户,或已被授予该函数 EXECUTE 权限的用户)连接到服务器(连接哪个数据库都可以),并执行命令: SELECT pg_start_backup('label', false, false); -其中,label 是用于唯一标识此次备份操作的任意字符串。调用 pg_start_backup 的连接必须一直保持到备份结束,否则备份会自动中止。 +其中,label 是用于唯一标识此次备份操作的任意字符串。调用 pg_start_backup 的连接必须一直保持到备份结束,否则备份会自动中止。 默认情况下,pg_start_backup 可能需要很长时间才能完成。这是因为它会执行一次检查点,而检查点所需的 I/O 会分散在较长时间内,默认是检查点间隔的一半(参见配置参数 )。这通常是理想的行为,因为它尽量减少了对查询处理的影响。如果希望尽快开始备份,请将第二个参数改为 true,这会尽可能利用可用 I/O 立即执行检查点。 @@ -434,9 +446,9 @@ SELECT * FROM pg_stop_backup(false, true); 以有权运行 pg_start_backup 的用户身份(超级用户,或已被授予该函数 EXECUTE 权限的用户)连接到服务器(连接哪个数据库都可以),并执行命令: SELECT pg_start_backup('label'); -其中,label 是用于唯一标识此次备份操作的任意字符串。pg_start_backup 会创建一个备份标签文件,名为 backup_label,位于集簇目录中,包含备份信息,例如开始时间和标签字符串。该函数还会创建一个表空间映射文件,名为 tablespace_map,位于集簇目录中,包含 pg_tblspc/ 中表空间符号链接的信息(如果存在一个或多个这样的链接)。如果需要从备份恢复,这两个文件对备份的完整性都至关重要。 +其中,label 是用于唯一标识此次备份操作的任意字符串。pg_start_backup 会创建一个备份标签文件,名为 backup_label,位于集簇目录中,包含备份信息,例如开始时间和标签字符串。该函数还会创建一个表空间映射文件,名为 tablespace_map,位于集簇目录中,包含 pg_tblspc/ 中表空间符号链接的信息(如果存在一个或多个这样的链接)。如果需要从备份恢复,这两个文件对备份的完整性都至关重要。 - 默认情况下,pg_start_backup 可能需要很长时间才能完成。这是因为它会执行一次检查点,而检查点所需的 I/O 会分散在较长时间内,默认是检查点间隔的一半(参见配置参数 )。这通常是理想的行为,因为它尽量减少了对查询处理的影响。如果希望尽快开始备份,请使用: + 默认情况下,pg_start_backup 可能需要很长时间才能完成。这是因为它会执行一次检查点,而检查点所需的 I/O 会分散在较长时间内,默认是检查点间隔的一半(参见配置参数 )。这通常是理想的行为,因为它尽量减少了对查询处理的影响。如果希望尽快开始备份,请使用: SELECT pg_start_backup('label', true); 这会强制尽快完成检查点。 @@ -494,7 +506,9 @@ SELECT pg_stop_backup(); 使用持续归档备份进行恢复 - 如果最坏的情况已经发生,需要从备份恢复,请按以下流程操作: + + 现在,最坏的情况发生了,你需要通过备份进行恢复。步骤如下: + 如果服务器仍在运行,就先停止它。 @@ -512,7 +526,7 @@ SELECT pg_stop_backup(); - 如果你正在恢复完整备份,可以把数据库文件直接恢复到目标目录中。务必确保它们以正确的所有者(数据库系统用户,而不是root!)和正确的权限恢复。如果使用了表空间,还应验证pg_tblspc/中的符号链接是否已正确恢复。 + 从文件系统备份中恢复数据库文件。务必确保它们以正确的所有者(数据库系统用户,而不是root!)和正确的权限恢复。如果使用了表空间,还应验证pg_tblspc/中的符号链接是否已正确恢复。 @@ -539,16 +553,16 @@ SELECT pg_stop_backup(); - 整个过程的关键,是设置一个恢复配置文件,说明希望如何恢复,以及恢复到什么位置。可以使用 recovery.conf.sample(通常位于安装目录的 share/ 目录中)作为模板。必须在 recovery.conf 中指定 restore_command,它告诉 PostgreSQL 如何获取已归档的 WAL 段。与 archive_command 一样,它是一个 shell 命令字符串,可以包含 %f,该标记会被替换为所需日志文件的名称;还可以包含 %p,该标记会被替换为日志文件要复制到的路径名。(路径名相对于当前工作目录,即集簇的数据目录。)使用 %% 可以在命令中嵌入实际的 % 字符。最简单的可用命令类似于: + 整个过程的关键,是设置一个恢复配置文件,说明希望如何恢复,以及恢复到什么位置。可以使用 recovery.conf.sample(通常位于安装目录的 share/ 目录中)作为模板。必须在 recovery.conf 中指定 restore_command,它告诉 PostgreSQL 如何获取已归档的 WAL 段文件。与 archive_command 一样,它是一个 shell 命令字符串,可以包含 %f,该标记会被替换为所需日志文件的名称;还可以包含 %p,该标记会被替换为日志文件要复制到的路径名。(路径名相对于当前工作目录,即集簇的数据目录。)使用 %% 可以在命令中嵌入实际的 % 字符。最简单的可用命令类似于: restore_command = 'cp /mnt/server/archivedir/%f %p' 这会复制先前归档的 WAL 段,来源目录为 /mnt/server/archivedir。当然,也可以使用复杂得多的命令,甚至可以使用要求操作人员挂载相应磁带的 shell 脚本。 - 重要的是,该命令在失败时必须返回非零退出状态。系统调用该命令来请求归档中不存在的文件;遇到这种情况时,它就应返回非零值。这不是一种错误情况。例外是,如果该命令被信号终止(用于数据库服务器关闭的SIGTERM除外),或者因 shell 错误(如命令未找到)而失败,那么恢复将中止,服务器也不会启动。 + 重要的是,该命令在失败时必须返回非零退出状态。系统调用该命令来请求归档中不存在的文件;遇到这种情况时,它必须返回非零值。这不是一种错误情况。例外是,如果该命令被信号终止(用于数据库服务器关闭的SIGTERM除外),或者因 shell 错误(如命令未找到)而失败,那么恢复将中止,服务器也不会启动。 - 被请求的文件并不全都是 WAL 段文件;你还应预期会收到对带有.history后缀文件的请求。另外请注意,%p路径的基本文件名会与%f不同;不要指望它们可以互换使用。 + 被请求的文件并不全都是 WAL 段文件;你还应预期会收到对带有.history后缀文件的请求。另外请注意,%p路径的文件名部分会与%f不同;不要指望它们可以互换使用。 @@ -556,14 +570,14 @@ restore_command = 'cp /mnt/server/archivedir/%f %p' - 通常,恢复会处理完所有可用的 WAL 段,从而把数据库恢复到当前时间点(或者在可用 WAL 段所允许的情况下尽可能接近当前时间点)。因此,一次正常恢复通常会以一条file not found消息结束,具体错误文本取决于你选择的restore_command。在恢复开始时,你也可能看到一条针对类似00000001.history文件的错误消息。这同样是正常的,在简单恢复场景中并不表示有问题;相关讨论见。 + 通常,恢复会处理完所有可用的 WAL 段,从而把数据库恢复到当前时间点(或者在可用 WAL 段所允许的情况下尽可能接近当前时间点)。因此,一次正常恢复会以一条file not found消息结束,具体错误文本取决于你选择的restore_command。在恢复开始时,你也可能看到一条针对类似00000001.history文件的错误消息。这同样是正常的,在简单恢复场景中并不表示有问题;相关讨论见 如果希望恢复到过去的某个时间点(例如初级 DBA 删除主要事务表之前),只需在 recovery.conf 中指定所需的停止点。这个停止点称为恢复目标,可以通过日期/时间、命名恢复点,或某个特定事务 ID 的完成来指定。撰写本文时,只有日期/时间和命名恢复点这两种方式比较实用,因为还没有工具能帮助你准确确定应使用哪个事务 ID。 - 停止点必须晚于基础备份的结束时间,也就是pg_stop_backup的结束时间。你不能用某次基础备份恢复到该备份仍在进行中的时间点。(若要恢复到这样的时间点,必须回到更早的一次基础备份,再从那里向前滚动。) + 停止点必须晚于基础备份的结束时间,也就是pg_stop_backup的结束时间。你不能用某次基础备份恢复到该备份仍在进行中的时间点。(若要恢复到这样的时间点,必须回到更早的一次基础备份,再从那里向前重放日志。) @@ -577,14 +591,16 @@ restore_command = 'cp /mnt/server/archivedir/%f %p' 时间线 - timelines + 时间线 能够将数据库恢复到过去某个时间点,也会带来一些类似科幻故事中时间旅行和平行宇宙的复杂情况。例如,假设在数据库原来的历史中,你在周二下午 5:15 删除了一张重要的表,直到周三中午才发现错误。你从容地取出备份,将数据库恢复到周二下午 5:14,然后重新投入运行。在数据库宇宙的这段历史中,你从未删除过那张表。但假设你后来发现这样做不太合适,希望回到原来历史中的周三上午某个时刻。如果数据库恢复运行后覆盖了通往该时刻所需的某些 WAL 段文件,就无法回去了。因此,为了避免这种情况,需要区分时间点恢复后产生的一系列 WAL 记录与数据库原来历史中产生的记录。 为解决这一问题,PostgreSQL 引入了时间线的概念。每当归档恢复完成,系统都会创建一条新时间线,用于标识此次恢复之后产生的一系列 WAL 记录。时间线 ID 是 WAL 段文件名的一部分,因此新时间线不会覆盖旧时间线产生的 WAL 数据。实际上,可以归档许多不同的时间线。这个功能看似没什么用,却常常能救急。比如,你不能确定应该恢复到哪个时间点,需要反复尝试时间点恢复,直到找到脱离旧历史的最佳分支点。没有时间线,这个过程很快就会乱得无法管理。有了时间线,就可以恢复到任何先前的状态,包括早先已放弃的时间线分支中的状态。 - 每次创建新时间线时,PostgreSQL 都会创建一个时间线历史文件,记录它从哪条时间线、在何时分支出来。从包含多条时间线的归档中恢复时,系统需要这些历史文件来选择正确的 WAL 段文件。因此,历史文件与 WAL 段文件一样,也会归档到 WAL 归档区。历史文件只是很小的文本文件,长期保留成本很低,也很合适(不像体积很大的段文件)。如果愿意,可以在历史文件中添加注释,记录这条时间线是如何创建的,以及为什么创建它。当反复试验产生了许多交错的时间线时,这些注释会格外有用。 + + 每当创建一条新的时间线时,PostgreSQL都会创建一个时间线历史文件,记录它是从哪条时间线、在何时分叉出来的。当从包含多条时间线的归档中恢复时,这些历史文件对于系统选取正确的 WAL 段文件是必需的。因此,它们会像 WAL 段文件一样被归档到 WAL 归档区域。历史文件只是很小的文本文件,因此长期保存它们既便宜也合适(而段文件通常很大)。如果你愿意,还可以在历史文件中加入注释,记录创建这条时间线的方式和原因。当你因实验而积累出一批错综复杂的时间线时,这类注释会特别有价值。 + 默认情况下,恢复会沿着制作基础备份时的当前时间线进行。如果希望恢复到某条子时间线(即返回到一次恢复尝试之后产生的某个状态),需要在 recovery.conf 中指定目标时间线 ID。不能恢复到在基础备份之前就已分支出去的时间线。 @@ -597,19 +613,19 @@ restore_command = 'cp /mnt/server/archivedir/%f %p' - 单机热备份 + 独立热备份 - 可以利用PostgreSQL的备份设施生成单机热备份。这些备份不能用于时间点恢复,但它们的制作和恢复通常都比pg_dump转储快得多。(它们也比pg_dump转储大得多,因此在某些情况下速度优势可能会被抵消。) + 可以利用PostgreSQL的备份设施生成独立热备份。这些备份不能用于时间点恢复,但它们的制作和恢复通常都比pg_dump转储快得多。(它们也比pg_dump转储大得多,因此在某些情况下速度优势可能会被抵消。) - 和基础备份一样,生成单机热备份最简单的方法是使用工具。如果在调用它时包含-X参数,使用该备份所需的全部预写式日志都会自动包含在备份中,恢复该备份时也不需要额外动作。 + 和基础备份一样,生成独立热备份最简单的方法是使用工具。如果在调用它时包含-X参数,使用该备份所需的全部预写式日志都会自动包含在备份中,恢复该备份时也不需要额外动作。 - 如果复制备份文件时需要更大的灵活性,也可以使用更低级的流程制作独立热备份。要准备低级独立热备份,请确保将 wal_level 设为 replica 或更高值,将 archive_mode 设为 on,并配置一个 archive_command,使其仅在开关文件存在时执行归档。例如: + 如果复制备份文件时需要更大的灵活性,也可以使用更低级的流程制作独立热备份。要准备低级独立热备份,请确保将 wal_level 设为 replica 或更高值,将 archive_mode 设为 on,并配置一个 archive_command,使其仅在开关文件存在时执行归档。例如: archive_command = 'test ! -f /var/lib/pgsql/backup_in_progress || (test ! -f /var/lib/pgsql/archive/%f && cp %p /var/lib/pgsql/archive/%f)' -/var/lib/pgsql/backup_in_progress 存在时,这条命令会执行归档;否则会静默地返回零退出状态(允许 PostgreSQL 回收不需要的 WAL 文件)。 +/var/lib/pgsql/backup_in_progress 存在时,这条命令会执行归档;否则会静默地返回零退出状态(允许 PostgreSQL 回收不需要的 WAL 文件)。 做好上述准备后,就可以使用类似下面的脚本进行备份: touch /var/lib/pgsql/backup_in_progress @@ -618,7 +634,7 @@ tar -cf /var/lib/pgsql/backup.tar /var/lib/pgsql/data/ psql -c "select pg_stop_backup();" rm /var/lib/pgsql/backup_in_progress tar -rf /var/lib/pgsql/backup.tar /var/lib/pgsql/archive/ -首先创建开关文件 /var/lib/pgsql/backup_in_progress,以启用已完成 WAL 文件的归档。备份完成后删除该开关文件。随后将已归档的 WAL 文件加入备份,使基础备份与所有必需的 WAL 文件都包含在同一个 tar 文件中。请记得在备份脚本中加入错误处理。 +首先创建开关文件 /var/lib/pgsql/backup_in_progress,以启用已完成 WAL 文件的归档。备份完成后删除该开关文件。随后将已归档的 WAL 文件加入备份,使基础备份与所有必需的 WAL 文件都包含在同一个 tar 文件中。请记得在备份脚本中加入错误处理。 @@ -645,7 +661,7 @@ archive_command = 'local_backup_script.sh "%p" "%f"' - 脚本中可能需要解决的需求示例包括: + 可以在脚本中处理的需求示例包括: @@ -654,7 +670,7 @@ archive_command = 'local_backup_script.sh "%p" "%f"' - 把 WAL 文件成批处理,使其每三个小时传输一次,而不是每生成一个就传一次 + 把 WAL 文件成批处理,使其每三个小时传输一次,而不是每次只传输一个 @@ -681,7 +697,10 @@ archive_command = 'local_backup_script.sh "%p" "%f"' 注意事项 - 撰写本文时,连续归档技术还有几个限制。这些限制可能会在未来版本中消除: + + 在撰写本文时,持续归档技术还存在若干局限。这些问题很可能会在未来版本中得到修复: + + 如果在进行基础备份时执行了命令,而该CREATE DATABASE所复制的模板数据库又在基础备份尚未结束时被修改,那么恢复时可能会把这些修改也传播到新建数据库中。这当然并不理想。为避免这种风险,最好在进行基础备份时不要修改任何模板数据库。 diff --git a/zh/10/brin.sgml b/zh/10/brin.sgml index ac0c8742..944c51f6 100644 --- a/zh/10/brin.sgml +++ b/zh/10/brin.sgml @@ -4,7 +4,7 @@ BRIN 索引 - index + 索引 BRIN @@ -20,8 +20,7 @@ - 如果索引中存储的摘要信息与查询条件相一致BRIN - 索引就可以通过常规位图索引扫描来满足查询,并返回每个范围内所有页上的全部元组。 + BRIN 索引可以通过常规位图索引扫描来满足查询;对于每个范围,如果索引中存储的摘要信息与查询条件相一致,就会返回该范围内所有页上的全部元组。 查询执行器负责重新检查这些元组,并丢弃不匹配查询条件的元组 — 换句话说,这些索引是有损的。 由于 BRIN 索引非常小,与顺序扫描相比,扫描索引只会带来很小的额外开销, 但可以避免扫描那些已知不包含匹配元组的大块表数据。 @@ -293,7 +292,7 @@ LOG: request for BRIN range summarization for index "brin_wi_idx" page 128 was range_inclusion_ops - any range type + 任意范围类型 << &< && &> >> @> <@ -|- = < <= = > >= @@ -432,13 +431,13 @@ LOG: request for BRIN range summarization for index "brin_wi_idx" page 128 was 返回索引列摘要数据的内部信息。返回值必须指向一个由 palloc 分配的BrinOpcInfo,其定义如下: typedef struct BrinOpcInfo { - /* Number of columns stored in an index column of this opclass */ + /* 此操作符类在一个索引列中存储的列数 */ uint16 oi_nstored; - /* Opaque pointer for the opclass' private use */ + /* 供操作符类私有使用的不透明指针 */ void *oi_opaque; - /* Type cache entries of the stored columns */ + /* 所存储列的类型缓存条目 */ TypeCacheEntry *oi_typcache[FLEXIBLE_ARRAY_MEMBER]; } BrinOpcInfo; @@ -502,19 +501,19 @@ typedef struct BrinOpcInfo - 支持过程 1 + 支持函数 1 内部函数brin_minmax_opcinfo() - 支持过程 2 + 支持函数 2 内部函数brin_minmax_add_value() - 支持过程 3 + 支持函数 3 内部函数brin_minmax_consistent() - 支持过程 4 + 支持函数 4 内部函数brin_minmax_union() @@ -562,103 +561,103 @@ typedef struct BrinOpcInfo - 支持过程 1 + 支持函数 1 内部函数brin_inclusion_opcinfo() - 支持过程 2 + 支持函数 2 内部函数brin_inclusion_add_value() - 支持过程 3 + 支持函数 3 内部函数brin_inclusion_consistent() - 支持过程 4 + 支持函数 4 内部函数brin_inclusion_union() - 支持过程 11 + 支持函数 11 合并两个元素的函数 - 支持过程 12 + 支持函数 12 可选函数,检查两个元素是否可以合并 - 支持过程 13 + 支持函数 13 可选函数,检查一个元素是否被包含在另一个中 - 支持过程 14 + 支持函数 14 可选函数,用于检查元素是否为空 操作符策略 1 - left-of 操作符 + 位于左侧的操作符 操作符策略 4 操作符策略 2 - does-not-extend-to-the-right-of 操作符 + 不延伸到右侧的操作符 操作符策略 5 操作符策略 3 - overlaps 操作符 + 重叠操作符 操作符策略 4 - does-not-extend-to-the-left-of 操作符 + 不延伸到左侧的操作符 操作符策略 1 操作符策略 5 - right-of 操作符 + 位于右侧的操作符 操作符策略 2 - 操作符策略 6, 18 - same-as-or-equal-to 操作符 + 操作符策略 6、18 + 相同或等于操作符 操作符策略 7 - 操作符策略 7, 13, 16, 24, 25 - contains-or-equal-to 操作符 + 操作符策略 7、13、16、24、25 + 包含或等于操作符 - 操作符策略 8, 14, 26, 27 - is-contained-by-or-equal-to 操作符 + 操作符策略 8、14、26、27 + 被包含或等于操作符 操作符策略 3 操作符策略 9 - does-not-extend-above 操作符 + 不延伸到上方的操作符 操作符策略 11 操作符策略 10 - is-below 操作符 + 位于下方的操作符 操作符策略 12 操作符策略 11 - is-above 操作符 + 位于上方的操作符 操作符策略 9 操作符策略 12 - does-not-extend-below 操作符 + 不延伸到下方的操作符 操作符策略 10 diff --git a/zh/10/catalogs.sgml b/zh/10/catalogs.sgml index add23efb..fdb05782 100644 --- a/zh/10/catalogs.sgml +++ b/zh/10/catalogs.sgml @@ -369,7 +369,7 @@ - Name + 名称 类型 引用 @@ -573,7 +573,7 @@ - Name + 名称 类型 引用 @@ -644,7 +644,7 @@ - Name + 名称 类型 引用 @@ -787,7 +787,7 @@ - Name + 名称 类型 引用 @@ -878,7 +878,7 @@ - Name + 名称 类型 引用 @@ -960,7 +960,7 @@ - Name + 名称 类型 引用 @@ -1052,7 +1052,7 @@ atttypmod记录了在表创建时提供的类型相关数据(例如一个varchar列的最大长度)。 - 它会被传递给类型相关的输入函数和长度强制函数。对于那些不需要atttypmod的类型,这个值通常总是为-1。 + 它会被传递给类型相关的输入函数和长度强制转换函数。对于那些不需要atttypmod的类型,这个值通常为 -1。 @@ -1089,7 +1089,7 @@ bool - 此列具有一个非空约束(可能尚未验证) + 这代表一个非空约束 @@ -1115,7 +1115,7 @@ bool - 该列被删除且不再有效。一个删除的列仍然物理存在于表中,但是会被分析器忽略并因此无法通过SQL访问。 + 该列被删除且不再有效。一个删除的列仍然物理存在于表中,但是会被解析器忽略并因此无法通过SQL访问。 @@ -1142,7 +1142,7 @@ oid pg_collation.oid - 该列被定义的排序规则,如果该列不是一个可排序数据类型则为0。 + 该列定义的排序规则;如果该列的数据类型不支持排序规则,则为零。 @@ -1151,7 +1151,7 @@ aclitem[] - 列级访问权限, 如果此列上已有特别授予的权限 + 列级访问权限,如果此列上已有特别授予的权限 @@ -1178,9 +1178,7 @@ - 在一个被删除的列的pg_attribute的项中,atttypid被重置为0,但attlen以及其他从pg_type拷贝的域仍然有效。 - 这种安排用于处理一种情况,即被删除列的数据类型后来被删除,并且因此不再有相应的pg_type行。 - attlen和其他域可以被用来解释表的一行的内容。 + 在被删除列的 pg_attribute 条目中,atttypid 被重置为零,但 attlen 以及其他从 pg_type 复制的字段仍然有效。这种安排用于应对被删除列的数据类型后来也被删除、因而不再有相应 pg_type 行的情况。attlen 和其他字段可用于解释表中一行的内容。 @@ -1214,7 +1212,7 @@ - Name + 名称 类型 描述 @@ -1298,21 +1296,21 @@ rolconnlimit int4 - 对于可以登录的角色,本列设置该角色可以同时发起最大连接数。-1表示无限制。 + 对于可以登录的角色,本列设置该角色能够建立的最大并发连接数。-1 表示无限制。 rolpassword text - 密码(可能已加密);如果没有则为空。其格式取决于所使用的加密形式。 + 密码(可能已加密);如果未设置则为空值。其格式取决于所使用的加密方式。 rolvaliduntil timestamptz - 密码过期时间(只用于密码鉴定),如果永不过期则为空 + 密码过期时间(仅用于密码认证);不设过期时间时为空值 @@ -1320,7 +1318,7 @@ - 对于一个MD5加密的密码,rolpassword列将由字符串md5后面跟上一个32字符的十六进制MD5哈希值构成。MD5哈希值将是该用户的密码串接上它们的用户名。例如,如果用户joe的密码是xyzzy,则PostgreSQL将存储xyzzyjoe的md5哈希。 + 对于一个MD5加密的密码,rolpassword列将由字符串md5后面跟上一个32字符的十六进制MD5哈希值构成。MD5 哈希值通过在用户密码后拼接用户名再计算得到。例如,如果用户joe的密码是xyzzy,则PostgreSQL将存储xyzzyjoe的md5哈希。 如果密码使用 SCRAM-SHA-256 加密,其格式为: @@ -1352,7 +1350,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -1416,7 +1414,7 @@ SCRAM-SHA-256$<iteration count>:&l - 需要注意的是,pg_cast并不表示系统知道如何执行的所有类型转换,它只包括那些不能从某些通用规则推导出的转换。例如,一个域及其基类型之间的转换并未显式地在pg_cast中展示。另一个重要的例外是自动的基于 I/O 的类型转换,它们通过数据类型自己的 I/O 函数来转换成(或者转换自)text或其他字符串类型,这些转换也没有显式地在pg_cast中表示。 + 需要注意的是,pg_cast并不表示系统知道如何执行的所有类型转换,它只包括那些不能从某些通用规则推导出的转换。例如,一个域及其基础类型之间的转换并未显式地在pg_cast中展示。另一个重要的例外是自动的基于 I/O 的类型转换,它们通过数据类型自己的 I/O 函数来转换成(或者转换自)text或其他字符串类型,这些转换也没有显式地在pg_cast中表示。 @@ -1425,7 +1423,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -1526,7 +1524,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -1590,7 +1588,7 @@ SCRAM-SHA-256$<iteration count>:&l relam oid pg_am.oid - 如果这是索引,则为使用的访问方法(B-树、哈希等) + 如果这是索引,则为使用的访问方法(B-树、hash 等) @@ -1675,7 +1673,7 @@ SCRAM-SHA-256$<iteration count>:&l char - p = 永久表, u = 不记录 WAL 的表, + p = 永久表,u = 不记录 WAL 的表, t = 临时表 @@ -1783,7 +1781,7 @@ SCRAM-SHA-256$<iteration count>:&l bool - 如果表已被填充则为真(对于所有关系该列都为真,但对于某些物化视图却不是) + 如果关系已被填充则为真(对于所有关系该列都为真,但对于某些物化视图却不是) @@ -1825,7 +1823,7 @@ SCRAM-SHA-256$<iteration count>:&l xid - 在此之前的多事务ID在表中已经被替换为一个事务ID。这被用于跟踪表是否需要被清理,以阻止 + 在此之前的所有多事务ID在表中已经被替换为一个事务ID。这被用于跟踪表是否需要被清理,以阻止 多事务ID回卷或者允许pg_multixact被收缩。如果关系不是一个表则 为0(InvalidMultiXactId)。 @@ -1852,7 +1850,7 @@ SCRAM-SHA-256$<iteration count>:&l pg_node_tree - 如果表示一个分区(见relispartition),则为分区边界的内部表示 + 如果表是一个分区(见relispartition),则为分区边界的内部表示 @@ -1860,7 +1858,7 @@ SCRAM-SHA-256$<iteration count>:&l
- pg_class中的一些逻辑标志被以一种懒惰的方式维护:在正确状态时它们被保证为真,但是当条件不再为真时它们并不会被立刻重置为假。 + pg_class中的一些布尔标志采用延迟维护:当条件成立时,保证它们为真;但当条件不再成立时,可能不会立即将它们重置为假。 例如,relhasindexCREATE INDEX设置,但它从不会被DROP INDEX清除。 作为替代,VACUUM会在找到无索引表后清除其relhasindex。 这种安排避免了竞争条件并且提高了并发性。 @@ -1884,7 +1882,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -1933,9 +1931,10 @@ SCRAM-SHA-256$<iteration count>:&l char - 排序规则提供者:d = 数据库默认值, + 排序规则提供程序:d = 数据库默认值, c = libc, - i = icu + i = icu + @@ -1952,7 +1951,7 @@ SCRAM-SHA-256$<iteration count>:&l name - 此排序规则对象的 LC_COLLATE + 此排序规则对象的 LC_COLLATE @@ -1961,7 +1960,7 @@ SCRAM-SHA-256$<iteration count>:&l name - 此排序规则对象的 LC_CTYPE + 此排序规则对象的 LC_CTYPE
@@ -1970,7 +1969,7 @@ SCRAM-SHA-256$<iteration count>:&l text - 排序规则的提供者相关的版本。这是在排序规则创建时记录下来的,并且在使用排序规则时会被检查以检测可能导致数据损坏的排序规则定义的改变。 + 提供程序特有的排序规则版本。它会在创建排序规则时记录下来,并在使用时接受检查,以检测可能导致数据损坏的排序规则定义更改。
@@ -2015,7 +2014,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -2266,9 +2265,9 @@ SCRAM-SHA-256$<iteration count>:&l - 在一个排他约束的情况中, conkey只对约束元素是单一列引用时有用。 - 对于其他情况,conkey中出现一个0且必须查阅相关索引来发现被约束的表达式。 - (对于索引,conkey因此和pg_index.indkey具有相同的内容)。 + 对于排他约束,conkey仅对作为简单列引用的约束元素有用。 + 对于其他情况,conkey中会出现一个 0,必须查阅关联索引来确定被约束的表达式。 + (因此,conkey与该索引的 pg_index.indkey具有相同的内容。) @@ -2303,7 +2302,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -2412,7 +2411,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -2480,7 +2479,7 @@ SCRAM-SHA-256$<iteration count>:&l bool - 如果为真,则此数据库可被任何具有CREATEDB权限的用户克隆; + 如果为真,则此数据库可被任何具有CREATEDB权限的用户克隆; 如果为假,则只有超级用户或者该数据库的属主能够克隆它。 @@ -2490,7 +2489,7 @@ SCRAM-SHA-256$<iteration count>:&l bool - 如果为假则没有人能连接到这个数据库。这可以用来保护template0数据库不被修改。 + 如果为假则没有人能连接到这个数据库。这可以用来保护template0数据库不被修改。 @@ -2578,7 +2577,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -2637,7 +2636,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -2735,7 +2734,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -2904,7 +2903,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -2973,7 +2972,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -3047,7 +3046,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -3137,7 +3136,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -3244,7 +3243,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -3335,7 +3334,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -3437,7 +3436,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -3497,7 +3496,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -3539,7 +3538,7 @@ SCRAM-SHA-256$<iteration count>:&l bool - 如为真, 这是唯一索引 + 如为真, 这是唯一索引 @@ -3645,7 +3644,7 @@ SCRAM-SHA-256$<iteration count>:&l oidvector pg_collation.oid - 对于索引键中的每一列,这包含要用于该索引的排序规则的OID,如果该列不是一种可排序数据类型则为零。 + 对于索引键中的每一列,这包含要用于该索引的排序规则的OID,如果该列的数据类型不支持排序规则则为零。 @@ -3709,7 +3708,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -3778,7 +3777,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -3856,7 +3855,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -3970,7 +3969,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -4033,7 +4032,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -4089,7 +4088,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -4158,7 +4157,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -4276,7 +4275,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -4446,7 +4445,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -4527,7 +4526,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -4590,7 +4589,7 @@ SCRAM-SHA-256$<iteration count>:&l oidvector pg_opclass.oid - 对于分区键中的每一个列,这个域包含要用于分区的排序规则的OID,如果该列不是一种可排序数据类型则为零。 + 对于分区键中的每一个列,这个域包含要用于分区的排序规则的OID,如果该列的数据类型不支持排序规则则为零。 @@ -4634,7 +4633,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 描述 @@ -4730,7 +4729,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -4843,7 +4842,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -5159,7 +5158,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -5251,7 +5250,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -5300,7 +5299,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -5368,7 +5367,11 @@ SCRAM-SHA-256$<iteration count>:&l - rngsubopc (加上rngcollation,如果元素类型是可排序的)决定了被该范围类型所使用的排序顺序。rngcanonical用于离散类型的元素类型。rngsubdiff是可选的,但是提供它可以提高范围类型上的GiST索引性能。 + rngsubopc(如果元素类型支持排序规则,则还包括 + rngcollation)决定范围类型所用的排序顺序。 + rngcanonical用于元素类型为离散类型的情况。 + rngsubdiff是可选的,但应当提供它, + 以提高范围类型上的 GiST 索引性能。 @@ -5391,7 +5394,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -5440,7 +5443,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -5558,7 +5561,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -5635,7 +5638,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -5745,7 +5748,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -5890,7 +5893,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -5958,7 +5961,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -6019,8 +6022,8 @@ SCRAM-SHA-256$<iteration count>:&l 通常,每个已分析的表列都有一个条目,其中stainherit = false。 - 如果表具有继承子项或分区,则还会创建第二个条目,其中stainherit = true。 - 此行表示继承树上列的统计信息,即您可以通过SELECT column FROM table*看到的数据的统计信息, + 如果表具有继承子表,则还会创建第二个条目,其中stainherit = true。 + 此行表示继承树上列的统计信息,即你可以通过SELECT column FROM table*看到的数据的统计信息, 而stainherit = false行表示SELECT column FROM ONLY table的结果。 @@ -6029,7 +6032,7 @@ SCRAM-SHA-256$<iteration count>:&l
- 因为不同类型的统计信息适用于不同类型的数据, pg_statistic 被设计成不太在意自己存储的是什么类型的统计。 只有极为常用的统计信息(比如NULL的含量)才在pg_statistic里给予专用的字段。 其它所有东西都存储在槽位中,而槽位是一组相关的列, 它们的内容用槽位中的一个列里的代码表示。 更详细的信息请参阅 src/include/catalog/pg_statistic.h。 + 由于不同种类的数据可能适合不同种类的统计信息,pg_statistic 在设计上尽量不对所存储的统计信息种类作出假定。只有极为通用的统计信息(例如空值情况)才在 pg_statistic 中有专用的列。其余统计信息都存储在槽位中。每个槽位都是一组相关的列,其内容由其中一列的代码编号来标识。更多信息见 src/include/catalog/pg_statistic.h @@ -6042,7 +6045,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -6084,7 +6087,7 @@ SCRAM-SHA-256$<iteration count>:&l float4 - 列的项为空的比例 + 列中空值所占的比例 @@ -6102,8 +6105,8 @@ SCRAM-SHA-256$<iteration count>:&l float4 - 列中非空唯一值的数目。一个大于零的值是唯一值的真正数目。 - 一个小于零的值是表中行数的乘数的负值;例如,对于一个 80% 的值为非空且每个非空值平均出现两次的列,可以表示为stadistinct = -0.4。一个0值表示唯一值的数目未知。 + 列中不同非空数据值的数量。一个大于零的值是不同值的真正数目。 + 一个小于零的值是表中行数的乘数的负值;例如,对于一个约 80% 的值为非空且每个非空值平均出现两次的列,可以表示为stadistinct = -0.4。一个0值表示不同值的数目未知。
@@ -6131,7 +6134,7 @@ SCRAM-SHA-256$<iteration count>:&l float4[] - 第N槽位的类型的数值类型统计, 如果该槽位不涉及数值类型则为NULL + 第N槽位中相应种类的数值统计信息;如果该槽位种类不涉及数值,则为 NULL
@@ -6141,7 +6144,7 @@ SCRAM-SHA-256$<iteration count>:&l N槽位的类型的列值,如果该槽位类型不存储任何数据值则为 NULL。 - 每个数组的元素值实际上都是指定列的数据类型或者是一个相关类型(如数组元素类型), 因此,除了把这些列的类型定义成anyarray之外别无他法。 + 每个数组的元素值实际上都是指定列的数据类型或者是一个相关类型(如数组元素类型), 因此,无法把这些列的类型定义得比anyarray更具体。 @@ -6168,7 +6171,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -6288,7 +6291,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -6403,7 +6406,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -6478,7 +6481,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -6552,7 +6555,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -6622,7 +6625,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -6729,7 +6732,7 @@ SCRAM-SHA-256$<iteration count>:&l bool - 如果约束触发器可推迟则为真 + 如果约束触发器可延迟则为真 @@ -6738,7 +6741,7 @@ SCRAM-SHA-256$<iteration count>:&l bool - 如果约束触发器初始可推迟则为真 + 如果约束触发器初始处于延迟状态则为真 @@ -6841,7 +6844,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -6920,7 +6923,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -6992,7 +6995,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -7080,7 +7083,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -7186,7 +7189,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -7253,7 +7256,7 @@ SCRAM-SHA-256$<iteration count>:&l 目录pg_type存储有关数据类型的信息。 - 基类型和枚举类型(标量类型)使用创建,而域使用创建。 + 基础类型和枚举类型(标量类型)使用创建,而域使用创建。 数据库中的每一个表都会有一个自动创建的复合类型,用于表示表的行结构。 也可以使用CREATE TYPE AS创建复合类型。 @@ -7264,7 +7267,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -7336,7 +7339,7 @@ SCRAM-SHA-256$<iteration count>:&l typtype可以是: - b表示一个基类型, + b表示一个基础类型, c表示一个复合类型(例如一个表的行类型), d表示一个域, e表示一个枚举类型, @@ -7557,7 +7560,7 @@ SCRAM-SHA-256$<iteration count>:&l int4 - 域使用typtypmod来记录被应用于它们基类型的typmod(如果基类型不使用typmod,则为-1)。如果此类型不是一个域则为-1。 + 域使用typtypmod来记录被应用于它们基础类型的typmod(如果基础类型不使用typmod,则为-1)。如果此类型不是一个域则为-1。 @@ -7576,8 +7579,8 @@ SCRAM-SHA-256$<iteration count>:&l pg_collation.oid typcollation指定此类型的排序规则。如果类型不支持排序规则,此列为零。 - 支持排序规则的基类型在这里会有DEFAULT_COLLATION_OID。 - 基于可应用排序规则类型的域,如果为其指定了排序规则 OID,则它的排序规则 OID 可以不同于其基类型。 + 支持排序规则的基础类型在这里会有DEFAULT_COLLATION_OID。 + 基于支持排序规则的类型的域,如果为其指定了排序规则 OID,则它的排序规则 OID 可以不同于其基础类型的排序规则 OID。 @@ -7710,7 +7713,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -7958,7 +7961,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 描述 @@ -8026,7 +8029,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 描述 @@ -8127,7 +8130,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 描述 @@ -8195,7 +8198,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 描述 @@ -8292,7 +8295,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 描述 @@ -8384,7 +8387,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -8454,7 +8457,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 描述 @@ -8555,7 +8558,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -8601,7 +8604,7 @@ SCRAM-SHA-256$<iteration count>:&l text - 索引定义(重构出的 CREATE INDEX 命令) + 索引定义(重建出的 CREATE INDEX 命令) @@ -8635,8 +8638,8 @@ SCRAM-SHA-256$<iteration count>:&l 以及一般的数据库对象(由类OID和对象OID标识, 与pg_descriptionpg_depend中的方式相同)。 - 此外,扩展关系的权限被表示为一个单独的可锁定对象,以及更新 - pg_database.datfrozenxid 的更新权限。 + 此外,扩展关系的权利被表示为单独的可锁定对象,更新 + pg_database.datfrozenxid的权利也是如此。 此外,还可以对具有用户定义含义的数字施加咨询锁。 @@ -8646,7 +8649,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -8666,7 +8669,7 @@ SCRAM-SHA-256$<iteration count>:&l oid pg_database.oid - 锁目标存在的数据库的OID,如果目标是一个共享对象则为0,如果目标是一个事务ID则为空 + 锁目标存在的数据库的OID,如果目标是一个共享对象则为0,如果目标是一个事务ID则为 NULL @@ -8674,7 +8677,7 @@ SCRAM-SHA-256$<iteration count>:&l oid pg_class.oid - 作为锁目标的关系的OID,如果目标不是一个关系或者只是关系的一部分则此列为空 + 作为锁目标的关系的OID,如果目标既不是关系,也不是关系的一部分则此列为 NULL @@ -8682,7 +8685,7 @@ SCRAM-SHA-256$<iteration count>:&l integer - 作为锁目标的页在关系中的页号,如果目标不是一个关系页或元组则此列为空 + 作为锁目标的页在关系中的页号,如果目标不是一个关系页或元组则此列为 NULL @@ -8690,7 +8693,7 @@ SCRAM-SHA-256$<iteration count>:&l smallint - 作为锁目标的元组在页中的元组号,如果目标不是一个元组则此列为空 + 作为锁目标的元组在页中的元组号,如果目标不是一个元组则此列为 NULL @@ -8698,7 +8701,7 @@ SCRAM-SHA-256$<iteration count>:&l text - 锁定目标事务的虚拟 ID,如果目标不是虚拟事务 ID,则为空 + 锁定目标事务的虚拟 ID,如果目标不是虚拟事务 ID,则为 NULL @@ -8706,7 +8709,7 @@ SCRAM-SHA-256$<iteration count>:&l xid - 锁定目标事务的标识,如果目标不是事务 ID,则为空 + 锁定目标事务的标识,如果目标不是事务 ID,则为 NULL @@ -8714,7 +8717,7 @@ SCRAM-SHA-256$<iteration count>:&l oid pg_class.oid - 包含锁目标的系统目录的OID,如果目标不是一个普通数据库对象则此列为空 + 包含锁目标的系统目录的OID,如果目标不是一个普通数据库对象则此列为 NULL @@ -8722,7 +8725,7 @@ SCRAM-SHA-256$<iteration count>:&l oid 任意 OID 列 - 锁目标在它的系统目录中的OID,如果目标不是一个普通数据库对象则为空 + 锁目标在它的系统目录中的OID,如果目标不是一个普通数据库对象则为 NULL @@ -8730,7 +8733,7 @@ SCRAM-SHA-256$<iteration count>:&l smallint - 锁的目标列号(classidobjid指表本身),如果目标是某种其他普通数据库对象则此列为0,如果目标不是一个普通数据库对象则此列为空 + 锁的目标列号(classidobjid指表本身),如果目标是某种其他普通数据库对象则此列为0,如果目标不是一个普通数据库对象则此列为 NULL @@ -8746,7 +8749,7 @@ SCRAM-SHA-256$<iteration count>:&l integer - 保持这个锁或者正在等待这个锁的服务器进程的PID,如果此锁被一个预备事务所持有则此列为空 + 保持这个锁或者正在等待这个锁的服务器进程的PID,如果此锁被一个预备事务所持有则此列为 NULL @@ -8797,8 +8800,8 @@ SCRAM-SHA-256$<iteration count>:&l 咨询锁可以在由单个 bigint 值或两个整数值组成的键上获取。 - 一个bigint键在classid列中显示其高阶半部分, - 在objid列中显示其低阶半部分,并且objsubid等于1。 + 一个bigint键在classid列中显示其高位半部分, + 在objid列中显示其低位半部分,并且objsubid等于1。 可以使用表达式(classid::bigint << 32) | objid::bigint重新组装原始bigint值。 整数键在classid列中显示第一个键,在objid列中显示第二个键, 并且 objsubid 等于 2。键的实际含义由用户自行决定。咨询锁在每个数据库内都是本地的, @@ -8842,15 +8845,15 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx pg_locks视图显示来自常规锁管理器和谓词锁管理器的数据,这两个是独立的系统; - 此外,常规锁管理器将其锁分为常规锁和fast-path锁。 + 此外,常规锁管理器将其锁分为常规锁和快速路径锁。 不能保证这些数据完全一致。 当查询该视图时, - fast-path 锁的数据(具有fastpath = true) + 快速路径锁的数据(具有fastpath = true) 从每个后端逐个收集,而不会冻结整个锁管理器的状态,因此在收集信息时可能会发生锁的获取或释放。 但请注意,这些锁已知不会与当前放置的任何其他锁发生冲突。 - 在查询所有后端的 fast-path 锁后,剩余的常规锁管理器将作为一个单元被锁定,并且所有剩余锁的一致快照将作为一个原子操作收集。 + 在查询所有后端的快速路径锁后,剩余的常规锁管理器将作为一个单元被锁定,并且所有剩余锁的一致快照将作为一个原子操作收集。 解锁常规锁管理器后,谓词锁管理器类似地被锁定,并且所有谓词锁将作为一个原子操作收集。 - 因此,除了 fast-path 锁外,每个锁管理器将提供一致的结果集,但由于我们不同时锁定两个锁管理器,因此在询问常规锁管理器后和在询问谓词锁管理器前,可能会发生锁的获取或释放。 + 因此,除了快速路径锁外,每个锁管理器将提供一致的结果集,但由于我们不同时锁定两个锁管理器,因此在询问常规锁管理器后和在询问谓词锁管理器前,可能会发生锁的获取或释放。 @@ -8881,7 +8884,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - Name + 名称 类型 引用 @@ -8943,7 +8946,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx text - 物化视图的定义(一个重构的SELECT查询) + 物化视图的定义(一个重建的SELECT查询) @@ -8969,7 +8972,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - Name + 名称 类型 引用 @@ -9072,7 +9075,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - Name + 名称 类型 描述 @@ -9147,7 +9150,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - Name + 名称 类型 引用 @@ -9227,7 +9230,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - Name + 名称 类型 引用 @@ -9287,7 +9290,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - Name + 名称 类型 引用 @@ -9359,7 +9362,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - Name + 名称 类型 引用 @@ -9426,7 +9429,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx boolean - 如果该槽当前正被用于流送则为真 + 如果该槽当前正在使用中则为真 @@ -9435,7 +9438,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx integer - 为该槽流送数据的会话的进程 ID。NULL 表示不活动。 + 如果该槽当前正在使用中,则为使用该槽的会话的进程 ID;不活动时为 NULL @@ -9469,7 +9472,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx pg_lsn - 逻辑槽消费者已确认接收到数据的地址(LSN)。早于此地址的数据将不再可用。物理槽为 NULL。 + 逻辑槽消费者已确认接收的数据所到达的地址(LSN)。早于此地址的数据将不再可用。物理槽为 NULL @@ -9487,7 +9490,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx 视图pg_roles提供数据库角色的信息。它本质上是 - pg_authid 的公开可读视图,并将密码字段清空。 + pg_authid 的公开可读视图,并隐藏密码字段。 此视图显式显示底层表的 OID 列,因为与其他目录连接时需要此列。 @@ -9498,7 +9501,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - Name + 名称 类型 引用 @@ -9576,7 +9579,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx int4 - 对于可以登录的角色,本列设置该角色可以同时发起最大连接数。-1表示无限制。 + 对于可以登录的角色,本列设置该角色能够建立的最大并发连接数。-1 表示无限制。 @@ -9594,7 +9597,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx timestamptz - 密码过期时间(只用于密码认证),如果永不过期则为空 + 密码过期时间(仅用于密码认证);不设过期时间时为空值 @@ -9647,7 +9650,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - Name + 名称 类型 引用 @@ -9685,7 +9688,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx text - 规则定义(创建命令的重构) + 规则定义(重建的创建命令) @@ -9718,7 +9721,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - Name + 名称 类型 引用 @@ -9813,7 +9816,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - Name + 名称 类型 引用 @@ -9935,7 +9938,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - Name + 名称 类型 描述 @@ -10186,7 +10189,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx 这个名称源于该表不应向公众开放读取,因为它包含密码。 pg_user - 是 pg_shadow 的公开可读视图,并将密码字段清空。 + 是 pg_shadow 的公开可读视图,并隐藏密码字段。 @@ -10195,7 +10198,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - Name + 名称 类型 引用 @@ -10263,7 +10266,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx passwd text - 密码(可能已加密);如果没有则为空。关于加密密码的存储方式,详见pg_authid + 密码(可能已加密);如果未设置则为空值。关于加密密码的存储方式,详见pg_authid @@ -10313,7 +10316,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - Name + 名称 类型 引用 @@ -10479,7 +10482,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - Name + 名称 类型 引用 @@ -10573,7 +10576,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - Name + 名称 类型 描述 @@ -10637,7 +10640,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - Name + 名称 类型 描述 @@ -10688,7 +10691,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx 视图pg_user提供数据库用户的信息。它本质上是 - pg_shadow 的公开可读视图,并将密码字段清空。 + pg_shadow 的公开可读视图,并隐藏密码字段。
@@ -10697,7 +10700,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - Name + 名称 类型 描述 @@ -10801,7 +10804,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - Name + 名称 类型 引用 @@ -10907,7 +10910,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - Name + 名称 类型 引用 @@ -10945,7 +10948,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx text - 视图定义(一个重构的SELECT查询) + 视图定义(一个重建的SELECT查询) diff --git a/zh/10/charset.sgml b/zh/10/charset.sgml index 62fd00b3..9e222628 100644 --- a/zh/10/charset.sgml +++ b/zh/10/charset.sgml @@ -29,7 +29,7 @@ 区域设置支持 - locale + 区域设置 区域设置支持是指应用程序在字母表、排序、数字格式等 @@ -71,7 +71,7 @@ initdb --locale=sv_SE Swedish_Sweden.1252,但原则是相同的。 - 偶尔需要混合几个区域设置的规则,例如使用英语排序规则和西班牙语消息。为此,系统提供了一组区域设置子类别,分别控制本地化规则的某些方面: LC_COLLATE 字符串排序顺序 LC_CTYPE 字符分类(什么是字母?它对应的大写形式是什么?) LC_MESSAGES 消息语言 LC_MONETARY 货币金额格式 LC_NUMERIC 数字格式 LC_TIME 日期和时间格式 这些类别名称对应于 initdb 选项的名称,可覆盖某个特定类别的区域设置选择。例如,要将区域设置设为加拿大法语,但使用美国的货币格式规则,可使用 initdb --locale=fr_CA --lc-monetary=en_US。 + 有时混合多个区域设置的规则会很有用,例如使用英语排序规则但使用西班牙语消息。为此,存在一组只控制本地化规则某些方面的区域设置子类别: LC_COLLATE 字符串排序顺序 LC_CTYPE 字符分类(什么算字母?它的大写等价形式是什么?) LC_MESSAGES 消息的语言 LC_MONETARY 货币数量使用的格式 LC_NUMERIC 数字的格式 LC_TIME 日期和时间的格式 这些类别名会转换成initdb选项名,用于覆盖特定类别的区域设置选择。例如,要将区域设置设为加拿大法语,但对货币格式采用美国规则,可以使用initdb --locale=fr_CA --lc-monetary=en_US 如果希望系统表现得像没有区域设置支持一样,可使用特殊区域设置名 @@ -115,7 +115,7 @@ initdb --locale=sv_SE 某些消息本地化库还会查看环境变量LANGUAGE,它会覆盖所有 - 其他用于设置消息语言的区域设置。如果有疑问,请参考操作系统文档,尤其是 + 其他用于设置消息的语言的区域设置。如果有疑问,请参考操作系统文档,尤其是 关于gettext的文档。 @@ -157,7 +157,7 @@ initdb --locale=sv_SE 以及 POSIX 风格正则表达式);区域设置既会影响大小写不敏感匹配,也会 影响字符类正则表达式中的字符分类 LIKE与区域设置 - regular expressions与区域设置 + 正则表达式与区域设置 @@ -246,10 +246,10 @@ initdb --locale=sv_SE 概念 - 从概念上讲,每个可排序数据类型的表达式都有一个排序规则。(内置的可排序 - 数据类型包括textvarcharchar。 - 用户定义的基本类型也可以标记为可排序,当然,建立在可排序数据类型之上的 - 域也是可排序的。) + 从概念上讲,每个支持排序规则的数据类型的表达式都有一个排序规则。 + (内置的支持排序规则的数据类型包括textvarcharchar。 + 用户定义的基础类型也可以标记为支持排序规则,当然,建立在支持排序规则的数据类型之上的 + 域也支持排序规则。) 如果表达式是列引用,则该表达式的排序规则就是该列定义的排序规则。如果表 达式是常量,则其排序规则就是该常量数据类型的默认排序规则。更复杂表达式 的排序规则则按下文所述,从其输入表达式的排序规则推导出来。 @@ -274,7 +274,7 @@ initdb --locale=sv_SE 对于函数或操作符调用,通过检查参数排序规则推导出的排序规则,会在运行时 - 用于执行指定操作。如果该函数或操作符调用的结果属于可排序数据类型,那么 + 用于执行指定操作。如果该函数或操作符调用的结果属于支持排序规则的数据类型,那么 在解析时它也会被用作该函数或操作符表达式的已定义排序规则,以便在外围表 达式需要知道其排序规则时使用。 @@ -356,7 +356,7 @@ SELECT a || b FROM test1; - 如果函数或操作符返回的是可排序数据类型,那么分配给该函数或操作符组合输 + 如果函数或操作符返回的是支持排序规则的数据类型,那么分配给该函数或操作符组合输 入表达式的排序规则,也被认为适用于其结果。因此,在 SELECT * FROM test1 ORDER BY a || 'foo'; @@ -402,8 +402,7 @@ SELECT * FROM test1 ORDER BY a || b COLLATE "fr_FR"; - 由icu提供的排序规则对象,对应于 ICU 库提供的具名整 - 理器。ICU 不支持将collatectype分开设 + 由icu提供的排序规则对象,对应于 ICU 库提供的具名排序器。ICU 不支持将collatectype分开设 置,因此二者总是相同的。此外,ICU 排序规则与编码无关,因此在一个数据库 中,某个给定名称的 ICU 排序规则始终只有一个。 @@ -492,7 +491,7 @@ SELECT a COLLATE "C" < b COLLATE "POSIX" FROM test1; -x-icu,以便与 libc 区域设置区分开来。 - 以下是可能创建的排序规则示例: + 下面是一些可能创建出来的排序规则示例: de-x-icu @@ -578,7 +577,7 @@ CREATE COLLATION german (provider = libc, locale = 'de_DE'); CREATE COLLATION "de-u-co-phonebk-x-icu" (provider = icu, locale = 'de-u-co-phonebk'); CREATE COLLATION "de-u-co-phonebk-x-icu" (provider = icu, locale = 'de@collation=phonebook'); - 采用电话簿排序类型的德语排序规则 + 德语排序规则,电话簿排序类型 第一个示例使用 BCP 47 定义的语言标签来选择 ICU 区域设置。第二个示例使用传统的 ICU 专有区域设置语法。今后应优先采用第一种形式,但较旧的 ICU 版本不支持它。 注意,可以在 SQL 环境中为排序规则对象任意命名。本例遵循预定义排序规则所采用的命名风格,该风格也遵循 BCP 47,但用户定义的排序规则并不要求如此。 @@ -588,7 +587,9 @@ CREATE COLLATION german (provider = libc, locale = 'de_DE'); CREATE COLLATION "und-u-co-emoji-x-icu" (provider = icu, locale = 'und-u-co-emoji'); CREATE COLLATION "und-u-co-emoji-x-icu" (provider = icu, locale = '@collation=emoji'); - 采用 Unicode 技术标准 #51 所定义 Emoji 排序类型的根排序规则 + + 根排序规则,表情符号排序类型,依据 Unicode 技术标准 #51 + 注意,传统的 ICU 区域设置命名系统使用空字符串来选择根区域设置。 @@ -597,7 +598,9 @@ CREATE COLLATION german (provider = libc, locale = 'de_DE'); CREATE COLLATION latinlast (provider = icu, locale = 'en-u-kr-grek-latn'); CREATE COLLATION latinlast (provider = icu, locale = 'en@colReorder=grek-latn'); - 将希腊字母排在拉丁字母之前。(默认是拉丁字母在希腊字母之前。) + + 将希腊字母排在拉丁字母之前。(默认情况下是拉丁字母排在希腊字母之前。) + @@ -605,7 +608,9 @@ CREATE COLLATION german (provider = libc, locale = 'de_DE'); CREATE COLLATION upperfirst (provider = icu, locale = 'en-u-kf-upper'); CREATE COLLATION upperfirst (provider = icu, locale = 'en@colCaseFirst=upper'); - 将大写字母排在小写字母之前。(默认是小写字母在前。) + + 将大写字母排在小写字母之前。(默认情况下是小写字母在前。) + @@ -613,7 +618,9 @@ CREATE COLLATION german (provider = libc, locale = 'de_DE'); CREATE COLLATION special (provider = icu, locale = 'en-u-kf-upper-kr-grek-latn'); CREATE COLLATION special (provider = icu, locale = 'en@colCaseFirst=upper;colReorder=grek-latn'); - 组合上述两个选项。 + + 结合了以上两个选项。 + diff --git a/zh/10/client-auth.sgml b/zh/10/client-auth.sgml index 6bb389ee..58e66b4b 100644 --- a/zh/10/client-auth.sgml +++ b/zh/10/client-auth.sgml @@ -37,7 +37,14 @@ pg_hba.conf - 客户端认证由一个配置文件控制,该文件通常名为 pg_hba.conf,存储在数据库集簇的数据目录中。(HBA 表示基于主机的认证。)initdb 初始化数据目录时,会安装一个默认的 pg_hba.conf 文件。不过,也可以将认证配置文件放在其他位置;参见 配置参数。 + + 客户端认证由一个配置文件控制,该文件按惯例命名为 + pg_hba.conf,并存放在数据库集簇的数据目录中。 + (HBA 代表 host-based authentication,即基于主机的认证。) + 当数据目录由 initdb 初始化时,会安装一个默认的 + pg_hba.conf 文件。不过,也可以把认证配置文件放在别处; + 请参见配置参数 。 + pg_hba.conf 文件的基本格式是一组记录,每行一条。空行和 # 注释字符之后的所有文本都会被忽略。记录不能跨行续写。每条记录由若干字段组成,字段之间用空格和/或制表符分隔。如果字段值用双引号括起来,就可以包含空白。在数据库、用户或地址字段中,将关键字(例如 allreplication)用引号括起来,会使其失去特殊含义,只匹配同名的数据库、用户或主机。 @@ -133,7 +140,7 @@ hostnossl database user IP地址范围使用标准的数字表示法来指定起始地址,然后是斜杠(/)和一个CIDR掩码长度。 掩码长度表示客户端IP地址必须匹配的高位比特数。给定IP地址中右侧的比特应为零。 - IP地址、/和CIDR掩码长度之间不得有任何空格。 + IP地址、/和CIDR掩码长度之间不得有任何空白。 @@ -170,12 +177,12 @@ hostnossl database user 以点(.)开头的主机名规范匹配实际主机名的后缀。 因此,.example.com将匹配foo.example.com - (但不仅仅是example.com)。 + (但不匹配单独的example.com)。 当在pg_hba.conf中指定主机名时,应确保名称解析相对快速。 - 最好设置一个本地名称解析缓存,如nscd。 + 设置一个本地名称解析缓存可能会有帮助,如nscd。 此外,还可能希望启用配置参数log_hostname,以便在日志中看到客户端的主机名而不是 IP 地址。 @@ -185,7 +192,7 @@ hostnossl database user 用户有时会想知道为什么主机名以这种看似复杂的方式处理,包括两次名称解析,其中包括对客户端IP地址的反向查找。 - 如果客户端的反向DNS条目未设置或生成了一些不良的主机名,则使用该功能会变得复杂。 + 如果客户端的反向DNS条目未设置或返回了不符合预期的主机名,则使用该功能会变得复杂。 这主要是为了效率:这样,连接尝试最多需要两次解析器查找,一次反向查找和一次正向查找。 如果某个地址存在解析器问题,那就只会成为该客户端的问题。 一个假设的替代实现只进行正向查找的情况下,在每次连接尝试期间都必须解析pg_hba.conf中提到的每个主机名。 @@ -200,7 +207,7 @@ hostnossl database user 请注意,这种行为与其他流行的基于主机名的访问控制实现一致,例如 - Apache HTTP服务器和TCP包装器。 + Apache HTTP 服务器和 TCP Wrappers。 @@ -211,7 +218,7 @@ hostnossl database user IP-mask - 这两个字段可以用作IP地址/掩码长度 + 这两个字段可以用作IP-address/mask-length 表示法的替代方案。而不是指定掩码长度,实际掩码在一个单独的列中指定。 例如,255.0.0.0表示IPv4的CIDR掩码长度为8, 而255.255.255.255表示CIDR掩码长度为32。 @@ -224,7 +231,10 @@ hostnossl database user auth-method - 指定连接匹配此记录时使用的认证方法。这里概述可用的选项;详情参见 。所有选项都使用小写且区分大小写,因此即使是 ldap 这样的缩写,也必须使用小写。 + + 指定连接匹配此记录时要使用的认证方法。可选值在此处做了概述;详细说明见 。所有选项都必须使用小写并且区分大小写,因此即使是像 ldap 这样的首字母缩写也必须写成小写。 + + trust @@ -398,14 +408,14 @@ hostnossl database user 由于每次连接尝试都会按顺序检查 pg_hba.conf 记录,因此记录的顺序很重要。通常,靠前的记录使用较严格的连接匹配条件和较弱的认证方法,靠后的记录使用较宽松的匹配条件和较强的认证方法。例如,可能希望对本地 TCP/IP 连接使用 trust 认证,而要求远程 TCP/IP 连接提供密码。此时,为来自 127.0.0.1 的连接指定 trust 认证的记录,应放在为更大范围的允许客户端 IP 地址指定密码认证的记录之前。 - 在启动以及主服务器进程收到SIGHUPSIGHUP信号时,pg_hba.conf文件会被读取。 - 如果你在活动的系统上编辑了该文件,你将需要通知 postmaster(使用pg_ctl reload,调用SQL函数pg_reload_conf(),或使用kill -HUP)使其重新读取该文件。 + 在启动时以及主服务器进程收到 SIGHUPSIGHUP 信号时,pg_hba.conf 文件会被读取。 + 如果你在运行中的系统上编辑了该文件,就需要通知 postmaster(使用 pg_ctl reload、调用 SQL 函数 pg_reload_conf(),或者使用 kill -HUP)重新读取该文件。 - 前面的说明在Microsoft Windows上不为真:在Windows上,pg_hba.conf文件中的任何更改会立即被应用到后续的新连接上。 + 前面的说明不适用于 Microsoft Windows:在Windows上,pg_hba.conf文件中的任何更改会立即被应用到后续的新连接上。 @@ -425,92 +435,88 @@ hostnossl database user 示例 <filename>pg_hba.conf</filename> 项 -# Allow any user on the local system to connect to any database with -# any database user name using Unix-domain sockets (the default for local -# connections). +# 允许本地系统上的任何用户 +# 通过 Unix 域套接字(本地连接的默认方式)以任意 +# 数据库用户名连接到任意数据库。 # # TYPE DATABASE USER ADDRESS METHOD local all all trust -# The same using local loopback TCP/IP connections. +# 相同的规则,但是使用本地环回 TCP/IP 连接。 # # TYPE DATABASE USER ADDRESS METHOD host all all 127.0.0.1/32 trust -# The same as the previous line, but using a separate netmask column +# 和前一行相同,但是使用了一个独立的掩码列 # # TYPE DATABASE USER IP-ADDRESS IP-MASK METHOD host all all 127.0.0.1 255.255.255.255 trust -# The same over IPv6. +# IPv6 上相同的规则 # # TYPE DATABASE USER ADDRESS METHOD host all all ::1/128 trust -# The same using a host name (would typically cover both IPv4 and IPv6). +# 使用主机名的相同规则(通常同时覆盖 IPv4 和 IPv6)。 # # TYPE DATABASE USER ADDRESS METHOD host all all localhost trust -# Allow any user from any host with IP address 192.168.93.x to connect -# to database "postgres" as the same user name that ident reports for -# the connection (typically the operating system user name). +# 允许来自任意具有 IP 地址192.168.93.x 的主机上任意 +# 用户以 ident 为该连接所报告的相同用户名连接到 +# 数据库 "postgres"(通常是操作系统用户名)。 # # TYPE DATABASE USER ADDRESS METHOD host postgres all 192.168.93.0/24 ident -# Allow any user from host 192.168.12.10 to connect to database -# "postgres" if the user's password is correctly supplied. +# 如果用户的密码被正确提供,允许来自主机 192.168.12.10 +# 的任意用户连接到数据库 "postgres"。 # # TYPE DATABASE USER ADDRESS METHOD host postgres all 192.168.12.10/32 scram-sha-256 -# Allow any user from hosts in the example.com domain to connect to -# any database if the user's password is correctly supplied. +# 如果用户的密码被正确提供,允许 example.com 域中主机上 +# 的任意用户连接到任意数据库。 # -# Require SCRAM authentication for most users, but make an exception -# for user 'mike', who uses an older client that doesn't support SCRAM -# authentication. +# 为大部分用户要求SCRAM认证,但是用户'mike'是个例外, +# 他使用的是不支持SCRAM认证的旧客户端。 # # TYPE DATABASE USER ADDRESS METHOD host all mike .example.com md5 host all all .example.com scram-sha-256 -# In the absence of preceding "host" lines, these two lines will -# reject all connections from 192.168.54.1 (since that entry will be -# matched first), but allow GSSAPI connections from anywhere else -# on the Internet. The zero mask causes no bits of the host IP -# address to be considered, so it matches any host. +# 如果没有前面的 "host" 行,这两行将拒绝所有来自 192.168.54.1 的 +# 连接(因为该条目会先被匹配),但允许来自互联网其他任何位置的 +# GSSAPI 连接。零掩码表示不考虑主机 IP 地址中的任何位, +# 因而会匹配任意主机。 # # TYPE DATABASE USER ADDRESS METHOD host all all 192.168.54.1/32 reject host all all 0.0.0.0/0 gss -# Allow users from 192.168.x.x hosts to connect to any database, if -# they pass the ident check. If, for example, ident says the user is -# "bryanh" and he requests to connect as PostgreSQL user "guest1", the -# connection is allowed if there is an entry in pg_ident.conf for map -# "omicron" that says "bryanh" is allowed to connect as "guest1". +# 允许来自 192.168.x.x 主机的用户连接到任意数据库,如果它们能够 +# 通过 ident 检查。例如,假设 ident说用户是 "bryanh" 并且他要求以 +# PostgreSQL 用户 "guest1" 连接,如果在 pg_ident.conf 有一个映射 +# "omicron" 的条目表明 "bryanh" 被允许以 "guest1" 连接,则该连接将被允许。 # # TYPE DATABASE USER ADDRESS METHOD host all all 192.168.0.0/16 ident map=omicron -# If these are the only three lines for local connections, they will -# allow local users to connect only to their own databases (databases -# with the same name as their database user name) except for administrators -# and members of role "support", who can connect to all databases. The file -# $PGDATA/admins contains a list of names of administrators. Passwords -# are required in all cases. +# 如果这些是本地连接的唯一三行,它们将允许本地用户只连接到 +# 自己的数据库(与其数据库用户名同名的数据库),但管理员和 +# 角色 "support" 的成员除外,他们可以连接到所有数据库。 +# 文件 $PGDATA/admins 包含管理员名称列表。 +# 所有情况下都要求提供密码。 # # TYPE DATABASE USER ADDRESS METHOD local sameuser all md5 local all @admins md5 local all +support md5 -# The last two lines above can be combined into a single line: +# 上面的最后两行可以被整合为一行: local all @admins,+support md5 -# The database column can also use lists and file names: +# 数据库列也可以用列表和文件名: local db1,db2,@demodbs all md5 @@ -582,16 +588,14 @@ omicron bryanh guest1 - trust认证对于单用户工作站的本地连接是非常合适和方便的。通常它本身适用于一台多用户机器。不过,只要你利用文件系统权限限制了对服务器的 Unix 域套接字文件的访问,即使在多用户机器上,你也可以使用trust。 要做这些限制,你可以设置中描述的unix_socket_permissions配置参数(可能还有unix_socket_group)。 或者你可以设置unix_socket_directories配置参数来把 Unix 域套接字文件放在一个经过恰当限制的目录中。 + trust认证对于单用户工作站的本地连接是非常合适和方便的。通常它本身适用于一台多用户机器。不过,只要你利用文件系统权限限制了对服务器的 Unix 域套接字文件的访问,即使在多用户机器上,你也可能可以使用trust。 要做这些限制,你可以设置中描述的unix_socket_permissions配置参数(可能还有unix_socket_group)。 或者你可以设置unix_socket_directories配置参数来把 Unix 域套接字文件放在一个经过恰当限制的目录中。 设置文件系统权限只能有助于 Unix 套接字连接。本地 TCP/IP 连接不会被文件系统权限限制。因此,如果你想利用文件系统权限来控制本地安全,那么从pg_hba.conf中移除host ... 127.0.0.1 ...行,或者把它改为一个非trust认证方法。 - - 如果通过指定trustpg_hba.conf行让你信任每一个被允许连接到服务器的机器上的用户,trust认证只适合 TCP/IP 连接。为任何不是来自localhost(127.0.0.1)的 TCP/IP 连接使用trust很少是合理的。 - + 只有当你信任由 pg_hba.conf 中指定 trust 的行所允许连接的每台机器上的每个用户时,trust 认证才适合用于 TCP/IP 连接。对来自 localhost(127.0.0.1)以外的任何 TCP/IP 连接使用 trust,通常都不合理。 @@ -632,11 +636,9 @@ omicron bryanh guest1 md5 - - 方法md5使用一种自定义的安全性较低的挑战-响应机制。它能防止密码嗅探并且防止密码在服务器上以明文存储,但是无法保护攻击者想办法从服务器上窃取了密码哈希的情况。此外,现在认为MD5哈希算法对于确定攻击已经不再安全。 - + 方法md5使用一种自定义的、安全性较低的挑战-响应机制。它能防止密码嗅探,并避免在服务器上以明文存储密码;但如果攻击者设法从服务器上窃取了密码哈希,它就无法提供保护。此外,如今已不再认为 MD5 哈希算法能抵御有决心的攻击者。 - md5 方法不能与 功能一起使用。 + md5方法不能与功能一起使用。 为了简化从md5方法到较新的SCRAM方法的转变,如果在pg_hba.conf中指定了md5但是用户在服务器上的密码是为SCRAM(见下文)加密的,则将自动选择基于SCRAM的认证。 @@ -662,7 +664,7 @@ omicron bryanh guest1 - 要把现有安装从 md5 升级到 scram-sha-256,需要先确保所有正在使用的客户端库都足够新并支持 SCRAM,然后在 postgresql.conf 中设置 password_encryption = 'scram-sha-256',要求所有用户重新设置密码,并将 pg_hba.conf 中的认证方法说明改为 scram-sha-256。 + 要把现有安装从 md5 升级到 scram-sha-256,需要先确保所有正在使用的客户端库都足够新并支持 SCRAM,然后在 postgresql.conf 中设置 password_encryption = 'scram-sha-256',要求所有用户重新设置密码,并将 pg_hba.conf 中的认证方法设置改为 scram-sha-256 @@ -680,11 +682,11 @@ omicron bryanh guest1 GSSAPI 使用 Kerberos 时,采用格式为 servicename/hostname@realm 的标准主体。PostgreSQL 服务器会接受其所用 keytab 中包含的任何主体,但客户端建立连接时,必须注意通过 krbsrvname 连接参数指定正确的主体信息。(另见 。)构建时可以使用 ./configure --with-krb-srvnam=whatever,将安装默认值从 postgres 改为其他值。在大多数环境中,无需更改此参数。某些 Kerberos 实现可能要求不同的服务名,例如 Microsoft Active Directory 要求服务名使用大写(POSTGRES)。 - hostname 是服务器机器的完全限定主机名。服务主体的域是服务器机器的首选域。 + hostname 是服务器机器的完全限定主机名。服务主体的 realm 是服务器机器的首选 realm。 可以通过 pg_ident.conf 将客户端主体映射到不同的 PostgreSQL 数据库用户名。例如,可以将 pgusername@realm 映射为 pgusername。也可以不使用任何映射,直接将完整的 username@realm 主体用作 PostgreSQL 中的角色名。 - PostgreSQL 还支持一个从主体中去掉域的参数。提供这种方法是为了向后兼容,强烈不建议使用,因为这样就无法区分来自不同域但用户名相同的用户。要启用此行为,将 include_realm 设为 0。对于简单的单域安装环境,如果同时设置 krb_realm 参数(它会检查主体的域是否与 krb_realm 参数值完全一致),这种做法仍是安全的;但与在 pg_ident.conf 中指定显式映射相比,它的能力较弱。 + PostgreSQL 还支持一个从主体中去掉 realm 的参数。提供这种方法是为了向后兼容,强烈不建议使用,因为这样就无法区分来自不同 realm 但用户名相同的用户。要启用此行为,将 include_realm 设为 0。对于简单的单 realm 安装环境,如果同时设置 krb_realm 参数(它会检查主体的 realm 是否与 krb_realm 参数值完全一致),这种做法仍是安全的;但与在 pg_ident.conf 中指定显式映射相比,它的能力较弱。 确保 PostgreSQL 服务器账户能够读取服务器的 keytab 文件(最好只能读取,不能写入)。(另见 。)密钥文件的位置由 配置参数指定。默认位置是 /usr/local/pgsql/etc/krb5.keytab(或者构建时用 sysconfdir 指定的目录)。出于安全考虑,建议为 PostgreSQL 服务器使用专用 keytab,而不是放宽系统 keytab 文件的权限。 keytab 文件由 Kerberos 软件生成;详情参见 Kerberos 文档。以下示例适用于兼容 MIT 的 Kerberos 5 实现: @@ -740,14 +742,17 @@ omicron bryanh guest1 当使用Kerberos认证时,SSPIGSSAPI的工作方式相同,详见 - 以下配置选项适用于 SSPI: + + SSPI 支持下列配置选项: include_realm - 如果设为 0,则在通过用户名映射()之前,会先从已认证用户的主体名中去掉 realm 名称。不建议这样做;它主要是为了向后兼容而保留的,因为在多 realm 环境中这并不安全,除非同时使用了 krb_realm。建议将 include_realm 保持为默认值(1),并在 pg_ident.conf 中提供显式映射,把主体名转换成 PostgreSQL 用户名。 + 如果设为 0,则在通过用户名映射()之前,会先从已认证用户的主体名中去掉 realm 名称。 + 不建议这样做;它主要是为了向后兼容而保留的,因为在多 realm 环境中这并不安全,除非同时使用了 krb_realm。 + 建议将 include_realm 保持为默认值(1),并在 pg_ident.conf 中提供显式映射,把主体名转换成 PostgreSQL 用户名。 @@ -759,7 +764,7 @@ omicron bryanh guest1 如果设为 1,则会在 include_realm 选项中使用域的 SAM 兼容名称(也称为 NetBIOS 名称)。这是默认值。如果设为 0,则会使用 Kerberos 用户主体名中的真实 realm 名称。 - 不要禁用这个选项,除非你的服务器运行在一个域账号(这包括一个域成员系统上的虚拟服务账号)下并且所有通过 SSPI 认证的所有客户端也在使用域账号,否则认证将会失败。 + 不要禁用这个选项,除非你的服务器运行在一个域账号(这包括一个域成员系统上的虚拟服务账号)下并且所有通过 SSPI 认证的客户端也在使用域账号,否则认证将会失败。 @@ -779,7 +784,10 @@ omicron bryanh guest1 map - 允许在系统用户名与数据库用户名之间建立映射。详见 。对于 username@EXAMPLE.COM(或较少见的 username/hostbased@EXAMPLE.COM)这样的 SSPI/Kerberos 主体,映射所用的用户名是 username@EXAMPLE.COM(或相应的 username/hostbased@EXAMPLE.COM),除非将 include_realm 设为 0,此时映射所见的系统用户名为 username(或 username/hostbased)。 + + 允许在系统用户名和数据库用户名之间进行映射。详见 。 + 对于 SSPI/Kerberos 主体,例如 username@EXAMPLE.COM(或者较少见的 username/hostbased@EXAMPLE.COM),用于映射的用户名分别是 username@EXAMPLE.COM(或 username/hostbased@EXAMPLE.COM),除非已经将 include_realm 设为 0;在那种情况下,映射时视为系统用户名的是 username(或 username/hostbased)。 + @@ -819,7 +827,7 @@ omicron bryanh guest1 map - 允许在系统用户和数据库用户名称之间进行映射。详细信息请参见。 + 允许在系统用户名和数据库用户名之间进行映射。详见 @@ -833,7 +841,7 @@ omicron bryanh guest1
RFC 1413 - 标识协议的本意不是作为一种认证或访问控制协议。 + 标识协议的本意不是作为一种授权或访问控制协议。
@@ -860,7 +868,7 @@ omicron bryanh guest1 map - 允许在系统用户和数据库用户名称之间进行映射。详细信息请参见。 + 允许在系统用户名和数据库用户名之间进行映射。详见 @@ -880,14 +888,16 @@ omicron bryanh guest1 LDAP - 这种认证方法与 password 类似,只是使用 LDAP 验证密码。LDAP 仅用于验证用户名与密码的组合。因此,必须先在数据库中创建该用户,才能使用 LDAP 进行认证。 + + 这种认证方法的工作方式与 password 类似,只不过它使用 LDAP 作为密码验证方法。LDAP 只用于验证用户名/密码对。因此,在使用 LDAP 进行认证之前,用户必须已经存在于数据库中。 + LDAP 认证可以在两种模式下工作。第一种模式称为简单绑定模式,服务器会绑定到按 prefix username suffix 形式构造出的可分辨名称。通常,prefix 参数用于指定 cn=,或在 Active Directory 环境中指定 DOMAIN\suffix 则用于指定非 Active Directory 环境中 DN 的剩余部分。 - 第二种模式称为搜索+绑定模式,服务器首先使用由 ldapbinddnldapbindpasswd 指定的固定用户名和密码绑定到 LDAP 目录,并搜索试图登录数据库的用户。如果没有配置用户名和密码,则会尝试对目录进行匿名绑定。搜索会在 ldapbasedn 指定的子树上进行,并尝试对 ldapsearchattribute 指定的属性做精确匹配。一旦在搜索中找到了该用户,服务器就会作为该用户重新绑定到目录,并使用客户端指定的密码来验证登录是否正确。这种模式与 Apache mod_authnz_ldappam_ldap 等软件中的 LDAP 认证方案相同。这种方法使目录中用户对象的位置更具灵活性,但会对 LDAP 服务器额外发起两次请求。 + 第二种模式称为搜索+绑定模式,服务器首先使用由 ldapbinddnldapbindpasswd 指定的固定用户名和密码绑定到 LDAP 目录,并搜索试图登录数据库的用户。如果没有配置用户名和密码,则会尝试对目录进行匿名绑定。搜索会在 ldapbasedn 指定的子树上进行,并尝试对 ldapsearchattribute 指定的属性做精确匹配。一旦在搜索中找到了该用户,服务器会断开连接,再作为该用户重新绑定到目录,并使用客户端指定的密码来验证登录是否正确。这种模式与 Apache mod_authnz_ldappam_ldap 等软件中的 LDAP 认证方案相同。这种方法使目录中用户对象的位置更具灵活性,但会与 LDAP 服务器建立两个独立的连接。 以下配置选项适用于两种模式: @@ -983,20 +993,29 @@ ldap://host[:port]/ - 将简单绑定的配置选项与搜索加绑定的选项混用会导致错误。 + + 将简单绑定模式的配置选项与搜索+绑定模式的配置选项混用是错误的。 + - 下面是 LDAP 简单绑定配置的示例: + + 下面是一个简单绑定 LDAP 配置示例: + host ... ldap ldapserver=ldap.example.net ldapprefix="cn=" ldapsuffix=", dc=example, dc=net" -当请求以数据库用户 someuser 的身份连接数据库服务器时,PostgreSQL 会尝试使用 DN cn=someuser, dc=example, - dc=net 和客户端提供的密码绑定到 LDAP 服务器。如果连接成功,就会授予数据库访问权限。 + + 当请求以数据库用户 someuser 连接数据库服务器时,PostgreSQL 将尝试使用 DN cn=someuser, dc=example, dc=net 和客户端提供的密码绑定到 LDAP 服务器。如果该连接成功,数据库访问就会被授予。 + 下面是搜索加绑定配置的示例: host ... ldap ldapserver=ldap.example.net ldapbasedn="dc=example, dc=net" ldapsearchattribute=uid 当请求以数据库用户 someuser 的身份连接数据库服务器时,PostgreSQL 会尝试匿名绑定到 LDAP 服务器(因为没有指定 ldapbinddn),并在指定的基础 DN 下搜索 (uid=someuser)。如果找到了条目,就会尝试使用找到的信息和客户端提供的密码进行绑定。如果第二次连接成功,就会授予数据库访问权限。 - 下面是用 URL 表示的相同搜索加绑定配置: + + 下面是以 URL 形式写出的同一个搜索+绑定配置: + host ... ldap ldapurl="ldap://ldap.example.net/dc=example,dc=net?uid?sub" -一些支持 LDAP 认证的其他软件也使用相同的 URL 格式,因此更容易共享配置。 + + 某些支持 LDAP 认证的其他软件也使用相同的 URL 格式,因此共享这类配置会更容易。 + @@ -1206,7 +1225,7 @@ FATAL: user "andym" does not exist FATAL: database "testdb" does not exist - 你试图连接的数据库不存在。注意,如果你没有指定数据库名,默认会使用数据库用户名作为数据库名。 + 你试图连接的数据库不存在。注意,如果你没有指定数据库名,默认会使用数据库用户名作为数据库名,但这不一定是所需的数据库名。
diff --git a/zh/10/config.sgml b/zh/10/config.sgml index 52c13500..2bf2aabd 100644 --- a/zh/10/config.sgml +++ b/zh/10/config.sgml @@ -17,6 +17,7 @@ 设置参数 + 参数名称和值 @@ -43,14 +44,17 @@ + 字符串: 通常值被包括在单引号内,值内部的任何单引号都需要被双写。不过,如果值是一个简单数字或者 标识符,引号通常可以被省略。 + + 数字(整数和浮点数): 只有浮点数参数才允许使用小数点。不要使用千位分隔符。不要求使用引号。 @@ -58,11 +62,16 @@ + 带单位的数字: - 某些数值参数具有隐含单位,因为它们描述内存量或时间量。单位可能是千字节、块(通常为八千字节)、毫秒、秒或分钟。 - 对于这些设置,不带单位的数值会使用该设置的默认单位,可通过 - pg_settings.unit获知该单位。为方便起见,可以显式指定设置的单位,例如用'120 ms'表示时间值,系统会将它转换为参数的实际单位。注意,使用此功能时必须把值写成字符串(加引号)。单位名称区分大小写,数值和单位之间可以有空白。 + 一些数字参数具有隐含单位,因为它们描述的是内存或时间量。单位可能是千字节、块 + (通常为 8 千字节)、毫秒、秒或分钟。这类设置若给出不带单位的数字值,就会使用该设置的默认单位, + 可以通过 pg_settings.unit 了解该默认单位。为了方便, + 也可以显式指定单位,例如把时间值写成 '120 ms',系统会将其转换为该参数的实际单位。 + 注意,要使用这一特性,值必须写成字符串(带引号)。单位名称区分大小写,并且数字值与单位之间可以有空白。 + + 可用的内存单位是 kB(千字节)、 @@ -80,7 +89,8 @@ - + + @@ -95,15 +105,25 @@ + 通过配置文件影响参数 - 设置这些参数最基本的方法是编辑文件postgresql.confpostgresql.conf,该文件通常保存在数据目录中。初始化数据库集簇目录时会安装一份默认副本。该文件可能如下所示: + + 设置这些参数最基本的方法是编辑文件 + postgresql.confpostgresql.conf, + 它通常位于数据目录中。在数据库集簇目录初始化时,会安装该文件的一个默认副本。其内容示例如下: + # This is a comment log_connections = yes log_destination = 'syslog' search_path = '"$user", public' shared_buffers = 128MB -每行指定一个参数。名称与值之间的等号可以省略。空白没有特殊意义(引号内的参数值除外),空行会被忽略。井号(#)将该行的剩余部分标记为注释。不是简单标识符或数字的参数值必须用单引号括起。要在参数值中嵌入单引号,可以写两个单引号(推荐)或反斜线加单引号。如果文件中包含同一参数的多个条目,则只采用最后一个,忽略其余条目。 + + 每行指定一个参数。名称和值之间的等号是可选的。空白不重要(引号括起的参数值内部除外),空行会被忽略。 + 井号(#)表示该行余下部分是注释。不是简单标识符或数字的参数值必须用单引号括起。 + 要在参数值中嵌入单引号,可以写两个单引号(推荐)或使用反斜线转义单引号。 + 如果文件包含相同参数的多个条目,则忽略除最后一个之外的所有条目。 + 以这种方式设定的参数为集簇提供了默认值。除非这些设置被覆盖,活动会话看到的就是这些设置。 @@ -127,7 +147,7 @@ shared_buffers = 128MB 数据目录还包含文件 postgresql.auto.confpostgresql.auto.conf, 它与 postgresql.conf 采用相同的格式,但设计为自动编辑而非手工编辑。 - 这个文件保存了通过命令提供的设置。 + 这个文件保存了通过命令提供的设置。 每当读取 postgresql.conf 时,也会读取该文件,并以同样的方式使其中设置生效。 postgresql.auto.conf 中的设置会覆盖 postgresql.conf 中的设置。 @@ -148,25 +168,28 @@ shared_buffers = 128MB - 通过 SQL 影响参数 + + 通过SQL影响参数 PostgreSQL提供了三个SQL命令来建立配置默认值。 - 已经提到过的命令提供了一种改变全局默认值的从SQL可 + 已经提到过的命令提供了一种改变全局默认值的从SQL可 访问的方法;它在功效上等效于编辑postgresql.conf。此外,还有两个命令 可以针对每个数据库或者每个角色设置默认值: + - 命令允许针对一个数据库覆盖其全局设置。 + 命令允许针对各个数据库覆盖全局设置。 + - 命令允许用用户指定的值来覆盖全局设置和数据库设置。 + 命令允许用针对特定用户设置的值来覆盖全局设置和数据库设置。 @@ -185,16 +208,16 @@ shared_buffers = 128MB + - 命令允许察看所有参数的当前值。对应的函数是 - current_setting(setting_name text)。 + 命令允许查看所有参数的当前值。对应的函数为 current_setting(setting_name text) + - 那些可以在会话本地设置的参数,允许通过命令修改当前会话的参数值;它对其他会话没有影响。 - 相应的函数是set_config(setting_name, new_value, is_local)。 + 命令允许修改可在会话本地设置的参数的当前值;它对其他会话没有影响。对应的函数为 set_config(setting_name, new_value, is_local) @@ -215,9 +238,15 @@ shared_buffers = 128MB - 使用作用于此视图,具体来说就是更新其setting列,就等同于发出SET命令。例如,下述命令: + + + 在这个视图上使用并且指定更新setting + 列,其效果等同于发出SET命令。例如,下面的命令 + SET configuration_parameter TO DEFAULT; -等同于: + + 等效于: + UPDATE pg_settings SET setting = reset_val WHERE name = 'configuration_parameter'; @@ -227,23 +256,38 @@ UPDATE pg_settings SET setting = reset_val WHERE name = 'configuration_parameter + 通过 Shell 影响参数 - 除了在数据库或者角色层面上设置全局默认值或者进行覆盖,你还可以通过 shell 工具把设置 + 除了设置全局默认值或在数据库、角色级别覆盖默认值之外,你还可以通过 shell 工具把设置 传递给PostgreSQL。服务器和libpq 客户端库都能通过 shell 接受参数值。 - 在服务器启动期间,可以通过postgres命令的命令行参数传递参数设置。例如: + + + 在服务器启动期间,可以通过命令行参数把参数设置传递给 + postgres命令。例如: + postgres -c log_connections=yes -c log_destination='syslog' -以这种方式提供的设置会覆盖通过postgresql.confALTER SYSTEM进行的设置,因此不重启服务器就无法全局更改它们。 + + 这种方式提供的设置会覆盖通过postgresql.conf或者 + ALTER SYSTEM提供的设置,因此除了重启服务器之外无法从全局上改变它们。 + - 通过libpq启动客户端会话时,可以用PGOPTIONS环境变量指定参数设置。以这种方式建立的设置成为会话整个生命周期内的默认值,但不影响其他会话。出于历史原因,PGOPTIONS的格式与启动postgres命令时使用的格式相似;具体而言,必须指定标志。例如: + + + 当通过libpq启动一个客户端会话时,可以使用PGOPTIONS + 环境变量指定参数设置。这种方式建立的设置构成了会话生存期间的默认值,但是不会影响 + 其他的会话。由于历史原因,PGOPTIONS的格式和启动 + postgres命令时用到的相似,特别是标志必须被指定。 + 例如: + env PGOPTIONS="-c geqo=off -c statement_timeout=5min" psql @@ -288,7 +332,7 @@ include 'filename' 还有一个 include_if_exists 指令,其行为与 include 相同, 但在被引用文件不存在或无法读取时有所不同。普通的 include 会将其视为错误, - 而 include_if_exists 只会记录一条消息并继续处理引用配置文件。 + 而 include_if_exists 只会记录一条消息并继续处理引用它的配置文件。 @@ -299,21 +343,21 @@ include 'filename' postgresql.conf 文件也可以包含 include_dir 指令, 用来指定一个应被包含的配置文件目录。其用法如下: - include_dir 'directory' - - 非绝对目录名会被解释为相对于引用配置文件所在目录的路径。在指定目录中, +include_dir 'directory' + + 非绝对目录名会被解释为相对于引用它的配置文件所在目录的路径。在指定目录中, 只有名称以 .conf 结尾的非目录文件才会被包含。以 . 开头的文件名也会被忽略,以避免在某些平台上误处理隐藏文件。包含目录中的多个文件会按文件名顺序处理 (依据 C 区域规则排序,即数字在字母之前,大写字母在小写字母之前)。 - 包括文件或目录可以被用来在逻辑上分隔数据库配置的各个部分,而不是用一个很大的postgresql.conf文件。 + 包含文件或目录可以用来在逻辑上分隔数据库配置的各个部分,而不是用一个很大的postgresql.conf文件。 考虑一个有两台数据库服务器的公司,每一个都有不同的内存量。 - 很可能配置的元素都会被共享,例如用于日志的参数。但是两者关于内存的参数将会不同。 + 两者很可能会共享部分配置,例如日志设置。但是两者关于内存的参数将会不同。 并且还可能会有服务器相关的自定义。 一种管理这类情况的方法是将你的站点的自定义配置修改分成三个文件。 - 你可以把下面的内容加入到你的postgresql.conf文件末尾来包括它们: + 你可以把下面的内容加入到你的postgresql.conf文件末尾来包含它们: include 'shared.conf' include 'memory.conf' @@ -374,7 +418,7 @@ include_dir 'conf.d' - 指定用于数据存储的目录。这个选项只能在服务器启动时设置。 + 指定用于数据存储的目录。这个参数只能在服务器启动时设置。 @@ -434,7 +478,7 @@ include_dir 'conf.d' - 指定可被服务器创建的用于管理程序的额外进程 ID(PID)文件。这个参数只能在服务器启动的时候设置。 + 指定服务器应创建的额外进程 ID(PID)文件的名称,供服务器管理程序使用。这个参数只能在服务器启动的时候设置。 @@ -445,15 +489,15 @@ include_dir 'conf.d' - 如果你想把配置文件放在别的地方而不是数据目录中,那么postgres 命令行选项或者环境变量PGDATA必须指向包含配置文件的目录,并且postgresql.conf中(或者命令行上)的data_directory参数必须显示数据目录实际存放的地方。请注意,data_directory将覆盖PGDATA指定的数据目录位置,但是不覆盖配置文件的位置。 + 如果你想把配置文件放在别的地方而不是数据目录中,那么postgres 命令行选项或者环境变量PGDATA必须指向包含配置文件的目录,并且postgresql.conf中(或者命令行上)的data_directory参数必须设置为数据目录的实际位置。请注意,data_directory将覆盖PGDATA指定的数据目录位置,但是不覆盖配置文件的位置。 - 如果你愿意,可以使用选项config_filehba_file和/或ident_file单独指定配置文件名称和位置。config_file只能在postgres命令行上指定,但是其他文件可以在主配置文件中设置。如果所有三个参数外加data_directory被显式地设置,则不必指定PGDATA。 + 如果你愿意,可以使用选项config_filehba_file和/或ident_file单独指定配置文件名称和位置。config_file只能在postgres命令行上指定,但是其他参数可以在主配置文件中设置。如果所有三个参数外加data_directory被显式地设置,则不必指定PGDATA - 在设置任何这些参数时,相对路径将被解释为相对于postgres启动路径的路径。 + 在设置任何这些参数时,相对路径将被解释为相对于启动 postgres 时所在目录的路径。 @@ -491,11 +535,11 @@ include_dir 'conf.d' - - - 服务器监听的 TCP 端口;默认是 5432 。请注意服务器会同一个端口号监听所有的 IP 地址。这个参数只能在服务器启动时设置。 - - + + 服务器监听的 TCP 端口,默认是 5432。请注意,服务器监听的所有 IP 地址都使用同一个端口号。 + 此参数只能在服务器启动时设置。 + + @@ -592,26 +636,19 @@ include_dir 'conf.d' - 设置 Unix 域套接字的访问权限。Unix 域套接字使用普通的 Unix 文件系统权限集。这个参数值应该是数字的形式,也就是系统调用chmodumask接受的 形式(如果使用自定义的八进制格式,数字必须以一个0(零)开头)。 + 设置 Unix 域套接字的访问权限。Unix 域套接字使用通常的 Unix 文件系统权限集。参数值应是以 chmodumask 系统调用所接受格式指定的数字权限模式。(要使用惯用的八进制格式,数字必须以 0(零)开头。) - - 默认的权限是0777,意思是任何人都可以连接。合理的候选是0770(只有用户和同组的人可以访问, 又见unix_socket_group)和0700(只有用户自己可以访问)(请注意,对于 Unix 域套接字,只有写权限有麻烦,因此没有对读取和执行权限的设置和收回)。 + 默认权限是 0777,表示任何人都可以连接。合理的其他取值包括 0770(仅属主和所属组,另见 unix_socket_group)和 0700(仅属主)。(注意,对 Unix 域套接字而言,只有写权限起作用,因此设置或撤销读权限和执行权限没有意义。) - - 这个访问控制机制与中的用户认证没有关系。 + 此访问控制机制独立于 中描述的机制。 - - 这个参数只能在服务器启动时设置。 + 此参数只能在服务器启动时设置。 - - 这个参数与完全忽略套接字权限的系统无关,尤其是自版本10以上的Solaris。 - 在那些系统上,可以通过把unix_socket_directories指向一个把搜索权限 - 限制给指定用户的目录来实现相似的效果。 - Windows 没有 Unix 域套接字,因此此参数在 Windows 上也没有意义。 + 此参数对完全忽略套接字权限的系统无效,尤其是 Solaris(截至 Solaris 10)。在这些系统上,可以将 unix_socket_directories 指向一个仅向目标用户授予搜索权限的目录,以达到类似效果。Windows 没有 Unix 域套接字,因此此参数在 Windows 上也没有意义。 @@ -624,10 +661,8 @@ include_dir 'conf.d' - - 通过Bonjour广告服务器的存在。默认值是关闭。 - 这个参数只能在服务器启动时设置。 + 启用通过 Bonjour 通告服务器存在的功能。默认值为关闭。此参数只能在服务器启动时设置。 @@ -640,11 +675,11 @@ include_dir 'conf.d' - - - 指定Bonjour服务名称。空字符串''(默认值)表示使用计算机名。 如果编译时没有打开Bonjour支持那么将忽略这个参数。这个参数只能在服务器启动时设置。 - - + + 指定 Bonjour 服务名。空字符串 ''(默认值)表示使用计算机名。 + 如果编译时未启用 Bonjour 支持,则此参数会被忽略。此参数只能在服务器启动时设置。 + + @@ -867,7 +902,7 @@ include_dir 'conf.d'
- 可用的密码组细节可能会随着OpenSSL 版本变化。 + 可用的密码套件细节可能会随着OpenSSL 版本变化。 可使用命令 openssl ciphers -v 'HIGH:MEDIUM:+3DES:!aNULL'来查看当前安装的OpenSSL版本的实际细节。 注意这个列表是根据服务器密钥类型在运行时过滤过的。 @@ -882,38 +917,28 @@ include_dir 'conf.d' - 指定是否使用服务器的 SSL 密码首选项,而不是用客户端的。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 - 默认值是 true。 + 指定是否使用服务器的 SSL 密码套件优先顺序,而非客户端的优先顺序。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。默认值为 true - - 老的PostgreSQL版本没有这个设置并且总是使用客户端的首选项。这个设置主要用于与那些版本 - 的向后兼容性。使用服务器的首选项通常会更好,因为服务器更可能会被合适地配置。 + 旧版 PostgreSQL没有此设置,始终采用客户端的优先顺序。此设置主要用于与这些旧版本保持向后兼容。采用服务器的优先顺序通常更好,因为服务器更可能得到适当配置。 + + ssl_ecdh_curve (string) - ssl_ecdh_curve 配置参数 + ssl_ecdh_curve 配置参数 - 指定在 ECDH 密钥交换中使用的曲线名称。它需要被所有连接的客户端支持。 - 不必与服务器椭圆曲线密钥所使用的曲线相同。 - 该参数只能在postgresql.conf文件中或服务器命令行上设置。 - 默认值为prime256v1。 + 指定在 ECDH 密钥交换中使用的曲线名称。所有连接的客户端都必须支持该曲线。它不必与服务器椭圆曲线密钥使用的曲线相同。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。默认值为 prime256v1 - - OpenSSL最常见的曲线名称是: - prime256v1 (NIST P-256)、 - secp384r1 (NIST P-384)、 - secp521r1 (NIST P-521)。 - openssl ecparam -list_curves 命令可以显示可用曲线的完整列表, - 但并非所有曲线都可用于 TLS。 + OpenSSL 中最常见的曲线名称为:prime256v1(NIST P-256)、secp384r1(NIST P-384)、secp521r1(NIST P-521)。可以用 openssl ecparam -list_curves 命令显示可用曲线的完整列表,但其中并非所有曲线都能用于 TLS @@ -945,13 +970,11 @@ include_dir 'conf.d' - - 指定含有用于SSL密码的所谓临时DH家族的Diffie-Hellman参数的文件名。默认值为空,这种情况下将使用内置的默认DH参数。使用自定义的DH参数可以降低攻击者破解众所周知的内置DH参数的风险。可以用命令openssl dhparam -out dhparams.pem 2048创建自己的DH参数文件。 + 指定包含 Diffie-Hellman 参数的文件名,这些参数用于所谓临时 DH 系列的 SSL 密码套件。默认值为空,此时使用编译时内置的默认 DH 参数。如果攻击者破解了众所周知的内置 DH 参数,使用自定义 DH 参数可以降低由此带来的风险。可以用命令 openssl dhparam -out dhparams.pem 2048 创建自己的 DH 参数文件。 - - 这个参数只能在postgresql.conf文件中或通过服务器命令行进行设置。 + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 @@ -985,10 +1008,12 @@ include_dir 'conf.d' - + + + db_user_namespace (boolean) - db_user_namespace 配置参数 + db_user_namespace 配置参数 @@ -1021,7 +1046,6 @@ include_dir 'conf.d' -
@@ -1041,20 +1065,14 @@ include_dir 'conf.d' - 设置数据库服务器将使用的共享内存缓冲区量。默认通常是 128 兆字节(128MB),但是如果你的内核设置不支持(在initdb时决定),那么可能会更少。 - 这个设置必须至少为 128 千字节。不过为了更好的性能,通常会使用明显高于最小值的设置。 - (BLCKSZ 的非默认值会改变最小值。) - 此参数只能在服务器启动时设置。 + 设置数据库服务器用于共享内存缓冲区的内存量。默认值通常为 128 兆字节(128MB),但如果内核设置不支持,则可能更小(在 initdb 期间确定)。此设置必须至少为 128 千字节。(BLCKSZ 的非默认值会改变该最小值。)不过,要获得良好性能,通常需要远高于该最小值的设置。此参数只能在服务器启动时设置。 - - 如果有一个专用的 1GB 或更多内存的数据库服务器,一个合理的shared_buffers开始值是系统内存的 25%。即使更大的shared_buffers有效,也会造成一些工作负载, 但因为PostgreSQL同样依赖操作系统的高速缓冲区,将shared_buffers设置为超过 40% 的RAM不太可能比一个小点值工作得更好。为了能把对写大量新的或改变的数据的处理分布在一个较长的时间段内,shared_buffers更大的设置通常要求对max_wal_size也做相应增加。 + 如果专用数据库服务器具有 1GB 或更多内存,shared_buffers 的合理初始值是系统内存的 25%。对于某些工作负载,将 shared_buffers 设得更大也有效,但由于 PostgreSQL 同时依赖操作系统缓存,将超过 40% 的内存分配给 shared_buffers 不太可能比更小的值效果更好。将 shared_buffers 设得更大时,通常还需要相应增加 max_wal_size,以便将大量新数据或已修改数据的写入过程分散到更长的时间内。 - - 如果系统内存小于 1GB,一个较小的 RAM 百分数是合适的,这样可以为操作系统留下足够的空间。 + 对于内存少于 1GB 的系统,适合使用更小的内存比例,以便为操作系统留出足够空间。 - @@ -1066,20 +1084,16 @@ include_dir 'conf.d' - 启用或禁用巨型内存页。有效值为try(默认值)、onoff。 + 启用或禁用巨型内存页。有效值为 try(默认值)、onoff - - 目前,此特性仅在 Linux 上受支持。在其他系统上,设置为try时会被忽略。 + 目前只有 Linux 支持此特性。在其他系统上,设置为 try 时会忽略此设置。 - - 使用巨型页会减小页表,并减少花在内存管理上的 CPU 时间,从而提高性能。更多详情参见。 + 使用巨型页可缩小页表,减少内存管理所需的 CPU 时间,从而提高性能。更多信息参见 - - 将huge_pages设置为try时,服务器会尝试使用巨型页,失败时则退回到常规分配方式。 - 设置为on时,如果无法使用巨型页,服务器将无法启动。设置为off时,不会使用巨型页。 + 将 huge_pages 设为 try 时,服务器会尝试使用巨型页,失败后则回退到普通内存分配。设为 on 时,使用巨型页失败会导致服务器无法启动。设为 off 时,不使用巨型页。 @@ -1092,13 +1106,10 @@ include_dir 'conf.d' - 设置每个数据库会话使用的临时缓冲区的最大数量。这些缓冲区是仅用于访问临时表的会话本地缓冲区。 - 默认为 8 兆字节(8MB)。 - 这个设置可以在独立的会话内部被改变,但是只有在会话第一次使用临时表之前才能改变; 在会话中随后企图改变该值是无效的。 + 设置每个数据库会话使用的临时缓冲区的最大数量。这些是会话本地的缓冲区,仅用于访问临时表。默认值为 8 兆字节(8MB)。可以在单个会话内更改此设置,但必须在该会话首次使用临时表之前更改;此后尝试更改该值,对该会话不会产生影响。 - - 一个会话将按照temp_buffers给出的限制根据需要分配临时缓冲区。如果在一个并不需要大量临时缓冲区的会话里设置一个大的数值, 其开销只是一个缓冲区描述符,或者说temp_buffers每增加一则增加大概 64 字节。不过,如果一个缓冲区被实际使用,那么它就会额外消耗 8192 字节(或者BLCKSZ字节)。 + 会话会按需分配临时缓冲区,上限为 temp_buffers。对于实际不需要很多临时缓冲区的会话,将此参数设得较大时,开销仅为 temp_buffers 每增加一就多分配一个缓冲区描述符,约为 64 字节。不过,如果实际使用了某个缓冲区,还会为它额外消耗 8192 字节(一般而言为 BLCKSZ 字节)。 @@ -1111,16 +1122,13 @@ include_dir 'conf.d' - 设置可以同时处于prepared状态的事务的最大数目(见)。把这个参数设置 为零(这是默认设置)将禁用预备事务特性。这个参数只能在服务器启动时设置。 + 设置可同时处于预备状态的事务的最大数量(见 )。将此参数设为零(默认值)会禁用预备事务功能。此参数只能在服务器启动时设置。 - - 如果你不打算使用预备事务,可以把这个参数设置为零来防止意外创建预备事务。如果你正在使用预备事务,你将希望把max_prepared_transactions至少设置为一样大,因此每一个会话可以有一个预备事务待处理。 + 如果不打算使用预备事务,应将此参数设为零,以防意外创建预备事务。如果使用预备事务,通常应将 max_prepared_transactions 设为不小于 的值,以便每个会话都能有一个待处理的预备事务。 - - 当运行一个备库时,你必须设置这个参数等于或大于主库上的参数。 - 否则,备库上将不允许查询。 + 运行备库时,必须将此参数设为与主库相同或更大的值。否则,备库上将不允许执行查询。 @@ -1133,13 +1141,7 @@ include_dir 'conf.d' - 指定内部排序操作和哈希表在写入临时磁盘文件之前使用的内存量。默认值为四兆字节(4MB)。 - 请注意,复杂查询可能并行执行多个排序或哈希操作, - 每个操作允许在开始将数据写入临时文件之前使用此值指定的内存量。 - 此外,可能有多个正在运行的会话同时执行此类操作。 - 因此,使用的总内存量可能是work_mem值的多倍; - 在选择值时必须牢记这一事实。排序操作用于ORDER BYDISTINCT和合并连接。 - 哈希表用于哈希连接、基于哈希的聚合和IN子查询的基于哈希的处理。 + 指定内部排序操作和哈希表在写入临时磁盘文件之前可使用的内存量。默认值为 4 兆字节(4MB)。请注意,复杂查询可能并行执行多个排序或哈希操作,每个操作在开始向临时文件写入数据之前,都可以使用此值指定的内存量。此外,多个正在运行的会话也可能并发执行此类操作。因此,使用的总内存量可能是 work_mem 值的数倍;选择此值时必须考虑这一点。排序操作用于 ORDER BYDISTINCT 和归并连接。哈希表用于哈希连接、基于哈希的聚合、以及基于哈希的 IN 子查询处理。 @@ -1152,18 +1154,13 @@ include_dir 'conf.d' - 指定维护操作(如 VACUUMCREATE INDEX 和 - ALTER TABLE ADD FOREIGN KEY)可使用的最大内存量。 - 默认值为 64 兆字节(64MB)。 - 由于数据库会话一次只能执行一个这样的操作,而一个安装通常也不会有很多此类操作并发运行, - 因此把该值设置得明显大于 work_mem 通常是安全的。更大的设置可能改善清理和恢复数据库转储的性能。 + 指定维护操作(如 VACUUMCREATE INDEXALTER TABLE ADD FOREIGN KEY)可使用的最大内存量。默认值为 64 兆字节(64MB)。由于一个数据库会话一次只能执行一个此类操作,而一个数据库系统通常也不会并发运行很多此类操作,因此可以安全地将该值设得远大于 work_mem。更大的设置可能改善清理和恢复数据库转储的性能。 - 请注意,当 autovacuum 运行时,分配的内存量最多可能达到此值的倍,因此请小心,不要将默认值设置得过高。 - 单独设置可能有助于控制这一点。 + 注意,自动清理运行时,最多可能分配此内存量的 倍,因此不要将默认值设得过高。单独设置 可能有助于控制这一点。 - 请注意,为收集死元组标识符,VACUUM最多只能使用1GB内存。 + 注意,在收集死元组标识符时,VACUUM 最多只能使用 1GB 内存。 @@ -1183,7 +1180,7 @@ include_dir 'conf.d' 这可能让排序操作更快完成。
- 默认值为 150,000 个元组。请注意,更高的值通常不会更有效,甚至可能适得其反, + 默认值为 150,000 个元组。请注意,更高的值通常也不会让效果好很多,甚至可能适得其反, 因为优先队列对可用 CPU 缓存的大小很敏感,而默认策略使用缓存无关算法对有序段进行排序。 这一特性让默认排序策略能够自动、透明地有效利用可用 CPU 缓存。 @@ -1202,14 +1199,10 @@ include_dir 'conf.d' - 指定每个自动清理工作者进程能使用的最大内存量。 - 其默认值为 -1,表示转而使用 的值。 - 当运行在其他上下文环境中时,这个设置对VACUUM的行为没有影响。 - 这个参数只能在postgresql.conf中或者服务器命令行上设置。 + 指定每个自动清理工作进程可使用的最大内存量。默认值为 -1,表示改用 的值。该设置不影响其他上下文中运行的 VACUUM 的行为。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 - 为收集死元组标识符,autovacuum 最多只能使用1GB内存, - 因此将autovacuum_work_mem设置为更高的值,不会影响 autovacuum 扫描表时可以收集的死元组数量。 + 在收集死元组标识符时,自动清理最多只能使用 1GB 内存,因此将 autovacuum_work_mem 设得更高,不会影响自动清理扫描表时能收集的死元组数量。 @@ -1221,13 +1214,14 @@ include_dir 'conf.d' + 指定服务器执行栈的最大安全深度。此参数的理想设置是由内核强制执行的实际栈大小限制 - (如由ulimit -s或本地等效设置),减去大约一兆字节的安全边界。 - 需要安全边界是因为服务器中并非每个例程都检查栈深度,而只在表达式求值等关键的潜在递归例程中检查。 + (如由ulimit -s或本地等效设置),减去大约一兆字节的安全余量。 + 需要安全余量是因为服务器中并非每个例程都检查栈深度,而只在可能递归的关键例程(如表达式求值)中检查。 默认设置为两兆字节(2MB), 这是保守且不太可能引起崩溃的小值。但是,这可能太小,无法执行复杂函数。 - 只有超级用户能更改这个设置。 + 只有超级用户才能更改此设置。 @@ -1244,13 +1238,7 @@ include_dir 'conf.d' - 指定服务器应该使用的动态共享内存实现。可能的值包括posix(使用shm_open分配的POSIX共享内存), - sysv(通过shmget分配的System V共享内存), - windows(用于Windows共享内存), - mmap(使用存储在数据目录中的内存映射文件模拟共享内存),以及none(禁用此特性)。 - 并非所有平台都支持所有值;第一个支持的选项是该平台的默认值。 - mmap选项不是任何平台的默认选项,通常不建议使用,因为操作系统可能会反复将修改的页面写回磁盘,增加系统I/O负载; - 但在调试时,当pg_dynshmem目录存储在RAM磁盘上,或者其他共享内存设施不可用时,可能会有用。 + 指定服务器应使用的动态共享内存实现。可选值为 posix(使用 shm_open 分配的 POSIX 共享内存)、sysv(通过 shmget 分配的 System V 共享内存)、windows(Windows 共享内存)、mmap(使用存放在数据目录中的内存映射文件模拟共享内存),以及 none(禁用此功能)。并非所有平台都支持所有值;第一个受支持的选项是该平台的默认值。mmap 不是任何平台的默认选项,通常不建议使用,因为操作系统可能会反复将修改过的页面写回磁盘,增加系统 I/O 负载;不过,在调试、将 pg_dynshmem 目录存放在 RAM 磁盘上,或其他共享内存设施不可用时,它可能有用。 @@ -1270,14 +1258,10 @@ include_dir 'conf.d' - 指定进程可以用于临时文件(如排序和哈希临时文件)或保留游标的存储文件的最大磁盘空间。 - 尝试超过此限制的事务将被取消。 - 此值以千字节为单位指定。 - -1(默认值)表示没有限制。 - 只有超级用户能更改这个设置。 + 指定一个进程可用于临时文件的最大磁盘空间,例如排序和哈希临时文件,或保留游标的存储文件。尝试超过此限制的事务将被取消。该值以千字节为单位。-1(默认值)表示没有限制。只有超级用户才能更改此设置。 - 这个设置约束着一个给定PostgreSQL进程在任何瞬间所使用的所有临时文件的总空间。应该注意的是,与在查询执行中在幕后使用的临时文件相反,显式临时表所用的磁盘空间被这个设置所限制。 + 此设置限制单个 PostgreSQL 进程在任意时刻使用的所有临时文件的总空间。需要注意,显式临时表所用的磁盘空间计入该上限;计入的是查询执行过程中内部使用的临时文件。 @@ -1297,31 +1281,30 @@ include_dir 'conf.d' - 设置每个服务器子进程允许同时打开的最大文件数。默认值是一千个文件。 - 如果内核实施了安全的单进程限制,就不必担心此设置。但在某些平台上 - (尤其是大多数 BSD 系统),内核允许单个进程打开的文件数很多,以至于 - 当多个进程都试图打开这么多文件时,会超过系统实际能够支持的数量。 - 如果遇到Too many open files错误,可以尝试减小此设置。 - 此参数只能在服务器启动时设置。 + 设置每个服务器子进程允许同时打开的最大文件数量。默认值为一千个文件。如果内核强制实施了安全的每进程上限,就不必担心此设置。但在某些平台上(尤其是大多数 BSD 系统),内核允许单个进程打开的文件数量很大,如果很多进程都尝试打开这么多文件,就会远超系统实际能够支持的总量。如果遇到 Too many open files(打开的文件过多)错误,可尝试减小此设置。此参数只能在服务器启动时设置。
- + + 基于代价的清理延迟 - 在命令的执行过程中,系统维持着一个内部计数器来跟踪各种被执行的I/O操作的估算开销。当累计的代价达到一个限制(由vacuum_cost_limit指定),执行这些操作的进程将按照vacuum_cost_delay所指定的休眠一小段时间。然后它将重置计数器并继续执行。 + 执行 命令期间,系统维护一个内部计数器,记录已执行的各种 I/O 操作的估算代价。 + 当累计代价达到上限(由 vacuum_cost_limit 指定)时,执行该操作的进程会休眠一小段时间,时长由 vacuum_cost_delay 指定。 + 随后重置计数器并继续执行。 - 这个特性的出发点是允许管理员降低这些命令对并发的数据库活动产生的I/O影响。在很多情况下,VACUUMANALYZE等维护命令能否快速完成并不重要,而非常重要的是这些命令不会对系统执行其他数据库操作的能力产生显著的影响。基于代价的清理延迟提供了一种方式让管理员能够保证这一点。 + 此功能让管理员能够降低这些命令对并发数据库活动的 I/O 影响。在许多情况下,VACUUMANALYZE 等维护命令是否快速完成并不重要, + 但避免它们显著干扰系统执行其他数据库操作的能力通常很重要。基于代价的清理延迟为管理员提供了实现这一点的方法。 - 对于手动发出的VACUUM命令,该特性默认被禁用。要启用它,只要把vacuum_cost_delay变量设为一个非零值。 + 对于手动执行的 VACUUM 命令,此功能默认禁用。要启用它,将 vacuum_cost_delay 变量设为非零值。 @@ -1332,17 +1315,13 @@ include_dir 'conf.d' - - 超出代价限制时,进程将休眠的时间长度,以毫秒为单位。默认值为零,这会禁用基于代价的清理延迟特性。正值会启用基于代价的清理。 - 请注意,在许多系统上,休眠延迟的有效分辨率为 10 毫秒;将vacuum_cost_delay设置为非 10 的倍数的值, - 可能与设置为下一个更大的 10 的倍数具有相同效果。 - - - - 使用基于代价的清理时,vacuum_cost_delay的合适值通常很小,可能是 10 或 20 毫秒。 - 调整清理的资源消耗最好通过更改其他清理代价参数来完成。 - - + + 超过代价上限后,进程将休眠的时长,单位为毫秒。默认值为零,表示禁用基于代价的清理延迟功能。正值会启用基于代价的清理。注意,在许多系统上,休眠延迟的有效分辨率为 10 毫秒;将 vacuum_cost_delay 设为不是 10 的倍数的值,可能与将它设为下一个更大的 10 的倍数效果相同。 + + + 使用基于代价的清理时,vacuum_cost_delay 的合适值通常较小,例如 10 或 20 毫秒。调整清理的资源消耗时,最好更改其他清理代价参数。 + + @@ -1353,11 +1332,10 @@ include_dir 'conf.d' - - - 清理一个在共享缓存中找到的缓冲区的估计代价。它表示锁住缓冲池、查找共享哈希表和扫描页内容的代价。默认值为1。 - - + + 清理在共享缓冲区缓存中找到的缓冲区时所计入的估算代价。它表示锁定缓冲池、查找共享哈希表和扫描页内容的代价。默认值为 1。 + + @@ -1367,12 +1345,10 @@ include_dir 'conf.d' - - 清理一个必须从磁盘上读取的缓冲区的代价。 - 它表示锁住缓冲池、查找共享哈希表、从磁盘读取需要的块以及扫描其内容的代价。 - 默认值为10。 - - + + 清理必须从磁盘读取的缓冲区时所计入的估算代价。它表示锁定缓冲池、查找共享哈希表、从磁盘读取所需数据块并扫描其内容所需的工作量。默认值为 10。 + + @@ -1383,11 +1359,10 @@ include_dir 'conf.d' - - - 当清理修改一个之前干净的块时需要花费的估计代价。它表示再次把脏块刷出到磁盘所需要的额外I/O。默认值为20。 - - + + 清理操作修改原本干净的数据块时所计入的估算代价。它表示再次将脏块刷盘所需的额外 I/O。默认值为 20。 + + @@ -1398,20 +1373,18 @@ include_dir 'conf.d' - - - 将导致清理进程休眠的累计代价。默认值为200。 - - + + 会使清理进程休眠的累计代价。默认值为 200。 + + - - 有些操作会保持关键性的锁,这样可以尽快完成。基于代价的清理延迟在这类操作期间不会发生。因此有可能代价会累计至大大超过指定的限制。为了防止在这种情况下的无意义的长时间延迟,实际延迟的计算方式是vacuum_cost_delay * - accumulated_balance / - vacuum_cost_limit,且最大值是vacuum_cost_delay * 4。 + 某些操作持有关键的锁,因此应尽快完成。这些操作期间不会发生基于代价的清理延迟,所以累计代价可能远超指定上限。 + 为避免此时出现无益的长时间延迟,实际延迟按 vacuum_cost_delay * accumulated_balance / vacuum_cost_limit 计算, + 但最大不超过 vacuum_cost_delay * 4。 @@ -1420,10 +1393,11 @@ include_dir 'conf.d' 后台写入器 - 有一个独立的服务器进程,叫做后台写入器,它的功能就是发出写(新的或修改过的)共享缓冲区的命令。 - 当干净的共享缓存数量出现不足时,后台写入器写入一些脏缓存到文件系统,并标记为干净。 - 不过,后台写入器确实会增加 I/O 的总负荷,因为虽然在每个检查点间隔中一个重复弄脏的页面可能只会写出一次,但在同一个间隔中后台写入器可能会把它写出好几次。 - 在这一小节讨论的参数可以被用于调节本地需求的行为。 + 有一个独立的服务器进程,称为后台写入器,负责写出(新的或修改过的)共享缓冲区。 + 当干净的共享缓冲区数量似乎不足时,后台写入器会将一些脏缓冲区写入文件系统,并将其标记为干净。 + 这可以降低处理用户查询的服务器进程找不到干净缓冲区、因而不得不自行写出脏缓冲区的可能性。 + 不过,后台写入器确实会使总体 I/O 负载有所增加:反复变脏的页面原本可能在每个检查点间隔中只写出一次, + 而后台写入器可能在同一间隔内随着它变脏而多次写出。本节参数可用于根据实际需求调整此行为。 @@ -1434,12 +1408,10 @@ include_dir 'conf.d' - - 指定后台写入器活动轮次之间的延迟。在每个轮次中,写入器都会为一定数量的脏缓冲区发出写操作(可以用下面的参数控制)。 - 然后它就休眠 bgwriter_delay毫秒, 然后重复动作。当缓冲池中没有脏缓冲区时,不管 bgwriter_delay,它都会进入更长的休眠。默认值是 200 毫秒(200ms)。 - 注意在许多系统上,休眠延迟的有效解析度是 10 毫秒;因此,为bgwriter_delay设置一个 不是 10 的倍数的值与把它设置为下一个更高的 10 的倍数是一样的效果。这个选项只能在服务器命令行上或者在postgresql.conf文件中设置。 - - + + 指定后台写入器各轮活动之间的延迟。每一轮中,写入器会对一定数量的脏缓冲区发出写操作(由下面的参数控制),然后休眠 bgwriter_delay 毫秒,再重复此过程。不过,当缓冲池中没有脏缓冲区时,它会进入更长的休眠,而不受 bgwriter_delay 限制。默认值为 200 毫秒(200ms)。注意,在许多系统上,休眠延迟的有效分辨率为 10 毫秒;将 bgwriter_delay 设为不是 10 的倍数的值,可能与将它设为下一个更大的 10 的倍数效果相同。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 + + @@ -1450,11 +1422,10 @@ include_dir 'conf.d' - - - 在每个轮次中,不超过这么多个缓冲区将被后台写入器写出。把这个参数设置为零可禁用后台写出(注意被一个独立、专用辅助进程管理的检查点不受影响)。默认值是 100 个缓冲区。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 - - + + 后台写入器每轮写出的缓冲区数量不会超过此值。设为零会禁用后台写入。(由另一个独立的专用辅助进程管理的检查点不受影响。)默认值为 100 个缓冲区。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 + + @@ -1465,11 +1436,10 @@ include_dir 'conf.d' - - - 每一轮次要写的脏缓冲区的数目基于最近几个轮次中服务器进程需要的新缓冲区的数目。 最近所需的平均值乘以bgwriter_lru_multiplier可以估算下一轮次中将会需要的缓冲区数目。脏缓冲区将被写出直到有很多干净可重用的缓冲区(然而,每一轮次中写出的缓冲区数不超过bgwriter_lru_maxpages)。 因此,设置为 1.0 表示一种刚刚好的策略,这种策略会写出正好符合预测值的数目的缓冲区。 更大大的值可以为需求高峰提供某种缓冲,而更小的值则需要服务进程来处理一些写出操作。默认值是 2.0。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 - - + + 每轮写出的脏缓冲区数量取决于最近几轮服务器进程所需的新缓冲区数量。将近期平均需求乘以 bgwriter_lru_multiplier,即可估算下一轮所需的缓冲区数量。写入器会写出脏缓冲区,直到可用的干净且可重用缓冲区达到这一数量。(不过,每轮写出的缓冲区数量不会超过 bgwriter_lru_maxpages。)因此,设为 1.0 表示采用恰好及时策略,写出的缓冲区数量恰好等于预测需求量。更大的值可为需求突增留出余量,而更小的值则有意将部分写操作留给服务器进程执行。默认值为 2.0。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 + + @@ -1479,17 +1449,16 @@ include_dir 'conf.d' - - 只要后台写入器写入的数据超过bgwriter_flush_after字节,尝试强制 OS 把这些写发送到底层存储上。这样做将限制内核页缓存中脏数据的量,降低了在检查点末尾发出一个 fsync 时或者 OS 在后台大批量写回数据时卡住的可能性。 - 那常常会导致大幅度压缩的事务延迟,但是也有一些情况(特别是负载超过但小于 OS 页面高速缓存)的性能会降低。这种设置可能会在某些平台上没有效果。 - 合法的范围在0(禁用受控写回)和2MB之间。Linux 上的默认值是512kB,其他平台上是0(如果BLCKSZ不是8kB,则默认值和最大值会按比例缩放至这个值)。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 - - + + 每当后台写入器写出的数据超过bgwriter_flush_after 字节时,就尝试强制操作系统将这些写操作发往底层存储。这样可以限制内核页缓存中的脏数据量,降低在检查点结束时调用 fsync,或操作系统在后台以较大批次写回数据时发生停顿的可能性。通常,这能大幅降低事务延迟,但在某些情况下性能可能下降,尤其是工作负载大于 而小于操作系统页缓存时。此设置在某些平台上可能没有效果。有效范围为 0(禁用强制写回)至 2MB。Linux 上的默认值为 512kB,其他平台为 0。(如果 BLCKSZ 不是 8kB,默认值和最大值将按比例变化。)此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 + + - 较小的bgwriter_lru_maxpagesbgwriter_lru_multiplier可以降低由后台写入器造成的额外 I/O 开销。但更可能的是,服务器进程将必须自己发出写入操作,这会延迟交互式查询。 + 较小的 bgwriter_lru_maxpagesbgwriter_lru_multiplier 可以降低后台写入器造成的额外 I/O 负载, + 但也会增加服务器进程必须自行发出写操作的可能性,从而延迟交互式查询。 @@ -1504,29 +1473,19 @@ include_dir 'conf.d' - - 设置PostgreSQL预期可以同时执行的并发磁盘 I/O 操作数量。 - 提高该值会增加任何单个PostgreSQL会话尝试并行发起的 I/O 操作数。 - 允许的范围是 1 到 1000,或者零表示禁用异步 I/O 请求。目前,此设置只影响位图堆扫描。 - - - - 对于磁盘,此设置的一个良好起点是数据库所用的 RAID 0 条带或 RAID 1 镜像中独立磁盘的数量。 - (对于 RAID 5,不应计入奇偶校验盘。)但是,如果数据库经常忙于处理并发会话发出的多个查询,较低的值可能已足以让磁盘阵列保持忙碌。 - 超过使磁盘保持忙碌所需的值只会产生额外的 CPU 开销。 - SSD 和其他基于内存的存储通常可以处理很多并发请求,因此最佳值可能达到数百。 - - - - 异步 I/O 依赖有效的posix_fadvise函数,而某些操作系统缺少该函数。 - 如果不存在该函数,将此参数设置为零以外的任何值都会导致错误。 - 在某些操作系统上(例如 Solaris),该函数虽然存在,但实际上不起任何作用。 - - - - 在支持的系统上默认值为 1,否则为 0。对于位于特定表空间中的表,可以通过设置同名的表空间参数覆盖此值(参见)。 - - + + 设置 PostgreSQL 预期可以同时执行的并发磁盘 I/O 操作数量。提高此值会增加单个 PostgreSQL 会话尝试并行发起的 I/O 操作数量。允许的范围为 1 至 1000,或设为零以禁用异步 I/O 请求。目前,此设置仅影响位图堆扫描。 + + + 对于磁盘,可以将为数据库提供存储的 RAID 0 条带或 RAID 1 镜像中的独立磁盘数量作为合理初始值。(对于 RAID 5,不应计入校验盘。)不过,如果数据库经常忙于执行并发会话发出的多个查询,较小的值可能就足以使磁盘阵列保持繁忙。超过使磁盘保持繁忙所需的值只会增加 CPU 开销。SSD 和其他基于内存的存储通常可以处理大量并发请求,因此最佳值可能达到数百。 + + + 异步 I/O 依赖于有效的 posix_fadvise 函数,而某些操作系统缺少此函数。如果该函数不存在,将此参数设为任何非零值都会报错。在某些操作系统(如 Solaris)上,该函数虽然存在,却实际上不做任何事情。 + + + 支持此功能的系统上默认值为 1,其他系统为 0。对于位于特定表空间中的表,可以通过设置同名的表空间参数覆盖此值(见 )。 + + @@ -1536,19 +1495,16 @@ include_dir 'conf.d' - - 设置系统能够支持的后台进程的最大数量。这个参数只能在服务器启动时设置。默认值为 8。 + + 设置系统能够支持的后台进程的最大数量。此参数只能在服务器启动时设置。默认值为 8。 - - - 在运行一个备库时,你必须把这个参数设置为等于或者高于主库上的值。 - 否则,备库上将不允许查询。 - - - - 在更改此值时,考虑也调整。 - - + + 运行备库时,必须将此参数设为与主库相同或更大的值。否则,备库上将不允许执行查询。 + + + 更改此值时,也应考虑调整 。 + + @@ -1559,19 +1515,16 @@ include_dir 'conf.d' - - - 设置单个Gather或者Gather Merge节点能够开始的工作者的最大数量。并行工作者会从建立的进程池中取得,数量由限制。注意所要求的工作者数量在运行时可能实际无法被满足。如果这种事情发生,该计划将会以比预期更少的工作者运行,这可能会不太高效。默认值是2。把这个值设置为0将会禁用并行查询执行。 - - - - 注意并行查询可能消耗比非并行查询更多的资源,因为每一个工作者进程时一个完全独立的进程,它对系统产生的影响大致和一个额外的用户会话相同。在为这个设置选择值时,以及配置其他控制资源利用的设置(例如)时,应该把这个因素考虑在内。work_mem之类的资源限制会被独立地应用于每一个工作者,这意味着所有进程的总资源利用可能会比单个进程时高得多。例如,一个使用 4 个工作者的并行查询使用的 CPU 时间、内存、I/O 带宽可能是不使用工作者时的 5 倍之多。 - - - - 并行查询的更多信息请见。 - - + + 设置单个 GatherGather Merge 节点能够启动的工作进程的最大数量。并行工作进程取自 建立的进程池,并受到 的限制。注意,运行时实际可用的工作进程可能不足请求的数量。此时,计划会使用少于预期的工作进程运行,效率可能较低。默认值为 2。设为 0 会禁用并行查询执行。 + + + 注意,并行查询消耗的资源可能远多于非并行查询,因为每个工作进程都是完全独立的进程,对系统的影响大致相当于额外增加一个用户会话。选择此设置的值,以及配置其他控制资源使用的设置(如 )时,都应考虑这一点。work_mem 等资源限制分别应用于每个工作进程,因此所有进程的总资源用量可能远高于单个进程通常的用量。例如,使用 4 个工作进程的并行查询,其 CPU 时间、内存、I/O 带宽等用量可能达到完全不使用工作进程的查询的 5 倍。 + + + 并行查询的更多信息参见 。 + + @@ -1581,11 +1534,10 @@ include_dir 'conf.d' - - 设置系统能够为并行查询支持的工作者的最大数量。默认值为 8。增大或减小此值时,考虑也调整。 - 另外请注意,将此值设置得高于不会产生效果,因为并行工作者来自该设置建立的工作者进程池。 - - + + 设置系统能够为并行查询提供的工作进程的最大数量。默认值为 8。增大或减小此值时,也应考虑调整 。此外,将此值设得大于 没有效果,因为并行工作进程取自该设置建立的工作进程池。 + + @@ -1595,57 +1547,38 @@ include_dir 'conf.d' - - 当单个后端写入数据的量超过backend_flush_after字节时,尝试强制操作系统发送这些写入到底层存储。 - 这样做将限制内核的页面缓存中的脏数据量,降低在检查点末尾发出fsync时暂停的可能性,或者当操作系统在后台大批量的写回数据时。 - 通常的结果会大大减少事务延迟,但也有一些情况,特别是当工作负载大于,但小于操作系统的页面缓存时,性能可能会下降。 - 此设置在某些平台上可能无效。 - 有效范围在0,禁止强制回写,和2MB之间。 - 默认值是0,即没有强制回写。 - (如果BLCKSZ不是8kB,则最大值按其比例缩放。) - - + + 每当单个后端写出的数据超过backend_flush_after 字节时,就尝试强制操作系统将这些写操作发往底层存储。这样可以限制内核页缓存中的脏数据量,降低在检查点结束时调用 fsync,或操作系统在后台以较大批次写回数据时发生停顿的可能性。通常,这能大幅降低事务延迟,但在某些情况下性能可能下降,尤其是工作负载大于 而小于操作系统页缓存时。此设置在某些平台上可能没有效果。有效范围为 0(禁用强制写回)至 2MB。默认值为 0,即不强制写回。(如果 BLCKSZ 不是 8kB,最大值将按比例变化。) + + - + + old_snapshot_threshold (integer) - - old_snapshot_threshold配置参数 - - + + old_snapshot_threshold 配置参数 + + - - 设置快照可以被使用、且不会在使用时发生snapshot too old错误风险的最短时间。 - 此参数只能在服务器启动时设置。 - - - - 超过此阈值后,旧数据可能被清理掉。这有助于防止长期使用的快照造成膨胀。 - 为防止清理本应对快照可见的数据而产生错误结果,当快照比此阈值更旧,并且被用于读取自快照创建以来已被修改的页面时,会产生错误。 - - - - 默认值-1禁用此特性。用于生产工作的有效值可能从几小时到几天不等。 - 此设置会被强制转换为分钟粒度,允许01min之类的小值,只是因为它们有时可用于测试。 - 虽然允许高达60d的设置,但请注意,许多工作负载可能在短得多的时间内发生严重膨胀或事务 ID 回卷。 - - - - 启用此特性后,关系末尾释放出来的空间将不能返还给操作系统,因为那样会移除 - 检测snapshot too old条件所需的信息。分配给某个关系的全部空间都会一直 - 归属于该关系,只能在该关系内部重用,除非显式释放(例如使用 - VACUUM FULL)。 + + 设置快照在使用时不会发生 snapshot too old 错误的最短可用时间。此参数只能在服务器启动时设置。 - - - 此设置并不试图保证在任何特定情况下都会产生错误。事实上,例如对于已物化结果集的游标,如果仍能产生正确结果, - 即使所引用表中的底层行已被清理掉,也不会产生错误。 - 某些表(例如系统目录)无法安全地提前清理,因此不受此设置影响。 - 对于这些表,此设置既不会减少膨胀,也不会使扫描时可能出现snapshot too old错误。 - - + + 超过该阈值后,旧数据可以被清理掉。这有助于在快照长期保持使用时防止膨胀。为了避免因清理本应对该快照可见的数据而得到错误结果,当快照年龄超过该阈值,且该快照被用于读取自其建立以来已被修改过的页面时,就会报错。 + + + 值 -1 会禁用此功能,也是默认值。对生产环境而言,有用的取值大概从几个小时到几天不等。此设置会被强制调整为分钟粒度;较小的值(例如 01min)之所以被允许,只是因为它们有时可用于测试。虽然允许设置到 60d 这么高,但在许多工作负载中,严重膨胀或事务 ID 回卷可能会在更短时间内发生。 + + + 启用此功能后,关系末尾释放出来的空间不能返还给操作系统,因为那样可能会移除检测 snapshot too old 条件所需的信息。分配给某个关系的全部空间仍归属于该关系,只能在该关系内重用,除非显式释放(例如使用 VACUUM FULL)。 + + + 此设置不保证在任何特定情况下都一定会报错。实际上,如果仍能从某个对象(例如已物化结果集的游标)生成正确结果,那么即使被引用表中的底层行已被清理掉,也不会报错。有些表不能安全地提前清理,因此不受此设置影响,例如系统目录。对于这类表,此设置既不会减少膨胀,也不会在扫描时引入 snapshot too old 错误的可能性。 + + - + @@ -1679,12 +1612,12 @@ include_dir 'conf.d' CLUSTER 向同一事务中创建或截断的表执行COPY - 但最少的 WAL 不包含足够的信息来从基础备份和 WAL 日志重建数据,因此必须使用replica或更高级别来启用 WAL 归档 + 但 minimal 级别的 WAL 不包含足够的信息来从基础备份和 WAL 日志重建数据,因此必须使用replica或更高级别来启用 WAL 归档 ()和流复制。
logical级别上,记录与replica相同的信息,以及从WAL中提取逻辑变更集所需的信息。 - 使用logical级别会增加WAL的容量,特别是如果许多表被配置为REPLICA IDENTITY FULL, + 使用logical级别会增加 WAL 的数量,特别是如果许多表被配置为REPLICA IDENTITY FULL, 并且执行了许多UPDATEDELETE语句。 @@ -1711,16 +1644,15 @@ include_dir 'conf.d' - 能安全关闭fsync的环境的示例包括从一个备份文件中初始加载一个新数据库集簇、使用一个数据库集簇来在数据库被删掉并重建之后处理一批数据,或者一个被经常重建并却不用于失效备援的只读数据库克隆。单独的高质量硬件不足以成为关闭fsync的理由。 + 可以安全关闭fsync的情形包括:从备份文件初始装载一个新数据库集簇;用数据库集簇处理一批数据,处理后就丢弃并重建该数据库;或者使用经常重建且不用于故障切换的只读数据库克隆。仅有高质量硬件不足以成为关闭fsync的理由。 - 当把fsync从关闭改成打开时,为了可靠的恢复,需要强制在内核中的所有被修改的缓冲区进入持久化存储。这可以在多个时机来完成: - 在集簇被关闭时或在fsync因为运行initdb --sync-only而打开时、运行sync时、卸载文件系统时或者重启服务器时。 + 为确保将fsync从关闭改为打开后能够可靠恢复,必须将内核中所有已修改的缓冲区强制写入持久存储。可以在集簇已关闭或fsync已开启时,通过运行initdb --sync-only、运行sync、卸载文件系统或重启服务器来完成。 - 在很多情况下,为不重要的事务关闭可以提供很多关闭fsync的潜在性能收益,并不会有的同时, 关闭fsync可以提供很多潜在的性能优势,而不会有伴随着的数据损坏风险。 + 在很多情况下,为非关键事务关闭,可以获得关闭fsync所带来的大部分潜在性能收益,同时避免伴随的数据损坏风险。 @@ -1737,39 +1669,27 @@ include_dir 'conf.d' - 指定数据库服务器返回success指示给客户端之前,必须要完成多少WAL处理。 - 合法的值为remote_apply, on(默认值), remote_write,local, 和 off。 + 指定数据库服务器向客户端返回成功指示之前,必须完成多少 WAL 处理。有效值为remote_applyon(默认值)、remote_writelocaloff - 如果synchronous_standby_names为空,则唯一有意义的设置为onoff ; - remote_applyremote_writelocal都提供与on相同的本地同步级别。 - 所有非off模式的本地行为都是等待WAL的本地刷新到磁盘。 - 在 off模式,无需等待,因此在向客户端报告成功和以后保证事务安全防止服务器崩溃之间可能会出现延迟。 - (最大的延迟是的三倍。) - 不同于,将这个参数设置为off不会产生数据库不一致性的风险:一个操作系统或数据库崩溃可能会造成一些最近据说已提交的事务丢失,但数据库状态是一致的,就像这些事务已经被干净地中止。 - 因此,当性能比完全确保事务的持久性更重要时,关闭synchronous_commit可以作为一个有效的代替手段。更多讨论见。 + 如果synchronous_standby_names为空,只有onoff两种设置有意义;remote_applyremote_writelocal提供的本地同步级别都与on相同。所有非off模式在本地都会等待 WAL 刷写到磁盘。在off模式下则无需等待,因此,向客户端报告成功后,可能还要经过一段时间,才能保证事务不会因服务器崩溃而丢失。(最大延迟为的三倍。)与不同,将此参数设为off不会带来数据库不一致的风险:操作系统或数据库崩溃可能会使一些最近报告已提交的事务丢失,但数据库状态会与这些事务已正常中止时完全相同。因此,当性能比完全确保事务持久性更重要时,关闭synchronous_commit可以是一种有用的替代方案。更多讨论见 - 如果为非空,synchronous_commit也控制是否事务提交将等待它们的 WAL 记录在备库上被处理。 + 如果非空,synchronous_commit还控制事务提交是否等待备库处理其 WAL 记录。 - 当设置为 remote_apply 时,提交将等待,直到来自当前同步备库的答复显示他们已收到事务的提交记录并应用了它,以便它变得对备库上的查询可见,并写入备库上的持久存储。 - 这将导致比以前的设置更大的提交延迟,因为它等待 WAL 重放(replay)。 - 当设置为on时,提交将等待,直到来自于当前同步的备库的回复显示它们已经收到了事务的提交记录并将其刷入了磁盘。 - 这保证事务将不会被丢失,除非主库和所有同步备库都遭受到了数据库存储损坏的问题。 - 当这个参数被设置为remote_write时,提交将等待,直到来自当前的同步备库的回复指示它们已经收到了该事务的提交记录并且已经把该记录写到它们的文件系统,这种设置保证数据得以保存,在PostgreSQL的备库实例崩溃时,但是不能保证备库遭受操作系统级别崩溃时数据能被保持,因为数据不一定必须要在备库上达到持久存储。 - 设置local会导致提交等待本地刷写到磁盘,而不是复制。在使用同步复制时这通常是不可取的,但是为了完整性提供了这个选项。 + 设为remote_apply时,提交会等待当前同步备库回复,确认已收到并应用该事务的提交记录,使其对备库上的查询可见,并且已将其写入备库的持久存储。由于需要等待 WAL 重放,这会比之前的设置产生大得多的提交延迟。设为on时,提交会等待当前同步备库回复,确认已收到事务的提交记录,并已将其刷写到持久存储。这能保证事务不会丢失,除非主库和所有同步备库的数据库存储都损坏。设为remote_write时,提交会等待当前同步备库回复,确认已收到事务的提交记录,并已将其写入各自的文件系统。此设置能保证备库上的PostgreSQL实例崩溃时数据不丢失,但不能保证备库发生操作系统级别崩溃时数据不丢失,因为数据未必已写入备库的持久存储。设为local时,提交会等待本地刷盘,但不等待复制。使用同步复制时通常不希望采用这种设置,提供它是为了使选项完整。 - 这个参数可以随时被修改;任何一个事务的行为由其提交时生效的设置决定。因此,可以同步提交一些事务,同时异步提交其他事务。例如,当默认是相反时,实现一个单一多语句事务的异步提交,在事务中发出SET LOCAL synchronous_commit TO OFF。 + 此参数可以随时更改;每个事务的行为由提交时生效的设置决定。因此,让一些事务同步提交、另一些事务异步提交是可行且有用的。例如,当默认设置要求同步提交时,可以在一个包含多条语句的事务中执行SET LOCAL synchronous_commit TO OFF,使该事务异步提交。 - 概括了 synchronous_commit 各种设置具备的能力。 + 汇总了synchronous_commit各种设置具备的能力。
@@ -1783,9 +1703,9 @@ include_dir 'conf.d' synchronous_commit 设置 - 本地持久提交 - PG 崩溃备库持久提交 - OS 崩溃备库持久提交 + 本地提交持久性 + PG 崩溃后备库提交持久性 + OS 崩溃后备库提交持久性 备库查询一致性 @@ -1849,7 +1769,7 @@ include_dir 'conf.d' - 用来向强制 WAL 更新到磁盘的方法。如果fsync是关闭的,那么这个设置就不相关,因为 WAL 文件更新将根本不会被强制。可能的值是: + 用于将 WAL 更新强制写入磁盘的方法。如果fsync关闭,此设置就没有作用,因为 WAL 文件更新根本不会被强制写入磁盘。可选值为: @@ -1873,7 +1793,7 @@ include_dir 'conf.d' - fsync_writethrough(在每次提交时调用fsync(),强制任何磁盘写高速缓存的直通写) + fsync_writethrough(在每次提交时调用fsync(),强制穿透任何磁盘写缓存) @@ -1885,10 +1805,10 @@ include_dir 'conf.d' - open_* 选项也可以使用O_DIRECT(如果可用)。 + open_* 选项还会使用O_DIRECT(如果可用)。 不是在所有平台上都能使用所有这些选择。 - 默认值是列表中第一个被平台支持的那个, 不过fdatasync是 Linux和FreeBSD中的默认值。 - 默认值不一定是最理想的;有可能需要修改这个设置或系统配置的其他方面来创建一个崩溃-安全的配置,或达到最佳性能。 + 默认值是列表中第一个被平台支持的那个, 不过fdatasync是 Linux 和 FreeBSD 中的默认值。 + 默认值不一定最合适;可能需要更改此设置或系统配置的其他方面,以确保崩溃时的数据安全或达到最佳性能。 这些方面在中讨论。 这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 @@ -1903,11 +1823,11 @@ include_dir 'conf.d' - 当这个参数为打开时,PostgreSQL服务器在一个检查点之后的页面的第一次修改期间将每个页面的全部内容写到 WAL 中。这么做是因为在操作系统崩溃期间正在处理的一次页写入可能只有部分完成,从而导致在一个磁盘页面中混合有新旧数据。在崩溃后的恢复期间,通常存储在 WAL 中的行级改变数据不足以完全恢复这样一个页面。存储整页镜像可以保证页面被正确存储,但代价是增加了必须被写入 WAL 的数据量(因为 WAL 重放总是从一个检查点开始,所以在检查点后每个页面的第一次改变时这样做就够了。因此,一种减小全页面写开销的方法是增加检查点间隔参数值)。 + 启用此参数时,PostgreSQL服务器会在检查点之后首次修改每个磁盘页面时,将该页面的全部内容写入 WAL。这样做是因为,操作系统崩溃时正在进行的页面写入可能只完成了一部分,导致磁盘页面混有新旧数据。通常存储在 WAL 中的行级变更数据不足以在崩溃恢复时完整还原这样的页面。保存整页镜像能保证正确恢复页面,但会增加必须写入 WAL 的数据量。(由于 WAL 重放总是从检查点开始,只需在检查点之后首次修改每个页面时这样做。因此,减少整页写入开销的一种方法是增大检查点间隔参数。) - 把这个参数关闭会加快正常操作,但是在系统失败后可能导致不可恢复的数据损坏,或者静默的数据损坏。其风险类似于关闭fsync, 但是风险较小。并且只有在对该参数建议的相同情况下才应该关闭它。 + 关闭此参数可以加快正常操作,但系统故障后可能出现不可恢复的数据损坏或静默数据损坏。风险与关闭fsync类似,虽然较小,但也只有在该参数建议的相同情形下才应关闭此参数。 @@ -1930,7 +1850,7 @@ include_dir 'conf.d' - 当这个参数为on时,PostgreSQL服务器一个检查点之后页面被第一次修改期间把该磁盘页面的整个内容都写入 WAL,即使对所谓的提示位做非关键修改也会这样做。 + 当这个参数为on时,PostgreSQL服务器在检查点之后首次修改页面时把该磁盘页面的整个内容都写入 WAL,即使对所谓的提示位做非关键修改也会这样做。 @@ -1952,11 +1872,11 @@ include_dir 'conf.d' - 当这个参数为on时,PostgreSQL服务器在打开时或在基础备份期间,压缩写入WAL的整页镜像。在WAL回放期间将对压缩的页面镜像进行解压。默认值是off。只有超级用户能更改这个设置。 + 当这个参数为on时,PostgreSQL服务器在打开时或在基础备份期间,压缩写入WAL的整页镜像。在 WAL 重放期间将对压缩的整页镜像进行解压。默认值是off。只有超级用户能更改这个设置。 - 开启这个参数可以在不增加不可恢复的数据损坏风险的情况下减少WAL数据量,但代价是在WAL记录期间用于压缩以及在WAL回放期间用于解压的额外CPU开销。 + 开启此参数可以减少 WAL 数据量,而且不会增加不可恢复的数据损坏风险;代价是在记录 WAL 时压缩、重放 WAL 时解压会额外消耗一些 CPU。 @@ -1974,7 +1894,7 @@ include_dir 'conf.d' - 在每次事务提交时,WAL 缓冲区的内容被写出到磁盘,因此极大的值不可能提供显著的收益。不过,把这个值设置为几个兆字节可以在一个繁忙的服务器(其中很多客户端会在同一时间提交)上提高写性能。由默认设置 -1 选择的自动调节将在大部分情况下得到合理的结果。 + 在每次事务提交时,WAL 缓冲区的内容被写出到磁盘,因此极大的值不太可能带来显著收益。不过,把这个值设置为至少几个兆字节可以在一个繁忙的服务器(其中很多客户端会在同一时间提交)上提高写性能。由默认设置 -1 选择的自动调节将在大部分情况下得到合理的结果。 @@ -2022,18 +1942,18 @@ include_dir 'conf.d' - 设置commit_delay会在执行WAL刷新之前添加以微秒为单位的时间延迟。 + 设置commit_delay会在发起 WAL 刷盘之前添加以微秒为单位的时间延迟。 如果系统负载足够高,使得在给定时间间隔内有更多事务准备提交, - 这可以通过允许更多事务通过单个WAL刷新来提高组提交吞吐量。 - 然而,这也会增加延迟,最多为每个WAL刷新的commit_delay微秒。 - 因为如果没有其他事务准备提交,延迟就是浪费的,所以只有在至少有 - commit_siblings其他事务活动时才会执行延迟, - 当要启动刷新时,如果fsync被禁用,则不会执行延迟。 + 这可以通过允许更多事务通过一次 WAL 刷盘来提高组提交吞吐量。 + 不过,每次 WAL 刷盘的延迟也会因此增加,最多增加commit_delay微秒。 + 如果没有其他事务准备提交,等待就没有意义,因此仅当即将发起刷盘时至少还有 + commit_siblings个其他活动事务,才会等待。 + 此外,如果禁用了fsync,也不会等待。 默认commit_delay为零(无延迟)。 只有超级用户能更改这个设置。 - 在PostgreSQL的 9.3 发布之前,commit_delay的行为不同并且效果更差:它只影响提交,而不是所有 WAL 刷写,并且即使在 WAL 刷写马上就要完成时也会等待一整个配置的延迟。从PostgreSQL 9.3 中开始,第一个准备好刷写的进程会等待配置的间隔,而后续的进程只等到领先者完成刷写操作。 + 在PostgreSQL的 9.3 发布之前,commit_delay的行为不同并且效果更差:它只影响提交,而不是所有 WAL 刷写,并且即使 WAL 刷盘更早完成,也会等待整个配置的延迟时间。从PostgreSQL 9.3 开始,第一个准备好刷写的进程会等待配置的间隔,而后续的进程只等到领先者完成刷写操作。 @@ -2048,7 +1968,7 @@ include_dir 'conf.d' - 在执行commit_delay延迟时,要求的并发活动事务的最小数目。大一些的值会导致在延迟间隔期间更可能有至少另外一个事务准备好提交。默认值是五个事务。 + 执行commit_delay延迟前要求的并发活动事务的最小数目。大一些的值会导致在延迟间隔期间更可能有至少另外一个事务准备好提交。默认值是五个事务。 @@ -2068,7 +1988,7 @@ include_dir 'conf.d' 自动 WAL 检查点之间的最长时间,以秒为单位。 - 合理的范围在 30 秒到 1 天之间。默认是 5 分钟(5min)。增加这个参数的值会增加崩溃恢复所需的时间。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 + 合理的范围在 30 秒到 1 天之间。默认是 5 分钟(5min)。增加这个参数的值可能会增加崩溃恢复所需的时间。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 @@ -2097,7 +2017,7 @@ include_dir 'conf.d' 当执行检查点时写入的数据量超过checkpoint_flush_after字节时,就尝试强制 OS 把这些写发送到底层存储。 这样做将会限制内核页面高速缓存中的脏数据数量,降低在检查点末尾发出fsync或者 OS 在后台大批量写回数据时被卡住的可能性。 - 那常常会导致大幅度压缩的事务延迟,但是也有一些情况(特别是负载超过但小于 OS 页面高速缓存)的性能会降低。 + 这通常能显著降低事务延迟,但是也有一些情况(特别是负载超过但小于 OS 页面高速缓存)的性能会降低。 这种设置可能会在某些平台上没有效果。 合法的范围在0(禁用强制写回)和2MB之间。Linux 上的默认值是256kB,其他平台上是0(如果BLCKSZ不是8kB,则默认值和最大值会按比例缩放到它)。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 @@ -2168,10 +2088,9 @@ include_dir 'conf.d' 当启用archive_mode时,完成的WAL段会通过设置 - 发送到归档存储。除了off, - 要禁用,有两种模式:on和 + 发送到归档存储。除了用于禁用归档的off外,还有两种模式:onalways。在正常操作期间,这两种模式之间没有区别,但当设置为always时, - WAL归档程序在归档恢复或待机模式下也会被启用。在always模式下,从归档中恢复的所有文件 + WAL归档程序在归档恢复或备库模式下也会被启用。在always模式下,从归档中恢复的所有文件 或通过流复制传输的文件将被再次归档。详细信息请参见 @@ -2219,7 +2138,7 @@ include_dir 'conf.d' - 仅在完成的WAL段上调用。 + 只针对已完成的 WAL 段调用。 因此,如果您的服务器生成的WAL流量较少(或者在这样做时有间歇期),在事务完成和安全记录到归档存储之间可能会有很长的延迟。 为了限制未归档数据的年龄,您可以将archive_timeout设置为强制服务器定期切换到新的WAL段文件。 当此参数大于零时,只要自上次段文件切换以来经过了指定的秒数,并且存在任何数据库活动,包括单个检查点(如果没有数据库活动,则跳过检查点),服务器将切换到新的段文件。 @@ -2347,7 +2266,10 @@ include_dir 'conf.d' 主库 - 这些参数可以在发送复制数据给一个或多个备库的主库上设置。注意除了这些参数之外,在主库上必须设置合适的,并且也启用可选的 WAL 归档(见)。这些参数值与备库无关,尽管你可能希望为了准备好一个备库转变成主库来设置这些参数。 + 这些参数可以在向一个或多个备库发送复制数据的主库上设置。 + 除这些参数外,还必须在主库上适当设置 , + 也可以选择启用 WAL 归档(见 )。 + 这些参数在备库上的取值不影响备库运行,不过也可以预先设置,以备将来提升为主库。 @@ -2361,7 +2283,7 @@ include_dir 'conf.d' 所述,这个参数指定一个支持同步复制的备库的列表。 - 可能会有一个或者多个活动的同步备库,在这些备库确认收到它们的数据之后,等待提交的事务将被允许继续下去。 + 将有一个或多个活动的同步备库,在这些备库确认收到它们的数据之后,等待提交的事务将被允许继续下去。 同步备库是那些名字出现在这个列表中,并且当前已连接并且正在实时流式传输数据(如pg_stat_replication视图中streaming的状态所示)的服务器。 指定多于一台同步备库可以得到非常高的可用性并且能防止数据丢失。 @@ -2381,10 +2303,10 @@ ANY num_sync ( num_sync是事务需要等待其回复的同步备库的数量,standby_name是一个备库的名称。FIRST以及ANY指定从所列服务器中选取同步备库的方法。 - 关键词FIRST加上num_sync指定一种基于优先的同步复制,并且会让事务提交等待,直到它们的WAL记录被复制到基于优先级选择的num_sync台同步备库上为止。例如,设置FIRST 3 (s1, s2, s3, s4)将导致每次提交都等待来自三台较高优先级的备库的答复,这三台备库将从备库s1s2s3以及s4中选出。在该列表中出现较早的备库将被给予较高的优先级,并且将被考虑为同步备库。列表中出现的其他备库表示潜在的同步备库。如果当前的任何同步备库因为某种原因断开连接,它将立刻被下一个最高优先级的备库替代。关键词FIRST是可选的。 + 关键词FIRST加上num_sync指定一种基于优先级的同步复制,并且会让事务提交等待,直到它们的WAL记录被复制到基于优先级选择的num_sync台同步备库上为止。例如,设置FIRST 3 (s1, s2, s3, s4)将导致每次提交都等待来自三台较高优先级的备库的答复,这三台备库将从备库s1s2s3以及s4中选出。在该列表中出现较早的备库将被给予较高的优先级,并且将被考虑为同步备库。列表中出现的其他备库表示潜在的同步备库。如果当前的任何同步备库因为某种原因断开连接,它将立刻被下一个最高优先级的备库替代。关键词FIRST是可选的。 - 关键词ANY加上num_sync指定一种基于规定数量的同步复制,并且会让事务提交等待,直到它们的WAL记录被复制到所列出备库中的至少num_sync台上为止。例如,设置ANY 3 (s1, s2, s3, s4)将导致每次提交会在收到s1s2s3以及s4中任意三台备库的回答后立刻继续下去。 + 关键词ANY加上num_sync指定一种基于法定人数的同步复制,并且会让事务提交等待,直到它们的WAL记录被复制到所列出备库中的至少num_sync台上为止。例如,设置ANY 3 (s1, s2, s3, s4)将导致每次提交会在收到s1s2s3以及s4中任意三台备库的回答后立刻继续下去。 FIRSTANY是大小写不敏感的。如果这些关键词被用作备库的名字,其standby_name必须被放在双引号内。 @@ -2405,7 +2327,7 @@ ANY num_sync ( 参数设置为localoff。 + 如果这里没有指定同步备库名称,那么不启用同步复制并且事务提交将不会等待复制。这是默认的配置。即便当同步复制被启用时,个体事务也可以被配置为不等待复制,做法是将参数设置为localoff 这个参数只能在postgresql.conf文件中或通过服务器命令行进行设置。 @@ -2413,10 +2335,12 @@ ANY num_sync ( vacuum_defer_cleanup_age (integer) - vacuum_defer_cleanup_age 配置参数 + vacuum_defer_cleanup_age 配置参数 @@ -2436,8 +2360,7 @@ ANY num_sync ( @@ -2481,9 +2404,7 @@ ANY num_sync ( num_sync ( num_sync ( pg_stat_replication视图看到。 - 备库将报告它已经写入的上一个预写式日志位置、它已经刷到磁盘的上一个位置以及它已经应用的最后一个位置。 + 备库将报告最后写入的预写日志位置、最后刷盘的位置以及最后应用的位置。 这个参数的值是报告之间的最大间隔,以秒为单位。 - 每次写入或刷出位置改变时会发送状态更新,或者按这个参数的指定的频度发送。 + 每次写入或刷盘位置改变时会发送状态更新,或者至少按这个参数指定的频度发送。 因此,应用位置可能比真实位置略微滞后。 默认值是 10 秒。 将此参数设置为零会完全禁用状态更新。 @@ -2536,7 +2455,7 @@ ANY num_sync ( num_sync ( num_sync ( num_sync ( num_sync ( + + enable_bitmapscan (boolean) - 位图扫描 + 位图扫描 - enable_bitmapscan配置参数 + enable_bitmapscan 配置参数 - - 允许或禁止查询规划器使用位图扫描计划类型。默认值是on。 + 启用或禁用查询规划器对位图扫描计划类型的使用。默认值为 on - - + + - + + enable_gathermerge (boolean) - enable_gathermerge配置参数 + enable_gathermerge 配置参数 - - 启用或者禁用查询规划器对收集归并计划类型的使用。默认值是on。 + 启用或禁用查询规划器对收集归并计划类型的使用。默认值为 on - - + + + - + enable_hashagg (boolean) - enable_hashagg配置参数 + enable_hashagg 配置参数 - - 允许或禁用查询规划器使用哈希聚合计划类型。默认值是on。 + 启用或禁用查询规划器对哈希聚合计划类型的使用。默认值为 on - + + enable_hashjoin (boolean) - enable_hashjoin配置参数 + enable_hashjoin 配置参数 - - 允许或禁止查询规划器使用哈希连接计划类型。默认值是on。 + 启用或禁用查询规划器对哈希连接计划类型的使用。默认值为 on + + + + enable_indexscan (boolean) - 索引扫描 + 索引扫描 - enable_indexscan配置参数 + enable_indexscan 配置参数 - 允许或禁止查询规划器使用索引扫描计划类型。默认值是on。 + 启用或禁用查询规划器对索引扫描计划类型的使用。默认值为 on @@ -2756,21 +2677,22 @@ ANY num_sync ( enable_indexonlyscan (boolean) - enable_indexonlyscan配置参数 + enable_indexonlyscan 配置参数 - 允许或禁止查询规划器使用仅索引扫描计划类型(见)。默认值是on。 + 启用或禁用查询规划器对仅索引扫描计划类型的使用(参见 )。默认值为 on - + + enable_material (boolean) - enable_material配置参数 + enable_material 配置参数 @@ -2781,26 +2703,27 @@ ANY num_sync ( + + enable_mergejoin (boolean) - enable_mergejoin配置参数 + enable_mergejoin 配置参数 - - 允许或禁止查询规划器使用归并连接计划类型。默认值是on。 + 启用或禁用查询规划器对归并连接计划类型的使用。默认值为 on - + + enable_nestloop (boolean) - enable_nestloop配置参数 + enable_nestloop 配置参数 @@ -3210,7 +3133,7 @@ ANY num_sync ( constraint_exclusion (enum) - constraint exclusion + 约束排除 constraint_exclusion配置参数 @@ -3306,10 +3229,12 @@ SELECT * FROM parent WHERE key = 2400; + + force_parallel_mode (enum) - force_parallel_mode 配置参数 + force_parallel_mode 配置参数 @@ -3323,7 +3248,7 @@ SELECT * FROM parent WHERE key = 2400; 更具体地说,将此值设置为on会在任何看起来可以安全并行的查询计划顶部添加一个Gather节点, - 让查询在并行工作者中运行。即使没有可用的并行工作者或无法使用并行工作者, + 让查询在并行工作进程中运行。即使没有可用的并行工作进程或无法使用并行工作进程, 在并行查询上下文中不允许的操作(例如启动子事务)也会被禁止,除非规划器认为这会使查询失败。 如果设置此选项后出现失败或意外结果,查询使用的某些函数可能需要被标记为PARALLEL UNSAFE (也可能是PARALLEL RESTRICTED)。 @@ -3331,14 +3256,13 @@ SELECT * FROM parent WHERE key = 2400; 将此值设置为regress具有设置为on的所有效果,另外还有一些旨在方便自动回归测试的效果。 - 通常,来自并行工作者的消息会包含一行说明这一点的上下文信息,但regress设置会抑制此行,使输出与非并行执行时相同。 + 通常,来自并行工作进程的消息会包含一行说明这一点的上下文信息,但regress设置会抑制此行,使输出与非并行执行时相同。 此外,此设置添加到计划中的Gather节点会在EXPLAIN输出中隐藏, 使输出与此设置为off时的输出一致。 - - + @@ -3826,7 +3750,7 @@ local0.* /var/log/postgresql - application_name可以是任意小于NAMEDATALEN个字符(标准编译中是 64 个字符)的字符串。这通常由一个应用通过到服务器的连接设置。该名称将被显示在pg_stat_activity视图中并被包括在 CSV 日志项中。它也会被通过包括在普通日志项中。只有可打印 ASCII 字符能被使用在application_name之中。其他字符将被替换为问号(?)。 + application_name可以是任意小于NAMEDATALEN个字符(标准编译中是 64 个字符)的字符串。应用通常在连接服务器时设置此值。该名称将被显示在pg_stat_activity视图中并被包括在 CSV 日志项中。它也会被通过包括在普通日志项中。只有可打印 ASCII 字符能被使用在application_name之中。其他字符将被替换为问号(?)。 @@ -3905,7 +3829,7 @@ local0.* /var/log/postgresql - 某些客户端程序(例如psql)在要求密码时会尝试连接两次,因此重复的收到连接消息并不一定表示一个错误。 + 某些客户端程序(例如psql)在判断是否需要密码时会尝试连接两次,因此重复的收到连接消息并不一定表示一个错误。 @@ -4101,7 +4025,7 @@ local0.* /var/log/postgresql %% - 纯文字 % + 字面字符 % @@ -4125,7 +4049,7 @@ FROM pg_stat_activity; - Syslog产生自己的时间戳和进程 ID 信息,因此如果你记录到syslog你可能不希望包括哪些转义。 + Syslog产生自己的时间戳和进程 ID 信息,因此如果你记录到syslog你可能不希望包括那些转义。 @@ -4370,13 +4294,14 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; 运行时统计数据 - 累积查询和索引统计 + 查询和索引统计信息收集器 - 这些参数控制服务器范围内的累积统计系统。 - 启用后,收集的数据可以通过pg_statpg_statio - 系列系统视图进行访问。有关更多信息,请参阅。 - + 这些参数控制服务器范围内的统计信息收集功能。 + 启用统计信息收集后,产生的数据可以通过pg_stat和 + pg_statio系列系统视图进行访问。 + 更多信息请参阅。 + @@ -4556,7 +4481,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 注意即使该参数被禁用,系统也会在需要防止事务ID回卷时发起清理进程。详情请见。 + 注意即使该参数被禁用,系统也会在需要防止事务ID回卷时发起自动清理进程。详情请见 @@ -4601,7 +4526,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 指定自动清理在任意给定数据库上运行的最小延迟。在每一轮中后台进程检查数据库并根据需要为数据库中的表发出VACUUMANALYZE命令。 + 指定自动清理在任意给定数据库上各次运行之间的最小间隔。在每一轮中后台进程检查数据库并根据需要为数据库中的表发出VACUUMANALYZE命令。 延迟以秒为单位。默认值为1分钟(1min)。该参数只能在postgresql.conf文件或在服务器命令行上设置。 @@ -4722,7 +4647,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 指定用于自动VACUUM操作中的代价限制值。如果指定-1(默认值),则使用值。注意该值被按比例地分配到运行中的自动清理工作者上(如果有多个),因此每一个工作者的限制值之和不会超过这个变量中的值。该参数只能在postgresql.conf文件或在服务器命令中设置。但是对个别表可以通过修改表存储参数来覆盖该设置。 + 指定用于自动VACUUM操作中的代价限制值。如果指定-1(默认值),则使用值。注意该值被按比例地分配到运行中的自动清理工作进程上(如果有多个),因此每一个工作进程的限制值之和不会超过这个变量中的值。该参数只能在postgresql.conf文件或在服务器命令中设置。但是对个别表可以通过修改表存储参数来覆盖该设置。 @@ -4766,7 +4691,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; search_path配置参数 - pathfor schemas + 路径用于模式 @@ -4838,7 +4763,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; default_tablespace配置参数 - tablespacedefault + 表空间默认 @@ -4915,7 +4840,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; default_transaction_isolation (enum) - transaction isolation level + 事务隔离级别 设置默认值 @@ -4938,7 +4863,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; default_transaction_read_only (boolean) - read-only transaction + 只读事务 设置默认值 @@ -4960,7 +4885,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; default_transaction_deferrable (boolean) - deferrable transaction + 可延迟事务 设置默认值 @@ -4986,7 +4911,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; transaction_isolation (enum) - transaction isolation level + 事务隔离级别 transaction_isolation配置参数 @@ -5006,7 +4931,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; transaction_read_only (boolean) - read-only transaction + 只读事务 transaction_read_only 配置参数 @@ -5026,7 +4951,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; transaction_deferrable (boolean) - deferrable transaction + 可延迟事务 transaction_deferrable 配置参数 @@ -5126,7 +5051,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 当表的pg_class.relfrozenxid字段达到该设置指定的年龄时,VACUUM会执行激进扫描。激进扫描与常规VACUUM不同,它会访问每一个可能包含未冻结 XID 或 MXID 的页面,而不仅仅是那些可能包含死元组的页面。默认值是 1.5 亿个事务。尽管用户可以将该值设置为 0 到 20 亿之间的任意值,VACUUM会悄悄将有效值调整为的 95%,从而在触发防回卷 autovacuum 之前仍有机会执行一次常规手工VACUUM。更多信息请参见。 + 当表的pg_class.relfrozenxid字段达到该设置指定的年龄时,VACUUM会执行激进扫描。激进扫描与常规VACUUM不同,它会访问每一个可能包含未冻结 XID 或 MXID 的页面,而不仅仅是那些可能包含死元组的页面。默认值是 1.5 亿个事务。尽管用户可以将该值设置为 0 到 20 亿之间的任意值,VACUUM会悄悄将有效值限制为不超过的 95%,从而在触发防回卷 autovacuum 之前仍有机会执行一次常规手工VACUUM。更多信息请参见 @@ -5139,7 +5064,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 指定VACUUM在扫描表时用来决定是否冻结行版本的切断年龄(以事务计)。默认值是 5000 万个事务。尽管用户可以将该值设置为 0 到 10 亿之间的任意值,VACUUM会悄悄将有效值调整为的一半,这样强制 autovacuum 之间就不会间隔过短。更多信息请参见。 + 指定VACUUM在扫描表时用来决定是否冻结行版本的切断年龄(以事务计)。默认值是 5000 万个事务。尽管用户可以将该值设置为 0 到 10 亿之间的任意值,VACUUM会悄悄将有效值限制为不超过的一半,这样强制 autovacuum 之间就不会间隔过短。更多信息请参见 @@ -5152,7 +5077,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 当表的pg_class.relminmxid字段达到该设置指定的年龄时,VACUUM会执行激进扫描。激进扫描与常规VACUUM不同,它会访问每一个可能包含未冻结 XID 或 MXID 的页面,而不是只扫描那些可能包含死元组的页面。默认值是 1.5 亿个多事务。尽管用户可以将该值设置为 0 到 20 亿之间的任意值,VACUUM会悄悄将有效值调整为的 95%,从而在触发防回卷 autovacuum 之前仍有机会执行一次常规手工VACUUM。更多信息请参见。 + 当表的pg_class.relminmxid字段达到该设置指定的年龄时,VACUUM会执行激进扫描。激进扫描与常规VACUUM不同,它会访问每一个可能包含未冻结 XID 或 MXID 的页面,而不是只扫描那些可能包含死元组的页面。默认值是 1.5 亿个多事务。尽管用户可以将该值设置为 0 到 20 亿之间的任意值,VACUUM会悄悄将有效值限制为不超过的 95%,从而在触发防回卷 autovacuum 之前仍有机会执行一次常规手工VACUUM。更多信息请参见 @@ -5165,7 +5090,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 指定VACUUM在扫描表时用来决定是否将 multixact ID 替换为较新的事务 ID 或 multixact ID 的切断年龄(以 multixact 计)。默认值是 5000 万个 multixact。尽管用户可以将该值设置为 0 到 10 亿之间的任意值,VACUUM会悄悄将有效值调整为的一半,这样强制 autovacuum 之间就不会间隔过短。更多信息请参见。 + 指定VACUUM在扫描表时用来决定是否将多事务 ID 替换为较新的事务 ID 或多事务 ID 的切断年龄(以多事务计)。默认值是 500 万个多事务。尽管用户可以将该值设置为 0 到 10 亿之间的任意值,VACUUM会悄悄将有效值限制为不超过的一半,这样强制 autovacuum 之间就不会间隔过短。更多信息请参见 @@ -5214,7 +5139,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; SET XML OPTION - XML option + XML 选项 @@ -5293,7 +5218,7 @@ SET XML OPTION { DOCUMENT | CONTENT }; TimeZone配置参数 - time zone + 时区 @@ -5309,7 +5234,7 @@ SET XML OPTION { DOCUMENT | CONTENT }; timezone_abbreviations配置参数 - time zone names + 时区名称 @@ -5322,11 +5247,11 @@ SET XML OPTION { DOCUMENT | CONTENT }; extra_float_digits (integer) - significant digits + 有效数字 - floating-point - display + 浮点数 + 显示 extra_float_digits配置参数 @@ -5348,7 +5273,7 @@ SET XML OPTION { DOCUMENT | CONTENT }; client_encoding配置参数 - character set + 字符集 @@ -5646,12 +5571,12 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' deadlock_timeout (integer) - deadlock + 死锁 期间超时 - timeout - deadlock + 超时 + 死锁 deadlock_timeout配置参数 @@ -5684,12 +5609,11 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' 共享锁表跟踪在max_locks_per_transaction * ( + ) 个对象(如表)上的锁。因此,在任何一个时刻,只有不超过这么多个可区分对象能够被锁住。这个参数控制为每个事务分配的对象锁的平均数量。个体事务可以锁住更多对象,数量可以和锁表中能容纳的所有事务的锁一样多。这是能被锁住的行数,那个值是没有限制的。默认值 64 已经被历史证明是足够的,但是如果你有需要在一个事务中使用很多不同表的查询(例如查询一个有很多子表的父表),你可能需要提高这个值。这个参数只能在服务器启动时设置。 + linkend="guc-max-prepared-transactions">) 个对象(如表)上的锁。因此,在任何一个时刻,只有不超过这么多个可区分对象能够被锁住。这个参数控制为每个事务分配的对象锁的平均数量。只要所有事务的锁都能放入锁表中,单个事务就可以锁住更多对象。这是能被锁住的行数,那个值是没有限制的。默认值 64 已经被历史证明是足够的,但是如果你有需要在一个事务中使用很多不同表的查询(例如查询一个有很多子表的父表),你可能需要提高这个值。这个参数只能在服务器启动时设置。 - 当运行一个备库时,你必须设置这个参数等于或大于主库上的参数。 - 否则,备库上将不允许查询。 + 运行备库时,必须将此参数设置为大于或等于主库上的值。否则,备库上将不允许查询。 @@ -5706,7 +5630,7 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' 共享谓词锁表跟踪在max_pred_locks_per_transaction * ( + ) 个对象(如表)上的锁。因此,在任何一个时刻,只有不超过这么多个可区分对象能够被锁住。这个参数控制为每个事务分配的对象锁的平均数量。个体事务可以锁住更多对象,数量可以和锁表中能容纳的所有事务的锁一样多。这是能被锁住的行数,那个值是没有限制的。默认值 64 已经在测试中被证明通常是足够的,但是如果你有需要在一个可串行化事务中使用很多不同表的查询(例如查询一个有很多子表的父表),你可能需要提高这个值。这个参数只能在服务器启动时设置。 + linkend="guc-max-prepared-transactions">) 个对象(如表)上的锁。因此,在任何一个时刻,只有不超过这么多个可区分对象能够被锁住。这个参数控制为每个事务分配的对象锁的平均数量。只要所有事务的锁都能放入锁表中,单个事务就可以锁住更多对象。这是能被锁住的行数,那个值是没有限制的。默认值 64 已经在测试中被证明通常是足够的,但是如果你有会在单个可串行化事务中访问许多不同表的客户端,则可能需要提高这个值。这个参数只能在服务器启动时设置。 @@ -5773,7 +5697,7 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' backslash_quote (enum) - stringsbackslash quotes + 字符串反斜线引号 backslash_quote配置参数 @@ -5814,7 +5738,7 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' escape_string_warning (boolean) - strings转义警告 + 字符串转义警告 escape_string_warning配置参数 @@ -5887,7 +5811,7 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' standard_conforming_strings (boolean) - stringsstandard conforming + 字符串标准符合 standard_conforming_strings配置参数 @@ -6091,10 +6015,12 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' + + lc_collate (string) - lc_collate 配置参数 + lc_collate 配置参数 @@ -6105,10 +6031,12 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' + + lc_ctype (string) - lc_ctype 配置参数 + lc_ctype 配置参数 @@ -6185,7 +6113,7 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' server_encoding配置参数 - character set + 字符集 @@ -6379,10 +6307,12 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' + + trace_recovery_messages (enum) - trace_recovery_messages 配置参数 + trace_recovery_messages 配置参数 diff --git a/zh/10/datatype.sgml b/zh/10/datatype.sgml index 24289add..b92b994c 100644 --- a/zh/10/datatype.sgml +++ b/zh/10/datatype.sgml @@ -341,19 +341,19 @@ smallint 2字节 小范围整数 - -32768 to +32767 + -32768 到 +32767 integer 4字节 整数的典型选择 - -2147483648 to +2147483647 + -2147483648 到 +2147483647 bigint 8字节 大范围整数 - -9223372036854775808 to +9223372036854775807 + -9223372036854775808 到 +9223372036854775807 @@ -696,7 +696,10 @@ FROM generate_series(-3.5, 3.5, 1) as x; - 本节描述的是 PostgreSQL 特有的创建自动递增列的方法。另一种方法是使用 SQL 标准的标识列特性,参见 + + 本节介绍 PostgreSQL 特有的自动递增列创建方法。 + 另一种方法是使用 SQL 标准的标识列特性,参见。 + @@ -774,7 +777,7 @@ ALTER SEQUENCE tablename_money 类型以固定的小数精度存储货币金额; 参见 。小数精度由数据库的 设置决定。表中显示的范围假定 - 有两位小数。输入支持多种格式,包括整数和浮点文字,以及典型的 + 有两位小数。输入支持多种格式,包括整数字面量和浮点数字面量,以及典型的 货币格式,例如 '$1,000.00'。输出通常也采用 后一种形式,但会受到区域设置影响。 @@ -1167,7 +1170,7 @@ SELECT '\xDEADBEEF';
- <type>bytea</type>文字转义字节 + <type>bytea</type>字面量中需要转义的字节 @@ -3611,17 +3614,16 @@ a0ee-bc99-9c0b-4ef8-bb6d-6bb9-bd38-0a11 xml 数据类型可用于存储 XML 数据。与把 XML 数据存储在 - text 字段中相比,它的优势在于会检查输入值是否格式 - 良好,并且提供了可执行类型安全操作的支持函数;见 - 。使用该数据类型要求安装时启用 + text 字段中相比,它的优势在于会检查输入值的良构性,并且提供了可执行类型安全操作的支持函数;见 + 。使用该数据类型要求构建时使用 configure --with-libxml - xml 类型既可以存储符合 XML 标准定义的格式良好的 + xml 类型既可以存储 XML 标准所定义的良构 文档,也可以存储 内容 片段;后者是参照 XQuery 和 XPath 数据模型中更宽松的 - document node + 文档节点 概念来定义的。粗略地说,这意味着内容片段可以拥有多个顶层元素或字符 节点。表达式 xmlvalue IS DOCUMENT diff --git a/zh/10/dblink.sgml b/zh/10/dblink.sgml index 1688dd91..7c65b0eb 100644 --- a/zh/10/dblink.sgml +++ b/zh/10/dblink.sgml @@ -7,9 +7,13 @@ dblink - dblink模块支持在一个数据库会话中连接到其他PostgreSQL数据库。 + + dblink 是一个支持在数据库会话内连接到其他 PostgreSQL 数据库的模块。 + - 另请参阅,它使用更现代、符合标准的基础设施提供了大致相同的功能。 + + 另请参见 ,它使用更现代且更符合标准的基础设施提供了基本相同的功能。 + @@ -91,7 +95,7 @@ dblink_connect(text connname, text connstr) returns text 注解 - 如果不可信用户能够访问一个尚未采用模式的安全使用方式的数据库,则应在每个会话开始时从 + 如果不受信任的用户能够访问一个尚未采用模式的安全使用方式的数据库,则应在每个会话开始时从 search_path 中移除公共可写模式。例如,可以把 options=-csearch_path= 加到 connstr 中。这个注意事项并非 dblink 所特有;它适用于每一种执行任意 SQL 命令的接口。 @@ -125,9 +129,9 @@ SELECT dblink_connect('myconn', 'dbname=postgres options=-csearch_path='); OK (1 row) --- FOREIGN DATA WRAPPER functionality --- Note: local connection must require password authentication for this to work properly --- Otherwise, you will receive the following error from dblink_connect(): +-- FOREIGN DATA WRAPPER 功能 +-- 注意:要使本例正常工作,本地连接必须要求密码认证。 +-- 否则,dblink_connect() 将报告以下错误: -- ---------------------------------------------------------------------- -- ERROR: password is required -- DETAIL: Non-superuser cannot connect if the server does not request a password. @@ -143,13 +147,13 @@ GRANT SELECT ON TABLE foo TO regress_dblink_user; \set ORIGINAL_USER :USER \c - regress_dblink_user SELECT dblink_connect('myconn', 'fdtest'); - dblink_connect + dblink_connect ---------------- OK (1 row) SELECT * FROM dblink('myconn', 'SELECT * FROM foo') AS t(a int, b text, c text[]); - a | b | c + a | b | c ----+---+--------------- 0 | a | {a0,b0,c0} 1 | b | {a1,b1,c1} @@ -391,7 +395,7 @@ SELECT * WHERE proname LIKE 'bytea%'; - FROM 子句中的 alias 部分必须指定该函数将返回的列名和类型。(在别名中指定列名实际上是标准 SQL 语法,但指定列类型则是 + FROM 子句中的 别名 部分必须指定该函数将返回的列名和类型。(在别名中指定列名实际上是标准 SQL 语法,但指定列类型则是 PostgreSQL 的扩展。)这样系统才能在尝试执行该函数之前,就知道 * 应展开成什么,以及 WHERE 子句中的 proname 指的是什么。运行时,如果远程数据库返回的实际查询结果与 diff --git a/zh/10/dfunc.sgml b/zh/10/dfunc.sgml index 3e9b8c98..65a89f66 100644 --- a/zh/10/dfunc.sgml +++ b/zh/10/dfunc.sgml @@ -1,7 +1,7 @@ - 编译和链接动态载入的函数 + 编译和链接动态装载函数 在你能够使用以 C 编写的 PostgreSQL 扩展函数之前, @@ -46,7 +46,7 @@ FreeBSD - FreeBSDshared library + FreeBSD共享库 @@ -64,7 +64,7 @@ gcc -shared -o foo.so foo.o HP-UX - HP-UXshared library + HP-UX共享库 @@ -91,7 +91,7 @@ ld -b -o foo.sl foo.o Linux - Linuxshared library + Linux共享库 @@ -108,7 +108,7 @@ cc -shared -o foo.so foo.o macOS - macOSshared library + macOS共享库 @@ -124,7 +124,7 @@ cc -bundle -flat_namespace -undefined suppress -o foo.so foo.o NetBSD - NetBSDshared library + NetBSD共享库 @@ -142,7 +142,7 @@ gcc -shared -o foo.so foo.o OpenBSD - OpenBSDshared library + OpenBSD共享库 @@ -159,7 +159,7 @@ ld -Bshareable -o foo.so foo.o Solaris - Solarisshared library + Solaris共享库 diff --git a/zh/10/diskusage.sgml b/zh/10/diskusage.sgml index 3ed2a756..56746571 100644 --- a/zh/10/diskusage.sgml +++ b/zh/10/diskusage.sgml @@ -23,7 +23,7 @@ - 在最近做过 vacuum 或 analyze 的数据库上使用psql时,可以发出查询以查看任意表的磁盘使用情况: + 在最近进行过清理或分析 的数据库上使用psql时,可以发出查询以查看任意表的磁盘使用情况: SELECT pg_relation_filepath(oid), relpages FROM pg_class WHERE relname = 'customer'; @@ -71,7 +71,7 @@ ORDER BY c2.relname; - 利用这些信息,可以很容易找出最大的表和索引: + 利用这些信息,你可以很容易地找出最大的表和索引: SELECT relname, relpages FROM pg_class @@ -82,15 +82,15 @@ ORDER BY relpages DESC; bigtable | 3290 customer | 3144 - + 磁盘已满故障 - 数据库管理员最重要的磁盘监控任务,是确保磁盘不会被写满。数据盘被写满不会导致数据损坏,但可能使有用的活动无法继续进行。如果存放 WAL 文件的磁盘逐渐被写满,数据库服务器可能会进入 panic 状态并随后关闭。 - + 数据库管理员最重要的磁盘监控任务,是确保磁盘不会被写满。数据磁盘写满不会导致数据损坏,但可能会阻止有用的活动继续进行。如果保存 WAL 文件的磁盘被写满,则数据库服务器可能会 panic 并随后关闭。 + 如果无法通过删除其他内容来释放磁盘上的额外空间,可以利用表空间将部分数据库文件移到其他文件系统上。有关更多信息,请参见。 @@ -98,12 +98,12 @@ ORDER BY relpages DESC; - 有些文件系统在接近写满时性能很差,因此不要等到磁盘完全写满才采取措施。 - + 有些文件系统在接近写满时性能会明显变差,因此不要等到磁盘完全写满才采取措施。 + - 如果系统支持按用户设置磁盘配额,那么数据库自然会受限于运行服务器的那个用户所被施加的配额。超出配额与磁盘空间完全耗尽会产生同样的不良影响。 - + 如果你的系统支持按用户设置磁盘配额,那么数据库自然也会受到运行服务器的那个用户所拥有配额的限制。超出配额会带来与磁盘空间完全耗尽相同的不良影响。 + diff --git a/zh/10/docguide.sgml b/zh/10/docguide.sgml index e1e0ee48..ddbc0e4c 100644 --- a/zh/10/docguide.sgml +++ b/zh/10/docguide.sgml @@ -302,18 +302,26 @@ checking for fop... fop 这也是默认目标。输出位于子目录html中。 - 要生成 HTML 文档,并采用以下站点使用的样式表:postgresql.org,以替代默认的简单样式,请使用: + + 若要使用postgresql.org上所使用的样式表, + 而不是默认的简单样式来生成 HTML 文档,请使用: + doc/src/sgml$ make STYLE=website html + 手册页 - 我们使用 DocBook XSL 样式表转换DocBook - refentry页面,生成适用于手册页的 *roff 输出。手册页也以 tar 归档包形式分发,类似于HTML版本。要创建手册页,请使用以下命令: + + 我们使用 DocBook XSL 样式表将DocBook + refentry页面转换为适合手册页的 *roff 输出。 + 与HTML版本类似,手册页也以 tar 归档包形式分发。 + 要创建手册页,请使用以下命令: + doc/src/sgml$ make man @@ -322,16 +330,24 @@ checking for fop... fop PDF - 要生成 PDF 格式的文档,可以使用FOP,并根据所需纸张格式,选择以下命令之一: + + 要使用FOP生成文档的 PDF 版本, + 可根据所偏好的纸张格式使用下列命令之一: + + - 对于 A4 格式: + + 对于 A4 格式: + doc/src/sgml$ make postgres-A4.pdf - 对于美国信纸格式: + + 对于美国信纸格式: + doc/src/sgml$ make postgres-US.pdf @@ -339,30 +355,49 @@ checking for fop... fop - 由于 PostgreSQL 文档相当庞大,FOP需要大量内存。因此,在某些系统上,构建会失败并报告与内存有关的错误。通常可以通过在以下配置文件中调整 Java 堆设置来解决此问题:~/.foprc,例如: -# FOP binary distribution + + 由于 PostgreSQL 文档相当庞大,FOP需要占用相当多的内存。 + 因此,在某些系统上,构建会因内存相关错误而失败。这通常可以通过在配置文件 + ~/.foprc中配置 Java 堆设置来解决,例如: + +# FOP 二进制发行版 FOP_OPTS='-Xmx1500m' # Debian JAVA_ARGS='-Xmx1500m' # Red Hat ADDITIONAL_FLAGS='-Xmx1500m' -所需内存存在一个最低限度,而在一定范围内,更多内存似乎能使构建稍快一些。在内存很少(不足 1 GB)的系统上,构建要么因交换而非常缓慢,要么根本无法进行。 + + 所需内存存在一个最低门槛,而且在一定程度上,内存越多似乎会让构建稍快一些。 + 对于内存很少(小于 1 GB)的系统,构建要么会因交换而非常缓慢,要么根本无法工作。 + - 其他 XSL-FO 处理器也可以手动使用,但自动构建过程只支持 FOP。 + + + 也可以手工使用其他 XSL-FO 处理器,但自动化构建过程只支持 FOP。 + 纯文本文件 - 安装说明也以纯文本形式分发,以便在没有更好阅读工具的情况下使用。INSTALL文件对应于,仅为适应不同语境作了一些小改动。要重新创建该文件,请切换到doc/src/sgml目录并输入make INSTALL + + 安装说明也以纯文本形式分发,以便在没有更好的阅读工具时使用。 + INSTALL文件对应,并针对不同语境作了少量调整。 + 要重新生成该文件,请切换到doc/src/sgml目录,然后输入make INSTALL。 + - 过去,发布说明和回归测试说明也以纯文本形式分发,但这种做法已经停止。 + + 过去,发行说明和回归测试说明也曾以纯文本形式分发,但现已停止这种做法。 + 语法检查 - 构建文档可能耗时很长。但有一种方法可以只检查文档文件的语法是否正确,只需几秒钟: + + 构建文档可能非常耗时。但有一种方法可以只检查文档文件的语法是否正确, + 这只需要几秒钟: + doc/src/sgml$ make check diff --git a/zh/10/ecpg.sgml b/zh/10/ecpg.sgml index d3573cb0..77c53cc5 100644 --- a/zh/10/ecpg.sgml +++ b/zh/10/ecpg.sgml @@ -1022,7 +1022,7 @@ oid=313780, datname=testdb, size=8183012 - 结构体主变量将列尽数吸收成结构体的域。额外的列可以被分配给其他主变量。例如,上面的程序也可以使用结构体外部的size变量重新构造: + 结构体主变量吸收的列数与结构体的字段数相同。额外的列可以被分配给其他主变量。例如,上面的程序也可以使用结构体外部的size变量改写: EXEC SQL BEGIN DECLARE SECTION; typedef struct @@ -1286,7 +1286,7 @@ while (1) 用户定义的基础类型 - ECPG 并不直接支持新的用户定义的基本类型。你可以使用外部字符串表示以及类型char[]VARCHAR[]的主变量,并且这种方案事实上对很多类型都是合适和足够的。 + ECPG 并不直接支持新的用户定义的基础类型。你可以使用外部字符串表示以及类型char[]VARCHAR[]的主变量,并且这种方案事实上对很多类型都是合适和足够的。 下面的示例使用数据类型 complex,它来自 中的示例。该类型的外部字符串表示为 (%f,%f),由函数 complex_in()complex_out() 定义,见 。以下示例将复数类型的值 (1,1)(3,3) 分别插入列 ab,然后从表中查询它们。 @@ -4442,7 +4442,7 @@ EXEC SQL INCLUDE "filename"; 当前目录 /usr/local/include - PostgreSQL 的包括目录,在编译时定义(例如/usr/local/pgsql/include + PostgreSQL 的头文件目录,在编译时定义(例如/usr/local/pgsql/include /usr/include @@ -5156,7 +5156,7 @@ DATABASE connection_target 使用 user_name/passworduser_name IDENTIFIED BY password或者 - user_name USING password之一,这个参数也能指定用户名和密码. + user_name USING password之一,这个参数也能指定用户名和密码。 @@ -7168,19 +7168,19 @@ int rjulmdy(date d, short mdy[3]); rdefmtdate - 使用格式掩码将字符字符串转换为日期类型的值。 + 使用格式掩码将字符串转换为日期类型的值。 int rdefmtdate(date *d, char *fmt, char *str); - 该函数接收一个指向应该保存操作结果的日期值的指针(d), - 用于解析日期的格式掩码(fmt)和包含日期文本表示的C char*字符串 - (str)。文本表示应与格式掩码匹配。但是,你不需要将字符串 - 与格式掩码进行一一映射。该函数仅分析顺序顺序,并查找表示年份位置的文字 + 该函数接收一个指向应该保存操作结果的日期值的指针(d), + 用于解析日期的格式掩码(fmt)和包含日期文本表示的C char*字符串 + (str)。文本表示应与格式掩码匹配。但是,你不需要将字符串 + 与格式掩码进行一一映射。该函数只分析先后顺序,并查找表示年份位置的字面文本 yyyyyy,表示月份位置的mm 和表示日期位置的dd - 该函数返回以下值: + 该函数返回以下值: diff --git a/zh/10/event-trigger.sgml b/zh/10/event-trigger.sgml index 9f9f7eaa..6c278a6f 100644 --- a/zh/10/event-trigger.sgml +++ b/zh/10/event-trigger.sgml @@ -20,11 +20,11 @@ - 事件触发器行为概览 + 事件触发器行为概述 只要与事件触发器关联的事件在其定义所在数据库中发生,事件触发器就会被触发。 - 目前唯一支持的事件有 + 目前仅支持以下事件: ddl_command_startddl_command_endtable_rewrite @@ -39,14 +39,14 @@ COMMENTGRANTREVOKE 命令即将执行之前。在事件触发器触发之前,不会检查受影响对象究竟存在还是不存在。 但有一个例外:对于以共享对象 — 数据库、角色和表空间 — - 为目标的 DDL 命令,或者针对事件触发器本身的命令,不会发生该事件。事件触发器机制 + 为目标的 DDL 命令或者针对事件触发器本身的命令,不会发生该事件。事件触发器机制 不支持这些对象类型。 ddl_command_start 也会在 SELECT INTO 命令即将执行之前发生,因为它等价于 CREATE TABLE AS - ddl_command_end 事件发生在与上述同一组命令执行之后。 + ddl_command_end 事件发生在上述同一组命令执行之后。 要获取这些 DDL 操作的更多细节,可在 ddl_command_end 事件触发器代码中使用集合返回函数 pg_event_trigger_ddl_commands()(见 @@ -1009,7 +1009,7 @@ CALLED_AS_EVENT_TRIGGER(fcinfo) ((fcinfo)->context != NULL && IsA((fcinfo)->context, EventTriggerData)) - 如果该宏返回 true,那么就可以安全地将 fcinfo->context + 如果该宏返回真,那么就可以安全地将 fcinfo->context 转换为 EventTriggerData * 类型,并使用它所指向的 EventTriggerData 结构体。该函数 不得修改 EventTriggerData @@ -1075,7 +1075,7 @@ typedef struct EventTriggerData 事件触发器函数必须返回一个 NULL 指针 (不是 SQL 空值,也就是不要将 - isNull 设为 true)。 + isNull 设为真)。 diff --git a/zh/10/extend.sgml b/zh/10/extend.sgml index 6a9422dd..98e68415 100644 --- a/zh/10/extend.sgml +++ b/zh/10/extend.sgml @@ -39,7 +39,7 @@ - 相关对象包(从 开始) + 相关对象的包(从 开始) @@ -49,11 +49,28 @@ 可扩展性如何运作 - PostgreSQL 之所以具有可扩展性,是因为它的运作由目录驱动。如果你熟悉标准的关系数据库系统,就会知道它们会把数据库、表、列等信息存储在通常所说的系统目录中(有些系统称之为数据字典)。这些目录对用户来说看起来和普通表无异,但 DBMS 会在其中保存自己的内部记账信息。PostgreSQL 与标准关系数据库系统的一个关键区别在于,PostgreSQL在目录中存储了更多信息:不仅包括表和列的信息,还包括数据类型、函数、访问方法等信息。这些表可以由用户修改,而 PostgreSQL 又正是基于这些表运行的,这就意味着用户可以扩展 PostgreSQL。相比之下,传统数据库系统只能通过修改源代码中的硬编码过程,或装入由 DBMS 供应商专门编写的模块来扩展。 + PostgreSQL 之所以具有可扩展性,是因为其 + 运作由系统目录驱动。如果你熟悉标准的关系数据库系统,就会知道它们把 + 有关数据库、表、列等的信息存储在通常所说的系统目录中(有些系统把这 + 称为数据字典)。这些目录对用户而言看起来就像普通表一样,但 + DBMS 会在其中保存自己的内部管理信息。 + PostgreSQL 与标准关系数据库系统的一个关键差别是, + PostgreSQL 在目录中存储的信息要多得多:不仅有关于表和列的信息,还有关于数据 + 类型、函数、访问方法等的信息。这些表可以由用户修改,而 + PostgreSQL 又是基于这些表来运行的,这意味着 + PostgreSQL 可以由用户扩展。相比之下,传统数据库 + 系统只能通过修改源代码中的硬编码过程,或加载由 + DBMS 供应商专门编写的模块来扩展。 - 此外,PostgreSQL 服务器还可以通过动态加载将用户编写的代码纳入自身。也就是说,用户可以指定一个实现新类型或新函数的目标代码文件(例如共享库),而 PostgreSQL 会在需要时加载它。把用 SQL 编写的代码加入服务器就更简单了。这种能够即时修改自身行为的能力,使 PostgreSQL 特别适合用于新应用和新存储结构的快速原型设计。 + 此外,PostgreSQL 服务器还能通过动态加载把用户 + 编写的代码纳入自身。也就是说,用户可以指定一个实现了新类型或新函数 + 的目标代码文件(例如共享库),而 PostgreSQL + 会在需要时加载它。把用 SQL 编写的代码加入服务器就更 + 为简单了。这种能够即时修改自身行为的能力,使 + PostgreSQL 特别适合用于新应用和新存储结构的快速 + 原型设计。 @@ -75,7 +92,7 @@ 数据类型 - 组合 + 复合 PostgreSQL 数据类型可以分为基础类型、复合类型、域和伪类型。 @@ -238,7 +255,7 @@ 哪些 SQL 对象种类可以成为扩展成员,见 的说明。特别是,数据库集簇范围内的对象,如数据库、角色和表空间,不能 - 成为扩展成员,因为扩展只在单个数据库内可见。(尽管扩展脚本并不禁止创 + 成为扩展成员,因为扩展只在单个数据库内可见。(尽管并不禁止扩展脚本创 建这类对象,但如果这样做,它们不会作为扩展的一部分受到跟踪。)还要注意, 虽然表可以成为扩展成员,但其附属对象(如索引)并不直接被视为扩展成员。 另一个重要点是,模式可以属于扩展,但反过来不成立:扩展本身只有一个非 @@ -279,7 +296,11 @@ directory (string) - 包含扩展的 SQL 脚本文件的目录。除非给出绝对路径,否则该名称相对于安装目录的 SHAREDIR 目录。默认行为等价于指定 directory = 'extension' + + 包含扩展 SQL 脚本文件的目录。除非给出的是绝对路 + 径,否则该名称相对于安装的 SHAREDIR 目录。默认行为 + 等价于指定 directory = 'extension'。 + @@ -445,7 +466,7 @@ 扩展,应在控制文件中设置 relocatable = false,并在脚本文件中使用 @extschema@ 来引用目标模式。在脚本执行前,该字符 - 串的每次出现都会被替换为实际目标模式的名称(必要时加双引号)。用户 + 串的每次出现都会被替换为实际目标模式的名称。用户 可以通过 CREATE EXTENSIONSCHEMA 选项设置目标模式。 @@ -457,7 +478,7 @@ relocatable = false,并把 schema 设置为预定目标模式的名称。这样将阻止使用 CREATE EXTENSIONSCHEMA - 选项,除非它指定的正是控制文件中命名的那个模式。如果扩展对其模式名 + 选项,除非它指定的正是控制文件中命名的那个模式。如果扩展对模式名 称有无法通过 @extschema@ 替换解决的内部假设,通 常就需要采用这种方式。在这种情况下, @extschema@ 替换机制仍然可用,只是由于模式名由控 @@ -606,7 +627,7 @@ SELECT pg_catalog.pg_extension_config_dump('my_config', 'WHERE NOT standard_entr 在有合适更新脚本可用的前提下, - ALTER EXTENSION UPDATE 命令可以把已安装的扩展更新 + ALTER EXTENSION UPDATE 命令会把已安装的扩展更新 到指定的新版本。更新脚本运行在 CREATE EXTENSION 为安装脚本提供的同一环境中:尤其 是,search_path 的设置方式完全相同,而且脚本创建的 @@ -619,7 +640,7 @@ SELECT pg_catalog.pg_extension_config_dump('my_config', 'WHERE NOT standard_entr (新)版本相关联的那些参数。 - 更新机制可以用于解决一个重要的特殊情况:将散装对象集合转换为扩展。在 PostgreSQL 于 9.1 加入扩展机制之前,许多人编写的扩展模块只是创建各种未打包的对象。对于包含这些对象的现有数据库,如何将它们转换为正确打包的扩展?删除它们再执行普通的 CREATE EXTENSION 是一种办法,但如果对象具有依赖关系(例如,某些表列使用扩展创建的数据类型),就不适合这样做。解决方法是先创建一个空扩展,再使用 ALTER EXTENSION ADD 将每个现有对象附加到扩展中,最后创建当前扩展版本中存在、而散装版本中没有的新对象。CREATE EXTENSION 通过 FROM old_version 选项支持这种情况:它不运行目标版本的普通安装脚本,而是运行名为 extension--old_version--target_version.sql 的更新脚本。用作 old_version 的虚拟版本名由扩展作者选择,不过通常约定使用 unpackaged。如果需要将多个先前版本更新为扩展形式,应使用不同的虚拟版本名来标识它们。 + 更新机制可以用于解决一个重要的特殊情况:将松散对象集合转换为扩展。在 PostgreSQL 于 9.1 加入扩展机制之前,许多人编写的扩展模块只是创建各种未打包的对象。对于包含这些对象的现有数据库,如何将它们转换为正确打包的扩展?删除它们再执行普通的 CREATE EXTENSION 是一种办法,但如果对象具有依赖关系(例如,某些表列使用扩展创建的数据类型),就不适合这样做。解决方法是先创建一个空扩展,再使用 ALTER EXTENSION ADD 将每个现有对象附加到扩展中,最后创建当前扩展版本中存在、而未打包版本中没有的新对象。CREATE EXTENSION 通过 FROM old_version 选项支持这种情况:它不运行目标版本的普通安装脚本,而是运行名为 extension--old_version--target_version.sql 的更新脚本。用作 old_version 的虚拟版本名由扩展作者选择,不过通常约定使用 unpackaged。如果需要将多个先前版本更新为扩展形式,应使用不同的虚拟版本名来标识它们。 ALTER EXTENSION 能够执行一系列更新脚本文件来完成 @@ -634,7 +655,7 @@ SELECT pg_catalog.pg_extension_config_dump('my_config', 'WHERE NOT standard_entr 例如,它并不知道 1.1 是否跟在 1.0 之后。它只是匹配可用的版本名,并选择需要应用 更新脚本最少的那条路径。(实际上,版本名可以是任何不包含 - --,且不以前导或尾随 - 结尾的字 + --,且不以 - 开头或结尾的字 符串。) @@ -755,7 +776,7 @@ SELECT * FROM pg_extension_update_paths('extension_namemyschema.myfunc(bigint),那么像 myschema.myfunc(42) 这样的调用,就可能被恶意函数 myschema.myfunc(integer) 截获。要注意函数和操作符 - 参数的数据类型必须与声明的实参类型精确匹配,必要时请使用显式类型转 + 所传参数的数据类型必须与声明的参数类型精确匹配,必要时请使用显式类型转 换。 @@ -800,7 +821,7 @@ SELECT * FROM pg_extension_update_paths('extension_name扩展示例 - 下面给出一个纯 SQL 扩展的完整示例:一个双元素组合 + 下面给出一个纯 SQL 扩展的完整示例:一个双元素复合 类型,它可以在两个槽位中存储任意类型的值,这两个槽位名为 kv。非文本值会自动强制转换为文本后 再存储。 @@ -872,7 +893,7 @@ include $(PGXS) 如果你打算分发自己的 PostgreSQL 扩展模块, - 那么为它们搭建一个可移植的构建系统会相当困难。因此, + 那么为它们搭建一个可移植的构建系统可能相当困难。因此, PostgreSQL 安装提供了一套称为 PGXS 的扩展构建基础设施,使简单的扩展模块可以针对 已安装好的服务器直接构建。PGXS 主要面向包含 C 代码 @@ -894,7 +915,10 @@ PGXS := $(shell $(PG_CONFIG) --pgxs) include $(PGXS) 最后三行应始终相同。在文件的前面部分,可以给变量赋值或添加自定义的make规则。 - 设置这三个变量之一,以指定构建内容: + + 设定下列三个变量中的一个,以指定要构建的内容: + + MODULES @@ -908,7 +932,7 @@ include $(PGXS) MODULE_big - 要从多个源文件构建的共享库(在 OBJS 中列出对象 + 要从多个源文件构建的共享库(在 OBJS 中列出目标 文件) @@ -918,11 +942,15 @@ include $(PGXS) PROGRAM - 要构建的可执行程序(在 OBJS 中列出对象文件) + 要构建的可执行程序(在 OBJS 中列出目标文件) - 还可以设置以下变量: + + + 还可以设置以下变量: + + EXTENSION @@ -1127,7 +1155,12 @@ include $(PGXS) make 命令行上设置都可以。 - 如果希望将构建目录单独放置,也可以运行make,并将工作目录设在扩展源码树之外。这种做法也称为VPATHVPATH构建。具体方法如下: + + 如果你想保持构建目录与源代码目录分离,也可以在扩展源代码树之外的目录 + 中运行 make。这一过程也称为 + VPATHVPATH + 构建。做法如下: + mkdir build_dir cd build_dir make -f /path/to/extension/source/tree/Makefile @@ -1154,7 +1187,7 @@ make VPATH=/path/to/extension/source/tree install 正在运行的 PostgreSQL 服务器。列在 REGRESS 中的脚本文件必须位于扩展目录下名为 sql/ 的子目录中。这些文件必须具有 - .sql 扩展名,而该扩展名不应出现在 makefile 的 + .sql 扩展名,而该扩展名不能出现在 makefile 的 REGRESS 列表中。对于每个测试,还应在名为 expected/ 的子目录中有一个包含期望输出的文件,其主 干名相同,扩展名为 .out。 diff --git a/zh/10/external-projects.sgml b/zh/10/external-projects.sgml index 207e7b97..677d729e 100644 --- a/zh/10/external-projects.sgml +++ b/zh/10/external-projects.sgml @@ -35,7 +35,7 @@ - Name + 名称 语言 注释 网站 @@ -153,7 +153,7 @@ - Name + 名称 语言 网站 diff --git a/zh/10/features.sgml b/zh/10/features.sgml index 5349223d..09807c5e 100644 --- a/zh/10/features.sgml +++ b/zh/10/features.sgml @@ -385,7 +385,7 @@ SELECT XMLQUERY('$a is $b' PASSING BY VALUE x AS a, < DOCUMENTCONTENT形式的值。 一个 XQuery/XPath 表达式的上下文项必须是单个 XML 节点或原子值, 但 XPath 1.0 又进一步限制它只能是 XML 节点,并且没有允许CONTENT的节点类型。 - 归根结底,格式良好的DOCUMENT是 + 归根结底,良构的DOCUMENTPostgreSQL能够作为 XPath 上下文项提供的唯一 XML 值形式。 diff --git a/zh/10/func.sgml b/zh/10/func.sgml index c8d8579b..3d614011 100644 --- a/zh/10/func.sgml +++ b/zh/10/func.sgml @@ -25,14 +25,14 @@ 逻辑操作符 - operator - logical + 操作符 + 逻辑 - Boolean - operators - operators, logical + 布尔 + 操作符 + 操作符,逻辑 @@ -51,15 +51,15 @@ - conjunction + 合取 - disjunction + 析取 - negation + 否定 @@ -166,8 +166,8 @@ 比较函数和操作符 - comparison - operators + 比较 + 操作符 @@ -349,12 +349,12 @@ IS NOT DISTINCT FROM - 当有一个输入为空时,普通的比较操作符会得到空(表示未知),而不是真或假。例如,7 = NULL得到空,7 <> NULL也一样。如果这种行为不合适,可以使用IS NOT DISTINCT FROM谓词: + 当任一输入为 null 时,普通的比较操作符会得到 null(表示未知),而不是真或假。例如,7 = NULL得到 null,7 <> NULL也一样。如果这种行为不合适,可以使用IS NOT DISTINCT FROM谓词: a IS DISTINCT FROM b a IS NOT DISTINCT FROM b - 对于非空输入,IS DISTINCT FROM<>操作符一样。不过,如果两个输入都为空,它会返回假。而如果只有一个输入为空,它会返回真。类似地,IS NOT DISTINCT FROM对于非空输入的行为与=相同,但是当两个输入都为空时它返回真,并且当只有一个输入为空时返回假。因此,这些谓词实际上把空值当作一种普通数据值,而不是未知。 + 对于非 null 输入,IS DISTINCT FROM<>操作符一样。不过,如果两个输入都为 null,它会返回假。而如果只有一个输入为 null,它会返回真。类似地,IS NOT DISTINCT FROM对于非 null 输入的行为与=相同,但是当两个输入都为 null 时它返回真,并且当只有一个输入为 null 时返回假。因此,这些谓词实际上把 null 当作一种普通数据值,而不是未知 @@ -370,7 +370,7 @@ NOTNULL - 要检查一个值是否为空,使用下面的谓词: + 要检查一个值是否为 null,使用下面的谓词: expression IS NULL expression IS NOT NULL @@ -380,7 +380,7 @@ expression ISNULL expression NOTNULL - null valuecomparing + 空值比较 @@ -390,7 +390,7 @@ - 有些应用可能要求表达式expression = NULLexpression得出空值时返回真。我们强烈建议这样的应用修改成遵循 SQL 标准。但是,如果这样修改不可能完成,那么我们可以使用配置变量。如果打开它,PostgreSQL将把x = NULL子句转换成x IS NULL。 + 有些应用可能期望表达式expression = NULLexpression求值为 null 时返回真。我们强烈建议此类应用修改为遵循 SQL 标准。但是,如果无法这样修改,那么可以使用配置变量。如果将其打开,PostgreSQL会把x = NULL子句转换成x IS NULL @@ -426,7 +426,7 @@ boolean_expression IS UNKNOWN boolean_expression IS NOT UNKNOWN - 这些谓词将总是返回真或假,从来不返回空值,即使操作数为空也如此。空值输入被当作逻辑值未知。请注意,IS UNKNOWNIS NOT UNKNOWN实际上分别等同于IS NULLIS NOT NULL,只是输入表达式必须是布尔类型。 + 这些谓词总是返回真或假,从不返回空值,即使操作数为 null 也是如此。null 输入被当作逻辑值未知。请注意,IS UNKNOWNIS NOT UNKNOWN实际上分别等同于IS NULLIS NOT NULL,只是输入表达式必须是布尔类型。 + 正则表达式 + @@ -2822,7 +2824,7 @@ cast(-44 as bit(12)) 111111010100 SIMILAR TO 操作符根据其模式是否匹配给定字符串返回真或假。它与 LIKE 类似,但按照 SQL 标准定义的正则表达式来解释模式。SQL 正则表达式是 LIKE 表示法和常见正则表达式表示法的一种奇特结合。 - 类似LIKESIMILAR TO操作符只有在它的模式匹配整个串的时候才能成功;这一点和普通的 正则表达式的行为不同,在普通的正则表达式里,模式匹配串的任意部分。 和LIKE类似的地方还有,SIMILAR TO使用_%作为分别代表任意单个字符和任意串的通配符(这些可以比得上 POSIX 正则表达式里的..*)。 + 与LIKE类似,SIMILAR TO操作符只有在其模式匹配整个字符串时才算成功;这一点不同于普通正则表达式,后者可以匹配字符串的任意部分。与LIKE相同,SIMILAR TO也使用_%作为通配符,分别匹配任意单个字符和任意字符串(分别类似于 POSIX 正则表达式中的..*)。 @@ -2902,8 +2904,8 @@ substring('foobar' from '#"o_b#"%' for '#') NULLPOSIX正则表达式 - regular expression - pattern matching + 正则表达式 + 模式匹配 substring @@ -2959,11 +2961,11 @@ substring('foobar' from '#"o_b#"%' for '#') NULL - POSIX正则表达式提供了比LIKESIMILAR TO操作符更强大的含义。许多 Unix 工具,例如egrepsedawk使用一种与我们这里描述的类似的模式匹配语言。 + POSIX正则表达式提供了比LIKESIMILAR TO操作符更强大的模式匹配方式。许多 Unix 工具,例如egrepsedawk,都使用与这里描述的模式匹配语言相似的语言。 - 正则表达式是一个字符序列,它是定义一个串集合 (一个正则集)的缩写。 如果一个串是正则表达式描述的正则集中的一员时, 我们就说这个串匹配该正则表达式。 和LIKE一样,模式字符准确地匹配串字符, 除非在正则表达式语言里有特殊字符 — 不过正则表达式用的 特殊字符和LIKE用的不同。 和LIKE模式不一样的是,正则表达式允许匹配串里的任何位置,除非该正则表达式显式地挂接在串的开头或者结尾。 + 正则表达式是一个字符序列,是定义一组字符串(一个正则集)的简写。如果字符串属于正则表达式描述的正则集,就称该字符串匹配此正则表达式。与LIKE一样,模式中的字符精确匹配字符串中的字符,除非该模式字符在正则表达式语言中有特殊含义 — 但正则表达式使用的特殊字符与LIKE不同。与LIKE模式不同,正则表达式可以匹配字符串中的任意位置,除非显式将其锚定到字符串开头或末尾。 下面是一些示例: @@ -2999,13 +3001,13 @@ regexp_replace('foobarbaz', 'b(..)', 'X\1Y', 'g') - regexp_match函数返回一个文本数组,其中包含与POSIX正则表达式模式对字符串的第一个匹配的子字符串。它的语法为 + regexp_match函数返回一个文本数组,包含字符串首次匹配 POSIX 正则表达式模式时捕获的子字符串。它的语法为 regexp_match(string, pattern , flags )。 如果没有匹配,结果为NULL。 - 如果找到匹配,并且pattern不包含括号子表达式,则结果是包含与整个模式匹配的子字符串的单元素文本数组。 - 如果找到匹配,并且pattern包含括号子表达式,则结果是一个文本数组,其中第n个元素是匹配 - pattern的第n个括号子表达式的子字符串(不包括非捕获括号;详情见下文)。 + 如果找到匹配,并且pattern不包含圆括号子表达式,则结果是包含与整个模式匹配的子字符串的单元素文本数组。 + 如果找到匹配,并且pattern包含圆括号子表达式,则结果是一个文本数组,其中第n个元素是匹配 + pattern的第n个圆括号子表达式的子字符串(不包括非捕获括号;详情见下文)。 flags参数是一个可选的文本字符串,其中包含零个或多个单个字母标志,用于更改函数的行为。支持的标志在中描述。 @@ -3059,16 +3061,16 @@ SELECT regexp_matches('foobarbequebazilbarfbonk', '(b[^b]+)(b[^b]+)', 'g'); - 在大部分情况下,regexp_matches()应该与g标志一起使用,因为如果只是想要第一个匹配,使用regexp_match()会更加简单高效。不过,regexp_match()仅存在于PostgreSQL版本10以及更高的版本中。当在较老的版本中使用时,一种常用的技巧是把regexp_matches()调用放在子选择中,例如: + 在大部分情况下,regexp_matches()应该与g标志一起使用,因为如果只是想要第一个匹配,使用regexp_match()会更加简单高效。不过,regexp_match()仅存在于PostgreSQL版本10以及更高的版本中。当在较老的版本中使用时,一种常用的技巧是把regexp_matches()调用放在子查询中,例如: SELECT col1, (SELECT regexp_matches(col2, '(bar)(beque)')) FROM tab; - 如果有一个匹配,则这个语句会产生一个文本数组,否则返回NULL,这和regexp_match()的做法一样。如果没有子选择,这个查询对于没有匹配的表行根本不会产生输出,显然那不是想要的行为。 + 如果有一个匹配,则这个语句会产生一个文本数组,否则返回NULL,这和regexp_match()的做法一样。如果没有子查询,这个查询对于没有匹配的表行根本不会产生输出,这通常不是预期行为。 - regexp_split_to_table把一个 POSIX 正则表达式模式当作一个定界符来分离一个串。它的语法形式是regexp_split_to_table(string, pattern , flags )。如果没有与pattern的匹配,该函数返回string。如果有至少有一个匹配,对每一个匹配它都返回从上一个匹配的末尾(或者串的开头)到这次匹配开头之间的文本。当没有更多匹配时,它返回从上一次匹配的末尾到串末尾之间的文本。flags参数是一个可选的文本串,它包含零个或更多单字母标志,这些标识可以改变该函数的行为。regexp_split_to_table能支持的标志在中描述。 + regexp_split_to_table把一个 POSIX 正则表达式模式当作一个定界符来分割字符串。它的语法形式是regexp_split_to_table(string, pattern , flags )。如果没有与pattern的匹配,该函数返回string。如果至少有一个匹配,对每一个匹配它都返回从上一个匹配的末尾(或者串的开头)到这次匹配开头之间的文本。当没有更多匹配时,它返回从上一次匹配的末尾到串末尾之间的文本。flags参数是一个可选的文本串,它包含零个或更多单字母标志,这些标志可以改变该函数的行为。regexp_split_to_table能支持的标志在中描述。 @@ -3121,9 +3123,9 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; - 正如最后一个示例所示,regexp分割函数会忽略出现在字符串开头或结尾 + 正如最后一个示例所示,正则表达式分割函数会忽略出现在字符串开头或结尾 或紧跟在前一个匹配项之后的零长度匹配。这与regexp_matchregexp_matches实现的 - 严格的regexp匹配定义相矛盾,但在实践中通常是最方便的行为。 + 严格的正则表达式匹配定义相矛盾,但在实践中通常是最方便的行为。 其他软件系统如Perl使用类似的定义。 @@ -3157,7 +3159,7 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; - 一个量化原子是一个原子, 后面可能跟着一个量词。没有量词的时候,它匹配一个原子, 有量词的时候,它可以匹配若干个原子。一个原子可以是在里面显示的任何可能。 可能的量词和它们的含义在里显示。 + 一个量化原子是一个原子,后面可以跟一个量词。没有量词时,匹配一次原子所匹配的内容;有量词时,按量词指定的次数匹配原子所匹配的内容。原子可以是列出的任何一种形式。可用量词及其含义见 @@ -3180,12 +3182,12 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; (re) - (其中re是任何正则表达式) 匹配一个对re的匹配,匹配将为可能的报告被记下 + (其中re是任意正则表达式)匹配re所匹配的内容,并记录该匹配,以备输出结果 (?:re) - 同上,但是匹配不会为了报告而被记下 (一个非捕获圆括号集) (只对 ARE) + 同上,但不记录匹配结果(非捕获圆括号;仅适用于 ARE) @@ -3200,17 +3202,17 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; \k - (其中k是一个非字母数字字符) 匹配一个被当作普通字符看待的特定字符, 例如,\\匹配一个反斜线字符 + (其中k既不是字母也不是数字)把该字符视为普通字符并匹配它,例如,\\匹配反斜线字符 \c - 其中c是一个字母数字 (可能跟着其它字符),它是一个转义, 参阅(仅对 ARE; 在 ERE 和 BRE 中,它匹配c + 其中c是字母或数字(后面可能还有其他字符),这是一个转义,参见(仅适用于 ARE;在 ERE 和 BRE 中,它匹配c { - 如果后面跟着一个字符,而不是数字, 那么就匹配左花括弧{;如果跟着一个数字, 那么它是bound的开始(见下文) + 如果后面跟着非数字字符,则匹配左花括号{;如果后面跟着数字,则是bound的开头(见下文) @@ -3228,7 +3230,7 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; - 如果你关掉了,你在文串常量中写的任何反斜线都需要被双写。详见。 + 如果你关掉了,你在字符串常量中写的任何反斜线都需要被双写。详见 @@ -3317,7 +3319,7 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; - 非贪婪的量词(只在 ARE 中可用)匹配对应的正常 (贪婪)模式,区别是它寻找最少的匹配,而不是最多的匹配。详见。 + 非贪婪量词(仅适用于 ARE)与对应的普通(贪婪)量词匹配相同的可能内容,但优先选择最少的匹配次数,而不是最多的匹配次数。详见 @@ -3344,39 +3346,39 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; ^ - 串开头的匹配 + 在字符串开头匹配 $ - 串末尾的匹配 + 在字符串末尾匹配 (?=re) - 在某个位置上,如果从该位置开始的子串能够匹配re,则匹配正向先行断言(仅对 ARE) + 正向先行断言在这样的位置匹配:存在从该位置开始且匹配re的子字符串(仅适用于 ARE) (?!re) - 在某个位置上,如果从该位置开始的子串不能匹配re,则匹配负向先行断言(仅对 ARE) + 负向先行断言在这样的位置匹配:不存在任何从该位置开始且匹配re的子字符串(仅适用于 ARE) (?<=re) - 在某个位置上,如果以该位置结束的某个子串能够匹配re,则匹配正向后行断言(仅对 ARE) + 正向后行断言在这样的位置匹配:存在以该位置结束且匹配re的子字符串(仅适用于 ARE) (?<!re) - 在某个位置上,如果以该位置结束的任何子串都不能匹配re,则匹配负向后行断言(仅对 ARE) + 负向后行断言在这样的位置匹配:不存在任何以该位置结束且匹配re的子字符串(仅适用于 ARE)
- Lookahead 和 lookbehind 约束不能包含反向引用 (参阅),并且其中的所有圆括号 都被认为是非捕获的。 + 先行和后行约束不能包含反向引用(参见),其中的所有圆括号都视为非捕获圆括号。 @@ -3384,11 +3386,11 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; 方括号表达式 - 方括号表达式是一个包围在[]中的字符列表。它通常匹配列表中的任意单个字符(但见下文)。 如果列表以^开头,它匹配任意单个在该列表参与部分中的字符。如果该列表中两个字符用-隔开, 那它就是那两个字符(包括在内)之间的所有字符范围的缩写,例如,在ASCII[0-9]匹配任何十进制数字。两个范围共享一个端点是非法的,例如,a-c-e。范围与字符集关系密切, 可移植的程序应该避免依靠它们。 + 方括号表达式是用[]括起来的字符列表。通常,它匹配列表中的任意单个字符(但请参见下文)。如果列表以^开头,则匹配任意在列表剩余部分中的单个字符。如果列表中的两个字符用-分隔,则表示排序序列中这两个字符之间的完整字符范围(包含两个端点);例如,ASCII中的[0-9]匹配任意十进制数字。两个范围共享一个端点是不合法的,例如a-c-e。范围高度依赖排序序列,因此可移植程序应避免依赖它们。 - 想在列表中包含文本],可以让它做列表的首字符(如果使用了^,需要放在其后)。 想在列表中包含文本-,可以让它做列表的首字符或者尾字符,或者一个范围的第二个端点。 想在列表中把文本-当做范围的起点, 把它用[..]包围起来,这样它就成为一个排序元素(见下文)。 除了这些字符本身、一些用[的组合(见下段)以及转义(只在 ARE 中有效)以外,所有其它特殊字符 在方括号表达式里都失去它们的特殊含义。特别是,在 ERE 和 BRE 规则下\不是特殊的, 但在 ARE 里,它是特殊的(引入一个转义)。 + 想在列表中包含字面字符],可以让它做列表的首字符(如果使用了^,需要放在其后)。 想在列表中包含字面字符-,可以让它做列表的首字符或者尾字符,或者一个范围的第二个端点。 想在列表中把字面字符-当做范围的起点, 把它用[..]包围起来,这样它就成为一个排序元素(见下文)。 除了这些字符本身、一些用[的组合(见下段)以及转义(只在 ARE 中有效)以外,所有其它特殊字符 在方括号表达式里都失去它们的特殊含义。特别是,在 ERE 和 BRE 规则下\不是特殊的, 但在 ARE 里,它是特殊的(引入一个转义)。 @@ -3403,10 +3405,10 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; - 在方括号表达式里,包围在[==]里的排序元素是一个等价类, 代表等效于那一个的所有排序元素的字符序列,包括它本身(如果没有其它等效排序元素,那么就好象封装定界符是[..])。例如,如果o^是一个等价类的成员,那么[[=o=]][[=^=]][o^]都是同义的。一个等价类不能是一个范围的端点。 + 在方括号表达式里,包围在[==]里的排序元素是一个等价类, 代表等效于那一个的所有排序元素的字符序列,包括它本身(如果没有其它等效排序元素,那么就好像封装定界符是[..])。例如,如果o^是一个等价类的成员,那么[[=o=]][[=^=]][o^]都是同义的。一个等价类不能是一个范围的端点。 - 在方括号表达式中,用 [::] 括起的字符类名表示属于该类的所有字符的列表。标准字符类名包括:alnumalphablankcntrldigitgraphlowerprintpunctspaceupperxdigit。它们表示 ctype3 中定义的字符类。区域环境可以提供其他字符类。字符类不能用作范围的端点。 + 在方括号表达式中,用 [::] 括起的字符类名表示属于该类的所有字符的列表。标准字符类名包括:alnumalphablankcntrldigitgraphlowerprintpunctspaceupperxdigit。它们表示 ctype3 中定义的字符类。区域设置可以提供其他字符类。字符类不能用作范围的端点。 方括号表达式有两个特例:[[:<:]][[:>:]] 是约束,分别匹配单词开头和结尾的空字符串。单词定义为一个前后都没有单词字符的单词字符序列。单词字符是 alnum 字符(由 ctype3 定义)或下划线。这是与 POSIX 1003.2 兼容但未由其规定的扩展,在打算移植到其他系统的软件中应谨慎使用。通常更适合使用下文介绍的约束转义;它们并不更标准,但更容易键入。 @@ -3415,11 +3417,11 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; 正则表达式转义 - 转义是以\开头,后面跟着一个字母数字字符的特殊序列。 转义有好几种变体:字符输入转义、字符类简写转义、约束转义以及反向引用。在 ARE 里, 如果一个\后面跟着一个字母数字,但是并未组成一个合法的转义, 那么它是非法的。在 ERE 中没有转义:在方括号表达式之外,一个后面跟着字母数字字符的\只是表示该字符是一个普通的字符,而且在一个方括号表达式里,\是一个普通的字符(后者实际上在 ERE 和 ARE 不兼容)。 + 转义是以\开头,后面跟着一个字母或数字字符的特殊序列。 转义有好几种变体:字符输入转义、字符类简写转义、约束转义以及反向引用。在 ARE 里, 如果一个\后面跟着一个字母或数字,但是并未组成一个合法的转义, 那么它是非法的。在 ERE 中没有转义:在方括号表达式之外,一个后面跟着字母或数字字符的\只是表示该字符是一个普通的字符,而且在一个方括号表达式里,\是一个普通的字符(后者是 ERE 与 ARE 之间唯一的实际不兼容之处)。 - 字符输入转义用于便于我们在 RE 中声明那些不可打印的或其他习惯的字符。它们显示在中。 + 字符输入转义便于在 RE 中指定不可打印或其他不便输入的字符,见 @@ -3427,13 +3429,13 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; - 约束转义是一个约束,如果满足特定的条件,它匹配该空串。它们显示在中。 + 约束转义是以转义形式书写的约束,在满足特定条件时匹配空字符串,见 反向引用\n)匹配数字n指定的被前面的圆括号子表达式匹配的同一个串 (参阅)。 例如, ([bc])\1匹配bb或者cc, 但是不匹配bc或者cb。 - RE 中子表达式必须完全在反向引用前面。子表达式以它们的先导圆括号的顺序编号。 + RE 中子表达式必须完全在反向引用前面。子表达式以它们的左圆括号的顺序编号。 非捕获圆括号并不定义子表达式。 @@ -3472,7 +3474,7 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; \e - 排序序列名为ESC的字符,如果无法做到该字符为八进制值 033 + 排序序列名称为ESC的字符;若不存在这样的字符,则使用八进制值为033的字符 @@ -3482,7 +3484,7 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; \n - 新行,和 C 中一样 + 换行符,与 C 中相同 @@ -3636,7 +3638,7 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; \Y - 只在一个词的不是开头或末尾的点上匹配 + 只在不属于单词开头或末尾的位置匹配 @@ -3648,7 +3650,7 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo;
- 一个词被定义成在上面[[:<:]][[:>:]]中的声明。在方括号表达式里,约束转义是非法的。 + 单词的定义与上文[[:<:]][[:>:]]的说明相同。方括号表达式中不允许使用约束转义。 @@ -3668,12 +3670,12 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; \m - (其中m是一个非零位)一个到第m个子表达式的反向引用 + (其中m是一个非零数字)一个到第m个子表达式的反向引用 \mnn - (其中m是一个非零位,并且nn是一些更多的位,并且十六进制值mnn不超过目前能看到的封闭捕获圆括号的数目)一个到第mnn个子表达式的反向引用 + (其中m是一个非零数字,并且nn是后续的若干数字,并且十进制值mnn不大于此前已出现的捕获右圆括号数)一个到第mnn个子表达式的反向引用 @@ -3682,7 +3684,7 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; - 在八进制字符输入转义和反向引用之间有一个历史继承的歧义存在,这个歧义是 通过下面的启发式规则解决的,像上面描述地那样。前导零总是表示这是一个八进制转义。 而单个非零数字,如果没有跟着任何其它位,那么总是被认为反向引用。 一个多位的非零开头的序列也被认为是反向引用,只要它出现在合适的子表达式后面 (也就是说,在反向引用的合法范围中的数),否则就被认为是一个八进制。 + 八进制字符输入转义与反向引用之间存在固有歧义,按上文提到的启发式规则解决:前导零始终表示八进制转义。单个非零数字,如果后面没有其他数字,始终视为反向引用。不以零开头的多位数字序列,如果前面已有相应的子表达式(即该数字在反向引用的合法范围内),则视为反向引用,否则视为八进制转义。 @@ -3695,15 +3697,11 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; - RE 可以以两种特殊的引导前缀之一开头。 - 如果 RE 以***:开头,余下部分就被视为 ARE。 - (这在PostgreSQL中通常没有影响,因为 RE 默认被视为 ARE; - 但如果通过正则表达式函数的flags参数指定了 ERE 或 BRE 模式,它就会产生影响。) - 如果 RE 以***=开头,余下部分就被视为字面字符串,所有字符都被视为普通字符。 + RE 可以以两种特殊的引导前缀之一开头。如果 RE 以***:开头,余下部分就被视为 ARE。(这在PostgreSQL中通常没有影响,因为 RE 默认被视为 ARE;但如果通过正则表达式函数的flags参数指定了 ERE 或 BRE 模式,它就会产生影响。)如果 RE 以***=开头,余下部分就作为按字面解释的字符串处理,所有字符都视为普通字符。 - 一个 ARE 可以以嵌入选项开头:一个序列(?xyz)(这里的xyz是一个或多个字母字符)声明影响剩余 RE 的选项。 这些选项覆盖任何前面判断的选项 — 特别地,它们可以覆盖一个正则表达式操作符隐含的大小写敏感的行为,或者覆盖flags参数中的正则表达式函数。可用的选项字母在中显示。注意这些同样的选项字母也被用在正则表达式函数的flags参数中。 + 一个 ARE 可以以嵌入选项开头:一个序列(?xyz)(这里的xyz是一个或多个字母字符)声明影响剩余 RE 的选项。 这些选项覆盖任何先前确定的选项 — 特别地,它们可以覆盖一个正则表达式操作符隐含的大小写敏感的行为,或者覆盖正则表达式函数的flags参数所指定的选项。可用的选项字母在中显示。注意这些同样的选项字母也被用在正则表达式函数的flags参数中。
@@ -3747,32 +3745,32 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; n - 新行敏感的匹配(见 + 换行敏感的匹配(见 p - 部分新行敏感的匹配(见 + 部分换行敏感的匹配(见 q - RE的剩余部分是一个文字(quoted)串,全部是普通字符 + RE 的剩余部分按字面(加引号)解释,所有字符都视为普通字符 s - 非新行敏感的匹配(默认) + 非换行敏感的匹配(默认) t - 紧语法(默认,见下文) + 紧凑语法(默认;见下文) w - 逆部分新行敏感(怪异)的匹配(见 + 逆部分换行敏感(怪异)的匹配(见 @@ -3784,10 +3782,13 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo;
- 嵌入选项在)终止序列时发生作用。它们只在 ARE 的开始处起作用 (在任何可能存在的***:控制器后面)。 + 嵌入选项从结束该序列的)处开始生效。它们只能出现在 ARE 的开头(如果存在***:引导前缀,则位于该前缀之后)。 - 除了通常的()RE 语法(其中所有字符都有意义)之外,还有一种扩展语法,可以通过指定嵌入的x选项来使用。在扩展语法中,RE 中的空白字符会被忽略,同样被忽略的还有#与其后的换行符(或 RE 末尾)之间的所有字符。这使得复杂的 RE 可以分段并添加注释。此基本规则有三个例外: + + 除了通常的紧凑 RE 语法(其中所有字符都有意义)之外,还有一种扩展语法,可以通过指定嵌入的x选项来使用。在扩展语法中,RE 中的空白字符会被忽略,同样被忽略的还有#与其后的换行符(或 RE 末尾)之间的所有字符。这使得复杂的 RE 可以分段并添加注释。此基本规则有三个例外: + + 空白字符或 # 的前面若有 \,该字符就会被保留。 @@ -3801,13 +3802,16 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; 在多字符符号里面不能出现空白和注释,例如(?: - 在这里,空白字符包括空格、制表符、换行符,以及属于space字符类的任何字符。 + + + 在这里,空白字符包括空格、制表符、换行符,以及属于space字符类的任何字符。 +
- 最后,在 ARE 里,方括号表达式外面,序列(?#ttt)(其中ttt是任意不包含一个))的文本)是一个注释, 它被完全忽略。同样,这样的东西是不允许出现在多字符符号的字符中间的,例如 (?:。这种注释更像是一种历史产物而不是一种有用的设施,并且它们的使用已经被废弃;请使用扩展语法来替代。 + 最后,在 ARE 里,方括号表达式外面,序列(?#ttt)(其中ttt是任意不包含一个)的文本)是一个注释, 它被完全忽略。同样,这样的东西是不允许出现在多字符符号的字符中间的,例如 (?:。这种注释更像是一种历史产物而不是一种有用的设施,并且它们的使用已经被废弃;请使用扩展语法来替代。
- 如果声明了一个初始的***=控制器,那么所有这些元语法扩展都不能使用,因为这样表示把用户输入当作一个文字串而不是 RE 对待。 + 如果指定了开头的***=引导前缀,那么这些元语法扩展都不能使用,因为这表示把用户输入作为按字面解释的字符串,而非 RE 处理。 @@ -3823,7 +3827,7 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; - 大多数原子以及所有约束,都没有贪婪属性(因为它们毕竟无法匹配个数变化的文本)。 + 大多数原子以及所有约束,都没有贪婪属性(因为它们毕竟无法匹配长度不定的文本)。 @@ -3875,7 +3879,7 @@ SELECT SUBSTRING('XY1234Z', 'Y*?([0-9]{1,3})');
- 简而言之,如果一个 RE 同时包含贪婪和非贪婪的子表达式,那么总的匹配长度要么是尽可能长,要么是尽可能短,这取决于给整个 RE 赋予的属性。给子表达式赋予的属性只影响在这个匹配里,各个子表达式之间相互允许吃掉的多少。 + 简而言之,如果一个 RE 同时包含贪婪和非贪婪的子表达式,那么总的匹配长度要么是尽可能长,要么是尽可能短,这取决于给整个 RE 赋予的属性。给子表达式赋予的属性只影响在这个匹配里,各个子表达式相对于其他子表达式能吃掉多少内容。 @@ -3909,19 +3913,19 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 如果声明了大小写无关的匹配,那么效果就好像所有大小写区别在字母表中消失了。如果在多个情况中一个字母以一个普通字符的形式出现在方括号表达式外面,那么它实际上被转换成 一个包含大小写的方括号表达式,也就是说,x 变成 [xX]。 如果它出现在一个方括号表达式里面,那么它的所有大小写的同族都被加入 方括号表达式中,也就是说,x变成[xX]。当它出现在一个方括号表达式内时,它的所有大小写副本都被加入到方括号表达式中,例如, [x]会变成[xX],而[^x]会变成[^xX]。 + 如果指定不区分大小写的匹配,其效果近似于字母表中的所有大小写差别都消失了。当存在大小写形式的字母作为普通字符出现在方括号表达式之外时,实际上会转换为包含其大小写形式的方括号表达式,例如x变成[xX]。当它出现在方括号表达式内部时,其所有大小写形式都会加入该表达式,例如[x]变成[xX][^x]变成[^xX] - 如果指定了换行敏感的匹配,.和使用^的方括号表达式 将永远不会匹配换行字符(这样,匹配就不会跨越行,除非 RE 显式地包含了换行)并且^$除了分别匹配串开头和结尾之外,还将分别匹配换行后面和前面的空串。 + 如果指定了换行敏感的匹配,.和使用^的方括号表达式 将永远不会匹配换行字符(这样,匹配就不会跨越行,除非 RE 显式安排了跨行匹配)并且^$除了分别匹配串开头和结尾之外,还将分别匹配换行后面和前面的空串。 但是 ARE 转义\A\Z仍然匹配串的开头和结尾。 - 如果指定了部分新行敏感的匹配,那么它影响.和方括号表达式, 这个时候和新行敏感的匹配一样,但是不影响^$。 + 如果指定了部分换行敏感的匹配,那么它影响.和方括号表达式, 这个时候和换行敏感的匹配一样,但是不影响^$ - 如果指定了逆新行敏感匹配,那么它影响^$,其作用和在新行敏感的匹配里一样,但是不影响.和方括号表达式。这个并不是很有用,只是为了满足对称性而提供的。 + 如果指定了逆部分换行敏感匹配,那么它影响^$,其作用和在换行敏感的匹配里一样,但是不影响.和方括号表达式。这个并不是很有用,只是为了满足对称性而提供的。 @@ -3933,11 +3937,11 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - ARE 实际上和 POSIX ERE 不兼容的唯一的特性是在方括号表达式里\并不失去它特殊的含义。所有其它 ARE 特性都使用在 POSIX ERE 里面是非法或者是未定义、未声明效果的语法;指示器的***就是在 POSIX 的 BRE 和 ERE 之外的语法。 + ARE 与 POSIX ERE 实际不兼容的唯一特性是:\在方括号表达式中不会失去特殊含义。其他所有 ARE 特性所使用的语法,在 POSIX ERE 中都是非法的,或其效果未定义或未指定;引导前缀的***语法同样不属于 POSIX 的 BRE 或 ERE 语法。 - 许多 ARE 扩展都是从 Perl 那里借来的(但是有些被做了修改来清理它们),以及一些 Perl 里没有出现的扩展。要注意的不兼容性包括\b\B、对结尾的新行缺乏特别的处理、对那些被新行敏感匹配的东西附加的补齐方括号表达式、在 lookahead/lookbehind 约束里对圆括号和反向引用的限制以及最长/最短 匹配(而不是第一匹配)的语义。 + 许多 ARE 扩展借鉴自 Perl,但其中一些经过了整理和修改,也未实现少数 Perl 扩展。需要注意的不兼容之处包括\b\B、不对末尾换行符作特殊处理、取反的方括号表达式也受换行敏感匹配影响、先行和后行约束中对圆括号及反向引用的限制,以及采用最长或最短匹配而非首次匹配的语义。 ARE 与旧版 ERE 语法存在两点重要的不兼容,这里比较的是 7.4 之前的PostgreSQL: @@ -3958,7 +3962,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 基本正则表达式 - BREs 在几个方面和 ERE 不太一样。在 BRE 中,|+?都是普通字符并且没有与它们功能等价的东西。范围的定界符是\{\}, 因为 {}本身是普通字符。嵌套的子表达式的圆括号是\(\),因为()自身是普通字符。除非在 RE 开头或者是圆括号子表达式开头,^都是一个普通字符。 除非在 RE 结尾或者是圆括号子表达式的结尾,$是一个普通字符。如果*出现在 RE 开头或者是圆括号封装的子表达式开头 (前面可能有^),那么它是个普通字符。最后,可以用单数字的反向引用,\<\>分别是[[:<:]][[:>:]]的同义词;在 BRE 中没有其它可用的转义。 + BRE 在几个方面和 ERE 不太一样。在 BRE 中,|+?都是普通字符并且没有与它们功能等价的东西。范围的定界符是\{\},而{}本身是普通字符。嵌套的子表达式的圆括号是\(\),而()自身是普通字符。除非在 RE 开头或者是圆括号子表达式开头,^都是一个普通字符。 除非在 RE 结尾或者是圆括号子表达式的结尾,$是一个普通字符。如果*出现在 RE 开头或者是圆括号封装的子表达式开头 (前面可能有^),那么它是个普通字符。最后,可以用单数字的反向引用,\<\>分别是[[:<:]][[:>:]]的同义词;在 BRE 中没有其它可用的转义。 @@ -3972,11 +3976,11 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 数据类型格式化函数 - formatting + 格式化 - PostgreSQL格式化函数提供一套强大的工具用于把各种数据类型 (日期/时间、整数、浮点、数字) 转换成格式化的字符串以及反过来从格式化的字符串转换成 指定的数据类型。列出了这些函数。这些函数都遵循一个公共的调用规范: 第一个参数是待格式化的值,而第二个是一个定义输出或输入格式的模板。 + PostgreSQL格式化函数提供一套强大的工具用于把各种数据类型 (日期/时间、整数、浮点数、数值) 转换成格式化的字符串以及反过来从格式化的字符串转换成 指定的数据类型。列出了这些函数。这些函数都遵循一个公共的调用规范: 第一个参数是待格式化的值,而第二个是一个定义输出或输入格式的模板。 @@ -4060,7 +4064,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 展示了可以用于格式化日期和时间值的模版。 + 展示了可以用于格式化日期和时间值的模板模式。
@@ -4108,17 +4112,17 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); AM, am, - PM or pm - 正午指示器(不带句号) + PMpm + 上午/下午标记(不带句点) A.M., a.m., - P.M. or p.m. - 正午指示器(带句号) + P.M.p.m. + 上午/下午标记(带句点) Y,YYY - 带逗号的年(4 位或者更多位) with comma + 带逗号的年(4 位或者更多位) YYYY @@ -4164,15 +4168,15 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); MONTH - 全大写形式的月名(空格补齐到 9 字符) + 大写的月份全称(空格补齐到 9 字符) Month - 全首字母大写形式的月名(空格补齐到 9 字符) + 首字母大写的月份全称(空格补齐到 9 字符) month - 全小写形式的月名(空格补齐到 9 字符) + 小写的月份全称(空格补齐到 9 字符) MON @@ -4188,31 +4192,31 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); MM - 月份数(01-12) + 月份编号(01-12) DAY - 全大写形式的日名(空格补齐到 9 字符) + 大写的星期全称(空格补齐到 9 字符) Day - 全首字母大写形式的日名(空格补齐到 9 字符) + 首字母大写的星期全称(空格补齐到 9 字符) day - 全小写形式的日名(空格补齐到 9 字符) + 小写的星期全称(空格补齐到 9 字符) DY - 简写的大写形式的日名(英语 3 字符,本地化长度可变) + 大写的星期简称(英语 3 字符,本地化长度可变) Dy - 简写的首字母大写形式的日名(英语 3 字符,本地化长度可变) + 首字母大写的星期简称(英语 3 字符,本地化长度可变) dy - 简写的小写形式的日名(英语 3 字符,本地化长度可变) + 小写的星期简称(英语 3 字符,本地化长度可变) DDD @@ -4224,19 +4228,19 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); DD - 一月中的第几天(01-31) + 月内日序数(01-31) D - 周中的日,周日 (1) 到周六 (7) + 星期几,周日 (1) 到周六 (7) ID - 周中的 ISO 8601 日,周一 (1) 到周日 (7) + ISO 8601 星期几,周一 (1) 到周日 (7) W - 一月中的第几周(1-5)(第一周从该月第一天开始) + 月内周序数(1-5)(第一周从该月第一天开始) WW @@ -4276,55 +4280,55 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); OF - 从UTC开始的时区偏移(仅在to_char中支持) + 相对于 UTC 的时区偏移(仅在to_char中支持)
- 修饰语可以被应用于模板模式来修改它们的行为。例如,FMMonth就是带着FM修饰语的Month模式。展示了可用于日期/时间格式化的修饰语模式。 + 修饰符可以被应用于模板模式来修改它们的行为。例如,FMMonth就是带着FM修饰符的Month模式。展示了可用于日期/时间格式化的修饰符模式。 - 用于日期/时间格式化的模板模式修饰语 + 用于日期/时间格式化的模板模式修饰符 - 修饰语 + 修饰符 描述 示例 - FM prefix + FM 前缀 填充模式(抑制前导零和填充的空格) FMMonth - TH suffix + TH 后缀 大写形式的序数后缀 - DDTH, e.g., 12TH + DDTH,例如, 12TH - th suffix + th 后缀 小写形式的序数后缀 - DDth, e.g., 12th + DDth,例如, 12th - FX prefix - 固定的格式化全局选项(见使用须知) + FX 前缀 + 固定格式全局选项(见使用须知) FX Month DD Day - TM prefix + TM 前缀 翻译模式(根据 输出本地化的星期名和月份名) TMMonth - SP suffix + SP 后缀 拼写模式(未实现) DDSP @@ -4332,14 +4336,14 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}');
- 日期/时间格式化的使用说明: + 日期/时间格式化的使用注意事项: FM抑制了在模式输出中添加前导零和尾随空格的行为,这些前导零和尾随空格 本来会被添加以使输出成为固定宽度。在PostgreSQL中, - FM仅修改下一个规范,而在Oracle中FM影响所有后续 - 规范,并且重复的FM修饰符切换填充模式的开启和关闭。 + FM仅修改下一个格式说明,而在Oracle中FM影响所有后续 + 格式说明,并且重复的FM修饰符切换填充模式的开启和关闭。 @@ -4417,14 +4421,14 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 年份、周数和星期几:例如to_date('2006-42-4', 'IYYY-IW-ID') + 年份、周编号和星期几:例如to_date('2006-42-4', 'IYYY-IW-ID') 返回日期2006-10-19。 如果省略星期几,则假定为1(星期一)。 - 年份和年内天数:例如to_date('2006-291', 'IYYY-IDDD')也返回2006-10-19。 + 年份和年内日序数:例如to_date('2006-291', 'IYYY-IDDD')也返回2006-10-19 @@ -4432,14 +4436,14 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 尝试使用ISO 8601周编号字段和公历日期字段的混合输入日期是荒谬的,并将导致错误。 - 在ISO 8601周编号年的背景下,月份日期的概念没有意义。 + 在ISO 8601周编号年的背景下,月份月内日序数的概念没有意义。 在公历年的背景下,ISO周没有意义。 - 当to_date拒绝混合使用公历和ISO周编号日期字段时, - to_char不会,因为输出格式规范如YYYY-MM-DD (IYYY-IDDD)可能很有用。 + 虽然to_date会拒绝混合使用公历和ISO周编号日期字段, + 但to_char不会,因为输出格式规范如YYYY-MM-DD (IYYY-IDDD)可能很有用。 但要避免编写类似IYYY-MM-DD的内容;那会在年初附近产生令人惊讶的结果。 (有关更多信息,请参见。) @@ -4458,7 +4462,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 这是一个更复杂的示例: to_timestamp('15:12:02.020.001230', 'HH24:MI:SS.MS.US') - 是15小时,12分钟和2秒 + 20毫秒 + 1230微秒 = 2.021230秒。 + 为15小时12分钟,秒数为2秒 + 20毫秒 + 1230微秒 = 2.021230秒。 @@ -4466,7 +4470,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); to_char(..., 'ID')的星期几编号与extract(isodow from ...)函数匹配, - 但to_char(..., 'D')的不匹配extract(dow from ...)的星期编号。 + 但to_char(..., 'D')的不匹配extract(dow from ...)的星期几编号。 @@ -4483,12 +4487,12 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 展示了可以用于格式化数字值的模版模式。 + 展示了可以用于格式化数值的模板模式。 - 用于数字格式化的模板模式 + 用于数值格式化的模板模式 @@ -4501,21 +4505,21 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 9 - 数位(如果无意义可以被删除) + 数位(非有效位可以被省略) 0 - 数位(即便没有意义也不会被删除) + 数位(即便是非有效位也不会被省略) - . (period) + .(句点) 小数点 - , (comma) + ,(逗号) 分组(千)分隔符 @@ -4526,22 +4530,22 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); S - 带符号的数字(使用区域) + 紧贴数值的正负号(使用区域设置) L - 货币符号(使用区域) + 货币符号(使用区域设置) D - 小数点(使用区域) + 小数点(使用区域设置) G - 分组分隔符(使用区域) + 分组分隔符(使用区域设置) @@ -4565,7 +4569,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - TH or th + THth 序数后缀 @@ -4582,7 +4586,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}');
- 数值格式化的使用说明: + 数值格式化的使用注意事项: @@ -4596,7 +4600,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 模式字符SLDG表示当前区域设置定义的符号、货币符号、小数点和千位分隔符字符 + 模式字符SLDG表示当前区域设置定义的正负号、货币符号、小数点和千位分隔符字符 (参见)。模式字符句点和逗号表示这些确切字符,具有小数点和千位分隔符的含义,不受区域设置影响。 @@ -4605,15 +4609,14 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 如果在to_char()的模式中没有明确指定符号,将为符号保留一列,并将其锚定到(出现在)数字的左侧。 - 如果S出现在一些9的左侧,它也将锚定到数字。 + 如果to_char()的模式中没有明确指定正负号的位置,就会为正负号保留一列,并使其紧贴数值(紧靠数值左侧)。如果S紧邻若干个9的左侧,它同样会紧贴数值。 - 使用SGPLMI格式化的符号不与数字绑定; + 使用SGPLMI格式化的正负号不紧贴数值; 例如,to_char(-12, 'MI9999')会产生'-  12', 但to_char(-12, 'S9999')会产生'  -12'。 (Oracle实现不允许在9之前使用MI,而是要求9MI之前。) @@ -4642,7 +4645,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); Vto_char一起, 将输入值乘以10^n, 其中n是跟在V后面的数字位数。 - Vto_number一起以类似的方式除法。 + Vto_number一起以类似的方式进行除法。 to_charto_number不支持与小数点结合使用的V (例如,不允许使用99.9V99)。 @@ -4658,17 +4661,17 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 某些修饰语可以被应用到任何模板来改变其行为。例如,FM99.99是带有FM修饰语的99.99模式。中展示了用于数字格式化模式修饰语。 + 某些修饰符可以被应用到任何模板来改变其行为。例如,FM99.99是带有FM修饰符的99.99模式。中展示了用于数值格式化的模式修饰符。 - 用于数字格式化的模板模式修饰语 + 用于数值格式化的模板模式修饰符 - 修饰语 + 修饰符 描述 示例 @@ -4676,19 +4679,19 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - FM prefix - 填充模式(抑制拖尾零和填充的空白) + FM 前缀 + 填充模式(抑制尾随零和填充的空白) FM99.99 - TH suffix + TH 后缀 大写序数后缀 999TH - th suffix + th 后缀 小写序数后缀 999th @@ -4872,10 +4875,10 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 时间/日期函数和操作符 + 日期/时间函数和操作符 - 展示了可用于处理日期/时间值的函数,其细节在随后的小节中描述。演示了基本算术操作符 (+*等)的行为。 而与格式化相关的函数,可以参考。你应该很熟悉中的日期/时间数据类型的背景知识。 + 展示了可用于处理日期/时间值的函数,其细节在随后的小节中描述。演示了基本算术操作符 (+*等)的行为。 而与格式化相关的函数,可以参考。你应当熟悉中的日期/时间数据类型的背景知识。 @@ -5039,7 +5042,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); age age(timestamp, timestamp) interval - 减去参数,生成一个使用年和月,而不是只用日的符号化的结果 + 将两个参数相减,生成一个使用年和月,而不是只用日的符号化的结果 age(timestamp '2001-04-10', timestamp '1957-06-13') 43 years 9 mons 27 days @@ -5141,7 +5144,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); isfinite isfinite(date) boolean - 测试有限日期(不是+/-无限) + 测试日期是否有限(不是正负无穷) isfinite(date '2001-02-16') true @@ -5183,7 +5186,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); justify_interval justify_interval(interval) interval - 使用 justify_daysjustify_hours调整时间间隔; 通过额外的符号调整 + 使用 justify_daysjustify_hours调整时间间隔,并额外调整符号 justify_interval(interval '1 mon -1 hour') 29 days 23:00:00 @@ -5263,7 +5266,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); statement_timestamp statement_timestamp() timestamp with time zone - 当前日期和时间(当前语句的开始);参见 + 当前日期和时间(当前语句开始时);参见 @@ -5307,7 +5310,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); (start1, end1) OVERLAPS (start2, end2) (start1, length1) OVERLAPS (start2, length2) - 这个表达式在两个时间域(用它们的端点定义)重叠的时候得到真,当它们不重叠时得到假。端点可以用一对日期、时间或者时间戳来指定;或者是用一个后面跟着一个间隔的日期、时间或时间戳来指定。当一对值被提供时,起点或终点都可以被写在前面,OVERLAPS会自动地把较早的值作为起点。每一个时间段被认为是表示半开的间隔start <= time < end,除非startend相等,这种情况下它表示单个时间实例。例如这表示两个只有一个共同端点的时间段不重叠。 + 这个表达式在两个时间段(用它们的端点定义)重叠的时候得到真,当它们不重叠时得到假。端点可以用一对日期、时间或者时间戳来指定;或者是用一个后面跟着一个间隔的日期、时间或时间戳来指定。当一对值被提供时,起点或终点都可以被写在前面,OVERLAPS会自动地把较早的值作为起点。每一个时间段被认为是表示半开区间start <= time < end,除非startend相等,这种情况下它表示单个时刻。例如这表示两个只有一个共同端点的时间段不重叠。 @@ -5339,15 +5342,9 @@ SELECT timestamp with time zone '2005-04-02 12:00:00-07' + interval '24 hours'; - 日期和时间戳的减法也可能会很复杂。执行减法的一种概念上很简单的方法是,使用 - EXTRACT(EPOCH FROM ...)把每个值都转换成秒数,然后执行减法, - 这样会得到两个值之间的数。这种方法将会适应每个月中天数、 - 时区改变和夏令时调整。使用-操作符的日期或时间 - 戳减法会返回值之间的天数(24小时)以及时/分/秒,也会做同样的调整。 - age函数会返回年、月、日以及时/分/秒,执行按域的减法,然后对 - 负值域进行调整。下面的查询展示了这些方法的不同。示例中的结果由 - timezone = 'US/Eastern'产生,这使得两个使用的日期之间存在着夏令 - 时的变化: + 日期和时间戳的减法也可能很复杂。一种概念上简单的方法是,先用EXTRACT(EPOCH FROM ...)将各值转换为秒数,然后将结果相减;这样得到的是两个值之间的数。这种方法会针对每个月的天数、时区变化和夏令时变化进行调整。 + 用-操作符将日期或时间戳值相减,会返回两个值之间的天数(每一天为 24 小时)和时/分/秒,也会作相同的调整。age函数返回年、月、日和时/分/秒,它会逐字段相减,然后调整负值字段。 + 以下查询显示了这些方法的差异。示例结果在timezone = 'US/Eastern'设置下产生;所用的两个日期之间发生了夏令时切换: @@ -5463,7 +5460,7 @@ SELECT EXTRACT(DOY FROM TIMESTAMP '2001-02-16 20:38:40'); epoch - 对于timestamp with time zone值,自1970-01-01 00:00:00 UTC以来的秒数(负值表示该时间戳之前的时间); + 对于timestamp with time zone值,自1970-01-01 00:00:00 UTC以来的秒数(早于该时刻的时间戳对应负值); 对于datetimestamp值,自1970-01-01 00:00:00以来的名义秒数,不考虑时区或夏令时规则; 对于interval值,间隔中的总秒数 @@ -5486,8 +5483,8 @@ SELECT to_timestamp(982384720.12); - 注意,将to_timestamp应用于从datetimestamp值中提取的时代可能会产生误导性的结果: - 结果将有效地假定原始值是以UTC时间给出的,这可能并非事实。 + 注意,将to_timestamp应用于从datetimestamp值中提取的 epoch 值可能会产生误导性的结果: + 结果实际上会假定原始值是以UTC时间给出的,这可能并非事实。 @@ -5588,7 +5585,7 @@ SELECT EXTRACT(MILLENNIUM FROM TIMESTAMP '2001-02-16 20:38:40'); milliseconds - 第二个字段,包括小数部分,乘以1000。请注意,这包括完整的秒数。 + 秒字段,包括小数部分,乘以1000。请注意,这包括完整的秒数。 @@ -5667,7 +5664,7 @@ SELECT EXTRACT(SECOND FROM TIME '17:12:28.5'); - 时间区偏移的小时组件 + 时区偏移的小时部分 @@ -5677,7 +5674,7 @@ SELECT EXTRACT(SECOND FROM TIME '17:12:28.5'); - 时间区偏移的分钟组件 + 时区偏移的分钟部分 @@ -5687,16 +5684,11 @@ SELECT EXTRACT(SECOND FROM TIME '17:12:28.5'); - 一年中ISO 8601周编号周的数量。根据定义,ISO周从周一开始, - 一年的第一周包含该年的1月4日。换句话说,一年的第一个星期四在该年的第1周。 + 一年中按ISO 8601 周编号体系计算的周序号。根据定义,ISO 周从周一开始,一年的第一周包含该年的 1 月 4 日。换句话说,一年的第一个星期四在该年的第 1 周。 - 在ISO周编号系统中,早年1月的日期可能属于前一年的第52周或第53周,而 - 晚年12月的日期可能属于下一年的第一周。例如,2005-01-01 - 属于2004年的第53周,2006-01-01 属于2005年的第52周, - 而2012-12-31 属于2013年的第一周。建议同时使用 - isoyear 字段和week以获得一致的结果。 + 在 ISO 周编号体系中,1 月初的日期可能属于前一年的第 52 周或第 53 周,而 12 月末的日期可能属于下一年的第一周。例如,2005-01-01属于 2004 年的第 53 周,2006-01-01属于 2005 年的第 52 周,而2012-12-31属于 2013 年的第一周。建议将isoyear字段与week一起使用,以获得一致的结果。 @@ -5711,7 +5703,7 @@ SELECT EXTRACT(WEEK FROM TIMESTAMP '2001-02-16 20:38:40'); - 年份字段。请记住,没有0 AD,所以要小心地从AD年中减去BC年。 + 年份字段。请记住,没有0 AD,所以把BC年份从AD年份中减去时需要小心。 @@ -5727,7 +5719,7 @@ SELECT EXTRACT(YEAR FROM TIMESTAMP '2001-02-16 20:38:40'); - 当输入值为 +/-Infinity 时,extract对于单调增的域(epochjulianyearisoyeardecadecentury以及millennium)返回 +/-Infinity。对于其他域返回 NULL。PostgreSQL 9.6 之前的版本对所有输入无穷的情况都返回零。 + 当输入值为 +/-Infinity 时,extract对于单调递增的字段(epochjulianyearisoyeardecadecentury以及millennium)返回 +/-Infinity。对于其他字段返回 NULL。PostgreSQL 9.6 之前的版本对所有输入无穷的情况都返回零。 @@ -5735,10 +5727,11 @@ SELECT EXTRACT(YEAR FROM TIMESTAMP '2001-02-16 20:38:40'); extract函数主要的用途是做计算性处理。对于用于显示的日期/时间值格式化,参阅。 - date_part函数仿照传统的Ingres实现,后者等价于SQL标准函数extract: + date_part函数仿照传统的Ingres实现,后者对应SQL标准的extract函数: date_part('field', source) -注意,此处的field参数必须是字符串值,而不能是名称。函数date_part的有效字段名与以下函数相同:extract。 + + 注意,此处的field参数必须是字符串值,而不能是名称。date_part的有效字段名与extract相同。 @@ -5765,10 +5758,10 @@ SELECT date_part('hour', INTERVAL '4 hours 3 minutes'); date_trunc('field', source) - sourcetimestampinterval类型的值表达式。(类型为datetime的值会自动转换为timestampinterval,分别对应这两种输入类型。)field选择输入值的截断精度。返回值的类型是timestampinterval,所有小于所选精度的字段都设为零(日期和月份则设为一)。 + sourcetimestampinterval类型的值表达式。(类型为datetime的值会自动转换为timestampinterval,分别对应这两种输入类型。)field选择输入值的截断精度。返回值的类型是timestampinterval,所有小于所选精度的字段都设为零(日和月则设为一)。 - field的有效值是∶ + field的有效值是: microseconds milliseconds @@ -5800,8 +5793,8 @@ SELECT date_trunc('year', TIMESTAMP '2001-02-16 20:38:40'); <literal>AT TIME ZONE</literal> - time zone - conversion + 时区 + 转换 @@ -5861,7 +5854,7 @@ SELECT TIMESTAMP '2001-02-16 20:38:40-05' AT TIME ZONE 'Asia/Tokyo' AT TIME ZONE 第一个示例为不带时区的值添加时区,并使用当前TimeZone设置显示该值。第二个示例将带时区的时间戳值移到指定时区,并返回不带时区的值。这样就可以存储和显示与当前TimeZone设置不同的值。第三个示例将东京时间转换为芝加哥时间。将time值转换到其他时区时,由于没有提供日期,会使用当前生效的时区规则。 - 函数timezone(zone, timestamp)等效于 SQL 兼容的结构timestamp AT TIME ZONE zone。 + 函数timezone(zone, timestamp)等效于符合 SQL 标准的结构timestamp AT TIME ZONE zone @@ -5869,13 +5862,13 @@ SELECT TIMESTAMP '2001-02-16 20:38:40-05' AT TIME ZONE 'Asia/Tokyo' AT TIME ZONE 当前日期/时间 - date - current + 日期 + 当前 - time - current + 时间 + 当前 @@ -5894,11 +5887,11 @@ LOCALTIMESTAMP(precision) - CURRENT_TIMECURRENT_TIMESTAMP传递带有时区的值;LOCALTIMELOCALTIMESTAMP传递的值不带时区。 + CURRENT_TIMECURRENT_TIMESTAMP返回带时区的值;LOCALTIMELOCALTIMESTAMP返回不带时区的值。 - CURRENT_TIMECURRENT_TIMESTAMPLOCALTIMELOCALTIMESTAMP可以有选择地接受一个精度参数,该精度会使结果的秒字段圆整到指定的小数位数。如果没有精度参数,结果将给出可用的全部精度。 + CURRENT_TIMECURRENT_TIMESTAMPLOCALTIMELOCALTIMESTAMP可以有选择地接受一个精度参数,该精度会使结果的秒字段舍入到指定的小数位数。如果没有精度参数,结果将给出可用的全部精度。 下面是一些示例: @@ -5922,7 +5915,7 @@ SELECT LOCALTIMESTAMP; - 许多其它数据库系统可能会更频繁地推进这些值。 + 其他数据库系统可能会更频繁地推进这些值。 @@ -5939,13 +5932,15 @@ now() - transaction_timestamp()等价于CURRENT_TIMESTAMP,但是其命名清楚地反映了它的返回值。statement_timestamp()返回当前语句的开始时刻(更准确的说是收到 客户端最后一条命令的时间)。statement_timestamp()transaction_timestamp()在一个事务的第一条命令期间返回值相同,但是在随后的命令中却不一定相同。 clock_timestamp()返回真正的当前时间,因此它的值甚至在同一条 SQL 命令中都会变化。timeofday()是一个有历史原因的PostgreSQL函数。和clock_timestamp()相似,它也返回真实的当前时间,但是它的结果是一个格式化的text串,而不是timestamp with time zone值。now()PostgreSQL的一个传统,等效于transaction_timestamp()。 + transaction_timestamp()等价于CURRENT_TIMESTAMP,但是其命名清楚地反映了它的返回值。statement_timestamp()返回当前语句的开始时刻(更准确地说,是接收到客户端最近一条命令消息的时间)。statement_timestamp()transaction_timestamp()在一个事务的第一条命令期间返回值相同,但是在随后的命令中却不一定相同。 clock_timestamp()返回真正的当前时间,因此它的值甚至在同一条 SQL 命令中都会变化。timeofday()是一个有历史原因的PostgreSQL函数。和clock_timestamp()相似,它也返回真实的当前时间,但是它的结果是一个格式化的text串,而不是timestamp with time zone值。now()PostgreSQL中与transaction_timestamp()等价的传统函数。 - 所有日期/时间数据类型也都接受特殊字面值now来指定当前日期和时间(同样解释为事务开始时间)。因此,下面三种写法都返回相同的结果: + + 所有日期/时间数据类型也都接受特殊字面值now来指定当前日期和时间(同样解释为事务开始时间)。因此,下面三种写法都返回相同的结果: + SELECT CURRENT_TIMESTAMP; SELECT now(); -SELECT TIMESTAMP 'now'; -- but see tip below +SELECT TIMESTAMP 'now'; -- 但请参阅下面的提示 @@ -5953,7 +5948,7 @@ SELECT TIMESTAMP 'now'; -- but see tip below 当指定以后要计算的值时,不要使用第三种形式,例如在表列的DEFAULT子句中。 - 系统将在分析这个常量的时候把now转换为一个timestamp, 这样需要默认值时就会得到创建表的时间!而前两种形式要到实际使用缺省值的时候才被计算, 因为它们是函数调用。因此它们可以给出每次插入行的时刻。 + 系统将在分析这个常量的时候把now转换为一个timestamp, 这样需要默认值时就会得到创建表的时间!而前两种形式要到实际使用默认值的时候才被计算, 因为它们是函数调用。因此它们可以给出每次插入行的时刻。 (参见 。) @@ -5972,10 +5967,10 @@ SELECT TIMESTAMP 'now'; -- but see tip below pg_sleep_until - sleep + 休眠 - delay + 延迟 以下函数可用于延迟服务器进程的执行: @@ -6018,7 +6013,7 @@ SELECT pg_sleep_until('tomorrow 03:00'); 枚举支持函数 - 对于枚举类型(在中描述), 有一些函数允许更清洁的编码,而不需要为一个枚举类型硬写特定的值。它们被列在中。本例假定一个枚举类型被创建为: + 对于枚举类型(见),有些函数可以避免硬编码枚举类型中的特定值,使程序更简洁。这些函数列在中。以下示例假定枚举类型按如下方式创建: CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple'); @@ -6065,8 +6060,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple enum_range(anyenum, anyenum) - 以一个数组返回在给定两个枚举值之间的范围。值必须来自相同的枚举类型。 - 如果第一个参数为空,其结果将从枚举类型的第一个值开始。如果第二参数为空,其结果将以枚举类型的最后一个值结束。 + 以有序数组返回两个给定枚举值之间的范围。两个值必须来自同一枚举类型。如果第一个参数为 null,结果从该枚举类型的第一个值开始;如果第二个参数为 null,结果以该枚举类型的最后一个值结束。 enum_range('orange'::rainbow, 'green'::rainbow) {orange,yellow,green} @@ -6084,8 +6078,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple
- 请注意,除了双参数形式的enum_range外, 这些函数忽略传递给它们的具体值,它们只关心声明的数据类型。 - 空值或类型的一个特定值可以通过,并得到相同的结果。这些函数更多地被用于一个表列或函数参数,而不是一个硬写的类型名,如示例中所使用。 + 请注意,除了enum_range的双参数形式外,这些函数都忽略传入的具体值,只关心其声明的数据类型。传入 null 或该类型的某个具体值,结果都相同。通常会将这些函数用于表列或函数参数,而不是像示例那样使用硬编码的类型名。 @@ -6095,7 +6088,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple 几何类型pointboxlseglinepath、 - polygoncircle有一大堆本地支持函数和操作符,如中所示。 + polygoncircle有大量内置支持函数和操作符,如中所示。 @@ -6135,7 +6128,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple
# - 相交的点或盒子 + 相交的点或矩形框 box '((1,-1),(-1,1))' # box '((1,1),(-2,-2))' @@ -6245,7 +6238,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple ?-| - 是否垂直? + 是否互相垂直? lseg '((0,0),(0,1))' ?-| lseg '((0,0),(1,0))' @@ -6328,13 +6321,13 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple area(object) double precision - area + 面积 area(box '((0,0),(1,1))') center(object) point - center + 中心 center(box '((0,0),(1,2))') @@ -6346,7 +6339,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple height(box) double precision - 盒子的竖直尺寸 + 矩形框的竖直尺寸 height(box '((0,0),(1,1))') @@ -6364,7 +6357,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple length(object) double precision - length + 长度 length(path '((-1,0),(1,0))') @@ -6409,7 +6402,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple width(box) double precision - 盒子的水平尺寸 + 矩形框的水平尺寸 width(box '((0,0),(1,1))') @@ -6431,37 +6424,37 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple box box(circle) box - 将圆转换为盒子 + 将圆转换为矩形框 box(circle '((0,0),2.0)') box(point) box - 将点转换为空盒子 + 将点转换为空矩形框 box(point '(0,0)') box(point, point) box - 将点转换为盒子 + 将点转换为矩形框 box(point '(0,0)', point '(1,1)') box(polygon) box - 将多边形转换为盒子 + 将多边形转换为矩形框 box(polygon '((0,0),(1,1),(2,0))') bound_box(box, box) box - 将多个盒子转换为包围盒 + 将两个矩形框转换为边界框 bound_box(box '((0,0),(1,1))', box '((3,3),(4,4))') circle circle(box) circle - 将盒子转换为圆 + 将矩形框转换为圆 circle(box '((0,0),(1,1))') @@ -6485,7 +6478,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple lseg lseg(box) lseg - 将盒子的对角线转换为线段 + 将矩形框的对角线转换为线段 lseg(box '((-1,0),(1,0))') @@ -6509,7 +6502,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple point(box) point - 盒子的中心 + 矩形框的中心 point(box '((-1,0),(1,0))') @@ -6533,7 +6526,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple polygon polygon(box) polygon - 将盒子转换为 4 个顶点的多边形 + 将矩形框转换为 4 个顶点的多边形 polygon(box '((0,0),(1,1))') @@ -6559,7 +6552,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple - 我们可以把一个point的两个组成数字当作具有索引 0 和 1 的数组访问。例如,如果t.p是一个point列,那么SELECT p[0] FROM t检索 X 坐标而 UPDATE t SET p[1] = ...改变 Y 坐标。同样,box或者lseg类型的值可以当作两个point值的数组值看待。 + 可以把一个point当作下标为 0 和 1 的数组,访问它的两个数值分量。例如,如果t.p是一个point列,那么SELECT p[0] FROM t检索 X 坐标而 UPDATE t SET p[1] = ...改变 Y 坐标。同样,box或者lseg类型的值可以当作两个point值组成的数组看待。 area 函数适用于 boxcirclepath 类型。对于 path 数据类型,只有当 path 中的点构成的路径不自相交时,area 函数才能工作。例如,path '((0,0),(0,1),(2,1),(2,2),(1,2),(1,0),(0,0))'::PATH 无法使用;但下面这个视觉上相同的 path '((0,0),(0,1),(1,1),(1,2),(2,2),(2,1),(1,1),(1,0),(0,0))'::PATH 可以使用。如果难以理解自相交与非自相交 path 的区别,可以把上述两条 path 并排画在方格纸上。 @@ -6861,7 +6854,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple 文本搜索函数和操作符 - 全文搜索 + 全文检索 函数和操作符 @@ -6874,7 +6867,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple 以及 - 总结了为全文搜索提供的函数和操作符。PostgreSQL的文本搜索功能的详细解释可参考。 + 总结了为全文检索提供的函数和操作符。PostgreSQL的文本搜索功能的详细解释可参考。 @@ -6958,10 +6951,10 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple
- tsquery 包含操作符只考虑两个查询中列出的词元,忽略组合操作符。 + tsquery 包含操作符只考虑两个查询中列出的词位,忽略组合操作符。 - 除了表中列出的操作符,tsvectortsquery 类型还定义了普通的 B-tree 比较操作符(=< 等)。这些操作符对文本搜索用处不大,但可以用于其他用途,例如在这些类型的列上建立唯一索引。 + 除了表中列出的操作符,tsvectortsquery 类型还定义了普通的 B-树比较操作符(=< 等)。这些操作符对文本搜索用处不大,但可以用于其他用途,例如在这些类型的列上建立唯一索引。 文本搜索函数 @@ -6979,28 +6972,28 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple array_to_tsvector array_to_tsvector(text[]) tsvector - 将词元数组转换为 tsvector + 将词位数组转换为 tsvector array_to_tsvector('{fat,cat,rat}'::text[]) 'cat' 'fat' 'rat' get_current_ts_config get_current_ts_config() regconfig - 获取默认的全文搜索配置 + 获取默认的文本搜索配置 get_current_ts_config() english length length(tsvector) integer - tsvector 中的词元数 + tsvector 中的词位数 length('fat:2,4 cat:3 rat:5A'::tsvector) 3 numnode numnode(tsquery) integer - tsquery 中的词元数与操作符数之和 + tsquery 中的词位数与操作符数之和 numnode('(fat & rat) | cat'::tsquery) 5 @@ -7033,7 +7026,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple 'cat':3A 'fat':2A,4A 'rat':5A - setweight 为指定词元设置权重 setweight(vector tsvector, weight "char", lexemes text[]) + setweight 为指定词位设置权重 setweight(vector tsvector, weight "char", lexemes text[]) tsvector vector 中列在 lexemes 内的元素赋予 weight setweight('fat:2,4 cat:3 rat:5B'::tsvector, 'A', '{cat,rat}') @@ -7049,7 +7042,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple to_tsquery to_tsquery( config regconfig , query text) tsquery - 规范化单词并转换为 tsquery + 正规化单词并转换为 tsquery to_tsquery('english', 'The & Fat & Rats') 'fat' & 'rat' @@ -7077,7 +7070,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple ts_delete(vector tsvector, lexemes text[]) tsvector - vector 中移除 lexemes 所列词元的所有出现 + vector 中移除 lexemes 所列词位的所有出现 ts_delete('fat:2,4 cat:3 rat:5A'::tsvector, ARRAY['fat','rat']) 'cat':3 @@ -7147,7 +7140,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsvector_to_array tsvector_to_array(tsvector) text[] - tsvector 转换为词元数组 + tsvector 转换为词位数组 tsvector_to_array('fat:2,4 cat:3 rat:5A'::tsvector) {cat,fat,rat} @@ -7181,13 +7174,13 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple - 所有接受一个可选的regconfig参数的文本搜索函数在该参数被忽略时,使用由指定的配置。 + 所有接受一个可选的regconfig参数的文本搜索函数在省略该参数时,会使用由指定的配置。 中的函数被单独列出,因为它们通常不被用于日常的文本搜索操作。 - 它们主要有助于开发和调试新的文本搜索配置。 + 它们有助于开发和调试新的文本搜索配置。
@@ -7234,14 +7227,14 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple ts_token_type ts_token_type(parser_name text, OUT tokid integer, OUT alias text, OUT description text) setof record - 获取解析器定义的记号类型 + 获取解析器定义的词元类型 ts_token_type('default') (1,asciiword,"Word, all ASCII") ... ts_token_type(parser_oid oid, OUT tokid integer, OUT alias text, OUT description text) setof record - 获取解析器定义的记号类型 + 获取解析器定义的词元类型 ts_token_type(3722) (1,asciiword,"Word, all ASCII") ... @@ -7663,7 +7656,7 @@ SELECT xmlexists('//town[text() = ''Toronto'']' PASSING BY REF 'Tor - 示例: + 示例: - 示例: + 示例: test', ARRAY[ARRAY['my', 'http://example.com']]); @@ -7775,7 +7768,7 @@ SELECT xpath('//mydefns:b/text()', 'test - 示例: + 示例: test', ARRAY[ARRAY['my', 'http://example.com']]); @@ -8772,17 +8765,17 @@ table2-mapping - 如果输出列的类型是jsonjsonb,则会精确地重制JSON值。 - + 如果输出列的类型是jsonjsonb,则 JSON 值会被原样保留。 + - 如果输出列是复合(行)类型,且JSON值是JSON对象,则该对象的字段将转换为输出行类型的列,通过这些规则的递归应用程序。 + 如果输出列是复合(行)类型,且JSON值是JSON对象,则该对象的字段会通过递归应用这些规则,被转换为输出行类型的各列。 - 同样,如果输出列是数组类型,而JSON值是JSON数组,则通过这些规则的递归应用程序将JSON数组的元素转换为输出数组的元素。 + 同样,如果输出列是数组类型,而JSON值是JSON数组,则会通过递归应用这些规则,把JSON数组的元素转换为输出数组的元素。 @@ -8790,8 +8783,8 @@ table2-mapping - 否则,JSON值的普通文本表示将被提供给输入转换函数,以确定列的数据类型。 - + 否则,JSON 值的普通文本表示会被送入该列数据类型的输入转换函数。 + @@ -8818,7 +8811,7 @@ table2-mapping 序列操作函数 - sequence + 序列 nextval @@ -8834,7 +8827,7 @@ table2-mapping - 本节描述对序列对象进行操作的函数,也称为序列生成器或简称序列。 + 本节描述用于操作序列对象(也称为序列生成器,或简称序列)的函数。 序列对象是使用创建的特殊单行表。 序列对象通常用于为表中的行生成惟一标识符。在中列出的序列函数,提供了简单的、多用户安全方法,用于从序列对象中获取连续的序列值。 @@ -8890,10 +8883,10 @@ nextval('foo') 在搜索路径中查找 fo PostgreSQL 8.1 之前,序列函数的参数类型是 text,而不是 regclass;上述从文本字符串到 OID 值的转换会在每次调用时于运行期间执行。为保持向后兼容,这种能力仍然存在,但内部现在会在调用函数前,通过从 textregclass 的隐式强制转换来处理。 - 将序列函数的参数写成不加修饰的字符串字面量时,它会成为以下类型的常量:regclass。由于它实际上只是一个 OID,即使后来发生重命名、模式变更等情况,它仍会指向最初标识的序列。这种早绑定行为通常适用于列默认值和视图中的序列引用。但有时你可能希望采用后绑定,在运行时解析序列引用。要获得后期绑定行为,应强制将常量存储为text常量,而不是regclass: + 将序列函数的参数写成不加修饰的字符串字面量时,它会成为以下类型的常量:regclass。由于它实际上只是一个 OID,即使后来发生重命名、模式变更等情况,它仍会指向最初标识的序列。这种早绑定行为通常适用于列默认值和视图中的序列引用。但有时你可能希望采用后绑定,在运行时解析序列引用。要获得后绑定行为,应强制将常量存储为text常量,而不是regclass nextval('foo'::text) foo运行时被查找 -请注意,后期绑定是下列旧版本唯一支持的行为:PostgreSQL8.1 之前的版本,因此可能需要这样做来保留旧应用的语义。 +请注意,后绑定是下列旧版本唯一支持的行为:PostgreSQL8.1 之前的版本,因此可能需要这样做来保留旧应用的语义。 当然,序列函数的参数既可以是常量,也可以是表达式。如果它是文本表达式,隐式强制转换就会导致运行时查找。 @@ -8907,7 +8900,7 @@ nextval('foo'::text) foo运行时被查 如果使用默认参数创建序列对象,连续调用 nextval 会返回从 1 开始的连续值。可以在 命令中使用特殊参数获得其他行为;更多信息请参见该命令的参考页。 - 这个函数需要USAGEUPDATE权限在序列上。 + 这个函数需要序列上的USAGEUPDATE权限。 @@ -8994,7 +8987,7 @@ SELECT setval('foo', 42, false); 下一次 nextval< - 如果你的需求超过这些条件表达式的能力,你可能会希望用一种更富表现力的编程语言写一个服务器端函数。 + 如果你的需求超过这些条件表达式的能力,你可能会希望用一种更富表现力的编程语言写一个存储过程。 @@ -9011,7 +9004,7 @@ CASE WHEN condition THEN result - CASE子句可以用于任何表达式可以出现的地方。每一个condition是一个返回boolean结果的表达式。如果结果为真,那么CASE表达式的结果就是符合条件的result,并且剩下的CASE表达式不会被处理。如果条件的结果不为真,那么以相同方式搜寻任何随后的WHEN子句。如果没有WHEN condition为真,那么CASE表达式的值就是在ELSE子句里的result。如果省略了ELSE子句而且没有条件为真,结果为空。 + CASE子句可以用于任何表达式可以出现的地方。每一个condition是一个返回boolean结果的表达式。如果结果为真,那么CASE表达式的结果就是紧随该条件后的result,并且剩下的CASE表达式不会被处理。如果条件的结果不为真,那么以相同方式搜寻任何随后的WHEN子句。如果没有WHEN condition为真,那么CASE表达式的值就是在ELSE子句里的result。如果省略了ELSE子句而且没有条件为真,结果为 null。 @@ -9055,7 +9048,7 @@ CASE expression END - 第一个expression会被计算,然后与所有在WHEN子句中的每一个value对比,直到找到一个相等的。如果没有找到匹配的,则返回在ELSE子句中的result(或者控制)。 这类似于 C 里的switch语句。 + 第一个expression会被计算,然后与所有在WHEN子句中的每一个value对比,直到找到一个相等的。如果没有找到匹配的,则返回在ELSE子句中的result(或者 null 值)。 这类似于 C 里的switch语句。 @@ -9086,11 +9079,7 @@ SELECT ... WHERE CASE WHEN x <> 0 THEN y/x > 1.5 ELSE false END; - 如中所述,在有几种情况中一个表达式的子表达式 - 会被计算多次,因此CASE只计算必要的表达式这 - 一原则并非不可打破。例如一个常量子表达式1/0通常将会在规划时导致一次 - 除零错误,即便它位于一个执行时永远也不会进入的CASE分支时也是 - 如此。 + 如所述,在多种情况下,表达式中的子表达式会在不同阶段求值,因此CASE只计算必要的子表达式这一原则并非绝对成立。例如,常量子表达式1/0通常会在规划时导致除零错误,即便它位于一个运行时永远不会进入的CASE分支中也是如此。 @@ -9114,17 +9103,19 @@ SELECT ... WHERE CASE WHEN x <> 0 THEN y/x > 1.5 ELSE false END; COALESCE(value , ...) - COALESCE函数返回参数中第一个不为 null 的值。只有所有参数都为 null 时,才返回 null。它常用于在检索数据以供显示时,用默认值替换 null 值。例如: + COALESCE函数返回参数中第一个不为 null 的值。只有所有参数都为 null 时,才返回 null。它常用于在检索数据以供显示时,用默认值替换 null 值。例如: + SELECT COALESCE(description, short_description, '(none)') ... -此表达式返回description,前提是它不为 null,否则返回short_description,前提是它不为 null,否则返回(none)。 + + 此表达式返回description,前提是它不为 null,否则返回short_description,前提是它不为 null,否则返回(none) - 所有参数都必须转换为一个公共数据类型,它将是结果的类型 (详情参见 )。 + 所有参数都必须能转换为同一个数据类型,它将是结果的类型(详情参见)。 - 和CASE表达式一样,COALESCE将不会 计算无助于判断结果的参数;也就是说,在第一个非空参数右边的参数不会被计算。这个 SQL 标准函数提供了类似于NVLIFNULL的能力,它们被用在某些其他数据库系统中。 + 和CASE表达式一样,COALESCE只计算确定结果所需的参数;也就是说,在第一个不为 null 的参数右边的参数不会被计算。这个 SQL 标准函数提供了类似于NVLIFNULL的能力,它们被用在某些其他数据库系统中。 @@ -9140,12 +9131,12 @@ SELECT COALESCE(description, short_description, '(none)') ... - 当value1value2相等时,NULLIF返回一个空值。 + 当value1value2相等时,NULLIF返回 null。 否则它返回value1。 这些可以用于执行前文给出的COALESCE示例的逆操作: SELECT NULLIF(value, '(none)') ... - 在这个示例中,如果value(none),将返回空值,否则返回value的值。 + 在这个示例中,如果value(none),将返回 null,否则返回value的值。 @@ -9180,11 +9171,11 @@ SELECT NULLIF(value, '(none)') ... - GREATESTLEAST函数从一个任意的数字表达式列表里选取最大或者最小的数值。 这些表达式必须都可以转换成一个普通的数据类型,它将会是结果类型 (参阅获取细节)。列表中的 NULL 数值将被忽略。只有所有表达式的结果都是 NULL 的时候,结果才会是 NULL。 + GREATESTLEAST函数从由任意数量的表达式组成的列表中选取最大值或最小值。这些表达式都必须能转换为同一个数据类型,该类型将作为结果类型(详情参见)。列表中的 NULL 值会被忽略。只有所有表达式的求值结果都为 NULL 时,结果才为 NULL。 - 请注意GREATESTLEAST都不是 SQL 标准,但却是很常见的扩展。某些其他数据库让它们在任何参数为 NULL 时返回 NULL,而不是在所有参数都为 NULL 时才返回 NULL。 + 请注意GREATESTLEAST都未包含在 SQL 标准中,但却是很常见的扩展。某些其他数据库让它们在任何参数为 NULL 时返回 NULL,而不是在所有参数都为 NULL 时才返回 NULL。 @@ -9300,12 +9291,12 @@ SELECT NULLIF(value, '(none)') ...
- 数组排序操作符(<>= 等)使用元素数据类型的默认 B-tree 比较函数,逐个元素比较数组内容,并根据第一个差异决定排序顺序。多维数组的元素按行优先顺序访问(最后一个下标变化最快)。如果两个数组的内容相同,但维度不同,则由维度信息中的第一个差异决定排序顺序。(这与 PostgreSQL 8.2 之前的版本不同:旧版本会将内容相同的两个数组视为相等,即使它们的维数或下标范围不同。) + 数组排序操作符(<>= 等)使用元素数据类型的默认 B-树比较函数,逐个元素比较数组内容,并根据第一个差异决定排序顺序。多维数组的元素按行优先顺序访问(最后一个下标变化最快)。如果两个数组的内容相同,但维度信息不同,则由维度信息中的第一个差异决定排序顺序。(这与 PostgreSQL 8.2 之前的版本不同:旧版本会将内容相同的两个数组视为相等,即使它们的维数或下标范围不同。) 数组包含操作符(<@@>)在一个数组的每个元素都出现在另一个数组中时,认为前者包含在后者中。重复元素不会被特殊处理,因此 ARRAY[1]ARRAY[1,1] 被认为彼此包含。 - 参阅获取有关数组操作符行为的更多细节。有关哪些操作符支持被索引的操作,请参阅。 + 参阅获取有关数组操作符行为的更多细节。有关哪些操作符支持索引操作,请参阅 @@ -9591,7 +9582,7 @@ NULL baz(3 rows)
string_to_array 中,如果分隔符参数为 NULL,输入字符串中的每个字符都会成为结果数组中的独立元素。如果分隔符为空字符串,则将整个输入字符串作为单元素数组返回。否则,在分隔符字符串的每次出现处拆分输入字符串。 - string_to_array 中,如果省略空值字符串参数,或该参数为 NULL,则不会将任何输入子串替换为 NULL。在 array_to_string 中,如果省略空值字符串参数,或该参数为 NULL,则直接跳过数组中的所有空元素,不在输出字符串中表示它们。 + string_to_array 中,如果省略 null 替代字符串参数,或该参数为 NULL,则不会将任何输入子串替换为 NULL。在 array_to_string 中,如果省略 null 替代字符串参数,或该参数为 NULL,则直接跳过数组中的所有 null 元素,不在输出字符串中表示它们。 string_to_array 的行为与 PostgreSQL 9.1 之前的版本有两点不同。首先,当输入字符串长度为零时,它返回空数组(零元素),而不是 NULL。其次,如果分隔符字符串为 NULL,该函数会将输入拆分为单独的字符,而不是像以前那样返回 NULL。 @@ -9751,7 +9742,7 @@ NULL baz(3 rows)
- - difference + 差集 int8range(5,15) - int8range(10,20) [5,10) @@ -9760,7 +9751,7 @@ NULL baz(3 rows)
- 简单比较操作符 <><=>= 首先比较下界,只有下界相等时才比较上界。这些比较对范围通常用处不大,但提供这些操作符可以在范围上建立 B-tree 索引。 + 简单比较操作符 <><=>= 首先比较下界,只有下界相等时才比较上界。这些比较对范围通常用处不大,但提供这些操作符可以在范围上建立 B-树索引。 涉及空范围时,左侧、右侧和相邻操作符总是返回假;也就是说,空范围不被视为位于任何其他范围之前或之后。 @@ -9895,7 +9886,7 @@ NULL baz(3 rows)
- 如果范围为空,或请求的边界是无限的,lowerupper 函数返回空值。对于空范围,lower_incupper_inclower_infupper_inf 函数都返回假。 + 如果范围为空,或请求的边界是无限的,lowerupper 函数返回 null。对于空范围,lower_incupper_inclower_infupper_inf 函数都返回假。 @@ -9927,7 +9918,7 @@ NULL baz(3 rows)
array_agg array_agg(expression) 任意非数组类型 参数类型的数组 - No + 将输入值(包括 null)串接为数组
@@ -9935,7 +9926,7 @@ NULL baz(3 rows)
array_agg(expression) 任意数组类型 与参数数据类型相同 - No + 将输入数组串接为维数多一维的数组(所有输入的维数必须相同,且不能是空数组或 null)
@@ -10007,7 +9998,7 @@ NULL baz(3 rows)
json_agg json_agg(expression) any json - No + 将值(包括 null)聚合为 JSON 数组
@@ -10015,7 +10006,7 @@ NULL baz(3 rows)
jsonb_agg jsonb_agg(expression) any jsonb - No + 将值(包括 null)聚合为 JSON 数组
@@ -10025,7 +10016,7 @@ NULL baz(3 rows)
(any, any)
json - No + 将名称/值对聚合为 JSON 对象;值可以为 null,名称不能为 null
@@ -10035,7 +10026,7 @@ NULL baz(3 rows)
(any, any)
jsonb - No + 将名称/值对聚合为 JSON 对象;值可以为 null,名称不能为 null
@@ -10059,7 +10050,7 @@ NULL baz(3 rows)
string_agg string_agg(expression, delimiter) texttext)或(byteabytea 与参数类型相同 - No + 将非空输入值串接为字符串,以分隔符分隔
@@ -10075,7 +10066,7 @@ NULL baz(3 rows)
xmlagg xmlagg(expression) xml xml - No + 串接非空 XML 值(另见
@@ -10083,9 +10074,7 @@ NULL baz(3 rows)
- 应该注意的是,除了count之外,这些函数在没有选择行时返回空值。 - 特别地,行数的sum返回空(null),而不是预期的零,array_agg在没有输入行时返回空(null)而不是空数组。 - coalesce函数可以在必要时用零或空数组代替空(null)。 + 需要注意,除了count之外,这些函数在没有选中任何行时都会返回空值。特别地,sum在没有输入行时返回空值,而不是预期中的零;array_agg在没有输入行时返回空值,而不是空数组。必要时,可以用coalesce函数把空值替换成零或空数组。 支持部分模式的聚合函数可以参与并行聚合等多种优化。 @@ -10109,16 +10098,11 @@ SELECT count(*) FROM sometable; - 聚合函数 array_agg,json_agg, jsonb_agg,json_object_agg, jsonb_object_agg, - string_agg,和 xmlagg,以及类似的用户定义的聚合函数,根据输入值的顺序产生富有意义的不同的结果值。 - 默认情况下,这种排序是不指定的,但可以通过在聚合调用中写入ORDER BY子句来控制,如所示。 - 或者,从排序的子查询提供输入值通常也可以。例如: - + 聚合函数array_aggjson_aggjsonb_aggjson_object_aggjsonb_object_aggstring_aggxmlagg,以及类似的用户定义聚合函数,其结果值会随输入值的顺序发生实质性变化。默认情况下,输入顺序未指定,但可以在聚合调用中写入ORDER BY子句来控制,如所示。也可以用已排序的子查询提供输入值,这通常也能奏效。例如: - - 注意,如果外部查询级别包含其他处理,例如关联,则此方法可能会失败,因为这可能导致子查询的输出在计算聚合之前重新排序。 + 需要注意,如果外层查询包含连接等额外处理,这种方法可能失效,因为子查询的输出可能在计算聚合之前被重新排序。 列出了统计分析常用的聚合函数。(将它们单独列出只是为了避免让更常用的聚合函数列表过于拥挤。)说明中提到的 N 表示所有输入表达式均非空的输入行数。在所有情况下,如果计算没有意义,例如 N 为零,都会返回空值。 @@ -10150,7 +10134,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; 相关性 corr corr(Y, X) double precision double precision - Yes + 相关系数
@@ -10158,7 +10142,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; 协方差 总体 covar_pop covar_pop(Y, X) double precision double precision - Yes + 总体协方差
@@ -10166,7 +10150,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; 协方差 样本 covar_samp covar_samp(Y, X) double precision double precision - Yes + 样本协方差 @@ -10174,7 +10158,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; regr_avgx regr_avgx(Y, X) double precision double precision - Yes + 自变量的平均值(sum(X)/N @@ -10182,7 +10166,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; regr_avgy regr_avgy(Y, X) double precision double precision - Yes + 因变量的平均值(sum(Y)/N @@ -10190,7 +10174,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; regr_count regr_count(Y, X) double precision bigint - Yes + 两个表达式都非空的输入行数 @@ -10198,7 +10182,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; 回归截距 regr_intercept regr_intercept(Y, X) double precision double precision - Yes + 由(XY)数值对确定的最小二乘拟合线性方程的 y 轴截距 @@ -10206,7 +10190,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; regr_r2 regr_r2(Y, X) double precision double precision - Yes + 相关系数的平方 @@ -10214,7 +10198,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; 回归斜率 regr_slope regr_slope(Y, X) double precision double precision - Yes + 由(XY)数值对确定的最小二乘拟合线性方程的斜率 @@ -10222,7 +10206,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; regr_sxx regr_sxx(Y, X) double precision double precision - Yes + sum(X^2) - sum(X)^2/N(自变量的平方和 @@ -10230,7 +10214,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; regr_sxy regr_sxy(Y, X) double precision double precision - Yes + sum(X*Y) - sum(X) * sum(Y)/N(自变量与因变量的乘积和 @@ -10238,7 +10222,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; regr_syy regr_syy(Y, X) double precision double precision - Yes + sum(Y^2) - sum(Y)^2/N(因变量的平方和 @@ -10246,7 +10230,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; 标准差 stddev stddev(expression) smallintintbigintrealdouble precisionnumeric 浮点参数返回 double precision,其他情况返回 numeric - Yes + stddev_samp 的历史别名 @@ -10254,7 +10238,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; 标准差 总体 stddev_pop stddev_pop(expression) smallintintbigintrealdouble precisionnumeric 浮点参数返回 double precision,其他情况返回 numeric - Yes + 输入值的总体标准差 @@ -10262,7 +10246,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; 标准差 样本 stddev_samp stddev_samp(expression) smallintintbigintrealdouble precisionnumeric 浮点参数返回 double precision,其他情况返回 numeric - Yes + 输入值的样本标准差 @@ -10270,7 +10254,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; variance variance(expression) smallintintbigintrealdouble precisionnumeric 浮点参数返回 double precision,其他情况返回 numeric - Yes + var_samp 的历史别名 @@ -10278,7 +10262,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; 方差 总体 var_pop var_pop(expression) smallintintbigintrealdouble precisionnumeric 浮点参数返回 double precision,其他情况返回 numeric - Yes + 输入值的总体方差(总体标准差的平方) @@ -10286,7 +10270,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; 方差 样本 var_samp var_samp(expression) smallintintbigintrealdouble precisionnumeric 浮点参数返回 double precision,其他情况返回 numeric - Yes + 输入值的样本方差(样本标准差的平方) @@ -10296,7 +10280,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; 列出了一些使用有序集聚合语法的聚合函数。这些函数有时被称为逆分布函数。 - ordered-set aggregate + 有序集聚合 内置 @@ -10321,22 +10305,22 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; - mode 统计 mode() WITHIN GROUP (ORDER BY sort_expression) + 众数 统计 mode() WITHIN GROUP (ORDER BY sort_expression) 任意可排序类型 与排序表达式相同 - No + 返回出现次数最多的输入值(若有多个结果同样频繁,则任意选择第一个) - 百分位数 连续 percentile_cont(fraction) WITHIN GROUP (ORDER BY sort_expression) + 百分位点 连续 percentile_cont(fraction) WITHIN GROUP (ORDER BY sort_expression) double precision double precisioninterval 与排序表达式相同 - No - 连续百分位数:返回排序中与指定比例对应的值,必要时在相邻输入项之间插值 + + 连续百分位点:返回排序中与指定比例对应的值,必要时在相邻输入项之间插值 @@ -10346,8 +10330,8 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; double precisioninterval 排序表达式类型的数组 - No - 多个连续百分位数:返回形状与 fractions 参数一致的结果数组,将每个非空元素替换为与该百分位数对应的值 + + 多个连续百分位点:返回形状与 fractions 参数一致的结果数组,将每个非空元素替换为与该百分位点对应的值 @@ -10355,7 +10339,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; double precision 任意可排序类型 与排序表达式相同 - No + 离散百分位数:返回排序位置等于或超过指定比例的第一个输入值 @@ -10366,7 +10350,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; 任意可排序类型 排序表达式类型的数组 - No + 多个离散百分位数:返回形状与 fractions 参数一致的结果数组,将每个非空元素替换为与该百分位数对应的输入值 @@ -10374,10 +10358,10 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab;
- 中列出的所有聚合函数都忽略其排序输入中的空值。对于接受 fraction 参数的函数,该比例值必须在 0 和 1 之间,否则会报错。但空的比例值只会产生空结果。 + 中列出的所有聚合函数都忽略其排序输入中的空值。对于接受 fraction 参数的函数,该比例值必须在 0 和 1 之间,否则会报错。但 null 比例值只会产生 null 结果。 - hypothetical-set aggregate + 假想集聚合 内置 @@ -10405,7 +10389,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; VARIADIC "any" VARIADIC "any" bigint - No + 假设行的排名,重复行会造成排名空缺 @@ -10414,7 +10398,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; VARIADIC "any" VARIADIC "any" bigint - No + 假设行的排名,没有空缺 @@ -10423,7 +10407,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; VARIADIC "any" VARIADIC "any" double precision - No + 假设行的相对排名,范围为 0 到 1 @@ -10432,7 +10416,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; VARIADIC "any" VARIADIC "any" double precision - No + 假设行的相对排名,范围为 1/N 到 1 @@ -10561,31 +10545,31 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; lag lag(value anyelement [, offset integer [, default anyelement ]]) - same type as value + value 相同的类型 返回在分区内当前行之前 offset 行处计算的 value;如果没有这样的行,则返回 default(其类型必须与 value 相同)。offsetdefault 都针对当前行求值。如果省略,offset 默认为 1,default 默认为 null lead lead(value anyelement [, offset integer [, default anyelement ]]) - same type as value + value 相同的类型 返回在分区内当前行之后 offset 行处计算的 value;如果没有这样的行,则返回 default(其类型必须与 value 相同)。offsetdefault 都针对当前行求值。如果省略,offset 默认为 1,default 默认为 null first_value first_value(value any) - same type as value + value 相同的类型 返回在窗口帧第一行处计算的 value last_value last_value(value any) - same type as value + value 相同的类型 返回在窗口帧最后一行处计算的 value nth_value nth_value(value any, nth integer) - same type as value + value 相同的类型 返回在窗口帧第 nth 行处计算的 value(从 1 开始计数);没有这样的行时返回 null @@ -10607,8 +10591,8 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; 当一个聚合函数被用作窗口函数时,它将在当前行的窗口帧内的行上聚合。 - 一个使用ORDER BY和默认窗口帧定义的聚合产生一种运行时求和类型的行为,这可能是或者不是想要的结果。 - 为了获取在整个分区上的聚合,忽略ORDER BY或者使用ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING。 + 一个使用ORDER BY和默认窗口帧定义的聚合产生一种累计求和类型的行为,这可能是或者不是想要的结果。 + 为了获取在整个分区上的聚合,省略ORDER BY或者使用ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING。 其它窗口帧声明可以用来获得其它的效果。 @@ -10617,7 +10601,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; SQL 标准为leadlagfirst_valuelast_valuenth_value定义了一个RESPECT NULLSIGNORE NULLS选项。 这在PostgreSQL中没有实现:行为总是与标准的默认相同,即RESPECT NULLS。 - 同样,标准中用于nth_valueFROM FIRSTFROM LAST选项没有实现: 只有支持默认的FROM FIRST行为(你可以通过反转ORDER BY的排序达到FROM LAST的结果)。 + 同样,标准中用于nth_valueFROM FIRSTFROM LAST选项没有实现: 只支持默认的FROM FIRST行为(你可以通过反转ORDER BY的排序达到FROM LAST的结果)。 @@ -10653,11 +10637,11 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; - subquery + 子查询 - 本节描述PostgreSQL中可用的SQL兼容的子查询表达式。所有本节中成文的表达式都返回布尔值(真/假)结果。 + 本节描述PostgreSQL中可用的SQL兼容的子查询表达式。本节介绍的所有表达式形式都返回布尔值(真/假)结果。 @@ -10672,7 +10656,7 @@ EXISTS (subquery) - 子查询可以引用来自周围的查询的变量,这些变量在该子查询的任何一次计算中都起常量的作用。 + 子查询可以引用外层查询的变量,这些变量在该子查询的任何一次计算中都起常量的作用。 @@ -10684,7 +10668,7 @@ EXISTS (subquery) - 下面这个简单的示例类似在col2上的一次内联接,但是它为每个 tab1的行生成最多一个输出,即使存在多个匹配tab2的行也如此∶ + 下面这个简单的示例类似在col2上的一次内连接,但是它为每个 tab1的行最多生成一行输出,即使存在多个匹配tab2的行也如此: SELECT col1 FROM tab1 @@ -10701,15 +10685,15 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 右手边是一个圆括弧括起来的子查询, 它必须正好只返回一个列。左手边表达式将被计算并与子查询结果逐行进行比较。 如果找到任何等于子查询行的情况,那么IN的结果就是。 如果没有找到相等行,那么结果是(包括子查询没有返回任何行的情况)。 + 右手边是一个圆括号括起来的子查询,它必须恰好返回一列。左手边表达式会被求值,并与子查询结果逐行比较。如果找到任意相等的子查询行,那么IN的结果就是。如果没有找到相等行,那么结果就是(包括子查询不返回任何行的情况)。 - 请注意如果左手边表达式得到空值,或者没有相等的右手边值, 并且至少有一个右手边行得到空值,那么IN结构的结果将是空值,而不是假。这个行为是遵照 SQL 处理空值的一般规则的。 + 请注意,如果左侧表达式得到空值,或者右侧没有相等的值且至少有一行得到空值,则IN结构的结果将是空值,而不是假。这符合 SQL 对空值布尔组合的一般规则。 - 和EXISTS一样,假设子查询将被完成运行完全是不明智的。 + 和EXISTS一样,假定子查询一定会完整运行并不明智。 @@ -10717,7 +10701,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 这种形式的IN的左手边是一个行构造器, 如中所述。 右手边是一个圆括弧子查询,它必须返回和左手边返回的行中表达式所构成的完全一样多的列。 左手边表达式将被计算并与子查询结果逐行进行比较。如果找到任意相等的子查询行,则IN的结果为。如果没有找到相等行, 那么结果为(包括子查询不返回行的情况)。 + 这种形式的IN左手边是一个行构造器,如中所述。右手边是一个圆括号括起来的子查询,它必须返回与左手边行中表达式数量完全相同的列数。左手边表达式会被求值,并与子查询结果逐行比较。如果找到任意相等的子查询行,则IN的结果为。如果没有找到相等行,那么结果为(包括子查询不返回任何行的情况)。 @@ -10733,15 +10717,15 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 右手边是一个用圆括弧包围的子查询,它必须返回正好一个列。左手边表达式将被计算并与子查询结果逐行进行比较。 如果只找到不相等的子查询行(包括子查询不返回行的情况),那么NOT IN的结果是。 如果找到任何相等行,则结果为。 + 右手边是一个圆括号括起来的子查询,它必须恰好返回一列。左手边表达式会被求值,并与子查询结果逐行比较。如果只找到不相等的子查询行(包括子查询不返回任何行的情况),那么NOT IN的结果是。如果找到任何相等行,则结果为 - 请注意如果左手边表达式得到空值,或者没有相等的右手边值, 并且至少有一个右手边行得到空值,那么NOT IN结构的结果将是空值,而不是真。这个行为是遵照 SQL 处理空值的一般规则的。 + 请注意,如果左侧表达式得到空值,或者右侧没有相等的值且至少有一行得到空值,则NOT IN结构的结果将是空值,而不是真。这符合 SQL 对空值布尔组合的一般规则。 - 和EXISTS一样,假设子查询将被完成运行完全是不明智的。 + 和EXISTS一样,假定子查询一定会完整运行并不明智。 @@ -10749,7 +10733,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 这种形式的NOT IN的左手边是一个行构造器, 如中所述。 右手边是一个圆括弧子查询,它必须返回和左手边返回的行中表达式所构成的完全一样多的列。 左手边表达式将被计算并与子查询结果逐行进行比较。如果找到不等于子查询行的行,则NOT IN的结果为。如果找到相等行, 那么结果为(包括子查询不返回行的情况)。 + 这种形式的NOT IN左侧是一个行构造器,如中所述。右侧是一个用圆括号括起来的子查询,必须返回与左侧行中表达式数量完全相同的列数。对左侧表达式求值后,将其按行与子查询结果的每一行比较。如果只找到不相等的子查询行(包括子查询不返回任何行的情况),则NOT IN的结果为。如果找到任何相等行,则结果为 @@ -10774,11 +10758,11 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 请注意如果没有任何成功并且至少有一个右手边行为该操作符结果生成空值, 那么ANY结构的结果将是空值,而不是假。 这个行为是遵照 SQL 处理空值布尔组合的一般规则制定的。 + 请注意,如果没有任何比较返回真,并且至少有一个右侧行的操作符结果为空值,则ANY结构的结果将是空值,而不是假。这符合 SQL 对空值布尔组合的一般规则。 - 和EXISTS一样,假设子查询将被完成运行完全是不明智的。 + 和EXISTS一样,假定子查询一定会完整运行并不明智。 @@ -10787,7 +10771,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 这种形式的左侧是一个行构造器,如所述。右侧是一个用括号括起来的子查询,它必须返回与左侧行中表达式数量完全相同的列数。左侧表达式会被求值,并使用给定的operator与子查询结果的每一行逐行比较。如果比较对任何子查询行返回真,则ANY的结果为。如果比较对每一个子查询行都返回假,则结果为(包括子查询不返回行的情况)。如果比较对任何行都不返回真,并且至少有一次比较返回 NULL,则结果为 NULL。 + 这种形式的ANY左侧是一个行构造器,如所述。右侧是一个用括号括起来的子查询,它必须返回与左侧行中表达式数量完全相同的列数。左侧表达式会被求值,并使用给定的operator与子查询结果的每一行逐行比较。如果比较对任何子查询行返回真,则ANY的结果为。如果比较对每一个子查询行都返回假,则结果为(包括子查询不返回行的情况)。如果比较对任何行都不返回真,并且至少有一次比较返回 NULL,则结果为 NULL。 @@ -10803,7 +10787,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 这种形式的 ALL 右侧是一个用括号括起来的子查询,它必须只返回一列。左侧表达式会被求值,并使用给定的 operator 与子查询结果的每一行进行比较。该操作符必须产生布尔结果。如果所有行都得到真(包括子查询没有返回任何行的情况),ALL 的结果就是。如果发现任何假值结果,结果就是。如果比较对任何行都不返回假,并且至少有一次比较返回 NULL,则结果为 NULL。 + 右侧是一个用圆括号括起来的子查询,必须恰好返回一列。左侧表达式会被求值,并使用给定的operator与子查询结果的每一行进行比较。该操作符必须产生布尔结果。如果所有行都得到真(包括子查询不返回任何行的情况),则ALL的结果为。如果得到任何假值结果,则结果为。如果与任何子查询行的比较都不返回假,并且至少有一次比较返回 NULL,则结果为 NULL。 @@ -10811,7 +10795,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 和EXISTS一样,假设子查询将被完成运行完全是不明智的。 + 和EXISTS一样,假定子查询一定会完整运行并不明智。 @@ -10840,7 +10824,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 左手边是一个行构造器,如所述。 右手边是一个圆括弧括起来的子查询,该查询必须返回和左手边行中表达式数目完全一样的列。 另外,该子查询不能返回超过一行的数量(如果它返回零行,那么结果就是空值)。 左手边被计算并逐行与右手边的子查询结果行比较。 + 左侧是一个行构造器,如所述。右侧是一个用圆括号括起来的子查询,必须返回与左侧行中表达式数量完全相同的列数。此外,该子查询不能返回超过一行;如果它返回零行,则结果为空值。对左侧求值后,将所得的行与子查询返回的唯一一行进行比较。 @@ -10879,12 +10863,12 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 逐行比较 + 行比较 比较 - 逐行 + 复合类型 @@ -10901,7 +10885,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 本节描述几个特殊的结构,用于在值的组之间进行多重比较。这些形式语法上和前面一节的子查询形式相关,但是不涉及子查询。 这种形式涉及的数组子表达式是PostgreSQL的扩展; 其它的是SQL兼容的。所有本节记录的表达式形式都返回布尔(Boolean)结果(真/假)。 + 本节描述几个特殊的结构,用于在值的组之间进行多重比较。这些形式语法上和前面一节的子查询形式相关,但是不涉及子查询。 涉及数组子表达式的形式是PostgreSQL的扩展; 其余形式是SQL兼容的。本节介绍的所有表达式形式都返回布尔(Boolean)结果(真/假)。 @@ -10911,7 +10895,8 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); expression IN (value , ...) - 右侧是一个用圆括号括起的标量表达式列表。结果为true,条件是左侧表达式的结果等于右侧表达式中的任意一个。这是以下写法的简写: + 右侧是一个用圆括号括起来的标量表达式列表。如果左侧表达式的结果等于右侧任一表达式的结果,则结果为。这等价于以下写法: + expression = value1 OR expression = value2 @@ -10932,7 +10917,8 @@ OR expression NOT IN (value , ...) - 右侧是一个用圆括号括起的标量表达式列表。结果为true,条件是左侧表达式的结果与右侧的所有表达式都不相等。这是以下写法的简写: + 右侧是一个用圆括号括起来的标量表达式列表。如果左侧表达式的结果与右侧所有表达式的结果都不相等,则结果为。这等价于以下写法: + expression <> value1 AND expression <> value2 @@ -10954,7 +10940,7 @@ AND - <literal>ANY</literal>/<literal>SOME</literal> (array) + <literal>ANY</literal>/<literal>SOME</literal>(数组) expression operator ANY (array expression) @@ -10975,7 +10961,7 @@ AND - <literal>ALL</literal> (array) + <literal>ALL</literal>(数组) expression operator ALL (array expression) @@ -10997,7 +10983,7 @@ AND row_constructor operator row_constructor - 两侧都是行构造器,如所述。两个行值必须具有相同数量的字段。对两侧分别求值后,按行进行比较。当 operator=<><<=>>= 时,允许进行行构造器比较。每个行元素的类型都必须具有默认 B-tree 操作符类,否则尝试比较可能会报错。 + 两侧都是行构造器,如所述。两个行值必须具有相同数量的字段。对两侧分别求值后,按行进行比较。当 operator=<><<=>>= 时,允许进行行构造器比较。每个行元素的类型都必须具有默认 B-树操作符类,否则尝试比较可能会报错。 如果通过前面的列就已确定比较结果,则与元素数量或类型有关的错误可能不会发生。 @@ -11044,21 +11030,21 @@ AND - SQL 规范要求在结果依赖于比较两个 NULL 值或者一个 NULL 与一个非 NULL 时逐行比较返回 NULL。 + SQL 规范要求在结果依赖于比较两个 NULL 值或者一个 NULL 与一个非 NULL 时行比较返回 NULL。 PostgreSQL只有在比较两个行构造器(如)的结果或者比较一个行构造器与一个子查询的输出时才这样做(如中所述)。 - 在其他比较两个复合类型值的环境中,两个 NULL 域值被认为相等,并且一个 NULL 被认为大于一个非 NULL。 + 在其他比较两个复合类型值的环境中,两个 NULL 字段值被认为相等,并且一个 NULL 被认为大于一个非 NULL。 为了得到复合类型的一致的排序和索引行为,这样做是必要的。 - 每一边都会被计算并且它们会被逐行比较。当operator是 + 对两侧分别求值后,按行进行比较。当operator=<><<=>或者 - >=时或者具有与这些类似的语义时,允许复合类型的比较(更准确地说,如果一个操作符是一个 B-树操作符类的成员,或者是一个 B-树操作符类的=成员的否定词,它就可以是一个行比较操作符)。 - 上述操作符的行为与用于行构造器(见)的IS [ NOT ] DISTINCT FROM相同。 + >=时或者具有与这些类似的语义时,允许复合类型的比较(更准确地说,如果一个操作符是一个 B-树操作符类的成员,或者是一个 B-树操作符类的=成员的否定操作符,它就可以是一个行比较操作符)。 + 上述操作符的默认行为与用于行构造器(见)的IS [ NOT ] DISTINCT FROM相同。 @@ -11069,8 +11055,8 @@ AND *<=*>以及 *>=。 - 这些操作符比较两行的内部二进制表达。即使两行用相等操作符的比较为真,两行也可能具有不同的二进制表达。 - 行在这些比较操作符之下的排序是决定性的,其他倒没什么意义。 + 这些操作符比较两行的内部二进制表示。即使两行用相等操作符的比较为真,两行也可能具有不同的二进制表示。 + 使用这些比较操作符得到的行排序是确定的,但除此之外没有其他意义。 这些操作符在内部被用于物化视图并且可能对其他如复制之类的特殊功能有用,但是它们并不打算用在书写查询这类普通用途中。 @@ -11089,12 +11075,12 @@ AND - 本节描述那些可能返回多于一行的函数。目前这个类中被使用最广泛的是级数生成函数, 如所述。其他更特殊的集合返回函数在本手册的其他地方描述。 - 组合多集合返回函数的方法可见。 + 本节描述那些可能返回多于一行的函数。目前这个类中被使用最广泛的是序列生成函数, 如所述。其他更特殊的集合返回函数在本手册的其他地方描述。 + 组合多个集合返回函数的方法可见 - 级数生成函数 + 序列生成函数 @@ -11161,7 +11147,7 @@ SELECT generate_series(1.1, 4, 1.3); 3.7 (3 rows) --- this example relies on the date-plus-integer operator +-- 此示例使用日期加整数的操作符 SELECT current_date + s.a AS dates FROM generate_series(0,14,7) AS s(a); dates ------------ @@ -11221,7 +11207,7 @@ SELECT * FROM generate_series('2008-03-01 00:00'::timestamp, generate_subscripts是一个便利函数,用于生成给定数组在指定维度上的有效下标集合。对于没有所请求维度的数组或 NULL 数组,返回零行(但数组中的 NULL 元素仍会返回有效下标)。下面是一些示例: --- basic usage +-- 基本用法 SELECT generate_subscripts('{NULL,1,NULL,2}'::int[], 1) AS s; s --- @@ -11231,8 +11217,8 @@ SELECT generate_subscripts('{NULL,1,NULL,2}'::int[], 1) AS s; 4 (4 rows) --- presenting an array, the subscript and the subscripted --- value requires a subquery +-- 展示数组、下标和下标对应的值 +-- 需要使用子查询 SELECT * FROM arrays; a -------------------- @@ -11251,7 +11237,7 @@ FROM (SELECT generate_subscripts(a, 1) AS s, a FROM arrays) foo; {100,200,300} | 3 | 300 (5 rows) --- unnest a 2D array +-- 展开二维数组 CREATE OR REPLACE FUNCTION unnest2(anyarray) RETURNS SETOF anyelement AS $$ select $1[i][j] @@ -11271,13 +11257,13 @@ SELECT * FROM unnest2(ARRAY[[1,2],[3,4]]); - ordinality + 序号 FROM子句中的函数后面加上WITH ORDINALITY时,一个bigint列会追加到输出中,其值从 1 开始,对函数输出的每一行递增 1。这种方式对集合返回函数尤其有用,例如unnest() --- set returning function WITH ORDINALITY +-- 集合返回函数与 WITH ORDINALITY SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); ls | n -----------------+---- @@ -11310,7 +11296,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); 系统信息函数 - 展示了多个可以抽取会话和系统信息的函数。 + 列出了多个用于提取会话和系统信息的函数。 @@ -11401,7 +11387,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); pg_blocking_pids(int) int[] - 阻止指定服务器进程 ID 获取锁的进程 ID + 阻止指定服务器进程获取锁的进程 ID @@ -11449,7 +11435,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); pg_safe_snapshot_blocking_pids(int) int[] - 阻止指定服务器进程 ID 获取安全快照的进程 ID + 阻止指定服务器进程获取安全快照的进程 ID @@ -11481,8 +11467,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); - current_catalogcurrent_rolecurrent_schemacurrent_usersession_useruserSQL里有特殊的语法地位: 它们被调用时结尾不要跟着圆括号。 - 在 PostgreSQL 中,圆括号可以有选择性地被用于current_schema,但是不能和其他的一起用。 + current_catalogcurrent_rolecurrent_schemacurrent_usersession_useruserSQL中具有特殊语法:调用时不得在后面加圆括号。在 PostgreSQL 中,current_schema可以选择加圆括号,其他函数则不可以。 @@ -11519,13 +11504,13 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); - schema - current + 模式 + 当前 - search path - current + 搜索路径 + 当前 @@ -11533,8 +11518,8 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); - user - current + 用户 + 当前 @@ -11542,11 +11527,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); - session_user通常是发起当前数据库连接的用户,不过超级用户可以用修改这个设置。 - current_user是用于权限检查的用户标识。通常, 它总是等于会话用户,但是可以被改变。 - 它也会在函数执行的过程中随着属性SECURITY DEFINER的改变而改变。 - 在 Unix 的说法里,那么会话用户是真实用户,而当前用户是有效用户。 - current_role以及usercurrent_user的同义词(SQL标准在current_rolecurrent_user之间做了区分,但PostgreSQL不区分,因为它把用户和角色统一成了一种实体)。 + session_user通常是发起当前数据库连接的用户,但超级用户可以用修改此设置。current_user是用于权限检查的用户标识,通常等于会话用户,但可以用更改。在执行具有SECURITY DEFINER属性的函数期间,它也会改变。用 Unix 的术语来说,会话用户是真实用户,当前用户是有效用户current_roleusercurrent_user的同义词。(SQL 标准区分current_rolecurrent_user,但PostgreSQL不区分,因为它将用户和角色统一为同一种实体。) current_schema 返回搜索路径中第一个模式的名称(如果搜索路径为空,则返回空值)。在创建表或其他命名对象时,如果未指定目标模式,就会使用该模式。current_schemas(boolean) 返回当前搜索路径中所有模式名称的数组。布尔选项决定是否在返回的搜索路径中包含 pg_catalog 等隐式包含的系统模式。 @@ -11593,18 +11574,18 @@ SET search_path TO schema , schema, .. - Logging - pg_current_logfile函数 + 日志记录 + pg_current_logfile 函数 current_logfiles - 和pg_current_logfile函数 + 和pg_current_logfile 函数 - Logging - current_logfiles文件和pg_current_logfile函数 + 日志记录 + current_logfiles 文件和pg_current_logfile 函数 pg_current_logfiletext 返回日志收集器当前使用的日志文件路径。路径包括 目录和日志文件名。必须启用日志收集,否则返回值为 NULL。当存在多个格式不同的日志文件时,不带参数调用 pg_current_logfile 会按 stderrcsvlog 的顺序查找,返回找到的第一个格式的文件路径。如果没有任何日志文件采用这些格式,则返回 NULL。要请求特定文件格式,可向可选参数传入 text 类型的 csvlogstderr。如果请求的日志格式未配置在 中,返回值为 NULLpg_current_logfile 反映 current_logfiles 文件的内容。 @@ -11648,8 +11629,8 @@ SET search_path TO schema , schema, .. version 返回一个描述 PostgreSQL 服务器版本的字符串。也可以通过 获取此信息,或者通过 获取机器可读的版本。软件开发者应使用 server_version_num(自 8.2 起提供)或 ,而不是解析文本版本。 - privilege - querying + 权限 + 查询 列出了允许用户以编程方式查询对象访问权限的函数。关于权限的更多信息,请参见 @@ -11668,14 +11649,14 @@ SET search_path TO schema , schema, .. privilege) boolean - 用户是否对表的任意列具有权限 + 用户是否对表的至少一列具有权限 has_any_column_privilege(table, privilege) boolean - 当前用户是否对表的任意列具有权限 + 当前用户是否对表的至少一列具有权限 has_column_privilege(user, @@ -11924,7 +11905,7 @@ SELECT has_table_privilege('joe', 'mytable', 'INSERT, SELECT WITH GRANT OPTION') has_sequence_privilege 检查用户是否可以以某种方式访问序列。其参数形式与 has_table_privilege 类似。所需访问权限类型必须为 USAGESELECTUPDATE 之一。 - has_any_column_privilege 检查用户是否可以以某种方式访问表的任意列。其参数形式与 has_table_privilege 类似,但所需访问权限类型必须为 SELECTINSERTUPDATEREFERENCES 的某种组合。注意,在表级别拥有这些权限中的任意一种,就隐式地对表的每一列拥有该权限,因此对于相同参数,如果 has_table_privilege 返回 truehas_any_column_privilege 也总是返回真。但是,只要至少有一列获得该权限的列级授权,has_any_column_privilege 也会成功。 + has_any_column_privilege 检查用户是否可以以某种方式访问表的至少一列。其参数形式与 has_table_privilege 类似,但所需访问权限类型必须为 SELECTINSERTUPDATEREFERENCES 的某种组合。注意,在表级别拥有这些权限中的任意一种,就隐式地对表的每一列拥有该权限,因此对于相同参数,如果 has_table_privilege 返回 truehas_any_column_privilege 也总是返回真。但是,只要至少有一列获得该权限的列级授权,has_any_column_privilege 也会成功。 has_column_privilege 检查用户是否可以以某种方式访问列。其参数形式与 has_table_privilege 类似,但还可以通过列名或属性编号指定列。所需访问权限类型必须为 SELECTINSERTUPDATEREFERENCES 的某种组合。注意,在表级别拥有这些权限中的任意一种,就隐式地对表的每一列拥有该权限。 @@ -12014,22 +11995,22 @@ SELECT relname FROM pg_class WHERE pg_table_is_visible(oid); pg_ts_config_is_visible(config_oid) boolean - 全文搜索配置是否在搜索路径中可见 + 全文检索配置是否在搜索路径中可见 pg_ts_dict_is_visible(dict_oid) boolean - 全文搜索词典是否在搜索路径中可见 + 全文检索词典是否在搜索路径中可见 pg_ts_parser_is_visible(parser_oid) boolean - 全文搜索解析器是否在搜索路径中可见 + 全文检索解析器是否在搜索路径中可见 pg_ts_template_is_visible(template_oid) boolean - 全文搜索模板是否在搜索路径中可见 + 全文检索模板是否在搜索路径中可见 pg_type_is_visible(type_oid) @@ -12241,12 +12222,12 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); pg_get_expr(pg_node_tree, relation_oid) text - 反编译表达式的内部形式,假定其中所有 Var 都引用第二个参数指定的关系 + 反编译表达式的内部形式,假定其中所有 Var 节点都引用第二个参数指定的关系 pg_get_expr(pg_node_tree, relation_oid, pretty_bool) text - 反编译表达式的内部形式,假定其中所有 Var 都引用第二个参数指定的关系 + 反编译表达式的内部形式,假定其中所有 Var 节点都引用第二个参数指定的关系 pg_get_functiondef(func_oid) @@ -12431,12 +12412,12 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); pg_get_keywords 返回一组记录,描述服务器识别的 SQL 关键字。word 列包含关键字。catcode 列包含类别代码:U 表示非保留关键字,C 表示列名,T 表示类型名或函数名,R 表示保留关键字。catdesc 列包含描述该类别的字符串,该字符串可能已经过本地化。 - pg_get_constraintdefpg_get_indexdefpg_get_ruledefpg_get_statisticsobjdefpg_get_triggerdef 分别重建约束、索引、规则、扩展统计对象或触发器的创建命令。(注意,这是通过反编译重建的,并非命令的原始文本。)pg_get_expr 反编译单个表达式的内部形式,例如列的默认值。这在检查系统目录内容时可能很有用。如果表达式可能包含 Vars,请将它们所引用的关系的 OID 指定为第二个参数;如果预计不含 Vars,传入零即可。pg_get_viewdef 重建定义视图的 SELECT 查询。这些函数中的大多数有两种变体,其中一种可以选择美化输出结果。美化格式更易读,但默认格式更可能被未来版本的 PostgreSQL 以相同方式解释;转储时应避免使用美化输出。向美化输出参数传入 false,所得结果与完全没有该参数的变体相同。 + pg_get_constraintdefpg_get_indexdefpg_get_ruledefpg_get_statisticsobjdefpg_get_triggerdef 分别重建约束、索引、规则、扩展统计信息对象或触发器的创建命令。(注意,这是通过反编译重建的,并非命令的原始文本。)pg_get_expr 反编译单个表达式的内部形式,例如列的默认值。这在检查系统目录内容时可能很有用。如果表达式可能包含 Var 节点,请将它们所引用的关系的 OID 指定为第二个参数;如果预计不含 Var 节点,传入零即可。pg_get_viewdef 重建定义视图的 SELECT 查询。这些函数中的大多数有两种变体,其中一种可以选择美化输出结果。美化格式更易读,但默认格式更可能被未来版本的 PostgreSQL 以相同方式解释;转储时应避免使用美化输出。向美化输出参数传入 false,所得结果与完全没有该参数的变体相同。 pg_get_functiondef 返回一个函数的完整 CREATE OR REPLACE FUNCTION 语句。pg_get_function_argumentsCREATE FUNCTION 中所需的形式返回函数参数列表。pg_get_function_result 类似地返回该函数相应的 RETURNS 子句。pg_get_function_identity_arguments 返回标识函数所需的参数列表,例如以 ALTER FUNCTION 中所需的形式返回。此形式省略默认值。 - pg_get_serial_sequence返回与列关联的序列名称;如果该列没有关联序列,则返回 NULL。如果列是标识列,关联序列就是为标识列在内部创建的序列。对于使用某种串行类型(serialsmallserialbigserial)创建的列,关联序列就是为该串行列定义创建的序列。在后一种情况下,可以使用ALTER SEQUENCE OWNED BY修改或移除这种关联。(该函数也许应该叫作pg_get_owned_sequence;它当前的名称反映了它通常用于serialbigserial列这一事实。)第一个输入参数是可以带有模式名的表名,第二个参数是列名。由于第一个参数可能包含模式和表,它不会被当作双引号括起的标识符处理,因此默认转换为小写;第二个参数只包含列名,会被当作带双引号的标识符处理并保留大小写。函数返回的值采用适于传递给序列函数的格式(参见)。典型用法是读取标识列或串行列的序列当前值,例如: + pg_get_serial_sequence返回与列关联的序列名称;如果该列没有关联序列,则返回 NULL。如果列是标识列,关联序列就是为标识列在内部创建的序列。对于使用某种 serial 类型(serialsmallserialbigserial)创建的列,关联序列就是为该 serial 列定义创建的序列。在后一种情况下,可以使用ALTER SEQUENCE OWNED BY修改或移除这种关联。(该函数也许应该叫作pg_get_owned_sequence;它当前的名称反映了它通常用于serialbigserial列这一事实。)第一个输入参数是可以带有模式名的表名,第二个参数是列名。由于第一个参数可能包含模式和表,它不会被当作双引号括起的标识符处理,因此默认转换为小写;第二个参数只包含列名,会被当作带双引号的标识符处理并保留大小写。函数返回的值采用适于传递给序列函数的格式(参见)。典型用法是读取标识列或 serial 列的序列当前值,例如: SELECT currval(pg_get_serial_sequence('sometable', 'id')); @@ -12487,19 +12468,20 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); distance_orderable - 列能否通过一个distance操作符(例如ORDER BY col <-> constant)有序地扫描? + + 能否按距离操作符的结果有序地扫描该列,例如ORDER BY col <-> constant returnable - 列值是否可以通过一次只用索引扫描返回? + 列值是否可以通过一次仅索引扫描返回? search_array - 列是否天然支持col = ANY(array)搜索? + 列是否原生支持col = ANY(array)搜索? @@ -12514,7 +12496,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id'));
- 索引性质 + 索引属性 @@ -12550,7 +12532,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id'));
- 索引访问方法性质 + 索引访问方法属性 @@ -12635,12 +12617,11 @@ SELECT collation for ('foo' COLLATE "de_DE"); - 列出了与数据库对象 - 标识和定位有关的函数。 + 列出了与数据库对象标识和寻址有关的函数。
- 对象信息和定位函数 + 对象信息和寻址函数 名称 返回类型 描述 @@ -12671,7 +12652,7 @@ SELECT collation for ('foo' COLLATE "de_DE");
- pg_describe_object 返回数据库对象的文本描述,对象由系统目录 OID、对象 OID 和子对象 ID 指定(例如表中的列号;引用整个对象时,子对象 ID 为零)。该描述供人阅读,并可能根据服务器配置被翻译。这有助于确定存储在 pg_depend 系统目录中的对象身份。 + pg_describe_object 返回数据库对象的文本描述,对象由系统目录 OID、对象 OID 和子对象 ID 指定(例如表中的列号;引用整个对象时,子对象 ID 为零)。该描述供人阅读,并可能根据服务器配置被翻译。这有助于确定存储在 pg_depend 系统目录中的对象标识。 pg_identify_object 返回一行,其中包含足以唯一标识数据库对象的信息,该对象由系统目录 OID、对象 OID 和子对象 ID 指定。这些信息供机器读取,永远不会被翻译。type 标识数据库对象的类型;schema 是对象所属的模式名,对于不属于模式的对象类型则为 NULL;如果对象名(以及适用时的模式名)足以唯一标识该对象,name 就是对象名,并在必要时加引号,否则为 NULLidentity 是完整的对象标识,其具体格式取决于对象类型,格式中的每个名称都会根据需要加上模式限定和引号。 @@ -12697,7 +12678,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); - 中展示的函数抽取注释,注释是由命令在以前存储的。如果对指定参数找不到注释,则返回空值。 + 中的函数用于提取此前通过命令存储的注释。如果找不到与指定参数对应的注释,则返回空值。 @@ -12925,7 +12906,7 @@ SELECT collation for ('foo' COLLATE "de_DE");
- pg_control_checkpoint 返回一条记录,其内容见 + pg_control_checkpoint 返回一条记录,其内容见 <function>pg_control_checkpoint</function> 输出列 @@ -13039,7 +13020,7 @@ SELECT collation for ('foo' COLLATE "de_DE");
- pg_control_system 返回一条记录,其内容见 + pg_control_system 返回一条记录,其内容见 <function>pg_control_system</function> 输出列 @@ -13078,7 +13059,7 @@ SELECT collation for ('foo' COLLATE "de_DE");
- pg_control_init 返回一条记录,其内容见 + pg_control_init 返回一条记录,其内容见 <function>pg_control_init</function> 输出列 @@ -13157,7 +13138,7 @@ SELECT collation for ('foo' COLLATE "de_DE");
- pg_control_recovery 返回一条记录,其内容见 + pg_control_recovery 返回一条记录,其内容见 <function>pg_control_recovery</function> 输出列 @@ -13248,19 +13229,19 @@ SELECT collation for ('foo' COLLATE "de_DE"); - configuration - of the server - functions + 配置 + 服务器 + 函数 - 函数current_setting返回以下设置的当前值:setting_name。它对应于SQL命令SHOW。例如: + 函数current_setting返回设置setting_name的当前值。它对应于SQL命令SHOW。例如: SELECT current_setting('datestyle'); current_setting ----------------- ISO, MDY (1 row) -如果不存在以下名称的设置:setting_name, +如果不存在名为setting_name的设置, current_setting会报错,除非提供了missing_ok且其值为true @@ -13299,7 +13280,7 @@ SELECT set_config('log_statement_stats', 'off', false); - 在中展示的函数向其它服务器进程发送控制信号。默认情况下这些函数只能被超级用户使用,但是如果需要,可以利用GRANT把访问权限授予给其他用户。 + 在中展示的函数向其它服务器进程发送控制信号。默认情况下这些函数只能被超级用户使用,但是如果需要,可以利用GRANT把访问权限授予给其他用户(注明的例外除外)。
@@ -13343,7 +13324,7 @@ SELECT set_config('log_statement_stats', 'off', false); pg_cancel_backendpg_terminate_backend向由进程 ID 标识的后端进程发送信号(分别是SIGINTSIGTERM)。 - 一个活动后端的进程 ID可以从pg_stat_activity视图的pid列中找到,或者通过在服务器上列出postgres进程(在 Unix 上使用ps或者在Windows上使用Task Manager)得到。 + 一个活动后端的进程 ID可以从pg_stat_activity视图的pid列中找到,或者通过在服务器上列出postgres进程(在 Unix 上使用ps或者在Windows上使用任务管理器)得到。 一个活动后端的角色可以在pg_stat_activity视图的usename列中找到。 @@ -13357,7 +13338,7 @@ SELECT set_config('log_statement_stats', 'off', false); 备份控制函数 - backup + 备份 pg_create_restore_point @@ -13406,7 +13387,7 @@ SELECT set_config('log_statement_stats', 'off', false); pg_create_restore_point(name text) pg_lsn - 创建用于还原的命名点(默认仅限超级用户,但可以向其他用户授予 EXECUTE 权限以运行此函数) + 创建用于恢复的命名点(默认仅限超级用户,但可以向其他用户授予EXECUTE权限以运行此函数) @@ -13432,19 +13413,19 @@ SELECT set_config('log_statement_stats', 'off', false); pg_start_backup(label text , fast boolean , exclusive boolean ) pg_lsn - 准备执行在线备份(默认仅限超级用户,但可以向其他用户授予 EXECUTE 权限以运行此函数) + 准备执行在线备份(默认仅限超级用户,但可以向其他用户授予EXECUTE权限以运行此函数) pg_stop_backup() pg_lsn - 结束排他在线备份(默认仅限超级用户,但可以向其他用户授予 EXECUTE 权限以运行此函数) + 结束排他在线备份(默认仅限超级用户,但可以向其他用户授予EXECUTE权限以运行此函数) pg_stop_backup(exclusive boolean , wait_for_archive boolean ) setof record - 结束排他或非排他在线备份(默认仅限超级用户,但可以向其他用户授予 EXECUTE 权限以运行此函数) + 结束排他或非排他在线备份(默认仅限超级用户,但可以向其他用户授予EXECUTE权限以运行此函数) @@ -13465,7 +13446,7 @@ SELECT set_config('log_statement_stats', 'off', false); pg_switch_wal() pg_lsn - 强制切换到新的预写式日志文件(默认仅限超级用户,但可以向其他用户授予 EXECUTE 权限以运行此函数) + 强制切换到新的预写式日志文件(默认仅限超级用户,但可以向其他用户授予EXECUTE权限以运行此函数) pg_walfile_name(lsn pg_lsn) @@ -13594,7 +13575,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); - 控制恢复进度的功能如 所示。这些函数只能在恢复过程中执行。 + 列出的函数用于控制恢复进度。这些函数只能在恢复期间执行。
@@ -13618,14 +13599,14 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); pg_wal_replay_pause()void - 立即暂停恢复(默认仅限超级用户,但可以向其他用户授予 EXECUTE 权限以运行此函数)。 + 立即暂停恢复(默认仅限超级用户,但可以向其他用户授予EXECUTE权限以运行此函数)。 pg_wal_replay_resume() void - 如果恢复已暂停,则重新开始恢复(默认仅限超级用户,但可以向其他用户授予 EXECUTE 权限以运行此函数)。 + 如果恢复已暂停,则重新开始恢复(默认仅限超级用户,但可以向其他用户授予EXECUTE权限以运行此函数)。 @@ -13652,7 +13633,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); - 为了解决这个问题,PostgreSQL允许一个事务导出它正在使用的快照。只要导出的事务仍然保持打开,其他事务可以导入它的快照,并且因此可以保证它们可以看到和第一个事务看到的完全一样的数据库视图。但是注意这些事务中的任何一个对数据库所作的更改对其他事务仍然保持不可见,和未提交事务所作的修改一样。因此这些事务是针对以前存在的数据同步,而对由它们自己所作的更改则采取正常的动作。 + 为了解决这个问题,PostgreSQL允许一个事务导出它正在使用的快照。只要导出快照的事务仍然保持打开,其他事务可以导入它的快照,并且因此可以保证它们可以看到和第一个事务看到的完全一样的数据库视图。但是注意这些事务中的任何一个对数据库所作的更改对其他事务仍然保持不可见,和未提交事务所作的修改一样。因此这些事务是针对以前存在的数据同步,而对由它们自己所作的更改则采取正常的动作。 @@ -14004,7 +13985,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); 上述操作表和索引的函数接受一个regclass参数,它是该表或索引在pg_class系统目录中的 OID。 你不必手工去查找该 OID,因为regclass数据类型的输入转换器会为你代劳。 - 只写包围在单引号内的表名,这样它看起来像一个文字常量。 + 只写包围在单引号内的表名,这样它看起来像一个字面量。 为了与普通SQL名称的处理相兼容,该字符串将被转换为小写形式,除非其中在表名周围包含双引号。 @@ -14086,7 +14067,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); pg_collation_actual_version 返回当前安装在操作系统中的排序规则对象的实际版本。如果它与 pg_collation.collversion 中的值不同,则可能需要重建依赖该排序规则的对象。另见 - pg_import_system_collations 根据操作系统中找到的所有区域环境,向系统目录 pg_collation 添加排序规则。initdb 使用的就是此函数;更多信息见。如果以后在操作系统中安装了其他区域环境,可以再次运行此函数,为新区域环境添加排序规则。与 pg_collation 中现有条目匹配的区域环境会被跳过。(但此函数不会删除基于操作系统中已不存在的区域环境的排序规则对象。)schema 参数通常为 pg_catalog,但并非必须如此;也可以将排序规则安装到其他模式中。函数返回新建的排序规则对象数量。此函数仅限超级用户使用。 + pg_import_system_collations 根据操作系统中找到的所有区域设置,向系统目录 pg_collation 添加排序规则。initdb 使用的就是此函数;更多信息见。如果以后在操作系统中安装了其他区域设置,可以再次运行此函数,为新区域设置添加排序规则。与 pg_collation 中现有条目匹配的区域设置会被跳过。(但此函数不会删除基于操作系统中已不存在的区域设置的排序规则对象。)schema 参数通常为 pg_catalog,但并非必须如此;也可以将排序规则安装到其他模式中。函数返回新建的排序规则对象数量。此函数仅限超级用户使用。 @@ -14143,7 +14124,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup());
- brin_summarize_new_values 接受 BRIN 索引的 OID 或名称,检查索引,找出基表中尚未被索引汇总的页面范围;对于每个这样的范围,它通过扫描表页面创建新的汇总索引元组。函数返回插入索引的新页面范围汇总数量。brin_summarize_range 执行相同的操作,但只汇总覆盖给定块号的范围。 + brin_summarize_new_values 接受 BRIN 索引的 OID 或名称,检查索引,找出基表中尚未生成索引摘要的页面范围;对于每个这样的范围,它通过扫描表页面创建新的摘要索引元组。函数返回插入索引的新页面范围摘要数量。brin_summarize_range 执行相同的操作,但只对覆盖给定块号的范围生成摘要。 gin_clean_pending_list 接受 GIN 索引的 OID 或名称,通过将待处理列表中的条目批量移到主 GIN 数据结构中,清理指定索引的待处理列表。它返回从待处理列表中移除的页面数。注意,如果参数是禁用了 fastupdate 选项的 GIN 索引,则不执行清理并返回 0,因为该索引没有待处理列表。关于待处理列表和 fastupdate 选项的详细信息,请参见 @@ -14454,7 +14435,7 @@ FOR EACH ROW EXECUTE PROCEDURE suppress_redundant_updates_trigger(); 事件触发器函数 - PostgreSQL提供了这些助手函数来从事件触发器检索信息。 + PostgreSQL提供了这些辅助函数来从事件触发器检索信息。 @@ -14471,7 +14452,7 @@ FOR EACH ROW EXECUTE PROCEDURE suppress_redundant_updates_trigger(); 当在一个ddl_command_end事件触发器的函数中调用时,pg_event_trigger_ddl_commands返回被每一个用户动作执行的DDL命令的列表。 如果在其他任何环境中调用这个函数,会发生错误。 - pg_event_trigger_ddl_commands为每一个被执行的基本命令返回一行,某些只有一个单一 SQL 句子的命令可能会返回多于一行。 + pg_event_trigger_ddl_commands为每一个被执行的基本命令返回一行,某些由单条 SQL 语句构成的命令可能会返回多于一行。 这个函数返回下面的列: @@ -14488,7 +14469,7 @@ FOR EACH ROW EXECUTE PROCEDURE suppress_redundant_updates_trigger(); classid oid - 对象所属的目录的 OID + 对象所属系统目录的 OID objid @@ -14498,7 +14479,7 @@ FOR EACH ROW EXECUTE PROCEDURE suppress_redundant_updates_trigger(); objsubid integer - 对象的子-id(例如列的属性号) + 子对象 ID(例如列的属性编号) command_tag @@ -14514,16 +14495,14 @@ FOR EACH ROW EXECUTE PROCEDURE suppress_redundant_updates_trigger(); schema_name text - 该对象所属的模式的名称(如果有),如果没有则为NULL。 - 没有引号。 + 对象所属模式的名称(若有);否则为NULL。不加引号。 object_identity text - 对象标识的文本表现形式,用模式限定。如果必要,出现在 - 该标识中的每一个标识符都会加上引号。 + 对象标识的文本表示形式,带模式限定。标识中包含的每个标识符在必要时都会加引号。 @@ -14535,8 +14514,7 @@ FOR EACH ROW EXECUTE PROCEDURE suppress_redundant_updates_trigger(); command pg_ddl_command - 以内部格式表达的该命令的一个完整表现形式。这不能被直接输出, - 但是可以把它传递给其他函数来得到有关于该命令不同部分的信息。 + 命令的完整内部表示,不能直接输出,但可以将其传给其他函数以获取关于该命令的不同信息。 @@ -14567,7 +14545,7 @@ FOR EACH ROW EXECUTE PROCEDURE suppress_redundant_updates_trigger(); classid oid - 对象所属的目录的 OID + 对象原先所属系统目录的 OID objid @@ -14577,7 +14555,7 @@ FOR EACH ROW EXECUTE PROCEDURE suppress_redundant_updates_trigger(); objsubid integer - 子对象ID(如列的属性号) + 子对象 ID(例如列的属性编号) original @@ -14588,7 +14566,7 @@ FOR EACH ROW EXECUTE PROCEDURE suppress_redundant_updates_trigger(); normal bool - 指示在依赖图中有一个普通依赖关系指向该对象的标志 + 如果依赖图中存在指向该对象的普通依赖关系,则为真。 @@ -14607,29 +14585,28 @@ FOR EACH ROW EXECUTE PROCEDURE suppress_redundant_updates_trigger(); schema_name text - 对象所属模式的名称(如果存在);否则为NULL。不加引号。 + 对象原先所属模式的名称(若有);否则为NULL。不加引号。 object_name text - 如果模式和名称的组合能被用于对象的一个唯一标识符,则是对象的名称;否则是NULL。不加引号,并且名称不是模式限定的。 + 如果模式和名称的组合可用作该对象的唯一标识符,则为对象名称;否则为NULL。不加引号,并且该名称永远不带模式限定。 object_identity text - 带模式限定的对象标识的文本表示。其中的每个标识符都会在必要时加引号。 + 对象标识的文本表示形式,带模式限定。标识中包含的每个标识符在必要时都会加引号。 address_names text[] - 一个数组,它可以和object_typeaddress_args, - 一起通过pg_get_object_address()函数在一台包含有同类相同名称对象的远程服务器上重建该对象地址。 + 一个数组,可与object_typeaddress_args一起,通过pg_get_object_address()函数在包含同类同名对象的远程服务器上重建该对象地址。 diff --git a/zh/10/gin.sgml b/zh/10/gin.sgml index 65be6ae6..62ddc580 100644 --- a/zh/10/gin.sgml +++ b/zh/10/gin.sgml @@ -53,7 +53,7 @@ 内置操作符类 - PostgreSQL 核心发布包含 + PostgreSQL 核心发行版包含 所示的 GIN 操作符类。 (在 中描述的一些可选模块还提供额外的 GIN 操作符类。) @@ -64,7 +64,7 @@ 名称 - 索引数据类型 + 被索引数据类型 可索引操作符 @@ -118,7 +118,10 @@ GIN 将可扩展性与通用性、代码重用以及清晰的接口结合在一起。 - GIN中,操作符类必须提供以下两个方法: + + GIN 操作符类必须提供两个方法: + + Datum *extractValue(Datum itemValue, int32 *nkeys, bool **nullFlags) @@ -127,7 +130,7 @@ 给定一个要建立索引的项,返回一个用 palloc 分配的键数组。返回键的数量必须存入 *nkeys。如果任一键可以为 null,还要另外 palloc 一个包含 *nkeysbool 字段的数组,将其地址存入 - *nullFlags,并按需设置这些空值标志。如果所有键都非空, + *nullFlags,并按需设置这些空值标志。如果所有键都不是 null, *nullFlags 可以保持为 NULL(其初始值)。 如果该项不包含任何键,则返回值可以为 NULL @@ -147,7 +150,7 @@ query 的数据类型,以及应采用何种方法提取键值。返回键的数量必须存入 *nkeys。如果任一键可以为 null,还要另外 palloc 一个包含 *nkeysbool 字段的数组,将其地址存入 - *nullFlags,并按需设置这些空值标志。如果所有键都非空, + *nullFlags,并按需设置这些空值标志。如果所有键都不是 null, *nullFlags 可以保持为 NULL(其初始值)。 如果 query 不包含任何键,则返回值可以为 NULL @@ -160,7 +163,7 @@ 被设置为 GIN_SEARCH_MODE_INCLUDE_EMPTY,则除至少包含一个匹配键的项之外, 完全不含任何键的项也会被视为候选匹配。(例如,该模式对于实现是子集操作符很有用。) 若 *searchMode 被设置为 GIN_SEARCH_MODE_ALL, - 则索引中所有非空项都会被视为候选匹配,无论它们是否匹配任一返回键。 + 则索引中所有非 null 项都会被视为候选匹配,无论它们是否匹配任一返回键。 (该模式比前两种选择慢得多,因为它基本上需要扫描整个索引;但为了正确处理某些边界情况, 可能有此必要。在大多数情况下都需要此模式的操作符,大概并不适合作为 GIN 操作符类的候选。)用于设置该模式的符号定义在 @@ -188,7 +191,15 @@ - 操作符类还必须提供一个函数,用于检查被索引项是否匹配查询。它有两种形式:布尔型consistent函数和三值triConsistent函数。triConsistent涵盖两者的功能,因此只提供triConsistent就已经足够。不过,如果布尔变体的计算明显更便宜,那么同时提供两者会更有利。若只提供布尔变体,则一些依赖于在取回所有键之前先排除索引项的优化将被禁用。 + + + 操作符类还必须提供一个函数,用于检查被索引项是否匹配查询。它有两种形式:布尔型 + consistent 函数,以及三值型 triConsistent 函数。 + triConsistent 覆盖了两者的功能,因此仅提供 triConsistent + 就已经足够。不过,如果布尔变体的计算代价明显更低,那么同时提供两者可能更有利。 + 若只提供布尔变体,则一些依赖于在取回所有键之前先排除索引项的优化将被禁用。 + + bool consistent(bool check[], StrategyNumber n, Datum query, int32 nkeys, Pointer extra_data[], bool *recheck, @@ -200,10 +211,10 @@ 该函数无法直接访问被索引项的值,因为 GIN 并不显式存储项。 它所能利用的是这样一种信息:从查询中提取出的哪些键值出现在给定的被索引项中。 check 数组长度为 nkeys,这与先前针对该 - query 数据由 extractQuery 返回的键数量相同。 + query datum 由 extractQuery 返回的键数量相同。 如果被索引项包含相应查询键,则 check 数组中的对应元素为 TRUE; 也就是说,如果 (check[i] == TRUE),则 extractQuery - 结果数组中的第 i 个键存在于该被索引项中。传入原始 query 数据值, + 结果数组中的第 i 个键存在于该被索引项中。传入原始 query datum, 是为了让 consistent 方法在需要时可以查看它;同样也会传入先前由 extractQuery 返回的 queryKeys[]nullFlags[] 数组。extra_data 则是 @@ -241,7 +252,7 @@ 而 GIN_MAYBE 表示该键是否存在尚不确定。存在 GIN_MAYBE 值时,只有当无论索引项是否包含对应查询键,该项都确定匹配时,函数才应返回 GIN_TRUE。同样,只有当无论是否包含 GIN_MAYBE 键, - 该项都确定不匹配时,函数才必须返回 GIN_FALSE。如果结果依赖于 + 该项都确定不匹配时,函数才能返回 GIN_FALSE。如果结果依赖于 GIN_MAYBE 条目,也就是说,无法根据已知的查询键确认或否定匹配, 则函数必须返回 GIN_MAYBE @@ -255,7 +266,11 @@
- 此外,GIN 必须能够对索引中存储的键值排序。操作符类可以通过指定比较方法来定义排序顺序: + + 此外,GIN 必须有一种方法对存储在索引中的键值进行排序。 + 操作符类可以通过指定一个比较方法来定义这种排序顺序: + + int compare(Datum a, Datum b) @@ -265,7 +280,13 @@ - 或者,如果操作符类没有提供compare方法,GIN 就会查找索引键数据类型的默认 btree 操作符类,并使用其比较函数。对于只适用于一种数据类型的 GIN 操作符类,建议指定比较函数,因为查找 btree 操作符类需要耗费一些处理器周期。但是,多态 GIN 操作符类(例如array_ops)通常无法指定单一的比较函数。 + + + 或者,如果操作符类没有提供 compare 方法,GIN + 将查找该索引键数据类型的默认 B-树操作符类,并使用其比较函数。建议在仅面向单一数据类型的 + GIN 操作符类中显式指定比较函数,因为查找 B-树操作符类会消耗少量处理器周期。 + 不过,多态 GIN 操作符类(例如 array_ops)通常无法指定单一比较函数。 +
作为可选项,GIN操作符类可以提供以下方法: @@ -308,8 +329,8 @@ 在内部,一个 GIN 索引包含一个基于键构建的 B-树索引,其中每个键都是一个或多个被索引项中的某个元素 - (例如数组成员),而叶子页中的每个元组要么包含一个指向堆指针 B-树的指针(posting tree), - 要么在列表足够小、能够连同键值一起放入单个索引元组时,直接包含一个简单的堆指针列表(posting list)。 + (例如数组成员),而叶子页中的每个元组要么包含一个指向堆指针 B-树的指针(倒排树), + 要么在列表足够小、能够连同键值一起放入单个索引元组时,直接包含一个简单的堆指针列表(倒排列表)。 @@ -346,7 +367,7 @@ - 如果一致的响应时间比更新速度更重要,可以通过关闭 GIN 索引的 + 如果稳定的响应时间比更新速度更重要,可以通过关闭 GIN 索引的 fastupdate 存储参数来禁用待处理列表机制。详见 @@ -382,7 +403,7 @@ 因此,对于向表中执行的批量插入,建议先删除 GIN 索引,待批量插入完成后再重建它。 - PostgreSQL 8.4 开始,由于采用了延迟索引,这项建议已不那么必要(详见)。但对于非常大的更新,最好仍然是删除并重建索引。 + PostgreSQL 8.4 开始,由于采用了延迟索引,这项建议已不那么必要(详见)。但对于非常大的更新,删除并重建索引仍然可能是最佳选择。 @@ -449,14 +470,19 @@ GIN 假定可索引操作符是严格的。这意味着,当项值为 null 时, 根本不会对其调用 extractValue(而是自动创建一个占位符索引项); 当查询值为 null 时,也不会调用 extractQuery(而是认为该查询不可满足)。 - 不过要注意,非空组合项或查询值内部包含的 null 键值仍然受支持。 + 不过要注意,非 null 的组合项或查询值内部包含的 null 键值仍然受支持。
示例 - PostgreSQL核心发行版包含GIN操作符类,见前文。以下contrib模块也包含GIN操作符类: + + PostgreSQL 核心发行版包含前面在 + 中展示过的 GIN 操作符类。 + 下列 contrib 模块也包含 GIN 操作符类: + + btree_gin diff --git a/zh/10/gist.sgml b/zh/10/gist.sgml index df3b6434..23317615 100644 --- a/zh/10/gist.sgml +++ b/zh/10/gist.sgml @@ -4,7 +4,7 @@ GiST 索引 - index + 索引 GiST @@ -45,7 +45,7 @@ 名称 - 索引数据类型 + 被索引数据类型 可索引操作符 排序操作符 @@ -127,7 +127,7 @@ CREATE INDEX ON my_table USING GIST (my_inet_column inet_ops); - 这种可扩展性不应与其他标准搜索树在可处理数据方面的可扩展性相混淆。例如,PostgreSQL支持可扩展的 B-树和哈希索引。这意味着你可以用PostgreSQL在任意数据类型上构建 B-树或哈希索引。但 B-树只支持范围谓词(<=>),而哈希索引只支持等值查询。 + 这种可扩展性不应与其他标准搜索树在可处理数据方面的可扩展性相混淆。例如,PostgreSQL支持可扩展的 B-树和 hash 索引。这意味着你可以用PostgreSQL在任意数据类型上构建 B-树或 hash 索引。但 B-树只支持范围谓词(<=>),而 hash 索引只支持等值查询。 @@ -151,12 +151,19 @@ CREATE INDEX ON my_table USING GIST (my_inet_column inet_ops); indexable_operator q为真。对于叶子索引项,这等同于测试该可索引条件;而对于内部树节点,这决定是否有必要扫描该树节点所表示的索引子树。当结果为true时,还必须返回一个recheck标志。它表示该谓词是确定为真,还是仅可能为真。如果recheck = false,则该索引已经精确测试了谓词条件;如果recheck = true,则该行只是候选匹配。在这种情况下,系统会自动针对实际行值计算indexable_operator,以判断它是否真的匹配。这种约定使GiST能够同时支持无损和有损的索引结构。 - SQL声明必须如下所示: + + 该函数的SQL声明必须如下所示: + + CREATE OR REPLACE FUNCTION my_consistent(internal, data_type, smallint, oid, internal) RETURNS bool AS 'MODULE_PATHNAME' LANGUAGE C STRICT; -C 模块中相应的代码可以采用以下框架: + + + 而 C 模块中的对应代码则可以遵循如下框架: + + PG_FUNCTION_INFO_V1(my_consistent); Datum @@ -171,19 +178,21 @@ my_consistent(PG_FUNCTION_ARGS) bool retval; /* - * determine return value as a function of strategy, key and query. + * 根据 strategy、key 和 query 确定返回值。 * - * Use GIST_LEAF(entry) to know where you're called in the index tree, - * which comes handy when supporting the = operator for example (you could - * check for non empty union() in non-leaf nodes and equality in leaf - * nodes). + * 使用 GIST_LEAF(entry) 判断当前调用位于索引树的哪个位置。 + * 例如,支持 = 操作符时这很有用(可以在非叶节点检查 + * union() 是否非空,在叶节点检查是否相等)。 */ - *recheck = true; /* or false if check is exact */ + *recheck = true; /* 如果检查是精确的,则为 false */ PG_RETURN_BOOL(retval); } -这里,key是索引中的元素,query是要在索引中查找的值。StrategyNumber参数指明正在应用操作符类中的哪个操作符,它对应于CREATE OPERATOR CLASS命令中的某个操作符编号。 + + + 这里,key是索引中的一个元素,而query是在该索引中查找的值。StrategyNumber参数指示应用的是操作符类中的哪个操作符,它对应于CREATE OPERATOR CLASS命令中的某个操作符编号。 + 取决于你在该类中包含了哪些操作符,query的数据类型可能会随操作符而变化,因为它将是操作符右侧的类型,而这可能不同于左侧出现的被索引数据类型。(上面的代码框架假定只可能有一种类型;如果不是这样,获取query参数值的方式就必须依赖于具体的操作符。)建议在consistent函数的 SQL 声明中,对query参数使用该操作符类的被索引数据类型,即使实际类型可能因为操作符不同而有所不同。 @@ -199,12 +208,19 @@ my_consistent(PG_FUNCTION_ARGS) 该方法用于汇总树中的信息。给定一组项,该函数生成一个新的索引项,用来表示所有给定项。 - SQL声明必须如下所示: + + 该函数的SQL声明必须如下所示: + + CREATE OR REPLACE FUNCTION my_union(internal, internal) RETURNS storage_type AS 'MODULE_PATHNAME' LANGUAGE C STRICT; -C 模块中相应的代码可以采用以下框架: + + + 而 C 模块中的对应代码则可以遵循如下框架: + + PG_FUNCTION_INFO_V1(my_union); Datum @@ -260,12 +276,19 @@ my_union(PG_FUNCTION_ARGS) 将一个数据项转换成适合在索引页中物理存储的格式。 - SQL声明必须如下所示: + + 该函数的SQL声明必须如下所示: + + CREATE OR REPLACE FUNCTION my_compress(internal) RETURNS internal AS 'MODULE_PATHNAME' LANGUAGE C STRICT; -C 模块中相应的代码可以采用以下框架: + + + 而 C 模块中的对应代码则可以遵循如下框架: + + PG_FUNCTION_INFO_V1(my_compress); Datum @@ -276,10 +299,10 @@ my_compress(PG_FUNCTION_ARGS) if (entry->leafkey) { - /* replace entry->key with a compressed version */ + /* 将 entry->key 替换为压缩后的形式 */ compressed_data_type *compressed_data = palloc(sizeof(compressed_data_type)); - /* fill *compressed_data from entry->key ... */ + /* 根据 entry->key 填充 *compressed_data ... */ retval = palloc(sizeof(GISTENTRY)); gistentryinit(*retval, PointerGetDatum(compressed_data), @@ -287,7 +310,7 @@ my_compress(PG_FUNCTION_ARGS) } else { - /* typically we needn't do anything with non-leaf entries */ + /* 通常无需对非叶项做任何处理 */ retval = entry; } @@ -331,12 +354,19 @@ my_decompress(PG_FUNCTION_ARGS) 返回一个值,指示把新项插入树中特定分支的代价。项会沿着树中penalty最小的路径插入。penalty返回的值应为非负;如果返回负值,它将被按零处理。 - SQL声明必须如下所示: + + 该函数的SQL声明必须如下所示: + + CREATE OR REPLACE FUNCTION my_penalty(internal, internal, internal) RETURNS internal AS 'MODULE_PATHNAME' -LANGUAGE C STRICT; -- in some cases penalty functions need not be strict -C 模块中相应的代码可以采用以下框架: +LANGUAGE C STRICT; -- 某些情况下 penalty 函数不必是严格函数 + + + 而 C 模块中的对应代码则可以遵循如下框架: + + PG_FUNCTION_INFO_V1(my_penalty); Datum @@ -351,7 +381,10 @@ my_penalty(PG_FUNCTION_ARGS) *penalty = my_penalty_implementation(orig, new); PG_RETURN_POINTER(penalty); } -由于历史原因,penalty函数不能仅仅返回一个float结果,而必须将该值存储到第三个参数指向的位置。函数自身的返回值会被忽略,但通常会返回该参数的地址。 + + + 出于历史原因,penalty函数并不是直接返回一个float结果;相反,它必须把该值存储到第三个参数指示的位置。返回值本身会被忽略,不过通常会返回该参数所指向的地址。 + penalty函数对于索引的良好性能至关重要。它会在插入时用于决定在树中应沿着哪个分支向下,以便选择把新项加到哪里。在查询时,索引越平衡,查找就越快。 @@ -366,12 +399,19 @@ my_penalty(PG_FUNCTION_ARGS) 当索引页必须分裂时,该函数决定页面上的哪些项留在旧页中,哪些移到新页中。 - SQL声明必须如下所示: + + 该函数的SQL声明必须如下所示: + + CREATE OR REPLACE FUNCTION my_picksplit(internal, internal) RETURNS internal AS 'MODULE_PATHNAME' LANGUAGE C STRICT; -C 模块中相应的代码可以采用以下框架: + + + 而 C 模块中的对应代码则可以遵循如下框架: + + PG_FUNCTION_INFO_V1(my_picksplit); Datum @@ -404,7 +444,7 @@ my_picksplit(PG_FUNCTION_ARGS) unionL = NULL; unionR = NULL; - /* Initialize the raw entry vector. */ + /* 初始化原始项向量。 */ raw_entryvec = (GISTENTRY **) malloc(entryvec->n * sizeof(void *)); for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) raw_entryvec[i] = &(entryvec->vector[i]); @@ -417,9 +457,9 @@ my_picksplit(PG_FUNCTION_ARGS) Assert(tmp_union != NULL); /* - * Choose where to put the index entries and update unionL and unionR - * accordingly. Append the entries to either v->spl_left or - * v->spl_right, and care about the counters. + * 选择索引项的存放位置,并相应更新 unionL 和 unionR。 + * 将项追加到 v->spl_left 或 v->spl_right, + * 同时更新计数器。 */ if (my_choice_is_left(unionL, curl, unionR, curr)) @@ -436,7 +476,7 @@ my_picksplit(PG_FUNCTION_ARGS) else { /* - * Same on the right + * 对右侧执行相同操作 */ } } @@ -445,7 +485,9 @@ my_picksplit(PG_FUNCTION_ARGS) v->spl_rdatum = DataTypeGetDatum(unionR); PG_RETURN_POINTER(v); } -注意,picksplit函数通过修改传入的v结构体来传递结果。函数自身的返回值会被忽略,但通常会返回以下结构体的地址:v。 + + + 注意,picksplit函数的结果是通过修改传入的v结构体来传递的。返回值本身会被忽略,不过通常会返回v的地址。 @@ -461,12 +503,19 @@ my_picksplit(PG_FUNCTION_ARGS) 如果两个索引项相同则返回真,否则返回假。(索引项是索引存储类型的值,不一定是原始被索引列的类型。) - SQL声明必须如下所示: + + 该函数的SQL声明必须如下所示: + + CREATE OR REPLACE FUNCTION my_same(storage_type, storage_type, internal) RETURNS internal AS 'MODULE_PATHNAME' LANGUAGE C STRICT; -C 模块中相应的代码可以采用以下框架: + + + 而 C 模块中的对应代码则可以遵循如下框架: + + PG_FUNCTION_INFO_V1(my_same); Datum @@ -479,7 +528,10 @@ my_same(PG_FUNCTION_ARGS) *result = my_eq(v1, v2); PG_RETURN_POINTER(result); } -由于历史原因,same函数不能仅仅返回布尔结果,而必须将该标志存储到第三个参数指向的位置。函数自身的返回值会被忽略,但通常会返回该参数的地址。 + + + 出于历史原因,same函数并不是直接返回一个布尔结果;相反,它必须把该标志存储到第三个参数指示的位置。返回值本身会被忽略,不过通常会返回该参数所指向的地址。 + @@ -490,12 +542,19 @@ my_same(PG_FUNCTION_ARGS) 给定一个索引项p和一个查询值q,该函数确定索引项与查询值之间的距离。如果操作符类包含任何排序操作符,就必须提供此函数。使用排序操作符的查询会优先返回距离值最小的索引项,因此结果必须与该操作符的语义一致。对于叶子索引项,结果仅表示到该索引项的距离;对于内部树节点,结果必须是其任意子项可能具有的最小距离。 - SQL声明必须如下所示: + + 该函数的SQL声明必须如下所示: + + CREATE OR REPLACE FUNCTION my_distance(internal, data_type, smallint, oid, internal) RETURNS float8 AS 'MODULE_PATHNAME' LANGUAGE C STRICT; -C 模块中相应的代码可以采用以下框架: + + + 而 C 模块中的对应代码则可以遵循如下框架: + + PG_FUNCTION_INFO_V1(my_distance); Datum @@ -510,19 +569,22 @@ my_distance(PG_FUNCTION_ARGS) double retval; /* - * determine return value as a function of strategy, key and query. + * 根据 strategy、key 和 query 确定返回值。 */ PG_RETURN_FLOAT8(retval); } -distance函数的参数与consistent函数的参数完全相同。 + + + distance函数的参数与consistent函数的参数完全相同。 + - 在确定距离时允许有一定近似,只要结果永不大于该项的实际距离即可。因此,例如在几何应用中,到外包盒的距离通常就足够了。对于内部树节点,返回的距离不能大于其任一子节点的距离。如果返回的距离不精确,函数必须将*recheck设为 true。(对内部树节点则不必这样做;对它们总是假定计算结果不精确。)在这种情况下,执行器会在从堆中取出元组后计算准确距离,并在必要时重新排序这些元组。 + 在确定距离时允许有一定近似,只要结果永不大于该项的实际距离即可。因此,例如在几何应用中,到包围盒的距离通常就足够了。对于内部树节点,返回的距离不能大于其任一子节点的距离。如果返回的距离不精确,函数必须将*recheck设为 true。(对内部树节点则不必这样做;对它们总是假定计算结果不精确。)在这种情况下,执行器会在从堆中取出元组后计算准确距离,并在必要时重新排序这些元组。 - 如果距离函数对任何叶节点都返回*recheck = true,原始排序操作符的返回类型必须是float8float4,且距离函数的结果值必须能与原始排序操作符的结果进行比较,因为执行器会同时使用距离函数结果和重新计算得到的排序操作符结果进行排序。否则,距离函数的结果值可以是任意有限的float8值,只要这些结果值的相对顺序与排序操作符返回的顺序一致即可。(无穷大和负无穷在内部用于处理空值等情况,因此不建议distance函数返回这些值。) + 如果距离函数对任意一个叶节点返回*recheck = true,原始排序操作符的返回类型必须是float8float4,且距离函数的结果值必须能与原始排序操作符的结果进行比较,因为执行器会同时使用距离函数结果和重新计算得到的排序操作符结果进行排序。否则,距离函数的结果值可以是任意有限的float8值,只要这些结果值的相对顺序与排序操作符返回的顺序一致即可。(无穷大和负无穷在内部用于处理空值等情况,因此不建议distance函数返回这些值。) @@ -560,10 +622,10 @@ my_fetch(PG_FUNCTION_ARGS) fetched_data = palloc(sizeof(fetched_data_type)); /* - * Convert 'fetched_data' into the a Datum of the original datatype. + * 将 'fetched_data' 转换为原始数据类型的 Datum。 */ - /* fill *retval from fetched_data. */ + /* 根据 fetched_data 填充 *retval。 */ gistentryinit(*retval, PointerGetDatum(converted_datum), entry->rel, entry->page, entry->offset, FALSE); @@ -607,7 +669,10 @@ my_fetch(PG_FUNCTION_ARGS) 示例 - PostgreSQL源码发行包包含若干使用GiST实现索引方法的示例。核心系统目前提供文本搜索支持(为tsvectortsquery建立索引),还为部分内置几何数据类型提供等价于 R 树的功能(参见src/backend/access/gist/gistproc.c)。以下contrib模块也包含GiST操作符类: + + PostgreSQL源代码发行包包含了若干使用GiST实现的索引方法示例。核心系统目前提供了文本搜索支持(为tsvectortsquery建立索引),并为某些内置几何数据类型提供了与 R 树等价的功能(见src/backend/access/gist/gistproc.c)。下列contrib模块中也包含GiST操作符类: + + btree_gist @@ -625,7 +690,7 @@ my_fetch(PG_FUNCTION_ARGS) hstore - 用于存储 (key, value) 对的模块 + 用于存储(键,值)对的模块 diff --git a/zh/10/hash.sgml b/zh/10/hash.sgml index 199395b2..81f5f878 100644 --- a/zh/10/hash.sgml +++ b/zh/10/hash.sgml @@ -1,11 +1,11 @@ -哈希索引 +Hash 索引 索引 - 哈希 + Hash @@ -13,51 +13,51 @@ PostgreSQL - 提供了持久化的磁盘哈希索引实现,并且完全支持崩溃恢复。任何数据类型都可以使用哈希索引,包括那些没有明确定义线性顺序的数据类型。哈希索引只存储被索引数据的哈希值,因此对被索引数据列的大小没有限制。 + 提供了持久化的磁盘 hash 索引实现,并且完全支持崩溃恢复。任何数据类型都可以使用 hash 索引,包括那些没有明确定义线性顺序的数据类型。Hash 索引只存储被索引数据的 hash 值,因此对被索引数据列的大小没有限制。 - 哈希索引仅支持单列索引,也不支持唯一性检查。 + Hash 索引仅支持单列索引,也不支持唯一性检查。 - 哈希索引仅支持=操作符,因此指定范围操作的 WHERE 子句无法利用哈希索引。 + Hash 索引仅支持=操作符,因此指定范围操作的 WHERE 子句无法利用 hash 索引。 - 每个哈希索引元组只存储 4 字节的哈希值,而不存储实际的列值。因此,在为 UUID、URL 等较长的数据项建立索引时,哈希索引可能比 B-树小得多。由于没有列值,所有哈希索引扫描也都是有损的。哈希索引可以参与位图索引扫描和反向扫描。 + 每个 hash 索引元组只存储 4 字节的 hash 值,而不存储实际的列值。因此,在为 UUID、URL 等较长的数据项建立索引时,hash 索引可能比 B-树小得多。由于没有列值,所有 hash 索引扫描也都是有损的。Hash 索引可以参与位图索引扫描和反向扫描。 - 哈希索引最适合于在较大表上执行等值扫描、且以 SELECT 和 UPDATE 为主的工作负载。在 B-树索引中,搜索必须沿树向下直到找到叶页。在拥有数百万行的表中,这种向下遍历会增加访问数据的时间。在哈希索引中,与叶页对应的页称为桶页。相比之下,哈希索引允许直接访问桶页,因此可能减少大表中的索引访问时间。这种“逻辑 I/O”的减少,在索引/数据大于 shared_buffers/RAM 时会更加明显。 + Hash 索引最适合于在较大表上执行等值扫描、且以 SELECT 和 UPDATE 为主的工作负载。在 B-树索引中,搜索必须沿树向下直到找到叶页。在拥有数百万行的表中,这种向下遍历会增加访问数据的时间。在 hash 索引中,与叶页对应的页称为桶页。相比之下,hash 索引允许直接访问桶页,因此可能减少大表中的索引访问时间。这种“逻辑 I/O”的减少,在索引/数据大于 shared_buffers/RAM 时会更加明显。 - 哈希索引在设计上能够应对哈希值分布不均的情况。如果哈希值分布均匀,那么直接访问桶页的效果很好。当插入导致桶页填满时,额外的溢出页就会链接到该特定桶页上,从而在局部扩展用于存放匹配该哈希值的索引元组的空间。查询期间扫描某个哈希桶时,需要遍历其全部溢出页。因此,对于某些数据,不平衡的哈希索引在所需块访问次数方面实际上可能比 B-树更差。 + Hash 索引在设计上能够应对 hash 值分布不均的情况。如果 hash 值分布均匀,那么直接访问桶页的效果很好。当插入导致桶页填满时,额外的溢出页就会链接到该特定桶页上,从而在局部扩展用于存放匹配该 hash 值的索引元组的空间。查询期间扫描某个 hash 桶时,需要遍历其全部溢出页。因此,对于某些数据,不平衡的 hash 索引在所需块访问次数方面实际上可能比 B-树更差。 - 由于会出现这些溢出情况,可以说哈希索引最适合用于唯一值、近乎唯一值,或者每个哈希桶中行数较少的数据。 + 由于会出现这些溢出情况,可以说 hash 索引最适合用于唯一值、近乎唯一值,或者每个 hash 桶中行数较少的数据。 避免问题的一种可能办法,是使用部分索引条件把高度非唯一的值排除在索引之外,但这在很多情况下可能并不适用。 - 与 B-树一样,哈希索引也会执行简单的索引元组删除。这是一种延迟维护操作,用于删除那些已知可以安全删除的索引元组(即其项标识符的 LP_DEAD 位已经被设置的那些元组)。如果插入操作发现页上没有可用空间,我们会尝试通过移除死索引元组来避免创建新的溢出页。如果该页当时已被钉住,就无法执行移除。死索引指针也会在 VACUUM 期间被删除。 + 与 B-树一样,hash 索引也会执行简单的索引元组删除。这是一种延迟维护操作,用于删除那些已知可以安全删除的索引元组(即其项标识符的 LP_DEAD 位已经被设置的那些元组)。如果插入操作发现页上没有可用空间,我们会尝试通过移除死索引元组来避免创建新的溢出页。如果该页当时已被钉住,就无法执行移除。死索引指针也会在 VACUUM 期间被删除。 - 如果可能,VACUUM 还会尝试将索引元组压缩到尽可能少的溢出页上,以最小化溢出链。 + 如果可能,VACUUM 还会尝试将索引元组集中存放在尽可能少的溢出页上,以最小化溢出链。 如果某个溢出页变为空页,该溢出页就可以被回收并在其他桶中重用,不过我们从不将它们返还给操作系统。 - 目前除了使用 REINDEX 重建哈希索引之外,还没有缩小哈希索引的方法。 + 目前除了使用 REINDEX 重建 hash 索引之外,还没有缩小 hash 索引的方法。 同样也没有减少桶数量的方法。 - 随着被索引行数的增长,哈希索引可能会扩展桶页数量。哈希键到桶号的映射经过选择,使得索引能够增量扩展。当需要向索引中添加一个新桶时,恰好只需要“拆分”一个现有桶,并根据更新后的键到桶号映射,将其中一部分元组转移到新桶。 + 随着被索引行数的增长,Hash 索引可能会扩展桶页数量。hash 键到桶号的映射经过选择,使得索引能够增量扩展。当需要向索引中添加一个新桶时,恰好只需要“拆分”一个现有桶,并根据更新后的键到桶号映射,将其中一部分元组转移到新桶。 - 这种扩展是在前台进行的,因此可能会增加用户插入操作的执行时间。因此,哈希索引可能不适合行数快速增长的表。 + 这种扩展是在前台进行的,因此可能会增加用户插入操作的执行时间。因此,hash 索引可能不适合行数快速增长的表。 @@ -66,7 +66,7 @@ 实现 - 哈希索引中有四种页:元页(第零页),其中包含静态分配的控制信息;主桶页;溢出页;以及位图页,后者用于跟踪已被释放且可供重用的溢出页。在寻址时,位图页被视为溢出页的一个子集。 + hash 索引中有四种页:元页(第零页),其中包含静态分配的控制信息;主桶页;溢出页;以及位图页,后者用于跟踪已被释放且可供重用的溢出页。在寻址时,位图页被视为溢出页的一个子集。 @@ -74,15 +74,15 @@ - 主桶页和溢出页是独立分配的,因为任何一个给定索引相对于其桶数,可能需要更多或更少的溢出页。哈希代码使用了一组颇有意思的寻址规则,以支持可变数量的溢出页,同时又不必在主桶页创建后再移动它们。 + 主桶页和溢出页是独立分配的,因为任何一个给定索引相对于其桶数,可能需要更多或更少的溢出页。hash 实现代码使用了一组颇有意思的寻址规则,以支持可变数量的溢出页,同时又不必在主桶页创建后再移动它们。 - 被索引表中的每一行,都由哈希索引中的单个索引元组表示。哈希索引元组存储在桶页中,如果存在溢出页,也会存储在溢出页中。为了加快搜索速度,我们将任一索引页中的索引项按哈希码排序,从而可以在索引页内使用二分查找。但请注意,并不假定同一桶中不同索引页之间的哈希码具有任何相对顺序。 + 被索引表中的每一行,都由 hash 索引中的单个索引元组表示。Hash 索引元组存储在桶页中,如果存在溢出页,也会存储在溢出页中。为了加快搜索速度,我们将任一索引页中的索引项按 hash 码排序,从而可以在索引页内使用二分查找。但请注意,并不假定同一桶中不同索引页之间的 hash 码具有任何相对顺序。 - 用于扩展哈希索引的桶拆分算法过于复杂,这里不再展开说明;但在src/backend/access/hash/README中有更详细的描述。该拆分算法具备崩溃安全性,如果未能成功完成,可以重新启动。 + 用于扩展 hash 索引的桶拆分算法过于复杂,这里不再展开说明;但在src/backend/access/hash/README中有更详细的描述。该拆分算法具备崩溃安全性,如果未能成功完成,可以重新启动。 diff --git a/zh/10/high-availability.sgml b/zh/10/high-availability.sgml index 9ee55485..7c8ad58f 100644 --- a/zh/10/high-availability.sgml +++ b/zh/10/high-availability.sgml @@ -253,7 +253,7 @@ protocol to make nodes agree on a serializable transactional order. - 主库失效绝不会丢失数据 + 主库失效时绝不丢失数据 启用同步时 @@ -341,7 +341,7 @@ protocol to make nodes agree on a serializable transactional order. - 连续归档可用于创建一种高可用性(HA)集簇配置,其中有一个或多个备库随时准备在主库失效时接管操作。这种能力通常称为温备日志传送。 + 持续归档可用于创建一种高可用性(HA)集簇配置,其中有一个或多个备库随时准备在主库失效时接管操作。这种能力通常称为温备日志传送 @@ -441,7 +441,7 @@ protocol to make nodes agree on a serializable transactional order. 如果使用 WAL 归档,可以借助 参数删除备库不再需要的文件,以尽量缩小归档大小。pg_archivecleanup 工具专门设计用于在典型的单备库配置中与 archive_cleanup_command 配合使用,见 。不过请注意,如果你还把归档用于备份目的,即使这些文件对备库已经不再需要,也必须至少保留从最新基础备份恢复所需的那些文件。 + linkend="archive-cleanup-command"> 参数删除备库不再需要的文件,以尽量缩小归档大小。pg_archivecleanup 工具专门设计用于在典型的单备库配置中与 archive_cleanup_command 配合使用,见 。不过请注意,如果你还把归档用于备份目的,即使这些文件对备库已经不再需要,也必须至少保留从最新基础备份恢复所需的那些文件。 一个简单的 recovery.conf 示例如下: @@ -473,7 +473,9 @@ archive_cleanup_command = 'pg_archivecleanup /path/to/archive %r' 默认情况下流复制是异步的(见 ),在这种情况下主库上提交一个事务与该变化在备库上变得可见之间存在短暂的延迟。不过这种延迟比基于文件的日志传送方式中要小得多,在备库的能力足以跟得上负载的前提下,延迟通常低于一秒。在流复制中,不需要 archive_timeout 来缩减数据丢失窗口。 - 如果使用流复制却未使用基于文件的连续归档,服务器可能在备库收到旧 WAL 段之前就将其回收。如果发生这种情况,备库需要从新的基础备份重新初始化。可以将 wal_keep_segments 设得足够大,确保 WAL 段不会过早回收,或者为备库配置复制槽,以避免这种情况。如果配置了备库可以访问的 WAL 归档,则不需要这些办法,因为只要归档保留了足够的段,备库就始终可以借助归档追赶主库。 + + 如果你使用流复制,但没有启用基于文件的持续归档,服务器可能会在备库收到旧的 WAL 段之前就把它们回收掉。如果发生这种情况,备库就需要重新通过新的基础备份进行初始化。可以通过把 wal_keep_segments 设置得足够大,以确保 WAL 段不会过早被回收,或者为备库配置一个复制槽,从而避免这种情况。如果配置了一个备库可访问的 WAL 归档,就不需要这些方案,因为只要归档保留了足够多的段,备库始终可以利用归档追赶上来。 + 要使用流复制,请先按 所述配置基于文件的日志传送备库。将这种备库转为流复制备库的关键步骤,是在 recovery.conf 文件中设置 primary_conninfo,使其指向主库。在主库上设置 和认证选项(参见 pg_hba.conf),使备库能够连接主库的 replication 伪数据库(参见 )。 @@ -485,13 +487,16 @@ archive_cleanup_command = 'pg_archivecleanup /path/to/archive %r' 设置来自备库的最大并发连接数(详见 )。 - 备库启动后,如果正确设置了 primary_conninfo,备库会在重放归档中所有可用的 WAL 文件后连接主库。如果连接成功,就会在备库上看到 WAL 接收进程,在主库上看到对应的 WAL 发送进程。 + 备库启动后,如果正确设置了 primary_conninfo,备库会在重放归档中所有可用的 WAL 文件后连接主库。如果连接成功,就会在备库上看到 walreceiver 进程,在主库上看到对应的 walsender 进程。 认证 - 务必正确设置复制访问权限,使只有受信任的用户才能读取 WAL 流,因为很容易从中提取特权信息。备库必须以超级用户或具有 REPLICATION 权限的账户向主库认证。建议为复制创建专用用户账户,并授予 REPLICATIONLOGIN 权限。虽然 REPLICATION 权限赋予的权限很高,但它不允许用户修改主库系统上的任何数据,而 SUPERUSER 权限允许这样做。 + 务必正确设置复制访问权限,使只有受信任的用户才能读取 WAL 流,因为很容易从中提取需要权限才能访问的信息。备库必须以超级用户或具有 REPLICATION 权限的账户向主库认证。建议为复制创建专用用户账户,并授予 REPLICATIONLOGIN 权限。虽然 REPLICATION 权限赋予的权限很高,但它不允许用户修改主库系统上的任何数据,而 SUPERUSER 权限允许这样做。 + + + 复制的客户端认证由 pg_hba.conf 中的一条记录控制,该记录需要把 replication 指定在 database 字段中。例如,如果备库运行在主机 IP 192.168.1.100 上,并且用于复制的账户名为 foo,管理员可以在主库上的 pg_hba.conf 文件中加入下列行: - 复制的客户端认证由 pg_hba.conf 中的记录控制。记录要将 replication 指定为 database 字段的值。例如,如果备库所在主机的 IP 地址为 192.168.1.100,用于复制的账户名为 foo,管理员可以将以下行添加到 pg_hba.conf 文件(位于主库)中: + # Allow the user "foo" from host 192.168.1.100 to connect to the primary # as a replication standby if the user's password is correctly supplied. # @@ -512,7 +517,7 @@ primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass' 流复制的一个重要健康指标,是主库上已经生成但尚未在备库上应用的 WAL 记录量。你可以通过比较主库上的当前 WAL 写入位置和备库收到的最后一个 WAL 位置来计算这种滞后。这些位置分别可以用主库上的 pg_current_wal_lsn 和备库上的 pg_last_wal_receive_lsn 取得(详见 )。备库上的最后一个 WAL 接收位置也会显示在 WAL 接收进程的进程状态中,即通过 ps 命令显示的状态(详见 )。 - 可以通过 pg_stat_replication 视图获取 WAL 发送进程列表。pg_current_wal_lsn 与该视图的 sent_lsn 字段相差较大,可能表示主库负载很高;而 sent_lsn 与备库上 pg_last_wal_receive_lsn 的差值较大,则可能表示网络延迟或备库负载很高。 + 可以通过 pg_stat_replication 视图获取 WAL 发送进程列表。pg_current_wal_lsn 与该视图的 sent_lsn 字段相差较大,可能表示主库负载很高;而 sent_lsn 与备库上 pg_last_wal_receive_lsn 之间存在差异,则可能表示网络延迟或备库负载很高。
@@ -523,12 +528,12 @@ primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass' 流复制 - 复制槽提供了一种自动化方法,以确保主库在所有备库都收到 WAL 段之前不会删除它们,并且即使备库处于断开状态,主库也不会删除可能导致恢复冲突的行。 + 复制槽提供了一种自动化方法,以确保主库在所有备库都收到 WAL 段之前不会删除它们,并且即使备库处于断开状态,主库也不会删除那些一旦删除就可能导致恢复冲突的行。 除了使用复制槽,也可以通过 防止旧 WAL 段被删除,或者使用 将这些段保存在归档中。不过,这些方法通常会保留多于实际所需的 WAL 段,而复制槽只保留已知必需的段数。这些方法的优点是能限制 pg_wal 的空间需求;目前使用复制槽还无法做到这一点。 类似地, 可以保护相关行,避免它们被清理删除,但前者在备库未连接期间无法提供保护,后者则通常需要设为较大的值才能提供充分保护。复制槽克服了这些缺点。 - 查询和操作复制槽 + 查询和管理复制槽 每个复制槽都有一个名称,该名称可以包含小写字母、数字和下划线字符。 @@ -574,7 +579,9 @@ primary_slot_name = 'node_a_slot' 级联复制特性允许一台备库接受复制连接,并像中继器一样把 WAL 记录流式发送给其他备库。这可以用来减少直接连接到主库的连接数,并使站点间的带宽开销最小化。 - 同时充当接收方和发送方的备库称为级联备库。与主库连接更直接的备库称为上游服务器,距离更远的备库则称为下游服务器。级联复制不限制下游服务器的数量或组织方式,不过每个备库只连接一个上游服务器,并最终连接到同一个主库。 + + 一台同时扮演接收者和发送者角色的备库称为级联备库。与主库连接更直接(经过更少级联备库)的备库称为上游服务器,而距离更远的备库称为下游服务器。级联复制并不限制下游服务器的数量和拓扑,不过每台备库只连接到一台上游服务器,而这条链路最终都会通向同一台主库。 + 级联备库不仅发送从主库接收到的 WAL 记录,也会发送那些从归档中恢复的记录。因此,即使某条上游复制连接被中断,只要仍有新的 WAL 记录可用,下游的流复制就会继续。 @@ -614,7 +621,9 @@ primary_slot_name = 'node_a_slot' 请求同步复制时,每个写事务的提交都会等待,直到收到确认,表明该提交已被写入主库和备库磁盘上的预写式日志。数据唯一可能丢失的情况,是主库和备库同时崩溃。这可以提供更高的持久性级别,不过前提是系统管理员必须谨慎地部署和管理这两台服务器。等待确认会增强用户对服务器崩溃时更改不会丢失的信心,但也必然会增加请求事务的响应时间。最短等待时间是主库与备库之间的往返时间。 - 只读事务和事务回滚无需等待备库回复。子事务提交也不等待备库响应,只有顶层提交才会等待。数据加载或索引构建等长时间运行的操作,直到最后的提交消息才会等待。所有两阶段提交操作都需要等待提交,包括准备和提交两个阶段。 + + 只读事务和事务回滚不需要等待备库的回应。子事务提交也不需要等待备库响应,只有顶层提交才需要等待。数据装载或索引构建等长时间运行的动作,直到最终提交时才会等待。所有两阶段提交操作都需要等待提交,包括准备和提交两个阶段。 + 同步备库可以是物理复制备库,也可以是逻辑复制订阅者。它还可以是任何其他物理或逻辑 WAL 复制流的消费者,只要它知道如何发送适当的反馈消息。除了内置的物理和逻辑复制系统之外,还包括pg_receivewalpg_recvlogical之类的专用程序,以及一些第三方复制系统和定制程序。关于同步复制支持的细节,请查看相应文档。 @@ -624,11 +633,11 @@ primary_slot_name = 'node_a_slot' 基本配置 - 一旦流复制已经配置好,配置同步复制只需要额外一步:必须把设置为非空值。synchronous_commit也必须设置为on,但由于这是默认值,通常无需更改(见)。这样的配置会导致每次提交都等待确认,以保证备库已经把提交记录写入持久存储。synchronous_commit可以由单个用户设置,因此既可以在配置文件中配置,也可以针对特定用户或数据库配置,或者由应用动态配置,从而在每事务级别控制持久性保证。 + 一旦流复制已经配置好,配置同步复制只需要额外一步:必须把设置为非空值。synchronous_commit也必须设置为on,但由于这是默认值,通常无需更改(见)。这样的配置会导致每次提交都等待确认,以保证备库已经把提交记录写入持久存储。synchronous_commit可以由单个用户设置,因此既可以在配置文件中配置,也可以针对特定用户或数据库配置,或者由应用动态配置,从而在每事务级别控制持久性保证。 - 当提交记录已经在主库上写入磁盘之后,WAL 记录就会被发送到备库。每当新的一批 WAL 数据被写入磁盘时,备库就会发送回复消息,除非备库上的wal_receiver_status_interval被设置为零。如果synchronous_commit被设置为remote_apply,那么备库会在提交记录被重放时发送回复消息,从而使该事务变得可见。如果根据主库上的synchronous_standby_names设置,该备库被选为同步备库,那么它发出的回复会与其他同步备库的回复一起,用于决定何时释放那些正在等待确认提交记录已被收到的事务。这些参数允许管理员指定哪些备库应作为同步备库。注意,同步复制的配置主要在主库上进行。被命名的备库必须直接连接到主库;主库并不知道使用级联复制的下游备库。 + 当提交记录已经在主库上写入磁盘之后,WAL 记录就会被发送到备库。每当新的一批 WAL 数据被写入磁盘时,备库就会发送回复消息,除非备库上的wal_receiver_status_interval被设置为零。如果synchronous_commit被设置为remote_apply,那么备库会在提交记录被重放、该事务变得可见时发送回复消息。如果根据主库上的synchronous_standby_names设置,该备库被选为同步备库,那么它发出的回复会与其他同步备库的回复一起,用于决定何时释放那些正在等待确认提交记录已被收到的事务。这些参数允许管理员指定哪些备库应作为同步备库。注意,同步复制的配置主要在主库上进行。被命名的备库必须直接连接到主库;主库并不知道使用级联复制的下游备库。 @@ -640,7 +649,7 @@ primary_slot_name = 'node_a_slot' - 如果请求快速关闭,用户将停止等待。不过,与使用异步复制时一样,在所有尚未解决的 WAL 记录传输到当前已连接的备库之前,服务器不会完全关闭。 + 如果请求快速关闭,用户将停止等待。不过,与使用异步复制时一样,在所有尚未传送的 WAL 记录传输到当前已连接的备库之前,服务器不会完全关闭。 @@ -662,14 +671,14 @@ synchronous_standby_names = 'FIRST 2 (s1, s2, s3)' 在这个例子中,如果四台备库s1s2s3s4都在运行,则s1s2会被选为同步备库,因为它们的名字在备库名称列表中出现得更早。s3是潜在的同步备库,当s1s2中的任意一台失效时,它就会接替其角色。由于s4的名称不在列表中,因此它是异步备库。 - ANY方法指定基于法定人数的同步复制,使事务提交等待,直到它们的 WAL 记录被复制到列表中所要求数量的同步备库中的至少这么多台。 + ANY方法指定基于法定人数的同步复制,使事务提交等待,直到它们的 WAL 记录被复制到列表中至少所要求数量的同步备库。 基于法定人数的多同步备库的synchronous_standby_names示例如下: synchronous_standby_names = 'ANY 2 (s1, s2, s3)' - 在这个例子中,如果四台备库s1s2s3s4都在运行,事务提交将等待来自s1s2s3中的任意两台备库的回复。由于s4的名字不在列表中,因此它是异步备库。 + 在这个例子中,如果四台备库s1s2s3s4都在运行,事务提交将等待来自s1s2s3中的至少任意两台备库的回复。由于s4的名字不在列表中,因此它是异步备库。 备库的同步状态可以通过pg_stat_replication视图查看。 @@ -692,7 +701,7 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' - 通过在应用级别(在主库上)指定同步复制选项,我们可以只对最重要的变更提供同步复制,而不会拖慢整体工作负载。应用级别选项是让高性能应用获得同步复制收益的一种重要而实用的工具。 + 通过在应用级别(在主库上)指定同步复制选项,我们可以只对最重要的变更提供同步复制,而不会拖慢大部分工作负载。应用级别选项是让高性能应用获得同步复制收益的一种重要而实用的工具。 @@ -704,7 +713,9 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' 高可用规划 - synchronous_standby_names 指定同步备库的数量和名称。当 synchronous_commit 设为 onremote_applyremote_write 时,事务提交会等待这些备库响应。如果其中任何一个同步备库崩溃,这些事务提交就可能永远无法完成。 + + synchronous_standby_names指定了当synchronous_commit设置为onremote_applyremote_write时,事务提交需要等待其响应的同步备库的数量和名称。如果任意一台同步备库崩溃,此类事务提交就可能永远无法完成。 + 对于高可用而言,最好的办法是确保你始终保有所要求数量的同步备库。这可以通过在synchronous_standby_names中命名多个潜在同步备库来实现。 @@ -722,7 +733,9 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' 当一台备库第一次连接到主库时,它还没有正确同步。这种状态称为catchup模式。一旦备库与主库之间的滞后第一次变为零,它就会进入实时的streaming状态。备库刚创建之后,追赶阶段可能会持续较长时间。如果备库被关闭,则追赶阶段会随着它停机时间的延长而变长。只有在到达streaming状态后,备库才能成为同步备库。这种状态可以通过pg_stat_replication视图查看。 - 如果主库在提交等待确认期间重启,那么主库数据库恢复后,这些等待中的事务就会被标记为完全提交。无法确定在主库崩溃时,所有备库是否已收到所有尚未确认的 WAL 数据。某些事务即使在主库上显示为已提交,在备库上也可能未显示为已提交。我们提供的保证是:只有确定 WAL 数据已由所有同步备库安全接收,应用才会收到事务成功提交的明确确认。 + + 如果主库在提交正等待确认时重启,这些等待中的事务会在主库恢复后被标记为已完全提交。无法确定在主库崩溃时,所有备库是否已经收到全部待传送的 WAL 数据。因此,某些事务可能不会在备库上显示为已提交,即使它们在主库上显示为已提交。我们所提供的保证是:只有在确认 WAL 数据已经被所有同步备库安全接收之后,应用才会收到事务成功提交的显式确认。 + 如果你确实无法维持所要求数量的同步备库,那么就应当在synchronous_standby_names中减少事务提交需要等待其响应的同步备库数量(或者禁用它),然后在主库上重新加载配置文件。 @@ -738,7 +751,7 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' - 备库上的连续归档 + 在备库中持续归档 持续归档 @@ -779,7 +792,7 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' - 一旦故障切换到备库,系统中就只剩下一台服务器在运行。这被称为退化状态。原来的备库现在成为主库,而原来的主库已经停机,并且可能持续停机。要恢复到正常运行状态,就必须重新创建一台备库:要么在原主库恢复后在其上重建,要么在第三台可能是全新的服务器上重建。在大型集簇上,可以使用工具来加快这一过程。一旦完成,就可以认为主库和备库已经交换了角色。有些人会选择使用第三台服务器,在新的备库重建完成之前为新的主库提供备份,但显然这会让系统配置和操作流程更加复杂。 + 一旦故障切换到备库,系统中就只剩下一台服务器在运行。这被称为退化状态。原来的备库现在成为主库,而原来的主库已经停机,并且可能持续停机。要恢复到正常运行状态,就必须重新创建一台备库:要么在原主库恢复后在其上重建,要么在第三台可能是全新的服务器上重建。在大型集簇上,可以使用工具来加快这一过程。一旦完成,就可以认为主库和备库已经交换了角色。有些人会选择使用第三台服务器,在新的备库重建完成之前为新的主库提供后备支持,但显然这会让系统配置和操作流程更加复杂。 @@ -796,7 +809,7 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' 注意,在这种模式下,服务器每次应用一整个 WAL 文件。因此,如果使用备库处理查询(参见热备),主库上的操作与备库上能看到该操作的结果之间,会有一段延迟,其长度相当于写满一个 WAL 文件所需的时间。可以用 archive_timeout 缩短这一延迟。还要注意,这种方法不能与流复制结合使用。 - 主库和备库上执行的操作都是普通的连续归档和恢复任务。两台数据库服务器之间唯一的联系,就是它们共享的 WAL 文件归档:主库写入归档,备库从归档读取。必须确保不同主库的 WAL 归档不会混在一起或弄错。如果归档仅用于备库运行,则无需保留很大的归档。 + 主库和备库上执行的操作都是普通的持续归档和恢复任务。两台数据库服务器之间唯一的联系,就是它们共享的 WAL 文件归档:主库写入归档,备库从归档读取。必须确保不同主库的 WAL 归档不会混在一起或弄错。如果归档仅用于备库运行,则无需保留很大的归档。 让这两台松散耦合的服务器协同工作的关键,只是备库上的 restore_command:当请求下一个 WAL 文件时,它会等待主库提供该文件。restore_command 在备库的 recovery.conf 文件中指定。正常恢复处理会从 WAL 归档请求文件,如果文件不可用,就报告失败。对备库处理而言,下一个 WAL 文件尚不可用是正常情况,因此备库必须等待它出现。对于以 .history 结尾的文件,则无需等待,必须返回非零返回码。可以编写一个自定义脚本,循环检查下一个 WAL 文件是否存在,从而实现会等待的 restore_command。还必须提供触发故障切换的方法,用来中断 restore_command、跳出循环,并向备库返回文件未找到错误。这会结束恢复,随后备库就会作为普通服务器启动。 @@ -825,7 +838,7 @@ if (!triggered) 尽可能将主库和备库系统配置得相同,包括安装两个完全相同、发行版本一致的 PostgreSQL 副本。 - 配置连续归档,将主库的 WAL 归档到备库上的一个目录。确保在主库上正确设置 (参见 )。 + 配置持续归档,将主库的 WAL 归档到备库上的一个目录。确保在主库上正确设置 (参见 )。 制作主库的基础备份(参见 ),并将这些数据装载到备库上。 @@ -871,25 +884,34 @@ if (!triggered) 用户概览 - 当备库上的参数被设置为真时,一旦恢复把系统带到一致状态并为热备做好准备,它就会开始接受连接。所有这类连接都严格是只读的,甚至不能写入临时表。 + 当备库上的参数被设置为真时,一旦恢复把系统带到一致状态,它就会开始接受连接。所有这类连接都严格是只读的,甚至不能写入临时表。 备库上的数据需要一些时间才能从主库到达,因此主库和备库之间会有可测量的延迟。因此,在主库和备库上几乎同时运行同一查询,可能会返回不同的结果。我们说备库上的数据与主库是最终一致的。一旦某个事务的提交记录在备库上被重放,该事务所做的修改就会对备库上之后取得的所有新快照可见。快照可以在每个查询开始时取得,也可以在每个事务开始时取得,这取决于当前的事务隔离级别。详见 - 热备期间启动的事务可以执行以下命令: + + 在热备期间启动的事务可以发出下列命令: + + - 查询访问 - SELECTCOPY TO + + 查询访问:SELECTCOPY TO + - 游标命令 - DECLAREFETCHCLOSE + + 游标命令:DECLAREFETCHCLOSE + - 参数 - SHOWSETRESET + 参数:SHOWSETRESET - 事务管理命令 + + 事务管理命令: + BEGINENDABORTSTART TRANSACTION @@ -902,7 +924,7 @@ if (!triggered) - EXCEPTION块或其他内部子事务 + EXCEPTION块和其他内部子事务 @@ -915,10 +937,15 @@ if (!triggered) - 计划和资源 - PREPAREEXECUTEDEALLOCATEDISCARD + + 计划和资源:PREPAREEXECUTE、 + DEALLOCATEDISCARD + - 插件和扩展 - LOAD + + 插件和扩展:LOAD + @@ -928,12 +955,23 @@ if (!triggered) - 热备期间启动的事务不会被分配事务 ID,也不能写入系统的预写式日志。因此,以下操作会产生错误消息: + + 在热备期间启动的事务永远不会被分配事务 ID,也不能写入系统预写式日志。因此,下列动作都会产生错误消息: + + - 数据操纵语言(DML)- INSERTUPDATEDELETECOPY FROMTRUNCATE。注意,恢复期间不允许任何会导致触发器执行的操作。这一限制也适用于临时表,因为不分配事务 ID 就无法读写表中的行,而目前热备环境中无法分配事务 ID。 + + 数据操纵语言(DML):INSERT、 + UPDATEDELETE、 + COPY FROM、 + TRUNCATE。请注意,恢复期间不存在任何允许执行触发器的动作。这个限制甚至适用于临时表,因为不分配事务 ID 就无法读取或写入表行,而目前热备环境中无法分配事务 ID。 + - 数据定义语言(DDL)- CREATEDROPALTERCOMMENT。这一限制也适用于临时表,因为执行这些操作需要更新系统目录表。 + + 数据定义语言(DDL):CREATE、 + DROPALTERCOMMENT。这个限制甚至适用于临时表,因为执行这些操作需要更新系统目录表。 + @@ -961,13 +999,13 @@ if (!triggered) - BEGIN READ WRITE, + BEGIN READ WRITESTART TRANSACTION READ WRITE - SET TRANSACTION READ WRITE, + SET TRANSACTION READ WRITESET SESSION CHARACTERISTICS AS TRANSACTION READ WRITE @@ -980,10 +1018,16 @@ if (!triggered) - 两阶段提交命令 - PREPARE TRANSACTIONCOMMIT PREPAREDROLLBACK PREPARED,因为即使只读事务也需要在准备阶段(两阶段提交的第一阶段)写入 WAL。 + + 两阶段提交命令:PREPARE TRANSACTION、 + COMMIT PREPAREDROLLBACK PREPARED, + 因为即使是只读事务,在准备阶段(两阶段提交的第一阶段)也需要写入 WAL。 + - 序列更新 - nextval()setval() + + 序列更新:nextval()setval() + @@ -1061,19 +1105,17 @@ if (!triggered) - 一旦max_standby_archive_delaymax_standby_streaming_delay指定的延迟被超越,冲突查询将被取消。这通常仅导致一个取消错误,尽管在重放一个DROP DATABASE的情况下整个冲突会话都将被中断。另外,如果冲突发生在一个被空闲事务持有的锁上,该冲突会话会被中断(这种行为可能在未来被改变)。 + 一旦max_standby_archive_delaymax_standby_streaming_delay指定的延迟被超越,冲突查询将被取消。这通常仅导致一个取消错误,尽管在重放一个DROP DATABASE的情况下整个冲突会话都将被终止。另外,如果冲突发生在一个被空闲事务持有的锁上,该冲突会话会被终止(这种行为可能在未来被改变)。 - - 被取消的查询可能会立即被重试(当然是在开始一个新的事务后)。因为查询取消依赖于 WAL 记录被重放的本质,如果一个被取消的查询被再次执行,它可能会很好地成功完成。 - + 被取消的查询可以立即重试(当然,要先开始一个新事务)。由于查询取消取决于正在重放的 WAL 记录的性质,被取消的查询再次执行时完全可能成功。 - 记住延迟参数是从 WAL 数据被备库收到后流逝的时间。因此,留给备库上任何一个查询的宽限期从不会超过延迟参数,并且如果备库已经由于等待之前的查询完成而落后或者因为过重的更新负载而无法跟上主库,宽限期可能会更少。 + 请记住,延迟参数要与备库收到 WAL 数据之后经过的时间进行比较。因此,留给备库上任何一个查询的宽限期从不会超过延迟参数,并且如果备库已经由于等待之前的查询完成而落后或者因为过重的更新负载而无法跟上主库,宽限期可能会更少。 - 备库查询与 WAL 重放发生冲突的最常见原因是过早清理。正常情况下,当没有事务需要看到旧行版本时,PostgreSQL允许清理这些旧行版本,以保证按照 MVCC 规则得到正确的数据可见性。不过,这条规则只能应用于在主库上执行的事务。因此,主库上的清理有可能移除某个备库事务仍然可见的行版本。 + 备库查询与 WAL 重放发生冲突的最常见原因是过早清理。正常情况下,当不再有事务需要看到旧行版本来保证符合 MVCC 规则的数据可见性时,PostgreSQL允许清理这些旧行版本。不过,这条规则只能应用于在主库上执行的事务。因此,主库上的清理有可能移除某个备库事务仍然可见的行版本。 有经验的用户应注意,行版本清理和行版本冻结都有可能与备库查询冲突。手动运行 VACUUM FREEZE 很可能导致冲突,即使表中没有更新过或删除过的行也是如此。 @@ -1146,18 +1188,29 @@ LOG: database system is ready to accept read only connections - 主库上写出的事务状态 "hint bits" 不会被 WAL 记录,因此备库上的数据很可能会再次写出这些提示位。这样一来,即使所有用户都是只读的,备库仍然会执行磁盘写操作;不过数据值本身并不会发生变化。用户仍然会写出大型排序临时文件,并重新生成 relcache 信息文件,因此在热备模式下,数据库没有任何部分是真正只读的。还要注意,使用dblink模块写入远程数据库,以及借助 PL 函数执行其他数据库外部操作,依然是可能的,即使该事务在本地是只读的。 + 主库上写出的事务状态“提示位” 不会被 WAL 记录,因此备库上的数据很可能会再次写出这些提示位。这样一来,即使所有用户都是只读的,备库仍然会执行磁盘写操作;不过数据值本身并不会发生变化。用户仍然会写出大型排序临时文件,并重新生成 relcache 信息文件,因此在热备模式下,数据库没有任何部分是真正只读的。还要注意,使用dblink模块写入远程数据库,以及借助 PL 函数执行其他数据库外部操作,依然是可能的,即使该事务在本地是只读的。 - 恢复模式下不接受以下类型的管理命令: + + 在恢复模式下,不接受下列类型的管理命令: + + - 数据定义语言(DDL)- 例如 CREATE INDEX + + 数据定义语言(DDL):例如 CREATE INDEX + - 权限和所有权 - GRANTREVOKEREASSIGN + + 权限和所有权:GRANTREVOKE、 + REASSIGN + - 维护命令 - ANALYZEVACUUMCLUSTERREINDEX + + 维护命令:ANALYZEVACUUM、 + CLUSTERREINDEX + @@ -1202,7 +1255,9 @@ LOG: database system is ready to accept read only connections 不能分配新的 OID,不过某些UUID生成器仍可工作,只要它们不依赖于向数据库写入新的状态。 - 目前,不允许在只读事务中创建临时表,因此现有脚本在某些情况下无法正确运行。未来版本可能会放宽这一限制。这既涉及 SQL 标准兼容性,也涉及技术问题。 + + 目前,在只读事务期间不允许创建临时表,因此某些现有脚本在这种情况下将无法正常运行。这个限制可能会在未来版本中放宽。这既涉及 SQL 标准兼容性问题,也涉及技术问题。 + 只有在表空间为空时DROP TABLESPACE才能成功。某些备库用户可能正在通过他们的temp_tablespaces参数使用该表空间。如果该表空间中存在临时文件,所有活动查询都将被取消,以确保临时文件被移除,这样该表空间才能被移除并且 WAL 重放可以继续。 @@ -1212,7 +1267,9 @@ LOG: database system is ready to accept read only connections 在主库上执行DROP DATABASEALTER DATABASE ... SET TABLESPACE会生成一条 WAL 记录,从而强制断开备库上所有连接到该数据库的用户。这个动作会立即发生,而不受max_standby_streaming_delay设置的影响。注意,ALTER DATABASE ... RENAME不会断开用户,这在大多数情况下不会被注意到,但如果程序依赖某种基于数据库名的机制,在某些情况下可能会导致混乱。 - 在正常(非恢复)模式下,如果对具有登录能力的角色执行 DROP USERDROP ROLE,而该用户仍处于连接状态,已连接的用户不会受到影响,会继续保持连接。不过,该用户无法重新连接。恢复期间也是如此,因此,在主库上执行 DROP USER 不会断开该用户在备库上的连接。 + + 在普通(非恢复)模式下,如果你对一个具有登录能力的角色执行DROP USERDROP ROLE,而该用户仍然处于连接状态,那么已连接用户不会发生任何变化 — 他们会继续保持连接,不过之后不能重新连接。这种行为在恢复期间同样适用,因此在主库上执行一次DROP USER并不会断开备库上的该用户连接。 + 统计收集器在恢复期间保持活动状态。所有扫描、读取、块、索引使用情况等,都会在备库上正常记录。重放操作不会重复记录其在主库上产生的统计影响,因此重放一次插入不会增加 pg_stat_user_tables 的 Inserts 列。统计文件会在恢复开始时被删除,因此主库和备库的统计信息不同;这是特性,不是缺陷。 @@ -1240,9 +1297,15 @@ LOG: database system is ready to accept read only connections 注意事项 - 热备有几个限制。这些限制能够、也很可能会在未来版本中消除: + + 热备有若干限制。 + 这些限制在未来的版本中可以、也很可能会被修复: + + - 必须完整掌握正在运行的事务,才能取得快照。如果事务使用了大量子事务(目前为超过 64 个),只读连接的开始时间就会延迟,直到运行时间最长的写事务完成。发生这种情况时,服务器日志中会记录说明消息。 + + 在能够取得快照之前,必须完整了解正在运行的事务。使用大量子事务(目前超过 64 个)的事务,会把只读连接的启动推迟到持续时间最长的写事务完成之后。如果发生这种情况,服务器日志中会发送解释性消息。 + diff --git a/zh/10/history.sgml b/zh/10/history.sgml index c2388a1d..e2d0c195 100644 --- a/zh/10/history.sgml +++ b/zh/10/history.sgml @@ -153,6 +153,8 @@ 不过各个方面的工作仍在继续。 - 关于此后PostgreSQL发生了哪些变化的详情,可在中查阅。 + + 自那以后 PostgreSQL 发生了哪些变化,可见 。 + diff --git a/zh/10/indexam.sgml b/zh/10/indexam.sgml index e17eeb2d..720465f5 100644 --- a/zh/10/indexam.sgml +++ b/zh/10/indexam.sgml @@ -34,62 +34,62 @@ typedef struct IndexAmRoutine NodeTag type; /* - * Total number of strategies (operators) by which we can traverse/search - * this AM. Zero if AM does not have a fixed set of strategy assignments. + * 可用于遍历或搜索此 AM 的策略(操作符)总数。 + * 如果 AM 没有固定的一组策略分配,则为零。 */ uint16 amstrategies; - /* total number of support functions that this AM uses */ + /* 此 AM 使用的支持函数总数 */ uint16 amsupport; - /* does AM support ORDER BY indexed column's value? */ + /* AM 是否支持按被索引列的值进行 ORDER BY? */ bool amcanorder; - /* does AM support ORDER BY result of an operator on indexed column? */ + /* AM 是否支持按被索引列上操作符的结果进行 ORDER BY? */ bool amcanorderbyop; - /* does AM support backward scanning? */ + /* AM 是否支持反向扫描? */ bool amcanbackward; - /* does AM support UNIQUE indexes? */ + /* AM 是否支持 UNIQUE 索引? */ bool amcanunique; - /* does AM support multi-column indexes? */ + /* AM 是否支持多列索引? */ bool amcanmulticol; - /* does AM require scans to have a constraint on the first index column? */ + /* AM 是否要求扫描必须约束第一个索引列? */ bool amoptionalkey; - /* does AM handle ScalarArrayOpExpr quals? */ + /* AM 是否处理 ScalarArrayOpExpr 限定条件? */ bool amsearcharray; - /* does AM handle IS NULL/IS NOT NULL quals? */ + /* AM 是否处理 IS NULL/IS NOT NULL 限定条件? */ bool amsearchnulls; - /* can index storage data type differ from column data type? */ + /* 索引存储数据类型是否可以不同于列数据类型? */ bool amstorage; - /* can an index of this type be clustered on? */ + /* 是否可以按此类型的索引进行聚簇? */ bool amclusterable; - /* does AM handle predicate locks? */ + /* AM 是否处理谓词锁? */ bool ampredlocks; - /* does AM support parallel scan? */ + /* AM 是否支持并行扫描? */ bool amcanparallel; - /* type of data stored in index, or InvalidOid if variable */ + /* 索引中存储的数据类型;如果可变,则为 InvalidOid */ Oid amkeytype; - /* interface functions */ + /* 接口函数 */ ambuild_function ambuild; ambuildempty_function ambuildempty; aminsert_function aminsert; ambulkdelete_function ambulkdelete; amvacuumcleanup_function amvacuumcleanup; - amcanreturn_function amcanreturn; /* can be NULL */ + amcanreturn_function amcanreturn; /* 可以为 NULL */ amcostestimate_function amcostestimate; amoptions_function amoptions; - amproperty_function amproperty; /* can be NULL */ + amproperty_function amproperty; /* 可以为 NULL */ amvalidate_function amvalidate; ambeginscan_function ambeginscan; amrescan_function amrescan; - amgettuple_function amgettuple; /* can be NULL */ - amgetbitmap_function amgetbitmap; /* can be NULL */ + amgettuple_function amgettuple; /* 可以为 NULL */ + amgetbitmap_function amgetbitmap; /* 可以为 NULL */ amendscan_function amendscan; - ammarkpos_function ammarkpos; /* can be NULL */ - amrestrpos_function amrestrpos; /* can be NULL */ + ammarkpos_function ammarkpos; /* 可以为 NULL */ + amrestrpos_function amrestrpos; /* 可以为 NULL */ - /* interface functions to support parallel index scans */ - amestimateparallelscan_function amestimateparallelscan; /* can be NULL */ - aminitparallelscan_function aminitparallelscan; /* can be NULL */ - amparallelrescan_function amparallelrescan; /* can be NULL */ + /* 支持并行索引扫描的接口函数 */ + amestimateparallelscan_function amestimateparallelscan; /* 可以为 NULL */ + aminitparallelscan_function aminitparallelscan; /* 可以为 NULL */ + amparallelrescan_function amparallelrescan; /* 可以为 NULL */ } IndexAmRoutine; @@ -161,7 +161,7 @@ ambulkdelete (IndexVacuumInfo *info, IndexBulkDeleteCallback callback, void *callback_state); - 从索引中删除元组。这是一个批量删除操作,通常应通过扫描整个索引并检查每个条目是否应被删除来实现。必须调用传入的 callback 函数,其调用形式为 callback(TID, callback_state) returns bool,以确定由其引用 TID 标识的某个索引条目是否应删除。该函数必须返回 NULL,或者返回一个通过 palloc 分配的结构体,其中包含此次删除操作影响的统计信息。如果不需要向 amvacuumcleanup 传递信息,返回 NULL 也是可以的。 + 从索引中删除元组。这是一个批量删除操作,旨在通过扫描整个索引并检查每个条目是否应被删除来实现。必须调用传入的 callback 函数,其调用形式为 callback(TID, callback_state) returns bool,以确定由其引用 TID 标识的某个索引条目是否应删除。该函数必须返回 NULL,或者返回一个通过 palloc 分配的结构体,其中包含此次删除操作影响的统计信息。如果不需要向 amvacuumcleanup 传递信息,返回 NULL 也是可以的。 @@ -185,8 +185,7 @@ amvacuumcleanup (IndexVacuumInfo *info, bool amcanreturn (Relation indexRelation, int attno); -检查索引是否可以支持仅索引扫描(针对给定列),做法是以如下形式返回某个索引条目的被索引列值:IndexTuple。属性编号从 1 开始,也就是说第一列的 attno 为 1。若支持则返回 TRUE,否则返回 FALSE。如果访问方法根本不支持仅索引扫描,那么amcanreturn字段在其IndexAmRoutine结构体中可以设为 NULL。 +检查索引能否通过以 IndexTuple 形式返回某个索引条目的被索引列值,在给定列上支持仅索引扫描。属性编号从 1 开始,也就是说第一列的 attno 为 1。若支持则返回 TRUE,否则返回 FALSE。如果访问方法根本不支持仅索引扫描,那么amcanreturn字段在其IndexAmRoutine结构体中可以设为 NULL。 @@ -199,7 +198,9 @@ amcostestimate (PlannerInfo *root, Selectivity *indexSelectivity, double *indexCorrelation, double *indexPages); -估计一次索引扫描的开销。该函数的完整说明见(见下文)。 + + 估计一次索引扫描的代价。该函数将在后面的 中详细讨论。 + @@ -207,7 +208,7 @@ bytea * amoptions (ArrayType *reloptions, bool validate); - 解析并验证索引的 reloptions 数组。只有当该索引存在非空的 reloptions 数组时才会调用此函数。reloptions 是一个 text 数组,其中的条目形如 name=value。该函数应构造一个 bytea 值,并将其复制到索引 relcache 条目的 rd_options 字段中。这个 bytea 值中的数据内容由访问方法自行定义;大多数标准访问方法使用结构体 StdRdOptions。当 validate 为真时,若存在未识别选项或无效取值,函数应报告合适的错误消息;当 validate 为假时,无效条目应被静默忽略。(当装载已存储在 pg_catalog 中的选项时,validate 为假;此时只有在访问方法改变了选项规则时才可能发现无效条目,而忽略过时条目是合适的。)如果希望采用默认行为,返回 NULL 也是可以的。 + 解析并验证索引的 reloptions 数组。只有当该索引存在非 NULL 的 reloptions 数组时才会调用此函数。reloptions 是一个 text 数组,其中的条目形如 name=value。该函数应构造一个 bytea 值,并将其复制到索引 relcache 条目的 rd_options 字段中。这个 bytea 值中的数据内容由访问方法自行定义;大多数标准访问方法使用结构体 StdRdOptions。当 validate 为真时,若存在未识别选项或无效取值,函数应报告合适的错误消息;当 validate 为假时,无效条目应被静默忽略。(当装载已存储在 pg_catalog 中的选项时,validate 为假;此时只有在访问方法改变了选项规则时才可能发现无效条目,而忽略过时条目是合适的。)如果希望采用默认行为,返回 NULL 也是可以的。 @@ -219,7 +220,7 @@ amproperty (Oid index_oid, int attno, 该amproperty方法允许索引访问方法覆盖pg_index_column_has_property及其相关函数的默认行为。如果访问方法对索引属性查询没有任何特殊行为,那么amproperty字段在其IndexAmRoutine结构体中可以设为 NULL。否则,amproperty方法会收到如下调用参数:index_oid和attno均为零,对应pg_indexam_has_property调用;或者index_oid有效且attno为零,对应pg_index_has_property调用;或者index_oid有效且attno大于零,对应pg_index_column_has_property调用。prop是一个枚举值,用来标识当前测试的属性;propname则是原始属性名字符串。如果核心代码不认识该属性名,那么propAMPROP_UNKNOWN。访问方法可以通过检查propname是否匹配来定义自定义属性名(使用pg_strcasecmp进行匹配,以与核心代码保持一致);对于核心代码已知的名称,最好检查prop。如果amproperty方法返回true,则表示它已确定属性测试结果:它必须将*res设为要返回的布尔值,或者把*isnull设为true以返回 NULL。(所引用的两个变量在调用前都初始化为false。)如果amproperty方法返回false,核心代码就会按其正常逻辑确定属性测试结果。 - 支持排序操作符的访问方法应当实现 AMPROP_DISTANCE_ORDERABLE 属性测试,因为核心代码不知道如何完成该测试,只会返回 NULL。若实现成本低于打开索引并调用 amcanreturn(这正是核心代码的默认行为),那么实现 AMPROP_RETURNABLE 测试也可能是有利的。对于其他所有标准属性,默认行为应当已经足够。 + 支持排序操作符的访问方法应当实现 AMPROP_DISTANCE_ORDERABLE 属性测试,因为核心代码不知道如何完成该测试,只会返回 NULL。若完成该测试的代价低于打开索引并调用 amcanreturn(这正是核心代码的默认行为),那么实现 AMPROP_RETURNABLE 测试也可能是有利的。对于其他所有标准属性,默认行为应当已经足够。 @@ -239,7 +240,8 @@ IndexScanDesc ambeginscan (Relation indexRelation, int nkeys, int norderbys); -为索引扫描做准备。nkeysnorderbys参数指明扫描中将使用的限定条件和排序操作符的数量,可用于分配空间。注意,此时尚未提供扫描键的实际值。结果必须是用 palloc 分配的结构体。由于实现方面的原因,索引访问方法必须调用RelationGetIndexScan()来创建此结构体。大多数情况下,ambeginscan除了执行该调用以及可能获取锁之外,几乎不做其他工作;索引扫描启动过程的主要工作位于amrescan。 + + 为一次索引扫描做准备。nkeysnorderbys 参数表示扫描中将使用的限定条件和排序操作符数量,这些信息可能有助于空间分配。请注意,此时还没有提供扫描键的实际值。结果必须是一个通过 palloc 分配的结构体。出于实现上的原因,索引访问方法必须通过调用 RelationGetIndexScan() 来创建这个结构体。大多数情况下,ambeginscan 除了做这次调用以及也许获取一些锁之外,不会做太多工作;索引扫描启动中真正有意思的部分在 amrescan 中。 @@ -262,7 +264,7 @@ amgettuple (IndexScanDesc scan, 沿给定方向(在索引中向前或向后)取出给定扫描中的下一个元组。若取得元组则返回 TRUE,若没有剩余匹配元组则返回 FALSE。返回 TRUE 时,元组 TID 存入scan结构体中。注意,成功仅表示索引中包含与扫描键匹配的条目,并不表示该元组一定仍存在于堆中,或者能够通过调用方的快照测试。成功时,amgettuple还必须将scan->xs_recheck设为 TRUE 或 FALSE。FALSE 表示可以确定该索引条目匹配扫描键。TRUE 表示无法确定,因此在取出堆元组后必须重新检查扫描键所代表的条件。这一规定支持有损索引操作符。注意,重新检查仅针对扫描条件;部分索引谓词(如果有)永远不会由amgettuple的调用方重新检查。 - 如果索引支持 仅索引扫描(即 amcanreturn 对它返回 TRUE),那么成功时 AM 还必须检查 scan->xs_want_itup;若其为真,就必须返回该索引条目的原始被索引数据。数据可以通过以下两种形式之一返回:一种是把 IndexTuple 指针存入 scan->xs_itup,其元组描述符为 scan->xs_itupdesc;另一种是把 HeapTuple 指针存入 scan->xs_hitup,其元组描述符为 scan->xs_hitupdesc。(当重建出的数据可能装不进 IndexTuple 时,应使用后一种格式。)无论采用哪种形式,指针所引用数据的管理责任都在访问方法一侧。对这份数据的有效性必须至少保持到该扫描下一次调用 amgettupleamrescanamendscan 为止。 + 如果索引支持 仅索引扫描(即 amcanreturn 对它返回 TRUE),那么成功时 AM 还必须检查 scan->xs_want_itup;若其为真,就必须返回该索引条目的原始被索引数据。数据可以通过以下两种形式之一返回:一种是把 IndexTuple 指针存入 scan->xs_itup,其元组描述符为 scan->xs_itupdesc;另一种是把 HeapTuple 指针存入 scan->xs_hitup,其元组描述符为 scan->xs_hitupdesc。(当重建出的数据可能装不进 IndexTuple 时,应使用后一种格式。)无论采用哪种形式,指针所引用数据的管理责任都在访问方法一侧。这份数据必须至少保持有效,直到该扫描下一次调用 amgettupleamrescanamendscan @@ -274,7 +276,8 @@ amgettuple (IndexScanDesc scan, int64 amgetbitmap (IndexScanDesc scan, TIDBitmap *tbm); -获取给定扫描中的所有元组,并将其加入调用方提供的TIDBitmap中(即将元组 ID 集合与位图中已有的集合做 OR 运算)。返回获取到的元组数量(可能只是近似值,例如某些访问方法不检测重复项)。向位图插入元组 ID 时,amgetbitmap可以指明需要对特定元组 ID 重新检查扫描条件。这类似于xs_recheck输出参数,它属于amgettuple。注意:在当前实现中,此特性的支持与位图自身有损存储的支持混在一起,因此对于需要重查的元组,调用方会重新检查扫描条件和部分索引谓词(如果有)。但将来未必始终如此。amgetbitmapamgettuple不能在同一次索引扫描中使用;使用amgetbitmap时还有其他限制,详见。 + + 取出给定扫描中的所有元组,并将其加入调用者提供的 TIDBitmap 中(也就是把这组元组 ID 与位图中已有的集合做 OR)。返回值是取得的元组数量(这可能只是近似计数,例如某些 AM 不会检测重复项)。在把元组 ID 插入位图时,amgetbitmap 可以指出某些具体的元组 ID 需要重新检查扫描条件。这类似于 amgettuplexs_recheck 输出参数。注意:在当前实现中,对这一特性的支持与位图自身的有损存储支持混在一起,因此调用者会对需要重检的元组同时重新检查扫描条件和部分索引谓词(如果有)。不过,这并不一定永远如此。amgetbitmapamgettuple 不能在同一次索引扫描中同时使用;使用 amgetbitmap 时还有其他限制,详见 @@ -286,7 +289,7 @@ amgetbitmap (IndexScanDesc scan, void amendscan (IndexScanDesc scan); - 结束一次扫描并释放资源。scan 结构体本身不应被释放,但访问方法内部获取的任何锁或 pin,以及由 ambeginscan 和其他扫描相关函数分配的其他内存,都必须被释放。 + 结束一次扫描并释放资源。scan 结构体本身不应被释放,但必须释放访问方法内部获取的所有锁、解除所有钉住状态,并释放由 ambeginscan 和其他扫描相关函数分配的其他内存。 @@ -403,7 +406,7 @@ amparallelrescan (IndexScanDesc scan); - 除了使用 amgettuple 外,索引扫描也可以使用 amgetbitmap,在一次调用中取出所有元组。与 amgettuple 相比,这通常明显更高效,因为它可以避免访问方法内部的反复加锁和解锁。原则上,amgetbitmap 应具有与重复调用 amgettuple 相同的效果,但为了简化实现,我们施加了若干限制。首先,amgetbitmap 一次性返回全部元组,因此不支持标记或恢复扫描位置。其次,元组是通过一个位图返回的,没有特定顺序,这也是为什么 amgetbitmap 不带 direction 参数的原因。(这种扫描也永远不会提供排序操作符。)此外,使用 amgetbitmap 时也没有仅索引扫描的支持,因为没有办法返回索引元组的内容。最后,amgetbitmap 不保证对返回的元组做任何锁定,其影响见 。 + 除了使用 amgettuple 外,索引扫描也可以使用 amgetbitmap,在一次调用中取出所有元组。与 amgettuple 相比,这可能明显更高效,因为它可以避免访问方法内部的反复加锁和解锁。原则上,amgetbitmap 应具有与重复调用 amgettuple 相同的效果,但为了简化实现,我们施加了若干限制。首先,amgetbitmap 一次性返回全部元组,因此不支持标记或恢复扫描位置。其次,元组是通过一个位图返回的,没有特定顺序,这也是为什么 amgetbitmap 不带 direction 参数的原因。(这种扫描也永远不会提供排序操作符。)此外,使用 amgetbitmap 时也没有仅索引扫描的支持,因为没有办法返回索引元组的内容。最后,amgetbitmap 不保证对返回的元组做任何锁定,其影响见 @@ -420,7 +423,7 @@ amparallelrescan (IndexScanDesc scan); - 构建一种支持并发更新的索引类型,通常需要对所需行为进行大量而细致的分析。对于 B-树和哈希索引类型,可以阅读 src/backend/access/nbtree/READMEsrc/backend/access/hash/README 中涉及的设计决策。 + 构建一种支持并发更新的索引类型,通常需要对所需行为进行大量而细致的分析。对于 B-树和 hash 索引类型,可以阅读 src/backend/access/nbtree/READMEsrc/backend/access/hash/README 中涉及的设计决策。 @@ -439,12 +442,12 @@ amparallelrescan (IndexScanDesc scan); - 索引扫描必须在保存 amgettuple 最近一次返回条目的索引页面上维护一个 pin,而 ambulkdelete 不能从被其他后端钉住的页面中删除条目。下面会解释为什么需要这条规则。 + 索引扫描必须在保存 amgettuple 最近一次返回条目的索引页面上保持钉住状态,而 ambulkdelete 不能从被其他后端钉住的页面中删除条目。下面会解释为什么需要这条规则。 - 如果没有第三条规则,索引读取者就有可能在某个索引条目被 VACUUM 删除之前先看到它,然后在对应的堆条目已被 VACUUM 删除之后才到达那里。如果读取者到达时,该项号仍未被重新使用,就不会造成严重问题,因为空项槽位会被 heap_fetch() 忽略。但如果第三个后端已经把这个项槽位重新用作别的东西呢?在使用 MVCC 兼容快照时不会有问题,因为该槽位的新占用者一定太新,无法通过快照测试。然而,对于非 MVCC 兼容的快照(例如 SnapshotAny),就可能错误地接受并返回一行实际上并不匹配扫描键的数据。我们可以要求在所有情况下都对堆行重新检查扫描键,以防范这种情形,但那样代价太高。于是,我们改为把索引页面上的 pin 作为一种代理,表示读取者可能仍处于从索引条目前往匹配堆条目的飞行中。让 ambulkdelete 在这种 pin 上阻塞,能够保证 VACUUM 不会在读取者处理完之前删除对应的堆条目。这种方案运行时开销很小,只有在真正发生冲突的少数情况下才会增加阻塞开销。 + 如果没有第三条规则,索引读取者就有可能在某个索引条目被 VACUUM 删除之前先看到它,然后在对应的堆条目已被 VACUUM 删除之后才到达那里。如果读取者到达时,该项号仍未被重新使用,就不会造成严重问题,因为空项槽位会被 heap_fetch() 忽略。但如果第三个后端已经把这个项槽位重新用作别的东西呢?在使用 MVCC 兼容快照时不会有问题,因为该槽位的新占用者一定太新,无法通过快照测试。然而,对于非 MVCC 兼容的快照(例如 SnapshotAny),就可能错误地接受并返回一行实际上并不匹配扫描键的数据。我们可以要求在所有情况下都对堆行重新检查扫描键,以防范这种情形,但那样代价太高。于是,我们改为把索引页面的钉住状态作为一种代理,表示读取者从索引条目到匹配堆条目的访问过程可能仍在进行中。让 ambulkdelete 因这种钉住状态而阻塞,能够保证 VACUUM 不会在读取者处理完之前删除对应的堆条目。这种方案运行时开销很小,只有在真正发生冲突的少数情况下才会增加阻塞开销。 @@ -452,7 +455,7 @@ amparallelrescan (IndexScanDesc scan); - 在 amgetbitmap 索引扫描中,访问方法不会在任何返回的元组上保留索引 pin。因此,只有把这种扫描与 MVCC 兼容的快照一起使用才是安全的。 + 在 amgetbitmap 索引扫描中,访问方法不会为任何返回的元组保持索引页面的钉住状态。因此,只有把这种扫描与 MVCC 兼容的快照一起使用才是安全的。 @@ -491,14 +494,17 @@ amparallelrescan (IndexScanDesc scan); - 此外,在按照上述规则报告唯一性违背之前,访问方法必须立即重新检查正在插入那一行的存活性。如果它已经是提交后死亡的状态,就不应报告违背。(这种情况不会出现在插入由当前事务刚创建的行这一普通场景中,但在 CREATE UNIQUE INDEX CONCURRENTLY 期间却可能发生。) + 此外,就在按照上述规则报告唯一性违背之前,访问方法必须重新检查正在插入那一行的存活性。如果它已经是提交后死亡的状态,就不应报告违背。(这种情况不会出现在插入由当前事务刚创建的行这一普通场景中,但在 CREATE UNIQUE INDEX CONCURRENTLY 期间却可能发生。) 我们要求索引访问方法自行应用这些测试,这意味着它必须深入堆中检查那些根据索引内容显示为具有重复键的行的提交状态。毫无疑问,这样做既丑陋又不够模块化,但它避免了重复工作:如果我们单独再做一次探测,那么在寻找新行索引条目插入位置时,查找冲突行的索引搜索实际上就会被重复执行。更何况,除非把冲突检查作为插入新索引条目动作的一个组成部分,否则也没有明显的方法可以避免竞争条件。 - 如果唯一约束可延迟,处理就更复杂:需要能够为新行插入索引条目,同时将唯一性冲突错误延迟到语句结束时甚至更晚。为避免不必要地重复搜索索引,索引访问方法应在首次插入时进行初步唯一性检查。如果确定不存在冲突的存活元组,就已完成检查。否则,应在需要强制执行约束时安排重新检查。如果重新检查时,插入的元组和某个具有相同键的其他元组都仍存活,就必须报告错误。(注意,在此场景中,存活实际表示索引条目 HOT 链中的任一元组是存活的。)为实现这一点,会向aminsert函数传入一个checkUnique参数,其值为以下之一: + + 如果唯一约束是可延迟的,情况会更复杂:我们需要能够为新行插入一个索引条目,但把任何唯一性违背错误延迟到语句结束时甚至更晚才报告。为了避免对索引进行不必要的重复搜索,索引访问方法应在初始插入期间执行一次初步唯一性检查。如果这表明确实不存在冲突的存活元组,那么事情就结束了。否则,我们会安排在真正强制约束时再做一次重检。若在重检时,插入的元组与另外某个具有相同键值的元组都仍然存活,就必须报告错误。(注意,就此用途而言,存活实际上是指索引条目 HOT 链中至少有一个元组是存活的。)为实现这一点,传给 aminsert 函数的 checkUnique 参数会取以下值之一: + + UNIQUE_CHECK_NO 表示不应执行唯一性检查(这不是唯一索引)。 @@ -533,10 +539,10 @@ amparallelrescan (IndexScanDesc scan); - 索引开销估计函数 + 索引代价估算函数 - amcostestimate 函数会收到描述某种可能索引扫描方式的信息,其中包括已经确定可用于该索引的 WHERE 子句和 ORDER BY 子句列表。它必须返回访问该索引的开销估计,以及 WHERE 子句的选择率(也就是在索引扫描期间将从父表中检索出的行所占比例)。对于简单情况,开销估计器几乎所有工作都可以通过调用优化器中的标准例程来完成;之所以提供 amcostestimate 函数,是为了让索引访问方法能够提供与索引类型有关的专门知识,以便在可能时改进标准估计。 + amcostestimate 函数会收到描述某种可能索引扫描方式的信息,其中包括已经确定可用于该索引的 WHERE 子句和 ORDER BY 子句列表。它必须返回访问该索引的代价估算,以及 WHERE 子句选择率的估计值(也就是在索引扫描期间将从父表中检索出的行所占比例)。对于简单情况,代价估算器几乎所有工作都可以通过调用优化器中的标准例程来完成;之所以提供 amcostestimate 函数,是为了让索引访问方法能够提供与索引类型有关的专门知识,以便在可能时改进标准估计。 @@ -570,7 +576,7 @@ amcostestimate (PlannerInfo *root, path - 当前正在考虑的索引访问路径。除开销和选择率字段外,其余字段都有效。 + 当前正在考虑的索引访问路径。除代价和选择率字段外,其余字段都有效。 @@ -579,7 +585,7 @@ amcostestimate (PlannerInfo *root, loop_count - 在开销估计中应计入的索引扫描重复次数。当考虑在嵌套循环连接内部使用参数化扫描时,这个参数通常会大于 1。请注意,开销估计仍应只针对一次扫描;更大的 loop_count 只表示可以适当考虑多次扫描之间的一些缓存效应。 + 在代价估算中应计入的索引扫描重复次数。当考虑在嵌套循环连接内部使用参数化扫描时,这个参数通常会大于 1。请注意,代价估算仍应只针对一次扫描;更大的 loop_count 只表示可以适当考虑多次扫描之间的一些缓存效应。 @@ -594,7 +600,7 @@ amcostestimate (PlannerInfo *root, *indexStartupCost - 设为索引启动处理的开销。 + 设为索引启动处理的代价。 @@ -603,7 +609,7 @@ amcostestimate (PlannerInfo *root, *indexTotalCost - 设为索引处理的总开销。 + 设为索引处理的总代价。 @@ -638,19 +644,19 @@ amcostestimate (PlannerInfo *root, - 请注意,开销估计函数必须用 C 编写,而不能用 SQL 或任何可用的过程语言,因为它们必须访问规划器/优化器的内部数据结构。 + 请注意,代价估算函数必须用 C 编写,而不能用 SQL 或任何可用的过程语言,因为它们必须访问规划器/优化器的内部数据结构。 - 索引访问开销应使用 src/backend/optimizer/path/costsize.c 所采用的参数来计算:顺序磁盘块读取的开销为 seq_page_cost,非顺序读取的开销为 random_page_cost,处理一条索引行的开销通常应取为 cpu_index_tuple_cost。此外,在索引处理期间调用的任何比较操作符(特别是对 indexquals 本身的求值)都应计入适当倍数的 cpu_operator_cost。 + 索引访问代价应使用 src/backend/optimizer/path/costsize.c 所采用的参数来计算:顺序磁盘块读取的代价为 seq_page_cost,非顺序读取的代价为 random_page_cost,处理一条索引行的代价通常应取为 cpu_index_tuple_cost。此外,在索引处理期间调用的任何比较操作符(特别是对 indexquals 本身的求值)都应计入适当倍数的 cpu_operator_cost - 访问开销应包括与扫描索引本身有关的全部磁盘和 CPU 开销,但包括取出或处理由索引标识出的父表行的开销。 + 访问代价应包括与扫描索引本身有关的全部磁盘和 CPU 代价,但包括取出或处理由索引标识出的父表行的代价。 - 启动开销是整个扫描总开销中必须在开始取第一行之前先付出的那一部分。对大多数索引来说,这可以视为零;但启动开销较高的索引类型可能希望把它设为非零。 + 启动代价是整个扫描总代价中必须在开始取第一行之前先付出的那一部分。对大多数索引来说,这可以视为零;但启动代价较高的索引类型可能希望把它设为非零。 @@ -658,7 +664,7 @@ amcostestimate (PlannerInfo *root, - indexCorrelation 应设为索引顺序与表顺序之间的相关性(范围从 -1.0 到 1.0)。该值用于调整从父表取行开销的估计。 + indexCorrelation 应设为索引顺序与表顺序之间的相关性(范围从 -1.0 到 1.0)。该值用于调整从父表取行代价的估计。 @@ -670,9 +676,9 @@ amcostestimate (PlannerInfo *root, - 开销估计 + 代价估算 - 一个典型的开销估计器会按如下步骤进行: + 一个典型的代价估算器会按如下步骤进行: @@ -701,14 +707,14 @@ amcostestimate (PlannerInfo *root, - 计算索引访问开销。一个通用估计器可能会这样做: + 计算索引访问代价。一个通用估计器可能会这样做: /* - * Our generic assumption is that the index pages will be read - * sequentially, so they cost seq_page_cost each, not random_page_cost. - * Also, we charge for evaluation of the indexquals at each index row. - * All the costs are assumed to be paid incrementally during the scan. + * 通用假设是索引页面将按顺序读取, + * 因此每页代价为 seq_page_cost,而非 random_page_cost。 + * 此外,还要计入在每个索引行上对 indexquals 求值的代价。 + * 假定所有代价都在扫描过程中逐步付出。 */ cost_qual_eval(&index_qual_cost, path->indexquals, root); *indexStartupCost = index_qual_cost.startup; @@ -728,7 +734,7 @@ cost_qual_eval(&index_qual_cost, path->indexquals, root); - 开销估计器函数的示例可在 src/backend/utils/adt/selfuncs.c 中找到。 + 代价估算器函数的示例可在 src/backend/utils/adt/selfuncs.c 中找到。 diff --git a/zh/10/indices.sgml b/zh/10/indices.sgml index 3c0b62b1..f872bfe7 100644 --- a/zh/10/indices.sgml +++ b/zh/10/indices.sgml @@ -31,7 +31,7 @@ SELECT content FROM test1 WHERE id = constant; - 大多数非小说类书籍也采用了类似的方法:读者经常查找的术语和概念会被收集到书末按字母顺序排列的索引中。感兴趣的读者可以相对快速地浏览索引并翻到相应页面,而不必通读整本书才能找到自己感兴趣的内容。正如作者需要预判读者可能查找哪些条目一样,数据库程序员也需要预见哪些索引会有用。 + 大多数非虚构类书籍也采用了类似的方法:读者经常查找的术语和概念会被收集到书末按字母顺序排列的索引中。感兴趣的读者可以相对快速地浏览索引并翻到相应页面,而不必通读整本书才能找到自己感兴趣的内容。正如作者需要预判读者可能查找哪些条目一样,数据库程序员也需要预见哪些索引会有用。 @@ -68,7 +68,7 @@ CREATE INDEX test1_id_index ON test1 (id); 索引类型 - PostgreSQL提供了多种索引类型:B-树、哈希、GiST、SP-GiST、GIN、BRIN,以及扩展bloom。每种索引类型都采用不同的算法,分别最适合不同类型的查询。默认情况下,CREATE INDEX命令创建的是 B-树索引,它适用于最常见的场景。 + PostgreSQL提供了多种索引类型:B-树、Hash、GiST、SP-GiST、GIN、BRIN,以及扩展bloom。每种索引类型都采用不同的算法,分别最适合不同类型的查询。默认情况下,CREATE INDEX命令创建的是 B-树索引,它适用于最常见的场景。 索引 B-树 B-树 索引 B-树能够处理可以按某种顺序排序的数据上的等值查询和范围查询。特别是,只要已索引列参与了下列任一操作符的比较,PostgreSQL查询规划器就会考虑使用 B-树索引: @@ -91,12 +91,12 @@ CREATE INDEX test1_id_index ON test1 (id); 索引 - 哈希 + hash - 哈希 + hash 索引 - 哈希索引只能处理简单的等值比较。只要已索引列参与的是使用=操作符的比较,查询规划器就会考虑使用哈希索引。使用以下命令创建哈希索引: + Hash 索引只能处理简单的等值比较。只要已索引列参与的是使用=操作符的比较,查询规划器就会考虑使用 Hash 索引。使用以下命令创建 Hash 索引: CREATE INDEX name ON table USING HASH (column); @@ -115,7 +115,7 @@ CREATE INDEX name ON table SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10; ]]> - 这会找出距离给定目标点最近的十个地点。是否能做到这一点,同样取决于所使用的具体操作符类。在中,可以按这种方式使用的操作符列在Ordering Operators这一列中。 + 这会找出距离给定目标点最近的十个地点。是否能做到这一点,同样取决于所使用的具体操作符类。在中,可以按这种方式使用的操作符列在排序操作符这一列中。 索引 SP-GiST SP-GiST 索引 @@ -152,8 +152,8 @@ SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10; 多列索引 - index - multicolumn + 索引 + 多列 @@ -184,15 +184,15 @@ CREATE INDEX test2_mm_idx ON test2 (major, minor); - 多列 GIN 索引可以用于涉及索引任意列子集的查询条件。与 B-树或 GiST 不同,无论查询条件使用的是哪一列索引列,GIN 的索引搜索效果都一样。 + 多列 GIN 索引可以用于涉及索引任意列子集的查询条件。与 B-树或 GiST 不同,无论查询条件使用的是哪些索引列,GIN 的索引搜索效果都一样。 - 多列 BRIN 索引可以用于涉及索引任意列子集的查询条件。和 GIN 一样、不同于 B-树或 GiST,无论查询条件使用的是哪一列索引列,索引搜索效果都一样。在单个表上使用多个 BRIN 索引,而不是使用一个多列 BRIN 索引的唯一理由,是需要不同的pages_per_range存储参数。 + 多列 BRIN 索引可以用于涉及索引任意列子集的查询条件。和 GIN 一样、不同于 B-树或 GiST,无论查询条件使用的是哪些索引列,索引搜索效果都一样。在单个表上使用多个 BRIN 索引,而不是使用一个多列 BRIN 索引的唯一理由,是需要不同的pages_per_range存储参数。 - 多列 GIN 索引可以用于涉及索引任意列子集的查询条件。与 B-树或 GiST 不同,无论查询条件使用的是哪一列索引列,GIN 的索引搜索效果都一样。 + 当然,每一列都必须配合适合该索引类型的操作符使用;涉及其他操作符的子句不会被考虑。 @@ -205,8 +205,8 @@ CREATE INDEX test2_mm_idx ON test2 (major, minor); 索引和<literal>ORDER BY</literal> - index - and ORDER BY + 索引 + ORDER BY @@ -214,7 +214,7 @@ CREATE INDEX test2_mm_idx ON test2 (major, minor); - 规划器在满足ORDER BY要求时,会考虑两种方案:扫描一个与该要求匹配的可用索引,或者按物理顺序扫描表再显式排序。对于需要扫描表中很大一部分内容的查询,显式排序通常会比使用索引更快,因为它遵循顺序访问模式,需要的磁盘 I/O 更少。只有在只需取出少量行时,索引才更有价值。一个重要的特例是ORDER BYLIMIT n组合使用:显式排序必须处理所有数据才能找出最前面的n行,而如果有一个与ORDER BY匹配的索引,就可以直接取回前n行,而完全不必扫描剩余数据。 + 规划器在满足ORDER BY要求时,会考虑两种方案:扫描一个与该要求匹配的可用索引,或者按物理顺序扫描表再显式排序。对于需要扫描表中很大一部分内容的查询,显式排序通常会比使用索引更快,因为它遵循顺序访问模式,需要的磁盘 I/O 更少。只需取出少量行时,索引更有价值。一个重要的特例是ORDER BYLIMIT n组合使用:显式排序必须处理所有数据才能找出最前面的n行,而如果有一个与ORDER BY匹配的索引,就可以直接取回前n行,而完全不必扫描剩余数据。 @@ -244,12 +244,12 @@ CREATE INDEX test3_desc_index ON test3 (id DESC NULLS LAST); 组合多个索引 - index - combining multiple indexes + 索引 + 组合多个索引 - bitmap scan + 位图扫描 @@ -276,8 +276,8 @@ CREATE INDEX test3_desc_index ON test3 (id DESC NULLS LAST); 唯一索引 - index - unique + 索引 + 唯一 @@ -308,8 +308,8 @@ CREATE UNIQUE INDEX name ON table表达式索引 - index - on expressions + 索引 + 基于表达式 @@ -356,8 +356,8 @@ CREATE INDEX people_names ON people ((first_name || ' ' || last_name)); 部分索引 - index - partial + 索引 + 部分 @@ -365,7 +365,7 @@ CREATE INDEX people_names ON people ((first_name || ' ' || last_name)); - 使用部分索引的一个主要原因是避免索引常见值。由于搜索常见值的查询(即占全部表行百分之几以上的值)反正也不会使用索引,因此完全没有必要把这些行保留在索引里。这会减小索引尺寸,从而加快那些确实会使用该索引的查询。它也会加快很多表更新操作,因为索引并不需要在所有情况下都更新。展示了这种思路的一种可能应用。 + 使用部分索引的一个主要原因是避免索引常见值。由于搜索常见值(即占全部表行百分之几以上的值)的查询反正也不会使用索引,因此完全没有必要把这些行保留在索引里。这会减小索引尺寸,从而加快那些确实会使用该索引的查询。它也会加快很多表更新操作,因为索引并不需要在所有情况下都更新。展示了这种思路的一种可能应用。 @@ -449,7 +449,7 @@ SELECT * FROM orders WHERE order_nr = 3501; - 也说明了:索引列和谓词中使用的列不必一致。PostgreSQL支持带任意谓词的部分索引,只要其中只涉及正在建立索引的那张表的列。不过要记住,谓词必须与那些希望从该索引受益的查询中使用的条件相匹配。更准确地说,只有当系统能够识别出查询的WHERE条件在数学上蕴含该索引的谓词时,部分索引才能用于该查询。PostgreSQL并没有一个复杂的定理证明器,来识别那些写法不同但数学上等价的表达式。(不仅构建这样一个通用定理证明器极其困难,而且它很可能也会慢到失去实际用途。)系统可以识别简单的不等式蕴含,例如x < 1蕴含x < 2;否则,谓词条件必须与查询WHERE条件的某一部分完全匹配,否则索引不会被识别为可用。匹配发生在查询规划阶段,而不是运行时。因此,参数化查询子句无法与部分索引配合工作。例如,一个带参数的预备查询可能写成x < ?,而对于参数的所有可能取值,它都不可能蕴含x < 2。 + 也说明了:索引列和谓词中使用的列不必一致。PostgreSQL支持带任意谓词的部分索引,只要其中只涉及正在建立索引的那张表的列。不过要记住,谓词必须与那些希望从该索引受益的查询中使用的条件相匹配。更准确地说,只有当系统能够识别出查询的WHERE条件在数学上蕴含该索引的谓词时,部分索引才能用于该查询。PostgreSQL并没有一个复杂的定理证明器,来识别那些写法不同但数学上等价的表达式。(不仅构建这样一个通用定理证明器极其困难,而且它很可能也会慢到失去实际用途。)系统可以识别简单的不等式蕴含,例如x < 1蕴含x < 2;否则,谓词条件必须与查询WHERE条件的某一部分完全匹配,否则索引不会被识别为可用。匹配发生在查询规划阶段,而不是运行时。因此,参数化查询子句无法与部分索引配合工作。例如,一个带参数的预备查询可能写成x < ?,而它无法保证在参数的所有可能取值下都蕴含x < 2 @@ -460,7 +460,9 @@ SELECT * FROM orders WHERE order_nr = 3501; 建立一个部分唯一索引 - 假设有一个记录测试结果的表。我们希望确保每个给定的测试对象和目标组合只有一个成功条目,但可以有任意数量的失败条目。下面是一种实现方法: + + 假设我们有一张描述测试结果的表。我们希望确保对于给定的测试对象和目标组合,只有一条成功记录,但可以有任意多条失败记录。实现方法之一如下: + CREATE TABLE tests ( subject text, target text, @@ -470,7 +472,9 @@ CREATE TABLE tests ( CREATE UNIQUE INDEX tests_success_constraint ON tests (subject, target) WHERE success; -在成功测试很少而失败测试很多时,这种方法尤其高效。也可以创建一个带有IS NULL限制的唯一部分索引,从而只允许列中出现一个空值。 + + 当成功测试很少而失败测试很多时,这是一种特别高效的方法。也可以通过创建一个带IS NULL限制的唯一部分索引,来让某一列只允许出现一个空值。 + @@ -523,11 +527,11 @@ CREATE INDEX mytable_cat_data ON mytable (category, data); 操作符类和操作符族 - operator class + 操作符类 - operator family + 操作符族 索引定义可以为索引的每一列指定一个操作符类 @@ -648,7 +652,10 @@ CREATE INDEX test1c_content_y_index ON test1c (content COLLATE "y"); PostgreSQL中的所有索引都是二级索引,也就是说,每个索引都与表的主数据区分开存储(在PostgreSQL术语中,这个主数据区称为表的)。这意味着,在普通索引扫描中,每次取回一行都需要同时从索引和堆中取数据。此外,尽管满足某个可索引WHERE条件的索引项通常在索引中彼此接近,但它们引用的表行却可能分布在堆中的任何位置。因此,索引扫描的堆访问部分会涉及大量对堆的随机访问,这可能很慢,尤其是在传统旋转介质上。(正如中所述,位图扫描试图通过按排序顺序进行堆访问来缓解这项代价,但那也只能缓解到一定程度。) - 为了解决这一性能问题,PostgreSQL支持仅索引扫描,仅通过索引就能完成查询,无需访问堆。其基本思路是直接从各个索引项返回值,而不访问相关联的堆项。使用这种方法有两个基本限制: + + 为了解决这个性能问题,PostgreSQL支持仅索引扫描,它可以仅凭索引而不访问堆来回答查询。基本思路是直接从每个索引项中返回值,而不是再去查对应的堆项。要使用这种方法,有两个根本限制: + + 索引类型必须支持仅索引扫描。B-树索引总是支持。GiST 和 SP-GiST 索引对某些操作符类支持仅索引扫描,但对另一些则不支持。其他索引类型则完全不支持。底层要求是,索引必须实际存储原始数据值,或者至少能够重建出每个索引项对应的原始数据值。反例是 GIN 索引,它不能支持仅索引扫描,因为每个索引项通常只保存原始数据值的一部分。 @@ -656,13 +663,19 @@ CREATE INDEX test1c_content_y_index ON test1c (content COLLATE "y"); - 查询只能引用存储在索引中的列。例如,假设某个表的x和y列上有一个索引,且该表还有一列z,那么以下查询可以使用仅索引扫描: + + 查询只能引用存储在索引中的列。例如,假设某个表的xy列上有一个索引,且该表还有一列z,那么下面这些查询可以使用仅索引扫描: + SELECT x, y FROM tab WHERE x = 'key'; SELECT x FROM tab WHERE x = 'key' AND y < 42; -但以下查询不能: + + 但下面这些查询则不能: + SELECT x, z FROM tab WHERE x = 'key'; SELECT x FROM tab WHERE x = 'key' AND z < 42; -(表达式索引和部分索引会使这条规则更复杂,下文将作讨论。) + + (表达式索引和部分索引会让这条规则变得更复杂,下文会讨论。) + @@ -707,8 +720,8 @@ SELECT target FROM tests WHERE subject = 'some-subject' AND success; 检查索引使用情况 - index - examining usage + 索引 + 检查使用情况 diff --git a/zh/10/information_schema.sgml b/zh/10/information_schema.sgml index b18943a3..26a45836 100644 --- a/zh/10/information_schema.sgml +++ b/zh/10/information_schema.sgml @@ -105,7 +105,7 @@ - Name + 名称 数据类型 描述 @@ -139,7 +139,7 @@ - Name + 名称 数据类型 描述 @@ -191,7 +191,7 @@ - Name + 名称 数据类型 描述 @@ -241,7 +241,7 @@ - Name + 名称 数据类型 描述 @@ -361,7 +361,7 @@ collation_catalog sql_identifier - 包含此属性排序规则的数据库名(总是当前数据库),如果默认或者该属性的数据类型不可排序则为空 + 包含该属性排序规则的数据库名称(总是当前数据库);如果使用默认排序规则,或该属性的数据类型不支持排序规则,则为 null。 @@ -369,7 +369,7 @@ collation_schema sql_identifier - 包含此属性排序规则的模式名,如果默认或者该属性的数据类型不可排序则为空 + 包含该属性排序规则的模式名称;如果使用默认排序规则,或该属性的数据类型不支持排序规则,则为 null。 @@ -377,7 +377,7 @@ collation_name sql_identifier - 该属性排序规则的名称,如果默认或者该属性的数据类型不可排序则为空 + 该属性排序规则的名称;如果使用默认排序规则,或该属性的数据类型不支持排序规则,则为 null。 @@ -564,7 +564,7 @@ - Name + 名称 数据类型 描述 @@ -655,7 +655,7 @@ - Name + 名称 数据类型 描述 @@ -729,7 +729,7 @@ - Name + 名称 数据类型 描述 @@ -787,7 +787,7 @@ - Name + 名称 数据类型 描述 @@ -845,7 +845,7 @@ - Name + 名称 数据类型 描述 @@ -919,7 +919,7 @@ - Name + 名称 数据类型 描述 @@ -1001,7 +1001,7 @@ - Name + 名称 数据类型 描述 @@ -1081,7 +1081,7 @@ - Name + 名称 数据类型 描述 @@ -1171,7 +1171,7 @@ - Name + 名称 数据类型 描述 @@ -1253,7 +1253,7 @@ - Name + 名称 数据类型 描述 @@ -1426,7 +1426,7 @@ collation_catalog sql_identifier - 包含此属性排序规则的数据库名(总是当前数据库),如果默认或者该属性的数据类型不可排序则为空 + 包含该列排序规则的数据库名称(总是当前数据库);如果使用默认排序规则,或该列的数据类型不支持排序规则,则为 null。 @@ -1434,7 +1434,7 @@ collation_schema sql_identifier - 该列的包含排序规则的模式名,如果默认或者该列的数据类型不可排序则为空 + 包含该列排序规则的模式名称;如果使用默认排序规则,或该列的数据类型不支持排序规则,则为 null。 @@ -1442,7 +1442,7 @@ collation_name sql_identifier - 该列的排序规则的名称,如果默认或者该列的数据类型不可排序则为空 + 该列排序规则的名称;如果使用默认排序规则,或该列的数据类型不支持排序规则,则为 null。 @@ -1645,7 +1645,7 @@ - Name + 名称 数据类型 描述 @@ -1727,7 +1727,7 @@ - Name + 名称 数据类型 描述 @@ -1801,7 +1801,7 @@ - Name + 名称 数据类型 描述 @@ -1867,7 +1867,7 @@ - Name + 名称 数据类型 描述 @@ -1957,7 +1957,7 @@ - Name + 名称 数据类型 描述 @@ -2032,7 +2032,7 @@ - Name + 名称 数据类型 描述 @@ -2119,7 +2119,7 @@ collation_catalog sql_identifier - 包含此域排序规则的数据库名(总是当前数据库),如果默认或者该域的数据类型不可排序则为空 + 包含该域排序规则的数据库名称(总是当前数据库);如果使用默认排序规则,或该域的数据类型不支持排序规则,则为 null。 @@ -2127,7 +2127,7 @@ collation_schema sql_identifier - 包含此域排序规则的模式名,如果默认或者该域的数据类型不可排序则为空 + 包含该域排序规则的模式名称;如果使用默认排序规则,或该域的数据类型不支持排序规则,则为 null。 @@ -2135,7 +2135,7 @@ collation_name sql_identifier - 该域排序规则的名称,如果默认或者该域的数据类型不可排序则为空 + 该域排序规则的名称;如果使用默认排序规则,或该域的数据类型不支持排序规则,则为 null。 @@ -2275,7 +2275,7 @@ <literal>element_types</literal> - 视图element_types包含数组元素的数据类型描述符。当一个表列、复合类型属性、域、函数参数或函数返回值被定义为一种数组类型,相应的信息模式视图只在列data_type中包含ARRAY。要获得该数组元素类型的信息,你可以连接该相应的视图和这个视图。例如,要显示一个表的列及其数据类型和数组元素类型,你可以: + 视图element_types包含数组元素的数据类型描述符。当一个表列、复合类型属性、域、函数参数或函数返回值被定义为一种数组类型时,相应的信息模式视图只在列data_type中包含ARRAY。要获得该数组元素类型的信息,你可以连接该相应的视图和这个视图。例如,要显示一个表的列及其数据类型和数组元素类型(如果适用),你可以: SELECT c.column_name, c.data_type, e.data_type AS element_type FROM information_schema.columns c LEFT JOIN information_schema.element_types e @@ -2293,7 +2293,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -2394,7 +2394,7 @@ ORDER BY c.ordinal_position; collation_catalog sql_identifier - 包含元素类型排序规则的数据库名称(总是当前数据库), 如果默认或该元素的数据类型是不可排序的则为空 + 包含该元素类型排序规则的数据库名称(总是当前数据库);如果使用默认排序规则,或该元素类型不支持排序规则,则为 null。 @@ -2402,7 +2402,7 @@ ORDER BY c.ordinal_position; collation_schema sql_identifier - 包含元素类型排序规则的模式名称, 如果默认或该元素的数据类型是不可排序的则为空 + 包含该元素类型排序规则的模式名称;如果使用默认排序规则,或该元素类型不支持排序规则,则为 null。 @@ -2410,7 +2410,7 @@ ORDER BY c.ordinal_position; collation_name sql_identifier - 元素类型的排序规则名, 如果默认或该元素的数据类型是不可排序的则为空 + 该元素类型排序规则的名称;如果使用默认排序规则,或该元素类型不支持排序规则,则为 null。 @@ -2465,9 +2465,7 @@ ORDER BY c.ordinal_position; domain_default character_data - - 元素的数据类型所在的数据库名称(总是当前数据库) - + 尚未实现 @@ -2557,7 +2555,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -2591,7 +2589,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -2649,7 +2647,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -2715,7 +2713,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -2773,7 +2771,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -2855,7 +2853,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -2921,7 +2919,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -2987,7 +2985,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -3085,7 +3083,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -3369,7 +3367,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -3470,7 +3468,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -3560,7 +3558,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -3666,7 +3664,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -3760,7 +3758,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -3842,7 +3840,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -3932,7 +3930,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -4038,7 +4036,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -4726,7 +4724,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -4808,7 +4806,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -4936,7 +4934,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -5018,7 +5016,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -5084,7 +5082,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -5150,7 +5148,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -5208,7 +5206,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -5274,7 +5272,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -5330,7 +5328,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -5390,7 +5388,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -5488,7 +5486,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -5582,7 +5580,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -5706,7 +5704,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -5798,7 +5796,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -5880,7 +5878,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -6067,7 +6065,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -6157,7 +6155,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -6242,7 +6240,7 @@ ORDER BY c.ordinal_position; - SQL 了解两种用户定义类型:结构类型(在PostgreSQL中也称为复合类型)以及 distinct 类型(PostgreSQL 尚未实现)。为兼顾将来,请使用列user_defined_type_category来区分它们。其他用户定义类型,如基类型和枚举(两者都是PostgreSQL的扩展),不会在这里显示。域的相关信息见。 + SQL 中有两种用户定义类型:结构类型(在PostgreSQL中也称为复合类型)以及独立类型(distinct type,PostgreSQL 尚未实现)。为兼顾将来,请使用列user_defined_type_category来区分它们。其他用户定义类型,如基础类型和枚举(两者都是PostgreSQL的扩展),不会在这里显示。域的相关信息见 @@ -6251,7 +6249,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -6509,7 +6507,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -6576,7 +6574,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -6632,7 +6630,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -6714,7 +6712,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -6794,7 +6792,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -6868,7 +6866,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 diff --git a/zh/10/install-windows.sgml b/zh/10/install-windows.sgml index bc898a7b..46d992f3 100644 --- a/zh/10/install-windows.sgml +++ b/zh/10/install-windows.sgml @@ -4,8 +4,8 @@ 在 <productname>Windows</productname> 上从源代码安装 - installation - on Windows + 安装 + 在 Windows 上 @@ -63,7 +63,10 @@ $ENV{MSBFLAGS}="/m"; 需求 - 以下附加产品是构建 PostgreSQL 所必需的。请使用 config.pl 文件指定各个库所在的目录。 + + 构建PostgreSQL需要以下附加产品。请使用config.pl文件指定这些库所在的目录。 + + Microsoft Windows SDK @@ -81,7 +84,10 @@ $ENV{MSBFLAGS}="/m"; - 开始使用时不需要以下附加产品,但构建完整软件包时需要。请使用 config.pl 文件指定各个库所在的目录。 + + 以下附加产品并非入门所必需,但若要构建完整的软件包则需要它们。请使用config.pl文件指定这些库所在的目录。 + + ActiveState TCL 构建 PL/Tcl 需要它(注意:需要 8.4 版本,免费的标准发行版即可)。 @@ -272,7 +278,8 @@ $ENV{PERL5LIB}=$ENV{PERL5LIB} . ';c:\IPC-Run-0.94\lib'; - 部分 TAP 测试依赖一些外部命令,相关测试会根据这些命令是否可用而选择性触发。以下各变量都可以在 buildenv.pl 中设置或取消设置: + + 部分 TAP 测试依赖一些外部命令,相关测试会根据这些命令是否可用而选择性触发。以下各变量都可以在 buildenv.pl 中设置或取消设置: GZIP_PROGRAM @@ -292,7 +299,7 @@ $ENV{PERL5LIB}=$ENV{PERL5LIB} . ';c:\IPC-Run-0.94\lib'; - 使用 Make 构建文档 + 构建文档 将 PostgreSQL 文档构建为 HTML 格式,需要若干工具和文件。请为这些文件创建一个根目录,并将它们存放在下列子目录中。 diff --git a/zh/10/installation.sgml b/zh/10/installation.sgml index 302aa0ea..e3bc81d4 100644 --- a/zh/10/installation.sgml +++ b/zh/10/installation.sgml @@ -11,7 +11,7 @@ in a standalone-ignore clause. <![%standalone-include[<productname>PostgreSQL</productname>]]> 从源代码安装 - installation + 安装 介绍如何使用源代码发布包安装 PostgreSQL。(如果你安装的是预打包的发行版,例如 RPM 或 Debian 软件包,请忽略本,改为阅读打包者提供的说明。) @@ -42,7 +42,8 @@ su - postgres 一般来说,现代的 Unix 兼容平台应该能够运行 PostgreSQL。发布时经过具体测试的平台列于下方 。发行包的 doc 子目录中有若干平台特定的 FAQ 文档,遇到问题时可以查阅。 - 以下软件包必须备齐,才能构建 PostgreSQL: + + 构建 PostgreSQL 需要下列软件包: @@ -119,13 +120,17 @@ su - postgres - 以下软件包是可选的。默认配置不需要它们,但启用某些构建选项时需要,具体如下: + + 下列软件包是可选的。默认配置不需要它们,但在启用某些构建选项时会用到, + 如下所述: + + 要构建服务器端编程语言 PL/Perl, 你需要一个完整的 Perl 安装, 包括 libperl 库和头文件。 - 最低要求版本是 Perl 5.14。 + 最低要求版本是 Perl 5.8.3。 由于 PL/Perl 是一个共享库,在大多数平台上, libperl libperl 也必须是共享库。这在较新的 @@ -183,7 +188,7 @@ su - postgres - 如果你希望支持使用相应服务进行身份验证,就需要 KerberosOpenLDAP 和/或 PAM + 如果你希望支持使用相应服务进行认证,就需要 KerberosOpenLDAP 和/或 PAM @@ -211,10 +216,10 @@ su - postgres 获取源代码 - 要获取 PostgreSQL &version; 的源码,请访问网站的下载区:。你应该取得一个名为 postgresql-&version;.tar.gzpostgresql-&version;.tar.bz2 的文件。取得文件后,将其解包: + 要获取 PostgreSQL &version; 的源码,请访问网站的下载区:。你应该取得一个名为 postgresql-&version;.tar.gzpostgresql-&version;.tar.bz2 的文件。取得文件后,将其解包: gunzip postgresql-&version;.tar.gz tar xf postgresql-&version;.tar -(可使用 bunzip2 代替 gunzip 来解压 .bz2 文件。)这会在当前目录下创建目录 postgresql-&version;,其中包含 PostgreSQL 源码。切换到该目录,继续完成其余安装过程。 +(可使用 bunzip2 代替 gunzip 来解压 .bz2 文件。)这会在当前目录下创建目录 postgresql-&version;,其中包含 PostgreSQL 源码。切换到该目录,继续完成其余安装过程。 你也可以直接从版本控制仓库获取源码,参见 @@ -530,7 +535,7 @@ su - postgres 构建时支持 ICUICU 库。这要求已安装 ICU4C 软件包。当前 ICU4C 的最低要求版本是 4.2。 - 默认情况下,pkg-configpkg-config 用于查找所需的编译选项。此方式支持 ICU4C 4.6 及更高版本。对于更早的版本,或者当 pkg-config 不可用时,可以将变量 ICU_CFLAGSICU_LIBS 指定给 configure,如下例所示: + 默认情况下,pkg-configpkg-config 用于查找所需的编译选项。此方式支持 ICU4C 4.6 及更高版本。对于更早的版本,或者当 pkg-config 不可用时,可以将变量 ICU_CFLAGSICU_LIBS 指定给 configure,如下例所示: ./configure ... --with-icu ICU_CFLAGS='-I/some/where/include' ICU_LIBS='-L/some/where/lib -licui18n -licuuc -licudata' (如果 ICU4C 位于编译器的默认搜索路径中,仍需要指定一个非空字符串,以避免使用 pkg-config,例如 ICU_CFLAGS=' '。) @@ -624,7 +629,7 @@ su - postgres ,使用 OSSP UUID library + url="http://www.ossp.org/pkg/lib/uuid/">OSSP UUID 库 @@ -643,7 +648,10 @@ su - postgres - 使用 libxml2 构建,以启用 SQL/XML 支持。此功能要求 Libxml2 2.6.23 或更高版本。 + + 构建时支持 libxml2,以启用 SQL/XML 支持。 + 这一特性要求 libxml2 2.6.23 或更高版本。 + 为检测所需的编译器和链接器选项,PostgreSQL 会查询 pkg-config,前提是已安装该程序且其中有 libxml2 的信息。否则,如果找到 libxml2 安装的 xml2-config 程序,就会使用它。优先使用 pkg-config,因为它能更好地处理多架构安装。 @@ -792,7 +800,7 @@ su - postgres - 如果使用 GCC,所有程序和库都会编译为可进行性能剖析的形式。后端退出时,会创建一个子目录,其中包含用于性能剖析的 gmon.out 文件。此选项仅用于使用 GCC 进行开发工作时。 + 如果使用 GCC,所有程序和库都会编译为可进行性能分析的形式。后端退出时,会创建一个子目录,其中包含用于性能分析的 gmon.out 文件。此选项仅用于使用 GCC 进行开发工作时。 @@ -800,11 +808,11 @@ su - postgres - 在服务器中启用 assertion 检查,用于测试许多 - 不应该发生的条件。这对代码开发非常有价值,但这些测试会显著拖慢 + 在服务器中启用 断言 检查,用于测试许多 + 不可能发生的条件。这对代码开发非常有价值,但这些测试可能会显著拖慢 服务器速度。此外,启用这些测试并不一定会增强服务器稳定性! 断言检查并未按严重程度分类,因此即使某个 bug 相对无害,只要触发了断言失败, - 仍可能导致服务器重启。该选项不建议用于生产环境,但如果你在做开发工作 + 仍会导致服务器重启。该选项不建议用于生产环境,但如果你在做开发工作 或运行测试版,就应当启用它。 @@ -854,7 +862,10 @@ su - postgres - 以下是可以通过这种方式设置的重要变量: + + 下面列出可以按这种方式设置的重要变量: + + BISON @@ -999,10 +1010,10 @@ su - postgres 有时,事后补充编译器标志会很有用;原有标志由 configure 选定。一个重要的例子是 gcc 选项不能包含在以下变量中:CFLAGS(该变量会传给 configure),因为它会破坏 configure 的许多内置测试。要添加此类标志,请将其放入 COPT 环境变量,再运行 makeCOPT 的内容会被加入以下两组选项:CFLAGSLDFLAGS;这两组选项原本由以下程序设置:configure。例如,你可以执行: -make COPT='-Werror' +make COPT='-Werror' 或者: -export COPT='-Werror' -make +export COPT='-Werror' +make @@ -1039,7 +1050,7 @@ All of PostgreSQL successfully made. Ready to install. - 如果要构建所有可构建的内容,包括文档(HTML 和 man 页面)及附加模块(contrib),请改为输入: + 如果要构建所有可构建的内容,包括文档(HTML 和手册页)及附加模块(contrib),请改为输入: make world 显示的最后一行应该是: PostgreSQL, contrib, and documentation successfully made. Ready to install. @@ -1208,10 +1219,15 @@ setenv LD_LIBRARY_PATH /usr/local/pgsql/lib bin 目录中。 - 如果不确定,请参阅系统的手册页(可能是 ld.sorld)。如果以后遇到类似以下的消息: + + 如果不确定,请参考你系统的手册页(可能是 ld.so + 或 rld)。如果你随后收到类似下面这样的消息: + psql: error in loading shared libraries libpq.so.2.1: cannot open shared object file: No such file or directory -则说明此步骤不可省略。届时补做即可。 + + 那就说明这一步确实是必须的。到那时再处理即可。 + @@ -1250,10 +1266,17 @@ libpq.so.2.1: cannot open shared object file: No such file or directory PostgreSQL 的使用方便得多。 - 为此,请将以下内容添加到 shell 启动文件中,例如 ~/.bash_profile(或者使用 /etc/profile,使其对所有用户生效): + + 为此,请把下面内容加到你的 shell 启动文件中,例如 + ~/.bash_profile(如果你希望影响所有用户,则用 + /etc/profile): + PATH=/usr/local/pgsql/bin:$PATH export PATH -如果使用 cshtcsh,则使用以下命令: + + 如果你使用的是 cshtcsh, + 则使用这条命令: + set path = ( /usr/local/pgsql/bin $path ) @@ -1283,7 +1306,7 @@ export MANPATH - 从头开始 + 开始使用 以下简要介绍安装后如何启动并运行 PostgreSQL。主文档包含更多信息。 @@ -1383,7 +1406,12 @@ kill `cat /usr/local/pgsql/data/postmaster.pid` 可以预期 PostgreSQL 能在以下操作系统上工作:Linux(所有近期发行版)、Windows(Win2000 SP4 及更高版本)、FreeBSD、OpenBSD、NetBSD、macOS、AIX、HP/UX 和 Solaris。其他类 Unix 系统也可能可用,但目前未在测试。大多数情况下,某个操作系统所支持的全部 CPU 架构也都可以工作。尤其是在使用较旧系统时,请查看下面的 ,看看是否有针对你的操作系统的特别说明。 - 如果近期构建农场的结果表明某个平台受支持,但你在该平台上遇到安装问题,请向 pgsql-bugs@lists.postgresql.org 报告。如果你有兴趣将 PostgreSQL 移植到新平台,可以在 pgsql-hackers@lists.postgresql.org 讨论。 + + 如果你在某个平台上遇到安装问题,而根据近期构建农场的结果该平台是受支持的, + 请把问题报告到 pgsql-bugs@lists.postgresql.org。 + 如果你有兴趣把 PostgreSQL 移植到一个新平台, + 那么 pgsql-hackers@lists.postgresql.org 是合适的讨论地点。 + @@ -1565,9 +1593,11 @@ ERROR: could not load library "/opt/dbs/pgsql/lib/plperl.so": Bad address - 并行回归测试(make check)可能因溢出而误报回归测试失败;溢出发生在 listen() 的待处理连接队列中,会导致连接被拒绝的错误或挂起。可以使用 make 变量 MAX_CONNECTIONS 限制连接数,方法如下: + 并行回归测试(make check)可能因 listen() 的待处理连接队列溢出而误报回归测试失败;队列溢出会导致连接被拒绝的错误或挂起。可以使用 make 变量 MAX_CONNECTIONS 限制连接数,方法如下: + make MAX_CONNECTIONS=5 check -(在某些系统上,并发连接数最高可达约 10 个。) + +(在某些系统上,并发连接数最高可达约 10 个。) @@ -1604,7 +1634,7 @@ PHSS_30849 s700_800 u2comp/be/plugin library Patch - 如果同时安装了 HP 的 C 编译器和 GCC,可以在运行以下命令时显式选择要使用的编译器:configure: + 如果同时安装了 HP 的 C 编译器和 GCC,可以在运行 configure 时显式选择要使用的编译器: ./configure CC=cc 这会选择 HP 的 C 编译器;或者执行: @@ -1674,7 +1704,7 @@ xcrun --show-sdk-path 这种情况并未经过 PostgreSQL 开发者测试,也不受支持。 - macOSSystem Integrity Protection(SIP)功能会破坏 make check,因为它会阻止将所需的 DYLD_LIBRARY_PATH 设置传给被测试的可执行文件。可以在 make check 之前先执行 make install 来规避这一问题。不过,大多数 Postgres 开发者会直接关闭 SIP。 + macOS系统完整性保护(SIP)功能会破坏 make check,因为它会阻止将所需的 DYLD_LIBRARY_PATH 设置传给被测试的可执行文件。可以在 make check 之前先执行 make install 来规避这一问题。不过,大多数 Postgres 开发者会直接关闭 SIP。 @@ -1694,7 +1724,7 @@ xcrun --show-sdk-path 安装好所有组件后,建议在 CMD.EXE 下运行 psql,因为 MSYS 控制台存在缓冲问题。 - 收集崩溃转储 + 在 Windows 上收集崩溃转储 如果 PostgreSQL 在 Windows 上崩溃,它能够生成 @@ -1724,14 +1754,14 @@ xcrun --show-sdk-path 你可以使用 GCC 或 Sun 编译器套件来构建。为了获得更好的代码优化,在 SPARC 架构上强烈推荐使用 Sun 编译器。我们收到过使用 GCC 2.95.1 时出现问题的报告;建议使用 GCC 2.95.3 或更高版本。如果使用 Sun 编译器,请注意不要选择 /usr/ucb/cc;应使用 /opt/SUNWspro/bin/cc - 你可以从 下载 Sun Studio。许多 GNU 工具已经集成到 Solaris 10 中,或者包含在 Solaris companion CD 中。如果你需要适用于较旧 Solaris 版本的软件包,可以到 查找这些工具。如果你更想要源码,请看 + 你可以从 下载 Sun Studio。许多 GNU 工具已经集成到 Solaris 10 中,或者包含在 Solaris 配套光盘中。如果你需要适用于较旧 Solaris 版本的软件包,可以到 查找这些工具。如果你更想要源码,请看 - configure 抱怨测试程序失败 + configure 报告测试程序失败 - 如果 configure 抱怨某个测试程序失败, + 如果 configure 报告某个测试程序失败, 这多半是因为运行时链接器找不到某些库,通常是 libz、libreadline, 或其他非标准库如 libssl。要把它指向正确位置,请在 configure 命令行中设置环境变量 LDFLAGS, diff --git a/zh/10/isn.sgml b/zh/10/isn.sgml index 02e1627e..1c6924b8 100644 --- a/zh/10/isn.sgml +++ b/zh/10/isn.sgml @@ -1,7 +1,7 @@ - isn — 国际标准编号(ISBN、EAN、UPC 等)的数据类型 + isn isn @@ -217,24 +217,24 @@ make_valid(isn)make_valid isn - - 设置弱输入模式,并返回新的设置值。 - + 使无效编号变为有效(清除无效标记) is_valid(isn)is_valid boolean - - 返回弱模式的当前状态。 - + 检查是否存在无效标记
- 模式用于将无效数据插入表中。无效是指校验位错误,而不是编号缺失。 + + 模式用于允许向表中插入无效数据。这里的“无效”指的是校验位错误,而不是缺少数字。 + - 为什么需要使用弱模式?例如,手头可能有一大批 ISBN 编号,数量多到难免会有一些编号因为某些奇怪的原因而带有错误的校验位(也许这些编号是从印刷清单扫描得到的,而 OCR 把数字识别错了;也许这些编号是人工录入的……谁知道呢)。总之,可能想把这些混乱情况清理干净,但同时仍希望先把所有编号都装入数据库,并借助外部工具在数据库中定位无效编号,以便核对信息并更容易完成校验;例如,可能会想把表中所有无效编号都查询出来。 + + 为什么会需要使用弱模式呢?例如,手头可能有一大批 ISBN 编号,数量多到难免会有一些编号因为某些奇怪的原因而带有错误的校验位(也许这些编号是从印刷清单扫描得到的,而 OCR 把数字识别错了;也许这些编号是人工录入的……谁知道呢)。总之,可能想把这些混乱情况清理干净,但同时仍希望先把所有编号都装入数据库,并借助外部工具在数据库中定位无效编号,以便核对信息并更容易完成校验;例如,可能会想把表中所有无效编号都查询出来。 + 当在弱模式下向表中插入无效编号时,实际插入的是校验位已更正的编号,但显示时会在末尾附加一个感叹号(!),例如0-11-000322-5!。可以用is_valid函数检查这个无效标记,并用make_valid函数清除它。 @@ -292,18 +292,26 @@ SELECT isbn13(id) FROM test; 参考文献 - 实现此模块所需的信息收集自多个网站,包括: + + 实现该模块所需的信息收集自若干网站,包括: + - 连字符化使用的前缀也收集自: + + + 用于进行连字符分隔的前缀还整理自: + - 在创建这些算法时十分谨慎,并根据官方 ISBN、ISMN、ISSN 用户手册中建议的算法进行了细致验证。 + + + 在创建这些算法时已十分谨慎,并依据官方 ISBN、ISMN、ISSN 用户手册中建议的算法进行了细致核验。 + diff --git a/zh/10/libpq.sgml b/zh/10/libpq.sgml index 35cb86a3..d9201174 100644 --- a/zh/10/libpq.sgml +++ b/zh/10/libpq.sgml @@ -33,7 +33,7 @@ 以下函数用于建立到PostgreSQL后端服务器的连接。应用程序可以同时保持多个后端连接。(这样做的原因之一是访问多个数据库。)每个连接由一个PGconnPGconn对象表示,该对象可以通过以下函数获取:PQconnectdbPQconnectdbParams,或PQsetdbLogin。注意,这些函数总是返回非空的对象指针,除非内存不足,甚至无法分配PGconn对象。应调用PQstatus函数检查返回值,确认连接成功后,再通过连接对象发送查询。 - 如果不可信用户能够访问一个没有采用模式的安全使用方式的数据库,那么每个会话开始时都应从search_path中移除公开可写的模式。可以把参数关键词options设置为-csearch_path=。也可以在连接后发出PQexec(conn, "SELECT pg_catalog.set_config('search_path', '', false)")。这种考虑并非专门针对libpq;它适用于每一种可执行任意 SQL 命令的接口。 + 如果不受信任的用户能够访问一个没有采用模式的安全使用方式的数据库,那么每个会话开始时都应从search_path中移除公开可写的模式。可以把参数关键词options设置为-csearch_path=。也可以在连接后发出PQexec(conn, "SELECT pg_catalog.set_config('search_path', '', false)")。这种考虑并非专门针对libpq;它适用于每一种可执行任意 SQL 命令的接口。 @@ -195,7 +195,7 @@ PostgresPollingStatusType PQconnectPoll(PGconn *conn); 无论是PQconnectStartParams还是PQconnectStart还是PQconnectPoll都不会阻塞,只要满足以下限制: - 必须正确使用 hostaddr 参数,避免执行 DNS 查询。详细信息请参见 中此参数的文档。 + 必须正确使用 hostaddr 参数,以避免执行 DNS 查询。详细信息请参见 中该参数的说明。 @@ -1282,20 +1282,31 @@ PGTransactionStatusType PQtransactionStatus(const PGconn *conn); PQparameterStatus PQparameterStatus - 查找服务器某个参数的当前设置。 + + 查找服务器某个参数的当前设置。 + + const char *PQparameterStatus(const PGconn *conn, const char *paramName); -服务器会在连接启动时,以及某些参数值发生变化时,自动报告这些参数值。PQparameterStatus可用于查询这些设置。如果已知该参数,则返回其当前值;如果未知,则返回NULL + - 当前版本报告的参数包括 server_versionserver_encodingclient_encodingapplication_nameis_superusersession_authorizationDateStyleIntervalStyleTimeZoneinteger_datetimesstandard_conforming_strings。(8.0 之前的版本不报告 server_encodingTimeZoneinteger_datetimes;8.1 之前的版本不报告 standard_conforming_strings;8.4 之前的版本不报告 IntervalStyle;9.0 之前的版本不报告 application_name。)注意,server_versionserver_encodinginteger_datetimes 在启动后不能改变。 + 服务器会在连接启动时,以及某些参数值发生变化时,自动报告这些参数值。PQparameterStatus可用于查询这些设置。如果已知该参数,则返回其当前值;如果未知,则返回NULL。 + + + + 当前版本报告的参数包括: + server_versionserver_encodingclient_encodingapplication_nameis_superusersession_authorizationDateStyleIntervalStyleTimeZoneinteger_datetimesstandard_conforming_strings。 + (8.0 之前的版本不报告 server_encodingTimeZoneinteger_datetimes;8.1 之前的版本不报告 standard_conforming_strings;8.4 之前的版本不报告 IntervalStyle;9.0 之前的版本不报告 application_name。) + 注意,server_versionserver_encodinginteger_datetimes 在启动后不能改变。 + 使用 3.0 之前协议的服务器不报告参数设置,但 libpq 仍包含获取 server_versionclient_encoding 值的逻辑。建议应用程序使用 PQparameterStatus,而不是专门编写代码来确定这些值。(但要注意,在使用 3.0 之前协议的连接上,连接启动后通过 SET 改变 client_encoding,不会反映在 PQparameterStatus 的结果中。)对于 server_version,另请参见 PQserverVersion,它以数值形式返回此信息,更易于比较。 - 如果没有为standard_conforming_strings报告值,应用能假设它是off,也就是说反斜线会被视为字符串中的转义。还有,这个参数的存在可以被作为转义字符串语法(E'...')被接受的指示。 + 如果服务器未报告standard_conforming_strings的值,应用程序可以假定其为off,即反斜杠在字符串字面量中被视为转义字符。此外,服务器报告此参数也表明它接受转义字符串语法(E'...')。 - 尽管被返回的指针被声明成const,它事实上指向与PGconn结构体相关的可变存储。假定该指针在存储之间保持有效是不明智的。 + 返回的指针虽然被声明为const,但实际上指向与PGconn结构体关联的可变存储。不能假定该指针在执行其他查询后仍然有效。 @@ -1665,7 +1676,7 @@ PGresult *PQexecParams(PGconn *conn, paramTypes[] - 通过 OID 指定要赋予给参数符号的数据类型。如果paramTypesNULL或者该数组中任何特定元素为零,服务器会用对待未知类型文字串的方式为参数符号推测一种数据类型。 + 通过 OID 指定要赋予给参数符号的数据类型。如果paramTypesNULL或者该数组中任何特定元素为零,服务器会用对待未指定类型的字符串字面量的方式为参数符号推测一种数据类型。 @@ -1757,7 +1768,7 @@ PGresult *PQprepare(PGconn *conn, 否则,如果语句名称已经在当前会话中被定义,则是一种错误。如果使用了任何参数,它们在查询中以$1$2等引用。 nParams是参数的个数,其类型在数组paramTypes[]中被预先指定(当nParams为零时,该数组指针可以是NULL)。 paramTypes[]通过 OID 指定要赋予给参数符号的数据类型。 - 如果paramTypesNULL或者该数组中任何特定元素为零,服务器会用对待未知类型文字串的方式为参数符号推测一种数据类型。 + 如果paramTypesNULL或者该数组中任何特定元素为零,服务器会用对待未指定类型的字符串字面量的方式为参数符号推测一种数据类型。 还有,查询能够使用编号高于nParams的参数符号,它们的数据类型也会被自动推测(找出推测出的数据类型的方法见PQdescribePrepared)。 @@ -2058,7 +2069,7 @@ char *PQresultErrorField(const PGresult *res, int fieldcode); PG_DIAG_MESSAGE_DETAIL - 细节:一个可选的次级错误消息,它携带了关于问题的等多细节。可能有多行。 + 细节:一个可选的次级错误消息,它携带了关于问题的更多细节。可能有多行。 @@ -2076,7 +2087,7 @@ char *PQresultErrorField(const PGresult *res, int fieldcode); PG_DIAG_STATEMENT_POSITION - 包含一个十进制整数的字符串,它表示一个错误游标位置,该位置是原始语句字符串的索引。第一个字符的索引是 1,位置以字符计算而不是以及字节计算。 + 包含一个十进制整数的字符串,它表示一个错误游标位置,该位置是原始语句字符串的索引。第一个字符的索引是 1,位置以字符计算而不是以字节计算。 @@ -2778,7 +2789,7 @@ unsigned char *PQescapeByteaConn(PGconn *conn, - 当某些字节值被用作一个SQL语句中的bytea文字的一部分时,它们必须被转义。 + 当某些字节值被用作一个SQL语句中的bytea字面量的一部分时,它们必须被转义。 PQescapeByteaConn使用十六进制编码或反斜杠转义来转义这些字节。详见 @@ -2819,19 +2830,26 @@ unsigned char *PQescapeBytea(const unsigned char *from, PQunescapeBytea PQunescapeBytea - 将二进制数据的字符串表示转换为二进制数据,这是以下函数的逆操作:PQescapeBytea。以文本格式取得bytea数据时需要此操作;以二进制格式取得时则不需要。 + + 将二进制数据的字符串表示转换为二进制数据,这是PQescapeBytea的逆操作。 + 以文本格式取得bytea数据时需要此操作;以二进制格式取得时则不需要。 + + unsigned char *PQunescapeBytea(const unsigned char *from, size_t *to_length); - from参数指向一个字符串,例如PQgetvalue被应用到一个bytea列上所返回的。 - PQunescapeBytea把这个串表示转换成它的二进制表示。 - 它返回一个指向用malloc()分配的缓冲区的指针,在错误时返回NULL,并且把缓冲区的尺寸放在to_length中。 - 当结果不再需要时,它必须使用PQfreemem释放。 + from参数指向一个字符串,例如对bytea列调用PQgetvalue时返回的字符串。 + PQunescapeBytea将这个字符串表示转换为二进制表示。 + 它返回指向通过malloc()分配的缓冲区的指针,出错时返回NULL,并将缓冲区大小存入to_length。 + 不再需要结果时,必须使用PQfreemem释放它。 - 此转换并不完全是 PQescapeBytea 的逆操作,因为从 PQgetvalue 收到的字符串不应已经过转义。具体而言,这意味着无需考虑字符串引号,因此也不需要 PGconn 参数。 + + 此转换并不完全是PQescapeBytea的逆操作,因为从PQgetvalue收到的字符串并非经过转义的形式。 + 具体而言,这意味着无需考虑字符串引号,因此也不需要PGconn参数。 + @@ -3287,7 +3305,7 @@ typedef struct - 要传递NULL参数到函数,将参数结构体的len字段设置为-1;isintu 字段就不相关了。(但这仅适用于使用协议 3.0 及更高版本的连接。) + 要传递NULL参数到函数,将参数结构体的len字段设置为-1isintu 字段就不相关了。(但这仅适用于使用协议 3.0 及更高版本的连接。)
如果函数返回 NULL,则将 *result_len 设为 -1,而不修改 *result_buf。(这仅适用于使用协议 3.0 及更高版本的连接;在协议 2.0 中,既不修改 *result_len,也不修改 *result_buf。) @@ -3868,11 +3886,12 @@ PGresult *PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status); 这是libpq内部用于分配并初始化一个空PGresult对象的函数。 - 如果不能分配内存,那么这个函数返回NULL。 - 它也是可以对外使用的,因为一些应用需要自行生成结果对象(特别是带有错误状态的对象)。 - 如果conn非空,并且status表示一个错误,那么指定连接的当前错误消息会被复制到PGresult中。 - 如果conn非空,那么连接中的任何已注册事件过程也会被复制到PGresult中(它们不会获得PGEVT_RESULTCREATE调用,但可参见PQfireResultCreateEvents)。 - 注意在该对象上最终应该调用PQclear,正如对libpq本身返回的PGresult对象所作的那样。 + 如果无法分配内存,此函数返回NULL。 + 将它导出供外部调用,是因为一些应用需要自行生成结果对象,特别是带有错误状态的对象。 + 如果conn非空,并且status表示错误,指定连接的当前错误消息会被复制到PGresult中。 + 此外,如果conn非空,连接中注册的所有事件过程也会被复制到PGresult中。 + (这些过程不会收到PGEVT_RESULTCREATE调用,但可参见PQfireResultCreateEvents。) + 注意,最终应对该对象调用PQclear,就像处理libpq自身返回的PGresult一样。
@@ -4148,13 +4167,25 @@ typedef struct PGEVT_RESULTCREATE - 任何生成结果的查询执行函数都会触发结果创建事件,其中包括PQgetResult。只有成功创建结果后才会触发该事件。 + + 任何生成结果的查询执行函数都会触发结果创建事件,其中包括PQgetResult。 + 只有成功创建结果后才会触发该事件。 + + typedef struct { PGconn *conn; PGresult *result; } PGEventResultCreate; -收到PGEVT_RESULTCREATE事件时,应将evtInfo指针强制转换为PGEventResultCreate *。其中,conn是用于生成结果的连接。这是初始化需要与结果关联的instanceData的理想位置。如果事件处理函数失败,结果会被清除,失败也会向外传递。事件处理函数不得自行调用PQclear来清除结果对象。返回失败代码时,必须完成所有清理工作,因为不会发送PGEVT_RESULTDESTROY事件。 + + + 收到PGEVT_RESULTCREATE事件时,应将evtInfo指针转换为PGEventResultCreate *。 + 其中,conn是用于生成结果的连接。 + 这是初始化需要与结果关联的instanceData的理想位置。 + 如果事件过程失败,结果会被清除,失败也会向外传递。 + 事件过程不得自行调用PQclear来清除结果对象。 + 返回失败代码时,必须完成所有清理工作,因为不会发送PGEVT_RESULTDESTROY事件。 + @@ -4796,13 +4827,8 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough) - 用户的主目录中的文件.pgpass可以包含密码, - 如果连接需要密码(且未指定其他密码)。在Microsoft Windows中, - 该文件的名称为%APPDATA%\postgresql\pgpass.conf - (其中%APPDATA%指用户配置文件中的应用数据子目录)。 - 或者,可以使用连接参数 - 或环境变量PGPASSFILE指定要使用的密码文件。 - + 用户主目录中的.pgpass文件可保存密码,供连接需要密码且尚未通过其他方式指定密码时使用。在 Microsoft Windows 上,文件名为%APPDATA%\postgresql\pgpass.conf(其中%APPDATA%指用户配置文件中的应用数据子目录)。也可以通过连接参数或环境变量PGPASSFILE指定要使用的密码文件。 +
该文件中的行应采用以下格式: hostname:port:database:username:password @@ -5236,8 +5262,8 @@ void PQinitSSL(int do_ssl); 在线程化程序中的行为 - threads - with libpq + 线程 + 用于 libpq libpq 默认是可重入且线程安全的。编译应用程序代码时,可能需要使用特殊的编译器命令行选项。有关如何构建支持线程的应用程序,请参阅系统文档,或查看 src/Makefile.global 中的 PTHREAD_CFLAGSPTHREAD_LIBS。以下函数可用于查询 libpq 的线程安全状态: @@ -5255,7 +5281,7 @@ int PQisthreadsafe(); - 如果libpq是线程安全的则返回 1,否则返回 0。在版本 17 及以上始终返回 1。 + 如果libpq是线程安全的则返回 1,否则返回 0。 diff --git a/zh/10/logical-replication.sgml b/zh/10/logical-replication.sgml index b29fdefd..779eed6e 100644 --- a/zh/10/logical-replication.sgml +++ b/zh/10/logical-replication.sgml @@ -201,7 +201,12 @@ - 数据库模式和DDL命令不会被复制。初始模式可使用pg_dump --schema-only手动复制。后续的模式变更需要手动保持同步。(注意,两端的模式不需要完全相同。)当数据库模式在运行中发生变更时,逻辑复制是健壮的:当发布端模式变更后,复制的数据开始到达订阅端但不符合表的模式时,复制会出错,直到模式被更新。在很多情况下,通过先在订阅端应用增量式模式变更,可以避免间歇性错误。 + 数据库模式和 DDL 命令不会被复制。初始模式可以手工使用 + pg_dump --schema-only 复制。之后的模式更改需要手工保持同步。 + (不过请注意,两端的模式其实不需要绝对一致。)当活动数据库中的模式定义发生变化时, + 逻辑复制仍然能够稳健运行:如果发布端修改了模式,而复制数据开始到达订阅端时 + 与表模式不匹配,复制就会报错,直到模式被更新。在很多情况下,可以通过先在订阅端 + 应用仅添加内容的模式变更来避免间歇性错误。 @@ -235,13 +240,13 @@
- 逻辑复制采用类似于物理流复制的架构(见)。它由walsenderapply进程实现。walsender 进程启动 WAL 的逻辑解码(见),并加载标准逻辑解码输出插件(pgoutput)。该插件将从 WAL 读取的变更转换为逻辑复制协议(见),并根据发布规范过滤数据。然后使用流复制协议将数据持续传输给 apply 工作进程,该工作进程将数据映射到本地表,并按正确的事务顺序逐一应用每个变更。 + 逻辑复制采用类似于物理流复制的架构(见)。它由walsenderapply进程实现。walsender 进程启动 WAL 的逻辑解码(见),并加载标准逻辑解码输出插件(pgoutput)。该插件将从 WAL 读取的变更转换为逻辑复制协议(见),并根据发布规范过滤数据。然后使用流复制协议将数据持续传输给 应用工作进程,该工作进程将数据映射到本地表,并按正确的事务顺序逐一应用每个变更。 订阅端数据库上的应用进程总是在 session_replication_role 设为 replica 的情况下运行,这会对触发器和约束产生通常的影响。 - 逻辑复制的apply进程目前只触发行触发器,不触发语句触发器。但初始表同步的实现方式类似于COPY命令,因此会触发INSERT的行触发器和语句触发器。 + 逻辑复制的应用进程目前只触发行触发器,不触发语句触发器。但初始表同步的实现方式类似于COPY命令,因此会触发INSERT的行触发器和语句触发器。 @@ -264,7 +269,7 @@ - 正常情况下,已启用的订阅会有一个apply进程在运行。被禁用或已崩溃的订阅在此视图中将有零行。如果任何表的初始数据同步正在进行中,将有额外的工作进程用于正在同步的表。 + 正常情况下,已启用的订阅会有一个应用进程在运行。被禁用或已崩溃的订阅在此视图中将有零行。如果任何表的初始数据同步正在进行中,将有额外的工作进程用于正在同步的表。 @@ -296,7 +301,7 @@ - 订阅的apply进程将以超级用户的权限在本地数据库上运行。 + 订阅应用进程将以超级用户的权限在本地数据库中运行。 diff --git a/zh/10/maintenance.sgml b/zh/10/maintenance.sgml index 241c4d00..c4e02ae1 100644 --- a/zh/10/maintenance.sgml +++ b/zh/10/maintenance.sgml @@ -397,12 +397,9 @@ SELECT datname, age(datfrozenxid) FROM pg_database; - 虽然 VACUUM 主要扫描自上次清理以来被修改过的页面, - 但它也可能为了冻结它们而积极扫描某些全部可见但未全部冻结的页面; - 不过,只有当表中每一个可能包含未冻结 XID 的页面都被扫描时, - relfrozenxid 才会被推进。当 - relfrozenxid 比 - vacuum_freeze_table_age 旧、使用了 VACUUM 的 + VACUUM通常只扫描自上次清理以来被修改过的页面,但只有当表中每一个可能包含未冻结 XID 的页面都被扫描时, + relfrozenxid 才会被推进。当 + relfrozenxid的年龄超过vacuum_freeze_table_age个事务、使用了 VACUUMFREEZE 选项,或者所有尚未全部冻结的页面碰巧都需要清理以移除死行版本时, 就会发生这种情况。当 VACUUM 扫描了表中每个尚未全部冻结的页面时, 它应把 age(relfrozenxid) 设为略高于所用 @@ -433,14 +430,14 @@ HINT: Stop the postmaster and vacuum that database in single-user mode. 多事务 ID 的 - 多事务 ID 用于支持多个事务对行加锁。由于元组头中存放锁信息的空间有限,当多个事务同时锁定一行时,这些信息会被编码为一个多事务 ID,简称 multixact ID。某个特定 multixact ID 包含哪些事务 ID 的信息,单独存放在 pg_multixact 子目录中,元组头的 xmax 字段中只保存 multixact ID。与事务 ID 一样,multixact ID 由 32 位计数器和相应的存储实现,都需要谨慎处理老化管理、存储清理和回卷。另有单独的存储区保存每个 multixact 的成员列表,它同样使用 32 位计数器,也需要管理。 + 多事务 ID 用于支持多个事务对行加锁。由于元组头中存放锁信息的空间有限,当多个事务同时锁定一行时,这些信息会被编码为一个多事务 ID,简称 multixact ID。某个特定 多事务 ID 包含哪些事务 ID 的信息,单独存放在 pg_multixact 子目录中,元组头的 xmax 字段中只保存 多事务 ID。与事务 ID 一样,多事务 ID 由 32 位计数器和相应的存储实现,都需要谨慎处理老化管理、存储清理和回卷。另有单独的存储区保存每个 多事务 的成员列表,它同样使用 32 位计数器,也需要管理。 每当 VACUUM 扫描表的任何部分时,它都会把遇到的、早于 - 的任何 multixact ID 替换为另一个值,该值可能是零值、单个事务 ID,或者更新的 multixact ID。 + 的任何 多事务 ID 替换为另一个值,该值可能是零值、单个事务 ID,或者更新的 多事务 ID。 对于每个表,pg_class.relminmxid - 保存该表任何元组中仍可能出现的最老 multixact ID。如果这个值早于 + 保存该表任何元组中仍可能出现的最老 多事务 ID。如果这个值早于 ,就会强制执行一次激进扫描。 正如上一节所述,激进扫描意味着只有那些已知为全部冻结的页面才会被跳过。 可以对 pg_class.relminmxid @@ -449,10 +446,10 @@ HINT: Stop the postmaster and vacuum that database in single-user mode. 无论出于何种原因而发生,激进的 VACUUM 扫描都能推进该表的值。最终,随着所有数据库中的所有表都被扫描, - 并推进其最老的 multixact 值,较老 multixact 的磁盘存储就可以被移除。 + 并推进其最老的 多事务 值,较老 多事务 的磁盘存储就可以被移除。 - 作为一项安全措施,对于 multixact 年龄大于 的任何表,都会执行激进清理扫描。如果已使用的成员存储空间超过可寻址存储空间的 50%,还会从 multixact 年龄最大的表开始,逐步对所有表执行激进清理扫描。即使名义上禁用了自动清理,这两类激进扫描也都会发生。 + 作为一项安全措施,对于 多事务 年龄大于 的任何表,都会执行激进清理扫描。如果已使用的成员存储空间超过可寻址存储空间的 50%,还会从 多事务 年龄最大的表开始,逐步对所有表执行激进清理扫描。即使名义上禁用了自动清理,这两类激进扫描也都会发生。 @@ -652,7 +649,7 @@ pg_ctl start | rotatelogs /var/log/pgsql_log 86400 不过,在很多系统上,syslog 并不十分可靠, 尤其是在日志消息很大时;它可能恰恰在你最需要消息的时候截断或丢弃它们。 此外,在 Linux 上, - syslog 会把每条消息都刷新到磁盘,导致性能较差。 + syslog 会把每条消息都刷盘,导致性能较差。 (你可以在 syslog 配置文件的文件名开头使用一个 - 来禁用同步。) diff --git a/zh/10/monitoring.sgml b/zh/10/monitoring.sgml index 8cbf0693..5955bd64 100644 --- a/zh/10/monitoring.sgml +++ b/zh/10/monitoring.sgml @@ -76,14 +76,14 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 统计收集器 - statistics + 统计信息 PostgreSQL统计收集器是一个支持收集和报告服务器活动信息的子系统。 - 目前,对表和索引的访问以磁盘块和单个行的术语进行计数。每个表中的总行数, - 以及每个表的清理和分析操作的信息也被计数。如果启用,对用户定义函数的调用 - 和每个函数中花费的总时间也会被计数。 + 目前,对表和索引的访问分别以磁盘块和单行计数。每个表中的总行数, + 以及每个表的清理和分析操作的信息也被计数。它还可以统计对用户定义函数的调用 + 和每个函数中花费的总时间。 @@ -140,7 +140,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - 另一个重要点是,当要求服务器进程显示这些统计信息中的任何一种时,它会先取回收集器进程最近发出的报告,然后在当前事务结束之前,对所有统计视图和函数一直使用这一快照。因此,只要你继续当前事务,统计信息就会显示静态信息。类似地,在事务中第一次请求任意当前会话的查询信息时,就会收集所有会话当前查询的信息,并且在整个事务期间显示的都是同一份信息。这是一个特性,而不是一个错误,因为它允许你对统计信息执行多个查询并对结果做关联,而不必担心数字在你眼前变化。但如果希望每个查询都看到新的结果,请确保在任何事务块之外执行这些查询。或者,也可以调用pg_stat_clear_snapshot(),它会丢弃当前事务的统计快照(如果有)。下一次使用统计信息时,就会获取一个新的快照。 + 另一个重要点是,当要求服务器进程显示这些统计信息中的任何一种时,它会先取回收集器进程最近发出的报告,然后在当前事务结束之前,对所有统计视图和函数一直使用这一快照。因此,只要你继续当前事务,统计信息就会显示静态信息。类似地,在事务中第一次请求这类当前查询信息时,就会收集所有会话当前查询的信息,并且在整个事务期间显示的都是同一份信息。这是一个特性,而不是一个错误,因为它允许你对统计信息执行多个查询并对结果做关联,而不必担心数字在你眼前变化。但如果希望每个查询都看到新的结果,请确保在任何事务块之外执行这些查询。或者,也可以调用pg_stat_clear_snapshot(),它会丢弃当前事务的统计快照(如果有)。下一次使用统计信息时,就会获取一个新的快照。 @@ -216,122 +216,123 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser + pg_stat_archiverpg_stat_archiver 只有一行,显示 WAL 归档进程活动的统计信息。详见 - + pg_stat_bgwriterpg_stat_bgwriter - 只有一行,显示后台写入进程活动的统计信息。详见 + 只有一行,显示后台写入器活动的统计信息。详见 - + pg_stat_databasepg_stat_database 每个数据库一行,显示整个数据库的统计信息。详见 - + pg_stat_database_conflictspg_stat_database_conflicts 每个数据库一行,显示备库上因与恢复冲突而取消查询的数据库范围统计信息。详见 - + pg_stat_all_tablespg_stat_all_tables 当前数据库中的每个表一行,显示访问该表的统计信息。详见 - + pg_stat_sys_tablespg_stat_sys_tables pg_stat_all_tables一样,但只显示系统表。 - + pg_stat_user_tablespg_stat_user_tables pg_stat_all_tables一样,但只显示用户表。 - + pg_stat_xact_all_tablespg_stat_xact_all_tables - pg_stat_all_tables相似,但计数动作只在当前事务内发生(还没有被包括在pg_stat_all_tables和相关视图中)。用于生存和死亡行数量的列以及清理和分析动作在此视图中不出现。 + pg_stat_all_tables 相似,但只统计当前事务中截至目前执行的操作(这些操作尚计入 pg_stat_all_tables 及相关视图)。此视图不包含存活行和死行数量以及清理、分析操作的列。 - + pg_stat_xact_sys_tablespg_stat_xact_sys_tables pg_stat_xact_all_tables一样,但只显示系统表。 - + pg_stat_xact_user_tablespg_stat_xact_user_tables pg_stat_xact_all_tables一样,但只显示用户表。 - + pg_stat_all_indexespg_stat_all_indexes 当前数据库中的每个索引一行,显示访问该索引的统计信息。详见 - + pg_stat_sys_indexespg_stat_sys_indexes pg_stat_all_indexes一样,但只显示系统表上的索引。 - + pg_stat_user_indexespg_stat_user_indexes pg_stat_all_indexes一样,但只显示用户表上的索引。 - + pg_statio_all_tablespg_statio_all_tables 当前数据库中的每个表一行,显示该表的 I/O 统计信息。详见 - + pg_statio_sys_tablespg_statio_sys_tables pg_statio_all_tables一样,但只显示系统表。 - + pg_statio_user_tablespg_statio_user_tables pg_statio_all_tables一样,但只显示用户表。 - + pg_statio_all_indexespg_statio_all_indexes 当前数据库中的每个索引一行,显示该索引的 I/O 统计信息。详见 - + pg_statio_sys_indexespg_statio_sys_indexes pg_statio_all_indexes一样,但只显示系统表上的索引。 - + pg_statio_user_indexespg_statio_user_indexes pg_statio_all_indexes一样,但只显示用户表上的索引。 - + pg_statio_all_sequencespg_statio_all_sequences 当前数据库中的每个序列一行,显示该序列的 I/O 统计信息。详见 - + pg_statio_sys_sequencespg_statio_sys_sequences pg_statio_all_sequences一样,但只显示系统序列(目前没有定义系统序列,因此这个视图总是为空)。 - + pg_statio_user_sequencespg_statio_user_sequences pg_statio_all_sequences一样,但只显示用户序列。 - + pg_stat_user_functionspg_stat_user_functions 每个被跟踪的函数一行,显示该函数执行的统计信息。详见 - + pg_stat_xact_user_functionspg_stat_xact_user_functions pg_stat_user_functions相似,但是只统计在当前事务期间的调用(还没有被包括在pg_stat_user_functions中)。 @@ -413,7 +414,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser client_addr inet - 连接到这个后端的客户端的 IP 地址。如果这个字段为空,它表示客户端通过服务器机器上的一个 Unix 套接字连接或者这是一个内部进程,如自动清理。 + 连接到这个后端的客户端的 IP 地址。如果这个字段为空值,它表示客户端通过服务器机器上的一个 Unix 套接字连接或者这是一个内部进程,如自动清理。 @@ -440,8 +441,8 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser xact_start timestamp with time zone - 这个进程的当前事务被启动的时间,如果没有活动事务则为空。 - 如果当前查询是它的第一个事务,这一列等于query_start列。 + 这个进程的当前事务被启动的时间,如果没有活动事务则为空值。 + 如果当前查询是其事务中的第一个查询,这一列等于query_start列。 @@ -461,7 +462,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser wait_event_type text - 后端正在等待的事件类型(如果有),否则为 NULL。可能的值为: + 后端正在等待的事件类型(如果有),否则为空值。可能的值为: LWLock:后端正在等待轻量级锁。每个这样的锁保护共享内存中的某个特定数据结构。wait_event将包含标识该轻量级锁用途的名称。(有些锁具有专门的名称,另一些锁属于一组用途相似的锁。) @@ -495,32 +496,32 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser wait_event text - 如果后端当前正在等待,则为等待事件名称,否则为 NULL。详见 + 如果后端当前正在等待,则为等待事件名称,否则为空值。详见 state text 该后端当前的总体状态。可能的值为: - - active:后端正在执行一个查询。 - - - idle:后端正在等待新的客户端命令。 - - - idle in transaction:后端处于事务中,但当前没有执行查询。 - - - idle in transaction (aborted):该状态与idle in transaction类似,但事务中的某个语句导致了错误。 - - - fastpath function call:后端正在执行一个快速路径函数。 - - - disabled:如果在此后端中禁用了,就会报告此状态。 - + + active:后端正在执行一个查询。 + + + idle:后端正在等待新的客户端命令。 + + + idle in transaction:后端处于事务中,但当前没有执行查询。 + + + idle in transaction (aborted):该状态与idle in transaction类似,但事务中的某个语句导致了错误。 + + + fastpath function call:后端正在执行一个快速路径函数。 + + + disabled:如果在此后端中禁用了,就会报告此状态。 + - + backend_xid @@ -533,7 +534,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser backend_xmin xid - 当前后端的xmin范围。 + 当前后端的xmin视界。 @@ -577,7 +578,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - LWLock + LWLock ShmemIndexLock 等待在共享内存中找到或分配空间。 @@ -585,754 +586,753 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser OidGenLock 等待分配或指派 OID。 - + XidGenLock 等待分配或指派事务 ID。 - + ProcArrayLock 等待获取快照,或在事务结束时清除事务 ID。 - + SInvalReadLock 等待从共享失效队列中取出或移除消息。 - + SInvalWriteLock 等待向共享失效队列添加消息。 - + WALBufMappingLock 等待在WAL缓冲区中替换一个页面。 - + WALWriteLock 等待WAL缓冲区写入磁盘。 - + ControlFileLock 等待读取或更新控制文件,或创建新的 WAL 文件。 - + CheckpointLock 等待执行检查点。 - + CLogControlLock 等待读取或更新事务状态。 - + SubtransControlLock 等待读取或更新子事务信息。 - + MultiXactGenLock - 等待读取或更新共享的multixact状态。 + 等待读取或更新共享的多事务状态。 - + MultiXactOffsetControlLock 等待读取或更新多事务偏移映射。 - + MultiXactMemberControlLock 等待读取或更新多事务成员映射。 - + RelCacheInitLock 等待读取或写入关系缓存初始化文件。 - + CheckpointerCommLock 等待管理fsync请求。 - + TwoPhaseStateLock - 等待读取或更新已准备事务的状态。 + 等待读取或更新预备事务的状态。 - + TablespaceCreateLock 等待创建或删除表空间。 - + BtreeVacuumLock 等待读取或更新B-树索引的清理相关信息。 - + AddinShmemInitLock 等待管理共享内存中的空间分配。 - + AutovacuumLock 自动清理工作进程或启动进程正在等待更新或读取自动清理工作进程的当前状态。 - + AutovacuumScheduleLock 等待确认已选定要清理的表仍然需要清理。 - + SyncScanLock 等待获取同步扫描所用的表扫描起始位置。 - + RelationMappingLock - 等待更新用于存储目录到文件节点映射的关系映射文件。 + 等待更新用于存储系统目录到文件节点映射的关系映射文件。 - + AsyncCtlLock 等待读取或更新共享通知状态。 - + AsyncQueueLock 等待读取或更新通知消息。 - + SerializableXactHashLock - 等待获取或存储可序列化事务的信息。 + 等待获取或存储可串行化事务的信息。 - + SerializableFinishedListLock 等待访问已完成的可串行化事务列表。 - + SerializablePredicateLockListLock - 等待对可序列化事务所持有的锁列表执行操作。 + 等待对可串行化事务所持有的锁列表执行操作。 - + OldSerXidLock - 等待读取或记录相互冲突的可序列化事务。 + 等待读取或记录相互冲突的可串行化事务。 - + SyncRepLock 等待读取或更新同步副本的信息。 - + BackgroundWorkerLock 等待读取或更新后台工作进程状态。 - + DynamicSharedMemoryControlLock 等待读取或更新动态共享内存状态。 - + AutoFileLock 等待更新postgresql.auto.conf文件。 - + ReplicationSlotAllocationLock 等待分配或释放复制槽。 - + ReplicationSlotControlLock 等待读取或更新复制槽状态。 - + CommitTsControlLock 等待读取或更新事务提交时间戳。 - + CommitTsLock 等待读取或更新最近设置的事务时间戳值。 - + ReplicationOriginLock 等待设置、删除或使用复制源。 - + MultiXactTruncationLock - 等待读取或截断multixact信息。 + 等待读取或截断多事务信息。 - + OldSnapshotTimeMapLock 等待读取或更新旧的快照控制信息。 - + BackendRandomLock 等待生成随机数。 - + LogicalRepWorkerLock 等待对逻辑复制工作进程的操作完成。 - + CLogTruncationLock 等待执行txid_status,或更新该函数可用的最早事务 ID。 - + WrapLimitsVacuumLock - 等待更新事务 ID和multixact消费的限制。 + 等待更新事务 ID 和多事务消耗量的限制。 - + NotifyQueueTailLock 等待更新通知消息存储的限制。 - + clog 等待 clog(事务状态)缓冲区上的 I/O。 - + commit_timestamp 等待提交时间戳缓冲区上的 I/O。 - + subtrans 等待子事务缓冲区上的 I/O。 - + multixact_offset - 等待多事务偏移缓冲区上的 I/O。 + 等待多事务偏移量缓冲区上的 I/O。 - + multixact_member 等待 multixact_member 缓冲区上的 I/O。 - + async 等待 async(通知)缓冲区上的 I/O。 - + oldserxid 等待 oldserxid 缓冲区上的 I/O。 - + wal_insert 等待将 WAL 插入内存缓冲区。 - + buffer_content 等待读取或写入内存中的数据页。 - + buffer_io 等待数据页上的 I/O。 - + replication_origin 等待读取或更新复制进度。 - + replication_slot_io 在复制槽上等待I/O。 - + proc 等待读取或更新快速路径锁信息。 - + buffer_mapping 等待将数据块与缓冲池中的缓冲区关联。 - + lock_manager 等待添加或检查后端的锁,或者等待加入或退出锁组(用于并行查询)。 - + predicate_lock_manager 等待添加或检查谓词锁信息。 - + parallel_query_dsa 等待并行查询的动态共享内存分配锁。 - + tbm 等待 TBM 共享迭代器锁。 - - Lock - relation - 等待获得一个关系的锁。 + + Lock + relation + 等待获取关系上的锁。 - - extend + + extend 等待扩展一个关系。 - + frozenid - 等待升级 pg_database.datfrozenxid - 和 pg_database.datminmxid. + 等待更新 pg_database.datfrozenxidpg_database.datminmxid - - page + + page 等待获取关系页上的锁。 - - tuple + + tuple 等待获取元组上的锁。 - - transactionid + + transactionid 等待事务完成。 - - virtualxid + + virtualxid 等待获取虚拟事务 ID 锁。 - + speculative token - 等待获取推测的插入锁。 + 等待获取推测插入锁。 - - object + + object 等待获取非关系数据库对象上的锁。 - - userlock + + userlock 等待获取用户锁。 - - advisory - 等待获得一个建议用户锁。 + + advisory + 等待获取用户咨询锁。 - - BufferPin - BufferPin + + BufferPin + BufferPin 等待获取缓冲区上的钉住。 - - Activity - ArchiverMain + + Activity + ArchiverMain 在归档进程的主循环中等待。 - - AutoVacuumMain - 在自动清理启动过程的主循环中等待。 + + AutoVacuumMain + 在自动清理启动进程的主循环中等待。 - - BgWriterHibernate - 在后台写入器中等待,休眠状态。 + + BgWriterHibernate + 在后台写入器进程中休眠等待。 - - BgWriterMain - 在后台写入进程这一后台工作进程的主循环中等待。 + + BgWriterMain + 在后台写入器进程(后台工作进程)的主循环中等待。 - - CheckpointerMain + + CheckpointerMain 在检查点进程的主循环中等待。 - + LogicalApplyMain 在逻辑应用进程的主循环中等待。 - + LogicalLauncherMain 在逻辑启动进程的主循环中等待。 - + PgStatMain 在统计收集器进程的主循环中等待。 - + RecoveryWalAll 在恢复期间等待来自流的 WAL。 - - RecoveryWalStream + + RecoveryWalStream 在恢复期间,若所有来源(本地、归档或流)都没有可用的 WAL 数据,则在重新尝试获取 WAL 数据前等待。 - - SysLoggerMain + + SysLoggerMain 在 syslogger 进程的主循环中等待。 - - WalReceiverMain - 在WAL 接收进程的主循环中等待。 + + WalReceiverMain + 在 WAL 接收进程的主循环中等待。 - - WalSenderMain + + WalSenderMain 在 WAL 发送进程的主循环中等待。 - - WalWriterMain - 在WAL写入进程的主循环中等待。 + + WalWriterMain + 在 WAL 写入进程的主循环中等待。 - - Client - ClientRead + + Client + ClientRead 等待从客户端读取数据。 - - ClientWrite + + ClientWrite 等待写入数据到客户端。 - - LibPQWalReceiverConnect - 在WAL 接收进程等待与远程服务器建立连接。 + + LibPQWalReceiverConnect + 在 WAL 接收进程中等待与远程服务器建立连接。 - - LibPQWalReceiverReceive - 在WAL 接收进程中等待从远程服务器接收数据。 + + LibPQWalReceiverReceive + 在 WAL 接收进程中等待从远程服务器接收数据。 - - SSLOpenServer + + SSLOpenServer 在尝试连接时等待SSL。 - - WalReceiverWaitStart + + WalReceiverWaitStart 等待启动进程为流复制发送初始数据。 - - WalSenderWaitForWAL - 在 WAL 发送进程中等待 WAL 被刷新。 + + WalSenderWaitForWAL + 在 WAL 发送进程中等待 WAL 刷盘。 - - WalSenderWriteData + + WalSenderWriteData 在 WAL 发送进程中处理 WAL 接收进程的回复时,等待任何活动。 - - Extension - Extension + + Extension + Extension 在扩展中等待。 - - IPC - BgWorkerShutdown + + IPC + BgWorkerShutdown 等待后台工作进程关闭。 - - BgWorkerStartup + + BgWorkerStartup 等待后台工作进程启动。 - - BtreePage - 正等待继续并行B-树扫描所需的页号变得可用。 + + BtreePage + 等待继续并行 B-树扫描所需的页号变得可用。 - - ExecuteGather + + ExecuteGather 在执行Gather节点时等待子进程的活动。 - - LogicalSyncData + + LogicalSyncData 等待逻辑复制远程服务器为初始表同步发送数据。 - - LogicalSyncStateChange + + LogicalSyncStateChange 等待逻辑复制远程服务器改变状态。 - - MessageQueueInternal + + MessageQueueInternal 等待其他进程附加到共享消息队列。 - - MessageQueuePutMessage + + MessageQueuePutMessage 等待将协议消息写入共享消息队列。 - - MessageQueueReceive + + MessageQueueReceive 等待从共享消息队列接收字节。 - - MessageQueueSend + + MessageQueueSend 等待将字节发送到共享消息队列。 - + ParallelBitmapScan - 等待并行位图扫描被初始化。 + 等待并行位图扫描完成初始化。 - + ParallelFinish - 等待并行工作人员完成计算。 + 等待并行工作进程完成计算。 - + ProcArrayGroupUpdate 等待组领导者在事务结束时清除事务 ID。 - + ReplicationOriginDrop 等待复制源变为非活动状态,以便将其删除。 - - ReplicationSlotDrop + + ReplicationSlotDrop 等待复制槽变为非活动状态,以便将其删除。 - - SafeSnapshot + + SafeSnapshot 等待READ ONLY DEFERRABLE事务的快照。 - - SyncRep + + SyncRep 在同步复制期间等待远程服务器的确认。 - - Timeout - BaseBackupThrottle - 当有限流活动时在基础备份期间等待。 + + Timeout + BaseBackupThrottle + 在基础备份期间因限流而等待。 - - PgSleep + + PgSleep 调用pg_sleep的进程正在等待。 - - RecoveryApplyDelay + + RecoveryApplyDelay 在恢复期间,由于应用 WAL 被延迟而等待。 - - IO - BufFileRead + + IO + BufFileRead 等待从缓冲文件中读取。 - - BufFileWrite + + BufFileWrite 等待对缓冲文件的写入。 - - ControlFileRead + + ControlFileRead 等待读取控制文件。 - - ControlFileSync - 等待控制文件写入持久存储。 + + ControlFileSync + 等待控制文件同步到持久存储。 - - ControlFileSyncUpdate - 等待控制文件的更新写入持久存储。 + + ControlFileSyncUpdate + 等待对控制文件的更新同步到持久存储。 - - ControlFileWrite + + ControlFileWrite 等待写入控制文件。 - - ControlFileWriteUpdate + + ControlFileWriteUpdate 等待写入以更新控制文件。 - - CopyFileRead + + CopyFileRead 在文件复制操作期间等待读取。 - - CopyFileWrite - 在文件拷贝操作期间等待写入。 + + CopyFileWrite + 在文件复制操作期间等待写入。 - - DataFileExtend + + DataFileExtend 等待关系数据文件被扩展。 - - DataFileFlush - 等待关系数据文件达到持久存储。 + + DataFileFlush + 等待关系数据文件同步到持久存储。 - - DataFileImmediateSync - 等待关系数据文件到持久存储的立即同步。 + + DataFileImmediateSync + 等待关系数据文件立即同步到持久存储。 - - DataFilePrefetch + + DataFilePrefetch 等待关系数据文件的异步预取。 - - DataFileRead + + DataFileRead 等待对关系数据文件的读取。 - - DataFileSync - 等待对关系数据文件的更改达到持久存储。 + + DataFileSync + 等待对关系数据文件的更改同步到持久存储。 - - DataFileTruncate + + DataFileTruncate 等待关系数据文件被截断。 - - DataFileWrite + + DataFileWrite 等待对关系数据文件的写入。 - - DSMFillZeroWrite - 等待将零字节写入动态共享内存的后备文件。 + + DSMFillZeroWrite + 等待向动态共享内存的后备文件写入值为零的字节。 - - LockFileAddToDataDirRead + + LockFileAddToDataDirRead 在向数据目录锁文件中添加一行时等待读取。 - - LockFileAddToDataDirSync - 等待数据到达持久存储,同时向数据目录锁文件添加一行。 + + LockFileAddToDataDirSync + 在向数据目录锁文件中添加一行时,等待数据同步到持久存储。 - - LockFileAddToDataDirWrite + + LockFileAddToDataDirWrite 在向数据目录锁文件中添加一行时等待写操作。 - - LockFileCreateRead + + LockFileCreateRead 创建数据目录锁文件时等待读取。 - - LockFileCreateSync - 在创建数据目录锁文件时等待数据到达持久存储。 + + LockFileCreateSync + 在创建数据目录锁文件时,等待数据同步到持久存储。 - - LockFileCreateWrite + + LockFileCreateWrite 在创建数据目录锁文件时等待写操作。 - - LockFileReCheckDataDirRead + + LockFileReCheckDataDirRead 在重新检查数据目录锁文件期间等待读取。 - - LogicalRewriteCheckpointSync - 等待逻辑重写映射到在检查点到达持久存储。 + + LogicalRewriteCheckpointSync + 在检查点期间等待逻辑重写映射同步到持久存储。 - - LogicalRewriteMappingSync - 在逻辑重写期间等待映射数据到达持久存储 + + LogicalRewriteMappingSync + 在逻辑重写期间等待映射数据同步到持久存储。 - - LogicalRewriteMappingWrite + + LogicalRewriteMappingWrite 在逻辑重写期间等待映射数据的写入。 - - LogicalRewriteSync - 等待逻辑重写映射到达持久存储。 + + LogicalRewriteSync + 等待逻辑重写映射同步到持久存储。 - - LogicalRewriteTruncate - 等待在逻辑重写期间截断映射数据。 + + LogicalRewriteTruncate + 在逻辑重写期间等待截断映射数据。 - - LogicalRewriteWrite + + LogicalRewriteWrite 等待逻辑重写映射的写入。 - - RelationMapRead + + RelationMapRead 等待关系映射文件的读取。 - - RelationMapSync - 等待关系映射文件到达持久存储。 + + RelationMapSync + 等待关系映射文件同步到持久存储。 - - RelationMapWrite + + RelationMapWrite 等待对关系映射文件的写入。 - - ReorderBufferRead - 在重新排序缓冲区管理期间等待读取。 + + ReorderBufferRead + 在重排序缓冲区管理期间等待读取。 - - ReorderBufferWrite - 在重新排序缓冲区管理期间等待写操作。 + + ReorderBufferWrite + 在重排序缓冲区管理期间等待写入。 - - ReorderLogicalMappingRead - 在重新排序缓冲区管理期间等待读取逻辑映射。 + + ReorderLogicalMappingRead + 在重排序缓冲区管理期间等待读取逻辑映射。 - - ReplicationSlotRead + + ReplicationSlotRead 等待从复制槽控制文件读取。 - - ReplicationSlotRestoreSync - 等待复制槽控制文件到达持久存储,同时将其恢复到内存中。 + + ReplicationSlotRestoreSync + 在将复制槽控制文件恢复到内存期间,等待该文件同步到持久存储。 - - ReplicationSlotSync - 等待复制槽控制文件到达持久存储。 + + ReplicationSlotSync + 等待复制槽控制文件同步到持久存储。 - - ReplicationSlotWrite + + ReplicationSlotWrite 等待对复制槽控制文件的写入。 - - SLRUFlushSync - 在检查点或数据库关闭期间等待SLRU数据到达持久存储。 + + SLRUFlushSync + 在检查点或数据库关闭期间,等待 SLRU 数据同步到持久存储。 - - SLRURead + + SLRURead 等待读取SLRU页面。 - - SLRUSync - 在写页面后等待SLRU数据到达持久存储。 + + SLRUSync + 在页面写入后等待 SLRU 数据同步到持久存储。 - - SLRUWrite + + SLRUWrite 等待SLRU页面的写入。 - - SnapbuildRead - 等待读取序列化的历史目录快照。 + + SnapbuildRead + 等待读取序列化的历史系统目录快照。 - - SnapbuildSync - 等待序列化历史目录快照到达持久存储。 + + SnapbuildSync + 等待序列化的历史系统目录快照同步到持久存储。 - - SnapbuildWrite - 等待串行历史目录快照的写入。 + + SnapbuildWrite + 等待写入序列化的历史系统目录快照。 - - TimelineHistoryFileSync - 等待通过流复制接收的时间线历史文件到达持久存储。 + + TimelineHistoryFileSync + 等待通过流复制接收的时间线历史文件同步到持久存储。 - - TimelineHistoryFileWrite + + TimelineHistoryFileWrite 等待通过流复制接收的时间线历史文件的写入。 - - TimelineHistoryRead + + TimelineHistoryRead 等待读取时间线历史文件。 - - TimelineHistorySync - 等待新创建的时间线历史文件到达持久存储。 + + TimelineHistorySync + 等待新创建的时间线历史文件同步到持久存储。 - - TimelineHistoryWrite + + TimelineHistoryWrite 等待写入新创建的时间线历史文件。 - - TwophaseFileRead + + TwophaseFileRead 等待读取两阶段状态文件。 - - TwophaseFileSync - 等待两阶段状态文件到达持久存储。 + + TwophaseFileSync + 等待两阶段状态文件同步到持久存储。 - - TwophaseFileWrite + + TwophaseFileWrite 等待对两阶段状态文件的写入。 - - WALBootstrapSync - 在引导过程中等待WAL达到持久存储。 + + WALBootstrapSync + 在引导过程中等待 WAL 同步到持久存储。 - - WALBootstrapWrite + + WALBootstrapWrite 在引导过程中等待WAL页面的写入。 - - WALCopyRead + + WALCopyRead 通过复制一个已有WAL段来创建一个新的WAL段时等待读取。 - - WALCopySync - 等待通过复制已有 WAL 段创建的新 WAL 段写入持久存储。 + + WALCopySync + 等待通过复制现有 WAL 段创建的新 WAL 段同步到持久存储。 - - WALCopyWrite + + WALCopyWrite 通过复制一个已有WAL段来创建一个新的WAL段时等待写入。 - - WALInitSync - 等待一个新初始化的WAL文件到持久存储。 + + WALInitSync + 等待新初始化的 WAL 文件同步到持久存储。 - - WALInitWrite + + WALInitWrite 在初始化一个新的WAL文件时等待写入。 - - WALRead + + WALRead 等待WAL文件的读取。 - - WALSenderTimelineHistoryRead + + WALSenderTimelineHistoryRead 在 WAL 发送进程执行时间线命令期间,等待读取时间线历史文件。 - - WALSyncMethodAssign - 在指派 WAL 同步方法时等待数据写入持久存储。 + + WALSyncMethodAssign + 在设置 WAL 同步方法时,等待数据同步到持久存储。 - - WALWrite - 等待写入WAL文件。 + + WALWrite + 等待写入 WAL 文件。
@@ -1397,7 +1397,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i inet 连接到这个 WAL 发送进程的客户端的 IP 地址。 - 如果这个域为空,它表示该客户端通过服务器机器上的一个Unix 套接字连接。 + 如果这个字段为空值,它表示该客户端通过服务器机器上的一个Unix 套接字连接。 @@ -1435,27 +1435,27 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i 当前 WAL 发送进程的状态。可能的值为: - startup: 此 WAL 发送进程正在启动。 + startup: 此 WAL 发送进程正在启动。 - catchup: 与此 WAL 发送进程连接的备库正在赶上主库。 + catchup: 与此 WAL 发送进程连接的备库正在赶上主库。 - streaming: 在其连接的备库赶上主库之后,此 WAL 发送进程正在流式传输更改。 + streaming: 在其连接的备库赶上主库之后,此 WAL 发送进程正在流式传输更改。 - backup: 此 WAL 发送进程正在发送一个备份。 + backup: 此 WAL 发送进程正在发送一个备份。 - stopping: 此 WAL 发送进程正在停止。 + stopping: 此 WAL 发送进程正在停止。 @@ -1492,26 +1492,17 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i write_lag interval - - 从本地刷写最近的 WAL,到收到该备库已写入该 WAL(但尚未刷盘或应用)的通知之间经过的时间。 - 如果该服务器被配置为同步备库,可用此值衡量在提交时 synchronous_commit 级别 remote_write 所导致的延迟。 - + 从在本地将最近的 WAL 刷盘,到收到该备库已写入该 WAL(但尚未刷盘或应用)的通知之间经过的时间。如果该服务器被配置为同步备库,可用此值衡量在提交时synchronous_commit级别remote_write所导致的延迟。 flush_lag interval - - 从本地刷写最近的 WAL,到收到该备库已写入并刷写该 WAL(但尚未应用)的通知之间经过的时间。 - 如果该服务器被配置为同步备库,可用此值衡量在提交时 synchronous_commit 级别 on 所导致的延迟。 - + 从在本地将最近的 WAL 刷盘,到收到该备库已写入该 WAL 并将其刷盘(但尚未应用)的通知之间经过的时间。如果该服务器被配置为同步备库,可用此值衡量在提交时synchronous_commit级别on所导致的延迟。 replay_lag interval - - 从本地刷写最近的 WAL,到收到该备库已写入、刷写并应用该 WAL 的通知之间经过的时间。 - 如果该服务器被配置为同步备库,可用此值衡量在提交时 synchronous_commit 级别 remote_apply 所导致的延迟。 - + 从在本地将最近的 WAL 刷盘,到收到该备库已写入该 WAL、将其刷盘并应用的通知之间经过的时间。如果该服务器被配置为同步备库,可用此值衡量在提交时synchronous_commit级别remote_apply所导致的延迟。 sync_priority @@ -1526,22 +1517,22 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i 此备库的同步状态。可能的值为: - async: 该备库是异步的。 + async: 该备库是异步的。 - potential: 该备库当前是异步的,但在当前同步备库失效时可能变为同步的。 + potential: 该备库当前是异步的,但在当前某个同步备库失效时可能变为同步的。 - sync: 该备库是同步的。 + sync: 该备库是同步的。 - quorum: 该备库被作为法定人数同步复制候选备库。 + quorum: 该备库被作为法定人数同步复制候选备库。 @@ -1557,16 +1548,16 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i - pg_stat_replication视图中报告的滞后时间,是最近的 WAL 被写入、刷写和重放,以及发送端获知这些操作完成所花费时间的度量。如果远程服务器被配置为同步备库,这些时间表示各个同步提交级别带来或可能带来的提交延迟。对于异步备库,replay_lag列是最近事务对查询变得可见所需延迟时间的近似值。如果备库已经完全追上发送服务器且没有新的 WAL 活动,系统会在短时间内继续显示最近测得的滞后时间,随后显示为 NULL。 + pg_stat_replication视图中报告的滞后时间,是最近的 WAL 被写入、刷盘和重放,以及发送端获知这些操作完成所花费时间的度量。如果远程服务器被配置为同步备库,这些时间表示各个同步提交级别带来或可能带来的提交延迟。对于异步备库,replay_lag列是最近事务对查询变得可见所需延迟时间的近似值。如果备库已经完全追上发送服务器且没有新的 WAL 活动,系统会在短时间内继续显示最近测得的滞后时间,随后显示为空值。 - 对于物理复制,滞后时间会自动测量。逻辑解码插件可以选择发出跟踪消息;如果没有这样做,跟踪机制会将滞后显示为 NULL。 + 对于物理复制,滞后时间会自动测量。逻辑解码插件可以选择发出跟踪消息;如果没有这样做,跟踪机制会将滞后显示为空值。 - 报告出的滞后时间并不是根据当前重放速率预测该备库还需多久才能追上发送服务器。在持续生成新 WAL 时,那样的系统可能会显示相近的时间;但当发送端空闲时,就会显示不同的值。特别是当备库已经完全追上时,pg_stat_replication显示的是写入、刷写和重放最近报告的 WAL 位置所花费的时间,而不是某些用户可能预期的零。这样做符合为最近写事务测量同步提交和事务可见性延迟的目的。为减少用户因预期另一种滞后模型而产生的混淆,在一个已完全重放且处于空闲状态的系统上,lag 列会在较短时间后恢复为 NULL。监控系统应自行决定将这种情况表示为缺失数据、零,还是继续显示最近一次已知值。 + 报告出的滞后时间并不是根据当前重放速率预测该备库还需多久才能追上发送服务器。在持续生成新 WAL 时,那样的系统可能会显示相近的时间;但当发送端空闲时,就会显示不同的值。特别是当备库已经完全追上时,pg_stat_replication显示的是写入、刷盘和重放最近报告的 WAL 位置所花费的时间,而不是某些用户可能预期的零。这样做符合为最近写事务测量同步提交和事务可见性延迟的目的。为减少用户因预期另一种滞后模型而产生的混淆,在一个已完全重放且处于空闲状态的系统上,滞后列会在较短时间后恢复为空值。监控系统应自行决定将这种情况表示为缺失数据、零,还是继续显示最近一次已知值。 @@ -1586,42 +1577,42 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i pid integer - WAL 接收进程的进程ID + WAL 接收进程的进程 ID status text - WAL接收进程的活动状态 + WAL 接收进程的活动状态 receive_start_lsn pg_lsn - WAL 接收进程启动时使用的第一个写前日志位置 + WAL 接收进程启动时使用的第一个预写式日志位置 receive_start_tli integer - WAL 接收进程启动时使用的第一个时间线数字 + WAL 接收进程启动时使用的第一个时间线编号 received_lsn pg_lsn - 已经接收并刷入到磁盘的最后一个预写式日志位置,该字段的初始值是启动WAL 接收进程时使用的第一个日志位置 + 已经接收并刷入到磁盘的最后一个预写式日志位置,该字段的初始值是启动 WAL 接收进程时使用的第一个日志位置 received_tli integer - 接收并刷入到磁盘的最后一个预写式日志位置的时间线数字,该字段的初始值为启动WAL 接收进程时使用的第一个日志位置的时间线数字 + 接收并刷入到磁盘的最后一个预写式日志位置的时间线编号,该字段的初始值为启动 WAL 接收进程时使用的第一个日志位置的时间线编号 @@ -1656,23 +1647,21 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i slot_name text - 这个WAL 接收进程使用的复制槽的名称 + 这个 WAL 接收进程使用的复制槽的名称 conninfo text - 这个WAL 接收进程使用的连接字符串,对安全敏感的字段进行了模糊处理。 + 这个 WAL 接收进程使用的连接字符串,对安全敏感的字段进行了模糊处理。 - - pg_stat_wal_receiver事务只包含一行,它显示了从 WAL 接收进程所连接的服务器得到的有关该接收进程的统计信息。 - + pg_stat_wal_receiver视图只包含一行,显示 WAL 接收进程从其所连接服务器接收数据的统计信息。 <structname>pg_stat_subscription</structname> 视图 @@ -1686,70 +1675,80 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i - + + subid oid 订阅的OID - + + subname text 订阅的名称 - + + pid integer 订阅工作进程的进程 ID - + + relid Oid - 该工作进程正在同步的关系的 OID;主应用工作进程则为 NULL + 该工作进程正在同步的关系的 OID;主应用工作进程则为空值 - + + received_lsn pg_lsn - 接收到的最后一个预写式日志位置,该字段的初始值为0 + 接收到的最后一个预写式日志位置,该字段的初始值为 0 - + + last_msg_send_time timestamp with time zone 从源 WAL 发送进程收到的最后一条消息的发送时间 - + + last_msg_receipt_time timestamp with time zone 从源 WAL 发送进程收到的最后一条消息的接收时间 - + + latest_end_lsn pg_lsn 向源 WAL 发送进程报告的最后一个预写式日志位置 - + + latest_end_time timestamp with time zone - 向 WAL 发送进程报告最后一个预写式日志位置的时间 + 向源 WAL 发送进程报告最后一个预写式日志位置的时间 - + +
@@ -1785,34 +1784,34 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i version text - 使用SSL的版本,如果此连接上没有使用SSL则为NULL + 使用SSL的版本,如果此连接上没有使用SSL则为空值
cipher text - 正在使用的SSL密码的名称,如果此连接上没有使用SSL则为NULL + 正在使用的SSL 密码套件的名称,如果此连接上没有使用SSL则为空值 bits integer - 使用的加密算法中的位数,如果此连接上没有使用SSL则为NULL + 使用的加密算法中的位数,如果此连接上没有使用SSL则为空值 compression boolean - 使用 SSL 压缩时为真,否则为假;如果此连接未使用 SSL,则为 NULL + 使用 SSL 压缩时为真,否则为假;如果此连接未使用 SSL,则为空值 clientdn text - 区别名称(DN,Distinguished Name)字段与使用的客户端证书,如果没有提供客户端证书或在此连接上没有使用SSL,则为NULL。 - 如果DN字段长于NAMEDATALEN(标准构建中为64个字符),则该字段将被截断。 + 所用客户端证书中的区别名称(DN,Distinguished Name)字段,如果没有提供客户端证书或在此连接上没有使用SSL,则为空值。 + 如果DN字段长于NAMEDATALEN(标准构建中为64个字符),则该字段将被截断。 @@ -1883,9 +1882,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i stats_reset timestamp with time zone - - 这些统计数据最后一次重置的时间 - + 这些统计信息上次被重置的时间 @@ -1955,7 +1952,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i buffers_backend_fsync bigint - 后端必须自行执行fsync调用的次数(通常即使后端自行写入,也由后台写入进程处理这些调用) + 后端必须自行执行fsync调用的次数(通常即使后端自行写入,也由后台写入器处理这些调用) buffers_alloc @@ -1967,16 +1964,14 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i stats_reset timestamp with time zone - - 这些统计信息上次被重置的时间 - + 这些统计信息上次被重置的时间 - pg_stat_bgwriter 视图始终只有一行,包含有关集簇后台写入器的数据。 + pg_stat_bgwriter 视图始终只有一行,包含整个集簇的全局数据。 @@ -1991,21 +1986,24 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i - + + datid oid 数据库的OID - + + datname name 数据库的名称 - + + numbackends integer @@ -2013,115 +2011,132 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i 这是该视图中唯一返回反映当前状态的值的列;所有其他列返回的都是自上次重置以来累积的值。 - + + xact_commit bigint 此数据库中已提交的事务数 - + + xact_rollback bigint 该数据库中已回滚的事务数 - + + blks_read bigint 在该数据库中读取的磁盘块数 - + + blks_hit bigint 在缓冲区缓存中发现磁盘块、因而无需读取的次数(这里只统计 PostgreSQL 缓冲区缓存中的命中,不包括操作系统文件系统缓存中的命中) - + + tup_returned bigint - 由顺序扫描获取的活动行数和由索引扫描返回的索引条目数 + 此数据库中的查询返回的行数 - + + tup_fetched bigint - 该数据库中由索引扫描检索的活动行数 + 此数据库中的查询获取的行数 - + + tup_inserted bigint 查询在该数据库中插入的行数 - + + tup_updated bigint 这个数据库中查询更新的行数 - + + tup_deleted bigint 这个数据库中被查询删除的行数 - + + conflicts bigint 由于与此数据库中的恢复冲突而被取消的查询数。(冲突只会发生在备库上;请参阅。) - + + temp_files bigint 这个数据库中查询创建的临时文件的数量。所有临时文件都将被计数,而不顾及临时文件为什么被创建(例如,排序或散列),也不考虑设置。 - + + temp_bytes bigint 这个数据库中的查询写入临时文件的数据总量。所有临时文件都将被计数,而不考虑临时文件为什么被创建,也不考虑设置。 - + + deadlocks bigint 在此数据库中检测到的死锁数 - + + blk_read_time double precision 此数据库的后端读取数据文件块所花费的时间,单位为毫秒 - + + blk_write_time double precision 此数据库的后端写入数据文件块所花费的时间,单位为毫秒 - + + stats_reset timestamp with time zone 这些统计数据最后一次重置的时间 - + +
@@ -2178,7 +2193,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i confl_bufferpin bigint - 此数据库中由于固定缓冲区而被取消的查询数 + 此数据库中由于缓冲区被钉住而被取消的查询数
@@ -2238,7 +2253,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i seq_tup_read bigint - 连续扫描获取的实时行数 + 顺序扫描获取的存活行数 @@ -2252,7 +2267,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i idx_tup_fetch bigint - 索引扫描获取的实时行数 + 索引扫描获取的存活行数 @@ -2278,7 +2293,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i n_tup_hot_upd bigint - HOT更新的行数(即,不需要单独的索引更新) + HOT 更新的行数(即不需要单独更新索引) @@ -2306,7 +2321,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i last_vacuum timestamp with time zone - 最后一次手动清理这个表(不包括VACUUM FULL) + 最后一次手动清理这个表的时间(不包括VACUUM FULL) @@ -2320,21 +2335,21 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i last_analyze timestamp with time zone - 上一次手动分析这个表 + 上一次手动分析这个表的时间 last_autoanalyze timestamp with time zone - 自动清理守护进程最后一次分析这个表 + 自动清理守护进程最后一次分析这个表的时间 vacuum_count bigint - 这个表被手动清理的次数(VACUUM FULL不计数) + 这个表被手动清理的次数(VACUUM FULL不计数) @@ -2432,7 +2447,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i idx_tup_fetch bigint - 使用此索引进行简单索引扫描获取的活动表行数 + 使用此索引进行简单索引扫描获取的存活表行数 @@ -2444,13 +2459,13 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i - 索引可以被简单索引扫描、位图索引扫描以及优化器使用。在一次位图扫描中,多个索引的输出可以被通过 AND 或 OR 规则组合,因此当使用一次位图扫描时难以将取得的个体堆行与特定的索引关联起来。因此,一次位图扫描会增加它使用的索引的pg_stat_all_indexes.idx_tup_read计数,并且为每个表增加pg_stat_all_tables.idx_tup_fetch计数,但是它不影响pg_stat_all_indexes.idx_tup_fetch。如果所提供的常量值不在优化器统计信息记录的范围之内,优化器也会访问索引来检查,因为优化器统计信息可能已经“不新鲜”了。 + 索引可以被简单索引扫描、位图索引扫描以及优化器使用。在一次位图扫描中,多个索引的输出可以被通过 AND 或 OR 规则组合,因此当使用一次位图扫描时难以将取得的个体堆行与特定的索引关联起来。因此,一次位图扫描会增加它使用的索引的pg_stat_all_indexes.idx_tup_read计数,并且为该表增加pg_stat_all_tables.idx_tup_fetch计数,但是它不影响pg_stat_all_indexes.idx_tup_fetch。如果所提供的常量值不在优化器统计信息记录的范围之内,优化器也会访问索引来检查,因为优化器统计信息可能已经过时。 - 即使不用位图扫描,idx_tup_readidx_tup_fetch计数也可能不同,因为idx_tup_read统计从该索引取得的索引项而idx_tup_fetch统计从表取得的活着的行。如果使用该索引取得了任何死亡行或还未提交的行,或者如果通过一次只用索引扫描的方式避免了任何堆获取,后者将较小。 + 即使不用位图扫描,idx_tup_readidx_tup_fetch计数也可能不同,因为idx_tup_read统计从该索引取得的索引项而idx_tup_fetch统计从表取得的存活行。如果使用该索引取得了任何死亡行或还未提交的行,或者如果通过一次仅索引扫描的方式避免了任何堆获取,后者将较小。 @@ -2519,28 +2534,28 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i toast_blks_read bigint - 从这个表的TOAST表中读取的磁盘块的数量(如果有的话) + 从这个表的TOAST表中读取的磁盘块的数量(如果有的话) toast_blks_hit bigint - 这个表的TOAST表中的缓冲区命中数(如果有的话) + 这个表的TOAST表中的缓冲区命中数(如果有的话) tidx_blks_read bigint - 从这个表的TOAST表索引中读取的磁盘块的数量(如果有的话) + 从这个表的TOAST表索引中读取的磁盘块的数量(如果有的话) tidx_blks_hit bigint - 这个表的TOAST表索引中的缓冲区命中数(如果有的话) + 这个表的TOAST表索引中的缓冲区命中数(如果有的话) @@ -2951,23 +2966,23 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, 查看锁 - lock - monitoring + + 监控 - 监控数据库活动的另外一个有用的工具是pg_locks系统表。这样就允许数据库管理员查看在锁管理器里面未解决的锁的信息。例如,这个功能可以被用于: + 监控数据库活动的另外一个有用的工具是pg_locks系统表。这样就允许数据库管理员查看锁管理器中当前存在的锁的信息。例如,这个功能可以被用于: - 查看当前所有未解决的锁、在一个特定数据库中的关系上所有的锁、在一个特定关系上所有的锁,或者由一个特定PostgreSQL会话持有的所有的锁。 + 查看当前存在的所有锁、在一个特定数据库中的关系上所有的锁、在一个特定关系上所有的锁,或者由一个特定PostgreSQL会话持有的所有的锁。 - 判断当前数据库中带有最多未授予锁的关系(它很可能是数据库客户端的竞争源)。 + 判断当前数据库中带有最多未授予锁的关系(它可能是数据库客户端之间的竞争来源)。 @@ -3029,21 +3044,21 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, relid oid - 被vacuum的表的OID。 + 正在清理的表的OID。 phase text - vacuum的当前处理阶段。参见 。 + 清理的当前处理阶段。参见 heap_blks_total bigint - 该表中堆块的总数。这个数字在扫描开始时报告,之后增加的块将不会(并且不需要)被这个VACUUM访问。 + 该表中堆块的总数。这个数字以扫描开始时的数量为准,之后增加的块将不会(并且不需要)被这个VACUUM访问。 @@ -3074,14 +3089,14 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, max_dead_tuples bigint - 在需要执行索引清理周期之前可存储的死亡元组数据量,取决于。 + 在需要执行索引清理周期之前可存储的死亡元组数量,取决于 num_dead_tuples bigint - 自上一个索引清理周期以来收集到的死亡元组数据量。 + 自上一个索引清理周期以来收集到的死亡元组数量。 @@ -3089,7 +3104,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - VACUUM的阶段 + VACUUM 阶段 @@ -3109,33 +3124,29 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, scanning heap - VACUUM正在扫描堆。如果需要,它将会对每个页面进行修建以及碎片整理,并且可能会执行冻结动作。heap_blks_scanned列可以用来监控扫描的进度。 + VACUUM正在扫描堆。如果需要,它将会对每个页面进行剪枝以及碎片整理,并且可能会执行冻结动作。heap_blks_scanned列可以用来监控扫描的进度。 vacuuming indexes - - VACUUM当前正在清理索引。 - 如果一个表拥有索引,那么每次清理时这个阶段会在堆扫描完成后至少发生一次。 - 如果不足以存放找到的死亡元组(或者, 在autovacuum情况下,如果设置了) ,则每次清理时会多次清理索引。 - + VACUUM当前正在清理索引。如果表有索引,每次清理都会在堆扫描完成后至少执行一次此阶段。如果(或者,对于自动清理,已设置的)不足以存储找到的死亡元组数量,则每次清理可能多次执行此阶段。 vacuuming heap - VACUUM当前正在清理堆。清理堆与扫描堆不是同一个概念,清理堆发生在每一次清理索引的实例之后。如果heap_blks_scanned小于heap_blks_total,系统将在这个阶段完成之后回去扫描堆;否则,系统将在这个阶段完成后开始清理索引。 + VACUUM当前正在清理堆。清理堆与扫描堆不是同一个概念,清理堆发生在每次索引清理之后。如果heap_blks_scanned小于heap_blks_total,系统将在这个阶段完成之后回去扫描堆;否则,系统将在这个阶段完成后开始索引收尾清理。 cleaning up indexes - VACUUM当前正在清除索引。这个阶段发生在堆被完全扫描并且对堆和索引的所有清理都已经完成以后。 + VACUUM当前正在进行索引收尾清理。这个阶段发生在堆被完全扫描并且对堆和索引的所有清理都已经完成以后。 truncating heap - VACUUM正在截断堆,以便把关系尾部的空页面返还给操作系统。这个阶段发生在清除完索引之后。 + VACUUM正在截断堆,以便把关系尾部的空页面返还给操作系统。这个阶段发生在索引收尾清理完成之后。 @@ -3174,7 +3185,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - 动态追踪的编译 + 为动态追踪编译 默认情况下,探针是不可用的,因此你将需要显式地告诉配置脚本让探针在PostgreSQL中可用。要包括 DTrace 支持,在配置时指定。更多信息请见。 @@ -3185,7 +3196,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, 内置探针 - 如所示,源代码中提供了一些标准探针。显式了在探针中使用的类型。当然,可以增加更多探针来增强PostgreSQL的可观测性。 + 如所示,源代码中提供了一些标准探针。显示了在探针中使用的类型。当然,可以增加更多探针来增强PostgreSQL的可观测性。
@@ -3215,12 +3226,12 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, transaction-abort (LocalTransactionId) - 当一个事务失败完成时触发的探针。arg0 是事务 ID。 + 当一个事务失败结束时触发的探针。arg0 是事务 ID。 query-start (const char *) - 当一个查询的处理被开始时触发的探针。arg0 是查询字符串。 + 当一个查询的处理开始时触发的探针。arg0 是查询字符串。 query-done @@ -3230,7 +3241,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, query-parse-start (const char *) - 当一个查询的解析被开始时触发的探针。arg0 是查询字符串。 + 当一个查询的解析开始时触发的探针。arg0 是查询字符串。 query-parse-done @@ -3240,7 +3251,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, query-rewrite-start (const char *) - 当一个查询的重写被开始时触发的探针。arg0 是查询字符串。 + 当一个查询的重写开始时触发的探针。arg0 是查询字符串。 query-rewrite-done @@ -3250,7 +3261,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, query-plan-start () - 当一个查询的规划被开始时触发的探针。 + 当一个查询的规划开始时触发的探针。 query-plan-done @@ -3260,7 +3271,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, query-execute-start () - 当一个查询的执行被开始时触发的探针。 + 当一个查询的执行开始时触发的探针。 query-execute-done @@ -3275,17 +3286,17 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, checkpoint-start (int) - 当一个检查点被开始时触发的探针。arg0 传递位标志来区分不同的检查点类型,例如关闭(shutdown)、立即(immediate)或强制(force)。 + 当一个检查点开始时触发的探针。arg0 传递位标志来区分不同的检查点类型,例如关闭(shutdown)、立即(immediate)或强制(force)。 checkpoint-done (int, int, int, int, int) - 当一个检查点完成时触发的探针(检查点处理过程中序列中列出的下一个触发的探针)。arg0 是要写的缓冲区数量。arg1 是缓冲区的总数。arg2、arg3 和 arg4 分别包含了增加、删除和循环回收的 WAL 文件的数量。 + 当一个检查点完成时触发的探针(下面列出的探针会在检查点处理过程中依次触发)。arg0 是已写入的缓冲区数量。arg1 是缓冲区的总数。arg2、arg3 和 arg4 分别包含了增加、删除和循环回收的 WAL 文件的数量。 clog-checkpoint-start (bool) - 当一个检查点的 CLOG 部分被开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 + 当一个检查点的 CLOG 部分开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 clog-checkpoint-done @@ -3295,7 +3306,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, subtrans-checkpoint-start (bool) - 当一个检查点的 SUBTRANS 部分被开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 + 当一个检查点的 SUBTRANS 部分开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 subtrans-checkpoint-done @@ -3305,7 +3316,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, multixact-checkpoint-start (bool) - 当一个检查点的 MultiXact 部分被开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 + 当一个检查点的 MultiXact 部分开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 multixact-checkpoint-done @@ -3315,7 +3326,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, buffer-checkpoint-start (int) - 当一个检查点的写缓冲区部分被开始时触发的探针。arg0 传递位标志来区分不同的检查点类型,例如关闭(shutdown)、立即(immediate)或强制(force)。 + 当一个检查点的写缓冲区部分开始时触发的探针。arg0 传递位标志来区分不同的检查点类型,例如关闭(shutdown)、立即(immediate)或强制(force)。 buffer-sync-start @@ -3345,7 +3356,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, twophase-checkpoint-start () - 当一个检查点的两阶段部分被开始时触发的探针。 + 当一个检查点的两阶段部分开始时触发的探针。 twophase-checkpoint-done @@ -3355,17 +3366,17 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, buffer-read-start (ForkNumber, BlockNumber, Oid, Oid, Oid, int, bool) - 当一次缓冲区读被开始时触发的探针。arg0 和 arg1 包含该页的分叉号和块号(如果这是一次关系扩展请求,arg1 为 -1)。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是 InvalidBackendId(-1)。arg6 为真表示一次关系扩展请求,为假表示正常读。 + 当一次缓冲区读开始时触发的探针。arg0 和 arg1 包含该页的分支号和块号(如果这是一次关系扩展请求,arg1 为 -1)。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是 InvalidBackendId(-1)。arg6 为真表示一次关系扩展请求,为假表示正常读。 buffer-read-done (ForkNumber, BlockNumber, Oid, Oid, Oid, int, bool, bool) - 当一次缓冲区读完成时触发的探针。arg0 和 arg1 包含该页的分叉号和块号(如果这是一次关系扩展请求,arg1 现在包含新增加块的块号)。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是 InvalidBackendId(-1)。arg6 为真表示一次关系扩展请求,为假表示正常读。arg7 为真表示在池中找到该缓冲区,为假表示没有找到。 + 当一次缓冲区读完成时触发的探针。arg0 和 arg1 包含该页的分支号和块号(如果这是一次关系扩展请求,arg1 现在包含新增加块的块号)。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是 InvalidBackendId(-1)。arg6 为真表示一次关系扩展请求,为假表示正常读。arg7 为真表示在池中找到该缓冲区,为假表示没有找到。 buffer-flush-start (ForkNumber, BlockNumber, Oid, Oid, Oid) - 在发出对一个共享缓冲区的任意写请求之前触发的探针。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。 + 在发出对一个共享缓冲区的任意写请求之前触发的探针。arg0 和 arg1 包含该页的分支号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。 buffer-flush-done @@ -3375,7 +3386,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, buffer-write-dirty-start (ForkNumber, BlockNumber, Oid, Oid, Oid) - 当一个服务器进程开始写一个脏缓冲区时触发的探针(如果这经常发生,表示太小,或需要调整后台写入器的控制参数)。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。 + 当一个服务器进程开始写一个脏缓冲区时触发的探针(如果这经常发生,表示太小,或需要调整后台写入器的控制参数)。arg0 和 arg1 包含该页的分支号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。 buffer-write-dirty-done @@ -3390,12 +3401,12 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, wal-buffer-write-dirty-done () - 当一次脏 WAL 缓冲区完成时触发的探针。 + 当一次脏 WAL 缓冲区写入完成时触发的探针。 wal-insert (unsigned char, unsigned char) - 当一个 WAL 记录被插入时触发的探针。arg0 是该记录的资源管理者(rmid)。arg1 包含 info 标志。 + 当一个 WAL 记录被插入时触发的探针。arg0 是该记录的资源管理器(rmid)。arg1 包含 info 标志。 wal-switch @@ -3405,27 +3416,27 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, smgr-md-read-start (ForkNumber, BlockNumber, Oid, Oid, Oid, int) - 当开始从一个关系读取一块时触发的探针。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。 + 当开始从一个关系读取一块时触发的探针。arg0 和 arg1 包含该页的分支号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。 smgr-md-read-done (ForkNumber, BlockNumber, Oid, Oid, Oid, int, int, int) - 当一次块读取完成时触发的探针。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。arg6 是实际读取的字节数,而 arg7 是请求读取的字节数(如果两者不同就意味着麻烦)。 + 当一次块读取完成时触发的探针。arg0 和 arg1 包含该页的分支号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。arg6 是实际读取的字节数,而 arg7 是请求读取的字节数(如果两者不同就意味着麻烦)。 smgr-md-write-start (ForkNumber, BlockNumber, Oid, Oid, Oid, int) - 当开始向一个关系中写入一个块时触发的探针。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。 + 当开始向一个关系中写入一个块时触发的探针。arg0 和 arg1 包含该页的分支号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。 smgr-md-write-done (ForkNumber, BlockNumber, Oid, Oid, Oid, int, int, int) - 当一个块写操作完成时触发的探针。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3和arg4 包含表空间、数据库和关系 OID来标识该关系。对于一个本地缓冲区,arg5 是创建临时关系的后端 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。arg6 是实际写的字节数,而 arg7 是要求写的字节数(如果这两者不同,则意味着麻烦)。 + 当一个块写操作完成时触发的探针。arg0 和 arg1 包含该页的分支号和块号。arg2、arg3和arg4 包含表空间、数据库和关系 OID来标识该关系。对于一个本地缓冲区,arg5 是创建临时关系的后端 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。arg6 是实际写的字节数,而 arg7 是要求写的字节数(如果这两者不同,则意味着麻烦)。 sort-start (int, bool, int, int, bool) - 当一次排序操作开始时触发的探针。arg0 指示是堆排序、索引排序或数据排序。arg1 为真表示强制唯一值。arg2 是键列数。arg3 是允许使用的工作内存大小(以千字节计)。如果要求随机访问排序结果,则 arg4 为真。 + 当一次排序操作开始时触发的探针。arg0 指示是堆排序、索引排序或 datum 排序。arg1 为真表示强制唯一值。arg2 是键列数。arg3 是允许使用的工作内存大小(以千字节计)。如果要求随机访问排序结果,则 arg4 为真。 sort-done @@ -3437,7 +3448,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, (char *, LWLockMode) 当成功获得一个 LWLock 时触发的探针。 arg0 是该 LWLock 所在的切片(Tranche)。 - arg1 所请求的锁模式,是排他或共享。 + arg1 是所请求的锁模式,是排他或共享。 lwlock-release @@ -3450,30 +3461,30 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, (char *, LWLockMode) 当一个 LWLock不是当即可用并且一个服务器进程因此开始等待该锁变为可用时触发的探针。 arg0 是该 LWLock 所在的切片(Tranche)。 - arg1 请求的锁模式,是排他或共享。 + arg1 是所请求的锁模式,是排他或共享。 lwlock-wait-done (char *, LWLockMode) 当一个进程从对一个 LWLock 的等待中被释放时(它实际还没有得到该锁)时触发的探针。arg0 是该 LWLock 所在的切片(Tranche)。 - arg1 所请求的锁模式,是排他或共享。 + arg1 是所请求的锁模式,是排他或共享。 lwlock-condacquire (char *, LWLockMode) 当调用者指定无需等待而成功获得一个 LWLock 时触发的探针。arg0 是该 LWLock 所在的切片(Tranche)。 - arg1 所请求的锁模式,是排他或共享。 + arg1 是所请求的锁模式,是排他或共享。 lwlock-condacquire-fail (char *, LWLockMode) 当调用者指定无需等待而没有成功获得一个 LWLock 时触发的探针。arg0 是该 LWLock 所在的切片(Tranche)。 - arg1 所请求的锁模式,是排他或共享。 + arg1 是所请求的锁模式,是排他或共享。 lock-wait-start (unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, LOCKMODE) - 当一个重量级锁(lmgr锁)的请求由于锁不可用开始等待时触发的探针。arg0 到 arg3 是标识被锁定对象的标签域。arg4 指示被锁对象的类型。arg5 表示被请求的锁类型。 + 当一个重量级锁(lmgr锁)的请求由于锁不可用开始等待时触发的探针。arg0 到 arg3 是标识被锁定对象的标签字段。arg4 指示被锁对象的类型。arg5 表示被请求的锁类型。 lock-wait-done @@ -3491,7 +3502,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid,
- 定义用在探针参数中的类型 + 探针参数中使用的已定义类型 @@ -3586,7 +3597,7 @@ Total time (ns) 2312105013 - 你应该记住,DTrace 脚本需要细心地编写和调试,否则被收集的追踪信息可能会毫无意义。在大部分发现问题的情况中,它就是发生问题的部件,而不是底层系统。当讨论使用动态追踪发现的信息时,一定要附上使用的脚本以便其也被检查和讨论。 + 你应该记住,DTrace 脚本需要细心地编写和调试,否则被收集的追踪信息可能会毫无意义。在大多数发现问题的情况下,出错的是插桩,而不是底层系统。当讨论使用动态追踪发现的信息时,一定要附上使用的脚本以便其也被检查和讨论。 @@ -3602,7 +3613,7 @@ Total time (ns) 2312105013 - 决定探针名称以及探针可用的数据 + 决定探针名称以及要通过探针提供的数据 @@ -3616,7 +3627,7 @@ Total time (ns) 2312105013 - 如果pg_trace.h还不存在于包含该探针点的模块中,包括它,并且在源代码中期望的位置插入TRACE_POSTGRESQL探针宏 + 如果pg_trace.h尚未被包含该探针点的模块引用,则将它包含进来,并且在源代码中期望的位置插入TRACE_POSTGRESQL探针宏 @@ -3652,14 +3663,14 @@ Total time (ns) 2312105013 probe transaction__start(LocalTransactionId); - 注意探针名字中双下划线的使用。在一个使用探针的 DTrace 脚本中,双下划线需要被替换为一个连字符,因此 ,对用户而言transaction-start是文档名。 + 注意探针名字中双下划线的使用。在一个使用探针的 DTrace 脚本中,双下划线需要被替换为一个连字符,因此,文档中应向用户说明的名称是transaction-start - 在编译时,transaction__start被转换成一个宏调用TRACE_POSTGRESQL_TRANSACTION_START(注意这里是单下划线),可以通过包括头文件pg_trace.h获得。将宏调用加入到源代码中的合适位置。在这种情况下,看起来类似: + 在编译时,transaction__start被转换成一个名为TRACE_POSTGRESQL_TRANSACTION_START的宏(注意这里是单下划线),可以通过包含头文件pg_trace.h获得。将宏调用加入到源代码中的合适位置。在这种情况下,看起来类似: TRACE_POSTGRESQL_TRANSACTION_START(vxid.localTransactionId); @@ -3696,7 +3707,7 @@ TRACE_POSTGRESQL_TRANSACTION_START(vxid.localTransactionId); - 在大多数平台上,如果用编译了PostgreSQL,无论何时当控制经过一个追踪宏时,都会评估该宏的参数,即使没有进行追踪也会这样做。通常不需要担心你是否只在报告一些局部变量的值。但是要注意不要将开销大的函数调用放入参数中。如果你需要这样做,考虑通过检查追踪是否真的被启用来保护该宏: + 在大多数平台上,如果用编译了PostgreSQL,无论何时当控制经过一个追踪宏时,都会对该宏的参数求值,即使没有进行追踪也会这样做。如果只是报告少数局部变量的值,通常无需担心这一点。但是要注意不要将开销大的函数调用放入参数中。如果你需要这样做,考虑通过检查追踪是否真的被启用来保护该宏: if (TRACE_POSTGRESQL_TRANSACTION_START_ENABLED()) diff --git a/zh/10/mvcc.sgml b/zh/10/mvcc.sgml index 2c0e3d66..bead77c0 100644 --- a/zh/10/mvcc.sgml +++ b/zh/10/mvcc.sgml @@ -4,7 +4,7 @@ 并发控制 - concurrency + 并发 @@ -15,7 +15,7 @@ 介绍 - Multiversion Concurrency Control + 多版本并发控制 @@ -23,7 +23,7 @@ - Serializable Snapshot Isolation + 可串行化快照隔离 @@ -50,7 +50,7 @@ 事务隔离 - transaction isolation + 事务隔离 @@ -61,11 +61,14 @@ (这并不奇怪,如果事务的效果必须与一次只运行一个事务保持一致,又怎么可能看到由相互作用引起的任何现象呢?) - 各隔离级别所禁止的现象如下: + + 在各个级别上被禁止的现象有: + + 脏读 - dirty read + 脏读 @@ -77,7 +80,7 @@ 不可重复读 - nonrepeatable read + 不可重复读 @@ -89,7 +92,7 @@ 幻读 - phantom read + 幻读 @@ -101,7 +104,7 @@ 串行化异常 - serialization anomaly + 串行化异常 @@ -114,7 +117,7 @@ - transaction isolation level + 事务隔离级别 SQL 标准以及 PostgreSQL 实现的事务隔离级别见 @@ -241,12 +244,12 @@ 读已提交隔离级别 - transaction isolation level - read committed + 事务隔离级别 + 读已提交 - read committed + 读已提交 @@ -292,7 +295,7 @@ 由于上述规则,更新命令可能看到一个不一致的快照:它能够看到并发更新命令在它试图更新的同一行上的效果, 却看不到这些命令对数据库中其他行的影响。这种行为使得读已提交模式不适合涉及复杂搜索条件的命令; - 不过,对于较简单的场景它恰到好处。例如,考虑将 100 美元从一个账户转到另一个账户: + 不过,对于较简单的场景它恰到好处。例如,考虑以如下事务更新银行余额: BEGIN; @@ -301,13 +304,13 @@ UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 7534; COMMIT; - 如果另一个事务并发地尝试更改账户 7534 的余额,我们显然希望第二条语句从该账户行的已更新版本开始。 + 如果两个这样的事务并发地尝试更改账户 12345 的余额,我们显然希望第二个事务从该账户行的已更新版本开始。 因为每个命令只影响一个预先确定的行,让它看到该行的已更新版本不会造成任何麻烦的不一致。 在读已提交模式下,更复杂的用法可能产生不理想的结果。例如,考虑一个 - DELETE 命令,它所处理的数据会被另一个命令同时加入和移出其筛选条件。 + DELETE 命令,另一个命令正在修改数据,使某些行开始满足其筛选条件、另一些行不再满足。 假设 website 是一个有两行的表,其中 website.hits 分别等于 910: @@ -315,7 +318,7 @@ COMMIT; BEGIN; UPDATE website SET hits = hits + 1; --- run from another session: DELETE FROM website WHERE hits = 10; +-- 从另一个会话运行: DELETE FROM website WHERE hits = 10; COMMIT; @@ -343,12 +346,12 @@ COMMIT; 可重复读隔离级别 - transaction isolation level - repeatable read + 事务隔离级别 + 可重复读 - repeatable read + 可重复读 @@ -400,9 +403,7 @@ ERROR: could not serialize access due to concurrent update 可重复读模式提供了严格的保证,即每个事务都看到数据库的一个完全稳定的视图。 不过,这个视图并不一定总能与同一级别并发事务的某种串行(一次一个)执行保持一致。 - 例如,即使该级别上的只读事务可能看到一条控制记录被更新,表明某个批处理已经完成, - 但它并不一定能看到作为该批处理逻辑组成部分的某条明细记录, - 因为它读到的是控制记录的较早版本。如果不仔细使用显式锁来阻塞冲突事务, + 例如,即使是该级别的只读事务,也可能看到一条表明某批次已完成的控制记录,却看不到逻辑上属于该批次的某条明细记录,因为创建该明细记录的事务读取了控制记录的较早版本。如果不仔细使用显式锁来阻塞冲突事务, 试图依靠运行在这一隔离级别的事务来强制业务规则,往往无法正确工作。 @@ -410,7 +411,7 @@ ERROR: could not serialize access due to concurrent update 可重复读隔离级别是通过一种技术实现的,这种技术在学术数据库文献中以及某些其他数据库产品中被称为 快照隔离。与使用会降低并发性的传统加锁技术的系统相比, 其行为和性能可能会表现出差异。有些其他系统甚至把可重复读和快照隔离作为两个行为不同的独立隔离级别提供。 - 用来区分这两种技术的允许现象,直到 SQL 标准制定之后才被数据库研究人员正式定义,因此超出了本手册的范围。 + 用来区分这两种技术的允许现象,直到 SQL 标准制定之后才被数据库研究人员正式定义,并且超出了本手册的范围。 完整讨论请参阅 @@ -426,20 +427,20 @@ ERROR: could not serialize access due to concurrent update 可串行化隔离级别 - transaction isolation level - serializable + 事务隔离级别 + 可串行化 - serializable + 可串行化 - predicate locking + 谓词锁 - serialization anomaly + 串行化异常 @@ -469,13 +470,13 @@ ERROR: could not serialize access due to read/write dependencies among transact 当依赖可串行化事务来防止异常时,重要的是:从永久用户表读取的任何数据,在读取它的事务成功提交之前, - 都不应视为有效。即使对于只读事务也是如此;唯一的例外是可推迟只读事务中读取的数据, + 都不应视为有效。即使对于只读事务也是如此;唯一的例外是可延迟只读事务中读取的数据, 它一经读出就可视为有效,因为这种事务会等到能够获取一个保证不存在此类问题的快照后才开始读取数据。 在所有其他情况下,应用不能依赖后来被中止事务中读到的结果;相反,应重试事务直到成功。 - 为了保证真正的可串行化,PostgreSQL 使用了谓词锁, + 为了保证真正的可串行性,PostgreSQL 使用了谓词锁, 也就是说,系统会保留一些锁,以便判断某个写操作如果先发生,是否会影响并发事务先前读取的结果。 在 PostgreSQL 中,这些锁不会造成任何阻塞,因此会参与形成死锁。 它们用于识别并标记并发可串行化事务之间的依赖关系,而这些依赖在某些组合下可能导致串行化异常。 @@ -497,7 +498,7 @@ ERROR: could not serialize access due to read/write dependencies among transact - 持续使用可串行化事务可以简化开发。任何一组成功提交的并发可串行化事务,都保证与把它们一次一个运行的效果相同;这意味着,如果你能够证明某个事务在单独运行时会做正确的事,那么即使不了解其他事务会做什么,也可以相信它在任何可串行化事务的混合执行中也会做正确的事,否则它就不会成功提交。重要的是,采用这种技术的环境应当有一套通用机制来处理串行化失败(其 SQLSTATE 值总是 '40001'),因为很难准确预测究竟哪些事务会对读/写依赖关系有贡献,并因此需要被回滚来防止串行化异常。监视读/写依赖关系会带来开销,被串行化失败中止的事务重新启动也会带来开销;但在把这些开销与显式锁以及 SELECT FOR UPDATESELECT FOR SHARE 所涉及的成本和阻塞进行权衡之后,可串行化事务在某些环境中仍然是性能最佳的选择。 + 统一采用可串行化事务可以简化开发。任何一组成功提交的并发可串行化事务,都保证与把它们一次一个运行的效果相同;这意味着,如果你能够证明某个事务在单独运行时会做正确的事,那么即使不了解其他事务会做什么,也可以相信它在任何可串行化事务的混合执行中也会做正确的事,否则它就不会成功提交。重要的是,采用这种技术的环境应当有一套通用机制来处理串行化失败(其 SQLSTATE 值总是 '40001'),因为很难准确预测究竟哪些事务会对读/写依赖关系有贡献,并因此需要被回滚来防止串行化异常。监视读/写依赖关系会带来开销,被串行化失败中止的事务重新启动也会带来开销;但在把这些开销与显式锁以及 SELECT FOR UPDATESELECT FOR SHARE 所涉及的成本和阻塞进行权衡之后,可串行化事务在某些环境中仍然是性能最佳的选择。 @@ -541,7 +542,7 @@ ERROR: could not serialize access due to read/write dependencies among transact - 当系统因谓词锁表内存不足而被迫把多个页级谓词锁合并为单个关系级谓词锁时,串行化失败的比例可能会上升。你可以通过增加 来避免这种情况。 + 当系统因谓词锁表内存不足而被迫把多个页级谓词锁合并为单个关系级谓词锁时,串行化失败的比例可能会上升。你可以通过增加 和/或 来避免这种情况。 @@ -565,7 +566,7 @@ ERROR: could not serialize access due to read/write dependencies among transact 显式锁定 - lock + @@ -909,7 +910,7 @@ ERROR: could not serialize access due to read/write dependencies among transact - 行为与 FOR SHARE 类似,不过锁更弱:SELECT FOR UPDATE 会被阻塞,但 SELECT FOR NO KEY UPDATE 不会。键共享锁会阻塞其他事务执行会修改键值的 DELETEUPDATE,但不会阻塞其他 UPDATE,也不会阻止 SELECT FOR NO KEY UPDATESELECT FOR SHARESELECT FOR KEY SHARE。 + 行为与 FOR SHARE 类似,不过锁更弱:SELECT FOR UPDATE 会被阻塞,但 SELECT FOR NO KEY UPDATE 不会。键共享锁会阻塞其他事务执行 DELETE 或任何会修改键值的 UPDATE,但不会阻塞其他 UPDATE,也不会阻止 SELECT FOR NO KEY UPDATESELECT FOR SHARESELECT FOR KEY SHARE @@ -984,7 +985,7 @@ ERROR: could not serialize access due to read/write dependencies among transact 死锁 - deadlock + 死锁 @@ -1027,12 +1028,12 @@ UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 22222; 咨询锁 - advisory lock + 咨询锁 - lock - advisory + + 咨询 @@ -1064,12 +1065,12 @@ UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 22222; 在某些使用咨询锁的方法中,特别是涉及显式排序和 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(id) FROM foo WHERE id = 12345; -- 可以 +SELECT pg_advisory_lock(id) FROM foo WHERE id > 12345 LIMIT 100; -- 危险! SELECT pg_advisory_lock(q.id) FROM ( SELECT id FROM foo WHERE id > 12345 LIMIT 100 -) q; -- ok +) q; -- 可以 在上面的查询中,第二种形式是危险的,因为不能保证在执行加锁函数之前先应用 LIMIT。 这可能导致获取了一些应用并未预期的锁,因此应用也不会去释放它们(直到会话结束)。 @@ -1087,12 +1088,12 @@ SELECT pg_advisory_lock(q.id) FROM 应用级别的数据一致性检查 - 在读已提交事务下,想要通过业务规则强制数据一致性非常困难,因为数据视图会随每条语句而变化, + 用读已提交事务强制执行有关数据完整性的业务规则非常困难,因为数据视图会随每条语句而变化, 而且一旦发生写冲突,即使是单条语句也未必局限于该语句自己的快照。 - 虽然可重复读事务在整个执行期间都具有稳定的数据视图,但在使用 MVCC 快照进行数据一致性检查时,还存在一个微妙问题,即所谓的读/写冲突。如果一个事务写入数据,而并发事务试图读取相同的数据(无论是在写入之前还是之后),它都看不到另一个事务的工作。于是,读取者看起来就像是先执行的一方,而不管究竟是谁先启动,也不管谁先提交。如果事情只停留在这一步,就没有问题;但如果读取者还写入了数据,而这些数据又被另一个并发事务读取,那么现在就会有一个事务看起来像是在前面提到的任一事务之前执行。如果看起来最后执行的事务实际上最先提交,就很容易在事务执行顺序图中形成一个环。一旦出现这样的环,不借助额外机制,一致性检查就无法正确工作。 + 虽然可重复读事务在整个执行期间都具有稳定的数据视图,但在使用 MVCC 快照进行数据一致性检查时,还存在一个微妙问题,即所谓的读/写冲突。如果一个事务写入数据,而并发事务试图读取相同的数据(无论是在写入之前还是之后),它都看不到另一个事务的工作。于是,读取者看起来就像是先执行的一方,而不管究竟是谁先启动,也不管谁先提交。如果事情只停留在这一步,就没有问题;但如果读取者还写入了数据,而这些数据又被另一个并发事务读取,那么现在就会有一个事务看起来像是在前面提到的任一事务之前执行。如果看起来最后执行的事务实际上最先提交,就很容易在事务执行顺序图中形成一个环。一旦出现这样的环,不借助额外机制,完整性检查就无法正确工作。 @@ -1109,7 +1110,7 @@ SELECT pg_advisory_lock(q.id) FROM - 使用这种技术时,如果应用软件通过某个框架运行,并由该框架自动重试因串行化错误而回滚的事务,就可以避免给应用程序员带来不必要的负担。把 default_transaction_isolation 设置为 serializable 可能是个好主意。通过在触发器中检查事务隔离级别来采取某些措施,以确保不会因为疏忽或为了绕过完整性检查而使用其他事务隔离级别,也是明智的。 + 使用这种技术时,如果应用软件通过某个框架运行,并由该框架自动重试因串行化失败而回滚的事务,就可以避免给应用程序员带来不必要的负担。把 default_transaction_isolation 设置为 serializable 可能是个好主意。通过在触发器中检查事务隔离级别来采取某些措施,以确保不会因为疏忽或为了绕过完整性检查而使用其他事务隔离级别,也是明智的。 @@ -1118,8 +1119,8 @@ SELECT pg_advisory_lock(q.id) FROM - 利用可串行化事务提供的这一层完整性保护,尚未扩展到热备模式()或逻辑副本。 - 因此,使用热备或逻辑复制的用户可能希望在主库上使用可重复读和显式锁定。 + 利用可串行化事务提供的这一层完整性保护,尚未扩展到热备模式()。 + 因此,使用热备的用户可能希望在主库上使用可重复读和显式锁定。 @@ -1148,7 +1149,7 @@ SELECT pg_advisory_lock(q.id) FROM 在非可串行化的 MVCC 环境下,全局有效性检查需要额外考虑。 - 例如,一个银行应用可能希望检查一个表中的所有收入总和等于另一个表中的所有支出总和, + 例如,一个银行应用可能希望检查一个表中的贷方金额总和等于另一个表中的借方金额总和, 而这两个表都在被活跃更新。在读已提交模式下,比较两个连续的 SELECT sum(...) 命令的结果并不可靠,因为第二个查询很可能会包含第一个查询没有统计到的事务提交结果。 在单个可重复读事务中完成这两次求和,只能准确反映在该可重复读事务开始之前已提交事务的效果 @@ -1196,18 +1197,21 @@ SELECT pg_advisory_lock(q.id) FROM 锁定和索引 - index - locks + 索引 + - 虽然PostgreSQL提供了对表数据的非阻塞读写访问,但目前并非所有已实现的索引访问方法都具备这种能力。下面按索引类型说明PostgreSQL的处理方式: + + 尽管 PostgreSQL 为表数据提供了非阻塞的读写访问,但 PostgreSQL 当前实现的索引访问方法并不是每一种都能提供非阻塞的读写访问。各种索引类型的处理方式如下: + + B-树、GiSTSP-GiST 索引 - 读写访问使用短期的页级共享/排他锁。每个索引行在被取出或插入之后,锁都会立即释放。这些索引类型在不存在死锁条件的前提下提供了最高的并发性。 + 读写访问使用短期的页级共享/排他锁。每个索引行在被取出或插入之后,锁都会立即释放。这些索引类型提供最高的并发性,并且不会产生死锁。 @@ -1229,7 +1233,7 @@ SELECT pg_advisory_lock(q.id) FROM - 读写访问使用短期的页级共享/排他锁。每个索引行在被取出或插入之后,锁都会立即释放。但要注意,插入一个 GIN 索引值通常会导致每行产生多个索引键插入,因此 GIN 可能为了插入单个值而做大量工作。 + 读写访问使用短期的页级共享/排他锁。每个索引行在被取出或插入之后,锁都会立即释放。但要注意,插入一个使用 GIN 索引的值通常会导致每行产生多个索引键插入,因此 GIN 可能为了插入单个值而做大量工作。 diff --git a/zh/10/oid2name.sgml b/zh/10/oid2name.sgml index aae0a030..4b995570 100644 --- a/zh/10/oid2name.sgml +++ b/zh/10/oid2name.sgml @@ -8,7 +8,7 @@ oid2name 1 - Application + 应用程序 diff --git a/zh/10/pgbuffercache.sgml b/zh/10/pgbuffercache.sgml index e4d4e994..67d89b60 100644 --- a/zh/10/pgbuffercache.sgml +++ b/zh/10/pgbuffercache.sgml @@ -37,7 +37,7 @@ - Name + 名称 类型 引用 diff --git a/zh/10/pgcrypto.sgml b/zh/10/pgcrypto.sgml index 9ff7487a..f67bd102 100644 --- a/zh/10/pgcrypto.sgml +++ b/zh/10/pgcrypto.sgml @@ -210,14 +210,14 @@ gen_salt(type text [, iter_count integer ]) returns text - type参数指定哈希算法。 + type参数指定 hash 算法。 接受的类型有:desxdesmd5bf iter_count参数允许用户为支持该参数的算法指定迭代次数。 - 次数越高,密码哈希所需时间越长,从而破解它所需时间也越长。 - 不过,如果次数过高,计算一个哈希可能需要数年时间 — 这显然不切实际。 + 次数越高,对密码进行 hash 所需的时间越长,从而破解它所需时间也越长。 + 不过,如果次数过高,计算一个 hash 可能需要数年时间 — 这显然不切实际。 若省略iter_count参数,则使用默认迭代次数。 允许的iter_count值取决于算法,如所示。 @@ -255,24 +255,24 @@ gen_salt(type text [, iter_count integer ]) returns text - 为了选择合适的迭代次数,可以考虑原始 DES crypt 在当时硬件上的设计速度是每秒 4 次哈希。 - 低于每秒 4 次哈希可能会影响可用性,而高于每秒 100 次哈希则很可能过快。 + 为了选择合适的迭代次数,可以考虑原始 DES crypt 在当时硬件上的设计速度是每秒 4 次 hash。 + 低于每秒 4 次 hash 可能会影响可用性,而高于每秒 100 次 hash 则很可能过快。 - 概述了不同哈希算法之间的相对速度差异。 + 概述了不同 hash 算法之间的相对速度差异。 该表展示了在 8 字符密码上尝试所有字符组合所需的时间,假定密码只包含小写字母, 或者包含大小写字母和数字。在crypt-bf条目中, 斜杠后的数字是gen_saltiter_count参数值。
- 哈希算法速度 + Hash 算法速度 算法 - 每秒哈希次数 + 每秒 hash 次数 针对[a-z] 针对[A-Za-z0-9] 相对于md5 hash的耗时倍数 diff --git a/zh/10/pgstandby.sgml b/zh/10/pgstandby.sgml index 39b07c22..1c051a82 100644 --- a/zh/10/pgstandby.sgml +++ b/zh/10/pgstandby.sgml @@ -8,7 +8,7 @@ pg_standby 1 - Application + 应用程序 diff --git a/zh/10/pgstatstatements.sgml b/zh/10/pgstatstatements.sgml index 12d708d0..171e7deb 100644 --- a/zh/10/pgstatstatements.sgml +++ b/zh/10/pgstatstatements.sgml @@ -24,7 +24,7 @@ - Name + 名称 类型 引用 diff --git a/zh/10/plhandler.sgml b/zh/10/plhandler.sgml index 2eb441b2..6a52cf63 100644 --- a/zh/10/plhandler.sgml +++ b/zh/10/plhandler.sgml @@ -1,7 +1,7 @@ - 编写过程语言处理器 + 编写过程语言调用处理器 过程语言 @@ -16,17 +16,17 @@ 过程语言的调用处理器是一个普通函数,必须使用诸如 C 这样的编译型语言、按照版本 1 接口编写,并在 PostgreSQL 中注册为不接受参数且返回 language_handler 类型。这个特殊伪类型会将该函数标识为调用处理器,并阻止它在 SQL 命令中被直接调用。有关 C 语言调用约定和动态装载的更多细节,见 。 - 调用处理器与其他函数的调用方式相同:它接收一个指向 FunctionCallInfoData struct 的指针,其中包含参数值和被调用函数的信息,并应返回一个 Datum 结果(如果要返回 SQL 空值,还可能需要设置 FunctionCallInfoData 结构的 isnull 字段)。调用处理器与普通被调用函数的区别在于,FunctionCallInfoData 结构的 flinfo->fn_oid 字段包含的是实际要调用的函数的 OID,而不是调用处理器自身的 OID。调用处理器必须使用该字段确定应执行哪个函数。此外,传入的参数列表也是按照目标函数的声明设置的,而不是按照调用处理器的声明。 + 调用处理器与其他函数的调用方式相同:它接收一个指向 FunctionCallInfoData struct 的指针,其中包含参数值和被调用函数的信息,并应返回一个 Datum 结果(如果要返回 SQL 空值,还需要设置 FunctionCallInfoData 结构体的 isnull 字段)。调用处理器与普通被调用函数的区别在于,FunctionCallInfoData 结构体的 flinfo->fn_oid 字段包含的是实际要调用的函数的 OID,而不是调用处理器自身的 OID。调用处理器必须使用该字段确定应执行哪个函数。此外,传入的参数列表也是按照目标函数的声明设置的,而不是按照调用处理器的声明。 - 调用处理器必须从系统目录 pg_proc 中取出该函数的条目,并分析被调用函数的参数类型和返回类型。该函数的 AS 子句可在其 CREATE FUNCTION 命令对应的 prosrc 列里找到,也就是 pg_proc 行中的该列。这里通常是一段过程语言源文本,但理论上也可以是其他内容,例如某个文件的路径名,或者任何能详细告诉调用处理器该做什么的信息。 + 调用处理器必须从系统目录 pg_proc 中取出该函数的条目,并分析被调用函数的参数类型和返回类型。该函数的 CREATE FUNCTION 命令中的 AS 子句内容,保存在 pg_proc 对应行的 prosrc 列中。这里通常是一段过程语言源文本,但理论上也可以是其他内容,例如某个文件的路径名,或者任何能详细告诉调用处理器该做什么的信息。 同一个函数在执行一条 SQL 语句期间往往会被调用很多次。调用处理器可以利用 flinfo->fn_extra 字段,避免重复查找被调用函数的信息。该字段起初为 NULL,但调用处理器可以把它设置为指向与被调用函数有关的信息。在后续调用中,如果 flinfo->fn_extra 已经不是 NULL,就可以直接使用它并跳过信息查找步骤。调用处理器必须确保 flinfo->fn_extra 指向的内存至少能存活到当前查询结束,因为 FmgrInfo 数据结构可能会保留这么久。一种做法是在 flinfo->fn_mcxt 指定的内存上下文中分配这些额外数据;这类数据通常会与 FmgrInfo 本身具有相同的生命周期。不过,处理器也可以选择使用生命周期更长的内存上下文,以便跨查询缓存函数定义信息。 - 过程语言函数作为触发器调用时,不会按通常方式传入参数,但 FunctionCallInfoDatacontext 字段会指向一个 TriggerData 结构,而不是像普通函数调用那样为 NULL。语言处理器应提供让过程语言函数获取触发器信息的机制。 + 过程语言函数作为触发器调用时,不会按通常方式传入参数,但 FunctionCallInfoDatacontext 字段会指向一个 TriggerData 结构体,而不是像普通函数调用那样为 NULL。语言调用处理器应提供让过程语言函数获取触发器信息的机制。 下面是用 C 编写的过程语言处理器模板: #include "postgres.h" @@ -52,7 +52,7 @@ plsample_call_handler(PG_FUNCTION_ARGS) if (CALLED_AS_TRIGGER(fcinfo)) { /* - * Called as a trigger procedure + * 作为触发器过程调用 */ TriggerData *trigdata = (TriggerData *) fcinfo->context; @@ -61,7 +61,7 @@ plsample_call_handler(PG_FUNCTION_ARGS) else { /* - * Called as a function + * 作为函数调用 */ retval = ... diff --git a/zh/10/plperl.sgml b/zh/10/plperl.sgml index e279aae4..76f5797b 100644 --- a/zh/10/plperl.sgml +++ b/zh/10/plperl.sgml @@ -23,8 +23,7 @@ - 如果把该语言安装到 template1 中,之后创建的所有 - 数据库都会自动安装该语言。 + 如果把某种语言安装到template1中,之后创建的所有数据库都会自动安装该语言。 @@ -40,18 +39,28 @@ PL/Perl 函数和参数 - 要创建 PL/Perl 语言函数,请使用标准的 语法: + + 要用 PL/Perl 语言创建一个函数,可使用标准的 + 语法: + + CREATE FUNCTION funcname (argument-types) RETURNS return-type AS $$ - # PL/Perl function body + # PL/Perl 函数体 $$ LANGUAGE plperl; -函数体就是普通的 Perl 代码。实际上,PL/Perl 的衔接代码会将其包装在一个 Perl 子例程中。PL/Perl 函数在标量上下文中调用,因此不能返回列表。可以通过返回引用来返回非标量值(数组、记录和集合),详见下文。 + + + 函数的主体就是普通的 Perl 代码。事实上,PL/Perl 的粘合代码会把它 + 包裹在一个 Perl 子程序中。PL/Perl 函数在标量上下文中被调用,因此 + 不能返回列表。如下文所述,可以通过返回引用来返回 + 非标量值(数组、记录和集合)。 + PL/Perl 也支持用 语句调用的匿名代码块: DO $$ - # PL/Perl code + # PL/Perl 代码 $$ LANGUAGE plperl; @@ -109,15 +118,14 @@ $$ LANGUAGE plperl; 如果一个 SQL 空值空值in PL/Perl被传给一个函数,在 - Perl 中该参数值将呈现为undefined。上述函数定义对于 - 空输入的行为并不理想(实际上,它会把它们当作零)。我们可以在函数 + sortas="PL/Perl">在 PL/Perl 中被传给一个函数,在 + Perl 中该参数值将呈现为未定义。上述函数定义对于 + 空值输入的行为并不理想(实际上,它会把它们当作零)。我们可以在函数 定义中添加 STRICT,让 PostgreSQL 采取更合理的做法:如果传入空值, - 函数将根本不会被调用,而是自动返回空结果。另一种方式是在函数体中 + 函数将根本不会被调用,而是自动返回空值结果。另一种方式是在函数体中 检查未定义输入。例如,假设我们希望在 - perl_max 的两个参数中一个为空、另一个非空时, - 返回非空参数而不是空值: + perl_max 的两个参数中一个为空值、另一个非空值时,返回非空值参数而不是空值: CREATE FUNCTION perl_max (integer, integer) RETURNS integer AS $$ @@ -177,12 +185,12 @@ CREATE OR REPLACE FUNCTION concat_array_elements(text[]) RETURNS TEXT AS $$ my $result = ""; return undef if (!defined $arg); - # as an array reference + # 作为数组引用 for (@$arg) { $result .= $_; } - # also works as a string + # 也可以作为字符串使用 $result .= $arg; return $result; @@ -193,7 +201,8 @@ SELECT concat_array_elements(ARRAY['PL','/','Perl']); - 多维数组会以所有 Perl 程序员都熟悉的方式,表示为对低维数组引用的引用。 + 多维数组按 Perl 程序员熟悉的方式表示为指向较低维数组的引用, + 而这些数组的元素又是引用。 @@ -289,11 +298,11 @@ SELECT * FROM perl_set(); 如果希望在代码中使用 strict 编译指示,可以有几种 选择。对于临时的全局用法,可以 SET - plperl.use_strict 为 true。这会影响后续编译的 + plperl.use_strict 为真。这会影响后续编译的 PL/Perl 函数,但不会影响当前会话中已经编译的 函数。对于永久的全局用法,可以在 postgresql.conf 文件中将 - plperl.use_strict 设为 true。 + plperl.use_strict 设为真。 @@ -399,21 +408,21 @@ SELECT * FROM test_munge(); spi_query(command) spi_query - in PL/Perl + 在 PL/Perl 中 spi_fetchrow(cursor) spi_fetchrow - in PL/Perl + 在 PL/Perl 中 spi_cursor_close(cursor) spi_cursor_close - in PL/Perl + 在 PL/Perl 中 @@ -433,7 +442,7 @@ CREATE OR REPLACE FUNCTION lotsa_md5 (INTEGER) RETURNS SETOF foo_type AS $$ my $file = '/usr/share/dict/words'; my $t = localtime; elog(NOTICE, "opening file $file at $t" ); - open my $fh, '<', $file # ooh, it's a file access! + open my $fh, '<', $file # 注意,这里访问了文件! or elog(ERROR, "cannot open $file for reading: $!"); my @words = <$fh>; close $fh; @@ -472,28 +481,28 @@ SELECT * from lotsa_md5(500); spi_prepare(command, argument types) spi_prepare - in PL/Perl + 在 PL/Perl 中 spi_query_prepared(plan, arguments) spi_query_prepared - in PL/Perl + 在 PL/Perl 中 spi_exec_prepared(plan [, attributes], arguments) spi_exec_prepared - in PL/Perl + 在 PL/Perl 中 spi_freeplan(plan) spi_freeplan - in PL/Perl + 在 PL/Perl 中 @@ -505,7 +514,7 @@ $plan = spi_prepare('SELECT * FROM test WHERE id > $1 AND name = $2', 调用 spi_prepare 预备查询计划后,就可以使用该计划代替查询字符串。可以将其用于 spi_exec_prepared,其结果与以下函数返回的结果相同:spi_exec_query;也可以用于 spi_query_prepared,它返回游标,行为与 spi_query 完全相同。随后可以将该游标传给 spi_fetchrowspi_exec_prepared 可选的第二个参数是属性哈希引用;目前唯一支持的属性是 limit,用于设置查询返回的最大行数。 - 预处理查询的优点在于,一个准备好的计划可以用于多次查询执行。当计划 + 预备查询的优点在于,一个准备好的计划可以用于多次查询执行。当计划 不再需要时,可以用 spi_freeplan 将其释放: CREATE OR REPLACE FUNCTION init() RETURNS VOID AS $$ @@ -579,7 +588,7 @@ SELECT release_hosts_query(); - PL/Perl 中的工具函数 + PL/Perl 中的辅助函数 @@ -587,7 +596,7 @@ SELECT release_hosts_query(); elog(level, msg) elog - in PL/Perl + 在 PL/Perl 中 @@ -612,7 +621,7 @@ SELECT release_hosts_query(); quote_literal(string) quote_literal - in PL/Perl + 在 PL/Perl 中 @@ -632,7 +641,7 @@ SELECT release_hosts_query(); quote_nullable(string) quote_nullable - in PL/Perl + 在 PL/Perl 中 @@ -650,7 +659,7 @@ SELECT release_hosts_query(); quote_ident(string) quote_ident - in PL/Perl + 在 PL/Perl 中 @@ -668,7 +677,7 @@ SELECT release_hosts_query(); decode_bytea(string) decode_bytea - in PL/Perl + 在 PL/Perl 中 @@ -685,7 +694,7 @@ SELECT release_hosts_query(); encode_bytea(string) encode_bytea - in PL/Perl + 在 PL/Perl 中 @@ -701,7 +710,7 @@ SELECT release_hosts_query(); encode_array_literal(array) encode_array_literal - in PL/Perl + 在 PL/Perl 中 @@ -723,7 +732,7 @@ SELECT release_hosts_query(); encode_typed_literal(value, typename) encode_typed_literal - in PL/Perl + 在 PL/Perl 中 @@ -740,7 +749,7 @@ SELECT release_hosts_query(); encode_array_constructor(array) encode_array_constructor - in PL/Perl + 在 PL/Perl 中 @@ -760,7 +769,7 @@ SELECT release_hosts_query(); looks_like_number(string) looks_like_number - in PL/Perl + 在 PL/Perl 中 @@ -779,11 +788,15 @@ SELECT release_hosts_query(); is_array_ref(argument) is_array_ref - in PL/Perl + 在 PL/Perl 中 - 如果给定参数可以作为数组引用处理,即参数的 ref 为 ARRAYPostgreSQL::InServer::ARRAY,则返回真值;否则返回假值。 + + 如果给定参数可被视为数组引用,则返回真值;也就是该参数的 + ref 值为 ARRAY 或 + PostgreSQL::InServer::ARRAY。否则返回假值。 + @@ -832,9 +845,9 @@ CREATE OR REPLACE FUNCTION myfuncs() RETURNS void AS $$ }; $$ LANGUAGE plperl; -SELECT myfuncs(); /* initializes the function */ +SELECT myfuncs(); /* 初始化函数 */ -/* Set up a function that uses the quote function */ +/* 创建一个使用加引号函数的函数 */ CREATE OR REPLACE FUNCTION use_quote(TEXT) RETURNS text AS $$ my $text_to_quote = shift; @@ -849,11 +862,9 @@ $$ LANGUAGE plperl; - 出于安全原因,PL/Perl 会为某个 SQL 角色调用的函数在该角色专用的独立 - Perl 解释器中执行。这可以防止一个用户意外或恶意地干扰另一个用户的 + 出于安全原因,PL/Perl 会在每个 SQL 角色各自独立的 Perl 解释器中执行该角色调用的函数。这可以防止一个用户意外或恶意地干扰另一个用户的 PL/Perl 函数行为。每个这样的解释器都有自己的 - %_SHARED 变量值和其他全局状态。因此,只有在两个 - PL/Perl 函数都由同一 SQL 角色执行时,它们才会共享 + %_SHARED 变量值和其他全局状态。因此,当且仅当两个 PL/Perl 函数都由同一 SQL 角色执行时,它们才会共享 %_SHARED 的值。在某些应用中,一个会话可能会在多个 SQL 角色下执行代码(通过 SECURITY DEFINER 函数、 使用 SET ROLE 等),这时可能需要显式采取措施, @@ -865,20 +876,20 @@ $$ LANGUAGE plperl; - 可信与不可信的 PL/Perl + 受信任与不受信任的 PL/Perl - trusted + 受信任的 PL/Perl 通常,PL/Perl 会被安装为一种名为 plperl 的 - 可信编程语言。在这种设置下,为了保持安全性,某些 Perl + 受信任的编程语言。在这种设置下,为了保持安全性,某些 Perl 操作会被禁用。一般来说,受限制的是那些与环境交互的操作,包括文件句柄 操作、requireuse (针对外部模块)。它无法像 C 函数那样访问数据库服务器进程的内部, - 也无法以服务器进程的权限获取操作系统级访问。因此,可以允许任何无权限 + 也无法以服务器进程的权限获取操作系统级访问。因此,可以允许任何无特权 的数据库用户使用这种语言。 @@ -900,16 +911,16 @@ $$ LANGUAGE plperl; 有时需要编写不受这些限制的 Perl 函数。例如,可能需要一个能发送邮件的 Perl 函数。为处理这类情况,也可以把 PL/Perl 安装成一种 - 不可信语言(通常称为 + 不受信任的语言(通常称为 PL/PerlUPL/PerlU)。 在这种情况下,完整的 Perl 语言都可用。安装该语言时,使用语言名 - plperlu 就会选择不可信的 PL/Perl 变体。 + plperlu 就会选择不受信任的 PL/Perl 变体。 PL/PerlU 函数的编写者必须注意,函数不能被 用于任何非预期用途,因为它能够执行以数据库管理员身份登录的用户所能 - 做的任何事情。请注意,数据库系统只允许数据库超级用户用不可信语言创建 + 做的任何事情。请注意,数据库系统只允许数据库超级用户用不受信任的语言创建 函数。 @@ -957,7 +968,13 @@ $$ LANGUAGE plperl; PL/Perl 触发器 - 可以用 PL/Perl 编写触发器函数。在触发器函数中,哈希引用 $_TD 包含当前触发器事件的信息。$_TD 是全局变量,每次触发器调用都有独立的局部值。以下是 $_TD 哈希引用的字段: + + PL/Perl 可用于编写触发器函数。在触发器函数中,哈希引用 + $_TD 包含有关当前触发器事件的信息。 + $_TD 是一个全局变量,对触发器的每一次调用都会得到 + 一个单独的局部值。$_TD 哈希引用包含以下字段: + + $_TD->{new}{foo} @@ -1037,7 +1054,7 @@ $$ LANGUAGE plperl; $_TD->{relname} - 触发该触发器的表名。该字段已废弃,并且可能会在未来版本中移除。 + 触发该触发器的表名。该字段已弃用,并且可能会在未来版本中移除。 请改用 $_TD->{table_name}。 @@ -1073,7 +1090,10 @@ $$ LANGUAGE plperl; - 行级触发器可以返回以下值之一: + + 行级触发器可以返回下列之一: + + return; @@ -1111,12 +1131,12 @@ CREATE TABLE test ( CREATE OR REPLACE FUNCTION valid_id() RETURNS trigger AS $$ if (($_TD->{new}{i} >= 100) || ($_TD->{new}{i} <= 0)) { - return "SKIP"; # skip INSERT/UPDATE command + return "SKIP"; # 跳过 INSERT/UPDATE 命令 } elsif ($_TD->{new}{v} ne "immortal") { $_TD->{new}{v} .= "(modified by trigger)"; - return "MODIFY"; # modify row and execute INSERT/UPDATE command + return "MODIFY"; # 修改行并执行 INSERT/UPDATE 命令 } else { - return; # execute INSERT/UPDATE command + return; # 执行 INSERT/UPDATE 命令 } $$ LANGUAGE plperl; @@ -1130,7 +1150,13 @@ CREATE TRIGGER test_valid_id_trig PL/Perl 事件触发器 - 可以用 PL/Perl 编写事件触发器函数。在事件触发器函数中,哈希引用 $_TD 包含当前触发器事件的信息。$_TD 是全局变量,每次触发器调用都有独立的局部值。以下是 $_TD 哈希引用的字段: + + PL/Perl 可用于编写事件触发器函数。在事件触发器函数中,哈希引用 + $_TD 包含有关当前触发器事件的信息。 + $_TD 是一个全局变量,对触发器的每一次调用都会得到 + 一个单独的局部值。$_TD 哈希引用包含以下字段: + + $_TD->{event} @@ -1261,7 +1287,7 @@ DO 'elog(WARNING, join ", ", sort keys %INC)' LANGUAGE plperl; 也会发生。这是在 plperl.on_init 完成的任何初始化 之后进行的。执行这段代码时 SPI 函数不可用。 plperl.on_plperl_init 中的 Perl 代码是在对解释器 - 进行锁定之后执行的,因此只能执行可信操作。 + 进行锁定之后执行的,因此只能执行受信任的操作。 @@ -1302,7 +1328,10 @@ DO 'elog(WARNING, join ", ", sort keys %INC)' LANGUAGE plperl; 限制与缺失特性 - PL/Perl 目前还缺少以下功能,欢迎贡献这些功能的实现。 + + PL/Perl 目前仍缺少下列特性,但欢迎为此作出贡献。 + + PL/Perl 函数不能直接调用彼此。 diff --git a/zh/10/plpgsql.sgml b/zh/10/plpgsql.sgml index 76a561dd..f86663f6 100644 --- a/zh/10/plpgsql.sgml +++ b/zh/10/plpgsql.sgml @@ -11,7 +11,9 @@ 概述 - PL/pgSQL是一种可装载的过程语言,适用于PostgreSQL数据库系统。PL/pgSQL的设计目标是创建一种具有以下特点的可装载过程语言: + PL/pgSQL 是一种用于 PostgreSQL 数据库系统的可载入过程语言。PL/pgSQL 的设计目标,是创建一种具备以下特性的可载入过程语言: + + 可用于创建函数和触发器函数, @@ -132,7 +134,7 @@ CREATE FUNCTION somefunc(integer, text) RETURNS integer AS 'function body text' LANGUAGE plpgsql; - 就 CREATE FUNCTION 而言,函数体目前只是一个字符串字面量。编写函数体时,通常最好使用美元引用(见 ),而不是普通的单引号语法。如果不使用美元引用,函数体中的任何单引号或反斜线都必须通过双写进行转义。本章几乎所有示例的函数体都使用了美元引用。 + 就 CREATE FUNCTION 而言,函数体只是一个字符串字面量。编写函数体时,通常最好使用美元引用(见 ),而不是普通的单引号语法。如果不使用美元引用,函数体中的任何单引号或反斜线都必须通过双写进行转义。本章几乎所有示例的函数体都使用了美元引用。 @@ -313,7 +315,7 @@ $$ LANGUAGE plpgsql; - 当 PL/pgSQL 函数声明了输出参数时,输出参数也会像普通输入参数一样获得 $n 名称和可选别名。输出参数本质上是一个初始值为 NULL 的变量,应在函数执行期间给它赋值。该参数的最终值就是返回值。例如,sales-tax 的示例也可以这样写: + 当 PL/pgSQL 函数声明了输出参数时,输出参数也会像普通输入参数一样获得 $n 名称和可选别名。输出参数本质上是一个初始值为 NULL 的变量,应在函数执行期间给它赋值。该参数的最终值就是返回值。例如,销售税的示例也可以这样写: CREATE FUNCTION sales_tax(subtotal real, OUT tax real) AS $$ @@ -326,14 +328,19 @@ $$ LANGUAGE plpgsql; 注意这里省略了 RETURNS real — 当然也可以写上,但那只是冗余。 - 输出参数在返回多个值时最有用。一个简单的例子是: + + 当需要返回多个值时,输出参数尤其有用。下面是一个简单示例: + + CREATE FUNCTION sum_n_product(x int, y int, OUT sum int, OUT prod int) AS $$ BEGIN sum := x + y; prod := x * y; END; $$ LANGUAGE plpgsql; -所述,这实际上为函数结果创建了一个匿名记录类型。如果给出RETURNS子句,它必须写为RETURNS record。 + + + 如 所述,这实际上会为函数结果创建一个匿名记录类型。如果写了 RETURNS 子句,它必须是 RETURNS record @@ -424,7 +431,9 @@ user_id users.user_id%TYPE; 使用 %TYPE 的好处是,你不必知道所引用结构的实际数据类型;更重要的是,如果被引用项的数据类型将来发生变化(例如把 user_id 的类型从 integer 改成 real),你可能就不需要修改函数定义。 - %TYPE在多态函数中特别有用,因为内部变量所需的数据类型可能在各次调用之间发生变化。可以对函数参数或结果占位符应用%TYPE,以创建适当的变量。 + + %TYPE 在多态函数中特别有价值,因为内部变量所需的数据类型可能在不同调用之间变化。可以把 %TYPE 应用到函数参数或结果占位符上,以创建合适的变量。 + @@ -440,9 +449,13 @@ user_id users.user_id%TYPE; 复合类型的变量称为变量(或行类型变量)。只要查询的列集合与该变量声明的类型相匹配,这种变量就可以保存 SELECTFOR 查询结果中的整行。行值的各个字段可以使用通常的点号记法访问,例如 rowvar.field - 可以使用table_name%ROWTYPE记号,将行变量声明为与现有表或视图的行具有相同类型;也可以通过给出复合类型名称来声明它。(因为每个表都有一个同名的关联复合类型,所以在PostgreSQL中,实际上写不写%ROWTYPE都没有区别。但带有%ROWTYPE的形式更易于移植。) + + 行变量既可以通过 table_name%ROWTYPE 记法声明为与现有表或视图的行具有相同类型,也可以通过给出某个复合类型的名称来声明。(由于每个表都有一个同名的关联复合类型,所以在 PostgreSQL 中实际上写不写 %ROWTYPE 并无区别;不过带 %ROWTYPE 的形式可移植性更好。) + - 函数参数可以是复合类型(完整的表行)。在这种情况下,相应的标识符$n将是一个行变量,可以从中选取字段,例如$1.user_id + + 函数参数也可以是复合类型(完整的表行)。在这种情况下,相应的标识符 $n 就是一个行变量,并且可以从中选取字段,例如 $1.user_id。 + 在行类型变量中,只能访问表行中用户定义的列,不能访问 OID 或其他系统列(因为该行可能来自视图)。对于char(n)这样的数据类型,行类型中的字段会继承表字段的大小或精度。 @@ -486,12 +499,12 @@ SELECT merge_fields(t.*) FROM table1 t WHERE ... ; <application>PL/pgSQL</application>变量的排序规则 - collation - in PL/pgSQL + 排序规则 + 在 PL/pgSQL 中 - 当 PL/pgSQL 函数具有一个或多个可排序数据类型参数时,每次函数调用都会根据分配给实际参数的排序规则确定出一个排序规则,如 所述。如果该排序规则能成功确定出来(即参数之间的隐式排序规则没有冲突),那么所有可排序参数都会被视为隐式带有该排序规则。这会影响函数中那些受排序规则影响的操作。例如,考虑 + 当 PL/pgSQL 函数具有一个或多个支持排序规则的数据类型参数时,每次函数调用都会根据分配给实际参数的排序规则确定出一个排序规则,如 所述。如果该排序规则能成功确定出来(即参数之间的隐式排序规则没有冲突),那么所有支持排序规则的参数都会被视为隐式带有该排序规则。这会影响函数中那些受排序规则影响的操作。例如,考虑 CREATE FUNCTION less_than(a text, b text) RETURNS boolean AS $$ @@ -508,7 +521,7 @@ SELECT less_than(text_field_1, text_field_2 COLLATE "C") FROM table1; - 此外,确定出的排序规则也会被视为任何可排序数据类型局部变量的排序规则。因此,即使把这个函数写成下面这样,其行为也不会有任何不同: + 此外,确定出的排序规则也会被视为任何支持排序规则的数据类型局部变量的排序规则。因此,即使把这个函数写成下面这样,其行为也不会有任何不同: CREATE FUNCTION less_than(a text, b text) RETURNS boolean AS $$ @@ -523,11 +536,11 @@ $$ LANGUAGE plpgsql; - 如果函数没有可排序数据类型的参数,或者无法为它们确定共同排序规则,那么参数和局部变量将使用其数据类型的默认排序规则(通常是数据库默认排序规则,但对于域类型变量也可能不同)。 + 如果函数没有支持排序规则的数据类型的参数,或者无法为它们确定共同排序规则,那么参数和局部变量将使用其数据类型的默认排序规则(通常是数据库默认排序规则,但对于域类型变量也可能不同)。 - 通过在可排序数据类型局部变量的声明中加入 COLLATE 选项,可以为其指定不同的排序规则,例如 + 通过在支持排序规则的数据类型局部变量的声明中加入 COLLATE 选项,可以为其指定不同的排序规则,例如 DECLARE @@ -632,12 +645,12 @@ PERFORM create_mv('cs_session_page_requests_mv', my_query); SELECT INTO - in PL/pgSQL + 在 PL/pgSQL 中 RETURNING INTO - in PL/pgSQL + 在 PL/pgSQL 中 产生单行(可能有多列)结果的 SQL 命令,其结果可以赋给记录变量、行类型变量或标量变量列表。方法是在基本 SQL 命令中添加INTO子句。例如: @@ -678,7 +691,7 @@ END; 成功执行带有STRICT的命令总会将FOUND设为真。 - 对于带有RETURNINGINSERT/UPDATE/DELETE/即使没有指定STRICTPL/pgSQL也会针对多于一个返回行的情况报告一个错误。这是因为没有类似于ORDER BY的选项可以用来决定应该返回哪个被影响的行。 + 对于带有RETURNINGINSERT/UPDATE/DELETE,即使没有指定STRICTPL/pgSQL也会针对多于一个返回行的情况报告一个错误。这是因为没有类似于ORDER BY的选项可以用来决定应该返回哪个被影响的行。 如果print_strict_params已为该函数启用,那么当不满足STRICT要求而抛出错误时,错误消息的DETAIL部分将包含传给查询的参数信息。可以为所有函数更改print_strict_params设置,方法是设置plpgsql.print_strict_params,不过只会影响随后编译的函数。也可以通过编译器选项逐函数启用,例如: @@ -715,25 +728,23 @@ CONTEXT: PL/pgSQL function get_userid(text) line 6 at SQL statement 执行动态命令 - 很多时候你将想要在PL/pgSQL函数中产生动态命令,也就是每次执行中会涉及到不同表或不同数据类型的命令。PL/pgSQL通常对于命令所做的缓存计划尝试(如中讨论)在这种情境下无法工作。要处理这一类问题,需要提供EXECUTE语句: + 很多时候你将想要在PL/pgSQL函数中产生动态命令,也就是每次执行中会涉及到不同表或不同数据类型的命令。PL/pgSQL通常对于命令所做的缓存计划尝试(如中讨论)在这种情境下无法工作。要处理这一类问题,提供了EXECUTE语句: EXECUTE command-string INTO STRICT target USING expression , ... ; - 其中command-string是一个能得到一个包含要被执行命令字符串(类型text)的表达式。可选的target是一个记录变量、一个行变量或者一个逗号分隔的简单变量以及记录/行域的列表,该命令的结果将存储在其中。可选的USING表达式提供要被插入到该命令中的值。 + 其中command-string是一个能得到一个包含要被执行命令字符串(类型text)的表达式。可选的target是一个记录变量、一个行变量或者一个逗号分隔的简单变量以及记录/行字段的列表,该命令的结果将存储在其中。可选的USING表达式提供要被插入到该命令中的值。 在计算得到的命令字符串中,不会做PL/pgSQL变量的替换。任何所需的变量值必须在命令字符串被构造时被插入其中,或者你可以使用下面描述的参数。 - - 还有,对于通过EXECUTE执行的命令不会有计划被缓存。该命令反而在每次运行时都会被做计划。因此,该命令字符串可以在执行不同表和列上动作的函数中被动态创建。 - + 此外,通过 EXECUTE 执行的命令不会缓存计划,而是在每次运行该语句时重新规划。因此,可以在函数中动态构造命令字符串,对不同的表和列执行操作。 - INTO子句指定一个返回行的 SQL 命令的结果应该被赋值到哪里。如果提供了一个行或变量列表,它必须完全匹配查询命令结果的结构(当一个记录变量被提供时,它会自动把它自己配置为匹配结果结构)。如果返回多个行,只有第一个行会被赋值给INTO变量。如果没有返回行,NULL 会被赋值给INTO变量。如果没有指定INTO子句,该查询结果会被抛弃。 + INTO子句指定一个返回行的 SQL 命令的结果应该被赋值到哪里。如果提供了一个行变量或变量列表,它必须完全匹配查询命令结果的结构(当一个记录变量被提供时,它会自动把它自己配置为匹配结果结构)。如果返回多个行,只有第一个行会被赋值给INTO变量。如果没有返回行,NULL 会被赋值给INTO变量。如果没有指定INTO子句,该查询结果会被抛弃。 @@ -741,7 +752,7 @@ EXECUTE command-string INT - 命令字符串可以使用参数值,它们在命令中用$1$2等引用。这些符号引用在USING子句中提供的值。这种方法常常更适合于把数据值作为文本插入到命令字符串中:它避免了将该值转换为文本以及转换回来的运行时负荷,并且它更不容易被 SQL 注入攻击,因为不需要引用或转义。一个示例是: + 命令字符串可以使用参数值,它们在命令中用$1$2等引用。这些符号引用在USING子句中提供的值。这种方法通常比把数据值作为文本插入命令字符串更可取:它避免了将该值转换为文本以及转换回来的运行时负荷,并且它更不容易被 SQL 注入攻击,因为不需要引用或转义。一个示例是: EXECUTE 'SELECT count(*) FROM mytable WHERE inserted_by = $1 AND inserted <= $2' INTO c @@ -763,7 +774,7 @@ EXECUTE format('SELECT count(*) FROM %I ' 参数符号的另一个限制是,它们只能用于SELECTINSERTUPDATE以及DELETE命令。在其他语句类型(统称为工具语句)中,即使只是数据值,也必须以文本形式插入。 - 在上面第一个示例中,带有一个简单的常量命令字符串和一些USING参数的EXECUTE命令在功能上等效于直接用PL/pgSQL写的命令,并且允许自动发生PL/pgSQL变量替换。重要的不同之处在于,EXECUTE会在每一次执行时根据当前的参数值重新计划该命令,而PL/pgSQL则是创建一个通用计划并且将其缓存以便重用。在最佳计划强依赖于参数值的情况中,使用EXECUTE来明确地保证不会选择一个通用计划是很有帮助的。 + 在上面第一个示例中,带有一个简单的常量命令字符串和一些USING参数的EXECUTE命令在功能上等效于直接用PL/pgSQL写的命令,并且允许自动发生PL/pgSQL变量替换。重要的不同之处在于,EXECUTE会在每一次执行时根据当前的参数值重新计划该命令,而PL/pgSQL则可能创建一个通用计划并且将其缓存以便重用。在最佳计划强依赖于参数值的情况中,使用EXECUTE来明确地保证不会选择一个通用计划是很有帮助的。 @@ -834,19 +845,19 @@ EXECUTE 'UPDATE tbl SET ' || ' WHERE key = ' || quote_nullable(keyvalue); - 如果正在处理的参数值可能为空,那么通常应该用quote_nullable来代替quote_literal。 + 如果正在处理的参数值可能为空值,那么通常应该用quote_nullable来代替quote_literal - 通常,必须小心地确保查询中的空值不会递送意料之外的结果。例如如果keyvalue为空,下面的WHERE子句 + 通常,必须小心地确保查询中的空值不会产生意料之外的结果。例如如果keyvalue为空值,下面的WHERE子句 'WHERE key = ' || quote_nullable(keyvalue) - 永远不会成功,因为在=操作符中使用空操作数得到的结果总是为空。如果想让空和一个普通键值一样工作,你应该将上面的命令重写成 + 永远不会成功,因为在=操作符中使用空值操作数得到的结果总是空值。如果想让空值像普通键值一样工作,你应该将上面的命令重写成 'WHERE key IS NOT DISTINCT FROM ' || quote_nullable(keyvalue) - (目前,IS NOT DISTINCT FROM的处理效率不如=,因此只有在非常必要时才这样做。关于空和IS DISTINCT的详细信息请见)。 + (目前,IS NOT DISTINCT FROM的处理效率不如=,因此只有在非常必要时才这样做。关于空值和IS DISTINCT的详细信息请见)。 @@ -859,7 +870,7 @@ EXECUTE 'UPDATE tbl SET ' || '$$ WHERE key = ' || quote_literal(keyvalue); - 因为如果newvalue的内容碰巧含有$$,那么这段代码就会出问题。同样的缺点可能适用于你选择的任何其他美元符号引用定界符。因此,要想安全地引用事先不知道的文本,必须恰当地使用quote_literalquote_nullablequote_ident。 + 因为如果newvalue的内容碰巧含有$$,那么这段代码就会出问题。同样的问题也适用于你选择的任何其他美元符号引用定界符。因此,要想安全地引用事先不知道的文本,必须恰当地使用quote_literalquote_nullablequote_ident @@ -898,7 +909,7 @@ EXECUTE format('UPDATE tbl SET %I = $1 WHERE key = $2', colname) GET CURRENT DIAGNOSTICS variable { = | := } item , ... ; - 这条命令允许检索系统状态指示符。CURRENT是一个噪声词(另见中的GET STACKED DIAGNOSTICS)。每个item是一个关键字, 它标识一个要被赋予给指定变量的状态值(变量应具有正确的数据类型来接收状态值)。中展示了当前可用的状态项。冒号等号(:=)可以被用来取代 SQL 标准的=符号。例如: + 这条命令允许检索系统状态指示符。CURRENT是一个噪声词(另见中的GET STACKED DIAGNOSTICS)。每个item是一个关键字, 它标识一个要被赋予给指定variable的状态值(变量应具有正确的数据类型来接收状态值)。中展示了当前可用的状态项。冒号等号(:=)可以被用来取代 SQL 标准的=符号。例如: GET DIAGNOSTICS integer_var = ROW_COUNT; @@ -935,10 +946,15 @@ GET DIAGNOSTICS integer_var = ROW_COUNT;
- 确定命令执行效果的第二种方法是检查名为FOUND的特殊变量,其类型为booleanFOUND的初始值为假,这适用于每次PL/pgSQL函数调用。以下各类语句都会设置它: + + 第二种确定命令效果的方法是检查名为FOUND的特殊变量,类型为boolean。 + 在每次PL/pgSQL函数调用中,FOUND的初始值都是 false。 + 它由以下类型的语句设置: + + - SELECT INTO语句在分配行时将FOUND设置为true, + SELECT INTO语句在为目标赋上一行值时将FOUND设置为true, 如果没有返回行则设置为false。 @@ -967,7 +983,7 @@ GET DIAGNOSTICS integer_var = ROW_COUNT; FORFOREACH语句在迭代一次或多次时将 FOUND设置为true,否则设置为false。 - 当循环退出时,FOUND被设置为这种方式; + 当循环退出时,FOUND会按上述方式设置; 在循环执行过程中,FOUND不会被循环语句修改, 尽管它可能会被循环体内的其他语句执行修改。 @@ -979,7 +995,11 @@ GET DIAGNOSTICS integer_var = ROW_COUNT; 如果没有返回行则设置为false。 - 其他PL/pgSQL语句不会改变以下变量的状态:FOUND。特别要注意的是,EXECUTE会改变GET DIAGNOSTICS的输出,但不会改变FOUND。 +
+ + 其他PL/pgSQL语句不会改变FOUND的状态。 + 特别注意,EXECUTE会改变GET DIAGNOSTICS的输出, + 但不会改变FOUND
@@ -999,12 +1019,14 @@ NULL; - 例如,下面两个代码片段是等价的: + + 例如,下面的两段代码是等价的: + BEGIN y := x / 0; EXCEPTION WHEN division_by_zero THEN - NULL; -- ignore the error + NULL; -- 忽略错误 END; @@ -1012,9 +1034,11 @@ END; BEGIN y := x / 0; EXCEPTION - WHEN division_by_zero THEN -- ignore the error + WHEN division_by_zero THEN -- 忽略错误 END; -选用哪一种取决于个人偏好。 + + 究竟使用哪一种取决于各人的喜好。 + @@ -1052,7 +1076,7 @@ RETURN expression; - 如果函数返回的是标量类型,表达式结果会自动转换为函数的返回类型。但如果要返回一个组合(行)值,你必须写出一个恰好生成所需列集合的表达式。这可能需要显式类型转换。 + 如果函数返回的是标量类型,表达式结果会按照赋值部分的说明自动转换为函数的返回类型。但如果要返回一个复合(行)值,你必须写出一个恰好生成所需列集合的表达式。这可能需要显式类型转换。 @@ -1064,17 +1088,20 @@ RETURN expression; - 一个函数的返回值不能是未定义。如果控制到达了函数最顶层的块而没有碰到一个RETURN语句,那么会发生一个运行时错误。不过,这个限制不适用于带输出参数的函数以及返回void的函数。在这些情况中,如果顶层的块结束,将自动执行一个RETURN语句。 + 一个函数的返回值不能是未定义。如果控制到达了函数最顶层块的末尾而没有碰到一个RETURN语句,那么会发生一个运行时错误。不过,这个限制不适用于带输出参数的函数以及返回void的函数。在这些情况中,如果顶层的块结束,将自动执行一个RETURN语句。 - 下面是一些例子: --- functions returning a scalar type + + 一些示例: + + +-- 返回一个标量类型的函数 RETURN 1 + 2; RETURN scalar_var; --- functions returning a composite type +-- 返回一个复合类型的函数 RETURN composite_type_var; -RETURN (1, 2, 'three'::text); -- must cast columns to correct types +RETURN (1, 2, 'three'::text); -- 必须把列类型转换成正确的类型 @@ -1083,11 +1110,11 @@ RETURN (1, 2, 'three'::text); -- must cast columns to correct types <command>RETURN NEXT</command> 和 <command>RETURN QUERY</command> RETURN NEXT - in PL/pgSQL + 在 PL/pgSQL 中 RETURN QUERY - in PL/pgSQL + 在 PL/pgSQL 中 @@ -1097,7 +1124,7 @@ RETURN QUERY EXECUTE command-string < - 当 PL/pgSQL 函数被声明为返回 SETOF sometype 时,返回过程会略有不同。在这种情况下,要返回的各个项通过一系列 RETURN NEXTRETURN QUERY 命令指定,最后再用一个不带参数的 RETURN 命令表明函数已经执行完毕。RETURN NEXT 可用于标量和组合数据类型;对于组合结果类型,会返回完整的结果RETURN QUERY 会把查询执行结果追加到函数的结果集中。在同一个集合返回函数中,RETURN NEXTRETURN QUERY 可以自由混用,此时它们的结果会被串接起来。 + 当 PL/pgSQL 函数被声明为返回 SETOF sometype 时,返回过程会略有不同。在这种情况下,要返回的各个项通过一系列 RETURN NEXTRETURN QUERY 命令指定,最后再用一个不带参数的 RETURN 命令表明函数已经执行完毕。RETURN NEXT 可用于标量和复合数据类型;对于复合结果类型,会返回完整的结果RETURN QUERY 会把查询执行结果追加到函数的结果集中。在同一个集合返回函数中,RETURN NEXTRETURN QUERY 可以自由混用,此时它们的结果会被串接起来。 @@ -1112,7 +1139,8 @@ RETURN QUERY EXECUTE command-string < 如果你声明函数带有输出参数,只需要写不带表达式的RETURN NEXT。在每一次执行时,输出参数变量的当前值将被保存下来用于最终返回为结果的一行。注意为了创建一个带有输出参数的集合返回函数,在有多个输出参数时,你必须声明函数为返回SETOF record;或者如果只有一个类型为sometype的输出参数时,声明函数为SETOF sometype - 下面的函数示例使用了RETURN NEXT: + + 下面是一个使用RETURN NEXT的函数示例: CREATE TABLE foo (fooid INT, foosubid INT, fooname TEXT); @@ -1127,8 +1155,8 @@ BEGIN FOR r IN SELECT * FROM foo WHERE fooid > 0 LOOP - -- can do some processing here - RETURN NEXT r; -- return current row of SELECT + -- 这里可以做一些处理 + RETURN NEXT r; -- 返回 SELECT 的当前行 END LOOP; RETURN; END; @@ -1297,7 +1325,7 @@ ELSIF number > 0 THEN ELSIF number < 0 THEN result := 'negative'; ELSE - -- 嗯,唯一的其他可能性是数字为空 + -- 嗯,唯一的其他可能性是 number 为 null result := 'NULL'; END IF; @@ -1400,12 +1428,12 @@ END CASE; 简单循环 - loop + 循环 在 PL/pgSQL 中 - 使用LOOPEXITCONTINUEWHILEFORFOREACH语句,你可以安排PL/pgSQL重复一系列命令。 + 使用LOOPEXITCONTINUEWHILEFORFOREACH语句,你可以安排PL/pgSQL函数重复一系列命令。 @@ -1451,26 +1479,28 @@ EXIT label WHEN BEGIN 块一起使用时,EXIT 会把控制转交给该块结束后的下一条语句。需要注意的是,为此必须使用标签;未加标签的 EXIT 永远不会被视为匹配某个 BEGIN 块。这与 PostgreSQL 8.4 之前的版本不同,旧版本允许未加标签的 EXIT 匹配 BEGIN 块。 - 例如: + + 示例: + LOOP - -- some computations + -- 一些计算 IF count > 0 THEN - EXIT; -- exit loop + EXIT; -- 退出循环 END IF; END LOOP; LOOP - -- some computations - EXIT WHEN count > 0; -- same result as previous example + -- 一些计算 + EXIT WHEN count > 0; -- 和前一个示例相同的结果 END LOOP; <<ablock>> BEGIN - -- some computations + -- 一些计算 IF stocks > 100000 THEN - EXIT ablock; -- causes exit from the BEGIN block + EXIT ablock; -- 导致从 BEGIN 块中退出 END IF; - -- computations here will be skipped when stocks > 100000 + -- 当stocks > 100000时,这里的计算将被跳过 END; @@ -1500,7 +1530,9 @@ CONTINUE label WHEN CONTINUE可以被用在所有类型的循环中,它并不限于在无条件循环中使用。 - 例如: + + 示例: + LOOP -- 一些计算 EXIT WHEN count > 100; @@ -1557,22 +1589,22 @@ END LOOP label ; - 这种形式的FOR会创建一个在一个整数范围上迭代的循环。变量name会自动定义为类型integer并且只在循环内存在(任何该变量名的现有定义在此循环内都将被忽略)。给出范围上下界的两个表达式在进入循环的时候计算一次。如果没有指定BY子句,迭代步长为 1,否则步长是BY中指定的值,该值也只在循环进入时计算一次。如果指定了REVERSE,那么在每次迭代后步长值会被减除而不是增加。 + 这种形式的FOR会创建一个在一个整数范围上迭代的循环。变量name会自动定义为类型integer并且只在循环内存在(任何该变量名的现有定义在此循环内都将被忽略)。给出范围上下界的两个表达式在进入循环的时候计算一次。如果没有指定BY子句,迭代步长为 1,否则步长是BY中指定的值,该值也只在循环进入时计算一次。如果指定了REVERSE,那么在每次迭代后会减去步长,而不是加上步长。 整数FOR循环的一些示例: FOR i IN 1..10 LOOP - -- 我在循环中将取值 1,2,3,4,5,6,7,8,9,10 + -- i 在循环中将取值 1,2,3,4,5,6,7,8,9,10 END LOOP; FOR i IN REVERSE 10..1 LOOP - -- 我在循环中将取值 10,9,8,7,6,5,4,3,2,1 + -- i 在循环中将取值 10,9,8,7,6,5,4,3,2,1 END LOOP; FOR i IN REVERSE 10..1 BY 2 LOOP - -- 我在循环中将取值 10,8,6,4,2 + -- i 在循环中将取值 10,8,6,4,2 END LOOP; @@ -1635,7 +1667,7 @@ $$ LANGUAGE plpgsql; - 在这类 FOR 语句中使用的 query,可以是任何向调用者返回行的 SQL 命令:最常见的是 SELECT,但也可以是带 RETURNING 子句的 INSERTUPDATEDELETE。某些实用程序命令,如 EXPLAIN,也可以用于此处。 + 在这类 FOR 语句中使用的 query,可以是任何向调用者返回行的 SQL 命令:最常见的是 SELECT,但也可以是带 RETURNING 子句的 INSERTUPDATEDELETE。某些工具命令,如 EXPLAIN,也可以用于此处。 PL/pgSQL变量会被替换到查询文本中,并且如中详细讨论的,查询计划会被缓存以用于可能的重用。 @@ -1648,7 +1680,7 @@ FOR target IN EXECUTE text_expressionstatements END LOOP label ; - 这个示例类似前面的形式,只不过源查询被指定为一个字符串表达式,在每次进入FOR循环时都会计算它并且重新计划。这允许程序员在一个预先计划好了的命令的速度和一个动态命令的灵活性之间进行选择,就像一个纯EXECUTE语句那样。在使用EXECUTE时,可以通过USING将参数值插入到动态命令中。 + 这个示例类似前面的形式,只不过源查询被指定为一个字符串表达式,在每次进入FOR循环时都会计算它并且重新计划。这允许程序员在一个预先计划好了的命令的速度和一个动态命令的灵活性之间进行选择,就像一个纯EXECUTE语句那样。与EXECUTE一样,可以通过USING将参数值插入到动态命令中。 @@ -1685,7 +1717,7 @@ END; $$ LANGUAGE plpgsql; - 元素会按存储顺序访问,而不管数组有多少维。尽管target通常只是单个变量,但在遍历组合值(记录)数组时,它也可以是一个变量列表。在这种情况下,每个数组元素都会按组合值的连续列给这些变量赋值。 + 元素会按存储顺序访问,而不管数组有多少维。尽管target通常只是单个变量,但在遍历复合值(记录)数组时,它也可以是一个变量列表。在这种情况下,每个数组元素都会按复合值的连续列给这些变量赋值。 @@ -1717,8 +1749,8 @@ NOTICE: row = {10,11,12} 捕获错误 - exceptions - in PL/pgSQL + 异常 + 在 PL/pgSQL 中 @@ -1777,7 +1809,7 @@ END; - 进入和退出一个包含EXCEPTION子句的块要比不包含该子句的块开销大的多。因此,只在必要的时候使用EXCEPTION。 + 进入和退出一个包含EXCEPTION子句的块要比不包含该子句的块开销大得多。因此,只在必要的时候使用EXCEPTION @@ -1804,9 +1836,9 @@ BEGIN IF found THEN RETURN; END IF; - -- 不在这里,那么尝试插入该键 + -- 该键不存在,因此尝试插入 -- 如果其他某人并发地插入同一个键, - -- 我们可能得到一个唯一键失败 + -- 就可能发生违反唯一约束的错误 BEGIN INSERT INTO db(a,b) VALUES (key, data); RETURN; @@ -1844,7 +1876,7 @@ SELECT merge_db(1, 'dennis'); GET STACKED DIAGNOSTICS variable { = | := } item , ... ; - 每个item是一个关键词,它标识一个被赋予给指定变量(应该具有接收该值的正确数据类型)的状态值。中显示了当前可用的状态项。 + 每个item是一个关键词,它标识一个被赋予给指定variable(应该具有接收该值的正确数据类型)的状态值。中显示了当前可用的状态项。 @@ -1952,7 +1984,7 @@ END; 获得执行位置信息 - GET DIAGNOSTICS(之前在中描述)命令检索有关当前执行状态的信息(反之上文讨论的GET STACKED DIAGNOSTICS命令会把有关执行状态的信息报告成一个以前的错误)。它的PG_CONTEXT状态项可用于标识当前执行位置。状态项PG_CONTEXT将返回一个文本字符串,其中有描述该调用栈的多行文本。第一行会指向当前函数以及当前正在执行GET DIAGNOSTICS的命令。第二行及其后的行表示调用栈中更上层的调用函数。例如: + GET DIAGNOSTICS(之前在中描述)命令检索有关当前执行状态的信息(反之上文讨论的GET STACKED DIAGNOSTICS命令报告先前发生错误时的执行状态信息)。它的PG_CONTEXT状态项可用于标识当前执行位置。状态项PG_CONTEXT将返回一个文本字符串,其中包含一行或多行描述该调用栈的文本。第一行会指向当前函数以及当前正在执行的GET DIAGNOSTICS命令。第二行及其后的行表示调用栈中更上层的调用函数。例如: CREATE OR REPLACE FUNCTION outer_func() RETURNS integer AS $$ @@ -1995,7 +2027,7 @@ CONTEXT: PL/pgSQL function outer_func() line 3 at RETURN 游标 - cursor + 游标 在 PL/pgSQL 中 @@ -2099,7 +2131,9 @@ OPEN bound_cursorvar ( 位置或命名记号可以传递参数值。在位置记号中,所有参数都必须按照顺序指定。在命名记号中,每一个参数的名字使用:=与参数表达式分隔。类似于中描述的调用函数,也允许混合位置和命名记号。 - 例如(使用前面的游标声明示例): + + 示例(这些示例使用上面示例中的游标声明): + OPEN curs2; OPEN curs3(42); OPEN curs3(key := 42); @@ -2325,12 +2359,17 @@ COMMIT; 遍历游标结果 - 有一种FOR语句的变体可以遍历游标返回的行。其语法为: + + 有一种FOR语句的变体,它允许通过游标返回的行进行迭代。语法是: + + <<label>> FOR recordvar IN bound_cursorvar ( argument_name := argument_value , ... ) LOOP statements END LOOP label ; -游标变量必须在声明时绑定到某个查询,并且此时不能处于已打开状态。FOR语句会自动打开该游标,并在循环退出时将其关闭。当且仅当游标声明为接受参数时,才必须给出实际参数值表达式列表。这些值会被替换到查询中,其方式与执行以下命令时相同:OPEN(见)。 + + + 该游标变量必须在声明时已经被绑定到某个查询,并且它不能已经被打开。FOR语句会自动打开游标,并且在退出循环时自动关闭游标。当且仅当游标被声明要使用参数时,才必须出现一个实际参数值表达式的列表。这些值会被替换到查询中,采用OPEN期间的方式(见)。 @@ -2368,19 +2407,21 @@ RAISE ; level(如果有)之后,可以指定一个format字符串(必须是简单的字符串字面量,不能是表达式)。格式字符串指定要报告的错误消息文本。格式字符串之后可以跟上可选的参数表达式,其值将被插入消息中。在格式字符串内,%会被替换为下一个可选参数值的字符串表示。写成%%可以输出一个字面的%。参数个数必须与格式字符串中%占位符的个数匹配,否则会在函数编译期间报错。 - 在这个例子中,v_job_id的值会替换字符串中的% + + 在这个示例中,v_job_id的值将替换字符串中的%: + RAISE NOTICE 'Calling cs_create_job(%)', v_job_id; - 可以为错误报告附加额外信息,方法是写出USING,后面跟上可以为错误报告附加额外信息,方法是写出USING,后面跟上option = expression项目。每个expression都可以是任意字符串值表达式。允许的option关键字为: MESSAGE - 设置错误消息文本。如果RAISE采用了在USING之前包含格式字符串的形式,则不能使用此选项。 + 设置错误消息文本。该选项不能用于在USING之前包含格式字符串的RAISE形式。 @@ -2394,14 +2435,14 @@ RAISE NOTICE 'Calling cs_create_job(%)', v_job_id; HINT - 提供提示消息。 + 提供一个提示消息。 ERRCODE - 指定要报告的错误码(SQLSTATE),可以使用中所示的条件名,也可以直接使用五个字符的 SQLSTATE 代码。 + 指定要报告的错误代码(SQLSTATE),可以用中所示的条件名,或者直接作为一个五字符 SQLSTATE 代码。 @@ -2412,7 +2453,7 @@ RAISE NOTICE 'Calling cs_create_job(%)', v_job_id; TABLE SCHEMA - 提供相关对象的名称。 + 提供一个相关对象的名称。 @@ -2424,23 +2465,33 @@ RAISE EXCEPTION 'Nonexistent ID --> %', user_id - 这两个例子展示了设置 SQLSTATE 的等价方式: + + 这两个示例展示了设置 SQLSTATE 的两种等价的方法: + RAISE 'Duplicate user ID: %', user_id USING ERRCODE = 'unique_violation'; RAISE 'Duplicate user ID: %', user_id USING ERRCODE = '23505'; - 还有第二种RAISE语法,其主要参数是要报告的条件名或 SQLSTATE,例如: + + 还有第二种RAISE语法,其中主参数是要报告的条件名或 SQLSTATE,例如: + RAISE division_by_zero; RAISE SQLSTATE '22012'; -在这种语法中,USING可以用来提供自定义的错误消息、详细信息或提示。前面例子的另一种写法是 + + 在这种语法中,USING可以用来提供自定义的错误消息、细节或提示。另一种达到前面示例同样效果的方式是: + RAISE unique_violation USING MESSAGE = 'Duplicate user ID: ' || user_id; - 还有一种变体是写成RAISE USINGRAISE level USING,并把其余所有内容放入USING列表。 + + 还有另一种变体是写RAISE USINGRAISE level USING,并把其余内容都放在USING列表里。 + - 最后一种RAISE变体完全不带参数。这种形式只能用于BEGIN块的EXCEPTION子句内部;它会重新抛出当前正在处理的错误。 + + RAISE的最后一种变体根本没有参数。这种形式只能被用在一个BEGIN块的EXCEPTION子句中,它导致当前正在被处理的错误被重新抛出。 + @@ -2458,7 +2509,7 @@ RAISE unique_violation USING MESSAGE = 'Duplicate user ID: ' || user_id; - 当用 SQLSTATE 代码指定错误代码时,你并不受限于预定义错误代码,而是可以选择任何由五位数字和/或大写 ASCII 字母构成的错误代码,唯一不能使用的是 00000。我们建议尽量避免抛出以三个零结尾的错误代码,因为这些是类别代码,只能用于捕获整个类别。 + 当用 SQLSTATE 代码指定错误代码时,你并不受限于预定义错误代码,而是可以选择任何由五位数字和/或大写 ASCII 字母构成的错误代码,唯一不能使用的是 00000。我们建议尽量避免抛出以三个零结尾的错误代码,因为这些是类别代码,只能通过捕获整个类别来捕获这类错误。 @@ -2470,12 +2521,12 @@ RAISE unique_violation USING MESSAGE = 'Duplicate user ID: ' || user_id; ASSERT - in PL/pgSQL + 在 PL/pgSQL 中 - assertions - in PL/pgSQL + 断言 + 在 PL/pgSQL 中 @@ -2492,15 +2543,14 @@ ASSERT condition , condition是一个布尔 表达式,它被期望总是计算为真。如果确实如此, - ASSERT语句不会再做什么。但如果结果是假 - 或者空,那么将发生一个ASSERT_FAILURE异常(如果在计算 + ASSERT语句不会再做什么。但如果结果是假或者空值,那么将发生一个ASSERT_FAILURE异常(如果在计算 condition时发生错误, 它会被报告为一个普通错误)。 如果提供了可选的message, - 它是一个结果(如果非空)被用来替换默认错误消息文本 + 它是一个结果(如果不为 NULL)被用来替换默认错误消息文本 assertion failed的表达式(如果 condition失败)。 message表达式在 @@ -2652,11 +2702,11 @@ ASSERT condition , - INSTEAD OF触发器(总是行级触发器,并且可能只被用于视图)能够返回空来表示它们没有执行任何更新,并且对该行剩余的操作可以被跳过(即后续的触发器不会被引发,并且该行不会被计入外围INSERT/UPDATE/DELETE的行影响状态中)。否则一个非空值应该被返回用以表示该触发器执行了所请求的操作。对于INSERTUPDATE操作,返回值应该是NEW,触发器函数可能对它进行了修改来支持INSERT RETURNINGUPDATE RETURNING(这也将影响被传递给任何后续触发器的行值,或者被传递给带有ON CONFLICT DO UPDATEINSERT语句中一个特殊的EXCLUDED别名引用)。对于DELETE操作,返回值应该是OLD。 + INSTEAD OF触发器(总是行级触发器,并且只能用于视图)能够返回 null 来表示它们没有执行任何更新,并且对该行剩余的操作应被跳过(即后续的触发器不会被引发,并且该行不会被计入外围INSERT/UPDATE/DELETE的行影响状态中)。否则应该返回一个非 null 值用以表示该触发器执行了所请求的操作。对于INSERTUPDATE操作,返回值应该是NEW,触发器函数可能对它进行了修改来支持INSERT RETURNINGUPDATE RETURNING(这也将影响被传递给任何后续触发器的行值,或者被传递给带有ON CONFLICT DO UPDATEINSERT语句中一个特殊的EXCLUDED别名引用)。对于DELETE操作,返回值应该是OLD - 一个AFTER行级触发器或一个BEFOREAFTER语句级触发器的返回值总是会被忽略,它可能也是空。不过,任何这些类型的触发器可能仍会通过抛出一个错误来中止整个操作。 + 一个AFTER行级触发器或一个BEFOREAFTER语句级触发器的返回值总是会被忽略,因此也可以返回 null。不过,任何这些类型的触发器可能仍会通过抛出一个错误来中止整个操作。 @@ -2828,10 +2878,10 @@ INSTEAD OF INSERT OR UPDATE OR DELETE ON emp_view - 一个 <application>PL/pgSQL</application> 用于维护汇总表的触发器函数 + 一个用于维护汇总表的 <application>PL/pgSQL</application> 触发器函数 - 这里详述的模式有一部分是基于 Ralph Kimball 所作的数据仓工具包中的Grocery Store示例。 + 这里详述的模式有一部分是基于 Ralph Kimball 所作的数据仓库工具包中的Grocery Store示例。 @@ -2975,7 +3025,7 @@ SELECT * FROM sales_summary_bytime; 使用过渡表审计 - 这个示例产生和相同的结果,但并未使用一个为每一行都触发的触发器,而是在把相关信息收集到一个过渡表中之后用了一个只为每个语句引发一次的触发器。当调用语句修改了很多行时,这种方法明显比行触发器方法快。注意我们必须为每一种事件建立一个单独的触发器声明,因为每种情况的REFERENCING子句必须不同。但是这并不能阻止我们使用单一的触发器函数(实际上,使用三个单独的函数会更好,因为可以避免在TG_OP上的运行时测试)。 + 这个示例产生和相同的结果,但并未使用一个为每一行都触发的触发器,而是在把相关信息收集到一个过渡表中之后用了一个只为每个语句引发一次的触发器。当调用语句修改了很多行时,这种方法可能显著快于行触发器方法。注意我们必须为每一种事件建立一个单独的触发器声明,因为每种情况的REFERENCING子句必须不同。但是这并不能阻止我们使用单一的触发器函数(实际上,使用三个单独的函数可能会更好,因为可以避免在TG_OP上的运行时测试)。 @@ -3085,9 +3135,7 @@ CREATE EVENT TRIGGER snitch ON ddl_command_start EXECUTE PROCEDURE snitch(); <application>PL/pgSQL</application> 内部机制 - - 这一节讨论了一些PL/pgSQL用户应该知道的一些重要的实现细节。 - + 本节讨论一些实现细节,了解这些细节对 PL/pgSQL 用户通常很重要。 变量替换 @@ -3158,7 +3206,7 @@ CREATE FUNCTION stamp_user(id int, comment text) RETURNS void AS $$ END; $$ LANGUAGE plpgsql; - 在UPDATE命令中,curtimecomment以及id将引用该函数的变量和参数,不管users有没有这些名称的列。注意,我们不得不在WHERE子句中对users.id的引用加以限定,以便让它引用表列。但是我们不需要在UPDATE列表中把对comment的引用限定为一个目标,因为语法上那必须是users的一列。我们可以用下面的方式写一个相同的不依赖于variable_conflict设置的函数: + 在UPDATE命令中,curtimecomment以及id将引用该函数的变量和参数,不管users有没有这些名称的列。注意,我们不得不在WHERE子句中对users.id的引用加以限定,以便让它引用表列。但是我们不需要对UPDATE列表中作为目标的comment引用加以限定,因为语法上那必须是users的一列。我们可以用下面的方式写一个相同的不依赖于variable_conflict设置的函数: CREATE FUNCTION stamp_user(id int, comment text) RETURNS void AS $$ <<fn>> @@ -3197,7 +3245,7 @@ $$ LANGUAGE plpgsql; - PL/pgSQL(更准确地说,是 SPI 管理器)还会尝试缓存与某个预备语句相关的执行计划。如果没有使用缓存计划,那么每次执行该语句时都会生成新的执行计划,而当前参数值(也就是 PL/pgSQL 变量值)可用于优化所选计划。如果该语句没有参数,或者会被执行很多次,SPI 管理器就会考虑创建一个不依赖具体参数值的通用计划,并将其缓存起来供重复使用。通常只有在执行计划对其中引用的 PL/pgSQL 变量值不太敏感时,才会这样做。如果执行计划对参数值非常敏感,那么每次重新生成计划总体上反而更划算。关于预备语句的行为,详见 。 + PL/pgSQL(更准确地说,是 SPI 管理器)还可以尝试缓存与某个预备语句相关的执行计划。如果没有使用缓存计划,那么每次执行该语句时都会生成新的执行计划,而当前参数值(也就是 PL/pgSQL 变量值)可用于优化所选计划。如果该语句没有参数,或者会被执行很多次,SPI 管理器就会考虑创建一个不依赖具体参数值的通用计划,并将其缓存起来供重复使用。通常只有在执行计划对其中引用的 PL/pgSQL 变量值不太敏感时,才会这样做。如果执行计划对参数值非常敏感,那么每次重新生成计划总体上反而更划算。关于预备语句的行为,详见 @@ -3246,7 +3294,7 @@ $$ LANGUAGE plpgsql; - 在logfunc2中,PostgreSQL的主解析器不知道应该把'now'解释成什么类型,因此返回一个text类型的数据值,其中包含字符串now。在确定对本地变量curtime的赋值时,PL/pgSQL解释器通过调用用于该转换的textouttimestamp_in函数,把这个字符串转换为timestamp类型。因此,计算得到的时间戳会按程序员预期在每次执行时更新。虽然这恰好能得到预期结果,但效率并不高,因此使用now()函数仍然是更好的主意。 + 在logfunc2中,PostgreSQL的主解析器不知道应该把'now'解释成什么类型,因此返回一个text类型的数据值,其中包含字符串now。在随后给局部变量curtime赋值时,PL/pgSQL解释器通过调用用于该转换的textouttimestamp_in函数,把这个字符串转换为timestamp类型。因此,计算得到的时间戳会按程序员预期在每次执行时更新。虽然这恰好能得到预期结果,但效率并不高,因此使用now()函数仍然是更好的主意。 @@ -3274,14 +3322,14 @@ $$ LANGUAGE plpgsql; - 另一种开发PL/pgSQL的好方法,是使用有助于过程语言开发的 GUI 数据库访问工具。这类工具的一个例子是pgAdmin,当然也有其他工具。它们通常提供一些方便的特性,例如转义单引号,以及让重新创建和调试函数变得更容易。 + 另一种使用PL/pgSQL进行开发的好方法,是使用有助于过程语言开发的 GUI 数据库访问工具。这类工具的一个例子是pgAdmin,当然也有其他工具。它们通常提供一些方便的特性,例如转义单引号,以及让重新创建和调试函数变得更容易。 引号的处理 - 一个PL/pgSQL函数的代码在一个CREATE FUNCTION中被指定为一个字符串。如果你用通常的方式把该字符串写在单引号中间,那么该函数体中的任何单引号都必须被双写;同样任何反斜线也必须被双写(假定使用了转义字符串语法)。双写引号最多有点冗长,并且在更复杂的情况中代码会变得完全无法理解,因为你很容易发现你需要半打或者更多相邻的引号。我们推荐你转而把函数体写成一个美元引用的字符串(见)。在美元引用方法中,你从不需要双写任何引号。但是要注意为你需要的每一层嵌套选择一个不同的美元引用定界符。例如,你可能把CREATE FUNCTION命令写成: + 一个PL/pgSQL函数的代码在一个CREATE FUNCTION中被指定为一个字符串字面量。如果你用通常的方式把该字符串写在单引号中间,那么该函数体中的任何单引号都必须被双写;同样任何反斜线也必须被双写(假定使用了转义字符串语法)。双写引号本身就很繁琐,并且在更复杂的情况中代码会变得完全无法理解,因为你很容易发现你需要半打或者更多相邻的引号。我们推荐你转而把函数体写成一个美元引用的字符串(见)。在美元引用方法中,你从不需要双写任何引号。但是要注意为你需要的每一层嵌套选择一个不同的美元引用定界符。例如,你可能把CREATE FUNCTION命令写成: CREATE OR REPLACE FUNCTION testfunc(integer) RETURNS integer AS $PROC$ .... @@ -3316,7 +3364,7 @@ CREATE FUNCTION foo() RETURNS integer AS ' - 用于函数体内的字符串,例如: + 用于函数体内的字符串字面量,例如: a_output := ''Blah''; SELECT * FROM users WHERE f_name=''foobar''; @@ -3326,7 +3374,7 @@ SELECT * FROM users WHERE f_name=''foobar''; a_output := 'Blah'; SELECT * FROM users WHERE f_name='foobar'; - 这恰好就是PL/pgSQL在两种情况中会看到的。 + 这恰好就是PL/pgSQL解析器在两种情况中会看到的。 @@ -3348,7 +3396,7 @@ a_output := a_output || '' AND name LIKE ''''foobar'''' AND xyz'' a_output := a_output || $$ AND name LIKE 'foobar' AND xyz$$ - 要小心在这周围的任何美元引用定界符不只是$$。 + 要小心在这周围的任何美元引用定界符都不能是$$ @@ -3379,7 +3427,7 @@ a_output := a_output || $$ AND name LIKE 'foobar'$$ - 当你想在一个字符串常量(占 8 个引号)中有两个单引号时并且这会挨着该字符串常量的末尾(另外 2 个)。如果你正在写一个产生其他函数的函数(如中),你将很可能只需要这种。例如: + 当字符串常量中需要两个单引号(这需要 8 个引号),而且它们紧邻该字符串常量的末尾(还需 2 个引号)时。通常只有在编写生成其他函数的函数时(如所示),才会需要这种写法。例如: a_output := a_output || '' if v_'' || referrer_keys.kind || '' like '''''''''' @@ -3476,7 +3524,7 @@ CREATE FUNCTION - 在PostgreSQL中,函数体必须写成字符串文本。因此你需要使用美元符引用或者转义函数体中的单引号(见)。 + 在PostgreSQL中,函数体必须写成字符串字面量。因此你需要使用美元符引用或者转义函数体中的单引号(见)。 @@ -3565,13 +3613,13 @@ show errors; - 在PostgreSQL中,函数体被认为是一个字符串,所以你需要使用引号或者美元符号包围它。这代替了Oracle 方法中的用于终止的/。 + 在PostgreSQL中,函数体被认为是一个字符串字面量,所以你需要使用引号或者美元引用定界符包围它。这代替了Oracle 方法中的用于终止的/ - 在PostgreSQL中没有show errors命令, 并且也不需要这个命令,因为错误是自动报告的。 + 在PostgreSQL中没有show errors命令, 并且也不需要这个命令,因为错误是自动报告的。 @@ -3602,9 +3650,7 @@ $$ LANGUAGE plpgsql; 从<application>PL/SQL</application>移植一个创建另一个函数的函数到<application>PL/pgSQL</application> - - 下面的过程从一个SELECT语句抓取行,并且为了效率而构建一个带有IF语句中结果的大型函数。 - + 下面的过程从 SELECT 语句读取行,并将结果写入 IF 语句,从而构造一个大型函数,以提高效率。 这是 Oracle 版本: @@ -3682,12 +3728,14 @@ $func$ LANGUAGE plpgsql; 下面的Oracle PL/SQL 过程被用来解析一个 URL 并且返回一些元素(主机、路径和查询)。 - 这是 Oracle 版本: + + 这是 Oracle 版本: + CREATE OR REPLACE PROCEDURE cs_parse_url( v_url IN VARCHAR2, - v_host OUT VARCHAR2, -- This will be passed back - v_path OUT VARCHAR2, -- This one too - v_query OUT VARCHAR2) -- And this one + v_host OUT VARCHAR2, -- 这个值将被返回 + v_path OUT VARCHAR2, -- 这个也是 + v_query OUT VARCHAR2) -- 还有这个 IS a_pos1 INTEGER; a_pos2 INTEGER; @@ -3723,13 +3771,14 @@ show errors; - 下面是一种可行的移植写法,目标语言为PL/pgSQL: + + 这里给出一种可能的 PL/pgSQL 写法: CREATE OR REPLACE FUNCTION cs_parse_url( v_url IN VARCHAR, - v_host OUT VARCHAR, -- This will be passed back - v_path OUT VARCHAR, -- This one too - v_query OUT VARCHAR) -- And this one + v_host OUT VARCHAR, -- 这个值将被返回 + v_path OUT VARCHAR, -- 这个也是 + v_query OUT VARCHAR) -- 还有这个 AS $$ DECLARE a_pos1 INTEGER; @@ -3762,14 +3811,17 @@ BEGIN v_query := substr(v_url, a_pos1 + 1); END; $$ LANGUAGE plpgsql; -该函数可以这样使用: + + + 这个函数可以这样使用: + SELECT * FROM cs_parse_url('http://foobar.com/query.cgi?baz'); - 展示了如何移植一个使用了多种 Oracle 特性的过程。 + 展示了如何移植一个使用了多种 Oracle 专属特性的过程。 @@ -3878,7 +3930,7 @@ EXCEPTION END; - 如果你正在移植一个以这种方式使用SAVEPOINTROLLBACK TO的 Oracle 过程,工作会比较简单:只要忽略SAVEPOINTROLLBACK TO即可。如果你的 Oracle 过程以不同方式使用SAVEPOINTROLLBACK TO,那就需要认真思考了。 + 如果你正在移植一个以这种方式使用SAVEPOINTROLLBACK TO的 Oracle 过程,工作会比较简单:只要省略SAVEPOINTROLLBACK TO即可。如果你的 Oracle 过程以不同方式使用SAVEPOINTROLLBACK TO,那就需要认真思考了。 @@ -3895,11 +3947,11 @@ END; 优化 <application>PL/pgSQL</application> 函数 - PostgreSQL提供了两种函数创建修饰符来优化执行:volatility(对于给定的相同参数,函数是否总是返回相同的结果)以及strictness (如果任何参数为空,函数是否返回空)。详见参考页。 + PostgreSQL提供了两种函数创建修饰符来优化执行:volatility(对于给定的相同参数,函数是否总是返回相同的结果)以及strictness (如果任何参数为空值,函数是否返回空值)。详见参考页。 - 在利用这些优化属性时,你的CREATE FUNCTION语句应该看起来像这样: + 在利用这些优化属性时,你的CREATE FUNCTION语句可能像这样: CREATE FUNCTION foo(...) RETURNS integer AS $$ diff --git a/zh/10/plpython.sgml b/zh/10/plpython.sgml index 06b8332f..42bba4cb 100644 --- a/zh/10/plpython.sgml +++ b/zh/10/plpython.sgml @@ -108,7 +108,7 @@ CREATE FUNCTION funcname (argument-list) RETURNS return-type AS $$ - # PL/Python function body + # PL/Python 函数体 $$ LANGUAGE plpythonu; @@ -146,7 +146,7 @@ def __plpython_procedure_pymax_23456(): CREATE FUNCTION pystrip(x text) RETURNS text AS $$ - x = x.strip() # error + x = x.strip() # 错误 return x $$ LANGUAGE plpythonu; @@ -156,7 +156,7 @@ CREATE FUNCTION pystrip(x text) RETURNS text AS $$ global x - x = x.strip() # ok now + x = x.strip() # 现在可以正常工作 return x $$ LANGUAGE plpythonu; @@ -172,7 +172,10 @@ $$ LANGUAGE plpythonu; 数据类型映射 - 调用 PL/Python 函数时,参数会从 PostgreSQL 数据类型转换为相应的 Python 类型: + + 调用 PL/Python 函数时,其参数会从 PostgreSQL 数据类型转换为相应的 Python 类型: + + PostgreSQL boolean 会转换为 Python bool。 @@ -209,8 +212,9 @@ $$ LANGUAGE plpythonu; - 所有其他数据类型,包括 PostgreSQL 字符串类型, - 都会转换为 Python str(和所有 Python 字符串一样,都是 Unicode)。 + 所有其他数据类型,包括 PostgreSQL 字符串类型,都会转换为 Python + str。在 Python 2 中,该字符串采用 PostgreSQL 服务器编码; + 在 Python 3 中,它与所有字符串一样,都是 Unicode 字符串。 @@ -222,7 +226,10 @@ $$ LANGUAGE plpythonu; - PL/Python 函数返回时,返回值按以下规则转换为该函数声明的 PostgreSQL 返回数据类型: + + 当 PL/Python 函数返回时,其返回值会按如下方式转换成该函数声明的 PostgreSQL 返回数据类型: + + 当 PostgreSQL 返回类型为boolean时,返回值会按照Python规则进行真值判定。也就是说,0 和空字符串为假,但值得注意的是,'f' 为真。 @@ -239,7 +246,10 @@ $$ LANGUAGE plpythonu; - 字符串在传给 PostgreSQL 时,会自动转换为 PostgreSQL 服务器编码。 + Python 2 中的字符串传给 PostgreSQL 时,必须采用 PostgreSQL 服务器编码。 + 在当前服务器编码中无效的字符串会引发错误,但并非所有编码不匹配都能被检测到, + 因此处理不当仍可能产生乱码数据。Unicode 字符串会自动转换为正确的编码, + 因而使用它们可能更安全、更方便。在 Python 3 中,所有字符串都是 Unicode 字符串。 @@ -248,7 +258,10 @@ $$ LANGUAGE plpythonu; 对于非标量数据类型,请参见下文。 - 注意,如果声明的 PostgreSQL 返回类型与实际返回对象的 Python 数据类型在逻辑上不匹配,系统不会提示;无论如何都会转换该值。 + + + 请注意,即使声明的 PostgreSQL 返回类型与实际返回对象的 Python 数据类型在逻辑上并不匹配,也不会报错;无论如何该值都会被转换。 + @@ -350,12 +363,19 @@ $$ LANGUAGE plpythonu; - 从 Python 函数返回行类型或复合类型,有多种方式。以下示例假定已定义: + + 有多种方法可以从 Python 函数返回行类型或复合类型。以下示例假定我们有: + + CREATE TYPE named_value AS ( name text, value integer ); -复合结果可以用以下形式返回: + + + 复合结果可以按以下形式返回: + + 序列类型(元组或列表,但不能是集合,因为集合不可通过索引访问) @@ -364,7 +384,7 @@ CREATE FUNCTION make_pair (name text, value integer) RETURNS named_value AS $$ return ( name, value ) - # or alternatively, as list: return [ name, value ] + # 也可以使用列表: return [ name, value ] $$ LANGUAGE plpythonu; 要为某一列返回 SQL 空值,请将 None 放在对应位置。 @@ -402,7 +422,7 @@ AS $$ self.value = v return named_value(name, value) - # or simply + # 或者简写为 class nv: pass nv.name = name nv.value = value @@ -428,13 +448,20 @@ SELECT * FROM multiout_simple(); - 返回集合的函数 - 一个 PL/Python 函数也可以返回标量类型或复合类型的集合。实现方式有多种,因为返回对象在内部会被转换为迭代器。以下示例假定已定义复合类型: + 集合返回函数 + + PL/Python函数也可以返回标量类型或复合类型的集合。实现方式有多种,因为返回的对象在内部会被转换成一个迭代器。以下示例假定我们有如下复合类型: + + CREATE TYPE greeting AS ( how text, who text ); -集合结果可以通过以下形式返回: + + + 集合结果可以通过以下对象返回: + + 序列类型(元组、列表、集合) @@ -443,8 +470,8 @@ CREATE TYPE greeting AS ( CREATE FUNCTION greet (how text) RETURNS SETOF greeting AS $$ - # return tuple containing lists as composite types - # all other combinations work also + # 返回包含列表的元组,以列表表示复合类型 + # 其他组合方式也都可用 return ( [ how, "World" ], [ how, "PostgreSQL" ], [ how, "PL/Python" ] ) $$ LANGUAGE plpythonu; @@ -502,7 +529,7 @@ $$ LANGUAGE plpythonu; - 也支持带OUT参数的返回集函数(使用RETURNS SETOF record)。例如: + 也支持带OUT参数的集合返回函数(使用RETURNS SETOF record)。例如: CREATE FUNCTION multiout_simple_setof(n integer, OUT integer, OUT integer) RETURNS SETOF record AS $$ return [(1, 2)] * n @@ -537,7 +564,7 @@ SELECT * FROM multiout_simple_setof(3); DO $$ - # PL/Python code + # PL/Python 代码 $$ LANGUAGE plpythonu; @@ -779,7 +806,7 @@ CREATE FUNCTION usesavedplan() RETURNS trigger AS $$ else: plan = plpy.prepare("SELECT 1") SD["plan"] = plan - # rest of function + # 函数的其余部分 $$ LANGUAGE plpythonu; @@ -797,7 +824,7 @@ $$ LANGUAGE plpythonu; 游标对象提供 fetch 方法,接受一个整数参数并返回结果对象。每次调用 fetch,返回对象都包含下一批行,行数不会超过参数值。所有行都取完后,fetch 开始返回空的结果对象。游标对象还提供迭代器接口,每次产生一行,直到所有行取完。通过这种方式取得的数据不是结果对象,而是字典,每个字典对应一行结果。 - 下面示例展示了如何处理大表中的数据: + 下面示例展示了处理大表中数据的两种方式: CREATE FUNCTION count_odd_iterator() RETURNS integer AS $$ odd = 0 @@ -823,7 +850,7 @@ $$ LANGUAGE plpythonu; CREATE FUNCTION count_odd_prepared() RETURNS integer AS $$ odd = 0 plan = plpy.prepare("select num from largetable where num % $1 <> 0", ["integer"]) -rows = list(plpy.cursor(plan, [2])) # or: = list(plan.cursor([2])) +rows = list(plpy.cursor(plan, [2])) # 或者:= list(plan.cursor([2])) return len(rows) $$ LANGUAGE plpythonu; @@ -924,9 +951,9 @@ $$ LANGUAGE plpythonu; - 旧式 Python 2 用法 + 较早的 Python 版本 - 使用 with 关键字的上下文管理器语法,从 Python 2.6 起默认可用。如果 PL/Python 使用更早的 Python 版本,仍然可以使用显式子事务,只是没那么方便。可以调用子事务管理器的 __enter____exit__ 函数,也可以使用它们的便捷别名 enterexit。转账示例函数可以写成: + 使用 with 关键字的上下文管理器语法,从 Python 2.6 起默认可用。如果 PL/Python 使用更早的 Python 版本,仍然可以使用显式子事务,只是没那么方便。可以通过便捷别名 enterexit,调用子事务管理器的 __enter____exit__ 函数。转账示例函数可以写成: CREATE FUNCTION transfer_funds_old() RETURNS void AS $$ try: subxact = plpy.subtransaction() @@ -959,7 +986,7 @@ $$ LANGUAGE plpythonu; - 实用函数 + 辅助函数 plpy模块还提供以下函数: @@ -1013,7 +1040,7 @@ PL/Python function "raise_custom_exception" - 另一组实用函数是plpy.quote_literal(string)plpy.quote_nullable(string)以及plpy.quote_ident(string)。它们等价于中描述的内置引用函数。在构造临时查询时,这些函数很有用。中动态 SQL 的一个 PL/Python 等价写法如下: + 另一组辅助函数是plpy.quote_literal(string)plpy.quote_nullable(string)以及plpy.quote_ident(string)。它们等价于中描述的内置加引号函数。在构造临时查询时,这些函数很有用。中动态 SQL 的一个 PL/Python 等价写法如下: plpy.execute("UPDATE tbl SET %s = %s WHERE key = %s" % ( plpy.quote_ident(colname), diff --git a/zh/10/pltcl.sgml b/zh/10/pltcl.sgml index 4d7f5470..ade74ed9 100644 --- a/zh/10/pltcl.sgml +++ b/zh/10/pltcl.sgml @@ -50,7 +50,7 @@ CREATE FUNCTION funcname (argument-types) RETURNS return-type AS $$ - # PL/Tcl function body + # PL/Tcl 函数体 $$ LANGUAGE pltcl; @@ -69,11 +69,11 @@ CREATE FUNCTION tcl_max(integer, integer) RETURNS integer AS $$ $$ LANGUAGE pltcl STRICT; - 注意STRICT子句,它让我们不必考虑空输入值:如果传入的是空值,函数根本不会被调用,而是会自动返回空结果。 + 注意STRICT子句,它让我们不必考虑空值输入:如果传入的是空值,函数根本不会被调用,而是会自动返回空值结果。 - 在非严格函数中,如果某个参数的实际值为空,对应的$n变量会被设置为空串。要检测某个特定参数是否为空,可使用函数argisnull。例如,假设我们希望在tcl_max的两个参数中一个为空、一个非空时返回非空参数,而不是返回空值: + 在非严格函数中,如果某个参数的实际值为空值,对应的$n变量会被设置为空串。要检测某个特定参数是否为空值,可使用函数argisnull。例如,假设我们希望在tcl_max的两个参数中一个为空值、一个非空值时返回非空值参数,而不是返回空值: CREATE FUNCTION tcl_max(integer, integer) RETURNS integer AS $$ @@ -93,7 +93,7 @@ $$ LANGUAGE pltcl; - 复合类型参数会作为 Tcl 数组传递给函数。数组元素名就是该复合类型的属性名。如果传入行中的某个属性为 NULL,它就不会出现在数组中。下面是一个示例: + 复合类型参数会作为 Tcl 数组传递给函数。数组元素名就是该复合类型的属性名。如果传入行中的某个属性为空值,它就不会出现在数组中。下面是一个示例: CREATE TABLE employee ( @@ -167,7 +167,7 @@ $$ LANGUAGE pltcl; PL/Tcl 中的数据值 - 提供给 PL/Tcl 函数代码的参数值,只是将输入参数转换成文本形式(就像用SELECT语句将它们显示出来一样)。反过来,returnreturn_next命令会接受任何字符串,只要它是该函数声明结果类型或组合结果类型中指定列的可接受输入格式。 + 提供给 PL/Tcl 函数代码的参数值,只是将输入参数转换成文本形式(就像用SELECT语句将它们显示出来一样)。反过来,returnreturn_next命令会接受任何字符串,只要它是该函数声明结果类型或复合结果类型中指定列的可接受输入格式。 @@ -177,8 +177,8 @@ $$ LANGUAGE pltcl; PL/Tcl 中的全局数据 - global data - in PL/Tcl + 全局数据 + 在 PL/Tcl 中 @@ -205,13 +205,16 @@ $$ LANGUAGE pltcl; 从 PL/Tcl 访问数据库 - 本节遵循 Tcl 的惯例,在语法概要中用问号而不是方括号表示可选元素。在 PL/Tcl 函数体中可以使用以下命令访问数据库: + + 在本节中,我们遵循 Tcl 的通常约定,用问号而不是方括号来表示语法摘要中的可选元素。下列命令可用于从 PL/Tcl 函数体中访问数据库: + + spi_exec -count n -array name command loop-body - 执行以字符串形式给出的 SQL 命令。命令出错时会引发错误。否则,spi_exec的返回值是该命令处理的行数(选出、插入、更新或删除的行),如果命令是实用程序语句则返回零。此外,如果命令是SELECT语句,则所选列的值会按下文所述放入 Tcl 变量中。 + 执行以字符串形式给出的 SQL 命令。命令出错时会引发错误。否则,spi_exec的返回值是该命令处理的行数(选出、插入、更新或删除的行),如果命令是工具语句则返回零。此外,如果命令是SELECT语句,则所选列的值会按下文所述放入 Tcl 变量中。 可选的 -count 值告诉 spi_exec 此命令最多处理多少行,其效果类似于将查询设为游标后执行 FETCH n @@ -243,7 +246,7 @@ spi_exec -array C "SELECT * FROM pg_class" { 会为pg_class的每一行打印一条日志消息。这个特性与其他 Tcl 循环结构的工作方式类似;特别是continuebreak在循环体内按通常方式工作。 - 如果查询结果中的某一列为空,则对应的目标变量会被unset,而不是被设值。 + 如果查询结果中的某一列为空值,则对应的目标变量会被unset,而不是被设值。 @@ -255,7 +258,7 @@ spi_exec -array C "SELECT * FROM pg_class" { 准备并保存一个查询计划以供后续执行。保存的计划会在当前会话的整个生命周期内保留。 准备查询 - 在PL/Tcl中 + 在 PL/Tcl 中 @@ -285,7 +288,7 @@ spi_exec -array C "SELECT * FROM pg_class" { 可选的-nulls值是由空格和'n'字符组成的字符串,用来告诉spi_execp哪些参数是空值。 - 如果给出,它的长度必须与value-list完全相同。如果未给出,则所有参数值都视为非空。 + 如果给出,它的长度必须与value-list完全相同。如果未给出,则所有参数值都视为非空值。 @@ -299,7 +302,7 @@ spi_exec -array C "SELECT * FROM pg_class" { CREATE FUNCTION t1_count(integer, integer) RETURNS integer AS $$ if {![ info exists GD(plan) ]} { - # prepare the saved plan on the first call + # 在首次调用时准备并保存计划 set GD(plan) [ spi_prepare \ "SELECT count(*) AS cnt FROM t1 WHERE num >= \$1 AND num <= \$2" \ [ list int4 int4 ] ] @@ -341,7 +344,7 @@ $$ LANGUAGE pltcl; 将给定字符串中的所有单引号和反斜杠字符都加倍。 - 这可用于安全地引用那些要插入到传给spi_execspi_prepare的 SQL 命令中的字符串。 + 这可用于安全地为那些要插入到传给spi_execspi_prepare的 SQL 命令中的字符串加引号。 例如,考虑如下 SQL 命令字符串: @@ -367,7 +370,7 @@ SELECT 'doesn''t' AS ret "SELECT '[ quote $val ]' AS ret" - spi_execp的一个优点是,你不必像这样对参数值做引用,因为这些参数永远不会作为 SQL 命令字符串的一部分被解析。 + spi_execp的一个优点是,你不必像这样给参数值加引号,因为这些参数永远不会作为 SQL 命令字符串的一部分被解析。 @@ -377,7 +380,7 @@ SELECT 'doesn''t' AS ret elog level msg elog - 在PL/Tcl中 + 在 PL/Tcl 中 @@ -408,8 +411,8 @@ SELECT 'doesn''t' AS ret PL/Tcl 中的触发器函数 - trigger - in PL/Tcl + 触发器 + 在 PL/Tcl 中 可以用 PL/Tcl 编写触发器函数。PostgreSQL 要求作为触发器调用的函数必须声明为无参数、返回类型为 trigger 的函数。 @@ -485,7 +488,7 @@ SELECT 'doesn''t' AS ret $NEW - 对于INSERTUPDATE动作,这是一个包含新表行值的关联数组;对于DELETE则为空。该数组以列名为索引。值为 NULL 的列不会出现在数组中。对于语句级触发器,不会设置这个变量。 + 对于INSERTUPDATE动作,这是一个包含新表行值的关联数组;对于DELETE则为空。该数组以列名为索引。值为空值的列不会出现在数组中。对于语句级触发器,不会设置这个变量。 @@ -494,7 +497,7 @@ SELECT 'doesn''t' AS ret $OLD - 对于UPDATEDELETE动作,这是一个包含旧表行值的关联数组;对于INSERT则为空。该数组以列名为索引。值为 NULL 的列不会出现在数组中。对于语句级触发器,不会设置这个变量。 + 对于UPDATEDELETE动作,这是一个包含旧表行值的关联数组;对于INSERT则为空。该数组以列名为索引。值为空值的列不会出现在数组中。对于语句级触发器,不会设置这个变量。 @@ -546,8 +549,8 @@ CREATE TRIGGER trig_mytab_modcount BEFORE INSERT OR UPDATE ON mytab PL/Tcl 中的事件触发器函数 - event trigger - in PL/Tcl + 事件触发器 + 在 PL/Tcl 中 可以用 PL/Tcl 编写事件触发器函数。PostgreSQL 要求作为事件触发器调用的函数必须声明为无参数、返回类型为 event_trigger 的函数。 @@ -557,7 +560,7 @@ CREATE TRIGGER trig_mytab_modcount BEFORE INSERT OR UPDATE ON mytab $TG_event - 触发器因其而被触发的事件名称。 + 该触发器所针对的事件名称。 @@ -566,7 +569,7 @@ CREATE TRIGGER trig_mytab_modcount BEFORE INSERT OR UPDATE ON mytab $TG_tag - 触发器因其而被触发的命令标签。 + 该触发器所针对的命令标签。 @@ -589,8 +592,8 @@ CREATE EVENT TRIGGER tcl_a_snitch ON ddl_command_start EXECUTE PROCEDURE tclsnit PL/Tcl 中的错误处理 - exceptions - in PL/Tcl + 异常 + 在 PL/Tcl 中 @@ -618,9 +621,9 @@ if {[catch { spi_exec $sql_command }]} { if {[lindex $::errorCode 0] == "POSTGRES"} { array set errorArray $::errorCode if {$errorArray(condition) == "undefined_table"} { - # deal with missing table + # 处理表不存在的情况 } else { - # deal with some other type of SQL error + # 处理其他类型的 SQL 错误 } } } @@ -634,8 +637,8 @@ if {[catch { spi_exec $sql_command }]} { PL/Tcl 中的显式子事务 - subtransactions - in PL/Tcl + 子事务 + 在 PL/Tcl 中 @@ -700,7 +703,7 @@ $$ LANGUAGE pltcl; pltcl.start_proc (string) - pltcl.start_proc configuration parameter + pltcl.start_proc 配置参数 @@ -728,7 +731,7 @@ $$ LANGUAGE pltcl; pltclu.start_proc (string) - pltclu.start_proc configuration parameter + pltclu.start_proc 配置参数 @@ -747,7 +750,7 @@ $$ LANGUAGE pltcl; Tcl 过程名 - 在PostgreSQL中,只要参数个数或参数类型不同,就可以复用同一个函数名。不过,Tcl 要求所有过程名都必须不同。PL/Tcl 通过让内部 Tcl 过程名包含系统表pg_proc中该函数的对象 ID 来解决这个问题。因此,名称相同而参数类型不同的PostgreSQL函数,也会对应不同的 Tcl 过程。这通常不是 PL/Tcl 程序员需要关心的事情,但在调试时可能会看到。 + 在PostgreSQL中,只要参数个数或参数类型不同,就可以复用同一个函数名。不过,Tcl 要求所有过程名都必须不同。PL/Tcl 处理这一问题的方式是:在内部 Tcl 过程名中包含系统表 pg_proc 中的函数对象 ID 作为其名称的一部分。因此,名称相同但参数类型不同的PostgreSQL函数,也会对应不同的 Tcl 过程。这通常不是 PL/Tcl 程序员需要关心的事情,但在调试时可能会看见。 diff --git a/zh/10/postgres-fdw.sgml b/zh/10/postgres-fdw.sgml index 2d5025f1..5b4da8b1 100644 --- a/zh/10/postgres-fdw.sgml +++ b/zh/10/postgres-fdw.sgml @@ -239,7 +239,7 @@ 该选项是一个以逗号分隔的 PostgreSQL 扩展 名称列表,这些扩展必须在本地和远程服务器上都已安装且版本兼容。 - 属于列出扩展且为 immutable 的函数和操作符,将被视为可下推到远程服务器 + 属于列出扩展且不可变的函数和操作符,将被视为可下推到远程服务器 执行。该选项只能为外部服务器指定,不能按表指定。 @@ -410,8 +410,7 @@ - 请注意,postgres_fdw 当前不支持将远程事务预备为 - 两阶段提交。 + 请注意,postgres_fdw 当前不支持为两阶段提交预备远程事务。 diff --git a/zh/10/protocol.sgml b/zh/10/protocol.sgml index b6b88ba2..0ff3349c 100644 --- a/zh/10/protocol.sgml +++ b/zh/10/protocol.sgml @@ -691,7 +691,12 @@ 只要后端认为前端应当知晓的某个参数的当前有效值发生变化,就会生成 ParameterStatus 消息。最常见的情况是响应前端执行的SET命令,这种情况实际上是同步的;但也可能是管理员修改了配置文件,然后向服务器发送SIGHUP信号,从而导致参数状态发生变化。同样,如果某条SET命令被回滚,也会生成适当的 ParameterStatus 消息,用于报告当前生效的值。 - 目前,会为一组固定的参数生成 ParameterStatus,包括 server_versionserver_encodingclient_encodingapplication_nameis_superusersession_authorizationDateStyleIntervalStyleTimeZoneinteger_datetimesstandard_conforming_strings。(8.0 之前的版本不报告 server_encodingTimeZoneinteger_datetimes;8.1 之前的版本不报告 standard_conforming_strings;8.4 之前的版本不报告 IntervalStyle;9.0 之前的版本不报告 application_name。)注意,server_versionserver_encodinginteger_datetimes 是启动后不能改变的伪参数。这组参数将来可能变化,甚至可能变为可配置。因此,前端应直接忽略其不理解或不关心的参数的 ParameterStatus。 + + 目前,会为一组固定的参数生成 ParameterStatus,参数如下: + server_versionserver_encodingclient_encodingapplication_nameis_superusersession_authorizationDateStyleIntervalStyleTimeZoneinteger_datetimesstandard_conforming_strings。 + (8.0 之前的版本不报告 server_encodingTimeZoneinteger_datetimes;8.1 之前的版本不报告 standard_conforming_strings;8.4 之前的版本不报告 IntervalStyle;9.0 之前的版本不报告 application_name。) + 注意,server_versionserver_encodinginteger_datetimes 是启动后不能改变的伪参数。这组参数将来可能变化,甚至可能变为可配置。因此,前端应直接忽略其不理解或不关心的参数的 ParameterStatus。 + 如果前端发出一个LISTEN命令, 那么无论何时在为同一个通道名NOTIFY时,后端将发送一个NotificationResponse消息(不要和NoticeResponse搞混!)。 @@ -1016,8 +1021,8 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" TEMPORARY - 该命令导出的快照标识符。该快照在此连接上执行下一条命令之前,或复制连接关闭之前有效。如果所创建的是物理复制槽,则为 null。 - + 指定此复制槽为临时槽。临时槽不会保存到磁盘,并且在错误或会话结束时会自动删除。 + @@ -1038,11 +1043,14 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 作为对此命令的响应,服务器会发送仅含一行的结果集,其中包含以下字段: + + 在响应此命令时,服务器将发送一个包含以下字段的单行结果集: slot_name (text) - 新建复制槽的名称。 + + 新创建的复制槽的名称。 + @@ -1059,7 +1067,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" snapshot_name (text) - 该命令导出的快照标识符。该快照在此连接上执行下一条命令之前,或复制连接关闭之前有效。如果所创建的是物理复制槽,则为 null。 + 该命令导出的快照标识符。该快照在此连接上执行下一条命令之前,或复制连接关闭之前有效。如果所创建的是物理复制槽,则为空值。 @@ -1068,7 +1076,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" output_plugin (text) - 新建复制槽所使用的输出插件名称。如果所创建的是物理复制槽,则为 null。 + 新建复制槽所使用的输出插件名称。如果所创建的是物理复制槽,则为空值。 @@ -1377,14 +1385,19 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" BASE_BACKUP [ LABEL 'label' ] [ PROGRESS ] [ FAST ] [ WAL ] [ NOWAIT ] [ MAX_RATE rate ] [ TABLESPACE_MAP ] BASE_BACKUP - 指示服务器开始流式传输基础备份。系统会在备份开始前自动进入备份模式,在备份完成后退出该模式。接受以下选项: + + 指示服务器开始流式传输基础备份。 + 在备份开始之前,系统将自动进入备份模式,并在备份完成后退出备份模式。 + 接受以下选项: + + LABEL 'label' 设置备份的标签。如果未指定,则将使用base backup作为备份标签。 - 标签的引用规则与打开的标准SQL字符串相同。 + 标签的引号使用规则与打开的标准SQL字符串相同。 @@ -1393,8 +1406,12 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" PROGRESS - 请求生成进度报告所需的信息。这将在每个表空间的头部发回大致大小,可用于计算流式传输的完成进度。此大小通过在传输开始之前枚举所有文件大小来计算,因此可能对性能有负面影响。特别是在第一个数据被发出之前可能需要更长的时间。 - + 请求生成进度报告所需的信息。这将在每个表空间的首部发送一个近似大小, + 可用于计算流式传输的进度。这是通过在传输开始之前先枚举所有文件大小来计算的, + 可能会对性能产生负面影响。特别是,在流式传输数据之前可能需要更长的时间。 + 由于备份期间数据库文件可能会发生变化,因此大小仅为近似值, + 在估算与实际发送文件之间的这段时间里可能会增长或缩小。 + @@ -1411,9 +1428,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" WAL - - 如果设置为true,则在备份中包含必要的WAL段。这将包括在开始和停止备份之间的所有文件在基本目录tar文件的pg_wal目录中。默认值为false。 - + 在备份中包含必要的 WAL 段。这会把开始备份到停止备份之间的所有文件放入基础目录 tar 文件内的pg_wal目录中。 @@ -1441,23 +1456,27 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 如果为true,则在名为tablespace_map的文件中包含目录pg_tblspc中存在的符号链接的信息。 - 表空间映射文件包括目录pg_tblspc/中每个符号链接的名称及该符号链接的完整路径。默认值为false。 + 在名为tablespace_map的文件中包含目录pg_tblspc中存在的符号链接的信息。 + 表空间映射文件包括目录pg_tblspc/中每个符号链接的名称及该符号链接的完整路径。 - + 备份开始时,服务器首先发送两个普通结果集,然后发送一个或多个 CopyResponse 结果。 第一个普通结果集包含备份的起始位置,在一个包含两列的单行中。第一列包含以XLogRecPtr格式给出的起始位置,第二列包含相应的时间线ID。 - 第二个普通结果集为每个表空间包含一行。这一行的字段如下: + + 第二个普通结果集中的每个表空间都有一行。 + 这一行中的字段是: + + spcoid (oid) - 表空间的OID,如果是基本目录则为null。 + 表空间的OID,如果是基础目录则为null。 @@ -1465,7 +1484,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" spclocation (text) - 表空间目录的完整路径,如果是基本目录则为null。 + 表空间目录的完整路径,如果是基础目录则为null。 @@ -1476,10 +1495,13 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - + 在第二个普通结果集之后,会发送一个或多个 CopyResponse 结果,其中一个用于主数据目录,其他结果分别用于 pg_defaultpg_global 之外的各个附加表空间。CopyResponse 结果中的数据是表空间内容的 tar 格式转储(遵循 POSIX 1003.1-2008 标准中规定的 ustar interchange format),但省略了标准规定的末尾两个全零块。tar 数据传输完成后,会发送最后一个普通结果集,其中包含备份的 WAL 结束位置,格式与起始位置相同。 - 数据目录和每个表空间的 tar 归档都会包含目录中的所有文件,无论是PostgreSQL文件,还是添加到同一目录的其他文件。仅排除以下文件: + + 数据目录和每个表空间的tar归档将包含目录中的所有文件,无论它们是PostgreSQL文件还是添加到同一目录的其他文件。唯一排除的文件是: + + postmaster.pid @@ -1495,7 +1517,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - pg_wal,包括子目录。如果备份包含WAL文件,则将包含pg_wal的合成版本,但它只包含备份工作所需的文件,而不包含其余内容。 + pg_wal,包括子目录。如果备份包含WAL文件,则将包含pg_wal的合成版本,但它只包含使备份可用所需的文件,而不包含其余内容。 @@ -1508,10 +1530,12 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 除了常规文件和目录之外的文件,如符号链接(除了上述列出的目录之外的符号链接)以及特殊设备和操作系统文件,将被跳过。(pg_tblspc中的符号链接将被保留。) + 除了普通文件和目录之外的文件,如符号链接(除了上述列出的目录之外的符号链接)以及特殊设备文件,将被跳过。(pg_tblspc中的符号链接将被保留。) - 如果服务器底层文件系统支持,还会设置所有者、组和文件模式。 + + 如果服务器上的底层文件系统支持,将设置所有者、组和文件模式。 + @@ -1534,7 +1558,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 逻辑复制参数 + 逻辑流复制参数 逻辑复制的START_REPLICATION命令接受以下参数: @@ -1547,7 +1571,9 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" publication_names - 要订阅(接收变更)的发布名称列表,以逗号分隔。各个发布名称按标准对象名称处理,可以按需以相同方式加引号。 + + 要订阅(接收变更)的发布名称列表,以逗号分隔。各个发布名称按标准对象名处理,可按需加引号。 + @@ -2195,33 +2221,51 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" -CancelRequest (F) + +CancelRequest (F) + -Int32(16) + + Int32(16) + -消息内容的长度,以字节为单位,包括此长度字段本身。 + + 消息内容的长度,以字节为单位,包括此长度字段本身。 + -Int32(80877102) + + Int32(80877102) + -取消请求代码。此值的最高 16 位为 1234,最低 16 位为 5678。(为避免混淆,此代码不能与任何协议版本号相同。) + + 取消请求代码。此值的最高 16 位为 1234,最低 16 位为 5678。(为避免混淆,此代码不能与任何协议版本号相同。) + -Int32 + + Int32 + -目标后端的进程 ID。 + + 目标后端的进程 ID。 + -Int32 + + Int32 + -目标后端的密钥。 + + 目标后端的密钥。 + @@ -3866,7 +3910,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 严重性: 字段内容为ERROR, FATAL, 或 + 严重性: 字段内容为ERROR, FATAL, 或 PANIC (在错误消息中), 或 WARNING, NOTICE, DEBUG, INFO, 或 LOG (在通知消息中), @@ -3904,7 +3948,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 消息: 主要的人类可读错误消息。 + 消息: 主要的人类可读错误消息。 这应该准确但简洁(通常一行)。 总是存在。 @@ -3926,7 +3970,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 提示: 关于问题应该怎么做的一个可选建议。 + 提示: 关于问题应该怎么做的一个可选建议。 这意在与细节不同,它提供建议(可能不合适)而不是硬性事实。 可能会跨越多行。 @@ -3959,7 +4003,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" q - 内部查询: 一个失败的内部生成命令的文本。 + 内部查询: 一个失败的内部生成命令的文本。 例如,这可能是由PL/pgSQL函数发出的SQL查询。 @@ -3992,7 +4036,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 表名: 如果错误与特定表相关联,则为表的名称。(有关表模式名称的名称,请参考模式名称字段。) + 表名: 如果错误与特定表相关联,则为表的名称。(有关表模式名称的名称,请参考模式名称字段。) @@ -4002,7 +4046,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 列名: 如果错误与特定表列相关联,则为列的名称。(请参考模式和表名字段以识别表。) + 列名: 如果错误与特定表列相关联,则为列的名称。(请参考模式和表名字段以识别表。) @@ -4012,7 +4056,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 数据类型名称: 如果错误与特定数据类型相关联,则为数据类型的名称。 + 数据类型名称: 如果错误与特定数据类型相关联,则为数据类型的名称。 (有关数据类型模式的名称,请参阅模式名称字段。) @@ -4023,7 +4067,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 约束名称: 如果错误与特定约束相关联,则为约束的名称。请参考上面列出的字段,了解相关表或域。 + 约束名称: 如果错误与特定约束相关联,则为约束的名称。请参考上面列出的字段,了解相关表或域。 (为此,即使索引不是使用约束语法创建的,也将其视为约束。) @@ -4034,7 +4078,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 文件: 报告错误的源代码位置的文件名。 + 文件: 报告错误的源代码位置的文件名。 @@ -4548,13 +4592,13 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" -协议 3.0 与之前版本的变化总结 +自协议 2.0 以来的变更总结 - 本节概述了协议 3.0 与之前协议版本之间的变化。这可以帮助那些需要实现同时处理多种协议版本的客户端库的开发者,或仅仅出于好奇的读者。 - + 本节提供一份简要的变更清单,供准备将现有客户端库更新到协议 3.0 的开发者参考。 + -初始启动包采用灵活的字符串列表格式,取代了固定格式。注意,运行时参数的会话默认值现在可以直接在启动包中指定。(实际上,以前也能通过 options 字段实现,但由于 options 的宽度有限,且无法引用值中的空白,这种方法并不稳妥。) +初始启动包采用灵活的字符串列表格式,取代了固定格式。注意,运行时参数的会话默认值现在可以直接在启动包中指定。(实际上,以前也能通过 options 字段实现,但由于 options 的宽度有限,且无法用引号保护值中的空白字符,这种方法并不稳妥。) 现在,所有消息都在消息类型字节之后紧跟一个长度计数(启动包除外,它没有类型字节)。另请注意,PasswordMessage 现在也有类型字节。 diff --git a/zh/10/queries.sgml b/zh/10/queries.sgml index 5560ed52..758c665a 100644 --- a/zh/10/queries.sgml +++ b/zh/10/queries.sgml @@ -486,7 +486,7 @@ FROM (VALUES ('anne', 'smith'), ('bob', 'jones'), ('joe', 'blow')) - 表函数是那些生成行集合的函数,这些行可以由基本数据类型(标量类型)组成,也可以由复合数据类型(表行)组成。它们在查询的FROM子句中用法类似于表、视图或子查询。表函数返回的列可以像表、视图或子查询的列一样,出现在SELECTJOINWHERE子句中。 + 表函数是那些生成行集合的函数,这些行可以由基础类型(标量类型)组成,也可以由复合数据类型(表行)组成。它们在查询的FROM子句中用法类似于表、视图或子查询。表函数返回的列可以像表、视图或子查询的列一样,出现在SELECTJOINWHERE子句中。 @@ -524,7 +524,7 @@ UNNEST( array_expression , ... - 如果没有提供列的别名,那么对于一个返回基数据类型的函数,列名也与该函数 + 如果没有提供列的别名,那么对于一个返回基础类型的函数,列名也与该函数 名相同。对于一个返回复合类型的函数,结果列会从该类型的属性得到名称。 diff --git a/zh/10/rangetypes.sgml b/zh/10/rangetypes.sgml index 4f7c61f8..92eca5d6 100644 --- a/zh/10/rangetypes.sgml +++ b/zh/10/rangetypes.sgml @@ -159,21 +159,25 @@ SELECT '[4,4)'::int4range; 构造范围 - 每个范围类型都有一个与其同名的构造函数。使用构造函数通常比编写范围字面常量更方便,因为无需对边界值额外加引号。构造函数接受两个或三个参数。两个参数的形式构造标准形式的范围(包含下界,不包含上界);三个参数的形式则按第三个参数指定的形式构造范围边界。第三个参数必须是以下字符串之一:(), - (], - [)[]。例如: --- The full form is: lower bound, upper bound, and text argument indicating --- inclusivity/exclusivity of bounds. + + 每种范围类型都有一个与范围类型同名的构造函数。使用构造函数通常比书写范围字面量更方便,因为这样无需为界限值额外加引号。构造函数接受两个或三个参数。两个参数的形式构造标准形式的范围(下界包含,上界排除),而三个参数的形式则按第三个参数指定的界限形式构造范围。第三个参数必须是下列字符串之一: + ()、 + (]、 + [)或者 + []。 + 例如: + + +-- 完整形式为:下界、上界,以及指示界限包含性/排除性的文本参数。 SELECT numrange(1.0, 14.0, '(]'); --- If the third argument is omitted, '[)' is assumed. +-- 如果省略第三个参数,则假定为 '[)'。 SELECT numrange(1.0, 14.0); --- Although '(]' is specified here, on display the value will be converted to --- canonical form, since int8range is a discrete range type (see below). +-- 虽然这里指定的是 '(]',但显示时该值会转换为规范形式,因为 int8range 是离散范围类型(见下文)。 SELECT int8range(1, 14, '(]'); --- Using NULL for either bound causes the range to be unbounded on that side. +-- 任一界限使用 NULL 都会使该侧无界。 SELECT numrange(NULL, 2.2); diff --git a/zh/10/recovery-config.sgml b/zh/10/recovery-config.sgml index 492fe006..20c3d614 100644 --- a/zh/10/recovery-config.sgml +++ b/zh/10/recovery-config.sgml @@ -54,7 +54,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows 这个信息可以被用来把归档截断为支持从当前恢复重启所需的最小值。 对于单一备库配置,模块常常被用在archive_cleanup_command中,例如: archive_cleanup_command = 'pg_archivecleanup /mnt/server/archivedir %r' - 但是注意,如果多个备库正在从同一个归档目录中恢复,你将需要保证只有当任意服务器都不再需要 WAL 文件时才会删除它们。 + 但是注意,如果多个备库正在从同一个归档目录中恢复,你将需要保证只有当所有服务器都不再需要这些 WAL 文件时才会删除它们。 archive_cleanup_command通常被用于一种温备配置(见)中。 要在该命令中嵌入一个真正的%字符,需要写成%% @@ -106,7 +106,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows - 这个参数指定(pg_create_restore_point()所创建)的已命名的恢复点,恢复将进入该恢复点。 + 这个参数指定(pg_create_restore_point()所创建)的已命名的恢复点,恢复将进行到该恢复点。 @@ -128,7 +128,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows recovery_target_lsn (pg_lsn) recovery_target_lsn 恢复参数 - 此参数指定恢复要进行到的预写式日志位置的 LSN。精确的停止点还受 影响。此参数使用系统数据类型 pg_lsn 解析。 + 此参数指定恢复要进行到的预写日志位置的 LSN。精确的停止点还受 影响。此参数使用系统数据类型 pg_lsn 解析。 @@ -164,13 +164,13 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows 最后,shutdown将在达到恢复目标之后停止服务器。 - 使用pause设置的目的是:如果这个恢复目标就是恢复最想要的位置,就允许对数据库执行查询。 + 使用pause设置的目的是允许对数据库执行查询,以检查这个恢复目标是否为最合适的恢复位置。 暂停的状态可以使用pg_wal_replay_resume()(见)继续,这会让恢复终结。 如果这个恢复目标不是想要的停止点,那么关闭服务器,将恢复目标设置改为一个稍后的目标并且重启以继续恢复。 要让实例在想要的重放点那里准备好,shutdown设置可以派上用场。 - 该实例将仍能重放更多 WAL 记录(并且事实上将不得不重放从下一次它被启动后最后一个检查点以来的 WAL 记录)。 + 该实例将仍能重放更多 WAL 记录(并且事实上,下次启动时必须重新回放自上一个检查点以来的 WAL 记录)。 注意,将 recovery_target_action 设为 shutdown 时,recovery.conf 不会被重命名,因此除非更改配置或手动删除 recovery.conf 文件,否则之后每次启动都会立即关闭。 如果未设置恢复目标,此设置不起作用。如果未启用 ,则 pause 的行为与 shutdown 相同。 @@ -213,13 +213,33 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows - recovery_min_apply_delay (integer) recovery_min_apply_delay 恢复参数 + recovery_min_apply_delay (integer) + + recovery_min_apply_delay 恢复参数 + + - 默认情况下,备库会尽快恢复来自主库的 WAL 记录。保留一份有时间延迟的数据副本可能很有用,可以为纠正导致数据丢失的错误提供机会。此参数允许将恢复延迟固定的一段时间,未指定单位时以毫秒计。例如,设为 5min 时,只有备库系统时间比主库报告的提交时间至少晚五分钟,备库才会重放该事务的提交。 - 服务器之间的复制延迟可能超过此参数的值,此时不会增加额外延迟。注意,延迟是根据主库写入的 WAL 时间戳与备库当前时间之间的差值计算的。网络滞后或级联复制配置造成的传输延迟,可能显著减少实际等待时间。如果主库和备库的系统时钟不同步,可能导致恢复比预期更早地应用记录;但这不是主要问题,因为此参数的实用设置值远大于服务器之间通常的时间偏差。 - 延迟只作用于事务提交的 WAL 记录。其他记录会尽快重放,这不会造成问题,因为 MVCC 可见性规则确保在相应提交记录应用之前,它们的影响不可见。 - 正在恢复的数据库达到一致状态后,延迟就会生效,直到备库被提升或触发。此后,备库将不再继续等待,而是结束恢复。 - 此参数面向流复制部署设计;但只要指定了它,在所有情况下都会生效。使用此功能会延迟 hot_standby_feedback,可能导致主库膨胀;同时使用二者时应谨慎。 synchronous_commit 设为 remote_apply 时,同步复制会受此设置影响;每次 COMMIT 都必须等待提交被应用。 + + 默认情况下,备库会尽快恢复来自主库的 WAL 记录。保留一份延迟的数据副本可能很有用,因为它提供了纠正数据丢失错误的机会。此参数允许将恢复延迟一段固定时间;如果没有指定单位,则以毫秒计。例如,将此参数设置为 5min 时,只有当备库系统时间比主库报告的提交时间至少晚五分钟,备库才会重放各事务的提交。 + + + 服务器之间的复制延迟可能超过此参数的值,这种情况下不会增加延迟。注意,延迟根据主库写入的 WAL 时间戳与备库当前时间之差计算。网络延迟或级联复制配置导致的传输延迟,可能显著缩短实际等待时间。如果主库和备库的系统时钟不同步,恢复时可能比预期更早应用记录;但这通常不是主要问题,因为此参数的实用取值远大于服务器间常见的时间偏差。 + + + 延迟仅发生在事务提交的 WAL 记录上。其他记录会尽快重放;这不会造成问题,因为 MVCC 可见性规则确保在对应提交记录被应用之前,它们的效果不会可见。 + + + 恢复中的数据库达到一致状态后开始延迟,直到备库被提升或触发。此后,备库会结束恢复,不再等待。 + + + 此参数旨在用于流复制部署;不过,只要指定了此参数,它就会在所有情况下生效。使用此功能也会延迟 hot_standby_feedback,可能导致主库膨胀;同时使用两者时应谨慎。 + + + 当 synchronous_commit 设置为 remote_apply 时,同步复制会受到此设置影响;每个 COMMIT 都必须等待提交被应用。 + + + + diff --git a/zh/10/ref/abort.sgml b/zh/10/ref/abort.sgml index c798b8f6..ffef76c6 100644 --- a/zh/10/ref/abort.sgml +++ b/zh/10/ref/abort.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ABORT 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/alter_aggregate.sgml b/zh/10/ref/alter_aggregate.sgml index 561585ee..e0d31467 100644 --- a/zh/10/ref/alter_aggregate.sgml +++ b/zh/10/ref/alter_aggregate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER AGGREGATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/alter_collation.sgml b/zh/10/ref/alter_collation.sgml index 1a9c2e56..346b7a1d 100644 --- a/zh/10/ref/alter_collation.sgml +++ b/zh/10/ref/alter_collation.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER COLLATION 7 - SQL - Language Statements + SQL - 语言语句 @@ -96,7 +96,8 @@ ALTER COLLATION name SET SCHEMA new_sche 注解 - 创建排序规则对象时,该排序规则的提供者特定版本会记录在系统目录中。 + 使用 ICU 库提供的排序规则时,创建排序规则对象会在系统目录中记录 + ICU 给出的排序器版本。 使用该排序规则时,会将当前版本与记录的版本进行比较;如果二者不匹 配,就会发出警告,例如: @@ -106,16 +107,16 @@ HINT: Rebuild all objects affected by this collation and run ALTER COLLATION pg 排序规则定义的变化可能导致索引损坏及其他问题,因为数据库系统依赖已 存储对象具有特定的排序顺序。一般来说应避免这种情况,但在某些合理情 - 形下仍可能发生,例如将操作系统升级到新的主版本,或者使用 + 形下仍可能发生,例如使用 pg_upgrade升级到链接了较新 ICU 版本的服务器二进 制文件时。出现这种情况时,应重建所有依赖该排序规则的对象,例如使用 REINDEX。完成后,可以使用命令 ALTER COLLATION ... REFRESH VERSION刷新排序规则 - 版本。这样会更新系统目录,使其记录当前的排序规则版本,并让该警告消 + 版本。这样会更新系统目录,使其记录当前的排序器版本,并让该警告消 失。请注意,这实际上并不会检查所有受影响对象是否都已被正确重建。 - 可以使用以下查询找出当前数据库中所有需要刷新的排序规则,以及依赖这些排序规则的对象:以下查询可用于识别当前数据库中所有需要刷新的排序规则,以及依赖它们的对象: ALTER CONVERSION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/alter_database.sgml b/zh/10/ref/alter_database.sgml index aae328ab..1019bf33 100644 --- a/zh/10/ref/alter_database.sgml +++ b/zh/10/ref/alter_database.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER DATABASE 7 - SQL - Language Statements + SQL - 语言语句 @@ -59,7 +59,9 @@ ALTER DATABASE name RESET ALL 第三种形式更改数据库的所有者。要更改所有者,必须拥有该数据库,并且还必须是新所有者角色的直接或间接成员,并且必须拥有CREATEDB权限。(请注意,超级用户会自动拥有所有这些权限。) - 第四种形式更改数据库的默认表空间。只有数据库所有者或超级用户可以执行此操作;还必须拥有新表空间的创建权限。此命令会将数据库旧默认表空间中的所有表或索引物理移动到新表空间。对该数据库而言,新默认表空间必须为空,并且不能有任何人连接到该数据库。非默认表空间中的表和索引不受影响。 + + 第四种形式更改数据库的默认表空间。只有数据库拥有者或者超级用户可以这样做;你还必须对新表空间具有创建权限。该命令会将数据库旧默认表空间中的所有表和索引在物理上移动到新表空间中。对于该数据库而言,新默认表空间必须为空,并且不能有人连接到该数据库。位于非默认表空间中的表和索引不受影响。 + 其余形式会更改某个PostgreSQL数据库的运行时配置变量的会话默认值。此后每当在该数据库中启动一个新会话时,指定的值就会成为会话默认值。数据库特定的默认值会覆盖postgresql.conf中的设置,或者从postgres命令行接收到的设置。只有数据库拥有者或者超级用户才能更改该数据库的会话默认值。某些变量不能以这种方式设置,或者只能由超级用户设置。 @@ -82,9 +84,7 @@ ALTER DATABASE name RESET ALL allowconn - - 如果为假,则没有人能连接到这个数据库。 - + 如果为 false,则任何人都不能连接到该数据库。 @@ -100,7 +100,9 @@ ALTER DATABASE name RESET ALL istemplate - 如果为 true,则任何拥有CREATEDB权限的用户都可以克隆该数据库;如果为 false,则只有超级用户或数据库所有者可以克隆它。 + + 如果为 true,则任何具有 CREATEDB 权限的用户都可以克隆该数据库;如果为 false,则只有超级用户或该数据库的拥有者可以克隆它。 + @@ -139,9 +141,17 @@ ALTER DATABASE name RESET ALL configuration_parameter value - 将此数据库的会话默认值设置为指定配置参数的给定值。如果指定valueDEFAULT,或者等效地使用RESET,则删除数据库特定设置,因此新会话将继承系统范围的默认设置。使用RESET ALL清除所有数据库特定设置。SET FROM CURRENT将会话当前参数值保存为数据库特定值。 + + 将此数据库在指定配置参数上的会话默认值设为给定值。如果 + valueDEFAULT,或者等效地使用了 + RESET,则数据库特定设置会被移除,因此新会话将继承系统范围的默认设置。使用 + RESET ALL可清除所有数据库特定设置。 + SET FROM CURRENT会把该参数在当前会话中的值保存为数据库特定值。 + - 有关允许的参数名称和值的更多信息,请参见 + + 关于允许的参数名和值的更多信息,见。 + diff --git a/zh/10/ref/alter_default_privileges.sgml b/zh/10/ref/alter_default_privileges.sgml index d0a9e3f2..906b088c 100644 --- a/zh/10/ref/alter_default_privileges.sgml +++ b/zh/10/ref/alter_default_privileges.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER DEFAULT PRIVILEGES 7 - SQL - Language Statements + SQL - 语言语句 @@ -116,8 +116,8 @@ REVOKE [ GRANT OPTION FOR ] 一个现有模式的名称。如果指定,将修改以后在该模式中创建的对象的默认权限。 如果省略IN SCHEMA,则修改全局默认权限。 - 在为模式和大对象设置权限时,不允许使用IN SCHEMA, - 因为模式不能嵌套,而大对象不属于任何模式。 + 在为模式设置权限时,不允许使用IN SCHEMA, + 因为模式不能嵌套。 diff --git a/zh/10/ref/alter_domain.sgml b/zh/10/ref/alter_domain.sgml index 2e088d19..4c32b9e1 100644 --- a/zh/10/ref/alter_domain.sgml +++ b/zh/10/ref/alter_domain.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER DOMAIN 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/alter_event_trigger.sgml b/zh/10/ref/alter_event_trigger.sgml index 7e8c1b23..73bcd87d 100644 --- a/zh/10/ref/alter_event_trigger.sgml +++ b/zh/10/ref/alter_event_trigger.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER EVENT TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -58,7 +58,7 @@ ALTER EVENT TRIGGER name RENAME TO new_owner - 该事件触发器的新拥有者的用户名。 + 该事件触发器的新所有者的用户名。 @@ -94,7 +94,7 @@ ALTER EVENT TRIGGER name RENAME TO - 另见 + 参见 diff --git a/zh/10/ref/alter_extension.sgml b/zh/10/ref/alter_extension.sgml index 81605777..892e9d06 100644 --- a/zh/10/ref/alter_extension.sgml +++ b/zh/10/ref/alter_extension.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER EXTENSION 7 - SQL - Language Statements + SQL - 语言语句 @@ -57,7 +57,7 @@ ALTER EXTENSION name DROP object_name | VIEW object_name -aggregate_signature为: +其中 aggregate_signature 是: * | [ argmode ] [ argname ] argtype [ , ... ] | @@ -69,7 +69,10 @@ ALTER EXTENSION name DROP 描述 - ALTER EXTENSION更改已安装扩展的定义。有几个子形式: + ALTER EXTENSION更改已安装扩展的定义。 + 其子形式如下: + + UPDATE @@ -110,7 +113,10 @@ ALTER EXTENSION name DROP - 有关这些操作的更多信息。 + + + 有关这些操作的更多信息,见。 + 要使用ALTER EXTENSION,你必须拥有该扩展。 diff --git a/zh/10/ref/alter_foreign_data_wrapper.sgml b/zh/10/ref/alter_foreign_data_wrapper.sgml index ca24fc46..281da286 100644 --- a/zh/10/ref/alter_foreign_data_wrapper.sgml +++ b/zh/10/ref/alter_foreign_data_wrapper.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER FOREIGN DATA WRAPPER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/alter_foreign_table.sgml b/zh/10/ref/alter_foreign_table.sgml index 47eaf157..0b037fb0 100644 --- a/zh/10/ref/alter_foreign_table.sgml +++ b/zh/10/ref/alter_foreign_table.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER FOREIGN TABLE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/alter_function.sgml b/zh/10/ref/alter_function.sgml index fc528b55..3d235cdc 100644 --- a/zh/10/ref/alter_function.sgml +++ b/zh/10/ref/alter_function.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER FUNCTION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/alter_group.sgml b/zh/10/ref/alter_group.sgml index 09de18fb..9a4cbe90 100644 --- a/zh/10/ref/alter_group.sgml +++ b/zh/10/ref/alter_group.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER GROUP 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/alter_index.sgml b/zh/10/ref/alter_index.sgml index 8f7271ef..a300f9b8 100644 --- a/zh/10/ref/alter_index.sgml +++ b/zh/10/ref/alter_index.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER INDEX 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/alter_language.sgml b/zh/10/ref/alter_language.sgml index d8bbfd0b..3c4d0994 100644 --- a/zh/10/ref/alter_language.sgml +++ b/zh/10/ref/alter_language.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER LANGUAGE 7 - SQL - Language Statements + SQL - 语言语句 @@ -31,8 +31,8 @@ ALTER [ PROCEDURAL ] LANGUAGE name OWNER TO { ALTER LANGUAGE更改一种过程语言的定义。 - 目前唯一的功能是重命名该语言或为其指定新的拥有者。 - 要使用ALTER LANGUAGE,你必须是超级用户或者该语言的拥有者。 + 目前唯一的功能是重命名该语言或为其指定新的所有者。 + 要使用ALTER LANGUAGE,你必须是超级用户或者该语言的所有者。 @@ -62,7 +62,7 @@ ALTER [ PROCEDURAL ] LANGUAGE name OWNER TO { new_owner - 该语言的新拥有者 + 该语言的新所有者 diff --git a/zh/10/ref/alter_large_object.sgml b/zh/10/ref/alter_large_object.sgml index 1a3f4017..bb0c805c 100644 --- a/zh/10/ref/alter_large_object.sgml +++ b/zh/10/ref/alter_large_object.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER LARGE OBJECT 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/alter_materialized_view.sgml b/zh/10/ref/alter_materialized_view.sgml index 03c69eb9..870122bd 100644 --- a/zh/10/ref/alter_materialized_view.sgml +++ b/zh/10/ref/alter_materialized_view.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER MATERIALIZED VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/alter_opclass.sgml b/zh/10/ref/alter_opclass.sgml index 7e5154eb..f9a6e2ef 100644 --- a/zh/10/ref/alter_opclass.sgml +++ b/zh/10/ref/alter_opclass.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER OPERATOR CLASS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/alter_operator.sgml b/zh/10/ref/alter_operator.sgml index 423d0763..c0dff2db 100644 --- a/zh/10/ref/alter_operator.sgml +++ b/zh/10/ref/alter_operator.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER OPERATOR 7 - SQL - Language Statements + SQL - 语言语句 @@ -101,7 +101,7 @@ ALTER OPERATOR name ( { left_type - 注解 + 示例 更改自定义操作符的拥有者,该操作符为a @@ b,类型为text diff --git a/zh/10/ref/alter_opfamily.sgml b/zh/10/ref/alter_opfamily.sgml index df9b4330..487fd305 100644 --- a/zh/10/ref/alter_opfamily.sgml +++ b/zh/10/ref/alter_opfamily.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER OPERATOR FAMILY 7 - SQL - Language Statements + SQL - 语言语句 @@ -154,14 +154,14 @@ ALTER OPERATOR FAMILY name USING support_number - 与操作符族关联的函数的索引方法支持过程编号。 + 与操作符族关联的函数的索引方法支持函数编号。 function_name - 作为操作符族索引方法支持过程的函数名称(可带模式限定)。如果未指定参数列表,该名称在其模式中必须唯一。 + 作为操作符族索引方法支持函数的函数名称(可带模式限定)。如果未指定参数列表,该名称在其模式中必须唯一。 @@ -227,7 +227,9 @@ ALTER OPERATOR FAMILY name USING name RENAME TO < CONNECTION 'conninfo' - 该子句替换最初由设置的连接字符串。 + 该子句更改最初由设置的连接属性。 详情请参见该命令。 diff --git a/zh/10/ref/alter_system.sgml b/zh/10/ref/alter_system.sgml index 95ff3118..d7ae2dde 100644 --- a/zh/10/ref/alter_system.sgml +++ b/zh/10/ref/alter_system.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER SYSTEM 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/alter_table.sgml b/zh/10/ref/alter_table.sgml index d4a492fb..e9cb340d 100644 --- a/zh/10/ref/alter_table.sgml +++ b/zh/10/ref/alter_table.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TABLE 7 - SQL - Language Statements + SQL - 语言语句 @@ -656,7 +656,7 @@ ALTER TABLE [ IF EXISTS ] name DROP COLUMN形式不会从物理上删除列,而只是使其对 SQL 操作不可见。表后续的插入和更新操作会为该列存储空值。因此,删除列的速度很快,但不会立即减少表在磁盘上的大小,因为被删除列占用的空间不会被回收。随着现有行被更新,空间会逐渐回收。(删除系统oid列时不适用这些说明;删除该列会立即重写表。) - 若要强制立即回收已删除列所占的空间,可以执行任何一种会导致整表重写的ALTER TABLE形式。这样会重新构造每一行,并用空值替换被删除的列。 + 若要强制立即回收已删除列所占的空间,可以执行任何一种会导致整表重写的ALTER TABLE形式。这样会重建每一行,并用空值替换被删除的列。 diff --git a/zh/10/ref/alter_tablespace.sgml b/zh/10/ref/alter_tablespace.sgml index ad761cca..643f4637 100644 --- a/zh/10/ref/alter_tablespace.sgml +++ b/zh/10/ref/alter_tablespace.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TABLESPACE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/alter_trigger.sgml b/zh/10/ref/alter_trigger.sgml index 82be3a8c..7384e01b 100644 --- a/zh/10/ref/alter_trigger.sgml +++ b/zh/10/ref/alter_trigger.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -31,7 +31,9 @@ ALTER TRIGGER name ON ALTER TRIGGER更改现有触发器的属性。RENAME子句更改给定触发器的名称,但不以其他方式更改触发器定义。DEPENDS ON EXTENSION子句将触发器标记为依赖扩展,因此扩展被删除时触发器也会自动删除。 - 要更改触发器的属性,必须拥有触发器所在的表。 + + 若要更改触发器的属性,你必须拥有该触发器所作用的表。 + @@ -106,7 +108,7 @@ ALTER TRIGGER emp_stamp ON emp DEPENDS ON EXTENSION emplib; - 另见 + 参见 diff --git a/zh/10/ref/alter_tsconfig.sgml b/zh/10/ref/alter_tsconfig.sgml index d793049e..c19cfa68 100644 --- a/zh/10/ref/alter_tsconfig.sgml +++ b/zh/10/ref/alter_tsconfig.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TEXT SEARCH CONFIGURATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/alter_tsdictionary.sgml b/zh/10/ref/alter_tsdictionary.sgml index 746c5312..1356e2fd 100644 --- a/zh/10/ref/alter_tsdictionary.sgml +++ b/zh/10/ref/alter_tsdictionary.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TEXT SEARCH DICTIONARY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/alter_tsparser.sgml b/zh/10/ref/alter_tsparser.sgml index 687343f3..e1026b50 100644 --- a/zh/10/ref/alter_tsparser.sgml +++ b/zh/10/ref/alter_tsparser.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TEXT SEARCH PARSER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/alter_tstemplate.sgml b/zh/10/ref/alter_tstemplate.sgml index 1c699f7f..e2604fd1 100644 --- a/zh/10/ref/alter_tstemplate.sgml +++ b/zh/10/ref/alter_tstemplate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TEXT SEARCH TEMPLATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/alter_type.sgml b/zh/10/ref/alter_type.sgml index 672bfda8..16184100 100644 --- a/zh/10/ref/alter_type.sgml +++ b/zh/10/ref/alter_type.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TYPE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/alter_user.sgml b/zh/10/ref/alter_user.sgml index f239f5f4..9bc791c4 100644 --- a/zh/10/ref/alter_user.sgml +++ b/zh/10/ref/alter_user.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER USER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/alter_user_mapping.sgml b/zh/10/ref/alter_user_mapping.sgml index c236e3fc..be12eafb 100644 --- a/zh/10/ref/alter_user_mapping.sgml +++ b/zh/10/ref/alter_user_mapping.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER USER MAPPING 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/alter_view.sgml b/zh/10/ref/alter_view.sgml index 6747d15e..72dcdf7f 100644 --- a/zh/10/ref/alter_view.sgml +++ b/zh/10/ref/alter_view.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/analyze.sgml b/zh/10/ref/analyze.sgml index 40bd12da..bbb752fa 100644 --- a/zh/10/ref/analyze.sgml +++ b/zh/10/ref/analyze.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ANALYZE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/begin.sgml b/zh/10/ref/begin.sgml index ebf0e22b..b3fc5a6b 100644 --- a/zh/10/ref/begin.sgml +++ b/zh/10/ref/begin.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation BEGIN 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/checkpoint.sgml b/zh/10/ref/checkpoint.sgml index b3df8307..ea614a5d 100644 --- a/zh/10/ref/checkpoint.sgml +++ b/zh/10/ref/checkpoint.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CHECKPOINT 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/close.sgml b/zh/10/ref/close.sgml index 0332fa85..2bd31368 100644 --- a/zh/10/ref/close.sgml +++ b/zh/10/ref/close.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation CLOSE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/cluster.sgml b/zh/10/ref/cluster.sgml index dac618aa..5fe1ac6b 100644 --- a/zh/10/ref/cluster.sgml +++ b/zh/10/ref/cluster.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CLUSTER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/clusterdb.sgml b/zh/10/ref/clusterdb.sgml index de6f955e..1f783c71 100644 --- a/zh/10/ref/clusterdb.sgml +++ b/zh/10/ref/clusterdb.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation clusterdb 1 - Application + 应用程序 diff --git a/zh/10/ref/comment.sgml b/zh/10/ref/comment.sgml index 4d94e3fa..73726ce1 100644 --- a/zh/10/ref/comment.sgml +++ b/zh/10/ref/comment.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation COMMENT 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/commit.sgml b/zh/10/ref/commit.sgml index 64614878..0e4ea87c 100644 --- a/zh/10/ref/commit.sgml +++ b/zh/10/ref/commit.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation COMMIT 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/commit_prepared.sgml b/zh/10/ref/commit_prepared.sgml index 285c46ba..9c51f29a 100644 --- a/zh/10/ref/commit_prepared.sgml +++ b/zh/10/ref/commit_prepared.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation COMMIT PREPARED 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/copy.sgml b/zh/10/ref/copy.sgml index 4ef72add..be77d422 100644 --- a/zh/10/ref/copy.sgml +++ b/zh/10/ref/copy.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation COPY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/create_access_method.sgml b/zh/10/ref/create_access_method.sgml index 94dd0ae4..1007f3b7 100644 --- a/zh/10/ref/create_access_method.sgml +++ b/zh/10/ref/create_access_method.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE ACCESS METHOD 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/create_aggregate.sgml b/zh/10/ref/create_aggregate.sgml index e46d5020..ed2c96bc 100644 --- a/zh/10/ref/create_aggregate.sgml +++ b/zh/10/ref/create_aggregate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE AGGREGATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/create_cast.sgml b/zh/10/ref/create_cast.sgml index 008dc5a9..2ea4aaee 100644 --- a/zh/10/ref/create_cast.sgml +++ b/zh/10/ref/create_cast.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE CAST 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/create_collation.sgml b/zh/10/ref/create_collation.sgml index 1d11c518..1702179a 100644 --- a/zh/10/ref/create_collation.sgml +++ b/zh/10/ref/create_collation.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE COLLATION 7 - SQL - Language Statements + SQL - 语言语句 @@ -94,7 +94,7 @@ CREATE COLLATION [ IF NOT EXISTS ] name FROM provider - 指定用于与此排序规则关联的区域设置服务的提供者。可能的值为: icuICU libclibc 是默认值。可用选项取决于操作系统和构建选项。 + 指定用于与此排序规则关联的区域设置服务的提供程序。可能的值为: icuICU libclibc 是默认值。可用选项取决于操作系统和构建选项。 @@ -155,7 +155,9 @@ CREATE COLLATION french (locale = 'fr_FR.utf8'); - 使用 ICU 提供者并采用德语电话簿排序顺序创建排序规则: + + 使用 ICU 提供程序并采用德语电话簿排序顺序创建一种排序规则: + CREATE COLLATION german_phonebook (provider = icu, locale = 'de-u-co-phonebk'); diff --git a/zh/10/ref/create_conversion.sgml b/zh/10/ref/create_conversion.sgml index 91a21cba..33f27e07 100644 --- a/zh/10/ref/create_conversion.sgml +++ b/zh/10/ref/create_conversion.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE CONVERSION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/create_database.sgml b/zh/10/ref/create_database.sgml index 259877ee..785609be 100644 --- a/zh/10/ref/create_database.sgml +++ b/zh/10/ref/create_database.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE DATABASE 7 - SQL - Language Statements + SQL - 语言语句 @@ -46,7 +46,15 @@ CREATE DATABASE name CREATEDB 权限。见 - 默认情况下,新数据库将通过克隆标准系统数据库 template1 来创建。可以通过编写 TEMPLATE name 指定不同的模板。特别地,通过编写 TEMPLATE template0,可以创建一个仅包含由您的 PostgreSQL 版本预定义的标准对象的全新数据库。如果您希望避免复制可能已添加到 template1 的任何安装本地对象,此方法非常有用。 + + 默认情况下,新数据库通过克隆标准系统数据库 + template1 来创建。可以通过写成 TEMPLATE + name 指定其他模板。特别是, + 写成 TEMPLATE template0 时,可以创建一个全新的数据库, + 它只包含你的 PostgreSQL 版本预定义的标准对象。 + 如果你希望避免复制任何可能已添加到 template1 中的站点本地附加对象, + 这会很有用。 + @@ -56,25 +64,36 @@ CREATE DATABASE name name - 要创建的数据库名称。 + + 要创建的数据库名称。 + user_name - 新数据库所有者的角色名称,或使用 DEFAULT 以使用默认值(即执行命令的用户)。要创建由其他角色拥有的数据库,您必须是该角色的直接或间接成员,或为超级用户。 + 新数据库所有者的角色名称,或使用 DEFAULT 以使用默认值(即执行命令的用户)。要创建由其他角色拥有的数据库,你必须是该角色的直接或间接成员,或为超级用户。 template - 用于创建新数据库的模板名称,或使用 DEFAULT 以使用默认模板(template1)。 + + 用于创建新数据库的模板名称,或者指定 DEFAULT + 以使用默认模板(template1)。 + encoding - 新数据库中使用的字符集编码。指定字符串常量(例如 'SQL_ASCII'),或整数编码编号,或使用 DEFAULT 以使用默认编码(即模板数据库的编码)。PostgreSQL 服务器支持的字符集在 中有描述。请参见下方的附加限制。 + + 新数据库要使用的字符集编码。可指定字符串常量(例如 + 'SQL_ASCII')、整数编码编号,或者指定 + DEFAULT 以使用默认编码(即模板数据库的编码)。 + PostgreSQL 服务器支持的字符集见 + 。其他限制见下文。 + @@ -92,28 +111,40 @@ CREATE DATABASE name tablespace_name - 将与新数据库关联的表空间名称,或使用 DEFAULT 来使用模板数据库的表空间。该表空间将成为在此数据库中创建的对象的默认表空间。有关更多信息,请参见 + + 将与新数据库关联的表空间名称,或者指定 DEFAULT + 以使用模板数据库的表空间。该表空间将成为在此数据库中创建对象时使用的默认表空间。详见 + 。 + allowconn - 如果为 false,则没有人可以连接到此数据库。默认值为 true,允许连接(除非受其他机制(如 GRANT/REVOKE CONNECT)限制)。 + + 如果为 false,则任何人都不能连接到该数据库。默认值为 true,即允许连接 + (但仍受其他机制限制,例如 + GRANT/REVOKE CONNECT)。 + connlimit - 可以同时连接到此数据库的连接数。-1(默认值)表示无限制。 + + 可对该数据库建立的并发连接数。-1(默认值)表示不受限制。 + istemplate - 如果为 true,则任何拥有 CREATEDB 权限的用户都可以克隆此数据库;如果为 false(默认值),则只有超级用户或数据库所有者才能克隆它。 + + 如果为 true,则任何具有 CREATEDB 权限的用户都可以克隆该数据库;如果为 false(默认值),则只有超级用户或该数据库的拥有者可以克隆它。 + @@ -135,7 +166,7 @@ CREATE DATABASE name 多半与数据目录权限不足、磁盘已满或其他文件系统问题有关。 - 使用 删除数据库 + 使用 删除数据库。 程序 是这个命令的一个包装器程序,为方便使用而提供。 @@ -152,11 +183,24 @@ CREATE DATABASE name - 为新数据库指定的字符集编码必须与所选的区域设置(LC_COLLATELC_CTYPE)兼容。如果区域设置为 C(或等效的 POSIX),则允许所有编码,但其他区域设置仅有一种编码能正常工作。(在 Windows 上,UTF-8 编码可与任何区域设置一起使用。)CREATE DATABASE 允许超级用户指定 SQL_ASCII 编码,而不管区域设置如何,但此选择已弃用,如果在数据库中存储了与区域设置不兼容编码的数据,可能导致字符串函数行为异常。 + + 为新数据库指定的字符集编码必须与所选区域设置(LC_COLLATE + 和 LC_CTYPE)兼容。如果区域设置为 C + (或等价的 POSIX),则允许所有编码;但对于其他区域设置,只有一种编码能够正常工作。(不过,在 Windows 上,UTF-8 编码可与任何区域设置一起使用。) + CREATE DATABASE 允许超级用户不考虑区域设置而指定 + SQL_ASCII 编码,但这种选择已弃用;如果数据库中存储了与该区域设置不兼容编码的数据,字符串函数的行为可能会出错。 + - 编码和区域设置必须与模板数据库匹配,除非使用 template0 作为模板。这是因为其他数据库可能包含与指定编码不匹配的数据,或包含受 LC_COLLATELC_CTYPE 影响排序顺序的索引。复制此类数据将导致数据库在新设置下出现损坏。然而,template0 被确认不包含任何会受影响的数据或索引。 + + 编码和区域设置必须与模板数据库的设置一致,除非使用 + template0 作为模板。这是因为其他数据库可能包含与指定编码不匹配的数据,或者包含排序顺序会受 + LC_COLLATELC_CTYPE 影响的索引。复制这样的数据会导致数据库在新设置下被视为损坏。不过,已知 + template0 不包含任何会受此影响的数据或索引。 + - CONNECTION LIMIT 选项仅近似强制执行;如果两个新会话几乎同时启动,而数据库仅剩一个连接 ,则有可能两者都会失败。此外,该限制对超级用户或后台工作进程不生效。 + + CONNECTION LIMIT 选项只是近似地被强制执行;如果两个新会话几乎同时启动,而该数据库只剩下一个连接,则两者都可能失败。此外,该限制对超级用户或后台工作进程无效。 + @@ -170,25 +214,39 @@ CREATE DATABASE lusiadas; - 要创建数据库sales,其所有者为用户 salesapp,默认表空间为 salesspace: + + 要创建一个由用户 salesapp 拥有、默认表空间为 + salesspace 的数据库 sales CREATE DATABASE sales OWNER salesapp TABLESPACE salesspace; - 要创建数据库music,使用不同的区域设置: + + 要创建一个使用不同区域设置的数据库 music: + + CREATE DATABASE music LC_COLLATE 'sv_SE.utf8' LC_CTYPE 'sv_SE.utf8' TEMPLATE template0; -在此示例中,TEMPLATE template0子句在指定的区域设置与template1中的区域设置不同时是必需的。(如果相同,则显式指定区域设置是多余的。) + + 在这个示例中,如果指定的区域设置与 template1 中的不同, + 则必须使用 TEMPLATE template0 子句。(如果相同, + 那么显式指定区域设置就是多余的。) + - 要创建数据库music2,使用不同的区域设置和不同的字符集编码: + + 要创建一个使用不同区域设置和不同字符集编码的数据库 + music2: + CREATE DATABASE music2 LC_COLLATE 'sv_SE.iso885915' LC_CTYPE 'sv_SE.iso885915' ENCODING LATIN9 TEMPLATE template0; -指定的区域设置和编码设置必须匹配,否则将报告错误。 + + 指定的区域设置和编码设置必须匹配,否则会报错。 + 请注意,区域设置名称是特定于操作系统的,因此上述命令未必在所有环境中都以相同方式工作。 diff --git a/zh/10/ref/create_domain.sgml b/zh/10/ref/create_domain.sgml index 310e45d7..8129d5bc 100644 --- a/zh/10/ref/create_domain.sgml +++ b/zh/10/ref/create_domain.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE DOMAIN 7 - SQL - Language Statements + SQL - 语言语句 @@ -86,7 +86,7 @@ CREATE DOMAIN name [ AS ] 该域的可选排序规则。如果未指定排序规则,则该域的排序规则行为与其 底层数据类型相同。如果指定了COLLATE,则底层 - 类型必须是一种可排序数据类型。 + 类型必须是一种支持排序规则的数据类型。 diff --git a/zh/10/ref/create_event_trigger.sgml b/zh/10/ref/create_event_trigger.sgml index e8804738..034073d1 100644 --- a/zh/10/ref/create_event_trigger.sgml +++ b/zh/10/ref/create_event_trigger.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE EVENT TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -38,7 +38,7 @@ CREATE EVENT TRIGGER name CREATE EVENT TRIGGER创建一个新的事件触发器。 每当指定的事件发生,并且与该触发器关联的WHEN条件(如果有)得到 满足时,就会执行该触发器函数。有关事件触发器的一般性介绍,见 - 。创建事件触发器的用户将成为其拥有者。 + 。创建事件触发器的用户将成为其所有者。 @@ -75,8 +75,7 @@ CREATE EVENT TRIGGER name - 用于过滤事件的变量名称。这使得可以将触发器限定为只在支持该变量的部 - 分情形下触发。当前唯一支持的 + 用于过滤事件的变量名称。这样可以将触发器限定为只在原本支持的部分情形下触发。当前唯一支持的 filter_variableTAG @@ -155,7 +154,7 @@ CREATE EVENT TRIGGER abort_ddl ON ddl_command_start - 另见 + 参见 diff --git a/zh/10/ref/create_extension.sgml b/zh/10/ref/create_extension.sgml index 6797781c..7d4ace7f 100644 --- a/zh/10/ref/create_extension.sgml +++ b/zh/10/ref/create_extension.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE EXTENSION 7 - SQL - Language Statements + SQL - 语言语句 @@ -67,7 +67,12 @@ CREATE EXTENSION [ IF NOT EXISTS ] extension_name extension_name - 要安装的扩展的名称。PostgreSQL 将使用 SHAREDIR/extension/extension_name.control 文件中的信息创建扩展。 + + 要安装的扩展名称。PostgreSQL将根据 + SHAREDIR/extension/extension_name.control + 文件中的详细信息创建该扩展。 + @@ -112,7 +117,7 @@ CREATE EXTENSION [ IF NOT EXISTS ] extension_name old_version - FROM old_version 必须在且仅在尝试安装一个替换 旧式模块的扩展时指定,该模块仅是一组未打包为扩展的对象集合。此选项会导致 CREATE EXTENSION 运行一个替代安装脚本,将现有对象吸收进扩展中,而不是创建新对象。请注意 SCHEMA 指定了包含这些预先存在的对象的模式。 + FROM old_version 必须在且仅在尝试安装一个替换 旧式模块的扩展时指定,该模块仅是一组未打包为扩展的对象集合。此选项会导致 CREATE EXTENSION 运行一个替代安装脚本,将现有对象吸收进扩展中,而不是创建新对象。请确保 SCHEMA 指定的是包含这些现有对象的模式。 old_version的值由扩展作者决定,如果存在多个可升级为扩展的旧式模块版本,该值可能会有所不同。对于PostgreSQL 9.1 之前版本提供的标准附加模块,将模块更新为扩展形式时应使用unpackaged作为old_version的值。 @@ -157,7 +162,7 @@ CREATE EXTENSION [ IF NOT EXISTS ] extension_name 会在之后执行编写粗心的扩展脚本时实施攻击,使该用户获得超级用户权限。 不过,只有当特洛伊木马对象在脚本执行期间位于 search_path 中时,它们才会构成危险;这意味着它们 - 位于扩展的安装目标模式中,或位于它所依赖的某个扩展所属的模式中。 + 位于扩展的安装目标模式中,或位于它所依赖的某个扩展的目标模式中。 因此,处理那些脚本尚未经过仔细审查的扩展时,一个经验法则是: 只把它们安装到从未向任何不受信任用户授予、而且今后也不会授予 CREATE 权限的模式中。它们所依赖的任何扩展也应如此。 @@ -179,10 +184,14 @@ CREATE EXTENSION [ IF NOT EXISTS ] extension_name 示例 - 安装hstore扩展到当前数据库,并将其对象放入模式addons: + + 将 hstore 扩展安装到当前数据库中,并把 + 其对象放在 addons 模式中: CREATE EXTENSION hstore SCHEMA addons; -另一种实现相同效果的方法: + + 实现同样效果的另一种方式是: + SET search_path = addons; CREATE EXTENSION hstore; diff --git a/zh/10/ref/create_foreign_data_wrapper.sgml b/zh/10/ref/create_foreign_data_wrapper.sgml index f1d65ae1..4092e11b 100644 --- a/zh/10/ref/create_foreign_data_wrapper.sgml +++ b/zh/10/ref/create_foreign_data_wrapper.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE FOREIGN DATA WRAPPER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/create_foreign_table.sgml b/zh/10/ref/create_foreign_table.sgml index f5b99a99..711b5716 100644 --- a/zh/10/ref/create_foreign_table.sgml +++ b/zh/10/ref/create_foreign_table.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE FOREIGN TABLE 7 - SQL - Language Statements + SQL - 语言语句 @@ -133,9 +133,7 @@ FROM ( { numeric_literal | COLLATE collation - - COLLATE子句为该列(必须是一种可排序数据类型)指定一个排序规则。如果未指定,则使用该列数据类型的默认排序规则。 - + COLLATE子句为列指定排序规则(该列必须属于支持排序规则的数据类型)。如果未指定,则使用列数据类型的默认排序规则。 diff --git a/zh/10/ref/create_function.sgml b/zh/10/ref/create_function.sgml index e6b54cd7..7a239223 100644 --- a/zh/10/ref/create_function.sgml +++ b/zh/10/ref/create_function.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE FUNCTION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/create_group.sgml b/zh/10/ref/create_group.sgml index 6db6ab93..970e6954 100644 --- a/zh/10/ref/create_group.sgml +++ b/zh/10/ref/create_group.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE GROUP 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/create_index.sgml b/zh/10/ref/create_index.sgml index b0a6e64a..605997a1 100644 --- a/zh/10/ref/create_index.sgml +++ b/zh/10/ref/create_index.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE INDEX 7 - SQL - Language Statements + SQL - 语言语句 @@ -53,7 +53,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] PostgreSQL提供了索引方法 - B-树、哈希、GiST、SP-GiST、GIN 以及 BRIN。用户也可以定义自己的索引 + B-树、hash、GiST、SP-GiST、GIN 以及 BRIN。用户也可以定义自己的索引 方法,但这相当复杂。 @@ -104,7 +104,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] 使用此选项时,PostgreSQL将在构建索引时不获取任何会阻止对表进行并发插入、更新或删除的锁;而标准索引构建会阻塞对表的写入(但不会阻塞读取),直到构建完成。使用此选项时有几个注意事项需要了解—请参见 对于临时表,CREATE INDEX始终是非并发的, - 因为没有其他会话可以访问它们,而且非并发创建索引的成本更低。 + 因为没有其他会话可以访问它们,而且非并发创建索引的代价更低。 @@ -112,7 +112,11 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] IF NOT EXISTS - 如果已存在同名关系,则不要抛出错误。此时会发出通知。请注意,无法保证现有索引与将要创建的索引有任何相似之处。指定IF NOT EXISTS时必须提供索引名称。 + + 如果同名关系已存在,则不抛出错误,而是发出一个提示。注意, + 现有索引并不保证与本应创建的索引有任何相似之处。指定 + IF NOT EXISTS时,必须提供索引名。 + @@ -126,49 +130,70 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] table_name - 要建立索引的表名称(可能包含模式限定)。 + + 要建立索引的表名(可以是模式限定名)。 + method - 要使用的索引方法名称。可选项包括btreehashgistspgistginbrin,以及用户安装的访问方法(例如bloom)。默认方法是btree + + 要使用的索引方法的名称。选择包括btreehash、 + gistspgistgin、 + brin,或用户安装的访问方法,如 + bloom。 + 默认方法是btree。 + column_name - 表的列名称。 + + 一个表列的名称。 + expression - 基于表中一个或多个列的表达式。通常必须按照语法所示,在表达式两侧加上括号。不过,如果表达式采用函数调用的形式,则可以省略括号。 + + 一个基于表中一个或多个列的表达式。通常必须像语法中所示那样写在 + 外围圆括号中。不过,如果该表达式是函数调用形式,则可以省略圆括号。 + collation - 用于索引的排序规则名称。默认情况下,索引使用要建立索引的列所声明的排序规则,或要建立索引的表达式的结果排序规则。具有非默认排序规则的索引对于涉及使用非默认排序规则的表达式的查询可能很有用。 + + 将用于该索引的排序规则名称。默认情况下,索引使用被索引列声明的 + 排序规则,或者被索引表达式的结果排序规则。对于涉及使用非默认排序 + 规则表达式的查询,使用非默认排序规则的索引可能会很有用。 + opclass - 操作符类的名称。详细信息见下文。 + + 一个操作符类的名称。详见下文。 + ASC - 指定升序排序(这是默认值)。 + + 指定升序排序(默认)。 + @@ -182,14 +207,20 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] NULLS FIRST - 指定将空值排在非空值之前。当指定DESC时,这是默认值。 + + 指定把空值排序在非空值前面。在指定DESC时, + 这是默认行为。 + NULLS LAST - 指定将空值排在非空值之后。当未指定DESC时,这是默认值。 + + 指定把空值排序在非空值后面。在没有指定DESC时, + 这是默认行为。 + @@ -203,7 +234,11 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] tablespace_name - 要创建索引的表空间。如果未指定,则查询;对于临时表上的索引,则查询 + + 在其中创建索引的表空间。如果未指定,将查阅 + ;对于临时表上的索引,则查阅 + 。 + @@ -222,6 +257,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] 可选的WITH子句为索引指定存储参数。每一种 索引方法都有其各自允许的存储参数集合。 + B-树、hash、GiST 和 SP-GiST 索引方法都接受以下参数: @@ -234,7 +270,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - B-树索引还接受以下参数: + GiST 索引还接受以下参数: @@ -247,7 +283,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - GiST 索引还接受以下参数: + GIN 索引接受不同的参数: @@ -274,7 +310,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - 为该索引覆盖的全局设置。 + 自定义参数。 该值以千字节为单位。 @@ -282,7 +318,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - BRIN 索引接受以下参数: + BRIN 索引接受不同的参数: @@ -310,8 +346,8 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] 并发构建索引 - index - building concurrently + 索引 + 并发构建 @@ -399,11 +435,21 @@ Indexes: 生成这些索引的统计信息。 - 对于大多数索引方法,创建索引的速度取决于的设置。较大的值会减少创建索引所需的时间,但前提是不能将它设得大于实际可用的内存量,否则机器会进入交换。 + + 对于大多数索引方法,索引的创建速度取决于 + 的设置。较大的值将会减少 + 索引创建所需的时间,当然不要把它设置得超过实际可用的内存量(那会迫使 + 机器进行交换)。 + 使用删除索引。 - 早期版本的PostgreSQL也有 R-tree 索引方法。由于它相对于 GiST 方法没有显著优势,该方法已被删除。如果指定USING rtreeCREATE INDEX会将其解释为USING gist,以便简化旧数据库向 GiST 的转换。 + + 早期版本的PostgreSQL还提供过一种 R-tree + 索引方法。该方法已经被移除,因为它相对于 GiST 方法并无明显优势。如果 + 指定了USING rtreeCREATE INDEX + 会将其解释为USING gist,以简化旧数据库向 GiST 的转换。 + @@ -454,7 +500,8 @@ CREATE INDEX gin_idx ON documents_table USING GIN (locations) WITH (fastupdate = - 要创建索引,索引列为 code,所在表为films,并将索引存放在表空间 indexspace: + 要在表films的列code上创建一个索引, + 并让该索引驻留在表空间indexspace中: CREATE INDEX code_idx ON films (code) TABLESPACE indexspace; diff --git a/zh/10/ref/create_language.sgml b/zh/10/ref/create_language.sgml index 80f66c53..64f6b37d 100644 --- a/zh/10/ref/create_language.sgml +++ b/zh/10/ref/create_language.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE LANGUAGE 7 - SQL - Language Statements + SQL - 语言语句 @@ -51,7 +51,7 @@ CREATE [ OR REPLACE ] [ TRUSTED ] [ PROCEDURAL ] LANGUAGE - 新过程语言的名称。该名称在数据库内必须唯一。 + 新过程语言的名称。该名称不能与数据库中其他语言的名称重复。 diff --git a/zh/10/ref/create_materialized_view.sgml b/zh/10/ref/create_materialized_view.sgml index 9069a8ab..a593dbd8 100644 --- a/zh/10/ref/create_materialized_view.sgml +++ b/zh/10/ref/create_materialized_view.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE MATERIALIZED VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/create_opclass.sgml b/zh/10/ref/create_opclass.sgml index effeede7..88dbc3a6 100644 --- a/zh/10/ref/create_opclass.sgml +++ b/zh/10/ref/create_opclass.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE OPERATOR CLASS 7 - SQL - Language Statements + SQL - 语言语句 @@ -34,7 +34,7 @@ CREATE OPERATOR CLASS name [ DEFAUL 描述 - CREATE OPERATOR CLASS创建一个新的操作符类。操作符类定义特定数据类型如何用于索引。它指定某些操作符为该数据类型和索引方法承担特定角色或策略。它还指定为索引列选择该操作符类时,索引方法要使用的支持过程。在创建操作符类之前,必须先定义它使用的所有操作符和函数。 + CREATE OPERATOR CLASS创建一个新的操作符类。操作符类定义特定数据类型如何用于索引。它指定某些操作符为该数据类型和索引方法承担特定角色或策略。它还指定为索引列选择该操作符类时,索引方法要使用的支持函数。在创建操作符类之前,必须先定义它使用的所有操作符和函数。 @@ -172,7 +172,7 @@ CREATE OPERATOR CLASS name [ DEFAUL support_number - 与操作符类关联的函数在索引方法中的支持过程编号。 + 与操作符类关联的函数在索引方法中的支持函数编号。 @@ -181,7 +181,7 @@ CREATE OPERATOR CLASS name [ DEFAUL function_name - 作为该操作符类的索引方法支持过程的函数名称(可带模式限定)。 + 作为该操作符类的索引方法支持函数的函数名称(可带模式限定)。 @@ -231,7 +231,7 @@ CREATE OPERATOR CLASS name [ DEFAUL - 在PostgreSQL 8.4 之前,OPERATOR子句可以包含RECHECK选项。现在不再支持它,因为索引操作符是否有损现在会在运行时动态确定。这使得系统可以高效处理操作符可能有损也可能无损的情况。 + 在PostgreSQL 8.4 之前,OPERATOR子句可以包含RECHECK选项。现在不再支持该选项,因为索引操作符是否有损会在运行时动态确定。这样可以高效处理操作符可能有损也可能无损的情况。 diff --git a/zh/10/ref/create_operator.sgml b/zh/10/ref/create_operator.sgml index 1dbeb278..acced1fa 100644 --- a/zh/10/ref/create_operator.sgml +++ b/zh/10/ref/create_operator.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE OPERATOR 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/create_opfamily.sgml b/zh/10/ref/create_opfamily.sgml index 7f42e055..1942faf9 100644 --- a/zh/10/ref/create_opfamily.sgml +++ b/zh/10/ref/create_opfamily.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE OPERATOR FAMILY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/create_policy.sgml b/zh/10/ref/create_policy.sgml index 81817d61..41b45ce7 100644 --- a/zh/10/ref/create_policy.sgml +++ b/zh/10/ref/create_policy.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE POLICY 7 - SQL - Language Statements + SQL - 语言语句 @@ -257,17 +257,17 @@ CREATE POLICY name ON 命令 - SELECT/ALL policy - INSERT/ALL policy - UPDATE/ALL policy - DELETE/ALL policy + SELECT/ALL策略 + INSERT/ALL策略 + UPDATE/ALL策略 + DELETE/ALL策略 - USING expression - WITH CHECK expression - USING expression - WITH CHECK expression - USING expression + USING 表达式 + WITH CHECK 表达式 + USING 表达式 + WITH CHECK 表达式 + USING 表达式 diff --git a/zh/10/ref/create_publication.sgml b/zh/10/ref/create_publication.sgml index 174c9420..1ca01e94 100644 --- a/zh/10/ref/create_publication.sgml +++ b/zh/10/ref/create_publication.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE PUBLICATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/create_role.sgml b/zh/10/ref/create_role.sgml index 9ff48ea7..230335b8 100644 --- a/zh/10/ref/create_role.sgml +++ b/zh/10/ref/create_role.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE ROLE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/create_rule.sgml b/zh/10/ref/create_rule.sgml index 0a16570f..82f3276e 100644 --- a/zh/10/ref/create_rule.sgml +++ b/zh/10/ref/create_rule.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE RULE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/create_schema.sgml b/zh/10/ref/create_schema.sgml index 6b2cd1aa..afac35cd 100644 --- a/zh/10/ref/create_schema.sgml +++ b/zh/10/ref/create_schema.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE SCHEMA 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/create_sequence.sgml b/zh/10/ref/create_sequence.sgml index f100be5d..7f868016 100644 --- a/zh/10/ref/create_sequence.sgml +++ b/zh/10/ref/create_sequence.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE SEQUENCE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/create_server.sgml b/zh/10/ref/create_server.sgml index 3af49798..ccadb029 100644 --- a/zh/10/ref/create_server.sgml +++ b/zh/10/ref/create_server.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE SERVER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/create_statistics.sgml b/zh/10/ref/create_statistics.sgml index 5e53270c..a242a4ad 100644 --- a/zh/10/ref/create_statistics.sgml +++ b/zh/10/ref/create_statistics.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE STATISTICS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/create_subscription.sgml b/zh/10/ref/create_subscription.sgml index a78572b1..62c5ac8e 100644 --- a/zh/10/ref/create_subscription.sgml +++ b/zh/10/ref/create_subscription.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE SUBSCRIPTION 7 - SQL - Language Statements + SQL - 语言语句 @@ -32,19 +32,18 @@ CREATE SUBSCRIPTION subscription_name描述 - CREATE SUBSCRIPTION添加一个新的逻辑复制订阅。 - 创建订阅的用户将成为该订阅的所有者。订阅名称必须与当前数据库中 - 任何现有订阅的名称不同。 + CREATE SUBSCRIPTION为当前数据库添加一个新订阅。 + 订阅名称必须与数据库中任何现有订阅的名称不同。 - 订阅表示与发布者的复制连接。因此,除了在本地系统目录中添加定义之外, - 该命令通常还会在发布者上创建一个复制槽。 + 订阅表示与发布者的复制连接。因此,该命令不仅会在本地系统目录中添加定义, + 还会在发布者上创建一个复制槽。 - 除非订阅初始即被禁用,否则在执行该命令所在事务提交时,会启动一个 - 逻辑复制工作进程为新订阅复制数据。 + 在执行该命令所在事务提交时,会启动一个逻辑复制工作进程, + 为新订阅复制数据。 diff --git a/zh/10/ref/create_table.sgml b/zh/10/ref/create_table.sgml index fdc988bf..d0ce82ce 100644 --- a/zh/10/ref/create_table.sgml +++ b/zh/10/ref/create_table.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TABLE 7 - SQL - Language Statements + SQL - 语言语句 @@ -113,7 +113,7 @@ FROM ( { numeric_literal | CREATE TABLE myschema.mytable ...),则表将在指定模式中创建。 否则,它将在当前模式中创建。临时表存在于一个特殊模式中,因此创建临时表时不能给出模式名。 - 表名必须与同一模式中任何其他关系(表、序列、索引、视图、物化视图或外部表)的名称不同。 + 表名必须与同一模式中任何其他表、序列、索引、视图或外部表的名称不同。 @@ -139,7 +139,7 @@ FROM ( { numeric_literal | - TEMPORARY or TEMP + TEMPORARYTEMP 如果指定该选项,表将创建为临时表。 @@ -153,7 +153,7 @@ FROM ( { numeric_literal | - 可以在 TEMPORARYTEMP 前写 GLOBALLOCAL。这在当前的 PostgreSQL 中没有区别,而且已废弃;见下文 。 + 可以在 TEMPORARYTEMP 前写 GLOBALLOCAL。这在当前的 PostgreSQL 中没有区别,而且已弃用;见下文 @@ -168,16 +168,20 @@ FROM ( { numeric_literal | - IF NOT EXISTS + IF NOT EXISTS - 如果已存在同名关系,则不抛出错误,而是发出通知。请注意,不能保证现有关系与原本要创建的关系有任何相似之处。 + + 如果已存在同名关系,则不抛出错误,而是发出一条提示。注意,这并不保证现有关系与本应创建出的关系有任何相似之处。 + table_name - 要创建的表的名称(可以带模式限定)。 + + 要创建的表名(可选地带模式限定)。 + @@ -238,41 +242,47 @@ FROM ( { numeric_literal | 还要注意,某些元素类型(如 timestamp)具有 - "infinity" 的概念,那只是另一种可存储的值。这不同于 + “无穷大” 的概念,那只是另一种可存储的值。这不同于 MINVALUEMAXVALUE,后两者并非可存储 的实际值,而只是表示值无界的方式。MAXVALUE 可以视为大于任何 - 其他值,包括 "infinity";MINVALUE 可以视为小于任何 - 其他值,包括 "minus infinity"。因此,范围 + 其他值,包括 “无穷大”;MINVALUE 可以视为小于任何 + 其他值,包括 “负无穷大”。因此,范围 FROM ('infinity') TO (MAXVALUE) 并不是空范围;它只允许存储 - 一个值 — "infinity"。 + 一个值 — “无穷大”。 分区必须具有与其所属分区表相同的列名和类型。如果父表指定了WITH OIDS,则所有分区都必须有 OID;父表的 OID 列会像其他列一样被所有分区继承。修改分区表的列名或类型,或者添加或删除 OID 列,都会自动传播到所有分区。每个分区都会自动继承CHECK约束,但单个分区可以指定额外的CHECK约束;如果额外约束与父表中约束的名称和条件相同,则会与父表约束合并。可以为每个分区分别指定默认值。但请注意,通过分区表插入元组时不会应用分区的默认值。 插入分区表的行会自动路由到正确的分区。如果不存在合适的分区,将发生错误。此外,如果由于新的分区键值,更新给定分区中的行需要将其移到另一个分区,也会发生错误。 - 通常会影响表及其所有继承子表的操作(例如 TRUNCATE)会级联到所有分区,但也可以在单个分区上执行。请注意,使用DROP TABLE删除分区需要对父表取得ACCESS EXCLUSIVE锁。 + TRUNCATE 等通常会影响一个表及其所有继承子表的操作,会级联到所有分区,但也可以在单个分区上执行。请注意,使用DROP TABLE删除分区需要在父表上获取ACCESS EXCLUSIVE锁。 column_name - 要在新表中创建的列的名称。 + + 要在新表中创建的列名。 + data_type - 列的数据类型。可以包含数组说明符。有关PostgreSQL支持的数据类型的更多信息,请参见 + + 列的数据类型。这可以包括数组说明符。有关 + PostgreSQL 支持的数据类型的更多信息,请参见 。 + COLLATE collation - COLLATE子句为该列分配排序规则(该列必须是支持排序规则的数据类型)。如果未指定,则使用列数据类型的默认排序规则。 + COLLATE子句为列指定排序规则(该列必须属于支持排序规则的数据类型)。如果未指定,则使用列数据类型的默认排序规则。 @@ -322,7 +332,11 @@ FROM ( { numeric_literal | 可选的PARTITION BY子句指定表的分区策略。这样创建的表称为分区表。括号中的列或表达式列表构成该表的分区键。使用范围分区时,分区键可以包含多个列或表达式(最多 32 个,但构建PostgreSQL时可以更改此限制);但对于列表分区,分区键必须由单个列或表达式组成。如果创建分区表时未指定 B-树 操作符类,则使用该数据类型的默认 B-树 操作符类。如果不存在,将报告错误。 - 分区表被划分为子表(称为分区),这些子表使用单独的CREATE TABLE命令创建。分区表本身为空。插入该表的数据行会根据分区键中列或表达式的值路由到某个分区。如果没有现有分区与新行中的值匹配,将报告错误。 + + 分区表被划分为多个子表(称为分区),它们使用单独的 CREATE TABLE 命令创建。 + 分区表本身为空。插入到该表的数据行会根据分区键中列或表达式的值被路由到相应分区。 + 如果没有现有分区与新行中的值匹配,就会报错。 + 分区表不支持UNIQUEPRIMARY KEYEXCLUDEFOREIGN KEY约束;不过,可以在单个分区上定义这些约束。 @@ -343,10 +357,10 @@ FROM ( { numeric_literal | 非空约束始终会复制到新表。只有指定INCLUDING CONSTRAINTS时,才会复制CHECK约束。列约束和表约束之间不作区分。 指定INCLUDING STATISTICS时,扩展统计信息会复制到新表。 只有指定INCLUDING INDEXES时,才会在新表上创建原表的索引、PRIMARY KEYUNIQUEEXCLUDE约束。新索引和约束的名称按照默认规则选择,与原名称无关。(此行为可以避免新索引可能发生名称重复错误。) - 只有指定INCLUDING STORAGE时,才会复制所复制列定义的STORAGE设置。默认行为是不包含STORAGE设置,因此新表中的所复制列将具有特定于类型的默认设置。有关STORAGE设置的更多信息,请参见 - 只有指定INCLUDING COMMENTS时,才会复制所复制列、约束和索引的注释。默认行为是不包含注释,因此新表中的所复制列和约束没有注释。 - INCLUDING ALLINCLUDING COMMENTS INCLUDING CONSTRAINTS INCLUDING DEFAULTS INCLUDING IDENTITY INCLUDING INDEXES INCLUDING STATISTICS INCLUDING STORAGE的缩写形式。 - 请注意,与INHERITS不同,LIKE复制的列和约束不会与同名的列和约束合并。如果在显式指定或另一个LIKE子句中指定了相同的名称,则会发出错误信号。 + 只有指定INCLUDING STORAGE时,才会复制所复制列定义的STORAGE设置。默认行为是不包含STORAGE设置,因此新表中复制的列使用其类型特定的默认设置。有关STORAGE设置的更多信息,请参见 + 只有指定INCLUDING COMMENTS时,才会复制所复制列、约束和索引的注释。默认行为是不包含注释,因此新表中复制的列和约束没有注释。 + INCLUDING ALLINCLUDING COMMENTS INCLUDING CONSTRAINTS INCLUDING DEFAULTS INCLUDING IDENTITY INCLUDING INDEXES INCLUDING STATISTICS INCLUDING STORAGE的简写形式。 + 请注意,与INHERITS不同,LIKE复制的列和约束不会与同名的列和约束合并。如果显式指定了相同的名称,或在另一个LIKE子句中指定了相同的名称,则会报错。 LIKE 子句也可用于从视图、外部表或复合类型复制列定义。不适用的选项(例如从视图复制 INCLUDING INDEXES)会被忽略。 @@ -364,9 +378,11 @@ FROM ( { numeric_literal | - NOT NULL + NOT NULL - 不允许该列包含空值。 + + 该列不允许包含空值。 + @@ -397,7 +413,7 @@ FROM ( { numeric_literal | - 一个被标记为NO INHERIT的约束将不会传播到子表。 + 标记为 NO INHERIT 的约束不会传播到子表。 @@ -410,7 +426,7 @@ FROM ( { numeric_literal | DEFAULT default_expr - DEFAULT子句为其列定义所在的列分配默认数据值。该值可以是任何不含变量的表达式(不允许子查询和对当前表中其他列的交叉引用)。默认表达式的数据类型必须与列的数据类型匹配。 + DEFAULT子句为其所在列定义的列指定默认数据值。该值可以是任何不含变量的表达式(不允许子查询,也不允许交叉引用当前表中的其他列)。默认表达式的数据类型必须与该列的数据类型匹配。 默认值表达式会用于任何未为该列指定值的插入操作。如果一列没有默认值,则默认值为 null。 @@ -427,9 +443,15 @@ FROM ( { numeric_literal | NOT NULL 约束。 - ALWAYSBY DEFAULT子句决定在INSERT语句中,序列值相对于用户指定值的优先级。如果指定ALWAYS,只有在INSERT语句指定OVERRIDING SYSTEM VALUE时才接受用户指定值。如果指定BY DEFAULT,则用户指定值优先。详情请参见。(在COPY命令中,无论此设置如何,始终使用用户指定的值。) + + ALWAYSBY DEFAULT子句决定在INSERT语句中序列值与用户指定值的优先关系。如果选择了 ALWAYS,则仅当 + INSERT 语句指定 OVERRIDING SYSTEM VALUE 时 + 才接受用户指定的值。如果选择了 BY DEFAULT,则用户指定的值优先。 + 有关详细信息,请参阅 。(在 COPY 命令中, + 无论此设置如何,始终使用用户指定的值。) + - 可选的sequence_options子句可用于覆盖序列的选项。详情请参见 + 可选的sequence_options子句可用于覆盖序列的选项。详情见 @@ -438,11 +460,18 @@ FROM ( { numeric_literal | UNIQUE ( column_name [, ... ] )(表约束) - UNIQUE约束指定表中的一组一个或多个列只能包含唯一值。唯一表约束的行为与唯一列约束相同,另外还可以跨越多列。因此,该约束强制任意两行至少在这些列中的一列上有所不同。 + + UNIQUE 约束指定表中一列或多列组成的一组只能包含唯一值。 + 表级唯一约束的行为与列级唯一约束相同,只是它还能跨越多列。因此,该约束 + 要求任意两行在这些列中至少有一列不同。 + - 就唯一约束而言,空值不被视为相等。 + 对于唯一约束,空值不被视为相等。 - 对于唯一约束,每个约束都应命名一组列,该列组不同于为该表定义的任何其他唯一约束或主键约束所命名的列组。(否则,冗余的唯一约束将被丢弃。) + + 每个唯一约束都应引用一组列,这组列应不同于该表上任何其他唯一约束或 + 主键约束所引用的列集合。(否则,冗余的唯一约束将被丢弃。) + @@ -468,26 +497,40 @@ FROM ( { numeric_literal | - 添加PRIMARY KEY约束会自动在约束所使用的列或列组上创建唯一的 B-树 索引。 + + 添加 PRIMARY KEY 约束会自动在约束所用的列或列组上创建 + 唯一 B-树索引。 EXCLUDE [ USING index_method ] ( exclude_element WITH operator [, ... ] ) index_parameters [ WHERE ( predicate ) ] - EXCLUDE子句定义排他约束,保证任意两行在指定列或表达式上使用指定操作符进行比较时,这些比较不会全部返回TRUE。如果所有指定操作符都测试相等,这就等同于UNIQUE约束,不过普通唯一约束会更快。但是,排他约束可以指定比简单相等更一般的约束。例如,可以使用&&操作符指定表中任意两行都不包含重叠圆(参见)。 + + EXCLUDE 子句定义一个排他约束。它保证如果任意两行在 + 指定列或表达式上使用指定操作符进行比较,这些比较不会全部返回 + TRUE。如果所有指定操作符都测试相等,这就等价于 + UNIQUE 约束,尽管普通唯一约束会更快。不过,排他约束可 + 以指定比简单相等更一般的约束。例如,你可以通过使用 + && 操作符来指定一个约束,使表中不存在两个包含重 + 叠圆的行(见 )。 + - 排他约束使用索引实现,因此对于索引访问方法index_method,每个指定操作符都必须与适当的操作符类关联(参见)。操作符必须是可交换的。每个exclude_element还可以选择指定操作符类和/或排序选项;这些选项在下有完整说明。 + 排他约束通过索引实现,因此每个指定的操作符都必须与索引访问方法index_method的适当操作符类关联(见)。这些操作符必须满足交换律。每个exclude_element都可以选择指定操作符类和/或排序选项;详见 访问方法必须支持 amgettuple(见 );目前这意味着不能使用 GIN。 虽然允许,但在排他约束上使用 B-树或 hash 索引意义不大,因为它们做不到 - 比普通唯一约束更好的事情。因此,实践中访问方法几乎总会是 + 比普通唯一约束更好的事情。因此,实践中访问方法总是 GiSTSP-GiST - predicate允许你指定表的一个子集上的排他约束;内部会创建一个部分索引。请注意,谓词周围必须有括号。 + + predicate 允许你只在表的一个 + 子集上指定排他约束;在内部,这会创建一个部分索引。注意, + predicate 周围的圆括号是必需的。 + @@ -499,27 +542,39 @@ FROM ( { numeric_literal | 这些子句指定外键约束,要求新表的一个或多个列组成的列组只能包含与被引用表某一行的被引用列值匹配的值。如果省略refcolumn列表,则使用reftable的主键。被引用列必须是被引用表中不可延迟的唯一约束或主键约束的列。用户必须拥有被引用表的REFERENCES权限(可以是整个表,也可以是特定的被引用列)。请注意,不能在临时表和永久表之间定义外键约束。 - 插入引用列中的值会使用给定匹配类型与被引用表及被引用列中的值进行匹配。有三种匹配类型:MATCH FULLMATCH PARTIALMATCH SIMPLE(默认)。MATCH FULL不允许多列外键中的某一列为空,除非所有外键列都为空;如果全部为空,则不要求该行在被引用表中存在匹配项。MATCH SIMPLE允许任意外键列为空;如果其中任意列为空,则不要求该行在被引用表中存在匹配项。MATCH PARTIAL尚未实现。(当然,可以对引用列应用NOT NULL约束,以防止出现这些情况。) + + 插入到引用列中的值会按照给定的匹配类型,与被引用表及其被引用列中的值进 + 行匹配。共有三种匹配类型:MATCH FULL、 + MATCH PARTIALMATCH SIMPLE + (默认值)。MATCH FULL 不允许多列外键中的某一列为 + 空,除非所有外键列都为空;如果它们都为空,则不要求该行在被引用表中有匹 + 配行。MATCH SIMPLE 允许任意外键列为空;如果其中任何一 + 列为空,则不要求该行在被引用表中有匹配行。 + MATCH PARTIAL 目前尚未实现。(当然,可以对引用列应用 + NOT NULL 约束,以防止出现这些情况。) + - 此外,当被引用列中的数据发生更改时,还会对该表列中的数据执行某些操作。该ON DELETE子句指定在被引用表中的某一被引用行被删除时要执行的操作。同样,ON UPDATE子句指定在被引用表中的被引用列更新为新值时要执行的操作。如果更新了该行,但被引用列实际上未更改,则不执行任何操作。除NO ACTION检查之外的引用动作都不能延迟,即使约束被声明为可延迟。每个子句有以下可能的操作: + 此外,当被引用列中的数据发生变化时,会对本表列中的数据执行某些操作。ON DELETE子句指定删除被引用表中的被引用行时要执行的操作。同样,ON UPDATE子句指定将被引用表中的被引用列更新为新值时要执行的操作。如果行被更新,但被引用列实际上没有变化,则不执行任何操作。除NO ACTION检查以外的引用操作都不能延迟,即使该约束声明为可延迟也是如此。每个子句可以指定以下操作: NO ACTION - 产生一个错误,指出删除或更新将导致外键约束冲突。如果约束是延迟的,并且在约束检查时仍存在任何引用行,则会产生此错误。这是默认操作。 + 产生错误,指出删除或更新会违反外键约束。如果该约束被延迟,则会在约束检查时仍存在引用行的情况下产生这个错误。这是默认操作。 RESTRICT - 产生一个错误,指出删除或更新将导致外键约束冲突。这与NO ACTION相同,只是检查不可延迟。 + 产生错误,指出删除或更新会违反外键约束。这与NO ACTION相同,但检查不能延迟。 CASCADE - 分别删除引用已删除行的所有行,或将引用列中的值更新为被引用列的新值。 + + 分别删除任何引用已删除行的行,或将引用列的值更新为被引用列的新值。 + @@ -533,13 +588,13 @@ FROM ( { numeric_literal | SET DEFAULT - 将引用列设置为其默认值。(如果默认值不为空,则被引用表中必须存在与默认值匹配的行,否则操作将失败。) + 将引用列设置为其默认值。(如果默认值不为空,则被引用表中必须存在与这些默认值匹配的行,否则操作会失败。) - 如果被引用列经常更改,最好为引用列添加索引,以便更高效地执行与外键约束关联的引用操作。 + 如果被引用列经常变化,可以考虑在引用列上添加索引,使与外键约束关联的引用操作能够更高效地执行。 @@ -562,26 +617,30 @@ FROM ( { numeric_literal | WITH ( storage_parameter [= value] [, ... ] ) - 此子句为表或索引指定可选存储参数;有关更多信息,请参见。表的WITH子句还可以包含OIDS=TRUE(或仅包含OIDS),以指定应为新表的行分配 OID(对象标识符),或者包含OIDS=FALSE,以指定不应为这些行分配 OID。如果未指定OIDS,默认设置取决于配置参数。(如果新表继承自任何具有 OID 的表,即使命令写明OIDS=FALSE,也会强制使用OIDS=TRUE。) + 该子句为表或索引指定可选的存储参数;详情见。表的WITH子句还可以包含OIDS=TRUE(或仅写OIDS),以指定为新表的行分配 OID(对象标识符);也可以包含OIDS=FALSE,以指定行不应具有 OID。如果未指定OIDS,默认设置取决于配置参数。(如果新表继承自任何具有 OID 的表,则会强制使用OIDS=TRUE,即使命令指定了OIDS=FALSE也是如此。) - 如果指定或隐含OIDS=FALSE,新表不会存储 OID,并且插入其中的行不会被分配 OID。通常认为这样做是值得的,因为它会减少 OID 消耗,从而推迟 32 位 OID 计数器回绕。一旦计数器回绕,就不能再假定 OID 唯一,这会使它们的用处大为降低。此外,从表中排除 OID 会使在磁盘上存储表所需的空间每行减少 4 字节(在大多数机器上),从而略微提高性能。 + 如果显式或隐式指定了OIDS=FALSE,新表将不存储 OID,也不会为插入其中的行分配 OID。通常认为这样做是值得的,因为它会减少 OID 的消耗,从而推迟 32 位 OID 计数器回卷。一旦计数器回卷,就不能再假定 OID 是唯一的,这会大大降低它们的用途。此外,不在表中包含 OID 可以减少在磁盘上存储该表所需的空间,在大多数机器上每行可减少 4 字节,从而略微提高性能。 - 创建表后,要从表中删除 OID,请使用 + 要在表创建后移除其 OID,请使用 - WITH OIDS + WITH OIDS WITHOUT OIDS - 这些是分别等同于WITH (OIDS)WITH (OIDS=FALSE)的过时语法。如果希望同时指定OIDS设置和存储参数,则必须使用WITH ( ... )语法;见上文。 + 这些是过时的语法,分别等价于WITH (OIDS)WITH (OIDS=FALSE)。如果要同时指定OIDS设置和存储参数,必须使用WITH ( ... )语法;见上文。 ON COMMIT - 临时表在事务块结束时的行为可以使用以下选项控制:ON COMMIT。三个选项是: + + 可以使用 ON COMMIT 控制临时表在事务块结束时的行为。三种 + 选项如下: + + PRESERVE ROWS @@ -594,7 +653,7 @@ FROM ( { numeric_literal | DELETE ROWS - 临时表中的所有行将在每个事务块结束时删除。本质上,每次提交时都会执行一次。在分区表上使用时,不会级联到其分区。 + 临时表中的所有行都会在每个事务块结束时删除。实际上,每次提交时都会自动执行一次。用于分区表时,这个操作不会级联到其分区。 @@ -637,7 +696,7 @@ FROM ( { numeric_literal | 存储参数 - storage parameters + 存储参数 WITH子句可以为表以及与UNIQUEPRIMARY KEYEXCLUDE约束关联的索引指定存储参数。索引的存储参数记载于。当前可用于表的存储参数列在下面。对于其中许多参数,如下所示,还存在一个同名但带有toast.前缀的附加参数,用于控制表的二级TOAST表(如果有)的行为(有关 TOAST 的更多信息请参见)。如果设置了表参数值而未设置等效的toast.参数,则 TOAST 表会使用表参数的值。不支持为分区表指定这些参数,但可以为单独的叶分区指定。 @@ -645,21 +704,21 @@ FROM ( { numeric_literal | - fillfactor (integer) + fillfactor (integer) 表的填充因子是 10 到 100 之间的百分比。100(完全填充)是默认值。指定较小的填充因子时,INSERT操作只将表页填充到指定百分比;每页的剩余空间保留用于更新该页上的行。这样,UPDATE就有机会将行的更新副本放在与原行相同的页面上,这比放在不同页面上更高效。对于从不更新其条目的表,完全填充是最佳选择;但对于频繁更新的表,适合使用较小的填充因子。不能为 TOAST 表设置此参数。 - parallel_workers (integer) + parallel_workers (integer) - 这设置用于协助并行扫描该表的工作者数量。如果未设置,系统将根据关系大小确定一个值。规划器选择的实际工作者数量可能更少,例如由于的设置。 + 这设置用于协助并行扫描该表的工作进程数量。如果未设置,系统将根据关系大小确定一个值。规划器选择的实际工作进程数量可能更少,例如由于的设置。 - autovacuum_enabled, toast.autovacuum_enabled (boolean) + autovacuum_enabled, toast.autovacuum_enabled (boolean) @@ -677,7 +736,7 @@ FROM ( { numeric_literal | - autovacuum_vacuum_threshold, toast.autovacuum_vacuum_threshold (integer) + autovacuum_vacuum_threshold, toast.autovacuum_vacuum_threshold (integer) @@ -687,7 +746,7 @@ FROM ( { numeric_literal | - autovacuum_vacuum_scale_factor, toast.autovacuum_vacuum_scale_factor (floating point) + autovacuum_vacuum_scale_factor, toast.autovacuum_vacuum_scale_factor (floating point) @@ -697,7 +756,7 @@ FROM ( { numeric_literal | - autovacuum_analyze_threshold (integer) + autovacuum_analyze_threshold (integer) @@ -707,7 +766,7 @@ FROM ( { numeric_literal | - autovacuum_analyze_scale_factor (floating point) + autovacuum_analyze_scale_factor (floating point) @@ -717,7 +776,7 @@ FROM ( { numeric_literal | - autovacuum_vacuum_cost_delay, toast.autovacuum_vacuum_cost_delay (integer) + autovacuum_vacuum_cost_delay, toast.autovacuum_vacuum_cost_delay (integer) @@ -727,7 +786,7 @@ FROM ( { numeric_literal | - autovacuum_vacuum_cost_limit, toast.autovacuum_vacuum_cost_limit (integer) + autovacuum_vacuum_cost_limit, toast.autovacuum_vacuum_cost_limit (integer) @@ -737,7 +796,7 @@ FROM ( { numeric_literal | - autovacuum_freeze_min_age, toast.autovacuum_freeze_min_age (integer) + autovacuum_freeze_min_age, toast.autovacuum_freeze_min_age (integer) @@ -749,7 +808,7 @@ FROM ( { numeric_literal | - autovacuum_freeze_max_age, toast.autovacuum_freeze_max_age (integer) + autovacuum_freeze_max_age, toast.autovacuum_freeze_max_age (integer) @@ -835,14 +894,14 @@ FROM ( { numeric_literal | 注解 - 不建议在新应用中使用 OID:在可能的情况下,最好使用标识列或其他序列生成器作为表的主键。不过,如果应用确实使用 OID 来标识表中的特定行,则建议在该表的oid列上创建唯一约束,以确保即使计数器回绕后,表中的 OID 仍确实能唯一标识行。避免假设不同表之间的 OID 是唯一的;如果需要数据库范围内的唯一标识符,请使用tableoid与行 OID 的组合。 + 不建议在新应用中使用 OID:在可能的情况下,优先使用标识列或其他序列生成器作为表的主键。不过,如果应用确实使用 OID 来标识表中的特定行,建议在该表的oid列上创建唯一约束,以确保即使计数器回卷,表中的 OID 也确实能唯一标识行。不要假定 OID 在不同表之间唯一;如果需要数据库范围的唯一标识符,请组合使用tableoid和行 OID。 - 不建议对没有主键的表使用OIDS=FALSE,因为没有 OID 或唯一数据键时,很难标识特定行。 + 对于没有主键的表,不建议使用OIDS=FALSE,因为既没有 OID,也没有唯一数据键时,很难标识特定行。 - PostgreSQL为每一个唯一约束和主键约束创建一个索引来强制唯一性。因此,没有必要显式地为主键列创建一个索引(详见)。 + PostgreSQL为每一个唯一约束和主键约束自动创建一个索引来强制唯一性。因此,没有必要显式地为主键列创建一个索引(详见)。 @@ -1185,7 +1244,7 @@ CREATE TABLE cities_ab_10000_to_100000 - 非延迟唯一约束 + 非延迟唯一性约束 UNIQUEPRIMARY KEY 约束不可延 @@ -1225,9 +1284,9 @@ CREATE TABLE cities_ab_10000_to_100000 NULL 约束(实际上并不是约束)是 - PostgreSQL 对 SQL 标准的扩展;它也被其他一些数 - 据库系统采纳,以便兼容(以及与对称的 NOT NULL 约束保持一 - 致)。由于它本来就是任意列的默认值,所以它的存在只是噪声。 + PostgreSQL 对 SQL 标准的扩展;提供它是为了 + 与其他一些数据库系统兼容(以及与 NOT NULL 约束保持 + 对称)。由于它本来就是任意列的默认情况,所以它的存在只是噪声。 @@ -1246,7 +1305,7 @@ CREATE TABLE cities_ab_10000_to_100000 PostgreSQL 允许创建没有列的表(例如 CREATE TABLE foo();)。这是对 SQL 标准的扩展,标准不允许 - 零列表。零列表本身并不十分有用,但若禁止它们,就会让 + 零列的表。零列的表本身并不十分有用,但若禁止它们,就会让 ALTER TABLE DROP COLUMN 出现奇怪的特殊情况,因此忽略这 一规范限制看起来更整洁。 @@ -1259,7 +1318,7 @@ CREATE TABLE cities_ab_10000_to_100000 PostgreSQL 允许一个表拥有多个标识列。 该标准指定一个表最多只能有一个标识列。 - 这主要是为了给模式更改或迁移提供更大的灵活性。 + 放宽这一限制主要是为了给模式更改或迁移提供更大的灵活性。 请注意,INSERT 命令仅支持一个适用于整个语句的覆盖子 句,因此对行为不同的多个标识列支持并不好。 @@ -1280,7 +1339,10 @@ CREATE TABLE cities_ab_10000_to_100000 <literal>WITH</literal> 子句 - WITH子句是PostgreSQL的扩展;存储参数和 OID 都不属于标准。 + + WITH 子句是 PostgreSQL 的扩 + 展;存储参数和 OID 都不属于标准内容。 + @@ -1297,7 +1359,11 @@ CREATE TABLE cities_ab_10000_to_100000 类型化表 - 类型化表实现 SQL 标准的一个子集。根据该标准,类型化表除了具有与底层复合类型对应的列外,还具有一个作为自引用列的其他列。PostgreSQL 不显式支持这些自引用列,但可以使用 OID 功能实现相同效果。 + + 类型化表实现了 SQL 标准的一个子集。按照标准,类型化表除了具有与底层复合 + 类型相对应的列之外,还应有一个额外的自引用列。 + PostgreSQL 不显式支持自引用列,但使用 OID 功能可以达到相同的效果。 + diff --git a/zh/10/ref/create_table_as.sgml b/zh/10/ref/create_table_as.sgml index 9a51d7a0..c2172ab0 100644 --- a/zh/10/ref/create_table_as.sgml +++ b/zh/10/ref/create_table_as.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TABLE AS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/create_tablespace.sgml b/zh/10/ref/create_tablespace.sgml index 2a492e17..89a08e7b 100644 --- a/zh/10/ref/create_tablespace.sgml +++ b/zh/10/ref/create_tablespace.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TABLESPACE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/create_transform.sgml b/zh/10/ref/create_transform.sgml index cdb6bf68..181fc805 100644 --- a/zh/10/ref/create_transform.sgml +++ b/zh/10/ref/create_transform.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TRANSFORM 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/create_trigger.sgml b/zh/10/ref/create_trigger.sgml index 52df6e03..4170efa1 100644 --- a/zh/10/ref/create_trigger.sgml +++ b/zh/10/ref/create_trigger.sgml @@ -10,13 +10,13 @@ PostgreSQL documentation 过渡表 - ephemeral named relation + 临时命名关系 CREATE TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -55,7 +55,7 @@ CREATE [ CONSTRAINT ] TRIGGER name UPDATEDELETE之前); 也可以在该操作完成之后引发(即在检查约束以及完成 INSERTUPDATE或 - DELETE之后);或者改为执行该操作 + DELETE之后);或者取代该操作执行 (用于视图上的插入、更新或删除)。如果触发器在事件之前引发,或者改为取代该事件执行, 则它可以跳过对当前行的操作,或者修改待插入的行 (仅适用于INSERTUPDATE操作)。 @@ -111,7 +111,7 @@ CREATE [ CONSTRAINT ] TRIGGER name TRUNCATE - 表和外部表 + @@ -124,7 +124,7 @@ CREATE [ CONSTRAINT ] TRIGGER name TRUNCATE - 表和外部表 + @@ -154,7 +154,7 @@ CREATE [ CONSTRAINT ] TRIGGER name 如果针对同一事件定义了多个同类触发器,它们将按名称的字母顺序引发。 - 指定CONSTRAINT选项时,此命令会创建约束触发器。这与普通触发器相同,只是可以使用调整触发器触发的时间。约束触发器必须是普通表(不是外部表)上的AFTER ROW触发器。它们可以在导致触发事件的语句结束时触发,也可以在包含该语句的事务结束时触发;后一种情况下称为延迟。也可以使用SET CONSTRAINTS强制挂起的延迟触发器立即触发。约束触发器应在其实现的约束被违反时引发异常。 + 指定CONSTRAINT选项时,此命令会创建约束触发器。这与普通触发器相同,只是可以使用调整触发器触发的时间。约束触发器必须是普通表(不是外部表)上的AFTER ROW触发器。它们可以在导致触发事件的语句结束时触发,也可以在包含该语句的事务结束时触发;后一种情况下称为延迟。也可以使用SET CONSTRAINTS强制尚待执行的延迟触发器立即触发。约束触发器应在其实现的约束被违反时引发异常。 REFERENCING选项允许收集过渡关系,即包含当前 SQL 语句插入、删除或修改的全部行的行集合。该特性使触发器能够看到该语句所做更改的整体视图,而不是一次只看到一行。该选项仅允许用于不是约束触发器的AFTER触发器;如果触发器是UPDATE触发器,则不得指定column_name列表。OLD TABLE最多只能指定一次,并且只能用于可能在UPDATEDELETE上触发的触发器;它会创建一个过渡关系,其中包含该语句更新或删除的全部行的前映像。同样,NEW TABLE最多只能指定一次,并且只能用于可能在UPDATEINSERT上触发的触发器;它会创建一个过渡关系,其中包含该语句更新或插入的全部行的后映像 @@ -208,9 +208,13 @@ CREATE [ CONSTRAINT ] TRIGGER name 除请求过渡关系的情况外,可以使用OR指定多个事件。 - 对于UPDATE事件,可以使用以下语法指定列列表: + + 对于 UPDATE 事件,可以使用以下语法指定列列表: + UPDATE OF column_name1 [, column_name2 ... ] -只有列出的列中至少有一列被指定为UPDATE命令的目标时,触发器才会触发。 + + 只有当列出的列中至少有一列被列为 UPDATE 命令的目标时,触发器才会触发。 + INSTEAD OF UPDATE 事件不允许指定列列表。 diff --git a/zh/10/ref/create_tsconfig.sgml b/zh/10/ref/create_tsconfig.sgml index 671aaee3..caf8d05b 100644 --- a/zh/10/ref/create_tsconfig.sgml +++ b/zh/10/ref/create_tsconfig.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TEXT SEARCH CONFIGURATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/create_tsdictionary.sgml b/zh/10/ref/create_tsdictionary.sgml index e16248d9..ad77cd39 100644 --- a/zh/10/ref/create_tsdictionary.sgml +++ b/zh/10/ref/create_tsdictionary.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TEXT SEARCH DICTIONARY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/create_tsparser.sgml b/zh/10/ref/create_tsparser.sgml index 494798ab..d8ebb16a 100644 --- a/zh/10/ref/create_tsparser.sgml +++ b/zh/10/ref/create_tsparser.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TEXT SEARCH PARSER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/create_tstemplate.sgml b/zh/10/ref/create_tstemplate.sgml index 39a055c8..f6d2128f 100644 --- a/zh/10/ref/create_tstemplate.sgml +++ b/zh/10/ref/create_tstemplate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TEXT SEARCH TEMPLATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/create_type.sgml b/zh/10/ref/create_type.sgml index ac6243c0..0b4125c3 100644 --- a/zh/10/ref/create_type.sgml +++ b/zh/10/ref/create_type.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TYPE 7 - SQL - Language Statements + SQL - 语言语句 @@ -91,7 +91,7 @@ CREATE TYPE name 复合类型 - 第一种形式的CREATE TYPE创建复合类型。组合 + 第一种形式的CREATE TYPE创建复合类型。复合 类型由属性名和数据类型列表指定。如果某个属性的数据类型支持排序规 则,还可以指定该属性的排序规则。复合类型本质上与表的行类型相同, 但如果目的只是定义一种类型,使用CREATE TYPE @@ -280,7 +280,7 @@ CREATE TYPE name 数才知道,但仍有若干内部表示属性必须向 PostgreSQL声明。其中最重要的是 internallength。 - 基础数据类型可以是定长的,此时internallength为正整数;也可 以是变长的,此时将internallength设为 @@ -384,7 +384,7 @@ CREATE TYPE name collatable为真,则 该类型的列定义和表达式可以通过COLLATE子句携 带排序规则信息。是否实际使用这些排序规则信息取决于操作该类型的函 - 数实现;仅仅把类型标记为 collatable 并不会自动实现这一点。 + 数实现;仅仅把类型标记为支持排序规则并不会自动实现这一点。 @@ -743,7 +743,7 @@ CREATE TYPE name 以这种方式创建 shell 类型。 - PostgreSQL 7.3 以前的版本中,通常完全不创建壳类型,而是将函数中对类型名的前向引用替换为占位伪类型opaque。在 7.3 以前,cstring参数和结果也必须声明为opaque。为了支持载入旧转储文件,CREATE TYPE会接受使用opaque声明的 I/O 函数,但会发出通知,并修改函数声明以使用正确的类型。 + PostgreSQL 7.3 以前的版本中,通常完全不创建 shell 类型,而是将函数中对类型名的前向引用替换为占位伪类型opaque。在 7.3 以前,cstring参数和结果也必须声明为opaque。为了支持载入旧转储文件,CREATE TYPE会接受使用opaque声明的 I/O 函数,但会发出通知,并修改函数声明以使用正确的类型。 @@ -783,7 +783,7 @@ CREATE TYPE float8_range AS RANGE (subtype = float8, subtype_diff = float8mi); - 这个示例创建基础数据类型box,然后在表定义中使用它: + 这个示例创建基础类型box,然后在表定义中使用它: CREATE TYPE box; diff --git a/zh/10/ref/create_user.sgml b/zh/10/ref/create_user.sgml index aff1f9e3..8ce7c0a0 100644 --- a/zh/10/ref/create_user.sgml +++ b/zh/10/ref/create_user.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE USER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/create_user_mapping.sgml b/zh/10/ref/create_user_mapping.sgml index a8ef1c03..d81c0db7 100644 --- a/zh/10/ref/create_user_mapping.sgml +++ b/zh/10/ref/create_user_mapping.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE USER MAPPING 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/create_view.sgml b/zh/10/ref/create_view.sgml index ba296b2f..17fffe75 100644 --- a/zh/10/ref/create_view.sgml +++ b/zh/10/ref/create_view.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/createdb.sgml b/zh/10/ref/createdb.sgml index 15ceea7c..746b8166 100644 --- a/zh/10/ref/createdb.sgml +++ b/zh/10/ref/createdb.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation createdb 1 - Application + 应用程序 diff --git a/zh/10/ref/createuser.sgml b/zh/10/ref/createuser.sgml index a3b26579..dab53df8 100644 --- a/zh/10/ref/createuser.sgml +++ b/zh/10/ref/createuser.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation createuser 1 - Application + 应用程序 @@ -111,13 +111,10 @@ PostgreSQL documentation - (已废弃) + - - 指定新角色应自动成为指定现有角色的成员。 - 可以通过写多个开关来指定多个现有角色。 - + 指定此角色应立即作为新成员加入的现有角色。可以使用多个开关,指定此角色要加入的多个角色。 @@ -263,7 +260,7 @@ PostgreSQL documentation 新用户将不具有REPLICATION权限,关于该权限的更完整说明见。这是默认设置。 + linkend="sql-createrole">。 diff --git a/zh/10/ref/deallocate.sgml b/zh/10/ref/deallocate.sgml index e9bbb7be..462e51b4 100644 --- a/zh/10/ref/deallocate.sgml +++ b/zh/10/ref/deallocate.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation DEALLOCATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/declare.sgml b/zh/10/ref/declare.sgml index e0a61c47..7087c7d8 100644 --- a/zh/10/ref/declare.sgml +++ b/zh/10/ref/declare.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation DECLARE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/delete.sgml b/zh/10/ref/delete.sgml index b6b27874..63dc323c 100644 --- a/zh/10/ref/delete.sgml +++ b/zh/10/ref/delete.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DELETE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/discard.sgml b/zh/10/ref/discard.sgml index 02fece75..63c210bc 100644 --- a/zh/10/ref/discard.sgml +++ b/zh/10/ref/discard.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DISCARD 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/do.sgml b/zh/10/ref/do.sgml index ac3c0d16..28b0592e 100644 --- a/zh/10/ref/do.sgml +++ b/zh/10/ref/do.sgml @@ -15,7 +15,7 @@ PostgreSQL documentation DO 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/drop_access_method.sgml b/zh/10/ref/drop_access_method.sgml index 82d3621b..3cf87b0d 100644 --- a/zh/10/ref/drop_access_method.sgml +++ b/zh/10/ref/drop_access_method.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP ACCESS METHOD 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/drop_aggregate.sgml b/zh/10/ref/drop_aggregate.sgml index b9c15b35..38563257 100644 --- a/zh/10/ref/drop_aggregate.sgml +++ b/zh/10/ref/drop_aggregate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP AGGREGATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/drop_cast.sgml b/zh/10/ref/drop_cast.sgml index 0b719b92..877ede67 100644 --- a/zh/10/ref/drop_cast.sgml +++ b/zh/10/ref/drop_cast.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP CAST 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/drop_collation.sgml b/zh/10/ref/drop_collation.sgml index 134f5696..83f1144c 100644 --- a/zh/10/ref/drop_collation.sgml +++ b/zh/10/ref/drop_collation.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP COLLATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/drop_conversion.sgml b/zh/10/ref/drop_conversion.sgml index 946fc7fe..1a1d2d2c 100644 --- a/zh/10/ref/drop_conversion.sgml +++ b/zh/10/ref/drop_conversion.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP CONVERSION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/drop_database.sgml b/zh/10/ref/drop_database.sgml index 2c031c54..acb5254c 100644 --- a/zh/10/ref/drop_database.sgml +++ b/zh/10/ref/drop_database.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP DATABASE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/drop_domain.sgml b/zh/10/ref/drop_domain.sgml index a9eb8d62..84bd038f 100644 --- a/zh/10/ref/drop_domain.sgml +++ b/zh/10/ref/drop_domain.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP DOMAIN 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/drop_event_trigger.sgml b/zh/10/ref/drop_event_trigger.sgml index 3f4a900f..4cd25424 100644 --- a/zh/10/ref/drop_event_trigger.sgml +++ b/zh/10/ref/drop_event_trigger.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP EVENT TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -30,7 +30,7 @@ DROP EVENT TRIGGER [ IF EXISTS ] name DROP EVENT TRIGGER移除一个现有的事件触发器。 - 要执行此命令,当前用户必须是该事件触发器的拥有者。 + 要执行此命令,当前用户必须是该事件触发器的所有者。 @@ -99,7 +99,7 @@ DROP EVENT TRIGGER snitch; - 另见 + 参见 diff --git a/zh/10/ref/drop_extension.sgml b/zh/10/ref/drop_extension.sgml index fe222dfa..1991dc1c 100644 --- a/zh/10/ref/drop_extension.sgml +++ b/zh/10/ref/drop_extension.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP EXTENSION 7 - SQL - Language Statements + SQL - 语言语句 @@ -53,8 +53,8 @@ DROP EXTENSION [ IF EXISTS ] name [ name - 已安装扩展的名称。 - + 一个已安装扩展的名称。 + @@ -85,7 +85,7 @@ DROP EXTENSION [ IF EXISTS ] name [ DROP EXTENSION hstore; - 如果数据库中正在使用hstore的任何对象, + 如果数据库中使用了hstore的任何对象, 例如某些表具有hstore类型的列,则该命令会失败。 加上CASCADE选项可以强制一并移除这些依赖对象。 diff --git a/zh/10/ref/drop_foreign_data_wrapper.sgml b/zh/10/ref/drop_foreign_data_wrapper.sgml index d47b24c9..49e7bcc9 100644 --- a/zh/10/ref/drop_foreign_data_wrapper.sgml +++ b/zh/10/ref/drop_foreign_data_wrapper.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP FOREIGN DATA WRAPPER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/drop_foreign_table.sgml b/zh/10/ref/drop_foreign_table.sgml index d795723d..09c693de 100644 --- a/zh/10/ref/drop_foreign_table.sgml +++ b/zh/10/ref/drop_foreign_table.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP FOREIGN TABLE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/drop_function.sgml b/zh/10/ref/drop_function.sgml index 6bdd91fd..632a588a 100644 --- a/zh/10/ref/drop_function.sgml +++ b/zh/10/ref/drop_function.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP FUNCTION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/drop_group.sgml b/zh/10/ref/drop_group.sgml index 7433a45d..8dc907d6 100644 --- a/zh/10/ref/drop_group.sgml +++ b/zh/10/ref/drop_group.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP GROUP 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/drop_index.sgml b/zh/10/ref/drop_index.sgml index a4db8c5d..17cdce94 100644 --- a/zh/10/ref/drop_index.sgml +++ b/zh/10/ref/drop_index.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP INDEX 7 - SQL - Language Statements + SQL - 语言语句 @@ -55,7 +55,7 @@ DROP INDEX [ CONCURRENTLY ] [ IF EXISTS ] nameDROP INDEX CONCURRENTLY不可以。 对于临时表,DROP INDEX始终是非并发的, - 因为没有其他会话可以访问它们,而且非并发删除索引的成本更低。 + 因为没有其他会话可以访问它们,而且非并发删除索引的代价更低。 @@ -64,7 +64,7 @@ DROP INDEX [ CONCURRENTLY ] [ IF EXISTS ] nameIF EXISTS - 如果该索引不存在,则不要抛出错误。这种情况下会发出一个提示。 + 如果该索引不存在,则不要抛出错误。这种情况下会发出一条提示。 diff --git a/zh/10/ref/drop_language.sgml b/zh/10/ref/drop_language.sgml index 707bdcda..0b2e3835 100644 --- a/zh/10/ref/drop_language.sgml +++ b/zh/10/ref/drop_language.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP LANGUAGE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/drop_materialized_view.sgml b/zh/10/ref/drop_materialized_view.sgml index a771b161..ce4dfe2a 100644 --- a/zh/10/ref/drop_materialized_view.sgml +++ b/zh/10/ref/drop_materialized_view.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP MATERIALIZED VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/drop_opclass.sgml b/zh/10/ref/drop_opclass.sgml index 08e1b0c3..53d1b5a7 100644 --- a/zh/10/ref/drop_opclass.sgml +++ b/zh/10/ref/drop_opclass.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP OPERATOR CLASS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/drop_operator.sgml b/zh/10/ref/drop_operator.sgml index a57ce901..29225416 100644 --- a/zh/10/ref/drop_operator.sgml +++ b/zh/10/ref/drop_operator.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP OPERATOR 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/drop_opfamily.sgml b/zh/10/ref/drop_opfamily.sgml index 99c3de7c..743c2568 100644 --- a/zh/10/ref/drop_opfamily.sgml +++ b/zh/10/ref/drop_opfamily.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP OPERATOR FAMILY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/drop_owned.sgml b/zh/10/ref/drop_owned.sgml index af0113ca..ea20668a 100644 --- a/zh/10/ref/drop_owned.sgml +++ b/zh/10/ref/drop_owned.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP OWNED 7 - SQL - Language Statements + SQL - 语言语句 @@ -31,7 +31,7 @@ DROP OWNED BY { name | CURRENT_USER DROP OWNED删除当前数据库中由指定角色之一拥有的所有对象。 同时,授予给这些角色的、针对当前数据库中的对象或共享对象 - (数据库、表空间、配置参数)的任何权限也会被撤销。 + (数据库、表空间)的任何权限也会被撤销。 diff --git a/zh/10/ref/drop_policy.sgml b/zh/10/ref/drop_policy.sgml index 0693510d..9b8956f7 100644 --- a/zh/10/ref/drop_policy.sgml +++ b/zh/10/ref/drop_policy.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP POLICY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/drop_publication.sgml b/zh/10/ref/drop_publication.sgml index 54ed9ee7..fb054d76 100644 --- a/zh/10/ref/drop_publication.sgml +++ b/zh/10/ref/drop_publication.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP PUBLICATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/drop_role.sgml b/zh/10/ref/drop_role.sgml index baa61bd8..b6058ac6 100644 --- a/zh/10/ref/drop_role.sgml +++ b/zh/10/ref/drop_role.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP ROLE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/drop_rule.sgml b/zh/10/ref/drop_rule.sgml index c878ab5a..00932e10 100644 --- a/zh/10/ref/drop_rule.sgml +++ b/zh/10/ref/drop_rule.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP RULE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/drop_schema.sgml b/zh/10/ref/drop_schema.sgml index 83525b82..fb7576bd 100644 --- a/zh/10/ref/drop_schema.sgml +++ b/zh/10/ref/drop_schema.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP SCHEMA 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/drop_sequence.sgml b/zh/10/ref/drop_sequence.sgml index f137733a..6a34c691 100644 --- a/zh/10/ref/drop_sequence.sgml +++ b/zh/10/ref/drop_sequence.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP SEQUENCE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/drop_server.sgml b/zh/10/ref/drop_server.sgml index 3729543b..f62590ea 100644 --- a/zh/10/ref/drop_server.sgml +++ b/zh/10/ref/drop_server.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP SERVER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/drop_statistics.sgml b/zh/10/ref/drop_statistics.sgml index 51aa2a28..ec713fd0 100644 --- a/zh/10/ref/drop_statistics.sgml +++ b/zh/10/ref/drop_statistics.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP STATISTICS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/drop_subscription.sgml b/zh/10/ref/drop_subscription.sgml index 65ac5861..08482457 100644 --- a/zh/10/ref/drop_subscription.sgml +++ b/zh/10/ref/drop_subscription.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP SUBSCRIPTION 7 - SQL - Language Statements + SQL - 语言语句 @@ -32,9 +32,7 @@ DROP SUBSCRIPTION [ IF EXISTS ] nameDROP SUBSCRIPTION从数据库集簇中移除一个订阅。 - - 要执行此命令,用户必须是该订阅的拥有者。 - + 只有超级用户才能删除订阅。 如果订阅与复制槽相关联,则不能在事务块内执行DROP SUBSCRIPTION。(可以使用ALTER SUBSCRIPTION来取消设置该槽。) diff --git a/zh/10/ref/drop_table.sgml b/zh/10/ref/drop_table.sgml index a92a7629..fc5b0a5e 100644 --- a/zh/10/ref/drop_table.sgml +++ b/zh/10/ref/drop_table.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TABLE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/drop_tablespace.sgml b/zh/10/ref/drop_tablespace.sgml index 0f79e7cb..e342cafa 100644 --- a/zh/10/ref/drop_tablespace.sgml +++ b/zh/10/ref/drop_tablespace.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TABLESPACE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/drop_transform.sgml b/zh/10/ref/drop_transform.sgml index 75dc31dd..bbd1cd77 100644 --- a/zh/10/ref/drop_transform.sgml +++ b/zh/10/ref/drop_transform.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TRANSFORM 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/drop_trigger.sgml b/zh/10/ref/drop_trigger.sgml index ec394326..73a84426 100644 --- a/zh/10/ref/drop_trigger.sgml +++ b/zh/10/ref/drop_trigger.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -30,7 +30,7 @@ DROP TRIGGER [ IF EXISTS ] name ON DROP TRIGGER移除一个现有触发器的定义。 - 要执行此命令,当前用户必须是定义该触发器的表的拥有者。 + 要执行此命令,当前用户必须是定义该触发器的表的所有者。 @@ -109,7 +109,7 @@ DROP TRIGGER if_dist_exists ON films; - 另见 + 参见 diff --git a/zh/10/ref/drop_tsconfig.sgml b/zh/10/ref/drop_tsconfig.sgml index d43794ad..0881769f 100644 --- a/zh/10/ref/drop_tsconfig.sgml +++ b/zh/10/ref/drop_tsconfig.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TEXT SEARCH CONFIGURATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/drop_tsdictionary.sgml b/zh/10/ref/drop_tsdictionary.sgml index 48534c99..ba5c3de3 100644 --- a/zh/10/ref/drop_tsdictionary.sgml +++ b/zh/10/ref/drop_tsdictionary.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TEXT SEARCH DICTIONARY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/drop_tsparser.sgml b/zh/10/ref/drop_tsparser.sgml index 09c9b30c..a3ea49d7 100644 --- a/zh/10/ref/drop_tsparser.sgml +++ b/zh/10/ref/drop_tsparser.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TEXT SEARCH PARSER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/drop_tstemplate.sgml b/zh/10/ref/drop_tstemplate.sgml index 7a981fca..2a0fda88 100644 --- a/zh/10/ref/drop_tstemplate.sgml +++ b/zh/10/ref/drop_tstemplate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TEXT SEARCH TEMPLATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/drop_type.sgml b/zh/10/ref/drop_type.sgml index 923332af..ae45c9ac 100644 --- a/zh/10/ref/drop_type.sgml +++ b/zh/10/ref/drop_type.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TYPE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/drop_user.sgml b/zh/10/ref/drop_user.sgml index 52bcaa73..613f563d 100644 --- a/zh/10/ref/drop_user.sgml +++ b/zh/10/ref/drop_user.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP USER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/drop_user_mapping.sgml b/zh/10/ref/drop_user_mapping.sgml index 4a0b69de..7b8907e4 100644 --- a/zh/10/ref/drop_user_mapping.sgml +++ b/zh/10/ref/drop_user_mapping.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP USER MAPPING 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/drop_view.sgml b/zh/10/ref/drop_view.sgml index 8003c839..692a0970 100644 --- a/zh/10/ref/drop_view.sgml +++ b/zh/10/ref/drop_view.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/dropdb.sgml b/zh/10/ref/dropdb.sgml index 6b3a5b26..d702fec0 100644 --- a/zh/10/ref/dropdb.sgml +++ b/zh/10/ref/dropdb.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation dropdb 1 - Application + 应用程序 diff --git a/zh/10/ref/dropuser.sgml b/zh/10/ref/dropuser.sgml index 2a738d96..ae544634 100644 --- a/zh/10/ref/dropuser.sgml +++ b/zh/10/ref/dropuser.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation dropuser 1 - Application + 应用程序 diff --git a/zh/10/ref/ecpg-ref.sgml b/zh/10/ref/ecpg-ref.sgml index 9d6dbe20..08f0a7dc 100644 --- a/zh/10/ref/ecpg-ref.sgml +++ b/zh/10/ref/ecpg-ref.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ecpg 1 - Application + 应用程序 diff --git a/zh/10/ref/end.sgml b/zh/10/ref/end.sgml index 8947ae8e..bb375657 100644 --- a/zh/10/ref/end.sgml +++ b/zh/10/ref/end.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation END 7 - SQL - Language Statements + SQL - 语言语句 @@ -56,9 +56,7 @@ END [ WORK | TRANSACTION ] 注解 - - 使用可中止一个事务。 - + 使用 中止事务。 在事务块之外发出END不会造成任何影响,但会产生一条警告消息。 diff --git a/zh/10/ref/execute.sgml b/zh/10/ref/execute.sgml index a5160a17..66d25bee 100644 --- a/zh/10/ref/execute.sgml +++ b/zh/10/ref/execute.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation EXECUTE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/explain.sgml b/zh/10/ref/explain.sgml index 513c3114..0904987b 100644 --- a/zh/10/ref/explain.sgml +++ b/zh/10/ref/explain.sgml @@ -21,7 +21,7 @@ PostgreSQL documentation EXPLAIN 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/fetch.sgml b/zh/10/ref/fetch.sgml index be66fdf9..1a92e153 100644 --- a/zh/10/ref/fetch.sgml +++ b/zh/10/ref/fetch.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation FETCH 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/grant.sgml b/zh/10/ref/grant.sgml index 5bc4f2a8..809bbe55 100644 --- a/zh/10/ref/grant.sgml +++ b/zh/10/ref/grant.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation GRANT 7 - SQL - Language Statements + SQL - 语言语句 @@ -326,7 +326,7 @@ GRANT role_name [, ...] TO - 如果超级用户选择执行 GRANTREVOKE 命令,该命令会像由受影响对象的拥有者发出一样执行。特别是,通过这种命令授予的权限看起来会像是由对象拥有者授予的。(对于角色成员资格,则看起来像是由引导超级用户授予的。) + 如果超级用户选择执行 GRANTREVOKE 命令,该命令会像由受影响对象的拥有者发出一样执行。特别是,通过这种命令授予的权限看起来会像是由对象拥有者授予的。(对于角色成员资格,则看起来像是由被授予成员资格的角色本身授予的。) @@ -457,7 +457,7 @@ GRANT admins TO joe; - 数据库、表空间、模式、语言以及配置参数上的权限都是 PostgreSQL 扩展。 + 数据库、表空间、模式和语言上的权限都是 PostgreSQL 扩展。 diff --git a/zh/10/ref/import_foreign_schema.sgml b/zh/10/ref/import_foreign_schema.sgml index 33cab2c5..b509701c 100644 --- a/zh/10/ref/import_foreign_schema.sgml +++ b/zh/10/ref/import_foreign_schema.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation IMPORT FOREIGN SCHEMA 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/initdb.sgml b/zh/10/ref/initdb.sgml index a8d7df96..923ac1c1 100644 --- a/zh/10/ref/initdb.sgml +++ b/zh/10/ref/initdb.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation initdb 1 - Application + 应用程序 diff --git a/zh/10/ref/insert.sgml b/zh/10/ref/insert.sgml index b5d6969f..ebca19e1 100644 --- a/zh/10/ref/insert.sgml +++ b/zh/10/ref/insert.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation INSERT 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/listen.sgml b/zh/10/ref/listen.sgml index 01910fab..15477e30 100644 --- a/zh/10/ref/listen.sgml +++ b/zh/10/ref/listen.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation LISTEN 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/load.sgml b/zh/10/ref/load.sgml index 0427d28d..5e8e7d0b 100644 --- a/zh/10/ref/load.sgml +++ b/zh/10/ref/load.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation LOAD 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/lock.sgml b/zh/10/ref/lock.sgml index 3bac679f..8faf4500 100644 --- a/zh/10/ref/lock.sgml +++ b/zh/10/ref/lock.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation LOCK 7 - SQL - Language Statements + SQL - 语言语句 @@ -128,7 +128,11 @@ LOCK [ TABLE ] [ ONLY ] name [ * ] - LOCK TABLE在事务块外没有用处:锁只会持有到语句完成。因此,PostgreSQL会在事务块外使用LOCK时报错。使用(或)可以定义事务块。 + LOCK TABLE在事务块外毫无用处:锁只会一直持有到该语句结束。 + 因此,如果在事务块外使用LOCKPostgreSQL会报告错误。 + 请使用和 + + (或)来定义事务块。 diff --git a/zh/10/ref/move.sgml b/zh/10/ref/move.sgml index 632cc12c..789fc055 100644 --- a/zh/10/ref/move.sgml +++ b/zh/10/ref/move.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation MOVE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/notify.sgml b/zh/10/ref/notify.sgml index 5f26850e..dcda0c70 100644 --- a/zh/10/ref/notify.sgml +++ b/zh/10/ref/notify.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation NOTIFY 7 - SQL - Language Statements + SQL - 语言语句 @@ -88,7 +88,7 @@ NOTIFY channel [ , 注解 - 系统中有一个队列,用来保存那些已经发送但尚未被所有监听会话处理的通知。如果这个队列被塞满,那么调用NOTIFY的事务会在提交时失败。该队列非常大(标准安装中为 8GB),几乎足以满足所有用例。不过,如果某个会话执行了LISTEN后又长时间停留在一个事务里,就无法进行清理。一旦队列占用超过一半,你就会在日志文件中看到警告,指出究竟是哪个会话阻碍了清理。在这种情况下,应确保该会话结束其当前事务,以便清理能够继续进行。 + 系统中有一个队列,用来保存那些已经发送但尚未被所有监听会话处理的通知。如果这个队列被塞满,那么调用NOTIFY的事务会在提交时失败。该队列非常大(标准安装中为 8GB),几乎足以满足所有用例。不过,如果某个会话执行了LISTEN后又长时间停留在一个事务里,就无法进行清理。一旦队列占用达到一半,你就会在日志文件中看到警告,指出究竟是哪个会话阻碍了清理。在这种情况下,应确保该会话结束其当前事务,以便清理能够继续进行。 函数pg_notification_queue_usage返回当前被待处理通知占用的队列比例。详见。 diff --git a/zh/10/ref/pg_basebackup.sgml b/zh/10/ref/pg_basebackup.sgml index 2a0e49f0..58cabc68 100644 --- a/zh/10/ref/pg_basebackup.sgml +++ b/zh/10/ref/pg_basebackup.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_basebackup 1 - Application + 应用程序 @@ -37,7 +37,7 @@ PostgreSQL documentation 备份通过使用复制协议的普通PostgreSQL连接进行。建立连接时必须使用超级用户或具有REPLICATION权限(参见)的用户,并且pg_hba.conf必须明确允许复制连接。服务器还必须将设置得足够高,以便至少为备份保留一个可用会话,并在使用 WAL 流式传输时再为其保留一个会话。 - 可以同时运行多个pg_basebackup,但从性能角度来看,通常最好只执行一次备份,然后复制其结果。 + 可以同时运行多个pg_basebackup,但从性能角度来看,最好只执行一次备份,然后复制其结果。 @@ -186,7 +186,7 @@ PostgreSQL documentation - 目前,此选项仅适用于 plain 输出格式;如果选择了 tar 格式,则会被忽略。 + 目前,此选项仅适用于 普通文件 输出格式;如果选择了 tar 格式,则会被忽略。 @@ -194,7 +194,7 @@ PostgreSQL documentation - 指定预写式日志目录的位置。waldir必须是绝对路径。只有在备份采用 plain 模式时,才能指定预写式日志目录。 + 指定预写式日志目录的位置。waldir必须是绝对路径。只有在备份采用 普通文件 模式时,才能指定预写式日志目录。 @@ -264,7 +264,7 @@ PostgreSQL documentation - 启用 tar 文件输出的 gzip 压缩,使用默认压缩级别。压缩仅在使用 tar 格式时可用,并且所有 tar 文件名都会自动添加.gz后缀。 + 启用 tar 文件输出的 gzip 压缩,并指定压缩级别(0 到 9,其中 0 表示不压缩,9 表示最佳压缩)。压缩仅在使用 tar 格式时可用,并且所有 tar 文件名都会自动添加.gz后缀。 @@ -302,7 +302,7 @@ PostgreSQL documentation - 请注意,无论如何表空间目录都不会被清理。 + 请注意,无论是否使用此选项,表空间目录都不会被清理。 @@ -422,7 +422,10 @@ PostgreSQL documentation - 还可以使用其他选项: + + 其他选项也可用: + + @@ -458,18 +461,18 @@ PostgreSQL documentation - 注意 + 注解 在备份开始时,需要在源服务器上执行一次检查点。这可能需要一些时间(尤其是在未使用--checkpoint=fast选项时);在此期间,pg_basebackup看起来会处于空闲状态。 - 备份将包括数据目录和表空间中的所有文件,包括配置文件以及第三方放在这些目录中的任何额外文件,但由 PostgreSQL 管理的某些临时文件和操作系统文件除外。不过,只有普通文件和目录会被复制,但用于表空间的符号链接会被保留。指向 PostgreSQL 已知某些目录的符号链接会被复制为空目录。其他符号链接和特殊设备文件则会被跳过。具体细节见。 + 备份将包括数据目录和表空间中的所有文件,包括配置文件以及第三方放在这些目录中的任何额外文件,但由 PostgreSQL 管理的某些临时文件除外。不过,只有普通文件和目录会被复制,但用于表空间的符号链接会被保留。指向 PostgreSQL 已知某些目录的符号链接会被复制为空目录。其他符号链接和特殊设备文件则会被跳过。具体细节见 - 在 plain 格式中,除非使用了--tablespace-mapping选项,否则表空间会备份到其在源服务器上的相同路径。如果不使用此选项,那么当表空间正在使用时,就无法在与服务器相同的主机上执行 plain 格式的基础备份,因为备份将不得不写入与原始表空间相同的目录位置。 + 在 普通文件 格式中,除非使用了--tablespace-mapping选项,否则表空间会备份到其在源服务器上的相同路径。如果不使用此选项,那么当表空间正在使用时,就无法在与服务器相同的主机上执行 普通文件 格式的基础备份,因为备份将不得不写入与原始表空间相同的目录位置。 使用 tar 格式时,用户有责任在启动 PostgreSQL 服务器之前解包每个 tar 文件。如果存在额外表空间,则其 tar 文件必须解包到正确的位置。在这种情况下,服务器会根据tablespace_map文件的内容,为这些表空间创建符号链接,该文件包含在base.tar文件中。 @@ -511,7 +514,7 @@ PostgreSQL documentation - 参见 + 另见 diff --git a/zh/10/ref/pg_config-ref.sgml b/zh/10/ref/pg_config-ref.sgml index 37dd43a8..7ea2f196 100644 --- a/zh/10/ref/pg_config-ref.sgml +++ b/zh/10/ref/pg_config-ref.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_config 1 - Application + 应用程序 diff --git a/zh/10/ref/pg_controldata.sgml b/zh/10/ref/pg_controldata.sgml index 7170eea2..dd5cbc53 100644 --- a/zh/10/ref/pg_controldata.sgml +++ b/zh/10/ref/pg_controldata.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_controldata 1 - Application + 应用程序 diff --git a/zh/10/ref/pg_ctl-ref.sgml b/zh/10/ref/pg_ctl-ref.sgml index 1764a187..56ba0260 100644 --- a/zh/10/ref/pg_ctl-ref.sgml +++ b/zh/10/ref/pg_ctl-ref.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_ctl 1 - Application + 应用程序 @@ -149,7 +149,7 @@ PostgreSQL documentation - 模式会关闭在指定数据目录中运行的服务器。可以使用选项选择三种不同的关闭方法。Smart模式不允许新连接,然后等待所有现有客户端断开。如果服务器处于热备状态,那么在所有客户端断开后,恢复和流复制都会终止。Fast模式(默认值)不等待客户端断开。所有活动事务都会回滚,客户端会被强制断开,然后服务器关闭。Immediate模式会立即中止所有服务器进程,而不执行干净关闭。这样会导致服务器在下次启动时进入一次崩溃恢复周期。 + 模式会关闭在指定数据目录中运行的服务器。可以使用选项选择三种不同的关闭方法。Smart模式不允许新连接,然后等待所有现有客户端断开,以及所有在线备份结束。如果服务器处于热备状态,那么在所有客户端断开后,恢复和流复制都会终止。Fast模式(默认值)不等待客户端断开,并会终止正在进行的在线备份。所有活动事务都会回滚,客户端会被强制断开,然后服务器关闭。Immediate模式会立即中止所有服务器进程,而不执行干净关闭。这样会导致服务器在下次启动时进入一次崩溃恢复周期。 @@ -539,13 +539,16 @@ PostgreSQL documentation 显示服务器状态 - 下面是状态输出的示例,来自 pg_ctl: + + 下面是pg_ctl状态输出的示例: $ pg_ctl status pg_ctl: server is running (PID: 13718) /usr/local/pgsql/bin/postgres "-D" "/usr/local/pgsql/data" "-p" "5433" "-B" "128" -第二行是在重启模式下将会调用的命令。 + + 第二行是在重启模式下会调用的命令。 + diff --git a/zh/10/ref/pg_dump.sgml b/zh/10/ref/pg_dump.sgml index 8f700364..326a915a 100644 --- a/zh/10/ref/pg_dump.sgml +++ b/zh/10/ref/pg_dump.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_dump 1 - Application + 应用程序 @@ -272,7 +272,9 @@ PostgreSQL documentation 同步快照特性,就无法保证各个工作任务在各自连接中看到相同的数据,这会 导致备份不一致。 - 如果要对 9.2 之前的服务器执行并行转储,必须确保从主进程连接数据库起,到最后一个工作任务连接数据库为止,数据库内容都不发生变化。最简单的方法是在开始备份之前,暂停所有访问数据库并修改数据的进程(DDL 和 DML)。对 9.2 之前的服务器使用参数也是必需的,即使用pg_dump -j连接这些PostgreSQL服务器时。 + + 如果要对 9.2 之前的服务器执行并行转储,必须确保从主进程连接数据库起,到最后一个工作任务连接数据库为止,数据库内容都不发生变化。最简单的方法是在开始备份之前,暂停所有访问数据库并修改数据的进程(DDL 和 DML)。对 9.2 之前的PostgreSQL服务器运行pg_dump -j时,还必须指定参数。 + diff --git a/zh/10/ref/pg_dumpall.sgml b/zh/10/ref/pg_dumpall.sgml index ab7da1d3..fa268088 100644 --- a/zh/10/ref/pg_dumpall.sgml +++ b/zh/10/ref/pg_dumpall.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_dumpall 1 - Application + 应用程序 diff --git a/zh/10/ref/pg_isready.sgml b/zh/10/ref/pg_isready.sgml index e1e9934f..546d14c8 100644 --- a/zh/10/ref/pg_isready.sgml +++ b/zh/10/ref/pg_isready.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_isready 1 - Application + 应用程序 diff --git a/zh/10/ref/pg_receivewal.sgml b/zh/10/ref/pg_receivewal.sgml index 70648358..45efd444 100644 --- a/zh/10/ref/pg_receivewal.sgml +++ b/zh/10/ref/pg_receivewal.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_receivewal 1 - Application + 应用程序 diff --git a/zh/10/ref/pg_recvlogical.sgml b/zh/10/ref/pg_recvlogical.sgml index a996172c..b3e7331d 100644 --- a/zh/10/ref/pg_recvlogical.sgml +++ b/zh/10/ref/pg_recvlogical.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_recvlogical 1 - Application + 应用程序 @@ -60,7 +60,9 @@ PostgreSQL documentation - 删除由指定名称的复制槽,然后退出。 + + 删除由指定名称的复制槽,然后退出。 + @@ -72,9 +74,13 @@ PostgreSQL documentation 如果服务端的更改流因服务器关闭或断开连接而结束,则除非指定了,否则会循环重试。 - 流格式由创建槽时指定的输出插件决定。 + + 流格式由创建该槽时指定的输出插件决定。 + - 必须连接到创建槽时使用的同一个数据库。 + + 该连接必须连到创建该槽时所用的同一个数据库。 + @@ -122,7 +128,7 @@ PostgreSQL documentation 指定pg_recvlogical应当以多高的频率发起fsync()调用, - 以确保输出文件被安全地刷入磁盘。 + 以确保输出文件安全刷盘。 @@ -148,7 +154,9 @@ PostgreSQL documentation - 指定且指定名称的槽已存在时,不报错。 + + 当指定且指定名称的槽已存在时,不报错。 + @@ -156,7 +164,9 @@ PostgreSQL documentation - 当与服务器的连接丢失时,不循环重试,直接退出。 + + 当与服务器的连接丢失时,不要循环重试,直接退出。 + @@ -164,7 +174,10 @@ PostgreSQL documentation - 将选项name传递给输出插件,如果指定了选项值value,也一并传递。有哪些选项以及它们的效果取决于所用的输出插件。 + + 将选项name传递给输出插件;如果指定了value, + 则将其用作该选项的值。可用选项及其效果取决于所使用的输出插件。 + @@ -188,7 +201,11 @@ PostgreSQL documentation - 模式下,使用名为slot_name的现有逻辑复制槽。在模式下,创建此名称的槽。在模式下,删除此名称的槽。 + + 在模式下,使用名为slot_name的现有逻辑复制槽。 + 在模式下,以此名称创建该槽。 + 在模式下,删除此名称的槽。 + @@ -196,7 +213,9 @@ PostgreSQL documentation - 启用详细模式。 + + 启用详细模式。 + @@ -240,7 +259,9 @@ PostgreSQL documentation - 连接时使用的用户名。默认为当前操作系统用户名。 + + 用于连接的用户名。默认为当前操作系统用户名。 + @@ -282,7 +303,9 @@ PostgreSQL documentation - 打印pg_recvlogical的版本并退出。 + + 打印pg_recvlogical的版本并退出。 + @@ -290,7 +313,9 @@ PostgreSQL documentation - 显示pg_recvlogical命令行参数的帮助并退出。 + + 显示pg_recvlogical命令行参数的帮助并退出。 + @@ -298,7 +323,7 @@ PostgreSQL documentation - 退出状态 + 环境 与大多数其他PostgreSQL工具一样,该工具使用libpq支持的环境变量(见)。 diff --git a/zh/10/ref/pg_resetwal.sgml b/zh/10/ref/pg_resetwal.sgml index b5b83015..7382509e 100644 --- a/zh/10/ref/pg_resetwal.sgml +++ b/zh/10/ref/pg_resetwal.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_resetwal 1 - Application + 应用程序 diff --git a/zh/10/ref/pg_restore.sgml b/zh/10/ref/pg_restore.sgml index b8830370..febfbce9 100644 --- a/zh/10/ref/pg_restore.sgml +++ b/zh/10/ref/pg_restore.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_restore 1 - Application + 应用程序 diff --git a/zh/10/ref/pg_rewind.sgml b/zh/10/ref/pg_rewind.sgml index b645fc2a..4a4c462b 100644 --- a/zh/10/ref/pg_rewind.sgml +++ b/zh/10/ref/pg_rewind.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_rewind 1 - Application + 应用程序 diff --git a/zh/10/ref/pg_waldump.sgml b/zh/10/ref/pg_waldump.sgml index b5aee945..23a3e8ef 100644 --- a/zh/10/ref/pg_waldump.sgml +++ b/zh/10/ref/pg_waldump.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_waldump 1 - Application + 应用程序 diff --git a/zh/10/ref/pgarchivecleanup.sgml b/zh/10/ref/pgarchivecleanup.sgml index 3df3d882..a3c2f5e3 100644 --- a/zh/10/ref/pgarchivecleanup.sgml +++ b/zh/10/ref/pgarchivecleanup.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_archivecleanup 1 - Application + 应用程序 diff --git a/zh/10/ref/pgbench.sgml b/zh/10/ref/pgbench.sgml index 4ae2d44b..441fd105 100644 --- a/zh/10/ref/pgbench.sgml +++ b/zh/10/ref/pgbench.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pgbench 1 - Application + 应用程序 @@ -1124,7 +1124,7 @@ script statistics: 安全性 - 如果不可信用户能够访问尚未采用模式的安全使用方式的数据库,就不要在该数据库中运行pgbenchpgbench使用非限定名称,并且不会更改搜索路径。 + 如果不受信任的用户能够访问尚未采用模式的安全使用方式的数据库,就不要在该数据库中运行pgbenchpgbench使用非限定名称,并且不会更改搜索路径。 diff --git a/zh/10/ref/pgtestfsync.sgml b/zh/10/ref/pgtestfsync.sgml index 2090fcc2..4a06cec6 100644 --- a/zh/10/ref/pgtestfsync.sgml +++ b/zh/10/ref/pgtestfsync.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_test_fsync 1 - Application + 应用程序 diff --git a/zh/10/ref/pgtesttiming.sgml b/zh/10/ref/pgtesttiming.sgml index 318b865d..7253f1a2 100644 --- a/zh/10/ref/pgtesttiming.sgml +++ b/zh/10/ref/pgtesttiming.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_test_timing 1 - Application + 应用程序 diff --git a/zh/10/ref/pgupgrade.sgml b/zh/10/ref/pgupgrade.sgml index 7fb35780..c53e28cc 100644 --- a/zh/10/ref/pgupgrade.sgml +++ b/zh/10/ref/pgupgrade.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_upgrade 1 - Application + 应用程序 @@ -104,7 +104,7 @@ PostgreSQL documentation - 要使用的并发连接和进程/线程数 + 要使用的并发进程或线程数 @@ -532,7 +532,7 @@ psql --username=postgres --file=script.sql postgres - 环境 + 注解 pg_upgrade不支持升级包含下列reg* OID 引用系统数据类型的数据库:regprocregprocedureregoperregoperatorregconfigregdictionary。(regtype可以升级。) @@ -565,7 +565,7 @@ psql --username=postgres --file=script.sql postgres - 注解 + 另见 diff --git a/zh/10/ref/postgres-ref.sgml b/zh/10/ref/postgres-ref.sgml index 135b4eb4..b5d44c78 100644 --- a/zh/10/ref/postgres-ref.sgml +++ b/zh/10/ref/postgres-ref.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation postgres 1 - Application + 应用程序 @@ -97,7 +97,7 @@ PostgreSQL documentation 打印指定运行时参数的值并退出。 - (详情见上面的选项。)这会返回 + (详情见上面的选项。)这个选项可用于正在运行的服务器,它会返回 postgresql.conf中的值,并应用本次调用中提供的任何参数修改。它不反映 集簇启动时提供的参数。 @@ -529,7 +529,7 @@ PostgreSQL documentation - 表明另一台服务器已经在运行的失败消息 + 表明另一个服务器已经在运行的失败消息 应仔细检查,例如可根据你的系统使用下面的命令: $ ps ax | grep postgres @@ -674,16 +674,26 @@ PostgreSQL documentation 示例 - 启动 postgres 时,如需使用默认值并在后台运行,请输入: + + 要使用默认值在后台启动postgres, + 输入: + + $ nohup postgres >logfile 2>&1 </dev/null & - 启动 postgres 并指定端口,例如 1234: + + 要用指定端口启动postgres, + 例如 1234: + $ postgres -p 1234 -要使用 psql 连接到此服务器,请用 -p 选项指定该端口: + + 要使用psql连接到该服务器,请用选项指定这个端口: + $ psql -p 1234 -或者设置环境变量 PGPORT: + + 或者设置环境变量PGPORT $ export PGPORT=1234 $ psql @@ -708,7 +718,7 @@ PostgreSQL documentation - 参见 + 另见 , diff --git a/zh/10/ref/prepare.sgml b/zh/10/ref/prepare.sgml index 2089bdf0..ce84452d 100644 --- a/zh/10/ref/prepare.sgml +++ b/zh/10/ref/prepare.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation PREPARE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/prepare_transaction.sgml b/zh/10/ref/prepare_transaction.sgml index 352971b6..4ae4891c 100644 --- a/zh/10/ref/prepare_transaction.sgml +++ b/zh/10/ref/prepare_transaction.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation PREPARE TRANSACTION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/psql-ref.sgml b/zh/10/ref/psql-ref.sgml index dbe1ebae..4bc80215 100644 --- a/zh/10/ref/psql-ref.sgml +++ b/zh/10/ref/psql-ref.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation psql 1 - Application + 应用程序 @@ -524,7 +524,7 @@ testdb=> - 如果不可信用户能够访问尚未采用模式的安全使用方式的数据库,请在会话开始时从search_path中移除所有公众可写的 schema。可以在连接字符串中加入options=-csearch_path=,或者在执行其他 SQL 命令之前发出SELECT pg_catalog.set_config('search_path', '', false)。这种考虑并非psql特有;它适用于任何执行任意 SQL 命令的接口。 + 如果不受信任的用户能够访问尚未采用模式的安全使用方式的数据库,请在会话开始时从search_path中移除所有公众可写的模式。可以在连接字符串中加入options=-csearch_path=,或者在执行其他 SQL 命令之前发出SELECT pg_catalog.set_config('search_path', '', false)。这种考虑并非psql特有;它适用于任何执行任意 SQL 命令的接口。 每当执行命令时,psql也会轮询由生成的异步通知事件。 @@ -1173,11 +1173,7 @@ CREATE INDEX - 生成的查询按照返回的行的顺序执行,并在每行内从左到右执行,如果有多个列。NULL字段将被忽略。生成的查询文字 - 直接发送到服务器进行处理,因此它们不能是psql元命令,也不能包含psql - 变量引用。如果任何单个查询失败,剩余查询的执行将继续,除非设置了ON_ERROR_STOP。每个查询的执行 - 都受ECHO处理的影响。(通常在使用\gexec时,将ECHO设置为 - allqueries是明智的。)查询记录、单步模式、计时和其他查询执行功能也适用于每个生成的查询。 + 生成的查询按照返回行的顺序执行;如果有多列,则在每行内从左到右执行。NULL 字段会被忽略。生成的查询按原样发送到服务器进行处理,因此不能是psql元命令,也不能包含psql变量引用。如果某个查询失败,仍会继续执行其余查询,除非设置了ON_ERROR_STOP。每个查询的执行都受ECHO处理的影响。(通常,在使用\gexec时,适宜将ECHO设为allqueries。)查询日志、单步模式、计时及其他查询执行功能也适用于每个生成的查询。 如果当前查询缓冲区为空,则改为重新执行最近发送的查询。 @@ -2268,7 +2264,7 @@ bar <acronym>SQL</acronym> 中插入变量 - psql变量的一个关键特性是可以把它们替换(插入)到常规SQL语句中,也可以把它们作为元命令的参数。此外,psql还提供了功能来确保被用作 SQL 文字和标识符的变量值会被正确地引用。插入一个值而不需要加引用的语法是在变量名前面加上一个冒号(:)。例如, + psql变量的一个关键特性是可以把它们替换(插入)到常规SQL语句中,也可以把它们作为元命令的参数。此外,psql还提供了功能来确保被用作 SQL 字面量和标识符的变量值会被正确地加引号。插入一个值而不加引号的语法是在变量名前面加上一个冒号(:)。例如, testdb=> \set foo 'my_table' testdb=> SELECT * FROM :foo; diff --git a/zh/10/ref/reassign_owned.sgml b/zh/10/ref/reassign_owned.sgml index 7715eb4e..9c24c0d1 100644 --- a/zh/10/ref/reassign_owned.sgml +++ b/zh/10/ref/reassign_owned.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation REASSIGN OWNED 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/refresh_materialized_view.sgml b/zh/10/ref/refresh_materialized_view.sgml index e533367e..d9d77a17 100644 --- a/zh/10/ref/refresh_materialized_view.sgml +++ b/zh/10/ref/refresh_materialized_view.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation REFRESH MATERIALIZED VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/reindex.sgml b/zh/10/ref/reindex.sgml index e3b3490e..ec27e801 100644 --- a/zh/10/ref/reindex.sgml +++ b/zh/10/ref/reindex.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation REINDEX 7 - SQL - Language Statements + SQL - 语言语句 @@ -29,7 +29,8 @@ REINDEX [ ( VERBOSE ) ] { INDEX | TABLE | SCHEMA | DATABASE | SYSTEM } 描述 - REINDEX利用索引所属表中存储的数据重建索引,替换该索引的旧副本。以下几种情况适合使用REINDEX: + REINDEX使用索引所属表中存储的数据重建索引, + 并替换索引的旧副本。以下几种场景适合使用REINDEX @@ -99,8 +100,8 @@ REINDEX [ ( VERBOSE ) ] { INDEX | TABLE | SCHEMA | DATABASE | SYSTEM } - 重新创建当前数据库中除系统目录外的所有索引。 - 系统目录上的索引不会被处理。这种形式的REINDEX不能 + 重新创建当前数据库中的所有索引。 + 共享系统目录上的索引也会被处理。这种形式的REINDEX不能 在事务块内执行。 @@ -125,8 +126,7 @@ REINDEX [ ( VERBOSE ) ] { INDEX | TABLE | SCHEMA | DATABASE | SYSTEM } 要重新索引的特定索引、表或数据库的名称。索引名和表名可以带模式限 定。目前,REINDEX DATABASE和 - REINDEX SYSTEM只能对当前数据库重新索引。它们的参 - 数是可选的,但如果给出,就必须与当前数据库名匹配。 + REINDEX SYSTEM只能对当前数据库重新索引,所以其参数必须与当前数据库名匹配。 diff --git a/zh/10/ref/reindexdb.sgml b/zh/10/ref/reindexdb.sgml index 44d85428..f30b8f19 100644 --- a/zh/10/ref/reindexdb.sgml +++ b/zh/10/ref/reindexdb.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation reindexdb 1 - Application + 应用程序 @@ -322,22 +322,24 @@ PostgreSQL documentation - 示例 + 注解 reindexdb 可能需要多次连接到 PostgreSQL 服务器,每次都要求输入密码。在这种情况下,使用 ~/.pgpass 文件会很方便。更多信息见 - 参见 + 示例 - 要重新索引数据库test: + + 要重建数据库test中的索引: $ reindexdb test - 要重新索引表foo和索引bar,其所在数据库名为abcd: + + 要重建名为abcd的数据库中表foo的索引和索引bar $ reindexdb --table=foo --index=bar abcd diff --git a/zh/10/ref/release_savepoint.sgml b/zh/10/ref/release_savepoint.sgml index 009f1b93..c964b77f 100644 --- a/zh/10/ref/release_savepoint.sgml +++ b/zh/10/ref/release_savepoint.sgml @@ -10,18 +10,18 @@ PostgreSQL documentation 保存点 - releasing + 释放 RELEASE SAVEPOINT 7 - SQL - Language Statements + SQL - 语言语句 RELEASE SAVEPOINT - 释放一个先前定义的保存点 + 销毁一个先前定义的保存点 @@ -48,7 +48,7 @@ RELEASE [ SAVEPOINT ] savepoint_name savepoint_name - 要释放的保存点名称。 + 要销毁的保存点名称。 @@ -74,14 +74,18 @@ RELEASE [ SAVEPOINT ] savepoint_name 示例 - 建立保存点并在之后将其销毁: + + 要建立保存点,并在稍后销毁它: + BEGIN; INSERT INTO table1 VALUES (3); SAVEPOINT my_savepoint; INSERT INTO table1 VALUES (4); RELEASE SAVEPOINT my_savepoint; COMMIT; -上面的事务会同时插入 3 和 4。 + + 上述事务将同时插入 3 和 4。 + diff --git a/zh/10/ref/reset.sgml b/zh/10/ref/reset.sgml index 6c1a91f7..cc3b5237 100644 --- a/zh/10/ref/reset.sgml +++ b/zh/10/ref/reset.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation RESET 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/revoke.sgml b/zh/10/ref/revoke.sgml index 5d2cab45..61a310f3 100644 --- a/zh/10/ref/revoke.sgml +++ b/zh/10/ref/revoke.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation REVOKE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/rollback.sgml b/zh/10/ref/rollback.sgml index 35bf62f7..c6df0b43 100644 --- a/zh/10/ref/rollback.sgml +++ b/zh/10/ref/rollback.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ROLLBACK 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/rollback_prepared.sgml b/zh/10/ref/rollback_prepared.sgml index 99ac9fb1..4929a72c 100644 --- a/zh/10/ref/rollback_prepared.sgml +++ b/zh/10/ref/rollback_prepared.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ROLLBACK PREPARED 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/rollback_to.sgml b/zh/10/ref/rollback_to.sgml index a01b3a63..592c0a7c 100644 --- a/zh/10/ref/rollback_to.sgml +++ b/zh/10/ref/rollback_to.sgml @@ -10,13 +10,13 @@ PostgreSQL documentation 保存点 - rolling back + 回滚 ROLLBACK TO SAVEPOINT 7 - SQL - Language Statements + SQL - 语言语句 @@ -34,8 +34,7 @@ ROLLBACK [ WORK | TRANSACTION ] TO [ SAVEPOINT ] savepoint_name描述 - 回滚该保存点建立后执行的所有命令,然后在同一事务层级启动一个新的 - 子事务。该保存点仍然有效,如有需要,之后还可以再次回滚到它。 + 回滚该保存点建立后执行的所有命令。该保存点仍然有效,如有需要,之后还可以再次回滚到它。 diff --git a/zh/10/ref/savepoint.sgml b/zh/10/ref/savepoint.sgml index a7f3672f..c59218ea 100644 --- a/zh/10/ref/savepoint.sgml +++ b/zh/10/ref/savepoint.sgml @@ -10,13 +10,13 @@ PostgreSQL documentation 保存点 - defining + 定义 SAVEPOINT 7 - SQL - Language Statements + SQL - 语言语句 @@ -102,7 +102,9 @@ COMMIT; 上述事务将同时插入 3 和 4。 - 使用同一个保存点名称: + + 要重复使用同一个保存点名称: + BEGIN; INSERT INTO table1 VALUES (1); SAVEPOINT my_savepoint; @@ -110,18 +112,20 @@ BEGIN; SAVEPOINT my_savepoint; INSERT INTO table1 VALUES (3); - -- rollback to the second savepoint + -- 回滚到第二个保存点 ROLLBACK TO SAVEPOINT my_savepoint; - SELECT * FROM table1; -- shows rows 1 and 2 + SELECT * FROM table1; -- 显示值为 1 和 2 的行 - -- release the second savepoint + -- 释放第二个保存点 RELEASE SAVEPOINT my_savepoint; - -- rollback to the first savepoint + -- 回滚到第一个保存点 ROLLBACK TO SAVEPOINT my_savepoint; - SELECT * FROM table1; -- shows only row 1 + SELECT * FROM table1; -- 仅显示值为 1 的行 COMMIT; -上面的事务展示了先回滚行 3,再回滚行 2。 + + 上述事务展示了先回滚值为 3 的行,再回滚值为 2 的行。 + diff --git a/zh/10/ref/security_label.sgml b/zh/10/ref/security_label.sgml index 2efa0a34..b63643d7 100644 --- a/zh/10/ref/security_label.sgml +++ b/zh/10/ref/security_label.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SECURITY LABEL 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/select.sgml b/zh/10/ref/select.sgml index 60cc735e..28a02b51 100644 --- a/zh/10/ref/select.sgml +++ b/zh/10/ref/select.sgml @@ -20,7 +20,7 @@ PostgreSQL documentation SELECT 7 - SQL - Language Statements + SQL - 语言语句 @@ -1266,7 +1266,7 @@ SELECT * FROM (SELECT * FROM mytable FOR UPDATE) ss ORDER BY column1; REPEATABLE READSERIALIZABLE事务隔离级别下, - 这将导致序列化失败(带有SQLSTATE'40001'), + 这将导致串行化失败(SQLSTATE'40001'), 因此在这些隔离级别下不可能接收到无序的行。 diff --git a/zh/10/ref/select_into.sgml b/zh/10/ref/select_into.sgml index 34fffb7a..936bfe69 100644 --- a/zh/10/ref/select_into.sgml +++ b/zh/10/ref/select_into.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SELECT INTO 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/set.sgml b/zh/10/ref/set.sgml index 85063395..8b81d779 100644 --- a/zh/10/ref/set.sgml +++ b/zh/10/ref/set.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SET 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/set_constraints.sgml b/zh/10/ref/set_constraints.sgml index 51e924ef..7701efbf 100644 --- a/zh/10/ref/set_constraints.sgml +++ b/zh/10/ref/set_constraints.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SET CONSTRAINTS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/set_role.sgml b/zh/10/ref/set_role.sgml index d132fb32..c2695218 100644 --- a/zh/10/ref/set_role.sgml +++ b/zh/10/ref/set_role.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SET ROLE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/set_session_auth.sgml b/zh/10/ref/set_session_auth.sgml index b3b765fa..8cb55d2d 100644 --- a/zh/10/ref/set_session_auth.sgml +++ b/zh/10/ref/set_session_auth.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SET SESSION AUTHORIZATION 7 - SQL - Language Statements + SQL - 语言语句 @@ -46,7 +46,7 @@ RESET SESSION AUTHORIZATION - 只有当初始会话用户(即已认证用户)具有超级用户权限时, + 只有当初始会话用户(即已认证用户)最初具有超级用户权限时, 才能更改会话用户标识符。否则,只有当该命令指定的是已认证用户名时, 才会被接受。 diff --git a/zh/10/ref/set_transaction.sgml b/zh/10/ref/set_transaction.sgml index 2742ccff..d2ca5852 100644 --- a/zh/10/ref/set_transaction.sgml +++ b/zh/10/ref/set_transaction.sgml @@ -26,7 +26,7 @@ PostgreSQL documentation SET TRANSACTION 7 - SQL - Language Statements + SQL - 语言语句 @@ -66,7 +66,7 @@ SET SESSION CHARACTERISTICS AS TRANSACTION transa - 一个事务的隔离级别决定当其他事务并行运行时该事务能看见什么数据: + 一个事务的隔离级别决定当其他事务并发运行时该事务能看见什么数据: @@ -137,7 +137,7 @@ SET SESSION CHARACTERISTICS AS TRANSACTION transa 事务属性才会生效。当为一个事务同时选择这三个属性时,该事务在 首次获取其快照时可能会阻塞;在此之后,它便可以运行,而无需承担普通 SERIALIZABLE事务的常规开销,也不会有促成 - 序列化失败或因序列化失败而被取消的风险。这种模式非常适合长时间运行的 + 串行化失败或因串行化失败而被取消的风险。这种模式非常适合长时间运行的 报表或备份。 diff --git a/zh/10/ref/show.sgml b/zh/10/ref/show.sgml index 1b540304..08538428 100644 --- a/zh/10/ref/show.sgml +++ b/zh/10/ref/show.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SHOW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/start_transaction.sgml b/zh/10/ref/start_transaction.sgml index 0fe10c05..bcbdc548 100644 --- a/zh/10/ref/start_transaction.sgml +++ b/zh/10/ref/start_transaction.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation START TRANSACTION 7 - SQL - Language Statements + SQL - 语言语句 @@ -64,15 +64,16 @@ START TRANSACTION [ transaction_mode - DEFERRABLE 这一 - transaction_mode 是 - PostgreSQL语言扩展。 + DEFERRABLE + transaction_mode + 是PostgreSQL的一种语言扩展。 SQL 标准要求在连续的transaction_modes之间有逗号, - 但出于历史原因PostgreSQL允许省略逗号。 + 但出于历史原因, + PostgreSQL允许省略逗号。 diff --git a/zh/10/ref/truncate.sgml b/zh/10/ref/truncate.sgml index 617d294d..a33a2fcc 100644 --- a/zh/10/ref/truncate.sgml +++ b/zh/10/ref/truncate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation TRUNCATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/unlisten.sgml b/zh/10/ref/unlisten.sgml index 003300c3..f28790c8 100644 --- a/zh/10/ref/unlisten.sgml +++ b/zh/10/ref/unlisten.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation UNLISTEN 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/update.sgml b/zh/10/ref/update.sgml index 18b2d46b..2cc93bf4 100644 --- a/zh/10/ref/update.sgml +++ b/zh/10/ref/update.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation UPDATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/ref/vacuum.sgml b/zh/10/ref/vacuum.sgml index a16506e5..76a1a5f0 100644 --- a/zh/10/ref/vacuum.sgml +++ b/zh/10/ref/vacuum.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation VACUUM 7 - SQL - Language Statements + SQL - 语言语句 @@ -182,7 +182,7 @@ VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] ANALYZE [ 示例 - 清理单个表onek,对其执行优化器分析,并打印详细的清理活动报告: + 清理单个表onek,对其进行分析以供优化器使用,并打印详细的清理活动报告: VACUUM (VERBOSE, ANALYZE) onek; diff --git a/zh/10/ref/vacuumdb.sgml b/zh/10/ref/vacuumdb.sgml index 84434fed..fb1d475e 100644 --- a/zh/10/ref/vacuumdb.sgml +++ b/zh/10/ref/vacuumdb.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation vacuumdb 1 - Application + 应用程序 @@ -118,7 +118,7 @@ PostgreSQL documentation - 积极地冻结元组。 + 激进地冻结元组。 @@ -212,11 +212,9 @@ PostgreSQL documentation 仅计算供优化器使用的统计信息(不执行清理),类似。使用不同的配置设置运行多个(目前为三个)分析阶段,以便更快地生成可用统计信息。 - 此选项仅在分析当前没有统计信息,或现有统计信息完全错误的数据库时才有用,例如数据库是 - 从恢复出的转储中重新填充,或是通过 pg_upgrade 新建得到的。 - 注意,在已有统计信息的数据库上使用此选项,可能会因为早期阶段采用较低统计目标, - 导致查询优化器的选择暂时变差。 - + 此选项适合分析刚通过恢复转储或pg_upgrade填充的数据库。 + 它会尽快尝试生成一些统计信息,让数据库能够使用,然后在后续阶段生成完整统计信息。 + @@ -349,13 +347,13 @@ PostgreSQL documentation - 示例 + 注解 vacuumdb可能需要多次连接到PostgreSQL服务器,每次都要询问密码。在这种情况下,使用~/.pgpass文件会比较方便。更多信息见 - 参见 + 示例 清理数据库 test diff --git a/zh/10/ref/values.sgml b/zh/10/ref/values.sgml index 13abb8d1..ba17afe2 100644 --- a/zh/10/ref/values.sgml +++ b/zh/10/ref/values.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation VALUES 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/10/runtime.sgml b/zh/10/runtime.sgml index ea07b0e3..035ae6d3 100644 --- a/zh/10/runtime.sgml +++ b/zh/10/runtime.sgml @@ -9,7 +9,7 @@ <productname>PostgreSQL</productname>用户账户 - postgres user + postgres 用户 与任何可从外部访问的服务器守护进程一样,建议使用单独的用户账户运行 PostgreSQL。该用户账户应该只拥有服务器管理的数据,不应与其他守护进程共用。(例如,使用 nobody 用户就不是好主意。)不建议将可执行文件安装为由该用户所有,因为系统一旦被攻破,就可能修改自己的二进制文件。 @@ -32,7 +32,7 @@ - 在做任何事情之前,必须先在磁盘上初始化一个数据库存储区域。我们把它称为数据库集簇。(SQL 标准使用术语 catalog cluster。)数据库集簇是由一个正在运行的数据库服务器实例管理的一组数据库。初始化之后,数据库集簇中会包含一个名为postgres的数据库,作为供工具、用户和第三方应用使用的默认数据库。数据库服务器本身并不要求该postgres数据库存在,但许多外部工具程序都假定它存在。初始化期间,集簇中还会创建另一个数据库,名为template1。顾名思义,它会作为后续新建数据库的模板;不应将它用于实际工作。(关于在集簇中创建新数据库的信息,见。) + 在做任何事情之前,必须先在磁盘上初始化一个数据库存储区域。我们把它称为数据库集簇。(SQL 标准使用术语目录集簇(catalog cluster)。)数据库集簇是由一个正在运行的数据库服务器实例管理的一组数据库。初始化之后,数据库集簇中会包含一个名为postgres的数据库,作为供工具、用户和第三方应用使用的默认数据库。数据库服务器本身并不要求该postgres数据库存在,但许多外部工具程序都假定它存在。初始化期间,集簇中还会创建另一个数据库,名为template1。顾名思义,它会作为后续新建数据库的模板;不应将它用于实际工作。(关于在集簇中创建新数据库的信息,见。) 从文件系统角度看,数据库集簇就是一个目录,所有数据都存储在其下。我们将它称为数据目录数据区域。数据存放位置完全由你决定,没有默认值;常用位置包括 /usr/local/pgsql/data/var/lib/pgsql/data。要初始化数据库集簇,请使用命令 initdb该命令随以下产品安装:PostgreSQL。数据库集簇在文件系统中的目标位置通过 选项指定,例如: @@ -157,14 +157,14 @@ su postgres -c 'pg_ctl start -D /usr/local/pgsql/data -l serverlog' 对于FreeBSD,请查看PostgreSQL源码发布包中的contrib/start-scripts/freebsd文件。 - FreeBSDstart script + FreeBSD启动脚本 OpenBSD上,把以下内容加入/etc/rc.local: - OpenBSDstart script + OpenBSD启动脚本 if [ -x /usr/local/pgsql/bin/pg_ctl -a -x /usr/local/pgsql/bin/postgres ]; then su -l postgres -c '/usr/local/pgsql/bin/pg_ctl start -s -l /var/postgresql/log -D /usr/local/pgsql/data' @@ -177,7 +177,7 @@ fi Linux系统上,可以把 - Linuxstart script + Linux启动脚本 /usr/local/pgsql/bin/pg_ctl start -l logfile -D /usr/local/pgsql/data @@ -216,14 +216,14 @@ WantedBy=multi-user.target NetBSD上,可根据偏好使用FreeBSDLinux的启动脚本。 - NetBSDstart script + NetBSD启动脚本 Solaris上,创建一个名为/etc/init.d/postgresql的文件,其中包含以下内容: - Solarisstart script + Solaris启动脚本 su - postgres -c "/usr/local/pgsql/bin/pg_ctl start -l logfile -D /usr/local/pgsql/data" @@ -310,7 +310,7 @@ psql: could not connect to server: No such file or directory 管理内核资源 - PostgreSQL有时会耗尽操作系统的各种资源限制,尤其是在同一系统上运行多个服务器副本,或在非常大型的安装环境中时更是如此。本节解释PostgreSQL使用的内核资源,以及你可以采取哪些步骤来解决与内核资源消耗相关的问题。 + PostgreSQL有时会达到操作系统的各种资源上限,尤其是在同一系统上运行多个服务器实例,或在非常大型的安装环境中时更是如此。本节解释PostgreSQL使用的内核资源,以及你可以采取哪些步骤来解决与内核资源消耗相关的问题。 @@ -337,7 +337,7 @@ psql: could not connect to server: No such file or directory - System V IPC 功能通常受系统范围的分配限制约束。当PostgreSQL超出这些限制之一时,服务器会拒绝启动,并留下带有指导性的错误消息,说明问题所在以及应如何处理(另见)。相关内核参数在不同系统上的命名基本一致,给出了概览;不过,设置它们的方法却各不相同。下面给出一些平台上的建议。 + System V IPC 功能通常受系统范围的分配限制约束。当PostgreSQL超出这些限制之一时,服务器会拒绝启动,并应留下带有指导性的错误消息,说明问题所在以及应如何处理(另见)。相关内核参数在不同系统上的命名基本一致,给出了概览;不过,设置它们的方法却各不相同。下面给出一些平台上的建议。
@@ -357,7 +357,7 @@ psql: could not connect to server: No such file or directory SHMMAX 共享内存段的最大尺寸(字节) - 至少 1kB,但是默认值通常要高一些 + 至少 1kB,但是默认值通常高得多 @@ -432,7 +432,7 @@ psql: could not connect to server: No such file or directory - 与semaphore undo有关的其他各种设置,如SEMMNUSEMUME,不会影响PostgreSQL。 + 与信号量撤销有关的其他各种设置,如SEMMNUSEMUME,不会影响PostgreSQL 使用 POSIX 信号量时,所需数量与 System V 相同,即每个允许的连接()、自动清理工作进程()和后台进程()各需一个信号量。在优先使用此实现的平台上,POSIX 信号量数量没有特定的内核限制。 @@ -456,11 +456,13 @@ psql: could not connect to server: No such file or directory FreeBSDIPC 配置 - 要更改默认 IPC 设置,可以使用 sysctlloader 接口。可以通过 sysctl 设置以下参数: + + 可以使用sysctlloader接口更改默认 IPC 配置。下列参数可用sysctl设置: # sysctl kern.ipc.shmall=32768 # sysctl kern.ipc.shmmax=134217728 -要让这些设置在重启后仍然生效,请修改 /etc/sysctl.conf。 + + 要让这些设置在重启之后也保持,请修改/etc/sysctl.conf 这些信号量相关设置对于 sysctl 是只读的;设置它们时,可修改 /boot/loader.conf: @@ -632,7 +634,9 @@ project.max-msg-ids=(priv,4096,deny) - 此外,如果你正在某个区(zone)中运行 PostgreSQL,可能也需要提高该区的资源使用限制。关于 projectsprctl 的更多信息,请参见 System Administrator's Guide 中的“Chapter2: Projects and Tasks”。 + + 此外,如果你正在某个区(zone)中运行PostgreSQL,可能也需要提高该区的资源使用限制。关于projectsprctl的更多信息,请参见System Administrator's Guide中的 "Chapter 2: Projects and Tasks"。 + @@ -666,7 +670,7 @@ WARNING: could not remove shared memory segment "/PostgreSQL.1450751626": No su - 用户注销可能会作为维护作业的一部分发生,也可能在管理员以postgres用户或类似名称登录时手工触发,因此通常很难彻底防止。 + 用户注销可能会作为维护作业的一部分发生,也可能在管理员以postgres用户登录或执行类似操作时手工触发,因此通常很难彻底防止。 @@ -737,7 +741,7 @@ default:\ - 另一个在支持大量客户端连接时可能需要关注的内核限制,是套接字连接队列的最大长度。如果在很短时间内到达的连接请求超过了这个数量,那么其中一些请求可能会在主管服务器进程来得及处理之前就被拒绝,于是客户端会收到不太有帮助的连接失败错误,例如Resource temporarily unavailableConnection refused。在许多平台上,默认队列长度限制是 128。要提高它,请通过sysctl调整相应的内核参数,然后重新启动主管服务器进程。该参数在不同系统上的名称不同:在 Linux 上是net.core.somaxconn,在较新的 FreeBSD 上是kern.ipc.soacceptqueue,在 macOS 和其他 BSD 变体上是kern.ipc.somaxconn。 + 另一个在支持大量客户端连接时可能需要关注的内核限制,是套接字连接队列的最大长度。如果在很短时间内到达的连接请求超过了这个数量,那么其中一些请求可能会在postmaster来得及处理之前就被拒绝,于是客户端会收到不太有帮助的连接失败错误,例如Resource temporarily unavailableConnection refused。在许多平台上,默认队列长度限制是 128。要提高它,请通过sysctl调整相应的内核参数,然后重新启动postmaster。该参数在不同系统上的名称不同:在 Linux 上是net.core.somaxconn,在较新的 FreeBSD 上是kern.ipc.soacceptqueue,在 macOS 和其他 BSD 变体上是kern.ipc.somaxconn @@ -745,7 +749,7 @@ default:\ Linux 内存过量分配 - memory overcommit + 内存过量分配 @@ -753,7 +757,7 @@ default:\ - overcommit + 过量分配 在 Linux 2.4 及更高版本中,默认的虚拟内存行为对 PostgreSQL 并非最佳。由于内核实现内存过量分配的方式,如果 PostgreSQL 或其他进程的内存需求导致系统耗尽虚拟内存,内核可能会终止 PostgreSQL 的 postmaster(主管服务器进程)。 @@ -770,7 +774,7 @@ Out of Memory: Killed process 12345 (postgres). 避免该问题的一种办法,是让PostgreSQL运行在一台你能确定不会被其他进程耗尽内存的机器上。如果内存紧张,增加操作系统交换空间也有助于避免这个问题,因为内存不足(OOM)杀手只有在物理内存和交换空间都耗尽时才会被触发。 - 如果导致系统耗尽内存的正是 PostgreSQL 自身,那么你可以通过调整配置来避免该问题。在某些情况下,调低与内存相关的配置参数会有帮助,尤其是 shared_bufferswork_mem。在其他情况下,允许数据库服务器接受过多连接也可能导致这一问题。很多时候,更好的做法是减小 max_connections,并转而使用外部连接池软件。 + 如果导致系统耗尽内存的正是 PostgreSQL 自身,那么你可以通过调整配置来避免该问题。在某些情况下,调低与内存相关的配置参数会有帮助,尤其是 shared_bufferswork_mem。在其他情况下,允许数据库服务器接受过多连接也可能导致这一问题。很多时候,更好的做法可能是减小 max_connections,并转而使用外部连接池软件。 在 Linux 2.6 及更高版本中,可以修改内核的行为,使其不会过量分配内存。虽然此设置无法完全阻止 OOM 杀手 被调用,但会显著降低发生概率,从而使系统行为更健壮。方法是选择严格的过量分配模式,使用以下命令:sysctl: @@ -779,12 +783,26 @@ sysctl -w vm.overcommit_memory=2 或者在以下文件中加入等效条目:/etc/sysctl.conf。你可能还希望修改相关设置 vm.overcommit_ratio。详细信息参见内核文档文件 - 另一种方法不要求改变 vm.overcommit_memory,但也可与该设置的修改结合使用:将 postmaster 进程特有的OOM score adjustment值设为 -1000,从而保证它不会成为 OOM 杀手 的目标。最简单的方法是执行: + + 另一种方法可在修改或不修改 vm.overcommit_memory 的情况下使用: + 把 postmaster 进程专属的OOM 评分调整值设为 -1000, + 从而保证它不会成为 OOM 杀手的目标。最简单的做法是在 postmaster + 启动脚本中、调用 postmaster 之前执行: + echo -1000 > /proc/self/oom_score_adj -执行位置是在 postmaster 的启动脚本中,紧接在调用 postmaster 之前。注意,必须以 root 身份执行此操作,否则不会生效;因此,在 root 所有的启动脚本中执行最方便。如果这样做,还应在启动脚本中调用 postmaster 之前设置以下环境变量: + + 请注意,这个操作必须以 root 身份完成,否则不会生效;因此,由 root 拥有的启动脚本是最容易执行该操作的位置。 + 如果这样做,还应在调用 postmaster 之前,在启动脚本中设置以下环境变量: + export PG_OOM_ADJUST_FILE=/proc/self/oom_score_adj export PG_OOM_ADJUST_VALUE=0 -这些设置会使 postmaster 子进程以正常的 OOM 分数调整值零运行,因此 OOM 杀手 仍可在需要时将它们作为目标。你可以为以下变量使用其他值:PG_OOM_ADJUST_VALUE,以使子进程采用其他 OOM 分数调整值。(PG_OOM_ADJUST_VALUE 也可以省略,此时默认为零。)如果不设置 PG_OOM_ADJUST_FILE,子进程将使用与 postmaster 相同的 OOM 分数调整值,这并不明智,因为这样设置的目的就是确保 postmaster 获得优先保护。 + + 这些设置会使 postmaster 子进程以常规的 OOM 评分调整值零运行,以便 OOM 杀手在需要时仍可将它们作为目标。 + 如果希望子进程以其他 OOM 评分调整值运行,也可以为 PG_OOM_ADJUST_VALUE 指定其他值。 + (也可以省略 PG_OOM_ADJUST_VALUE,此时默认为零。) + 如果不设置 PG_OOM_ADJUST_FILE,子进程就会和 postmaster 使用相同的 OOM 评分调整值, + 这并不明智,因为这样做的目的正是确保 postmaster 获得优先保护。 + 较旧的 Linux 内核不提供 /proc/self/oom_score_adj,但可能提供名为 /proc/self/oom_adj 的同类功能的早期版本。其工作方式相同,只是禁用值为 -17 而非 -1000 @@ -814,8 +832,9 @@ $ grep Huge /proc/meminfo - 你可能还需要授予数据库服务器的操作系统用户使用大页的权限,例如通过sysctl设置vm.hugetlb_shm_group,以及/或者授予其使用ulimit -l锁定内存的权限。 - + 可能还需要通过 sysctl 设置 vm.hugetlb_shm_group, + 授予数据库服务器的操作系统用户使用大页的权限,以及/或者通过 ulimit -l 授予其锁定内存的权限。 + PostgreSQL 对大页的默认行为是:只要可能就使用它们;如果失败,则回退到普通页。要强制使用大页,可以在 postgresql.conf 中将 设为 on。请注意,在这种设置下,如果没有足够的大页可用,PostgreSQL 将无法启动。 @@ -841,7 +860,7 @@ $ grep Huge /proc/meminfo 这是智能关闭模式。 收到SIGTERM后,服务器禁止新连接,但允许现有会话正常结束工作。 - 仅在所有会话终止后才会关闭。如果服务器在请求智能关闭时处于恢复状态, + 仅在所有会话终止后才会关闭。如果服务器处于在线备份模式,还会等待该模式结束。在线备份模式生效期间,仍允许新的超级用户连接(这一例外允许超级用户连接以结束在线备份模式),但不允许其他新连接。如果服务器在请求智能关闭时处于恢复状态, 则只有在所有常规会话终止后,恢复和流复制才会停止。 @@ -854,7 +873,7 @@ $ grep Huge /proc/meminfo 这是快速关闭模式。 服务器禁止新连接并向所有现有服务器进程发送SIGTERM, 这将导致它们中止当前事务并迅速退出。然后等待所有服务器进程退出,最后关闭。 - + 如果服务器处于在线备份模式,该模式将被终止,导致备份不可用。 @@ -887,12 +906,12 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`升级 PostgreSQL 集簇 - upgrading + 升级 - version - compatibility + 版本 + 兼容性 @@ -907,10 +926,11 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` - 对于 PostgreSQL版本,内部数据存储格式可能会发生变化,因此升级会更复杂。将数据迁移到新的大版本的传统方法是转储并重新载入数据库,不过这可能比较慢。更快的方法是 。此外,也可以使用复制方法,如下所述。 + + 对于PostgreSQL版本,内部数据存储格式可能会发生变化,因此升级会复杂得多。将数据迁移到新的主版本的传统方法是转储并重新载入数据库,不过这可能比较慢。更快的方法是。此外,也可以使用复制方法,如下所述。 - 新的主版本通常还会引入一些用户可见的不兼容变化,因此应用程序可能也需要做出修改。所有用户可见的变化都列在发行说明()中;请特别留意标为Migration的小节。虽然你可以从一个主版本直接升级到另一个主版本,而不必逐个升级中间版本,但仍应阅读所有中间版本的主版本发行说明。 + 新的主版本通常还会引入一些用户可见的不兼容变化,因此应用程序可能也需要做出修改。所有用户可见的变化都列在发行说明()中;请特别留意标为迁移(Migration)的小节。虽然你可以从一个主版本直接升级到另一个主版本,而不必逐个升级中间版本,但仍应阅读所有中间版本的主版本发行说明。 @@ -969,7 +989,7 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` - 这涉及以后端函数 API 为代表的变更,该 API 使用 C 语言编写。这类变更会影响那些深入引用服务器内部后端函数的代码。 + 这涉及使用 C 语言编写的后端函数 API 的变更。这类变更会影响那些深入引用服务器内部后端函数的代码。 @@ -979,7 +999,7 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` 通过<application>pg_dumpall</application>升级数据 - 一种升级方法是从某个大版本的 PostgreSQL 转储数据,再在另一个版本中重新载入。要这样做,必须使用逻辑备份工具,例如 pg_dumpall;文件系统级备份方法不起作用。(系统中有相应检查,会阻止你在不兼容版本的 PostgreSQL 上使用数据目录,因此尝试用错误版本的服务器启动某个数据目录,不会造成严重损害。) + 一种升级方法是从某个主版本的 PostgreSQL 转储数据,再在另一个版本中重新载入。要这样做,必须使用逻辑备份工具,例如 pg_dumpall;文件系统级备份方法不起作用。(系统中有相应检查,会阻止你在不兼容版本的 PostgreSQL 上使用数据目录,因此尝试用错误版本的服务器启动某个数据目录,不会造成严重损害。) 建议使用来自较新版本 PostgreSQLpg_dumppg_dumpall 程序,以利用这些程序可能包含的改进。当前版本的转储程序可以读取从 8.0 起任意服务器版本的数据。 @@ -991,13 +1011,13 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` - 如果是在制作备份,请确认数据库此时没有正在进行更新。这不会影响备份的一致性,但那些变更当然不会包含在备份中。必要时,可修改/usr/local/pgsql/data/pg_hba.conf中的访问权限(或采用等效方法),禁止除你之外的其他人访问数据库。有关访问控制的更多信息见。 + 如果是在制作备份,请确认数据库此时没有正在进行更新。更新操作不会影响备份的完整性,但那些变更当然不会包含在备份中。必要时,可修改/usr/local/pgsql/data/pg_hba.conf(或等效文件)中的访问权限,禁止除你之外的其他人访问数据库。有关访问控制的更多信息见 pg_dumpall - use during upgrade + 在升级期间使用 要备份整个数据库安装,请输入: @@ -1018,7 +1038,7 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` pg_ctl stop - 在那些会自动启动PostgreSQL的系统上,可能已经有某个启动脚本能完成同样的工作。例如,在Red Hat Linux系统上,也许下面这条命令就可以: + 在那些会在开机时自动启动PostgreSQL的系统上,可能已经有某个启动脚本能完成同样的工作。例如,在Red Hat Linux系统上,也许下面这条命令就可以: /etc/rc.d/init.d/postgresql stop @@ -1100,7 +1120,7 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 通过复制升级数据 - 也可以使用某些复制方法,例如 Slony,创建一个运行较新版本 PostgreSQL 的备库。之所以可行,是因为 Slony 支持不同大版本 PostgreSQL 之间进行复制。该备库可以与旧服务器部署在同一台机器上,也可以部署在不同机器上。一旦它与主库(运行旧版本 PostgreSQL)同步,就可以切换主备角色,让备库成为主库,并关闭旧的数据库实例。这种计划内切换只会为升级带来几秒钟的停机时间。 + 也可以使用某些复制方法,例如 Slony,创建一个运行较新版本 PostgreSQL 的备库。之所以可行,是因为 Slony 支持不同主版本 PostgreSQL 之间进行复制。该备库可以与旧服务器部署在同一台机器上,也可以部署在不同机器上。一旦它与主库(运行旧版本 PostgreSQL)同步,就可以切换主备角色,让备库成为主库,并关闭旧的数据库实例。这种计划内切换只会为升级带来几秒钟的停机时间。 @@ -1135,7 +1155,7 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 - PostgreSQL提供了多个层次的加密,并在防止数据因数据库服务器被盗、不可靠的管理员或不安全网络等原因而泄露方面提供了很高的灵活性。对于医疗记录、金融交易等敏感数据,加密也可能是合规要求的一部分。 + PostgreSQL提供了多个层次的加密,并在防止数据因数据库服务器被盗、不诚实的管理员或不安全网络等原因而泄露方面提供了很高的灵活性。为了保护医疗记录、金融交易等敏感数据,也可能需要使用加密。 @@ -1242,7 +1262,7 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 - 使用NULL-SHANULL-MD5密码套件,可以在几乎没有加密开销的情况下完成认证。不过,中间人仍然能够读取并转发客户端与服务器之间的通信。此外,与认证的开销相比,加密开销本身通常很小。基于这些原因,不建议使用 NULL 密码套件。 + 使用NULL-SHANULL-MD5密码套件,可以在没有加密开销的情况下完成认证。不过,中间人仍然能够读取并转发客户端与服务器之间的通信。此外,与认证的开销相比,加密开销本身很小。基于这些原因,不建议使用 NULL 密码套件。 @@ -1256,7 +1276,9 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 如果私钥受口令保护,服务器会提示输入口令,并在输入之前一直等待,不会启动。使用口令也会禁用无需重启服务器即可更改 SSL 配置的能力。此外,在 Windows 上完全不能使用受口令保护的私钥。 - server.crt 中的第一个证书必须是服务器证书,因为它必须与服务器私钥匹配。也可以将中间证书颁发机构的证书追加到此文件中。这样可以避免在客户端上存储中间证书,前提是根证书和中间证书使用 v3_ca 扩展创建。(这会将证书的基本约束 CA 设为 true。)这使中间证书的到期处理更容易。 + + server.crt中的第一个证书必须是服务器证书,因为它必须与服务器私钥相匹配。中间证书颁发机构的证书也可以追加到该文件中。假设根证书和中间证书是使用v3_ca 扩展创建的(这会将证书的 CA 基本约束设为 true),这样做就可以避免在客户端上存储中间证书。同时,这也使中间证书更容易单独过期。 + 无需把根证书加入server.crt。相反,客户端必须持有服务器证书链对应的根证书。 @@ -1462,17 +1484,19 @@ ssh -L 63333:db.foo.com:5432 joe@shell.foo.com - 在 <systemitem class="osname">Windows</systemitem> 上注册 <application>Event Log</application> + 在<systemitem class="osname">Windows</systemitem>上注册<application>事件日志</application> 事件日志 事件日志 - 要向操作系统注册 Windows - event log 库,请执行以下命令: + + 要向操作系统注册一个Windows事件日志库,请执行以下命令: + regsvr32 pgsql_library_directory/pgevent.dll -这会创建事件查看器使用的注册表条目,条目位于默认事件源之下,其名称为 PostgreSQL。 + + 这会创建被事件查看器使用的注册表项,默认事件源命名为PostgreSQL @@ -1482,7 +1506,9 @@ ssh -L 63333:db.foo.com:5432 joe@shell.foo.com - 要从操作系统中注销 event log 库,请执行以下命令: + + 要从操作系统中注销该事件日志库,请执行以下命令: + regsvr32 /u [/i:event_source_name] pgsql_library_directory/pgevent.dll diff --git a/zh/10/spgist.sgml b/zh/10/spgist.sgml index ed1f8074..55492e6a 100644 --- a/zh/10/spgist.sgml +++ b/zh/10/spgist.sgml @@ -4,7 +4,7 @@ SP-GiST 索引 - index + 索引 SP-GiST @@ -12,7 +12,7 @@ 简介 - SP-GiST 是 space-partitioned GiST + SP-GiST 是空间分区 GiST 的缩写。SP-GiST 支持分区搜索树,这使得开发多种不同的 非平衡数据结构成为可能,例如四叉树、k-d 树以及基数树(trie)。这些结构 的共同特征是,它们会反复将搜索空间划分为不必等大的分区。与这种划分规则良 @@ -48,7 +48,7 @@ 内置操作符类 - 核心 PostgreSQL 发行版包含了 + PostgreSQL 核心发行版包含了 SP-GiST 操作符类,如 所示。 @@ -59,7 +59,7 @@ 名称 - 索引数据类型 + 被索引数据类型 可索引操作符 @@ -141,11 +141,11 @@ - SP-GiST 核心代码会处理空项。虽然 - SP-GiST 索引确实会为被索引列中的空值存储项,但这一 - 点对索引操作符类代码是隐藏的:不会有空的索引项或搜索条件传递给操作符类 - 方法。(这里假定 SP-GiST 操作符是严格的,因此对空 - 值不可能成功。)因此,这里不再进一步讨论空值。 + SP-GiST 核心代码负责处理值为 null 的索引项。虽然 + SP-GiST 索引会为被索引列中的 null 值存储索引项, + 但索引操作符类代码看不到这些项:值为 null 的索引项或搜索条件绝不会传给 + 操作符类方法。(这里假定 SP-GiST 操作符是严格的, + 因此对 null 值不可能返回真。)所以这里不再讨论 null 值。 @@ -154,7 +154,7 @@ internal 参数,第一个参数是指向某个 C 结构体的指针,其中包 含该支持方法的输入值;第二个参数也是指向某个 C 结构体的指针,方法必须将输 出值写入其中。四个必需方法只返回 void,因为它们的全部结果 - 都体现在输出结构体中;但 leaf_consistent 会返回一个 + 都体现在输出结构体中;但 leaf_consistent 还返回一个 boolean 结果。这些方法不得修改其输入结构体中的任何字段。在 所有情况下,调用用户定义方法之前,输出结构体都会先被清零。 @@ -173,15 +173,15 @@ CREATE FUNCTION my_config(internal, internal) RETURNS void ... 第一个参数是一个指向spgConfigInC 结构体的指针,其中包含该函数的输入数据。第二个参数是一个指向spgConfigOutC 结构体的指针,函数必须将结果数据填入其中。 typedef struct spgConfigIn { - Oid attType; /* Data type to be indexed */ + Oid attType; /* 要被索引的数据类型 */ } spgConfigIn; typedef struct spgConfigOut { - Oid prefixType; /* Data type of inner-tuple prefixes */ - Oid labelType; /* Data type of inner-tuple node labels */ - bool canReturnData; /* Opclass can reconstruct original data */ - bool longValuesOK; /* Opclass can cope with values > 1 page */ + Oid prefixType; /* 内部元组前缀的数据类型 */ + Oid labelType; /* 内部元组结点标签的数据类型 */ + bool canReturnData; /* 操作符类能重建原始数据 */ + bool longValuesOK; /* 操作符类能处理大小 > 1 页的值 */ } spgConfigOut; @@ -218,7 +218,7 @@ typedef struct spgChooseIn int level; /* 当前层级(从零开始计) */ /* 来自当前内部元组的数据 */ - bool allTheSame; /* 元组被标记为 all-the-same? */ + bool allTheSame; /* 元组被标记为全部相同? */ bool hasPrefix; /* 元组有前缀? */ Datum prefixDatum; /* 如果有,前缀值 */ int nNodes; /* 内部元组中的结点数 */ @@ -414,33 +414,33 @@ CREATE FUNCTION my_inner_consistent(internal, internal) RETURNS void ... 第一个参数是一个指向spgInnerConsistentInC 结构体的指针,其中包含该函数的输入数据。第二个参数是一个指向spgInnerConsistentOutC 结构体的指针,函数必须将结果数据填入其中。 typedef struct spgInnerConsistentIn { - ScanKey scankeys; /* array of operators and comparison values */ - int nkeys; /* length of array */ - - Datum reconstructedValue; /* value reconstructed at parent */ - void *traversalValue; /* opclass-specific traverse value */ - MemoryContext traversalMemoryContext; /* put new traverse values here */ - int level; /* current level (counting from zero) */ - bool returnData; /* original data must be returned? */ - - /* Data from current inner tuple */ - bool allTheSame; /* tuple is marked all-the-same? */ - bool hasPrefix; /* tuple has a prefix? */ - Datum prefixDatum; /* if so, the prefix value */ - int nNodes; /* number of nodes in the inner tuple */ - Datum *nodeLabels; /* node label values (NULL if none) */ + ScanKey scankeys; /* 操作符和比较值的数组 */ + int nkeys; /* 数组长度 */ + + Datum reconstructedValue; /* 在父元组处重建的值 */ + void *traversalValue; /* 操作符类特定的遍历值 */ + MemoryContext traversalMemoryContext; /* 将新的遍历值放在这里 */ + int level; /* 当前层级(从零开始计) */ + bool returnData; /* 必须返回原始数据? */ + + /* 来自当前内部元组的数据 */ + bool allTheSame; /* 元组被标记为全部相同? */ + bool hasPrefix; /* 元组有前缀? */ + Datum prefixDatum; /* 如果有,前缀值 */ + int nNodes; /* 内部元组中的结点数 */ + Datum *nodeLabels; /* 结点标签值(如果没有则为 NULL) */ } spgInnerConsistentIn; typedef struct spgInnerConsistentOut { - int nNodes; /* number of child nodes to be visited */ - int *nodeNumbers; /* their indexes in the node array */ - int *levelAdds; /* increment level by this much for each */ - Datum *reconstructedValues; /* associated reconstructed values */ - void **traversalValues; /* opclass-specific traverse values */ + int nNodes; /* 需要访问的子结点数 */ + int *nodeNumbers; /* 它们在结点数组中的索引 */ + int *levelAdds; /* 对每个结点层级增加这么多 */ + Datum *reconstructedValues; /* 关联的重建值 */ + void **traversalValues; /* 操作符类特定的遍历值 */ } spgInnerConsistentOut; -数组scankeys的长度为nkeys,它描述索引搜索条件。这些条件用 AND 组合 — 只有满足全部条件的索引项才是我们关心的。(注意,nkeys= 0 表示所有索引项都满足该查询。)通常 consistent 函数只关心sk_strategysk_argument字段,它们分别给出可索引操作符和比较值。特别地,无需检查sk_flags以判断比较值是否为 NULL,因为 SP-GiST 核心代码会过滤掉此类条件。reconstructedValue是为父元组重建的值;以下情况下它为(Datum) 0:位于根层,或者inner_consistent函数没有在父层提供该值。traversalValue是指向任意遍历数据的指针,这些数据由上一次调用inner_consistent处理父索引元组时向下传递;在根层时则为 NULL。traversalMemoryContext是存放输出遍历值(见下文)的内存上下文。level是当前内部元组的层级,根层为零。returnDatatrue表示本查询需要重建数据;这要求config函数明确设置了canReturnData。 - allTheSame为真,表示当前内部元组被标记为all-the-same;在这种情况下,所有结点都具有相同的标签(如果有),因此要么全部匹配该查询,要么全部不匹配(参见)。 +数组scankeys的长度为nkeys,它描述索引搜索条件。这些条件用 AND 组合 — 只有满足全部条件的索引项才是我们关心的。(注意,nkeys= 0 表示所有索引项都满足该查询。)通常一致性检查函数只关心每个数组元素的sk_strategysk_argument字段,它们分别给出可索引操作符和比较值。特别地,无需检查sk_flags以判断比较值是否为 NULL,因为 SP-GiST 核心代码会过滤掉此类条件。reconstructedValue是为父元组重建的值;以下情况下它为(Datum) 0:位于根层,或者inner_consistent函数没有在父层提供该值。traversalValue是指向任意遍历数据的指针,这些数据由上一次调用inner_consistent处理父索引元组时向下传递;在根层时则为 NULL。traversalMemoryContext是存放输出遍历值(见下文)的内存上下文。level是当前内部元组的层级,根层为零。returnDatatrue表示本查询需要重建数据;这要求config函数将canReturnData设为真。 + allTheSame为真,表示当前内部元组被标记为全部相同;在这种情况下,所有结点都具有相同的标签(如果有),因此要么全部匹配该查询,要么全部不匹配(参见)。 hasPrefix为真时,表示当前内部元组包含前缀;若是如此,prefixDatum就是该前缀值。nNodes是内部元组中包含的子结点数量,而nodeLabels是它们的标签值数组;如果结点没有标签,则为 NULL。 @@ -481,23 +481,23 @@ CREATE FUNCTION my_leaf_consistent(internal, internal) RETURNS bool ... 第一个参数是一个指向spgLeafConsistentInC 结构体的指针,其中包含该函数的输入数据。第二个参数是一个指向spgLeafConsistentOutC 结构体的指针,函数必须将结果数据填入其中。 typedef struct spgLeafConsistentIn { - ScanKey scankeys; /* array of operators and comparison values */ - int nkeys; /* length of array */ + ScanKey scankeys; /* 操作符和比较值的数组 */ + int nkeys; /* 数组长度 */ - Datum reconstructedValue; /* value reconstructed at parent */ - void *traversalValue; /* opclass-specific traverse value */ - int level; /* current level (counting from zero) */ - bool returnData; /* original data must be returned? */ + Datum reconstructedValue; /* 在父元组处重建的值 */ + void *traversalValue; /* 操作符类特定的遍历值 */ + int level; /* 当前层级(从零开始计) */ + bool returnData; /* 必须返回原始数据? */ - Datum leafDatum; /* datum in leaf tuple */ + Datum leafDatum; /* 叶子元组中的 datum */ } spgLeafConsistentIn; typedef struct spgLeafConsistentOut { - Datum leafValue; /* reconstructed original data, if any */ - bool recheck; /* set true if operator must be rechecked */ + Datum leafValue; /* 重建出的原始数据(如果有) */ + bool recheck; /* 如果必须重新检查操作符则设为真 */ } spgLeafConsistentOut; -数组scankeys的长度为nkeys,它描述索引搜索条件。这些条件用 AND 组合 — 只有满足全部条件的索引项才满足该查询。(注意,nkeys= 0 表示所有索引项都满足该查询。)通常 consistent 函数只关心sk_strategysk_argument字段,它们分别给出可索引操作符和比较值。特别地,无需检查sk_flags以判断比较值是否为 NULL,因为 SP-GiST 核心代码会过滤掉此类条件。reconstructedValue是为父元组重建的值;以下情况下它为(Datum) 0:位于根层,或者inner_consistent函数没有在父层提供该值。traversalValue是指向任意遍历数据的指针,这些数据由上一次调用inner_consistent处理父索引元组时向下传递;在根层时则为 NULL。level是当前叶子元组的层级,根层为零。returnDatatrue表示本查询需要重建数据;这要求config函数明确设置了canReturnData。 +数组scankeys的长度为nkeys,它描述索引搜索条件。这些条件用 AND 组合 — 只有满足全部条件的索引项才满足该查询。(注意,nkeys= 0 表示所有索引项都满足该查询。)通常一致性检查函数只关心每个数组元素的sk_strategysk_argument字段,它们分别给出可索引操作符和比较值。特别地,无需检查sk_flags以判断比较值是否为 NULL,因为 SP-GiST 核心代码会过滤掉此类条件。reconstructedValue是为父元组重建的值;以下情况下它为(Datum) 0:位于根层,或者inner_consistent函数没有在父层提供该值。traversalValue是指向任意遍历数据的指针,这些数据由上一次调用inner_consistent处理父索引元组时向下传递;在根层时则为 NULL。level是当前叶子元组的层级,根层为零。returnDatatrue表示本查询需要重建数据;这要求config函数将canReturnData设为真。 leafDatum是当前叶子元组中存储的键值。 @@ -525,7 +525,7 @@ typedef struct spgLeafConsistentOut - 如果被索引列属于可应用排序规则的数据类型,则索引排序规则会通过标准的 + 如果被索引列属于支持排序规则的数据类型,则索引排序规则会通过标准的 PG_GET_COLLATION() 机制传递给所有支持方法。 @@ -603,7 +603,7 @@ typedef struct spgLeafConsistentOut - <quote>All-the-same</quote> 内部元组 + <quote>全部相同</quote>的内部元组 picksplit 无法把提供的叶子值划分为至少两个结点 diff --git a/zh/10/spi.sgml b/zh/10/spi.sgml index da1a43ce..69478464 100644 --- a/zh/10/spi.sgml +++ b/zh/10/spi.sgml @@ -74,7 +74,7 @@ int SPI_connect(void) SPI_connect 会为某次过程调用打开到 SPI 管理器 的连接。如果要通过 SPI 执行命令,就必须调用此函数。不过,有些 SPI - 实用函数可以在未连接的过程中调用。 + 辅助函数可以在未连接的过程中调用。 @@ -95,7 +95,7 @@ int SPI_connect(void) SPI_ERROR_CONNECT - 出错时 + 发生错误时 @@ -267,11 +267,11 @@ SPI_execute("INSERT INTO foo SELECT * FROM bar RETURNING *", false, 5); typedef struct { - MemoryContext tuptabcxt; /* memory context of result table */ - uint64 alloced; /* number of alloced vals */ - uint64 free; /* number of free vals */ - TupleDesc tupdesc; /* row descriptor */ - HeapTuple *vals; /* rows */ + MemoryContext tuptabcxt; /* 结果表的内存上下文 */ + uint64 alloced; /* 已分配的 vals 数量 */ + uint64 free; /* 空闲的 vals 数量 */ + TupleDesc tupdesc; /* 行描述符 */ + HeapTuple *vals; /* 行 */ } SPITupleTable; vals 是一个指向行的指针数组。(有效项数为 SPI_processed。) @@ -483,7 +483,7 @@ typedef struct 所有 SPI 查询执行函数都会设置 SPI_processed 和 - SPI_tuptable(只设置指针,而不会设置结构体内容)。如果 + SPI_tuptable(只设置指针,而不更改结构体内容)。如果 需要在后续调用之后继续访问 SPI_execute 或其他查询 执行函数的结果表,请把这两个全局变量保存到过程局部变量中。 @@ -530,7 +530,7 @@ int SPI_exec(const char * command, long count< const char * command - 包含要执行命令的字符串 + 包含待执行命令的字符串 @@ -539,7 +539,7 @@ int SPI_exec(const char * command, long count< long count - 要返回的最大行数,或者用0表示没有限制 + 要返回的最大行数,或者用 0 表示不限制 @@ -601,7 +601,7 @@ int SPI_execute_with_args(const char *command, SPI_execute_plan 达到类似效果。不过,使用本函数 时,查询计划总会针对所提供的具体参数值进行定制。对于一次性查询执行,应 优先选择本函数。如果同一条命令要用许多不同参数重复执行,则两种方式孰快 - 取决于重新计划的代价与定制计划收益之间的权衡。 + 取决于重新规划的代价与定制计划收益之间的权衡。 @@ -656,9 +656,9 @@ int SPI_execute_with_args(const char *command, 如果 nullsNULL,则 - SPI_execute_with_args 会假定没有参数为 NULL。 - 否则,如果对应参数值非 NULL,则 nulls 数组中 - 的对应项应为 ' ';如果对应参数值为 NULL,则 + SPI_execute_with_args 会假定没有参数为空值。 + 否则,如果对应参数值非空值,则 nulls 数组中 + 的对应项应为 ' ';如果对应参数值为空值,则 对应项应为 'n'。(后一种情况下,对应 values 项中的实际值无关紧要。)注意, nulls 不是文本字符串,而只是一个数组,因此不 @@ -712,7 +712,7 @@ int SPI_execute_with_args(const char *command, SPI_prepare - 准备一个语句,但不执行它 + 准备一个语句,但暂不执行 @@ -791,8 +791,7 @@ SPIPlanPtr SPI_prepare(const char * command, int 返回值 - SPI_prepare 返回一个指向非空 SPIPlan - 的指针,它是表示预备语句的不透明结构体。发生错误时会返回 + SPI_prepare 返回一个非空指针,指向表示预备语句的不透明结构体 SPIPlan。发生错误时会返回 NULL,并将 SPI_result 设为 SPI_execute 所使用的那些错误码之一;但如果 commandNULL,或者 @@ -811,17 +810,16 @@ SPIPlanPtr SPI_prepare(const char * command, int SPI_execute_plan 在最初几次使用时会根据提供的参数 值生成定制计划。当同一个预备语句被使用足够多次之后, SPI_execute_plan 会构建一个通用计划;如果它的代价 - 没有比定制计划高出太多,就会开始改用通用计划,而不是每次都重新计划。如 + 没有比定制计划高出太多,就会开始改用通用计划,而不是每次都重新规划。如 果这种默认行为不合适,可以把 CURSOR_OPT_GENERIC_PLANCURSOR_OPT_CUSTOM_PLAN 标志传给 SPI_prepare_cursor,分别强制使用通用计划或定制计划。 - 尽管预备语句的主要目的在于避免重复进行解析分析和计划,但只要语句中使用 + 尽管预备语句的主要目的在于避免重复进行解析分析和规划,但只要语句中使用 的数据库对象自上次使用该预备语句以来发生了定义性(DDL)变更, - PostgreSQL 就会在再次使用前强制重新分析并重 - 新计划该语句。此外,如果 的值在两次 + PostgreSQL 就会在再次使用前强制重新分析并重新规划该语句。此外,如果 的值在两次 使用之间发生变化,该语句也会基于新的 search_path 重 新解析。(后一种行为是从 PostgreSQL 9.3 开 始引入的。)有关预备语句行为的更多信息,请参见 @@ -907,7 +905,7 @@ SPIPlanPtr SPI_prepare_cursor(const char * command, int < Oid * argtypes - 指向数组的指针,该数组包含参数数据类型的 + 一个数组指针,它指向的数组包含参数的数据类型的 OID @@ -999,7 +997,7 @@ SPIPlanPtr SPI_prepare_params(const char * command, ParserSetupHook parserSetup - 语法分析器钩子设置函数 + 解析器钩子设置函数 @@ -1214,8 +1212,8 @@ bool SPI_is_cursor_plan(SPIPlanPtr plan) 返回值 - 如果 plan 能产生游标,则返回 - true;如果不能,则返回 false,并将 + 返回 truefalse,表示 + plan 能否产生游标,同时将 SPI_result 设为零。如果无法确定答案(例如 planNULL 或无效,或者在 未连接到 SPI 时调用),则会将 SPI_result 设为合适 @@ -1287,15 +1285,14 @@ int SPI_execute_plan(SPIPlanPtr plan, Datum * - 如果nullsNULL, - 那么SPI_execute_plan会假设没有参数 - 为空值。否则,如果对应的参数值为非空, - nulls - 数组的每一个项都应该是' ';如果对应参数值为空, - 对应项应为'n'(在后 - 面的情况中,对应的values项中的值没有 - 关系)。注意nulls不是一个文本字符串, - 它只是一个数组:它不需要一个'\0'终止符。 + 如果 nullsNULL,则 + SPI_execute_plan 会假定没有参数为空值。 + 否则,如果对应参数值非空值,则 nulls 数组中 + 的对应项应为 ' ';如果对应参数值为空值,则 + 对应项应为 'n'。(后一种情况下,对应 + values 项中的实际值无关紧要。)注意, + nulls 不是文本字符串,而只是一个数组,因此不 + 需要 '\0' 终止符。 @@ -1426,7 +1423,7 @@ int SPI_execute_plan_with_paramlist(SPIPlanPtr plan, long count - 要返回的最大行数,或者用0表示没有限制 + 要返回的最大行数,或者用 0 表示不限制 @@ -1510,15 +1507,14 @@ int SPI_execp(SPIPlanPtr plan, Datum * values< - 如果nullsNULL, - 那么SPI_execp会假设没有参数 - 为空值。否则,如果对应的参数值为非空, - nulls - 数组的每一个项都应该是' ';如果对应参数值为空, - 对应项应为'n'(在后 - 面的情况中,对应的values项中的值没有 - 关系)。注意nulls不是一个文本字符串, - 它只是一个数组:它不需要一个'\0'终止符。 + 如果 nullsNULL,则 + SPI_execp 会假定没有参数为空值。 + 否则,如果对应参数值非空值,则 nulls 数组中 + 的对应项应为 ' ';如果对应参数值为空值,则 + 对应项应为 'n'。(后一种情况下,对应 + values 项中的实际值无关紧要。)注意, + nulls 不是文本字符串,而只是一个数组,因此不 + 需要 '\0' 终止符。 @@ -1527,7 +1523,7 @@ int SPI_execp(SPIPlanPtr plan, Datum * values< long count - 要返回的最大行数,或者用0表示没有限制 + 要返回的最大行数,或者用 0 表示不限制 @@ -1635,15 +1631,14 @@ Portal SPI_cursor_open(const char * name, SPIPlanPtr - 如果nullsNULL, - 那么SPI_cursor_open会假设没有参数 - 为空值。否则,如果对应的参数值为非空, - nulls - 数组的每一个项都应该是' ';如果对应参数值为空, - 对应项应为'n'(在后 - 面的情况中,对应的values项中的值没有 - 关系)。注意nulls不是一个文本字符串, - 它只是一个数组:它不需要一个'\0'终止符。 + 如果 nullsNULL,则 + SPI_cursor_open 会假定没有参数为空值。 + 否则,如果对应参数值非空值,则 nulls 数组中 + 的对应项应为 ' ';如果对应参数值为空值,则 + 对应项应为 'n'。(后一种情况下,对应 + values 项中的实际值无关紧要。)注意, + nulls 不是文本字符串,而只是一个数组,因此不 + 需要 '\0' 终止符。 @@ -1704,11 +1699,10 @@ Portal SPI_cursor_open_with_args(const char *name, - 对于一次性的查询执行,这个函数应该比 - SPI_prepare_cursor加上其后的 - SPI_cursor_open更好。如果相同的命令 - 要被用很多不同的参数执行,哪种方法更快就要取决于重做计划的 - 代价与定制计划带来的好处之间谁更有利。 + 对于一次性查询执行,应优先使用此函数,而不是先调用 + SPI_prepare_cursor 再调用 + SPI_cursor_open。如果同一条命令要用许多不同参数执行, + 哪种方法更快取决于重新规划的代价与定制计划收益之间的权衡。 @@ -1752,8 +1746,8 @@ Portal SPI_cursor_open_with_args(const char *name, Oid * argtypes - 一个长度为nargs的数组, - 包含参数的数据类型的OID + 一个长度为 nargs 的数组,包含参数数据类型的 + OID @@ -1762,8 +1756,7 @@ Portal SPI_cursor_open_with_args(const char *name, Datum * values - 一个长度为nargs的数组, - 包含实际的参数值 + 一个长度为 nargs 的数组,包含实际参数值 @@ -1772,20 +1765,19 @@ Portal SPI_cursor_open_with_args(const char *name, const char * nulls - 一个长度为nargs的数组, - 描述哪些参数为空值 + 一个长度为 nargs 的数组,用于描述哪些参数为 + 空值 - 如果nullsNULL, - 那么SPI_cursor_open_with_args会假设没有参数 - 为空值。否则,如果对应的参数值为非空, - nulls - 数组的每一个项都应该是' ';如果对应参数值为空, - 对应项应为'n'(在后 - 面的情况中,对应的values项中的值没有 - 关系)。注意nulls不是一个文本字符串, - 它只是一个数组:它不需要一个'\0'终止符。 + 如果 nullsNULL,则 + SPI_cursor_open_with_args 会假定没有参数为空值。 + 否则,如果对应参数值非空值,则 nulls 数组中 + 的对应项应为 ' ';如果对应参数值为空值,则 + 对应项应为 'n'。(后一种情况下,对应 + values 项中的实际值无关紧要。)注意, + nulls 不是文本字符串,而只是一个数组,因此不 + 需要 '\0' 终止符。 @@ -2044,7 +2036,7 @@ void SPI_cursor_fetch(Portal portal, bool forw 如果该游标的计划不是用CURSOR_OPT_SCROLL - 选项创建的,向后获取会失败。 + 选项创建的,向后获取可能失败。 @@ -2118,7 +2110,7 @@ void SPI_cursor_move(Portal portal, bool forwa 如果该游标的计划不是用CURSOR_OPT_SCROLL - 选项创建的,向后移动会失败。 + 选项创建的,向后移动可能失败。 @@ -2214,8 +2206,7 @@ void SPI_scroll_cursor_fetch(Portal portal, FetchDirectio 如果该游标的计划不是用CURSOR_OPT_SCROLL - 选项创建的,除FETCH_FORWARD之外的方向值会 - 失败。 + 选项创建的,除FETCH_FORWARD之外的方向值可能失败。 @@ -2312,8 +2303,7 @@ void SPI_scroll_cursor_move(Portal portal, FetchDirection 如果该游标的计划不是用CURSOR_OPT_SCROLL - 选项创建的,除FETCH_FORWARD之外的方向值会 - 失败。 + 选项创建的,除FETCH_FORWARD之外的方向值可能失败。 @@ -2488,7 +2478,8 @@ SPIPlanPtr SPI_saveplan(SPIPlanPtr plan) 返回值 - 返回指向复制后的语句的指针;如果失败,则返回 NULL。出错时,SPI_result 设置如下: + 复制后语句的指针;如果未成功则返回NULL。 + 错误时,SPI_result会被这样设置: @@ -2534,8 +2525,8 @@ SPIPlanPtr SPI_saveplan(SPIPlanPtr plan) SPI_register_relation - ephemeral named relation - registering with SPI + 临时命名关系 + 向 SPI 注册 @@ -2559,7 +2550,7 @@ int SPI_register_relation(EphemeralNamedRelation enr) SPI_register_relation 使一个带有相关信息的临时命名关 - 系对通过当前 SPI 连接计划和执行的查询可用。 + 系对通过当前 SPI 连接规划和执行的查询可用。 @@ -2639,8 +2630,8 @@ int SPI_register_relation(EphemeralNamedRelation enr) SPI_unregister_relation - ephemeral named relation - unregistering from SPI + 临时命名关系 + 从 SPI 注销 @@ -2687,7 +2678,7 @@ int SPI_unregister_relation(const char * name) 返回值 - 如果该命令的执行成功,则会返回下列(非负)值: + 如果该命令的执行成功,则将返回下列(非负)值: @@ -2742,13 +2733,13 @@ int SPI_unregister_relation(const char * name) SPI_register_trigger_data - ephemeral named relation - registering with SPI + 临时命名关系 + 向 SPI 注册 - transition tables - implementation in PLs + 过渡表 + 在 PL 中实现 @@ -2772,8 +2763,8 @@ int SPI_register_trigger_data(TriggerData *tdata) SPI_register_trigger_data 使触发器捕获的所有临时关系 - 都能在通过当前 SPI 连接计划和执行的查询中使用。目前,这指的是通过 - REFERENCING OLD/NEW TABLE AS ... 子句定义、并由 + 都能在通过当前 SPI 连接规划和执行的查询中使用。目前,这指的是由带有 + REFERENCING OLD/NEW TABLE AS ... 子句的 AFTER 触发器捕获的过渡表。PL 触发器处理函数应在建 立 SPI 连接后调用此函数。 @@ -2799,7 +2790,7 @@ int SPI_register_trigger_data(TriggerData *tdata) 返回值 - 如果命令的执行成功,则会返回下列(非负)值: + 如果该命令的执行成功,则将返回下列(非负)值: @@ -3071,7 +3062,7 @@ char * SPI_getvalue(HeapTuple row, TupleDesc r 返回值 - 列值;如果该列为 NULL、colnumber 超出范围 + 列值;如果该列为空值、colnumber 超出范围 (SPI_result 被设置为 SPI_ERROR_NOATTRIBUTE)或者没有输出函数 可用(SPI_result 被设置为 @@ -3163,8 +3154,8 @@ Datum SPI_getbinval(HeapTuple row, TupleDesc r 返回值 - 返回该列的二进制值。如果该列为 NULL,则 - isnull 指向的变量会被设为 true,否则设为 false。 + 返回该列的二进制值。如果该列为空值,则 + isnull 指向的变量会被设为真,否则设为假。 @@ -3200,7 +3191,7 @@ char * SPI_gettype(TupleDesc rowdesc, int coln SPI_gettype返回该指定列的数据类型名称 - 的拷贝(当你不再需要该拷贝后,可以使用pfree + 的副本(当你不再需要该副本后,可以使用pfree 释放它)。 @@ -3332,7 +3323,7 @@ char * SPI_getrelname(Relation rel) SPI_getrelname返回该指定关系的名称 - 的拷贝(当你不再需要该拷贝后,可以使用pfree + 的副本(当你不再需要该副本后,可以使用pfree 释放它)。 @@ -3422,8 +3413,8 @@ char * SPI_getnspname(Relation rel) - memory context - in SPI + 内存上下文 + 在 SPI 中 PostgreSQL内存上下文 中分配内存。内存上下文为管理那些在许多不同位置创建、且生命周期各不相同 @@ -3447,7 +3438,7 @@ char * SPI_getnspname(Relation rel) 办法是用 SPI_palloc 为返回对象分配内存。 SPI_palloc上层执行器上下文中分配 内存,也就是调用 SPI_connect 时的当前内存上下文; - 这正是从过程返回值最合适的上下文。本节介绍的其他几个实用函数同样会返 + 这正是从过程返回值最合适的上下文。本节介绍的其他几个辅助函数同样会返 回在上层执行器上下文中创建的对象。 @@ -3455,7 +3446,7 @@ char * SPI_getnspname(Relation rel) 调用 SPI_connect 时,会把该过程的私有上下文 (由 SPI_connect 创建)设为当前上下文。所有通过 pallocrepalloc 或 SPI - 实用函数分配的内存(本节另有说明的除外)都位于这个上下文中。当过程通 + 辅助函数分配的内存(本节另有说明的除外)都位于这个上下文中。当过程通 过 SPI_finish 与 SPI 管理器断开连接时,当前上下文 会恢复为上层执行器上下文,而在该过程内存上下文中分配的所有内存都会被 释放,之后就不能再使用。 @@ -3650,7 +3641,7 @@ void SPI_pfree(void * pointer) SPI_copytuple - 在上层执行器上下文中创建一行的拷贝 + 在上层执行器上下文中创建一行的副本 @@ -3683,7 +3674,7 @@ HeapTuple SPI_copytuple(HeapTuple row) HeapTuple row - 要拷贝的行 + 要复制的行 @@ -3694,7 +3685,7 @@ HeapTuple SPI_copytuple(HeapTuple row) 返回值 - 拷贝后的行;出错时返回 NULL + 复制后的行;出错时返回 NULL (错误指示见 SPI_result @@ -3750,7 +3741,7 @@ HeapTupleHeader SPI_returntuple(HeapTuple row, TupleDesc HeapTuple row - 要拷贝的行 + 要复制的行 @@ -3759,7 +3750,7 @@ HeapTupleHeader SPI_returntuple(HeapTuple row, TupleDesc TupleDesc rowdesc - 行描述符(若要获得最佳缓存效果,大多数情况下应每次都传入同一个描述符) + 行描述符(若要获得最佳缓存效果,每次都传入同一个描述符) @@ -3770,7 +3761,7 @@ HeapTupleHeader SPI_returntuple(HeapTuple row, TupleDesc 返回值 - 指向拷贝后行的 HeapTupleHeader;出错时返回 + 指向复制后行的 HeapTupleHeader;出错时返回 NULL(错误指示见 SPI_result @@ -3872,13 +3863,14 @@ HeapTuple SPI_modifytuple(Relation rel, HeapTuple - 如果nullsNULL,那么 - SPI_modifytuple假定没有新值为空值。否则, - 如果对应的新值为非空,nulls数组的每一项都应 - 该是' ',而如果对应的新值为空值则为'n'(在 - 后一种情况中,对应的values项中的新值无关紧 - 要)。注意nulls不是一个文本字符串,只是一个 - 数组:它不需要一个'\0'终止符。 + 如果 nullsNULL,则 + SPI_modifytuple 会假定没有新值为空值。 + 否则,如果对应新值非空值,则 nulls 数组中 + 的对应项应为 ' ';如果对应新值为空值,则 + 对应项应为 'n'。(后一种情况下,对应 + values 项中的实际值无关紧要。)注意, + nulls 不是文本字符串,而只是一个数组,因此不 + 需要 '\0' 终止符。 @@ -3957,7 +3949,7 @@ void SPI_freetuple(HeapTuple row) SPI_freetuple释放之前在上层执行器上下文中 - 分配的一个行。 + 分配的一行。 @@ -4102,7 +4094,7 @@ int SPI_freeplan(SPIPlanPtr plan) - 数据改变的可见性 + 数据更改的可见性 下列规则决定了使用 SPI 的函数(以及其他任何 C 函数)中数据更改的可见 @@ -4184,7 +4176,7 @@ execq(PG_FUNCTION_ARGS) int ret; uint64 proc; - /* Convert given text object to a C string */ + /* 把给定的文本对象转换成一个 C 字符串 */ command = text_to_cstring(PG_GETARG_TEXT_PP(0)); cnt = PG_GETARG_INT32(1); @@ -4195,7 +4187,7 @@ execq(PG_FUNCTION_ARGS) proc = SPI_processed; /* - * If some rows were fetched, print them via elog(INFO). + * 如果取出了一些行,通过 elog(INFO) 打印它们。 */ if (ret > 0 && SPI_tuptable != NULL) { @@ -4247,8 +4239,8 @@ CREATE FUNCTION execq(text, integer) RETURNS int8 => INSERT INTO a VALUES (execq('INSERT INTO a VALUES (0)', 0)); INSERT 0 1 => SELECT execq('SELECT * FROM a', 0); -INFO: EXECQ: 0 -- inserted by execq -INFO: EXECQ: 1 -- returned by execq and inserted by upper INSERT +INFO: EXECQ: 0 -- 由 execq 插入 +INFO: EXECQ: 1 -- 由 execq 返回并被外层 INSERT 插入 execq ------- @@ -4264,11 +4256,11 @@ INFO: EXECQ: 1 -- returned by execq and inserted by upper INSERT => SELECT execq('SELECT * FROM a', 10); INFO: EXECQ: 0 INFO: EXECQ: 1 -INFO: EXECQ: 2 -- 0 + 2, only one row inserted - as specified +INFO: EXECQ: 2 -- 0 + 2,按指定只插入一行 execq ------- - 3 -- 10 is the max value only, 3 is the real number of rows + 3 -- 10 只是最大值,3 才是真正的行数 (1 row) => DELETE FROM a; @@ -4278,7 +4270,7 @@ INSERT 0 1 => SELECT * FROM a; x --- - 1 -- no rows in a (0) + 1 + 1 -- a 中没有行(0)+ 1 (1 row) => INSERT INTO a VALUES (execq('SELECT * FROM a', 0) + 1); @@ -4288,10 +4280,10 @@ INSERT 0 1 x --- 1 - 2 -- there was one row in a + 1 + 2 -- a 中原有一行 + 1 (2 rows) --- This demonstrates the data changes visibility rule: +-- 下面演示数据更改可见性规则: => INSERT INTO a SELECT execq('SELECT * FROM a', 0) * x FROM a; INFO: EXECQ: 1 @@ -4305,10 +4297,10 @@ INSERT 0 2 --- 1 2 - 2 -- 2 rows * 1 (x in first row) - 6 -- 3 rows (2 + 1 just inserted) * 2 (x in second row) + 2 -- 2 行 * 1(第一行中的 x) + 6 -- 3 行(前面的 2 行加上刚插入的 1 行)* 2(第二行中的 x) (4 rows) ^^^^^^ - rows visible to execq() in different invocations + 不同调用中 execq() 可见的行 diff --git a/zh/10/stylesheet-speedup-common.xsl b/zh/10/stylesheet-speedup-common.xsl index e3fb582a..403f350c 100644 --- a/zh/10/stylesheet-speedup-common.xsl +++ b/zh/10/stylesheet-speedup-common.xsl @@ -95,6 +95,6 @@ -en +zh_cn diff --git a/zh/10/syntax.sgml b/zh/10/syntax.sgml index 95006bb7..59968235 100644 --- a/zh/10/syntax.sgml +++ b/zh/10/syntax.sgml @@ -21,7 +21,7 @@ 词法结构 - token + 词元 @@ -29,7 +29,7 @@ - 一个词元可以是关键词标识符带引号的标识符文字值(或常量),或者特殊字符符号。词元通常由空白(空格、制表符、换行)分隔,但如果不存在歧义,则不必如此(一般只有特殊字符与其他类型的词元相邻时才会这样)。 + 一个词元可以是关键词标识符带引号的标识符字面量(或常量),或者特殊字符符号。词元通常由空白(空格、制表符、换行)分隔,但如果不存在歧义,则不必如此(一般只有特殊字符与其他类型的词元相邻时才会这样)。 @@ -58,18 +58,18 @@ INSERT INTO MY_TABLE VALUES (3, 'hi there'); 标识符和关键词 - identifier - syntax of + 标识符 + 语法 - name - syntax of + 名称 + 语法 - key word - syntax of + 关键词 + 语法 @@ -83,7 +83,7 @@ INSERT INTO MY_TABLE VALUES (3, 'hi there'); - identifierlength + 标识符长度 系统对标识符最多只使用 NAMEDATALEN-1 个字节;在命令中可以写更长的名称,但它们会被截断。默认情况下, NAMEDATALEN 为 64,因此标识符的最大长度是 63 字节。如果这个限制有问题,可以通过修改 src/include/pg_config_manual.h 中的 NAMEDATALEN 常量来提高。 @@ -91,8 +91,8 @@ INSERT INTO MY_TABLE VALUES (3, 'hi there'); - case sensitivity - of SQL commands + 大小写敏感性 + SQL 命令 关键词和未加引号的标识符不区分大小写。因此: @@ -110,8 +110,8 @@ UPDATE my_table SET a = 5; - quotation marks - and identifiers + 引号 + 与标识符 还有第二类标识符:定界标识符带引号的标识符。它通过把任意字符序列括在双引号中形成(")。 定界标识符始终是标识符,绝不会是关键词。因此,"select" 可以用来引用名为 select 的列或表,而不加引号的 select 会被视为关键词,因此在期望表名或列名的位置使用时会导致解析错误。这个示例可以用带引号的标识符写成: @@ -125,7 +125,7 @@ UPDATE "my_table" SET "a" = 5; Unicode 转义 - in identifiers + 在标识符中 @@ -165,7 +165,7 @@ U&"d!0061t!+000061" UESCAPE '!' 常量 - constant + 常量 @@ -176,8 +176,8 @@ U&"d!0061t!+000061" UESCAPE '!' 字符串常量 - character string - constant + 字符串 + 常量 @@ -288,7 +288,7 @@ SELECT 'foo' 'bar'; - 如果配置参数off,那么PostgreSQL对常规字符串常量和转义字符串常量中的反斜线转义都识别。不过,从PostgreSQL 9.1 开始,该参数的默认值为on,意味着只在转义字符串常量中识别反斜线转义。这种行为更兼容标准,但是可能打断依赖于历史行为(反斜线转义总是会被识别)的应用。作为一种变通,你可以设置该参数为off,但是最好迁移到符合新的行为。如果你需要使用一个反斜线转义来表示一个特殊字符,为该字符串常量写上一个E。 + 如果配置参数off,那么PostgreSQL对常规字符串常量和转义字符串常量中的反斜线转义都识别。不过,从PostgreSQL 9.1 开始,该参数的默认值为on,意味着只在转义字符串常量中识别反斜线转义。这种行为更兼容标准,但是可能使依赖历史行为(始终识别反斜线转义)的应用无法正常工作。作为一种变通,你可以设置该参数为off,但最好修改应用,不再使用反斜线转义。如果你需要使用一个反斜线转义来表示一个特殊字符,为该字符串常量写上一个E @@ -306,7 +306,7 @@ SELECT 'foo' 'bar'; Unicode 转义 - in string constants + 在字符串常量中 @@ -346,7 +346,7 @@ U&'d!0061t!+000061' UESCAPE '!' 美元引用的字符串常量 - dollar quoting + 美元引用 指定字符串常量的标准语法通常很方便,但当所需字符串包含很多单引号或反斜线时,就可能难以理解,因为每个这样的字符都必须写成双份。为了在这种情况下让查询更易读,PostgreSQL提供了另一种编写字符串常量的方法,称为美元引用。美元引用的字符串常量由一个美元符号($)、一个由零个或多个字符组成的可选标签、另一个美元符号、构成字符串内容的任意字符序列、一个美元符号、与该美元引用开头相同的标签,以及一个美元符号组成。例如,对于字符串 Dianne's horse,下面是使用美元引用指定它的两种不同方法: @@ -384,8 +384,8 @@ $function$ 位串常量 - bit string - constant + 位串 + 常量 @@ -405,18 +405,28 @@ $function$ 数字常量 - number - constant + 数字 + 常量 - 数字常量接受下列一般形式: + + 数字常量接受下列一般形式: + digits digits.digitse+-digits digits.digitse+-digits digitse+-digits -其中 digits 是一个或多个十进制数字(0 到 9)。若使用小数点,则小数点前后至少有一侧必须有数字。若使用指数标记(e),其后至少必须有一位数字。常量中不能嵌入空格或其他字符。注意,开头的正号或负号实际上不被视为常量的一部分,而是作用于常量的操作符。 + + 其中 digits 是一个或多个十进制数字(0 到 9)。 + 若使用小数点,则小数点前后至少有一侧必须有数字。若使用指数标记 + (e),其后至少必须有一位数字。常量中不能嵌入空格或 + 其他字符。请注意,前导正号或负号 + 实际上不属于常量本身,而是作用于常量的操作符。 + - 下面是一些有效数字常量的示例: + + 这些是合法数字常量的示例: + 42 3.5 4. @@ -434,12 +444,12 @@ $function$ - 为数字常量最初指定的数据类型,只是类型解析算法的起点。在大多数情况下,常量会根据上下文被自动强制转换成最合适的类型。必要时,你可以通过类型转换强制把一个数值解释为特定的数据类型。type cast + 为数字常量最初指定的数据类型,只是类型解析算法的起点。在大多数情况下,常量会根据上下文被自动强制转换成最合适的类型。必要时,你可以通过类型转换强制把一个数值解释为特定的数据类型。类型转换 例如,可以通过下面的写法强制把一个数值当作类型 realfloat4)处理: -REAL '1.23' -- string style -1.23::REAL -- PostgreSQL (historical) style +REAL '1.23' -- 字符串形式 +1.23::REAL -- PostgreSQL(历史)形式 这些实际上只是下面将要讨论的一般类型转换记法的特例。 @@ -450,8 +460,8 @@ REAL '1.23' -- string style 其他类型的常量 - data type - constant + 数据类型 + 常量 @@ -477,7 +487,7 @@ CAST ( 'string' AS type ) - 如中所述,::CAST() 以及函数调用语法也可以用来指定任意表达式的运行时类型转换。为避免语法歧义,type 'string' 语法只能用来指定简单字面常量的类型。该语法的另一个限制是不能用于数组类型;要指定数组常量的类型,请使用 ::CAST()。 + 如中所述,::CAST() 以及函数调用语法也可以用来指定任意表达式的运行时类型转换。为避免语法歧义,type 'string' 语法只能用来指定简单字面常量的类型。type 'string' 语法的另一个限制是不能用于数组类型;要指定数组常量的类型,请使用 ::CAST() @@ -490,8 +500,8 @@ CAST ( 'string' AS type ) 操作符 - operator - syntax + 操作符 + 语法 @@ -541,7 +551,7 @@ CAST ( 'string' AS type ) - 圆括号(())具有它们通常的含义,用来分组表达式并且强制优先。在某些情况中,圆括号被要求作为一个特定 SQL 命令的固定语法的一部分。 + 圆括号(())具有它们通常的含义,用来对表达式分组并确定运算优先级。在某些情况中,圆括号被要求作为一个特定 SQL 命令的固定语法的一部分。 @@ -559,7 +569,7 @@ CAST ( 'string' AS type ) - 分号(;)结束一个 SQL 命令。它不能出现在一个命令中间的任何位置,除了在一个字符串常量中或者一个被引用的标识符中。 + 分号(;)结束一个 SQL 命令。它不能出现在一个命令中间的任何位置,除了在一个字符串常量中或者一个带引号的标识符中。 @@ -571,7 +581,7 @@ CAST ( 'string' AS type ) - 星号(*)在某些上下文中用来表示表行或组合值的所有字段。当它被用作聚合函数的参数时,还有一种特殊含义,即该聚合不需要任何显式参数。 + 星号(*)在某些上下文中用来表示表行或复合值的所有字段。当它被用作聚合函数的参数时,还有一种特殊含义,即该聚合不需要任何显式参数。 @@ -589,22 +599,22 @@ CAST ( 'string' AS type ) 注释 - comment - in SQL + 注释 + 在 SQL 中 注释是一串以双连字符开始并延伸到行尾的字符,例如: --- This is a standard SQL comment +-- 这是一条标准 SQL 注释 另外,也可以使用 C 风格注释块: -/* multiline comment - * with nesting: /* nested block comment */ +/* 多行注释 + * 包含嵌套:/* 嵌套块注释 */ */ 这里该注释开始于/*并且延伸到匹配出现的*/。这些注释块可按照 SQL 标准中指定的方式嵌套,但和 C 中不同。这样我们可以注释掉一大段可能包含注释块的代码。 @@ -619,8 +629,8 @@ CAST ( 'string' AS type ) 操作符优先级 - operator - precedence + 操作符 + 优先级 展示了 PostgreSQL 中操作符的优先级和结合性。大多数操作符具有相同的优先级,并且是左结合的。操作符的优先级和结合性是固定写在解析器中的。 @@ -667,19 +677,19 @@ SELECT (5 !) - 6; + - - 一元加、一元减 + 一元正号、一元负号 ^ - 指数 + 求幂 * / % - 乘、除、模 + 乘、除、取模 @@ -691,7 +701,7 @@ SELECT (5 !) - 6; (任意其他操作符) - 所有其他本地以及用户定义的操作符 + 所有其他内置以及用户定义的操作符 @@ -1342,7 +1352,7 @@ SELECT * FROM tbl WHERE a COLLATE "C" > 'foo'; SELECT * FROM tbl WHERE (a > 'foo') COLLATE "C"; - 因为它尝试把一个排序规则应用到>操作符的结果,而它的数据类型是非可排序数据类型boolean。 + 因为它尝试把一个排序规则应用到>操作符的结果,而它的数据类型是不支持排序规则的数据类型boolean diff --git a/zh/10/textsearch.sgml b/zh/10/textsearch.sgml index a8760ee6..c96e4756 100644 --- a/zh/10/textsearch.sgml +++ b/zh/10/textsearch.sgml @@ -1903,7 +1903,7 @@ ALTER TEXT SEARCH CONFIGURATION russian 分类词典示例 - 考虑简单的天文词库 thesaurus_astro,其中包含一些天文单词组合: + 考虑简单的天文词库 thesaurus_astro,其中包含一些天文单词组合: supernovae stars : sn @@ -2342,7 +2342,7 @@ ts_debug( config re - 以下是一个简单的示例: + 以下是一个简单的示例: SELECT * FROM ts_debug('english', 'a fat cat sat on a mat - it ate a fat rats'); diff --git a/zh/10/trigger.sgml b/zh/10/trigger.sgml index afa8b38f..88084951 100644 --- a/zh/10/trigger.sgml +++ b/zh/10/trigger.sgml @@ -4,7 +4,7 @@ 触发器 - trigger + 触发器 @@ -115,7 +115,7 @@ - 如果在同一关系上的同一事件为其定义了多个触发器,它们会按触发器名称的字母顺序触发。对于 BEFOREINSTEAD OF + 如果为同一关系上的同一事件定义了多个触发器,它们会按触发器名称的字母顺序触发。对于 BEFOREINSTEAD OF 触发器,每个触发器返回的、可能已经被修改过的行都会成为下一个触发器的输入。如果任何一个 BEFOREINSTEAD OF 触发器返回 NULL,则会放弃对该行执行该操作,并且后续触发器(针对该行)都不会再触发。 @@ -144,8 +144,8 @@ - trigger - arguments for trigger functions + 触发器 + 触发器函数的参数 在定义触发器时,可以为它指定参数。在触发器定义中包含参数,是为了让需求相似的不同触发器能够调用同一个函数。举例来说,可以有一个通用触发器函数,它接受两个列名作为参数,把当前用户写入其中一个列,把当前时间戳写入另一个列。只要编写得当,这个触发器函数就应独立于它所作用的具体表。因此,同一个函数可用于任何具有适当列的表上的 INSERT 事件,例如自动跟踪某个事务表中记录的创建。如果把它定义成 UPDATE 触发器,还可以用来跟踪最近更新事件。 @@ -171,7 +171,10 @@ 数据更改的可见性 - 如果你在触发器函数中执行 SQL 命令,而且这些命令访问的是该触发器所在的表,那么就需要了解数据可见性规则,因为这些规则决定了这些 SQL 命令能否看到导致该触发器触发的数据更改。简要来说: + + 如果你在触发器函数中执行 SQL 命令,而这些命令又访问该触发器所属的表,就需要了解数据可见性规则,因为这些规则决定了这些 SQL 命令是否能看到引发触发器的数据更改。简而言之: + + @@ -225,13 +228,13 @@ 用 C 编写触发器函数 - trigger - in C + 触发器 + 在 C 中 - transition tables - referencing from C trigger + 过渡表 + 从 C 触发器中引用 @@ -243,7 +246,7 @@ - 当函数由触发器管理器调用时,不会向它传递任何普通参数,但会传递一个指向 TriggerData 结构体的 context 指针。C 函数可以通过执行下列宏来检查自己是否由触发器管理器调用: + 当函数由触发器管理器调用时,不会向它传递任何普通参数,但会传递一个指向 TriggerData 结构体的 上下文 指针。C 函数可以通过执行下列宏来检查自己是否由触发器管理器调用: CALLED_AS_TRIGGER(fcinfo) @@ -288,14 +291,15 @@ typedef struct TriggerData tg_event - 描述调用该函数所对应的事件。可以使用下列宏来检查tg_event: + + 描述调用函数的事件。可以使用以下宏检查 tg_event TRIGGER_FIRED_BEFORE(tg_event) - 如果触发器在操作之前触发,则返回 true。 + 如果触发器在操作之前触发,则返回真。 @@ -304,7 +308,7 @@ typedef struct TriggerData TRIGGER_FIRED_AFTER(tg_event) - 如果触发器在操作之后触发,则返回 true。 + 如果触发器在操作之后触发,则返回真。 @@ -313,7 +317,7 @@ typedef struct TriggerData TRIGGER_FIRED_INSTEAD(tg_event) - 如果触发器是取代该操作而触发,则返回 true。 + 如果触发器是取代该操作而触发,则返回真。 @@ -322,7 +326,7 @@ typedef struct TriggerData TRIGGER_FIRED_FOR_ROW(tg_event) - 如果触发器是因行级事件触发,则返回 true。 + 如果触发器是因行级事件触发,则返回真。 @@ -331,7 +335,7 @@ typedef struct TriggerData TRIGGER_FIRED_FOR_STATEMENT(tg_event) - 如果触发器是因语句级事件触发,则返回 true。 + 如果触发器是因语句级事件触发,则返回真。 @@ -340,7 +344,7 @@ typedef struct TriggerData TRIGGER_FIRED_BY_INSERT(tg_event) - 如果触发器是由 INSERT 命令触发,则返回 true。 + 如果触发器是由 INSERT 命令触发,则返回真。 @@ -349,7 +353,7 @@ typedef struct TriggerData TRIGGER_FIRED_BY_UPDATE(tg_event) - 如果触发器是由 UPDATE 命令触发,则返回 true。 + 如果触发器是由 UPDATE 命令触发,则返回真。 @@ -358,7 +362,7 @@ typedef struct TriggerData TRIGGER_FIRED_BY_DELETE(tg_event) - 如果触发器是由 DELETE 命令触发,则返回 true。 + 如果触发器是由 DELETE 命令触发,则返回真。 @@ -367,7 +371,7 @@ typedef struct TriggerData TRIGGER_FIRED_BY_TRUNCATE(tg_event) - 如果触发器是由 TRUNCATE 命令触发,则返回 true。 + 如果触发器是由 TRUNCATE 命令触发,则返回真。 @@ -493,16 +497,16 @@ typedef struct Trigger - 一个完整的触发器实例 + 一个完整的触发器示例 这里给出一个非常简单的、用 C 编写的触发器函数示例。(用过程语言编写的触发器示例可见各过程语言的文档。) - 如果某条命令试图向列 x 中插入空值,函数 - trigf 就会报告表 ttest - 中的行数,并跳过实际操作。(这样,这个触发器就起到了非空约束的作用,但不会中止事务。) + 函数 trigf 会报告表 ttest 中的行数, + 并在命令试图向列 x 中插入空值时跳过实际操作。 + (这样,这个触发器就起到了非空约束的作用,但不会中止事务。) @@ -514,7 +518,9 @@ CREATE TABLE ttest ( - 这是触发器函数的源代码: + 下面是触发器函数的源代码: + -PostgreSQL扫描器/解析器将词法元素分成五个基本类别:整数、非整数数字、字符串、标识符和关键字。大多数非数值类型的常量会先被归类为字符串。SQL语言定义允许用字符串指定类型名,而PostgreSQL可以利用这一机制让解析器从一开始就沿着正确的路径处理。例如,查询: +PostgreSQL扫描器/解析器将词法元素分成五个基本类别:整数、非整数数字、字符串、标识符和关键字。大多数非数值类型的常量会先被归类为字符串。SQL语言定义允许给字符串指定类型名,而PostgreSQL可以利用这一机制让解析器从一开始就沿着正确的路径处理。例如,查询: SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; @@ -39,11 +39,11 @@ SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; (1 row) -包含两个文字常量,它们的类型分别是textpoint。如果没有为某个字符串文字指定类型,那么它最初会被赋予占位类型unknown,并在后文所述的后续阶段解析。 +包含两个字面量,它们的类型分别是textpoint。如果没有为某个字符串字面量指定类型,那么它最初会被赋予占位类型unknown,并在后文所述的后续阶段解析。 -有四种基本的 SQL 结构需要在 PostgreSQL 解析器中使用不同的类型转换规则: +在PostgreSQL解析器中,有四种基本的SQL结构需要采用不同的类型转换规则: @@ -82,7 +82,7 @@ SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; -由于经合并的SELECT语句的所有查询结果都必须出现在同一组列中,因此每个SELECT子句的结果类型必须彼此匹配,并转换为统一的一组类型。类似地,CASE结构中的结果表达式必须转换为某种公共类型,这样整个CASE表达式才有确定的输出类型。其他一些结构,如ARRAY[]以及GREATESTLEAST函数,也同样需要为若干子表达式确定公共类型。 +由于经UNION合并的SELECT语句的所有查询结果都必须出现在同一组列中,因此每个SELECT子句的结果类型必须彼此匹配,并转换为统一的一组类型。类似地,CASE结构中的结果表达式必须转换为某种公共类型,这样整个CASE表达式才有确定的输出类型。其他一些结构,如ARRAY[]以及GREATESTLEAST函数,也同样需要为若干子表达式确定公共类型。 @@ -161,11 +161,11 @@ SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; -检查是否存在一个恰好接受输入参数类型的操作符。如果存在(在被考虑的操作符集合中至多只有一个精确匹配),就使用它。若通过限定名调用(这种情况并不常见)某个允许不可信用户创建对象的模式中的操作符,而又缺少精确匹配,就会带来安全隐患 +检查是否存在一个恰好接受输入参数类型的操作符。如果存在(在被考虑的操作符集合中至多只有一个精确匹配),就使用它。若通过限定名调用(这种情况并不常见)某个允许不受信任的用户创建对象的模式中的操作符,而又缺少精确匹配,就会带来安全隐患 - 对于未带模式限定的名称,不会出现这种隐患,因为包含允许不可信用户创建对象的模式的搜索路径不是一种模式的安全使用方式。 + 对于未带模式限定的名称,不会出现这种隐患,因为包含允许不受信任的用户创建对象的模式的搜索路径不是一种模式的安全使用方式。 。在这种情况下,应通过对参数进行类型转换来强制获得精确匹配。 @@ -180,7 +180,7 @@ SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; -如果二元操作符调用的一个参数是unknown类型,而另一个是域类型,则接着检查是否存在两边都恰好接受该域基类型的操作符;如果有,就使用它。 +如果二元操作符调用的一个参数是unknown类型,而另一个是域类型,则接着检查是否存在两边都恰好接受该域基础类型的操作符;如果有,就使用它。 @@ -194,13 +194,13 @@ SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; -丢弃那些输入类型不匹配,且也无法通过隐式类型转换实现匹配的候选操作符。为此,假定unknown文字可以转换为任何类型。如果只剩一个候选操作符,就使用它;否则继续下一步。 +丢弃那些输入类型不匹配,且也无法通过隐式类型转换实现匹配的候选操作符。为此,假定unknown字面量可以转换为任何类型。如果只剩一个候选操作符,就使用它;否则继续下一步。 -如果任何输入参数是域类型,则在后续所有步骤中都把它当作该域的基类型。这样可以确保在解决操作符歧义时,域的行为与其基类型一致。 +如果任何输入参数是域类型,则在后续所有步骤中都把它当作该域的基础类型。这样可以确保在解决操作符歧义时,域的行为与其基础类型一致。 @@ -212,12 +212,12 @@ SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; -遍历所有候选操作符,保留那些在需要类型转换的最多位置上接受首选类型(属于输入数据类型的类型分类)的候选项。如果没有候选项接受首选类型,则保留全部候选项。如果只剩一个候选操作符,就使用它;否则继续下一步。 +遍历所有候选操作符,在需要类型转换的位置上,保留接受首选类型(属于输入数据类型的类型分类)的位置数最多的候选项。如果没有候选项接受首选类型,则保留全部候选项。如果只剩一个候选操作符,就使用它;否则继续下一步。 -如果有任何输入参数是unknown,就检查剩余候选项在这些参数位置上接受哪些类型分类。在每个位置上,如果有任何候选项接受string分类,就选择该分类。(这种偏向字符串的做法是合适的,因为unknown类型的文字看起来像字符串。)否则,如果所有剩余候选项都接受同一种类型分类,就选择该分类;否则失败,因为在缺少更多线索的情况下无法推断出正确选择。然后丢弃不接受所选类型分类的候选项。此外,如果有任何候选项接受该分类中的首选类型,就丢弃在该参数上接受非首选类型的候选项。如果没有候选项通过这些测试,则保留全部候选项。如果只剩一个候选项,就使用它;否则继续下一步。 +如果有任何输入参数是unknown,就检查剩余候选操作符在这些参数位置上接受哪些类型分类。在每个位置上,如果有任何候选项接受string分类,就选择该分类。(这种偏向字符串的做法是合适的,因为unknown类型的字面量看起来像字符串。)否则,如果所有剩余候选项都接受同一种类型分类,就选择该分类;否则失败,因为在缺少更多线索的情况下无法推断出正确选择。然后丢弃不接受所选类型分类的候选项。此外,如果有任何候选项接受该分类中的首选类型,就丢弃在该参数上接受非首选类型的候选项。如果没有候选项通过这些测试,则保留全部候选项。如果只剩一个候选操作符,就使用它;否则继续下一步。 @@ -265,7 +265,7 @@ SELECT CAST(40 AS bigint) ! AS "40 factorial"; -一个只有一个未指定参数的例子: +一个参数未指定类型的例子: SELECT text 'abc' || 'def' AS "text and unknown"; @@ -293,7 +293,7 @@ SELECT 'abc' || 'def' AS "unspecified"; -这里对使用哪种类型没有初始提示,因为查询中没有指定任何类型。因此,解析器会查找所有候选操作符,并发现既有接受字符串分类输入的候选项,也有接受位串分类输入的候选项。由于在可用时优先选择字符串分类,所以会选中该分类,再使用字符串的首选类型text作为解析这些unknown类型文字的具体类型。 +这里对使用哪种类型没有初始提示,因为查询中没有指定任何类型。因此,解析器会查找所有候选操作符,并发现既有接受字符串分类输入的候选项,也有接受位串分类输入的候选项。由于在可用时优先选择字符串分类,所以会选中该分类,再使用字符串的首选类型text作为解析这些unknown类型字面量的具体类型。 @@ -301,7 +301,7 @@ SELECT 'abc' || 'def' AS "unspecified"; 绝对值与取反操作符类型解析 -在 PostgreSQL 操作符目录中,前缀操作符 @ 有多个条目,分别实现各种数值数据类型的绝对值运算。其中一个条目用于类型 float8,它是数值分类中的首选类型。因此,PostgreSQL 会使用该条目来处理 unknown 输入: +PostgreSQL操作符目录中为前缀操作符@提供了多个条目,它们分别实现各种数值数据类型的绝对值操作。其中一个条目对应float8,它是数值分类中的首选类型。因此,当遇到一个unknown输入时,PostgreSQL会使用该条目: SELECT @ '-4.5' AS "abs"; abs @@ -309,7 +309,7 @@ SELECT @ '-4.5' AS "abs"; 4.5 (1 row) -这里,系统在应用所选操作符之前,已将 unknown 类型文字隐式解析为 float8 类型。我们可以验证所使用的是 float8 而不是其他类型: +这里,系统在应用所选操作符之前,已经把unknown类型字面量隐式解析为float8。我们可以验证使用的确实是float8,而不是其他类型: SELECT @ '-4.5e500' AS "abs"; @@ -351,8 +351,7 @@ SELECT array[1,2] <@ '{1,2,3}' as "is subset"; t (1 row) -在 PostgreSQL 操作符目录中,中缀操作符 <@ 有多个条目,但可能接受左侧为整数数组的只有两个:数组包含(anyarray <@ anyarray)和范围包含(anyelement <@ anyrange)。由于这些多态伪类型(见 )都不是首选类型,解析器无法据此消除歧义。不过, 要求它假定 unknown 类型文字与另一个输入的类型相同,即整数数组。这样,两个操作符中只有一个能够匹配,因此会选择数组包含。(如果选择了范围包含,就会得到错误,因为该字符串的格式不符合范围文字的要求。) +PostgreSQL操作符目录中为中缀操作符<@定义了多个条目,但左侧能够接受整数数组的只有两种:数组包含(anyarray <@ anyarray)和范围包含(anyelement <@ anyrange)。由于这些多态伪类型(见)都不被视为首选类型,解析器无法据此消除歧义。不过,要求它假定unknown类型字面量与另一输入具有相同类型,也就是整数数组。这样两个操作符中只有一个能够匹配,因此会选择数组包含。(如果选中范围包含,就会报错,因为该字符串的格式并不是合法的范围字面量。) @@ -361,7 +360,7 @@ linkend="datatype-pseudo">)都不是首选类型,解析器无法据此消除 域类型上的自定义操作符 -用户有时会尝试声明只适用于某个域类型的操作符。这是可行的,但远没有看上去那样有用,因为操作符解析规则被设计成优先选择作用于域基类型的操作符。考虑下面的例子: +用户有时会尝试声明只适用于某个域类型的操作符。这是可行的,但远没有看上去那样有用,因为操作符解析规则被设计成优先选择作用于域基础类型的操作符。考虑下面的例子: CREATE DOMAIN mytext AS text CHECK(...); CREATE FUNCTION mytext_eq_text (mytext, text) RETURNS boolean AS ...; @@ -370,11 +369,11 @@ CREATE TABLE mytable (val mytext); SELECT * FROM mytable WHERE val = 'foo'; -这个查询不会使用自定义操作符。解析器首先会检查是否存在mytext = mytext操作符(),但并不存在;然后它会考虑该域的基类型text,并检查是否存在text = text操作符(),而这是存在的;于是它会把unknown类型的文字解析为text,并使用text = text操作符。要让自定义操作符被使用,唯一的方法是显式地对该文字做类型转换: +这个查询不会使用自定义操作符。解析器首先会检查是否存在mytext = mytext操作符(),但并不存在;然后它会考虑该域的基础类型text,并检查是否存在text = text操作符(),而这是存在的;于是它会把unknown类型的字面量解析为text,并使用text = text操作符。要让自定义操作符被使用,唯一的方法是显式地对该字面量做类型转换: SELECT * FROM mytable WHERE val = text 'foo'; -这样就会根据精确匹配规则立即找到mytext = text操作符。如果解析过程进入最佳匹配规则,它们会主动排斥作用于域类型的操作符。如果不是这样,这类操作符会导致过多的操作符歧义失败,因为类型转换规则总是把域视为可以转换到其基类型或从其基类型转换而来,因此域操作符会在所有与基类型上同名操作符相同的场景中都被视为可用。 +这样就会根据精确匹配规则立即找到mytext = text操作符。如果解析过程进入最佳匹配规则,它们会主动排斥作用于域类型的操作符。如果不是这样,这类操作符会导致过多的操作符歧义失败,因为类型转换规则总是把域视为可以转换到其基础类型或从其基础类型转换而来,因此域操作符会在所有与基础类型上同名操作符相同的场景中都被视为可用。 @@ -409,26 +408,26 @@ SELECT * FROM mytable WHERE val = text 'foo'; -如果函数声明了一个VARIADIC数组参数,而调用时没有使用VARIADIC关键字,则把该函数视为其数组参数按需要被其元素类型的一个或多个出现所替换,以匹配该调用。扩展之后,该函数的有效参数类型可能与某个非可变参数函数完全相同。在这种情况下,使用搜索路径中较早出现的函数;如果两个函数位于同一模式,则优先选择非可变参数函数。 +如果函数声明了一个VARIADIC数组参数,而调用时没有使用VARIADIC关键字,则把数组参数视为一个或多个其元素类型的参数,个数按匹配该调用的需要确定。扩展之后,该函数的有效参数类型可能与某个非VARIADIC函数完全相同。在这种情况下,使用搜索路径中较早出现的函数;如果两个函数位于同一模式,则优先选择非VARIADIC函数。 -通过限定名调用某个允许不可信用户创建对象的模式中找到的可变参数函数时,会带来安全隐患 +通过限定名调用某个允许不受信任的用户创建对象的模式中找到的可变参数函数时,会带来安全隐患 - 对于未带模式限定的名称,不会出现这种隐患,因为包含允许不可信用户创建对象的模式的搜索路径不是一种模式的安全使用方式。 + 对于未带模式限定的名称,不会出现这种隐患,因为包含允许不受信任的用户创建对象的模式的搜索路径不是一种模式的安全使用方式。 - 。恶意用户可以借此劫持调用,并以你的身份执行任意 SQL 函数。改为使用带有VARIADIC关键字的调用可以绕过这一隐患。对于填充VARIADIC "any"参数的调用,往往没有包含VARIADIC关键字的等价写法。要安全地发出这类调用,该函数所在模式必须只允许可信用户创建对象。 + 。恶意用户可以借此劫持调用,并以你的身份执行任意 SQL 函数。改为使用带有VARIADIC关键字的调用可以绕过这一隐患。对于填充VARIADIC "any"参数的调用,往往没有包含VARIADIC关键字的等价写法。要安全地发出这类调用,该函数所在模式必须只允许受信任的用户创建对象。 -带有参数默认值的函数,被认为可以匹配任何省略了零个或多个可默认参数位置的调用。如果不止一个这样的函数能匹配某个调用,则使用搜索路径中最早出现的那一个。如果同一模式中存在两个或更多这样的函数,并且它们在未使用默认值的参数位置上的参数类型相同(如果它们具有不同的可默认参数集合,这种情况是可能的),系统就无法判断该偏好哪一个;如果找不到更好的匹配,就会报有歧义的函数调用错误。 +带有参数默认值的函数,被认为可以匹配任何省略了零个或多个可使用默认值的参数位置的调用。如果不止一个这样的函数能匹配某个调用,则使用搜索路径中最早出现的那一个。如果同一模式中存在两个或更多这样的函数,并且它们在未使用默认值的参数位置上的参数类型相同(如果它们具有不同的带有默认值的参数集合,这种情况是可能的),系统就无法判断该偏好哪一个;如果找不到更好的匹配,就会报有歧义的函数调用错误。 -通过限定名调用某个允许不可信用户创建对象的模式中的任意函数时,会带来可用性隐患。恶意用户可以用现有函数的名字创建一个新函数,复制该函数的参数,并附加带有默认值的新参数。这样就会阻止对原始函数的新调用。为避免这种隐患,应把函数放在只允许可信用户创建对象的模式中。 +通过限定名调用某个允许不受信任的用户创建对象的模式中的任意函数时,会带来可用性隐患。恶意用户可以用现有函数的名字创建一个新函数,复制该函数的参数,并附加带有默认值的新参数。这样就会阻止对原始函数的新调用。为避免这种隐患,应把函数放在只允许受信任的用户创建对象的模式中。 @@ -437,13 +436,13 @@ SELECT * FROM mytable WHERE val = text 'foo'; -检查是否存在一个恰好接受输入参数类型的函数。如果存在(在被考虑的函数集合中至多只有一个精确匹配),就使用它。若通过限定名调用某个允许不可信用户创建对象的模式中的函数,而又缺少精确匹配,就会带来安全隐患。在这种情况下,应通过对参数进行类型转换来强制获得精确匹配。(涉及unknown的情况在这一步永远找不到匹配。) +检查是否存在一个恰好接受输入参数类型的函数。如果存在(在被考虑的函数集合中至多只有一个精确匹配),就使用它。若通过限定名调用某个允许不受信任的用户创建对象的模式中的函数,而又缺少精确匹配,就会带来安全隐患。在这种情况下,应通过对参数进行类型转换来强制获得精确匹配。(涉及unknown的情况在这一步永远找不到匹配。) -如果没有找到精确匹配,就检查该函数调用是否看起来像一种特殊的类型转换请求。这种情况发生在:函数调用只有一个参数,且函数名与某个数据类型的(内部)名称相同。此外,函数参数必须是unknown类型文字,或者是一种到该命名数据类型二进制可强制转换的类型,或者是一种可以通过应用其 I/O 函数转换为该命名数据类型的类型(也就是说,该转换要么转到某种标准字符串类型,要么从某种标准字符串类型转来)。满足这些条件时,该函数调用会被当作一种CAST形式。 +如果没有找到精确匹配,就检查该函数调用是否看起来像一种特殊的类型转换请求。这种情况发生在:函数调用只有一个参数,且函数名与某个数据类型的(内部)名称相同。此外,函数参数必须是unknown类型字面量,或者是一种可以二进制强制转换为该命名数据类型的类型,或者是一种可以通过应用其 I/O 函数转换为该命名数据类型的类型(也就是说,该转换要么转到某种标准字符串类型,要么从某种标准字符串类型转来)。满足这些条件时,该函数调用会被当作一种CAST形式。 之所以有这一步,是为了在不存在实际类型转换函数的情况下仍支持函数风格的类型转换写法。如果存在类型转换函数,按惯例它会以其输出类型命名,因此无需为此设置特殊情况。更多说明见。 @@ -459,13 +458,13 @@ SELECT * FROM mytable WHERE val = text 'foo'; -丢弃那些输入类型不匹配,且也无法通过隐式类型转换实现匹配的候选函数。为此,假定unknown文字可以转换为任何类型。如果只剩一个候选函数,就使用它;否则继续下一步。 +丢弃那些输入类型不匹配,且也无法通过隐式类型转换实现匹配的候选函数。为此,假定unknown字面量可以转换为任何类型。如果只剩一个候选函数,就使用它;否则继续下一步。 -如果任何输入参数是域类型,则在后续所有步骤中都把它当作该域的基类型。这样可以确保在解决函数歧义时,域的行为与其基类型一致。 +如果任何输入参数是域类型,则在后续所有步骤中都把它当作该域的基础类型。这样可以确保在解决函数歧义时,域的行为与其基础类型一致。 @@ -477,12 +476,12 @@ SELECT * FROM mytable WHERE val = text 'foo'; -遍历所有候选函数,保留那些在需要类型转换的最多位置上接受首选类型(属于输入数据类型的类型分类)的候选项。如果没有候选项接受首选类型,则保留全部候选项。如果只剩一个候选函数,就使用它;否则继续下一步。 +遍历所有候选函数,在需要类型转换的位置上,保留接受首选类型(属于输入数据类型的类型分类)的位置数最多的候选项。如果没有候选项接受首选类型,则保留全部候选项。如果只剩一个候选函数,就使用它;否则继续下一步。 -如果有任何输入参数是unknown,就检查剩余候选项在这些参数位置上接受哪些类型分类。在每个位置上,如果有任何候选项接受string分类,就选择该分类。(这种偏向字符串的做法是合适的,因为unknown类型的文字看起来像字符串。)否则,如果所有剩余候选项都接受同一种类型分类,就选择该分类;否则失败,因为在缺少更多线索的情况下无法推断出正确选择。然后丢弃不接受所选类型分类的候选项。此外,如果有任何候选项接受该分类中的首选类型,就丢弃在该参数上接受非首选类型的候选项。如果没有候选项通过这些测试,则保留全部候选项。如果只剩一个候选项,就使用它;否则继续下一步。 +如果有任何输入参数是unknown,就检查剩余候选函数在这些参数位置上接受哪些类型分类。在每个位置上,如果有任何候选项接受string分类,就选择该分类。(这种偏向字符串的做法是合适的,因为unknown类型的字面量看起来像字符串。)否则,如果所有剩余候选项都接受同一种类型分类,就选择该分类;否则失败,因为在缺少更多线索的情况下无法推断出正确选择。然后丢弃不接受所选类型分类的候选项。此外,如果有任何候选项接受该分类中的首选类型,就丢弃在该参数上接受非首选类型的候选项。如果没有候选项通过这些测试,则保留全部候选项。如果只剩一个候选函数,就使用它;否则继续下一步。 @@ -539,7 +538,7 @@ CREATE FUNCTION public.variadic_example(VARIADIC numeric[]) RETURNS int CREATE FUNCTION -此函数接受 VARIADIC 关键字,但不要求使用它。它可以接受 integer 和 numeric 参数: +这个函数接受但不要求使用VARIADIC关键字。它既能接受integer参数,也能接受numeric参数: SELECT public.variadic_example(0), @@ -551,7 +550,7 @@ SELECT public.variadic_example(0), (1 row) -不过,如果有更具体的函数,前两个调用会优先选择它们: +但是,如果有更具体的函数可用,第一和第二个调用会优先选择它们: CREATE FUNCTION public.variadic_example(numeric) RETURNS int @@ -571,7 +570,7 @@ SELECT public.variadic_example(0), (1 row) -在默认配置下,如果只存在第一个函数,前两个调用是不安全的。任何用户都可以通过创建第二个或第三个函数来截获它们。由于精确匹配参数类型并使用了 VARIADIC 关键字,第三个调用是安全的。 +在默认配置下,且只存在第一个函数时,第一和第二个调用并不安全。任何用户都可以通过创建第二个或第三个函数来劫持它们。第三个调用由于参数类型精确匹配且使用了VARIADIC关键字,因此是安全的。 @@ -659,7 +658,7 @@ SELECT substr(CAST (1234 AS text), 3); -否则,尝试把表达式转换为目标类型。如果这两种类型之间在pg_cast目录中登记了赋值类型转换(见),就可以这样做。另一种情况是,如果表达式是unknown类型文字,则会把文字字符串的内容送入目标类型的输入转换例程。 +否则,尝试把表达式转换为目标类型。如果这两种类型之间在pg_cast目录中登记了赋值类型转换(见),就可以这样做。另一种情况是,如果表达式是unknown类型字面量,则会把字符串字面量的内容送入目标类型的输入转换例程。 @@ -691,7 +690,7 @@ SELECT v, octet_length(v) FROM vv; -这里实际发生的是,两个unknown类型文字默认都被解析为text,从而使||操作符被解析为text的连接操作。然后,操作符得到的text结果被转换为bpcharblank-padded char,即character数据类型的内部名称),以匹配目标列类型。(由于从textbpchar的转换是二进制可强制转换的,这一步不会插入任何真实的函数调用。)最后,系统目录中找到尺寸调整函数bpchar(bpchar, integer, boolean),并把它应用到操作符结果以及存储列长度上。这个特定于类型的函数会执行所需的长度检查并补齐填充空格。 +这里实际发生的是,两个unknown类型字面量默认都被解析为text,从而使||操作符被解析为text的连接操作。然后,操作符得到的text结果被转换为bpchar用空格填充的字符,blank-padded char,即character数据类型的内部名称),以匹配目标列类型。(由于从textbpchar的转换是二进制可强制转换的,这一步不会插入任何真实的函数调用。)最后,系统从系统目录中找到尺寸调整函数bpchar(bpchar, integer, boolean),并把它应用到操作符结果以及存储列长度上。这个特定于类型的函数会执行所需的长度检查并补齐填充空格。 @@ -746,10 +745,10 @@ SQL 的UNION结构必须让可能不同的类型彼此匹配 -如果任何输入是域类型,则在后续所有步骤中都把它当作该域的基类型。 +如果任何输入是域类型,则在后续所有步骤中都把它当作该域的基础类型。 - 这在某种程度上类似于操作符和函数对域输入的处理方式;只要用户确保所有输入都隐式或显式地正好属于该域类型,这种行为就能让域类型在UNION或类似结构中得以保留。否则,就会使用该域的基类型。 + 这在某种程度上类似于操作符和函数对域输入的处理方式;只要用户确保所有输入都隐式或显式地正好属于该域类型,这种行为就能让域类型在UNION或类似结构中得以保留。否则,就会使用该域的基础类型。 @@ -764,13 +763,13 @@ SQL 的UNION结构必须让可能不同的类型彼此匹配 -如果非unknown输入并非全都属于同一类型分类,则失败。 +如果非unknown输入并非全都属于同一类型分类,则失败。 -选择第一个非unknown输入的类型作为候选类型,然后按从左到右的顺序考虑其余每个非unknown输入类型。 +选择第一个非unknown输入的类型作为候选类型,然后按从左到右的顺序考虑其余每个非unknown输入类型。 出于历史原因,CASE会把其ELSE子句(如果有)视为第一个输入,THEN子句则在其后考虑。其他所有情况中,从左到右都指表达式在查询文本中出现的顺序。 @@ -793,7 +792,7 @@ SQL 的UNION结构必须让可能不同的类型彼此匹配 -UNION 中未充分指定类型时的类型解析 +<literal>UNION</literal> 中未充分指定类型时的类型解析 @@ -805,12 +804,12 @@ SELECT text 'a' AS "text" UNION SELECT 'b'; b (2 rows) -这里,unknown 类型文字 'b' 将被解析为类型 text。 +这里,unknown类型字面量'b'会被解析为text类型。 -简单 UNION 中的类型解析 +简单 <literal>UNION</literal> 中的类型解析 @@ -822,12 +821,12 @@ SELECT 1.2 AS "numeric" UNION SELECT 1; 1.2 (2 rows) -文字常量1.2的类型是numeric,而integer1可以隐式转换为numeric,因此使用该类型。 +字面量1.2的类型是numeric,而integer1可以隐式转换为numeric,因此使用该类型。 -次序对调的 UNION 中的类型解析 +次序对调的 <literal>UNION</literal> 中的类型解析 @@ -839,12 +838,12 @@ SELECT 1 AS "real" UNION SELECT CAST('2.2' AS REAL); 2.2 (2 rows) -这里,由于类型 real 不能隐式转换为 integer,但 integer 可以隐式转换为 real,因此合并结果类型被解析为 real。 +这里,由于real类型不能隐式转换为integer,而integer可以隐式转换为real,因此UNION结果类型被解析为real -嵌套 UNION 中的类型解析 +嵌套 <literal>UNION</literal> 中的类型解析 @@ -874,17 +873,17 @@ ERROR: UNION types text and integer cannot be matched -前面各节给出的规则会为 SQL 查询中的所有表达式赋予非 unknown 数据类型,但作为 SELECT 命令的简单输出列出现的未指定类型文字除外。例如,在 +前面各节给出的规则会为 SQL 查询中的所有表达式赋予非 unknown 数据类型,但作为 SELECT 命令的简单输出列出现的未指定类型字面量除外。例如,在 SELECT 'Hello World'; -中,没有任何信息可用于确定应将该字符串文字视为什么类型。在这种情况下,PostgreSQL 会回退为将该文字的类型解析为 text。 +中,没有任何信息可用于确定应将该字符串字面量视为什么类型。在这种情况下,PostgreSQL 会回退为将该字面量的类型解析为 text -当SELECTUNION(或INTERSECTEXCEPT)结构的一端,或者出现在INSERT ... SELECT中时,这条规则不适用,因为前面各节给出的规则具有更高优先级。在前一种情况下,未指定类型文字的类型可以从UNION的另一侧取得;在后一种情况下,则从目标列取得。 +当SELECTUNION(或INTERSECTEXCEPT)结构的一端,或者出现在INSERT ... SELECT中时,这条规则不适用,因为前面各节给出的规则具有更高优先级。在前一种情况下,未指定类型字面量的类型可以从UNION的另一侧取得;在后一种情况下,则从目标列取得。 @@ -894,7 +893,7 @@ SELECT 'Hello World'; - 在PostgreSQL 10 之前,这条规则并不存在,SELECT输出列表中的未指定类型文字会被保留为unknown类型。这会带来各种不良后果,因此后来做了修改。 + 在PostgreSQL 10 之前,这条规则并不存在,SELECT输出列表中的未指定类型字面量会被保留为unknown类型。这会带来各种不良后果,因此后来做了修改。 diff --git a/zh/10/user-manag.sgml b/zh/10/user-manag.sgml index 0e8f8ebd..bcfb4124 100644 --- a/zh/10/user-manag.sgml +++ b/zh/10/user-manag.sgml @@ -71,7 +71,7 @@ SELECT rolname FROM pg_roles; - 为了完成数据库系统的初始引导,一个刚初始化的系统总会包含一个预定义的可登录角色。该角色总是一个超级用户,并且除非另行指定了不同名称,否则它的名称与用initdb初始化数据库集簇的操作系统用户相同。这个角色通常命名为postgres。要创建更多角色,必须先以这个初始角色建立连接。 + 为了完成数据库系统的初始引导,一个刚初始化的系统总会包含一个预定义角色。该角色总是一个超级用户,并且除非另行指定了不同名称,否则它的名称与用initdb初始化数据库集簇的操作系统用户相同。这个角色通常命名为postgres。要创建更多角色,必须先以这个初始角色建立连接。 @@ -194,13 +194,12 @@ CREATE USER name; - 角色还可以为 中描述的许多运行时配置设置指定角色专属的默认值。例如,如果出于某种原因,你希望每次连接时都禁用索引扫描(提示:这不是一个好主意),可以使用: + 角色还可以为中描述的许多运行时配置设置指定角色特定默认值。例如,如果出于某种原因你希望每次连接时都禁用索引扫描(提示:这不是个好主意),你可以使用: ALTER ROLE myname SET enable_indexscan TO off; - 这会保存该设置(但不会立即设置它)。此角色后续建立的连接就好像在会话开始前刚执行过 SET enable_indexscan TO off 一样。在会话期间仍然可以更改这一设置;它只是默认值。要移除角色专属的默认设置,请使用 - ALTER ROLE rolename RESET varname。请注意,附加在没有 LOGIN 权限的角色上的角色专属默认值几乎没有用处,因为它们永远不会被调用。 + 这会保存该设置(但不会立即生效)。在该角色后续建立的连接中,它看起来就像在会话开始之前执行了SET enable_indexscan TO off一样。你仍然可以在会话期间更改该设置;它只会作为默认值。要移除角色特定默认设置,使用ALTER ROLE rolename RESET varname。注意,附加到没有LOGIN权限的角色上的角色特定默认值几乎没有用,因为它们永远不会生效。 @@ -236,7 +235,7 @@ REVOKE group_role FROM role1 组角色的成员可以通过两种方式使用该角色的权限。首先,组的每个成员都可以显式执行 - ,以暂时成为该组角色。在这种状态下,数据库会话可以使用组角色的权限,而不是原始登录角色的权限;创建的任何数据库对象也被视为由组角色而非登录角色拥有。其次,具有 INHERIT 属性的成员角色可以自动使用其所属角色的权限,包括这些角色继承的所有权限。例如,假定我们已经执行了: + ,以暂时成为该组角色。在这种状态下,数据库会话可以使用组角色的权限,而不是原始登录角色的权限;创建的任何数据库对象也被视为由组角色而非登录角色拥有。其次,具有 INHERIT 属性的成员角色可以自动使用其所属角色的权限,包括这些角色继承的所有权限。例如,假定我们已经执行了: CREATE ROLE joe LOGIN INHERIT; CREATE ROLE admin NOINHERIT; @@ -245,7 +244,7 @@ GRANT admin TO joe; GRANT wheel TO admin; 以角色 joe 连接后,数据库会话立即可以使用直接授予 joe 的权限,以及授予 admin 的所有权限,因为 joe - 继承 admin 的权限。不过,授予 wheel 的权限不可用,因为即使 joe 间接属于 wheel,该成员资格也是通过 admin 获得的,而后者具有 NOINHERIT 属性。执行以下命令后: + 继承 admin 的权限。不过,授予 wheel 的权限不可用,因为即使 joe 间接属于 wheel,该成员资格也是通过 admin 获得的,而后者具有 NOINHERIT 属性。执行以下命令后: SET ROLE admin; @@ -255,7 +254,7 @@ SET ROLE admin; SET ROLE wheel; 会话将只能使用授予 - wheel 的权限,而不能使用授予 joeadmin 的权限。使用以下任一命令可以恢复原始的权限状态: + wheel 的权限,而不能使用授予 joeadmin 的权限。使用以下任一命令可以恢复原始的权限状态: SET ROLE joe; SET ROLE NONE; @@ -307,12 +306,12 @@ ALTER TABLE bobs_table OWNER TO alice; - 一旦有价值的对象都已转移给新拥有者,被删除角色所拥有的其余对象即可使用命令删除。同样,由于该命令不能访问其他数据库中的对象,因此必须在包含该角色所拥有对象的每个数据库中运行它。另外,DROP + 一旦有价值的对象都已转移给新拥有者,待删除角色所拥有的其余对象即可使用命令删除。同样,由于该命令不能访问其他数据库中的对象,因此必须在包含该角色所拥有对象的每个数据库中运行它。另外,DROP OWNED不会删除整个数据库或表空间,因此如果该角色拥有任何尚未转移给新拥有者的数据库或表空间,就必须手工删除它们。 - DROP OWNED还会负责移除授予目标角色、但不属于它自身对象的任何权限。由于REASSIGN OWNED不会处理这类对象,所以通常需要同时运行REASSIGN OWNEDDROP OWNED(按这个顺序!),才能完整移除待删除角色的依赖关系。 + DROP OWNED还会负责移除目标角色在其他角色所拥有的对象上获授的所有权限。由于REASSIGN OWNED不会处理这类对象,所以通常需要同时运行REASSIGN OWNEDDROP OWNED(按这个顺序!),才能完整移除待删除角色的依赖关系。 @@ -365,7 +364,7 @@ DROP ROLE doomed_role; pg_read_all_stats - 读取所有 pg_stat_* 视图,并使用各种与统计信息相关的扩展,即使是那些通常仅对超级用户可见的扩展。 + 读取所有 pg_stat_* 视图,并使用各种与统计信息相关的扩展,包括通常仅对超级用户可见的内容。 pg_stat_scan_tables @@ -409,7 +408,7 @@ GRANT pg_signal_backend TO admin_user; 函数安全性 - 函数、触发器和行级安全策略允许用户把代码插入后端服务器,而其他用户可能会无意中执行这些代码。因此,这些机制使用户能够相对容易地对其他用户实施特洛伊木马攻击。最强的保护方式是严格控制谁能定义对象。如果这不可行,则应编写只引用拥有者可信对象的查询,并从search_path中移除任何允许不受信任用户创建对象的模式。 + 函数、触发器和行级安全策略允许用户把代码插入后端服务器,而其他用户可能会无意中执行这些代码。因此,这些机制使用户能够相对容易地对其他用户实施特洛伊木马攻击。最强的保护方式是严格控制谁能定义对象。如果这不可行,则应编写只引用拥有者可信的对象的查询,并从search_path中移除 public 模式以及任何其他允许不受信任用户创建对象的模式。 diff --git a/zh/10/vacuumlo.sgml b/zh/10/vacuumlo.sgml index 3ac365e3..24979ea6 100644 --- a/zh/10/vacuumlo.sgml +++ b/zh/10/vacuumlo.sgml @@ -8,7 +8,7 @@ vacuumlo 1 - Application + 应用程序 diff --git a/zh/10/wal.sgml b/zh/10/wal.sgml index bfd220e2..691381a9 100644 --- a/zh/10/wal.sgml +++ b/zh/10/wal.sgml @@ -349,9 +349,9 @@ 检查点检查点 是事务序列中的一些点,在这些点上可以保证堆和索引数据文件已经用检查点之前写入 - 的全部信息进行了更新。执行检查点时,所有脏数据页都会刷写到磁盘,并向 WAL - 文件写入一条特殊的检查点记录。(更改记录此前已经刷入 WAL - 文件。)如果发生崩溃,崩溃恢复过程会查看最新的检查点记录,以确定应该从 WAL + 的全部信息进行了更新。执行检查点时,所有脏数据页都会刷盘,并向 WAL + 文件写入一条特殊的检查点记录。(更改记录此前已写入 WAL + 文件并刷盘。)如果发生崩溃,崩溃恢复过程会查看最新的检查点记录,以确定应该从 WAL 的哪个位置(称为重做记录)开始执行 REDO。该点之前对数据文件所做的任何更改 都保证已经在磁盘上。因此,检查点之后,位于包含重做记录的段之前的 WAL 段不再需要, 可以被回收或删除。(若正在执行 WAL 归档,则这些 WAL 段必 @@ -379,7 +379,7 @@ 减小 checkpoint_timeout 和/或 max_wal_size 会让检查点更频繁地发生。这样可以加快崩溃后 - 恢复,因为需要重做的工作更少。不过,这必须与更频繁刷写脏数据页所增加的成本 + 恢复,因为需要重做的工作更少。不过,这必须与更频繁地将脏数据页刷盘所增加的成本 权衡。如果设置了 (默认就是如此), 还要考虑另一个因素。为了保证数据页一致性,每个检查点之后对某个数据页的首次 修改,都会导致把整页内容写入日志。在这种情况下,更短的检查点间隔会增加输出到 @@ -417,7 +417,7 @@ 在 Linux 和 POSIX 平台上, - 允许在检查点写出的操作系统页面达到可配置的字节数后,强制把它们刷到磁盘。 + 允许在检查点写出的操作系统页面达到可配置的字节数后,强制将它们刷盘。 否则,这些页面可能会停留在操作系统页缓存中,从而在检查点末尾发出 fsync 时引发停顿。这个设置通常有助于降低事务延迟,但也可能 对性能产生不利影响,尤其是在工作负载大于 @@ -453,7 +453,7 @@ 在归档恢复或备库模式下,服务器会周期性地执行 重启点重启点, - 其行为类似于正常运行时的检查点:服务器会强制把自身状态写盘,更新 + 其行为类似于正常运行时的检查点:服务器会强制将其所有状态刷盘,更新 pg_control 文件,以表明已经处理过的 WAL 数据无需再次 扫描,然后回收 pg_wal 目录中的旧 WAL 段文件。重启点的 执行频率不会高于主库上的检查点,因为重启点只能在检查点记录处执行。当到达某条检查点记录且距离上次重启点 @@ -476,7 +476,7 @@ 快。更糟的是,写 WAL 缓冲区还可能迫使系统创建新的 WAL 段, 这会花费更多时间。正常情况下,WAL 缓冲区应由 XLogFlush 请求负责写出并刷盘; - 该请求大多发生在事务提交时,以确保事务记录被刷入持久存储。在 WAL 输出量很高 + 该请求大多发生在事务提交时,以确保事务记录已刷盘至持久存储。在 WAL 输出量很高 的系统上,XLogFlush 请求可能不够频繁,无法避免 XLogInsertRecord 自己去执行写出。在这种系统上,应增加 WAL 缓冲区的数量,具体做法是修改参数 @@ -532,9 +532,9 @@ 参数 决定 PostgreSQL 将如何请求内核把 - WAL 更新强制刷到磁盘。就可靠性而言,所有选项应当都是相同 + WAL 更新强制刷盘。就可靠性而言,所有选项应当都是相同 的;例外是 fsync_writethrough,它有时能够在其他选项做不 - 到时强制刷新磁盘缓存。不过,具体哪个选项速度最快则高度依赖平台。可以使用 + 到时强制将磁盘缓存中的数据刷盘。不过,具体哪个选项速度最快则高度依赖平台。可以使用 程序测试不同选项的速度。请注意,如果 fsync 已被关闭,那么这个参数就没有意义。 diff --git a/zh/10/xaggr.sgml b/zh/10/xaggr.sgml index c97aed1c..10b82858 100644 --- a/zh/10/xaggr.sgml +++ b/zh/10/xaggr.sgml @@ -42,11 +42,11 @@ SELECT sum(a) FROM test_complex; - 如果没有非空输入值,上述sum定义将返回零(即初始状态值)。也许我们更希望在这种情况下返回空值 — SQL 标准要求sum这样做。实现这一点只需省略initcond短语,使初始状态值为空。通常这意味着sfunc需要检查输入的状态值是否为空。但对于sum以及maxmin这类其他简单聚合,只需把第一个非空输入值放入状态变量,然后从第二个非空输入值开始应用转移函数即可。如果初始状态值为空,并且转移函数被标记为strict(即不会对空输入调用),PostgreSQL会自动这样做。 + 如果没有非空输入值,上述sum定义将返回零(即初始状态值)。也许我们更希望在这种情况下返回空值 — SQL 标准要求sum这样做。实现这一点只需省略initcond短语,使初始状态值为空值。通常这意味着sfunc需要检查输入的状态值是否为空值。但对于sum以及maxmin这类其他简单聚合,只需把第一个非空输入值放入状态变量,然后从第二个非空输入值开始应用转移函数即可。如果初始状态值为空值,并且转移函数被标记为strict(即不会对空值输入调用),PostgreSQL会自动这样做。 - strict转移函数的另一项默认行为是,只要遇到空输入值,就会保留先前的状态值不变。因此,空值会被忽略。如果你需要对空输入采用其他行为,就不要把转移函数声明为 strict,而应在函数代码中自行检测空输入并完成所需处理。 + strict转移函数的另一项默认行为是,只要遇到空值输入,就会保留先前的状态值不变。因此,空值会被忽略。如果你需要对空值输入采用其他行为,就不要把转移函数声明为 strict,而应在函数代码中自行检测空值输入并完成所需处理。 @@ -71,7 +71,7 @@ CREATE AGGREGATE avg (float8) - SQL 中的聚合函数调用允许使用DISTINCTORDER BY选项,以控制哪些行会传递给聚合的转移函数,以及传递顺序。这些选项是在后台实现的,并不是聚合支持函数需要关心的事情。 + SQL 中的聚合函数调用允许使用DISTINCTORDER BY选项,以控制哪些行会传递给聚合的转移函数,以及传递顺序。这些选项由系统在内部实现,并不是聚合支持函数需要关心的事情。 @@ -283,7 +283,7 @@ SELECT percentile_disc(0.5) WITHIN GROUP (ORDER BY income) FROM households; - 与普通聚合不同,有序集聚合的输入行排序不是在幕后完成的,而是由聚合的支持函数负责。典型的实现方法是在聚合的状态值中保存一个tuplesort对象的引用,把输入行送入该对象,然后在最终函数中完成排序并读出数据。这样的设计使最终函数可以执行特殊操作,例如向待排序数据中注入额外的假想行。普通聚合通常可以使用由PL/pgSQL或其他 PL 语言编写的支持函数来实现,但有序集聚合通常必须用 C 编写,因为它们的状态值无法定义为任何 SQL 数据类型。(在上面的示例中,注意状态值被声明为internal类型 — 这很典型。) + 与普通聚合不同,有序集聚合的输入行排序不是由系统在内部完成的,而是由聚合的支持函数负责。典型的实现方法是在聚合的状态值中保存一个tuplesort对象的引用,把输入行送入该对象,然后在最终函数中完成排序并读出数据。这样的设计使最终函数可以执行特殊操作,例如向待排序数据中注入额外的假想行。普通聚合通常可以使用由PL/pgSQL或其他 PL 语言编写的支持函数来实现,但有序集聚合通常必须用 C 编写,因为它们的状态值无法定义为任何 SQL 数据类型。(在上面的示例中,注意状态值被声明为internal类型 — 这很典型。) @@ -352,7 +352,7 @@ if (AggCheckCallContext(fcinfo, NULL)) 检查这一点的一个原因是,如果对状态转移函数来说结果为真,那么第一个输入一定是临时状态值,因此可以安全地原地修改,而不必分配一个新副本。示例见int8inc()。(这是函数可以安全地修改按引用传递的输入的唯一情况。特别是,普通聚合的最终函数在任何情况下都不得修改其输入,因为在某些情况下,它们会在同一个最终状态值上被再次执行。) - AggCheckCallContext的第二个参数可用于取得保存聚合状态值的内存上下文。这对于希望把扩展对象(见)用作状态值的转移函数很有用。第一次调用时,转移函数应返回一个扩展对象,其内存上下文是聚合状态上下文的子上下文;之后的调用则持续返回同一个扩展对象。示例见array_append()。(array_append()并不是任何内置聚合的转移函数,但它的写法保证了在用作自定义聚合的转移函数时也能高效工作。) + AggCheckCallContext的第二个参数可用于取得保存聚合状态值的内存上下文。这对于希望把展开对象(见)用作状态值的转移函数很有用。第一次调用时,转移函数应返回一个展开对象,其内存上下文是聚合状态上下文的子上下文;之后的调用则持续返回同一个展开对象。示例见array_append()。(array_append()并不是任何内置聚合的转移函数,但它的写法保证了在用作自定义聚合的转移函数时也能高效工作。) diff --git a/zh/10/xfunc.sgml b/zh/10/xfunc.sgml index 5077f645..6ce6b359 100644 --- a/zh/10/xfunc.sgml +++ b/zh/10/xfunc.sgml @@ -4,8 +4,8 @@ 用户定义的函数 - function - user-defined + 函数 + 用户定义的 @@ -36,11 +36,11 @@ - 每一类函数可以采用基本类型、复合类型或者它们的组合作为参数。此外,每一类函数可以返回一个基本类型或一个复合类型。函数也能被定义成返回基本类型或复合类型值的集合。 + 每一类函数可以采用基础类型、复合类型或者它们的组合作为参数。此外,每一类函数可以返回一个基础类型或一个复合类型。函数也能被定义成返回基础类型或复合类型值的集合。 - 很多类函数可以接受或者返回特定的伪类型(例如,多态类型),但是可用的功能会变化。详情可以参考每一种函数的描述。 + 很多类函数可以接受或者返回特定的伪类型(例如,多态类型),但是可用的功能因函数类别而异。详情可以参考每一种函数的描述。 定义SQL函数最容易,因此我们将从讨论它们开始。大部分SQL函数的概念也能用到其他类型的函数上。 @@ -57,7 +57,7 @@ 函数 用户定义的 - in SQL + 在 SQL 中 @@ -71,7 +71,7 @@ SQL 函数的函数体必须是一个由分号分隔的 SQL 语句列表。最后一条语句后的分号是可选的。除非该函数被声明为返回 void,否则最后一条语句必须是 SELECT,或者是 INSERTUPDATEDELETE 并带有 RETURNING 子句。 任意一组 SQL 语言命令都可以打包并定义成函数。除 SELECT 查询外,这些命令还可以包含数据修改查询(INSERT, - UPDATEDELETE),以及其他 SQL 命令。(不能使用事务控制命令,例如 COMMITSAVEPOINT,以及某些实用命令,例如 VACUUM,来编写 SQL 函数。)不过,最后一条命令必须是 SELECT,或者带有 RETURNING 子句,并返回与函数声明返回类型相符的结果。或者,如果你想定义一个执行动作但没有有用返回值的 SQL 函数,也可以把它定义为返回 void。例如,下面这个函数会删除 emp 表中薪资为负的行: + UPDATEDELETE),以及其他 SQL 命令。(不能使用事务控制命令,例如 COMMITSAVEPOINT,以及某些工具命令,例如 VACUUM,来编写 SQL 函数。)不过,最后一条命令必须是 SELECT,或者带有 RETURNING 子句,并返回与函数声明返回类型相符的结果。或者,如果你想定义一个执行动作但没有有用返回值的 SQL 函数,也可以把它定义为返回 void。例如,下面这个函数会删除 emp 表中薪资为负的行: CREATE FUNCTION clean_emp() RETURNS void AS ' DELETE FROM emp WHERE salary < 0; @@ -140,10 +140,10 @@ INSERT INTO $1 VALUES (42); - 基本类型上的<acronym>SQL</acronym>函数 + 基础类型上的<acronym>SQL</acronym>函数 - 最简单的 SQL 函数没有参数,只是返回一个基本类型,例如 + 最简单的 SQL 函数没有参数,只是返回一个基础类型,例如 integer @@ -169,7 +169,7 @@ SELECT one(); - 定义接受基本类型参数的 SQL 函数也几乎同样容易: + 定义接受基础类型参数的 SQL 函数也几乎同样容易: CREATE FUNCTION add_em(x integer, y integer) RETURNS integer AS $$ @@ -288,17 +288,17 @@ SELECT name, double_salary(emp.*) AS dream 注意这里用 $1.salary 语法来选取参数行值中的一个字段。 还要注意,调用时的 SELECT 命令使用 - table_name.* 将表的当前整行取作一个组合值。该表行也可以仅用表名来引用: + table_name.* 将表的当前整行取作一个复合值。该表行也可以仅用表名来引用: SELECT name, double_salary(emp) AS dream FROM emp WHERE emp.cubicle ~= point '(2,1)'; - 但这种用法已被废弃,因为它很容易让人混淆(关于表行组合值这两种记法的更多细节,见)。 + 但这种用法已被弃用,因为它很容易让人混淆(关于表行复合值这两种记法的更多细节,见)。 - 有时候即时构造一个组合参数会很方便。这可以用ROW构造器完成。 + 有时候即时构造一个复合参数值会很方便。这可以用ROW构造器完成。 例如,我们可以调整被传递给函数的数据: SELECT name, double_salary(ROW(name, salary*1.1, age, cubicle)) AS dream @@ -321,9 +321,12 @@ $$ LANGUAGE SQL; 在这个示例中,我们为每一个属性指定了一个常量值,但是可以用任何计算来替换这些常量。 - 定义该函数时要注意两件重要的事情: + + 定义该函数时有两点重要注意事项: + + - 查询中的选择列表顺序必须与列在该复合类型所关联的表中出现的顺序完全相同。(正如我们上面所做的那样,命名列与系统无关。) + 查询中的选择列表顺序必须与列在该复合类型所关联的表中出现的顺序完全相同。(系统不考虑像上面这样指定的列名。) 你必须对表达式进行类型转换,使之与复合类型的定义匹配,否则会得到这样的错误: @@ -402,7 +405,7 @@ SELECT name(new_emp()); - 另一种使用函数返回复合类型的方法是将结果传递给另一个接受正确行类型作为输入的函数: + 另一种使用函数返回复合类型的方法是将结果传递给另一个接受正确行类型作为输入的函数: CREATE FUNCTION getname(emp) RETURNS text AS $$ @@ -490,12 +493,12 @@ DROP FUNCTION sum_n_product (int, int); 带有可变数量参数的<acronym>SQL</acronym>函数 - function - variadic + 函数 + 可变参数 - variadic function + 可变参数函数 @@ -526,27 +529,27 @@ SELECT mleast(ARRAY[10, -1, 5, 4.4]); -- doesn't work - 有时候,能够把一个已经构造好的数组传给 variadic 函数会很有用,尤其是当一个 variadic 函数想把它的数组参数再传给另一个函数时。此外,在允许不受信任用户创建对象的模式中调用 variadic 函数时,这是唯一安全的方式,见。你可以在调用中指定VARIADIC来做到这一点: + 有时候,能够把一个已经构造好的数组传给可变参数函数会很有用,尤其是当一个可变参数函数想把它的数组参数再传给另一个函数时。此外,在允许不受信任用户创建对象的模式中调用可变参数函数时,这是唯一安全的方式,见。你可以在调用中指定VARIADIC来做到这一点: SELECT mleast(VARIADIC ARRAY[10, -1, 5, 4.4]); - 这样会阻止函数的 variadic 参数按其元素类型展开,从而让数组实参能够按常规方式匹配。VARIADIC 只能附加在函数调用的最后一个实参上。 + 这样会阻止函数的可变参数按其元素类型展开,从而让数组实参能够按常规方式匹配。VARIADIC 只能附加在函数调用的最后一个实参上。 - 在调用中指定VARIADIC也是向 variadic 函数传递空数组的唯一方式,例如: + 在调用中指定VARIADIC也是向可变参数函数传递空数组的唯一方式,例如: SELECT mleast(VARIADIC ARRAY[]::numeric[]); - 仅仅写成SELECT mleast()是行不通的,因为 variadic 参数必须匹配至少一个实参。(如果你希望允许这种调用,可以再定义一个同名且不带参数的函数mleast。) + 仅仅写成SELECT mleast()是行不通的,因为可变参数必须匹配至少一个实参。(如果你希望允许这种调用,可以再定义一个同名且不带参数的函数mleast。) - 从 variadic 参数派生出的数组元素参数会被视为没有自己的名字。这意味着除非你指定了 VARIADIC,否则不能使用命名参数来调用 variadic 函数()。例如,下面的调用是可行的: + 从可变参数派生出的数组元素参数会被视为没有自己的名字。这意味着除非你指定了 VARIADIC,否则不能使用命名参数来调用可变参数函数()。例如,下面的调用是可行的: SELECT mleast(VARIADIC arr => ARRAY[10, -1, 5, 4.4]); @@ -565,7 +568,7 @@ SELECT mleast(arr => ARRAY[10, -1, 5, 4.4]); 带有参数默认值的<acronym>SQL</acronym>函数 - function + 函数 参数的默认值 @@ -574,7 +577,7 @@ SELECT mleast(arr => ARRAY[10, -1, 5, 4.4]); 没有给出足够多的实参,就会插入默认值来弥补缺失的实参。由于参数只 能从实参列表的尾部开始被省略,在一个有默认值的参数之后的所有参数 都不得不也具有默认值(尽管使用命名参数记法可以允许放松这种限制, - 这种限制仍然会被强制以便位置参数记法能工作)。不管你是否使用它,这种能力都要求在某些用户不信任其他用户的数据中调用函数时做一些预防措施,见。 + 这种限制仍然会被强制以便位置参数记法能工作)。不管你是否使用它,这种能力都要求在某些用户不信任其他用户的数据库中调用函数时做一些预防措施,见 @@ -617,13 +620,13 @@ ERROR: function foo() does not exist 所有的 SQL 函数都可以被用在查询的FROM子句中,但是 - 对于返回复合类型的函数特别有用。如果函数被定义为返回一种基本类型, + 对于返回复合类型的函数特别有用。如果函数被定义为返回一种基础类型, 该表函数会产生一个单列表。如果该函数被定义为返回一种复合类型,该 表函数会为该复合类型的每一个属性产生一列。 - 以下是一个示例: + 以下是一个示例: CREATE TABLE foo (fooid int, foosubid int, fooname text); @@ -656,8 +659,8 @@ SELECT *, upper(fooname) FROM getfoo(1) AS t1; 返回集合的<acronym>SQL</acronym>函数 - function - with SETOF + 函数 + 使用 SETOF @@ -805,7 +808,7 @@ SELECT srf1(srf2(x), srf3(y)), srf4(srf5(z)) FROM tab; SELECT x, CASE WHEN x > 0 THEN generate_series(1, 5) ELSE 0 END FROM tab; - 看起来这个语句应该产生满足x > 0的输入行的五次重复,以及不满足的行的一次重复。但实际上,由于在CASE表达时被计算前,generate_series(1, 5)会被运行在一个隐式的LATERAL FROM项中,它会为每个输入行产生五次重复。为了减少混乱,这类情况会产生一个解析时错误。 + 看起来这个语句应该产生满足x > 0的输入行的五次重复,以及不满足的行的一次重复。但实际上,由于在CASE表达式被计算前,generate_series(1, 5)会被运行在一个隐式的LATERAL FROM项中,它会为每个输入行产生五次重复。为了减少混乱,这类情况会产生一个解析时错误。 @@ -817,11 +820,11 @@ SELECT x, CASE WHEN x > 0 THEN generate_series(1, 5) ELSE 0 END FROM tab; 在 PostgreSQL 10 之前,除非多个集合返回函数始终产生相同数量的行,否则把它们放在同一个选择列表中的行为并不合理。 否则,得到的输出行数会是这些集合返回函数各自产生行数的最小公倍数。 此外,嵌套的集合返回函数也不像上文所描述的那样工作;相反,一个集合返回函数至多只能有一个集合返回参数, - 并且每一层嵌套都会独立运行。再加上过去还允许条件执行(即在 CASE 等结构内部使用集合返回函数), + 并且每一组嵌套的集合返回函数都会独立运行。再加上过去还允许条件执行(即在 CASE 等结构内部使用集合返回函数), 事情就更加复杂了。 如果你要编写需要在旧版 PostgreSQL 上运行的查询,建议使用 LATERAL 语法, 因为这样在不同版本之间能够得到一致的结果。 - 如果你的查询依赖于集合返回函数的条件执行,可以把条件判断移动到自定义集合返回函数内部来修复。例如, + 如果你的查询依赖于集合返回函数的条件执行,或许可以把条件判断移动到自定义集合返回函数内部来修复。例如, SELECT x, CASE WHEN y > 0 THEN generate_series(1, z) ELSE 5 END FROM tab; @@ -839,7 +842,7 @@ END$$ LANGUAGE plpgsql; SELECT x, case_generate_series(y > 0, 1, z, 5) FROM tab; - 这种写法在所有版本的 PostgreSQL 中都能正常工作。 + 这种写法在所有版本的 PostgreSQL 中的行为都相同。 @@ -848,7 +851,7 @@ SELECT x, case_generate_series(y > 0, 1, z, 5) FROM tab; 返回<literal>TABLE</literal>的<acronym>SQL</acronym>函数 - function + 函数 RETURNS TABLE @@ -937,7 +940,7 @@ SELECT * FROM dup(22); - 多态也可以用于 variadic 函数。例如: + 多态也可以用于可变参数函数。例如: CREATE FUNCTION anyleast (VARIADIC anyarray) RETURNS anyelement AS $$ SELECT min($1[i]) FROM generate_subscripts($1, 1) g(i); @@ -972,11 +975,11 @@ SELECT concat_values('|', 1, 4, 2); 带有排序规则的<acronym>SQL</acronym>函数 - collation - in SQL functions + 排序规则 + 在 SQL 函数中 - 当一个 SQL 函数有一个或多个可设定排序规则的数据类型参数时,会根据实参所带的排序规则,为每次函数调用确定一个排序规则,详见 。如果能够成功确定(也就是说,参数之间不存在隐式排序规则冲突),那么所有可设定排序规则的参数都会被视为隐式带有该排序规则。这会影响函数中对排序规则敏感的操作的行为。例如,使用上文的 anyleast 函数时, + 当一个 SQL 函数有一个或多个支持排序规则的数据类型参数时,会根据实参所带的排序规则,为每次函数调用确定一个排序规则,详见 。如果能够成功确定(也就是说,参数之间不存在隐式排序规则冲突),那么所有支持排序规则的参数都会被视为隐式带有该排序规则。这会影响函数中对排序规则敏感的操作的行为。例如,使用上文的 anyleast 函数时, SELECT anyleast('abc'::text, 'ABC'); 的结果将取决于数据库的默认排序规则。在 C 区域设置下,结果会是 ABC,但在许多其他区域设置下则会是 abc。可以在任意参数上添加 COLLATE 子句来强制指定要使用的排序规则,例如: SELECT anyleast('abc'::text, 'ABC' COLLATE "C"); @@ -984,7 +987,7 @@ SELECT anyleast('abc'::text, 'ABC' COLLATE "C"); CREATE FUNCTION anyleast (VARIADIC anyarray) RETURNS anyelement AS $$ SELECT min($1[i] COLLATE "en_US") FROM generate_subscripts($1, 1) g(i); $$ LANGUAGE SQL; -但请注意,如果把它用于不可设定排序规则的数据类型,就会抛出错误。 +但请注意,如果把它用于不支持排序规则的数据类型,就会抛出错误。 如果无法在实参之间确定共同的排序规则,那么 SQL 函数会把参数视为带有其数据类型的默认排序规则 @@ -992,7 +995,7 @@ $$ LANGUAGE SQL; - 这种可设定排序规则参数的行为,可以看作是仅适用于文本数据类型的一种受限多态形式。 + 这种支持排序规则的参数的行为,可以看作是仅适用于文本数据类型的一种受限多态形式。 @@ -1001,8 +1004,8 @@ $$ LANGUAGE SQL; 函数重载 - overloading - functions + 重载 + 函数 @@ -1034,10 +1037,10 @@ CREATE FUNCTION test(smallint, double precision) RETURNS ... - 另一类可能的冲突发生在 variadic 函数和非 variadic 函数之间。例如,可以同时创建 + 另一类可能的冲突发生在可变参数函数和非可变参数函数之间。例如,可以同时创建 foo(numeric)foo(VARIADIC numeric[])。 这时,对于只提供一个 numeric 参数的调用(例如 foo(10.1)),就不清楚该匹配哪个函数。 - 规则是:优先使用在搜索路径中出现较早的那个函数;如果两者位于同一模式中,则优先使用非 variadic 函数。 + 规则是:优先使用在搜索路径中出现较早的那个函数;如果两者位于同一模式中,则优先使用非可变参数函数。 @@ -1064,8 +1067,8 @@ CREATE FUNCTION test(int, int) RETURNS int 函数易变性分类 - volatility - functions + 易变性 + 函数 VOLATILE @@ -1082,7 +1085,7 @@ CREATE FUNCTION test(int, int) RETURNS int 一个VOLATILE函数可以做任何事情,包括修改数据库。在 使用相同的参数连续调用时,它能返回不同的结果。优化器不会对这类函 - 数的行为做任何假定。对于在每一行都需要 volatile 函数值的查询,函数都会被重新求值。 + 数的行为做任何假定。使用易变函数的查询会在需要该函数值的每一行上重新对它求值。 @@ -1130,8 +1133,7 @@ CREATE FUNCTION test(int, int) RETURNS int 在考虑先规划然后立即执行的简单交互式查询时,在STABLEIMMUTABLE分类间的区别相对较小:一个函数是在规划时只 执行一次还是在查询执行开始期间只执行一次没有太大关系。但是如果计划 - 被保存下来然后在后面被重用,区别就大了。如果在不允许过早把一个函数 - 变成规划期间的一个常数时把它标记为IMMUTABLE,会导致 + 被保存下来然后在后面被重用,区别就大了。如果把一个实际上并非不可变的函数标记为IMMUTABLE,就可能在规划期间过早将它折叠成常量,导致 在后续重用该计划时继续使用陈旧的值。在使用预备语句,或使用会缓存执行计划的函数语言(如 PL/pgSQL)时,这会带来严重问题。 @@ -1199,7 +1201,7 @@ CREATE FUNCTION test(int, int) RETURNS int 内部函数 - functioninternal + 函数内部 内部函数由 C 编写并且已经被静态链接到PostgreSQL @@ -1237,9 +1239,9 @@ CREATE FUNCTION square_root(double precision) RETURNS double precision C 语言函数 - function - user-defined - in C + 函数 + 用户定义的 + 在 C 中 @@ -1263,17 +1265,17 @@ CREATE FUNCTION square_root(double precision) RETURNS double precision - 在一个会话中第一次调用一个特定可载入对象文件中的用户定义函数时, - 动态载入器会把那个对象文件载入到内存以便该函数被调用。因此用户 + 在一个会话中第一次调用一个特定可载入目标文件中的用户定义函数时, + 动态载入器会把那个目标文件载入到内存以便该函数被调用。因此用户 定义的 C 函数的CREATE FUNCTION必须 - 为该函数指定两块信息:可载入对象文件的名称,以及要在该对象文件中 + 为该函数指定两块信息:可载入目标文件的名称,以及要在该目标文件中 调用的特定函数的 C 名称(链接符号)。如果没有显式指定 C 名称,则 它被假定为和 SQL 函数名相同。 下面的算法被用来基于CREATE FUNCTION - 命令中给定的名称来定位共享对象文件: + 命令中给定的名称来定位共享目标文件: @@ -1332,16 +1334,16 @@ CREATE FUNCTION square_root(double precision) RETURNS double precision PostgreSQL不会自动编译 C 函数。在 - 从CREATE FUNCTION命令中引用对象文件 + 从CREATE FUNCTION命令中引用目标文件 之前,它必须先被编译好。更多信息请见 - magic block + 魔数块 - 为确保动态装载的对象文件不会被加载到不兼容的服务器中,PostgreSQL会检查该文件是否包含内容适当的magic block。这样服务器就能检测出明显的不兼容情况,例如代码所针对的大版本不同于当前的 PostgreSQL。magic block 自 PostgreSQL 8.2 起就是必需的。要加入 magic block,请在模块某一个(且只能一个)源文件中写入下列内容,并事先包含头文件 fmgr.h: + 为确保动态装载的目标文件不会被加载到不兼容的服务器中,PostgreSQL会检查该文件是否包含内容适当的魔数块。这样服务器就能检测出明显的不兼容情况,例如代码所针对的大版本不同于当前的 PostgreSQL。魔数块自 PostgreSQL 8.2 起就是必需的。要加入魔数块,请在模块某一个(且只能一个)源文件中写入下列内容,并事先包含头文件 fmgr.h #ifdef PG_MODULE_MAGIC @@ -1350,9 +1352,9 @@ PG_MODULE_MAGIC; 可以省略 #ifdef 检查,如果代码不需要针对 8.2 之前的 PostgreSQL 版本编译的话。 - 在第一次使用之后,动态载入对象文件会保留在内存中。在同一个会话中, + 在第一次使用之后,动态载入目标文件会保留在内存中。在同一个会话中, 后续对该文件中函数的调用只需付出一次很小的符号表查找开销。如果需要 - 强制重新载入一个对象文件(例如在重新编译之后),就需要开启一个新的会话。 + 强制重新载入一个目标文件(例如在重新编译之后),就需要开启一个新的会话。 @@ -1371,7 +1373,7 @@ PG_MODULE_MAGIC; - C 语言函数中的基本类型 + C 语言函数中的基础类型 数据类型 @@ -1380,16 +1382,16 @@ PG_MODULE_MAGIC; 要了解如何编写 C 语言函数,你需要了解 - PostgreSQL如何在内部表达基本数据类型 + PostgreSQL如何在内部表达基础类型 以及如何与函数传递它们。在内部, - PostgreSQL把基本类型视为一块内存数据块。 + PostgreSQL把基础类型视为一块内存数据块。 你为该类型定义的用户自定义函数,决定了 PostgreSQL 如何操作它。 也就是说,PostgreSQL 只负责把数据存到磁盘、再从磁盘取回, 而数据的输入、处理和输出则依赖你定义的这些函数。 - 基本类型可以有三种内部格式之一: + 基础类型可以有三种内部格式之一: @@ -1454,10 +1456,9 @@ typedef struct 最后,所有变长类型必须也以引用的方式传递。所有变长类型必须用一个 - 正好 4 字节的不透明长度域开始,该域会由SET_VARSIZE - 设置,绝不要直接设置该域!所有要被存储在该类型中的数据必须在内存 - 中接着该长度域的后面存储。长度域包含该结构体的总长度,也就是包括长 - 度域本身的尺寸。 + 正好 4 字节的不透明长度字段开始,该字段会由SET_VARSIZE + 设置,绝不要直接设置该字段!所有要被存储在该类型中的数据必须在内存 + 中接着该长度字段的后面存储。长度字段包含该结构体的总长度,也就是包括长度字段本身的尺寸。 @@ -1507,16 +1508,16 @@ memcpy(destination->data, buffer, 40); VARHDRSZsizeof(int32)一样, - 但是用宏VARHDRSZ来引用变长类型的载荷的 + 但是用宏VARHDRSZ来引用变长类型的额外开销的 尺寸被认为是比较好的风格。还有,必须 - 使用SET_VARSIZE宏来设置长度域,而不是用 + 使用SET_VARSIZE宏来设置长度字段,而不是用 简单的赋值来设置。 展示了 PostgreSQL 中许多内置 SQL 数据类型所对应的 C 类型。 - Defined In列给出了需要包含的头文件,以获取类型定义。 + 定义文件列给出了需要包含的头文件,以获取类型定义。 (实际的定义可能位于所列文件包含的其他文件中。建议用户坚持使用已定义的接口。) 请注意,在服务器代码的任何源文件中,都应该始终首先包含postgres.h, 因为它声明了很多你反正都会用到的内容,而且先包含其他头文件可能会带来可移植性问题。 @@ -1704,8 +1705,7 @@ memcpy(destination->data, buffer, 40);
- 现在我们已经复习了基本类型所有可能的结构,现在可以展示一些 - 真实函数的示例了。 + 了解了基础类型所有可能的结构后,就可以看一些实际函数示例。 @@ -1713,7 +1713,7 @@ memcpy(destination->data, buffer, 40); 版本 1 的调用约定 - 版本-1 的调用规范依赖于宏来降低传参数和结果的复杂度。版本-1 函数的 + 版本-1 的调用约定依赖于宏来降低传参数和结果的复杂度。版本-1 函数的 C 声明总是: Datum funcname(PG_FUNCTION_ARGS) @@ -1725,14 +1725,16 @@ PG_FUNCTION_INFO_V1(funcname); 必须出现在同一个源文件中(按惯例会正好写在该函数本身之前)。 这种宏调用不是internal语言函数所需要的,因为 PostgreSQL会假定所有内部函数都使用 - 版本-1 规范。不过,对于动态载入函数是必需的。 + 版本-1 调用约定。不过,对于动态载入函数是必需的。 - 在版本-1 函数中,每一个实参都使用对应于该参数数据类型的PG_GETARG_xxx()宏取得。(在非严格的函数中,需要使用PG_ARGISNULL()对参数是否为空提前做检查;见下文。)结果要用对应于返回类型的PG_RETURN_xxx()宏返回。PG_GETARG_xxx()的参数是要取得的函数参数的编号,从零开始计。PG_RETURN_xxx()的参数是实际要返回的值。 + 在版本-1 函数中,每一个实参都使用对应于该参数数据类型的PG_GETARG_xxx()宏取得。(在非严格的函数中,需要使用PG_ARGISNULL()对参数是否为空值提前做检查;见下文。)结果要用对应于返回类型的PG_RETURN_xxx()宏返回。PG_GETARG_xxx()的参数是要取得的函数参数的编号,从零开始计。PG_RETURN_xxx()的参数是实际要返回的值。 - 下面是一些使用版本-1 调用约定的示例: + + 这里是一些使用版本-1调用约定的示例: + - 注意我们已经把函数指定为strict,这意味着如果有任何输入值为空,系统应该自动假定得到空结果。通过这种做法,我们避免在函数代码中检查空值输入。如果不这样做,我们必须使用PG_ARGISNULL()明确地检查空值输入。 + 注意我们已经把函数指定为strict,这意味着如果有任何输入值为空值,系统应该自动假定结果为空值。通过这种做法,我们避免在函数代码中检查空值输入。如果不这样做,我们必须使用PG_ARGISNULL()明确地检查空值输入。 - 宏PG_ARGISNULL(n)允许一个函数测试是否每一个输入为空(当然,只需要在没有声明为strict的函数中这样做)。和PG_GETARG_xxx()宏一样,输入参数也是从零开始计数。注意应该在验证了一个参数不是空之后才执行PG_GETARG_xxx()。要返回一个空结果,应执行PG_RETURN_NULL(),它对严格的以及非严格的函数都有用。 + 宏PG_ARGISNULL(n)允许一个函数测试是否每一个输入为空值(当然,只需要在没有声明为strict的函数中这样做)。和PG_GETARG_xxx()宏一样,输入参数也是从零开始计数。注意应该在验证了一个参数不是空值之后才执行PG_GETARG_xxx()。要返回空值结果,应执行PG_RETURN_NULL(),它对严格的以及非严格的函数都有用。 @@ -1876,11 +1878,11 @@ CREATE FUNCTION concat_text(text, text) RETURNS text - 在版本-1接口中提供的其他选项是PG_GETARG_xxx()宏的两个变种。其中的第一种是PG_GETARG_xxx_COPY(),它确保返回的指定参数的拷贝可以被安全地写入(通常的宏有时会返回一个指向表中物理存储的值,它不能被写入。使用PG_GETARG_xxx_COPY()宏可以保证得到一个可写的结果)。第二种变种PG_GETARG_xxx_SLICE()宏有三个参数。第一个是函数参数的编号(如上文)。第二个和第三个是要被返回的段的偏移量和长度。偏移量从零开始计算,而负值的长度则表示要求返回该值的剩余部分。当大型值的存储类型为external时,这些宏提供了访问这些大型值的更有效的方法(列的存储类型可以使用ALTER TABLE tablename ALTER COLUMN colname SET STORAGE storagetype来指定。storagetypeplainexternalextended或者main)。 + 在版本-1接口中提供的其他选项是PG_GETARG_xxx()宏的两个变种。其中的第一种是PG_GETARG_xxx_COPY(),它确保返回的指定参数的拷贝可以被安全地写入(通常的宏有时会返回一个指向表中物理存储值的指针,不能写入该值。使用PG_GETARG_xxx_COPY()宏可以保证得到一个可写的结果)。第二种变种PG_GETARG_xxx_SLICE()宏有三个参数。第一个是函数参数的编号(如上文)。第二个和第三个是要被返回的段的偏移量和长度。偏移量从零开始计算,而负值的长度则表示要求返回该值的剩余部分。当大型值的存储类型为external时,这些宏提供了访问这些大型值的部分内容的更有效方法(列的存储类型可以使用ALTER TABLE tablename ALTER COLUMN colname SET STORAGE storagetype来指定。storagetypeplainexternalextended或者main)。 - 最后,版本-1 的函数调用规范可以返回集合结果()、实现触发器函数()和过程语言调用处理器()。更多细节 + 最后,版本-1 的函数调用约定可以返回集合结果()、实现触发器函数()和过程语言调用处理器()。更多细节 可见源代码发布中的src/backend/utils/fmgr/README @@ -1891,18 +1893,24 @@ CREATE FUNCTION concat_text(text, text) RETURNS text 在开始更高级的话题之前,我们应该讨论一下用于 PostgreSQL C 语言函数的编码规则。 - 虽然可以把不是 C 编写的函数载入到 - PostgreSQL中,这通常是很困难的, + 虽然有可能把不是 C 编写的函数载入到 + PostgreSQL中,但即使能够做到,通常也很困难, 因为其他语言(例如 C++、FORTRAN 或者 Pascal)通常不会遵循和 C - 相同的调用规范。也就是说,其他语言不会以同样的方式在函数之间传递 + 相同的调用约定。也就是说,其他语言不会以同样的方式在函数之间传递 参数以及返回值。由于这个原因,我们会假定你的 C 语言函数确实是用 C 编写的。 - 编写和构建 C 函数的基本规则如下: + + 编写和构建 C 语言函数的基本规则如下: + + - 使用pg_config - --includedir-serverpg_config用于用户定义的 C 函数来确定PostgreSQL服务器头文件在你的系统(或用户将要运行的系统)上的安装位置。 + + 使用 pg_config + --includedir-serverpg_config用于用户定义的 C 函数 + 查出 PostgreSQL 服务器头文件在你的系统上(或你的用户将要运行的系统上)安装于何处。 + @@ -1913,7 +1921,7 @@ CREATE FUNCTION concat_text(text, text) RETURNS text - 记得按照中的说明,为你的共享库定义一个magic block。 + 记得按照中的说明,为你的共享库定义一个魔数块 @@ -1939,7 +1947,7 @@ CREATE FUNCTION concat_text(text, text) RETURNS text - 对象文件中定义的符号名不能彼此冲突,也不能与 + 目标文件中定义的符号名不能彼此冲突,也不能与 PostgreSQL 服务器可执行文件中定义的符号冲突。如果你收到这类错误消息,就必须重命名相关函数或变量。 @@ -1950,10 +1958,10 @@ CREATE FUNCTION concat_text(text, text) RETURNS text 复合类型没有像 C 结构体那样的固定布局。复合类型的实例可能包含 - 空值域。此外,继承层次中的复合类型可能具有和同一继承层次中 - 其他成员不同的域。因此, + 空值字段。此外,继承层次中的复合类型可能具有和同一继承层次中 + 其他成员不同的字段。因此, PostgreSQL提供了函数接口 - 来访问 C 的复合类型的域。 + 以便从 C 访问复合类型的字段。 假设我们想编写一个函数来回答如下查询: @@ -1991,12 +1999,12 @@ c_overpaid(PG_FUNCTION_ARGS) GetAttributeByName 是 - PostgreSQL 的一个系统函数,用于从指定行中取出属性。它有三个参数:传入函数的 HeapTupleHeader 类型参数、所需属性的名称,以及一个用于指示该属性是否为 null 的返回参数。GetAttributeByName 返回一个 Datum 值,你可以用适当的 DatumGetXXX() 函数把它转换为正确的数据类型。注意,如果 null 标志被设置,那么返回值本身没有意义;在尝试对结果做任何处理之前,务必先检查这个 null 标志。 + PostgreSQL 的一个系统函数,用于从指定行中取出属性。它有三个参数:传入函数的 HeapTupleHeader 类型参数、所需属性的名称,以及一个用于指示该属性是否为 null 的返回参数。GetAttributeByName 返回一个 Datum 值,你可以用适当的 DatumGetXXX() 宏把它转换为正确的数据类型。注意,如果 null 标志被设置,那么返回值本身没有意义;在尝试对结果做任何处理之前,务必先检查这个 null 标志。 也有GetAttributeByNum函数,它可以用目标属性 - 的属性号而不是属性名来选择目标属性。 + 的列号而不是属性名来选择目标属性。 @@ -2018,14 +2026,14 @@ CREATE FUNCTION c_overpaid(emp, integer) RETURNS boolean 要从 C 语言函数中返回一行或一个复合类型值,可以使用一套特殊的 API, - 它通过一组宏和函数隐藏了构造组合数据类型时的大部分复杂性。要使用这套 API,源文件中必须包含: + 它通过一组宏和函数隐藏了构造复合数据类型时的大部分复杂性。要使用这套 API,源文件中必须包含: #include "funcapi.h" - 构造组合数据值(下文简称元组)有两种方式: + 构造复合数据值(下文简称元组)有两种方式: 一种是从 Datum 值数组构造,另一种是从 C 字符串数组构造,这些字符串会传给该元组各列数据类型的输入转换函数。 无论采用哪种方式,首先都需要获取或构造描述该元组结构的 TupleDesc。 处理 Datum 时,需要把 TupleDesc 传给 BlessTupleDesc,然后为每一行调用 heap_form_tuple。 @@ -2034,13 +2042,13 @@ CREATE FUNCTION c_overpaid(emp, integer) RETURNS boolean - 有一些辅助函数可以用来设置所需的 TupleDesc。在大多数返回组合值的函数中,推荐的做法是调用: + 有一些辅助函数可以用来设置所需的 TupleDesc。在大多数返回复合值的函数中,推荐的做法是调用: TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc) - 传入与调用函数本身相同的 fcinfo 结构体(这当然要求使用版本 1 调用约定)。 + 传入调用函数本身收到的同一个 fcinfo 结构体(这当然要求使用版本 1 调用约定)。 resultTypeId 可以指定为 NULL,也可以指定为一个本地变量的地址,用于接收函数结果类型的 OID。 resultTupleDesc 应当是一个本地 TupleDesc 变量的地址。 检查返回结果是否为 TYPEFUNC_COMPOSITE;如果是,resultTupleDesc 就会被填入所需的 TupleDesc。 @@ -2059,7 +2067,7 @@ TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, get_call_result_type有一个兄弟 get_expr_result_type,它被用来解析被表示为一棵表达式 - 树的函数调用的输出类型。在尝试确定来自函数外部的结果类型时可以用它。 + 树的函数调用的输出类型。在尝试从函数自身外部确定结果类型时可以用它。 也有一个get_func_result_type,当只有函数的 OID 可用时 可以用它。不过这些函数无法处理被声明为返回record的 函数,并且get_func_result_type无法解析多态类型,因此你 @@ -2068,22 +2076,22 @@ TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo,
- 更早、现在已被废弃的获取TupleDesc的函数有: + 更早、现在已被弃用的获取TupleDesc的函数有: TupleDesc RelationNameGetTupleDesc(const char *relname) - 它可以为一个提到的关系的行类型得到TupleDesc, + 它可以为一个指定名称的关系的行类型得到TupleDesc, 还有: TupleDesc TypeGetTupleDesc(Oid typeoid, List *colaliases) 可以基于一个类型 OID 得到TupleDesc。这可以被用来 - 为一种基础或者复合类型获得TupleDesc。不过,对于 + 为一种基本或者复合类型获得TupleDesc。不过,对于 返回record的函数它不起作用,并且它无法解析多态类型。 - 一旦有了一个TupleDesc,如果计划处理 Datum可以调用: + 一旦有了一个TupleDesc,如果计划处理 Datum,可以调用: TupleDesc BlessTupleDesc(TupleDesc tupdesc) @@ -2093,7 +2101,7 @@ AttInMetadata *TupleDescGetAttInMetadata(TupleDesc tupdesc) 如果正在编写一个返回集合的函数,你可以把这些函数的结果保存在 FuncCallContext结构体中 — 分别使用 - tuple_desc或者attinmeta域。 + tuple_desc或者attinmeta字段。 @@ -2113,8 +2121,7 @@ HeapTuple BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values) values是一个 C 字符串数组,每一个元素是返回行 的一个属性。每一个 C 字符串应该是该属性数据类型的输入函数所期望 的格式。为了对一个属性返回空值,values数组中对 - 应的指针应该被设置为NULL。对于你返回的每一行都将 - 再次调用这个函数。 + 应的指针应该被设置为NULL。对于你返回的每一行都需要再次调用这个函数。 @@ -2149,82 +2156,82 @@ HeapTupleGetDatum(HeapTuple tuple) 使用 ValuePerCall 模式时,重要的是要记住查询不能保证运行完成; 也就是说,由于诸如LIMIT之类的选项, - 执行程序可能会在获取所有行之前停止调用 set-returning 函数。 + 执行器可能会在获取所有行之前停止调用集合返回函数。 这意味着在最后一次调用中执行清理活动是不安全的,因为这可能永远不会发生。 对于需要访问外部资源(例如文件描述符)的函数,建议使用 Materialize 模式。 - 本节的其余部分记录了一组使用 ValuePerCall 模式的 SRF 常用(尽管不是必须使用)的帮助程序宏。 + 本节的其余部分记录了一组使用 ValuePerCall 模式的 SRF 常用(尽管不是必须使用)的辅助宏。 有关 Materialize 模式的其他详细信息可以在src/backend/utils/fmgr/README中找到。 此外,PostgreSQL源代码分发中的contrib 模块包含许多使用 ValuePerCall 和 Materialize 模式的 SRF 示例。 - 要使用这里描述的 ValuePerCall 支持宏,请包含 funcapi.h。这些宏会用到一个结构体 FuncCallContext,该结构体包含需要跨调用保存的状态。在使用这些宏的 SRF 中,fcinfo->flinfo->fn_extra 用于在调用之间保存指向 FuncCallContext 的指针。宏在第一次使用时自动填充该字段,并期望在后续使用中找到相同的指针。 + + 要使用此处描述的 ValuePerCall 支持宏,请包含funcapi.h。 + 这些宏与结构体FuncCallContext一起使用,该结构体包含需要跨调用保存的状态。 + 在使用这些宏的 SRF 中,fcinfo->flinfo->fn_extra用于在调用之间保存 + 指向FuncCallContext的指针。 + 宏在第一次使用时自动填充该字段,并期望在后续使用中找到相同的指针。 + typedef struct FuncCallContext { /* - * Number of times we've been called before + * 本次调用以前已经被调用过多少次 * - * call_cntr is initialized to 0 for you by SRF_FIRSTCALL_INIT(), and - * incremented for you every time SRF_RETURN_NEXT() is called. + * SRF_FIRSTCALL_INIT() 会为你把 call_cntr 初始化为 0, + * 并且在每次调用 SRF_RETURN_NEXT() 时增加。 */ uint64 call_cntr; /* - * OPTIONAL maximum number of calls + * 可选:最大调用次数 * - * max_calls is here for convenience only and setting it is optional. - * If not set, you must provide alternative means to know when the - * function is done. + * 这里的 max_calls 只是为了方便,设置它是可选的。 + * 如果没有设置,你必须提供替代的方法来了解函数什么时候做完。 */ uint64 max_calls; /* - * OPTIONAL pointer to result slot + * 可选:指向结果槽的指针 * - * This is obsolete and only present for backward compatibility, viz, - * user-defined SRFs that use the deprecated TupleDescGetSlot(). + * 此字段已过时,仅为向后兼容而保留,即兼容使用已弃用的 + * TupleDescGetSlot() 的用户定义 SRF。 */ TupleTableSlot *slot; /* - * OPTIONAL pointer to miscellaneous user-provided context information + * 可选:指向用户提供的上下文信息的指针 * - * user_fctx is for use as a pointer to your own data to retain - * arbitrary context information between calls of your function. + * user_fctx 是一个指向你自己的数据的指针,它可用来在函数的多次 + * 调用之间保存任意的上下文信息。 */ void *user_fctx; /* - * OPTIONAL pointer to struct containing attribute type input metadata + * 可选:指向包含属性类型输入元数据的结构的指针 * - * attinmeta is for use when returning tuples (i.e., composite data types) - * and is not used when returning base data types. It is only needed - * if you intend to use BuildTupleFromCStrings() to create the return - * tuple. + * attinmeta 被用在返回元组(即复合数据类型)时,在返回基础类型 + * 时不会使用。只有想用BuildTupleFromCStrings()创建返回元组时才需要它。 */ AttInMetadata *attinmeta; /* - * memory context used for structures that must live for multiple calls + * 用于保存必须在多次调用间都存在的结构的内存上下文 * - * multi_call_memory_ctx is set by SRF_FIRSTCALL_INIT() for you, and used - * by SRF_RETURN_DONE() for cleanup. It is the most appropriate memory - * context for any memory that is to be reused across multiple calls - * of the SRF. + * SRF_FIRSTCALL_INIT() 会为你设置 multi_call_memory_ctx,并且由 + * SRF_RETURN_DONE() 来清理。对于任何需要在 SRF 的多次调用间都 + * 存在的内存来说,它是最合适的内存上下文。 */ MemoryContext multi_call_memory_ctx; /* - * OPTIONAL pointer to struct containing tuple description + * 可选:指向包含元组描述的结构的指针 * - * tuple_desc is for use when returning tuples (i.e., composite data types) - * and is only needed if you are going to build the tuples with - * heap_form_tuple() rather than with BuildTupleFromCStrings(). Note that - * the TupleDesc pointer stored here should usually have been run through - * BlessTupleDesc() first. + * tuple_desc 被用在返回元组(即复合数据类型)时,并且只有在用 + * heap_form_tuple() 而不是 BuildTupleFromCStrings() 构建元组时才需要它。 + * 注意这里存储的 TupleDesc 指针通常已经被先运行过 BlessTupleDesc()。 */ TupleDesc tuple_desc; @@ -2326,14 +2333,16 @@ my_set_returning_function(PG_FUNCTION_ARGS) else { /* 这里已经完成了项的返回,所以只报告事实。 */ - /* (不要将清理代码放在这里的。) */ + /* (不要将清理代码放在这里。) */ SRF_RETURN_DONE(funcctx); } } - 下面是一个返回复合类型的简单 SRF 的完整示例: + 一个返回复合类型的简单SRF的完整示例如下: +multi_call_memory_ctx); - /* total number of tuples to be returned */ + /* 要返回的元组总数 */ funcctx->max_calls = PG_GETARG_UINT32(0); - /* Build a tuple descriptor for our result type */ + /* 为我们的结果类型构建一个元组描述符 */ if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), @@ -2367,8 +2376,7 @@ retcomposite(PG_FUNCTION_ARGS) "that cannot accept type record"))); /* - * generate attribute metadata needed later to produce tuples from raw - * C strings + * 生成后续从原始C字符串生成元组所需的属性元数据 */ attinmeta = TupleDescGetAttInMetadata(tupdesc); funcctx->attinmeta = attinmeta; @@ -2376,23 +2384,22 @@ retcomposite(PG_FUNCTION_ARGS) MemoryContextSwitchTo(oldcontext); } - /* stuff done on every call of the function */ + /* 每次函数调用时执行的操作 */ funcctx = SRF_PERCALL_SETUP(); call_cntr = funcctx->call_cntr; max_calls = funcctx->max_calls; attinmeta = funcctx->attinmeta; - if (call_cntr < max_calls) /* do when there is more left to send */ + if (call_cntr < max_calls) /* 当还有更多要发送时执行 */ { char **values; HeapTuple tuple; Datum result; /* - * Prepare a values array for building the returned tuple. - * This should be an array of C strings which will - * be processed later by the type input functions. + * 为构建返回的元组准备一个值数组。 + * 这应该是一个由后续类型输入函数处理的C字符串数组。 */ values = (char **) palloc(3 * sizeof(char *)); values[0] = (char *) palloc(16 * sizeof(char)); @@ -2403,13 +2410,13 @@ retcomposite(PG_FUNCTION_ARGS) snprintf(values[1], 16, "%d", 2 * PG_GETARG_INT32(1)); snprintf(values[2], 16, "%d", 3 * PG_GETARG_INT32(1)); - /* build a tuple */ + /* 构建一个元组 */ tuple = BuildTupleFromCStrings(attinmeta, values); - /* make the tuple into a datum */ + /* 将元组转换为 datum */ result = HeapTupleGetDatum(tuple); - /* clean up (this is not really necessary) */ + /* 清理(这实际上并不是必要的) */ pfree(values[0]); pfree(values[1]); pfree(values[2]); @@ -2417,26 +2424,33 @@ retcomposite(PG_FUNCTION_ARGS) SRF_RETURN_NEXT(funcctx, result); } - else /* do when there is no more left */ + else /* 当没有更多要发送时执行 */ { SRF_RETURN_DONE(funcctx); } } ]]> -在 SQL 中声明该函数的一种方法是: + + + 在SQL中声明此函数的一种方法是: + CREATE TYPE __retcomposite AS (f1 integer, f2 integer, f3 integer); CREATE OR REPLACE FUNCTION retcomposite(integer, integer) RETURNS SETOF __retcomposite AS 'filename', 'retcomposite' LANGUAGE C IMMUTABLE STRICT; -另一种方法是使用 OUT 参数: + + 另一种方法是使用OUT参数: + CREATE OR REPLACE FUNCTION retcomposite(IN integer, IN integer, OUT f1 integer, OUT f2 integer, OUT f3 integer) RETURNS SETOF record AS 'filename', 'retcomposite' LANGUAGE C IMMUTABLE STRICT; -注意,在这种方法中,该函数的输出类型在形式上是一个匿名的 record 类型。 + + 请注意,采用这种方法时,函数的输出类型在形式上是一个匿名的 record 类型。 + @@ -2455,10 +2469,10 @@ CREATE OR REPLACE FUNCTION retcomposite(IN integer, IN integer, fcinfo->flinfo访问。参数argnum则是从零 开始计。get_call_result_type也可被用作 get_fn_expr_rettype的一种替代品。还有 - get_fn_expr_variadic,它可以被用来找出 variadic 参数 + get_fn_expr_variadic,它可以被用来找出可变参数 是否已经被合并到了一个数组中。这主要用于 VARIADIC "any"函数,因为对于接收普通数组类型的 - variadic 函数来说总是会发生这类合并。 + 可变参数函数来说总是会发生这类合并。 @@ -2526,7 +2540,7 @@ CREATE FUNCTION make_array(anyelement) RETURNS anyarray 它与 anyelement 类似,但不会要求不同的 "any" 参数必须是同一种类型,也不会帮助确定函数的结果类型。 C 语言函数还可以把最后一个参数声明为 VARIADIC "any"。 这可以匹配一个或多个任意类型的实参(不必是同一种类型)。 - 这些参数不会像普通 variadic 函数那样被收集成一个数组,而是会单独传给函数。 + 这些参数不会像普通可变参数函数那样被收集成一个数组,而是会单独传给函数。 使用这种特性时,必须结合 PG_NARGS() 宏以及前面介绍的方法来确定实参的个数和类型。 此外,这种函数的用户也可能希望在函数调用中使用 VARIADIC 关键字,以便让函数把数组元素当作独立参数处理。 如果希望支持这种行为,函数本身就必须在使用 get_fn_expr_variadic 检测到实参被标记为 VARIADIC 后自行实现它。 @@ -2544,7 +2558,7 @@ CREATE FUNCTION make_array(anyelement) RETURNS anyarray - 共享内存 + 共享内存与 LWLocks 附加模块可以在服务器启动时预留 LWLock 和一块共享内存。附加模块的共享库必须通过在以下参数中指定它来预装载:shared_preload_libraries。共享内存可以通过下面的调用来预留: void RequestAddinShmemSpace(int size) @@ -2613,9 +2627,9 @@ if (!ptr) - 如果从 C++ 代码调用后端函数,确定 C++ 调用栈值包含传统 C 风格 + 如果从 C++ 代码调用后端函数,确定 C++ 调用栈只包含传统 C 风格 的数据结构(POD)。这是必要的,因为后端错误会 - 产生远距离的longjmp(),它无法正确的退回具有非 + 产生远距离的longjmp(),它无法正确地展开具有非 POD 对象的 C++ 调用栈。 diff --git a/zh/10/xindex.sgml b/zh/10/xindex.sgml index 32bf92fe..2f926700 100644 --- a/zh/10/xindex.sgml +++ b/zh/10/xindex.sgml @@ -22,7 +22,7 @@ pg_am 表为每个索引方法(内部称为访问方法)保存一行。对表进行常规访问的支持内置于 PostgreSQL 中,但所有索引方法都在 pg_am 中描述。可以编写必要的代码,然后在 pg_am 中创建一行,从而添加新的索引访问方法 — 但这超出了本章的范围(参见)。 - 索引方法的例程并不直接知道它将处理哪些数据类型。相反,一个操作符类operator class标识了索引方法在处理特定数据类型时需要使用的那组操作。之所以称为操作符类,是因为它指定的一项内容就是可与索引一起使用的 WHERE 子句操作符集合(也就是能被转换成索引扫描条件的操作符)。操作符类还可以指定索引方法内部操作所需的一些支持函数,但这些函数并不直接对应任何可与索引一起使用的 WHERE 子句操作符。 + 索引方法的例程并不直接知道它将处理哪些数据类型。相反,一个操作符类操作符类标识了索引方法在处理特定数据类型时需要使用的那组操作。之所以称为操作符类,是因为它指定的一项内容就是可与索引一起使用的 WHERE 子句操作符集合(也就是能被转换成索引扫描条件的操作符)。操作符类还可以指定索引方法内部操作所需的一些支持函数,但这些函数并不直接对应任何可与索引一起使用的 WHERE 子句操作符。 @@ -310,7 +310,9 @@ - 比较两个键,并返回小于零、等于零或大于零的整数,分别表示第一个键小于、等于或大于第二个键 + + 比较两个键,并返回一个小于零、等于零或大于零的整数,用以表示第一个键是小于、等于还是大于第二个键 + 1 @@ -466,7 +468,7 @@ compare - 比较两个键,并返回一个小于零、等于零或大于零的整数,以表示第一个键是小于、等于还是大于第二个键 + 比较两个键,并返回一个小于零、等于零或大于零的整数,用以表示第一个键是小于、等于还是大于第二个键 1 @@ -616,7 +618,7 @@ CREATE OPERATOR < ( commutator = > , negator = >= , restrict = scalarltsel, join = scalarltjoinsel ); -必须指定正确的交换操作符和求反操作符,以及合适的限制选择率与连接选择率函数,否则优化器无法有效使用索引。注意,小于、等于和大于这几种情况应使用不同的选择率函数。 +必须指定正确的交换子和求反器操作符,以及合适的限制选择率与连接选择率函数,否则优化器无法有效使用索引。注意,小于、等于和大于这几种情况应使用不同的选择率函数。 这里还有几点值得注意: @@ -694,14 +696,14 @@ CREATE OPERATOR CLASS complex_abs_ops - 为了满足这些需求,PostgreSQL使用操作符族operator family这一概念。一个操作符族包含一个或多个操作符类,还可以包含属于整个族、但不属于族中任何单一类的可索引操作符及其相应的支持函数。我们称这样的操作符和函数在该族中是松散的,而不是绑定在某个特定类中。通常,每个操作符类只包含单一数据类型的操作符,而跨数据类型操作符则作为操作符族中的松散成员存在。 + 为了满足这些需求,PostgreSQL使用操作符族操作符族这一概念。一个操作符族包含一个或多个操作符类,还可以包含属于整个族、但不属于族中任何单一类的可索引操作符及其相应的支持函数。我们称这样的操作符和函数在该族中是松散的,而不是绑定在某个特定类中。通常,每个操作符类只包含单一数据类型的操作符,而跨数据类型操作符则作为操作符族中的松散成员存在。 一个操作符族中的所有操作符和函数都必须具有兼容的语义,而兼容性的要求由索引方法设定。因此,你也许会疑惑,为什么还要把该族的某些子集单独划成操作符类;事实上,对很多用途而言,类的划分并不重要,真正有意义的分组只有操作符族。之所以定义操作符类,是因为它们规定了支持特定索引所需的操作符族内容。如果某个索引使用了某个操作符类,那么在不删除该索引的情况下就不能删除该操作符类 — 但操作符族中的其他部分,也就是其他操作符类和松散操作符,则可以被删除。因此,一个操作符类应当只包含在特定数据类型上支持索引所合理需要的最小操作符和函数集合,而那些相关但非必需的操作符,则可以作为操作符族的松散成员加入。 - 例如,PostgreSQL内置了 B 树操作符族integer_ops,其中包含操作符类int8_opsint4_opsint2_ops,它们分别用于以下列类型上的索引:bigintint8), + 例如,PostgreSQL内置了 B-树操作符族integer_ops,其中包含操作符类int8_opsint4_opsint2_ops,它们分别用于以下列类型上的索引:bigintint8), integerint4)和smallintint2)。该操作符族还包含跨数据类型的比较操作符,允许对这些类型中的任意两个进行比较,因此可以使用一种类型的比较值搜索另一种类型上的索引。可以用以下定义复制这个操作符族: (int2, int4) , FUNCTION 1 btint24cmp(int2, int4) ; ]]> -注意,此定义重载了操作符策略编号和支持函数编号:每个编号在操作符族中出现多次。只要同一编号的每个实例具有不同的输入数据类型,这就是允许的。两个输入类型都等于某个操作符类输入类型的实例,是该操作符类的主要操作符和支持函数,通常应声明为操作符类的一部分,而不是操作符族的独立成员。 +注意,此定义重载了操作符策略编号和支持函数编号:每个编号在操作符族中出现多次。只要同一编号的每个实例具有不同的输入数据类型,这就是允许的。两个输入类型都等于某个操作符类输入类型的实例,是该操作符类的主要操作符和支持函数,通常应声明为操作符类的一部分,而不是操作符族的松散成员。 在一个 B-树操作符族中,该族中的所有操作符都必须以兼容的方式排序,也就是说,传递律必须适用于该族支持的所有数据类型:如果 A = B 且 B = C,则 A = C,以及如果 A < B 且 B < C,则 A < C。此外,操作符族中所表示的类型之间的隐式或二进制强制类型转换不得改变相关的排序顺序。对族中的每一个操作符,都必须有一个具有相同两个输入数据类型的支持函数。建议让操作符族保持完整,也就是说,对每一种数据类型组合都应包含全部操作符。每个操作符类只应包含其数据类型对应的非跨数据类型操作符和支持函数。 - 要构建一个多数据类型的哈希操作符族,必须为该族支持的每一种数据类型创建相互兼容的哈希支持函数。这里的兼容性是指:对任意两个被该族中的等值操作符视为相等的值,这些函数都保证返回相同的哈希码,即使这两个值属于不同类型也是如此。当这些类型具有不同的物理表示时,这通常难以实现,但在某些情况下可以做到。此外,将该操作符族中一种数据类型的值通过隐式或二进制强制转换转换成该族中另一种数据类型时,不应改变所计算出的哈希值。注意,每种数据类型只有一个支持函数,而不是每个等值操作符一个。建议让操作符族保持完整,也就是说,对每一种数据类型组合都提供一个等值操作符。每个操作符类只应包含其数据类型对应的非跨数据类型等值操作符和支持函数。 + 要构建一个多数据类型的哈希操作符族,必须为该族支持的每一种数据类型创建相互兼容的哈希支持函数。这里的兼容性是指:对任意两个被该族中的等值操作符视为相等的值,这些函数都保证返回相同的哈希码,即使这两个值属于不同类型也是如此。当这些类型具有不同的物理表示时,这通常难以实现,但在某些情况下可以做到。此外,将该操作符族中一种数据类型的值通过隐式或二进制强制转换转为该族中另一种数据类型时,不得改变所计算出的哈希值。注意,每种数据类型只有一个支持函数,而不是每个等值操作符一个。建议让操作符族保持完整,也就是说,对每一种数据类型组合都提供一个等值操作符。每个操作符类只应包含其数据类型对应的非跨数据类型等值操作符和支持函数。 @@ -805,7 +807,7 @@ ALTER OPERATOR FAMILY integer_ops USING btree ADD - 在 PostgreSQL 8.3 之前,并没有操作符族这一概念,因此任何打算与索引一起使用的跨数据类型操作符都必须直接绑定到该索引的操作符类中。虽然这种做法仍然有效,但已经废弃,因为它会使索引的依赖关系过于宽泛,而且当两种数据类型都在同一操作符族中拥有操作符时,规划器能更有效地处理跨数据类型比较。 + 在 PostgreSQL 8.3 之前,并没有操作符族这一概念,因此任何打算与索引一起使用的跨数据类型操作符都必须直接绑定到该索引的操作符类中。虽然这种做法仍然有效,但已被弃用,因为它会使索引的依赖关系过于宽泛,而且当两种数据类型都在同一操作符族中拥有操作符时,规划器能更有效地处理跨数据类型比较。 @@ -814,7 +816,7 @@ ALTER OPERATOR FAMILY integer_ops USING btree ADD 系统对操作符类的依赖 - ordering operator + 排序操作符 @@ -822,7 +824,7 @@ ALTER OPERATOR FAMILY integer_ops USING btree ADD - 特别地,ORDER BYDISTINCT等 SQL 特性要求对值的比较和排序。为了在用户定义的数据类型上实现这些特性,PostgreSQL会为数据类型查找默认 B-树操作符类。这个操作符类的equals成员定义了用于GROUP BYDISTINCT的值的等值概念,而该操作符类施加的排序顺序定义了默认的ORDER BY顺序。 + 特别地,ORDER BYDISTINCT等 SQL 特性要求对值的比较和排序。为了在用户定义的数据类型上实现这些特性,PostgreSQL会为数据类型查找默认 B-树操作符类。这个操作符类的相等成员定义了用于GROUP BYDISTINCT的值的等值概念,而该操作符类施加的排序顺序定义了默认的ORDER BY顺序。 用户定义类型的数组比较也依赖于该类型默认 B-树操作符类所定义的语义。 @@ -857,7 +859,7 @@ SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10; 可以找到距离指定目标点最近的十个地点。location 列上的 GiST 索引能够高效完成此操作,因为<->是排序操作符。 - 搜索操作符必须返回布尔结果,而排序操作符通常返回其他类型的结果,例如表示距离的浮点数或数值。这种类型通常不同于被索引的数据类型。为了避免对不同数据类型行为作硬编码假设,在定义排序操作符时,必须指定一个 B-树操作符族,用来说明结果数据类型的排序顺序。正如上一节所述,B-树操作符族定义了 PostgreSQL 的顺序概念,因此这是一种自然的表示方式。由于点的 <-> 操作符返回 float8,因此可以在创建操作符类时这样指定它: + 搜索操作符必须返回布尔结果,而排序操作符通常返回其他类型的结果,例如用于表示距离的 float 或 numeric。这种类型通常不同于被索引的数据类型。为了避免对不同数据类型行为作硬编码假设,在定义排序操作符时,必须指定一个 B-树操作符族,用来说明结果数据类型的排序顺序。正如上一节所述,B-树操作符族定义了 PostgreSQL 的顺序概念,因此这是一种自然的表示方式。由于点的 <-> 操作符返回 float8,因此可以在创建操作符类时这样指定它: (point, point) FOR ORDER BY float_ops ]]> @@ -870,7 +872,7 @@ OPERATOR 15 <-> (point, point) FOR ORDER BY float_ops 操作符类的特殊特性 - 还有两个操作符类的特殊特性我们尚未讨论,主要是因为它们对最常用的索引方法并不太有用。 + 还有两个操作符类的特殊特性我们尚未讨论,主要是因为它们对最常用的索引方法没有用处。 @@ -886,7 +888,7 @@ CREATE OPERATOR CLASS polygon_ops DEFAULT FOR TYPE polygon USING gist AS ... STORAGE box; -目前,只有 GiST、GIN 和 BRIN 索引方法支持与列数据类型不同的STORAGE类型。GiST 的compressdecompress支持函数在使用STORAGE时必须处理数据类型转换。在 GIN 中,STORAGE类型标识key值的类型,通常与被索引列的类型不同。例如,整数数组列的操作符类可以只使用整数作为键。GIN 的extractValueextractQuery支持函数负责从被索引值中提取键。BRIN 与 GIN 类似:STORAGE类型标识所存储摘要值的类型,而操作符类的支持函数负责正确解释这些摘要值。 +目前,只有 GiST、GIN 和 BRIN 索引方法支持与列数据类型不同的STORAGE类型。GiST 的compressdecompress支持函数在使用STORAGE时必须处理数据类型转换。在 GIN 中,STORAGE类型标识值的类型,通常与被索引列的类型不同。例如,整数数组列的操作符类可以只使用整数作为键。GIN 的extractValueextractQuery支持函数负责从被索引值中提取键。BRIN 与 GIN 类似:STORAGE类型标识所存储摘要值的类型,而操作符类的支持函数负责正确解释这些摘要值。 diff --git a/zh/10/xml2.sgml b/zh/10/xml2.sgml index f1a81e78..3ac02368 100644 --- a/zh/10/xml2.sgml +++ b/zh/10/xml2.sgml @@ -1,7 +1,7 @@ - xml2 — XPath 查询与 XSLT 功能 + xml2 xml2 @@ -43,7 +43,7 @@ bool - 此函数解析其参数中的文档文本,如果文档是格式良好的 XML,则返回 true。(注意:这是标准 PostgreSQL 函数 xml_is_well_formed() 的别名。由于 XML 中有效性和格式良好性具有不同含义,函数名 xml_valid() 在技术上并不正确。) + 此函数解析其参数中的文档文本,如果文档是良构 XML,则返回 true。(注意:这是标准 PostgreSQL 函数 xml_is_well_formed() 的别名。由于 XML 中有效性和良构性具有不同含义,函数名 xml_valid() 在技术上并不正确。) @@ -83,10 +83,10 @@ 该函数计算文档上的查询,并将结果封装在 XML 标签中。如果结果有多个值,输出将如下所示: <toptag> -<itemtag>Value 1 which could be an XML fragment</itemtag> +<itemtag>Value 1(可以是 XML 片段)</itemtag> <itemtag>Value 2....</itemtag> </toptag> -如果toptag或itemtag为空字符串,就会省略相应的标签。 +如果toptagitemtag为空字符串,就会省略相应的标签。 @@ -169,7 +169,7 @@ xpath_table(text key, text document, text relation, text xpaths, text criteria) key - key 字段的名称 — 这只是一个作为输出表第一列使用的字段,也就是说,它用于标识每个输出行来自哪条记录(关于多个值,见下文注释) + 字段的名称 — 这只是一个作为输出表第一列使用的字段,也就是说,它用于标识每个输出行来自哪条记录(关于多个值,见下文注释) @@ -200,7 +200,9 @@ xpath_table(text key, text document, text relation, text xpaths, text criteria) criteria - WHERE 子句的内容。这一项不能省略,因此如果你想处理该关系中的所有行,请使用 true1=1 + + WHERE 子句的内容。这一项不能省略,因此如果你想处理该表或视图中的所有行,请使用 true1=1 + @@ -228,7 +230,7 @@ xpath_table('article_id', 'date_entered > ''2003-01-01'' ') AS t(article_id integer, author text, page_count integer, title text); - AS 子句定义了输出表中各列的名称和类型。第一列是 key 字段,其余各列对应 XPath 查询。如果 XPath 查询多于结果列,多出的查询将被忽略。如果结果列多于 XPath 查询,多出的列将为 NULL。 + AS 子句定义了输出表中各列的名称和类型。第一列是 字段,其余各列对应 XPath 查询。如果 XPath 查询多于结果列,多出的查询将被忽略。如果结果列多于 XPath 查询,多出的列将为 NULL。 @@ -257,7 +259,7 @@ WHERE t.author_id = p.person_id; - 在某些情况下,用户会知道某个 XPath 查询只会返回单个结果(例如唯一文档标识符)— 如果它与返回多个结果的 XPath 查询一起使用,这个单值结果只会出现在结果的第一行。解决办法是把 key 字段作为与一个更简单的 XPath 查询结果进行连接的条件之一。例如: + 在某些情况下,用户会知道某个 XPath 查询只会返回单个结果(例如唯一文档标识符)— 如果它与返回多个结果的 XPath 查询一起使用,这个单值结果只会出现在结果的第一行。解决办法是把键字段作为与一个更简单的 XPath 查询结果进行连接的条件之一。例如: CREATE TABLE test ( diff --git a/zh/10/xoper.sgml b/zh/10/xoper.sgml index be1ca96a..d9c42388 100644 --- a/zh/10/xoper.sgml +++ b/zh/10/xoper.sgml @@ -108,7 +108,7 @@ SELECT (a + b) AS c FROM test_complex; 转成 tab2.y = tab1.x,否则它就无法生成索引扫描,因为 索引扫描机制要求传给它的操作符左侧必须是已建立索引的列。 PostgreSQL 不会仅凭假 - 设就认为这种转换有效 — = 操作符的创建者必须通过为该操 + 设就认为这种转换有效;= 操作符的创建者必须通过为该操 作符标记交换子信息,明确声明这种转换是有效的。 @@ -162,10 +162,10 @@ SELECT (a + b) AS c FROM test_complex; <literal>RESTRICT</literal> - 如果给出 RESTRICT 子句,它指定该操作符的限制选择度估 + 如果给出 RESTRICT 子句,它指定该操作符的限制选择率估 算函数。(注意,这里是函数名,而不是操作符名。) RESTRICT 子句只对返回 boolean 的二元操 - 作符有意义。限制选择度估算器的作用,是针对当前操作符和某个特定常量值, + 作符有意义。限制选择率估算器的作用,是针对当前操作符和某个特定常量值, 猜测一张表中有多少比例的行会满足如下形式的 WHERE 子句条件: @@ -189,7 +189,7 @@ column OP constant 这些分类可能看起来有点奇怪,但仔细想想就会发现它们是有道理的。= 通常只会接受表中很小一部分行;<> 通常只会拒绝很小一部分行。< 接受的比例取决于给定常量落在该表列的值范围中的什么位置(恰好,这正是 ANALYZE 收集并提供给选择率估算器的信息)。对于相同的比较常量,<= 接受的比例会比 < 略大,但二者足够接近,不值得区分,尤其是无论如何我们很可能也只能做出粗略猜测。类似的说法也适用于 >>= - 对于选择度非常高或非常低的操作符,即使它们实际上并不是真正的相等或不等 + 对于选择率非常高或非常低的操作符,即使它们实际上并不是真正的相等或不等 比较,你也常常可以勉强使用 eqselneqsel。例如,几何类型中的近似相等操作符就使用 eqsel,其依据是它们通常只会匹配表中很小一部分项。 @@ -207,7 +207,7 @@ column OP constant src/backend/utils/adt/geo_selfuncs.c 中,还为几 - 何操作符提供了其他选择度估算函数:areasel、 + 何操作符提供了其他选择率估算函数:areaselpositionselcontsel。截至 目前,这些函数都还只是桩实现,但你也许仍会想使用它们(或者更好的是,改 进它们)。 @@ -218,9 +218,9 @@ column OP constant <literal>JOIN</literal> - 如果给出 JOIN 子句,它指定该操作符的连接选择度估算函 + 如果给出 JOIN 子句,它指定该操作符的连接选择率估算函 数。(注意,这里是函数名,而不是操作符名。)JOIN 子 - 句只对返回 boolean 的二元操作符有意义。连接选择度估算器的 + 句只对返回 boolean 的二元操作符有意义。连接选择率估算器的 作用,是针对当前操作符,猜测两张表中有多少比例的行对会满足如下形式的 WHERE 子句条件: @@ -287,7 +287,7 @@ table1.column1 OP table2.column2 一个可参与哈希连接的操作符,必须拥有一个交换子(如果两侧操作数数据类型 - 相同,则可以是它自身;如果不同,则应是相关的相等操作符),并且该交换子 + 相同,则为它自身;如果不同,则应是相关的相等操作符),并且该交换子 也必须出现在同一个操作符族中。否则,在使用该操作符时可能会发生规划器错 误。另外,对于支持多种数据类型的哈希操作符族,最好(虽然并非严格必需) 为每一种数据类型组合都提供相等操作符;这样可以获得更好的优化效果。 @@ -324,7 +324,7 @@ table1.column1 OP table2.column2 - 归并连接的基本思想,是先把左表和右表分别排序,然后并行扫描它们。因此, + 归并连接的基本思想,是先把左表和右表分别排序,然后同步扫描它们。因此, 两种数据类型都必须能够被完全排序,而连接操作符必须只能在那对值位于排序 次序中同一位置时才成功。实际效果上,这意味着连接操作符 必须表现得像相等比较一样。不过,只要两种不同的数据类型在逻辑上兼容,也 @@ -344,7 +344,7 @@ table1.column1 OP table2.column2 一个可参与归并连接的操作符,必须拥有一个交换子(如果两侧操作数数据类型 - 相同,则可以是它自身;如果不同,则应是相关的相等操作符),并且该交换子 + 相同,则为它自身;如果不同,则应是相关的相等操作符),并且该交换子 也必须出现在同一个操作符族中。否则,在使用该操作符时可能会发生规划器错 误。另外,对于支持多种数据类型的 btree 操作符族,最 好(虽然并非严格必需)为每一种数据类型组合都提供相等操作符;这样可以获 diff --git a/zh/10/xplang.sgml b/zh/10/xplang.sgml index 997fc34e..81fc1484 100644 --- a/zh/10/xplang.sgml +++ b/zh/10/xplang.sgml @@ -158,7 +158,7 @@ CREATE TRUSTED PROCEDURAL LANGUAGE plperl 在默认的PostgreSQL安装中, PL/pgSQL语言的调用处理器会被构建并安装到 - library目录中;此外, + 目录中;此外, PL/pgSQL语言本身也安装在所有数据库中。如 果在构建时配置了Tcl支持,那么 PL/TclPL/TclU diff --git a/zh/10/xtypes.sgml b/zh/10/xtypes.sgml index b7091ba2..b96b1d41 100644 --- a/zh/10/xtypes.sgml +++ b/zh/10/xtypes.sgml @@ -213,7 +213,7 @@ CREATE TYPE complex ( 如果数据类型的内部表示是可变长度的,则这种内部表示必须遵循可变长度数 据的标准布局:前四个字节必须是一个从不直接访问的char[4] 字段(惯例上命名为vl_len_)。必须使用 - SET_VARSIZE()宏在该字段中存储该值的总大小(包括 + SET_VARSIZE()宏在该字段中存储该 datum 的总大小(包括 长度字段本身),并使用VARSIZE()取回它。(这些宏 之所以存在,是因为长度字段可能会随平台不同而采用编码形式。) @@ -255,7 +255,7 @@ CREATE TYPE complex ( PG_DETOAST_DATUM_PACKED(通常通过定义 GETARG_DATATYPE_PP宏来隐藏),并使用 VARSIZE_ANY_EXHDRVARDATA_ANY - 宏访问一个可能采用打包形式的值。再次注意,即使数据类型定义指定了 + 宏访问一个可能采用打包形式的 datum。再次注意,即使数据类型定义指定了 对齐方式,这些宏返回的数据也不是对齐的。如果对齐很重要,就必须使用常 规的PG_DETOAST_DATUM接口。 @@ -266,8 +266,7 @@ CREATE TYPE complex ( 较旧的代码常把vl_len_声明为 int32字段,而不是char[4]字段。只要结构体定 义中还有其他至少按int32对齐的字段,这样做是可以的。但 - 在处理可能未对齐的值时使用这种结构体定义就很危险;编译器可能据此假定该 - 值实际上是对齐的,从而在对齐要求严格的体系结构上导致核心转储。 + 在处理可能未对齐的 datum 时使用这种结构体定义就很危险;编译器可能据此假定该 datum 实际上是对齐的,从而在对齐要求严格的体系结构上导致核心转储。 diff --git a/zh/11/adminpack.sgml b/zh/11/adminpack.sgml index e59876e1..71c32886 100644 --- a/zh/11/adminpack.sgml +++ b/zh/11/adminpack.sgml @@ -19,7 +19,7 @@ <filename>adminpack</filename> 函数 - Name 返回类型 + 名称 返回类型 描述 @@ -61,7 +61,7 @@ pg_file_rename - pg_file_rename重命名文件。如果省略archivename或其值为 NULL,则它只是将oldname重命名为newname(后者必须尚不存在)。如果提供了archivename,它会先将newname重命名为archivename(后者必须尚不存在),然后再将oldname重命名为newname。如果第二个重命名步骤失败,它会在报告错误之前尝试将archivename再改回newname。成功时返回 true;如果源文件不存在或不可写,则返回 false;其他情况会抛出错误。 + pg_file_rename重命名文件。如果省略archivename或其值为空值,则它只是将oldname重命名为newname(后者必须尚不存在)。如果提供了archivename,它会先将newname重命名为archivename(后者必须尚不存在),然后再将oldname重命名为newname。如果第二个重命名步骤失败,它会在报告错误之前尝试将archivename再改回newname。成功时返回 true;如果源文件不存在或不可写,则返回 false;其他情况会抛出错误。 diff --git a/zh/11/amcheck.sgml b/zh/11/amcheck.sgml index 1c94608f..764feefa 100644 --- a/zh/11/amcheck.sgml +++ b/zh/11/amcheck.sgml @@ -159,7 +159,7 @@ ORDER BY c.relpages DESC LIMIT 10; 这也包括因操作系统排序规则的比较规则发生变化而引起的问题。 - 像text这类可排序类型的数据值之间的比较必须是不可变的 + 像text这类支持排序规则的类型的 datum 之间的比较必须是不可变的 (正如用于 B-树索引扫描的所有比较都必须不可变一样), 这就意味着操作系统排序规则绝不能发生变化。 虽然这种情况比较少见,但操作系统排序规则的更新确实可能导致此类问题。 @@ -233,12 +233,10 @@ ORDER BY c.relpages DESC LIMIT 10; 修复损坏 - 请注意,如果访问某个块时只是命中了共享缓冲区, - 那么amcheck检查的是验证时该页面在某个共享内存缓冲区中的表示。 - 因此,amcheck并不一定会检查验证时从文件系统读入的数据。 - 另请注意,当启用了校验和时,如果某个损坏块被读入缓冲区, - amcheck可能会因为校验和失败而引发错误。 - + amcheck报告的与损坏有关的错误绝不应被当作误报。 + amcheck会在那些按定义绝不应该发生的情况下抛出错误, + 因此通常需要对这类错误进行仔细分析。 + 对于amcheck检测到的问题,并不存在通用的修复方法。 应当查明导致不变式遭到破坏的根本原因。 diff --git a/zh/11/auth-delay.sgml b/zh/11/auth-delay.sgml index c0146092..652355f9 100644 --- a/zh/11/auth-delay.sgml +++ b/zh/11/auth-delay.sgml @@ -1,7 +1,7 @@ - auth_delay — 在认证失败时暂停 + auth_delay auth_delay diff --git a/zh/11/backup.sgml b/zh/11/backup.sgml index 7d25f5e7..c6b149d4 100644 --- a/zh/11/backup.sgml +++ b/zh/11/backup.sgml @@ -3,7 +3,7 @@ 备份和恢复 - backup + 备份 与任何保存重要数据的系统一样,PostgreSQL数据库也应定期备份。虽然其过程基本简单,但清楚理解其底层技术和前提假设非常重要。 @@ -61,11 +61,17 @@ psql dbname < - 默认情况下,psql 在遇到 SQL 错误后仍会继续执行脚本。可以在运行 psql 时设置 ON_ERROR_STOP 变量来改变这一行为,让 psql 在发生 SQL 错误时以退出状态 3 退出: + + 默认情况下,psql脚本在遇到 SQL 错误后仍会继续执行。你可能希望让psql在设置了ON_ERROR_STOP变量的情况下运行,以改变这一行为,并让psql在发生 SQL 错误时以退出状态码 3 退出: + psql --set ON_ERROR_STOP=on dbname < dumpfile -不论采用哪种方式,最终都只会得到部分恢复的数据库。另一种做法是指定将整个转储作为一个事务恢复,这样恢复要么全部完成,要么全部回滚。可通过将命令行选项 传递给 psql 来指定这种模式。使用该模式时要注意,即使是很小的错误,也可能使已经运行数小时的恢复全部回滚。不过,这可能仍比在部分恢复转储后手动清理复杂的数据库更好。 + + 无论采用上述哪种方式,你最终只会得到一个部分恢复的数据库。另一种做法是指定将整个转储作为单个事务恢复,这样恢复要么全部完成,要么全部回滚。可以通过把命令行选项传给psql来启用这种模式。使用这种模式时要注意,即便是一个很小的错误,也可能回滚一个已经运行了许多小时的恢复过程。不过,这仍可能比在部分恢复后手工清理一个复杂数据库更可取。 + - 利用 pg_dumppsql 向管道写入或从管道读取的能力,可以直接将数据库从一台服务器转储到另一台,例如: + + pg_dumppsql能够写入或读取管道,这使得可以把数据库直接从一台服务器转储到另一台服务器,例如: + pg_dump -h host1 dbname | psql -h host2 dbname @@ -85,12 +91,16 @@ pg_dump -h host1 dbname | 使用<application>pg_dumpall</application> - pg_dump 每次只转储一个数据库,不转储角色或表空间信息(因为它们属于整个集簇,而非某个数据库)。为了便于转储数据库集簇的全部内容,系统提供了 程序。pg_dumpall 会备份给定集簇中的每个数据库,并保留角色和表空间定义等集簇级数据。该命令的基本用法如下: + pg_dump一次只转储一个数据库,而且不会转储角色或表空间的信息(因为这些是整个集簇级别的,而不是每个数据库各自的)。为了方便地转储整个数据库集簇的全部内容,提供了程序。pg_dumpall会备份给定集簇中的每个数据库,并保留角色定义和表空间定义等集簇范围的数据。该命令的基本用法是: + pg_dumpall > dumpfile -要恢复生成的转储,可以使用 psql: + + 生成的转储可以用psql恢复: psql -f dumpfile postgres -(实际上,可以指定任何已存在的数据库名作为起点;但如果装载到空集簇中,通常应使用 postgres。)恢复 pg_dumpall 转储时,必须具有数据库超级用户权限,因为恢复角色和表空间信息需要这些权限。如果使用了表空间,请确保转储中的表空间路径适合新的安装环境。 + + (实际上,可以指定任意一个现有数据库名作为起点,但如果要装载到一个空集簇中,通常应使用postgres。)恢复pg_dumpall转储时始终需要数据库超级用户权限,因为恢复角色和表空间信息必须使用该权限。如果使用了表空间,请确保转储中的表空间路径适合新的安装。 + pg_dumpall的工作方式是先发出重新创建角色、表空间和空数据库的命令,然后针对每个数据库调用pg_dump。这意味着每个数据库本身都是内部一致的,但不同数据库的快照并不同步。 @@ -176,7 +186,7 @@ pg_restore -d dbname - 对于非常大的数据库,你可能需要把split与前两种方法之一结合使用。 + 对于非常大的数据库,你可能需要把split与另外两种方法之一结合使用。 @@ -232,7 +242,7 @@ tar -cf backup.tar /usr/local/pgsql/data - 如果无法获得同时的快照,一种选择是将数据库服务器关闭足够长的时间,以建立所有冻结快照。另一种选择是执行持续归档基础备份(),因为这种备份不受备份期间文件系统变化的影响。这要求只在备份过程中启用持续归档;恢复则使用持续归档恢复()。 + 如果无法获得同时的快照,一种选择是将数据库服务器关闭足够长的时间,以建立所有冻结快照。另一种选择是执行持续归档基础备份(),因为这种备份不受备份期间文件系统变化的影响。这种方法只需在备份期间启用持续归档;恢复则使用持续归档恢复()。 @@ -248,11 +258,11 @@ tar -cf backup.tar /usr/local/pgsql/data 持续归档和时间点恢复(PITR) - continuous archiving + 持续归档 - point-in-time recovery + 时间点恢复 @@ -292,7 +302,7 @@ tar -cf backup.tar /usr/local/pgsql/data - 和普通文件系统备份技术一样,这种方法只能支持整个数据库集簇的恢复,而不支持其中某个子集的恢复。此外,它需要大量归档存储:基础备份可能很庞大,繁忙系统也会产生大量必须归档的 WAL 流量。尽管如此,在很多需要高可靠性的场景中,它仍是首选的备份技术。 + 和普通文件系统备份技术一样,这种方法只能支持整个数据库集簇的恢复,而不支持其中某个子集的恢复。此外,它需要大量归档存储:基础备份可能很庞大,繁忙系统也会产生许多兆字节的、必须归档的 WAL 流量。尽管如此,在很多需要高可靠性的场景中,它仍是首选的备份技术。 @@ -307,7 +317,7 @@ tar -cf backup.tar /usr/local/pgsql/data - 在归档 WAL 数据时,我们需要在每个段文件写满后捕获其内容,并在该段文件被回收重用之前把数据保存到某处。根据应用场景和可用硬件的不同,把数据保存到某处可以有很多不同的方法:可以把段文件复制到另一台机器上的 NFS 挂载目录,把它们写到磁带机中(确保你有办法识别每个文件的原始文件名),把它们批量打包后刻录到 CD 上,或者采用完全不同的方式。为了给数据库管理员提供灵活性,PostgreSQL尽量不对归档方式作任何假设。相反,PostgreSQL允许管理员指定一个 shell 命令或一个归档库,以便把已完成的段文件复制到它应去的地方。这既可以只是一个使用cp的 shell 命令,也可以调用一个复杂的 C 函数,全由你决定。 + 在归档 WAL 数据时,我们需要在每个段文件写满后捕获其内容,并在该段文件被回收重用之前把数据保存到某处。根据应用场景和可用硬件的不同,把数据保存到某处可以有很多不同的方法:可以把段文件复制到另一台机器上的 NFS 挂载目录,把它们写到磁带机中(确保你有办法识别每个文件的原始文件名),把它们批量打包后刻录到 CD 上,或者采用完全不同的方式。为了给数据库管理员提供灵活性,PostgreSQL尽量不对归档方式作任何假设。相反,PostgreSQL允许管理员指定一个 shell 命令,以便把已完成的段文件复制到它应去的地方。该命令可以只是一次简单的cp调用,也可以调用一个复杂的 shell 脚本,全由你决定。 要启用 WAL 归档,请将 配置参数设为 replica 或更高值,将 设为 on,并在 通常应将归档命令设计为拒绝覆盖任何已存在的归档文件。这是一项重要的安全保护措施,能在管理员操作失误时(例如将两台不同服务器的输出发送到同一归档目录)维护归档的完整性。 - 建议测试所拟定的归档命令,确保它确实不会覆盖已有文件,并且在这种情况下返回非零状态。上面给出的 Unix 示例命令通过单独加入一个test步骤,避免覆盖已有归档。在某些 Unix 平台上,cp提供了诸如之类的开关,也可以更简洁地实现同样目的,但在你确认它会返回正确的退出状态之前,不应依赖这些开关。(尤其是 GNU cp在使用且目标文件已存在时会返回状态零,这不是我们想要的行为。) + 建议测试所拟定的归档命令,确保它确实不会覆盖已有文件,并且在这种情况下返回非零状态。上面给出的 Unix 示例命令通过单独加入一个test步骤,确保这两点。在某些 Unix 平台上,cp提供了诸如之类的开关,也可以更简洁地实现同样目的,但在你确认它会返回正确的退出状态之前,不应依赖这些开关。(尤其是 GNU cp在使用且目标文件已存在时会返回状态零,这不是我们想要的行为。) - 在设计归档方案时,请考虑如果归档命令或归档库因为某些环节需要操作员干预,或者归档空间耗尽而反复失败,会发生什么。例如,如果你在没有自动换带器的情况下向磁带写入数据,那么磁带满了以后,在更换磁带之前将无法继续归档。你应确保任何错误情况或对人工操作员的请求都能得到适当报告,以便问题能够比较快地解决。在问题解决之前,pg_wal/目录会继续堆积 WAL 段文件。(如果包含pg_wal/的文件系统被写满,PostgreSQL将执行 PANIC 关闭。不会丢失已提交的事务,但在释放出一些空间之前,数据库会一直离线。) + 在设计归档方案时,请考虑如果归档命令因为某些环节需要操作员干预,或者归档空间耗尽而反复失败,会发生什么。例如,如果你在没有自动换带器的情况下向磁带写入数据,那么磁带满了以后,在更换磁带之前将无法继续归档。你应确保任何错误情况或对人工操作员的请求都能得到适当报告,以便问题能够比较快地解决。在问题解决之前,pg_wal/目录会继续堆积 WAL 段文件。(如果包含pg_wal/的文件系统被写满,PostgreSQL将执行 PANIC 关闭。不会丢失已提交的事务,但在释放出一些空间之前,数据库会一直离线。) - 归档命令或归档库的速度并不重要,只要它能跟上服务器生成 WAL 数据的平均速度即可。即使归档过程稍有滞后,正常操作也会继续。如果归档明显落后,灾难发生时可能丢失的数据量就会增加。这还意味着pg_wal/目录会包含大量尚未归档的段文件,最终可能耗尽可用磁盘空间。建议监控归档过程,确保它按你的预期工作。 + 归档命令的速度并不重要,只要它能跟上服务器生成 WAL 数据的平均速度即可。即使归档过程稍有滞后,正常操作也会继续。如果归档明显落后,灾难发生时可能丢失的数据量就会增加。这还意味着pg_wal/目录会包含大量尚未归档的段文件,最终可能耗尽可用磁盘空间。建议监控归档过程,确保它按你的预期工作。 - 在编写归档命令或归档库时,应假定待归档文件名最长可达 64 个字符,并且可以包含 ASCII 字母、数字和点号的任意组合。无需保留原始相对路径(%p),但必须保留文件名(%f)。 + 在编写归档命令时,应假定待归档文件名最长可达 64 个字符,并且可以包含 ASCII 字母、数字和点号的任意组合。无需保留原始相对路径(%p),但必须保留文件名(%f)。 注意,虽然 WAL 归档允许你恢复对PostgreSQL数据库中数据所做的任何修改,但它不会恢复对配置文件(即postgresql.confpg_hba.confpg_ident.conf)的修改,因为这些文件是手工编辑的,而不是通过 SQL 操作修改的。你可能希望把配置文件放在常规文件系统备份过程能够覆盖的位置。关于如何重定位配置文件,见 - 归档命令只会在已完成的 WAL 段上调用。因此,如果服务器产生的 WAL 流量很小(或者存在这样的低谷期),事务完成到其被安全写入归档存储之间可能会有很长延迟。为了限制未归档数据的最长滞留时间,可以设置 ,强制服务器至少每隔这么长时间切换到一个新的 WAL 段文件。注意,由强制切换而提前归档的文件长度仍与装满的文件相同。因此,把 archive_timeout 设得很短并不明智,这会使归档存储膨胀。将 archive_timeout 设为大约一分钟通常是合理的。 + + 归档命令只会针对已完成的 WAL 段调用。因此,如果服务器产生的 WAL 流量很小(或者存在低谷期),事务完成到其被安全写入归档存储之间可能会有很长延迟。为了限制未归档数据可能有多旧,你可以设置,使服务器强制切换到新 WAL 段文件的间隔不超过这个值。注意,由强制切换而提前归档的文件长度仍与装满的文件相同。因此,把archive_timeout设得很短并不明智,这会使归档存储膨胀。archive_timeout设为大约 1 分钟通常是合理的。 + 此外,如果你希望确保一个刚刚完成的事务尽快被归档,可以使用pg_switch_wal手工强制一次段切换。其他与 WAL 管理相关的实用函数列在中。 - 当wal_levelminimal时,某些 SQL 命令会像中所述那样被优化为避免 WAL 记录。如果在执行这些语句期间启用了归档或流复制,WAL 将不包含归档恢复所需的足够信息。(崩溃恢复不受影响。)因此,wal_level只能在服务器启动时更改。然而,archive_command可以通过重新加载配置文件来更改。如果你通过 shell 进行归档并希望暂时停止归档,一种办法是将archive_command设置为空字符串('')。这会导致 WAL 文件在pg_wal/中累积,直到重新建立可用的archive_command。 + 当wal_levelminimal时,某些 SQL 命令会像中所述那样被优化为避免 WAL 记录。如果在执行这些语句期间启用了归档或流复制,WAL 将不包含归档恢复所需的足够信息。(崩溃恢复不受影响。)因此,wal_level只能在服务器启动时更改。然而,archive_command可以通过重新加载配置文件来更改。如果你希望暂时停止归档,一种办法是将archive_command设置为空字符串('')。这会导致 WAL 文件在pg_wal/中累积,直到重新建立可用的archive_command @@ -381,7 +393,7 @@ test ! -f /mnt/server/archivedir/00000001000000A900000065 && cp pg_wal/0 - 使用低级接口进行基础备份 + 使用低级 API 进行基础备份 使用低级 API 制作基础备份的过程,比 方法多几个步骤,但相对简单。务必按顺序执行这些步骤,并在继续下一步之前确认当前步骤成功。 低级基础备份可以采用非排他或排他方式。建议使用非排他方式;排他方式已弃用,最终将被移除。 @@ -500,7 +512,9 @@ SELECT pg_stop_backup(); 使用持续归档备份进行恢复 - 如果最坏的情况已经发生,需要从备份恢复,请按以下流程操作: + + 现在,最坏的情况发生了,你需要通过备份进行恢复。步骤如下: + 如果服务器仍在运行,就先停止它。 @@ -518,7 +532,7 @@ SELECT pg_stop_backup(); - 如果你正在恢复完整备份,可以把数据库文件直接恢复到目标目录中。务必确保它们以正确的所有者(数据库系统用户,而不是root!)和正确的权限恢复。如果使用了表空间,还应验证pg_tblspc/中的符号链接是否已正确恢复。 + 从文件系统备份中恢复数据库文件。务必确保它们以正确的所有者(数据库系统用户,而不是root!)和正确的权限恢复。如果使用了表空间,还应验证pg_tblspc/中的符号链接是否已正确恢复。 @@ -545,16 +559,16 @@ SELECT pg_stop_backup(); - 整个过程的关键,是设置一个恢复配置文件,说明希望如何恢复,以及恢复到什么位置。可以使用 recovery.conf.sample(通常位于安装目录的 share/ 目录中)作为模板。必须在 recovery.conf 中指定 restore_command,它告诉 PostgreSQL 如何获取已归档的 WAL 段。与 archive_command 一样,它是一个 shell 命令字符串,可以包含 %f,该标记会被替换为所需日志文件的名称;还可以包含 %p,该标记会被替换为日志文件要复制到的路径名。(路径名相对于当前工作目录,即集簇的数据目录。)使用 %% 可以在命令中嵌入实际的 % 字符。最简单的可用命令类似于: + 整个过程的关键,是设置一个恢复配置文件,说明希望如何恢复,以及恢复到什么位置。可以使用 recovery.conf.sample(通常位于安装目录的 share/ 目录中)作为模板。必须在 recovery.conf 中指定 restore_command,它告诉 PostgreSQL 如何获取已归档的 WAL 段文件。与 archive_command 一样,它是一个 shell 命令字符串,可以包含 %f,该标记会被替换为所需日志文件的名称;还可以包含 %p,该标记会被替换为日志文件要复制到的路径名。(路径名相对于当前工作目录,即集簇的数据目录。)使用 %% 可以在命令中嵌入实际的 % 字符。最简单的可用命令类似于: restore_command = 'cp /mnt/server/archivedir/%f %p' 这会复制先前归档的 WAL 段,来源目录为 /mnt/server/archivedir。当然,也可以使用复杂得多的命令,甚至可以使用要求操作人员挂载相应磁带的 shell 脚本。 - 重要的是,该命令在失败时必须返回非零退出状态。系统调用该命令来请求归档中不存在的文件;遇到这种情况时,它就应返回非零值。这不是一种错误情况。例外是,如果该命令被信号终止(用于数据库服务器关闭的SIGTERM除外),或者因 shell 错误(如命令未找到)而失败,那么恢复将中止,服务器也不会启动。 + 重要的是,该命令在失败时必须返回非零退出状态。系统调用该命令来请求归档中不存在的文件;遇到这种情况时,它必须返回非零值。这不是一种错误情况。例外是,如果该命令被信号终止(用于数据库服务器关闭的SIGTERM除外),或者因 shell 错误(如命令未找到)而失败,那么恢复将中止,服务器也不会启动。 - 被请求的文件并不全都是 WAL 段文件;你还应预期会收到对带有.history后缀文件的请求。另外请注意,%p路径的基本文件名会与%f不同;不要指望它们可以互换使用。 + 被请求的文件并不全都是 WAL 段文件;你还应预期会收到对带有.history后缀文件的请求。另外请注意,%p路径的文件名部分会与%f不同;不要指望它们可以互换使用。 @@ -562,14 +576,14 @@ restore_command = 'cp /mnt/server/archivedir/%f %p' - 通常,恢复会处理完所有可用的 WAL 段,从而把数据库恢复到当前时间点(或者在可用 WAL 段所允许的情况下尽可能接近当前时间点)。因此,一次正常恢复通常会以一条file not found消息结束,具体错误文本取决于你选择的restore_command。在恢复开始时,你也可能看到一条针对类似00000001.history文件的错误消息。这同样是正常的,在简单恢复场景中并不表示有问题;相关讨论见。 + 通常,恢复会处理完所有可用的 WAL 段,从而把数据库恢复到当前时间点(或者在可用 WAL 段所允许的情况下尽可能接近当前时间点)。因此,一次正常恢复会以一条file not found消息结束,具体错误文本取决于你选择的restore_command。在恢复开始时,你也可能看到一条针对类似00000001.history文件的错误消息。这同样是正常的,在简单恢复场景中并不表示有问题;相关讨论见 如果希望恢复到过去的某个时间点(例如初级 DBA 删除主要事务表之前),只需在 recovery.conf 中指定所需的停止点。这个停止点称为恢复目标,可以通过日期/时间、命名恢复点,或某个特定事务 ID 的完成来指定。撰写本文时,只有日期/时间和命名恢复点这两种方式比较实用,因为还没有工具能帮助你准确确定应使用哪个事务 ID。 - 停止点必须晚于基础备份的结束时间,也就是pg_stop_backup的结束时间。你不能用某次基础备份恢复到该备份仍在进行中的时间点。(若要恢复到这样的时间点,必须回到更早的一次基础备份,再从那里向前滚动。) + 停止点必须晚于基础备份的结束时间,也就是pg_stop_backup的结束时间。你不能用某次基础备份恢复到该备份仍在进行中的时间点。(若要恢复到这样的时间点,必须回到更早的一次基础备份,再从那里向前重放日志。) @@ -583,14 +597,16 @@ restore_command = 'cp /mnt/server/archivedir/%f %p' 时间线 - timelines + 时间线 能够将数据库恢复到过去某个时间点,也会带来一些类似科幻故事中时间旅行和平行宇宙的复杂情况。例如,假设在数据库原来的历史中,你在周二下午 5:15 删除了一张重要的表,直到周三中午才发现错误。你从容地取出备份,将数据库恢复到周二下午 5:14,然后重新投入运行。在数据库宇宙的这段历史中,你从未删除过那张表。但假设你后来发现这样做不太合适,希望回到原来历史中的周三上午某个时刻。如果数据库恢复运行后覆盖了通往该时刻所需的某些 WAL 段文件,就无法回去了。因此,为了避免这种情况,需要区分时间点恢复后产生的一系列 WAL 记录与数据库原来历史中产生的记录。 为解决这一问题,PostgreSQL 引入了时间线的概念。每当归档恢复完成,系统都会创建一条新时间线,用于标识此次恢复之后产生的一系列 WAL 记录。时间线 ID 是 WAL 段文件名的一部分,因此新时间线不会覆盖旧时间线产生的 WAL 数据。实际上,可以归档许多不同的时间线。这个功能看似没什么用,却常常能救急。比如,你不能确定应该恢复到哪个时间点,需要反复尝试时间点恢复,直到找到脱离旧历史的最佳分支点。没有时间线,这个过程很快就会乱得无法管理。有了时间线,就可以恢复到任何先前的状态,包括早先已放弃的时间线分支中的状态。 - 每次创建新时间线时,PostgreSQL 都会创建一个时间线历史文件,记录它从哪条时间线、在何时分支出来。从包含多条时间线的归档中恢复时,系统需要这些历史文件来选择正确的 WAL 段文件。因此,历史文件与 WAL 段文件一样,也会归档到 WAL 归档区。历史文件只是很小的文本文件,长期保留成本很低,也很合适(不像体积很大的段文件)。如果愿意,可以在历史文件中添加注释,记录这条时间线是如何创建的,以及为什么创建它。当反复试验产生了许多交错的时间线时,这些注释会格外有用。 + + 每当创建一条新的时间线时,PostgreSQL都会创建一个时间线历史文件,记录它是从哪条时间线、在何时分叉出来的。当从包含多条时间线的归档中恢复时,这些历史文件对于系统选取正确的 WAL 段文件是必需的。因此,它们会像 WAL 段文件一样被归档到 WAL 归档区域。历史文件只是很小的文本文件,因此长期保存它们既便宜也合适(而段文件通常很大)。如果你愿意,还可以在历史文件中加入注释,记录创建这条时间线的方式和原因。当你因实验而积累出一批错综复杂的时间线时,这类注释会特别有价值。 + 默认情况下,恢复会沿着制作基础备份时的当前时间线进行。如果希望恢复到某条子时间线(即返回到一次恢复尝试之后产生的某个状态),需要在 recovery.conf 中指定目标时间线 ID。不能恢复到在基础备份之前就已分支出去的时间线。 @@ -603,14 +619,14 @@ restore_command = 'cp /mnt/server/archivedir/%f %p' - 单机热备份 + 独立热备份 - 可以利用PostgreSQL的备份设施生成单机热备份。这些备份不能用于时间点恢复,但它们的制作和恢复通常都比pg_dump转储快得多。(它们也比pg_dump转储大得多,因此在某些情况下速度优势可能会被抵消。) + 可以利用PostgreSQL的备份设施生成独立热备份。这些备份不能用于时间点恢复,但它们的制作和恢复通常都比pg_dump转储快得多。(它们也比pg_dump转储大得多,因此在某些情况下速度优势可能会被抵消。) - 和基础备份一样,生成单机热备份最简单的方法是使用工具。如果在调用它时包含-X参数,使用该备份所需的全部预写式日志都会自动包含在备份中,恢复该备份时也不需要额外动作。 + 和基础备份一样,生成独立热备份最简单的方法是使用工具。如果在调用它时包含-X参数,使用该备份所需的全部预写式日志都会自动包含在备份中,恢复该备份时也不需要额外动作。 如果复制备份文件时需要更大的灵活性,也可以使用更低级的流程制作独立热备份。要准备低级独立热备份,请确保将 wal_level 设为 replica 或更高值,将 archive_mode 设为 on,并配置一个 archive_command,使其仅在开关文件存在时执行归档。例如: @@ -651,7 +667,7 @@ archive_command = 'local_backup_script.sh "%p" "%f"' - 脚本中可能需要解决的需求示例包括: + 可以在脚本中处理的需求示例包括: @@ -660,7 +676,7 @@ archive_command = 'local_backup_script.sh "%p" "%f"' - 把 WAL 文件成批处理,使其每三个小时传输一次,而不是每生成一个就传一次 + 把 WAL 文件成批处理,使其每三个小时传输一次,而不是每次只传输一个 @@ -687,7 +703,10 @@ archive_command = 'local_backup_script.sh "%p" "%f"' 注意事项 - 撰写本文时,连续归档技术还有几个限制。这些限制可能会在未来版本中消除: + + 在撰写本文时,持续归档技术还存在若干局限。这些问题很可能会在未来版本中得到修复: + + 如果在进行基础备份时执行了命令,而该CREATE DATABASE所复制的模板数据库又在基础备份尚未结束时被修改,那么恢复时可能会把这些修改也传播到新建数据库中。这当然并不理想。为避免这种风险,最好在进行基础备份时不要修改任何模板数据库。 diff --git a/zh/11/brin.sgml b/zh/11/brin.sgml index ba5083b1..2f2d99dd 100644 --- a/zh/11/brin.sgml +++ b/zh/11/brin.sgml @@ -4,7 +4,7 @@ BRIN 索引 - index + 索引 BRIN @@ -20,8 +20,7 @@ - 如果索引中存储的摘要信息与查询条件相一致BRIN - 索引就可以通过常规位图索引扫描来满足查询,并返回每个范围内所有页上的全部元组。 + BRIN 索引可以通过常规位图索引扫描来满足查询;对于每个范围,如果索引中存储的摘要信息与查询条件相一致,就会返回该范围内所有页上的全部元组。 查询执行器负责重新检查这些元组,并丢弃不匹配查询条件的元组 — 换句话说,这些索引是有损的。 由于 BRIN 索引非常小,与顺序扫描相比,扫描索引只会带来很小的额外开销, 但可以避免扫描那些已知不包含匹配元组的大块表数据。 @@ -293,7 +292,7 @@ LOG: request for BRIN range summarization for index "brin_wi_idx" page 128 was range_inclusion_ops - any range type + 任意范围类型 << &< && &> >> @> <@ -|- = < <= = > >= @@ -429,20 +428,25 @@ LOG: request for BRIN range summarization for index "brin_wi_idx" page 128 was BrinOpcInfo *opcInfo(Oid type_oid) - 返回索引列摘要数据的内部信息。返回值必须指向一个由 palloc 分配的BrinOpcInfo,其定义如下: + + 返回被索引列的摘要数据的内部信息。返回值必须指向一个用 palloc 分配的 + BrinOpcInfo,其定义如下: + typedef struct BrinOpcInfo { - /* Number of columns stored in an index column of this opclass */ + /* 此操作符类在一个索引列中存储的列数 */ uint16 oi_nstored; - /* Opaque pointer for the opclass' private use */ + /* 供操作符类私有使用的不透明指针 */ void *oi_opaque; - /* Type cache entries of the stored columns */ + /* 所存储列的类型缓存条目 */ TypeCacheEntry *oi_typcache[FLEXIBLE_ARRAY_MEMBER]; } BrinOpcInfo; - BrinOpcInfo.oi_opaque可供操作符类函数使用,在索引扫描期间于各支持函数之间传递信息。 + BrinOpcInfo.oi_opaque + 可供操作符类例程在索引扫描期间于各个支持函数之间传递信息。 + @@ -603,62 +607,62 @@ typedef struct BrinOpcInfo 操作符策略 1 - left-of 操作符 + 位于左侧的操作符 操作符策略 4 操作符策略 2 - does-not-extend-to-the-right-of 操作符 + 不延伸到右侧的操作符 操作符策略 5 操作符策略 3 - overlaps 操作符 + 重叠操作符 操作符策略 4 - does-not-extend-to-the-left-of 操作符 + 不延伸到左侧的操作符 操作符策略 1 操作符策略 5 - right-of 操作符 + 位于右侧的操作符 操作符策略 2 - 操作符策略 6, 18 - same-as-or-equal-to 操作符 + 操作符策略 6、18 + 相同或等于操作符 操作符策略 7 - 操作符策略 7, 13, 16, 24, 25 - contains-or-equal-to 操作符 + 操作符策略 7、13、16、24、25 + 包含或等于操作符 - 操作符策略 8, 14, 26, 27 - is-contained-by-or-equal-to 操作符 + 操作符策略 8、14、26、27 + 被包含或等于操作符 操作符策略 3 操作符策略 9 - does-not-extend-above 操作符 + 不延伸到上方的操作符 操作符策略 11 操作符策略 10 - is-below 操作符 + 位于下方的操作符 操作符策略 12 操作符策略 11 - is-above 操作符 + 位于上方的操作符 操作符策略 9 操作符策略 12 - does-not-extend-below 操作符 + 不延伸到下方的操作符 操作符策略 10 diff --git a/zh/11/btree.sgml b/zh/11/btree.sgml index 653a142f..5b0ebd19 100644 --- a/zh/11/btree.sgml +++ b/zh/11/btree.sgml @@ -4,7 +4,7 @@ B-树索引 - index + 索引 B-树 @@ -18,10 +18,10 @@ - 由于每个 B-树 操作符类都会为其数据类型施加一种排序顺序,B-树 + 由于每个 B-树操作符类都会为其数据类型施加一种排序顺序,B-树 操作符类(更准确地说,是操作符族)已经成为 PostgreSQL 用来统一表示和理解排序语义的方式。因此,它们具备了一些超出单纯支持 - B-树 索引所需范围的特性,系统中某些与 btree AM + B-树索引所需范围的特性,系统中某些与 B-树 AM 相距甚远的部分也会利用它们。 @@ -55,7 +55,7 @@ - = 操作符必须是一种等价关系;也就是说,对于该数据类型的所有非空值 + = 操作符必须是一种等价关系;也就是说,对于该数据类型的所有非 null 值 ABC: @@ -93,7 +93,7 @@ - < 操作符必须是一种强排序关系;也就是说,对于所有非空值 + < 操作符必须是一种强排序关系;也就是说,对于所有非 null 值 ABC: @@ -123,7 +123,7 @@ - 此外,该顺序还是全序的;也就是说,对于所有非空值 + 此外,该顺序还是全序的;也就是说,对于所有非 null 值 AB: @@ -176,14 +176,14 @@ B-树支持函数 - 所示,btree 定义了一个必需支持函数和两个可选支持函数。 + 所示,B-树定义了一个必需支持函数和两个可选支持函数。 - 对于 B-树 操作符族为其提供比较操作符的每一种数据类型组合,都必须提供一个比较支持函数。该函数在 + 对于 B-树操作符族为其提供比较操作符的每一种数据类型组合,都必须提供一个比较支持函数。该函数在 pg_amproc 中注册,支持函数编号为 1,并且 amproclefttype/amprocrighttype 要等于该比较的左右数据类型(也就是与匹配操作符在 - pg_amop 中注册时相同的数据类型)。比较函数必须接受两个非空值 + pg_amop 中注册时相同的数据类型)。比较函数必须接受两个非 null 值 AB,并返回一个 int32 值,其值为 < 0、 @@ -192,12 +192,12 @@ < BA = BA - > B。不允许返回空值:该数据类型的所有值都必须可比较。示例见 + > B。不允许返回 null:该数据类型的所有值都必须可比较。示例见 src/backend/access/nbtree/nbtcompare.c - 如果参与比较的值属于可排序数据类型,则会通过标准的 + 如果参与比较的值属于支持排序规则的数据类型,则会通过标准的 PG_GET_COLLATION() 机制,把适当的排序规则 OID 传递给比较支持函数。 @@ -210,11 +210,11 @@ - in_range support functions + in_range 支持函数 - support functions + 支持函数 in_range @@ -230,14 +230,35 @@ offset 值进行加减。 - in_range函数必须具有以下签名: + + in_range 函数必须具有如下签名: + in_range(val type1, base type1, offset type2, sub bool, less bool) returns bool - valbase必须具有相同的类型,且该类型是操作符族支持的类型之一(即该操作符族为其提供排序顺序的类型)。但是,offset可以具有不同的类型,甚至可以是操作符族在其他方面不支持的类型。例如,内置的time_ops操作符族提供一个in_range函数,其中offset的类型为interval。操作符族可以提供in_range函数,用于其支持的任意类型与一种或多种offset类型的组合。每个in_range函数都应登记在pg_amproc中,并使amproclefttype等于type1amprocrighttype等于type2。 + val 和 + base 必须具有相同类型,并且该类型必须是操作符族支持的类型之一(也就是该族为其提供排序的一种类型)。不过, + offset + 可以是另一种类型,而该类型甚至可能不被该族以其他方式支持。例如,内置的 + time_ops 族就提供了一个 in_range + 函数,其 offset 的类型为 + interval。一个族可以提供 in_range + 函数,分别对应其支持的任意类型以及一个或多个 + offset 类型。每个 + in_range 函数都应在 + pg_amproc 中登记,其中 + amproclefttype 等于 + type1,而 + amprocrighttype 等于 + type2 - 对于in_range函数,其核心语义取决于两个布尔标志参数。它应当先对baseoffset做加法或减法,再把val与结果比较,具体如下: + + in_range 函数的核心语义取决于这两个布尔 + 标志参数。它应当先对 base 与 + offset 做加法或减法,再把 + val 与结果比较,具体如下: + 如果 !sub 且 @@ -274,7 +295,15 @@ returns bool offset) - 在此之前,函数应检查offset的符号:如果它小于零,就引发错误ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE(22013),错误文本类似于invalid preceding or following size in window function。(这是 SQL 标准的要求,尽管非标准操作符族或许会选择忽略这一限制,因为从语义上看似乎并没有太大必要。)把这个要求委托给in_range函数,是为了让核心代码无需理解小于零对于某个特定数据类型究竟意味着什么。 + + 在此之前,函数应检查 offset 的符号:如果它小于零,就引发错误 + ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE + (22013),错误文本类似于 + invalid preceding or following size in window function。 + (这是 SQL 标准的要求,尽管非标准操作符族或许会选择忽略这一限制,因为从语义上看似乎并没有太大必要。) + 把这个要求委托给 in_range + 函数,是为了让核心代码无需理解对于某个特定数据类型来说小于零究竟意味着什么。 + 另外还希望 in_range 函数在可行时避免因为 @@ -287,7 +316,11 @@ returns bool in_range 的结果与该操作符族的正常排序顺序一致。 - in_range函数的结果必须与操作符族规定的排序顺序一致。具体而言,对于任意固定的offsetsub值,应满足以下条件: + + in_range 函数的结果必须与操作符族施加的排序顺序保持一致。更精确地说,给定任意固定的 + offset 和 + sub 值,则: + 如果 in_range 在 @@ -332,10 +365,13 @@ returns bool val 相同,它也必须返回假。 - less= false 时,类似的结论成立,但条件相反。 + + 当 less = false + 时,也有条件相反的对应陈述成立。 + - 如果被排序的类型(type1)属于可排序数据类型,则会通过标准的 + 如果被排序的类型(type1)属于支持排序规则的数据类型,则会通过标准的 PG_GET_COLLATION() 机制,把适当的排序规则 OID 传递给 in_range 函数。 @@ -350,7 +386,7 @@ returns bool 实现 - 可在src/backend/access/nbtree/README中找到对 btree 索引实现的介绍。 + 可在src/backend/access/nbtree/README中找到对 B-树索引实现的介绍。 diff --git a/zh/11/catalogs.sgml b/zh/11/catalogs.sgml index 7f851876..e81e5cd4 100644 --- a/zh/11/catalogs.sgml +++ b/zh/11/catalogs.sgml @@ -369,7 +369,7 @@ - Name + 名称 类型 引用 @@ -592,7 +592,7 @@ - Name + 名称 类型 引用 @@ -663,7 +663,7 @@ - Name + 名称 类型 引用 @@ -806,7 +806,7 @@ - Name + 名称 类型 引用 @@ -897,7 +897,7 @@ - Name + 名称 类型 引用 @@ -979,7 +979,7 @@ - Name + 名称 类型 引用 @@ -1071,7 +1071,7 @@ atttypmod记录了在表创建时提供的类型相关数据(例如一个varchar列的最大长度)。 - 它会被传递给类型相关的输入函数和长度强制函数。对于那些不需要atttypmod的类型,这个值通常总是为-1。 + 它会被传递给类型相关的输入函数和长度强制转换函数。对于那些不需要atttypmod的类型,这个值通常为 -1。 @@ -1108,7 +1108,7 @@ bool - 此列具有一个非空约束(可能尚未验证) + 这代表一个非空约束 @@ -1124,8 +1124,7 @@ bool - 该列在行中完全缺失时会用到这个列的值,如果在行创建之后增加一个有非易失DEFAULT值的列,就会发生这种情况。 - 实际使用的值被存放在attmissingval列中。 + 此列有一个值,供该列在数据行中完全缺失时使用;在数据行创建之后添加带有非易失 DEFAULT 值的列时,就会出现这种情况。实际使用的值存储在 attmissingval 列中。 @@ -1144,7 +1143,7 @@ bool - 该列被删除且不再有效。一个删除的列仍然物理存在于表中,但是会被分析器忽略并因此无法通过SQL访问。 + 该列被删除且不再有效。一个删除的列仍然物理存在于表中,但是会被解析器忽略并因此无法通过SQL访问。 @@ -1171,7 +1170,7 @@ oid pg_collation.oid - 该列被定义的排序规则,如果该列不是一个可排序数据类型则为0。 + 该列定义的排序规则;如果该列的数据类型不支持排序规则,则为零。 @@ -1180,7 +1179,7 @@ aclitem[] - 列级访问权限, 如果此列上已有特别授予的权限 + 列级访问权限,如果此列上已有特别授予的权限 @@ -1208,7 +1207,7 @@ 这个列中是一个含有一个元素的数组,其中的值被用于该列在行中完全缺失时,如果在行创建之后增加一个有非易失DEFAULT值的列,就会发生这种情况。 - 只有当atthasmissing为真时才使用这个值。如果没有值则该列为空。 + 只有当atthasmissing为真时才使用这个值。如果没有值则该列为空值。 @@ -1217,9 +1216,7 @@ - 在一个被删除的列的pg_attribute的项中,atttypid被重置为0,但attlen以及其他从pg_type拷贝的域仍然有效。 - 这种安排用于处理一种情况,即被删除列的数据类型后来被删除,并且因此不再有相应的pg_type行。 - attlen和其他域可以被用来解释表的一行的内容。 + 在被删除列的 pg_attribute 条目中,atttypid 被重置为零,但 attlen 以及其他从 pg_type 复制的字段仍然有效。这种安排用于应对被删除列的数据类型后来也被删除、因而不再有相应 pg_type 行的情况。attlen 和其他字段可用于解释表中一行的内容。 @@ -1253,7 +1250,7 @@ - Name + 名称 类型 描述 @@ -1337,21 +1334,21 @@ rolconnlimit int4 - 对于可以登录的角色,本列设置该角色可以同时发起最大连接数。-1表示无限制。 + 对于可以登录的角色,本列设置该角色能够建立的最大并发连接数。-1 表示无限制。 rolpassword text - 密码(可能已加密);如果没有则为空。其格式取决于所使用的加密形式。 + 密码(可能已加密);如果未设置则为空值。其格式取决于所使用的加密方式。 rolvaliduntil timestamptz - 密码过期时间(只用于密码鉴定),如果永不过期则为空 + 密码过期时间(仅用于密码认证);不设过期时间时为空值 @@ -1359,7 +1356,7 @@ - 对于一个MD5加密的密码,rolpassword列将由字符串md5后面跟上一个32字符的十六进制MD5哈希值构成。MD5哈希值将是该用户的密码串接上它们的用户名。例如,如果用户joe的密码是xyzzy,则PostgreSQL将存储xyzzyjoe的md5哈希。 + 对于一个MD5加密的密码,rolpassword列将由字符串md5后面跟上一个32字符的十六进制MD5哈希值构成。MD5 哈希值通过在用户密码后拼接用户名再计算得到。例如,如果用户joe的密码是xyzzy,则PostgreSQL将存储xyzzyjoe的md5哈希。 如果密码使用 SCRAM-SHA-256 加密,其格式为: @@ -1391,7 +1388,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -1455,7 +1452,7 @@ SCRAM-SHA-256$<iteration count>:&l - 需要注意的是,pg_cast并不表示系统知道如何执行的所有类型转换,它只包括那些不能从某些通用规则推导出的转换。例如,一个域及其基类型之间的转换并未显式地在pg_cast中展示。另一个重要的例外是自动的基于 I/O 的类型转换,它们通过数据类型自己的 I/O 函数来转换成(或者转换自)text或其他字符串类型,这些转换也没有显式地在pg_cast中表示。 + 需要注意的是,pg_cast并不表示系统知道如何执行的所有类型转换,它只包括那些不能从某些通用规则推导出的转换。例如,一个域及其基础类型之间的转换并未显式地在pg_cast中展示。另一个重要的例外是自动的基于 I/O 的类型转换,它们通过数据类型自己的 I/O 函数来转换成(或者转换自)text或其他字符串类型,这些转换也没有显式地在pg_cast中表示。 @@ -1464,7 +1461,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -1555,7 +1552,7 @@ SCRAM-SHA-256$<iteration count>:&l - 目录pg_class描述了具有列或与表类似的其他对象。这包括索引(但请参见pg_index)、序列(但请参见pg_sequence)、视图、物化视图、复合类型和TOAST表;请参见relkind。 + 目录pg_class描述了表以及其他具有列或在其他方面与表类似的对象。这包括索引(但请参见pg_index)、序列(但请参见pg_sequence)、视图、物化视图、复合类型和TOAST表;请参见relkind。 在下面,当我们指的是所有这些类型的对象时,我们称之为关系(relations)。并非所有pg_class的列对所有关系类型都有意义。 @@ -1565,7 +1562,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -1629,7 +1626,7 @@ SCRAM-SHA-256$<iteration count>:&l relam oid pg_am.oid - 如果这是索引,则为使用的访问方法(B-树、哈希等) + 如果这是索引,则为使用的访问方法(B-树、hash 等) @@ -1714,7 +1711,7 @@ SCRAM-SHA-256$<iteration count>:&l char - p = 永久表, u = 不记录 WAL 的表, + p = 永久表,u = 不记录 WAL 的表, t = 临时表 @@ -1816,7 +1813,7 @@ SCRAM-SHA-256$<iteration count>:&l bool - 如果表已被填充则为真(对于所有关系该列都为真,但对于某些物化视图却不是) + 如果关系已被填充则为真(对于所有关系该列都为真,但对于某些物化视图却不是) @@ -1868,7 +1865,7 @@ SCRAM-SHA-256$<iteration count>:&l xid - 在此之前的多事务ID在表中已经被替换为一个事务ID。这被用于跟踪表是否需要被清理,以阻止 + 在此之前的所有多事务ID在表中已经被替换为一个事务ID。这被用于跟踪表是否需要被清理,以阻止 多事务ID回卷或者允许pg_multixact被收缩。如果关系不是一个表则 为0(InvalidMultiXactId)。 @@ -1895,7 +1892,7 @@ SCRAM-SHA-256$<iteration count>:&l pg_node_tree - 如果表示一个分区(见relispartition),则为分区边界的内部表示 + 如果表是一个分区(见relispartition),则为分区边界的内部表示 @@ -1903,7 +1900,7 @@ SCRAM-SHA-256$<iteration count>:&l
- pg_class中的一些逻辑标志被以一种懒惰的方式维护:在正确状态时它们被保证为真,但是当条件不再为真时它们并不会被立刻重置为假。 + pg_class中的一些布尔标志采用延迟维护:当条件成立时,保证它们为真;但当条件不再成立时,可能不会立即将它们重置为假。 例如,relhasindexCREATE INDEX设置,但它从不会被DROP INDEX清除。 作为替代,VACUUM会在找到无索引表后清除其relhasindex。 这种安排避免了竞争条件并且提高了并发性。 @@ -1927,7 +1924,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -1976,9 +1973,10 @@ SCRAM-SHA-256$<iteration count>:&l char - 排序规则提供者:d = 数据库默认值, + 排序规则提供程序:d = 数据库默认值, c = libc, - i = icu + i = icu + @@ -2013,7 +2011,7 @@ SCRAM-SHA-256$<iteration count>:&l text - 排序规则的提供者相关的版本。这是在排序规则创建时记录下来的,并且在使用排序规则时会被检查以检测可能导致数据损坏的排序规则定义的改变。 + 提供程序特有的排序规则版本。它会在创建排序规则时记录下来,并在使用时接受检查,以检测可能导致数据损坏的排序规则定义更改。 @@ -2058,7 +2056,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -2318,9 +2316,9 @@ SCRAM-SHA-256$<iteration count>:&l - 在一个排他约束的情况中, conkey只对约束元素是单一列引用时有用。 - 对于其他情况,conkey中出现一个0且必须查阅相关索引来发现被约束的表达式。 - (对于索引,conkey因此和pg_index.indkey具有相同的内容)。 + 对于排他约束,conkey仅对作为简单列引用的约束元素有用。 + 对于其他情况,conkey中会出现一个 0,必须查阅关联索引来确定被约束的表达式。 + (因此,conkey与该索引的 pg_index.indkey具有相同的内容。) @@ -2355,7 +2353,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -2464,7 +2462,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -2630,7 +2628,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -2689,7 +2687,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -2787,7 +2785,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -2970,7 +2968,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -3039,7 +3037,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -3113,7 +3111,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -3203,7 +3201,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -3310,7 +3308,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -3401,7 +3399,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -3503,7 +3501,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -3563,7 +3561,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -3614,7 +3612,7 @@ SCRAM-SHA-256$<iteration count>:&l bool - 如为真, 这是唯一索引 + 如为真, 这是唯一索引 @@ -3720,7 +3718,7 @@ SCRAM-SHA-256$<iteration count>:&l oidvector pg_collation.oid - 对于索引键(indnkeyatts值)中的每一列,这包含要用于该索引的排序规则的OID,如果该列不是一种可排序数据类型则为零。 + 对于索引键(indnkeyatts值)中的每一列,这包含要用于该索引的排序规则的OID,如果该列的数据类型不支持排序规则则为零。 @@ -3783,7 +3781,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -3850,7 +3848,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -3928,7 +3926,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -4042,7 +4040,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -4105,7 +4103,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -4161,7 +4159,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -4230,7 +4228,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -4348,7 +4346,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -4518,7 +4516,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -4599,7 +4597,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -4671,7 +4669,7 @@ SCRAM-SHA-256$<iteration count>:&l oidvector pg_opclass.oid - 对于分区键中的每一个列,这个域包含要用于分区的排序规则的OID,如果该列不是一种可排序数据类型则为零。 + 对于分区键中的每一个列,这个域包含要用于分区的排序规则的OID,如果该列的数据类型不支持排序规则则为零。 @@ -4715,7 +4713,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 描述 @@ -4811,7 +4809,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -4922,7 +4920,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -5233,7 +5231,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -5334,7 +5332,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -5383,7 +5381,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -5451,7 +5449,11 @@ SCRAM-SHA-256$<iteration count>:&l - rngsubopc (加上rngcollation,如果元素类型是可排序的)决定了被该范围类型所使用的排序顺序。rngcanonical用于离散类型的元素类型。rngsubdiff是可选的,但是提供它可以提高范围类型上的GiST索引性能。 + rngsubopc(如果元素类型支持排序规则,则还包括 + rngcollation)决定范围类型所用的排序顺序。 + rngcanonical用于元素类型为离散类型的情况。 + rngsubdiff是可选的,但应当提供它, + 以提高范围类型上的 GiST 索引性能。
@@ -5478,7 +5480,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -5527,7 +5529,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -5645,7 +5647,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -5722,7 +5724,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -5832,7 +5834,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -5986,7 +5988,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -6054,7 +6056,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -6115,8 +6117,8 @@ SCRAM-SHA-256$<iteration count>:&l 通常,每个已分析的表列都有一个条目,其中stainherit = false。 - 如果表具有继承子项或分区,则还会创建第二个条目,其中stainherit = true。 - 此行表示继承树上列的统计信息,即您可以通过SELECT column FROM table*看到的数据的统计信息, + 如果表具有继承子表,则还会创建第二个条目,其中stainherit = true。 + 此行表示继承树上列的统计信息,即你可以通过SELECT column FROM table*看到的数据的统计信息, 而stainherit = false行表示SELECT column FROM ONLY table的结果。 @@ -6125,7 +6127,7 @@ SCRAM-SHA-256$<iteration count>:&l - 因为不同类型的统计信息适用于不同类型的数据, pg_statistic 被设计成不太在意自己存储的是什么类型的统计。 只有极为常用的统计信息(比如NULL的含量)才在pg_statistic里给予专用的字段。 其它所有东西都存储在槽位中,而槽位是一组相关的列, 它们的内容用槽位中的一个列里的代码表示。 更详细的信息请参阅 src/include/catalog/pg_statistic.h。 + 由于不同种类的数据可能适合不同种类的统计信息,pg_statistic 在设计上尽量不对所存储的统计信息种类作出假定。只有极为通用的统计信息(例如空值情况)才在 pg_statistic 中有专用的列。其余统计信息都存储在槽位中。每个槽位都是一组相关的列,其内容由其中一列的代码编号来标识。更多信息见 src/include/catalog/pg_statistic.h @@ -6138,7 +6140,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -6180,7 +6182,7 @@ SCRAM-SHA-256$<iteration count>:&l float4 - 列的项为空的比例 + 列中空值所占的比例 @@ -6198,8 +6200,8 @@ SCRAM-SHA-256$<iteration count>:&l float4 - 列中非空唯一值的数目。一个大于零的值是唯一值的真正数目。 - 一个小于零的值是表中行数的乘数的负值;例如,对于一个 80% 的值为非空且每个非空值平均出现两次的列,可以表示为stadistinct = -0.4。一个0值表示唯一值的数目未知。 + 列中不同非空数据值的数量。一个大于零的值是不同值的真正数目。 + 一个小于零的值是表中行数的乘数的负值;例如,对于一个约 80% 的值为非空且每个非空值平均出现两次的列,可以表示为stadistinct = -0.4。一个0值表示不同值的数目未知。 @@ -6227,7 +6229,7 @@ SCRAM-SHA-256$<iteration count>:&l float4[] - 第N槽位的类型的数值类型统计, 如果该槽位不涉及数值类型则为NULL + 第N槽位中相应种类的数值统计信息;如果该槽位种类不涉及数值,则为 NULL @@ -6237,7 +6239,7 @@ SCRAM-SHA-256$<iteration count>:&l N槽位的类型的列值,如果该槽位类型不存储任何数据值则为 NULL。 - 每个数组的元素值实际上都是指定列的数据类型或者是一个相关类型(如数组元素类型), 因此,除了把这些列的类型定义成anyarray之外别无他法。 + 每个数组的元素值实际上都是指定列的数据类型或者是一个相关类型(如数组元素类型), 因此,无法把这些列的类型定义得比anyarray更具体。 @@ -6264,7 +6266,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -6384,7 +6386,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -6499,7 +6501,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -6574,7 +6576,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -6648,7 +6650,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -6718,7 +6720,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -6825,7 +6827,7 @@ SCRAM-SHA-256$<iteration count>:&l bool - 如果约束触发器可推迟则为真 + 如果约束触发器可延迟则为真 @@ -6834,7 +6836,7 @@ SCRAM-SHA-256$<iteration count>:&l bool - 如果约束触发器初始可推迟则为真 + 如果约束触发器初始处于延迟状态则为真 @@ -6937,7 +6939,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -7016,7 +7018,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -7088,7 +7090,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -7176,7 +7178,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -7282,7 +7284,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -7349,7 +7351,7 @@ SCRAM-SHA-256$<iteration count>:&l 目录pg_type存储有关数据类型的信息。 - 基类型和枚举类型(标量类型)使用创建,而域使用创建。 + 基础类型和枚举类型(标量类型)使用创建,而域使用创建。 数据库中的每一个表都会有一个自动创建的复合类型,用于表示表的行结构。 也可以使用CREATE TYPE AS创建复合类型。 @@ -7360,7 +7362,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -7432,7 +7434,7 @@ SCRAM-SHA-256$<iteration count>:&l typtype可以是: - b表示一个基类型, + b表示一个基础类型, c表示一个复合类型(例如一个表的行类型), d表示一个域, e表示一个枚举类型, @@ -7653,7 +7655,7 @@ SCRAM-SHA-256$<iteration count>:&l int4 - 域使用typtypmod来记录被应用于它们基类型的typmod(如果基类型不使用typmod,则为-1)。如果此类型不是一个域则为-1。 + 域使用typtypmod来记录被应用于它们基础类型的typmod(如果基础类型不使用typmod,则为-1)。如果此类型不是一个域则为-1。 @@ -7672,8 +7674,8 @@ SCRAM-SHA-256$<iteration count>:&l pg_collation.oid typcollation指定此类型的排序规则。如果类型不支持排序规则,此列为零。 - 支持排序规则的基类型在这里会有DEFAULT_COLLATION_OID。 - 基于可应用排序规则类型的域,如果为其指定了排序规则 OID,则它的排序规则 OID 可以不同于其基类型。 + 支持排序规则的基础类型在这里会有DEFAULT_COLLATION_OID。 + 基于支持排序规则的类型的域,如果为其指定了排序规则 OID,则它的排序规则 OID 可以不同于其基础类型的排序规则 OID。 @@ -7806,7 +7808,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -8054,7 +8056,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 描述 @@ -8122,7 +8124,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 描述 @@ -8223,7 +8225,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 描述 @@ -8291,7 +8293,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 描述 @@ -8388,7 +8390,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 描述 @@ -8480,7 +8482,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -8550,7 +8552,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 描述 @@ -8651,7 +8653,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -8697,7 +8699,7 @@ SCRAM-SHA-256$<iteration count>:&l text - 索引定义(重构出的 CREATE INDEX 命令) + 索引定义(重建出的 CREATE INDEX 命令) @@ -8731,8 +8733,8 @@ SCRAM-SHA-256$<iteration count>:&l 以及一般的数据库对象(由类OID和对象OID标识, 与pg_descriptionpg_depend中的方式相同)。 - 此外,扩展关系的权限被表示为一个单独的可锁定对象,以及更新 - pg_database.datfrozenxid 的更新权限。 + 此外,扩展关系的权利被表示为单独的可锁定对象,更新 + pg_database.datfrozenxid的权利也是如此。 此外,还可以对具有用户定义含义的数字施加咨询锁。 @@ -8742,7 +8744,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -8762,7 +8764,7 @@ SCRAM-SHA-256$<iteration count>:&l oid pg_database.oid - 锁目标存在的数据库的OID,如果目标是一个共享对象则为0,如果目标是一个事务ID则为空 + 锁目标存在的数据库的OID,如果目标是一个共享对象则为0,如果目标是一个事务ID则为 NULL @@ -8770,7 +8772,7 @@ SCRAM-SHA-256$<iteration count>:&l oid pg_class.oid - 作为锁目标的关系的OID,如果目标不是一个关系或者只是关系的一部分则此列为空 + 作为锁目标的关系的OID,如果目标既不是关系,也不是关系的一部分则此列为 NULL @@ -8778,7 +8780,7 @@ SCRAM-SHA-256$<iteration count>:&l integer - 作为锁目标的页在关系中的页号,如果目标不是一个关系页或元组则此列为空 + 作为锁目标的页在关系中的页号,如果目标不是一个关系页或元组则此列为 NULL @@ -8786,7 +8788,7 @@ SCRAM-SHA-256$<iteration count>:&l smallint - 作为锁目标的元组在页中的元组号,如果目标不是一个元组则此列为空 + 作为锁目标的元组在页中的元组号,如果目标不是一个元组则此列为 NULL @@ -8794,7 +8796,7 @@ SCRAM-SHA-256$<iteration count>:&l text - 锁定目标事务的虚拟 ID,如果目标不是虚拟事务 ID,则为空 + 锁定目标事务的虚拟 ID,如果目标不是虚拟事务 ID,则为 NULL @@ -8802,7 +8804,7 @@ SCRAM-SHA-256$<iteration count>:&l xid - 锁定目标事务的标识,如果目标不是事务 ID,则为空 + 锁定目标事务的标识,如果目标不是事务 ID,则为 NULL @@ -8810,7 +8812,7 @@ SCRAM-SHA-256$<iteration count>:&l oid pg_class.oid - 包含锁目标的系统目录的OID,如果目标不是一个普通数据库对象则此列为空 + 包含锁目标的系统目录的OID,如果目标不是一个普通数据库对象则此列为 NULL @@ -8818,7 +8820,7 @@ SCRAM-SHA-256$<iteration count>:&l oid 任意 OID 列 - 锁目标在它的系统目录中的OID,如果目标不是一个普通数据库对象则为空 + 锁目标在它的系统目录中的OID,如果目标不是一个普通数据库对象则为 NULL @@ -8826,7 +8828,7 @@ SCRAM-SHA-256$<iteration count>:&l smallint - 锁的目标列号(classidobjid指表本身),如果目标是某种其他普通数据库对象则此列为0,如果目标不是一个普通数据库对象则此列为空 + 锁的目标列号(classidobjid指表本身),如果目标是某种其他普通数据库对象则此列为0,如果目标不是一个普通数据库对象则此列为 NULL @@ -8842,7 +8844,7 @@ SCRAM-SHA-256$<iteration count>:&l integer - 保持这个锁或者正在等待这个锁的服务器进程的PID,如果此锁被一个预备事务所持有则此列为空 + 保持这个锁或者正在等待这个锁的服务器进程的PID,如果此锁被一个预备事务所持有则此列为 NULL @@ -8893,8 +8895,8 @@ SCRAM-SHA-256$<iteration count>:&l 咨询锁可以在由单个 bigint 值或两个整数值组成的键上获取。 - 一个bigint键在classid列中显示其高阶半部分, - 在objid列中显示其低阶半部分,并且objsubid等于1。 + 一个bigint键在classid列中显示其高位半部分, + 在objid列中显示其低位半部分,并且objsubid等于1。 可以使用表达式(classid::bigint << 32) | objid::bigint重新组装原始bigint值。 整数键在classid列中显示第一个键,在objid列中显示第二个键, 并且 objsubid 等于 2。键的实际含义由用户自行决定。咨询锁在每个数据库内都是本地的, @@ -8938,15 +8940,15 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx pg_locks视图显示来自常规锁管理器和谓词锁管理器的数据,这两个是独立的系统; - 此外,常规锁管理器将其锁分为常规锁和fast-path锁。 + 此外,常规锁管理器将其锁分为常规锁和快速路径锁。 不能保证这些数据完全一致。 当查询该视图时, - fast-path 锁的数据(具有fastpath = true) + 快速路径锁的数据(具有fastpath = true) 从每个后端逐个收集,而不会冻结整个锁管理器的状态,因此在收集信息时可能会发生锁的获取或释放。 但请注意,这些锁已知不会与当前放置的任何其他锁发生冲突。 - 在查询所有后端的 fast-path 锁后,剩余的常规锁管理器将作为一个单元被锁定,并且所有剩余锁的一致快照将作为一个原子操作收集。 + 在查询所有后端的快速路径锁后,剩余的常规锁管理器将作为一个单元被锁定,并且所有剩余锁的一致快照将作为一个原子操作收集。 解锁常规锁管理器后,谓词锁管理器类似地被锁定,并且所有谓词锁将作为一个原子操作收集。 - 因此,除了 fast-path 锁外,每个锁管理器将提供一致的结果集,但由于我们不同时锁定两个锁管理器,因此在询问常规锁管理器后和在询问谓词锁管理器前,可能会发生锁的获取或释放。 + 因此,除了快速路径锁外,每个锁管理器将提供一致的结果集,但由于我们不同时锁定两个锁管理器,因此在询问常规锁管理器后和在询问谓词锁管理器前,可能会发生锁的获取或释放。 @@ -8977,7 +8979,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - Name + 名称 类型 引用 @@ -9039,7 +9041,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx text - 物化视图的定义(一个重构的SELECT查询) + 物化视图的定义(一个重建的SELECT查询) @@ -9065,7 +9067,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - Name + 名称 类型 引用 @@ -9168,7 +9170,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - Name + 名称 类型 描述 @@ -9243,7 +9245,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - Name + 名称 类型 引用 @@ -9323,7 +9325,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - Name + 名称 类型 引用 @@ -9383,7 +9385,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - Name + 名称 类型 引用 @@ -9455,7 +9457,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - Name + 名称 类型 引用 @@ -9522,7 +9524,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx boolean - 如果该槽当前正被用于流送则为真 + 如果该槽当前正在使用中则为真 @@ -9531,7 +9533,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx integer - 为该槽流送数据的会话的进程 ID。NULL 表示不活动。 + 如果该槽当前正在使用中,则为使用该槽的会话的进程 ID;不活动时为 NULL @@ -9565,7 +9567,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx pg_lsn - 逻辑槽消费者已确认接收到数据的地址(LSN)。早于此地址的数据将不再可用。物理槽为 NULL。 + 逻辑槽消费者已确认接收的数据所到达的地址(LSN)。早于此地址的数据将不再可用。物理槽为 NULL @@ -9583,7 +9585,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx 视图pg_roles提供数据库角色的信息。它本质上是 - pg_authid 的公开可读视图,并将密码字段清空。 + pg_authid 的公开可读视图,并隐藏密码字段。 此视图显式显示底层表的 OID 列,因为与其他目录连接时需要此列。 @@ -9594,7 +9596,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - Name + 名称 类型 引用 @@ -9672,7 +9674,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx int4 - 对于可以登录的角色,本列设置该角色可以同时发起最大连接数。-1表示无限制。 + 对于可以登录的角色,本列设置该角色能够建立的最大并发连接数。-1 表示无限制。 @@ -9690,7 +9692,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx timestamptz - 密码过期时间(只用于密码认证),如果永不过期则为空 + 密码过期时间(仅用于密码认证);不设过期时间时为空值 @@ -9743,7 +9745,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - Name + 名称 类型 引用 @@ -9781,7 +9783,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx text - 规则定义(创建命令的重构) + 规则定义(重建的创建命令) @@ -9814,7 +9816,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - Name + 名称 类型 引用 @@ -9909,7 +9911,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - Name + 名称 类型 引用 @@ -10031,7 +10033,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - Name + 名称 类型 描述 @@ -10282,7 +10284,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx 这个名称源于该表不应向公众开放读取,因为它包含密码。 pg_user - 是 pg_shadow 的公开可读视图,并将密码字段清空。 + 是 pg_shadow 的公开可读视图,并隐藏密码字段。 @@ -10291,7 +10293,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - Name + 名称 类型 引用 @@ -10359,7 +10361,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx passwd text - 密码(可能已加密);如果没有则为空。关于加密密码的存储方式,详见pg_authid + 密码(可能已加密);如果未设置则为空值。关于加密密码的存储方式,详见pg_authid @@ -10409,7 +10411,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - Name + 名称 类型 引用 @@ -10575,7 +10577,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - Name + 名称 类型 引用 @@ -10669,7 +10671,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - Name + 名称 类型 描述 @@ -10733,7 +10735,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - Name + 名称 类型 描述 @@ -10784,7 +10786,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx 视图pg_user提供数据库用户的信息。它本质上是 - pg_shadow 的公开可读视图,并将密码字段清空。 + pg_shadow 的公开可读视图,并隐藏密码字段。
@@ -10793,7 +10795,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - Name + 名称 类型 描述 @@ -10897,7 +10899,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - Name + 名称 类型 引用 @@ -11003,7 +11005,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - Name + 名称 类型 引用 @@ -11041,7 +11043,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx text - 视图定义(一个重构的SELECT查询) + 视图定义(一个重建的SELECT查询) diff --git a/zh/11/charset.sgml b/zh/11/charset.sgml index 9a829a10..46a1b416 100644 --- a/zh/11/charset.sgml +++ b/zh/11/charset.sgml @@ -29,7 +29,7 @@ 区域设置支持 - locale + 区域设置 区域设置支持是指应用程序在字母表、排序、数字格式等 @@ -71,7 +71,7 @@ initdb --locale=sv_SE Swedish_Sweden.1252,但原则是相同的。 - 偶尔需要混合几个区域设置的规则,例如使用英语排序规则和西班牙语消息。为此,系统提供了一组区域设置子类别,分别控制本地化规则的某些方面: LC_COLLATE 字符串排序顺序 LC_CTYPE 字符分类(什么是字母?它对应的大写形式是什么?) LC_MESSAGES 消息语言 LC_MONETARY 货币金额格式 LC_NUMERIC 数字格式 LC_TIME 日期和时间格式 这些类别名称对应于 initdb 选项的名称,可覆盖某个特定类别的区域设置选择。例如,要将区域设置设为加拿大法语,但使用美国的货币格式规则,可使用 initdb --locale=fr_CA --lc-monetary=en_US。 + 有时混合多个区域设置的规则会很有用,例如使用英语排序规则但使用西班牙语消息。为此,存在一组只控制本地化规则某些方面的区域设置子类别: LC_COLLATE 字符串排序顺序 LC_CTYPE 字符分类(什么算字母?它的大写等价形式是什么?) LC_MESSAGES 消息的语言 LC_MONETARY 货币数量使用的格式 LC_NUMERIC 数字的格式 LC_TIME 日期和时间的格式 这些类别名会转换成initdb选项名,用于覆盖特定类别的区域设置选择。例如,要将区域设置设为加拿大法语,但对货币格式采用美国规则,可以使用initdb --locale=fr_CA --lc-monetary=en_US 如果希望系统表现得像没有区域设置支持一样,可使用特殊区域设置名 @@ -115,7 +115,7 @@ initdb --locale=sv_SE 某些消息本地化库还会查看环境变量LANGUAGE,它会覆盖所有 - 其他用于设置消息语言的区域设置。如果有疑问,请参考操作系统文档,尤其是 + 其他用于设置消息的语言的区域设置。如果有疑问,请参考操作系统文档,尤其是 关于gettext的文档。 @@ -157,7 +157,7 @@ initdb --locale=sv_SE 以及 POSIX 风格正则表达式);区域设置既会影响大小写不敏感匹配,也会 影响字符类正则表达式中的字符分类 LIKE与区域设置 - regular expressions与区域设置 + 正则表达式与区域设置 @@ -246,10 +246,10 @@ initdb --locale=sv_SE 概念 - 从概念上讲,每个可排序数据类型的表达式都有一个排序规则。(内置的可排序 - 数据类型包括textvarcharchar。 - 用户定义的基本类型也可以标记为可排序,当然,建立在可排序数据类型之上的 - 域也是可排序的。) + 从概念上讲,每个支持排序规则的数据类型的表达式都有一个排序规则。 + (内置的支持排序规则的数据类型包括textvarcharchar。 + 用户定义的基础类型也可以标记为支持排序规则,当然,建立在支持排序规则的数据类型之上的 + 域也支持排序规则。) 如果表达式是列引用,则该表达式的排序规则就是该列定义的排序规则。如果表 达式是常量,则其排序规则就是该常量数据类型的默认排序规则。更复杂表达式 的排序规则则按下文所述,从其输入表达式的排序规则推导出来。 @@ -274,7 +274,7 @@ initdb --locale=sv_SE 对于函数或操作符调用,通过检查参数排序规则推导出的排序规则,会在运行时 - 用于执行指定操作。如果该函数或操作符调用的结果属于可排序数据类型,那么 + 用于执行指定操作。如果该函数或操作符调用的结果属于支持排序规则的数据类型,那么 在解析时它也会被用作该函数或操作符表达式的已定义排序规则,以便在外围表 达式需要知道其排序规则时使用。 @@ -356,7 +356,7 @@ SELECT a || b FROM test1; - 如果函数或操作符返回的是可排序数据类型,那么分配给该函数或操作符组合输 + 如果函数或操作符返回的是支持排序规则的数据类型,那么分配给该函数或操作符组合输 入表达式的排序规则,也被认为适用于其结果。因此,在 SELECT * FROM test1 ORDER BY a || 'foo'; @@ -402,8 +402,7 @@ SELECT * FROM test1 ORDER BY a || b COLLATE "fr_FR"; - 由icu提供的排序规则对象,对应于 ICU 库提供的具名整 - 理器。ICU 不支持将collatectype分开设 + 由icu提供的排序规则对象,对应于 ICU 库提供的具名排序器。ICU 不支持将collatectype分开设 置,因此二者总是相同的。此外,ICU 排序规则与编码无关,因此在一个数据库 中,某个给定名称的 ICU 排序规则始终只有一个。 @@ -492,7 +491,7 @@ SELECT a COLLATE "C" < b COLLATE "POSIX" FROM test1; -x-icu,以便与 libc 区域设置区分开来。 - 以下是可能创建的排序规则示例: + 下面是一些可能创建出来的排序规则示例: de-x-icu @@ -578,7 +577,7 @@ CREATE COLLATION german (provider = libc, locale = 'de_DE'); CREATE COLLATION "de-u-co-phonebk-x-icu" (provider = icu, locale = 'de-u-co-phonebk'); CREATE COLLATION "de-u-co-phonebk-x-icu" (provider = icu, locale = 'de@collation=phonebook'); - 采用电话簿排序类型的德语排序规则 + 德语排序规则,电话簿排序类型 第一个示例使用 BCP 47 定义的语言标签来选择 ICU 区域设置。第二个示例使用传统的 ICU 专有区域设置语法。今后应优先采用第一种形式,但较旧的 ICU 版本不支持它。 注意,可以在 SQL 环境中为排序规则对象任意命名。本例遵循预定义排序规则所采用的命名风格,该风格也遵循 BCP 47,但用户定义的排序规则并不要求如此。 @@ -588,7 +587,9 @@ CREATE COLLATION german (provider = libc, locale = 'de_DE'); CREATE COLLATION "und-u-co-emoji-x-icu" (provider = icu, locale = 'und-u-co-emoji'); CREATE COLLATION "und-u-co-emoji-x-icu" (provider = icu, locale = '@collation=emoji'); - 采用 Unicode 技术标准 #51 所定义 Emoji 排序类型的根排序规则 + + 根排序规则,表情符号排序类型,依据 Unicode 技术标准 #51 + 注意,传统的 ICU 区域设置命名系统使用空字符串来选择根区域设置。 @@ -597,7 +598,9 @@ CREATE COLLATION german (provider = libc, locale = 'de_DE'); CREATE COLLATION latinlast (provider = icu, locale = 'en-u-kr-grek-latn'); CREATE COLLATION latinlast (provider = icu, locale = 'en@colReorder=grek-latn'); - 将希腊字母排在拉丁字母之前。(默认是拉丁字母在希腊字母之前。) + + 将希腊字母排在拉丁字母之前。(默认情况下是拉丁字母排在希腊字母之前。) + @@ -605,7 +608,9 @@ CREATE COLLATION german (provider = libc, locale = 'de_DE'); CREATE COLLATION upperfirst (provider = icu, locale = 'en-u-kf-upper'); CREATE COLLATION upperfirst (provider = icu, locale = 'en@colCaseFirst=upper'); - 将大写字母排在小写字母之前。(默认是小写字母在前。) + + 将大写字母排在小写字母之前。(默认情况下是小写字母在前。) + @@ -613,7 +618,9 @@ CREATE COLLATION german (provider = libc, locale = 'de_DE'); CREATE COLLATION special (provider = icu, locale = 'en-u-kf-upper-kr-grek-latn'); CREATE COLLATION special (provider = icu, locale = 'en@colCaseFirst=upper;colReorder=grek-latn'); - 组合上述两个选项。 + + 结合了以上两个选项。 + diff --git a/zh/11/client-auth.sgml b/zh/11/client-auth.sgml index efbbbe59..09b60ad5 100644 --- a/zh/11/client-auth.sgml +++ b/zh/11/client-auth.sgml @@ -37,7 +37,14 @@ pg_hba.conf - 客户端认证由一个配置文件控制,该文件通常名为 pg_hba.conf,存储在数据库集簇的数据目录中。(HBA 表示基于主机的认证。)initdb 初始化数据目录时,会安装一个默认的 pg_hba.conf 文件。不过,也可以将认证配置文件放在其他位置;参见 配置参数。 + + 客户端认证由一个配置文件控制,该文件按惯例命名为 + pg_hba.conf,并存放在数据库集簇的数据目录中。 + (HBA 代表 host-based authentication,即基于主机的认证。) + 当数据目录由 initdb 初始化时,会安装一个默认的 + pg_hba.conf 文件。不过,也可以把认证配置文件放在别处; + 请参见配置参数 。 + pg_hba.conf 文件的基本格式是一组记录,每行一条。空行和 # 注释字符之后的所有文本都会被忽略。记录不能跨行续写。每条记录由若干字段组成,字段之间用空格和/或制表符分隔。如果字段值用双引号括起来,就可以包含空白。在数据库、用户或地址字段中,将关键字(例如 allreplication)用引号括起来,会使其失去特殊含义,只匹配同名的数据库、用户或主机。 @@ -133,7 +140,7 @@ hostnossl database user IP地址范围使用标准的数字表示法来指定起始地址,然后是斜杠(/)和一个CIDR掩码长度。 掩码长度表示客户端IP地址必须匹配的高位比特数。给定IP地址中右侧的比特应为零。 - IP地址、/和CIDR掩码长度之间不得有任何空格。 + IP地址、/和CIDR掩码长度之间不得有任何空白。 @@ -170,12 +177,12 @@ hostnossl database user 以点(.)开头的主机名规范匹配实际主机名的后缀。 因此,.example.com将匹配foo.example.com - (但不仅仅是example.com)。 + (但不匹配单独的example.com)。 当在pg_hba.conf中指定主机名时,应确保名称解析相对快速。 - 最好设置一个本地名称解析缓存,如nscd。 + 设置一个本地名称解析缓存可能会有帮助,如nscd。 此外,还可能希望启用配置参数log_hostname,以便在日志中看到客户端的主机名而不是 IP 地址。 @@ -185,7 +192,7 @@ hostnossl database user 用户有时会想知道为什么主机名以这种看似复杂的方式处理,包括两次名称解析,其中包括对客户端IP地址的反向查找。 - 如果客户端的反向DNS条目未设置或生成了一些不良的主机名,则使用该功能会变得复杂。 + 如果客户端的反向DNS条目未设置或返回了不符合预期的主机名,则使用该功能会变得复杂。 这主要是为了效率:这样,连接尝试最多需要两次解析器查找,一次反向查找和一次正向查找。 如果某个地址存在解析器问题,那就只会成为该客户端的问题。 一个假设的替代实现只进行正向查找的情况下,在每次连接尝试期间都必须解析pg_hba.conf中提到的每个主机名。 @@ -200,7 +207,7 @@ hostnossl database user 请注意,这种行为与其他流行的基于主机名的访问控制实现一致,例如 - Apache HTTP服务器和TCP包装器。 + Apache HTTP 服务器和 TCP Wrappers。 @@ -211,7 +218,7 @@ hostnossl database user IP-mask - 这两个字段可以用作IP地址/掩码长度 + 这两个字段可以用作IP-address/mask-length 表示法的替代方案。而不是指定掩码长度,实际掩码在一个单独的列中指定。 例如,255.0.0.0表示IPv4的CIDR掩码长度为8, 而255.255.255.255表示CIDR掩码长度为32。 @@ -224,7 +231,10 @@ hostnossl database user auth-method - 指定连接匹配此记录时使用的认证方法。这里概述可用的选项;详情参见 。所有选项都使用小写且区分大小写,因此即使是 ldap 这样的缩写,也必须使用小写。 + + 指定连接匹配此记录时要使用的认证方法。可选值在此处做了概述;详细说明见 。所有选项都必须使用小写并且区分大小写,因此即使是像 ldap 这样的首字母缩写也必须写成小写。 + + trust @@ -398,14 +408,14 @@ hostnossl database user 由于每次连接尝试都会按顺序检查 pg_hba.conf 记录,因此记录的顺序很重要。通常,靠前的记录使用较严格的连接匹配条件和较弱的认证方法,靠后的记录使用较宽松的匹配条件和较强的认证方法。例如,可能希望对本地 TCP/IP 连接使用 trust 认证,而要求远程 TCP/IP 连接提供密码。此时,为来自 127.0.0.1 的连接指定 trust 认证的记录,应放在为更大范围的允许客户端 IP 地址指定密码认证的记录之前。 - 在启动以及主服务器进程收到SIGHUPSIGHUP信号时,pg_hba.conf文件会被读取。 - 如果你在活动的系统上编辑了该文件,你将需要通知 postmaster(使用pg_ctl reload,调用SQL函数pg_reload_conf(),或使用kill -HUP)使其重新读取该文件。 + 在启动时以及主服务器进程收到 SIGHUPSIGHUP 信号时,pg_hba.conf 文件会被读取。 + 如果你在运行中的系统上编辑了该文件,就需要通知 postmaster(使用 pg_ctl reload、调用 SQL 函数 pg_reload_conf(),或者使用 kill -HUP)重新读取该文件。 - 前面的说明在Microsoft Windows上不为真:在Windows上,pg_hba.conf文件中的任何更改会立即被应用到后续的新连接上。 + 前面的说明不适用于 Microsoft Windows:在Windows上,pg_hba.conf文件中的任何更改会立即被应用到后续的新连接上。 @@ -425,92 +435,88 @@ hostnossl database user 示例 <filename>pg_hba.conf</filename> 项 -# Allow any user on the local system to connect to any database with -# any database user name using Unix-domain sockets (the default for local -# connections). +# 允许本地系统上的任何用户 +# 通过 Unix 域套接字(本地连接的默认方式)以任意 +# 数据库用户名连接到任意数据库。 # # TYPE DATABASE USER ADDRESS METHOD local all all trust -# The same using local loopback TCP/IP connections. +# 相同的规则,但是使用本地环回 TCP/IP 连接。 # # TYPE DATABASE USER ADDRESS METHOD host all all 127.0.0.1/32 trust -# The same as the previous line, but using a separate netmask column +# 和前一行相同,但是使用了一个独立的掩码列 # # TYPE DATABASE USER IP-ADDRESS IP-MASK METHOD host all all 127.0.0.1 255.255.255.255 trust -# The same over IPv6. +# IPv6 上相同的规则 # # TYPE DATABASE USER ADDRESS METHOD host all all ::1/128 trust -# The same using a host name (would typically cover both IPv4 and IPv6). +# 使用主机名的相同规则(通常同时覆盖 IPv4 和 IPv6)。 # # TYPE DATABASE USER ADDRESS METHOD host all all localhost trust -# Allow any user from any host with IP address 192.168.93.x to connect -# to database "postgres" as the same user name that ident reports for -# the connection (typically the operating system user name). +# 允许来自任意具有 IP 地址192.168.93.x 的主机上任意 +# 用户以 ident 为该连接所报告的相同用户名连接到 +# 数据库 "postgres"(通常是操作系统用户名)。 # # TYPE DATABASE USER ADDRESS METHOD host postgres all 192.168.93.0/24 ident -# Allow any user from host 192.168.12.10 to connect to database -# "postgres" if the user's password is correctly supplied. +# 如果用户的密码被正确提供,允许来自主机 192.168.12.10 +# 的任意用户连接到数据库 "postgres"。 # # TYPE DATABASE USER ADDRESS METHOD host postgres all 192.168.12.10/32 scram-sha-256 -# Allow any user from hosts in the example.com domain to connect to -# any database if the user's password is correctly supplied. +# 如果用户的密码被正确提供,允许 example.com 域中主机上 +# 的任意用户连接到任意数据库。 # -# Require SCRAM authentication for most users, but make an exception -# for user 'mike', who uses an older client that doesn't support SCRAM -# authentication. +# 为大部分用户要求SCRAM认证,但是用户'mike'是个例外, +# 他使用的是不支持SCRAM认证的旧客户端。 # # TYPE DATABASE USER ADDRESS METHOD host all mike .example.com md5 host all all .example.com scram-sha-256 -# In the absence of preceding "host" lines, these two lines will -# reject all connections from 192.168.54.1 (since that entry will be -# matched first), but allow GSSAPI connections from anywhere else -# on the Internet. The zero mask causes no bits of the host IP -# address to be considered, so it matches any host. +# 如果没有前面的 "host" 行,这两行将拒绝所有来自 192.168.54.1 的 +# 连接(因为该条目会先被匹配),但允许来自互联网其他任何位置的 +# GSSAPI 连接。零掩码表示不考虑主机 IP 地址中的任何位, +# 因而会匹配任意主机。 # # TYPE DATABASE USER ADDRESS METHOD host all all 192.168.54.1/32 reject host all all 0.0.0.0/0 gss -# Allow users from 192.168.x.x hosts to connect to any database, if -# they pass the ident check. If, for example, ident says the user is -# "bryanh" and he requests to connect as PostgreSQL user "guest1", the -# connection is allowed if there is an entry in pg_ident.conf for map -# "omicron" that says "bryanh" is allowed to connect as "guest1". +# 允许来自 192.168.x.x 主机的用户连接到任意数据库,如果它们能够 +# 通过 ident 检查。例如,假设 ident说用户是 "bryanh" 并且他要求以 +# PostgreSQL 用户 "guest1" 连接,如果在 pg_ident.conf 有一个映射 +# "omicron" 的条目表明 "bryanh" 被允许以 "guest1" 连接,则该连接将被允许。 # # TYPE DATABASE USER ADDRESS METHOD host all all 192.168.0.0/16 ident map=omicron -# If these are the only three lines for local connections, they will -# allow local users to connect only to their own databases (databases -# with the same name as their database user name) except for administrators -# and members of role "support", who can connect to all databases. The file -# $PGDATA/admins contains a list of names of administrators. Passwords -# are required in all cases. +# 如果这些是本地连接的唯一三行,它们将允许本地用户只连接到 +# 自己的数据库(与其数据库用户名同名的数据库),但管理员和 +# 角色 "support" 的成员除外,他们可以连接到所有数据库。 +# 文件 $PGDATA/admins 包含管理员名称列表。 +# 所有情况下都要求提供密码。 # # TYPE DATABASE USER ADDRESS METHOD local sameuser all md5 local all @admins md5 local all +support md5 -# The last two lines above can be combined into a single line: +# 上面的最后两行可以被整合为一行: local all @admins,+support md5 -# The database column can also use lists and file names: +# 数据库列也可以用列表和文件名: local db1,db2,@demodbs all md5 @@ -634,7 +640,7 @@ omicron bryanh guest1 - Peer 认证通常适用于本地连接,不过在某些情况下,信任认证也可能已经足够。 + 通常建议对本地连接使用 Peer 认证,不过在某些情况下,信任认证也可能已经足够。 密码认证是远程连接最容易采用的选择。 其余所有选项都需要某种外部安全基础设施(通常是认证服务器,或用于签发 SSL 证书的证书颁发机构),或者属于平台特定功能。 @@ -653,16 +659,14 @@ omicron bryanh guest1 - trust认证对于单用户工作站的本地连接是非常合适和方便的。通常它本身适用于一台多用户机器。不过,只要你利用文件系统权限限制了对服务器的 Unix 域套接字文件的访问,即使在多用户机器上,你也可以使用trust。 要做这些限制,你可以设置中描述的unix_socket_permissions配置参数(可能还有unix_socket_group)。 或者你可以设置unix_socket_directories配置参数来把 Unix 域套接字文件放在一个经过恰当限制的目录中。 + trust认证对于单用户工作站的本地连接是非常合适和方便的。通常它本身适用于一台多用户机器。不过,只要你利用文件系统权限限制了对服务器的 Unix 域套接字文件的访问,即使在多用户机器上,你也可能可以使用trust。 要做这些限制,你可以设置中描述的unix_socket_permissions配置参数(可能还有unix_socket_group)。 或者你可以设置unix_socket_directories配置参数来把 Unix 域套接字文件放在一个经过恰当限制的目录中。 设置文件系统权限只能有助于 Unix 套接字连接。本地 TCP/IP 连接不会被文件系统权限限制。因此,如果你想利用文件系统权限来控制本地安全,那么从pg_hba.conf中移除host ... 127.0.0.1 ...行,或者把它改为一个非trust认证方法。 - - 如果通过指定trustpg_hba.conf行让你信任每一个被允许连接到服务器的机器上的用户,trust认证只适合 TCP/IP 连接。为任何不是来自localhost(127.0.0.1)的 TCP/IP 连接使用trust很少是合理的。 - + 只有当你信任由 pg_hba.conf 中指定 trust 的行所允许连接的每台机器上的每个用户时,trust 认证才适合用于 TCP/IP 连接。对来自 localhost(127.0.0.1)以外的任何 TCP/IP 连接使用 trust,通常都不合理。 @@ -703,11 +707,9 @@ omicron bryanh guest1 md5 - - 方法md5使用一种自定义的安全性较低的挑战-响应机制。它能防止密码嗅探并且防止密码在服务器上以明文存储,但是无法保护攻击者想办法从服务器上窃取了密码哈希的情况。此外,现在认为MD5哈希算法对于确定攻击已经不再安全。 - + 方法md5使用一种自定义的、安全性较低的挑战-响应机制。它能防止密码嗅探,并避免在服务器上以明文存储密码;但如果攻击者设法从服务器上窃取了密码哈希,它就无法提供保护。此外,如今已不再认为 MD5 哈希算法能抵御有决心的攻击者。 - md5 方法不能与 功能一起使用。 + md5方法不能与功能一起使用。 为了简化从md5方法到较新的SCRAM方法的转变,如果在pg_hba.conf中指定了md5但是用户在服务器上的密码是为SCRAM(见下文)加密的,则将自动选择基于SCRAM的认证。 @@ -735,7 +737,7 @@ omicron bryanh guest1 - 要把现有安装从 md5 升级到 scram-sha-256,需要先确保所有正在使用的客户端库都足够新并支持 SCRAM,然后在 postgresql.conf 中设置 password_encryption = 'scram-sha-256',要求所有用户重新设置密码,并将 pg_hba.conf 中的认证方法说明改为 scram-sha-256。 + 要把现有安装从 md5 升级到 scram-sha-256,需要先确保所有正在使用的客户端库都足够新并支持 SCRAM,然后在 postgresql.conf 中设置 password_encryption = 'scram-sha-256',要求所有用户重新设置密码,并将 pg_hba.conf 中的认证方法设置改为 scram-sha-256 @@ -753,11 +755,11 @@ omicron bryanh guest1 GSSAPI 使用 Kerberos 时,采用格式为 servicename/hostname@realm 的标准主体。PostgreSQL 服务器会接受其所用 keytab 中包含的任何主体,但客户端建立连接时,必须注意通过 krbsrvname 连接参数指定正确的主体信息。(另见 。)构建时可以使用 ./configure --with-krb-srvnam=whatever,将安装默认值从 postgres 改为其他值。在大多数环境中,无需更改此参数。某些 Kerberos 实现可能要求不同的服务名,例如 Microsoft Active Directory 要求服务名使用大写(POSTGRES)。 - hostname 是服务器机器的完全限定主机名。服务主体的域是服务器机器的首选域。 + hostname 是服务器机器的完全限定主机名。服务主体的 realm 是服务器机器的首选 realm。 可以通过 pg_ident.conf 将客户端主体映射到不同的 PostgreSQL 数据库用户名。例如,可以将 pgusername@realm 映射为 pgusername。也可以不使用任何映射,直接将完整的 username@realm 主体用作 PostgreSQL 中的角色名。 - PostgreSQL 还支持一个从主体中去掉域的参数。提供这种方法是为了向后兼容,强烈不建议使用,因为这样就无法区分来自不同域但用户名相同的用户。要启用此行为,将 include_realm 设为 0。对于简单的单域安装环境,如果同时设置 krb_realm 参数(它会检查主体的域是否与 krb_realm 参数值完全一致),这种做法仍是安全的;但与在 pg_ident.conf 中指定显式映射相比,它的能力较弱。 + PostgreSQL 还支持一个从主体中去掉 realm 的参数。提供这种方法是为了向后兼容,强烈不建议使用,因为这样就无法区分来自不同 realm 但用户名相同的用户。要启用此行为,将 include_realm 设为 0。对于简单的单 realm 安装环境,如果同时设置 krb_realm 参数(它会检查主体的 realm 是否与 krb_realm 参数值完全一致),这种做法仍是安全的;但与在 pg_ident.conf 中指定显式映射相比,它的能力较弱。 确保 PostgreSQL 服务器账户能够读取服务器的 keytab 文件(最好只能读取,不能写入)。(另见 。)密钥文件的位置由 配置参数指定。默认位置是 /usr/local/pgsql/etc/krb5.keytab(或者构建时用 sysconfdir 指定的目录)。出于安全考虑,建议为 PostgreSQL 服务器使用专用 keytab,而不是放宽系统 keytab 文件的权限。 keytab 文件由 Kerberos 软件生成;详情参见 Kerberos 文档。以下示例适用于兼容 MIT 的 Kerberos 5 实现: @@ -820,7 +822,8 @@ omicron bryanh guest1 当使用Kerberos认证时,SSPIGSSAPI的工作方式相同,详见 - 以下配置选项适用于 SSPI: + + SSPI 支持下列配置选项: @@ -839,7 +842,7 @@ omicron bryanh guest1 如果设为 1,则会在 include_realm 选项中使用域的 SAM 兼容名称(也称为 NetBIOS 名称)。这是默认值。如果设为 0,则会使用 Kerberos 用户主体名中的真实 realm 名称。 - 不要禁用这个选项,除非你的服务器运行在一个域账号(这包括一个域成员系统上的虚拟服务账号)下并且所有通过 SSPI 认证的所有客户端也在使用域账号,否则认证将会失败。 + 不要禁用这个选项,除非你的服务器运行在一个域账号(这包括一个域成员系统上的虚拟服务账号)下并且所有通过 SSPI 认证的客户端也在使用域账号,否则认证将会失败。 @@ -859,7 +862,10 @@ omicron bryanh guest1 map - 允许在系统用户名与数据库用户名之间建立映射。详见 。对于 username@EXAMPLE.COM(或较少见的 username/hostbased@EXAMPLE.COM)这样的 SSPI/Kerberos 主体,映射所用的用户名是 username@EXAMPLE.COM(或相应的 username/hostbased@EXAMPLE.COM),除非将 include_realm 设为 0,此时映射所见的系统用户名为 username(或 username/hostbased)。 + + 允许在系统用户名和数据库用户名之间进行映射。详见 。 + 对于 SSPI/Kerberos 主体,例如 username@EXAMPLE.COM(或者较少见的 username/hostbased@EXAMPLE.COM),用于映射的用户名分别是 username@EXAMPLE.COM(或 username/hostbased@EXAMPLE.COM),除非已经将 include_realm 设为 0;在那种情况下,映射时视为系统用户名的是 username(或 username/hostbased)。 + @@ -899,7 +905,7 @@ omicron bryanh guest1 map - 允许在系统用户和数据库用户名称之间进行映射。详细信息请参见。 + 允许在系统用户名和数据库用户名之间进行映射。详见 @@ -913,7 +919,7 @@ omicron bryanh guest1
RFC 1413 - 标识协议的本意不是作为一种认证或访问控制协议。 + 标识协议的本意不是作为一种授权或访问控制协议。
@@ -940,7 +946,7 @@ omicron bryanh guest1 map - 允许在系统用户和数据库用户名称之间进行映射。详细信息请参见。 + 允许在系统用户名和数据库用户名之间进行映射。详见 @@ -960,17 +966,21 @@ omicron bryanh guest1 LDAP - 这种认证方法与 password 类似,只是使用 LDAP 验证密码。LDAP 仅用于验证用户名与密码的组合。因此,必须先在数据库中创建该用户,才能使用 LDAP 进行认证。 + + 这种认证方法的工作方式与 password 类似,只不过它使用 LDAP 作为密码验证方法。LDAP 只用于验证用户名/密码对。因此,在使用 LDAP 进行认证之前,用户必须已经存在于数据库中。 + LDAP 认证可以在两种模式下工作。第一种模式称为简单绑定模式,服务器会绑定到按 prefix username suffix 形式构造出的可分辨名称。通常,prefix 参数用于指定 cn=,或在 Active Directory 环境中指定 DOMAIN\suffix 则用于指定非 Active Directory 环境中 DN 的剩余部分。 - 第二种模式称为搜索+绑定模式,服务器首先使用由 ldapbinddnldapbindpasswd 指定的固定用户名和密码绑定到 LDAP 目录,并搜索试图登录数据库的用户。如果没有配置用户名和密码,则会尝试对目录进行匿名绑定。搜索会在 ldapbasedn 指定的子树上进行,并尝试对 ldapsearchattribute 指定的属性做精确匹配。一旦在搜索中找到了该用户,服务器就会作为该用户重新绑定到目录,并使用客户端指定的密码来验证登录是否正确。这种模式与 Apache mod_authnz_ldappam_ldap 等软件中的 LDAP 认证方案相同。这种方法使目录中用户对象的位置更具灵活性,但会对 LDAP 服务器额外发起两次请求。 + 第二种模式称为搜索+绑定模式,服务器首先使用由 ldapbinddnldapbindpasswd 指定的固定用户名和密码绑定到 LDAP 目录,并搜索试图登录数据库的用户。如果没有配置用户名和密码,则会尝试对目录进行匿名绑定。搜索会在 ldapbasedn 指定的子树上进行,并尝试对 ldapsearchattribute 指定的属性做精确匹配。一旦在搜索中找到了该用户,服务器会断开连接,再作为该用户重新绑定到目录,并使用客户端指定的密码来验证登录是否正确。这种模式与 Apache mod_authnz_ldappam_ldap 等软件中的 LDAP 认证方案相同。这种方法使目录中用户对象的位置更具灵活性,但会与 LDAP 服务器建立两个独立的连接。 - 以下配置选项适用于两种模式: + + 以下配置选项在两种模式下都使用: + ldapserver @@ -991,8 +1001,7 @@ omicron bryanh guest1 ldapscheme - 设置为ldaps以使用LDAPS。这是一种非标准的使用LDAP - 进行SSL加密的方式,受一些LDAP服务器实现支持。另请参阅ldaptls + 设置为ldaps以使用LDAPS。这是一种非标准的通过 SSL 使用 LDAP 的方式,受一些LDAP服务器实现支持。另请参阅ldaptls 选项作为替代。 @@ -1010,7 +1019,9 @@ omicron bryanh guest1 注意使用ldapschemeldaptls仅会加密PostgreSQL 服务器和LDAP服务器之间的通信。PostgreSQL 服务器和PostgreSQL客户端之间的连接仍是未加密的,除非也在其上使用SSL。 - 以下选项仅适用于简单绑定模式: + + 下列选项只被用于简单绑定模式: + ldapprefix @@ -1030,7 +1041,9 @@ omicron bryanh guest1 - 以下选项仅适用于搜索加绑定模式: + + 以下选项仅在搜索+绑定模式中使用: + ldapbasedn @@ -1093,26 +1106,37 @@ ldap[s]://host[:port]/ - 将简单绑定的配置选项与搜索加绑定的选项混用会导致错误。 + + 将简单绑定模式的配置选项与搜索+绑定模式的配置选项混用是错误的。 + 在使用搜索+绑定模式时,可以使用由 ldapsearchattribute 指定的单个属性执行搜索,也可以使用由 ldapsearchfilter 指定的自定义搜索过滤器执行搜索。指定 ldapsearchattribute=foo 等价于指定 ldapsearchfilter="(foo=$username)"。如果两个选项都未指定,则默认使用 ldapsearchattribute=uid - 下面是 LDAP 简单绑定配置的示例: + + 下面是一个简单绑定 LDAP 配置示例: + host ... ldap ldapserver=ldap.example.net ldapprefix="cn=" ldapsuffix=", dc=example, dc=net" -当请求以数据库用户 someuser 的身份连接数据库服务器时,PostgreSQL 会尝试使用 DN cn=someuser, dc=example, - dc=net 和客户端提供的密码绑定到 LDAP 服务器。如果连接成功,就会授予数据库访问权限。 + + 当请求以数据库用户 someuser 连接数据库服务器时,PostgreSQL 将尝试使用 DN cn=someuser, dc=example, dc=net 和客户端提供的密码绑定到 LDAP 服务器。如果该连接成功,数据库访问就会被授予。 + 下面是搜索加绑定配置的示例: host ... ldap ldapserver=ldap.example.net ldapbasedn="dc=example, dc=net" ldapsearchattribute=uid 当请求以数据库用户 someuser 的身份连接数据库服务器时,PostgreSQL 会尝试匿名绑定到 LDAP 服务器(因为没有指定 ldapbinddn),并在指定的基础 DN 下搜索 (uid=someuser)。如果找到了条目,就会尝试使用找到的信息和客户端提供的密码进行绑定。如果第二次连接成功,就会授予数据库访问权限。 - 下面是用 URL 表示的相同搜索加绑定配置: + + 下面是以 URL 形式写出的同一个搜索+绑定配置: + host ... ldap ldapurl="ldap://ldap.example.net/dc=example,dc=net?uid?sub" -一些支持 LDAP 认证的其他软件也使用相同的 URL 格式,因此更容易共享配置。 + + 某些支持 LDAP 认证的其他软件也使用相同的 URL 格式,因此共享这类配置会更容易。 + - 下面是搜索加绑定配置的示例,使用 ldapsearchfilter 代替 ldapsearchattribute,以便通过用户 ID 或电子邮件地址进行认证: + + 这里是一个搜索+绑定配置的示例,它使用 ldapsearchfilter 而不是 ldapsearchattribute 来允许用用户 ID 或电子邮件地址进行认证: + host ... ldap ldapserver=ldap.example.net ldapbasedn="dc=example, dc=net" ldapsearchfilter="(|(uid=$username)(mail=$username))" @@ -1336,7 +1360,7 @@ FATAL: user "andym" does not exist FATAL: database "testdb" does not exist - 你试图连接的数据库不存在。注意,如果你没有指定数据库名,默认会使用数据库用户名作为数据库名。 + 你试图连接的数据库不存在。注意,如果你没有指定数据库名,默认会使用数据库用户名作为数据库名,但这不一定是所需的数据库名。 diff --git a/zh/11/config.sgml b/zh/11/config.sgml index 940adbcc..8537d74b 100644 --- a/zh/11/config.sgml +++ b/zh/11/config.sgml @@ -17,6 +17,7 @@ 设置参数 + 参数名称和值 @@ -43,14 +44,17 @@ + 字符串: 通常值被包括在单引号内,值内部的任何单引号都需要被双写。不过,如果值是一个简单数字或者 标识符,引号通常可以被省略。 + + 数字(整数和浮点数): 只有浮点数参数才允许使用小数点。不要使用千位分隔符。不要求使用引号。 @@ -58,8 +62,16 @@ + - 带单位的数字:某些数值参数具有隐含单位,因为它们描述的是内存量或时间量。单位可能是字节、千字节、块(通常为八千字节)、毫秒、秒或分钟。不带修饰的数值会使用该设置的默认单位,可通过pg_settings.unit获知该单位。为方便起见,可以显式指定设置的单位,例如用'120 ms'表示时间值,系统会将它转换为参数的实际单位。注意,使用此功能时必须把值写成字符串(加引号)。单位名称区分大小写,数值和单位之间可以有空白。 + 带单位的数字: + 一些数字参数具有隐含单位,因为它们描述的是内存或时间量。单位可能是字节、千字节、块 + (通常为 8 千字节)、毫秒、秒或分钟。这类设置若给出不带单位的数字值,就会使用该设置的默认单位, + 可以通过 pg_settings.unit 了解该默认单位。为了方便, + 也可以显式指定单位,例如把时间值写成 '120 ms',系统会将其转换为该参数的实际单位。 + 注意,要使用这一特性,值必须写成字符串(带引号)。单位名称区分大小写,并且数字值与单位之间可以有空白。 + + 可用的内存单位是 B(字节)、kB(千字节)、 @@ -77,7 +89,8 @@ - + + @@ -92,15 +105,25 @@ + 通过配置文件影响参数 - 设置这些参数最基本的方法是编辑文件postgresql.confpostgresql.conf,该文件通常保存在数据目录中。初始化数据库集簇目录时会安装一份默认副本。该文件可能如下所示: + + 设置这些参数最基本的方法是编辑文件 + postgresql.confpostgresql.conf, + 它通常位于数据目录中。在数据库集簇目录初始化时,会安装该文件的一个默认副本。其内容示例如下: + # This is a comment log_connections = yes log_destination = 'syslog' search_path = '"$user", public' shared_buffers = 128MB -每行指定一个参数。名称与值之间的等号可以省略。空白没有特殊意义(引号内的参数值除外),空行会被忽略。井号(#)将该行的剩余部分标记为注释。不是简单标识符或数字的参数值必须用单引号括起。要在参数值中嵌入单引号,可以写两个单引号(推荐)或反斜线加单引号。如果文件中包含同一参数的多个条目,则只采用最后一个,忽略其余条目。 + + 每行指定一个参数。名称和值之间的等号是可选的。空白不重要(引号括起的参数值内部除外),空行会被忽略。 + 井号(#)表示该行余下部分是注释。不是简单标识符或数字的参数值必须用单引号括起。 + 要在参数值中嵌入单引号,可以写两个单引号(推荐)或使用反斜线转义单引号。 + 如果文件包含相同参数的多个条目,则忽略除最后一个之外的所有条目。 + 以这种方式设定的参数为集簇提供了默认值。除非这些设置被覆盖,活动会话看到的就是这些设置。 @@ -145,7 +168,8 @@ shared_buffers = 128MB - 通过 SQL 影响参数 + + 通过SQL影响参数 PostgreSQL提供了三个SQL命令来建立配置默认值。 @@ -156,14 +180,16 @@ shared_buffers = 128MB + - 命令允许针对一个数据库覆盖其全局设置。 + 命令允许针对各个数据库覆盖全局设置。 + - 命令允许用用户指定的值来覆盖全局设置和数据库设置。 + 命令允许用针对特定用户设置的值来覆盖全局设置和数据库设置。 @@ -182,16 +208,16 @@ shared_buffers = 128MB + - 命令允许察看所有参数的当前值。对应的函数是 - current_setting(setting_name text)。 + 命令允许查看所有参数的当前值。对应的函数为 current_setting(setting_name text) + - 那些可以在会话本地设置的参数,允许通过命令修改当前会话的参数值;它对其他会话没有影响。 - 相应的函数是set_config(setting_name, new_value, is_local)。 + 命令允许修改可在会话本地设置的参数的当前值;它对其他会话没有影响。对应的函数为 set_config(setting_name, new_value, is_local) @@ -212,9 +238,15 @@ shared_buffers = 128MB - 使用作用于此视图,具体来说就是更新其setting列,就等同于发出SET命令。例如,下述命令: + + + 在这个视图上使用并且指定更新setting + 列,其效果等同于发出SET命令。例如,下面的命令 + SET configuration_parameter TO DEFAULT; -等同于: + + 等效于: + UPDATE pg_settings SET setting = reset_val WHERE name = 'configuration_parameter'; @@ -224,23 +256,38 @@ UPDATE pg_settings SET setting = reset_val WHERE name = 'configuration_parameter + 通过 Shell 影响参数 - 除了在数据库或者角色层面上设置全局默认值或者进行覆盖,你还可以通过 shell 工具把设置 + 除了设置全局默认值或在数据库、角色级别覆盖默认值之外,你还可以通过 shell 工具把设置 传递给PostgreSQL。服务器和libpq 客户端库都能通过 shell 接受参数值。 - 在服务器启动期间,可以通过postgres命令的命令行参数传递参数设置。例如: + + + 在服务器启动期间,可以通过命令行参数把参数设置传递给 + postgres命令。例如: + postgres -c log_connections=yes -c log_destination='syslog' -以这种方式提供的设置会覆盖通过postgresql.confALTER SYSTEM进行的设置,因此不重启服务器就无法全局更改它们。 + + 这种方式提供的设置会覆盖通过postgresql.conf或者 + ALTER SYSTEM提供的设置,因此除了重启服务器之外无法从全局上改变它们。 + - 通过libpq启动客户端会话时,可以用PGOPTIONS环境变量指定参数设置。以这种方式建立的设置成为会话整个生命周期内的默认值,但不影响其他会话。出于历史原因,PGOPTIONS的格式与启动postgres命令时使用的格式相似;具体而言,必须指定标志。例如: + + + 当通过libpq启动一个客户端会话时,可以使用PGOPTIONS + 环境变量指定参数设置。这种方式建立的设置构成了会话生存期间的默认值,但是不会影响 + 其他的会话。由于历史原因,PGOPTIONS的格式和启动 + postgres命令时用到的相似,特别是标志必须被指定。 + 例如: + env PGOPTIONS="-c geqo=off -c statement_timeout=5min" psql @@ -285,7 +332,7 @@ include 'filename' 还有一个 include_if_exists 指令,其行为与 include 相同, 但在被引用文件不存在或无法读取时有所不同。普通的 include 会将其视为错误, - 而 include_if_exists 只会记录一条消息并继续处理引用配置文件。 + 而 include_if_exists 只会记录一条消息并继续处理引用它的配置文件。 @@ -296,21 +343,21 @@ include 'filename' postgresql.conf 文件也可以包含 include_dir 指令, 用来指定一个应被包含的配置文件目录。其用法如下: - include_dir 'directory' - - 非绝对目录名会被解释为相对于引用配置文件所在目录的路径。在指定目录中, +include_dir 'directory' + + 非绝对目录名会被解释为相对于引用它的配置文件所在目录的路径。在指定目录中, 只有名称以 .conf 结尾的非目录文件才会被包含。以 . 开头的文件名也会被忽略,以避免在某些平台上误处理隐藏文件。包含目录中的多个文件会按文件名顺序处理 (依据 C 区域规则排序,即数字在字母之前,大写字母在小写字母之前)。 - 包括文件或目录可以被用来在逻辑上分隔数据库配置的各个部分,而不是用一个很大的postgresql.conf文件。 + 包含文件或目录可以用来在逻辑上分隔数据库配置的各个部分,而不是用一个很大的postgresql.conf文件。 考虑一个有两台数据库服务器的公司,每一个都有不同的内存量。 - 很可能配置的元素都会被共享,例如用于日志的参数。但是两者关于内存的参数将会不同。 + 两者很可能会共享部分配置,例如日志设置。但是两者关于内存的参数将会不同。 并且还可能会有服务器相关的自定义。 一种管理这类情况的方法是将你的站点的自定义配置修改分成三个文件。 - 你可以把下面的内容加入到你的postgresql.conf文件末尾来包括它们: + 你可以把下面的内容加入到你的postgresql.conf文件末尾来包含它们: include 'shared.conf' include 'memory.conf' @@ -371,7 +418,7 @@ include_dir 'conf.d' - 指定用于数据存储的目录。这个选项只能在服务器启动时设置。 + 指定用于数据存储的目录。这个参数只能在服务器启动时设置。 @@ -431,7 +478,7 @@ include_dir 'conf.d' - 指定可被服务器创建的用于管理程序的额外进程 ID(PID)文件。这个参数只能在服务器启动的时候设置。 + 指定服务器应创建的额外进程 ID(PID)文件的名称,供服务器管理程序使用。这个参数只能在服务器启动的时候设置。 @@ -442,15 +489,15 @@ include_dir 'conf.d' - 如果你想把配置文件放在别的地方而不是数据目录中,那么postgres 命令行选项或者环境变量PGDATA必须指向包含配置文件的目录,并且postgresql.conf中(或者命令行上)的data_directory参数必须显示数据目录实际存放的地方。请注意,data_directory将覆盖PGDATA指定的数据目录位置,但是不覆盖配置文件的位置。 + 如果你想把配置文件放在别的地方而不是数据目录中,那么postgres 命令行选项或者环境变量PGDATA必须指向包含配置文件的目录,并且postgresql.conf中(或者命令行上)的data_directory参数必须设置为数据目录的实际位置。请注意,data_directory将覆盖PGDATA指定的数据目录位置,但是不覆盖配置文件的位置。 - 如果你愿意,可以使用选项config_filehba_file和/或ident_file单独指定配置文件名称和位置。config_file只能在postgres命令行上指定,但是其他文件可以在主配置文件中设置。如果所有三个参数外加data_directory被显式地设置,则不必指定PGDATA。 + 如果你愿意,可以使用选项config_filehba_file和/或ident_file单独指定配置文件名称和位置。config_file只能在postgres命令行上指定,但是其他参数可以在主配置文件中设置。如果所有三个参数外加data_directory被显式地设置,则不必指定PGDATA - 在设置任何这些参数时,相对路径将被解释为相对于postgres启动路径的路径。 + 在设置任何这些参数时,相对路径将被解释为相对于启动 postgres 时所在目录的路径。 @@ -472,7 +519,7 @@ include_dir 'conf.d' - 指定服务器用于监听来自客户端应用程序的连接的TCP/IP地址(指服务器网卡IP地址)。 + 指定服务器用于监听来自客户端应用程序的连接的TCP/IP地址。 该值采用逗号分隔的主机名和/或数字IP地址的形式。特殊条目*对应于所有可用的IP接口。 条目0.0.0.0允许监听所有IPv4地址,::允许监听所有IPv6地址。 如果列表为空,则服务器不会在任何IP接口上监听,此时只能使用Unix域套接字进行连接。 @@ -495,11 +542,11 @@ include_dir 'conf.d' - - - 服务器监听的 TCP 端口;默认是 5432 。请注意服务器会同一个端口号监听所有的 IP 地址。这个参数只能在服务器启动时设置。 - - + + 服务器监听的 TCP 端口,默认是 5432。请注意,服务器监听的所有 IP 地址都使用同一个端口号。 + 此参数只能在服务器启动时设置。 + + @@ -596,26 +643,19 @@ include_dir 'conf.d' - 设置 Unix 域套接字的访问权限。Unix 域套接字使用普通的 Unix 文件系统权限集。这个参数值应该是数字的形式,也就是系统调用chmodumask接受的 形式(如果使用自定义的八进制格式,数字必须以一个0(零)开头)。 + 设置 Unix 域套接字的访问权限。Unix 域套接字使用通常的 Unix 文件系统权限集。参数值应是以 chmodumask 系统调用所接受格式指定的数字权限模式。(要使用惯用的八进制格式,数字必须以 0(零)开头。) - - 默认的权限是0777,意思是任何人都可以连接。合理的候选是0770(只有用户和同组的人可以访问, 又见unix_socket_group)和0700(只有用户自己可以访问)(请注意,对于 Unix 域套接字,只有写权限有麻烦,因此没有对读取和执行权限的设置和收回)。 + 默认权限是 0777,表示任何人都可以连接。合理的其他取值包括 0770(仅属主和所属组,另见 unix_socket_group)和 0700(仅属主)。(注意,对 Unix 域套接字而言,只有写权限起作用,因此设置或撤销读权限和执行权限没有意义。) - - 这个访问控制机制与中的用户认证没有关系。 + 此访问控制机制独立于 中描述的机制。 - - 这个参数只能在服务器启动时设置。 + 此参数只能在服务器启动时设置。 - - 这个参数与完全忽略套接字权限的系统无关,尤其是自版本10以上的Solaris。 - 在那些系统上,可以通过把unix_socket_directories指向一个把搜索权限 - 限制给指定用户的目录来实现相似的效果。 - Windows 没有 Unix 域套接字,因此此参数在 Windows 上也没有意义。 + 此参数对完全忽略套接字权限的系统无效,尤其是 Solaris(截至 Solaris 10)。在这些系统上,可以将 unix_socket_directories 指向一个仅向目标用户授予搜索权限的目录,以达到类似效果。Windows 没有 Unix 域套接字,因此此参数在 Windows 上也没有意义。 @@ -628,10 +668,8 @@ include_dir 'conf.d' - - 通过Bonjour广告服务器的存在。默认值是关闭。 - 这个参数只能在服务器启动时设置。 + 启用通过 Bonjour 通告服务器存在的功能。默认值为关闭。此参数只能在服务器启动时设置。 @@ -644,11 +682,11 @@ include_dir 'conf.d' - - - 指定Bonjour服务名称。空字符串''(默认值)表示使用计算机名。 如果编译时没有打开Bonjour支持那么将忽略这个参数。这个参数只能在服务器启动时设置。 - - + + 指定 Bonjour 服务名。空字符串 ''(默认值)表示使用计算机名。 + 如果编译时未启用 Bonjour 支持,则此参数会被忽略。此参数只能在服务器启动时设置。 + + @@ -786,6 +824,7 @@ include_dir 'conf.d' + db_user_namespace (boolean) @@ -822,14 +861,14 @@ include_dir 'conf.d' - + SSL - 查看以获取有关设置SSL的更多信息。 + 关于 SSL 的设置,参见 @@ -965,7 +1004,7 @@ include_dir 'conf.d' - 可用的密码组细节可能会随着OpenSSL 版本变化。 + 可用的密码套件细节可能会随着OpenSSL 版本变化。 可使用命令 openssl ciphers -v 'HIGH:MEDIUM:+3DES:!aNULL'来查看当前安装的OpenSSL版本的实际细节。 注意这个列表是根据服务器密钥类型在运行时过滤过的。 @@ -980,17 +1019,16 @@ include_dir 'conf.d' - 指定是否使用服务器的 SSL 密码首选项,而不是用客户端的。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 - 默认值是 true。 + 指定是否使用服务器的 SSL 密码套件优先顺序,而非客户端的优先顺序。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。默认值为 true - - 老的PostgreSQL版本没有这个设置并且总是使用客户端的首选项。这个设置主要用于与那些版本 - 的向后兼容性。使用服务器的首选项通常会更好,因为服务器更可能会被合适地配置。 + 旧版 PostgreSQL没有此设置,始终采用客户端的优先顺序。此设置主要用于与这些旧版本保持向后兼容。采用服务器的优先顺序通常更好,因为服务器更可能得到适当配置。 + + ssl_ecdh_curve (string) @@ -999,19 +1037,10 @@ include_dir 'conf.d' - 指定在 ECDH 密钥交换中使用的曲线名称。它需要被所有连接的客户端支持。 - 不必与服务器椭圆曲线密钥所使用的曲线相同。 - 该参数只能在postgresql.conf文件中或服务器命令行上设置。 - 默认值为prime256v1。 + 指定在 ECDH 密钥交换中使用的曲线名称。所有连接的客户端都必须支持该曲线。它不必与服务器椭圆曲线密钥使用的曲线相同。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。默认值为 prime256v1 - - OpenSSL最常见的曲线名称是: - prime256v1 (NIST P-256)、 - secp384r1 (NIST P-384)、 - secp521r1 (NIST P-521)。 - openssl ecparam -list_curves 命令可以显示可用曲线的完整列表, - 但并非所有曲线都可用于 TLS。 + OpenSSL 中最常见的曲线名称为:prime256v1(NIST P-256)、secp384r1(NIST P-384)、secp521r1(NIST P-521)。可以用 openssl ecparam -list_curves 命令显示可用曲线的完整列表,但其中并非所有曲线都能用于 TLS @@ -1024,13 +1053,11 @@ include_dir 'conf.d' - - 指定含有用于SSL密码的所谓临时DH家族的Diffie-Hellman参数的文件名。默认值为空,这种情况下将使用内置的默认DH参数。使用自定义的DH参数可以降低攻击者破解众所周知的内置DH参数的风险。可以用命令openssl dhparam -out dhparams.pem 2048创建自己的DH参数文件。 + 指定包含 Diffie-Hellman 参数的文件名,这些参数用于所谓临时 DH 系列的 SSL 密码套件。默认值为空,此时使用编译时内置的默认 DH 参数。如果攻击者破解了众所周知的内置 DH 参数,使用自定义 DH 参数可以降低由此带来的风险。可以用命令 openssl dhparam -out dhparams.pem 2048 创建自己的 DH 参数文件。 - - 这个参数只能在postgresql.conf文件中或通过服务器命令行进行设置。 + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 @@ -1043,21 +1070,17 @@ include_dir 'conf.d' - - 设置当需要一个密码(例如一个私钥)来解密SSL文件时会调用的一个外部命令。默认情况下,这个参数为空,表示使用内置的提示机制。 + 设置获取用于解密私钥等 SSL 文件的口令时要调用的外部命令。默认值为空,表示使用内置的提示机制。 - - 该命令必须将密码打印到标准输出并且以代码0退出。在该参数值中,%p被替换为一个提示字符串(要得到文字%,应该写成%%)。注意该提示字符串将可能含有空格,因此要确保加上适当的引号。如果输出的末尾有单一的新行,它会被剥离掉。 + 该命令必须将口令输出到标准输出,并以退出码 0 结束。参数值中的 %p 会被替换为提示字符串。(要表示字面值 %,应写成 %%。)提示字符串可能包含空白,因此务必正确加引号。如果输出末尾有一个换行符,会将其去掉。 - - 该命令实际上并不一定要提示用户输入一个密码。它可以从文件中读取密码、从钥匙链得到密码等等。确保选中的机制足够安全是用户的责任。 + 该命令不一定要提示用户输入口令,也可以从文件读取口令、从钥匙链获取口令等。用户应自行确保所选机制足够安全。 - - 这个参数只能在postgresql.conf文件中或通过服务器命令行进行设置。 + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 @@ -1070,13 +1093,10 @@ include_dir 'conf.d' - 这个参数决定在配置重载期间如果一个密钥文件需要密码时,是否也调用ssl_passphrase_command设置的密码命令。 - 如果这个参数为false(默认),那么在重载期间将忽略ssl_passphrase_command,如果在此期间需要密码则SSL配置将不会被重载。 - 对于要求一个TTY(当服务器正在运行时可能是不可用的)来进行提示的命令,这种设置是合适的。 - 例如,如果密码是从一个文件中得到的,将这个参数设置为true可能是合适的。 + 此参数决定:配置重载期间,如果密钥文件需要口令,是否也调用 ssl_passphrase_command 设置的口令命令。如果此参数为 false(默认值),则重载时会忽略 ssl_passphrase_command,如果需要口令,就不会重载 SSL 配置。此设置适合需要通过 TTY 提示用户的命令,因为服务器运行期间可能无法使用 TTY。例如,如果从文件中获取口令,则适合将此参数设为 true。 - 这个参数只能在postgresql.conf文件中或通过服务器命令行进行设置。 + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 @@ -1099,20 +1119,14 @@ include_dir 'conf.d' - 设置数据库服务器将使用的共享内存缓冲区量。默认通常是 128 兆字节(128MB),但是如果你的内核设置不支持(在initdb时决定),那么可能会更少。 - 这个设置必须至少为 128 千字节。不过为了更好的性能,通常会使用明显高于最小值的设置。 - (BLCKSZ 的非默认值会改变最小值。) - 此参数只能在服务器启动时设置。 + 设置数据库服务器用于共享内存缓冲区的内存量。默认值通常为 128 兆字节(128MB),但如果内核设置不支持,则可能更小(在 initdb 期间确定)。此设置必须至少为 128 千字节。(BLCKSZ 的非默认值会改变该最小值。)不过,要获得良好性能,通常需要远高于该最小值的设置。此参数只能在服务器启动时设置。 - - 如果有一个专用的 1GB 或更多内存的数据库服务器,一个合理的shared_buffers开始值是系统内存的 25%。即使更大的shared_buffers有效,也会造成一些工作负载, 但因为PostgreSQL同样依赖操作系统的高速缓冲区,将shared_buffers设置为超过 40% 的RAM不太可能比一个小点值工作得更好。为了能把对写大量新的或改变的数据的处理分布在一个较长的时间段内,shared_buffers更大的设置通常要求对max_wal_size也做相应增加。 + 如果专用数据库服务器具有 1GB 或更多内存,shared_buffers 的合理初始值是系统内存的 25%。对于某些工作负载,将 shared_buffers 设得更大也有效,但由于 PostgreSQL 同时依赖操作系统缓存,将超过 40% 的内存分配给 shared_buffers 不太可能比更小的值效果更好。将 shared_buffers 设得更大时,通常还需要相应增加 max_wal_size,以便将大量新数据或已修改数据的写入过程分散到更长的时间内。 - - 如果系统内存小于 1GB,一个较小的 RAM 百分数是合适的,这样可以为操作系统留下足够的空间。 + 对于内存少于 1GB 的系统,适合使用更小的内存比例,以便为操作系统留出足够空间。 - @@ -1123,6 +1137,7 @@ include_dir 'conf.d' + 控制是否为主共享内存区域请求巨型页。有效值是try(默认)、on以及off。如果huge_pages被设置为try,则服务器将尝试请求巨型页,但是如果失败会退回到默认的方式。如果为on,请求巨型页失败将使得服务器无法启动。如果为off,则不会请求巨型页。 @@ -1132,19 +1147,19 @@ include_dir 'conf.d' - 巨型页面的使用会导致更小的页面表以及花费在内存管理上的 CPU 时间更少,从而提高性能。更多有关Linux上使用巨型页面的细节请见。 + 巨型页的使用会导致更小的页表以及花费在内存管理上的 CPU 时间更少,从而提高性能。更多有关Linux上使用巨型页的细节请见 巨型页在Windows上被称为大页面。 要使用大页面,需要为运行PostgreSQL的Windows用户账号分配在内存中锁定页面的用户权限。 可以使用Windows的组策略工具(gpedit.msc)来分配用户权限在内存中锁定页面。 - 为了在命令窗口以单进程(而不是Windows服务)的方式启动数据库服务器,命令窗口必须以管理员身份运行或者禁用用户访问控制(UAC)。 + 为了在命令窗口以独立进程(而不是Windows服务)的方式启动数据库服务器,命令窗口必须以管理员身份运行或者禁用用户访问控制(UAC)。 当UAC被启用时,普通的命令窗口会在启动时收回用户权限在内存中锁定页面。 - 注意这种设置仅影响主共享内存区域。Linux、FreeBSD以及Illumos之类的操作系统也能为普通内存分配自动使用巨型页(也被称为超级页或者页面),而不需要来自PostgreSQL的显式请求。在Linux上,这被称为transparent huge pagestransparent huge pages(THP,透明巨型页)。已知这种特性对某些Linux版本上的某些用户会导致PostgreSQL的性能退化,因此当前并不鼓励使用它(与huge_pages的显式使用不同)。 + 注意这种设置仅影响主共享内存区域。Linux、FreeBSD以及Illumos之类的操作系统也能为普通内存分配自动使用巨型页(也被称为超级页或者页面),而不需要来自PostgreSQL的显式请求。在Linux上,这被称为transparent huge pages透明巨型页(THP,透明巨型页)。已知这种特性对某些Linux版本上的某些用户会导致PostgreSQL的性能退化,因此当前并不鼓励使用它(与huge_pages的显式使用不同)。 @@ -1157,13 +1172,10 @@ include_dir 'conf.d' - 设置每个数据库会话使用的临时缓冲区的最大数量。这些缓冲区是仅用于访问临时表的会话本地缓冲区。 - 默认为 8 兆字节(8MB)。 - 这个设置可以在独立的会话内部被改变,但是只有在会话第一次使用临时表之前才能改变; 在会话中随后企图改变该值是无效的。 + 设置每个数据库会话使用的临时缓冲区的最大数量。这些是会话本地的缓冲区,仅用于访问临时表。默认值为 8 兆字节(8MB)。可以在单个会话内更改此设置,但必须在该会话首次使用临时表之前更改;此后尝试更改该值,对该会话不会产生影响。 - - 一个会话将按照temp_buffers给出的限制根据需要分配临时缓冲区。如果在一个并不需要大量临时缓冲区的会话里设置一个大的数值, 其开销只是一个缓冲区描述符,或者说temp_buffers每增加一则增加大概 64 字节。不过,如果一个缓冲区被实际使用,那么它就会额外消耗 8192 字节(或者BLCKSZ字节)。 + 会话会按需分配临时缓冲区,上限为 temp_buffers。对于实际不需要很多临时缓冲区的会话,将此参数设得较大时,开销仅为 temp_buffers 每增加一就多分配一个缓冲区描述符,约为 64 字节。不过,如果实际使用了某个缓冲区,还会为它额外消耗 8192 字节(一般而言为 BLCKSZ 字节)。 @@ -1176,16 +1188,13 @@ include_dir 'conf.d' - 设置可以同时处于prepared状态的事务的最大数目(见)。把这个参数设置 为零(这是默认设置)将禁用预备事务特性。这个参数只能在服务器启动时设置。 + 设置可同时处于预备状态的事务的最大数量(见 )。将此参数设为零(默认值)会禁用预备事务功能。此参数只能在服务器启动时设置。 - - 如果你不打算使用预备事务,可以把这个参数设置为零来防止意外创建预备事务。如果你正在使用预备事务,你将希望把max_prepared_transactions至少设置为一样大,因此每一个会话可以有一个预备事务待处理。 + 如果不打算使用预备事务,应将此参数设为零,以防意外创建预备事务。如果使用预备事务,通常应将 max_prepared_transactions 设为不小于 的值,以便每个会话都能有一个待处理的预备事务。 - - 当运行一个备库时,你必须设置这个参数等于或大于主库上的参数。 - 否则,备库上将不允许查询。 + 运行备库时,必须将此参数设为与主库相同或更大的值。否则,备库上将不允许执行查询。 @@ -1198,13 +1207,7 @@ include_dir 'conf.d' - 指定内部排序操作和哈希表在写入临时磁盘文件之前使用的内存量。默认值为四兆字节(4MB)。 - 请注意,复杂查询可能同时执行多个排序和哈希操作, - 每个操作通常允许在开始将数据写入临时文件之前使用此值指定的内存量。 - 此外,可能有多个正在运行的会话同时执行此类操作。 - 因此,使用的总内存量可能是work_mem值的多倍; - 在选择值时必须牢记这一事实。排序操作用于ORDER BYDISTINCT和合并连接。 - 哈希表用于哈希连接、基于哈希的聚合和IN子查询的基于哈希的处理。 + 指定内部排序操作和哈希表在写入临时磁盘文件之前可使用的内存量。默认值为 4 兆字节(4MB)。请注意,复杂查询可能同时执行多个排序和哈希操作,每个操作在开始向临时文件写入数据之前,通常都可以使用此值指定的内存量。此外,多个正在运行的会话也可能并发执行此类操作。因此,使用的总内存量可能是 work_mem 值的数倍;选择此值时必须考虑这一点。排序操作用于 ORDER BYDISTINCT 和归并连接。哈希表用于哈希连接、基于哈希的聚合、以及基于哈希的 IN 子查询处理。 @@ -1217,18 +1220,13 @@ include_dir 'conf.d' - 指定维护操作(如 VACUUMCREATE INDEX 和 - ALTER TABLE ADD FOREIGN KEY)可使用的最大内存量。 - 默认值为 64 兆字节(64MB)。 - 由于数据库会话一次只能执行一个这样的操作,而一个安装通常也不会有很多此类操作并发运行, - 因此把该值设置得明显大于 work_mem 通常是安全的。更大的设置可能改善清理和恢复数据库转储的性能。 + 指定维护操作(如 VACUUMCREATE INDEXALTER TABLE ADD FOREIGN KEY)可使用的最大内存量。默认值为 64 兆字节(64MB)。由于一个数据库会话一次只能执行一个此类操作,而一个数据库系统通常也不会并发运行很多此类操作,因此可以安全地将该值设得远大于 work_mem。更大的设置可能改善清理和恢复数据库转储的性能。 - 请注意,当 autovacuum 运行时,分配的内存量最多可能达到此值的倍,因此请小心,不要将默认值设置得过高。 - 单独设置可能有助于控制这一点。 + 注意,自动清理运行时,最多可能分配此内存量的 倍,因此不要将默认值设得过高。单独设置 可能有助于控制这一点。 - 请注意,为收集死元组标识符,VACUUM最多只能使用1GB内存。 + 注意,在收集死元组标识符时,VACUUM 最多只能使用 1GB 内存。 @@ -1241,14 +1239,10 @@ include_dir 'conf.d' - 指定每个自动清理工作者进程能使用的最大内存量。 - 其默认值为 -1,表示转而使用 的值。 - 当运行在其他上下文环境中时,这个设置对VACUUM的行为没有影响。 - 这个参数只能在postgresql.conf中或者服务器命令行上设置。 + 指定每个自动清理工作进程可使用的最大内存量。默认值为 -1,表示改用 的值。该设置不影响其他上下文中运行的 VACUUM 的行为。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 - 为收集死元组标识符,autovacuum 最多只能使用1GB内存, - 因此将autovacuum_work_mem设置为更高的值,不会影响 autovacuum 扫描表时可以收集的死元组数量。 + 在收集死元组标识符时,自动清理最多只能使用 1GB 内存,因此将 autovacuum_work_mem 设得更高,不会影响自动清理扫描表时能收集的死元组数量。 @@ -1260,13 +1254,14 @@ include_dir 'conf.d' + 指定服务器执行栈的最大安全深度。此参数的理想设置是由内核强制执行的实际栈大小限制 - (如由ulimit -s或本地等效设置),减去大约一兆字节的安全边界。 - 需要安全边界是因为服务器中并非每个例程都检查栈深度,而只在表达式求值等关键的潜在递归例程中检查。 + (如由ulimit -s或本地等效设置),减去大约一兆字节的安全余量。 + 需要安全余量是因为服务器中并非每个例程都检查栈深度,而只在可能递归的关键例程(如表达式求值)中检查。 默认设置为两兆字节(2MB), 这是保守且不太可能引起崩溃的小值。但是,这可能太小,无法执行复杂函数。 - 只有超级用户能更改这个设置。 + 只有超级用户才能更改此设置。 @@ -1283,13 +1278,7 @@ include_dir 'conf.d' - 指定服务器应该使用的动态共享内存实现。可能的值包括posix(使用shm_open分配的POSIX共享内存), - sysv(通过shmget分配的System V共享内存), - windows(用于Windows共享内存), - mmap(使用存储在数据目录中的内存映射文件模拟共享内存),以及none(禁用此特性)。 - 并非所有平台都支持所有值;第一个支持的选项是该平台的默认值。 - mmap选项不是任何平台的默认选项,通常不建议使用,因为操作系统可能会反复将修改的页面写回磁盘,增加系统I/O负载; - 但在调试时,当pg_dynshmem目录存储在RAM磁盘上,或者其他共享内存设施不可用时,可能会有用。 + 指定服务器应使用的动态共享内存实现。可选值为 posix(使用 shm_open 分配的 POSIX 共享内存)、sysv(通过 shmget 分配的 System V 共享内存)、windows(Windows 共享内存)、mmap(使用存放在数据目录中的内存映射文件模拟共享内存),以及 none(禁用此功能)。并非所有平台都支持所有值;第一个受支持的选项是该平台的默认值。mmap 不是任何平台的默认选项,通常不建议使用,因为操作系统可能会反复将修改过的页面写回磁盘,增加系统 I/O 负载;不过,在调试、将 pg_dynshmem 目录存放在 RAM 磁盘上,或其他共享内存设施不可用时,它可能有用。 @@ -1309,14 +1298,10 @@ include_dir 'conf.d' - 指定进程可以用于临时文件(如排序和哈希临时文件)或保留游标的存储文件的最大磁盘空间。 - 尝试超过此限制的事务将被取消。 - 此值以千字节为单位指定。 - -1(默认值)表示没有限制。 - 只有超级用户能更改这个设置。 + 指定一个进程可用于临时文件的最大磁盘空间,例如排序和哈希临时文件,或保留游标的存储文件。尝试超过此限制的事务将被取消。该值以千字节为单位。-1(默认值)表示没有限制。只有超级用户才能更改此设置。 - 这个设置约束着一个给定PostgreSQL进程在任何瞬间所使用的所有临时文件的总空间。应该注意的是,与在查询执行中在幕后使用的临时文件相反,显式临时表所用的磁盘空间被这个设置所限制。 + 此设置限制单个 PostgreSQL 进程在任意时刻使用的所有临时文件的总空间。需要注意,显式临时表所用的磁盘空间计入该上限;计入的是查询执行过程中内部使用的临时文件。 @@ -1336,31 +1321,30 @@ include_dir 'conf.d' - 设置每个服务器子进程允许同时打开的最大文件数。默认值是一千个文件。 - 如果内核实施了安全的单进程限制,就不必担心此设置。但在某些平台上 - (尤其是大多数 BSD 系统),内核允许单个进程打开的文件数很多,以至于 - 当多个进程都试图打开这么多文件时,会超过系统实际能够支持的数量。 - 如果遇到Too many open files错误,可以尝试减小此设置。 - 此参数只能在服务器启动时设置。 + 设置每个服务器子进程允许同时打开的最大文件数量。默认值为一千个文件。如果内核强制实施了安全的每进程上限,就不必担心此设置。但在某些平台上(尤其是大多数 BSD 系统),内核允许单个进程打开的文件数量很大,如果很多进程都尝试打开这么多文件,就会远超系统实际能够支持的总量。如果遇到 Too many open files(打开的文件过多)错误,可尝试减小此设置。此参数只能在服务器启动时设置。
- + + 基于代价的清理延迟 - 在命令的执行过程中,系统维持着一个内部计数器来跟踪各种被执行的I/O操作的估算开销。当累计的代价达到一个限制(由vacuum_cost_limit指定),执行这些操作的进程将按照vacuum_cost_delay所指定的休眠一小段时间。然后它将重置计数器并继续执行。 + 执行 命令期间,系统维护一个内部计数器,记录已执行的各种 I/O 操作的估算代价。 + 当累计代价达到上限(由 vacuum_cost_limit 指定)时,执行该操作的进程会休眠一小段时间,时长由 vacuum_cost_delay 指定。 + 随后重置计数器并继续执行。 - 这个特性的出发点是允许管理员降低这些命令对并发的数据库活动产生的I/O影响。在很多情况下,VACUUMANALYZE等维护命令能否快速完成并不重要,而非常重要的是这些命令不会对系统执行其他数据库操作的能力产生显著的影响。基于代价的清理延迟提供了一种方式让管理员能够保证这一点。 + 此功能让管理员能够降低这些命令对并发数据库活动的 I/O 影响。在许多情况下,VACUUMANALYZE 等维护命令是否快速完成并不重要, + 但避免它们显著干扰系统执行其他数据库操作的能力通常很重要。基于代价的清理延迟为管理员提供了实现这一点的方法。 - 对于手动发出的VACUUM命令,该特性默认被禁用。要启用它,只要把vacuum_cost_delay变量设为一个非零值。 + 对于手动执行的 VACUUM 命令,此功能默认禁用。要启用它,将 vacuum_cost_delay 变量设为非零值。 @@ -1371,17 +1355,13 @@ include_dir 'conf.d' - - 超出代价限制时,进程将休眠的时间长度,以毫秒为单位。默认值为零,这会禁用基于代价的清理延迟特性。正值会启用基于代价的清理。 - 请注意,在许多系统上,休眠延迟的有效分辨率为 10 毫秒;将vacuum_cost_delay设置为非 10 的倍数的值, - 可能与设置为下一个更大的 10 的倍数具有相同效果。 - - - - 使用基于代价的清理时,vacuum_cost_delay的合适值通常很小,可能是 10 或 20 毫秒。 - 调整清理的资源消耗最好通过更改其他清理代价参数来完成。 - - + + 超过代价上限后,进程将休眠的时长,单位为毫秒。默认值为零,表示禁用基于代价的清理延迟功能。正值会启用基于代价的清理。注意,在许多系统上,休眠延迟的有效分辨率为 10 毫秒;将 vacuum_cost_delay 设为不是 10 的倍数的值,可能与将它设为下一个更大的 10 的倍数效果相同。 + + + 使用基于代价的清理时,vacuum_cost_delay 的合适值通常较小,例如 10 或 20 毫秒。调整清理的资源消耗时,最好更改其他清理代价参数。 + + @@ -1392,11 +1372,10 @@ include_dir 'conf.d' - - - 清理一个在共享缓存中找到的缓冲区的估计代价。它表示锁住缓冲池、查找共享哈希表和扫描页内容的代价。默认值为1。 - - + + 清理在共享缓冲区缓存中找到的缓冲区时所计入的估算代价。它表示锁定缓冲池、查找共享哈希表和扫描页内容的代价。默认值为 1。 + + @@ -1406,12 +1385,10 @@ include_dir 'conf.d' - - 清理一个必须从磁盘上读取的缓冲区的代价。 - 它表示锁住缓冲池、查找共享哈希表、从磁盘读取需要的块以及扫描其内容的代价。 - 默认值为10。 - - + + 清理必须从磁盘读取的缓冲区时所计入的估算代价。它表示锁定缓冲池、查找共享哈希表、从磁盘读取所需数据块并扫描其内容所需的工作量。默认值为 10。 + + @@ -1422,11 +1399,10 @@ include_dir 'conf.d' - - - 当清理修改一个之前干净的块时需要花费的估计代价。它表示再次把脏块刷出到磁盘所需要的额外I/O。默认值为20。 - - + + 清理操作修改原本干净的数据块时所计入的估算代价。它表示再次将脏块刷盘所需的额外 I/O。默认值为 20。 + + @@ -1437,20 +1413,18 @@ include_dir 'conf.d' - - - 将导致清理进程休眠的累计代价。默认值为200。 - - + + 会使清理进程休眠的累计代价。默认值为 200。 + + - - 有些操作会保持关键性的锁,这样可以尽快完成。基于代价的清理延迟在这类操作期间不会发生。因此有可能代价会累计至大大超过指定的限制。为了防止在这种情况下的无意义的长时间延迟,实际延迟的计算方式是vacuum_cost_delay * - accumulated_balance / - vacuum_cost_limit,且最大值是vacuum_cost_delay * 4。 + 某些操作持有关键的锁,因此应尽快完成。这些操作期间不会发生基于代价的清理延迟,所以累计代价可能远超指定上限。 + 为避免此时出现无益的长时间延迟,实际延迟按 vacuum_cost_delay * accumulated_balance / vacuum_cost_limit 计算, + 但最大不超过 vacuum_cost_delay * 4。 @@ -1459,10 +1433,11 @@ include_dir 'conf.d' 后台写入器 - 有一个独立的服务器进程,叫做后台写入器,它的功能就是发出写(新的或修改过的)共享缓冲区的命令。 - 当干净的共享缓存数量出现不足时,后台写入器写入一些脏缓存到文件系统,并标记为干净。 - 不过,后台写入器确实会增加 I/O 的总负荷,因为虽然在每个检查点间隔中一个重复弄脏的页面可能只会写出一次,但在同一个间隔中后台写入器可能会把它写出好几次。 - 在这一小节讨论的参数可以被用于调节本地需求的行为。 + 有一个独立的服务器进程,称为后台写入器,负责写出(新的或修改过的)共享缓冲区。 + 当干净的共享缓冲区数量似乎不足时,后台写入器会将一些脏缓冲区写入文件系统,并将其标记为干净。 + 这可以降低处理用户查询的服务器进程找不到干净缓冲区、因而不得不自行写出脏缓冲区的可能性。 + 不过,后台写入器确实会使总体 I/O 负载有所增加:反复变脏的页面原本可能在每个检查点间隔中只写出一次, + 而后台写入器可能在同一间隔内随着它变脏而多次写出。本节参数可用于根据实际需求调整此行为。 @@ -1473,12 +1448,10 @@ include_dir 'conf.d' - - 指定后台写入器活动轮次之间的延迟。在每个轮次中,写入器都会为一定数量的脏缓冲区发出写操作(可以用下面的参数控制)。 - 然后它就休眠 bgwriter_delay毫秒, 然后重复动作。当缓冲池中没有脏缓冲区时,不管 bgwriter_delay,它都会进入更长的休眠。默认值是 200 毫秒(200ms)。 - 注意在许多系统上,休眠延迟的有效解析度是 10 毫秒;因此,为bgwriter_delay设置一个 不是 10 的倍数的值与把它设置为下一个更高的 10 的倍数是一样的效果。这个选项只能在服务器命令行上或者在postgresql.conf文件中设置。 - - + + 指定后台写入器各轮活动之间的延迟。每一轮中,写入器会对一定数量的脏缓冲区发出写操作(由下面的参数控制),然后休眠 bgwriter_delay 毫秒,再重复此过程。不过,当缓冲池中没有脏缓冲区时,它会进入更长的休眠,而不受 bgwriter_delay 限制。默认值为 200 毫秒(200ms)。注意,在许多系统上,休眠延迟的有效分辨率为 10 毫秒;将 bgwriter_delay 设为不是 10 的倍数的值,可能与将它设为下一个更大的 10 的倍数效果相同。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 + + @@ -1489,11 +1462,10 @@ include_dir 'conf.d' - - - 在每个轮次中,不超过这么多个缓冲区将被后台写入器写出。把这个参数设置为零可禁用后台写出(注意被一个独立、专用辅助进程管理的检查点不受影响)。默认值是 100 个缓冲区。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 - - + + 后台写入器每轮写出的缓冲区数量不会超过此值。设为零会禁用后台写入。(由另一个独立的专用辅助进程管理的检查点不受影响。)默认值为 100 个缓冲区。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 + + @@ -1504,11 +1476,10 @@ include_dir 'conf.d' - - - 每一轮次要写的脏缓冲区的数目基于最近几个轮次中服务器进程需要的新缓冲区的数目。 最近所需的平均值乘以bgwriter_lru_multiplier可以估算下一轮次中将会需要的缓冲区数目。脏缓冲区将被写出直到有很多干净可重用的缓冲区(然而,每一轮次中写出的缓冲区数不超过bgwriter_lru_maxpages)。 因此,设置为 1.0 表示一种刚刚好的策略,这种策略会写出正好符合预测值的数目的缓冲区。 更大大的值可以为需求高峰提供某种缓冲,而更小的值则需要服务进程来处理一些写出操作。默认值是 2.0。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 - - + + 每轮写出的脏缓冲区数量取决于最近几轮服务器进程所需的新缓冲区数量。将近期平均需求乘以 bgwriter_lru_multiplier,即可估算下一轮所需的缓冲区数量。写入器会写出脏缓冲区,直到可用的干净且可重用缓冲区达到这一数量。(不过,每轮写出的缓冲区数量不会超过 bgwriter_lru_maxpages。)因此,设为 1.0 表示采用恰好及时策略,写出的缓冲区数量恰好等于预测需求量。更大的值可为需求突增留出余量,而更小的值则有意将部分写操作留给服务器进程执行。默认值为 2.0。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 + + @@ -1518,17 +1489,16 @@ include_dir 'conf.d' - - 只要后台写入器写入的数据超过bgwriter_flush_after字节,尝试强制 OS 把这些写发送到底层存储上。这样做将限制内核页缓存中脏数据的量,降低了在检查点末尾发出一个 fsync 时或者 OS 在后台大批量写回数据时卡住的可能性。 - 那常常会导致大幅度压缩的事务延迟,但是也有一些情况(特别是负载超过但小于 OS 页面高速缓存)的性能会降低。这种设置可能会在某些平台上没有效果。 - 合法的范围在0(禁用受控写回)和2MB之间。Linux 上的默认值是512kB,其他平台上是0(如果BLCKSZ不是8kB,则默认值和最大值会按比例缩放至这个值)。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 - - + + 每当后台写入器写出的数据超过bgwriter_flush_after 字节时,就尝试强制操作系统将这些写操作发往底层存储。这样可以限制内核页缓存中的脏数据量,降低在检查点结束时调用 fsync,或操作系统在后台以较大批次写回数据时发生停顿的可能性。通常,这能大幅降低事务延迟,但在某些情况下性能可能下降,尤其是工作负载大于 而小于操作系统页缓存时。此设置在某些平台上可能没有效果。有效范围为 0(禁用强制写回)至 2MB。Linux 上的默认值为 512kB,其他平台为 0。(如果 BLCKSZ 不是 8kB,默认值和最大值将按比例变化。)此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 + + - 较小的bgwriter_lru_maxpagesbgwriter_lru_multiplier可以降低由后台写入器造成的额外 I/O 开销。但更可能的是,服务器进程将必须自己发出写入操作,这会延迟交互式查询。 + 较小的 bgwriter_lru_maxpagesbgwriter_lru_multiplier 可以降低后台写入器造成的额外 I/O 负载, + 但也会增加服务器进程必须自行发出写操作的可能性,从而延迟交互式查询。 @@ -1543,29 +1513,19 @@ include_dir 'conf.d' - - 设置PostgreSQL预期可以同时执行的并发磁盘 I/O 操作数量。 - 提高该值会增加任何单个PostgreSQL会话尝试并行发起的 I/O 操作数。 - 允许的范围是 1 到 1000,或者零表示禁用异步 I/O 请求。目前,此设置只影响位图堆扫描。 - - - - 对于磁盘,此设置的一个良好起点是数据库所用的 RAID 0 条带或 RAID 1 镜像中独立磁盘的数量。 - (对于 RAID 5,不应计入奇偶校验盘。)但是,如果数据库经常忙于处理并发会话发出的多个查询,较低的值可能已足以让磁盘阵列保持忙碌。 - 超过使磁盘保持忙碌所需的值只会产生额外的 CPU 开销。 - SSD 和其他基于内存的存储通常可以处理很多并发请求,因此最佳值可能达到数百。 - - - - 异步 I/O 依赖有效的posix_fadvise函数,而某些操作系统缺少该函数。 - 如果不存在该函数,将此参数设置为零以外的任何值都会导致错误。 - 在某些操作系统上(例如 Solaris),该函数虽然存在,但实际上不起任何作用。 - - - - 在支持的系统上默认值为 1,否则为 0。对于位于特定表空间中的表,可以通过设置同名的表空间参数覆盖此值(参见)。 - - + + 设置 PostgreSQL 预期可以同时执行的并发磁盘 I/O 操作数量。提高此值会增加单个 PostgreSQL 会话尝试并行发起的 I/O 操作数量。允许的范围为 1 至 1000,或设为零以禁用异步 I/O 请求。目前,此设置仅影响位图堆扫描。 + + + 对于磁盘,可以将为数据库提供存储的 RAID 0 条带或 RAID 1 镜像中的独立磁盘数量作为合理初始值。(对于 RAID 5,不应计入校验盘。)不过,如果数据库经常忙于执行并发会话发出的多个查询,较小的值可能就足以使磁盘阵列保持繁忙。超过使磁盘保持繁忙所需的值只会增加 CPU 开销。SSD 和其他基于内存的存储通常可以处理大量并发请求,因此最佳值可能达到数百。 + + + 异步 I/O 依赖于有效的 posix_fadvise 函数,而某些操作系统缺少此函数。如果该函数不存在,将此参数设为任何非零值都会报错。在某些操作系统(如 Solaris)上,该函数虽然存在,却实际上不做任何事情。 + + + 支持此功能的系统上默认值为 1,其他系统为 0。对于位于特定表空间中的表,可以通过设置同名的表空间参数覆盖此值(见 )。 + + @@ -1575,19 +1535,16 @@ include_dir 'conf.d' - - 设置系统能够支持的后台进程的最大数量。这个参数只能在服务器启动时设置。默认值为 8。 + + 设置系统能够支持的后台进程的最大数量。此参数只能在服务器启动时设置。默认值为 8。 - - - 在运行一个备库时,你必须把这个参数设置为等于或者高于主库上的值。 - 否则,备库上将不允许查询。 - - - - 在更改这个值时,考虑也对以及进行调整。 - - + + 运行备库时,必须将此参数设为与主库相同或更大的值。否则,备库上将不允许执行查询。 + + + 更改此值时,也应考虑调整 。 + + @@ -1598,19 +1555,16 @@ include_dir 'conf.d' - - - 设置单个Gather或者Gather Merge节点能够开始的工作者的最大数量。并行工作者会从建立的进程池中取得,数量由限制。注意所要求的工作者数量在运行时可能实际无法被满足。如果这种事情发生,该计划将会以比预期更少的工作者运行,这可能会不太高效。默认值是2。把这个值设置为0将会禁用并行查询执行。 - - - - 注意并行查询可能消耗比非并行查询更多的资源,因为每一个工作者进程时一个完全独立的进程,它对系统产生的影响大致和一个额外的用户会话相同。在为这个设置选择值时,以及配置其他控制资源利用的设置(例如)时,应该把这个因素考虑在内。work_mem之类的资源限制会被独立地应用于每一个工作者,这意味着所有进程的总资源利用可能会比单个进程时高得多。例如,一个使用 4 个工作者的并行查询使用的 CPU 时间、内存、I/O 带宽可能是不使用工作者时的 5 倍之多。 - - - - 并行查询的更多信息请见。 - - + + 设置单个 GatherGather Merge 节点能够启动的工作进程的最大数量。并行工作进程取自 建立的进程池,并受到 的限制。注意,运行时实际可用的工作进程可能不足请求的数量。此时,计划会使用少于预期的工作进程运行,效率可能较低。默认值为 2。设为 0 会禁用并行查询执行。 + + + 注意,并行查询消耗的资源可能远多于非并行查询,因为每个工作进程都是完全独立的进程,对系统的影响大致相当于额外增加一个用户会话。选择此设置的值,以及配置其他控制资源使用的设置(如 )时,都应考虑这一点。work_mem 等资源限制分别应用于每个工作进程,因此所有进程的总资源用量可能远高于单个进程通常的用量。例如,使用 4 个工作进程的并行查询,其 CPU 时间、内存、I/O 带宽等用量可能达到完全不使用工作进程的查询的 5 倍。 + + + 并行查询的更多信息参见 。 + + @@ -1620,17 +1574,13 @@ include_dir 'conf.d' - - 设置单一工具性命令能够启动的并行工作者的最大数目。 - 当前,支持使用并行工作者的工具性命令是CREATE INDEX,并且只有在构建B-树索引时才能并行。 - 并行工作者从由创建的进程池中取出,数量由控制。 - 注意实际在运行时所请求数量的工作者可能不可用。如果发生这种情况,工具性操作将使用比预期数量少的工作者运行。默认值为2。将这个值设置为0可以禁用工具性命令对并行工作者的使用。 - - - - 注意并行工具性命令不应该消耗比同等数量非并行操作更多的内存。这种策略与并行查询不同,并行查询的资源限制通常是应用在每个工作者进程上。并行工具性命令把资源限制maintenance_work_mem当作对整个工具性命令的限制,而不管其中用到了多少个并行工作者进程。不过,并行工具性命令实际上可能仍会消耗更多的CPU资源和I/O带宽。 - - + + 设置单个工具命令能够启动的并行工作进程的最大数量。目前,唯一支持使用并行工作进程的工具命令是 CREATE INDEX,且仅在构建 B-树索引时支持。并行工作进程取自 建立的进程池,并受到 的限制。注意,运行时实际可用的工作进程可能不足请求的数量。此时,工具操作会使用少于预期的工作进程运行。默认值为 2。设为 0 会禁止工具命令使用并行工作进程。 + + + 注意,并行工具命令的内存消耗不应明显高于等效的非并行操作。这与并行查询的策略不同,后者的资源限制通常分别应用于每个工作进程。并行工具命令将 maintenance_work_mem 视为整个工具命令的资源上限,而不论使用多少个并行工作进程。不过,并行工具命令仍可能消耗多得多的 CPU 资源和 I/O 带宽。 + + @@ -1640,8 +1590,10 @@ include_dir 'conf.d' - 设置系统能够支持的并行操作工作进程最大数量。默认值为 8。增大或减小该值时,也应考虑调整。另外注意,将此值设得高于不会产生效果,因为并行工作进程取自该设置所建立的工作进程池。 - + + 设置系统能够为并行操作提供的工作进程的最大数量。默认值为 8。增大或减小此值时,也应考虑调整 。此外,将此值设得大于 没有效果,因为并行工作进程取自该设置建立的工作进程池。 + + @@ -1651,57 +1603,38 @@ include_dir 'conf.d' - - 当单个后端写入数据的量超过backend_flush_after字节时,尝试强制操作系统发送这些写入到底层存储。 - 这样做将限制内核的页面缓存中的脏数据量,降低在检查点末尾发出fsync时暂停的可能性,或者当操作系统在后台大批量的写回数据时。 - 通常的结果会大大减少事务延迟,但也有一些情况,特别是当工作负载大于,但小于操作系统的页面缓存时,性能可能会下降。 - 此设置在某些平台上可能无效。 - 有效范围在0,禁止强制回写,和2MB之间。 - 默认值是0,即没有强制回写。 - (如果BLCKSZ不是8kB,则最大值按其比例缩放。) - - + + 每当单个后端写出的数据超过backend_flush_after 字节时,就尝试强制操作系统将这些写操作发往底层存储。这样可以限制内核页缓存中的脏数据量,降低在检查点结束时调用 fsync,或操作系统在后台以较大批次写回数据时发生停顿的可能性。通常,这能大幅降低事务延迟,但在某些情况下性能可能下降,尤其是工作负载大于 而小于操作系统页缓存时。此设置在某些平台上可能没有效果。有效范围为 0(禁用强制写回)至 2MB。默认值为 0,即不强制写回。(如果 BLCKSZ 不是 8kB,最大值将按比例变化。) + + - + + old_snapshot_threshold (integer) - - old_snapshot_threshold配置参数 - - + + old_snapshot_threshold 配置参数 + + - - 设置快照可以被使用、且不会在使用时发生snapshot too old错误风险的最短时间。 - 此参数只能在服务器启动时设置。 - - - - 超过此阈值后,旧数据可能被清理掉。这有助于防止长期使用的快照造成膨胀。 - 为防止清理本应对快照可见的数据而产生错误结果,当快照比此阈值更旧,并且被用于读取自快照创建以来已被修改的页面时,会产生错误。 - - - - 默认值-1禁用此特性。用于生产工作的有效值可能从几小时到几天不等。 - 此设置会被强制转换为分钟粒度,允许01min之类的小值,只是因为它们有时可用于测试。 - 虽然允许高达60d的设置,但请注意,许多工作负载可能在短得多的时间内发生严重膨胀或事务 ID 回卷。 - - - - 启用此特性后,关系末尾释放出来的空间将不能返还给操作系统,因为那样会移除 - 检测snapshot too old条件所需的信息。分配给某个关系的全部空间都会一直 - 归属于该关系,只能在该关系内部重用,除非显式释放(例如使用 - VACUUM FULL)。 + + 设置快照在使用时不会发生 snapshot too old 错误的最短可用时间。此参数只能在服务器启动时设置。 - - - 此设置并不试图保证在任何特定情况下都会产生错误。事实上,例如对于已物化结果集的游标,如果仍能产生正确结果, - 即使所引用表中的底层行已被清理掉,也不会产生错误。 - 某些表(例如系统目录)无法安全地提前清理,因此不受此设置影响。 - 对于这些表,此设置既不会减少膨胀,也不会使扫描时可能出现snapshot too old错误。 - - + + 超过该阈值后,旧数据可以被清理掉。这有助于在快照长期保持使用时防止膨胀。为了避免因清理本应对该快照可见的数据而得到错误结果,当快照年龄超过该阈值,且该快照被用于读取自其建立以来已被修改过的页面时,就会报错。 + + + 值 -1 会禁用此功能,也是默认值。对生产环境而言,有用的取值大概从几个小时到几天不等。此设置会被强制调整为分钟粒度;较小的值(例如 01min)之所以被允许,只是因为它们有时可用于测试。虽然允许设置到 60d 这么高,但在许多工作负载中,严重膨胀或事务 ID 回卷可能会在更短时间内发生。 + + + 启用此功能后,关系末尾释放出来的空间不能返还给操作系统,因为那样可能会移除检测 snapshot too old 条件所需的信息。分配给某个关系的全部空间仍归属于该关系,只能在该关系内重用,除非显式释放(例如使用 VACUUM FULL)。 + + + 此设置不保证在任何特定情况下都一定会报错。实际上,如果仍能从某个对象(例如已物化结果集的游标)生成正确结果,那么即使被引用表中的底层行已被清理掉,也不会报错。有些表不能安全地提前清理,因此不受此设置影响,例如系统目录。对于这类表,此设置既不会减少膨胀,也不会在扫描时引入 snapshot too old 错误的可能性。 + + -
+ @@ -1735,12 +1668,12 @@ include_dir 'conf.d' CLUSTER 向同一事务中创建或截断的表执行COPY - 但最少的 WAL 不包含足够的信息来从基础备份和 WAL 日志重建数据,因此必须使用replica或更高级别来启用 WAL 归档 + 但 minimal 级别的 WAL 不包含足够的信息来从基础备份和 WAL 日志重建数据,因此必须使用replica或更高级别来启用 WAL 归档 ()和流复制。
logical级别上,记录与replica相同的信息,以及从WAL中提取逻辑变更集所需的信息。 - 使用logical级别会增加WAL的容量,特别是如果许多表被配置为REPLICA IDENTITY FULL, + 使用logical级别会增加 WAL 的数量,特别是如果许多表被配置为REPLICA IDENTITY FULL, 并且执行了许多UPDATEDELETE语句。 @@ -1767,16 +1700,15 @@ include_dir 'conf.d' - 能安全关闭fsync的环境的示例包括从一个备份文件中初始加载一个新数据库集簇、使用一个数据库集簇来在数据库被删掉并重建之后处理一批数据,或者一个被经常重建并却不用于失效备援的只读数据库克隆。单独的高质量硬件不足以成为关闭fsync的理由。 + 可以安全关闭fsync的情形包括:从备份文件初始装载一个新数据库集簇;用数据库集簇处理一批数据,处理后就丢弃并重建该数据库;或者使用经常重建且不用于故障切换的只读数据库克隆。仅有高质量硬件不足以成为关闭fsync的理由。 - 当把fsync从关闭改成打开时,为了可靠的恢复,需要强制在内核中的所有被修改的缓冲区进入持久化存储。这可以在多个时机来完成: - 在集簇被关闭时或在fsync因为运行initdb --sync-only而打开时、运行sync时、卸载文件系统时或者重启服务器时。 + 为确保将fsync从关闭改为打开后能够可靠恢复,必须将内核中所有已修改的缓冲区强制写入持久存储。可以在集簇已关闭或fsync已开启时,通过运行initdb --sync-only、运行sync、卸载文件系统或重启服务器来完成。 - 在很多情况下,为不重要的事务关闭可以提供很多关闭fsync的潜在性能收益,并不会有的同时, 关闭fsync可以提供很多潜在的性能优势,而不会有伴随着的数据损坏风险。 + 在很多情况下,为非关键事务关闭,可以获得关闭fsync所带来的大部分潜在性能收益,同时避免伴随的数据损坏风险。 @@ -1793,39 +1725,27 @@ include_dir 'conf.d' - 指定数据库服务器返回success指示给客户端之前,必须要完成多少WAL处理。 - 合法的值为remote_apply, on(默认值), remote_write,local, 和 off。 + 指定数据库服务器向客户端返回成功指示之前,必须完成多少 WAL 处理。有效值为remote_applyon(默认值)、remote_writelocaloff - 如果synchronous_standby_names为空,则唯一有意义的设置为onoff ; - remote_applyremote_writelocal都提供与on相同的本地同步级别。 - 所有非off模式的本地行为都是等待WAL的本地刷新到磁盘。 - 在 off模式,无需等待,因此在向客户端报告成功和以后保证事务安全防止服务器崩溃之间可能会出现延迟。 - (最大的延迟是的三倍。) - 不同于,将这个参数设置为off不会产生数据库不一致性的风险:一个操作系统或数据库崩溃可能会造成一些最近据说已提交的事务丢失,但数据库状态是一致的,就像这些事务已经被干净地中止。 - 因此,当性能比完全确保事务的持久性更重要时,关闭synchronous_commit可以作为一个有效的代替手段。更多讨论见。 + 如果synchronous_standby_names为空,只有onoff两种设置有意义;remote_applyremote_writelocal提供的本地同步级别都与on相同。所有非off模式在本地都会等待 WAL 刷写到磁盘。在off模式下则无需等待,因此,向客户端报告成功后,可能还要经过一段时间,才能保证事务不会因服务器崩溃而丢失。(最大延迟为的三倍。)与不同,将此参数设为off不会带来数据库不一致的风险:操作系统或数据库崩溃可能会使一些最近报告已提交的事务丢失,但数据库状态会与这些事务已正常中止时完全相同。因此,当性能比完全确保事务持久性更重要时,关闭synchronous_commit可以是一种有用的替代方案。更多讨论见 - 如果为非空,synchronous_commit也控制是否事务提交将等待它们的 WAL 记录在备库上被处理。 + 如果非空,synchronous_commit还控制事务提交是否等待备库处理其 WAL 记录。 - 当设置为 remote_apply 时,提交将等待,直到来自当前同步备库的答复显示他们已收到事务的提交记录并应用了它,以便它变得对备库上的查询可见,并写入备库上的持久存储。 - 这将导致比以前的设置更大的提交延迟,因为它等待 WAL 重放(replay)。 - 当设置为on时,提交将等待,直到来自于当前同步的备库的回复显示它们已经收到了事务的提交记录并将其刷入了磁盘。 - 这保证事务将不会被丢失,除非主库和所有同步备库都遭受到了数据库存储损坏的问题。 - 当这个参数被设置为remote_write时,提交将等待,直到来自当前的同步备库的回复指示它们已经收到了该事务的提交记录并且已经把该记录写到它们的文件系统,这种设置保证数据得以保存,在PostgreSQL的备库实例崩溃时,但是不能保证备库遭受操作系统级别崩溃时数据能被保持,因为数据不一定必须要在备库上达到持久存储。 - 设置local会导致提交等待本地刷写到磁盘,而不是复制。在使用同步复制时这通常是不可取的,但是为了完整性提供了这个选项。 + 设为remote_apply时,提交会等待当前同步备库回复,确认已收到并应用该事务的提交记录,使其对备库上的查询可见,并且已将其写入备库的持久存储。由于需要等待 WAL 重放,这会比之前的设置产生大得多的提交延迟。设为on时,提交会等待当前同步备库回复,确认已收到事务的提交记录,并已将其刷写到持久存储。这能保证事务不会丢失,除非主库和所有同步备库的数据库存储都损坏。设为remote_write时,提交会等待当前同步备库回复,确认已收到事务的提交记录,并已将其写入各自的文件系统。此设置能保证备库上的PostgreSQL实例崩溃时数据不丢失,但不能保证备库发生操作系统级别崩溃时数据不丢失,因为数据未必已写入备库的持久存储。设为local时,提交会等待本地刷盘,但不等待复制。使用同步复制时通常不希望采用这种设置,提供它是为了使选项完整。 - 这个参数可以随时被修改;任何一个事务的行为由其提交时生效的设置决定。因此,可以同步提交一些事务,同时异步提交其他事务。例如,当默认是相反时,实现一个单一多语句事务的异步提交,在事务中发出SET LOCAL synchronous_commit TO OFF。 + 此参数可以随时更改;每个事务的行为由提交时生效的设置决定。因此,让一些事务同步提交、另一些事务异步提交是可行且有用的。例如,当默认设置要求同步提交时,可以在一个包含多条语句的事务中执行SET LOCAL synchronous_commit TO OFF,使该事务异步提交。 - 概括了 synchronous_commit 各种设置具备的能力。 + 汇总了synchronous_commit各种设置具备的能力。
@@ -1839,9 +1759,9 @@ include_dir 'conf.d' synchronous_commit 设置 - 本地持久提交 - PG 崩溃备库持久提交 - OS 崩溃备库持久提交 + 本地提交持久性 + PG 崩溃后备库提交持久性 + OS 崩溃后备库提交持久性 备库查询一致性 @@ -1905,7 +1825,7 @@ include_dir 'conf.d' - 用来向强制 WAL 更新到磁盘的方法。如果fsync是关闭的,那么这个设置就不相关,因为 WAL 文件更新将根本不会被强制。可能的值是: + 用于将 WAL 更新强制写入磁盘的方法。如果fsync关闭,此设置就没有作用,因为 WAL 文件更新根本不会被强制写入磁盘。可选值为: @@ -1929,7 +1849,7 @@ include_dir 'conf.d' - fsync_writethrough(在每次提交时调用fsync(),强制任何磁盘写高速缓存的直通写) + fsync_writethrough(在每次提交时调用fsync(),强制穿透任何磁盘写缓存) @@ -1941,10 +1861,10 @@ include_dir 'conf.d' - open_* 选项也可以使用O_DIRECT(如果可用)。 + open_* 选项还会使用O_DIRECT(如果可用)。 不是在所有平台上都能使用所有这些选择。 - 默认值是列表中第一个被平台支持的那个, 不过fdatasync是 Linux和FreeBSD中的默认值。 - 默认值不一定是最理想的;有可能需要修改这个设置或系统配置的其他方面来创建一个崩溃-安全的配置,或达到最佳性能。 + 默认值是列表中第一个被平台支持的那个, 不过fdatasync是 Linux 和 FreeBSD 中的默认值。 + 默认值不一定最合适;可能需要更改此设置或系统配置的其他方面,以确保崩溃时的数据安全或达到最佳性能。 这些方面在中讨论。 这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 @@ -1959,11 +1879,11 @@ include_dir 'conf.d' - 当这个参数为打开时,PostgreSQL服务器在一个检查点之后的页面的第一次修改期间将每个页面的全部内容写到 WAL 中。这么做是因为在操作系统崩溃期间正在处理的一次页写入可能只有部分完成,从而导致在一个磁盘页面中混合有新旧数据。在崩溃后的恢复期间,通常存储在 WAL 中的行级改变数据不足以完全恢复这样一个页面。存储整页镜像可以保证页面被正确存储,但代价是增加了必须被写入 WAL 的数据量(因为 WAL 重放总是从一个检查点开始,所以在检查点后每个页面的第一次改变时这样做就够了。因此,一种减小全页面写开销的方法是增加检查点间隔参数值)。 + 启用此参数时,PostgreSQL服务器会在检查点之后首次修改每个磁盘页面时,将该页面的全部内容写入 WAL。这样做是因为,操作系统崩溃时正在进行的页面写入可能只完成了一部分,导致磁盘页面混有新旧数据。通常存储在 WAL 中的行级变更数据不足以在崩溃恢复时完整还原这样的页面。保存整页镜像能保证正确恢复页面,但会增加必须写入 WAL 的数据量。(由于 WAL 重放总是从检查点开始,只需在检查点之后首次修改每个页面时这样做。因此,减少整页写入开销的一种方法是增大检查点间隔参数。) - 把这个参数关闭会加快正常操作,但是在系统失败后可能导致不可恢复的数据损坏,或者静默的数据损坏。其风险类似于关闭fsync, 但是风险较小。并且只有在对该参数建议的相同情况下才应该关闭它。 + 关闭此参数可以加快正常操作,但系统故障后可能出现不可恢复的数据损坏或静默数据损坏。风险与关闭fsync类似,虽然较小,但也只有在该参数建议的相同情形下才应关闭此参数。 @@ -1986,7 +1906,7 @@ include_dir 'conf.d' - 当这个参数为on时,PostgreSQL服务器一个检查点之后页面被第一次修改期间把该磁盘页面的整个内容都写入 WAL,即使对所谓的提示位做非关键修改也会这样做。 + 当这个参数为on时,PostgreSQL服务器在检查点之后首次修改页面时把该磁盘页面的整个内容都写入 WAL,即使对所谓的提示位做非关键修改也会这样做。 @@ -2008,11 +1928,11 @@ include_dir 'conf.d' - 当这个参数为on时,PostgreSQL服务器在打开时或在基础备份期间,压缩写入WAL的整页镜像。在WAL回放期间将对压缩的页面镜像进行解压。默认值是off。只有超级用户能更改这个设置。 + 当这个参数为on时,PostgreSQL服务器在打开时或在基础备份期间,压缩写入WAL的整页镜像。在 WAL 重放期间将对压缩的整页镜像进行解压。默认值是off。只有超级用户能更改这个设置。 - 开启这个参数可以在不增加不可恢复的数据损坏风险的情况下减少WAL数据量,但代价是在WAL记录期间用于压缩以及在WAL回放期间用于解压的额外CPU开销。 + 开启此参数可以减少 WAL 数据量,而且不会增加不可恢复的数据损坏风险;代价是在记录 WAL 时压缩、重放 WAL 时解压会额外消耗一些 CPU。 @@ -2030,7 +1950,7 @@ include_dir 'conf.d' - 在每次事务提交时,WAL 缓冲区的内容被写出到磁盘,因此极大的值不可能提供显著的收益。不过,把这个值设置为几个兆字节可以在一个繁忙的服务器(其中很多客户端会在同一时间提交)上提高写性能。由默认设置 -1 选择的自动调节将在大部分情况下得到合理的结果。 + 在每次事务提交时,WAL 缓冲区的内容被写出到磁盘,因此极大的值不太可能带来显著收益。不过,把这个值设置为至少几个兆字节可以在一个繁忙的服务器(其中很多客户端会在同一时间提交)上提高写性能。由默认设置 -1 选择的自动调节将在大部分情况下得到合理的结果。 @@ -2078,18 +1998,18 @@ include_dir 'conf.d' - 设置commit_delay会在执行WAL刷新之前添加以微秒为单位的时间延迟。 + 设置commit_delay会在发起 WAL 刷盘之前添加以微秒为单位的时间延迟。 如果系统负载足够高,使得在给定时间间隔内有更多事务准备提交, - 这可以通过允许更多事务通过单个WAL刷新来提高组提交吞吐量。 - 然而,这也会增加延迟,最多为每个WAL刷新的commit_delay微秒。 - 因为如果没有其他事务准备提交,延迟就是浪费的,所以只有在至少有 - commit_siblings其他事务活动时才会执行延迟, - 当要启动刷新时,如果fsync被禁用,则不会执行延迟。 + 这可以通过允许更多事务通过一次 WAL 刷盘来提高组提交吞吐量。 + 不过,每次 WAL 刷盘的延迟也会因此增加,最多增加commit_delay微秒。 + 如果没有其他事务准备提交,等待就没有意义,因此仅当即将发起刷盘时至少还有 + commit_siblings个其他活动事务,才会等待。 + 此外,如果禁用了fsync,也不会等待。 默认commit_delay为零(无延迟)。 只有超级用户能更改这个设置。 - 在PostgreSQL的 9.3 发布之前,commit_delay的行为不同并且效果更差:它只影响提交,而不是所有 WAL 刷写,并且即使在 WAL 刷写马上就要完成时也会等待一整个配置的延迟。从PostgreSQL 9.3 中开始,第一个准备好刷写的进程会等待配置的间隔,而后续的进程只等到领先者完成刷写操作。 + 在PostgreSQL的 9.3 发布之前,commit_delay的行为不同并且效果更差:它只影响提交,而不是所有 WAL 刷写,并且即使 WAL 刷盘更早完成,也会等待整个配置的延迟时间。从PostgreSQL 9.3 开始,第一个准备好刷写的进程会等待配置的间隔,而后续的进程只等到领先者完成刷写操作。 @@ -2104,7 +2024,7 @@ include_dir 'conf.d' - 在执行commit_delay延迟时,要求的并发活动事务的最小数目。大一些的值会导致在延迟间隔期间更可能有至少另外一个事务准备好提交。默认值是五个事务。 + 执行commit_delay延迟前要求的并发活动事务的最小数目。大一些的值会导致在延迟间隔期间更可能有至少另外一个事务准备好提交。默认值是五个事务。 @@ -2124,7 +2044,7 @@ include_dir 'conf.d' 自动 WAL 检查点之间的最长时间,以秒为单位。 - 合理的范围在 30 秒到 1 天之间。默认是 5 分钟(5min)。增加这个参数的值会增加崩溃恢复所需的时间。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 + 合理的范围在 30 秒到 1 天之间。默认是 5 分钟(5min)。增加这个参数的值可能会增加崩溃恢复所需的时间。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 @@ -2153,7 +2073,7 @@ include_dir 'conf.d' 当执行检查点时写入的数据量超过checkpoint_flush_after字节时,就尝试强制 OS 把这些写发送到底层存储。 这样做将会限制内核页面高速缓存中的脏数据数量,降低在检查点末尾发出fsync或者 OS 在后台大批量写回数据时被卡住的可能性。 - 那常常会导致大幅度压缩的事务延迟,但是也有一些情况(特别是负载超过但小于 OS 页面高速缓存)的性能会降低。 + 这通常能显著降低事务延迟,但是也有一些情况(特别是负载超过但小于 OS 页面高速缓存)的性能会降低。 这种设置可能会在某些平台上没有效果。 合法的范围在0(禁用强制写回)和2MB之间。Linux 上的默认值是256kB,其他平台上是0(如果BLCKSZ不是8kB,则默认值和最大值会按比例缩放到它)。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 @@ -2224,10 +2144,9 @@ include_dir 'conf.d' 当启用archive_mode时,完成的WAL段会通过设置 - 发送到归档存储。除了off, - 要禁用,有两种模式:on和 + 发送到归档存储。除了用于禁用归档的off外,还有两种模式:onalways。在正常操作期间,这两种模式之间没有区别,但当设置为always时, - WAL归档程序在归档恢复或待机模式下也会被启用。在always模式下,从归档中恢复的所有文件 + WAL归档程序在归档恢复或备库模式下也会被启用。在always模式下,从归档中恢复的所有文件 或通过流复制传输的文件将被再次归档。详细信息请参见 @@ -2275,7 +2194,7 @@ include_dir 'conf.d' - 仅在完成的WAL段上调用。 + 只针对已完成的 WAL 段调用。 因此,如果您的服务器生成的WAL流量较少(或者在这样做时有间歇期),在事务完成和安全记录到归档存储之间可能会有很长的延迟。 为了限制未归档数据的年龄,您可以将archive_timeout设置为强制服务器定期切换到新的WAL段文件。 当此参数大于零时,只要自上次段文件切换以来经过了指定的秒数,并且存在任何数据库活动,包括单个检查点(如果没有数据库活动,则跳过检查点),服务器将切换到新的段文件。 @@ -2404,7 +2323,10 @@ include_dir 'conf.d' 主库 - 这些参数可以在发送复制数据给一个或多个备库的主库上设置。注意除了这些参数之外,在主库上必须设置合适的,并且也启用可选的 WAL 归档(见)。这些参数值与备库无关,尽管你可能希望为了准备好一个备库转变成主库来设置这些参数。 + 这些参数可以在向一个或多个备库发送复制数据的主库上设置。 + 除这些参数外,还必须在主库上适当设置 , + 也可以选择启用 WAL 归档(见 )。 + 这些参数在备库上的取值不影响备库运行,不过也可以预先设置,以备将来提升为主库。 @@ -2418,8 +2340,8 @@ include_dir 'conf.d' 所述,这个参数指定一个支持同步复制的备库的列表。 - 可能会有一个或者多个活动的同步备库,在这些备库确认收到它们的数据之后,等待提交的事务将被允许继续下去。 - 同步备库是那些名字出现在这个列表前面,并且当前已连接并且正在实时流式传输数据(如pg_stat_replication视图中streaming的状态所示)的服务器。 指定多于一台同步备库可以得到非常高的可用性并且能防止数据丢失。 @@ -2439,10 +2361,10 @@ ANY num_sync ( num_sync是事务需要等待其回复的同步备库的数量,standby_name是一个备库的名称。FIRST以及ANY指定从所列服务器中选取同步备库的方法。 - 关键词FIRST加上num_sync指定一种基于优先的同步复制,并且会让事务提交等待,直到它们的WAL记录被复制到基于优先级选择的num_sync台同步备库上为止。例如,设置FIRST 3 (s1, s2, s3, s4)将导致每次提交都等待来自三台较高优先级的备库的答复,这三台备库将从备库s1s2s3以及s4中选出。在该列表中出现较早的备库将被给予较高的优先级,并且将被考虑为同步备库。列表中出现的其他备库表示潜在的同步备库。如果当前的任何同步备库因为某种原因断开连接,它将立刻被下一个最高优先级的备库替代。关键词FIRST是可选的。 + 关键词FIRST加上num_sync指定一种基于优先级的同步复制,并且会让事务提交等待,直到它们的WAL记录被复制到基于优先级选择的num_sync台同步备库上为止。例如,设置FIRST 3 (s1, s2, s3, s4)将导致每次提交都等待来自三台较高优先级的备库的答复,这三台备库将从备库s1s2s3以及s4中选出。在该列表中出现较早的备库将被给予较高的优先级,并且将被考虑为同步备库。列表中出现的其他备库表示潜在的同步备库。如果当前的任何同步备库因为某种原因断开连接,它将立刻被下一个最高优先级的备库替代。关键词FIRST是可选的。 - 关键词ANY加上num_sync指定一种基于规定数量的同步复制,并且会让事务提交等待,直到它们的WAL记录被复制到所列出备库中的至少num_sync台上为止。例如,设置ANY 3 (s1, s2, s3, s4)将导致每次提交会在收到s1s2s3以及s4中任意三台备库的回答后立刻继续下去。 + 关键词ANY加上num_sync指定一种基于法定人数的同步复制,并且会让事务提交等待,直到它们的WAL记录被复制到所列出备库中的至少num_sync台上为止。例如,设置ANY 3 (s1, s2, s3, s4)将导致每次提交会在收到s1s2s3以及s4中任意三台备库的回答后立刻继续下去。 FIRSTANY是大小写不敏感的。如果这些关键词被用作备库的名字,其standby_name必须被放在双引号内。 @@ -2463,7 +2385,7 @@ ANY num_sync ( 参数设置为localoff。 + 如果这里没有指定同步备库名称,那么不启用同步复制并且事务提交将不会等待复制。这是默认的配置。即便当同步复制被启用时,个体事务也可以被配置为不等待复制,做法是将参数设置为localoff 这个参数只能在postgresql.conf文件中或通过服务器命令行进行设置。 @@ -2471,6 +2393,8 @@ ANY num_sync ( vacuum_defer_cleanup_age (integer) @@ -2494,8 +2418,7 @@ ANY num_sync ( @@ -2539,9 +2462,7 @@ ANY num_sync ( num_sync ( num_sync ( pg_stat_replication视图看到。 - 备库将报告它已经写入的上一个预写式日志位置、它已经刷到磁盘的上一个位置以及它已经应用的最后一个位置。 + 备库将报告最后写入的预写日志位置、最后刷盘的位置以及最后应用的位置。 这个参数的值是报告之间的最大间隔,以秒为单位。 - 每次写入或刷出位置改变时会发送状态更新,或者按这个参数的指定的频度发送。 + 每次写入或刷盘位置改变时会发送状态更新,或者至少按这个参数指定的频度发送。 因此,应用位置可能比真实位置略微滞后。 默认值是 10 秒。 将此参数设置为零会完全禁用状态更新。 @@ -2594,7 +2513,7 @@ ANY num_sync ( num_sync ( num_sync ( num_sync ( num_sync ( + + enable_bitmapscan (boolean) - 位图扫描 + 位图扫描 - enable_bitmapscan配置参数 + enable_bitmapscan 配置参数 - - 允许或禁止查询规划器使用位图扫描计划类型。默认值是on。 + 启用或禁用查询规划器对位图扫描计划类型的使用。默认值为 on - - + + - + + enable_gathermerge (boolean) - enable_gathermerge配置参数 + enable_gathermerge 配置参数 - - 启用或者禁用查询规划器对收集归并计划类型的使用。默认值是on。 + 启用或禁用查询规划器对收集归并计划类型的使用。默认值为 on - - + + - + + enable_hashagg (boolean) - enable_hashagg配置参数 + enable_hashagg 配置参数 - - 允许或禁用查询规划器使用哈希聚合计划类型。默认值是on。 + 启用或禁用查询规划器对哈希聚合计划类型的使用。默认值为 on - + + enable_hashjoin (boolean) - enable_hashjoin配置参数 + enable_hashjoin 配置参数 - - 允许或禁止查询规划器使用哈希连接计划类型。默认值是on。 + 启用或禁用查询规划器对哈希连接计划类型的使用。默认值为 on + + + + enable_indexscan (boolean) - 索引扫描 + 索引扫描 - enable_indexscan配置参数 + enable_indexscan 配置参数 - 允许或禁止查询规划器使用索引扫描计划类型。默认值是on。 + 启用或禁用查询规划器对索引扫描计划类型的使用。默认值为 on @@ -2814,21 +2735,22 @@ ANY num_sync ( enable_indexonlyscan (boolean) - enable_indexonlyscan配置参数 + enable_indexonlyscan 配置参数 - 允许或禁止查询规划器使用仅索引扫描计划类型(见)。默认值是on。 + 启用或禁用查询规划器对仅索引扫描计划类型的使用(参见 )。默认值为 on - + + enable_material (boolean) - enable_material配置参数 + enable_material 配置参数 @@ -2839,26 +2761,27 @@ ANY num_sync ( + + enable_mergejoin (boolean) - enable_mergejoin配置参数 + enable_mergejoin 配置参数 - - 允许或禁止查询规划器使用归并连接计划类型。默认值是on。 + 启用或禁用查询规划器对归并连接计划类型的使用。默认值为 on - + + enable_nestloop (boolean) - enable_nestloop配置参数 + enable_nestloop 配置参数 @@ -2884,17 +2807,17 @@ ANY num_sync ( + + enable_parallel_hash (boolean) - enable_parallel_hash配置参数 + enable_parallel_hash 配置参数 - - 允许或禁止查询规划器对并行哈希使用哈希连接计划类型。如果哈希连接计划也没有启用,这个参数没有效果。默认值是on。 + 启用或禁用查询规划器对使用并行哈希的哈希连接计划类型的使用。如果没有同时启用哈希连接计划,此参数不起作用。默认值为 on @@ -2914,17 +2837,19 @@ ANY num_sync ( enable_partitionwise_join (boolean) - enable_partitionwise_join配置参数 + enable_partitionwise_join 配置参数 - 允许或者禁止查询规划器使用面向分区的连接,这使得分区表之间的连接以连接匹配的分区的方式来执行。 - 面向分区的连接当前只适用于连接条件包括所有分区键的情况,分区键必须具有相同的数据类型,并且子分区集合必须完全匹配。 - 由于面向分区的连接规划在规划期间会使用可观的CPU时间和内存,所以默认值为off。 + 启用或禁用查询规划器对分区连接的使用,使分区表之间的连接可以通过连接相匹配的分区来完成。分区连接目前仅适用于连接条件包含所有分区键的情况;这些分区键必须具有相同的数据类型,并且子分区集合必须完全匹配。由于分区连接规划可能在规划期间使用明显更多的 CPU 时间和内存,默认值为 off @@ -2932,14 +2857,12 @@ ANY num_sync ( enable_partitionwise_aggregate (boolean) - enable_partitionwise_aggregate配置参数 + enable_partitionwise_aggregate 配置参数 - 启用或禁用查询规划器使用分区分组或聚合的功能,该功能允许在分区表上分别对每个分区执行分组或聚合操作。 - 如果GROUP BY子句不包括分区键,那么只能在每个分区的基础上执行部分聚合,并且必须在稍后进行最终化处理。 - 由于分区分组或聚合在规划期间可能会使用更多的CPU时间和内存,因此默认情况下为off。 + 启用或禁用查询规划器对分区分组或聚合的使用,使分区表上的分组或聚合可以在各个分区上分别执行。如果 GROUP BY 子句不包含分区键,则只能在各分区上执行部分聚合,随后还必须进行最终处理。由于分区分组或聚合可能在规划期间使用明显更多的 CPU 时间和内存,默认值为 off @@ -3389,7 +3312,7 @@ ANY num_sync ( parallel_leader_participation (boolean) - parallel_leader_participation 配置参数 + + parallel_leader_participation configuration + parameter + - + - 允许领导者进程执行GatherGather Merge节点之下的查询计划,而不是等待工作者进程。 - 默认值为on。将此值设置为off可以降低工作者因领导者读取元组不够快而阻塞的可能性, - 但也要求领导者进程等待工作者进程启动之后才能产生第一批元组。 - 领导者对性能的帮助或妨碍程度取决于计划类型、工作者数量和查询持续时间。 + 允许领导者进程执行 GatherGather Merge 节点下的查询计划,而不是等待工作进程。默认值为 on。将此值设置为 off,可以降低工作进程因领导者读取元组不够快而被阻塞的可能性,但在产生第一批元组之前,领导者进程必须等待工作进程启动。领导者对性能的帮助或妨碍程度取决于计划类型、工作进程数量和查询持续时间。 @@ -3532,7 +3459,7 @@ SELECT * FROM parent WHERE key = 2400; 更具体地说,将此值设置为on会在任何看起来可以安全并行的查询计划顶部添加一个Gather节点, - 让查询在并行工作者中运行。即使没有可用的并行工作者或无法使用并行工作者, + 让查询在并行工作进程中运行。即使没有可用的并行工作进程或无法使用并行工作进程, 在并行查询上下文中不允许的操作(例如启动子事务)也会被禁止,除非规划器认为这会使查询失败。 如果设置此选项后出现失败或意外结果,查询使用的某些函数可能需要被标记为PARALLEL UNSAFE (也可能是PARALLEL RESTRICTED)。 @@ -3540,14 +3467,13 @@ SELECT * FROM parent WHERE key = 2400; 将此值设置为regress具有设置为on的所有效果,另外还有一些旨在方便自动回归测试的效果。 - 通常,来自并行工作者的消息会包含一行说明这一点的上下文信息,但regress设置会抑制此行,使输出与非并行执行时相同。 + 通常,来自并行工作进程的消息会包含一行说明这一点的上下文信息,但regress设置会抑制此行,使输出与非并行执行时相同。 此外,此设置添加到计划中的Gather节点会在EXPLAIN输出中隐藏, 使输出与此设置为off时的输出一致。 - - + @@ -4035,7 +3961,7 @@ local0.* /var/log/postgresql - application_name可以是任意小于NAMEDATALEN个字符(标准编译中是 64 个字符)的字符串。这通常由一个应用通过到服务器的连接设置。该名称将被显示在pg_stat_activity视图中并被包括在 CSV 日志项中。它也会被通过包括在普通日志项中。只有可打印 ASCII 字符能被使用在application_name之中。其他字符将被替换为问号(?)。 + application_name可以是任意小于NAMEDATALEN个字符(标准编译中是 64 个字符)的字符串。应用通常在连接服务器时设置此值。该名称将被显示在pg_stat_activity视图中并被包括在 CSV 日志项中。它也会被通过包括在普通日志项中。只有可打印 ASCII 字符能被使用在application_name之中。其他字符将被替换为问号(?)。 @@ -4114,7 +4040,7 @@ local0.* /var/log/postgresql - 某些客户端程序(例如psql)在要求密码时会尝试连接两次,因此重复的收到连接消息并不一定表示一个错误。 + 某些客户端程序(例如psql)在判断是否需要密码时会尝试连接两次,因此重复的收到连接消息并不一定表示一个错误。 @@ -4310,7 +4236,7 @@ local0.* /var/log/postgresql %% - 纯文字 % + 字面字符 % @@ -4334,7 +4260,7 @@ FROM pg_stat_activity; - Syslog产生自己的时间戳和进程 ID 信息,因此如果你记录到syslog你可能不希望包括哪些转义。 + Syslog产生自己的时间戳和进程 ID 信息,因此如果你记录到syslog你可能不希望包括那些转义。 @@ -4579,13 +4505,14 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; 运行时统计数据 - 累积查询和索引统计 + 查询和索引统计信息收集器 - 这些参数控制服务器范围内的累积统计系统。 - 启用后,收集的数据可以通过pg_statpg_statio - 系列系统视图进行访问。有关更多信息,请参阅。 - + 这些参数控制服务器范围内的统计信息收集功能。 + 启用统计信息收集后,产生的数据可以通过pg_stat和 + pg_statio系列系统视图进行访问。 + 更多信息请参阅。 + @@ -4765,7 +4692,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 注意即使该参数被禁用,系统也会在需要防止事务ID回卷时发起清理进程。详情请见。 + 注意即使该参数被禁用,系统也会在需要防止事务ID回卷时发起自动清理进程。详情请见 @@ -4810,7 +4737,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 指定自动清理在任意给定数据库上运行的最小延迟。在每一轮中后台进程检查数据库并根据需要为数据库中的表发出VACUUMANALYZE命令。 + 指定自动清理在任意给定数据库上各次运行之间的最小间隔。在每一轮中后台进程检查数据库并根据需要为数据库中的表发出VACUUMANALYZE命令。 延迟以秒为单位。默认值为1分钟(1min)。该参数只能在postgresql.conf文件或在服务器命令行上设置。 @@ -4931,7 +4858,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 指定用于自动VACUUM操作中的代价限制值。如果指定-1(默认值),则使用值。注意该值被按比例地分配到运行中的自动清理工作者上(如果有多个),因此每一个工作者的限制值之和不会超过这个变量中的值。该参数只能在postgresql.conf文件或在服务器命令中设置。但是对个别表可以通过修改表存储参数来覆盖该设置。 + 指定用于自动VACUUM操作中的代价限制值。如果指定-1(默认值),则使用值。注意该值被按比例地分配到运行中的自动清理工作进程上(如果有多个),因此每一个工作进程的限制值之和不会超过这个变量中的值。该参数只能在postgresql.conf文件或在服务器命令中设置。但是对个别表可以通过修改表存储参数来覆盖该设置。 @@ -4975,7 +4902,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; search_path配置参数 - pathfor schemas + 路径用于模式 @@ -5049,7 +4976,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; default_tablespace配置参数 - tablespacedefault + 表空间默认 @@ -5126,7 +5053,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; default_transaction_isolation (enum) - transaction isolation level + 事务隔离级别 设置默认值 @@ -5149,7 +5076,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; default_transaction_read_only (boolean) - read-only transaction + 只读事务 设置默认值 @@ -5171,7 +5098,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; default_transaction_deferrable (boolean) - deferrable transaction + 可延迟事务 设置默认值 @@ -5197,7 +5124,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; transaction_isolation (enum) - transaction isolation level + 事务隔离级别 transaction_isolation配置参数 @@ -5217,7 +5144,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; transaction_read_only (boolean) - read-only transaction + 只读事务 transaction_read_only 配置参数 @@ -5237,7 +5164,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; transaction_deferrable (boolean) - deferrable transaction + 可延迟事务 transaction_deferrable 配置参数 @@ -5353,7 +5280,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 当表的pg_class.relfrozenxid字段达到该设置指定的年龄时,VACUUM会执行激进扫描。激进扫描与常规VACUUM不同,它会访问每一个可能包含未冻结 XID 或 MXID 的页面,而不仅仅是那些可能包含死元组的页面。默认值是 1.5 亿个事务。尽管用户可以将该值设置为 0 到 20 亿之间的任意值,VACUUM会悄悄将有效值调整为的 95%,从而在触发防回卷 autovacuum 之前仍有机会执行一次常规手工VACUUM。更多信息请参见。 + 当表的pg_class.relfrozenxid字段达到该设置指定的年龄时,VACUUM会执行激进扫描。激进扫描与常规VACUUM不同,它会访问每一个可能包含未冻结 XID 或 MXID 的页面,而不仅仅是那些可能包含死元组的页面。默认值是 1.5 亿个事务。尽管用户可以将该值设置为 0 到 20 亿之间的任意值,VACUUM会悄悄将有效值限制为不超过的 95%,从而在触发防回卷 autovacuum 之前仍有机会执行一次常规手工VACUUM。更多信息请参见 @@ -5366,7 +5293,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 指定VACUUM在扫描表时用来决定是否冻结行版本的切断年龄(以事务计)。默认值是 5000 万个事务。尽管用户可以将该值设置为 0 到 10 亿之间的任意值,VACUUM会悄悄将有效值调整为的一半,这样强制 autovacuum 之间就不会间隔过短。更多信息请参见。 + 指定VACUUM在扫描表时用来决定是否冻结行版本的切断年龄(以事务计)。默认值是 5000 万个事务。尽管用户可以将该值设置为 0 到 10 亿之间的任意值,VACUUM会悄悄将有效值限制为不超过的一半,这样强制 autovacuum 之间就不会间隔过短。更多信息请参见 @@ -5379,7 +5306,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 当表的pg_class.relminmxid字段达到该设置指定的年龄时,VACUUM会执行激进扫描。激进扫描与常规VACUUM不同,它会访问每一个可能包含未冻结 XID 或 MXID 的页面,而不是只扫描那些可能包含死元组的页面。默认值是 1.5 亿个多事务。尽管用户可以将该值设置为 0 到 20 亿之间的任意值,VACUUM会悄悄将有效值调整为的 95%,从而在触发防回卷 autovacuum 之前仍有机会执行一次常规手工VACUUM。更多信息请参见。 + 当表的pg_class.relminmxid字段达到该设置指定的年龄时,VACUUM会执行激进扫描。激进扫描与常规VACUUM不同,它会访问每一个可能包含未冻结 XID 或 MXID 的页面,而不是只扫描那些可能包含死元组的页面。默认值是 1.5 亿个多事务。尽管用户可以将该值设置为 0 到 20 亿之间的任意值,VACUUM会悄悄将有效值限制为不超过的 95%,从而在触发防回卷 autovacuum 之前仍有机会执行一次常规手工VACUUM。更多信息请参见 @@ -5392,7 +5319,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 指定VACUUM在扫描表时用来决定是否将 multixact ID 替换为较新的事务 ID 或 multixact ID 的切断年龄(以 multixact 计)。默认值是 5000 万个 multixact。尽管用户可以将该值设置为 0 到 10 亿之间的任意值,VACUUM会悄悄将有效值调整为的一半,这样强制 autovacuum 之间就不会间隔过短。更多信息请参见。 + 指定VACUUM在扫描表时用来决定是否将多事务 ID 替换为较新的事务 ID 或多事务 ID 的切断年龄(以多事务计)。默认值是 500 万个多事务。尽管用户可以将该值设置为 0 到 10 亿之间的任意值,VACUUM会悄悄将有效值限制为不超过的一半,这样强制 autovacuum 之间就不会间隔过短。更多信息请参见 @@ -5470,7 +5397,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; SET XML OPTION - XML option + XML 选项 @@ -5549,7 +5476,7 @@ SET XML OPTION { DOCUMENT | CONTENT }; TimeZone配置参数 - time zone + 时区 @@ -5565,7 +5492,7 @@ SET XML OPTION { DOCUMENT | CONTENT }; timezone_abbreviations配置参数 - time zone names + 时区名称 @@ -5578,11 +5505,11 @@ SET XML OPTION { DOCUMENT | CONTENT }; extra_float_digits (integer) - significant digits + 有效数字 - floating-point - display + 浮点数 + 显示 extra_float_digits配置参数 @@ -5604,7 +5531,7 @@ SET XML OPTION { DOCUMENT | CONTENT }; client_encoding配置参数 - character set + 字符集 @@ -5922,12 +5849,12 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' deadlock_timeout (integer) - deadlock + 死锁 期间超时 - timeout - deadlock + 超时 + 死锁 deadlock_timeout配置参数 @@ -5960,12 +5887,11 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' 共享锁表跟踪在max_locks_per_transaction * ( + ) 个对象(如表)上的锁。因此,在任何一个时刻,只有不超过这么多个可区分对象能够被锁住。这个参数控制为每个事务分配的对象锁的平均数量。个体事务可以锁住更多对象,数量可以和锁表中能容纳的所有事务的锁一样多。这是能被锁住的行数,那个值是没有限制的。默认值 64 已经被历史证明是足够的,但是如果你有需要在一个事务中使用很多不同表的查询(例如查询一个有很多子表的父表),你可能需要提高这个值。这个参数只能在服务器启动时设置。 + linkend="guc-max-prepared-transactions"/>) 个对象(如表)上的锁。因此,在任何一个时刻,只有不超过这么多个可区分对象能够被锁住。这个参数控制为每个事务分配的对象锁的平均数量。只要所有事务的锁都能放入锁表中,单个事务就可以锁住更多对象。这是能被锁住的行数,那个值是没有限制的。默认值 64 已经被历史证明是足够的,但是如果你有需要在一个事务中使用很多不同表的查询(例如查询一个有很多子表的父表),你可能需要提高这个值。这个参数只能在服务器启动时设置。 - 当运行一个备库时,你必须设置这个参数等于或大于主库上的参数。 - 否则,备库上将不允许查询。 + 运行备库时,必须将此参数设置为大于或等于主库上的值。否则,备库上将不允许查询。 @@ -5982,7 +5908,7 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' 共享谓词锁表跟踪在max_pred_locks_per_transaction * ( + ) 个对象(如表)上的锁。因此,在任何一个时刻,只有不超过这么多个可区分对象能够被锁住。这个参数控制为每个事务分配的对象锁的平均数量。个体事务可以锁住更多对象,数量可以和锁表中能容纳的所有事务的锁一样多。这是能被锁住的行数,那个值是没有限制的。默认值 64 已经在测试中被证明通常是足够的,但是如果你有需要在一个可串行化事务中使用很多不同表的查询(例如查询一个有很多子表的父表),你可能需要提高这个值。这个参数只能在服务器启动时设置。 + linkend="guc-max-prepared-transactions"/>) 个对象(如表)上的锁。因此,在任何一个时刻,只有不超过这么多个可区分对象能够被锁住。这个参数控制为每个事务分配的对象锁的平均数量。只要所有事务的锁都能放入锁表中,单个事务就可以锁住更多对象。这是能被锁住的行数,那个值是没有限制的。默认值 64 已经在测试中被证明通常是足够的,但是如果你有会在单个可串行化事务中访问许多不同表的客户端,则可能需要提高这个值。这个参数只能在服务器启动时设置。 @@ -6049,7 +5975,7 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' backslash_quote (enum) - stringsbackslash quotes + 字符串反斜线引号 backslash_quote配置参数 @@ -6090,7 +6016,7 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' escape_string_warning (boolean) - strings转义警告 + 字符串转义警告 escape_string_warning配置参数 @@ -6165,7 +6091,7 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' standard_conforming_strings (boolean) - stringsstandard conforming + 字符串标准符合 standard_conforming_strings配置参数 @@ -6384,6 +6310,8 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' + + lc_collate (string) @@ -6398,6 +6326,8 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' + + lc_ctype (string) @@ -6478,7 +6408,7 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' server_encoding配置参数 - character set + 字符集 @@ -6673,6 +6603,8 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' + + trace_recovery_messages (enum) diff --git a/zh/11/datatype.sgml b/zh/11/datatype.sgml index 8dc2b79d..f567c21f 100644 --- a/zh/11/datatype.sgml +++ b/zh/11/datatype.sgml @@ -341,19 +341,19 @@ smallint 2字节 小范围整数 - -32768 to +32767 + -32768 到 +32767 integer 4字节 整数的典型选择 - -2147483648 to +2147483647 + -2147483648 到 +2147483647 bigint 8字节 大范围整数 - -9223372036854775808 to +9223372036854775807 + -9223372036854775808 到 +9223372036854775807 @@ -696,7 +696,10 @@ FROM generate_series(-3.5, 3.5, 1) as x; - 本节描述的是 PostgreSQL 特有的创建自动递增列的方法。另一种方法是使用 SQL 标准的标识列特性,参见 + + 本节介绍 PostgreSQL 特有的自动递增列创建方法。 + 另一种方法是使用 SQL 标准的标识列特性,参见。 + @@ -774,7 +777,7 @@ ALTER SEQUENCE tablename_money 类型以固定的小数精度存储货币金额; 参见 。小数精度由数据库的 设置决定。表中显示的范围假定 - 有两位小数。输入支持多种格式,包括整数和浮点文字,以及典型的 + 有两位小数。输入支持多种格式,包括整数字面量和浮点数字面量,以及典型的 货币格式,例如 '$1,000.00'。输出通常也采用 后一种形式,但会受到区域设置影响。 @@ -1172,7 +1175,7 @@ SELECT '\xDEADBEEF'::bytea;
- <type>bytea</type>文字转义字节 + <type>bytea</type>字面量中需要转义的字节 @@ -3618,17 +3621,16 @@ a0ee-bc99-9c0b-4ef8-bb6d-6bb9-bd38-0a11 xml 数据类型可用于存储 XML 数据。与把 XML 数据存储在 - text 字段中相比,它的优势在于会检查输入值是否格式 - 良好,并且提供了可执行类型安全操作的支持函数;见 - 。使用该数据类型要求安装时启用 + text 字段中相比,它的优势在于会检查输入值的良构性,并且提供了可执行类型安全操作的支持函数;见 + 。使用该数据类型要求构建时使用 configure --with-libxml - xml 类型既可以存储符合 XML 标准定义的格式良好的 + xml 类型既可以存储 XML 标准所定义的良构 文档,也可以存储 内容 片段;后者是参照 XQuery 和 XPath 数据模型中更宽松的 - document node + 文档节点 概念来定义的。粗略地说,这意味着内容片段可以拥有多个顶层元素或字符 节点。表达式 xmlvalue IS DOCUMENT @@ -3778,7 +3780,7 @@ SET xmloption TO { DOCUMENT | CONTENT }; - 是一种用户定义的数据类型,它基于另一种底层类型。根据需要,它可以有约束来限制其有效值为底层类型所允许值的一个子集。如果没有约束,它的行为就和底层类型一样 — 例如,任何适用于底层类型的操作符或函数都对该域类型有效。底层类型可以是任何内置或者用户定义的基础类型、枚举类型、数组类型、复合类型、范围类型或者另一个域。 + 是一种用户定义的数据类型,它基于另一种底层类型。根据需要,它可以有约束来限制其有效值为底层类型所允许值的一个子集。除此之外,它的行为与底层类型相同 — 例如,任何适用于底层类型的操作符或函数都对该域类型有效。底层类型可以是任何内置或者用户定义的基础类型、枚举类型、数组类型、复合类型、范围类型或者另一个域。 diff --git a/zh/11/dblink.sgml b/zh/11/dblink.sgml index bdcd607c..70ea13cd 100644 --- a/zh/11/dblink.sgml +++ b/zh/11/dblink.sgml @@ -7,9 +7,13 @@ dblink - dblink模块支持在一个数据库会话中连接到其他PostgreSQL数据库。 + + dblink 是一个支持在数据库会话内连接到其他 PostgreSQL 数据库的模块。 + - 另请参阅,它使用更现代、符合标准的基础设施提供了大致相同的功能。 + + 另请参见 ,它使用更现代且更符合标准的基础设施提供了基本相同的功能。 + @@ -91,7 +95,7 @@ dblink_connect(text connname, text connstr) returns text 注解 - 如果不可信用户能够访问一个尚未采用模式的安全使用方式的数据库,则应在每个会话开始时从 + 如果不受信任的用户能够访问一个尚未采用模式的安全使用方式的数据库,则应在每个会话开始时从 search_path 中移除公共可写模式。例如,可以把 options=-csearch_path= 加到 connstr 中。这个注意事项并非 dblink 所特有;它适用于每一种执行任意 SQL 命令的接口。 @@ -125,9 +129,9 @@ SELECT dblink_connect('myconn', 'dbname=postgres options=-csearch_path='); OK (1 row) --- FOREIGN DATA WRAPPER functionality --- Note: local connection must require password authentication for this to work properly --- Otherwise, you will receive the following error from dblink_connect(): +-- FOREIGN DATA WRAPPER 功能 +-- 注意:要使本例正常工作,本地连接必须要求密码认证。 +-- 否则,dblink_connect() 将报告以下错误: -- ---------------------------------------------------------------------- -- ERROR: password is required -- DETAIL: Non-superuser cannot connect if the server does not request a password. @@ -143,13 +147,13 @@ GRANT SELECT ON TABLE foo TO regress_dblink_user; \set ORIGINAL_USER :USER \c - regress_dblink_user SELECT dblink_connect('myconn', 'fdtest'); - dblink_connect + dblink_connect ---------------- OK (1 row) SELECT * FROM dblink('myconn', 'SELECT * FROM foo') AS t(a int, b text, c text[]); - a | b | c + a | b | c ----+---+--------------- 0 | a | {a0,b0,c0} 1 | b | {a1,b1,c1} @@ -391,7 +395,7 @@ SELECT * WHERE proname LIKE 'bytea%'; - FROM 子句中的 alias 部分必须指定该函数将返回的列名和类型。(在别名中指定列名实际上是标准 SQL 语法,但指定列类型则是 + FROM 子句中的 别名 部分必须指定该函数将返回的列名和类型。(在别名中指定列名实际上是标准 SQL 语法,但指定列类型则是 PostgreSQL 的扩展。)这样系统才能在尝试执行该函数之前,就知道 * 应展开成什么,以及 WHERE 子句中的 proname 指的是什么。运行时,如果远程数据库返回的实际查询结果与 diff --git a/zh/11/dfunc.sgml b/zh/11/dfunc.sgml index 03dc5633..07a5e916 100644 --- a/zh/11/dfunc.sgml +++ b/zh/11/dfunc.sgml @@ -1,7 +1,7 @@ - 编译和链接动态载入的函数 + 编译和链接动态装载函数 在你能够使用以 C 编写的 PostgreSQL 扩展函数之前, @@ -46,7 +46,7 @@ FreeBSD - FreeBSDshared library + FreeBSD共享库 @@ -64,7 +64,7 @@ gcc -shared -o foo.so foo.o HP-UX - HP-UXshared library + HP-UX共享库 @@ -91,7 +91,7 @@ ld -b -o foo.sl foo.o Linux - Linuxshared library + Linux共享库 @@ -108,7 +108,7 @@ cc -shared -o foo.so foo.o macOS - macOSshared library + macOS共享库 @@ -124,7 +124,7 @@ cc -bundle -flat_namespace -undefined suppress -o foo.so foo.o NetBSD - NetBSDshared library + NetBSD共享库 @@ -142,7 +142,7 @@ gcc -shared -o foo.so foo.o OpenBSD - OpenBSDshared library + OpenBSD共享库 @@ -159,7 +159,7 @@ ld -Bshareable -o foo.so foo.o Solaris - Solarisshared library + Solaris共享库 diff --git a/zh/11/diskusage.sgml b/zh/11/diskusage.sgml index b7220f3f..1baf1dac 100644 --- a/zh/11/diskusage.sgml +++ b/zh/11/diskusage.sgml @@ -15,15 +15,15 @@ - 每个表都有一个主堆磁盘文件,其中存储了大部分数据。如果该表有任何值可能较宽的列,还可能会有一个与该表关联的TOAST文件,用于存储宽到无法方便地放入主表中的值(见)。如果存在,还会在TOAST表上有一个有效索引。也可能会有与基表关联的索引。每个表和索引都存储在单独的磁盘文件中 — 如果文件会超过 1 GB,则可能分成多个文件。这些文件的命名约定见。 - + 每个表都有一个主堆磁盘文件,大部分数据都存储在那里。如果表中有任何列可能包含较宽的值,还可能有一个与该表关联的 TOAST 文件,用于存储那些不适合放在主表中的过宽值(参见)。如果该 TOAST 表存在,则它会有一个有效索引。基础表本身也可能带有索引。每个表和索引都存储在单独的磁盘文件中;如果某个文件会超过 1 GB,则可能拆分为多个文件。关于这些文件的命名规则,请参见。 + - 可以通过三种方式监控磁盘空间:使用中列出的 SQL 函数,使用模块,或者手工检查系统目录。SQL 函数最容易使用,通常也是推荐的方法。本节其余部分展示如何通过检查系统目录来完成此事。 - + 你可以通过三种方式监控磁盘空间:使用中列出的 SQL 函数、使用模块,或者手工检查系统目录。SQL 函数最容易使用,通常也是推荐的方法。本节余下内容展示如何通过检查系统目录来完成这项工作。 + - 在最近做过 vacuum 或 analyze 的数据库上使用psql时,可以发出查询以查看任意表的磁盘使用情况: + 在最近进行过清理或分析 的数据库上使用 psql,你可以发出查询来查看任意表的磁盘使用情况: SELECT pg_relation_filepath(oid), relpages FROM pg_class WHERE relname = 'customer'; @@ -32,11 +32,11 @@ SELECT pg_relation_filepath(oid), relpages FROM pg_class WHERE relname = 'custom base/16384/16806 | 60 (1 row) - 每个页通常为 8 KB。(请记住,relpages只会由VACUUMANALYZE以及少数 DDL 命令(如CREATE INDEX)更新。)如果你想直接检查该表的磁盘文件,文件路径名就很有用。 - + 每一页通常是 8 KB。(请记住,relpages 只会由 VACUUMANALYZE 以及少数 DDL 命令如 CREATE INDEX 更新。)如果你想直接检查该表的磁盘文件,那么文件路径名会很有用。 + - 要显示TOAST表使用的空间,可使用如下查询: + 要显示 TOAST 表使用的空间,可以使用如下查询: SELECT relname, relpages FROM pg_class, @@ -54,7 +54,7 @@ ORDER BY relname; pg_toast_16806 | 0 pg_toast_16806_index | 1 - + 也可以轻松显示索引大小: SELECT c2.relname, c2.relpages @@ -71,7 +71,7 @@ ORDER BY c2.relname; - 利用这些信息,可以很容易找出最大的表和索引: + 利用这些信息,你可以很容易地找出最大的表和索引: SELECT relname, relpages FROM pg_class @@ -82,28 +82,28 @@ ORDER BY relpages DESC; bigtable | 3290 customer | 3144 - + 磁盘已满故障 - 数据库管理员最重要的磁盘监控任务,是确保磁盘不会被写满。数据盘被写满不会导致数据损坏,但可能使有用的活动无法继续进行。如果存放 WAL 文件的磁盘逐渐被写满,数据库服务器可能会进入 panic 状态并随后关闭。 - + 数据库管理员最重要的磁盘监控任务,是确保磁盘不会被写满。数据磁盘写满不会导致数据损坏,但可能会阻止有用的活动继续进行。如果保存 WAL 文件的磁盘被写满,则数据库服务器可能会 panic 并随后关闭。 + - 如果无法通过删除其他内容来释放磁盘上的额外空间,可以利用表空间将部分数据库文件移到其他文件系统上。有关更多信息,请参见。 - + 如果你无法通过删除其他文件来释放更多磁盘空间,那么可以利用表空间把部分数据库文件移动到其他文件系统上。详见。 + - 有些文件系统在接近写满时性能很差,因此不要等到磁盘完全写满才采取措施。 - + 有些文件系统在接近写满时性能会明显变差,因此不要等到磁盘完全写满才采取措施。 + - 如果系统支持按用户设置磁盘配额,那么数据库自然会受限于运行服务器的那个用户所被施加的配额。超出配额与磁盘空间完全耗尽会产生同样的不良影响。 - + 如果你的系统支持按用户设置磁盘配额,那么数据库自然也会受到运行服务器的那个用户所拥有配额的限制。超出配额会带来与磁盘空间完全耗尽相同的不良影响。 + diff --git a/zh/11/docguide.sgml b/zh/11/docguide.sgml index afb14ca5..1a5feed2 100644 --- a/zh/11/docguide.sgml +++ b/zh/11/docguide.sgml @@ -230,18 +230,25 @@ checking for dbtoepub... dbtoepub 这也是默认目标。输出位于子目录html中。 - 要生成 HTML 文档,并采用以下站点使用的样式表:postgresql.org,以替代默认的简单样式,请使用: + + 若要使用postgresql.org上所使用的样式表, + 而不是默认的简单样式来生成 HTML 文档,请使用: + doc/src/sgml$ make STYLE=website html + 手册页 - 我们使用 DocBook XSL 样式表转换DocBook - refentry页面,生成适用于手册页的 *roff 输出。要创建手册页,请使用以下命令: + + 我们使用 DocBook XSL 样式表将DocBook + refentry页面转换为适合手册页的 *roff 输出。 + 要创建手册页,请使用以下命令: + doc/src/sgml$ make man @@ -250,16 +257,24 @@ checking for dbtoepub... dbtoepub PDF - 要生成 PDF 格式的文档,可以使用FOP,并根据所需纸张格式,选择以下命令之一: + + 要使用FOP生成文档的 PDF 版本, + 可根据所偏好的纸张格式使用下列命令之一: + + - 对于 A4 格式: + + 对于 A4 格式: + doc/src/sgml$ make postgres-A4.pdf - 对于美国信纸格式: + + 对于美国信纸格式: + doc/src/sgml$ make postgres-US.pdf @@ -267,30 +282,49 @@ checking for dbtoepub... dbtoepub - 由于 PostgreSQL 文档相当庞大,FOP需要大量内存。因此,在某些系统上,构建会失败并报告与内存有关的错误。通常可以通过在以下配置文件中调整 Java 堆设置来解决此问题:~/.foprc,例如: -# FOP binary distribution + + 由于 PostgreSQL 文档相当庞大,FOP需要占用相当多的内存。 + 因此,在某些系统上,构建会因内存相关错误而失败。这通常可以通过在配置文件 + ~/.foprc中配置 Java 堆设置来解决,例如: + +# FOP 二进制发行版 FOP_OPTS='-Xmx1500m' # Debian JAVA_ARGS='-Xmx1500m' # Red Hat ADDITIONAL_FLAGS='-Xmx1500m' -所需内存存在一个最低限度,而在一定范围内,更多内存似乎能使构建稍快一些。在内存很少(不足 1 GB)的系统上,构建要么因交换而非常缓慢,要么根本无法进行。 + + 所需内存存在一个最低门槛,而且在一定程度上,内存越多似乎会让构建稍快一些。 + 对于内存很少(小于 1 GB)的系统,构建要么会因交换而非常缓慢,要么根本无法工作。 + - 其他 XSL-FO 处理器也可以手动使用,但自动构建过程只支持 FOP。 + + + 也可以手工使用其他 XSL-FO 处理器,但自动化构建过程只支持 FOP。 + 纯文本文件 - 安装说明也以纯文本形式分发,以便在没有更好阅读工具的情况下使用。INSTALL文件对应于,仅为适应不同语境作了一些小改动。要重新创建该文件,请切换到doc/src/sgml目录并输入make INSTALL + + 安装说明也以纯文本形式分发,以便在没有更好的阅读工具时使用。 + INSTALL文件对应,并针对不同语境作了少量调整。 + 要重新生成该文件,请切换到doc/src/sgml目录,然后输入make INSTALL。 + - 过去,发布说明和回归测试说明也以纯文本形式分发,但这种做法已经停止。 + + 过去,发行说明和回归测试说明也曾以纯文本形式分发,但现已停止这种做法。 + 语法检查 - 构建文档可能耗时很长。但有一种方法可以只检查文档文件的语法是否正确,只需几秒钟: + + 构建文档可能非常耗时。但有一种方法可以只检查文档文件的语法是否正确, + 这只需要几秒钟: + doc/src/sgml$ make check diff --git a/zh/11/ecpg.sgml b/zh/11/ecpg.sgml index 4c0406e5..b11d5f26 100644 --- a/zh/11/ecpg.sgml +++ b/zh/11/ecpg.sgml @@ -1016,7 +1016,7 @@ oid=313780, datname=testdb, size=8183012 - 结构体主变量将列尽数吸收成结构体的域。额外的列可以被分配给其他主变量。例如,上面的程序也可以使用结构体外部的size变量重新构造: + 结构体主变量吸收的列数与结构体的字段数相同。额外的列可以被分配给其他主变量。例如,上面的程序也可以使用结构体外部的size变量改写: EXEC SQL BEGIN DECLARE SECTION; typedef struct @@ -1280,7 +1280,7 @@ while (1) 用户定义的基础类型 - ECPG 并不直接支持新的用户定义的基本类型。你可以使用外部字符串表示以及类型char[]VARCHAR[]的主变量,并且这种方案事实上对很多类型都是合适和足够的。 + ECPG 并不直接支持新的用户定义的基础类型。你可以使用外部字符串表示以及类型char[]VARCHAR[]的主变量,并且这种方案事实上对很多类型都是合适和足够的。 下面的示例使用数据类型 complex,它来自 中的示例。该类型的外部字符串表示为 (%f,%f),由函数 complex_in()complex_out() 定义,见 。以下示例将复数类型的值 (1,1)(3,3) 分别插入列 ab,然后从表中查询它们。 @@ -4448,7 +4448,7 @@ EXEC SQL INCLUDE "filename"; 当前目录 /usr/local/include - PostgreSQL 的包括目录,在编译时定义(例如/usr/local/pgsql/include + PostgreSQL 的头文件目录,在编译时定义(例如/usr/local/pgsql/include /usr/include @@ -5162,7 +5162,7 @@ DATABASE connection_target 使用 user_name/passworduser_name IDENTIFIED BY password或者 - user_name USING password之一,这个参数也能指定用户名和密码. + user_name USING password之一,这个参数也能指定用户名和密码。 @@ -7167,19 +7167,19 @@ int rjulmdy(date d, short mdy[3]); rdefmtdate - 使用格式掩码将字符字符串转换为日期类型的值。 + 使用格式掩码将字符串转换为日期类型的值。 int rdefmtdate(date *d, char *fmt, char *str); 该函数接收一个指向应该保存操作结果的日期值的指针(d), 用于解析日期的格式掩码(fmt)和包含日期文本表示的C char*字符串 (str)。文本表示应与格式掩码匹配。但是,你不需要将字符串 - 与格式掩码进行一一映射。该函数仅分析顺序顺序,并查找表示年份位置的文字 + 与格式掩码进行一一映射。该函数只分析先后顺序,并查找表示年份位置的字面文本 yyyyyy,表示月份位置的mm 和表示日期位置的dd - 该函数返回以下值: + 该函数返回以下值: diff --git a/zh/11/event-trigger.sgml b/zh/11/event-trigger.sgml index ca40cdfa..28455902 100644 --- a/zh/11/event-trigger.sgml +++ b/zh/11/event-trigger.sgml @@ -20,11 +20,11 @@ - 事件触发器行为概览 + 事件触发器行为概述 只要与事件触发器关联的事件在其定义所在数据库中发生,事件触发器就会被触发。 - 目前唯一支持的事件有 + 目前仅支持以下事件: ddl_command_startddl_command_endtable_rewrite @@ -39,14 +39,14 @@ COMMENTGRANTREVOKE 命令即将执行之前。在事件触发器触发之前,不会检查受影响对象究竟存在还是不存在。 但有一个例外:对于以共享对象 — 数据库、角色和表空间 — - 为目标的 DDL 命令,或者针对事件触发器本身的命令,不会发生该事件。事件触发器机制 + 为目标的 DDL 命令或者针对事件触发器本身的命令,不会发生该事件。事件触发器机制 不支持这些对象类型。 ddl_command_start 也会在 SELECT INTO 命令即将执行之前发生,因为它等价于 CREATE TABLE AS - ddl_command_end 事件发生在与上述同一组命令执行之后。 + ddl_command_end 事件发生在上述同一组命令执行之后。 要获取这些 DDL 操作的更多细节,可在 ddl_command_end 事件触发器代码中使用集合返回函数 pg_event_trigger_ddl_commands()(见 @@ -1049,7 +1049,7 @@ CALLED_AS_EVENT_TRIGGER(fcinfo) ((fcinfo)->context != NULL && IsA((fcinfo)->context, EventTriggerData)) - 如果该宏返回 true,那么就可以安全地将 fcinfo->context + 如果该宏返回真,那么就可以安全地将 fcinfo->context 转换为 EventTriggerData * 类型,并使用它所指向的 EventTriggerData 结构体。该函数 不得修改 EventTriggerData @@ -1115,7 +1115,7 @@ typedef struct EventTriggerData 事件触发器函数必须返回一个 NULL 指针 (不是 SQL 空值,也就是不要将 - isNull 设为 true)。 + isNull 设为真)。 @@ -1162,7 +1162,9 @@ noddl(PG_FUNCTION_ARGS) ]]> - 编译源代码后(见),声明函数和触发器: + + 编译源代码之后(见 ),声明该函数和触发器: + CREATE FUNCTION noddl() RETURNS event_trigger AS 'noddl' LANGUAGE C; @@ -1171,7 +1173,9 @@ CREATE EVENT TRIGGER noddl ON ddl_command_start - 现在可以测试触发器的工作情况: + + 现在可以测试该触发器的工作情况: + =# \dy List of event triggers Name | Event | Owner | Enabled | Function | Tags @@ -1206,7 +1210,9 @@ COMMIT; 从而只允许在维护窗口内执行重写。 - 下面是一个实现这种策略的示例。 + + 以下是实现这种策略的一个示例。 + CREATE OR REPLACE FUNCTION no_rewrite() RETURNS event_trigger LANGUAGE plpgsql AS diff --git a/zh/11/extend.sgml b/zh/11/extend.sgml index 3546adbc..86983efc 100644 --- a/zh/11/extend.sgml +++ b/zh/11/extend.sgml @@ -39,7 +39,7 @@ - 相关对象包(从 开始) + 相关对象的包(从 开始) @@ -49,11 +49,28 @@ 可扩展性如何运作 - PostgreSQL 之所以具有可扩展性,是因为它的运作由目录驱动。如果你熟悉标准的关系数据库系统,就会知道它们会把数据库、表、列等信息存储在通常所说的系统目录中(有些系统称之为数据字典)。这些目录对用户来说看起来和普通表无异,但 DBMS 会在其中保存自己的内部记账信息。PostgreSQL 与标准关系数据库系统的一个关键区别在于,PostgreSQL在目录中存储了更多信息:不仅包括表和列的信息,还包括数据类型、函数、访问方法等信息。这些表可以由用户修改,而 PostgreSQL 又正是基于这些表运行的,这就意味着用户可以扩展 PostgreSQL。相比之下,传统数据库系统只能通过修改源代码中的硬编码过程,或装入由 DBMS 供应商专门编写的模块来扩展。 + PostgreSQL 之所以具有可扩展性,是因为其 + 运作由系统目录驱动。如果你熟悉标准的关系数据库系统,就会知道它们把 + 有关数据库、表、列等的信息存储在通常所说的系统目录中(有些系统把这 + 称为数据字典)。这些目录对用户而言看起来就像普通表一样,但 + DBMS 会在其中保存自己的内部管理信息。 + PostgreSQL 与标准关系数据库系统的一个关键差别是, + PostgreSQL 在目录中存储的信息要多得多:不仅有关于表和列的信息,还有关于数据 + 类型、函数、访问方法等的信息。这些表可以由用户修改,而 + PostgreSQL 又是基于这些表来运行的,这意味着 + PostgreSQL 可以由用户扩展。相比之下,传统数据库 + 系统只能通过修改源代码中的硬编码过程,或加载由 + DBMS 供应商专门编写的模块来扩展。 - 此外,PostgreSQL 服务器还可以通过动态加载将用户编写的代码纳入自身。也就是说,用户可以指定一个实现新类型或新函数的目标代码文件(例如共享库),而 PostgreSQL 会在需要时加载它。把用 SQL 编写的代码加入服务器就更简单了。这种能够即时修改自身行为的能力,使 PostgreSQL 特别适合用于新应用和新存储结构的快速原型设计。 + 此外,PostgreSQL 服务器还能通过动态加载把用户 + 编写的代码纳入自身。也就是说,用户可以指定一个实现了新类型或新函数 + 的目标代码文件(例如共享库),而 PostgreSQL + 会在需要时加载它。把用 SQL 编写的代码加入服务器就更 + 为简单了。这种能够即时修改自身行为的能力,使 + PostgreSQL 特别适合用于新应用和新存储结构的快速 + 原型设计。 @@ -75,7 +92,7 @@ 数据类型 - 组合 + 复合 @@ -295,7 +312,7 @@ 哪些 SQL 对象种类可以成为扩展成员,见 的说明。特别是,数据库集簇范围内的对象,如数据库、角色和表空间,不能 - 成为扩展成员,因为扩展只在单个数据库内可见。(尽管扩展脚本并不禁止创 + 成为扩展成员,因为扩展只在单个数据库内可见。(尽管并不禁止扩展脚本创 建这类对象,但如果这样做,它们不会作为扩展的一部分受到跟踪。)还要注意, 虽然表可以成为扩展成员,但其附属对象(如索引)并不直接被视为扩展成员。 另一个重要点是,模式可以属于扩展,但反过来不成立:扩展本身只有一个非 @@ -336,7 +353,11 @@ directory (string) - 包含扩展的 SQL 脚本文件的目录。除非给出绝对路径,否则该名称相对于安装目录的 SHAREDIR 目录。默认行为等价于指定 directory = 'extension' + + 包含扩展 SQL 脚本文件的目录。除非给出的是绝对路 + 径,否则该名称相对于安装的 SHAREDIR 目录。默认行为 + 等价于指定 directory = 'extension'。 + @@ -502,7 +523,7 @@ 扩展,应在控制文件中设置 relocatable = false,并在脚本文件中使用 @extschema@ 来引用目标模式。在脚本执行前,该字符 - 串的每次出现都会被替换为实际目标模式的名称(必要时加双引号)。用户 + 串的每次出现都会被替换为实际目标模式的名称。用户 可以通过 CREATE EXTENSIONSCHEMA 选项设置目标模式。 @@ -514,7 +535,7 @@ relocatable = false,并把 schema 设置为预定目标模式的名称。这样将阻止使用 CREATE EXTENSIONSCHEMA - 选项,除非它指定的正是控制文件中命名的那个模式。如果扩展对其模式名 + 选项,除非它指定的正是控制文件中命名的那个模式。如果扩展对模式名 称有无法通过 @extschema@ 替换解决的内部假设,通 常就需要采用这种方式。在这种情况下, @extschema@ 替换机制仍然可用,只是由于模式名由控 @@ -663,7 +684,7 @@ SELECT pg_catalog.pg_extension_config_dump('my_config', 'WHERE NOT standard_entr 在有合适更新脚本可用的前提下, - ALTER EXTENSION UPDATE 命令可以把已安装的扩展更新 + ALTER EXTENSION UPDATE 命令会把已安装的扩展更新 到指定的新版本。更新脚本运行在 CREATE EXTENSION 为安装脚本提供的同一环境中:尤其 是,search_path 的设置方式完全相同,而且脚本创建的 @@ -676,7 +697,7 @@ SELECT pg_catalog.pg_extension_config_dump('my_config', 'WHERE NOT standard_entr (新)版本相关联的那些参数。 - 更新机制可以用于解决一个重要的特殊情况:将散装对象集合转换为扩展。在 PostgreSQL 于 9.1 加入扩展机制之前,许多人编写的扩展模块只是创建各种未打包的对象。对于包含这些对象的现有数据库,如何将它们转换为正确打包的扩展?删除它们再执行普通的 CREATE EXTENSION 是一种办法,但如果对象具有依赖关系(例如,某些表列使用扩展创建的数据类型),就不适合这样做。解决方法是先创建一个空扩展,再使用 ALTER EXTENSION ADD 将每个现有对象附加到扩展中,最后创建当前扩展版本中存在、而散装版本中没有的新对象。CREATE EXTENSION 通过 FROM old_version 选项支持这种情况:它不运行目标版本的普通安装脚本,而是运行名为 extension--old_version--target_version.sql 的更新脚本。用作 old_version 的虚拟版本名由扩展作者选择,不过通常约定使用 unpackaged。如果需要将多个先前版本更新为扩展形式,应使用不同的虚拟版本名来标识它们。 + 更新机制可以用于解决一个重要的特殊情况:将松散对象集合转换为扩展。在 PostgreSQL 于 9.1 加入扩展机制之前,许多人编写的扩展模块只是创建各种未打包的对象。对于包含这些对象的现有数据库,如何将它们转换为正确打包的扩展?删除它们再执行普通的 CREATE EXTENSION 是一种办法,但如果对象具有依赖关系(例如,某些表列使用扩展创建的数据类型),就不适合这样做。解决方法是先创建一个空扩展,再使用 ALTER EXTENSION ADD 将每个现有对象附加到扩展中,最后创建当前扩展版本中存在、而未打包版本中没有的新对象。CREATE EXTENSION 通过 FROM old_version 选项支持这种情况:它不运行目标版本的普通安装脚本,而是运行名为 extension--old_version--target_version.sql 的更新脚本。用作 old_version 的虚拟版本名由扩展作者选择,不过通常约定使用 unpackaged。如果需要将多个先前版本更新为扩展形式,应使用不同的虚拟版本名来标识它们。 ALTER EXTENSION 能够执行一系列更新脚本文件来完成 @@ -691,7 +712,7 @@ SELECT pg_catalog.pg_extension_config_dump('my_config', 'WHERE NOT standard_entr 例如,它并不知道 1.1 是否跟在 1.0 之后。它只是匹配可用的版本名,并选择需要应用 更新脚本最少的那条路径。(实际上,版本名可以是任何不包含 - --,且不以前导或尾随 - 结尾的字 + --,且不以 - 开头或结尾的字 符串。) @@ -812,7 +833,7 @@ SELECT * FROM pg_extension_update_paths('extension_namemyschema.myfunc(bigint),那么像 myschema.myfunc(42) 这样的调用,就可能被恶意函数 myschema.myfunc(integer) 截获。要注意函数和操作符 - 参数的数据类型必须与声明的实参类型精确匹配,必要时请使用显式类型转 + 所传参数的数据类型必须与声明的参数类型精确匹配,必要时请使用显式类型转 换。 @@ -857,7 +878,7 @@ SELECT * FROM pg_extension_update_paths('extension_name扩展示例 - 下面给出一个纯 SQL 扩展的完整示例:一个双元素组合 + 下面给出一个纯 SQL 扩展的完整示例:一个双元素复合 类型,它可以在两个槽位中存储任意类型的值,这两个槽位名为 kv。非文本值会自动强制转换为文本后 再存储。 @@ -929,7 +950,7 @@ include $(PGXS) 如果你打算分发自己的 PostgreSQL 扩展模块, - 那么为它们搭建一个可移植的构建系统会相当困难。因此, + 那么为它们搭建一个可移植的构建系统可能相当困难。因此, PostgreSQL 安装提供了一套称为 PGXS 的扩展构建基础设施,使简单的扩展模块可以针对 已安装好的服务器直接构建。PGXS 主要面向包含 C 代码 @@ -940,7 +961,15 @@ include $(PGXS) 可能还是需要自己编写构建系统。 - 要使用PGXS基础设施构建扩展,必须编写一个简单的 makefile。在其中需要设置一些变量,并包含全局PGXSmakefile。下面的示例构建一个扩展模块,名为isbn_issn,由包含一些 C 代码的共享库、扩展控制文件、SQL 脚本、包含文件(仅在其他模块可能需要不经 SQL 访问扩展函数时才需要)以及文档文本文件组成: + + 要为你的扩展使用 PGXS 基础设施,你必须写一个简单 + 的 makefile。在这个 makefile 中,需要设置一些变量并包含全局 + PGXS makefile。下面是一个示例,它构建一个名为 + isbn_issn 的扩展模块,该模块包含一个装有一些 C 代 + 码的共享库、一个扩展控制文件、一个 SQL 脚本、一个头文件(只有当其他 + 模块可能需要绕过 SQL 直接访问扩展函数时才需要),以及一个文档文本文 + 件: + MODULES = isbn_issn EXTENSION = isbn_issn DATA = isbn_issn--1.0.sql @@ -950,9 +979,15 @@ HEADERS_isbn_issn = isbn_issn.h PG_CONFIG = pg_config PGXS := $(shell $(PG_CONFIG) --pgxs) include $(PGXS) -最后三行应始终相同。在文件的前面部分,可以给变量赋值或添加自定义的make规则。 + + 最后三行始终都应相同。你应在文件前面的部分设置变量或添加自定义的 + make 规则。 + + + + 设定下列三个变量中的一个,以指定要构建的内容: - 设置这三个变量之一,以指定构建内容: + MODULES @@ -966,7 +1001,7 @@ include $(PGXS) MODULE_big - 要从多个源文件构建的共享库(在 OBJS 中列出对象 + 要从多个源文件构建的共享库(在 OBJS 中列出目标 文件) @@ -976,11 +1011,15 @@ include $(PGXS) PROGRAM - 要构建的可执行程序(在 OBJS 中列出对象文件) + 要构建的可执行程序(在 OBJS 中列出目标文件) - 还可以设置以下变量: + + + 还可以设置以下变量: + + EXTENSION @@ -1230,7 +1269,12 @@ include $(PGXS) make 命令行上设置都可以。 - 如果希望将构建目录单独放置,也可以运行make,并将工作目录设在扩展源码树之外。这种做法也称为VPATHVPATH构建。具体方法如下: + + 如果你想保持构建目录与源代码目录分离,也可以在扩展源代码树之外的目录 + 中运行 make。这一过程也称为 + VPATHVPATH + 构建。做法如下: + mkdir build_dir cd build_dir make -f /path/to/extension/source/tree/Makefile @@ -1257,7 +1301,7 @@ make VPATH=/path/to/extension/source/tree install 正在运行的 PostgreSQL 服务器。列在 REGRESS 中的脚本文件必须位于扩展目录下名为 sql/ 的子目录中。这些文件必须具有 - .sql 扩展名,而该扩展名不应出现在 makefile 的 + .sql 扩展名,而该扩展名不能出现在 makefile 的 REGRESS 列表中。对于每个测试,还应在名为 expected/ 的子目录中有一个包含期望输出的文件,其主 干名相同,扩展名为 .out。 diff --git a/zh/11/features.sgml b/zh/11/features.sgml index 801d4e16..7c3e8658 100644 --- a/zh/11/features.sgml +++ b/zh/11/features.sgml @@ -385,7 +385,7 @@ SELECT XMLQUERY('$a is $b' PASSING BY VALUE x AS a, < DOCUMENTCONTENT形式的值。 一个 XQuery/XPath 表达式的上下文项必须是单个 XML 节点或原子值, 但 XPath 1.0 又进一步限制它只能是 XML 节点,并且没有允许CONTENT的节点类型。 - 归根结底,格式良好的DOCUMENT是 + 归根结底,良构的DOCUMENTPostgreSQL能够作为 XPath 上下文项提供的唯一 XML 值形式。 diff --git a/zh/11/func.sgml b/zh/11/func.sgml index 230220a0..327a7fa5 100644 --- a/zh/11/func.sgml +++ b/zh/11/func.sgml @@ -25,14 +25,14 @@ 逻辑操作符 - operator - logical + 操作符 + 逻辑 - Boolean - operators - operators, logical + 布尔 + 操作符 + 操作符,逻辑 @@ -51,15 +51,15 @@ - conjunction + 合取 - disjunction + 析取 - negation + 否定 @@ -166,8 +166,8 @@ 比较函数和操作符 - comparison - operators + 比较 + 操作符 @@ -349,12 +349,12 @@ IS NOT DISTINCT FROM - 当有一个输入为空时,普通的比较操作符会得到空(表示未知),而不是真或假。例如,7 = NULL得到空,7 <> NULL也一样。如果这种行为不合适,可以使用IS NOT DISTINCT FROM谓词: + 当任一输入为 null 时,普通的比较操作符会得到 null(表示未知),而不是真或假。例如,7 = NULL得到 null,7 <> NULL也一样。如果这种行为不合适,可以使用IS NOT DISTINCT FROM谓词: a IS DISTINCT FROM b a IS NOT DISTINCT FROM b - 对于非空输入,IS DISTINCT FROM<>操作符一样。不过,如果两个输入都为空,它会返回假。而如果只有一个输入为空,它会返回真。类似地,IS NOT DISTINCT FROM对于非空输入的行为与=相同,但是当两个输入都为空时它返回真,并且当只有一个输入为空时返回假。因此,这些谓词实际上把空值当作一种普通数据值,而不是未知。 + 对于非 null 输入,IS DISTINCT FROM<>操作符一样。不过,如果两个输入都为 null,它会返回假。而如果只有一个输入为 null,它会返回真。类似地,IS NOT DISTINCT FROM对于非 null 输入的行为与=相同,但是当两个输入都为 null 时它返回真,并且当只有一个输入为 null 时返回假。因此,这些谓词实际上把 null 当作一种普通数据值,而不是未知 @@ -370,7 +370,7 @@ NOTNULL - 要检查一个值是否为空,使用下面的谓词: + 要检查一个值是否为 null,使用下面的谓词: expression IS NULL expression IS NOT NULL @@ -380,7 +380,7 @@ expression ISNULL expression NOTNULL - null valuecomparing + 空值比较 @@ -390,7 +390,7 @@ - 有些应用可能要求表达式expression = NULLexpression得出空值时返回真。我们强烈建议这样的应用修改成遵循 SQL 标准。但是,如果这样修改不可能完成,那么我们可以使用配置变量。如果打开它,PostgreSQL将把x = NULL子句转换成x IS NULL。 + 有些应用可能期望表达式expression = NULLexpression求值为 null 时返回真。我们强烈建议此类应用修改为遵循 SQL 标准。但是,如果无法这样修改,那么可以使用配置变量。如果将其打开,PostgreSQL会把x = NULL子句转换成x IS NULL @@ -426,7 +426,7 @@ boolean_expression IS UNKNOWN boolean_expression IS NOT UNKNOWN - 这些谓词将总是返回真或假,从来不返回空值,即使操作数为空也如此。空值输入被当作逻辑值未知。请注意,IS UNKNOWNIS NOT UNKNOWN实际上分别等同于IS NULLIS NOT NULL,只是输入表达式必须是布尔类型。 + 这些谓词总是返回真或假,从不返回空值,即使操作数为 null 也是如此。null 输入被当作逻辑值未知。请注意,IS UNKNOWNIS NOT UNKNOWN实际上分别等同于IS NULLIS NOT NULL,只是输入表达式必须是布尔类型。 + 正则表达式 + @@ -2868,7 +2872,7 @@ cast(-44 as bit(12)) 111111010100 SIMILAR TO 操作符根据其模式是否匹配给定字符串返回真或假。它与 LIKE 类似,但按照 SQL 标准定义的正则表达式来解释模式。SQL 正则表达式是 LIKE 表示法和常见正则表达式表示法的一种奇特结合。 - 类似LIKESIMILAR TO操作符只有在它的模式匹配整个串的时候才能成功;这一点和普通的 正则表达式的行为不同,在普通的正则表达式里,模式匹配串的任意部分。 和LIKE类似的地方还有,SIMILAR TO使用_%作为分别代表任意单个字符和任意串的通配符(这些可以比得上 POSIX 正则表达式里的..*)。 + 与LIKE类似,SIMILAR TO操作符只有在其模式匹配整个字符串时才算成功;这一点不同于普通正则表达式,后者可以匹配字符串的任意部分。与LIKE相同,SIMILAR TO也使用_%作为通配符,分别匹配任意单个字符和任意字符串(分别类似于 POSIX 正则表达式中的..*)。 @@ -2948,8 +2952,8 @@ substring('foobar' from '#"o_b#"%' for '#') NULLPOSIX正则表达式 - regular expression - pattern matching + 正则表达式 + 模式匹配 substring @@ -3005,11 +3009,11 @@ substring('foobar' from '#"o_b#"%' for '#') NULL - POSIX正则表达式提供了比LIKESIMILAR TO操作符更强大的含义。许多 Unix 工具,例如egrepsedawk使用一种与我们这里描述的类似的模式匹配语言。 + POSIX正则表达式提供了比LIKESIMILAR TO操作符更强大的模式匹配方式。许多 Unix 工具,例如egrepsedawk,都使用与这里描述的模式匹配语言相似的语言。 - 正则表达式是一个字符序列,它是定义一个串集合 (一个正则集)的缩写。 如果一个串是正则表达式描述的正则集中的一员时, 我们就说这个串匹配该正则表达式。 和LIKE一样,模式字符准确地匹配串字符, 除非在正则表达式语言里有特殊字符 — 不过正则表达式用的 特殊字符和LIKE用的不同。 和LIKE模式不一样的是,正则表达式允许匹配串里的任何位置,除非该正则表达式显式地挂接在串的开头或者结尾。 + 正则表达式是一个字符序列,是定义一组字符串(一个正则集)的简写。如果字符串属于正则表达式描述的正则集,就称该字符串匹配此正则表达式。与LIKE一样,模式中的字符精确匹配字符串中的字符,除非该模式字符在正则表达式语言中有特殊含义 — 但正则表达式使用的特殊字符与LIKE不同。与LIKE模式不同,正则表达式可以匹配字符串中的任意位置,除非显式将其锚定到字符串开头或末尾。 下面是一些示例: @@ -3045,13 +3049,13 @@ regexp_replace('foobarbaz', 'b(..)', 'X\1Y', 'g') - regexp_match函数返回一个文本数组,其中包含与POSIX正则表达式模式对字符串的第一个匹配的子字符串。它的语法为 + regexp_match函数返回一个文本数组,包含字符串首次匹配 POSIX 正则表达式模式时捕获的子字符串。它的语法为 regexp_match(string, pattern , flags )。 如果没有匹配,结果为NULL。 - 如果找到匹配,并且pattern不包含括号子表达式,则结果是包含与整个模式匹配的子字符串的单元素文本数组。 - 如果找到匹配,并且pattern包含括号子表达式,则结果是一个文本数组,其中第n个元素是匹配 - pattern的第n个括号子表达式的子字符串(不包括非捕获括号;详情见下文)。 + 如果找到匹配,并且pattern不包含圆括号子表达式,则结果是包含与整个模式匹配的子字符串的单元素文本数组。 + 如果找到匹配,并且pattern包含圆括号子表达式,则结果是一个文本数组,其中第n个元素是匹配 + pattern的第n个圆括号子表达式的子字符串(不包括非捕获括号;详情见下文)。 flags参数是一个可选的文本字符串,其中包含零个或多个单个字母标志,用于更改函数的行为。支持的标志在中描述。 @@ -3105,16 +3109,16 @@ SELECT regexp_matches('foobarbequebazilbarfbonk', '(b[^b]+)(b[^b]+)', 'g'); - 在大部分情况下,regexp_matches()应该与g标志一起使用,因为如果只是想要第一个匹配,使用regexp_match()会更加简单高效。不过,regexp_match()仅存在于PostgreSQL版本10以及更高的版本中。当在较老的版本中使用时,一种常用的技巧是把regexp_matches()调用放在子选择中,例如: + 在大部分情况下,regexp_matches()应该与g标志一起使用,因为如果只是想要第一个匹配,使用regexp_match()会更加简单高效。不过,regexp_match()仅存在于PostgreSQL版本10以及更高的版本中。当在较老的版本中使用时,一种常用的技巧是把regexp_matches()调用放在子查询中,例如: SELECT col1, (SELECT regexp_matches(col2, '(bar)(beque)')) FROM tab; - 如果有一个匹配,则这个语句会产生一个文本数组,否则返回NULL,这和regexp_match()的做法一样。如果没有子选择,这个查询对于没有匹配的表行根本不会产生输出,显然那不是想要的行为。 + 如果有一个匹配,则这个语句会产生一个文本数组,否则返回NULL,这和regexp_match()的做法一样。如果没有子查询,这个查询对于没有匹配的表行根本不会产生输出,这通常不是预期行为。 - regexp_split_to_table把一个 POSIX 正则表达式模式当作一个定界符来分离一个串。它的语法形式是regexp_split_to_table(string, pattern , flags )。如果没有与pattern的匹配,该函数返回string。如果有至少有一个匹配,对每一个匹配它都返回从上一个匹配的末尾(或者串的开头)到这次匹配开头之间的文本。当没有更多匹配时,它返回从上一次匹配的末尾到串末尾之间的文本。flags参数是一个可选的文本串,它包含零个或更多单字母标志,这些标识可以改变该函数的行为。regexp_split_to_table能支持的标志在中描述。 + regexp_split_to_table把一个 POSIX 正则表达式模式当作一个定界符来分割字符串。它的语法形式是regexp_split_to_table(string, pattern , flags )。如果没有与pattern的匹配,该函数返回string。如果至少有一个匹配,对每一个匹配它都返回从上一个匹配的末尾(或者串的开头)到这次匹配开头之间的文本。当没有更多匹配时,它返回从上一次匹配的末尾到串末尾之间的文本。flags参数是一个可选的文本串,它包含零个或更多单字母标志,这些标志可以改变该函数的行为。regexp_split_to_table能支持的标志在中描述。 @@ -3167,9 +3171,9 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; - 正如最后一个示例所示,regexp分割函数会忽略出现在字符串开头或结尾 + 正如最后一个示例所示,正则表达式分割函数会忽略出现在字符串开头或结尾 或紧跟在前一个匹配项之后的零长度匹配。这与regexp_matchregexp_matches实现的 - 严格的regexp匹配定义相矛盾,但在实践中通常是最方便的行为。 + 严格的正则表达式匹配定义相矛盾,但在实践中通常是最方便的行为。 其他软件系统如Perl使用类似的定义。 @@ -3203,7 +3207,7 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; - 一个量化原子是一个原子, 后面可能跟着一个量词。没有量词的时候,它匹配一个原子, 有量词的时候,它可以匹配若干个原子。一个原子可以是在里面显示的任何可能。 可能的量词和它们的含义在里显示。 + 一个量化原子是一个原子,后面可以跟一个量词。没有量词时,匹配一次原子所匹配的内容;有量词时,按量词指定的次数匹配原子所匹配的内容。原子可以是列出的任何一种形式。可用量词及其含义见 @@ -3226,12 +3230,12 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; (re) - (其中re是任何正则表达式) 匹配一个对re的匹配,匹配将为可能的报告被记下 + (其中re是任意正则表达式)匹配re所匹配的内容,并记录该匹配,以备输出结果 (?:re) - 同上,但是匹配不会为了报告而被记下 (一个非捕获圆括号集) (只对 ARE) + 同上,但不记录匹配结果(非捕获圆括号;仅适用于 ARE) @@ -3246,17 +3250,17 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; \k - (其中k是一个非字母数字字符) 匹配一个被当作普通字符看待的特定字符, 例如,\\匹配一个反斜线字符 + (其中k既不是字母也不是数字)把该字符视为普通字符并匹配它,例如,\\匹配反斜线字符 \c - 其中c是一个字母数字 (可能跟着其它字符),它是一个转义, 参阅(仅对 ARE; 在 ERE 和 BRE 中,它匹配c + 其中c是字母或数字(后面可能还有其他字符),这是一个转义,参见(仅适用于 ARE;在 ERE 和 BRE 中,它匹配c { - 如果后面跟着一个字符,而不是数字, 那么就匹配左花括弧{;如果跟着一个数字, 那么它是bound的开始(见下文) + 如果后面跟着非数字字符,则匹配左花括号{;如果后面跟着数字,则是bound的开头(见下文) @@ -3274,7 +3278,7 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; - 如果你关掉了,你在文串常量中写的任何反斜线都需要被双写。详见。 + 如果你关掉了,你在字符串常量中写的任何反斜线都需要被双写。详见 @@ -3363,7 +3367,7 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; - 非贪婪的量词(只在 ARE 中可用)匹配对应的正常 (贪婪)模式,区别是它寻找最少的匹配,而不是最多的匹配。详见。 + 非贪婪量词(仅适用于 ARE)与对应的普通(贪婪)量词匹配相同的可能内容,但优先选择最少的匹配次数,而不是最多的匹配次数。详见 @@ -3390,39 +3394,39 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; ^ - 串开头的匹配 + 在字符串开头匹配 $ - 串末尾的匹配 + 在字符串末尾匹配 (?=re) - 在某个位置上,如果从该位置开始的子串能够匹配re,则匹配正向先行断言(仅对 ARE) + 正向先行断言在这样的位置匹配:存在从该位置开始且匹配re的子字符串(仅适用于 ARE) (?!re) - 在某个位置上,如果从该位置开始的子串不能匹配re,则匹配负向先行断言(仅对 ARE) + 负向先行断言在这样的位置匹配:不存在任何从该位置开始且匹配re的子字符串(仅适用于 ARE) (?<=re) - 在某个位置上,如果以该位置结束的某个子串能够匹配re,则匹配正向后行断言(仅对 ARE) + 正向后行断言在这样的位置匹配:存在以该位置结束且匹配re的子字符串(仅适用于 ARE) (?<!re) - 在某个位置上,如果以该位置结束的任何子串都不能匹配re,则匹配负向后行断言(仅对 ARE) + 负向后行断言在这样的位置匹配:不存在任何以该位置结束且匹配re的子字符串(仅适用于 ARE)
- Lookahead 和 lookbehind 约束不能包含反向引用 (参阅),并且其中的所有圆括号 都被认为是非捕获的。 + 先行和后行约束不能包含反向引用(参见),其中的所有圆括号都视为非捕获圆括号。 @@ -3430,11 +3434,11 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; 方括号表达式 - 方括号表达式是一个包围在[]中的字符列表。它通常匹配列表中的任意单个字符(但见下文)。 如果列表以^开头,它匹配任意单个在该列表参与部分中的字符。如果该列表中两个字符用-隔开, 那它就是那两个字符(包括在内)之间的所有字符范围的缩写,例如,在ASCII[0-9]匹配任何十进制数字。两个范围共享一个端点是非法的,例如,a-c-e。范围与字符集关系密切, 可移植的程序应该避免依靠它们。 + 方括号表达式是用[]括起来的字符列表。通常,它匹配列表中的任意单个字符(但请参见下文)。如果列表以^开头,则匹配任意在列表剩余部分中的单个字符。如果列表中的两个字符用-分隔,则表示排序序列中这两个字符之间的完整字符范围(包含两个端点);例如,ASCII中的[0-9]匹配任意十进制数字。两个范围共享一个端点是不合法的,例如a-c-e。范围高度依赖排序序列,因此可移植程序应避免依赖它们。 - 想在列表中包含文本],可以让它做列表的首字符(如果使用了^,需要放在其后)。 想在列表中包含文本-,可以让它做列表的首字符或者尾字符,或者一个范围的第二个端点。 想在列表中把文本-当做范围的起点, 把它用[..]包围起来,这样它就成为一个排序元素(见下文)。 除了这些字符本身、一些用[的组合(见下段)以及转义(只在 ARE 中有效)以外,所有其它特殊字符 在方括号表达式里都失去它们的特殊含义。特别是,在 ERE 和 BRE 规则下\不是特殊的, 但在 ARE 里,它是特殊的(引入一个转义)。 + 想在列表中包含字面字符],可以让它做列表的首字符(如果使用了^,需要放在其后)。 想在列表中包含字面字符-,可以让它做列表的首字符或者尾字符,或者一个范围的第二个端点。 想在列表中把字面字符-当做范围的起点, 把它用[..]包围起来,这样它就成为一个排序元素(见下文)。 除了这些字符本身、一些用[的组合(见下段)以及转义(只在 ARE 中有效)以外,所有其它特殊字符 在方括号表达式里都失去它们的特殊含义。特别是,在 ERE 和 BRE 规则下\不是特殊的, 但在 ARE 里,它是特殊的(引入一个转义)。 @@ -3449,10 +3453,10 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; - 在方括号表达式里,包围在[==]里的排序元素是一个等价类, 代表等效于那一个的所有排序元素的字符序列,包括它本身(如果没有其它等效排序元素,那么就好象封装定界符是[..])。例如,如果o^是一个等价类的成员,那么[[=o=]][[=^=]][o^]都是同义的。一个等价类不能是一个范围的端点。 + 在方括号表达式里,包围在[==]里的排序元素是一个等价类, 代表等效于那一个的所有排序元素的字符序列,包括它本身(如果没有其它等效排序元素,那么就好像封装定界符是[..])。例如,如果o^是一个等价类的成员,那么[[=o=]][[=^=]][o^]都是同义的。一个等价类不能是一个范围的端点。 - 在方括号表达式中,用 [::] 括起的字符类名表示属于该类的所有字符的列表。标准字符类名包括:alnumalphablankcntrldigitgraphlowerprintpunctspaceupperxdigit。它们表示 ctype3 中定义的字符类。区域环境可以提供其他字符类。字符类不能用作范围的端点。 + 在方括号表达式中,用 [::] 括起的字符类名表示属于该类的所有字符的列表。标准字符类名包括:alnumalphablankcntrldigitgraphlowerprintpunctspaceupperxdigit。它们表示 ctype3 中定义的字符类。区域设置可以提供其他字符类。字符类不能用作范围的端点。 方括号表达式有两个特例:[[:<:]][[:>:]] 是约束,分别匹配单词开头和结尾的空字符串。单词定义为一个前后都没有单词字符的单词字符序列。单词字符是 alnum 字符(由 ctype3 定义)或下划线。这是与 POSIX 1003.2 兼容但未由其规定的扩展,在打算移植到其他系统的软件中应谨慎使用。通常更适合使用下文介绍的约束转义;它们并不更标准,但更容易键入。 @@ -3461,11 +3465,11 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; 正则表达式转义 - 转义是以\开头,后面跟着一个字母数字字符的特殊序列。 转义有好几种变体:字符输入转义、字符类简写转义、约束转义以及反向引用。在 ARE 里, 如果一个\后面跟着一个字母数字,但是并未组成一个合法的转义, 那么它是非法的。在 ERE 中没有转义:在方括号表达式之外,一个后面跟着字母数字字符的\只是表示该字符是一个普通的字符,而且在一个方括号表达式里,\是一个普通的字符(后者实际上在 ERE 和 ARE 不兼容)。 + 转义是以\开头,后面跟着一个字母或数字字符的特殊序列。 转义有好几种变体:字符输入转义、字符类简写转义、约束转义以及反向引用。在 ARE 里, 如果一个\后面跟着一个字母或数字,但是并未组成一个合法的转义, 那么它是非法的。在 ERE 中没有转义:在方括号表达式之外,一个后面跟着字母或数字字符的\只是表示该字符是一个普通的字符,而且在一个方括号表达式里,\是一个普通的字符(后者是 ERE 与 ARE 之间唯一的实际不兼容之处)。 - 字符输入转义用于便于我们在 RE 中声明那些不可打印的或其他习惯的字符。它们显示在中。 + 字符输入转义便于在 RE 中指定不可打印或其他不便输入的字符,见 @@ -3473,13 +3477,13 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; - 约束转义是一个约束,如果满足特定的条件,它匹配该空串。它们显示在中。 + 约束转义是以转义形式书写的约束,在满足特定条件时匹配空字符串,见 反向引用\n)匹配数字n指定的被前面的圆括号子表达式匹配的同一个串 (参阅)。 例如, ([bc])\1匹配bb或者cc, 但是不匹配bc或者cb。 - RE 中子表达式必须完全在反向引用前面。子表达式以它们的先导圆括号的顺序编号。 + RE 中子表达式必须完全在反向引用前面。子表达式以它们的左圆括号的顺序编号。 非捕获圆括号并不定义子表达式。 @@ -3518,7 +3522,7 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; \e - 排序序列名为ESC的字符,如果无法做到该字符为八进制值 033 + 排序序列名称为ESC的字符;若不存在这样的字符,则使用八进制值为033的字符 @@ -3528,7 +3532,7 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; \n - 新行,和 C 中一样 + 换行符,与 C 中相同 @@ -3682,7 +3686,7 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; \Y - 只在一个词的不是开头或末尾的点上匹配 + 只在不属于单词开头或末尾的位置匹配 @@ -3694,7 +3698,7 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo;
- 一个词被定义成在上面[[:<:]][[:>:]]中的声明。在方括号表达式里,约束转义是非法的。 + 单词的定义与上文[[:<:]][[:>:]]的说明相同。方括号表达式中不允许使用约束转义。 @@ -3714,12 +3718,12 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; \m - (其中m是一个非零位)一个到第m个子表达式的反向引用 + (其中m是一个非零数字)一个到第m个子表达式的反向引用 \mnn - (其中m是一个非零位,并且nn是一些更多的位,并且十六进制值mnn不超过目前能看到的封闭捕获圆括号的数目)一个到第mnn个子表达式的反向引用 + (其中m是一个非零数字,并且nn是后续的若干数字,并且十进制值mnn不大于此前已出现的捕获右圆括号数)一个到第mnn个子表达式的反向引用 @@ -3728,7 +3732,7 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; - 在八进制字符输入转义和反向引用之间有一个历史继承的歧义存在,这个歧义是 通过下面的启发式规则解决的,像上面描述地那样。前导零总是表示这是一个八进制转义。 而单个非零数字,如果没有跟着任何其它位,那么总是被认为反向引用。 一个多位的非零开头的序列也被认为是反向引用,只要它出现在合适的子表达式后面 (也就是说,在反向引用的合法范围中的数),否则就被认为是一个八进制。 + 八进制字符输入转义与反向引用之间存在固有歧义,按上文提到的启发式规则解决:前导零始终表示八进制转义。单个非零数字,如果后面没有其他数字,始终视为反向引用。不以零开头的多位数字序列,如果前面已有相应的子表达式(即该数字在反向引用的合法范围内),则视为反向引用,否则视为八进制转义。 @@ -3741,15 +3745,11 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; - RE 可以以两种特殊的引导前缀之一开头。 - 如果 RE 以***:开头,余下部分就被视为 ARE。 - (这在PostgreSQL中通常没有影响,因为 RE 默认被视为 ARE; - 但如果通过正则表达式函数的flags参数指定了 ERE 或 BRE 模式,它就会产生影响。) - 如果 RE 以***=开头,余下部分就被视为字面字符串,所有字符都被视为普通字符。 + RE 可以以两种特殊的引导前缀之一开头。如果 RE 以***:开头,余下部分就被视为 ARE。(这在PostgreSQL中通常没有影响,因为 RE 默认被视为 ARE;但如果通过正则表达式函数的flags参数指定了 ERE 或 BRE 模式,它就会产生影响。)如果 RE 以***=开头,余下部分就作为按字面解释的字符串处理,所有字符都视为普通字符。 - 一个 ARE 可以以嵌入选项开头:一个序列(?xyz)(这里的xyz是一个或多个字母字符)声明影响剩余 RE 的选项。 这些选项覆盖任何前面判断的选项 — 特别地,它们可以覆盖一个正则表达式操作符隐含的大小写敏感的行为,或者覆盖flags参数中的正则表达式函数。可用的选项字母在中显示。注意这些同样的选项字母也被用在正则表达式函数的flags参数中。 + 一个 ARE 可以以嵌入选项开头:一个序列(?xyz)(这里的xyz是一个或多个字母字符)声明影响剩余 RE 的选项。 这些选项覆盖任何先前确定的选项 — 特别地,它们可以覆盖一个正则表达式操作符隐含的大小写敏感的行为,或者覆盖正则表达式函数的flags参数所指定的选项。可用的选项字母在中显示。注意这些同样的选项字母也被用在正则表达式函数的flags参数中。
@@ -3793,32 +3793,32 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; n - 新行敏感的匹配(见 + 换行敏感的匹配(见 p - 部分新行敏感的匹配(见 + 部分换行敏感的匹配(见 q - RE的剩余部分是一个文字(quoted)串,全部是普通字符 + RE 的剩余部分按字面(加引号)解释,所有字符都视为普通字符 s - 非新行敏感的匹配(默认) + 非换行敏感的匹配(默认) t - 紧语法(默认,见下文) + 紧凑语法(默认;见下文) w - 逆部分新行敏感(怪异)的匹配(见 + 逆部分换行敏感(怪异)的匹配(见 @@ -3830,10 +3830,13 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo;
- 嵌入选项在)终止序列时发生作用。它们只在 ARE 的开始处起作用 (在任何可能存在的***:控制器后面)。 + 嵌入选项从结束该序列的)处开始生效。它们只能出现在 ARE 的开头(如果存在***:引导前缀,则位于该前缀之后)。 - 除了通常的()RE 语法(其中所有字符都有意义)之外,还有一种扩展语法,可以通过指定嵌入的x选项来使用。在扩展语法中,RE 中的空白字符会被忽略,同样被忽略的还有#与其后的换行符(或 RE 末尾)之间的所有字符。这使得复杂的 RE 可以分段并添加注释。此基本规则有三个例外: + + 除了通常的紧凑 RE 语法(其中所有字符都有意义)之外,还有一种扩展语法,可以通过指定嵌入的x选项来使用。在扩展语法中,RE 中的空白字符会被忽略,同样被忽略的还有#与其后的换行符(或 RE 末尾)之间的所有字符。这使得复杂的 RE 可以分段并添加注释。此基本规则有三个例外: + + 空白字符或 # 的前面若有 \,该字符就会被保留。 @@ -3847,13 +3850,16 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; 在多字符符号里面不能出现空白和注释,例如(?: - 在这里,空白字符包括空格、制表符、换行符,以及属于space字符类的任何字符。 + + + 在这里,空白字符包括空格、制表符、换行符,以及属于space字符类的任何字符。 +
- 最后,在 ARE 里,方括号表达式外面,序列(?#ttt)(其中ttt是任意不包含一个))的文本)是一个注释, 它被完全忽略。同样,这样的东西是不允许出现在多字符符号的字符中间的,例如 (?:。这种注释更像是一种历史产物而不是一种有用的设施,并且它们的使用已经被废弃;请使用扩展语法来替代。 + 最后,在 ARE 里,方括号表达式外面,序列(?#ttt)(其中ttt是任意不包含一个)的文本)是一个注释, 它被完全忽略。同样,这样的东西是不允许出现在多字符符号的字符中间的,例如 (?:。这种注释更像是一种历史产物而不是一种有用的设施,并且它们的使用已经被废弃;请使用扩展语法来替代。
- 如果声明了一个初始的***=控制器,那么所有这些元语法扩展都不能使用,因为这样表示把用户输入当作一个文字串而不是 RE 对待。 + 如果指定了开头的***=引导前缀,那么这些元语法扩展都不能使用,因为这表示把用户输入作为按字面解释的字符串,而非 RE 处理。 @@ -3869,7 +3875,7 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; - 大多数原子以及所有约束,都没有贪婪属性(因为它们毕竟无法匹配个数变化的文本)。 + 大多数原子以及所有约束,都没有贪婪属性(因为它们毕竟无法匹配长度不定的文本)。 @@ -3921,7 +3927,7 @@ SELECT SUBSTRING('XY1234Z', 'Y*?([0-9]{1,3})');
- 简而言之,如果一个 RE 同时包含贪婪和非贪婪的子表达式,那么总的匹配长度要么是尽可能长,要么是尽可能短,这取决于给整个 RE 赋予的属性。给子表达式赋予的属性只影响在这个匹配里,各个子表达式之间相互允许吃掉的多少。 + 简而言之,如果一个 RE 同时包含贪婪和非贪婪的子表达式,那么总的匹配长度要么是尽可能长,要么是尽可能短,这取决于给整个 RE 赋予的属性。给子表达式赋予的属性只影响在这个匹配里,各个子表达式相对于其他子表达式能吃掉多少内容。 @@ -3955,19 +3961,19 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 如果声明了大小写无关的匹配,那么效果就好像所有大小写区别在字母表中消失了。如果在多个情况中一个字母以一个普通字符的形式出现在方括号表达式外面,那么它实际上被转换成 一个包含大小写的方括号表达式,也就是说,x 变成 [xX]。 如果它出现在一个方括号表达式里面,那么它的所有大小写的同族都被加入 方括号表达式中,也就是说,x变成[xX]。当它出现在一个方括号表达式内时,它的所有大小写副本都被加入到方括号表达式中,例如, [x]会变成[xX],而[^x]会变成[^xX]。 + 如果指定不区分大小写的匹配,其效果近似于字母表中的所有大小写差别都消失了。当存在大小写形式的字母作为普通字符出现在方括号表达式之外时,实际上会转换为包含其大小写形式的方括号表达式,例如x变成[xX]。当它出现在方括号表达式内部时,其所有大小写形式都会加入该表达式,例如[x]变成[xX][^x]变成[^xX] - 如果指定了换行敏感的匹配,.和使用^的方括号表达式 将永远不会匹配换行字符(这样,匹配就不会跨越行,除非 RE 显式地包含了换行)并且^$除了分别匹配串开头和结尾之外,还将分别匹配换行后面和前面的空串。 + 如果指定了换行敏感的匹配,.和使用^的方括号表达式 将永远不会匹配换行字符(这样,匹配就不会跨越行,除非 RE 显式安排了跨行匹配)并且^$除了分别匹配串开头和结尾之外,还将分别匹配换行后面和前面的空串。 但是 ARE 转义\A\Z仍然匹配串的开头和结尾。 - 如果指定了部分新行敏感的匹配,那么它影响.和方括号表达式, 这个时候和新行敏感的匹配一样,但是不影响^$。 + 如果指定了部分换行敏感的匹配,那么它影响.和方括号表达式, 这个时候和换行敏感的匹配一样,但是不影响^$ - 如果指定了逆新行敏感匹配,那么它影响^$,其作用和在新行敏感的匹配里一样,但是不影响.和方括号表达式。这个并不是很有用,只是为了满足对称性而提供的。 + 如果指定了逆部分换行敏感匹配,那么它影响^$,其作用和在换行敏感的匹配里一样,但是不影响.和方括号表达式。这个并不是很有用,只是为了满足对称性而提供的。 @@ -3979,11 +3985,11 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - ARE 实际上和 POSIX ERE 不兼容的唯一的特性是在方括号表达式里\并不失去它特殊的含义。所有其它 ARE 特性都使用在 POSIX ERE 里面是非法或者是未定义、未声明效果的语法;指示器的***就是在 POSIX 的 BRE 和 ERE 之外的语法。 + ARE 与 POSIX ERE 实际不兼容的唯一特性是:\在方括号表达式中不会失去特殊含义。其他所有 ARE 特性所使用的语法,在 POSIX ERE 中都是非法的,或其效果未定义或未指定;引导前缀的***语法同样不属于 POSIX 的 BRE 或 ERE 语法。 - 许多 ARE 扩展都是从 Perl 那里借来的(但是有些被做了修改来清理它们),以及一些 Perl 里没有出现的扩展。要注意的不兼容性包括\b\B、对结尾的新行缺乏特别的处理、对那些被新行敏感匹配的东西附加的补齐方括号表达式、在 lookahead/lookbehind 约束里对圆括号和反向引用的限制以及最长/最短 匹配(而不是第一匹配)的语义。 + 许多 ARE 扩展借鉴自 Perl,但其中一些经过了整理和修改,也未实现少数 Perl 扩展。需要注意的不兼容之处包括\b\B、不对末尾换行符作特殊处理、取反的方括号表达式也受换行敏感匹配影响、先行和后行约束中对圆括号及反向引用的限制,以及采用最长或最短匹配而非首次匹配的语义。 ARE 与旧版 ERE 语法存在两点重要的不兼容,这里比较的是 7.4 之前的PostgreSQL: @@ -4004,7 +4010,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 基本正则表达式 - BREs 在几个方面和 ERE 不太一样。在 BRE 中,|+?都是普通字符并且没有与它们功能等价的东西。范围的定界符是\{\}, 因为 {}本身是普通字符。嵌套的子表达式的圆括号是\(\),因为()自身是普通字符。除非在 RE 开头或者是圆括号子表达式开头,^都是一个普通字符。 除非在 RE 结尾或者是圆括号子表达式的结尾,$是一个普通字符。如果*出现在 RE 开头或者是圆括号封装的子表达式开头 (前面可能有^),那么它是个普通字符。最后,可以用单数字的反向引用,\<\>分别是[[:<:]][[:>:]]的同义词;在 BRE 中没有其它可用的转义。 + BRE 在几个方面和 ERE 不太一样。在 BRE 中,|+?都是普通字符并且没有与它们功能等价的东西。范围的定界符是\{\},而{}本身是普通字符。嵌套的子表达式的圆括号是\(\),而()自身是普通字符。除非在 RE 开头或者是圆括号子表达式开头,^都是一个普通字符。 除非在 RE 结尾或者是圆括号子表达式的结尾,$是一个普通字符。如果*出现在 RE 开头或者是圆括号封装的子表达式开头 (前面可能有^),那么它是个普通字符。最后,可以用单数字的反向引用,\<\>分别是[[:<:]][[:>:]]的同义词;在 BRE 中没有其它可用的转义。 @@ -4018,11 +4024,11 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 数据类型格式化函数 - formatting + 格式化 - PostgreSQL格式化函数提供一套强大的工具用于把各种数据类型 (日期/时间、整数、浮点、数字) 转换成格式化的字符串以及反过来从格式化的字符串转换成 指定的数据类型。列出了这些函数。这些函数都遵循一个公共的调用规范: 第一个参数是待格式化的值,而第二个是一个定义输出或输入格式的模板。 + PostgreSQL格式化函数提供一套强大的工具用于把各种数据类型 (日期/时间、整数、浮点数、数值) 转换成格式化的字符串以及反过来从格式化的字符串转换成 指定的数据类型。列出了这些函数。这些函数都遵循一个公共的调用规范: 第一个参数是待格式化的值,而第二个是一个定义输出或输入格式的模板。 @@ -4106,7 +4112,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 展示了可以用于格式化日期和时间值的模版。 + 展示了可以用于格式化日期和时间值的模板模式。
@@ -4154,17 +4160,17 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); AM, am, - PM or pm - 正午指示器(不带句号) + PMpm + 上午/下午标记(不带句点) A.M., a.m., - P.M. or p.m. - 正午指示器(带句号) + P.M.p.m. + 上午/下午标记(带句点) Y,YYY - 带逗号的年(4 位或者更多位) with comma + 带逗号的年(4 位或者更多位) YYYY @@ -4210,15 +4216,15 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); MONTH - 全大写形式的月名(空格补齐到 9 字符) + 大写的月份全称(空格补齐到 9 字符) Month - 全首字母大写形式的月名(空格补齐到 9 字符) + 首字母大写的月份全称(空格补齐到 9 字符) month - 全小写形式的月名(空格补齐到 9 字符) + 小写的月份全称(空格补齐到 9 字符) MON @@ -4234,31 +4240,31 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); MM - 月份数(01-12) + 月份编号(01-12) DAY - 全大写形式的日名(空格补齐到 9 字符) + 大写的星期全称(空格补齐到 9 字符) Day - 全首字母大写形式的日名(空格补齐到 9 字符) + 首字母大写的星期全称(空格补齐到 9 字符) day - 全小写形式的日名(空格补齐到 9 字符) + 小写的星期全称(空格补齐到 9 字符) DY - 简写的大写形式的日名(英语 3 字符,本地化长度可变) + 大写的星期简称(英语 3 字符,本地化长度可变) Dy - 简写的首字母大写形式的日名(英语 3 字符,本地化长度可变) + 首字母大写的星期简称(英语 3 字符,本地化长度可变) dy - 简写的小写形式的日名(英语 3 字符,本地化长度可变) + 小写的星期简称(英语 3 字符,本地化长度可变) DDD @@ -4270,19 +4276,19 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); DD - 一月中的第几天(01-31) + 月内日序数(01-31) D - 周中的日,周日 (1) 到周六 (7) + 星期几,周日 (1) 到周六 (7) ID - 周中的 ISO 8601 日,周一 (1) 到周日 (7) + ISO 8601 星期几,周一 (1) 到周日 (7) W - 一月中的第几周(1-5)(第一周从该月第一天开始) + 月内周序数(1-5)(第一周从该月第一天开始) WW @@ -4330,55 +4336,55 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); OF - 从UTC开始的时区偏移(仅在to_char中支持) + 相对于 UTC 的时区偏移(仅在to_char中支持)
- 修饰语可以被应用于模板模式来修改它们的行为。例如,FMMonth就是带着FM修饰语的Month模式。展示了可用于日期/时间格式化的修饰语模式。 + 修饰符可以被应用于模板模式来修改它们的行为。例如,FMMonth就是带着FM修饰符的Month模式。展示了可用于日期/时间格式化的修饰符模式。 - 用于日期/时间格式化的模板模式修饰语 + 用于日期/时间格式化的模板模式修饰符 - 修饰语 + 修饰符 描述 示例 - FM prefix + FM 前缀 填充模式(抑制前导零和填充的空格) FMMonth - TH suffix + TH 后缀 大写形式的序数后缀 - DDTH, e.g., 12TH + DDTH,例如, 12TH - th suffix + th 后缀 小写形式的序数后缀 - DDth, e.g., 12th + DDth,例如, 12th - FX prefix - 固定的格式化全局选项(见使用须知) + FX 前缀 + 固定格式全局选项(见使用须知) FX Month DD Day - TM prefix + TM 前缀 翻译模式(根据 输出本地化的星期名和月份名) TMMonth - SP suffix + SP 后缀 拼写模式(未实现) DDSP @@ -4386,14 +4392,14 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}');
- 日期/时间格式化的使用说明: + 日期/时间格式化的使用注意事项: FM抑制了在模式输出中添加前导零和尾随空格的行为,这些前导零和尾随空格 本来会被添加以使输出成为固定宽度。在PostgreSQL中, - FM仅修改下一个规范,而在Oracle中FM影响所有后续 - 规范,并且重复的FM修饰符切换填充模式的开启和关闭。 + FM仅修改下一个格式说明,而在Oracle中FM影响所有后续 + 格式说明,并且重复的FM修饰符切换填充模式的开启和关闭。 @@ -4407,12 +4413,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 普通文本允许在to_char模板中,并且将被直接输出。您可以将子字符串放在双引号中, - 以强制将其解释为文字文本,即使它包含模板模式。例如,在'"Hello Year "YYYY'中, - YYYY将被年份数据替换,但Year中的单个Y不会被替换。 - 在to_dateto_numberto_timestamp中, - 文本和双引号字符串会导致跳过字符串中包含的字符数;例如"XX"跳过两个输入字符 - (无论它们是否为XX)。 + 普通文本可以出现在to_char模板中,并会按字面输出。可以用双引号括起子串,使其即使包含模式关键字也强制按字面文本解释。例如,在'"Hello Year "YYYY'中,YYYY会被年份数据替换,但Year中单独的Y不会被替换。在to_dateto_numberto_timestamp中,字面文本和双引号字符串会跳过与该字符串所含字符数相同数量的输入字符;例如,"XX"跳过两个输入字符(无论它们是否为XX)。 @@ -4421,7 +4422,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 如果您想在输出中使用双引号,必须在其前面加上反斜杠,例如'\"YYYY Month\"' - 反斜杠在双引号之外不起特殊作用。在双引号字符串内部,反斜杠会使下一个字符被直接解释,无论是什么(但除非下一个字符是双引号或另一个反斜杠,否则没有特殊效果)。 + 反斜杠在双引号之外不起特殊作用。在双引号字符串内部,反斜杠会使下一个字符被按字面解释,无论是什么(但除非下一个字符是双引号或另一个反斜杠,否则没有特殊效果)。 @@ -4483,14 +4484,14 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 年份、周数和星期几:例如to_date('2006-42-4', 'IYYY-IW-ID') + 年份、周编号和星期几:例如to_date('2006-42-4', 'IYYY-IW-ID') 返回日期2006-10-19。 如果省略星期几,则假定为1(星期一)。 - 年份和年内天数:例如to_date('2006-291', 'IYYY-IDDD')也返回2006-10-19。 + 年份和年内日序数:例如to_date('2006-291', 'IYYY-IDDD')也返回2006-10-19 @@ -4498,14 +4499,14 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 尝试使用ISO 8601周编号字段和公历日期字段的混合输入日期是荒谬的,并将导致错误。 - 在ISO 8601周编号年的背景下,月份日期的概念没有意义。 + 在ISO 8601周编号年的背景下,月份月内日序数的概念没有意义。 在公历年的背景下,ISO周没有意义。 - 当to_date拒绝混合使用公历和ISO周编号日期字段时, - to_char不会,因为输出格式规范如YYYY-MM-DD (IYYY-IDDD)可能很有用。 + 虽然to_date会拒绝混合使用公历和ISO周编号日期字段, + 但to_char不会,因为输出格式规范如YYYY-MM-DD (IYYY-IDDD)可能很有用。 但要避免编写类似IYYY-MM-DD的内容;那会在年初附近产生令人惊讶的结果。 (有关更多信息,请参见。) @@ -4524,7 +4525,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 这是一个更复杂的示例: to_timestamp('15:12:02.020.001230', 'HH24:MI:SS.MS.US') - 是15小时,12分钟和2秒 + 20毫秒 + 1230微秒 = 2.021230秒。 + 为15小时12分钟,秒数为2秒 + 20毫秒 + 1230微秒 = 2.021230秒。 @@ -4532,7 +4533,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); to_char(..., 'ID')的星期几编号与extract(isodow from ...)函数匹配, - 但to_char(..., 'D')的不匹配extract(dow from ...)的星期编号。 + 但to_char(..., 'D')的不匹配extract(dow from ...)的星期几编号。 @@ -4549,12 +4550,12 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 展示了可以用于格式化数字值的模版模式。 + 展示了可以用于格式化数值的模板模式。 - 用于数字格式化的模板模式 + 用于数值格式化的模板模式 @@ -4567,21 +4568,21 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 9 - 数位(如果无意义可以被删除) + 数位(非有效位可以被省略) 0 - 数位(即便没有意义也不会被删除) + 数位(即便是非有效位也不会被省略) - . (period) + .(句点) 小数点 - , (comma) + ,(逗号) 分组(千)分隔符 @@ -4592,22 +4593,22 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); S - 带符号的数字(使用区域) + 紧贴数值的正负号(使用区域设置) L - 货币符号(使用区域) + 货币符号(使用区域设置) D - 小数点(使用区域) + 小数点(使用区域设置) G - 分组分隔符(使用区域) + 分组分隔符(使用区域设置) @@ -4631,7 +4632,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - TH or th + THth 序数后缀 @@ -4648,7 +4649,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}');
- 数值格式化的使用说明: + 数值格式化的使用注意事项: @@ -4662,14 +4663,14 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 如果格式提供的小数位数少于被格式化的数字,则to_char()将会将数字四舍五入到指定的小数位数。 + 如果格式指定的小数位数少于被格式化数值的小数位数,to_char()会将该数值舍入到指定的小数位数。 - 模式字符SLDG表示当前区域设置定义的符号、货币符号、小数点和千位分隔符字符 + 模式字符SLDG表示当前区域设置定义的正负号、货币符号、小数点和千位分隔符字符 (参见)。模式字符句点和逗号表示这些确切字符,具有小数点和千位分隔符的含义,不受区域设置影响。 @@ -4678,15 +4679,14 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 如果在to_char()的模式中没有明确指定符号,将为符号保留一列,并将其锚定到(出现在)数字的左侧。 - 如果S出现在一些9的左侧,它也将锚定到数字。 + 如果to_char()的模式中没有明确指定正负号的位置,就会为正负号保留一列,并使其紧贴数值(紧靠数值左侧)。如果S紧邻若干个9的左侧,它同样会紧贴数值。 - 使用SGPLMI格式化的符号不与数字绑定; + 使用SGPLMI格式化的正负号不紧贴数值; 例如,to_char(-12, 'MI9999')会产生'-  12', 但to_char(-12, 'S9999')会产生'  -12'。 (Oracle实现不允许在9之前使用MI,而是要求9MI之前。) @@ -4713,7 +4713,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); to_number函数中,如果使用非数据模板模式,如LTH, - 则会跳过相应数量的输入字符,无论它们是否与模板模式匹配,除非它们是数据字符(即数字、符号、小数点或逗号)。 + 则会跳过相应数量的输入字符,无论它们是否与模板模式匹配,除非它们是数据字符(即数字、正负号、小数点或逗号)。 例如,TH会跳过两个非数据字符。 @@ -4724,7 +4724,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); Vto_char一起, 将输入值乘以10^n, 其中n是跟在V后面的数字位数。 - Vto_number一起以类似的方式除法。 + Vto_number一起以类似的方式进行除法。 to_charto_number不支持与小数点结合使用的V (例如,不允许使用99.9V99)。 @@ -4740,17 +4740,17 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 某些修饰语可以被应用到任何模板来改变其行为。例如,FM99.99是带有FM修饰语的99.99模式。中展示了用于数字格式化模式修饰语。 + 某些修饰符可以被应用到任何模板来改变其行为。例如,FM99.99是带有FM修饰符的99.99模式。中展示了用于数值格式化的模式修饰符。 - 用于数字格式化的模板模式修饰语 + 用于数值格式化的模板模式修饰符 - 修饰语 + 修饰符 描述 示例 @@ -4758,19 +4758,19 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - FM prefix - 填充模式(抑制拖尾零和填充的空白) + FM 前缀 + 填充模式(抑制尾随零和填充的空白) FM99.99 - TH suffix + TH 后缀 大写序数后缀 999TH - th suffix + th 后缀 小写序数后缀 999th @@ -4954,10 +4954,10 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 时间/日期函数和操作符 + 日期/时间函数和操作符 - 展示了可用于处理日期/时间值的函数,其细节在随后的小节中描述。演示了基本算术操作符 (+*等)的行为。 而与格式化相关的函数,可以参考。你应该很熟悉中的日期/时间数据类型的背景知识。 + 展示了可用于处理日期/时间值的函数,其细节在随后的小节中描述。演示了基本算术操作符 (+*等)的行为。 而与格式化相关的函数,可以参考。你应当熟悉中的日期/时间数据类型的背景知识。 @@ -5121,7 +5121,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); age age(timestamp, timestamp) interval - 减去参数,生成一个使用年和月,而不是只用日的符号化的结果 + 将两个参数相减,生成一个使用年和月,而不是只用日的符号化的结果 age(timestamp '2001-04-10', timestamp '1957-06-13') 43 years 9 mons 27 days @@ -5223,7 +5223,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); isfinite isfinite(date) boolean - 测试有限日期(不是+/-无限) + 测试日期是否有限(不是正负无穷) isfinite(date '2001-02-16') true @@ -5265,7 +5265,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); justify_interval justify_interval(interval) interval - 使用 justify_daysjustify_hours调整时间间隔; 通过额外的符号调整 + 使用 justify_daysjustify_hours调整时间间隔,并额外调整符号 justify_interval(interval '1 mon -1 hour') 29 days 23:00:00 @@ -5345,7 +5345,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); statement_timestamp statement_timestamp() timestamp with time zone - 当前日期和时间(当前语句的开始);参见 + 当前日期和时间(当前语句开始时);参见 @@ -5389,7 +5389,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); (start1, end1) OVERLAPS (start2, end2) (start1, length1) OVERLAPS (start2, length2) - 这个表达式在两个时间域(用它们的端点定义)重叠的时候得到真,当它们不重叠时得到假。端点可以用一对日期、时间或者时间戳来指定;或者是用一个后面跟着一个间隔的日期、时间或时间戳来指定。当一对值被提供时,起点或终点都可以被写在前面,OVERLAPS会自动地把较早的值作为起点。每一个时间段被认为是表示半开的间隔start <= time < end,除非startend相等,这种情况下它表示单个时间实例。例如这表示两个只有一个共同端点的时间段不重叠。 + 这个表达式在两个时间段(用它们的端点定义)重叠的时候得到真,当它们不重叠时得到假。端点可以用一对日期、时间或者时间戳来指定;或者是用一个后面跟着一个间隔的日期、时间或时间戳来指定。当一对值被提供时,起点或终点都可以被写在前面,OVERLAPS会自动地把较早的值作为起点。每一个时间段被认为是表示半开区间start <= time < end,除非startend相等,这种情况下它表示单个时刻。例如这表示两个只有一个共同端点的时间段不重叠。 @@ -5421,15 +5421,9 @@ SELECT timestamp with time zone '2005-04-02 12:00:00-07' + interval '24 hours'; - 日期和时间戳的减法也可能会很复杂。执行减法的一种概念上很简单的方法是,使用 - EXTRACT(EPOCH FROM ...)把每个值都转换成秒数,然后执行减法, - 这样会得到两个值之间的数。这种方法将会适应每个月中天数、 - 时区改变和夏令时调整。使用-操作符的日期或时间 - 戳减法会返回值之间的天数(24小时)以及时/分/秒,也会做同样的调整。 - age函数会返回年、月、日以及时/分/秒,执行按域的减法,然后对 - 负值域进行调整。下面的查询展示了这些方法的不同。示例中的结果由 - timezone = 'US/Eastern'产生,这使得两个使用的日期之间存在着夏令 - 时的变化: + 日期和时间戳的减法也可能很复杂。一种概念上简单的方法是,先用EXTRACT(EPOCH FROM ...)将各值转换为秒数,然后将结果相减;这样得到的是两个值之间的数。这种方法会针对每个月的天数、时区变化和夏令时变化进行调整。 + 用-操作符将日期或时间戳值相减,会返回两个值之间的天数(每一天为 24 小时)和时/分/秒,也会作相同的调整。age函数返回年、月、日和时/分/秒,它会逐字段相减,然后调整负值字段。 + 以下查询显示了这些方法的差异。示例结果在timezone = 'US/Eastern'设置下产生;所用的两个日期之间发生了夏令时切换: @@ -5545,7 +5539,7 @@ SELECT EXTRACT(DOY FROM TIMESTAMP '2001-02-16 20:38:40'); epoch - 对于timestamp with time zone值,自1970-01-01 00:00:00 UTC以来的秒数(负值表示该时间戳之前的时间); + 对于timestamp with time zone值,自1970-01-01 00:00:00 UTC以来的秒数(早于该时刻的时间戳对应负值); 对于datetimestamp值,自1970-01-01 00:00:00以来的名义秒数,不考虑时区或夏令时规则; 对于interval值,间隔中的总秒数 @@ -5568,8 +5562,8 @@ SELECT to_timestamp(982384720.12); - 注意,将to_timestamp应用于从datetimestamp值中提取的时代可能会产生误导性的结果: - 结果将有效地假定原始值是以UTC时间给出的,这可能并非事实。 + 注意,将to_timestamp应用于从datetimestamp值中提取的 epoch 值可能会产生误导性的结果: + 结果实际上会假定原始值是以UTC时间给出的,这可能并非事实。 @@ -5670,7 +5664,7 @@ SELECT EXTRACT(MILLENNIUM FROM TIMESTAMP '2001-02-16 20:38:40'); milliseconds - 第二个字段,包括小数部分,乘以1000。请注意,这包括完整的秒数。 + 秒字段,包括小数部分,乘以1000。请注意,这包括完整的秒数。 @@ -5749,7 +5743,7 @@ SELECT EXTRACT(SECOND FROM TIME '17:12:28.5'); - 时间区偏移的小时组件 + 时区偏移的小时部分 @@ -5759,7 +5753,7 @@ SELECT EXTRACT(SECOND FROM TIME '17:12:28.5'); - 时间区偏移的分钟组件 + 时区偏移的分钟部分 @@ -5769,16 +5763,11 @@ SELECT EXTRACT(SECOND FROM TIME '17:12:28.5'); - 一年中ISO 8601周编号周的数量。根据定义,ISO周从周一开始, - 一年的第一周包含该年的1月4日。换句话说,一年的第一个星期四在该年的第1周。 + 一年中按ISO 8601 周编号体系计算的周序号。根据定义,ISO 周从周一开始,一年的第一周包含该年的 1 月 4 日。换句话说,一年的第一个星期四在该年的第 1 周。 - 在ISO周编号系统中,早年1月的日期可能属于前一年的第52周或第53周,而 - 晚年12月的日期可能属于下一年的第一周。例如,2005-01-01 - 属于2004年的第53周,2006-01-01 属于2005年的第52周, - 而2012-12-31 属于2013年的第一周。建议同时使用 - isoyear 字段和week以获得一致的结果。 + 在 ISO 周编号体系中,1 月初的日期可能属于前一年的第 52 周或第 53 周,而 12 月末的日期可能属于下一年的第一周。例如,2005-01-01属于 2004 年的第 53 周,2006-01-01属于 2005 年的第 52 周,而2012-12-31属于 2013 年的第一周。建议将isoyear字段与week一起使用,以获得一致的结果。 @@ -5793,7 +5782,7 @@ SELECT EXTRACT(WEEK FROM TIMESTAMP '2001-02-16 20:38:40'); - 年份字段。请记住,没有0 AD,所以要小心地从AD年中减去BC年。 + 年份字段。请记住,没有0 AD,所以把BC年份从AD年份中减去时需要小心。 @@ -5809,7 +5798,7 @@ SELECT EXTRACT(YEAR FROM TIMESTAMP '2001-02-16 20:38:40'); - 当输入值为 +/-Infinity 时,extract对于单调增的域(epochjulianyearisoyeardecadecentury以及millennium)返回 +/-Infinity。对于其他域返回 NULL。PostgreSQL 9.6 之前的版本对所有输入无穷的情况都返回零。 + 当输入值为 +/-Infinity 时,extract对于单调递增的字段(epochjulianyearisoyeardecadecentury以及millennium)返回 +/-Infinity。对于其他字段返回 NULL。PostgreSQL 9.6 之前的版本对所有输入无穷的情况都返回零。 @@ -5817,10 +5806,11 @@ SELECT EXTRACT(YEAR FROM TIMESTAMP '2001-02-16 20:38:40'); extract函数主要的用途是做计算性处理。对于用于显示的日期/时间值格式化,参阅。 - date_part函数仿照传统的Ingres实现,后者等价于SQL标准函数extract: + date_part函数仿照传统的Ingres实现,后者对应SQL标准的extract函数: date_part('field', source) -注意,此处的field参数必须是字符串值,而不能是名称。函数date_part的有效字段名与以下函数相同:extract。 + + 注意,此处的field参数必须是字符串值,而不能是名称。date_part的有效字段名与extract相同。 @@ -5847,10 +5837,10 @@ SELECT date_part('hour', INTERVAL '4 hours 3 minutes'); date_trunc('field', source) - sourcetimestampinterval类型的值表达式。(类型为datetime的值会自动转换为timestampinterval,分别对应这两种输入类型。)field选择输入值的截断精度。返回值的类型是timestampinterval,所有小于所选精度的字段都设为零(日期和月份则设为一)。 + sourcetimestampinterval类型的值表达式。(类型为datetime的值会自动转换为timestampinterval,分别对应这两种输入类型。)field选择输入值的截断精度。返回值的类型是timestampinterval,所有小于所选精度的字段都设为零(日和月则设为一)。 - field的有效值是∶ + field的有效值是: microseconds milliseconds @@ -5882,8 +5872,8 @@ SELECT date_trunc('year', TIMESTAMP '2001-02-16 20:38:40'); <literal>AT TIME ZONE</literal> - time zone - conversion + 时区 + 转换 @@ -5943,7 +5933,7 @@ SELECT TIMESTAMP '2001-02-16 20:38:40-05' AT TIME ZONE 'Asia/Tokyo' AT TIME ZONE 第一个示例为不带时区的值添加时区,并使用当前TimeZone设置显示该值。第二个示例将带时区的时间戳值移到指定时区,并返回不带时区的值。这样就可以存储和显示与当前TimeZone设置不同的值。第三个示例将东京时间转换为芝加哥时间。将time值转换到其他时区时,由于没有提供日期,会使用当前生效的时区规则。 - 函数timezone(zone, timestamp)等效于 SQL 兼容的结构timestamp AT TIME ZONE zone。 + 函数timezone(zone, timestamp)等效于符合 SQL 标准的结构timestamp AT TIME ZONE zone @@ -5951,13 +5941,13 @@ SELECT TIMESTAMP '2001-02-16 20:38:40-05' AT TIME ZONE 'Asia/Tokyo' AT TIME ZONE 当前日期/时间 - date - current + 日期 + 当前 - time - current + 时间 + 当前 @@ -5976,11 +5966,11 @@ LOCALTIMESTAMP(precision) - CURRENT_TIMECURRENT_TIMESTAMP传递带有时区的值;LOCALTIMELOCALTIMESTAMP传递的值不带时区。 + CURRENT_TIMECURRENT_TIMESTAMP返回带时区的值;LOCALTIMELOCALTIMESTAMP返回不带时区的值。 - CURRENT_TIMECURRENT_TIMESTAMPLOCALTIMELOCALTIMESTAMP可以有选择地接受一个精度参数,该精度会使结果的秒字段圆整到指定的小数位数。如果没有精度参数,结果将给出可用的全部精度。 + CURRENT_TIMECURRENT_TIMESTAMPLOCALTIMELOCALTIMESTAMP可以有选择地接受一个精度参数,该精度会使结果的秒字段舍入到指定的小数位数。如果没有精度参数,结果将给出可用的全部精度。 下面是一些示例: @@ -6004,7 +5994,7 @@ SELECT LOCALTIMESTAMP; - 许多其它数据库系统可能会更频繁地推进这些值。 + 其他数据库系统可能会更频繁地推进这些值。 @@ -6021,13 +6011,15 @@ now() - transaction_timestamp()等价于CURRENT_TIMESTAMP,但是其命名清楚地反映了它的返回值。statement_timestamp()返回当前语句的开始时刻(更准确的说是收到 客户端最后一条命令的时间)。statement_timestamp()transaction_timestamp()在一个事务的第一条命令期间返回值相同,但是在随后的命令中却不一定相同。 clock_timestamp()返回真正的当前时间,因此它的值甚至在同一条 SQL 命令中都会变化。timeofday()是一个有历史原因的PostgreSQL函数。和clock_timestamp()相似,它也返回真实的当前时间,但是它的结果是一个格式化的text串,而不是timestamp with time zone值。now()PostgreSQL的一个传统,等效于transaction_timestamp()。 + transaction_timestamp()等价于CURRENT_TIMESTAMP,但是其命名清楚地反映了它的返回值。statement_timestamp()返回当前语句的开始时刻(更准确地说,是接收到客户端最近一条命令消息的时间)。statement_timestamp()transaction_timestamp()在一个事务的第一条命令期间返回值相同,但是在随后的命令中却不一定相同。 clock_timestamp()返回真正的当前时间,因此它的值甚至在同一条 SQL 命令中都会变化。timeofday()是一个有历史原因的PostgreSQL函数。和clock_timestamp()相似,它也返回真实的当前时间,但是它的结果是一个格式化的text串,而不是timestamp with time zone值。now()PostgreSQL中与transaction_timestamp()等价的传统函数。 - 所有日期/时间数据类型也都接受特殊字面值now来指定当前日期和时间(同样解释为事务开始时间)。因此,下面三种写法都返回相同的结果: + + 所有日期/时间数据类型也都接受特殊字面值now来指定当前日期和时间(同样解释为事务开始时间)。因此,下面三种写法都返回相同的结果: + SELECT CURRENT_TIMESTAMP; SELECT now(); -SELECT TIMESTAMP 'now'; -- but see tip below +SELECT TIMESTAMP 'now'; -- 但请参阅下面的提示 @@ -6035,7 +6027,7 @@ SELECT TIMESTAMP 'now'; -- but see tip below 当指定以后要计算的值时,不要使用第三种形式,例如在表列的DEFAULT子句中。 - 系统将在分析这个常量的时候把now转换为一个timestamp, 这样需要默认值时就会得到创建表的时间!而前两种形式要到实际使用缺省值的时候才被计算, 因为它们是函数调用。因此它们可以给出每次插入行的时刻。 + 系统将在分析这个常量的时候把now转换为一个timestamp, 这样需要默认值时就会得到创建表的时间!而前两种形式要到实际使用默认值的时候才被计算, 因为它们是函数调用。因此它们可以给出每次插入行的时刻。 (参见 。) @@ -6054,10 +6046,10 @@ SELECT TIMESTAMP 'now'; -- but see tip below pg_sleep_until - sleep + 休眠 - delay + 延迟 以下函数可用于延迟服务器进程的执行: @@ -6100,7 +6092,7 @@ SELECT pg_sleep_until('tomorrow 03:00'); 枚举支持函数 - 对于枚举类型(在中描述), 有一些函数允许更清洁的编码,而不需要为一个枚举类型硬写特定的值。它们被列在中。本例假定一个枚举类型被创建为: + 对于枚举类型(见),有些函数可以避免硬编码枚举类型中的特定值,使程序更简洁。这些函数列在中。以下示例假定枚举类型按如下方式创建: CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple'); @@ -6147,8 +6139,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple enum_range(anyenum, anyenum) - 以一个数组返回在给定两个枚举值之间的范围。值必须来自相同的枚举类型。 - 如果第一个参数为空,其结果将从枚举类型的第一个值开始。如果第二参数为空,其结果将以枚举类型的最后一个值结束。 + 以有序数组返回两个给定枚举值之间的范围。两个值必须来自同一枚举类型。如果第一个参数为 null,结果从该枚举类型的第一个值开始;如果第二个参数为 null,结果以该枚举类型的最后一个值结束。 enum_range('orange'::rainbow, 'green'::rainbow) {orange,yellow,green} @@ -6166,8 +6157,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple
- 请注意,除了双参数形式的enum_range外, 这些函数忽略传递给它们的具体值,它们只关心声明的数据类型。 - 空值或类型的一个特定值可以通过,并得到相同的结果。这些函数更多地被用于一个表列或函数参数,而不是一个硬写的类型名,如示例中所使用。 + 请注意,除了enum_range的双参数形式外,这些函数都忽略传入的具体值,只关心其声明的数据类型。传入 null 或该类型的某个具体值,结果都相同。通常会将这些函数用于表列或函数参数,而不是像示例那样使用硬编码的类型名。 @@ -6177,7 +6167,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple 几何类型pointboxlseglinepath、 - polygoncircle有一大堆本地支持函数和操作符,如中所示。 + polygoncircle有大量内置支持函数和操作符,如中所示。 @@ -6217,7 +6207,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple
# - 相交的点或盒子 + 相交的点或矩形框 box '((1,-1),(-1,1))' # box '((1,1),(-2,-2))' @@ -6327,7 +6317,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple ?-| - 是否垂直? + 是否互相垂直? lseg '((0,0),(0,1))' ?-| lseg '((0,0),(1,0))' @@ -6410,13 +6400,13 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple area(object) double precision - area + 面积 area(box '((0,0),(1,1))') center(object) point - center + 中心 center(box '((0,0),(1,2))') @@ -6428,7 +6418,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple height(box) double precision - 盒子的竖直尺寸 + 矩形框的竖直尺寸 height(box '((0,0),(1,1))') @@ -6446,7 +6436,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple length(object) double precision - length + 长度 length(path '((-1,0),(1,0))') @@ -6482,7 +6472,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple width(box) double precision - 盒子的水平尺寸 + 矩形框的水平尺寸 width(box '((0,0),(1,1))') @@ -6504,37 +6494,37 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple box box(circle) box - 将圆转换为盒子 + 将圆转换为矩形框 box(circle '((0,0),2.0)') box(point) box - 将点转换为空盒子 + 将点转换为空矩形框 box(point '(0,0)') box(point, point) box - 将点转换为盒子 + 将点转换为矩形框 box(point '(0,0)', point '(1,1)') box(polygon) box - 将多边形转换为盒子 + 将多边形转换为矩形框 box(polygon '((0,0),(1,1),(2,0))') bound_box(box, box) box - 将多个盒子转换为包围盒 + 将两个矩形框转换为边界框 bound_box(box '((0,0),(1,1))', box '((3,3),(4,4))') circle circle(box) circle - 将盒子转换为圆 + 将矩形框转换为圆 circle(box '((0,0),(1,1))') @@ -6558,7 +6548,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple lseg lseg(box) lseg - 将盒子的对角线转换为线段 + 将矩形框的对角线转换为线段 lseg(box '((-1,0),(1,0))') @@ -6582,7 +6572,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple point(box) point - 盒子的中心 + 矩形框的中心 point(box '((-1,0),(1,0))') @@ -6606,7 +6596,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple polygon polygon(box) polygon - 将盒子转换为 4 个顶点的多边形 + 将矩形框转换为 4 个顶点的多边形 polygon(box '((0,0),(1,1))') @@ -6632,7 +6622,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple - 我们可以把一个point的两个组成数字当作具有索引 0 和 1 的数组访问。例如,如果t.p是一个point列,那么SELECT p[0] FROM t检索 X 坐标而 UPDATE t SET p[1] = ...改变 Y 坐标。同样,box或者lseg类型的值可以当作两个point值的数组值看待。 + 可以把一个point当作下标为 0 和 1 的数组,访问它的两个数值分量。例如,如果t.p是一个point列,那么SELECT p[0] FROM t检索 X 坐标而 UPDATE t SET p[1] = ...改变 Y 坐标。同样,box或者lseg类型的值可以当作两个point值组成的数组看待。 area 函数适用于 boxcirclepath 类型。对于 path 数据类型,只有当 path 中的点构成的路径不自相交时,area 函数才能工作。例如,path '((0,0),(0,1),(2,1),(2,2),(1,2),(1,0),(0,0))'::PATH 无法使用;但下面这个视觉上相同的 path '((0,0),(0,1),(1,1),(1,2),(2,2),(2,1),(1,1),(1,0),(0,0))'::PATH 可以使用。如果难以理解自相交与非自相交 path 的区别,可以把上述两条 path 并排画在方格纸上。 @@ -6934,7 +6924,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple 文本搜索函数和操作符 - 全文搜索 + 全文检索 函数和操作符 @@ -6947,7 +6937,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple 以及 - 总结了为全文搜索提供的函数和操作符。PostgreSQL的文本搜索功能的详细解释可参考。 + 总结了为全文检索提供的函数和操作符。PostgreSQL的文本搜索功能的详细解释可参考。 @@ -7031,10 +7021,10 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple
- tsquery 包含操作符只考虑两个查询中列出的词元,忽略组合操作符。 + tsquery 包含操作符只考虑两个查询中列出的词位,忽略组合操作符。 - 除了表中列出的操作符,tsvectortsquery 类型还定义了普通的 B-tree 比较操作符(=< 等)。这些操作符对文本搜索用处不大,但可以用于其他用途,例如在这些类型的列上建立唯一索引。 + 除了表中列出的操作符,tsvectortsquery 类型还定义了普通的 B-树比较操作符(=< 等)。这些操作符对文本搜索用处不大,但可以用于其他用途,例如在这些类型的列上建立唯一索引。 文本搜索函数 @@ -7052,28 +7042,28 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple array_to_tsvector array_to_tsvector(text[]) tsvector - 将词元数组转换为 tsvector + 将词位数组转换为 tsvector array_to_tsvector('{fat,cat,rat}'::text[]) 'cat' 'fat' 'rat' get_current_ts_config get_current_ts_config() regconfig - 获取默认的全文搜索配置 + 获取默认的文本搜索配置 get_current_ts_config() english length length(tsvector) integer - tsvector 中的词元数 + tsvector 中的词位数 length('fat:2,4 cat:3 rat:5A'::tsvector) 3 numnode numnode(tsquery) integer - tsquery 中的词元数与操作符数之和 + tsquery 中的词位数与操作符数之和 numnode('(fat & rat) | cat'::tsquery) 5 @@ -7113,7 +7103,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple 'cat':3A 'fat':2A,4A 'rat':5A - setweight 为指定词元设置权重 setweight(vector tsvector, weight "char", lexemes text[]) + setweight 为指定词位设置权重 setweight(vector tsvector, weight "char", lexemes text[]) tsvector vector 中列在 lexemes 内的元素赋予 weight setweight('fat:2,4 cat:3 rat:5B'::tsvector, 'A', '{cat,rat}') @@ -7129,7 +7119,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple to_tsquery to_tsquery( config regconfig , query text) tsquery - 规范化单词并转换为 tsquery + 正规化单词并转换为 tsquery to_tsquery('english', 'The & Fat & Rats') 'fat' & 'rat' @@ -7164,7 +7154,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple ts_delete(vector tsvector, lexemes text[]) tsvector - vector 中移除 lexemes 所列词元的所有出现 + vector 中移除 lexemes 所列词位的所有出现 ts_delete('fat:2,4 cat:3 rat:5A'::tsvector, ARRAY['fat','rat']) 'cat':3 @@ -7234,7 +7224,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsvector_to_array tsvector_to_array(tsvector) text[] - tsvector 转换为词元数组 + tsvector 转换为词位数组 tsvector_to_array('fat:2,4 cat:3 rat:5A'::tsvector) {cat,fat,rat} @@ -7268,13 +7258,13 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple - 所有接受一个可选的regconfig参数的文本搜索函数在该参数被忽略时,使用由指定的配置。 + 所有接受一个可选的regconfig参数的文本搜索函数在省略该参数时,会使用由指定的配置。 中的函数被单独列出,因为它们通常不被用于日常的文本搜索操作。 - 它们主要有助于开发和调试新的文本搜索配置。 + 它们有助于开发和调试新的文本搜索配置。
@@ -7321,14 +7311,14 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple ts_token_type ts_token_type(parser_name text, OUT tokid integer, OUT alias text, OUT description text) setof record - 获取解析器定义的记号类型 + 获取解析器定义的词元类型 ts_token_type('default') (1,asciiword,"Word, all ASCII") ... ts_token_type(parser_oid oid, OUT tokid integer, OUT alias text, OUT description text) setof record - 获取解析器定义的记号类型 + 获取解析器定义的词元类型 ts_token_type(3722) (1,asciiword,"Word, all ASCII") ... @@ -7750,7 +7740,7 @@ SELECT xmlexists('//town[text() = ''Toronto'']' PASSING BY REF 'Tor - 示例: + 示例: - 示例: + 示例: test', ARRAY[ARRAY['my', 'http://example.com']]); @@ -7862,7 +7852,7 @@ SELECT xpath('//mydefns:b/text()', 'test - 示例: + 示例: test', ARRAY[ARRAY['my', 'http://example.com']]); @@ -8859,17 +8849,17 @@ table2-mapping - 如果输出列的类型是jsonjsonb,则会精确地重制JSON值。 - + 如果输出列的类型是jsonjsonb,则 JSON 值会被原样保留。 + - 如果输出列是复合(行)类型,且JSON值是JSON对象,则该对象的字段将转换为输出行类型的列,通过这些规则的递归应用程序。 + 如果输出列是复合(行)类型,且JSON值是JSON对象,则该对象的字段会通过递归应用这些规则,被转换为输出行类型的各列。 - 同样,如果输出列是数组类型,而JSON值是JSON数组,则通过这些规则的递归应用程序将JSON数组的元素转换为输出数组的元素。 + 同样,如果输出列是数组类型,而JSON值是JSON数组,则会通过递归应用这些规则,把JSON数组的元素转换为输出数组的元素。 @@ -8877,8 +8867,8 @@ table2-mapping - 否则,JSON值的普通文本表示将被提供给输入转换函数,以确定列的数据类型。 - + 否则,JSON 值的普通文本表示会被送入该列数据类型的输入转换函数。 + @@ -8905,7 +8895,7 @@ table2-mapping 序列操作函数 - sequence + 序列 nextval @@ -8921,7 +8911,7 @@ table2-mapping - 本节描述对序列对象进行操作的函数,也称为序列生成器或简称序列。 + 本节描述用于操作序列对象(也称为序列生成器,或简称序列)的函数。 序列对象是使用创建的特殊单行表。 序列对象通常用于为表中的行生成惟一标识符。在中列出的序列函数,提供了简单的、多用户安全方法,用于从序列对象中获取连续的序列值。 @@ -8977,10 +8967,10 @@ nextval('foo') 在搜索路径中查找 fo PostgreSQL 8.1 之前,序列函数的参数类型是 text,而不是 regclass;上述从文本字符串到 OID 值的转换会在每次调用时于运行期间执行。为保持向后兼容,这种能力仍然存在,但内部现在会在调用函数前,通过从 textregclass 的隐式强制转换来处理。 - 将序列函数的参数写成不加修饰的字符串字面量时,它会成为以下类型的常量:regclass。由于它实际上只是一个 OID,即使后来发生重命名、模式变更等情况,它仍会指向最初标识的序列。这种早绑定行为通常适用于列默认值和视图中的序列引用。但有时你可能希望采用后绑定,在运行时解析序列引用。要获得后期绑定行为,应强制将常量存储为text常量,而不是regclass: + 将序列函数的参数写成不加修饰的字符串字面量时,它会成为以下类型的常量:regclass。由于它实际上只是一个 OID,即使后来发生重命名、模式变更等情况,它仍会指向最初标识的序列。这种早绑定行为通常适用于列默认值和视图中的序列引用。但有时你可能希望采用后绑定,在运行时解析序列引用。要获得后绑定行为,应强制将常量存储为text常量,而不是regclass nextval('foo'::text) foo运行时被查找 -请注意,后期绑定是下列旧版本唯一支持的行为:PostgreSQL8.1 之前的版本,因此可能需要这样做来保留旧应用的语义。 +请注意,后绑定是下列旧版本唯一支持的行为:PostgreSQL8.1 之前的版本,因此可能需要这样做来保留旧应用的语义。 当然,序列函数的参数既可以是常量,也可以是表达式。如果它是文本表达式,隐式强制转换就会导致运行时查找。 @@ -8994,7 +8984,7 @@ nextval('foo'::text) foo运行时被查 如果使用默认参数创建序列对象,连续调用 nextval 会返回从 1 开始的连续值。可以在 命令中使用特殊参数获得其他行为;更多信息请参见该命令的参考页。 - 这个函数需要USAGEUPDATE权限在序列上。 + 这个函数需要序列上的USAGEUPDATE权限。 @@ -9099,7 +9089,7 @@ CASE WHEN condition THEN result - CASE子句可以用于任何表达式可以出现的地方。每一个condition是一个返回boolean结果的表达式。如果结果为真,那么CASE表达式的结果就是符合条件的result,并且剩下的CASE表达式不会被处理。如果条件的结果不为真,那么以相同方式搜寻任何随后的WHEN子句。如果没有WHEN condition为真,那么CASE表达式的值就是在ELSE子句里的result。如果省略了ELSE子句而且没有条件为真,结果为空。 + CASE子句可以用于任何表达式可以出现的地方。每一个condition是一个返回boolean结果的表达式。如果结果为真,那么CASE表达式的结果就是紧随该条件后的result,并且剩下的CASE表达式不会被处理。如果条件的结果不为真,那么以相同方式搜寻任何随后的WHEN子句。如果没有WHEN condition为真,那么CASE表达式的值就是在ELSE子句里的result。如果省略了ELSE子句而且没有条件为真,结果为 null。 @@ -9143,7 +9133,7 @@ CASE expression END - 第一个expression会被计算,然后与所有在WHEN子句中的每一个value对比,直到找到一个相等的。如果没有找到匹配的,则返回在ELSE子句中的result(或者控制)。 这类似于 C 里的switch语句。 + 第一个expression会被计算,然后与所有在WHEN子句中的每一个value对比,直到找到一个相等的。如果没有找到匹配的,则返回在ELSE子句中的result(或者 null 值)。 这类似于 C 里的switch语句。 @@ -9174,11 +9164,7 @@ SELECT ... WHERE CASE WHEN x <> 0 THEN y/x > 1.5 ELSE false END; - 如中所述,在有几种情况中一个表达式的子表达式 - 会被计算多次,因此CASE只计算必要的表达式这 - 一原则并非不可打破。例如一个常量子表达式1/0通常将会在规划时导致一次 - 除零错误,即便它位于一个执行时永远也不会进入的CASE分支时也是 - 如此。 + 如所述,在多种情况下,表达式中的子表达式会在不同阶段求值,因此CASE只计算必要的子表达式这一原则并非绝对成立。例如,常量子表达式1/0通常会在规划时导致除零错误,即便它位于一个运行时永远不会进入的CASE分支中也是如此。 @@ -9202,17 +9188,19 @@ SELECT ... WHERE CASE WHEN x <> 0 THEN y/x > 1.5 ELSE false END; COALESCE(value , ...) - COALESCE函数返回参数中第一个不为 null 的值。只有所有参数都为 null 时,才返回 null。它常用于在检索数据以供显示时,用默认值替换 null 值。例如: + COALESCE函数返回参数中第一个不为 null 的值。只有所有参数都为 null 时,才返回 null。它常用于在检索数据以供显示时,用默认值替换 null 值。例如: + SELECT COALESCE(description, short_description, '(none)') ... -此表达式返回description,前提是它不为 null,否则返回short_description,前提是它不为 null,否则返回(none)。 + + 此表达式返回description,前提是它不为 null,否则返回short_description,前提是它不为 null,否则返回(none) - 所有参数都必须转换为一个公共数据类型,它将是结果的类型 (详情参见 )。 + 所有参数都必须能转换为同一个数据类型,它将是结果的类型(详情参见)。 - 和CASE表达式一样,COALESCE将不会 计算无助于判断结果的参数;也就是说,在第一个非空参数右边的参数不会被计算。这个 SQL 标准函数提供了类似于NVLIFNULL的能力,它们被用在某些其他数据库系统中。 + 和CASE表达式一样,COALESCE只计算确定结果所需的参数;也就是说,在第一个不为 null 的参数右边的参数不会被计算。这个 SQL 标准函数提供了类似于NVLIFNULL的能力,它们被用在某些其他数据库系统中。 @@ -9228,12 +9216,12 @@ SELECT COALESCE(description, short_description, '(none)') ... - 当value1value2相等时,NULLIF返回一个空值。 + 当value1value2相等时,NULLIF返回 null。 否则它返回value1。 这些可以用于执行前文给出的COALESCE示例的逆操作: SELECT NULLIF(value, '(none)') ... - 在这个示例中,如果value(none),将返回空值,否则返回value的值。 + 在这个示例中,如果value(none),将返回 null,否则返回value的值。 @@ -9268,11 +9256,11 @@ SELECT NULLIF(value, '(none)') ... - GREATESTLEAST函数从一个任意的数字表达式列表里选取最大或者最小的数值。 这些表达式必须都可以转换成一个普通的数据类型,它将会是结果类型 (参阅获取细节)。列表中的 NULL 数值将被忽略。只有所有表达式的结果都是 NULL 的时候,结果才会是 NULL。 + GREATESTLEAST函数从由任意数量的表达式组成的列表中选取最大值或最小值。这些表达式都必须能转换为同一个数据类型,该类型将作为结果类型(详情参见)。列表中的 NULL 值会被忽略。只有所有表达式的求值结果都为 NULL 时,结果才为 NULL。 - 请注意GREATESTLEAST都不是 SQL 标准,但却是很常见的扩展。某些其他数据库让它们在任何参数为 NULL 时返回 NULL,而不是在所有参数都为 NULL 时才返回 NULL。 + 请注意GREATESTLEAST都未包含在 SQL 标准中,但却是很常见的扩展。某些其他数据库让它们在任何参数为 NULL 时返回 NULL,而不是在所有参数都为 NULL 时才返回 NULL。 @@ -9388,12 +9376,12 @@ SELECT NULLIF(value, '(none)') ...
- 数组排序操作符(<>= 等)使用元素数据类型的默认 B-tree 比较函数,逐个元素比较数组内容,并根据第一个差异决定排序顺序。多维数组的元素按行优先顺序访问(最后一个下标变化最快)。如果两个数组的内容相同,但维度不同,则由维度信息中的第一个差异决定排序顺序。(这与 PostgreSQL 8.2 之前的版本不同:旧版本会将内容相同的两个数组视为相等,即使它们的维数或下标范围不同。) + 数组排序操作符(<>= 等)使用元素数据类型的默认 B-树比较函数,逐个元素比较数组内容,并根据第一个差异决定排序顺序。多维数组的元素按行优先顺序访问(最后一个下标变化最快)。如果两个数组的内容相同,但维度信息不同,则由维度信息中的第一个差异决定排序顺序。(这与 PostgreSQL 8.2 之前的版本不同:旧版本会将内容相同的两个数组视为相等,即使它们的维数或下标范围不同。) 数组包含操作符(<@@>)在一个数组的每个元素都出现在另一个数组中时,认为前者包含在后者中。重复元素不会被特殊处理,因此 ARRAY[1]ARRAY[1,1] 被认为彼此包含。 - 参阅获取有关数组操作符行为的更多细节。有关哪些操作符支持被索引的操作,请参阅。 + 参阅获取有关数组操作符行为的更多细节。有关哪些操作符支持索引操作,请参阅 @@ -9679,7 +9667,7 @@ NULL baz(3 rows)
string_to_array 中,如果分隔符参数为 NULL,输入字符串中的每个字符都会成为结果数组中的独立元素。如果分隔符为空字符串,则将整个输入字符串作为单元素数组返回。否则,在分隔符字符串的每次出现处拆分输入字符串。 - string_to_array 中,如果省略空值字符串参数,或该参数为 NULL,则不会将任何输入子串替换为 NULL。在 array_to_string 中,如果省略空值字符串参数,或该参数为 NULL,则直接跳过数组中的所有空元素,不在输出字符串中表示它们。 + string_to_array 中,如果省略 null 替代字符串参数,或该参数为 NULL,则不会将任何输入子串替换为 NULL。在 array_to_string 中,如果省略 null 替代字符串参数,或该参数为 NULL,则直接跳过数组中的所有 null 元素,不在输出字符串中表示它们。 string_to_array 的行为与 PostgreSQL 9.1 之前的版本有两点不同。首先,当输入字符串长度为零时,它返回空数组(零元素),而不是 NULL。其次,如果分隔符字符串为 NULL,该函数会将输入拆分为单独的字符,而不是像以前那样返回 NULL。 @@ -9839,7 +9827,7 @@ NULL baz(3 rows)
- - difference + 差集 int8range(5,15) - int8range(10,20) [5,10) @@ -9848,7 +9836,7 @@ NULL baz(3 rows)
- 简单比较操作符 <><=>= 首先比较下界,只有下界相等时才比较上界。这些比较对范围通常用处不大,但提供这些操作符可以在范围上建立 B-tree 索引。 + 简单比较操作符 <><=>= 首先比较下界,只有下界相等时才比较上界。这些比较对范围通常用处不大,但提供这些操作符可以在范围上建立 B-树索引。 涉及空范围时,左侧、右侧和相邻操作符总是返回假;也就是说,空范围不被视为位于任何其他范围之前或之后。 @@ -9983,7 +9971,7 @@ NULL baz(3 rows)
- 如果范围为空,或请求的边界是无限的,lowerupper 函数返回空值。对于空范围,lower_incupper_inclower_infupper_inf 函数都返回假。 + 如果范围为空,或请求的边界是无限的,lowerupper 函数返回 null。对于空范围,lower_incupper_inclower_infupper_inf 函数都返回假。 @@ -10015,7 +10003,7 @@ NULL baz(3 rows)
array_agg array_agg(expression) 任意非数组类型 参数类型的数组 - No + 将输入值(包括 null)串接为数组
@@ -10023,7 +10011,7 @@ NULL baz(3 rows)
array_agg(expression) 任意数组类型 与参数数据类型相同 - No + 将输入数组串接为维数多一维的数组(所有输入的维数必须相同,且不能是空数组或 null)
@@ -10095,7 +10083,7 @@ NULL baz(3 rows)
json_agg json_agg(expression) any json - No + 将值(包括 null)聚合为 JSON 数组
@@ -10103,7 +10091,7 @@ NULL baz(3 rows)
jsonb_agg jsonb_agg(expression) any jsonb - No + 将值(包括 null)聚合为 JSON 数组
@@ -10113,7 +10101,7 @@ NULL baz(3 rows)
(any, any)
json - No + 将名称/值对聚合为 JSON 对象;值可以为 null,名称不能为 null
@@ -10123,7 +10111,7 @@ NULL baz(3 rows)
(any, any)
jsonb - No + 将名称/值对聚合为 JSON 对象;值可以为 null,名称不能为 null
@@ -10147,7 +10135,7 @@ NULL baz(3 rows)
string_agg string_agg(expression, delimiter) texttext)或(byteabytea 与参数类型相同 - No + 将非空输入值串接为字符串,以分隔符分隔
@@ -10163,7 +10151,7 @@ NULL baz(3 rows)
xmlagg xmlagg(expression) xml xml - No + 串接非空 XML 值(另见
@@ -10171,9 +10159,7 @@ NULL baz(3 rows)
- 应该注意的是,除了count之外,这些函数在没有选择行时返回空值。 - 特别地,行数的sum返回空(null),而不是预期的零,array_agg在没有输入行时返回空(null)而不是空数组。 - coalesce函数可以在必要时用零或空数组代替空(null)。 + 需要注意,除了count之外,这些函数在没有选中任何行时都会返回空值。特别地,sum在没有输入行时返回空值,而不是预期中的零;array_agg在没有输入行时返回空值,而不是空数组。必要时,可以用coalesce函数把空值替换成零或空数组。 支持部分模式的聚合函数可以参与并行聚合等多种优化。 @@ -10197,16 +10183,11 @@ SELECT count(*) FROM sometable; - 聚合函数 array_agg,json_agg, jsonb_agg,json_object_agg, jsonb_object_agg, - string_agg,和 xmlagg,以及类似的用户定义的聚合函数,根据输入值的顺序产生富有意义的不同的结果值。 - 默认情况下,这种排序是不指定的,但可以通过在聚合调用中写入ORDER BY子句来控制,如所示。 - 或者,从排序的子查询提供输入值通常也可以。例如: - + 聚合函数array_aggjson_aggjsonb_aggjson_object_aggjsonb_object_aggstring_aggxmlagg,以及类似的用户定义聚合函数,其结果值会随输入值的顺序发生实质性变化。默认情况下,输入顺序未指定,但可以在聚合调用中写入ORDER BY子句来控制,如所示。也可以用已排序的子查询提供输入值,这通常也能奏效。例如: - - 注意,如果外部查询级别包含其他处理,例如关联,则此方法可能会失败,因为这可能导致子查询的输出在计算聚合之前重新排序。 + 需要注意,如果外层查询包含连接等额外处理,这种方法可能失效,因为子查询的输出可能在计算聚合之前被重新排序。 列出了统计分析常用的聚合函数。(将它们单独列出只是为了避免让更常用的聚合函数列表过于拥挤。)说明中提到的 N 表示所有输入表达式均非空的输入行数。在所有情况下,如果计算没有意义,例如 N 为零,都会返回空值。 @@ -10238,7 +10219,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; 相关性 corr corr(Y, X) double precision double precision - Yes + 相关系数
@@ -10246,7 +10227,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; 协方差 总体 covar_pop covar_pop(Y, X) double precision double precision - Yes + 总体协方差
@@ -10254,7 +10235,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; 协方差 样本 covar_samp covar_samp(Y, X) double precision double precision - Yes + 样本协方差
@@ -10262,7 +10243,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; regr_avgx regr_avgx(Y, X) double precision double precision - Yes + 自变量的平均值(sum(X)/N
@@ -10270,7 +10251,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; regr_avgy regr_avgy(Y, X) double precision double precision - Yes + 因变量的平均值(sum(Y)/N
@@ -10278,7 +10259,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; regr_count regr_count(Y, X) double precision bigint - Yes + 两个表达式都非空的输入行数
@@ -10286,7 +10267,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; 回归截距 regr_intercept regr_intercept(Y, X) double precision double precision - Yes + 由(XY)数值对确定的最小二乘拟合线性方程的 y 轴截距 @@ -10294,7 +10275,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; regr_r2 regr_r2(Y, X) double precision double precision - Yes + 相关系数的平方 @@ -10302,7 +10283,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; 回归斜率 regr_slope regr_slope(Y, X) double precision double precision - Yes + 由(XY)数值对确定的最小二乘拟合线性方程的斜率 @@ -10310,7 +10291,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; regr_sxx regr_sxx(Y, X) double precision double precision - Yes + sum(X^2) - sum(X)^2/N(自变量的平方和 @@ -10318,7 +10299,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; regr_sxy regr_sxy(Y, X) double precision double precision - Yes + sum(X*Y) - sum(X) * sum(Y)/N(自变量与因变量的乘积和 @@ -10326,7 +10307,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; regr_syy regr_syy(Y, X) double precision double precision - Yes + sum(Y^2) - sum(Y)^2/N(因变量的平方和 @@ -10334,7 +10315,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; 标准差 stddev stddev(expression) smallintintbigintrealdouble precisionnumeric 浮点参数返回 double precision,其他情况返回 numeric - Yes + stddev_samp 的历史别名 @@ -10342,7 +10323,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; 标准差 总体 stddev_pop stddev_pop(expression) smallintintbigintrealdouble precisionnumeric 浮点参数返回 double precision,其他情况返回 numeric - Yes + 输入值的总体标准差 @@ -10350,7 +10331,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; 标准差 样本 stddev_samp stddev_samp(expression) smallintintbigintrealdouble precisionnumeric 浮点参数返回 double precision,其他情况返回 numeric - Yes + 输入值的样本标准差 @@ -10358,7 +10339,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; variance variance(expression) smallintintbigintrealdouble precisionnumeric 浮点参数返回 double precision,其他情况返回 numeric - Yes + var_samp 的历史别名 @@ -10366,7 +10347,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; 方差 总体 var_pop var_pop(expression) smallintintbigintrealdouble precisionnumeric 浮点参数返回 double precision,其他情况返回 numeric - Yes + 输入值的总体方差(总体标准差的平方) @@ -10374,7 +10355,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; 方差 样本 var_samp var_samp(expression) smallintintbigintrealdouble precisionnumeric 浮点参数返回 double precision,其他情况返回 numeric - Yes + 输入值的样本方差(样本标准差的平方) @@ -10384,7 +10365,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; 列出了一些使用有序集聚合语法的聚合函数。这些函数有时被称为逆分布函数。 - ordered-set aggregate + 有序集聚合 内置 @@ -10409,22 +10390,22 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; - mode 统计 mode() WITHIN GROUP (ORDER BY sort_expression) + 众数 统计 mode() WITHIN GROUP (ORDER BY sort_expression) 任意可排序类型 与排序表达式相同 - No + 返回出现次数最多的输入值(若有多个结果同样频繁,则任意选择第一个) - 百分位数 连续 percentile_cont(fraction) WITHIN GROUP (ORDER BY sort_expression) + 百分位点 连续 percentile_cont(fraction) WITHIN GROUP (ORDER BY sort_expression) double precision double precisioninterval 与排序表达式相同 - No - 连续百分位数:返回排序中与指定比例对应的值,必要时在相邻输入项之间插值 + + 连续百分位点:返回排序中与指定比例对应的值,必要时在相邻输入项之间插值 @@ -10434,8 +10415,8 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; double precisioninterval 排序表达式类型的数组 - No - 多个连续百分位数:返回形状与 fractions 参数一致的结果数组,将每个非空元素替换为与该百分位数对应的值 + + 多个连续百分位点:返回形状与 fractions 参数一致的结果数组,将每个非空元素替换为与该百分位点对应的值 @@ -10443,7 +10424,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; double precision 任意可排序类型 与排序表达式相同 - No + 离散百分位数:返回排序位置等于或超过指定比例的第一个输入值 @@ -10454,7 +10435,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; 任意可排序类型 排序表达式类型的数组 - No + 多个离散百分位数:返回形状与 fractions 参数一致的结果数组,将每个非空元素替换为与该百分位数对应的输入值 @@ -10462,10 +10443,10 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab;
- 中列出的所有聚合函数都忽略其排序输入中的空值。对于接受 fraction 参数的函数,该比例值必须在 0 和 1 之间,否则会报错。但空的比例值只会产生空结果。 + 中列出的所有聚合函数都忽略其排序输入中的空值。对于接受 fraction 参数的函数,该比例值必须在 0 和 1 之间,否则会报错。但 null 比例值只会产生 null 结果。 - hypothetical-set aggregate + 假想集聚合 内置 @@ -10493,7 +10474,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; VARIADIC "any" VARIADIC "any" bigint - No + 假设行的排名,重复行会造成排名空缺 @@ -10502,7 +10483,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; VARIADIC "any" VARIADIC "any" bigint - No + 假设行的排名,没有空缺 @@ -10511,7 +10492,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; VARIADIC "any" VARIADIC "any" double precision - No + 假设行的相对排名,范围为 0 到 1 @@ -10520,7 +10501,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; VARIADIC "any" VARIADIC "any" double precision - No + 假设行的相对排名,范围为 1/N 到 1 @@ -10649,31 +10630,31 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; lag lag(value anyelement [, offset integer [, default anyelement ]]) - same type as value + value 相同的类型 返回在分区内当前行之前 offset 行处计算的 value;如果没有这样的行,则返回 default(其类型必须与 value 相同)。offsetdefault 都针对当前行求值。如果省略,offset 默认为 1,default 默认为 null lead lead(value anyelement [, offset integer [, default anyelement ]]) - same type as value + value 相同的类型 返回在分区内当前行之后 offset 行处计算的 value;如果没有这样的行,则返回 default(其类型必须与 value 相同)。offsetdefault 都针对当前行求值。如果省略,offset 默认为 1,default 默认为 null first_value first_value(value any) - same type as value + value 相同的类型 返回在窗口帧第一行处计算的 value last_value last_value(value any) - same type as value + value 相同的类型 返回在窗口帧最后一行处计算的 value nth_value nth_value(value any, nth integer) - same type as value + value 相同的类型 返回在窗口帧第 nth 行处计算的 value(从 1 开始计数);没有这样的行时返回 null @@ -10695,8 +10676,8 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; 当一个聚合函数被用作窗口函数时,它将在当前行的窗口帧内的行上聚合。 - 一个使用ORDER BY和默认窗口帧定义的聚合产生一种运行时求和类型的行为,这可能是或者不是想要的结果。 - 为了获取在整个分区上的聚合,忽略ORDER BY或者使用ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING。 + 一个使用ORDER BY和默认窗口帧定义的聚合产生一种累计求和类型的行为,这可能是或者不是想要的结果。 + 为了获取在整个分区上的聚合,省略ORDER BY或者使用ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING。 其它窗口帧声明可以用来获得其它的效果。 @@ -10705,7 +10686,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; SQL 标准为leadlagfirst_valuelast_valuenth_value定义了一个RESPECT NULLSIGNORE NULLS选项。 这在PostgreSQL中没有实现:行为总是与标准的默认相同,即RESPECT NULLS。 - 同样,标准中用于nth_valueFROM FIRSTFROM LAST选项没有实现: 只有支持默认的FROM FIRST行为(你可以通过反转ORDER BY的排序达到FROM LAST的结果)。 + 同样,标准中用于nth_valueFROM FIRSTFROM LAST选项没有实现: 只支持默认的FROM FIRST行为(你可以通过反转ORDER BY的排序达到FROM LAST的结果)。 @@ -10741,11 +10722,11 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; - subquery + 子查询 - 本节描述PostgreSQL中可用的SQL兼容的子查询表达式。所有本节中成文的表达式都返回布尔值(真/假)结果。 + 本节描述PostgreSQL中可用的SQL兼容的子查询表达式。本节介绍的所有表达式形式都返回布尔值(真/假)结果。 @@ -10760,7 +10741,7 @@ EXISTS (subquery) - 子查询可以引用来自周围的查询的变量,这些变量在该子查询的任何一次计算中都起常量的作用。 + 子查询可以引用外层查询的变量,这些变量在该子查询的任何一次计算中都起常量的作用。 @@ -10772,7 +10753,7 @@ EXISTS (subquery) - 下面这个简单的示例类似在col2上的一次内联接,但是它为每个 tab1的行生成最多一个输出,即使存在多个匹配tab2的行也如此∶ + 下面这个简单的示例类似在col2上的一次内连接,但是它为每个 tab1的行最多生成一行输出,即使存在多个匹配tab2的行也如此: SELECT col1 FROM tab1 @@ -10789,15 +10770,15 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 右手边是一个圆括弧括起来的子查询, 它必须正好只返回一个列。左手边表达式将被计算并与子查询结果逐行进行比较。 如果找到任何等于子查询行的情况,那么IN的结果就是。 如果没有找到相等行,那么结果是(包括子查询没有返回任何行的情况)。 + 右手边是一个圆括号括起来的子查询,它必须恰好返回一列。左手边表达式会被求值,并与子查询结果逐行比较。如果找到任意相等的子查询行,那么IN的结果就是。如果没有找到相等行,那么结果就是(包括子查询不返回任何行的情况)。 - 请注意如果左手边表达式得到空值,或者没有相等的右手边值, 并且至少有一个右手边行得到空值,那么IN结构的结果将是空值,而不是假。这个行为是遵照 SQL 处理空值的一般规则的。 + 请注意,如果左侧表达式得到空值,或者右侧没有相等的值且至少有一行得到空值,则IN结构的结果将是空值,而不是假。这符合 SQL 对空值布尔组合的一般规则。 - 和EXISTS一样,假设子查询将被完成运行完全是不明智的。 + 和EXISTS一样,假定子查询一定会完整运行并不明智。 @@ -10805,7 +10786,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 这种形式的IN的左手边是一个行构造器, 如中所述。 右手边是一个圆括弧子查询,它必须返回和左手边返回的行中表达式所构成的完全一样多的列。 左手边表达式将被计算并与子查询结果逐行进行比较。如果找到任意相等的子查询行,则IN的结果为。如果没有找到相等行, 那么结果为(包括子查询不返回行的情况)。 + 这种形式的IN左手边是一个行构造器,如中所述。右手边是一个圆括号括起来的子查询,它必须返回与左手边行中表达式数量完全相同的列数。左手边表达式会被求值,并与子查询结果逐行比较。如果找到任意相等的子查询行,则IN的结果为。如果没有找到相等行,那么结果为(包括子查询不返回任何行的情况)。 @@ -10821,15 +10802,15 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 右手边是一个用圆括弧包围的子查询,它必须返回正好一个列。左手边表达式将被计算并与子查询结果逐行进行比较。 如果只找到不相等的子查询行(包括子查询不返回行的情况),那么NOT IN的结果是。 如果找到任何相等行,则结果为。 + 右手边是一个圆括号括起来的子查询,它必须恰好返回一列。左手边表达式会被求值,并与子查询结果逐行比较。如果只找到不相等的子查询行(包括子查询不返回任何行的情况),那么NOT IN的结果是。如果找到任何相等行,则结果为 - 请注意如果左手边表达式得到空值,或者没有相等的右手边值, 并且至少有一个右手边行得到空值,那么NOT IN结构的结果将是空值,而不是真。这个行为是遵照 SQL 处理空值的一般规则的。 + 请注意,如果左侧表达式得到空值,或者右侧没有相等的值且至少有一行得到空值,则NOT IN结构的结果将是空值,而不是真。这符合 SQL 对空值布尔组合的一般规则。 - 和EXISTS一样,假设子查询将被完成运行完全是不明智的。 + 和EXISTS一样,假定子查询一定会完整运行并不明智。 @@ -10837,7 +10818,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 这种形式的NOT IN的左手边是一个行构造器, 如中所述。 右手边是一个圆括弧子查询,它必须返回和左手边返回的行中表达式所构成的完全一样多的列。 左手边表达式将被计算并与子查询结果逐行进行比较。如果找到不等于子查询行的行,则NOT IN的结果为。如果找到相等行, 那么结果为(包括子查询不返回行的情况)。 + 这种形式的NOT IN左侧是一个行构造器,如中所述。右侧是一个用圆括号括起来的子查询,必须返回与左侧行中表达式数量完全相同的列数。对左侧表达式求值后,将其按行与子查询结果的每一行比较。如果只找到不相等的子查询行(包括子查询不返回任何行的情况),则NOT IN的结果为。如果找到任何相等行,则结果为 @@ -10862,11 +10843,11 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 请注意如果没有任何成功并且至少有一个右手边行为该操作符结果生成空值, 那么ANY结构的结果将是空值,而不是假。 这个行为是遵照 SQL 处理空值布尔组合的一般规则制定的。 + 请注意,如果没有任何比较返回真,并且至少有一个右侧行的操作符结果为空值,则ANY结构的结果将是空值,而不是假。这符合 SQL 对空值布尔组合的一般规则。 - 和EXISTS一样,假设子查询将被完成运行完全是不明智的。 + 和EXISTS一样,假定子查询一定会完整运行并不明智。 @@ -10875,7 +10856,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 这种形式的左侧是一个行构造器,如所述。右侧是一个用括号括起来的子查询,它必须返回与左侧行中表达式数量完全相同的列数。左侧表达式会被求值,并使用给定的operator与子查询结果的每一行逐行比较。如果比较对任何子查询行返回真,则ANY的结果为。如果比较对每一个子查询行都返回假,则结果为(包括子查询不返回行的情况)。如果比较对任何行都不返回真,并且至少有一次比较返回 NULL,则结果为 NULL。 + 这种形式的ANY左侧是一个行构造器,如所述。右侧是一个用括号括起来的子查询,它必须返回与左侧行中表达式数量完全相同的列数。左侧表达式会被求值,并使用给定的operator与子查询结果的每一行逐行比较。如果比较对任何子查询行返回真,则ANY的结果为。如果比较对每一个子查询行都返回假,则结果为(包括子查询不返回行的情况)。如果比较对任何行都不返回真,并且至少有一次比较返回 NULL,则结果为 NULL。 @@ -10891,7 +10872,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 这种形式的 ALL 右侧是一个用括号括起来的子查询,它必须只返回一列。左侧表达式会被求值,并使用给定的 operator 与子查询结果的每一行进行比较。该操作符必须产生布尔结果。如果所有行都得到真(包括子查询没有返回任何行的情况),ALL 的结果就是。如果发现任何假值结果,结果就是。如果比较对任何行都不返回假,并且至少有一次比较返回 NULL,则结果为 NULL。 + 右侧是一个用圆括号括起来的子查询,必须恰好返回一列。左侧表达式会被求值,并使用给定的operator与子查询结果的每一行进行比较。该操作符必须产生布尔结果。如果所有行都得到真(包括子查询不返回任何行的情况),则ALL的结果为。如果得到任何假值结果,则结果为。如果与任何子查询行的比较都不返回假,并且至少有一次比较返回 NULL,则结果为 NULL。 @@ -10899,7 +10880,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 和EXISTS一样,假设子查询将被完成运行完全是不明智的。 + 和EXISTS一样,假定子查询一定会完整运行并不明智。 @@ -10928,7 +10909,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 左手边是一个行构造器,如所述。 右手边是一个圆括弧括起来的子查询,该查询必须返回和左手边行中表达式数目完全一样的列。 另外,该子查询不能返回超过一行的数量(如果它返回零行,那么结果就是空值)。 左手边被计算并逐行与右手边的子查询结果行比较。 + 左侧是一个行构造器,如所述。右侧是一个用圆括号括起来的子查询,必须返回与左侧行中表达式数量完全相同的列数。此外,该子查询不能返回超过一行;如果它返回零行,则结果为空值。对左侧求值后,将所得的行与子查询返回的唯一一行进行比较。 @@ -10967,12 +10948,12 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 逐行比较 + 行比较 比较 - 逐行 + 复合类型 @@ -10989,7 +10970,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 本节描述几个特殊的结构,用于在值的组之间进行多重比较。这些形式语法上和前面一节的子查询形式相关,但是不涉及子查询。 这种形式涉及的数组子表达式是PostgreSQL的扩展; 其它的是SQL兼容的。所有本节记录的表达式形式都返回布尔(Boolean)结果(真/假)。 + 本节描述几个特殊的结构,用于在值的组之间进行多重比较。这些形式语法上和前面一节的子查询形式相关,但是不涉及子查询。 涉及数组子表达式的形式是PostgreSQL的扩展; 其余形式是SQL兼容的。本节介绍的所有表达式形式都返回布尔(Boolean)结果(真/假)。 @@ -10999,7 +10980,8 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); expression IN (value , ...) - 右侧是用圆括号括起的表达式列表。结果为true,条件是左侧表达式的结果等于右侧表达式中的任意一个。这是以下写法的简写: + 右侧是一个用圆括号括起来的表达式列表。如果左侧表达式的结果等于右侧任一表达式的结果,则结果为。这等价于以下写法: + expression = value1 OR expression = value2 @@ -11020,7 +11002,8 @@ OR expression NOT IN (value , ...) - 右侧是用圆括号括起的表达式列表。结果为true,条件是左侧表达式的结果与右侧的所有表达式都不相等。这是以下写法的简写: + 右侧是一个用圆括号括起来的表达式列表。如果左侧表达式的结果与右侧所有表达式的结果都不相等,则结果为。这等价于以下写法: + expression <> value1 AND expression <> value2 @@ -11042,7 +11025,7 @@ AND - <literal>ANY</literal>/<literal>SOME</literal> (array) + <literal>ANY</literal>/<literal>SOME</literal>(数组) expression operator ANY (array expression) @@ -11063,7 +11046,7 @@ AND - <literal>ALL</literal> (array) + <literal>ALL</literal>(数组) expression operator ALL (array expression) @@ -11087,20 +11070,7 @@ AND - 每一边都是一个行构造器, - 如在中描述的那样。 - 这两个行构造器必须具有相同数量的字段。 - 给定的operator应用于每一对 - 对应的字段。(由于字段可能是不同类型的,这意味着每对可能选择不同的具体操作符。) - 所有选定的操作符必须是某个B-树操作符类的成员,或者是B-树操作符类的=成员的否定形式, - 这意味着只有当operator是 - =、 - <>、 - <、 - <=、 - >或 - >=时才可能进行行构造器比较, - 或者具有类似于这些操作符的语义。 + 两侧都是行构造器,如所述。两个行构造器必须具有相同数量的字段。给定的operator应用于每一对对应字段。(由于字段可能具有不同的类型,因此可能为各对字段选择不同的具体操作符。)所选操作符必须是某个 B-树操作符类的成员,或者是 B-树操作符类中=成员的否定操作符。这意味着只有当operator=<><<=>>=,或具有与这些操作符类似的语义时,才可以进行行构造器比较。 @@ -11144,21 +11114,21 @@ AND - SQL 规范要求在结果依赖于比较两个 NULL 值或者一个 NULL 与一个非 NULL 时逐行比较返回 NULL。 + SQL 规范要求在结果依赖于比较两个 NULL 值或者一个 NULL 与一个非 NULL 时行比较返回 NULL。 PostgreSQL只有在比较两个行构造器(如)的结果或者比较一个行构造器与一个子查询的输出时才这样做(如中所述)。 - 在其他比较两个复合类型值的环境中,两个 NULL 域值被认为相等,并且一个 NULL 被认为大于一个非 NULL。 + 在其他比较两个复合类型值的环境中,两个 NULL 字段值被认为相等,并且一个 NULL 被认为大于一个非 NULL。 为了得到复合类型的一致的排序和索引行为,这样做是必要的。 - 每一边都会被计算并且它们会被逐行比较。当operator是 + 对两侧分别求值后,按行进行比较。当operator=<><<=>或者 - >=时或者具有与这些类似的语义时,允许复合类型的比较(更准确地说,如果一个操作符是一个 B-树操作符类的成员,或者是一个 B-树操作符类的=成员的否定词,它就可以是一个行比较操作符)。 - 上述操作符的行为与用于行构造器(见)的IS [ NOT ] DISTINCT FROM相同。 + >=时或者具有与这些类似的语义时,允许复合类型的比较(更准确地说,如果一个操作符是一个 B-树操作符类的成员,或者是一个 B-树操作符类的=成员的否定操作符,它就可以是一个行比较操作符)。 + 上述操作符的默认行为与用于行构造器(见)的IS [ NOT ] DISTINCT FROM相同。 @@ -11169,8 +11139,8 @@ AND *<=*>以及 *>=。 - 这些操作符比较两行的内部二进制表达。即使两行用相等操作符的比较为真,两行也可能具有不同的二进制表达。 - 行在这些比较操作符之下的排序是决定性的,其他倒没什么意义。 + 这些操作符比较两行的内部二进制表示。即使两行用相等操作符的比较为真,两行也可能具有不同的二进制表示。 + 使用这些比较操作符得到的行排序是确定的,但除此之外没有其他意义。 这些操作符在内部被用于物化视图并且可能对其他如复制之类的特殊功能有用,但是它们并不打算用在书写查询这类普通用途中。 @@ -11189,12 +11159,12 @@ AND - 本节描述那些可能返回多于一行的函数。目前这个类中被使用最广泛的是级数生成函数, 如所述。其他更特殊的集合返回函数在本手册的其他地方描述。 - 组合多集合返回函数的方法可见。 + 本节描述那些可能返回多于一行的函数。目前这个类中被使用最广泛的是序列生成函数, 如所述。其他更特殊的集合返回函数在本手册的其他地方描述。 + 组合多个集合返回函数的方法可见 - 级数生成函数 + 序列生成函数 @@ -11261,7 +11231,7 @@ SELECT generate_series(1.1, 4, 1.3); 3.7 (3 rows) --- this example relies on the date-plus-integer operator +-- 此示例使用日期加整数的操作符 SELECT current_date + s.a AS dates FROM generate_series(0,14,7) AS s(a); dates ------------ @@ -11321,7 +11291,7 @@ SELECT * FROM generate_series('2008-03-01 00:00'::timestamp, generate_subscripts是一个便利函数,用于生成给定数组在指定维度上的有效下标集合。对于没有所请求维度的数组或 NULL 数组,返回零行(但数组中的 NULL 元素仍会返回有效下标)。下面是一些示例: --- basic usage +-- 基本用法 SELECT generate_subscripts('{NULL,1,NULL,2}'::int[], 1) AS s; s --- @@ -11331,8 +11301,8 @@ SELECT generate_subscripts('{NULL,1,NULL,2}'::int[], 1) AS s; 4 (4 rows) --- presenting an array, the subscript and the subscripted --- value requires a subquery +-- 展示数组、下标和下标对应的值 +-- 需要使用子查询 SELECT * FROM arrays; a -------------------- @@ -11351,7 +11321,7 @@ FROM (SELECT generate_subscripts(a, 1) AS s, a FROM arrays) foo; {100,200,300} | 3 | 300 (5 rows) --- unnest a 2D array +-- 展开二维数组 CREATE OR REPLACE FUNCTION unnest2(anyarray) RETURNS SETOF anyelement AS $$ select $1[i][j] @@ -11371,13 +11341,13 @@ SELECT * FROM unnest2(ARRAY[[1,2],[3,4]]); - ordinality + 序号 FROM子句中的函数后面加上WITH ORDINALITY时,一个bigint列会追加到输出中,其值从 1 开始,对函数输出的每一行递增 1。这种方式对集合返回函数尤其有用,例如unnest() --- set returning function WITH ORDINALITY +-- 集合返回函数与 WITH ORDINALITY SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); ls | n -----------------+---- @@ -11410,7 +11380,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); 系统信息函数 - 展示了多个可以抽取会话和系统信息的函数。 + 列出了多个用于提取会话和系统信息的函数。 @@ -11501,7 +11471,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); pg_blocking_pids(int) int[] - 阻止指定服务器进程 ID 获取锁的进程 ID + 阻止指定服务器进程获取锁的进程 ID @@ -11555,7 +11525,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); pg_safe_snapshot_blocking_pids(int) int[] - 阻止指定服务器进程 ID 获取安全快照的进程 ID + 阻止指定服务器进程获取安全快照的进程 ID @@ -11587,8 +11557,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); - current_catalogcurrent_rolecurrent_schemacurrent_usersession_useruserSQL里有特殊的语法地位: 它们被调用时结尾不要跟着圆括号。 - 在 PostgreSQL 中,圆括号可以有选择性地被用于current_schema,但是不能和其他的一起用。 + current_catalogcurrent_rolecurrent_schemacurrent_usersession_useruserSQL中具有特殊语法:调用时不得在后面加圆括号。在 PostgreSQL 中,current_schema可以选择加圆括号,其他函数则不可以。 @@ -11625,13 +11594,13 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); - schema - current + 模式 + 当前 - search path - current + 搜索路径 + 当前 @@ -11639,8 +11608,8 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); - user - current + 用户 + 当前 @@ -11648,11 +11617,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); - session_user通常是发起当前数据库连接的用户,不过超级用户可以用修改这个设置。 - current_user是用于权限检查的用户标识。通常, 它总是等于会话用户,但是可以被改变。 - 它也会在函数执行的过程中随着属性SECURITY DEFINER的改变而改变。 - 在 Unix 的说法里,那么会话用户是真实用户,而当前用户是有效用户。 - current_role以及usercurrent_user的同义词(SQL标准在current_rolecurrent_user之间做了区分,但PostgreSQL不区分,因为它把用户和角色统一成了一种实体)。 + session_user通常是发起当前数据库连接的用户,但超级用户可以用修改此设置。current_user是用于权限检查的用户标识,通常等于会话用户,但可以用更改。在执行具有SECURITY DEFINER属性的函数期间,它也会改变。用 Unix 的术语来说,会话用户是真实用户,当前用户是有效用户current_roleusercurrent_user的同义词。(SQL 标准区分current_rolecurrent_user,但PostgreSQL不区分,因为它将用户和角色统一为同一种实体。) current_schema 返回搜索路径中第一个模式的名称(如果搜索路径为空,则返回空值)。在创建表或其他命名对象时,如果未指定目标模式,就会使用该模式。current_schemas(boolean) 返回当前搜索路径中所有模式名称的数组。布尔选项决定是否在返回的搜索路径中包含 pg_catalog 等隐式包含的系统模式。 @@ -11699,18 +11664,18 @@ SET search_path TO schema , sc - Logging - pg_current_logfile函数 + 日志记录 + pg_current_logfile 函数 current_logfiles - 和pg_current_logfile函数 + 和pg_current_logfile 函数 - Logging - current_logfiles文件和pg_current_logfile函数 + 日志记录 + current_logfiles 文件和pg_current_logfile 函数 pg_current_logfiletext 返回日志收集器当前使用的日志文件路径。路径包括 目录和日志文件名。必须启用日志收集,否则返回值为 NULL。当存在多个格式不同的日志文件时,不带参数调用 pg_current_logfile 会按 stderrcsvlog 的顺序查找,返回找到的第一个格式的文件路径。如果没有任何日志文件采用这些格式,则返回 NULL。要请求特定文件格式,可向可选参数传入 text 类型的 csvlogstderr。如果请求的日志格式未配置在 中,返回值为 NULLpg_current_logfile 反映 current_logfiles 文件的内容。 @@ -11754,8 +11719,8 @@ SET search_path TO schema , sc version 返回一个描述 PostgreSQL 服务器版本的字符串。也可以通过 获取此信息,或者通过 获取机器可读的版本。软件开发者应使用 server_version_num(自 8.2 起提供)或 ,而不是解析文本版本。 - privilege - querying + 权限 + 查询 列出了允许用户以编程方式查询对象访问权限的函数。关于权限的更多信息,请参见 @@ -11774,14 +11739,14 @@ SET search_path TO schema , sc privilege) boolean - 用户是否对表的任意列具有权限 + 用户是否对表的至少一列具有权限 has_any_column_privilege(table, privilege) boolean - 当前用户是否对表的任意列具有权限 + 当前用户是否对表的至少一列具有权限 has_column_privilege(user, @@ -12030,7 +11995,7 @@ SELECT has_table_privilege('joe', 'mytable', 'INSERT, SELECT WITH GRANT OPTION') has_sequence_privilege 检查用户是否可以以某种方式访问序列。其参数形式与 has_table_privilege 类似。所需访问权限类型必须为 USAGESELECTUPDATE 之一。 - has_any_column_privilege 检查用户是否可以以某种方式访问表的任意列。其参数形式与 has_table_privilege 类似,但所需访问权限类型必须为 SELECTINSERTUPDATEREFERENCES 的某种组合。注意,在表级别拥有这些权限中的任意一种,就隐式地对表的每一列拥有该权限,因此对于相同参数,如果 has_table_privilege 返回 truehas_any_column_privilege 也总是返回真。但是,只要至少有一列获得该权限的列级授权,has_any_column_privilege 也会成功。 + has_any_column_privilege 检查用户是否可以以某种方式访问表的至少一列。其参数形式与 has_table_privilege 类似,但所需访问权限类型必须为 SELECTINSERTUPDATEREFERENCES 的某种组合。注意,在表级别拥有这些权限中的任意一种,就隐式地对表的每一列拥有该权限,因此对于相同参数,如果 has_table_privilege 返回 truehas_any_column_privilege 也总是返回真。但是,只要至少有一列获得该权限的列级授权,has_any_column_privilege 也会成功。 has_column_privilege 检查用户是否可以以某种方式访问列。其参数形式与 has_table_privilege 类似,但还可以通过列名或属性编号指定列。所需访问权限类型必须为 SELECTINSERTUPDATEREFERENCES 的某种组合。注意,在表级别拥有这些权限中的任意一种,就隐式地对表的每一列拥有该权限。 @@ -12120,22 +12085,22 @@ SELECT relname FROM pg_class WHERE pg_table_is_visible(oid); pg_ts_config_is_visible(config_oid) boolean - 全文搜索配置是否在搜索路径中可见 + 全文检索配置是否在搜索路径中可见 pg_ts_dict_is_visible(dict_oid) boolean - 全文搜索词典是否在搜索路径中可见 + 全文检索词典是否在搜索路径中可见 pg_ts_parser_is_visible(parser_oid) boolean - 全文搜索解析器是否在搜索路径中可见 + 全文检索解析器是否在搜索路径中可见 pg_ts_template_is_visible(template_oid) boolean - 全文搜索模板是否在搜索路径中可见 + 全文检索模板是否在搜索路径中可见 pg_type_is_visible(type_oid) @@ -12347,12 +12312,12 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); pg_get_expr(pg_node_tree, relation_oid) text - 反编译表达式的内部形式,假定其中所有 Var 都引用第二个参数指定的关系 + 反编译表达式的内部形式,假定其中所有 Var 节点都引用第二个参数指定的关系 pg_get_expr(pg_node_tree, relation_oid, pretty_bool) text - 反编译表达式的内部形式,假定其中所有 Var 都引用第二个参数指定的关系 + 反编译表达式的内部形式,假定其中所有 Var 节点都引用第二个参数指定的关系 pg_get_functiondef(func_oid) @@ -12537,12 +12502,12 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); pg_get_keywords 返回一组记录,描述服务器识别的 SQL 关键字。word 列包含关键字。catcode 列包含类别代码:U 表示非保留关键字,C 表示列名,T 表示类型名或函数名,R 表示保留关键字。catdesc 列包含描述该类别的字符串,该字符串可能已经过本地化。 - pg_get_constraintdefpg_get_indexdefpg_get_ruledefpg_get_statisticsobjdefpg_get_triggerdef 分别重建约束、索引、规则、扩展统计对象或触发器的创建命令。(注意,这是通过反编译重建的,并非命令的原始文本。)pg_get_expr 反编译单个表达式的内部形式,例如列的默认值。这在检查系统目录内容时可能很有用。如果表达式可能包含 Vars,请将它们所引用的关系的 OID 指定为第二个参数;如果预计不含 Vars,传入零即可。pg_get_viewdef 重建定义视图的 SELECT 查询。这些函数中的大多数有两种变体,其中一种可以选择美化输出结果。美化格式更易读,但默认格式更可能被未来版本的 PostgreSQL 以相同方式解释;转储时应避免使用美化输出。向美化输出参数传入 false,所得结果与完全没有该参数的变体相同。 + pg_get_constraintdefpg_get_indexdefpg_get_ruledefpg_get_statisticsobjdefpg_get_triggerdef 分别重建约束、索引、规则、扩展统计信息对象或触发器的创建命令。(注意,这是通过反编译重建的,并非命令的原始文本。)pg_get_expr 反编译单个表达式的内部形式,例如列的默认值。这在检查系统目录内容时可能很有用。如果表达式可能包含 Var 节点,请将它们所引用的关系的 OID 指定为第二个参数;如果预计不含 Var 节点,传入零即可。pg_get_viewdef 重建定义视图的 SELECT 查询。这些函数中的大多数有两种变体,其中一种可以选择美化输出结果。美化格式更易读,但默认格式更可能被未来版本的 PostgreSQL 以相同方式解释;转储时应避免使用美化输出。向美化输出参数传入 false,所得结果与完全没有该参数的变体相同。 pg_get_functiondef 返回一个函数的完整 CREATE OR REPLACE FUNCTION 语句。pg_get_function_argumentsCREATE FUNCTION 中所需的形式返回函数参数列表。pg_get_function_result 类似地返回该函数相应的 RETURNS 子句。pg_get_function_identity_arguments 返回标识函数所需的参数列表,例如以 ALTER FUNCTION 中所需的形式返回。此形式省略默认值。 - pg_get_serial_sequence返回与列关联的序列名称;如果该列没有关联序列,则返回 NULL。如果列是标识列,关联序列就是为标识列在内部创建的序列。对于使用某种串行类型(serialsmallserialbigserial)创建的列,关联序列就是为该串行列定义创建的序列。在后一种情况下,可以使用ALTER SEQUENCE OWNED BY修改或移除这种关联。(该函数也许应该叫作pg_get_owned_sequence;它当前的名称反映了它通常用于serialbigserial列这一事实。)第一个输入参数是可以带有模式名的表名,第二个参数是列名。由于第一个参数可能包含模式和表,它不会被当作双引号括起的标识符处理,因此默认转换为小写;第二个参数只包含列名,会被当作带双引号的标识符处理并保留大小写。函数返回的值采用适于传递给序列函数的格式(参见)。典型用法是读取标识列或串行列的序列当前值,例如: + pg_get_serial_sequence返回与列关联的序列名称;如果该列没有关联序列,则返回 NULL。如果列是标识列,关联序列就是为标识列在内部创建的序列。对于使用某种 serial 类型(serialsmallserialbigserial)创建的列,关联序列就是为该 serial 列定义创建的序列。在后一种情况下,可以使用ALTER SEQUENCE OWNED BY修改或移除这种关联。(该函数也许应该叫作pg_get_owned_sequence;它当前的名称反映了它通常用于serialbigserial列这一事实。)第一个输入参数是可以带有模式名的表名,第二个参数是列名。由于第一个参数可能包含模式和表,它不会被当作双引号括起的标识符处理,因此默认转换为小写;第二个参数只包含列名,会被当作带双引号的标识符处理并保留大小写。函数返回的值采用适于传递给序列函数的格式(参见)。典型用法是读取标识列或 serial 列的序列当前值,例如: SELECT currval(pg_get_serial_sequence('sometable', 'id')); @@ -12593,19 +12558,20 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); distance_orderable - 列能否通过一个distance操作符(例如ORDER BY col <-> constant)有序地扫描? + + 能否按距离操作符的结果有序地扫描该列,例如ORDER BY col <-> constant returnable - 列值是否可以通过一次只用索引扫描返回? + 列值是否可以通过一次仅索引扫描返回? search_array - 列是否天然支持col = ANY(array)搜索? + 列是否原生支持col = ANY(array)搜索? @@ -12620,7 +12586,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id'));
- 索引性质 + 索引属性 @@ -12657,7 +12623,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id'));
- 索引访问方法性质 + 索引访问方法属性 @@ -12752,12 +12718,11 @@ SELECT collation for ('foo' COLLATE "de_DE"); - 列出了与数据库对象 - 标识和定位有关的函数。 + 列出了与数据库对象标识和寻址有关的函数。
- 对象信息和定位函数 + 对象信息和寻址函数 名称 返回类型 描述 @@ -12788,7 +12753,7 @@ SELECT collation for ('foo' COLLATE "de_DE");
- pg_describe_object 返回数据库对象的文本描述,对象由系统目录 OID、对象 OID 和子对象 ID 指定(例如表中的列号;引用整个对象时,子对象 ID 为零)。该描述供人阅读,并可能根据服务器配置被翻译。这有助于确定存储在 pg_depend 系统目录中的对象身份。 + pg_describe_object 返回数据库对象的文本描述,对象由系统目录 OID、对象 OID 和子对象 ID 指定(例如表中的列号;引用整个对象时,子对象 ID 为零)。该描述供人阅读,并可能根据服务器配置被翻译。这有助于确定存储在 pg_depend 系统目录中的对象标识。 pg_identify_object 返回一行,其中包含足以唯一标识数据库对象的信息,该对象由系统目录 OID、对象 OID 和子对象 ID 指定。这些信息供机器读取,永远不会被翻译。type 标识数据库对象的类型;schema 是对象所属的模式名,对于不属于模式的对象类型则为 NULL;如果对象名(以及适用时的模式名)足以唯一标识该对象,name 就是对象名,并在必要时加引号,否则为 NULLidentity 是完整的对象标识,其具体格式取决于对象类型,格式中的每个名称都会根据需要加上模式限定和引号。 @@ -12814,7 +12779,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); - 中展示的函数抽取注释,注释是由命令在以前存储的。如果对指定参数找不到注释,则返回空值。 + 中的函数用于提取此前通过命令存储的注释。如果找不到与指定参数对应的注释,则返回空值。 @@ -13042,7 +13007,7 @@ SELECT collation for ('foo' COLLATE "de_DE");
- pg_control_checkpoint 返回一条记录,其内容见 + pg_control_checkpoint 返回一条记录,其内容见 <function>pg_control_checkpoint</function> 输出列 @@ -13151,7 +13116,7 @@ SELECT collation for ('foo' COLLATE "de_DE");
- pg_control_system 返回一条记录,其内容见 + pg_control_system 返回一条记录,其内容见 <function>pg_control_system</function> 输出列 @@ -13190,7 +13155,7 @@ SELECT collation for ('foo' COLLATE "de_DE");
- pg_control_init 返回一条记录,其内容见 + pg_control_init 返回一条记录,其内容见 <function>pg_control_init</function> 输出列 @@ -13269,7 +13234,7 @@ SELECT collation for ('foo' COLLATE "de_DE");
- pg_control_recovery 返回一条记录,其内容见 + pg_control_recovery 返回一条记录,其内容见 <function>pg_control_recovery</function> 输出列 @@ -13360,19 +13325,19 @@ SELECT collation for ('foo' COLLATE "de_DE"); - configuration - of the server - functions + 配置 + 服务器 + 函数 - 函数current_setting返回以下设置的当前值:setting_name。它对应于SQL命令SHOW。例如: + 函数current_setting返回设置setting_name的当前值。它对应于SQL命令SHOW。例如: SELECT current_setting('datestyle'); current_setting ----------------- ISO, MDY (1 row) -如果不存在以下名称的设置:setting_name, +如果不存在名为setting_name的设置, current_setting会报错,除非提供了missing_ok且其值为true @@ -13411,7 +13376,7 @@ SELECT set_config('log_statement_stats', 'off', false); - 在中展示的函数向其它服务器进程发送控制信号。默认情况下这些函数只能被超级用户使用,但是如果需要,可以利用GRANT把访问权限授予给其他用户。 + 在中展示的函数向其它服务器进程发送控制信号。默认情况下这些函数只能被超级用户使用,但是如果需要,可以利用GRANT把访问权限授予给其他用户(注明的例外除外)。
@@ -13455,7 +13420,7 @@ SELECT set_config('log_statement_stats', 'off', false); pg_cancel_backendpg_terminate_backend向由进程 ID 标识的后端进程发送信号(分别是SIGINTSIGTERM)。 - 一个活动后端的进程 ID可以从pg_stat_activity视图的pid列中找到,或者通过在服务器上列出postgres进程(在 Unix 上使用ps或者在Windows上使用Task Manager)得到。 + 一个活动后端的进程 ID可以从pg_stat_activity视图的pid列中找到,或者通过在服务器上列出postgres进程(在 Unix 上使用ps或者在Windows上使用任务管理器)得到。 一个活动后端的角色可以在pg_stat_activity视图的usename列中找到。 @@ -13469,7 +13434,7 @@ SELECT set_config('log_statement_stats', 'off', false); 备份控制函数 - backup + 备份 pg_create_restore_point @@ -13518,7 +13483,7 @@ SELECT set_config('log_statement_stats', 'off', false); pg_create_restore_point(name text) pg_lsn - 创建用于还原的命名点(默认仅限超级用户,但可以向其他用户授予 EXECUTE 权限以运行此函数) + 创建用于恢复的命名点(默认仅限超级用户,但可以向其他用户授予EXECUTE权限以运行此函数) @@ -13544,19 +13509,19 @@ SELECT set_config('log_statement_stats', 'off', false); pg_start_backup(label text , fast boolean , exclusive boolean ) pg_lsn - 准备执行在线备份(默认仅限超级用户,但可以向其他用户授予 EXECUTE 权限以运行此函数) + 准备执行在线备份(默认仅限超级用户,但可以向其他用户授予EXECUTE权限以运行此函数) pg_stop_backup() pg_lsn - 结束排他在线备份(默认仅限超级用户,但可以向其他用户授予 EXECUTE 权限以运行此函数) + 结束排他在线备份(默认仅限超级用户,但可以向其他用户授予EXECUTE权限以运行此函数) pg_stop_backup(exclusive boolean , wait_for_archive boolean ) setof record - 结束排他或非排他在线备份(默认仅限超级用户,但可以向其他用户授予 EXECUTE 权限以运行此函数) + 结束排他或非排他在线备份(默认仅限超级用户,但可以向其他用户授予EXECUTE权限以运行此函数) @@ -13577,7 +13542,7 @@ SELECT set_config('log_statement_stats', 'off', false); pg_switch_wal() pg_lsn - 强制切换到新的预写式日志文件(默认仅限超级用户,但可以向其他用户授予 EXECUTE 权限以运行此函数) + 强制切换到新的预写式日志文件(默认仅限超级用户,但可以向其他用户授予EXECUTE权限以运行此函数) pg_walfile_name(lsn pg_lsn) @@ -13706,7 +13671,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); - 控制恢复进度的功能如 所示。这些函数只能在恢复过程中执行。 + 列出的函数用于控制恢复进度。这些函数只能在恢复期间执行。
@@ -13730,14 +13695,14 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); pg_wal_replay_pause()void - 立即暂停恢复(默认仅限超级用户,但可以向其他用户授予 EXECUTE 权限以运行此函数)。 + 立即暂停恢复(默认仅限超级用户,但可以向其他用户授予EXECUTE权限以运行此函数)。 pg_wal_replay_resume() void - 如果恢复已暂停,则重新开始恢复(默认仅限超级用户,但可以向其他用户授予 EXECUTE 权限以运行此函数)。 + 如果恢复已暂停,则重新开始恢复(默认仅限超级用户,但可以向其他用户授予EXECUTE权限以运行此函数)。 @@ -13764,7 +13729,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); - 为了解决这个问题,PostgreSQL允许一个事务导出它正在使用的快照。只要导出的事务仍然保持打开,其他事务可以导入它的快照,并且因此可以保证它们可以看到和第一个事务看到的完全一样的数据库视图。但是注意这些事务中的任何一个对数据库所作的更改对其他事务仍然保持不可见,和未提交事务所作的修改一样。因此这些事务是针对以前存在的数据同步,而对由它们自己所作的更改则采取正常的动作。 + 为了解决这个问题,PostgreSQL允许一个事务导出它正在使用的快照。只要导出快照的事务仍然保持打开,其他事务可以导入它的快照,并且因此可以保证它们可以看到和第一个事务看到的完全一样的数据库视图。但是注意这些事务中的任何一个对数据库所作的更改对其他事务仍然保持不可见,和未提交事务所作的修改一样。因此这些事务是针对以前存在的数据同步,而对由它们自己所作的更改则采取正常的动作。 @@ -14125,7 +14090,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); 上述操作表和索引的函数接受一个regclass参数,它是该表或索引在pg_class系统目录中的 OID。 你不必手工去查找该 OID,因为regclass数据类型的输入转换器会为你代劳。 - 只写包围在单引号内的表名,这样它看起来像一个文字常量。 + 只写包围在单引号内的表名,这样它看起来像一个字面量。 为了与普通SQL名称的处理相兼容,该字符串将被转换为小写形式,除非其中在表名周围包含双引号。 @@ -14207,7 +14172,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); pg_collation_actual_version 返回当前安装在操作系统中的排序规则对象的实际版本。如果它与 pg_collation.collversion 中的值不同,则可能需要重建依赖该排序规则的对象。另见 - pg_import_system_collations 根据操作系统中找到的所有区域环境,向系统目录 pg_collation 添加排序规则。initdb 使用的就是此函数;更多信息见。如果以后在操作系统中安装了其他区域环境,可以再次运行此函数,为新区域环境添加排序规则。与 pg_collation 中现有条目匹配的区域环境会被跳过。(但此函数不会删除基于操作系统中已不存在的区域环境的排序规则对象。)schema 参数通常为 pg_catalog,但并非必须如此;也可以将排序规则安装到其他模式中。函数返回新建的排序规则对象数量。此函数仅限超级用户使用。 + pg_import_system_collations 根据操作系统中找到的所有区域设置,向系统目录 pg_collation 添加排序规则。initdb 使用的就是此函数;更多信息见。如果以后在操作系统中安装了其他区域设置,可以再次运行此函数,为新区域设置添加排序规则。与 pg_collation 中现有条目匹配的区域设置会被跳过。(但此函数不会删除基于操作系统中已不存在的区域设置的排序规则对象。)schema 参数通常为 pg_catalog,但并非必须如此;也可以将排序规则安装到其他模式中。函数返回新建的排序规则对象数量。此函数仅限超级用户使用。 @@ -14264,7 +14229,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup());
- brin_summarize_new_values 接受 BRIN 索引的 OID 或名称,检查索引,找出基表中尚未被索引汇总的页面范围;对于每个这样的范围,它通过扫描表页面创建新的汇总索引元组。函数返回插入索引的新页面范围汇总数量。brin_summarize_range 执行相同的操作,但只汇总覆盖给定块号的范围。 + brin_summarize_new_values 接受 BRIN 索引的 OID 或名称,检查索引,找出基表中尚未生成索引摘要的页面范围;对于每个这样的范围,它通过扫描表页面创建新的摘要索引元组。函数返回插入索引的新页面范围摘要数量。brin_summarize_range 执行相同的操作,但只对覆盖给定块号的范围生成摘要。 gin_clean_pending_list 接受 GIN 索引的 OID 或名称,通过将待处理列表中的条目批量移到主 GIN 数据结构中,清理指定索引的待处理列表。它返回从待处理列表中移除的页面数。注意,如果参数是禁用了 fastupdate 选项的 GIN 索引,则不执行清理并返回 0,因为该索引没有待处理列表。关于待处理列表和 fastupdate 选项的详细信息,请参见 @@ -14275,7 +14240,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); 中展示的函数提供了对数据库服务器所在机器上的文件的本地访问。 - 只能访问数据库集簇目录以及log_directory中的文件,除非用户被授予了角色pg_read_server_files。 + 只能访问数据库集簇目录以及log_directory中的文件,除非用户被授予了角色pg_read_server_files。 使用相对路径访问集簇目录里面的文件,以及匹配 log_directory配置设置的路径访问日志文件。 @@ -14293,7 +14258,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); pg_ls_dir(dirname text [, missing_ok boolean, include_dot_dirs boolean]) setof text - 列出目录内容。默认仅限超级用户,但可以向其他用户授予 EXECUTE 权限以运行此函数。 + 列出目录内容。默认仅限超级用户,但可以向其他用户授予EXECUTE权限以运行此函数。 @@ -14312,17 +14277,17 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); pg_read_file(filename text [, offset bigint, length bigint [, missing_ok boolean] ]) text - 返回文本文件的内容。默认仅限超级用户,但可以向其他用户授予 EXECUTE 权限以运行此函数。 + 返回文本文件的内容。默认仅限超级用户,但可以向其他用户授予EXECUTE权限以运行此函数。 pg_read_binary_file(filename text [, offset bigint, length bigint [, missing_ok boolean] ]) bytea - 返回文件内容。默认仅限超级用户,但可以向其他用户授予 EXECUTE 权限以运行此函数。 + 返回文件内容。默认仅限超级用户,但可以向其他用户授予EXECUTE权限以运行此函数。 pg_stat_file(filename text[, missing_ok boolean]) record - 返回文件信息。默认仅限超级用户,但可以向其他用户授予 EXECUTE 权限以运行此函数。 + 返回文件信息。默认仅限超级用户,但可以向其他用户授予EXECUTE权限以运行此函数。 @@ -14583,7 +14548,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); 事件触发器函数 - PostgreSQL提供了这些助手函数来从事件触发器检索信息。 + PostgreSQL提供了这些辅助函数来从事件触发器检索信息。 @@ -14600,7 +14565,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); 当在一个ddl_command_end事件触发器的函数中调用时,pg_event_trigger_ddl_commands返回被每一个用户动作执行的DDL命令的列表。 如果在其他任何环境中调用这个函数,会发生错误。 - pg_event_trigger_ddl_commands为每一个被执行的基本命令返回一行,某些只有一个单一 SQL 句子的命令可能会返回多于一行。 + pg_event_trigger_ddl_commands为每一个被执行的基本命令返回一行,某些由单条 SQL 语句构成的命令可能会返回多于一行。 这个函数返回下面的列: @@ -14617,7 +14582,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); classid oid - 对象所属的目录的 OID + 对象所属系统目录的 OID objid @@ -14627,7 +14592,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); objsubid integer - 对象的子-id(例如列的属性号) + 子对象 ID(例如列的属性编号) command_tag @@ -14643,16 +14608,14 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); schema_name text - 该对象所属的模式的名称(如果有),如果没有则为NULL。 - 没有引号。 + 对象所属模式的名称(若有);否则为NULL。不加引号。 object_identity text - 对象标识的文本表现形式,用模式限定。如果必要,出现在 - 该标识中的每一个标识符都会加上引号。 + 对象标识的文本表示形式,带模式限定。标识中包含的每个标识符在必要时都会加引号。 @@ -14664,8 +14627,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); command pg_ddl_command - 以内部格式表达的该命令的一个完整表现形式。这不能被直接输出, - 但是可以把它传递给其他函数来得到有关于该命令不同部分的信息。 + 命令的完整内部表示,不能直接输出,但可以将其传给其他函数以获取关于该命令的不同信息。 @@ -14696,7 +14658,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); classid oid - 对象所属的目录的 OID + 对象原先所属系统目录的 OID objid @@ -14706,7 +14668,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); objsubid integer - 子对象ID(如列的属性号) + 子对象 ID(例如列的属性编号) original @@ -14717,7 +14679,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); normal bool - 指示在依赖图中有一个普通依赖关系指向该对象的标志 + 如果依赖图中存在指向该对象的普通依赖关系,则为真。 @@ -14736,29 +14698,28 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); schema_name text - 对象所属模式的名称(如果存在);否则为NULL。不加引号。 + 对象原先所属模式的名称(若有);否则为NULL。不加引号。 object_name text - 如果模式和名称的组合能被用于对象的一个唯一标识符,则是对象的名称;否则是NULL。不加引号,并且名称不是模式限定的。 + 如果模式和名称的组合可用作该对象的唯一标识符,则为对象名称;否则为NULL。不加引号,并且该名称永远不带模式限定。 object_identity text - 带模式限定的对象标识的文本表示。其中的每个标识符都会在必要时加引号。 + 对象标识的文本表示形式,带模式限定。标识中包含的每个标识符在必要时都会加引号。 address_names text[] - 一个数组,它可以和object_typeaddress_args, - 一起通过pg_get_object_address()函数在一台包含有同类相同名称对象的远程服务器上重建该对象地址。 + 一个数组,可与object_typeaddress_args一起,通过pg_get_object_address()函数在包含同类同名对象的远程服务器上重建该对象地址。 diff --git a/zh/11/gin.sgml b/zh/11/gin.sgml index ec883efc..bca17ba6 100644 --- a/zh/11/gin.sgml +++ b/zh/11/gin.sgml @@ -53,7 +53,7 @@ 内置操作符类 - PostgreSQL 核心发布包含 + PostgreSQL 核心发行版包含 所示的 GIN 操作符类。 (在 中描述的一些可选模块还提供额外的 GIN 操作符类。) @@ -64,7 +64,7 @@ 名称 - 索引数据类型 + 被索引数据类型 可索引操作符 @@ -118,7 +118,10 @@ GIN 将可扩展性与通用性、代码重用以及清晰的接口结合在一起。 - GIN中,操作符类必须提供以下两个方法: + + GIN 操作符类必须提供两个方法: + + Datum *extractValue(Datum itemValue, int32 *nkeys, bool **nullFlags) @@ -127,7 +130,7 @@ 给定一个要建立索引的项,返回一个用 palloc 分配的键数组。返回键的数量必须存入 *nkeys。如果任一键可以为 null,还要另外 palloc 一个包含 *nkeysbool 字段的数组,将其地址存入 - *nullFlags,并按需设置这些空值标志。如果所有键都非空, + *nullFlags,并按需设置这些空值标志。如果所有键都不是 null, *nullFlags 可以保持为 NULL(其初始值)。 如果该项不包含任何键,则返回值可以为 NULL @@ -147,7 +150,7 @@ query 的数据类型,以及应采用何种方法提取键值。返回键的数量必须存入 *nkeys。如果任一键可以为 null,还要另外 palloc 一个包含 *nkeysbool 字段的数组,将其地址存入 - *nullFlags,并按需设置这些空值标志。如果所有键都非空, + *nullFlags,并按需设置这些空值标志。如果所有键都不是 null, *nullFlags 可以保持为 NULL(其初始值)。 如果 query 不包含任何键,则返回值可以为 NULL @@ -160,7 +163,7 @@ 被设置为 GIN_SEARCH_MODE_INCLUDE_EMPTY,则除至少包含一个匹配键的项之外, 完全不含任何键的项也会被视为候选匹配。(例如,该模式对于实现是子集操作符很有用。) 若 *searchMode 被设置为 GIN_SEARCH_MODE_ALL, - 则索引中所有非空项都会被视为候选匹配,无论它们是否匹配任一返回键。 + 则索引中所有非 null 项都会被视为候选匹配,无论它们是否匹配任一返回键。 (该模式比前两种选择慢得多,因为它基本上需要扫描整个索引;但为了正确处理某些边界情况, 可能有此必要。在大多数情况下都需要此模式的操作符,大概并不适合作为 GIN 操作符类的候选。)用于设置该模式的符号定义在 @@ -188,7 +191,15 @@ - 操作符类还必须提供一个函数,用于检查被索引项是否匹配查询。它有两种形式:布尔型consistent函数和三值triConsistent函数。triConsistent涵盖两者的功能,因此只提供triConsistent就已经足够。不过,如果布尔变体的计算明显更便宜,那么同时提供两者会更有利。若只提供布尔变体,则一些依赖于在取回所有键之前先排除索引项的优化将被禁用。 + + + 操作符类还必须提供一个函数,用于检查被索引项是否匹配查询。它有两种形式:布尔型 + consistent 函数,以及三值型 triConsistent 函数。 + triConsistent 覆盖了两者的功能,因此仅提供 triConsistent + 就已经足够。不过,如果布尔变体的计算代价明显更低,那么同时提供两者可能更有利。 + 若只提供布尔变体,则一些依赖于在取回所有键之前先排除索引项的优化将被禁用。 + + bool consistent(bool check[], StrategyNumber n, Datum query, int32 nkeys, Pointer extra_data[], bool *recheck, @@ -200,10 +211,10 @@ 该函数无法直接访问被索引项的值,因为 GIN 并不显式存储项。 它所能利用的是这样一种信息:从查询中提取出的哪些键值出现在给定的被索引项中。 check 数组长度为 nkeys,这与先前针对该 - query 数据由 extractQuery 返回的键数量相同。 + query datum 由 extractQuery 返回的键数量相同。 如果被索引项包含相应查询键,则 check 数组中的对应元素为 true; 也就是说,如果 (check[i] == true),则 extractQuery - 结果数组中的第 i 个键存在于该被索引项中。传入原始 query 数据值, + 结果数组中的第 i 个键存在于该被索引项中。传入原始 query datum, 是为了让 consistent 方法在需要时可以查看它;同样也会传入先前由 extractQuery 返回的 queryKeys[]nullFlags[] 数组。extra_data 则是 @@ -241,7 +252,7 @@ 而 GIN_MAYBE 表示该键是否存在尚不确定。存在 GIN_MAYBE 值时,只有当无论索引项是否包含对应查询键,该项都确定匹配时,函数才应返回 GIN_TRUE。同样,只有当无论是否包含 GIN_MAYBE 键, - 该项都确定不匹配时,函数才必须返回 GIN_FALSE。如果结果依赖于 + 该项都确定不匹配时,函数才能返回 GIN_FALSE。如果结果依赖于 GIN_MAYBE 条目,也就是说,无法根据已知的查询键确认或否定匹配, 则函数必须返回 GIN_MAYBE @@ -255,7 +266,11 @@
- 此外,GIN 必须能够对索引中存储的键值排序。操作符类可以通过指定比较方法来定义排序顺序: + + 此外,GIN 必须有一种方法对存储在索引中的键值进行排序。 + 操作符类可以通过指定一个比较方法来定义这种排序顺序: + + int compare(Datum a, Datum b) @@ -265,7 +280,13 @@ - 或者,如果操作符类没有提供compare方法,GIN 就会查找索引键数据类型的默认 btree 操作符类,并使用其比较函数。对于只适用于一种数据类型的 GIN 操作符类,建议指定比较函数,因为查找 btree 操作符类需要耗费一些处理器周期。但是,多态 GIN 操作符类(例如array_ops)通常无法指定单一的比较函数。 + + + 或者,如果操作符类没有提供 compare 方法,GIN + 将查找该索引键数据类型的默认 B-树操作符类,并使用其比较函数。建议在仅面向单一数据类型的 + GIN 操作符类中显式指定比较函数,因为查找 B-树操作符类会消耗少量处理器周期。 + 不过,多态 GIN 操作符类(例如 array_ops)通常无法指定单一比较函数。 +
作为可选项,GIN操作符类可以提供以下方法: @@ -308,8 +329,8 @@ 在内部,一个 GIN 索引包含一个基于键构建的 B-树索引,其中每个键都是一个或多个被索引项中的某个元素 - (例如数组成员),而叶子页中的每个元组要么包含一个指向堆指针 B-树的指针(posting tree), - 要么在列表足够小、能够连同键值一起放入单个索引元组时,直接包含一个简单的堆指针列表(posting list)。 + (例如数组成员),而叶子页中的每个元组要么包含一个指向堆指针 B-树的指针(倒排树), + 要么在列表足够小、能够连同键值一起放入单个索引元组时,直接包含一个简单的堆指针列表(倒排列表)。 @@ -346,7 +367,7 @@ - 如果一致的响应时间比更新速度更重要,可以通过关闭 GIN 索引的 + 如果稳定的响应时间比更新速度更重要,可以通过关闭 GIN 索引的 fastupdate 存储参数来禁用待处理列表机制。详见 @@ -382,7 +403,7 @@ 因此,对于向表中执行的批量插入,建议先删除 GIN 索引,待批量插入完成后再重建它。 - PostgreSQL 8.4 开始,由于采用了延迟索引,这项建议已不那么必要(详见)。但对于非常大的更新,最好仍然是删除并重建索引。 + PostgreSQL 8.4 开始,由于采用了延迟索引,这项建议已不那么必要(详见)。但对于非常大的更新,删除并重建索引仍然可能是最佳选择。 @@ -449,14 +470,19 @@ GIN 假定可索引操作符是严格的。这意味着,当项值为 null 时, 根本不会对其调用 extractValue(而是自动创建一个占位符索引项); 当查询值为 null 时,也不会调用 extractQuery(而是认为该查询不可满足)。 - 不过要注意,非空组合项或查询值内部包含的 null 键值仍然受支持。 + 不过要注意,非 null 的组合项或查询值内部包含的 null 键值仍然受支持。
示例 - PostgreSQL核心发行版包含GIN操作符类,见前文。以下contrib模块也包含GIN操作符类: + + PostgreSQL 核心发行版包含前面在 + 中展示过的 GIN 操作符类。 + 下列 contrib 模块也包含 GIN 操作符类: + + btree_gin diff --git a/zh/11/gist.sgml b/zh/11/gist.sgml index aa2b7ff0..eb2c2180 100644 --- a/zh/11/gist.sgml +++ b/zh/11/gist.sgml @@ -4,7 +4,7 @@ GiST 索引 - index + 索引 GiST @@ -45,7 +45,7 @@ 名称 - 索引数据类型 + 被索引数据类型 可索引操作符 排序操作符 @@ -127,7 +127,7 @@ CREATE INDEX ON my_table USING GIST (my_inet_column inet_ops); - 这种可扩展性不应与其他标准搜索树在可处理数据方面的可扩展性相混淆。例如,PostgreSQL支持可扩展的 B-树和哈希索引。这意味着你可以用PostgreSQL在任意数据类型上构建 B-树或哈希索引。但 B-树只支持范围谓词(<=>),而哈希索引只支持等值查询。 + 这种可扩展性不应与其他标准搜索树在可处理数据方面的可扩展性相混淆。例如,PostgreSQL支持可扩展的 B-树和 hash 索引。这意味着你可以用PostgreSQL在任意数据类型上构建 B-树或 hash 索引。但 B-树只支持范围谓词(<=>),而 hash 索引只支持等值查询。 @@ -151,12 +151,19 @@ CREATE INDEX ON my_table USING GIST (my_inet_column inet_ops); indexable_operator q为真。对于叶子索引项,这等同于测试该可索引条件;而对于内部树节点,这决定是否有必要扫描该树节点所表示的索引子树。当结果为true时,还必须返回一个recheck标志。它表示该谓词是确定为真,还是仅可能为真。如果recheck = false,则该索引已经精确测试了谓词条件;如果recheck = true,则该行只是候选匹配。在这种情况下,系统会自动针对实际行值计算indexable_operator,以判断它是否真的匹配。这种约定使GiST能够同时支持无损和有损的索引结构。 - SQL声明必须如下所示: + + 该函数的SQL声明必须如下所示: + + CREATE OR REPLACE FUNCTION my_consistent(internal, data_type, smallint, oid, internal) RETURNS bool AS 'MODULE_PATHNAME' LANGUAGE C STRICT; -C 模块中相应的代码可以采用以下框架: + + + 而 C 模块中的对应代码则可以遵循如下框架: + + PG_FUNCTION_INFO_V1(my_consistent); Datum @@ -171,19 +178,21 @@ my_consistent(PG_FUNCTION_ARGS) bool retval; /* - * determine return value as a function of strategy, key and query. + * 根据 strategy、key 和 query 确定返回值。 * - * Use GIST_LEAF(entry) to know where you're called in the index tree, - * which comes handy when supporting the = operator for example (you could - * check for non empty union() in non-leaf nodes and equality in leaf - * nodes). + * 使用 GIST_LEAF(entry) 判断当前调用位于索引树的哪个位置。 + * 例如,支持 = 操作符时这很有用(可以在非叶节点检查 + * union() 是否非空,在叶节点检查是否相等)。 */ - *recheck = true; /* or false if check is exact */ + *recheck = true; /* 如果检查是精确的,则为 false */ PG_RETURN_BOOL(retval); } -这里,key是索引中的元素,query是要在索引中查找的值。StrategyNumber参数指明正在应用操作符类中的哪个操作符,它对应于CREATE OPERATOR CLASS命令中的某个操作符编号。 + + + 这里,key是索引中的一个元素,而query是在该索引中查找的值。StrategyNumber参数指示应用的是操作符类中的哪个操作符,它对应于CREATE OPERATOR CLASS命令中的某个操作符编号。 + 取决于你在该类中包含了哪些操作符,query的数据类型可能会随操作符而变化,因为它将是操作符右侧的类型,而这可能不同于左侧出现的被索引数据类型。(上面的代码框架假定只可能有一种类型;如果不是这样,获取query参数值的方式就必须依赖于具体的操作符。)建议在consistent函数的 SQL 声明中,对query参数使用该操作符类的被索引数据类型,即使实际类型可能因为操作符不同而有所不同。 @@ -199,12 +208,19 @@ my_consistent(PG_FUNCTION_ARGS) 该方法用于汇总树中的信息。给定一组项,该函数生成一个新的索引项,用来表示所有给定项。 - SQL声明必须如下所示: + + 该函数的SQL声明必须如下所示: + + CREATE OR REPLACE FUNCTION my_union(internal, internal) RETURNS storage_type AS 'MODULE_PATHNAME' LANGUAGE C STRICT; -C 模块中相应的代码可以采用以下框架: + + + 而 C 模块中的对应代码则可以遵循如下框架: + + PG_FUNCTION_INFO_V1(my_union); Datum @@ -262,12 +278,19 @@ my_union(PG_FUNCTION_ARGS) 将一个数据项转换成适合在索引页中物理存储的格式。如果省略compress方法,数据项将不经修改地存储在索引中。 - SQL声明必须如下所示: + + 该函数的SQL声明必须如下所示: + + CREATE OR REPLACE FUNCTION my_compress(internal) RETURNS internal AS 'MODULE_PATHNAME' LANGUAGE C STRICT; -C 模块中相应的代码可以采用以下框架: + + + 而 C 模块中的对应代码则可以遵循如下框架: + + PG_FUNCTION_INFO_V1(my_compress); Datum @@ -278,10 +301,10 @@ my_compress(PG_FUNCTION_ARGS) if (entry->leafkey) { - /* replace entry->key with a compressed version */ + /* 将 entry->key 替换为压缩后的形式 */ compressed_data_type *compressed_data = palloc(sizeof(compressed_data_type)); - /* fill *compressed_data from entry->key ... */ + /* 根据 entry->key 填充 *compressed_data ... */ retval = palloc(sizeof(GISTENTRY)); gistentryinit(*retval, PointerGetDatum(compressed_data), @@ -289,7 +312,7 @@ my_compress(PG_FUNCTION_ARGS) } else { - /* typically we needn't do anything with non-leaf entries */ + /* 通常无需对非叶项做任何处理 */ retval = entry; } @@ -311,12 +334,19 @@ my_compress(PG_FUNCTION_ARGS) 将数据项的存储表示转换成操作符类中其他 GiST 方法能够操作的格式。如果省略decompress方法,就假定其他 GiST 方法可以直接处理存储的数据格式。(decompress不一定是compress方法的逆操作;特别是如果compress是有损的,那么decompress就不可能精确重建原始数据。decompress也不一定等同于fetch,因为其他 GiST 方法未必需要把数据完全重建出来。) - SQL声明必须如下所示: + + 该函数的SQL声明必须如下所示: + + CREATE OR REPLACE FUNCTION my_decompress(internal) RETURNS internal AS 'MODULE_PATHNAME' LANGUAGE C STRICT; -C 模块中相应的代码可以采用以下框架: + + + 而 C 模块中的对应代码则可以遵循如下框架: + + PG_FUNCTION_INFO_V1(my_decompress); Datum @@ -324,7 +354,10 @@ my_decompress(PG_FUNCTION_ARGS) { PG_RETURN_POINTER(PG_GETARG_POINTER(0)); } -上述框架适用于无需解压缩的情况。(当然,完全省略该方法更简单,这种情况下也建议如此。) + + + 上述框架适用于不需要解压的情况。(当然,在这种情况下,直接完全省略该方法会更简单,而且也推荐这么做。) + @@ -335,12 +368,19 @@ my_decompress(PG_FUNCTION_ARGS) 返回一个值,指示把新项插入树中特定分支的代价。项会沿着树中penalty最小的路径插入。penalty返回的值应为非负;如果返回负值,它将被按零处理。 - SQL声明必须如下所示: + + 该函数的SQL声明必须如下所示: + + CREATE OR REPLACE FUNCTION my_penalty(internal, internal, internal) RETURNS internal AS 'MODULE_PATHNAME' -LANGUAGE C STRICT; -- in some cases penalty functions need not be strict -C 模块中相应的代码可以采用以下框架: +LANGUAGE C STRICT; -- 某些情况下 penalty 函数不必是严格函数 + + + 而 C 模块中的对应代码则可以遵循如下框架: + + PG_FUNCTION_INFO_V1(my_penalty); Datum @@ -355,7 +395,10 @@ my_penalty(PG_FUNCTION_ARGS) *penalty = my_penalty_implementation(orig, new); PG_RETURN_POINTER(penalty); } -由于历史原因,penalty函数不能仅仅返回一个float结果,而必须将该值存储到第三个参数指向的位置。函数自身的返回值会被忽略,但通常会返回该参数的地址。 + + + 出于历史原因,penalty函数并不是直接返回一个float结果;相反,它必须把该值存储到第三个参数指示的位置。返回值本身会被忽略,不过通常会返回该参数所指向的地址。 + penalty函数对于索引的良好性能至关重要。它会在插入时用于决定在树中应沿着哪个分支向下,以便选择把新项加到哪里。在查询时,索引越平衡,查找就越快。 @@ -370,12 +413,19 @@ my_penalty(PG_FUNCTION_ARGS) 当索引页必须分裂时,该函数决定页面上的哪些项留在旧页中,哪些移到新页中。 - SQL声明必须如下所示: + + 该函数的SQL声明必须如下所示: + + CREATE OR REPLACE FUNCTION my_picksplit(internal, internal) RETURNS internal AS 'MODULE_PATHNAME' LANGUAGE C STRICT; -C 模块中相应的代码可以采用以下框架: + + + 而 C 模块中的对应代码则可以遵循如下框架: + + PG_FUNCTION_INFO_V1(my_picksplit); Datum @@ -408,7 +458,7 @@ my_picksplit(PG_FUNCTION_ARGS) unionL = NULL; unionR = NULL; - /* Initialize the raw entry vector. */ + /* 初始化原始项向量。 */ raw_entryvec = (GISTENTRY **) malloc(entryvec->n * sizeof(void *)); for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) raw_entryvec[i] = &(entryvec->vector[i]); @@ -421,9 +471,9 @@ my_picksplit(PG_FUNCTION_ARGS) Assert(tmp_union != NULL); /* - * Choose where to put the index entries and update unionL and unionR - * accordingly. Append the entries to either v->spl_left or - * v->spl_right, and care about the counters. + * 选择索引项的存放位置,并相应更新 unionL 和 unionR。 + * 将项追加到 v->spl_left 或 v->spl_right, + * 同时更新计数器。 */ if (my_choice_is_left(unionL, curl, unionR, curr)) @@ -440,7 +490,7 @@ my_picksplit(PG_FUNCTION_ARGS) else { /* - * Same on the right + * 对右侧执行相同操作 */ } } @@ -449,7 +499,9 @@ my_picksplit(PG_FUNCTION_ARGS) v->spl_rdatum = DataTypeGetDatum(unionR); PG_RETURN_POINTER(v); } -注意,picksplit函数通过修改传入的v结构体来传递结果。函数自身的返回值会被忽略,但通常会返回以下结构体的地址:v。 + + + 注意,picksplit函数的结果是通过修改传入的v结构体来传递的。返回值本身会被忽略,不过通常会返回v的地址。 @@ -465,12 +517,19 @@ my_picksplit(PG_FUNCTION_ARGS) 如果两个索引项相同则返回真,否则返回假。(索引项是索引存储类型的值,不一定是原始被索引列的类型。) - SQL声明必须如下所示: + + 该函数的SQL声明必须如下所示: + + CREATE OR REPLACE FUNCTION my_same(storage_type, storage_type, internal) RETURNS internal AS 'MODULE_PATHNAME' LANGUAGE C STRICT; -C 模块中相应的代码可以采用以下框架: + + + 而 C 模块中的对应代码则可以遵循如下框架: + + PG_FUNCTION_INFO_V1(my_same); Datum @@ -483,7 +542,10 @@ my_same(PG_FUNCTION_ARGS) *result = my_eq(v1, v2); PG_RETURN_POINTER(result); } -由于历史原因,same函数不能仅仅返回布尔结果,而必须将该标志存储到第三个参数指向的位置。函数自身的返回值会被忽略,但通常会返回该参数的地址。 + + + 出于历史原因,same函数并不是直接返回一个布尔结果;相反,它必须把该标志存储到第三个参数指示的位置。返回值本身会被忽略,不过通常会返回该参数所指向的地址。 + @@ -494,12 +556,19 @@ my_same(PG_FUNCTION_ARGS) 给定一个索引项p和一个查询值q,该函数确定索引项与查询值之间的距离。如果操作符类包含任何排序操作符,就必须提供此函数。使用排序操作符的查询会优先返回距离值最小的索引项,因此结果必须与该操作符的语义一致。对于叶子索引项,结果仅表示到该索引项的距离;对于内部树节点,结果必须是其任意子项可能具有的最小距离。 - SQL声明必须如下所示: + + 该函数的SQL声明必须如下所示: + + CREATE OR REPLACE FUNCTION my_distance(internal, data_type, smallint, oid, internal) RETURNS float8 AS 'MODULE_PATHNAME' LANGUAGE C STRICT; -C 模块中相应的代码可以采用以下框架: + + + 而 C 模块中的对应代码则可以遵循如下框架: + + PG_FUNCTION_INFO_V1(my_distance); Datum @@ -514,19 +583,22 @@ my_distance(PG_FUNCTION_ARGS) double retval; /* - * determine return value as a function of strategy, key and query. + * 根据 strategy、key 和 query 确定返回值。 */ PG_RETURN_FLOAT8(retval); } -distance函数的参数与consistent函数的参数完全相同。 + + + distance函数的参数与consistent函数的参数完全相同。 + - 在确定距离时允许有一定近似,只要结果永不大于该项的实际距离即可。因此,例如在几何应用中,到外包盒的距离通常就足够了。对于内部树节点,返回的距离不能大于其任一子节点的距离。如果返回的距离不精确,函数必须将*recheck设为 true。(对内部树节点则不必这样做;对它们总是假定计算结果不精确。)在这种情况下,执行器会在从堆中取出元组后计算准确距离,并在必要时重新排序这些元组。 + 在确定距离时允许有一定近似,只要结果永不大于该项的实际距离即可。因此,例如在几何应用中,到包围盒的距离通常就足够了。对于内部树节点,返回的距离不能大于其任一子节点的距离。如果返回的距离不精确,函数必须将*recheck设为 true。(对内部树节点则不必这样做;对它们总是假定计算结果不精确。)在这种情况下,执行器会在从堆中取出元组后计算准确距离,并在必要时重新排序这些元组。 - 如果距离函数对任何叶节点都返回*recheck = true,原始排序操作符的返回类型必须是float8float4,且距离函数的结果值必须能与原始排序操作符的结果进行比较,因为执行器会同时使用距离函数结果和重新计算得到的排序操作符结果进行排序。否则,距离函数的结果值可以是任意有限的float8值,只要这些结果值的相对顺序与排序操作符返回的顺序一致即可。(无穷大和负无穷在内部用于处理空值等情况,因此不建议distance函数返回这些值。) + 如果距离函数对任意一个叶节点返回*recheck = true,原始排序操作符的返回类型必须是float8float4,且距离函数的结果值必须能与原始排序操作符的结果进行比较,因为执行器会同时使用距离函数结果和重新计算得到的排序操作符结果进行排序。否则,距离函数的结果值可以是任意有限的float8值,只要这些结果值的相对顺序与排序操作符返回的顺序一致即可。(无穷大和负无穷在内部用于处理空值等情况,因此不建议distance函数返回这些值。) @@ -539,12 +611,18 @@ my_distance(PG_FUNCTION_ARGS) 为了支持仅索引扫描,将数据项的压缩索引表示转换为原始数据类型。返回的数据必须是最初被索引值的精确、无损副本。 - SQL声明必须如下所示: + + 该函数的SQL声明必须如下所示: + + CREATE OR REPLACE FUNCTION my_fetch(internal) RETURNS internal AS 'MODULE_PATHNAME' LANGUAGE C STRICT; -参数是一个指向GISTENTRY结构体的指针。进入该函数时,它的key字段包含一个压缩形式的非 NULL 叶子 datum。返回值是另一个GISTENTRY结构体,其中的key字段以原始、未压缩形式包含同一个 datum。如果该操作符类的 compress 函数对叶子项不做任何处理,fetch方法可以原样返回参数。如果操作符类没有 compress 函数,则fetch方法也可以省略,因为它必然不会执行任何实际操作。 + + + 参数是一个指向GISTENTRY结构体的指针。进入该函数时,它的key字段包含一个压缩形式的非 NULL 叶子 datum。返回值是另一个GISTENTRY结构体,其key字段以原始、未压缩形式包含同一个 datum。如果该操作符类的 compress 函数对叶子项不做任何处理,fetch方法可以原样返回该参数。或者,如果该操作符类没有 compress 函数,那么fetch方法也可以省略,因为它必然是空操作。 + 而 C 模块中的对应代码则可以遵循如下框架: @@ -564,10 +642,10 @@ my_fetch(PG_FUNCTION_ARGS) fetched_data = palloc(sizeof(fetched_data_type)); /* - * Convert 'fetched_data' into the a Datum of the original datatype. + * 将 'fetched_data' 转换为原始数据类型的 Datum。 */ - /* fill *retval from fetched_data. */ + /* 根据 fetched_data 填充 *retval。 */ gistentryinit(*retval, PointerGetDatum(converted_datum), entry->rel, entry->page, entry->offset, FALSE); @@ -611,7 +689,10 @@ my_fetch(PG_FUNCTION_ARGS) 示例 - PostgreSQL源码发行包包含若干使用GiST实现索引方法的示例。核心系统目前提供文本搜索支持(为tsvectortsquery建立索引),还为部分内置几何数据类型提供等价于 R 树的功能(参见src/backend/access/gist/gistproc.c)。以下contrib模块也包含GiST操作符类: + + PostgreSQL源代码发行包包含了若干使用GiST实现的索引方法示例。核心系统目前提供了文本搜索支持(为tsvectortsquery建立索引),并为某些内置几何数据类型提供了与 R 树等价的功能(见src/backend/access/gist/gistproc.c)。下列contrib模块中也包含GiST操作符类: + + btree_gist @@ -629,7 +710,7 @@ my_fetch(PG_FUNCTION_ARGS) hstore - 用于存储 (key, value) 对的模块 + 用于存储(键,值)对的模块 diff --git a/zh/11/hash.sgml b/zh/11/hash.sgml index 199395b2..81f5f878 100644 --- a/zh/11/hash.sgml +++ b/zh/11/hash.sgml @@ -1,11 +1,11 @@ -哈希索引 +Hash 索引 索引 - 哈希 + Hash @@ -13,51 +13,51 @@ PostgreSQL - 提供了持久化的磁盘哈希索引实现,并且完全支持崩溃恢复。任何数据类型都可以使用哈希索引,包括那些没有明确定义线性顺序的数据类型。哈希索引只存储被索引数据的哈希值,因此对被索引数据列的大小没有限制。 + 提供了持久化的磁盘 hash 索引实现,并且完全支持崩溃恢复。任何数据类型都可以使用 hash 索引,包括那些没有明确定义线性顺序的数据类型。Hash 索引只存储被索引数据的 hash 值,因此对被索引数据列的大小没有限制。 - 哈希索引仅支持单列索引,也不支持唯一性检查。 + Hash 索引仅支持单列索引,也不支持唯一性检查。 - 哈希索引仅支持=操作符,因此指定范围操作的 WHERE 子句无法利用哈希索引。 + Hash 索引仅支持=操作符,因此指定范围操作的 WHERE 子句无法利用 hash 索引。 - 每个哈希索引元组只存储 4 字节的哈希值,而不存储实际的列值。因此,在为 UUID、URL 等较长的数据项建立索引时,哈希索引可能比 B-树小得多。由于没有列值,所有哈希索引扫描也都是有损的。哈希索引可以参与位图索引扫描和反向扫描。 + 每个 hash 索引元组只存储 4 字节的 hash 值,而不存储实际的列值。因此,在为 UUID、URL 等较长的数据项建立索引时,hash 索引可能比 B-树小得多。由于没有列值,所有 hash 索引扫描也都是有损的。Hash 索引可以参与位图索引扫描和反向扫描。 - 哈希索引最适合于在较大表上执行等值扫描、且以 SELECT 和 UPDATE 为主的工作负载。在 B-树索引中,搜索必须沿树向下直到找到叶页。在拥有数百万行的表中,这种向下遍历会增加访问数据的时间。在哈希索引中,与叶页对应的页称为桶页。相比之下,哈希索引允许直接访问桶页,因此可能减少大表中的索引访问时间。这种“逻辑 I/O”的减少,在索引/数据大于 shared_buffers/RAM 时会更加明显。 + Hash 索引最适合于在较大表上执行等值扫描、且以 SELECT 和 UPDATE 为主的工作负载。在 B-树索引中,搜索必须沿树向下直到找到叶页。在拥有数百万行的表中,这种向下遍历会增加访问数据的时间。在 hash 索引中,与叶页对应的页称为桶页。相比之下,hash 索引允许直接访问桶页,因此可能减少大表中的索引访问时间。这种“逻辑 I/O”的减少,在索引/数据大于 shared_buffers/RAM 时会更加明显。 - 哈希索引在设计上能够应对哈希值分布不均的情况。如果哈希值分布均匀,那么直接访问桶页的效果很好。当插入导致桶页填满时,额外的溢出页就会链接到该特定桶页上,从而在局部扩展用于存放匹配该哈希值的索引元组的空间。查询期间扫描某个哈希桶时,需要遍历其全部溢出页。因此,对于某些数据,不平衡的哈希索引在所需块访问次数方面实际上可能比 B-树更差。 + Hash 索引在设计上能够应对 hash 值分布不均的情况。如果 hash 值分布均匀,那么直接访问桶页的效果很好。当插入导致桶页填满时,额外的溢出页就会链接到该特定桶页上,从而在局部扩展用于存放匹配该 hash 值的索引元组的空间。查询期间扫描某个 hash 桶时,需要遍历其全部溢出页。因此,对于某些数据,不平衡的 hash 索引在所需块访问次数方面实际上可能比 B-树更差。 - 由于会出现这些溢出情况,可以说哈希索引最适合用于唯一值、近乎唯一值,或者每个哈希桶中行数较少的数据。 + 由于会出现这些溢出情况,可以说 hash 索引最适合用于唯一值、近乎唯一值,或者每个 hash 桶中行数较少的数据。 避免问题的一种可能办法,是使用部分索引条件把高度非唯一的值排除在索引之外,但这在很多情况下可能并不适用。 - 与 B-树一样,哈希索引也会执行简单的索引元组删除。这是一种延迟维护操作,用于删除那些已知可以安全删除的索引元组(即其项标识符的 LP_DEAD 位已经被设置的那些元组)。如果插入操作发现页上没有可用空间,我们会尝试通过移除死索引元组来避免创建新的溢出页。如果该页当时已被钉住,就无法执行移除。死索引指针也会在 VACUUM 期间被删除。 + 与 B-树一样,hash 索引也会执行简单的索引元组删除。这是一种延迟维护操作,用于删除那些已知可以安全删除的索引元组(即其项标识符的 LP_DEAD 位已经被设置的那些元组)。如果插入操作发现页上没有可用空间,我们会尝试通过移除死索引元组来避免创建新的溢出页。如果该页当时已被钉住,就无法执行移除。死索引指针也会在 VACUUM 期间被删除。 - 如果可能,VACUUM 还会尝试将索引元组压缩到尽可能少的溢出页上,以最小化溢出链。 + 如果可能,VACUUM 还会尝试将索引元组集中存放在尽可能少的溢出页上,以最小化溢出链。 如果某个溢出页变为空页,该溢出页就可以被回收并在其他桶中重用,不过我们从不将它们返还给操作系统。 - 目前除了使用 REINDEX 重建哈希索引之外,还没有缩小哈希索引的方法。 + 目前除了使用 REINDEX 重建 hash 索引之外,还没有缩小 hash 索引的方法。 同样也没有减少桶数量的方法。 - 随着被索引行数的增长,哈希索引可能会扩展桶页数量。哈希键到桶号的映射经过选择,使得索引能够增量扩展。当需要向索引中添加一个新桶时,恰好只需要“拆分”一个现有桶,并根据更新后的键到桶号映射,将其中一部分元组转移到新桶。 + 随着被索引行数的增长,Hash 索引可能会扩展桶页数量。hash 键到桶号的映射经过选择,使得索引能够增量扩展。当需要向索引中添加一个新桶时,恰好只需要“拆分”一个现有桶,并根据更新后的键到桶号映射,将其中一部分元组转移到新桶。 - 这种扩展是在前台进行的,因此可能会增加用户插入操作的执行时间。因此,哈希索引可能不适合行数快速增长的表。 + 这种扩展是在前台进行的,因此可能会增加用户插入操作的执行时间。因此,hash 索引可能不适合行数快速增长的表。 @@ -66,7 +66,7 @@ 实现 - 哈希索引中有四种页:元页(第零页),其中包含静态分配的控制信息;主桶页;溢出页;以及位图页,后者用于跟踪已被释放且可供重用的溢出页。在寻址时,位图页被视为溢出页的一个子集。 + hash 索引中有四种页:元页(第零页),其中包含静态分配的控制信息;主桶页;溢出页;以及位图页,后者用于跟踪已被释放且可供重用的溢出页。在寻址时,位图页被视为溢出页的一个子集。 @@ -74,15 +74,15 @@ - 主桶页和溢出页是独立分配的,因为任何一个给定索引相对于其桶数,可能需要更多或更少的溢出页。哈希代码使用了一组颇有意思的寻址规则,以支持可变数量的溢出页,同时又不必在主桶页创建后再移动它们。 + 主桶页和溢出页是独立分配的,因为任何一个给定索引相对于其桶数,可能需要更多或更少的溢出页。hash 实现代码使用了一组颇有意思的寻址规则,以支持可变数量的溢出页,同时又不必在主桶页创建后再移动它们。 - 被索引表中的每一行,都由哈希索引中的单个索引元组表示。哈希索引元组存储在桶页中,如果存在溢出页,也会存储在溢出页中。为了加快搜索速度,我们将任一索引页中的索引项按哈希码排序,从而可以在索引页内使用二分查找。但请注意,并不假定同一桶中不同索引页之间的哈希码具有任何相对顺序。 + 被索引表中的每一行,都由 hash 索引中的单个索引元组表示。Hash 索引元组存储在桶页中,如果存在溢出页,也会存储在溢出页中。为了加快搜索速度,我们将任一索引页中的索引项按 hash 码排序,从而可以在索引页内使用二分查找。但请注意,并不假定同一桶中不同索引页之间的 hash 码具有任何相对顺序。 - 用于扩展哈希索引的桶拆分算法过于复杂,这里不再展开说明;但在src/backend/access/hash/README中有更详细的描述。该拆分算法具备崩溃安全性,如果未能成功完成,可以重新启动。 + 用于扩展 hash 索引的桶拆分算法过于复杂,这里不再展开说明;但在src/backend/access/hash/README中有更详细的描述。该拆分算法具备崩溃安全性,如果未能成功完成,可以重新启动。 diff --git a/zh/11/high-availability.sgml b/zh/11/high-availability.sgml index fd71e711..587ebff5 100644 --- a/zh/11/high-availability.sgml +++ b/zh/11/high-availability.sgml @@ -253,7 +253,7 @@ protocol to make nodes agree on a serializable transactional order. - 主库失效绝不会丢失数据 + 主库失效时绝不丢失数据 启用同步时 @@ -341,7 +341,7 @@ protocol to make nodes agree on a serializable transactional order. - 连续归档可用于创建一种高可用性(HA)集簇配置,其中有一个或多个备库随时准备在主库失效时接管操作。这种能力通常称为温备日志传送。 + 持续归档可用于创建一种高可用性(HA)集簇配置,其中有一个或多个备库随时准备在主库失效时接管操作。这种能力通常称为温备日志传送 @@ -473,7 +473,9 @@ archive_cleanup_command = 'pg_archivecleanup /path/to/archive %r' 默认情况下流复制是异步的(见 ),在这种情况下主库上提交一个事务与该变化在备库上变得可见之间存在短暂的延迟。不过这种延迟比基于文件的日志传送方式中要小得多,在备库的能力足以跟得上负载的前提下,延迟通常低于一秒。在流复制中,不需要 archive_timeout 来缩减数据丢失窗口。 - 如果使用流复制却未使用基于文件的连续归档,服务器可能在备库收到旧 WAL 段之前就将其回收。如果发生这种情况,备库需要从新的基础备份重新初始化。可以将 wal_keep_segments 设得足够大,确保 WAL 段不会过早回收,或者为备库配置复制槽,以避免这种情况。如果配置了备库可以访问的 WAL 归档,则不需要这些办法,因为只要归档保留了足够的段,备库就始终可以借助归档追赶主库。 + + 如果你使用流复制,但没有启用基于文件的持续归档,服务器可能会在备库收到旧的 WAL 段之前就把它们回收掉。如果发生这种情况,备库就需要重新通过新的基础备份进行初始化。可以通过把 wal_keep_segments 设置得足够大,以确保 WAL 段不会过早被回收,或者为备库配置一个复制槽,从而避免这种情况。如果配置了一个备库可访问的 WAL 归档,就不需要这些方案,因为只要归档保留了足够多的段,备库始终可以利用归档追赶上来。 + 要使用流复制,请先按 所述配置基于文件的日志传送备库。将这种备库转为流复制备库的关键步骤,是在 recovery.conf 文件中设置 primary_conninfo,使其指向主库。在主库上设置 和认证选项(参见 pg_hba.conf),使备库能够连接主库的 replication 伪数据库(参见 )。 @@ -485,13 +487,16 @@ archive_cleanup_command = 'pg_archivecleanup /path/to/archive %r' 设置来自备库的最大并发连接数(详见 )。 - 备库启动后,如果正确设置了 primary_conninfo,备库会在重放归档中所有可用的 WAL 文件后连接主库。如果连接成功,就会在备库上看到 WAL 接收进程,在主库上看到对应的 WAL 发送进程。 + 备库启动后,如果正确设置了 primary_conninfo,备库会在重放归档中所有可用的 WAL 文件后连接主库。如果连接成功,就会在备库上看到 walreceiver 进程,在主库上看到对应的 walsender 进程。 认证 - 务必正确设置复制访问权限,使只有受信任的用户才能读取 WAL 流,因为很容易从中提取特权信息。备库必须以超级用户或具有 REPLICATION 权限的账户向主库认证。建议为复制创建专用用户账户,并授予 REPLICATIONLOGIN 权限。虽然 REPLICATION 权限赋予的权限很高,但它不允许用户修改主库系统上的任何数据,而 SUPERUSER 权限允许这样做。 + 务必正确设置复制访问权限,使只有受信任的用户才能读取 WAL 流,因为很容易从中提取需要权限才能访问的信息。备库必须以超级用户或具有 REPLICATION 权限的账户向主库认证。建议为复制创建专用用户账户,并授予 REPLICATIONLOGIN 权限。虽然 REPLICATION 权限赋予的权限很高,但它不允许用户修改主库系统上的任何数据,而 SUPERUSER 权限允许这样做。 + + + 复制的客户端认证由 pg_hba.conf 中的一条记录控制,该记录需要把 replication 指定在 database 字段中。例如,如果备库运行在主机 IP 192.168.1.100 上,并且用于复制的账户名为 foo,管理员可以在主库上的 pg_hba.conf 文件中加入下列行: - 复制的客户端认证由 pg_hba.conf 中的记录控制。记录要将 replication 指定为 database 字段的值。例如,如果备库所在主机的 IP 地址为 192.168.1.100,用于复制的账户名为 foo,管理员可以将以下行添加到 pg_hba.conf 文件(位于主库)中: + # Allow the user "foo" from host 192.168.1.100 to connect to the primary # as a replication standby if the user's password is correctly supplied. # @@ -512,7 +517,7 @@ primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass' 流复制的一个重要健康指标,是主库上已经生成但尚未在备库上应用的 WAL 记录量。你可以通过比较主库上的当前 WAL 写入位置和备库收到的最后一个 WAL 位置来计算这种滞后。这些位置分别可以用主库上的 pg_current_wal_lsn 和备库上的 pg_last_wal_receive_lsn 取得(详见 )。备库上的最后一个 WAL 接收位置也会显示在 WAL 接收进程的进程状态中,即通过 ps 命令显示的状态(详见 )。 - 可以通过 视图获取 WAL 发送进程列表。pg_current_wal_lsn 与该视图的 sent_lsn 字段相差较大,可能表示主库负载很高;而 sent_lsn 与备库上 pg_last_wal_receive_lsn 的差值较大,则可能表示网络延迟或备库负载很高。 + 可以通过 视图获取 WAL 发送进程列表。pg_current_wal_lsn 与该视图的 sent_lsn 字段相差较大,可能表示主库负载很高;而 sent_lsn 与备库上 pg_last_wal_receive_lsn 之间存在差异,则可能表示网络延迟或备库负载很高。 在热备上,可以通过 视图获取 WAL 接收进程的状态。如果 pg_last_wal_replay_lsn 与该视图的 received_lsn 相差较大,说明接收 WAL 的速度超过了重放速度。
@@ -524,12 +529,12 @@ primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass' 流复制 - 复制槽提供了一种自动化方法,以确保主库在所有备库都收到 WAL 段之前不会删除它们,并且即使备库处于断开状态,主库也不会删除可能导致恢复冲突的行。 + 复制槽提供了一种自动化方法,以确保主库在所有备库都收到 WAL 段之前不会删除它们,并且即使备库处于断开状态,主库也不会删除那些一旦删除就可能导致恢复冲突的行。 除了使用复制槽,也可以通过 防止旧 WAL 段被删除,或者使用 将这些段保存在归档中。不过,这些方法通常会保留多于实际所需的 WAL 段,而复制槽只保留已知必需的段数。这些方法的优点是能限制 pg_wal 的空间需求;目前使用复制槽还无法做到这一点。 类似地, 可以保护相关行,避免它们被清理删除,但前者在备库未连接期间无法提供保护,后者则通常需要设为较大的值才能提供充分保护。复制槽克服了这些缺点。 - 查询和操作复制槽 + 查询和管理复制槽 每个复制槽都有一个名称,该名称可以包含小写字母、数字和下划线字符。 @@ -575,7 +580,9 @@ primary_slot_name = 'node_a_slot' 级联复制特性允许一台备库接受复制连接,并像中继器一样把 WAL 记录流式发送给其他备库。这可以用来减少直接连接到主库的连接数,并使站点间的带宽开销最小化。 - 同时充当接收方和发送方的备库称为级联备库。与主库连接更直接的备库称为上游服务器,距离更远的备库则称为下游服务器。级联复制不限制下游服务器的数量或组织方式,不过每个备库只连接一个上游服务器,并最终连接到同一个主库。 + + 一台同时扮演接收者和发送者角色的备库称为级联备库。与主库连接更直接(经过更少级联备库)的备库称为上游服务器,而距离更远的备库称为下游服务器。级联复制并不限制下游服务器的数量和拓扑,不过每台备库只连接到一台上游服务器,而这条链路最终都会通向同一台主库。 + 级联备库不仅发送从主库接收到的 WAL 记录,也会发送那些从归档中恢复的记录。因此,即使某条上游复制连接被中断,只要仍有新的 WAL 记录可用,下游的流复制就会继续。 @@ -615,7 +622,9 @@ primary_slot_name = 'node_a_slot' 请求同步复制时,每个写事务的提交都会等待,直到收到确认,表明该提交已被写入主库和备库磁盘上的预写式日志。数据唯一可能丢失的情况,是主库和备库同时崩溃。这可以提供更高的持久性级别,不过前提是系统管理员必须谨慎地部署和管理这两台服务器。等待确认会增强用户对服务器崩溃时更改不会丢失的信心,但也必然会增加请求事务的响应时间。最短等待时间是主库与备库之间的往返时间。 - 只读事务和事务回滚无需等待备库回复。子事务提交也不等待备库响应,只有顶层提交才会等待。数据加载或索引构建等长时间运行的操作,直到最后的提交消息才会等待。所有两阶段提交操作都需要等待提交,包括准备和提交两个阶段。 + + 只读事务和事务回滚不需要等待备库的回应。子事务提交也不需要等待备库响应,只有顶层提交才需要等待。数据装载或索引构建等长时间运行的动作,直到最终提交时才会等待。所有两阶段提交操作都需要等待提交,包括准备和提交两个阶段。 + 同步备库可以是物理复制备库,也可以是逻辑复制订阅者。它还可以是任何其他物理或逻辑 WAL 复制流的消费者,只要它知道如何发送适当的反馈消息。除了内置的物理和逻辑复制系统之外,还包括pg_receivewalpg_recvlogical之类的专用程序,以及一些第三方复制系统和定制程序。关于同步复制支持的细节,请查看相应文档。 @@ -629,7 +638,7 @@ primary_slot_name = 'node_a_slot' - 当提交记录已经在主库上写入磁盘之后,WAL 记录就会被发送到备库。每当新的一批 WAL 数据被写入磁盘时,备库就会发送回复消息,除非备库上的wal_receiver_status_interval被设置为零。如果synchronous_commit被设置为remote_apply,那么备库会在提交记录被重放时发送回复消息,从而使该事务变得可见。如果根据主库上的synchronous_standby_names设置,该备库被选为同步备库,那么它发出的回复会与其他同步备库的回复一起,用于决定何时释放那些正在等待确认提交记录已被收到的事务。这些参数允许管理员指定哪些备库应作为同步备库。注意,同步复制的配置主要在主库上进行。被命名的备库必须直接连接到主库;主库并不知道使用级联复制的下游备库。 + 当提交记录已经在主库上写入磁盘之后,WAL 记录就会被发送到备库。每当新的一批 WAL 数据被写入磁盘时,备库就会发送回复消息,除非备库上的wal_receiver_status_interval被设置为零。如果synchronous_commit被设置为remote_apply,那么备库会在提交记录被重放、该事务变得可见时发送回复消息。如果根据主库上的synchronous_standby_names设置,该备库被选为同步备库,那么它发出的回复会与其他同步备库的回复一起,用于决定何时释放那些正在等待确认提交记录已被收到的事务。这些参数允许管理员指定哪些备库应作为同步备库。注意,同步复制的配置主要在主库上进行。被命名的备库必须直接连接到主库;主库并不知道使用级联复制的下游备库。 @@ -641,7 +650,7 @@ primary_slot_name = 'node_a_slot' - 如果请求快速关闭,用户将停止等待。不过,与使用异步复制时一样,在所有尚未解决的 WAL 记录传输到当前已连接的备库之前,服务器不会完全关闭。 + 如果请求快速关闭,用户将停止等待。不过,与使用异步复制时一样,在所有尚未传送的 WAL 记录传输到当前已连接的备库之前,服务器不会完全关闭。 @@ -663,14 +672,14 @@ synchronous_standby_names = 'FIRST 2 (s1, s2, s3)' 在这个例子中,如果四台备库s1s2s3s4都在运行,则s1s2会被选为同步备库,因为它们的名字在备库名称列表中出现得更早。s3是潜在的同步备库,当s1s2中的任意一台失效时,它就会接替其角色。由于s4的名称不在列表中,因此它是异步备库。 - ANY方法指定基于法定人数的同步复制,使事务提交等待,直到它们的 WAL 记录被复制到列表中所要求数量的同步备库中的至少这么多台。 + ANY方法指定基于法定人数的同步复制,使事务提交等待,直到它们的 WAL 记录被复制到列表中至少所要求数量的同步备库。 基于法定人数的多同步备库的synchronous_standby_names示例如下: synchronous_standby_names = 'ANY 2 (s1, s2, s3)' - 在这个例子中,如果四台备库s1s2s3s4都在运行,事务提交将等待来自s1s2s3中的任意两台备库的回复。由于s4的名字不在列表中,因此它是异步备库。 + 在这个例子中,如果四台备库s1s2s3s4都在运行,事务提交将等待来自s1s2s3中的至少任意两台备库的回复。由于s4的名字不在列表中,因此它是异步备库。 备库的同步状态可以通过pg_stat_replication视图查看。 @@ -693,7 +702,7 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' - 通过在应用级别(在主库上)指定同步复制选项,我们可以只对最重要的变更提供同步复制,而不会拖慢整体工作负载。应用级别选项是让高性能应用获得同步复制收益的一种重要而实用的工具。 + 通过在应用级别(在主库上)指定同步复制选项,我们可以只对最重要的变更提供同步复制,而不会拖慢大部分工作负载。应用级别选项是让高性能应用获得同步复制收益的一种重要而实用的工具。 @@ -705,7 +714,9 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' 高可用规划 - synchronous_standby_names 指定同步备库的数量和名称。当 synchronous_commit 设为 onremote_applyremote_write 时,事务提交会等待这些备库响应。如果其中任何一个同步备库崩溃,这些事务提交就可能永远无法完成。 + + synchronous_standby_names指定了当synchronous_commit设置为onremote_applyremote_write时,事务提交需要等待其响应的同步备库的数量和名称。如果任意一台同步备库崩溃,此类事务提交就可能永远无法完成。 + 对于高可用而言,最好的办法是确保你始终保有所要求数量的同步备库。这可以通过在synchronous_standby_names中命名多个潜在同步备库来实现。 @@ -723,7 +734,9 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' 当一台备库第一次连接到主库时,它还没有正确同步。这种状态称为catchup模式。一旦备库与主库之间的滞后第一次变为零,它就会进入实时的streaming状态。备库刚创建之后,追赶阶段可能会持续较长时间。如果备库被关闭,则追赶阶段会随着它停机时间的延长而变长。只有在到达streaming状态后,备库才能成为同步备库。这种状态可以通过pg_stat_replication视图查看。 - 如果主库在提交等待确认期间重启,那么主库数据库恢复后,这些等待中的事务就会被标记为完全提交。无法确定在主库崩溃时,所有备库是否已收到所有尚未确认的 WAL 数据。某些事务即使在主库上显示为已提交,在备库上也可能未显示为已提交。我们提供的保证是:只有确定 WAL 数据已由所有同步备库安全接收,应用才会收到事务成功提交的明确确认。 + + 如果主库在提交正等待确认时重启,这些等待中的事务会在主库恢复后被标记为已完全提交。无法确定在主库崩溃时,所有备库是否已经收到全部待传送的 WAL 数据。因此,某些事务可能不会在备库上显示为已提交,即使它们在主库上显示为已提交。我们所提供的保证是:只有在确认 WAL 数据已经被所有同步备库安全接收之后,应用才会收到事务成功提交的显式确认。 + 如果你确实无法维持所要求数量的同步备库,那么就应当在synchronous_standby_names中减少事务提交需要等待其响应的同步备库数量(或者禁用它),然后在主库上重新加载配置文件。 @@ -739,7 +752,7 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' - 备库上的连续归档 + 在备库中持续归档 持续归档 @@ -780,7 +793,7 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' - 一旦故障切换到备库,系统中就只剩下一台服务器在运行。这被称为退化状态。原来的备库现在成为主库,而原来的主库已经停机,并且可能持续停机。要恢复到正常运行状态,就必须重新创建一台备库:要么在原主库恢复后在其上重建,要么在第三台可能是全新的服务器上重建。在大型集簇上,可以使用工具来加快这一过程。一旦完成,就可以认为主库和备库已经交换了角色。有些人会选择使用第三台服务器,在新的备库重建完成之前为新的主库提供备份,但显然这会让系统配置和操作流程更加复杂。 + 一旦故障切换到备库,系统中就只剩下一台服务器在运行。这被称为退化状态。原来的备库现在成为主库,而原来的主库已经停机,并且可能持续停机。要恢复到正常运行状态,就必须重新创建一台备库:要么在原主库恢复后在其上重建,要么在第三台可能是全新的服务器上重建。在大型集簇上,可以使用工具来加快这一过程。一旦完成,就可以认为主库和备库已经交换了角色。有些人会选择使用第三台服务器,在新的备库重建完成之前为新的主库提供后备支持,但显然这会让系统配置和操作流程更加复杂。 @@ -797,7 +810,7 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' 注意,在这种模式下,服务器每次应用一整个 WAL 文件。因此,如果使用备库处理查询(参见热备),主库上的操作与备库上能看到该操作的结果之间,会有一段延迟,其长度相当于写满一个 WAL 文件所需的时间。可以用 archive_timeout 缩短这一延迟。还要注意,这种方法不能与流复制结合使用。 - 主库和备库上执行的操作都是普通的连续归档和恢复任务。两台数据库服务器之间唯一的联系,就是它们共享的 WAL 文件归档:主库写入归档,备库从归档读取。必须确保不同主库的 WAL 归档不会混在一起或弄错。如果归档仅用于备库运行,则无需保留很大的归档。 + 主库和备库上执行的操作都是普通的持续归档和恢复任务。两台数据库服务器之间唯一的联系,就是它们共享的 WAL 文件归档:主库写入归档,备库从归档读取。必须确保不同主库的 WAL 归档不会混在一起或弄错。如果归档仅用于备库运行,则无需保留很大的归档。 让这两台松散耦合的服务器协同工作的关键,只是备库上的 restore_command:当请求下一个 WAL 文件时,它会等待主库提供该文件。restore_command 在备库的 recovery.conf 文件中指定。正常恢复处理会从 WAL 归档请求文件,如果文件不可用,就报告失败。对备库处理而言,下一个 WAL 文件尚不可用是正常情况,因此备库必须等待它出现。对于以 .history 结尾的文件,则无需等待,必须返回非零返回码。可以编写一个自定义脚本,循环检查下一个 WAL 文件是否存在,从而实现会等待的 restore_command。还必须提供触发故障切换的方法,用来中断 restore_command、跳出循环,并向备库返回文件未找到错误。这会结束恢复,随后备库就会作为普通服务器启动。 @@ -826,7 +839,7 @@ if (!triggered) 尽可能将主库和备库系统配置得相同,包括安装两个完全相同、发行版本一致的 PostgreSQL 副本。 - 配置连续归档,将主库的 WAL 归档到备库上的一个目录。确保在主库上正确设置 (参见 )。 + 配置持续归档,将主库的 WAL 归档到备库上的一个目录。确保在主库上正确设置 (参见 )。 制作主库的基础备份(参见 ),并将这些数据装载到备库上。 @@ -872,25 +885,34 @@ if (!triggered) 用户概览 - 当备库上的参数被设置为真时,一旦恢复把系统带到一致状态并为热备做好准备,它就会开始接受连接。所有这类连接都严格是只读的,甚至不能写入临时表。 + 当备库上的参数被设置为真时,一旦恢复把系统带到一致状态,它就会开始接受连接。所有这类连接都严格是只读的,甚至不能写入临时表。 备库上的数据需要一些时间才能从主库到达,因此主库和备库之间会有可测量的延迟。因此,在主库和备库上几乎同时运行同一查询,可能会返回不同的结果。我们说备库上的数据与主库是最终一致的。一旦某个事务的提交记录在备库上被重放,该事务所做的修改就会对备库上之后取得的所有新快照可见。快照可以在每个查询开始时取得,也可以在每个事务开始时取得,这取决于当前的事务隔离级别。详见 - 热备期间启动的事务可以执行以下命令: + + 在热备期间启动的事务可以发出下列命令: + + - 查询访问 - SELECTCOPY TO + + 查询访问:SELECTCOPY TO + - 游标命令 - DECLAREFETCHCLOSE + + 游标命令:DECLAREFETCHCLOSE + - 参数 - SHOWSETRESET + 参数:SHOWSETRESET - 事务管理命令 + + 事务管理命令: + BEGINENDABORTSTART TRANSACTION @@ -903,7 +925,7 @@ if (!triggered) - EXCEPTION块或其他内部子事务 + EXCEPTION块和其他内部子事务 @@ -916,10 +938,15 @@ if (!triggered) - 计划和资源 - PREPAREEXECUTEDEALLOCATEDISCARD + + 计划和资源:PREPAREEXECUTE、 + DEALLOCATEDISCARD + - 插件和扩展 - LOAD + + 插件和扩展:LOAD + @@ -929,12 +956,23 @@ if (!triggered) - 热备期间启动的事务不会被分配事务 ID,也不能写入系统的预写式日志。因此,以下操作会产生错误消息: + + 在热备期间启动的事务永远不会被分配事务 ID,也不能写入系统预写式日志。因此,下列动作都会产生错误消息: + + - 数据操纵语言(DML)- INSERTUPDATEDELETECOPY FROMTRUNCATE。注意,恢复期间不允许任何会导致触发器执行的操作。这一限制也适用于临时表,因为不分配事务 ID 就无法读写表中的行,而目前热备环境中无法分配事务 ID。 + + 数据操纵语言(DML):INSERT、 + UPDATEDELETE、 + COPY FROM、 + TRUNCATE。请注意,恢复期间不存在任何允许执行触发器的动作。这个限制甚至适用于临时表,因为不分配事务 ID 就无法读取或写入表行,而目前热备环境中无法分配事务 ID。 + - 数据定义语言(DDL)- CREATEDROPALTERCOMMENT。这一限制也适用于临时表,因为执行这些操作需要更新系统目录表。 + + 数据定义语言(DDL):CREATE、 + DROPALTERCOMMENT。这个限制甚至适用于临时表,因为执行这些操作需要更新系统目录表。 + @@ -962,13 +1000,13 @@ if (!triggered) - BEGIN READ WRITE, + BEGIN READ WRITESTART TRANSACTION READ WRITE - SET TRANSACTION READ WRITE, + SET TRANSACTION READ WRITESET SESSION CHARACTERISTICS AS TRANSACTION READ WRITE @@ -981,10 +1019,16 @@ if (!triggered) - 两阶段提交命令 - PREPARE TRANSACTIONCOMMIT PREPAREDROLLBACK PREPARED,因为即使只读事务也需要在准备阶段(两阶段提交的第一阶段)写入 WAL。 + + 两阶段提交命令:PREPARE TRANSACTION、 + COMMIT PREPAREDROLLBACK PREPARED, + 因为即使是只读事务,在准备阶段(两阶段提交的第一阶段)也需要写入 WAL。 + - 序列更新 - nextval()setval() + + 序列更新:nextval()setval() + @@ -1062,19 +1106,17 @@ if (!triggered) - 一旦max_standby_archive_delaymax_standby_streaming_delay指定的延迟被超越,冲突查询将被取消。这通常仅导致一个取消错误,尽管在重放一个DROP DATABASE的情况下整个冲突会话都将被中断。另外,如果冲突发生在一个被空闲事务持有的锁上,该冲突会话会被中断(这种行为可能在未来被改变)。 + 一旦max_standby_archive_delaymax_standby_streaming_delay指定的延迟被超越,冲突查询将被取消。这通常仅导致一个取消错误,尽管在重放一个DROP DATABASE的情况下整个冲突会话都将被终止。另外,如果冲突发生在一个被空闲事务持有的锁上,该冲突会话会被终止(这种行为可能在未来被改变)。 - - 被取消的查询可能会立即被重试(当然是在开始一个新的事务后)。因为查询取消依赖于 WAL 记录被重放的本质,如果一个被取消的查询被再次执行,它可能会很好地成功完成。 - + 被取消的查询可以立即重试(当然,要先开始一个新事务)。由于查询取消取决于正在重放的 WAL 记录的性质,被取消的查询再次执行时完全可能成功。 - 记住延迟参数是从 WAL 数据被备库收到后流逝的时间。因此,留给备库上任何一个查询的宽限期从不会超过延迟参数,并且如果备库已经由于等待之前的查询完成而落后或者因为过重的更新负载而无法跟上主库,宽限期可能会更少。 + 请记住,延迟参数要与备库收到 WAL 数据之后经过的时间进行比较。因此,留给备库上任何一个查询的宽限期从不会超过延迟参数,并且如果备库已经由于等待之前的查询完成而落后或者因为过重的更新负载而无法跟上主库,宽限期可能会更少。 - 备库查询与 WAL 重放发生冲突的最常见原因是过早清理。正常情况下,当没有事务需要看到旧行版本时,PostgreSQL允许清理这些旧行版本,以保证按照 MVCC 规则得到正确的数据可见性。不过,这条规则只能应用于在主库上执行的事务。因此,主库上的清理有可能移除某个备库事务仍然可见的行版本。 + 备库查询与 WAL 重放发生冲突的最常见原因是过早清理。正常情况下,当不再有事务需要看到旧行版本来保证符合 MVCC 规则的数据可见性时,PostgreSQL允许清理这些旧行版本。不过,这条规则只能应用于在主库上执行的事务。因此,主库上的清理有可能移除某个备库事务仍然可见的行版本。 有经验的用户应注意,行版本清理和行版本冻结都有可能与备库查询冲突。手动运行 VACUUM FREEZE 很可能导致冲突,即使表中没有更新过或删除过的行也是如此。 @@ -1147,18 +1189,29 @@ LOG: database system is ready to accept read only connections - 主库上写出的事务状态 "hint bits" 不会被 WAL 记录,因此备库上的数据很可能会再次写出这些提示位。这样一来,即使所有用户都是只读的,备库仍然会执行磁盘写操作;不过数据值本身并不会发生变化。用户仍然会写出大型排序临时文件,并重新生成 relcache 信息文件,因此在热备模式下,数据库没有任何部分是真正只读的。还要注意,使用dblink模块写入远程数据库,以及借助 PL 函数执行其他数据库外部操作,依然是可能的,即使该事务在本地是只读的。 + 主库上写出的事务状态“提示位” 不会被 WAL 记录,因此备库上的数据很可能会再次写出这些提示位。这样一来,即使所有用户都是只读的,备库仍然会执行磁盘写操作;不过数据值本身并不会发生变化。用户仍然会写出大型排序临时文件,并重新生成 relcache 信息文件,因此在热备模式下,数据库没有任何部分是真正只读的。还要注意,使用dblink模块写入远程数据库,以及借助 PL 函数执行其他数据库外部操作,依然是可能的,即使该事务在本地是只读的。 - 恢复模式下不接受以下类型的管理命令: + + 在恢复模式下,不接受下列类型的管理命令: + + - 数据定义语言(DDL)- 例如 CREATE INDEX + + 数据定义语言(DDL):例如 CREATE INDEX + - 权限和所有权 - GRANTREVOKEREASSIGN + + 权限和所有权:GRANTREVOKE、 + REASSIGN + - 维护命令 - ANALYZEVACUUMCLUSTERREINDEX + + 维护命令:ANALYZEVACUUM、 + CLUSTERREINDEX + @@ -1203,7 +1256,9 @@ LOG: database system is ready to accept read only connections 不能分配新的 OID,不过某些UUID生成器仍可工作,只要它们不依赖于向数据库写入新的状态。 - 目前,不允许在只读事务中创建临时表,因此现有脚本在某些情况下无法正确运行。未来版本可能会放宽这一限制。这既涉及 SQL 标准兼容性,也涉及技术问题。 + + 目前,在只读事务期间不允许创建临时表,因此某些现有脚本在这种情况下将无法正常运行。这个限制可能会在未来版本中放宽。这既涉及 SQL 标准兼容性问题,也涉及技术问题。 + 只有在表空间为空时DROP TABLESPACE才能成功。某些备库用户可能正在通过他们的temp_tablespaces参数使用该表空间。如果该表空间中存在临时文件,所有活动查询都将被取消,以确保临时文件被移除,这样该表空间才能被移除并且 WAL 重放可以继续。 @@ -1213,7 +1268,9 @@ LOG: database system is ready to accept read only connections 在主库上执行DROP DATABASEALTER DATABASE ... SET TABLESPACE会生成一条 WAL 记录,从而强制断开备库上所有连接到该数据库的用户。这个动作会立即发生,而不受max_standby_streaming_delay设置的影响。注意,ALTER DATABASE ... RENAME不会断开用户,这在大多数情况下不会被注意到,但如果程序依赖某种基于数据库名的机制,在某些情况下可能会导致混乱。 - 在正常(非恢复)模式下,如果对具有登录能力的角色执行 DROP USERDROP ROLE,而该用户仍处于连接状态,已连接的用户不会受到影响,会继续保持连接。不过,该用户无法重新连接。恢复期间也是如此,因此,在主库上执行 DROP USER 不会断开该用户在备库上的连接。 + + 在普通(非恢复)模式下,如果你对一个具有登录能力的角色执行DROP USERDROP ROLE,而该用户仍然处于连接状态,那么已连接用户不会发生任何变化 — 他们会继续保持连接,不过之后不能重新连接。这种行为在恢复期间同样适用,因此在主库上执行一次DROP USER并不会断开备库上的该用户连接。 + 统计收集器在恢复期间保持活动状态。所有扫描、读取、块、索引使用情况等,都会在备库上正常记录。重放操作不会重复记录其在主库上产生的统计影响,因此重放一次插入不会增加 pg_stat_user_tables 的 Inserts 列。统计文件会在恢复开始时被删除,因此主库和备库的统计信息不同;这是特性,不是缺陷。 @@ -1241,9 +1298,15 @@ LOG: database system is ready to accept read only connections 注意事项 - 热备有几个限制。这些限制能够、也很可能会在未来版本中消除: + + 热备有若干限制。 + 这些限制在未来的版本中可以、也很可能会被修复: + + - 必须完整掌握正在运行的事务,才能取得快照。如果事务使用了大量子事务(目前为超过 64 个),只读连接的开始时间就会延迟,直到运行时间最长的写事务完成。发生这种情况时,服务器日志中会记录说明消息。 + + 在能够取得快照之前,必须完整了解正在运行的事务。使用大量子事务(目前超过 64 个)的事务,会把只读连接的启动推迟到持续时间最长的写事务完成之后。如果发生这种情况,服务器日志中会发送解释性消息。 + diff --git a/zh/11/history.sgml b/zh/11/history.sgml index ae5b49e0..2e00b444 100644 --- a/zh/11/history.sgml +++ b/zh/11/history.sgml @@ -151,6 +151,8 @@ 不过各个方面的工作仍在继续。 - 关于此后PostgreSQL发生了哪些变化的详情,可在中查阅。 + + 自那以后 PostgreSQL 发生了哪些变化,可见 。 + diff --git a/zh/11/indexam.sgml b/zh/11/indexam.sgml index 6a0bb36f..ec3a7aa6 100644 --- a/zh/11/indexam.sgml +++ b/zh/11/indexam.sgml @@ -34,64 +34,64 @@ typedef struct IndexAmRoutine NodeTag type; /* - * Total number of strategies (operators) by which we can traverse/search - * this AM. Zero if AM does not have a fixed set of strategy assignments. + * 可用于遍历或搜索此 AM 的策略(操作符)总数。 + * 如果 AM 没有固定的一组策略分配,则为零。 */ uint16 amstrategies; - /* total number of support functions that this AM uses */ + /* 此 AM 使用的支持函数总数 */ uint16 amsupport; - /* does AM support ORDER BY indexed column's value? */ + /* AM 是否支持按被索引列的值进行 ORDER BY? */ bool amcanorder; - /* does AM support ORDER BY result of an operator on indexed column? */ + /* AM 是否支持按被索引列上操作符的结果进行 ORDER BY? */ bool amcanorderbyop; - /* does AM support backward scanning? */ + /* AM 是否支持反向扫描? */ bool amcanbackward; - /* does AM support UNIQUE indexes? */ + /* AM 是否支持 UNIQUE 索引? */ bool amcanunique; - /* does AM support multi-column indexes? */ + /* AM 是否支持多列索引? */ bool amcanmulticol; - /* does AM require scans to have a constraint on the first index column? */ + /* AM 是否要求扫描必须约束第一个索引列? */ bool amoptionalkey; - /* does AM handle ScalarArrayOpExpr quals? */ + /* AM 是否处理 ScalarArrayOpExpr 限定条件? */ bool amsearcharray; - /* does AM handle IS NULL/IS NOT NULL quals? */ + /* AM 是否处理 IS NULL/IS NOT NULL 限定条件? */ bool amsearchnulls; - /* can index storage data type differ from column data type? */ + /* 索引存储数据类型是否可以不同于列数据类型? */ bool amstorage; - /* can an index of this type be clustered on? */ + /* 是否可以按此类型的索引进行聚簇? */ bool amclusterable; - /* does AM handle predicate locks? */ + /* AM 是否处理谓词锁? */ bool ampredlocks; - /* does AM support parallel scan? */ + /* AM 是否支持并行扫描? */ bool amcanparallel; - /* does AM support columns included with clause INCLUDE? */ + /* AM 是否支持由 INCLUDE 子句包含的列? */ bool amcaninclude; - /* type of data stored in index, or InvalidOid if variable */ + /* 索引中存储的数据类型;如果可变,则为 InvalidOid */ Oid amkeytype; - /* interface functions */ + /* 接口函数 */ ambuild_function ambuild; ambuildempty_function ambuildempty; aminsert_function aminsert; ambulkdelete_function ambulkdelete; amvacuumcleanup_function amvacuumcleanup; - amcanreturn_function amcanreturn; /* can be NULL */ + amcanreturn_function amcanreturn; /* 可以为 NULL */ amcostestimate_function amcostestimate; amoptions_function amoptions; - amproperty_function amproperty; /* can be NULL */ + amproperty_function amproperty; /* 可以为 NULL */ amvalidate_function amvalidate; ambeginscan_function ambeginscan; amrescan_function amrescan; - amgettuple_function amgettuple; /* can be NULL */ - amgetbitmap_function amgetbitmap; /* can be NULL */ + amgettuple_function amgettuple; /* 可以为 NULL */ + amgetbitmap_function amgetbitmap; /* 可以为 NULL */ amendscan_function amendscan; - ammarkpos_function ammarkpos; /* can be NULL */ - amrestrpos_function amrestrpos; /* can be NULL */ + ammarkpos_function ammarkpos; /* 可以为 NULL */ + amrestrpos_function amrestrpos; /* 可以为 NULL */ - /* interface functions to support parallel index scans */ - amestimateparallelscan_function amestimateparallelscan; /* can be NULL */ - aminitparallelscan_function aminitparallelscan; /* can be NULL */ - amparallelrescan_function amparallelrescan; /* can be NULL */ + /* 支持并行索引扫描的接口函数 */ + amestimateparallelscan_function amestimateparallelscan; /* 可以为 NULL */ + aminitparallelscan_function aminitparallelscan; /* 可以为 NULL */ + amparallelrescan_function amparallelrescan; /* 可以为 NULL */ } IndexAmRoutine; @@ -169,7 +169,7 @@ ambulkdelete (IndexVacuumInfo *info, IndexBulkDeleteCallback callback, void *callback_state); - 从索引中删除元组。这是一个批量删除操作,通常应通过扫描整个索引并检查每个条目是否应被删除来实现。必须调用传入的 callback 函数,其调用形式为 callback(TID, callback_state) returns bool,以确定由其引用 TID 标识的某个索引条目是否应删除。该函数必须返回 NULL,或者返回一个通过 palloc 分配的结构体,其中包含此次删除操作影响的统计信息。如果不需要向 amvacuumcleanup 传递信息,返回 NULL 也是可以的。 + 从索引中删除元组。这是一个批量删除操作,旨在通过扫描整个索引并检查每个条目是否应被删除来实现。必须调用传入的 callback 函数,其调用形式为 callback(TID, callback_state) returns bool,以确定由其引用 TID 标识的某个索引条目是否应删除。该函数必须返回 NULL,或者返回一个通过 palloc 分配的结构体,其中包含此次删除操作影响的统计信息。如果不需要向 amvacuumcleanup 传递信息,返回 NULL 也是可以的。 @@ -193,8 +193,9 @@ amvacuumcleanup (IndexVacuumInfo *info, bool amcanreturn (Relation indexRelation, int attno); -检查索引是否可以支持仅索引扫描,方法是返回给定列的原始被索引值。属性编号从 1 开始,即第一列的 attno 为 1。支持时返回真,否则返回假。对于包含列(如果支持),此函数应始终返回真,因为无法取回值的包含列没有什么意义。如果访问方法完全不支持仅索引扫描,则其amcanreturn字段在其IndexAmRoutine结构体中可以设为 NULL。 + + 检查索引能否通过返回给定列原始的被索引值,在该列上支持 仅索引扫描。属性编号从 1 开始,也就是说第一列的 attno 为 1。若支持则返回真,否则返回假。如果支持包含列,这个函数应始终对包含列返回真,因为不能取回的包含列几乎没有意义。如果访问方法根本不支持仅索引扫描,那么它的 IndexAmRoutine 结构体中的 amcanreturn 字段可以设为 NULL。 + @@ -207,7 +208,9 @@ amcostestimate (PlannerInfo *root, Selectivity *indexSelectivity, double *indexCorrelation, double *indexPages); -估计一次索引扫描的开销。该函数的完整说明见(见下文)。 + + 估计一次索引扫描的代价。该函数将在后面的 中详细讨论。 + @@ -215,7 +218,7 @@ bytea * amoptions (ArrayType *reloptions, bool validate); - 解析并验证索引的 reloptions 数组。只有当该索引存在非空的 reloptions 数组时才会调用此函数。reloptions 是一个 text 数组,其中的条目形如 name=value。该函数应构造一个 bytea 值,并将其复制到索引 relcache 条目的 rd_options 字段中。这个 bytea 值中的数据内容由访问方法自行定义;大多数标准访问方法使用结构体 StdRdOptions。当 validate 为真时,若存在未识别选项或无效取值,函数应报告合适的错误消息;当 validate 为假时,无效条目应被静默忽略。(当装载已存储在 pg_catalog 中的选项时,validate 为假;此时只有在访问方法改变了选项规则时才可能发现无效条目,而忽略过时条目是合适的。)如果希望采用默认行为,返回 NULL 也是可以的。 + 解析并验证索引的 reloptions 数组。只有当该索引存在非 NULL 的 reloptions 数组时才会调用此函数。reloptions 是一个 text 数组,其中的条目形如 name=value。该函数应构造一个 bytea 值,并将其复制到索引 relcache 条目的 rd_options 字段中。这个 bytea 值中的数据内容由访问方法自行定义;大多数标准访问方法使用结构体 StdRdOptions。当 validate 为真时,若存在未识别选项或无效取值,函数应报告合适的错误消息;当 validate 为假时,无效条目应被静默忽略。(当装载已存储在 pg_catalog 中的选项时,validate 为假;此时只有在访问方法改变了选项规则时才可能发现无效条目,而忽略过时条目是合适的。)如果希望采用默认行为,返回 NULL 也是可以的。 @@ -227,7 +230,7 @@ amproperty (Oid index_oid, int attno, 该amproperty方法允许索引访问方法覆盖pg_index_column_has_property及其相关函数的默认行为。如果访问方法对索引属性查询没有任何特殊行为,那么amproperty字段在其IndexAmRoutine结构体中可以设为 NULL。否则,amproperty方法会收到如下调用参数:index_oidattno均为零,对应pg_indexam_has_property调用;或者index_oid有效且attno为零,对应pg_index_has_property调用;或者index_oid有效且attno大于零,对应pg_index_column_has_property调用。prop是一个枚举值,用来标识当前测试的属性;propname则是原始属性名字符串。如果核心代码不认识该属性名,那么propAMPROP_UNKNOWN。访问方法可以通过检查propname是否匹配来定义自定义属性名(使用pg_strcasecmp进行匹配,以与核心代码保持一致);对于核心代码已知的名称,最好检查prop。如果amproperty方法返回true,则表示它已确定属性测试结果:它必须将*res设为要返回的布尔值,或者把*isnull设为true以返回 NULL。(所引用的两个变量在调用前都初始化为false。)如果amproperty方法返回false,核心代码就会按其正常逻辑确定属性测试结果。 - 支持排序操作符的访问方法应当实现 AMPROP_DISTANCE_ORDERABLE 属性测试,因为核心代码不知道如何完成该测试,只会返回 NULL。若实现成本低于打开索引并调用 amcanreturn(这正是核心代码的默认行为),那么实现 AMPROP_RETURNABLE 测试也可能是有利的。对于其他所有标准属性,默认行为应当已经足够。 + 支持排序操作符的访问方法应当实现 AMPROP_DISTANCE_ORDERABLE 属性测试,因为核心代码不知道如何完成该测试,只会返回 NULL。若完成该测试的代价低于打开索引并调用 amcanreturn(这正是核心代码的默认行为),那么实现 AMPROP_RETURNABLE 测试也可能是有利的。对于其他所有标准属性,默认行为应当已经足够。 @@ -247,7 +250,8 @@ IndexScanDesc ambeginscan (Relation indexRelation, int nkeys, int norderbys); -为索引扫描做准备。nkeysnorderbys参数指明扫描中将使用的限定条件和排序操作符的数量,可用于分配空间。注意,此时尚未提供扫描键的实际值。结果必须是用 palloc 分配的结构体。由于实现方面的原因,索引访问方法必须调用RelationGetIndexScan()来创建此结构体。大多数情况下,ambeginscan除了执行该调用以及可能获取锁之外,几乎不做其他工作;索引扫描启动过程的主要工作位于amrescan。 + + 为一次索引扫描做准备。nkeysnorderbys 参数表示扫描中将使用的限定条件和排序操作符数量,这些信息可能有助于空间分配。请注意,此时还没有提供扫描键的实际值。结果必须是一个通过 palloc 分配的结构体。出于实现上的原因,索引访问方法必须通过调用 RelationGetIndexScan() 来创建这个结构体。大多数情况下,ambeginscan 除了做这次调用以及也许获取一些锁之外,不会做太多工作;索引扫描启动中真正有意思的部分在 amrescan 中。 @@ -267,10 +271,12 @@ amrescan (IndexScanDesc scan, bool amgettuple (IndexScanDesc scan, ScanDirection direction); -沿给定方向(在索引中向前或向后)获取给定扫描中的下一个元组。如果取得元组,则返回 true;如果没有剩余的匹配元组,则返回 false。返回 true 时,将元组 TID 存储到scan结构体中。注意,成功仅表示索引中包含与扫描键匹配的条目,并不表示该元组一定仍存在于堆中,或者能够通过调用方的快照测试。成功时,amgettuple还必须将scan->xs_recheck设为 true 或 false。false 表示可以确定索引条目与扫描键匹配;true 表示尚不确定,在获取堆元组后,必须对它重新检查扫描键所表示的条件。这一规定支持有损索引操作符。注意,重新检查仅针对扫描条件;部分索引谓词(如果有)永远不会由amgettuple的调用方重新检查。 + + 在给定扫描中取出下一个元组,并按给定方向移动(在索引中向前或向后)。若成功取得元组则返回真;若不再有匹配元组则返回假。在返回真时,元组的 TID 会存入 scan 结构体中。请注意,成功仅表示索引中存在一个匹配扫描键的条目,并不表示该元组一定仍然存在于堆中,或者一定能通过调用者的快照测试。成功时,amgettuple 还必须把 scan->xs_recheck 设为真或假。假表示可以确定该索引条目匹配扫描键;真表示这一点并不确定,因此在取到堆元组后必须根据扫描键所代表的条件重新检查它。这一机制支持有损索引操作符。请注意,重检只针对扫描条件;部分索引谓词(如果有)永远不会由 amgettuple 的调用者重新检查。 + - 如果索引支持 仅索引扫描(即其任一列上 amcanreturn 返回真),那么成功时 AM 还必须检查 scan->xs_want_itup;若其为真,就必须返回该索引条目的原始被索引数据。对于 amcanreturn 返回假的列,可以把其值作为 NULL 返回。数据可以通过以下两种形式之一返回:一种是把 IndexTuple 指针存入 scan->xs_itup,其元组描述符为 scan->xs_itupdesc;另一种是把 HeapTuple 指针存入 scan->xs_hitup,其元组描述符为 scan->xs_hitupdesc。(当重建出的数据可能装不进 IndexTuple 时,应使用后一种格式。)无论采用哪种形式,指针所引用数据的管理责任都在访问方法一侧。对这份数据的有效性必须至少保持到该扫描下一次调用 amgettupleamrescanamendscan 为止。 + 如果索引支持 仅索引扫描(即其至少一列上 amcanreturn 返回真),那么成功时 AM 还必须检查 scan->xs_want_itup;若其为真,就必须返回该索引条目的原始被索引数据。对于 amcanreturn 返回假的列,可以把其值作为 NULL 返回。数据可以通过以下两种形式之一返回:一种是把 IndexTuple 指针存入 scan->xs_itup,其元组描述符为 scan->xs_itupdesc;另一种是把 HeapTuple 指针存入 scan->xs_hitup,其元组描述符为 scan->xs_hitupdesc。(当重建出的数据可能装不进 IndexTuple 时,应使用后一种格式。)无论采用哪种形式,指针所引用数据的管理责任都在访问方法一侧。这份数据必须至少保持有效,直到该扫描下一次调用 amgettupleamrescanamendscan @@ -282,7 +288,8 @@ amgettuple (IndexScanDesc scan, int64 amgetbitmap (IndexScanDesc scan, TIDBitmap *tbm); -获取给定扫描中的所有元组,并将其加入调用方提供的TIDBitmap中(即将元组 ID 集合与位图中已有的集合做 OR 运算)。返回获取到的元组数量(可能只是近似值,例如某些访问方法不检测重复项)。向位图插入元组 ID 时,amgetbitmap可以指明需要对特定元组 ID 重新检查扫描条件。这类似于xs_recheck输出参数,它属于amgettuple。注意:在当前实现中,此特性的支持与位图自身有损存储的支持混在一起,因此对于需要重查的元组,调用方会重新检查扫描条件和部分索引谓词(如果有)。但将来未必始终如此。amgetbitmapamgettuple不能在同一次索引扫描中使用;使用amgetbitmap时还有其他限制,详见。 + + 取出给定扫描中的所有元组,并将其加入调用者提供的 TIDBitmap 中(也就是把这组元组 ID 与位图中已有的集合做 OR)。返回值是取得的元组数量(这可能只是近似计数,例如某些 AM 不会检测重复项)。在把元组 ID 插入位图时,amgetbitmap 可以指出某些具体的元组 ID 需要重新检查扫描条件。这类似于 amgettuplexs_recheck 输出参数。注意:在当前实现中,对这一特性的支持与位图自身的有损存储支持混在一起,因此调用者会对需要重检的元组同时重新检查扫描条件和部分索引谓词(如果有)。不过,这并不一定永远如此。amgetbitmapamgettuple 不能在同一次索引扫描中同时使用;使用 amgetbitmap 时还有其他限制,详见 @@ -294,7 +301,7 @@ amgetbitmap (IndexScanDesc scan, void amendscan (IndexScanDesc scan); - 结束一次扫描并释放资源。scan 结构体本身不应被释放,但访问方法内部获取的任何锁或 pin,以及由 ambeginscan 和其他扫描相关函数分配的其他内存,都必须被释放。 + 结束一次扫描并释放资源。scan 结构体本身不应被释放,但必须释放访问方法内部获取的所有锁、解除所有钉住状态,并释放由 ambeginscan 和其他扫描相关函数分配的其他内存。 @@ -411,7 +418,7 @@ amparallelrescan (IndexScanDesc scan); - 除了使用 amgettuple 外,索引扫描也可以使用 amgetbitmap,在一次调用中取出所有元组。与 amgettuple 相比,这通常明显更高效,因为它可以避免访问方法内部的反复加锁和解锁。原则上,amgetbitmap 应具有与重复调用 amgettuple 相同的效果,但为了简化实现,我们施加了若干限制。首先,amgetbitmap 一次性返回全部元组,因此不支持标记或恢复扫描位置。其次,元组是通过一个位图返回的,没有特定顺序,这也是为什么 amgetbitmap 不带 direction 参数的原因。(这种扫描也永远不会提供排序操作符。)此外,使用 amgetbitmap 时也没有仅索引扫描的支持,因为没有办法返回索引元组的内容。最后,amgetbitmap 不保证对返回的元组做任何锁定,其影响见 。 + 除了使用 amgettuple 外,索引扫描也可以使用 amgetbitmap,在一次调用中取出所有元组。与 amgettuple 相比,这可能明显更高效,因为它可以避免访问方法内部的反复加锁和解锁。原则上,amgetbitmap 应具有与重复调用 amgettuple 相同的效果,但为了简化实现,我们施加了若干限制。首先,amgetbitmap 一次性返回全部元组,因此不支持标记或恢复扫描位置。其次,元组是通过一个位图返回的,没有特定顺序,这也是为什么 amgetbitmap 不带 direction 参数的原因。(这种扫描也永远不会提供排序操作符。)此外,使用 amgetbitmap 时也没有仅索引扫描的支持,因为没有办法返回索引元组的内容。最后,amgetbitmap 不保证对返回的元组做任何锁定,其影响见 @@ -428,7 +435,7 @@ amparallelrescan (IndexScanDesc scan); - 构建一种支持并发更新的索引类型,通常需要对所需行为进行大量而细致的分析。对于 B-树和哈希索引类型,可以阅读 src/backend/access/nbtree/READMEsrc/backend/access/hash/README 中涉及的设计决策。 + 构建一种支持并发更新的索引类型,通常需要对所需行为进行大量而细致的分析。对于 B-树和 hash 索引类型,可以阅读 src/backend/access/nbtree/READMEsrc/backend/access/hash/README 中涉及的设计决策。 @@ -447,12 +454,12 @@ amparallelrescan (IndexScanDesc scan); - 索引扫描必须在保存 amgettuple 最近一次返回条目的索引页面上维护一个 pin,而 ambulkdelete 不能从被其他后端钉住的页面中删除条目。下面会解释为什么需要这条规则。 + 索引扫描必须在保存 amgettuple 最近一次返回条目的索引页面上保持钉住状态,而 ambulkdelete 不能从被其他后端钉住的页面中删除条目。下面会解释为什么需要这条规则。 - 如果没有第三条规则,索引读取者就有可能在某个索引条目被 VACUUM 删除之前先看到它,然后在对应的堆条目已被 VACUUM 删除之后才到达那里。如果读取者到达时,该项号仍未被重新使用,就不会造成严重问题,因为空项槽位会被 heap_fetch() 忽略。但如果第三个后端已经把这个项槽位重新用作别的东西呢?在使用 MVCC 兼容快照时不会有问题,因为该槽位的新占用者一定太新,无法通过快照测试。然而,对于非 MVCC 兼容的快照(例如 SnapshotAny),就可能错误地接受并返回一行实际上并不匹配扫描键的数据。我们可以要求在所有情况下都对堆行重新检查扫描键,以防范这种情形,但那样代价太高。于是,我们改为把索引页面上的 pin 作为一种代理,表示读取者可能仍处于从索引条目前往匹配堆条目的飞行中。让 ambulkdelete 在这种 pin 上阻塞,能够保证 VACUUM 不会在读取者处理完之前删除对应的堆条目。这种方案运行时开销很小,只有在真正发生冲突的少数情况下才会增加阻塞开销。 + 如果没有第三条规则,索引读取者就有可能在某个索引条目被 VACUUM 删除之前先看到它,然后在对应的堆条目已被 VACUUM 删除之后才到达那里。如果读取者到达时,该项号仍未被重新使用,就不会造成严重问题,因为空项槽位会被 heap_fetch() 忽略。但如果第三个后端已经把这个项槽位重新用作别的东西呢?在使用 MVCC 兼容快照时不会有问题,因为该槽位的新占用者一定太新,无法通过快照测试。然而,对于非 MVCC 兼容的快照(例如 SnapshotAny),就可能错误地接受并返回一行实际上并不匹配扫描键的数据。我们可以要求在所有情况下都对堆行重新检查扫描键,以防范这种情形,但那样代价太高。于是,我们改为把索引页面的钉住状态作为一种代理,表示读取者从索引条目到匹配堆条目的访问过程可能仍在进行中。让 ambulkdelete 因这种钉住状态而阻塞,能够保证 VACUUM 不会在读取者处理完之前删除对应的堆条目。这种方案运行时开销很小,只有在真正发生冲突的少数情况下才会增加阻塞开销。 @@ -460,7 +467,7 @@ amparallelrescan (IndexScanDesc scan); - 在 amgetbitmap 索引扫描中,访问方法不会在任何返回的元组上保留索引 pin。因此,只有把这种扫描与 MVCC 兼容的快照一起使用才是安全的。 + 在 amgetbitmap 索引扫描中,访问方法不会为任何返回的元组保持索引页面的钉住状态。因此,只有把这种扫描与 MVCC 兼容的快照一起使用才是安全的。 @@ -499,14 +506,17 @@ amparallelrescan (IndexScanDesc scan); - 此外,在按照上述规则报告唯一性违背之前,访问方法必须立即重新检查正在插入那一行的存活性。如果它已经是提交后死亡的状态,就不应报告违背。(这种情况不会出现在插入由当前事务刚创建的行这一普通场景中,但在 CREATE UNIQUE INDEX CONCURRENTLY 期间却可能发生。) + 此外,就在按照上述规则报告唯一性违背之前,访问方法必须重新检查正在插入那一行的存活性。如果它已经是提交后死亡的状态,就不应报告违背。(这种情况不会出现在插入由当前事务刚创建的行这一普通场景中,但在 CREATE UNIQUE INDEX CONCURRENTLY 期间却可能发生。) 我们要求索引访问方法自行应用这些测试,这意味着它必须深入堆中检查那些根据索引内容显示为具有重复键的行的提交状态。毫无疑问,这样做既丑陋又不够模块化,但它避免了重复工作:如果我们单独再做一次探测,那么在寻找新行索引条目插入位置时,查找冲突行的索引搜索实际上就会被重复执行。更何况,除非把冲突检查作为插入新索引条目动作的一个组成部分,否则也没有明显的方法可以避免竞争条件。 - 如果唯一约束可延迟,处理就更复杂:需要能够为新行插入索引条目,同时将唯一性冲突错误延迟到语句结束时甚至更晚。为避免不必要地重复搜索索引,索引访问方法应在首次插入时进行初步唯一性检查。如果确定不存在冲突的存活元组,就已完成检查。否则,应在需要强制执行约束时安排重新检查。如果重新检查时,插入的元组和某个具有相同键的其他元组都仍存活,就必须报告错误。(注意,在此场景中,存活实际表示索引条目 HOT 链中的任一元组是存活的。)为实现这一点,会向aminsert函数传入一个checkUnique参数,其值为以下之一: + + 如果唯一约束是可延迟的,情况会更复杂:我们需要能够为新行插入一个索引条目,但把任何唯一性违背错误延迟到语句结束时甚至更晚才报告。为了避免对索引进行不必要的重复搜索,索引访问方法应在初始插入期间执行一次初步唯一性检查。如果这表明确实不存在冲突的存活元组,那么事情就结束了。否则,我们会安排在真正强制约束时再做一次重检。若在重检时,插入的元组与另外某个具有相同键值的元组都仍然存活,就必须报告错误。(注意,就此用途而言,存活实际上是指索引条目 HOT 链中至少有一个元组是存活的。)为实现这一点,传给 aminsert 函数的 checkUnique 参数会取以下值之一: + + UNIQUE_CHECK_NO 表示不应执行唯一性检查(这不是唯一索引)。 @@ -541,10 +551,10 @@ amparallelrescan (IndexScanDesc scan); - 索引开销估计函数 + 索引代价估算函数 - amcostestimate 函数会收到描述某种可能索引扫描方式的信息,其中包括已经确定可用于该索引的 WHERE 子句和 ORDER BY 子句列表。它必须返回访问该索引的开销估计,以及 WHERE 子句的选择率(也就是在索引扫描期间将从父表中检索出的行所占比例)。对于简单情况,开销估计器几乎所有工作都可以通过调用优化器中的标准例程来完成;之所以提供 amcostestimate 函数,是为了让索引访问方法能够提供与索引类型有关的专门知识,以便在可能时改进标准估计。 + amcostestimate 函数会收到描述某种可能索引扫描方式的信息,其中包括已经确定可用于该索引的 WHERE 子句和 ORDER BY 子句列表。它必须返回访问该索引的代价估算,以及 WHERE 子句选择率的估计值(也就是在索引扫描期间将从父表中检索出的行所占比例)。对于简单情况,代价估算器几乎所有工作都可以通过调用优化器中的标准例程来完成;之所以提供 amcostestimate 函数,是为了让索引访问方法能够提供与索引类型有关的专门知识,以便在可能时改进标准估计。 @@ -578,7 +588,7 @@ amcostestimate (PlannerInfo *root, path - 当前正在考虑的索引访问路径。除开销和选择率字段外,其余字段都有效。 + 当前正在考虑的索引访问路径。除代价和选择率字段外,其余字段都有效。 @@ -587,7 +597,7 @@ amcostestimate (PlannerInfo *root, loop_count - 在开销估计中应计入的索引扫描重复次数。当考虑在嵌套循环连接内部使用参数化扫描时,这个参数通常会大于 1。请注意,开销估计仍应只针对一次扫描;更大的 loop_count 只表示可以适当考虑多次扫描之间的一些缓存效应。 + 在代价估算中应计入的索引扫描重复次数。当考虑在嵌套循环连接内部使用参数化扫描时,这个参数通常会大于 1。请注意,代价估算仍应只针对一次扫描;更大的 loop_count 只表示可以适当考虑多次扫描之间的一些缓存效应。 @@ -602,7 +612,7 @@ amcostestimate (PlannerInfo *root, *indexStartupCost - 设为索引启动处理的开销。 + 设为索引启动处理的代价。 @@ -611,7 +621,7 @@ amcostestimate (PlannerInfo *root, *indexTotalCost - 设为索引处理的总开销。 + 设为索引处理的总代价。 @@ -646,19 +656,19 @@ amcostestimate (PlannerInfo *root, - 请注意,开销估计函数必须用 C 编写,而不能用 SQL 或任何可用的过程语言,因为它们必须访问规划器/优化器的内部数据结构。 + 请注意,代价估算函数必须用 C 编写,而不能用 SQL 或任何可用的过程语言,因为它们必须访问规划器/优化器的内部数据结构。 - 索引访问开销应使用 src/backend/optimizer/path/costsize.c 所采用的参数来计算:顺序磁盘块读取的开销为 seq_page_cost,非顺序读取的开销为 random_page_cost,处理一条索引行的开销通常应取为 cpu_index_tuple_cost。此外,在索引处理期间调用的任何比较操作符(特别是对 indexquals 本身的求值)都应计入适当倍数的 cpu_operator_cost。 + 索引访问代价应使用 src/backend/optimizer/path/costsize.c 所采用的参数来计算:顺序磁盘块读取的代价为 seq_page_cost,非顺序读取的代价为 random_page_cost,处理一条索引行的代价通常应取为 cpu_index_tuple_cost。此外,在索引处理期间调用的任何比较操作符(特别是对 indexquals 本身的求值)都应计入适当倍数的 cpu_operator_cost - 访问开销应包括与扫描索引本身有关的全部磁盘和 CPU 开销,但包括取出或处理由索引标识出的父表行的开销。 + 访问代价应包括与扫描索引本身有关的全部磁盘和 CPU 代价,但包括取出或处理由索引标识出的父表行的代价。 - 启动开销是整个扫描总开销中必须在开始取第一行之前先付出的那一部分。对大多数索引来说,这可以视为零;但启动开销较高的索引类型可能希望把它设为非零。 + 启动代价是整个扫描总代价中必须在开始取第一行之前先付出的那一部分。对大多数索引来说,这可以视为零;但启动代价较高的索引类型可能希望把它设为非零。 @@ -666,7 +676,7 @@ amcostestimate (PlannerInfo *root, - indexCorrelation 应设为索引顺序与表顺序之间的相关性(范围从 -1.0 到 1.0)。该值用于调整从父表取行开销的估计。 + indexCorrelation 应设为索引顺序与表顺序之间的相关性(范围从 -1.0 到 1.0)。该值用于调整从父表取行代价的估计。 @@ -678,9 +688,9 @@ amcostestimate (PlannerInfo *root, - 开销估计 + 代价估算 - 一个典型的开销估计器会按如下步骤进行: + 一个典型的代价估算器会按如下步骤进行: @@ -709,14 +719,14 @@ amcostestimate (PlannerInfo *root, - 计算索引访问开销。一个通用估计器可能会这样做: + 计算索引访问代价。一个通用估计器可能会这样做: /* - * Our generic assumption is that the index pages will be read - * sequentially, so they cost seq_page_cost each, not random_page_cost. - * Also, we charge for evaluation of the indexquals at each index row. - * All the costs are assumed to be paid incrementally during the scan. + * 通用假设是索引页面将按顺序读取, + * 因此每页代价为 seq_page_cost,而非 random_page_cost。 + * 此外,还要计入在每个索引行上对 indexquals 求值的代价。 + * 假定所有代价都在扫描过程中逐步付出。 */ cost_qual_eval(&index_qual_cost, path->indexquals, root); *indexStartupCost = index_qual_cost.startup; @@ -736,7 +746,7 @@ cost_qual_eval(&index_qual_cost, path->indexquals, root); - 开销估计器函数的示例可在 src/backend/utils/adt/selfuncs.c 中找到。 + 代价估算器函数的示例可在 src/backend/utils/adt/selfuncs.c 中找到。 diff --git a/zh/11/indices.sgml b/zh/11/indices.sgml index 38f93ea5..02b50e47 100644 --- a/zh/11/indices.sgml +++ b/zh/11/indices.sgml @@ -31,7 +31,7 @@ SELECT content FROM test1 WHERE id = constant; - 大多数非小说类书籍也采用了类似的方法:读者经常查找的术语和概念会被收集到书末按字母顺序排列的索引中。感兴趣的读者可以相对快速地浏览索引并翻到相应页面,而不必通读整本书才能找到自己感兴趣的内容。正如作者需要预判读者可能查找哪些条目一样,数据库程序员也需要预见哪些索引会有用。 + 大多数非虚构类书籍也采用了类似的方法:读者经常查找的术语和概念会被收集到书末按字母顺序排列的索引中。感兴趣的读者可以相对快速地浏览索引并翻到相应页面,而不必通读整本书才能找到自己感兴趣的内容。正如作者需要预判读者可能查找哪些条目一样,数据库程序员也需要预见哪些索引会有用。 @@ -68,7 +68,7 @@ CREATE INDEX test1_id_index ON test1 (id); 索引类型 - PostgreSQL提供了多种索引类型:B-树、哈希、GiST、SP-GiST、GIN、BRIN,以及扩展bloom。每种索引类型都采用不同的算法,分别最适合不同类型的查询。默认情况下,CREATE INDEX命令创建的是 B-树索引,它适用于最常见的场景。 + PostgreSQL提供了多种索引类型:B-树、Hash、GiST、SP-GiST、GIN、BRIN,以及扩展bloom。每种索引类型都采用不同的算法,分别最适合不同类型的查询。默认情况下,CREATE INDEX命令创建的是 B-树索引,它适用于最常见的场景。 索引 B-树 B-树 索引 B-树能够处理可以按某种顺序排序的数据上的等值查询和范围查询。特别是,只要已索引列参与了下列任一操作符的比较,PostgreSQL查询规划器就会考虑使用 B-树索引: @@ -91,12 +91,12 @@ CREATE INDEX test1_id_index ON test1 (id); 索引 - 哈希 + hash - 哈希 + hash 索引 - 哈希索引只能处理简单的等值比较。只要已索引列参与的是使用=操作符的比较,查询规划器就会考虑使用哈希索引。使用以下命令创建哈希索引: + Hash 索引只能处理简单的等值比较。只要已索引列参与的是使用=操作符的比较,查询规划器就会考虑使用 Hash 索引。使用以下命令创建 Hash 索引: CREATE INDEX name ON table USING HASH (column); @@ -115,7 +115,7 @@ CREATE INDEX name ON table SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10; ]]> - 这会找出距离给定目标点最近的十个地点。是否能做到这一点,同样取决于所使用的具体操作符类。在中,可以按这种方式使用的操作符列在Ordering Operators这一列中。 + 这会找出距离给定目标点最近的十个地点。是否能做到这一点,同样取决于所使用的具体操作符类。在中,可以按这种方式使用的操作符列在排序操作符这一列中。 索引 SP-GiST SP-GiST 索引 @@ -152,8 +152,8 @@ SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10; 多列索引 - index - multicolumn + 索引 + 多列 @@ -184,15 +184,15 @@ CREATE INDEX test2_mm_idx ON test2 (major, minor); - 多列 GIN 索引可以用于涉及索引任意列子集的查询条件。与 B-树或 GiST 不同,无论查询条件使用的是哪一列索引列,GIN 的索引搜索效果都一样。 + 多列 GIN 索引可以用于涉及索引任意列子集的查询条件。与 B-树或 GiST 不同,无论查询条件使用的是哪些索引列,GIN 的索引搜索效果都一样。 - 多列 BRIN 索引可以用于涉及索引任意列子集的查询条件。和 GIN 一样、不同于 B-树或 GiST,无论查询条件使用的是哪一列索引列,索引搜索效果都一样。在单个表上使用多个 BRIN 索引,而不是使用一个多列 BRIN 索引的唯一理由,是需要不同的pages_per_range存储参数。 + 多列 BRIN 索引可以用于涉及索引任意列子集的查询条件。和 GIN 一样、不同于 B-树或 GiST,无论查询条件使用的是哪些索引列,索引搜索效果都一样。在单个表上使用多个 BRIN 索引,而不是使用一个多列 BRIN 索引的唯一理由,是需要不同的pages_per_range存储参数。 - 多列 GIN 索引可以用于涉及索引任意列子集的查询条件。与 B-树或 GiST 不同,无论查询条件使用的是哪一列索引列,GIN 的索引搜索效果都一样。 + 当然,每一列都必须配合适合该索引类型的操作符使用;涉及其他操作符的子句不会被考虑。 @@ -205,8 +205,8 @@ CREATE INDEX test2_mm_idx ON test2 (major, minor); 索引和<literal>ORDER BY</literal> - index - and ORDER BY + 索引 + ORDER BY @@ -214,7 +214,7 @@ CREATE INDEX test2_mm_idx ON test2 (major, minor); - 规划器在满足ORDER BY要求时,会考虑两种方案:扫描一个与该要求匹配的可用索引,或者按物理顺序扫描表再显式排序。对于需要扫描表中很大一部分内容的查询,显式排序通常会比使用索引更快,因为它遵循顺序访问模式,需要的磁盘 I/O 更少。只有在只需取出少量行时,索引才更有价值。一个重要的特例是ORDER BYLIMIT n组合使用:显式排序必须处理所有数据才能找出最前面的n行,而如果有一个与ORDER BY匹配的索引,就可以直接取回前n行,而完全不必扫描剩余数据。 + 规划器在满足ORDER BY要求时,会考虑两种方案:扫描一个与该要求匹配的可用索引,或者按物理顺序扫描表再显式排序。对于需要扫描表中很大一部分内容的查询,显式排序通常会比使用索引更快,因为它遵循顺序访问模式,需要的磁盘 I/O 更少。只需取出少量行时,索引更有价值。一个重要的特例是ORDER BYLIMIT n组合使用:显式排序必须处理所有数据才能找出最前面的n行,而如果有一个与ORDER BY匹配的索引,就可以直接取回前n行,而完全不必扫描剩余数据。 @@ -244,12 +244,12 @@ CREATE INDEX test3_desc_index ON test3 (id DESC NULLS LAST); 组合多个索引 - index - combining multiple indexes + 索引 + 组合多个索引 - bitmap scan + 位图扫描 @@ -276,8 +276,8 @@ CREATE INDEX test3_desc_index ON test3 (id DESC NULLS LAST); 唯一索引 - index - unique + 索引 + 唯一 @@ -308,8 +308,8 @@ CREATE UNIQUE INDEX name ON table表达式索引 - index - on expressions + 索引 + 基于表达式 @@ -356,8 +356,8 @@ CREATE INDEX people_names ON people ((first_name || ' ' || last_name)); 部分索引 - index - partial + 索引 + 部分 @@ -365,7 +365,7 @@ CREATE INDEX people_names ON people ((first_name || ' ' || last_name)); - 使用部分索引的一个主要原因是避免索引常见值。由于搜索常见值的查询(即占全部表行百分之几以上的值)反正也不会使用索引,因此完全没有必要把这些行保留在索引里。这会减小索引尺寸,从而加快那些确实会使用该索引的查询。它也会加快很多表更新操作,因为索引并不需要在所有情况下都更新。展示了这种思路的一种可能应用。 + 使用部分索引的一个主要原因是避免索引常见值。由于搜索常见值(即占全部表行百分之几以上的值)的查询反正也不会使用索引,因此完全没有必要把这些行保留在索引里。这会减小索引尺寸,从而加快那些确实会使用该索引的查询。它也会加快很多表更新操作,因为索引并不需要在所有情况下都更新。展示了这种思路的一种可能应用。 @@ -449,7 +449,7 @@ SELECT * FROM orders WHERE order_nr = 3501; - 也说明了:索引列和谓词中使用的列不必一致。PostgreSQL支持带任意谓词的部分索引,只要其中只涉及正在建立索引的那张表的列。不过要记住,谓词必须与那些希望从该索引受益的查询中使用的条件相匹配。更准确地说,只有当系统能够识别出查询的WHERE条件在数学上蕴含该索引的谓词时,部分索引才能用于该查询。PostgreSQL并没有一个复杂的定理证明器,来识别那些写法不同但数学上等价的表达式。(不仅构建这样一个通用定理证明器极其困难,而且它很可能也会慢到失去实际用途。)系统可以识别简单的不等式蕴含,例如x < 1蕴含x < 2;否则,谓词条件必须与查询WHERE条件的某一部分完全匹配,否则索引不会被识别为可用。匹配发生在查询规划阶段,而不是运行时。因此,参数化查询子句无法与部分索引配合工作。例如,一个带参数的预备查询可能写成x < ?,而对于参数的所有可能取值,它都不可能蕴含x < 2。 + 也说明了:索引列和谓词中使用的列不必一致。PostgreSQL支持带任意谓词的部分索引,只要其中只涉及正在建立索引的那张表的列。不过要记住,谓词必须与那些希望从该索引受益的查询中使用的条件相匹配。更准确地说,只有当系统能够识别出查询的WHERE条件在数学上蕴含该索引的谓词时,部分索引才能用于该查询。PostgreSQL并没有一个复杂的定理证明器,来识别那些写法不同但数学上等价的表达式。(不仅构建这样一个通用定理证明器极其困难,而且它很可能也会慢到失去实际用途。)系统可以识别简单的不等式蕴含,例如x < 1蕴含x < 2;否则,谓词条件必须与查询WHERE条件的某一部分完全匹配,否则索引不会被识别为可用。匹配发生在查询规划阶段,而不是运行时。因此,参数化查询子句无法与部分索引配合工作。例如,一个带参数的预备查询可能写成x < ?,而它无法保证在参数的所有可能取值下都蕴含x < 2 @@ -460,7 +460,9 @@ SELECT * FROM orders WHERE order_nr = 3501; 建立一个部分唯一索引 - 假设有一个记录测试结果的表。我们希望确保每个给定的测试对象和目标组合只有一个成功条目,但可以有任意数量的失败条目。下面是一种实现方法: + + 假设我们有一张描述测试结果的表。我们希望确保对于给定的测试对象和目标组合,只有一条成功记录,但可以有任意多条失败记录。实现方法之一如下: + CREATE TABLE tests ( subject text, target text, @@ -470,7 +472,9 @@ CREATE TABLE tests ( CREATE UNIQUE INDEX tests_success_constraint ON tests (subject, target) WHERE success; -在成功测试很少而失败测试很多时,这种方法尤其高效。也可以创建一个带有IS NULL限制的唯一部分索引,从而只允许列中出现一个空值。 + + 当成功测试很少而失败测试很多时,这是一种特别高效的方法。也可以通过创建一个带IS NULL限制的唯一部分索引,来让某一列只允许出现一个空值。 + @@ -541,7 +545,10 @@ CREATE INDEX mytable_cat_data ON mytable (category, data); PostgreSQL中的所有索引都是二级索引,也就是说,每个索引都与表的主数据区分开存储(在PostgreSQL术语中,这个主数据区称为表的)。这意味着,在普通索引扫描中,每次取回一行都需要同时从索引和堆中取数据。此外,尽管满足某个可索引WHERE条件的索引项通常在索引中彼此接近,但它们引用的表行却可能分布在堆中的任何位置。因此,索引扫描的堆访问部分会涉及大量对堆的随机访问,这可能很慢,尤其是在传统旋转介质上。(正如中所述,位图扫描试图通过按排序顺序进行堆访问来缓解这项代价,但那也只能缓解到一定程度。) - 为了解决这一性能问题,PostgreSQL支持仅索引扫描,仅通过索引就能完成查询,无需访问堆。其基本思路是直接从各个索引项返回值,而不访问相关联的堆项。使用这种方法有两个基本限制: + + 为了解决这个性能问题,PostgreSQL支持仅索引扫描,它可以仅凭索引而不访问堆来回答查询。基本思路是直接从每个索引项中返回值,而不是再去查对应的堆项。要使用这种方法,有两个根本限制: + + 索引类型必须支持仅索引扫描。B-树索引总是支持。GiST 和 SP-GiST 索引对某些操作符类支持仅索引扫描,但对另一些则不支持。其他索引类型则完全不支持。底层要求是,索引必须实际存储原始数据值,或者至少能够重建出每个索引项对应的原始数据值。反例是 GIN 索引,它不能支持仅索引扫描,因为每个索引项通常只保存原始数据值的一部分。 @@ -549,13 +556,19 @@ CREATE INDEX mytable_cat_data ON mytable (category, data); - 查询只能引用存储在索引中的列。例如,假设某个表的xy列上有一个索引,且该表还有一列z,那么以下查询可以使用仅索引扫描: + + 查询只能引用存储在索引中的列。例如,假设某个表的xy列上有一个索引,且该表还有一列z,那么下面这些查询可以使用仅索引扫描: + SELECT x, y FROM tab WHERE x = 'key'; SELECT x FROM tab WHERE x = 'key' AND y < 42; -但以下查询不能: + + 但下面这些查询则不能: + SELECT x, z FROM tab WHERE x = 'key'; SELECT x FROM tab WHERE x = 'key' AND z < 42; -(表达式索引和部分索引会使这条规则更复杂,下文将作讨论。) + + (表达式索引和部分索引会让这条规则变得更复杂,下文会讨论。) + @@ -572,15 +585,25 @@ SELECT x FROM tab WHERE x = 'key' AND z < 42; INCLUDE 在索引定义中 - 为了有效利用仅索引扫描,可以创建一个覆盖索引,即专门包含某类常用查询所需列的索引。由于查询通常需要取出的列比搜索条件涉及的列更多,PostgreSQL允许创建这样的索引:其中一些列仅用作负载,并非搜索键的一部分。为此,需要添加一个INCLUDE子句,列出这些额外列。例如,如果经常执行如下查询: + + 为了有效利用仅索引扫描特性,你可以选择创建一个覆盖索引,也就是专门设计来包含某一类高频查询所需列的索引。由于查询通常需要取回的列不止是用于搜索的那些列,PostgreSQL允许你创建一种索引,其中某些列只是负载,而不是搜索键的一部分。这是通过添加一个INCLUDE子句列出这些额外列来实现的。例如,如果你经常运行如下查询: + SELECT y FROM tab WHERE x = 'key'; -加快此类查询的传统做法,是仅在以下列上创建索引:x。但是,定义如下的索引: + + 传统上,为了加速这类查询,通常会只在x上创建一个索引。但如果将索引定义为: + CREATE INDEX tab_x_y ON tab(x) INCLUDE (y); -可以通过仅索引扫描处理这些查询,因为y可以直接从索引中取得,无需访问堆。 + + 那么这些查询就可以以仅索引扫描的方式完成,因为y可以直接从索引中取得,而不必访问堆。 + - 由于列y并非索引搜索键的一部分,其数据类型不必是索引能够处理的类型;该列只是存储在索引中,索引机制不会解释它。另外,如果该索引是唯一索引,也就是: + + 由于列y不是索引搜索键的一部分,因此它不必属于该索引能够处理的数据类型;它只是被存储在索引中,而不会被索引机制解释。此外,如果该索引是唯一索引,即 + CREATE UNIQUE INDEX tab_x_y ON tab(x) INCLUDE (y); -那么唯一性条件只应用于列x,而不应用于xy的组合。(INCLUDE子句也可以写在UNIQUEPRIMARY KEY约束中,为建立这样的索引提供另一种语法。) + + 那么唯一性条件只作用于列x,而不作用于xy的组合。(INCLUDE子句也可以写在UNIQUEPRIMARY KEY约束中,作为建立这种索引的另一种语法。) + 向索引中添加非键负载列时,明智的做法是保持保守,尤其是宽列。如果某个索引元组超过该索引类型允许的最大尺寸,数据插入就会失败。无论如何,非键列都会复制索引对应表中的数据并让索引膨胀,因此可能拖慢搜索。另外请记住,除非表变化足够缓慢,以至于仅索引扫描很可能无需访问堆,否则把负载列包含在索引中并没有太大意义。如果反正必须访问堆元组,那么顺便从那里取出该列的值也不会增加额外代价。其他限制包括:当前不支持把表达式作为包含列;并且当前只有 B-树 索引支持包含列。 @@ -621,11 +644,11 @@ SELECT target FROM tests WHERE subject = 'some-subject' AND success; 操作符类和操作符族 - operator class + 操作符类 - operator family + 操作符族 索引定义可以为索引的每一列指定一个操作符类 @@ -735,8 +758,8 @@ CREATE INDEX test1c_content_y_index ON test1c (content COLLATE "y"); 检查索引使用情况 - index - examining usage + 索引 + 检查使用情况 diff --git a/zh/11/information_schema.sgml b/zh/11/information_schema.sgml index cbb3a91c..66b358dd 100644 --- a/zh/11/information_schema.sgml +++ b/zh/11/information_schema.sgml @@ -105,7 +105,7 @@ - Name + 名称 数据类型 描述 @@ -139,7 +139,7 @@ - Name + 名称 数据类型 描述 @@ -191,7 +191,7 @@ - Name + 名称 数据类型 描述 @@ -241,7 +241,7 @@ - Name + 名称 数据类型 描述 @@ -361,7 +361,7 @@ collation_catalog sql_identifier - 包含此属性排序规则的数据库名(总是当前数据库),如果默认或者该属性的数据类型不可排序则为空 + 包含该属性排序规则的数据库名称(总是当前数据库);如果使用默认排序规则,或该属性的数据类型不支持排序规则,则为 null。 @@ -369,7 +369,7 @@ collation_schema sql_identifier - 包含此属性排序规则的模式名,如果默认或者该属性的数据类型不可排序则为空 + 包含该属性排序规则的模式名称;如果使用默认排序规则,或该属性的数据类型不支持排序规则,则为 null。 @@ -377,7 +377,7 @@ collation_name sql_identifier - 该属性排序规则的名称,如果默认或者该属性的数据类型不可排序则为空 + 该属性排序规则的名称;如果使用默认排序规则,或该属性的数据类型不支持排序规则,则为 null。 @@ -564,7 +564,7 @@ - Name + 名称 数据类型 描述 @@ -655,7 +655,7 @@ - Name + 名称 数据类型 描述 @@ -729,7 +729,7 @@ - Name + 名称 数据类型 描述 @@ -787,7 +787,7 @@ - Name + 名称 数据类型 描述 @@ -845,7 +845,7 @@ - Name + 名称 数据类型 描述 @@ -919,7 +919,7 @@ - Name + 名称 数据类型 描述 @@ -1001,7 +1001,7 @@ - Name + 名称 数据类型 描述 @@ -1081,7 +1081,7 @@ - Name + 名称 数据类型 描述 @@ -1171,7 +1171,7 @@ - Name + 名称 数据类型 描述 @@ -1253,7 +1253,7 @@ - Name + 名称 数据类型 描述 @@ -1426,7 +1426,7 @@ collation_catalog sql_identifier - 包含此属性排序规则的数据库名(总是当前数据库),如果默认或者该属性的数据类型不可排序则为空 + 包含该列排序规则的数据库名称(总是当前数据库);如果使用默认排序规则,或该列的数据类型不支持排序规则,则为 null。 @@ -1434,7 +1434,7 @@ collation_schema sql_identifier - 该列的包含排序规则的模式名,如果默认或者该列的数据类型不可排序则为空 + 包含该列排序规则的模式名称;如果使用默认排序规则,或该列的数据类型不支持排序规则,则为 null。 @@ -1442,7 +1442,7 @@ collation_name sql_identifier - 该列的排序规则的名称,如果默认或者该列的数据类型不可排序则为空 + 该列排序规则的名称;如果使用默认排序规则,或该列的数据类型不支持排序规则,则为 null。 @@ -1645,7 +1645,7 @@ - Name + 名称 数据类型 描述 @@ -1727,7 +1727,7 @@ - Name + 名称 数据类型 描述 @@ -1801,7 +1801,7 @@ - Name + 名称 数据类型 描述 @@ -1867,7 +1867,7 @@ - Name + 名称 数据类型 描述 @@ -1957,7 +1957,7 @@ - Name + 名称 数据类型 描述 @@ -2032,7 +2032,7 @@ - Name + 名称 数据类型 描述 @@ -2119,7 +2119,7 @@ collation_catalog sql_identifier - 包含此域排序规则的数据库名(总是当前数据库),如果默认或者该域的数据类型不可排序则为空 + 包含该域排序规则的数据库名称(总是当前数据库);如果使用默认排序规则,或该域的数据类型不支持排序规则,则为 null。 @@ -2127,7 +2127,7 @@ collation_schema sql_identifier - 包含此域排序规则的模式名,如果默认或者该域的数据类型不可排序则为空 + 包含该域排序规则的模式名称;如果使用默认排序规则,或该域的数据类型不支持排序规则,则为 null。 @@ -2135,7 +2135,7 @@ collation_name sql_identifier - 该域排序规则的名称,如果默认或者该域的数据类型不可排序则为空 + 该域排序规则的名称;如果使用默认排序规则,或该域的数据类型不支持排序规则,则为 null。 @@ -2275,7 +2275,7 @@ <literal>element_types</literal> - 视图element_types包含数组元素的数据类型描述符。当一个表列、复合类型属性、域、函数参数或函数返回值被定义为一种数组类型,相应的信息模式视图只在列data_type中包含ARRAY。要获得该数组元素类型的信息,你可以连接该相应的视图和这个视图。例如,要显示一个表的列及其数据类型和数组元素类型,你可以: + 视图element_types包含数组元素的数据类型描述符。当一个表列、复合类型属性、域、函数参数或函数返回值被定义为一种数组类型时,相应的信息模式视图只在列data_type中包含ARRAY。要获得该数组元素类型的信息,你可以连接该相应的视图和这个视图。例如,要显示一个表的列及其数据类型和数组元素类型(如果适用),你可以: SELECT c.column_name, c.data_type, e.data_type AS element_type FROM information_schema.columns c LEFT JOIN information_schema.element_types e @@ -2293,7 +2293,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -2394,7 +2394,7 @@ ORDER BY c.ordinal_position; collation_catalog sql_identifier - 包含元素类型排序规则的数据库名称(总是当前数据库), 如果默认或该元素的数据类型是不可排序的则为空 + 包含该元素类型排序规则的数据库名称(总是当前数据库);如果使用默认排序规则,或该元素类型不支持排序规则,则为 null。 @@ -2402,7 +2402,7 @@ ORDER BY c.ordinal_position; collation_schema sql_identifier - 包含元素类型排序规则的模式名称, 如果默认或该元素的数据类型是不可排序的则为空 + 包含该元素类型排序规则的模式名称;如果使用默认排序规则,或该元素类型不支持排序规则,则为 null。 @@ -2410,7 +2410,7 @@ ORDER BY c.ordinal_position; collation_name sql_identifier - 元素类型的排序规则名, 如果默认或该元素的数据类型是不可排序的则为空 + 该元素类型排序规则的名称;如果使用默认排序规则,或该元素类型不支持排序规则,则为 null。 @@ -2465,9 +2465,7 @@ ORDER BY c.ordinal_position; domain_default character_data - - 元素的数据类型所在的数据库名称(总是当前数据库) - + 尚未实现 @@ -2557,7 +2555,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -2591,7 +2589,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -2649,7 +2647,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -2715,7 +2713,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -2773,7 +2771,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -2855,7 +2853,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -2921,7 +2919,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -2987,7 +2985,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -3085,7 +3083,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -3369,7 +3367,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -3470,7 +3468,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -3560,7 +3558,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -3666,7 +3664,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -3760,7 +3758,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -3842,7 +3840,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -3932,7 +3930,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -4038,7 +4036,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -4728,7 +4726,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -4810,7 +4808,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -4938,7 +4936,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -5020,7 +5018,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -5086,7 +5084,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -5152,7 +5150,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -5210,7 +5208,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -5276,7 +5274,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -5332,7 +5330,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -5392,7 +5390,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -5495,7 +5493,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -5589,7 +5587,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -5713,7 +5711,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -5805,7 +5803,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -5887,7 +5885,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -6077,7 +6075,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -6167,7 +6165,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -6252,7 +6250,7 @@ ORDER BY c.ordinal_position; - SQL 了解两种用户定义类型:结构类型(在PostgreSQL中也称为复合类型)以及 distinct 类型(PostgreSQL 尚未实现)。为兼顾将来,请使用列user_defined_type_category来区分它们。其他用户定义类型,如基类型和枚举(两者都是PostgreSQL的扩展),不会在这里显示。域的相关信息见。 + SQL 中有两种用户定义类型:结构类型(在PostgreSQL中也称为复合类型)以及独立类型(distinct type,PostgreSQL 尚未实现)。为兼顾将来,请使用列user_defined_type_category来区分它们。其他用户定义类型,如基础类型和枚举(两者都是PostgreSQL的扩展),不会在这里显示。域的相关信息见 @@ -6261,7 +6259,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -6519,7 +6517,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -6586,7 +6584,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -6642,7 +6640,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -6724,7 +6722,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -6804,7 +6802,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -6878,7 +6876,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 diff --git a/zh/11/install-windows.sgml b/zh/11/install-windows.sgml index b2c212aa..478e2d39 100644 --- a/zh/11/install-windows.sgml +++ b/zh/11/install-windows.sgml @@ -4,8 +4,8 @@ 在 <productname>Windows</productname> 上从源代码安装 - installation - on Windows + 安装 + 在 Windows 上 @@ -63,7 +63,10 @@ $ENV{MSBFLAGS}="/m"; 需求 - 以下附加产品是构建 PostgreSQL 所必需的。请使用 config.pl 文件指定各个库所在的目录。 + + 构建PostgreSQL需要以下附加产品。请使用config.pl文件指定这些库所在的目录。 + + Microsoft Windows SDK @@ -81,7 +84,10 @@ $ENV{MSBFLAGS}="/m"; - 开始使用时不需要以下附加产品,但构建完整软件包时需要。请使用 config.pl 文件指定各个库所在的目录。 + + 以下附加产品并非入门所必需,但若要构建完整的软件包则需要它们。请使用config.pl文件指定这些库所在的目录。 + + ActiveState TCL 构建 PL/Tcl 需要它(注意:需要 8.4 版本,免费的标准发行版即可)。 @@ -268,7 +274,9 @@ $ENV{CONFIG}="Debug"; 有关回归测试的更多信息,参见 - vcregress bincheck 运行客户端程序的回归测试、用 vcregress recoverycheck 运行恢复测试,或用 vcregress taptest 指定并运行 TAP 测试,都需要另外安装一个 Perl 模块: + + 对客户端程序运行回归测试时使用vcregress bincheck,对恢复测试使用vcregress recoverycheck,或者运行由vcregress taptest指定的 TAP 测试时,需要额外安装一个 Perl 模块: + IPC::Run 撰写本文时,IPC::Run 既未包含在 ActiveState Perl 安装中,也未包含在 ActiveState Perl 软件包管理器(PPM)的库中。要安装它,请下载以下文件:IPC-Run-<version>.tar.gz,这是 CPAN 提供的源码归档,地址为 ,然后将其解压。编辑 buildenv.pl 文件,并添加 PERL5LIB 变量,使其指向解压后归档中的 lib 子目录。例如: @@ -279,7 +287,8 @@ $ENV{PERL5LIB}=$ENV{PERL5LIB} . ';c:\IPC-Run-0.94\lib'; - 部分 TAP 测试依赖一些外部命令,相关测试会根据这些命令是否可用而选择性触发。以下各变量都可以在 buildenv.pl 中设置或取消设置: + + 部分 TAP 测试依赖一些外部命令,相关测试会根据这些命令是否可用而选择性触发。以下各变量都可以在 buildenv.pl 中设置或取消设置: GZIP_PROGRAM @@ -299,7 +308,7 @@ $ENV{PERL5LIB}=$ENV{PERL5LIB} . ';c:\IPC-Run-0.94\lib'; - 使用 Make 构建文档 + 构建文档 将 PostgreSQL 文档构建为 HTML 格式,需要若干工具和文件。请为这些文件创建一个根目录,并将它们存放在下列子目录中。 diff --git a/zh/11/installation.sgml b/zh/11/installation.sgml index 5829971b..86ef54eb 100644 --- a/zh/11/installation.sgml +++ b/zh/11/installation.sgml @@ -12,7 +12,7 @@ documentation. See standalone-profile.xsl for details. 从源代码安装 - installation + 安装 本章介绍如何使用源代码发布包安装 PostgreSQL。(如果你安装的是预打包的发行版,例如 RPM 或 Debian 软件包,请忽略本章,改为阅读打包者提供的说明。) @@ -34,7 +34,7 @@ su - postgres /usr/local/pgsql/bin/postgres -D /usr/local/pgsql/data >logfile 2>&1 & /usr/local/pgsql/bin/createdb test /usr/local/pgsql/bin/psql test -详细说明见本。 +详细说明见本的其余部分。 @@ -44,7 +44,8 @@ su - postgres 一般来说,现代的 Unix 兼容平台应该能够运行 PostgreSQL。发布时经过具体测试的平台列于下方 。发行包的 doc 子目录中有若干平台特定的 FAQ 文档,遇到问题时可以查阅。 - 以下软件包必须备齐,才能构建 PostgreSQL: + + 构建 PostgreSQL 需要下列软件包: @@ -121,13 +122,17 @@ su - postgres - 以下软件包是可选的。默认配置不需要它们,但启用某些构建选项时需要,具体如下: + + 下列软件包是可选的。默认配置不需要它们,但在启用某些构建选项时会用到, + 如下所述: + + 要构建服务器端编程语言 PL/Perl, 你需要一个完整的 Perl 安装, 包括 libperl 库和头文件。 - 最低要求版本是 Perl 5.14。 + 最低要求版本是 Perl 5.8.3。 由于 PL/Perl 是一个共享库,在大多数平台上, libperl libperl 也必须是共享库。这在较新的 @@ -185,11 +190,14 @@ su - postgres - 如果你希望支持使用相应服务进行身份验证,就需要 KerberosOpenLDAP 和/或 PAM + 如果你希望支持使用相应服务进行认证,就需要 KerberosOpenLDAP 和/或 PAM - 构建 PostgreSQL 文档另有一组要求;参见 + + 要构建 PostgreSQL 文档,还需要满足另一组要求; + 见 。 + @@ -663,7 +671,7 @@ su - postgres ,使用 OSSP UUID library + url="http://www.ossp.org/pkg/lib/uuid/">OSSP UUID 库 @@ -682,7 +690,10 @@ su - postgres - 使用 libxml2 构建,以启用 SQL/XML 支持。此功能要求 Libxml2 2.6.23 或更高版本。 + + 构建时支持 libxml2,以启用 SQL/XML 支持。 + 这一特性要求 libxml2 2.6.23 或更高版本。 + 为检测所需的编译器和链接器选项,PostgreSQL 会查询 pkg-config,前提是已安装该程序且其中有 libxml2 的信息。否则,如果找到 libxml2 安装的 xml2-config 程序,就会使用它。优先使用 pkg-config,因为它能更好地处理多架构安装。 @@ -829,7 +840,7 @@ su - postgres - 如果使用 GCC,所有程序和库都会编译为可进行性能剖析的形式。后端退出时,会创建一个子目录,其中包含用于性能剖析的 gmon.out 文件。此选项仅用于使用 GCC 进行开发工作时。 + 如果使用 GCC,所有程序和库都会编译为可进行性能分析的形式。后端退出时,会创建一个子目录,其中包含用于性能分析的 gmon.out 文件。此选项仅用于使用 GCC 进行开发工作时。 @@ -837,11 +848,11 @@ su - postgres - 在服务器中启用 assertion 检查,用于测试许多 - 不应该发生的条件。这对代码开发非常有价值,但这些测试会显著拖慢 + 在服务器中启用 断言 检查,用于测试许多 + 不可能发生的条件。这对代码开发非常有价值,但这些测试可能会显著拖慢 服务器速度。此外,启用这些测试并不一定会增强服务器稳定性! 断言检查并未按严重程度分类,因此即使某个 bug 相对无害,只要触发了断言失败, - 仍可能导致服务器重启。该选项不建议用于生产环境,但如果你在做开发工作 + 仍会导致服务器重启。该选项不建议用于生产环境,但如果你在做开发工作 或运行测试版,就应当启用它。 @@ -900,7 +911,10 @@ su - postgres - 以下是可以通过这种方式设置的重要变量: + + 下面列出可以按这种方式设置的重要变量: + + BISON @@ -933,7 +947,7 @@ su - postgres 在使用 --with-llvm 编译时, - 用于处理源代码以内联的 clang 程序路径 + 用于处理源代码以进行内联的 clang 程序路径 @@ -1124,7 +1138,7 @@ All of PostgreSQL successfully made. Ready to install. - 如果要构建所有可构建的内容,包括文档(HTML 和 man 页面)及附加模块(contrib),请改为输入: + 如果要构建所有可构建的内容,包括文档(HTML 和手册页)及附加模块(contrib),请改为输入: make world 显示的最后一行应该是: PostgreSQL, contrib, and documentation successfully made. Ready to install. @@ -1157,9 +1171,17 @@ build-postgresql: 回归测试 - 如果希望在安装前测试刚构建的服务器,可以在此时运行回归测试。回归测试是一套测试程序,用于验证 PostgreSQL 是否在你的机器上按开发者预期的方式运行。输入: + + 如果你希望在安装之前测试新构建的服务器,可以在此时运行回归测试。 + 回归测试是一套测试,用来验证 PostgreSQL + 是否按开发者预期的方式在你的机器上运行。输入: + make check -(不能以 root 身份运行;请使用非特权用户。)参见 ,其中包含解读测试结果的详细信息。以后任何时候都可以通过执行同一命令来重复此测试。 + + (这不能以 root 身份运行;请使用非特权用户。) + 关于如何解释测试结果的详细信息,见 。 + 在以后的任何时候,你都可以再次执行同样的命令来重复此测试。 + @@ -1284,14 +1306,25 @@ build-postgresql: Solaris - 设置共享库搜索路径的方法因平台而异,但最常见的方法是设置环境变量 LD_LIBRARY_PATH,方法如下。在 Bourne shell(shkshbashzsh): + + 设置共享库搜索路径的方法因平台而异,但最常见的方法是按如下方式设置环境变量 + LD_LIBRARY_PATH。对于 Bourne shell + (shkshbash、 + zsh): LD_LIBRARY_PATH=/usr/local/pgsql/lib export LD_LIBRARY_PATH -或者在 cshtcsh: + + 或者对于 cshtcsh setenv LD_LIBRARY_PATH /usr/local/pgsql/lib -请将 /usr/local/pgsql/lib 替换为你为 指定的值,设置过程见 。应将这些命令放入 shell 启动文件,例如 /etc/profile~/.bash_profile。关于此方法相关注意事项的一些有用信息,参见 + 请把这里的 /usr/local/pgsql/lib 替换为你在 + 中通过 + 设置的值。你应该把这些命令放入 shell 启动文件,例如 + /etc/profile~/.bash_profile。 + 关于这种方法的注意事项,有一些不错的资料可参见 + @@ -1306,10 +1339,15 @@ setenv LD_LIBRARY_PATH /usr/local/pgsql/lib bin 目录中。 - 如果不确定,请参阅系统的手册页(可能是 ld.sorld)。如果以后遇到类似以下的消息: + + 如果不确定,请参考你系统的手册页(可能是 ld.so + 或 rld)。如果你随后收到类似下面这样的消息: + psql: error in loading shared libraries libpq.so.2.1: cannot open shared object file: No such file or directory -则说明此步骤不可省略。届时补做即可。 + + 那就说明这一步确实是必须的。到那时再处理即可。 + @@ -1348,10 +1386,17 @@ libpq.so.2.1: cannot open shared object file: No such file or directory PostgreSQL 的使用方便得多。 - 为此,请将以下内容添加到 shell 启动文件中,例如 ~/.bash_profile(或者使用 /etc/profile,使其对所有用户生效): + + 为此,请把下面内容加到你的 shell 启动文件中,例如 + ~/.bash_profile(如果你希望影响所有用户,则用 + /etc/profile): + PATH=/usr/local/pgsql/bin:$PATH export PATH -如果使用 cshtcsh,则使用以下命令: + + 如果你使用的是 cshtcsh, + 则使用这条命令: + set path = ( /usr/local/pgsql/bin $path ) @@ -1397,7 +1442,12 @@ export MANPATH 可以预期 PostgreSQL 能在以下操作系统上工作:Linux(所有近期发行版)、Windows(Win2000 SP4 及更高版本)、FreeBSD、OpenBSD、NetBSD、macOS、AIX、HP/UX 和 Solaris。其他类 Unix 系统也可能可用,但目前未在测试。大多数情况下,某个操作系统所支持的全部 CPU 架构也都可以工作。尤其是在使用较旧系统时,请查看下面的 ,看看是否有针对你的操作系统的特别说明。 - 如果近期构建农场的结果表明某个平台受支持,但你在该平台上遇到安装问题,请向 pgsql-bugs@lists.postgresql.org 报告。如果你有兴趣将 PostgreSQL 移植到新平台,可以在 pgsql-hackers@lists.postgresql.org 讨论。 + + 如果你在某个平台上遇到安装问题,而根据近期构建农场的结果该平台是受支持的, + 请把问题报告到 pgsql-bugs@lists.postgresql.org。 + 如果你有兴趣把 PostgreSQL 移植到一个新平台, + 那么 pgsql-hackers@lists.postgresql.org 是合适的讨论地点。 + @@ -1583,9 +1633,11 @@ ERROR: could not load library "/opt/dbs/pgsql/lib/plperl.so": Bad address - 并行回归测试(make check)可能因溢出而误报回归测试失败;溢出发生在 listen() 的待处理连接队列中,会导致连接被拒绝的错误或挂起。可以使用 make 变量 MAX_CONNECTIONS 限制连接数,方法如下: + 并行回归测试(make check)可能因 listen() 的待处理连接队列溢出而误报回归测试失败;队列溢出会导致连接被拒绝的错误或挂起。可以使用 make 变量 MAX_CONNECTIONS 限制连接数,方法如下: + make MAX_CONNECTIONS=5 check -(在某些系统上,并发连接数最高可达约 10 个。) + +(在某些系统上,并发连接数最高可达约 10 个。) @@ -1622,7 +1674,7 @@ PHSS_30849 s700_800 u2comp/be/plugin library Patch - 如果同时安装了 HP 的 C 编译器和 GCC,可以在运行以下命令时显式选择要使用的编译器:configure: + 如果同时安装了 HP 的 C 编译器和 GCC,可以在运行 configure 时显式选择要使用的编译器: ./configure CC=cc 这会选择 HP 的 C 编译器;或者执行: @@ -1692,7 +1744,7 @@ xcrun --show-sdk-path 这种情况并未经过 PostgreSQL 开发者测试,也不受支持。 - macOSSystem Integrity Protection(SIP)功能会破坏 make check,因为它会阻止将所需的 DYLD_LIBRARY_PATH 设置传给被测试的可执行文件。可以在 make check 之前先执行 make install 来规避这一问题。不过,大多数 Postgres 开发者会直接关闭 SIP。 + macOS系统完整性保护(SIP)功能会破坏 make check,因为它会阻止将所需的 DYLD_LIBRARY_PATH 设置传给被测试的可执行文件。可以在 make check 之前先执行 make install 来规避这一问题。不过,大多数 Postgres 开发者会直接关闭 SIP。 @@ -1712,7 +1764,7 @@ xcrun --show-sdk-path 安装好所有组件后,建议在 CMD.EXE 下运行 psql,因为 MSYS 控制台存在缓冲问题。 - 收集崩溃转储 + 在 Windows 上收集崩溃转储 如果 PostgreSQL 在 Windows 上崩溃,它能够生成 @@ -1742,14 +1794,14 @@ xcrun --show-sdk-path 你可以使用 GCC 或 Sun 编译器套件来构建。为了获得更好的代码优化,在 SPARC 架构上强烈推荐使用 Sun 编译器。我们收到过使用 GCC 2.95.1 时出现问题的报告;建议使用 GCC 2.95.3 或更高版本。如果使用 Sun 编译器,请注意不要选择 /usr/ucb/cc;应使用 /opt/SUNWspro/bin/cc - 你可以从 下载 Sun Studio。许多 GNU 工具已经集成到 Solaris 10 中,或者包含在 Solaris companion CD 中。如果你需要适用于较旧 Solaris 版本的软件包,可以到 查找这些工具。如果你更想要源码,请看 + 你可以从 下载 Sun Studio。许多 GNU 工具已经集成到 Solaris 10 中,或者包含在 Solaris 配套光盘中。如果你需要适用于较旧 Solaris 版本的软件包,可以到 查找这些工具。如果你更想要源码,请看 - configure 抱怨测试程序失败 + configure 报告测试程序失败 - 如果 configure 抱怨某个测试程序失败, + 如果 configure 报告某个测试程序失败, 这多半是因为运行时链接器找不到某些库,通常是 libz、libreadline, 或其他非标准库如 libssl。要把它指向正确位置,请在 configure 命令行中设置环境变量 LDFLAGS, diff --git a/zh/11/isn.sgml b/zh/11/isn.sgml index 5074ad6a..ea612463 100644 --- a/zh/11/isn.sgml +++ b/zh/11/isn.sgml @@ -1,7 +1,7 @@ - isn — 国际标准编号(ISBN、EAN、UPC 等)的数据类型 + isn isn @@ -217,24 +217,24 @@ make_valid(isn)make_valid isn - - 设置弱输入模式,并返回新的设置值。 - + 使无效编号变为有效(清除无效标记) is_valid(isn)is_valid boolean - - 返回弱模式的当前状态。 - + 检查是否存在无效标记
- 模式用于将无效数据插入表中。无效是指校验位错误,而不是编号缺失。 + + 模式用于允许向表中插入无效数据。这里的“无效”指的是校验位错误,而不是缺少数字。 + - 为什么需要使用弱模式?例如,手头可能有一大批 ISBN 编号,数量多到难免会有一些编号因为某些奇怪的原因而带有错误的校验位(也许这些编号是从印刷清单扫描得到的,而 OCR 把数字识别错了;也许这些编号是人工录入的……谁知道呢)。总之,可能想把这些混乱情况清理干净,但同时仍希望先把所有编号都装入数据库,并借助外部工具在数据库中定位无效编号,以便核对信息并更容易完成校验;例如,可能会想把表中所有无效编号都查询出来。 + + 为什么会需要使用弱模式呢?例如,手头可能有一大批 ISBN 编号,数量多到难免会有一些编号因为某些奇怪的原因而带有错误的校验位(也许这些编号是从印刷清单扫描得到的,而 OCR 把数字识别错了;也许这些编号是人工录入的……谁知道呢)。总之,可能想把这些混乱情况清理干净,但同时仍希望先把所有编号都装入数据库,并借助外部工具在数据库中定位无效编号,以便核对信息并更容易完成校验;例如,可能会想把表中所有无效编号都查询出来。 + 当在弱模式下向表中插入无效编号时,实际插入的是校验位已更正的编号,但显示时会在末尾附加一个感叹号(!),例如0-11-000322-5!。可以用is_valid函数检查这个无效标记,并用make_valid函数清除它。 @@ -292,18 +292,26 @@ SELECT isbn13(id) FROM test; 参考文献 - 实现此模块所需的信息收集自多个网站,包括: + + 实现该模块所需的信息收集自若干网站,包括: + - 连字符化使用的前缀也收集自: + + + 用于进行连字符分隔的前缀还整理自: + - 在创建这些算法时十分谨慎,并根据官方 ISBN、ISMN、ISSN 用户手册中建议的算法进行了细致验证。 + + + 在创建这些算法时已十分谨慎,并依据官方 ISBN、ISMN、ISSN 用户手册中建议的算法进行了细致核验。 + diff --git a/zh/11/libpq.sgml b/zh/11/libpq.sgml index 9de3a9b0..3fbd4433 100644 --- a/zh/11/libpq.sgml +++ b/zh/11/libpq.sgml @@ -33,7 +33,7 @@ 以下函数用于建立到PostgreSQL后端服务器的连接。应用程序可以同时保持多个后端连接。(这样做的原因之一是访问多个数据库。)每个连接由一个PGconnPGconn对象表示,该对象可以通过以下函数获取:PQconnectdbPQconnectdbParams,或PQsetdbLogin。注意,这些函数总是返回非空的对象指针,除非内存不足,甚至无法分配PGconn对象。应调用PQstatus函数检查返回值,确认连接成功后,再通过连接对象发送查询。 - 如果不可信用户能够访问一个没有采用模式的安全使用方式的数据库,那么每个会话开始时都应从search_path中移除公开可写的模式。可以把参数关键词options设置为-csearch_path=。也可以在连接后发出PQexec(conn, "SELECT pg_catalog.set_config('search_path', '', false)")。这种考虑并非专门针对libpq;它适用于每一种可执行任意 SQL 命令的接口。 + 如果不受信任的用户能够访问一个没有采用模式的安全使用方式的数据库,那么每个会话开始时都应从search_path中移除公开可写的模式。可以把参数关键词options设置为-csearch_path=。也可以在连接后发出PQexec(conn, "SELECT pg_catalog.set_config('search_path', '', false)")。这种考虑并非专门针对libpq;它适用于每一种可执行任意 SQL 命令的接口。 @@ -195,7 +195,7 @@ PostgresPollingStatusType PQconnectPoll(PGconn *conn); 无论是PQconnectStartParams还是PQconnectStart还是PQconnectPoll都不会阻塞,只要满足以下限制: - 必须正确使用 hostaddr 参数,避免执行 DNS 查询。详细信息请参见 中此参数的文档。 + 必须正确使用 hostaddr 参数,以避免执行 DNS 查询。详细信息请参见 中该参数的说明。 @@ -1345,20 +1345,31 @@ PGTransactionStatusType PQtransactionStatus(const PGconn *conn); PQparameterStatus PQparameterStatus - 查找服务器某个参数的当前设置。 + + 查找服务器某个参数的当前设置。 + + const char *PQparameterStatus(const PGconn *conn, const char *paramName); -服务器会在连接启动时,以及某些参数值发生变化时,自动报告这些参数值。PQparameterStatus可用于查询这些设置。如果已知该参数,则返回其当前值;如果未知,则返回NULL + - 当前版本报告的参数包括 server_versionserver_encodingclient_encodingapplication_nameis_superusersession_authorizationDateStyleIntervalStyleTimeZoneinteger_datetimesstandard_conforming_strings。(8.0 之前的版本不报告 server_encodingTimeZoneinteger_datetimes;8.1 之前的版本不报告 standard_conforming_strings;8.4 之前的版本不报告 IntervalStyle;9.0 之前的版本不报告 application_name。)注意,server_versionserver_encodinginteger_datetimes 在启动后不能改变。 + 服务器会在连接启动时,以及某些参数值发生变化时,自动报告这些参数值。PQparameterStatus可用于查询这些设置。如果已知该参数,则返回其当前值;如果未知,则返回NULL。 + + + + 当前版本报告的参数包括: + server_versionserver_encodingclient_encodingapplication_nameis_superusersession_authorizationDateStyleIntervalStyleTimeZoneinteger_datetimesstandard_conforming_strings。 + (8.0 之前的版本不报告 server_encodingTimeZoneinteger_datetimes;8.1 之前的版本不报告 standard_conforming_strings;8.4 之前的版本不报告 IntervalStyle;9.0 之前的版本不报告 application_name。) + 注意,server_versionserver_encodinginteger_datetimes 在启动后不能改变。 + 使用 3.0 之前协议的服务器不报告参数设置,但 libpq 仍包含获取 server_versionclient_encoding 值的逻辑。建议应用程序使用 PQparameterStatus,而不是专门编写代码来确定这些值。(但要注意,在使用 3.0 之前协议的连接上,连接启动后通过 SET 改变 client_encoding,不会反映在 PQparameterStatus 的结果中。)对于 server_version,另请参见 PQserverVersion,它以数值形式返回此信息,更易于比较。 - 如果没有为standard_conforming_strings报告值,应用能假设它是off,也就是说反斜线会被视为字符串中的转义。还有,这个参数的存在可以被作为转义字符串语法(E'...')被接受的指示。 + 如果服务器未报告standard_conforming_strings的值,应用程序可以假定其为off,即反斜杠在字符串字面量中被视为转义字符。此外,服务器报告此参数也表明它接受转义字符串语法(E'...')。 - 尽管被返回的指针被声明成const,它事实上指向与PGconn结构体相关的可变存储。假定该指针在存储之间保持有效是不明智的。 + 返回的指针虽然被声明为const,但实际上指向与PGconn结构体关联的可变存储。不能假定该指针在执行其他查询后仍然有效。 @@ -1728,7 +1739,7 @@ PGresult *PQexecParams(PGconn *conn, paramTypes[] - 通过 OID 指定要赋予给参数符号的数据类型。如果paramTypesNULL或者该数组中任何特定元素为零,服务器会用对待未知类型文字串的方式为参数符号推测一种数据类型。 + 通过 OID 指定要赋予给参数符号的数据类型。如果paramTypesNULL或者该数组中任何特定元素为零,服务器会用对待未指定类型的字符串字面量的方式为参数符号推测一种数据类型。 @@ -1820,7 +1831,7 @@ PGresult *PQprepare(PGconn *conn, 否则,如果语句名称已经在当前会话中被定义,则是一种错误。如果使用了任何参数,它们在查询中以$1$2等引用。 nParams是参数的个数,其类型在数组paramTypes[]中被预先指定(当nParams为零时,该数组指针可以是NULL)。 paramTypes[]通过 OID 指定要赋予给参数符号的数据类型。 - 如果paramTypesNULL或者该数组中任何特定元素为零,服务器会用对待未知类型文字串的方式为参数符号推测一种数据类型。 + 如果paramTypesNULL或者该数组中任何特定元素为零,服务器会用对待未指定类型的字符串字面量的方式为参数符号推测一种数据类型。 还有,查询能够使用编号高于nParams的参数符号,它们的数据类型也会被自动推测(找出推测出的数据类型的方法见PQdescribePrepared)。 @@ -2121,7 +2132,7 @@ char *PQresultErrorField(const PGresult *res, int fieldcode); PG_DIAG_MESSAGE_DETAIL - 细节:一个可选的次级错误消息,它携带了关于问题的等多细节。可能有多行。 + 细节:一个可选的次级错误消息,它携带了关于问题的更多细节。可能有多行。 @@ -2139,7 +2150,7 @@ char *PQresultErrorField(const PGresult *res, int fieldcode); PG_DIAG_STATEMENT_POSITION - 包含一个十进制整数的字符串,它表示一个错误游标位置,该位置是原始语句字符串的索引。第一个字符的索引是 1,位置以字符计算而不是以及字节计算。 + 包含一个十进制整数的字符串,它表示一个错误游标位置,该位置是原始语句字符串的索引。第一个字符的索引是 1,位置以字符计算而不是以字节计算。 @@ -2841,7 +2852,7 @@ unsigned char *PQescapeByteaConn(PGconn *conn, - 当某些字节值被用作一个SQL语句中的bytea文字的一部分时,它们必须被转义。 + 当某些字节值被用作一个SQL语句中的bytea字面量的一部分时,它们必须被转义。 PQescapeByteaConn使用十六进制编码或反斜杠转义来转义这些字节。详见 @@ -2882,19 +2893,26 @@ unsigned char *PQescapeBytea(const unsigned char *from, PQunescapeBytea PQunescapeBytea - 将二进制数据的字符串表示转换为二进制数据,这是以下函数的逆操作:PQescapeBytea。以文本格式取得bytea数据时需要此操作;以二进制格式取得时则不需要。 + + 将二进制数据的字符串表示转换为二进制数据,这是PQescapeBytea的逆操作。 + 以文本格式取得bytea数据时需要此操作;以二进制格式取得时则不需要。 + + unsigned char *PQunescapeBytea(const unsigned char *from, size_t *to_length); - from参数指向一个字符串,例如PQgetvalue被应用到一个bytea列上所返回的。 - PQunescapeBytea把这个串表示转换成它的二进制表示。 - 它返回一个指向用malloc()分配的缓冲区的指针,在错误时返回NULL,并且把缓冲区的尺寸放在to_length中。 - 当结果不再需要时,它必须使用PQfreemem释放。 + from参数指向一个字符串,例如对bytea列调用PQgetvalue时返回的字符串。 + PQunescapeBytea将这个字符串表示转换为二进制表示。 + 它返回指向通过malloc()分配的缓冲区的指针,出错时返回NULL,并将缓冲区大小存入to_length。 + 不再需要结果时,必须使用PQfreemem释放它。 - 此转换并不完全是 PQescapeBytea 的逆操作,因为从 PQgetvalue 收到的字符串不应已经过转义。具体而言,这意味着无需考虑字符串引号,因此也不需要 PGconn 参数。 + + 此转换并不完全是PQescapeBytea的逆操作,因为从PQgetvalue收到的字符串并非经过转义的形式。 + 具体而言,这意味着无需考虑字符串引号,因此也不需要PGconn参数。 + @@ -3350,7 +3368,7 @@ typedef struct - 要传递NULL参数到函数,将参数结构体的len字段设置为-1;isintu 字段就不相关了。(但这仅适用于使用协议 3.0 及更高版本的连接。) + 要传递NULL参数到函数,将参数结构体的len字段设置为-1isintu 字段就不相关了。(但这仅适用于使用协议 3.0 及更高版本的连接。)
如果函数返回 NULL,则将 *result_len 设为 -1,而不修改 *result_buf。(这仅适用于使用协议 3.0 及更高版本的连接;在协议 2.0 中,既不修改 *result_len,也不修改 *result_buf。) @@ -3934,11 +3952,12 @@ PGresult *PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status); 这是libpq内部用于分配并初始化一个空PGresult对象的函数。 - 如果不能分配内存,那么这个函数返回NULL。 - 它也是可以对外使用的,因为一些应用需要自行生成结果对象(特别是带有错误状态的对象)。 - 如果conn非空,并且status表示一个错误,那么指定连接的当前错误消息会被复制到PGresult中。 - 如果conn非空,那么连接中的任何已注册事件过程也会被复制到PGresult中(它们不会获得PGEVT_RESULTCREATE调用,但可参见PQfireResultCreateEvents)。 - 注意在该对象上最终应该调用PQclear,正如对libpq本身返回的PGresult对象所作的那样。 + 如果无法分配内存,此函数返回NULL。 + 将它导出供外部调用,是因为一些应用需要自行生成结果对象,特别是带有错误状态的对象。 + 如果conn非空,并且status表示错误,指定连接的当前错误消息会被复制到PGresult中。 + 此外,如果conn非空,连接中注册的所有事件过程也会被复制到PGresult中。 + (这些过程不会收到PGEVT_RESULTCREATE调用,但可参见PQfireResultCreateEvents。) + 注意,最终应对该对象调用PQclear,就像处理libpq自身返回的PGresult一样。
@@ -4214,13 +4233,25 @@ typedef struct PGEVT_RESULTCREATE - 任何生成结果的查询执行函数都会触发结果创建事件,其中包括PQgetResult。只有成功创建结果后才会触发该事件。 + + 任何生成结果的查询执行函数都会触发结果创建事件,其中包括PQgetResult。 + 只有成功创建结果后才会触发该事件。 + + typedef struct { PGconn *conn; PGresult *result; } PGEventResultCreate; -收到PGEVT_RESULTCREATE事件时,应将evtInfo指针强制转换为PGEventResultCreate *。其中,conn是用于生成结果的连接。这是初始化需要与结果关联的instanceData的理想位置。如果事件处理函数失败,结果会被清除,失败也会向外传递。事件处理函数不得自行调用PQclear来清除结果对象。返回失败代码时,必须完成所有清理工作,因为不会发送PGEVT_RESULTDESTROY事件。 + + + 收到PGEVT_RESULTCREATE事件时,应将evtInfo指针转换为PGEventResultCreate *。 + 其中,conn是用于生成结果的连接。 + 这是初始化需要与结果关联的instanceData的理想位置。 + 如果事件过程失败,结果会被清除,失败也会向外传递。 + 事件过程不得自行调用PQclear来清除结果对象。 + 返回失败代码时,必须完成所有清理工作,因为不会发送PGEVT_RESULTDESTROY事件。 + @@ -4862,13 +4893,8 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough) - 用户的主目录中的文件.pgpass可以包含密码, - 如果连接需要密码(且未指定其他密码)。在Microsoft Windows中, - 该文件的名称为%APPDATA%\postgresql\pgpass.conf - (其中%APPDATA%指用户配置文件中的应用数据子目录)。 - 或者,可以使用连接参数 - 或环境变量PGPASSFILE指定要使用的密码文件。 - + 用户主目录中的.pgpass文件可保存密码,供连接需要密码且尚未通过其他方式指定密码时使用。在 Microsoft Windows 上,文件名为%APPDATA%\postgresql\pgpass.conf(其中%APPDATA%指用户配置文件中的应用数据子目录)。也可以通过连接参数或环境变量PGPASSFILE指定要使用的密码文件。 +
该文件中的行应采用以下格式: hostname:port:database:username:password @@ -5305,8 +5331,8 @@ void PQinitSSL(int do_ssl); 在线程化程序中的行为 - threads - with libpq + 线程 + 用于 libpq libpq 默认是可重入且线程安全的。编译应用程序代码时,可能需要使用特殊的编译器命令行选项。有关如何构建支持线程的应用程序,请参阅系统文档,或查看 src/Makefile.global 中的 PTHREAD_CFLAGSPTHREAD_LIBS。以下函数可用于查询 libpq 的线程安全状态: @@ -5324,7 +5350,7 @@ int PQisthreadsafe(); - 如果libpq是线程安全的则返回 1,否则返回 0。在版本 17 及以上始终返回 1。 + 如果libpq是线程安全的则返回 1,否则返回 0。 diff --git a/zh/11/logical-replication.sgml b/zh/11/logical-replication.sgml index 0a097651..eaf9fbb8 100644 --- a/zh/11/logical-replication.sgml +++ b/zh/11/logical-replication.sgml @@ -201,7 +201,12 @@ - 数据库模式和DDL命令不会被复制。初始模式可使用pg_dump --schema-only手动复制。后续的模式变更需要手动保持同步。(注意,两端的模式不需要完全相同。)当数据库模式在运行中发生变更时,逻辑复制是健壮的:当发布端模式变更后,复制的数据开始到达订阅端但不符合表的模式时,复制会出错,直到模式被更新。在很多情况下,通过先在订阅端应用增量式模式变更,可以避免间歇性错误。 + 数据库模式和 DDL 命令不会被复制。初始模式可以手工使用 + pg_dump --schema-only 复制。之后的模式更改需要手工保持同步。 + (不过请注意,两端的模式其实不需要绝对一致。)当活动数据库中的模式定义发生变化时, + 逻辑复制仍然能够稳健运行:如果发布端修改了模式,而复制数据开始到达订阅端时 + 与表模式不匹配,复制就会报错,直到模式被更新。在很多情况下,可以通过先在订阅端 + 应用仅添加内容的模式变更来避免间歇性错误。 @@ -237,15 +242,15 @@
- 逻辑复制采用类似于物理流复制的架构(见)。它由walsenderapply进程实现。walsender 进程启动 WAL 的逻辑解码(见),并加载标准逻辑解码输出插件(pgoutput)。该插件将从 WAL 读取的变更转换为逻辑复制协议(见),并根据发布规范过滤数据。然后使用流复制协议将数据持续传输给 apply 工作进程,该工作进程将数据映射到本地表,并按正确的事务顺序逐一应用每个变更。 + 逻辑复制采用类似于物理流复制的架构(见)。它由walsenderapply进程实现。walsender 进程启动 WAL 的逻辑解码(见),并加载标准逻辑解码输出插件(pgoutput)。该插件将从 WAL 读取的变更转换为逻辑复制协议(见),并根据发布规范过滤数据。然后使用流复制协议将数据持续传输给 应用工作进程,该工作进程将数据映射到本地表,并按正确的事务顺序逐一应用每个变更。 - 订阅端数据库上的 apply 进程总是在session_replication_role设置为replica的情况下运行。这意味着默认情况下,触发器和规则不会在订阅端触发。用户可以选择使用ALTER TABLE命令和ENABLE TRIGGERENABLE RULE子句在表上启用触发器和规则。 + 订阅端数据库上的 应用进程总是在session_replication_role设置为replica的情况下运行。这意味着默认情况下,触发器和规则不会在订阅端触发。用户可以选择使用ALTER TABLE命令和ENABLE TRIGGERENABLE RULE子句在表上启用触发器和规则。 - 逻辑复制的apply进程目前只触发行触发器,不触发语句触发器。但初始表同步的实现方式类似于COPY命令,因此会触发INSERT的行触发器和语句触发器。 + 逻辑复制的应用进程目前只触发行触发器,不触发语句触发器。但初始表同步的实现方式类似于COPY命令,因此会触发INSERT的行触发器和语句触发器。 @@ -268,7 +273,7 @@ - 正常情况下,已启用的订阅会有一个apply进程在运行。被禁用或已崩溃的订阅在此视图中将有零行。如果任何表的初始数据同步正在进行中,将有额外的工作进程用于正在同步的表。 + 正常情况下,已启用的订阅会有一个应用进程在运行。被禁用或已崩溃的订阅在此视图中将有零行。如果任何表的初始数据同步正在进行中,将有额外的工作进程用于正在同步的表。 @@ -300,7 +305,7 @@ - 订阅的apply进程将以超级用户的权限在本地数据库上运行。 + 订阅应用进程将以超级用户的权限在本地数据库中运行。 diff --git a/zh/11/maintenance.sgml b/zh/11/maintenance.sgml index 51a3fd63..6f8a68cb 100644 --- a/zh/11/maintenance.sgml +++ b/zh/11/maintenance.sgml @@ -397,12 +397,9 @@ SELECT datname, age(datfrozenxid) FROM pg_database; - 虽然 VACUUM 主要扫描自上次清理以来被修改过的页面, - 但它也可能为了冻结它们而积极扫描某些全部可见但未全部冻结的页面; - 不过,只有当表中每一个可能包含未冻结 XID 的页面都被扫描时, - relfrozenxid 才会被推进。当 - relfrozenxid 比 - vacuum_freeze_table_age 旧、使用了 VACUUM 的 + VACUUM通常只扫描自上次清理以来被修改过的页面,但只有当表中每一个可能包含未冻结 XID 的页面都被扫描时, + relfrozenxid 才会被推进。当 + relfrozenxid的年龄超过vacuum_freeze_table_age个事务、使用了 VACUUMFREEZE 选项,或者所有尚未全部冻结的页面碰巧都需要清理以移除死行版本时, 就会发生这种情况。当 VACUUM 扫描了表中每个尚未全部冻结的页面时, 它应把 age(relfrozenxid) 设为略高于所用 @@ -433,14 +430,14 @@ HINT: Stop the postmaster and vacuum that database in single-user mode. 多事务 ID 的 - 多事务 ID 用于支持多个事务对行加锁。由于元组头中存放锁信息的空间有限,当多个事务同时锁定一行时,这些信息会被编码为一个多事务 ID,简称 multixact ID。某个特定 multixact ID 包含哪些事务 ID 的信息,单独存放在 pg_multixact 子目录中,元组头的 xmax 字段中只保存 multixact ID。与事务 ID 一样,multixact ID 由 32 位计数器和相应的存储实现,都需要谨慎处理老化管理、存储清理和回卷。另有单独的存储区保存每个 multixact 的成员列表,它同样使用 32 位计数器,也需要管理。 + 多事务 ID 用于支持多个事务对行加锁。由于元组头中存放锁信息的空间有限,当多个事务同时锁定一行时,这些信息会被编码为一个多事务 ID,简称 multixact ID。某个特定 多事务 ID 包含哪些事务 ID 的信息,单独存放在 pg_multixact 子目录中,元组头的 xmax 字段中只保存 多事务 ID。与事务 ID 一样,多事务 ID 由 32 位计数器和相应的存储实现,都需要谨慎处理老化管理、存储清理和回卷。另有单独的存储区保存每个 多事务 的成员列表,它同样使用 32 位计数器,也需要管理。 每当 VACUUM 扫描表的任何部分时,它都会把遇到的、早于 - 的任何 multixact ID 替换为另一个值,该值可能是零值、单个事务 ID,或者更新的 multixact ID。 + 的任何 多事务 ID 替换为另一个值,该值可能是零值、单个事务 ID,或者更新的 多事务 ID。 对于每个表,pg_class.relminmxid - 保存该表任何元组中仍可能出现的最老 multixact ID。如果这个值早于 + 保存该表任何元组中仍可能出现的最老 多事务 ID。如果这个值早于 ,就会强制执行一次激进扫描。 正如上一节所述,激进扫描意味着只有那些已知为全部冻结的页面才会被跳过。 可以对 pg_class.relminmxid @@ -449,10 +446,10 @@ HINT: Stop the postmaster and vacuum that database in single-user mode. 无论出于何种原因而发生,激进的 VACUUM 扫描都能推进该表的值。最终,随着所有数据库中的所有表都被扫描, - 并推进其最老的 multixact 值,较老 multixact 的磁盘存储就可以被移除。 + 并推进其最老的 多事务 值,较老 多事务 的磁盘存储就可以被移除。 - 作为一项安全措施,对于 multixact 年龄大于 的任何表,都会执行激进清理扫描。如果已使用的成员存储空间超过可寻址存储空间的 50%,还会从 multixact 年龄最大的表开始,逐步对所有表执行激进清理扫描。即使名义上禁用了自动清理,这两类激进扫描也都会发生。 + 作为一项安全措施,对于 多事务 年龄大于 的任何表,都会执行激进清理扫描。如果已使用的成员存储空间超过可寻址存储空间的 50%,还会从 多事务 年龄最大的表开始,逐步对所有表执行激进清理扫描。即使名义上禁用了自动清理,这两类激进扫描也都会发生。 @@ -657,7 +654,7 @@ pg_ctl start | rotatelogs /var/log/pgsql_log 86400 不过,在很多系统上,syslog 并不十分可靠, 尤其是在日志消息很大时;它可能恰恰在你最需要消息的时候截断或丢弃它们。 此外,在 Linux 上, - syslog 会把每条消息都刷新到磁盘,导致性能较差。 + syslog 会把每条消息都刷盘,导致性能较差。 (你可以在 syslog 配置文件的文件名开头使用一个 - 来禁用同步。) diff --git a/zh/11/monitoring.sgml b/zh/11/monitoring.sgml index c149973a..a84a7fa9 100644 --- a/zh/11/monitoring.sgml +++ b/zh/11/monitoring.sgml @@ -47,7 +47,9 @@ postgres 15610 0.0 0.0 58772 3056 ? Ss 18:07 0:00 postgres: tgl postgres: user database host activity 在客户端连接的整个生命周期内,用户、数据库和(客户端)主机这几项保持不变,但活动指示符会改变。活动可以是idle(即等待客户端命令)、idle in transaction(在BEGIN块内等待客户端),或者命令类型名称,例如SELECT。此外,服务器进程当前若正在等待另一会话持有的锁,还会附加waiting。在上面的示例中,可以推断进程 15606 正在等待进程 15610 完成事务,从而释放某个锁。(进程 15610 必定是阻塞者,因为不存在其他活动会话。在更复杂的情况下,必须查看pg_locks系统视图,才能确定谁在阻塞谁。) - 如果已配置,集簇名称也会显示在ps的输出中: + + 如果配置了,则集簇名称也会显示在ps输出中: + $ psql -c 'SHOW cluster_name' cluster_name -------------- @@ -76,14 +78,14 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 统计收集器 - statistics + 统计信息 PostgreSQL统计收集器是一个支持收集和报告服务器活动信息的子系统。 - 目前,对表和索引的访问以磁盘块和单个行的术语进行计数。每个表中的总行数, - 以及每个表的清理和分析操作的信息也被计数。如果启用,对用户定义函数的调用 - 和每个函数中花费的总时间也会被计数。 + 目前,对表和索引的访问分别以磁盘块和单行计数。每个表中的总行数, + 以及每个表的清理和分析操作的信息也被计数。它还可以统计对用户定义函数的调用 + 和每个函数中花费的总时间。 @@ -140,7 +142,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - 另一个重要点是,当要求服务器进程显示这些统计信息中的任何一种时,它会先取回收集器进程最近发出的报告,然后在当前事务结束之前,对所有统计视图和函数一直使用这一快照。因此,只要你继续当前事务,统计信息就会显示静态信息。类似地,在事务中第一次请求任意当前会话的查询信息时,就会收集所有会话当前查询的信息,并且在整个事务期间显示的都是同一份信息。这是一个特性,而不是一个错误,因为它允许你对统计信息执行多个查询并对结果做关联,而不必担心数字在你眼前变化。但如果希望每个查询都看到新的结果,请确保在任何事务块之外执行这些查询。或者,也可以调用pg_stat_clear_snapshot(),它会丢弃当前事务的统计快照(如果有)。下一次使用统计信息时,就会获取一个新的快照。 + 另一个重要点是,当要求服务器进程显示这些统计信息中的任何一种时,它会先取回收集器进程最近发出的报告,然后在当前事务结束之前,对所有统计视图和函数一直使用这一快照。因此,只要你继续当前事务,统计信息就会显示静态信息。类似地,在事务中第一次请求这类当前查询信息时,就会收集所有会话当前查询的信息,并且在整个事务期间显示的都是同一份信息。这是一个特性,而不是一个错误,因为它允许你对统计信息执行多个查询并对结果做关联,而不必担心数字在你眼前变化。但如果希望每个查询都看到新的结果,请确保在任何事务块之外执行这些查询。或者,也可以调用pg_stat_clear_snapshot(),它会丢弃当前事务的统计快照(如果有)。下一次使用统计信息时,就会获取一个新的快照。 @@ -216,122 +218,123 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser + pg_stat_archiverpg_stat_archiver 只有一行,显示 WAL 归档进程活动的统计信息。详见 - + pg_stat_bgwriterpg_stat_bgwriter - 只有一行,显示后台写入进程活动的统计信息。详见 + 只有一行,显示后台写入器活动的统计信息。详见 - + pg_stat_databasepg_stat_database 每个数据库一行,显示整个数据库的统计信息。详见 - + pg_stat_database_conflictspg_stat_database_conflicts 每个数据库一行,显示备库上因与恢复冲突而取消查询的数据库范围统计信息。详见 - + pg_stat_all_tablespg_stat_all_tables 当前数据库中的每个表一行,显示访问该表的统计信息。详见 - + pg_stat_sys_tablespg_stat_sys_tables pg_stat_all_tables一样,但只显示系统表。 - + pg_stat_user_tablespg_stat_user_tables pg_stat_all_tables一样,但只显示用户表。 - + pg_stat_xact_all_tablespg_stat_xact_all_tables - pg_stat_all_tables相似,但计数动作只在当前事务内发生(还没有被包括在pg_stat_all_tables和相关视图中)。用于生存和死亡行数量的列以及清理和分析动作在此视图中不出现。 + pg_stat_all_tables 相似,但只统计当前事务中截至目前执行的操作(这些操作尚计入 pg_stat_all_tables 及相关视图)。此视图不包含存活行和死行数量以及清理、分析操作的列。 - + pg_stat_xact_sys_tablespg_stat_xact_sys_tables pg_stat_xact_all_tables一样,但只显示系统表。 - + pg_stat_xact_user_tablespg_stat_xact_user_tables pg_stat_xact_all_tables一样,但只显示用户表。 - + pg_stat_all_indexespg_stat_all_indexes 当前数据库中的每个索引一行,显示访问该索引的统计信息。详见 - + pg_stat_sys_indexespg_stat_sys_indexes pg_stat_all_indexes一样,但只显示系统表上的索引。 - + pg_stat_user_indexespg_stat_user_indexes pg_stat_all_indexes一样,但只显示用户表上的索引。 - + pg_statio_all_tablespg_statio_all_tables 当前数据库中的每个表一行,显示该表的 I/O 统计信息。详见 - + pg_statio_sys_tablespg_statio_sys_tables pg_statio_all_tables一样,但只显示系统表。 - + pg_statio_user_tablespg_statio_user_tables pg_statio_all_tables一样,但只显示用户表。 - + pg_statio_all_indexespg_statio_all_indexes 当前数据库中的每个索引一行,显示该索引的 I/O 统计信息。详见 - + pg_statio_sys_indexespg_statio_sys_indexes pg_statio_all_indexes一样,但只显示系统表上的索引。 - + pg_statio_user_indexespg_statio_user_indexes pg_statio_all_indexes一样,但只显示用户表上的索引。 - + pg_statio_all_sequencespg_statio_all_sequences 当前数据库中的每个序列一行,显示该序列的 I/O 统计信息。详见 - + pg_statio_sys_sequencespg_statio_sys_sequences pg_statio_all_sequences一样,但只显示系统序列(目前没有定义系统序列,因此这个视图总是为空)。 - + pg_statio_user_sequencespg_statio_user_sequences pg_statio_all_sequences一样,但只显示用户序列。 - + pg_stat_user_functionspg_stat_user_functions 每个被跟踪的函数一行,显示该函数执行的统计信息。详见 - + pg_stat_xact_user_functionspg_stat_xact_user_functions pg_stat_user_functions相似,但是只统计在当前事务期间的调用(还没有被包括在pg_stat_user_functions中)。 @@ -413,7 +416,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser client_addr inet - 连接到这个后端的客户端的 IP 地址。如果这个字段为空,它表示客户端通过服务器机器上的一个 Unix 套接字连接或者这是一个内部进程,如自动清理。 + 连接到这个后端的客户端的 IP 地址。如果这个字段为空值,它表示客户端通过服务器机器上的一个 Unix 套接字连接或者这是一个内部进程,如自动清理。 @@ -440,8 +443,8 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser xact_start timestamp with time zone - 这个进程的当前事务被启动的时间,如果没有活动事务则为空。 - 如果当前查询是它的第一个事务,这一列等于query_start列。 + 这个进程的当前事务被启动的时间,如果没有活动事务则为空值。 + 如果当前查询是其事务中的第一个查询,这一列等于query_start列。 @@ -461,7 +464,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser wait_event_type text - 后端正在等待的事件类型(如果有),否则为 NULL。可能的值为: + 后端正在等待的事件类型(如果有),否则为空值。可能的值为: LWLock:后端正在等待轻量级锁。每个这样的锁保护共享内存中的某个特定数据结构。wait_event将包含标识该轻量级锁用途的名称。(有些锁具有专门的名称,另一些锁属于一组用途相似的锁。) @@ -495,32 +498,32 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser wait_event text - 如果后端当前正在等待,则为等待事件名称,否则为 NULL。详见 + 如果后端当前正在等待,则为等待事件名称,否则为空值。详见 state text 该后端当前的总体状态。可能的值为: - - active:后端正在执行一个查询。 - - - idle:后端正在等待新的客户端命令。 - - - idle in transaction:后端处于事务中,但当前没有执行查询。 - - - idle in transaction (aborted):该状态与idle in transaction类似,但事务中的某个语句导致了错误。 - - - fastpath function call:后端正在执行一个快速路径函数。 - - - disabled:如果在此后端中禁用了,就会报告此状态。 - + + active:后端正在执行一个查询。 + + + idle:后端正在等待新的客户端命令。 + + + idle in transaction:后端处于事务中,但当前没有执行查询。 + + + idle in transaction (aborted):该状态与idle in transaction类似,但事务中的某个语句导致了错误。 + + + fastpath function call:后端正在执行一个快速路径函数。 + + + disabled:如果在此后端中禁用了,就会报告此状态。 + - + backend_xid @@ -533,7 +536,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser backend_xmin xid - 当前后端的xmin范围。 + 当前后端的xmin视界。 @@ -547,17 +550,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser backend_type text - - 当前后端的类型。可能的类型为 - autovacuum launcher, autovacuum worker, - logical replication launcher, - logical replication worker, - parallel worker, background writer, - client backend, checkpointer, - startup, walreceiver, - walsenderwalwriter。 - 此外,由扩展注册的后台工作进程还可能有额外的类型。 - + 当前后端的类型。可能的类型为autovacuum launcherautovacuum workerlogical replication launcherlogical replication workerparallel workerbackground writerclient backendcheckpointerstartupwalreceiverwalsenderwalwriter。此外,由扩展注册的后台工作进程还可能有额外的类型。 @@ -595,830 +588,829 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser OidGenLock 等待分配或指派 OID。 - + XidGenLock 等待分配或指派事务 ID。 - + ProcArrayLock 等待获取快照,或在事务结束时清除事务 ID。 - + SInvalReadLock 等待从共享失效队列中取出或移除消息。 - + SInvalWriteLock 等待向共享失效队列添加消息。 - + WALBufMappingLock 等待在WAL缓冲区中替换一个页面。 - + WALWriteLock 等待WAL缓冲区写入磁盘。 - + ControlFileLock 等待读取或更新控制文件,或创建新的 WAL 文件。 - + CheckpointLock 等待执行检查点。 - + CLogControlLock 等待读取或更新事务状态。 - + SubtransControlLock 等待读取或更新子事务信息。 - + MultiXactGenLock - 等待读取或更新共享的multixact状态。 + 等待读取或更新共享的多事务状态。 - + MultiXactOffsetControlLock 等待读取或更新多事务偏移映射。 - + MultiXactMemberControlLock 等待读取或更新多事务成员映射。 - + RelCacheInitLock 等待读取或写入关系缓存初始化文件。 - + CheckpointerCommLock 等待管理fsync请求。 - + TwoPhaseStateLock - 等待读取或更新已准备事务的状态。 + 等待读取或更新预备事务的状态。 - + TablespaceCreateLock 等待创建或删除表空间。 - + BtreeVacuumLock 等待读取或更新B-树索引的清理相关信息。 - + AddinShmemInitLock 等待管理共享内存中的空间分配。 - + AutovacuumLock 自动清理工作进程或启动进程正在等待更新或读取自动清理工作进程的当前状态。 - + AutovacuumScheduleLock 等待确认已选定要清理的表仍然需要清理。 - + SyncScanLock 等待获取同步扫描所用的表扫描起始位置。 - + RelationMappingLock - 等待更新用于存储目录到文件节点映射的关系映射文件。 + 等待更新用于存储系统目录到文件节点映射的关系映射文件。 - + AsyncCtlLock 等待读取或更新共享通知状态。 - + AsyncQueueLock 等待读取或更新通知消息。 - + SerializableXactHashLock - 等待获取或存储可序列化事务的信息。 + 等待获取或存储可串行化事务的信息。 - + SerializableFinishedListLock 等待访问已完成的可串行化事务列表。 - + SerializablePredicateLockListLock - 等待对可序列化事务所持有的锁列表执行操作。 + 等待对可串行化事务所持有的锁列表执行操作。 - + OldSerXidLock - 等待读取或记录相互冲突的可序列化事务。 + 等待读取或记录相互冲突的可串行化事务。 - + SyncRepLock 等待读取或更新同步副本的信息。 - + BackgroundWorkerLock 等待读取或更新后台工作进程状态。 - + DynamicSharedMemoryControlLock 等待读取或更新动态共享内存状态。 - + AutoFileLock 等待更新postgresql.auto.conf文件。 - + ReplicationSlotAllocationLock 等待分配或释放复制槽。 - + ReplicationSlotControlLock 等待读取或更新复制槽状态。 - + CommitTsControlLock 等待读取或更新事务提交时间戳。 - + CommitTsLock 等待读取或更新最近设置的事务时间戳值。 - + ReplicationOriginLock 等待设置、删除或使用复制源。 - + MultiXactTruncationLock - 等待读取或截断multixact信息。 + 等待读取或截断多事务信息。 - + OldSnapshotTimeMapLock 等待读取或更新旧的快照控制信息。 - + BackendRandomLock 等待生成随机数。 - + LogicalRepWorkerLock 等待对逻辑复制工作进程的操作完成。 - + CLogTruncationLock 等待执行txid_status,或更新该函数可用的最早事务 ID。 - + WrapLimitsVacuumLock - 等待更新事务 ID和multixact消费的限制。 + 等待更新事务 ID 和多事务消耗量的限制。 - + NotifyQueueTailLock 等待更新通知消息存储的限制。 - + clog 等待 clog(事务状态)缓冲区上的 I/O。 - + commit_timestamp 等待提交时间戳缓冲区上的 I/O。 - + subtrans 等待子事务缓冲区上的 I/O。 - + multixact_offset - 等待多事务偏移缓冲区上的 I/O。 + 等待多事务偏移量缓冲区上的 I/O。 - + multixact_member 等待 multixact_member 缓冲区上的 I/O。 - + async 等待 async(通知)缓冲区上的 I/O。 - + oldserxid 等待 oldserxid 缓冲区上的 I/O。 - + wal_insert 等待将 WAL 插入内存缓冲区。 - + buffer_content 等待读取或写入内存中的数据页。 - + buffer_io 等待数据页上的 I/O。 - + replication_origin 等待读取或更新复制进度。 - + replication_slot_io 在复制槽上等待I/O。 - + proc 等待读取或更新快速路径锁信息。 - + buffer_mapping 等待将数据块与缓冲池中的缓冲区关联。 - + lock_manager 等待添加或检查后端的锁,或者等待加入或退出锁组(用于并行查询)。 - + predicate_lock_manager 等待添加或检查谓词锁信息。 - + parallel_query_dsa 等待并行查询的动态共享内存分配锁。 - + tbm 等待 TBM 共享迭代器锁。 - + parallel_append - 在并行附加计划执行期间等待选择下一个子计划。 + 在 Parallel Append 计划执行期间等待选择下一个子计划。 - + parallel_hash_join - 等待在执行并行哈希计划期间分配或交换内存块,或者更新计数器。 + 在 Parallel Hash 计划执行期间,等待分配或交换内存块,或更新计数器。 - + Lock relation - 等待获得一个关系的锁。 + 等待获取关系上的锁。 - + extend 等待扩展一个关系。 - + frozenid - 等待升级 pg_database.datfrozenxid - 和 pg_database.datminmxid. + 等待更新 pg_database.datfrozenxidpg_database.datminmxid - + page 等待获取关系页上的锁。 - + tuple 等待获取元组上的锁。 - + transactionid 等待事务完成。 - + virtualxid 等待获取虚拟事务 ID 锁。 - + speculative token - 等待获取推测的插入锁。 + 等待获取推测插入锁。 - + object 等待获取非关系数据库对象上的锁。 - + userlock 等待获取用户锁。 - + advisory - 等待获得一个建议用户锁。 + 等待获取用户咨询锁。 - + BufferPin BufferPin 等待获取缓冲区上的钉住。 - + Activity ArchiverMain 在归档进程的主循环中等待。 - + AutoVacuumMain - 在自动清理启动过程的主循环中等待。 + 在自动清理启动进程的主循环中等待。 - + BgWriterHibernate - 在后台写入器中等待,休眠状态。 + 在后台写入器进程中休眠等待。 - + BgWriterMain - 在后台写入进程这一后台工作进程的主循环中等待。 + 在后台写入器进程(后台工作进程)的主循环中等待。 - + CheckpointerMain 在检查点进程的主循环中等待。 - + LogicalApplyMain 在逻辑应用进程的主循环中等待。 - + LogicalLauncherMain 在逻辑启动进程的主循环中等待。 - + PgStatMain 在统计收集器进程的主循环中等待。 - + RecoveryWalAll 在恢复期间等待来自流的 WAL。 - + RecoveryWalStream 在恢复期间,若所有来源(本地、归档或流)都没有可用的 WAL 数据,则在重新尝试获取 WAL 数据前等待。 - + SysLoggerMain 在 syslogger 进程的主循环中等待。 - + WalReceiverMain - 在WAL 接收进程的主循环中等待。 + 在 WAL 接收进程的主循环中等待。 - + WalSenderMain 在 WAL 发送进程的主循环中等待。 - + WalWriterMain - 在WAL写入进程的主循环中等待。 + 在 WAL 写入进程的主循环中等待。 - + Client ClientRead 等待从客户端读取数据。 - + ClientWrite 等待写入数据到客户端。 - + LibPQWalReceiverConnect - 在WAL 接收进程等待与远程服务器建立连接。 + 在 WAL 接收进程中等待与远程服务器建立连接。 - + LibPQWalReceiverReceive - 在WAL 接收进程中等待从远程服务器接收数据。 + 在 WAL 接收进程中等待从远程服务器接收数据。 - + SSLOpenServer 在尝试连接时等待SSL。 - + WalReceiverWaitStart 等待启动进程为流复制发送初始数据。 - + WalSenderWaitForWAL - 在 WAL 发送进程中等待 WAL 被刷新。 + 在 WAL 发送进程中等待 WAL 刷盘。 - + WalSenderWriteData 在 WAL 发送进程中处理 WAL 接收进程的回复时,等待任何活动。 - + Extension Extension 在扩展中等待。 - + IPC BgWorkerShutdown 等待后台工作进程关闭。 - + BgWorkerStartup 等待后台工作进程启动。 - + BtreePage - 正等待继续并行B-树扫描所需的页号变得可用。 + 等待继续并行 B-树扫描所需的页号变得可用。 - + ClogGroupUpdate 等待组领导者在事务结束时更新事务状态。 - + ExecuteGather 在执行Gather节点时等待子进程的活动。 - + Hash/Batch/Allocating - 等待一个选定的并行哈希参与者分配哈希表。 + 等待选出的 Parallel Hash 参与者分配哈希表。 - + Hash/Batch/Electing - 选举一个并行哈希参与者来分配哈希表。 + 选出负责分配哈希表的 Parallel Hash 参与者。 - + Hash/Batch/Loading - 等待其他并行哈希参与者完成哈希表的加载。 + 等待其他 Parallel Hash 参与者完成哈希表的加载。 - + Hash/Build/Allocating - 等待一个选定的并行哈希参与者分配初始哈希表。 + 等待选出的 Parallel Hash 参与者分配初始哈希表。 - + Hash/Build/Electing - 选举一个并行哈希参与者来分配初始哈希表。 + 选出负责分配初始哈希表的 Parallel Hash 参与者。 - + Hash/Build/HashingInner - 等待其他并行哈希参与者完成内部关系的散列。 + 等待其他 Parallel Hash 参与者完成对内层关系的哈希处理。 - + Hash/Build/HashingOuter - 等待其他Parallel 哈希参与者完成对外部关系的分区。 + 等待其他 Parallel Hash 参与者完成对外层关系的分区。 - + Hash/GrowBatches/Allocating - 等待选定的并行哈希参与者分配更多批处理。 + 等待选出的 Parallel Hash 参与者分配更多批次。 - + Hash/GrowBatches/Deciding - 选举一个并行哈希参与者来决定后续批次增长。 + 选出负责决定后续批次增长的 Parallel Hash 参与者。 - + Hash/GrowBatches/Electing - 选举一个并行哈希参与者来分配更多批次。 + 选出负责分配更多批次的 Parallel Hash 参与者。 - + Hash/GrowBatches/Finishing - 等待当选的平行散列参与者决定未来的批量增长。 + 等待选出的 Parallel Hash 参与者决定后续的批次增长。 - + Hash/GrowBatches/Repartitioning - 等待其他并行哈希参与者完成重新分区。 + 等待其他 Parallel Hash 参与者完成重新分区。 - + Hash/GrowBuckets/Allocating - 等待选定的并行哈希参与者完成更多bucket的分配。 + 等待选出的 Parallel Hash 参与者完成更多桶的分配。 - + Hash/GrowBuckets/Electing - 选举一个并行哈希参与者来分配更多桶。 + 选出负责分配更多桶的 Parallel Hash 参与者。 - + Hash/GrowBuckets/Reinserting - 等待其他Parallel 哈希参与者完成将元组插入到新buckets中。 + 等待其他 Parallel Hash 参与者完成向新桶插入元组。 - + LogicalSyncData 等待逻辑复制远程服务器为初始表同步发送数据。 - + LogicalSyncStateChange 等待逻辑复制远程服务器改变状态。 - + MessageQueueInternal 等待其他进程附加到共享消息队列。 - + MessageQueuePutMessage 等待将协议消息写入共享消息队列。 - + MessageQueueReceive 等待从共享消息队列接收字节。 - + MessageQueueSend 等待将字节发送到共享消息队列。 - + ParallelBitmapScan - 等待并行位图扫描被初始化。 + 等待并行位图扫描完成初始化。 - + ParallelCreateIndexScan - 等待并行CREATE INDEX 工作进程完成堆扫描。 + 等待并行 CREATE INDEX 工作进程完成堆扫描。 - + ParallelFinish - 等待并行工作人员完成计算。 + 等待并行工作进程完成计算。 - + ProcArrayGroupUpdate 等待组领导者在事务结束时清除事务 ID。 - + ReplicationOriginDrop 等待复制源变为非活动状态,以便将其删除。 - + ReplicationSlotDrop 等待复制槽变为非活动状态,以便将其删除。 - + SafeSnapshot 等待READ ONLY DEFERRABLE事务的快照。 - + SyncRep 在同步复制期间等待远程服务器的确认。 - + Timeout BaseBackupThrottle - 当有限流活动时在基础备份期间等待。 + 在基础备份期间因限流而等待。 - + PgSleep 调用pg_sleep的进程正在等待。 - + RecoveryApplyDelay 在恢复期间,由于应用 WAL 被延迟而等待。 - + IO BufFileRead 等待从缓冲文件中读取。 - + BufFileWrite 等待对缓冲文件的写入。 - + ControlFileRead 等待读取控制文件。 - + ControlFileSync - 等待控制文件写入持久存储。 + 等待控制文件同步到持久存储。 - + ControlFileSyncUpdate - 等待控制文件的更新写入持久存储。 + 等待对控制文件的更新同步到持久存储。 - + ControlFileWrite 等待写入控制文件。 - + ControlFileWriteUpdate 等待写入以更新控制文件。 - + CopyFileRead 在文件复制操作期间等待读取。 - + CopyFileWrite - 在文件拷贝操作期间等待写入。 + 在文件复制操作期间等待写入。 - + DataFileExtend 等待关系数据文件被扩展。 - + DataFileFlush - 等待关系数据文件达到持久存储。 + 等待关系数据文件同步到持久存储。 - + DataFileImmediateSync - 等待关系数据文件到持久存储的立即同步。 + 等待关系数据文件立即同步到持久存储。 - + DataFilePrefetch 等待关系数据文件的异步预取。 - + DataFileRead 等待对关系数据文件的读取。 - + DataFileSync - 等待对关系数据文件的更改达到持久存储。 + 等待对关系数据文件的更改同步到持久存储。 - + DataFileTruncate 等待关系数据文件被截断。 - + DataFileWrite 等待对关系数据文件的写入。 - + DSMFillZeroWrite - 等待将零字节写入动态共享内存的后备文件。 + 等待向动态共享内存的后备文件写入值为零的字节。 - + LockFileAddToDataDirRead 在向数据目录锁文件中添加一行时等待读取。 - + LockFileAddToDataDirSync - 等待数据到达持久存储,同时向数据目录锁文件添加一行。 + 在向数据目录锁文件中添加一行时,等待数据同步到持久存储。 - + LockFileAddToDataDirWrite 在向数据目录锁文件中添加一行时等待写操作。 - + LockFileCreateRead 创建数据目录锁文件时等待读取。 - + LockFileCreateSync - 在创建数据目录锁文件时等待数据到达持久存储。 + 在创建数据目录锁文件时,等待数据同步到持久存储。 - + LockFileCreateWrite 在创建数据目录锁文件时等待写操作。 - + LockFileReCheckDataDirRead 在重新检查数据目录锁文件期间等待读取。 - + LogicalRewriteCheckpointSync - 等待逻辑重写映射到在检查点到达持久存储。 + 在检查点期间等待逻辑重写映射同步到持久存储。 - + LogicalRewriteMappingSync - 在逻辑重写期间等待映射数据到达持久存储 + 在逻辑重写期间等待映射数据同步到持久存储。 - + LogicalRewriteMappingWrite 在逻辑重写期间等待映射数据的写入。 - + LogicalRewriteSync - 等待逻辑重写映射到达持久存储。 + 等待逻辑重写映射同步到持久存储。 - + LogicalRewriteTruncate - 等待在逻辑重写期间截断映射数据。 + 在逻辑重写期间等待截断映射数据。 - + LogicalRewriteWrite 等待逻辑重写映射的写入。 - + RelationMapRead 等待关系映射文件的读取。 - + RelationMapSync - 等待关系映射文件到达持久存储。 + 等待关系映射文件同步到持久存储。 - + RelationMapWrite 等待对关系映射文件的写入。 - + ReorderBufferRead - 在重新排序缓冲区管理期间等待读取。 + 在重排序缓冲区管理期间等待读取。 - + ReorderBufferWrite - 在重新排序缓冲区管理期间等待写操作。 + 在重排序缓冲区管理期间等待写入。 - + ReorderLogicalMappingRead - 在重新排序缓冲区管理期间等待读取逻辑映射。 + 在重排序缓冲区管理期间等待读取逻辑映射。 - + ReplicationSlotRead 等待从复制槽控制文件读取。 - + ReplicationSlotRestoreSync - 等待复制槽控制文件到达持久存储,同时将其恢复到内存中。 + 在将复制槽控制文件恢复到内存期间,等待该文件同步到持久存储。 - + ReplicationSlotSync - 等待复制槽控制文件到达持久存储。 + 等待复制槽控制文件同步到持久存储。 - + ReplicationSlotWrite 等待对复制槽控制文件的写入。 - + SLRUFlushSync - 在检查点或数据库关闭期间等待SLRU数据到达持久存储。 + 在检查点或数据库关闭期间,等待 SLRU 数据同步到持久存储。 - + SLRURead 等待读取SLRU页面。 - + SLRUSync - 在写页面后等待SLRU数据到达持久存储。 + 在页面写入后等待 SLRU 数据同步到持久存储。 - + SLRUWrite 等待SLRU页面的写入。 - + SnapbuildRead - 等待读取序列化的历史目录快照。 + 等待读取序列化的历史系统目录快照。 - + SnapbuildSync - 等待序列化历史目录快照到达持久存储。 + 等待序列化的历史系统目录快照同步到持久存储。 - + SnapbuildWrite - 等待串行历史目录快照的写入。 + 等待写入序列化的历史系统目录快照。 - + TimelineHistoryFileSync - 等待通过流复制接收的时间线历史文件到达持久存储。 + 等待通过流复制接收的时间线历史文件同步到持久存储。 - + TimelineHistoryFileWrite 等待通过流复制接收的时间线历史文件的写入。 - + TimelineHistoryRead 等待读取时间线历史文件。 - + TimelineHistorySync - 等待新创建的时间线历史文件到达持久存储。 + 等待新创建的时间线历史文件同步到持久存储。 - + TimelineHistoryWrite 等待写入新创建的时间线历史文件。 - + TwophaseFileRead 等待读取两阶段状态文件。 - + TwophaseFileSync - 等待两阶段状态文件到达持久存储。 + 等待两阶段状态文件同步到持久存储。 - + TwophaseFileWrite 等待对两阶段状态文件的写入。 - + WALBootstrapSync - 在引导过程中等待WAL达到持久存储。 + 在引导过程中等待 WAL 同步到持久存储。 - + WALBootstrapWrite 在引导过程中等待WAL页面的写入。 - + WALCopyRead 通过复制一个已有WAL段来创建一个新的WAL段时等待读取。 - + WALCopySync - 等待通过复制已有 WAL 段创建的新 WAL 段写入持久存储。 + 等待通过复制现有 WAL 段创建的新 WAL 段同步到持久存储。 - + WALCopyWrite 通过复制一个已有WAL段来创建一个新的WAL段时等待写入。 - + WALInitSync - 等待一个新初始化的WAL文件到持久存储。 + 等待新初始化的 WAL 文件同步到持久存储。 - + WALInitWrite 在初始化一个新的WAL文件时等待写入。 - + WALRead 等待WAL文件的读取。 - + WALSenderTimelineHistoryRead 在 WAL 发送进程执行时间线命令期间,等待读取时间线历史文件。 - + WALSyncMethodAssign - 在指派 WAL 同步方法时等待数据写入持久存储。 + 在设置 WAL 同步方法时,等待数据同步到持久存储。 - + WALWrite - 等待写入WAL文件。 + 等待写入 WAL 文件。 @@ -1483,7 +1475,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i inet 连接到这个 WAL 发送进程的客户端的 IP 地址。 - 如果这个域为空,它表示该客户端通过服务器机器上的一个Unix 套接字连接。 + 如果这个字段为空值,它表示该客户端通过服务器机器上的一个Unix 套接字连接。 @@ -1518,34 +1510,37 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i state text - 当前 WAL 发送进程的状态。可能的值为: + + 当前的 WAL 发送进程状态。 + 可能的值是: + - startup: 此 WAL 发送进程正在启动。 + startup: 此 WAL 发送进程正在启动。 - catchup: 与此 WAL 发送进程连接的备库正在赶上主库。 + catchup: 与此 WAL 发送进程连接的备库正在赶上主库。 - streaming: 在其连接的备库赶上主库之后,此 WAL 发送进程正在流式传输更改。 + streaming: 在其连接的备库赶上主库之后,此 WAL 发送进程正在流式传输更改。 - backup: 此 WAL 发送进程正在发送一个备份。 + backup: 此 WAL 发送进程正在发送一个备份。 - stopping: 此 WAL 发送进程正在停止。 + stopping: 此 WAL 发送进程正在停止。 - + sent_lsn @@ -1578,26 +1573,17 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i write_lag interval - - 从本地刷写最近的 WAL,到收到该备库已写入该 WAL(但尚未刷盘或应用)的通知之间经过的时间。 - 如果该服务器被配置为同步备库,可用此值衡量在提交时 synchronous_commit 级别 remote_write 所导致的延迟。 - + 从在本地将最近的 WAL 刷盘,到收到该备库已写入该 WAL(但尚未刷盘或应用)的通知之间经过的时间。如果该服务器被配置为同步备库,可用此值衡量在提交时synchronous_commit级别remote_write所导致的延迟。 flush_lag interval - - 从本地刷写最近的 WAL,到收到该备库已写入并刷写该 WAL(但尚未应用)的通知之间经过的时间。 - 如果该服务器被配置为同步备库,可用此值衡量在提交时 synchronous_commit 级别 on 所导致的延迟。 - + 从在本地将最近的 WAL 刷盘,到收到该备库已写入该 WAL 并将其刷盘(但尚未应用)的通知之间经过的时间。如果该服务器被配置为同步备库,可用此值衡量在提交时synchronous_commit级别on所导致的延迟。 replay_lag interval - - 从本地刷写最近的 WAL,到收到该备库已写入、刷写并应用该 WAL 的通知之间经过的时间。 - 如果该服务器被配置为同步备库,可用此值衡量在提交时 synchronous_commit 级别 remote_apply 所导致的延迟。 - + 从在本地将最近的 WAL 刷盘,到收到该备库已写入该 WAL、将其刷盘并应用的通知之间经过的时间。如果该服务器被配置为同步备库,可用此值衡量在提交时synchronous_commit级别remote_apply所导致的延迟。 sync_priority @@ -1609,29 +1595,32 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i sync_state text - 此备库的同步状态。可能的值为: + + 该备库的同步状态。 + 可能的值是: + - async: 该备库是异步的。 + async: 该备库是异步的。 - potential: 该备库当前是异步的,但在当前同步备库失效时可能变为同步的。 + potential: 该备库当前是异步的,但在当前某个同步备库失效时可能变为同步的。 - sync: 该备库是同步的。 + sync: 该备库是同步的。 - quorum: 该备库被作为法定人数同步复制候选备库。 + quorum: 该备库被作为法定人数同步复制候选备库。 - + @@ -1643,16 +1632,16 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i - pg_stat_replication视图中报告的滞后时间,是最近的 WAL 被写入、刷写和重放,以及发送端获知这些操作完成所花费时间的度量。如果远程服务器被配置为同步备库,这些时间表示各个同步提交级别带来或可能带来的提交延迟。对于异步备库,replay_lag列是最近事务对查询变得可见所需延迟时间的近似值。如果备库已经完全追上发送服务器且没有新的 WAL 活动,系统会在短时间内继续显示最近测得的滞后时间,随后显示为 NULL。 + pg_stat_replication视图中报告的滞后时间,是最近的 WAL 被写入、刷盘和重放,以及发送端获知这些操作完成所花费时间的度量。如果远程服务器被配置为同步备库,这些时间表示各个同步提交级别带来或可能带来的提交延迟。对于异步备库,replay_lag列是最近事务对查询变得可见所需延迟时间的近似值。如果备库已经完全追上发送服务器且没有新的 WAL 活动,系统会在短时间内继续显示最近测得的滞后时间,随后显示为空值。 - 对于物理复制,滞后时间会自动测量。逻辑解码插件可以选择发出跟踪消息;如果没有这样做,跟踪机制会将滞后显示为 NULL。 + 对于物理复制,滞后时间会自动测量。逻辑解码插件可以选择发出跟踪消息;如果没有这样做,跟踪机制会将滞后显示为空值。 - 报告出的滞后时间并不是根据当前重放速率预测该备库还需多久才能追上发送服务器。在持续生成新 WAL 时,那样的系统可能会显示相近的时间;但当发送端空闲时,就会显示不同的值。特别是当备库已经完全追上时,pg_stat_replication显示的是写入、刷写和重放最近报告的 WAL 位置所花费的时间,而不是某些用户可能预期的零。这样做符合为最近写事务测量同步提交和事务可见性延迟的目的。为减少用户因预期另一种滞后模型而产生的混淆,在一个已完全重放且处于空闲状态的系统上,lag 列会在较短时间后恢复为 NULL。监控系统应自行决定将这种情况表示为缺失数据、零,还是继续显示最近一次已知值。 + 报告出的滞后时间并不是根据当前重放速率预测该备库还需多久才能追上发送服务器。在持续生成新 WAL 时,那样的系统可能会显示相近的时间;但当发送端空闲时,就会显示不同的值。特别是当备库已经完全追上时,pg_stat_replication显示的是写入、刷盘和重放最近报告的 WAL 位置所花费的时间,而不是某些用户可能预期的零。这样做符合为最近写事务测量同步提交和事务可见性延迟的目的。为减少用户因预期另一种滞后模型而产生的混淆,在一个已完全重放且处于空闲状态的系统上,滞后列会在较短时间后恢复为空值。监控系统应自行决定将这种情况表示为缺失数据、零,还是继续显示最近一次已知值。 @@ -1672,42 +1661,42 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i pid integer - WAL 接收进程的进程ID + WAL 接收进程的进程 ID status text - WAL接收进程的活动状态 + WAL 接收进程的活动状态 receive_start_lsn pg_lsn - WAL 接收进程启动时使用的第一个写前日志位置 + WAL 接收进程启动时使用的第一个预写式日志位置 receive_start_tli integer - WAL 接收进程启动时使用的第一个时间线数字 + WAL 接收进程启动时使用的第一个时间线编号 received_lsn pg_lsn - 已经接收并刷入到磁盘的最后一个预写式日志位置,该字段的初始值是启动WAL 接收进程时使用的第一个日志位置 + 已经接收并刷入到磁盘的最后一个预写式日志位置,该字段的初始值是启动 WAL 接收进程时使用的第一个日志位置 received_tli integer - 接收并刷入到磁盘的最后一个预写式日志位置的时间线数字,该字段的初始值为启动WAL 接收进程时使用的第一个日志位置的时间线数字 + 接收并刷入到磁盘的最后一个预写式日志位置的时间线编号,该字段的初始值为启动 WAL 接收进程时使用的第一个日志位置的时间线编号 @@ -1742,38 +1731,36 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i slot_name text - 这个WAL 接收进程使用的复制槽的名称 + 这个 WAL 接收进程使用的复制槽的名称 sender_host text - 这个WAL 接收进程连接到的PostgreSQL实例的主机。 - 这可以是主机名、IP地址,或者目录路径,如果连接是通过Unix套接字进行的。(路径的情况可以区分,因为它总是以/开头的绝对路径。) + 这个 WAL 接收进程连接到的PostgreSQL实例的主机。 + 这可以是主机名、IP地址,或者目录路径,如果连接是通过Unix套接字进行的。(路径的情况可以区分,因为它总是以/开头的绝对路径。) sender_port integer - 这个WAL 接收进程连接的PostgreSQL实例的端口号。 + 这个 WAL 接收进程连接的PostgreSQL实例的端口号。 conninfo text - 这个WAL 接收进程使用的连接字符串,对安全敏感的字段进行了模糊处理。 + 这个 WAL 接收进程使用的连接字符串,对安全敏感的字段进行了模糊处理。 - - pg_stat_wal_receiver事务只包含一行,它显示了从 WAL 接收进程所连接的服务器得到的有关该接收进程的统计信息。 - + pg_stat_wal_receiver视图只包含一行,显示 WAL 接收进程从其所连接服务器接收数据的统计信息。 <structname>pg_stat_subscription</structname> 视图 @@ -1787,70 +1774,80 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i - + + subid oid 订阅的OID - + + subname text 订阅的名称 - + + pid integer 订阅工作进程的进程 ID - + + relid Oid - 该工作进程正在同步的关系的 OID;主应用工作进程则为 NULL + 该工作进程正在同步的关系的 OID;主应用工作进程则为空值 - + + received_lsn pg_lsn - 接收到的最后一个预写式日志位置,该字段的初始值为0 + 接收到的最后一个预写式日志位置,该字段的初始值为 0 - + + last_msg_send_time timestamp with time zone 从源 WAL 发送进程收到的最后一条消息的发送时间 - + + last_msg_receipt_time timestamp with time zone 从源 WAL 发送进程收到的最后一条消息的接收时间 - + + latest_end_lsn pg_lsn 向源 WAL 发送进程报告的最后一个预写式日志位置 - + + latest_end_time timestamp with time zone - 向 WAL 发送进程报告最后一个预写式日志位置的时间 + 向源 WAL 发送进程报告最后一个预写式日志位置的时间 - + +
@@ -1886,34 +1883,34 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i version text - 使用SSL的版本,如果此连接上没有使用SSL则为NULL + 使用SSL的版本,如果此连接上没有使用SSL则为空值 cipher text - 正在使用的SSL密码的名称,如果此连接上没有使用SSL则为NULL + 正在使用的SSL 密码套件的名称,如果此连接上没有使用SSL则为空值 bits integer - 使用的加密算法中的位数,如果此连接上没有使用SSL则为NULL + 使用的加密算法中的位数,如果此连接上没有使用SSL则为空值 compression boolean - 使用 SSL 压缩时为真,否则为假;如果此连接未使用 SSL,则为 NULL + 使用 SSL 压缩时为真,否则为假;如果此连接未使用 SSL,则为空值 clientdn text - 区别名称(DN,Distinguished Name)字段与使用的客户端证书,如果没有提供客户端证书或在此连接上没有使用SSL,则为NULL。 - 如果DN字段长于NAMEDATALEN(标准构建中为64个字符),则该字段将被截断。 + 所用客户端证书中的区别名称(DN,Distinguished Name)字段,如果没有提供客户端证书或在此连接上没有使用SSL,则为空值。 + 如果DN字段长于NAMEDATALEN(标准构建中为64个字符),则该字段将被截断。 @@ -1984,9 +1981,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i stats_reset timestamp with time zone - - 这些统计数据最后一次重置的时间 - + 这些统计信息上次被重置的时间 @@ -2056,7 +2051,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i buffers_backend_fsync bigint - 后端必须自行执行fsync调用的次数(通常即使后端自行写入,也由后台写入进程处理这些调用) + 后端必须自行执行fsync调用的次数(通常即使后端自行写入,也由后台写入器处理这些调用) buffers_alloc @@ -2068,16 +2063,14 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i stats_reset timestamp with time zone - - 这些统计信息上次被重置的时间 - + 这些统计信息上次被重置的时间 - pg_stat_bgwriter 视图始终只有一行,包含有关集簇后台写入器的数据。 + pg_stat_bgwriter 视图始终只有一行,包含整个集簇的全局数据。 @@ -2092,21 +2085,24 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i - + + datid oid 数据库的OID - + + datname name 数据库的名称 - + + numbackends integer @@ -2114,115 +2110,132 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i 这是该视图中唯一返回反映当前状态的值的列;所有其他列返回的都是自上次重置以来累积的值。 - + + xact_commit bigint 此数据库中已提交的事务数 - + + xact_rollback bigint 该数据库中已回滚的事务数 - + + blks_read bigint 在该数据库中读取的磁盘块数 - + + blks_hit bigint 在缓冲区缓存中发现磁盘块、因而无需读取的次数(这里只统计 PostgreSQL 缓冲区缓存中的命中,不包括操作系统文件系统缓存中的命中) - + + tup_returned bigint - 由顺序扫描获取的活动行数和由索引扫描返回的索引条目数 + 此数据库中的查询返回的行数 - + + tup_fetched bigint - 该数据库中由索引扫描检索的活动行数 + 此数据库中的查询获取的行数 - + + tup_inserted bigint 查询在该数据库中插入的行数 - + + tup_updated bigint 这个数据库中查询更新的行数 - + + tup_deleted bigint 这个数据库中被查询删除的行数 - + + conflicts bigint 由于与此数据库中的恢复冲突而被取消的查询数。(冲突只会发生在备库上;请参阅。) - + + temp_files bigint 这个数据库中查询创建的临时文件的数量。所有临时文件都将被计数,而不顾及临时文件为什么被创建(例如,排序或散列),也不考虑设置。 - + + temp_bytes bigint 这个数据库中的查询写入临时文件的数据总量。所有临时文件都将被计数,而不考虑临时文件为什么被创建,也不考虑设置。 - + + deadlocks bigint 在此数据库中检测到的死锁数 - + + blk_read_time double precision 此数据库的后端读取数据文件块所花费的时间,单位为毫秒 - + + blk_write_time double precision 此数据库的后端写入数据文件块所花费的时间,单位为毫秒 - + + stats_reset timestamp with time zone 这些统计数据最后一次重置的时间 - + +
@@ -2279,7 +2292,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i confl_bufferpin bigint - 此数据库中由于固定缓冲区而被取消的查询数 + 此数据库中由于缓冲区被钉住而被取消的查询数
@@ -2339,7 +2352,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i seq_tup_read bigint - 连续扫描获取的实时行数 + 顺序扫描获取的存活行数 @@ -2353,7 +2366,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i idx_tup_fetch bigint - 索引扫描获取的实时行数 + 索引扫描获取的存活行数 @@ -2381,7 +2394,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i n_tup_hot_upd bigint - HOT更新的行数(即,不需要单独的索引更新) + HOT 更新的行数(即不需要单独更新索引) @@ -2409,7 +2422,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i last_vacuum timestamp with time zone - 最后一次手动清理这个表(不包括VACUUM FULL) + 最后一次手动清理这个表的时间(不包括VACUUM FULL @@ -2423,21 +2436,21 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i last_analyze timestamp with time zone - 上一次手动分析这个表 + 上一次手动分析这个表的时间 last_autoanalyze timestamp with time zone - 自动清理守护进程最后一次分析这个表 + 自动清理守护进程最后一次分析这个表的时间 vacuum_count bigint - 这个表被手动清理的次数(VACUUM FULL不计数) + 这个表被手动清理的次数(VACUUM FULL不计数) @@ -2535,7 +2548,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i idx_tup_fetch bigint - 使用此索引进行简单索引扫描获取的活动表行数 + 使用此索引进行简单索引扫描获取的存活表行数 @@ -2547,13 +2560,13 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i
- 索引可以被简单索引扫描、位图索引扫描以及优化器使用。在一次位图扫描中,多个索引的输出可以被通过 AND 或 OR 规则组合,因此当使用一次位图扫描时难以将取得的个体堆行与特定的索引关联起来。因此,一次位图扫描会增加它使用的索引的pg_stat_all_indexes.idx_tup_read计数,并且为每个表增加pg_stat_all_tables.idx_tup_fetch计数,但是它不影响pg_stat_all_indexes.idx_tup_fetch。如果所提供的常量值不在优化器统计信息记录的范围之内,优化器也会访问索引来检查,因为优化器统计信息可能已经“不新鲜”了。 + 索引可以被简单索引扫描、位图索引扫描以及优化器使用。在一次位图扫描中,多个索引的输出可以被通过 AND 或 OR 规则组合,因此当使用一次位图扫描时难以将取得的个体堆行与特定的索引关联起来。因此,一次位图扫描会增加它使用的索引的pg_stat_all_indexes.idx_tup_read计数,并且为该表增加pg_stat_all_tables.idx_tup_fetch计数,但是它不影响pg_stat_all_indexes.idx_tup_fetch。如果所提供的常量值不在优化器统计信息记录的范围之内,优化器也会访问索引来检查,因为优化器统计信息可能已经过时。 - 即使不用位图扫描,idx_tup_readidx_tup_fetch计数也可能不同,因为idx_tup_read统计从该索引取得的索引项而idx_tup_fetch统计从表取得的活着的行。如果使用该索引取得了任何死亡行或还未提交的行,或者如果通过一次只用索引扫描的方式避免了任何堆获取,后者将较小。 + 即使不用位图扫描,idx_tup_readidx_tup_fetch计数也可能不同,因为idx_tup_read统计从该索引取得的索引项而idx_tup_fetch统计从表取得的存活行。如果使用该索引取得了任何死亡行或还未提交的行,或者如果通过一次仅索引扫描的方式避免了任何堆获取,后者将较小。 @@ -2622,28 +2635,28 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i toast_blks_read bigint - 从这个表的TOAST表中读取的磁盘块的数量(如果有的话) + 从这个表的TOAST表中读取的磁盘块的数量(如果有的话) toast_blks_hit bigint - 这个表的TOAST表中的缓冲区命中数(如果有的话) + 这个表的TOAST表中的缓冲区命中数(如果有的话) tidx_blks_read bigint - 从这个表的TOAST表索引中读取的磁盘块的数量(如果有的话) + 从这个表的TOAST表索引中读取的磁盘块的数量(如果有的话) tidx_blks_hit bigint - 这个表的TOAST表索引中的缓冲区命中数(如果有的话) + 这个表的TOAST表索引中的缓冲区命中数(如果有的话) @@ -3072,23 +3085,23 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, 查看锁 - lock - monitoring + + 监控 - 监控数据库活动的另外一个有用的工具是pg_locks系统表。这样就允许数据库管理员查看在锁管理器里面未解决的锁的信息。例如,这个功能可以被用于: + 监控数据库活动的另外一个有用的工具是pg_locks系统表。这样就允许数据库管理员查看锁管理器中当前存在的锁的信息。例如,这个功能可以被用于: - 查看当前所有未解决的锁、在一个特定数据库中的关系上所有的锁、在一个特定关系上所有的锁,或者由一个特定PostgreSQL会话持有的所有的锁。 + 查看当前存在的所有锁、在一个特定数据库中的关系上所有的锁、在一个特定关系上所有的锁,或者由一个特定PostgreSQL会话持有的所有的锁。 - 判断当前数据库中带有最多未授予锁的关系(它很可能是数据库客户端的竞争源)。 + 判断当前数据库中带有最多未授予锁的关系(它可能是数据库客户端之间的竞争来源)。 @@ -3150,21 +3163,21 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, relid oid - 被vacuum的表的OID。 + 正在清理的表的OID。 phase text - vacuum的当前处理阶段。参见 。 + 清理的当前处理阶段。参见 heap_blks_total bigint - 该表中堆块的总数。这个数字在扫描开始时报告,之后增加的块将不会(并且不需要)被这个VACUUM访问。 + 该表中堆块的总数。这个数字以扫描开始时的数量为准,之后增加的块将不会(并且不需要)被这个VACUUM访问。 @@ -3195,14 +3208,14 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, max_dead_tuples bigint - 在需要执行索引清理周期之前可存储的死亡元组数据量,取决于。 + 在需要执行索引清理周期之前可存储的死亡元组数量,取决于 num_dead_tuples bigint - 自上一个索引清理周期以来收集到的死亡元组数据量。 + 自上一个索引清理周期以来收集到的死亡元组数量。 @@ -3210,7 +3223,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - VACUUM的阶段 + VACUUM 阶段 @@ -3230,33 +3243,29 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, scanning heap - VACUUM正在扫描堆。如果需要,它将会对每个页面进行修建以及碎片整理,并且可能会执行冻结动作。heap_blks_scanned列可以用来监控扫描的进度。 + VACUUM正在扫描堆。如果需要,它将会对每个页面进行剪枝以及碎片整理,并且可能会执行冻结动作。heap_blks_scanned列可以用来监控扫描的进度。 vacuuming indexes - - VACUUM当前正在清理索引。 - 如果一个表拥有索引,那么每次清理时这个阶段会在堆扫描完成后至少发生一次。 - 如果不足以存放找到的死亡元组(或者, 在autovacuum情况下,如果设置了) ,则每次清理时会多次清理索引。 - + VACUUM当前正在清理索引。如果表有索引,每次清理都会在堆扫描完成后至少执行一次此阶段。如果(或者,对于自动清理,已设置的)不足以存储找到的死亡元组数量,则每次清理可能多次执行此阶段。 vacuuming heap - VACUUM当前正在清理堆。清理堆与扫描堆不是同一个概念,清理堆发生在每一次清理索引的实例之后。如果heap_blks_scanned小于heap_blks_total,系统将在这个阶段完成之后回去扫描堆;否则,系统将在这个阶段完成后开始清理索引。 + VACUUM当前正在清理堆。清理堆与扫描堆不是同一个概念,清理堆发生在每次索引清理之后。如果heap_blks_scanned小于heap_blks_total,系统将在这个阶段完成之后回去扫描堆;否则,系统将在这个阶段完成后开始索引收尾清理。 cleaning up indexes - VACUUM当前正在清除索引。这个阶段发生在堆被完全扫描并且对堆和索引的所有清理都已经完成以后。 + VACUUM当前正在进行索引收尾清理。这个阶段发生在堆被完全扫描并且对堆和索引的所有清理都已经完成以后。 truncating heap - VACUUM正在截断堆,以便把关系尾部的空页面返还给操作系统。这个阶段发生在清除完索引之后。 + VACUUM正在截断堆,以便把关系尾部的空页面返还给操作系统。这个阶段发生在索引收尾清理完成之后。 @@ -3295,7 +3304,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - 动态追踪的编译 + 为动态追踪编译 默认情况下,探针是不可用的,因此你将需要显式地告诉配置脚本让探针在PostgreSQL中可用。要包括 DTrace 支持,在配置时指定。更多信息请见。 @@ -3306,7 +3315,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, 内置探针 - 如所示,源代码中提供了一些标准探针。显式了在探针中使用的类型。当然,可以增加更多探针来增强PostgreSQL的可观测性。 + 如所示,源代码中提供了一些标准探针。显示了在探针中使用的类型。当然,可以增加更多探针来增强PostgreSQL的可观测性。
@@ -3338,13 +3347,13 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, transaction-abort (LocalTransactionId) - 当一个事务失败完成时触发的探针。arg0 是事务 ID。 + 当一个事务失败结束时触发的探针。arg0 是事务 ID。 query-start (const char *) - 当一个查询的处理被开始时触发的探针。arg0 是查询字符串。 + 当一个查询的处理开始时触发的探针。arg0 是查询字符串。 @@ -3356,7 +3365,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, query-parse-start (const char *) - 当一个查询的解析被开始时触发的探针。arg0 是查询字符串。 + 当一个查询的解析开始时触发的探针。arg0 是查询字符串。 @@ -3368,7 +3377,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, query-rewrite-start (const char *) - 当一个查询的重写被开始时触发的探针。arg0 是查询字符串。 + 当一个查询的重写开始时触发的探针。arg0 是查询字符串。 @@ -3380,7 +3389,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, query-plan-start () - 当一个查询的规划被开始时触发的探针。 + 当一个查询的规划开始时触发的探针。 @@ -3392,7 +3401,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, query-execute-start () - 当一个查询的执行被开始时触发的探针。 + 当一个查询的执行开始时触发的探针。 @@ -3410,19 +3419,19 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, checkpoint-start (int) - 当一个检查点被开始时触发的探针。arg0 传递位标志来区分不同的检查点类型,例如关闭(shutdown)、立即(immediate)或强制(force)。 + 当一个检查点开始时触发的探针。arg0 传递位标志来区分不同的检查点类型,例如关闭(shutdown)、立即(immediate)或强制(force)。 checkpoint-done (int, int, int, int, int) - 当一个检查点完成时触发的探针(检查点处理过程中序列中列出的下一个触发的探针)。arg0 是要写的缓冲区数量。arg1 是缓冲区的总数。arg2、arg3 和 arg4 分别包含了增加、删除和循环回收的 WAL 文件的数量。 + 当一个检查点完成时触发的探针(下面列出的探针会在检查点处理过程中依次触发)。arg0 是已写入的缓冲区数量。arg1 是缓冲区的总数。arg2、arg3 和 arg4 分别包含了增加、删除和循环回收的 WAL 文件的数量。 clog-checkpoint-start (bool) - 当一个检查点的 CLOG 部分被开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 + 当一个检查点的 CLOG 部分开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 @@ -3434,7 +3443,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, subtrans-checkpoint-start (bool) - 当一个检查点的 SUBTRANS 部分被开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 + 当一个检查点的 SUBTRANS 部分开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 @@ -3446,7 +3455,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, multixact-checkpoint-start (bool) - 当一个检查点的 MultiXact 部分被开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 + 当一个检查点的 MultiXact 部分开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 @@ -3458,7 +3467,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, buffer-checkpoint-start (int) - 当一个检查点的写缓冲区部分被开始时触发的探针。arg0 传递位标志来区分不同的检查点类型,例如关闭(shutdown)、立即(immediate)或强制(force)。 + 当一个检查点的写缓冲区部分开始时触发的探针。arg0 传递位标志来区分不同的检查点类型,例如关闭(shutdown)、立即(immediate)或强制(force)。 @@ -3494,7 +3503,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, twophase-checkpoint-start () - 当一个检查点的两阶段部分被开始时触发的探针。 + 当一个检查点的两阶段部分开始时触发的探针。 @@ -3506,19 +3515,19 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, buffer-read-start (ForkNumber, BlockNumber, Oid, Oid, Oid, int, bool) - 当一次缓冲区读被开始时触发的探针。arg0 和 arg1 包含该页的分叉号和块号(如果这是一次关系扩展请求,arg1 为 -1)。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是 InvalidBackendId(-1)。arg6 为真表示一次关系扩展请求,为假表示正常读。 + 当一次缓冲区读开始时触发的探针。arg0 和 arg1 包含该页的分支号和块号(如果这是一次关系扩展请求,arg1 为 -1)。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是 InvalidBackendId(-1)。arg6 为真表示一次关系扩展请求,为假表示正常读。 buffer-read-done (ForkNumber, BlockNumber, Oid, Oid, Oid, int, bool, bool) - 当一次缓冲区读完成时触发的探针。arg0 和 arg1 包含该页的分叉号和块号(如果这是一次关系扩展请求,arg1 现在包含新增加块的块号)。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是 InvalidBackendId(-1)。arg6 为真表示一次关系扩展请求,为假表示正常读。arg7 为真表示在池中找到该缓冲区,为假表示没有找到。 + 当一次缓冲区读完成时触发的探针。arg0 和 arg1 包含该页的分支号和块号(如果这是一次关系扩展请求,arg1 现在包含新增加块的块号)。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是 InvalidBackendId(-1)。arg6 为真表示一次关系扩展请求,为假表示正常读。arg7 为真表示在池中找到该缓冲区,为假表示没有找到。 buffer-flush-start (ForkNumber, BlockNumber, Oid, Oid, Oid) - 在发出对一个共享缓冲区的任意写请求之前触发的探针。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。 + 在发出对一个共享缓冲区的任意写请求之前触发的探针。arg0 和 arg1 包含该页的分支号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。 @@ -3530,7 +3539,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, buffer-write-dirty-start (ForkNumber, BlockNumber, Oid, Oid, Oid) - 当一个服务器进程开始写一个脏缓冲区时触发的探针(如果这经常发生,表示太小,或需要调整后台写入器的控制参数)。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。 + 当一个服务器进程开始写一个脏缓冲区时触发的探针(如果这经常发生,表示太小,或需要调整后台写入器的控制参数)。arg0 和 arg1 包含该页的分支号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。 @@ -3548,13 +3557,13 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, wal-buffer-write-dirty-done () - 当一次脏 WAL 缓冲区完成时触发的探针。 + 当一次脏 WAL 缓冲区写入完成时触发的探针。 wal-insert (unsigned char, unsigned char) - 当一个 WAL 记录被插入时触发的探针。arg0 是该记录的资源管理者(rmid)。arg1 包含 info 标志。 + 当一个 WAL 记录被插入时触发的探针。arg0 是该记录的资源管理器(rmid)。arg1 包含 info 标志。 @@ -3566,31 +3575,31 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, smgr-md-read-start (ForkNumber, BlockNumber, Oid, Oid, Oid, int) - 当开始从一个关系读取一块时触发的探针。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。 + 当开始从一个关系读取一块时触发的探针。arg0 和 arg1 包含该页的分支号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。 smgr-md-read-done (ForkNumber, BlockNumber, Oid, Oid, Oid, int, int, int) - 当一次块读取完成时触发的探针。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。arg6 是实际读取的字节数,而 arg7 是请求读取的字节数(如果两者不同就意味着麻烦)。 + 当一次块读取完成时触发的探针。arg0 和 arg1 包含该页的分支号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。arg6 是实际读取的字节数,而 arg7 是请求读取的字节数(如果两者不同就意味着麻烦)。 smgr-md-write-start (ForkNumber, BlockNumber, Oid, Oid, Oid, int) - 当开始向一个关系中写入一个块时触发的探针。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。 + 当开始向一个关系中写入一个块时触发的探针。arg0 和 arg1 包含该页的分支号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。 smgr-md-write-done (ForkNumber, BlockNumber, Oid, Oid, Oid, int, int, int) - 当一个块写操作完成时触发的探针。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3和arg4 包含表空间、数据库和关系 OID来标识该关系。对于一个本地缓冲区,arg5 是创建临时关系的后端 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。arg6 是实际写的字节数,而 arg7 是要求写的字节数(如果这两者不同,则意味着麻烦)。 + 当一个块写操作完成时触发的探针。arg0 和 arg1 包含该页的分支号和块号。arg2、arg3和arg4 包含表空间、数据库和关系 OID来标识该关系。对于一个本地缓冲区,arg5 是创建临时关系的后端 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。arg6 是实际写的字节数,而 arg7 是要求写的字节数(如果这两者不同,则意味着麻烦)。 sort-start (int, bool, int, int, bool, int) - 当一次排序操作开始时触发的探针。arg0 指示是堆排序、索引排序或数据排序。arg1 为真表示强制唯一值。arg2 是键列数。arg3 是允许使用的工作内存大小(以千字节计)。如果要求随机访问排序结果,则 arg4 为真。arg5 为 0 时表示串行,为 1 时表示并行工作进程,为 2 时表示并行领导者。 + 当一次排序操作开始时触发的探针。arg0 指示是堆排序、索引排序或 datum 排序。arg1 为真表示强制唯一值。arg2 是键列数。arg3 是允许使用的工作内存大小(以千字节计)。如果要求随机访问排序结果,则 arg4 为真。arg5 为 0 时表示串行,为 1 时表示并行工作进程,为 2 时表示并行领导者。 @@ -3604,7 +3613,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, (char *, LWLockMode) 当成功获得一个 LWLock 时触发的探针。 arg0 是该 LWLock 所在的切片(Tranche)。 - arg1 所请求的锁模式,是排他或共享。 + arg1 是所请求的锁模式,是排他或共享。 @@ -3619,34 +3628,34 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, (char *, LWLockMode) 当一个 LWLock不是当即可用并且一个服务器进程因此开始等待该锁变为可用时触发的探针。 arg0 是该 LWLock 所在的切片(Tranche)。 - arg1 请求的锁模式,是排他或共享。 + arg1 是所请求的锁模式,是排他或共享。 lwlock-wait-done (char *, LWLockMode) 当一个进程从对一个 LWLock 的等待中被释放时(它实际还没有得到该锁)时触发的探针。arg0 是该 LWLock 所在的切片(Tranche)。 - arg1 所请求的锁模式,是排他或共享。 + arg1 是所请求的锁模式,是排他或共享。 lwlock-condacquire (char *, LWLockMode) 当调用者指定无需等待而成功获得一个 LWLock 时触发的探针。arg0 是该 LWLock 所在的切片(Tranche)。 - arg1 所请求的锁模式,是排他或共享。 + arg1 是所请求的锁模式,是排他或共享。 lwlock-condacquire-fail (char *, LWLockMode) 当调用者指定无需等待而没有成功获得一个 LWLock 时触发的探针。arg0 是该 LWLock 所在的切片(Tranche)。 - arg1 所请求的锁模式,是排他或共享。 + arg1 是所请求的锁模式,是排他或共享。 lock-wait-start (unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, LOCKMODE) - 当一个重量级锁(lmgr锁)的请求由于锁不可用开始等待时触发的探针。arg0 到 arg3 是标识被锁定对象的标签域。arg4 指示被锁对象的类型。arg5 表示被请求的锁类型。 + 当一个重量级锁(lmgr锁)的请求由于锁不可用开始等待时触发的探针。arg0 到 arg3 是标识被锁定对象的标签字段。arg4 指示被锁对象的类型。arg5 表示被请求的锁类型。 @@ -3666,7 +3675,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid,
- 定义用在探针参数中的类型 + 探针参数中使用的已定义类型 @@ -3761,7 +3770,7 @@ Total time (ns) 2312105013 - 你应该记住,DTrace 脚本需要细心地编写和调试,否则被收集的追踪信息可能会毫无意义。在大部分发现问题的情况中,它就是发生问题的部件,而不是底层系统。当讨论使用动态追踪发现的信息时,一定要附上使用的脚本以便其也被检查和讨论。 + 你应该记住,DTrace 脚本需要细心地编写和调试,否则被收集的追踪信息可能会毫无意义。在大多数发现问题的情况下,出错的是插桩,而不是底层系统。当讨论使用动态追踪发现的信息时,一定要附上使用的脚本以便其也被检查和讨论。 @@ -3777,7 +3786,7 @@ Total time (ns) 2312105013 - 决定探针名称以及探针可用的数据 + 决定探针名称以及要通过探针提供的数据 @@ -3791,7 +3800,7 @@ Total time (ns) 2312105013 - 如果pg_trace.h还不存在于包含该探针点的模块中,包括它,并且在源代码中期望的位置插入TRACE_POSTGRESQL探针宏 + 如果pg_trace.h尚未被包含该探针点的模块引用,则将它包含进来,并且在源代码中期望的位置插入TRACE_POSTGRESQL探针宏 @@ -3827,14 +3836,14 @@ Total time (ns) 2312105013 probe transaction__start(LocalTransactionId); - 注意探针名字中双下划线的使用。在一个使用探针的 DTrace 脚本中,双下划线需要被替换为一个连字符,因此 ,对用户而言transaction-start是文档名。 + 注意探针名字中双下划线的使用。在一个使用探针的 DTrace 脚本中,双下划线需要被替换为一个连字符,因此,文档中应向用户说明的名称是transaction-start - 在编译时,transaction__start被转换成一个宏调用TRACE_POSTGRESQL_TRANSACTION_START(注意这里是单下划线),可以通过包括头文件pg_trace.h获得。将宏调用加入到源代码中的合适位置。在这种情况下,看起来类似: + 在编译时,transaction__start被转换成一个名为TRACE_POSTGRESQL_TRANSACTION_START的宏(注意这里是单下划线),可以通过包含头文件pg_trace.h获得。将宏调用加入到源代码中的合适位置。在这种情况下,看起来类似: TRACE_POSTGRESQL_TRANSACTION_START(vxid.localTransactionId); @@ -3871,7 +3880,7 @@ TRACE_POSTGRESQL_TRANSACTION_START(vxid.localTransactionId); - 在大多数平台上,如果用编译了PostgreSQL,无论何时当控制经过一个追踪宏时,都会评估该宏的参数,即使没有进行追踪也会这样做。通常不需要担心你是否只在报告一些局部变量的值。但是要注意不要将开销大的函数调用放入参数中。如果你需要这样做,考虑通过检查追踪是否真的被启用来保护该宏: + 在大多数平台上,如果用编译了PostgreSQL,无论何时当控制经过一个追踪宏时,都会对该宏的参数求值,即使没有进行追踪也会这样做。如果只是报告少数局部变量的值,通常无需担心这一点。但是要注意不要将开销大的函数调用放入参数中。如果你需要这样做,考虑通过检查追踪是否真的被启用来保护该宏: if (TRACE_POSTGRESQL_TRANSACTION_START_ENABLED()) diff --git a/zh/11/mvcc.sgml b/zh/11/mvcc.sgml index 3a10a941..3b487d3d 100644 --- a/zh/11/mvcc.sgml +++ b/zh/11/mvcc.sgml @@ -4,7 +4,7 @@ 并发控制 - concurrency + 并发 @@ -15,7 +15,7 @@ 介绍 - Multiversion Concurrency Control + 多版本并发控制 @@ -23,7 +23,7 @@ - Serializable Snapshot Isolation + 可串行化快照隔离 @@ -50,7 +50,7 @@ 事务隔离 - transaction isolation + 事务隔离 @@ -61,11 +61,14 @@ (这并不奇怪,如果事务的效果必须与一次只运行一个事务保持一致,又怎么可能看到由相互作用引起的任何现象呢?) - 各隔离级别所禁止的现象如下: + + 在各个级别上被禁止的现象有: + + 脏读 - dirty read + 脏读 @@ -77,7 +80,7 @@ 不可重复读 - nonrepeatable read + 不可重复读 @@ -89,7 +92,7 @@ 幻读 - phantom read + 幻读 @@ -101,7 +104,7 @@ 串行化异常 - serialization anomaly + 串行化异常 @@ -114,7 +117,7 @@ - transaction isolation level + 事务隔离级别 SQL 标准以及 PostgreSQL 实现的事务隔离级别见 @@ -241,12 +244,12 @@ 读已提交隔离级别 - transaction isolation level - read committed + 事务隔离级别 + 读已提交 - read committed + 读已提交 @@ -292,7 +295,7 @@ 由于上述规则,更新命令可能看到一个不一致的快照:它能够看到并发更新命令在它试图更新的同一行上的效果, 却看不到这些命令对数据库中其他行的影响。这种行为使得读已提交模式不适合涉及复杂搜索条件的命令; - 不过,对于较简单的场景它恰到好处。例如,考虑将 100 美元从一个账户转到另一个账户: + 不过,对于较简单的场景它恰到好处。例如,考虑以如下事务更新银行余额: BEGIN; @@ -301,13 +304,13 @@ UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 7534; COMMIT; - 如果另一个事务并发地尝试更改账户 7534 的余额,我们显然希望第二条语句从该账户行的已更新版本开始。 + 如果两个这样的事务并发地尝试更改账户 12345 的余额,我们显然希望第二个事务从该账户行的已更新版本开始。 因为每个命令只影响一个预先确定的行,让它看到该行的已更新版本不会造成任何麻烦的不一致。 在读已提交模式下,更复杂的用法可能产生不理想的结果。例如,考虑一个 - DELETE 命令,它所处理的数据会被另一个命令同时加入和移出其筛选条件。 + DELETE 命令,另一个命令正在修改数据,使某些行开始满足其筛选条件、另一些行不再满足。 假设 website 是一个有两行的表,其中 website.hits 分别等于 910: @@ -315,7 +318,7 @@ COMMIT; BEGIN; UPDATE website SET hits = hits + 1; --- run from another session: DELETE FROM website WHERE hits = 10; +-- 从另一个会话运行: DELETE FROM website WHERE hits = 10; COMMIT; @@ -343,12 +346,12 @@ COMMIT; 可重复读隔离级别 - transaction isolation level - repeatable read + 事务隔离级别 + 可重复读 - repeatable read + 可重复读 @@ -400,9 +403,7 @@ ERROR: could not serialize access due to concurrent update 可重复读模式提供了严格的保证,即每个事务都看到数据库的一个完全稳定的视图。 不过,这个视图并不一定总能与同一级别并发事务的某种串行(一次一个)执行保持一致。 - 例如,即使该级别上的只读事务可能看到一条控制记录被更新,表明某个批处理已经完成, - 但它并不一定能看到作为该批处理逻辑组成部分的某条明细记录, - 因为它读到的是控制记录的较早版本。如果不仔细使用显式锁来阻塞冲突事务, + 例如,即使是该级别的只读事务,也可能看到一条表明某批次已完成的控制记录,却看不到逻辑上属于该批次的某条明细记录,因为创建该明细记录的事务读取了控制记录的较早版本。如果不仔细使用显式锁来阻塞冲突事务, 试图依靠运行在这一隔离级别的事务来强制业务规则,往往无法正确工作。 @@ -410,7 +411,7 @@ ERROR: could not serialize access due to concurrent update 可重复读隔离级别是通过一种技术实现的,这种技术在学术数据库文献中以及某些其他数据库产品中被称为 快照隔离。与使用会降低并发性的传统加锁技术的系统相比, 其行为和性能可能会表现出差异。有些其他系统甚至把可重复读和快照隔离作为两个行为不同的独立隔离级别提供。 - 用来区分这两种技术的允许现象,直到 SQL 标准制定之后才被数据库研究人员正式定义,因此超出了本手册的范围。 + 用来区分这两种技术的允许现象,直到 SQL 标准制定之后才被数据库研究人员正式定义,并且超出了本手册的范围。 完整讨论请参阅 @@ -426,20 +427,20 @@ ERROR: could not serialize access due to concurrent update 可串行化隔离级别 - transaction isolation level - serializable + 事务隔离级别 + 可串行化 - serializable + 可串行化 - predicate locking + 谓词锁 - serialization anomaly + 串行化异常 @@ -469,13 +470,13 @@ ERROR: could not serialize access due to read/write dependencies among transact 当依赖可串行化事务来防止异常时,重要的是:从永久用户表读取的任何数据,在读取它的事务成功提交之前, - 都不应视为有效。即使对于只读事务也是如此;唯一的例外是可推迟只读事务中读取的数据, + 都不应视为有效。即使对于只读事务也是如此;唯一的例外是可延迟只读事务中读取的数据, 它一经读出就可视为有效,因为这种事务会等到能够获取一个保证不存在此类问题的快照后才开始读取数据。 在所有其他情况下,应用不能依赖后来被中止事务中读到的结果;相反,应重试事务直到成功。 - 为了保证真正的可串行化,PostgreSQL 使用了谓词锁, + 为了保证真正的可串行性,PostgreSQL 使用了谓词锁, 也就是说,系统会保留一些锁,以便判断某个写操作如果先发生,是否会影响并发事务先前读取的结果。 在 PostgreSQL 中,这些锁不会造成任何阻塞,因此会参与形成死锁。 它们用于识别并标记并发可串行化事务之间的依赖关系,而这些依赖在某些组合下可能导致串行化异常。 @@ -497,7 +498,7 @@ ERROR: could not serialize access due to read/write dependencies among transact - 持续使用可串行化事务可以简化开发。任何一组成功提交的并发可串行化事务,都保证与把它们一次一个运行的效果相同;这意味着,如果你能够证明某个事务在单独运行时会做正确的事,那么即使不了解其他事务会做什么,也可以相信它在任何可串行化事务的混合执行中也会做正确的事,否则它就不会成功提交。重要的是,采用这种技术的环境应当有一套通用机制来处理串行化失败(其 SQLSTATE 值总是 '40001'),因为很难准确预测究竟哪些事务会对读/写依赖关系有贡献,并因此需要被回滚来防止串行化异常。监视读/写依赖关系会带来开销,被串行化失败中止的事务重新启动也会带来开销;但在把这些开销与显式锁以及 SELECT FOR UPDATESELECT FOR SHARE 所涉及的成本和阻塞进行权衡之后,可串行化事务在某些环境中仍然是性能最佳的选择。 + 统一采用可串行化事务可以简化开发。任何一组成功提交的并发可串行化事务,都保证与把它们一次一个运行的效果相同;这意味着,如果你能够证明某个事务在单独运行时会做正确的事,那么即使不了解其他事务会做什么,也可以相信它在任何可串行化事务的混合执行中也会做正确的事,否则它就不会成功提交。重要的是,采用这种技术的环境应当有一套通用机制来处理串行化失败(其 SQLSTATE 值总是 '40001'),因为很难准确预测究竟哪些事务会对读/写依赖关系有贡献,并因此需要被回滚来防止串行化异常。监视读/写依赖关系会带来开销,被串行化失败中止的事务重新启动也会带来开销;但在把这些开销与显式锁以及 SELECT FOR UPDATESELECT FOR SHARE 所涉及的成本和阻塞进行权衡之后,可串行化事务在某些环境中仍然是性能最佳的选择。 @@ -541,7 +542,7 @@ ERROR: could not serialize access due to read/write dependencies among transact - 当系统因谓词锁表内存不足而被迫把多个页级谓词锁合并为单个关系级谓词锁时,串行化失败的比例可能会上升。你可以通过增加 来避免这种情况。 + 当系统因谓词锁表内存不足而被迫把多个页级谓词锁合并为单个关系级谓词锁时,串行化失败的比例可能会上升。你可以通过增加 和/或 来避免这种情况。 @@ -565,7 +566,7 @@ ERROR: could not serialize access due to read/write dependencies among transact 显式锁定 - lock + @@ -909,7 +910,7 @@ ERROR: could not serialize access due to read/write dependencies among transact - 行为与 FOR SHARE 类似,不过锁更弱:SELECT FOR UPDATE 会被阻塞,但 SELECT FOR NO KEY UPDATE 不会。键共享锁会阻塞其他事务执行会修改键值的 DELETEUPDATE,但不会阻塞其他 UPDATE,也不会阻止 SELECT FOR NO KEY UPDATESELECT FOR SHARESELECT FOR KEY SHARE。 + 行为与 FOR SHARE 类似,不过锁更弱:SELECT FOR UPDATE 会被阻塞,但 SELECT FOR NO KEY UPDATE 不会。键共享锁会阻塞其他事务执行 DELETE 或任何会修改键值的 UPDATE,但不会阻塞其他 UPDATE,也不会阻止 SELECT FOR NO KEY UPDATESELECT FOR SHARESELECT FOR KEY SHARE @@ -984,7 +985,7 @@ ERROR: could not serialize access due to read/write dependencies among transact 死锁 - deadlock + 死锁 @@ -1027,12 +1028,12 @@ UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 22222; 咨询锁 - advisory lock + 咨询锁 - lock - advisory + + 咨询 @@ -1064,12 +1065,12 @@ UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 22222; 在某些使用咨询锁的方法中,特别是涉及显式排序和 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(id) FROM foo WHERE id = 12345; -- 可以 +SELECT pg_advisory_lock(id) FROM foo WHERE id > 12345 LIMIT 100; -- 危险! SELECT pg_advisory_lock(q.id) FROM ( SELECT id FROM foo WHERE id > 12345 LIMIT 100 -) q; -- ok +) q; -- 可以 在上面的查询中,第二种形式是危险的,因为不能保证在执行加锁函数之前先应用 LIMIT。 这可能导致获取了一些应用并未预期的锁,因此应用也不会去释放它们(直到会话结束)。 @@ -1087,12 +1088,12 @@ SELECT pg_advisory_lock(q.id) FROM 应用级别的数据一致性检查 - 在读已提交事务下,想要通过业务规则强制数据一致性非常困难,因为数据视图会随每条语句而变化, + 用读已提交事务强制执行有关数据完整性的业务规则非常困难,因为数据视图会随每条语句而变化, 而且一旦发生写冲突,即使是单条语句也未必局限于该语句自己的快照。 - 虽然可重复读事务在整个执行期间都具有稳定的数据视图,但在使用 MVCC 快照进行数据一致性检查时,还存在一个微妙问题,即所谓的读/写冲突。如果一个事务写入数据,而并发事务试图读取相同的数据(无论是在写入之前还是之后),它都看不到另一个事务的工作。于是,读取者看起来就像是先执行的一方,而不管究竟是谁先启动,也不管谁先提交。如果事情只停留在这一步,就没有问题;但如果读取者还写入了数据,而这些数据又被另一个并发事务读取,那么现在就会有一个事务看起来像是在前面提到的任一事务之前执行。如果看起来最后执行的事务实际上最先提交,就很容易在事务执行顺序图中形成一个环。一旦出现这样的环,不借助额外机制,一致性检查就无法正确工作。 + 虽然可重复读事务在整个执行期间都具有稳定的数据视图,但在使用 MVCC 快照进行数据一致性检查时,还存在一个微妙问题,即所谓的读/写冲突。如果一个事务写入数据,而并发事务试图读取相同的数据(无论是在写入之前还是之后),它都看不到另一个事务的工作。于是,读取者看起来就像是先执行的一方,而不管究竟是谁先启动,也不管谁先提交。如果事情只停留在这一步,就没有问题;但如果读取者还写入了数据,而这些数据又被另一个并发事务读取,那么现在就会有一个事务看起来像是在前面提到的任一事务之前执行。如果看起来最后执行的事务实际上最先提交,就很容易在事务执行顺序图中形成一个环。一旦出现这样的环,不借助额外机制,完整性检查就无法正确工作。 @@ -1109,7 +1110,7 @@ SELECT pg_advisory_lock(q.id) FROM - 使用这种技术时,如果应用软件通过某个框架运行,并由该框架自动重试因串行化错误而回滚的事务,就可以避免给应用程序员带来不必要的负担。把 default_transaction_isolation 设置为 serializable 可能是个好主意。通过在触发器中检查事务隔离级别来采取某些措施,以确保不会因为疏忽或为了绕过完整性检查而使用其他事务隔离级别,也是明智的。 + 使用这种技术时,如果应用软件通过某个框架运行,并由该框架自动重试因串行化失败而回滚的事务,就可以避免给应用程序员带来不必要的负担。把 default_transaction_isolation 设置为 serializable 可能是个好主意。通过在触发器中检查事务隔离级别来采取某些措施,以确保不会因为疏忽或为了绕过完整性检查而使用其他事务隔离级别,也是明智的。 @@ -1118,8 +1119,8 @@ SELECT pg_advisory_lock(q.id) FROM - 利用可串行化事务提供的这一层完整性保护,尚未扩展到热备模式()或逻辑副本。 - 因此,使用热备或逻辑复制的用户可能希望在主库上使用可重复读和显式锁定。 + 利用可串行化事务提供的这一层完整性保护,尚未扩展到热备模式()。 + 因此,使用热备的用户可能希望在主库上使用可重复读和显式锁定。 @@ -1148,7 +1149,7 @@ SELECT pg_advisory_lock(q.id) FROM 在非可串行化的 MVCC 环境下,全局有效性检查需要额外考虑。 - 例如,一个银行应用可能希望检查一个表中的所有收入总和等于另一个表中的所有支出总和, + 例如,一个银行应用可能希望检查一个表中的贷方金额总和等于另一个表中的借方金额总和, 而这两个表都在被活跃更新。在读已提交模式下,比较两个连续的 SELECT sum(...) 命令的结果并不可靠,因为第二个查询很可能会包含第一个查询没有统计到的事务提交结果。 在单个可重复读事务中完成这两次求和,只能准确反映在该可重复读事务开始之前已提交事务的效果 @@ -1196,18 +1197,21 @@ SELECT pg_advisory_lock(q.id) FROM 锁定和索引 - index - locks + 索引 + - 虽然PostgreSQL提供了对表数据的非阻塞读写访问,但目前并非所有已实现的索引访问方法都具备这种能力。下面按索引类型说明PostgreSQL的处理方式: + + 尽管 PostgreSQL 为表数据提供了非阻塞的读写访问,但 PostgreSQL 当前实现的索引访问方法并不是每一种都能提供非阻塞的读写访问。各种索引类型的处理方式如下: + + B-树、GiSTSP-GiST 索引 - 读写访问使用短期的页级共享/排他锁。每个索引行在被取出或插入之后,锁都会立即释放。这些索引类型在不存在死锁条件的前提下提供了最高的并发性。 + 读写访问使用短期的页级共享/排他锁。每个索引行在被取出或插入之后,锁都会立即释放。这些索引类型提供最高的并发性,并且不会产生死锁。 @@ -1229,7 +1233,7 @@ SELECT pg_advisory_lock(q.id) FROM - 读写访问使用短期的页级共享/排他锁。每个索引行在被取出或插入之后,锁都会立即释放。但要注意,插入一个 GIN 索引值通常会导致每行产生多个索引键插入,因此 GIN 可能为了插入单个值而做大量工作。 + 读写访问使用短期的页级共享/排他锁。每个索引行在被取出或插入之后,锁都会立即释放。但要注意,插入一个使用 GIN 索引的值通常会导致每行产生多个索引键插入,因此 GIN 可能为了插入单个值而做大量工作。 diff --git a/zh/11/oid2name.sgml b/zh/11/oid2name.sgml index 10f87894..f1f95acd 100644 --- a/zh/11/oid2name.sgml +++ b/zh/11/oid2name.sgml @@ -8,7 +8,7 @@ oid2name 1 - Application + 应用程序 diff --git a/zh/11/parallel.sgml b/zh/11/parallel.sgml index 3a7b29ed..d644feb5 100644 --- a/zh/11/parallel.sgml +++ b/zh/11/parallel.sgml @@ -205,7 +205,7 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%'; - Parallel Append + 并行追加 每当 PostgreSQL 需要将来自多个源的行合并成一个结果集时,它就会使用 AppendMergeAppend 计划节点。这种情况常见于实现 UNION ALL 或扫描分区表时。这样的节点和其他任何计划中的情形一样,也可以用于并行计划。不过,在并行计划中,规划器也可能改用 Parallel Append 节点。 diff --git a/zh/11/pgbuffercache.sgml b/zh/11/pgbuffercache.sgml index d410e435..b2b07113 100644 --- a/zh/11/pgbuffercache.sgml +++ b/zh/11/pgbuffercache.sgml @@ -37,7 +37,7 @@ - Name + 名称 类型 引用 diff --git a/zh/11/pgcrypto.sgml b/zh/11/pgcrypto.sgml index 27779da0..0598abc0 100644 --- a/zh/11/pgcrypto.sgml +++ b/zh/11/pgcrypto.sgml @@ -210,14 +210,14 @@ gen_salt(type text [, iter_count integer ]) returns text - type参数指定哈希算法。 + type参数指定 hash 算法。 接受的类型有:desxdesmd5bf iter_count参数允许用户为支持该参数的算法指定迭代次数。 - 次数越高,密码哈希所需时间越长,从而破解它所需时间也越长。 - 不过,如果次数过高,计算一个哈希可能需要数年时间 — 这显然不切实际。 + 次数越高,对密码进行 hash 所需的时间越长,从而破解它所需时间也越长。 + 不过,如果次数过高,计算一个 hash 可能需要数年时间 — 这显然不切实际。 若省略iter_count参数,则使用默认迭代次数。 允许的iter_count值取决于算法,如所示。 @@ -255,24 +255,24 @@ gen_salt(type text [, iter_count integer ]) returns text - 为了选择合适的迭代次数,可以考虑原始 DES crypt 在当时硬件上的设计速度是每秒 4 次哈希。 - 低于每秒 4 次哈希可能会影响可用性,而高于每秒 100 次哈希则很可能过快。 + 为了选择合适的迭代次数,可以考虑原始 DES crypt 在当时硬件上的设计速度是每秒 4 次 hash。 + 低于每秒 4 次 hash 可能会影响可用性,而高于每秒 100 次 hash 则很可能过快。 - 概述了不同哈希算法之间的相对速度差异。 + 概述了不同 hash 算法之间的相对速度差异。 该表展示了在 8 字符密码上尝试所有字符组合所需的时间,假定密码只包含小写字母, 或者包含大小写字母和数字。在crypt-bf条目中, 斜杠后的数字是gen_saltiter_count参数值。
- 哈希算法速度 + Hash 算法速度 算法 - 每秒哈希次数 + 每秒 hash 次数 针对[a-z] 针对[A-Za-z0-9] 相对于md5 hash的耗时倍数 diff --git a/zh/11/pgstandby.sgml b/zh/11/pgstandby.sgml index 633b48b8..29fb3c45 100644 --- a/zh/11/pgstandby.sgml +++ b/zh/11/pgstandby.sgml @@ -8,7 +8,7 @@ pg_standby 1 - Application + 应用程序 diff --git a/zh/11/pgstatstatements.sgml b/zh/11/pgstatstatements.sgml index 1798a494..d8958321 100644 --- a/zh/11/pgstatstatements.sgml +++ b/zh/11/pgstatstatements.sgml @@ -24,7 +24,7 @@ - Name + 名称 类型 引用 diff --git a/zh/11/plhandler.sgml b/zh/11/plhandler.sgml index 7de4f9a0..e4f420f8 100644 --- a/zh/11/plhandler.sgml +++ b/zh/11/plhandler.sgml @@ -1,7 +1,7 @@ - 编写过程语言处理器 + 编写过程语言调用处理器 过程语言 @@ -16,17 +16,17 @@ 过程语言的调用处理器是一个普通函数,必须使用诸如 C 这样的编译型语言、按照版本 1 接口编写,并在 PostgreSQL 中注册为不接受参数且返回 language_handler 类型。这个特殊伪类型会将该函数标识为调用处理器,并阻止它在 SQL 命令中被直接调用。有关 C 语言调用约定和动态装载的更多细节,见 。 - 调用处理器与其他函数的调用方式相同:它接收一个指向 FunctionCallInfoData struct 的指针,其中包含参数值和被调用函数的信息,并应返回一个 Datum 结果(如果要返回 SQL 空值,还可能需要设置 FunctionCallInfoData 结构的 isnull 字段)。调用处理器与普通被调用函数的区别在于,FunctionCallInfoData 结构的 flinfo->fn_oid 字段包含的是实际要调用的函数的 OID,而不是调用处理器自身的 OID。调用处理器必须使用该字段确定应执行哪个函数。此外,传入的参数列表也是按照目标函数的声明设置的,而不是按照调用处理器的声明。 + 调用处理器与其他函数的调用方式相同:它接收一个指向 FunctionCallInfoData struct 的指针,其中包含参数值和被调用函数的信息,并应返回一个 Datum 结果(如果要返回 SQL 空值,还需要设置 FunctionCallInfoData 结构体的 isnull 字段)。调用处理器与普通被调用函数的区别在于,FunctionCallInfoData 结构体的 flinfo->fn_oid 字段包含的是实际要调用的函数的 OID,而不是调用处理器自身的 OID。调用处理器必须使用该字段确定应执行哪个函数。此外,传入的参数列表也是按照目标函数的声明设置的,而不是按照调用处理器的声明。 - 调用处理器必须从系统目录 pg_proc 中取出该函数的条目,并分析被调用函数的参数类型和返回类型。该函数的 AS 子句可在其 CREATE FUNCTION 命令对应的 prosrc 列里找到,也就是 pg_proc 行中的该列。这里通常是一段过程语言源文本,但理论上也可以是其他内容,例如某个文件的路径名,或者任何能详细告诉调用处理器该做什么的信息。 + 调用处理器必须从系统目录 pg_proc 中取出该函数的条目,并分析被调用函数的参数类型和返回类型。该函数的 CREATE FUNCTION 命令中的 AS 子句内容,保存在 pg_proc 对应行的 prosrc 列中。这里通常是一段过程语言源文本,但理论上也可以是其他内容,例如某个文件的路径名,或者任何能详细告诉调用处理器该做什么的信息。 同一个函数在执行一条 SQL 语句期间往往会被调用很多次。调用处理器可以利用 flinfo->fn_extra 字段,避免重复查找被调用函数的信息。该字段起初为 NULL,但调用处理器可以把它设置为指向与被调用函数有关的信息。在后续调用中,如果 flinfo->fn_extra 已经不是 NULL,就可以直接使用它并跳过信息查找步骤。调用处理器必须确保 flinfo->fn_extra 指向的内存至少能存活到当前查询结束,因为 FmgrInfo 数据结构可能会保留这么久。一种做法是在 flinfo->fn_mcxt 指定的内存上下文中分配这些额外数据;这类数据通常会与 FmgrInfo 本身具有相同的生命周期。不过,处理器也可以选择使用生命周期更长的内存上下文,以便跨查询缓存函数定义信息。 - 过程语言函数作为触发器调用时,不会按通常方式传入参数,但 FunctionCallInfoDatacontext 字段会指向一个 TriggerData 结构,而不是像普通函数调用那样为 NULL。语言处理器应提供让过程语言函数获取触发器信息的机制。 + 过程语言函数作为触发器调用时,不会按通常方式传入参数,但 FunctionCallInfoDatacontext 字段会指向一个 TriggerData 结构体,而不是像普通函数调用那样为 NULL。语言调用处理器应提供让过程语言函数获取触发器信息的机制。 下面是用 C 编写的过程语言处理器模板: #include "postgres.h" @@ -50,7 +50,7 @@ plsample_call_handler(PG_FUNCTION_ARGS) if (CALLED_AS_TRIGGER(fcinfo)) { /* - * Called as a trigger function + * 作为触发器函数调用 */ TriggerData *trigdata = (TriggerData *) fcinfo->context; @@ -59,7 +59,7 @@ plsample_call_handler(PG_FUNCTION_ARGS) else { /* - * Called as a function + * 作为函数调用 */ retval = ... @@ -88,7 +88,7 @@ CREATE LANGUAGE plsample 验证器函数通常应遵循 参数:如果它被关闭,就应跳过任何开销高昂或依赖上下文的检查。如果该语言允许在编译时执行代码,验证器还必须抑制会诱发此类执行的检查。特别是,pg_dump 会关闭这个参数,这样它就可以装载过程语言函数,而不必担心函数体对其他数据库对象的副作用或依赖关系。(正因为有这一要求,调用处理器不应假设验证器已经完整检查了函数。提供验证器的目的,并不是让调用处理器省略检查,而是在 CREATE FUNCTION 命令中存在明显错误时立即通知用户。)虽然究竟检查哪些内容主要由验证器函数自行决定,但要注意,核心 CREATE FUNCTION 代码只会执行附加到函数上的 SET 子句,前提是 check_function_bodies 打开。因此,当 check_function_bodies 关闭时,那些结果可能受 GUC 参数影响的检查肯定都应跳过,以避免在恢复转储时出现虚假的失败。 + linkend="guc-check-function-bodies"/> 参数:如果它被关闭,就应跳过任何开销高昂或依赖上下文的检查。如果该语言允许在编译时执行代码,验证器还必须抑制会诱发此类执行的检查。特别是,pg_dump 会关闭这个参数,这样它就可以装载过程语言函数,而不必担心副作用或函数体对其他数据库对象的依赖关系。(正因为有这一要求,调用处理器不应假设验证器已经完整检查了函数。提供验证器的目的,并不是让调用处理器省略检查,而是在 CREATE FUNCTION 命令中存在明显错误时立即通知用户。)虽然究竟检查哪些内容主要由验证器函数自行决定,但要注意,只有在 check_function_bodies 打开时,核心 CREATE FUNCTION 代码才会执行函数附带的 SET 子句。因此,当 check_function_bodies 关闭时,那些结果可能受 GUC 参数影响的检查肯定都应跳过,以避免在恢复转储时出现虚假的失败。 diff --git a/zh/11/plperl.sgml b/zh/11/plperl.sgml index 43e64828..bbf5afad 100644 --- a/zh/11/plperl.sgml +++ b/zh/11/plperl.sgml @@ -12,7 +12,7 @@ - PL/Perl 是一种可载入的过程语言,它允许使用 + PL/Perl 是一种可加载的过程语言,它允许使用 Perl 编程语言编写 PostgreSQL 函数和过程。 @@ -31,8 +31,7 @@ - 如果把该语言安装到 template1 中,之后创建的所有 - 数据库都会自动安装该语言。 + 如果把某种语言安装到template1中,之后创建的所有数据库都会自动安装该语言。 @@ -48,11 +47,21 @@ PL/Perl 函数和参数 - 要创建 PL/Perl 语言函数,请使用标准的 语法: + + 要用 PL/Perl 语言创建一个函数,可使用标准的 + 语法: + + CREATE FUNCTION funcname (argument-types) RETURNS return-type AS $$ - # PL/Perl function body + # PL/Perl 函数体 $$ LANGUAGE plperl; -函数体就是普通的 Perl 代码。实际上,PL/Perl 的衔接代码会将其包装在一个 Perl 子例程中。PL/Perl 函数在标量上下文中调用,因此不能返回列表。可以通过返回引用来返回非标量值(数组、记录和集合),详见下文。 + + + 函数的主体就是普通的 Perl 代码。事实上,PL/Perl 的粘合代码会把它 + 包裹在一个 Perl 子程序中。PL/Perl 函数在标量上下文中被调用,因此 + 不能返回列表。如下文所述,可以通过返回引用来返回 + 非标量值(数组、记录和集合)。 + 在 PL/Perl 过程中,Perl 代码返回的任何值都会被忽略。 @@ -63,7 +72,7 @@ $$ LANGUAGE plperl; DO $$ - # PL/Perl code + # PL/Perl 代码 $$ LANGUAGE plperl; @@ -121,15 +130,14 @@ $$ LANGUAGE plperl; 如果一个 SQL 空值空值in PL/Perl被传给一个函数,在 - Perl 中该参数值将呈现为undefined。上述函数定义对于 - 空输入的行为并不理想(实际上,它会把它们当作零)。我们可以在函数 + sortas="PL/Perl">在 PL/Perl 中被传给一个函数,在 + Perl 中该参数值将呈现为未定义。上述函数定义对于 + 空值输入的行为并不理想(实际上,它会把它们当作零)。我们可以在函数 定义中添加 STRICT,让 PostgreSQL 采取更合理的做法:如果传入空值, - 函数将根本不会被调用,而是自动返回空结果。另一种方式是在函数体中 + 函数将根本不会被调用,而是自动返回空值结果。另一种方式是在函数体中 检查未定义输入。例如,假设我们希望在 - perl_max 的两个参数中一个为空、另一个非空时, - 返回非空参数而不是空值: + perl_max 的两个参数中一个为空值、另一个非空值时,返回非空值参数而不是空值: CREATE FUNCTION perl_max (integer, integer) RETURNS integer AS $$ @@ -189,12 +197,12 @@ CREATE OR REPLACE FUNCTION concat_array_elements(text[]) RETURNS TEXT AS $$ my $result = ""; return undef if (!defined $arg); - # as an array reference + # 作为数组引用 for (@$arg) { $result .= $_; } - # also works as a string + # 也可以作为字符串使用 $result .= $arg; return $result; @@ -205,7 +213,8 @@ SELECT concat_array_elements(ARRAY['PL','/','Perl']); - 多维数组会以所有 Perl 程序员都熟悉的方式,表示为对低维数组引用的引用。 + 多维数组按 Perl 程序员熟悉的方式表示为指向较低维数组的引用, + 而这些数组的元素又是引用。 @@ -314,11 +323,11 @@ SELECT * FROM perl_set(); 如果希望在代码中使用 strict 编译指示,可以有几种 选择。对于临时的全局用法,可以 SET - plperl.use_strict 为 true。这会影响后续编译的 + plperl.use_strict 为真。这会影响后续编译的 PL/Perl 函数,但不会影响当前会话中已经编译的 函数。对于永久的全局用法,可以在 postgresql.conf 文件中将 - plperl.use_strict 设为 true。 + plperl.use_strict 设为真。 @@ -363,7 +372,7 @@ use strict; spi_exec_query(query [, limit]) spi_exec_query - in PL/Perl + 在 PL/Perl 中 @@ -377,11 +386,19 @@ use strict; -只有在确定结果集会比较小时,才应使用此命令。下面是一个查询(SELECT 命令)的示例,指定了可选的最大行数: +只有在确定结果集会比较小时,才应使用此命令。下面是一个带可选最大行数的查询(SELECT 命令)示例: + + $rv = spi_exec_query('SELECT * FROM my_table', 5); -这会返回最多 5 行,来自表 my_table。如果 my_table 包含列 my_column,就可以取得结果中第 $i 行的该列值,方法如下: + + 这样会从表 my_table 返回最多 5 行。如果 + my_table 有一列 my_column, + 可以像下面这样从结果的第 $i 行取得该值: + $foo = $rv->{rows}[$i]->{my_column}; -要取得 SELECT 查询返回的总行数,可以这样做: + + 可以这样访问 SELECT 查询返回的总行数: + $nrows = $rv->{processed} @@ -439,21 +456,21 @@ SELECT * FROM test_munge(); spi_query(command) spi_query - in PL/Perl + 在 PL/Perl 中 spi_fetchrow(cursor) spi_fetchrow - in PL/Perl + 在 PL/Perl 中 spi_cursor_close(cursor) spi_cursor_close - in PL/Perl + 在 PL/Perl 中 @@ -473,7 +490,7 @@ CREATE OR REPLACE FUNCTION lotsa_md5 (INTEGER) RETURNS SETOF foo_type AS $$ my $file = '/usr/share/dict/words'; my $t = localtime; elog(NOTICE, "opening file $file at $t" ); - open my $fh, '<', $file # ooh, it's a file access! + open my $fh, '<', $file # 注意,这里访问了文件! or elog(ERROR, "cannot open $file for reading: $!"); my @words = <$fh>; close $fh; @@ -512,40 +529,55 @@ SELECT * from lotsa_md5(500); spi_prepare(command, argument types) spi_prepare - in PL/Perl + 在 PL/Perl 中 spi_query_prepared(plan, arguments) spi_query_prepared - in PL/Perl + 在 PL/Perl 中 spi_exec_prepared(plan [, attributes], arguments) spi_exec_prepared - in PL/Perl + 在 PL/Perl 中 spi_freeplan(plan) spi_freeplan - in PL/Perl + 在 PL/Perl 中 - spi_preparespi_query_preparedspi_exec_prepared,以及 spi_freeplan 实现相同的功能,但用于预备查询。spi_prepare 接受包含编号参数占位符($1、$2 等)的查询字符串,以及由参数类型字符串组成的列表: + spi_preparespi_query_prepared、 + spi_exec_preparedspi_freeplan + 提供相同的功能,但用于预备查询。spi_prepare + 接受一个带编号参数占位符($1、$2 等)的查询字符串,以及参数类型的 + 字符串列表: + $plan = spi_prepare('SELECT * FROM test WHERE id > $1 AND name = $2', 'INTEGER', 'TEXT'); -调用 spi_prepare 预备查询计划后,就可以使用该计划代替查询字符串。可以将其用于 spi_exec_prepared,其结果与以下函数返回的结果相同:spi_exec_query;也可以用于 spi_query_prepared,它返回游标,行为与 spi_query 完全相同。随后可以将该游标传给 spi_fetchrowspi_exec_prepared 可选的第二个参数是属性哈希引用;目前唯一支持的属性是 limit,用于设置查询返回的最大行数。省略 limit 或将其指定为零,表示不限制行数。 + + 一旦通过调用 spi_prepare 准备好查询计划,就可以用它 + 代替字符串查询。可以在 spi_exec_prepared 中使用, + 此时结果与 spi_exec_query 返回的结果相同;也可以在 + spi_query_prepared 中使用,它会像 + spi_query 一样返回一个游标,随后可传给 + spi_fetchrowspi_exec_prepared + 的可选第二个参数是属性哈希引用;目前唯一支持的属性是 + limit,它用于设置查询返回的最大行数。省略 + limit 或将其指定为零时,不会限制返回行数。 + - 预处理查询的优点在于,一个准备好的计划可以用于多次查询执行。当计划 + 预备查询的优点在于,一个准备好的计划可以用于多次查询执行。当计划 不再需要时,可以用 spi_freeplan 将其释放: CREATE OR REPLACE FUNCTION init() RETURNS VOID AS $$ @@ -621,14 +653,14 @@ SELECT release_hosts_query(); spi_commit() spi_commit - in PL/Perl + 在 PL/Perl 中 spi_rollback() spi_rollback - in PL/Perl + 在 PL/Perl 中 @@ -667,7 +699,7 @@ CALL transaction_test1(); - PL/Perl 中的工具函数 + PL/Perl 中的辅助函数 @@ -675,7 +707,7 @@ CALL transaction_test1(); elog(level, msg) elog - in PL/Perl + 在 PL/Perl 中 @@ -700,7 +732,7 @@ CALL transaction_test1(); quote_literal(string) quote_literal - in PL/Perl + 在 PL/Perl 中 @@ -720,7 +752,7 @@ CALL transaction_test1(); quote_nullable(string) quote_nullable - in PL/Perl + 在 PL/Perl 中 @@ -738,7 +770,7 @@ CALL transaction_test1(); quote_ident(string) quote_ident - in PL/Perl + 在 PL/Perl 中 @@ -756,7 +788,7 @@ CALL transaction_test1(); decode_bytea(string) decode_bytea - in PL/Perl + 在 PL/Perl 中 @@ -773,7 +805,7 @@ CALL transaction_test1(); encode_bytea(string) encode_bytea - in PL/Perl + 在 PL/Perl 中 @@ -789,7 +821,7 @@ CALL transaction_test1(); encode_array_literal(array) encode_array_literal - in PL/Perl + 在 PL/Perl 中 @@ -811,7 +843,7 @@ CALL transaction_test1(); encode_typed_literal(value, typename) encode_typed_literal - in PL/Perl + 在 PL/Perl 中 @@ -828,7 +860,7 @@ CALL transaction_test1(); encode_array_constructor(array) encode_array_constructor - in PL/Perl + 在 PL/Perl 中 @@ -848,7 +880,7 @@ CALL transaction_test1(); looks_like_number(string) looks_like_number - in PL/Perl + 在 PL/Perl 中 @@ -867,11 +899,15 @@ CALL transaction_test1(); is_array_ref(argument) is_array_ref - in PL/Perl + 在 PL/Perl 中 - 如果给定参数可以作为数组引用处理,即参数的 ref 为 ARRAYPostgreSQL::InServer::ARRAY,则返回真值;否则返回假值。 + + 如果给定参数可被视为数组引用,则返回真值;也就是该参数的 + ref 值为 ARRAY 或 + PostgreSQL::InServer::ARRAY。否则返回假值。 + @@ -920,9 +956,9 @@ CREATE OR REPLACE FUNCTION myfuncs() RETURNS void AS $$ }; $$ LANGUAGE plperl; -SELECT myfuncs(); /* initializes the function */ +SELECT myfuncs(); /* 初始化函数 */ -/* Set up a function that uses the quote function */ +/* 创建一个使用加引号函数的函数 */ CREATE OR REPLACE FUNCTION use_quote(TEXT) RETURNS text AS $$ my $text_to_quote = shift; @@ -937,11 +973,9 @@ $$ LANGUAGE plperl; - 出于安全原因,PL/Perl 会为某个 SQL 角色调用的函数在该角色专用的独立 - Perl 解释器中执行。这可以防止一个用户意外或恶意地干扰另一个用户的 + 出于安全原因,PL/Perl 会在每个 SQL 角色各自独立的 Perl 解释器中执行该角色调用的函数。这可以防止一个用户意外或恶意地干扰另一个用户的 PL/Perl 函数行为。每个这样的解释器都有自己的 - %_SHARED 变量值和其他全局状态。因此,只有在两个 - PL/Perl 函数都由同一 SQL 角色执行时,它们才会共享 + %_SHARED 变量值和其他全局状态。因此,当且仅当两个 PL/Perl 函数都由同一 SQL 角色执行时,它们才会共享 %_SHARED 的值。在某些应用中,一个会话可能会在多个 SQL 角色下执行代码(通过 SECURITY DEFINER 函数、 使用 SET ROLE 等),这时可能需要显式采取措施, @@ -953,20 +987,20 @@ $$ LANGUAGE plperl; - 可信与不可信的 PL/Perl + 受信任与不受信任的 PL/Perl - trusted + 受信任的 PL/Perl 通常,PL/Perl 会被安装为一种名为 plperl 的 - 可信编程语言。在这种设置下,为了保持安全性,某些 Perl + 受信任的编程语言。在这种设置下,为了保持安全性,某些 Perl 操作会被禁用。一般来说,受限制的是那些与环境交互的操作,包括文件句柄 操作、requireuse (针对外部模块)。它无法像 C 函数那样访问数据库服务器进程的内部, - 也无法以服务器进程的权限获取操作系统级访问。因此,可以允许任何无权限 + 也无法以服务器进程的权限获取操作系统级访问。因此,可以允许任何无特权 的数据库用户使用这种语言。 @@ -988,16 +1022,16 @@ $$ LANGUAGE plperl; 有时需要编写不受这些限制的 Perl 函数。例如,可能需要一个能发送邮件的 Perl 函数。为处理这类情况,也可以把 PL/Perl 安装成一种 - 不可信语言(通常称为 + 不受信任的语言(通常称为 PL/PerlUPL/PerlU)。 在这种情况下,完整的 Perl 语言都可用。安装该语言时,使用语言名 - plperlu 就会选择不可信的 PL/Perl 变体。 + plperlu 就会选择不受信任的 PL/Perl 变体。 PL/PerlU 函数的编写者必须注意,函数不能被 用于任何非预期用途,因为它能够执行以数据库管理员身份登录的用户所能 - 做的任何事情。请注意,数据库系统只允许数据库超级用户用不可信语言创建 + 做的任何事情。请注意,数据库系统只允许数据库超级用户用不受信任的语言创建 函数。 @@ -1045,7 +1079,13 @@ $$ LANGUAGE plperl; PL/Perl 触发器 - 可以用 PL/Perl 编写触发器函数。在触发器函数中,哈希引用 $_TD 包含当前触发器事件的信息。$_TD 是全局变量,每次触发器调用都有独立的局部值。以下是 $_TD 哈希引用的字段: + + PL/Perl 可用于编写触发器函数。在触发器函数中,哈希引用 + $_TD 包含有关当前触发器事件的信息。 + $_TD 是一个全局变量,对触发器的每一次调用都会得到 + 一个单独的局部值。$_TD 哈希引用包含以下字段: + + $_TD->{new}{foo} @@ -1125,7 +1165,7 @@ $$ LANGUAGE plperl; $_TD->{relname} - 触发该触发器的表名。该字段已废弃,并且可能会在未来版本中移除。 + 触发该触发器的表名。该字段已弃用,并且可能会在未来版本中移除。 请改用 $_TD->{table_name}。 @@ -1161,7 +1201,10 @@ $$ LANGUAGE plperl; - 行级触发器可以返回以下值之一: + + 行级触发器可以返回下列之一: + + return; @@ -1191,7 +1234,9 @@ $$ LANGUAGE plperl; - 下面的触发器函数示例演示了上述部分内容: + + 下面是一个触发器函数示例,用于说明上述部分内容: + CREATE TABLE test ( i int, v varchar @@ -1199,12 +1244,12 @@ CREATE TABLE test ( CREATE OR REPLACE FUNCTION valid_id() RETURNS trigger AS $$ if (($_TD->{new}{i} >= 100) || ($_TD->{new}{i} <= 0)) { - return "SKIP"; # skip INSERT/UPDATE command + return "SKIP"; # 跳过 INSERT/UPDATE 命令 } elsif ($_TD->{new}{v} ne "immortal") { $_TD->{new}{v} .= "(modified by trigger)"; - return "MODIFY"; # modify row and execute INSERT/UPDATE command + return "MODIFY"; # 修改行并执行 INSERT/UPDATE 命令 } else { - return; # execute INSERT/UPDATE command + return; # 执行 INSERT/UPDATE 命令 } $$ LANGUAGE plperl; @@ -1218,7 +1263,13 @@ CREATE TRIGGER test_valid_id_trig PL/Perl 事件触发器 - 可以用 PL/Perl 编写事件触发器函数。在事件触发器函数中,哈希引用 $_TD 包含当前触发器事件的信息。$_TD 是全局变量,每次触发器调用都有独立的局部值。以下是 $_TD 哈希引用的字段: + + PL/Perl 可用于编写事件触发器函数。在事件触发器函数中,哈希引用 + $_TD 包含有关当前触发器事件的信息。 + $_TD 是一个全局变量,对触发器的每一次调用都会得到 + 一个单独的局部值。$_TD 哈希引用包含以下字段: + + $_TD->{event} @@ -1243,7 +1294,9 @@ CREATE TRIGGER test_valid_id_trig 触发器函数的返回值会被忽略。 - 下面的事件触发器函数示例演示了上述部分内容: + + 下面是一个事件触发器函数示例,用于说明上述部分内容: + CREATE OR REPLACE FUNCTION perlsnitch() RETURNS event_trigger AS $$ elog(NOTICE, "perlsnitch: " . $_TD->{event} . " " . $_TD->{tag} . " "); $$ LANGUAGE plperl; @@ -1351,7 +1404,7 @@ DO 'elog(WARNING, join ", ", sort keys %INC)' LANGUAGE plperl; 也会发生。这是在 plperl.on_init 完成的任何初始化 之后进行的。执行这段代码时 SPI 函数不可用。 plperl.on_plperl_init 中的 Perl 代码是在对解释器 - 进行锁定之后执行的,因此只能执行可信操作。 + 进行锁定之后执行的,因此只能执行受信任的操作。 @@ -1392,7 +1445,10 @@ DO 'elog(WARNING, join ", ", sort keys %INC)' LANGUAGE plperl; 限制与缺失特性 - PL/Perl 目前还缺少以下功能,欢迎贡献这些功能的实现。 + + PL/Perl 目前仍缺少下列特性,但欢迎为此作出贡献。 + + PL/Perl 函数不能直接调用彼此。 diff --git a/zh/11/plpgsql.sgml b/zh/11/plpgsql.sgml index 7e975791..03c1ee74 100644 --- a/zh/11/plpgsql.sgml +++ b/zh/11/plpgsql.sgml @@ -11,7 +11,9 @@ 概述 - PL/pgSQL是一种可装载的过程语言,适用于PostgreSQL数据库系统。PL/pgSQL的设计目标是创建一种具有以下特点的可装载过程语言: + PL/pgSQL 是一种用于 PostgreSQL 数据库系统的可载入过程语言。PL/pgSQL 的设计目标,是创建一种具备以下特性的可载入过程语言: + + 可用于创建函数、过程和触发器, @@ -137,7 +139,7 @@ CREATE FUNCTION somefunc(integer, text) RETURNS integer AS 'function body text' LANGUAGE plpgsql; - 就 CREATE FUNCTION 而言,函数体目前只是一个字符串字面量。编写函数体时,通常最好使用美元引用(见 ),而不是普通的单引号语法。如果不使用美元引用,函数体中的任何单引号或反斜线都必须通过双写进行转义。本章几乎所有示例的函数体都使用了美元引用。 + 就 CREATE FUNCTION 而言,函数体只是一个字符串字面量。编写函数体时,通常最好使用美元引用(见 ),而不是普通的单引号语法。如果不使用美元引用,函数体中的任何单引号或反斜线都必须通过双写进行转义。本章几乎所有示例的函数体都使用了美元引用。 @@ -320,7 +322,7 @@ $$ LANGUAGE plpgsql; - 当 PL/pgSQL 函数声明了输出参数时,输出参数也会像普通输入参数一样获得 $n 名称和可选别名。输出参数本质上是一个初始值为 NULL 的变量,应在函数执行期间给它赋值。该参数的最终值就是返回值。例如,sales-tax 的示例也可以这样写: + 当 PL/pgSQL 函数声明了输出参数时,输出参数也会像普通输入参数一样获得 $n 名称和可选别名。输出参数本质上是一个初始值为 NULL 的变量,应在函数执行期间给它赋值。该参数的最终值就是返回值。例如,销售税的示例也可以这样写: CREATE FUNCTION sales_tax(subtotal real, OUT tax real) AS $$ @@ -333,14 +335,19 @@ $$ LANGUAGE plpgsql; 注意这里省略了 RETURNS real — 当然也可以写上,但那只是冗余。 - 输出参数在返回多个值时最有用。一个简单的例子是: + + 当需要返回多个值时,输出参数尤其有用。下面是一个简单示例: + + CREATE FUNCTION sum_n_product(x int, y int, OUT sum int, OUT prod int) AS $$ BEGIN sum := x + y; prod := x * y; END; $$ LANGUAGE plpgsql; -所述,这实际上为函数结果创建了一个匿名记录类型。如果给出RETURNS子句,它必须写为RETURNS record。 + + + 如 所述,这实际上会为函数结果创建一个匿名记录类型。如果写了 RETURNS 子句,它必须是 RETURNS record @@ -431,7 +438,9 @@ user_id users.user_id%TYPE; 使用 %TYPE 的好处是,你不必知道所引用结构的实际数据类型;更重要的是,如果被引用项的数据类型将来发生变化(例如把 user_id 的类型从 integer 改成 real),你可能就不需要修改函数定义。 - %TYPE在多态函数中特别有用,因为内部变量所需的数据类型可能在各次调用之间发生变化。可以对函数参数或结果占位符应用%TYPE,以创建适当的变量。 + + %TYPE 在多态函数中特别有价值,因为内部变量所需的数据类型可能在不同调用之间变化。可以把 %TYPE 应用到函数参数或结果占位符上,以创建合适的变量。 + @@ -447,9 +456,13 @@ user_id users.user_id%TYPE; 复合类型的变量称为变量(或行类型变量)。只要查询的列集合与该变量声明的类型相匹配,这种变量就可以保存 SELECTFOR 查询结果中的整行。行值的各个字段可以使用通常的点号记法访问,例如 rowvar.field - 可以使用table_name%ROWTYPE记号,将行变量声明为与现有表或视图的行具有相同类型;也可以通过给出复合类型名称来声明它。(因为每个表都有一个同名的关联复合类型,所以在PostgreSQL中,实际上写不写%ROWTYPE都没有区别。但带有%ROWTYPE的形式更易于移植。) + + 行变量既可以通过 table_name%ROWTYPE 记法声明为与现有表或视图的行具有相同类型,也可以通过给出某个复合类型的名称来声明。(由于每个表都有一个同名的关联复合类型,所以在 PostgreSQL 中实际上写不写 %ROWTYPE 并无区别;不过带 %ROWTYPE 的形式可移植性更好。) + - 函数参数可以是复合类型(完整的表行)。在这种情况下,相应的标识符$n将是一个行变量,可以从中选取字段,例如$1.user_id + + 函数参数也可以是复合类型(完整的表行)。在这种情况下,相应的标识符 $n 就是一个行变量,并且可以从中选取字段,例如 $1.user_id。 + 下面是一个使用复合类型的示例。table1table2 是已经存在的表,它们至少包含下面提到的字段: @@ -491,12 +504,12 @@ SELECT merge_fields(t.*) FROM table1 t WHERE ... ; <application>PL/pgSQL</application>变量的排序规则 - collation - in PL/pgSQL + 排序规则 + 在 PL/pgSQL 中 - 当 PL/pgSQL 函数具有一个或多个可排序数据类型参数时,每次函数调用都会根据分配给实际参数的排序规则确定出一个排序规则,如 所述。如果该排序规则能成功确定出来(即参数之间的隐式排序规则没有冲突),那么所有可排序参数都会被视为隐式带有该排序规则。这会影响函数中那些受排序规则影响的操作。例如,考虑 + 当 PL/pgSQL 函数具有一个或多个支持排序规则的数据类型参数时,每次函数调用都会根据分配给实际参数的排序规则确定出一个排序规则,如 所述。如果该排序规则能成功确定出来(即参数之间的隐式排序规则没有冲突),那么所有支持排序规则的参数都会被视为隐式带有该排序规则。这会影响函数中那些受排序规则影响的操作。例如,考虑 CREATE FUNCTION less_than(a text, b text) RETURNS boolean AS $$ @@ -513,7 +526,7 @@ SELECT less_than(text_field_1, text_field_2 COLLATE "C") FROM table1; - 此外,确定出的排序规则也会被视为任何可排序数据类型局部变量的排序规则。因此,即使把这个函数写成下面这样,其行为也不会有任何不同: + 此外,确定出的排序规则也会被视为任何支持排序规则的数据类型局部变量的排序规则。因此,即使把这个函数写成下面这样,其行为也不会有任何不同: CREATE FUNCTION less_than(a text, b text) RETURNS boolean AS $$ @@ -528,11 +541,11 @@ $$ LANGUAGE plpgsql; - 如果函数没有可排序数据类型的参数,或者无法为它们确定共同排序规则,那么参数和局部变量将使用其数据类型的默认排序规则(通常是数据库默认排序规则,但对于域类型变量也可能不同)。 + 如果函数没有支持排序规则的数据类型的参数,或者无法为它们确定共同排序规则,那么参数和局部变量将使用其数据类型的默认排序规则(通常是数据库默认排序规则,但对于域类型变量也可能不同)。 - 通过在可排序数据类型局部变量的声明中加入 COLLATE 选项,可以为其指定不同的排序规则,例如 + 通过在支持排序规则的数据类型局部变量的声明中加入 COLLATE 选项,可以为其指定不同的排序规则,例如 DECLARE @@ -637,12 +650,12 @@ PERFORM create_mv('cs_session_page_requests_mv', my_query); SELECT INTO - in PL/pgSQL + 在 PL/pgSQL 中 RETURNING INTO - in PL/pgSQL + 在 PL/pgSQL 中 产生单行(可能有多列)结果的 SQL 命令,其结果可以赋给记录变量、行类型变量或标量变量列表。方法是在基本 SQL 命令中添加INTO子句。例如: @@ -683,7 +696,7 @@ END; 成功执行带有STRICT的命令总会将FOUND设为真。 - 对于带有RETURNINGINSERT/UPDATE/DELETE/即使没有指定STRICTPL/pgSQL也会针对多于一个返回行的情况报告一个错误。这是因为没有类似于ORDER BY的选项可以用来决定应该返回哪个被影响的行。 + 对于带有RETURNINGINSERT/UPDATE/DELETE,即使没有指定STRICTPL/pgSQL也会针对多于一个返回行的情况报告一个错误。这是因为没有类似于ORDER BY的选项可以用来决定应该返回哪个被影响的行。 如果print_strict_params已为该函数启用,那么当不满足STRICT要求而抛出错误时,错误消息的DETAIL部分将包含传给查询的参数信息。可以为所有函数更改print_strict_params设置,方法是设置plpgsql.print_strict_params,不过只会影响随后编译的函数。也可以通过编译器选项逐函数启用,例如: @@ -720,25 +733,23 @@ CONTEXT: PL/pgSQL function get_userid(text) line 6 at SQL statement 执行动态命令 - 很多时候你将想要在PL/pgSQL函数中产生动态命令,也就是每次执行中会涉及到不同表或不同数据类型的命令。PL/pgSQL通常对于命令所做的缓存计划尝试(如中讨论)在这种情境下无法工作。要处理这一类问题,需要提供EXECUTE语句: + 很多时候你将想要在PL/pgSQL函数中产生动态命令,也就是每次执行中会涉及到不同表或不同数据类型的命令。PL/pgSQL通常对于命令所做的缓存计划尝试(如中讨论)在这种情境下无法工作。要处理这一类问题,提供了EXECUTE语句: EXECUTE command-string INTO STRICT target USING expression , ... ; - 其中command-string是一个能得到一个包含要被执行命令字符串(类型text)的表达式。可选的target是一个记录变量、一个行变量或者一个逗号分隔的简单变量以及记录/行域的列表,该命令的结果将存储在其中。可选的USING表达式提供要被插入到该命令中的值。 + 其中command-string是一个能得到一个包含要被执行命令字符串(类型text)的表达式。可选的target是一个记录变量、一个行变量或者一个逗号分隔的简单变量以及记录/行字段的列表,该命令的结果将存储在其中。可选的USING表达式提供要被插入到该命令中的值。 在计算得到的命令字符串中,不会做PL/pgSQL变量的替换。任何所需的变量值必须在命令字符串被构造时被插入其中,或者你可以使用下面描述的参数。 - - 还有,对于通过EXECUTE执行的命令不会有计划被缓存。该命令反而在每次运行时都会被做计划。因此,该命令字符串可以在执行不同表和列上动作的函数中被动态创建。 - + 此外,通过 EXECUTE 执行的命令不会缓存计划,而是在每次运行该语句时重新规划。因此,可以在函数中动态构造命令字符串,对不同的表和列执行操作。 - INTO子句指定一个返回行的 SQL 命令的结果应该被赋值到哪里。如果提供了一个行或变量列表,它必须完全匹配查询命令结果的结构(当一个记录变量被提供时,它会自动把它自己配置为匹配结果结构)。如果返回多个行,只有第一个行会被赋值给INTO变量。如果没有返回行,NULL 会被赋值给INTO变量。如果没有指定INTO子句,该查询结果会被抛弃。 + INTO子句指定一个返回行的 SQL 命令的结果应该被赋值到哪里。如果提供了一个行变量或变量列表,它必须完全匹配查询命令结果的结构(当一个记录变量被提供时,它会自动把它自己配置为匹配结果结构)。如果返回多个行,只有第一个行会被赋值给INTO变量。如果没有返回行,NULL 会被赋值给INTO变量。如果没有指定INTO子句,该查询结果会被抛弃。 @@ -746,7 +757,7 @@ EXECUTE command-string INT - 命令字符串可以使用参数值,它们在命令中用$1$2等引用。这些符号引用在USING子句中提供的值。这种方法常常更适合于把数据值作为文本插入到命令字符串中:它避免了将该值转换为文本以及转换回来的运行时负荷,并且它更不容易被 SQL 注入攻击,因为不需要引用或转义。一个示例是: + 命令字符串可以使用参数值,它们在命令中用$1$2等引用。这些符号引用在USING子句中提供的值。这种方法通常比把数据值作为文本插入命令字符串更可取:它避免了将该值转换为文本以及转换回来的运行时负荷,并且它更不容易被 SQL 注入攻击,因为不需要引用或转义。一个示例是: EXECUTE 'SELECT count(*) FROM mytable WHERE inserted_by = $1 AND inserted <= $2' INTO c @@ -768,7 +779,7 @@ EXECUTE format('SELECT count(*) FROM %I ' 参数符号的另一个限制是,它们只能用于SELECTINSERTUPDATE以及DELETE命令。在其他语句类型(统称为工具语句)中,即使只是数据值,也必须以文本形式插入。 - 在上面第一个示例中,带有一个简单的常量命令字符串和一些USING参数的EXECUTE命令在功能上等效于直接用PL/pgSQL写的命令,并且允许自动发生PL/pgSQL变量替换。重要的不同之处在于,EXECUTE会在每一次执行时根据当前的参数值重新计划该命令,而PL/pgSQL则是创建一个通用计划并且将其缓存以便重用。在最佳计划强依赖于参数值的情况中,使用EXECUTE来明确地保证不会选择一个通用计划是很有帮助的。 + 在上面第一个示例中,带有一个简单的常量命令字符串和一些USING参数的EXECUTE命令在功能上等效于直接用PL/pgSQL写的命令,并且允许自动发生PL/pgSQL变量替换。重要的不同之处在于,EXECUTE会在每一次执行时根据当前的参数值重新计划该命令,而PL/pgSQL则可能创建一个通用计划并且将其缓存以便重用。在最佳计划强依赖于参数值的情况中,使用EXECUTE来明确地保证不会选择一个通用计划是很有帮助的。 @@ -839,19 +850,19 @@ EXECUTE 'UPDATE tbl SET ' || ' WHERE key = ' || quote_nullable(keyvalue); - 如果正在处理的参数值可能为空,那么通常应该用quote_nullable来代替quote_literal。 + 如果正在处理的参数值可能为空值,那么通常应该用quote_nullable来代替quote_literal - 通常,必须小心地确保查询中的空值不会递送意料之外的结果。例如如果keyvalue为空,下面的WHERE子句 + 通常,必须小心地确保查询中的空值不会产生意料之外的结果。例如如果keyvalue为空值,下面的WHERE子句 'WHERE key = ' || quote_nullable(keyvalue) - 永远不会成功,因为在=操作符中使用空操作数得到的结果总是为空。如果想让空和一个普通键值一样工作,你应该将上面的命令重写成 + 永远不会成功,因为在=操作符中使用空值操作数得到的结果总是空值。如果想让空值像普通键值一样工作,你应该将上面的命令重写成 'WHERE key IS NOT DISTINCT FROM ' || quote_nullable(keyvalue) - (目前,IS NOT DISTINCT FROM的处理效率不如=,因此只有在非常必要时才这样做。关于空和IS DISTINCT的详细信息请见)。 + (目前,IS NOT DISTINCT FROM的处理效率不如=,因此只有在非常必要时才这样做。关于空值和IS DISTINCT的详细信息请见)。 @@ -864,7 +875,7 @@ EXECUTE 'UPDATE tbl SET ' || '$$ WHERE key = ' || quote_literal(keyvalue); - 因为如果newvalue的内容碰巧含有$$,那么这段代码就会出问题。同样的缺点可能适用于你选择的任何其他美元符号引用定界符。因此,要想安全地引用事先不知道的文本,必须恰当地使用quote_literalquote_nullablequote_ident。 + 因为如果newvalue的内容碰巧含有$$,那么这段代码就会出问题。同样的问题也适用于你选择的任何其他美元符号引用定界符。因此,要想安全地引用事先不知道的文本,必须恰当地使用quote_literalquote_nullablequote_ident @@ -902,7 +913,7 @@ EXECUTE format('UPDATE tbl SET %I = $1 WHERE key = $2', colname) GET CURRENT DIAGNOSTICS variable { = | := } item , ... ; - 这条命令允许检索系统状态指示符。CURRENT是一个噪声词(另见中的GET STACKED DIAGNOSTICS)。每个item是一个关键字, 它标识一个要被赋予给指定变量的状态值(变量应具有正确的数据类型来接收状态值)。中展示了当前可用的状态项。冒号等号(:=)可以被用来取代 SQL 标准的=符号。例如: + 这条命令允许检索系统状态指示符。CURRENT是一个噪声词(另见中的GET STACKED DIAGNOSTICS)。每个item是一个关键字, 它标识一个要被赋予给指定variable的状态值(变量应具有正确的数据类型来接收状态值)。中展示了当前可用的状态项。冒号等号(:=)可以被用来取代 SQL 标准的=符号。例如: GET DIAGNOSTICS integer_var = ROW_COUNT; @@ -939,10 +950,15 @@ GET DIAGNOSTICS integer_var = ROW_COUNT;
- 确定命令执行效果的第二种方法是检查名为FOUND的特殊变量,其类型为booleanFOUND的初始值为假,这适用于每次PL/pgSQL函数调用。以下各类语句都会设置它: + + 第二种确定命令效果的方法是检查名为FOUND的特殊变量,类型为boolean。 + 在每次PL/pgSQL函数调用中,FOUND的初始值都是 false。 + 它由以下类型的语句设置: + + - SELECT INTO语句在分配行时将FOUND设置为true, + SELECT INTO语句在为目标赋上一行值时将FOUND设置为true, 如果没有返回行则设置为false。 @@ -971,7 +987,7 @@ GET DIAGNOSTICS integer_var = ROW_COUNT; FORFOREACH语句在迭代一次或多次时将 FOUND设置为true,否则设置为false。 - 当循环退出时,FOUND被设置为这种方式; + 当循环退出时,FOUND会按上述方式设置; 在循环执行过程中,FOUND不会被循环语句修改, 尽管它可能会被循环体内的其他语句执行修改。 @@ -983,7 +999,11 @@ GET DIAGNOSTICS integer_var = ROW_COUNT; 如果没有返回行则设置为false。 - 其他PL/pgSQL语句不会改变以下变量的状态:FOUND。特别要注意的是,EXECUTE会改变GET DIAGNOSTICS的输出,但不会改变FOUND。 +
+ + 其他PL/pgSQL语句不会改变FOUND的状态。 + 特别注意,EXECUTE会改变GET DIAGNOSTICS的输出, + 但不会改变FOUND
@@ -1003,12 +1023,14 @@ NULL; - 例如,下面两个代码片段是等价的: + + 例如,下面的两段代码是等价的: + BEGIN y := x / 0; EXCEPTION WHEN division_by_zero THEN - NULL; -- ignore the error + NULL; -- 忽略错误 END; @@ -1016,9 +1038,11 @@ END; BEGIN y := x / 0; EXCEPTION - WHEN division_by_zero THEN -- ignore the error + WHEN division_by_zero THEN -- 忽略错误 END; -选用哪一种取决于个人偏好。 + + 究竟使用哪一种取决于各人的喜好。 +
@@ -1056,7 +1080,7 @@ RETURN expression; - 如果函数返回的是标量类型,表达式结果会自动转换为函数的返回类型。但如果要返回一个组合(行)值,你必须写出一个恰好生成所需列集合的表达式。这可能需要显式类型转换。 + 如果函数返回的是标量类型,表达式结果会按照赋值部分的说明自动转换为函数的返回类型。但如果要返回一个复合(行)值,你必须写出一个恰好生成所需列集合的表达式。这可能需要显式类型转换。 @@ -1068,17 +1092,20 @@ RETURN expression; - 一个函数的返回值不能是未定义。如果控制到达了函数最顶层的块而没有碰到一个RETURN语句,那么会发生一个运行时错误。不过,这个限制不适用于带输出参数的函数以及返回void的函数。在这些情况中,如果顶层的块结束,将自动执行一个RETURN语句。 + 一个函数的返回值不能是未定义。如果控制到达了函数最顶层块的末尾而没有碰到一个RETURN语句,那么会发生一个运行时错误。不过,这个限制不适用于带输出参数的函数以及返回void的函数。在这些情况中,如果顶层的块结束,将自动执行一个RETURN语句。 - 下面是一些例子: --- functions returning a scalar type + + 一些示例: + + +-- 返回一个标量类型的函数 RETURN 1 + 2; RETURN scalar_var; --- functions returning a composite type +-- 返回一个复合类型的函数 RETURN composite_type_var; -RETURN (1, 2, 'three'::text); -- must cast columns to correct types +RETURN (1, 2, 'three'::text); -- 必须把列类型转换成正确的类型 @@ -1087,11 +1114,11 @@ RETURN (1, 2, 'three'::text); -- must cast columns to correct types <command>RETURN NEXT</command> 和 <command>RETURN QUERY</command> RETURN NEXT - in PL/pgSQL + 在 PL/pgSQL 中 RETURN QUERY - in PL/pgSQL + 在 PL/pgSQL 中 @@ -1101,7 +1128,7 @@ RETURN QUERY EXECUTE command-string < - 当 PL/pgSQL 函数被声明为返回 SETOF sometype 时,返回过程会略有不同。在这种情况下,要返回的各个项通过一系列 RETURN NEXTRETURN QUERY 命令指定,最后再用一个不带参数的 RETURN 命令表明函数已经执行完毕。RETURN NEXT 可用于标量和组合数据类型;对于组合结果类型,会返回完整的结果RETURN QUERY 会把查询执行结果追加到函数的结果集中。在同一个集合返回函数中,RETURN NEXTRETURN QUERY 可以自由混用,此时它们的结果会被串接起来。 + 当 PL/pgSQL 函数被声明为返回 SETOF sometype 时,返回过程会略有不同。在这种情况下,要返回的各个项通过一系列 RETURN NEXTRETURN QUERY 命令指定,最后再用一个不带参数的 RETURN 命令表明函数已经执行完毕。RETURN NEXT 可用于标量和复合数据类型;对于复合结果类型,会返回完整的结果RETURN QUERY 会把查询执行结果追加到函数的结果集中。在同一个集合返回函数中,RETURN NEXTRETURN QUERY 可以自由混用,此时它们的结果会被串接起来。 @@ -1116,7 +1143,8 @@ RETURN QUERY EXECUTE command-string < 如果你声明函数带有输出参数,只需要写不带表达式的RETURN NEXT。在每一次执行时,输出参数变量的当前值将被保存下来用于最终返回为结果的一行。注意为了创建一个带有输出参数的集合返回函数,在有多个输出参数时,你必须声明函数为返回SETOF record;或者如果只有一个类型为sometype的输出参数时,声明函数为SETOF sometype - 下面的函数示例使用了RETURN NEXT: + + 下面是一个使用RETURN NEXT的函数示例: CREATE TABLE foo (fooid INT, foosubid INT, fooname TEXT); @@ -1131,8 +1159,8 @@ BEGIN FOR r IN SELECT * FROM foo WHERE fooid > 0 LOOP - -- can do some processing here - RETURN NEXT r; -- return current row of SELECT + -- 这里可以做一些处理 + RETURN NEXT r; -- 返回 SELECT 的当前行 END LOOP; RETURN; END; @@ -1143,7 +1171,8 @@ SELECT * FROM get_all_foo(); - 下面的函数示例使用了RETURN QUERY: + + 这里是一个使用RETURN QUERY的函数的示例: CREATE FUNCTION get_available_flightid(date) RETURNS SETOF integer AS @@ -1154,8 +1183,8 @@ BEGIN WHERE flightdate >= $1 AND flightdate < ($1 + 1); - -- Since execution is not finished, we can check whether rows were returned - -- and raise exception if not. + -- 因为执行还未结束,我们可以检查是否有行被返回 + -- 如果没有就抛出异常。 IF NOT FOUND THEN RAISE EXCEPTION 'No flight at %.', $1; END IF; @@ -1165,8 +1194,7 @@ BEGIN $BODY$ LANGUAGE plpgsql; --- Returns available flights or raises exception if there are no --- available flights. +-- 返回可用的航班或者在没有可用航班时抛出异常。 SELECT * FROM get_available_flightid(CURRENT_DATE); @@ -1337,7 +1365,7 @@ ELSIF number > 0 THEN ELSIF number < 0 THEN result := 'negative'; ELSE - -- 嗯,唯一的其他可能性是数字为空 + -- 嗯,唯一的其他可能性是 number 为 null result := 'NULL'; END IF; @@ -1440,12 +1468,12 @@ END CASE; 简单循环 - loop + 循环 在 PL/pgSQL 中 - 使用LOOPEXITCONTINUEWHILEFORFOREACH语句,你可以安排PL/pgSQL重复一系列命令。 + 使用LOOPEXITCONTINUEWHILEFORFOREACH语句,你可以安排PL/pgSQL函数重复一系列命令。 @@ -1491,26 +1519,28 @@ EXIT label WHEN BEGIN 块一起使用时,EXIT 会把控制转交给该块结束后的下一条语句。需要注意的是,为此必须使用标签;未加标签的 EXIT 永远不会被视为匹配某个 BEGIN 块。这与 PostgreSQL 8.4 之前的版本不同,旧版本允许未加标签的 EXIT 匹配 BEGIN 块。 - 例如: + + 示例: + LOOP - -- some computations + -- 一些计算 IF count > 0 THEN - EXIT; -- exit loop + EXIT; -- 退出循环 END IF; END LOOP; LOOP - -- some computations - EXIT WHEN count > 0; -- same result as previous example + -- 一些计算 + EXIT WHEN count > 0; -- 和前一个示例相同的结果 END LOOP; <<ablock>> BEGIN - -- some computations + -- 一些计算 IF stocks > 100000 THEN - EXIT ablock; -- causes exit from the BEGIN block + EXIT ablock; -- 导致从 BEGIN 块中退出 END IF; - -- computations here will be skipped when stocks > 100000 + -- 当stocks > 100000时,这里的计算将被跳过 END; @@ -1540,7 +1570,9 @@ CONTINUE label WHEN CONTINUE可以被用在所有类型的循环中,它并不限于在无条件循环中使用。 - 例如: + + 示例: + LOOP -- 一些计算 EXIT WHEN count > 100; @@ -1597,22 +1629,22 @@ END LOOP label ; - 这种形式的FOR会创建一个在一个整数范围上迭代的循环。变量name会自动定义为类型integer并且只在循环内存在(任何该变量名的现有定义在此循环内都将被忽略)。给出范围上下界的两个表达式在进入循环的时候计算一次。如果没有指定BY子句,迭代步长为 1,否则步长是BY中指定的值,该值也只在循环进入时计算一次。如果指定了REVERSE,那么在每次迭代后步长值会被减除而不是增加。 + 这种形式的FOR会创建一个在一个整数范围上迭代的循环。变量name会自动定义为类型integer并且只在循环内存在(任何该变量名的现有定义在此循环内都将被忽略)。给出范围上下界的两个表达式在进入循环的时候计算一次。如果没有指定BY子句,迭代步长为 1,否则步长是BY中指定的值,该值也只在循环进入时计算一次。如果指定了REVERSE,那么在每次迭代后会减去步长,而不是加上步长。 整数FOR循环的一些示例: FOR i IN 1..10 LOOP - -- 我在循环中将取值 1,2,3,4,5,6,7,8,9,10 + -- i 在循环中将取值 1,2,3,4,5,6,7,8,9,10 END LOOP; FOR i IN REVERSE 10..1 LOOP - -- 我在循环中将取值 10,9,8,7,6,5,4,3,2,1 + -- i 在循环中将取值 10,9,8,7,6,5,4,3,2,1 END LOOP; FOR i IN REVERSE 10..1 BY 2 LOOP - -- 我在循环中将取值 10,8,6,4,2 + -- i 在循环中将取值 10,8,6,4,2 END LOOP; @@ -1675,7 +1707,7 @@ $$ LANGUAGE plpgsql; - 在这类 FOR 语句中使用的 query,可以是任何向调用者返回行的 SQL 命令:最常见的是 SELECT,但也可以是带 RETURNING 子句的 INSERTUPDATEDELETE。某些实用程序命令,如 EXPLAIN,也可以用于此处。 + 在这类 FOR 语句中使用的 query,可以是任何向调用者返回行的 SQL 命令:最常见的是 SELECT,但也可以是带 RETURNING 子句的 INSERTUPDATEDELETE。某些工具命令,如 EXPLAIN,也可以用于此处。 PL/pgSQL变量会被替换到查询文本中,并且如中详细讨论的,查询计划会被缓存以用于可能的重用。 @@ -1688,7 +1720,7 @@ FOR target IN EXECUTE text_expressionstatements END LOOP label ; - 这个示例类似前面的形式,只不过源查询被指定为一个字符串表达式,在每次进入FOR循环时都会计算它并且重新计划。这允许程序员在一个预先计划好了的命令的速度和一个动态命令的灵活性之间进行选择,就像一个纯EXECUTE语句那样。在使用EXECUTE时,可以通过USING将参数值插入到动态命令中。 + 这个示例类似前面的形式,只不过源查询被指定为一个字符串表达式,在每次进入FOR循环时都会计算它并且重新计划。这允许程序员在一个预先计划好了的命令的速度和一个动态命令的灵活性之间进行选择,就像一个纯EXECUTE语句那样。与EXECUTE一样,可以通过USING将参数值插入到动态命令中。 @@ -1725,7 +1757,7 @@ END; $$ LANGUAGE plpgsql; - 元素会按存储顺序访问,而不管数组有多少维。尽管target通常只是单个变量,但在遍历组合值(记录)数组时,它也可以是一个变量列表。在这种情况下,每个数组元素都会按组合值的连续列给这些变量赋值。 + 元素会按存储顺序访问,而不管数组有多少维。尽管target通常只是单个变量,但在遍历复合值(记录)数组时,它也可以是一个变量列表。在这种情况下,每个数组元素都会按复合值的连续列给这些变量赋值。 @@ -1757,8 +1789,8 @@ NOTICE: row = {10,11,12} 捕获错误 - exceptions - in PL/pgSQL + 异常 + 在 PL/pgSQL 中 @@ -1817,7 +1849,7 @@ END; - 进入和退出一个包含EXCEPTION子句的块要比不包含该子句的块开销大的多。因此,只在必要的时候使用EXCEPTION。 + 进入和退出一个包含EXCEPTION子句的块要比不包含该子句的块开销大得多。因此,只在必要的时候使用EXCEPTION @@ -1844,9 +1876,9 @@ BEGIN IF found THEN RETURN; END IF; - -- 不在这里,那么尝试插入该键 + -- 该键不存在,因此尝试插入 -- 如果其他某人并发地插入同一个键, - -- 我们可能得到一个唯一键失败 + -- 就可能发生违反唯一约束的错误 BEGIN INSERT INTO db(a,b) VALUES (key, data); RETURN; @@ -1884,7 +1916,7 @@ SELECT merge_db(1, 'dennis'); GET STACKED DIAGNOSTICS variable { = | := } item , ... ; - 每个item是一个关键词,它标识一个被赋予给指定变量(应该具有接收该值的正确数据类型)的状态值。中显示了当前可用的状态项。 + 每个item是一个关键词,它标识一个被赋予给指定variable(应该具有接收该值的正确数据类型)的状态值。中显示了当前可用的状态项。 @@ -1992,7 +2024,7 @@ END; 获得执行位置信息 - GET DIAGNOSTICS(之前在中描述)命令检索有关当前执行状态的信息(反之上文讨论的GET STACKED DIAGNOSTICS命令会把有关执行状态的信息报告成一个以前的错误)。它的PG_CONTEXT状态项可用于标识当前执行位置。状态项PG_CONTEXT将返回一个文本字符串,其中有描述该调用栈的多行文本。第一行会指向当前函数以及当前正在执行GET DIAGNOSTICS的命令。第二行及其后的行表示调用栈中更上层的调用函数。例如: + GET DIAGNOSTICS(之前在中描述)命令检索有关当前执行状态的信息(反之上文讨论的GET STACKED DIAGNOSTICS命令报告先前发生错误时的执行状态信息)。它的PG_CONTEXT状态项可用于标识当前执行位置。状态项PG_CONTEXT将返回一个文本字符串,其中包含一行或多行描述该调用栈的文本。第一行会指向当前函数以及当前正在执行的GET DIAGNOSTICS命令。第二行及其后的行表示调用栈中更上层的调用函数。例如: CREATE OR REPLACE FUNCTION outer_func() RETURNS integer AS $$ @@ -2035,7 +2067,7 @@ CONTEXT: PL/pgSQL function outer_func() line 3 at RETURN 游标 - cursor + 游标 在 PL/pgSQL 中 @@ -2067,7 +2099,7 @@ DECLARE - 当游标查询使用 FOR UPDATE/SHARE 时,不能使用 SCROLL 选项。此外,对于涉及易失函数的查询,最好使用 NO SCROLLSCROLL 的实现假定重新读取查询输出会得到一致的结果,而易失函数并不满足这一假设。 + 当游标查询使用 FOR UPDATE/SHARE 时,不能使用 SCROLL 选项。此外,对于涉及易失函数的查询,最好使用 NO SCROLLSCROLL 的实现假定重新读取查询输出会得到一致的结果,而易失函数可能无法满足这一假设。 @@ -2145,7 +2177,9 @@ OPEN bound_cursorvar ( 位置或命名记号可以传递参数值。在位置记号中,所有参数都必须按照顺序指定。在命名记号中,每一个参数的名字使用:=与参数表达式分隔。类似于中描述的调用函数,也允许混合位置和命名记号。 - 例如(使用前面的游标声明示例): + + 示例(这些示例使用上面示例中的游标声明): + OPEN curs2; OPEN curs3(42); OPEN curs3(key := 42); @@ -2371,12 +2405,17 @@ COMMIT; 遍历游标结果 - 有一种FOR语句的变体可以遍历游标返回的行。其语法为: + + 有一种FOR语句的变体,它允许通过游标返回的行进行迭代。语法是: + + <<label>> FOR recordvar IN bound_cursorvar ( argument_name := argument_value , ... ) LOOP statements END LOOP label ; -游标变量必须在声明时绑定到某个查询,并且此时不能处于已打开状态。FOR语句会自动打开该游标,并在循环退出时将其关闭。当且仅当游标声明为接受参数时,才必须给出实际参数值表达式列表。这些值会被替换到查询中,其方式与执行以下命令时相同:OPEN(见)。 + + + 该游标变量必须在声明时已经被绑定到某个查询,并且它不能已经被打开。FOR语句会自动打开游标,并且在退出循环时自动关闭游标。当且仅当游标被声明要使用参数时,才必须出现一个实际参数值表达式的列表。这些值会被替换到查询中,采用OPEN期间的方式(见)。 @@ -2471,7 +2510,9 @@ RAISE ; level(如果有)之后,可以指定一个format字符串(必须是简单的字符串字面量,不能是表达式)。格式字符串指定要报告的错误消息文本。格式字符串之后可以跟上可选的参数表达式,其值将被插入消息中。在格式字符串内,%会被替换为下一个可选参数值的字符串表示。写成%%可以输出一个字面的%。参数个数必须与格式字符串中%占位符的个数匹配,否则会在函数编译期间报错。 - 在这个例子中,v_job_id的值会替换字符串中的% + + 在这个示例中,v_job_id的值将替换字符串中的%: + RAISE NOTICE 'Calling cs_create_job(%)', v_job_id; @@ -2483,7 +2524,7 @@ RAISE NOTICE 'Calling cs_create_job(%)', v_job_id; MESSAGE - 设置错误消息文本。如果RAISE采用了在USING之前包含格式字符串的形式,则不能使用此选项。 + 设置错误消息文本。该选项不能用于在USING之前包含格式字符串的RAISE形式。 @@ -2497,14 +2538,14 @@ RAISE NOTICE 'Calling cs_create_job(%)', v_job_id; HINT - 提供提示消息。 + 提供一个提示消息。 ERRCODE - 指定要报告的错误码(SQLSTATE),可以使用中所示的条件名,也可以直接使用五个字符的 SQLSTATE 代码。 + 指定要报告的错误代码(SQLSTATE),可以用中所示的条件名,或者直接作为一个五字符 SQLSTATE 代码。 @@ -2515,7 +2556,7 @@ RAISE NOTICE 'Calling cs_create_job(%)', v_job_id; TABLE SCHEMA - 提供相关对象的名称。 + 提供一个相关对象的名称。 @@ -2527,23 +2568,33 @@ RAISE EXCEPTION 'Nonexistent ID --> %', user_id - 这两个例子展示了设置 SQLSTATE 的等价方式: + + 这两个示例展示了设置 SQLSTATE 的两种等价的方法: + RAISE 'Duplicate user ID: %', user_id USING ERRCODE = 'unique_violation'; RAISE 'Duplicate user ID: %', user_id USING ERRCODE = '23505'; - 还有第二种RAISE语法,其主要参数是要报告的条件名或 SQLSTATE,例如: + + 还有第二种RAISE语法,其中主参数是要报告的条件名或 SQLSTATE,例如: + RAISE division_by_zero; RAISE SQLSTATE '22012'; -在这种语法中,USING可以用来提供自定义的错误消息、详细信息或提示。前面例子的另一种写法是 + + 在这种语法中,USING可以用来提供自定义的错误消息、细节或提示。另一种达到前面示例同样效果的方式是: + RAISE unique_violation USING MESSAGE = 'Duplicate user ID: ' || user_id; - 还有一种变体是写成RAISE USINGRAISE level USING,并把其余所有内容放入USING列表。 + + 还有另一种变体是写RAISE USINGRAISE level USING,并把其余内容都放在USING列表里。 + - 最后一种RAISE变体完全不带参数。这种形式只能用于BEGIN块的EXCEPTION子句内部;它会重新抛出当前正在处理的错误。 + + RAISE的最后一种变体根本没有参数。这种形式只能被用在一个BEGIN块的EXCEPTION子句中,它导致当前正在被处理的错误被重新抛出。 + @@ -2561,7 +2612,7 @@ RAISE unique_violation USING MESSAGE = 'Duplicate user ID: ' || user_id; - 当用 SQLSTATE 代码指定错误代码时,你并不受限于预定义错误代码,而是可以选择任何由五位数字和/或大写 ASCII 字母构成的错误代码,唯一不能使用的是 00000。我们建议尽量避免抛出以三个零结尾的错误代码,因为这些是类别代码,只能用于捕获整个类别。 + 当用 SQLSTATE 代码指定错误代码时,你并不受限于预定义错误代码,而是可以选择任何由五位数字和/或大写 ASCII 字母构成的错误代码,唯一不能使用的是 00000。我们建议尽量避免抛出以三个零结尾的错误代码,因为这些是类别代码,只能通过捕获整个类别来捕获这类错误。 @@ -2573,12 +2624,12 @@ RAISE unique_violation USING MESSAGE = 'Duplicate user ID: ' || user_id; ASSERT - in PL/pgSQL + 在 PL/pgSQL 中 - assertions - in PL/pgSQL + 断言 + 在 PL/pgSQL 中 @@ -2595,15 +2646,14 @@ ASSERT condition , condition是一个布尔 表达式,它被期望总是计算为真。如果确实如此, - ASSERT语句不会再做什么。但如果结果是假 - 或者空,那么将发生一个ASSERT_FAILURE异常(如果在计算 + ASSERT语句不会再做什么。但如果结果是假或者空值,那么将发生一个ASSERT_FAILURE异常(如果在计算 condition时发生错误, 它会被报告为一个普通错误)。 如果提供了可选的message, - 它是一个结果(如果非空)被用来替换默认错误消息文本 + 它是一个结果(如果不为 NULL)被用来替换默认错误消息文本 assertion failed的表达式(如果 condition失败)。 message表达式在 @@ -2757,11 +2807,11 @@ ASSERT condition , - INSTEAD OF触发器(总是行级触发器,并且可能只被用于视图)能够返回空来表示它们没有执行任何更新,并且对该行剩余的操作可以被跳过(即后续的触发器不会被引发,并且该行不会被计入外围INSERT/UPDATE/DELETE的行影响状态中)。否则一个非空值应该被返回用以表示该触发器执行了所请求的操作。对于INSERTUPDATE操作,返回值应该是NEW,触发器函数可能对它进行了修改来支持INSERT RETURNINGUPDATE RETURNING(这也将影响被传递给任何后续触发器的行值,或者被传递给带有ON CONFLICT DO UPDATEINSERT语句中一个特殊的EXCLUDED别名引用)。对于DELETE操作,返回值应该是OLD。 + INSTEAD OF触发器(总是行级触发器,并且只能用于视图)能够返回 null 来表示它们没有执行任何更新,并且对该行剩余的操作应被跳过(即后续的触发器不会被引发,并且该行不会被计入外围INSERT/UPDATE/DELETE的行影响状态中)。否则应该返回一个非 null 值用以表示该触发器执行了所请求的操作。对于INSERTUPDATE操作,返回值应该是NEW,触发器函数可能对它进行了修改来支持INSERT RETURNINGUPDATE RETURNING(这也将影响被传递给任何后续触发器的行值,或者被传递给带有ON CONFLICT DO UPDATEINSERT语句中一个特殊的EXCLUDED别名引用)。对于DELETE操作,返回值应该是OLD - 一个AFTER行级触发器或一个BEFOREAFTER语句级触发器的返回值总是会被忽略,它可能也是空。不过,任何这些类型的触发器可能仍会通过抛出一个错误来中止整个操作。 + 一个AFTER行级触发器或一个BEFOREAFTER语句级触发器的返回值总是会被忽略,因此也可以返回 null。不过,任何这些类型的触发器可能仍会通过抛出一个错误来中止整个操作。 @@ -2934,15 +2984,15 @@ INSTEAD OF INSERT OR UPDATE OR DELETE ON emp_view - 一个 <application>PL/pgSQL</application> 用于维护汇总表的触发器函数 + 一个用于维护汇总表的 <application>PL/pgSQL</application> 触发器函数 - 这里详述的模式有一部分是基于 Ralph Kimball 所作的数据仓工具包中的Grocery Store示例。 + 这里详述的模式有一部分是基于 Ralph Kimball 所作的数据仓库工具包中的Grocery Store示例。 -- --- Main tables - time dimension and sales fact. +-- 主表 - 时间维度和销售事实。 -- CREATE TABLE time_dimension ( time_key integer NOT NULL, @@ -2965,7 +3015,7 @@ CREATE TABLE sales_fact ( CREATE INDEX sales_fact_time ON sales_fact(time_key); -- --- Summary table - sales by time. +-- 汇总表 - 按时间汇总销售 -- CREATE TABLE sales_summary_bytime ( time_key integer NOT NULL, @@ -2976,7 +3026,7 @@ CREATE TABLE sales_summary_bytime ( CREATE UNIQUE INDEX sales_summary_bytime_key ON sales_summary_bytime(time_key); -- --- Function and trigger to amend summarized column(s) on UPDATE, INSERT, DELETE. +-- 在 UPDATE、INSERT、DELETE 时修改汇总列的函数和触发器。 -- CREATE OR REPLACE FUNCTION maint_sales_summary_bytime() RETURNS TRIGGER AS $maint_sales_summary_bytime$ @@ -2987,7 +3037,7 @@ AS $maint_sales_summary_bytime$ delta_amount_cost numeric(15,2); BEGIN - -- Work out the increment/decrement amount(s). + -- 算出增量/减量数。 IF (TG_OP = 'DELETE') THEN delta_time_key = OLD.time_key; @@ -2997,9 +3047,8 @@ AS $maint_sales_summary_bytime$ ELSIF (TG_OP = 'UPDATE') THEN - -- forbid updates that change the time_key - - -- (probably not too onerous, as DELETE + INSERT is how most - -- changes will be made). + -- 禁止修改 time_key + -- (可能不会太麻烦,因为大部分的更改是用 DELETE + INSERT 完成的)。 IF ( OLD.time_key != NEW.time_key) THEN RAISE EXCEPTION 'Update of time_key : % -> % not allowed', OLD.time_key, NEW.time_key; @@ -3019,8 +3068,7 @@ AS $maint_sales_summary_bytime$ END IF; - - -- Insert or update the summary row with the new values. + -- 插入或更新带有新值的汇总行。 <<insert_update>> LOOP UPDATE sales_summary_bytime @@ -3048,7 +3096,7 @@ AS $maint_sales_summary_bytime$ EXCEPTION WHEN UNIQUE_VIOLATION THEN - -- do nothing + -- 什么也不做 END; END LOOP insert_update; @@ -3082,7 +3130,7 @@ SELECT * FROM sales_summary_bytime; 使用过渡表审计 - 这个示例产生和相同的结果,但并未使用一个为每一行都触发的触发器,而是在把相关信息收集到一个过渡表中之后用了一个只为每个语句引发一次的触发器。当调用语句修改了很多行时,这种方法明显比行触发器方法快。注意我们必须为每一种事件建立一个单独的触发器声明,因为每种情况的REFERENCING子句必须不同。但是这并不能阻止我们使用单一的触发器函数(实际上,使用三个单独的函数会更好,因为可以避免在TG_OP上的运行时测试)。 + 这个示例产生和相同的结果,但并未使用一个为每一行都触发的触发器,而是在把相关信息收集到一个过渡表中之后用了一个只为每个语句引发一次的触发器。当调用语句修改了很多行时,这种方法可能显著快于行触发器方法。注意我们必须为每一种事件建立一个单独的触发器声明,因为每种情况的REFERENCING子句必须不同。但是这并不能阻止我们使用单一的触发器函数(实际上,使用三个单独的函数可能会更好,因为可以避免在TG_OP上的运行时测试)。 @@ -3193,9 +3241,7 @@ CREATE EVENT TRIGGER snitch ON ddl_command_start EXECUTE FUNCTION snitch(); <application>PL/pgSQL</application> 内部机制 - - 这一节讨论了一些PL/pgSQL用户应该知道的一些重要的实现细节。 - + 本节讨论一些实现细节,了解这些细节对 PL/pgSQL 用户通常很重要。 变量替换 @@ -3266,7 +3312,7 @@ CREATE FUNCTION stamp_user(id int, comment text) RETURNS void AS $$ END; $$ LANGUAGE plpgsql; - 在UPDATE命令中,curtimecomment以及id将引用该函数的变量和参数,不管users有没有这些名称的列。注意,我们不得不在WHERE子句中对users.id的引用加以限定,以便让它引用表列。但是我们不需要在UPDATE列表中把对comment的引用限定为一个目标,因为语法上那必须是users的一列。我们可以用下面的方式写一个相同的不依赖于variable_conflict设置的函数: + 在UPDATE命令中,curtimecomment以及id将引用该函数的变量和参数,不管users有没有这些名称的列。注意,我们不得不在WHERE子句中对users.id的引用加以限定,以便让它引用表列。但是我们不需要对UPDATE列表中作为目标的comment引用加以限定,因为语法上那必须是users的一列。我们可以用下面的方式写一个相同的不依赖于variable_conflict设置的函数: CREATE FUNCTION stamp_user(id int, comment text) RETURNS void AS $$ <<fn>> @@ -3305,7 +3351,7 @@ $$ LANGUAGE plpgsql; - PL/pgSQL(更准确地说,是 SPI 管理器)还会尝试缓存与某个预备语句相关的执行计划。如果没有使用缓存计划,那么每次执行该语句时都会生成新的执行计划,而当前参数值(也就是 PL/pgSQL 变量值)可用于优化所选计划。如果该语句没有参数,或者会被执行很多次,SPI 管理器就会考虑创建一个不依赖具体参数值的通用计划,并将其缓存起来供重复使用。通常只有在执行计划对其中引用的 PL/pgSQL 变量值不太敏感时,才会这样做。如果执行计划对参数值非常敏感,那么每次重新生成计划总体上反而更划算。关于预备语句的行为,详见 。 + PL/pgSQL(更准确地说,是 SPI 管理器)还可以尝试缓存与某个预备语句相关的执行计划。如果没有使用缓存计划,那么每次执行该语句时都会生成新的执行计划,而当前参数值(也就是 PL/pgSQL 变量值)可用于优化所选计划。如果该语句没有参数,或者会被执行很多次,SPI 管理器就会考虑创建一个不依赖具体参数值的通用计划,并将其缓存起来供重复使用。通常只有在执行计划对其中引用的 PL/pgSQL 变量值不太敏感时,才会这样做。如果执行计划对参数值非常敏感,那么每次重新生成计划总体上反而更划算。关于预备语句的行为,详见 @@ -3354,7 +3400,7 @@ $$ LANGUAGE plpgsql; - 在logfunc2中,PostgreSQL的主解析器不知道应该把'now'解释成什么类型,因此返回一个text类型的数据值,其中包含字符串now。在确定对本地变量curtime的赋值时,PL/pgSQL解释器通过调用用于该转换的textouttimestamp_in函数,把这个字符串转换为timestamp类型。因此,计算得到的时间戳会按程序员预期在每次执行时更新。虽然这恰好能得到预期结果,但效率并不高,因此使用now()函数仍然是更好的主意。 + 在logfunc2中,PostgreSQL的主解析器不知道应该把'now'解释成什么类型,因此返回一个text类型的数据值,其中包含字符串now。在随后给局部变量curtime赋值时,PL/pgSQL解释器通过调用用于该转换的textouttimestamp_in函数,把这个字符串转换为timestamp类型。因此,计算得到的时间戳会按程序员预期在每次执行时更新。虽然这恰好能得到预期结果,但效率并不高,因此使用now()函数仍然是更好的主意。 @@ -3382,14 +3428,14 @@ $$ LANGUAGE plpgsql; - 另一种开发PL/pgSQL的好方法,是使用有助于过程语言开发的 GUI 数据库访问工具。这类工具的一个例子是pgAdmin,当然也有其他工具。它们通常提供一些方便的特性,例如转义单引号,以及让重新创建和调试函数变得更容易。 + 另一种使用PL/pgSQL进行开发的好方法,是使用有助于过程语言开发的 GUI 数据库访问工具。这类工具的一个例子是pgAdmin,当然也有其他工具。它们通常提供一些方便的特性,例如转义单引号,以及让重新创建和调试函数变得更容易。 引号的处理 - 一个PL/pgSQL函数的代码在一个CREATE FUNCTION中被指定为一个字符串。如果你用通常的方式把该字符串写在单引号中间,那么该函数体中的任何单引号都必须被双写;同样任何反斜线也必须被双写(假定使用了转义字符串语法)。双写引号最多有点冗长,并且在更复杂的情况中代码会变得完全无法理解,因为你很容易发现你需要半打或者更多相邻的引号。我们推荐你转而把函数体写成一个美元引用的字符串(见)。在美元引用方法中,你从不需要双写任何引号。但是要注意为你需要的每一层嵌套选择一个不同的美元引用定界符。例如,你可能把CREATE FUNCTION命令写成: + 一个PL/pgSQL函数的代码在一个CREATE FUNCTION中被指定为一个字符串字面量。如果你用通常的方式把该字符串写在单引号中间,那么该函数体中的任何单引号都必须被双写;同样任何反斜线也必须被双写(假定使用了转义字符串语法)。双写引号本身就很繁琐,并且在更复杂的情况中代码会变得完全无法理解,因为你很容易发现你需要半打或者更多相邻的引号。我们推荐你转而把函数体写成一个美元引用的字符串(见)。在美元引用方法中,你从不需要双写任何引号。但是要注意为你需要的每一层嵌套选择一个不同的美元引用定界符。例如,你可能把CREATE FUNCTION命令写成: CREATE OR REPLACE FUNCTION testfunc(integer) RETURNS integer AS $PROC$ .... @@ -3424,7 +3470,7 @@ CREATE FUNCTION foo() RETURNS integer AS ' - 用于函数体内的字符串,例如: + 用于函数体内的字符串字面量,例如: a_output := ''Blah''; SELECT * FROM users WHERE f_name=''foobar''; @@ -3434,7 +3480,7 @@ SELECT * FROM users WHERE f_name=''foobar''; a_output := 'Blah'; SELECT * FROM users WHERE f_name='foobar'; - 这恰好就是PL/pgSQL在两种情况中会看到的。 + 这恰好就是PL/pgSQL解析器在两种情况中会看到的。 @@ -3456,7 +3502,7 @@ a_output := a_output || '' AND name LIKE ''''foobar'''' AND xyz'' a_output := a_output || $$ AND name LIKE 'foobar' AND xyz$$ - 要小心在这周围的任何美元引用定界符不只是$$。 + 要小心在这周围的任何美元引用定界符都不能是$$ @@ -3487,7 +3533,7 @@ a_output := a_output || $$ AND name LIKE 'foobar'$$ - 当你想在一个字符串常量(占 8 个引号)中有两个单引号时并且这会挨着该字符串常量的末尾(另外 2 个)。如果你正在写一个产生其他函数的函数(如中),你将很可能只需要这种。例如: + 当字符串常量中需要两个单引号(这需要 8 个引号),而且它们紧邻该字符串常量的末尾(还需 2 个引号)时。通常只有在编写生成其他函数的函数时(如所示),才会需要这种写法。例如: a_output := a_output || '' if v_'' || referrer_keys.kind || '' like '''''''''' @@ -3584,7 +3630,7 @@ CREATE FUNCTION - 在PostgreSQL中,函数体必须写成字符串文本。因此你需要使用美元符引用或者转义函数体中的单引号(见)。 + 在PostgreSQL中,函数体必须写成字符串字面量。因此你需要使用美元符引用或者转义函数体中的单引号(见)。 @@ -3673,13 +3719,13 @@ show errors; - 在PostgreSQL中,函数体被认为是一个字符串,所以你需要使用引号或者美元符号包围它。这代替了Oracle 方法中的用于终止的/。 + 在PostgreSQL中,函数体被认为是一个字符串字面量,所以你需要使用引号或者美元引用定界符包围它。这代替了Oracle 方法中的用于终止的/ - 在PostgreSQL中没有show errors命令, 并且也不需要这个命令,因为错误是自动报告的。 + 在PostgreSQL中没有show errors命令, 并且也不需要这个命令,因为错误是自动报告的。 @@ -3710,9 +3756,7 @@ $$ LANGUAGE plpgsql; 从<application>PL/SQL</application>移植一个创建另一个函数的函数到<application>PL/pgSQL</application> - - 下面的过程从一个SELECT语句抓取行,并且为了效率而构建一个带有IF语句中结果的大型函数。 - + 下面的过程从 SELECT 语句读取行,并将结果写入 IF 语句,从而构造一个大型函数,以提高效率。 这是 Oracle 版本: @@ -3790,12 +3834,14 @@ $func$ LANGUAGE plpgsql; 下面的Oracle PL/SQL 过程被用来解析一个 URL 并且返回一些元素(主机、路径和查询)。 - 这是 Oracle 版本: + + 这是 Oracle 版本: + CREATE OR REPLACE PROCEDURE cs_parse_url( v_url IN VARCHAR2, - v_host OUT VARCHAR2, -- This will be passed back - v_path OUT VARCHAR2, -- This one too - v_query OUT VARCHAR2) -- And this one + v_host OUT VARCHAR2, -- 这个值将被返回 + v_path OUT VARCHAR2, -- 这个也是 + v_query OUT VARCHAR2) -- 还有这个 IS a_pos1 INTEGER; a_pos2 INTEGER; @@ -3831,13 +3877,14 @@ show errors; - 下面是一种可行的移植写法,目标语言为PL/pgSQL: + + 这里给出一种可能的 PL/pgSQL 写法: CREATE OR REPLACE FUNCTION cs_parse_url( v_url IN VARCHAR, - v_host OUT VARCHAR, -- This will be passed back - v_path OUT VARCHAR, -- This one too - v_query OUT VARCHAR) -- And this one + v_host OUT VARCHAR, -- 这个值将被返回 + v_path OUT VARCHAR, -- 这个也是 + v_query OUT VARCHAR) -- 还有这个 AS $$ DECLARE a_pos1 INTEGER; @@ -3870,20 +3917,26 @@ BEGIN v_query := substr(v_url, a_pos1 + 1); END; $$ LANGUAGE plpgsql; -该函数可以这样使用: + + + 这个函数可以这样使用: + SELECT * FROM cs_parse_url('http://foobar.com/query.cgi?baz'); - 展示了如何移植一个使用了多种 Oracle 特性的过程。 + 展示了如何移植一个使用了多种 Oracle 专属特性的过程。 从<application>PL/SQL</application>移植一个过程到<application>PL/pgSQL</application> - Oracle 版本: + + Oracle 版本: + + CREATE OR REPLACE PROCEDURE cs_create_job(v_job_id IN INTEGER) IS a_running_job_count INTEGER; BEGIN @@ -3892,7 +3945,7 @@ BEGIN SELECT count(*) INTO a_running_job_count FROM cs_jobs WHERE end_stamp IS NULL; IF a_running_job_count > 0 THEN - COMMIT; -- free lock + COMMIT; -- 释放锁 raise_application_error(-20000, 'Unable to create a new job: a job is currently running.'); END IF; @@ -3903,7 +3956,7 @@ BEGIN BEGIN INSERT INTO cs_jobs (job_id, start_stamp) VALUES (v_job_id, now()); EXCEPTION - WHEN dup_val_on_index THEN NULL; -- don't worry if it already exists + WHEN dup_val_on_index THEN NULL; -- 如果已经存在也不用担心 END; COMMIT; END; @@ -3912,7 +3965,8 @@ show errors - 下面展示了如何移植这个过程,目标语言为PL/pgSQL: + + 下面展示了如何将这个过程移植到PL/pgSQL CREATE OR REPLACE PROCEDURE cs_create_job(v_job_id integer) AS $$ @@ -3924,7 +3978,7 @@ BEGIN SELECT count(*) INTO a_running_job_count FROM cs_jobs WHERE end_stamp IS NULL; IF a_running_job_count > 0 THEN - COMMIT; -- free lock + COMMIT; -- 释放锁 RAISE EXCEPTION 'Unable to create a new job: a job is currently running'; -- END IF; @@ -3935,7 +3989,7 @@ BEGIN INSERT INTO cs_jobs (job_id, start_stamp) VALUES (v_job_id, now()); EXCEPTION WHEN unique_violation THEN -- - -- don't worry if it already exists + -- 如果已经存在不要担心 END; COMMIT; END; @@ -3986,7 +4040,7 @@ EXCEPTION END; - 如果你正在移植一个以这种方式使用SAVEPOINTROLLBACK TO的 Oracle 过程,工作会比较简单:只要忽略SAVEPOINTROLLBACK TO即可。如果你的 Oracle 过程以不同方式使用SAVEPOINTROLLBACK TO,那就需要认真思考了。 + 如果你正在移植一个以这种方式使用SAVEPOINTROLLBACK TO的 Oracle 过程,工作会比较简单:只要省略SAVEPOINTROLLBACK TO即可。如果你的 Oracle 过程以不同方式使用SAVEPOINTROLLBACK TO,那就需要认真思考了。 @@ -4003,11 +4057,11 @@ END; 优化 <application>PL/pgSQL</application> 函数 - PostgreSQL提供了两种函数创建修饰符来优化执行:volatility(对于给定的相同参数,函数是否总是返回相同的结果)以及strictness (如果任何参数为空,函数是否返回空)。详见参考页。 + PostgreSQL提供了两种函数创建修饰符来优化执行:volatility(对于给定的相同参数,函数是否总是返回相同的结果)以及strictness (如果任何参数为空值,函数是否返回空值)。详见参考页。 - 在利用这些优化属性时,你的CREATE FUNCTION语句应该看起来像这样: + 在利用这些优化属性时,你的CREATE FUNCTION语句可能像这样: CREATE FUNCTION foo(...) RETURNS integer AS $$ diff --git a/zh/11/plpython.sgml b/zh/11/plpython.sgml index 6e63c6f3..12572708 100644 --- a/zh/11/plpython.sgml +++ b/zh/11/plpython.sgml @@ -110,7 +110,7 @@ CREATE FUNCTION funcname (argument-list) RETURNS return-type AS $$ - # PL/Python function body + # PL/Python 函数体 $$ LANGUAGE plpythonu; @@ -150,7 +150,7 @@ def __plpython_procedure_pymax_23456(): CREATE FUNCTION pystrip(x text) RETURNS text AS $$ - x = x.strip() # error + x = x.strip() # 错误 return x $$ LANGUAGE plpythonu; @@ -160,7 +160,7 @@ CREATE FUNCTION pystrip(x text) RETURNS text AS $$ global x - x = x.strip() # ok now + x = x.strip() # 现在可以正常工作 return x $$ LANGUAGE plpythonu; @@ -176,7 +176,10 @@ $$ LANGUAGE plpythonu; 数据类型映射 - 调用 PL/Python 函数时,参数会从 PostgreSQL 数据类型转换为相应的 Python 类型: + + 调用 PL/Python 函数时,其参数会从 PostgreSQL 数据类型转换为相应的 Python 类型: + + PostgreSQL boolean 会转换为 Python bool。 @@ -213,8 +216,9 @@ $$ LANGUAGE plpythonu; - 所有其他数据类型,包括 PostgreSQL 字符串类型, - 都会转换为 Python str(和所有 Python 字符串一样,都是 Unicode)。 + 所有其他数据类型,包括 PostgreSQL 字符串类型,都会转换为 Python + str。在 Python 2 中,该字符串采用 PostgreSQL 服务器编码; + 在 Python 3 中,它与所有字符串一样,都是 Unicode 字符串。 @@ -226,7 +230,10 @@ $$ LANGUAGE plpythonu; - PL/Python 函数返回时,返回值按以下规则转换为该函数声明的 PostgreSQL 返回数据类型: + + 当 PL/Python 函数返回时,其返回值会按如下方式转换成该函数声明的 PostgreSQL 返回数据类型: + + 当 PostgreSQL 返回类型为boolean时,返回值会按照Python规则进行真值判定。也就是说,0 和空字符串为假,但值得注意的是,'f' 为真。 @@ -243,7 +250,10 @@ $$ LANGUAGE plpythonu; - 字符串在传给 PostgreSQL 时,会自动转换为 PostgreSQL 服务器编码。 + Python 2 中的字符串传给 PostgreSQL 时,必须采用 PostgreSQL 服务器编码。 + 在当前服务器编码中无效的字符串会引发错误,但并非所有编码不匹配都能被检测到, + 因此处理不当仍可能产生乱码数据。Unicode 字符串会自动转换为正确的编码, + 因而使用它们可能更安全、更方便。在 Python 3 中,所有字符串都是 Unicode 字符串。 @@ -252,7 +262,10 @@ $$ LANGUAGE plpythonu; 对于非标量数据类型,请参见下文。 - 注意,如果声明的 PostgreSQL 返回类型与实际返回对象的 Python 数据类型在逻辑上不匹配,系统不会提示;无论如何都会转换该值。 + + + 请注意,即使声明的 PostgreSQL 返回类型与实际返回对象的 Python 数据类型在逻辑上并不匹配,也不会报错;无论如何该值都会被转换。 + @@ -354,12 +367,19 @@ $$ LANGUAGE plpythonu; - 从 Python 函数返回行类型或复合类型,有多种方式。以下示例假定已定义: + + 有多种方法可以从 Python 函数返回行类型或复合类型。以下示例假定我们有: + + CREATE TYPE named_value AS ( name text, value integer ); -复合结果可以用以下形式返回: + + + 复合结果可以按以下形式返回: + + 序列类型(元组或列表,但不能是集合,因为集合不可通过索引访问) @@ -368,7 +388,7 @@ CREATE FUNCTION make_pair (name text, value integer) RETURNS named_value AS $$ return ( name, value ) - # or alternatively, as list: return [ name, value ] + # 也可以使用列表: return [ name, value ] $$ LANGUAGE plpythonu; 要为某一列返回 SQL 空值,请将 None 放在对应位置。 @@ -406,7 +426,7 @@ AS $$ self.value = v return named_value(name, value) - # or simply + # 或者简写为 class nv: pass nv.name = name nv.value = value @@ -443,13 +463,20 @@ CALL python_triple(5, 10); - 返回集合的函数 - 一个 PL/Python 函数也可以返回标量类型或复合类型的集合。实现方式有多种,因为返回对象在内部会被转换为迭代器。以下示例假定已定义复合类型: + 集合返回函数 + + PL/Python函数也可以返回标量类型或复合类型的集合。实现方式有多种,因为返回的对象在内部会被转换成一个迭代器。以下示例假定我们有如下复合类型: + + CREATE TYPE greeting AS ( how text, who text ); -集合结果可以通过以下形式返回: + + + 集合结果可以通过以下对象返回: + + 序列类型(元组、列表、集合) @@ -458,8 +485,8 @@ CREATE TYPE greeting AS ( CREATE FUNCTION greet (how text) RETURNS SETOF greeting AS $$ - # return tuple containing lists as composite types - # all other combinations work also + # 返回包含列表的元组,以列表表示复合类型 + # 其他组合方式也都可用 return ( [ how, "World" ], [ how, "PostgreSQL" ], [ how, "PL/Python" ] ) $$ LANGUAGE plpythonu; @@ -517,7 +544,7 @@ $$ LANGUAGE plpythonu; - 也支持带OUT参数的返回集函数(使用RETURNS SETOF record)。例如: + 也支持带OUT参数的集合返回函数(使用RETURNS SETOF record)。例如: CREATE FUNCTION multiout_simple_setof(n integer, OUT integer, OUT integer) RETURNS SETOF record AS $$ return [(1, 2)] * n @@ -552,7 +579,7 @@ SELECT * FROM multiout_simple_setof(3); DO $$ - # PL/Python code + # PL/Python 代码 $$ LANGUAGE plpythonu; @@ -799,7 +826,7 @@ CREATE FUNCTION usesavedplan() RETURNS trigger AS $$ else: plan = plpy.prepare("SELECT 1") SD["plan"] = plan - # rest of function + # 函数的其余部分 $$ LANGUAGE plpythonu; @@ -816,11 +843,11 @@ $$ LANGUAGE plpythonu; - 游标对象提供fetch方法,它接受一个整数参数并返回结果对象。每次调用fetch,返回对象都会包含下一批行,数量不会超过该参数值。一旦所有行都已取完,fetch就会开始返回空结果对象。游标对象还提供迭代器接口,每次产生一行,直到所有行为止。以这种方式获取的数据不会作为结果对象返回,而是以字典形式返回,每个字典对应一行结果。 + 游标对象提供fetch方法,它接受一个整数参数并返回结果对象。每次调用fetch,返回对象都会包含下一批行,数量不会超过该参数值。一旦所有行都已取完,fetch就会开始返回空结果对象。游标对象还提供迭代器接口,每次产生一行,直到取完所有行。以这种方式获取的数据不会作为结果对象返回,而是以字典形式返回,每个字典对应一行结果。 - 下面示例展示了如何处理大表中的数据: + 下面示例展示了处理大表中数据的两种方式: CREATE FUNCTION count_odd_iterator() RETURNS integer AS $$ odd = 0 @@ -846,7 +873,7 @@ $$ LANGUAGE plpythonu; CREATE FUNCTION count_odd_prepared() RETURNS integer AS $$ odd = 0 plan = plpy.prepare("select num from largetable where num % $1 <> 0", ["integer"]) -rows = list(plpy.cursor(plan, [2])) # or: = list(plan.cursor([2])) +rows = list(plpy.cursor(plan, [2])) # 或者:= list(plan.cursor([2])) return len(rows) $$ LANGUAGE plpythonu; @@ -950,9 +977,9 @@ $$ LANGUAGE plpythonu; - 旧式 Python 2 用法 + 较早的 Python 版本 - 使用 with 关键字的上下文管理器语法,从 Python 2.6 起默认可用。如果 PL/Python 使用更早的 Python 版本,仍然可以使用显式子事务,只是没那么方便。可以调用子事务管理器的 __enter____exit__ 函数,也可以使用它们的便捷别名 enterexit。转账示例函数可以写成: + 使用 with 关键字的上下文管理器语法,从 Python 2.6 起默认可用。如果 PL/Python 使用更早的 Python 版本,仍然可以使用显式子事务,只是没那么方便。可以通过便捷别名 enterexit,调用子事务管理器的 __enter____exit__ 函数。转账示例函数可以写成: CREATE FUNCTION transfer_funds_old() RETURNS void AS $$ try: subxact = plpy.subtransaction() @@ -1016,7 +1043,7 @@ CALL transaction_test1(); - 实用函数 + 辅助函数 plpy模块还提供以下函数: @@ -1070,7 +1097,7 @@ PL/Python function "raise_custom_exception" - 另一组实用函数是plpy.quote_literal(string)plpy.quote_nullable(string)以及plpy.quote_ident(string)。它们等价于中描述的内置引用函数。在构造临时查询时,这些函数很有用。中动态 SQL 的一个 PL/Python 等价写法如下: + 另一组辅助函数是plpy.quote_literal(string)plpy.quote_nullable(string)以及plpy.quote_ident(string)。它们等价于中描述的内置加引号函数。在构造临时查询时,这些函数很有用。中动态 SQL 的一个 PL/Python 等价写法如下: plpy.execute("UPDATE tbl SET %s = %s WHERE key = %s" % ( plpy.quote_ident(colname), diff --git a/zh/11/pltcl.sgml b/zh/11/pltcl.sgml index d3bb1082..a8585af6 100644 --- a/zh/11/pltcl.sgml +++ b/zh/11/pltcl.sgml @@ -12,7 +12,7 @@ - PL/Tcl 是一种适用于 PostgreSQL 数据库系统的可载入的过程语言,它允许使用 Tcl 语言 来编写 PostgreSQL 函数和过程。 + PL/Tcl 是一种适用于 PostgreSQL 数据库系统的可加载的过程语言,它允许使用 Tcl 语言 来编写 PostgreSQL 函数和过程。 @@ -53,7 +53,7 @@ CREATE FUNCTION funcname (argument-types) RETURNS return-type AS $$ - # PL/Tcl function body + # PL/Tcl 函数体 $$ LANGUAGE pltcl; @@ -74,11 +74,11 @@ CREATE FUNCTION tcl_max(integer, integer) RETURNS integer AS $$ $$ LANGUAGE pltcl STRICT; - 注意STRICT子句,它让我们不必考虑空输入值:如果传入的是空值,函数根本不会被调用,而是会自动返回空结果。 + 注意STRICT子句,它让我们不必考虑空值输入:如果传入的是空值,函数根本不会被调用,而是会自动返回空值结果。 - 在非严格函数中,如果某个参数的实际值为空,对应的$n变量会被设置为空串。要检测某个特定参数是否为空,可使用函数argisnull。例如,假设我们希望在tcl_max的两个参数中一个为空、一个非空时返回非空参数,而不是返回空值: + 在非严格函数中,如果某个参数的实际值为空值,对应的$n变量会被设置为空串。要检测某个特定参数是否为空值,可使用函数argisnull。例如,假设我们希望在tcl_max的两个参数中一个为空值、一个非空值时返回非空值参数,而不是返回空值: CREATE FUNCTION tcl_max(integer, integer) RETURNS integer AS $$ @@ -98,7 +98,7 @@ $$ LANGUAGE pltcl; - 复合类型参数会作为 Tcl 数组传递给函数。数组元素名就是该复合类型的属性名。如果传入行中的某个属性为 NULL,它就不会出现在数组中。下面是一个示例: + 复合类型参数会作为 Tcl 数组传递给函数。数组元素名就是该复合类型的属性名。如果传入行中的某个属性为空值,它就不会出现在数组中。下面是一个示例: CREATE TABLE employee ( @@ -184,7 +184,7 @@ $$ LANGUAGE pltcl; PL/Tcl 中的数据值 - 提供给 PL/Tcl 函数代码的参数值,只是将输入参数转换成文本形式(就像用SELECT语句将它们显示出来一样)。反过来,returnreturn_next命令会接受任何字符串,只要它是该函数声明结果类型或组合结果类型中指定列的可接受输入格式。 + 提供给 PL/Tcl 函数代码的参数值,只是将输入参数转换成文本形式(就像用SELECT语句将它们显示出来一样)。反过来,returnreturn_next命令会接受任何字符串,只要它是该函数声明结果类型或复合结果类型中指定列的可接受输入格式。 @@ -194,8 +194,8 @@ $$ LANGUAGE pltcl; PL/Tcl 中的全局数据 - global data - in PL/Tcl + 全局数据 + 在 PL/Tcl 中 @@ -222,14 +222,17 @@ $$ LANGUAGE pltcl; 从 PL/Tcl 访问数据库 - 本节遵循 Tcl 的惯例,在语法概要中用问号而不是方括号表示可选元素。在 PL/Tcl 函数体中可以使用以下命令访问数据库: + + 在本节中,我们遵循 Tcl 的通常约定,用问号而不是方括号来表示语法摘要中的可选元素。下列命令可用于从 PL/Tcl 函数体中访问数据库: + + spi_exec -count n -array name command loop-body - 执行以字符串形式给出的 SQL 命令。命令出错时会引发错误。否则,spi_exec的返回值是该命令处理的行数(选出、插入、更新或删除的行),如果命令是实用程序语句则返回零。此外,如果命令是SELECT语句,则所选列的值会按下文所述放入 Tcl 变量中。 + 执行以字符串形式给出的 SQL 命令。命令出错时会引发错误。否则,spi_exec的返回值是该命令处理的行数(选出、插入、更新或删除的行),如果命令是工具语句则返回零。此外,如果命令是SELECT语句,则所选列的值会按下文所述放入 Tcl 变量中。 @@ -270,7 +273,7 @@ spi_exec -array C "SELECT * FROM pg_class" { - 如果查询结果中的某一列为空,则对应的目标变量会被unset,而不是被设值。 + 如果查询结果中的某一列为空值,则对应的目标变量会被unset,而不是被设值。 @@ -282,7 +285,7 @@ spi_exec -array C "SELECT * FROM pg_class" { 准备并保存一个查询计划以供后续执行。保存的计划会在当前会话的整个生命周期内保留。 准备查询 - 在PL/Tcl中 + 在 PL/Tcl 中 @@ -312,7 +315,7 @@ spi_exec -array C "SELECT * FROM pg_class" { 可选的-nulls值是由空格和'n'字符组成的字符串,用来告诉spi_execp哪些参数是空值。 - 如果给出,它的长度必须与value-list完全相同。如果未给出,则所有参数值都视为非空。 + 如果给出,它的长度必须与value-list完全相同。如果未给出,则所有参数值都视为非空值。 @@ -326,7 +329,7 @@ spi_exec -array C "SELECT * FROM pg_class" { CREATE FUNCTION t1_count(integer, integer) RETURNS integer AS $$ if {![ info exists GD(plan) ]} { - # prepare the saved plan on the first call + # 在首次调用时准备并保存计划 set GD(plan) [ spi_prepare \ "SELECT count(*) AS cnt FROM t1 WHERE num >= \$1 AND num <= \$2" \ [ list int4 int4 ] ] @@ -368,7 +371,7 @@ $$ LANGUAGE pltcl; 将给定字符串中的所有单引号和反斜杠字符都加倍。 - 这可用于安全地引用那些要插入到传给spi_execspi_prepare的 SQL 命令中的字符串。 + 这可用于安全地为那些要插入到传给spi_execspi_prepare的 SQL 命令中的字符串加引号。 例如,考虑如下 SQL 命令字符串: @@ -394,7 +397,7 @@ SELECT 'doesn''t' AS ret "SELECT '[ quote $val ]' AS ret" - spi_execp的一个优点是,你不必像这样对参数值做引用,因为这些参数永远不会作为 SQL 命令字符串的一部分被解析。 + spi_execp的一个优点是,你不必像这样给参数值加引号,因为这些参数永远不会作为 SQL 命令字符串的一部分被解析。 @@ -404,7 +407,7 @@ SELECT 'doesn''t' AS ret elog level msg elog - 在PL/Tcl中 + 在 PL/Tcl 中 @@ -435,14 +438,17 @@ SELECT 'doesn''t' AS ret PL/Tcl 中的触发器函数 - trigger - in PL/Tcl + 触发器 + 在 PL/Tcl 中 触发器函数也可以用 PL/Tcl 编写。PostgreSQL要求,凡是要作为触发器调用的函数,都必须声明为无参数且返回类型为trigger - 触发器管理器的信息通过以下变量传入函数体: + + 来自触发器管理器的信息会通过下列变量传递给函数体: + + $TG_name @@ -520,7 +526,7 @@ SELECT 'doesn''t' AS ret $NEW - 对于INSERTUPDATE动作,这是一个包含新表行值的关联数组;对于DELETE则为空。该数组以列名为索引。值为 NULL 的列不会出现在数组中。对于语句级触发器,不会设置这个变量。 + 对于INSERTUPDATE动作,这是一个包含新表行值的关联数组;对于DELETE则为空。该数组以列名为索引。值为空值的列不会出现在数组中。对于语句级触发器,不会设置这个变量。 @@ -529,7 +535,7 @@ SELECT 'doesn''t' AS ret $OLD - 对于UPDATEDELETE动作,这是一个包含旧表行值的关联数组;对于INSERT则为空。该数组以列名为索引。值为 NULL 的列不会出现在数组中。对于语句级触发器,不会设置这个变量。 + 对于UPDATEDELETE动作,这是一个包含旧表行值的关联数组;对于INSERT则为空。该数组以列名为索引。值为空值的列不会出现在数组中。对于语句级触发器,不会设置这个变量。 @@ -592,20 +598,23 @@ CREATE TRIGGER trig_mytab_modcount BEFORE INSERT OR UPDATE ON mytab PL/Tcl 中的事件触发器函数 - event trigger - in PL/Tcl + 事件触发器 + 在 PL/Tcl 中 事件触发器函数也可以用 PL/Tcl 编写。PostgreSQL要求,凡是要作为事件触发器调用的函数,都必须声明为无参数且返回类型为event_trigger - 触发器管理器的信息通过以下变量传入函数体: + + 来自触发器管理器的信息会通过下列变量传递给函数体: + + $TG_event - 触发器因其而被触发的事件名称。 + 该触发器所针对的事件名称。 @@ -614,7 +623,7 @@ CREATE TRIGGER trig_mytab_modcount BEFORE INSERT OR UPDATE ON mytab $TG_tag - 触发器因其而被触发的命令标签。 + 该触发器所针对的命令标签。 @@ -622,10 +631,13 @@ CREATE TRIGGER trig_mytab_modcount BEFORE INSERT OR UPDATE ON mytab - 事件触发器函数的返回值会被忽略。 + 触发器函数的返回值会被忽略。 - 下面是一个简单的事件触发器函数示例,每当执行受支持的命令时,它只发出一条 NOTICE 消息: + + 下面是一个小型事件触发器函数示例。每当执行受支持的命令时,它都会简单地发出一条NOTICE消息: + + CREATE OR REPLACE FUNCTION tclsnitch() RETURNS event_trigger AS $$ elog NOTICE "tclsnitch: $TG_event $TG_tag" $$ LANGUAGE pltcl; @@ -639,8 +651,8 @@ CREATE EVENT TRIGGER tcl_a_snitch ON ddl_command_start EXECUTE FUNCTION tclsnitc PL/Tcl 中的错误处理 - exceptions - in PL/Tcl + 异常 + 在 PL/Tcl 中 @@ -668,9 +680,9 @@ if {[catch { spi_exec $sql_command }]} { if {[lindex $::errorCode 0] == "POSTGRES"} { array set errorArray $::errorCode if {$errorArray(condition) == "undefined_table"} { - # deal with missing table + # 处理表不存在的情况 } else { - # deal with some other type of SQL error + # 处理其他类型的 SQL 错误 } } } @@ -684,8 +696,8 @@ if {[catch { spi_exec $sql_command }]} { PL/Tcl 中的显式子事务 - subtransactions - in PL/Tcl + 子事务 + 在 PL/Tcl 中 @@ -783,7 +795,7 @@ CALL transaction_test1(); pltcl.start_proc (string) - pltcl.start_proc configuration parameter + pltcl.start_proc 配置参数 @@ -811,7 +823,7 @@ CALL transaction_test1(); pltclu.start_proc (string) - pltclu.start_proc configuration parameter + pltclu.start_proc 配置参数 @@ -830,7 +842,7 @@ CALL transaction_test1(); Tcl 过程名 - 在PostgreSQL中,只要参数个数或参数类型不同,就可以复用同一个函数名。不过,Tcl 要求所有过程名都必须不同。PL/Tcl 通过让内部 Tcl 过程名包含系统表pg_proc中该函数的对象 ID 来解决这个问题。因此,名称相同而参数类型不同的PostgreSQL函数,也会对应不同的 Tcl 过程。这通常不是 PL/Tcl 程序员需要关心的事情,但在调试时可能会看到。 + 在PostgreSQL中,只要参数个数或参数类型不同,就可以复用同一个函数名。不过,Tcl 要求所有过程名都必须不同。PL/Tcl 处理这一问题的方式是:在内部 Tcl 过程名中包含系统表 pg_proc 中的函数对象 ID 作为其名称的一部分。因此,名称相同但参数类型不同的PostgreSQL函数,也会对应不同的 Tcl 过程。这通常不是 PL/Tcl 程序员需要关心的事情,但在调试时可能会看见。 diff --git a/zh/11/postgres-fdw.sgml b/zh/11/postgres-fdw.sgml index adee5a9a..e48bb4fd 100644 --- a/zh/11/postgres-fdw.sgml +++ b/zh/11/postgres-fdw.sgml @@ -243,7 +243,7 @@ 该选项是一个以逗号分隔的 PostgreSQL 扩展 名称列表,这些扩展必须在本地和远程服务器上都已安装且版本兼容。 - 属于列出扩展且为 immutable 的函数和操作符,将被视为可下推到远程服务器 + 属于列出扩展且不可变的函数和操作符,将被视为可下推到远程服务器 执行。该选项只能为外部服务器指定,不能按表指定。 @@ -414,8 +414,7 @@ - 请注意,postgres_fdw 当前不支持将远程事务预备为 - 两阶段提交。 + 请注意,postgres_fdw 当前不支持为两阶段提交预备远程事务。 diff --git a/zh/11/protocol.sgml b/zh/11/protocol.sgml index 14f9a98b..097ac8e6 100644 --- a/zh/11/protocol.sgml +++ b/zh/11/protocol.sgml @@ -758,7 +758,12 @@ SELCT 1/0; 只要后端认为前端应当知晓的某个参数的当前有效值发生变化,就会生成 ParameterStatus 消息。最常见的情况是响应前端执行的SET命令,这种情况实际上是同步的;但也可能是管理员修改了配置文件,然后向服务器发送SIGHUP信号,从而导致参数状态发生变化。同样,如果某条SET命令被回滚,也会生成适当的 ParameterStatus 消息,用于报告当前生效的值。 - 目前,会为一组固定的参数生成 ParameterStatus,包括 server_versionserver_encodingclient_encodingapplication_nameis_superusersession_authorizationDateStyleIntervalStyleTimeZoneinteger_datetimesstandard_conforming_strings。(8.0 之前的版本不报告 server_encodingTimeZoneinteger_datetimes;8.1 之前的版本不报告 standard_conforming_strings;8.4 之前的版本不报告 IntervalStyle;9.0 之前的版本不报告 application_name。)注意,server_versionserver_encodinginteger_datetimes 是启动后不能改变的伪参数。这组参数将来可能变化,甚至可能变为可配置。因此,前端应直接忽略其不理解或不关心的参数的 ParameterStatus。 + + 目前,会为一组固定的参数生成 ParameterStatus,参数如下: + server_versionserver_encodingclient_encodingapplication_nameis_superusersession_authorizationDateStyleIntervalStyleTimeZoneinteger_datetimesstandard_conforming_strings。 + (8.0 之前的版本不报告 server_encodingTimeZoneinteger_datetimes;8.1 之前的版本不报告 standard_conforming_strings;8.4 之前的版本不报告 IntervalStyle;9.0 之前的版本不报告 application_name。) + 注意,server_versionserver_encodinginteger_datetimes 是启动后不能改变的伪参数。这组参数将来可能变化,甚至可能变为可配置。因此,前端应直接忽略其不理解或不关心的参数的 ParameterStatus。 + 如果前端发出一个LISTEN命令, 那么无论何时在为同一个通道名NOTIFY时,后端将发送一个NotificationResponse消息(不要和NoticeResponse搞混!)。 @@ -1126,7 +1131,9 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" output_plugin - 用于逻辑解码的输出插件名称(参见 )。 + + 用于逻辑解码的输出插件的名称(参见)。 + @@ -1134,8 +1141,8 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" TEMPORARY - 该命令导出的快照标识符。该快照在此连接上执行下一条命令之前,或复制连接关闭之前有效。如果所创建的是物理复制槽,则为 null。 - + 指定此复制槽为临时槽。临时槽不会保存到磁盘,并且在错误或会话结束时会自动删除。 + @@ -1156,11 +1163,14 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 作为对此命令的响应,服务器会发送仅含一行的结果集,其中包含以下字段: + + 在响应此命令时,服务器将发送一个包含以下字段的单行结果集: slot_name (text) - 新建复制槽的名称。 + + 新创建的复制槽的名称。 + @@ -1177,7 +1187,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" snapshot_name (text) - 该命令导出的快照标识符。该快照在此连接上执行下一条命令之前,或复制连接关闭之前有效。如果所创建的是物理复制槽,则为 null。 + 该命令导出的快照标识符。该快照在此连接上执行下一条命令之前,或复制连接关闭之前有效。如果所创建的是物理复制槽,则为空值。 @@ -1186,7 +1196,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" output_plugin (text) - 新建复制槽所使用的输出插件名称。如果所创建的是物理复制槽,则为 null。 + 新建复制槽所使用的输出插件名称。如果所创建的是物理复制槽,则为空值。 @@ -1495,14 +1505,19 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" BASE_BACKUP [ LABEL 'label' ] [ PROGRESS ] [ FAST ] [ WAL ] [ NOWAIT ] [ MAX_RATE rate ] [ TABLESPACE_MAP ] [ NOVERIFY_CHECKSUMS ] BASE_BACKUP - 指示服务器开始流式传输基础备份。系统会在备份开始前自动进入备份模式,在备份完成后退出该模式。接受以下选项: + + 指示服务器开始流式传输基础备份。 + 在备份开始之前,系统将自动进入备份模式,并在备份完成后退出备份模式。 + 接受以下选项: + + LABEL 'label' 设置备份的标签。如果未指定,则将使用base backup作为备份标签。 - 标签的引用规则与打开的标准SQL字符串相同。 + 标签的引号使用规则与打开的标准SQL字符串相同。 @@ -1511,8 +1526,12 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" PROGRESS - 请求生成进度报告所需的信息。这将在每个表空间的头部发回大致大小,可用于计算流式传输的完成进度。此大小通过在传输开始之前枚举所有文件大小来计算,因此可能对性能有负面影响。特别是在第一个数据被发出之前可能需要更长的时间。 - + 请求生成进度报告所需的信息。这将在每个表空间的首部发送一个近似大小, + 可用于计算流式传输的进度。这是通过在传输开始之前先枚举所有文件大小来计算的, + 可能会对性能产生负面影响。特别是,在流式传输数据之前可能需要更长的时间。 + 由于备份期间数据库文件可能会发生变化,因此大小仅为近似值, + 在估算与实际发送文件之间的这段时间里可能会增长或缩小。 + @@ -1529,9 +1548,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" WAL - - 如果设置为true,则在备份中包含必要的WAL段。这将包括在开始和停止备份之间的所有文件在基本目录tar文件的pg_wal目录中。默认值为false。 - + 在备份中包含必要的 WAL 段。这会把开始备份到停止备份之间的所有文件放入基础目录 tar 文件内的pg_wal目录中。 @@ -1559,8 +1576,8 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 如果为true,则在名为tablespace_map的文件中包含目录pg_tblspc中存在的符号链接的信息。 - 表空间映射文件包括目录pg_tblspc/中每个符号链接的名称及该符号链接的完整路径。默认值为false。 + 在名为tablespace_map的文件中包含目录pg_tblspc中存在的符号链接的信息。 + 表空间映射文件包括目录pg_tblspc/中每个符号链接的名称及该符号链接的完整路径。 @@ -1572,17 +1589,21 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - + 备份开始时,服务器首先发送两个普通结果集,然后发送一个或多个 CopyResponse 结果。 第一个普通结果集包含备份的起始位置,在一个包含两列的单行中。第一列包含以XLogRecPtr格式给出的起始位置,第二列包含相应的时间线ID。 - 第二个普通结果集为每个表空间包含一行。这一行的字段如下: + + 第二个普通结果集中的每个表空间都有一行。 + 这一行中的字段是: + + spcoid (oid) - 表空间的OID,如果是基本目录则为null。 + 表空间的OID,如果是基础目录则为null。 @@ -1590,7 +1611,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" spclocation (text) - 表空间目录的完整路径,如果是基本目录则为null。 + 表空间目录的完整路径,如果是基础目录则为null。 @@ -1601,10 +1622,13 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - + 在第二个普通结果集之后,会发送一个或多个 CopyResponse 结果,其中一个用于主数据目录,其他结果分别用于 pg_defaultpg_global 之外的各个附加表空间。CopyResponse 结果中的数据是表空间内容的 tar 格式转储(遵循 POSIX 1003.1-2008 标准中规定的 ustar interchange format),但省略了标准规定的末尾两个全零块。tar 数据传输完成后,会发送最后一个普通结果集,其中包含备份的 WAL 结束位置,格式与起始位置相同。 - 数据目录和每个表空间的 tar 归档都会包含目录中的所有文件,无论是PostgreSQL文件,还是添加到同一目录的其他文件。仅排除以下文件: + + 数据目录和每个表空间的tar归档将包含目录中的所有文件,无论它们是PostgreSQL文件还是添加到同一目录的其他文件。唯一排除的文件是: + + postmaster.pid @@ -1626,13 +1650,11 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - - 不记录 WAL 的关系(Unlogged表),除了需要在恢复时重新创建(空的)不记录 WAL 的关系的init fork。 - + 不记录 WAL 的关系,但不包括恢复时重新创建(空的)不记录 WAL 的关系所需的初始化分支。 - pg_wal,包括子目录。如果备份包含WAL文件,则将包含pg_wal的合成版本,但它只包含备份工作所需的文件,而不包含其余内容。 + pg_wal,包括子目录。如果备份包含WAL文件,则将包含pg_wal的合成版本,但它只包含使备份可用所需的文件,而不包含其余内容。 @@ -1645,10 +1667,12 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 除了常规文件和目录之外的文件,如符号链接(除了上述列出的目录之外的符号链接)以及特殊设备和操作系统文件,将被跳过。(pg_tblspc中的符号链接将被保留。) + 除了普通文件和目录之外的文件,如符号链接(除了上述列出的目录之外的符号链接)以及特殊设备文件,将被跳过。(pg_tblspc中的符号链接将被保留。) - 如果服务器底层文件系统支持,还会设置所有者、组和文件模式。 + + 如果服务器上的底层文件系统支持,将设置所有者、组和文件模式。 + @@ -1671,7 +1695,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 逻辑复制参数 + 逻辑流复制参数 逻辑复制的START_REPLICATION命令接受以下参数: @@ -1684,7 +1708,9 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" publication_names - 要订阅(接收变更)的发布名称列表,以逗号分隔。各个发布名称按标准对象名称处理,可以按需以相同方式加引号。 + + 要订阅(接收变更)的发布名称列表,以逗号分隔。各个发布名称按标准对象名处理,可按需加引号。 + @@ -2332,33 +2358,51 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" -CancelRequest (F) + +CancelRequest (F) + -Int32(16) + + Int32(16) + -消息内容的长度,以字节为单位,包括此长度字段本身。 + + 消息内容的长度,以字节为单位,包括此长度字段本身。 + -Int32(80877102) + + Int32(80877102) + -取消请求代码。此值的最高 16 位为 1234,最低 16 位为 5678。(为避免混淆,此代码不能与任何协议版本号相同。) + + 取消请求代码。此值的最高 16 位为 1234,最低 16 位为 5678。(为避免混淆,此代码不能与任何协议版本号相同。) + -Int32 + + Int32 + -目标后端的进程 ID。 + + 目标后端的进程 ID。 + -Int32 + + Int32 + -目标后端的密钥。 + + 目标后端的密钥。 + @@ -4003,7 +4047,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 严重性: 字段内容为ERROR, FATAL, 或 + 严重性: 字段内容为ERROR, FATAL, 或 PANIC (在错误消息中), 或 WARNING, NOTICE, DEBUG, INFO, 或 LOG (在通知消息中), @@ -4041,7 +4085,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 消息: 主要的人类可读错误消息。 + 消息: 主要的人类可读错误消息。 这应该准确但简洁(通常一行)。 总是存在。 @@ -4063,7 +4107,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 提示: 关于问题应该怎么做的一个可选建议。 + 提示: 关于问题应该怎么做的一个可选建议。 这意在与细节不同,它提供建议(可能不合适)而不是硬性事实。 可能会跨越多行。 @@ -4096,7 +4140,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" q - 内部查询: 一个失败的内部生成命令的文本。 + 内部查询: 一个失败的内部生成命令的文本。 例如,这可能是由PL/pgSQL函数发出的SQL查询。 @@ -4129,7 +4173,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 表名: 如果错误与特定表相关联,则为表的名称。(有关表模式名称的名称,请参考模式名称字段。) + 表名: 如果错误与特定表相关联,则为表的名称。(有关表模式名称的名称,请参考模式名称字段。) @@ -4139,7 +4183,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 列名: 如果错误与特定表列相关联,则为列的名称。(请参考模式和表名字段以识别表。) + 列名: 如果错误与特定表列相关联,则为列的名称。(请参考模式和表名字段以识别表。) @@ -4149,7 +4193,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 数据类型名称: 如果错误与特定数据类型相关联,则为数据类型的名称。 + 数据类型名称: 如果错误与特定数据类型相关联,则为数据类型的名称。 (有关数据类型模式的名称,请参阅模式名称字段。) @@ -4160,7 +4204,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 约束名称: 如果错误与特定约束相关联,则为约束的名称。请参考上面列出的字段,了解相关表或域。 + 约束名称: 如果错误与特定约束相关联,则为约束的名称。请参考上面列出的字段,了解相关表或域。 (为此,即使索引不是使用约束语法创建的,也将其视为约束。) @@ -4171,7 +4215,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 文件: 报告错误的源代码位置的文件名。 + 文件: 报告错误的源代码位置的文件名。 @@ -4724,13 +4768,13 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" -协议 3.0 与之前版本的变化总结 +自协议 2.0 以来的变更总结 - 本节概述了协议 3.0 与之前协议版本之间的变化。这可以帮助那些需要实现同时处理多种协议版本的客户端库的开发者,或仅仅出于好奇的读者。 - + 本节提供一份简要的变更清单,供准备将现有客户端库更新到协议 3.0 的开发者参考。 + -初始启动包采用灵活的字符串列表格式,取代了固定格式。注意,运行时参数的会话默认值现在可以直接在启动包中指定。(实际上,以前也能通过 options 字段实现,但由于 options 的宽度有限,且无法引用值中的空白,这种方法并不稳妥。) +初始启动包采用灵活的字符串列表格式,取代了固定格式。注意,运行时参数的会话默认值现在可以直接在启动包中指定。(实际上,以前也能通过 options 字段实现,但由于 options 的宽度有限,且无法用引号保护值中的空白字符,这种方法并不稳妥。) 现在,所有消息都在消息类型字节之后紧跟一个长度计数(启动包除外,它没有类型字节)。另请注意,PasswordMessage 现在也有类型字节。 diff --git a/zh/11/queries.sgml b/zh/11/queries.sgml index 33d02b62..3ac2e472 100644 --- a/zh/11/queries.sgml +++ b/zh/11/queries.sgml @@ -487,7 +487,7 @@ FROM (VALUES ('anne', 'smith'), ('bob', 'jones'), ('joe', 'blow')) - 表函数是那些生成行集合的函数,这些行可以由基本数据类型(标量类型)组成,也可以由复合数据类型(表行)组成。它们在查询的FROM子句中用法类似于表、视图或子查询。表函数返回的列可以像表、视图或子查询的列一样,出现在SELECTJOINWHERE子句中。 + 表函数是那些生成行集合的函数,这些行可以由基础类型(标量类型)组成,也可以由复合数据类型(表行)组成。它们在查询的FROM子句中用法类似于表、视图或子查询。表函数返回的列可以像表、视图或子查询的列一样,出现在SELECTJOINWHERE子句中。 @@ -525,7 +525,7 @@ UNNEST( array_expression , ... - 如果没有提供列的别名,那么对于一个返回基数据类型的函数,列名也与该函数 + 如果没有提供列的别名,那么对于一个返回基础类型的函数,列名也与该函数 名相同。对于一个返回复合类型的函数,结果列会从该类型的属性得到名称。 diff --git a/zh/11/rangetypes.sgml b/zh/11/rangetypes.sgml index 8457287b..e29cda85 100644 --- a/zh/11/rangetypes.sgml +++ b/zh/11/rangetypes.sgml @@ -159,21 +159,25 @@ SELECT '[4,4)'::int4range; 构造范围 - 每个范围类型都有一个与其同名的构造函数。使用构造函数通常比编写范围字面常量更方便,因为无需对边界值额外加引号。构造函数接受两个或三个参数。两个参数的形式构造标准形式的范围(包含下界,不包含上界);三个参数的形式则按第三个参数指定的形式构造范围边界。第三个参数必须是以下字符串之一:(), - (], - [)[]。例如: --- The full form is: lower bound, upper bound, and text argument indicating --- inclusivity/exclusivity of bounds. + + 每种范围类型都有一个与范围类型同名的构造函数。使用构造函数通常比书写范围字面量更方便,因为这样无需为界限值额外加引号。构造函数接受两个或三个参数。两个参数的形式构造标准形式的范围(下界包含,上界排除),而三个参数的形式则按第三个参数指定的界限形式构造范围。第三个参数必须是下列字符串之一: + ()、 + (]、 + [)或者 + []。 + 例如: + + +-- 完整形式为:下界、上界,以及指示界限包含性/排除性的文本参数。 SELECT numrange(1.0, 14.0, '(]'); --- If the third argument is omitted, '[)' is assumed. +-- 如果省略第三个参数,则假定为 '[)'。 SELECT numrange(1.0, 14.0); --- Although '(]' is specified here, on display the value will be converted to --- canonical form, since int8range is a discrete range type (see below). +-- 虽然这里指定的是 '(]',但显示时该值会转换为规范形式,因为 int8range 是离散范围类型(见下文)。 SELECT int8range(1, 14, '(]'); --- Using NULL for either bound causes the range to be unbounded on that side. +-- 任一界限使用 NULL 都会使该侧无界。 SELECT numrange(NULL, 2.2); diff --git a/zh/11/recovery-config.sgml b/zh/11/recovery-config.sgml index db096382..178d9c57 100644 --- a/zh/11/recovery-config.sgml +++ b/zh/11/recovery-config.sgml @@ -54,7 +54,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows 这个信息可以被用来把归档截断为支持从当前恢复重启所需的最小值。 对于单一备库配置,模块常常被用在archive_cleanup_command中,例如: archive_cleanup_command = 'pg_archivecleanup /mnt/server/archivedir %r' - 但是注意,如果多个备库正在从同一个归档目录中恢复,你将需要保证只有当任意服务器都不再需要 WAL 文件时才会删除它们。 + 但是注意,如果多个备库正在从同一个归档目录中恢复,你将需要保证只有当所有服务器都不再需要这些 WAL 文件时才会删除它们。 archive_cleanup_command通常被用于一种温备配置(见)中。 要在该命令中嵌入一个真正的%字符,需要写成%% @@ -106,7 +106,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows - 这个参数指定(pg_create_restore_point()所创建)的已命名的恢复点,恢复将进入该恢复点。 + 这个参数指定(pg_create_restore_point()所创建)的已命名的恢复点,恢复将进行到该恢复点。 @@ -128,7 +128,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows recovery_target_lsn (pg_lsn) recovery_target_lsn 恢复参数 - 此参数指定恢复要进行到的预写式日志位置的 LSN。精确的停止点还受 影响。此参数使用系统数据类型 pg_lsn 解析。 + 此参数指定恢复要进行到的预写日志位置的 LSN。精确的停止点还受 影响。此参数使用系统数据类型 pg_lsn 解析。 @@ -164,13 +164,13 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows 最后,shutdown将在达到恢复目标之后停止服务器。 - 使用pause设置的目的是:如果这个恢复目标就是恢复最想要的位置,就允许对数据库执行查询。 + 使用pause设置的目的是允许对数据库执行查询,以检查这个恢复目标是否为最合适的恢复位置。 暂停的状态可以使用pg_wal_replay_resume()(见)继续,这会让恢复终结。 如果这个恢复目标不是想要的停止点,那么关闭服务器,将恢复目标设置改为一个稍后的目标并且重启以继续恢复。 要让实例在想要的重放点那里准备好,shutdown设置可以派上用场。 - 该实例将仍能重放更多 WAL 记录(并且事实上将不得不重放从下一次它被启动后最后一个检查点以来的 WAL 记录)。 + 该实例将仍能重放更多 WAL 记录(并且事实上,下次启动时必须重新回放自上一个检查点以来的 WAL 记录)。 注意,将 recovery_target_action 设为 shutdown 时,recovery.conf 不会被重命名,因此除非更改配置或手动删除 recovery.conf 文件,否则之后每次启动都会立即关闭。 如果未设置恢复目标,此设置不起作用。如果未启用 ,则 pause 的行为与 shutdown 相同。 @@ -213,13 +213,33 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows - recovery_min_apply_delay (integer) recovery_min_apply_delay 恢复参数 + recovery_min_apply_delay (integer) + + recovery_min_apply_delay 恢复参数 + + - 默认情况下,备库会尽快恢复来自主库的 WAL 记录。保留一份有时间延迟的数据副本可能很有用,可以为纠正导致数据丢失的错误提供机会。此参数允许将恢复延迟固定的一段时间,未指定单位时以毫秒计。例如,设为 5min 时,只有备库系统时间比主库报告的提交时间至少晚五分钟,备库才会重放该事务的提交。 - 服务器之间的复制延迟可能超过此参数的值,此时不会增加额外延迟。注意,延迟是根据主库写入的 WAL 时间戳与备库当前时间之间的差值计算的。网络滞后或级联复制配置造成的传输延迟,可能显著减少实际等待时间。如果主库和备库的系统时钟不同步,可能导致恢复比预期更早地应用记录;但这不是主要问题,因为此参数的实用设置值远大于服务器之间通常的时间偏差。 - 延迟只作用于事务提交的 WAL 记录。其他记录会尽快重放,这不会造成问题,因为 MVCC 可见性规则确保在相应提交记录应用之前,它们的影响不可见。 - 正在恢复的数据库达到一致状态后,延迟就会生效,直到备库被提升或触发。此后,备库将不再继续等待,而是结束恢复。 - 此参数面向流复制部署设计;但只要指定了它,在所有情况下都会生效。使用此功能会延迟 hot_standby_feedback,可能导致主库膨胀;同时使用二者时应谨慎。 synchronous_commit 设为 remote_apply 时,同步复制会受此设置影响;每次 COMMIT 都必须等待提交被应用。 + + 默认情况下,备库会尽快恢复来自主库的 WAL 记录。保留一份延迟的数据副本可能很有用,因为它提供了纠正数据丢失错误的机会。此参数允许将恢复延迟一段固定时间;如果没有指定单位,则以毫秒计。例如,将此参数设置为 5min 时,只有当备库系统时间比主库报告的提交时间至少晚五分钟,备库才会重放各事务的提交。 + + + 服务器之间的复制延迟可能超过此参数的值,这种情况下不会增加延迟。注意,延迟根据主库写入的 WAL 时间戳与备库当前时间之差计算。网络延迟或级联复制配置导致的传输延迟,可能显著缩短实际等待时间。如果主库和备库的系统时钟不同步,恢复时可能比预期更早应用记录;但这通常不是主要问题,因为此参数的实用取值远大于服务器间常见的时间偏差。 + + + 延迟仅发生在事务提交的 WAL 记录上。其他记录会尽快重放;这不会造成问题,因为 MVCC 可见性规则确保在对应提交记录被应用之前,它们的效果不会可见。 + + + 恢复中的数据库达到一致状态后开始延迟,直到备库被提升或触发。此后,备库会结束恢复,不再等待。 + + + 此参数旨在用于流复制部署;不过,只要指定了此参数,它就会在所有情况下生效。使用此功能也会延迟 hot_standby_feedback,可能导致主库膨胀;同时使用两者时应谨慎。 + + + 当 synchronous_commit 设置为 remote_apply 时,同步复制会受到此设置影响;每个 COMMIT 都必须等待提交被应用。 + + + + diff --git a/zh/11/ref/abort.sgml b/zh/11/ref/abort.sgml index 7d271a43..dce850bc 100644 --- a/zh/11/ref/abort.sgml +++ b/zh/11/ref/abort.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ABORT 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/alter_aggregate.sgml b/zh/11/ref/alter_aggregate.sgml index c5bd8344..3daf286a 100644 --- a/zh/11/ref/alter_aggregate.sgml +++ b/zh/11/ref/alter_aggregate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER AGGREGATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/alter_collation.sgml b/zh/11/ref/alter_collation.sgml index 379a9542..ca34304e 100644 --- a/zh/11/ref/alter_collation.sgml +++ b/zh/11/ref/alter_collation.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER COLLATION 7 - SQL - Language Statements + SQL - 语言语句 @@ -96,7 +96,8 @@ ALTER COLLATION name SET SCHEMA new_sche 注解 - 创建排序规则对象时,该排序规则的提供者特定版本会记录在系统目录中。 + 使用 ICU 库提供的排序规则时,创建排序规则对象会在系统目录中记录 + ICU 给出的排序器版本。 使用该排序规则时,会将当前版本与记录的版本进行比较;如果二者不匹 配,就会发出警告,例如: @@ -106,16 +107,16 @@ HINT: Rebuild all objects affected by this collation and run ALTER COLLATION pg 排序规则定义的变化可能导致索引损坏及其他问题,因为数据库系统依赖已 存储对象具有特定的排序顺序。一般来说应避免这种情况,但在某些合理情 - 形下仍可能发生,例如将操作系统升级到新的主版本,或者使用 + 形下仍可能发生,例如使用 pg_upgrade升级到链接了较新 ICU 版本的服务器二进 制文件时。出现这种情况时,应重建所有依赖该排序规则的对象,例如使用 REINDEX。完成后,可以使用命令 ALTER COLLATION ... REFRESH VERSION刷新排序规则 - 版本。这样会更新系统目录,使其记录当前的排序规则版本,并让该警告消 + 版本。这样会更新系统目录,使其记录当前的排序器版本,并让该警告消 失。请注意,这实际上并不会检查所有受影响对象是否都已被正确重建。 - 可以使用以下查询找出当前数据库中所有需要刷新的排序规则,以及依赖这些排序规则的对象:以下查询可用于识别当前数据库中所有需要刷新的排序规则,以及依赖它们的对象: ALTER CONVERSION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/alter_database.sgml b/zh/11/ref/alter_database.sgml index 516bc49b..9132cf6d 100644 --- a/zh/11/ref/alter_database.sgml +++ b/zh/11/ref/alter_database.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER DATABASE 7 - SQL - Language Statements + SQL - 语言语句 @@ -59,7 +59,9 @@ ALTER DATABASE name RESET ALL 第三种形式更改数据库的所有者。要更改所有者,必须拥有该数据库,并且还必须是新所有者角色的直接或间接成员,并且必须拥有CREATEDB权限。(请注意,超级用户会自动拥有所有这些权限。) - 第四种形式更改数据库的默认表空间。只有数据库所有者或超级用户可以执行此操作;还必须拥有新表空间的创建权限。此命令会将数据库旧默认表空间中的所有表或索引物理移动到新表空间。对该数据库而言,新默认表空间必须为空,并且不能有任何人连接到该数据库。非默认表空间中的表和索引不受影响。 + + 第四种形式更改数据库的默认表空间。只有数据库拥有者或者超级用户可以这样做;你还必须对新表空间具有创建权限。该命令会将数据库旧默认表空间中的所有表和索引在物理上移动到新表空间中。对于该数据库而言,新默认表空间必须为空,并且不能有人连接到该数据库。位于非默认表空间中的表和索引不受影响。 + 其余形式会更改某个PostgreSQL数据库的运行时配置变量的会话默认值。此后每当在该数据库中启动一个新会话时,指定的值就会成为会话默认值。数据库特定的默认值会覆盖postgresql.conf中的设置,或者从postgres命令行接收到的设置。只有数据库拥有者或者超级用户才能更改该数据库的会话默认值。某些变量不能以这种方式设置,或者只能由超级用户设置。 @@ -82,9 +84,7 @@ ALTER DATABASE name RESET ALL allowconn - - 如果为假,则没有人能连接到这个数据库。 - + 如果为 false,则任何人都不能连接到该数据库。 @@ -100,7 +100,9 @@ ALTER DATABASE name RESET ALL istemplate - 如果为 true,则任何拥有CREATEDB权限的用户都可以克隆该数据库;如果为 false,则只有超级用户或数据库所有者可以克隆它。 + + 如果为 true,则任何具有 CREATEDB 权限的用户都可以克隆该数据库;如果为 false,则只有超级用户或该数据库的拥有者可以克隆它。 + @@ -139,9 +141,17 @@ ALTER DATABASE name RESET ALL configuration_parameter value - 将此数据库的会话默认值设置为指定配置参数的给定值。如果指定valueDEFAULT,或者等效地使用RESET,则删除数据库特定设置,因此新会话将继承系统范围的默认设置。使用RESET ALL清除所有数据库特定设置。SET FROM CURRENT将会话当前参数值保存为数据库特定值。 + + 将此数据库在指定配置参数上的会话默认值设为给定值。如果 + valueDEFAULT,或者等效地使用了 + RESET,则数据库特定设置会被移除,因此新会话将继承系统范围的默认设置。使用 + RESET ALL可清除所有数据库特定设置。 + SET FROM CURRENT会把该参数在当前会话中的值保存为数据库特定值。 + - 有关允许的参数名称和值的更多信息,请参见 + + 关于允许的参数名和值的更多信息,见。 + diff --git a/zh/11/ref/alter_default_privileges.sgml b/zh/11/ref/alter_default_privileges.sgml index b19457b2..0fddb225 100644 --- a/zh/11/ref/alter_default_privileges.sgml +++ b/zh/11/ref/alter_default_privileges.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER DEFAULT PRIVILEGES 7 - SQL - Language Statements + SQL - 语言语句 @@ -116,8 +116,8 @@ REVOKE [ GRANT OPTION FOR ] 一个现有模式的名称。如果指定,将修改以后在该模式中创建的对象的默认权限。 如果省略IN SCHEMA,则修改全局默认权限。 - 在为模式和大对象设置权限时,不允许使用IN SCHEMA, - 因为模式不能嵌套,而大对象不属于任何模式。 + 在为模式设置权限时,不允许使用IN SCHEMA, + 因为模式不能嵌套。 diff --git a/zh/11/ref/alter_domain.sgml b/zh/11/ref/alter_domain.sgml index 5af8b2be..97c34014 100644 --- a/zh/11/ref/alter_domain.sgml +++ b/zh/11/ref/alter_domain.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER DOMAIN 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/alter_event_trigger.sgml b/zh/11/ref/alter_event_trigger.sgml index 99cf937f..5f35b6d4 100644 --- a/zh/11/ref/alter_event_trigger.sgml +++ b/zh/11/ref/alter_event_trigger.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER EVENT TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -58,7 +58,7 @@ ALTER EVENT TRIGGER name RENAME TO new_owner - 该事件触发器的新拥有者的用户名。 + 该事件触发器的新所有者的用户名。 @@ -94,7 +94,7 @@ ALTER EVENT TRIGGER name RENAME TO - 另见 + 参见 diff --git a/zh/11/ref/alter_extension.sgml b/zh/11/ref/alter_extension.sgml index dd8eac79..86286dec 100644 --- a/zh/11/ref/alter_extension.sgml +++ b/zh/11/ref/alter_extension.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER EXTENSION 7 - SQL - Language Statements + SQL - 语言语句 @@ -71,7 +71,10 @@ ALTER EXTENSION name DROP 描述 - ALTER EXTENSION更改已安装扩展的定义。有几个子形式: + ALTER EXTENSION更改已安装扩展的定义。 + 其子形式如下: + + UPDATE @@ -112,7 +115,10 @@ ALTER EXTENSION name DROP - 有关这些操作的更多信息。 + + + 有关这些操作的更多信息,见。 + 要使用ALTER EXTENSION,你必须拥有该扩展。 diff --git a/zh/11/ref/alter_foreign_data_wrapper.sgml b/zh/11/ref/alter_foreign_data_wrapper.sgml index 44945b43..7c89c190 100644 --- a/zh/11/ref/alter_foreign_data_wrapper.sgml +++ b/zh/11/ref/alter_foreign_data_wrapper.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER FOREIGN DATA WRAPPER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/alter_foreign_table.sgml b/zh/11/ref/alter_foreign_table.sgml index 476bc2b5..4ad45807 100644 --- a/zh/11/ref/alter_foreign_table.sgml +++ b/zh/11/ref/alter_foreign_table.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER FOREIGN TABLE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/alter_function.sgml b/zh/11/ref/alter_function.sgml index ababf315..71e4fe73 100644 --- a/zh/11/ref/alter_function.sgml +++ b/zh/11/ref/alter_function.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER FUNCTION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/alter_group.sgml b/zh/11/ref/alter_group.sgml index 26b7f7c8..37888a95 100644 --- a/zh/11/ref/alter_group.sgml +++ b/zh/11/ref/alter_group.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER GROUP 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/alter_index.sgml b/zh/11/ref/alter_index.sgml index 8785b84f..d94086bf 100644 --- a/zh/11/ref/alter_index.sgml +++ b/zh/11/ref/alter_index.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER INDEX 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/alter_language.sgml b/zh/11/ref/alter_language.sgml index f9b7bec8..f1f6efc6 100644 --- a/zh/11/ref/alter_language.sgml +++ b/zh/11/ref/alter_language.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER LANGUAGE 7 - SQL - Language Statements + SQL - 语言语句 @@ -31,8 +31,8 @@ ALTER [ PROCEDURAL ] LANGUAGE name OWNER TO { ALTER LANGUAGE更改一种过程语言的定义。 - 目前唯一的功能是重命名该语言或为其指定新的拥有者。 - 要使用ALTER LANGUAGE,你必须是超级用户或者该语言的拥有者。 + 目前唯一的功能是重命名该语言或为其指定新的所有者。 + 要使用ALTER LANGUAGE,你必须是超级用户或者该语言的所有者。 @@ -62,7 +62,7 @@ ALTER [ PROCEDURAL ] LANGUAGE name OWNER TO { new_owner - 该语言的新拥有者 + 该语言的新所有者 diff --git a/zh/11/ref/alter_large_object.sgml b/zh/11/ref/alter_large_object.sgml index f962ec9e..a703b418 100644 --- a/zh/11/ref/alter_large_object.sgml +++ b/zh/11/ref/alter_large_object.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER LARGE OBJECT 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/alter_materialized_view.sgml b/zh/11/ref/alter_materialized_view.sgml index 746f2a11..6102379d 100644 --- a/zh/11/ref/alter_materialized_view.sgml +++ b/zh/11/ref/alter_materialized_view.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER MATERIALIZED VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/alter_opclass.sgml b/zh/11/ref/alter_opclass.sgml index 9ea60c82..6d0da98d 100644 --- a/zh/11/ref/alter_opclass.sgml +++ b/zh/11/ref/alter_opclass.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER OPERATOR CLASS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/alter_operator.sgml b/zh/11/ref/alter_operator.sgml index 0ad43b17..6a7c3bcc 100644 --- a/zh/11/ref/alter_operator.sgml +++ b/zh/11/ref/alter_operator.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER OPERATOR 7 - SQL - Language Statements + SQL - 语言语句 @@ -101,7 +101,7 @@ ALTER OPERATOR name ( { left_type - 注解 + 示例 更改自定义操作符的拥有者,该操作符为a @@ b,类型为text diff --git a/zh/11/ref/alter_opfamily.sgml b/zh/11/ref/alter_opfamily.sgml index 47aff9e6..d8999797 100644 --- a/zh/11/ref/alter_opfamily.sgml +++ b/zh/11/ref/alter_opfamily.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER OPERATOR FAMILY 7 - SQL - Language Statements + SQL - 语言语句 @@ -232,7 +232,9 @@ ALTER OPERATOR FAMILY name USING name RENAME TO < CONNECTION 'conninfo' - 该子句替换最初由设置的连接字符串。 + 该子句更改最初由设置的连接属性。 详情请参见该命令。 diff --git a/zh/11/ref/alter_system.sgml b/zh/11/ref/alter_system.sgml index 72f81233..cc40d0e2 100644 --- a/zh/11/ref/alter_system.sgml +++ b/zh/11/ref/alter_system.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER SYSTEM 7 - SQL - Language Statements + SQL - 语言语句 @@ -80,8 +80,7 @@ ALTER SYSTEM RESET ALL - 对于某些接受列表的参数,带引号的值会生成带双引号的输出,以保留空 - 格和逗号;对于另一些参数,则必须在单引号字符串内部使用双引号才能 + 对于某些接受列表的参数,带引号的值会生成带双引号的输出,以保留空白和逗号;对于另一些参数,则必须在单引号字符串内部使用双引号才能 达到这种效果。 diff --git a/zh/11/ref/alter_table.sgml b/zh/11/ref/alter_table.sgml index fa660f5d..a80463b2 100644 --- a/zh/11/ref/alter_table.sgml +++ b/zh/11/ref/alter_table.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TABLE 7 - SQL - Language Statements + SQL - 语言语句 @@ -726,7 +726,7 @@ WITH ( MODULUS numeric_literal, REM DROP COLUMN形式不会从物理上删除列,而只是使其对 SQL 操作不可见。表后续的插入和更新操作会为该列存储空值。因此,删除列的速度很快,但不会立即减少表在磁盘上的大小,因为被删除列占用的空间不会被回收。随着现有行被更新,空间会逐渐回收。(删除系统oid列时不适用这些说明;删除该列会立即重写表。) - 若要强制立即回收已删除列所占的空间,可以执行任何一种会导致整表重写的ALTER TABLE形式。这样会重新构造每一行,并用空值替换被删除的列。 + 若要强制立即回收已删除列所占的空间,可以执行任何一种会导致整表重写的ALTER TABLE形式。这样会重建每一行,并用空值替换被删除的列。 diff --git a/zh/11/ref/alter_tablespace.sgml b/zh/11/ref/alter_tablespace.sgml index ada74112..6fadbfb3 100644 --- a/zh/11/ref/alter_tablespace.sgml +++ b/zh/11/ref/alter_tablespace.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TABLESPACE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/alter_trigger.sgml b/zh/11/ref/alter_trigger.sgml index 0e58bbbd..7e0ee6c4 100644 --- a/zh/11/ref/alter_trigger.sgml +++ b/zh/11/ref/alter_trigger.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -31,7 +31,9 @@ ALTER TRIGGER name ON ALTER TRIGGER更改现有触发器的属性。RENAME子句更改给定触发器的名称,但不以其他方式更改触发器定义。DEPENDS ON EXTENSION子句将触发器标记为依赖扩展,因此扩展被删除时触发器也会自动删除。 - 要更改触发器的属性,必须拥有触发器所在的表。 + + 若要更改触发器的属性,你必须拥有该触发器所作用的表。 + @@ -110,7 +112,7 @@ ALTER TRIGGER emp_stamp ON emp DEPENDS ON EXTENSION emplib; - 另见 + 参见 diff --git a/zh/11/ref/alter_tsconfig.sgml b/zh/11/ref/alter_tsconfig.sgml index ef8f24cf..453d7ee7 100644 --- a/zh/11/ref/alter_tsconfig.sgml +++ b/zh/11/ref/alter_tsconfig.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TEXT SEARCH CONFIGURATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/alter_tsdictionary.sgml b/zh/11/ref/alter_tsdictionary.sgml index 8c11355e..9fedf32d 100644 --- a/zh/11/ref/alter_tsdictionary.sgml +++ b/zh/11/ref/alter_tsdictionary.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TEXT SEARCH DICTIONARY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/alter_tsparser.sgml b/zh/11/ref/alter_tsparser.sgml index 525064c9..0844cb0a 100644 --- a/zh/11/ref/alter_tsparser.sgml +++ b/zh/11/ref/alter_tsparser.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TEXT SEARCH PARSER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/alter_tstemplate.sgml b/zh/11/ref/alter_tstemplate.sgml index fa4157f9..a3eec599 100644 --- a/zh/11/ref/alter_tstemplate.sgml +++ b/zh/11/ref/alter_tstemplate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TEXT SEARCH TEMPLATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/alter_type.sgml b/zh/11/ref/alter_type.sgml index 6d41c1c0..b68c81cd 100644 --- a/zh/11/ref/alter_type.sgml +++ b/zh/11/ref/alter_type.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TYPE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/alter_user.sgml b/zh/11/ref/alter_user.sgml index b6544c05..55150300 100644 --- a/zh/11/ref/alter_user.sgml +++ b/zh/11/ref/alter_user.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER USER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/alter_user_mapping.sgml b/zh/11/ref/alter_user_mapping.sgml index 0083f95b..1e7245a4 100644 --- a/zh/11/ref/alter_user_mapping.sgml +++ b/zh/11/ref/alter_user_mapping.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER USER MAPPING 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/alter_view.sgml b/zh/11/ref/alter_view.sgml index 4eaccd4d..28a35509 100644 --- a/zh/11/ref/alter_view.sgml +++ b/zh/11/ref/alter_view.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/analyze.sgml b/zh/11/ref/analyze.sgml index e867186d..682f1412 100644 --- a/zh/11/ref/analyze.sgml +++ b/zh/11/ref/analyze.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ANALYZE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/begin.sgml b/zh/11/ref/begin.sgml index dc5eff7b..8c68c21c 100644 --- a/zh/11/ref/begin.sgml +++ b/zh/11/ref/begin.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation BEGIN 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/call.sgml b/zh/11/ref/call.sgml index 64781670..7582f545 100644 --- a/zh/11/ref/call.sgml +++ b/zh/11/ref/call.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CALL 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/checkpoint.sgml b/zh/11/ref/checkpoint.sgml index e9d12c3a..53544983 100644 --- a/zh/11/ref/checkpoint.sgml +++ b/zh/11/ref/checkpoint.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CHECKPOINT 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/close.sgml b/zh/11/ref/close.sgml index 415ec160..deb8a9be 100644 --- a/zh/11/ref/close.sgml +++ b/zh/11/ref/close.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation CLOSE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/cluster.sgml b/zh/11/ref/cluster.sgml index 55f14ec5..9c7e8a0d 100644 --- a/zh/11/ref/cluster.sgml +++ b/zh/11/ref/cluster.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CLUSTER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/clusterdb.sgml b/zh/11/ref/clusterdb.sgml index f7112fa7..b78995d4 100644 --- a/zh/11/ref/clusterdb.sgml +++ b/zh/11/ref/clusterdb.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation clusterdb 1 - Application + 应用程序 diff --git a/zh/11/ref/comment.sgml b/zh/11/ref/comment.sgml index 52b848b5..89b06fe3 100644 --- a/zh/11/ref/comment.sgml +++ b/zh/11/ref/comment.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation COMMENT 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/commit.sgml b/zh/11/ref/commit.sgml index 962d0dbd..3513a1da 100644 --- a/zh/11/ref/commit.sgml +++ b/zh/11/ref/commit.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation COMMIT 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/commit_prepared.sgml b/zh/11/ref/commit_prepared.sgml index 3cdfcf03..b8429aa4 100644 --- a/zh/11/ref/commit_prepared.sgml +++ b/zh/11/ref/commit_prepared.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation COMMIT PREPARED 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/copy.sgml b/zh/11/ref/copy.sgml index be47bf24..f602ef5a 100644 --- a/zh/11/ref/copy.sgml +++ b/zh/11/ref/copy.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation COPY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/create_access_method.sgml b/zh/11/ref/create_access_method.sgml index 46bbc9b9..967df08a 100644 --- a/zh/11/ref/create_access_method.sgml +++ b/zh/11/ref/create_access_method.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE ACCESS METHOD 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/create_aggregate.sgml b/zh/11/ref/create_aggregate.sgml index 0418b1d5..dd31c2b4 100644 --- a/zh/11/ref/create_aggregate.sgml +++ b/zh/11/ref/create_aggregate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE AGGREGATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/create_cast.sgml b/zh/11/ref/create_cast.sgml index 353229a1..84a2ce12 100644 --- a/zh/11/ref/create_cast.sgml +++ b/zh/11/ref/create_cast.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE CAST 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/create_collation.sgml b/zh/11/ref/create_collation.sgml index af25bc82..3f95f242 100644 --- a/zh/11/ref/create_collation.sgml +++ b/zh/11/ref/create_collation.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE COLLATION 7 - SQL - Language Statements + SQL - 语言语句 @@ -94,7 +94,7 @@ CREATE COLLATION [ IF NOT EXISTS ] name FROM provider - 指定用于与此排序规则关联的区域设置服务的提供者。可能的值为: icuICU libclibc 是默认值。可用选项取决于操作系统和构建选项。 + 指定用于与此排序规则关联的区域设置服务的提供程序。可能的值为: icuICU libclibc 是默认值。可用选项取决于操作系统和构建选项。 @@ -155,7 +155,9 @@ CREATE COLLATION french (locale = 'fr_FR.utf8'); - 使用 ICU 提供者并采用德语电话簿排序顺序创建排序规则: + + 使用 ICU 提供程序并采用德语电话簿排序顺序创建一种排序规则: + CREATE COLLATION german_phonebook (provider = icu, locale = 'de-u-co-phonebk'); diff --git a/zh/11/ref/create_conversion.sgml b/zh/11/ref/create_conversion.sgml index fa50caff..1200e3b4 100644 --- a/zh/11/ref/create_conversion.sgml +++ b/zh/11/ref/create_conversion.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE CONVERSION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/create_database.sgml b/zh/11/ref/create_database.sgml index ed111233..cb3cd75a 100644 --- a/zh/11/ref/create_database.sgml +++ b/zh/11/ref/create_database.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE DATABASE 7 - SQL - Language Statements + SQL - 语言语句 @@ -46,7 +46,15 @@ CREATE DATABASE name CREATEDB 权限。见 - 默认情况下,新数据库将通过克隆标准系统数据库 template1 来创建。可以通过编写 TEMPLATE name 指定不同的模板。特别地,通过编写 TEMPLATE template0,可以创建一个仅包含由您的 PostgreSQL 版本预定义的标准对象的全新数据库。如果您希望避免复制可能已添加到 template1 的任何安装本地对象,此方法非常有用。 + + 默认情况下,新数据库通过克隆标准系统数据库 + template1 来创建。可以通过写成 TEMPLATE + name 指定其他模板。特别是, + 写成 TEMPLATE template0 时,可以创建一个全新的数据库, + 它只包含你的 PostgreSQL 版本预定义的标准对象。 + 如果你希望避免复制任何可能已添加到 template1 中的站点本地附加对象, + 这会很有用。 + @@ -56,25 +64,36 @@ CREATE DATABASE name name - 要创建的数据库名称。 + + 要创建的数据库名称。 + user_name - 新数据库所有者的角色名称,或使用 DEFAULT 以使用默认值(即执行命令的用户)。要创建由其他角色拥有的数据库,您必须是该角色的直接或间接成员,或为超级用户。 + 新数据库所有者的角色名称,或使用 DEFAULT 以使用默认值(即执行命令的用户)。要创建由其他角色拥有的数据库,你必须是该角色的直接或间接成员,或为超级用户。 template - 用于创建新数据库的模板名称,或使用 DEFAULT 以使用默认模板(template1)。 + + 用于创建新数据库的模板名称,或者指定 DEFAULT + 以使用默认模板(template1)。 + encoding - 新数据库中使用的字符集编码。指定字符串常量(例如 'SQL_ASCII'),或整数编码编号,或使用 DEFAULT 以使用默认编码(即模板数据库的编码)。PostgreSQL 服务器支持的字符集在 中有描述。请参见下方的附加限制。 + + 新数据库要使用的字符集编码。可指定字符串常量(例如 + 'SQL_ASCII')、整数编码编号,或者指定 + DEFAULT 以使用默认编码(即模板数据库的编码)。 + PostgreSQL 服务器支持的字符集见 + 。其他限制见下文。 + @@ -92,28 +111,40 @@ CREATE DATABASE name tablespace_name - 将与新数据库关联的表空间名称,或使用 DEFAULT 来使用模板数据库的表空间。该表空间将成为在此数据库中创建的对象的默认表空间。有关更多信息,请参见 + + 将与新数据库关联的表空间名称,或者指定 DEFAULT + 以使用模板数据库的表空间。该表空间将成为在此数据库中创建对象时使用的默认表空间。详见 + 。 + allowconn - 如果为 false,则没有人可以连接到此数据库。默认值为 true,允许连接(除非受其他机制(如 GRANT/REVOKE CONNECT)限制)。 + + 如果为 false,则任何人都不能连接到该数据库。默认值为 true,即允许连接 + (但仍受其他机制限制,例如 + GRANT/REVOKE CONNECT)。 + connlimit - 可以同时连接到此数据库的连接数。-1(默认值)表示无限制。 + + 可对该数据库建立的并发连接数。-1(默认值)表示不受限制。 + istemplate - 如果为 true,则任何拥有 CREATEDB 权限的用户都可以克隆此数据库;如果为 false(默认值),则只有超级用户或数据库所有者才能克隆它。 + + 如果为 true,则任何具有 CREATEDB 权限的用户都可以克隆该数据库;如果为 false(默认值),则只有超级用户或该数据库的拥有者可以克隆它。 + @@ -152,11 +183,24 @@ CREATE DATABASE name 。 - 为新数据库指定的字符集编码必须与所选的区域设置(LC_COLLATELC_CTYPE)兼容。如果区域设置为 C(或等效的 POSIX),则允许所有编码,但其他区域设置仅有一种编码能正常工作。(在 Windows 上,UTF-8 编码可与任何区域设置一起使用。)CREATE DATABASE 允许超级用户指定 SQL_ASCII 编码,而不管区域设置如何,但此选择已弃用,如果在数据库中存储了与区域设置不兼容编码的数据,可能导致字符串函数行为异常。 + + 为新数据库指定的字符集编码必须与所选区域设置(LC_COLLATE + 和 LC_CTYPE)兼容。如果区域设置为 C + (或等价的 POSIX),则允许所有编码;但对于其他区域设置,只有一种编码能够正常工作。(不过,在 Windows 上,UTF-8 编码可与任何区域设置一起使用。) + CREATE DATABASE 允许超级用户不考虑区域设置而指定 + SQL_ASCII 编码,但这种选择已弃用;如果数据库中存储了与该区域设置不兼容编码的数据,字符串函数的行为可能会出错。 + - 编码和区域设置必须与模板数据库匹配,除非使用 template0 作为模板。这是因为其他数据库可能包含与指定编码不匹配的数据,或包含受 LC_COLLATELC_CTYPE 影响排序顺序的索引。复制此类数据将导致数据库在新设置下出现损坏。然而,template0 被确认不包含任何会受影响的数据或索引。 + + 编码和区域设置必须与模板数据库的设置一致,除非使用 + template0 作为模板。这是因为其他数据库可能包含与指定编码不匹配的数据,或者包含排序顺序会受 + LC_COLLATELC_CTYPE 影响的索引。复制这样的数据会导致数据库在新设置下被视为损坏。不过,已知 + template0 不包含任何会受此影响的数据或索引。 + - CONNECTION LIMIT 选项仅近似强制执行;如果两个新会话几乎同时启动,而数据库仅剩一个连接 ,则有可能两者都会失败。此外,该限制对超级用户或后台工作进程不生效。 + + CONNECTION LIMIT 选项只是近似地被强制执行;如果两个新会话几乎同时启动,而该数据库只剩下一个连接,则两者都可能失败。此外,该限制对超级用户或后台工作进程无效。 + @@ -170,25 +214,39 @@ CREATE DATABASE lusiadas; - 要创建数据库sales,其所有者为用户 salesapp,默认表空间为 salesspace: + + 要创建一个由用户 salesapp 拥有、默认表空间为 + salesspace 的数据库 sales CREATE DATABASE sales OWNER salesapp TABLESPACE salesspace; - 要创建数据库music,使用不同的区域设置: + + 要创建一个使用不同区域设置的数据库 music: + + CREATE DATABASE music LC_COLLATE 'sv_SE.utf8' LC_CTYPE 'sv_SE.utf8' TEMPLATE template0; -在此示例中,TEMPLATE template0子句在指定的区域设置与template1中的区域设置不同时是必需的。(如果相同,则显式指定区域设置是多余的。) + + 在这个示例中,如果指定的区域设置与 template1 中的不同, + 则必须使用 TEMPLATE template0 子句。(如果相同, + 那么显式指定区域设置就是多余的。) + - 要创建数据库music2,使用不同的区域设置和不同的字符集编码: + + 要创建一个使用不同区域设置和不同字符集编码的数据库 + music2: + CREATE DATABASE music2 LC_COLLATE 'sv_SE.iso885915' LC_CTYPE 'sv_SE.iso885915' ENCODING LATIN9 TEMPLATE template0; -指定的区域设置和编码设置必须匹配,否则将报告错误。 + + 指定的区域设置和编码设置必须匹配,否则会报错。 + 请注意,区域设置名称是特定于操作系统的,因此上述命令未必在所有环境中都以相同方式工作。 diff --git a/zh/11/ref/create_domain.sgml b/zh/11/ref/create_domain.sgml index b3a10dde..916546fd 100644 --- a/zh/11/ref/create_domain.sgml +++ b/zh/11/ref/create_domain.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE DOMAIN 7 - SQL - Language Statements + SQL - 语言语句 @@ -86,7 +86,7 @@ CREATE DOMAIN name [ AS ] 该域的可选排序规则。如果未指定排序规则,则该域的排序规则行为与其 底层数据类型相同。如果指定了COLLATE,则底层 - 类型必须是一种可排序数据类型。 + 类型必须是一种支持排序规则的数据类型。 diff --git a/zh/11/ref/create_event_trigger.sgml b/zh/11/ref/create_event_trigger.sgml index ddf889db..3659259b 100644 --- a/zh/11/ref/create_event_trigger.sgml +++ b/zh/11/ref/create_event_trigger.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE EVENT TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -40,7 +40,7 @@ CREATE EVENT TRIGGER name CREATE EVENT TRIGGER创建一个新的事件触发器。 每当指定的事件发生,并且与该触发器关联的WHEN条件(如果有)得到 满足时,就会执行该触发器函数。有关事件触发器的一般性介绍,见 - 。创建事件触发器的用户将成为其拥有者。 + 。创建事件触发器的用户将成为其所有者。 @@ -77,8 +77,7 @@ CREATE EVENT TRIGGER name - 用于过滤事件的变量名称。这使得可以将触发器限定为只在支持该变量的部 - 分情形下触发。当前唯一支持的 + 用于过滤事件的变量名称。这样可以将触发器限定为只在原本支持的部分情形下触发。当前唯一支持的 filter_variableTAG @@ -168,7 +167,7 @@ CREATE EVENT TRIGGER abort_ddl ON ddl_command_start - 另见 + 参见 diff --git a/zh/11/ref/create_extension.sgml b/zh/11/ref/create_extension.sgml index 69fffd86..338fd980 100644 --- a/zh/11/ref/create_extension.sgml +++ b/zh/11/ref/create_extension.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE EXTENSION 7 - SQL - Language Statements + SQL - 语言语句 @@ -67,7 +67,12 @@ CREATE EXTENSION [ IF NOT EXISTS ] extension_name extension_name - 要安装的扩展的名称。PostgreSQL 将使用 SHAREDIR/extension/extension_name.control 文件中的信息创建扩展。 + + 要安装的扩展名称。PostgreSQL将根据 + SHAREDIR/extension/extension_name.control + 文件中的详细信息创建该扩展。 + @@ -112,7 +117,7 @@ CREATE EXTENSION [ IF NOT EXISTS ] extension_name old_version - FROM old_version 必须在且仅在尝试安装一个替换 旧式模块的扩展时指定,该模块仅是一组未打包为扩展的对象集合。此选项会导致 CREATE EXTENSION 运行一个替代安装脚本,将现有对象吸收进扩展中,而不是创建新对象。请注意 SCHEMA 指定了包含这些预先存在的对象的模式。 + FROM old_version 必须在且仅在尝试安装一个替换 旧式模块的扩展时指定,该模块仅是一组未打包为扩展的对象集合。此选项会导致 CREATE EXTENSION 运行一个替代安装脚本,将现有对象吸收进扩展中,而不是创建新对象。请确保 SCHEMA 指定的是包含这些现有对象的模式。 old_version的值由扩展作者决定,如果存在多个可升级为扩展的旧式模块版本,该值可能会有所不同。对于PostgreSQL 9.1 之前版本提供的标准附加模块,将模块更新为扩展形式时应使用unpackaged作为old_version的值。 @@ -157,7 +162,7 @@ CREATE EXTENSION [ IF NOT EXISTS ] extension_name 会在之后执行编写粗心的扩展脚本时实施攻击,使该用户获得超级用户权限。 不过,只有当特洛伊木马对象在脚本执行期间位于 search_path 中时,它们才会构成危险;这意味着它们 - 位于扩展的安装目标模式中,或位于它所依赖的某个扩展所属的模式中。 + 位于扩展的安装目标模式中,或位于它所依赖的某个扩展的目标模式中。 因此,处理那些脚本尚未经过仔细审查的扩展时,一个经验法则是: 只把它们安装到从未向任何不受信任用户授予、而且今后也不会授予 CREATE 权限的模式中。它们所依赖的任何扩展也应如此。 @@ -179,10 +184,14 @@ CREATE EXTENSION [ IF NOT EXISTS ] extension_name 示例 - 安装hstore扩展到当前数据库,并将其对象放入模式addons: + + 将 hstore 扩展安装到当前数据库中,并把 + 其对象放在 addons 模式中: CREATE EXTENSION hstore SCHEMA addons; -另一种实现相同功能的方法: + + 实现同样效果的另一种方式是: + SET search_path = addons; CREATE EXTENSION hstore; diff --git a/zh/11/ref/create_foreign_data_wrapper.sgml b/zh/11/ref/create_foreign_data_wrapper.sgml index 1eb28864..e7701eb2 100644 --- a/zh/11/ref/create_foreign_data_wrapper.sgml +++ b/zh/11/ref/create_foreign_data_wrapper.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE FOREIGN DATA WRAPPER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/create_foreign_table.sgml b/zh/11/ref/create_foreign_table.sgml index aa2ba21e..5e7a11b9 100644 --- a/zh/11/ref/create_foreign_table.sgml +++ b/zh/11/ref/create_foreign_table.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE FOREIGN TABLE 7 - SQL - Language Statements + SQL - 语言语句 @@ -134,9 +134,7 @@ WITH ( MODULUS numeric_literal, REM COLLATE collation - - COLLATE子句为该列(必须是一种可排序数据类型)指定一个排序规则。如果未指定,则使用该列数据类型的默认排序规则。 - + COLLATE子句为列指定排序规则(该列必须属于支持排序规则的数据类型)。如果未指定,则使用列数据类型的默认排序规则。 diff --git a/zh/11/ref/create_function.sgml b/zh/11/ref/create_function.sgml index c31dac3f..63bffd96 100644 --- a/zh/11/ref/create_function.sgml +++ b/zh/11/ref/create_function.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE FUNCTION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/create_group.sgml b/zh/11/ref/create_group.sgml index 06195a91..9a6538ed 100644 --- a/zh/11/ref/create_group.sgml +++ b/zh/11/ref/create_group.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE GROUP 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/create_index.sgml b/zh/11/ref/create_index.sgml index 3de0a637..039a3a1f 100644 --- a/zh/11/ref/create_index.sgml +++ b/zh/11/ref/create_index.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE INDEX 7 - SQL - Language Statements + SQL - 语言语句 @@ -54,7 +54,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] PostgreSQL提供了索引方法 - B-树、哈希、GiST、SP-GiST、GIN 以及 BRIN。用户也可以定义自己的索引 + B-树、hash、GiST、SP-GiST、GIN 以及 BRIN。用户也可以定义自己的索引 方法,但这相当复杂。 @@ -111,7 +111,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] 使用此选项时,PostgreSQL将在构建索引时不获取任何会阻止对表进行并发插入、更新或删除的锁;而标准索引构建会阻塞对表的写入(但不会阻塞读取),直到构建完成。使用此选项时有几个注意事项需要了解—请参见 对于临时表,CREATE INDEX始终是非并发的, - 因为没有其他会话可以访问它们,而且非并发创建索引的成本更低。 + 因为没有其他会话可以访问它们,而且非并发创建索引的代价更低。 @@ -119,20 +119,36 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] IF NOT EXISTS - 如果已存在同名关系,则不要抛出错误。此时会发出通知。请注意,无法保证现有索引与将要创建的索引有任何相似之处。指定IF NOT EXISTS时必须提供索引名称。 + + 如果同名关系已存在,则不抛出错误,而是发出一个提示。注意, + 现有索引并不保证与本应创建的索引有任何相似之处。指定 + IF NOT EXISTS时,必须提供索引名。 + INCLUDE - 可选的INCLUDE子句指定要作为非键列包含在索引中的列列表。非键列不能用于索引扫描的搜索限定条件,索引强制执行的任何唯一性约束或排他约束也会忽略这些列。不过,仅索引扫描可以直接从索引条目取得非键列的内容,无需访问索引所对应的表。因此,添加非键列可以让原本无法使用仅索引扫描的查询使用这种扫描。 + + 可选的INCLUDE子句指定一个列列表,这些列将作为 + 非键列包含在索引中。非键列不能用作索引扫描的 + 搜索限定条件,在索引强制执行的任何唯一性或排他约束中也会被忽略。不过, + 非键列的内容可以由仅索引扫描返回,而无需访问索引对应的表,因为它们 + 可直接从索引项中取得。因此,添加非键列可以让原本无法使用仅索引扫描 + 的查询也能使用它。 + 向索引添加非键列时,谨慎一些是明智的,尤其是宽列。如果索引元组超过该索引类型允许的最大大小,数据插入将失败。无论如何,非键列会复制索引所对应的表中的数据并使索引膨胀,从而可能降低搜索速度。 - INCLUDE子句中列出的列不需要适用的操作符类;对于给定访问方法,如果某些列的数据类型没有定义操作符类,该子句仍可包含这些列。 + + INCLUDE子句中列出的列不需要合适的操作符类; + 该子句可以包含数据类型尚未为给定访问方法定义操作符类的列。 + - 表达式不支持作为包含列,因为它们不能用于仅索引扫描。 + + 不支持将表达式作为包含列,因为它们不能用于仅索引扫描。 + 目前,只有 B-树 索引访问方法支持此功能。在 B-树 索引中,INCLUDE子句中列出的列值会包含在对应堆元组的叶元组中,但不会包含在用于树导航的上层索引条目中。 @@ -148,56 +164,80 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] ONLY - 如果表已分区,则表示创建索引时不要递归到分区。默认情况下会递归。 + + 表示如果该表是分区表,则不要递归地在各分区上创建索引。 + 默认会递归。 + table_name - 要建立索引的表名称(可能包含模式限定)。 + + 要建立索引的表名(可以是模式限定名)。 + method - 要使用的索引方法名称。可选项包括btreehashgistspgistginbrin,以及用户安装的访问方法(例如bloom)。默认方法是btree + + 要使用的索引方法的名称。选择包括btreehash、 + gistspgistgin、 + brin,或用户安装的访问方法,如 + bloom。 + 默认方法是btree。 + column_name - 表的列名称。 + + 一个表列的名称。 + expression - 基于表中一个或多个列的表达式。通常必须按照语法所示,在表达式两侧加上括号。不过,如果表达式采用函数调用的形式,则可以省略括号。 + + 一个基于表中一个或多个列的表达式。通常必须像语法中所示那样写在 + 外围圆括号中。不过,如果该表达式是函数调用形式,则可以省略圆括号。 + collation - 用于索引的排序规则名称。默认情况下,索引使用要建立索引的列所声明的排序规则,或要建立索引的表达式的结果排序规则。具有非默认排序规则的索引对于涉及使用非默认排序规则的表达式的查询可能很有用。 + + 将用于该索引的排序规则名称。默认情况下,索引使用被索引列声明的 + 排序规则,或者被索引表达式的结果排序规则。对于涉及使用非默认排序 + 规则表达式的查询,使用非默认排序规则的索引可能会很有用。 + opclass - 操作符类的名称。详细信息见下文。 + + 一个操作符类的名称。详见下文。 + ASC - 指定升序排序(这是默认值)。 + + 指定升序排序(默认)。 + @@ -211,14 +251,20 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] NULLS FIRST - 指定将空值排在非空值之前。当指定DESC时,这是默认值。 + + 指定把空值排序在非空值前面。在指定DESC时, + 这是默认行为。 + NULLS LAST - 指定将空值排在非空值之后。当未指定DESC时,这是默认值。 + + 指定把空值排序在非空值后面。在没有指定DESC时, + 这是默认行为。 + @@ -232,7 +278,11 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] tablespace_name - 要创建索引的表空间。如果未指定,则查询;对于临时表上的索引,则查询 + + 在其中创建索引的表空间。如果未指定,将查阅 + ;对于临时表上的索引,则查阅 + 。 + @@ -251,6 +301,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] 可选的WITH子句为索引指定存储参数。每一种 索引方法都有其各自允许的存储参数集合。 + B-树、hash、GiST 和 SP-GiST 索引方法都接受以下参数: @@ -263,7 +314,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - B-树、哈希、GiST 和 SP-GiST 索引方法都接受以下参数: + B-树索引还接受以下参数: @@ -276,7 +327,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - B-树索引还接受以下参数: + GiST 索引还接受以下参数: @@ -289,7 +340,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - GiST 索引还接受以下参数: + GIN 索引接受不同的参数: @@ -316,7 +367,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - 为该索引覆盖的全局设置。 + 自定义参数。 该值以千字节为单位。 @@ -324,7 +375,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - BRIN 索引接受以下参数: + BRIN 索引接受不同的参数: @@ -352,8 +403,8 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] 并发构建索引 - index - building concurrently + 索引 + 并发构建 @@ -467,12 +518,17 @@ Indexes: 生成这些索引的统计信息。 - 对于大多数索引方法,创建索引的速度取决于的设置。较大的值会减少创建索引所需的时间,但前提是不能将它设得大于实际可用的内存量,否则机器会进入交换。 + + 对于大多数索引方法,索引的创建速度取决于 + 的设置。较大的值将会减少 + 索引创建所需的时间,当然不要把它设置得超过实际可用的内存量(那会迫使 + 机器进行交换)。 + PostgreSQL可以在构建索引时利用多个 CPU, 以便更快处理表中的行。这项特性被称为并行索引构建。 - 对于支持并行构建索引的索引方法(当前为 B-树、GIN 和 BRIN), + 对于支持并行构建索引的索引方法(当前只有 B-树), maintenance_work_mem指定每次索引构建操作整体最多 可使用的内存量,而不管启动了多少工作者进程。通常,代价模型会自动决 定是否需要请求工作者进程,以及请求多少个。 @@ -510,11 +566,20 @@ Indexes: - 虽然带有CONCURRENTLY选项的CREATE INDEX支持并行构建且没有特殊限制,但实际只有第一次表扫描是并行执行的。 + + 虽然带有CONCURRENTLY选项的CREATE INDEX + 在没有特殊限制的情况下支持并行构建,但实际上只有第一次表扫描会以并行 + 方式执行。 + 使用删除索引。 - 早期版本的PostgreSQL也有 R-tree 索引方法。由于它相对于 GiST 方法没有显著优势,该方法已被删除。如果指定USING rtreeCREATE INDEX会将其解释为USING gist,以便简化旧数据库向 GiST 的转换。 + + 早期版本的PostgreSQL还提供过一种 R-tree + 索引方法。该方法已经被移除,因为它相对于 GiST 方法并无明显优势。如果 + 指定了USING rtreeCREATE INDEX + 会将其解释为USING gist,以简化旧数据库向 GiST 的转换。 + diff --git a/zh/11/ref/create_language.sgml b/zh/11/ref/create_language.sgml index afa16d63..18ca6cc1 100644 --- a/zh/11/ref/create_language.sgml +++ b/zh/11/ref/create_language.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE LANGUAGE 7 - SQL - Language Statements + SQL - 语言语句 @@ -55,7 +55,7 @@ CREATE [ OR REPLACE ] [ TRUSTED ] [ PROCEDURAL ] LANGUAGE - 新过程语言的名称。该名称在数据库内必须唯一。 + 新过程语言的名称。该名称不能与数据库中其他语言的名称重复。 diff --git a/zh/11/ref/create_materialized_view.sgml b/zh/11/ref/create_materialized_view.sgml index aeb4bf41..ca50832d 100644 --- a/zh/11/ref/create_materialized_view.sgml +++ b/zh/11/ref/create_materialized_view.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE MATERIALIZED VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/create_opclass.sgml b/zh/11/ref/create_opclass.sgml index 0e71beaf..eb57a114 100644 --- a/zh/11/ref/create_opclass.sgml +++ b/zh/11/ref/create_opclass.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE OPERATOR CLASS 7 - SQL - Language Statements + SQL - 语言语句 @@ -236,7 +236,7 @@ CREATE OPERATOR CLASS name [ DEFAUL - 在PostgreSQL 8.4 之前,OPERATOR子句可以包含RECHECK选项。现在不再支持它,因为索引操作符是否有损现在会在运行时动态确定。这使得系统可以高效处理操作符可能有损也可能无损的情况。 + 在PostgreSQL 8.4 之前,OPERATOR子句可以包含RECHECK选项。现在不再支持该选项,因为索引操作符是否有损会在运行时动态确定。这样可以高效处理操作符可能有损也可能无损的情况。 diff --git a/zh/11/ref/create_operator.sgml b/zh/11/ref/create_operator.sgml index f9348de7..71f250c4 100644 --- a/zh/11/ref/create_operator.sgml +++ b/zh/11/ref/create_operator.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE OPERATOR 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/create_opfamily.sgml b/zh/11/ref/create_opfamily.sgml index ebe6fd9c..23f2e669 100644 --- a/zh/11/ref/create_opfamily.sgml +++ b/zh/11/ref/create_opfamily.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE OPERATOR FAMILY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/create_policy.sgml b/zh/11/ref/create_policy.sgml index 2b562dc1..2208cec0 100644 --- a/zh/11/ref/create_policy.sgml +++ b/zh/11/ref/create_policy.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE POLICY 7 - SQL - Language Statements + SQL - 语言语句 @@ -257,17 +257,17 @@ CREATE POLICY name ON 命令 - SELECT/ALL policy - INSERT/ALL policy - UPDATE/ALL policy - DELETE/ALL policy + SELECT/ALL策略 + INSERT/ALL策略 + UPDATE/ALL策略 + DELETE/ALL策略 - USING expression - WITH CHECK expression - USING expression - WITH CHECK expression - USING expression + USING 表达式 + WITH CHECK 表达式 + USING 表达式 + WITH CHECK 表达式 + USING 表达式 diff --git a/zh/11/ref/create_procedure.sgml b/zh/11/ref/create_procedure.sgml index 014109b0..1c87b5f3 100644 --- a/zh/11/ref/create_procedure.sgml +++ b/zh/11/ref/create_procedure.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE PROCEDURE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/create_publication.sgml b/zh/11/ref/create_publication.sgml index b2bf2b7a..ec6a8a06 100644 --- a/zh/11/ref/create_publication.sgml +++ b/zh/11/ref/create_publication.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE PUBLICATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/create_role.sgml b/zh/11/ref/create_role.sgml index 4a379a7a..c25f6fa7 100644 --- a/zh/11/ref/create_role.sgml +++ b/zh/11/ref/create_role.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE ROLE 7 - SQL - Language Statements + SQL - 语言语句 @@ -107,7 +107,7 @@ in sync when changing the above synopsis! 这些子句决定某个角色是否被允许创建、更改、删除其他角色,为其添加注释, - 以及更改其安全标签。关于该权限赋予的具体能力,参见 + 更改其安全标签,以及授予或撤销其中的成员资格。关于该权限赋予的具体能力,参见 。若未指定,默认值是 NOCREATEROLE diff --git a/zh/11/ref/create_rule.sgml b/zh/11/ref/create_rule.sgml index 6367a679..6abd2969 100644 --- a/zh/11/ref/create_rule.sgml +++ b/zh/11/ref/create_rule.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE RULE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/create_schema.sgml b/zh/11/ref/create_schema.sgml index f3dc7a31..fede6380 100644 --- a/zh/11/ref/create_schema.sgml +++ b/zh/11/ref/create_schema.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE SCHEMA 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/create_sequence.sgml b/zh/11/ref/create_sequence.sgml index 24987272..81ad1fe9 100644 --- a/zh/11/ref/create_sequence.sgml +++ b/zh/11/ref/create_sequence.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE SEQUENCE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/create_server.sgml b/zh/11/ref/create_server.sgml index c4b79d02..7f438b0b 100644 --- a/zh/11/ref/create_server.sgml +++ b/zh/11/ref/create_server.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE SERVER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/create_statistics.sgml b/zh/11/ref/create_statistics.sgml index 40b1a139..eabdb73d 100644 --- a/zh/11/ref/create_statistics.sgml +++ b/zh/11/ref/create_statistics.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE STATISTICS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/create_subscription.sgml b/zh/11/ref/create_subscription.sgml index 738cf39b..a55439cf 100644 --- a/zh/11/ref/create_subscription.sgml +++ b/zh/11/ref/create_subscription.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE SUBSCRIPTION 7 - SQL - Language Statements + SQL - 语言语句 @@ -32,19 +32,18 @@ CREATE SUBSCRIPTION subscription_name描述 - CREATE SUBSCRIPTION添加一个新的逻辑复制订阅。 - 创建订阅的用户将成为该订阅的所有者。订阅名称必须与当前数据库中 - 任何现有订阅的名称不同。 + CREATE SUBSCRIPTION为当前数据库添加一个新订阅。 + 订阅名称必须与数据库中任何现有订阅的名称不同。 - 订阅表示与发布者的复制连接。因此,除了在本地系统目录中添加定义之外, - 该命令通常还会在发布者上创建一个复制槽。 + 订阅表示与发布者的复制连接。因此,该命令不仅会在本地系统目录中添加定义, + 还会在发布者上创建一个复制槽。 - 除非订阅初始即被禁用,否则在执行该命令所在事务提交时,会启动一个 - 逻辑复制工作进程为新订阅复制数据。 + 在执行该命令所在事务提交时,会启动一个逻辑复制工作进程, + 为新订阅复制数据。 diff --git a/zh/11/ref/create_table.sgml b/zh/11/ref/create_table.sgml index 8c22f672..1cad0806 100644 --- a/zh/11/ref/create_table.sgml +++ b/zh/11/ref/create_table.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TABLE 7 - SQL - Language Statements + SQL - 语言语句 @@ -116,7 +116,7 @@ WITH ( MODULUS numeric_literal, REM 如果给出了模式名(例如 CREATE TABLE myschema.mytable ...),则表将在指定模式中创建。 否则,它将在当前模式中创建。临时表存在于一个特殊模式中,因此创建临时表时不能给出模式名。 - 表名必须与同一模式中任何其他关系(表、序列、索引、视图、物化视图或外部表)的名称不同。 + 表名必须与同一模式中任何其他表、序列、索引、视图或外部表的名称不同。 @@ -142,7 +142,7 @@ WITH ( MODULUS numeric_literal, REM - TEMPORARY or TEMP + TEMPORARYTEMP 如果指定该选项,表将创建为临时表。 @@ -156,7 +156,7 @@ WITH ( MODULUS numeric_literal, REM - 可以在 TEMPORARYTEMP 前写 GLOBALLOCAL。这在当前的 PostgreSQL 中没有区别,而且已废弃;见下文 。 + 可以在 TEMPORARYTEMP 前写 GLOBALLOCAL。这在当前的 PostgreSQL 中没有区别,而且已弃用;见下文 @@ -173,14 +173,18 @@ WITH ( MODULUS numeric_literal, REM IF NOT EXISTS - 如果已存在同名关系,则不抛出错误,而是发出通知。请注意,不能保证现有关系与原本要创建的关系有任何相似之处。 + + 如果已存在同名关系,则不抛出错误,而是发出一条提示。注意,这并不保证现有关系与本应创建出的关系有任何相似之处。 + table_name - 要创建的表的名称(可以带模式限定)。 + + 要创建的表名(可选地带模式限定)。 + @@ -196,14 +200,20 @@ WITH ( MODULUS numeric_literal, REM column_name - 要在新表中创建的列的名称。 + + 要在新表中创建的列名。 + data_type - 列的数据类型,可以包含数组说明符。有关PostgreSQL支持的数据类型的更多信息,请参见 + + 列的数据类型。这可以包括数组说明符。有关 + PostgreSQL 支持的数据类型的更多信息,请参见 。 + @@ -258,15 +268,31 @@ WITH ( MODULUS numeric_literal, REM PARTITION BY { RANGE | LIST | HASH } ( { column_name | ( expression ) } [ opclass ] [, ...] ) - 可选的PARTITION BY子句指定表的分区策略。这样创建的表称为分区表。括号内的列或表达式列表构成该表的分区键。使用范围分区或哈希分区时,分区键可以包含多个列或表达式(最多 32 个,但可以在构建PostgreSQL时更改此限制);对于列表分区,分区键则必须由单个列或表达式组成。 + + 可选的 PARTITION BY 子句指定表的分区策略。 + 这样创建的表称为分区表。 + 括号中的列或表达式列表构成该表的分区键。 + 使用范围分区或哈希分区时,分区键可以包含多个列或表达式(最多 32 个,但该限制可在构建 PostgreSQL 时调整); + 而列表分区的分区键必须由单个列或表达式组成。 + - 范围分区和列表分区需要 B-树操作符类,而哈希分区需要哈希操作符类。如果没有显式指定操作符类,则使用相应类型的默认操作符类;如果不存在默认操作符类,则报错。使用哈希分区时,所用操作符类必须实现支持函数 2(详情见)。 + + 范围分区和列表分区需要 B-树 操作符类,哈希分区则需要 hash 操作符类。 + 如果未显式指定操作符类,将使用相应类型的默认操作符类;若不存在默认操作符类,则会报错。 + 使用哈希分区时,所用操作符类必须实现支持函数 2(详见 )。 + - 分区表划分为多个子表(称为分区),通过单独的CREATE TABLE命令创建。分区表本身为空。插入该表的数据行会根据分区键中列或表达式的值路由到某个分区。如果没有现有分区匹配新行中的值,则会报错。 + + 分区表被划分为多个子表(称为分区),它们使用单独的 CREATE TABLE 命令创建。 + 分区表本身为空。插入到该表的数据行会根据分区键中列或表达式的值被路由到相应分区。 + 如果没有现有分区与新行中的值匹配,就会报错。 + 分区表不支持EXCLUDE约束;不过,可以在单个分区上定义这些约束。此外,虽然可以在分区表上定义PRIMARY KEY约束,但目前不支持创建引用分区表的外键。 - 关于表分区的更多讨论,请参见 + + 有关表分区的更多讨论,请参阅 。 + @@ -327,13 +353,13 @@ WITH ( MODULUS numeric_literal, REM 还要注意,某些元素类型(如 timestamp)具有 - "infinity" 的概念,那只是另一种可存储的值。这不同于 + “无穷大” 的概念,那只是另一种可存储的值。这不同于 MINVALUEMAXVALUE,后两者并非可存储 的实际值,而只是表示值无界的方式。MAXVALUE 可以视为大于任何 - 其他值,包括 "infinity";MINVALUE 可以视为小于任何 - 其他值,包括 "minus infinity"。因此,范围 + 其他值,包括 “无穷大”;MINVALUE 可以视为小于任何 + 其他值,包括 “负无穷大”。因此,范围 FROM ('infinity') TO (MAXVALUE) 并不是空范围;它只允许存储 - 一个值 — "infinity"。 + 一个值 — “无穷大”。 @@ -440,7 +466,7 @@ WITH ( MODULUS numeric_literal, REM - 一个被标记为NO INHERIT的约束将不会传播到子表。 + 标记为 NO INHERIT 的约束不会传播到子表。 @@ -488,19 +514,29 @@ WITH ( MODULUS numeric_literal, REM INCLUDE ( column_name [, ...]) (表约束) - UNIQUE约束指定表中由一个或多个列组成的一组列只能包含唯一值。表级唯一约束的行为与列级唯一约束相同,但还能够跨越多个列。因此,这个约束要求任意两行在这些列中至少有一列不同。 + + UNIQUE 约束指定表中一列或多列组成的一组只能包含唯一值。 + 表级唯一约束的行为与列级唯一约束相同,只是它还能跨越多列。因此,该约束 + 要求任意两行在这些列中至少有一列不同。 + 对于唯一约束,空值不被视为相等。 - 每个唯一约束指定的列集合,都应与为该表定义的任何其他唯一约束或主键约束指定的列集合不同。(否则,冗余的唯一约束会被丢弃。) + + 每个唯一约束都应引用一组列,这组列应不同于该表上任何其他唯一约束或 + 主键约束所引用的列集合。(否则,冗余的唯一约束将被丢弃。) + - 为多级分区层次结构建立唯一约束时,约束定义必须包含目标分区表的分区键中的所有列,以及其所有后代分区表的分区键中的所有列。 + + 在为多级分区层次结构建立唯一约束时,目标分区表分区键中的所有列,以及 + 其所有后代分区表分区键中的所有列,都必须包含在约束定义中。 + 添加唯一约束会自动在约束所用的列或列组上创建唯一 B-树索引。 可选的 INCLUDE 子句会向该索引添加一个或多个仅作为 - payload 的列:对这些列不强制唯一性,而且该索引也不能据此 + 载荷 的列:对这些列不强制唯一性,而且该索引也不能据此 进行搜索。不过,它们可以通过仅索引扫描取回。注意,尽管约束不在包含列上 强制执行,它仍然依赖于这些列。因此,对这类列执行某些操作(例如 DROP COLUMN)可能导致约束和索引被级联删除。 @@ -542,7 +578,7 @@ WITH ( MODULUS numeric_literal, REM 可选的 INCLUDE 子句会向该索引添加一个或多个仅作为 - payload 的列:对这些列不强制唯一性,而且该索引也不能据此 + 载荷 的列:对这些列不强制唯一性,而且该索引也不能据此 进行搜索。不过,它们可以通过仅索引扫描取回。注意,尽管约束不在包含列上 强制执行,它仍然依赖于这些列。因此,对这类列执行某些操作(例如 DROP COLUMN)可能导致约束和索引被级联删除。 @@ -569,11 +605,15 @@ WITH ( MODULUS numeric_literal, REM 访问方法必须支持 amgettuple(见 );目前这意味着不能使用 GIN。 虽然允许,但在排他约束上使用 B-树或 hash 索引意义不大,因为它们做不到 - 比普通唯一约束更好的事情。因此,实践中访问方法几乎总会是 + 比普通唯一约束更好的事情。因此,实践中访问方法总是 GiSTSP-GiST - predicate允许在表的一个子集上指定排他约束;内部会为此创建部分索引。请注意,谓词必须用括号括起来。 + + predicate 允许你只在表的一个 + 子集上指定排他约束;在内部,这会创建一个部分索引。注意, + predicate 周围的圆括号是必需的。 + @@ -585,7 +625,17 @@ WITH ( MODULUS numeric_literal, REM 这些子句指定外键约束,要求新表中由一个或多个列组成的列组只能包含与被引用表中某一行的被引用列中的值相匹配的值。如果省略refcolumn列表,则使用reftable的主键。被引用列必须是被引用表中不可延迟的唯一约束或主键约束的列。用户必须拥有被引用表的REFERENCES权限(可以针对整个表,也可以针对具体的被引用列)。添加外键约束需要在被引用表上获取SHARE ROW EXCLUSIVE锁。请注意,不能在临时表和永久表之间定义外键约束。还要注意,虽然可以在分区表上定义外键,但不能声明引用分区表的外键。 - 插入引用列的值会使用指定的匹配类型,与被引用表的被引用列中的值进行匹配。有三种匹配类型:MATCH FULLMATCH PARTIALMATCH SIMPLE(默认值)。MATCH FULL不允许多列外键中的某一列为空,除非所有外键列都为空;如果全部为空,则不要求该行在被引用表中存在匹配行。MATCH SIMPLE允许任意外键列为空;只要其中任何一列为空,就不要求该行在被引用表中存在匹配行。MATCH PARTIAL尚未实现。(当然,可以对引用列施加NOT NULL约束来防止这些情况发生。) + + 插入到引用列中的值会按照给定的匹配类型,与被引用表及其被引用列中的值进 + 行匹配。共有三种匹配类型:MATCH FULL、 + MATCH PARTIALMATCH SIMPLE + (默认值)。MATCH FULL 不允许多列外键中的某一列为 + 空,除非所有外键列都为空;如果它们都为空,则不要求该行在被引用表中有匹 + 配行。MATCH SIMPLE 允许任意外键列为空;如果其中任何一 + 列为空,则不要求该行在被引用表中有匹配行。 + MATCH PARTIAL 目前尚未实现。(当然,可以对引用列应用 + NOT NULL 约束,以防止出现这些情况。) + 此外,当被引用列中的数据发生变化时,会对本表列中的数据执行某些操作。ON DELETE子句指定删除被引用表中的被引用行时要执行的操作。同样,ON UPDATE子句指定将被引用表中的被引用列更新为新值时要执行的操作。如果行被更新,但被引用列实际上没有变化,则不执行任何操作。除NO ACTION检查以外的引用操作都不能延迟,即使该约束声明为可延迟也是如此。每个子句可以指定以下操作: @@ -605,7 +655,9 @@ WITH ( MODULUS numeric_literal, REM CASCADE - 分别删除引用被删除行的所有行,或将引用列的值更新为被引用列的新值。 + + 分别删除任何引用已删除行的行,或将引用列的值更新为被引用列的新值。 + @@ -667,7 +719,11 @@ WITH ( MODULUS numeric_literal, REM ON COMMIT - 临时表在事务块结束时的行为可以使用以下选项控制:ON COMMIT。三个选项是: + + 可以使用 ON COMMIT 控制临时表在事务块结束时的行为。三种 + 选项如下: + + PRESERVE ROWS @@ -729,7 +785,7 @@ WITH ( MODULUS numeric_literal, REM 存储参数 - storage parameters + 存储参数 @@ -786,7 +842,7 @@ WITH ( MODULUS numeric_literal, REM - 该参数设置在对该表执行并行扫描时可用于辅助扫描的工作进程数量。若未设置, + 该参数设置在对该表执行并行扫描时用于辅助扫描的工作进程数量。若未设置, 系统会根据关系大小决定一个值。规划器或使用并行扫描的实用命令实际选择的 工作进程数量可能更少,例如可能受 设置所限。 @@ -978,7 +1034,7 @@ WITH ( MODULUS numeric_literal, REM - PostgreSQL为每一个唯一约束和主键约束创建一个索引来强制唯一性。因此,没有必要显式地为主键列创建一个索引(详见)。 + PostgreSQL为每一个唯一约束和主键约束自动创建一个索引来强制唯一性。因此,没有必要显式地为主键列创建一个索引(详见)。 @@ -1392,9 +1448,9 @@ CREATE TABLE cities_partdef NULL 约束(实际上并不是约束)是 - PostgreSQL 对 SQL 标准的扩展;它也被其他一些数 - 据库系统采纳,以便兼容(以及与对称的 NOT NULL 约束保持一 - 致)。由于它本来就是任意列的默认值,所以它的存在只是噪声。 + PostgreSQL 对 SQL 标准的扩展;提供它是为了 + 与其他一些数据库系统兼容(以及与 NOT NULL 约束保持 + 对称)。由于它本来就是任意列的默认情况,所以它的存在只是噪声。 @@ -1423,12 +1479,12 @@ CREATE TABLE cities_partdef - 零列表 + 零列的表 PostgreSQL 允许创建没有列的表(例如 CREATE TABLE foo();)。这是对 SQL 标准的扩展,标准不允许 - 零列表。零列表本身并不十分有用,但若禁止它们,就会让 + 零列的表。零列的表本身并不十分有用,但若禁止它们,就会让 ALTER TABLE DROP COLUMN 出现奇怪的特殊情况,因此忽略这 一规范限制看起来更整洁。 @@ -1441,7 +1497,7 @@ CREATE TABLE cities_partdef PostgreSQL 允许一个表拥有多个标识列。 该标准指定一个表最多只能有一个标识列。 - 这主要是为了给模式更改或迁移提供更大的灵活性。 + 放宽这一限制主要是为了给模式更改或迁移提供更大的灵活性。 请注意,INSERT 命令仅支持一个适用于整个语句的覆盖子 句,因此对行为不同的多个标识列支持并不好。 diff --git a/zh/11/ref/create_table_as.sgml b/zh/11/ref/create_table_as.sgml index 20353ddd..07c94280 100644 --- a/zh/11/ref/create_table_as.sgml +++ b/zh/11/ref/create_table_as.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TABLE AS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/create_tablespace.sgml b/zh/11/ref/create_tablespace.sgml index 7c51335b..cf8bc937 100644 --- a/zh/11/ref/create_tablespace.sgml +++ b/zh/11/ref/create_tablespace.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TABLESPACE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/create_transform.sgml b/zh/11/ref/create_transform.sgml index 865b53e5..381e3bcd 100644 --- a/zh/11/ref/create_transform.sgml +++ b/zh/11/ref/create_transform.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TRANSFORM 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/create_trigger.sgml b/zh/11/ref/create_trigger.sgml index 849f7249..d43ac2a2 100644 --- a/zh/11/ref/create_trigger.sgml +++ b/zh/11/ref/create_trigger.sgml @@ -10,13 +10,13 @@ PostgreSQL documentation 过渡表 - ephemeral named relation + 临时命名关系 CREATE TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -55,7 +55,7 @@ CREATE [ CONSTRAINT ] TRIGGER name UPDATEDELETE之前); 也可以在该操作完成之后引发(即在检查约束以及完成 INSERTUPDATE或 - DELETE之后);或者改为执行该操作 + DELETE之后);或者取代该操作执行 (用于视图上的插入、更新或删除)。如果触发器在事件之前引发,或者改为取代该事件执行, 则它可以跳过对当前行的操作,或者修改待插入的行 (仅适用于INSERTUPDATE操作)。 @@ -111,7 +111,7 @@ CREATE [ CONSTRAINT ] TRIGGER name TRUNCATE - 表和外部表 + @@ -124,7 +124,7 @@ CREATE [ CONSTRAINT ] TRIGGER name TRUNCATE - 表和外部表 + @@ -154,7 +154,7 @@ CREATE [ CONSTRAINT ] TRIGGER name 如果针对同一事件定义了多个同类触发器,它们将按名称的字母顺序引发。 - 当指定CONSTRAINT选项时,此命令会创建一个约束触发器。这与普通触发器相同,只是可以使用调整其触发时机。约束触发器必须是普通表(不是外部表)上的AFTER ROW触发器。它们既可以在导致触发事件的语句结束时触发,也可以在包含它的事务结束时触发;后一种情况称为延迟。也可以使用SET CONSTRAINTS强制挂起的延迟触发立即触发。约束触发器应当在其所实现的约束遭到违反时抛出异常。 + 当指定CONSTRAINT选项时,此命令会创建一个约束触发器。这与普通触发器相同,只是可以使用调整其触发时机。约束触发器必须是普通表(不是外部表)上的AFTER ROW触发器。它们既可以在导致触发事件的语句结束时触发,也可以在包含它的事务结束时触发;后一种情况称为延迟。也可以使用SET CONSTRAINTS强制尚待执行的延迟触发器立即触发。约束触发器应当在其所实现的约束遭到违反时抛出异常。 REFERENCING选项允许收集过渡关系,即包含当前 SQL 语句插入、删除或修改的全部行的行集合。该特性使触发器能够看到该语句所做更改的整体视图,而不是一次只看到一行。该选项仅允许用于不是约束触发器的AFTER触发器;如果触发器是UPDATE触发器,则不得指定column_name列表。OLD TABLE最多只能指定一次,并且只能用于可能在UPDATEDELETE上触发的触发器;它会创建一个过渡关系,其中包含该语句更新或删除的全部行的前映像。同样,NEW TABLE最多只能指定一次,并且只能用于可能在UPDATEINSERT上触发的触发器;它会创建一个过渡关系,其中包含该语句更新或插入的全部行的后映像 @@ -350,7 +350,7 @@ UPDATE OF column_name1 [, column_name2CREATE TRIGGER的语法中,关键字 FUNCTIONPROCEDURE 是等价的, 但无论如何,被引用的对象都必须是函数而不是过程。 - 这里使用 PROCEDURE 关键字只是出于历史原因,并且已被废弃。 + 这里使用 PROCEDURE 关键字只是出于历史原因,并且已被弃用。 diff --git a/zh/11/ref/create_tsconfig.sgml b/zh/11/ref/create_tsconfig.sgml index ec121658..974ef42a 100644 --- a/zh/11/ref/create_tsconfig.sgml +++ b/zh/11/ref/create_tsconfig.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TEXT SEARCH CONFIGURATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/create_tsdictionary.sgml b/zh/11/ref/create_tsdictionary.sgml index 25935390..2dbca552 100644 --- a/zh/11/ref/create_tsdictionary.sgml +++ b/zh/11/ref/create_tsdictionary.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TEXT SEARCH DICTIONARY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/create_tsparser.sgml b/zh/11/ref/create_tsparser.sgml index 290e30b0..6af67ab8 100644 --- a/zh/11/ref/create_tsparser.sgml +++ b/zh/11/ref/create_tsparser.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TEXT SEARCH PARSER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/create_tstemplate.sgml b/zh/11/ref/create_tstemplate.sgml index 44061296..5dd2e1c0 100644 --- a/zh/11/ref/create_tstemplate.sgml +++ b/zh/11/ref/create_tstemplate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TEXT SEARCH TEMPLATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/create_type.sgml b/zh/11/ref/create_type.sgml index 46fece29..76e85012 100644 --- a/zh/11/ref/create_type.sgml +++ b/zh/11/ref/create_type.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TYPE 7 - SQL - Language Statements + SQL - 语言语句 @@ -91,7 +91,7 @@ CREATE TYPE name 复合类型 - 第一种形式的CREATE TYPE创建复合类型。组合 + 第一种形式的CREATE TYPE创建复合类型。复合 类型由属性名和数据类型列表指定。如果某个属性的数据类型支持排序规 则,还可以指定该属性的排序规则。复合类型本质上与表的行类型相同, 但如果目的只是定义一种类型,使用CREATE TYPE @@ -280,7 +280,7 @@ CREATE TYPE name 数才知道,但仍有若干内部表示属性必须向 PostgreSQL声明。其中最重要的是 internallength。 - 基础数据类型可以是定长的,此时internallength为正整数;也可 以是变长的,此时将internallength设为 @@ -384,7 +384,7 @@ CREATE TYPE name collatable为真,则 该类型的列定义和表达式可以通过COLLATE子句携 带排序规则信息。是否实际使用这些排序规则信息取决于操作该类型的函 - 数实现;仅仅把类型标记为 collatable 并不会自动实现这一点。 + 数实现;仅仅把类型标记为支持排序规则并不会自动实现这一点。 @@ -743,7 +743,7 @@ CREATE TYPE name 以这种方式创建 shell 类型。 - PostgreSQL 7.3 以前的版本中,通常完全不创建壳类型,而是将函数中对类型名的前向引用替换为占位伪类型opaque。在 7.3 以前,cstring参数和结果也必须声明为opaque。为了支持载入旧转储文件,CREATE TYPE会接受使用opaque声明的 I/O 函数,但会发出通知,并修改函数声明以使用正确的类型。 + PostgreSQL 7.3 以前的版本中,通常完全不创建 shell 类型,而是将函数中对类型名的前向引用替换为占位伪类型opaque。在 7.3 以前,cstring参数和结果也必须声明为opaque。为了支持载入旧转储文件,CREATE TYPE会接受使用opaque声明的 I/O 函数,但会发出通知,并修改函数声明以使用正确的类型。 @@ -783,7 +783,7 @@ CREATE TYPE float8_range AS RANGE (subtype = float8, subtype_diff = float8mi); - 这个示例创建基础数据类型box,然后在表定义中使用它: + 这个示例创建基础类型box,然后在表定义中使用它: CREATE TYPE box; diff --git a/zh/11/ref/create_user.sgml b/zh/11/ref/create_user.sgml index 64ee1d8b..3cc56400 100644 --- a/zh/11/ref/create_user.sgml +++ b/zh/11/ref/create_user.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE USER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/create_user_mapping.sgml b/zh/11/ref/create_user_mapping.sgml index 7a16d2d5..d8730f6c 100644 --- a/zh/11/ref/create_user_mapping.sgml +++ b/zh/11/ref/create_user_mapping.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE USER MAPPING 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/create_view.sgml b/zh/11/ref/create_view.sgml index 37244835..e1907d33 100644 --- a/zh/11/ref/create_view.sgml +++ b/zh/11/ref/create_view.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/createdb.sgml b/zh/11/ref/createdb.sgml index e79a1f59..eacb5b35 100644 --- a/zh/11/ref/createdb.sgml +++ b/zh/11/ref/createdb.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation createdb 1 - Application + 应用程序 diff --git a/zh/11/ref/createuser.sgml b/zh/11/ref/createuser.sgml index 68e3b7d2..31a93b37 100644 --- a/zh/11/ref/createuser.sgml +++ b/zh/11/ref/createuser.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation createuser 1 - Application + 应用程序 @@ -119,13 +119,10 @@ PostgreSQL documentation - (已废弃) + - - 指定新角色应自动成为指定现有角色的成员。 - 可以通过写多个开关来指定多个现有角色。 - + 指定此角色应立即作为新成员加入的现有角色。可以使用多个开关,指定此角色要加入的多个角色。 @@ -275,7 +272,7 @@ PostgreSQL documentation 新用户将不具有REPLICATION权限,关于该权限的更完整说明见。这是默认设置。 + linkend="sql-createrole"/>。 diff --git a/zh/11/ref/deallocate.sgml b/zh/11/ref/deallocate.sgml index 27b9da86..6dea341e 100644 --- a/zh/11/ref/deallocate.sgml +++ b/zh/11/ref/deallocate.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation DEALLOCATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/declare.sgml b/zh/11/ref/declare.sgml index 5f90767f..c1673288 100644 --- a/zh/11/ref/declare.sgml +++ b/zh/11/ref/declare.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation DECLARE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/delete.sgml b/zh/11/ref/delete.sgml index 61fbd1c8..5f6b6fc0 100644 --- a/zh/11/ref/delete.sgml +++ b/zh/11/ref/delete.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DELETE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/discard.sgml b/zh/11/ref/discard.sgml index ba502b13..22645229 100644 --- a/zh/11/ref/discard.sgml +++ b/zh/11/ref/discard.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DISCARD 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/do.sgml b/zh/11/ref/do.sgml index 2e77e74e..a6ef1768 100644 --- a/zh/11/ref/do.sgml +++ b/zh/11/ref/do.sgml @@ -15,7 +15,7 @@ PostgreSQL documentation DO 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/drop_access_method.sgml b/zh/11/ref/drop_access_method.sgml index 407ec4cd..646100e1 100644 --- a/zh/11/ref/drop_access_method.sgml +++ b/zh/11/ref/drop_access_method.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP ACCESS METHOD 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/drop_aggregate.sgml b/zh/11/ref/drop_aggregate.sgml index 1c8a1122..9fd7ea4b 100644 --- a/zh/11/ref/drop_aggregate.sgml +++ b/zh/11/ref/drop_aggregate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP AGGREGATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/drop_cast.sgml b/zh/11/ref/drop_cast.sgml index 73860e3c..5e330ae0 100644 --- a/zh/11/ref/drop_cast.sgml +++ b/zh/11/ref/drop_cast.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP CAST 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/drop_collation.sgml b/zh/11/ref/drop_collation.sgml index b90849fc..b10b3206 100644 --- a/zh/11/ref/drop_collation.sgml +++ b/zh/11/ref/drop_collation.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP COLLATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/drop_conversion.sgml b/zh/11/ref/drop_conversion.sgml index b63d1291..35009708 100644 --- a/zh/11/ref/drop_conversion.sgml +++ b/zh/11/ref/drop_conversion.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP CONVERSION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/drop_database.sgml b/zh/11/ref/drop_database.sgml index e9e9456d..7d8eea80 100644 --- a/zh/11/ref/drop_database.sgml +++ b/zh/11/ref/drop_database.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP DATABASE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/drop_domain.sgml b/zh/11/ref/drop_domain.sgml index d43f95c6..b292b189 100644 --- a/zh/11/ref/drop_domain.sgml +++ b/zh/11/ref/drop_domain.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP DOMAIN 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/drop_event_trigger.sgml b/zh/11/ref/drop_event_trigger.sgml index 80020f78..f4f0053f 100644 --- a/zh/11/ref/drop_event_trigger.sgml +++ b/zh/11/ref/drop_event_trigger.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP EVENT TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -30,7 +30,7 @@ DROP EVENT TRIGGER [ IF EXISTS ] name DROP EVENT TRIGGER移除一个现有的事件触发器。 - 要执行此命令,当前用户必须是该事件触发器的拥有者。 + 要执行此命令,当前用户必须是该事件触发器的所有者。 @@ -99,7 +99,7 @@ DROP EVENT TRIGGER snitch; - 另见 + 参见 diff --git a/zh/11/ref/drop_extension.sgml b/zh/11/ref/drop_extension.sgml index f01f950b..eb209195 100644 --- a/zh/11/ref/drop_extension.sgml +++ b/zh/11/ref/drop_extension.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP EXTENSION 7 - SQL - Language Statements + SQL - 语言语句 @@ -53,8 +53,8 @@ DROP EXTENSION [ IF EXISTS ] name [ name - 已安装扩展的名称。 - + 一个已安装扩展的名称。 + @@ -85,7 +85,7 @@ DROP EXTENSION [ IF EXISTS ] name [ DROP EXTENSION hstore; - 如果数据库中正在使用hstore的任何对象, + 如果数据库中使用了hstore的任何对象, 例如某些表具有hstore类型的列,则该命令会失败。 加上CASCADE选项可以强制一并移除这些依赖对象。 diff --git a/zh/11/ref/drop_foreign_data_wrapper.sgml b/zh/11/ref/drop_foreign_data_wrapper.sgml index 9902c875..6f781f31 100644 --- a/zh/11/ref/drop_foreign_data_wrapper.sgml +++ b/zh/11/ref/drop_foreign_data_wrapper.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP FOREIGN DATA WRAPPER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/drop_foreign_table.sgml b/zh/11/ref/drop_foreign_table.sgml index 0b4d0bbd..c420e4ba 100644 --- a/zh/11/ref/drop_foreign_table.sgml +++ b/zh/11/ref/drop_foreign_table.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP FOREIGN TABLE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/drop_function.sgml b/zh/11/ref/drop_function.sgml index 97b28a9b..84d45502 100644 --- a/zh/11/ref/drop_function.sgml +++ b/zh/11/ref/drop_function.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP FUNCTION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/drop_group.sgml b/zh/11/ref/drop_group.sgml index 6ca1c03f..a4bace0f 100644 --- a/zh/11/ref/drop_group.sgml +++ b/zh/11/ref/drop_group.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP GROUP 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/drop_index.sgml b/zh/11/ref/drop_index.sgml index b65b810b..d7f892d9 100644 --- a/zh/11/ref/drop_index.sgml +++ b/zh/11/ref/drop_index.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP INDEX 7 - SQL - Language Statements + SQL - 语言语句 @@ -57,7 +57,7 @@ DROP INDEX [ CONCURRENTLY ] [ IF EXISTS ] name 对于临时表,DROP INDEX始终是非并发的, - 因为没有其他会话可以访问它们,而且非并发删除索引的成本更低。 + 因为没有其他会话可以访问它们,而且非并发删除索引的代价更低。 @@ -66,7 +66,7 @@ DROP INDEX [ CONCURRENTLY ] [ IF EXISTS ] nameIF EXISTS - 如果该索引不存在,则不要抛出错误。这种情况下会发出一个提示。 + 如果该索引不存在,则不要抛出错误。这种情况下会发出一条提示。 diff --git a/zh/11/ref/drop_language.sgml b/zh/11/ref/drop_language.sgml index 1dcebc91..55d5fa0b 100644 --- a/zh/11/ref/drop_language.sgml +++ b/zh/11/ref/drop_language.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP LANGUAGE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/drop_materialized_view.sgml b/zh/11/ref/drop_materialized_view.sgml index f3682552..71ad4326 100644 --- a/zh/11/ref/drop_materialized_view.sgml +++ b/zh/11/ref/drop_materialized_view.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP MATERIALIZED VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/drop_opclass.sgml b/zh/11/ref/drop_opclass.sgml index c3dd2e74..9d67dc64 100644 --- a/zh/11/ref/drop_opclass.sgml +++ b/zh/11/ref/drop_opclass.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP OPERATOR CLASS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/drop_operator.sgml b/zh/11/ref/drop_operator.sgml index 64533bef..724a6ffc 100644 --- a/zh/11/ref/drop_operator.sgml +++ b/zh/11/ref/drop_operator.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP OPERATOR 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/drop_opfamily.sgml b/zh/11/ref/drop_opfamily.sgml index 8e7097f9..06223045 100644 --- a/zh/11/ref/drop_opfamily.sgml +++ b/zh/11/ref/drop_opfamily.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP OPERATOR FAMILY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/drop_owned.sgml b/zh/11/ref/drop_owned.sgml index 05e28e68..81bb029c 100644 --- a/zh/11/ref/drop_owned.sgml +++ b/zh/11/ref/drop_owned.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP OWNED 7 - SQL - Language Statements + SQL - 语言语句 @@ -31,7 +31,7 @@ DROP OWNED BY { name | CURRENT_USER DROP OWNED删除当前数据库中由指定角色之一拥有的所有对象。 同时,授予给这些角色的、针对当前数据库中的对象或共享对象 - (数据库、表空间、配置参数)的任何权限也会被撤销。 + (数据库、表空间)的任何权限也会被撤销。 diff --git a/zh/11/ref/drop_policy.sgml b/zh/11/ref/drop_policy.sgml index ee64ffa0..a939a688 100644 --- a/zh/11/ref/drop_policy.sgml +++ b/zh/11/ref/drop_policy.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP POLICY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/drop_procedure.sgml b/zh/11/ref/drop_procedure.sgml index 145a6c99..62c601f7 100644 --- a/zh/11/ref/drop_procedure.sgml +++ b/zh/11/ref/drop_procedure.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP PROCEDURE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/drop_publication.sgml b/zh/11/ref/drop_publication.sgml index 6bc4bf59..048c1756 100644 --- a/zh/11/ref/drop_publication.sgml +++ b/zh/11/ref/drop_publication.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP PUBLICATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/drop_role.sgml b/zh/11/ref/drop_role.sgml index 6e06020f..d85224dd 100644 --- a/zh/11/ref/drop_role.sgml +++ b/zh/11/ref/drop_role.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP ROLE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/drop_routine.sgml b/zh/11/ref/drop_routine.sgml index 5488da87..491d93eb 100644 --- a/zh/11/ref/drop_routine.sgml +++ b/zh/11/ref/drop_routine.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP ROUTINE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/drop_rule.sgml b/zh/11/ref/drop_rule.sgml index ddb561f4..2968d946 100644 --- a/zh/11/ref/drop_rule.sgml +++ b/zh/11/ref/drop_rule.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP RULE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/drop_schema.sgml b/zh/11/ref/drop_schema.sgml index 9f622df3..94843c9a 100644 --- a/zh/11/ref/drop_schema.sgml +++ b/zh/11/ref/drop_schema.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP SCHEMA 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/drop_sequence.sgml b/zh/11/ref/drop_sequence.sgml index 4ba78640..586d3038 100644 --- a/zh/11/ref/drop_sequence.sgml +++ b/zh/11/ref/drop_sequence.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP SEQUENCE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/drop_server.sgml b/zh/11/ref/drop_server.sgml index 0864a4c2..8bdacdc8 100644 --- a/zh/11/ref/drop_server.sgml +++ b/zh/11/ref/drop_server.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP SERVER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/drop_statistics.sgml b/zh/11/ref/drop_statistics.sgml index 3120dc06..4773bfa8 100644 --- a/zh/11/ref/drop_statistics.sgml +++ b/zh/11/ref/drop_statistics.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP STATISTICS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/drop_subscription.sgml b/zh/11/ref/drop_subscription.sgml index ea0f7e7c..455ea597 100644 --- a/zh/11/ref/drop_subscription.sgml +++ b/zh/11/ref/drop_subscription.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP SUBSCRIPTION 7 - SQL - Language Statements + SQL - 语言语句 @@ -32,9 +32,7 @@ DROP SUBSCRIPTION [ IF EXISTS ] nameDROP SUBSCRIPTION从数据库集簇中移除一个订阅。 - - 要执行此命令,用户必须是该订阅的拥有者。 - + 只有超级用户才能删除订阅。 如果订阅与复制槽相关联,则不能在事务块内执行DROP SUBSCRIPTION。(可以使用ALTER SUBSCRIPTION来取消设置该槽。) diff --git a/zh/11/ref/drop_table.sgml b/zh/11/ref/drop_table.sgml index 6193c2e3..50b73e31 100644 --- a/zh/11/ref/drop_table.sgml +++ b/zh/11/ref/drop_table.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TABLE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/drop_tablespace.sgml b/zh/11/ref/drop_tablespace.sgml index c8b09e59..a31fd70f 100644 --- a/zh/11/ref/drop_tablespace.sgml +++ b/zh/11/ref/drop_tablespace.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TABLESPACE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/drop_transform.sgml b/zh/11/ref/drop_transform.sgml index e606b35b..dfba428d 100644 --- a/zh/11/ref/drop_transform.sgml +++ b/zh/11/ref/drop_transform.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TRANSFORM 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/drop_trigger.sgml b/zh/11/ref/drop_trigger.sgml index 1f85cf41..160a5ebd 100644 --- a/zh/11/ref/drop_trigger.sgml +++ b/zh/11/ref/drop_trigger.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -30,7 +30,7 @@ DROP TRIGGER [ IF EXISTS ] name ON DROP TRIGGER移除一个现有触发器的定义。 - 要执行此命令,当前用户必须是定义该触发器的表的拥有者。 + 要执行此命令,当前用户必须是定义该触发器的表的所有者。 @@ -109,7 +109,7 @@ DROP TRIGGER if_dist_exists ON films; - 另见 + 参见 diff --git a/zh/11/ref/drop_tsconfig.sgml b/zh/11/ref/drop_tsconfig.sgml index 2a7cdc52..ea139802 100644 --- a/zh/11/ref/drop_tsconfig.sgml +++ b/zh/11/ref/drop_tsconfig.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TEXT SEARCH CONFIGURATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/drop_tsdictionary.sgml b/zh/11/ref/drop_tsdictionary.sgml index 1eb24189..316c5d00 100644 --- a/zh/11/ref/drop_tsdictionary.sgml +++ b/zh/11/ref/drop_tsdictionary.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TEXT SEARCH DICTIONARY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/drop_tsparser.sgml b/zh/11/ref/drop_tsparser.sgml index 0cfa7acd..a65f47be 100644 --- a/zh/11/ref/drop_tsparser.sgml +++ b/zh/11/ref/drop_tsparser.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TEXT SEARCH PARSER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/drop_tstemplate.sgml b/zh/11/ref/drop_tstemplate.sgml index 282231c5..fa1faab0 100644 --- a/zh/11/ref/drop_tstemplate.sgml +++ b/zh/11/ref/drop_tstemplate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TEXT SEARCH TEMPLATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/drop_type.sgml b/zh/11/ref/drop_type.sgml index dab5bfa0..2f139da5 100644 --- a/zh/11/ref/drop_type.sgml +++ b/zh/11/ref/drop_type.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TYPE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/drop_user.sgml b/zh/11/ref/drop_user.sgml index 48d31af4..32bedce7 100644 --- a/zh/11/ref/drop_user.sgml +++ b/zh/11/ref/drop_user.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP USER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/drop_user_mapping.sgml b/zh/11/ref/drop_user_mapping.sgml index 5cfe0086..029b4362 100644 --- a/zh/11/ref/drop_user_mapping.sgml +++ b/zh/11/ref/drop_user_mapping.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP USER MAPPING 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/drop_view.sgml b/zh/11/ref/drop_view.sgml index 4feb47e5..8f995245 100644 --- a/zh/11/ref/drop_view.sgml +++ b/zh/11/ref/drop_view.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/dropdb.sgml b/zh/11/ref/dropdb.sgml index b7685473..220ce633 100644 --- a/zh/11/ref/dropdb.sgml +++ b/zh/11/ref/dropdb.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation dropdb 1 - Application + 应用程序 diff --git a/zh/11/ref/dropuser.sgml b/zh/11/ref/dropuser.sgml index 14c65d1e..5b2a4a5f 100644 --- a/zh/11/ref/dropuser.sgml +++ b/zh/11/ref/dropuser.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation dropuser 1 - Application + 应用程序 diff --git a/zh/11/ref/ecpg-ref.sgml b/zh/11/ref/ecpg-ref.sgml index e4589c64..fc2123c5 100644 --- a/zh/11/ref/ecpg-ref.sgml +++ b/zh/11/ref/ecpg-ref.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ecpg 1 - Application + 应用程序 diff --git a/zh/11/ref/end.sgml b/zh/11/ref/end.sgml index d38606e6..7b1fe348 100644 --- a/zh/11/ref/end.sgml +++ b/zh/11/ref/end.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation END 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/execute.sgml b/zh/11/ref/execute.sgml index 7537072b..81cf7335 100644 --- a/zh/11/ref/execute.sgml +++ b/zh/11/ref/execute.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation EXECUTE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/explain.sgml b/zh/11/ref/explain.sgml index 34e70b2b..18c77ccc 100644 --- a/zh/11/ref/explain.sgml +++ b/zh/11/ref/explain.sgml @@ -21,7 +21,7 @@ PostgreSQL documentation EXPLAIN 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/fetch.sgml b/zh/11/ref/fetch.sgml index 7e6abb4b..d5392d7f 100644 --- a/zh/11/ref/fetch.sgml +++ b/zh/11/ref/fetch.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation FETCH 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/grant.sgml b/zh/11/ref/grant.sgml index ab8e1b4a..040edce2 100644 --- a/zh/11/ref/grant.sgml +++ b/zh/11/ref/grant.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation GRANT 7 - SQL - Language Statements + SQL - 语言语句 @@ -96,7 +96,7 @@ GRANT role_name [, ...] TO 描述 - GRANT 命令有两个基本变体:一种是在数据库对象(表、列、视图、外部表、序列、数据库、外部数据包装器、外部服务器、函数、过程、过程语言、大对象、配置参数、模式、表空间或类型)上授予权限,另一种是授予角色成员资格。这两种变体在许多方面相似,但差异也足够大,因此分别说明。 + GRANT 命令有两个基本变体:一种是在数据库对象(表、列、视图、外部表、序列、数据库、外部数据包装器、外部服务器、函数、过程、过程语言、模式或表空间)上授予权限,另一种是授予角色成员资格。这两种变体在许多方面相似,但差异也足够大,因此分别说明。 @@ -325,7 +325,7 @@ GRANT role_name [, ...] TO - 如果超级用户选择执行 GRANTREVOKE 命令,该命令会像由受影响对象的拥有者发出一样执行。特别是,通过这种命令授予的权限看起来会像是由对象拥有者授予的。(对于角色成员资格,则看起来像是由引导超级用户授予的。) + 如果超级用户选择执行 GRANTREVOKE 命令,该命令会像由受影响对象的拥有者发出一样执行。特别是,通过这种命令授予的权限看起来会像是由对象拥有者授予的。(对于角色成员资格,则看起来像是由被授予成员资格的角色本身授予的。) @@ -456,7 +456,7 @@ GRANT admins TO joe; - 数据库、表空间、模式、语言以及配置参数上的权限都是 PostgreSQL 扩展。 + 数据库、表空间、模式和语言上的权限都是 PostgreSQL 扩展。 diff --git a/zh/11/ref/import_foreign_schema.sgml b/zh/11/ref/import_foreign_schema.sgml index 6e912201..1957d60a 100644 --- a/zh/11/ref/import_foreign_schema.sgml +++ b/zh/11/ref/import_foreign_schema.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation IMPORT FOREIGN SCHEMA 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/initdb.sgml b/zh/11/ref/initdb.sgml index fdbcb5e8..67014373 100644 --- a/zh/11/ref/initdb.sgml +++ b/zh/11/ref/initdb.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation initdb 1 - Application + 应用程序 diff --git a/zh/11/ref/insert.sgml b/zh/11/ref/insert.sgml index e89adb9b..fe3408e4 100644 --- a/zh/11/ref/insert.sgml +++ b/zh/11/ref/insert.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation INSERT 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/listen.sgml b/zh/11/ref/listen.sgml index 5b96dd0b..59d96afb 100644 --- a/zh/11/ref/listen.sgml +++ b/zh/11/ref/listen.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation LISTEN 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/load.sgml b/zh/11/ref/load.sgml index bb0adb7c..89bdb114 100644 --- a/zh/11/ref/load.sgml +++ b/zh/11/ref/load.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation LOAD 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/lock.sgml b/zh/11/ref/lock.sgml index 8b49adb5..50085983 100644 --- a/zh/11/ref/lock.sgml +++ b/zh/11/ref/lock.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation LOCK 7 - SQL - Language Statements + SQL - 语言语句 @@ -55,7 +55,7 @@ LOCK [ TABLE ] [ ONLY ] name [ * ] 因为SHARE锁模式与写入者获取的ROW EXCLUSIVE锁冲突, 而LOCK TABLE name IN SHARE MODE - 语句会一直等待,直到任何并发持有ROW EXCLUSIVE模式锁的事务提交或回滚。 + 语句会一直等待,直到所有并发持有ROW EXCLUSIVE模式锁的事务提交或回滚。 因此,一旦获得该锁,就不存在尚未提交的写入;而且在释放该锁之前,也不会有新的写入开始。 diff --git a/zh/11/ref/move.sgml b/zh/11/ref/move.sgml index e90c1b88..961359c8 100644 --- a/zh/11/ref/move.sgml +++ b/zh/11/ref/move.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation MOVE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/notify.sgml b/zh/11/ref/notify.sgml index a90a45ef..938baf9f 100644 --- a/zh/11/ref/notify.sgml +++ b/zh/11/ref/notify.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation NOTIFY 7 - SQL - Language Statements + SQL - 语言语句 @@ -88,7 +88,7 @@ NOTIFY channel [ , 注解 - 系统中有一个队列,用来保存那些已经发送但尚未被所有监听会话处理的通知。如果这个队列被塞满,那么调用NOTIFY的事务会在提交时失败。该队列非常大(标准安装中为 8GB),几乎足以满足所有用例。不过,如果某个会话执行了LISTEN后又长时间停留在一个事务里,就无法进行清理。一旦队列占用超过一半,你就会在日志文件中看到警告,指出究竟是哪个会话阻碍了清理。在这种情况下,应确保该会话结束其当前事务,以便清理能够继续进行。 + 系统中有一个队列,用来保存那些已经发送但尚未被所有监听会话处理的通知。如果这个队列被塞满,那么调用NOTIFY的事务会在提交时失败。该队列非常大(标准安装中为 8GB),几乎足以满足所有用例。不过,如果某个会话执行了LISTEN后又长时间停留在一个事务里,就无法进行清理。一旦队列占用达到一半,你就会在日志文件中看到警告,指出究竟是哪个会话阻碍了清理。在这种情况下,应确保该会话结束其当前事务,以便清理能够继续进行。 函数pg_notification_queue_usage返回当前被待处理通知占用的队列比例。详见。 diff --git a/zh/11/ref/pg_basebackup.sgml b/zh/11/ref/pg_basebackup.sgml index 343d093c..41312ca8 100644 --- a/zh/11/ref/pg_basebackup.sgml +++ b/zh/11/ref/pg_basebackup.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_basebackup 1 - Application + 应用程序 @@ -37,7 +37,7 @@ PostgreSQL documentation 备份通过使用复制协议的普通PostgreSQL连接进行。建立连接时必须使用超级用户或具有REPLICATION权限(参见)的用户,并且pg_hba.conf必须明确允许复制连接。服务器还必须将设置得足够高,以便至少为备份保留一个可用会话,并在使用 WAL 流式传输时再为其保留一个会话。 - 可以同时运行多个pg_basebackup,但从性能角度来看,通常最好只执行一次备份,然后复制其结果。 + 可以同时运行多个pg_basebackup,但从性能角度来看,最好只执行一次备份,然后复制其结果。 @@ -160,7 +160,7 @@ PostgreSQL documentation - 目前,此选项仅适用于 plain 输出格式;如果选择了 tar 格式,则会被忽略。 + 目前,此选项仅适用于 普通文件 输出格式;如果选择了 tar 格式,则会被忽略。 @@ -168,7 +168,7 @@ PostgreSQL documentation - 指定预写式日志目录的位置。waldir必须是绝对路径。只有在备份采用 plain 模式时,才能指定预写式日志目录。 + 指定预写式日志目录的位置。waldir必须是绝对路径。只有在备份采用 普通文件 模式时,才能指定预写式日志目录。 @@ -238,7 +238,7 @@ PostgreSQL documentation - 启用 tar 文件输出的 gzip 压缩,使用默认压缩级别。压缩仅在使用 tar 格式时可用,并且所有 tar 文件名都会自动添加.gz后缀。 + 启用 tar 文件输出的 gzip 压缩,并指定压缩级别(0 到 9,其中 0 表示不压缩,9 表示最佳压缩)。压缩仅在使用 tar 格式时可用,并且所有 tar 文件名都会自动添加.gz后缀。 @@ -286,7 +286,7 @@ PostgreSQL documentation - 请注意,无论如何表空间目录都不会被清理。 + 请注意,无论是否使用此选项,表空间目录都不会被清理。 @@ -445,7 +445,10 @@ PostgreSQL documentation - 还可以使用其他选项: + + 其他选项也可用: + + @@ -481,18 +484,18 @@ PostgreSQL documentation - 注意 + 注解 在备份开始时,需要在源服务器上执行一次检查点。这可能需要一些时间(尤其是在未使用--checkpoint=fast选项时);在此期间,pg_basebackup看起来会处于空闲状态。 - 备份将包括数据目录和表空间中的所有文件,包括配置文件以及第三方放在这些目录中的任何额外文件,但由 PostgreSQL 管理的某些临时文件和操作系统文件除外。不过,只有普通文件和目录会被复制,但用于表空间的符号链接会被保留。指向 PostgreSQL 已知某些目录的符号链接会被复制为空目录。其他符号链接和特殊设备文件则会被跳过。具体细节见。 + 备份将包括数据目录和表空间中的所有文件,包括配置文件以及第三方放在这些目录中的任何额外文件,但由 PostgreSQL 管理的某些临时文件除外。不过,只有普通文件和目录会被复制,但用于表空间的符号链接会被保留。指向 PostgreSQL 已知某些目录的符号链接会被复制为空目录。其他符号链接和特殊设备文件则会被跳过。具体细节见 - 在 plain 格式中,除非使用了--tablespace-mapping选项,否则表空间会备份到其在源服务器上的相同路径。如果不使用此选项,那么当表空间正在使用时,就无法在与服务器相同的主机上执行 plain 格式的基础备份,因为备份将不得不写入与原始表空间相同的目录位置。 + 在 普通文件 格式中,除非使用了--tablespace-mapping选项,否则表空间会备份到其在源服务器上的相同路径。如果不使用此选项,那么当表空间正在使用时,就无法在与服务器相同的主机上执行 普通文件 格式的基础备份,因为备份将不得不写入与原始表空间相同的目录位置。 使用 tar 格式时,用户有责任在启动 PostgreSQL 服务器之前解包每个 tar 文件。如果存在额外表空间,则其 tar 文件必须解包到正确的位置。在这种情况下,服务器会根据tablespace_map文件的内容,为这些表空间创建符号链接,该文件包含在base.tar文件中。 @@ -536,7 +539,7 @@ PostgreSQL documentation - 参见 + 另见 diff --git a/zh/11/ref/pg_config-ref.sgml b/zh/11/ref/pg_config-ref.sgml index 37dd43a8..7ea2f196 100644 --- a/zh/11/ref/pg_config-ref.sgml +++ b/zh/11/ref/pg_config-ref.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_config 1 - Application + 应用程序 diff --git a/zh/11/ref/pg_controldata.sgml b/zh/11/ref/pg_controldata.sgml index 4d6f3045..2509a98f 100644 --- a/zh/11/ref/pg_controldata.sgml +++ b/zh/11/ref/pg_controldata.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_controldata 1 - Application + 应用程序 diff --git a/zh/11/ref/pg_ctl-ref.sgml b/zh/11/ref/pg_ctl-ref.sgml index 078070e0..7a73af9f 100644 --- a/zh/11/ref/pg_ctl-ref.sgml +++ b/zh/11/ref/pg_ctl-ref.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_ctl 1 - Application + 应用程序 @@ -149,7 +149,7 @@ PostgreSQL documentation - 模式会关闭在指定数据目录中运行的服务器。可以使用选项选择三种不同的关闭方法。Smart模式不允许新连接,然后等待所有现有客户端断开。如果服务器处于热备状态,那么在所有客户端断开后,恢复和流复制都会终止。Fast模式(默认值)不等待客户端断开。所有活动事务都会回滚,客户端会被强制断开,然后服务器关闭。Immediate模式会立即中止所有服务器进程,而不执行干净关闭。这样会导致服务器在下次启动时进入一次崩溃恢复周期。 + 模式会关闭在指定数据目录中运行的服务器。可以使用选项选择三种不同的关闭方法。Smart模式不允许新连接,然后等待所有现有客户端断开,以及所有在线备份结束。如果服务器处于热备状态,那么在所有客户端断开后,恢复和流复制都会终止。Fast模式(默认值)不等待客户端断开,并会终止正在进行的在线备份。所有活动事务都会回滚,客户端会被强制断开,然后服务器关闭。Immediate模式会立即中止所有服务器进程,而不执行干净关闭。这样会导致服务器在下次启动时进入一次崩溃恢复周期。 diff --git a/zh/11/ref/pg_dump.sgml b/zh/11/ref/pg_dump.sgml index e148462c..250b39f7 100644 --- a/zh/11/ref/pg_dump.sgml +++ b/zh/11/ref/pg_dump.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_dump 1 - Application + 应用程序 @@ -290,7 +290,9 @@ PostgreSQL documentation 同步快照特性,就无法保证各个工作任务在各自连接中看到相同的数据,这会 导致备份不一致。 - 如果要对 9.2 之前的服务器执行并行转储,必须确保从主进程连接数据库起,到最后一个工作任务连接数据库为止,数据库内容都不发生变化。最简单的方法是在开始备份之前,暂停所有访问数据库并修改数据的进程(DDL 和 DML)。对 9.2 之前的服务器使用参数也是必需的,即使用pg_dump -j连接这些PostgreSQL服务器时。 + + 如果要对 9.2 之前的服务器执行并行转储,必须确保从主进程连接数据库起,到最后一个工作任务连接数据库为止,数据库内容都不发生变化。最简单的方法是在开始备份之前,暂停所有访问数据库并修改数据的进程(DDL 和 DML)。对 9.2 之前的PostgreSQL服务器运行pg_dump -j时,还必须指定参数。 + diff --git a/zh/11/ref/pg_dumpall.sgml b/zh/11/ref/pg_dumpall.sgml index c6656fc8..a1bd97c4 100644 --- a/zh/11/ref/pg_dumpall.sgml +++ b/zh/11/ref/pg_dumpall.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_dumpall 1 - Application + 应用程序 @@ -32,7 +32,7 @@ PostgreSQL documentation pg_dumpall是一个实用程序,用于写出(转储)一个集簇中的所有PostgreSQL数据库到一个脚本文件中。该脚本文件包含SQL命令,可作为的输入来恢复这些数据库。它通过对集簇中的每个数据库调用来实现这一点。pg_dumpall还会转储所有数据库共有的全局对象,即数据库角色、表空间以及配置参数的权限授予。 + linkend="app-psql"/>的输入来恢复这些数据库。它通过对集簇中的每个数据库调用来实现这一点。pg_dumpall还会转储所有数据库共有的全局对象,即数据库角色、表空间。 (pg_dump不会保存这些对象。) diff --git a/zh/11/ref/pg_isready.sgml b/zh/11/ref/pg_isready.sgml index 712c7822..897f405f 100644 --- a/zh/11/ref/pg_isready.sgml +++ b/zh/11/ref/pg_isready.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_isready 1 - Application + 应用程序 diff --git a/zh/11/ref/pg_receivewal.sgml b/zh/11/ref/pg_receivewal.sgml index 1ff9de34..16f0c68a 100644 --- a/zh/11/ref/pg_receivewal.sgml +++ b/zh/11/ref/pg_receivewal.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_receivewal 1 - Application + 应用程序 diff --git a/zh/11/ref/pg_recvlogical.sgml b/zh/11/ref/pg_recvlogical.sgml index 1dab7ba3..bee35215 100644 --- a/zh/11/ref/pg_recvlogical.sgml +++ b/zh/11/ref/pg_recvlogical.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_recvlogical 1 - Application + 应用程序 @@ -60,7 +60,9 @@ PostgreSQL documentation - 删除由指定名称的复制槽,然后退出。 + + 删除由指定名称的复制槽,然后退出。 + @@ -72,9 +74,13 @@ PostgreSQL documentation 如果服务端的更改流因服务器关闭或断开连接而结束,则除非指定了,否则会循环重试。 - 流格式由创建槽时指定的输出插件决定。 + + 流格式由创建该槽时指定的输出插件决定。 + - 必须连接到创建槽时使用的同一个数据库。 + + 该连接必须连到创建该槽时所用的同一个数据库。 + @@ -111,7 +117,9 @@ PostgreSQL documentation - 将接收到的已解码事务数据写入此文件。使用-表示stdout + + 将接收到并解码后的事务数据写入该文件。指定-表示写入stdout。 + @@ -122,7 +130,7 @@ PostgreSQL documentation 指定pg_recvlogical应当以多高的频率发起fsync()调用, - 以确保输出文件被安全地刷入磁盘。 + 以确保输出文件安全刷盘。 @@ -141,14 +149,20 @@ PostgreSQL documentation - 模式下,从给定的 LSN 开始复制。有关其效果的详细信息,请参阅中的文档。在其他模式下忽略此选项。 + + 在模式下,从给定的 LSN 开始复制。关于其影响的详细信息,请参见 + 中的说明。 + 在其他模式下会忽略此选项。 + - 指定且指定名称的槽已存在时,不报错。 + + 当指定且指定名称的槽已存在时,不报错。 + @@ -156,7 +170,9 @@ PostgreSQL documentation - 当与服务器的连接丢失时,不循环重试,直接退出。 + + 当与服务器的连接丢失时,不要循环重试,直接退出。 + @@ -164,7 +180,10 @@ PostgreSQL documentation - 将选项name传递给输出插件,如果指定了选项值value,也一并传递。有哪些选项以及它们的效果取决于所用的输出插件。 + + 将选项name传递给输出插件;如果指定了value, + 则将其用作该选项的值。可用选项及其效果取决于所使用的输出插件。 + @@ -172,7 +191,10 @@ PostgreSQL documentation - 创建槽时,使用指定的逻辑解码输出插件。参见。如果槽已存在,此选项不起作用。 + + 创建该槽时,使用指定的逻辑解码输出插件。参见。 + 如果该槽已经存在,则此选项不起作用。 + @@ -180,7 +202,9 @@ PostgreSQL documentation - 此选项与中同名选项的效果相同。请参阅那里的说明。 + + 该选项与中同名选项的效果相同。参见该处说明。 + @@ -188,7 +212,11 @@ PostgreSQL documentation - 模式下,使用名为slot_name的现有逻辑复制槽。在模式下,创建此名称的槽。在模式下,删除此名称的槽。 + + 在模式下,使用名为slot_name的现有逻辑复制槽。 + 在模式下,以此名称创建该槽。 + 在模式下,删除此名称的槽。 + @@ -196,7 +224,9 @@ PostgreSQL documentation - 启用详细模式。 + + 启用详细模式。 + @@ -240,7 +270,9 @@ PostgreSQL documentation - 连接时使用的用户名。默认为当前操作系统用户名。 + + 用于连接的用户名。默认为当前操作系统用户名。 + @@ -282,7 +314,9 @@ PostgreSQL documentation - 打印pg_recvlogical的版本并退出。 + + 打印pg_recvlogical的版本并退出。 + @@ -290,7 +324,9 @@ PostgreSQL documentation - 显示pg_recvlogical命令行参数的帮助并退出。 + + 显示pg_recvlogical命令行参数的帮助并退出。 + @@ -298,7 +334,7 @@ PostgreSQL documentation - 退出状态 + 环境 与大多数其他PostgreSQL工具一样,该工具使用libpq支持的环境变量(见)。 @@ -306,7 +342,7 @@ PostgreSQL documentation - 环境 + 注解 如果源集簇启用了组权限,pg_recvlogical会在接收到的 WAL 文件上保留这些组权限。 diff --git a/zh/11/ref/pg_resetwal.sgml b/zh/11/ref/pg_resetwal.sgml index c745b778..be93baf5 100644 --- a/zh/11/ref/pg_resetwal.sgml +++ b/zh/11/ref/pg_resetwal.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_resetwal 1 - Application + 应用程序 diff --git a/zh/11/ref/pg_restore.sgml b/zh/11/ref/pg_restore.sgml index 220bc2bd..cb67cc66 100644 --- a/zh/11/ref/pg_restore.sgml +++ b/zh/11/ref/pg_restore.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_restore 1 - Application + 应用程序 diff --git a/zh/11/ref/pg_rewind.sgml b/zh/11/ref/pg_rewind.sgml index 21e2490a..5f61507c 100644 --- a/zh/11/ref/pg_rewind.sgml +++ b/zh/11/ref/pg_rewind.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_rewind 1 - Application + 应用程序 diff --git a/zh/11/ref/pg_verify_checksums.sgml b/zh/11/ref/pg_verify_checksums.sgml index 769b6289..49b1e035 100644 --- a/zh/11/ref/pg_verify_checksums.sgml +++ b/zh/11/ref/pg_verify_checksums.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_verify_checksums 1 - Application + 应用程序 diff --git a/zh/11/ref/pg_waldump.sgml b/zh/11/ref/pg_waldump.sgml index 3addac84..029f0a4d 100644 --- a/zh/11/ref/pg_waldump.sgml +++ b/zh/11/ref/pg_waldump.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_waldump 1 - Application + 应用程序 diff --git a/zh/11/ref/pgarchivecleanup.sgml b/zh/11/ref/pgarchivecleanup.sgml index 1c9c175a..b94414de 100644 --- a/zh/11/ref/pgarchivecleanup.sgml +++ b/zh/11/ref/pgarchivecleanup.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_archivecleanup 1 - Application + 应用程序 diff --git a/zh/11/ref/pgbench.sgml b/zh/11/ref/pgbench.sgml index 539c56be..1a237fb1 100644 --- a/zh/11/ref/pgbench.sgml +++ b/zh/11/ref/pgbench.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pgbench 1 - Application + 应用程序 @@ -1512,7 +1512,7 @@ statement latencies in milliseconds: 安全性 - 如果不可信用户能够访问尚未采用模式的安全使用方式的数据库,就不要在该数据库中运行pgbenchpgbench使用非限定名称,并且不会更改搜索路径。 + 如果不受信任的用户能够访问尚未采用模式的安全使用方式的数据库,就不要在该数据库中运行pgbenchpgbench使用非限定名称,并且不会更改搜索路径。 diff --git a/zh/11/ref/pgtestfsync.sgml b/zh/11/ref/pgtestfsync.sgml index e041469d..eca01155 100644 --- a/zh/11/ref/pgtestfsync.sgml +++ b/zh/11/ref/pgtestfsync.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_test_fsync 1 - Application + 应用程序 diff --git a/zh/11/ref/pgtesttiming.sgml b/zh/11/ref/pgtesttiming.sgml index 5b023c7f..1b7dbeee 100644 --- a/zh/11/ref/pgtesttiming.sgml +++ b/zh/11/ref/pgtesttiming.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_test_timing 1 - Application + 应用程序 diff --git a/zh/11/ref/pgupgrade.sgml b/zh/11/ref/pgupgrade.sgml index 2325b3e6..da629770 100644 --- a/zh/11/ref/pgupgrade.sgml +++ b/zh/11/ref/pgupgrade.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_upgrade 1 - Application + 应用程序 @@ -104,7 +104,7 @@ PostgreSQL documentation - 要使用的并发连接和进程/线程数 + 要使用的并发进程或线程数 @@ -534,7 +534,7 @@ psql --username=postgres --file=script.sql postgres - 环境 + 注解 pg_upgrade不支持升级包含使用下列reg* OID 引用系统数据类型的表列的数据库:regprocregprocedureregoperregoperatorregconfigregdictionary。(regtype可以升级。) @@ -567,7 +567,7 @@ psql --username=postgres --file=script.sql postgres - 注解 + 另见 diff --git a/zh/11/ref/postgres-ref.sgml b/zh/11/ref/postgres-ref.sgml index d6496236..f286d2d2 100644 --- a/zh/11/ref/postgres-ref.sgml +++ b/zh/11/ref/postgres-ref.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation postgres 1 - Application + 应用程序 @@ -97,7 +97,7 @@ PostgreSQL documentation 打印指定运行时参数的值并退出。 - (详情见上面的选项。)这会返回 + (详情见上面的选项。)这个选项可用于正在运行的服务器,它会返回 postgresql.conf中的值,并应用本次调用中提供的任何参数修改。它不反映 集簇启动时提供的参数。 @@ -529,7 +529,7 @@ PostgreSQL documentation - 表明另一台服务器已经在运行的失败消息 + 表明另一个服务器已经在运行的失败消息 应仔细检查,例如可根据你的系统使用下面的命令: $ ps ax | grep postgres @@ -674,16 +674,26 @@ PostgreSQL documentation 示例 - 启动 postgres 时,如需使用默认值并在后台运行,请输入: + + 要使用默认值在后台启动postgres, + 输入: + + $ nohup postgres >logfile 2>&1 </dev/null & - 启动 postgres 并指定端口,例如 1234: + + 要用指定端口启动postgres, + 例如 1234: + $ postgres -p 1234 -要使用 psql 连接到此服务器,请用 -p 选项指定该端口: + + 要使用psql连接到该服务器,请用选项指定这个端口: + $ psql -p 1234 -或者设置环境变量 PGPORT: + + 或者设置环境变量PGPORT $ export PGPORT=1234 $ psql @@ -708,7 +718,7 @@ PostgreSQL documentation - 参见 + 另见 , diff --git a/zh/11/ref/prepare.sgml b/zh/11/ref/prepare.sgml index 3a2dc184..8269da30 100644 --- a/zh/11/ref/prepare.sgml +++ b/zh/11/ref/prepare.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation PREPARE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/prepare_transaction.sgml b/zh/11/ref/prepare_transaction.sgml index 3cc45ab5..493473eb 100644 --- a/zh/11/ref/prepare_transaction.sgml +++ b/zh/11/ref/prepare_transaction.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation PREPARE TRANSACTION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/psql-ref.sgml b/zh/11/ref/psql-ref.sgml index 2396d2ed..f8b60cf8 100644 --- a/zh/11/ref/psql-ref.sgml +++ b/zh/11/ref/psql-ref.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation psql 1 - Application + 应用程序 @@ -524,7 +524,7 @@ testdb=> - 如果不可信用户能够访问尚未采用模式的安全使用方式的数据库,请在会话开始时从search_path中移除所有公众可写的 schema。可以在连接字符串中加入options=-csearch_path=,或者在执行其他 SQL 命令之前发出SELECT pg_catalog.set_config('search_path', '', false)。这种考虑并非psql特有;它适用于任何执行任意 SQL 命令的接口。 + 如果不受信任的用户能够访问尚未采用模式的安全使用方式的数据库,请在会话开始时从search_path中移除所有公众可写的模式。可以在连接字符串中加入options=-csearch_path=,或者在执行其他 SQL 命令之前发出SELECT pg_catalog.set_config('search_path', '', false)。这种考虑并非psql特有;它适用于任何执行任意 SQL 命令的接口。 @@ -1192,11 +1192,7 @@ CREATE INDEX - 生成的查询按照返回的行的顺序执行,并在每行内从左到右执行,如果有多个列。NULL字段将被忽略。生成的查询文字 - 直接发送到服务器进行处理,因此它们不能是psql元命令,也不能包含psql - 变量引用。如果任何单个查询失败,剩余查询的执行将继续,除非设置了ON_ERROR_STOP。每个查询的执行 - 都受ECHO处理的影响。(通常在使用\gexec时,将ECHO设置为 - allqueries是明智的。)查询记录、单步模式、计时和其他查询执行功能也适用于每个生成的查询。 + 生成的查询按照返回行的顺序执行;如果有多列,则在每行内从左到右执行。NULL 字段会被忽略。生成的查询按原样发送到服务器进行处理,因此不能是psql元命令,也不能包含psql变量引用。如果某个查询失败,仍会继续执行其余查询,除非设置了ON_ERROR_STOP。每个查询的执行都受ECHO处理的影响。(通常,在使用\gexec时,适宜将ECHO设为allqueries。)查询日志、单步模式、计时及其他查询执行功能也适用于每个生成的查询。 如果当前查询缓冲区为空,则改为重新执行最近发送的查询。 @@ -2339,7 +2335,7 @@ bar <acronym>SQL</acronym> 中插入变量 - psql变量的一个关键特性是可以把它们替换(插入)到常规SQL语句中,也可以把它们作为元命令的参数。此外,psql还提供了功能来确保被用作 SQL 文字和标识符的变量值会被正确地引用。插入一个值而不需要加引用的语法是在变量名前面加上一个冒号(:)。例如, + psql变量的一个关键特性是可以把它们替换(插入)到常规SQL语句中,也可以把它们作为元命令的参数。此外,psql还提供了功能来确保被用作 SQL 字面量和标识符的变量值会被正确地加引号。插入一个值而不加引号的语法是在变量名前面加上一个冒号(:)。例如, testdb=> \set foo 'my_table' testdb=> SELECT * FROM :foo; diff --git a/zh/11/ref/reassign_owned.sgml b/zh/11/ref/reassign_owned.sgml index b436f800..e3717fea 100644 --- a/zh/11/ref/reassign_owned.sgml +++ b/zh/11/ref/reassign_owned.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation REASSIGN OWNED 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/refresh_materialized_view.sgml b/zh/11/ref/refresh_materialized_view.sgml index 8df289dd..4b8f7812 100644 --- a/zh/11/ref/refresh_materialized_view.sgml +++ b/zh/11/ref/refresh_materialized_view.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation REFRESH MATERIALIZED VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/reindex.sgml b/zh/11/ref/reindex.sgml index 6e2e056f..2eabf78c 100644 --- a/zh/11/ref/reindex.sgml +++ b/zh/11/ref/reindex.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation REINDEX 7 - SQL - Language Statements + SQL - 语言语句 @@ -29,7 +29,8 @@ REINDEX [ ( VERBOSE ) ] { INDEX | TABLE | SCHEMA | DATABASE | SYSTEM } 描述 - REINDEX利用索引所属表中存储的数据重建索引,替换该索引的旧副本。以下几种情况适合使用REINDEX: + REINDEX使用索引所属表中存储的数据重建索引, + 并替换索引的旧副本。以下几种场景适合使用REINDEX @@ -99,8 +100,8 @@ REINDEX [ ( VERBOSE ) ] { INDEX | TABLE | SCHEMA | DATABASE | SYSTEM } - 重新创建当前数据库中除系统目录外的所有索引。 - 系统目录上的索引不会被处理。这种形式的REINDEX不能 + 重新创建当前数据库中的所有索引。 + 共享系统目录上的索引也会被处理。这种形式的REINDEX不能 在事务块内执行。 @@ -125,8 +126,7 @@ REINDEX [ ( VERBOSE ) ] { INDEX | TABLE | SCHEMA | DATABASE | SYSTEM } 要重新索引的特定索引、表或数据库的名称。索引名和表名可以带模式限 定。目前,REINDEX DATABASE和 - REINDEX SYSTEM只能对当前数据库重新索引。它们的参 - 数是可选的,但如果给出,就必须与当前数据库名匹配。 + REINDEX SYSTEM只能对当前数据库重新索引,所以其参数必须与当前数据库名匹配。 diff --git a/zh/11/ref/reindexdb.sgml b/zh/11/ref/reindexdb.sgml index 9d3cbc0e..8c4ef632 100644 --- a/zh/11/ref/reindexdb.sgml +++ b/zh/11/ref/reindexdb.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation reindexdb 1 - Application + 应用程序 @@ -141,7 +141,10 @@ PostgreSQL documentation - 仅重建 index。可以重建多个索引,方法是多次指定 开关。 + + 只重建index。 + 可以通过写多个开关来重建多个索引。 + @@ -169,7 +172,10 @@ PostgreSQL documentation - 仅重建以下对象的索引:schema。可以重建多个模式中的索引,方法是多次指定 开关。 + + 只重建schema中的索引。 + 可以通过写多个开关来重建多个模式中的索引。 + @@ -177,7 +183,10 @@ PostgreSQL documentation - 仅重建以下对象的索引:table。可以重建多个表的索引,方法是多次指定 开关。 + + 只重建table上的索引。 + 可以通过写多个开关来重建多个表上的索引。 + @@ -325,22 +334,24 @@ PostgreSQL documentation - 示例 + 注解 reindexdb 可能需要多次连接到 PostgreSQL 服务器,每次都要求输入密码。在这种情况下,使用 ~/.pgpass 文件会很方便。更多信息见 - 参见 + 示例 - 要重新索引数据库test: + + 要重建数据库test中的索引: $ reindexdb test - 要重新索引表foo和索引bar,其所在数据库名为abcd: + + 要重建名为abcd的数据库中表foo的索引和索引bar $ reindexdb --table=foo --index=bar abcd diff --git a/zh/11/ref/release_savepoint.sgml b/zh/11/ref/release_savepoint.sgml index f060b242..c3b97896 100644 --- a/zh/11/ref/release_savepoint.sgml +++ b/zh/11/ref/release_savepoint.sgml @@ -10,18 +10,18 @@ PostgreSQL documentation 保存点 - releasing + 释放 RELEASE SAVEPOINT 7 - SQL - Language Statements + SQL - 语言语句 RELEASE SAVEPOINT - 释放一个先前定义的保存点 + 销毁一个先前定义的保存点 @@ -48,7 +48,7 @@ RELEASE [ SAVEPOINT ] savepoint_name savepoint_name - 要释放的保存点名称。 + 要销毁的保存点名称。 @@ -74,14 +74,18 @@ RELEASE [ SAVEPOINT ] savepoint_name 示例 - 建立保存点并在之后将其销毁: + + 要建立保存点,并在稍后销毁它: + BEGIN; INSERT INTO table1 VALUES (3); SAVEPOINT my_savepoint; INSERT INTO table1 VALUES (4); RELEASE SAVEPOINT my_savepoint; COMMIT; -上面的事务会同时插入 3 和 4。 + + 上述事务将同时插入 3 和 4。 + diff --git a/zh/11/ref/reset.sgml b/zh/11/ref/reset.sgml index e8aeae8c..5e249ff9 100644 --- a/zh/11/ref/reset.sgml +++ b/zh/11/ref/reset.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation RESET 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/revoke.sgml b/zh/11/ref/revoke.sgml index 765789e7..ba756050 100644 --- a/zh/11/ref/revoke.sgml +++ b/zh/11/ref/revoke.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation REVOKE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/rollback.sgml b/zh/11/ref/rollback.sgml index f66fd2c7..e7e29c9f 100644 --- a/zh/11/ref/rollback.sgml +++ b/zh/11/ref/rollback.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ROLLBACK 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/rollback_prepared.sgml b/zh/11/ref/rollback_prepared.sgml index 3a227014..d126fabb 100644 --- a/zh/11/ref/rollback_prepared.sgml +++ b/zh/11/ref/rollback_prepared.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ROLLBACK PREPARED 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/rollback_to.sgml b/zh/11/ref/rollback_to.sgml index 0242c50b..33d84c77 100644 --- a/zh/11/ref/rollback_to.sgml +++ b/zh/11/ref/rollback_to.sgml @@ -10,13 +10,13 @@ PostgreSQL documentation 保存点 - rolling back + 回滚 ROLLBACK TO SAVEPOINT 7 - SQL - Language Statements + SQL - 语言语句 @@ -34,8 +34,7 @@ ROLLBACK [ WORK | TRANSACTION ] TO [ SAVEPOINT ] savepoint_name描述 - 回滚该保存点建立后执行的所有命令,然后在同一事务层级启动一个新的 - 子事务。该保存点仍然有效,如有需要,之后还可以再次回滚到它。 + 回滚该保存点建立后执行的所有命令。该保存点仍然有效,如有需要,之后还可以再次回滚到它。 diff --git a/zh/11/ref/savepoint.sgml b/zh/11/ref/savepoint.sgml index 99f5a6bc..6b92b9a4 100644 --- a/zh/11/ref/savepoint.sgml +++ b/zh/11/ref/savepoint.sgml @@ -10,13 +10,13 @@ PostgreSQL documentation 保存点 - defining + 定义 SAVEPOINT 7 - SQL - Language Statements + SQL - 语言语句 @@ -102,7 +102,9 @@ COMMIT; 上述事务将同时插入 3 和 4。 - 使用同一个保存点名称: + + 要重复使用同一个保存点名称: + BEGIN; INSERT INTO table1 VALUES (1); SAVEPOINT my_savepoint; @@ -110,18 +112,20 @@ BEGIN; SAVEPOINT my_savepoint; INSERT INTO table1 VALUES (3); - -- rollback to the second savepoint + -- 回滚到第二个保存点 ROLLBACK TO SAVEPOINT my_savepoint; - SELECT * FROM table1; -- shows rows 1 and 2 + SELECT * FROM table1; -- 显示值为 1 和 2 的行 - -- release the second savepoint + -- 释放第二个保存点 RELEASE SAVEPOINT my_savepoint; - -- rollback to the first savepoint + -- 回滚到第一个保存点 ROLLBACK TO SAVEPOINT my_savepoint; - SELECT * FROM table1; -- shows only row 1 + SELECT * FROM table1; -- 仅显示值为 1 的行 COMMIT; -上面的事务展示了先回滚行 3,再回滚行 2。 + + 上述事务展示了先回滚值为 3 的行,再回滚值为 2 的行。 + diff --git a/zh/11/ref/security_label.sgml b/zh/11/ref/security_label.sgml index b011ab8f..2ed9da38 100644 --- a/zh/11/ref/security_label.sgml +++ b/zh/11/ref/security_label.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SECURITY LABEL 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/select.sgml b/zh/11/ref/select.sgml index 5ba44ace..adc176d3 100644 --- a/zh/11/ref/select.sgml +++ b/zh/11/ref/select.sgml @@ -20,7 +20,7 @@ PostgreSQL documentation SELECT 7 - SQL - Language Statements + SQL - 语言语句 @@ -1343,7 +1343,7 @@ SELECT * FROM (SELECT * FROM mytable FOR UPDATE) ss ORDER BY column1; REPEATABLE READSERIALIZABLE事务隔离级别下, - 这将导致序列化失败(带有SQLSTATE'40001'), + 这将导致串行化失败(SQLSTATE'40001'), 因此在这些隔离级别下不可能接收到无序的行。 diff --git a/zh/11/ref/select_into.sgml b/zh/11/ref/select_into.sgml index 0f6598a8..a29b4d73 100644 --- a/zh/11/ref/select_into.sgml +++ b/zh/11/ref/select_into.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SELECT INTO 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/set.sgml b/zh/11/ref/set.sgml index 8b488bec..0eb60779 100644 --- a/zh/11/ref/set.sgml +++ b/zh/11/ref/set.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SET 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/set_constraints.sgml b/zh/11/ref/set_constraints.sgml index 53d0c7a0..e5588db7 100644 --- a/zh/11/ref/set_constraints.sgml +++ b/zh/11/ref/set_constraints.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SET CONSTRAINTS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/set_role.sgml b/zh/11/ref/set_role.sgml index e53e261b..7e768998 100644 --- a/zh/11/ref/set_role.sgml +++ b/zh/11/ref/set_role.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SET ROLE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/set_session_auth.sgml b/zh/11/ref/set_session_auth.sgml index 3fb9b989..99525834 100644 --- a/zh/11/ref/set_session_auth.sgml +++ b/zh/11/ref/set_session_auth.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SET SESSION AUTHORIZATION 7 - SQL - Language Statements + SQL - 语言语句 @@ -46,7 +46,7 @@ RESET SESSION AUTHORIZATION - 只有当初始会话用户(即已认证用户)具有超级用户权限时, + 只有当初始会话用户(即已认证用户)最初具有超级用户权限时, 才能更改会话用户标识符。否则,只有当该命令指定的是已认证用户名时, 才会被接受。 diff --git a/zh/11/ref/set_transaction.sgml b/zh/11/ref/set_transaction.sgml index 65c10806..5355df65 100644 --- a/zh/11/ref/set_transaction.sgml +++ b/zh/11/ref/set_transaction.sgml @@ -26,7 +26,7 @@ PostgreSQL documentation SET TRANSACTION 7 - SQL - Language Statements + SQL - 语言语句 @@ -66,7 +66,7 @@ SET SESSION CHARACTERISTICS AS TRANSACTION transa - 一个事务的隔离级别决定当其他事务并行运行时该事务能看见什么数据: + 一个事务的隔离级别决定当其他事务并发运行时该事务能看见什么数据: @@ -137,7 +137,7 @@ SET SESSION CHARACTERISTICS AS TRANSACTION transa 事务属性才会生效。当为一个事务同时选择这三个属性时,该事务在 首次获取其快照时可能会阻塞;在此之后,它便可以运行,而无需承担普通 SERIALIZABLE事务的常规开销,也不会有促成 - 序列化失败或因序列化失败而被取消的风险。这种模式非常适合长时间运行的 + 串行化失败或因串行化失败而被取消的风险。这种模式非常适合长时间运行的 报表或备份。 diff --git a/zh/11/ref/show.sgml b/zh/11/ref/show.sgml index 093d1793..9f542eea 100644 --- a/zh/11/ref/show.sgml +++ b/zh/11/ref/show.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SHOW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/start_transaction.sgml b/zh/11/ref/start_transaction.sgml index e78db715..d85eee63 100644 --- a/zh/11/ref/start_transaction.sgml +++ b/zh/11/ref/start_transaction.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation START TRANSACTION 7 - SQL - Language Statements + SQL - 语言语句 @@ -64,15 +64,16 @@ START TRANSACTION [ transaction_mode - DEFERRABLE 这一 - transaction_mode 是 - PostgreSQL语言扩展。 + DEFERRABLE + transaction_mode + 是PostgreSQL的一种语言扩展。 SQL 标准要求在连续的transaction_modes之间有逗号, - 但出于历史原因PostgreSQL允许省略逗号。 + 但出于历史原因, + PostgreSQL允许省略逗号。 diff --git a/zh/11/ref/truncate.sgml b/zh/11/ref/truncate.sgml index 5d8fcd4e..d2929b96 100644 --- a/zh/11/ref/truncate.sgml +++ b/zh/11/ref/truncate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation TRUNCATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/unlisten.sgml b/zh/11/ref/unlisten.sgml index fde4a5dd..505b888b 100644 --- a/zh/11/ref/unlisten.sgml +++ b/zh/11/ref/unlisten.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation UNLISTEN 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/update.sgml b/zh/11/ref/update.sgml index 2ef2540b..7dad0114 100644 --- a/zh/11/ref/update.sgml +++ b/zh/11/ref/update.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation UPDATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/ref/vacuum.sgml b/zh/11/ref/vacuum.sgml index b7fe0125..01712461 100644 --- a/zh/11/ref/vacuum.sgml +++ b/zh/11/ref/vacuum.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation VACUUM 7 - SQL - Language Statements + SQL - 语言语句 @@ -200,7 +200,7 @@ VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ ANALYZE ] [ - 参见 + 示例 清理数据库 test diff --git a/zh/11/ref/values.sgml b/zh/11/ref/values.sgml index 98520764..d02d1de6 100644 --- a/zh/11/ref/values.sgml +++ b/zh/11/ref/values.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation VALUES 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/11/release-11.sgml b/zh/11/release-11.sgml index acde0cc7..3b9af4d4 100644 --- a/zh/11/release-11.sgml +++ b/zh/11/release-11.sgml @@ -1056,8 +1056,8 @@ Branch: REL_11_STABLE [0048c3b51] 2023-07-04 09:27:00 +1200 - 使用位图堆扫描、使用 GIN 索引以及检查初始为空的 B-树 索引时可能会遗漏冲突。 - 所有这些情况都可能因不当允许冲突事务提交而导致可序列化失败。 + 使用位图堆扫描、使用 GIN 索引以及检查初始为空的 B-树索引时可能会遗漏冲突。 + 所有这些情况都可能因不当允许相互冲突的事务提交而破坏可串行性。 diff --git a/zh/11/runtime.sgml b/zh/11/runtime.sgml index 87fbf88a..0ac767b5 100644 --- a/zh/11/runtime.sgml +++ b/zh/11/runtime.sgml @@ -9,7 +9,7 @@ <productname>PostgreSQL</productname>用户账户 - postgres user + postgres 用户 与任何可从外部访问的服务器守护进程一样,建议使用单独的用户账户运行 PostgreSQL。该用户账户应该只拥有服务器管理的数据,不应与其他守护进程共用。(例如,使用 nobody 用户就不是好主意。)不建议将可执行文件安装为由该用户所有,因为系统一旦被攻破,就可能修改自己的二进制文件。 @@ -32,7 +32,7 @@ - 在做任何事情之前,必须先在磁盘上初始化一个数据库存储区域。我们把它称为数据库集簇。(SQL 标准使用术语 catalog cluster。)数据库集簇是由一个正在运行的数据库服务器实例管理的一组数据库。初始化之后,数据库集簇中会包含一个名为postgres的数据库,作为供工具、用户和第三方应用使用的默认数据库。数据库服务器本身并不要求该postgres数据库存在,但许多外部工具程序都假定它存在。初始化期间,集簇中还会创建另一个数据库,名为template1。顾名思义,它会作为后续新建数据库的模板;不应将它用于实际工作。(关于在集簇中创建新数据库的信息,见。) + 在做任何事情之前,必须先在磁盘上初始化一个数据库存储区域。我们把它称为数据库集簇。(SQL 标准使用术语目录集簇(catalog cluster)。)数据库集簇是由一个正在运行的数据库服务器实例管理的一组数据库。初始化之后,数据库集簇中会包含一个名为postgres的数据库,作为供工具、用户和第三方应用使用的默认数据库。数据库服务器本身并不要求该postgres数据库存在,但许多外部工具程序都假定它存在。初始化期间,集簇中还会创建另一个数据库,名为template1。顾名思义,它会作为后续新建数据库的模板;不应将它用于实际工作。(关于在集簇中创建新数据库的信息,见。) 从文件系统角度看,数据库集簇就是一个目录,所有数据都存储在其下。我们将它称为数据目录数据区域。数据存放位置完全由你决定,没有默认值;常用位置包括 /usr/local/pgsql/data/var/lib/pgsql/data。要初始化数据库集簇,请使用命令 initdb该命令随以下产品安装:PostgreSQL。数据库集簇在文件系统中的目标位置通过 选项指定,例如: @@ -163,14 +163,14 @@ su postgres -c 'pg_ctl start -D /usr/local/pgsql/data -l serverlog' 对于FreeBSD,请查看PostgreSQL源码发布包中的contrib/start-scripts/freebsd文件。 - FreeBSDstart script + FreeBSD启动脚本 OpenBSD上,把以下内容加入/etc/rc.local: - OpenBSDstart script + OpenBSD启动脚本 if [ -x /usr/local/pgsql/bin/pg_ctl -a -x /usr/local/pgsql/bin/postgres ]; then su -l postgres -c '/usr/local/pgsql/bin/pg_ctl start -s -l /var/postgresql/log -D /usr/local/pgsql/data' @@ -183,7 +183,7 @@ fi Linux系统上,可以把 - Linuxstart script + Linux启动脚本 /usr/local/pgsql/bin/pg_ctl start -l logfile -D /usr/local/pgsql/data @@ -222,14 +222,14 @@ WantedBy=multi-user.target NetBSD上,可根据偏好使用FreeBSDLinux的启动脚本。 - NetBSDstart script + NetBSD启动脚本 Solaris上,创建一个名为/etc/init.d/postgresql的文件,其中包含以下内容: - Solarisstart script + Solaris启动脚本 su - postgres -c "/usr/local/pgsql/bin/pg_ctl start -l logfile -D /usr/local/pgsql/data" @@ -316,7 +316,7 @@ psql: could not connect to server: No such file or directory 管理内核资源 - PostgreSQL有时会耗尽操作系统的各种资源限制,尤其是在同一系统上运行多个服务器副本,或在非常大型的安装环境中时更是如此。本节解释PostgreSQL使用的内核资源,以及你可以采取哪些步骤来解决与内核资源消耗相关的问题。 + PostgreSQL有时会达到操作系统的各种资源上限,尤其是在同一系统上运行多个服务器实例,或在非常大型的安装环境中时更是如此。本节解释PostgreSQL使用的内核资源,以及你可以采取哪些步骤来解决与内核资源消耗相关的问题。 @@ -343,7 +343,7 @@ psql: could not connect to server: No such file or directory - System V IPC 功能通常受系统范围的分配限制约束。当PostgreSQL超出这些限制之一时,服务器会拒绝启动,并留下带有指导性的错误消息,说明问题所在以及应如何处理(另见)。相关内核参数在不同系统上的命名基本一致,给出了概览;不过,设置它们的方法却各不相同。下面给出一些平台上的建议。 + System V IPC 功能通常受系统范围的分配限制约束。当PostgreSQL超出这些限制之一时,服务器会拒绝启动,并应留下带有指导性的错误消息,说明问题所在以及应如何处理(另见)。相关内核参数在不同系统上的命名基本一致,给出了概览;不过,设置它们的方法却各不相同。下面给出一些平台上的建议。
@@ -363,7 +363,7 @@ psql: could not connect to server: No such file or directory SHMMAX 共享内存段的最大尺寸(字节) - 至少 1kB,但是默认值通常要高一些 + 至少 1kB,但是默认值通常高得多 @@ -438,7 +438,7 @@ psql: could not connect to server: No such file or directory - 与semaphore undo有关的其他各种设置,如SEMMNUSEMUME,不会影响PostgreSQL。 + 与信号量撤销有关的其他各种设置,如SEMMNUSEMUME,不会影响PostgreSQL 使用 POSIX 信号量时,所需数量与 System V 相同,即每个允许的连接()、自动清理工作进程()和后台进程()各需一个信号量。在优先使用此实现的平台上,POSIX 信号量数量没有特定的内核限制。 @@ -462,11 +462,13 @@ psql: could not connect to server: No such file or directory FreeBSDIPC 配置 - 要更改默认 IPC 设置,可以使用 sysctlloader 接口。可以通过 sysctl 设置以下参数: + + 可以使用sysctlloader接口更改默认 IPC 配置。下列参数可用sysctl设置: # sysctl kern.ipc.shmall=32768 # sysctl kern.ipc.shmmax=134217728 -要让这些设置在重启后仍然生效,请修改 /etc/sysctl.conf。 + + 要让这些设置在重启之后也保持,请修改/etc/sysctl.conf 这些信号量相关设置对于 sysctl 是只读的;设置它们时,可修改 /boot/loader.conf: @@ -638,7 +640,9 @@ project.max-msg-ids=(priv,4096,deny) - 此外,如果你正在某个区(zone)中运行 PostgreSQL,可能也需要提高该区的资源使用限制。关于 projectsprctl 的更多信息,请参见 System Administrator's Guide 中的“Chapter2: Projects and Tasks”。 + + 此外,如果你正在某个区(zone)中运行PostgreSQL,可能也需要提高该区的资源使用限制。关于projectsprctl的更多信息,请参见System Administrator's Guide中的 "Chapter 2: Projects and Tasks"。 + @@ -672,7 +676,7 @@ WARNING: could not remove shared memory segment "/PostgreSQL.1450751626": No su - 用户注销可能会作为维护作业的一部分发生,也可能在管理员以postgres用户或类似名称登录时手工触发,因此通常很难彻底防止。 + 用户注销可能会作为维护作业的一部分发生,也可能在管理员以postgres用户登录或执行类似操作时手工触发,因此通常很难彻底防止。 @@ -743,7 +747,7 @@ default:\ - 另一个在支持大量客户端连接时可能需要关注的内核限制,是套接字连接队列的最大长度。如果在很短时间内到达的连接请求超过了这个数量,那么其中一些请求可能会在主管服务器进程来得及处理之前就被拒绝,于是客户端会收到不太有帮助的连接失败错误,例如Resource temporarily unavailableConnection refused。在许多平台上,默认队列长度限制是 128。要提高它,请通过sysctl调整相应的内核参数,然后重新启动主管服务器进程。该参数在不同系统上的名称不同:在 Linux 上是net.core.somaxconn,在较新的 FreeBSD 上是kern.ipc.soacceptqueue,在 macOS 和其他 BSD 变体上是kern.ipc.somaxconn。 + 另一个在支持大量客户端连接时可能需要关注的内核限制,是套接字连接队列的最大长度。如果在很短时间内到达的连接请求超过了这个数量,那么其中一些请求可能会在postmaster来得及处理之前就被拒绝,于是客户端会收到不太有帮助的连接失败错误,例如Resource temporarily unavailableConnection refused。在许多平台上,默认队列长度限制是 128。要提高它,请通过sysctl调整相应的内核参数,然后重新启动postmaster。该参数在不同系统上的名称不同:在 Linux 上是net.core.somaxconn,在较新的 FreeBSD 上是kern.ipc.soacceptqueue,在 macOS 和其他 BSD 变体上是kern.ipc.somaxconn @@ -751,7 +755,7 @@ default:\ Linux 内存过量分配 - memory overcommit + 内存过量分配 @@ -759,7 +763,7 @@ default:\ - overcommit + 过量分配 在 Linux 2.4 及更高版本中,默认的虚拟内存行为对 PostgreSQL 并非最佳。由于内核实现内存过量分配的方式,如果 PostgreSQL 或其他进程的内存需求导致系统耗尽虚拟内存,内核可能会终止 PostgreSQL 的 postmaster(主管服务器进程)。 @@ -776,7 +780,7 @@ Out of Memory: Killed process 12345 (postgres). 避免该问题的一种办法,是让PostgreSQL运行在一台你能确定不会被其他进程耗尽内存的机器上。如果内存紧张,增加操作系统交换空间也有助于避免这个问题,因为内存不足(OOM)杀手只有在物理内存和交换空间都耗尽时才会被触发。 - 如果导致系统耗尽内存的正是 PostgreSQL 自身,那么你可以通过调整配置来避免该问题。在某些情况下,调低与内存相关的配置参数会有帮助,尤其是 shared_bufferswork_mem。在其他情况下,允许数据库服务器接受过多连接也可能导致这一问题。很多时候,更好的做法是减小 max_connections,并转而使用外部连接池软件。 + 如果导致系统耗尽内存的正是 PostgreSQL 自身,那么你可以通过调整配置来避免该问题。在某些情况下,调低与内存相关的配置参数会有帮助,尤其是 shared_bufferswork_mem。在其他情况下,允许数据库服务器接受过多连接也可能导致这一问题。很多时候,更好的做法可能是减小 max_connections,并转而使用外部连接池软件。 在 Linux 2.6 及更高版本中,可以修改内核的行为,使其不会过量分配内存。虽然此设置无法完全阻止 OOM 杀手 被调用,但会显著降低发生概率,从而使系统行为更健壮。方法是选择严格的过量分配模式,使用以下命令:sysctl: @@ -785,12 +789,26 @@ sysctl -w vm.overcommit_memory=2 或者在以下文件中加入等效条目:/etc/sysctl.conf。你可能还希望修改相关设置 vm.overcommit_ratio。详细信息参见内核文档文件 - 另一种方法不要求改变 vm.overcommit_memory,但也可与该设置的修改结合使用:将 postmaster 进程特有的OOM score adjustment值设为 -1000,从而保证它不会成为 OOM 杀手 的目标。最简单的方法是执行: + + 另一种方法可在修改或不修改 vm.overcommit_memory 的情况下使用: + 把 postmaster 进程专属的OOM 评分调整值设为 -1000, + 从而保证它不会成为 OOM 杀手的目标。最简单的做法是在 postmaster + 启动脚本中、调用 postmaster 之前执行: + echo -1000 > /proc/self/oom_score_adj -执行位置是在 postmaster 的启动脚本中,紧接在调用 postmaster 之前。注意,必须以 root 身份执行此操作,否则不会生效;因此,在 root 所有的启动脚本中执行最方便。如果这样做,还应在启动脚本中调用 postmaster 之前设置以下环境变量: + + 请注意,这个操作必须以 root 身份完成,否则不会生效;因此,由 root 拥有的启动脚本是最容易执行该操作的位置。 + 如果这样做,还应在调用 postmaster 之前,在启动脚本中设置以下环境变量: + export PG_OOM_ADJUST_FILE=/proc/self/oom_score_adj export PG_OOM_ADJUST_VALUE=0 -这些设置会使 postmaster 子进程以正常的 OOM 分数调整值零运行,因此 OOM 杀手 仍可在需要时将它们作为目标。你可以为以下变量使用其他值:PG_OOM_ADJUST_VALUE,以使子进程采用其他 OOM 分数调整值。(PG_OOM_ADJUST_VALUE 也可以省略,此时默认为零。)如果不设置 PG_OOM_ADJUST_FILE,子进程将使用与 postmaster 相同的 OOM 分数调整值,这并不明智,因为这样设置的目的就是确保 postmaster 获得优先保护。 + + 这些设置会使 postmaster 子进程以常规的 OOM 评分调整值零运行,以便 OOM 杀手在需要时仍可将它们作为目标。 + 如果希望子进程以其他 OOM 评分调整值运行,也可以为 PG_OOM_ADJUST_VALUE 指定其他值。 + (也可以省略 PG_OOM_ADJUST_VALUE,此时默认为零。) + 如果不设置 PG_OOM_ADJUST_FILE,子进程就会和 postmaster 使用相同的 OOM 评分调整值, + 这并不明智,因为这样做的目的正是确保 postmaster 获得优先保护。 + 较旧的 Linux 内核不提供 /proc/self/oom_score_adj,但可能提供名为 /proc/self/oom_adj 的同类功能的早期版本。其工作方式相同,只是禁用值为 -17 而非 -1000 @@ -820,8 +838,9 @@ $ grep Huge /proc/meminfo - 你可能还需要授予数据库服务器的操作系统用户使用大页的权限,例如通过sysctl设置vm.hugetlb_shm_group,以及/或者授予其使用ulimit -l锁定内存的权限。 - + 可能还需要通过 sysctl 设置 vm.hugetlb_shm_group, + 授予数据库服务器的操作系统用户使用大页的权限,以及/或者通过 ulimit -l 授予其锁定内存的权限。 + PostgreSQL 对大页的默认行为是:只要可能就使用它们;如果失败,则回退到普通页。要强制使用大页,可以在 postgresql.conf 中将 设为 on。请注意,在这种设置下,如果没有足够的大页可用,PostgreSQL 将无法启动。 @@ -847,7 +866,7 @@ $ grep Huge /proc/meminfo 这是智能关闭模式。 收到SIGTERM后,服务器禁止新连接,但允许现有会话正常结束工作。 - 仅在所有会话终止后才会关闭。如果服务器在请求智能关闭时处于恢复状态, + 仅在所有会话终止后才会关闭。如果服务器处于在线备份模式,还会等待该模式结束。在线备份模式生效期间,仍允许新的超级用户连接(这一例外允许超级用户连接以结束在线备份模式),但不允许其他新连接。如果服务器在请求智能关闭时处于恢复状态, 则只有在所有常规会话终止后,恢复和流复制才会停止。 @@ -860,7 +879,7 @@ $ grep Huge /proc/meminfo 这是快速关闭模式。 服务器禁止新连接并向所有现有服务器进程发送SIGTERM, 这将导致它们中止当前事务并迅速退出。然后等待所有服务器进程退出,最后关闭。 - + 如果服务器处于在线备份模式,该模式将被终止,导致备份不可用。 @@ -893,12 +912,12 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`升级 PostgreSQL 集簇 - upgrading + 升级 - version - compatibility + 版本 + 兼容性 @@ -913,10 +932,11 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` - 对于 PostgreSQL版本,内部数据存储格式可能会发生变化,因此升级会更复杂。将数据迁移到新的大版本的传统方法是转储并恢复数据库,不过这可能比较慢。更快的方法是 。此外,也可以使用复制方法,如下所述。 + + 对于PostgreSQL版本,内部数据存储格式可能会发生变化,因此升级会复杂得多。将数据迁移到新的主版本的传统方法是转储并恢复数据库,不过这可能比较慢。更快的方法是。此外,也可以使用复制方法,如下所述。 - 新的主版本通常还会引入一些用户可见的不兼容变化,因此应用程序可能也需要做出修改。所有用户可见的变化都列在发行说明()中;请特别留意标为Migration的小节。虽然你可以从一个主版本直接升级到另一个主版本,而不必逐个升级中间版本,但仍应阅读所有中间版本的主版本发行说明。 + 新的主版本通常还会引入一些用户可见的不兼容变化,因此应用程序可能也需要做出修改。所有用户可见的变化都列在发行说明()中;请特别留意标为迁移(Migration)的小节。虽然你可以从一个主版本直接升级到另一个主版本,而不必逐个升级中间版本,但仍应阅读所有中间版本的主版本发行说明。 @@ -975,7 +995,7 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` - 这涉及以后端函数 API 为代表的变更,该 API 使用 C 语言编写。这类变更会影响那些深入引用服务器内部后端函数的代码。 + 这涉及使用 C 语言编写的后端函数 API 的变更。这类变更会影响那些深入引用服务器内部后端函数的代码。 @@ -986,7 +1006,7 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`通过pg_dumpall升级数据 - 一种升级方法是从某个主版本的PostgreSQL导出数据,再在另一个版本中恢复。要这样做,必须使用逻辑备份工具,例如pg_dumpall;文件系统级备份方法不起作用。(系统中有相应检查,会阻止你在不兼容版本的PostgreSQL上使用某个数据目录,因此即便误用错误版本的服务器去启动某个数据目录,通常也不会造成太大损害。) + 一种升级方法是从某个主版本的PostgreSQL转储数据,再在另一个版本中恢复。要这样做,必须使用逻辑备份工具,例如pg_dumpall;文件系统级备份方法不起作用。(系统中有相应检查,会阻止你在不兼容版本的PostgreSQL上使用某个数据目录,因此即便误用错误版本的服务器去启动某个数据目录,通常也不会造成太大损害。) 建议使用来自较新版本 PostgreSQLpg_dumppg_dumpall 程序,以利用这些程序可能包含的改进。当前版本的转储程序可以读取从 8.0 起任意服务器版本的数据。 @@ -999,13 +1019,13 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` - 如果是在制作备份,请确认数据库此时没有正在进行更新。这不会影响备份的一致性,但那些变更当然不会包含在备份中。必要时,可修改/usr/local/pgsql/data/pg_hba.conf中的访问权限(或采用等效方法),禁止除你之外的其他人访问数据库。有关访问控制的更多信息见。 + 如果是在制作备份,请确认数据库此时没有正在进行更新。更新操作不会影响备份的完整性,但那些变更当然不会包含在备份中。必要时,可修改/usr/local/pgsql/data/pg_hba.conf(或等效文件)中的访问权限,禁止除你之外的其他人访问数据库。有关访问控制的更多信息见 pg_dumpall - use during upgrade + 在升级期间使用 要备份整个数据库安装,请输入: @@ -1026,7 +1046,7 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` pg_ctl stop - 在那些会自动启动PostgreSQL的系统上,可能已经有某个启动脚本能完成同样的工作。例如,在Red Hat Linux系统上,也许下面这条命令就可以: + 在那些会在开机时自动启动PostgreSQL的系统上,可能已经有某个启动脚本能完成同样的工作。例如,在Red Hat Linux系统上,也许下面这条命令就可以: /etc/rc.d/init.d/postgresql stop @@ -1108,7 +1128,9 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 通过复制升级数据 - 也可以使用逻辑复制方法,创建一个运行较新版本 PostgreSQL 的备库。之所以可行,是因为逻辑复制支持不同大版本 PostgreSQL 之间进行复制。该备库可以与旧服务器部署在同一台机器上,也可以部署在不同机器上。一旦它与主库(运行旧版本 PostgreSQL)同步,就可以切换主备角色,让备库成为主库,并关闭旧的数据库实例。这种计划内切换只会为升级带来几秒钟的停机时间。 + + 也可以使用逻辑复制方法,创建一个运行较新版本PostgreSQL的备库。之所以可行,是因为逻辑复制支持不同主版本PostgreSQL之间进行复制。该备库可以与旧服务器部署在同一台机器上,也可以部署在不同机器上。一旦它与主库(运行旧版本PostgreSQL)同步,就可以切换主备角色,让备库提升为主库,并关闭旧的数据库实例。这种切换使升级只需几秒钟的停机时间。 + 这种升级方法既可以使用内置的逻辑复制功能,也可以使用外部逻辑复制系统,例如pglogicalSlonyLondisteBucardo。 @@ -1146,7 +1168,7 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 - PostgreSQL提供了多个层次的加密,并在防止数据因数据库服务器被盗、不可靠的管理员或不安全网络等原因而泄露方面提供了很高的灵活性。对于医疗记录、金融交易等敏感数据,加密也可能是合规要求的一部分。 + PostgreSQL提供了多个层次的加密,并在防止数据因数据库服务器被盗、不诚实的管理员或不安全网络等原因而泄露方面提供了很高的灵活性。为了保护医疗记录、金融交易等敏感数据,也可能需要使用加密。 @@ -1258,7 +1280,7 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 - 如果私钥受密码保护,服务器会提示输入该密码,并在输入之前不会启动。默认情况下,使用密码会禁用无需重启服务器即可更改 SSL 配置的能力,不过参见。此外,在 Windows 上完全无法使用带密码保护的私钥。 + 如果私钥受口令保护,服务器会提示输入该口令,并在输入之前不会启动。默认情况下,使用口令会禁用无需重启服务器即可更改 SSL 配置的能力,不过参见。此外,在 Windows 上完全无法使用带口令保护的私钥。 @@ -1285,7 +1307,7 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 - 使用NULL-SHANULL-MD5密码套件,可以在几乎没有加密开销的情况下完成认证。不过,中间人仍然能够读取并转发客户端与服务器之间的通信。此外,与认证的开销相比,加密开销本身通常很小。基于这些原因,不建议使用 NULL 密码套件。 + 使用NULL-SHANULL-MD5密码套件,可以在没有加密开销的情况下完成认证。不过,中间人仍然能够读取并转发客户端与服务器之间的通信。此外,与认证的开销相比,加密开销本身很小。基于这些原因,不建议使用 NULL 密码套件。 @@ -1494,17 +1516,19 @@ ssh -L 63333:db.foo.com:5432 joe@shell.foo.com - 在 <systemitem class="osname">Windows</systemitem> 上注册 <application>Event Log</application> + 在<systemitem class="osname">Windows</systemitem>上注册<application>事件日志</application> 事件日志 事件日志 - 要向操作系统注册 Windows - event log 库,请执行以下命令: + + 要向操作系统注册一个Windows事件日志库,请执行以下命令: + regsvr32 pgsql_library_directory/pgevent.dll -这会创建事件查看器使用的注册表条目,条目位于默认事件源之下,其名称为 PostgreSQL。 + + 这会创建被事件查看器使用的注册表项,默认事件源命名为PostgreSQL @@ -1514,7 +1538,9 @@ ssh -L 63333:db.foo.com:5432 joe@shell.foo.com - 要从操作系统中注销 event log 库,请执行以下命令: + + 要从操作系统中注销该事件日志库,请执行以下命令: + regsvr32 /u [/i:event_source_name] pgsql_library_directory/pgevent.dll diff --git a/zh/11/spgist.sgml b/zh/11/spgist.sgml index 2d5f41d7..fb465640 100644 --- a/zh/11/spgist.sgml +++ b/zh/11/spgist.sgml @@ -4,7 +4,7 @@ SP-GiST 索引 - index + 索引 SP-GiST @@ -12,7 +12,7 @@ 简介 - SP-GiST 是 space-partitioned GiST + SP-GiST 是空间分区 GiST 的缩写。SP-GiST 支持分区搜索树,这使得开发多种不同的 非平衡数据结构成为可能,例如四叉树、k-d 树以及基数树(trie)。这些结构 的共同特征是,它们会反复将搜索空间划分为不必等大的分区。与这种划分规则良 @@ -49,7 +49,7 @@ 内置操作符类 - 核心 PostgreSQL 发行版包含了 + PostgreSQL 核心发行版包含了 SP-GiST 操作符类,如 所示。 @@ -60,7 +60,7 @@ 名称 - 索引数据类型 + 被索引数据类型 可索引操作符 @@ -158,11 +158,11 @@ - SP-GiST 核心代码会处理空项。虽然 - SP-GiST 索引确实会为被索引列中的空值存储项,但这一 - 点对索引操作符类代码是隐藏的:不会有空的索引项或搜索条件传递给操作符类 - 方法。(这里假定 SP-GiST 操作符是严格的,因此对空 - 值不可能成功。)因此,这里不再进一步讨论空值。 + SP-GiST 核心代码负责处理值为 null 的索引项。虽然 + SP-GiST 索引会为被索引列中的 null 值存储索引项, + 但索引操作符类代码看不到这些项:值为 null 的索引项或搜索条件绝不会传给 + 操作符类方法。(这里假定 SP-GiST 操作符是严格的, + 因此对 null 值不可能返回真。)所以这里不再讨论 null 值。 @@ -172,7 +172,7 @@ internal 参数,第一个参数是指向某个 C 结构体的指针,其中包 含该支持方法的输入值;第二个参数也是指向某个 C 结构体的指针,方法必须将输 出值写入其中。四个必需方法只返回 void,因为它们的全部结果 - 都体现在输出结构体中;但 leaf_consistent 会返回一个 + 都体现在输出结构体中;但 leaf_consistent 还返回一个 boolean 结果。这些方法不得修改其输入结构体中的任何字段。在 所有情况下,调用用户定义方法之前,输出结构体都会先被清零。可选的第六个方 法 compress 只接受一个待索引的 datum @@ -190,9 +190,16 @@ 返回索引实现的静态信息,包括前缀和结点标签数据类型的 OID。 - SQL声明必须如下所示: + + 该函数的 SQL 声明必须如下所示: + CREATE FUNCTION my_config(internal, internal) RETURNS void ... -第一个参数是一个指向spgConfigInC 结构体的指针,其中包含该函数的输入数据。第二个参数是一个指向spgConfigOutC 结构体的指针,函数必须将结果数据填入其中。 + + 第一个参数是一个指向 spgConfigIn C 结构体的 + 指针,其中包含该函数的输入数据。第二个参数是一个指向 + spgConfigOut C 结构体的指针,函数必须将结果 + 数据填入其中。 + typedef struct spgConfigIn { Oid attType; /* 要被索引的数据类型 */ @@ -203,12 +210,14 @@ typedef struct spgConfigOut Oid prefixType; /* 内部元组前缀的数据类型 */ Oid labelType; /* 内部元组结点标签的数据类型 */ Oid leafType; /* 叶子元组值的数据类型 */ - bool canReturnData; /* 操作符类能重构原始数据 */ - bool longValuesOK; /* 操作符类能处理值 > 1 页 */ + bool canReturnData; /* 操作符类能重建原始数据 */ + bool longValuesOK; /* 操作符类能处理大小 > 1 页的值 */ } spgConfigOut; - attType的传入是为了支持多态索引操作符类;对于普通的固定数据类型操作符类,它始终具有相同的值,因此可以忽略。 + 传入 attType 是为了支持多态索引操作符类; + 对于普通的固定数据类型操作符类,它始终具有相同的值,因此可以忽略。 + 对于不使用前缀的操作符类,可以将 prefixType @@ -222,7 +231,7 @@ typedef struct spgConfigOut )。 - leafType通常与attType相同。出于向后兼容的考虑,config方法可以不初始化leafType;这与将leafType设为等于attType具有相同效果。当attTypeleafType不同时,必须提供可选的compress方法。compress方法负责把待索引的 datum 从attType转换为leafType。注意:两个 consistent 函数都会收到未经改变的scankeys,不会经过compress的转换。 + leafType通常与attType相同。出于向后兼容的考虑,config方法可以不初始化leafType;这与将leafType设为等于attType具有相同效果。当attTypeleafType不同时,必须提供可选的compress方法。compress方法负责把待索引的 datum 从attType转换为leafType。注意:两个一致性检查函数都会收到未经改变的scankeys,不会经过compress的转换。 @@ -233,9 +242,16 @@ typedef struct spgConfigOut 为向内部元组插入新值选择一种方法。 - SQL声明必须如下所示: + + 该函数的 SQL 声明必须如下所示: + CREATE FUNCTION my_choose(internal, internal) RETURNS void ... -第一个参数是一个指向spgChooseInC 结构体的指针,其中包含该函数的输入数据。第二个参数是一个指向spgChooseOutC 结构体的指针,函数必须将结果数据填入其中。 + + 第一个参数是一个指向 spgChooseIn C 结构体的 + 指针,其中包含该函数的输入数据。第二个参数是一个指向 + spgChooseOut C 结构体的指针,函数必须将结果 + 数据填入其中。 + typedef struct spgChooseIn { Datum datum; /* 要被索引的原始 datum */ @@ -243,7 +259,7 @@ typedef struct spgChooseIn int level; /* 当前层级(从零开始计) */ /* 来自当前内部元组的数据 */ - bool allTheSame; /* 元组被标记为 all-the-same? */ + bool allTheSame; /* 元组被标记为全部相同? */ bool hasPrefix; /* 元组有前缀? */ Datum prefixDatum; /* 如果有,前缀值 */ int nNodes; /* 内部元组中的结点数 */ @@ -291,8 +307,27 @@ typedef struct spgChooseOut } spgChooseOut; - datum是要插入索引的原始数据,其类型为spgConfigIn.attTypeleafDatum是一个spgConfigOut.leafType类型的值,其初始值是方法compress应用于datum的结果,前提是提供了方法compress;否则,其值与datum相同。leafDatum可能在树的较低层发生变化,如果choosepicksplit方法对它进行了修改。当插入搜索到达叶页时,leafDatum的当前值将存储到新创建的叶子元组中。level是当前内部元组的层级,根层为零。allTheSame为真,表示当前内部元组被标记为包含多个等价结点(参见)。 - hasPrefix为真时,表示当前内部元组包含前缀;若是如此,prefixDatum就是该前缀值。nNodes是内部元组中包含的子结点数量,而nodeLabels是它们的标签值数组;如果没有标签,则为 NULL。 + datum 是将要插入索引的、类型为 + spgConfigIn.attType + 的原始 datum。leafDatum 是一个类型为 + spgConfigOut.leafType + 的值;如果提供了 compress 方法,它最初是将 + datum 交给 + compress 的结果,否则与 + datum 相同。如果 choose + 或 picksplit 方法修改了它,那么在树的更低层级中 + leafDatum 可能会发生变化。当插入搜索到达 + 叶子页时,leafDatum 的当前值将存储在新创 + 建的叶子元组中。level 是当前内部元组的层 + 级,根层为零。若当前内部元组被标记为包含多个等价结点(参见 + ),则 + allTheSame 为真。若当前内部元组包含前缀, + 则 hasPrefix 为真;若是如此, + prefixDatum 就是该前缀值。 + nNodes 是内部元组中包含的子结点数量, + nodeLabels 是它们的标签值数组;如果没有 + 标签,则为 NULL。 + choose 函数可以判定:新值要么匹配某个现有子结 @@ -361,9 +396,16 @@ typedef struct spgChooseOut 决定如何在一组叶子元组上创建一个新的内部元组。 - SQL声明必须如下所示: + + 该函数的 SQL 声明必须如下所示: + CREATE FUNCTION my_picksplit(internal, internal) RETURNS void ... -第一个参数是一个指向spgPickSplitInC 结构体的指针,其中包含该函数的输入数据。第二个参数是一个指向spgPickSplitOutC 结构体的指针,函数必须将结果数据填入其中。 + + 第一个参数是一个指向 spgPickSplitIn C 结构体的 + 指针,其中包含该函数的输入数据。第二个参数是一个指向 + spgPickSplitOut C 结构体的指针,函数必须将结 + 果数据填入其中。 + typedef struct spgPickSplitIn { int nTuples; /* 叶子元组的数量 */ @@ -384,7 +426,12 @@ typedef struct spgPickSplitOut } spgPickSplitOut; - nTuples是所提供的叶子元组数量。datums是包含这些元组数据值的数组,其中的值属于spgConfigOut.leafType类型。level是所有这些叶子元组当前共同的层级,它将成为新内部元组的层级。 + nTuples 是提供的叶子元组数量。 + datums 是由它们的 datum 值组成的数组,类 + 型为 spgConfigOut.leafType。 + level 是这些叶子元组共享的当前层级,它将 + 成为新内部元组的层级。 + hasPrefix 设为指示新的内部元组是否应 @@ -439,33 +486,33 @@ CREATE FUNCTION my_inner_consistent(internal, internal) RETURNS void ... 第一个参数是一个指向spgInnerConsistentInC 结构体的指针,其中包含该函数的输入数据。第二个参数是一个指向spgInnerConsistentOutC 结构体的指针,函数必须将结果数据填入其中。 typedef struct spgInnerConsistentIn { - ScanKey scankeys; /* array of operators and comparison values */ - int nkeys; /* length of array */ - - Datum reconstructedValue; /* value reconstructed at parent */ - void *traversalValue; /* opclass-specific traverse value */ - MemoryContext traversalMemoryContext; /* put new traverse values here */ - int level; /* current level (counting from zero) */ - bool returnData; /* original data must be returned? */ - - /* Data from current inner tuple */ - bool allTheSame; /* tuple is marked all-the-same? */ - bool hasPrefix; /* tuple has a prefix? */ - Datum prefixDatum; /* if so, the prefix value */ - int nNodes; /* number of nodes in the inner tuple */ - Datum *nodeLabels; /* node label values (NULL if none) */ + ScanKey scankeys; /* 操作符和比较值的数组 */ + int nkeys; /* 数组长度 */ + + Datum reconstructedValue; /* 在父元组处重建的值 */ + void *traversalValue; /* 操作符类特定的遍历值 */ + MemoryContext traversalMemoryContext; /* 将新的遍历值放在这里 */ + int level; /* 当前层级(从零开始计) */ + bool returnData; /* 必须返回原始数据? */ + + /* 来自当前内部元组的数据 */ + bool allTheSame; /* 元组被标记为全部相同? */ + bool hasPrefix; /* 元组有前缀? */ + Datum prefixDatum; /* 如果有,前缀值 */ + int nNodes; /* 内部元组中的结点数 */ + Datum *nodeLabels; /* 结点标签值(如果没有则为 NULL) */ } spgInnerConsistentIn; typedef struct spgInnerConsistentOut { - int nNodes; /* number of child nodes to be visited */ - int *nodeNumbers; /* their indexes in the node array */ - int *levelAdds; /* increment level by this much for each */ - Datum *reconstructedValues; /* associated reconstructed values */ - void **traversalValues; /* opclass-specific traverse values */ + int nNodes; /* 需要访问的子结点数 */ + int *nodeNumbers; /* 它们在结点数组中的索引 */ + int *levelAdds; /* 对每个结点层级增加这么多 */ + Datum *reconstructedValues; /* 关联的重建值 */ + void **traversalValues; /* 操作符类特定的遍历值 */ } spgInnerConsistentOut; -数组scankeys的长度为nkeys,它描述索引搜索条件。这些条件用 AND 组合 — 只有满足全部条件的索引项才是我们关心的。(注意,nkeys= 0 表示所有索引项都满足该查询。)通常 consistent 函数只关心sk_strategysk_argument字段,它们分别给出可索引操作符和比较值。特别地,无需检查sk_flags以判断比较值是否为 NULL,因为 SP-GiST 核心代码会过滤掉此类条件。reconstructedValue是为父元组重建的值;以下情况下它为(Datum) 0:位于根层,或者inner_consistent函数没有在父层提供该值。reconstructedValue始终属于spgConfigOut.leafType类型。traversalValue是指向任意遍历数据的指针,这些数据由上一次调用inner_consistent处理父索引元组时向下传递;在根层时则为 NULL。traversalMemoryContext是存放输出遍历值(见下文)的内存上下文。level是当前内部元组的层级,根层为零。returnDatatrue表示本查询需要重建数据;这要求config函数明确设置了canReturnData。 - allTheSame为真,表示当前内部元组被标记为all-the-same;在这种情况下,所有结点都具有相同的标签(如果有),因此要么全部匹配该查询,要么全部不匹配(参见)。 +数组scankeys的长度为nkeys,它描述索引搜索条件。这些条件用 AND 组合 — 只有满足全部条件的索引项才是我们关心的。(注意,nkeys= 0 表示所有索引项都满足该查询。)通常一致性检查函数只关心每个数组元素的sk_strategysk_argument字段,它们分别给出可索引操作符和比较值。特别地,无需检查sk_flags以判断比较值是否为 NULL,因为 SP-GiST 核心代码会过滤掉此类条件。reconstructedValue是为父元组重建的值;以下情况下它为(Datum) 0:位于根层,或者inner_consistent函数没有在父层提供该值。reconstructedValue始终属于spgConfigOut.leafType类型。traversalValue是指向任意遍历数据的指针,这些数据由上一次调用inner_consistent处理父索引元组时向下传递;在根层时则为 NULL。traversalMemoryContext是存放输出遍历值(见下文)的内存上下文。level是当前内部元组的层级,根层为零。returnDatatrue表示本查询需要重建数据;这要求config函数将canReturnData设为真。 + allTheSame为真,表示当前内部元组被标记为全部相同;在这种情况下,所有结点都具有相同的标签(如果有),因此要么全部匹配该查询,要么全部不匹配(参见)。 hasPrefix为真时,表示当前内部元组包含前缀;若是如此,prefixDatum就是该前缀值。nNodes是内部元组中包含的子结点数量,而nodeLabels是它们的标签值数组;如果结点没有标签,则为 NULL。 @@ -506,23 +553,23 @@ CREATE FUNCTION my_leaf_consistent(internal, internal) RETURNS bool ... 第一个参数是一个指向spgLeafConsistentInC 结构体的指针,其中包含该函数的输入数据。第二个参数是一个指向spgLeafConsistentOutC 结构体的指针,函数必须将结果数据填入其中。 typedef struct spgLeafConsistentIn { - ScanKey scankeys; /* array of operators and comparison values */ - int nkeys; /* length of array */ + ScanKey scankeys; /* 操作符和比较值的数组 */ + int nkeys; /* 数组长度 */ - Datum reconstructedValue; /* value reconstructed at parent */ - void *traversalValue; /* opclass-specific traverse value */ - int level; /* current level (counting from zero) */ - bool returnData; /* original data must be returned? */ + Datum reconstructedValue; /* 在父元组处重建的值 */ + void *traversalValue; /* 操作符类特定的遍历值 */ + int level; /* 当前层级(从零开始计) */ + bool returnData; /* 必须返回原始数据? */ - Datum leafDatum; /* datum in leaf tuple */ + Datum leafDatum; /* 叶子元组中的 datum */ } spgLeafConsistentIn; typedef struct spgLeafConsistentOut { - Datum leafValue; /* reconstructed original data, if any */ - bool recheck; /* set true if operator must be rechecked */ + Datum leafValue; /* 重建出的原始数据(如果有) */ + bool recheck; /* 如果必须重新检查操作符则设为真 */ } spgLeafConsistentOut; -数组scankeys的长度为nkeys,它描述索引搜索条件。这些条件用 AND 组合 — 只有满足全部条件的索引项才满足该查询。(注意,nkeys= 0 表示所有索引项都满足该查询。)通常 consistent 函数只关心sk_strategysk_argument字段,它们分别给出可索引操作符和比较值。特别地,无需检查sk_flags以判断比较值是否为 NULL,因为 SP-GiST 核心代码会过滤掉此类条件。reconstructedValue是为父元组重建的值;以下情况下它为(Datum) 0:位于根层,或者inner_consistent函数没有在父层提供该值。reconstructedValue始终属于spgConfigOut.leafType类型。traversalValue是指向任意遍历数据的指针,这些数据由上一次调用inner_consistent处理父索引元组时向下传递;在根层时则为 NULL。level是当前叶子元组的层级,根层为零。returnDatatrue表示本查询需要重建数据;这要求config函数明确设置了canReturnData。 +数组scankeys的长度为nkeys,它描述索引搜索条件。这些条件用 AND 组合 — 只有满足全部条件的索引项才满足该查询。(注意,nkeys= 0 表示所有索引项都满足该查询。)通常一致性检查函数只关心每个数组元素的sk_strategysk_argument字段,它们分别给出可索引操作符和比较值。特别地,无需检查sk_flags以判断比较值是否为 NULL,因为 SP-GiST 核心代码会过滤掉此类条件。reconstructedValue是为父元组重建的值;以下情况下它为(Datum) 0:位于根层,或者inner_consistent函数没有在父层提供该值。reconstructedValue始终属于spgConfigOut.leafType类型。traversalValue是指向任意遍历数据的指针,这些数据由上一次调用inner_consistent处理父索引元组时向下传递;在根层时则为 NULL。level是当前叶子元组的层级,根层为零。returnDatatrue表示本查询需要重建数据;这要求config函数将canReturnData设为真。 leafDatum是当前叶元组中存储的键值,其类型为spgConfigOut.leafType @@ -569,7 +616,7 @@ typedef struct spgLeafConsistentOut - 如果被索引列属于可应用排序规则的数据类型,则索引排序规则会通过标准的 + 如果被索引列属于支持排序规则的数据类型,则索引排序规则会通过标准的 PG_GET_COLLATION() 机制传递给所有支持方法。 @@ -647,7 +694,7 @@ typedef struct spgLeafConsistentOut - <quote>All-the-same</quote> 内部元组 + <quote>全部相同</quote>的内部元组 picksplit 无法把提供的叶子值划分为至少两个结点 diff --git a/zh/11/spi.sgml b/zh/11/spi.sgml index 64fd0140..15900055 100644 --- a/zh/11/spi.sgml +++ b/zh/11/spi.sgml @@ -76,7 +76,7 @@ int SPI_connect_ext(int options) SPI_connect 会为某次 C 函数调用打开到 SPI 管理器 的连接。如果要通过 SPI 执行命令,就必须调用此函数。不过,有些 SPI - 实用函数可以在未连接的 C 函数中调用。 + 辅助函数可以在未连接的 C 函数中调用。 @@ -119,7 +119,7 @@ int SPI_connect_ext(int options) SPI_ERROR_CONNECT - 出错时 + 发生错误时 @@ -291,11 +291,11 @@ SPI_execute("INSERT INTO foo SELECT * FROM bar RETURNING *", false, 5); typedef struct { - MemoryContext tuptabcxt; /* memory context of result table */ - uint64 alloced; /* number of alloced vals */ - uint64 free; /* number of free vals */ - TupleDesc tupdesc; /* row descriptor */ - HeapTuple *vals; /* rows */ + MemoryContext tuptabcxt; /* 结果表的内存上下文 */ + uint64 alloced; /* 已分配的 vals 数量 */ + uint64 free; /* 空闲的 vals 数量 */ + TupleDesc tupdesc; /* 行描述符 */ + HeapTuple *vals; /* 行 */ } SPITupleTable; vals 是一个指向行的指针数组。(有效项数为 SPI_processed。) @@ -494,7 +494,7 @@ typedef struct SPI_ERROR_UNCONNECTED - 从未连接的 C 函数中调用 + 如果从一个未连接的 C 函数中调用 @@ -507,9 +507,9 @@ typedef struct 所有 SPI 查询执行函数都会设置 SPI_processed 和 - SPI_tuptable(只设置指针,而不会复制结构体内容)。如果 + SPI_tuptable(只设置指针,而不更改结构体内容)。如果 需要在后续调用之后继续访问 SPI_execute 或其他查询 - 执行函数的结果表,请把这两个全局变量保存到本地 C 函数变量中。 + 执行函数的结果表,请把这两个全局变量保存到 C 函数的局部变量中。 @@ -554,7 +554,7 @@ int SPI_exec(const char * command, long count< const char * command - 包含要执行命令的字符串 + 包含待执行命令的字符串 @@ -563,7 +563,7 @@ int SPI_exec(const char * command, long count< long count - 要返回的最大行数,或者用0表示没有限制 + 要返回的最大行数,或者用 0 表示不限制 @@ -625,7 +625,7 @@ int SPI_execute_with_args(const char *command, SPI_execute_plan 达到类似效果。不过,使用本函数 时,查询计划总会针对所提供的具体参数值进行定制。对于一次性查询执行,应 优先选择本函数。如果同一条命令要用许多不同参数重复执行,则两种方式孰快 - 取决于重新计划的代价与定制计划收益之间的权衡。 + 取决于重新规划的代价与定制计划收益之间的权衡。 @@ -680,9 +680,9 @@ int SPI_execute_with_args(const char *command, 如果 nullsNULL,则 - SPI_execute_with_args 会假定没有参数为 NULL。 - 否则,如果对应参数值非 NULL,则 nulls 数组中 - 的对应项应为 ' ';如果对应参数值为 NULL,则 + SPI_execute_with_args 会假定没有参数为空值。 + 否则,如果对应参数值非空值,则 nulls 数组中 + 的对应项应为 ' ';如果对应参数值为空值,则 对应项应为 'n'。(后一种情况下,对应 values 项中的实际值无关紧要。)注意, nulls 不是文本字符串,而只是一个数组,因此不 @@ -736,7 +736,7 @@ int SPI_execute_with_args(const char *command, SPI_prepare - 准备一个语句,但不执行它 + 准备一个语句,但暂不执行 @@ -815,8 +815,7 @@ SPIPlanPtr SPI_prepare(const char * command, int 返回值 - SPI_prepare 返回一个指向非空 SPIPlan - 的指针,它是表示预备语句的不透明结构体。发生错误时会返回 + SPI_prepare 返回一个非空指针,指向表示预备语句的不透明结构体 SPIPlan。发生错误时会返回 NULL,并将 SPI_result 设为 SPI_execute 所使用的那些错误码之一;但如果 commandNULL,或者 @@ -835,17 +834,16 @@ SPIPlanPtr SPI_prepare(const char * command, int SPI_execute_plan 在最初几次使用时会根据提供的参数 值生成定制计划。当同一个预备语句被使用足够多次之后, SPI_execute_plan 会构建一个通用计划;如果它的代价 - 没有比定制计划高出太多,就会开始改用通用计划,而不是每次都重新计划。如 + 没有比定制计划高出太多,就会开始改用通用计划,而不是每次都重新规划。如 果这种默认行为不合适,可以把 CURSOR_OPT_GENERIC_PLANCURSOR_OPT_CUSTOM_PLAN 标志传给 SPI_prepare_cursor,分别强制使用通用计划或定制计划。 - 尽管预备语句的主要目的在于避免重复进行解析分析和计划,但只要语句中使用 + 尽管预备语句的主要目的在于避免重复进行解析分析和规划,但只要语句中使用 的数据库对象自上次使用该预备语句以来发生了定义性(DDL)变更, - PostgreSQL 就会在再次使用前强制重新分析并重 - 新计划该语句。此外,如果 的值在两次 + PostgreSQL 就会在再次使用前强制重新分析并重新规划该语句。此外,如果 的值在两次 使用之间发生变化,该语句也会基于新的 search_path 重 新解析。(后一种行为是从 PostgreSQL 9.3 开 始引入的。)有关预备语句行为的更多信息,请参见 @@ -931,7 +929,7 @@ SPIPlanPtr SPI_prepare_cursor(const char * command, int < Oid * argtypes - 指向数组的指针,该数组包含参数数据类型的 + 一个数组指针,它指向的数组包含参数的数据类型的 OID @@ -1023,7 +1021,7 @@ SPIPlanPtr SPI_prepare_params(const char * command, ParserSetupHook parserSetup - 语法分析器钩子设置函数 + 解析器钩子设置函数 @@ -1238,8 +1236,8 @@ bool SPI_is_cursor_plan(SPIPlanPtr plan) 返回值 - 如果 plan 能产生游标,则返回 - true;如果不能,则返回 false,并将 + 返回 truefalse,表示 + plan 能否产生游标,同时将 SPI_result 设为零。如果无法确定答案(例如 planNULL 或无效,或者在 未连接到 SPI 时调用),则会将 SPI_result 设为合适 @@ -1311,15 +1309,14 @@ int SPI_execute_plan(SPIPlanPtr plan, Datum * - 如果nullsNULL, - 那么SPI_execute_plan会假设没有参数 - 为空值。否则,如果对应的参数值为非空, - nulls - 数组的每一个项都应该是' ';如果对应参数值为空, - 对应项应为'n'(在后 - 面的情况中,对应的values项中的值没有 - 关系)。注意nulls不是一个文本字符串, - 它只是一个数组:它不需要一个'\0'终止符。 + 如果 nullsNULL,则 + SPI_execute_plan 会假定没有参数为空值。 + 否则,如果对应参数值非空值,则 nulls 数组中 + 的对应项应为 ' ';如果对应参数值为空值,则 + 对应项应为 'n'。(后一种情况下,对应 + values 项中的实际值无关紧要。)注意, + nulls 不是文本字符串,而只是一个数组,因此不 + 需要 '\0' 终止符。 @@ -1450,7 +1447,7 @@ int SPI_execute_plan_with_paramlist(SPIPlanPtr plan, long count - 要返回的最大行数,或者用0表示没有限制 + 要返回的最大行数,或者用 0 表示不限制 @@ -1534,15 +1531,14 @@ int SPI_execp(SPIPlanPtr plan, Datum * values< - 如果nullsNULL, - 那么SPI_execp会假设没有参数 - 为空值。否则,如果对应的参数值为非空, - nulls - 数组的每一个项都应该是' ';如果对应参数值为空, - 对应项应为'n'(在后 - 面的情况中,对应的values项中的值没有 - 关系)。注意nulls不是一个文本字符串, - 它只是一个数组:它不需要一个'\0'终止符。 + 如果 nullsNULL,则 + SPI_execp 会假定没有参数为空值。 + 否则,如果对应参数值非空值,则 nulls 数组中 + 的对应项应为 ' ';如果对应参数值为空值,则 + 对应项应为 'n'。(后一种情况下,对应 + values 项中的实际值无关紧要。)注意, + nulls 不是文本字符串,而只是一个数组,因此不 + 需要 '\0' 终止符。 @@ -1551,7 +1547,7 @@ int SPI_execp(SPIPlanPtr plan, Datum * values< long count - 要返回的最大行数,或者用0表示没有限制 + 要返回的最大行数,或者用 0 表示不限制 @@ -1659,15 +1655,14 @@ Portal SPI_cursor_open(const char * name, SPIPlanPtr - 如果nullsNULL, - 那么SPI_cursor_open会假设没有参数 - 为空值。否则,如果对应的参数值为非空, - nulls - 数组的每一个项都应该是' ';如果对应参数值为空, - 对应项应为'n'(在后 - 面的情况中,对应的values项中的值没有 - 关系)。注意nulls不是一个文本字符串, - 它只是一个数组:它不需要一个'\0'终止符。 + 如果 nullsNULL,则 + SPI_cursor_open 会假定没有参数为空值。 + 否则,如果对应参数值非空值,则 nulls 数组中 + 的对应项应为 ' ';如果对应参数值为空值,则 + 对应项应为 'n'。(后一种情况下,对应 + values 项中的实际值无关紧要。)注意, + nulls 不是文本字符串,而只是一个数组,因此不 + 需要 '\0' 终止符。 @@ -1728,11 +1723,10 @@ Portal SPI_cursor_open_with_args(const char *name, - 对于一次性的查询执行,这个函数应该比 - SPI_prepare_cursor加上其后的 - SPI_cursor_open更好。如果相同的命令 - 要被用很多不同的参数执行,哪种方法更快就要取决于重做计划的 - 代价与定制计划带来的好处之间谁更有利。 + 对于一次性查询执行,应优先使用此函数,而不是先调用 + SPI_prepare_cursor 再调用 + SPI_cursor_open。如果同一条命令要用许多不同参数执行, + 哪种方法更快取决于重新规划的代价与定制计划收益之间的权衡。 @@ -1776,8 +1770,8 @@ Portal SPI_cursor_open_with_args(const char *name, Oid * argtypes - 一个长度为nargs的数组, - 包含参数的数据类型的OID + 一个长度为 nargs 的数组,包含参数数据类型的 + OID @@ -1786,8 +1780,7 @@ Portal SPI_cursor_open_with_args(const char *name, Datum * values - 一个长度为nargs的数组, - 包含实际的参数值 + 一个长度为 nargs 的数组,包含实际参数值 @@ -1796,20 +1789,19 @@ Portal SPI_cursor_open_with_args(const char *name, const char * nulls - 一个长度为nargs的数组, - 描述哪些参数为空值 + 一个长度为 nargs 的数组,用于描述哪些参数为 + 空值 - 如果nullsNULL, - 那么SPI_cursor_open_with_args会假设没有参数 - 为空值。否则,如果对应的参数值为非空, - nulls - 数组的每一个项都应该是' ';如果对应参数值为空, - 对应项应为'n'(在后 - 面的情况中,对应的values项中的值没有 - 关系)。注意nulls不是一个文本字符串, - 它只是一个数组:它不需要一个'\0'终止符。 + 如果 nullsNULL,则 + SPI_cursor_open_with_args 会假定没有参数为空值。 + 否则,如果对应参数值非空值,则 nulls 数组中 + 的对应项应为 ' ';如果对应参数值为空值,则 + 对应项应为 'n'。(后一种情况下,对应 + values 项中的实际值无关紧要。)注意, + nulls 不是文本字符串,而只是一个数组,因此不 + 需要 '\0' 终止符。 @@ -2079,7 +2071,7 @@ void SPI_cursor_fetch(Portal portal, bool forw 如果该游标的计划不是用CURSOR_OPT_SCROLL - 选项创建的,向后获取会失败。 + 选项创建的,向后获取可能失败。 @@ -2153,7 +2145,7 @@ void SPI_cursor_move(Portal portal, bool forwa 如果该游标的计划不是用CURSOR_OPT_SCROLL - 选项创建的,向后移动会失败。 + 选项创建的,向后移动可能失败。 @@ -2249,8 +2241,7 @@ void SPI_scroll_cursor_fetch(Portal portal, FetchDirectio 如果该游标的计划不是用CURSOR_OPT_SCROLL - 选项创建的,除FETCH_FORWARD之外的方向值会 - 失败。 + 选项创建的,除FETCH_FORWARD之外的方向值可能失败。 @@ -2347,8 +2338,7 @@ void SPI_scroll_cursor_move(Portal portal, FetchDirection 如果该游标的计划不是用CURSOR_OPT_SCROLL - 选项创建的,除FETCH_FORWARD之外的方向值会 - 失败。 + 选项创建的,除FETCH_FORWARD之外的方向值可能失败。 @@ -2523,7 +2513,8 @@ SPIPlanPtr SPI_saveplan(SPIPlanPtr plan) 返回值 - 返回指向复制后的语句的指针;如果失败,则返回 NULL。出错时,SPI_result 设置如下: + 复制后语句的指针;如果未成功则返回NULL。 + 错误时,SPI_result会被这样设置: @@ -2569,8 +2560,8 @@ SPIPlanPtr SPI_saveplan(SPIPlanPtr plan) SPI_register_relation - ephemeral named relation - registering with SPI + 临时命名关系 + 向 SPI 注册 @@ -2594,7 +2585,7 @@ int SPI_register_relation(EphemeralNamedRelation enr) SPI_register_relation 使一个带有相关信息的临时命名关 - 系对通过当前 SPI 连接计划和执行的查询可用。 + 系对通过当前 SPI 连接规划和执行的查询可用。 @@ -2674,8 +2665,8 @@ int SPI_register_relation(EphemeralNamedRelation enr) SPI_unregister_relation - ephemeral named relation - unregistering from SPI + 临时命名关系 + 从 SPI 注销 @@ -2722,7 +2713,7 @@ int SPI_unregister_relation(const char * name) 返回值 - 如果该命令的执行成功,则会返回下列(非负)值: + 如果该命令的执行成功,则将返回下列(非负)值: @@ -2777,13 +2768,13 @@ int SPI_unregister_relation(const char * name) SPI_register_trigger_data - ephemeral named relation - registering with SPI + 临时命名关系 + 向 SPI 注册 - transition tables - implementation in PLs + 过渡表 + 在 PL 中实现 @@ -2807,8 +2798,8 @@ int SPI_register_trigger_data(TriggerData *tdata) SPI_register_trigger_data 使触发器捕获的所有临时关系 - 都能在通过当前 SPI 连接计划和执行的查询中使用。目前,这指的是通过 - REFERENCING OLD/NEW TABLE AS ... 子句定义、并由 + 都能在通过当前 SPI 连接规划和执行的查询中使用。目前,这指的是由带有 + REFERENCING OLD/NEW TABLE AS ... 子句的 AFTER 触发器捕获的过渡表。PL 触发器处理函数应在建 立 SPI 连接后调用此函数。 @@ -2834,7 +2825,7 @@ int SPI_register_trigger_data(TriggerData *tdata) 返回值 - 如果命令的执行成功,则会返回下列(非负)值: + 如果该命令的执行成功,则将返回下列(非负)值: @@ -3106,7 +3097,7 @@ char * SPI_getvalue(HeapTuple row, TupleDesc r 返回值 - 列值;如果该列为 NULL、colnumber 超出范围 + 列值;如果该列为空值、colnumber 超出范围 (SPI_result 被设置为 SPI_ERROR_NOATTRIBUTE)或者没有输出函数 可用(SPI_result 被设置为 @@ -3198,8 +3189,8 @@ Datum SPI_getbinval(HeapTuple row, TupleDesc r 返回值 - 返回该列的二进制值。如果该列为 NULL,则 - isnull 指向的变量会被设为 true,否则设为 false。 + 返回该列的二进制值。如果该列为空值,则 + isnull 指向的变量会被设为真,否则设为假。 @@ -3235,7 +3226,7 @@ char * SPI_gettype(TupleDesc rowdesc, int coln SPI_gettype返回该指定列的数据类型名称 - 的拷贝(当你不再需要该拷贝后,可以使用pfree + 的副本(当你不再需要该副本后,可以使用pfree 释放它)。 @@ -3367,7 +3358,7 @@ char * SPI_getrelname(Relation rel) SPI_getrelname返回该指定关系的名称 - 的拷贝(当你不再需要该拷贝后,可以使用pfree + 的副本(当你不再需要该副本后,可以使用pfree 释放它)。 @@ -3460,7 +3451,7 @@ char * SPI_getnspname(Relation rel) SPI_result_code_string - 将结果代码表示为字符串 + 返回错误码的字符串表示 @@ -3474,7 +3465,7 @@ const char * SPI_result_code_string(int code); SPI_result_code_string 返回各种 SPI 函数返回的,或 - 存放在 SPI_result 中的结果代码的字符串表示。 + 存放在 SPI_result 中的结果码的字符串表示。 @@ -3486,7 +3477,7 @@ const char * SPI_result_code_string(int code); int code - 结果代码 + 结果码 @@ -3497,7 +3488,7 @@ const char * SPI_result_code_string(int code); 返回值 - 结果代码的字符串表示。 + 结果码的字符串表示。 @@ -3509,8 +3500,8 @@ const char * SPI_result_code_string(int code); - memory context - in SPI + 内存上下文 + 在 SPI 中 PostgreSQL内存上下文 中分配内存。内存上下文为管理那些在许多不同位置创建、且生命周期各不相同 @@ -3535,7 +3526,7 @@ const char * SPI_result_code_string(int code); 办法是用 SPI_palloc 为返回对象分配内存。 SPI_palloc上层执行器上下文中分配 内存,也就是调用 SPI_connect 时的当前内存上下文; - 这正是从 C 函数返回值最合适的上下文。本节介绍的其他几个实用函数同样会返 + 这正是从 C 函数返回值最合适的上下文。本节介绍的其他几个辅助函数同样会返 回在上层执行器上下文中创建的对象。 @@ -3543,7 +3534,7 @@ const char * SPI_result_code_string(int code); 调用 SPI_connect 时,会把该 C 函数的私有上下文 (由 SPI_connect 创建)设为当前上下文。所有通过 pallocrepalloc 或 SPI - 实用函数分配的内存(本节另有说明的除外)都位于这个上下文中。当 C 函数通 + 辅助函数分配的内存(本节另有说明的除外)都位于这个上下文中。当 C 函数通 过 SPI_finish 与 SPI 管理器断开连接时,当前上下文 会恢复为上层执行器上下文,而在该 C 函数内存上下文中分配的所有内存都会被 释放,之后就不能再使用。 @@ -3738,7 +3729,7 @@ void SPI_pfree(void * pointer) SPI_copytuple - 在上层执行器上下文中创建一行的拷贝 + 在上层执行器上下文中创建一行的副本 @@ -3771,7 +3762,7 @@ HeapTuple SPI_copytuple(HeapTuple row) HeapTuple row - 要拷贝的行 + 要复制的行 @@ -3782,7 +3773,7 @@ HeapTuple SPI_copytuple(HeapTuple row) 返回值 - 拷贝后的行;出错时返回 NULL + 复制后的行;出错时返回 NULL (错误指示见 SPI_result @@ -3838,7 +3829,7 @@ HeapTupleHeader SPI_returntuple(HeapTuple row, TupleDesc HeapTuple row - 要拷贝的行 + 要复制的行 @@ -3847,7 +3838,7 @@ HeapTupleHeader SPI_returntuple(HeapTuple row, TupleDesc TupleDesc rowdesc - 行描述符(若要获得最佳缓存效果,大多数情况下应每次都传入同一个描述符) + 行描述符(若要获得最佳缓存效果,每次都传入同一个描述符) @@ -3858,7 +3849,7 @@ HeapTupleHeader SPI_returntuple(HeapTuple row, TupleDesc 返回值 - 指向拷贝后行的 HeapTupleHeader;出错时返回 + 指向复制后行的 HeapTupleHeader;出错时返回 NULL(错误指示见 SPI_result @@ -3960,13 +3951,14 @@ HeapTuple SPI_modifytuple(Relation rel, HeapTuple - 如果nullsNULL,那么 - SPI_modifytuple假定没有新值为空值。否则, - 如果对应的新值为非空,nulls数组的每一项都应 - 该是' ',而如果对应的新值为空值则为'n'(在 - 后一种情况中,对应的values项中的新值无关紧 - 要)。注意nulls不是一个文本字符串,只是一个 - 数组:它不需要一个'\0'终止符。 + 如果 nullsNULL,则 + SPI_modifytuple 会假定没有新值为空值。 + 否则,如果对应新值非空值,则 nulls 数组中 + 的对应项应为 ' ';如果对应新值为空值,则 + 对应项应为 'n'。(后一种情况下,对应 + values 项中的实际值无关紧要。)注意, + nulls 不是文本字符串,而只是一个数组,因此不 + 需要 '\0' 终止符。 @@ -4045,7 +4037,7 @@ void SPI_freetuple(HeapTuple row) SPI_freetuple释放之前在上层执行器上下文中 - 分配的一个行。 + 分配的一行。 @@ -4320,7 +4312,7 @@ void SPI_start_transaction(void) - 数据改变的可见性 + 数据更改的可见性 下列规则决定了使用 SPI 的函数(以及其他任何 C 函数)中数据更改的可见 @@ -4400,7 +4392,7 @@ execq(PG_FUNCTION_ARGS) int ret; uint64 proc; - /* Convert given text object to a C string */ + /* 把给定的文本对象转换成一个 C 字符串 */ command = text_to_cstring(PG_GETARG_TEXT_PP(0)); cnt = PG_GETARG_INT32(1); @@ -4411,7 +4403,7 @@ execq(PG_FUNCTION_ARGS) proc = SPI_processed; /* - * If some rows were fetched, print them via elog(INFO). + * 如果取出了一些行,通过 elog(INFO) 打印它们。 */ if (ret > 0 && SPI_tuptable != NULL) { @@ -4452,7 +4444,8 @@ CREATE FUNCTION execq(text, integer) RETURNS int8 - 以下是一个示例会话: + 下面是一个示例会话: + => SELECT execq('CREATE TABLE a (x integer)', 0); execq diff --git a/zh/11/stylesheet-speedup-common.xsl b/zh/11/stylesheet-speedup-common.xsl index e3fb582a..403f350c 100644 --- a/zh/11/stylesheet-speedup-common.xsl +++ b/zh/11/stylesheet-speedup-common.xsl @@ -95,6 +95,6 @@ -en +zh_cn diff --git a/zh/11/syntax.sgml b/zh/11/syntax.sgml index 93137ebf..612e8c25 100644 --- a/zh/11/syntax.sgml +++ b/zh/11/syntax.sgml @@ -21,7 +21,7 @@ 词法结构 - token + 词元 @@ -29,7 +29,7 @@ - 一个词元可以是关键词标识符带引号的标识符文字值(或常量),或者特殊字符符号。词元通常由空白(空格、制表符、换行)分隔,但如果不存在歧义,则不必如此(一般只有特殊字符与其他类型的词元相邻时才会这样)。 + 一个词元可以是关键词标识符带引号的标识符字面量(或常量),或者特殊字符符号。词元通常由空白(空格、制表符、换行)分隔,但如果不存在歧义,则不必如此(一般只有特殊字符与其他类型的词元相邻时才会这样)。 @@ -58,18 +58,18 @@ INSERT INTO MY_TABLE VALUES (3, 'hi there'); 标识符和关键词 - identifier - syntax of + 标识符 + 语法 - name - syntax of + 名称 + 语法 - key word - syntax of + 关键词 + 语法 @@ -83,7 +83,7 @@ INSERT INTO MY_TABLE VALUES (3, 'hi there'); - identifierlength + 标识符长度 系统对标识符最多只使用 NAMEDATALEN-1 个字节;在命令中可以写更长的名称,但它们会被截断。默认情况下, NAMEDATALEN 为 64,因此标识符的最大长度是 63 字节。如果这个限制有问题,可以通过修改 src/include/pg_config_manual.h 中的 NAMEDATALEN 常量来提高。 @@ -91,8 +91,8 @@ INSERT INTO MY_TABLE VALUES (3, 'hi there'); - case sensitivity - of SQL commands + 大小写敏感性 + SQL 命令 关键词和未加引号的标识符不区分大小写。因此: @@ -110,8 +110,8 @@ UPDATE my_table SET a = 5; - quotation marks - and identifiers + 引号 + 与标识符 还有第二类标识符:定界标识符带引号的标识符。它通过把任意字符序列括在双引号中形成(")。 定界标识符始终是标识符,绝不会是关键词。因此,"select" 可以用来引用名为 select 的列或表,而不加引号的 select 会被视为关键词,因此在期望表名或列名的位置使用时会导致解析错误。这个示例可以用带引号的标识符写成: @@ -125,7 +125,7 @@ UPDATE "my_table" SET "a" = 5; Unicode 转义 - in identifiers + 在标识符中 @@ -165,7 +165,7 @@ U&"d!0061t!+000061" UESCAPE '!' 常量 - constant + 常量 @@ -176,8 +176,8 @@ U&"d!0061t!+000061" UESCAPE '!' 字符串常量 - character string - constant + 字符串 + 常量 @@ -288,7 +288,7 @@ SELECT 'foo' 'bar'; - 如果配置参数off,那么PostgreSQL对常规字符串常量和转义字符串常量中的反斜线转义都识别。不过,从PostgreSQL 9.1 开始,该参数的默认值为on,意味着只在转义字符串常量中识别反斜线转义。这种行为更兼容标准,但是可能打断依赖于历史行为(反斜线转义总是会被识别)的应用。作为一种变通,你可以设置该参数为off,但是最好迁移到符合新的行为。如果你需要使用一个反斜线转义来表示一个特殊字符,为该字符串常量写上一个E。 + 如果配置参数off,那么PostgreSQL对常规字符串常量和转义字符串常量中的反斜线转义都识别。不过,从PostgreSQL 9.1 开始,该参数的默认值为on,意味着只在转义字符串常量中识别反斜线转义。这种行为更兼容标准,但是可能使依赖历史行为(始终识别反斜线转义)的应用无法正常工作。作为一种变通,你可以设置该参数为off,但最好修改应用,不再使用反斜线转义。如果你需要使用一个反斜线转义来表示一个特殊字符,为该字符串常量写上一个E @@ -306,7 +306,7 @@ SELECT 'foo' 'bar'; Unicode 转义 - in string constants + 在字符串常量中 @@ -346,13 +346,18 @@ U&'d!0061t!+000061' UESCAPE '!' 美元引用的字符串常量 - dollar quoting + 美元引用 - 指定字符串常量的标准语法通常很方便,但当所需字符串包含许多单引号时,就可能难以理解,因为每个单引号都必须写两遍。为了让这类情况下的查询更易读,PostgreSQL提供了另一种编写字符串常量的方法,称为美元引用。美元引用的字符串常量由一个美元符号($)、一个由零个或多个字符组成的可选标签、另一个美元符号、构成字符串内容的任意字符序列、一个美元符号、与该美元引用开头相同的标签,以及一个美元符号组成。例如,对于字符串 Dianne's horse,下面是使用美元引用指定它的两种不同方法: + + 虽然指定字符串常量的标准语法通常很方便,但当目标字符串中包含很多单引号时,就会变得难以阅读,因为每个单引号都必须写成两个。为了在这种情况下让查询更易读, + PostgreSQL 提供了另一种编写字符串常量的方式,称为美元引用(dollar quoting)。一个美元引用字符串常量由美元符号($)、一个由零个或多个字符组成的可选标签、另一个美元符号、组成字符串内容的任意字符序列、一个美元符号、开始该美元引用时使用的同一个标签以及最后一个美元符号组成。例如,下面是使用美元引用指定字符串 Dianne's horse 的两种不同写法: + $$Dianne's horse$$ $SomeTag$Dianne's horse$SomeTag$ -注意,在美元引用的字符串中,单引号不需要转义就可以使用。事实上,美元引用字符串内的任何字符都不会被转义:字符串内容始终按字面书写。反斜线没有特殊含义,美元符号也没有,除非它是与开头标签相匹配的序列的一部分。 + + 注意,在美元引用字符串内部,单引号可以直接使用而无须转义。事实上,美元引用字符串内部的任何字符都不会被转义:字符串内容总是按字面方式书写。反斜线不是特殊字符,美元符号也不是,除非它们构成了与开头标签匹配的序列。 + 可以通过在每个嵌套层级选择不同的标签,来嵌套美元引用字符串常量。这种做法最常见于编写函数定义时。例如: @@ -384,8 +389,8 @@ $function$ 位串常量 - bit string - constant + 位串 + 常量 @@ -405,18 +410,28 @@ $function$ 数字常量 - number - constant + 数字 + 常量 - 数字常量接受下列一般形式: + + 数字常量接受下列一般形式: + digits digits.digitse+-digits digits.digitse+-digits digitse+-digits -其中 digits 是一个或多个十进制数字(0 到 9)。若使用小数点,则小数点前后至少有一侧必须有数字。若使用指数标记(e),其后至少必须有一位数字。常量中不能嵌入空格或其他字符。注意,开头的正号或负号实际上不被视为常量的一部分,而是作用于常量的操作符。 + + 其中 digits 是一个或多个十进制数字(0 到 9)。 + 若使用小数点,则小数点前后至少有一侧必须有数字。若使用指数标记 + (e),其后至少必须有一位数字。常量中不能嵌入空格或 + 其他字符。请注意,前导正号或负号 + 实际上不属于常量本身,而是作用于常量的操作符。 + - 下面是一些有效数字常量的示例: + + 这些是合法数字常量的示例: + 42 3.5 4. @@ -434,12 +449,12 @@ $function$ - 为数字常量最初指定的数据类型,只是类型解析算法的起点。在大多数情况下,常量会根据上下文被自动强制转换成最合适的类型。必要时,你可以通过类型转换强制把一个数值解释为特定的数据类型。type cast + 为数字常量最初指定的数据类型,只是类型解析算法的起点。在大多数情况下,常量会根据上下文被自动强制转换成最合适的类型。必要时,你可以通过类型转换强制把一个数值解释为特定的数据类型。类型转换 例如,可以通过下面的写法强制把一个数值当作类型 realfloat4)处理: -REAL '1.23' -- string style -1.23::REAL -- PostgreSQL (historical) style +REAL '1.23' -- 字符串形式 +1.23::REAL -- PostgreSQL(历史)形式 这些实际上只是下面将要讨论的一般类型转换记法的特例。 @@ -450,8 +465,8 @@ REAL '1.23' -- string style 其他类型的常量 - data type - constant + 数据类型 + 常量 @@ -477,7 +492,7 @@ CAST ( 'string' AS type ) - 如中所述,::CAST() 以及函数调用语法也可以用来指定任意表达式的运行时类型转换。为避免语法歧义,type 'string' 语法只能用来指定简单字面常量的类型。该语法的另一个限制是不能用于数组类型;要指定数组常量的类型,请使用 ::CAST()。 + 如中所述,::CAST() 以及函数调用语法也可以用来指定任意表达式的运行时类型转换。为避免语法歧义,type 'string' 语法只能用来指定简单字面常量的类型。type 'string' 语法的另一个限制是不能用于数组类型;要指定数组常量的类型,请使用 ::CAST() @@ -490,8 +505,8 @@ CAST ( 'string' AS type ) 操作符 - operator - syntax + 操作符 + 语法 @@ -541,7 +556,7 @@ CAST ( 'string' AS type ) - 圆括号(())具有它们通常的含义,用来分组表达式并且强制优先。在某些情况中,圆括号被要求作为一个特定 SQL 命令的固定语法的一部分。 + 圆括号(())具有它们通常的含义,用来对表达式分组并确定运算优先级。在某些情况中,圆括号被要求作为一个特定 SQL 命令的固定语法的一部分。 @@ -559,7 +574,7 @@ CAST ( 'string' AS type ) - 分号(;)结束一个 SQL 命令。它不能出现在一个命令中间的任何位置,除了在一个字符串常量中或者一个被引用的标识符中。 + 分号(;)结束一个 SQL 命令。它不能出现在一个命令中间的任何位置,除了在一个字符串常量中或者一个带引号的标识符中。 @@ -571,7 +586,7 @@ CAST ( 'string' AS type ) - 星号(*)在某些上下文中用来表示表行或组合值的所有字段。当它被用作聚合函数的参数时,还有一种特殊含义,即该聚合不需要任何显式参数。 + 星号(*)在某些上下文中用来表示表行或复合值的所有字段。当它被用作聚合函数的参数时,还有一种特殊含义,即该聚合不需要任何显式参数。 @@ -589,22 +604,22 @@ CAST ( 'string' AS type ) 注释 - comment - in SQL + 注释 + 在 SQL 中 注释是一串以双连字符开始并延伸到行尾的字符,例如: --- This is a standard SQL comment +-- 这是一条标准 SQL 注释 另外,也可以使用 C 风格注释块: -/* multiline comment - * with nesting: /* nested block comment */ +/* 多行注释 + * 包含嵌套:/* 嵌套块注释 */ */ 这里该注释开始于/*并且延伸到匹配出现的*/。这些注释块可按照 SQL 标准中指定的方式嵌套,但和 C 中不同。这样我们可以注释掉一大段可能包含注释块的代码。 @@ -619,8 +634,8 @@ CAST ( 'string' AS type ) 操作符优先级 - operator - precedence + 操作符 + 优先级 展示了 PostgreSQL 中操作符的优先级和结合性。大多数操作符具有相同的优先级,并且是左结合的。操作符的优先级和结合性是固定写在解析器中的。 @@ -667,19 +682,19 @@ SELECT (5 !) - 6; + - - 一元加、一元减 + 一元正号、一元负号 ^ - 指数 + 求幂 * / % - 乘、除、模 + 乘、除、取模 @@ -691,7 +706,7 @@ SELECT (5 !) - 6; (任意其他操作符) - 所有其他本地以及用户定义的操作符 + 所有其他内置以及用户定义的操作符 @@ -1377,7 +1392,7 @@ SELECT * FROM tbl WHERE a COLLATE "C" > 'foo'; SELECT * FROM tbl WHERE (a > 'foo') COLLATE "C"; - 因为它尝试把一个排序规则应用到>操作符的结果,而它的数据类型是非可排序数据类型boolean。 + 因为它尝试把一个排序规则应用到>操作符的结果,而它的数据类型是不支持排序规则的数据类型boolean diff --git a/zh/11/textsearch.sgml b/zh/11/textsearch.sgml index ddcc608a..af545bdb 100644 --- a/zh/11/textsearch.sgml +++ b/zh/11/textsearch.sgml @@ -1961,7 +1961,7 @@ ALTER TEXT SEARCH CONFIGURATION russian 分类词典示例 - 考虑简单的天文词库 thesaurus_astro,其中包含一些天文单词组合: + 考虑简单的天文词库 thesaurus_astro,其中包含一些天文单词组合: supernovae stars : sn @@ -2396,7 +2396,7 @@ ts_debug( config re - 以下是一个简单的示例: + 以下是一个简单的示例: SELECT * FROM ts_debug('english', 'a fat cat sat on a mat - it ate a fat rats'); diff --git a/zh/11/trigger.sgml b/zh/11/trigger.sgml index adda6403..34b4e2a8 100644 --- a/zh/11/trigger.sgml +++ b/zh/11/trigger.sgml @@ -4,7 +4,7 @@ 触发器 - trigger + 触发器 @@ -127,7 +127,7 @@ - 如果在同一关系上的同一事件为其定义了多个触发器,它们会按触发器名称的字母顺序触发。对于 BEFOREINSTEAD OF + 如果为同一关系上的同一事件定义了多个触发器,它们会按触发器名称的字母顺序触发。对于 BEFOREINSTEAD OF 触发器,每个触发器返回的、可能已经被修改过的行都会成为下一个触发器的输入。如果任何一个 BEFOREINSTEAD OF 触发器返回 NULL,则会放弃对该行执行该操作,并且后续触发器(针对该行)都不会再触发。 @@ -156,8 +156,8 @@ - trigger - arguments for trigger functions + 触发器 + 触发器函数的参数 在定义触发器时,可以为它指定参数。在触发器定义中包含参数,是为了让需求相似的不同触发器能够调用同一个函数。举例来说,可以有一个通用触发器函数,它接受两个列名作为参数,把当前用户写入其中一个列,把当前时间戳写入另一个列。只要编写得当,这个触发器函数就应独立于它所作用的具体表。因此,同一个函数可用于任何具有适当列的表上的 INSERT 事件,例如自动跟踪某个事务表中记录的创建。如果把它定义成 UPDATE 触发器,还可以用来跟踪最近更新事件。 @@ -183,7 +183,10 @@ 数据更改的可见性 - 如果你在触发器函数中执行 SQL 命令,而且这些命令访问的是该触发器所在的表,那么就需要了解数据可见性规则,因为这些规则决定了这些 SQL 命令能否看到导致该触发器触发的数据更改。简要来说: + + 如果你在触发器函数中执行 SQL 命令,而这些命令又访问该触发器所属的表,就需要了解数据可见性规则,因为这些规则决定了这些 SQL 命令是否能看到引发触发器的数据更改。简而言之: + + @@ -237,13 +240,13 @@ 用 C 编写触发器函数 - trigger - in C + 触发器 + 在 C 中 - transition tables - referencing from C trigger + 过渡表 + 从 C 触发器中引用 @@ -255,7 +258,7 @@ - 当函数由触发器管理器调用时,不会向它传递任何普通参数,但会传递一个指向 TriggerData 结构体的 context 指针。C 函数可以通过执行下列宏来检查自己是否由触发器管理器调用: + 当函数由触发器管理器调用时,不会向它传递任何普通参数,但会传递一个指向 TriggerData 结构体的 上下文 指针。C 函数可以通过执行下列宏来检查自己是否由触发器管理器调用: CALLED_AS_TRIGGER(fcinfo) @@ -300,14 +303,15 @@ typedef struct TriggerData tg_event - 描述调用该函数所对应的事件。可以使用下列宏来检查tg_event: + + 描述调用函数的事件。可以使用以下宏检查 tg_event TRIGGER_FIRED_BEFORE(tg_event) - 如果触发器在操作之前触发,则返回 true。 + 如果触发器在操作之前触发,则返回真。 @@ -316,7 +320,7 @@ typedef struct TriggerData TRIGGER_FIRED_AFTER(tg_event) - 如果触发器在操作之后触发,则返回 true。 + 如果触发器在操作之后触发,则返回真。 @@ -325,7 +329,7 @@ typedef struct TriggerData TRIGGER_FIRED_INSTEAD(tg_event) - 如果触发器是取代该操作而触发,则返回 true。 + 如果触发器是取代该操作而触发,则返回真。 @@ -334,7 +338,7 @@ typedef struct TriggerData TRIGGER_FIRED_FOR_ROW(tg_event) - 如果触发器是因行级事件触发,则返回 true。 + 如果触发器是因行级事件触发,则返回真。 @@ -343,7 +347,7 @@ typedef struct TriggerData TRIGGER_FIRED_FOR_STATEMENT(tg_event) - 如果触发器是因语句级事件触发,则返回 true。 + 如果触发器是因语句级事件触发,则返回真。 @@ -352,7 +356,7 @@ typedef struct TriggerData TRIGGER_FIRED_BY_INSERT(tg_event) - 如果触发器是由 INSERT 命令触发,则返回 true。 + 如果触发器是由 INSERT 命令触发,则返回真。 @@ -361,7 +365,7 @@ typedef struct TriggerData TRIGGER_FIRED_BY_UPDATE(tg_event) - 如果触发器是由 UPDATE 命令触发,则返回 true。 + 如果触发器是由 UPDATE 命令触发,则返回真。 @@ -370,7 +374,7 @@ typedef struct TriggerData TRIGGER_FIRED_BY_DELETE(tg_event) - 如果触发器是由 DELETE 命令触发,则返回 true。 + 如果触发器是由 DELETE 命令触发,则返回真。 @@ -379,7 +383,7 @@ typedef struct TriggerData TRIGGER_FIRED_BY_TRUNCATE(tg_event) - 如果触发器是由 TRUNCATE 命令触发,则返回 true。 + 如果触发器是由 TRUNCATE 命令触发,则返回真。 @@ -505,16 +509,16 @@ typedef struct Trigger - 一个完整的触发器实例 + 一个完整的触发器示例 这里给出一个非常简单的、用 C 编写的触发器函数示例。(用过程语言编写的触发器示例可见各过程语言的文档。) - 如果某条命令试图向列 x 中插入空值,函数 - trigf 就会报告表 ttest - 中的行数,并跳过实际操作。(这样,这个触发器就起到了非空约束的作用,但不会中止事务。) + 函数 trigf 会报告表 ttest 中的行数, + 并在命令试图向列 x 中插入空值时跳过实际操作。 + (这样,这个触发器就起到了非空约束的作用,但不会中止事务。) @@ -526,7 +530,9 @@ CREATE TABLE ttest ( - 这是触发器函数的源代码: + 下面是触发器函数的源代码: + - 编译完源代码后(参见),声明函数和触发器: + + 编译完这段源代码之后(见 ),声明该函数和这些触发器: + CREATE FUNCTION trigf() RETURNS trigger AS 'filename' LANGUAGE C; diff --git a/zh/11/typeconv.sgml b/zh/11/typeconv.sgml index ce3d5cb7..ab6407d4 100644 --- a/zh/11/typeconv.sgml +++ b/zh/11/typeconv.sgml @@ -28,7 +28,7 @@ -PostgreSQL扫描器/解析器将词法元素分成五个基本类别:整数、非整数数字、字符串、标识符和关键字。大多数非数值类型的常量会先被归类为字符串。SQL语言定义允许用字符串指定类型名,而PostgreSQL可以利用这一机制让解析器从一开始就沿着正确的路径处理。例如,查询: +PostgreSQL扫描器/解析器将词法元素分成五个基本类别:整数、非整数数字、字符串、标识符和关键字。大多数非数值类型的常量会先被归类为字符串。SQL语言定义允许给字符串指定类型名,而PostgreSQL可以利用这一机制让解析器从一开始就沿着正确的路径处理。例如,查询: SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; @@ -39,11 +39,11 @@ SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; (1 row) -包含两个文字常量,它们的类型分别是textpoint。如果没有为某个字符串文字指定类型,那么它最初会被赋予占位类型unknown,并在后文所述的后续阶段解析。 +包含两个字面量,它们的类型分别是textpoint。如果没有为某个字符串字面量指定类型,那么它最初会被赋予占位类型unknown,并在后文所述的后续阶段解析。 -有四种基本的 SQL 结构需要在 PostgreSQL 解析器中使用不同的类型转换规则: +在PostgreSQL解析器中,有四种基本的SQL结构需要采用不同的类型转换规则: @@ -82,7 +82,7 @@ SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; -由于经合并的SELECT语句的所有查询结果都必须出现在同一组列中,因此每个SELECT子句的结果类型必须彼此匹配,并转换为统一的一组类型。类似地,CASE结构中的结果表达式必须转换为某种公共类型,这样整个CASE表达式才有确定的输出类型。其他一些结构,如ARRAY[]以及GREATESTLEAST函数,也同样需要为若干子表达式确定公共类型。 +由于经UNION合并的SELECT语句的所有查询结果都必须出现在同一组列中,因此每个SELECT子句的结果类型必须彼此匹配,并转换为统一的一组类型。类似地,CASE结构中的结果表达式必须转换为某种公共类型,这样整个CASE表达式才有确定的输出类型。其他一些结构,如ARRAY[]以及GREATESTLEAST函数,也同样需要为若干子表达式确定公共类型。 @@ -161,11 +161,11 @@ SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; -检查是否存在一个恰好接受输入参数类型的操作符。如果存在(在被考虑的操作符集合中至多只有一个精确匹配),就使用它。若通过限定名调用(这种情况并不常见)某个允许不可信用户创建对象的模式中的操作符,而又缺少精确匹配,就会带来安全隐患 +检查是否存在一个恰好接受输入参数类型的操作符。如果存在(在被考虑的操作符集合中至多只有一个精确匹配),就使用它。若通过限定名调用(这种情况并不常见)某个允许不受信任的用户创建对象的模式中的操作符,而又缺少精确匹配,就会带来安全隐患 - 对于未带模式限定的名称,不会出现这种隐患,因为包含允许不可信用户创建对象的模式的搜索路径不是一种模式的安全使用方式。 + 对于未带模式限定的名称,不会出现这种隐患,因为包含允许不受信任的用户创建对象的模式的搜索路径不是一种模式的安全使用方式。 。在这种情况下,应通过对参数进行类型转换来强制获得精确匹配。 @@ -180,7 +180,7 @@ SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; -如果二元操作符调用的一个参数是unknown类型,而另一个是域类型,则接着检查是否存在两边都恰好接受该域基类型的操作符;如果有,就使用它。 +如果二元操作符调用的一个参数是unknown类型,而另一个是域类型,则接着检查是否存在两边都恰好接受该域基础类型的操作符;如果有,就使用它。 @@ -194,13 +194,13 @@ SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; -丢弃那些输入类型不匹配,且也无法通过隐式类型转换实现匹配的候选操作符。为此,假定unknown文字可以转换为任何类型。如果只剩一个候选操作符,就使用它;否则继续下一步。 +丢弃那些输入类型不匹配,且也无法通过隐式类型转换实现匹配的候选操作符。为此,假定unknown字面量可以转换为任何类型。如果只剩一个候选操作符,就使用它;否则继续下一步。 -如果任何输入参数是域类型,则在后续所有步骤中都把它当作该域的基类型。这样可以确保在解决操作符歧义时,域的行为与其基类型一致。 +如果任何输入参数是域类型,则在后续所有步骤中都把它当作该域的基础类型。这样可以确保在解决操作符歧义时,域的行为与其基础类型一致。 @@ -212,12 +212,12 @@ SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; -遍历所有候选操作符,保留那些在需要类型转换的最多位置上接受首选类型(属于输入数据类型的类型分类)的候选项。如果没有候选项接受首选类型,则保留全部候选项。如果只剩一个候选操作符,就使用它;否则继续下一步。 +遍历所有候选操作符,在需要类型转换的位置上,保留接受首选类型(属于输入数据类型的类型分类)的位置数最多的候选项。如果没有候选项接受首选类型,则保留全部候选项。如果只剩一个候选操作符,就使用它;否则继续下一步。 -如果有任何输入参数是unknown,就检查剩余候选项在这些参数位置上接受哪些类型分类。在每个位置上,如果有任何候选项接受string分类,就选择该分类。(这种偏向字符串的做法是合适的,因为unknown类型的文字看起来像字符串。)否则,如果所有剩余候选项都接受同一种类型分类,就选择该分类;否则失败,因为在缺少更多线索的情况下无法推断出正确选择。然后丢弃不接受所选类型分类的候选项。此外,如果有任何候选项接受该分类中的首选类型,就丢弃在该参数上接受非首选类型的候选项。如果没有候选项通过这些测试,则保留全部候选项。如果只剩一个候选项,就使用它;否则继续下一步。 +如果有任何输入参数是unknown,就检查剩余候选操作符在这些参数位置上接受哪些类型分类。在每个位置上,如果有任何候选项接受string分类,就选择该分类。(这种偏向字符串的做法是合适的,因为unknown类型的字面量看起来像字符串。)否则,如果所有剩余候选项都接受同一种类型分类,就选择该分类;否则失败,因为在缺少更多线索的情况下无法推断出正确选择。然后丢弃不接受所选类型分类的候选项。此外,如果有任何候选项接受该分类中的首选类型,就丢弃在该参数上接受非首选类型的候选项。如果没有候选项通过这些测试,则保留全部候选项。如果只剩一个候选操作符,就使用它;否则继续下一步。 @@ -265,7 +265,7 @@ SELECT CAST(40 AS bigint) ! AS "40 factorial"; -一个只有一个未指定参数的例子: +一个参数未指定类型的例子: SELECT text 'abc' || 'def' AS "text and unknown"; @@ -293,7 +293,7 @@ SELECT 'abc' || 'def' AS "unspecified"; -这里对使用哪种类型没有初始提示,因为查询中没有指定任何类型。因此,解析器会查找所有候选操作符,并发现既有接受字符串分类输入的候选项,也有接受位串分类输入的候选项。由于在可用时优先选择字符串分类,所以会选中该分类,再使用字符串的首选类型text作为解析这些unknown类型文字的具体类型。 +这里对使用哪种类型没有初始提示,因为查询中没有指定任何类型。因此,解析器会查找所有候选操作符,并发现既有接受字符串分类输入的候选项,也有接受位串分类输入的候选项。由于在可用时优先选择字符串分类,所以会选中该分类,再使用字符串的首选类型text作为解析这些unknown类型字面量的具体类型。 @@ -301,7 +301,7 @@ SELECT 'abc' || 'def' AS "unspecified"; 绝对值与取反操作符类型解析 -在 PostgreSQL 操作符目录中,前缀操作符 @ 有多个条目,分别实现各种数值数据类型的绝对值运算。其中一个条目用于类型 float8,它是数值分类中的首选类型。因此,PostgreSQL 会使用该条目来处理 unknown 输入: +PostgreSQL操作符目录中为前缀操作符@提供了多个条目,它们分别实现各种数值数据类型的绝对值操作。其中一个条目对应float8,它是数值分类中的首选类型。因此,当遇到一个unknown输入时,PostgreSQL会使用该条目: SELECT @ '-4.5' AS "abs"; abs @@ -309,7 +309,7 @@ SELECT @ '-4.5' AS "abs"; 4.5 (1 row) -这里,系统在应用所选操作符之前,已将 unknown 类型文字隐式解析为 float8 类型。我们可以验证所使用的是 float8 而不是其他类型: +这里,系统在应用所选操作符之前,已经把unknown类型字面量隐式解析为float8。我们可以验证使用的确实是float8,而不是其他类型: SELECT @ '-4.5e500' AS "abs"; @@ -351,8 +351,7 @@ SELECT array[1,2] <@ '{1,2,3}' as "is subset"; t (1 row) -在 PostgreSQL 操作符目录中,中缀操作符 <@ 有多个条目,但可能接受左侧为整数数组的只有两个:数组包含(anyarray <@ anyarray)和范围包含(anyelement <@ anyrange)。由于这些多态伪类型(见 )都不是首选类型,解析器无法据此消除歧义。不过, 要求它假定 unknown 类型文字与另一个输入的类型相同,即整数数组。这样,两个操作符中只有一个能够匹配,因此会选择数组包含。(如果选择了范围包含,就会得到错误,因为该字符串的格式不符合范围文字的要求。) +PostgreSQL操作符目录中为中缀操作符<@定义了多个条目,但左侧能够接受整数数组的只有两种:数组包含(anyarray <@ anyarray)和范围包含(anyelement <@ anyrange)。由于这些多态伪类型(见)都不被视为首选类型,解析器无法据此消除歧义。不过,要求它假定unknown类型字面量与另一输入具有相同类型,也就是整数数组。这样两个操作符中只有一个能够匹配,因此会选择数组包含。(如果选中范围包含,就会报错,因为该字符串的格式并不是合法的范围字面量。) @@ -361,7 +360,7 @@ linkend="datatype-pseudo"/>)都不是首选类型,解析器无法据此消 域类型上的自定义操作符 -用户有时会尝试声明只适用于某个域类型的操作符。这是可行的,但远没有看上去那样有用,因为操作符解析规则被设计成优先选择作用于域基类型的操作符。考虑下面的例子: +用户有时会尝试声明只适用于某个域类型的操作符。这是可行的,但远没有看上去那样有用,因为操作符解析规则被设计成优先选择作用于域基础类型的操作符。考虑下面的例子: CREATE DOMAIN mytext AS text CHECK(...); CREATE FUNCTION mytext_eq_text (mytext, text) RETURNS boolean AS ...; @@ -370,11 +369,11 @@ CREATE TABLE mytable (val mytext); SELECT * FROM mytable WHERE val = 'foo'; -这个查询不会使用自定义操作符。解析器首先会检查是否存在mytext = mytext操作符(),但并不存在;然后它会考虑该域的基类型text,并检查是否存在text = text操作符(),而这是存在的;于是它会把unknown类型的文字解析为text,并使用text = text操作符。要让自定义操作符被使用,唯一的方法是显式地对该文字做类型转换: +这个查询不会使用自定义操作符。解析器首先会检查是否存在mytext = mytext操作符(),但并不存在;然后它会考虑该域的基础类型text,并检查是否存在text = text操作符(),而这是存在的;于是它会把unknown类型的字面量解析为text,并使用text = text操作符。要让自定义操作符被使用,唯一的方法是显式地对该字面量做类型转换: SELECT * FROM mytable WHERE val = text 'foo'; -这样就会根据精确匹配规则立即找到mytext = text操作符。如果解析过程进入最佳匹配规则,它们会主动排斥作用于域类型的操作符。如果不是这样,这类操作符会导致过多的操作符歧义失败,因为类型转换规则总是把域视为可以转换到其基类型或从其基类型转换而来,因此域操作符会在所有与基类型上同名操作符相同的场景中都被视为可用。 +这样就会根据精确匹配规则立即找到mytext = text操作符。如果解析过程进入最佳匹配规则,它们会主动排斥作用于域类型的操作符。如果不是这样,这类操作符会导致过多的操作符歧义失败,因为类型转换规则总是把域视为可以转换到其基础类型或从其基础类型转换而来,因此域操作符会在所有与基础类型上同名操作符相同的场景中都被视为可用。 @@ -409,26 +408,26 @@ SELECT * FROM mytable WHERE val = text 'foo'; -如果函数声明了一个VARIADIC数组参数,而调用时没有使用VARIADIC关键字,则把该函数视为其数组参数按需要被其元素类型的一个或多个出现所替换,以匹配该调用。扩展之后,该函数的有效参数类型可能与某个非可变参数函数完全相同。在这种情况下,使用搜索路径中较早出现的函数;如果两个函数位于同一模式,则优先选择非可变参数函数。 +如果函数声明了一个VARIADIC数组参数,而调用时没有使用VARIADIC关键字,则把数组参数视为一个或多个其元素类型的参数,个数按匹配该调用的需要确定。扩展之后,该函数的有效参数类型可能与某个非VARIADIC函数完全相同。在这种情况下,使用搜索路径中较早出现的函数;如果两个函数位于同一模式,则优先选择非VARIADIC函数。 -通过限定名调用某个允许不可信用户创建对象的模式中找到的可变参数函数时,会带来安全隐患 +通过限定名调用某个允许不受信任的用户创建对象的模式中找到的可变参数函数时,会带来安全隐患 - 对于未带模式限定的名称,不会出现这种隐患,因为包含允许不可信用户创建对象的模式的搜索路径不是一种模式的安全使用方式。 + 对于未带模式限定的名称,不会出现这种隐患,因为包含允许不受信任的用户创建对象的模式的搜索路径不是一种模式的安全使用方式。 - 。恶意用户可以借此劫持调用,并以你的身份执行任意 SQL 函数。改为使用带有VARIADIC关键字的调用可以绕过这一隐患。对于填充VARIADIC "any"参数的调用,往往没有包含VARIADIC关键字的等价写法。要安全地发出这类调用,该函数所在模式必须只允许可信用户创建对象。 + 。恶意用户可以借此劫持调用,并以你的身份执行任意 SQL 函数。改为使用带有VARIADIC关键字的调用可以绕过这一隐患。对于填充VARIADIC "any"参数的调用,往往没有包含VARIADIC关键字的等价写法。要安全地发出这类调用,该函数所在模式必须只允许受信任的用户创建对象。 -带有参数默认值的函数,被认为可以匹配任何省略了零个或多个可默认参数位置的调用。如果不止一个这样的函数能匹配某个调用,则使用搜索路径中最早出现的那一个。如果同一模式中存在两个或更多这样的函数,并且它们在未使用默认值的参数位置上的参数类型相同(如果它们具有不同的可默认参数集合,这种情况是可能的),系统就无法判断该偏好哪一个;如果找不到更好的匹配,就会报有歧义的函数调用错误。 +带有参数默认值的函数,被认为可以匹配任何省略了零个或多个可使用默认值的参数位置的调用。如果不止一个这样的函数能匹配某个调用,则使用搜索路径中最早出现的那一个。如果同一模式中存在两个或更多这样的函数,并且它们在未使用默认值的参数位置上的参数类型相同(如果它们具有不同的带有默认值的参数集合,这种情况是可能的),系统就无法判断该偏好哪一个;如果找不到更好的匹配,就会报有歧义的函数调用错误。 -通过限定名调用某个允许不可信用户创建对象的模式中的任意函数时,会带来可用性隐患。恶意用户可以用现有函数的名字创建一个新函数,复制该函数的参数,并附加带有默认值的新参数。这样就会阻止对原始函数的新调用。为避免这种隐患,应把函数放在只允许可信用户创建对象的模式中。 +通过限定名调用某个允许不受信任的用户创建对象的模式中的任意函数时,会带来可用性隐患。恶意用户可以用现有函数的名字创建一个新函数,复制该函数的参数,并附加带有默认值的新参数。这样就会阻止对原始函数的新调用。为避免这种隐患,应把函数放在只允许受信任的用户创建对象的模式中。 @@ -437,13 +436,13 @@ SELECT * FROM mytable WHERE val = text 'foo'; -检查是否存在一个恰好接受输入参数类型的函数。如果存在(在被考虑的函数集合中至多只有一个精确匹配),就使用它。若通过限定名调用某个允许不可信用户创建对象的模式中的函数,而又缺少精确匹配,就会带来安全隐患。在这种情况下,应通过对参数进行类型转换来强制获得精确匹配。(涉及unknown的情况在这一步永远找不到匹配。) +检查是否存在一个恰好接受输入参数类型的函数。如果存在(在被考虑的函数集合中至多只有一个精确匹配),就使用它。若通过限定名调用某个允许不受信任的用户创建对象的模式中的函数,而又缺少精确匹配,就会带来安全隐患。在这种情况下,应通过对参数进行类型转换来强制获得精确匹配。(涉及unknown的情况在这一步永远找不到匹配。) -如果没有找到精确匹配,就检查该函数调用是否看起来像一种特殊的类型转换请求。这种情况发生在:函数调用只有一个参数,且函数名与某个数据类型的(内部)名称相同。此外,函数参数必须是unknown类型文字,或者是一种到该命名数据类型二进制可强制转换的类型,或者是一种可以通过应用其 I/O 函数转换为该命名数据类型的类型(也就是说,该转换要么转到某种标准字符串类型,要么从某种标准字符串类型转来)。满足这些条件时,该函数调用会被当作一种CAST形式。 +如果没有找到精确匹配,就检查该函数调用是否看起来像一种特殊的类型转换请求。这种情况发生在:函数调用只有一个参数,且函数名与某个数据类型的(内部)名称相同。此外,函数参数必须是unknown类型字面量,或者是一种可以二进制强制转换为该命名数据类型的类型,或者是一种可以通过应用其 I/O 函数转换为该命名数据类型的类型(也就是说,该转换要么转到某种标准字符串类型,要么从某种标准字符串类型转来)。满足这些条件时,该函数调用会被当作一种CAST形式。 之所以有这一步,是为了在不存在实际类型转换函数的情况下仍支持函数风格的类型转换写法。如果存在类型转换函数,按惯例它会以其输出类型命名,因此无需为此设置特殊情况。更多说明见。 @@ -459,13 +458,13 @@ SELECT * FROM mytable WHERE val = text 'foo'; -丢弃那些输入类型不匹配,且也无法通过隐式类型转换实现匹配的候选函数。为此,假定unknown文字可以转换为任何类型。如果只剩一个候选函数,就使用它;否则继续下一步。 +丢弃那些输入类型不匹配,且也无法通过隐式类型转换实现匹配的候选函数。为此,假定unknown字面量可以转换为任何类型。如果只剩一个候选函数,就使用它;否则继续下一步。 -如果任何输入参数是域类型,则在后续所有步骤中都把它当作该域的基类型。这样可以确保在解决函数歧义时,域的行为与其基类型一致。 +如果任何输入参数是域类型,则在后续所有步骤中都把它当作该域的基础类型。这样可以确保在解决函数歧义时,域的行为与其基础类型一致。 @@ -477,12 +476,12 @@ SELECT * FROM mytable WHERE val = text 'foo'; -遍历所有候选函数,保留那些在需要类型转换的最多位置上接受首选类型(属于输入数据类型的类型分类)的候选项。如果没有候选项接受首选类型,则保留全部候选项。如果只剩一个候选函数,就使用它;否则继续下一步。 +遍历所有候选函数,在需要类型转换的位置上,保留接受首选类型(属于输入数据类型的类型分类)的位置数最多的候选项。如果没有候选项接受首选类型,则保留全部候选项。如果只剩一个候选函数,就使用它;否则继续下一步。 -如果有任何输入参数是unknown,就检查剩余候选项在这些参数位置上接受哪些类型分类。在每个位置上,如果有任何候选项接受string分类,就选择该分类。(这种偏向字符串的做法是合适的,因为unknown类型的文字看起来像字符串。)否则,如果所有剩余候选项都接受同一种类型分类,就选择该分类;否则失败,因为在缺少更多线索的情况下无法推断出正确选择。然后丢弃不接受所选类型分类的候选项。此外,如果有任何候选项接受该分类中的首选类型,就丢弃在该参数上接受非首选类型的候选项。如果没有候选项通过这些测试,则保留全部候选项。如果只剩一个候选项,就使用它;否则继续下一步。 +如果有任何输入参数是unknown,就检查剩余候选函数在这些参数位置上接受哪些类型分类。在每个位置上,如果有任何候选项接受string分类,就选择该分类。(这种偏向字符串的做法是合适的,因为unknown类型的字面量看起来像字符串。)否则,如果所有剩余候选项都接受同一种类型分类,就选择该分类;否则失败,因为在缺少更多线索的情况下无法推断出正确选择。然后丢弃不接受所选类型分类的候选项。此外,如果有任何候选项接受该分类中的首选类型,就丢弃在该参数上接受非首选类型的候选项。如果没有候选项通过这些测试,则保留全部候选项。如果只剩一个候选函数,就使用它;否则继续下一步。 @@ -539,7 +538,7 @@ CREATE FUNCTION public.variadic_example(VARIADIC numeric[]) RETURNS int CREATE FUNCTION -此函数接受 VARIADIC 关键字,但不要求使用它。它可以接受 integer 和 numeric 参数: +这个函数接受但不要求使用VARIADIC关键字。它既能接受integer参数,也能接受numeric参数: SELECT public.variadic_example(0), @@ -551,7 +550,7 @@ SELECT public.variadic_example(0), (1 row) -不过,如果有更具体的函数,前两个调用会优先选择它们: +但是,如果有更具体的函数可用,第一和第二个调用会优先选择它们: CREATE FUNCTION public.variadic_example(numeric) RETURNS int @@ -571,7 +570,7 @@ SELECT public.variadic_example(0), (1 row) -在默认配置下,如果只存在第一个函数,前两个调用是不安全的。任何用户都可以通过创建第二个或第三个函数来截获它们。由于精确匹配参数类型并使用了 VARIADIC 关键字,第三个调用是安全的。 +在默认配置下,且只存在第一个函数时,第一和第二个调用并不安全。任何用户都可以通过创建第二个或第三个函数来劫持它们。第三个调用由于参数类型精确匹配且使用了VARIADIC关键字,因此是安全的。 @@ -659,7 +658,7 @@ SELECT substr(CAST (1234 AS text), 3); -否则,尝试把表达式转换为目标类型。如果这两种类型之间在pg_cast目录中登记了赋值类型转换(见),就可以这样做。另一种情况是,如果表达式是unknown类型文字,则会把文字字符串的内容送入目标类型的输入转换例程。 +否则,尝试把表达式转换为目标类型。如果这两种类型之间在pg_cast目录中登记了赋值类型转换(见),就可以这样做。另一种情况是,如果表达式是unknown类型字面量,则会把字符串字面量的内容送入目标类型的输入转换例程。 @@ -691,7 +690,7 @@ SELECT v, octet_length(v) FROM vv; -这里实际发生的是,两个unknown类型文字默认都被解析为text,从而使||操作符被解析为text的连接操作。然后,操作符得到的text结果被转换为bpcharblank-padded char,即character数据类型的内部名称),以匹配目标列类型。(由于从textbpchar的转换是二进制可强制转换的,这一步不会插入任何真实的函数调用。)最后,系统目录中找到尺寸调整函数bpchar(bpchar, integer, boolean),并把它应用到操作符结果以及存储列长度上。这个特定于类型的函数会执行所需的长度检查并补齐填充空格。 +这里实际发生的是,两个unknown类型字面量默认都被解析为text,从而使||操作符被解析为text的连接操作。然后,操作符得到的text结果被转换为bpchar用空格填充的字符,blank-padded char,即character数据类型的内部名称),以匹配目标列类型。(由于从textbpchar的转换是二进制可强制转换的,这一步不会插入任何真实的函数调用。)最后,系统从系统目录中找到尺寸调整函数bpchar(bpchar, integer, boolean),并把它应用到操作符结果以及存储列长度上。这个特定于类型的函数会执行所需的长度检查并补齐填充空格。 @@ -746,10 +745,10 @@ SQL 的UNION结构必须让可能不同的类型彼此匹配 -如果任何输入是域类型,则在后续所有步骤中都把它当作该域的基类型。 +如果任何输入是域类型,则在后续所有步骤中都把它当作该域的基础类型。 - 这在某种程度上类似于操作符和函数对域输入的处理方式;只要用户确保所有输入都隐式或显式地正好属于该域类型,这种行为就能让域类型在UNION或类似结构中得以保留。否则,就会使用该域的基类型。 + 这在某种程度上类似于操作符和函数对域输入的处理方式;只要用户确保所有输入都隐式或显式地正好属于该域类型,这种行为就能让域类型在UNION或类似结构中得以保留。否则,就会使用该域的基础类型。 @@ -764,13 +763,13 @@ SQL 的UNION结构必须让可能不同的类型彼此匹配 -如果非unknown输入并非全都属于同一类型分类,则失败。 +如果非unknown输入并非全都属于同一类型分类,则失败。 -选择第一个非unknown输入的类型作为候选类型,然后按从左到右的顺序考虑其余每个非unknown输入类型。 +选择第一个非unknown输入的类型作为候选类型,然后按从左到右的顺序考虑其余每个非unknown输入类型。 出于历史原因,CASE会把其ELSE子句(如果有)视为第一个输入,THEN子句则在其后考虑。其他所有情况中,从左到右都指表达式在查询文本中出现的顺序。 @@ -793,7 +792,7 @@ SQL 的UNION结构必须让可能不同的类型彼此匹配 -UNION 中未充分指定类型时的类型解析 +<literal>UNION</literal> 中未充分指定类型时的类型解析 @@ -805,12 +804,12 @@ SELECT text 'a' AS "text" UNION SELECT 'b'; b (2 rows) -这里,unknown 类型文字 'b' 将被解析为类型 text。 +这里,unknown类型字面量'b'会被解析为text类型。 -简单 UNION 中的类型解析 +简单 <literal>UNION</literal> 中的类型解析 @@ -822,12 +821,12 @@ SELECT 1.2 AS "numeric" UNION SELECT 1; 1.2 (2 rows) -文字常量1.2的类型是numeric,而integer1可以隐式转换为numeric,因此使用该类型。 +字面量1.2的类型是numeric,而integer1可以隐式转换为numeric,因此使用该类型。 -次序对调的 UNION 中的类型解析 +次序对调的 <literal>UNION</literal> 中的类型解析 @@ -839,12 +838,12 @@ SELECT 1 AS "real" UNION SELECT CAST('2.2' AS REAL); 2.2 (2 rows) -这里,由于类型 real 不能隐式转换为 integer,但 integer 可以隐式转换为 real,因此合并结果类型被解析为 real。 +这里,由于real类型不能隐式转换为integer,而integer可以隐式转换为real,因此UNION结果类型被解析为real -嵌套 UNION 中的类型解析 +嵌套 <literal>UNION</literal> 中的类型解析 @@ -874,17 +873,17 @@ ERROR: UNION types text and integer cannot be matched -前面各节给出的规则会为 SQL 查询中的所有表达式赋予非 unknown 数据类型,但作为 SELECT 命令的简单输出列出现的未指定类型文字除外。例如,在 +前面各节给出的规则会为 SQL 查询中的所有表达式赋予非 unknown 数据类型,但作为 SELECT 命令的简单输出列出现的未指定类型字面量除外。例如,在 SELECT 'Hello World'; -中,没有任何信息可用于确定应将该字符串文字视为什么类型。在这种情况下,PostgreSQL 会回退为将该文字的类型解析为 text。 +中,没有任何信息可用于确定应将该字符串字面量视为什么类型。在这种情况下,PostgreSQL 会回退为将该字面量的类型解析为 text -当SELECTUNION(或INTERSECTEXCEPT)结构的一端,或者出现在INSERT ... SELECT中时,这条规则不适用,因为前面各节给出的规则具有更高优先级。在前一种情况下,未指定类型文字的类型可以从UNION的另一侧取得;在后一种情况下,则从目标列取得。 +当SELECTUNION(或INTERSECTEXCEPT)结构的一端,或者出现在INSERT ... SELECT中时,这条规则不适用,因为前面各节给出的规则具有更高优先级。在前一种情况下,未指定类型字面量的类型可以从UNION的另一侧取得;在后一种情况下,则从目标列取得。 @@ -894,7 +893,7 @@ SELECT 'Hello World'; - 在PostgreSQL 10 之前,这条规则并不存在,SELECT输出列表中的未指定类型文字会被保留为unknown类型。这会带来各种不良后果,因此后来做了修改。 + 在PostgreSQL 10 之前,这条规则并不存在,SELECT输出列表中的未指定类型字面量会被保留为unknown类型。这会带来各种不良后果,因此后来做了修改。 diff --git a/zh/11/user-manag.sgml b/zh/11/user-manag.sgml index 42abc036..e430f14b 100644 --- a/zh/11/user-manag.sgml +++ b/zh/11/user-manag.sgml @@ -71,7 +71,7 @@ SELECT rolname FROM pg_roles; - 为了完成数据库系统的初始引导,一个刚初始化的系统总会包含一个预定义的可登录角色。该角色总是一个超级用户,并且除非另行指定了不同名称,否则它的名称与用initdb初始化数据库集簇的操作系统用户相同。这个角色通常命名为postgres。要创建更多角色,必须先以这个初始角色建立连接。 + 为了完成数据库系统的初始引导,一个刚初始化的系统总会包含一个预定义角色。该角色总是一个超级用户,并且除非另行指定了不同名称,否则它的名称与用initdb初始化数据库集簇的操作系统用户相同。这个角色通常命名为postgres。要创建更多角色,必须先以这个初始角色建立连接。 @@ -94,12 +94,12 @@ SELECT rolname FROM pg_roles; 登录权限登录权限 - 只有具有 LOGIN 属性的角色才能用作数据库连接的初始角色名。具有 LOGIN 属性的角色可以视为数据库用户。要创建具有登录权限的角色,可以使用以下任一命令: + 只有具有LOGIN属性的角色才能用作数据库连接的初始角色名。具有LOGIN属性的角色可以被视为数据库用户。要创建具有登录权限的角色,可使用以下任一方式: CREATE ROLE name LOGIN; CREATE USER name; - (CREATE USER 等价于 CREATE ROLE,区别在于 CREATE USER 包含 LOGIN,而 CREATE ROLE 不会如此。) + (CREATE USER等价于CREATE ROLE,不同之处只在于CREATE USER默认包含LOGIN,而CREATE ROLE不包含。) @@ -196,13 +196,12 @@ CREATE USER name; - 角色还可以为 中描述的许多运行时配置设置指定角色专属的默认值。例如,如果出于某种原因,你希望每次连接时都禁用索引扫描(提示:这不是一个好主意),可以使用: + 角色还可以为中描述的许多运行时配置设置指定角色特定默认值。例如,如果出于某种原因你希望每次连接时都禁用索引扫描(提示:这不是个好主意),你可以使用: ALTER ROLE myname SET enable_indexscan TO off; - 这会保存该设置(但不会立即设置它)。此角色后续建立的连接就好像在会话开始前刚执行过 SET enable_indexscan TO off 一样。在会话期间仍然可以更改这一设置;它只是默认值。要移除角色专属的默认设置,请使用 - ALTER ROLE rolename RESET varname。请注意,附加在没有 LOGIN 权限的角色上的角色专属默认值几乎没有用处,因为它们永远不会被调用。 + 这会保存该设置(但不会立即生效)。在该角色后续建立的连接中,它看起来就像在会话开始之前执行了SET enable_indexscan TO off一样。你仍然可以在会话期间更改该设置;它只会作为默认值。要移除角色特定默认设置,使用ALTER ROLE rolename RESET varname。注意,附加到没有LOGIN权限的角色上的角色特定默认值几乎没有用,因为它们永远不会生效。 @@ -309,12 +308,12 @@ ALTER TABLE bobs_table OWNER TO alice; - 一旦有价值的对象都已转移给新拥有者,被删除角色所拥有的其余对象即可使用命令删除。同样,由于该命令不能访问其他数据库中的对象,因此必须在包含该角色所拥有对象的每个数据库中运行它。另外,DROP + 一旦有价值的对象都已转移给新拥有者,待删除角色所拥有的其余对象即可使用命令删除。同样,由于该命令不能访问其他数据库中的对象,因此必须在包含该角色所拥有对象的每个数据库中运行它。另外,DROP OWNED不会删除整个数据库或表空间,因此如果该角色拥有任何尚未转移给新拥有者的数据库或表空间,就必须手工删除它们。 - DROP OWNED还会负责移除授予目标角色、但不属于它自身对象的任何权限。由于REASSIGN OWNED不会处理这类对象,所以通常需要同时运行REASSIGN OWNEDDROP OWNED(按这个顺序!),才能完整移除待删除角色的依赖关系。 + DROP OWNED还会负责移除目标角色在其他角色所拥有的对象上获授的所有权限。由于REASSIGN OWNED不会处理这类对象,所以通常需要同时运行REASSIGN OWNEDDROP OWNED(按这个顺序!),才能完整移除待删除角色的依赖关系。 @@ -367,7 +366,7 @@ DROP ROLE doomed_role; pg_read_all_stats - 读取所有 pg_stat_* 视图,并使用各种与统计信息相关的扩展,即使是那些通常仅对超级用户可见的扩展。 + 读取所有 pg_stat_* 视图,并使用各种与统计信息相关的扩展,包括通常仅对超级用户可见的内容。 pg_stat_scan_tables @@ -406,11 +405,11 @@ DROP ROLE doomed_role; - pg_read_server_filespg_write_server_filespg_execute_server_program角色旨在让管理员能够创建受信任但非超级用户的角色,使其能够以数据库运行所用用户的身份访问文件并在数据库服务器上运行程序。由于这些角色能够访问服务器文件系统上的任意文件,它们在直接访问文件时会绕过所有数据库级权限检查,并且可被用来获得超级用户级别的访问能力,因此向用户授予这些角色时必须极其谨慎。 + pg_read_server_filespg_write_server_filespg_execute_server_program角色旨在让管理员能够使受信任但非超级用户的角色能够以数据库运行所用用户的身份访问文件并在数据库服务器上运行程序。由于这些角色能够访问服务器文件系统上的任意文件,它们在直接访问文件时会绕过所有数据库级权限检查,并且可被用来获得超级用户级别的访问能力,因此向用户授予这些角色时必须极其谨慎。 - 授予这些角色时应当谨慎,确保它们只在需要时使用,并理解这些角色会授予对特权信息的访问。 + 授予这些角色时应当谨慎,确保它们只在需要时使用,并理解这些角色会授予对需要特权才能访问的信息的访问。 @@ -427,7 +426,7 @@ GRANT pg_signal_backend TO admin_user; 函数安全性 - 函数、触发器和行级安全策略允许用户把代码插入后端服务器,而其他用户可能会无意中执行这些代码。因此,这些机制使用户能够相对容易地对其他用户实施特洛伊木马攻击。最强的保护方式是严格控制谁能定义对象。如果这不可行,则应编写只引用拥有者可信对象的查询,并从search_path中移除任何允许不受信任用户创建对象的模式。 + 函数、触发器和行级安全策略允许用户把代码插入后端服务器,而其他用户可能会无意中执行这些代码。因此,这些机制使用户能够相对容易地对其他用户实施特洛伊木马攻击。最强的保护方式是严格控制谁能定义对象。如果这不可行,则应编写只引用拥有者可信的对象的查询,并从search_path中移除 public 模式以及任何其他允许不受信任用户创建对象的模式。 diff --git a/zh/11/vacuumlo.sgml b/zh/11/vacuumlo.sgml index a01a7954..46cd2152 100644 --- a/zh/11/vacuumlo.sgml +++ b/zh/11/vacuumlo.sgml @@ -8,7 +8,7 @@ vacuumlo 1 - Application + 应用程序 diff --git a/zh/11/wal.sgml b/zh/11/wal.sgml index b4efd998..39e7e419 100644 --- a/zh/11/wal.sgml +++ b/zh/11/wal.sgml @@ -349,9 +349,9 @@ 检查点检查点 是事务序列中的一些点,在这些点上可以保证堆和索引数据文件已经用检查点之前写入 - 的全部信息进行了更新。执行检查点时,所有脏数据页都会刷写到磁盘,并向 WAL - 文件写入一条特殊的检查点记录。(更改记录此前已经刷入 WAL - 文件。)如果发生崩溃,崩溃恢复过程会查看最新的检查点记录,以确定应该从 WAL + 的全部信息进行了更新。执行检查点时,所有脏数据页都会刷盘,并向 WAL + 文件写入一条特殊的检查点记录。(更改记录此前已写入 WAL + 文件并刷盘。)如果发生崩溃,崩溃恢复过程会查看最新的检查点记录,以确定应该从 WAL 的哪个位置(称为重做记录)开始执行 REDO。该点之前对数据文件所做的任何更改 都保证已经在磁盘上。因此,检查点之后,位于包含重做记录的段之前的 WAL 段不再需要, 可以被回收或删除。(若正在执行 WAL 归档,则这些 WAL 段必 @@ -379,7 +379,7 @@ 减小 checkpoint_timeout 和/或 max_wal_size 会让检查点更频繁地发生。这样可以加快崩溃后 - 恢复,因为需要重做的工作更少。不过,这必须与更频繁刷写脏数据页所增加的成本 + 恢复,因为需要重做的工作更少。不过,这必须与更频繁地将脏数据页刷盘所增加的成本 权衡。如果设置了 (默认就是如此), 还要考虑另一个因素。为了保证数据页一致性,每个检查点之后对某个数据页的首次 修改,都会导致把整页内容写入日志。在这种情况下,更短的检查点间隔会增加输出到 @@ -417,7 +417,7 @@ 在 Linux 和 POSIX 平台上, - 允许在检查点写出的操作系统页面达到可配置的字节数后,强制把它们刷到磁盘。 + 允许在检查点写出的操作系统页面达到可配置的字节数后,强制将它们刷盘。 否则,这些页面可能会停留在操作系统页缓存中,从而在检查点末尾发出 fsync 时引发停顿。这个设置通常有助于降低事务延迟,但也可能 对性能产生不利影响,尤其是在工作负载大于 @@ -453,7 +453,7 @@ 在归档恢复或备库模式下,服务器会周期性地执行 重启点重启点, - 其行为类似于正常运行时的检查点:服务器会强制把自身状态写盘,更新 + 其行为类似于正常运行时的检查点:服务器会强制将其所有状态刷盘,更新 pg_control 文件,以表明已经处理过的 WAL 数据无需再次 扫描,然后回收 pg_wal 目录中的旧 WAL 段文件。重启点的 执行频率不会高于主库上的检查点,因为重启点只能在检查点记录处执行。当到达某条检查点记录且距离上次重启点 @@ -476,7 +476,7 @@ 快。更糟的是,写 WAL 缓冲区还可能迫使系统创建新的 WAL 段, 这会花费更多时间。正常情况下,WAL 缓冲区应由 XLogFlush 请求负责写出并刷盘; - 该请求大多发生在事务提交时,以确保事务记录被刷入持久存储。在 WAL 输出量很高 + 该请求大多发生在事务提交时,以确保事务记录已刷盘至持久存储。在 WAL 输出量很高 的系统上,XLogFlush 请求可能不够频繁,无法避免 XLogInsertRecord 自己去执行写出。在这种系统上,应增加 WAL 缓冲区的数量,具体做法是修改参数 @@ -532,9 +532,9 @@ 参数 决定 PostgreSQL 将如何请求内核把 - WAL 更新强制刷到磁盘。就可靠性而言,所有选项应当都是相同 + WAL 更新强制刷盘。就可靠性而言,所有选项应当都是相同 的;例外是 fsync_writethrough,它有时能够在其他选项做不 - 到时强制刷新磁盘缓存。不过,具体哪个选项速度最快则高度依赖平台。可以使用 + 到时强制将磁盘缓存中的数据刷盘。不过,具体哪个选项速度最快则高度依赖平台。可以使用 程序测试不同选项的速度。请注意,如果 fsync 已被关闭,那么这个参数就没有意义。 diff --git a/zh/11/xaggr.sgml b/zh/11/xaggr.sgml index 8d6eb399..b2293d67 100644 --- a/zh/11/xaggr.sgml +++ b/zh/11/xaggr.sgml @@ -42,11 +42,11 @@ SELECT sum(a) FROM test_complex; - 如果没有非空输入值,上述sum定义将返回零(即初始状态值)。也许我们更希望在这种情况下返回空值 — SQL 标准要求sum这样做。实现这一点只需省略initcond短语,使初始状态值为空。通常这意味着sfunc需要检查输入的状态值是否为空。但对于sum以及maxmin这类其他简单聚合,只需把第一个非空输入值放入状态变量,然后从第二个非空输入值开始应用转移函数即可。如果初始状态值为空,并且转移函数被标记为strict(即不会对空输入调用),PostgreSQL会自动这样做。 + 如果没有非空输入值,上述sum定义将返回零(即初始状态值)。也许我们更希望在这种情况下返回空值 — SQL 标准要求sum这样做。实现这一点只需省略initcond短语,使初始状态值为空值。通常这意味着sfunc需要检查输入的状态值是否为空值。但对于sum以及maxmin这类其他简单聚合,只需把第一个非空输入值放入状态变量,然后从第二个非空输入值开始应用转移函数即可。如果初始状态值为空值,并且转移函数被标记为strict(即不会对空值输入调用),PostgreSQL会自动这样做。 - strict转移函数的另一项默认行为是,只要遇到空输入值,就会保留先前的状态值不变。因此,空值会被忽略。如果你需要对空输入采用其他行为,就不要把转移函数声明为 strict,而应在函数代码中自行检测空输入并完成所需处理。 + strict转移函数的另一项默认行为是,只要遇到空值输入,就会保留先前的状态值不变。因此,空值会被忽略。如果你需要对空值输入采用其他行为,就不要把转移函数声明为 strict,而应在函数代码中自行检测空值输入并完成所需处理。 @@ -71,7 +71,7 @@ CREATE AGGREGATE avg (float8) - SQL 中的聚合函数调用允许使用DISTINCTORDER BY选项,以控制哪些行会传递给聚合的转移函数,以及传递顺序。这些选项是在后台实现的,并不是聚合支持函数需要关心的事情。 + SQL 中的聚合函数调用允许使用DISTINCTORDER BY选项,以控制哪些行会传递给聚合的转移函数,以及传递顺序。这些选项由系统在内部实现,并不是聚合支持函数需要关心的事情。 @@ -283,7 +283,7 @@ SELECT percentile_disc(0.5) WITHIN GROUP (ORDER BY income) FROM households; - 与普通聚合不同,有序集聚合的输入行排序不是在幕后完成的,而是由聚合的支持函数负责。典型的实现方法是在聚合的状态值中保存一个tuplesort对象的引用,把输入行送入该对象,然后在最终函数中完成排序并读出数据。这样的设计使最终函数可以执行特殊操作,例如向待排序数据中注入额外的假想行。普通聚合通常可以使用由PL/pgSQL或其他 PL 语言编写的支持函数来实现,但有序集聚合通常必须用 C 编写,因为它们的状态值无法定义为任何 SQL 数据类型。(在上面的示例中,注意状态值被声明为internal类型,这很典型。)另外,由于最终函数执行了排序,之后就不可能再通过再次执行转移函数来继续加入输入行。这意味着最终函数不是READ_ONLY;在中,必须将其声明为READ_WRITE,或者如果额外的最终函数调用能够利用已经排好序的状态,则声明为SHAREABLE。 + 与普通聚合不同,有序集聚合的输入行排序不是由系统在内部完成的,而是由聚合的支持函数负责。典型的实现方法是在聚合的状态值中保存一个tuplesort对象的引用,把输入行送入该对象,然后在最终函数中完成排序并读出数据。这样的设计使最终函数可以执行特殊操作,例如向待排序数据中注入额外的假想行。普通聚合通常可以使用由PL/pgSQL或其他 PL 语言编写的支持函数来实现,但有序集聚合通常必须用 C 编写,因为它们的状态值无法定义为任何 SQL 数据类型。(在上面的示例中,注意状态值被声明为internal类型,这很典型。)另外,由于最终函数执行了排序,之后就不可能再通过再次执行转移函数来继续加入输入行。这意味着最终函数不是READ_ONLY;在中,必须将其声明为READ_WRITE,或者如果额外的最终函数调用能够利用已经排好序的状态,则声明为SHAREABLE @@ -347,12 +347,16 @@ SELECT percentile_disc(0.5) WITHIN GROUP (ORDER BY income) FROM households; 支持函数 - 用 C 编写的函数可以通过调用AggCheckCallContext来检测自己是否作为聚合支持函数被调用,例如: + + 用 C 编写的函数可以通过调用AggCheckCallContext来检测自己是否作为聚合支持函数被调用,例如: + if (AggCheckCallContext(fcinfo, NULL)) -进行这种检查的一个原因是:如果结果为真,第一个输入必然是一个临时状态值,因此可以安全地原地修改,而不必分配新的副本。示例可见 int8inc()。(虽然聚合状态转移函数总是允许原地修改状态值,但通常不鼓励聚合最终函数这样做;如果它确实这样做,则必须在创建聚合时声明这种行为。更多细节见 。) + + 进行这种检查的一个原因是:如果结果为真,第一个输入必然是一个临时状态值,因此可以安全地原地修改,而不必分配新的副本。示例可见int8inc()。(虽然聚合转移函数总是允许原地修改状态值,但通常不鼓励聚合最终函数这样做;如果它确实这样做,则必须在创建聚合时声明这种行为。更多细节见。) + - AggCheckCallContext的第二个参数可用于取得保存聚合状态值的内存上下文。这对于希望把扩展对象(见)用作状态值的转移函数很有用。第一次调用时,转移函数应返回一个扩展对象,其内存上下文是聚合状态上下文的子上下文;之后的调用则持续返回同一个扩展对象。示例见array_append()。(array_append()并不是任何内置聚合的转移函数,但它的写法保证了在用作自定义聚合的转移函数时也能高效工作。) + AggCheckCallContext的第二个参数可用于取得保存聚合状态值的内存上下文。这对于希望把展开对象(见)用作状态值的转移函数很有用。第一次调用时,转移函数应返回一个展开对象,其内存上下文是聚合状态上下文的子上下文;之后的调用则持续返回同一个展开对象。示例见array_append()。(array_append()并不是任何内置聚合的转移函数,但它的写法保证了在用作自定义聚合的转移函数时也能高效工作。) diff --git a/zh/11/xfunc.sgml b/zh/11/xfunc.sgml index 6c0728f6..af7294b1 100644 --- a/zh/11/xfunc.sgml +++ b/zh/11/xfunc.sgml @@ -4,8 +4,8 @@ 用户定义的函数 - function - user-defined + 函数 + 用户定义的 @@ -36,11 +36,11 @@ - 每一类函数可以采用基本类型、复合类型或者它们的组合作为参数。此外,每一类函数可以返回一个基本类型或一个复合类型。函数也能被定义成返回基本类型或复合类型值的集合。 + 每一类函数可以采用基础类型、复合类型或者它们的组合作为参数。此外,每一类函数可以返回一个基础类型或一个复合类型。函数也能被定义成返回基础类型或复合类型值的集合。 - 很多类函数可以接受或者返回特定的伪类型(例如,多态类型),但是可用的功能会变化。详情可以参考每一种函数的描述。 + 很多类函数可以接受或者返回特定的伪类型(例如,多态类型),但是可用的功能因函数类别而异。详情可以参考每一种函数的描述。 定义SQL函数最容易,因此我们将从讨论它们开始。大部分SQL函数的概念也能用到其他类型的函数上。 @@ -55,8 +55,8 @@ 用户定义的过程 - procedure - user-defined + 过程 + 用户定义的 过程是一个类似于函数的数据库对象。关键差异是: @@ -95,7 +95,7 @@ - 函数和过程一起构成了例程routine。 + 函数和过程统称为例程例程。 有这样的命令可以操作函数和过程而不需要知道它们是哪一种。 不过,要注意没有CREATE ROUTINE命令。 @@ -107,7 +107,7 @@ 函数 用户定义的 - in SQL + 在 SQL 中 @@ -121,7 +121,7 @@ SQL 函数的函数体必须是一个由分号分隔的 SQL 语句列表。最后一条语句后的分号是可选的。除非该函数被声明为返回 void,否则最后一条语句必须是 SELECT,或者是 INSERTUPDATEDELETE 并带有 RETURNING 子句。 任意一组 SQL 语言命令都可以打包并定义成函数。除 SELECT 查询外,这些命令还可以包含数据修改查询(INSERT, - UPDATEDELETE),以及其他 SQL 命令。(不能使用事务控制命令,例如 COMMITSAVEPOINT,以及某些实用命令,例如 VACUUM,来编写 SQL 函数。)不过,最后一条命令必须是 SELECT,或者带有 RETURNING 子句,并返回与函数声明返回类型相符的结果。或者,如果你想定义一个执行动作但没有有用返回值的 SQL 函数,也可以把它定义为返回 void。例如,下面这个函数会删除 emp 表中薪资为负的行: + UPDATEDELETE),以及其他 SQL 命令。(不能使用事务控制命令,例如 COMMITSAVEPOINT,以及某些工具命令,例如 VACUUM,来编写 SQL 函数。)不过,最后一条命令必须是 SELECT,或者带有 RETURNING 子句,并返回与函数声明返回类型相符的结果。或者,如果你想定义一个执行动作但没有有用返回值的 SQL 函数,也可以把它定义为返回 void。例如,下面这个函数会删除 emp 表中薪资为负的行: CREATE FUNCTION clean_emp() RETURNS void AS ' DELETE FROM emp WHERE salary < 0; @@ -190,10 +190,10 @@ INSERT INTO $1 VALUES (42); - 基本类型上的<acronym>SQL</acronym>函数 + 基础类型上的<acronym>SQL</acronym>函数 - 最简单的 SQL 函数没有参数,只是返回一个基本类型,例如 + 最简单的 SQL 函数没有参数,只是返回一个基础类型,例如 integer @@ -219,7 +219,7 @@ SELECT one(); - 定义接受基本类型参数的 SQL 函数也几乎同样容易: + 定义接受基础类型参数的 SQL 函数也几乎同样容易: CREATE FUNCTION add_em(x integer, y integer) RETURNS integer AS $$ @@ -349,17 +349,17 @@ SELECT name, double_salary(emp.*) AS dream 注意这里用 $1.salary 语法来选取参数行值中的一个字段。 还要注意,调用时的 SELECT 命令使用 - table_name.* 将表的当前整行取作一个组合值。该表行也可以仅用表名来引用: + table_name.* 将表的当前整行取作一个复合值。该表行也可以仅用表名来引用: SELECT name, double_salary(emp) AS dream FROM emp WHERE emp.cubicle ~= point '(2,1)'; - 但这种用法已被废弃,因为它很容易让人混淆(关于表行组合值这两种记法的更多细节,见)。 + 但这种用法已被弃用,因为它很容易让人混淆(关于表行复合值这两种记法的更多细节,见)。 - 有时候即时构造一个组合参数会很方便。这可以用ROW构造器完成。 + 有时候即时构造一个复合参数值会很方便。这可以用ROW构造器完成。 例如,我们可以调整被传递给函数的数据: SELECT name, double_salary(ROW(name, salary*1.1, age, cubicle)) AS dream @@ -382,9 +382,12 @@ $$ LANGUAGE SQL; 在这个示例中,我们为每一个属性指定了一个常量值,但是可以用任何计算来替换这些常量。 - 定义该函数时要注意两件重要的事情: + + 定义该函数时有两点重要注意事项: + + - 查询中的选择列表顺序必须与列在该复合类型所关联的表中出现的顺序完全相同。(正如我们上面所做的那样,命名列与系统无关。) + 查询中的选择列表顺序必须与列在该复合类型所关联的表中出现的顺序完全相同。(系统不考虑像上面这样指定的列名。) 我们必须确保每个表达式的类型与复合类型中对应列的类型相匹配,必要时插入类型转换。否则,就会得到这样的错误: @@ -462,7 +465,7 @@ SELECT name(new_emp()); - 另一种使用函数返回复合类型的方法是将结果传递给另一个接受正确行类型作为输入的函数: + 另一种使用函数返回复合类型的方法是将结果传递给另一个接受正确行类型作为输入的函数: CREATE FUNCTION getname(emp) RETURNS text AS $$ @@ -550,12 +553,12 @@ DROP FUNCTION sum_n_product (int, int); 带有可变数量参数的<acronym>SQL</acronym>函数 - function - variadic + 函数 + 可变参数 - variadic function + 可变参数函数 @@ -586,27 +589,27 @@ SELECT mleast(ARRAY[10, -1, 5, 4.4]); -- doesn't work - 有时候,能够把一个已经构造好的数组传给 variadic 函数会很有用,尤其是当一个 variadic 函数想把它的数组参数再传给另一个函数时。此外,在允许不受信任用户创建对象的模式中调用 variadic 函数时,这是唯一安全的方式,见。你可以在调用中指定VARIADIC来做到这一点: + 有时候,能够把一个已经构造好的数组传给可变参数函数会很有用,尤其是当一个可变参数函数想把它的数组参数再传给另一个函数时。此外,在允许不受信任用户创建对象的模式中调用可变参数函数时,这是唯一安全的方式,见。你可以在调用中指定VARIADIC来做到这一点: SELECT mleast(VARIADIC ARRAY[10, -1, 5, 4.4]); - 这样会阻止函数的 variadic 参数按其元素类型展开,从而让数组实参能够按常规方式匹配。VARIADIC 只能附加在函数调用的最后一个实参上。 + 这样会阻止函数的可变参数按其元素类型展开,从而让数组实参能够按常规方式匹配。VARIADIC 只能附加在函数调用的最后一个实参上。 - 在调用中指定VARIADIC也是向 variadic 函数传递空数组的唯一方式,例如: + 在调用中指定VARIADIC也是向可变参数函数传递空数组的唯一方式,例如: SELECT mleast(VARIADIC ARRAY[]::numeric[]); - 仅仅写成SELECT mleast()是行不通的,因为 variadic 参数必须匹配至少一个实参。(如果你希望允许这种调用,可以再定义一个同名且不带参数的函数mleast。) + 仅仅写成SELECT mleast()是行不通的,因为可变参数必须匹配至少一个实参。(如果你希望允许这种调用,可以再定义一个同名且不带参数的函数mleast。) - 从 variadic 参数派生出的数组元素参数会被视为没有自己的名字。这意味着除非你指定了 VARIADIC,否则不能使用命名参数来调用 variadic 函数()。例如,下面的调用是可行的: + 从可变参数派生出的数组元素参数会被视为没有自己的名字。这意味着除非你指定了 VARIADIC,否则不能使用命名参数来调用可变参数函数()。例如,下面的调用是可行的: SELECT mleast(VARIADIC arr => ARRAY[10, -1, 5, 4.4]); @@ -625,7 +628,7 @@ SELECT mleast(arr => ARRAY[10, -1, 5, 4.4]); 带有参数默认值的<acronym>SQL</acronym>函数 - function + 函数 参数的默认值 @@ -634,7 +637,7 @@ SELECT mleast(arr => ARRAY[10, -1, 5, 4.4]); 没有给出足够多的实参,就会插入默认值来弥补缺失的实参。由于参数只 能从实参列表的尾部开始被省略,在一个有默认值的参数之后的所有参数 都不得不也具有默认值(尽管使用命名参数记法可以允许放松这种限制, - 这种限制仍然会被强制以便位置参数记法能工作)。不管你是否使用它,这种能力都要求在某些用户不信任其他用户的数据中调用函数时做一些预防措施,见。 + 这种限制仍然会被强制以便位置参数记法能工作)。不管你是否使用它,这种能力都要求在某些用户不信任其他用户的数据库中调用函数时做一些预防措施,见 @@ -677,13 +680,13 @@ ERROR: function foo() does not exist 所有的 SQL 函数都可以被用在查询的FROM子句中,但是 - 对于返回复合类型的函数特别有用。如果函数被定义为返回一种基本类型, + 对于返回复合类型的函数特别有用。如果函数被定义为返回一种基础类型, 该表函数会产生一个单列表。如果该函数被定义为返回一种复合类型,该 表函数会为该复合类型的每一个属性产生一列。 - 以下是一个示例: + 以下是一个示例: CREATE TABLE foo (fooid int, foosubid int, fooname text); @@ -716,8 +719,8 @@ SELECT *, upper(fooname) FROM getfoo(1) AS t1; 返回集合的<acronym>SQL</acronym>函数 - function - with SETOF + 函数 + 使用 SETOF @@ -865,7 +868,7 @@ SELECT srf1(srf2(x), srf3(y)), srf4(srf5(z)) FROM tab; SELECT x, CASE WHEN x > 0 THEN generate_series(1, 5) ELSE 0 END FROM tab; - 看起来这个语句应该产生满足x > 0的输入行的五次重复,以及不满足的行的一次重复。但实际上,由于在CASE表达时被计算前,generate_series(1, 5)会被运行在一个隐式的LATERAL FROM项中,它会为每个输入行产生五次重复。为了减少混乱,这类情况会产生一个解析时错误。 + 看起来这个语句应该产生满足x > 0的输入行的五次重复,以及不满足的行的一次重复。但实际上,由于在CASE表达式被计算前,generate_series(1, 5)会被运行在一个隐式的LATERAL FROM项中,它会为每个输入行产生五次重复。为了减少混乱,这类情况会产生一个解析时错误。 @@ -877,11 +880,11 @@ SELECT x, CASE WHEN x > 0 THEN generate_series(1, 5) ELSE 0 END FROM tab; 在 PostgreSQL 10 之前,除非多个集合返回函数始终产生相同数量的行,否则把它们放在同一个选择列表中的行为并不合理。 否则,得到的输出行数会是这些集合返回函数各自产生行数的最小公倍数。 此外,嵌套的集合返回函数也不像上文所描述的那样工作;相反,一个集合返回函数至多只能有一个集合返回参数, - 并且每一层嵌套都会独立运行。再加上过去还允许条件执行(即在 CASE 等结构内部使用集合返回函数), + 并且每一组嵌套的集合返回函数都会独立运行。再加上过去还允许条件执行(即在 CASE 等结构内部使用集合返回函数), 事情就更加复杂了。 如果你要编写需要在旧版 PostgreSQL 上运行的查询,建议使用 LATERAL 语法, 因为这样在不同版本之间能够得到一致的结果。 - 如果你的查询依赖于集合返回函数的条件执行,可以把条件判断移动到自定义集合返回函数内部来修复。例如, + 如果你的查询依赖于集合返回函数的条件执行,或许可以把条件判断移动到自定义集合返回函数内部来修复。例如, SELECT x, CASE WHEN y > 0 THEN generate_series(1, z) ELSE 5 END FROM tab; @@ -899,7 +902,7 @@ END$$ LANGUAGE plpgsql; SELECT x, case_generate_series(y > 0, 1, z, 5) FROM tab; - 这种写法在所有版本的 PostgreSQL 中都能正常工作。 + 这种写法在所有版本的 PostgreSQL 中的行为都相同。 @@ -908,7 +911,7 @@ SELECT x, case_generate_series(y > 0, 1, z, 5) FROM tab; 返回<literal>TABLE</literal>的<acronym>SQL</acronym>函数 - function + 函数 RETURNS TABLE @@ -997,7 +1000,7 @@ SELECT * FROM dup(22); - 多态也可以用于 variadic 函数。例如: + 多态也可以用于可变参数函数。例如: CREATE FUNCTION anyleast (VARIADIC anyarray) RETURNS anyelement AS $$ SELECT min($1[i]) FROM generate_subscripts($1, 1) g(i); @@ -1032,11 +1035,11 @@ SELECT concat_values('|', 1, 4, 2); 带有排序规则的<acronym>SQL</acronym>函数 - collation - in SQL functions + 排序规则 + 在 SQL 函数中 - 当一个 SQL 函数有一个或多个可设定排序规则的数据类型参数时,会根据实参所带的排序规则,为每次函数调用确定一个排序规则,详见 。如果能够成功确定(也就是说,参数之间不存在隐式排序规则冲突),那么所有可设定排序规则的参数都会被视为隐式带有该排序规则。这会影响函数中对排序规则敏感的操作的行为。例如,使用上文的 anyleast 函数时, + 当一个 SQL 函数有一个或多个支持排序规则的数据类型参数时,会根据实参所带的排序规则,为每次函数调用确定一个排序规则,详见 。如果能够成功确定(也就是说,参数之间不存在隐式排序规则冲突),那么所有支持排序规则的参数都会被视为隐式带有该排序规则。这会影响函数中对排序规则敏感的操作的行为。例如,使用上文的 anyleast 函数时, SELECT anyleast('abc'::text, 'ABC'); 的结果将取决于数据库的默认排序规则。在 C 区域设置下,结果会是 ABC,但在许多其他区域设置下则会是 abc。可以在任意参数上添加 COLLATE 子句来强制指定要使用的排序规则,例如: SELECT anyleast('abc'::text, 'ABC' COLLATE "C"); @@ -1044,7 +1047,7 @@ SELECT anyleast('abc'::text, 'ABC' COLLATE "C"); CREATE FUNCTION anyleast (VARIADIC anyarray) RETURNS anyelement AS $$ SELECT min($1[i] COLLATE "en_US") FROM generate_subscripts($1, 1) g(i); $$ LANGUAGE SQL; -但请注意,如果把它用于不可设定排序规则的数据类型,就会抛出错误。 +但请注意,如果把它用于不支持排序规则的数据类型,就会抛出错误。 如果无法在实参之间确定共同的排序规则,那么 SQL 函数会把参数视为带有其数据类型的默认排序规则 @@ -1052,7 +1055,7 @@ $$ LANGUAGE SQL; - 这种可设定排序规则参数的行为,可以看作是仅适用于文本数据类型的一种受限多态形式。 + 这种支持排序规则的参数的行为,可以看作是仅适用于文本数据类型的一种受限多态形式。 @@ -1061,8 +1064,8 @@ $$ LANGUAGE SQL; 函数重载 - overloading - functions + 重载 + 函数 @@ -1094,10 +1097,10 @@ CREATE FUNCTION test(smallint, double precision) RETURNS ... - 另一类可能的冲突发生在 variadic 函数和非 variadic 函数之间。例如,可以同时创建 + 另一类可能的冲突发生在可变参数函数和非可变参数函数之间。例如,可以同时创建 foo(numeric)foo(VARIADIC numeric[])。 这时,对于只提供一个 numeric 参数的调用(例如 foo(10.1)),就不清楚该匹配哪个函数。 - 规则是:优先使用在搜索路径中出现较早的那个函数;如果两者位于同一模式中,则优先使用非 variadic 函数。 + 规则是:优先使用在搜索路径中出现较早的那个函数;如果两者位于同一模式中,则优先使用非可变参数函数。 @@ -1124,8 +1127,8 @@ CREATE FUNCTION test(int, int) RETURNS int 函数易变性分类 - volatility - functions + 易变性 + 函数 VOLATILE @@ -1142,7 +1145,7 @@ CREATE FUNCTION test(int, int) RETURNS int 一个VOLATILE函数可以做任何事情,包括修改数据库。在 使用相同的参数连续调用时,它能返回不同的结果。优化器不会对这类函 - 数的行为做任何假定。对于在每一行都需要 volatile 函数值的查询,函数都会被重新求值。 + 数的行为做任何假定。使用易变函数的查询会在需要该函数值的每一行上重新对它求值。 @@ -1190,8 +1193,7 @@ CREATE FUNCTION test(int, int) RETURNS int 在考虑先规划然后立即执行的简单交互式查询时,在STABLEIMMUTABLE分类间的区别相对较小:一个函数是在规划时只 执行一次还是在查询执行开始期间只执行一次没有太大关系。但是如果计划 - 被保存下来然后在后面被重用,区别就大了。如果在不允许过早把一个函数 - 变成规划期间的一个常数时把它标记为IMMUTABLE,会导致 + 被保存下来然后在后面被重用,区别就大了。如果把一个实际上并非不可变的函数标记为IMMUTABLE,就可能在规划期间过早将它折叠成常量,导致 在后续重用该计划时继续使用陈旧的值。在使用预备语句,或使用会缓存执行计划的函数语言(如 PL/pgSQL)时,这会带来严重问题。 @@ -1259,7 +1261,7 @@ CREATE FUNCTION test(int, int) RETURNS int 内部函数 - functioninternal + 函数内部 内部函数由 C 编写并且已经被静态链接到PostgreSQL @@ -1297,9 +1299,9 @@ CREATE FUNCTION square_root(double precision) RETURNS double precision C 语言函数 - function - user-defined - in C + 函数 + 用户定义的 + 在 C 中 @@ -1323,17 +1325,17 @@ CREATE FUNCTION square_root(double precision) RETURNS double precision - 在一个会话中第一次调用一个特定可载入对象文件中的用户定义函数时, - 动态载入器会把那个对象文件载入到内存以便该函数被调用。因此用户 + 在一个会话中第一次调用一个特定可载入目标文件中的用户定义函数时, + 动态载入器会把那个目标文件载入到内存以便该函数被调用。因此用户 定义的 C 函数的CREATE FUNCTION必须 - 为该函数指定两块信息:可载入对象文件的名称,以及要在该对象文件中 + 为该函数指定两块信息:可载入目标文件的名称,以及要在该目标文件中 调用的特定函数的 C 名称(链接符号)。如果没有显式指定 C 名称,则 它被假定为和 SQL 函数名相同。 下面的算法被用来基于CREATE FUNCTION - 命令中给定的名称来定位共享对象文件: + 命令中给定的名称来定位共享目标文件: @@ -1392,16 +1394,17 @@ CREATE FUNCTION square_root(double precision) RETURNS double precision PostgreSQL不会自动编译 C 函数。在 - 从CREATE FUNCTION命令中引用对象文件 + 从CREATE FUNCTION命令中引用目标文件 之前,它必须先被编译好。更多信息请见 - magic block + 魔数块 - 为确保动态装载的对象文件不会被加载到不兼容的服务器中,PostgreSQL会检查该文件是否包含内容适当的magic block。这样服务器就能检测出明显的不兼容情况,例如代码所针对的大版本不同于当前的 PostgreSQL。要加入 magic block,请在模块某一个(且只能一个)源文件中写入下列内容,并事先包含头文件 fmgr.h: + + 为确保动态装载的目标文件不会被加载到不兼容的服务器中,PostgreSQL 会检查该文件是否包含内容正确的魔数块。这样服务器就能检测出明显的不兼容情况,例如代码是针对另一个 PostgreSQL 主版本编译的。要加入魔数块,请在模块某一个(且只能一个)源文件中,在包含头文件 fmgr.h 之后写入: PG_MODULE_MAGIC; @@ -1409,9 +1412,9 @@ PG_MODULE_MAGIC; - 在第一次使用之后,动态载入对象文件会保留在内存中。在同一个会话中, + 在第一次使用之后,动态载入目标文件会保留在内存中。在同一个会话中, 后续对该文件中函数的调用只需付出一次很小的符号表查找开销。如果需要 - 强制重新载入一个对象文件(例如在重新编译之后),就需要开启一个新的会话。 + 强制重新载入一个目标文件(例如在重新编译之后),就需要开启一个新的会话。 @@ -1430,7 +1433,7 @@ PG_MODULE_MAGIC; - C 语言函数中的基本类型 + C 语言函数中的基础类型 数据类型 @@ -1439,16 +1442,16 @@ PG_MODULE_MAGIC; 要了解如何编写 C 语言函数,你需要了解 - PostgreSQL如何在内部表达基本数据类型 + PostgreSQL如何在内部表达基础类型 以及如何与函数传递它们。在内部, - PostgreSQL把基本类型视为一块内存数据块。 + PostgreSQL把基础类型视为一块内存数据块。 你为该类型定义的用户自定义函数,决定了 PostgreSQL 如何操作它。 也就是说,PostgreSQL 只负责把数据存到磁盘、再从磁盘取回, 而数据的输入、处理和输出则依赖你定义的这些函数。 - 基本类型可以有三种内部格式之一: + 基础类型可以有三种内部格式之一: @@ -1513,10 +1516,9 @@ typedef struct 最后,所有变长类型必须也以引用的方式传递。所有变长类型必须用一个 - 正好 4 字节的不透明长度域开始,该域会由SET_VARSIZE - 设置,绝不要直接设置该域!所有要被存储在该类型中的数据必须在内存 - 中接着该长度域的后面存储。长度域包含该结构体的总长度,也就是包括长 - 度域本身的尺寸。 + 正好 4 字节的不透明长度字段开始,该字段会由SET_VARSIZE + 设置,绝不要直接设置该字段!所有要被存储在该类型中的数据必须在内存 + 中接着该长度字段的后面存储。长度字段包含该结构体的总长度,也就是包括长度字段本身的尺寸。 @@ -1566,16 +1568,16 @@ memcpy(destination->data, buffer, 40); VARHDRSZsizeof(int32)一样, - 但是用宏VARHDRSZ来引用变长类型的载荷的 + 但是用宏VARHDRSZ来引用变长类型的额外开销的 尺寸被认为是比较好的风格。还有,必须 - 使用SET_VARSIZE宏来设置长度域,而不是用 + 使用SET_VARSIZE宏来设置长度字段,而不是用 简单的赋值来设置。 展示了 PostgreSQL 中许多内置 SQL 数据类型所对应的 C 类型。 - Defined In列给出了需要包含的头文件,以获取类型定义。 + 定义文件列给出了需要包含的头文件,以获取类型定义。 (实际的定义可能位于所列文件包含的其他文件中。建议用户坚持使用已定义的接口。) 请注意,在服务器代码的任何源文件中,都应该始终首先包含postgres.h, 因为它声明了很多你反正都会用到的内容,而且先包含其他头文件可能会带来可移植性问题。 @@ -1763,8 +1765,7 @@ memcpy(destination->data, buffer, 40);
- 现在我们已经复习了基本类型所有可能的结构,现在可以展示一些 - 真实函数的示例了。 + 了解了基础类型所有可能的结构后,就可以看一些实际函数示例。 @@ -1772,7 +1773,7 @@ memcpy(destination->data, buffer, 40); 版本 1 的调用约定 - 版本-1 的调用规范依赖于宏来降低传参数和结果的复杂度。版本-1 函数的 + 版本-1 的调用约定依赖于宏来降低传参数和结果的复杂度。版本-1 函数的 C 声明总是: Datum funcname(PG_FUNCTION_ARGS) @@ -1784,14 +1785,16 @@ PG_FUNCTION_INFO_V1(funcname); 必须出现在同一个源文件中(按惯例会正好写在该函数本身之前)。 这种宏调用不是internal语言函数所需要的,因为 PostgreSQL会假定所有内部函数都使用 - 版本-1 规范。不过,对于动态载入函数是必需的。 + 版本-1 调用约定。不过,对于动态载入函数是必需的。 - 在版本-1 函数中,每一个实参都使用对应于该参数数据类型的PG_GETARG_xxx()宏取得。(在非严格的函数中,需要使用PG_ARGISNULL()对参数是否为空提前做检查;见下文。)结果要用对应于返回类型的PG_RETURN_xxx()宏返回。PG_GETARG_xxx()的参数是要取得的函数参数的编号,从零开始计。PG_RETURN_xxx()的参数是实际要返回的值。 + 在版本-1 函数中,每一个实参都使用对应于该参数数据类型的PG_GETARG_xxx()宏取得。(在非严格的函数中,需要使用PG_ARGISNULL()对参数是否为空值提前做检查;见下文。)结果要用对应于返回类型的PG_RETURN_xxx()宏返回。PG_GETARG_xxx()的参数是要取得的函数参数的编号,从零开始计。PG_RETURN_xxx()的参数是实际要返回的值。 - 下面是一些使用版本-1 调用约定的示例: + + 这里是一些使用版本-1调用约定的示例: + - 注意我们已经把函数指定为strict,这意味着如果有任何输入值为空,系统应该自动假定得到空结果。通过这种做法,我们避免在函数代码中检查空值输入。如果不这样做,我们必须使用PG_ARGISNULL()明确地检查空值输入。 + 注意我们已经把函数指定为strict,这意味着如果有任何输入值为空值,系统应该自动假定结果为空值。通过这种做法,我们避免在函数代码中检查空值输入。如果不这样做,我们必须使用PG_ARGISNULL()明确地检查空值输入。 - 宏PG_ARGISNULL(n)允许一个函数测试是否每一个输入为空(当然,只需要在没有声明为strict的函数中这样做)。和PG_GETARG_xxx()宏一样,输入参数也是从零开始计数。注意应该在验证了一个参数不是空之后才执行PG_GETARG_xxx()。要返回一个空结果,应执行PG_RETURN_NULL(),它对严格的以及非严格的函数都有用。 + 宏PG_ARGISNULL(n)允许一个函数测试是否每一个输入为空值(当然,只需要在没有声明为strict的函数中这样做)。和PG_GETARG_xxx()宏一样,输入参数也是从零开始计数。注意应该在验证了一个参数不是空值之后才执行PG_GETARG_xxx()。要返回空值结果,应执行PG_RETURN_NULL(),它对严格的以及非严格的函数都有用。 @@ -1933,11 +1936,11 @@ CREATE FUNCTION concat_text(text, text) RETURNS text - 在版本-1接口中提供的其他选项是PG_GETARG_xxx()宏的两个变种。其中的第一种是PG_GETARG_xxx_COPY(),它确保返回的指定参数的拷贝可以被安全地写入(通常的宏有时会返回一个指向表中物理存储的值,它不能被写入。使用PG_GETARG_xxx_COPY()宏可以保证得到一个可写的结果)。第二种变种PG_GETARG_xxx_SLICE()宏有三个参数。第一个是函数参数的编号(如上文)。第二个和第三个是要被返回的段的偏移量和长度。偏移量从零开始计算,而负值的长度则表示要求返回该值的剩余部分。当大型值的存储类型为external时,这些宏提供了访问这些大型值的更有效的方法(列的存储类型可以使用ALTER TABLE tablename ALTER COLUMN colname SET STORAGE storagetype来指定。storagetypeplainexternalextended或者main)。 + 在版本-1接口中提供的其他选项是PG_GETARG_xxx()宏的两个变种。其中的第一种是PG_GETARG_xxx_COPY(),它确保返回的指定参数的拷贝可以被安全地写入(通常的宏有时会返回一个指向表中物理存储值的指针,不能写入该值。使用PG_GETARG_xxx_COPY()宏可以保证得到一个可写的结果)。第二种变种PG_GETARG_xxx_SLICE()宏有三个参数。第一个是函数参数的编号(如上文)。第二个和第三个是要被返回的段的偏移量和长度。偏移量从零开始计算,而负值的长度则表示要求返回该值的剩余部分。当大型值的存储类型为external时,这些宏提供了访问这些大型值的部分内容的更有效方法(列的存储类型可以使用ALTER TABLE tablename ALTER COLUMN colname SET STORAGE storagetype来指定。storagetypeplainexternalextended或者main)。 - 最后,版本-1 的函数调用规范可以返回集合结果()、实现触发器函数()和过程语言调用处理器()。更多细节 + 最后,版本-1 的函数调用约定可以返回集合结果()、实现触发器函数()和过程语言调用处理器()。更多细节 可见源代码发布中的src/backend/utils/fmgr/README @@ -1948,18 +1951,24 @@ CREATE FUNCTION concat_text(text, text) RETURNS text 在开始更高级的话题之前,我们应该讨论一下用于 PostgreSQL C 语言函数的编码规则。 - 虽然可以把不是 C 编写的函数载入到 - PostgreSQL中,这通常是很困难的, + 虽然有可能把不是 C 编写的函数载入到 + PostgreSQL中,但即使能够做到,通常也很困难, 因为其他语言(例如 C++、FORTRAN 或者 Pascal)通常不会遵循和 C - 相同的调用规范。也就是说,其他语言不会以同样的方式在函数之间传递 + 相同的调用约定。也就是说,其他语言不会以同样的方式在函数之间传递 参数以及返回值。由于这个原因,我们会假定你的 C 语言函数确实是用 C 编写的。 - 编写和构建 C 函数的基本规则如下: + + 编写和构建 C 语言函数的基本规则如下: + + - 使用pg_config - --includedir-serverpg_config用于用户定义的 C 函数来确定PostgreSQL服务器头文件在你的系统(或用户将要运行的系统)上的安装位置。 + + 使用 pg_config + --includedir-serverpg_config用于用户定义的 C 函数 + 查出 PostgreSQL 服务器头文件在你的系统上(或你的用户将要运行的系统上)安装于何处。 + @@ -1970,7 +1979,7 @@ CREATE FUNCTION concat_text(text, text) RETURNS text - 记得按照中的说明,为你的共享库定义一个magic block。 + 记得按照中的说明,为你的共享库定义一个魔数块 @@ -1996,7 +2005,7 @@ CREATE FUNCTION concat_text(text, text) RETURNS text - 对象文件中定义的符号名不能彼此冲突,也不能与 + 目标文件中定义的符号名不能彼此冲突,也不能与 PostgreSQL 服务器可执行文件中定义的符号冲突。如果你收到这类错误消息,就必须重命名相关函数或变量。 @@ -2007,17 +2016,25 @@ CREATE FUNCTION concat_text(text, text) RETURNS text 复合类型没有像 C 结构体那样的固定布局。复合类型的实例可能包含 - 空值域。此外,继承层次中的复合类型可能具有和同一继承层次中 - 其他成员不同的域。因此, + 空值字段。此外,继承层次中的复合类型可能具有和同一继承层次中 + 其他成员不同的字段。因此, PostgreSQL提供了函数接口 - 来访问 C 的复合类型的域。 + 以便从 C 访问复合类型的字段。 - 假设我们想编写一个函数来回答如下查询: + + 假设我们想要写一个函数来回答查询: + + SELECT name, c_overpaid(emp, 1500) AS overpaid FROM emp WHERE name = 'Bill' OR name = 'Sam'; -使用版本-1 调用约定,我们可以将 c_overpaid 定义为: + + 如果使用版本-1的调用约定,我们可以定义 + c_overpaid为: + + GetAttributeByName 是 - PostgreSQL 的一个系统函数,用于从指定行中取出属性。它有三个参数:传入函数的 HeapTupleHeader 类型参数、所需属性的名称,以及一个用于指示该属性是否为 null 的返回参数。GetAttributeByName 返回一个 Datum 值,你可以用适当的 DatumGetXXX() 函数把它转换为正确的数据类型。注意,如果 null 标志被设置,那么返回值本身没有意义;在尝试对结果做任何处理之前,务必先检查这个 null 标志。 + PostgreSQL 的一个系统函数,用于从指定行中取出属性。它有三个参数:传入函数的 HeapTupleHeader 类型参数、所需属性的名称,以及一个用于指示该属性是否为 null 的返回参数。GetAttributeByName 返回一个 Datum 值,你可以用适当的 DatumGetXXX() 宏把它转换为正确的数据类型。注意,如果 null 标志被设置,那么返回值本身没有意义;在尝试对结果做任何处理之前,务必先检查这个 null 标志。 也有GetAttributeByNum函数,它可以用目标属性 - 的属性号而不是属性名来选择目标属性。 + 的列号而不是属性名来选择目标属性。 @@ -2073,14 +2090,14 @@ CREATE FUNCTION c_overpaid(emp, integer) RETURNS boolean 要从 C 语言函数中返回一行或一个复合类型值,可以使用一套特殊的 API, - 它通过一组宏和函数隐藏了构造组合数据类型时的大部分复杂性。要使用这套 API,源文件中必须包含: + 它通过一组宏和函数隐藏了构造复合数据类型时的大部分复杂性。要使用这套 API,源文件中必须包含: #include "funcapi.h" - 构造组合数据值(下文简称元组)有两种方式: + 构造复合数据值(下文简称元组)有两种方式: 一种是从 Datum 值数组构造,另一种是从 C 字符串数组构造,这些字符串会传给该元组各列数据类型的输入转换函数。 无论采用哪种方式,首先都需要获取或构造描述该元组结构的 TupleDesc。 处理 Datum 时,需要把 TupleDesc 传给 BlessTupleDesc,然后为每一行调用 heap_form_tuple。 @@ -2089,13 +2106,13 @@ CREATE FUNCTION c_overpaid(emp, integer) RETURNS boolean - 有一些辅助函数可以用来设置所需的 TupleDesc。在大多数返回组合值的函数中,推荐的做法是调用: + 有一些辅助函数可以用来设置所需的 TupleDesc。在大多数返回复合值的函数中,推荐的做法是调用: TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc) - 传入与调用函数本身相同的 fcinfo 结构体(这当然要求使用版本 1 调用约定)。 + 传入调用函数本身收到的同一个 fcinfo 结构体(这当然要求使用版本 1 调用约定)。 resultTypeId 可以指定为 NULL,也可以指定为一个本地变量的地址,用于接收函数结果类型的 OID。 resultTupleDesc 应当是一个本地 TupleDesc 变量的地址。 检查返回结果是否为 TYPEFUNC_COMPOSITE;如果是,resultTupleDesc 就会被填入所需的 TupleDesc。 @@ -2114,7 +2131,7 @@ TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, get_call_result_type有一个兄弟 get_expr_result_type,它被用来解析被表示为一棵表达式 - 树的函数调用的输出类型。在尝试确定来自函数外部的结果类型时可以用它。 + 树的函数调用的输出类型。在尝试从函数自身外部确定结果类型时可以用它。 也有一个get_func_result_type,当只有函数的 OID 可用时 可以用它。不过这些函数无法处理被声明为返回record的 函数,并且get_func_result_type无法解析多态类型,因此你 @@ -2123,22 +2140,22 @@ TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo,
- 更早、现在已被废弃的获取TupleDesc的函数有: + 更早、现在已被弃用的获取TupleDesc的函数有: TupleDesc RelationNameGetTupleDesc(const char *relname) - 它可以为一个提到的关系的行类型得到TupleDesc, + 它可以为一个指定名称的关系的行类型得到TupleDesc, 还有: TupleDesc TypeGetTupleDesc(Oid typeoid, List *colaliases) 可以基于一个类型 OID 得到TupleDesc。这可以被用来 - 为一种基础或者复合类型获得TupleDesc。不过,对于 + 为一种基本或者复合类型获得TupleDesc。不过,对于 返回record的函数它不起作用,并且它无法解析多态类型。 - 一旦有了一个TupleDesc,如果计划处理 Datum可以调用: + 一旦有了一个TupleDesc,如果计划处理 Datum,可以调用: TupleDesc BlessTupleDesc(TupleDesc tupdesc) @@ -2148,7 +2165,7 @@ AttInMetadata *TupleDescGetAttInMetadata(TupleDesc tupdesc) 如果正在编写一个返回集合的函数,你可以把这些函数的结果保存在 FuncCallContext结构体中 — 分别使用 - tuple_desc或者attinmeta域。 + tuple_desc或者attinmeta字段。 @@ -2168,8 +2185,7 @@ HeapTuple BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values) values是一个 C 字符串数组,每一个元素是返回行 的一个属性。每一个 C 字符串应该是该属性数据类型的输入函数所期望 的格式。为了对一个属性返回空值,values数组中对 - 应的指针应该被设置为NULL。对于你返回的每一行都将 - 再次调用这个函数。 + 应的指针应该被设置为NULL。对于你返回的每一行都需要再次调用这个函数。 @@ -2204,82 +2220,82 @@ HeapTupleGetDatum(HeapTuple tuple) 使用 ValuePerCall 模式时,重要的是要记住查询不能保证运行完成; 也就是说,由于诸如LIMIT之类的选项, - 执行程序可能会在获取所有行之前停止调用 set-returning 函数。 + 执行器可能会在获取所有行之前停止调用集合返回函数。 这意味着在最后一次调用中执行清理活动是不安全的,因为这可能永远不会发生。 对于需要访问外部资源(例如文件描述符)的函数,建议使用 Materialize 模式。 - 本节的其余部分记录了一组使用 ValuePerCall 模式的 SRF 常用(尽管不是必须使用)的帮助程序宏。 + 本节的其余部分记录了一组使用 ValuePerCall 模式的 SRF 常用(尽管不是必须使用)的辅助宏。 有关 Materialize 模式的其他详细信息可以在src/backend/utils/fmgr/README中找到。 此外,PostgreSQL源代码分发中的contrib 模块包含许多使用 ValuePerCall 和 Materialize 模式的 SRF 示例。 - 要使用这里描述的 ValuePerCall 支持宏,请包含 funcapi.h。这些宏会用到一个结构体 FuncCallContext,该结构体包含需要跨调用保存的状态。在使用这些宏的 SRF 中,fcinfo->flinfo->fn_extra 用于在调用之间保存指向 FuncCallContext 的指针。宏在第一次使用时自动填充该字段,并期望在后续使用中找到相同的指针。 + + 要使用此处描述的 ValuePerCall 支持宏,请包含funcapi.h。 + 这些宏与结构体FuncCallContext一起使用,该结构体包含需要跨调用保存的状态。 + 在使用这些宏的 SRF 中,fcinfo->flinfo->fn_extra用于在调用之间保存 + 指向FuncCallContext的指针。 + 宏在第一次使用时自动填充该字段,并期望在后续使用中找到相同的指针。 + typedef struct FuncCallContext { /* - * Number of times we've been called before + * 本次调用以前已经被调用过多少次 * - * call_cntr is initialized to 0 for you by SRF_FIRSTCALL_INIT(), and - * incremented for you every time SRF_RETURN_NEXT() is called. + * SRF_FIRSTCALL_INIT() 会为你把 call_cntr 初始化为 0, + * 并且在每次调用 SRF_RETURN_NEXT() 时增加。 */ uint64 call_cntr; /* - * OPTIONAL maximum number of calls + * 可选:最大调用次数 * - * max_calls is here for convenience only and setting it is optional. - * If not set, you must provide alternative means to know when the - * function is done. + * 这里的 max_calls 只是为了方便,设置它是可选的。 + * 如果没有设置,你必须提供替代的方法来了解函数什么时候做完。 */ uint64 max_calls; /* - * OPTIONAL pointer to result slot + * 可选:指向结果槽的指针 * - * This is obsolete and only present for backward compatibility, viz, - * user-defined SRFs that use the deprecated TupleDescGetSlot(). + * 此字段已过时,仅为向后兼容而保留,即兼容使用已弃用的 + * TupleDescGetSlot() 的用户定义 SRF。 */ TupleTableSlot *slot; /* - * OPTIONAL pointer to miscellaneous user-provided context information + * 可选:指向用户提供的上下文信息的指针 * - * user_fctx is for use as a pointer to your own data to retain - * arbitrary context information between calls of your function. + * user_fctx 是一个指向你自己的数据的指针,它可用来在函数的多次 + * 调用之间保存任意的上下文信息。 */ void *user_fctx; /* - * OPTIONAL pointer to struct containing attribute type input metadata + * 可选:指向包含属性类型输入元数据的结构的指针 * - * attinmeta is for use when returning tuples (i.e., composite data types) - * and is not used when returning base data types. It is only needed - * if you intend to use BuildTupleFromCStrings() to create the return - * tuple. + * attinmeta 被用在返回元组(即复合数据类型)时,在返回基础类型 + * 时不会使用。只有想用BuildTupleFromCStrings()创建返回元组时才需要它。 */ AttInMetadata *attinmeta; /* - * memory context used for structures that must live for multiple calls + * 用于保存必须在多次调用间都存在的结构的内存上下文 * - * multi_call_memory_ctx is set by SRF_FIRSTCALL_INIT() for you, and used - * by SRF_RETURN_DONE() for cleanup. It is the most appropriate memory - * context for any memory that is to be reused across multiple calls - * of the SRF. + * SRF_FIRSTCALL_INIT() 会为你设置 multi_call_memory_ctx,并且由 + * SRF_RETURN_DONE() 来清理。对于任何需要在 SRF 的多次调用间都 + * 存在的内存来说,它是最合适的内存上下文。 */ MemoryContext multi_call_memory_ctx; /* - * OPTIONAL pointer to struct containing tuple description + * 可选:指向包含元组描述的结构的指针 * - * tuple_desc is for use when returning tuples (i.e., composite data types) - * and is only needed if you are going to build the tuples with - * heap_form_tuple() rather than with BuildTupleFromCStrings(). Note that - * the TupleDesc pointer stored here should usually have been run through - * BlessTupleDesc() first. + * tuple_desc 被用在返回元组(即复合数据类型)时,并且只有在用 + * heap_form_tuple() 而不是 BuildTupleFromCStrings() 构建元组时才需要它。 + * 注意这里存储的 TupleDesc 指针通常已经被先运行过 BlessTupleDesc()。 */ TupleDesc tuple_desc; @@ -2381,14 +2397,16 @@ my_set_returning_function(PG_FUNCTION_ARGS) else { /* 这里已经完成了项的返回,所以只报告事实。 */ - /* (不要将清理代码放在这里的。) */ + /* (不要将清理代码放在这里。) */ SRF_RETURN_DONE(funcctx); } } - 下面是一个返回复合类型的简单 SRF 的完整示例: + 一个返回复合类型的简单SRF的完整示例如下: +multi_call_memory_ctx); - /* total number of tuples to be returned */ + /* 要返回的元组总数 */ funcctx->max_calls = PG_GETARG_UINT32(0); - /* Build a tuple descriptor for our result type */ + /* 为我们的结果类型构建一个元组描述符 */ if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), @@ -2422,8 +2440,7 @@ retcomposite(PG_FUNCTION_ARGS) "that cannot accept type record"))); /* - * generate attribute metadata needed later to produce tuples from raw - * C strings + * 生成后续从原始C字符串生成元组所需的属性元数据 */ attinmeta = TupleDescGetAttInMetadata(tupdesc); funcctx->attinmeta = attinmeta; @@ -2431,23 +2448,22 @@ retcomposite(PG_FUNCTION_ARGS) MemoryContextSwitchTo(oldcontext); } - /* stuff done on every call of the function */ + /* 每次函数调用时执行的操作 */ funcctx = SRF_PERCALL_SETUP(); call_cntr = funcctx->call_cntr; max_calls = funcctx->max_calls; attinmeta = funcctx->attinmeta; - if (call_cntr < max_calls) /* do when there is more left to send */ + if (call_cntr < max_calls) /* 当还有更多要发送时执行 */ { char **values; HeapTuple tuple; Datum result; /* - * Prepare a values array for building the returned tuple. - * This should be an array of C strings which will - * be processed later by the type input functions. + * 为构建返回的元组准备一个值数组。 + * 这应该是一个由后续类型输入函数处理的C字符串数组。 */ values = (char **) palloc(3 * sizeof(char *)); values[0] = (char *) palloc(16 * sizeof(char)); @@ -2458,13 +2474,13 @@ retcomposite(PG_FUNCTION_ARGS) snprintf(values[1], 16, "%d", 2 * PG_GETARG_INT32(1)); snprintf(values[2], 16, "%d", 3 * PG_GETARG_INT32(1)); - /* build a tuple */ + /* 构建一个元组 */ tuple = BuildTupleFromCStrings(attinmeta, values); - /* make the tuple into a datum */ + /* 将元组转换为 datum */ result = HeapTupleGetDatum(tuple); - /* clean up (this is not really necessary) */ + /* 清理(这实际上并不是必要的) */ pfree(values[0]); pfree(values[1]); pfree(values[2]); @@ -2472,26 +2488,33 @@ retcomposite(PG_FUNCTION_ARGS) SRF_RETURN_NEXT(funcctx, result); } - else /* do when there is no more left */ + else /* 当没有更多要发送时执行 */ { SRF_RETURN_DONE(funcctx); } } ]]> -在 SQL 中声明该函数的一种方法是: + + + 在SQL中声明此函数的一种方法是: + CREATE TYPE __retcomposite AS (f1 integer, f2 integer, f3 integer); CREATE OR REPLACE FUNCTION retcomposite(integer, integer) RETURNS SETOF __retcomposite AS 'filename', 'retcomposite' LANGUAGE C IMMUTABLE STRICT; -另一种方法是使用 OUT 参数: + + 另一种方法是使用OUT参数: + CREATE OR REPLACE FUNCTION retcomposite(IN integer, IN integer, OUT f1 integer, OUT f2 integer, OUT f3 integer) RETURNS SETOF record AS 'filename', 'retcomposite' LANGUAGE C IMMUTABLE STRICT; -注意,在这种方法中,该函数的输出类型在形式上是一个匿名的 record 类型。 + + 请注意,采用这种方法时,函数的输出类型在形式上是一个匿名的 record 类型。 + @@ -2510,10 +2533,10 @@ CREATE OR REPLACE FUNCTION retcomposite(IN integer, IN integer, fcinfo->flinfo访问。参数argnum则是从零 开始计。get_call_result_type也可被用作 get_fn_expr_rettype的一种替代品。还有 - get_fn_expr_variadic,它可以被用来找出 variadic 参数 + get_fn_expr_variadic,它可以被用来找出可变参数 是否已经被合并到了一个数组中。这主要用于 VARIADIC "any"函数,因为对于接收普通数组类型的 - variadic 函数来说总是会发生这类合并。 + 可变参数函数来说总是会发生这类合并。 @@ -2581,7 +2604,7 @@ CREATE FUNCTION make_array(anyelement) RETURNS anyarray 它与 anyelement 类似,但不会要求不同的 "any" 参数必须是同一种类型,也不会帮助确定函数的结果类型。 C 语言函数还可以把最后一个参数声明为 VARIADIC "any"。 这可以匹配一个或多个任意类型的实参(不必是同一种类型)。 - 这些参数不会像普通 variadic 函数那样被收集成一个数组,而是会单独传给函数。 + 这些参数不会像普通可变参数函数那样被收集成一个数组,而是会单独传给函数。 使用这种特性时,必须结合 PG_NARGS() 宏以及前面介绍的方法来确定实参的个数和类型。 此外,这种函数的用户也可能希望在函数调用中使用 VARIADIC 关键字,以便让函数把数组元素当作独立参数处理。 如果希望支持这种行为,函数本身就必须在使用 get_fn_expr_variadic 检测到实参被标记为 VARIADIC 后自行实现它。 @@ -2599,7 +2622,7 @@ CREATE FUNCTION make_array(anyelement) RETURNS anyarray - 共享内存 + 共享内存与 LWLocks 附加模块可以在服务器启动时预留 LWLock 和一块共享内存。附加模块的共享库必须通过在以下参数中指定它来预装载:shared_preload_libraries。共享内存可以通过下面的调用来预留: void RequestAddinShmemSpace(int size) @@ -2668,9 +2691,9 @@ if (!ptr) - 如果从 C++ 代码调用后端函数,确定 C++ 调用栈值包含传统 C 风格 + 如果从 C++ 代码调用后端函数,确定 C++ 调用栈只包含传统 C 风格 的数据结构(POD)。这是必要的,因为后端错误会 - 产生远距离的longjmp(),它无法正确的退回具有非 + 产生远距离的longjmp(),它无法正确地展开具有非 POD 对象的 C++ 调用栈。 diff --git a/zh/11/xindex.sgml b/zh/11/xindex.sgml index 267ca468..7116fa28 100644 --- a/zh/11/xindex.sgml +++ b/zh/11/xindex.sgml @@ -22,7 +22,7 @@ pg_am 表为每个索引方法(内部称为访问方法)保存一行。对表进行常规访问的支持内置于 PostgreSQL 中,但所有索引方法都在 pg_am 中描述。可以编写必要的代码,然后在 pg_am 中创建一个条目,从而添加新的索引访问方法 — 但这超出了本章的范围(参见)。 - 索引方法的例程并不直接知道它将处理哪些数据类型。相反,一个操作符类operator class标识了索引方法在处理特定数据类型时需要使用的那组操作。之所以称为操作符类,是因为它指定的一项内容就是可与索引一起使用的 WHERE 子句操作符集合(也就是能被转换成索引扫描条件的操作符)。操作符类还可以指定索引方法内部操作所需的一些支持函数,但这些函数并不直接对应任何可与索引一起使用的 WHERE 子句操作符。 + 索引方法的例程并不直接知道它将处理哪些数据类型。相反,一个操作符类操作符类标识了索引方法在处理特定数据类型时需要使用的那组操作。之所以称为操作符类,是因为它指定的一项内容就是可与索引一起使用的 WHERE 子句操作符集合(也就是能被转换成索引扫描条件的操作符)。操作符类还可以指定索引方法内部操作所需的一些支持函数,但这些函数并不直接对应任何可与索引一起使用的 WHERE 子句操作符。 @@ -310,15 +310,21 @@ - 比较两个键,并返回小于零、等于零或大于零的整数,分别表示第一个键小于、等于或大于第二个键 + + 比较两个键,并返回一个小于零、等于零或大于零的整数,用以表示第一个键是小于、等于还是大于第二个键 + 1 - 返回可从 C 调用的排序支持函数的地址(可选) + + 返回可由 C 调用的排序支持函数地址(可选) + 2 - 将测试值与基准值加上或减去偏移量后的结果进行比较,并根据比较结果返回真或假(可选) + + 将测试值与基准值加上或减去某个偏移量后的结果进行比较,并根据比较结果返回真或假(可选) + 3 @@ -345,7 +351,7 @@ - 给定一个 64 位 salt,计算一个键的 64 位哈希值;如果 salt 为 0,结果的低 32 位必须与函数 1 计算出的值一致(可选) + 给定一个 64 位盐值,计算一个键的 64 位哈希值;如果盐值为 0,结果的低 32 位必须与函数 1 计算出的值一致(可选) 2 @@ -478,7 +484,7 @@ compare - 比较两个键,并返回一个小于零、等于零或大于零的整数,以表示第一个键是小于、等于还是大于第二个键 + 比较两个键,并返回一个小于零、等于零或大于零的整数,用以表示第一个键是小于、等于还是大于第二个键 1 @@ -618,7 +624,10 @@ complex_abs_lt(PG_FUNCTION_ARGS) 其他四个函数的区别只在于它们如何比较内部函数的结果与 0。 - 接下来,在 SQL 中声明这些函数,以及基于这些函数的操作符: + + 接着,我们在 SQL 中声明这些函数以及基于它们的操作符: + + CREATE FUNCTION complex_abs_lt(complex, complex) RETURNS bool AS 'filename', 'complex_abs_lt' LANGUAGE C IMMUTABLE STRICT; @@ -628,7 +637,9 @@ CREATE OPERATOR < ( commutator = > , negator = >= , restrict = scalarltsel, join = scalarltjoinsel ); -必须指定正确的交换操作符和求反操作符,以及合适的限制选择率与连接选择率函数,否则优化器无法有效使用索引。 + + 指定正确的交换子和求反器操作符很重要,同样也要指定合适的限制选择率函数和连接选择率函数,否则优化器将无法有效地利用索引。 + 这里还有几点值得注意: @@ -706,14 +717,14 @@ CREATE OPERATOR CLASS complex_abs_ops - 为了满足这些需求,PostgreSQL使用操作符族operator family这一概念。一个操作符族包含一个或多个操作符类,还可以包含属于整个族、但不属于族中任何单一类的可索引操作符及其相应的支持函数。我们称这样的操作符和函数在该族中是松散的,而不是绑定在某个特定类中。通常,每个操作符类只包含单一数据类型的操作符,而跨数据类型操作符则作为操作符族中的松散成员存在。 + 为了满足这些需求,PostgreSQL使用操作符族操作符族这一概念。一个操作符族包含一个或多个操作符类,还可以包含属于整个族、但不属于族中任何单一类的可索引操作符及其相应的支持函数。我们称这样的操作符和函数在该族中是松散的,而不是绑定在某个特定类中。通常,每个操作符类只包含单一数据类型的操作符,而跨数据类型操作符则作为操作符族中的松散成员存在。 一个操作符族中的所有操作符和函数都必须具有兼容的语义,而兼容性的要求由索引方法设定。因此,你也许会疑惑,为什么还要把该族的某些子集单独划成操作符类;事实上,对很多用途而言,类的划分并不重要,真正有意义的分组只有操作符族。之所以定义操作符类,是因为它们规定了支持特定索引所需的操作符族内容。如果某个索引使用了某个操作符类,那么在不删除该索引的情况下就不能删除该操作符类 — 但操作符族中的其他部分,也就是其他操作符类和松散操作符,则可以被删除。因此,一个操作符类应当只包含在特定数据类型上支持索引所合理需要的最小操作符和函数集合,而那些相关但非必需的操作符,则可以作为操作符族的松散成员加入。 - 例如,PostgreSQL内置了 B 树操作符族integer_ops,其中包含操作符类int8_opsint4_opsint2_ops,它们分别用于以下列类型上的索引:bigintint8), + 例如,PostgreSQL内置了 B-树操作符族integer_ops,其中包含操作符类int8_opsint4_opsint2_ops,它们分别用于以下列类型上的索引:bigintint8), integerint4)和smallintint2)。该操作符族还包含跨数据类型的比较操作符,允许对这些类型中的任意两个进行比较,因此可以使用一种类型的比较值搜索另一种类型上的索引。可以用以下定义复制这个操作符族: -注意,此定义重载了操作符策略编号和支持函数编号:每个编号在操作符族中出现多次。只要同一编号的每个实例具有不同的输入数据类型,这就是允许的。两个输入类型都等于某个操作符类输入类型的实例,是该操作符类的主要操作符和支持函数,通常应声明为操作符类的一部分,而不是操作符族的独立成员。 +注意,此定义重载了操作符策略编号和支持函数编号:每个编号在操作符族中出现多次。只要同一编号的每个实例具有不同的输入数据类型,这就是允许的。两个输入类型都等于某个操作符类输入类型的实例,是该操作符类的主要操作符和支持函数,通常应声明为操作符类的一部分,而不是操作符族的松散成员。 所详述,在一个 B-树操作符族中,该族中的所有操作符都必须以兼容的方式排序。对族中的每一个操作符,都必须有一个具有相同两个输入数据类型的支持函数。建议让操作符族保持完整,也就是说,对每一种数据类型组合都应包含全部操作符。每个操作符类只应包含其数据类型对应的非跨数据类型操作符和支持函数。 - 要构建一个多数据类型的哈希操作符族,必须为该族支持的每一种数据类型创建相互兼容的哈希支持函数。这里的兼容性是指:对任意两个被该族中的等值操作符视为相等的值,这些函数都保证返回相同的哈希码,即使这两个值属于不同类型也是如此。当这些类型具有不同的物理表示时,这通常难以实现,但在某些情况下可以做到。此外,将该操作符族中一种数据类型的值通过隐式或二进制强制转换转换成该族中另一种数据类型时,不应改变所计算出的哈希值。注意,每种数据类型只有一个支持函数,而不是每个等值操作符一个。建议让操作符族保持完整,也就是说,对每一种数据类型组合都提供一个等值操作符。每个操作符类只应包含其数据类型对应的非跨数据类型等值操作符和支持函数。 + 要构建一个多数据类型的哈希操作符族,必须为该族支持的每一种数据类型创建相互兼容的哈希支持函数。这里的兼容性是指:对任意两个被该族中的等值操作符视为相等的值,这些函数都保证返回相同的哈希码,即使这两个值属于不同类型也是如此。当这些类型具有不同的物理表示时,这通常难以实现,但在某些情况下可以做到。此外,将该操作符族中一种数据类型的值通过隐式或二进制强制转换转为该族中另一种数据类型时,不得改变所计算出的哈希值。注意,每种数据类型只有一个支持函数,而不是每个等值操作符一个。建议让操作符族保持完整,也就是说,对每一种数据类型组合都提供一个等值操作符。每个操作符类只应包含其数据类型对应的非跨数据类型等值操作符和支持函数。 @@ -828,7 +839,7 @@ ALTER OPERATOR FAMILY integer_ops USING btree ADD - 在 PostgreSQL 8.3 之前,并没有操作符族这一概念,因此任何打算与索引一起使用的跨数据类型操作符都必须直接绑定到该索引的操作符类中。虽然这种做法仍然有效,但已经废弃,因为它会使索引的依赖关系过于宽泛,而且当两种数据类型都在同一操作符族中拥有操作符时,规划器能更有效地处理跨数据类型比较。 + 在 PostgreSQL 8.3 之前,并没有操作符族这一概念,因此任何打算与索引一起使用的跨数据类型操作符都必须直接绑定到该索引的操作符类中。虽然这种做法仍然有效,但已被弃用,因为它会使索引的依赖关系过于宽泛,而且当两种数据类型都在同一操作符族中拥有操作符时,规划器能更有效地处理跨数据类型比较。 @@ -837,7 +848,7 @@ ALTER OPERATOR FAMILY integer_ops USING btree ADD 系统对操作符类的依赖 - ordering operator + 排序操作符 @@ -845,7 +856,7 @@ ALTER OPERATOR FAMILY integer_ops USING btree ADD - 特别地,ORDER BYDISTINCT等 SQL 特性要求对值的比较和排序。为了在用户定义的数据类型上实现这些特性,PostgreSQL会为数据类型查找默认 B-树操作符类。这个操作符类的equals成员定义了用于GROUP BYDISTINCT的值的等值概念,而该操作符类施加的排序顺序定义了默认的ORDER BY顺序。 + 特别地,ORDER BYDISTINCT等 SQL 特性要求对值的比较和排序。为了在用户定义的数据类型上实现这些特性,PostgreSQL会为数据类型查找默认 B-树操作符类。这个操作符类的相等成员定义了用于GROUP BYDISTINCT的值的等值概念,而该操作符类施加的排序顺序定义了默认的ORDER BY顺序。 @@ -871,11 +882,11 @@ SELECT * FROM mytable ORDER BY somecol USING ~<~; - 用户定义类型的数组比较也依赖于该类型默认 B-树操作符类所定义的语义。如果没有默认 B-树操作符类,但有默认的哈希操作符类,则支持数组相等比较,但不支持顺序比较。 + 用户定义类型的数组比较也依赖于该类型默认 B-树操作符类所定义的语义。如果没有默认 B-树操作符类,但有默认的哈希操作符类,则支持数组相等比较,但不支持排序比较。 - 另一种需要更多数据类型相关知识的 SQL 特性,是窗口函数中的 RANGE offset PRECEDING/FOLLOWING 框架选项(见)。对于下面这样的查询 + 另一种需要更多数据类型相关知识的 SQL 特性,是窗口函数中的 RANGE offset PRECEDING/FOLLOWING 帧选项(见)。对于下面这样的查询 SELECT sum(x) OVER (ORDER BY x RANGE BETWEEN 5 PRECEDING AND 10 FOLLOWING) FROM mytable; @@ -903,7 +914,7 @@ SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10; 可以找到距离指定目标点最近的十个地点。location 列上的 GiST 索引能够高效完成此操作,因为<->是排序操作符。 - 搜索操作符必须返回布尔结果,而排序操作符通常返回其他类型的结果,例如表示距离的浮点数或数值。这种类型通常不同于被索引的数据类型。为了避免对不同数据类型行为作硬编码假设,在定义排序操作符时,必须指定一个 B-树操作符族,用来说明结果数据类型的排序顺序。正如上一节所述,B-树操作符族定义了 PostgreSQL 的顺序概念,因此这是一种自然的表示方式。由于点的 <-> 操作符返回 float8,因此可以在创建操作符类时这样指定它: + 搜索操作符必须返回布尔结果,而排序操作符通常返回其他类型的结果,例如用于表示距离的 float 或 numeric。这种类型通常不同于被索引的数据类型。为了避免对不同数据类型行为作硬编码假设,在定义排序操作符时,必须指定一个 B-树操作符族,用来说明结果数据类型的排序顺序。正如上一节所述,B-树操作符族定义了 PostgreSQL 的顺序概念,因此这是一种自然的表示方式。由于点的 <-> 操作符返回 float8,因此可以在创建操作符类时这样指定它: (point, point) FOR ORDER BY float_ops ]]> @@ -916,7 +927,7 @@ OPERATOR 15 <-> (point, point) FOR ORDER BY float_ops 操作符类的特殊特性 - 还有两个操作符类的特殊特性我们尚未讨论,主要是因为它们对最常用的索引方法并不太有用。 + 还有两个操作符类的特殊特性我们尚未讨论,主要是因为它们对最常用的索引方法没有用处。 @@ -932,7 +943,7 @@ CREATE OPERATOR CLASS polygon_ops DEFAULT FOR TYPE polygon USING gist AS ... STORAGE box; -目前,只有 GiST、GIN 和 BRIN 索引方法支持与列数据类型不同的STORAGE类型。GiST 的compressdecompress支持函数在使用STORAGE时必须处理数据类型转换。在 GIN 中,STORAGE类型标识key值的类型,通常与被索引列的类型不同。例如,整数数组列的操作符类可以只使用整数作为键。GIN 的extractValueextractQuery支持函数负责从被索引值中提取键。BRIN 与 GIN 类似:STORAGE类型标识所存储摘要值的类型,而操作符类的支持函数负责正确解释这些摘要值。 +目前,只有 GiST、GIN 和 BRIN 索引方法支持与列数据类型不同的STORAGE类型。GiST 的compressdecompress支持函数在使用STORAGE时必须处理数据类型转换。在 GIN 中,STORAGE类型标识值的类型,通常与被索引列的类型不同。例如,整数数组列的操作符类可以只使用整数作为键。GIN 的extractValueextractQuery支持函数负责从被索引值中提取键。BRIN 与 GIN 类似:STORAGE类型标识所存储摘要值的类型,而操作符类的支持函数负责正确解释这些摘要值。 diff --git a/zh/11/xml2.sgml b/zh/11/xml2.sgml index 8b9b8344..33b00e73 100644 --- a/zh/11/xml2.sgml +++ b/zh/11/xml2.sgml @@ -1,7 +1,7 @@ - xml2 — XPath 查询与 XSLT 功能 + xml2 xml2 @@ -43,7 +43,7 @@ bool - 此函数解析其参数中的文档文本,如果文档是格式良好的 XML,则返回 true。(注意:这是标准 PostgreSQL 函数 xml_is_well_formed() 的别名。由于 XML 中有效性和格式良好性具有不同含义,函数名 xml_valid() 在技术上并不正确。) + 此函数解析其参数中的文档文本,如果文档是良构 XML,则返回 true。(注意:这是标准 PostgreSQL 函数 xml_is_well_formed() 的别名。由于 XML 中有效性和良构性具有不同含义,函数名 xml_valid() 在技术上并不正确。) @@ -83,7 +83,7 @@ 该函数计算文档上的查询,并将结果封装在 XML 标签中。如果结果有多个值,输出将如下所示: <toptag> -<itemtag>Value 1 which could be an XML fragment</itemtag> +<itemtag>Value 1(可以是 XML 片段)</itemtag> <itemtag>Value 2....</itemtag> </toptag> 如果toptagitemtag为空字符串,就会省略相应的标签。 @@ -169,7 +169,7 @@ xpath_table(text key, text document, text relation, text xpaths, text criteria) key - key 字段的名称 — 这只是一个作为输出表第一列使用的字段,也就是说,它用于标识每个输出行来自哪条记录(关于多个值,见下文注释) + 字段的名称 — 这只是一个作为输出表第一列使用的字段,也就是说,它用于标识每个输出行来自哪条记录(关于多个值,见下文注释) @@ -200,7 +200,9 @@ xpath_table(text key, text document, text relation, text xpaths, text criteria) criteria - WHERE 子句的内容。这一项不能省略,因此如果你想处理该关系中的所有行,请使用 true1=1 + + WHERE 子句的内容。这一项不能省略,因此如果你想处理该表或视图中的所有行,请使用 true1=1 + @@ -228,7 +230,7 @@ xpath_table('article_id', 'date_entered > ''2003-01-01'' ') AS t(article_id integer, author text, page_count integer, title text); - AS 子句定义了输出表中各列的名称和类型。第一列是 key 字段,其余各列对应 XPath 查询。如果 XPath 查询多于结果列,多出的查询将被忽略。如果结果列多于 XPath 查询,多出的列将为 NULL。 + AS 子句定义了输出表中各列的名称和类型。第一列是 字段,其余各列对应 XPath 查询。如果 XPath 查询多于结果列,多出的查询将被忽略。如果结果列多于 XPath 查询,多出的列将为 NULL。 @@ -257,7 +259,7 @@ WHERE t.author_id = p.person_id; - 在某些情况下,用户会知道某个 XPath 查询只会返回单个结果(例如唯一文档标识符)— 如果它与返回多个结果的 XPath 查询一起使用,这个单值结果只会出现在结果的第一行。解决办法是把 key 字段作为与一个更简单的 XPath 查询结果进行连接的条件之一。例如: + 在某些情况下,用户会知道某个 XPath 查询只会返回单个结果(例如唯一文档标识符)— 如果它与返回多个结果的 XPath 查询一起使用,这个单值结果只会出现在结果的第一行。解决办法是把键字段作为与一个更简单的 XPath 查询结果进行连接的条件之一。例如: CREATE TABLE test ( diff --git a/zh/11/xoper.sgml b/zh/11/xoper.sgml index d2b97103..257dee66 100644 --- a/zh/11/xoper.sgml +++ b/zh/11/xoper.sgml @@ -23,7 +23,12 @@ 哪个操作符。 - 下面是创建一个用于将两个复数相加的操作符的示例。假定我们已经创建了类型complex的定义(见)。首先需要一个完成实际工作的函数,然后就可以定义操作符: + + 下面是为两个复数相加创建一个操作符的示例。我们假设已经创建了 + complex类型的定义(见)。首先需要 + 一个完成实际工作的函数,然后才能定义该操作符: + + CREATE FUNCTION complex_add(complex, complex) RETURNS complex AS 'filename', 'complex_add' @@ -108,7 +113,7 @@ SELECT (a + b) AS c FROM test_complex; 转成 tab2.y = tab1.x,否则它就无法生成索引扫描,因为 索引扫描机制要求传给它的操作符左侧必须是已建立索引的列。 PostgreSQL 不会仅凭假 - 设就认为这种转换有效 — = 操作符的创建者必须通过为该操 + 设就认为这种转换有效;= 操作符的创建者必须通过为该操 作符标记交换子信息,明确声明这种转换是有效的。 @@ -162,10 +167,10 @@ SELECT (a + b) AS c FROM test_complex; <literal>RESTRICT</literal> - 如果给出 RESTRICT 子句,它指定该操作符的限制选择度估 + 如果给出 RESTRICT 子句,它指定该操作符的限制选择率估 算函数。(注意,这里是函数名,而不是操作符名。) RESTRICT 子句只对返回 boolean 的二元操 - 作符有意义。限制选择度估算器的作用,是针对当前操作符和某个特定常量值, + 作符有意义。限制选择率估算器的作用,是针对当前操作符和某个特定常量值, 猜测一张表中有多少比例的行会满足如下形式的 WHERE 子句条件: @@ -177,9 +182,9 @@ column OP constant - 编写新的限制选择度估算函数远远超出了本章的范围,不过幸运的是,对于你自 + 编写新的限制选择率估算函数远远超出了本章的范围,不过幸运的是,对于你自 己的很多操作符,通常都可以直接使用系统提供的某个标准估算器。标准的限制 - 选择度估算器如下: + 选择率估算器如下: eqsel 用于 = neqsel 用于 <> @@ -191,7 +196,7 @@ column OP constant - 对于选择度非常高或非常低的操作符,即使它们实际上并不是真正的相等或不等 + 对于选择率非常高或非常低的操作符,即使它们实际上并不是真正的相等或不等 比较,你也常常可以勉强使用 eqselneqsel。例如,几何类型中的近似相等操作符就使用 eqsel,其依据是它们通常只会匹配表中很小一部分项。 @@ -211,7 +216,7 @@ column OP constant src/backend/utils/adt/geo_selfuncs.c 中,还为几 - 何操作符提供了其他选择度估算函数:areasel、 + 何操作符提供了其他选择率估算函数:areaselpositionselcontsel。截至 目前,这些函数都还只是桩实现,但你也许仍会想使用它们(或者更好的是,改 进它们)。 @@ -222,9 +227,9 @@ column OP constant <literal>JOIN</literal> - 如果给出 JOIN 子句,它指定该操作符的连接选择度估算函 + 如果给出 JOIN 子句,它指定该操作符的连接选择率估算函 数。(注意,这里是函数名,而不是操作符名。)JOIN 子 - 句只对返回 boolean 的二元操作符有意义。连接选择度估算器的 + 句只对返回 boolean 的二元操作符有意义。连接选择率估算器的 作用,是针对当前操作符,猜测两张表中有多少比例的行对会满足如下形式的 WHERE 子句条件: @@ -293,7 +298,7 @@ table1.column1 OP table2.column2 一个可参与哈希连接的操作符,必须拥有一个交换子(如果两侧操作数数据类型 - 相同,则可以是它自身;如果不同,则应是相关的相等操作符),并且该交换子 + 相同,则为它自身;如果不同,则应是相关的相等操作符),并且该交换子 也必须出现在同一个操作符族中。否则,在使用该操作符时可能会发生规划器错 误。另外,对于支持多种数据类型的哈希操作符族,最好(虽然并非严格必需) 为每一种数据类型组合都提供相等操作符;这样可以获得更好的优化效果。 @@ -330,7 +335,7 @@ table1.column1 OP table2.column2 - 归并连接的基本思想,是先把左表和右表分别排序,然后并行扫描它们。因此, + 归并连接的基本思想,是先把左表和右表分别排序,然后同步扫描它们。因此, 两种数据类型都必须能够被完全排序,而连接操作符必须只能在那对值位于排序 次序中同一位置时才成功。实际效果上,这意味着连接操作符 必须表现得像相等比较一样。不过,只要两种不同的数据类型在逻辑上兼容,也 @@ -350,7 +355,7 @@ table1.column1 OP table2.column2 一个可参与归并连接的操作符,必须拥有一个交换子(如果两侧操作数数据类型 - 相同,则可以是它自身;如果不同,则应是相关的相等操作符),并且该交换子 + 相同,则为它自身;如果不同,则应是相关的相等操作符),并且该交换子 也必须出现在同一个操作符族中。否则,在使用该操作符时可能会发生规划器错 误。另外,对于支持多种数据类型的 btree 操作符族,最 好(虽然并非严格必需)为每一种数据类型组合都提供相等操作符;这样可以获 diff --git a/zh/11/xplang.sgml b/zh/11/xplang.sgml index 892dd017..a39dcbcd 100644 --- a/zh/11/xplang.sgml +++ b/zh/11/xplang.sgml @@ -158,7 +158,7 @@ CREATE TRUSTED PROCEDURAL LANGUAGE plperl 在默认的PostgreSQL安装中, PL/pgSQL语言的调用处理器会被构建并安装到 - library目录中;此外, + 目录中;此外, PL/pgSQL语言本身也安装在所有数据库中。如 果在构建时配置了Tcl支持,那么 PL/TclPL/TclU diff --git a/zh/11/xtypes.sgml b/zh/11/xtypes.sgml index 2d231c34..866d5410 100644 --- a/zh/11/xtypes.sgml +++ b/zh/11/xtypes.sgml @@ -213,7 +213,7 @@ CREATE TYPE complex ( 如果数据类型的内部表示是可变长度的,则这种内部表示必须遵循可变长度数 据的标准布局:前四个字节必须是一个从不直接访问的char[4] 字段(惯例上命名为vl_len_)。必须使用 - SET_VARSIZE()宏在该字段中存储该值的总大小(包括 + SET_VARSIZE()宏在该字段中存储该 datum 的总大小(包括 长度字段本身),并使用VARSIZE()取回它。(这些宏 之所以存在,是因为长度字段可能会随平台不同而采用编码形式。) @@ -255,7 +255,7 @@ CREATE TYPE complex ( PG_DETOAST_DATUM_PACKED(通常通过定义 GETARG_DATATYPE_PP宏来隐藏),并使用 VARSIZE_ANY_EXHDRVARDATA_ANY - 宏访问一个可能采用打包形式的值。再次注意,即使数据类型定义指定了 + 宏访问一个可能采用打包形式的 datum。再次注意,即使数据类型定义指定了 对齐方式,这些宏返回的数据也不是对齐的。如果对齐很重要,就必须使用常 规的PG_DETOAST_DATUM接口。 @@ -266,8 +266,7 @@ CREATE TYPE complex ( 较旧的代码常把vl_len_声明为 int32字段,而不是char[4]字段。只要结构体定 义中还有其他至少按int32对齐的字段,这样做是可以的。但 - 在处理可能未对齐的值时使用这种结构体定义就很危险;编译器可能据此假定该 - 值实际上是对齐的,从而在对齐要求严格的体系结构上导致核心转储。 + 在处理可能未对齐的 datum 时使用这种结构体定义就很危险;编译器可能据此假定该 datum 实际上是对齐的,从而在对齐要求严格的体系结构上导致核心转储。 diff --git a/zh/12/adminpack.sgml b/zh/12/adminpack.sgml index e59876e1..71c32886 100644 --- a/zh/12/adminpack.sgml +++ b/zh/12/adminpack.sgml @@ -19,7 +19,7 @@ <filename>adminpack</filename> 函数 - Name 返回类型 + 名称 返回类型 描述 @@ -61,7 +61,7 @@ pg_file_rename - pg_file_rename重命名文件。如果省略archivename或其值为 NULL,则它只是将oldname重命名为newname(后者必须尚不存在)。如果提供了archivename,它会先将newname重命名为archivename(后者必须尚不存在),然后再将oldname重命名为newname。如果第二个重命名步骤失败,它会在报告错误之前尝试将archivename再改回newname。成功时返回 true;如果源文件不存在或不可写,则返回 false;其他情况会抛出错误。 + pg_file_rename重命名文件。如果省略archivename或其值为空值,则它只是将oldname重命名为newname(后者必须尚不存在)。如果提供了archivename,它会先将newname重命名为archivename(后者必须尚不存在),然后再将oldname重命名为newname。如果第二个重命名步骤失败,它会在报告错误之前尝试将archivename再改回newname。成功时返回 true;如果源文件不存在或不可写,则返回 false;其他情况会抛出错误。 diff --git a/zh/12/amcheck.sgml b/zh/12/amcheck.sgml index 75a900e8..5e92ee3d 100644 --- a/zh/12/amcheck.sgml +++ b/zh/12/amcheck.sgml @@ -166,7 +166,7 @@ ORDER BY c.relpages DESC LIMIT 10; 这也包括因操作系统排序规则的比较规则发生变化而引起的问题。 - 像text这类可排序类型的数据值之间的比较必须是不可变的 + 像text这类支持排序规则的类型的 datum 之间的比较必须是不可变的 (正如用于 B-树索引扫描的所有比较都必须不可变一样), 这就意味着操作系统排序规则绝不能发生变化。 虽然这种情况比较少见,但操作系统排序规则的更新确实可能导致此类问题。 @@ -240,12 +240,10 @@ ORDER BY c.relpages DESC LIMIT 10; 修复损坏 - 请注意,如果访问某个块时只是命中了共享缓冲区, - 那么amcheck检查的是验证时该页面在某个共享内存缓冲区中的表示。 - 因此,amcheck并不一定会检查验证时从文件系统读入的数据。 - 另请注意,当启用了校验和时,如果某个损坏块被读入缓冲区, - amcheck可能会因为校验和失败而引发错误。 - + amcheck报告的与损坏有关的错误绝不应被当作误报。 + amcheck会在那些按定义绝不应该发生的情况下抛出错误, + 因此通常需要对这类错误进行仔细分析。 + 对于amcheck检测到的问题,并不存在通用的修复方法。 应当查明导致不变式遭到破坏的根本原因。 diff --git a/zh/12/auth-delay.sgml b/zh/12/auth-delay.sgml index c0146092..652355f9 100644 --- a/zh/12/auth-delay.sgml +++ b/zh/12/auth-delay.sgml @@ -1,7 +1,7 @@ - auth_delay — 在认证失败时暂停 + auth_delay auth_delay diff --git a/zh/12/backup.sgml b/zh/12/backup.sgml index 2b142c47..62c703b2 100644 --- a/zh/12/backup.sgml +++ b/zh/12/backup.sgml @@ -3,7 +3,7 @@ 备份和恢复 - backup + 备份 与任何保存重要数据的系统一样,PostgreSQL数据库也应定期备份。虽然其过程基本简单,但清楚理解其底层技术和前提假设非常重要。 @@ -61,11 +61,17 @@ psql dbname < - 默认情况下,psql 在遇到 SQL 错误后仍会继续执行脚本。可以在运行 psql 时设置 ON_ERROR_STOP 变量来改变这一行为,让 psql 在发生 SQL 错误时以退出状态 3 退出: + + 默认情况下,psql脚本在遇到 SQL 错误后仍会继续执行。你可能希望让psql在设置了ON_ERROR_STOP变量的情况下运行,以改变这一行为,并让psql在发生 SQL 错误时以退出状态码 3 退出: + psql --set ON_ERROR_STOP=on dbname < dumpfile -不论采用哪种方式,最终都只会得到部分恢复的数据库。另一种做法是指定将整个转储作为一个事务恢复,这样恢复要么全部完成,要么全部回滚。可通过将命令行选项 传递给 psql 来指定这种模式。使用该模式时要注意,即使是很小的错误,也可能使已经运行数小时的恢复全部回滚。不过,这可能仍比在部分恢复转储后手动清理复杂的数据库更好。 + + 无论采用上述哪种方式,你最终只会得到一个部分恢复的数据库。另一种做法是指定将整个转储作为单个事务恢复,这样恢复要么全部完成,要么全部回滚。可以通过把命令行选项传给psql来启用这种模式。使用这种模式时要注意,即便是一个很小的错误,也可能回滚一个已经运行了许多小时的恢复过程。不过,这仍可能比在部分恢复后手工清理一个复杂数据库更可取。 + - 利用 pg_dumppsql 向管道写入或从管道读取的能力,可以直接将数据库从一台服务器转储到另一台,例如: + + pg_dumppsql能够写入或读取管道,这使得可以把数据库直接从一台服务器转储到另一台服务器,例如: + pg_dump -h host1 dbname | psql -h host2 dbname @@ -85,12 +91,16 @@ pg_dump -h host1 dbname | 使用<application>pg_dumpall</application> - pg_dump 每次只转储一个数据库,不转储角色或表空间信息(因为它们属于整个集簇,而非某个数据库)。为了便于转储数据库集簇的全部内容,系统提供了 程序。pg_dumpall 会备份给定集簇中的每个数据库,并保留角色和表空间定义等集簇级数据。该命令的基本用法如下: + pg_dump一次只转储一个数据库,而且不会转储角色或表空间的信息(因为这些是整个集簇级别的,而不是每个数据库各自的)。为了方便地转储整个数据库集簇的全部内容,提供了程序。pg_dumpall会备份给定集簇中的每个数据库,并保留角色定义和表空间定义等集簇范围的数据。该命令的基本用法是: + pg_dumpall > dumpfile -要恢复生成的转储,可以使用 psql: + + 生成的转储可以用psql恢复: psql -f dumpfile postgres -(实际上,可以指定任何已存在的数据库名作为起点;但如果装载到空集簇中,通常应使用 postgres。)恢复 pg_dumpall 转储时,必须具有数据库超级用户权限,因为恢复角色和表空间信息需要这些权限。如果使用了表空间,请确保转储中的表空间路径适合新的安装环境。 + + (实际上,可以指定任意一个现有数据库名作为起点,但如果要装载到一个空集簇中,通常应使用postgres。)恢复pg_dumpall转储时始终需要数据库超级用户权限,因为恢复角色和表空间信息必须使用该权限。如果使用了表空间,请确保转储中的表空间路径适合新的安装。 + pg_dumpall的工作方式是先发出重新创建角色、表空间和空数据库的命令,然后针对每个数据库调用pg_dump。这意味着每个数据库本身都是内部一致的,但不同数据库的快照并不同步。 @@ -176,7 +186,7 @@ pg_restore -d dbname - 对于非常大的数据库,你可能需要把split与前两种方法之一结合使用。 + 对于非常大的数据库,你可能需要把split与另外两种方法之一结合使用。 @@ -232,7 +242,7 @@ tar -cf backup.tar /usr/local/pgsql/data - 如果无法获得同时的快照,一种选择是将数据库服务器关闭足够长的时间,以建立所有冻结快照。另一种选择是执行持续归档基础备份(),因为这种备份不受备份期间文件系统变化的影响。这要求只在备份过程中启用持续归档;恢复则使用持续归档恢复()。 + 如果无法获得同时的快照,一种选择是将数据库服务器关闭足够长的时间,以建立所有冻结快照。另一种选择是执行持续归档基础备份(),因为这种备份不受备份期间文件系统变化的影响。这种方法只需在备份期间启用持续归档;恢复则使用持续归档恢复()。 @@ -248,11 +258,11 @@ tar -cf backup.tar /usr/local/pgsql/data 持续归档和时间点恢复(PITR) - continuous archiving + 持续归档 - point-in-time recovery + 时间点恢复 @@ -292,7 +302,7 @@ tar -cf backup.tar /usr/local/pgsql/data - 和普通文件系统备份技术一样,这种方法只能支持整个数据库集簇的恢复,而不支持其中某个子集的恢复。此外,它需要大量归档存储:基础备份可能很庞大,繁忙系统也会产生大量必须归档的 WAL 流量。尽管如此,在很多需要高可靠性的场景中,它仍是首选的备份技术。 + 和普通文件系统备份技术一样,这种方法只能支持整个数据库集簇的恢复,而不支持其中某个子集的恢复。此外,它需要大量归档存储:基础备份可能很庞大,繁忙系统也会产生许多兆字节的、必须归档的 WAL 流量。尽管如此,在很多需要高可靠性的场景中,它仍是首选的备份技术。 @@ -307,7 +317,7 @@ tar -cf backup.tar /usr/local/pgsql/data - 在归档 WAL 数据时,我们需要在每个段文件写满后捕获其内容,并在该段文件被回收重用之前把数据保存到某处。根据应用场景和可用硬件的不同,把数据保存到某处可以有很多不同的方法:可以把段文件复制到另一台机器上的 NFS 挂载目录,把它们写到磁带机中(确保你有办法识别每个文件的原始文件名),把它们批量打包后刻录到 CD 上,或者采用完全不同的方式。为了给数据库管理员提供灵活性,PostgreSQL尽量不对归档方式作任何假设。相反,PostgreSQL允许管理员指定一个 shell 命令或一个归档库,以便把已完成的段文件复制到它应去的地方。这既可以只是一个使用cp的 shell 命令,也可以调用一个复杂的 C 函数,全由你决定。 + 在归档 WAL 数据时,我们需要在每个段文件写满后捕获其内容,并在该段文件被回收重用之前把数据保存到某处。根据应用场景和可用硬件的不同,把数据保存到某处可以有很多不同的方法:可以把段文件复制到另一台机器上的 NFS 挂载目录,把它们写到磁带机中(确保你有办法识别每个文件的原始文件名),把它们批量打包后刻录到 CD 上,或者采用完全不同的方式。为了给数据库管理员提供灵活性,PostgreSQL尽量不对归档方式作任何假设。相反,PostgreSQL允许管理员指定一个 shell 命令,以便把已完成的段文件复制到它应去的地方。该命令可以只是一次简单的cp调用,也可以调用一个复杂的 shell 脚本,全由你决定。 要启用 WAL 归档,请将 配置参数设为 replica 或更高值,将 设为 on,并在 通常应将归档命令设计为拒绝覆盖任何已存在的归档文件。这是一项重要的安全保护措施,能在管理员操作失误时(例如将两台不同服务器的输出发送到同一归档目录)维护归档的完整性。 - 建议测试所拟定的归档命令,确保它确实不会覆盖已有文件,并且在这种情况下返回非零状态。上面给出的 Unix 示例命令通过单独加入一个test步骤,避免覆盖已有归档。在某些 Unix 平台上,cp提供了诸如之类的开关,也可以更简洁地实现同样目的,但在你确认它会返回正确的退出状态之前,不应依赖这些开关。(尤其是 GNU cp在使用且目标文件已存在时会返回状态零,这不是我们想要的行为。) + 建议测试所拟定的归档命令,确保它确实不会覆盖已有文件,并且在这种情况下返回非零状态。上面给出的 Unix 示例命令通过单独加入一个test步骤,确保这两点。在某些 Unix 平台上,cp提供了诸如之类的开关,也可以更简洁地实现同样目的,但在你确认它会返回正确的退出状态之前,不应依赖这些开关。(尤其是 GNU cp在使用且目标文件已存在时会返回状态零,这不是我们想要的行为。) - 在设计归档方案时,请考虑如果归档命令或归档库因为某些环节需要操作员干预,或者归档空间耗尽而反复失败,会发生什么。例如,如果你在没有自动换带器的情况下向磁带写入数据,那么磁带满了以后,在更换磁带之前将无法继续归档。你应确保任何错误情况或对人工操作员的请求都能得到适当报告,以便问题能够比较快地解决。在问题解决之前,pg_wal/目录会继续堆积 WAL 段文件。(如果包含pg_wal/的文件系统被写满,PostgreSQL将执行 PANIC 关闭。不会丢失已提交的事务,但在释放出一些空间之前,数据库会一直离线。) + 在设计归档方案时,请考虑如果归档命令因为某些环节需要操作员干预,或者归档空间耗尽而反复失败,会发生什么。例如,如果你在没有自动换带器的情况下向磁带写入数据,那么磁带满了以后,在更换磁带之前将无法继续归档。你应确保任何错误情况或对人工操作员的请求都能得到适当报告,以便问题能够比较快地解决。在问题解决之前,pg_wal/目录会继续堆积 WAL 段文件。(如果包含pg_wal/的文件系统被写满,PostgreSQL将执行 PANIC 关闭。不会丢失已提交的事务,但在释放出一些空间之前,数据库会一直离线。) - 归档命令或归档库的速度并不重要,只要它能跟上服务器生成 WAL 数据的平均速度即可。即使归档过程稍有滞后,正常操作也会继续。如果归档明显落后,灾难发生时可能丢失的数据量就会增加。这还意味着pg_wal/目录会包含大量尚未归档的段文件,最终可能耗尽可用磁盘空间。建议监控归档过程,确保它按你的预期工作。 + 归档命令的速度并不重要,只要它能跟上服务器生成 WAL 数据的平均速度即可。即使归档过程稍有滞后,正常操作也会继续。如果归档明显落后,灾难发生时可能丢失的数据量就会增加。这还意味着pg_wal/目录会包含大量尚未归档的段文件,最终可能耗尽可用磁盘空间。建议监控归档过程,确保它按你的预期工作。 - 在编写归档命令或归档库时,应假定待归档文件名最长可达 64 个字符,并且可以包含 ASCII 字母、数字和点号的任意组合。无需保留原始相对路径(%p),但必须保留文件名(%f)。 + 在编写归档命令时,应假定待归档文件名最长可达 64 个字符,并且可以包含 ASCII 字母、数字和点号的任意组合。无需保留原始相对路径(%p),但必须保留文件名(%f)。 注意,虽然 WAL 归档允许你恢复对PostgreSQL数据库中数据所做的任何修改,但它不会恢复对配置文件(即postgresql.confpg_hba.confpg_ident.conf)的修改,因为这些文件是手工编辑的,而不是通过 SQL 操作修改的。你可能希望把配置文件放在常规文件系统备份过程能够覆盖的位置。关于如何重定位配置文件,见 - 归档命令只会在已完成的 WAL 段上调用。因此,如果服务器产生的 WAL 流量很小(或者存在这样的低谷期),事务完成到其被安全写入归档存储之间可能会有很长延迟。为了限制未归档数据的最长滞留时间,可以设置 ,强制服务器至少每隔这么长时间切换到一个新的 WAL 段文件。注意,由强制切换而提前归档的文件长度仍与装满的文件相同。因此,把 archive_timeout 设得很短并不明智,这会使归档存储膨胀。将 archive_timeout 设为大约一分钟通常是合理的。 + + 归档命令只会针对已完成的 WAL 段调用。因此,如果服务器产生的 WAL 流量很小(或者存在低谷期),事务完成到其被安全写入归档存储之间可能会有很长延迟。为了限制未归档数据可能有多旧,你可以设置,使服务器强制切换到新 WAL 段文件的间隔不超过这个值。注意,由强制切换而提前归档的文件长度仍与装满的文件相同。因此,把archive_timeout设得很短并不明智,这会使归档存储膨胀。archive_timeout设为大约 1 分钟通常是合理的。 + 此外,如果你希望确保一个刚刚完成的事务尽快被归档,可以使用pg_switch_wal手工强制一次段切换。其他与 WAL 管理相关的实用函数列在中。 - 当wal_levelminimal时,某些 SQL 命令会像中所述那样被优化为避免 WAL 记录。如果在执行这些语句期间启用了归档或流复制,WAL 将不包含归档恢复所需的足够信息。(崩溃恢复不受影响。)因此,wal_level只能在服务器启动时更改。然而,archive_command可以通过重新加载配置文件来更改。如果你通过 shell 进行归档并希望暂时停止归档,一种办法是将archive_command设置为空字符串('')。这会导致 WAL 文件在pg_wal/中累积,直到重新建立可用的archive_command。 + 当wal_levelminimal时,某些 SQL 命令会像中所述那样被优化为避免 WAL 记录。如果在执行这些语句期间启用了归档或流复制,WAL 将不包含归档恢复所需的足够信息。(崩溃恢复不受影响。)因此,wal_level只能在服务器启动时更改。然而,archive_command可以通过重新加载配置文件来更改。如果你希望暂时停止归档,一种办法是将archive_command设置为空字符串('')。这会导致 WAL 文件在pg_wal/中累积,直到重新建立可用的archive_command @@ -381,7 +393,7 @@ test ! -f /mnt/server/archivedir/00000001000000A900000065 && cp pg_wal/0 - 使用低级接口进行基础备份 + 使用低级 API 进行基础备份 使用低级 API 制作基础备份的过程,比 方法多几个步骤,但相对简单。务必按顺序执行这些步骤,并在继续下一步之前确认当前步骤成功。 低级基础备份可以采用非排他或排他方式。建议使用非排他方式;排他方式已弃用,最终将被移除。 @@ -508,7 +520,9 @@ SELECT pg_stop_backup(); 使用持续归档备份进行恢复 - 如果最坏的情况已经发生,需要从备份恢复,请按以下流程操作: + + 现在,最坏的情况发生了,你需要通过备份进行恢复。步骤如下: + 如果服务器仍在运行,就先停止它。 @@ -526,7 +540,7 @@ SELECT pg_stop_backup(); - 如果你正在恢复完整备份,可以把数据库文件直接恢复到目标目录中。务必确保它们以正确的所有者(数据库系统用户,而不是root!)和正确的权限恢复。如果使用了表空间,还应验证pg_tblspc/中的符号链接是否已正确恢复。 + 从文件系统备份中恢复数据库文件。务必确保它们以正确的所有者(数据库系统用户,而不是root!)和正确的权限恢复。如果使用了表空间,还应验证pg_tblspc/中的符号链接是否已正确恢复。 @@ -557,16 +571,16 @@ SELECT pg_stop_backup(); - 整个过程的关键,是设置恢复配置,说明希望如何恢复,以及恢复到什么位置。必须指定的设置是 restore_command,它告诉 PostgreSQL 如何获取已归档的 WAL 段。与 archive_command 一样,它是一个 shell 命令字符串,可以包含 %f,该标记会被替换为所需日志文件的名称;还可以包含 %p,该标记会被替换为日志文件要复制到的路径名。(路径名相对于当前工作目录,即集簇的数据目录。)使用 %% 可以在命令中嵌入实际的 % 字符。最简单的可用命令类似于: + 整个过程的关键,是设置恢复配置,说明希望如何恢复,以及恢复到什么位置。必须指定的设置是 restore_command,它告诉 PostgreSQL 如何获取已归档的 WAL 段文件。与 archive_command 一样,它是一个 shell 命令字符串,可以包含 %f,该标记会被替换为所需日志文件的名称;还可以包含 %p,该标记会被替换为日志文件要复制到的路径名。(路径名相对于当前工作目录,即集簇的数据目录。)使用 %% 可以在命令中嵌入实际的 % 字符。最简单的可用命令类似于: restore_command = 'cp /mnt/server/archivedir/%f %p' 这会复制先前归档的 WAL 段,来源目录为 /mnt/server/archivedir。当然,也可以使用复杂得多的命令,甚至可以使用要求操作人员挂载相应磁带的 shell 脚本。 - 重要的是,该命令在失败时必须返回非零退出状态。系统调用该命令来请求归档中不存在的文件;遇到这种情况时,它就应返回非零值。这不是一种错误情况。例外是,如果该命令被信号终止(用于数据库服务器关闭的SIGTERM除外),或者因 shell 错误(如命令未找到)而失败,那么恢复将中止,服务器也不会启动。 + 重要的是,该命令在失败时必须返回非零退出状态。系统调用该命令来请求归档中不存在的文件;遇到这种情况时,它必须返回非零值。这不是一种错误情况。例外是,如果该命令被信号终止(用于数据库服务器关闭的SIGTERM除外),或者因 shell 错误(如命令未找到)而失败,那么恢复将中止,服务器也不会启动。 - 被请求的文件并不全都是 WAL 段文件;你还应预期会收到对带有.history后缀文件的请求。另外请注意,%p路径的基本文件名会与%f不同;不要指望它们可以互换使用。 + 被请求的文件并不全都是 WAL 段文件;你还应预期会收到对带有.history后缀文件的请求。另外请注意,%p路径的文件名部分会与%f不同;不要指望它们可以互换使用。 @@ -574,16 +588,16 @@ restore_command = 'cp /mnt/server/archivedir/%f %p' - 通常,恢复会处理完所有可用的 WAL 段,从而把数据库恢复到当前时间点(或者在可用 WAL 段所允许的情况下尽可能接近当前时间点)。因此,一次正常恢复通常会以一条file not found消息结束,具体错误文本取决于你选择的restore_command。在恢复开始时,你也可能看到一条针对类似00000001.history文件的错误消息。这同样是正常的,在简单恢复场景中并不表示有问题;相关讨论见。 + 通常,恢复会处理完所有可用的 WAL 段,从而把数据库恢复到当前时间点(或者在可用 WAL 段所允许的情况下尽可能接近当前时间点)。因此,一次正常恢复会以一条file not found消息结束,具体错误文本取决于你选择的restore_command。在恢复开始时,你也可能看到一条针对类似00000001.history文件的错误消息。这同样是正常的,在简单恢复场景中并不表示有问题;相关讨论见 - 如果你希望恢复到过去的某个时间点(例如恢复到那位初级 DBA 删掉你的主事务表之前),只需指定所需的停止点即可。这个停止点也称为恢复目标,可以通过日期/时间、命名恢复点或者某个特定事务 ID 完成时刻来指定。在目前的实现下,只有日期/时间和命名恢复点这两种方式真正比较实用,因为没有工具能够帮助你足够准确地识别应使用哪个事务 ID。 + 如果你希望恢复到过去的某个时间点(例如恢复到那位初级 DBA 删掉你的主事务表之前),只需指定所需的停止点即可。这个停止点也称为恢复目标,可以通过日期/时间、命名恢复点或者某个特定事务 ID 完成时刻来指定。在撰写本文时,只有日期/时间和命名恢复点这两种方式真正比较实用,因为没有工具能够帮助你足够准确地识别应使用哪个事务 ID。 - 停止点必须晚于基础备份的结束时间,也就是pg_stop_backup的结束时间。你不能用某次基础备份恢复到该备份仍在进行中的时间点。(若要恢复到这样的时间点,必须回到更早的一次基础备份,再从那里向前滚动。) + 停止点必须晚于基础备份的结束时间,也就是pg_stop_backup的结束时间。你不能用某次基础备份恢复到该备份仍在进行中的时间点。(若要恢复到这样的时间点,必须回到更早的一次基础备份,再从那里向前重放日志。) @@ -597,14 +611,16 @@ restore_command = 'cp /mnt/server/archivedir/%f %p' 时间线 - timelines + 时间线 能够将数据库恢复到过去某个时间点,也会带来一些类似科幻故事中时间旅行和平行宇宙的复杂情况。例如,假设在数据库原来的历史中,你在周二下午 5:15 删除了一张重要的表,直到周三中午才发现错误。你从容地取出备份,将数据库恢复到周二下午 5:14,然后重新投入运行。在数据库宇宙的这段历史中,你从未删除过那张表。但假设你后来发现这样做不太合适,希望回到原来历史中的周三上午某个时刻。如果数据库恢复运行后覆盖了通往该时刻所需的某些 WAL 段文件,就无法回去了。因此,为了避免这种情况,需要区分时间点恢复后产生的一系列 WAL 记录与数据库原来历史中产生的记录。 为解决这一问题,PostgreSQL 引入了时间线的概念。每当归档恢复完成,系统都会创建一条新时间线,用于标识此次恢复之后产生的一系列 WAL 记录。时间线 ID 是 WAL 段文件名的一部分,因此新时间线不会覆盖旧时间线产生的 WAL 数据。实际上,可以归档许多不同的时间线。这个功能看似没什么用,却常常能救急。比如,你不能确定应该恢复到哪个时间点,需要反复尝试时间点恢复,直到找到脱离旧历史的最佳分支点。没有时间线,这个过程很快就会乱得无法管理。有了时间线,就可以恢复到任何先前的状态,包括早先已放弃的时间线分支中的状态。 - 每次创建新时间线时,PostgreSQL 都会创建一个时间线历史文件,记录它从哪条时间线、在何时分支出来。从包含多条时间线的归档中恢复时,系统需要这些历史文件来选择正确的 WAL 段文件。因此,历史文件与 WAL 段文件一样,也会归档到 WAL 归档区。历史文件只是很小的文本文件,长期保留成本很低,也很合适(不像体积很大的段文件)。如果愿意,可以在历史文件中添加注释,记录这条时间线是如何创建的,以及为什么创建它。当反复试验产生了许多交错的时间线时,这些注释会格外有用。 + + 每当创建一条新的时间线时,PostgreSQL都会创建一个时间线历史文件,记录它是从哪条时间线、在何时分叉出来的。当从包含多条时间线的归档中恢复时,这些历史文件对于系统选取正确的 WAL 段文件是必需的。因此,它们会像 WAL 段文件一样被归档到 WAL 归档区域。历史文件只是很小的文本文件,因此长期保存它们既便宜也合适(而段文件通常很大)。如果你愿意,还可以在历史文件中加入注释,记录创建这条时间线的方式和原因。当你因实验而积累出一批错综复杂的时间线时,这类注释会特别有价值。 + 默认的恢复行为是恢复到归档中找到的最新时间线。如果希望恢复到制作基础备份时的当前时间线,或者某条特定的子时间线(即希望返回到一次恢复尝试之后产生的某个状态),需要在 中指定 current 或目标时间线 ID。不能恢复到在基础备份之前就已分支出去的时间线。 @@ -617,14 +633,14 @@ restore_command = 'cp /mnt/server/archivedir/%f %p' - 单机热备份 + 独立热备份 - 可以利用PostgreSQL的备份设施生成单机热备份。这些备份不能用于时间点恢复,但它们的制作和恢复通常都比pg_dump转储快得多。(它们也比pg_dump转储大得多,因此在某些情况下速度优势可能会被抵消。) + 可以利用PostgreSQL的备份设施生成独立热备份。这些备份不能用于时间点恢复,但它们的制作和恢复通常都比pg_dump转储快得多。(它们也比pg_dump转储大得多,因此在某些情况下速度优势可能会被抵消。) - 和基础备份一样,生成单机热备份最简单的方法是使用工具。如果在调用它时包含-X参数,使用该备份所需的全部预写式日志都会自动包含在备份中,恢复该备份时也不需要额外动作。 + 和基础备份一样,生成独立热备份最简单的方法是使用工具。如果在调用它时包含-X参数,使用该备份所需的全部预写式日志都会自动包含在备份中,恢复该备份时也不需要额外动作。 如果复制备份文件时需要更大的灵活性,也可以使用更低级的流程制作独立热备份。要准备低级独立热备份,请确保将 wal_level 设为 replica 或更高值,将 archive_mode 设为 on,并配置一个 archive_command,使其仅在开关文件存在时执行归档。例如: @@ -665,7 +681,7 @@ archive_command = 'local_backup_script.sh "%p" "%f"' - 脚本中可能需要解决的需求示例包括: + 可以在脚本中处理的需求示例包括: @@ -674,7 +690,7 @@ archive_command = 'local_backup_script.sh "%p" "%f"' - 把 WAL 文件成批处理,使其每三个小时传输一次,而不是每生成一个就传一次 + 把 WAL 文件成批处理,使其每三个小时传输一次,而不是每次只传输一个 @@ -701,7 +717,10 @@ archive_command = 'local_backup_script.sh "%p" "%f"' 注意事项 - 撰写本文时,连续归档技术还有几个限制。这些限制可能会在未来版本中消除: + + 在撰写本文时,持续归档技术还存在若干局限。这些问题很可能会在未来版本中得到修复: + + 如果在进行基础备份时执行了命令,而该CREATE DATABASE所复制的模板数据库又在基础备份尚未结束时被修改,那么恢复时可能会把这些修改也传播到新建数据库中。这当然并不理想。为避免这种风险,最好在进行基础备份时不要修改任何模板数据库。 diff --git a/zh/12/brin.sgml b/zh/12/brin.sgml index c88f18ed..c4c1c36d 100644 --- a/zh/12/brin.sgml +++ b/zh/12/brin.sgml @@ -4,7 +4,7 @@ BRIN 索引 - index + 索引 BRIN @@ -25,8 +25,7 @@ - 如果索引中存储的摘要信息与查询条件相一致BRIN - 索引就可以通过常规位图索引扫描来满足查询,并返回每个范围内所有页上的全部元组。 + BRIN 索引可以通过常规位图索引扫描来满足查询;对于每个范围,如果索引中存储的摘要信息与查询条件相一致,就会返回该范围内所有页上的全部元组。 查询执行器负责重新检查这些元组,并丢弃不匹配查询条件的元组 — 换句话说,这些索引是有损的。 由于 BRIN 索引非常小,与顺序扫描相比,扫描索引只会带来很小的额外开销, 但可以避免扫描那些已知不包含匹配元组的大块表数据。 @@ -83,7 +82,7 @@ 当启用自动摘要时,一旦检测到向下一个块范围第一页的第一项执行了插入, - 就会向 autovacuum 发送请求,要求对该块范围执行定向摘要。 + 就会向 autovacuum 发送请求,要求对前一个块范围执行定向摘要。 该请求会在同一数据库中的某个 autovacuum 工作进程下一次结束运行时得到处理。 如果请求队列已满,该请求就不会被记录,并会向服务器日志发送一条消息: @@ -326,7 +325,7 @@ LOG: request for BRIN range summarization for index "brin_wi_idx" page 128 was range_inclusion_ops - any range type + 任意范围类型 << &< && &> >> @> <@ -|- = < <= = > >= @@ -451,20 +450,25 @@ LOG: request for BRIN range summarization for index "brin_wi_idx" page 128 was BrinOpcInfo *opcInfo(Oid type_oid) - 返回索引列摘要数据的内部信息。返回值必须指向一个由 palloc 分配的BrinOpcInfo,其定义如下: + + 返回被索引列的摘要数据的内部信息。返回值必须指向一个用 palloc 分配的 + BrinOpcInfo,其定义如下: + typedef struct BrinOpcInfo { - /* Number of columns stored in an index column of this opclass */ + /* 此操作符类在一个索引列中存储的列数 */ uint16 oi_nstored; - /* Opaque pointer for the opclass' private use */ + /* 供操作符类私有使用的不透明指针 */ void *oi_opaque; - /* Type cache entries of the stored columns */ + /* 所存储列的类型缓存条目 */ TypeCacheEntry *oi_typcache[FLEXIBLE_ARRAY_MEMBER]; } BrinOpcInfo; - BrinOpcInfo.oi_opaque可供操作符类函数使用,在索引扫描期间于各支持函数之间传递信息。 + BrinOpcInfo.oi_opaque + 可供操作符类例程在索引扫描期间于各个支持函数之间传递信息。 + @@ -625,62 +629,62 @@ typedef struct BrinOpcInfo 操作符策略 1 - left-of 操作符 + 位于左侧的操作符 操作符策略 4 操作符策略 2 - does-not-extend-to-the-right-of 操作符 + 不延伸到右侧的操作符 操作符策略 5 操作符策略 3 - overlaps 操作符 + 重叠操作符 操作符策略 4 - does-not-extend-to-the-left-of 操作符 + 不延伸到左侧的操作符 操作符策略 1 操作符策略 5 - right-of 操作符 + 位于右侧的操作符 操作符策略 2 - 操作符策略 6, 18 - same-as-or-equal-to 操作符 + 操作符策略 6、18 + 相同或等于操作符 操作符策略 7 - 操作符策略 7, 13, 16, 24, 25 - contains-or-equal-to 操作符 + 操作符策略 7、13、16、24、25 + 包含或等于操作符 - 操作符策略 8, 14, 26, 27 - is-contained-by-or-equal-to 操作符 + 操作符策略 8、14、26、27 + 被包含或等于操作符 操作符策略 3 操作符策略 9 - does-not-extend-above 操作符 + 不延伸到上方的操作符 操作符策略 11 操作符策略 10 - is-below 操作符 + 位于下方的操作符 操作符策略 12 操作符策略 11 - is-above 操作符 + 位于上方的操作符 操作符策略 9 操作符策略 12 - does-not-extend-below 操作符 + 不延伸到下方的操作符 操作符策略 10 diff --git a/zh/12/btree.sgml b/zh/12/btree.sgml index 653a142f..5b0ebd19 100644 --- a/zh/12/btree.sgml +++ b/zh/12/btree.sgml @@ -4,7 +4,7 @@ B-树索引 - index + 索引 B-树 @@ -18,10 +18,10 @@ - 由于每个 B-树 操作符类都会为其数据类型施加一种排序顺序,B-树 + 由于每个 B-树操作符类都会为其数据类型施加一种排序顺序,B-树 操作符类(更准确地说,是操作符族)已经成为 PostgreSQL 用来统一表示和理解排序语义的方式。因此,它们具备了一些超出单纯支持 - B-树 索引所需范围的特性,系统中某些与 btree AM + B-树索引所需范围的特性,系统中某些与 B-树 AM 相距甚远的部分也会利用它们。 @@ -55,7 +55,7 @@ - = 操作符必须是一种等价关系;也就是说,对于该数据类型的所有非空值 + = 操作符必须是一种等价关系;也就是说,对于该数据类型的所有非 null 值 ABC: @@ -93,7 +93,7 @@ - < 操作符必须是一种强排序关系;也就是说,对于所有非空值 + < 操作符必须是一种强排序关系;也就是说,对于所有非 null 值 ABC: @@ -123,7 +123,7 @@ - 此外,该顺序还是全序的;也就是说,对于所有非空值 + 此外,该顺序还是全序的;也就是说,对于所有非 null 值 AB: @@ -176,14 +176,14 @@ B-树支持函数 - 所示,btree 定义了一个必需支持函数和两个可选支持函数。 + 所示,B-树定义了一个必需支持函数和两个可选支持函数。 - 对于 B-树 操作符族为其提供比较操作符的每一种数据类型组合,都必须提供一个比较支持函数。该函数在 + 对于 B-树操作符族为其提供比较操作符的每一种数据类型组合,都必须提供一个比较支持函数。该函数在 pg_amproc 中注册,支持函数编号为 1,并且 amproclefttype/amprocrighttype 要等于该比较的左右数据类型(也就是与匹配操作符在 - pg_amop 中注册时相同的数据类型)。比较函数必须接受两个非空值 + pg_amop 中注册时相同的数据类型)。比较函数必须接受两个非 null 值 AB,并返回一个 int32 值,其值为 < 0、 @@ -192,12 +192,12 @@ < BA = BA - > B。不允许返回空值:该数据类型的所有值都必须可比较。示例见 + > B。不允许返回 null:该数据类型的所有值都必须可比较。示例见 src/backend/access/nbtree/nbtcompare.c - 如果参与比较的值属于可排序数据类型,则会通过标准的 + 如果参与比较的值属于支持排序规则的数据类型,则会通过标准的 PG_GET_COLLATION() 机制,把适当的排序规则 OID 传递给比较支持函数。 @@ -210,11 +210,11 @@ - in_range support functions + in_range 支持函数 - support functions + 支持函数 in_range @@ -230,14 +230,35 @@ offset 值进行加减。 - in_range函数必须具有以下签名: + + in_range 函数必须具有如下签名: + in_range(val type1, base type1, offset type2, sub bool, less bool) returns bool - valbase必须具有相同的类型,且该类型是操作符族支持的类型之一(即该操作符族为其提供排序顺序的类型)。但是,offset可以具有不同的类型,甚至可以是操作符族在其他方面不支持的类型。例如,内置的time_ops操作符族提供一个in_range函数,其中offset的类型为interval。操作符族可以提供in_range函数,用于其支持的任意类型与一种或多种offset类型的组合。每个in_range函数都应登记在pg_amproc中,并使amproclefttype等于type1amprocrighttype等于type2。 + val 和 + base 必须具有相同类型,并且该类型必须是操作符族支持的类型之一(也就是该族为其提供排序的一种类型)。不过, + offset + 可以是另一种类型,而该类型甚至可能不被该族以其他方式支持。例如,内置的 + time_ops 族就提供了一个 in_range + 函数,其 offset 的类型为 + interval。一个族可以提供 in_range + 函数,分别对应其支持的任意类型以及一个或多个 + offset 类型。每个 + in_range 函数都应在 + pg_amproc 中登记,其中 + amproclefttype 等于 + type1,而 + amprocrighttype 等于 + type2 - 对于in_range函数,其核心语义取决于两个布尔标志参数。它应当先对baseoffset做加法或减法,再把val与结果比较,具体如下: + + in_range 函数的核心语义取决于这两个布尔 + 标志参数。它应当先对 base 与 + offset 做加法或减法,再把 + val 与结果比较,具体如下: + 如果 !sub 且 @@ -274,7 +295,15 @@ returns bool offset) - 在此之前,函数应检查offset的符号:如果它小于零,就引发错误ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE(22013),错误文本类似于invalid preceding or following size in window function。(这是 SQL 标准的要求,尽管非标准操作符族或许会选择忽略这一限制,因为从语义上看似乎并没有太大必要。)把这个要求委托给in_range函数,是为了让核心代码无需理解小于零对于某个特定数据类型究竟意味着什么。 + + 在此之前,函数应检查 offset 的符号:如果它小于零,就引发错误 + ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE + (22013),错误文本类似于 + invalid preceding or following size in window function。 + (这是 SQL 标准的要求,尽管非标准操作符族或许会选择忽略这一限制,因为从语义上看似乎并没有太大必要。) + 把这个要求委托给 in_range + 函数,是为了让核心代码无需理解对于某个特定数据类型来说小于零究竟意味着什么。 + 另外还希望 in_range 函数在可行时避免因为 @@ -287,7 +316,11 @@ returns bool in_range 的结果与该操作符族的正常排序顺序一致。 - in_range函数的结果必须与操作符族规定的排序顺序一致。具体而言,对于任意固定的offsetsub值,应满足以下条件: + + in_range 函数的结果必须与操作符族施加的排序顺序保持一致。更精确地说,给定任意固定的 + offset 和 + sub 值,则: + 如果 in_range 在 @@ -332,10 +365,13 @@ returns bool val 相同,它也必须返回假。 - less= false 时,类似的结论成立,但条件相反。 + + 当 less = false + 时,也有条件相反的对应陈述成立。 + - 如果被排序的类型(type1)属于可排序数据类型,则会通过标准的 + 如果被排序的类型(type1)属于支持排序规则的数据类型,则会通过标准的 PG_GET_COLLATION() 机制,把适当的排序规则 OID 传递给 in_range 函数。 @@ -350,7 +386,7 @@ returns bool 实现 - 可在src/backend/access/nbtree/README中找到对 btree 索引实现的介绍。 + 可在src/backend/access/nbtree/README中找到对 B-树索引实现的介绍。 diff --git a/zh/12/catalogs.sgml b/zh/12/catalogs.sgml index 512e3885..1260e389 100644 --- a/zh/12/catalogs.sgml +++ b/zh/12/catalogs.sgml @@ -374,7 +374,7 @@ - Name + 名称 类型 引用 @@ -597,7 +597,7 @@ - Name + 名称 类型 引用 @@ -640,7 +640,7 @@ t = 表(包括物化视图), - i = 索引. + i = 索引。 @@ -673,7 +673,7 @@ - Name + 名称 类型 引用 @@ -818,7 +818,7 @@ - Name + 名称 类型 引用 @@ -911,7 +911,7 @@ - Name + 名称 类型 引用 @@ -985,7 +985,7 @@ - Name + 名称 类型 引用 @@ -1077,7 +1077,7 @@ atttypmod记录了在表创建时提供的类型相关数据(例如一个varchar列的最大长度)。 - 它会被传递给类型相关的输入函数和长度强制函数。对于那些不需要atttypmod的类型,这个值通常总是为-1。 + 它会被传递给类型相关的输入函数和长度强制转换函数。对于那些不需要atttypmod的类型,这个值通常为 -1。 @@ -1114,7 +1114,7 @@ bool - 此列具有一个非空约束(可能尚未验证) + 这代表一个非空约束 @@ -1133,8 +1133,7 @@ bool - 该列在行中完全缺失时会用到这个列的值,如果在行创建之后增加一个有非易失DEFAULT值的列,就会发生这种情况。 - 实际使用的值被存放在attmissingval列中。 + 此列有一个值,供该列在数据行中完全缺失时使用;在数据行创建之后添加带有非易失 DEFAULT 值的列时,就会出现这种情况。实际使用的值存储在 attmissingval 列中。 @@ -1154,7 +1153,7 @@ 如果是零字节(''),则不是生成列。 - 否则,s = 存储式(stored)。(将来可能会增加其他值。) + 否则,s = 存储式。(将来可能会添加其他值。) @@ -1163,7 +1162,7 @@ bool - 该列被删除且不再有效。一个删除的列仍然物理存在于表中,但是会被分析器忽略并因此无法通过SQL访问。 + 该列被删除且不再有效。一个删除的列仍然物理存在于表中,但是会被解析器忽略并因此无法通过SQL访问。 @@ -1190,7 +1189,7 @@ oid pg_collation.oid - 该列被定义的排序规则,如果该列不是一个可排序数据类型则为0。 + 该列定义的排序规则;如果该列的数据类型不支持排序规则,则为零。 @@ -1199,7 +1198,7 @@ aclitem[] - 列级访问权限, 如果此列上已有特别授予的权限 + 列级访问权限,如果此列上已有特别授予的权限 @@ -1227,7 +1226,7 @@ 这个列中是一个含有一个元素的数组,其中的值被用于该列在行中完全缺失时,如果在行创建之后增加一个有非易失DEFAULT值的列,就会发生这种情况。 - 只有当atthasmissing为真时才使用这个值。如果没有值则该列为空。 + 只有当atthasmissing为真时才使用这个值。如果没有值则该列为空值。 @@ -1236,9 +1235,7 @@ - 在一个被删除的列的pg_attribute的项中,atttypid被重置为0,但attlen以及其他从pg_type拷贝的域仍然有效。 - 这种安排用于处理一种情况,即被删除列的数据类型后来被删除,并且因此不再有相应的pg_type行。 - attlen和其他域可以被用来解释表的一行的内容。 + 在被删除列的 pg_attribute 条目中,atttypid 被重置为零,但 attlen 以及其他从 pg_type 复制的字段仍然有效。这种安排用于应对被删除列的数据类型后来也被删除、因而不再有相应 pg_type 行的情况。attlen 和其他字段可用于解释表中一行的内容。 @@ -1272,7 +1269,7 @@ - Name + 名称 类型 描述 @@ -1358,21 +1355,21 @@ rolconnlimit int4 - 对于可以登录的角色,本列设置该角色可以同时发起最大连接数。-1表示无限制。 + 对于可以登录的角色,本列设置该角色能够建立的最大并发连接数。-1 表示无限制。 rolpassword text - 密码(可能已加密);如果没有则为空。其格式取决于所使用的加密形式。 + 密码(可能已加密);如果未设置则为空值。其格式取决于所使用的加密方式。 rolvaliduntil timestamptz - 密码过期时间(只用于密码鉴定),如果永不过期则为空 + 密码过期时间(仅用于密码认证);不设过期时间时为空值 @@ -1380,7 +1377,7 @@ - 对于一个MD5加密的密码,rolpassword列将由字符串md5后面跟上一个32字符的十六进制MD5哈希值构成。MD5哈希值将是该用户的密码串接上它们的用户名。例如,如果用户joe的密码是xyzzy,则PostgreSQL将存储xyzzyjoe的md5哈希。 + 对于一个MD5加密的密码,rolpassword列将由字符串md5后面跟上一个32字符的十六进制MD5哈希值构成。MD5 哈希值通过在用户密码后拼接用户名再计算得到。例如,如果用户joe的密码是xyzzy,则PostgreSQL将存储xyzzyjoe的md5哈希。 如果密码使用 SCRAM-SHA-256 加密,其格式为: @@ -1412,7 +1409,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -1476,7 +1473,7 @@ SCRAM-SHA-256$<iteration count>:&l - 需要注意的是,pg_cast并不表示系统知道如何执行的所有类型转换,它只包括那些不能从某些通用规则推导出的转换。例如,一个域及其基类型之间的转换并未显式地在pg_cast中展示。另一个重要的例外是自动的基于 I/O 的类型转换,它们通过数据类型自己的 I/O 函数来转换成(或者转换自)text或其他字符串类型,这些转换也没有显式地在pg_cast中表示。 + 需要注意的是,pg_cast并不表示系统知道如何执行的所有类型转换,它只包括那些不能从某些通用规则推导出的转换。例如,一个域及其基础类型之间的转换并未显式地在pg_cast中展示。另一个重要的例外是自动的基于 I/O 的类型转换,它们通过数据类型自己的 I/O 函数来转换成(或者转换自)text或其他字符串类型,这些转换也没有显式地在pg_cast中表示。 @@ -1485,7 +1482,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -1578,7 +1575,7 @@ SCRAM-SHA-256$<iteration count>:&l - 目录pg_class描述了具有列或与表类似的其他对象。这包括索引(但请参见pg_index)、序列(但请参见pg_sequence)、视图、物化视图、复合类型和TOAST表;请参见relkind。 + 目录pg_class描述了表以及其他具有列或在其他方面与表类似的对象。这包括索引(但请参见pg_index)、序列(但请参见pg_sequence)、视图、物化视图、复合类型和TOAST表;请参见relkind。 在下面,当我们指的是所有这些类型的对象时,我们称之为关系(relations)。并非所有pg_class的列对所有关系类型都有意义。 @@ -1588,7 +1585,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -1654,7 +1651,7 @@ SCRAM-SHA-256$<iteration count>:&l relam oid pg_am.oid - 如果这是表或索引,则为使用的访问方法(堆、B-树、哈希等) + 如果这是表或索引,则为使用的访问方法(堆、B-树、hash 等) @@ -1740,7 +1737,7 @@ SCRAM-SHA-256$<iteration count>:&l char - p = 永久表, u = 不记录 WAL 的表, + p = 永久表,u = 不记录 WAL 的表, t = 临时表 @@ -1835,7 +1832,7 @@ SCRAM-SHA-256$<iteration count>:&l bool - 如果表已被填充则为真(对于所有关系该列都为真,但对于某些物化视图却不是) + 如果关系已被填充则为真(对于所有关系该列都为真,但对于某些物化视图却不是) @@ -1887,7 +1884,7 @@ SCRAM-SHA-256$<iteration count>:&l xid - 在此之前的多事务ID在表中已经被替换为一个事务ID。这被用于跟踪表是否需要被清理,以阻止 + 在此之前的所有多事务ID在表中已经被替换为一个事务ID。这被用于跟踪表是否需要被清理,以阻止 多事务ID回卷或者允许pg_multixact被收缩。如果关系不是一个表则 为0(InvalidMultiXactId)。 @@ -1916,7 +1913,7 @@ SCRAM-SHA-256$<iteration count>:&l pg_node_tree - 如果表示一个分区(见relispartition),则为分区边界的内部表示 + 如果表是一个分区(见relispartition),则为分区边界的内部表示 @@ -1924,7 +1921,7 @@ SCRAM-SHA-256$<iteration count>:&l
- pg_class中的一些逻辑标志被以一种懒惰的方式维护:在正确状态时它们被保证为真,但是当条件不再为真时它们并不会被立刻重置为假。 + pg_class中的一些布尔标志采用延迟维护:当条件成立时,保证它们为真;但当条件不再成立时,可能不会立即将它们重置为假。 例如,relhasindexCREATE INDEX设置,但它从不会被DROP INDEX清除。 作为替代,VACUUM会在找到无索引表后清除其relhasindex。 这种安排避免了竞争条件并且提高了并发性。 @@ -1948,7 +1945,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -1999,9 +1996,10 @@ SCRAM-SHA-256$<iteration count>:&l char - 排序规则提供者:d = 数据库默认值, + 排序规则提供程序:d = 数据库默认值, c = libc, - i = icu + i = icu + @@ -2045,7 +2043,7 @@ SCRAM-SHA-256$<iteration count>:&l text - 排序规则的提供者相关的版本。这是在排序规则创建时记录下来的,并且在使用排序规则时会被检查以检测可能导致数据损坏的排序规则定义的改变。 + 提供程序特有的排序规则版本。它会在创建排序规则时记录下来,并在使用时接受检查,以检测可能导致数据损坏的排序规则定义更改。 @@ -2090,7 +2088,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -2345,9 +2343,9 @@ SCRAM-SHA-256$<iteration count>:&l - 在一个排他约束的情况中, conkey只对约束元素是单一列引用时有用。 - 对于其他情况,conkey中出现一个0且必须查阅相关索引来发现被约束的表达式。 - (对于索引,conkey因此和pg_index.indkey具有相同的内容)。 + 对于排他约束,conkey仅对作为简单列引用的约束元素有用。 + 对于其他情况,conkey中会出现一个 0,必须查阅关联索引来确定被约束的表达式。 + (因此,conkey与该索引的 pg_index.indkey具有相同的内容。) @@ -2375,7 +2373,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -2486,7 +2484,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -2656,7 +2654,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -2715,7 +2713,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -2815,7 +2813,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -3015,7 +3013,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -3084,7 +3082,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -3160,7 +3158,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -3250,7 +3248,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -3359,7 +3357,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -3454,7 +3452,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -3560,7 +3558,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -3620,7 +3618,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -3671,7 +3669,7 @@ SCRAM-SHA-256$<iteration count>:&l bool - 如为真, 这是唯一索引 + 如为真, 这是唯一索引 @@ -3777,7 +3775,7 @@ SCRAM-SHA-256$<iteration count>:&l oidvector pg_collation.oid - 对于索引键(indnkeyatts值)中的每一列,这包含要用于该索引的排序规则的OID,如果该列不是一种可排序数据类型则为零。 + 对于索引键(indnkeyatts值)中的每一列,这包含要用于该索引的排序规则的OID,如果该列的数据类型不支持排序规则则为零。 @@ -3840,7 +3838,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -3907,7 +3905,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -3987,7 +3985,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -4105,7 +4103,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -4168,7 +4166,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -4228,7 +4226,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -4301,7 +4299,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -4421,7 +4419,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -4593,7 +4591,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -4676,7 +4674,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -4748,7 +4746,7 @@ SCRAM-SHA-256$<iteration count>:&l oidvector pg_opclass.oid - 对于分区键中的每一个列,这个域包含要用于分区的排序规则的OID,如果该列不是一种可排序数据类型则为零。 + 对于分区键中的每一个列,这个域包含要用于分区的排序规则的OID,如果该列的数据类型不支持排序规则则为零。 @@ -4792,7 +4790,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 描述 @@ -4888,7 +4886,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -4999,7 +4997,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -5316,7 +5314,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -5419,7 +5417,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -5468,7 +5466,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -5536,7 +5534,11 @@ SCRAM-SHA-256$<iteration count>:&l - rngsubopc (加上rngcollation,如果元素类型是可排序的)决定了被该范围类型所使用的排序顺序。rngcanonical用于离散类型的元素类型。rngsubdiff是可选的,但是提供它可以提高范围类型上的GiST索引性能。 + rngsubopc(如果元素类型支持排序规则,则还包括 + rngcollation)决定范围类型所用的排序顺序。 + rngcanonical用于元素类型为离散类型的情况。 + rngsubdiff是可选的,但应当提供它, + 以提高范围类型上的 GiST 索引性能。
@@ -5563,7 +5565,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -5612,7 +5614,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -5732,7 +5734,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -5809,7 +5811,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -5919,7 +5921,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -6073,7 +6075,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -6141,7 +6143,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -6202,8 +6204,8 @@ SCRAM-SHA-256$<iteration count>:&l 通常,每个已分析的表列都有一个条目,其中stainherit = false。 - 如果表具有继承子项或分区,则还会创建第二个条目,其中stainherit = true。 - 此行表示继承树上列的统计信息,即您可以通过SELECT column FROM table*看到的数据的统计信息, + 如果表具有继承子表,则还会创建第二个条目,其中stainherit = true。 + 此行表示继承树上列的统计信息,即你可以通过SELECT column FROM table*看到的数据的统计信息, 而stainherit = false行表示SELECT column FROM ONLY table的结果。 @@ -6212,7 +6214,7 @@ SCRAM-SHA-256$<iteration count>:&l - 因为不同类型的统计信息适用于不同类型的数据, pg_statistic 被设计成不太在意自己存储的是什么类型的统计。 只有极为常用的统计信息(比如NULL的含量)才在pg_statistic里给予专用的字段。 其它所有东西都存储在槽位中,而槽位是一组相关的列, 它们的内容用槽位中的一个列里的代码表示。 更详细的信息请参阅 src/include/catalog/pg_statistic.h。 + 由于不同种类的数据可能适合不同种类的统计信息,pg_statistic 在设计上尽量不对所存储的统计信息种类作出假定。只有极为通用的统计信息(例如空值情况)才在 pg_statistic 中有专用的列。其余统计信息都存储在槽位中。每个槽位都是一组相关的列,其内容由其中一列的代码编号来标识。更多信息见 src/include/catalog/pg_statistic.h @@ -6225,7 +6227,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -6267,7 +6269,7 @@ SCRAM-SHA-256$<iteration count>:&l float4 - 列的项为空的比例 + 列中空值所占的比例 @@ -6285,8 +6287,8 @@ SCRAM-SHA-256$<iteration count>:&l float4 - 列中非空唯一值的数目。一个大于零的值是唯一值的真正数目。 - 一个小于零的值是表中行数的乘数的负值;例如,对于一个 80% 的值为非空且每个非空值平均出现两次的列,可以表示为stadistinct = -0.4。一个0值表示唯一值的数目未知。 + 列中不同非空数据值的数量。一个大于零的值是不同值的真正数目。 + 一个小于零的值是表中行数的乘数的负值;例如,对于一个约 80% 的值为非空且每个非空值平均出现两次的列,可以表示为stadistinct = -0.4。一个0值表示不同值的数目未知。 @@ -6314,8 +6316,8 @@ SCRAM-SHA-256$<iteration count>:&l oid pg_collation.oid - 用于导出存储在第N槽位中的统计信息的排序规则。 - 例如,可应用排序规则列的直方图槽会显示定义数据排序顺序的排序规则。对于不可应用排序规则的数据,则为零。 + 用于生成存储在第N槽位中的统计信息的排序规则。 + 例如,支持排序规则的列的直方图槽会显示定义数据排序顺序的排序规则。对于不支持排序规则的数据,则为零。 @@ -6324,7 +6326,7 @@ SCRAM-SHA-256$<iteration count>:&l float4[] - 第N槽位的类型的数值类型统计, 如果该槽位不涉及数值类型则为NULL + 第N槽位中相应种类的数值统计信息;如果该槽位种类不涉及数值,则为 NULL @@ -6334,7 +6336,7 @@ SCRAM-SHA-256$<iteration count>:&l N槽位的类型的列值,如果该槽位类型不存储任何数据值则为 NULL。 - 每个数组的元素值实际上都是指定列的数据类型或者是一个相关类型(如数组元素类型), 因此,除了把这些列的类型定义成anyarray之外别无他法。 + 每个数组的元素值实际上都是指定列的数据类型或者是一个相关类型(如数组元素类型), 因此,无法把这些列的类型定义得比anyarray更具体。 @@ -6361,7 +6363,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -6434,8 +6436,8 @@ SCRAM-SHA-256$<iteration count>:&l - pg_statistic_ext条目在CREATE STATISTICS期间完全填充,但是随后不计算实际的统计值。 - 后来ANALYZE命令计算所需的值,并在pg_statistic_ext_data目录中填充条目。 + pg_statistic_ext条目在CREATE STATISTICS期间完全填充,但此时不会计算实际的统计值。 + 后续的ANALYZE命令计算所需的值,并在pg_statistic_ext_data目录中填充条目。 @@ -6467,7 +6469,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -6510,7 +6512,7 @@ SCRAM-SHA-256$<iteration count>:&l pg_mcv_list - MCV(最频值)列表统计信息,序列化为pg_mcv_list类型 + MCV(高频值)列表统计信息,序列化为pg_mcv_list类型 @@ -6545,7 +6547,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -6662,7 +6664,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -6737,7 +6739,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -6815,7 +6817,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -6885,7 +6887,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -6994,7 +6996,7 @@ SCRAM-SHA-256$<iteration count>:&l bool - 如果约束触发器可推迟则为真 + 如果约束触发器可延迟则为真 @@ -7003,7 +7005,7 @@ SCRAM-SHA-256$<iteration count>:&l bool - 如果约束触发器初始可推迟则为真 + 如果约束触发器初始处于延迟状态则为真 @@ -7106,7 +7108,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -7187,7 +7189,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -7259,7 +7261,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -7349,7 +7351,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -7457,7 +7459,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -7526,7 +7528,7 @@ SCRAM-SHA-256$<iteration count>:&l 目录pg_type存储有关数据类型的信息。 - 基类型和枚举类型(标量类型)使用创建,而域使用创建。 + 基础类型和枚举类型(标量类型)使用创建,而域使用创建。 数据库中的每一个表都会有一个自动创建的复合类型,用于表示表的行结构。 也可以使用CREATE TYPE AS创建复合类型。 @@ -7537,7 +7539,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -7611,7 +7613,7 @@ SCRAM-SHA-256$<iteration count>:&l typtype可以是: - b表示一个基类型, + b表示一个基础类型, c表示一个复合类型(例如一个表的行类型), d表示一个域, e表示一个枚举类型, @@ -7832,7 +7834,7 @@ SCRAM-SHA-256$<iteration count>:&l int4 - 域使用typtypmod来记录被应用于它们基类型的typmod(如果基类型不使用typmod,则为-1)。如果此类型不是一个域则为-1。 + 域使用typtypmod来记录被应用于它们基础类型的typmod(如果基础类型不使用typmod,则为-1)。如果此类型不是一个域则为-1。 @@ -7851,8 +7853,8 @@ SCRAM-SHA-256$<iteration count>:&l pg_collation.oid typcollation指定此类型的排序规则。如果类型不支持排序规则,此列为零。 - 支持排序规则的基类型在这里会有一个非零值,典型值为DEFAULT_COLLATION_OID。 - 基于可应用排序规则类型的域,如果为其指定了排序规则 OID,则它的排序规则 OID 可以不同于其基类型。 + 支持排序规则的基础类型在这里会有一个非零值,典型值为DEFAULT_COLLATION_OID。 + 基于支持排序规则的类型的域,如果为其指定了排序规则 OID,则它的排序规则 OID 可以不同于其基础类型的排序规则 OID。 @@ -7987,7 +7989,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -8242,7 +8244,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 描述 @@ -8310,7 +8312,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 描述 @@ -8411,7 +8413,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 描述 @@ -8479,7 +8481,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 描述 @@ -8576,7 +8578,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 描述 @@ -8668,7 +8670,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -8738,7 +8740,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 描述 @@ -8839,7 +8841,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -8885,7 +8887,7 @@ SCRAM-SHA-256$<iteration count>:&l text - 索引定义(重构出的 CREATE INDEX 命令) + 索引定义(重建出的 CREATE INDEX 命令) @@ -8919,8 +8921,8 @@ SCRAM-SHA-256$<iteration count>:&l 以及一般的数据库对象(由类OID和对象OID标识, 与pg_descriptionpg_depend中的方式相同)。 - 此外,扩展关系的权限被表示为一个单独的可锁定对象,以及更新 - pg_database.datfrozenxid 的更新权限。 + 此外,扩展关系的权利被表示为单独的可锁定对象,更新 + pg_database.datfrozenxid的权利也是如此。 此外,还可以对具有用户定义含义的数字施加咨询锁。 @@ -8930,7 +8932,7 @@ SCRAM-SHA-256$<iteration count>:&l - Name + 名称 类型 引用 @@ -8950,7 +8952,7 @@ SCRAM-SHA-256$<iteration count>:&l oid pg_database.oid - 锁目标存在的数据库的OID,如果目标是一个共享对象则为0,如果目标是一个事务ID则为空 + 锁目标存在的数据库的OID,如果目标是一个共享对象则为0,如果目标是一个事务ID则为 NULL @@ -8958,7 +8960,7 @@ SCRAM-SHA-256$<iteration count>:&l oid pg_class.oid - 作为锁目标的关系的OID,如果目标不是一个关系或者只是关系的一部分则此列为空 + 作为锁目标的关系的OID,如果目标既不是关系,也不是关系的一部分则此列为 NULL @@ -8966,7 +8968,7 @@ SCRAM-SHA-256$<iteration count>:&l integer - 作为锁目标的页在关系中的页号,如果目标不是一个关系页或元组则此列为空 + 作为锁目标的页在关系中的页号,如果目标不是一个关系页或元组则此列为 NULL @@ -8974,7 +8976,7 @@ SCRAM-SHA-256$<iteration count>:&l smallint - 作为锁目标的元组在页中的元组号,如果目标不是一个元组则此列为空 + 作为锁目标的元组在页中的元组号,如果目标不是一个元组则此列为 NULL @@ -8982,7 +8984,7 @@ SCRAM-SHA-256$<iteration count>:&l text - 锁定目标事务的虚拟 ID,如果目标不是虚拟事务 ID,则为空 + 锁定目标事务的虚拟 ID,如果目标不是虚拟事务 ID,则为 NULL @@ -8990,7 +8992,7 @@ SCRAM-SHA-256$<iteration count>:&l xid - 锁定目标事务的标识,如果目标不是事务 ID,则为空 + 锁定目标事务的标识,如果目标不是事务 ID,则为 NULL @@ -8998,7 +9000,7 @@ SCRAM-SHA-256$<iteration count>:&l oid pg_class.oid - 包含锁目标的系统目录的OID,如果目标不是一个普通数据库对象则此列为空 + 包含锁目标的系统目录的OID,如果目标不是一个普通数据库对象则此列为 NULL @@ -9006,7 +9008,7 @@ SCRAM-SHA-256$<iteration count>:&l oid 任意 OID 列 - 锁目标在它的系统目录中的OID,如果目标不是一个普通数据库对象则为空 + 锁目标在它的系统目录中的OID,如果目标不是一个普通数据库对象则为 NULL @@ -9014,7 +9016,7 @@ SCRAM-SHA-256$<iteration count>:&l smallint - 锁的目标列号(classidobjid指表本身),如果目标是某种其他普通数据库对象则此列为0,如果目标不是一个普通数据库对象则此列为空 + 锁的目标列号(classidobjid指表本身),如果目标是某种其他普通数据库对象则此列为0,如果目标不是一个普通数据库对象则此列为 NULL @@ -9030,7 +9032,7 @@ SCRAM-SHA-256$<iteration count>:&l integer - 保持这个锁或者正在等待这个锁的服务器进程的PID,如果此锁被一个预备事务所持有则此列为空 + 保持这个锁或者正在等待这个锁的服务器进程的PID,如果此锁被一个预备事务所持有则此列为 NULL @@ -9081,8 +9083,8 @@ SCRAM-SHA-256$<iteration count>:&l 咨询锁可以在由单个 bigint 值或两个整数值组成的键上获取。 - 一个bigint键在classid列中显示其高阶半部分, - 在objid列中显示其低阶半部分,并且objsubid等于1。 + 一个bigint键在classid列中显示其高位半部分, + 在objid列中显示其低位半部分,并且objsubid等于1。 可以使用表达式(classid::bigint << 32) | objid::bigint重新组装原始bigint值。 整数键在classid列中显示第一个键,在objid列中显示第二个键, 并且 objsubid 等于 2。键的实际含义由用户自行决定。咨询锁在每个数据库内都是本地的, @@ -9126,15 +9128,15 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx pg_locks视图显示来自常规锁管理器和谓词锁管理器的数据,这两个是独立的系统; - 此外,常规锁管理器将其锁分为常规锁和fast-path锁。 + 此外,常规锁管理器将其锁分为常规锁和快速路径锁。 不能保证这些数据完全一致。 当查询该视图时, - fast-path 锁的数据(具有fastpath = true) + 快速路径锁的数据(具有fastpath = true) 从每个后端逐个收集,而不会冻结整个锁管理器的状态,因此在收集信息时可能会发生锁的获取或释放。 但请注意,这些锁已知不会与当前放置的任何其他锁发生冲突。 - 在查询所有后端的 fast-path 锁后,剩余的常规锁管理器将作为一个单元被锁定,并且所有剩余锁的一致快照将作为一个原子操作收集。 + 在查询所有后端的快速路径锁后,剩余的常规锁管理器将作为一个单元被锁定,并且所有剩余锁的一致快照将作为一个原子操作收集。 解锁常规锁管理器后,谓词锁管理器类似地被锁定,并且所有谓词锁将作为一个原子操作收集。 - 因此,除了 fast-path 锁外,每个锁管理器将提供一致的结果集,但由于我们不同时锁定两个锁管理器,因此在询问常规锁管理器后和在询问谓词锁管理器前,可能会发生锁的获取或释放。 + 因此,除了快速路径锁外,每个锁管理器将提供一致的结果集,但由于我们不同时锁定两个锁管理器,因此在询问常规锁管理器后和在询问谓词锁管理器前,可能会发生锁的获取或释放。 @@ -9165,7 +9167,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - Name + 名称 类型 引用 @@ -9227,7 +9229,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx text - 物化视图的定义(一个重构的SELECT查询) + 物化视图的定义(一个重建的SELECT查询) @@ -9253,7 +9255,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - Name + 名称 类型 引用 @@ -9356,7 +9358,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - Name + 名称 类型 描述 @@ -9431,7 +9433,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - Name + 名称 类型 引用 @@ -9511,7 +9513,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - Name + 名称 类型 引用 @@ -9571,7 +9573,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - Name + 名称 类型 引用 @@ -9643,7 +9645,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - Name + 名称 类型 引用 @@ -9710,7 +9712,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx boolean - 如果该槽当前正被用于流送则为真 + 如果该槽当前正在使用中则为真 @@ -9719,7 +9721,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx integer - 为该槽流送数据的会话的进程 ID。NULL 表示不活动。 + 如果该槽当前正在使用中,则为使用该槽的会话的进程 ID;不活动时为 NULL @@ -9753,7 +9755,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx pg_lsn - 逻辑槽消费者已确认接收到数据的地址(LSN)。早于此地址的数据将不再可用。物理槽为 NULL。 + 逻辑槽消费者已确认接收的数据所到达的地址(LSN)。早于此地址的数据将不再可用。物理槽为 NULL @@ -9771,7 +9773,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx 视图pg_roles提供数据库角色的信息。它本质上是 - pg_authid 的公开可读视图,并将密码字段清空。 + pg_authid 的公开可读视图,并隐藏密码字段。 @@ -9780,7 +9782,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - Name + 名称 类型 引用 @@ -9858,7 +9860,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx int4 - 对于可以登录的角色,本列设置该角色可以同时发起最大连接数。-1表示无限制。 + 对于可以登录的角色,本列设置该角色能够建立的最大并发连接数。-1 表示无限制。 @@ -9876,7 +9878,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx timestamptz - 密码过期时间(只用于密码认证),如果永不过期则为空 + 密码过期时间(仅用于密码认证);不设过期时间时为空值 @@ -9929,7 +9931,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - Name + 名称 类型 引用 @@ -9967,7 +9969,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx text - 规则定义(创建命令的重构) + 规则定义(重建的创建命令) @@ -10000,7 +10002,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - Name + 名称 类型 引用 @@ -10095,7 +10097,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - Name + 名称 类型 引用 @@ -10217,7 +10219,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - Name + 名称 类型 描述 @@ -10468,7 +10470,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx 这个名称源于该表不应向公众开放读取,因为它包含密码。 pg_user - 是 pg_shadow 的公开可读视图,并将密码字段清空。 + 是 pg_shadow 的公开可读视图,并隐藏密码字段。
@@ -10477,7 +10479,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - Name + 名称 类型 引用 @@ -10545,7 +10547,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx passwd text - 密码(可能已加密);如果没有则为空。关于加密密码的存储方式,详见pg_authid + 密码(可能已加密);如果未设置则为空值。关于加密密码的存储方式,详见pg_authid @@ -10595,7 +10597,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - Name + 名称 类型 引用 @@ -10768,7 +10770,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - Name + 名称 类型 引用 @@ -10924,7 +10926,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - Name + 名称 类型 引用 @@ -11018,7 +11020,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - Name + 名称 类型 描述 @@ -11082,7 +11084,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - Name + 名称 类型 描述 @@ -11133,7 +11135,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx 视图pg_user提供数据库用户的信息。它本质上是 - pg_shadow 的公开可读视图,并将密码字段清空。 + pg_shadow 的公开可读视图,并隐藏密码字段。
@@ -11142,7 +11144,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - Name + 名称 类型 描述 @@ -11246,7 +11248,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - Name + 名称 类型 引用 @@ -11352,7 +11354,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - Name + 名称 类型 引用 @@ -11390,7 +11392,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx text - 视图定义(一个重构的SELECT查询) + 视图定义(一个重建的SELECT查询) diff --git a/zh/12/charset.sgml b/zh/12/charset.sgml index 8a67ac44..2bb08ec5 100644 --- a/zh/12/charset.sgml +++ b/zh/12/charset.sgml @@ -29,7 +29,7 @@ 区域设置支持 - locale + 区域设置 区域设置支持是指应用程序在字母表、排序、数字格式等 @@ -71,7 +71,7 @@ initdb --locale=sv_SE Swedish_Sweden.1252,但原则是相同的。 - 偶尔需要混合几个区域设置的规则,例如使用英语排序规则和西班牙语消息。为此,系统提供了一组区域设置子类别,分别控制本地化规则的某些方面: LC_COLLATE 字符串排序顺序 LC_CTYPE 字符分类(什么是字母?它对应的大写形式是什么?) LC_MESSAGES 消息语言 LC_MONETARY 货币金额格式 LC_NUMERIC 数字格式 LC_TIME 日期和时间格式 这些类别名称对应于 initdb 选项的名称,可覆盖某个特定类别的区域设置选择。例如,要将区域设置设为加拿大法语,但使用美国的货币格式规则,可使用 initdb --locale=fr_CA --lc-monetary=en_US。 + 有时混合多个区域设置的规则会很有用,例如使用英语排序规则但使用西班牙语消息。为此,存在一组只控制本地化规则某些方面的区域设置子类别: LC_COLLATE 字符串排序顺序 LC_CTYPE 字符分类(什么算字母?它的大写等价形式是什么?) LC_MESSAGES 消息的语言 LC_MONETARY 货币数量使用的格式 LC_NUMERIC 数字的格式 LC_TIME 日期和时间的格式 这些类别名会转换成initdb选项名,用于覆盖特定类别的区域设置选择。例如,要将区域设置设为加拿大法语,但对货币格式采用美国规则,可以使用initdb --locale=fr_CA --lc-monetary=en_US 如果希望系统表现得像没有区域设置支持一样,可使用特殊区域设置名 @@ -115,7 +115,7 @@ initdb --locale=sv_SE 某些消息本地化库还会查看环境变量LANGUAGE,它会覆盖所有 - 其他用于设置消息语言的区域设置。如果有疑问,请参考操作系统文档,尤其是 + 其他用于设置消息的语言的区域设置。如果有疑问,请参考操作系统文档,尤其是 关于gettext的文档。 @@ -157,7 +157,7 @@ initdb --locale=sv_SE 以及 POSIX 风格正则表达式);区域设置既会影响大小写不敏感匹配,也会 影响字符类正则表达式中的字符分类 LIKE与区域设置 - regular expressions与区域设置 + 正则表达式与区域设置 @@ -246,10 +246,10 @@ initdb --locale=sv_SE 概念 - 从概念上讲,每个可排序数据类型的表达式都有一个排序规则。(内置的可排序 - 数据类型包括textvarcharchar。 - 用户定义的基本类型也可以标记为可排序,当然,建立在可排序数据类型之上的 - 域也是可排序的。) + 从概念上讲,每个支持排序规则的数据类型的表达式都有一个排序规则。 + (内置的支持排序规则的数据类型包括textvarcharchar。 + 用户定义的基础类型也可以标记为支持排序规则,当然,建立在支持排序规则的数据类型之上的 + 域也支持排序规则。) 如果表达式是列引用,则该表达式的排序规则就是该列定义的排序规则。如果表 达式是常量,则其排序规则就是该常量数据类型的默认排序规则。更复杂表达式 的排序规则则按下文所述,从其输入表达式的排序规则推导出来。 @@ -274,7 +274,7 @@ initdb --locale=sv_SE 对于函数或操作符调用,通过检查参数排序规则推导出的排序规则,会在运行时 - 用于执行指定操作。如果该函数或操作符调用的结果属于可排序数据类型,那么 + 用于执行指定操作。如果该函数或操作符调用的结果属于支持排序规则的数据类型,那么 在解析时它也会被用作该函数或操作符表达式的已定义排序规则,以便在外围表 达式需要知道其排序规则时使用。 @@ -356,7 +356,7 @@ SELECT a || b FROM test1; - 如果函数或操作符返回的是可排序数据类型,那么分配给该函数或操作符组合输 + 如果函数或操作符返回的是支持排序规则的数据类型,那么分配给该函数或操作符组合输 入表达式的排序规则,也被认为适用于其结果。因此,在 SELECT * FROM test1 ORDER BY a || 'foo'; @@ -402,8 +402,7 @@ SELECT * FROM test1 ORDER BY a || b COLLATE "fr_FR"; - 由icu提供的排序规则对象,对应于 ICU 库提供的具名整 - 理器。ICU 不支持将collatectype分开设 + 由icu提供的排序规则对象,对应于 ICU 库提供的具名排序器。ICU 不支持将collatectype分开设 置,因此二者总是相同的。此外,ICU 排序规则与编码无关,因此在一个数据库 中,某个给定名称的 ICU 排序规则始终只有一个。 @@ -492,7 +491,7 @@ SELECT a COLLATE "C" < b COLLATE "POSIX" FROM test1; -x-icu,以便与 libc 区域设置区分开来。 - 以下是可能创建的排序规则示例: + 下面是一些可能创建出来的排序规则示例: de-x-icu @@ -578,7 +577,7 @@ CREATE COLLATION german (provider = libc, locale = 'de_DE'); CREATE COLLATION "de-u-co-phonebk-x-icu" (provider = icu, locale = 'de-u-co-phonebk'); CREATE COLLATION "de-u-co-phonebk-x-icu" (provider = icu, locale = 'de@collation=phonebook'); - 采用电话簿排序类型的德语排序规则 + 德语排序规则,电话簿排序类型 第一个示例使用 BCP 47 定义的语言标签来选择 ICU 区域设置。第二个示例使用传统的 ICU 专有区域设置语法。今后应优先采用第一种形式,但较旧的 ICU 版本不支持它。 注意,可以在 SQL 环境中为排序规则对象任意命名。本例遵循预定义排序规则所采用的命名风格,该风格也遵循 BCP 47,但用户定义的排序规则并不要求如此。 @@ -588,7 +587,9 @@ CREATE COLLATION german (provider = libc, locale = 'de_DE'); CREATE COLLATION "und-u-co-emoji-x-icu" (provider = icu, locale = 'und-u-co-emoji'); CREATE COLLATION "und-u-co-emoji-x-icu" (provider = icu, locale = '@collation=emoji'); - 采用 Unicode 技术标准 #51 所定义 Emoji 排序类型的根排序规则 + + 根排序规则,表情符号排序类型,依据 Unicode 技术标准 #51 + 注意,传统的 ICU 区域设置命名系统使用空字符串来选择根区域设置。 @@ -597,7 +598,9 @@ CREATE COLLATION german (provider = libc, locale = 'de_DE'); CREATE COLLATION latinlast (provider = icu, locale = 'en-u-kr-grek-latn'); CREATE COLLATION latinlast (provider = icu, locale = 'en@colReorder=grek-latn'); - 将希腊字母排在拉丁字母之前。(默认是拉丁字母在希腊字母之前。) + + 将希腊字母排在拉丁字母之前。(默认情况下是拉丁字母排在希腊字母之前。) + @@ -605,7 +608,9 @@ CREATE COLLATION german (provider = libc, locale = 'de_DE'); CREATE COLLATION upperfirst (provider = icu, locale = 'en-u-kf-upper'); CREATE COLLATION upperfirst (provider = icu, locale = 'en@colCaseFirst=upper'); - 将大写字母排在小写字母之前。(默认是小写字母在前。) + + 将大写字母排在小写字母之前。(默认情况下是小写字母在前。) + @@ -613,7 +618,9 @@ CREATE COLLATION german (provider = libc, locale = 'de_DE'); CREATE COLLATION special (provider = icu, locale = 'en-u-kf-upper-kr-grek-latn'); CREATE COLLATION special (provider = icu, locale = 'en@colCaseFirst=upper;colReorder=grek-latn'); - 组合上述两个选项。 + + 结合了以上两个选项。 + @@ -652,7 +659,17 @@ CREATE COLLATION french FROM "fr-x-icu"; 非确定性排序规则 - 排序规则分为确定性非确定性两类。确定性排序规则使用确定性比较,即仅当字符串由相同的字节序列组成时,才认为它们相等。非确定性比较则可能将字节不同的字符串判为相等。典型情况包括不区分大小写的比较、不区分重音的比较,以及采用不同 Unicode 规范形式的字符串之间的比较。这些不敏感的比较由排序规则提供者实际实现;确定性标志只决定是否使用逐字节比较来打破平局。关于术语的更多信息,另见 Unicode 技术标准 10 + + 排序规则要么是确定性的,要么是 + 非确定性的。确定性排序规则使用确定性比较,这 + 意味着只有当两个字符串由完全相同的字节序列组成时,才会认为它们相等。 + 非确定性比较则可能在两个字符串的字节不同的情况下,仍判断它们相等。典型 + 情况包括不区分大小写的比较、不区分重音的比较,以及对采用不同 Unicode + 规范化形式的字符串进行比较。具体是否实现这些不敏感比较,取决于排序规则 + 提供程序;deterministic标志只决定当比较结果相等时, + 是否再使用按字节比较来打破平局。更多术语信息可参见Unicode 技术标准 10。 + 要创建非确定性排序规则,可在CREATE COLLATION中指 diff --git a/zh/12/client-auth.sgml b/zh/12/client-auth.sgml index 9397dbf4..87329b75 100644 --- a/zh/12/client-auth.sgml +++ b/zh/12/client-auth.sgml @@ -37,7 +37,14 @@ pg_hba.conf - 客户端认证由一个配置文件控制,该文件通常名为 pg_hba.conf,存储在数据库集簇的数据目录中。(HBA 表示基于主机的认证。)initdb 初始化数据目录时,会安装一个默认的 pg_hba.conf 文件。不过,也可以将认证配置文件放在其他位置;参见 配置参数。 + + 客户端认证由一个配置文件控制,该文件按惯例命名为 + pg_hba.conf,并存放在数据库集簇的数据目录中。 + (HBA 代表 host-based authentication,即基于主机的认证。) + 当数据目录由 initdb 初始化时,会安装一个默认的 + pg_hba.conf 文件。不过,也可以把认证配置文件放在别处; + 请参见配置参数 。 + pg_hba.conf 文件的基本格式是一组记录,每行一条。空行和 # 注释字符之后的所有文本都会被忽略。记录不能跨行续写。每条记录由若干字段组成,字段之间用空格和/或制表符分隔。如果字段值用双引号括起来,就可以包含空白。在数据库、用户或地址字段中,将关键字(例如 allreplication)用引号括起来,会使其失去特殊含义,只匹配同名的数据库、用户或主机。 @@ -172,7 +179,7 @@ hostnogssenc database user IP地址范围使用标准的数字表示法来指定起始地址,然后是斜杠(/)和一个CIDR掩码长度。 掩码长度表示客户端IP地址必须匹配的高位比特数。给定IP地址中右侧的比特应为零。 - IP地址、/和CIDR掩码长度之间不得有任何空格。 + IP地址、/和CIDR掩码长度之间不得有任何空白。 @@ -209,12 +216,12 @@ hostnogssenc database user 以点(.)开头的主机名规范匹配实际主机名的后缀。 因此,.example.com将匹配foo.example.com - (但不仅仅是example.com)。 + (但不匹配单独的example.com)。 当在pg_hba.conf中指定主机名时,应确保名称解析相对快速。 - 最好设置一个本地名称解析缓存,如nscd。 + 设置一个本地名称解析缓存可能会有帮助,如nscd。 此外,还可能希望启用配置参数log_hostname,以便在日志中看到客户端的主机名而不是 IP 地址。 @@ -226,7 +233,7 @@ hostnogssenc database user 用户有时会想知道为什么主机名以这种看似复杂的方式处理,包括两次名称解析,其中包括对客户端IP地址的反向查找。 - 如果客户端的反向DNS条目未设置或生成了一些不良的主机名,则使用该功能会变得复杂。 + 如果客户端的反向DNS条目未设置或返回了不符合预期的主机名,则使用该功能会变得复杂。 这主要是为了效率:这样,连接尝试最多需要两次解析器查找,一次反向查找和一次正向查找。 如果某个地址存在解析器问题,那就只会成为该客户端的问题。 一个假设的替代实现只进行正向查找的情况下,在每次连接尝试期间都必须解析pg_hba.conf中提到的每个主机名。 @@ -241,7 +248,7 @@ hostnogssenc database user 请注意,这种行为与其他流行的基于主机名的访问控制实现一致,例如 - Apache HTTP服务器和TCP包装器。 + Apache HTTP 服务器和 TCP Wrappers。 @@ -253,7 +260,7 @@ hostnogssenc database user - 这两个字段可以用作IP地址/掩码长度 + 这两个字段可以用作IP-address/mask-length 表示法的替代方案。而不是指定掩码长度,实际掩码在一个单独的列中指定。 例如,255.0.0.0表示IPv4的CIDR掩码长度为8, 而255.255.255.255表示CIDR掩码长度为32。 @@ -268,7 +275,10 @@ hostnogssenc database user auth-method - 指定连接匹配此记录时使用的认证方法。这里概述可用的选项;详情参见 。所有选项都使用小写且区分大小写,因此即使是 ldap 这样的缩写,也必须使用小写。 + + 指定连接匹配此记录时要使用的认证方法。可选值在此处做了概述;详细说明见 。所有选项都必须使用小写并且区分大小写,因此即使是像 ldap 这样的首字母缩写也必须写成小写。 + + trust @@ -434,7 +444,15 @@ hostnogssenc database user auth-method 字段之后,可以有一个或多个形如 name=value 的字段,用于指定认证方法的选项。下文会详细说明各认证方法有哪些可用选项。 - 除下文列出的各方法专用选项外,还有一个与方法无关的认证选项 clientcert,可以在任何 hostssl 记录中指定。它可以设为 verify-caverify-full。二者都要求客户端提供有效(受信任)的 SSL 证书,而 verify-full 还要求证书中的 cn(通用名称)与用户名或适用的映射相匹配。这与 cert 认证方法(参见 )的行为类似,但可以将客户端证书验证与任何支持 hostssl 条目的认证方法搭配使用。 + + 除了下面列出的特定于方法的选项外,还有一个方法无关的认证选项 clientcert, + 可以在任何hostssl记录中指定。 + 此选项可以设置为verify-caverify-full。 + 这两个选项都要求客户端提供有效(受信任的)SSL证书, + 而verify-full还要求证书中的cn(通用名称)与用户名或适用映射匹配。 + 这种行为类似于 cert 认证方法(见), + 但允许把客户端证书验证与任何支持 hostssl 条目的认证方法配合使用。 + @@ -447,14 +465,14 @@ hostnogssenc database user由于每次连接尝试都会按顺序检查 pg_hba.conf 记录,因此记录的顺序很重要。通常,靠前的记录使用较严格的连接匹配条件和较弱的认证方法,靠后的记录使用较宽松的匹配条件和较强的认证方法。例如,可能希望对本地 TCP/IP 连接使用 trust 认证,而要求远程 TCP/IP 连接提供密码。此时,为来自 127.0.0.1 的连接指定 trust 认证的记录,应放在为更大范围的允许客户端 IP 地址指定密码认证的记录之前。 - 在启动以及主服务器进程收到SIGHUPSIGHUP信号时,pg_hba.conf文件会被读取。 - 如果你在活动的系统上编辑了该文件,你将需要通知 postmaster(使用pg_ctl reload,调用SQL函数pg_reload_conf(),或使用kill -HUP)使其重新读取该文件。 + 在启动时以及主服务器进程收到 SIGHUPSIGHUP 信号时,pg_hba.conf 文件会被读取。 + 如果你在运行中的系统上编辑了该文件,就需要通知 postmaster(使用 pg_ctl reload、调用 SQL 函数 pg_reload_conf(),或者使用 kill -HUP)重新读取该文件。 - 前面的说明在Microsoft Windows上不为真:在Windows上,pg_hba.conf文件中的任何更改会立即被应用到后续的新连接上。 + 前面的说明不适用于 Microsoft Windows:在Windows上,pg_hba.conf文件中的任何更改会立即被应用到后续的新连接上。 @@ -474,95 +492,92 @@ hostnogssenc database user 示例 <filename>pg_hba.conf</filename> 项 -# Allow any user on the local system to connect to any database with -# any database user name using Unix-domain sockets (the default for local -# connections). +# 允许本地系统上的任何用户 +# 通过 Unix 域套接字(本地连接的默认方式)以任意 +# 数据库用户名连接到任意数据库。 # # TYPE DATABASE USER ADDRESS METHOD local all all trust -# The same using local loopback TCP/IP connections. +# 相同的规则,但是使用本地环回 TCP/IP 连接。 # # TYPE DATABASE USER ADDRESS METHOD host all all 127.0.0.1/32 trust -# The same as the previous line, but using a separate netmask column +# 和前一行相同,但是使用了一个独立的掩码列 # # TYPE DATABASE USER IP-ADDRESS IP-MASK METHOD host all all 127.0.0.1 255.255.255.255 trust -# The same over IPv6. +# IPv6 上相同的规则 # # TYPE DATABASE USER ADDRESS METHOD host all all ::1/128 trust -# The same using a host name (would typically cover both IPv4 and IPv6). +# 使用主机名的相同规则(通常同时覆盖 IPv4 和 IPv6)。 # # TYPE DATABASE USER ADDRESS METHOD host all all localhost trust -# Allow any user from any host with IP address 192.168.93.x to connect -# to database "postgres" as the same user name that ident reports for -# the connection (typically the operating system user name). +# 允许来自任意具有 IP 地址192.168.93.x 的主机上任意 +# 用户以 ident 为该连接所报告的相同用户名连接到 +# 数据库 "postgres"(通常是操作系统用户名)。 # # TYPE DATABASE USER ADDRESS METHOD host postgres all 192.168.93.0/24 ident -# Allow any user from host 192.168.12.10 to connect to database -# "postgres" if the user's password is correctly supplied. +# 如果用户的密码被正确提供,允许来自主机 192.168.12.10 +# 的任意用户连接到数据库 "postgres"。 # # TYPE DATABASE USER ADDRESS METHOD host postgres all 192.168.12.10/32 scram-sha-256 -# Allow any user from hosts in the example.com domain to connect to -# any database if the user's password is correctly supplied. +# 如果用户的密码被正确提供,允许 example.com 域中主机上 +# 的任意用户连接到任意数据库。 # -# Require SCRAM authentication for most users, but make an exception -# for user 'mike', who uses an older client that doesn't support SCRAM -# authentication. +# 为大部分用户要求SCRAM认证,但是用户'mike'是个例外, +# 他使用的是不支持SCRAM认证的旧客户端。 # # TYPE DATABASE USER ADDRESS METHOD host all mike .example.com md5 host all all .example.com scram-sha-256 -# In the absence of preceding "host" lines, these three lines will -# reject all connections from 192.168.54.1 (since that entry will be -# matched first), but allow GSSAPI-encrypted connections from anywhere else -# on the Internet. The zero mask causes no bits of the host IP address to -# be considered, so it matches any host. Unencrypted GSSAPI connections -# (which "fall through" to the third line since "hostgssenc" only matches -# encrypted GSSAPI connections) are allowed, but only from 192.168.12.10. +# 如果没有前面的 "host" 行,这三行 +# 将拒绝所有来自 192.168.54.1的连接(因为该条目将首先被匹配), +# 但是允许来自互联网其他任何地方的 +# GSSAPI 加密连接。零掩码表示不会考虑主机 IP 地址中的任何位, +# 因此它会匹配任意主机。未加密的 GSSAPI 连接 +# (由于 "hostgssenc" 只匹配加密的 GSSAPI 连接,因此它们会继续匹配到第三行) +# 也是允许的,但只能来自 192.168.12.10。 # # TYPE DATABASE USER ADDRESS METHOD host all all 192.168.54.1/32 reject hostgssenc all all 0.0.0.0/0 gss host all all 192.168.12.10/32 gss -# Allow users from 192.168.x.x hosts to connect to any database, if -# they pass the ident check. If, for example, ident says the user is -# "bryanh" and he requests to connect as PostgreSQL user "guest1", the -# connection is allowed if there is an entry in pg_ident.conf for map -# "omicron" that says "bryanh" is allowed to connect as "guest1". +# 允许来自 192.168.x.x 主机的用户连接到任意数据库,如果它们能够 +# 通过 ident 检查。例如,假设 ident说用户是 "bryanh" 并且他要求以 +# PostgreSQL 用户 "guest1" 连接,如果在 pg_ident.conf 有一个映射 +# "omicron" 的条目表明 "bryanh" 被允许以 "guest1" 连接,则该连接将被允许。 # # TYPE DATABASE USER ADDRESS METHOD host all all 192.168.0.0/16 ident map=omicron -# If these are the only three lines for local connections, they will -# allow local users to connect only to their own databases (databases -# with the same name as their database user name) except for administrators -# and members of role "support", who can connect to all databases. The file -# $PGDATA/admins contains a list of names of administrators. Passwords -# are required in all cases. +# 如果这些是本地连接的唯一三行,它们将允许本地用户只连接到 +# 自己的数据库(与其数据库用户名同名的数据库),但管理员和 +# 角色 "support" 的成员除外,他们可以连接到所有数据库。 +# 文件 $PGDATA/admins 包含管理员名称列表。 +# 所有情况下都要求提供密码。 # # TYPE DATABASE USER ADDRESS METHOD local sameuser all md5 local all @admins md5 local all +support md5 -# The last two lines above can be combined into a single line: +# 上面的最后两行可以被整合为一行: local all @admins,+support md5 -# The database column can also use lists and file names: +# 数据库列也可以用列表和文件名: local db1,db2,@demodbs all md5 @@ -686,7 +701,7 @@ omicron bryanh guest1 - Peer 认证通常适用于本地连接,不过在某些情况下,信任认证也可能已经足够。 + 通常建议对本地连接使用 Peer 认证,不过在某些情况下,信任认证也可能已经足够。 密码认证是远程连接最容易采用的选择。 其余所有选项都需要某种外部安全基础设施(通常是认证服务器,或用于签发 SSL 证书的证书颁发机构),或者属于平台特定功能。 @@ -705,16 +720,14 @@ omicron bryanh guest1 - trust认证对于单用户工作站的本地连接是非常合适和方便的。通常它本身适用于一台多用户机器。不过,只要你利用文件系统权限限制了对服务器的 Unix 域套接字文件的访问,即使在多用户机器上,你也可以使用trust。 要做这些限制,你可以设置中描述的unix_socket_permissions配置参数(可能还有unix_socket_group)。 或者你可以设置unix_socket_directories配置参数来把 Unix 域套接字文件放在一个经过恰当限制的目录中。 + trust认证对于单用户工作站的本地连接是非常合适和方便的。通常它本身适用于一台多用户机器。不过,只要你利用文件系统权限限制了对服务器的 Unix 域套接字文件的访问,即使在多用户机器上,你也可能可以使用trust。 要做这些限制,你可以设置中描述的unix_socket_permissions配置参数(可能还有unix_socket_group)。 或者你可以设置unix_socket_directories配置参数来把 Unix 域套接字文件放在一个经过恰当限制的目录中。 设置文件系统权限只能有助于 Unix 套接字连接。本地 TCP/IP 连接不会被文件系统权限限制。因此,如果你想利用文件系统权限来控制本地安全,那么从pg_hba.conf中移除host ... 127.0.0.1 ...行,或者把它改为一个非trust认证方法。 - - 如果通过指定trustpg_hba.conf行让你信任每一个被允许连接到服务器的机器上的用户,trust认证只适合 TCP/IP 连接。为任何不是来自localhost(127.0.0.1)的 TCP/IP 连接使用trust很少是合理的。 - + 只有当你信任由 pg_hba.conf 中指定 trust 的行所允许连接的每台机器上的每个用户时,trust 认证才适合用于 TCP/IP 连接。对来自 localhost(127.0.0.1)以外的任何 TCP/IP 连接使用 trust,通常都不合理。 @@ -755,11 +768,9 @@ omicron bryanh guest1 md5 - - 方法md5使用一种自定义的安全性较低的挑战-响应机制。它能防止密码嗅探并且防止密码在服务器上以明文存储,但是无法保护攻击者想办法从服务器上窃取了密码哈希的情况。此外,现在认为MD5哈希算法对于确定攻击已经不再安全。 - + 方法md5使用一种自定义的、安全性较低的挑战-响应机制。它能防止密码嗅探,并避免在服务器上以明文存储密码;但如果攻击者设法从服务器上窃取了密码哈希,它就无法提供保护。此外,如今已不再认为 MD5 哈希算法能抵御有决心的攻击者。 - md5 方法不能与 功能一起使用。 + md5方法不能与功能一起使用。 为了简化从md5方法到较新的SCRAM方法的转变,如果在pg_hba.conf中指定了md5但是用户在服务器上的密码是为SCRAM(见下文)加密的,则将自动选择基于SCRAM的认证。 @@ -787,7 +798,7 @@ omicron bryanh guest1 - 要把现有安装从 md5 升级到 scram-sha-256,需要先确保所有正在使用的客户端库都足够新并支持 SCRAM,然后在 postgresql.conf 中设置 password_encryption = 'scram-sha-256',要求所有用户重新设置密码,并将 pg_hba.conf 中的认证方法说明改为 scram-sha-256。 + 要把现有安装从 md5 升级到 scram-sha-256,需要先确保所有正在使用的客户端库都足够新并支持 SCRAM,然后在 postgresql.conf 中设置 password_encryption = 'scram-sha-256',要求所有用户重新设置密码,并将 pg_hba.conf 中的认证方法设置改为 scram-sha-256 @@ -920,7 +931,8 @@ omicron bryanh guest1 当使用Kerberos认证时,SSPIGSSAPI的工作方式相同,详见 - 以下配置选项适用于 SSPI: + + SSPI 支持下列配置选项: @@ -939,7 +951,7 @@ omicron bryanh guest1 如果设为 1,则会在 include_realm 选项中使用域的 SAM 兼容名称(也称为 NetBIOS 名称)。这是默认值。如果设为 0,则会使用 Kerberos 用户主体名中的真实 realm 名称。 - 不要禁用这个选项,除非你的服务器运行在一个域账号(这包括一个域成员系统上的虚拟服务账号)下并且所有通过 SSPI 认证的所有客户端也在使用域账号,否则认证将会失败。 + 不要禁用这个选项,除非你的服务器运行在一个域账号(这包括一个域成员系统上的虚拟服务账号)下并且所有通过 SSPI 认证的客户端也在使用域账号,否则认证将会失败。 @@ -959,7 +971,10 @@ omicron bryanh guest1 map - 允许在系统用户名与数据库用户名之间建立映射。详见 。对于 username@EXAMPLE.COM(或较少见的 username/hostbased@EXAMPLE.COM)这样的 SSPI/Kerberos 主体,映射所用的用户名是 username@EXAMPLE.COM(或相应的 username/hostbased@EXAMPLE.COM),除非将 include_realm 设为 0,此时映射所见的系统用户名为 username(或 username/hostbased)。 + + 允许在系统用户名和数据库用户名之间进行映射。详见 。 + 对于 SSPI/Kerberos 主体,例如 username@EXAMPLE.COM(或者较少见的 username/hostbased@EXAMPLE.COM),用于映射的用户名分别是 username@EXAMPLE.COM(或 username/hostbased@EXAMPLE.COM),除非已经将 include_realm 设为 0;在那种情况下,映射时视为系统用户名的是 username(或 username/hostbased)。 + @@ -999,7 +1014,7 @@ omicron bryanh guest1 map - 允许在系统用户和数据库用户名称之间进行映射。详细信息请参见。 + 允许在系统用户名和数据库用户名之间进行映射。详见 @@ -1013,7 +1028,7 @@ omicron bryanh guest1
RFC 1413 - 标识协议的本意不是作为一种认证或访问控制协议。 + 标识协议的本意不是作为一种授权或访问控制协议。
@@ -1040,7 +1055,7 @@ omicron bryanh guest1 map - 允许在系统用户和数据库用户名称之间进行映射。详细信息请参见。 + 允许在系统用户名和数据库用户名之间进行映射。详见 @@ -1060,17 +1075,21 @@ omicron bryanh guest1 LDAP - 这种认证方法与 password 类似,只是使用 LDAP 验证密码。LDAP 仅用于验证用户名与密码的组合。因此,必须先在数据库中创建该用户,才能使用 LDAP 进行认证。 + + 这种认证方法的工作方式与 password 类似,只不过它使用 LDAP 作为密码验证方法。LDAP 只用于验证用户名/密码对。因此,在使用 LDAP 进行认证之前,用户必须已经存在于数据库中。 + LDAP 认证可以在两种模式下工作。第一种模式称为简单绑定模式,服务器会绑定到按 prefix username suffix 形式构造出的可分辨名称。通常,prefix 参数用于指定 cn=,或在 Active Directory 环境中指定 DOMAIN\suffix 则用于指定非 Active Directory 环境中 DN 的剩余部分。 - 第二种模式称为搜索+绑定模式,服务器首先使用由 ldapbinddnldapbindpasswd 指定的固定用户名和密码绑定到 LDAP 目录,并搜索试图登录数据库的用户。如果没有配置用户名和密码,则会尝试对目录进行匿名绑定。搜索会在 ldapbasedn 指定的子树上进行,并尝试对 ldapsearchattribute 指定的属性做精确匹配。一旦在搜索中找到了该用户,服务器就会作为该用户重新绑定到目录,并使用客户端指定的密码来验证登录是否正确。这种模式与 Apache mod_authnz_ldappam_ldap 等软件中的 LDAP 认证方案相同。这种方法使目录中用户对象的位置更具灵活性,但会对 LDAP 服务器额外发起两次请求。 + 第二种模式称为搜索+绑定模式,服务器首先使用由 ldapbinddnldapbindpasswd 指定的固定用户名和密码绑定到 LDAP 目录,并搜索试图登录数据库的用户。如果没有配置用户名和密码,则会尝试对目录进行匿名绑定。搜索会在 ldapbasedn 指定的子树上进行,并尝试对 ldapsearchattribute 指定的属性做精确匹配。一旦在搜索中找到了该用户,服务器会断开连接,再作为该用户重新绑定到目录,并使用客户端指定的密码来验证登录是否正确。这种模式与 Apache mod_authnz_ldappam_ldap 等软件中的 LDAP 认证方案相同。这种方法使目录中用户对象的位置更具灵活性,但会与 LDAP 服务器建立两个独立的连接。 - 以下配置选项适用于两种模式: + + 以下配置选项在两种模式下都使用: + ldapserver @@ -1091,8 +1110,7 @@ omicron bryanh guest1 ldapscheme - 设置为ldaps以使用LDAPS。这是一种非标准的使用LDAP - 进行SSL加密的方式,受一些LDAP服务器实现支持。另请参阅ldaptls + 设置为ldaps以使用LDAPS。这是一种非标准的通过 SSL 使用 LDAP 的方式,受一些LDAP服务器实现支持。另请参阅ldaptls 选项作为替代。 @@ -1110,7 +1128,9 @@ omicron bryanh guest1 注意使用ldapschemeldaptls仅会加密PostgreSQL 服务器和LDAP服务器之间的通信。PostgreSQL 服务器和PostgreSQL客户端之间的连接仍是未加密的,除非也在其上使用SSL。 - 以下选项仅适用于简单绑定模式: + + 下列选项只被用于简单绑定模式: + ldapprefix @@ -1130,7 +1150,9 @@ omicron bryanh guest1 - 以下选项仅适用于搜索加绑定模式: + + 以下选项仅在搜索+绑定模式中使用: + ldapbasedn @@ -1195,7 +1217,9 @@ ldap[s]://host[:port]/ - 将简单绑定的配置选项与搜索加绑定的选项混用会导致错误。 + + 将简单绑定模式的配置选项与搜索+绑定模式的配置选项混用是错误的。 + 在使用搜索+绑定模式时,可以使用由 ldapsearchattribute 指定的单个属性执行搜索,也可以使用由 ldapsearchfilter 指定的自定义搜索过滤器执行搜索。指定 ldapsearchattribute=foo 等价于指定 ldapsearchfilter="(foo=$username)"。如果两个选项都未指定,则默认使用 ldapsearchattribute=uid。 @@ -1205,25 +1229,35 @@ ldap[s]://host[:port]/PostgreSQL 编译时使用了 OpenLDAP 作为 LDAP 客户端库,则可以省略 ldapserver 设置。在这种情况下,会通过 RFC 2782 DNS SRV 记录查找主机名和端口列表。查找的名称是 _ldap._tcp.DOMAIN,其中 DOMAINldapbasedn 中提取。 - 下面是 LDAP 简单绑定配置的示例: + + 下面是一个简单绑定 LDAP 配置示例: + host ... ldap ldapserver=ldap.example.net ldapprefix="cn=" ldapsuffix=", dc=example, dc=net" -当请求以数据库用户 someuser 的身份连接数据库服务器时,PostgreSQL 会尝试使用 DN cn=someuser, dc=example, - dc=net 和客户端提供的密码绑定到 LDAP 服务器。如果连接成功,就会授予数据库访问权限。 + + 当请求以数据库用户 someuser 连接数据库服务器时,PostgreSQL 将尝试使用 DN cn=someuser, dc=example, dc=net 和客户端提供的密码绑定到 LDAP 服务器。如果该连接成功,数据库访问就会被授予。 + 下面是搜索加绑定配置的示例: host ... ldap ldapserver=ldap.example.net ldapbasedn="dc=example, dc=net" ldapsearchattribute=uid 当请求以数据库用户 someuser 的身份连接数据库服务器时,PostgreSQL 会尝试匿名绑定到 LDAP 服务器(因为没有指定 ldapbinddn),并在指定的基础 DN 下搜索 (uid=someuser)。如果找到了条目,就会尝试使用找到的信息和客户端提供的密码进行绑定。如果第二次连接成功,就会授予数据库访问权限。 - 下面是用 URL 表示的相同搜索加绑定配置: + + 下面是以 URL 形式写出的同一个搜索+绑定配置: + host ... ldap ldapurl="ldap://ldap.example.net/dc=example,dc=net?uid?sub" -一些支持 LDAP 认证的其他软件也使用相同的 URL 格式,因此更容易共享配置。 + + 某些支持 LDAP 认证的其他软件也使用相同的 URL 格式,因此共享这类配置会更容易。 + - 下面是搜索加绑定配置的示例,使用 ldapsearchfilter 代替 ldapsearchattribute,以便通过用户 ID 或电子邮件地址进行认证: + + 这里是一个搜索+绑定配置的示例,它使用 ldapsearchfilter 而不是 ldapsearchattribute 来允许用用户 ID 或电子邮件地址进行认证: + host ... ldap ldapserver=ldap.example.net ldapbasedn="dc=example, dc=net" ldapsearchfilter="(|(uid=$username)(mail=$username))" - 下面的搜索加绑定配置通过 DNS SRV 发现来查找 LDAP 服务的主机名和端口,所用域名为 example.net: + + 这是一个搜索+绑定配置的示例,它使用 DNS SRV 发现来查找域名 example.net 的 LDAP 服务的主机名和端口。 host ... ldap ldapbasedn="dc=example,dc=net" @@ -1452,7 +1486,7 @@ FATAL: user "andym" does not exist FATAL: database "testdb" does not exist - 你试图连接的数据库不存在。注意,如果你没有指定数据库名,默认会使用数据库用户名作为数据库名。 + 你试图连接的数据库不存在。注意,如果你没有指定数据库名,默认会使用数据库用户名作为数据库名,但这不一定是所需的数据库名。 diff --git a/zh/12/config.sgml b/zh/12/config.sgml index 1f83c6d1..ec854239 100644 --- a/zh/12/config.sgml +++ b/zh/12/config.sgml @@ -17,6 +17,7 @@ 设置参数 + 参数名称和值 @@ -43,11 +44,12 @@ + 字符串: 通常值被包括在单引号内,值内部的任何单引号都需要被双写。不过,如果值是一个简单数字或者 标识符,引号通常可以被省略。 - (与 SQL 关键字匹配的值需要在某些上下文中引用。) + (与 SQL 关键字匹配的值在某些上下文中需要加引号。) @@ -62,8 +64,16 @@ + - 带单位的数字:某些数值参数具有隐含单位,因为它们描述的是内存量或时间量。单位可能是字节、千字节、块(通常为八千字节)、毫秒、秒或分钟。不带修饰的数值会使用该设置的默认单位,可通过pg_settings.unit获知该单位。为方便起见,可以显式指定设置的单位,例如用'120 ms'表示时间值,系统会将它转换为参数的实际单位。注意,使用此功能时必须把值写成字符串(加引号)。单位名称区分大小写,数值和单位之间可以有空白。 + 带单位的数字: + 一些数字参数具有隐含单位,因为它们描述的是内存或时间量。单位可能是字节、千字节、块 + (通常为 8 千字节)、毫秒、秒或分钟。这类设置若给出不带单位的数字值,就会使用该设置的默认单位, + 可以通过 pg_settings.unit 了解该默认单位。为了方便, + 也可以显式指定单位,例如把时间值写成 '120 ms',系统会将其转换为该参数的实际单位。 + 注意,要使用这一特性,值必须写成字符串(带引号)。单位名称区分大小写,并且数字值与单位之间可以有空白。 + + 可用的内存单位是 B(字节)、kB(千字节)、 @@ -81,8 +91,11 @@ h(小时)和d(天)。 - 如果带单位指定了小数值,且存在下一级更小的单位,就会将其舍入为该更小单位的整数倍。例如,30.1 GB会被转换为30822 MB而不是32319628902 B。 - 如果参数为整数类型,则在任何单位转换之后,最终将结果舍入为整数。 + + + 如果指定了带单位的小数值,并且存在更小一级的单位,则会将其四舍五入为该更小单位的整数倍。 + 例如,30.1 GB会被转换为30822 MB,而不是32319628902 B。 + 如果参数是整数类型,则在完成所有单位转换之后还会再做一次整数取整。 @@ -98,15 +111,25 @@ + 通过配置文件影响参数 - 设置这些参数最基本的方法是编辑文件postgresql.confpostgresql.conf,该文件通常保存在数据目录中。初始化数据库集簇目录时会安装一份默认副本。该文件可能如下所示: + + 设置这些参数最基本的方法是编辑文件 + postgresql.confpostgresql.conf, + 它通常位于数据目录中。在数据库集簇目录初始化时,会安装该文件的一个默认副本。其内容示例如下: + # This is a comment log_connections = yes log_destination = 'syslog' search_path = '"$user", public' shared_buffers = 128MB -每行指定一个参数。名称与值之间的等号可以省略。空白没有特殊意义(引号内的参数值除外),空行会被忽略。井号(#)将该行的剩余部分标记为注释。不是简单标识符或数字的参数值必须用单引号括起。要在参数值中嵌入单引号,可以写两个单引号(推荐)或反斜线加单引号。如果文件中包含同一参数的多个条目,则只采用最后一个,忽略其余条目。 + + 每行指定一个参数。名称和值之间的等号是可选的。空白不重要(引号括起的参数值内部除外),空行会被忽略。 + 井号(#)表示该行余下部分是注释。不是简单标识符或数字的参数值必须用单引号括起。 + 要在参数值中嵌入单引号,可以写两个单引号(推荐)或使用反斜线转义单引号。 + 如果文件包含相同参数的多个条目,则忽略除最后一个之外的所有条目。 + 以这种方式设定的参数为集簇提供了默认值。除非这些设置被覆盖,活动会话看到的就是这些设置。 @@ -151,7 +174,8 @@ shared_buffers = 128MB - 通过 SQL 影响参数 + + 通过SQL影响参数 PostgreSQL提供了三个SQL命令来建立配置默认值。 @@ -162,14 +186,16 @@ shared_buffers = 128MB + - 命令允许针对一个数据库覆盖其全局设置。 + 命令允许针对各个数据库覆盖全局设置。 + - 命令允许用用户指定的值来覆盖全局设置和数据库设置。 + 命令允许用针对特定用户设置的值来覆盖全局设置和数据库设置。 @@ -188,16 +214,16 @@ shared_buffers = 128MB + - 命令允许察看所有参数的当前值。对应的函数是 - current_setting(setting_name text)。 + 命令允许查看所有参数的当前值。对应的函数为 current_setting(setting_name text) + - 那些可以在会话本地设置的参数,允许通过命令修改当前会话的参数值;它对其他会话没有影响。 - 相应的函数是set_config(setting_name, new_value, is_local)。 + 命令允许修改可在会话本地设置的参数的当前值;它对其他会话没有影响。对应的函数为 set_config(setting_name, new_value, is_local) @@ -218,9 +244,15 @@ shared_buffers = 128MB - 使用作用于此视图,具体来说就是更新其setting列,就等同于发出SET命令。例如,下述命令: + + + 在这个视图上使用并且指定更新setting + 列,其效果等同于发出SET命令。例如,下面的命令 + SET configuration_parameter TO DEFAULT; -等同于: + + 等效于: + UPDATE pg_settings SET setting = reset_val WHERE name = 'configuration_parameter'; @@ -230,23 +262,38 @@ UPDATE pg_settings SET setting = reset_val WHERE name = 'configuration_parameter + 通过 Shell 影响参数 - 除了在数据库或者角色层面上设置全局默认值或者进行覆盖,你还可以通过 shell 工具把设置 + 除了设置全局默认值或在数据库、角色级别覆盖默认值之外,你还可以通过 shell 工具把设置 传递给PostgreSQL。服务器和libpq 客户端库都能通过 shell 接受参数值。 - 在服务器启动期间,可以通过postgres命令的命令行参数传递参数设置。例如: + + + 在服务器启动期间,可以通过命令行参数把参数设置传递给 + postgres命令。例如: + postgres -c log_connections=yes -c log_destination='syslog' -以这种方式提供的设置会覆盖通过postgresql.confALTER SYSTEM进行的设置,因此不重启服务器就无法全局更改它们。 + + 这种方式提供的设置会覆盖通过postgresql.conf或者 + ALTER SYSTEM提供的设置,因此除了重启服务器之外无法从全局上改变它们。 + - 通过libpq启动客户端会话时,可以用PGOPTIONS环境变量指定参数设置。以这种方式建立的设置成为会话整个生命周期内的默认值,但不影响其他会话。出于历史原因,PGOPTIONS的格式与启动postgres命令时使用的格式相似;具体而言,必须指定标志。例如: + + + 当通过libpq启动一个客户端会话时,可以使用PGOPTIONS + 环境变量指定参数设置。这种方式建立的设置构成了会话生存期间的默认值,但是不会影响 + 其他的会话。由于历史原因,PGOPTIONS的格式和启动 + postgres命令时用到的相似,特别是标志必须被指定。 + 例如: + env PGOPTIONS="-c geqo=off -c statement_timeout=5min" psql @@ -291,7 +338,7 @@ include 'filename' 还有一个 include_if_exists 指令,其行为与 include 相同, 但在被引用文件不存在或无法读取时有所不同。普通的 include 会将其视为错误, - 而 include_if_exists 只会记录一条消息并继续处理引用配置文件。 + 而 include_if_exists 只会记录一条消息并继续处理引用它的配置文件。 @@ -302,21 +349,21 @@ include 'filename' postgresql.conf 文件也可以包含 include_dir 指令, 用来指定一个应被包含的配置文件目录。其用法如下: - include_dir 'directory' - - 非绝对目录名会被解释为相对于引用配置文件所在目录的路径。在指定目录中, +include_dir 'directory' + + 非绝对目录名会被解释为相对于引用它的配置文件所在目录的路径。在指定目录中, 只有名称以 .conf 结尾的非目录文件才会被包含。以 . 开头的文件名也会被忽略,以避免在某些平台上误处理隐藏文件。包含目录中的多个文件会按文件名顺序处理 (依据 C 区域规则排序,即数字在字母之前,大写字母在小写字母之前)。 - 包括文件或目录可以被用来在逻辑上分隔数据库配置的各个部分,而不是用一个很大的postgresql.conf文件。 + 包含文件或目录可以用来在逻辑上分隔数据库配置的各个部分,而不是用一个很大的postgresql.conf文件。 考虑一个有两台数据库服务器的公司,每一个都有不同的内存量。 - 很可能配置的元素都会被共享,例如用于日志的参数。但是两者关于内存的参数将会不同。 + 两者很可能会共享部分配置,例如日志设置。但是两者关于内存的参数将会不同。 并且还可能会有服务器相关的自定义。 一种管理这类情况的方法是将你的站点的自定义配置修改分成三个文件。 - 你可以把下面的内容加入到你的postgresql.conf文件末尾来包括它们: + 你可以把下面的内容加入到你的postgresql.conf文件末尾来包含它们: include 'shared.conf' include 'memory.conf' @@ -377,7 +424,7 @@ include_dir 'conf.d' - 指定用于数据存储的目录。这个选项只能在服务器启动时设置。 + 指定用于数据存储的目录。这个参数只能在服务器启动时设置。 @@ -437,7 +484,7 @@ include_dir 'conf.d' - 指定可被服务器创建的用于管理程序的额外进程 ID(PID)文件。这个参数只能在服务器启动的时候设置。 + 指定服务器应创建的额外进程 ID(PID)文件的名称,供服务器管理程序使用。这个参数只能在服务器启动的时候设置。 @@ -448,15 +495,15 @@ include_dir 'conf.d' - 如果你想把配置文件放在别的地方而不是数据目录中,那么postgres 命令行选项或者环境变量PGDATA必须指向包含配置文件的目录,并且postgresql.conf中(或者命令行上)的data_directory参数必须显示数据目录实际存放的地方。请注意,data_directory将覆盖PGDATA指定的数据目录位置,但是不覆盖配置文件的位置。 + 如果你想把配置文件放在别的地方而不是数据目录中,那么postgres 命令行选项或者环境变量PGDATA必须指向包含配置文件的目录,并且postgresql.conf中(或者命令行上)的data_directory参数必须设置为数据目录的实际位置。请注意,data_directory将覆盖PGDATA指定的数据目录位置,但是不覆盖配置文件的位置。 - 如果你愿意,可以使用选项config_filehba_file和/或ident_file单独指定配置文件名称和位置。config_file只能在postgres命令行上指定,但是其他文件可以在主配置文件中设置。如果所有三个参数外加data_directory被显式地设置,则不必指定PGDATA。 + 如果你愿意,可以使用选项config_filehba_file和/或ident_file单独指定配置文件名称和位置。config_file只能在postgres命令行上指定,但是其他参数可以在主配置文件中设置。如果所有三个参数外加data_directory被显式地设置,则不必指定PGDATA - 在设置任何这些参数时,相对路径将被解释为相对于postgres启动路径的路径。 + 在设置任何这些参数时,相对路径将被解释为相对于启动 postgres 时所在目录的路径。 @@ -478,7 +525,7 @@ include_dir 'conf.d' - 指定服务器用于监听来自客户端应用程序的连接的TCP/IP地址(指服务器网卡IP地址)。 + 指定服务器用于监听来自客户端应用程序的连接的TCP/IP地址。 该值采用逗号分隔的主机名和/或数字IP地址的形式。特殊条目*对应于所有可用的IP接口。 条目0.0.0.0允许监听所有IPv4地址,::允许监听所有IPv6地址。 如果列表为空,则服务器不会在任何IP接口上监听,此时只能使用Unix域套接字进行连接。 @@ -501,11 +548,11 @@ include_dir 'conf.d' - - - 服务器监听的 TCP 端口;默认是 5432 。请注意服务器会同一个端口号监听所有的 IP 地址。这个参数只能在服务器启动时设置。 - - + + 服务器监听的 TCP 端口,默认是 5432。请注意,服务器监听的所有 IP 地址都使用同一个端口号。 + 此参数只能在服务器启动时设置。 + + @@ -604,26 +651,19 @@ include_dir 'conf.d' - 设置 Unix 域套接字的访问权限。Unix 域套接字使用普通的 Unix 文件系统权限集。这个参数值应该是数字的形式,也就是系统调用chmodumask接受的 形式(如果使用自定义的八进制格式,数字必须以一个0(零)开头)。 + 设置 Unix 域套接字的访问权限。Unix 域套接字使用通常的 Unix 文件系统权限集。参数值应是以 chmodumask 系统调用所接受格式指定的数字权限模式。(要使用惯用的八进制格式,数字必须以 0(零)开头。) - - 默认的权限是0777,意思是任何人都可以连接。合理的候选是0770(只有用户和同组的人可以访问, 又见unix_socket_group)和0700(只有用户自己可以访问)(请注意,对于 Unix 域套接字,只有写权限有麻烦,因此没有对读取和执行权限的设置和收回)。 + 默认权限是 0777,表示任何人都可以连接。合理的其他取值包括 0770(仅属主和所属组,另见 unix_socket_group)和 0700(仅属主)。(注意,对 Unix 域套接字而言,只有写权限起作用,因此设置或撤销读权限和执行权限没有意义。) - - 这个访问控制机制与中的用户认证没有关系。 + 此访问控制机制独立于 中描述的机制。 - - 这个参数只能在服务器启动时设置。 + 此参数只能在服务器启动时设置。 - - 这个参数与完全忽略套接字权限的系统无关,尤其是自版本10以上的Solaris。 - 在那些系统上,可以通过把unix_socket_directories指向一个把搜索权限 - 限制给指定用户的目录来实现相似的效果。 - Windows 没有 Unix 域套接字,因此此参数在 Windows 上也没有意义。 + 此参数对完全忽略套接字权限的系统无效,尤其是 Solaris(截至 Solaris 10)。在这些系统上,可以将 unix_socket_directories 指向一个仅向目标用户授予搜索权限的目录,以达到类似效果。Windows 没有 Unix 域套接字,因此此参数在 Windows 上也没有意义。 @@ -636,10 +676,8 @@ include_dir 'conf.d' - - 通过Bonjour广告服务器的存在。默认值是关闭。 - 这个参数只能在服务器启动时设置。 + 启用通过 Bonjour 通告服务器存在的功能。默认值为关闭。此参数只能在服务器启动时设置。 @@ -652,11 +690,11 @@ include_dir 'conf.d' - - - 指定Bonjour服务名称。空字符串''(默认值)表示使用计算机名。 如果编译时没有打开Bonjour支持那么将忽略这个参数。这个参数只能在服务器启动时设置。 - - + + 指定 Bonjour 服务名。空字符串 ''(默认值)表示使用计算机名。 + 如果编译时未启用 Bonjour 支持,则此参数会被忽略。此参数只能在服务器启动时设置。 + + @@ -801,7 +839,7 @@ include_dir 'conf.d' 设置服务器的Kerberos密钥文件的位置。 - 默认为FILE:/usr/local/pgsql/etc/krb5.keytab(其中目录部分是在构建时由sysconfdir指定的;用pg_config --sysconfdir来决定)。 + 默认为FILE:/usr/local/pgsql/etc/krb5.keytab(其中目录部分是在构建时由sysconfdir指定的;可用pg_config --sysconfdir来确定该目录)。 如果这个参数被设为空字符串,它将被忽略,并且系统依赖的默认值被应用。 这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 详情请参考。 @@ -824,6 +862,7 @@ include_dir 'conf.d' + db_user_namespace (boolean) @@ -860,14 +899,14 @@ include_dir 'conf.d' - + SSL - 查看以获取有关设置SSL的更多信息。 + 关于 SSL 的设置,参见 @@ -1003,7 +1042,7 @@ include_dir 'conf.d' - 可用的密码组细节可能会随着OpenSSL 版本变化。 + 可用的密码套件细节可能会随着OpenSSL 版本变化。 可使用命令 openssl ciphers -v 'HIGH:MEDIUM:+3DES:!aNULL'来查看当前安装的OpenSSL版本的实际细节。 注意这个列表是根据服务器密钥类型在运行时过滤过的。 @@ -1018,17 +1057,16 @@ include_dir 'conf.d' - 指定是否使用服务器的 SSL 密码首选项,而不是用客户端的。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 - 默认值是 on。 + 指定是否使用服务器的 SSL 密码套件优先顺序,而非客户端的优先顺序。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。默认值为 on - - 9.4 之前的PostgreSQL版本没有这个设置并且总是使用客户端的首选项。这个设置主要用于与那些版本 - 的向后兼容性。使用服务器的首选项通常会更好,因为服务器更可能会被合适地配置。 + PostgreSQL 9.4 之前的版本没有此设置,始终采用客户端的优先顺序。此设置主要用于与这些旧版本保持向后兼容。采用服务器的优先顺序通常更好,因为服务器更可能得到适当配置。 + + ssl_ecdh_curve (string) @@ -1037,19 +1075,10 @@ include_dir 'conf.d' - 指定在 ECDH 密钥交换中使用的曲线名称。它需要被所有连接的客户端支持。 - 不必与服务器椭圆曲线密钥所使用的曲线相同。 - 该参数只能在postgresql.conf文件中或服务器命令行上设置。 - 默认值为prime256v1。 + 指定在 ECDH 密钥交换中使用的曲线名称。所有连接的客户端都必须支持该曲线。它不必与服务器椭圆曲线密钥使用的曲线相同。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。默认值为 prime256v1 - - OpenSSL最常见的曲线名称是: - prime256v1 (NIST P-256)、 - secp384r1 (NIST P-384)、 - secp521r1 (NIST P-521)。 - openssl ecparam -list_curves 命令可以显示可用曲线的完整列表, - 但并非所有曲线都可用于 TLS。 + OpenSSL 中最常见的曲线名称为:prime256v1(NIST P-256)、secp384r1(NIST P-384)、secp521r1(NIST P-521)。可以用 openssl ecparam -list_curves 命令显示可用曲线的完整列表,但其中并非所有曲线都能用于 TLS @@ -1062,18 +1091,13 @@ include_dir 'conf.d' - 设置要使用的最小 SSL/TLS 协议版本。当前可用的版本包括:TLSv1TLSv1.1TLSv1.2TLSv1.3。 - 旧版本的 OpenSSL 库不支持所有值;如果选择了不支持的设置,将会引发错误。 - TLS 1.0 之前的协议版本,也就是 SSL 版本 2 和 3,总是被禁用的。 + 设置要使用的最低 SSL/TLS 协议版本。当前有效值为:TLSv1TLSv1.1TLSv1.2TLSv1.3。较旧版本的 OpenSSL 库不支持所有值;如果选择了不支持的设置,就会报错。TLS 1.0 之前的协议版本,即 SSL 2 和 3,始终被禁用。 - - 默认值为TLSv1,主要是为了支持较旧版本的OpenSSL库。 - 如果所有软件组件都能支持较新的协议版本,你可能希望将此值设置得更高。 + 默认值为 TLSv1,主要用于支持较旧版本的 OpenSSL 库。如果所有软件组件均支持更新的协议版本,可以将此值设得更高。 - - 这个参数只能在postgresql.conf文件中或通过服务器命令行进行设置。 + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 @@ -1086,15 +1110,11 @@ include_dir 'conf.d' - - 设定要使用的最大SSL/TLS协议版本。 - 有效的版本为 , 添加一个空字符串,允许任何协议版本。 - 默认为允许任何版本。设置最大协议版本主要用于测试,或者某个组件在与较新的协议配合工作时出现了问题。 + 设置要使用的最高 SSL/TLS 协议版本。有效值与 相同,此外还可设为空字符串,表示允许任意协议版本。默认允许任意版本。设置最高协议版本主要用于测试,或处理某些组件无法正常配合更新协议工作的问题。 - - 这个参数只能在postgresql.conf文件中或通过服务器命令行进行设置。 + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 @@ -1107,13 +1127,11 @@ include_dir 'conf.d' - - 指定含有用于SSL密码的所谓临时DH家族的Diffie-Hellman参数的文件名。默认值为空,这种情况下将使用内置的默认DH参数。使用自定义的DH参数可以降低攻击者破解众所周知的内置DH参数的风险。可以用命令openssl dhparam -out dhparams.pem 2048创建自己的DH参数文件。 + 指定包含 Diffie-Hellman 参数的文件名,这些参数用于所谓临时 DH 系列的 SSL 密码套件。默认值为空,此时使用编译时内置的默认 DH 参数。如果攻击者破解了众所周知的内置 DH 参数,使用自定义 DH 参数可以降低由此带来的风险。可以用命令 openssl dhparam -out dhparams.pem 2048 创建自己的 DH 参数文件。 - - 这个参数只能在postgresql.conf文件中或通过服务器命令行进行设置。 + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 @@ -1126,21 +1144,17 @@ include_dir 'conf.d' - - 设置当需要一个密码(例如一个私钥)来解密SSL文件时会调用的一个外部命令。默认情况下,这个参数为空,表示使用内置的提示机制。 + 设置获取用于解密私钥等 SSL 文件的口令时要调用的外部命令。默认值为空,表示使用内置的提示机制。 - - 该命令必须将密码打印到标准输出并且以代码0退出。在该参数值中,%p被替换为一个提示字符串(要得到文字%,应该写成%%)。注意该提示字符串将可能含有空格,因此要确保加上适当的引号。如果输出的末尾有单一的新行,它会被剥离掉。 + 该命令必须将口令输出到标准输出,并以退出码 0 结束。参数值中的 %p 会被替换为提示字符串。(要表示字面值 %,应写成 %%。)提示字符串可能包含空白,因此务必正确加引号。如果输出末尾有一个换行符,会将其去掉。 - - 该命令实际上并不一定要提示用户输入一个密码。它可以从文件中读取密码、从钥匙链得到密码等等。确保选中的机制足够安全是用户的责任。 + 该命令不一定要提示用户输入口令,也可以从文件读取口令、从钥匙链获取口令等。用户应自行确保所选机制足够安全。 - - 这个参数只能在postgresql.conf文件中或通过服务器命令行进行设置。 + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 @@ -1153,13 +1167,10 @@ include_dir 'conf.d' - 这个参数决定在配置重载期间如果一个密钥文件需要密码时,是否也调用ssl_passphrase_command设置的密码命令。 - 如果这个参数为off(默认),那么在重载期间将忽略ssl_passphrase_command,如果在此期间需要密码则SSL配置将不会被重载。 - 对于要求一个TTY(当服务器正在运行时可能是不可用的)来进行提示的命令,这种设置是合适的。 - 例如,如果密码是从一个文件中得到的,将这个参数设置为on可能是合适的。 + 此参数决定:配置重载期间,如果密钥文件需要口令,是否也调用 ssl_passphrase_command 设置的口令命令。如果此参数为 off(默认值),则重载时会忽略 ssl_passphrase_command,如果需要口令,就不会重载 SSL 配置。此设置适合需要通过 TTY 提示用户的命令,因为服务器运行期间可能无法使用 TTY。例如,如果从文件中获取口令,则适合将此参数设为 on。 - 这个参数只能在postgresql.conf文件中或通过服务器命令行进行设置。 + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 @@ -1182,22 +1193,15 @@ include_dir 'conf.d' - - 设置数据库服务器将使用的共享内存缓冲区量。默认通常是 128 兆字节(128MB),但是如果你的内核设置不支持(在initdb时决定),那么可以会更少。 - 这个设置必须至少为 128 千字节。不过为了更好的性能,通常会使用明显高于最小值的设置。 - 如果指定值时没有单位,则以块为单位,即BLCKSZ字节,通常为8kB.(BLCKSZ 的非默认值改变最小值。) - 此参数只能在服务器启动时设置。 + 设置数据库服务器用于共享内存缓冲区的内存量。默认值通常为 128 兆字节(128MB),但如果内核设置不支持,则可能更小(在 initdb 期间确定)。此设置必须至少为 128 千字节。不过,要获得良好性能,通常需要远高于该最小值的设置。如果指定值时没有单位,则以块为单位,即 BLCKSZ 字节,通常为 8kB。(BLCKSZ 的非默认值会改变该最小值。)此参数只能在服务器启动时设置。 - - 如果有一个专用的 1GB 或更多内存的数据库服务器,一个合理的shared_buffers开始值是系统内存的 25%。即使更大的shared_buffers有效,也会造成一些工作负载, 但因为PostgreSQL同样依赖操作系统的高速缓冲区,将shared_buffers设置为超过 40% 的RAM不太可能比一个小点值工作得更好。为了能把对写大量新的或改变的数据的处理分布在一个较长的时间段内,shared_buffers更大的设置通常要求对max_wal_size也做相应增加。 + 如果专用数据库服务器具有 1GB 或更多内存,shared_buffers 的合理初始值是系统内存的 25%。对于某些工作负载,将 shared_buffers 设得更大也有效,但由于 PostgreSQL 同时依赖操作系统缓存,将超过 40% 的内存分配给 shared_buffers 不太可能比更小的值效果更好。将 shared_buffers 设得更大时,通常还需要相应增加 max_wal_size,以便将大量新数据或已修改数据的写入过程分散到更长的时间内。 - - 如果系统内存小于 1GB,一个较小的 RAM 百分数是合适的,这样可以为操作系统留下足够的空间。 + 对于内存少于 1GB 的系统,适合使用更小的内存比例,以便为操作系统留出足够空间。 - @@ -1208,6 +1212,7 @@ include_dir 'conf.d' + 控制是否为主共享内存区域请求巨型页。有效值是try(默认)、on以及off。如果huge_pages被设置为try,则服务器将尝试请求巨型页,但是如果失败会退回到默认的方式。如果为on,请求巨型页失败将使得服务器无法启动。如果为off,则不会请求巨型页。 @@ -1218,19 +1223,19 @@ include_dir 'conf.d' - 巨型页面的使用会导致更小的页面表以及花费在内存管理上的 CPU 时间更少,从而提高性能。更多有关Linux上使用巨型页面的细节请见。 + 巨型页的使用会导致更小的页表以及花费在内存管理上的 CPU 时间更少,从而提高性能。更多有关Linux上使用巨型页的细节请见 巨型页在Windows上被称为大页面。 要使用大页面,需要为运行PostgreSQL的Windows用户账号分配在内存中锁定页面的用户权限。 可以使用Windows的组策略工具(gpedit.msc)来分配用户权限在内存中锁定页面。 - 为了在命令窗口以单进程(而不是Windows服务)的方式启动数据库服务器,命令窗口必须以管理员身份运行或者禁用用户访问控制(UAC)。 + 为了在命令窗口以独立进程(而不是Windows服务)的方式启动数据库服务器,命令窗口必须以管理员身份运行或者禁用用户访问控制(UAC)。 当UAC被启用时,普通的命令窗口会在启动时收回用户权限在内存中锁定页面。 - 注意这种设置仅影响主共享内存区域。Linux、FreeBSD以及Illumos之类的操作系统也能为普通内存分配自动使用巨型页(也被称为超级页或者页面),而不需要来自PostgreSQL的显式请求。在Linux上,这被称为transparent huge pagestransparent huge pages(THP,透明巨型页)。已知这种特性对某些Linux版本上的某些用户会导致PostgreSQL的性能退化,因此当前并不鼓励使用它(与huge_pages的显式使用不同)。 + 注意这种设置仅影响主共享内存区域。Linux、FreeBSD以及Illumos之类的操作系统也能为普通内存分配自动使用巨型页(也被称为超级页或者页面),而不需要来自PostgreSQL的显式请求。在Linux上,这被称为transparent huge pages透明巨型页(THP,透明巨型页)。已知这种特性对某些Linux版本上的某些用户会导致PostgreSQL的性能退化,因此当前并不鼓励使用它(与huge_pages的显式使用不同)。 @@ -1243,16 +1248,11 @@ include_dir 'conf.d' - - 为每个数据库会话设置用于临时缓冲区的最大内存。这些缓冲区是仅用于访问临时表的会话本地缓冲区。 - 如果指定值时没有单位,则以块为单位,即BLCKSZ字节,通常为8kB。 - 默认为 8 兆字节(8MB)。(如果BLCKSZ不是 8 kB,则默认值按比例缩放。) - 这个设置可以在独立的会话内部被改变,但是只有在会话第一次使用临时表之前才能改变; 在会话中随后企图改变该值是无效的。 + 设置每个数据库会话用于临时缓冲区的最大内存量。这些是会话本地的缓冲区,仅用于访问临时表。如果指定值时没有单位,则以块为单位,即 BLCKSZ 字节,通常为 8kB。默认值为 8 兆字节(8MB)。(如果 BLCKSZ 不是 8kB,则默认值按比例变化。)可以在单个会话内更改此设置,但必须在该会话首次使用临时表之前更改;此后尝试更改该值,对该会话不会产生影响。 - - 一个会话将按照temp_buffers给出的限制根据需要分配临时缓冲区。如果在一个并不需要大量临时缓冲区的会话里设置一个大的数值, 其开销只是一个缓冲区描述符,或者说temp_buffers每增加一则增加大概 64 字节。不过,如果一个缓冲区被实际使用,那么它就会额外消耗 8192 字节(或者BLCKSZ字节)。 + 会话会按需分配临时缓冲区,上限为 temp_buffers。对于实际不需要很多临时缓冲区的会话,将此参数设得较大时,开销仅为 temp_buffers 每增加一就多分配一个缓冲区描述符,约为 64 字节。不过,如果实际使用了某个缓冲区,还会为它额外消耗 8192 字节(一般而言为 BLCKSZ 字节)。 @@ -1265,16 +1265,13 @@ include_dir 'conf.d' - 设置可以同时处于prepared状态的事务的最大数目(见)。把这个参数设置 为零(这是默认设置)将禁用预备事务特性。这个参数只能在服务器启动时设置。 + 设置可同时处于预备状态的事务的最大数量(见 )。将此参数设为零(默认值)会禁用预备事务功能。此参数只能在服务器启动时设置。 - - 如果你不打算使用预备事务,可以把这个参数设置为零来防止意外创建预备事务。如果你正在使用预备事务,你将希望把max_prepared_transactions至少设置为一样大,因此每一个会话可以有一个预备事务待处理。 + 如果不打算使用预备事务,应将此参数设为零,以防意外创建预备事务。如果使用预备事务,通常应将 max_prepared_transactions 设为不小于 的值,以便每个会话都能有一个待处理的预备事务。 - - 当运行一个备库时,你必须设置这个参数等于或大于主库上的参数。 - 否则,备库上将不允许查询。 + 运行备库时,必须将此参数设为与主库相同或更大的值。否则,备库上将不允许执行查询。 @@ -1287,14 +1284,7 @@ include_dir 'conf.d' - 设置查询操作(如排序或哈希表)在写入临时磁盘文件之前可使用的最大内存量。 - 如果未指定单位,则将其视为千字节。默认值为四兆字节(4MB)。 - 请注意,复杂查询可能同时执行多个排序和哈希操作, - 每个操作通常允许在开始将数据写入临时文件之前使用此值指定的内存量。 - 此外,可能有多个正在运行的会话同时执行此类操作。 - 因此,使用的总内存量可能是work_mem值的多倍; - 在选择值时必须牢记这一事实。排序操作用于ORDER BYDISTINCT和合并连接。 - 哈希表用于哈希连接、基于哈希的聚合和IN子查询的基于哈希的处理。 + 设置查询操作(如排序或哈希表)在写入临时磁盘文件之前可使用的最大内存量。如果未指定单位,则以千字节为单位。默认值为 4 兆字节(4MB)。请注意,复杂查询可能同时执行多个排序和哈希操作,每个操作在开始向临时文件写入数据之前,通常都可以使用此值指定的内存量。此外,多个正在运行的会话也可能并发执行此类操作。因此,使用的总内存量可能是 work_mem 值的数倍;选择此值时必须考虑这一点。排序操作用于 ORDER BYDISTINCT 和归并连接。哈希表用于哈希连接、基于哈希的聚合、以及基于哈希的 IN 子查询处理。 @@ -1307,18 +1297,13 @@ include_dir 'conf.d' - 指定维护操作(如 VACUUMCREATE INDEX 和 - ALTER TABLE ADD FOREIGN KEY)可使用的最大内存量。 - 如果指定值时未带单位,则按千字节解释。默认值为 64 兆字节(64MB)。 - 由于数据库会话一次只能执行一个这样的操作,而一个安装通常也不会有很多此类操作并发运行, - 因此把该值设置得明显大于 work_mem 通常是安全的。更大的设置可能改善清理和恢复数据库转储的性能。 + 指定维护操作(如 VACUUMCREATE INDEXALTER TABLE ADD FOREIGN KEY)可使用的最大内存量。如果未指定单位,则以千字节为单位。默认值为 64 兆字节(64MB)。由于一个数据库会话一次只能执行一个此类操作,而一个数据库系统通常也不会并发运行很多此类操作,因此可以安全地将该值设得远大于 work_mem。更大的设置可能改善清理和恢复数据库转储的性能。 - 请注意,当 autovacuum 运行时,分配的内存量最多可能达到此值的倍,因此请小心,不要将默认值设置得过高。 - 单独设置可能有助于控制这一点。 + 注意,自动清理运行时,最多可能分配此内存量的 倍,因此不要将默认值设得过高。单独设置 可能有助于控制这一点。 - 请注意,为收集死元组标识符,VACUUM最多只能使用1GB内存。 + 注意,在收集死元组标识符时,VACUUM 最多只能使用 1GB 内存。 @@ -1331,15 +1316,10 @@ include_dir 'conf.d' - 指定每个自动清理工作者进程能使用的最大内存量。 - 如果指定值时没有单位,则以千字节为单位。 - 其默认值为 -1,表示转而使用 的值。 - 当运行在其他上下文环境中时,这个设置对VACUUM的行为没有影响。 - 这个参数只能在postgresql.conf中或者服务器命令行上设置。 + 指定每个自动清理工作进程可使用的最大内存量。如果未指定单位,则以千字节为单位。默认值为 -1,表示改用 的值。该设置不影响其他上下文中运行的 VACUUM 的行为。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 - 为收集死元组标识符,autovacuum 最多只能使用1GB内存, - 因此将autovacuum_work_mem设置为更高的值,不会影响 autovacuum 扫描表时可以收集的死元组数量。 + 在收集死元组标识符时,自动清理最多只能使用 1GB 内存,因此将 autovacuum_work_mem 设得更高,不会影响自动清理扫描表时能收集的死元组数量。 @@ -1355,11 +1335,11 @@ include_dir 'conf.d' 指定服务器执行栈的最大安全深度。此参数的理想设置是由内核强制执行的实际栈大小限制 - (如由ulimit -s或本地等效设置),减去大约一兆字节的安全边界。 - 需要安全边界是因为服务器中并非每个例程都检查栈深度,而只在关键的潜在递归例程中检查。 + (如由ulimit -s或本地等效设置),减去大约一兆字节的安全余量。 + 需要安全余量是因为服务器中并非每个例程都检查栈深度,而只在关键的潜在递归例程中检查。 如果未指定单位,则将其视为千字节。默认设置为两兆字节(2MB), 这是保守且不太可能引起崩溃的小值。但是,这可能太小,无法执行复杂函数。 - 只有超级用户能更改这个设置。 + 只有超级用户才能更改此设置。 @@ -1376,10 +1356,7 @@ include_dir 'conf.d' - 指定服务器应用于主共享内存区域的共享内存实现,包括 PostgreSQL 的共享缓冲区和其他共享数据。 - 可能的值为 mmap(对使用 mmap 分配的匿名共享内存)、sysv(通过 shmget 分配的 System V 共享内存)和 windows(Windows 共享内存)。 - 并非在所有平台上都支持全部值;第一个受支持的选项是该平台的默认选项。 - sysv 选项不是任何平台的默认选项,通常不建议使用,因为它通常需要非默认的内核设置来允许大量的地址分配(参见 )。 + 指定服务器用于主共享内存区域的共享内存实现,该区域存放 PostgreSQL 的共享缓冲区及其他共享数据。可选值为 mmap(使用 mmap 分配的匿名共享内存)、sysv(通过 shmget 分配的 System V 共享内存)和 windows(Windows 共享内存)。并非所有平台都支持所有值;第一个受支持的选项是该平台的默认值。sysv 不是任何平台的默认选项,通常不建议使用,因为它一般需要更改内核的默认设置才能分配大量内存(见 )。 @@ -1392,13 +1369,7 @@ include_dir 'conf.d' - 指定服务器应该使用的动态共享内存实现。可能的值包括posix(使用shm_open分配的POSIX共享内存), - sysv(通过shmget分配的System V共享内存), - windows(用于Windows共享内存), - 和mmap(使用存储在数据目录中的内存映射文件模拟共享内存)。 - 并非所有平台都支持所有值;第一个支持的选项是该平台的默认值。 - mmap选项不是任何平台的默认选项,通常不建议使用,因为操作系统可能会反复将修改的页面写回磁盘,增加系统I/O负载; - 但在调试时,当pg_dynshmem目录存储在RAM磁盘上,或者其他共享内存设施不可用时,可能会有用。 + 指定服务器应使用的动态共享内存实现。可选值为 posix(使用 shm_open 分配的 POSIX 共享内存)、sysv(通过 shmget 分配的 System V 共享内存)、windows(Windows 共享内存)、mmap(使用存放在数据目录中的内存映射文件模拟共享内存)。并非所有平台都支持所有值;第一个受支持的选项是该平台的默认值。mmap 不是任何平台的默认选项,通常不建议使用,因为操作系统可能会反复将修改过的页面写回磁盘,增加系统 I/O 负载;不过,在调试、将 pg_dynshmem 目录存放在 RAM 磁盘上,或其他共享内存设施不可用时,它可能有用。 @@ -1419,17 +1390,11 @@ include_dir 'conf.d' - - 指定进程可以用于临时文件(如排序和哈希临时文件)或保留游标的存储文件的最大磁盘空间。 - 尝试超过此限制的事务将被取消。 - 如果未指定单位,则将其视为千字节。 - -1(默认值)表示没有限制。 - 只有超级用户能更改这个设置。 + 指定一个进程可用于临时文件的最大磁盘空间,例如排序和哈希临时文件,或保留游标的存储文件。尝试超过此限制的事务将被取消。如果未指定单位,则以千字节为单位。-1(默认值)表示没有限制。只有超级用户才能更改此设置。 - - 这个设置约束着一个给定PostgreSQL进程在任何瞬间所使用的所有临时文件的总空间。应该注意的是,与在查询执行中在幕后使用的临时文件相反,显式临时表所用的磁盘空间被这个设置所限制。 + 此设置限制单个 PostgreSQL 进程在任意时刻使用的所有临时文件的总空间。需要注意,显式临时表所用的磁盘空间计入该上限;计入的是查询执行过程中内部使用的临时文件。 @@ -1449,31 +1414,30 @@ include_dir 'conf.d' - 设置每个服务器子进程允许同时打开的最大文件数。默认值是一千个文件。 - 如果内核实施了安全的单进程限制,就不必担心此设置。但在某些平台上 - (尤其是大多数 BSD 系统),内核允许单个进程打开的文件数很多,以至于 - 当多个进程都试图打开这么多文件时,会超过系统实际能够支持的数量。 - 如果遇到Too many open files错误,可以尝试减小此设置。 - 此参数只能在服务器启动时设置。 + 设置每个服务器子进程允许同时打开的最大文件数量。默认值为一千个文件。如果内核强制实施了安全的每进程上限,就不必担心此设置。但在某些平台上(尤其是大多数 BSD 系统),内核允许单个进程打开的文件数量很大,如果很多进程都尝试打开这么多文件,就会远超系统实际能够支持的总量。如果遇到 Too many open files(打开的文件过多)错误,可尝试减小此设置。此参数只能在服务器启动时设置。 - + + 基于代价的清理延迟 - 在命令的执行过程中,系统维持着一个内部计数器来跟踪各种被执行的I/O操作的估算开销。当累计的代价达到一个限制(由vacuum_cost_limit指定),执行这些操作的进程将按照vacuum_cost_delay所指定的休眠一小段时间。然后它将重置计数器并继续执行。 + 执行 命令期间,系统维护一个内部计数器,记录已执行的各种 I/O 操作的估算代价。 + 当累计代价达到上限(由 vacuum_cost_limit 指定)时,执行该操作的进程会休眠一小段时间,时长由 vacuum_cost_delay 指定。 + 随后重置计数器并继续执行。 - 这个特性的出发点是允许管理员降低这些命令对并发的数据库活动产生的I/O影响。在很多情况下,VACUUMANALYZE等维护命令能否快速完成并不重要,而非常重要的是这些命令不会对系统执行其他数据库操作的能力产生显著的影响。基于代价的清理延迟提供了一种方式让管理员能够保证这一点。 + 此功能让管理员能够降低这些命令对并发数据库活动的 I/O 影响。在许多情况下,VACUUMANALYZE 等维护命令是否快速完成并不重要, + 但避免它们显著干扰系统执行其他数据库操作的能力通常很重要。基于代价的清理延迟为管理员提供了实现这一点的方法。 - 对于手动发出的VACUUM命令,该特性默认被禁用。要启用它,只要把vacuum_cost_delay变量设为一个非零值。 + 对于手动执行的 VACUUM 命令,此功能默认禁用。要启用它,将 vacuum_cost_delay 变量设为非零值。 @@ -1485,19 +1449,13 @@ include_dir 'conf.d' - - - 当超出开销限制时进程将要休眠的时间量。如果指定值时没有单位,则以毫秒为单位。 - 其默认值为0,这将禁用基于代价的清理延迟特性。正值将启用基于代价的清理。 - - - - 在使用基于代价的清理时,vacuum_cost_delay的合适值通常很小,也许是小于1毫秒。 - 虽然vacuum_cost_delay可以被设置为毫秒级别的值,但是在较老的平台上可能无法准确地测量这种延迟。 - 在这样的平台上,增加 VACUUM的节流资源消耗在1ms以上,需要改变其他的清理开销参数。 - 尽管如此,你应该保持 vacuum_cost_delay 在平台能持续测量的情况下尽可能小;大延迟没有帮助。 - - + + 超过代价上限后,进程将休眠的时长。如果未指定单位,则以毫秒为单位。默认值为 0,表示禁用基于代价的清理延迟功能。正值会启用基于代价的清理。 + + + 使用基于代价的清理时,vacuum_cost_delay 的合适值通常很小,可能不到 1 毫秒。虽然 vacuum_cost_delay 可以设为以毫秒为单位的小数值,但较旧的平台可能无法准确计量这种延迟。在这些平台上,若要让 VACUUM 的资源用量超过延迟设为 1ms 时的水平,需要调整其他清理代价参数。尽管如此,仍应将 vacuum_cost_delay 设为平台能够稳定计量的尽可能小的值;较大的延迟没有帮助。 + + @@ -1508,11 +1466,10 @@ include_dir 'conf.d' - - - 清理一个在共享缓存中找到的缓冲区的估计代价。它表示锁住缓冲池、查找共享哈希表和扫描页内容的代价。默认值为1。 - - + + 清理在共享缓冲区缓存中找到的缓冲区时所计入的估算代价。它表示锁定缓冲池、查找共享哈希表和扫描页内容的代价。默认值为 1。 + + @@ -1522,12 +1479,10 @@ include_dir 'conf.d' - - 清理一个必须从磁盘上读取的缓冲区的代价。 - 它表示锁住缓冲池、查找共享哈希表、从磁盘读取需要的块以及扫描其内容的代价。 - 默认值为10。 - - + + 清理必须从磁盘读取的缓冲区时所计入的估算代价。它表示锁定缓冲池、查找共享哈希表、从磁盘读取所需数据块并扫描其内容所需的工作量。默认值为 10。 + + @@ -1538,11 +1493,10 @@ include_dir 'conf.d' - - - 当清理修改一个之前干净的块时需要花费的估计代价。它表示再次把脏块刷出到磁盘所需要的额外I/O。默认值为20。 - - + + 清理操作修改原本干净的数据块时所计入的估算代价。它表示再次将脏块刷盘所需的额外 I/O。默认值为 20。 + + @@ -1553,33 +1507,31 @@ include_dir 'conf.d' - - - 将导致清理进程休眠的累计代价。默认值为200。 - - + + 会使清理进程休眠的累计代价。默认值为 200。 + + - - 有些操作会保持关键性的锁,这样可以尽快完成。基于代价的清理延迟在这类操作期间不会发生。因此有可能代价会累计至大大超过指定的限制。为了防止在这种情况下的无意义的长时间延迟,实际延迟的计算方式是vacuum_cost_delay * - accumulated_balance / - vacuum_cost_limit,且最大值是vacuum_cost_delay * 4。 + 某些操作持有关键的锁,因此应尽快完成。这些操作期间不会发生基于代价的清理延迟,所以累计代价可能远超指定上限。 + 为避免此时出现无益的长时间延迟,实际延迟按 vacuum_cost_delay * accumulated_balance / vacuum_cost_limit 计算, + 但最大不超过 vacuum_cost_delay * 4。 - 后台写入器 - 有一个独立的服务器进程,叫做后台写入器,它的功能就是发出写(新的或修改过的)共享缓冲区的命令。 - 当干净的共享缓存数量出现不足时,后台写入器写入一些脏缓存到文件系统,并标记为干净。 - 不过,后台写入器确实会增加 I/O 的总负荷,因为虽然在每个检查点间隔中一个重复弄脏的页面可能只会写出一次,但在同一个间隔中后台写入器可能会把它写出好几次。 - 在这一小节讨论的参数可以被用于调节本地需求的行为。 + 有一个独立的服务器进程,称为后台写入器,负责写出(新的或修改过的)共享缓冲区。 + 当干净的共享缓冲区数量似乎不足时,后台写入器会将一些脏缓冲区写入文件系统,并将其标记为干净。 + 这可以降低处理用户查询的服务器进程找不到干净缓冲区、因而不得不自行写出脏缓冲区的可能性。 + 不过,后台写入器确实会使总体 I/O 负载有所增加:反复变脏的页面原本可能在每个检查点间隔中只写出一次, + 而后台写入器可能在同一间隔内随着它变脏而多次写出。本节参数可用于根据实际需求调整此行为。 @@ -1591,13 +1543,10 @@ include_dir 'conf.d' - - - 指定后台写入器活动轮次之间的延迟。在每个轮次中,写入器都会为一定数量的脏缓冲区发出写操作(可以用下面的参数控制)。 - 然后它就休眠 bgwriter_delay的时长, 然后重复动作。当缓冲池中没有脏缓冲区时,不管 bgwriter_delay,它都会进入更长的休眠。如果指定值时没有单位,则以毫秒为单位。默认值是 200 毫秒(200ms)。 - 注意在许多系统上,休眠延迟的有效解析度是 10 毫秒;因此,为bgwriter_delay设置一个 不是 10 的倍数的值与把它设置为下一个更高的 10 的倍数是一样的效果。这个选项只能在服务器命令行上或者在postgresql.conf文件中设置。 - - + + 指定后台写入器各轮活动之间的延迟。每一轮中,写入器会对一定数量的脏缓冲区发出写操作(由下面的参数控制),然后休眠 bgwriter_delay 指定的时长,再重复此过程。不过,当缓冲池中没有脏缓冲区时,它会进入更长的休眠,而不受 bgwriter_delay 限制。如果未指定单位,则以毫秒为单位。默认值为 200 毫秒(200ms)。注意,在许多系统上,休眠延迟的有效分辨率为 10 毫秒;将 bgwriter_delay 设为不是 10 的倍数的值,可能与将它设为下一个更大的 10 的倍数效果相同。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 + + @@ -1608,11 +1557,10 @@ include_dir 'conf.d' - - - 在每个轮次中,不超过这么多个缓冲区将被后台写入器写出。把这个参数设置为零可禁用后台写出(注意被一个独立、专用辅助进程管理的检查点不受影响)。默认值是 100 个缓冲区。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 - - + + 后台写入器每轮写出的缓冲区数量不会超过此值。设为零会禁用后台写入。(由另一个独立的专用辅助进程管理的检查点不受影响。)默认值为 100 个缓冲区。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 + + @@ -1623,11 +1571,10 @@ include_dir 'conf.d' - - - 每一轮次要写的脏缓冲区的数目基于最近几个轮次中服务器进程需要的新缓冲区的数目。 最近所需的平均值乘以bgwriter_lru_multiplier可以估算下一轮次中将会需要的缓冲区数目。脏缓冲区将被写出直到有很多干净可重用的缓冲区(然而,每一轮次中写出的缓冲区数不超过bgwriter_lru_maxpages)。 因此,设置为 1.0 表示一种刚刚好的策略,这种策略会写出正好符合预测值的数目的缓冲区。 更大大的值可以为需求高峰提供某种缓冲,而更小的值则需要服务进程来处理一些写出操作。默认值是 2.0。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 - - + + 每轮写出的脏缓冲区数量取决于最近几轮服务器进程所需的新缓冲区数量。将近期平均需求乘以 bgwriter_lru_multiplier,即可估算下一轮所需的缓冲区数量。写入器会写出脏缓冲区,直到可用的干净且可重用缓冲区达到这一数量。(不过,每轮写出的缓冲区数量不会超过 bgwriter_lru_maxpages。)因此,设为 1.0 表示采用恰好及时策略,写出的缓冲区数量恰好等于预测需求量。更大的值可为需求突增留出余量,而更小的值则有意将部分写操作留给服务器进程执行。默认值为 2.0。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 + + @@ -1638,18 +1585,16 @@ include_dir 'conf.d' - - - 只要后台写入的数据超过这个数量,尝试强制 OS 把这些写发送到底层存储上。这样做将限制内核页缓存中脏数据的量,降低了在检查点末尾发出一个 fsync 时或者 OS 在后台大批量写回数据时卡住的可能性。 - 那常常会导致大幅度压缩的事务延迟,但是也有一些情况(特别是负载超过但小于 OS 页面高速缓存)的性能会降低。这种设置可能会在某些平台上没有效果。 - 如果指定值时没有单位,则以块为单位,即为BLCKSZ 字节,通常为8kB.合法的范围在0(禁用受控写回)和2MB之间。Linux 上的默认值是512kB,其他平台上是0(如果BLCKSZ不是8kB,则默认值和最大值会按比例缩放至这个值)。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 - - + + 每当后台写入器写出的数据超过此数量时,就尝试强制操作系统将这些写操作发往底层存储。这样可以限制内核页缓存中的脏数据量,降低在检查点结束时调用 fsync,或操作系统在后台以较大批次写回数据时发生停顿的可能性。通常,这能大幅降低事务延迟,但在某些情况下性能可能下降,尤其是工作负载大于 而小于操作系统页缓存时。此设置在某些平台上可能没有效果。如果未指定单位,则以块为单位,即 BLCKSZ 字节,通常为 8kB。有效范围为 0(禁用强制写回)至 2MB。Linux 上的默认值为 512kB,其他平台为 0。(如果 BLCKSZ 不是 8kB,默认值和最大值将按比例变化。)此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 + + - 较小的bgwriter_lru_maxpagesbgwriter_lru_multiplier可以降低由后台写入器造成的额外 I/O 开销。但更可能的是,服务器进程将必须自己发出写入操作,这会延迟交互式查询。 + 较小的 bgwriter_lru_maxpagesbgwriter_lru_multiplier 可以降低后台写入器造成的额外 I/O 负载, + 但也会增加服务器进程必须自行发出写操作的可能性,从而延迟交互式查询。 @@ -1664,29 +1609,19 @@ include_dir 'conf.d' - - 设置PostgreSQL预期可以同时执行的并发磁盘 I/O 操作数量。 - 提高该值会增加任何单个PostgreSQL会话尝试并行发起的 I/O 操作数。 - 允许的范围是 1 到 1000,或者零表示禁用异步 I/O 请求。目前,此设置只影响位图堆扫描。 - - - - 对于磁盘,此设置的一个良好起点是数据库所用的 RAID 0 条带或 RAID 1 镜像中独立磁盘的数量。 - (对于 RAID 5,不应计入奇偶校验盘。)但是,如果数据库经常忙于处理并发会话发出的多个查询,较低的值可能已足以让磁盘阵列保持忙碌。 - 超过使磁盘保持忙碌所需的值只会产生额外的 CPU 开销。 - SSD 和其他基于内存的存储通常可以处理很多并发请求,因此最佳值可能达到数百。 - - - - 异步 I/O 依赖有效的posix_fadvise函数,而某些操作系统缺少该函数。 - 如果不存在该函数,将此参数设置为零以外的任何值都会导致错误。 - 在某些操作系统上(例如 Solaris),该函数虽然存在,但实际上不起任何作用。 - - - - 在支持的系统上默认值为 1,否则为 0。对于位于特定表空间中的表,可以通过设置同名的表空间参数覆盖此值(参见)。 - - + + 设置 PostgreSQL 预期可以同时执行的并发磁盘 I/O 操作数量。提高此值会增加单个 PostgreSQL 会话尝试并行发起的 I/O 操作数量。允许的范围为 1 至 1000,或设为零以禁用异步 I/O 请求。目前,此设置仅影响位图堆扫描。 + + + 对于磁盘,可以将为数据库提供存储的 RAID 0 条带或 RAID 1 镜像中的独立磁盘数量作为合理初始值。(对于 RAID 5,不应计入校验盘。)不过,如果数据库经常忙于执行并发会话发出的多个查询,较小的值可能就足以使磁盘阵列保持繁忙。超过使磁盘保持繁忙所需的值只会增加 CPU 开销。SSD 和其他基于内存的存储通常可以处理大量并发请求,因此最佳值可能达到数百。 + + + 异步 I/O 依赖于有效的 posix_fadvise 函数,而某些操作系统缺少此函数。如果该函数不存在,将此参数设为任何非零值都会报错。在某些操作系统(如 Solaris)上,该函数虽然存在,却实际上不做任何事情。 + + + 支持此功能的系统上默认值为 1,其他系统为 0。对于位于特定表空间中的表,可以通过设置同名的表空间参数覆盖此值(见 )。 + + @@ -1696,19 +1631,16 @@ include_dir 'conf.d' - - 设置系统能够支持的后台进程的最大数量。这个参数只能在服务器启动时设置。默认值为 8。 + + 设置系统能够支持的后台进程的最大数量。此参数只能在服务器启动时设置。默认值为 8。 - - - 在运行一个备库时,你必须把这个参数设置为等于或者高于主库上的值。 - 否则,备库上将不允许查询。 - - - - 在更改这个值时,考虑也对以及进行调整。 - - + + 运行备库时,必须将此参数设为与主库相同或更大的值。否则,备库上将不允许执行查询。 + + + 更改此值时,也应考虑调整 。 + + @@ -1719,19 +1651,16 @@ include_dir 'conf.d' - - - 设置单个Gather或者Gather Merge节点能够开始的工作者的最大数量。并行工作者会从建立的进程池中取得,数量由限制。注意所要求的工作者数量在运行时可能实际无法被满足。如果这种事情发生,该计划将会以比预期更少的工作者运行,这可能会不太高效。默认值是2。把这个值设置为0将会禁用并行查询执行。 - - - - 注意并行查询可能消耗比非并行查询更多的资源,因为每一个工作者进程时一个完全独立的进程,它对系统产生的影响大致和一个额外的用户会话相同。在为这个设置选择值时,以及配置其他控制资源利用的设置(例如)时,应该把这个因素考虑在内。work_mem之类的资源限制会被独立地应用于每一个工作者,这意味着所有进程的总资源利用可能会比单个进程时高得多。例如,一个使用 4 个工作者的并行查询使用的 CPU 时间、内存、I/O 带宽可能是不使用工作者时的 5 倍之多。 - - - - 并行查询的更多信息请见。 - - + + 设置单个 GatherGather Merge 节点能够启动的工作进程的最大数量。并行工作进程取自 建立的进程池,并受到 的限制。注意,运行时实际可用的工作进程可能不足请求的数量。此时,计划会使用少于预期的工作进程运行,效率可能较低。默认值为 2。设为 0 会禁用并行查询执行。 + + + 注意,并行查询消耗的资源可能远多于非并行查询,因为每个工作进程都是完全独立的进程,对系统的影响大致相当于额外增加一个用户会话。选择此设置的值,以及配置其他控制资源使用的设置(如 )时,都应考虑这一点。work_mem 等资源限制分别应用于每个工作进程,因此所有进程的总资源用量可能远高于单个进程通常的用量。例如,使用 4 个工作进程的并行查询,其 CPU 时间、内存、I/O 带宽等用量可能达到完全不使用工作进程的查询的 5 倍。 + + + 并行查询的更多信息参见 。 + + @@ -1741,17 +1670,13 @@ include_dir 'conf.d' - - 设置单一工具性命令能够启动的并行工作者的最大数目。 - 当前,支持使用并行工作者的工具性命令是CREATE INDEX,并且只有在构建B-树索引时才能并行。 - 并行工作者从由创建的进程池中取出,数量由控制。 - 注意实际在运行时所请求数量的工作者可能不可用。如果发生这种情况,工具性操作将使用比预期数量少的工作者运行。默认值为2。将这个值设置为0可以禁用工具性命令对并行工作者的使用。 - - - - 注意并行工具性命令不应该消耗比同等数量非并行操作更多的内存。这种策略与并行查询不同,并行查询的资源限制通常是应用在每个工作者进程上。并行工具性命令把资源限制maintenance_work_mem当作对整个工具性命令的限制,而不管其中用到了多少个并行工作者进程。不过,并行工具性命令实际上可能仍会消耗更多的CPU资源和I/O带宽。 - - + + 设置单个工具命令能够启动的并行工作进程的最大数量。目前,唯一支持使用并行工作进程的工具命令是 CREATE INDEX,且仅在构建 B-树索引时支持。并行工作进程取自 建立的进程池,并受到 的限制。注意,运行时实际可用的工作进程可能不足请求的数量。此时,工具操作会使用少于预期的工作进程运行。默认值为 2。设为 0 会禁止工具命令使用并行工作进程。 + + + 注意,并行工具命令的内存消耗不应明显高于等效的非并行操作。这与并行查询的策略不同,后者的资源限制通常分别应用于每个工作进程。并行工具命令将 maintenance_work_mem 视为整个工具命令的资源上限,而不论使用多少个并行工作进程。不过,并行工具命令仍可能消耗多得多的 CPU 资源和 I/O 带宽。 + + @@ -1761,8 +1686,10 @@ include_dir 'conf.d' - 设置系统能够支持的并行操作工作进程最大数量。默认值为 8。增大或减小该值时,也应考虑调整。另外注意,将此值设得高于不会产生效果,因为并行工作进程取自该设置所建立的工作进程池。 - + + 设置系统能够为并行操作提供的工作进程的最大数量。默认值为 8。增大或减小此值时,也应考虑调整 。此外,将此值设得大于 没有效果,因为并行工作进程取自该设置建立的工作进程池。 + + @@ -1773,27 +1700,20 @@ include_dir 'conf.d' - - - 当单个后端写入数据的量超过这个数量时,尝试强制操作系统发送这些写入到底层存储。 - 这样做将限制内核的页面缓存中的脏数据量,降低在检查点末尾发出fsync时暂停的可能性,或者当操作系统在后台大批量的写回数据时。 - 通常的结果会大大减少事务延迟,但也有一些情况,特别是当工作负载大于,但小于操作系统的页面缓存时,性能可能会下降。 - 此设置在某些平台上可能无效。 - 如果指定此值时没有单位,则将其作为块,即BLCKSZ字节,通常为8kB。 - 有效范围在0,禁止强制回写,和2MB之间。 - 默认值是0,即没有强制回写。 - (如果BLCKSZ不是8kB,则最大值按其比例缩放。) - - + + 每当单个后端写出的数据超过此数量时,就尝试强制操作系统将这些写操作发往底层存储。这样可以限制内核页缓存中的脏数据量,降低在检查点结束时调用 fsync,或操作系统在后台以较大批次写回数据时发生停顿的可能性。通常,这能大幅降低事务延迟,但在某些情况下性能可能下降,尤其是工作负载大于 而小于操作系统页缓存时。此设置在某些平台上可能没有效果。如果未指定单位,则以块为单位,即 BLCKSZ 字节,通常为 8kB。有效范围为 0(禁用强制写回)至 2MB。默认值为 0,即不强制写回。(如果 BLCKSZ 不是 8kB,最大值将按比例变化。) + + - - old_snapshot_threshold (integer) - - old_snapshot_threshold配置参数 - - - + + + old_snapshot_threshold (integer) + + old_snapshot_threshold 配置参数 + + + 设置查询快照在使用时不发生snapshot too old错误的最短可用时间。 已死亡超过该阈值的数据允许被清理掉。这有助于在快照长期保持使用时防止膨胀。 @@ -1815,7 +1735,7 @@ include_dir 'conf.d' - 启用此特性后,关系末尾释放出来的空间将不能返还给操作系统,因为那样会移除 + 启用此特性后,关系末尾释放出来的空间将不能返还给操作系统,因为那样可能会移除 检测snapshot too old条件所需的信息。分配给某个关系的全部空间都会一直 归属于该关系,只能在该关系内部重用,除非显式释放(例如使用 VACUUM FULL)。 @@ -1829,8 +1749,8 @@ include_dir 'conf.d' snapshot too old错误的可能性。 - - + + @@ -1864,12 +1784,12 @@ include_dir 'conf.d' CLUSTER 向同一事务中创建或截断的表执行COPY - 但最少的 WAL 不包含足够的信息来从基础备份和 WAL 日志重建数据,因此必须使用replica或更高级别来启用 WAL 归档 + 但 minimal 级别的 WAL 不包含足够的信息来从基础备份和 WAL 日志重建数据,因此必须使用replica或更高级别来启用 WAL 归档 ()和流复制。 logical级别上,记录与replica相同的信息,以及从WAL中提取逻辑变更集所需的信息。 - 使用logical级别会增加WAL的容量,特别是如果许多表被配置为REPLICA IDENTITY FULL, + 使用logical级别会增加 WAL 的数量,特别是如果许多表被配置为REPLICA IDENTITY FULL, 并且执行了许多UPDATEDELETE语句。 @@ -1896,16 +1816,15 @@ include_dir 'conf.d' - 能安全关闭fsync的环境的示例包括从一个备份文件中初始加载一个新数据库集簇、使用一个数据库集簇来在数据库被删掉并重建之后处理一批数据,或者一个被经常重建并却不用于失效备援的只读数据库克隆。单独的高质量硬件不足以成为关闭fsync的理由。 + 可以安全关闭fsync的情形包括:从备份文件初始装载一个新数据库集簇;用数据库集簇处理一批数据,处理后就丢弃并重建该数据库;或者使用经常重建且不用于故障切换的只读数据库克隆。仅有高质量硬件不足以成为关闭fsync的理由。 - 当把fsync从关闭改成打开时,为了可靠的恢复,需要强制在内核中的所有被修改的缓冲区进入持久化存储。这可以在多个时机来完成: - 在集簇被关闭时或在fsync因为运行initdb --sync-only而打开时、运行sync时、卸载文件系统时或者重启服务器时。 + 为确保将fsync从关闭改为打开后能够可靠恢复,必须将内核中所有已修改的缓冲区强制写入持久存储。可以在集簇已关闭或fsync已开启时,通过运行initdb --sync-only、运行sync、卸载文件系统或重启服务器来完成。 - 在很多情况下,为不重要的事务关闭可以提供很多关闭fsync的潜在性能收益,并不会有的同时, 关闭fsync可以提供很多潜在的性能优势,而不会有伴随着的数据损坏风险。 + 在很多情况下,为非关键事务关闭,可以获得关闭fsync所带来的大部分潜在性能收益,同时避免伴随的数据损坏风险。 @@ -1922,39 +1841,27 @@ include_dir 'conf.d' - 指定数据库服务器返回success指示给客户端之前,必须要完成多少WAL处理。 - 合法的值为remote_apply, on(默认值), remote_write,local, 和 off。 + 指定数据库服务器向客户端返回成功指示之前,必须完成多少 WAL 处理。有效值为remote_applyon(默认值)、remote_writelocaloff - 如果synchronous_standby_names为空,则唯一有意义的设置为onoff ; - remote_applyremote_writelocal都提供与on相同的本地同步级别。 - 所有非off模式的本地行为都是等待WAL的本地刷新到磁盘。 - 在 off模式,无需等待,因此在向客户端报告成功和以后保证事务安全防止服务器崩溃之间可能会出现延迟。 - (最大的延迟是的三倍。) - 不同于,将这个参数设置为off不会产生数据库不一致性的风险:一个操作系统或数据库崩溃可能会造成一些最近据说已提交的事务丢失,但数据库状态是一致的,就像这些事务已经被干净地中止。 - 因此,当性能比完全确保事务的持久性更重要时,关闭synchronous_commit可以作为一个有效的代替手段。更多讨论见。 + 如果synchronous_standby_names为空,只有onoff两种设置有意义;remote_applyremote_writelocal提供的本地同步级别都与on相同。所有非off模式在本地都会等待 WAL 刷写到磁盘。在off模式下则无需等待,因此,向客户端报告成功后,可能还要经过一段时间,才能保证事务不会因服务器崩溃而丢失。(最大延迟为的三倍。)与不同,将此参数设为off不会带来数据库不一致的风险:操作系统或数据库崩溃可能会使一些最近报告已提交的事务丢失,但数据库状态会与这些事务已正常中止时完全相同。因此,当性能比完全确保事务持久性更重要时,关闭synchronous_commit可以是一种有用的替代方案。更多讨论见 - 如果为非空,synchronous_commit也控制是否事务提交将等待它们的 WAL 记录在备库上被处理。 + 如果非空,synchronous_commit还控制事务提交是否等待备库处理其 WAL 记录。 - 当设置为 remote_apply 时,提交将等待,直到来自当前同步备库的答复显示他们已收到事务的提交记录并应用了它,以便它变得对备库上的查询可见,并写入备库上的持久存储。 - 这将导致比以前的设置更大的提交延迟,因为它等待 WAL 重放(replay)。 - 当设置为on时,提交将等待,直到来自于当前同步的备库的回复显示它们已经收到了事务的提交记录并将其刷入了磁盘。 - 这保证事务将不会被丢失,除非主库和所有同步备库都遭受到了数据库存储损坏的问题。 - 当这个参数被设置为remote_write时,提交将等待,直到来自当前的同步备库的回复指示它们已经收到了该事务的提交记录并且已经把该记录写到它们的文件系统,这种设置保证数据得以保存,在PostgreSQL的备库实例崩溃时,但是不能保证备库遭受操作系统级别崩溃时数据能被保持,因为数据不一定必须要在备库上达到持久存储。 - 设置local会导致提交等待本地刷写到磁盘,而不是复制。在使用同步复制时这通常是不可取的,但是为了完整性提供了这个选项。 + 设为remote_apply时,提交会等待当前同步备库回复,确认已收到并应用该事务的提交记录,使其对备库上的查询可见,并且已将其写入备库的持久存储。由于需要等待 WAL 重放,这会比之前的设置产生大得多的提交延迟。设为on时,提交会等待当前同步备库回复,确认已收到事务的提交记录,并已将其刷写到持久存储。这能保证事务不会丢失,除非主库和所有同步备库的数据库存储都损坏。设为remote_write时,提交会等待当前同步备库回复,确认已收到事务的提交记录,并已将其写入各自的文件系统。此设置能保证备库上的PostgreSQL实例崩溃时数据不丢失,但不能保证备库发生操作系统级别崩溃时数据不丢失,因为数据未必已写入备库的持久存储。设为local时,提交会等待本地刷盘,但不等待复制。使用同步复制时通常不希望采用这种设置,提供它是为了使选项完整。 - 这个参数可以随时被修改;任何一个事务的行为由其提交时生效的设置决定。因此,可以同步提交一些事务,同时异步提交其他事务。例如,当默认是相反时,实现一个单一多语句事务的异步提交,在事务中发出SET LOCAL synchronous_commit TO OFF。 + 此参数可以随时更改;每个事务的行为由提交时生效的设置决定。因此,让一些事务同步提交、另一些事务异步提交是可行且有用的。例如,当默认设置要求同步提交时,可以在一个包含多条语句的事务中执行SET LOCAL synchronous_commit TO OFF,使该事务异步提交。 - 概括了 synchronous_commit 各种设置具备的能力。 + 汇总了synchronous_commit各种设置具备的能力。
@@ -1968,9 +1875,9 @@ include_dir 'conf.d' synchronous_commit 设置 - 本地持久提交 - PG 崩溃备库持久提交 - OS 崩溃备库持久提交 + 本地提交持久性 + PG 崩溃后备库提交持久性 + OS 崩溃后备库提交持久性 备库查询一致性 @@ -2034,7 +1941,7 @@ include_dir 'conf.d' - 用来向强制 WAL 更新到磁盘的方法。如果fsync是关闭的,那么这个设置就不相关,因为 WAL 文件更新将根本不会被强制。可能的值是: + 用于将 WAL 更新强制写入磁盘的方法。如果fsync关闭,此设置就没有作用,因为 WAL 文件更新根本不会被强制写入磁盘。可选值为: @@ -2058,7 +1965,7 @@ include_dir 'conf.d' - fsync_writethrough(在每次提交时调用fsync(),强制任何磁盘写高速缓存的直通写) + fsync_writethrough(在每次提交时调用fsync(),强制穿透任何磁盘写缓存) @@ -2070,10 +1977,10 @@ include_dir 'conf.d' - open_* 选项也可以使用O_DIRECT(如果可用)。 + open_* 选项还会使用O_DIRECT(如果可用)。 不是在所有平台上都能使用所有这些选择。 - 默认值是列表中第一个被平台支持的那个, 不过fdatasync是 Linux和FreeBSD中的默认值。 - 默认值不一定是最理想的;有可能需要修改这个设置或系统配置的其他方面来创建一个崩溃-安全的配置,或达到最佳性能。 + 默认值是列表中第一个被平台支持的那个, 不过fdatasync是 Linux 和 FreeBSD 中的默认值。 + 默认值不一定最合适;可能需要更改此设置或系统配置的其他方面,以确保崩溃时的数据安全或达到最佳性能。 这些方面在中讨论。 这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 @@ -2088,11 +1995,11 @@ include_dir 'conf.d' - 当这个参数为打开时,PostgreSQL服务器在一个检查点之后的页面的第一次修改期间将每个页面的全部内容写到 WAL 中。这么做是因为在操作系统崩溃期间正在处理的一次页写入可能只有部分完成,从而导致在一个磁盘页面中混合有新旧数据。在崩溃后的恢复期间,通常存储在 WAL 中的行级改变数据不足以完全恢复这样一个页面。存储整页镜像可以保证页面被正确存储,但代价是增加了必须被写入 WAL 的数据量(因为 WAL 重放总是从一个检查点开始,所以在检查点后每个页面的第一次改变时这样做就够了。因此,一种减小全页面写开销的方法是增加检查点间隔参数值)。 + 启用此参数时,PostgreSQL服务器会在检查点之后首次修改每个磁盘页面时,将该页面的全部内容写入 WAL。这样做是因为,操作系统崩溃时正在进行的页面写入可能只完成了一部分,导致磁盘页面混有新旧数据。通常存储在 WAL 中的行级变更数据不足以在崩溃恢复时完整还原这样的页面。保存整页镜像能保证正确恢复页面,但会增加必须写入 WAL 的数据量。(由于 WAL 重放总是从检查点开始,只需在检查点之后首次修改每个页面时这样做。因此,减少整页写入开销的一种方法是增大检查点间隔参数。) - 把这个参数关闭会加快正常操作,但是在系统失败后可能导致不可恢复的数据损坏,或者静默的数据损坏。其风险类似于关闭fsync, 但是风险较小。并且只有在对该参数建议的相同情况下才应该关闭它。 + 关闭此参数可以加快正常操作,但系统故障后可能出现不可恢复的数据损坏或静默数据损坏。风险与关闭fsync类似,虽然较小,但也只有在该参数建议的相同情形下才应关闭此参数。 @@ -2115,7 +2022,7 @@ include_dir 'conf.d' - 当这个参数为on时,PostgreSQL服务器一个检查点之后页面被第一次修改期间把该磁盘页面的整个内容都写入 WAL,即使对所谓的提示位做非关键修改也会这样做。 + 当这个参数为on时,PostgreSQL服务器在检查点之后首次修改页面时把该磁盘页面的整个内容都写入 WAL,即使对所谓的提示位做非关键修改也会这样做。 @@ -2137,11 +2044,11 @@ include_dir 'conf.d' - 当这个参数为on时,PostgreSQL服务器在打开时或在基础备份期间,压缩写入WAL的整页镜像。在WAL回放期间将对压缩的页面镜像进行解压。默认值是off。只有超级用户能更改这个设置。 + 当这个参数为on时,PostgreSQL服务器在打开时或在基础备份期间,压缩写入WAL的整页镜像。在 WAL 重放期间将对压缩的整页镜像进行解压。默认值是off。只有超级用户能更改这个设置。 - 开启这个参数可以在不增加不可恢复的数据损坏风险的情况下减少WAL数据量,但代价是在WAL记录期间用于压缩以及在WAL回放期间用于解压的额外CPU开销。 + 开启此参数可以减少 WAL 数据量,而且不会增加不可恢复的数据损坏风险;代价是在记录 WAL 时压缩、重放 WAL 时解压会额外消耗一些 CPU。 @@ -2156,10 +2063,10 @@ include_dir 'conf.d' - 如果设置为on(默认值),此选项会导致新的 WAL 文件被零填充。 - 在某些文件系统上,这可确保在我们需要写入 WAL 记录之前分配空间。 - 但是,Copy-On-Write(COW)文件系统可能不会从此技术中受益,因此可以选择跳过不必要的工作。 - 如果设置为off,则在创建文件时仅写入最终字节,以便其具有预期大小。 + 如果设置为on(默认值),此选项会导致新的 WAL 文件被零填充。 + 在某些文件系统上,这可确保在我们需要写入 WAL 记录之前分配空间。 + 但是,写时复制(COW)文件系统可能不会从此技术中受益,因此可以选择跳过不必要的工作。 + 如果设置为off,则在创建文件时只写入最后一个字节,以便其具有预期大小。 @@ -2174,8 +2081,8 @@ include_dir 'conf.d' - 如果设置为 on (默认值),此选项通过重命名来回收 WAL 文件,从而避免创建新文件。 - 在 COW 文件系统上,创建新文件系统可能更快,因此提供了禁用此行为的选项。 + 如果设置为 on (默认值),此选项通过重命名来回收 WAL 文件,从而避免创建新文件。 + 在 COW 文件系统上,创建新文件可能更快,因此提供了禁用此行为的选项。 @@ -2193,7 +2100,7 @@ include_dir 'conf.d' - 在每次事务提交时,WAL 缓冲区的内容被写出到磁盘,因此极大的值不可能提供显著的收益。不过,把这个值设置为几个兆字节可以在一个繁忙的服务器(其中很多客户端会在同一时间提交)上提高写性能。由默认设置 -1 选择的自动调节将在大部分情况下得到合理的结果。 + 在每次事务提交时,WAL 缓冲区的内容被写出到磁盘,因此极大的值不太可能带来显著收益。不过,把这个值设置为至少几个兆字节可以在一个繁忙的服务器(其中很多客户端会在同一时间提交)上提高写性能。由默认设置 -1 选择的自动调节将在大部分情况下得到合理的结果。 @@ -2211,9 +2118,9 @@ include_dir 'conf.d' 指定 WAL 写入器刷写 WAL 的频繁程度,以时间为单位。 在刷写WAL之后,写入器将根据wal_writer_delay所给出的时间长度进行睡眠,除非被一个异步提交的事务提前唤醒。 - 如果最近的刷写发生在 wal_writer_delay 之前,并且小于 wal_writer_flush_after WAL的值产生之后,那么WAL只会被写入操作系统,而不会被刷写到磁盘。 + 如果距上次刷盘的时间小于wal_writer_delay,并且自那以后产生的 WAL 数据量小于wal_writer_flush_after,则只将 WAL 写入操作系统,而不刷写到磁盘。 如果指定值时没有单位,则以毫秒作为单位。 - 默认值是 200 毫秒(200ms)。注意在很多系统上,有效的睡眠延迟粒度是 10 毫秒,把wal_writer_delay设置为一个不是 10 的倍数的值,其效果和把它设置为大于该值的下一个 10 的倍数产生的效果相同。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 + 默认值是 200 毫秒(200ms)。注意在很多系统上,有效的睡眠延迟粒度是 10 毫秒,把wal_writer_delay设置为一个不是 10 的倍数的值,其效果可能与将其设置为下一个更大的 10 的倍数相同。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 @@ -2228,8 +2135,8 @@ include_dir 'conf.d' - 指定 WAL 写入器刷写 WAL 的频繁程度,以卷为单位。 - 如果最近的刷写发生在 wal_writer_delay 之前,并且小于 wal_writer_flush_after WAL的值产生之后,那么WAL只会被写入操作系统,而不会被刷写到磁盘。 + 指定 WAL 写入器刷写 WAL 的频繁程度,按数据量衡量。 + 如果距上次刷盘的时间小于wal_writer_delay,并且自那以后产生的 WAL 数据量小于wal_writer_flush_after,则只将 WAL 写入操作系统,而不刷写到磁盘。 如果wal_writer_flush_after被设置为0,则WAL数据总是会被立即刷写。 如果指定值时没有单位,则以WAL块作为单位,即为XLOG_BLCKSZ字节,通常为8kB。 默认是1MB。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 @@ -2247,20 +2154,20 @@ include_dir 'conf.d' - 设置commit_delay会在执行WAL刷新之前添加时间延迟。 + 设置commit_delay会在发起 WAL 刷盘之前添加时间延迟。 如果系统负载足够高,使得在给定时间间隔内有更多事务准备提交, - 这可以通过允许更多事务通过单个WAL刷新来提高组提交吞吐量。 - 然而,这也会增加延迟,最多为每个WAL刷新的commit_delay。 - 因为如果没有其他事务准备提交,延迟就是浪费的,所以只有在至少有 - commit_siblings其他事务活动时才会执行延迟, - 当要启动刷新时,如果fsync被禁用,则不会执行延迟。 + 这可以通过允许更多事务通过一次 WAL 刷盘来提高组提交吞吐量。 + 不过,每次 WAL 刷盘的延迟也会因此增加,最多增加commit_delay。 + 如果没有其他事务准备提交,等待就没有意义,因此仅当即将发起刷盘时至少还有 + commit_siblings个其他活动事务,才会等待。 + 此外,如果禁用了fsync,也不会等待。 如果未指定单位,则将其视为微秒。 默认commit_delay为零(无延迟)。 只有超级用户能更改这个设置。 - 在PostgreSQL的 9.3 发布之前,commit_delay的行为不同并且效果更差:它只影响提交,而不是所有 WAL 刷写,并且即使在 WAL 刷写马上就要完成时也会等待一整个配置的延迟。从PostgreSQL 9.3 中开始,第一个准备好刷写的进程会等待配置的间隔,而后续的进程只等到领先者完成刷写操作。 + 在PostgreSQL的 9.3 发布之前,commit_delay的行为不同并且效果更差:它只影响提交,而不是所有 WAL 刷写,并且即使 WAL 刷盘更早完成,也会等待整个配置的延迟时间。从PostgreSQL 9.3 开始,第一个准备好刷写的进程会等待配置的间隔,而后续的进程只等到领先者完成刷写操作。 @@ -2275,7 +2182,7 @@ include_dir 'conf.d' - 在执行commit_delay延迟时,要求的并发活动事务的最小数目。大一些的值会导致在延迟间隔期间更可能有至少另外一个事务准备好提交。默认值是五个事务。 + 执行commit_delay延迟前要求的并发活动事务的最小数目。大一些的值会导致在延迟间隔期间更可能有至少另外一个事务准备好提交。默认值是五个事务。 @@ -2297,7 +2204,7 @@ include_dir 'conf.d' 自动 WAL 检查点之间的最长时间。如果指定值时没有单位,则以秒为单位。 - 合理的范围在 30 秒到 1 天之间。默认是 5 分钟(5min)。增加这个参数的值会增加崩溃恢复所需的时间。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 + 合理的范围在 30 秒到 1 天之间。默认是 5 分钟(5min)。增加这个参数的值可能会增加崩溃恢复所需的时间。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 @@ -2328,7 +2235,7 @@ include_dir 'conf.d' 当执行检查点时写入的数据量超过此数量时,就尝试强制 OS 把这些写发送到底层存储。 这样做将会限制内核页面高速缓存中的脏数据数量,降低在检查点末尾发出fsync或者 OS 在后台大批量写回数据时被卡住的可能性。 - 那常常会导致大幅度压缩的事务延迟,但是也有一些情况(特别是负载超过但小于 OS 页面高速缓存)的性能会降低。 + 这通常能显著降低事务延迟,但是也有一些情况(特别是负载超过但小于 OS 页面高速缓存)的性能会降低。 这种设置可能会在某些平台上没有效果。 如果指定值时没有单位,则以块为单位,即为BLCKSZ 字节,通常为8kB。 合法的范围在0(禁用强制写回)和2MB之间。Linux 上的默认值是256kB,其他平台上是0(如果BLCKSZ不是8kB,则默认值和最大值会按比例缩放到它)。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 @@ -2404,10 +2311,9 @@ include_dir 'conf.d' 当启用archive_mode时,完成的WAL段会通过设置 - 发送到归档存储。除了off, - 要禁用,有两种模式:on和 + 发送到归档存储。除了用于禁用归档的off外,还有两种模式:onalways。在正常操作期间,这两种模式之间没有区别,但当设置为always时, - WAL归档程序在归档恢复或待机模式下也会被启用。在always模式下,从归档中恢复的所有文件 + WAL归档程序在归档恢复或备库模式下也会被启用。在always模式下,从归档中恢复的所有文件 或通过流复制传输的文件将被再次归档。详细信息请参见 @@ -2455,7 +2361,7 @@ include_dir 'conf.d' - 仅在完成的WAL段上调用。 + 只针对已完成的 WAL 段调用。 因此,如果您的服务器生成的WAL流量较少(或者在这样做时有间歇期),在事务完成和安全记录到归档存储之间可能会有很长的延迟。 为了限制未归档数据的年龄,您可以将archive_timeout设置为强制服务器定期切换到新的WAL段文件。 当此参数大于零时,只要自上次段文件切换以来经过了这段时间,并且存在任何数据库活动,包括单个检查点(如果没有数据库活动,则跳过检查点),服务器将切换到新的段文件。 @@ -2475,8 +2381,8 @@ include_dir 'conf.d' 归档恢复 - configuration - of recovery + 配置 + 恢复 一个备库 @@ -2485,7 +2391,7 @@ include_dir 'conf.d' - Recovery 涵盖使用服务器作为备库或用于执行目标恢复。 + 恢复 涵盖使用服务器作为备库或用于执行目标恢复。 通常情况,备库模式用于提供高可用性和/或读可扩展性,而目标恢复用于从数据丢失中恢复。 @@ -2552,7 +2458,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows 这个信息可以被用来把归档截断为支持从当前恢复重启所需的最小值。 对于单一备库配置,模块常常被用在archive_cleanup_command中,例如: archive_cleanup_command = 'pg_archivecleanup /mnt/server/archivedir %r' - 但是注意,如果多个备库正在从同一个归档目录中恢复,你将需要保证只有当任意服务器都不再需要 WAL 文件时才会删除它们。 + 但是注意,如果多个备库正在从同一个归档目录中恢复,你将需要保证只有当所有服务器都不再需要这些 WAL 文件时才会删除它们。 archive_cleanup_command通常被用于一种温备配置(见)中。 要在该命令中嵌入一个真正的%字符,需要写成%% @@ -2605,7 +2511,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows 默认情况下,恢复将会一直恢复到 WAL 日志的末尾。下面的参数可以被用来指定一个更早的停止点。 在recovery_targetrecovery_target_lsnrecovery_target_namerecovery_target_timerecovery_target_xid中, - 最多只能使用一个,如果在配置文件中使用了多个,将会产生一个错误。这个参数只能在服务器启动时设置。 + 最多只能使用一个,如果在配置文件中使用了多个,将会产生一个错误。这些参数只能在服务器启动时设置。 @@ -2638,7 +2544,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows - 这个参数指定(pg_create_restore_point()所创建)的已命名的恢复点,恢复将进入该恢复点。 + 这个参数指定(pg_create_restore_point()所创建)的已命名的恢复点,恢复将进行到该恢复点。 @@ -2653,7 +2559,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows - 此参数指定恢复将执行的时间戳。精确的停止点还受到得影响。 + 此参数指定恢复要进行到的时间戳。精确的停止点还受到的影响。 @@ -2673,7 +2579,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows - 这个参数指定恢复将进入的事务 ID。记住虽然事务 ID 是在事务开始时顺序分配的,但是事务可能以不同的数字顺序完成。 + 这个参数指定恢复要进行到的事务 ID。记住虽然事务 ID 是在事务开始时顺序分配的,但是事务可能以不同的数字顺序完成。 那些在指定事务之前(也可以包括该事务)提交的事务将被恢复。精确的停止点也受到的影响。 @@ -2689,7 +2595,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows - 此参数指定恢复将继续进行的预写日志位置的LSN。精确的停靠点也受 的影响。 + 此参数指定恢复要进行到的预写日志位置的 LSN。精确的停止点也受 的影响。 使用系统数据类型pg_lsn解析此参数。 @@ -2714,28 +2620,33 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows 指定我们是否仅在指定的恢复目标之后停止(on),或者仅在恢复目标之前停止(off)。 适用于或者被指定的情况。 - 这个设置分别控制事务是否有准确的目标WAL位置(LSN)、提交时间或事务ID将被包括在该恢复中。默认值为on。 + 这个设置控制恢复是否包含 WAL 位置(LSN)、提交时间或事务 ID 分别恰好等于目标值的事务。默认值为on + recovery_target_timeline (string) recovery_target_timeline 配置参数 + - 指定恢复到某条时间线。此值可以是数字时间线 ID 或特殊值。 - 值current会沿获取基础备份时的当前时间线恢复。 - 值latest会恢复到归档中找到的最新时间线,这对备库很有用。默认值为latest。 + 指定恢复到一个特定的时间线中。该值可以是数字时间线 ID 或特殊值。 + 值current沿着与执行基础备份时相同的时间线恢复。 + 值latest将恢复到归档中能找到的最新时间线,这在备库中很有用。 + latest是默认值。 + + - 通常只有在复杂的再次恢复情形中才需要设置此参数,也就是需要返回某个本身是在时点恢复之后达到的状态时。 - 相关讨论参见。 + 你通常只需要在复杂的再次恢复场景中设置此参数,也就是当你需要回到某个状态,而该状态本身又是在一次时间点恢复之后达到的。 + 相关讨论见 @@ -2754,13 +2665,13 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows 最后,shutdown将在达到恢复目标之后停止服务器。 - 使用pause设置的目的是:如果这个恢复目标就是恢复最想要的位置,就允许对数据库执行查询。 + 使用pause设置的目的是允许对数据库执行查询,以检查这个恢复目标是否为最合适的恢复位置。 暂停的状态可以使用pg_wal_replay_resume()(见)继续,这会让恢复终结。 如果这个恢复目标不是想要的停止点,那么关闭服务器,将恢复目标设置改为一个稍后的目标并且重启以继续恢复。 要让实例在想要的重放点那里准备好,shutdown设置可以派上用场。 - 该实例将仍能重放更多 WAL 记录(并且事实上将不得不重放从下一次它被启动后最后一个检查点以来的 WAL 记录)。 + 该实例将仍能重放更多 WAL 记录(并且事实上,下次启动时必须重新回放自上一个检查点以来的 WAL 记录)。 注意由于在recovery_target_action被设置为shutdown时,recovery.signal将不会被移除, @@ -2794,23 +2705,26 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows + max_wal_senders (integer) max_wal_senders配置参数 + - 指定来自备库或流式基础备份客户端的并发连接的最大数量(即同时运行 WAL 发送进程的最大数)。 - 默认值是10。值0意味着禁用复制。 - 突然的流式传输客户端断开连接可能留下一个孤立连接槽(直到达到超时),因此这个参数应该设置得略高于最大客户端连接数,这样断开连接的客户端可以立刻重新连接。 - 这个参数只能在服务器启动时被设置。此外,wal_level必须设置为replica或更高级别以允许来自备库的连接。 + 指定来自备库或流式基础备份客户端的最大并发连接数(即同时运行的 WAL 发送进程的最大数量)。 + 默认值为 10。值 0 表示禁用复制。 + 流式客户端突然断开连接后,可能会留下一个孤立连接槽,直到超时才释放。 + 因此,此参数应设置得略高于预期的最大客户端数,使断开连接的客户端能够立即重新连接。 + 此参数只能在服务器启动时设置。此外,wal_level 必须设置为 + replica 或更高级别,才允许来自备库的连接。 - 在运行一个备库时,你必须把这个参数设置为等于或者高于主库上的值。 - 否则,备库上将不允许查询。 - + 运行备库时,必须将此参数设置为大于或等于主库上的值。否则,备库上将不允许查询。 + @@ -2870,14 +2784,14 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows - 中断那些停止活动超过这个时间量的复制连接。这对发送服务器检测一个费用服务器崩溃或网络中断有用。 - 如果指定值时没有单位,则以毫秒为单位。默认值是 60 秒。值0将禁用超时机制。 + 终止非活动时间超过此值的复制连接。这有助于发送服务器检测备库崩溃或网络中断。 + 如果指定值时没有单位,则按毫秒计算。默认值为 60 秒。值零禁用超时机制。 - 对于跨越多个地理位置分布的集簇,每个位置使用不同的值可以为集簇管理带来更大的灵活性。 - 对于具有低延迟网络连接的备库,较小的值有助于更快的故障检测; - 对于位于远端位置的具有高延迟网络连接的备库,较大的值有助于更好地判断备库的健康状况。 + 对于跨多个地理位置分布的集簇,在各位置使用不同的值可以提高集簇管理的灵活性。 + 对于网络延迟较低的备库,较小的值有助于更快地检测故障; + 对于地处远端、网络延迟较高的备库,较大的值有助于更准确地判断其健康状况。 @@ -2902,7 +2816,10 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows 主库 - 这些参数可以在发送复制数据给一个或多个备库的主库上设置。注意除了这些参数之外,在主库上必须设置合适的,并且也启用可选的 WAL 归档(见)。这些参数值与备库无关,尽管你可能希望为了准备好一个备库转变成主库来设置这些参数。 + 这些参数可以在向一个或多个备库发送复制数据的主库上设置。 + 除这些参数外,还必须在主库上适当设置 , + 也可以选择启用 WAL 归档(见 )。 + 这些参数在备库上的取值不影响备库运行,不过也可以预先设置,以备将来提升为主库。 @@ -2918,16 +2835,18 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows 所述,这个参数指定一个支持同步复制的备库的列表。 - 可能会有一个或者多个活动的同步备库,在这些备库确认收到它们的数据之后,等待提交的事务将被允许继续下去。 - 同步备库是那些名字出现在这个列表前面,并且当前已连接并且正在实时流式传输数据(如pg_stat_replication视图中streaming的状态所示)的服务器。 指定多于一台同步备库可以得到非常高的可用性并且能防止数据丢失。 用于这一目的的备库的名称是其application_name设置,它在备库的连接信息中设置。 - 在物理复制备库的情况下,这应该被设置在primary_conninfo设置中,如果设置了,默认是的设置,否则为 walreceiver。 - 对于逻辑复制,可以在订阅的连接信息中设置。对于其他复制流消费者,请参考其文档。 + 对于物理复制备库,应在 primary_conninfo 设置中指定。 + 若已设置 ,则默认使用其值;否则默认值为 walreceiver。 + 对于逻辑复制,可以在订阅的连接信息中设置,默认值为订阅名称。 + 对于其他复制流消费者,请参考其文档。 @@ -2941,11 +2860,11 @@ ANY num_sync ( num_sync指定一种基于优先的同步复制,并且会让事务提交等待,直到它们的WAL记录被复制到基于优先级选择的num_sync台同步备库上为止。例如,设置FIRST 3 (s1, s2, s3, s4)将导致每次提交都等待来自三台较高优先级的备库的答复,这三台备库将从备库s1s2s3以及s4中选出。在该列表中出现较早的备库将被给予较高的优先级,并且将被考虑为同步备库。列表中出现的其他备库表示潜在的同步备库。如果当前的任何同步备库因为某种原因断开连接,它将立刻被下一个最高优先级的备库替代。关键词FIRST是可选的。 + 关键词FIRST加上num_sync指定一种基于优先级的同步复制,并且会让事务提交等待,直到它们的WAL记录被复制到基于优先级选择的num_sync台同步备库上为止。例如,设置FIRST 3 (s1, s2, s3, s4)将导致每次提交都等待来自三台较高优先级的备库的答复,这三台备库将从备库s1s2s3以及s4中选出。在该列表中出现较早的备库将被给予较高的优先级,并且将被考虑为同步备库。列表中出现的其他备库表示潜在的同步备库。如果当前的任何同步备库因为某种原因断开连接,它将立刻被下一个最高优先级的备库替代。关键词FIRST是可选的。 - 关键词ANY加上num_sync指定一种基于规定数量的同步复制,并且会让事务提交等待,直到它们的WAL记录被复制到所列出备库中的至少num_sync台上为止。例如,设置ANY 3 (s1, s2, s3, s4)将导致每次提交会在收到s1s2s3以及s4中任意三台备库的回答后立刻继续下去。 + 关键词ANY加上num_sync指定一种基于法定人数的同步复制,并且会让事务提交等待,直到它们的WAL记录被复制到所列出备库中的至少num_sync台上为止。例如,设置ANY 3 (s1, s2, s3, s4)将导致每次提交会在收到s1s2s3以及s4中任意三台备库的回答后立刻继续下去。 @@ -2971,7 +2890,7 @@ ANY num_sync ( 参数设置为localoff。 + 如果这里没有指定同步备库名称,那么不启用同步复制并且事务提交将不会等待复制。这是默认的配置。即便当同步复制被启用时,个体事务也可以被配置为不等待复制,做法是将参数设置为localoff @@ -2980,6 +2899,8 @@ ANY num_sync ( vacuum_defer_cleanup_age (integer) @@ -3003,8 +2924,7 @@ ANY num_sync ( @@ -3055,7 +2975,9 @@ ANY num_sync ( + + + promote_trigger_file (string) promote_trigger_file 配置参数 @@ -3104,9 +3026,7 @@ ANY num_sync ( num_sync ( num_sync ( pg_stat_replication视图看到。 - 备库将报告它已经写入的上一个预写式日志位置、它已经刷到磁盘的上一个位置以及它已经应用的最后一个位置。 + 备库将报告最后写入的预写日志位置、最后刷盘的位置以及最后应用的位置。 这个参数的值是报告之间的最大时间量。 - 每次写入或刷出位置改变时会发送状态更新,或者按这个参数的指定的频度发送。 + 每次写入或刷盘位置改变时会发送状态更新,或者至少按这个参数指定的频度发送。 因此,应用位置可能比真实位置略微滞后。 如果指定值时没有单位,则以秒为单位。 默认值是 10 秒。 @@ -3163,7 +3081,7 @@ ANY num_sync ( num_sync ( num_sync ( recovery_min_apply_delay (integer) @@ -3221,39 +3141,32 @@ ANY num_sync ( @@ -3264,7 +3177,7 @@ ANY num_sync ( num_sync ( num_sync ( num_sync ( + + enable_bitmapscan (boolean) - 位图扫描 + 位图扫描 - enable_bitmapscan配置参数 + enable_bitmapscan 配置参数 - - 允许或禁止查询规划器使用位图扫描计划类型。默认值是on。 + 启用或禁用查询规划器对位图扫描计划类型的使用。默认值为 on - - + + + - + enable_gathermerge (boolean) - enable_gathermerge配置参数 + enable_gathermerge 配置参数 - - 启用或者禁用查询规划器对收集归并计划类型的使用。默认值是on。 + 启用或禁用查询规划器对收集归并计划类型的使用。默认值为 on - - + + + - + enable_hashagg (boolean) - enable_hashagg配置参数 + enable_hashagg 配置参数 - - 允许或禁用查询规划器使用哈希聚合计划类型。默认值是on。 + 启用或禁用查询规划器对哈希聚合计划类型的使用。默认值为 on - + + enable_hashjoin (boolean) - enable_hashjoin配置参数 + enable_hashjoin 配置参数 - - 允许或禁止查询规划器使用哈希连接计划类型。默认值是on。 + 启用或禁用查询规划器对哈希连接计划类型的使用。默认值为 on + + + + enable_indexscan (boolean) - 索引扫描 + 索引扫描 - enable_indexscan配置参数 + enable_indexscan 配置参数 - 允许或禁止查询规划器使用索引扫描和只用索引扫描计划类型。默认值是on。另见 + + 启用或禁用查询规划器对索引扫描和仅索引扫描计划类型的使用。默认值为 on。另请参见 。 + enable_indexonlyscan (boolean) - enable_indexonlyscan配置参数 + enable_indexonlyscan 配置参数 - 允许或禁止查询规划器使用只用索引扫描计划类型(见)。默认值是on。还必须启用设置,查询规划器才会考虑只用索引扫描。 + + 启用或禁用查询规划器对仅索引扫描计划类型的使用(参见 )。默认值为 on。还必须启用 ,查询规划器才会考虑仅索引扫描。 + - + + enable_material (boolean) - enable_material配置参数 + enable_material 配置参数 @@ -3446,26 +3366,27 @@ ANY num_sync ( + + enable_mergejoin (boolean) - enable_mergejoin配置参数 + enable_mergejoin 配置参数 - - 允许或禁止查询规划器使用归并连接计划类型。默认值是on。 + 启用或禁用查询规划器对归并连接计划类型的使用。默认值为 on - + + enable_nestloop (boolean) - enable_nestloop配置参数 + enable_nestloop 配置参数 @@ -3491,17 +3412,17 @@ ANY num_sync ( + + enable_parallel_hash (boolean) - enable_parallel_hash配置参数 + enable_parallel_hash 配置参数 - - 允许或禁止查询规划器对并行哈希使用哈希连接计划类型。如果哈希连接计划也没有启用,这个参数没有效果。默认值是on。 + 启用或禁用查询规划器对使用并行哈希的哈希连接计划类型的使用。如果没有同时启用哈希连接计划,此参数不起作用。默认值为 on @@ -3521,19 +3442,19 @@ ANY num_sync ( enable_partitionwise_join (boolean) - enable_partitionwise_join配置参数 + enable_partitionwise_join 配置参数 - 允许或者禁止查询规划器使用面向分区的连接,这使得分区表之间的连接以连接匹配的分区的方式来执行。 - 面向分区的连接当前只适用于连接条件包括所有分区键的情况,分区键必须具有相同的数据类型,并且子分区集合必须完全匹配。 - 启用此设置后,最终计划中内存使用量受work_mem限制的节点数可能会随所扫描分区的数量线性增加, - 从而使查询执行时的总内存消耗大幅增加。查询规划在内存和 CPU 方面的代价也会显著增加。 - 默认值为off。 + 启用或禁用查询规划器对分区连接的使用,使分区表之间的连接可以通过连接相匹配的分区来完成。分区连接目前仅适用于连接条件包含所有分区键的情况;这些分区键必须具有相同的数据类型,并且子分区集合必须完全匹配。启用此设置后,最终计划中内存用量受 work_mem 限制的节点数量可能随所扫描分区的数量线性增加。这可能大幅增加查询执行期间的总内存消耗。查询规划在内存和 CPU 方面的开销也会显著增加。默认值为 off @@ -3541,16 +3462,12 @@ ANY num_sync ( enable_partitionwise_aggregate (boolean) - enable_partitionwise_aggregate配置参数 + enable_partitionwise_aggregate 配置参数 - 启用或禁用查询规划器使用分区分组或聚合的功能,该功能允许在分区表上分别对每个分区执行分组或聚合操作。 - 如果GROUP BY子句不包括分区键,那么只能在每个分区的基础上执行部分聚合,并且必须在稍后进行最终化处理。 - 启用此设置后,最终计划中内存使用量受work_mem限制的节点数可能会随所扫描分区的数量线性增加, - 从而使查询执行时的总内存消耗大幅增加。查询规划在内存和 CPU 方面的代价也会显著增加。 - 默认值为off。 + 启用或禁用查询规划器对分区分组或聚合的使用,使分区表上的分组或聚合可以在各个分区上分别执行。如果 GROUP BY 子句不包含分区键,则只能在各分区上执行部分聚合,随后还必须进行最终处理。启用此设置后,最终计划中内存用量受 work_mem 限制的节点数量可能随所扫描分区的数量线性增加。这可能大幅增加查询执行期间的总内存消耗。查询规划在内存和 CPU 方面的开销也会显著增加。默认值为 off @@ -4005,7 +3922,7 @@ ANY num_sync ( parallel_leader_participation (boolean) - parallel_leader_participation 配置参数 + + parallel_leader_participation configuration + parameter + - + - 允许领导者进程执行GatherGather Merge节点之下的查询计划,而不是等待工作者进程。 - 默认值为on。将此值设置为off可以降低工作者因领导者读取元组不够快而阻塞的可能性, - 但也要求领导者进程等待工作者进程启动之后才能产生第一批元组。 - 领导者对性能的帮助或妨碍程度取决于计划类型、工作者数量和查询持续时间。 + 允许领导者进程执行 GatherGather Merge 节点下的查询计划,而不是等待工作进程。默认值为 on。将此值设置为 off,可以降低工作进程因领导者读取元组不够快而被阻塞的可能性,但在产生第一批元组之前,领导者进程必须等待工作进程启动。领导者对性能的帮助或妨碍程度取决于计划类型、工作进程数量和查询持续时间。 @@ -4150,7 +4071,7 @@ SELECT * FROM parent WHERE key = 2400; 更具体地说,将此值设置为on会在任何看起来可以安全并行的查询计划顶部添加一个Gather节点, - 让查询在并行工作者中运行。即使没有可用的并行工作者或无法使用并行工作者, + 让查询在并行工作进程中运行。即使没有可用的并行工作进程或无法使用并行工作进程, 在并行查询上下文中不允许的操作(例如启动子事务)也会被禁止,除非规划器认为这会使查询失败。 如果设置此选项后出现失败或意外结果,查询使用的某些函数可能需要被标记为PARALLEL UNSAFE (也可能是PARALLEL RESTRICTED)。 @@ -4158,7 +4079,7 @@ SELECT * FROM parent WHERE key = 2400; 将此值设置为regress具有设置为on的所有效果,另外还有一些旨在方便自动回归测试的效果。 - 通常,来自并行工作者的消息会包含一行说明这一点的上下文信息,但regress设置会抑制此行,使输出与非并行执行时相同。 + 通常,来自并行工作进程的消息会包含一行说明这一点的上下文信息,但regress设置会抑制此行,使输出与非并行执行时相同。 此外,此设置添加到计划中的Gather节点会在EXPLAIN输出中隐藏, 使输出与此设置为off时的输出一致。 @@ -4700,7 +4621,7 @@ local0.* /var/log/postgresql - application_name可以是任意小于NAMEDATALEN个字符(标准编译中是 64 个字符)的字符串。这通常由一个应用通过到服务器的连接设置。该名称将被显示在pg_stat_activity视图中并被包括在 CSV 日志项中。它也会被通过包括在普通日志项中。只有可打印 ASCII 字符能被使用在application_name之中。其他字符将被替换为问号(?)。 + application_name可以是任意小于NAMEDATALEN个字符(标准编译中是 64 个字符)的字符串。应用通常在连接服务器时设置此值。该名称将被显示在pg_stat_activity视图中并被包括在 CSV 日志项中。它也会被通过包括在普通日志项中。只有可打印 ASCII 字符能被使用在application_name之中。其他字符将被替换为问号(?)。 @@ -4779,7 +4700,7 @@ local0.* /var/log/postgresql - 某些客户端程序(例如psql)在要求密码时会尝试连接两次,因此重复的收到连接消息并不一定表示一个错误。 + 某些客户端程序(例如psql)在判断是否需要密码时会尝试连接两次,因此重复的收到连接消息并不一定表示一个错误。 @@ -4978,7 +4899,7 @@ local0.* /var/log/postgresql %% - 纯文字 % + 字面字符 % @@ -5002,7 +4923,7 @@ FROM pg_stat_activity; - Syslog产生自己的时间戳和进程 ID 信息,因此如果你记录到syslog你可能不希望包括哪些转义。 + Syslog产生自己的时间戳和进程 ID 信息,因此如果你记录到syslog你可能不希望包括那些转义。 @@ -5225,7 +5146,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 这个名称可以是任何长度不超过NAMEDATALEN个字符(在标准编译中是 64字符)的任何字符串。只有可打印的 ASCII 字符能被用在cluster_name值中。其他字符将被替换为问号(?)。如果这个参数被设置为空字符串''(也是默认值),将不会显示名称。这个参数只能在服务器启动时设置。 + 这个名称可以是任何长度少于NAMEDATALEN个字符(在标准编译中是 64字符)的任何字符串。只有可打印的 ASCII 字符能被用在cluster_name值中。其他字符将被替换为问号(?)。如果这个参数被设置为空字符串''(也是默认值),将不会显示名称。这个参数只能在服务器启动时设置。 @@ -5255,13 +5176,14 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; 运行时统计数据 - 累积查询和索引统计 + 查询和索引统计信息收集器 - 这些参数控制服务器范围内的累积统计系统。 - 启用后,收集的数据可以通过pg_statpg_statio - 系列系统视图进行访问。有关更多信息,请参阅。 - + 这些参数控制服务器范围内的统计信息收集功能。 + 启用统计信息收集后,产生的数据可以通过pg_stat和 + pg_statio系列系统视图进行访问。 + 更多信息请参阅。 + @@ -5443,7 +5365,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 注意即使该参数被禁用,系统也会在需要防止事务ID回卷时发起清理进程。详情请见。 + 注意即使该参数被禁用,系统也会在需要防止事务ID回卷时发起自动清理进程。详情请见 @@ -5491,7 +5413,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 指定自动清理在任意给定数据库上运行的最小延迟。在每一轮中后台进程检查数据库并根据需要为数据库中的表发出VACUUMANALYZE命令。 + 指定自动清理在任意给定数据库上各次运行之间的最小间隔。在每一轮中后台进程检查数据库并根据需要为数据库中的表发出VACUUMANALYZE命令。 如果指定值时没有单位,则以秒为单位。默认值为1分钟(1min)。该参数只能在postgresql.conf文件或在服务器命令行上设置。 @@ -5629,7 +5551,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 指定用于自动VACUUM操作中的代价限制值。如果指定-1(默认值),则使用值。注意该值被按比例地分配到运行中的自动清理工作者上(如果有多个),因此每一个工作者的限制值之和不会超过这个变量中的值。该参数只能在postgresql.conf文件或在服务器命令中设置。但是对个别表可以通过修改表存储参数来覆盖该设置。 + 指定用于自动VACUUM操作中的代价限制值。如果指定-1(默认值),则使用值。注意该值被按比例地分配到运行中的自动清理工作进程上(如果有多个),因此每一个工作进程的限制值之和不会超过这个变量中的值。该参数只能在postgresql.conf文件或在服务器命令中设置。但是对个别表可以通过修改表存储参数来覆盖该设置。 @@ -5673,7 +5595,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; search_path配置参数 - pathfor schemas + 路径用于模式 @@ -5764,7 +5686,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; default_tablespace配置参数 - tablespacedefault + 表空间默认 @@ -5847,7 +5769,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; default_transaction_isolation (enum) - transaction isolation level + 事务隔离级别 设置默认值 @@ -5870,7 +5792,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; default_transaction_read_only (boolean) - read-only transaction + 只读事务 设置默认值 @@ -5892,7 +5814,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; default_transaction_deferrable (boolean) - deferrable transaction + 可延迟事务 设置默认值 @@ -5918,7 +5840,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; transaction_isolation (enum) - transaction isolation level + 事务隔离级别 transaction_isolation配置参数 @@ -5938,7 +5860,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; transaction_read_only (boolean) - read-only transaction + 只读事务 transaction_read_only 配置参数 @@ -5958,7 +5880,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; transaction_deferrable (boolean) - deferrable transaction + 可延迟事务 transaction_deferrable 配置参数 @@ -6082,7 +6004,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 当表的pg_class.relfrozenxid字段达到该设置指定的年龄时,VACUUM会执行激进扫描。激进扫描与常规VACUUM不同,它会访问每一个可能包含未冻结 XID 或 MXID 的页面,而不仅仅是那些可能包含死元组的页面。默认值是 1.5 亿个事务。尽管用户可以将该值设置为 0 到 20 亿之间的任意值,VACUUM会悄悄将有效值调整为的 95%,从而在触发防回卷 autovacuum 之前仍有机会执行一次常规手工VACUUM。更多信息请参见。 + 当表的pg_class.relfrozenxid字段达到该设置指定的年龄时,VACUUM会执行激进扫描。激进扫描与常规VACUUM不同,它会访问每一个可能包含未冻结 XID 或 MXID 的页面,而不仅仅是那些可能包含死元组的页面。默认值是 1.5 亿个事务。尽管用户可以将该值设置为 0 到 20 亿之间的任意值,VACUUM会悄悄将有效值限制为不超过的 95%,从而在触发防回卷 autovacuum 之前仍有机会执行一次常规手工VACUUM。更多信息请参见 @@ -6095,7 +6017,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 指定VACUUM在扫描表时用来决定是否冻结行版本的切断年龄(以事务计)。默认值是 5000 万个事务。尽管用户可以将该值设置为 0 到 10 亿之间的任意值,VACUUM会悄悄将有效值调整为的一半,这样强制 autovacuum 之间就不会间隔过短。更多信息请参见。 + 指定VACUUM在扫描表时用来决定是否冻结行版本的切断年龄(以事务计)。默认值是 5000 万个事务。尽管用户可以将该值设置为 0 到 10 亿之间的任意值,VACUUM会悄悄将有效值限制为不超过的一半,这样强制 autovacuum 之间就不会间隔过短。更多信息请参见 @@ -6108,7 +6030,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 当表的pg_class.relminmxid字段达到该设置指定的年龄时,VACUUM会执行激进扫描。激进扫描与常规VACUUM不同,它会访问每一个可能包含未冻结 XID 或 MXID 的页面,而不是只扫描那些可能包含死元组的页面。默认值是 1.5 亿个多事务。尽管用户可以将该值设置为 0 到 20 亿之间的任意值,VACUUM会悄悄将有效值调整为的 95%,从而在触发防回卷 autovacuum 之前仍有机会执行一次常规手工VACUUM。更多信息请参见。 + 当表的pg_class.relminmxid字段达到该设置指定的年龄时,VACUUM会执行激进扫描。激进扫描与常规VACUUM不同,它会访问每一个可能包含未冻结 XID 或 MXID 的页面,而不是只扫描那些可能包含死元组的页面。默认值是 1.5 亿个多事务。尽管用户可以将该值设置为 0 到 20 亿之间的任意值,VACUUM会悄悄将有效值限制为不超过的 95%,从而在触发防回卷 autovacuum 之前仍有机会执行一次常规手工VACUUM。更多信息请参见 @@ -6121,7 +6043,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 指定VACUUM在扫描表时用来决定是否将 multixact ID 替换为较新的事务 ID 或 multixact ID 的切断年龄(以 multixact 计)。默认值是 5000 万个 multixact。尽管用户可以将该值设置为 0 到 10 亿之间的任意值,VACUUM会悄悄将有效值调整为的一半,这样强制 autovacuum 之间就不会间隔过短。更多信息请参见。 + 指定VACUUM在扫描表时用来决定是否将多事务 ID 替换为较新的事务 ID 或多事务 ID 的切断年龄(以多事务计)。默认值是 500 万个多事务。尽管用户可以将该值设置为 0 到 10 亿之间的任意值,VACUUM会悄悄将有效值限制为不超过的一半,这样强制 autovacuum 之间就不会间隔过短。更多信息请参见 @@ -6200,7 +6122,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; SET XML OPTION - XML option + XML 选项 @@ -6238,20 +6160,21 @@ SET XML OPTION { DOCUMENT | CONTENT }; + - restrict_nonsystem_relation_kind (string) - + restrict_nonsystem_relation_kind (string) + restrict_nonsystem_relation_kind 配置参数 - - + + 设置禁止访问非系统关系的关系类型。该值采用关系类型的逗号分隔列表形式。 目前支持的关系类型是viewforeign-table - + @@ -6297,7 +6220,7 @@ SET XML OPTION { DOCUMENT | CONTENT }; TimeZone配置参数 - time zone + 时区 @@ -6313,7 +6236,7 @@ SET XML OPTION { DOCUMENT | CONTENT }; timezone_abbreviations配置参数 - time zone names + 时区名称 @@ -6327,11 +6250,11 @@ SET XML OPTION { DOCUMENT | CONTENT }; extra_float_digits (integer) - significant digits + 有效数字 - floating-point - display + 浮点数 + 显示 extra_float_digits配置参数 @@ -6359,7 +6282,7 @@ SET XML OPTION { DOCUMENT | CONTENT }; - 此参数的含义,以及其默认值,在 PostgreSQL 12 中发生了变化; + 此参数的含义,以及其默认值,在 PostgreSQL 12 中发生了变化; 参见 以便进一步讨论。 @@ -6372,7 +6295,7 @@ SET XML OPTION { DOCUMENT | CONTENT }; client_encoding配置参数 - character set + 字符集 @@ -6691,12 +6614,12 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' deadlock_timeout (integer) - deadlock + 死锁 期间超时 - timeout - deadlock + 超时 + 死锁 deadlock_timeout配置参数 @@ -6731,12 +6654,11 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' 共享锁表跟踪在max_locks_per_transaction * ( + ) 个对象(如表)上的锁。因此,在任何一个时刻,只有不超过这么多个可区分对象能够被锁住。这个参数控制为每个事务分配的对象锁的平均数量。个体事务可以锁住更多对象,数量可以和锁表中能容纳的所有事务的锁一样多。这是能被锁住的行数,那个值是没有限制的。默认值 64 已经被历史证明是足够的,但是如果你有需要在一个事务中使用很多不同表的查询(例如查询一个有很多子表的父表),你可能需要提高这个值。这个参数只能在服务器启动时设置。 + linkend="guc-max-prepared-transactions"/>) 个对象(如表)上的锁。因此,在任何一个时刻,只有不超过这么多个可区分对象能够被锁住。这个参数控制为每个事务分配的对象锁的平均数量。只要所有事务的锁都能放入锁表中,单个事务就可以锁住更多对象。这是能被锁住的行数,那个值是没有限制的。默认值 64 已经被历史证明是足够的,但是如果你有需要在一个事务中使用很多不同表的查询(例如查询一个有很多子表的父表),你可能需要提高这个值。这个参数只能在服务器启动时设置。 - 当运行一个备库时,你必须设置这个参数等于或大于主库上的参数。 - 否则,备库上将不允许查询。 + 运行备库时,必须将此参数设置为大于或等于主库上的值。否则,备库上将不允许查询。 @@ -6753,7 +6675,7 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' 共享谓词锁表跟踪在max_pred_locks_per_transaction * ( + ) 个对象(如表)上的锁。因此,在任何一个时刻,只有不超过这么多个可区分对象能够被锁住。这个参数控制为每个事务分配的对象锁的平均数量。个体事务可以锁住更多对象,数量可以和锁表中能容纳的所有事务的锁一样多。这是能被锁住的行数,那个值是没有限制的。默认值 64 已经在测试中被证明通常是足够的,但是如果你有需要在一个可串行化事务中使用很多不同表的查询(例如查询一个有很多子表的父表),你可能需要提高这个值。这个参数只能在服务器启动时设置。 + linkend="guc-max-prepared-transactions"/>) 个对象(如表)上的锁。因此,在任何一个时刻,只有不超过这么多个可区分对象能够被锁住。这个参数控制为每个事务分配的对象锁的平均数量。只要所有事务的锁都能放入锁表中,单个事务就可以锁住更多对象。这是能被锁住的行数,那个值是没有限制的。默认值 64 已经在测试中被证明通常是足够的,但是如果你有会在单个可串行化事务中访问许多不同表的客户端,则可能需要提高这个值。这个参数只能在服务器启动时设置。 @@ -6820,7 +6742,7 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' backslash_quote (enum) - stringsbackslash quotes + 字符串反斜线引号 backslash_quote配置参数 @@ -6839,7 +6761,7 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' escape_string_warning (boolean) - strings转义警告 + 字符串转义警告 escape_string_warning配置参数 @@ -6914,7 +6836,7 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' standard_conforming_strings (boolean) - stringsstandard conforming + 字符串标准符合 standard_conforming_strings配置参数 @@ -7141,6 +7063,8 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' + + lc_collate (string) @@ -7155,6 +7079,8 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' + + lc_ctype (string) @@ -7235,7 +7161,7 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' server_encoding配置参数 - character set + 字符集 @@ -7448,6 +7374,8 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' + + trace_recovery_messages (enum) diff --git a/zh/12/datatype.sgml b/zh/12/datatype.sgml index 98fc7347..8240cb0e 100644 --- a/zh/12/datatype.sgml +++ b/zh/12/datatype.sgml @@ -341,19 +341,19 @@ smallint 2字节 小范围整数 - -32768 to +32767 + -32768 到 +32767 integer 4字节 整数的典型选择 - -2147483648 to +2147483647 + -2147483648 到 +2147483647 bigint 8字节 大范围整数 - -9223372036854775808 to +9223372036854775807 + -9223372036854775808 到 +9223372036854775807 @@ -740,7 +740,10 @@ FROM generate_series(-3.5, 3.5, 1) as x; - 本节描述的是 PostgreSQL 特有的创建自动递增列的方法。另一种方法是使用 SQL 标准的标识列特性,参见 + + 本节介绍 PostgreSQL 特有的自动递增列创建方法。 + 另一种方法是使用 SQL 标准的标识列特性,参见。 + @@ -818,7 +821,7 @@ ALTER SEQUENCE tablename_money 类型以固定的小数精度存储货币金额; 参见 。小数精度由数据库的 设置决定。表中显示的范围假定 - 有两位小数。输入支持多种格式,包括整数和浮点文字,以及典型的 + 有两位小数。输入支持多种格式,包括整数字面量和浮点数字面量,以及典型的 货币格式,例如 '$1,000.00'。输出通常也采用 后一种形式,但会受到区域设置影响。 @@ -1216,7 +1219,7 @@ SELECT '\xDEADBEEF'::bytea;
- <type>bytea</type>文字转义字节 + <type>bytea</type>字面量中需要转义的字节 @@ -3675,17 +3678,16 @@ a0ee-bc99-9c0b-4ef8-bb6d-6bb9-bd38-0a11 xml 数据类型可用于存储 XML 数据。与把 XML 数据存储在 - text 字段中相比,它的优势在于会检查输入值是否格式 - 良好,并且提供了可执行类型安全操作的支持函数;见 - 。使用该数据类型要求安装时启用 + text 字段中相比,它的优势在于会检查输入值的良构性,并且提供了可执行类型安全操作的支持函数;见 + 。使用该数据类型要求构建时使用 configure --with-libxml - xml 类型既可以存储符合 XML 标准定义的格式良好的 + xml 类型既可以存储 XML 标准所定义的良构 文档,也可以存储 内容 片段;后者是参照 XQuery 和 XPath 数据模型中更宽松的 - document node + 文档节点 概念来定义的。粗略地说,这意味着内容片段可以拥有多个顶层元素或字符 节点。表达式 xmlvalue IS DOCUMENT @@ -3835,7 +3837,7 @@ SET xmloption TO { DOCUMENT | CONTENT }; - 是一种用户定义的数据类型,它基于另一种底层类型。根据需要,它可以有约束来限制其有效值为底层类型所允许值的一个子集。如果没有约束,它的行为就和底层类型一样 — 例如,任何适用于底层类型的操作符或函数都对该域类型有效。底层类型可以是任何内置或者用户定义的基础类型、枚举类型、数组类型、复合类型、范围类型或者另一个域。 + 是一种用户定义的数据类型,它基于另一种底层类型。根据需要,它可以有约束来限制其有效值为底层类型所允许值的一个子集。除此之外,它的行为与底层类型相同 — 例如,任何适用于底层类型的操作符或函数都对该域类型有效。底层类型可以是任何内置或者用户定义的基础类型、枚举类型、数组类型、复合类型、范围类型或者另一个域。 diff --git a/zh/12/dblink.sgml b/zh/12/dblink.sgml index bdcd607c..70ea13cd 100644 --- a/zh/12/dblink.sgml +++ b/zh/12/dblink.sgml @@ -7,9 +7,13 @@ dblink - dblink模块支持在一个数据库会话中连接到其他PostgreSQL数据库。 + + dblink 是一个支持在数据库会话内连接到其他 PostgreSQL 数据库的模块。 + - 另请参阅,它使用更现代、符合标准的基础设施提供了大致相同的功能。 + + 另请参见 ,它使用更现代且更符合标准的基础设施提供了基本相同的功能。 + @@ -91,7 +95,7 @@ dblink_connect(text connname, text connstr) returns text 注解 - 如果不可信用户能够访问一个尚未采用模式的安全使用方式的数据库,则应在每个会话开始时从 + 如果不受信任的用户能够访问一个尚未采用模式的安全使用方式的数据库,则应在每个会话开始时从 search_path 中移除公共可写模式。例如,可以把 options=-csearch_path= 加到 connstr 中。这个注意事项并非 dblink 所特有;它适用于每一种执行任意 SQL 命令的接口。 @@ -125,9 +129,9 @@ SELECT dblink_connect('myconn', 'dbname=postgres options=-csearch_path='); OK (1 row) --- FOREIGN DATA WRAPPER functionality --- Note: local connection must require password authentication for this to work properly --- Otherwise, you will receive the following error from dblink_connect(): +-- FOREIGN DATA WRAPPER 功能 +-- 注意:要使本例正常工作,本地连接必须要求密码认证。 +-- 否则,dblink_connect() 将报告以下错误: -- ---------------------------------------------------------------------- -- ERROR: password is required -- DETAIL: Non-superuser cannot connect if the server does not request a password. @@ -143,13 +147,13 @@ GRANT SELECT ON TABLE foo TO regress_dblink_user; \set ORIGINAL_USER :USER \c - regress_dblink_user SELECT dblink_connect('myconn', 'fdtest'); - dblink_connect + dblink_connect ---------------- OK (1 row) SELECT * FROM dblink('myconn', 'SELECT * FROM foo') AS t(a int, b text, c text[]); - a | b | c + a | b | c ----+---+--------------- 0 | a | {a0,b0,c0} 1 | b | {a1,b1,c1} @@ -391,7 +395,7 @@ SELECT * WHERE proname LIKE 'bytea%'; - FROM 子句中的 alias 部分必须指定该函数将返回的列名和类型。(在别名中指定列名实际上是标准 SQL 语法,但指定列类型则是 + FROM 子句中的 别名 部分必须指定该函数将返回的列名和类型。(在别名中指定列名实际上是标准 SQL 语法,但指定列类型则是 PostgreSQL 的扩展。)这样系统才能在尝试执行该函数之前,就知道 * 应展开成什么,以及 WHERE 子句中的 proname 指的是什么。运行时,如果远程数据库返回的实际查询结果与 diff --git a/zh/12/ddl.sgml b/zh/12/ddl.sgml index 76231373..3c3caa76 100644 --- a/zh/12/ddl.sgml +++ b/zh/12/ddl.sgml @@ -1317,7 +1317,7 @@ REVOKE ALL ON accounts FROM PUBLIC;
- 访问控制列表权限缩写 + ACL 权限缩写 diff --git a/zh/12/dfunc.sgml b/zh/12/dfunc.sgml index 784bf1be..d0a7fa1f 100644 --- a/zh/12/dfunc.sgml +++ b/zh/12/dfunc.sgml @@ -46,7 +46,7 @@ FreeBSD - FreeBSDshared library + FreeBSD共享库 @@ -64,7 +64,7 @@ gcc -shared -o foo.so foo.o HP-UX - HP-UXshared library + HP-UX共享库 @@ -91,7 +91,7 @@ ld -b -o foo.sl foo.o Linux - Linuxshared library + Linux共享库 @@ -108,7 +108,7 @@ cc -shared -o foo.so foo.o macOS - macOSshared library + macOS共享库 @@ -124,7 +124,7 @@ cc -bundle -flat_namespace -undefined suppress -o foo.so foo.o NetBSD - NetBSDshared library + NetBSD共享库 @@ -142,7 +142,7 @@ gcc -shared -o foo.so foo.o OpenBSD - OpenBSDshared library + OpenBSD共享库 @@ -159,7 +159,7 @@ ld -Bshareable -o foo.so foo.o Solaris - Solarisshared library + Solaris共享库 diff --git a/zh/12/diskusage.sgml b/zh/12/diskusage.sgml index 69058394..be6f91e6 100644 --- a/zh/12/diskusage.sgml +++ b/zh/12/diskusage.sgml @@ -15,15 +15,15 @@ - 每个表都有一个主堆磁盘文件,其中存储了大部分数据。如果该表有任何值可能较宽的列,还可能会有一个与该表关联的TOAST文件,用于存储宽到无法方便地放入主表中的值(见)。如果存在,还会在TOAST表上有一个有效索引。也可能会有与基表关联的索引。每个表和索引都存储在单独的磁盘文件中 — 如果文件会超过 1 GB,则可能分成多个文件。这些文件的命名约定见。 - + 每个表都有一个主堆磁盘文件,大部分数据都存储在那里。如果表中有任何列可能包含较宽的值,还可能有一个与该表关联的 TOAST 文件,用于存储那些不适合放在主表中的过宽值(参见)。如果该 TOAST 表存在,则它会有一个有效索引。基础表本身也可能带有索引。每个表和索引都存储在单独的磁盘文件中;如果某个文件会超过 1 GB,则可能拆分为多个文件。关于这些文件的命名规则,请参见。 + - 可以通过三种方式监控磁盘空间:使用中列出的 SQL 函数,使用模块,或者手工检查系统目录。SQL 函数最容易使用,通常也是推荐的方法。本节其余部分展示如何通过检查系统目录来完成此事。 - + 你可以通过三种方式监控磁盘空间:使用中列出的 SQL 函数、使用模块,或者手工检查系统目录。SQL 函数最容易使用,通常也是推荐的方法。本节余下内容展示如何通过检查系统目录来完成这项工作。 + - 在最近做过 vacuum 或 analyze 的数据库上使用psql时,可以发出查询以查看任意表的磁盘使用情况: + 在最近进行过清理或分析 的数据库上使用 psql,你可以发出查询来查看任意表的磁盘使用情况: SELECT pg_relation_filepath(oid), relpages FROM pg_class WHERE relname = 'customer'; @@ -32,11 +32,11 @@ SELECT pg_relation_filepath(oid), relpages FROM pg_class WHERE relname = 'custom base/16384/16806 | 60 (1 row) - 每个页通常为 8 KB。(请记住,relpages只会由VACUUMANALYZE以及少数 DDL 命令(如CREATE INDEX)更新。)如果你想直接检查该表的磁盘文件,文件路径名就很有用。 - + 每一页通常是 8 KB。(请记住,relpages 只会由 VACUUMANALYZE 以及少数 DDL 命令如 CREATE INDEX 更新。)如果你想直接检查该表的磁盘文件,那么文件路径名会很有用。 + - 要显示TOAST表使用的空间,可使用如下查询: + 要显示 TOAST 表使用的空间,可以使用如下查询: SELECT relname, relpages FROM pg_class, @@ -54,9 +54,11 @@ ORDER BY relname; pg_toast_16806 | 0 pg_toast_16806_index | 1 - + - 也可以轻松显示索引大小: + + 也可以很容易地显示索引所占空间: + SELECT c2.relname, c2.relpages FROM pg_class c, pg_class c2, pg_index i WHERE c.relname = 'customer' AND @@ -68,10 +70,10 @@ ORDER BY c2.relname; -------------------+---------- customer_id_index | 26 - + - 利用这些信息,可以很容易找出最大的表和索引: + 利用这些信息,你可以很容易地找出最大的表和索引: SELECT relname, relpages FROM pg_class @@ -82,28 +84,28 @@ ORDER BY relpages DESC; bigtable | 3290 customer | 3144 - + 磁盘已满故障 - 数据库管理员最重要的磁盘监控任务,是确保磁盘不会被写满。数据盘被写满不会导致数据损坏,但可能使有用的活动无法继续进行。如果存放 WAL 文件的磁盘逐渐被写满,数据库服务器可能会进入 panic 状态并随后关闭。 - + 数据库管理员最重要的磁盘监控任务,是确保磁盘不会被写满。数据磁盘写满不会导致数据损坏,但可能会阻止有用的活动继续进行。如果保存 WAL 文件的磁盘被写满,则数据库服务器可能会 panic 并随后关闭。 + - 如果无法通过删除其他内容来释放磁盘上的额外空间,可以利用表空间将部分数据库文件移到其他文件系统上。有关更多信息,请参见。 - + 如果你无法通过删除其他文件来释放更多磁盘空间,那么可以利用表空间把部分数据库文件移动到其他文件系统上。详见。 + - 有些文件系统在接近写满时性能很差,因此不要等到磁盘完全写满才采取措施。 - + 有些文件系统在接近写满时性能会明显变差,因此不要等到磁盘完全写满才采取措施。 + - 如果系统支持按用户设置磁盘配额,那么数据库自然会受限于运行服务器的那个用户所被施加的配额。超出配额与磁盘空间完全耗尽会产生同样的不良影响。 - + 如果你的系统支持按用户设置磁盘配额,那么数据库自然也会受到运行服务器的那个用户所拥有配额的限制。超出配额会带来与磁盘空间完全耗尽相同的不良影响。 + diff --git a/zh/12/docguide.sgml b/zh/12/docguide.sgml index 1e6c18fc..722d5b4e 100644 --- a/zh/12/docguide.sgml +++ b/zh/12/docguide.sgml @@ -212,7 +212,7 @@ checking for dbtoepub... dbtoepub - 使用 Make 构建文档 + 构建文档 一切设置妥当后,切换到doc/src/sgml目录,并运行后续各小节中介绍的某个命令来构建文档。 @@ -230,18 +230,25 @@ checking for dbtoepub... dbtoepub 这也是默认目标。输出位于子目录html中。 - 要生成 HTML 文档,并采用以下站点使用的样式表:postgresql.org,以替代默认的简单样式,请使用: + + 若要使用postgresql.org上所使用的样式表, + 而不是默认的简单样式来生成 HTML 文档,请使用: + doc/src/sgml$ make STYLE=website html + 手册页 - 我们使用 DocBook XSL 样式表转换DocBook - refentry页面,生成适用于手册页的 *roff 输出。要创建手册页,请使用以下命令: + + 我们使用 DocBook XSL 样式表将DocBook + refentry页面转换为适合手册页的 *roff 输出。 + 要创建手册页,请使用以下命令: + doc/src/sgml$ make man @@ -250,16 +257,24 @@ checking for dbtoepub... dbtoepub PDF - 要生成 PDF 格式的文档,可以使用FOP,并根据所需纸张格式,选择以下命令之一: + + 要使用FOP生成文档的 PDF 版本, + 可根据所偏好的纸张格式使用下列命令之一: + + - 对于 A4 格式: + + 对于 A4 格式: + doc/src/sgml$ make postgres-A4.pdf - 对于美国信纸格式: + + 对于美国信纸格式: + doc/src/sgml$ make postgres-US.pdf @@ -267,30 +282,50 @@ checking for dbtoepub... dbtoepub - 由于 PostgreSQL 文档相当庞大,FOP需要大量内存。因此,在某些系统上,构建会失败并报告与内存有关的错误。通常可以通过在以下配置文件中调整 Java 堆设置来解决此问题:~/.foprc,例如: -# FOP binary distribution + + 由于 PostgreSQL 文档相当庞大,FOP需要占用相当多的内存。 + 因此,在某些系统上,构建会因内存相关错误而失败。这通常可以通过在配置文件 + ~/.foprc中配置 Java 堆设置来解决,例如: + +# FOP 二进制发行版 FOP_OPTS='-Xmx1500m' # Debian JAVA_ARGS='-Xmx1500m' # Red Hat ADDITIONAL_FLAGS='-Xmx1500m' -所需内存存在一个最低限度,而在一定范围内,更多内存似乎能使构建稍快一些。在内存很少(不足 1 GB)的系统上,构建要么因交换而非常缓慢,要么根本无法进行。 + + 所需内存存在一个最低门槛,而且在一定程度上,内存越多似乎会让构建稍快一些。 + 对于内存很少(小于 1 GB)的系统,构建要么会因交换而非常缓慢,要么根本无法工作。 + - 其他 XSL-FO 处理器也可以手动使用,但自动构建过程只支持 FOP。 + + + 也可以手工使用其他 XSL-FO 处理器,但自动化构建过程只支持 FOP。 + 纯文本文件 - 安装说明也以纯文本形式分发,以便在没有更好阅读工具的情况下使用。INSTALL文件对应于,仅为适应不同语境作了一些小改动。要重新创建该文件,请切换到doc/src/sgml目录并输入make INSTALL。构建文本输出还需要Pandoc 1.13 或更新版本作为额外的构建工具。 + + 安装说明也以纯文本形式分发,以便在没有更好的阅读工具时使用。 + INSTALL文件对应,并针对不同语境作了少量调整。 + 要重新生成该文件,请切换到doc/src/sgml目录,然后输入make INSTALL。 + 构建文本输出还需要Pandoc 1.13 或更新版本作为额外的构建工具。 + - 过去,发布说明和回归测试说明也以纯文本形式分发,但这种做法已经停止。 + + 过去,发行说明和回归测试说明也曾以纯文本形式分发,但现已停止这种做法。 + 语法检查 - 构建文档可能耗时很长。但有一种方法可以只检查文档文件的语法是否正确,只需几秒钟: + + 构建文档可能非常耗时。但有一种方法可以只检查文档文件的语法是否正确, + 这只需要几秒钟: + doc/src/sgml$ make check diff --git a/zh/12/ecpg.sgml b/zh/12/ecpg.sgml index aff440ce..c08fbbc6 100644 --- a/zh/12/ecpg.sgml +++ b/zh/12/ecpg.sgml @@ -1041,7 +1041,7 @@ oid=313780, datname=testdb, size=8183012 - 结构体主变量将列尽数吸收成结构体的域。额外的列可以被分配给其他主变量。例如,上面的程序也可以使用结构体外部的size变量重新构造: + 结构体主变量吸收的列数与结构体的字段数相同。额外的列可以被分配给其他主变量。例如,上面的程序也可以使用结构体外部的size变量改写: EXEC SQL BEGIN DECLARE SECTION; typedef struct @@ -1305,7 +1305,7 @@ while (1) 用户定义的基础类型 - ECPG 并不直接支持新的用户定义的基本类型。你可以使用外部字符串表示以及类型char[]VARCHAR[]的主变量,并且这种方案事实上对很多类型都是合适和足够的。 + ECPG 并不直接支持新的用户定义的基础类型。你可以使用外部字符串表示以及类型char[]VARCHAR[]的主变量,并且这种方案事实上对很多类型都是合适和足够的。 下面的示例使用数据类型 complex,它来自 中的示例。该类型的外部字符串表示为 (%f,%f),由函数 complex_in()complex_out() 定义,见 。以下示例将复数类型的值 (1,1)(3,3) 分别插入列 ab,然后从表中查询它们。 @@ -4473,7 +4473,7 @@ EXEC SQL INCLUDE "filename"; 当前目录 /usr/local/include - PostgreSQL 的包括目录,在编译时定义(例如/usr/local/pgsql/include + PostgreSQL 的头文件目录,在编译时定义(例如/usr/local/pgsql/include /usr/include @@ -5193,7 +5193,7 @@ DATABASE connection_target 使用 user_name/passworduser_name IDENTIFIED BY password或者 - user_name USING password之一,这个参数也能指定用户名和密码. + user_name USING password之一,这个参数也能指定用户名和密码。 @@ -7198,19 +7198,19 @@ int rjulmdy(date d, short mdy[3]); rdefmtdate - 使用格式掩码将字符字符串转换为日期类型的值。 + 使用格式掩码将字符串转换为日期类型的值。 int rdefmtdate(date *d, char *fmt, char *str); 该函数接收一个指向应该保存操作结果的日期值的指针(d), 用于解析日期的格式掩码(fmt)和包含日期文本表示的C char*字符串 (str)。文本表示应与格式掩码匹配。但是,你不需要将字符串 - 与格式掩码进行一一映射。该函数仅分析顺序顺序,并查找表示年份位置的文字 + 与格式掩码进行一一映射。该函数只分析先后顺序,并查找表示年份位置的字面文本 yyyyyy,表示月份位置的mm 和表示日期位置的dd - 该函数返回以下值: + 该函数返回以下值: diff --git a/zh/12/event-trigger.sgml b/zh/12/event-trigger.sgml index ca40cdfa..28455902 100644 --- a/zh/12/event-trigger.sgml +++ b/zh/12/event-trigger.sgml @@ -20,11 +20,11 @@ - 事件触发器行为概览 + 事件触发器行为概述 只要与事件触发器关联的事件在其定义所在数据库中发生,事件触发器就会被触发。 - 目前唯一支持的事件有 + 目前仅支持以下事件: ddl_command_startddl_command_endtable_rewrite @@ -39,14 +39,14 @@ COMMENTGRANTREVOKE 命令即将执行之前。在事件触发器触发之前,不会检查受影响对象究竟存在还是不存在。 但有一个例外:对于以共享对象 — 数据库、角色和表空间 — - 为目标的 DDL 命令,或者针对事件触发器本身的命令,不会发生该事件。事件触发器机制 + 为目标的 DDL 命令或者针对事件触发器本身的命令,不会发生该事件。事件触发器机制 不支持这些对象类型。 ddl_command_start 也会在 SELECT INTO 命令即将执行之前发生,因为它等价于 CREATE TABLE AS - ddl_command_end 事件发生在与上述同一组命令执行之后。 + ddl_command_end 事件发生在上述同一组命令执行之后。 要获取这些 DDL 操作的更多细节,可在 ddl_command_end 事件触发器代码中使用集合返回函数 pg_event_trigger_ddl_commands()(见 @@ -1049,7 +1049,7 @@ CALLED_AS_EVENT_TRIGGER(fcinfo) ((fcinfo)->context != NULL && IsA((fcinfo)->context, EventTriggerData)) - 如果该宏返回 true,那么就可以安全地将 fcinfo->context + 如果该宏返回真,那么就可以安全地将 fcinfo->context 转换为 EventTriggerData * 类型,并使用它所指向的 EventTriggerData 结构体。该函数 不得修改 EventTriggerData @@ -1115,7 +1115,7 @@ typedef struct EventTriggerData 事件触发器函数必须返回一个 NULL 指针 (不是 SQL 空值,也就是不要将 - isNull 设为 true)。 + isNull 设为真)。 @@ -1162,7 +1162,9 @@ noddl(PG_FUNCTION_ARGS) ]]> - 编译源代码后(见),声明函数和触发器: + + 编译源代码之后(见 ),声明该函数和触发器: + CREATE FUNCTION noddl() RETURNS event_trigger AS 'noddl' LANGUAGE C; @@ -1171,7 +1173,9 @@ CREATE EVENT TRIGGER noddl ON ddl_command_start - 现在可以测试触发器的工作情况: + + 现在可以测试该触发器的工作情况: + =# \dy List of event triggers Name | Event | Owner | Enabled | Function | Tags @@ -1206,7 +1210,9 @@ COMMIT; 从而只允许在维护窗口内执行重写。 - 下面是一个实现这种策略的示例。 + + 以下是实现这种策略的一个示例。 + CREATE OR REPLACE FUNCTION no_rewrite() RETURNS event_trigger LANGUAGE plpgsql AS diff --git a/zh/12/extend.sgml b/zh/12/extend.sgml index dac5452e..9e9bd8e7 100644 --- a/zh/12/extend.sgml +++ b/zh/12/extend.sgml @@ -39,7 +39,7 @@ - 相关对象包(从 开始) + 相关对象的包(从 开始) @@ -49,11 +49,28 @@ 可扩展性如何运作 - PostgreSQL 之所以具有可扩展性,是因为它的运作由目录驱动。如果你熟悉标准的关系数据库系统,就会知道它们会把数据库、表、列等信息存储在通常所说的系统目录中(有些系统称之为数据字典)。这些目录对用户来说看起来和普通表无异,但 DBMS 会在其中保存自己的内部记账信息。PostgreSQL 与标准关系数据库系统的一个关键区别在于,PostgreSQL在目录中存储了更多信息:不仅包括表和列的信息,还包括数据类型、函数、访问方法等信息。这些表可以由用户修改,而 PostgreSQL 又正是基于这些表运行的,这就意味着用户可以扩展 PostgreSQL。相比之下,传统数据库系统只能通过修改源代码中的硬编码过程,或装入由 DBMS 供应商专门编写的模块来扩展。 + PostgreSQL 之所以具有可扩展性,是因为其 + 运作由系统目录驱动。如果你熟悉标准的关系数据库系统,就会知道它们把 + 有关数据库、表、列等的信息存储在通常所说的系统目录中(有些系统把这 + 称为数据字典)。这些目录对用户而言看起来就像普通表一样,但 + DBMS 会在其中保存自己的内部管理信息。 + PostgreSQL 与标准关系数据库系统的一个关键差别是, + PostgreSQL 在目录中存储的信息要多得多:不仅有关于表和列的信息,还有关于数据 + 类型、函数、访问方法等的信息。这些表可以由用户修改,而 + PostgreSQL 又是基于这些表来运行的,这意味着 + PostgreSQL 可以由用户扩展。相比之下,传统数据库 + 系统只能通过修改源代码中的硬编码过程,或加载由 + DBMS 供应商专门编写的模块来扩展。 - 此外,PostgreSQL 服务器还可以通过动态加载将用户编写的代码纳入自身。也就是说,用户可以指定一个实现新类型或新函数的目标代码文件(例如共享库),而 PostgreSQL 会在需要时加载它。把用 SQL 编写的代码加入服务器就更简单了。这种能够即时修改自身行为的能力,使 PostgreSQL 特别适合用于新应用和新存储结构的快速原型设计。 + 此外,PostgreSQL 服务器还能通过动态加载把用户 + 编写的代码纳入自身。也就是说,用户可以指定一个实现了新类型或新函数 + 的目标代码文件(例如共享库),而 PostgreSQL + 会在需要时加载它。把用 SQL 编写的代码加入服务器就更 + 为简单了。这种能够即时修改自身行为的能力,使 + PostgreSQL 特别适合用于新应用和新存储结构的快速 + 原型设计。 @@ -75,7 +92,7 @@ 数据类型 - 组合 + 复合 @@ -295,7 +312,7 @@ 哪些 SQL 对象种类可以成为扩展成员,见 的说明。特别是,数据库集簇范围内的对象,如数据库、角色和表空间,不能 - 成为扩展成员,因为扩展只在单个数据库内可见。(尽管扩展脚本并不禁止创 + 成为扩展成员,因为扩展只在单个数据库内可见。(尽管并不禁止扩展脚本创 建这类对象,但如果这样做,它们不会作为扩展的一部分受到跟踪。)还要注意, 虽然表可以成为扩展成员,但其附属对象(如索引)并不直接被视为扩展成员。 另一个重要点是,模式可以属于扩展,但反过来不成立:扩展本身只有一个非 @@ -336,7 +353,11 @@ directory (string) - 包含扩展的 SQL 脚本文件的目录。除非给出绝对路径,否则该名称相对于安装目录的 SHAREDIR 目录。默认行为等价于指定 directory = 'extension' + + 包含扩展 SQL 脚本文件的目录。除非给出的是绝对路 + 径,否则该名称相对于安装的 SHAREDIR 目录。默认行为 + 等价于指定 directory = 'extension'。 + @@ -502,7 +523,7 @@ 扩展,应在控制文件中设置 relocatable = false,并在脚本文件中使用 @extschema@ 来引用目标模式。在脚本执行前,该字符 - 串的每次出现都会被替换为实际目标模式的名称(必要时加双引号)。用户 + 串的每次出现都会被替换为实际目标模式的名称。用户 可以通过 CREATE EXTENSIONSCHEMA 选项设置目标模式。 @@ -514,7 +535,7 @@ relocatable = false,并把 schema 设置为预定目标模式的名称。这样将阻止使用 CREATE EXTENSIONSCHEMA - 选项,除非它指定的正是控制文件中命名的那个模式。如果扩展对其模式名 + 选项,除非它指定的正是控制文件中命名的那个模式。如果扩展对模式名 称有无法通过 @extschema@ 替换解决的内部假设,通 常就需要采用这种方式。在这种情况下, @extschema@ 替换机制仍然可用,只是由于模式名由控 @@ -663,7 +684,7 @@ SELECT pg_catalog.pg_extension_config_dump('my_config', 'WHERE NOT standard_entr 在有合适更新脚本可用的前提下, - ALTER EXTENSION UPDATE 命令可以把已安装的扩展更新 + ALTER EXTENSION UPDATE 命令会把已安装的扩展更新 到指定的新版本。更新脚本运行在 CREATE EXTENSION 为安装脚本提供的同一环境中:尤其 是,search_path 的设置方式完全相同,而且脚本创建的 @@ -676,7 +697,7 @@ SELECT pg_catalog.pg_extension_config_dump('my_config', 'WHERE NOT standard_entr (新)版本相关联的那些参数。 - 更新机制可以用于解决一个重要的特殊情况:将散装对象集合转换为扩展。在 PostgreSQL 于 9.1 加入扩展机制之前,许多人编写的扩展模块只是创建各种未打包的对象。对于包含这些对象的现有数据库,如何将它们转换为正确打包的扩展?删除它们再执行普通的 CREATE EXTENSION 是一种办法,但如果对象具有依赖关系(例如,某些表列使用扩展创建的数据类型),就不适合这样做。解决方法是先创建一个空扩展,再使用 ALTER EXTENSION ADD 将每个现有对象附加到扩展中,最后创建当前扩展版本中存在、而散装版本中没有的新对象。CREATE EXTENSION 通过 FROM old_version 选项支持这种情况:它不运行目标版本的普通安装脚本,而是运行名为 extension--old_version--target_version.sql 的更新脚本。用作 old_version 的虚拟版本名由扩展作者选择,不过通常约定使用 unpackaged。如果需要将多个先前版本更新为扩展形式,应使用不同的虚拟版本名来标识它们。 + 更新机制可以用于解决一个重要的特殊情况:将松散对象集合转换为扩展。在 PostgreSQL 于 9.1 加入扩展机制之前,许多人编写的扩展模块只是创建各种未打包的对象。对于包含这些对象的现有数据库,如何将它们转换为正确打包的扩展?删除它们再执行普通的 CREATE EXTENSION 是一种办法,但如果对象具有依赖关系(例如,某些表列使用扩展创建的数据类型),就不适合这样做。解决方法是先创建一个空扩展,再使用 ALTER EXTENSION ADD 将每个现有对象附加到扩展中,最后创建当前扩展版本中存在、而未打包版本中没有的新对象。CREATE EXTENSION 通过 FROM old_version 选项支持这种情况:它不运行目标版本的普通安装脚本,而是运行名为 extension--old_version--target_version.sql 的更新脚本。用作 old_version 的虚拟版本名由扩展作者选择,不过通常约定使用 unpackaged。如果需要将多个先前版本更新为扩展形式,应使用不同的虚拟版本名来标识它们。 ALTER EXTENSION 能够执行一系列更新脚本文件来完成 @@ -691,7 +712,7 @@ SELECT pg_catalog.pg_extension_config_dump('my_config', 'WHERE NOT standard_entr 例如,它并不知道 1.1 是否跟在 1.0 之后。它只是匹配可用的版本名,并选择需要应用 更新脚本最少的那条路径。(实际上,版本名可以是任何不包含 - --,且不以前导或尾随 - 结尾的字 + --,且不以 - 开头或结尾的字 符串。) @@ -812,7 +833,7 @@ SELECT * FROM pg_extension_update_paths('extension_namemyschema.myfunc(bigint),那么像 myschema.myfunc(42) 这样的调用,就可能被恶意函数 myschema.myfunc(integer) 截获。要注意函数和操作符 - 参数的数据类型必须与声明的实参类型精确匹配,必要时请使用显式类型转 + 所传参数的数据类型必须与声明的参数类型精确匹配,必要时请使用显式类型转 换。 @@ -857,7 +878,7 @@ SELECT * FROM pg_extension_update_paths('extension_name扩展示例 - 下面给出一个纯 SQL 扩展的完整示例:一个双元素组合 + 下面给出一个纯 SQL 扩展的完整示例:一个双元素复合 类型,它可以在两个槽位中存储任意类型的值,这两个槽位名为 kv。非文本值会自动强制转换为文本后 再存储。 @@ -929,7 +950,7 @@ include $(PGXS) 如果你打算分发自己的 PostgreSQL 扩展模块, - 那么为它们搭建一个可移植的构建系统会相当困难。因此, + 那么为它们搭建一个可移植的构建系统可能相当困难。因此, PostgreSQL 安装提供了一套称为 PGXS 的扩展构建基础设施,使简单的扩展模块可以针对 已安装好的服务器直接构建。PGXS 主要面向包含 C 代码 @@ -940,7 +961,15 @@ include $(PGXS) 可能还是需要自己编写构建系统。 - 要使用PGXS基础设施构建扩展,必须编写一个简单的 makefile。在其中需要设置一些变量,并包含全局PGXSmakefile。下面的示例构建一个扩展模块,名为isbn_issn,由包含一些 C 代码的共享库、扩展控制文件、SQL 脚本、包含文件(仅在其他模块可能需要不经 SQL 访问扩展函数时才需要)以及文档文本文件组成: + + 要为你的扩展使用 PGXS 基础设施,你必须写一个简单 + 的 makefile。在这个 makefile 中,需要设置一些变量并包含全局 + PGXS makefile。下面是一个示例,它构建一个名为 + isbn_issn 的扩展模块,该模块包含一个装有一些 C 代 + 码的共享库、一个扩展控制文件、一个 SQL 脚本、一个头文件(只有当其他 + 模块可能需要绕过 SQL 直接访问扩展函数时才需要),以及一个文档文本文 + 件: + MODULES = isbn_issn EXTENSION = isbn_issn DATA = isbn_issn--1.0.sql @@ -950,9 +979,15 @@ HEADERS_isbn_issn = isbn_issn.h PG_CONFIG = pg_config PGXS := $(shell $(PG_CONFIG) --pgxs) include $(PGXS) -最后三行应始终相同。在文件的前面部分,可以给变量赋值或添加自定义的make规则。 + + 最后三行始终都应相同。你应在文件前面的部分设置变量或添加自定义的 + make 规则。 + + + + 设定下列三个变量中的一个,以指定要构建的内容: - 设置这三个变量之一,以指定构建内容: + MODULES @@ -966,7 +1001,7 @@ include $(PGXS) MODULE_big - 要从多个源文件构建的共享库(在 OBJS 中列出对象 + 要从多个源文件构建的共享库(在 OBJS 中列出目标 文件) @@ -976,11 +1011,15 @@ include $(PGXS) PROGRAM - 要构建的可执行程序(在 OBJS 中列出对象文件) + 要构建的可执行程序(在 OBJS 中列出目标文件) - 还可以设置以下变量: + + + 还可以设置以下变量: + + EXTENSION @@ -1257,7 +1296,12 @@ include $(PGXS) make 命令行上设置都可以。 - 如果希望将构建目录单独放置,也可以运行make,并将工作目录设在扩展源码树之外。这种做法也称为VPATHVPATH构建。具体方法如下: + + 如果你想保持构建目录与源代码目录分离,也可以在扩展源代码树之外的目录 + 中运行 make。这一过程也称为 + VPATHVPATH + 构建。做法如下: + mkdir build_dir cd build_dir make -f /path/to/extension/source/tree/Makefile @@ -1284,7 +1328,7 @@ make VPATH=/path/to/extension/source/tree install 正在运行的 PostgreSQL 服务器。列在 REGRESS 中的脚本文件必须位于扩展目录下名为 sql/ 的子目录中。这些文件必须具有 - .sql 扩展名,而该扩展名不应出现在 makefile 的 + .sql 扩展名,而该扩展名不能出现在 makefile 的 REGRESS 列表中。对于每个测试,还应在名为 expected/ 的子目录中有一个包含期望输出的文件,其主 干名相同,扩展名为 .out。 @@ -1303,7 +1347,7 @@ make VPATH=/path/to/extension/source/tree install 必须有一个正在运行的 PostgreSQL 服务器。列 在 ISOLATION 中的脚本文件必须位于扩展目录下名为 specs/ 的子目录中。这些文件必须具有 - .spec 扩展名,而该扩展名不应出现在 makefile 的 + .spec 扩展名,而该扩展名不能出现在 makefile 的 ISOLATION 列表中。对于每个测试,还应在名为 expected/ 的子目录中有一个包含期望输出的文件,其主 干名相同,扩展名为 .out。 diff --git a/zh/12/features.sgml b/zh/12/features.sgml index 234306e7..dabd100b 100644 --- a/zh/12/features.sgml +++ b/zh/12/features.sgml @@ -376,7 +376,7 @@ SELECT XMLQUERY('$a is $b' PASSING BY VALUE x AS a, < DOCUMENTCONTENT形式的值。 一个 XQuery/XPath 表达式的上下文项必须是单个 XML 节点或原子值, 但 XPath 1.0 又进一步限制它只能是 XML 节点,并且没有允许CONTENT的节点类型。 - 归根结底,格式良好的DOCUMENT是 + 归根结底,良构的DOCUMENTPostgreSQL能够作为 XPath 上下文项提供的唯一 XML 值形式。 diff --git a/zh/12/func.sgml b/zh/12/func.sgml index 12244865..6683e9be 100644 --- a/zh/12/func.sgml +++ b/zh/12/func.sgml @@ -25,14 +25,14 @@ 逻辑操作符 - operator - logical + 操作符 + 逻辑 - Boolean - operators - operators, logical + 布尔 + 操作符 + 操作符,逻辑 @@ -51,15 +51,15 @@ - conjunction + 合取 - disjunction + 析取 - negation + 否定 @@ -166,8 +166,8 @@ 比较函数和操作符 - comparison - operators + 比较 + 操作符 @@ -349,12 +349,12 @@ IS NOT DISTINCT FROM - 当有一个输入为空时,普通的比较操作符会得到空(表示未知),而不是真或假。例如,7 = NULL得到空,7 <> NULL也一样。如果这种行为不合适,可以使用IS NOT DISTINCT FROM谓词: + 当任一输入为 null 时,普通的比较操作符会得到 null(表示未知),而不是真或假。例如,7 = NULL得到 null,7 <> NULL也一样。如果这种行为不合适,可以使用IS NOT DISTINCT FROM谓词: a IS DISTINCT FROM b a IS NOT DISTINCT FROM b - 对于非空输入,IS DISTINCT FROM<>操作符一样。不过,如果两个输入都为空,它会返回假。而如果只有一个输入为空,它会返回真。类似地,IS NOT DISTINCT FROM对于非空输入的行为与=相同,但是当两个输入都为空时它返回真,并且当只有一个输入为空时返回假。因此,这些谓词实际上把空值当作一种普通数据值,而不是未知。 + 对于非 null 输入,IS DISTINCT FROM<>操作符一样。不过,如果两个输入都为 null,它会返回假。而如果只有一个输入为 null,它会返回真。类似地,IS NOT DISTINCT FROM对于非 null 输入的行为与=相同,但是当两个输入都为 null 时它返回真,并且当只有一个输入为 null 时返回假。因此,这些谓词实际上把 null 当作一种普通数据值,而不是未知 @@ -370,7 +370,7 @@ NOTNULL - 要检查一个值是否为空,使用下面的谓词: + 要检查一个值是否为 null,使用下面的谓词: expression IS NULL expression IS NOT NULL @@ -380,7 +380,7 @@ expression ISNULL expression NOTNULL - null valuecomparing + 空值比较 @@ -390,7 +390,7 @@ - 有些应用可能要求表达式expression = NULLexpression得出空值时返回真。我们强烈建议这样的应用修改成遵循 SQL 标准。但是,如果这样修改不可能完成,那么我们可以使用配置变量。如果打开它,PostgreSQL将把x = NULL子句转换成x IS NULL。 + 有些应用可能期望表达式expression = NULLexpression求值为 null 时返回真。我们强烈建议此类应用修改为遵循 SQL 标准。但是,如果无法这样修改,那么可以使用配置变量。如果将其打开,PostgreSQL会把x = NULL子句转换成x IS NULL @@ -426,7 +426,7 @@ boolean_expression IS UNKNOWN boolean_expression IS NOT UNKNOWN - 这些谓词将总是返回真或假,从来不返回空值,即使操作数为空也如此。空值输入被当作逻辑值未知。请注意,IS UNKNOWNIS NOT UNKNOWN实际上分别等同于IS NULLIS NOT NULL,只是输入表达式必须是布尔类型。 + 这些谓词总是返回真或假,从不返回空值,即使操作数为 null 也是如此。null 输入被当作逻辑值未知。请注意,IS UNKNOWNIS NOT UNKNOWN实际上分别等同于IS NULLIS NOT NULL,只是输入表达式必须是布尔类型。 + 正则表达式 + @@ -2939,7 +2945,7 @@ cast(-44 as bit(12)) 111111010100 SIMILAR TO 操作符根据其模式是否匹配给定字符串返回真或假。它与 LIKE 类似,但按照 SQL 标准定义的正则表达式来解释模式。SQL 正则表达式是 LIKE 表示法和常见正则表达式表示法的一种奇特结合。 - 类似LIKESIMILAR TO操作符只有在它的模式匹配整个串的时候才能成功;这一点和普通的 正则表达式的行为不同,在普通的正则表达式里,模式匹配串的任意部分。 和LIKE类似的地方还有,SIMILAR TO使用_%作为分别代表任意单个字符和任意串的通配符(这些可以比得上 POSIX 正则表达式里的..*)。 + 与LIKE类似,SIMILAR TO操作符只有在其模式匹配整个字符串时才算成功;这一点不同于普通正则表达式,后者可以匹配字符串的任意部分。与LIKE相同,SIMILAR TO也使用_%作为通配符,分别匹配任意单个字符和任意字符串(分别类似于 POSIX 正则表达式中的..*)。 @@ -3017,7 +3023,7 @@ substring(string, pattern, - 作为对SQL标准的扩展,PostgreSQL只允许有一个转义双引号分隔符,在这种情况下,第三个正则表达式被视为空;或者没有分隔符,在这种情况下,第一个和第三个正则表达式被视为空。 + 作为对SQL标准的扩展,PostgreSQL允许仅有一个转义双引号分隔符,在这种情况下,第三个正则表达式被视为空;或者没有分隔符,在这种情况下,第一个和第三个正则表达式被视为空。 下面是一些示例,其中使用#"界定返回字符串: @@ -3031,8 +3037,8 @@ substring('foobar' from '#"o_b#"%' for '#') NULLPOSIX正则表达式 - regular expression - pattern matching + 正则表达式 + 模式匹配 substring @@ -3088,11 +3094,11 @@ substring('foobar' from '#"o_b#"%' for '#') NULL - POSIX正则表达式提供了比LIKESIMILAR TO操作符更强大的含义。许多 Unix 工具,例如egrepsedawk使用一种与我们这里描述的类似的模式匹配语言。 + POSIX正则表达式提供了比LIKESIMILAR TO操作符更强大的模式匹配方式。许多 Unix 工具,例如egrepsedawk,都使用与这里描述的模式匹配语言相似的语言。 - 正则表达式是一个字符序列,它是定义一个串集合 (一个正则集)的缩写。 如果一个串是正则表达式描述的正则集中的一员时, 我们就说这个串匹配该正则表达式。 和LIKE一样,模式字符准确地匹配串字符, 除非在正则表达式语言里有特殊字符 — 不过正则表达式用的 特殊字符和LIKE用的不同。 和LIKE模式不一样的是,正则表达式允许匹配串里的任何位置,除非该正则表达式显式地挂接在串的开头或者结尾。 + 正则表达式是一个字符序列,是定义一组字符串(一个正则集)的简写。如果字符串属于正则表达式描述的正则集,就称该字符串匹配此正则表达式。与LIKE一样,模式中的字符精确匹配字符串中的字符,除非该模式字符在正则表达式语言中有特殊含义 — 但正则表达式使用的特殊字符与LIKE不同。与LIKE模式不同,正则表达式可以匹配字符串中的任意位置,除非显式将其锚定到字符串开头或末尾。 下面是一些示例: @@ -3128,13 +3134,13 @@ regexp_replace('foobarbaz', 'b(..)', 'X\1Y', 'g') - regexp_match函数返回一个文本数组,其中包含与POSIX正则表达式模式对字符串的第一个匹配的子字符串。它的语法为 + regexp_match函数返回一个文本数组,包含字符串首次匹配 POSIX 正则表达式模式时捕获的子字符串。它的语法为 regexp_match(string, pattern , flags )。 如果没有匹配,结果为NULL。 - 如果找到匹配,并且pattern不包含括号子表达式,则结果是包含与整个模式匹配的子字符串的单元素文本数组。 - 如果找到匹配,并且pattern包含括号子表达式,则结果是一个文本数组,其中第n个元素是匹配 - pattern的第n个括号子表达式的子字符串(不包括非捕获括号;详情见下文)。 + 如果找到匹配,并且pattern不包含圆括号子表达式,则结果是包含与整个模式匹配的子字符串的单元素文本数组。 + 如果找到匹配,并且pattern包含圆括号子表达式,则结果是一个文本数组,其中第n个元素是匹配 + pattern的第n个圆括号子表达式的子字符串(不包括非捕获括号;详情见下文)。 flags参数是一个可选的文本字符串,其中包含零个或多个单个字母标志,用于更改函数的行为。支持的标志在中描述。 @@ -3188,16 +3194,16 @@ SELECT regexp_matches('foobarbequebazilbarfbonk', '(b[^b]+)(b[^b]+)', 'g'); - 在大部分情况下,regexp_matches()应该与g标志一起使用,因为如果只是想要第一个匹配,使用regexp_match()会更加简单高效。不过,regexp_match()仅存在于PostgreSQL版本10以及更高的版本中。当在较老的版本中使用时,一种常用的技巧是把regexp_matches()调用放在子选择中,例如: + 在大部分情况下,regexp_matches()应该与g标志一起使用,因为如果只是想要第一个匹配,使用regexp_match()会更加简单高效。不过,regexp_match()仅存在于PostgreSQL版本10以及更高的版本中。当在较老的版本中使用时,一种常用的技巧是把regexp_matches()调用放在子查询中,例如: SELECT col1, (SELECT regexp_matches(col2, '(bar)(beque)')) FROM tab; - 如果有一个匹配,则这个语句会产生一个文本数组,否则返回NULL,这和regexp_match()的做法一样。如果没有子选择,这个查询对于没有匹配的表行根本不会产生输出,显然那不是想要的行为。 + 如果有一个匹配,则这个语句会产生一个文本数组,否则返回NULL,这和regexp_match()的做法一样。如果没有子查询,这个查询对于没有匹配的表行根本不会产生输出,这通常不是预期行为。 - regexp_split_to_table把一个 POSIX 正则表达式模式当作一个定界符来分离一个串。它的语法形式是regexp_split_to_table(string, pattern , flags )。如果没有与pattern的匹配,该函数返回string。如果有至少有一个匹配,对每一个匹配它都返回从上一个匹配的末尾(或者串的开头)到这次匹配开头之间的文本。当没有更多匹配时,它返回从上一次匹配的末尾到串末尾之间的文本。flags参数是一个可选的文本串,它包含零个或更多单字母标志,这些标识可以改变该函数的行为。regexp_split_to_table能支持的标志在中描述。 + regexp_split_to_table把一个 POSIX 正则表达式模式当作一个定界符来分割字符串。它的语法形式是regexp_split_to_table(string, pattern , flags )。如果没有与pattern的匹配,该函数返回string。如果至少有一个匹配,对每一个匹配它都返回从上一个匹配的末尾(或者串的开头)到这次匹配开头之间的文本。当没有更多匹配时,它返回从上一次匹配的末尾到串末尾之间的文本。flags参数是一个可选的文本串,它包含零个或更多单字母标志,这些标志可以改变该函数的行为。regexp_split_to_table能支持的标志在中描述。 @@ -3250,9 +3256,9 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; - 正如最后一个示例所示,regexp分割函数会忽略出现在字符串开头或结尾 + 正如最后一个示例所示,正则表达式分割函数会忽略出现在字符串开头或结尾 或紧跟在前一个匹配项之后的零长度匹配。这与regexp_matchregexp_matches实现的 - 严格的regexp匹配定义相矛盾,但在实践中通常是最方便的行为。 + 严格的正则表达式匹配定义相矛盾,但在实践中通常是最方便的行为。 其他软件系统如Perl使用类似的定义。 @@ -3286,7 +3292,7 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; - 一个量化原子是一个原子, 后面可能跟着一个量词。没有量词的时候,它匹配一个原子, 有量词的时候,它可以匹配若干个原子。一个原子可以是在里面显示的任何可能。 可能的量词和它们的含义在里显示。 + 一个量化原子是一个原子,后面可以跟一个量词。没有量词时,匹配一次原子所匹配的内容;有量词时,按量词指定的次数匹配原子所匹配的内容。原子可以是列出的任何一种形式。可用量词及其含义见 @@ -3309,12 +3315,12 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; (re) - (其中re是任何正则表达式) 匹配一个对re的匹配,匹配将为可能的报告被记下 + (其中re是任意正则表达式)匹配re所匹配的内容,并记录该匹配,以备输出结果 (?:re) - 同上,但是匹配不会为了报告而被记下 (一个非捕获圆括号集) (只对 ARE) + 同上,但不记录匹配结果(非捕获圆括号;仅适用于 ARE) @@ -3329,17 +3335,17 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; \k - (其中k是一个非字母数字字符) 匹配一个被当作普通字符看待的特定字符, 例如,\\匹配一个反斜线字符 + (其中k既不是字母也不是数字)把该字符视为普通字符并匹配它,例如,\\匹配反斜线字符 \c - 其中c是一个字母数字 (可能跟着其它字符),它是一个转义, 参阅(仅对 ARE; 在 ERE 和 BRE 中,它匹配c + 其中c是字母或数字(后面可能还有其他字符),这是一个转义,参见(仅适用于 ARE;在 ERE 和 BRE 中,它匹配c { - 如果后面跟着一个字符,而不是数字, 那么就匹配左花括弧{;如果跟着一个数字, 那么它是bound的开始(见下文) + 如果后面跟着非数字字符,则匹配左花括号{;如果后面跟着数字,则是bound的开头(见下文) @@ -3357,7 +3363,7 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; - 如果你关掉了,你在文串常量中写的任何反斜线都需要被双写。详见。 + 如果你关掉了,你在字符串常量中写的任何反斜线都需要被双写。详见 @@ -3446,7 +3452,7 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; - 非贪婪的量词(只在 ARE 中可用)匹配对应的正常 (贪婪)模式,区别是它寻找最少的匹配,而不是最多的匹配。详见。 + 非贪婪量词(仅适用于 ARE)与对应的普通(贪婪)量词匹配相同的可能内容,但优先选择最少的匹配次数,而不是最多的匹配次数。详见 @@ -3473,39 +3479,39 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; ^ - 串开头的匹配 + 在字符串开头匹配 $ - 串末尾的匹配 + 在字符串末尾匹配 (?=re) - 在某个位置上,如果从该位置开始的子串能够匹配re,则匹配正向先行断言(仅对 ARE) + 正向先行断言在这样的位置匹配:存在从该位置开始且匹配re的子字符串(仅适用于 ARE) (?!re) - 在某个位置上,如果从该位置开始的子串不能匹配re,则匹配负向先行断言(仅对 ARE) + 负向先行断言在这样的位置匹配:不存在任何从该位置开始且匹配re的子字符串(仅适用于 ARE) (?<=re) - 在某个位置上,如果以该位置结束的某个子串能够匹配re,则匹配正向后行断言(仅对 ARE) + 正向后行断言在这样的位置匹配:存在以该位置结束且匹配re的子字符串(仅适用于 ARE) (?<!re) - 在某个位置上,如果以该位置结束的任何子串都不能匹配re,则匹配负向后行断言(仅对 ARE) + 负向后行断言在这样的位置匹配:不存在任何以该位置结束且匹配re的子字符串(仅适用于 ARE)
- Lookahead 和 lookbehind 约束不能包含反向引用 (参阅),并且其中的所有圆括号 都被认为是非捕获的。 + 先行和后行约束不能包含反向引用(参见),其中的所有圆括号都视为非捕获圆括号。 @@ -3513,11 +3519,11 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; 方括号表达式 - 方括号表达式是一个包围在[]中的字符列表。它通常匹配列表中的任意单个字符(但见下文)。 如果列表以^开头,它匹配任意单个在该列表参与部分中的字符。如果该列表中两个字符用-隔开, 那它就是那两个字符(包括在内)之间的所有字符范围的缩写,例如,在ASCII[0-9]匹配任何十进制数字。两个范围共享一个端点是非法的,例如,a-c-e。范围与字符集关系密切, 可移植的程序应该避免依靠它们。 + 方括号表达式是用[]括起来的字符列表。通常,它匹配列表中的任意单个字符(但请参见下文)。如果列表以^开头,则匹配任意在列表剩余部分中的单个字符。如果列表中的两个字符用-分隔,则表示排序序列中这两个字符之间的完整字符范围(包含两个端点);例如,ASCII中的[0-9]匹配任意十进制数字。两个范围共享一个端点是不合法的,例如a-c-e。范围高度依赖排序序列,因此可移植程序应避免依赖它们。 - 想在列表中包含文本],可以让它做列表的首字符(如果使用了^,需要放在其后)。 想在列表中包含文本-,可以让它做列表的首字符或者尾字符,或者一个范围的第二个端点。 想在列表中把文本-当做范围的起点, 把它用[..]包围起来,这样它就成为一个排序元素(见下文)。 除了这些字符本身、一些用[的组合(见下段)以及转义(只在 ARE 中有效)以外,所有其它特殊字符 在方括号表达式里都失去它们的特殊含义。特别是,在 ERE 和 BRE 规则下\不是特殊的, 但在 ARE 里,它是特殊的(引入一个转义)。 + 想在列表中包含字面字符],可以让它做列表的首字符(如果使用了^,需要放在其后)。 想在列表中包含字面字符-,可以让它做列表的首字符或者尾字符,或者一个范围的第二个端点。 想在列表中把字面字符-当做范围的起点, 把它用[..]包围起来,这样它就成为一个排序元素(见下文)。 除了这些字符本身、一些用[的组合(见下段)以及转义(只在 ARE 中有效)以外,所有其它特殊字符 在方括号表达式里都失去它们的特殊含义。特别是,在 ERE 和 BRE 规则下\不是特殊的, 但在 ARE 里,它是特殊的(引入一个转义)。 @@ -3532,30 +3538,11 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; - 在方括号表达式里,包围在[==]里的排序元素是一个等价类, 代表等效于那一个的所有排序元素的字符序列,包括它本身(如果没有其它等效排序元素,那么就好象封装定界符是[..])。例如,如果o^是一个等价类的成员,那么[[=o=]][[=^=]][o^]都是同义的。一个等价类不能是一个范围的端点。 + 在方括号表达式里,包围在[==]里的排序元素是一个等价类, 代表等效于那一个的所有排序元素的字符序列,包括它本身(如果没有其它等效排序元素,那么就好像封装定界符是[..])。例如,如果o^是一个等价类的成员,那么[[=o=]][[=^=]][o^]都是同义的。一个等价类不能是一个范围的端点。 - 在方括号表达式里,在[::]里面封装的字符类的名字代表属于该类的所有字符的列表。 - 字符类不能作为范围的端点使用。 - POSIX标准定义了这些字符类的名称: - alnum (字母和数字), - alpha (字母), - blank (空格和制表符tab), - cntrl (控制符), - digit (数字), - graph (空格除外可打印字符), - lower (小写字母), - print (包含空格可打印字符), - punct (标点符号), - space (空白), - upper (大写字母), - 和 xdigit (十六进制数). - 对于7位ASCII字符集中的字符来说,这些标准字符类的行为在不同平台上一般是一致的。 - 一个给定的非 ASCII 字符是否被认为属于这些类别中的一个,取决于正则表达式函数或操作符所使用的排序规则(见),或者在默认情况下取决于数据库的LC_CTYPE locale 设置(见)。 - 非ASCII字符的分类在不同的平台上会有不同的分类,即使是在类似命名的locale中也是如此。 - (但C locale从不认为任何非ASCII字符属于上述任何一类)。 - 除了这些标准字符类之外,PostgreSQL定义了ascii字符类,它完全包含7位ASCII字符集。 + 在方括号表达式中,用[::]括起来的字符类名称表示属于该类的所有字符。字符类不能作为范围的端点。POSIX标准定义了以下字符类名称:alnum(字母和数字)、alpha(字母)、blank(空格和制表符)、cntrl(控制字符)、digit(数字)、graph(空格以外的可打印字符)、lower(小写字母)、print(包括空格的可打印字符)、punct(标点符号)、space(任意空白字符)、upper(大写字母)和xdigit(十六进制数字)。对于 7 位 ASCII 字符集中的字符,这些标准字符类在各平台上的行为通常一致。给定的非 ASCII 字符是否属于其中某个类,取决于正则表达式函数或操作符使用的排序规则(参见),默认则取决于数据库的LC_CTYPE区域设置(参见)。即使区域设置名称相似,非 ASCII 字符的分类也可能因平台而异。(但C区域设置不会将任何非 ASCII 字符归入这些类。)除了这些标准字符类,PostgreSQL还定义了恰好包含 7 位 ASCII 字符集的ascii字符类。 @@ -3571,11 +3558,11 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; 正则表达式转义 - 转义是以\开头,后面跟着一个字母数字字符的特殊序列。 转义有好几种变体:字符输入转义、字符类简写转义、约束转义以及反向引用。在 ARE 里, 如果一个\后面跟着一个字母数字,但是并未组成一个合法的转义, 那么它是非法的。在 ERE 中没有转义:在方括号表达式之外,一个后面跟着字母数字字符的\只是表示该字符是一个普通的字符,而且在一个方括号表达式里,\是一个普通的字符(后者实际上在 ERE 和 ARE 不兼容)。 + 转义是以\开头,后面跟着一个字母或数字字符的特殊序列。 转义有好几种变体:字符输入转义、字符类简写转义、约束转义以及反向引用。在 ARE 里, 如果一个\后面跟着一个字母或数字,但是并未组成一个合法的转义, 那么它是非法的。在 ERE 中没有转义:在方括号表达式之外,一个后面跟着字母或数字字符的\只是表示该字符是一个普通的字符,而且在一个方括号表达式里,\是一个普通的字符(后者是 ERE 与 ARE 之间唯一的实际不兼容之处)。 - 字符输入转义用于便于我们在 RE 中声明那些不可打印的或其他习惯的字符。它们显示在中。 + 字符输入转义便于在 RE 中指定不可打印或其他不便输入的字符,见 @@ -3583,13 +3570,13 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; - 约束转义是一个约束,如果满足特定的条件,它匹配该空串。它们显示在中。 + 约束转义是以转义形式书写的约束,在满足特定条件时匹配空字符串,见 反向引用\n)匹配数字n指定的被前面的圆括号子表达式匹配的同一个串 (参阅)。 例如, ([bc])\1匹配bb或者cc, 但是不匹配bc或者cb。 - RE 中子表达式必须完全在反向引用前面。子表达式以它们的先导圆括号的顺序编号。 + RE 中子表达式必须完全在反向引用前面。子表达式以它们的左圆括号的顺序编号。 非捕获圆括号并不定义子表达式。 @@ -3629,7 +3616,7 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; \e - 排序序列名为ESC的字符,如果无法做到该字符为八进制值 033 + 排序序列名称为ESC的字符;若不存在这样的字符,则使用八进制值为033的字符 @@ -3639,7 +3626,7 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; \n - 新行,和 C 中一样 + 换行符,与 C 中相同 @@ -3793,7 +3780,7 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; \Y - 只在一个词的不是开头或末尾的点上匹配 + 只在不属于单词开头或末尾的位置匹配 @@ -3805,7 +3792,7 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo;
- 一个词被定义成在上面[[:<:]][[:>:]]中的声明。在方括号表达式里,约束转义是非法的。 + 单词的定义与上文[[:<:]][[:>:]]的说明相同。方括号表达式中不允许使用约束转义。 @@ -3825,12 +3812,12 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; \m - (其中m是一个非零位)一个到第m个子表达式的反向引用 + (其中m是一个非零数字)一个到第m个子表达式的反向引用 \mnn - (其中m是一个非零位,并且nn是一些更多的位,并且十六进制值mnn不超过目前能看到的封闭捕获圆括号的数目)一个到第mnn个子表达式的反向引用 + (其中m是一个非零数字,并且nn是后续的若干数字,并且十进制值mnn不大于此前已出现的捕获右圆括号数)一个到第mnn个子表达式的反向引用 @@ -3839,7 +3826,7 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; - 在八进制字符输入转义和反向引用之间有一个历史继承的歧义存在,这个歧义是 通过下面的启发式规则解决的,像上面描述地那样。前导零总是表示这是一个八进制转义。 而单个非零数字,如果没有跟着任何其它位,那么总是被认为反向引用。 一个多位的非零开头的序列也被认为是反向引用,只要它出现在合适的子表达式后面 (也就是说,在反向引用的合法范围中的数),否则就被认为是一个八进制。 + 八进制字符输入转义与反向引用之间存在固有歧义,按上文提到的启发式规则解决:前导零始终表示八进制转义。单个非零数字,如果后面没有其他数字,始终视为反向引用。不以零开头的多位数字序列,如果前面已有相应的子表达式(即该数字在反向引用的合法范围内),则视为反向引用,否则视为八进制转义。 @@ -3852,15 +3839,11 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; - RE 可以以两种特殊的引导前缀之一开头。 - 如果 RE 以***:开头,余下部分就被视为 ARE。 - (这在PostgreSQL中通常没有影响,因为 RE 默认被视为 ARE; - 但如果通过正则表达式函数的flags参数指定了 ERE 或 BRE 模式,它就会产生影响。) - 如果 RE 以***=开头,余下部分就被视为字面字符串,所有字符都被视为普通字符。 + RE 可以以两种特殊的引导前缀之一开头。如果 RE 以***:开头,余下部分就被视为 ARE。(这在PostgreSQL中通常没有影响,因为 RE 默认被视为 ARE;但如果通过正则表达式函数的flags参数指定了 ERE 或 BRE 模式,它就会产生影响。)如果 RE 以***=开头,余下部分就作为按字面解释的字符串处理,所有字符都视为普通字符。 - 一个 ARE 可以以嵌入选项开头:一个序列(?xyz)(这里的xyz是一个或多个字母字符)声明影响剩余 RE 的选项。 这些选项覆盖任何前面判断的选项 — 特别地,它们可以覆盖一个正则表达式操作符隐含的大小写敏感的行为,或者覆盖flags参数中的正则表达式函数。可用的选项字母在中显示。注意这些同样的选项字母也被用在正则表达式函数的flags参数中。 + 一个 ARE 可以以嵌入选项开头:一个序列(?xyz)(这里的xyz是一个或多个字母字符)声明影响剩余 RE 的选项。 这些选项覆盖任何先前确定的选项 — 特别地,它们可以覆盖一个正则表达式操作符隐含的大小写敏感的行为,或者覆盖正则表达式函数的flags参数所指定的选项。可用的选项字母在中显示。注意这些同样的选项字母也被用在正则表达式函数的flags参数中。
@@ -3905,32 +3888,32 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; n - 新行敏感的匹配(见 + 换行敏感的匹配(见 p - 部分新行敏感的匹配(见 + 部分换行敏感的匹配(见 q - RE的剩余部分是一个文字(quoted)串,全部是普通字符 + RE 的剩余部分按字面(加引号)解释,所有字符都视为普通字符 s - 非新行敏感的匹配(默认) + 非换行敏感的匹配(默认) t - 紧语法(默认,见下文) + 紧凑语法(默认;见下文) w - 逆部分新行敏感(怪异)的匹配(见 + 逆部分换行敏感(怪异)的匹配(见 @@ -3942,10 +3925,13 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo;
- 嵌入选项在)终止序列时发生作用。它们只在 ARE 的开始处起作用 (在任何可能存在的***:控制器后面)。 + 嵌入选项从结束该序列的)处开始生效。它们只能出现在 ARE 的开头(如果存在***:引导前缀,则位于该前缀之后)。 - 除了通常的()RE 语法(其中所有字符都有意义)之外,还有一种扩展语法,可以通过指定嵌入的x选项来使用。在扩展语法中,RE 中的空白字符会被忽略,同样被忽略的还有#与其后的换行符(或 RE 末尾)之间的所有字符。这使得复杂的 RE 可以分段并添加注释。此基本规则有三个例外: + + 除了通常的紧凑 RE 语法(其中所有字符都有意义)之外,还有一种扩展语法,可以通过指定嵌入的x选项来使用。在扩展语法中,RE 中的空白字符会被忽略,同样被忽略的还有#与其后的换行符(或 RE 末尾)之间的所有字符。这使得复杂的 RE 可以分段并添加注释。此基本规则有三个例外: + + 空白字符或 # 的前面若有 \,该字符就会被保留。 @@ -3959,13 +3945,16 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; 在多字符符号里面不能出现空白和注释,例如(?: - 在这里,空白字符包括空格、制表符、换行符,以及属于space字符类的任何字符。 + + + 在这里,空白字符包括空格、制表符、换行符,以及属于space字符类的任何字符。 +
- 最后,在 ARE 里,方括号表达式外面,序列(?#ttt)(其中ttt是任意不包含一个))的文本)是一个注释, 它被完全忽略。同样,这样的东西是不允许出现在多字符符号的字符中间的,例如 (?:。这种注释更像是一种历史产物而不是一种有用的设施,并且它们的使用已经被废弃;请使用扩展语法来替代。 + 最后,在 ARE 里,方括号表达式外面,序列(?#ttt)(其中ttt是任意不包含一个)的文本)是一个注释, 它被完全忽略。同样,这样的东西是不允许出现在多字符符号的字符中间的,例如 (?:。这种注释更像是一种历史产物而不是一种有用的设施,并且它们的使用已经被废弃;请使用扩展语法来替代。
- 如果声明了一个初始的***=控制器,那么所有这些元语法扩展都不能使用,因为这样表示把用户输入当作一个文字串而不是 RE 对待。 + 如果指定了开头的***=引导前缀,那么这些元语法扩展都不能使用,因为这表示把用户输入作为按字面解释的字符串,而非 RE 处理。 @@ -3981,7 +3970,7 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; - 大多数原子以及所有约束,都没有贪婪属性(因为它们毕竟无法匹配个数变化的文本)。 + 大多数原子以及所有约束,都没有贪婪属性(因为它们毕竟无法匹配长度不定的文本)。 @@ -4033,7 +4022,7 @@ SELECT SUBSTRING('XY1234Z', 'Y*?([0-9]{1,3})');
- 简而言之,如果一个 RE 同时包含贪婪和非贪婪的子表达式,那么总的匹配长度要么是尽可能长,要么是尽可能短,这取决于给整个 RE 赋予的属性。给子表达式赋予的属性只影响在这个匹配里,各个子表达式之间相互允许吃掉的多少。 + 简而言之,如果一个 RE 同时包含贪婪和非贪婪的子表达式,那么总的匹配长度要么是尽可能长,要么是尽可能短,这取决于给整个 RE 赋予的属性。给子表达式赋予的属性只影响在这个匹配里,各个子表达式相对于其他子表达式能吃掉多少内容。 @@ -4067,19 +4056,19 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 如果声明了大小写无关的匹配,那么效果就好像所有大小写区别在字母表中消失了。如果在多个情况中一个字母以一个普通字符的形式出现在方括号表达式外面,那么它实际上被转换成 一个包含大小写的方括号表达式,也就是说,x 变成 [xX]。 如果它出现在一个方括号表达式里面,那么它的所有大小写的同族都被加入 方括号表达式中,也就是说,x变成[xX]。当它出现在一个方括号表达式内时,它的所有大小写副本都被加入到方括号表达式中,例如, [x]会变成[xX],而[^x]会变成[^xX]。 + 如果指定不区分大小写的匹配,其效果近似于字母表中的所有大小写差别都消失了。当存在大小写形式的字母作为普通字符出现在方括号表达式之外时,实际上会转换为包含其大小写形式的方括号表达式,例如x变成[xX]。当它出现在方括号表达式内部时,其所有大小写形式都会加入该表达式,例如[x]变成[xX][^x]变成[^xX] - 如果指定了换行敏感的匹配,.和使用^的方括号表达式 将永远不会匹配换行字符(这样,匹配就不会跨越行,除非 RE 显式地包含了换行)并且^$除了分别匹配串开头和结尾之外,还将分别匹配换行后面和前面的空串。 + 如果指定了换行敏感的匹配,.和使用^的方括号表达式 将永远不会匹配换行字符(这样,匹配就不会跨越行,除非 RE 显式安排了跨行匹配)并且^$除了分别匹配串开头和结尾之外,还将分别匹配换行后面和前面的空串。 但是 ARE 转义\A\Z仍然匹配串的开头和结尾。 - 如果指定了部分新行敏感的匹配,那么它影响.和方括号表达式, 这个时候和新行敏感的匹配一样,但是不影响^$。 + 如果指定了部分换行敏感的匹配,那么它影响.和方括号表达式, 这个时候和换行敏感的匹配一样,但是不影响^$ - 如果指定了逆新行敏感匹配,那么它影响^$,其作用和在新行敏感的匹配里一样,但是不影响.和方括号表达式。这个并不是很有用,只是为了满足对称性而提供的。 + 如果指定了逆部分换行敏感匹配,那么它影响^$,其作用和在换行敏感的匹配里一样,但是不影响.和方括号表达式。这个并不是很有用,只是为了满足对称性而提供的。 @@ -4091,11 +4080,11 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}');
- ARE 实际上和 POSIX ERE 不兼容的唯一的特性是在方括号表达式里\并不失去它特殊的含义。所有其它 ARE 特性都使用在 POSIX ERE 里面是非法或者是未定义、未声明效果的语法;指示器的***就是在 POSIX 的 BRE 和 ERE 之外的语法。 + ARE 与 POSIX ERE 实际不兼容的唯一特性是:\在方括号表达式中不会失去特殊含义。其他所有 ARE 特性所使用的语法,在 POSIX ERE 中都是非法的,或其效果未定义或未指定;引导前缀的***语法同样不属于 POSIX 的 BRE 或 ERE 语法。 - 许多 ARE 扩展都是从 Perl 那里借来的(但是有些被做了修改来清理它们),以及一些 Perl 里没有出现的扩展。要注意的不兼容性包括\b\B、对结尾的新行缺乏特别的处理、对那些被新行敏感匹配的东西附加的补齐方括号表达式、在 lookahead/lookbehind 约束里对圆括号和反向引用的限制以及最长/最短 匹配(而不是第一匹配)的语义。 + 许多 ARE 扩展借鉴自 Perl,但其中一些经过了整理和修改,也未实现少数 Perl 扩展。需要注意的不兼容之处包括\b\B、不对末尾换行符作特殊处理、取反的方括号表达式也受换行敏感匹配影响、先行和后行约束中对圆括号及反向引用的限制,以及采用最长或最短匹配而非首次匹配的语义。 ARE 与旧版 ERE 语法存在两点重要的不兼容,这里比较的是 7.4 之前的PostgreSQL: @@ -4116,7 +4105,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 基本正则表达式 - BREs 在几个方面和 ERE 不太一样。在 BRE 中,|+?都是普通字符并且没有与它们功能等价的东西。范围的定界符是\{\}, 因为 {}本身是普通字符。嵌套的子表达式的圆括号是\(\),因为()自身是普通字符。除非在 RE 开头或者是圆括号子表达式开头,^都是一个普通字符。 除非在 RE 结尾或者是圆括号子表达式的结尾,$是一个普通字符。如果*出现在 RE 开头或者是圆括号封装的子表达式开头 (前面可能有^),那么它是个普通字符。最后,可以用单数字的反向引用,\<\>分别是[[:<:]][[:>:]]的同义词;在 BRE 中没有其它可用的转义。 + BRE 在几个方面和 ERE 不太一样。在 BRE 中,|+?都是普通字符并且没有与它们功能等价的东西。范围的定界符是\{\},而{}本身是普通字符。嵌套的子表达式的圆括号是\(\),而()自身是普通字符。除非在 RE 开头或者是圆括号子表达式开头,^都是一个普通字符。 除非在 RE 结尾或者是圆括号子表达式的结尾,$是一个普通字符。如果*出现在 RE 开头或者是圆括号封装的子表达式开头 (前面可能有^),那么它是个普通字符。最后,可以用单数字的反向引用,\<\>分别是[[:<:]][[:>:]]的同义词;在 BRE 中没有其它可用的转义。 @@ -4146,15 +4135,12 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 使用\p{UnicodeProperty}或其反义\P{UnicodeProperty}来定义XQuery字符类元素是不被支持的。 + 使用\p{UnicodeProperty}或其取反形式\P{UnicodeProperty}来定义XQuery字符类元素是不被支持的。 - POSIX解释字符类,如\w - (参见) - 根据当前区域设置(你可以通过将COLLATE子句附加到操作符或函数上来控制)。 - XQuery通过参考Unicode字符属性来指定这些类别,因此只有遵循Unicode规则的区域设置才能获得等效行为。 + POSIX 根据当前区域设置解释\w等字符类(参见);你可以通过为操作符或函数附加COLLATE子句来控制该区域设置。XQuery 根据 Unicode 字符属性定义这些类,因此只有使用遵循 Unicode 规则的区域设置时,才能得到等效行为。 @@ -4173,7 +4159,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - XQuery没有前瞻或后顾约束,也没有在中描述的任何约束转义。 + XQuery没有先行或后行约束,也没有在中描述的任何约束转义。 @@ -4187,7 +4173,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); XQuery的s(允许点匹配换行符) 和m(允许^ - 和$匹配换行符)标志提供 + 和$在换行处匹配)标志提供 与POSIX的npw标志相同的行为,但它们 匹配POSIX的sm标志的行为。 @@ -4218,11 +4204,11 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 数据类型格式化函数 - formatting + 格式化 - PostgreSQL格式化函数提供一套强大的工具用于把各种数据类型 (日期/时间、整数、浮点、数字) 转换成格式化的字符串以及反过来从格式化的字符串转换成 指定的数据类型。列出了这些函数。这些函数都遵循一个公共的调用规范: 第一个参数是待格式化的值,而第二个是一个定义输出或输入格式的模板。 + PostgreSQL格式化函数提供一套强大的工具用于把各种数据类型 (日期/时间、整数、浮点数、数值) 转换成格式化的字符串以及反过来从格式化的字符串转换成 指定的数据类型。列出了这些函数。这些函数都遵循一个公共的调用规范: 第一个参数是待格式化的值,而第二个是一个定义输出或输入格式的模板。 @@ -4306,7 +4292,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 展示了可以用于格式化日期和时间值的模版。 + 展示了可以用于格式化日期和时间值的模板模式。
@@ -4354,17 +4340,17 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); AM, am, - PM or pm - 正午指示器(不带句号) + PMpm + 上午/下午标记(不带句点) A.M., a.m., - P.M. or p.m. - 正午指示器(带句号) + P.M.p.m. + 上午/下午标记(带句点) Y,YYY - 带逗号的年(4 位或者更多位) with comma + 带逗号的年(4 位或者更多位) YYYY @@ -4410,15 +4396,15 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); MONTH - 全大写形式的月名(空格补齐到 9 字符) + 大写的月份全称(空格补齐到 9 字符) Month - 全首字母大写形式的月名(空格补齐到 9 字符) + 首字母大写的月份全称(空格补齐到 9 字符) month - 全小写形式的月名(空格补齐到 9 字符) + 小写的月份全称(空格补齐到 9 字符) MON @@ -4434,31 +4420,31 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); MM - 月份数(01-12) + 月份编号(01-12) DAY - 全大写形式的日名(空格补齐到 9 字符) + 大写的星期全称(空格补齐到 9 字符) Day - 全首字母大写形式的日名(空格补齐到 9 字符) + 首字母大写的星期全称(空格补齐到 9 字符) day - 全小写形式的日名(空格补齐到 9 字符) + 小写的星期全称(空格补齐到 9 字符) DY - 简写的大写形式的日名(英语 3 字符,本地化长度可变) + 大写的星期简称(英语 3 字符,本地化长度可变) Dy - 简写的首字母大写形式的日名(英语 3 字符,本地化长度可变) + 首字母大写的星期简称(英语 3 字符,本地化长度可变) dy - 简写的小写形式的日名(英语 3 字符,本地化长度可变) + 小写的星期简称(英语 3 字符,本地化长度可变) DDD @@ -4470,19 +4456,19 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); DD - 一月中的第几天(01-31) + 月内日序数(01-31) D - 周中的日,周日 (1) 到周六 (7) + 星期几,周日 (1) 到周六 (7) ID - 周中的 ISO 8601 日,周一 (1) 到周日 (7) + ISO 8601 星期几,周一 (1) 到周日 (7) W - 一月中的第几周(1-5)(第一周从该月第一天开始) + 月内周序数(1-5)(第一周从该月第一天开始) WW @@ -4530,55 +4516,55 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); OF - 从UTC开始的时区偏移(仅在to_char中支持) + 相对于 UTC 的时区偏移(仅在to_char中支持)
- 修饰语可以被应用于模板模式来修改它们的行为。例如,FMMonth就是带着FM修饰语的Month模式。展示了可用于日期/时间格式化的修饰语模式。 + 修饰符可以被应用于模板模式来修改它们的行为。例如,FMMonth就是带着FM修饰符的Month模式。展示了可用于日期/时间格式化的修饰符模式。 - 用于日期/时间格式化的模板模式修饰语 + 用于日期/时间格式化的模板模式修饰符 - 修饰语 + 修饰符 描述 示例 - FM prefix + FM 前缀 填充模式(抑制前导零和填充的空格) FMMonth - TH suffix + TH 后缀 大写形式的序数后缀 - DDTH, e.g., 12TH + DDTH,例如, 12TH - th suffix + th 后缀 小写形式的序数后缀 - DDth, e.g., 12th + DDth,例如, 12th - FX prefix - 固定的格式化全局选项(见使用须知) + FX 前缀 + 固定格式全局选项(见使用须知) FX Month DD Day - TM prefix + TM 前缀 翻译模式(根据 输出本地化的星期名和月份名) TMMonth - SP suffix + SP 后缀 拼写模式(未实现) DDSP @@ -4586,14 +4572,14 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}');
- 日期/时间格式化的使用说明: + 日期/时间格式化的使用注意事项: FM抑制了在模式输出中添加前导零和尾随空格的行为,这些前导零和尾随空格 本来会被添加以使输出成为固定宽度。在PostgreSQL中, - FM仅修改下一个规范,而在Oracle中FM影响所有后续 - 规范,并且重复的FM修饰符切换填充模式的开启和关闭。 + FM仅修改下一个格式说明,而在Oracle中FM影响所有后续 + 格式说明,并且重复的FM修饰符切换填充模式的开启和关闭。 @@ -4639,10 +4625,10 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 一个TZH模板模式可以匹配有符号数。 - 没有FX选项,减号可能会有歧义,并且可能被解释为分隔符。 - 此歧义解决如下:如果模板字符串中TZH之前的分隔符数量少于输入字符串中减号之前的分隔符数量, - 则减号被解释为TZH的一部分。 - 否则,减号被视为值之间的分隔符。 + 没有FX选项,负号可能会有歧义,并且可能被解释为分隔符。 + 此歧义解决如下:如果模板字符串中TZH之前的分隔符数量少于输入字符串中负号之前的分隔符数量, + 则负号被解释为TZH的一部分。 + 否则,负号被视为值之间的分隔符。 例如,to_timestamp('2000 -10', 'YYYY TZH')匹配 -10TZH,但 to_timestamp('2000 -10', 'YYYY  TZH') @@ -4653,12 +4639,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 普通文本允许在to_char模板中,并且将被直接输出。您可以将子字符串放在双引号中, - 以强制将其解释为文字文本,即使它包含模板模式。例如,在'"Hello Year "YYYY'中, - YYYY将被年份数据替换,但Year中的单个Y不会被替换。 - 在to_dateto_numberto_timestamp中, - 文本和双引号字符串会导致跳过字符串中包含的字符数;例如"XX"跳过两个输入字符 - (无论它们是否为XX)。 + 普通文本可以出现在to_char模板中,并会按字面输出。可以用双引号括起子串,使其即使包含模式关键字也强制按字面文本解释。例如,在'"Hello Year "YYYY'中,YYYY会被年份数据替换,但Year中单独的Y不会被替换。在to_dateto_numberto_timestamp中,字面文本和双引号字符串会跳过与该字符串所含字符数相同数量的输入字符;例如,"XX"跳过两个输入字符(无论它们是否为XX)。 @@ -4677,7 +4658,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 如果您想在输出中使用双引号,必须在其前面加上反斜杠,例如'\"YYYY Month\"' - 反斜杠在双引号之外不起特殊作用。在双引号字符串内部,反斜杠会使下一个字符被直接解释,无论是什么(但除非下一个字符是双引号或另一个反斜杠,否则没有特殊效果)。 + 反斜杠在双引号之外不起特殊作用。在双引号字符串内部,反斜杠会使下一个字符被按字面解释,无论是什么(但除非下一个字符是双引号或另一个反斜杠,否则没有特殊效果)。 @@ -4740,14 +4721,14 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 年份、周数和星期几:例如to_date('2006-42-4', 'IYYY-IW-ID') + 年份、周编号和星期几:例如to_date('2006-42-4', 'IYYY-IW-ID') 返回日期2006-10-19。 如果省略星期几,则假定为1(星期一)。 - 年份和年内天数:例如to_date('2006-291', 'IYYY-IDDD')也返回2006-10-19。 + 年份和年内日序数:例如to_date('2006-291', 'IYYY-IDDD')也返回2006-10-19 @@ -4755,14 +4736,14 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 尝试使用ISO 8601周编号字段和公历日期字段的混合输入日期是荒谬的,并将导致错误。 - 在ISO 8601周编号年的背景下,月份日期的概念没有意义。 + 在ISO 8601周编号年的背景下,月份月内日序数的概念没有意义。 在公历年的背景下,ISO周没有意义。 - 当to_date拒绝混合使用公历和ISO周编号日期字段时, - to_char不会,因为输出格式规范如YYYY-MM-DD (IYYY-IDDD)可能很有用。 + 虽然to_date会拒绝混合使用公历和ISO周编号日期字段, + 但to_char不会,因为输出格式规范如YYYY-MM-DD (IYYY-IDDD)可能很有用。 但要避免编写类似IYYY-MM-DD的内容;那会在年初附近产生令人惊讶的结果。 (有关更多信息,请参见。) @@ -4781,7 +4762,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 这是一个更复杂的示例: to_timestamp('15:12:02.020.001230', 'HH24:MI:SS.MS.US') - 是15小时,12分钟和2秒 + 20毫秒 + 1230微秒 = 2.021230秒。 + 为15小时12分钟,秒数为2秒 + 20毫秒 + 1230微秒 = 2.021230秒。
@@ -4789,7 +4770,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); to_char(..., 'ID')的星期几编号与extract(isodow from ...)函数匹配, - 但to_char(..., 'D')的不匹配extract(dow from ...)的星期编号。 + 但to_char(..., 'D')的不匹配extract(dow from ...)的星期几编号。 @@ -4806,12 +4787,12 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}');
- 展示了可以用于格式化数字值的模版模式。 + 展示了可以用于格式化数值的模板模式。 - 用于数字格式化的模板模式 + 用于数值格式化的模板模式 @@ -4824,21 +4805,21 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 9 - 数位(如果无意义可以被删除) + 数位(非有效位可以被省略) 0 - 数位(即便没有意义也不会被删除) + 数位(即便是非有效位也不会被省略) - . (period) + .(句点) 小数点 - , (comma) + ,(逗号) 分组(千)分隔符 @@ -4849,22 +4830,22 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); S - 带符号的数字(使用区域) + 紧贴数值的正负号(使用区域设置) L - 货币符号(使用区域) + 货币符号(使用区域设置) D - 小数点(使用区域) + 小数点(使用区域设置) G - 分组分隔符(使用区域) + 分组分隔符(使用区域设置) @@ -4888,7 +4869,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - TH or th + THth 序数后缀 @@ -4905,7 +4886,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}');
- 数值格式化的使用说明: + 数值格式化的使用注意事项: @@ -4919,14 +4900,14 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 如果格式提供的小数位数少于被格式化的数字,则to_char()将会将数字四舍五入到指定的小数位数。 + 如果格式指定的小数位数少于被格式化数值的小数位数,to_char()会将该数值舍入到指定的小数位数。 - 模式字符SLDG表示当前区域设置定义的符号、货币符号、小数点和千位分隔符字符 + 模式字符SLDG表示当前区域设置定义的正负号、货币符号、小数点和千位分隔符字符 (参见)。模式字符句点和逗号表示这些确切字符,具有小数点和千位分隔符的含义,不受区域设置影响。 @@ -4935,15 +4916,14 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 如果在to_char()的模式中没有明确指定符号,将为符号保留一列,并将其锚定到(出现在)数字的左侧。 - 如果S出现在一些9的左侧,它也将锚定到数字。 + 如果to_char()的模式中没有明确指定正负号的位置,就会为正负号保留一列,并使其紧贴数值(紧靠数值左侧)。如果S紧邻若干个9的左侧,它同样会紧贴数值。 - 使用SGPLMI格式化的符号不与数字绑定; + 使用SGPLMI格式化的正负号不紧贴数值; 例如,to_char(-12, 'MI9999')会产生'-  12', 但to_char(-12, 'S9999')会产生'  -12'。 (Oracle实现不允许在9之前使用MI,而是要求9MI之前。) @@ -4970,7 +4950,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); to_number函数中,如果使用非数据模板模式,如LTH, - 则会跳过相应数量的输入字符,无论它们是否与模板模式匹配,除非它们是数据字符(即数字、符号、小数点或逗号)。 + 则会跳过相应数量的输入字符,无论它们是否与模板模式匹配,除非它们是数据字符(即数字、正负号、小数点或逗号)。 例如,TH会跳过两个非数据字符。 @@ -4981,7 +4961,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); Vto_char一起, 将输入值乘以10^n, 其中n是跟在V后面的数字位数。 - Vto_number一起以类似的方式除法。 + Vto_number一起以类似的方式进行除法。 to_charto_number不支持与小数点结合使用的V (例如,不允许使用99.9V99)。 @@ -4997,17 +4977,17 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 某些修饰语可以被应用到任何模板来改变其行为。例如,FM99.99是带有FM修饰语的99.99模式。中展示了用于数字格式化模式修饰语。 + 某些修饰符可以被应用到任何模板来改变其行为。例如,FM99.99是带有FM修饰符的99.99模式。中展示了用于数值格式化的模式修饰符。 - 用于数字格式化的模板模式修饰语 + 用于数值格式化的模板模式修饰符 - 修饰语 + 修饰符 描述 示例 @@ -5015,19 +4995,19 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - FM prefix - 填充模式(抑制拖尾零和填充的空白) + FM 前缀 + 填充模式(抑制尾随零和填充的空白) FM99.99 - TH suffix + TH 后缀 大写序数后缀 999TH - th suffix + th 后缀 小写序数后缀 999th @@ -5211,10 +5191,10 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 时间/日期函数和操作符 + 日期/时间函数和操作符 - 展示了可用于处理日期/时间值的函数,其细节在随后的小节中描述。演示了基本算术操作符 (+*等)的行为。 而与格式化相关的函数,可以参考。你应该很熟悉中的日期/时间数据类型的背景知识。 + 展示了可用于处理日期/时间值的函数,其细节在随后的小节中描述。演示了基本算术操作符 (+*等)的行为。 而与格式化相关的函数,可以参考。你应当熟悉中的日期/时间数据类型的背景知识。 @@ -5378,7 +5358,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); age age(timestamp, timestamp) interval - 减去参数,生成一个使用年和月,而不是只用日的符号化的结果 + 将两个参数相减,生成一个使用年和月,而不是只用日的符号化的结果 age(timestamp '2001-04-10', timestamp '1957-06-13') 43 years 9 mons 27 days @@ -5494,7 +5474,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); isfinite isfinite(date) boolean - 测试有限日期(不是+/-无限) + 测试日期是否有限(不是正负无穷) isfinite(date '2001-02-16') true @@ -5536,7 +5516,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); justify_interval justify_interval(interval) interval - 使用 justify_daysjustify_hours调整时间间隔; 通过额外的符号调整 + 使用 justify_daysjustify_hours调整时间间隔,并额外调整符号 justify_interval(interval '1 mon -1 hour') 29 days 23:00:00 @@ -5616,7 +5596,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); statement_timestamp statement_timestamp() timestamp with time zone - 当前日期和时间(当前语句的开始);参见 + 当前日期和时间(当前语句开始时);参见 @@ -5660,7 +5640,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); (start1, end1) OVERLAPS (start2, end2) (start1, length1) OVERLAPS (start2, length2) - 这个表达式在两个时间域(用它们的端点定义)重叠的时候得到真,当它们不重叠时得到假。端点可以用一对日期、时间或者时间戳来指定;或者是用一个后面跟着一个间隔的日期、时间或时间戳来指定。当一对值被提供时,起点或终点都可以被写在前面,OVERLAPS会自动地把较早的值作为起点。每一个时间段被认为是表示半开的间隔start <= time < end,除非startend相等,这种情况下它表示单个时间实例。例如这表示两个只有一个共同端点的时间段不重叠。 + 这个表达式在两个时间段(用它们的端点定义)重叠的时候得到真,当它们不重叠时得到假。端点可以用一对日期、时间或者时间戳来指定;或者是用一个后面跟着一个间隔的日期、时间或时间戳来指定。当一对值被提供时,起点或终点都可以被写在前面,OVERLAPS会自动地把较早的值作为起点。每一个时间段被认为是表示半开区间start <= time < end,除非startend相等,这种情况下它表示单个时刻。例如这表示两个只有一个共同端点的时间段不重叠。 @@ -5692,15 +5672,9 @@ SELECT timestamp with time zone '2005-04-02 12:00:00-07' + interval '24 hours'; - 日期和时间戳的减法也可能会很复杂。执行减法的一种概念上很简单的方法是,使用 - EXTRACT(EPOCH FROM ...)把每个值都转换成秒数,然后执行减法, - 这样会得到两个值之间的数。这种方法将会适应每个月中天数、 - 时区改变和夏令时调整。使用-操作符的日期或时间 - 戳减法会返回值之间的天数(24小时)以及时/分/秒,也会做同样的调整。 - age函数会返回年、月、日以及时/分/秒,执行按域的减法,然后对 - 负值域进行调整。下面的查询展示了这些方法的不同。示例中的结果由 - timezone = 'US/Eastern'产生,这使得两个使用的日期之间存在着夏令 - 时的变化: + 日期和时间戳的减法也可能很复杂。一种概念上简单的方法是,先用EXTRACT(EPOCH FROM ...)将各值转换为秒数,然后将结果相减;这样得到的是两个值之间的数。这种方法会针对每个月的天数、时区变化和夏令时变化进行调整。 + 用-操作符将日期或时间戳值相减,会返回两个值之间的天数(每一天为 24 小时)和时/分/秒,也会作相同的调整。age函数返回年、月、日和时/分/秒,它会逐字段相减,然后调整负值字段。 + 以下查询显示了这些方法的差异。示例结果在timezone = 'US/Eastern'设置下产生;所用的两个日期之间发生了夏令时切换: @@ -5816,7 +5790,7 @@ SELECT EXTRACT(DOY FROM TIMESTAMP '2001-02-16 20:38:40'); epoch - 对于timestamp with time zone值,自1970-01-01 00:00:00 UTC以来的秒数(负值表示该时间戳之前的时间); + 对于timestamp with time zone值,自1970-01-01 00:00:00 UTC以来的秒数(早于该时刻的时间戳对应负值); 对于datetimestamp值,自1970-01-01 00:00:00以来的名义秒数,不考虑时区或夏令时规则; 对于interval值,间隔中的总秒数 @@ -5839,8 +5813,8 @@ SELECT to_timestamp(982384720.12); - 注意,将to_timestamp应用于从datetimestamp值中提取的时代可能会产生误导性的结果: - 结果将有效地假定原始值是以UTC时间给出的,这可能并非事实。 + 注意,将to_timestamp应用于从datetimestamp值中提取的 epoch 值可能会产生误导性的结果: + 结果实际上会假定原始值是以UTC时间给出的,这可能并非事实。 @@ -5941,7 +5915,7 @@ SELECT EXTRACT(MILLENNIUM FROM TIMESTAMP '2001-02-16 20:38:40'); milliseconds - 第二个字段,包括小数部分,乘以1000。请注意,这包括完整的秒数。 + 秒字段,包括小数部分,乘以1000。请注意,这包括完整的秒数。 @@ -6020,7 +5994,7 @@ SELECT EXTRACT(SECOND FROM TIME '17:12:28.5'); - 时间区偏移的小时组件 + 时区偏移的小时部分 @@ -6030,7 +6004,7 @@ SELECT EXTRACT(SECOND FROM TIME '17:12:28.5'); - 时间区偏移的分钟组件 + 时区偏移的分钟部分 @@ -6040,16 +6014,11 @@ SELECT EXTRACT(SECOND FROM TIME '17:12:28.5'); - 一年中ISO 8601周编号周的数量。根据定义,ISO周从周一开始, - 一年的第一周包含该年的1月4日。换句话说,一年的第一个星期四在该年的第1周。 + 一年中按ISO 8601 周编号体系计算的周序号。根据定义,ISO 周从周一开始,一年的第一周包含该年的 1 月 4 日。换句话说,一年的第一个星期四在该年的第 1 周。 - 在ISO周编号系统中,早年1月的日期可能属于前一年的第52周或第53周,而 - 晚年12月的日期可能属于下一年的第一周。例如,2005-01-01 - 属于2004年的第53周,2006-01-01 属于2005年的第52周, - 而2012-12-31 属于2013年的第一周。建议同时使用 - isoyear 字段和week以获得一致的结果。 + 在 ISO 周编号体系中,1 月初的日期可能属于前一年的第 52 周或第 53 周,而 12 月末的日期可能属于下一年的第一周。例如,2005-01-01属于 2004 年的第 53 周,2006-01-01属于 2005 年的第 52 周,而2012-12-31属于 2013 年的第一周。建议将isoyear字段与week一起使用,以获得一致的结果。 @@ -6064,7 +6033,7 @@ SELECT EXTRACT(WEEK FROM TIMESTAMP '2001-02-16 20:38:40'); - 年份字段。请记住,没有0 AD,所以要小心地从AD年中减去BC年。 + 年份字段。请记住,没有0 AD,所以把BC年份从AD年份中减去时需要小心。 @@ -6080,7 +6049,7 @@ SELECT EXTRACT(YEAR FROM TIMESTAMP '2001-02-16 20:38:40'); - 当输入值为 +/-Infinity 时,extract对于单调增的域(epochjulianyearisoyeardecadecentury以及millennium)返回 +/-Infinity。对于其他域返回 NULL。PostgreSQL 9.6 之前的版本对所有输入无穷的情况都返回零。 + 当输入值为 +/-Infinity 时,extract对于单调递增的字段(epochjulianyearisoyeardecadecentury以及millennium)返回 +/-Infinity。对于其他字段返回 NULL。PostgreSQL 9.6 之前的版本对所有输入无穷的情况都返回零。 @@ -6088,10 +6057,11 @@ SELECT EXTRACT(YEAR FROM TIMESTAMP '2001-02-16 20:38:40'); extract函数主要的用途是做计算性处理。对于用于显示的日期/时间值格式化,参阅。 - date_part函数仿照传统的Ingres实现,后者等价于SQL标准函数extract: + date_part函数仿照传统的Ingres实现,后者对应SQL标准的extract函数: date_part('field', source) -注意,此处的field参数必须是字符串值,而不能是名称。函数date_part的有效字段名与以下函数相同:extract。 + + 注意,此处的field参数必须是字符串值,而不能是名称。date_part的有效字段名与extract相同。 @@ -6118,10 +6088,11 @@ SELECT date_part('hour', INTERVAL '4 hours 3 minutes'); date_trunc(field, source [, time_zone ]) - sourcetimestamptimestamp with time zone,或interval类型的值表达式。(类型为datetime的值会自动转换为timestampinterval,分别对应这两种输入类型。)field选择输入值的截断精度。返回值同样为以下类型:timestamptimestamp with time zone,或interval,其中所有小于所选精度的字段都设为零(日期和月份则设为一)。 + sourcetimestamptimestamp with time zoneinterval类型的值表达式。(datetime类型的值会分别自动转换为timestampinterval。) + field选择输入值的截断精度。返回值同样为timestamptimestamp with time zoneinterval类型,其中低于所选精度的所有字段都设为零(日和月则设为一)。 - field的有效值是∶ + field的有效值是: microseconds milliseconds @@ -6140,7 +6111,7 @@ date_trunc(field, source [ - 当输入值的类型为timestamp with time zone时。截断是针对特定时区进行的。 例如,截断为day,产生的值是 是该区域的午夜。 默认情况下,截断是在以下方面进行的 到当前的设置,但在当前的 可以提供可选的time_zone参数。以指定不同的时区。 可以指定时区名称 中描述的任何一种方式。 + 当输入值为timestamp with time zone类型时,截断会以特定时区为准;例如,截断到day会得到该时区的午夜。默认情况下,截断以当前的设置为准,但可以通过可选的time_zone参数指定其他时区。时区名称可以用中描述的任意方式指定。 @@ -6167,8 +6138,8 @@ SELECT date_trunc('hour', INTERVAL '3 days 02:47:33'); <literal>AT TIME ZONE</literal> - time zone - conversion + 时区 + 转换 @@ -6228,7 +6199,7 @@ SELECT TIMESTAMP '2001-02-16 20:38:40-05' AT TIME ZONE 'Asia/Tokyo' AT TIME ZONE 第一个示例为不带时区的值添加时区,并使用当前TimeZone设置显示该值。第二个示例将带时区的时间戳值移到指定时区,并返回不带时区的值。这样就可以存储和显示与当前TimeZone设置不同的值。第三个示例将东京时间转换为芝加哥时间。将time值转换到其他时区时,由于没有提供日期,会使用当前生效的时区规则。 - 函数timezone(zone, timestamp)等效于 SQL 兼容的结构timestamp AT TIME ZONE zone。 + 函数timezone(zone, timestamp)等效于符合 SQL 标准的结构timestamp AT TIME ZONE zone @@ -6236,13 +6207,13 @@ SELECT TIMESTAMP '2001-02-16 20:38:40-05' AT TIME ZONE 'Asia/Tokyo' AT TIME ZONE 当前日期/时间 - date - current + 日期 + 当前 - time - current + 时间 + 当前 @@ -6261,11 +6232,11 @@ LOCALTIMESTAMP(precision) - CURRENT_TIMECURRENT_TIMESTAMP传递带有时区的值;LOCALTIMELOCALTIMESTAMP传递的值不带时区。 + CURRENT_TIMECURRENT_TIMESTAMP返回带时区的值;LOCALTIMELOCALTIMESTAMP返回不带时区的值。 - CURRENT_TIMECURRENT_TIMESTAMPLOCALTIMELOCALTIMESTAMP可以有选择地接受一个精度参数,该精度会使结果的秒字段圆整到指定的小数位数。如果没有精度参数,结果将给出可用的全部精度。 + CURRENT_TIMECURRENT_TIMESTAMPLOCALTIMELOCALTIMESTAMP可以有选择地接受一个精度参数,该精度会使结果的秒字段舍入到指定的小数位数。如果没有精度参数,结果将给出可用的全部精度。 下面是一些示例: @@ -6289,7 +6260,7 @@ SELECT LOCALTIMESTAMP; - 许多其它数据库系统可能会更频繁地推进这些值。 + 其他数据库系统可能会更频繁地推进这些值。 @@ -6306,13 +6277,15 @@ now() - transaction_timestamp()等价于CURRENT_TIMESTAMP,但是其命名清楚地反映了它的返回值。statement_timestamp()返回当前语句的开始时刻(更准确的说是收到 客户端最后一条命令的时间)。statement_timestamp()transaction_timestamp()在一个事务的第一条命令期间返回值相同,但是在随后的命令中却不一定相同。 clock_timestamp()返回真正的当前时间,因此它的值甚至在同一条 SQL 命令中都会变化。timeofday()是一个有历史原因的PostgreSQL函数。和clock_timestamp()相似,它也返回真实的当前时间,但是它的结果是一个格式化的text串,而不是timestamp with time zone值。now()PostgreSQL的一个传统,等效于transaction_timestamp()。 + transaction_timestamp()等价于CURRENT_TIMESTAMP,但是其命名清楚地反映了它的返回值。statement_timestamp()返回当前语句的开始时刻(更准确地说,是接收到客户端最近一条命令消息的时间)。statement_timestamp()transaction_timestamp()在一个事务的第一条命令期间返回值相同,但是在随后的命令中却不一定相同。 clock_timestamp()返回真正的当前时间,因此它的值甚至在同一条 SQL 命令中都会变化。timeofday()是一个有历史原因的PostgreSQL函数。和clock_timestamp()相似,它也返回真实的当前时间,但是它的结果是一个格式化的text串,而不是timestamp with time zone值。now()PostgreSQL中与transaction_timestamp()等价的传统函数。 - 所有日期/时间数据类型也都接受特殊字面值now来指定当前日期和时间(同样解释为事务开始时间)。因此,下面三种写法都返回相同的结果: + + 所有日期/时间数据类型也都接受特殊字面值now来指定当前日期和时间(同样解释为事务开始时间)。因此,下面三种写法都返回相同的结果: + SELECT CURRENT_TIMESTAMP; SELECT now(); -SELECT TIMESTAMP 'now'; -- but see tip below +SELECT TIMESTAMP 'now'; -- 但请参阅下面的提示 @@ -6320,7 +6293,7 @@ SELECT TIMESTAMP 'now'; -- but see tip below 当指定以后要计算的值时,不要使用第三种形式,例如在表列的DEFAULT子句中。 - 系统将在分析这个常量的时候把now转换为一个timestamp, 这样需要默认值时就会得到创建表的时间!而前两种形式要到实际使用缺省值的时候才被计算, 因为它们是函数调用。因此它们可以给出每次插入行的时刻。 + 系统将在分析这个常量的时候把now转换为一个timestamp, 这样需要默认值时就会得到创建表的时间!而前两种形式要到实际使用默认值的时候才被计算, 因为它们是函数调用。因此它们可以给出每次插入行的时刻。 (参见 。) @@ -6339,10 +6312,10 @@ SELECT TIMESTAMP 'now'; -- but see tip below pg_sleep_until - sleep + 休眠 - delay + 延迟 以下函数可用于延迟服务器进程的执行: @@ -6385,7 +6358,7 @@ SELECT pg_sleep_until('tomorrow 03:00'); 枚举支持函数 - 对于枚举类型(在中描述), 有一些函数允许更清洁的编码,而不需要为一个枚举类型硬写特定的值。它们被列在中。本例假定一个枚举类型被创建为: + 对于枚举类型(见),有些函数可以避免硬编码枚举类型中的特定值,使程序更简洁。这些函数列在中。以下示例假定枚举类型按如下方式创建: CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple'); @@ -6432,8 +6405,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple enum_range(anyenum, anyenum) - 以一个数组返回在给定两个枚举值之间的范围。值必须来自相同的枚举类型。 - 如果第一个参数为空,其结果将从枚举类型的第一个值开始。如果第二参数为空,其结果将以枚举类型的最后一个值结束。 + 以有序数组返回两个给定枚举值之间的范围。两个值必须来自同一枚举类型。如果第一个参数为 null,结果从该枚举类型的第一个值开始;如果第二个参数为 null,结果以该枚举类型的最后一个值结束。 enum_range('orange'::rainbow, 'green'::rainbow) {orange,yellow,green} @@ -6451,8 +6423,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple
- 请注意,除了双参数形式的enum_range外, 这些函数忽略传递给它们的具体值,它们只关心声明的数据类型。 - 空值或类型的一个特定值可以通过,并得到相同的结果。这些函数更多地被用于一个表列或函数参数,而不是一个硬写的类型名,如示例中所使用。 + 请注意,除了enum_range的双参数形式外,这些函数都忽略传入的具体值,只关心其声明的数据类型。传入 null 或该类型的某个具体值,结果都相同。通常会将这些函数用于表列或函数参数,而不是像示例那样使用硬编码的类型名。 @@ -6462,7 +6433,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple 几何类型pointboxlseglinepath、 - polygoncircle有一大堆本地支持函数和操作符,如中所示。 + polygoncircle有大量内置支持函数和操作符,如中所示。 @@ -6502,7 +6473,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple
# - 相交的点或盒子 + 相交的点或矩形框 box '((1,-1),(-1,1))' # box '((1,1),(-2,-2))' @@ -6612,7 +6583,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple ?-| - 是否垂直? + 是否互相垂直? lseg '((0,0),(0,1))' ?-| lseg '((0,0),(1,0))' @@ -6695,13 +6666,13 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple area(object) double precision - area + 面积 area(box '((0,0),(1,1))') center(object) point - center + 中心 center(box '((0,0),(1,2))') @@ -6713,7 +6684,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple height(box) double precision - 盒子的竖直尺寸 + 矩形框的竖直尺寸 height(box '((0,0),(1,1))') @@ -6731,7 +6702,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple length(object) double precision - length + 长度 length(path '((-1,0),(1,0))') @@ -6767,7 +6738,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple width(box) double precision - 盒子的水平尺寸 + 矩形框的水平尺寸 width(box '((0,0),(1,1))') @@ -6789,37 +6760,37 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple box box(circle) box - 将圆转换为盒子 + 将圆转换为矩形框 box(circle '((0,0),2.0)') box(point) box - 将点转换为空盒子 + 将点转换为空矩形框 box(point '(0,0)') box(point, point) box - 将点转换为盒子 + 将点转换为矩形框 box(point '(0,0)', point '(1,1)') box(polygon) box - 将多边形转换为盒子 + 将多边形转换为矩形框 box(polygon '((0,0),(1,1),(2,0))') bound_box(box, box) box - 将多个盒子转换为包围盒 + 将两个矩形框转换为边界框 bound_box(box '((0,0),(1,1))', box '((3,3),(4,4))') circle circle(box) circle - 将盒子转换为圆 + 将矩形框转换为圆 circle(box '((0,0),(1,1))') @@ -6843,7 +6814,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple lseg lseg(box) lseg - 将盒子的对角线转换为线段 + 将矩形框的对角线转换为线段 lseg(box '((-1,0),(1,0))') @@ -6867,7 +6838,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple point(box) point - 盒子的中心 + 矩形框的中心 point(box '((-1,0),(1,0))') @@ -6891,7 +6862,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple polygon polygon(box) polygon - 将盒子转换为 4 个顶点的多边形 + 将矩形框转换为 4 个顶点的多边形 polygon(box '((0,0),(1,1))') @@ -6917,7 +6888,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple - 我们可以把一个point的两个组成数字当作具有索引 0 和 1 的数组访问。例如,如果t.p是一个point列,那么SELECT p[0] FROM t检索 X 坐标而 UPDATE t SET p[1] = ...改变 Y 坐标。同样,box或者lseg类型的值可以当作两个point值的数组值看待。 + 可以把一个point当作下标为 0 和 1 的数组,访问它的两个数值分量。例如,如果t.p是一个point列,那么SELECT p[0] FROM t检索 X 坐标而 UPDATE t SET p[1] = ...改变 Y 坐标。同样,box或者lseg类型的值可以当作两个point值组成的数组看待。 area 函数适用于 boxcirclepath 类型。对于 path 数据类型,只有当 path 中的点构成的路径不自相交时,area 函数才能工作。例如,path '((0,0),(0,1),(2,1),(2,2),(1,2),(1,0),(0,0))'::PATH 无法使用;但下面这个视觉上相同的 path '((0,0),(0,1),(1,1),(1,2),(2,2),(2,1),(1,1),(1,0),(0,0))'::PATH 可以使用。如果难以理解自相交与非自相交 path 的区别,可以把上述两条 path 并排画在方格纸上。 @@ -7219,7 +7190,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple 文本搜索函数和操作符 - 全文搜索 + 全文检索 函数和操作符 @@ -7232,7 +7203,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple 以及 - 总结了为全文搜索提供的函数和操作符。PostgreSQL的文本搜索功能的详细解释可参考。 + 总结了为全文检索提供的函数和操作符。PostgreSQL的文本搜索功能的详细解释可参考。 @@ -7316,10 +7287,10 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple
- tsquery 包含操作符只考虑两个查询中列出的词元,忽略组合操作符。 + tsquery 包含操作符只考虑两个查询中列出的词位,忽略组合操作符。 - 除了表中列出的操作符,tsvectortsquery 类型还定义了普通的 B-tree 比较操作符(=< 等)。这些操作符对文本搜索用处不大,但可以用于其他用途,例如在这些类型的列上建立唯一索引。 + 除了表中列出的操作符,tsvectortsquery 类型还定义了普通的 B-树比较操作符(=< 等)。这些操作符对文本搜索用处不大,但可以用于其他用途,例如在这些类型的列上建立唯一索引。 文本搜索函数 @@ -7337,28 +7308,28 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple array_to_tsvector array_to_tsvector(text[]) tsvector - 将词元数组转换为 tsvector + 将词位数组转换为 tsvector array_to_tsvector('{fat,cat,rat}'::text[]) 'cat' 'fat' 'rat' get_current_ts_config get_current_ts_config() regconfig - 获取默认的全文搜索配置 + 获取默认的文本搜索配置 get_current_ts_config() english length length(tsvector) integer - tsvector 中的词元数 + tsvector 中的词位数 length('fat:2,4 cat:3 rat:5A'::tsvector) 3 numnode numnode(tsquery) integer - tsquery 中的词元数与操作符数之和 + tsquery 中的词位数与操作符数之和 numnode('(fat & rat) | cat'::tsquery) 5 @@ -7398,7 +7369,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple 'cat':3A 'fat':2A,4A 'rat':5A - setweight 为指定词元设置权重 setweight(vector tsvector, weight "char", lexemes text[]) + setweight 为指定词位设置权重 setweight(vector tsvector, weight "char", lexemes text[]) tsvector vector 中列在 lexemes 内的元素赋予 weight setweight('fat:2,4 cat:3 rat:5B'::tsvector, 'A', '{cat,rat}') @@ -7414,7 +7385,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple to_tsquery to_tsquery( config regconfig , query text) tsquery - 规范化单词并转换为 tsquery + 正规化单词并转换为 tsquery to_tsquery('english', 'The & Fat & Rats') 'fat' & 'rat' @@ -7449,7 +7420,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple ts_delete(vector tsvector, lexemes text[]) tsvector - vector 中移除 lexemes 所列词元的所有出现 + vector 中移除 lexemes 所列词位的所有出现 ts_delete('fat:2,4 cat:3 rat:5A'::tsvector, ARRAY['fat','rat']) 'cat':3 @@ -7519,7 +7490,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsvector_to_array tsvector_to_array(tsvector) text[] - tsvector 转换为词元数组 + tsvector 转换为词位数组 tsvector_to_array('fat:2,4 cat:3 rat:5A'::tsvector) {cat,fat,rat} @@ -7553,13 +7524,13 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple - 所有接受一个可选的regconfig参数的文本搜索函数在该参数被忽略时,使用由指定的配置。 + 所有接受一个可选的regconfig参数的文本搜索函数在省略该参数时,会使用由指定的配置。 中的函数被单独列出,因为它们通常不被用于日常的文本搜索操作。 - 它们主要有助于开发和调试新的文本搜索配置。 + 它们有助于开发和调试新的文本搜索配置。
@@ -7606,14 +7577,14 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple ts_token_type ts_token_type(parser_name text, OUT tokid integer, OUT alias text, OUT description text) setof record - 获取解析器定义的记号类型 + 获取解析器定义的词元类型 ts_token_type('default') (1,asciiword,"Word, all ASCII") ... ts_token_type(parser_oid oid, OUT tokid integer, OUT alias text, OUT description text) setof record - 获取解析器定义的记号类型 + 获取解析器定义的词元类型 ts_token_type(3722) (1,asciiword,"Word, all ASCII") ... @@ -8035,7 +8006,7 @@ SELECT xmlexists('//town[text() = ''Toronto'']' PASSING BY VALUE 'T - 示例: + 示例: - 示例: + 示例: test', ARRAY[ARRAY['my', 'http://example.com']]); @@ -8147,7 +8118,7 @@ SELECT xpath('//mydefns:b/text()', 'test - 示例: + 示例: test', ARRAY[ARRAY['my', 'http://example.com']]); @@ -8529,7 +8500,7 @@ table2-mapping - 本节描述: + 本节描述: @@ -8539,14 +8510,16 @@ table2-mapping - SQL/JSON路径语言 + SQL/JSON 路径语言 - 要了解有关SQL/JSON标准的更多信息,请参阅。有关PostgreSQL中支持的JSON类型的详细信息,见 。 + 要了解有关 SQL/JSON 标准的更多信息,请参阅。有关 + PostgreSQL 中支持的 JSON 类型的详细信息,见 + @@ -9300,17 +9273,17 @@ table2-mapping - 如果输出列的类型是jsonjsonb,则会精确地重制JSON值。 - + 如果输出列的类型是jsonjsonb,则 JSON 值会被原样保留。 + - 如果输出列是复合(行)类型,且JSON值是JSON对象,则该对象的字段将转换为输出行类型的列,通过这些规则的递归应用程序。 + 如果输出列是复合(行)类型,且JSON值是JSON对象,则该对象的字段会通过递归应用这些规则,被转换为输出行类型的各列。 - 同样,如果输出列是数组类型,而JSON值是JSON数组,则通过这些规则的递归应用程序将JSON数组的元素转换为输出数组的元素。 + 同样,如果输出列是数组类型,而JSON值是JSON数组,则会通过递归应用这些规则,把JSON数组的元素转换为输出数组的元素。 @@ -9318,8 +9291,8 @@ table2-mapping - 否则,JSON值的普通文本表示将被提供给输入转换函数,以确定列的数据类型。 - + 否则,JSON 值的普通文本表示会被送入该列数据类型的输入转换函数。 + @@ -9367,7 +9340,7 @@ table2-mapping 要引用待查询的 JSON 数据(上下文项),请在路径表达式中使用 $ 符号。它后面可以跟一个或多个访问操作符,沿 JSON 结构逐层向下获取上下文项的内容。每个后续操作符都处理上一步求值的结果。 - 例如,假设你有一些你想要解析的来自GPS跟踪器的JSON数据,例如: + 例如,假设你有一些你想要解析的来自GPS跟踪器的JSON数据,例如: { "track": { @@ -9414,10 +9387,10 @@ table2-mapping - 过滤表达式必须在它们应该应用的路径求值步骤之后写入。该步骤的结果将被筛选,以只包括满足所提供条件的那些项。 + 过滤表达式必须在它们应该应用的路径求值步骤之后指定。该步骤的结果会经过过滤,只保留满足给定条件的项。 SQL/JSON定义了三值逻辑,因此条件可以是 true, false,或 unknownunknown值发挥与SQL NULL相同的角色,可以使用is unknown谓词进行测试。 - 进一步的路径求值步骤只使用筛选器表达式返回true的那些项。 + 进一步的路径求值步骤只使用过滤表达式返回true的那些项。 可用于过滤表达式的函数和操作符列于。变量 @ 表示待过滤的路径求值结果。要引用嵌套层次更深的 JSON 元素,可在 @ 后添加一个或多个访问操作符。 @@ -9454,7 +9427,10 @@ table2-mapping - 路径表达式可以是布尔谓词,尽管 SQL/JSON 标准只允许在过滤器中使用谓词。这是实现以下操作符所必需的:@@。例如,以下jsonpath表达式可用于PostgreSQL: + + 路径表达式可以是布尔谓词,尽管 SQL/JSON 标准只允许在过滤器中使用谓词。 + 这对于实现 @@ 操作符是必要的。例如, + 下面的 jsonpath 表达式在 PostgreSQL 中是有效的: '$.track.segments[*].HR < 70' @@ -9472,7 +9448,7 @@ table2-mapping 严格模式与宽松模式 当查询JSON数据时,路径表达式可能与实际的JSON数据结构不匹配。 - 试图访问不存在的对象成员或数组元素会导致结构错误。SQL/JSON路径表达式有两种处理结构错误的模式: + 试图访问不存在的对象成员或数组元素会导致结构错误。SQL/JSON路径表达式有两种处理结构错误的模式: @@ -9486,16 +9462,18 @@ table2-mapping - 如果 JSON 数据不符合预期模式,宽松模式有助于使 JSON 文档结构与路径表达式相匹配。如果操作数不满足某个操作的要求,可以在执行该操作之前自动将其包装为 SQL/JSON 数组,或通过将其元素转换为 SQL/JSON 序列来展开。此外,在宽松模式下,比较操作符会自动展开其操作数,因此可以直接比较 SQL/JSON 数组。大小为 1 的数组被视为等于其唯一元素。只有以下情况不会自动展开: + + 如果 JSON 数据不符合预期模式,宽松模式有助于使 JSON 文档结构与路径表达式相匹配。如果操作数不满足某个操作的要求,可以在执行该操作之前自动将其包装为 SQL/JSON 数组,或通过将其元素转换为 SQL/JSON 序列来解包。此外,在宽松模式下,比较操作符会自动解包其操作数,因此可以直接比较 SQL/JSON 数组。大小为 1 的数组被视为等于其唯一元素。以下情况不会自动解包: + - 路径表达式包含type()size()方法,它们分别返回数组中的元素类型和数量。 + 路径表达式包含type()size()方法,它们分别返回类型和数组中的元素数量。 - 查询的JSON数据包含嵌套的数组。在本例中,只有最外层的数组被打开,而所有内部数组保持不变。 - 因此,隐式展开在每个路径求值步骤中只能向下进行一级。 + 查询的JSON数据包含嵌套的数组。在本例中,只有最外层的数组被解包,而所有内部数组保持不变。 + 因此,隐式解包在每个路径求值步骤中只能向下进行一级。 @@ -9506,14 +9484,14 @@ table2-mapping - 在严格模式下,指定路径必须与所查询 JSON 文档的结构完全匹配,才能返回 SQL/JSON 项,因此使用此路径表达式会导致错误。要得到与宽松模式相同的结果,必须显式展开segments数组: + 在严格模式下,指定路径必须与所查询 JSON 文档的结构完全匹配,才能返回 SQL/JSON 项,因此使用此路径表达式会导致错误。要得到与宽松模式相同的结果,必须显式解包segments数组: 'strict $.track.segments[*].location' .**访问器在宽松模式下可能产生出人意料的结果。例如,下面的查询会选出每个HR值两次: lax $.**.HR -这是因为.**访问器既选择segments数组,又选择其每个元素,而.HR访问器在宽松模式下会自动展开数组。为避免意外结果,建议将.**访问器仅用于严格模式。下面的查询只选出每个HR值一次: +这是因为.**访问器既选择segments数组,又选择其每个元素,而.HR访问器在宽松模式下会自动解包数组。为避免意外结果,建议将.**访问器仅用于严格模式。下面的查询只选出每个HR值一次: strict $.**.HR @@ -9525,7 +9503,7 @@ strict $.**.HR LIKE_REGEX - in SQL/JSON + 用于 SQL/JSON SQL/JSON 路径表达式允许使用like_regex过滤器,将文本与正则表达式进行匹配。例如,以下 SQL/JSON 路径查询会以不区分大小写的方式,匹配数组中所有以英语元音字母开头的字符串: @@ -9534,19 +9512,19 @@ strict $.**.HR - 可选的flag字符串可以包括一个或多个字符i用于不区分大小写的匹配,m允许^$在换行时匹配,s允许.匹配换行符,q引用整个模式(将行为简化为一个简单的子字符串匹配)。 + 可选的flag字符串可以包括一个或多个字符i用于不区分大小写的匹配,m允许^$在换行时匹配,s允许.匹配换行符,q将整个模式按字面量处理(将行为简化为一个简单的子字符串匹配)。 SQL/JSON标准借用了来自LIKE_REGEX操作符的正则表达式定义,其使用了XQuery标准。 PostgreSQL目前不支持LIKE_REGEX操作符。因此,like_regex过滤器是使用中描述的POSIX正则表达式引擎来实现的。 - 这导致了与标准SQL/JSON行为的各种细微差异,这在中进行了分类。 - 但是请注意,这里描述的标志字母不兼容并不适用于SQL/JSON,因为它将XQuery标志字母翻译为符合POSIX引擎的预期。 + 这导致了与标准SQL/JSON行为的各种细微差异,这些差异列在中。 + 但是请注意,这里描述的标志字母不兼容并不适用于SQL/JSON,因为 SQL/JSON 会将 XQuery 标志字母转换为 POSIX 引擎所预期的形式。 - 请记住,like_regex的模式参数是一个JSON路径字符串文字,根据给出的规则编写。 - 这特别意味着在正则表达式中要使用的任何反斜杠都必须加倍。例如,匹配只包含数字的根文档的字符串值: + 请记住,like_regex的模式参数是一个JSON 路径字符串字面量,根据给出的规则编写。 + 这特别意味着在正则表达式中要使用的任何反斜杠都必须加倍。例如,匹配根文档中仅包含数字的字符串值: $.* ? (@ like_regex "^\\d+$") @@ -9685,7 +9663,7 @@ $.* ? (@ like_regex "^\\d+$")
- <type>jsonpath</type> 过滤器表达式元素 + <type>jsonpath</type> 过滤表达式元素 @@ -9799,9 +9777,7 @@ $.* ? (@ like_regex "^\\d+$") like_regex - - 测试第一个操作数是否与第二个操作数给出的正则表达式匹配,可选使用由一串flag字符描述的修改(参见)。 - + 测试第一个操作数是否与第二个操作数给出的正则表达式匹配;可以用一串flag标志字符调整匹配行为(参见)。 ["abc", "abd", "aBdC", "abdacb", "babc"] $[*] ? (@ like_regex "^ab.*c" flag "i") "abc", "aBdC", "abdacb" @@ -9842,7 +9818,7 @@ $.* ? (@ like_regex "^\\d+$") 序列操作函数 - sequence + 序列 nextval @@ -9858,7 +9834,7 @@ $.* ? (@ like_regex "^\\d+$") - 本节描述对序列对象进行操作的函数,也称为序列生成器或简称序列。 + 本节描述用于操作序列对象(也称为序列生成器,或简称序列)的函数。 序列对象是使用创建的特殊单行表。 序列对象通常用于为表中的行生成惟一标识符。在中列出的序列函数,提供了简单的、多用户安全方法,用于从序列对象中获取连续的序列值。 @@ -9914,10 +9890,10 @@ nextval('foo') 在搜索路径中查找 fo PostgreSQL 8.1 之前,序列函数的参数类型是 text,而不是 regclass;上述从文本字符串到 OID 值的转换会在每次调用时于运行期间执行。为保持向后兼容,这种能力仍然存在,但内部现在会在调用函数前,通过从 textregclass 的隐式强制转换来处理。 - 将序列函数的参数写成不加修饰的字符串字面量时,它会成为以下类型的常量:regclass。由于它实际上只是一个 OID,即使后来发生重命名、模式变更等情况,它仍会指向最初标识的序列。这种早绑定行为通常适用于列默认值和视图中的序列引用。但有时你可能希望采用后绑定,在运行时解析序列引用。要获得后期绑定行为,应强制将常量存储为text常量,而不是regclass: + 将序列函数的参数写成不加修饰的字符串字面量时,它会成为以下类型的常量:regclass。由于它实际上只是一个 OID,即使后来发生重命名、模式变更等情况,它仍会指向最初标识的序列。这种早绑定行为通常适用于列默认值和视图中的序列引用。但有时你可能希望采用后绑定,在运行时解析序列引用。要获得后绑定行为,应强制将常量存储为text常量,而不是regclass nextval('foo'::text) foo运行时被查找 -请注意,后期绑定是下列旧版本唯一支持的行为:PostgreSQL8.1 之前的版本,因此可能需要这样做来保留旧应用的语义。 +请注意,后绑定是下列旧版本唯一支持的行为:PostgreSQL8.1 之前的版本,因此可能需要这样做来保留旧应用的语义。 当然,序列函数的参数既可以是常量,也可以是表达式。如果它是文本表达式,隐式强制转换就会导致运行时查找。 @@ -9931,7 +9907,7 @@ nextval('foo'::text) foo运行时被查 如果使用默认参数创建序列对象,连续调用 nextval 会返回从 1 开始的连续值。可以在 命令中使用特殊参数获得其他行为;更多信息请参见该命令的参考页。 - 这个函数需要USAGEUPDATE权限在序列上。 + 这个函数需要序列上的USAGEUPDATE权限。 @@ -10043,7 +10019,7 @@ CASE WHEN condition THEN result - CASE子句可以用于任何表达式可以出现的地方。每一个condition是一个返回boolean结果的表达式。如果结果为真,那么CASE表达式的结果就是符合条件的result,并且剩下的CASE表达式不会被处理。如果条件的结果不为真,那么以相同方式搜寻任何随后的WHEN子句。如果没有WHEN condition为真,那么CASE表达式的值就是在ELSE子句里的result。如果省略了ELSE子句而且没有条件为真,结果为空。 + CASE子句可以用于任何表达式可以出现的地方。每一个condition是一个返回boolean结果的表达式。如果结果为真,那么CASE表达式的结果就是紧随该条件后的result,并且剩下的CASE表达式不会被处理。如果条件的结果不为真,那么以相同方式搜寻任何随后的WHEN子句。如果没有WHEN condition为真,那么CASE表达式的值就是在ELSE子句里的result。如果省略了ELSE子句而且没有条件为真,结果为 null。 @@ -10087,7 +10063,7 @@ CASE expression END - 第一个expression会被计算,然后与所有在WHEN子句中的每一个value对比,直到找到一个相等的。如果没有找到匹配的,则返回在ELSE子句中的result(或者控制)。 这类似于 C 里的switch语句。 + 第一个expression会被计算,然后与所有在WHEN子句中的每一个value对比,直到找到一个相等的。如果没有找到匹配的,则返回在ELSE子句中的result(或者 null 值)。 这类似于 C 里的switch语句。 @@ -10118,11 +10094,7 @@ SELECT ... WHERE CASE WHEN x <> 0 THEN y/x > 1.5 ELSE false END; - 如中所述,在有几种情况中一个表达式的子表达式 - 会被计算多次,因此CASE只计算必要的表达式这 - 一原则并非不可打破。例如一个常量子表达式1/0通常将会在规划时导致一次 - 除零错误,即便它位于一个执行时永远也不会进入的CASE分支时也是 - 如此。 + 如所述,在多种情况下,表达式中的子表达式会在不同阶段求值,因此CASE只计算必要的子表达式这一原则并非绝对成立。例如,常量子表达式1/0通常会在规划时导致除零错误,即便它位于一个运行时永远不会进入的CASE分支中也是如此。 @@ -10146,17 +10118,19 @@ SELECT ... WHERE CASE WHEN x <> 0 THEN y/x > 1.5 ELSE false END; COALESCE(value , ...) - COALESCE函数返回参数中第一个不为 null 的值。只有所有参数都为 null 时,才返回 null。它常用于在检索数据以供显示时,用默认值替换 null 值。例如: + COALESCE函数返回参数中第一个不为 null 的值。只有所有参数都为 null 时,才返回 null。它常用于在检索数据以供显示时,用默认值替换 null 值。例如: + SELECT COALESCE(description, short_description, '(none)') ... -此表达式返回description,前提是它不为 null,否则返回short_description,前提是它不为 null,否则返回(none)。 + + 此表达式返回description,前提是它不为 null,否则返回short_description,前提是它不为 null,否则返回(none) - 所有参数都必须转换为一个公共数据类型,它将是结果的类型 (详情参见 )。 + 所有参数都必须能转换为同一个数据类型,它将是结果的类型(详情参见)。 - 和CASE表达式一样,COALESCE将不会 计算无助于判断结果的参数;也就是说,在第一个非空参数右边的参数不会被计算。这个 SQL 标准函数提供了类似于NVLIFNULL的能力,它们被用在某些其他数据库系统中。 + 和CASE表达式一样,COALESCE只计算确定结果所需的参数;也就是说,在第一个不为 null 的参数右边的参数不会被计算。这个 SQL 标准函数提供了类似于NVLIFNULL的能力,它们被用在某些其他数据库系统中。 @@ -10172,12 +10146,12 @@ SELECT COALESCE(description, short_description, '(none)') ... - 当value1value2相等时,NULLIF返回一个空值。 + 当value1value2相等时,NULLIF返回 null。 否则它返回value1。 这些可以用于执行前文给出的COALESCE示例的逆操作: SELECT NULLIF(value, '(none)') ... - 在这个示例中,如果value(none),将返回空值,否则返回value的值。 + 在这个示例中,如果value(none),将返回 null,否则返回value的值。 @@ -10212,11 +10186,11 @@ SELECT NULLIF(value, '(none)') ... - GREATESTLEAST函数从一个任意的数字表达式列表里选取最大或者最小的数值。 这些表达式必须都可以转换成一个普通的数据类型,它将会是结果类型 (参阅获取细节)。列表中的 NULL 数值将被忽略。只有所有表达式的结果都是 NULL 的时候,结果才会是 NULL。 + GREATESTLEAST函数从由任意数量的表达式组成的列表中选取最大值或最小值。这些表达式都必须能转换为同一个数据类型,该类型将作为结果类型(详情参见)。列表中的 NULL 值会被忽略。只有所有表达式的求值结果都为 NULL 时,结果才为 NULL。 - 请注意GREATESTLEAST都不是 SQL 标准,但却是很常见的扩展。某些其他数据库让它们在任何参数为 NULL 时返回 NULL,而不是在所有参数都为 NULL 时才返回 NULL。 + 请注意GREATESTLEAST都未包含在 SQL 标准中,但却是很常见的扩展。某些其他数据库让它们在任何参数为 NULL 时返回 NULL,而不是在所有参数都为 NULL 时才返回 NULL。 @@ -10332,12 +10306,12 @@ SELECT NULLIF(value, '(none)') ...
- 数组排序操作符(<>= 等)使用元素数据类型的默认 B-tree 比较函数,逐个元素比较数组内容,并根据第一个差异决定排序顺序。多维数组的元素按行优先顺序访问(最后一个下标变化最快)。如果两个数组的内容相同,但维度不同,则由维度信息中的第一个差异决定排序顺序。(这与 PostgreSQL 8.2 之前的版本不同:旧版本会将内容相同的两个数组视为相等,即使它们的维数或下标范围不同。) + 数组排序操作符(<>= 等)使用元素数据类型的默认 B-树比较函数,逐个元素比较数组内容,并根据第一个差异决定排序顺序。多维数组的元素按行优先顺序访问(最后一个下标变化最快)。如果两个数组的内容相同,但维度信息不同,则由维度信息中的第一个差异决定排序顺序。(这与 PostgreSQL 8.2 之前的版本不同:旧版本会将内容相同的两个数组视为相等,即使它们的维数或下标范围不同。) 数组包含操作符(<@@>)在一个数组的每个元素都出现在另一个数组中时,认为前者包含在后者中。重复元素不会被特殊处理,因此 ARRAY[1]ARRAY[1,1] 被认为彼此包含。 - 参阅获取有关数组操作符行为的更多细节。有关哪些操作符支持被索引的操作,请参阅。 + 参阅获取有关数组操作符行为的更多细节。有关哪些操作符支持索引操作,请参阅 @@ -10623,7 +10597,7 @@ NULL baz(3 rows)
string_to_array 中,如果分隔符参数为 NULL,输入字符串中的每个字符都会成为结果数组中的独立元素。如果分隔符为空字符串,则将整个输入字符串作为单元素数组返回。否则,在分隔符字符串的每次出现处拆分输入字符串。 - string_to_array 中,如果省略空值字符串参数,或该参数为 NULL,则不会将任何输入子串替换为 NULL。在 array_to_string 中,如果省略空值字符串参数,或该参数为 NULL,则直接跳过数组中的所有空元素,不在输出字符串中表示它们。 + string_to_array 中,如果省略 null 替代字符串参数,或该参数为 NULL,则不会将任何输入子串替换为 NULL。在 array_to_string 中,如果省略 null 替代字符串参数,或该参数为 NULL,则直接跳过数组中的所有 null 元素,不在输出字符串中表示它们。 string_to_array 的行为与 PostgreSQL 9.1 之前的版本有两点不同。首先,当输入字符串长度为零时,它返回空数组(零元素),而不是 NULL。其次,如果分隔符字符串为 NULL,该函数会将输入拆分为单独的字符,而不是像以前那样返回 NULL。 @@ -10783,7 +10757,7 @@ NULL baz(3 rows)
- - difference + 差集 int8range(5,15) - int8range(10,20) [5,10) @@ -10792,7 +10766,7 @@ NULL baz(3 rows)
- 简单比较操作符 <><=>= 首先比较下界,只有下界相等时才比较上界。这些比较对范围通常用处不大,但提供这些操作符可以在范围上建立 B-tree 索引。 + 简单比较操作符 <><=>= 首先比较下界,只有下界相等时才比较上界。这些比较对范围通常用处不大,但提供这些操作符可以在范围上建立 B-树索引。 涉及空范围时,左侧、右侧和相邻操作符总是返回假;也就是说,空范围不被视为位于任何其他范围之前或之后。 @@ -10927,7 +10901,7 @@ NULL baz(3 rows)
- 如果范围为空,或请求的边界是无限的,lowerupper 函数返回空值。对于空范围,lower_incupper_inclower_infupper_inf 函数都返回假。 + 如果范围为空,或请求的边界是无限的,lowerupper 函数返回 null。对于空范围,lower_incupper_inclower_infupper_inf 函数都返回假。 @@ -10959,7 +10933,7 @@ NULL baz(3 rows)
array_agg array_agg(expression) 任意非数组类型 参数类型的数组 - No + 将输入值(包括 null)串接为数组
@@ -10967,7 +10941,7 @@ NULL baz(3 rows)
array_agg(expression) 任意数组类型 与参数数据类型相同 - No + 将输入数组串接为维数多一维的数组(所有输入的维数必须相同,且不能是空数组或 null)
@@ -11039,7 +11013,7 @@ NULL baz(3 rows)
json_agg json_agg(expression) any json - No + 将值(包括 null)聚合为 JSON 数组
@@ -11047,7 +11021,7 @@ NULL baz(3 rows)
jsonb_agg jsonb_agg(expression) any jsonb - No + 将值(包括 null)聚合为 JSON 数组
@@ -11057,7 +11031,7 @@ NULL baz(3 rows)
(any, any)
json - No + 将名称/值对聚合为 JSON 对象;值可以为 null,名称不能为 null
@@ -11067,7 +11041,7 @@ NULL baz(3 rows)
(any, any)
jsonb - No + 将名称/值对聚合为 JSON 对象;值可以为 null,名称不能为 null
@@ -11091,7 +11065,7 @@ NULL baz(3 rows)
string_agg string_agg(expression, delimiter) texttext)或(byteabytea 与参数类型相同 - No + 将非空输入值串接为字符串,以分隔符分隔
@@ -11107,7 +11081,7 @@ NULL baz(3 rows)
xmlagg xmlagg(expression) xml xml - No + 串接非空 XML 值(另见
@@ -11115,9 +11089,7 @@ NULL baz(3 rows)
- 应该注意的是,除了count之外,这些函数在没有选择行时返回空值。 - 特别地,行数的sum返回空(null),而不是预期的零,array_agg在没有输入行时返回空(null)而不是空数组。 - coalesce函数可以在必要时用零或空数组代替空(null)。 + 需要注意,除了count之外,这些函数在没有选中任何行时都会返回空值。特别地,sum在没有输入行时返回空值,而不是预期中的零;array_agg在没有输入行时返回空值,而不是空数组。必要时,可以用coalesce函数把空值替换成零或空数组。 支持部分模式的聚合函数可以参与并行聚合等多种优化。 @@ -11141,16 +11113,11 @@ SELECT count(*) FROM sometable; - 聚合函数 array_agg,json_agg, jsonb_agg,json_object_agg, jsonb_object_agg, - string_agg,和 xmlagg,以及类似的用户定义的聚合函数,根据输入值的顺序产生富有意义的不同的结果值。 - 默认情况下,这种排序是不指定的,但可以通过在聚合调用中写入ORDER BY子句来控制,如所示。 - 或者,从排序的子查询提供输入值通常也可以。例如: - + 聚合函数array_aggjson_aggjsonb_aggjson_object_aggjsonb_object_aggstring_aggxmlagg,以及类似的用户定义聚合函数,其结果值会随输入值的顺序发生实质性变化。默认情况下,输入顺序未指定,但可以在聚合调用中写入ORDER BY子句来控制,如所示。也可以用已排序的子查询提供输入值,这通常也能奏效。例如: - - 注意,如果外部查询级别包含其他处理,例如关联,则此方法可能会失败,因为这可能导致子查询的输出在计算聚合之前重新排序。 + 需要注意,如果外层查询包含连接等额外处理,这种方法可能失效,因为子查询的输出可能在计算聚合之前被重新排序。 列出了统计分析常用的聚合函数。(将它们单独列出只是为了避免让更常用的聚合函数列表过于拥挤。)说明中提到的 N 表示所有输入表达式均非空的输入行数。在所有情况下,如果计算没有意义,例如 N 为零,都会返回空值。 @@ -11182,7 +11149,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; 相关性 corr corr(Y, X) double precision double precision - Yes + 相关系数
@@ -11190,7 +11157,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; 协方差 总体 covar_pop covar_pop(Y, X) double precision double precision - Yes + 总体协方差
@@ -11198,7 +11165,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; 协方差 样本 covar_samp covar_samp(Y, X) double precision double precision - Yes + 样本协方差
@@ -11206,7 +11173,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; regr_avgx regr_avgx(Y, X) double precision double precision - Yes + 自变量的平均值(sum(X)/N
@@ -11214,7 +11181,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; regr_avgy regr_avgy(Y, X) double precision double precision - Yes + 因变量的平均值(sum(Y)/N
@@ -11222,7 +11189,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; regr_count regr_count(Y, X) double precision bigint - Yes + 两个表达式都非空的输入行数 @@ -11230,7 +11197,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; 回归截距 regr_intercept regr_intercept(Y, X) double precision double precision - Yes + 由(XY)数值对确定的最小二乘拟合线性方程的 y 轴截距 @@ -11238,7 +11205,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; regr_r2 regr_r2(Y, X) double precision double precision - Yes + 相关系数的平方 @@ -11246,7 +11213,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; 回归斜率 regr_slope regr_slope(Y, X) double precision double precision - Yes + 由(XY)数值对确定的最小二乘拟合线性方程的斜率 @@ -11254,7 +11221,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; regr_sxx regr_sxx(Y, X) double precision double precision - Yes + sum(X^2) - sum(X)^2/N(自变量的平方和 @@ -11262,7 +11229,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; regr_sxy regr_sxy(Y, X) double precision double precision - Yes + sum(X*Y) - sum(X) * sum(Y)/N(自变量与因变量的乘积和 @@ -11270,7 +11237,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; regr_syy regr_syy(Y, X) double precision double precision - Yes + sum(Y^2) - sum(Y)^2/N(因变量的平方和 @@ -11278,7 +11245,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; 标准差 stddev stddev(expression) smallintintbigintrealdouble precisionnumeric 浮点参数返回 double precision,其他情况返回 numeric - Yes + stddev_samp 的历史别名 @@ -11286,7 +11253,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; 标准差 总体 stddev_pop stddev_pop(expression) smallintintbigintrealdouble precisionnumeric 浮点参数返回 double precision,其他情况返回 numeric - Yes + 输入值的总体标准差 @@ -11294,7 +11261,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; 标准差 样本 stddev_samp stddev_samp(expression) smallintintbigintrealdouble precisionnumeric 浮点参数返回 double precision,其他情况返回 numeric - Yes + 输入值的样本标准差 @@ -11302,7 +11269,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; variance variance(expression) smallintintbigintrealdouble precisionnumeric 浮点参数返回 double precision,其他情况返回 numeric - Yes + var_samp 的历史别名 @@ -11310,7 +11277,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; 方差 总体 var_pop var_pop(expression) smallintintbigintrealdouble precisionnumeric 浮点参数返回 double precision,其他情况返回 numeric - Yes + 输入值的总体方差(总体标准差的平方) @@ -11318,7 +11285,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; 方差 样本 var_samp var_samp(expression) smallintintbigintrealdouble precisionnumeric 浮点参数返回 double precision,其他情况返回 numeric - Yes + 输入值的样本方差(样本标准差的平方) @@ -11328,7 +11295,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; 列出了一些使用有序集聚合语法的聚合函数。这些函数有时被称为逆分布函数。 - ordered-set aggregate + 有序集聚合 内置 @@ -11353,22 +11320,22 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; - mode 统计 mode() WITHIN GROUP (ORDER BY sort_expression) + 众数 统计 mode() WITHIN GROUP (ORDER BY sort_expression) 任意可排序类型 与排序表达式相同 - No + 返回出现次数最多的输入值(若有多个结果同样频繁,则任意选择第一个) - 百分位数 连续 percentile_cont(fraction) WITHIN GROUP (ORDER BY sort_expression) + 百分位点 连续 percentile_cont(fraction) WITHIN GROUP (ORDER BY sort_expression) double precision double precisioninterval 与排序表达式相同 - No - 连续百分位数:返回排序中与指定比例对应的值,必要时在相邻输入项之间插值 + + 连续百分位点:返回排序中与指定比例对应的值,必要时在相邻输入项之间插值 @@ -11378,8 +11345,8 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; double precisioninterval 排序表达式类型的数组 - No - 多个连续百分位数:返回形状与 fractions 参数一致的结果数组,将每个非空元素替换为与该百分位数对应的值 + + 多个连续百分位点:返回形状与 fractions 参数一致的结果数组,将每个非空元素替换为与该百分位点对应的值 @@ -11387,7 +11354,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; double precision 任意可排序类型 与排序表达式相同 - No + 离散百分位数:返回排序位置等于或超过指定比例的第一个输入值 @@ -11398,7 +11365,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; 任意可排序类型 排序表达式类型的数组 - No + 多个离散百分位数:返回形状与 fractions 参数一致的结果数组,将每个非空元素替换为与该百分位数对应的输入值 @@ -11406,10 +11373,10 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab;
- 中列出的所有聚合函数都忽略其排序输入中的空值。对于接受 fraction 参数的函数,该比例值必须在 0 和 1 之间,否则会报错。但空的比例值只会产生空结果。 + 中列出的所有聚合函数都忽略其排序输入中的空值。对于接受 fraction 参数的函数,该比例值必须在 0 和 1 之间,否则会报错。但 null 比例值只会产生 null 结果。 - hypothetical-set aggregate + 假想集聚合 内置 @@ -11437,7 +11404,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; VARIADIC "any" VARIADIC "any" bigint - No + 假设行的排名,重复行会造成排名空缺 @@ -11446,7 +11413,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; VARIADIC "any" VARIADIC "any" bigint - No + 假设行的排名,没有空缺 @@ -11455,7 +11422,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; VARIADIC "any" VARIADIC "any" double precision - No + 假设行的相对排名,范围为 0 到 1 @@ -11464,7 +11431,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; VARIADIC "any" VARIADIC "any" double precision - No + 假设行的相对排名,范围为 1/N 到 1 @@ -11593,31 +11560,31 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; lag lag(value anyelement [, offset integer [, default anyelement ]]) - same type as value + value 相同的类型 返回在分区内当前行之前 offset 行处计算的 value;如果没有这样的行,则返回 default(其类型必须与 value 相同)。offsetdefault 都针对当前行求值。如果省略,offset 默认为 1,default 默认为 null lead lead(value anyelement [, offset integer [, default anyelement ]]) - same type as value + value 相同的类型 返回在分区内当前行之后 offset 行处计算的 value;如果没有这样的行,则返回 default(其类型必须与 value 相同)。offsetdefault 都针对当前行求值。如果省略,offset 默认为 1,default 默认为 null first_value first_value(value any) - same type as value + value 相同的类型 返回在窗口帧第一行处计算的 value last_value last_value(value any) - same type as value + value 相同的类型 返回在窗口帧最后一行处计算的 value nth_value nth_value(value any, nth integer) - same type as value + value 相同的类型 返回在窗口帧第 nth 行处计算的 value(从 1 开始计数);没有这样的行时返回 null @@ -11639,8 +11606,8 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; 当一个聚合函数被用作窗口函数时,它将在当前行的窗口帧内的行上聚合。 - 一个使用ORDER BY和默认窗口帧定义的聚合产生一种运行时求和类型的行为,这可能是或者不是想要的结果。 - 为了获取在整个分区上的聚合,忽略ORDER BY或者使用ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING。 + 一个使用ORDER BY和默认窗口帧定义的聚合产生一种累计求和类型的行为,这可能是或者不是想要的结果。 + 为了获取在整个分区上的聚合,省略ORDER BY或者使用ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING。 其它窗口帧声明可以用来获得其它的效果。 @@ -11649,7 +11616,7 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; SQL 标准为leadlagfirst_valuelast_valuenth_value定义了一个RESPECT NULLSIGNORE NULLS选项。 这在PostgreSQL中没有实现:行为总是与标准的默认相同,即RESPECT NULLS。 - 同样,标准中用于nth_valueFROM FIRSTFROM LAST选项没有实现: 只有支持默认的FROM FIRST行为(你可以通过反转ORDER BY的排序达到FROM LAST的结果)。 + 同样,标准中用于nth_valueFROM FIRSTFROM LAST选项没有实现: 只支持默认的FROM FIRST行为(你可以通过反转ORDER BY的排序达到FROM LAST的结果)。 @@ -11685,11 +11652,11 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; - subquery + 子查询 - 本节描述PostgreSQL中可用的SQL兼容的子查询表达式。所有本节中成文的表达式都返回布尔值(真/假)结果。 + 本节描述PostgreSQL中可用的SQL兼容的子查询表达式。本节介绍的所有表达式形式都返回布尔值(真/假)结果。 @@ -11704,7 +11671,7 @@ EXISTS (subquery) - 子查询可以引用来自周围的查询的变量,这些变量在该子查询的任何一次计算中都起常量的作用。 + 子查询可以引用外层查询的变量,这些变量在该子查询的任何一次计算中都起常量的作用。 @@ -11716,7 +11683,7 @@ EXISTS (subquery) - 下面这个简单的示例类似在col2上的一次内联接,但是它为每个 tab1的行生成最多一个输出,即使存在多个匹配tab2的行也如此∶ + 下面这个简单的示例类似在col2上的一次内连接,但是它为每个 tab1的行最多生成一行输出,即使存在多个匹配tab2的行也如此: SELECT col1 FROM tab1 @@ -11733,15 +11700,15 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 右手边是一个圆括弧括起来的子查询, 它必须正好只返回一个列。左手边表达式将被计算并与子查询结果逐行进行比较。 如果找到任何等于子查询行的情况,那么IN的结果就是。 如果没有找到相等行,那么结果是(包括子查询没有返回任何行的情况)。 + 右手边是一个圆括号括起来的子查询,它必须恰好返回一列。左手边表达式会被求值,并与子查询结果逐行比较。如果找到任意相等的子查询行,那么IN的结果就是。如果没有找到相等行,那么结果就是(包括子查询不返回任何行的情况)。 - 请注意如果左手边表达式得到空值,或者没有相等的右手边值, 并且至少有一个右手边行得到空值,那么IN结构的结果将是空值,而不是假。这个行为是遵照 SQL 处理空值的一般规则的。 + 请注意,如果左侧表达式得到空值,或者右侧没有相等的值且至少有一行得到空值,则IN结构的结果将是空值,而不是假。这符合 SQL 对空值布尔组合的一般规则。 - 和EXISTS一样,假设子查询将被完成运行完全是不明智的。 + 和EXISTS一样,假定子查询一定会完整运行并不明智。 @@ -11749,7 +11716,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 这种形式的IN的左手边是一个行构造器, 如中所述。 右手边是一个圆括弧子查询,它必须返回和左手边返回的行中表达式所构成的完全一样多的列。 左手边表达式将被计算并与子查询结果逐行进行比较。如果找到任意相等的子查询行,则IN的结果为。如果没有找到相等行, 那么结果为(包括子查询不返回行的情况)。 + 这种形式的IN左手边是一个行构造器,如中所述。右手边是一个圆括号括起来的子查询,它必须返回与左手边行中表达式数量完全相同的列数。左手边表达式会被求值,并与子查询结果逐行比较。如果找到任意相等的子查询行,则IN的结果为。如果没有找到相等行,那么结果为(包括子查询不返回任何行的情况)。 @@ -11765,15 +11732,15 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 右手边是一个用圆括弧包围的子查询,它必须返回正好一个列。左手边表达式将被计算并与子查询结果逐行进行比较。 如果只找到不相等的子查询行(包括子查询不返回行的情况),那么NOT IN的结果是。 如果找到任何相等行,则结果为。 + 右手边是一个圆括号括起来的子查询,它必须恰好返回一列。左手边表达式会被求值,并与子查询结果逐行比较。如果只找到不相等的子查询行(包括子查询不返回任何行的情况),那么NOT IN的结果是。如果找到任何相等行,则结果为 - 请注意如果左手边表达式得到空值,或者没有相等的右手边值, 并且至少有一个右手边行得到空值,那么NOT IN结构的结果将是空值,而不是真。这个行为是遵照 SQL 处理空值的一般规则的。 + 请注意,如果左侧表达式得到空值,或者右侧没有相等的值且至少有一行得到空值,则NOT IN结构的结果将是空值,而不是真。这符合 SQL 对空值布尔组合的一般规则。 - 和EXISTS一样,假设子查询将被完成运行完全是不明智的。 + 和EXISTS一样,假定子查询一定会完整运行并不明智。 @@ -11781,7 +11748,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 这种形式的NOT IN的左手边是一个行构造器, 如中所述。 右手边是一个圆括弧子查询,它必须返回和左手边返回的行中表达式所构成的完全一样多的列。 左手边表达式将被计算并与子查询结果逐行进行比较。如果找到不等于子查询行的行,则NOT IN的结果为。如果找到相等行, 那么结果为(包括子查询不返回行的情况)。 + 这种形式的NOT IN左侧是一个行构造器,如中所述。右侧是一个用圆括号括起来的子查询,必须返回与左侧行中表达式数量完全相同的列数。对左侧表达式求值后,将其按行与子查询结果的每一行比较。如果只找到不相等的子查询行(包括子查询不返回任何行的情况),则NOT IN的结果为。如果找到任何相等行,则结果为 @@ -11806,11 +11773,11 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 请注意如果没有任何成功并且至少有一个右手边行为该操作符结果生成空值, 那么ANY结构的结果将是空值,而不是假。 这个行为是遵照 SQL 处理空值布尔组合的一般规则制定的。 + 请注意,如果没有任何比较返回真,并且至少有一个右侧行的操作符结果为空值,则ANY结构的结果将是空值,而不是假。这符合 SQL 对空值布尔组合的一般规则。 - 和EXISTS一样,假设子查询将被完成运行完全是不明智的。 + 和EXISTS一样,假定子查询一定会完整运行并不明智。 @@ -11819,7 +11786,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 这种形式的左侧是一个行构造器,如所述。右侧是一个用括号括起来的子查询,它必须返回与左侧行中表达式数量完全相同的列数。左侧表达式会被求值,并使用给定的operator与子查询结果的每一行逐行比较。如果比较对任何子查询行返回真,则ANY的结果为。如果比较对每一个子查询行都返回假,则结果为(包括子查询不返回行的情况)。如果比较对任何行都不返回真,并且至少有一次比较返回 NULL,则结果为 NULL。 + 这种形式的ANY左侧是一个行构造器,如所述。右侧是一个用括号括起来的子查询,它必须返回与左侧行中表达式数量完全相同的列数。左侧表达式会被求值,并使用给定的operator与子查询结果的每一行逐行比较。如果比较对任何子查询行返回真,则ANY的结果为。如果比较对每一个子查询行都返回假,则结果为(包括子查询不返回行的情况)。如果比较对任何行都不返回真,并且至少有一次比较返回 NULL,则结果为 NULL。 @@ -11835,7 +11802,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 这种形式的 ALL 右侧是一个用括号括起来的子查询,它必须只返回一列。左侧表达式会被求值,并使用给定的 operator 与子查询结果的每一行进行比较。该操作符必须产生布尔结果。如果所有行都得到真(包括子查询没有返回任何行的情况),ALL 的结果就是。如果发现任何假值结果,结果就是。如果比较对任何行都不返回假,并且至少有一次比较返回 NULL,则结果为 NULL。 + 右侧是一个用圆括号括起来的子查询,必须恰好返回一列。左侧表达式会被求值,并使用给定的operator与子查询结果的每一行进行比较。该操作符必须产生布尔结果。如果所有行都得到真(包括子查询不返回任何行的情况),则ALL的结果为。如果得到任何假值结果,则结果为。如果与任何子查询行的比较都不返回假,并且至少有一次比较返回 NULL,则结果为 NULL。 @@ -11843,7 +11810,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 和EXISTS一样,假设子查询将被完成运行完全是不明智的。 + 和EXISTS一样,假定子查询一定会完整运行并不明智。 @@ -11872,7 +11839,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 左手边是一个行构造器,如所述。 右手边是一个圆括弧括起来的子查询,该查询必须返回和左手边行中表达式数目完全一样的列。 另外,该子查询不能返回超过一行的数量(如果它返回零行,那么结果就是空值)。 左手边被计算并逐行与右手边的子查询结果行比较。 + 左侧是一个行构造器,如所述。右侧是一个用圆括号括起来的子查询,必须返回与左侧行中表达式数量完全相同的列数。此外,该子查询不能返回超过一行;如果它返回零行,则结果为空值。对左侧求值后,将所得的行与子查询返回的唯一一行进行比较。 @@ -11911,12 +11878,12 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 逐行比较 + 行比较 比较 - 逐行 + 复合类型 @@ -11933,7 +11900,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 本节描述几个特殊的结构,用于在值的组之间进行多重比较。这些形式语法上和前面一节的子查询形式相关,但是不涉及子查询。 这种形式涉及的数组子表达式是PostgreSQL的扩展; 其它的是SQL兼容的。所有本节记录的表达式形式都返回布尔(Boolean)结果(真/假)。 + 本节描述几个特殊的结构,用于在值的组之间进行多重比较。这些形式语法上和前面一节的子查询形式相关,但是不涉及子查询。 涉及数组子表达式的形式是PostgreSQL的扩展; 其余形式是SQL兼容的。本节介绍的所有表达式形式都返回布尔(Boolean)结果(真/假)。 @@ -11943,7 +11910,8 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); expression IN (value , ...) - 右侧是用圆括号括起的表达式列表。结果为true,条件是左侧表达式的结果等于右侧表达式中的任意一个。这是以下写法的简写: + 右侧是一个用圆括号括起来的表达式列表。如果左侧表达式的结果等于右侧任一表达式的结果,则结果为。这等价于以下写法: + expression = value1 OR expression = value2 @@ -11964,7 +11932,8 @@ OR expression NOT IN (value , ...) - 右侧是用圆括号括起的表达式列表。结果为true,条件是左侧表达式的结果与右侧的所有表达式都不相等。这是以下写法的简写: + 右侧是一个用圆括号括起来的表达式列表。如果左侧表达式的结果与右侧所有表达式的结果都不相等,则结果为。这等价于以下写法: + expression <> value1 AND expression <> value2 @@ -11986,7 +11955,7 @@ AND - <literal>ANY</literal>/<literal>SOME</literal> (array) + <literal>ANY</literal>/<literal>SOME</literal>(数组) expression operator ANY (array expression) @@ -12007,7 +11976,7 @@ AND - <literal>ALL</literal> (array) + <literal>ALL</literal>(数组) expression operator ALL (array expression) @@ -12031,20 +12000,7 @@ AND - 每一边都是一个行构造器, - 如在中描述的那样。 - 这两个行构造器必须具有相同数量的字段。 - 给定的operator应用于每一对 - 对应的字段。(由于字段可能是不同类型的,这意味着每对可能选择不同的具体操作符。) - 所有选定的操作符必须是某个B-树操作符类的成员,或者是B-树操作符类的=成员的否定形式, - 这意味着只有当operator是 - =、 - <>、 - <、 - <=、 - >或 - >=时才可能进行行构造器比较, - 或者具有类似于这些操作符的语义。 + 两侧都是行构造器,如所述。两个行构造器必须具有相同数量的字段。给定的operator应用于每一对对应字段。(由于字段可能具有不同的类型,因此可能为各对字段选择不同的具体操作符。)所选操作符必须是某个 B-树操作符类的成员,或者是 B-树操作符类中=成员的否定操作符。这意味着只有当operator=<><<=>>=,或具有与这些操作符类似的语义时,才可以进行行构造器比较。 @@ -12088,21 +12044,21 @@ AND - SQL 规范要求在结果依赖于比较两个 NULL 值或者一个 NULL 与一个非 NULL 时逐行比较返回 NULL。 + SQL 规范要求在结果依赖于比较两个 NULL 值或者一个 NULL 与一个非 NULL 时行比较返回 NULL。 PostgreSQL只有在比较两个行构造器(如)的结果或者比较一个行构造器与一个子查询的输出时才这样做(如中所述)。 - 在其他比较两个复合类型值的环境中,两个 NULL 域值被认为相等,并且一个 NULL 被认为大于一个非 NULL。 + 在其他比较两个复合类型值的环境中,两个 NULL 字段值被认为相等,并且一个 NULL 被认为大于一个非 NULL。 为了得到复合类型的一致的排序和索引行为,这样做是必要的。 - 每一边都会被计算并且它们会被逐行比较。当operator是 + 对两侧分别求值后,按行进行比较。当operator=<><<=>或者 - >=时或者具有与这些类似的语义时,允许复合类型的比较(更准确地说,如果一个操作符是一个 B-树操作符类的成员,或者是一个 B-树操作符类的=成员的否定词,它就可以是一个行比较操作符)。 - 上述操作符的行为与用于行构造器(见)的IS [ NOT ] DISTINCT FROM相同。 + >=时或者具有与这些类似的语义时,允许复合类型的比较(更准确地说,如果一个操作符是一个 B-树操作符类的成员,或者是一个 B-树操作符类的=成员的否定操作符,它就可以是一个行比较操作符)。 + 上述操作符的默认行为与用于行构造器(见)的IS [ NOT ] DISTINCT FROM相同。 @@ -12113,8 +12069,8 @@ AND *<=*>以及 *>=。 - 这些操作符比较两行的内部二进制表达。即使两行用相等操作符的比较为真,两行也可能具有不同的二进制表达。 - 行在这些比较操作符之下的排序是决定性的,其他倒没什么意义。 + 这些操作符比较两行的内部二进制表示。即使两行用相等操作符的比较为真,两行也可能具有不同的二进制表示。 + 使用这些比较操作符得到的行排序是确定的,但除此之外没有其他意义。 这些操作符在内部被用于物化视图并且可能对其他如复制之类的特殊功能有用,但是它们并不打算用在书写查询这类普通用途中。 @@ -12133,12 +12089,12 @@ AND - 本节描述那些可能返回多于一行的函数。目前这个类中被使用最广泛的是级数生成函数, 如所述。其他更特殊的集合返回函数在本手册的其他地方描述。 - 组合多集合返回函数的方法可见。 + 本节描述那些可能返回多于一行的函数。目前这个类中被使用最广泛的是序列生成函数, 如所述。其他更特殊的集合返回函数在本手册的其他地方描述。 + 组合多个集合返回函数的方法可见 - 级数生成函数 + 序列生成函数 @@ -12205,7 +12161,7 @@ SELECT generate_series(1.1, 4, 1.3); 3.7 (3 rows) --- this example relies on the date-plus-integer operator +-- 此示例使用日期加整数的操作符 SELECT current_date + s.a AS dates FROM generate_series(0,14,7) AS s(a); dates ------------ @@ -12265,7 +12221,7 @@ SELECT * FROM generate_series('2008-03-01 00:00'::timestamp, generate_subscripts是一个便利函数,用于生成给定数组在指定维度上的有效下标集合。对于没有所请求维度的数组或 NULL 数组,返回零行(但数组中的 NULL 元素仍会返回有效下标)。下面是一些示例: --- basic usage +-- 基本用法 SELECT generate_subscripts('{NULL,1,NULL,2}'::int[], 1) AS s; s --- @@ -12275,8 +12231,8 @@ SELECT generate_subscripts('{NULL,1,NULL,2}'::int[], 1) AS s; 4 (4 rows) --- presenting an array, the subscript and the subscripted --- value requires a subquery +-- 展示数组、下标和下标对应的值 +-- 需要使用子查询 SELECT * FROM arrays; a -------------------- @@ -12295,7 +12251,7 @@ FROM (SELECT generate_subscripts(a, 1) AS s, a FROM arrays) foo; {100,200,300} | 3 | 300 (5 rows) --- unnest a 2D array +-- 展开二维数组 CREATE OR REPLACE FUNCTION unnest2(anyarray) RETURNS SETOF anyelement AS $$ select $1[i][j] @@ -12315,13 +12271,13 @@ SELECT * FROM unnest2(ARRAY[[1,2],[3,4]]); - ordinality + 序号 FROM子句中的函数后面加上WITH ORDINALITY时,一个bigint列会追加到输出中,其值从 1 开始,对函数输出的每一行递增 1。这种方式对集合返回函数尤其有用,例如unnest() --- set returning function WITH ORDINALITY +-- 集合返回函数与 WITH ORDINALITY SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); ls | n -----------------+---- @@ -12354,7 +12310,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); 系统信息函数和操作符 - 展示了多个可以抽取会话和系统信息的函数。 + 列出了多个用于提取会话和系统信息的函数。 @@ -12445,7 +12401,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); pg_blocking_pids(int) int[] - 阻止指定服务器进程 ID 获取锁的进程 ID + 阻止指定服务器进程获取锁的进程 ID @@ -12499,7 +12455,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); pg_safe_snapshot_blocking_pids(int) int[] - 阻止指定服务器进程 ID 获取安全快照的进程 ID + 阻止指定服务器进程获取安全快照的进程 ID @@ -12531,8 +12487,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); - current_catalogcurrent_rolecurrent_schemacurrent_usersession_useruserSQL里有特殊的语法地位: 它们被调用时结尾不要跟着圆括号。 - 在 PostgreSQL 中,圆括号可以有选择性地被用于current_schema,但是不能和其他的一起用。 + current_catalogcurrent_rolecurrent_schemacurrent_usersession_useruserSQL中具有特殊语法:调用时不得在后面加圆括号。在 PostgreSQL 中,current_schema可以选择加圆括号,其他函数则不可以。 @@ -12569,13 +12524,13 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); - schema - current + 模式 + 当前 - search path - current + 搜索路径 + 当前 @@ -12583,8 +12538,8 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); - user - current + 用户 + 当前 @@ -12592,11 +12547,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); - session_user通常是发起当前数据库连接的用户,不过超级用户可以用修改这个设置。 - current_user是用于权限检查的用户标识。通常, 它总是等于会话用户,但是可以被改变。 - 它也会在函数执行的过程中随着属性SECURITY DEFINER的改变而改变。 - 在 Unix 的说法里,那么会话用户是真实用户,而当前用户是有效用户。 - current_role以及usercurrent_user的同义词(SQL标准在current_rolecurrent_user之间做了区分,但PostgreSQL不区分,因为它把用户和角色统一成了一种实体)。 + session_user通常是发起当前数据库连接的用户,但超级用户可以用修改此设置。current_user是用于权限检查的用户标识,通常等于会话用户,但可以用更改。在执行具有SECURITY DEFINER属性的函数期间,它也会改变。用 Unix 的术语来说,会话用户是真实用户,当前用户是有效用户current_roleusercurrent_user的同义词。(SQL 标准区分current_rolecurrent_user,但PostgreSQL不区分,因为它将用户和角色统一为同一种实体。) current_schema 返回搜索路径中第一个模式的名称(如果搜索路径为空,则返回空值)。在创建表或其他命名对象时,如果未指定目标模式,就会使用该模式。current_schemas(boolean) 返回当前搜索路径中所有模式名称的数组。布尔选项决定是否在返回的搜索路径中包含 pg_catalog 等隐式包含的系统模式。 @@ -12643,18 +12594,18 @@ SET search_path TO schema , sc - Logging - pg_current_logfile函数 + 日志记录 + pg_current_logfile 函数 current_logfiles - 和pg_current_logfile函数 + 和pg_current_logfile 函数 - Logging - current_logfiles文件和pg_current_logfile函数 + 日志记录 + current_logfiles 文件和pg_current_logfile 函数 pg_current_logfiletext 返回日志收集器当前使用的日志文件路径。路径包括 目录和日志文件名。必须启用日志收集,否则返回值为 NULL。当存在多个格式不同的日志文件时,不带参数调用 pg_current_logfile 会按 stderrcsvlog 的顺序查找,返回找到的第一个格式的文件路径。如果没有任何日志文件采用这些格式,则返回 NULL。要请求特定文件格式,可向可选参数传入 text 类型的 csvlogstderr。如果请求的日志格式未配置在 中,返回值为 NULLpg_current_logfile 反映 current_logfiles 文件的内容。 @@ -12698,8 +12649,8 @@ SET search_path TO schema , sc version 返回一个描述 PostgreSQL 服务器版本的字符串。也可以通过 获取此信息,或者通过 获取机器可读的版本。软件开发者应使用 server_version_num(自 8.2 起提供)或 ,而不是解析文本版本。 - privilege - querying + 权限 + 查询 列出了允许用户以编程方式查询对象访问权限的函数。关于权限的更多信息,请参见 @@ -12718,14 +12669,14 @@ SET search_path TO schema , sc privilege) boolean - 用户是否对表的任意列具有权限 + 用户是否对表的至少一列具有权限 has_any_column_privilege(table, privilege) boolean - 当前用户是否对表的任意列具有权限 + 当前用户是否对表的至少一列具有权限 has_column_privilege(user, @@ -12974,7 +12925,7 @@ SELECT has_table_privilege('joe', 'mytable', 'INSERT, SELECT WITH GRANT OPTION') has_sequence_privilege 检查用户是否可以以某种方式访问序列。其参数形式与 has_table_privilege 类似。所需访问权限类型必须为 USAGESELECTUPDATE 之一。 - has_any_column_privilege 检查用户是否可以以某种方式访问表的任意列。其参数形式与 has_table_privilege 类似,但所需访问权限类型必须为 SELECTINSERTUPDATEREFERENCES 的某种组合。注意,在表级别拥有这些权限中的任意一种,就隐式地对表的每一列拥有该权限,因此对于相同参数,如果 has_table_privilege 返回 truehas_any_column_privilege 也总是返回真。但是,只要至少有一列获得该权限的列级授权,has_any_column_privilege 也会成功。 + has_any_column_privilege 检查用户是否可以以某种方式访问表的至少一列。其参数形式与 has_table_privilege 类似,但所需访问权限类型必须为 SELECTINSERTUPDATEREFERENCES 的某种组合。注意,在表级别拥有这些权限中的任意一种,就隐式地对表的每一列拥有该权限,因此对于相同参数,如果 has_table_privilege 返回 truehas_any_column_privilege 也总是返回真。但是,只要至少有一列获得该权限的列级授权,has_any_column_privilege 也会成功。 has_column_privilege 检查用户是否可以以某种方式访问列。其参数形式与 has_table_privilege 类似,但还可以通过列名或属性编号指定列。所需访问权限类型必须为 SELECTINSERTUPDATEREFERENCES 的某种组合。注意,在表级别拥有这些权限中的任意一种,就隐式地对表的每一列拥有该权限。 @@ -13003,8 +12954,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); row_security_active 检查在 current_user 和当前环境的上下文中,指定表的行级安全性是否生效。可以通过名称或 OID 指定表。 - 显示了aclitem类型的可用操作符,它是访问权限的目录表示。 - 有关如何读取访问权限值的信息,请参阅 。 + 列出了aclitem类型可用的操作符;该类型是访问权限在系统目录中的表示形式。有关如何解读访问权限值的信息,请参见 @@ -13062,7 +13012,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute');
- 显示了一些额外的函数来管理aclitem类型。 + 列出了一些用于管理aclitem类型的其他函数。 @@ -13094,7 +13044,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); acldefault 返回属于角色 ownerId、类型为 type 的对象的内置默认访问权限。当对象的 ACL 条目为空值时,会采用这些访问权限。(默认访问权限见。)type 参数的类型为 CHAR:'c' 表示 COLUMN,'r' 表示 TABLE 和类似表的对象,'s' 表示 SEQUENCE,'d' 表示 DATABASE,'f' 表示 FUNCTIONPROCEDURE,'l' 表示 LANGUAGE,'L' 表示 LARGE OBJECT,'n' 表示 SCHEMA,'t' 表示 TABLESPACE,'F' 表示 FOREIGN DATA WRAPPER,'S' 表示 FOREIGN SERVER,'T' 表示 TYPEDOMAIN - aclexplode 将一个 aclitem 数组返回为行集合。输出列依次为授予者的 oid、受让者的 oid0 表示 PUBLIC)、以 text 表示的所授予权限(SELECT 等),以及以 boolean 表示的该权限是否可以转授。makeaclitem 执行相反的操作。 + aclexplode 将一个 aclitem 数组返回为行集合。输出列依次为授权者的 oid、被授权者的 oid0 表示 PUBLIC)、以 text 表示的所授予权限(SELECT 等),以及以 boolean 表示的该权限是否可以转授。makeaclitem 执行相反的操作。 列出了判断某个特定对象是否可见的函数,其判断依据是当前模式搜索路径。例如,如果表所在的模式位于搜索路径中,并且在搜索路径的更前面没有同名表,就称该表可见。这等价于说,可以只通过表名引用该表,而不必显式地用模式限定。要列出所有可见表的名称: @@ -13158,22 +13108,22 @@ SELECT relname FROM pg_class WHERE pg_table_is_visible(oid); pg_ts_config_is_visible(config_oid) boolean - 全文搜索配置是否在搜索路径中可见 + 全文检索配置是否在搜索路径中可见 pg_ts_dict_is_visible(dict_oid) boolean - 全文搜索词典是否在搜索路径中可见 + 全文检索词典是否在搜索路径中可见 pg_ts_parser_is_visible(parser_oid) boolean - 全文搜索解析器是否在搜索路径中可见 + 全文检索解析器是否在搜索路径中可见 pg_ts_template_is_visible(template_oid) boolean - 全文搜索模板是否在搜索路径中可见 + 全文检索模板是否在搜索路径中可见 pg_type_is_visible(type_oid) @@ -13385,12 +13335,12 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); pg_get_expr(pg_node_tree, relation_oid) text - 反编译表达式的内部形式,假定其中所有 Var 都引用第二个参数指定的关系 + 反编译表达式的内部形式,假定其中所有 Var 节点都引用第二个参数指定的关系 pg_get_expr(pg_node_tree, relation_oid, pretty_bool) text - 反编译表达式的内部形式,假定其中所有 Var 都引用第二个参数指定的关系 + 反编译表达式的内部形式,假定其中所有 Var 节点都引用第二个参数指定的关系 pg_get_functiondef(func_oid) @@ -13575,12 +13525,12 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); pg_get_keywords 返回一组记录,描述服务器识别的 SQL 关键字。word 列包含关键字。catcode 列包含类别代码:U 表示非保留关键字,C 表示列名,T 表示类型名或函数名,R 表示保留关键字。catdesc 列包含描述该类别的字符串,该字符串可能已经过本地化。 - pg_get_constraintdefpg_get_indexdefpg_get_ruledefpg_get_statisticsobjdefpg_get_triggerdef 分别重建约束、索引、规则、扩展统计对象或触发器的创建命令。(注意,这是通过反编译重建的,并非命令的原始文本。)pg_get_expr 反编译单个表达式的内部形式,例如列的默认值。这在检查系统目录内容时可能很有用。如果表达式可能包含 Vars,请将它们所引用的关系的 OID 指定为第二个参数;如果预计不含 Vars,传入零即可。pg_get_viewdef 重建定义视图的 SELECT 查询。这些函数中的大多数有两种变体,其中一种可以选择美化输出结果。美化格式更易读,但默认格式更可能被未来版本的 PostgreSQL 以相同方式解释;转储时应避免使用美化输出。向美化输出参数传入 false,所得结果与完全没有该参数的变体相同。 + pg_get_constraintdefpg_get_indexdefpg_get_ruledefpg_get_statisticsobjdefpg_get_triggerdef 分别重建约束、索引、规则、扩展统计信息对象或触发器的创建命令。(注意,这是通过反编译重建的,并非命令的原始文本。)pg_get_expr 反编译单个表达式的内部形式,例如列的默认值。这在检查系统目录内容时可能很有用。如果表达式可能包含 Var 节点,请将它们所引用的关系的 OID 指定为第二个参数;如果预计不含 Var 节点,传入零即可。pg_get_viewdef 重建定义视图的 SELECT 查询。这些函数中的大多数有两种变体,其中一种可以选择美化输出结果。美化格式更易读,但默认格式更可能被未来版本的 PostgreSQL 以相同方式解释;转储时应避免使用美化输出。向美化输出参数传入 false,所得结果与完全没有该参数的变体相同。 pg_get_functiondef 返回一个函数的完整 CREATE OR REPLACE FUNCTION 语句。pg_get_function_argumentsCREATE FUNCTION 中所需的形式返回函数参数列表。pg_get_function_result 类似地返回该函数相应的 RETURNS 子句。pg_get_function_identity_arguments 返回标识函数所需的参数列表,例如以 ALTER FUNCTION 中所需的形式返回。此形式省略默认值。 - pg_get_serial_sequence返回与列关联的序列名称;如果该列没有关联序列,则返回 NULL。如果列是标识列,关联序列就是为标识列在内部创建的序列。对于使用某种串行类型(serialsmallserialbigserial)创建的列,关联序列就是为该串行列定义创建的序列。在后一种情况下,可以使用ALTER SEQUENCE OWNED BY修改或移除这种关联。(该函数也许应该叫作pg_get_owned_sequence;它当前的名称反映了它通常用于serialbigserial列这一事实。)第一个输入参数是可以带有模式名的表名,第二个参数是列名。由于第一个参数可能包含模式和表,它不会被当作双引号括起的标识符处理,因此默认转换为小写;第二个参数只包含列名,会被当作带双引号的标识符处理并保留大小写。函数返回的值采用适于传递给序列函数的格式(参见)。典型用法是读取标识列或串行列的序列当前值,例如: + pg_get_serial_sequence返回与列关联的序列名称;如果该列没有关联序列,则返回 NULL。如果列是标识列,关联序列就是为标识列在内部创建的序列。对于使用某种 serial 类型(serialsmallserialbigserial)创建的列,关联序列就是为该 serial 列定义创建的序列。在后一种情况下,可以使用ALTER SEQUENCE OWNED BY修改或移除这种关联。(该函数也许应该叫作pg_get_owned_sequence;它当前的名称反映了它通常用于serialbigserial列这一事实。)第一个输入参数是可以带有模式名的表名,第二个参数是列名。由于第一个参数可能包含模式和表,它不会被当作双引号括起的标识符处理,因此默认转换为小写;第二个参数只包含列名,会被当作带双引号的标识符处理并保留大小写。函数返回的值采用适于传递给序列函数的格式(参见)。典型用法是读取标识列或 serial 列的序列当前值,例如: SELECT currval(pg_get_serial_sequence('sometable', 'id')); @@ -13631,19 +13581,20 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); distance_orderable - 列能否通过一个distance操作符(例如ORDER BY col <-> constant)有序地扫描? + + 能否按距离操作符的结果有序地扫描该列,例如ORDER BY col <-> constant returnable - 列值是否可以通过一次只用索引扫描返回? + 列值是否可以通过一次仅索引扫描返回? search_array - 列是否天然支持col = ANY(array)搜索? + 列是否原生支持col = ANY(array)搜索? @@ -13658,7 +13609,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id'));
- 索引性质 + 索引属性 @@ -13695,7 +13646,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id'));
- 索引访问方法性质 + 索引访问方法属性 @@ -13790,12 +13741,11 @@ SELECT collation for ('foo' COLLATE "de_DE"); - 列出了与数据库对象 - 标识和定位有关的函数。 + 列出了与数据库对象标识和寻址有关的函数。
- 对象信息和定位函数 + 对象信息和寻址函数 名称 返回类型 描述 @@ -13826,7 +13776,7 @@ SELECT collation for ('foo' COLLATE "de_DE");
- pg_describe_object 返回数据库对象的文本描述,对象由系统目录 OID、对象 OID 和子对象 ID 指定(例如表中的列号;引用整个对象时,子对象 ID 为零)。该描述供人阅读,并可能根据服务器配置被翻译。这有助于确定存储在 pg_depend 系统目录中的对象身份。 + pg_describe_object 返回数据库对象的文本描述,对象由系统目录 OID、对象 OID 和子对象 ID 指定(例如表中的列号;引用整个对象时,子对象 ID 为零)。该描述供人阅读,并可能根据服务器配置被翻译。这有助于确定存储在 pg_depend 系统目录中的对象标识。 pg_identify_object 返回一行,其中包含足以唯一标识数据库对象的信息,该对象由系统目录 OID、对象 OID 和子对象 ID 指定。这些信息供机器读取,永远不会被翻译。type 标识数据库对象的类型;schema 是对象所属的模式名,对于不属于模式的对象类型则为 NULL;如果对象名(以及适用时的模式名)足以唯一标识该对象,name 就是对象名,并在必要时加引号,否则为 NULLidentity 是完整的对象标识,其具体格式取决于对象类型,格式中的每个名称都会根据需要加上模式限定和引号。 @@ -13852,7 +13802,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); - 中展示的函数抽取注释,注释是由命令在以前存储的。如果对指定参数找不到注释,则返回空值。 + 中的函数用于提取此前通过命令存储的注释。如果找不到与指定参数对应的注释,则返回空值。 @@ -14080,7 +14030,7 @@ SELECT collation for ('foo' COLLATE "de_DE");
- pg_control_checkpoint 返回一条记录,其内容见 + pg_control_checkpoint 返回一条记录,其内容见 <function>pg_control_checkpoint</function> 输出列 @@ -14189,7 +14139,7 @@ SELECT collation for ('foo' COLLATE "de_DE");
- pg_control_system 返回一条记录,其内容见 + pg_control_system 返回一条记录,其内容见 <function>pg_control_system</function> 输出列 @@ -14228,7 +14178,7 @@ SELECT collation for ('foo' COLLATE "de_DE");
- pg_control_init 返回一条记录,其内容见 + pg_control_init 返回一条记录,其内容见 <function>pg_control_init</function> 输出列 @@ -14307,7 +14257,7 @@ SELECT collation for ('foo' COLLATE "de_DE");
- pg_control_recovery 返回一条记录,其内容见 + pg_control_recovery 返回一条记录,其内容见 <function>pg_control_recovery</function> 输出列 @@ -14398,19 +14348,19 @@ SELECT collation for ('foo' COLLATE "de_DE"); - configuration - of the server - functions + 配置 + 服务器 + 函数 - 函数current_setting返回以下设置的当前值:setting_name。它对应于SQL命令SHOW。例如: + 函数current_setting返回设置setting_name的当前值。它对应于SQL命令SHOW。例如: SELECT current_setting('datestyle'); current_setting ----------------- ISO, MDY (1 row) -如果不存在以下名称的设置:setting_name, +如果不存在名为setting_name的设置, current_setting会报错,除非提供了missing_ok且其值为true @@ -14449,7 +14399,7 @@ SELECT set_config('log_statement_stats', 'off', false); - 在中展示的函数向其它服务器进程发送控制信号。默认情况下这些函数只能被超级用户使用,但是如果需要,可以利用GRANT把访问权限授予给其他用户。 + 在中展示的函数向其它服务器进程发送控制信号。默认情况下这些函数只能被超级用户使用,但是如果需要,可以利用GRANT把访问权限授予给其他用户(注明的例外除外)。
@@ -14493,7 +14443,7 @@ SELECT set_config('log_statement_stats', 'off', false); pg_cancel_backendpg_terminate_backend向由进程 ID 标识的后端进程发送信号(分别是SIGINTSIGTERM)。 - 一个活动后端的进程 ID可以从pg_stat_activity视图的pid列中找到,或者通过在服务器上列出postgres进程(在 Unix 上使用ps或者在Windows上使用Task Manager)得到。 + 一个活动后端的进程 ID可以从pg_stat_activity视图的pid列中找到,或者通过在服务器上列出postgres进程(在 Unix 上使用ps或者在Windows上使用任务管理器)得到。 一个活动后端的角色可以在pg_stat_activity视图的usename列中找到。 @@ -14507,7 +14457,7 @@ SELECT set_config('log_statement_stats', 'off', false); 备份控制函数 - backup + 备份 pg_create_restore_point @@ -14556,7 +14506,7 @@ SELECT set_config('log_statement_stats', 'off', false); pg_create_restore_point(name text) pg_lsn - 创建用于还原的命名点(默认仅限超级用户,但可以向其他用户授予 EXECUTE 权限以运行此函数) + 创建用于恢复的命名点(默认仅限超级用户,但可以向其他用户授予EXECUTE权限以运行此函数) @@ -14582,19 +14532,19 @@ SELECT set_config('log_statement_stats', 'off', false); pg_start_backup(label text , fast boolean , exclusive boolean ) pg_lsn - 准备执行在线备份(默认仅限超级用户,但可以向其他用户授予 EXECUTE 权限以运行此函数) + 准备执行在线备份(默认仅限超级用户,但可以向其他用户授予EXECUTE权限以运行此函数) pg_stop_backup() pg_lsn - 结束排他在线备份(默认仅限超级用户,但可以向其他用户授予 EXECUTE 权限以运行此函数) + 结束排他在线备份(默认仅限超级用户,但可以向其他用户授予EXECUTE权限以运行此函数) pg_stop_backup(exclusive boolean , wait_for_archive boolean ) setof record - 结束排他或非排他在线备份(默认仅限超级用户,但可以向其他用户授予 EXECUTE 权限以运行此函数) + 结束排他或非排他在线备份(默认仅限超级用户,但可以向其他用户授予EXECUTE权限以运行此函数) @@ -14615,7 +14565,7 @@ SELECT set_config('log_statement_stats', 'off', false); pg_switch_wal() pg_lsn - 强制切换到新的预写式日志文件(默认仅限超级用户,但可以向其他用户授予 EXECUTE 权限以运行此函数) + 强制切换到新的预写式日志文件(默认仅限超级用户,但可以向其他用户授予EXECUTE权限以运行此函数) pg_walfile_name(lsn pg_lsn) @@ -14747,7 +14697,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); - 控制恢复进度的功能如 所示。这些函数只能在恢复过程中执行。 + 列出的函数用于控制恢复进度。这些函数只能在恢复期间执行。
@@ -14769,21 +14719,21 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); pg_promote(wait boolean DEFAULT true, wait_seconds integer DEFAULT 60) boolean - 提升物理备库服务器。当 waittrue(默认值)时,函数等待提升完成或经过 wait_seconds 秒;提升成功时返回 true,否则返回 false。如果 waitfalse,函数向 postmaster 发送 SIGUSR1 以触发提升后,立即返回 true。默认情况下,此函数仅限超级用户使用,但可以向其他用户授予 EXECUTE 权限以运行它。 + 提升物理备库服务器。当 waittrue(默认值)时,函数等待提升完成或经过 wait_seconds 秒;提升成功时返回 true,否则返回 false。如果 waitfalse,函数向 postmaster 发送 SIGUSR1 以触发提升后,立即返回 true。默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 pg_wal_replay_pause() void - 立即暂停恢复(默认仅限超级用户,但可以向其他用户授予 EXECUTE 权限以运行此函数)。 + 立即暂停恢复(默认仅限超级用户,但可以向其他用户授予EXECUTE权限以运行此函数)。 pg_wal_replay_resume() void - 如果恢复已暂停,则重新开始恢复(默认仅限超级用户,但可以向其他用户授予 EXECUTE 权限以运行此函数)。 + 如果恢复已暂停,则重新开始恢复(默认仅限超级用户,但可以向其他用户授予EXECUTE权限以运行此函数)。 @@ -14810,7 +14760,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); - 为了解决这个问题,PostgreSQL允许一个事务导出它正在使用的快照。只要导出的事务仍然保持打开,其他事务可以导入它的快照,并且因此可以保证它们可以看到和第一个事务看到的完全一样的数据库视图。但是注意这些事务中的任何一个对数据库所作的更改对其他事务仍然保持不可见,和未提交事务所作的修改一样。因此这些事务是针对以前存在的数据同步,而对由它们自己所作的更改则采取正常的动作。 + 为了解决这个问题,PostgreSQL允许一个事务导出它正在使用的快照。只要导出快照的事务仍然保持打开,其他事务可以导入它的快照,并且因此可以保证它们可以看到和第一个事务看到的完全一样的数据库视图。但是注意这些事务中的任何一个对数据库所作的更改对其他事务仍然保持不可见,和未提交事务所作的修改一样。因此这些事务是针对以前存在的数据同步,而对由它们自己所作的更改则采取正常的动作。 @@ -14898,7 +14848,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); 将一个名为src_slot_name的现有物理复制槽复制到一个名为dst_slot_name的物理复制槽。 - 被复制的物理槽开始从与源槽相同的LSN开始保留WAL。temporary是可选的。 + 复制后的物理槽从与源槽相同的LSN开始保留WAL。temporary是可选的。 如果省略了temporary,则使用与源槽相同的值。 @@ -15191,7 +15141,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); 上述操作表和索引的函数接受一个regclass参数,它是该表或索引在pg_class系统目录中的 OID。 你不必手工去查找该 OID,因为regclass数据类型的输入转换器会为你代劳。 - 只写包围在单引号内的表名,这样它看起来像一个文字常量。 + 只写包围在单引号内的表名,这样它看起来像一个字面量。 为了与普通SQL名称的处理相兼容,该字符串将被转换为小写形式,除非其中在表名周围包含双引号。 @@ -15273,7 +15223,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); pg_collation_actual_version 返回当前安装在操作系统中的排序规则对象的实际版本。如果它与 pg_collation.collversion 中的值不同,则可能需要重建依赖该排序规则的对象。另见 - pg_import_system_collations 根据操作系统中找到的所有区域环境,向系统目录 pg_collation 添加排序规则。initdb 使用的就是此函数;更多信息见。如果以后在操作系统中安装了其他区域环境,可以再次运行此函数,为新区域环境添加排序规则。与 pg_collation 中现有条目匹配的区域环境会被跳过。(但此函数不会删除基于操作系统中已不存在的区域环境的排序规则对象。)schema 参数通常为 pg_catalog,但并非必须如此;也可以将排序规则安装到其他模式中。函数返回新建的排序规则对象数量。此函数仅限超级用户使用。 + pg_import_system_collations 根据操作系统中找到的所有区域设置,向系统目录 pg_collation 添加排序规则。initdb 使用的就是此函数;更多信息见。如果以后在操作系统中安装了其他区域设置,可以再次运行此函数,为新区域设置添加排序规则。与 pg_collation 中现有条目匹配的区域设置会被跳过。(但此函数不会删除基于操作系统中已不存在的区域设置的排序规则对象。)schema 参数通常为 pg_catalog,但并非必须如此;也可以将排序规则安装到其他模式中。函数返回新建的排序规则对象数量。此函数仅限超级用户使用。
分区信息函数 @@ -15368,7 +15318,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup());
- brin_summarize_new_values 接受 BRIN 索引的 OID 或名称,检查索引,找出基表中尚未被索引汇总的页面范围;对于每个这样的范围,它通过扫描表页面创建新的汇总索引元组。函数返回插入索引的新页面范围汇总数量。brin_summarize_range 执行相同的操作,但只汇总覆盖给定块号的范围。 + brin_summarize_new_values 接受 BRIN 索引的 OID 或名称,检查索引,找出基表中尚未生成索引摘要的页面范围;对于每个这样的范围,它通过扫描表页面创建新的摘要索引元组。函数返回插入索引的新页面范围摘要数量。brin_summarize_range 执行相同的操作,但只对覆盖给定块号的范围生成摘要。 gin_clean_pending_list 接受 GIN 索引的 OID 或名称,通过将待处理列表中的条目批量移到主 GIN 数据结构中,清理指定索引的待处理列表。它返回从待处理列表中移除的页面数。注意,如果参数是禁用了 fastupdate 选项的 GIN 索引,则不执行清理并返回 0,因为该索引没有待处理列表。关于待处理列表和 fastupdate 选项的详细信息,请参见 @@ -15379,7 +15329,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); 中展示的函数提供了对数据库服务器所在机器上的文件的本地访问。 - 只能访问数据库集簇目录以及log_directory中的文件,除非用户被授予了角色pg_read_server_files。 + 只能访问数据库集簇目录以及log_directory中的文件,除非用户被授予了角色pg_read_server_files。 使用相对路径访问集簇目录里面的文件,以及匹配 log_directory配置设置的路径访问日志文件。 @@ -15397,7 +15347,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); pg_ls_dir(dirname text [, missing_ok boolean, include_dot_dirs boolean]) setof text - 列出目录内容。默认仅限超级用户,但可以向其他用户授予 EXECUTE 权限以运行此函数。 + 列出目录内容。默认仅限超级用户,但可以向其他用户授予EXECUTE权限以运行此函数。 @@ -15428,17 +15378,17 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); pg_read_file(filename text [, offset bigint, length bigint [, missing_ok boolean] ]) text - 返回文本文件的内容。默认仅限超级用户,但可以向其他用户授予 EXECUTE 权限以运行此函数。 + 返回文本文件的内容。默认仅限超级用户,但可以向其他用户授予EXECUTE权限以运行此函数。 pg_read_binary_file(filename text [, offset bigint, length bigint [, missing_ok boolean] ]) bytea - 返回文件内容。默认仅限超级用户,但可以向其他用户授予 EXECUTE 权限以运行此函数。 + 返回文件内容。默认仅限超级用户,但可以向其他用户授予EXECUTE权限以运行此函数。 pg_stat_file(filename text[, missing_ok boolean]) record - 返回文件信息。默认仅限超级用户,但可以向其他用户授予 EXECUTE 权限以运行此函数。 + 返回文件信息。默认仅限超级用户,但可以向其他用户授予EXECUTE权限以运行此函数。 @@ -15709,7 +15659,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); 事件触发器函数 - PostgreSQL提供了这些助手函数来从事件触发器检索信息。 + PostgreSQL提供了这些辅助函数来从事件触发器检索信息。 @@ -15726,7 +15676,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); 当在一个ddl_command_end事件触发器的函数中调用时,pg_event_trigger_ddl_commands返回被每一个用户动作执行的DDL命令的列表。 如果在其他任何环境中调用这个函数,会发生错误。 - pg_event_trigger_ddl_commands为每一个被执行的基本命令返回一行,某些只有一个单一 SQL 句子的命令可能会返回多于一行。 + pg_event_trigger_ddl_commands为每一个被执行的基本命令返回一行,某些由单条 SQL 语句构成的命令可能会返回多于一行。 这个函数返回下面的列: @@ -15743,7 +15693,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); classid oid - 对象所属的目录的 OID + 对象所属系统目录的 OID objid @@ -15753,7 +15703,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); objsubid integer - 对象的子-id(例如列的属性号) + 子对象 ID(例如列的属性编号) command_tag @@ -15769,16 +15719,14 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); schema_name text - 该对象所属的模式的名称(如果有),如果没有则为NULL。 - 没有引号。 + 对象所属模式的名称(若有);否则为NULL。不加引号。 object_identity text - 对象标识的文本表现形式,用模式限定。如果必要,出现在 - 该标识中的每一个标识符都会加上引号。 + 对象标识的文本表示形式,带模式限定。标识中包含的每个标识符在必要时都会加引号。 @@ -15790,8 +15738,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); command pg_ddl_command - 以内部格式表达的该命令的一个完整表现形式。这不能被直接输出, - 但是可以把它传递给其他函数来得到有关于该命令不同部分的信息。 + 命令的完整内部表示,不能直接输出,但可以将其传给其他函数以获取关于该命令的不同信息。 @@ -15822,7 +15769,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); classid oid - 对象所属的目录的 OID + 对象原先所属系统目录的 OID objid @@ -15832,7 +15779,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); objsubid integer - 子对象ID(如列的属性号) + 子对象 ID(例如列的属性编号) original @@ -15843,7 +15790,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); normal bool - 指示在依赖图中有一个普通依赖关系指向该对象的标志 + 如果依赖图中存在指向该对象的普通依赖关系,则为真。 @@ -15862,29 +15809,28 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); schema_name text - 对象所属模式的名称(如果存在);否则为NULL。不加引号。 + 对象原先所属模式的名称(若有);否则为NULL。不加引号。 object_name text - 如果模式和名称的组合能被用于对象的一个唯一标识符,则是对象的名称;否则是NULL。不加引号,并且名称不是模式限定的。 + 如果模式和名称的组合可用作该对象的唯一标识符,则为对象名称;否则为NULL。不加引号,并且该名称永远不带模式限定。 object_identity text - 带模式限定的对象标识的文本表示。其中的每个标识符都会在必要时加引号。 + 对象标识的文本表示形式,带模式限定。标识中包含的每个标识符在必要时都会加引号。 address_names text[] - 一个数组,它可以和object_typeaddress_args, - 一起通过pg_get_object_address()函数在一台包含有同类相同名称对象的远程服务器上重建该对象地址。 + 一个数组,可与object_typeaddress_args一起,通过pg_get_object_address()函数在包含同类同名对象的远程服务器上重建该对象地址。 @@ -15979,12 +15925,12 @@ CREATE EVENT TRIGGER test_table_rewrite_oid 统计信息函数 - function - statistics + 函数 + 统计信息 - PostgreSQL提供了一个函数来检查使用CREATE STATISTICS命令定义的复杂统计。 + PostgreSQL提供了一个函数来检查使用CREATE STATISTICS命令定义的复杂统计信息。 diff --git a/zh/12/gin.sgml b/zh/12/gin.sgml index 7feee7e4..364a13b9 100644 --- a/zh/12/gin.sgml +++ b/zh/12/gin.sgml @@ -53,7 +53,7 @@ 内置操作符类 - PostgreSQL 核心发布包含 + PostgreSQL 核心发行版包含 所示的 GIN 操作符类。 (在 中描述的一些可选模块还提供额外的 GIN 操作符类。) @@ -64,7 +64,7 @@ 名称 - 索引数据类型 + 被索引数据类型 可索引操作符 @@ -129,7 +129,10 @@ GIN 将可扩展性与通用性、代码重用以及清晰的接口结合在一起。 - GIN中,操作符类必须提供以下两个方法: + + GIN 操作符类必须提供两个方法: + + Datum *extractValue(Datum itemValue, int32 *nkeys, bool **nullFlags) @@ -138,7 +141,7 @@ 给定一个要建立索引的项,返回一个用 palloc 分配的键数组。返回键的数量必须存入 *nkeys。如果任一键可以为 null,还要另外 palloc 一个包含 *nkeysbool 字段的数组,将其地址存入 - *nullFlags,并按需设置这些空值标志。如果所有键都非空, + *nullFlags,并按需设置这些空值标志。如果所有键都不是 null, *nullFlags 可以保持为 NULL(其初始值)。 如果该项不包含任何键,则返回值可以为 NULL @@ -158,7 +161,7 @@ query 的数据类型,以及应采用何种方法提取键值。返回键的数量必须存入 *nkeys。如果任一键可以为 null,还要另外 palloc 一个包含 *nkeysbool 字段的数组,将其地址存入 - *nullFlags,并按需设置这些空值标志。如果所有键都非空, + *nullFlags,并按需设置这些空值标志。如果所有键都不是 null, *nullFlags 可以保持为 NULL(其初始值)。 如果 query 不包含任何键,则返回值可以为 NULL @@ -171,7 +174,7 @@ 被设置为 GIN_SEARCH_MODE_INCLUDE_EMPTY,则除至少包含一个匹配键的项之外, 完全不含任何键的项也会被视为候选匹配。(例如,该模式对于实现是子集操作符很有用。) 若 *searchMode 被设置为 GIN_SEARCH_MODE_ALL, - 则索引中所有非空项都会被视为候选匹配,无论它们是否匹配任一返回键。 + 则索引中所有非 null 项都会被视为候选匹配,无论它们是否匹配任一返回键。 (该模式比前两种选择慢得多,因为它基本上需要扫描整个索引;但为了正确处理某些边界情况, 可能有此必要。在大多数情况下都需要此模式的操作符,大概并不适合作为 GIN 操作符类的候选。)用于设置该模式的符号定义在 @@ -199,7 +202,15 @@ - 操作符类还必须提供一个函数,用于检查被索引项是否匹配查询。它有两种形式:布尔型consistent函数和三值triConsistent函数。triConsistent涵盖两者的功能,因此只提供triConsistent即可。不过,如果布尔版本的计算代价明显更低,同时提供两者可能更有利。如果只提供布尔版本,则会禁用某些优化,这些优化依赖于在获取所有键之前排除不匹配的索引项。 + + + 操作符类还必须提供一个函数,用于检查被索引项是否匹配查询。它有两种形式:布尔型 + consistent 函数,以及三值型 triConsistent 函数。 + triConsistent 覆盖了两者的功能,因此仅提供 triConsistent + 就已经足够。不过,如果布尔变体的计算代价明显更低,那么同时提供两者可能更有利。 + 若只提供布尔变体,则一些依赖于在取回所有键之前先排除索引项的优化将被禁用。 + + bool consistent(bool check[], StrategyNumber n, Datum query, int32 nkeys, Pointer extra_data[], bool *recheck, @@ -211,10 +222,10 @@ 该函数无法直接访问被索引项的值,因为 GIN 并不显式存储项。 它所能利用的是这样一种信息:从查询中提取出的哪些键值出现在给定的被索引项中。 check 数组长度为 nkeys,这与先前针对该 - query 数据由 extractQuery 返回的键数量相同。 + query datum 由 extractQuery 返回的键数量相同。 如果被索引项包含相应查询键,则 check 数组中的对应元素为 true; 也就是说,如果 (check[i] == true),则 extractQuery - 结果数组中的第 i 个键存在于该被索引项中。传入原始 query 数据值, + 结果数组中的第 i 个键存在于该被索引项中。传入原始 query datum, 是为了让 consistent 方法在需要时可以查看它;同样也会传入先前由 extractQuery 返回的 queryKeys[]nullFlags[] 数组。extra_data 则是 @@ -252,7 +263,7 @@ 而 GIN_MAYBE 表示该键是否存在尚不确定。存在 GIN_MAYBE 值时,只有当无论索引项是否包含对应查询键,该项都确定匹配时,函数才应返回 GIN_TRUE。同样,只有当无论是否包含 GIN_MAYBE 键, - 该项都确定不匹配时,函数才必须返回 GIN_FALSE。如果结果依赖于 + 该项都确定不匹配时,函数才能返回 GIN_FALSE。如果结果依赖于 GIN_MAYBE 条目,也就是说,无法根据已知的查询键确认或否定匹配, 则函数必须返回 GIN_MAYBE @@ -266,7 +277,11 @@
- 此外,GIN 必须能够对索引中存储的键值排序。操作符类可以通过指定比较方法来定义排序顺序: + + 此外,GIN 必须有一种方法对存储在索引中的键值进行排序。 + 操作符类可以通过指定一个比较方法来定义这种排序顺序: + + int compare(Datum a, Datum b) @@ -276,7 +291,13 @@ - 或者,如果操作符类没有提供compare方法,GIN 就会查找索引键数据类型的默认 btree 操作符类,并使用其比较函数。对于只适用于一种数据类型的 GIN 操作符类,建议指定比较函数,因为查找 btree 操作符类需要耗费一些处理器周期。但是,多态 GIN 操作符类(例如array_ops)通常无法指定单一的比较函数。 + + + 或者,如果操作符类没有提供 compare 方法,GIN + 将查找该索引键数据类型的默认 B-树操作符类,并使用其比较函数。建议在仅面向单一数据类型的 + GIN 操作符类中显式指定比较函数,因为查找 B-树操作符类会消耗少量处理器周期。 + 不过,多态 GIN 操作符类(例如 array_ops)通常无法指定单一比较函数。 +
作为可选项,GIN操作符类可以提供以下方法: @@ -319,8 +340,8 @@ 在内部,一个 GIN 索引包含一个基于键构建的 B-树索引,其中每个键都是一个或多个被索引项中的某个元素 - (例如数组成员),而叶子页中的每个元组要么包含一个指向堆指针 B-树的指针(posting tree), - 要么在列表足够小、能够连同键值一起放入单个索引元组时,直接包含一个简单的堆指针列表(posting list)。 + (例如数组成员),而叶子页中的每个元组要么包含一个指向堆指针 B-树的指针(倒排树), + 要么在列表足够小、能够连同键值一起放入单个索引元组时,直接包含一个简单的堆指针列表(倒排列表)。 展示了 GIN 索引的这些组成部分。 @@ -367,7 +388,7 @@ - 如果一致的响应时间比更新速度更重要,可以通过关闭 GIN 索引的 + 如果稳定的响应时间比更新速度更重要,可以通过关闭 GIN 索引的 fastupdate 存储参数来禁用待处理列表机制。详见 @@ -403,7 +424,7 @@ 因此,对于向表中执行的批量插入,建议先删除 GIN 索引,待批量插入完成后再重建它。
- PostgreSQL 8.4 开始,由于采用了延迟索引,这项建议已不那么必要(详见)。但对于非常大的更新,最好仍然是删除并重建索引。 + PostgreSQL 8.4 开始,由于采用了延迟索引,这项建议已不那么必要(详见)。但对于非常大的更新,删除并重建索引仍然可能是最佳选择。 @@ -470,14 +491,19 @@ GIN 假定可索引操作符是严格的。这意味着,当项值为 null 时, 根本不会对其调用 extractValue(而是自动创建一个占位符索引项); 当查询值为 null 时,也不会调用 extractQuery(而是认为该查询不可满足)。 - 不过要注意,非空组合项或查询值内部包含的 null 键值仍然受支持。 + 不过要注意,非 null 的组合项或查询值内部包含的 null 键值仍然受支持。
示例 - PostgreSQL核心发行版包含GIN操作符类,见前文。以下contrib模块也包含GIN操作符类: + + PostgreSQL 核心发行版包含前面在 + 中展示过的 GIN 操作符类。 + 下列 contrib 模块也包含 GIN 操作符类: + + btree_gin diff --git a/zh/12/gist.sgml b/zh/12/gist.sgml index aa2b7ff0..eb2c2180 100644 --- a/zh/12/gist.sgml +++ b/zh/12/gist.sgml @@ -4,7 +4,7 @@ GiST 索引 - index + 索引 GiST @@ -45,7 +45,7 @@ 名称 - 索引数据类型 + 被索引数据类型 可索引操作符 排序操作符 @@ -127,7 +127,7 @@ CREATE INDEX ON my_table USING GIST (my_inet_column inet_ops); - 这种可扩展性不应与其他标准搜索树在可处理数据方面的可扩展性相混淆。例如,PostgreSQL支持可扩展的 B-树和哈希索引。这意味着你可以用PostgreSQL在任意数据类型上构建 B-树或哈希索引。但 B-树只支持范围谓词(<=>),而哈希索引只支持等值查询。 + 这种可扩展性不应与其他标准搜索树在可处理数据方面的可扩展性相混淆。例如,PostgreSQL支持可扩展的 B-树和 hash 索引。这意味着你可以用PostgreSQL在任意数据类型上构建 B-树或 hash 索引。但 B-树只支持范围谓词(<=>),而 hash 索引只支持等值查询。 @@ -151,12 +151,19 @@ CREATE INDEX ON my_table USING GIST (my_inet_column inet_ops); indexable_operator q为真。对于叶子索引项,这等同于测试该可索引条件;而对于内部树节点,这决定是否有必要扫描该树节点所表示的索引子树。当结果为true时,还必须返回一个recheck标志。它表示该谓词是确定为真,还是仅可能为真。如果recheck = false,则该索引已经精确测试了谓词条件;如果recheck = true,则该行只是候选匹配。在这种情况下,系统会自动针对实际行值计算indexable_operator,以判断它是否真的匹配。这种约定使GiST能够同时支持无损和有损的索引结构。 - SQL声明必须如下所示: + + 该函数的SQL声明必须如下所示: + + CREATE OR REPLACE FUNCTION my_consistent(internal, data_type, smallint, oid, internal) RETURNS bool AS 'MODULE_PATHNAME' LANGUAGE C STRICT; -C 模块中相应的代码可以采用以下框架: + + + 而 C 模块中的对应代码则可以遵循如下框架: + + PG_FUNCTION_INFO_V1(my_consistent); Datum @@ -171,19 +178,21 @@ my_consistent(PG_FUNCTION_ARGS) bool retval; /* - * determine return value as a function of strategy, key and query. + * 根据 strategy、key 和 query 确定返回值。 * - * Use GIST_LEAF(entry) to know where you're called in the index tree, - * which comes handy when supporting the = operator for example (you could - * check for non empty union() in non-leaf nodes and equality in leaf - * nodes). + * 使用 GIST_LEAF(entry) 判断当前调用位于索引树的哪个位置。 + * 例如,支持 = 操作符时这很有用(可以在非叶节点检查 + * union() 是否非空,在叶节点检查是否相等)。 */ - *recheck = true; /* or false if check is exact */ + *recheck = true; /* 如果检查是精确的,则为 false */ PG_RETURN_BOOL(retval); } -这里,key是索引中的元素,query是要在索引中查找的值。StrategyNumber参数指明正在应用操作符类中的哪个操作符,它对应于CREATE OPERATOR CLASS命令中的某个操作符编号。 + + + 这里,key是索引中的一个元素,而query是在该索引中查找的值。StrategyNumber参数指示应用的是操作符类中的哪个操作符,它对应于CREATE OPERATOR CLASS命令中的某个操作符编号。 + 取决于你在该类中包含了哪些操作符,query的数据类型可能会随操作符而变化,因为它将是操作符右侧的类型,而这可能不同于左侧出现的被索引数据类型。(上面的代码框架假定只可能有一种类型;如果不是这样,获取query参数值的方式就必须依赖于具体的操作符。)建议在consistent函数的 SQL 声明中,对query参数使用该操作符类的被索引数据类型,即使实际类型可能因为操作符不同而有所不同。 @@ -199,12 +208,19 @@ my_consistent(PG_FUNCTION_ARGS) 该方法用于汇总树中的信息。给定一组项,该函数生成一个新的索引项,用来表示所有给定项。 - SQL声明必须如下所示: + + 该函数的SQL声明必须如下所示: + + CREATE OR REPLACE FUNCTION my_union(internal, internal) RETURNS storage_type AS 'MODULE_PATHNAME' LANGUAGE C STRICT; -C 模块中相应的代码可以采用以下框架: + + + 而 C 模块中的对应代码则可以遵循如下框架: + + PG_FUNCTION_INFO_V1(my_union); Datum @@ -262,12 +278,19 @@ my_union(PG_FUNCTION_ARGS) 将一个数据项转换成适合在索引页中物理存储的格式。如果省略compress方法,数据项将不经修改地存储在索引中。 - SQL声明必须如下所示: + + 该函数的SQL声明必须如下所示: + + CREATE OR REPLACE FUNCTION my_compress(internal) RETURNS internal AS 'MODULE_PATHNAME' LANGUAGE C STRICT; -C 模块中相应的代码可以采用以下框架: + + + 而 C 模块中的对应代码则可以遵循如下框架: + + PG_FUNCTION_INFO_V1(my_compress); Datum @@ -278,10 +301,10 @@ my_compress(PG_FUNCTION_ARGS) if (entry->leafkey) { - /* replace entry->key with a compressed version */ + /* 将 entry->key 替换为压缩后的形式 */ compressed_data_type *compressed_data = palloc(sizeof(compressed_data_type)); - /* fill *compressed_data from entry->key ... */ + /* 根据 entry->key 填充 *compressed_data ... */ retval = palloc(sizeof(GISTENTRY)); gistentryinit(*retval, PointerGetDatum(compressed_data), @@ -289,7 +312,7 @@ my_compress(PG_FUNCTION_ARGS) } else { - /* typically we needn't do anything with non-leaf entries */ + /* 通常无需对非叶项做任何处理 */ retval = entry; } @@ -311,12 +334,19 @@ my_compress(PG_FUNCTION_ARGS) 将数据项的存储表示转换成操作符类中其他 GiST 方法能够操作的格式。如果省略decompress方法,就假定其他 GiST 方法可以直接处理存储的数据格式。(decompress不一定是compress方法的逆操作;特别是如果compress是有损的,那么decompress就不可能精确重建原始数据。decompress也不一定等同于fetch,因为其他 GiST 方法未必需要把数据完全重建出来。) - SQL声明必须如下所示: + + 该函数的SQL声明必须如下所示: + + CREATE OR REPLACE FUNCTION my_decompress(internal) RETURNS internal AS 'MODULE_PATHNAME' LANGUAGE C STRICT; -C 模块中相应的代码可以采用以下框架: + + + 而 C 模块中的对应代码则可以遵循如下框架: + + PG_FUNCTION_INFO_V1(my_decompress); Datum @@ -324,7 +354,10 @@ my_decompress(PG_FUNCTION_ARGS) { PG_RETURN_POINTER(PG_GETARG_POINTER(0)); } -上述框架适用于无需解压缩的情况。(当然,完全省略该方法更简单,这种情况下也建议如此。) + + + 上述框架适用于不需要解压的情况。(当然,在这种情况下,直接完全省略该方法会更简单,而且也推荐这么做。) + @@ -335,12 +368,19 @@ my_decompress(PG_FUNCTION_ARGS) 返回一个值,指示把新项插入树中特定分支的代价。项会沿着树中penalty最小的路径插入。penalty返回的值应为非负;如果返回负值,它将被按零处理。 - SQL声明必须如下所示: + + 该函数的SQL声明必须如下所示: + + CREATE OR REPLACE FUNCTION my_penalty(internal, internal, internal) RETURNS internal AS 'MODULE_PATHNAME' -LANGUAGE C STRICT; -- in some cases penalty functions need not be strict -C 模块中相应的代码可以采用以下框架: +LANGUAGE C STRICT; -- 某些情况下 penalty 函数不必是严格函数 + + + 而 C 模块中的对应代码则可以遵循如下框架: + + PG_FUNCTION_INFO_V1(my_penalty); Datum @@ -355,7 +395,10 @@ my_penalty(PG_FUNCTION_ARGS) *penalty = my_penalty_implementation(orig, new); PG_RETURN_POINTER(penalty); } -由于历史原因,penalty函数不能仅仅返回一个float结果,而必须将该值存储到第三个参数指向的位置。函数自身的返回值会被忽略,但通常会返回该参数的地址。 + + + 出于历史原因,penalty函数并不是直接返回一个float结果;相反,它必须把该值存储到第三个参数指示的位置。返回值本身会被忽略,不过通常会返回该参数所指向的地址。 + penalty函数对于索引的良好性能至关重要。它会在插入时用于决定在树中应沿着哪个分支向下,以便选择把新项加到哪里。在查询时,索引越平衡,查找就越快。 @@ -370,12 +413,19 @@ my_penalty(PG_FUNCTION_ARGS) 当索引页必须分裂时,该函数决定页面上的哪些项留在旧页中,哪些移到新页中。 - SQL声明必须如下所示: + + 该函数的SQL声明必须如下所示: + + CREATE OR REPLACE FUNCTION my_picksplit(internal, internal) RETURNS internal AS 'MODULE_PATHNAME' LANGUAGE C STRICT; -C 模块中相应的代码可以采用以下框架: + + + 而 C 模块中的对应代码则可以遵循如下框架: + + PG_FUNCTION_INFO_V1(my_picksplit); Datum @@ -408,7 +458,7 @@ my_picksplit(PG_FUNCTION_ARGS) unionL = NULL; unionR = NULL; - /* Initialize the raw entry vector. */ + /* 初始化原始项向量。 */ raw_entryvec = (GISTENTRY **) malloc(entryvec->n * sizeof(void *)); for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) raw_entryvec[i] = &(entryvec->vector[i]); @@ -421,9 +471,9 @@ my_picksplit(PG_FUNCTION_ARGS) Assert(tmp_union != NULL); /* - * Choose where to put the index entries and update unionL and unionR - * accordingly. Append the entries to either v->spl_left or - * v->spl_right, and care about the counters. + * 选择索引项的存放位置,并相应更新 unionL 和 unionR。 + * 将项追加到 v->spl_left 或 v->spl_right, + * 同时更新计数器。 */ if (my_choice_is_left(unionL, curl, unionR, curr)) @@ -440,7 +490,7 @@ my_picksplit(PG_FUNCTION_ARGS) else { /* - * Same on the right + * 对右侧执行相同操作 */ } } @@ -449,7 +499,9 @@ my_picksplit(PG_FUNCTION_ARGS) v->spl_rdatum = DataTypeGetDatum(unionR); PG_RETURN_POINTER(v); } -注意,picksplit函数通过修改传入的v结构体来传递结果。函数自身的返回值会被忽略,但通常会返回以下结构体的地址:v。 + + + 注意,picksplit函数的结果是通过修改传入的v结构体来传递的。返回值本身会被忽略,不过通常会返回v的地址。 @@ -465,12 +517,19 @@ my_picksplit(PG_FUNCTION_ARGS) 如果两个索引项相同则返回真,否则返回假。(索引项是索引存储类型的值,不一定是原始被索引列的类型。) - SQL声明必须如下所示: + + 该函数的SQL声明必须如下所示: + + CREATE OR REPLACE FUNCTION my_same(storage_type, storage_type, internal) RETURNS internal AS 'MODULE_PATHNAME' LANGUAGE C STRICT; -C 模块中相应的代码可以采用以下框架: + + + 而 C 模块中的对应代码则可以遵循如下框架: + + PG_FUNCTION_INFO_V1(my_same); Datum @@ -483,7 +542,10 @@ my_same(PG_FUNCTION_ARGS) *result = my_eq(v1, v2); PG_RETURN_POINTER(result); } -由于历史原因,same函数不能仅仅返回布尔结果,而必须将该标志存储到第三个参数指向的位置。函数自身的返回值会被忽略,但通常会返回该参数的地址。 + + + 出于历史原因,same函数并不是直接返回一个布尔结果;相反,它必须把该标志存储到第三个参数指示的位置。返回值本身会被忽略,不过通常会返回该参数所指向的地址。 + @@ -494,12 +556,19 @@ my_same(PG_FUNCTION_ARGS) 给定一个索引项p和一个查询值q,该函数确定索引项与查询值之间的距离。如果操作符类包含任何排序操作符,就必须提供此函数。使用排序操作符的查询会优先返回距离值最小的索引项,因此结果必须与该操作符的语义一致。对于叶子索引项,结果仅表示到该索引项的距离;对于内部树节点,结果必须是其任意子项可能具有的最小距离。 - SQL声明必须如下所示: + + 该函数的SQL声明必须如下所示: + + CREATE OR REPLACE FUNCTION my_distance(internal, data_type, smallint, oid, internal) RETURNS float8 AS 'MODULE_PATHNAME' LANGUAGE C STRICT; -C 模块中相应的代码可以采用以下框架: + + + 而 C 模块中的对应代码则可以遵循如下框架: + + PG_FUNCTION_INFO_V1(my_distance); Datum @@ -514,19 +583,22 @@ my_distance(PG_FUNCTION_ARGS) double retval; /* - * determine return value as a function of strategy, key and query. + * 根据 strategy、key 和 query 确定返回值。 */ PG_RETURN_FLOAT8(retval); } -distance函数的参数与consistent函数的参数完全相同。 + + + distance函数的参数与consistent函数的参数完全相同。 + - 在确定距离时允许有一定近似,只要结果永不大于该项的实际距离即可。因此,例如在几何应用中,到外包盒的距离通常就足够了。对于内部树节点,返回的距离不能大于其任一子节点的距离。如果返回的距离不精确,函数必须将*recheck设为 true。(对内部树节点则不必这样做;对它们总是假定计算结果不精确。)在这种情况下,执行器会在从堆中取出元组后计算准确距离,并在必要时重新排序这些元组。 + 在确定距离时允许有一定近似,只要结果永不大于该项的实际距离即可。因此,例如在几何应用中,到包围盒的距离通常就足够了。对于内部树节点,返回的距离不能大于其任一子节点的距离。如果返回的距离不精确,函数必须将*recheck设为 true。(对内部树节点则不必这样做;对它们总是假定计算结果不精确。)在这种情况下,执行器会在从堆中取出元组后计算准确距离,并在必要时重新排序这些元组。 - 如果距离函数对任何叶节点都返回*recheck = true,原始排序操作符的返回类型必须是float8float4,且距离函数的结果值必须能与原始排序操作符的结果进行比较,因为执行器会同时使用距离函数结果和重新计算得到的排序操作符结果进行排序。否则,距离函数的结果值可以是任意有限的float8值,只要这些结果值的相对顺序与排序操作符返回的顺序一致即可。(无穷大和负无穷在内部用于处理空值等情况,因此不建议distance函数返回这些值。) + 如果距离函数对任意一个叶节点返回*recheck = true,原始排序操作符的返回类型必须是float8float4,且距离函数的结果值必须能与原始排序操作符的结果进行比较,因为执行器会同时使用距离函数结果和重新计算得到的排序操作符结果进行排序。否则,距离函数的结果值可以是任意有限的float8值,只要这些结果值的相对顺序与排序操作符返回的顺序一致即可。(无穷大和负无穷在内部用于处理空值等情况,因此不建议distance函数返回这些值。) @@ -539,12 +611,18 @@ my_distance(PG_FUNCTION_ARGS) 为了支持仅索引扫描,将数据项的压缩索引表示转换为原始数据类型。返回的数据必须是最初被索引值的精确、无损副本。 - SQL声明必须如下所示: + + 该函数的SQL声明必须如下所示: + + CREATE OR REPLACE FUNCTION my_fetch(internal) RETURNS internal AS 'MODULE_PATHNAME' LANGUAGE C STRICT; -参数是一个指向GISTENTRY结构体的指针。进入该函数时,它的key字段包含一个压缩形式的非 NULL 叶子 datum。返回值是另一个GISTENTRY结构体,其中的key字段以原始、未压缩形式包含同一个 datum。如果该操作符类的 compress 函数对叶子项不做任何处理,fetch方法可以原样返回参数。如果操作符类没有 compress 函数,则fetch方法也可以省略,因为它必然不会执行任何实际操作。 + + + 参数是一个指向GISTENTRY结构体的指针。进入该函数时,它的key字段包含一个压缩形式的非 NULL 叶子 datum。返回值是另一个GISTENTRY结构体,其key字段以原始、未压缩形式包含同一个 datum。如果该操作符类的 compress 函数对叶子项不做任何处理,fetch方法可以原样返回该参数。或者,如果该操作符类没有 compress 函数,那么fetch方法也可以省略,因为它必然是空操作。 + 而 C 模块中的对应代码则可以遵循如下框架: @@ -564,10 +642,10 @@ my_fetch(PG_FUNCTION_ARGS) fetched_data = palloc(sizeof(fetched_data_type)); /* - * Convert 'fetched_data' into the a Datum of the original datatype. + * 将 'fetched_data' 转换为原始数据类型的 Datum。 */ - /* fill *retval from fetched_data. */ + /* 根据 fetched_data 填充 *retval。 */ gistentryinit(*retval, PointerGetDatum(converted_datum), entry->rel, entry->page, entry->offset, FALSE); @@ -611,7 +689,10 @@ my_fetch(PG_FUNCTION_ARGS) 示例 - PostgreSQL源码发行包包含若干使用GiST实现索引方法的示例。核心系统目前提供文本搜索支持(为tsvectortsquery建立索引),还为部分内置几何数据类型提供等价于 R 树的功能(参见src/backend/access/gist/gistproc.c)。以下contrib模块也包含GiST操作符类: + + PostgreSQL源代码发行包包含了若干使用GiST实现的索引方法示例。核心系统目前提供了文本搜索支持(为tsvectortsquery建立索引),并为某些内置几何数据类型提供了与 R 树等价的功能(见src/backend/access/gist/gistproc.c)。下列contrib模块中也包含GiST操作符类: + + btree_gist @@ -629,7 +710,7 @@ my_fetch(PG_FUNCTION_ARGS) hstore - 用于存储 (key, value) 对的模块 + 用于存储(键,值)对的模块 diff --git a/zh/12/hash.sgml b/zh/12/hash.sgml index 199395b2..81f5f878 100644 --- a/zh/12/hash.sgml +++ b/zh/12/hash.sgml @@ -1,11 +1,11 @@ -哈希索引 +Hash 索引 索引 - 哈希 + Hash @@ -13,51 +13,51 @@ PostgreSQL - 提供了持久化的磁盘哈希索引实现,并且完全支持崩溃恢复。任何数据类型都可以使用哈希索引,包括那些没有明确定义线性顺序的数据类型。哈希索引只存储被索引数据的哈希值,因此对被索引数据列的大小没有限制。 + 提供了持久化的磁盘 hash 索引实现,并且完全支持崩溃恢复。任何数据类型都可以使用 hash 索引,包括那些没有明确定义线性顺序的数据类型。Hash 索引只存储被索引数据的 hash 值,因此对被索引数据列的大小没有限制。 - 哈希索引仅支持单列索引,也不支持唯一性检查。 + Hash 索引仅支持单列索引,也不支持唯一性检查。 - 哈希索引仅支持=操作符,因此指定范围操作的 WHERE 子句无法利用哈希索引。 + Hash 索引仅支持=操作符,因此指定范围操作的 WHERE 子句无法利用 hash 索引。 - 每个哈希索引元组只存储 4 字节的哈希值,而不存储实际的列值。因此,在为 UUID、URL 等较长的数据项建立索引时,哈希索引可能比 B-树小得多。由于没有列值,所有哈希索引扫描也都是有损的。哈希索引可以参与位图索引扫描和反向扫描。 + 每个 hash 索引元组只存储 4 字节的 hash 值,而不存储实际的列值。因此,在为 UUID、URL 等较长的数据项建立索引时,hash 索引可能比 B-树小得多。由于没有列值,所有 hash 索引扫描也都是有损的。Hash 索引可以参与位图索引扫描和反向扫描。 - 哈希索引最适合于在较大表上执行等值扫描、且以 SELECT 和 UPDATE 为主的工作负载。在 B-树索引中,搜索必须沿树向下直到找到叶页。在拥有数百万行的表中,这种向下遍历会增加访问数据的时间。在哈希索引中,与叶页对应的页称为桶页。相比之下,哈希索引允许直接访问桶页,因此可能减少大表中的索引访问时间。这种“逻辑 I/O”的减少,在索引/数据大于 shared_buffers/RAM 时会更加明显。 + Hash 索引最适合于在较大表上执行等值扫描、且以 SELECT 和 UPDATE 为主的工作负载。在 B-树索引中,搜索必须沿树向下直到找到叶页。在拥有数百万行的表中,这种向下遍历会增加访问数据的时间。在 hash 索引中,与叶页对应的页称为桶页。相比之下,hash 索引允许直接访问桶页,因此可能减少大表中的索引访问时间。这种“逻辑 I/O”的减少,在索引/数据大于 shared_buffers/RAM 时会更加明显。 - 哈希索引在设计上能够应对哈希值分布不均的情况。如果哈希值分布均匀,那么直接访问桶页的效果很好。当插入导致桶页填满时,额外的溢出页就会链接到该特定桶页上,从而在局部扩展用于存放匹配该哈希值的索引元组的空间。查询期间扫描某个哈希桶时,需要遍历其全部溢出页。因此,对于某些数据,不平衡的哈希索引在所需块访问次数方面实际上可能比 B-树更差。 + Hash 索引在设计上能够应对 hash 值分布不均的情况。如果 hash 值分布均匀,那么直接访问桶页的效果很好。当插入导致桶页填满时,额外的溢出页就会链接到该特定桶页上,从而在局部扩展用于存放匹配该 hash 值的索引元组的空间。查询期间扫描某个 hash 桶时,需要遍历其全部溢出页。因此,对于某些数据,不平衡的 hash 索引在所需块访问次数方面实际上可能比 B-树更差。 - 由于会出现这些溢出情况,可以说哈希索引最适合用于唯一值、近乎唯一值,或者每个哈希桶中行数较少的数据。 + 由于会出现这些溢出情况,可以说 hash 索引最适合用于唯一值、近乎唯一值,或者每个 hash 桶中行数较少的数据。 避免问题的一种可能办法,是使用部分索引条件把高度非唯一的值排除在索引之外,但这在很多情况下可能并不适用。 - 与 B-树一样,哈希索引也会执行简单的索引元组删除。这是一种延迟维护操作,用于删除那些已知可以安全删除的索引元组(即其项标识符的 LP_DEAD 位已经被设置的那些元组)。如果插入操作发现页上没有可用空间,我们会尝试通过移除死索引元组来避免创建新的溢出页。如果该页当时已被钉住,就无法执行移除。死索引指针也会在 VACUUM 期间被删除。 + 与 B-树一样,hash 索引也会执行简单的索引元组删除。这是一种延迟维护操作,用于删除那些已知可以安全删除的索引元组(即其项标识符的 LP_DEAD 位已经被设置的那些元组)。如果插入操作发现页上没有可用空间,我们会尝试通过移除死索引元组来避免创建新的溢出页。如果该页当时已被钉住,就无法执行移除。死索引指针也会在 VACUUM 期间被删除。 - 如果可能,VACUUM 还会尝试将索引元组压缩到尽可能少的溢出页上,以最小化溢出链。 + 如果可能,VACUUM 还会尝试将索引元组集中存放在尽可能少的溢出页上,以最小化溢出链。 如果某个溢出页变为空页,该溢出页就可以被回收并在其他桶中重用,不过我们从不将它们返还给操作系统。 - 目前除了使用 REINDEX 重建哈希索引之外,还没有缩小哈希索引的方法。 + 目前除了使用 REINDEX 重建 hash 索引之外,还没有缩小 hash 索引的方法。 同样也没有减少桶数量的方法。 - 随着被索引行数的增长,哈希索引可能会扩展桶页数量。哈希键到桶号的映射经过选择,使得索引能够增量扩展。当需要向索引中添加一个新桶时,恰好只需要“拆分”一个现有桶,并根据更新后的键到桶号映射,将其中一部分元组转移到新桶。 + 随着被索引行数的增长,Hash 索引可能会扩展桶页数量。hash 键到桶号的映射经过选择,使得索引能够增量扩展。当需要向索引中添加一个新桶时,恰好只需要“拆分”一个现有桶,并根据更新后的键到桶号映射,将其中一部分元组转移到新桶。 - 这种扩展是在前台进行的,因此可能会增加用户插入操作的执行时间。因此,哈希索引可能不适合行数快速增长的表。 + 这种扩展是在前台进行的,因此可能会增加用户插入操作的执行时间。因此,hash 索引可能不适合行数快速增长的表。 @@ -66,7 +66,7 @@ 实现 - 哈希索引中有四种页:元页(第零页),其中包含静态分配的控制信息;主桶页;溢出页;以及位图页,后者用于跟踪已被释放且可供重用的溢出页。在寻址时,位图页被视为溢出页的一个子集。 + hash 索引中有四种页:元页(第零页),其中包含静态分配的控制信息;主桶页;溢出页;以及位图页,后者用于跟踪已被释放且可供重用的溢出页。在寻址时,位图页被视为溢出页的一个子集。 @@ -74,15 +74,15 @@ - 主桶页和溢出页是独立分配的,因为任何一个给定索引相对于其桶数,可能需要更多或更少的溢出页。哈希代码使用了一组颇有意思的寻址规则,以支持可变数量的溢出页,同时又不必在主桶页创建后再移动它们。 + 主桶页和溢出页是独立分配的,因为任何一个给定索引相对于其桶数,可能需要更多或更少的溢出页。hash 实现代码使用了一组颇有意思的寻址规则,以支持可变数量的溢出页,同时又不必在主桶页创建后再移动它们。 - 被索引表中的每一行,都由哈希索引中的单个索引元组表示。哈希索引元组存储在桶页中,如果存在溢出页,也会存储在溢出页中。为了加快搜索速度,我们将任一索引页中的索引项按哈希码排序,从而可以在索引页内使用二分查找。但请注意,并不假定同一桶中不同索引页之间的哈希码具有任何相对顺序。 + 被索引表中的每一行,都由 hash 索引中的单个索引元组表示。Hash 索引元组存储在桶页中,如果存在溢出页,也会存储在溢出页中。为了加快搜索速度,我们将任一索引页中的索引项按 hash 码排序,从而可以在索引页内使用二分查找。但请注意,并不假定同一桶中不同索引页之间的 hash 码具有任何相对顺序。 - 用于扩展哈希索引的桶拆分算法过于复杂,这里不再展开说明;但在src/backend/access/hash/README中有更详细的描述。该拆分算法具备崩溃安全性,如果未能成功完成,可以重新启动。 + 用于扩展 hash 索引的桶拆分算法过于复杂,这里不再展开说明;但在src/backend/access/hash/README中有更详细的描述。该拆分算法具备崩溃安全性,如果未能成功完成,可以重新启动。 diff --git a/zh/12/high-availability.sgml b/zh/12/high-availability.sgml index 4c65f336..e501e354 100644 --- a/zh/12/high-availability.sgml +++ b/zh/12/high-availability.sgml @@ -253,7 +253,7 @@ protocol to make nodes agree on a serializable transactional order. - 主库失效绝不会丢失数据 + 主库失效时绝不丢失数据 启用同步时 @@ -341,7 +341,7 @@ protocol to make nodes agree on a serializable transactional order. - 连续归档可用于创建一种高可用性(HA)集簇配置,其中有一个或多个备库随时准备在主库失效时接管操作。这种能力通常称为温备日志传送。 + 持续归档可用于创建一种高可用性(HA)集簇配置,其中有一个或多个备库随时准备在主库失效时接管操作。这种能力通常称为温备日志传送 @@ -488,7 +488,9 @@ archive_cleanup_command = 'pg_archivecleanup /path/to/archive %r' 默认情况下流复制是异步的(见 ),在这种情况下主库上提交一个事务与该变化在备库上变得可见之间存在短暂的延迟。不过这种延迟比基于文件的日志传送方式中要小得多,在备库的能力足以跟得上负载的前提下,延迟通常低于一秒。在流复制中,不需要 archive_timeout 来缩减数据丢失窗口。 - 如果使用流复制却未使用基于文件的连续归档,服务器可能在备库收到旧 WAL 段之前就将其回收。如果发生这种情况,备库需要从新的基础备份重新初始化。可以将 wal_keep_segments 设得足够大,确保 WAL 段不会过早回收,或者为备库配置复制槽,以避免这种情况。如果配置了备库可以访问的 WAL 归档,则不需要这些办法,因为只要归档保留了足够的段,备库就始终可以借助归档追赶主库。 + + 如果你使用流复制,但没有启用基于文件的持续归档,服务器可能会在备库收到旧的 WAL 段之前就把它们回收掉。如果发生这种情况,备库就需要重新通过新的基础备份进行初始化。可以通过把 wal_keep_segments 设置得足够大,以确保 WAL 段不会过早被回收,或者为备库配置一个复制槽,从而避免这种情况。如果配置了一个备库可访问的 WAL 归档,就不需要这些方案,因为只要归档保留了足够多的段,备库始终可以利用归档追赶上来。 + 要使用流复制,请先按 所述设置一个基于文件的日志传送备库。把它转变为流复制备库的步骤,就是把 primary_conninfo 设置为指向主库。还要在主库上设置 和认证选项(见 pg_hba.conf),以便备库能够连接到主库上的 replication 伪数据库(见 )。 @@ -502,13 +504,16 @@ archive_cleanup_command = 'pg_archivecleanup /path/to/archive %r' 设置来自备库的最大并发连接数(详见 )。 - 备库启动后,如果正确设置了 primary_conninfo,备库会在重放归档中所有可用的 WAL 文件后连接主库。如果连接成功,就会在备库上看到 WAL 接收进程,在主库上看到对应的 WAL 发送进程。 + 备库启动后,如果正确设置了 primary_conninfo,备库会在重放归档中所有可用的 WAL 文件后连接主库。如果连接成功,就会在备库上看到 walreceiver 进程,在主库上看到对应的 walsender 进程。 认证 - 务必正确设置复制访问权限,使只有受信任的用户才能读取 WAL 流,因为很容易从中提取特权信息。备库必须以超级用户或具有 REPLICATION 权限的账户向主库认证。建议为复制创建专用用户账户,并授予 REPLICATIONLOGIN 权限。虽然 REPLICATION 权限赋予的权限很高,但它不允许用户修改主库系统上的任何数据,而 SUPERUSER 权限允许这样做。 + 务必正确设置复制访问权限,使只有受信任的用户才能读取 WAL 流,因为很容易从中提取需要权限才能访问的信息。备库必须以超级用户或具有 REPLICATION 权限的账户向主库认证。建议为复制创建专用用户账户,并授予 REPLICATIONLOGIN 权限。虽然 REPLICATION 权限赋予的权限很高,但它不允许用户修改主库系统上的任何数据,而 SUPERUSER 权限允许这样做。 + + + 复制的客户端认证由 pg_hba.conf 中的一条记录控制,该记录需要把 replication 指定在 database 字段中。例如,如果备库运行在主机 IP 192.168.1.100 上,并且用于复制的账户名为 foo,管理员可以在主库上的 pg_hba.conf 文件中加入下列行: - 复制的客户端认证由 pg_hba.conf 中的记录控制。记录要将 replication 指定为 database 字段的值。例如,如果备库所在主机的 IP 地址为 192.168.1.100,用于复制的账户名为 foo,管理员可以将以下行添加到 pg_hba.conf 文件(位于主库)中: + # Allow the user "foo" from host 192.168.1.100 to connect to the primary # as a replication standby if the user's password is correctly supplied. # @@ -516,7 +521,10 @@ archive_cleanup_command = 'pg_archivecleanup /path/to/archive %r' host replication foo 192.168.1.100/32 md5 - 主库的主机名、端口号、连接用户名和密码在 中指定。也可以将密码设置在备库的 ~/.pgpass 文件中(将 replication 指定为 database 字段的值)。例如,如果主库所在主机的 IP 地址为 192.168.1.50,端口为 5432,用于复制的账户名为 foo,密码为 foopass,管理员可以将以下行添加到 postgresql.conf 文件(位于备库)中: + + 主库的主机名和端口号、连接用户名以及密码都在 中指定。密码也可以设置在备库上的 ~/.pgpass 文件中(把 replication 指定在 database 字段中)。例如,如果主库运行在主机 IP 192.168.1.50、端口 5432 上,用于复制的账户名为 foo,并且密码是 foopass,管理员可以在备库的 postgresql.conf 文件中加入下列行: + + # The standby connects to the primary that is running on host 192.168.1.50 # and port 5432 as the user "foo" whose password is "foopass". primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass' @@ -529,7 +537,7 @@ primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass' 流复制的一个重要健康指标,是主库上已经生成但尚未在备库上应用的 WAL 记录量。你可以通过比较主库上的当前 WAL 写入位置和备库收到的最后一个 WAL 位置来计算这种滞后。这些位置分别可以用主库上的 pg_current_wal_lsn 和备库上的 pg_last_wal_receive_lsn 取得(详见 )。备库上的最后一个 WAL 接收位置也会显示在 WAL 接收进程的进程状态中,即通过 ps 命令显示的状态(详见 )。 - 可以通过 视图获取 WAL 发送进程列表。pg_current_wal_lsn 与该视图的 sent_lsn 字段相差较大,可能表示主库负载很高;而 sent_lsn 与备库上 pg_last_wal_receive_lsn 的差值较大,则可能表示网络延迟或备库负载很高。 + 可以通过 视图获取 WAL 发送进程列表。pg_current_wal_lsn 与该视图的 sent_lsn 字段相差较大,可能表示主库负载很高;而 sent_lsn 与备库上 pg_last_wal_receive_lsn 之间存在差异,则可能表示网络延迟或备库负载很高。 在热备上,可以通过 视图获取 WAL 接收进程的状态。如果 pg_last_wal_replay_lsn 与该视图的 received_lsn 相差较大,说明接收 WAL 的速度超过了重放速度。
@@ -541,7 +549,7 @@ primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass' 流复制 - 复制槽提供了一种自动化方法,以确保主库在所有备库都收到 WAL 段之前不会删除它们,并且即使备库处于断开状态,主库也不会删除可能导致恢复冲突的行。 + 复制槽提供了一种自动化方法,以确保主库在所有备库都收到 WAL 段之前不会删除它们,并且即使备库处于断开状态,主库也不会删除那些一旦删除就可能导致恢复冲突的行。 除了使用复制槽,也可以通过 防止旧 WAL 段被删除,或者使用 将这些段保存在归档中。不过,这些方法通常会保留多于实际所需的 WAL 段,而复制槽只保留已知必需的段数。这些方法的优点是能限制 pg_wal 的空间需求;目前使用复制槽还无法做到这一点。 类似地, 可以保护相关行,避免它们被清理删除,但前者在备库未连接期间无法提供保护,后者则通常需要设为较大的值才能提供充分保护。复制槽克服了这些缺点。 @@ -561,7 +569,9 @@ primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass' 配置示例 - 可以这样创建复制槽: + + 你可以像下面这样创建一个复制槽: + postgres=# SELECT * FROM pg_create_physical_replication_slot('node_a_slot'); slot_name | lsn -------------+----- @@ -572,7 +582,9 @@ postgres=# SELECT slot_name, slot_type, active FROM pg_replication_slots; -------------+-----------+-------- node_a_slot | physical | f (1 row) -要配置备库使用此复制槽,需要将 primary_slot_name 配置在备库上。下面是一个简单的示例: + + 要让备库使用这个槽,应在备库上配置 primary_slot_name。下面是一个简单示例: + primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass' primary_slot_name = 'node_a_slot' @@ -591,7 +603,9 @@ primary_slot_name = 'node_a_slot' 级联复制特性允许一台备库接受复制连接,并像中继器一样把 WAL 记录流式发送给其他备库。这可以用来减少直接连接到主库的连接数,并使站点间的带宽开销最小化。 - 同时充当接收方和发送方的备库称为级联备库。与主库连接更直接的备库称为上游服务器,距离更远的备库则称为下游服务器。级联复制不限制下游服务器的数量或组织方式,不过每个备库只连接一个上游服务器,并最终连接到同一个主库。 + + 一台同时扮演接收者和发送者角色的备库称为级联备库。与主库连接更直接(经过更少级联备库)的备库称为上游服务器,而距离更远的备库称为下游服务器。级联复制并不限制下游服务器的数量和拓扑,不过每台备库只连接到一台上游服务器,而这条链路最终都会通向同一台主库。 + 级联备库不仅发送从主库接收到的 WAL 记录,也会发送那些从归档中恢复的记录。因此,即使某条上游复制连接被中断,只要仍有新的 WAL 记录可用,下游的流复制就会继续。 @@ -605,7 +619,9 @@ primary_slot_name = 'node_a_slot' 热备反馈会向上传播,无论级联拓扑如何。 - 如果某个上游备库被提升为新主库,只要 recovery_target_timeline 设为 'latest'(默认值),下游服务器就会继续从新主库接收流。 + + 如果一台上游备库被提升为新的主库,并且下游服务器的 recovery_target_timeline 被设置为 'latest'(默认值),下游服务器将继续从新的主库接收流。 + 要使用级联复制,需要把级联备库设置为能够接受复制连接(也就是设置 ,并配置 基于主机的认证)。你还需要把下游备库中的 primary_conninfo 设置为指向级联备库。 @@ -631,7 +647,9 @@ primary_slot_name = 'node_a_slot' 请求同步复制时,每个写事务的提交都会等待,直到收到确认,表明该提交已被写入主库和备库磁盘上的预写式日志。数据唯一可能丢失的情况,是主库和备库同时崩溃。这可以提供更高的持久性级别,不过前提是系统管理员必须谨慎地部署和管理这两台服务器。等待确认会增强用户对服务器崩溃时更改不会丢失的信心,但也必然会增加请求事务的响应时间。最短等待时间是主库与备库之间的往返时间。 - 只读事务和事务回滚无需等待备库回复。子事务提交也不等待备库响应,只有顶层提交才会等待。数据加载或索引构建等长时间运行的操作,直到最后的提交消息才会等待。所有两阶段提交操作都需要等待提交,包括准备和提交两个阶段。 + + 只读事务和事务回滚不需要等待备库的回应。子事务提交也不需要等待备库响应,只有顶层提交才需要等待。数据装载或索引构建等长时间运行的动作,直到最终提交时才会等待。所有两阶段提交操作都需要等待提交,包括准备和提交两个阶段。 + 同步备库可以是物理复制备库,也可以是逻辑复制订阅者。它还可以是任何其他物理或逻辑 WAL 复制流的消费者,只要它知道如何发送适当的反馈消息。除了内置的物理和逻辑复制系统之外,还包括pg_receivewalpg_recvlogical之类的专用程序,以及一些第三方复制系统和定制程序。关于同步复制支持的细节,请查看相应文档。 @@ -645,7 +663,7 @@ primary_slot_name = 'node_a_slot' - 当提交记录已经在主库上写入磁盘之后,WAL 记录就会被发送到备库。每当新的一批 WAL 数据被写入磁盘时,备库就会发送回复消息,除非备库上的wal_receiver_status_interval被设置为零。如果synchronous_commit被设置为remote_apply,那么备库会在提交记录被重放时发送回复消息,从而使该事务变得可见。如果根据主库上的synchronous_standby_names设置,该备库被选为同步备库,那么它发出的回复会与其他同步备库的回复一起,用于决定何时释放那些正在等待确认提交记录已被收到的事务。这些参数允许管理员指定哪些备库应作为同步备库。注意,同步复制的配置主要在主库上进行。被命名的备库必须直接连接到主库;主库并不知道使用级联复制的下游备库。 + 当提交记录已经在主库上写入磁盘之后,WAL 记录就会被发送到备库。每当新的一批 WAL 数据被写入磁盘时,备库就会发送回复消息,除非备库上的wal_receiver_status_interval被设置为零。如果synchronous_commit被设置为remote_apply,那么备库会在提交记录被重放、该事务变得可见时发送回复消息。如果根据主库上的synchronous_standby_names设置,该备库被选为同步备库,那么它发出的回复会与其他同步备库的回复一起,用于决定何时释放那些正在等待确认提交记录已被收到的事务。这些参数允许管理员指定哪些备库应作为同步备库。注意,同步复制的配置主要在主库上进行。被命名的备库必须直接连接到主库;主库并不知道使用级联复制的下游备库。 @@ -657,7 +675,7 @@ primary_slot_name = 'node_a_slot' - 如果请求快速关闭,用户将停止等待。不过,与使用异步复制时一样,在所有尚未解决的 WAL 记录传输到当前已连接的备库之前,服务器不会完全关闭。 + 如果请求快速关闭,用户将停止等待。不过,与使用异步复制时一样,在所有尚未传送的 WAL 记录传输到当前已连接的备库之前,服务器不会完全关闭。 @@ -679,14 +697,14 @@ synchronous_standby_names = 'FIRST 2 (s1, s2, s3)' 在这个例子中,如果四台备库s1s2s3s4都在运行,则s1s2会被选为同步备库,因为它们的名字在备库名称列表中出现得更早。s3是潜在的同步备库,当s1s2中的任意一台失效时,它就会接替其角色。由于s4的名称不在列表中,因此它是异步备库。 - ANY方法指定基于法定人数的同步复制,使事务提交等待,直到它们的 WAL 记录被复制到列表中所要求数量的同步备库中的至少这么多台。 + ANY方法指定基于法定人数的同步复制,使事务提交等待,直到它们的 WAL 记录被复制到列表中至少所要求数量的同步备库。 基于法定人数的多同步备库的synchronous_standby_names示例如下: synchronous_standby_names = 'ANY 2 (s1, s2, s3)' - 在这个例子中,如果四台备库s1s2s3s4都在运行,事务提交将等待来自s1s2s3中的任意两台备库的回复。由于s4的名字不在列表中,因此它是异步备库。 + 在这个例子中,如果四台备库s1s2s3s4都在运行,事务提交将等待来自s1s2s3中的至少任意两台备库的回复。由于s4的名字不在列表中,因此它是异步备库。 备库的同步状态可以通过pg_stat_replication视图查看。 @@ -709,7 +727,7 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' - 通过在应用级别(在主库上)指定同步复制选项,我们可以只对最重要的变更提供同步复制,而不会拖慢整体工作负载。应用级别选项是让高性能应用获得同步复制收益的一种重要而实用的工具。 + 通过在应用级别(在主库上)指定同步复制选项,我们可以只对最重要的变更提供同步复制,而不会拖慢大部分工作负载。应用级别选项是让高性能应用获得同步复制收益的一种重要而实用的工具。 @@ -742,7 +760,7 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' - 如果主库在提交正等待确认时重启,这些等待中的事务会在主库恢复后被标记为已完全提交。无法确定在主库崩溃时,所有备库是否已经收到全部尚未处理的 WAL 数据。因此,某些事务可能不会在备库上显示为已提交,即使它们在主库上显示为已提交。我们所提供的保证是:只有在确认 WAL 数据已经被所有同步备库安全接收之后,应用才会收到事务成功提交的显式确认。 + 如果主库在提交正等待确认时重启,这些等待中的事务会在主库恢复后被标记为已完全提交。无法确定在主库崩溃时,所有备库是否已经收到全部待传送的 WAL 数据。因此,某些事务可能不会在备库上显示为已提交,即使它们在主库上显示为已提交。我们所提供的保证是:只有在确认 WAL 数据已经被所有同步备库安全接收之后,应用才会收到事务成功提交的显式确认。 @@ -800,7 +818,7 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' - 一旦故障切换到备库,系统中就只剩下一台服务器在运行。这被称为退化状态。原来的备库现在成为主库,而原来的主库已经停机,并且可能持续停机。要恢复到正常运行状态,就必须重新创建一台备库:要么在原主库恢复后在其上重建,要么在第三台可能是全新的服务器上重建。在大型集簇上,可以使用工具来加快这一过程。一旦完成,就可以认为主库和备库已经交换了角色。有些人会选择使用第三台服务器,在新的备库重建完成之前为新的主库提供备份,但显然这会让系统配置和操作流程更加复杂。 + 一旦故障切换到备库,系统中就只剩下一台服务器在运行。这被称为退化状态。原来的备库现在成为主库,而原来的主库已经停机,并且可能持续停机。要恢复到正常运行状态,就必须重新创建一台备库:要么在原主库恢复后在其上重建,要么在第三台可能是全新的服务器上重建。在大型集簇上,可以使用工具来加快这一过程。一旦完成,就可以认为主库和备库已经交换了角色。有些人会选择使用第三台服务器,在新的备库重建完成之前为新的主库提供后备支持,但显然这会让系统配置和操作流程更加复杂。 @@ -817,7 +835,7 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' 注意,在这种模式下,服务器每次应用一整个 WAL 文件。因此,如果使用备库处理查询(参见热备),主库上的操作与备库上能看到该操作的结果之间,会有一段延迟,其长度相当于写满一个 WAL 文件所需的时间。可以用 archive_timeout 缩短这一延迟。还要注意,这种方法不能与流复制结合使用。 - 主库和备库上执行的操作都是普通的连续归档和恢复任务。两台数据库服务器之间唯一的联系,就是它们共享的 WAL 文件归档:主库写入归档,备库从归档读取。必须确保不同主库的 WAL 归档不会混在一起或弄错。如果归档仅用于备库运行,则无需保留很大的归档。 + 主库和备库上执行的操作都是普通的持续归档和恢复任务。两台数据库服务器之间唯一的联系,就是它们共享的 WAL 文件归档:主库写入归档,备库从归档读取。必须确保不同主库的 WAL 归档不会混在一起或弄错。如果归档仅用于备库运行,则无需保留很大的归档。 让这两台松散耦合的服务器协同工作的关键,只是备库上的 restore_command:当请求下一个 WAL 文件时,它会等待主库提供该文件。正常恢复处理会从 WAL 归档请求文件,如果文件不可用,就报告失败。对备库处理而言,下一个 WAL 文件尚不可用是正常情况,因此备库必须等待它出现。对于以 .history 结尾的文件,则无需等待,必须返回非零返回码。可以编写一个自定义脚本,循环检查下一个 WAL 文件是否存在,从而实现会等待的 restore_command。还必须提供触发故障切换的方法,用来中断 restore_command、跳出循环,并向备库返回文件未找到错误。这会结束恢复,随后备库就会作为普通服务器启动。 @@ -846,7 +864,7 @@ if (!triggered) 尽可能将主库和备库系统配置得相同,包括安装两个完全相同、发行版本一致的 PostgreSQL 副本。 - 配置连续归档,将主库的 WAL 归档到备库上的一个目录。确保在主库上正确设置 (参见 )。 + 配置持续归档,将主库的 WAL 归档到备库上的一个目录。确保在主库上正确设置 (参见 )。 制作主库的基础备份(参见 ),并将这些数据装载到备库上。 @@ -892,25 +910,34 @@ if (!triggered) 用户概览 - 当备库上的参数被设置为真时,一旦恢复把系统带到一致状态并为热备做好准备,它就会开始接受连接。所有这类连接都严格是只读的,甚至不能写入临时表。 + 当备库上的参数被设置为真时,一旦恢复把系统带到一致状态,它就会开始接受连接。所有这类连接都严格是只读的,甚至不能写入临时表。 备库上的数据需要一些时间才能从主库到达,因此主库和备库之间会有可测量的延迟。因此,在主库和备库上几乎同时运行同一查询,可能会返回不同的结果。我们说备库上的数据与主库是最终一致的。一旦某个事务的提交记录在备库上被重放,该事务所做的修改就会对备库上之后取得的所有新快照可见。快照可以在每个查询开始时取得,也可以在每个事务开始时取得,这取决于当前的事务隔离级别。详见 - 热备期间启动的事务可以执行以下命令: + + 在热备期间启动的事务可以发出下列命令: + + - 查询访问 - SELECTCOPY TO + + 查询访问:SELECTCOPY TO + - 游标命令 - DECLAREFETCHCLOSE + + 游标命令:DECLAREFETCHCLOSE + - 参数 - SHOWSETRESET + 参数:SHOWSETRESET - 事务管理命令 + + 事务管理命令: + BEGINENDABORTSTART TRANSACTION @@ -923,7 +950,7 @@ if (!triggered) - EXCEPTION块或其他内部子事务 + EXCEPTION块和其他内部子事务 @@ -936,10 +963,15 @@ if (!triggered) - 计划和资源 - PREPAREEXECUTEDEALLOCATEDISCARD + + 计划和资源:PREPAREEXECUTE、 + DEALLOCATEDISCARD + - 插件和扩展 - LOAD + + 插件和扩展:LOAD + @@ -949,12 +981,23 @@ if (!triggered) - 热备期间启动的事务不会被分配事务 ID,也不能写入系统的预写式日志。因此,以下操作会产生错误消息: + + 在热备期间启动的事务永远不会被分配事务 ID,也不能写入系统预写式日志。因此,下列动作都会产生错误消息: + + - 数据操纵语言(DML)- INSERTUPDATEDELETECOPY FROMTRUNCATE。注意,恢复期间不允许任何会导致触发器执行的操作。这一限制也适用于临时表,因为不分配事务 ID 就无法读写表中的行,而目前热备环境中无法分配事务 ID。 + + 数据操纵语言(DML):INSERT、 + UPDATEDELETE、 + COPY FROM、 + TRUNCATE。请注意,恢复期间不存在任何允许执行触发器的动作。这个限制甚至适用于临时表,因为不分配事务 ID 就无法读取或写入表行,而目前热备环境中无法分配事务 ID。 + - 数据定义语言(DDL)- CREATEDROPALTERCOMMENT。这一限制也适用于临时表,因为执行这些操作需要更新系统目录表。 + + 数据定义语言(DDL):CREATE、 + DROPALTERCOMMENT。这个限制甚至适用于临时表,因为执行这些操作需要更新系统目录表。 + @@ -982,13 +1025,13 @@ if (!triggered) - BEGIN READ WRITE, + BEGIN READ WRITESTART TRANSACTION READ WRITE - SET TRANSACTION READ WRITE, + SET TRANSACTION READ WRITESET SESSION CHARACTERISTICS AS TRANSACTION READ WRITE @@ -1001,10 +1044,16 @@ if (!triggered) - 两阶段提交命令 - PREPARE TRANSACTIONCOMMIT PREPAREDROLLBACK PREPARED,因为即使只读事务也需要在准备阶段(两阶段提交的第一阶段)写入 WAL。 + + 两阶段提交命令:PREPARE TRANSACTION、 + COMMIT PREPAREDROLLBACK PREPARED, + 因为即使是只读事务,在准备阶段(两阶段提交的第一阶段)也需要写入 WAL。 + - 序列更新 - nextval()setval() + + 序列更新:nextval()setval() + @@ -1082,19 +1131,17 @@ if (!triggered) - 一旦max_standby_archive_delaymax_standby_streaming_delay指定的延迟被超越,冲突查询将被取消。这通常仅导致一个取消错误,尽管在重放一个DROP DATABASE的情况下整个冲突会话都将被中断。另外,如果冲突发生在一个被空闲事务持有的锁上,该冲突会话会被中断(这种行为可能在未来被改变)。 + 一旦max_standby_archive_delaymax_standby_streaming_delay指定的延迟被超越,冲突查询将被取消。这通常仅导致一个取消错误,尽管在重放一个DROP DATABASE的情况下整个冲突会话都将被终止。另外,如果冲突发生在一个被空闲事务持有的锁上,该冲突会话会被终止(这种行为可能在未来被改变)。 - - 被取消的查询可能会立即被重试(当然是在开始一个新的事务后)。因为查询取消依赖于 WAL 记录被重放的本质,如果一个被取消的查询被再次执行,它可能会很好地成功完成。 - + 被取消的查询可以立即重试(当然,要先开始一个新事务)。由于查询取消取决于正在重放的 WAL 记录的性质,被取消的查询再次执行时完全可能成功。 - 记住延迟参数是从 WAL 数据被备库收到后流逝的时间。因此,留给备库上任何一个查询的宽限期从不会超过延迟参数,并且如果备库已经由于等待之前的查询完成而落后或者因为过重的更新负载而无法跟上主库,宽限期可能会更少。 + 请记住,延迟参数要与备库收到 WAL 数据之后经过的时间进行比较。因此,留给备库上任何一个查询的宽限期从不会超过延迟参数,并且如果备库已经由于等待之前的查询完成而落后或者因为过重的更新负载而无法跟上主库,宽限期可能会更少。 - 备库查询与 WAL 重放发生冲突的最常见原因是过早清理。正常情况下,当没有事务需要看到旧行版本时,PostgreSQL允许清理这些旧行版本,以保证按照 MVCC 规则得到正确的数据可见性。不过,这条规则只能应用于在主库上执行的事务。因此,主库上的清理有可能移除某个备库事务仍然可见的行版本。 + 备库查询与 WAL 重放发生冲突的最常见原因是过早清理。正常情况下,当不再有事务需要看到旧行版本来保证符合 MVCC 规则的数据可见性时,PostgreSQL允许清理这些旧行版本。不过,这条规则只能应用于在主库上执行的事务。因此,主库上的清理有可能移除某个备库事务仍然可见的行版本。 有经验的用户应注意,行版本清理和行版本冻结都有可能与备库查询冲突。手动运行 VACUUM FREEZE 很可能导致冲突,即使表中没有更新过或删除过的行也是如此。 @@ -1172,18 +1219,29 @@ LOG: database system is ready to accept read only connections - 主库上写出的事务状态 "hint bits" 不会被 WAL 记录,因此备库上的数据很可能会再次写出这些提示位。这样一来,即使所有用户都是只读的,备库仍然会执行磁盘写操作;不过数据值本身并不会发生变化。用户仍然会写出大型排序临时文件,并重新生成 relcache 信息文件,因此在热备模式下,数据库没有任何部分是真正只读的。还要注意,使用dblink模块写入远程数据库,以及借助 PL 函数执行其他数据库外部操作,依然是可能的,即使该事务在本地是只读的。 + 主库上写出的事务状态“提示位” 不会被 WAL 记录,因此备库上的数据很可能会再次写出这些提示位。这样一来,即使所有用户都是只读的,备库仍然会执行磁盘写操作;不过数据值本身并不会发生变化。用户仍然会写出大型排序临时文件,并重新生成 relcache 信息文件,因此在热备模式下,数据库没有任何部分是真正只读的。还要注意,使用dblink模块写入远程数据库,以及借助 PL 函数执行其他数据库外部操作,依然是可能的,即使该事务在本地是只读的。 - 恢复模式下不接受以下类型的管理命令: + + 在恢复模式下,不接受下列类型的管理命令: + + - 数据定义语言(DDL)- 例如 CREATE INDEX + + 数据定义语言(DDL):例如 CREATE INDEX + - 权限和所有权 - GRANTREVOKEREASSIGN + + 权限和所有权:GRANTREVOKE、 + REASSIGN + - 维护命令 - ANALYZEVACUUMCLUSTERREINDEX + + 维护命令:ANALYZEVACUUM、 + CLUSTERREINDEX + @@ -1228,7 +1286,9 @@ LOG: database system is ready to accept read only connections 不能分配新的 OID,不过某些UUID生成器仍可工作,只要它们不依赖于向数据库写入新的状态。 - 目前,不允许在只读事务中创建临时表,因此现有脚本在某些情况下无法正确运行。未来版本可能会放宽这一限制。这既涉及 SQL 标准兼容性,也涉及技术问题。 + + 目前,在只读事务期间不允许创建临时表,因此某些现有脚本在这种情况下将无法正常运行。这个限制可能会在未来版本中放宽。这既涉及 SQL 标准兼容性问题,也涉及技术问题。 + 只有在表空间为空时DROP TABLESPACE才能成功。某些备库用户可能正在通过他们的temp_tablespaces参数使用该表空间。如果该表空间中存在临时文件,所有活动查询都将被取消,以确保临时文件被移除,这样该表空间才能被移除并且 WAL 重放可以继续。 @@ -1238,7 +1298,9 @@ LOG: database system is ready to accept read only connections 在主库上执行DROP DATABASEALTER DATABASE ... SET TABLESPACE会生成一条 WAL 记录,从而强制断开备库上所有连接到该数据库的用户。这个动作会立即发生,而不受max_standby_streaming_delay设置的影响。注意,ALTER DATABASE ... RENAME不会断开用户,这在大多数情况下不会被注意到,但如果程序依赖某种基于数据库名的机制,在某些情况下可能会导致混乱。 - 在正常(非恢复)模式下,如果对具有登录能力的角色执行 DROP USERDROP ROLE,而该用户仍处于连接状态,已连接的用户不会受到影响,会继续保持连接。不过,该用户无法重新连接。恢复期间也是如此,因此,在主库上执行 DROP USER 不会断开该用户在备库上的连接。 + + 在普通(非恢复)模式下,如果你对一个具有登录能力的角色执行DROP USERDROP ROLE,而该用户仍然处于连接状态,那么已连接用户不会发生任何变化 — 他们会继续保持连接,不过之后不能重新连接。这种行为在恢复期间同样适用,因此在主库上执行一次DROP USER并不会断开备库上的该用户连接。 + 统计收集器在恢复期间保持活动状态。所有扫描、读取、块、索引使用情况等,都会在备库上正常记录。重放操作不会重复记录其在主库上产生的统计影响,因此重放一次插入不会增加 pg_stat_user_tables 的 Inserts 列。统计文件会在恢复开始时被删除,因此主库和备库的统计信息不同;这是特性,不是缺陷。 @@ -1266,9 +1328,15 @@ LOG: database system is ready to accept read only connections 注意事项 - 热备有几个限制。这些限制能够、也很可能会在未来版本中消除: + + 热备有若干限制。 + 这些限制在未来的版本中可以、也很可能会被修复: + + - 必须完整掌握正在运行的事务,才能取得快照。如果事务使用了大量子事务(目前为超过 64 个),只读连接的开始时间就会延迟,直到运行时间最长的写事务完成。发生这种情况时,服务器日志中会记录说明消息。 + + 在能够取得快照之前,必须完整了解正在运行的事务。使用大量子事务(目前超过 64 个)的事务,会把只读连接的启动推迟到持续时间最长的写事务完成之后。如果发生这种情况,服务器日志中会发送解释性消息。 + diff --git a/zh/12/history.sgml b/zh/12/history.sgml index ae5b49e0..2e00b444 100644 --- a/zh/12/history.sgml +++ b/zh/12/history.sgml @@ -151,6 +151,8 @@ 不过各个方面的工作仍在继续。 - 关于此后PostgreSQL发生了哪些变化的详情,可在中查阅。 + + 自那以后 PostgreSQL 发生了哪些变化,可见 。 + diff --git a/zh/12/images/fixup-svg.xsl b/zh/12/images/fixup-svg.xsl index d6c46b36..cf7169bb 100644 --- a/zh/12/images/fixup-svg.xsl +++ b/zh/12/images/fixup-svg.xsl @@ -32,6 +32,11 @@ Fix stroke="transparent" attribute, which is invalid SVG. none + + + 'Alibaba PuHuiTi 3.0',serif + + diff --git a/zh/12/images/gin.gv b/zh/12/images/gin.gv index 097e9102..b8e26542 100644 --- a/zh/12/images/gin.gv +++ b/zh/12/images/gin.gv @@ -1,11 +1,12 @@ digraph "gin" { layout=dot; - node [label="", shape=box, style=filled, fillcolor=gray, width=1.4]; + fontname="Alibaba PuHuiTi 3.0"; + node [fontname="Alibaba PuHuiTi 3.0", label="", shape=box, style=filled, fillcolor=gray, width=1.4]; - m1 [label="meta page"]; + m1 [label="元页"]; subgraph cluster01 { - label="entry tree"; + label="键项树"; subgraph egroup1 { rank=same; e1; @@ -27,13 +28,13 @@ digraph "gin" { e4 -> e8; e4 -> e9; - e6 [fillcolor=green, label="posting list"]; - e8 [fillcolor=green, label="posting list"]; - e9 [fillcolor=green, label="posting list"]; + e6 [fillcolor=green, label="倒排列表"]; + e8 [fillcolor=green, label="倒排列表"]; + e9 [fillcolor=green, label="倒排列表"]; } subgraph cluster02 { - label="posting tree"; + label="倒排树"; subgraph pgroup1 { rank=same; p1; @@ -45,22 +46,22 @@ digraph "gin" { p1 -> p2; p1 -> p3; - p2 [fillcolor=green, label="heap ptr"]; - p3 [fillcolor=green, label="heap ptr"]; + p2 [fillcolor=green, label="堆指针"]; + p3 [fillcolor=green, label="堆指针"]; } subgraph cluster03 { - label="posting tree"; + label="倒排树"; subgraph pgroup3 { rank=same; p4; } - p4 [fillcolor=green, label="heap ptr"]; + p4 [fillcolor=green, label="堆指针"]; } subgraph cluster04 { - label="posting tree"; + label="倒排树"; subgraph pgroup4 { rank=same; p5; @@ -72,12 +73,12 @@ digraph "gin" { p5 -> p6; p5 -> p7; - p6 [fillcolor=green, label="heap ptr"]; - p7 [fillcolor=green, label="heap ptr"]; + p6 [fillcolor=green, label="堆指针"]; + p7 [fillcolor=green, label="堆指针"]; } subgraph cluster05 { - label="pending list"; + label="待处理列表"; node [style=filled, fillcolor=red]; n1 -> n2 -> n3 -> n4; } diff --git a/zh/12/images/gin.svg b/zh/12/images/gin.svg index 04fe85ba..79cf14a9 100644 --- a/zh/12/images/gin.svg +++ b/zh/12/images/gin.svg @@ -9,33 +9,33 @@ cluster01 -entry tree +键项树 cluster02 -posting tree +倒排树 cluster03 -posting tree +倒排树 cluster04 -posting tree +倒排树 cluster05 -pending list +待处理列表 m1 -meta page +元页 @@ -113,7 +113,7 @@ e6 -posting list +倒排列表 @@ -142,7 +142,7 @@ e8 -posting list +倒排列表 @@ -154,7 +154,7 @@ e9 -posting list +倒排列表 @@ -195,7 +195,7 @@ p4 -heap ptr +堆指针 @@ -224,7 +224,7 @@ p2 -heap ptr +堆指针 @@ -236,7 +236,7 @@ p3 -heap ptr +堆指针 @@ -254,7 +254,7 @@ p6 -heap ptr +堆指针 @@ -266,7 +266,7 @@ p7 -heap ptr +堆指针 diff --git a/zh/12/indexam.sgml b/zh/12/indexam.sgml index a06a2a60..1cdf4337 100644 --- a/zh/12/indexam.sgml +++ b/zh/12/indexam.sgml @@ -42,65 +42,65 @@ typedef struct IndexAmRoutine NodeTag type; /* - * Total number of strategies (operators) by which we can traverse/search - * this AM. Zero if AM does not have a fixed set of strategy assignments. + * 可用于遍历或搜索此 AM 的策略(操作符)总数。 + * 如果 AM 没有固定的一组策略分配,则为零。 */ uint16 amstrategies; - /* total number of support functions that this AM uses */ + /* 此 AM 使用的支持函数总数 */ uint16 amsupport; - /* does AM support ORDER BY indexed column's value? */ + /* AM 是否支持按被索引列的值进行 ORDER BY? */ bool amcanorder; - /* does AM support ORDER BY result of an operator on indexed column? */ + /* AM 是否支持按被索引列上操作符的结果进行 ORDER BY? */ bool amcanorderbyop; - /* does AM support backward scanning? */ + /* AM 是否支持反向扫描? */ bool amcanbackward; - /* does AM support UNIQUE indexes? */ + /* AM 是否支持 UNIQUE 索引? */ bool amcanunique; - /* does AM support multi-column indexes? */ + /* AM 是否支持多列索引? */ bool amcanmulticol; - /* does AM require scans to have a constraint on the first index column? */ + /* AM 是否要求扫描必须约束第一个索引列? */ bool amoptionalkey; - /* does AM handle ScalarArrayOpExpr quals? */ + /* AM 是否处理 ScalarArrayOpExpr 限定条件? */ bool amsearcharray; - /* does AM handle IS NULL/IS NOT NULL quals? */ + /* AM 是否处理 IS NULL/IS NOT NULL 限定条件? */ bool amsearchnulls; - /* can index storage data type differ from column data type? */ + /* 索引存储数据类型是否可以不同于列数据类型? */ bool amstorage; - /* can an index of this type be clustered on? */ + /* 是否可以按此类型的索引进行聚簇? */ bool amclusterable; - /* does AM handle predicate locks? */ + /* AM 是否处理谓词锁? */ bool ampredlocks; - /* does AM support parallel scan? */ + /* AM 是否支持并行扫描? */ bool amcanparallel; - /* does AM support columns included with clause INCLUDE? */ + /* AM 是否支持由 INCLUDE 子句包含的列? */ bool amcaninclude; - /* type of data stored in index, or InvalidOid if variable */ + /* 索引中存储的数据类型;如果可变,则为 InvalidOid */ Oid amkeytype; - /* interface functions */ + /* 接口函数 */ ambuild_function ambuild; ambuildempty_function ambuildempty; aminsert_function aminsert; ambulkdelete_function ambulkdelete; amvacuumcleanup_function amvacuumcleanup; - amcanreturn_function amcanreturn; /* can be NULL */ + amcanreturn_function amcanreturn; /* 可以为 NULL */ amcostestimate_function amcostestimate; amoptions_function amoptions; - amproperty_function amproperty; /* can be NULL */ - ambuildphasename_function ambuildphasename; /* can be NULL */ + amproperty_function amproperty; /* 可以为 NULL */ + ambuildphasename_function ambuildphasename; /* 可以为 NULL */ amvalidate_function amvalidate; ambeginscan_function ambeginscan; amrescan_function amrescan; - amgettuple_function amgettuple; /* can be NULL */ - amgetbitmap_function amgetbitmap; /* can be NULL */ + amgettuple_function amgettuple; /* 可以为 NULL */ + amgetbitmap_function amgetbitmap; /* 可以为 NULL */ amendscan_function amendscan; - ammarkpos_function ammarkpos; /* can be NULL */ - amrestrpos_function amrestrpos; /* can be NULL */ + ammarkpos_function ammarkpos; /* 可以为 NULL */ + amrestrpos_function amrestrpos; /* 可以为 NULL */ - /* interface functions to support parallel index scans */ - amestimateparallelscan_function amestimateparallelscan; /* can be NULL */ - aminitparallelscan_function aminitparallelscan; /* can be NULL */ - amparallelrescan_function amparallelrescan; /* can be NULL */ + /* 支持并行索引扫描的接口函数 */ + amestimateparallelscan_function amestimateparallelscan; /* 可以为 NULL */ + aminitparallelscan_function aminitparallelscan; /* 可以为 NULL */ + amparallelrescan_function amparallelrescan; /* 可以为 NULL */ } IndexAmRoutine; @@ -178,7 +178,7 @@ ambulkdelete (IndexVacuumInfo *info, IndexBulkDeleteCallback callback, void *callback_state); - 从索引中删除元组。这是一个批量删除操作,通常应通过扫描整个索引并检查每个条目是否应被删除来实现。必须调用传入的 callback 函数,其调用形式为 callback(TID, callback_state) returns bool,以确定由其引用 TID 标识的某个索引条目是否应删除。该函数必须返回 NULL,或者返回一个通过 palloc 分配的结构体,其中包含此次删除操作影响的统计信息。如果不需要向 amvacuumcleanup 传递信息,返回 NULL 也是可以的。 + 从索引中删除元组。这是一个批量删除操作,旨在通过扫描整个索引并检查每个条目是否应被删除来实现。必须调用传入的 callback 函数,其调用形式为 callback(TID, callback_state) returns bool,以确定由其引用 TID 标识的某个索引条目是否应删除。该函数必须返回 NULL,或者返回一个通过 palloc 分配的结构体,其中包含此次删除操作影响的统计信息。如果不需要向 amvacuumcleanup 传递信息,返回 NULL 也是可以的。 @@ -202,8 +202,9 @@ amvacuumcleanup (IndexVacuumInfo *info, bool amcanreturn (Relation indexRelation, int attno); -检查索引是否可以支持仅索引扫描,方法是返回给定列的原始被索引值。属性编号从 1 开始,即第一列的 attno 为 1。支持时返回真,否则返回假。对于包含列(如果支持),此函数应始终返回真,因为无法取回值的包含列没有什么意义。如果访问方法完全不支持仅索引扫描,则其amcanreturn字段在其IndexAmRoutine结构体中可以设为 NULL。 + + 检查索引能否通过返回给定列原始的被索引值,在该列上支持 仅索引扫描。属性编号从 1 开始,也就是说第一列的 attno 为 1。若支持则返回真,否则返回假。如果支持包含列,这个函数应始终对包含列返回真,因为不能取回的包含列几乎没有意义。如果访问方法根本不支持仅索引扫描,那么它的 IndexAmRoutine 结构体中的 amcanreturn 字段可以设为 NULL。 + @@ -216,7 +217,9 @@ amcostestimate (PlannerInfo *root, Selectivity *indexSelectivity, double *indexCorrelation, double *indexPages); -估计一次索引扫描的开销。该函数的完整说明见(见下文)。 + + 估计一次索引扫描的代价。该函数将在后面的 中详细讨论。 + @@ -224,7 +227,7 @@ bytea * amoptions (ArrayType *reloptions, bool validate); - 解析并验证索引的 reloptions 数组。只有当该索引存在非空的 reloptions 数组时才会调用此函数。reloptions 是一个 text 数组,其中的条目形如 name=value。该函数应构造一个 bytea 值,并将其复制到索引 relcache 条目的 rd_options 字段中。这个 bytea 值中的数据内容由访问方法自行定义;大多数标准访问方法使用结构体 StdRdOptions。当 validate 为真时,若存在未识别选项或无效取值,函数应报告合适的错误消息;当 validate 为假时,无效条目应被静默忽略。(当装载已存储在 pg_catalog 中的选项时,validate 为假;此时只有在访问方法改变了选项规则时才可能发现无效条目,而忽略过时条目是合适的。)如果希望采用默认行为,返回 NULL 也是可以的。 + 解析并验证索引的 reloptions 数组。只有当该索引存在非 NULL 的 reloptions 数组时才会调用此函数。reloptions 是一个 text 数组,其中的条目形如 name=value。该函数应构造一个 bytea 值,并将其复制到索引 relcache 条目的 rd_options 字段中。这个 bytea 值中的数据内容由访问方法自行定义;大多数标准访问方法使用结构体 StdRdOptions。当 validate 为真时,若存在未识别选项或无效取值,函数应报告合适的错误消息;当 validate 为假时,无效条目应被静默忽略。(当装载已存储在 pg_catalog 中的选项时,validate 为假;此时只有在访问方法改变了选项规则时才可能发现无效条目,而忽略过时条目是合适的。)如果希望采用默认行为,返回 NULL 也是可以的。 @@ -236,7 +239,7 @@ amproperty (Oid index_oid, int attno, 该amproperty方法允许索引访问方法覆盖pg_index_column_has_property及其相关函数的默认行为。如果访问方法对索引属性查询没有任何特殊行为,那么amproperty字段在其IndexAmRoutine结构体中可以设为 NULL。否则,amproperty方法会收到如下调用参数:index_oidattno均为零,对应pg_indexam_has_property调用;或者index_oid有效且attno为零,对应pg_index_has_property调用;或者index_oid有效且attno大于零,对应pg_index_column_has_property调用。prop是一个枚举值,用来标识当前测试的属性;propname则是原始属性名字符串。如果核心代码不认识该属性名,那么propAMPROP_UNKNOWN。访问方法可以通过检查propname是否匹配来定义自定义属性名(使用pg_strcasecmp进行匹配,以与核心代码保持一致);对于核心代码已知的名称,最好检查prop。如果amproperty方法返回true,则表示它已确定属性测试结果:它必须将*res设为要返回的布尔值,或者把*isnull设为true以返回 NULL。(所引用的两个变量在调用前都初始化为false。)如果amproperty方法返回false,核心代码就会按其正常逻辑确定属性测试结果。 - 支持排序操作符的访问方法应当实现 AMPROP_DISTANCE_ORDERABLE 属性测试,因为核心代码不知道如何完成该测试,只会返回 NULL。若实现成本低于打开索引并调用 amcanreturn(这正是核心代码的默认行为),那么实现 AMPROP_RETURNABLE 测试也可能是有利的。对于其他所有标准属性,默认行为应当已经足够。 + 支持排序操作符的访问方法应当实现 AMPROP_DISTANCE_ORDERABLE 属性测试,因为核心代码不知道如何完成该测试,只会返回 NULL。若完成该测试的代价低于打开索引并调用 amcanreturn(这正是核心代码的默认行为),那么实现 AMPROP_RETURNABLE 测试也可能是有利的。对于其他所有标准属性,默认行为应当已经足够。 @@ -264,7 +267,8 @@ IndexScanDesc ambeginscan (Relation indexRelation, int nkeys, int norderbys); -为索引扫描做准备。nkeysnorderbys参数指明扫描中将使用的限定条件和排序操作符的数量,可用于分配空间。注意,此时尚未提供扫描键的实际值。结果必须是用 palloc 分配的结构体。由于实现方面的原因,索引访问方法必须调用RelationGetIndexScan()来创建此结构体。大多数情况下,ambeginscan除了执行该调用以及可能获取锁之外,几乎不做其他工作;索引扫描启动过程的主要工作位于amrescan。 + + 为一次索引扫描做准备。nkeysnorderbys 参数表示扫描中将使用的限定条件和排序操作符数量,这些信息可能有助于空间分配。请注意,此时还没有提供扫描键的实际值。结果必须是一个通过 palloc 分配的结构体。出于实现上的原因,索引访问方法必须通过调用 RelationGetIndexScan() 来创建这个结构体。大多数情况下,ambeginscan 除了做这次调用以及也许获取一些锁之外,不会做太多工作;索引扫描启动中真正有意思的部分在 amrescan 中。 @@ -284,10 +288,12 @@ amrescan (IndexScanDesc scan, bool amgettuple (IndexScanDesc scan, ScanDirection direction); -沿给定方向(在索引中向前或向后)获取给定扫描中的下一个元组。如果取得元组,则返回 true;如果没有剩余的匹配元组,则返回 false。返回 true 时,将元组 TID 存储到scan结构体中。注意,成功仅表示索引中包含与扫描键匹配的条目,并不表示该元组一定仍存在于堆中,或者能够通过调用方的快照测试。成功时,amgettuple还必须将scan->xs_recheck设为 true 或 false。false 表示可以确定索引条目与扫描键匹配;true 表示尚不确定,在获取堆元组后,必须对它重新检查扫描键所表示的条件。这一规定支持有损索引操作符。注意,重新检查仅针对扫描条件;部分索引谓词(如果有)永远不会由amgettuple的调用方重新检查。 + + 在给定扫描中取出下一个元组,并按给定方向移动(在索引中向前或向后)。若成功取得元组则返回真;若不再有匹配元组则返回假。在返回真时,元组的 TID 会存入 scan 结构体中。请注意,成功仅表示索引中存在一个匹配扫描键的条目,并不表示该元组一定仍然存在于堆中,或者一定能通过调用者的快照测试。成功时,amgettuple 还必须把 scan->xs_recheck 设为真或假。假表示可以确定该索引条目匹配扫描键;真表示这一点并不确定,因此在取到堆元组后必须根据扫描键所代表的条件重新检查它。这一机制支持有损索引操作符。请注意,重检只针对扫描条件;部分索引谓词(如果有)永远不会由 amgettuple 的调用者重新检查。 + - 如果索引支持 仅索引扫描(即其任一列上 amcanreturn 返回真),那么成功时 AM 还必须检查 scan->xs_want_itup;若其为真,就必须返回该索引条目的原始被索引数据。对于 amcanreturn 返回假的列,可以把其值作为 NULL 返回。数据可以通过以下两种形式之一返回:一种是把 IndexTuple 指针存入 scan->xs_itup,其元组描述符为 scan->xs_itupdesc;另一种是把 HeapTuple 指针存入 scan->xs_hitup,其元组描述符为 scan->xs_hitupdesc。(当重建出的数据可能装不进 IndexTuple 时,应使用后一种格式。)无论采用哪种形式,指针所引用数据的管理责任都在访问方法一侧。对这份数据的有效性必须至少保持到该扫描下一次调用 amgettupleamrescanamendscan 为止。 + 如果索引支持 仅索引扫描(即其至少一列上 amcanreturn 返回真),那么成功时 AM 还必须检查 scan->xs_want_itup;若其为真,就必须返回该索引条目的原始被索引数据。对于 amcanreturn 返回假的列,可以把其值作为 NULL 返回。数据可以通过以下两种形式之一返回:一种是把 IndexTuple 指针存入 scan->xs_itup,其元组描述符为 scan->xs_itupdesc;另一种是把 HeapTuple 指针存入 scan->xs_hitup,其元组描述符为 scan->xs_hitupdesc。(当重建出的数据可能装不进 IndexTuple 时,应使用后一种格式。)无论采用哪种形式,指针所引用数据的管理责任都在访问方法一侧。这份数据必须至少保持有效,直到该扫描下一次调用 amgettupleamrescanamendscan @@ -299,7 +305,8 @@ amgettuple (IndexScanDesc scan, int64 amgetbitmap (IndexScanDesc scan, TIDBitmap *tbm); -获取给定扫描中的所有元组,并将其加入调用方提供的TIDBitmap中(即将元组 ID 集合与位图中已有的集合做 OR 运算)。返回获取到的元组数量(可能只是近似值,例如某些访问方法不检测重复项)。向位图插入元组 ID 时,amgetbitmap可以指明需要对特定元组 ID 重新检查扫描条件。这类似于xs_recheck输出参数,它属于amgettuple。注意:在当前实现中,此特性的支持与位图自身有损存储的支持混在一起,因此对于需要重查的元组,调用方会重新检查扫描条件和部分索引谓词(如果有)。但将来未必始终如此。amgetbitmapamgettuple不能在同一次索引扫描中使用;使用amgetbitmap时还有其他限制,详见。 + + 取出给定扫描中的所有元组,并将其加入调用者提供的 TIDBitmap 中(也就是把这组元组 ID 与位图中已有的集合做 OR)。返回值是取得的元组数量(这可能只是近似计数,例如某些 AM 不会检测重复项)。在把元组 ID 插入位图时,amgetbitmap 可以指出某些具体的元组 ID 需要重新检查扫描条件。这类似于 amgettuplexs_recheck 输出参数。注意:在当前实现中,对这一特性的支持与位图自身的有损存储支持混在一起,因此调用者会对需要重检的元组同时重新检查扫描条件和部分索引谓词(如果有)。不过,这并不一定永远如此。amgetbitmapamgettuple 不能在同一次索引扫描中同时使用;使用 amgetbitmap 时还有其他限制,详见 @@ -311,7 +318,7 @@ amgetbitmap (IndexScanDesc scan, void amendscan (IndexScanDesc scan); - 结束一次扫描并释放资源。scan 结构体本身不应被释放,但访问方法内部获取的任何锁或 pin,以及由 ambeginscan 和其他扫描相关函数分配的其他内存,都必须被释放。 + 结束一次扫描并释放资源。scan 结构体本身不应被释放,但必须释放访问方法内部获取的所有锁、解除所有钉住状态,并释放由 ambeginscan 和其他扫描相关函数分配的其他内存。 @@ -428,7 +435,7 @@ amparallelrescan (IndexScanDesc scan); - 除了使用 amgettuple 外,索引扫描也可以使用 amgetbitmap,在一次调用中取出所有元组。与 amgettuple 相比,这通常明显更高效,因为它可以避免访问方法内部的反复加锁和解锁。原则上,amgetbitmap 应具有与重复调用 amgettuple 相同的效果,但为了简化实现,我们施加了若干限制。首先,amgetbitmap 一次性返回全部元组,因此不支持标记或恢复扫描位置。其次,元组是通过一个位图返回的,没有特定顺序,这也是为什么 amgetbitmap 不带 direction 参数的原因。(这种扫描也永远不会提供排序操作符。)此外,使用 amgetbitmap 时也没有仅索引扫描的支持,因为没有办法返回索引元组的内容。最后,amgetbitmap 不保证对返回的元组做任何锁定,其影响见 。 + 除了使用 amgettuple 外,索引扫描也可以使用 amgetbitmap,在一次调用中取出所有元组。与 amgettuple 相比,这可能明显更高效,因为它可以避免访问方法内部的反复加锁和解锁。原则上,amgetbitmap 应具有与重复调用 amgettuple 相同的效果,但为了简化实现,我们施加了若干限制。首先,amgetbitmap 一次性返回全部元组,因此不支持标记或恢复扫描位置。其次,元组是通过一个位图返回的,没有特定顺序,这也是为什么 amgetbitmap 不带 direction 参数的原因。(这种扫描也永远不会提供排序操作符。)此外,使用 amgetbitmap 时也没有仅索引扫描的支持,因为没有办法返回索引元组的内容。最后,amgetbitmap 不保证对返回的元组做任何锁定,其影响见 @@ -445,7 +452,7 @@ amparallelrescan (IndexScanDesc scan); - 构建一种支持并发更新的索引类型,通常需要对所需行为进行大量而细致的分析。对于 B-树和哈希索引类型,可以阅读 src/backend/access/nbtree/READMEsrc/backend/access/hash/README 中涉及的设计决策。 + 构建一种支持并发更新的索引类型,通常需要对所需行为进行大量而细致的分析。对于 B-树和 hash 索引类型,可以阅读 src/backend/access/nbtree/READMEsrc/backend/access/hash/README 中涉及的设计决策。 @@ -464,12 +471,12 @@ amparallelrescan (IndexScanDesc scan); - 索引扫描必须在保存 amgettuple 最近一次返回条目的索引页面上维护一个 pin,而 ambulkdelete 不能从被其他后端钉住的页面中删除条目。下面会解释为什么需要这条规则。 + 索引扫描必须在保存 amgettuple 最近一次返回条目的索引页面上保持钉住状态,而 ambulkdelete 不能从被其他后端钉住的页面中删除条目。下面会解释为什么需要这条规则。 - 如果没有第三条规则,索引读取者就有可能在某个索引条目被 VACUUM 删除之前先看到它,然后在对应的堆条目已被 VACUUM 删除之后才到达那里。如果读取者到达时,该项号仍未被重新使用,就不会造成严重问题,因为空项槽位会被 heap_fetch() 忽略。但如果第三个后端已经把这个项槽位重新用作别的东西呢?在使用 MVCC 兼容快照时不会有问题,因为该槽位的新占用者一定太新,无法通过快照测试。然而,对于非 MVCC 兼容的快照(例如 SnapshotAny),就可能错误地接受并返回一行实际上并不匹配扫描键的数据。我们可以要求在所有情况下都对堆行重新检查扫描键,以防范这种情形,但那样代价太高。于是,我们改为把索引页面上的 pin 作为一种代理,表示读取者可能仍处于从索引条目前往匹配堆条目的飞行中。让 ambulkdelete 在这种 pin 上阻塞,能够保证 VACUUM 不会在读取者处理完之前删除对应的堆条目。这种方案运行时开销很小,只有在真正发生冲突的少数情况下才会增加阻塞开销。 + 如果没有第三条规则,索引读取者就有可能在某个索引条目被 VACUUM 删除之前先看到它,然后在对应的堆条目已被 VACUUM 删除之后才到达那里。如果读取者到达时,该项号仍未被重新使用,就不会造成严重问题,因为空项槽位会被 heap_fetch() 忽略。但如果第三个后端已经把这个项槽位重新用作别的东西呢?在使用 MVCC 兼容快照时不会有问题,因为该槽位的新占用者一定太新,无法通过快照测试。然而,对于非 MVCC 兼容的快照(例如 SnapshotAny),就可能错误地接受并返回一行实际上并不匹配扫描键的数据。我们可以要求在所有情况下都对堆行重新检查扫描键,以防范这种情形,但那样代价太高。于是,我们改为把索引页面的钉住状态作为一种代理,表示读取者从索引条目到匹配堆条目的访问过程可能仍在进行中。让 ambulkdelete 因这种钉住状态而阻塞,能够保证 VACUUM 不会在读取者处理完之前删除对应的堆条目。这种方案运行时开销很小,只有在真正发生冲突的少数情况下才会增加阻塞开销。 @@ -477,7 +484,7 @@ amparallelrescan (IndexScanDesc scan); - 在 amgetbitmap 索引扫描中,访问方法不会在任何返回的元组上保留索引 pin。因此,只有把这种扫描与 MVCC 兼容的快照一起使用才是安全的。 + 在 amgetbitmap 索引扫描中,访问方法不会为任何返回的元组保持索引页面的钉住状态。因此,只有把这种扫描与 MVCC 兼容的快照一起使用才是安全的。 @@ -516,14 +523,17 @@ amparallelrescan (IndexScanDesc scan); - 此外,在按照上述规则报告唯一性违背之前,访问方法必须立即重新检查正在插入那一行的存活性。如果它已经是提交后死亡的状态,就不应报告违背。(这种情况不会出现在插入由当前事务刚创建的行这一普通场景中,但在 CREATE UNIQUE INDEX CONCURRENTLY 期间却可能发生。) + 此外,就在按照上述规则报告唯一性违背之前,访问方法必须重新检查正在插入那一行的存活性。如果它已经是提交后死亡的状态,就不应报告违背。(这种情况不会出现在插入由当前事务刚创建的行这一普通场景中,但在 CREATE UNIQUE INDEX CONCURRENTLY 期间却可能发生。) 我们要求索引访问方法自行应用这些测试,这意味着它必须深入堆中检查那些根据索引内容显示为具有重复键的行的提交状态。毫无疑问,这样做既丑陋又不够模块化,但它避免了重复工作:如果我们单独再做一次探测,那么在寻找新行索引条目插入位置时,查找冲突行的索引搜索实际上就会被重复执行。更何况,除非把冲突检查作为插入新索引条目动作的一个组成部分,否则也没有明显的方法可以避免竞争条件。 - 如果唯一约束可延迟,处理就更复杂:需要能够为新行插入索引条目,同时将唯一性冲突错误延迟到语句结束时甚至更晚。为避免不必要地重复搜索索引,索引访问方法应在首次插入时进行初步唯一性检查。如果确定不存在冲突的存活元组,就已完成检查。否则,应在需要强制执行约束时安排重新检查。如果重新检查时,插入的元组和某个具有相同键的其他元组都仍存活,就必须报告错误。(注意,在此场景中,存活实际表示索引条目 HOT 链中的任一元组是存活的。)为实现这一点,会向aminsert函数传入一个checkUnique参数,其值为以下之一: + + 如果唯一约束是可延迟的,情况会更复杂:我们需要能够为新行插入一个索引条目,但把任何唯一性违背错误延迟到语句结束时甚至更晚才报告。为了避免对索引进行不必要的重复搜索,索引访问方法应在初始插入期间执行一次初步唯一性检查。如果这表明确实不存在冲突的存活元组,那么事情就结束了。否则,我们会安排在真正强制约束时再做一次重检。若在重检时,插入的元组与另外某个具有相同键值的元组都仍然存活,就必须报告错误。(注意,就此用途而言,存活实际上是指索引条目 HOT 链中至少有一个元组是存活的。)为实现这一点,传给 aminsert 函数的 checkUnique 参数会取以下值之一: + + UNIQUE_CHECK_NO 表示不应执行唯一性检查(这不是唯一索引)。 @@ -558,10 +568,10 @@ amparallelrescan (IndexScanDesc scan); - 索引开销估计函数 + 索引代价估算函数 - amcostestimate 函数会收到描述某种可能索引扫描方式的信息,其中包括已经确定可用于该索引的 WHERE 子句和 ORDER BY 子句列表。它必须返回访问该索引的开销估计,以及 WHERE 子句的选择率(也就是在索引扫描期间将从父表中检索出的行所占比例)。对于简单情况,开销估计器几乎所有工作都可以通过调用优化器中的标准例程来完成;之所以提供 amcostestimate 函数,是为了让索引访问方法能够提供与索引类型有关的专门知识,以便在可能时改进标准估计。 + amcostestimate 函数会收到描述某种可能索引扫描方式的信息,其中包括已经确定可用于该索引的 WHERE 子句和 ORDER BY 子句列表。它必须返回访问该索引的代价估算,以及 WHERE 子句选择率的估计值(也就是在索引扫描期间将从父表中检索出的行所占比例)。对于简单情况,代价估算器几乎所有工作都可以通过调用优化器中的标准例程来完成;之所以提供 amcostestimate 函数,是为了让索引访问方法能够提供与索引类型有关的专门知识,以便在可能时改进标准估计。 @@ -595,7 +605,7 @@ amcostestimate (PlannerInfo *root, path - 当前正在考虑的索引访问路径。除开销和选择率字段外,其余字段都有效。 + 当前正在考虑的索引访问路径。除代价和选择率字段外,其余字段都有效。 @@ -604,7 +614,7 @@ amcostestimate (PlannerInfo *root, loop_count - 在开销估计中应计入的索引扫描重复次数。当考虑在嵌套循环连接内部使用参数化扫描时,这个参数通常会大于 1。请注意,开销估计仍应只针对一次扫描;更大的 loop_count 只表示可以适当考虑多次扫描之间的一些缓存效应。 + 在代价估算中应计入的索引扫描重复次数。当考虑在嵌套循环连接内部使用参数化扫描时,这个参数通常会大于 1。请注意,代价估算仍应只针对一次扫描;更大的 loop_count 只表示可以适当考虑多次扫描之间的一些缓存效应。 @@ -619,7 +629,7 @@ amcostestimate (PlannerInfo *root, *indexStartupCost - 设为索引启动处理的开销。 + 设为索引启动处理的代价。 @@ -628,7 +638,7 @@ amcostestimate (PlannerInfo *root, *indexTotalCost - 设为索引处理的总开销。 + 设为索引处理的总代价。 @@ -663,19 +673,19 @@ amcostestimate (PlannerInfo *root, - 请注意,开销估计函数必须用 C 编写,而不能用 SQL 或任何可用的过程语言,因为它们必须访问规划器/优化器的内部数据结构。 + 请注意,代价估算函数必须用 C 编写,而不能用 SQL 或任何可用的过程语言,因为它们必须访问规划器/优化器的内部数据结构。 - 索引访问开销应使用 src/backend/optimizer/path/costsize.c 所采用的参数来计算:顺序磁盘块读取的开销为 seq_page_cost,非顺序读取的开销为 random_page_cost,处理一条索引行的开销通常应取为 cpu_index_tuple_cost。此外,在索引处理期间调用的任何比较操作符(特别是对 indexquals 本身的求值)都应计入适当倍数的 cpu_operator_cost。 + 索引访问代价应使用 src/backend/optimizer/path/costsize.c 所采用的参数来计算:顺序磁盘块读取的代价为 seq_page_cost,非顺序读取的代价为 random_page_cost,处理一条索引行的代价通常应取为 cpu_index_tuple_cost。此外,在索引处理期间调用的任何比较操作符(特别是对 indexquals 本身的求值)都应计入适当倍数的 cpu_operator_cost - 访问开销应包括与扫描索引本身有关的全部磁盘和 CPU 开销,但包括取出或处理由索引标识出的父表行的开销。 + 访问代价应包括与扫描索引本身有关的全部磁盘和 CPU 代价,但包括取出或处理由索引标识出的父表行的代价。 - 启动开销是整个扫描总开销中必须在开始取第一行之前先付出的那一部分。对大多数索引来说,这可以视为零;但启动开销较高的索引类型可能希望把它设为非零。 + 启动代价是整个扫描总代价中必须在开始取第一行之前先付出的那一部分。对大多数索引来说,这可以视为零;但启动代价较高的索引类型可能希望把它设为非零。 @@ -683,7 +693,7 @@ amcostestimate (PlannerInfo *root, - indexCorrelation 应设为索引顺序与表顺序之间的相关性(范围从 -1.0 到 1.0)。该值用于调整从父表取行开销的估计。 + indexCorrelation 应设为索引顺序与表顺序之间的相关性(范围从 -1.0 到 1.0)。该值用于调整从父表取行代价的估计。 @@ -695,9 +705,9 @@ amcostestimate (PlannerInfo *root, - 开销估计 + 代价估算 - 一个典型的开销估计器会按如下步骤进行: + 一个典型的代价估算器会按如下步骤进行: @@ -726,14 +736,14 @@ amcostestimate (PlannerInfo *root, - 计算索引访问开销。一个通用估计器可能会这样做: + 计算索引访问代价。一个通用估计器可能会这样做: /* - * Our generic assumption is that the index pages will be read - * sequentially, so they cost seq_page_cost each, not random_page_cost. - * Also, we charge for evaluation of the indexquals at each index row. - * All the costs are assumed to be paid incrementally during the scan. + * 通用假设是索引页面将按顺序读取, + * 因此每页代价为 seq_page_cost,而非 random_page_cost。 + * 此外,还要计入在每个索引行上对 indexquals 求值的代价。 + * 假定所有代价都在扫描过程中逐步付出。 */ cost_qual_eval(&index_qual_cost, path->indexquals, root); *indexStartupCost = index_qual_cost.startup; @@ -753,7 +763,7 @@ cost_qual_eval(&index_qual_cost, path->indexquals, root); - 开销估计器函数的示例可在 src/backend/utils/adt/selfuncs.c 中找到。 + 代价估算器函数的示例可在 src/backend/utils/adt/selfuncs.c 中找到。 diff --git a/zh/12/indices.sgml b/zh/12/indices.sgml index 7057d082..43ef7a4c 100644 --- a/zh/12/indices.sgml +++ b/zh/12/indices.sgml @@ -31,7 +31,7 @@ SELECT content FROM test1 WHERE id = constant; - 大多数非小说类书籍也采用了类似的方法:读者经常查找的术语和概念会被收集到书末按字母顺序排列的索引中。感兴趣的读者可以相对快速地浏览索引并翻到相应页面,而不必通读整本书才能找到自己感兴趣的内容。正如作者需要预判读者可能查找哪些条目一样,数据库程序员也需要预见哪些索引会有用。 + 大多数非虚构类书籍也采用了类似的方法:读者经常查找的术语和概念会被收集到书末按字母顺序排列的索引中。感兴趣的读者可以相对快速地浏览索引并翻到相应页面,而不必通读整本书才能找到自己感兴趣的内容。正如作者需要预判读者可能查找哪些条目一样,数据库程序员也需要预见哪些索引会有用。 @@ -71,7 +71,7 @@ CREATE INDEX test1_id_index ON test1 (id); comparison-value operator indexed-column - 那么如果原始operator有一个可交换操作符,并且该操作符属于该索引的操作符类,就可以把它翻转成可索引的形式。 + 那么如果原始operator有一个交换子操作符,并且该操作符属于该索引的操作符类,就可以把它翻转成可索引的形式。 @@ -88,7 +88,7 @@ CREATE INDEX test1_id_index ON test1 (id); 索引类型 - PostgreSQL提供了多种索引类型:B-树、哈希、GiST、SP-GiST、GIN、BRIN,以及扩展bloom。每种索引类型都采用不同的算法,分别最适合不同类型的可索引子句。默认情况下,CREATE INDEX命令创建的是 B-树索引,它适用于最常见的场景。 + PostgreSQL提供了多种索引类型:B-树、Hash、GiST、SP-GiST、GIN、BRIN,以及扩展bloom。每种索引类型都采用不同的算法,分别最适合不同类型的可索引子句。默认情况下,CREATE INDEX命令创建的是 B-树索引,它适用于最常见的场景。 索引 B-树 B-树 索引 B-树能够处理可以按某种顺序排序的数据上的等值查询和范围查询。特别是,只要已索引列参与了下列任一操作符的比较,PostgreSQL查询规划器就会考虑使用 B-树索引: @@ -111,12 +111,12 @@ CREATE INDEX test1_id_index ON test1 (id); 索引 - 哈希 + hash - 哈希 + hash 索引 - 哈希索引只能处理简单的等值比较。只要已索引列参与的是使用=操作符的比较,查询规划器就会考虑使用哈希索引。使用以下命令创建哈希索引: + Hash 索引只能处理简单的等值比较。只要已索引列参与的是使用=操作符的比较,查询规划器就会考虑使用 Hash 索引。使用以下命令创建 Hash 索引: CREATE INDEX name ON table USING HASH (column); @@ -135,7 +135,7 @@ CREATE INDEX name ON table SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10; ]]> - 这会找出距离给定目标点最近的十个地点。是否能做到这一点,同样取决于所使用的具体操作符类。在中,可以按这种方式使用的操作符列在Ordering Operators这一列中。 + 这会找出距离给定目标点最近的十个地点。是否能做到这一点,同样取决于所使用的具体操作符类。在中,可以按这种方式使用的操作符列在排序操作符这一列中。 索引 SP-GiST SP-GiST 索引 @@ -174,8 +174,8 @@ SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10; 多列索引 - index - multicolumn + 索引 + 多列 @@ -206,15 +206,15 @@ CREATE INDEX test2_mm_idx ON test2 (major, minor); - 多列 GIN 索引可以用于涉及索引任意列子集的查询条件。与 B-树或 GiST 不同,无论查询条件使用的是哪一列索引列,GIN 的索引搜索效果都一样。 + 多列 GIN 索引可以用于涉及索引任意列子集的查询条件。与 B-树或 GiST 不同,无论查询条件使用的是哪些索引列,GIN 的索引搜索效果都一样。 - 多列 BRIN 索引可以用于涉及索引任意列子集的查询条件。和 GIN 一样、不同于 B-树或 GiST,无论查询条件使用的是哪一列索引列,索引搜索效果都一样。在单个表上使用多个 BRIN 索引,而不是使用一个多列 BRIN 索引的唯一理由,是需要不同的pages_per_range存储参数。 + 多列 BRIN 索引可以用于涉及索引任意列子集的查询条件。和 GIN 一样、不同于 B-树或 GiST,无论查询条件使用的是哪些索引列,索引搜索效果都一样。在单个表上使用多个 BRIN 索引,而不是使用一个多列 BRIN 索引的唯一理由,是需要不同的pages_per_range存储参数。 - 多列 GIN 索引可以用于涉及索引任意列子集的查询条件。与 B-树或 GiST 不同,无论查询条件使用的是哪一列索引列,GIN 的索引搜索效果都一样。 + 当然,每一列都必须配合适合该索引类型的操作符使用;涉及其他操作符的子句不会被考虑。 @@ -227,8 +227,8 @@ CREATE INDEX test2_mm_idx ON test2 (major, minor); 索引和<literal>ORDER BY</literal> - index - and ORDER BY + 索引 + ORDER BY @@ -236,7 +236,7 @@ CREATE INDEX test2_mm_idx ON test2 (major, minor); - 规划器在满足ORDER BY要求时,会考虑两种方案:扫描一个与该要求匹配的可用索引,或者按物理顺序扫描表再显式排序。对于需要扫描表中很大一部分内容的查询,显式排序通常会比使用索引更快,因为它遵循顺序访问模式,需要的磁盘 I/O 更少。只有在只需取出少量行时,索引才更有价值。一个重要的特例是ORDER BYLIMIT n组合使用:显式排序必须处理所有数据才能找出最前面的n行,而如果有一个与ORDER BY匹配的索引,就可以直接取回前n行,而完全不必扫描剩余数据。 + 规划器在满足ORDER BY要求时,会考虑两种方案:扫描一个与该要求匹配的可用索引,或者按物理顺序扫描表再显式排序。对于需要扫描表中很大一部分内容的查询,显式排序通常会比使用索引更快,因为它遵循顺序访问模式,需要的磁盘 I/O 更少。只需取出少量行时,索引更有价值。一个重要的特例是ORDER BYLIMIT n组合使用:显式排序必须处理所有数据才能找出最前面的n行,而如果有一个与ORDER BY匹配的索引,就可以直接取回前n行,而完全不必扫描剩余数据。 @@ -266,12 +266,12 @@ CREATE INDEX test3_desc_index ON test3 (id DESC NULLS LAST); 组合多个索引 - index - combining multiple indexes + 索引 + 组合多个索引 - bitmap scan + 位图扫描 @@ -298,8 +298,8 @@ CREATE INDEX test3_desc_index ON test3 (id DESC NULLS LAST); 唯一索引 - index - unique + 索引 + 唯一 @@ -330,8 +330,8 @@ CREATE UNIQUE INDEX name ON table表达式索引 - index - on expressions + 索引 + 基于表达式 @@ -378,8 +378,8 @@ CREATE INDEX people_names ON people ((first_name || ' ' || last_name)); 部分索引 - index - partial + 索引 + 部分 @@ -387,7 +387,7 @@ CREATE INDEX people_names ON people ((first_name || ' ' || last_name)); - 使用部分索引的一个主要原因是避免索引常见值。由于搜索常见值的查询(即占全部表行百分之几以上的值)反正也不会使用索引,因此完全没有必要把这些行保留在索引里。这会减小索引尺寸,从而加快那些确实会使用该索引的查询。它也会加快很多表更新操作,因为索引并不需要在所有情况下都更新。展示了这种思路的一种可能应用。 + 使用部分索引的一个主要原因是避免索引常见值。由于搜索常见值(即占全部表行百分之几以上的值)的查询反正也不会使用索引,因此完全没有必要把这些行保留在索引里。这会减小索引尺寸,从而加快那些确实会使用该索引的查询。它也会加快很多表更新操作,因为索引并不需要在所有情况下都更新。展示了这种思路的一种可能应用。 @@ -417,11 +417,15 @@ WHERE NOT (client_ip > inet '192.168.100.0' AND - 一个能够使用此索引的典型查询如下: + + 一个可以使用该索引的典型查询是: + SELECT * FROM access_log WHERE url = '/index.html' AND client_ip = inet '212.78.10.32'; -这里,查询的 IP 地址被部分索引覆盖。下面的查询不能使用该部分索引,因为它使用的 IP 地址被排除在索引之外: + + 这里查询中的 IP 地址落在部分索引覆盖的范围内。下面这个查询则不能使用该部分索引,因为它使用了一个被索引排除掉的 IP 地址: + SELECT * FROM access_log WHERE url = '/index.html' AND client_ip = inet '192.168.100.23'; @@ -471,7 +475,7 @@ SELECT * FROM orders WHERE order_nr = 3501; - 也说明了:索引列和谓词中使用的列不必一致。PostgreSQL支持带任意谓词的部分索引,只要其中只涉及正在建立索引的那张表的列。不过要记住,谓词必须与那些希望从该索引受益的查询中使用的条件相匹配。更准确地说,只有当系统能够识别出查询的WHERE条件在数学上蕴含该索引的谓词时,部分索引才能用于该查询。PostgreSQL并没有一个复杂的定理证明器,来识别那些写法不同但数学上等价的表达式。(不仅构建这样一个通用定理证明器极其困难,而且它很可能也会慢到失去实际用途。)系统可以识别简单的不等式蕴含,例如x < 1蕴含x < 2;否则,谓词条件必须与查询WHERE条件的某一部分完全匹配,否则索引不会被识别为可用。匹配发生在查询规划阶段,而不是运行时。因此,参数化查询子句无法与部分索引配合工作。例如,一个带参数的预备查询可能写成x < ?,而对于参数的所有可能取值,它都不可能蕴含x < 2。 + 也说明了:索引列和谓词中使用的列不必一致。PostgreSQL支持带任意谓词的部分索引,只要其中只涉及正在建立索引的那张表的列。不过要记住,谓词必须与那些希望从该索引受益的查询中使用的条件相匹配。更准确地说,只有当系统能够识别出查询的WHERE条件在数学上蕴含该索引的谓词时,部分索引才能用于该查询。PostgreSQL并没有一个复杂的定理证明器,来识别那些写法不同但数学上等价的表达式。(不仅构建这样一个通用定理证明器极其困难,而且它很可能也会慢到失去实际用途。)系统可以识别简单的不等式蕴含,例如x < 1蕴含x < 2;否则,谓词条件必须与查询WHERE条件的某一部分完全匹配,否则索引不会被识别为可用。匹配发生在查询规划阶段,而不是运行时。因此,参数化查询子句无法与部分索引配合工作。例如,一个带参数的预备查询可能写成x < ?,而它无法保证在参数的所有可能取值下都蕴含x < 2 @@ -482,7 +486,9 @@ SELECT * FROM orders WHERE order_nr = 3501; 建立一个部分唯一索引 - 假设有一个记录测试结果的表。我们希望确保每个给定的测试对象和目标组合只有一个成功条目,但可以有任意数量的失败条目。下面是一种实现方法: + + 假设我们有一张描述测试结果的表。我们希望确保对于给定的测试对象和目标组合,只有一条成功记录,但可以有任意多条失败记录。实现方法之一如下: + CREATE TABLE tests ( subject text, target text, @@ -492,7 +498,9 @@ CREATE TABLE tests ( CREATE UNIQUE INDEX tests_success_constraint ON tests (subject, target) WHERE success; -在成功测试很少而失败测试很多时,这种方法尤其高效。也可以创建一个带有IS NULL限制的唯一部分索引,从而只允许列中出现一个空值。 + + 当成功测试很少而失败测试很多时,这是一种特别高效的方法。也可以通过创建一个带IS NULL限制的唯一部分索引,来让某一列只允许出现一个空值。 + @@ -563,7 +571,10 @@ CREATE INDEX mytable_cat_data ON mytable (category, data); PostgreSQL中的所有索引都是二级索引,也就是说,每个索引都与表的主数据区分开存储(在PostgreSQL术语中,这个主数据区称为表的)。这意味着,在普通索引扫描中,每次取回一行都需要同时从索引和堆中取数据。此外,尽管满足某个可索引WHERE条件的索引项通常在索引中彼此接近,但它们引用的表行却可能分布在堆中的任何位置。因此,索引扫描的堆访问部分会涉及大量对堆的随机访问,这可能很慢,尤其是在传统旋转介质上。(正如中所述,位图扫描试图通过按排序顺序进行堆访问来缓解这项代价,但那也只能缓解到一定程度。) - 为了解决这一性能问题,PostgreSQL支持仅索引扫描,仅通过索引就能完成查询,无需访问堆。其基本思路是直接从各个索引项返回值,而不访问相关联的堆项。使用这种方法有两个基本限制: + + 为了解决这个性能问题,PostgreSQL支持仅索引扫描,它可以仅凭索引而不访问堆来回答查询。基本思路是直接从每个索引项中返回值,而不是再去查对应的堆项。要使用这种方法,有两个根本限制: + + 索引类型必须支持仅索引扫描。B-树索引总是支持。GiST 和 SP-GiST 索引对某些操作符类支持仅索引扫描,但对另一些则不支持。其他索引类型则完全不支持。底层要求是,索引必须实际存储原始数据值,或者至少能够重建出每个索引项对应的原始数据值。反例是 GIN 索引,它不能支持仅索引扫描,因为每个索引项通常只保存原始数据值的一部分。 @@ -571,13 +582,19 @@ CREATE INDEX mytable_cat_data ON mytable (category, data); - 查询只能引用存储在索引中的列。例如,假设某个表的xy列上有一个索引,且该表还有一列z,那么以下查询可以使用仅索引扫描: + + 查询只能引用存储在索引中的列。例如,假设某个表的xy列上有一个索引,且该表还有一列z,那么下面这些查询可以使用仅索引扫描: + SELECT x, y FROM tab WHERE x = 'key'; SELECT x FROM tab WHERE x = 'key' AND y < 42; -但以下查询不能: + + 但下面这些查询则不能: + SELECT x, z FROM tab WHERE x = 'key'; SELECT x FROM tab WHERE x = 'key' AND z < 42; -(表达式索引和部分索引会使这条规则更复杂,下文将作讨论。) + + (表达式索引和部分索引会让这条规则变得更复杂,下文会讨论。) + @@ -594,23 +611,37 @@ SELECT x FROM tab WHERE x = 'key' AND z < 42; INCLUDE 在索引定义中 - 为了有效利用仅索引扫描,可以创建一个覆盖索引,即专门包含某类常用查询所需列的索引。由于查询通常需要取出的列比搜索条件涉及的列更多,PostgreSQL允许创建这样的索引:其中一些列仅用作负载,并非搜索键的一部分。为此,需要添加一个INCLUDE子句,列出这些额外列。例如,如果经常执行如下查询: + + 为了有效利用仅索引扫描特性,你可以选择创建一个覆盖索引,也就是专门设计来包含某一类高频查询所需列的索引。由于查询通常需要取回的列不止是用于搜索的那些列,PostgreSQL允许你创建一种索引,其中某些列只是负载,而不是搜索键的一部分。这是通过添加一个INCLUDE子句列出这些额外列来实现的。例如,如果你经常运行如下查询: + SELECT y FROM tab WHERE x = 'key'; -加快此类查询的传统做法,是仅在以下列上创建索引:x。但是,定义如下的索引: + + 传统上,为了加速这类查询,通常会只在x上创建一个索引。但如果将索引定义为: + CREATE INDEX tab_x_y ON tab(x) INCLUDE (y); -可以通过仅索引扫描处理这些查询,因为y可以直接从索引中取得,无需访问堆。 + + 那么这些查询就可以以仅索引扫描的方式完成,因为y可以直接从索引中取得,而不必访问堆。 + - 由于列y并非索引搜索键的一部分,其数据类型不必是索引能够处理的类型;该列只是存储在索引中,索引机制不会解释它。另外,如果该索引是唯一索引,也就是: + + 由于列y不是索引搜索键的一部分,因此它不必属于该索引能够处理的数据类型;它只是被存储在索引中,而不会被索引机制解释。此外,如果该索引是唯一索引,即 + CREATE UNIQUE INDEX tab_x_y ON tab(x) INCLUDE (y); -那么唯一性条件只应用于列x,而不应用于xy的组合。(INCLUDE子句也可以写在UNIQUEPRIMARY KEY约束中,为建立这样的索引提供另一种语法。) + + 那么唯一性条件只作用于列x,而不作用于xy的组合。(INCLUDE子句也可以写在UNIQUEPRIMARY KEY约束中,作为建立这种索引的另一种语法。) + 向索引中添加非键负载列时,明智的做法是保持保守,尤其是宽列。如果某个索引元组超过该索引类型允许的最大尺寸,数据插入就会失败。无论如何,非键列都会复制索引对应表中的数据并让索引膨胀,因此可能拖慢搜索。另外请记住,除非表变化足够缓慢,以至于仅索引扫描很可能无需访问堆,否则把负载列包含在索引中并没有太大意义。如果反正必须访问堆元组,那么顺便从那里取出该列的值也不会增加额外代价。其他限制包括:当前不支持把表达式作为包含列;并且当前只有 B-树和 GiST 索引支持包含列。 - PostgreSQL支持INCLUDE功能之前,人们有时会将负载列写成普通索引列来创建覆盖索引,也就是写成 + + 在PostgreSQL还没有INCLUDE特性之前,人们有时会通过把负载列写成普通索引列来制作覆盖索引,也就是写成: + CREATE INDEX tab_x_y ON tab(x, y); -尽管他们从未打算将y用作WHERE子句的一部分。只要这些额外列位于末尾,这样做就没有问题;将它们放在前面是不明智的,原因见。但是,如果希望索引强制键列唯一,这种方法就不适用了。 + + 即便他们从没打算把y作为WHERE子句的一部分来使用。只要这些额外列位于尾部,这样做就没问题;如果把它们放到前导位置,则出于中解释的原因,是不明智的。不过,这种方法无法支持你希望索引对键列强制唯一性的场景。 + 后缀截断总会从 B-树 上层移除非键列。作为负载列,它们从不会被用于指导索引扫描。截断过程还会在剩余键列前缀已经足以描述最低 B-树 层上的元组时,移除一个或多个尾随键列。实践中,不带INCLUDE子句的覆盖索引通常也会避免在上层存储那些实际上只是负载的列。不过,把负载列显式定义为非键列,能可靠地让上层中的元组保持较小。 @@ -647,11 +678,11 @@ SELECT target FROM tests WHERE subject = 'some-subject' AND success; 操作符类和操作符族 - operator class + 操作符类 - operator family + 操作符族 索引定义可以为索引的每一列指定一个操作符类 @@ -761,8 +792,8 @@ CREATE INDEX test1c_content_y_index ON test1c (content COLLATE "y"); 检查索引使用情况 - index - examining usage + 索引 + 检查使用情况 diff --git a/zh/12/information_schema.sgml b/zh/12/information_schema.sgml index e78a9375..75fe4990 100644 --- a/zh/12/information_schema.sgml +++ b/zh/12/information_schema.sgml @@ -105,7 +105,7 @@ - Name + 名称 数据类型 描述 @@ -139,7 +139,7 @@ - Name + 名称 数据类型 描述 @@ -191,7 +191,7 @@ - Name + 名称 数据类型 描述 @@ -241,7 +241,7 @@ - Name + 名称 数据类型 描述 @@ -361,7 +361,7 @@ collation_catalog sql_identifier - 包含此属性排序规则的数据库名(总是当前数据库),如果默认或者该属性的数据类型不可排序则为空 + 包含该属性排序规则的数据库名称(总是当前数据库);如果使用默认排序规则,或该属性的数据类型不支持排序规则,则为 null。 @@ -369,7 +369,7 @@ collation_schema sql_identifier - 包含此属性排序规则的模式名,如果默认或者该属性的数据类型不可排序则为空 + 包含该属性排序规则的模式名称;如果使用默认排序规则,或该属性的数据类型不支持排序规则,则为 null。 @@ -377,7 +377,7 @@ collation_name sql_identifier - 该属性排序规则的名称,如果默认或者该属性的数据类型不可排序则为空 + 该属性排序规则的名称;如果使用默认排序规则,或该属性的数据类型不支持排序规则,则为 null。 @@ -563,7 +563,7 @@ - Name + 名称 数据类型 描述 @@ -654,7 +654,7 @@ - Name + 名称 数据类型 描述 @@ -728,7 +728,7 @@ - Name + 名称 数据类型 描述 @@ -786,7 +786,7 @@ - Name + 名称 数据类型 描述 @@ -844,7 +844,7 @@ - Name + 名称 数据类型 描述 @@ -918,7 +918,7 @@ - Name + 名称 数据类型 描述 @@ -984,7 +984,7 @@ - Name + 名称 数据类型 描述 @@ -1066,7 +1066,7 @@ - Name + 名称 数据类型 描述 @@ -1146,7 +1146,7 @@ - Name + 名称 数据类型 描述 @@ -1236,7 +1236,7 @@ - Name + 名称 数据类型 描述 @@ -1318,7 +1318,7 @@ - Name + 名称 数据类型 描述 @@ -1491,7 +1491,7 @@ collation_catalog sql_identifier - 包含此属性排序规则的数据库名(总是当前数据库),如果默认或者该属性的数据类型不可排序则为空 + 包含该列排序规则的数据库名称(总是当前数据库);如果使用默认排序规则,或该列的数据类型不支持排序规则,则为 null。 @@ -1499,7 +1499,7 @@ collation_schema sql_identifier - 该列的包含排序规则的模式名,如果默认或者该列的数据类型不可排序则为空 + 包含该列排序规则的模式名称;如果使用默认排序规则,或该列的数据类型不支持排序规则,则为 null。 @@ -1507,7 +1507,7 @@ collation_name sql_identifier - 该列的排序规则的名称,如果默认或者该列的数据类型不可排序则为空 + 该列排序规则的名称;如果使用默认排序规则,或该列的数据类型不支持排序规则,则为 null。 @@ -1710,7 +1710,7 @@ - Name + 名称 数据类型 描述 @@ -1792,7 +1792,7 @@ - Name + 名称 数据类型 描述 @@ -1866,7 +1866,7 @@ - Name + 名称 数据类型 描述 @@ -1932,7 +1932,7 @@ - Name + 名称 数据类型 描述 @@ -2022,7 +2022,7 @@ - Name + 名称 数据类型 描述 @@ -2097,7 +2097,7 @@ - Name + 名称 数据类型 描述 @@ -2184,7 +2184,7 @@ collation_catalog sql_identifier - 包含此域排序规则的数据库名(总是当前数据库),如果默认或者该域的数据类型不可排序则为空 + 包含该域排序规则的数据库名称(总是当前数据库);如果使用默认排序规则,或该域的数据类型不支持排序规则,则为 null。 @@ -2192,7 +2192,7 @@ collation_schema sql_identifier - 包含此域排序规则的模式名,如果默认或者该域的数据类型不可排序则为空 + 包含该域排序规则的模式名称;如果使用默认排序规则,或该域的数据类型不支持排序规则,则为 null。 @@ -2200,7 +2200,7 @@ collation_name sql_identifier - 该域排序规则的名称,如果默认或者该域的数据类型不可排序则为空 + 该域排序规则的名称;如果使用默认排序规则,或该域的数据类型不支持排序规则,则为 null。 @@ -2340,7 +2340,7 @@ <literal>element_types</literal> - 视图element_types包含数组元素的数据类型描述符。当一个表列、复合类型属性、域、函数参数或函数返回值被定义为一种数组类型,相应的信息模式视图只在列data_type中包含ARRAY。要获得该数组元素类型的信息,你可以连接该相应的视图和这个视图。例如,要显示一个表的列及其数据类型和数组元素类型,你可以: + 视图element_types包含数组元素的数据类型描述符。当一个表列、复合类型属性、域、函数参数或函数返回值被定义为一种数组类型时,相应的信息模式视图只在列data_type中包含ARRAY。要获得该数组元素类型的信息,你可以连接该相应的视图和这个视图。例如,要显示一个表的列及其数据类型和数组元素类型(如果适用),你可以: SELECT c.column_name, c.data_type, e.data_type AS element_type FROM information_schema.columns c LEFT JOIN information_schema.element_types e @@ -2358,7 +2358,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -2459,7 +2459,7 @@ ORDER BY c.ordinal_position; collation_catalog sql_identifier - 包含元素类型排序规则的数据库名称(总是当前数据库), 如果默认或该元素的数据类型是不可排序的则为空 + 包含该元素类型排序规则的数据库名称(总是当前数据库);如果使用默认排序规则,或该元素类型不支持排序规则,则为 null。 @@ -2467,7 +2467,7 @@ ORDER BY c.ordinal_position; collation_schema sql_identifier - 包含元素类型排序规则的模式名称, 如果默认或该元素的数据类型是不可排序的则为空 + 包含该元素类型排序规则的模式名称;如果使用默认排序规则,或该元素类型不支持排序规则,则为 null。 @@ -2475,7 +2475,7 @@ ORDER BY c.ordinal_position; collation_name sql_identifier - 元素类型的排序规则名, 如果默认或该元素的数据类型是不可排序的则为空 + 该元素类型排序规则的名称;如果使用默认排序规则,或该元素类型不支持排序规则,则为 null。 @@ -2530,9 +2530,7 @@ ORDER BY c.ordinal_position; domain_default character_data - - 元素的数据类型所在的数据库名称(总是当前数据库) - + 尚未实现 @@ -2622,7 +2620,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -2656,7 +2654,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -2714,7 +2712,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -2780,7 +2778,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -2838,7 +2836,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -2920,7 +2918,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -2986,7 +2984,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -3052,7 +3050,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -3150,7 +3148,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -3434,7 +3432,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -3535,7 +3533,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -3625,7 +3623,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -3731,7 +3729,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -3825,7 +3823,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -3907,7 +3905,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -3997,7 +3995,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -4103,7 +4101,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -4793,7 +4791,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -4875,7 +4873,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -5003,7 +5001,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -5085,7 +5083,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -5151,7 +5149,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -5217,7 +5215,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -5275,7 +5273,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -5341,7 +5339,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -5397,7 +5395,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -5457,7 +5455,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -5560,7 +5558,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -5654,7 +5652,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -5778,7 +5776,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -5870,7 +5868,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -5952,7 +5950,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -6142,7 +6140,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -6232,7 +6230,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -6317,7 +6315,7 @@ ORDER BY c.ordinal_position; - SQL 了解两种用户定义类型:结构类型(在PostgreSQL中也称为复合类型)以及 distinct 类型(PostgreSQL 尚未实现)。为兼顾将来,请使用列user_defined_type_category来区分它们。其他用户定义类型,如基类型和枚举(两者都是PostgreSQL的扩展),不会在这里显示。域的相关信息见。 + SQL 中有两种用户定义类型:结构类型(在PostgreSQL中也称为复合类型)以及独立类型(distinct type,PostgreSQL 尚未实现)。为兼顾将来,请使用列user_defined_type_category来区分它们。其他用户定义类型,如基础类型和枚举(两者都是PostgreSQL的扩展),不会在这里显示。域的相关信息见 @@ -6326,7 +6324,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -6584,7 +6582,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -6651,7 +6649,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -6707,7 +6705,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -6789,7 +6787,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -6869,7 +6867,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 @@ -6943,7 +6941,7 @@ ORDER BY c.ordinal_position; - Name + 名称 数据类型 描述 diff --git a/zh/12/install-windows.sgml b/zh/12/install-windows.sgml index b7c9a736..164d6d27 100644 --- a/zh/12/install-windows.sgml +++ b/zh/12/install-windows.sgml @@ -4,8 +4,8 @@ 在 <productname>Windows</productname> 上从源代码安装 - installation - on Windows + 安装 + 在 Windows 上 @@ -48,8 +48,6 @@ https://docs.microsoft.com/en-us/visualstudio/releases/2019/system-requirements For 2022 requirements: https://docs.microsoft.com/en-us/visualstudio/releases/2022/system-requirements - For 2026 requirements: - https://docs.microsoft.com/en-us/visualstudio/releases/2026/vs-system-requirements --> @@ -81,7 +79,10 @@ $ENV{MSBFLAGS}="/m"; 需求 - 以下附加产品是构建 PostgreSQL 所必需的。请使用 config.pl 文件指定各个库所在的目录。 + + 构建PostgreSQL需要以下附加产品。请使用config.pl文件指定这些库所在的目录。 + + Microsoft Windows SDK @@ -101,7 +102,10 @@ $ENV{MSBFLAGS}="/m"; - 开始使用时不需要以下附加产品,但构建完整软件包时需要。请使用 config.pl 文件指定各个库所在的目录。 + + 以下附加产品并非入门所必需,但若要构建完整的软件包则需要它们。请使用config.pl文件指定这些库所在的目录。 + + Magicsplat Tcl @@ -290,7 +294,9 @@ $ENV{CONFIG}="Debug"; 有关回归测试的更多信息,参见 - vcregress bincheck 运行客户端程序的回归测试、用 vcregress recoverycheck 运行恢复测试,或用 vcregress taptest 指定并运行 TAP 测试,都需要另外安装一个 Perl 模块: + + 对客户端程序运行回归测试时使用vcregress bincheck,对恢复测试使用vcregress recoverycheck,或者运行由vcregress taptest指定的 TAP 测试时,需要额外安装一个 Perl 模块: + IPC::Run 撰写本文时,IPC::Run 既未包含在 ActiveState Perl 安装中,也未包含在 ActiveState Perl 软件包管理器(PPM)的库中。要安装它,请下载以下文件:IPC-Run-<version>.tar.gz,这是 CPAN 提供的源码归档,地址为 ,然后将其解压。编辑 buildenv.pl 文件,并添加 PERL5LIB 变量,使其指向解压后归档中的 lib 子目录。例如: @@ -301,7 +307,8 @@ $ENV{PERL5LIB}=$ENV{PERL5LIB} . ';c:\IPC-Run-0.94\lib'; - 部分 TAP 测试依赖一些外部命令,相关测试会根据这些命令是否可用而选择性触发。以下各变量都可以在 buildenv.pl 中设置或取消设置: + + 部分 TAP 测试依赖一些外部命令,相关测试会根据这些命令是否可用而选择性触发。以下各变量都可以在 buildenv.pl 中设置或取消设置: GZIP_PROGRAM diff --git a/zh/12/installation.sgml b/zh/12/installation.sgml index 36d21f73..aae32f3d 100644 --- a/zh/12/installation.sgml +++ b/zh/12/installation.sgml @@ -12,7 +12,7 @@ documentation. See standalone-profile.xsl for details. 从源代码安装 - installation + 安装 @@ -37,7 +37,7 @@ su - postgres /usr/local/pgsql/bin/pg_ctl -D /usr/local/pgsql/data -l logfile start /usr/local/pgsql/bin/createdb test /usr/local/pgsql/bin/psql test -详细说明见本。 +详细说明见本的其余部分。 @@ -45,9 +45,14 @@ su - postgres 需求 - 一般来说,现代的 Unix 兼容平台应该能够运行 PostgreSQL。发布时经过具体测试的平台见下方 + + 一般来说,现代的 Unix 兼容平台都应当能够运行 + PostgreSQL。在发布时经过专门测试的平台, + 见下文 。 + - 以下软件包必须备齐,才能构建 PostgreSQL: + + 构建 PostgreSQL 需要下列软件包: @@ -129,13 +134,17 @@ su - postgres - 以下软件包是可选的。默认配置不需要它们,但启用某些构建选项时需要,具体如下: + + 下列软件包是可选的。默认配置不需要它们,但在启用某些构建选项时会用到, + 如下所述: + + 要构建服务器端编程语言 PL/Perl, 你需要一个完整的 Perl 安装, 包括 libperl 库和头文件。 - 最低要求版本是 Perl 5.14。 + 最低要求版本是 Perl 5.8.3。 由于 PL/Perl 是一个共享库,在大多数平台上, libperl libperl 也必须是共享库。这在较新的 @@ -193,11 +202,14 @@ su - postgres - 如果你希望支持使用相应服务进行身份验证,就需要 KerberosOpenLDAP 和/或 PAM + 如果你希望支持使用相应服务进行认证,就需要 KerberosOpenLDAP 和/或 PAM - 构建 PostgreSQL 文档另有一组要求;参见 + + 要构建 PostgreSQL 文档,还需要满足另一组要求; + 见 。 + @@ -671,7 +683,7 @@ su - postgres ,使用 OSSP UUID library + url="http://www.ossp.org/pkg/lib/uuid/">OSSP UUID 库 @@ -690,7 +702,10 @@ su - postgres - 使用 libxml2 构建,以启用 SQL/XML 支持。此功能要求 Libxml2 2.6.23 或更高版本。 + + 构建时支持 libxml2,以启用 SQL/XML 支持。 + 这一特性要求 libxml2 2.6.23 或更高版本。 + 为检测所需的编译器和链接器选项,PostgreSQL 会查询 pkg-config,前提是已安装该程序且其中有 libxml2 的信息。否则,如果找到 libxml2 安装的 xml2-config 程序,就会使用它。优先使用 pkg-config,因为它能更好地处理多架构安装。 @@ -830,7 +845,7 @@ su - postgres - 如果使用 GCC,所有程序和库都会编译为可进行性能剖析的形式。后端退出时,会创建一个子目录,其中包含用于性能剖析的 gmon.out 文件。此选项仅用于使用 GCC 进行开发工作时。 + 如果使用 GCC,所有程序和库都会编译为可进行性能分析的形式。后端退出时,会创建一个子目录,其中包含用于性能分析的 gmon.out 文件。此选项仅用于使用 GCC 进行开发工作时。 @@ -838,11 +853,11 @@ su - postgres - 在服务器中启用 assertion 检查,用于测试许多 - 不应该发生的条件。这对代码开发非常有价值,但这些测试会显著拖慢 + 在服务器中启用 断言 检查,用于测试许多 + 不可能发生的条件。这对代码开发非常有价值,但这些测试可能会显著拖慢 服务器速度。此外,启用这些测试并不一定会增强服务器稳定性! 断言检查并未按严重程度分类,因此即使某个 bug 相对无害,只要触发了断言失败, - 仍可能导致服务器重启。该选项不建议用于生产环境,但如果你在做开发工作 + 仍会导致服务器重启。该选项不建议用于生产环境,但如果你在做开发工作 或运行测试版,就应当启用它。 @@ -901,7 +916,10 @@ su - postgres - 以下是可以通过这种方式设置的重要变量: + + 下面列出可以按这种方式设置的重要变量: + + BISON @@ -934,7 +952,7 @@ su - postgres 在使用 --with-llvm 编译时, - 用于处理源代码以内联的 clang 程序路径 + 用于处理源代码以进行内联的 clang 程序路径 @@ -1125,7 +1143,7 @@ All of PostgreSQL successfully made. Ready to install. - 如果要构建所有可构建的内容,包括文档(HTML 和 man 页面)及附加模块(contrib),请改为输入: + 如果要构建所有可构建的内容,包括文档(HTML 和手册页)及附加模块(contrib),请改为输入: make world 显示的最后一行应该是: PostgreSQL, contrib, and documentation successfully made. Ready to install. @@ -1158,9 +1176,17 @@ build-postgresql: 回归测试 - 如果希望在安装前测试刚构建的服务器,可以在此时运行回归测试。回归测试是一套测试程序,用于验证 PostgreSQL 是否在你的机器上按开发者预期的方式运行。输入: + + 如果你希望在安装之前测试新构建的服务器,可以在此时运行回归测试。 + 回归测试是一套测试,用来验证 PostgreSQL + 是否按开发者预期的方式在你的机器上运行。输入: + make check -(不能以 root 身份运行;请使用非特权用户。)参见 ,其中包含解读测试结果的详细信息。以后任何时候都可以通过执行同一命令来重复此测试。 + + (这不能以 root 身份运行;请使用非特权用户。) + 关于如何解释测试结果的详细信息,见 。 + 在以后的任何时候,你都可以再次执行同样的命令来重复此测试。 + @@ -1285,14 +1311,25 @@ build-postgresql: Solaris - 设置共享库搜索路径的方法因平台而异,但最常见的方法是设置环境变量 LD_LIBRARY_PATH,方法如下。在 Bourne shell(shkshbashzsh): + + 设置共享库搜索路径的方法因平台而异,但最常见的方法是按如下方式设置环境变量 + LD_LIBRARY_PATH。对于 Bourne shell + (shkshbash、 + zsh): LD_LIBRARY_PATH=/usr/local/pgsql/lib export LD_LIBRARY_PATH -或者在 cshtcsh: + + 或者对于 cshtcsh setenv LD_LIBRARY_PATH /usr/local/pgsql/lib -请将 /usr/local/pgsql/lib 替换为你为 指定的值,设置过程见 。应将这些命令放入 shell 启动文件,例如 /etc/profile~/.bash_profile。关于此方法相关注意事项的一些有用信息,参见 + 请把这里的 /usr/local/pgsql/lib 替换为你在 + 中通过 + 设置的值。你应该把这些命令放入 shell 启动文件,例如 + /etc/profile~/.bash_profile。 + 关于这种方法的注意事项,有一些不错的资料可参见 + @@ -1307,10 +1344,15 @@ setenv LD_LIBRARY_PATH /usr/local/pgsql/lib bin 目录中。 - 如果不确定,请参阅系统的手册页(可能是 ld.sorld)。如果以后遇到类似以下的消息: + + 如果不确定,请参考你系统的手册页(可能是 ld.so + 或 rld)。如果你随后收到类似下面这样的消息: + psql: error in loading shared libraries libpq.so.2.1: cannot open shared object file: No such file or directory -则说明此步骤不可省略。届时补做即可。 + + 那就说明这一步确实是必须的。到那时再处理即可。 + @@ -1349,10 +1391,17 @@ libpq.so.2.1: cannot open shared object file: No such file or directory PostgreSQL 的使用方便得多。 - 为此,请将以下内容添加到 shell 启动文件中,例如 ~/.bash_profile(或者使用 /etc/profile,使其对所有用户生效): + + 为此,请把下面内容加到你的 shell 启动文件中,例如 + ~/.bash_profile(如果你希望影响所有用户,则用 + /etc/profile): + PATH=/usr/local/pgsql/bin:$PATH export PATH -如果使用 cshtcsh,则使用以下命令: + + 如果你使用的是 cshtcsh, + 则使用这条命令: + set path = ( /usr/local/pgsql/bin $path ) @@ -1398,7 +1447,12 @@ export MANPATH 可以预期 PostgreSQL 能在以下操作系统上工作:Linux(所有近期发行版)、Windows(Win2000 SP4 及更高版本)、FreeBSD、OpenBSD、NetBSD、macOS、AIX、HP/UX 和 Solaris。其他类 Unix 系统也可能可用,但目前未在测试。大多数情况下,某个操作系统所支持的全部 CPU 架构也都可以工作。尤其是在使用较旧系统时,请查看下面的 ,看看是否有针对你的操作系统的特别说明。 - 如果近期构建农场的结果表明某个平台受支持,但你在该平台上遇到安装问题,请向 pgsql-bugs@lists.postgresql.org 报告。如果你有兴趣将 PostgreSQL 移植到新平台,可以在 pgsql-hackers@lists.postgresql.org 讨论。 + + 如果你在某个平台上遇到安装问题,而根据近期构建农场的结果该平台是受支持的, + 请把问题报告到 pgsql-bugs@lists.postgresql.org。 + 如果你有兴趣把 PostgreSQL 移植到一个新平台, + 那么 pgsql-hackers@lists.postgresql.org 是合适的讨论地点。 + @@ -1460,8 +1514,12 @@ ERROR: could not load library "/opt/dbs/pgsql/lib/plperl.so": Bad address 可以使用 Cygwin 这个 Windows 上的类 Linux 环境来构建 PostgreSQL,但这种方式不如原生 Windows 构建(见 ,且如今已不再推荐在 Cygwin 下运行服务器。 - 从源码构建时,请按照 Unix 风格的安装过程操作(即 ./configure; - make 等),同时注意以下 Cygwin 特有的差异: + + 从源代码构建时,请按照 Unix 风格的安装过程(也就是 + ./configure; + make;等等)进行,但要注意下列 Cygwin 特有的差异: + + 请把路径设置成优先使用 Cygwin 的 bin 目录,而不是 Windows 工具目录。 @@ -1504,9 +1562,11 @@ ERROR: could not load library "/opt/dbs/pgsql/lib/plperl.so": Bad address - 并行回归测试(make check)可能因溢出而误报回归测试失败;溢出发生在 listen() 的待处理连接队列中,会导致连接被拒绝的错误或挂起。可以使用 make 变量 MAX_CONNECTIONS 限制连接数,方法如下: + 并行回归测试(make check)可能因 listen() 的待处理连接队列溢出而误报回归测试失败;队列溢出会导致连接被拒绝的错误或挂起。可以使用 make 变量 MAX_CONNECTIONS 限制连接数,方法如下: + make MAX_CONNECTIONS=5 check -(在某些系统上,并发连接数最高可达约 10 个。) + +(在某些系统上,并发连接数最高可达约 10 个。) @@ -1579,7 +1639,7 @@ xcrun --show-sdk-path macOS 的 - System Integrity Protection(SIP)特性会破坏 + 系统完整性保护(SIP)特性会破坏 make check,因为它会阻止把所需的 DYLD_LIBRARY_PATH 设置传递给被测试的可执行文件。 你可以通过在 make check 之前先执行 @@ -1605,7 +1665,7 @@ xcrun --show-sdk-path 安装好所有组件后,建议在 CMD.EXE 下运行 psql,因为 MSYS 控制台存在缓冲问题。 - 收集崩溃转储 + 在 Windows 上收集崩溃转储 如果 PostgreSQL 在 Windows 上崩溃,它能够生成 @@ -1647,7 +1707,7 @@ xcrun --show-sdk-path 你可以从 下载 Sun Studio。许多 GNU 工具已经集成到 Solaris 10 中, - 或者包含在 Solaris companion CD 中。如果你需要适用于较旧 Solaris 版本的 + 或者包含在 Solaris 配套光盘中。如果你需要适用于较旧 Solaris 版本的 软件包,可以到 查找这些工具。 如果你更想要源码,请看 。 @@ -1655,10 +1715,10 @@ xcrun --show-sdk-path - configure 抱怨测试程序失败 + configure 报告测试程序失败 - 如果 configure 抱怨某个测试程序失败, + 如果 configure 报告某个测试程序失败, 这多半是因为运行时链接器找不到某些库,通常是 libz、libreadline, 或其他非标准库如 libssl。要把它指向正确位置,请在 configure 命令行中设置环境变量 LDFLAGS, @@ -1697,7 +1757,9 @@ configure ... LDFLAGS="-R /usr/sfw/lib:/opt/sfw/lib:/usr/local/lib" 是的,可以使用 DTrace。更多信息见 - 如果发现链接 postgres 可执行文件时中止,并出现类似以下错误消息: + + 如果你看到在链接 postgres 可执行文件时中止,并显示如下错误: + Undefined first referenced symbol in file AbortTransaction utils/probes.o @@ -1705,7 +1767,10 @@ CommitTransaction utils/probes.o ld: fatal: Symbol referencing errors. No output written to postgres collect2: ld returned 1 exit status make: *** [postgres] Error 1 -则说明安装的 DTrace 太旧,无法处理静态函数中的探针。需要 Solaris 10u4 或更高版本才能使用 DTrace。 + + 那就说明你的 DTrace 安装太旧,无法处理静态函数中的探针。 + 你需要 Solaris 10u4 或更新版本才能使用 DTrace。 + diff --git a/zh/12/isn.sgml b/zh/12/isn.sgml index 5074ad6a..ea612463 100644 --- a/zh/12/isn.sgml +++ b/zh/12/isn.sgml @@ -1,7 +1,7 @@ - isn — 国际标准编号(ISBN、EAN、UPC 等)的数据类型 + isn isn @@ -217,24 +217,24 @@ make_valid(isn)make_valid isn - - 设置弱输入模式,并返回新的设置值。 - + 使无效编号变为有效(清除无效标记) is_valid(isn)is_valid boolean - - 返回弱模式的当前状态。 - + 检查是否存在无效标记
- 模式用于将无效数据插入表中。无效是指校验位错误,而不是编号缺失。 + + 模式用于允许向表中插入无效数据。这里的“无效”指的是校验位错误,而不是缺少数字。 + - 为什么需要使用弱模式?例如,手头可能有一大批 ISBN 编号,数量多到难免会有一些编号因为某些奇怪的原因而带有错误的校验位(也许这些编号是从印刷清单扫描得到的,而 OCR 把数字识别错了;也许这些编号是人工录入的……谁知道呢)。总之,可能想把这些混乱情况清理干净,但同时仍希望先把所有编号都装入数据库,并借助外部工具在数据库中定位无效编号,以便核对信息并更容易完成校验;例如,可能会想把表中所有无效编号都查询出来。 + + 为什么会需要使用弱模式呢?例如,手头可能有一大批 ISBN 编号,数量多到难免会有一些编号因为某些奇怪的原因而带有错误的校验位(也许这些编号是从印刷清单扫描得到的,而 OCR 把数字识别错了;也许这些编号是人工录入的……谁知道呢)。总之,可能想把这些混乱情况清理干净,但同时仍希望先把所有编号都装入数据库,并借助外部工具在数据库中定位无效编号,以便核对信息并更容易完成校验;例如,可能会想把表中所有无效编号都查询出来。 + 当在弱模式下向表中插入无效编号时,实际插入的是校验位已更正的编号,但显示时会在末尾附加一个感叹号(!),例如0-11-000322-5!。可以用is_valid函数检查这个无效标记,并用make_valid函数清除它。 @@ -292,18 +292,26 @@ SELECT isbn13(id) FROM test; 参考文献 - 实现此模块所需的信息收集自多个网站,包括: + + 实现该模块所需的信息收集自若干网站,包括: + - 连字符化使用的前缀也收集自: + + + 用于进行连字符分隔的前缀还整理自: + - 在创建这些算法时十分谨慎,并根据官方 ISBN、ISMN、ISSN 用户手册中建议的算法进行了细致验证。 + + + 在创建这些算法时已十分谨慎,并依据官方 ISBN、ISMN、ISSN 用户手册中建议的算法进行了细致核验。 + diff --git a/zh/12/libpq.sgml b/zh/12/libpq.sgml index c090110b..d21e6915 100644 --- a/zh/12/libpq.sgml +++ b/zh/12/libpq.sgml @@ -33,7 +33,7 @@ 以下函数用于建立到PostgreSQL后端服务器的连接。应用程序可以同时保持多个后端连接。(这样做的原因之一是访问多个数据库。)每个连接由一个PGconnPGconn对象表示,该对象可以通过以下函数获取:PQconnectdbPQconnectdbParams,或PQsetdbLogin。注意,这些函数总是返回非空的对象指针,除非内存不足,甚至无法分配PGconn对象。应调用PQstatus函数检查返回值,确认连接成功后,再通过连接对象发送查询。 - 如果不可信用户能够访问一个没有采用模式的安全使用方式的数据库,那么每个会话开始时都应从search_path中移除公开可写的模式。可以把参数关键词options设置为-csearch_path=。也可以在连接后发出PQexec(conn, "SELECT pg_catalog.set_config('search_path', '', false)")。这种考虑并非专门针对libpq;它适用于每一种可执行任意 SQL 命令的接口。 + 如果不受信任的用户能够访问一个没有采用模式的安全使用方式的数据库,那么每个会话开始时都应从search_path中移除公开可写的模式。可以把参数关键词options设置为-csearch_path=。也可以在连接后发出PQexec(conn, "SELECT pg_catalog.set_config('search_path', '', false)")。这种考虑并非专门针对libpq;它适用于每一种可执行任意 SQL 命令的接口。 @@ -195,7 +195,7 @@ PostgresPollingStatusType PQconnectPoll(PGconn *conn); 无论是PQconnectStartParams还是PQconnectStart还是PQconnectPoll都不会阻塞,只要满足以下限制: - 必须正确使用 hostaddr 参数,避免执行 DNS 查询。详细信息请参见 中此参数的文档。 + 必须正确使用 hostaddr 参数,以避免执行 DNS 查询。详细信息请参见 中该参数的说明。 @@ -1433,20 +1433,31 @@ PGTransactionStatusType PQtransactionStatus(const PGconn *conn); PQparameterStatus PQparameterStatus - 查找服务器某个参数的当前设置。 + + 查找服务器某个参数的当前设置。 + + const char *PQparameterStatus(const PGconn *conn, const char *paramName); -服务器会在连接启动时,以及某些参数值发生变化时,自动报告这些参数值。PQparameterStatus可用于查询这些设置。如果已知该参数,则返回其当前值;如果未知,则返回NULL + - 当前版本报告的参数包括 server_versionserver_encodingclient_encodingapplication_nameis_superusersession_authorizationDateStyleIntervalStyleTimeZoneinteger_datetimesstandard_conforming_strings。(8.0 之前的版本不报告 server_encodingTimeZoneinteger_datetimes;8.1 之前的版本不报告 standard_conforming_strings;8.4 之前的版本不报告 IntervalStyle;9.0 之前的版本不报告 application_name。)注意,server_versionserver_encodinginteger_datetimes 在启动后不能改变。 + 服务器会在连接启动时,以及某些参数值发生变化时,自动报告这些参数值。PQparameterStatus可用于查询这些设置。如果已知该参数,则返回其当前值;如果未知,则返回NULL。 + + + + 当前版本报告的参数包括: + server_versionserver_encodingclient_encodingapplication_nameis_superusersession_authorizationDateStyleIntervalStyleTimeZoneinteger_datetimesstandard_conforming_strings。 + (8.0 之前的版本不报告 server_encodingTimeZoneinteger_datetimes;8.1 之前的版本不报告 standard_conforming_strings;8.4 之前的版本不报告 IntervalStyle;9.0 之前的版本不报告 application_name。) + 注意,server_versionserver_encodinginteger_datetimes 在启动后不能改变。 + 使用 3.0 之前协议的服务器不报告参数设置,但 libpq 仍包含获取 server_versionclient_encoding 值的逻辑。建议应用程序使用 PQparameterStatus,而不是专门编写代码来确定这些值。(但要注意,在使用 3.0 之前协议的连接上,连接启动后通过 SET 改变 client_encoding,不会反映在 PQparameterStatus 的结果中。)对于 server_version,另请参见 PQserverVersion,它以数值形式返回此信息,更易于比较。 - 如果没有为standard_conforming_strings报告值,应用能假设它是off,也就是说反斜线会被视为字符串中的转义。还有,这个参数的存在可以被作为转义字符串语法(E'...')被接受的指示。 + 如果服务器未报告standard_conforming_strings的值,应用程序可以假定其为off,即反斜杠在字符串字面量中被视为转义字符。此外,服务器报告此参数也表明它接受转义字符串语法(E'...')。 - 尽管被返回的指针被声明成const,它事实上指向与PGconn结构体相关的可变存储。假定该指针在存储之间保持有效是不明智的。 + 返回的指针虽然被声明为const,但实际上指向与PGconn结构体关联的可变存储。不能假定该指针在执行其他查询后仍然有效。 @@ -1816,7 +1827,7 @@ PGresult *PQexecParams(PGconn *conn, paramTypes[] - 通过 OID 指定要赋予给参数符号的数据类型。如果paramTypesNULL或者该数组中任何特定元素为零,服务器会用对待未知类型文字串的方式为参数符号推测一种数据类型。 + 通过 OID 指定要赋予给参数符号的数据类型。如果paramTypesNULL或者该数组中任何特定元素为零,服务器会用对待未指定类型的字符串字面量的方式为参数符号推测一种数据类型。 @@ -1908,7 +1919,7 @@ PGresult *PQprepare(PGconn *conn, 否则,如果语句名称已经在当前会话中被定义,则是一种错误。如果使用了任何参数,它们在查询中以$1$2等引用。 nParams是参数的个数,其类型在数组paramTypes[]中被预先指定(当nParams为零时,该数组指针可以是NULL)。 paramTypes[]通过 OID 指定要赋予给参数符号的数据类型。 - 如果paramTypesNULL或者该数组中任何特定元素为零,服务器会用对待未知类型文字串的方式为参数符号推测一种数据类型。 + 如果paramTypesNULL或者该数组中任何特定元素为零,服务器会用对待未指定类型的字符串字面量的方式为参数符号推测一种数据类型。 还有,查询能够使用编号高于nParams的参数符号,它们的数据类型也会被自动推测(找出推测出的数据类型的方法见PQdescribePrepared)。 @@ -2209,7 +2220,7 @@ char *PQresultErrorField(const PGresult *res, int fieldcode); PG_DIAG_MESSAGE_DETAIL - 细节:一个可选的次级错误消息,它携带了关于问题的等多细节。可能有多行。 + 细节:一个可选的次级错误消息,它携带了关于问题的更多细节。可能有多行。 @@ -2227,7 +2238,7 @@ char *PQresultErrorField(const PGresult *res, int fieldcode); PG_DIAG_STATEMENT_POSITION - 包含一个十进制整数的字符串,它表示一个错误游标位置,该位置是原始语句字符串的索引。第一个字符的索引是 1,位置以字符计算而不是以及字节计算。 + 包含一个十进制整数的字符串,它表示一个错误游标位置,该位置是原始语句字符串的索引。第一个字符的索引是 1,位置以字符计算而不是以字节计算。 @@ -2929,7 +2940,7 @@ unsigned char *PQescapeByteaConn(PGconn *conn, - 当某些字节值被用作一个SQL语句中的bytea文字的一部分时,它们必须被转义。 + 当某些字节值被用作一个SQL语句中的bytea字面量的一部分时,它们必须被转义。 PQescapeByteaConn使用十六进制编码或反斜杠转义来转义这些字节。详见 @@ -2970,19 +2981,26 @@ unsigned char *PQescapeBytea(const unsigned char *from, PQunescapeBytea PQunescapeBytea - 将二进制数据的字符串表示转换为二进制数据,这是以下函数的逆操作:PQescapeBytea。以文本格式取得bytea数据时需要此操作;以二进制格式取得时则不需要。 + + 将二进制数据的字符串表示转换为二进制数据,这是PQescapeBytea的逆操作。 + 以文本格式取得bytea数据时需要此操作;以二进制格式取得时则不需要。 + + unsigned char *PQunescapeBytea(const unsigned char *from, size_t *to_length); - from参数指向一个字符串,例如PQgetvalue被应用到一个bytea列上所返回的。 - PQunescapeBytea把这个串表示转换成它的二进制表示。 - 它返回一个指向用malloc()分配的缓冲区的指针,在错误时返回NULL,并且把缓冲区的尺寸放在to_length中。 - 当结果不再需要时,它必须使用PQfreemem释放。 + from参数指向一个字符串,例如对bytea列调用PQgetvalue时返回的字符串。 + PQunescapeBytea将这个字符串表示转换为二进制表示。 + 它返回指向通过malloc()分配的缓冲区的指针,出错时返回NULL,并将缓冲区大小存入to_length。 + 不再需要结果时,必须使用PQfreemem释放它。 - 此转换并不完全是 PQescapeBytea 的逆操作,因为从 PQgetvalue 收到的字符串不应已经过转义。具体而言,这意味着无需考虑字符串引号,因此也不需要 PGconn 参数。 + + 此转换并不完全是PQescapeBytea的逆操作,因为从PQgetvalue收到的字符串并非经过转义的形式。 + 具体而言,这意味着无需考虑字符串引号,因此也不需要PGconn参数。 + @@ -3275,7 +3293,7 @@ int PQflush(PGconn *conn);
- 分块检索查询结果 + 逐行检索查询结果 libpq @@ -3444,7 +3462,7 @@ typedef struct
- 要传递NULL参数到函数,将参数结构体的len字段设置为-1;isintu 字段就不相关了。(但这仅适用于使用协议 3.0 及更高版本的连接。) + 要传递NULL参数到函数,将参数结构体的len字段设置为-1isintu 字段就不相关了。(但这仅适用于使用协议 3.0 及更高版本的连接。)
如果函数返回 NULL,则将 *result_len 设为 -1,而不修改 *result_buf。(这仅适用于使用协议 3.0 及更高版本的连接;在协议 2.0 中,既不修改 *result_len,也不修改 *result_buf。) @@ -4036,11 +4054,12 @@ PGresult *PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status); 这是libpq内部用于分配并初始化一个空PGresult对象的函数。 - 如果不能分配内存,那么这个函数返回NULL。 - 它也是可以对外使用的,因为一些应用需要自行生成结果对象(特别是带有错误状态的对象)。 - 如果conn非空,并且status表示一个错误,那么指定连接的当前错误消息会被复制到PGresult中。 - 如果conn非空,那么连接中的任何已注册事件过程也会被复制到PGresult中(它们不会获得PGEVT_RESULTCREATE调用,但可参见PQfireResultCreateEvents)。 - 注意在该对象上最终应该调用PQclear,正如对libpq本身返回的PGresult对象所作的那样。 + 如果无法分配内存,此函数返回NULL。 + 将它导出供外部调用,是因为一些应用需要自行生成结果对象,特别是带有错误状态的对象。 + 如果conn非空,并且status表示错误,指定连接的当前错误消息会被复制到PGresult中。 + 此外,如果conn非空,连接中注册的所有事件过程也会被复制到PGresult中。 + (这些过程不会收到PGEVT_RESULTCREATE调用,但可参见PQfireResultCreateEvents。) + 注意,最终应对该对象调用PQclear,就像处理libpq自身返回的PGresult一样。 @@ -4333,13 +4352,25 @@ typedef struct PGEVT_RESULTCREATE - 任何生成结果的查询执行函数都会触发结果创建事件,其中包括PQgetResult。只有成功创建结果后才会触发该事件。 + + 任何生成结果的查询执行函数都会触发结果创建事件,其中包括PQgetResult。 + 只有成功创建结果后才会触发该事件。 + + typedef struct { PGconn *conn; PGresult *result; } PGEventResultCreate; -收到PGEVT_RESULTCREATE事件时,应将evtInfo指针强制转换为PGEventResultCreate *。其中,conn是用于生成结果的连接。这是初始化需要与结果关联的instanceData的理想位置。如果事件处理函数失败,结果会被清除,失败也会向外传递。事件处理函数不得自行调用PQclear来清除结果对象。返回失败代码时,必须完成所有清理工作,因为不会发送PGEVT_RESULTDESTROY事件。 + + + 收到PGEVT_RESULTCREATE事件时,应将evtInfo指针转换为PGEventResultCreate *。 + 其中,conn是用于生成结果的连接。 + 这是初始化需要与结果关联的instanceData的理想位置。 + 如果事件过程失败,结果会被清除,失败也会向外传递。 + 事件过程不得自行调用PQclear来清除结果对象。 + 返回失败代码时,必须完成所有清理工作,因为不会发送PGEVT_RESULTDESTROY事件。 + @@ -4997,13 +5028,8 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough) - 用户的主目录中的文件.pgpass可以包含密码, - 如果连接需要密码(且未指定其他密码)。在Microsoft Windows中, - 该文件的名称为%APPDATA%\postgresql\pgpass.conf - (其中%APPDATA%指用户配置文件中的应用数据子目录)。 - 或者,可以使用连接参数 - 或环境变量PGPASSFILE指定要使用的密码文件。 - + 用户主目录中的.pgpass文件可保存密码,供连接需要密码且尚未通过其他方式指定密码时使用。在 Microsoft Windows 上,文件名为%APPDATA%\postgresql\pgpass.conf(其中%APPDATA%指用户配置文件中的应用数据子目录)。也可以通过连接参数或环境变量PGPASSFILE指定要使用的密码文件。 +
该文件中的行应采用以下格式: hostname:port:database:username:password @@ -5440,8 +5466,8 @@ void PQinitSSL(int do_ssl); 在线程化程序中的行为 - threads - with libpq + 线程 + 用于 libpq libpq 默认是可重入且线程安全的。编译应用程序代码时,可能需要使用特殊的编译器命令行选项。有关如何构建支持线程的应用程序,请参阅系统文档,或查看 src/Makefile.global 中的 PTHREAD_CFLAGSPTHREAD_LIBS。以下函数可用于查询 libpq 的线程安全状态: @@ -5459,7 +5485,7 @@ int PQisthreadsafe(); - 如果libpq是线程安全的则返回 1,否则返回 0。在版本 17 及以上始终返回 1。 + 如果libpq是线程安全的则返回 1,否则返回 0。 diff --git a/zh/12/logical-replication.sgml b/zh/12/logical-replication.sgml index 64b1a372..b8975a72 100644 --- a/zh/12/logical-replication.sgml +++ b/zh/12/logical-replication.sgml @@ -201,7 +201,12 @@ - 数据库模式和DDL命令不会被复制。初始模式可使用pg_dump --schema-only手动复制。后续的模式变更需要手动保持同步。(注意,两端的模式不需要完全相同。)当数据库模式在运行中发生变更时,逻辑复制是健壮的:当发布端模式变更后,复制的数据开始到达订阅端但不符合表的模式时,复制会出错,直到模式被更新。在很多情况下,通过先在订阅端应用增量式模式变更,可以避免间歇性错误。 + 数据库模式和 DDL 命令不会被复制。初始模式可以手工使用 + pg_dump --schema-only 复制。之后的模式更改需要手工保持同步。 + (不过请注意,两端的模式其实不需要绝对一致。)当活动数据库中的模式定义发生变化时, + 逻辑复制仍然能够稳健运行:如果发布端修改了模式,而复制数据开始到达订阅端时 + 与表模式不匹配,复制就会报错,直到模式被更新。在很多情况下,可以通过先在订阅端 + 应用仅添加内容的模式变更来避免间歇性错误。 @@ -237,15 +242,15 @@ - 逻辑复制采用类似于物理流复制的架构(见)。它由walsenderapply进程实现。walsender 进程启动 WAL 的逻辑解码(见),并加载标准逻辑解码输出插件(pgoutput)。该插件将从 WAL 读取的变更转换为逻辑复制协议(见),并根据发布规范过滤数据。然后使用流复制协议将数据持续传输给 apply 工作进程,该工作进程将数据映射到本地表,并按正确的事务顺序逐一应用每个变更。 + 逻辑复制采用类似于物理流复制的架构(见)。它由walsenderapply进程实现。walsender 进程启动 WAL 的逻辑解码(见),并加载标准逻辑解码输出插件(pgoutput)。该插件将从 WAL 读取的变更转换为逻辑复制协议(见),并根据发布规范过滤数据。然后使用流复制协议将数据持续传输给 应用工作进程,该工作进程将数据映射到本地表,并按正确的事务顺序逐一应用每个变更。 - 订阅端数据库上的 apply 进程总是在session_replication_role设置为replica的情况下运行。这意味着默认情况下,触发器和规则不会在订阅端触发。用户可以选择使用ALTER TABLE命令和ENABLE TRIGGERENABLE RULE子句在表上启用触发器和规则。 + 订阅端数据库上的 应用进程总是在session_replication_role设置为replica的情况下运行。这意味着默认情况下,触发器和规则不会在订阅端触发。用户可以选择使用ALTER TABLE命令和ENABLE TRIGGERENABLE RULE子句在表上启用触发器和规则。 - 逻辑复制的apply进程目前只触发行触发器,不触发语句触发器。但初始表同步的实现方式类似于COPY命令,因此会触发INSERT的行触发器和语句触发器。 + 逻辑复制的应用进程目前只触发行触发器,不触发语句触发器。但初始表同步的实现方式类似于COPY命令,因此会触发INSERT的行触发器和语句触发器。 @@ -268,7 +273,7 @@ - 正常情况下,已启用的订阅会有一个apply进程在运行。被禁用或已崩溃的订阅在此视图中将有零行。如果任何表的初始数据同步正在进行中,将有额外的工作进程用于正在同步的表。 + 正常情况下,已启用的订阅会有一个应用进程在运行。被禁用或已崩溃的订阅在此视图中将有零行。如果任何表的初始数据同步正在进行中,将有额外的工作进程用于正在同步的表。 @@ -300,7 +305,7 @@ - 订阅的apply进程将以超级用户的权限在本地数据库上运行。 + 订阅应用进程将以超级用户的权限在本地数据库中运行。 diff --git a/zh/12/maintenance.sgml b/zh/12/maintenance.sgml index 806c5fd8..b3eba58b 100644 --- a/zh/12/maintenance.sgml +++ b/zh/12/maintenance.sgml @@ -397,12 +397,9 @@ SELECT datname, age(datfrozenxid) FROM pg_database; - 虽然 VACUUM 主要扫描自上次清理以来被修改过的页面, - 但它也可能为了冻结它们而积极扫描某些全部可见但未全部冻结的页面; - 不过,只有当表中每一个可能包含未冻结 XID 的页面都被扫描时, - relfrozenxid 才会被推进。当 - relfrozenxid 比 - vacuum_freeze_table_age 旧、使用了 VACUUM 的 + VACUUM通常只扫描自上次清理以来被修改过的页面,但只有当表中每一个可能包含未冻结 XID 的页面都被扫描时, + relfrozenxid 才会被推进。当 + relfrozenxid的年龄超过vacuum_freeze_table_age个事务、使用了 VACUUMFREEZE 选项,或者所有尚未全部冻结的页面碰巧都需要清理以移除死行版本时, 就会发生这种情况。当 VACUUM 扫描了表中每个尚未全部冻结的页面时, 它应把 age(relfrozenxid) 设为略高于所用 @@ -433,14 +430,14 @@ HINT: Stop the postmaster and vacuum that database in single-user mode. 多事务 ID 的 - 多事务 ID 用于支持多个事务对行加锁。由于元组头中存放锁信息的空间有限,当多个事务同时锁定一行时,这些信息会被编码为一个多事务 ID,简称 multixact ID。某个特定 multixact ID 包含哪些事务 ID 的信息,单独存放在 pg_multixact 子目录中,元组头的 xmax 字段中只保存 multixact ID。与事务 ID 一样,multixact ID 由 32 位计数器和相应的存储实现,都需要谨慎处理老化管理、存储清理和回卷。另有单独的存储区保存每个 multixact 的成员列表,它同样使用 32 位计数器,也需要管理。 + 多事务 ID 用于支持多个事务对行加锁。由于元组头中存放锁信息的空间有限,当多个事务同时锁定一行时,这些信息会被编码为一个多事务 ID,简称 multixact ID。某个特定 多事务 ID 包含哪些事务 ID 的信息,单独存放在 pg_multixact 子目录中,元组头的 xmax 字段中只保存 多事务 ID。与事务 ID 一样,多事务 ID 由 32 位计数器和相应的存储实现,都需要谨慎处理老化管理、存储清理和回卷。另有单独的存储区保存每个 多事务 的成员列表,它同样使用 32 位计数器,也需要管理。 每当 VACUUM 扫描表的任何部分时,它都会把遇到的、早于 - 的任何 multixact ID 替换为另一个值,该值可能是零值、单个事务 ID,或者更新的 multixact ID。 + 的任何 多事务 ID 替换为另一个值,该值可能是零值、单个事务 ID,或者更新的 多事务 ID。 对于每个表,pg_class.relminmxid - 保存该表任何元组中仍可能出现的最老 multixact ID。如果这个值早于 + 保存该表任何元组中仍可能出现的最老 多事务 ID。如果这个值早于 ,就会强制执行一次激进扫描。 正如上一节所述,激进扫描意味着只有那些已知为全部冻结的页面才会被跳过。 可以对 pg_class.relminmxid @@ -449,10 +446,10 @@ HINT: Stop the postmaster and vacuum that database in single-user mode. 无论出于何种原因而发生,激进的 VACUUM 扫描都能推进该表的值。最终,随着所有数据库中的所有表都被扫描, - 并推进其最老的 multixact 值,较老 multixact 的磁盘存储就可以被移除。 + 并推进其最老的 多事务 值,较老 多事务 的磁盘存储就可以被移除。 - 作为一项安全措施,对于 multixact 年龄大于 的任何表,都会执行激进清理扫描。如果已使用的成员存储空间超过可寻址存储空间的 50%,还会从 multixact 年龄最大的表开始,逐步对所有表执行激进清理扫描。即使名义上禁用了自动清理,这两类激进扫描也都会发生。 + 作为一项安全措施,对于 多事务 年龄大于 的任何表,都会执行激进清理扫描。如果已使用的成员存储空间超过可寻址存储空间的 50%,还会从 多事务 年龄最大的表开始,逐步对所有表执行激进清理扫描。即使名义上禁用了自动清理,这两类激进扫描也都会发生。 @@ -680,7 +677,7 @@ pg_ctl start | rotatelogs /var/log/pgsql_log 86400 不过,在很多系统上,syslog 并不十分可靠, 尤其是在日志消息很大时;它可能恰恰在你最需要消息的时候截断或丢弃它们。 此外,在 Linux 上, - syslog 会把每条消息都刷新到磁盘,导致性能较差。 + syslog 会把每条消息都刷盘,导致性能较差。 (你可以在 syslog 配置文件的文件名开头使用一个 - 来禁用同步。) diff --git a/zh/12/monitoring.sgml b/zh/12/monitoring.sgml index aa54317a..089046fb 100644 --- a/zh/12/monitoring.sgml +++ b/zh/12/monitoring.sgml @@ -47,7 +47,9 @@ postgres 15610 0.0 0.0 58772 3056 ? Ss 18:07 0:00 postgres: tgl postgres: user database host activity 在客户端连接的整个生命周期内,用户、数据库和(客户端)主机这几项保持不变,但活动指示符会改变。活动可以是idle(即等待客户端命令)、idle in transaction(在BEGIN块内等待客户端),或者命令类型名称,例如SELECT。此外,服务器进程当前若正在等待另一会话持有的锁,还会附加waiting。在上面的示例中,可以推断进程 15606 正在等待进程 15610 完成事务,从而释放某个锁。(进程 15610 必定是阻塞者,因为不存在其他活动会话。在更复杂的情况下,必须查看pg_locks系统视图,才能确定谁在阻塞谁。) - 如果已配置,集簇名称也会显示在ps的输出中: + + 如果配置了,则集簇名称也会显示在ps输出中: + $ psql -c 'SHOW cluster_name' cluster_name -------------- @@ -76,14 +78,14 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 统计收集器 - statistics + 统计信息 PostgreSQL统计收集器是一个支持收集和报告服务器活动信息的子系统。 - 目前,对表和索引的访问以磁盘块和单个行的术语进行计数。每个表中的总行数, - 以及每个表的清理和分析操作的信息也被计数。如果启用,对用户定义函数的调用 - 和每个函数中花费的总时间也会被计数。 + 目前,对表和索引的访问分别以磁盘块和单行计数。每个表中的总行数, + 以及每个表的清理和分析操作的信息也被计数。它还可以统计对用户定义函数的调用 + 和每个函数中花费的总时间。 @@ -140,7 +142,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - 另一个重要点是,当要求服务器进程显示这些统计信息中的任何一种时,它会先取回收集器进程最近发出的报告,然后在当前事务结束之前,对所有统计视图和函数一直使用这一快照。因此,只要你继续当前事务,统计信息就会显示静态信息。类似地,在事务中第一次请求任意当前会话的查询信息时,就会收集所有会话当前查询的信息,并且在整个事务期间显示的都是同一份信息。这是一个特性,而不是一个错误,因为它允许你对统计信息执行多个查询并对结果做关联,而不必担心数字在你眼前变化。但如果希望每个查询都看到新的结果,请确保在任何事务块之外执行这些查询。或者,也可以调用pg_stat_clear_snapshot(),它会丢弃当前事务的统计快照(如果有)。下一次使用统计信息时,就会获取一个新的快照。 + 另一个重要点是,当要求服务器进程显示这些统计信息中的任何一种时,它会先取回收集器进程最近发出的报告,然后在当前事务结束之前,对所有统计视图和函数一直使用这一快照。因此,只要你继续当前事务,统计信息就会显示静态信息。类似地,在事务中第一次请求这类当前查询信息时,就会收集所有会话当前查询的信息,并且在整个事务期间显示的都是同一份信息。这是一个特性,而不是一个错误,因为它允许你对统计信息执行多个查询并对结果做关联,而不必担心数字在你眼前变化。但如果希望每个查询都看到新的结果,请确保在任何事务块之外执行这些查询。或者,也可以调用pg_stat_clear_snapshot(),它会丢弃当前事务的统计快照(如果有)。下一次使用统计信息时,就会获取一个新的快照。 @@ -152,12 +154,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 相反,它们在事务期间持续更新。 - - 动态统计视图中显示的一些信息在中受到安全限制。 - 普通用户只能查看关于他们自己会话的所有信息(属于他们是成员的角色的会话)。在关于其他会话的行中,许多列将为空。 - 但是,请注意,所有用户都可以看到会话的存在及其一般属性,例如会话用户和数据库。超级用户以及内置角色pg_read_all_stats的成员(另请参阅)可以查看所有会话的全部信息。 - + 所列动态统计视图中的一些信息受到安全限制。普通用户只能查看其自身会话的全部信息(包括属于其所加入角色的会话)。对于其他会话的行,许多列将为空值。不过,会话的存在及其一般属性(例如会话用户和数据库)对所有用户都可见。超级用户和内置角色pg_read_all_stats的成员(另请参阅)可以查看所有会话的全部信息。 动态统计视图 @@ -240,122 +237,123 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser + pg_stat_archiverpg_stat_archiver 只有一行,显示 WAL 归档进程活动的统计信息。详见 - + pg_stat_bgwriterpg_stat_bgwriter - 只有一行,显示后台写入进程活动的统计信息。详见 + 只有一行,显示后台写入器活动的统计信息。详见 - + pg_stat_databasepg_stat_database 每个数据库一行,显示整个数据库的统计信息。详见 - + pg_stat_database_conflictspg_stat_database_conflicts 每个数据库一行,显示备库上因与恢复冲突而取消查询的数据库范围统计信息。详见 - + pg_stat_all_tablespg_stat_all_tables 当前数据库中的每个表一行,显示访问该表的统计信息。详见 - + pg_stat_sys_tablespg_stat_sys_tables pg_stat_all_tables一样,但只显示系统表。 - + pg_stat_user_tablespg_stat_user_tables pg_stat_all_tables一样,但只显示用户表。 - + pg_stat_xact_all_tablespg_stat_xact_all_tables - pg_stat_all_tables相似,但计数动作只在当前事务内发生(还没有被包括在pg_stat_all_tables和相关视图中)。用于生存和死亡行数量的列以及清理和分析动作在此视图中不出现。 + pg_stat_all_tables 相似,但只统计当前事务中截至目前执行的操作(这些操作尚计入 pg_stat_all_tables 及相关视图)。此视图不包含存活行和死行数量以及清理、分析操作的列。 - + pg_stat_xact_sys_tablespg_stat_xact_sys_tables pg_stat_xact_all_tables一样,但只显示系统表。 - + pg_stat_xact_user_tablespg_stat_xact_user_tables pg_stat_xact_all_tables一样,但只显示用户表。 - + pg_stat_all_indexespg_stat_all_indexes 当前数据库中的每个索引一行,显示访问该索引的统计信息。详见 - + pg_stat_sys_indexespg_stat_sys_indexes pg_stat_all_indexes一样,但只显示系统表上的索引。 - + pg_stat_user_indexespg_stat_user_indexes pg_stat_all_indexes一样,但只显示用户表上的索引。 - + pg_statio_all_tablespg_statio_all_tables 当前数据库中的每个表一行,显示该表的 I/O 统计信息。详见 - + pg_statio_sys_tablespg_statio_sys_tables pg_statio_all_tables一样,但只显示系统表。 - + pg_statio_user_tablespg_statio_user_tables pg_statio_all_tables一样,但只显示用户表。 - + pg_statio_all_indexespg_statio_all_indexes 当前数据库中的每个索引一行,显示该索引的 I/O 统计信息。详见 - + pg_statio_sys_indexespg_statio_sys_indexes pg_statio_all_indexes一样,但只显示系统表上的索引。 - + pg_statio_user_indexespg_statio_user_indexes pg_statio_all_indexes一样,但只显示用户表上的索引。 - + pg_statio_all_sequencespg_statio_all_sequences 当前数据库中的每个序列一行,显示该序列的 I/O 统计信息。详见 - + pg_statio_sys_sequencespg_statio_sys_sequences pg_statio_all_sequences一样,但只显示系统序列(目前没有定义系统序列,因此这个视图总是为空)。 - + pg_statio_user_sequencespg_statio_user_sequences pg_statio_all_sequences一样,但只显示用户序列。 - + pg_stat_user_functionspg_stat_user_functions 每个被跟踪的函数一行,显示该函数执行的统计信息。详见 - + pg_stat_xact_user_functionspg_stat_xact_user_functions pg_stat_user_functions相似,但是只统计在当前事务期间的调用(还没有被包括在pg_stat_user_functions中)。 @@ -437,7 +435,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser client_addr inet - 连接到这个后端的客户端的 IP 地址。如果这个字段为空,它表示客户端通过服务器机器上的一个 Unix 套接字连接或者这是一个内部进程,如自动清理。 + 连接到这个后端的客户端的 IP 地址。如果这个字段为空值,它表示客户端通过服务器机器上的一个 Unix 套接字连接或者这是一个内部进程,如自动清理。 @@ -464,8 +462,8 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser xact_start timestamp with time zone - 这个进程的当前事务被启动的时间,如果没有活动事务则为空。 - 如果当前查询是它的第一个事务,这一列等于query_start列。 + 这个进程的当前事务被启动的时间,如果没有活动事务则为空值。 + 如果当前查询是其事务中的第一个查询,这一列等于query_start列。 @@ -485,7 +483,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser wait_event_type text - 后端正在等待的事件类型(如果有),否则为 NULL。可能的值为: + 后端正在等待的事件类型(如果有),否则为空值。可能的值为: LWLock:后端正在等待轻量级锁。每个这样的锁保护共享内存中的某个特定数据结构。wait_event将包含标识该轻量级锁用途的名称。(有些锁具有专门的名称,另一些锁属于一组用途相似的锁。) @@ -519,32 +517,32 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser wait_event text - 如果后端当前正在等待,则为等待事件名称,否则为 NULL。详见 + 如果后端当前正在等待,则为等待事件名称,否则为空值。详见 state text 该后端当前的总体状态。可能的值为: - - active:后端正在执行一个查询。 - - - idle:后端正在等待新的客户端命令。 - - - idle in transaction:后端处于事务中,但当前没有执行查询。 - - - idle in transaction (aborted):该状态与idle in transaction类似,但事务中的某个语句导致了错误。 - - - fastpath function call:后端正在执行一个快速路径函数。 - - - disabled:如果在此后端中禁用了,就会报告此状态。 - + + active:后端正在执行一个查询。 + + + idle:后端正在等待新的客户端命令。 + + + idle in transaction:后端处于事务中,但当前没有执行查询。 + + + idle in transaction (aborted):该状态与idle in transaction类似,但事务中的某个语句导致了错误。 + + + fastpath function call:后端正在执行一个快速路径函数。 + + + disabled:如果在此后端中禁用了,就会报告此状态。 + - + backend_xid @@ -557,7 +555,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser backend_xmin xid - 当前后端的xmin范围。 + 当前后端的xmin视界。 @@ -571,17 +569,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser backend_type text - - 当前后端的类型。可能的类型为 - autovacuum launcher, autovacuum worker, - logical replication launcher, - logical replication worker, - parallel worker, background writer, - client backend, checkpointer, - startup, walreceiver, - walsenderwalwriter。 - 此外,由扩展注册的后台工作进程还可能有额外的类型。 - + 当前后端的类型。可能的类型为autovacuum launcherautovacuum workerlogical replication launcherlogical replication workerparallel workerbackground writerclient backendcheckpointerstartupwalreceiverwalsenderwalwriter。此外,由扩展注册的后台工作进程还可能有额外的类型。 @@ -619,854 +607,853 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser OidGenLock等待分配或指派 OID。 - + XidGenLock 等待分配或指派事务 ID。 - + ProcArrayLock 等待获取快照,或在事务结束时清除事务 ID。 - + SInvalReadLock 等待从共享失效队列中取出或移除消息。 - + SInvalWriteLock 等待向共享失效队列添加消息。 - + WALBufMappingLock 等待在WAL缓冲区中替换一个页面。 - + WALWriteLock 等待WAL缓冲区写入磁盘。 - + ControlFileLock 等待读取或更新控制文件,或创建新的 WAL 文件。 - + CheckpointLock 等待执行检查点。 - + CLogControlLock 等待读取或更新事务状态。 - + SubtransControlLock 等待读取或更新子事务信息。 - + MultiXactGenLock - 等待读取或更新共享的multixact状态。 + 等待读取或更新共享的多事务状态。 - + MultiXactOffsetControlLock 等待读取或更新多事务偏移映射。 - + MultiXactMemberControlLock 等待读取或更新多事务成员映射。 - + RelCacheInitLock 等待读取或写入关系缓存初始化文件。 - + CheckpointerCommLock 等待管理fsync请求。 - + TwoPhaseStateLock - 等待读取或更新已准备事务的状态。 + 等待读取或更新预备事务的状态。 - + TablespaceCreateLock 等待创建或删除表空间。 - + BtreeVacuumLock 等待读取或更新B-树索引的清理相关信息。 - + AddinShmemInitLock 等待管理共享内存中的空间分配。 - + AutovacuumLock 自动清理工作进程或启动进程正在等待更新或读取自动清理工作进程的当前状态。 - + AutovacuumScheduleLock 等待确认已选定要清理的表仍然需要清理。 - + SyncScanLock 等待获取同步扫描所用的表扫描起始位置。 - + RelationMappingLock - 等待更新用于存储目录到文件节点映射的关系映射文件。 + 等待更新用于存储系统目录到文件节点映射的关系映射文件。 - + AsyncCtlLock 等待读取或更新共享通知状态。 - + AsyncQueueLock 等待读取或更新通知消息。 - + SerializableXactHashLock - 等待获取或存储可序列化事务的信息。 + 等待获取或存储可串行化事务的信息。 - + SerializableFinishedListLock 等待访问已完成的可串行化事务列表。 - + SerializablePredicateLockListLock - 等待对可序列化事务所持有的锁列表执行操作。 + 等待对可串行化事务所持有的锁列表执行操作。 - + OldSerXidLock - 等待读取或记录相互冲突的可序列化事务。 + 等待读取或记录相互冲突的可串行化事务。 - + SyncRepLock 等待读取或更新同步副本的信息。 - + BackgroundWorkerLock 等待读取或更新后台工作进程状态。 - + DynamicSharedMemoryControlLock 等待读取或更新动态共享内存状态。 - + AutoFileLock 等待更新postgresql.auto.conf文件。 - + ReplicationSlotAllocationLock 等待分配或释放复制槽。 - + ReplicationSlotControlLock 等待读取或更新复制槽状态。 - + CommitTsControlLock 等待读取或更新事务提交时间戳。 - + CommitTsLock 等待读取或更新最近设置的事务时间戳值。 - + ReplicationOriginLock 等待设置、删除或使用复制源。 - + MultiXactTruncationLock - 等待读取或截断multixact信息。 + 等待读取或截断多事务信息。 - + OldSnapshotTimeMapLock 等待读取或更新旧的快照控制信息。 - + LogicalRepWorkerLock 等待对逻辑复制工作进程的操作完成。 - + CLogTruncationLock 等待执行txid_status,或更新该函数可用的最早事务 ID。 - + WrapLimitsVacuumLock - 等待更新事务 ID和multixact消费的限制。 + 等待更新事务 ID 和多事务消耗量的限制。 - + NotifyQueueTailLock 等待更新通知消息存储的限制。 - + clog 等待 clog(事务状态)缓冲区上的 I/O。 - + commit_timestamp 等待提交时间戳缓冲区上的 I/O。 - + subtrans 等待子事务缓冲区上的 I/O。 - + multixact_offset - 等待多事务偏移缓冲区上的 I/O。 + 等待多事务偏移量缓冲区上的 I/O。 - + multixact_member 等待 multixact_member 缓冲区上的 I/O。 - + async 等待 async(通知)缓冲区上的 I/O。 - + oldserxid 等待 oldserxid 缓冲区上的 I/O。 - + wal_insert 等待将 WAL 插入内存缓冲区。 - + buffer_content 等待读取或写入内存中的数据页。 - + buffer_io 等待数据页上的 I/O。 - + replication_origin 等待读取或更新复制进度。 - + replication_slot_io 在复制槽上等待I/O。 - + proc 等待读取或更新快速路径锁信息。 - + buffer_mapping 等待将数据块与缓冲池中的缓冲区关联。 - + lock_manager 等待添加或检查后端的锁,或者等待加入或退出锁组(用于并行查询)。 - + predicate_lock_manager 等待添加或检查谓词锁信息。 - + serializable_xact - 等待在并行查询中对可序列化事务执行操作。 + 等待在并行查询中对可串行化事务执行操作。 - + parallel_query_dsa 等待并行查询的动态共享内存分配锁。 - + tbm 等待 TBM 共享迭代器锁。 - + parallel_append - 在并行附加计划执行期间等待选择下一个子计划。 + 在 Parallel Append 计划执行期间等待选择下一个子计划。 - + parallel_hash_join - 等待在执行并行哈希计划期间分配或交换内存块,或者更新计数器。 + 在 Parallel Hash 计划执行期间,等待分配或交换内存块,或更新计数器。 - + Lock relation - 等待获得一个关系的锁。 + 等待获取关系上的锁。 - + extend 等待扩展一个关系。 - + frozenid - 等待升级 pg_database.datfrozenxid - 和 pg_database.datminmxid. + 等待更新 pg_database.datfrozenxidpg_database.datminmxid - + page 等待获取关系页上的锁。 - + tuple 等待获取元组上的锁。 - + transactionid 等待事务完成。 - + virtualxid 等待获取虚拟事务 ID 锁。 - + speculative token - 等待获取推测的插入锁。 + 等待获取推测插入锁。 - + object 等待获取非关系数据库对象上的锁。 - + userlock 等待获取用户锁。 - + advisory - 等待获得一个建议用户锁。 + 等待获取用户咨询锁。 - + BufferPin BufferPin 等待获取缓冲区上的钉住。 - + Activity ArchiverMain 在归档进程的主循环中等待。 - + AutoVacuumMain - 在自动清理启动过程的主循环中等待。 + 在自动清理启动进程的主循环中等待。 - + BgWriterHibernate - 在后台写入器中等待,休眠状态。 + 在后台写入器进程中休眠等待。 - + BgWriterMain - 在后台写入进程这一后台工作进程的主循环中等待。 + 在后台写入器进程(后台工作进程)的主循环中等待。 - + CheckpointerMain 在检查点进程的主循环中等待。 - + LogicalApplyMain 在逻辑应用进程的主循环中等待。 - + LogicalLauncherMain 在逻辑启动进程的主循环中等待。 - + PgStatMain 在统计收集器进程的主循环中等待。 - + RecoveryWalAll 在恢复期间等待来自流的 WAL。 - + RecoveryWalStream 在恢复期间,若所有来源(本地、归档或流)都没有可用的 WAL 数据,则在重新尝试获取 WAL 数据前等待。 - + SysLoggerMain 在 syslogger 进程的主循环中等待。 - + WalReceiverMain - 在WAL 接收进程的主循环中等待。 + 在 WAL 接收进程的主循环中等待。 - + WalSenderMain 在 WAL 发送进程的主循环中等待。 - + WalWriterMain - 在WAL写入进程的主循环中等待。 + 在 WAL 写入进程的主循环中等待。 - + Client ClientRead 等待从客户端读取数据。 - + ClientWrite 等待写入数据到客户端。 - + GSSOpenServer 在建立 GSSAPI 会话时等待读取客户端数据。 - + LibPQWalReceiverConnect - 在WAL 接收进程等待与远程服务器建立连接。 + 在 WAL 接收进程中等待与远程服务器建立连接。 - + LibPQWalReceiverReceive - 在WAL 接收进程中等待从远程服务器接收数据。 + 在 WAL 接收进程中等待从远程服务器接收数据。 - + SSLOpenServer 在尝试连接时等待SSL。 - + WalReceiverWaitStart 等待启动进程为流复制发送初始数据。 - + WalSenderWaitForWAL - 在 WAL 发送进程中等待 WAL 被刷新。 + 在 WAL 发送进程中等待 WAL 刷盘。 - + WalSenderWriteData 在 WAL 发送进程中处理 WAL 接收进程的回复时,等待任何活动。 - + Extension Extension 在扩展中等待。 - + IPC BgWorkerShutdown 等待后台工作进程关闭。 - + BgWorkerStartup 等待后台工作进程启动。 - + BtreePage - 正等待继续并行B-树扫描所需的页号变得可用。 + 等待继续并行 B-树扫描所需的页号变得可用。 - + CheckpointDone 等待检查点完成。 - + CheckpointStart 等待检查点开始。 - + ClogGroupUpdate 等待组领导者在事务结束时更新事务状态。 - + ExecuteGather 在执行Gather节点时等待子进程的活动。 - + Hash/Batch/Allocating - 等待一个选定的并行哈希参与者分配哈希表。 + 等待选出的 Parallel Hash 参与者分配哈希表。 - + Hash/Batch/Electing - 选举一个并行哈希参与者来分配哈希表。 + 选出负责分配哈希表的 Parallel Hash 参与者。 - + Hash/Batch/Loading - 等待其他并行哈希参与者完成哈希表的加载。 + 等待其他 Parallel Hash 参与者完成哈希表的加载。 - + Hash/Build/Allocating - 等待一个选定的并行哈希参与者分配初始哈希表。 + 等待选出的 Parallel Hash 参与者分配初始哈希表。 - + Hash/Build/Electing - 选举一个并行哈希参与者来分配初始哈希表。 + 选出负责分配初始哈希表的 Parallel Hash 参与者。 - + Hash/Build/HashingInner - 等待其他并行哈希参与者完成内部关系的散列。 + 等待其他 Parallel Hash 参与者完成对内层关系的哈希处理。 - + Hash/Build/HashingOuter - 等待其他Parallel 哈希参与者完成对外部关系的分区。 + 等待其他 Parallel Hash 参与者完成对外层关系的分区。 - + Hash/GrowBatches/Allocating - 等待选定的并行哈希参与者分配更多批处理。 + 等待选出的 Parallel Hash 参与者分配更多批次。 - + Hash/GrowBatches/Deciding - 选举一个并行哈希参与者来决定后续批次增长。 + 选出负责决定后续批次增长的 Parallel Hash 参与者。 - + Hash/GrowBatches/Electing - 选举一个并行哈希参与者来分配更多批次。 + 选出负责分配更多批次的 Parallel Hash 参与者。 - + Hash/GrowBatches/Finishing - 等待当选的平行散列参与者决定未来的批量增长。 + 等待选出的 Parallel Hash 参与者决定后续的批次增长。 - + Hash/GrowBatches/Repartitioning - 等待其他并行哈希参与者完成重新分区。 + 等待其他 Parallel Hash 参与者完成重新分区。 - + Hash/GrowBuckets/Allocating - 等待选定的并行哈希参与者完成更多bucket的分配。 + 等待选出的 Parallel Hash 参与者完成更多桶的分配。 - + Hash/GrowBuckets/Electing - 选举一个并行哈希参与者来分配更多桶。 + 选出负责分配更多桶的 Parallel Hash 参与者。 - + Hash/GrowBuckets/Reinserting - 等待其他Parallel 哈希参与者完成将元组插入到新buckets中。 + 等待其他 Parallel Hash 参与者完成向新桶插入元组。 - + LogicalSyncData 等待逻辑复制远程服务器为初始表同步发送数据。 - + LogicalSyncStateChange 等待逻辑复制远程服务器改变状态。 - + MessageQueueInternal 等待其他进程附加到共享消息队列。 - + MessageQueuePutMessage 等待将协议消息写入共享消息队列。 - + MessageQueueReceive 等待从共享消息队列接收字节。 - + MessageQueueSend 等待将字节发送到共享消息队列。 - + ParallelBitmapScan - 等待并行位图扫描被初始化。 + 等待并行位图扫描完成初始化。 - + ParallelCreateIndexScan - 等待并行CREATE INDEX 工作进程完成堆扫描。 + 等待并行 CREATE INDEX 工作进程完成堆扫描。 - + ParallelFinish - 等待并行工作人员完成计算。 + 等待并行工作进程完成计算。 - + ProcArrayGroupUpdate 等待组领导者在事务结束时清除事务 ID。 - + Promote 等待备库提升。 - + ReplicationOriginDrop 等待复制源变为非活动状态,以便将其删除。 - + ReplicationSlotDrop 等待复制槽变为非活动状态,以便将其删除。 - + SafeSnapshot 等待READ ONLY DEFERRABLE事务的快照。 - + SyncRep 在同步复制期间等待远程服务器的确认。 - + Timeout BaseBackupThrottle - 当有限流活动时在基础备份期间等待。 + 在基础备份期间因限流而等待。 - + PgSleep 调用pg_sleep的进程正在等待。 - + RecoveryApplyDelay 在恢复期间,由于应用 WAL 被延迟而等待。 - + RegisterSyncRequest - 在发送同步请求到检查点程序时等待,因为请求队列已满。 + 向检查点进程发送同步请求时,因请求队列已满而等待。 - + IO BufFileRead 等待从缓冲文件中读取。 - + BufFileWrite 等待对缓冲文件的写入。 - + ControlFileRead 等待读取控制文件。 - + ControlFileSync - 等待控制文件写入持久存储。 + 等待控制文件同步到持久存储。 - + ControlFileSyncUpdate - 等待控制文件的更新写入持久存储。 + 等待对控制文件的更新同步到持久存储。 - + ControlFileWrite 等待写入控制文件。 - + ControlFileWriteUpdate 等待写入以更新控制文件。 - + CopyFileRead 在文件复制操作期间等待读取。 - + CopyFileWrite - 在文件拷贝操作期间等待写入。 + 在文件复制操作期间等待写入。 - + DataFileExtend 等待关系数据文件被扩展。 - + DataFileFlush - 等待关系数据文件达到持久存储。 + 等待关系数据文件同步到持久存储。 - + DataFileImmediateSync - 等待关系数据文件到持久存储的立即同步。 + 等待关系数据文件立即同步到持久存储。 - + DataFilePrefetch 等待关系数据文件的异步预取。 - + DataFileRead 等待对关系数据文件的读取。 - + DataFileSync - 等待对关系数据文件的更改达到持久存储。 + 等待对关系数据文件的更改同步到持久存储。 - + DataFileTruncate 等待关系数据文件被截断。 - + DataFileWrite 等待对关系数据文件的写入。 - + DSMFillZeroWrite - 等待将零字节写入动态共享内存的后备文件。 + 等待向动态共享内存的后备文件写入值为零的字节。 - + LockFileAddToDataDirRead 在向数据目录锁文件中添加一行时等待读取。 - + LockFileAddToDataDirSync - 等待数据到达持久存储,同时向数据目录锁文件添加一行。 + 在向数据目录锁文件中添加一行时,等待数据同步到持久存储。 - + LockFileAddToDataDirWrite 在向数据目录锁文件中添加一行时等待写操作。 - + LockFileCreateRead 创建数据目录锁文件时等待读取。 - + LockFileCreateSync - 在创建数据目录锁文件时等待数据到达持久存储。 + 在创建数据目录锁文件时,等待数据同步到持久存储。 - + LockFileCreateWrite 在创建数据目录锁文件时等待写操作。 - + LockFileReCheckDataDirRead 在重新检查数据目录锁文件期间等待读取。 - + LogicalRewriteCheckpointSync - 等待逻辑重写映射到在检查点到达持久存储。 + 在检查点期间等待逻辑重写映射同步到持久存储。 - + LogicalRewriteMappingSync - 在逻辑重写期间等待映射数据到达持久存储 + 在逻辑重写期间等待映射数据同步到持久存储。 - + LogicalRewriteMappingWrite 在逻辑重写期间等待映射数据的写入。 - + LogicalRewriteSync - 等待逻辑重写映射到达持久存储。 + 等待逻辑重写映射同步到持久存储。 - + LogicalRewriteTruncate - 等待在逻辑重写期间截断映射数据。 + 在逻辑重写期间等待截断映射数据。 - + LogicalRewriteWrite 等待逻辑重写映射的写入。 - + RelationMapRead 等待关系映射文件的读取。 - + RelationMapSync - 等待关系映射文件到达持久存储。 + 等待关系映射文件同步到持久存储。 - + RelationMapWrite 等待对关系映射文件的写入。 - + ReorderBufferRead - 在重新排序缓冲区管理期间等待读取。 + 在重排序缓冲区管理期间等待读取。 - + ReorderBufferWrite - 在重新排序缓冲区管理期间等待写操作。 + 在重排序缓冲区管理期间等待写入。 - + ReorderLogicalMappingRead - 在重新排序缓冲区管理期间等待读取逻辑映射。 + 在重排序缓冲区管理期间等待读取逻辑映射。 - + ReplicationSlotRead 等待从复制槽控制文件读取。 - + ReplicationSlotRestoreSync - 等待复制槽控制文件到达持久存储,同时将其恢复到内存中。 + 在将复制槽控制文件恢复到内存期间,等待该文件同步到持久存储。 - + ReplicationSlotSync - 等待复制槽控制文件到达持久存储。 + 等待复制槽控制文件同步到持久存储。 - + ReplicationSlotWrite 等待对复制槽控制文件的写入。 - + SLRUFlushSync - 在检查点或数据库关闭期间等待SLRU数据到达持久存储。 + 在检查点或数据库关闭期间,等待 SLRU 数据同步到持久存储。 - + SLRURead 等待读取SLRU页面。 - + SLRUSync - 在写页面后等待SLRU数据到达持久存储。 + 在页面写入后等待 SLRU 数据同步到持久存储。 - + SLRUWrite 等待SLRU页面的写入。 - + SnapbuildRead - 等待读取序列化的历史目录快照。 + 等待读取序列化的历史系统目录快照。 - + SnapbuildSync - 等待序列化历史目录快照到达持久存储。 + 等待序列化的历史系统目录快照同步到持久存储。 - + SnapbuildWrite - 等待串行历史目录快照的写入。 + 等待写入序列化的历史系统目录快照。 - + TimelineHistoryFileSync - 等待通过流复制接收的时间线历史文件到达持久存储。 + 等待通过流复制接收的时间线历史文件同步到持久存储。 - + TimelineHistoryFileWrite 等待通过流复制接收的时间线历史文件的写入。 - + TimelineHistoryRead 等待读取时间线历史文件。 - + TimelineHistorySync - 等待新创建的时间线历史文件到达持久存储。 + 等待新创建的时间线历史文件同步到持久存储。 - + TimelineHistoryWrite 等待写入新创建的时间线历史文件。 - + TwophaseFileRead 等待读取两阶段状态文件。 - + TwophaseFileSync - 等待两阶段状态文件到达持久存储。 + 等待两阶段状态文件同步到持久存储。 - + TwophaseFileWrite 等待对两阶段状态文件的写入。 - + WALBootstrapSync - 在引导过程中等待WAL达到持久存储。 + 在引导过程中等待 WAL 同步到持久存储。 - + WALBootstrapWrite 在引导过程中等待WAL页面的写入。 - + WALCopyRead 通过复制一个已有WAL段来创建一个新的WAL段时等待读取。 - + WALCopySync - 等待通过复制已有 WAL 段创建的新 WAL 段写入持久存储。 + 等待通过复制现有 WAL 段创建的新 WAL 段同步到持久存储。 - + WALCopyWrite 通过复制一个已有WAL段来创建一个新的WAL段时等待写入。 - + WALInitSync - 等待一个新初始化的WAL文件到持久存储。 + 等待新初始化的 WAL 文件同步到持久存储。 - + WALInitWrite 在初始化一个新的WAL文件时等待写入。 - + WALRead 等待WAL文件的读取。 - + WALSenderTimelineHistoryRead 在 WAL 发送进程执行时间线命令期间,等待读取时间线历史文件。 - + WALSync - 等待WAL文件到达持久存储。 + 等待 WAL 文件同步到持久存储。 - + WALSyncMethodAssign - 在指派 WAL 同步方法时等待数据写入持久存储。 + 在设置 WAL 同步方法时,等待数据同步到持久存储。 - + WALWrite - 等待写入WAL文件。 + 等待写入 WAL 文件。 @@ -1531,7 +1518,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i inet 连接到这个 WAL 发送进程的客户端的 IP 地址。 - 如果这个域为空,它表示该客户端通过服务器机器上的一个Unix 套接字连接。 + 如果这个字段为空值,它表示该客户端通过服务器机器上的一个Unix 套接字连接。 @@ -1566,34 +1553,37 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i state text - 当前 WAL 发送进程的状态。可能的值为: + + 当前的 WAL 发送进程状态。 + 可能的值是: + - startup: 此 WAL 发送进程正在启动。 + startup: 此 WAL 发送进程正在启动。 - catchup: 与此 WAL 发送进程连接的备库正在赶上主库。 + catchup: 与此 WAL 发送进程连接的备库正在赶上主库。 - streaming: 在其连接的备库赶上主库之后,此 WAL 发送进程正在流式传输更改。 + streaming: 在其连接的备库赶上主库之后,此 WAL 发送进程正在流式传输更改。 - backup: 此 WAL 发送进程正在发送一个备份。 + backup: 此 WAL 发送进程正在发送一个备份。 - stopping: 此 WAL 发送进程正在停止。 + stopping: 此 WAL 发送进程正在停止。 - + sent_lsn @@ -1626,26 +1616,17 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i write_lag interval - - 从本地刷写最近的 WAL,到收到该备库已写入该 WAL(但尚未刷盘或应用)的通知之间经过的时间。 - 如果该服务器被配置为同步备库,可用此值衡量在提交时 synchronous_commit 级别 remote_write 所导致的延迟。 - + 从在本地将最近的 WAL 刷盘,到收到该备库已写入该 WAL(但尚未刷盘或应用)的通知之间经过的时间。如果该服务器被配置为同步备库,可用此值衡量在提交时synchronous_commit级别remote_write所导致的延迟。 flush_lag interval - - 从本地刷写最近的 WAL,到收到该备库已写入并刷写该 WAL(但尚未应用)的通知之间经过的时间。 - 如果该服务器被配置为同步备库,可用此值衡量在提交时 synchronous_commit 级别 on 所导致的延迟。 - + 从在本地将最近的 WAL 刷盘,到收到该备库已写入该 WAL 并将其刷盘(但尚未应用)的通知之间经过的时间。如果该服务器被配置为同步备库,可用此值衡量在提交时synchronous_commit级别on所导致的延迟。 replay_lag interval - - 从本地刷写最近的 WAL,到收到该备库已写入、刷写并应用该 WAL 的通知之间经过的时间。 - 如果该服务器被配置为同步备库,可用此值衡量在提交时 synchronous_commit 级别 remote_apply 所导致的延迟。 - + 从在本地将最近的 WAL 刷盘,到收到该备库已写入该 WAL、将其刷盘并应用的通知之间经过的时间。如果该服务器被配置为同步备库,可用此值衡量在提交时synchronous_commit级别remote_apply所导致的延迟。 sync_priority @@ -1657,29 +1638,32 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i sync_state text - 此备库的同步状态。可能的值为: + + 该备库的同步状态。 + 可能的值是: + - async: 该备库是异步的。 + async: 该备库是异步的。 - potential: 该备库当前是异步的,但在当前同步备库失效时可能变为同步的。 + potential: 该备库当前是异步的,但在当前某个同步备库失效时可能变为同步的。 - sync: 该备库是同步的。 + sync: 该备库是同步的。 - quorum: 该备库被作为法定人数同步复制候选备库。 + quorum: 该备库被作为法定人数同步复制候选备库。 - + reply_time @@ -1698,16 +1682,16 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i - pg_stat_replication视图中报告的滞后时间,是最近的 WAL 被写入、刷写和重放,以及发送端获知这些操作完成所花费时间的度量。如果远程服务器被配置为同步备库,这些时间表示各个同步提交级别带来或可能带来的提交延迟。对于异步备库,replay_lag列是最近事务对查询变得可见所需延迟时间的近似值。如果备库已经完全追上发送服务器且没有新的 WAL 活动,系统会在短时间内继续显示最近测得的滞后时间,随后显示为 NULL。 + pg_stat_replication视图中报告的滞后时间,是最近的 WAL 被写入、刷盘和重放,以及发送端获知这些操作完成所花费时间的度量。如果远程服务器被配置为同步备库,这些时间表示各个同步提交级别带来或可能带来的提交延迟。对于异步备库,replay_lag列是最近事务对查询变得可见所需延迟时间的近似值。如果备库已经完全追上发送服务器且没有新的 WAL 活动,系统会在短时间内继续显示最近测得的滞后时间,随后显示为空值。 - 对于物理复制,滞后时间会自动测量。逻辑解码插件可以选择发出跟踪消息;如果没有这样做,跟踪机制会将滞后显示为 NULL。 + 对于物理复制,滞后时间会自动测量。逻辑解码插件可以选择发出跟踪消息;如果没有这样做,跟踪机制会将滞后显示为空值。 - 报告出的滞后时间并不是根据当前重放速率预测该备库还需多久才能追上发送服务器。在持续生成新 WAL 时,那样的系统可能会显示相近的时间;但当发送端空闲时,就会显示不同的值。特别是当备库已经完全追上时,pg_stat_replication显示的是写入、刷写和重放最近报告的 WAL 位置所花费的时间,而不是某些用户可能预期的零。这样做符合为最近写事务测量同步提交和事务可见性延迟的目的。为减少用户因预期另一种滞后模型而产生的混淆,在一个已完全重放且处于空闲状态的系统上,lag 列会在较短时间后恢复为 NULL。监控系统应自行决定将这种情况表示为缺失数据、零,还是继续显示最近一次已知值。 + 报告出的滞后时间并不是根据当前重放速率预测该备库还需多久才能追上发送服务器。在持续生成新 WAL 时,那样的系统可能会显示相近的时间;但当发送端空闲时,就会显示不同的值。特别是当备库已经完全追上时,pg_stat_replication显示的是写入、刷盘和重放最近报告的 WAL 位置所花费的时间,而不是某些用户可能预期的零。这样做符合为最近写事务测量同步提交和事务可见性延迟的目的。为减少用户因预期另一种滞后模型而产生的混淆,在一个已完全重放且处于空闲状态的系统上,滞后列会在较短时间后恢复为空值。监控系统应自行决定将这种情况表示为缺失数据、零,还是继续显示最近一次已知值。 @@ -1727,42 +1711,42 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i pid integer - WAL 接收进程的进程ID + WAL 接收进程的进程 ID status text - WAL接收进程的活动状态 + WAL 接收进程的活动状态 receive_start_lsn pg_lsn - WAL 接收进程启动时使用的第一个写前日志位置 + WAL 接收进程启动时使用的第一个预写式日志位置 receive_start_tli integer - WAL 接收进程启动时使用的第一个时间线数字 + WAL 接收进程启动时使用的第一个时间线编号 received_lsn pg_lsn - 已经接收并刷入到磁盘的最后一个预写式日志位置,该字段的初始值是启动WAL 接收进程时使用的第一个日志位置 + 已经接收并刷入到磁盘的最后一个预写式日志位置,该字段的初始值是启动 WAL 接收进程时使用的第一个日志位置 received_tli integer - 接收并刷入到磁盘的最后一个预写式日志位置的时间线数字,该字段的初始值为启动WAL 接收进程时使用的第一个日志位置的时间线数字 + 接收并刷入到磁盘的最后一个预写式日志位置的时间线编号,该字段的初始值为启动 WAL 接收进程时使用的第一个日志位置的时间线编号 @@ -1797,38 +1781,36 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i slot_name text - 这个WAL 接收进程使用的复制槽的名称 + 这个 WAL 接收进程使用的复制槽的名称 sender_host text - 这个WAL 接收进程连接到的PostgreSQL实例的主机。 - 这可以是主机名、IP地址,或者目录路径,如果连接是通过Unix套接字进行的。(路径的情况可以区分,因为它总是以/开头的绝对路径。) + 这个 WAL 接收进程连接到的PostgreSQL实例的主机。 + 这可以是主机名、IP地址,或者目录路径,如果连接是通过Unix套接字进行的。(路径的情况可以区分,因为它总是以/开头的绝对路径。) sender_port integer - 这个WAL 接收进程连接的PostgreSQL实例的端口号。 + 这个 WAL 接收进程连接的PostgreSQL实例的端口号。 conninfo text - 这个WAL 接收进程使用的连接字符串,对安全敏感的字段进行了模糊处理。 + 这个 WAL 接收进程使用的连接字符串,对安全敏感的字段进行了模糊处理。
- - pg_stat_wal_receiver事务只包含一行,它显示了从 WAL 接收进程所连接的服务器得到的有关该接收进程的统计信息。 - + pg_stat_wal_receiver视图只包含一行,显示 WAL 接收进程从其所连接服务器接收数据的统计信息。 <structname>pg_stat_subscription</structname> 视图 @@ -1842,70 +1824,80 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i - + + subid oid 订阅的OID - + + subname text 订阅的名称 - + + pid integer 订阅工作进程的进程 ID - + + relid Oid - 该工作进程正在同步的关系的 OID;主应用工作进程则为 NULL + 该工作进程正在同步的关系的 OID;主应用工作进程则为空值 - + + received_lsn pg_lsn - 接收到的最后一个预写式日志位置,该字段的初始值为0 + 接收到的最后一个预写式日志位置,该字段的初始值为 0 - + + last_msg_send_time timestamp with time zone 从源 WAL 发送进程收到的最后一条消息的发送时间 - + + last_msg_receipt_time timestamp with time zone 从源 WAL 发送进程收到的最后一条消息的接收时间 - + + latest_end_lsn pg_lsn 向源 WAL 发送进程报告的最后一个预写式日志位置 - + + latest_end_time timestamp with time zone - 向 WAL 发送进程报告最后一个预写式日志位置的时间 + 向源 WAL 发送进程报告最后一个预写式日志位置的时间 - + +
@@ -1941,49 +1933,49 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i version text - 使用SSL的版本,如果此连接上没有使用SSL则为NULL + 使用SSL的版本,如果此连接上没有使用SSL则为空值 cipher text - 正在使用的SSL密码的名称,如果此连接上没有使用SSL则为NULL + 正在使用的SSL 密码套件的名称,如果此连接上没有使用SSL则为空值 bits integer - 使用的加密算法中的位数,如果此连接上没有使用SSL则为NULL + 使用的加密算法中的位数,如果此连接上没有使用SSL则为空值 compression boolean - 使用 SSL 压缩时为真,否则为假;如果此连接未使用 SSL,则为 NULL + 使用 SSL 压缩时为真,否则为假;如果此连接未使用 SSL,则为空值 client_dn text - 区别名称(DN,Distinguished Name)字段与使用的客户端证书,如果没有提供客户端证书或在此连接上没有使用SSL,则为NULL。 - 如果DN字段长于NAMEDATALEN(标准构建中为64个字符),则该字段将被截断。 + 所用客户端证书中的区别名称(DN,Distinguished Name)字段,如果没有提供客户端证书或在此连接上没有使用SSL,则为空值。 + 如果DN字段长于NAMEDATALEN(标准构建中为64个字符),则该字段将被截断。 client_serial numeric - 客户端证书的序列号,如果没有提供客户端证书或在此连接上没有使用SSL,则为NULL。 - 证书序列号和证书颁发者的组合唯一标识一个证书(除非颁发者错误地重用序列号)。 + 客户端证书的序列号,如果没有提供客户端证书或在此连接上没有使用SSL,则为空值。 + 证书序列号和证书颁发者的组合唯一标识一个证书(除非颁发者错误地重用序列号)。 issuer_dn text - 客户端证书颁发者的区别名称(DN,Distinguished Name),如果没有提供客户端证书或在此连接上没有使用SSL,则为NULL。该字段像client_dn一样被截断。 + 客户端证书颁发者的区别名称(DN,Distinguished Name),如果没有提供客户端证书或在此连接上没有使用SSL,则为空值。该字段像client_dn一样被截断。 @@ -2025,8 +2017,8 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i principal text - 用于验证此连接的主体,如果未使用GSSAPI对此连接进行认证,则为NULL。 - 如果主体长度超过NAMEDATALEN(标准构建中为64个字符),则该字段被截断。 + 用于认证此连接的主体,如果未使用GSSAPI对此连接进行认证,则为空值。 + 如果主体长度超过NAMEDATALEN(标准构建中为64个字符),则该字段被截断。 @@ -2042,7 +2034,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i pg_stat_gssapi视图将包含每一个后端一个行,显示该连接上的GSSAPI使用情况。 - 它可以加入到pg_stat_activitypg_stat_replication上的pid列,获取更多关于连接的详细信息。 + 可以通过pid列将它与pg_stat_activitypg_stat_replication连接,获取更多关于连接的详细信息。 @@ -2104,9 +2096,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i stats_reset timestamp with time zone - - 这些统计数据最后一次重置的时间 - + 这些统计信息上次被重置的时间 @@ -2176,7 +2166,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i buffers_backend_fsync bigint - 后端必须自行执行fsync调用的次数(通常即使后端自行写入,也由后台写入进程处理这些调用) + 后端必须自行执行fsync调用的次数(通常即使后端自行写入,也由后台写入器处理这些调用) buffers_alloc @@ -2188,16 +2178,14 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i stats_reset timestamp with time zone - - 这些统计信息上次被重置的时间 - + 这些统计信息上次被重置的时间 - pg_stat_bgwriter 视图始终只有一行,包含有关集簇后台写入器的数据。 + pg_stat_bgwriter 视图始终只有一行,包含整个集簇的全局数据。 @@ -2212,21 +2200,24 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i - + + datid oid 该数据库的OID,属于共享关系的对象为0 - + + datname name 这个数据库的名称,或者共享对象为NULL - + + numbackends integer @@ -2234,129 +2225,148 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i 这是该视图中唯一返回反映当前状态的值的列;所有其他列返回的都是自上次重置以来累积的值。 - + + xact_commit bigint 此数据库中已提交的事务数 - + + xact_rollback bigint 该数据库中已回滚的事务数 - + + blks_read bigint 在该数据库中读取的磁盘块数 - + + blks_hit bigint 在缓冲区缓存中发现磁盘块、因而无需读取的次数(这里只统计 PostgreSQL 缓冲区缓存中的命中,不包括操作系统文件系统缓存中的命中) - + + tup_returned bigint - 由顺序扫描获取的活动行数和由索引扫描返回的索引条目数 + 此数据库中的查询返回的行数 - + + tup_fetched bigint - 该数据库中由索引扫描检索的活动行数 + 此数据库中的查询获取的行数 - + + tup_inserted bigint 查询在该数据库中插入的行数 - + + tup_updated bigint 这个数据库中查询更新的行数 - + + tup_deleted bigint 这个数据库中被查询删除的行数 - + + conflicts bigint 由于与此数据库中的恢复冲突而被取消的查询数。(冲突只会发生在备库上;请参阅。) - + + temp_files bigint 这个数据库中查询创建的临时文件的数量。所有临时文件都将被计数,而不顾及临时文件为什么被创建(例如,排序或散列),也不考虑设置。 - + + temp_bytes bigint 这个数据库中的查询写入临时文件的数据总量。所有临时文件都将被计数,而不考虑临时文件为什么被创建,也不考虑设置。 - + + deadlocks bigint 在此数据库中检测到的死锁数 - + + checksum_failures bigint 在此数据库(或共享对象)中检测到的数据页校验码失败数,如果没有启用数据校验码则为NULL。 - + + checksum_last_failure timestamp with time zone 在此数据库(或共享对象)中检测到最后一个数据页校验码失败的时间,如果没有启用数据校验码则为NULL。 - + + blk_read_time double precision 此数据库的后端读取数据文件块所花费的时间,单位为毫秒 - + + blk_write_time double precision 此数据库的后端写入数据文件块所花费的时间,单位为毫秒 - + + stats_reset timestamp with time zone 这些统计数据最后一次重置的时间 - + +
@@ -2413,7 +2423,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i confl_bufferpin bigint - 此数据库中由于固定缓冲区而被取消的查询数 + 此数据库中由于缓冲区被钉住而被取消的查询数
@@ -2473,7 +2483,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i seq_tup_read bigint - 连续扫描获取的实时行数 + 顺序扫描获取的存活行数 @@ -2487,7 +2497,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i idx_tup_fetch bigint - 索引扫描获取的实时行数 + 索引扫描获取的存活行数 @@ -2515,7 +2525,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i n_tup_hot_upd bigint - HOT更新的行数(即,不需要单独的索引更新) + HOT 更新的行数(即不需要单独更新索引) @@ -2543,7 +2553,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i last_vacuum timestamp with time zone - 最后一次手动清理这个表(不包括VACUUM FULL) + 最后一次手动清理这个表的时间(不包括VACUUM FULL @@ -2557,21 +2567,21 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i last_analyze timestamp with time zone - 上一次手动分析这个表 + 上一次手动分析这个表的时间 last_autoanalyze timestamp with time zone - 自动清理守护进程最后一次分析这个表 + 自动清理守护进程最后一次分析这个表的时间 vacuum_count bigint - 这个表被手动清理的次数(VACUUM FULL不计数) + 这个表被手动清理的次数(VACUUM FULL不计数) @@ -2669,7 +2679,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i idx_tup_fetch bigint - 使用此索引进行简单索引扫描获取的活动表行数 + 使用此索引进行简单索引扫描获取的存活表行数 @@ -2681,13 +2691,13 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i
- 索引可以被简单索引扫描、位图索引扫描以及优化器使用。在一次位图扫描中,多个索引的输出可以被通过 AND 或 OR 规则组合,因此当使用一次位图扫描时难以将取得的个体堆行与特定的索引关联起来。因此,一次位图扫描会增加它使用的索引的pg_stat_all_indexes.idx_tup_read计数,并且为每个表增加pg_stat_all_tables.idx_tup_fetch计数,但是它不影响pg_stat_all_indexes.idx_tup_fetch。如果所提供的常量值不在优化器统计信息记录的范围之内,优化器也会访问索引来检查,因为优化器统计信息可能已经“不新鲜”了。 + 索引可以被简单索引扫描、位图索引扫描以及优化器使用。在一次位图扫描中,多个索引的输出可以被通过 AND 或 OR 规则组合,因此当使用一次位图扫描时难以将取得的个体堆行与特定的索引关联起来。因此,一次位图扫描会增加它使用的索引的pg_stat_all_indexes.idx_tup_read计数,并且为该表增加pg_stat_all_tables.idx_tup_fetch计数,但是它不影响pg_stat_all_indexes.idx_tup_fetch。如果所提供的常量值不在优化器统计信息记录的范围之内,优化器也会访问索引来检查,因为优化器统计信息可能已经过时。 - 即使不用位图扫描,idx_tup_readidx_tup_fetch计数也可能不同,因为idx_tup_read统计从该索引取得的索引项而idx_tup_fetch统计从表取得的活着的行。如果使用该索引取得了任何死亡行或还未提交的行,或者如果通过一次只用索引扫描的方式避免了任何堆获取,后者将较小。 + 即使不用位图扫描,idx_tup_readidx_tup_fetch计数也可能不同,因为idx_tup_read统计从该索引取得的索引项而idx_tup_fetch统计从表取得的存活行。如果使用该索引取得了任何死亡行或还未提交的行,或者如果通过一次仅索引扫描的方式避免了任何堆获取,后者将较小。 @@ -2756,28 +2766,28 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i toast_blks_read bigint - 从这个表的TOAST表中读取的磁盘块的数量(如果有的话) + 从这个表的TOAST表中读取的磁盘块的数量(如果有的话) toast_blks_hit bigint - 这个表的TOAST表中的缓冲区命中数(如果有的话) + 这个表的TOAST表中的缓冲区命中数(如果有的话) tidx_blks_read bigint - 从这个表的TOAST表索引中读取的磁盘块的数量(如果有的话) + 从这个表的TOAST表索引中读取的磁盘块的数量(如果有的话) tidx_blks_hit bigint - 这个表的TOAST表索引中的缓冲区命中数(如果有的话) + 这个表的TOAST表索引中的缓冲区命中数(如果有的话) @@ -3206,23 +3216,23 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, 查看锁 - lock - monitoring + + 监控 - 监控数据库活动的另外一个有用的工具是pg_locks系统表。这样就允许数据库管理员查看在锁管理器里面未解决的锁的信息。例如,这个功能可以被用于: + 监控数据库活动的另外一个有用的工具是pg_locks系统表。这样就允许数据库管理员查看锁管理器中当前存在的锁的信息。例如,这个功能可以被用于: - 查看当前所有未解决的锁、在一个特定数据库中的关系上所有的锁、在一个特定关系上所有的锁,或者由一个特定PostgreSQL会话持有的所有的锁。 + 查看当前存在的所有锁、在一个特定数据库中的关系上所有的锁、在一个特定关系上所有的锁,或者由一个特定PostgreSQL会话持有的所有的锁。 - 判断当前数据库中带有最多未授予锁的关系(它很可能是数据库客户端的竞争源)。 + 判断当前数据库中带有最多未授予锁的关系(它可能是数据库客户端之间的竞争来源)。 @@ -3301,8 +3311,8 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, command text - 在运行的命令: CREATE INDEX,CREATE INDEX CONCURRENTLY, - REINDEX, 或 REINDEX CONCURRENTLY. + 在运行的命令: CREATE INDEXCREATE INDEX CONCURRENTLY、 + REINDEXREINDEX CONCURRENTLY @@ -3315,36 +3325,30 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, lockers_total bigint - - 在适用的情况下,需要等待的储物柜总数 - + 在适用的情况下,需要等待的持锁进程总数。 lockers_done bigint - - 已经等待的储物柜数量。 - + 已完成等待的持锁进程数量。 current_locker_pid bigint - - 目前正在等待的储物柜的进程ID。 - + 当前正在等待的持锁进程的进程 ID。 blocks_total bigint - 本阶段要处理的区块总数。 + 本阶段要处理的块总数。 blocks_done bigint - 当前阶段已经处理的区块数量。 + 当前阶段已经处理的块数量。 @@ -3382,7 +3386,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - CREATE INDEX 的阶段 + CREATE INDEX 阶段 @@ -3401,19 +3405,19 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, waiting for writers before build - CREATE INDEX CONCURRENTLYREINDEX CONCURRENTLY正在等待有可能看到表的写锁的事务完成。 当不在并发模式时,这个阶段会被跳过。lockers_totallockers_donecurrent_locker_pid 列包含了这个阶段的进度信息。 + CREATE INDEX CONCURRENTLYREINDEX CONCURRENTLY正在等待持有写锁且可能看到该表的事务结束。 当不在并发模式时,这个阶段会被跳过。lockers_totallockers_donecurrent_locker_pid 列包含了这个阶段的进度信息。 building index - 索引是由访问方法专用代码建立的。 在这一阶段,支持进度报告的访问方法填写自己的进度数据,子阶段在这一栏中表示。 通常情况下,blocks_totalblocks_done将包含进度数据,也可能包含tuples_totaltuples_done。 + 索引是由访问方法专用代码建立的。 在这一阶段,支持进度报告的访问方法填写自己的进度数据,子阶段在这一栏中表示。 通常情况下,blocks_totalblocks_done将包含进度数据,tuples_totaltuples_done也可能包含进度数据。 waiting for writers before validation - CREATE INDEX CONCURRENTLYREINDEX CONCURRENTLY正在等待有可能写入表的事务完成写锁的事务。当不在并发模式时,这个阶段会被跳过。lockers_totallockers_donecurrent_locker_pid 列包含了这个阶段的进度信息。 + CREATE INDEX CONCURRENTLYREINDEX CONCURRENTLY正在等待持有写锁且可能写入该表的事务结束。当不在并发模式时,这个阶段会被跳过。lockers_totallockers_donecurrent_locker_pid 列包含了这个阶段的进度信息。 @@ -3502,21 +3506,21 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, relid oid - 被vacuum的表的OID。 + 正在清理的表的OID。 phase text - vacuum的当前处理阶段。参见 。 + 清理的当前处理阶段。参见 heap_blks_total bigint - 该表中堆块的总数。这个数字在扫描开始时报告,之后增加的块将不会(并且不需要)被这个VACUUM访问。 + 该表中堆块的总数。这个数字以扫描开始时的数量为准,之后增加的块将不会(并且不需要)被这个VACUUM访问。 @@ -3547,14 +3551,14 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, max_dead_tuples bigint - 在需要执行索引清理周期之前可存储的死亡元组数据量,取决于。 + 在需要执行索引清理周期之前可存储的死亡元组数量,取决于 num_dead_tuples bigint - 自上一个索引清理周期以来收集到的死亡元组数据量。 + 自上一个索引清理周期以来收集到的死亡元组数量。 @@ -3562,7 +3566,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid,
- VACUUM的阶段 + VACUUM 阶段 @@ -3582,33 +3586,29 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, scanning heap - VACUUM正在扫描堆。如果需要,它将会对每个页面进行修建以及碎片整理,并且可能会执行冻结动作。heap_blks_scanned列可以用来监控扫描的进度。 + VACUUM正在扫描堆。如果需要,它将会对每个页面进行剪枝以及碎片整理,并且可能会执行冻结动作。heap_blks_scanned列可以用来监控扫描的进度。 vacuuming indexes - - VACUUM当前正在清理索引。 - 如果一个表拥有索引,那么每次清理时这个阶段会在堆扫描完成后至少发生一次。 - 如果不足以存放找到的死亡元组(或者, 在autovacuum情况下,如果设置了) ,则每次清理时会多次清理索引。 - + VACUUM当前正在清理索引。如果表有索引,每次清理都会在堆扫描完成后至少执行一次此阶段。如果(或者,对于自动清理,已设置的)不足以存储找到的死亡元组数量,则每次清理可能多次执行此阶段。 vacuuming heap - VACUUM当前正在清理堆。清理堆与扫描堆不是同一个概念,清理堆发生在每一次清理索引的实例之后。如果heap_blks_scanned小于heap_blks_total,系统将在这个阶段完成之后回去扫描堆;否则,系统将在这个阶段完成后开始清理索引。 + VACUUM当前正在清理堆。清理堆与扫描堆不是同一个概念,清理堆发生在每次索引清理之后。如果heap_blks_scanned小于heap_blks_total,系统将在这个阶段完成之后回去扫描堆;否则,系统将在这个阶段完成后开始索引收尾清理。 cleaning up indexes - VACUUM当前正在清除索引。这个阶段发生在堆被完全扫描并且对堆和索引的所有清理都已经完成以后。 + VACUUM当前正在进行索引收尾清理。这个阶段发生在堆被完全扫描并且对堆和索引的所有清理都已经完成以后。 truncating heap - VACUUM正在截断堆,以便把关系尾部的空页面返还给操作系统。这个阶段发生在清除完索引之后。 + VACUUM正在截断堆,以便把关系尾部的空页面返还给操作系统。这个阶段发生在索引收尾清理完成之后。 @@ -3629,7 +3629,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, CLUSTER 进度报告 - 每当CLUSTERVACUUM FULL运行时,pg_stat_progress_cluster视图将包含当前正在运行的每一个后台的记录。下面的表格描述了将被报告的信息,并提供了关于如何解释这些信息的信息。 + 每当CLUSTERVACUUM FULL运行时,pg_stat_progress_cluster视图将为每个当前正在运行这两种命令之一的后端包含一行。下面的表格描述了将被报告的信息,并提供了关于如何解释这些信息的信息。
@@ -3669,7 +3669,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, relidoid - 被集群的表的OID。 + 正在聚簇的表的OID。 @@ -3706,15 +3706,15 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, heap_tuples_written bigint - 写入的堆元组的数量。这个计数器只有在阶段为seq scanning heap,index scanning heap - 或 writing new heap时才会前进。 + 写入的堆元组的数量。这个计数器只有在阶段为seq scanning heapindex scanning heap + 或 writing new heap时才会递增。 heap_blks_total bigint - 表中的堆块总数。 这个数字是在seq scanning heap的开始时报告的。 + 表中的堆块总数。 这个数字以seq scanning heap开始时的数量为准。 @@ -3750,8 +3750,8 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, initializing - 该命令准备开始扫描堆栈。 这个阶段预计会非常短暂。 - + 命令正在准备开始扫描堆。这个阶段预计会非常短暂。 + seq scanning heap @@ -3774,7 +3774,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, writing new heap - CLUSTER目前正在编写新的堆。 + CLUSTER目前正在写入新的堆。 @@ -3823,7 +3823,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - 动态追踪的编译 + 为动态追踪编译 默认情况下,探针是不可用的,因此你将需要显式地告诉配置脚本让探针在PostgreSQL中可用。要包括 DTrace 支持,在配置时指定。更多信息请见。 @@ -3834,7 +3834,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, 内置探针 - 如所示,源代码中提供了一些标准探针。显式了在探针中使用的类型。当然,可以增加更多探针来增强PostgreSQL的可观测性。 + 如所示,源代码中提供了一些标准探针。显示了在探针中使用的类型。当然,可以增加更多探针来增强PostgreSQL的可观测性。
@@ -3866,13 +3866,13 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, transaction-abort (LocalTransactionId) - 当一个事务失败完成时触发的探针。arg0 是事务 ID。 + 当一个事务失败结束时触发的探针。arg0 是事务 ID。 query-start (const char *) - 当一个查询的处理被开始时触发的探针。arg0 是查询字符串。 + 当一个查询的处理开始时触发的探针。arg0 是查询字符串。 @@ -3884,7 +3884,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, query-parse-start (const char *) - 当一个查询的解析被开始时触发的探针。arg0 是查询字符串。 + 当一个查询的解析开始时触发的探针。arg0 是查询字符串。 @@ -3896,7 +3896,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, query-rewrite-start (const char *) - 当一个查询的重写被开始时触发的探针。arg0 是查询字符串。 + 当一个查询的重写开始时触发的探针。arg0 是查询字符串。 @@ -3908,7 +3908,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, query-plan-start () - 当一个查询的规划被开始时触发的探针。 + 当一个查询的规划开始时触发的探针。 @@ -3920,7 +3920,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, query-execute-start () - 当一个查询的执行被开始时触发的探针。 + 当一个查询的执行开始时触发的探针。 @@ -3938,19 +3938,19 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, checkpoint-start (int) - 当一个检查点被开始时触发的探针。arg0 传递位标志来区分不同的检查点类型,例如关闭(shutdown)、立即(immediate)或强制(force)。 + 当一个检查点开始时触发的探针。arg0 传递位标志来区分不同的检查点类型,例如关闭(shutdown)、立即(immediate)或强制(force)。 checkpoint-done (int, int, int, int, int) - 当一个检查点完成时触发的探针(检查点处理过程中序列中列出的下一个触发的探针)。arg0 是要写的缓冲区数量。arg1 是缓冲区的总数。arg2、arg3 和 arg4 分别包含了增加、删除和循环回收的 WAL 文件的数量。 + 当一个检查点完成时触发的探针(下面列出的探针会在检查点处理过程中依次触发)。arg0 是已写入的缓冲区数量。arg1 是缓冲区的总数。arg2、arg3 和 arg4 分别包含了增加、删除和循环回收的 WAL 文件的数量。 clog-checkpoint-start (bool) - 当一个检查点的 CLOG 部分被开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 + 当一个检查点的 CLOG 部分开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 @@ -3962,7 +3962,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, subtrans-checkpoint-start (bool) - 当一个检查点的 SUBTRANS 部分被开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 + 当一个检查点的 SUBTRANS 部分开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 @@ -3974,7 +3974,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, multixact-checkpoint-start (bool) - 当一个检查点的 MultiXact 部分被开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 + 当一个检查点的 MultiXact 部分开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 @@ -3986,7 +3986,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, buffer-checkpoint-start (int) - 当一个检查点的写缓冲区部分被开始时触发的探针。arg0 传递位标志来区分不同的检查点类型,例如关闭(shutdown)、立即(immediate)或强制(force)。 + 当一个检查点的写缓冲区部分开始时触发的探针。arg0 传递位标志来区分不同的检查点类型,例如关闭(shutdown)、立即(immediate)或强制(force)。 @@ -4022,7 +4022,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, twophase-checkpoint-start () - 当一个检查点的两阶段部分被开始时触发的探针。 + 当一个检查点的两阶段部分开始时触发的探针。 @@ -4034,19 +4034,19 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, buffer-read-start (ForkNumber, BlockNumber, Oid, Oid, Oid, int, bool) - 当一次缓冲区读被开始时触发的探针。arg0 和 arg1 包含该页的分叉号和块号(如果这是一次关系扩展请求,arg1 为 -1)。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是 InvalidBackendId(-1)。arg6 为真表示一次关系扩展请求,为假表示正常读。 + 当一次缓冲区读开始时触发的探针。arg0 和 arg1 包含该页的分支号和块号(如果这是一次关系扩展请求,arg1 为 -1)。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是 InvalidBackendId(-1)。arg6 为真表示一次关系扩展请求,为假表示正常读。 buffer-read-done (ForkNumber, BlockNumber, Oid, Oid, Oid, int, bool, bool) - 当一次缓冲区读完成时触发的探针。arg0 和 arg1 包含该页的分叉号和块号(如果这是一次关系扩展请求,arg1 现在包含新增加块的块号)。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是 InvalidBackendId(-1)。arg6 为真表示一次关系扩展请求,为假表示正常读。arg7 为真表示在池中找到该缓冲区,为假表示没有找到。 + 当一次缓冲区读完成时触发的探针。arg0 和 arg1 包含该页的分支号和块号(如果这是一次关系扩展请求,arg1 现在包含新增加块的块号)。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是 InvalidBackendId(-1)。arg6 为真表示一次关系扩展请求,为假表示正常读。arg7 为真表示在池中找到该缓冲区,为假表示没有找到。 buffer-flush-start (ForkNumber, BlockNumber, Oid, Oid, Oid) - 在发出对一个共享缓冲区的任意写请求之前触发的探针。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。 + 在发出对一个共享缓冲区的任意写请求之前触发的探针。arg0 和 arg1 包含该页的分支号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。 @@ -4058,7 +4058,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, buffer-write-dirty-start (ForkNumber, BlockNumber, Oid, Oid, Oid) - 当一个服务器进程开始写一个脏缓冲区时触发的探针(如果这经常发生,表示太小,或需要调整后台写入器的控制参数)。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。 + 当一个服务器进程开始写一个脏缓冲区时触发的探针(如果这经常发生,表示太小,或需要调整后台写入器的控制参数)。arg0 和 arg1 包含该页的分支号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。 @@ -4076,13 +4076,13 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, wal-buffer-write-dirty-done () - 当一次脏 WAL 缓冲区完成时触发的探针。 + 当一次脏 WAL 缓冲区写入完成时触发的探针。 wal-insert (unsigned char, unsigned char) - 当一个 WAL 记录被插入时触发的探针。arg0 是该记录的资源管理者(rmid)。arg1 包含 info 标志。 + 当一个 WAL 记录被插入时触发的探针。arg0 是该记录的资源管理器(rmid)。arg1 包含 info 标志。 @@ -4094,31 +4094,31 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, smgr-md-read-start (ForkNumber, BlockNumber, Oid, Oid, Oid, int) - 当开始从一个关系读取一块时触发的探针。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。 + 当开始从一个关系读取一块时触发的探针。arg0 和 arg1 包含该页的分支号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。 smgr-md-read-done (ForkNumber, BlockNumber, Oid, Oid, Oid, int, int, int) - 当一次块读取完成时触发的探针。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。arg6 是实际读取的字节数,而 arg7 是请求读取的字节数(如果两者不同就意味着麻烦)。 + 当一次块读取完成时触发的探针。arg0 和 arg1 包含该页的分支号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。arg6 是实际读取的字节数,而 arg7 是请求读取的字节数(如果两者不同就意味着麻烦)。 smgr-md-write-start (ForkNumber, BlockNumber, Oid, Oid, Oid, int) - 当开始向一个关系中写入一个块时触发的探针。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。 + 当开始向一个关系中写入一个块时触发的探针。arg0 和 arg1 包含该页的分支号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。 smgr-md-write-done (ForkNumber, BlockNumber, Oid, Oid, Oid, int, int, int) - 当一个块写操作完成时触发的探针。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3和arg4 包含表空间、数据库和关系 OID来标识该关系。对于一个本地缓冲区,arg5 是创建临时关系的后端 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。arg6 是实际写的字节数,而 arg7 是要求写的字节数(如果这两者不同,则意味着麻烦)。 + 当一个块写操作完成时触发的探针。arg0 和 arg1 包含该页的分支号和块号。arg2、arg3和arg4 包含表空间、数据库和关系 OID来标识该关系。对于一个本地缓冲区,arg5 是创建临时关系的后端 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。arg6 是实际写的字节数,而 arg7 是要求写的字节数(如果这两者不同,则意味着麻烦)。 sort-start (int, bool, int, int, bool, int) - 当一次排序操作开始时触发的探针。arg0 指示是堆排序、索引排序或数据排序。arg1 为真表示强制唯一值。arg2 是键列数。arg3 是允许使用的工作内存大小(以千字节计)。如果要求随机访问排序结果,则 arg4 为真。arg5 为 0 时表示串行,为 1 时表示并行工作进程,为 2 时表示并行领导者。 + 当一次排序操作开始时触发的探针。arg0 指示是堆排序、索引排序或 datum 排序。arg1 为真表示强制唯一值。arg2 是键列数。arg3 是允许使用的工作内存大小(以千字节计)。如果要求随机访问排序结果,则 arg4 为真。arg5 为 0 时表示串行,为 1 时表示并行工作进程,为 2 时表示并行领导者。 @@ -4132,7 +4132,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, (char *, LWLockMode) 当成功获得一个 LWLock 时触发的探针。 arg0 是该 LWLock 所在的切片(Tranche)。 - arg1 所请求的锁模式,是排他或共享。 + arg1 是所请求的锁模式,是排他或共享。 @@ -4147,34 +4147,34 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, (char *, LWLockMode) 当一个 LWLock不是当即可用并且一个服务器进程因此开始等待该锁变为可用时触发的探针。 arg0 是该 LWLock 所在的切片(Tranche)。 - arg1 请求的锁模式,是排他或共享。 + arg1 是所请求的锁模式,是排他或共享。 lwlock-wait-done (char *, LWLockMode) 当一个进程从对一个 LWLock 的等待中被释放时(它实际还没有得到该锁)时触发的探针。arg0 是该 LWLock 所在的切片(Tranche)。 - arg1 所请求的锁模式,是排他或共享。 + arg1 是所请求的锁模式,是排他或共享。 lwlock-condacquire (char *, LWLockMode) 当调用者指定无需等待而成功获得一个 LWLock 时触发的探针。arg0 是该 LWLock 所在的切片(Tranche)。 - arg1 所请求的锁模式,是排他或共享。 + arg1 是所请求的锁模式,是排他或共享。 lwlock-condacquire-fail (char *, LWLockMode) 当调用者指定无需等待而没有成功获得一个 LWLock 时触发的探针。arg0 是该 LWLock 所在的切片(Tranche)。 - arg1 所请求的锁模式,是排他或共享。 + arg1 是所请求的锁模式,是排他或共享。 lock-wait-start (unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, LOCKMODE) - 当一个重量级锁(lmgr锁)的请求由于锁不可用开始等待时触发的探针。arg0 到 arg3 是标识被锁定对象的标签域。arg4 指示被锁对象的类型。arg5 表示被请求的锁类型。 + 当一个重量级锁(lmgr锁)的请求由于锁不可用开始等待时触发的探针。arg0 到 arg3 是标识被锁定对象的标签字段。arg4 指示被锁对象的类型。arg5 表示被请求的锁类型。 @@ -4195,7 +4195,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid,
- 定义用在探针参数中的类型 + 探针参数中使用的已定义类型 @@ -4290,7 +4290,7 @@ Total time (ns) 2312105013 - 你应该记住,DTrace 脚本需要细心地编写和调试,否则被收集的追踪信息可能会毫无意义。在大部分发现问题的情况中,它就是发生问题的部件,而不是底层系统。当讨论使用动态追踪发现的信息时,一定要附上使用的脚本以便其也被检查和讨论。 + 你应该记住,DTrace 脚本需要细心地编写和调试,否则被收集的追踪信息可能会毫无意义。在大多数发现问题的情况下,出错的是插桩,而不是底层系统。当讨论使用动态追踪发现的信息时,一定要附上使用的脚本以便其也被检查和讨论。 @@ -4306,7 +4306,7 @@ Total time (ns) 2312105013 - 决定探针名称以及探针可用的数据 + 决定探针名称以及要通过探针提供的数据 @@ -4320,7 +4320,7 @@ Total time (ns) 2312105013 - 如果pg_trace.h还不存在于包含该探针点的模块中,包括它,并且在源代码中期望的位置插入TRACE_POSTGRESQL探针宏 + 如果pg_trace.h尚未被包含该探针点的模块引用,则将它包含进来,并且在源代码中期望的位置插入TRACE_POSTGRESQL探针宏 @@ -4356,14 +4356,14 @@ Total time (ns) 2312105013 probe transaction__start(LocalTransactionId); - 注意探针名字中双下划线的使用。在一个使用探针的 DTrace 脚本中,双下划线需要被替换为一个连字符,因此 ,对用户而言transaction-start是文档名。 + 注意探针名字中双下划线的使用。在一个使用探针的 DTrace 脚本中,双下划线需要被替换为一个连字符,因此,文档中应向用户说明的名称是transaction-start - 在编译时,transaction__start被转换成一个宏调用TRACE_POSTGRESQL_TRANSACTION_START(注意这里是单下划线),可以通过包括头文件pg_trace.h获得。将宏调用加入到源代码中的合适位置。在这种情况下,看起来类似: + 在编译时,transaction__start被转换成一个名为TRACE_POSTGRESQL_TRANSACTION_START的宏(注意这里是单下划线),可以通过包含头文件pg_trace.h获得。将宏调用加入到源代码中的合适位置。在这种情况下,看起来类似: TRACE_POSTGRESQL_TRANSACTION_START(vxid.localTransactionId); @@ -4400,7 +4400,7 @@ TRACE_POSTGRESQL_TRANSACTION_START(vxid.localTransactionId); - 在大多数平台上,如果用编译了PostgreSQL,无论何时当控制经过一个追踪宏时,都会评估该宏的参数,即使没有进行追踪也会这样做。通常不需要担心你是否只在报告一些局部变量的值。但是要注意不要将开销大的函数调用放入参数中。如果你需要这样做,考虑通过检查追踪是否真的被启用来保护该宏: + 在大多数平台上,如果用编译了PostgreSQL,无论何时当控制经过一个追踪宏时,都会对该宏的参数求值,即使没有进行追踪也会这样做。如果只是报告少数局部变量的值,通常无需担心这一点。但是要注意不要将开销大的函数调用放入参数中。如果你需要这样做,考虑通过检查追踪是否真的被启用来保护该宏: if (TRACE_POSTGRESQL_TRANSACTION_START_ENABLED()) diff --git a/zh/12/mvcc.sgml b/zh/12/mvcc.sgml index 7dcf0f35..c25a2cbc 100644 --- a/zh/12/mvcc.sgml +++ b/zh/12/mvcc.sgml @@ -4,7 +4,7 @@ 并发控制 - concurrency + 并发 @@ -15,7 +15,7 @@ 介绍 - Multiversion Concurrency Control + 多版本并发控制 @@ -23,7 +23,7 @@ - Serializable Snapshot Isolation + 可串行化快照隔离 @@ -50,7 +50,7 @@ 事务隔离 - transaction isolation + 事务隔离 @@ -61,11 +61,14 @@ (这并不奇怪,如果事务的效果必须与一次只运行一个事务保持一致,又怎么可能看到由相互作用引起的任何现象呢?) - 各隔离级别所禁止的现象如下: + + 在各个级别上被禁止的现象有: + + 脏读 - dirty read + 脏读 @@ -77,7 +80,7 @@ 不可重复读 - nonrepeatable read + 不可重复读 @@ -89,7 +92,7 @@ 幻读 - phantom read + 幻读 @@ -101,7 +104,7 @@ 串行化异常 - serialization anomaly + 串行化异常 @@ -114,7 +117,7 @@ - transaction isolation level + 事务隔离级别 SQL 标准以及 PostgreSQL 实现的事务隔离级别见 @@ -241,12 +244,12 @@ 读已提交隔离级别 - transaction isolation level - read committed + 事务隔离级别 + 读已提交 - read committed + 读已提交 @@ -292,7 +295,7 @@ 由于上述规则,更新命令可能看到一个不一致的快照:它能够看到并发更新命令在它试图更新的同一行上的效果, 却看不到这些命令对数据库中其他行的影响。这种行为使得读已提交模式不适合涉及复杂搜索条件的命令; - 不过,对于较简单的场景它恰到好处。例如,考虑将 100 美元从一个账户转到另一个账户: + 不过,对于较简单的场景它恰到好处。例如,考虑以如下事务更新银行余额: BEGIN; @@ -301,13 +304,13 @@ UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 7534; COMMIT; - 如果另一个事务并发地尝试更改账户 7534 的余额,我们显然希望第二条语句从该账户行的已更新版本开始。 + 如果两个这样的事务并发地尝试更改账户 12345 的余额,我们显然希望第二个事务从该账户行的已更新版本开始。 因为每个命令只影响一个预先确定的行,让它看到该行的已更新版本不会造成任何麻烦的不一致。 在读已提交模式下,更复杂的用法可能产生不理想的结果。例如,考虑一个 - DELETE 命令,它所处理的数据会被另一个命令同时加入和移出其筛选条件。 + DELETE 命令,另一个命令正在修改数据,使某些行开始满足其筛选条件、另一些行不再满足。 假设 website 是一个有两行的表,其中 website.hits 分别等于 910: @@ -315,7 +318,7 @@ COMMIT; BEGIN; UPDATE website SET hits = hits + 1; --- run from another session: DELETE FROM website WHERE hits = 10; +-- 从另一个会话运行: DELETE FROM website WHERE hits = 10; COMMIT; @@ -343,12 +346,12 @@ COMMIT; 可重复读隔离级别 - transaction isolation level - repeatable read + 事务隔离级别 + 可重复读 - repeatable read + 可重复读 @@ -400,9 +403,7 @@ ERROR: could not serialize access due to concurrent update 可重复读模式提供了严格的保证,即每个事务都看到数据库的一个完全稳定的视图。 不过,这个视图并不一定总能与同一级别并发事务的某种串行(一次一个)执行保持一致。 - 例如,即使该级别上的只读事务可能看到一条控制记录被更新,表明某个批处理已经完成, - 但它并不一定能看到作为该批处理逻辑组成部分的某条明细记录, - 因为它读到的是控制记录的较早版本。如果不仔细使用显式锁来阻塞冲突事务, + 例如,即使是该级别的只读事务,也可能看到一条表明某批次已完成的控制记录,却看不到逻辑上属于该批次的某条明细记录,因为创建该明细记录的事务读取了控制记录的较早版本。如果不仔细使用显式锁来阻塞冲突事务, 试图依靠运行在这一隔离级别的事务来强制业务规则,往往无法正确工作。 @@ -410,7 +411,7 @@ ERROR: could not serialize access due to concurrent update 可重复读隔离级别是通过一种技术实现的,这种技术在学术数据库文献中以及某些其他数据库产品中被称为 快照隔离。与使用会降低并发性的传统加锁技术的系统相比, 其行为和性能可能会表现出差异。有些其他系统甚至把可重复读和快照隔离作为两个行为不同的独立隔离级别提供。 - 用来区分这两种技术的允许现象,直到 SQL 标准制定之后才被数据库研究人员正式定义,因此超出了本手册的范围。 + 用来区分这两种技术的允许现象,直到 SQL 标准制定之后才被数据库研究人员正式定义,并且超出了本手册的范围。 完整讨论请参阅 @@ -426,20 +427,20 @@ ERROR: could not serialize access due to concurrent update 可串行化隔离级别 - transaction isolation level - serializable + 事务隔离级别 + 可串行化 - serializable + 可串行化 - predicate locking + 谓词锁 - serialization anomaly + 串行化异常 @@ -469,13 +470,13 @@ ERROR: could not serialize access due to read/write dependencies among transact 当依赖可串行化事务来防止异常时,重要的是:从永久用户表读取的任何数据,在读取它的事务成功提交之前, - 都不应视为有效。即使对于只读事务也是如此;唯一的例外是可推迟只读事务中读取的数据, + 都不应视为有效。即使对于只读事务也是如此;唯一的例外是可延迟只读事务中读取的数据, 它一经读出就可视为有效,因为这种事务会等到能够获取一个保证不存在此类问题的快照后才开始读取数据。 在所有其他情况下,应用不能依赖后来被中止事务中读到的结果;相反,应重试事务直到成功。 - 为了保证真正的可串行化,PostgreSQL 使用了谓词锁, + 为了保证真正的可串行性,PostgreSQL 使用了谓词锁, 也就是说,系统会保留一些锁,以便判断某个写操作如果先发生,是否会影响并发事务先前读取的结果。 在 PostgreSQL 中,这些锁不会造成任何阻塞,因此会参与形成死锁。 它们用于识别并标记并发可串行化事务之间的依赖关系,而这些依赖在某些组合下可能导致串行化异常。 @@ -497,7 +498,7 @@ ERROR: could not serialize access due to read/write dependencies among transact - 持续使用可串行化事务可以简化开发。任何一组成功提交的并发可串行化事务,都保证与把它们一次一个运行的效果相同;这意味着,如果你能够证明某个事务在单独运行时会做正确的事,那么即使不了解其他事务会做什么,也可以相信它在任何可串行化事务的混合执行中也会做正确的事,否则它就不会成功提交。重要的是,采用这种技术的环境应当有一套通用机制来处理串行化失败(其 SQLSTATE 值总是 '40001'),因为很难准确预测究竟哪些事务会对读/写依赖关系有贡献,并因此需要被回滚来防止串行化异常。监视读/写依赖关系会带来开销,被串行化失败中止的事务重新启动也会带来开销;但在把这些开销与显式锁以及 SELECT FOR UPDATESELECT FOR SHARE 所涉及的成本和阻塞进行权衡之后,可串行化事务在某些环境中仍然是性能最佳的选择。 + 统一采用可串行化事务可以简化开发。任何一组成功提交的并发可串行化事务,都保证与把它们一次一个运行的效果相同;这意味着,如果你能够证明某个事务在单独运行时会做正确的事,那么即使不了解其他事务会做什么,也可以相信它在任何可串行化事务的混合执行中也会做正确的事,否则它就不会成功提交。重要的是,采用这种技术的环境应当有一套通用机制来处理串行化失败(其 SQLSTATE 值总是 '40001'),因为很难准确预测究竟哪些事务会对读/写依赖关系有贡献,并因此需要被回滚来防止串行化异常。监视读/写依赖关系会带来开销,被串行化失败中止的事务重新启动也会带来开销;但在把这些开销与显式锁以及 SELECT FOR UPDATESELECT FOR SHARE 所涉及的成本和阻塞进行权衡之后,可串行化事务在某些环境中仍然是性能最佳的选择。 @@ -541,7 +542,7 @@ ERROR: could not serialize access due to read/write dependencies among transact - 当系统因谓词锁表内存不足而被迫把多个页级谓词锁合并为单个关系级谓词锁时,串行化失败的比例可能会上升。你可以通过增加 来避免这种情况。 + 当系统因谓词锁表内存不足而被迫把多个页级谓词锁合并为单个关系级谓词锁时,串行化失败的比例可能会上升。你可以通过增加 和/或 来避免这种情况。 @@ -565,7 +566,7 @@ ERROR: could not serialize access due to read/write dependencies among transact 显式锁定 - lock + @@ -662,7 +663,7 @@ ERROR: could not serialize access due to read/write dependencies among transact CREATE STATISTICSCOMMENT ONREINDEX CONCURRENTLY, 以及某些 ALTER INDEX - 和 ALTER TABLE 变体会获取这种锁 + 和 ALTER TABLE 变体获取这种锁 (完整详情见 )。 @@ -920,7 +921,7 @@ ERROR: could not serialize access due to read/write dependencies among transact - 行为与 FOR SHARE 类似,不过锁更弱:SELECT FOR UPDATE 会被阻塞,但 SELECT FOR NO KEY UPDATE 不会。键共享锁会阻塞其他事务执行会修改键值的 DELETEUPDATE,但不会阻塞其他 UPDATE,也不会阻止 SELECT FOR NO KEY UPDATESELECT FOR SHARESELECT FOR KEY SHARE。 + 行为与 FOR SHARE 类似,不过锁更弱:SELECT FOR UPDATE 会被阻塞,但 SELECT FOR NO KEY UPDATE 不会。键共享锁会阻塞其他事务执行 DELETE 或任何会修改键值的 UPDATE,但不会阻塞其他 UPDATE,也不会阻止 SELECT FOR NO KEY UPDATESELECT FOR SHARESELECT FOR KEY SHARE @@ -995,7 +996,7 @@ ERROR: could not serialize access due to read/write dependencies among transact 死锁 - deadlock + 死锁 @@ -1038,12 +1039,12 @@ UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 22222; 咨询锁 - advisory lock + 咨询锁 - lock - advisory + + 咨询 @@ -1075,12 +1076,12 @@ UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 22222; 在某些使用咨询锁的方法中,特别是涉及显式排序和 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(id) FROM foo WHERE id = 12345; -- 可以 +SELECT pg_advisory_lock(id) FROM foo WHERE id > 12345 LIMIT 100; -- 危险! SELECT pg_advisory_lock(q.id) FROM ( SELECT id FROM foo WHERE id > 12345 LIMIT 100 -) q; -- ok +) q; -- 可以 在上面的查询中,第二种形式是危险的,因为不能保证在执行加锁函数之前先应用 LIMIT。 这可能导致获取了一些应用并未预期的锁,因此应用也不会去释放它们(直到会话结束)。 @@ -1098,12 +1099,12 @@ SELECT pg_advisory_lock(q.id) FROM 应用级别的数据一致性检查 - 在读已提交事务下,想要通过业务规则强制数据一致性非常困难,因为数据视图会随每条语句而变化, + 用读已提交事务强制执行有关数据完整性的业务规则非常困难,因为数据视图会随每条语句而变化, 而且一旦发生写冲突,即使是单条语句也未必局限于该语句自己的快照。 - 虽然可重复读事务在整个执行期间都具有稳定的数据视图,但在使用 MVCC 快照进行数据一致性检查时,还存在一个微妙问题,即所谓的读/写冲突。如果一个事务写入数据,而并发事务试图读取相同的数据(无论是在写入之前还是之后),它都看不到另一个事务的工作。于是,读取者看起来就像是先执行的一方,而不管究竟是谁先启动,也不管谁先提交。如果事情只停留在这一步,就没有问题;但如果读取者还写入了数据,而这些数据又被另一个并发事务读取,那么现在就会有一个事务看起来像是在前面提到的任一事务之前执行。如果看起来最后执行的事务实际上最先提交,就很容易在事务执行顺序图中形成一个环。一旦出现这样的环,不借助额外机制,一致性检查就无法正确工作。 + 虽然可重复读事务在整个执行期间都具有稳定的数据视图,但在使用 MVCC 快照进行数据一致性检查时,还存在一个微妙问题,即所谓的读/写冲突。如果一个事务写入数据,而并发事务试图读取相同的数据(无论是在写入之前还是之后),它都看不到另一个事务的工作。于是,读取者看起来就像是先执行的一方,而不管究竟是谁先启动,也不管谁先提交。如果事情只停留在这一步,就没有问题;但如果读取者还写入了数据,而这些数据又被另一个并发事务读取,那么现在就会有一个事务看起来像是在前面提到的任一事务之前执行。如果看起来最后执行的事务实际上最先提交,就很容易在事务执行顺序图中形成一个环。一旦出现这样的环,不借助额外机制,完整性检查就无法正确工作。 @@ -1120,7 +1121,7 @@ SELECT pg_advisory_lock(q.id) FROM - 使用这种技术时,如果应用软件通过某个框架运行,并由该框架自动重试因串行化错误而回滚的事务,就可以避免给应用程序员带来不必要的负担。把 default_transaction_isolation 设置为 serializable 可能是个好主意。通过在触发器中检查事务隔离级别来采取某些措施,以确保不会因为疏忽或为了绕过完整性检查而使用其他事务隔离级别,也是明智的。 + 使用这种技术时,如果应用软件通过某个框架运行,并由该框架自动重试因串行化失败而回滚的事务,就可以避免给应用程序员带来不必要的负担。把 default_transaction_isolation 设置为 serializable 可能是个好主意。通过在触发器中检查事务隔离级别来采取某些措施,以确保不会因为疏忽或为了绕过完整性检查而使用其他事务隔离级别,也是明智的。 @@ -1129,14 +1130,14 @@ SELECT pg_advisory_lock(q.id) FROM - 利用可串行化事务提供的这一层完整性保护,尚未扩展到热备模式()或逻辑副本。 - 因此,使用热备或逻辑复制的用户可能希望在主库上使用可重复读和显式锁定。 + 利用可串行化事务提供的这一层完整性保护,尚未扩展到热备模式()。 + 因此,使用热备的用户可能希望在主库上使用可重复读和显式锁定。 - 使用显式锁定强制一致性 + 使用显式阻塞锁强制一致性 当存在非可串行化写入时,要确保某一行当前仍然有效,并保护它不受并发更新影响, @@ -1159,7 +1160,7 @@ SELECT pg_advisory_lock(q.id) FROM 在非可串行化的 MVCC 环境下,全局有效性检查需要额外考虑。 - 例如,一个银行应用可能希望检查一个表中的所有收入总和等于另一个表中的所有支出总和, + 例如,一个银行应用可能希望检查一个表中的贷方金额总和等于另一个表中的借方金额总和, 而这两个表都在被活跃更新。在读已提交模式下,比较两个连续的 SELECT sum(...) 命令的结果并不可靠,因为第二个查询很可能会包含第一个查询没有统计到的事务提交结果。 在单个可重复读事务中完成这两次求和,只能准确反映在该可重复读事务开始之前已提交事务的效果 @@ -1207,18 +1208,21 @@ SELECT pg_advisory_lock(q.id) FROM 锁定和索引 - index - locks + 索引 + - 虽然PostgreSQL提供了对表数据的非阻塞读写访问,但目前并非所有已实现的索引访问方法都具备这种能力。下面按索引类型说明PostgreSQL的处理方式: + + 尽管 PostgreSQL 为表数据提供了非阻塞的读写访问,但 PostgreSQL 当前实现的索引访问方法并不是每一种都能提供非阻塞的读写访问。各种索引类型的处理方式如下: + + B-树、GiSTSP-GiST 索引 - 读写访问使用短期的页级共享/排他锁。每个索引行在被取出或插入之后,锁都会立即释放。这些索引类型在不存在死锁条件的前提下提供了最高的并发性。 + 读写访问使用短期的页级共享/排他锁。每个索引行在被取出或插入之后,锁都会立即释放。这些索引类型提供最高的并发性,并且不会产生死锁。 @@ -1240,7 +1244,7 @@ SELECT pg_advisory_lock(q.id) FROM - 读写访问使用短期的页级共享/排他锁。每个索引行在被取出或插入之后,锁都会立即释放。但要注意,插入一个 GIN 索引值通常会导致每行产生多个索引键插入,因此 GIN 可能为了插入单个值而做大量工作。 + 读写访问使用短期的页级共享/排他锁。每个索引行在被取出或插入之后,锁都会立即释放。但要注意,插入一个使用 GIN 索引的值通常会导致每行产生多个索引键插入,因此 GIN 可能为了插入单个值而做大量工作。 diff --git a/zh/12/oid2name.sgml b/zh/12/oid2name.sgml index b9e0721a..03f5b515 100644 --- a/zh/12/oid2name.sgml +++ b/zh/12/oid2name.sgml @@ -8,7 +8,7 @@ oid2name 1 - Application + 应用程序 diff --git a/zh/12/parallel.sgml b/zh/12/parallel.sgml index 2a470d5a..61445cb2 100644 --- a/zh/12/parallel.sgml +++ b/zh/12/parallel.sgml @@ -193,7 +193,7 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%'; - Parallel Append + 并行追加 每当 PostgreSQL 需要将来自多个源的行合并成一个结果集时,它就会使用 AppendMergeAppend 计划节点。这种情况常见于实现 UNION ALL 或扫描分区表时。这样的节点和其他任何计划中的情形一样,也可以用于并行计划。不过,在并行计划中,规划器也可能改用 Parallel Append 节点。 diff --git a/zh/12/pgbuffercache.sgml b/zh/12/pgbuffercache.sgml index d410e435..b2b07113 100644 --- a/zh/12/pgbuffercache.sgml +++ b/zh/12/pgbuffercache.sgml @@ -37,7 +37,7 @@ - Name + 名称 类型 引用 diff --git a/zh/12/pgcrypto.sgml b/zh/12/pgcrypto.sgml index 569edf92..1d626eaf 100644 --- a/zh/12/pgcrypto.sgml +++ b/zh/12/pgcrypto.sgml @@ -210,14 +210,14 @@ gen_salt(type text [, iter_count integer ]) returns text - type参数指定哈希算法。 + type参数指定 hash 算法。 接受的类型有:desxdesmd5bf iter_count参数允许用户为支持该参数的算法指定迭代次数。 - 次数越高,密码哈希所需时间越长,从而破解它所需时间也越长。 - 不过,如果次数过高,计算一个哈希可能需要数年时间 — 这显然不切实际。 + 次数越高,对密码进行 hash 所需的时间越长,从而破解它所需时间也越长。 + 不过,如果次数过高,计算一个 hash 可能需要数年时间 — 这显然不切实际。 若省略iter_count参数,则使用默认迭代次数。 允许的iter_count值取决于算法,如所示。 @@ -255,24 +255,24 @@ gen_salt(type text [, iter_count integer ]) returns text - 为了选择合适的迭代次数,可以考虑原始 DES crypt 在当时硬件上的设计速度是每秒 4 次哈希。 - 低于每秒 4 次哈希可能会影响可用性,而高于每秒 100 次哈希则很可能过快。 + 为了选择合适的迭代次数,可以考虑原始 DES crypt 在当时硬件上的设计速度是每秒 4 次 hash。 + 低于每秒 4 次 hash 可能会影响可用性,而高于每秒 100 次 hash 则很可能过快。 - 概述了不同哈希算法之间的相对速度差异。 + 概述了不同 hash 算法之间的相对速度差异。 该表展示了在 8 字符密码上尝试所有字符组合所需的时间,假定密码只包含小写字母, 或者包含大小写字母和数字。在crypt-bf条目中, 斜杠后的数字是gen_saltiter_count参数值。
- 哈希算法速度 + Hash 算法速度 算法 - 每秒哈希次数 + 每秒 hash 次数 针对[a-z] 针对[A-Za-z0-9] 相对于md5 hash的耗时倍数 diff --git a/zh/12/pgstandby.sgml b/zh/12/pgstandby.sgml index 76be2c6f..df77336e 100644 --- a/zh/12/pgstandby.sgml +++ b/zh/12/pgstandby.sgml @@ -8,7 +8,7 @@ pg_standby 1 - Application + 应用程序 diff --git a/zh/12/pgstatstatements.sgml b/zh/12/pgstatstatements.sgml index 548757a0..a0d7bc9e 100644 --- a/zh/12/pgstatstatements.sgml +++ b/zh/12/pgstatstatements.sgml @@ -24,7 +24,7 @@ - Name + 名称 类型 引用 diff --git a/zh/12/plhandler.sgml b/zh/12/plhandler.sgml index 37493d95..40067ef0 100644 --- a/zh/12/plhandler.sgml +++ b/zh/12/plhandler.sgml @@ -17,11 +17,11 @@ - 调用处理器与其他函数一样被调用:它会接收一个指向 FunctionCallInfoBaseData struct 的指针,其中包含参数值以及被调用函数的相关信息;同时它还应返回一个 Datum 结果(如果希望返回 SQL 空值结果,还可以设置 isnull 字段,也就是 FunctionCallInfoBaseData 结构体中的该字段)。调用处理器与普通被调函数之间的区别在于,flinfo->fn_oid 字段在 FunctionCallInfoBaseData 结构体中保存的是实际要调用函数的 OID,而不是调用处理器本身的 OID。调用处理器必须使用这个字段来判定要执行哪个函数。另外,传入的参数列表是按照目标函数而不是调用处理器的声明来设置的。 + 调用处理器与其他函数一样被调用:它会接收一个指向 FunctionCallInfoBaseData struct 的指针,其中包含参数值以及被调用函数的相关信息;同时它还应返回一个 Datum 结果(如果希望返回 SQL 空值结果,还需要设置 isnull 字段,也就是 FunctionCallInfoBaseData 结构体中的该字段)。调用处理器与普通被调函数之间的区别在于,flinfo->fn_oid 字段在 FunctionCallInfoBaseData 结构体中保存的是实际要调用函数的 OID,而不是调用处理器本身的 OID。调用处理器必须使用这个字段来判定要执行哪个函数。另外,传入的参数列表是按照目标函数而不是调用处理器的声明来设置的。 - 调用处理器必须从系统目录 pg_proc 中取出该函数的条目,并分析被调用函数的参数类型和返回类型。该函数的 AS 子句可在其 CREATE FUNCTION 命令对应的 prosrc 列里找到,也就是 pg_proc 行中的该列。这里通常是一段过程语言源文本,但理论上也可以是其他内容,例如某个文件的路径名,或者任何能详细告诉调用处理器该做什么的信息。 + 调用处理器必须从系统目录 pg_proc 中取出该函数的条目,并分析被调用函数的参数类型和返回类型。该函数的 CREATE FUNCTION 命令中的 AS 子句内容,保存在 pg_proc 对应行的 prosrc 列中。这里通常是一段过程语言源文本,但理论上也可以是其他内容,例如某个文件的路径名,或者任何能详细告诉调用处理器该做什么的信息。 @@ -54,7 +54,7 @@ plsample_call_handler(PG_FUNCTION_ARGS) if (CALLED_AS_TRIGGER(fcinfo)) { /* - * Called as a trigger function + * 作为触发器函数调用 */ TriggerData *trigdata = (TriggerData *) fcinfo->context; @@ -63,7 +63,7 @@ plsample_call_handler(PG_FUNCTION_ARGS) else { /* - * Called as a function + * 作为函数调用 */ retval = ... @@ -92,7 +92,7 @@ CREATE LANGUAGE plsample 验证器函数通常应遵循 参数:如果它被关闭,就应跳过任何开销高昂或依赖上下文的检查。如果该语言允许在编译时执行代码,验证器还必须抑制会诱发此类执行的检查。特别是,pg_dump 会关闭这个参数,这样它就可以装载过程语言函数,而不必担心函数体对其他数据库对象的副作用或依赖关系。(正因为有这一要求,调用处理器不应假设验证器已经完整检查了函数。提供验证器的目的,并不是让调用处理器省略检查,而是在 CREATE FUNCTION 命令中存在明显错误时立即通知用户。)虽然究竟检查哪些内容主要由验证器函数自行决定,但要注意,核心 CREATE FUNCTION 代码只会执行附加到函数上的 SET 子句,前提是 check_function_bodies 打开。因此,当 check_function_bodies 关闭时,那些结果可能受 GUC 参数影响的检查肯定都应跳过,以避免在恢复转储时出现虚假的失败。 + linkend="guc-check-function-bodies"/> 参数:如果它被关闭,就应跳过任何开销高昂或依赖上下文的检查。如果该语言允许在编译时执行代码,验证器还必须抑制会诱发此类执行的检查。特别是,pg_dump 会关闭这个参数,这样它就可以装载过程语言函数,而不必担心副作用或函数体对其他数据库对象的依赖关系。(正因为有这一要求,调用处理器不应假设验证器已经完整检查了函数。提供验证器的目的,并不是让调用处理器省略检查,而是在 CREATE FUNCTION 命令中存在明显错误时立即通知用户。)虽然究竟检查哪些内容主要由验证器函数自行决定,但要注意,只有在 check_function_bodies 打开时,核心 CREATE FUNCTION 代码才会执行函数附带的 SET 子句。因此,当 check_function_bodies 关闭时,那些结果可能受 GUC 参数影响的检查肯定都应跳过,以避免在恢复转储时出现虚假的失败。 diff --git a/zh/12/plperl.sgml b/zh/12/plperl.sgml index 9558c10f..cde65ad4 100644 --- a/zh/12/plperl.sgml +++ b/zh/12/plperl.sgml @@ -12,7 +12,7 @@ - PL/Perl 是一种可载入的过程语言,它允许使用 + PL/Perl 是一种可加载的过程语言,它允许使用 Perl 编程语言编写 PostgreSQL 函数和过程。 @@ -31,8 +31,7 @@ - 如果把该语言安装到 template1 中,之后创建的所有 - 数据库都会自动安装该语言。 + 如果把某种语言安装到template1中,之后创建的所有数据库都会自动安装该语言。 @@ -48,11 +47,21 @@ PL/Perl 函数和参数 - 要创建 PL/Perl 语言函数,请使用标准的 语法: + + 要用 PL/Perl 语言创建一个函数,可使用标准的 + 语法: + + CREATE FUNCTION funcname (argument-types) RETURNS return-type AS $$ - # PL/Perl function body + # PL/Perl 函数体 $$ LANGUAGE plperl; -函数体就是普通的 Perl 代码。实际上,PL/Perl 的衔接代码会将其包装在一个 Perl 子例程中。PL/Perl 函数在标量上下文中调用,因此不能返回列表。可以通过返回引用来返回非标量值(数组、记录和集合),详见下文。 + + + 函数的主体就是普通的 Perl 代码。事实上,PL/Perl 的粘合代码会把它 + 包裹在一个 Perl 子程序中。PL/Perl 函数在标量上下文中被调用,因此 + 不能返回列表。如下文所述,可以通过返回引用来返回 + 非标量值(数组、记录和集合)。 + 在 PL/Perl 过程中,Perl 代码返回的任何值都会被忽略。 @@ -63,7 +72,7 @@ $$ LANGUAGE plperl; DO $$ - # PL/Perl code + # PL/Perl 代码 $$ LANGUAGE plperl; @@ -121,15 +130,14 @@ $$ LANGUAGE plperl; 如果一个 SQL 空值空值in PL/Perl被传给一个函数,在 - Perl 中该参数值将呈现为undefined。上述函数定义对于 - 空输入的行为并不理想(实际上,它会把它们当作零)。我们可以在函数 + sortas="PL/Perl">在 PL/Perl 中被传给一个函数,在 + Perl 中该参数值将呈现为未定义。上述函数定义对于 + 空值输入的行为并不理想(实际上,它会把它们当作零)。我们可以在函数 定义中添加 STRICT,让 PostgreSQL 采取更合理的做法:如果传入空值, - 函数将根本不会被调用,而是自动返回空结果。另一种方式是在函数体中 + 函数将根本不会被调用,而是自动返回空值结果。另一种方式是在函数体中 检查未定义输入。例如,假设我们希望在 - perl_max 的两个参数中一个为空、另一个非空时, - 返回非空参数而不是空值: + perl_max 的两个参数中一个为空值、另一个非空值时,返回非空值参数而不是空值: CREATE FUNCTION perl_max (integer, integer) RETURNS integer AS $$ @@ -189,12 +197,12 @@ CREATE OR REPLACE FUNCTION concat_array_elements(text[]) RETURNS TEXT AS $$ my $result = ""; return undef if (!defined $arg); - # as an array reference + # 作为数组引用 for (@$arg) { $result .= $_; } - # also works as a string + # 也可以作为字符串使用 $result .= $arg; return $result; @@ -205,7 +213,8 @@ SELECT concat_array_elements(ARRAY['PL','/','Perl']); - 多维数组会以所有 Perl 程序员都熟悉的方式,表示为对低维数组引用的引用。 + 多维数组按 Perl 程序员熟悉的方式表示为指向较低维数组的引用, + 而这些数组的元素又是引用。 @@ -314,11 +323,11 @@ SELECT * FROM perl_set(); 如果希望在代码中使用 strict 编译指示,可以有几种 选择。对于临时的全局用法,可以 SET - plperl.use_strict 为 true。这会影响后续编译的 + plperl.use_strict 为真。这会影响后续编译的 PL/Perl 函数,但不会影响当前会话中已经编译的 函数。对于永久的全局用法,可以在 postgresql.conf 文件中将 - plperl.use_strict 设为 true。 + plperl.use_strict 设为真。 @@ -363,7 +372,7 @@ use strict; spi_exec_query(query [, limit]) spi_exec_query - in PL/Perl + 在 PL/Perl 中 @@ -377,11 +386,19 @@ use strict; -只有在确定结果集会比较小时,才应使用此命令。下面是一个查询(SELECT 命令)的示例,指定了可选的最大行数: +只有在确定结果集会比较小时,才应使用此命令。下面是一个带可选最大行数的查询(SELECT 命令)示例: + + $rv = spi_exec_query('SELECT * FROM my_table', 5); -这会返回最多 5 行,来自表 my_table。如果 my_table 包含列 my_column,就可以取得结果中第 $i 行的该列值,方法如下: + + 这样会从表 my_table 返回最多 5 行。如果 + my_table 有一列 my_column, + 可以像下面这样从结果的第 $i 行取得该值: + $foo = $rv->{rows}[$i]->{my_column}; -要取得 SELECT 查询返回的总行数,可以这样做: + + 可以这样访问 SELECT 查询返回的总行数: + $nrows = $rv->{processed} @@ -439,21 +456,21 @@ SELECT * FROM test_munge(); spi_query(command) spi_query - in PL/Perl + 在 PL/Perl 中 spi_fetchrow(cursor) spi_fetchrow - in PL/Perl + 在 PL/Perl 中 spi_cursor_close(cursor) spi_cursor_close - in PL/Perl + 在 PL/Perl 中 @@ -473,7 +490,7 @@ CREATE OR REPLACE FUNCTION lotsa_md5 (INTEGER) RETURNS SETOF foo_type AS $$ my $file = '/usr/share/dict/words'; my $t = localtime; elog(NOTICE, "opening file $file at $t" ); - open my $fh, '<', $file # ooh, it's a file access! + open my $fh, '<', $file # 注意,这里访问了文件! or elog(ERROR, "cannot open $file for reading: $!"); my @words = <$fh>; close $fh; @@ -512,40 +529,55 @@ SELECT * from lotsa_md5(500); spi_prepare(command, argument types) spi_prepare - in PL/Perl + 在 PL/Perl 中 spi_query_prepared(plan, arguments) spi_query_prepared - in PL/Perl + 在 PL/Perl 中 spi_exec_prepared(plan [, attributes], arguments) spi_exec_prepared - in PL/Perl + 在 PL/Perl 中 spi_freeplan(plan) spi_freeplan - in PL/Perl + 在 PL/Perl 中 - spi_preparespi_query_preparedspi_exec_prepared,以及 spi_freeplan 实现相同的功能,但用于预备查询。spi_prepare 接受包含编号参数占位符($1、$2 等)的查询字符串,以及由参数类型字符串组成的列表: + spi_preparespi_query_prepared、 + spi_exec_preparedspi_freeplan + 提供相同的功能,但用于预备查询。spi_prepare + 接受一个带编号参数占位符($1、$2 等)的查询字符串,以及参数类型的 + 字符串列表: + $plan = spi_prepare('SELECT * FROM test WHERE id > $1 AND name = $2', 'INTEGER', 'TEXT'); -调用 spi_prepare 预备查询计划后,就可以使用该计划代替查询字符串。可以将其用于 spi_exec_prepared,其结果与以下函数返回的结果相同:spi_exec_query;也可以用于 spi_query_prepared,它返回游标,行为与 spi_query 完全相同。随后可以将该游标传给 spi_fetchrowspi_exec_prepared 可选的第二个参数是属性哈希引用;目前唯一支持的属性是 limit,用于设置查询返回的最大行数。省略 limit 或将其指定为零,表示不限制行数。 + + 一旦通过调用 spi_prepare 准备好查询计划,就可以用它 + 代替字符串查询。可以在 spi_exec_prepared 中使用, + 此时结果与 spi_exec_query 返回的结果相同;也可以在 + spi_query_prepared 中使用,它会像 + spi_query 一样返回一个游标,随后可传给 + spi_fetchrowspi_exec_prepared + 的可选第二个参数是属性哈希引用;目前唯一支持的属性是 + limit,它用于设置查询返回的最大行数。省略 + limit 或将其指定为零时,不会限制返回行数。 + - 预处理查询的优点在于,一个准备好的计划可以用于多次查询执行。当计划 + 预备查询的优点在于,一个准备好的计划可以用于多次查询执行。当计划 不再需要时,可以用 spi_freeplan 将其释放: CREATE OR REPLACE FUNCTION init() RETURNS VOID AS $$ @@ -621,14 +653,14 @@ SELECT release_hosts_query(); spi_commit() spi_commit - in PL/Perl + 在 PL/Perl 中 spi_rollback() spi_rollback - in PL/Perl + 在 PL/Perl 中 @@ -667,7 +699,7 @@ CALL transaction_test1(); - PL/Perl 中的工具函数 + PL/Perl 中的辅助函数 @@ -675,7 +707,7 @@ CALL transaction_test1(); elog(level, msg) elog - in PL/Perl + 在 PL/Perl 中 @@ -700,7 +732,7 @@ CALL transaction_test1(); quote_literal(string) quote_literal - in PL/Perl + 在 PL/Perl 中 @@ -720,7 +752,7 @@ CALL transaction_test1(); quote_nullable(string) quote_nullable - in PL/Perl + 在 PL/Perl 中 @@ -738,7 +770,7 @@ CALL transaction_test1(); quote_ident(string) quote_ident - in PL/Perl + 在 PL/Perl 中 @@ -756,7 +788,7 @@ CALL transaction_test1(); decode_bytea(string) decode_bytea - in PL/Perl + 在 PL/Perl 中 @@ -773,7 +805,7 @@ CALL transaction_test1(); encode_bytea(string) encode_bytea - in PL/Perl + 在 PL/Perl 中 @@ -789,7 +821,7 @@ CALL transaction_test1(); encode_array_literal(array) encode_array_literal - in PL/Perl + 在 PL/Perl 中 @@ -811,7 +843,7 @@ CALL transaction_test1(); encode_typed_literal(value, typename) encode_typed_literal - in PL/Perl + 在 PL/Perl 中 @@ -828,7 +860,7 @@ CALL transaction_test1(); encode_array_constructor(array) encode_array_constructor - in PL/Perl + 在 PL/Perl 中 @@ -848,7 +880,7 @@ CALL transaction_test1(); looks_like_number(string) looks_like_number - in PL/Perl + 在 PL/Perl 中 @@ -867,11 +899,15 @@ CALL transaction_test1(); is_array_ref(argument) is_array_ref - in PL/Perl + 在 PL/Perl 中 - 如果给定参数可以作为数组引用处理,即参数的 ref 为 ARRAYPostgreSQL::InServer::ARRAY,则返回真值;否则返回假值。 + + 如果给定参数可被视为数组引用,则返回真值;也就是该参数的 + ref 值为 ARRAY 或 + PostgreSQL::InServer::ARRAY。否则返回假值。 + @@ -920,9 +956,9 @@ CREATE OR REPLACE FUNCTION myfuncs() RETURNS void AS $$ }; $$ LANGUAGE plperl; -SELECT myfuncs(); /* initializes the function */ +SELECT myfuncs(); /* 初始化函数 */ -/* Set up a function that uses the quote function */ +/* 创建一个使用加引号函数的函数 */ CREATE OR REPLACE FUNCTION use_quote(TEXT) RETURNS text AS $$ my $text_to_quote = shift; @@ -937,11 +973,9 @@ $$ LANGUAGE plperl; - 出于安全原因,PL/Perl 会为某个 SQL 角色调用的函数在该角色专用的独立 - Perl 解释器中执行。这可以防止一个用户意外或恶意地干扰另一个用户的 + 出于安全原因,PL/Perl 会在每个 SQL 角色各自独立的 Perl 解释器中执行该角色调用的函数。这可以防止一个用户意外或恶意地干扰另一个用户的 PL/Perl 函数行为。每个这样的解释器都有自己的 - %_SHARED 变量值和其他全局状态。因此,只有在两个 - PL/Perl 函数都由同一 SQL 角色执行时,它们才会共享 + %_SHARED 变量值和其他全局状态。因此,当且仅当两个 PL/Perl 函数都由同一 SQL 角色执行时,它们才会共享 %_SHARED 的值。在某些应用中,一个会话可能会在多个 SQL 角色下执行代码(通过 SECURITY DEFINER 函数、 使用 SET ROLE 等),这时可能需要显式采取措施, @@ -954,29 +988,29 @@ $$ LANGUAGE plperl; - 可信与不可信的 PL/Perl + 受信任与不受信任的 PL/Perl - trusted + 受信任的 PL/Perl 通常,PL/Perl 会被安装为一种名为 plperl 的 - 可信编程语言。在这种设置下,为了保持安全性,某些 Perl + 受信任的编程语言。在这种设置下,为了保持安全性,某些 Perl 操作会被禁用。一般来说,受限制的是那些与环境交互的操作,包括文件句柄 操作、requireuse (针对外部模块)。它无法像 C 函数那样访问数据库服务器进程的内部, - 也无法以服务器进程的权限获取操作系统级访问。因此,可以允许任何无权限 + 也无法以服务器进程的权限获取操作系统级访问。因此,可以允许任何无特权 的数据库用户使用这种语言。 - 可信 PL/Perl 依赖 Perl 的 Opcode 模块来维持安全性。 + 受信任的 PL/Perl 依赖 Perl 的 Opcode 模块来维持安全性。 Perl 的 文档 - 指出,该模块对于可信 PL/Perl 这一使用场景并不有效。若你的安全需求 + 指出,该模块对于受信任的 PL/Perl 这一使用场景并不有效。若你的安全需求 不能接受该警告中的不确定性,请考虑执行 REVOKE USAGE ON LANGUAGE plperl FROM PUBLIC @@ -1000,16 +1034,16 @@ $$ LANGUAGE plperl; 有时需要编写不受这些限制的 Perl 函数。例如,可能需要一个能发送邮件的 Perl 函数。为处理这类情况,也可以把 PL/Perl 安装成一种 - 不可信语言(通常称为 + 不受信任的语言(通常称为 PL/PerlUPL/PerlU)。 在这种情况下,完整的 Perl 语言都可用。安装该语言时,使用语言名 - plperlu 就会选择不可信的 PL/Perl 变体。 + plperlu 就会选择不受信任的 PL/Perl 变体。 PL/PerlU 函数的编写者必须注意,函数不能被 用于任何非预期用途,因为它能够执行以数据库管理员身份登录的用户所能 - 做的任何事情。请注意,数据库系统只允许数据库超级用户用不可信语言创建 + 做的任何事情。请注意,数据库系统只允许数据库超级用户用不受信任的语言创建 函数。 @@ -1057,7 +1091,13 @@ $$ LANGUAGE plperl; PL/Perl 触发器 - 可以用 PL/Perl 编写触发器函数。在触发器函数中,哈希引用 $_TD 包含当前触发器事件的信息。$_TD 是全局变量,每次触发器调用都有独立的局部值。以下是 $_TD 哈希引用的字段: + + PL/Perl 可用于编写触发器函数。在触发器函数中,哈希引用 + $_TD 包含有关当前触发器事件的信息。 + $_TD 是一个全局变量,对触发器的每一次调用都会得到 + 一个单独的局部值。$_TD 哈希引用包含以下字段: + + $_TD->{new}{foo} @@ -1137,7 +1177,7 @@ $$ LANGUAGE plperl; $_TD->{relname} - 触发该触发器的表名。该字段已废弃,并且可能会在未来版本中移除。 + 触发该触发器的表名。该字段已弃用,并且可能会在未来版本中移除。 请改用 $_TD->{table_name}。 @@ -1173,7 +1213,10 @@ $$ LANGUAGE plperl; - 行级触发器可以返回以下值之一: + + 行级触发器可以返回下列之一: + + return; @@ -1203,7 +1246,9 @@ $$ LANGUAGE plperl; - 下面的触发器函数示例演示了上述部分内容: + + 下面是一个触发器函数示例,用于说明上述部分内容: + CREATE TABLE test ( i int, v varchar @@ -1211,12 +1256,12 @@ CREATE TABLE test ( CREATE OR REPLACE FUNCTION valid_id() RETURNS trigger AS $$ if (($_TD->{new}{i} >= 100) || ($_TD->{new}{i} <= 0)) { - return "SKIP"; # skip INSERT/UPDATE command + return "SKIP"; # 跳过 INSERT/UPDATE 命令 } elsif ($_TD->{new}{v} ne "immortal") { $_TD->{new}{v} .= "(modified by trigger)"; - return "MODIFY"; # modify row and execute INSERT/UPDATE command + return "MODIFY"; # 修改行并执行 INSERT/UPDATE 命令 } else { - return; # execute INSERT/UPDATE command + return; # 执行 INSERT/UPDATE 命令 } $$ LANGUAGE plperl; @@ -1230,7 +1275,13 @@ CREATE TRIGGER test_valid_id_trig PL/Perl 事件触发器 - 可以用 PL/Perl 编写事件触发器函数。在事件触发器函数中,哈希引用 $_TD 包含当前触发器事件的信息。$_TD 是全局变量,每次触发器调用都有独立的局部值。以下是 $_TD 哈希引用的字段: + + PL/Perl 可用于编写事件触发器函数。在事件触发器函数中,哈希引用 + $_TD 包含有关当前触发器事件的信息。 + $_TD 是一个全局变量,对触发器的每一次调用都会得到 + 一个单独的局部值。$_TD 哈希引用包含以下字段: + + $_TD->{event} @@ -1255,7 +1306,9 @@ CREATE TRIGGER test_valid_id_trig 触发器函数的返回值会被忽略。 - 下面的事件触发器函数示例演示了上述部分内容: + + 下面是一个事件触发器函数示例,用于说明上述部分内容: + CREATE OR REPLACE FUNCTION perlsnitch() RETURNS event_trigger AS $$ elog(NOTICE, "perlsnitch: " . $_TD->{event} . " " . $_TD->{tag} . " "); $$ LANGUAGE plperl; @@ -1363,7 +1416,7 @@ DO 'elog(WARNING, join ", ", sort keys %INC)' LANGUAGE plperl; 也会发生。这是在 plperl.on_init 完成的任何初始化 之后进行的。执行这段代码时 SPI 函数不可用。 plperl.on_plperl_init 中的 Perl 代码是在对解释器 - 进行锁定之后执行的,因此只能执行可信操作。 + 进行锁定之后执行的,因此只能执行受信任的操作。 @@ -1404,7 +1457,10 @@ DO 'elog(WARNING, join ", ", sort keys %INC)' LANGUAGE plperl; 限制与缺失特性 - PL/Perl 目前还缺少以下功能,欢迎贡献这些功能的实现。 + + PL/Perl 目前仍缺少下列特性,但欢迎为此作出贡献。 + + PL/Perl 函数不能直接调用彼此。 diff --git a/zh/12/plpgsql.sgml b/zh/12/plpgsql.sgml index a8e269e6..3fa56d0d 100644 --- a/zh/12/plpgsql.sgml +++ b/zh/12/plpgsql.sgml @@ -11,7 +11,9 @@ 概述 - PL/pgSQL是一种可装载的过程语言,适用于PostgreSQL数据库系统。PL/pgSQL的设计目标是创建一种具有以下特点的可装载过程语言: + PL/pgSQL 是一种用于 PostgreSQL 数据库系统的可载入过程语言。PL/pgSQL 的设计目标,是创建一种具备以下特性的可载入过程语言: + + 可用于创建函数、过程和触发器, @@ -137,7 +139,7 @@ CREATE FUNCTION somefunc(integer, text) RETURNS integer AS 'function body text' LANGUAGE plpgsql; - 就 CREATE FUNCTION 而言,函数体目前只是一个字符串字面量。编写函数体时,通常最好使用美元引用(见 ),而不是普通的单引号语法。如果不使用美元引用,函数体中的任何单引号或反斜线都必须通过双写进行转义。本章几乎所有示例的函数体都使用了美元引用。 + 就 CREATE FUNCTION 而言,函数体只是一个字符串字面量。编写函数体时,通常最好使用美元引用(见 ),而不是普通的单引号语法。如果不使用美元引用,函数体中的任何单引号或反斜线都必须通过双写进行转义。本章几乎所有示例的函数体都使用了美元引用。 @@ -320,7 +322,7 @@ $$ LANGUAGE plpgsql; - 当 PL/pgSQL 函数声明了输出参数时,输出参数也会像普通输入参数一样获得 $n 名称和可选别名。输出参数本质上是一个初始值为 NULL 的变量,应在函数执行期间给它赋值。该参数的最终值就是返回值。例如,sales-tax 的示例也可以这样写: + 当 PL/pgSQL 函数声明了输出参数时,输出参数也会像普通输入参数一样获得 $n 名称和可选别名。输出参数本质上是一个初始值为 NULL 的变量,应在函数执行期间给它赋值。该参数的最终值就是返回值。例如,销售税的示例也可以这样写: CREATE FUNCTION sales_tax(subtotal real, OUT tax real) AS $$ @@ -333,14 +335,19 @@ $$ LANGUAGE plpgsql; 注意这里省略了 RETURNS real — 当然也可以写上,但那只是冗余。 - 输出参数在返回多个值时最有用。一个简单的例子是: + + 当需要返回多个值时,输出参数尤其有用。下面是一个简单示例: + + CREATE FUNCTION sum_n_product(x int, y int, OUT sum int, OUT prod int) AS $$ BEGIN sum := x + y; prod := x * y; END; $$ LANGUAGE plpgsql; -所述,这实际上为函数结果创建了一个匿名记录类型。如果给出RETURNS子句,它必须写为RETURNS record。 + + + 如 所述,这实际上会为函数结果创建一个匿名记录类型。如果写了 RETURNS 子句,它必须是 RETURNS record @@ -431,7 +438,9 @@ user_id users.user_id%TYPE; 使用 %TYPE 的好处是,你不必知道所引用结构的实际数据类型;更重要的是,如果被引用项的数据类型将来发生变化(例如把 user_id 的类型从 integer 改成 real),你可能就不需要修改函数定义。 - %TYPE在多态函数中特别有用,因为内部变量所需的数据类型可能在各次调用之间发生变化。可以对函数参数或结果占位符应用%TYPE,以创建适当的变量。 + + %TYPE 在多态函数中特别有价值,因为内部变量所需的数据类型可能在不同调用之间变化。可以把 %TYPE 应用到函数参数或结果占位符上,以创建合适的变量。 + @@ -447,9 +456,13 @@ user_id users.user_id%TYPE; 复合类型的变量称为变量(或行类型变量)。只要查询的列集合与该变量声明的类型相匹配,这种变量就可以保存 SELECTFOR 查询结果中的整行。行值的各个字段可以使用通常的点号记法访问,例如 rowvar.field - 可以使用table_name%ROWTYPE记号,将行变量声明为与现有表或视图的行具有相同类型;也可以通过给出复合类型名称来声明它。(因为每个表都有一个同名的关联复合类型,所以在PostgreSQL中,实际上写不写%ROWTYPE都没有区别。但带有%ROWTYPE的形式更易于移植。) + + 行变量既可以通过 table_name%ROWTYPE 记法声明为与现有表或视图的行具有相同类型,也可以通过给出某个复合类型的名称来声明。(由于每个表都有一个同名的关联复合类型,所以在 PostgreSQL 中实际上写不写 %ROWTYPE 并无区别;不过带 %ROWTYPE 的形式可移植性更好。) + - 函数参数可以是复合类型(完整的表行)。在这种情况下,相应的标识符$n将是一个行变量,可以从中选取字段,例如$1.user_id + + 函数参数也可以是复合类型(完整的表行)。在这种情况下,相应的标识符 $n 就是一个行变量,并且可以从中选取字段,例如 $1.user_id。 + 下面是一个使用复合类型的示例。table1table2 是已经存在的表,它们至少包含下面提到的字段: @@ -491,12 +504,12 @@ SELECT merge_fields(t.*) FROM table1 t WHERE ... ; <application>PL/pgSQL</application>变量的排序规则 - collation - in PL/pgSQL + 排序规则 + 在 PL/pgSQL 中 - 当 PL/pgSQL 函数具有一个或多个可排序数据类型参数时,每次函数调用都会根据分配给实际参数的排序规则确定出一个排序规则,如 所述。如果该排序规则能成功确定出来(即参数之间的隐式排序规则没有冲突),那么所有可排序参数都会被视为隐式带有该排序规则。这会影响函数中那些受排序规则影响的操作。例如,考虑 + 当 PL/pgSQL 函数具有一个或多个支持排序规则的数据类型参数时,每次函数调用都会根据分配给实际参数的排序规则确定出一个排序规则,如 所述。如果该排序规则能成功确定出来(即参数之间的隐式排序规则没有冲突),那么所有支持排序规则的参数都会被视为隐式带有该排序规则。这会影响函数中那些受排序规则影响的操作。例如,考虑 CREATE FUNCTION less_than(a text, b text) RETURNS boolean AS $$ @@ -513,7 +526,7 @@ SELECT less_than(text_field_1, text_field_2 COLLATE "C") FROM table1; - 此外,确定出的排序规则也会被视为任何可排序数据类型局部变量的排序规则。因此,即使把这个函数写成下面这样,其行为也不会有任何不同: + 此外,确定出的排序规则也会被视为任何支持排序规则的数据类型局部变量的排序规则。因此,即使把这个函数写成下面这样,其行为也不会有任何不同: CREATE FUNCTION less_than(a text, b text) RETURNS boolean AS $$ @@ -528,11 +541,11 @@ $$ LANGUAGE plpgsql; - 如果函数没有可排序数据类型的参数,或者无法为它们确定共同排序规则,那么参数和局部变量将使用其数据类型的默认排序规则(通常是数据库默认排序规则,但对于域类型变量也可能不同)。 + 如果函数没有支持排序规则的数据类型的参数,或者无法为它们确定共同排序规则,那么参数和局部变量将使用其数据类型的默认排序规则(通常是数据库默认排序规则,但对于域类型变量也可能不同)。 - 通过在可排序数据类型局部变量的声明中加入 COLLATE 选项,可以为其指定不同的排序规则,例如 + 通过在支持排序规则的数据类型局部变量的声明中加入 COLLATE 选项,可以为其指定不同的排序规则,例如 DECLARE @@ -637,12 +650,12 @@ PERFORM create_mv('cs_session_page_requests_mv', my_query); SELECT INTO - in PL/pgSQL + 在 PL/pgSQL 中 RETURNING INTO - in PL/pgSQL + 在 PL/pgSQL 中 产生单行(可能有多列)结果的 SQL 命令,其结果可以赋给记录变量、行类型变量或标量变量列表。方法是在基本 SQL 命令中添加INTO子句。例如: @@ -683,7 +696,7 @@ END; 成功执行带有STRICT的命令总会将FOUND设为真。 - 对于带有RETURNINGINSERT/UPDATE/DELETE/即使没有指定STRICTPL/pgSQL也会针对多于一个返回行的情况报告一个错误。这是因为没有类似于ORDER BY的选项可以用来决定应该返回哪个被影响的行。 + 对于带有RETURNINGINSERT/UPDATE/DELETE,即使没有指定STRICTPL/pgSQL也会针对多于一个返回行的情况报告一个错误。这是因为没有类似于ORDER BY的选项可以用来决定应该返回哪个被影响的行。 如果print_strict_params已为该函数启用,那么当不满足STRICT要求而抛出错误时,错误消息的DETAIL部分将包含传给查询的参数信息。可以为所有函数更改print_strict_params设置,方法是设置plpgsql.print_strict_params,不过只会影响随后编译的函数。也可以通过编译器选项逐函数启用,例如: @@ -720,25 +733,23 @@ CONTEXT: PL/pgSQL function get_userid(text) line 6 at SQL statement 执行动态命令 - 很多时候你将想要在PL/pgSQL函数中产生动态命令,也就是每次执行中会涉及到不同表或不同数据类型的命令。PL/pgSQL通常对于命令所做的缓存计划尝试(如中讨论)在这种情境下无法工作。要处理这一类问题,需要提供EXECUTE语句: + 很多时候你将想要在PL/pgSQL函数中产生动态命令,也就是每次执行中会涉及到不同表或不同数据类型的命令。PL/pgSQL通常对于命令所做的缓存计划尝试(如中讨论)在这种情境下无法工作。要处理这一类问题,提供了EXECUTE语句: EXECUTE command-string INTO STRICT target USING expression , ... ; - 其中command-string是一个能得到一个包含要被执行命令字符串(类型text)的表达式。可选的target是一个记录变量、一个行变量或者一个逗号分隔的简单变量以及记录/行域的列表,该命令的结果将存储在其中。可选的USING表达式提供要被插入到该命令中的值。 + 其中command-string是一个能得到一个包含要被执行命令字符串(类型text)的表达式。可选的target是一个记录变量、一个行变量或者一个逗号分隔的简单变量以及记录/行字段的列表,该命令的结果将存储在其中。可选的USING表达式提供要被插入到该命令中的值。 在计算得到的命令字符串中,不会做PL/pgSQL变量的替换。任何所需的变量值必须在命令字符串被构造时被插入其中,或者你可以使用下面描述的参数。 - - 还有,对于通过EXECUTE执行的命令不会有计划被缓存。该命令反而在每次运行时都会被做计划。因此,该命令字符串可以在执行不同表和列上动作的函数中被动态创建。 - + 此外,通过 EXECUTE 执行的命令不会缓存计划,而是在每次运行该语句时重新规划。因此,可以在函数中动态构造命令字符串,对不同的表和列执行操作。 - INTO子句指定一个返回行的 SQL 命令的结果应该被赋值到哪里。如果提供了一个行或变量列表,它必须完全匹配查询命令结果的结构(当一个记录变量被提供时,它会自动把它自己配置为匹配结果结构)。如果返回多个行,只有第一个行会被赋值给INTO变量。如果没有返回行,NULL 会被赋值给INTO变量。如果没有指定INTO子句,该查询结果会被抛弃。 + INTO子句指定一个返回行的 SQL 命令的结果应该被赋值到哪里。如果提供了一个行变量或变量列表,它必须完全匹配查询命令结果的结构(当一个记录变量被提供时,它会自动把它自己配置为匹配结果结构)。如果返回多个行,只有第一个行会被赋值给INTO变量。如果没有返回行,NULL 会被赋值给INTO变量。如果没有指定INTO子句,该查询结果会被抛弃。 @@ -746,7 +757,7 @@ EXECUTE command-string INT - 命令字符串可以使用参数值,它们在命令中用$1$2等引用。这些符号引用在USING子句中提供的值。这种方法常常更适合于把数据值作为文本插入到命令字符串中:它避免了将该值转换为文本以及转换回来的运行时负荷,并且它更不容易被 SQL 注入攻击,因为不需要引用或转义。一个示例是: + 命令字符串可以使用参数值,它们在命令中用$1$2等引用。这些符号引用在USING子句中提供的值。这种方法通常比把数据值作为文本插入命令字符串更可取:它避免了将该值转换为文本以及转换回来的运行时负荷,并且它更不容易被 SQL 注入攻击,因为不需要引用或转义。一个示例是: EXECUTE 'SELECT count(*) FROM mytable WHERE inserted_by = $1 AND inserted <= $2' INTO c @@ -768,7 +779,7 @@ EXECUTE format('SELECT count(*) FROM %I ' 参数符号的另一个限制是,它们只能用于SELECTINSERTUPDATE以及DELETE命令。在其他语句类型(统称为工具语句)中,即使只是数据值,也必须以文本形式插入。 - 在上面第一个示例中,带有一个简单的常量命令字符串和一些USING参数的EXECUTE命令在功能上等效于直接用PL/pgSQL写的命令,并且允许自动发生PL/pgSQL变量替换。重要的不同之处在于,EXECUTE会在每一次执行时根据当前的参数值重新计划该命令,而PL/pgSQL则是创建一个通用计划并且将其缓存以便重用。在最佳计划强依赖于参数值的情况中,使用EXECUTE来明确地保证不会选择一个通用计划是很有帮助的。 + 在上面第一个示例中,带有一个简单的常量命令字符串和一些USING参数的EXECUTE命令在功能上等效于直接用PL/pgSQL写的命令,并且允许自动发生PL/pgSQL变量替换。重要的不同之处在于,EXECUTE会在每一次执行时根据当前的参数值重新计划该命令,而PL/pgSQL则可能创建一个通用计划并且将其缓存以便重用。在最佳计划强依赖于参数值的情况中,使用EXECUTE来明确地保证不会选择一个通用计划是很有帮助的。 @@ -840,19 +851,19 @@ EXECUTE 'UPDATE tbl SET ' || ' WHERE key = ' || quote_nullable(keyvalue); - 如果正在处理的参数值可能为空,那么通常应该用quote_nullable来代替quote_literal。 + 如果正在处理的参数值可能为空值,那么通常应该用quote_nullable来代替quote_literal - 通常,必须小心地确保查询中的空值不会递送意料之外的结果。例如如果keyvalue为空,下面的WHERE子句 + 通常,必须小心地确保查询中的空值不会产生意料之外的结果。例如如果keyvalue为空值,下面的WHERE子句 'WHERE key = ' || quote_nullable(keyvalue) - 永远不会成功,因为在=操作符中使用空操作数得到的结果总是为空。如果想让空和一个普通键值一样工作,你应该将上面的命令重写成 + 永远不会成功,因为在=操作符中使用空值操作数得到的结果总是空值。如果想让空值像普通键值一样工作,你应该将上面的命令重写成 'WHERE key IS NOT DISTINCT FROM ' || quote_nullable(keyvalue) - (目前,IS NOT DISTINCT FROM的处理效率不如=,因此只有在非常必要时才这样做。关于空和IS DISTINCT的详细信息请见)。 + (目前,IS NOT DISTINCT FROM的处理效率不如=,因此只有在非常必要时才这样做。关于空值和IS DISTINCT的详细信息请见)。 @@ -865,7 +876,7 @@ EXECUTE 'UPDATE tbl SET ' || '$$ WHERE key = ' || quote_literal(keyvalue); - 因为如果newvalue的内容碰巧含有$$,那么这段代码就会出问题。同样的缺点可能适用于你选择的任何其他美元符号引用定界符。因此,要想安全地引用事先不知道的文本,必须恰当地使用quote_literalquote_nullablequote_ident。 + 因为如果newvalue的内容碰巧含有$$,那么这段代码就会出问题。同样的问题也适用于你选择的任何其他美元符号引用定界符。因此,要想安全地引用事先不知道的文本,必须恰当地使用quote_literalquote_nullablequote_ident @@ -903,7 +914,7 @@ EXECUTE format('UPDATE tbl SET %I = $1 WHERE key = $2', colname) GET CURRENT DIAGNOSTICS variable { = | := } item , ... ; - 这条命令允许检索系统状态指示符。CURRENT是一个噪声词(另见中的GET STACKED DIAGNOSTICS)。每个item是一个关键字, 它标识一个要被赋予给指定变量的状态值(变量应具有正确的数据类型来接收状态值)。中展示了当前可用的状态项。冒号等号(:=)可以被用来取代 SQL 标准的=符号。例如: + 这条命令允许检索系统状态指示符。CURRENT是一个噪声词(另见中的GET STACKED DIAGNOSTICS)。每个item是一个关键字, 它标识一个要被赋予给指定variable的状态值(变量应具有正确的数据类型来接收状态值)。中展示了当前可用的状态项。冒号等号(:=)可以被用来取代 SQL 标准的=符号。例如: GET DIAGNOSTICS integer_var = ROW_COUNT; @@ -935,10 +946,15 @@ GET DIAGNOSTICS integer_var = ROW_COUNT;
- 确定命令执行效果的第二种方法是检查名为FOUND的特殊变量,其类型为booleanFOUND的初始值为假,这适用于每次PL/pgSQL函数调用。以下各类语句都会设置它: + + 第二种确定命令效果的方法是检查名为FOUND的特殊变量,类型为boolean。 + 在每次PL/pgSQL函数调用中,FOUND的初始值都是 false。 + 它由以下类型的语句设置: + + - SELECT INTO语句在分配行时将FOUND设置为true, + SELECT INTO语句在为目标赋上一行值时将FOUND设置为true, 如果没有返回行则设置为false。 @@ -967,7 +983,7 @@ GET DIAGNOSTICS integer_var = ROW_COUNT; FORFOREACH语句在迭代一次或多次时将 FOUND设置为true,否则设置为false。 - 当循环退出时,FOUND被设置为这种方式; + 当循环退出时,FOUND会按上述方式设置; 在循环执行过程中,FOUND不会被循环语句修改, 尽管它可能会被循环体内的其他语句执行修改。 @@ -979,7 +995,11 @@ GET DIAGNOSTICS integer_var = ROW_COUNT; 如果没有返回行则设置为false。 - 其他PL/pgSQL语句不会改变以下变量的状态:FOUND。特别要注意的是,EXECUTE会改变GET DIAGNOSTICS的输出,但不会改变FOUND。 +
+ + 其他PL/pgSQL语句不会改变FOUND的状态。 + 特别注意,EXECUTE会改变GET DIAGNOSTICS的输出, + 但不会改变FOUND
@@ -999,12 +1019,14 @@ NULL; - 例如,下面两个代码片段是等价的: + + 例如,下面的两段代码是等价的: + BEGIN y := x / 0; EXCEPTION WHEN division_by_zero THEN - NULL; -- ignore the error + NULL; -- 忽略错误 END; @@ -1012,9 +1034,11 @@ END; BEGIN y := x / 0; EXCEPTION - WHEN division_by_zero THEN -- ignore the error + WHEN division_by_zero THEN -- 忽略错误 END; -选用哪一种取决于个人偏好。 + + 究竟使用哪一种取决于各人的喜好。 +
@@ -1052,7 +1076,7 @@ RETURN expression; - 如果函数返回的是标量类型,表达式结果会自动转换为函数的返回类型。但如果要返回一个组合(行)值,你必须写出一个恰好生成所需列集合的表达式。这可能需要显式类型转换。 + 如果函数返回的是标量类型,表达式结果会按照赋值部分的说明自动转换为函数的返回类型。但如果要返回一个复合(行)值,你必须写出一个恰好生成所需列集合的表达式。这可能需要显式类型转换。 @@ -1064,17 +1088,20 @@ RETURN expression; - 一个函数的返回值不能是未定义。如果控制到达了函数最顶层的块而没有碰到一个RETURN语句,那么会发生一个运行时错误。不过,这个限制不适用于带输出参数的函数以及返回void的函数。在这些情况中,如果顶层的块结束,将自动执行一个RETURN语句。 + 一个函数的返回值不能是未定义。如果控制到达了函数最顶层块的末尾而没有碰到一个RETURN语句,那么会发生一个运行时错误。不过,这个限制不适用于带输出参数的函数以及返回void的函数。在这些情况中,如果顶层的块结束,将自动执行一个RETURN语句。 - 下面是一些例子: --- functions returning a scalar type + + 一些示例: + + +-- 返回一个标量类型的函数 RETURN 1 + 2; RETURN scalar_var; --- functions returning a composite type +-- 返回一个复合类型的函数 RETURN composite_type_var; -RETURN (1, 2, 'three'::text); -- must cast columns to correct types +RETURN (1, 2, 'three'::text); -- 必须把列类型转换成正确的类型 @@ -1083,11 +1110,11 @@ RETURN (1, 2, 'three'::text); -- must cast columns to correct types <command>RETURN NEXT</command> 和 <command>RETURN QUERY</command> RETURN NEXT - in PL/pgSQL + 在 PL/pgSQL 中 RETURN QUERY - in PL/pgSQL + 在 PL/pgSQL 中 @@ -1097,7 +1124,7 @@ RETURN QUERY EXECUTE command-string < - 当 PL/pgSQL 函数被声明为返回 SETOF sometype 时,返回过程会略有不同。在这种情况下,要返回的各个项通过一系列 RETURN NEXTRETURN QUERY 命令指定,最后再用一个不带参数的 RETURN 命令表明函数已经执行完毕。RETURN NEXT 可用于标量和组合数据类型;对于组合结果类型,会返回完整的结果RETURN QUERY 会把查询执行结果追加到函数的结果集中。在同一个集合返回函数中,RETURN NEXTRETURN QUERY 可以自由混用,此时它们的结果会被串接起来。 + 当 PL/pgSQL 函数被声明为返回 SETOF sometype 时,返回过程会略有不同。在这种情况下,要返回的各个项通过一系列 RETURN NEXTRETURN QUERY 命令指定,最后再用一个不带参数的 RETURN 命令表明函数已经执行完毕。RETURN NEXT 可用于标量和复合数据类型;对于复合结果类型,会返回完整的结果RETURN QUERY 会把查询执行结果追加到函数的结果集中。在同一个集合返回函数中,RETURN NEXTRETURN QUERY 可以自由混用,此时它们的结果会被串接起来。 @@ -1112,7 +1139,8 @@ RETURN QUERY EXECUTE command-string < 如果你声明函数带有输出参数,只需要写不带表达式的RETURN NEXT。在每一次执行时,输出参数变量的当前值将被保存下来用于最终返回为结果的一行。注意为了创建一个带有输出参数的集合返回函数,在有多个输出参数时,你必须声明函数为返回SETOF record;或者如果只有一个类型为sometype的输出参数时,声明函数为SETOF sometype - 下面的函数示例使用了RETURN NEXT: + + 下面是一个使用RETURN NEXT的函数示例: CREATE TABLE foo (fooid INT, foosubid INT, fooname TEXT); @@ -1127,8 +1155,8 @@ BEGIN FOR r IN SELECT * FROM foo WHERE fooid > 0 LOOP - -- can do some processing here - RETURN NEXT r; -- return current row of SELECT + -- 这里可以做一些处理 + RETURN NEXT r; -- 返回 SELECT 的当前行 END LOOP; RETURN; END; @@ -1139,7 +1167,8 @@ SELECT * FROM get_all_foo(); - 下面的函数示例使用了RETURN QUERY: + + 这里是一个使用RETURN QUERY的函数的示例: CREATE FUNCTION get_available_flightid(date) RETURNS SETOF integer AS @@ -1150,8 +1179,8 @@ BEGIN WHERE flightdate >= $1 AND flightdate < ($1 + 1); - -- Since execution is not finished, we can check whether rows were returned - -- and raise exception if not. + -- 因为执行还未结束,我们可以检查是否有行被返回 + -- 如果没有就抛出异常。 IF NOT FOUND THEN RAISE EXCEPTION 'No flight at %.', $1; END IF; @@ -1161,8 +1190,7 @@ BEGIN $BODY$ LANGUAGE plpgsql; --- Returns available flights or raises exception if there are no --- available flights. +-- 返回可用的航班或者在没有可用航班时抛出异常。 SELECT * FROM get_available_flightid(CURRENT_DATE); @@ -1334,7 +1362,7 @@ ELSIF number > 0 THEN ELSIF number < 0 THEN result := 'negative'; ELSE - -- 嗯,唯一的其他可能性是数字为空 + -- 嗯,唯一的其他可能性是 number 为 null result := 'NULL'; END IF; @@ -1437,12 +1465,12 @@ END CASE; 简单循环 - loop + 循环 在 PL/pgSQL 中 - 使用LOOPEXITCONTINUEWHILEFORFOREACH语句,你可以安排PL/pgSQL重复一系列命令。 + 使用LOOPEXITCONTINUEWHILEFORFOREACH语句,你可以安排PL/pgSQL函数重复一系列命令。 @@ -1488,26 +1516,28 @@ EXIT label WHEN BEGIN 块一起使用时,EXIT 会把控制转交给该块结束后的下一条语句。需要注意的是,为此必须使用标签;未加标签的 EXIT 永远不会被视为匹配某个 BEGIN 块。这与 PostgreSQL 8.4 之前的版本不同,旧版本允许未加标签的 EXIT 匹配 BEGIN 块。 - 例如: + + 示例: + LOOP - -- some computations + -- 一些计算 IF count > 0 THEN - EXIT; -- exit loop + EXIT; -- 退出循环 END IF; END LOOP; LOOP - -- some computations - EXIT WHEN count > 0; -- same result as previous example + -- 一些计算 + EXIT WHEN count > 0; -- 和前一个示例相同的结果 END LOOP; <<ablock>> BEGIN - -- some computations + -- 一些计算 IF stocks > 100000 THEN - EXIT ablock; -- causes exit from the BEGIN block + EXIT ablock; -- 导致从 BEGIN 块中退出 END IF; - -- computations here will be skipped when stocks > 100000 + -- 当stocks > 100000时,这里的计算将被跳过 END; @@ -1537,7 +1567,9 @@ CONTINUE label WHEN CONTINUE可以被用在所有类型的循环中,它并不限于在无条件循环中使用。 - 例如: + + 示例: + LOOP -- 一些计算 EXIT WHEN count > 100; @@ -1594,22 +1626,22 @@ END LOOP label ; - 这种形式的FOR会创建一个在一个整数范围上迭代的循环。变量name会自动定义为类型integer并且只在循环内存在(任何该变量名的现有定义在此循环内都将被忽略)。给出范围上下界的两个表达式在进入循环的时候计算一次。如果没有指定BY子句,迭代步长为 1,否则步长是BY中指定的值,该值也只在循环进入时计算一次。如果指定了REVERSE,那么在每次迭代后步长值会被减除而不是增加。 + 这种形式的FOR会创建一个在一个整数范围上迭代的循环。变量name会自动定义为类型integer并且只在循环内存在(任何该变量名的现有定义在此循环内都将被忽略)。给出范围上下界的两个表达式在进入循环的时候计算一次。如果没有指定BY子句,迭代步长为 1,否则步长是BY中指定的值,该值也只在循环进入时计算一次。如果指定了REVERSE,那么在每次迭代后会减去步长,而不是加上步长。 整数FOR循环的一些示例: FOR i IN 1..10 LOOP - -- 我在循环中将取值 1,2,3,4,5,6,7,8,9,10 + -- i 在循环中将取值 1,2,3,4,5,6,7,8,9,10 END LOOP; FOR i IN REVERSE 10..1 LOOP - -- 我在循环中将取值 10,9,8,7,6,5,4,3,2,1 + -- i 在循环中将取值 10,9,8,7,6,5,4,3,2,1 END LOOP; FOR i IN REVERSE 10..1 BY 2 LOOP - -- 我在循环中将取值 10,8,6,4,2 + -- i 在循环中将取值 10,8,6,4,2 END LOOP; @@ -1672,7 +1704,7 @@ $$ LANGUAGE plpgsql; - 在这类 FOR 语句中使用的 query,可以是任何向调用者返回行的 SQL 命令:最常见的是 SELECT,但也可以是带 RETURNING 子句的 INSERTUPDATEDELETE。某些实用程序命令,如 EXPLAIN,也可以用于此处。 + 在这类 FOR 语句中使用的 query,可以是任何向调用者返回行的 SQL 命令:最常见的是 SELECT,但也可以是带 RETURNING 子句的 INSERTUPDATEDELETE。某些工具命令,如 EXPLAIN,也可以用于此处。 PL/pgSQL变量会被替换到查询文本中,并且如中详细讨论的,查询计划会被缓存以用于可能的重用。 @@ -1685,7 +1717,7 @@ FOR target IN EXECUTE text_expressionstatements END LOOP label ; - 这个示例类似前面的形式,只不过源查询被指定为一个字符串表达式,在每次进入FOR循环时都会计算它并且重新计划。这允许程序员在一个预先计划好了的命令的速度和一个动态命令的灵活性之间进行选择,就像一个纯EXECUTE语句那样。在使用EXECUTE时,可以通过USING将参数值插入到动态命令中。 + 这个示例类似前面的形式,只不过源查询被指定为一个字符串表达式,在每次进入FOR循环时都会计算它并且重新计划。这允许程序员在一个预先计划好了的命令的速度和一个动态命令的灵活性之间进行选择,就像一个纯EXECUTE语句那样。与EXECUTE一样,可以通过USING将参数值插入到动态命令中。 @@ -1722,7 +1754,7 @@ END; $$ LANGUAGE plpgsql; - 元素会按存储顺序访问,而不管数组有多少维。尽管target通常只是单个变量,但在遍历组合值(记录)数组时,它也可以是一个变量列表。在这种情况下,每个数组元素都会按组合值的连续列给这些变量赋值。 + 元素会按存储顺序访问,而不管数组有多少维。尽管target通常只是单个变量,但在遍历复合值(记录)数组时,它也可以是一个变量列表。在这种情况下,每个数组元素都会按复合值的连续列给这些变量赋值。 @@ -1754,8 +1786,8 @@ NOTICE: row = {10,11,12} 捕获错误 - exceptions - in PL/pgSQL + 异常 + 在 PL/pgSQL 中 @@ -1814,7 +1846,7 @@ END; - 进入和退出一个包含EXCEPTION子句的块要比不包含该子句的块开销大的多。因此,只在必要的时候使用EXCEPTION。 + 进入和退出一个包含EXCEPTION子句的块要比不包含该子句的块开销大得多。因此,只在必要的时候使用EXCEPTION @@ -1841,9 +1873,9 @@ BEGIN IF found THEN RETURN; END IF; - -- 不在这里,那么尝试插入该键 + -- 该键不存在,因此尝试插入 -- 如果其他某人并发地插入同一个键, - -- 我们可能得到一个唯一键失败 + -- 就可能发生违反唯一约束的错误 BEGIN INSERT INTO db(a,b) VALUES (key, data); RETURN; @@ -1881,7 +1913,7 @@ SELECT merge_db(1, 'dennis'); GET STACKED DIAGNOSTICS variable { = | := } item , ... ; - 每个item是一个关键词,它标识一个被赋予给指定变量(应该具有接收该值的正确数据类型)的状态值。中显示了当前可用的状态项。 + 每个item是一个关键词,它标识一个被赋予给指定variable(应该具有接收该值的正确数据类型)的状态值。中显示了当前可用的状态项。 @@ -1989,7 +2021,7 @@ END; 获得执行位置信息 - GET DIAGNOSTICS(之前在中描述)命令检索有关当前执行状态的信息(反之上文讨论的GET STACKED DIAGNOSTICS命令会把有关执行状态的信息报告成一个以前的错误)。它的PG_CONTEXT状态项可用于标识当前执行位置。状态项PG_CONTEXT将返回一个文本字符串,其中有描述该调用栈的多行文本。第一行会指向当前函数以及当前正在执行GET DIAGNOSTICS的命令。第二行及其后的行表示调用栈中更上层的调用函数。例如: + GET DIAGNOSTICS(之前在中描述)命令检索有关当前执行状态的信息(反之上文讨论的GET STACKED DIAGNOSTICS命令报告先前发生错误时的执行状态信息)。它的PG_CONTEXT状态项可用于标识当前执行位置。状态项PG_CONTEXT将返回一个文本字符串,其中包含一行或多行描述该调用栈的文本。第一行会指向当前函数以及当前正在执行的GET DIAGNOSTICS命令。第二行及其后的行表示调用栈中更上层的调用函数。例如: CREATE OR REPLACE FUNCTION outer_func() RETURNS integer AS $$ @@ -2032,7 +2064,7 @@ CONTEXT: PL/pgSQL function outer_func() line 3 at RETURN 游标 - cursor + 游标 在 PL/pgSQL 中 @@ -2064,7 +2096,7 @@ DECLARE - 当游标查询使用 FOR UPDATE/SHARE 时,不能使用 SCROLL 选项。此外,对于涉及易失函数的查询,最好使用 NO SCROLLSCROLL 的实现假定重新读取查询输出会得到一致的结果,而易失函数并不满足这一假设。 + 当游标查询使用 FOR UPDATE/SHARE 时,不能使用 SCROLL 选项。此外,对于涉及易失函数的查询,最好使用 NO SCROLLSCROLL 的实现假定重新读取查询输出会得到一致的结果,而易失函数可能无法满足这一假设。 @@ -2142,7 +2174,9 @@ OPEN bound_cursorvar ( 位置或命名记号可以传递参数值。在位置记号中,所有参数都必须按照顺序指定。在命名记号中,每一个参数的名字使用:=与参数表达式分隔。类似于中描述的调用函数,也允许混合位置和命名记号。 - 例如(使用前面的游标声明示例): + + 示例(这些示例使用上面示例中的游标声明): + OPEN curs2; OPEN curs3(42); OPEN curs3(key := 42); @@ -2372,12 +2406,17 @@ COMMIT; 遍历游标结果 - 有一种FOR语句的变体可以遍历游标返回的行。其语法为: + + 有一种FOR语句的变体,它允许通过游标返回的行进行迭代。语法是: + + <<label>> FOR recordvar IN bound_cursorvar ( argument_name := argument_value , ... ) LOOP statements END LOOP label ; -游标变量必须在声明时绑定到某个查询,并且此时不能处于已打开状态。FOR语句会自动打开该游标,并在循环退出时将其关闭。当且仅当游标声明为接受参数时,才必须给出实际参数值表达式列表。这些值会被替换到查询中,其方式与执行以下命令时相同:OPEN(见)。 + + + 该游标变量必须在声明时已经被绑定到某个查询,并且它不能已经被打开。FOR语句会自动打开游标,并且在退出循环时自动关闭游标。当且仅当游标被声明要使用参数时,才必须出现一个实际参数值表达式的列表。这些值会被替换到查询中,采用OPEN期间的方式(见)。 @@ -2418,7 +2457,7 @@ CALL transaction_test1(); 连锁的事务 - 在 PL/pgSQL + 在 PL/pgSQL 中 @@ -2482,7 +2521,9 @@ RAISE ; level(如果有)之后,可以指定一个format字符串(必须是简单的字符串字面量,不能是表达式)。格式字符串指定要报告的错误消息文本。格式字符串之后可以跟上可选的参数表达式,其值将被插入消息中。在格式字符串内,%会被替换为下一个可选参数值的字符串表示。写成%%可以输出一个字面的%。参数个数必须与格式字符串中%占位符的个数匹配,否则会在函数编译期间报错。 - 在这个例子中,v_job_id的值会替换字符串中的% + + 在这个示例中,v_job_id的值将替换字符串中的%: + RAISE NOTICE 'Calling cs_create_job(%)', v_job_id; @@ -2494,7 +2535,7 @@ RAISE NOTICE 'Calling cs_create_job(%)', v_job_id; MESSAGE - 设置错误消息文本。如果RAISE采用了在USING之前包含格式字符串的形式,则不能使用此选项。 + 设置错误消息文本。该选项不能用于在USING之前包含格式字符串的RAISE形式。 @@ -2508,14 +2549,14 @@ RAISE NOTICE 'Calling cs_create_job(%)', v_job_id; HINT - 提供提示消息。 + 提供一个提示消息。 ERRCODE - 指定要报告的错误码(SQLSTATE),可以使用中所示的条件名,也可以直接使用五个字符的 SQLSTATE 代码。 + 指定要报告的错误代码(SQLSTATE),可以用中所示的条件名,或者直接作为一个五字符 SQLSTATE 代码。 @@ -2526,7 +2567,7 @@ RAISE NOTICE 'Calling cs_create_job(%)', v_job_id; TABLE SCHEMA - 提供相关对象的名称。 + 提供一个相关对象的名称。 @@ -2538,23 +2579,33 @@ RAISE EXCEPTION 'Nonexistent ID --> %', user_id - 这两个例子展示了设置 SQLSTATE 的等价方式: + + 这两个示例展示了设置 SQLSTATE 的两种等价的方法: + RAISE 'Duplicate user ID: %', user_id USING ERRCODE = 'unique_violation'; RAISE 'Duplicate user ID: %', user_id USING ERRCODE = '23505'; - 还有第二种RAISE语法,其主要参数是要报告的条件名或 SQLSTATE,例如: + + 还有第二种RAISE语法,其中主参数是要报告的条件名或 SQLSTATE,例如: + RAISE division_by_zero; RAISE SQLSTATE '22012'; -在这种语法中,USING可以用来提供自定义的错误消息、详细信息或提示。前面例子的另一种写法是 + + 在这种语法中,USING可以用来提供自定义的错误消息、细节或提示。另一种达到前面示例同样效果的方式是: + RAISE unique_violation USING MESSAGE = 'Duplicate user ID: ' || user_id; - 还有一种变体是写成RAISE USINGRAISE level USING,并把其余所有内容放入USING列表。 + + 还有另一种变体是写RAISE USINGRAISE level USING,并把其余内容都放在USING列表里。 + - 最后一种RAISE变体完全不带参数。这种形式只能用于BEGIN块的EXCEPTION子句内部;它会重新抛出当前正在处理的错误。 + + RAISE的最后一种变体根本没有参数。这种形式只能被用在一个BEGIN块的EXCEPTION子句中,它导致当前正在被处理的错误被重新抛出。 + @@ -2572,7 +2623,7 @@ RAISE unique_violation USING MESSAGE = 'Duplicate user ID: ' || user_id; - 当用 SQLSTATE 代码指定错误代码时,你并不受限于预定义错误代码,而是可以选择任何由五位数字和/或大写 ASCII 字母构成的错误代码,唯一不能使用的是 00000。我们建议尽量避免抛出以三个零结尾的错误代码,因为这些是类别代码,只能用于捕获整个类别。 + 当用 SQLSTATE 代码指定错误代码时,你并不受限于预定义错误代码,而是可以选择任何由五位数字和/或大写 ASCII 字母构成的错误代码,唯一不能使用的是 00000。我们建议尽量避免抛出以三个零结尾的错误代码,因为这些是类别代码,只能通过捕获整个类别来捕获这类错误。 @@ -2584,12 +2635,12 @@ RAISE unique_violation USING MESSAGE = 'Duplicate user ID: ' || user_id; ASSERT - in PL/pgSQL + 在 PL/pgSQL 中 - assertions - in PL/pgSQL + 断言 + 在 PL/pgSQL 中 @@ -2606,15 +2657,14 @@ ASSERT condition , condition是一个布尔 表达式,它被期望总是计算为真。如果确实如此, - ASSERT语句不会再做什么。但如果结果是假 - 或者空,那么将发生一个ASSERT_FAILURE异常(如果在计算 + ASSERT语句不会再做什么。但如果结果是假或者空值,那么将发生一个ASSERT_FAILURE异常(如果在计算 condition时发生错误, 它会被报告为一个普通错误)。 如果提供了可选的message, - 它是一个结果(如果非空)被用来替换默认错误消息文本 + 它是一个结果(如果不为 NULL)被用来替换默认错误消息文本 assertion failed的表达式(如果 condition失败)。 message表达式在 @@ -2768,11 +2818,11 @@ ASSERT condition , - INSTEAD OF触发器(总是行级触发器,并且可能只被用于视图)能够返回空来表示它们没有执行任何更新,并且对该行剩余的操作可以被跳过(即后续的触发器不会被引发,并且该行不会被计入外围INSERT/UPDATE/DELETE的行影响状态中)。否则一个非空值应该被返回用以表示该触发器执行了所请求的操作。对于INSERTUPDATE操作,返回值应该是NEW,触发器函数可能对它进行了修改来支持INSERT RETURNINGUPDATE RETURNING(这也将影响被传递给任何后续触发器的行值,或者被传递给带有ON CONFLICT DO UPDATEINSERT语句中一个特殊的EXCLUDED别名引用)。对于DELETE操作,返回值应该是OLD。 + INSTEAD OF触发器(总是行级触发器,并且只能用于视图)能够返回 null 来表示它们没有执行任何更新,并且对该行剩余的操作应被跳过(即后续的触发器不会被引发,并且该行不会被计入外围INSERT/UPDATE/DELETE的行影响状态中)。否则应该返回一个非 null 值用以表示该触发器执行了所请求的操作。对于INSERTUPDATE操作,返回值应该是NEW,触发器函数可能对它进行了修改来支持INSERT RETURNINGUPDATE RETURNING(这也将影响被传递给任何后续触发器的行值,或者被传递给带有ON CONFLICT DO UPDATEINSERT语句中一个特殊的EXCLUDED别名引用)。对于DELETE操作,返回值应该是OLD - 一个AFTER行级触发器或一个BEFOREAFTER语句级触发器的返回值总是会被忽略,它可能也是空。不过,任何这些类型的触发器可能仍会通过抛出一个错误来中止整个操作。 + 一个AFTER行级触发器或一个BEFOREAFTER语句级触发器的返回值总是会被忽略,因此也可以返回 null。不过,任何这些类型的触发器可能仍会通过抛出一个错误来中止整个操作。 @@ -2947,15 +2997,15 @@ INSTEAD OF INSERT OR UPDATE OR DELETE ON emp_view - 一个 <application>PL/pgSQL</application> 用于维护汇总表的触发器函数 + 一个用于维护汇总表的 <application>PL/pgSQL</application> 触发器函数 - 这里详述的模式有一部分是基于 Ralph Kimball 所作的数据仓工具包中的Grocery Store示例。 + 这里详述的模式有一部分是基于 Ralph Kimball 所作的数据仓库工具包中的Grocery Store示例。 -- --- Main tables - time dimension and sales fact. +-- 主表 - 时间维度和销售事实。 -- CREATE TABLE time_dimension ( time_key integer NOT NULL, @@ -2978,7 +3028,7 @@ CREATE TABLE sales_fact ( CREATE INDEX sales_fact_time ON sales_fact(time_key); -- --- Summary table - sales by time. +-- 汇总表 - 按时间汇总销售 -- CREATE TABLE sales_summary_bytime ( time_key integer NOT NULL, @@ -2989,7 +3039,7 @@ CREATE TABLE sales_summary_bytime ( CREATE UNIQUE INDEX sales_summary_bytime_key ON sales_summary_bytime(time_key); -- --- Function and trigger to amend summarized column(s) on UPDATE, INSERT, DELETE. +-- 在 UPDATE、INSERT、DELETE 时修改汇总列的函数和触发器。 -- CREATE OR REPLACE FUNCTION maint_sales_summary_bytime() RETURNS TRIGGER AS $maint_sales_summary_bytime$ @@ -3000,7 +3050,7 @@ AS $maint_sales_summary_bytime$ delta_amount_cost numeric(15,2); BEGIN - -- Work out the increment/decrement amount(s). + -- 算出增量/减量数。 IF (TG_OP = 'DELETE') THEN delta_time_key = OLD.time_key; @@ -3010,9 +3060,8 @@ AS $maint_sales_summary_bytime$ ELSIF (TG_OP = 'UPDATE') THEN - -- forbid updates that change the time_key - - -- (probably not too onerous, as DELETE + INSERT is how most - -- changes will be made). + -- 禁止修改 time_key + -- (可能不会太麻烦,因为大部分的更改是用 DELETE + INSERT 完成的)。 IF ( OLD.time_key != NEW.time_key) THEN RAISE EXCEPTION 'Update of time_key : % -> % not allowed', OLD.time_key, NEW.time_key; @@ -3032,8 +3081,7 @@ AS $maint_sales_summary_bytime$ END IF; - - -- Insert or update the summary row with the new values. + -- 插入或更新带有新值的汇总行。 <<insert_update>> LOOP UPDATE sales_summary_bytime @@ -3061,7 +3109,7 @@ AS $maint_sales_summary_bytime$ EXCEPTION WHEN UNIQUE_VIOLATION THEN - -- do nothing + -- 什么也不做 END; END LOOP insert_update; @@ -3095,7 +3143,7 @@ SELECT * FROM sales_summary_bytime; 使用过渡表审计 - 这个示例产生和相同的结果,但并未使用一个为每一行都触发的触发器,而是在把相关信息收集到一个过渡表中之后用了一个只为每个语句引发一次的触发器。当调用语句修改了很多行时,这种方法明显比行触发器方法快。注意我们必须为每一种事件建立一个单独的触发器声明,因为每种情况的REFERENCING子句必须不同。但是这并不能阻止我们使用单一的触发器函数(实际上,使用三个单独的函数会更好,因为可以避免在TG_OP上的运行时测试)。 + 这个示例产生和相同的结果,但并未使用一个为每一行都触发的触发器,而是在把相关信息收集到一个过渡表中之后用了一个只为每个语句引发一次的触发器。当调用语句修改了很多行时,这种方法可能显著快于行触发器方法。注意我们必须为每一种事件建立一个单独的触发器声明,因为每种情况的REFERENCING子句必须不同。但是这并不能阻止我们使用单一的触发器函数(实际上,使用三个单独的函数可能会更好,因为可以避免在TG_OP上的运行时测试)。 @@ -3206,9 +3254,7 @@ CREATE EVENT TRIGGER snitch ON ddl_command_start EXECUTE FUNCTION snitch(); <application>PL/pgSQL</application> 内部机制 - - 这一节讨论了一些PL/pgSQL用户应该知道的一些重要的实现细节。 - + 本节讨论一些实现细节,了解这些细节对 PL/pgSQL 用户通常很重要。 变量替换 @@ -3279,7 +3325,7 @@ CREATE FUNCTION stamp_user(id int, comment text) RETURNS void AS $$ END; $$ LANGUAGE plpgsql; - 在UPDATE命令中,curtimecomment以及id将引用该函数的变量和参数,不管users有没有这些名称的列。注意,我们不得不在WHERE子句中对users.id的引用加以限定,以便让它引用表列。但是我们不需要在UPDATE列表中把对comment的引用限定为一个目标,因为语法上那必须是users的一列。我们可以用下面的方式写一个相同的不依赖于variable_conflict设置的函数: + 在UPDATE命令中,curtimecomment以及id将引用该函数的变量和参数,不管users有没有这些名称的列。注意,我们不得不在WHERE子句中对users.id的引用加以限定,以便让它引用表列。但是我们不需要对UPDATE列表中作为目标的comment引用加以限定,因为语法上那必须是users的一列。我们可以用下面的方式写一个相同的不依赖于variable_conflict设置的函数: CREATE FUNCTION stamp_user(id int, comment text) RETURNS void AS $$ <<fn>> @@ -3318,7 +3364,7 @@ $$ LANGUAGE plpgsql; - PL/pgSQL(更准确地说,是 SPI 管理器)还会尝试缓存与某个预备语句相关的执行计划。如果没有使用缓存计划,那么每次执行该语句时都会生成新的执行计划,而当前参数值(也就是 PL/pgSQL 变量值)可用于优化所选计划。如果该语句没有参数,或者会被执行很多次,SPI 管理器就会考虑创建一个不依赖具体参数值的通用计划,并将其缓存起来供重复使用。通常只有在执行计划对其中引用的 PL/pgSQL 变量值不太敏感时,才会这样做。如果执行计划对参数值非常敏感,那么每次重新生成计划总体上反而更划算。关于预备语句的行为,详见 。 + PL/pgSQL(更准确地说,是 SPI 管理器)还可以尝试缓存与某个预备语句相关的执行计划。如果没有使用缓存计划,那么每次执行该语句时都会生成新的执行计划,而当前参数值(也就是 PL/pgSQL 变量值)可用于优化所选计划。如果该语句没有参数,或者会被执行很多次,SPI 管理器就会考虑创建一个不依赖具体参数值的通用计划,并将其缓存起来供重复使用。通常只有在执行计划对其中引用的 PL/pgSQL 变量值不太敏感时,才会这样做。如果执行计划对参数值非常敏感,那么每次重新生成计划总体上反而更划算。关于预备语句的行为,详见 @@ -3367,7 +3413,7 @@ $$ LANGUAGE plpgsql; - 在logfunc2中,PostgreSQL的主解析器不知道应该把'now'解释成什么类型,因此返回一个text类型的数据值,其中包含字符串now。在确定对本地变量curtime的赋值时,PL/pgSQL解释器通过调用用于该转换的textouttimestamp_in函数,把这个字符串转换为timestamp类型。因此,计算得到的时间戳会按程序员预期在每次执行时更新。虽然这恰好能得到预期结果,但效率并不高,因此使用now()函数仍然是更好的主意。 + 在logfunc2中,PostgreSQL的主解析器不知道应该把'now'解释成什么类型,因此返回一个text类型的数据值,其中包含字符串now。在随后给局部变量curtime赋值时,PL/pgSQL解释器通过调用用于该转换的textouttimestamp_in函数,把这个字符串转换为timestamp类型。因此,计算得到的时间戳会按程序员预期在每次执行时更新。虽然这恰好能得到预期结果,但效率并不高,因此使用now()函数仍然是更好的主意。 @@ -3395,14 +3441,14 @@ $$ LANGUAGE plpgsql; - 另一种开发PL/pgSQL的好方法,是使用有助于过程语言开发的 GUI 数据库访问工具。这类工具的一个例子是pgAdmin,当然也有其他工具。它们通常提供一些方便的特性,例如转义单引号,以及让重新创建和调试函数变得更容易。 + 另一种使用PL/pgSQL进行开发的好方法,是使用有助于过程语言开发的 GUI 数据库访问工具。这类工具的一个例子是pgAdmin,当然也有其他工具。它们通常提供一些方便的特性,例如转义单引号,以及让重新创建和调试函数变得更容易。 引号的处理 - 一个PL/pgSQL函数的代码在一个CREATE FUNCTION中被指定为一个字符串。如果你用通常的方式把该字符串写在单引号中间,那么该函数体中的任何单引号都必须被双写;同样任何反斜线也必须被双写(假定使用了转义字符串语法)。双写引号最多有点冗长,并且在更复杂的情况中代码会变得完全无法理解,因为你很容易发现你需要半打或者更多相邻的引号。我们推荐你转而把函数体写成一个美元引用的字符串(见)。在美元引用方法中,你从不需要双写任何引号。但是要注意为你需要的每一层嵌套选择一个不同的美元引用定界符。例如,你可能把CREATE FUNCTION命令写成: + 一个PL/pgSQL函数的代码在一个CREATE FUNCTION中被指定为一个字符串字面量。如果你用通常的方式把该字符串写在单引号中间,那么该函数体中的任何单引号都必须被双写;同样任何反斜线也必须被双写(假定使用了转义字符串语法)。双写引号本身就很繁琐,并且在更复杂的情况中代码会变得完全无法理解,因为你很容易发现你需要半打或者更多相邻的引号。我们推荐你转而把函数体写成一个美元引用的字符串(见)。在美元引用方法中,你从不需要双写任何引号。但是要注意为你需要的每一层嵌套选择一个不同的美元引用定界符。例如,你可能把CREATE FUNCTION命令写成: CREATE OR REPLACE FUNCTION testfunc(integer) RETURNS integer AS $PROC$ .... @@ -3437,7 +3483,7 @@ CREATE FUNCTION foo() RETURNS integer AS ' - 用于函数体内的字符串,例如: + 用于函数体内的字符串字面量,例如: a_output := ''Blah''; SELECT * FROM users WHERE f_name=''foobar''; @@ -3447,7 +3493,7 @@ SELECT * FROM users WHERE f_name=''foobar''; a_output := 'Blah'; SELECT * FROM users WHERE f_name='foobar'; - 这恰好就是PL/pgSQL在两种情况中会看到的。 + 这恰好就是PL/pgSQL解析器在两种情况中会看到的。 @@ -3469,7 +3515,7 @@ a_output := a_output || '' AND name LIKE ''''foobar'''' AND xyz'' a_output := a_output || $$ AND name LIKE 'foobar' AND xyz$$ - 要小心在这周围的任何美元引用定界符不只是$$。 + 要小心在这周围的任何美元引用定界符都不能是$$ @@ -3500,7 +3546,7 @@ a_output := a_output || $$ AND name LIKE 'foobar'$$ - 当你想在一个字符串常量(占 8 个引号)中有两个单引号时并且这会挨着该字符串常量的末尾(另外 2 个)。如果你正在写一个产生其他函数的函数(如中),你将很可能只需要这种。例如: + 当字符串常量中需要两个单引号(这需要 8 个引号),而且它们紧邻该字符串常量的末尾(还需 2 个引号)时。通常只有在编写生成其他函数的函数时(如所示),才会需要这种写法。例如: a_output := a_output || '' if v_'' || referrer_keys.kind || '' like '''''''''' @@ -3541,11 +3587,13 @@ a_output := a_output || $$ if v_$$ || referrer_keys.kind || $$ like '$$ 因此建议你在一个单独的开发环境中进行测试。 - - 根据需要设置 plpgsql.extra_warningsplpgsql.extra_errors,适当情况下,在开发和/或测试环境中可以设置为 "all"。 - + 建议在开发和/或测试环境中,根据需要将 plpgsql.extra_warningsplpgsql.extra_errors 设置为 "all" - 这些额外检查通过配置变量启用,其中plpgsql.extra_warnings用于警告,plpgsql.extra_errors用于错误。两者都可以设为逗号分隔的检查项列表、"none""all"。默认值为"none"。当前可用的检查包括: + + 这些额外的检查通过配置变量plpgsql.extra_warnings来启用警告, + 以及plpgsql.extra_errors来启用错误。两者都可以设置为逗号分隔的检查列表,"none""all"。 + 默认值为"none"。目前可用的检查列表包括: + shadowed_variables @@ -3577,7 +3625,10 @@ a_output := a_output || $$ if v_$$ || referrer_keys.kind || $$ like '$$ - 下面的例子展示了此设置的效果:plpgsql.extra_warnings设为shadowed_variables: + + + 以下示例显示了将plpgsql.extra_warnings设置为 + shadowed_variables的效果: SET plpgsql.extra_warnings TO 'shadowed_variables'; @@ -3592,7 +3643,9 @@ WARNING: variable "f1" shadows a previously defined variable LINE 3: f1 int; ^ CREATE FUNCTION -下面的例子展示了另一设置的效果:plpgsql.extra_warnings设为strict_multi_assignment: + + 以下示例显示了将plpgsql.extra_warnings设置为 + strict_multi_assignment的效果: SET plpgsql.extra_warnings TO 'strict_multi_assignment'; @@ -3654,7 +3707,7 @@ HINT: Make sure the query returns the exact list of columns. - 在PostgreSQL中,函数体必须写成字符串文本。因此你需要使用美元符引用或者转义函数体中的单引号(见)。 + 在PostgreSQL中,函数体必须写成字符串字面量。因此你需要使用美元符引用或者转义函数体中的单引号(见)。 @@ -3743,13 +3796,13 @@ show errors; - 在PostgreSQL中,函数体被认为是一个字符串,所以你需要使用引号或者美元符号包围它。这代替了Oracle 方法中的用于终止的/。 + 在PostgreSQL中,函数体被认为是一个字符串字面量,所以你需要使用引号或者美元引用定界符包围它。这代替了Oracle 方法中的用于终止的/ - 在PostgreSQL中没有show errors命令, 并且也不需要这个命令,因为错误是自动报告的。 + 在PostgreSQL中没有show errors命令, 并且也不需要这个命令,因为错误是自动报告的。 @@ -3780,9 +3833,7 @@ $$ LANGUAGE plpgsql; 从<application>PL/SQL</application>移植一个创建另一个函数的函数到<application>PL/pgSQL</application> - - 下面的过程从一个SELECT语句抓取行,并且为了效率而构建一个带有IF语句中结果的大型函数。 - + 下面的过程从 SELECT 语句读取行,并将结果写入 IF 语句,从而构造一个大型函数,以提高效率。 这是 Oracle 版本: @@ -3860,12 +3911,14 @@ $func$ LANGUAGE plpgsql; 下面的Oracle PL/SQL 过程被用来解析一个 URL 并且返回一些元素(主机、路径和查询)。 - 这是 Oracle 版本: + + 这是 Oracle 版本: + CREATE OR REPLACE PROCEDURE cs_parse_url( v_url IN VARCHAR2, - v_host OUT VARCHAR2, -- This will be passed back - v_path OUT VARCHAR2, -- This one too - v_query OUT VARCHAR2) -- And this one + v_host OUT VARCHAR2, -- 这个值将被返回 + v_path OUT VARCHAR2, -- 这个也是 + v_query OUT VARCHAR2) -- 还有这个 IS a_pos1 INTEGER; a_pos2 INTEGER; @@ -3901,13 +3954,14 @@ show errors; - 下面是一种可行的移植写法,目标语言为PL/pgSQL: + + 这里给出一种可能的 PL/pgSQL 写法: CREATE OR REPLACE FUNCTION cs_parse_url( v_url IN VARCHAR, - v_host OUT VARCHAR, -- This will be passed back - v_path OUT VARCHAR, -- This one too - v_query OUT VARCHAR) -- And this one + v_host OUT VARCHAR, -- 这个值将被返回 + v_path OUT VARCHAR, -- 这个也是 + v_query OUT VARCHAR) -- 还有这个 AS $$ DECLARE a_pos1 INTEGER; @@ -3940,20 +3994,26 @@ BEGIN v_query := substr(v_url, a_pos1 + 1); END; $$ LANGUAGE plpgsql; -该函数可以这样使用: + + + 这个函数可以这样使用: + SELECT * FROM cs_parse_url('http://foobar.com/query.cgi?baz'); - 展示了如何移植一个使用了多种 Oracle 特性的过程。 + 展示了如何移植一个使用了多种 Oracle 专属特性的过程。 从<application>PL/SQL</application>移植一个过程到<application>PL/pgSQL</application> - Oracle 版本: + + Oracle 版本: + + CREATE OR REPLACE PROCEDURE cs_create_job(v_job_id IN INTEGER) IS a_running_job_count INTEGER; BEGIN @@ -3962,7 +4022,7 @@ BEGIN SELECT count(*) INTO a_running_job_count FROM cs_jobs WHERE end_stamp IS NULL; IF a_running_job_count > 0 THEN - COMMIT; -- free lock + COMMIT; -- 释放锁 raise_application_error(-20000, 'Unable to create a new job: a job is currently running.'); END IF; @@ -3973,7 +4033,7 @@ BEGIN BEGIN INSERT INTO cs_jobs (job_id, start_stamp) VALUES (v_job_id, now()); EXCEPTION - WHEN dup_val_on_index THEN NULL; -- don't worry if it already exists + WHEN dup_val_on_index THEN NULL; -- 如果已经存在也不用担心 END; COMMIT; END; @@ -3982,7 +4042,8 @@ show errors - 下面展示了如何移植这个过程,目标语言为PL/pgSQL: + + 下面展示了如何将这个过程移植到PL/pgSQL CREATE OR REPLACE PROCEDURE cs_create_job(v_job_id integer) AS $$ @@ -3994,7 +4055,7 @@ BEGIN SELECT count(*) INTO a_running_job_count FROM cs_jobs WHERE end_stamp IS NULL; IF a_running_job_count > 0 THEN - COMMIT; -- free lock + COMMIT; -- 释放锁 RAISE EXCEPTION 'Unable to create a new job: a job is currently running'; -- END IF; @@ -4005,7 +4066,7 @@ BEGIN INSERT INTO cs_jobs (job_id, start_stamp) VALUES (v_job_id, now()); EXCEPTION WHEN unique_violation THEN -- - -- don't worry if it already exists + -- 如果已经存在不要担心 END; COMMIT; END; @@ -4056,7 +4117,7 @@ EXCEPTION END; - 如果你正在移植一个以这种方式使用SAVEPOINTROLLBACK TO的 Oracle 过程,工作会比较简单:只要忽略SAVEPOINTROLLBACK TO即可。如果你的 Oracle 过程以不同方式使用SAVEPOINTROLLBACK TO,那就需要认真思考了。 + 如果你正在移植一个以这种方式使用SAVEPOINTROLLBACK TO的 Oracle 过程,工作会比较简单:只要省略SAVEPOINTROLLBACK TO即可。如果你的 Oracle 过程以不同方式使用SAVEPOINTROLLBACK TO,那就需要认真思考了。 @@ -4073,11 +4134,11 @@ END; 优化 <application>PL/pgSQL</application> 函数 - PostgreSQL提供了两种函数创建修饰符来优化执行:volatility(对于给定的相同参数,函数是否总是返回相同的结果)以及strictness (如果任何参数为空,函数是否返回空)。详见参考页。 + PostgreSQL提供了两种函数创建修饰符来优化执行:volatility(对于给定的相同参数,函数是否总是返回相同的结果)以及strictness (如果任何参数为空值,函数是否返回空值)。详见参考页。 - 在利用这些优化属性时,你的CREATE FUNCTION语句应该看起来像这样: + 在利用这些优化属性时,你的CREATE FUNCTION语句可能像这样: CREATE FUNCTION foo(...) RETURNS integer AS $$ diff --git a/zh/12/plpython.sgml b/zh/12/plpython.sgml index 4a9f3ca8..8330b19f 100644 --- a/zh/12/plpython.sgml +++ b/zh/12/plpython.sgml @@ -110,7 +110,7 @@ CREATE FUNCTION funcname (argument-list) RETURNS return-type AS $$ - # PL/Python function body + # PL/Python 函数体 $$ LANGUAGE plpythonu; @@ -150,7 +150,7 @@ def __plpython_procedure_pymax_23456(): CREATE FUNCTION pystrip(x text) RETURNS text AS $$ - x = x.strip() # error + x = x.strip() # 错误 return x $$ LANGUAGE plpythonu; @@ -160,7 +160,7 @@ CREATE FUNCTION pystrip(x text) RETURNS text AS $$ global x - x = x.strip() # ok now + x = x.strip() # 现在可以正常工作 return x $$ LANGUAGE plpythonu; @@ -176,7 +176,10 @@ $$ LANGUAGE plpythonu; 数据类型映射 - 调用 PL/Python 函数时,参数会从 PostgreSQL 数据类型转换为相应的 Python 类型: + + 调用 PL/Python 函数时,其参数会从 PostgreSQL 数据类型转换为相应的 Python 类型: + + PostgreSQL boolean 会转换为 Python bool。 @@ -213,8 +216,9 @@ $$ LANGUAGE plpythonu; - 所有其他数据类型,包括 PostgreSQL 字符串类型, - 都会转换为 Python str(和所有 Python 字符串一样,都是 Unicode)。 + 所有其他数据类型,包括 PostgreSQL 字符串类型,都会转换为 Python + str。在 Python 2 中,该字符串采用 PostgreSQL 服务器编码; + 在 Python 3 中,它与所有字符串一样,都是 Unicode 字符串。 @@ -226,7 +230,10 @@ $$ LANGUAGE plpythonu; - PL/Python 函数返回时,返回值按以下规则转换为该函数声明的 PostgreSQL 返回数据类型: + + 当 PL/Python 函数返回时,其返回值会按如下方式转换成该函数声明的 PostgreSQL 返回数据类型: + + 当 PostgreSQL 返回类型为boolean时,返回值会按照Python规则进行真值判定。也就是说,0 和空字符串为假,但值得注意的是,'f' 为真。 @@ -243,7 +250,10 @@ $$ LANGUAGE plpythonu; - 字符串在传给 PostgreSQL 时,会自动转换为 PostgreSQL 服务器编码。 + Python 2 中的字符串传给 PostgreSQL 时,必须采用 PostgreSQL 服务器编码。 + 在当前服务器编码中无效的字符串会引发错误,但并非所有编码不匹配都能被检测到, + 因此处理不当仍可能产生乱码数据。Unicode 字符串会自动转换为正确的编码, + 因而使用它们可能更安全、更方便。在 Python 3 中,所有字符串都是 Unicode 字符串。 @@ -252,7 +262,10 @@ $$ LANGUAGE plpythonu; 对于非标量数据类型,请参见下文。 - 注意,如果声明的 PostgreSQL 返回类型与实际返回对象的 Python 数据类型在逻辑上不匹配,系统不会提示;无论如何都会转换该值。 + + + 请注意,即使声明的 PostgreSQL 返回类型与实际返回对象的 Python 数据类型在逻辑上并不匹配,也不会报错;无论如何该值都会被转换。 + @@ -354,12 +367,19 @@ $$ LANGUAGE plpythonu; - 从 Python 函数返回行类型或复合类型,有多种方式。以下示例假定已定义: + + 有多种方法可以从 Python 函数返回行类型或复合类型。以下示例假定我们有: + + CREATE TYPE named_value AS ( name text, value integer ); -复合结果可以用以下形式返回: + + + 复合结果可以按以下形式返回: + + 序列类型(元组或列表,但不能是集合,因为集合不可通过索引访问) @@ -368,7 +388,7 @@ CREATE FUNCTION make_pair (name text, value integer) RETURNS named_value AS $$ return ( name, value ) - # or alternatively, as list: return [ name, value ] + # 也可以使用列表: return [ name, value ] $$ LANGUAGE plpythonu; 要为某一列返回 SQL 空值,请将 None 放在对应位置。 @@ -406,7 +426,7 @@ AS $$ self.value = v return named_value(name, value) - # or simply + # 或者简写为 class nv: pass nv.name = name nv.value = value @@ -444,12 +464,19 @@ CALL python_triple(5, 10); 集合返回函数 - 一个 PL/Python 函数也可以返回标量类型或复合类型的集合。实现方式有多种,因为返回对象在内部会被转换为迭代器。以下示例假定已定义复合类型: + + PL/Python函数也可以返回标量类型或复合类型的集合。实现方式有多种,因为返回的对象在内部会被转换成一个迭代器。以下示例假定我们有如下复合类型: + + CREATE TYPE greeting AS ( how text, who text ); -集合结果可以通过以下形式返回: + + + 集合结果可以通过以下对象返回: + + 序列类型(元组、列表、集合) @@ -458,8 +485,8 @@ CREATE TYPE greeting AS ( CREATE FUNCTION greet (how text) RETURNS SETOF greeting AS $$ - # return tuple containing lists as composite types - # all other combinations work also + # 返回包含列表的元组,以列表表示复合类型 + # 其他组合方式也都可用 return ( [ how, "World" ], [ how, "PostgreSQL" ], [ how, "PL/Python" ] ) $$ LANGUAGE plpythonu; @@ -517,7 +544,7 @@ $$ LANGUAGE plpythonu; - 也支持带OUT参数的返回集函数(使用RETURNS SETOF record)。例如: + 也支持带OUT参数的集合返回函数(使用RETURNS SETOF record)。例如: CREATE FUNCTION multiout_simple_setof(n integer, OUT integer, OUT integer) RETURNS SETOF record AS $$ return [(1, 2)] * n @@ -552,7 +579,7 @@ SELECT * FROM multiout_simple_setof(3); DO $$ - # PL/Python code + # PL/Python 代码 $$ LANGUAGE plpythonu; @@ -799,7 +826,7 @@ CREATE FUNCTION usesavedplan() RETURNS trigger AS $$ else: plan = plpy.prepare("SELECT 1") SD["plan"] = plan - # rest of function + # 函数的其余部分 $$ LANGUAGE plpythonu; @@ -816,11 +843,11 @@ $$ LANGUAGE plpythonu; - 游标对象提供fetch方法,它接受一个整数参数并返回结果对象。每次调用fetch,返回对象都会包含下一批行,数量不会超过该参数值。一旦所有行都已取完,fetch就会开始返回空结果对象。游标对象还提供迭代器接口,每次产生一行,直到所有行为止。以这种方式获取的数据不会作为结果对象返回,而是以字典形式返回,每个字典对应一行结果。 + 游标对象提供fetch方法,它接受一个整数参数并返回结果对象。每次调用fetch,返回对象都会包含下一批行,数量不会超过该参数值。一旦所有行都已取完,fetch就会开始返回空结果对象。游标对象还提供迭代器接口,每次产生一行,直到取完所有行。以这种方式获取的数据不会作为结果对象返回,而是以字典形式返回,每个字典对应一行结果。 - 下面示例展示了如何处理大表中的数据: + 下面示例展示了处理大表中数据的两种方式: CREATE FUNCTION count_odd_iterator() RETURNS integer AS $$ odd = 0 @@ -846,7 +873,7 @@ $$ LANGUAGE plpythonu; CREATE FUNCTION count_odd_prepared() RETURNS integer AS $$ odd = 0 plan = plpy.prepare("select num from largetable where num % $1 <> 0", ["integer"]) -rows = list(plpy.cursor(plan, [2])) # or: = list(plan.cursor([2])) +rows = list(plpy.cursor(plan, [2])) # 或者:= list(plan.cursor([2])) return len(rows) $$ LANGUAGE plpythonu; @@ -950,9 +977,9 @@ $$ LANGUAGE plpythonu; - 旧式 Python 2 用法 + 较早的 Python 版本 - 使用 with 关键字的上下文管理器语法,从 Python 2.6 起默认可用。如果 PL/Python 使用更早的 Python 版本,仍然可以使用显式子事务,只是没那么方便。可以调用子事务管理器的 __enter____exit__ 函数,也可以使用它们的便捷别名 enterexit。转账示例函数可以写成: + 使用 with 关键字的上下文管理器语法,从 Python 2.6 起默认可用。如果 PL/Python 使用更早的 Python 版本,仍然可以使用显式子事务,只是没那么方便。可以通过便捷别名 enterexit,调用子事务管理器的 __enter____exit__ 函数。转账示例函数可以写成: CREATE FUNCTION transfer_funds_old() RETURNS void AS $$ try: subxact = plpy.subtransaction() @@ -1016,7 +1043,7 @@ CALL transaction_test1(); - 实用函数 + 辅助函数 plpy模块还提供以下函数: @@ -1070,7 +1097,7 @@ PL/Python function "raise_custom_exception" - 另一组实用函数是plpy.quote_literal(string)plpy.quote_nullable(string)以及plpy.quote_ident(string)。它们等价于中描述的内置引用函数。在构造临时查询时,这些函数很有用。中动态 SQL 的一个 PL/Python 等价写法如下: + 另一组辅助函数是plpy.quote_literal(string)plpy.quote_nullable(string)以及plpy.quote_ident(string)。它们等价于中描述的内置加引号函数。在构造临时查询时,这些函数很有用。中动态 SQL 的一个 PL/Python 等价写法如下: plpy.execute("UPDATE tbl SET %s = %s WHERE key = %s" % ( plpy.quote_ident(colname), diff --git a/zh/12/pltcl.sgml b/zh/12/pltcl.sgml index 04f087d3..5732c138 100644 --- a/zh/12/pltcl.sgml +++ b/zh/12/pltcl.sgml @@ -12,7 +12,7 @@ - PL/Tcl 是一种适用于 PostgreSQL 数据库系统的可载入的过程语言,它允许使用 Tcl 语言 来编写 PostgreSQL 函数和过程。 + PL/Tcl 是一种适用于 PostgreSQL 数据库系统的可加载的过程语言,它允许使用 Tcl 语言 来编写 PostgreSQL 函数和过程。 @@ -53,7 +53,7 @@ CREATE FUNCTION funcname (argument-types) RETURNS return-type AS $$ - # PL/Tcl function body + # PL/Tcl 函数体 $$ LANGUAGE pltcl; @@ -74,11 +74,11 @@ CREATE FUNCTION tcl_max(integer, integer) RETURNS integer AS $$ $$ LANGUAGE pltcl STRICT; - 注意STRICT子句,它让我们不必考虑空输入值:如果传入的是空值,函数根本不会被调用,而是会自动返回空结果。 + 注意STRICT子句,它让我们不必考虑空值输入:如果传入的是空值,函数根本不会被调用,而是会自动返回空值结果。 - 在非严格函数中,如果某个参数的实际值为空,对应的$n变量会被设置为空串。要检测某个特定参数是否为空,可使用函数argisnull。例如,假设我们希望在tcl_max的两个参数中一个为空、一个非空时返回非空参数,而不是返回空值: + 在非严格函数中,如果某个参数的实际值为空值,对应的$n变量会被设置为空串。要检测某个特定参数是否为空值,可使用函数argisnull。例如,假设我们希望在tcl_max的两个参数中一个为空值、一个非空值时返回非空值参数,而不是返回空值: CREATE FUNCTION tcl_max(integer, integer) RETURNS integer AS $$ @@ -98,7 +98,7 @@ $$ LANGUAGE pltcl; - 复合类型参数会作为 Tcl 数组传递给函数。数组元素名就是该复合类型的属性名。如果传入行中的某个属性为 NULL,它就不会出现在数组中。下面是一个示例: + 复合类型参数会作为 Tcl 数组传递给函数。数组元素名就是该复合类型的属性名。如果传入行中的某个属性为空值,它就不会出现在数组中。下面是一个示例: CREATE TABLE employee ( @@ -184,7 +184,7 @@ $$ LANGUAGE pltcl; PL/Tcl 中的数据值 - 提供给 PL/Tcl 函数代码的参数值,只是将输入参数转换成文本形式(就像用SELECT语句将它们显示出来一样)。反过来,returnreturn_next命令会接受任何字符串,只要它是该函数声明结果类型或组合结果类型中指定列的可接受输入格式。 + 提供给 PL/Tcl 函数代码的参数值,只是将输入参数转换成文本形式(就像用SELECT语句将它们显示出来一样)。反过来,returnreturn_next命令会接受任何字符串,只要它是该函数声明结果类型或复合结果类型中指定列的可接受输入格式。 @@ -194,8 +194,8 @@ $$ LANGUAGE pltcl; PL/Tcl 中的全局数据 - global data - in PL/Tcl + 全局数据 + 在 PL/Tcl 中 @@ -222,14 +222,17 @@ $$ LANGUAGE pltcl; 从 PL/Tcl 访问数据库 - 本节遵循 Tcl 的惯例,在语法概要中用问号而不是方括号表示可选元素。在 PL/Tcl 函数体中可以使用以下命令访问数据库: + + 在本节中,我们遵循 Tcl 的通常约定,用问号而不是方括号来表示语法摘要中的可选元素。下列命令可用于从 PL/Tcl 函数体中访问数据库: + + spi_exec -count n -array name command loop-body - 执行以字符串形式给出的 SQL 命令。命令出错时会引发错误。否则,spi_exec的返回值是该命令处理的行数(选出、插入、更新或删除的行),如果命令是实用程序语句则返回零。此外,如果命令是SELECT语句,则所选列的值会按下文所述放入 Tcl 变量中。 + 执行以字符串形式给出的 SQL 命令。命令出错时会引发错误。否则,spi_exec的返回值是该命令处理的行数(选出、插入、更新或删除的行),如果命令是工具语句则返回零。此外,如果命令是SELECT语句,则所选列的值会按下文所述放入 Tcl 变量中。 @@ -270,7 +273,7 @@ spi_exec -array C "SELECT * FROM pg_class" { - 如果查询结果中的某一列为空,则对应的目标变量会被unset,而不是被设值。 + 如果查询结果中的某一列为空值,则对应的目标变量会被unset,而不是被设值。 @@ -282,7 +285,7 @@ spi_exec -array C "SELECT * FROM pg_class" { 准备并保存一个查询计划以供后续执行。保存的计划会在当前会话的整个生命周期内保留。 准备查询 - 在PL/Tcl中 + 在 PL/Tcl 中 @@ -312,7 +315,7 @@ spi_exec -array C "SELECT * FROM pg_class" { 可选的-nulls值是由空格和'n'字符组成的字符串,用来告诉spi_execp哪些参数是空值。 - 如果给出,它的长度必须与value-list完全相同。如果未给出,则所有参数值都视为非空。 + 如果给出,它的长度必须与value-list完全相同。如果未给出,则所有参数值都视为非空值。 @@ -326,7 +329,7 @@ spi_exec -array C "SELECT * FROM pg_class" { CREATE FUNCTION t1_count(integer, integer) RETURNS integer AS $$ if {![ info exists GD(plan) ]} { - # prepare the saved plan on the first call + # 在首次调用时准备并保存计划 set GD(plan) [ spi_prepare \ "SELECT count(*) AS cnt FROM t1 WHERE num >= \$1 AND num <= \$2" \ [ list int4 int4 ] ] @@ -361,7 +364,7 @@ $$ LANGUAGE pltcl; 将给定字符串中的所有单引号和反斜杠字符都加倍。 - 这可用于安全地引用那些要插入到传给spi_execspi_prepare的 SQL 命令中的字符串。 + 这可用于安全地为那些要插入到传给spi_execspi_prepare的 SQL 命令中的字符串加引号。 例如,考虑如下 SQL 命令字符串: @@ -387,7 +390,7 @@ SELECT 'doesn''t' AS ret "SELECT '[ quote $val ]' AS ret" - spi_execp的一个优点是,你不必像这样对参数值做引用,因为这些参数永远不会作为 SQL 命令字符串的一部分被解析。 + spi_execp的一个优点是,你不必像这样给参数值加引号,因为这些参数永远不会作为 SQL 命令字符串的一部分被解析。 @@ -397,7 +400,7 @@ SELECT 'doesn''t' AS ret elog level msg elog - 在PL/Tcl中 + 在 PL/Tcl 中 @@ -428,14 +431,17 @@ SELECT 'doesn''t' AS ret PL/Tcl 中的触发器函数 - trigger - in PL/Tcl + 触发器 + 在 PL/Tcl 中 触发器函数也可以用 PL/Tcl 编写。PostgreSQL要求,凡是要作为触发器调用的函数,都必须声明为无参数且返回类型为trigger - 触发器管理器的信息通过以下变量传入函数体: + + 来自触发器管理器的信息会通过下列变量传递给函数体: + + $TG_name @@ -513,7 +519,7 @@ SELECT 'doesn''t' AS ret $NEW - 对于INSERTUPDATE动作,这是一个包含新表行值的关联数组;对于DELETE则为空。该数组以列名为索引。值为 NULL 的列不会出现在数组中。对于语句级触发器,不会设置这个变量。 + 对于INSERTUPDATE动作,这是一个包含新表行值的关联数组;对于DELETE则为空。该数组以列名为索引。值为空值的列不会出现在数组中。对于语句级触发器,不会设置这个变量。 @@ -522,7 +528,7 @@ SELECT 'doesn''t' AS ret $OLD - 对于UPDATEDELETE动作,这是一个包含旧表行值的关联数组;对于INSERT则为空。该数组以列名为索引。值为 NULL 的列不会出现在数组中。对于语句级触发器,不会设置这个变量。 + 对于UPDATEDELETE动作,这是一个包含旧表行值的关联数组;对于INSERT则为空。该数组以列名为索引。值为空值的列不会出现在数组中。对于语句级触发器,不会设置这个变量。 @@ -585,20 +591,23 @@ CREATE TRIGGER trig_mytab_modcount BEFORE INSERT OR UPDATE ON mytab PL/Tcl 中的事件触发器函数 - event trigger - in PL/Tcl + 事件触发器 + 在 PL/Tcl 中 事件触发器函数也可以用 PL/Tcl 编写。PostgreSQL要求,凡是要作为事件触发器调用的函数,都必须声明为无参数且返回类型为event_trigger - 触发器管理器的信息通过以下变量传入函数体: + + 来自触发器管理器的信息会通过下列变量传递给函数体: + + $TG_event - 触发器因其而被触发的事件名称。 + 该触发器所针对的事件名称。 @@ -607,7 +616,7 @@ CREATE TRIGGER trig_mytab_modcount BEFORE INSERT OR UPDATE ON mytab $TG_tag - 触发器因其而被触发的命令标签。 + 该触发器所针对的命令标签。 @@ -615,10 +624,13 @@ CREATE TRIGGER trig_mytab_modcount BEFORE INSERT OR UPDATE ON mytab - 事件触发器函数的返回值会被忽略。 + 触发器函数的返回值会被忽略。 - 下面是一个简单的事件触发器函数示例,每当执行受支持的命令时,它只发出一条 NOTICE 消息: + + 下面是一个小型事件触发器函数示例。每当执行受支持的命令时,它都会简单地发出一条NOTICE消息: + + CREATE OR REPLACE FUNCTION tclsnitch() RETURNS event_trigger AS $$ elog NOTICE "tclsnitch: $TG_event $TG_tag" $$ LANGUAGE pltcl; @@ -632,8 +644,8 @@ CREATE EVENT TRIGGER tcl_a_snitch ON ddl_command_start EXECUTE FUNCTION tclsnitc PL/Tcl 中的错误处理 - exceptions - in PL/Tcl + 异常 + 在 PL/Tcl 中 @@ -661,9 +673,9 @@ if {[catch { spi_exec $sql_command }]} { if {[lindex $::errorCode 0] == "POSTGRES"} { array set errorArray $::errorCode if {$errorArray(condition) == "undefined_table"} { - # deal with missing table + # 处理表不存在的情况 } else { - # deal with some other type of SQL error + # 处理其他类型的 SQL 错误 } } } @@ -677,8 +689,8 @@ if {[catch { spi_exec $sql_command }]} { PL/Tcl 中的显式子事务 - subtransactions - in PL/Tcl + 子事务 + 在 PL/Tcl 中 @@ -776,7 +788,7 @@ CALL transaction_test1(); pltcl.start_proc (string) - pltcl.start_proc configuration parameter + pltcl.start_proc 配置参数 @@ -804,7 +816,7 @@ CALL transaction_test1(); pltclu.start_proc (string) - pltclu.start_proc configuration parameter + pltclu.start_proc 配置参数 @@ -823,7 +835,7 @@ CALL transaction_test1(); Tcl 过程名 - 在PostgreSQL中,只要参数个数或参数类型不同,就可以复用同一个函数名。不过,Tcl 要求所有过程名都必须不同。PL/Tcl 通过让内部 Tcl 过程名包含系统表pg_proc中该函数的对象 ID 来解决这个问题。因此,名称相同而参数类型不同的PostgreSQL函数,也会对应不同的 Tcl 过程。这通常不是 PL/Tcl 程序员需要关心的事情,但在调试时可能会看到。 + 在PostgreSQL中,只要参数个数或参数类型不同,就可以复用同一个函数名。不过,Tcl 要求所有过程名都必须不同。PL/Tcl 处理这一问题的方式是:在内部 Tcl 过程名中包含系统表 pg_proc 中的函数对象 ID 作为其名称的一部分。因此,名称相同但参数类型不同的PostgreSQL函数,也会对应不同的 Tcl 过程。这通常不是 PL/Tcl 程序员需要关心的事情,但在调试时可能会看见。 diff --git a/zh/12/postgres-fdw.sgml b/zh/12/postgres-fdw.sgml index d5a84a14..9909de16 100644 --- a/zh/12/postgres-fdw.sgml +++ b/zh/12/postgres-fdw.sgml @@ -243,7 +243,7 @@ 该选项是一个以逗号分隔的 PostgreSQL 扩展 名称列表,这些扩展必须在本地和远程服务器上都已安装且版本兼容。 - 属于列出扩展且为 immutable 的函数和操作符,将被视为可下推到远程服务器 + 属于列出扩展且不可变的函数和操作符,将被视为可下推到远程服务器 执行。该选项只能为外部服务器指定,不能按表指定。 @@ -425,8 +425,7 @@ - 请注意,postgres_fdw 当前不支持将远程事务预备为 - 两阶段提交。 + 请注意,postgres_fdw 当前不支持为两阶段提交预备远程事务。 @@ -437,9 +436,9 @@ postgres_fdw 会尽力优化远程查询,以减少从外部 服务器传输的数据量。这是通过将查询的 WHERE 子句发送到 远程服务器执行,以及不获取当前查询不需要的表列来实现的。为降低查询被 - 错误执行的风险,除非 WHERE 子句仅使用内置数据类型、 - 操作符和函数,或属于外部服务器 extensions 选项列出的 - 扩展,否则不会将其发送到远程服务器。这类子句中的操作符和函数还必须是 + 错误执行的风险,只有当 WHERE 子句使用的所有数据类型、 + 操作符和函数都是内置的,或属于外部服务器 extensions + 选项列出的扩展时,才会将该子句发送到远程服务器。这类子句中的操作符和函数还必须是 IMMUTABLE。对于 UPDATEDELETE 查询,postgres_fdw 会在 查询中不存在无法发送到远程服务器的 WHERE 子句、没有 diff --git a/zh/12/protocol.sgml b/zh/12/protocol.sgml index 32e8fe91..70606ef1 100644 --- a/zh/12/protocol.sgml +++ b/zh/12/protocol.sgml @@ -758,7 +758,12 @@ SELCT 1/0; 只要后端认为前端应当知晓的某个参数的当前有效值发生变化,就会生成 ParameterStatus 消息。最常见的情况是响应前端执行的SET命令,这种情况实际上是同步的;但也可能是管理员修改了配置文件,然后向服务器发送SIGHUP信号,从而导致参数状态发生变化。同样,如果某条SET命令被回滚,也会生成适当的 ParameterStatus 消息,用于报告当前生效的值。 - 目前,会为一组固定的参数生成 ParameterStatus,包括 server_versionserver_encodingclient_encodingapplication_nameis_superusersession_authorizationDateStyleIntervalStyleTimeZoneinteger_datetimesstandard_conforming_strings。(8.0 之前的版本不报告 server_encodingTimeZoneinteger_datetimes;8.1 之前的版本不报告 standard_conforming_strings;8.4 之前的版本不报告 IntervalStyle;9.0 之前的版本不报告 application_name。)注意,server_versionserver_encodinginteger_datetimes 是启动后不能改变的伪参数。这组参数将来可能变化,甚至可能变为可配置。因此,前端应直接忽略其不理解或不关心的参数的 ParameterStatus。 + + 目前,会为一组固定的参数生成 ParameterStatus,参数如下: + server_versionserver_encodingclient_encodingapplication_nameis_superusersession_authorizationDateStyleIntervalStyleTimeZoneinteger_datetimesstandard_conforming_strings。 + (8.0 之前的版本不报告 server_encodingTimeZoneinteger_datetimes;8.1 之前的版本不报告 standard_conforming_strings;8.4 之前的版本不报告 IntervalStyle;9.0 之前的版本不报告 application_name。) + 注意,server_versionserver_encodinginteger_datetimes 是启动后不能改变的伪参数。这组参数将来可能变化,甚至可能变为可配置。因此,前端应直接忽略其不理解或不关心的参数的 ParameterStatus。 + 如果前端发出一个LISTEN命令, 那么无论何时在为同一个通道名NOTIFY时,后端将发送一个NotificationResponse消息(不要和NoticeResponse搞混!)。 @@ -1161,7 +1166,9 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" output_plugin - 用于逻辑解码的输出插件名称(参见 )。 + + 用于逻辑解码的输出插件的名称(参见)。 + @@ -1169,8 +1176,8 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" TEMPORARY - 该命令导出的快照标识符。该快照在此连接上执行下一条命令之前,或复制连接关闭之前有效。如果所创建的是物理复制槽,则为 null。 - + 指定此复制槽为临时槽。临时槽不会保存到磁盘,并且在错误或会话结束时会自动删除。 + @@ -1191,11 +1198,14 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 作为对此命令的响应,服务器会发送仅含一行的结果集,其中包含以下字段: + + 在响应此命令时,服务器将发送一个包含以下字段的单行结果集: slot_name (text) - 新建复制槽的名称。 + + 新创建的复制槽的名称。 + @@ -1212,7 +1222,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" snapshot_name (text) - 该命令导出的快照标识符。该快照在此连接上执行下一条命令之前,或复制连接关闭之前有效。如果所创建的是物理复制槽,则为 null。 + 该命令导出的快照标识符。该快照在此连接上执行下一条命令之前,或复制连接关闭之前有效。如果所创建的是物理复制槽,则为空值。 @@ -1221,7 +1231,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" output_plugin (text) - 新建复制槽所使用的输出插件名称。如果所创建的是物理复制槽,则为 null。 + 新建复制槽所使用的输出插件名称。如果所创建的是物理复制槽,则为空值。 @@ -1537,14 +1547,19 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" BASE_BACKUP [ LABEL 'label' ] [ PROGRESS ] [ FAST ] [ WAL ] [ NOWAIT ] [ MAX_RATE rate ] [ TABLESPACE_MAP ] [ NOVERIFY_CHECKSUMS ] BASE_BACKUP - 指示服务器开始流式传输基础备份。系统会在备份开始前自动进入备份模式,在备份完成后退出该模式。接受以下选项: + + 指示服务器开始流式传输基础备份。 + 在备份开始之前,系统将自动进入备份模式,并在备份完成后退出备份模式。 + 接受以下选项: + + LABEL 'label' 设置备份的标签。如果未指定,则将使用base backup作为备份标签。 - 标签的引用规则与打开的标准SQL字符串相同。 + 标签的引号使用规则与打开的标准SQL字符串相同。 @@ -1553,8 +1568,12 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" PROGRESS - 请求生成进度报告所需的信息。这将在每个表空间的头部发回大致大小,可用于计算流式传输的完成进度。此大小通过在传输开始之前枚举所有文件大小来计算,因此可能对性能有负面影响。特别是在第一个数据被发出之前可能需要更长的时间。 - + 请求生成进度报告所需的信息。这将在每个表空间的首部发送一个近似大小, + 可用于计算流式传输的进度。这是通过在传输开始之前先枚举所有文件大小来计算的, + 可能会对性能产生负面影响。特别是,在流式传输数据之前可能需要更长的时间。 + 由于备份期间数据库文件可能会发生变化,因此大小仅为近似值, + 在估算与实际发送文件之间的这段时间里可能会增长或缩小。 + @@ -1571,9 +1590,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" WAL - - 如果设置为true,则在备份中包含必要的WAL段。这将包括在开始和停止备份之间的所有文件在基本目录tar文件的pg_wal目录中。默认值为false。 - + 在备份中包含必要的 WAL 段。这会把开始备份到停止备份之间的所有文件放入基础目录 tar 文件内的pg_wal目录中。 @@ -1601,8 +1618,8 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 如果为true,则在名为tablespace_map的文件中包含目录pg_tblspc中存在的符号链接的信息。 - 表空间映射文件包括目录pg_tblspc/中每个符号链接的名称及该符号链接的完整路径。默认值为false。 + 在名为tablespace_map的文件中包含目录pg_tblspc中存在的符号链接的信息。 + 表空间映射文件包括目录pg_tblspc/中每个符号链接的名称及该符号链接的完整路径。 @@ -1614,17 +1631,21 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - + 备份开始时,服务器首先发送两个普通结果集,然后发送一个或多个 CopyResponse 结果。 第一个普通结果集包含备份的起始位置,在一个包含两列的单行中。第一列包含以XLogRecPtr格式给出的起始位置,第二列包含相应的时间线ID。 - 第二个普通结果集为每个表空间包含一行。这一行的字段如下: + + 第二个普通结果集中的每个表空间都有一行。 + 这一行中的字段是: + + spcoid (oid) - 表空间的OID,如果是基本目录则为null。 + 表空间的OID,如果是基础目录则为null。 @@ -1632,7 +1653,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" spclocation (text) - 表空间目录的完整路径,如果是基本目录则为null。 + 表空间目录的完整路径,如果是基础目录则为null。 @@ -1643,10 +1664,13 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - + 在第二个普通结果集之后,会发送一个或多个 CopyResponse 结果,其中一个用于主数据目录,其他结果分别用于 pg_defaultpg_global 之外的各个附加表空间。CopyResponse 结果中的数据是表空间内容的 tar 格式转储(遵循 POSIX 1003.1-2008 标准中规定的 ustar interchange format),但省略了标准规定的末尾两个全零块。tar 数据传输完成后,会发送最后一个普通结果集,其中包含备份的 WAL 结束位置,格式与起始位置相同。 - 数据目录和每个表空间的 tar 归档都会包含目录中的所有文件,无论是PostgreSQL文件,还是添加到同一目录的其他文件。仅排除以下文件: + + 数据目录和每个表空间的tar归档将包含目录中的所有文件,无论它们是PostgreSQL文件还是添加到同一目录的其他文件。唯一排除的文件是: + + postmaster.pid @@ -1668,13 +1692,11 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - - 不记录 WAL 的关系(Unlogged表),除了需要在恢复时重新创建(空的)不记录 WAL 的关系的init fork。 - + 不记录 WAL 的关系,但不包括恢复时重新创建(空的)不记录 WAL 的关系所需的初始化分支。 - pg_wal,包括子目录。如果备份包含WAL文件,则将包含pg_wal的合成版本,但它只包含备份工作所需的文件,而不包含其余内容。 + pg_wal,包括子目录。如果备份包含WAL文件,则将包含pg_wal的合成版本,但它只包含使备份可用所需的文件,而不包含其余内容。 @@ -1687,10 +1709,12 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 除了常规文件和目录之外的文件,如符号链接(除了上述列出的目录之外的符号链接)以及特殊设备和操作系统文件,将被跳过。(pg_tblspc中的符号链接将被保留。) + 除了普通文件和目录之外的文件,如符号链接(除了上述列出的目录之外的符号链接)以及特殊设备文件,将被跳过。(pg_tblspc中的符号链接将被保留。) - 如果服务器底层文件系统支持,还会设置所有者、组和文件模式。 + + 如果服务器上的底层文件系统支持,将设置所有者、组和文件模式。 + @@ -1718,7 +1742,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 逻辑复制参数 + 逻辑流复制参数 使用START_REPLICATION命令,pgoutput接受以下选项: @@ -1731,7 +1755,9 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" publication_names - 要订阅(接收更改)的发布名称列表,以逗号分隔。各个发布名称按标准对象名称处理,必要时可以同样使用引号。至少需要一个发布名称。 + + 要订阅(接收变更)的发布名称列表,以逗号分隔。各个发布名称按标准对象名处理,可按需加引号。至少需要一个发布名称。 + @@ -2379,33 +2405,51 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" -CancelRequest (F) + +CancelRequest (F) + -Int32(16) + + Int32(16) + -消息内容的长度,以字节为单位,包括此长度字段本身。 + + 消息内容的长度,以字节为单位,包括此长度字段本身。 + -Int32(80877102) + + Int32(80877102) + -取消请求代码。此值的最高 16 位为 1234,最低 16 位为 5678。(为避免混淆,此代码不能与任何协议版本号相同。) + + 取消请求代码。此值的最高 16 位为 1234,最低 16 位为 5678。(为避免混淆,此代码不能与任何协议版本号相同。) + -Int32 + + Int32 + -目标后端的进程 ID。 + + 目标后端的进程 ID。 + -Int32 + + Int32 + -目标后端的密钥。 + + 目标后端的密钥。 + @@ -4088,7 +4132,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 严重性: 字段内容为ERROR, FATAL, 或 + 严重性: 字段内容为ERROR, FATAL, 或 PANIC (在错误消息中), 或 WARNING, NOTICE, DEBUG, INFO, 或 LOG (在通知消息中), @@ -4126,7 +4170,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 消息: 主要的人类可读错误消息。 + 消息: 主要的人类可读错误消息。 这应该准确但简洁(通常一行)。 总是存在。 @@ -4148,7 +4192,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 提示: 关于问题应该怎么做的一个可选建议。 + 提示: 关于问题应该怎么做的一个可选建议。 这意在与细节不同,它提供建议(可能不合适)而不是硬性事实。 可能会跨越多行。 @@ -4181,7 +4225,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" q - 内部查询: 一个失败的内部生成命令的文本。 + 内部查询: 一个失败的内部生成命令的文本。 例如,这可能是由PL/pgSQL函数发出的SQL查询。 @@ -4214,7 +4258,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 表名: 如果错误与特定表相关联,则为表的名称。(有关表模式名称的名称,请参考模式名称字段。) + 表名: 如果错误与特定表相关联,则为表的名称。(有关表模式名称的名称,请参考模式名称字段。) @@ -4224,7 +4268,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 列名: 如果错误与特定表列相关联,则为列的名称。(请参考模式和表名字段以识别表。) + 列名: 如果错误与特定表列相关联,则为列的名称。(请参考模式和表名字段以识别表。) @@ -4234,7 +4278,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 数据类型名称: 如果错误与特定数据类型相关联,则为数据类型的名称。 + 数据类型名称: 如果错误与特定数据类型相关联,则为数据类型的名称。 (有关数据类型模式的名称,请参阅模式名称字段。) @@ -4245,7 +4289,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 约束名称: 如果错误与特定约束相关联,则为约束的名称。请参考上面列出的字段,了解相关表或域。 + 约束名称: 如果错误与特定约束相关联,则为约束的名称。请参考上面列出的字段,了解相关表或域。 (为此,即使索引不是使用约束语法创建的,也将其视为约束。) @@ -4256,7 +4300,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 文件: 报告错误的源代码位置的文件名。 + 文件: 报告错误的源代码位置的文件名。 @@ -4809,13 +4853,13 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" -协议 3.0 与之前版本的变化总结 +自协议 2.0 以来的变更总结 - 本节概述了协议 3.0 与之前协议版本之间的变化。这可以帮助那些需要实现同时处理多种协议版本的客户端库的开发者,或仅仅出于好奇的读者。 - + 本节提供一份简要的变更清单,供准备将现有客户端库更新到协议 3.0 的开发者参考。 + -初始启动包采用灵活的字符串列表格式,取代了固定格式。注意,运行时参数的会话默认值现在可以直接在启动包中指定。(实际上,以前也能通过 options 字段实现,但由于 options 的宽度有限,且无法引用值中的空白,这种方法并不稳妥。) +初始启动包采用灵活的字符串列表格式,取代了固定格式。注意,运行时参数的会话默认值现在可以直接在启动包中指定。(实际上,以前也能通过 options 字段实现,但由于 options 的宽度有限,且无法用引号保护值中的空白字符,这种方法并不稳妥。) 现在,所有消息都在消息类型字节之后紧跟一个长度计数(启动包除外,它没有类型字节)。另请注意,PasswordMessage 现在也有类型字节。 diff --git a/zh/12/queries.sgml b/zh/12/queries.sgml index 0ee3de74..dd62f234 100644 --- a/zh/12/queries.sgml +++ b/zh/12/queries.sgml @@ -487,7 +487,7 @@ FROM (VALUES ('anne', 'smith'), ('bob', 'jones'), ('joe', 'blow')) - 表函数是那些生成行集合的函数,这些行可以由基本数据类型(标量类型)组成,也可以由复合数据类型(表行)组成。它们在查询的FROM子句中用法类似于表、视图或子查询。表函数返回的列可以像表、视图或子查询的列一样,出现在SELECTJOINWHERE子句中。 + 表函数是那些生成行集合的函数,这些行可以由基础类型(标量类型)组成,也可以由复合数据类型(表行)组成。它们在查询的FROM子句中用法类似于表、视图或子查询。表函数返回的列可以像表、视图或子查询的列一样,出现在SELECTJOINWHERE子句中。 @@ -525,7 +525,7 @@ UNNEST( array_expression , ... - 如果没有提供列的别名,那么对于一个返回基数据类型的函数,列名也与该函数 + 如果没有提供列的别名,那么对于一个返回基础类型的函数,列名也与该函数 名相同。对于一个返回复合类型的函数,结果列会从该类型的属性得到名称。 diff --git a/zh/12/rangetypes.sgml b/zh/12/rangetypes.sgml index 8457287b..e29cda85 100644 --- a/zh/12/rangetypes.sgml +++ b/zh/12/rangetypes.sgml @@ -159,21 +159,25 @@ SELECT '[4,4)'::int4range; 构造范围 - 每个范围类型都有一个与其同名的构造函数。使用构造函数通常比编写范围字面常量更方便,因为无需对边界值额外加引号。构造函数接受两个或三个参数。两个参数的形式构造标准形式的范围(包含下界,不包含上界);三个参数的形式则按第三个参数指定的形式构造范围边界。第三个参数必须是以下字符串之一:(), - (], - [)[]。例如: --- The full form is: lower bound, upper bound, and text argument indicating --- inclusivity/exclusivity of bounds. + + 每种范围类型都有一个与范围类型同名的构造函数。使用构造函数通常比书写范围字面量更方便,因为这样无需为界限值额外加引号。构造函数接受两个或三个参数。两个参数的形式构造标准形式的范围(下界包含,上界排除),而三个参数的形式则按第三个参数指定的界限形式构造范围。第三个参数必须是下列字符串之一: + ()、 + (]、 + [)或者 + []。 + 例如: + + +-- 完整形式为:下界、上界,以及指示界限包含性/排除性的文本参数。 SELECT numrange(1.0, 14.0, '(]'); --- If the third argument is omitted, '[)' is assumed. +-- 如果省略第三个参数,则假定为 '[)'。 SELECT numrange(1.0, 14.0); --- Although '(]' is specified here, on display the value will be converted to --- canonical form, since int8range is a discrete range type (see below). +-- 虽然这里指定的是 '(]',但显示时该值会转换为规范形式,因为 int8range 是离散范围类型(见下文)。 SELECT int8range(1, 14, '(]'); --- Using NULL for either bound causes the range to be unbounded on that side. +-- 任一界限使用 NULL 都会使该侧无界。 SELECT numrange(NULL, 2.2); diff --git a/zh/12/ref/abort.sgml b/zh/12/ref/abort.sgml index b5512cbc..9413e79e 100644 --- a/zh/12/ref/abort.sgml +++ b/zh/12/ref/abort.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ABORT 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/alter_aggregate.sgml b/zh/12/ref/alter_aggregate.sgml index c5bd8344..3daf286a 100644 --- a/zh/12/ref/alter_aggregate.sgml +++ b/zh/12/ref/alter_aggregate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER AGGREGATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/alter_collation.sgml b/zh/12/ref/alter_collation.sgml index 379a9542..ca34304e 100644 --- a/zh/12/ref/alter_collation.sgml +++ b/zh/12/ref/alter_collation.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER COLLATION 7 - SQL - Language Statements + SQL - 语言语句 @@ -96,7 +96,8 @@ ALTER COLLATION name SET SCHEMA new_sche 注解 - 创建排序规则对象时,该排序规则的提供者特定版本会记录在系统目录中。 + 使用 ICU 库提供的排序规则时,创建排序规则对象会在系统目录中记录 + ICU 给出的排序器版本。 使用该排序规则时,会将当前版本与记录的版本进行比较;如果二者不匹 配,就会发出警告,例如: @@ -106,16 +107,16 @@ HINT: Rebuild all objects affected by this collation and run ALTER COLLATION pg 排序规则定义的变化可能导致索引损坏及其他问题,因为数据库系统依赖已 存储对象具有特定的排序顺序。一般来说应避免这种情况,但在某些合理情 - 形下仍可能发生,例如将操作系统升级到新的主版本,或者使用 + 形下仍可能发生,例如使用 pg_upgrade升级到链接了较新 ICU 版本的服务器二进 制文件时。出现这种情况时,应重建所有依赖该排序规则的对象,例如使用 REINDEX。完成后,可以使用命令 ALTER COLLATION ... REFRESH VERSION刷新排序规则 - 版本。这样会更新系统目录,使其记录当前的排序规则版本,并让该警告消 + 版本。这样会更新系统目录,使其记录当前的排序器版本,并让该警告消 失。请注意,这实际上并不会检查所有受影响对象是否都已被正确重建。 - 可以使用以下查询找出当前数据库中所有需要刷新的排序规则,以及依赖这些排序规则的对象:以下查询可用于识别当前数据库中所有需要刷新的排序规则,以及依赖它们的对象: ALTER CONVERSION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/alter_database.sgml b/zh/12/ref/alter_database.sgml index 516bc49b..9132cf6d 100644 --- a/zh/12/ref/alter_database.sgml +++ b/zh/12/ref/alter_database.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER DATABASE 7 - SQL - Language Statements + SQL - 语言语句 @@ -59,7 +59,9 @@ ALTER DATABASE name RESET ALL 第三种形式更改数据库的所有者。要更改所有者,必须拥有该数据库,并且还必须是新所有者角色的直接或间接成员,并且必须拥有CREATEDB权限。(请注意,超级用户会自动拥有所有这些权限。) - 第四种形式更改数据库的默认表空间。只有数据库所有者或超级用户可以执行此操作;还必须拥有新表空间的创建权限。此命令会将数据库旧默认表空间中的所有表或索引物理移动到新表空间。对该数据库而言,新默认表空间必须为空,并且不能有任何人连接到该数据库。非默认表空间中的表和索引不受影响。 + + 第四种形式更改数据库的默认表空间。只有数据库拥有者或者超级用户可以这样做;你还必须对新表空间具有创建权限。该命令会将数据库旧默认表空间中的所有表和索引在物理上移动到新表空间中。对于该数据库而言,新默认表空间必须为空,并且不能有人连接到该数据库。位于非默认表空间中的表和索引不受影响。 + 其余形式会更改某个PostgreSQL数据库的运行时配置变量的会话默认值。此后每当在该数据库中启动一个新会话时,指定的值就会成为会话默认值。数据库特定的默认值会覆盖postgresql.conf中的设置,或者从postgres命令行接收到的设置。只有数据库拥有者或者超级用户才能更改该数据库的会话默认值。某些变量不能以这种方式设置,或者只能由超级用户设置。 @@ -82,9 +84,7 @@ ALTER DATABASE name RESET ALL allowconn - - 如果为假,则没有人能连接到这个数据库。 - + 如果为 false,则任何人都不能连接到该数据库。 @@ -100,7 +100,9 @@ ALTER DATABASE name RESET ALL istemplate - 如果为 true,则任何拥有CREATEDB权限的用户都可以克隆该数据库;如果为 false,则只有超级用户或数据库所有者可以克隆它。 + + 如果为 true,则任何具有 CREATEDB 权限的用户都可以克隆该数据库;如果为 false,则只有超级用户或该数据库的拥有者可以克隆它。 + @@ -139,9 +141,17 @@ ALTER DATABASE name RESET ALL configuration_parameter value - 将此数据库的会话默认值设置为指定配置参数的给定值。如果指定valueDEFAULT,或者等效地使用RESET,则删除数据库特定设置,因此新会话将继承系统范围的默认设置。使用RESET ALL清除所有数据库特定设置。SET FROM CURRENT将会话当前参数值保存为数据库特定值。 + + 将此数据库在指定配置参数上的会话默认值设为给定值。如果 + valueDEFAULT,或者等效地使用了 + RESET,则数据库特定设置会被移除,因此新会话将继承系统范围的默认设置。使用 + RESET ALL可清除所有数据库特定设置。 + SET FROM CURRENT会把该参数在当前会话中的值保存为数据库特定值。 + - 有关允许的参数名称和值的更多信息,请参见 + + 关于允许的参数名和值的更多信息,见。 + diff --git a/zh/12/ref/alter_default_privileges.sgml b/zh/12/ref/alter_default_privileges.sgml index ca667c52..ba87960d 100644 --- a/zh/12/ref/alter_default_privileges.sgml +++ b/zh/12/ref/alter_default_privileges.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER DEFAULT PRIVILEGES 7 - SQL - Language Statements + SQL - 语言语句 @@ -122,8 +122,8 @@ REVOKE [ GRANT OPTION FOR ] 一个现有模式的名称。如果指定,将修改以后在该模式中创建的对象的默认权限。 如果省略IN SCHEMA,则修改全局默认权限。 - 在为模式和大对象设置权限时,不允许使用IN SCHEMA, - 因为模式不能嵌套,而大对象不属于任何模式。 + 在为模式设置权限时,不允许使用IN SCHEMA, + 因为模式不能嵌套。 diff --git a/zh/12/ref/alter_domain.sgml b/zh/12/ref/alter_domain.sgml index 664851db..6d969a1a 100644 --- a/zh/12/ref/alter_domain.sgml +++ b/zh/12/ref/alter_domain.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER DOMAIN 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/alter_event_trigger.sgml b/zh/12/ref/alter_event_trigger.sgml index 9c259dbe..86b46ee7 100644 --- a/zh/12/ref/alter_event_trigger.sgml +++ b/zh/12/ref/alter_event_trigger.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER EVENT TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -58,7 +58,7 @@ ALTER EVENT TRIGGER name RENAME TO new_owner - 该事件触发器的新拥有者的用户名。 + 该事件触发器的新所有者的用户名。 @@ -94,7 +94,7 @@ ALTER EVENT TRIGGER name RENAME TO - 另见 + 参见 diff --git a/zh/12/ref/alter_extension.sgml b/zh/12/ref/alter_extension.sgml index dd8eac79..86286dec 100644 --- a/zh/12/ref/alter_extension.sgml +++ b/zh/12/ref/alter_extension.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER EXTENSION 7 - SQL - Language Statements + SQL - 语言语句 @@ -71,7 +71,10 @@ ALTER EXTENSION name DROP 描述 - ALTER EXTENSION更改已安装扩展的定义。有几个子形式: + ALTER EXTENSION更改已安装扩展的定义。 + 其子形式如下: + + UPDATE @@ -112,7 +115,10 @@ ALTER EXTENSION name DROP - 有关这些操作的更多信息。 + + + 有关这些操作的更多信息,见。 + 要使用ALTER EXTENSION,你必须拥有该扩展。 diff --git a/zh/12/ref/alter_foreign_data_wrapper.sgml b/zh/12/ref/alter_foreign_data_wrapper.sgml index 18a2bd3c..7121d9c8 100644 --- a/zh/12/ref/alter_foreign_data_wrapper.sgml +++ b/zh/12/ref/alter_foreign_data_wrapper.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER FOREIGN DATA WRAPPER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/alter_foreign_table.sgml b/zh/12/ref/alter_foreign_table.sgml index c4937234..d3ff2978 100644 --- a/zh/12/ref/alter_foreign_table.sgml +++ b/zh/12/ref/alter_foreign_table.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER FOREIGN TABLE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/alter_function.sgml b/zh/12/ref/alter_function.sgml index d7e9c30b..b0cd3a7c 100644 --- a/zh/12/ref/alter_function.sgml +++ b/zh/12/ref/alter_function.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER FUNCTION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/alter_group.sgml b/zh/12/ref/alter_group.sgml index 26b7f7c8..37888a95 100644 --- a/zh/12/ref/alter_group.sgml +++ b/zh/12/ref/alter_group.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER GROUP 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/alter_index.sgml b/zh/12/ref/alter_index.sgml index 6cd4aa4d..1a8a5ac3 100644 --- a/zh/12/ref/alter_index.sgml +++ b/zh/12/ref/alter_index.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER INDEX 7 - SQL - Language Statements + SQL - 语言语句 @@ -38,7 +38,11 @@ ALTER INDEX ALL IN TABLESPACE name 描述 - ALTER INDEX更改现有索引的定义。下面介绍几种子形式。请注意,每种子形式所需的锁级别可能不同。除非明确说明,否则会持有一个ACCESS EXCLUSIVE锁。当列出多个子命令时,持有的锁将是所有子命令中所需的最严格锁。 + ALTER INDEX更改现有索引的定义。下面描述了若干种子形式。 + 请注意,每种子形式所需的锁级别可能不同。除非另有明确说明,否则会持有 + ACCESS EXCLUSIVE锁。若列出多个子命令,则持有的锁将是其中任一子命令所需的最严格锁。 + + RENAME diff --git a/zh/12/ref/alter_language.sgml b/zh/12/ref/alter_language.sgml index f9b7bec8..f1f6efc6 100644 --- a/zh/12/ref/alter_language.sgml +++ b/zh/12/ref/alter_language.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER LANGUAGE 7 - SQL - Language Statements + SQL - 语言语句 @@ -31,8 +31,8 @@ ALTER [ PROCEDURAL ] LANGUAGE name OWNER TO { ALTER LANGUAGE更改一种过程语言的定义。 - 目前唯一的功能是重命名该语言或为其指定新的拥有者。 - 要使用ALTER LANGUAGE,你必须是超级用户或者该语言的拥有者。 + 目前唯一的功能是重命名该语言或为其指定新的所有者。 + 要使用ALTER LANGUAGE,你必须是超级用户或者该语言的所有者。 @@ -62,7 +62,7 @@ ALTER [ PROCEDURAL ] LANGUAGE name OWNER TO { new_owner - 该语言的新拥有者 + 该语言的新所有者 diff --git a/zh/12/ref/alter_large_object.sgml b/zh/12/ref/alter_large_object.sgml index f962ec9e..a703b418 100644 --- a/zh/12/ref/alter_large_object.sgml +++ b/zh/12/ref/alter_large_object.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER LARGE OBJECT 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/alter_materialized_view.sgml b/zh/12/ref/alter_materialized_view.sgml index fded278d..73375c66 100644 --- a/zh/12/ref/alter_materialized_view.sgml +++ b/zh/12/ref/alter_materialized_view.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER MATERIALIZED VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/alter_opclass.sgml b/zh/12/ref/alter_opclass.sgml index 9ea60c82..6d0da98d 100644 --- a/zh/12/ref/alter_opclass.sgml +++ b/zh/12/ref/alter_opclass.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER OPERATOR CLASS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/alter_operator.sgml b/zh/12/ref/alter_operator.sgml index 0ad43b17..6a7c3bcc 100644 --- a/zh/12/ref/alter_operator.sgml +++ b/zh/12/ref/alter_operator.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER OPERATOR 7 - SQL - Language Statements + SQL - 语言语句 @@ -101,7 +101,7 @@ ALTER OPERATOR name ( { left_type - 注解 + 示例 更改自定义操作符的拥有者,该操作符为a @@ b,类型为text diff --git a/zh/12/ref/alter_opfamily.sgml b/zh/12/ref/alter_opfamily.sgml index 47aff9e6..d8999797 100644 --- a/zh/12/ref/alter_opfamily.sgml +++ b/zh/12/ref/alter_opfamily.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER OPERATOR FAMILY 7 - SQL - Language Statements + SQL - 语言语句 @@ -232,7 +232,9 @@ ALTER OPERATOR FAMILY name USING name RENAME TO < CONNECTION 'conninfo' - 该子句替换最初由设置的连接字符串。 + 该子句更改最初由设置的连接属性。 详情请参见该命令。 diff --git a/zh/12/ref/alter_system.sgml b/zh/12/ref/alter_system.sgml index 72f81233..cc40d0e2 100644 --- a/zh/12/ref/alter_system.sgml +++ b/zh/12/ref/alter_system.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER SYSTEM 7 - SQL - Language Statements + SQL - 语言语句 @@ -80,8 +80,7 @@ ALTER SYSTEM RESET ALL - 对于某些接受列表的参数,带引号的值会生成带双引号的输出,以保留空 - 格和逗号;对于另一些参数,则必须在单引号字符串内部使用双引号才能 + 对于某些接受列表的参数,带引号的值会生成带双引号的输出,以保留空白和逗号;对于另一些参数,则必须在单引号字符串内部使用双引号才能 达到这种效果。 diff --git a/zh/12/ref/alter_table.sgml b/zh/12/ref/alter_table.sgml index 1cb241a1..64a85f92 100644 --- a/zh/12/ref/alter_table.sgml +++ b/zh/12/ref/alter_table.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TABLE 7 - SQL - Language Statements + SQL - 语言语句 @@ -735,7 +735,7 @@ WITH ( MODULUS numeric_literal, REM - 若要强制立即回收已删除列所占的空间,可以执行任何一种会导致整表重写的ALTER TABLE形式。这样会重新构造每一行,并用空值替换被删除的列。 + 若要强制立即回收已删除列所占的空间,可以执行任何一种会导致整表重写的ALTER TABLE形式。这样会重建每一行,并用空值替换被删除的列。 diff --git a/zh/12/ref/alter_tablespace.sgml b/zh/12/ref/alter_tablespace.sgml index ada74112..6fadbfb3 100644 --- a/zh/12/ref/alter_tablespace.sgml +++ b/zh/12/ref/alter_tablespace.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TABLESPACE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/alter_trigger.sgml b/zh/12/ref/alter_trigger.sgml index 0e58bbbd..7e0ee6c4 100644 --- a/zh/12/ref/alter_trigger.sgml +++ b/zh/12/ref/alter_trigger.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -31,7 +31,9 @@ ALTER TRIGGER name ON ALTER TRIGGER更改现有触发器的属性。RENAME子句更改给定触发器的名称,但不以其他方式更改触发器定义。DEPENDS ON EXTENSION子句将触发器标记为依赖扩展,因此扩展被删除时触发器也会自动删除。 - 要更改触发器的属性,必须拥有触发器所在的表。 + + 若要更改触发器的属性,你必须拥有该触发器所作用的表。 + @@ -110,7 +112,7 @@ ALTER TRIGGER emp_stamp ON emp DEPENDS ON EXTENSION emplib; - 另见 + 参见 diff --git a/zh/12/ref/alter_tsconfig.sgml b/zh/12/ref/alter_tsconfig.sgml index ef8f24cf..453d7ee7 100644 --- a/zh/12/ref/alter_tsconfig.sgml +++ b/zh/12/ref/alter_tsconfig.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TEXT SEARCH CONFIGURATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/alter_tsdictionary.sgml b/zh/12/ref/alter_tsdictionary.sgml index 8c11355e..9fedf32d 100644 --- a/zh/12/ref/alter_tsdictionary.sgml +++ b/zh/12/ref/alter_tsdictionary.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TEXT SEARCH DICTIONARY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/alter_tsparser.sgml b/zh/12/ref/alter_tsparser.sgml index 525064c9..0844cb0a 100644 --- a/zh/12/ref/alter_tsparser.sgml +++ b/zh/12/ref/alter_tsparser.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TEXT SEARCH PARSER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/alter_tstemplate.sgml b/zh/12/ref/alter_tstemplate.sgml index fa4157f9..a3eec599 100644 --- a/zh/12/ref/alter_tstemplate.sgml +++ b/zh/12/ref/alter_tstemplate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TEXT SEARCH TEMPLATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/alter_type.sgml b/zh/12/ref/alter_type.sgml index 09902e37..acae132a 100644 --- a/zh/12/ref/alter_type.sgml +++ b/zh/12/ref/alter_type.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TYPE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/alter_user.sgml b/zh/12/ref/alter_user.sgml index b6544c05..55150300 100644 --- a/zh/12/ref/alter_user.sgml +++ b/zh/12/ref/alter_user.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER USER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/alter_user_mapping.sgml b/zh/12/ref/alter_user_mapping.sgml index 0083f95b..1e7245a4 100644 --- a/zh/12/ref/alter_user_mapping.sgml +++ b/zh/12/ref/alter_user_mapping.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER USER MAPPING 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/alter_view.sgml b/zh/12/ref/alter_view.sgml index 4eaccd4d..28a35509 100644 --- a/zh/12/ref/alter_view.sgml +++ b/zh/12/ref/alter_view.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/analyze.sgml b/zh/12/ref/analyze.sgml index affb3890..319283ca 100644 --- a/zh/12/ref/analyze.sgml +++ b/zh/12/ref/analyze.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ANALYZE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/begin.sgml b/zh/12/ref/begin.sgml index dc5eff7b..8c68c21c 100644 --- a/zh/12/ref/begin.sgml +++ b/zh/12/ref/begin.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation BEGIN 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/call.sgml b/zh/12/ref/call.sgml index 64781670..7582f545 100644 --- a/zh/12/ref/call.sgml +++ b/zh/12/ref/call.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CALL 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/checkpoint.sgml b/zh/12/ref/checkpoint.sgml index e9d12c3a..53544983 100644 --- a/zh/12/ref/checkpoint.sgml +++ b/zh/12/ref/checkpoint.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CHECKPOINT 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/close.sgml b/zh/12/ref/close.sgml index 415ec160..deb8a9be 100644 --- a/zh/12/ref/close.sgml +++ b/zh/12/ref/close.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation CLOSE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/cluster.sgml b/zh/12/ref/cluster.sgml index 55f14ec5..9c7e8a0d 100644 --- a/zh/12/ref/cluster.sgml +++ b/zh/12/ref/cluster.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CLUSTER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/clusterdb.sgml b/zh/12/ref/clusterdb.sgml index aa614163..50de0b84 100644 --- a/zh/12/ref/clusterdb.sgml +++ b/zh/12/ref/clusterdb.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation clusterdb 1 - Application + 应用程序 diff --git a/zh/12/ref/comment.sgml b/zh/12/ref/comment.sgml index 52b848b5..89b06fe3 100644 --- a/zh/12/ref/comment.sgml +++ b/zh/12/ref/comment.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation COMMENT 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/commit.sgml b/zh/12/ref/commit.sgml index f2ebcbe7..313a9396 100644 --- a/zh/12/ref/commit.sgml +++ b/zh/12/ref/commit.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation COMMIT 7 - SQL - Language Statements + SQL - 语言语句 @@ -39,7 +39,7 @@ COMMIT [ WORK | TRANSACTION ] [ AND [ NO ] CHAIN ] 参数 - chained transactions + 链式事务 diff --git a/zh/12/ref/commit_prepared.sgml b/zh/12/ref/commit_prepared.sgml index 3cdfcf03..b8429aa4 100644 --- a/zh/12/ref/commit_prepared.sgml +++ b/zh/12/ref/commit_prepared.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation COMMIT PREPARED 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/copy.sgml b/zh/12/ref/copy.sgml index 33685f84..fda7d788 100644 --- a/zh/12/ref/copy.sgml +++ b/zh/12/ref/copy.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation COPY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/create_access_method.sgml b/zh/12/ref/create_access_method.sgml index 0acbda86..53d00429 100644 --- a/zh/12/ref/create_access_method.sgml +++ b/zh/12/ref/create_access_method.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE ACCESS METHOD 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/create_aggregate.sgml b/zh/12/ref/create_aggregate.sgml index b734c07f..f1a562eb 100644 --- a/zh/12/ref/create_aggregate.sgml +++ b/zh/12/ref/create_aggregate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE AGGREGATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/create_cast.sgml b/zh/12/ref/create_cast.sgml index 353229a1..84a2ce12 100644 --- a/zh/12/ref/create_cast.sgml +++ b/zh/12/ref/create_cast.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE CAST 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/create_collation.sgml b/zh/12/ref/create_collation.sgml index ed8d7d53..4188f01c 100644 --- a/zh/12/ref/create_collation.sgml +++ b/zh/12/ref/create_collation.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE COLLATION 7 - SQL - Language Statements + SQL - 语言语句 @@ -95,7 +95,7 @@ CREATE COLLATION [ IF NOT EXISTS ] name FROM provider - 指定用于与此排序规则关联的区域设置服务的提供者。可能的值为: icuICU libclibc 是默认值。可用选项取决于操作系统和构建选项。 + 指定用于与此排序规则关联的区域设置服务的提供程序。可能的值为: icuICU libclibc 是默认值。可用选项取决于操作系统和构建选项。 @@ -105,7 +105,9 @@ CREATE COLLATION [ IF NOT EXISTS ] name FROM 指定排序规则是否应使用确定性比较。默认值为 true。确定性比较将字节上不相等的字符串视为不相等,即使它们在逻辑上相等。PostgreSQL 使用字节比较来解决歧义。非确定性比较可以使排序规则变为大小写不敏感或重音不敏感。为此,您需要选择适当的 LOCALE 设置 并且 在此处将排序规则设置为非确定性。 - 非确定性排序规则仅在 ICU 提供者下受支持。 + + 非确定性排序规则仅受 ICU 提供程序支持。 + @@ -173,7 +175,9 @@ CREATE COLLATION french (locale = 'fr_FR.utf8'); - 使用 ICU 提供者并采用德语电话簿排序顺序创建排序规则: + + 使用 ICU 提供程序并采用德语电话簿排序顺序创建一种排序规则: + CREATE COLLATION german_phonebook (provider = icu, locale = 'de-u-co-phonebk'); diff --git a/zh/12/ref/create_conversion.sgml b/zh/12/ref/create_conversion.sgml index fa50caff..1200e3b4 100644 --- a/zh/12/ref/create_conversion.sgml +++ b/zh/12/ref/create_conversion.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE CONVERSION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/create_database.sgml b/zh/12/ref/create_database.sgml index ed111233..cb3cd75a 100644 --- a/zh/12/ref/create_database.sgml +++ b/zh/12/ref/create_database.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE DATABASE 7 - SQL - Language Statements + SQL - 语言语句 @@ -46,7 +46,15 @@ CREATE DATABASE name CREATEDB 权限。见 - 默认情况下,新数据库将通过克隆标准系统数据库 template1 来创建。可以通过编写 TEMPLATE name 指定不同的模板。特别地,通过编写 TEMPLATE template0,可以创建一个仅包含由您的 PostgreSQL 版本预定义的标准对象的全新数据库。如果您希望避免复制可能已添加到 template1 的任何安装本地对象,此方法非常有用。 + + 默认情况下,新数据库通过克隆标准系统数据库 + template1 来创建。可以通过写成 TEMPLATE + name 指定其他模板。特别是, + 写成 TEMPLATE template0 时,可以创建一个全新的数据库, + 它只包含你的 PostgreSQL 版本预定义的标准对象。 + 如果你希望避免复制任何可能已添加到 template1 中的站点本地附加对象, + 这会很有用。 + @@ -56,25 +64,36 @@ CREATE DATABASE name name - 要创建的数据库名称。 + + 要创建的数据库名称。 + user_name - 新数据库所有者的角色名称,或使用 DEFAULT 以使用默认值(即执行命令的用户)。要创建由其他角色拥有的数据库,您必须是该角色的直接或间接成员,或为超级用户。 + 新数据库所有者的角色名称,或使用 DEFAULT 以使用默认值(即执行命令的用户)。要创建由其他角色拥有的数据库,你必须是该角色的直接或间接成员,或为超级用户。 template - 用于创建新数据库的模板名称,或使用 DEFAULT 以使用默认模板(template1)。 + + 用于创建新数据库的模板名称,或者指定 DEFAULT + 以使用默认模板(template1)。 + encoding - 新数据库中使用的字符集编码。指定字符串常量(例如 'SQL_ASCII'),或整数编码编号,或使用 DEFAULT 以使用默认编码(即模板数据库的编码)。PostgreSQL 服务器支持的字符集在 中有描述。请参见下方的附加限制。 + + 新数据库要使用的字符集编码。可指定字符串常量(例如 + 'SQL_ASCII')、整数编码编号,或者指定 + DEFAULT 以使用默认编码(即模板数据库的编码)。 + PostgreSQL 服务器支持的字符集见 + 。其他限制见下文。 + @@ -92,28 +111,40 @@ CREATE DATABASE name tablespace_name - 将与新数据库关联的表空间名称,或使用 DEFAULT 来使用模板数据库的表空间。该表空间将成为在此数据库中创建的对象的默认表空间。有关更多信息,请参见 + + 将与新数据库关联的表空间名称,或者指定 DEFAULT + 以使用模板数据库的表空间。该表空间将成为在此数据库中创建对象时使用的默认表空间。详见 + 。 + allowconn - 如果为 false,则没有人可以连接到此数据库。默认值为 true,允许连接(除非受其他机制(如 GRANT/REVOKE CONNECT)限制)。 + + 如果为 false,则任何人都不能连接到该数据库。默认值为 true,即允许连接 + (但仍受其他机制限制,例如 + GRANT/REVOKE CONNECT)。 + connlimit - 可以同时连接到此数据库的连接数。-1(默认值)表示无限制。 + + 可对该数据库建立的并发连接数。-1(默认值)表示不受限制。 + istemplate - 如果为 true,则任何拥有 CREATEDB 权限的用户都可以克隆此数据库;如果为 false(默认值),则只有超级用户或数据库所有者才能克隆它。 + + 如果为 true,则任何具有 CREATEDB 权限的用户都可以克隆该数据库;如果为 false(默认值),则只有超级用户或该数据库的拥有者可以克隆它。 + @@ -152,11 +183,24 @@ CREATE DATABASE name - 为新数据库指定的字符集编码必须与所选的区域设置(LC_COLLATELC_CTYPE)兼容。如果区域设置为 C(或等效的 POSIX),则允许所有编码,但其他区域设置仅有一种编码能正常工作。(在 Windows 上,UTF-8 编码可与任何区域设置一起使用。)CREATE DATABASE 允许超级用户指定 SQL_ASCII 编码,而不管区域设置如何,但此选择已弃用,如果在数据库中存储了与区域设置不兼容编码的数据,可能导致字符串函数行为异常。 + + 为新数据库指定的字符集编码必须与所选区域设置(LC_COLLATE + 和 LC_CTYPE)兼容。如果区域设置为 C + (或等价的 POSIX),则允许所有编码;但对于其他区域设置,只有一种编码能够正常工作。(不过,在 Windows 上,UTF-8 编码可与任何区域设置一起使用。) + CREATE DATABASE 允许超级用户不考虑区域设置而指定 + SQL_ASCII 编码,但这种选择已弃用;如果数据库中存储了与该区域设置不兼容编码的数据,字符串函数的行为可能会出错。 + - 编码和区域设置必须与模板数据库匹配,除非使用 template0 作为模板。这是因为其他数据库可能包含与指定编码不匹配的数据,或包含受 LC_COLLATELC_CTYPE 影响排序顺序的索引。复制此类数据将导致数据库在新设置下出现损坏。然而,template0 被确认不包含任何会受影响的数据或索引。 + + 编码和区域设置必须与模板数据库的设置一致,除非使用 + template0 作为模板。这是因为其他数据库可能包含与指定编码不匹配的数据,或者包含排序顺序会受 + LC_COLLATELC_CTYPE 影响的索引。复制这样的数据会导致数据库在新设置下被视为损坏。不过,已知 + template0 不包含任何会受此影响的数据或索引。 + - CONNECTION LIMIT 选项仅近似强制执行;如果两个新会话几乎同时启动,而数据库仅剩一个连接 ,则有可能两者都会失败。此外,该限制对超级用户或后台工作进程不生效。 + + CONNECTION LIMIT 选项只是近似地被强制执行;如果两个新会话几乎同时启动,而该数据库只剩下一个连接,则两者都可能失败。此外,该限制对超级用户或后台工作进程无效。 + @@ -170,25 +214,39 @@ CREATE DATABASE lusiadas; - 要创建数据库sales,其所有者为用户 salesapp,默认表空间为 salesspace: + + 要创建一个由用户 salesapp 拥有、默认表空间为 + salesspace 的数据库 sales CREATE DATABASE sales OWNER salesapp TABLESPACE salesspace; - 要创建数据库music,使用不同的区域设置: + + 要创建一个使用不同区域设置的数据库 music: + + CREATE DATABASE music LC_COLLATE 'sv_SE.utf8' LC_CTYPE 'sv_SE.utf8' TEMPLATE template0; -在此示例中,TEMPLATE template0子句在指定的区域设置与template1中的区域设置不同时是必需的。(如果相同,则显式指定区域设置是多余的。) + + 在这个示例中,如果指定的区域设置与 template1 中的不同, + 则必须使用 TEMPLATE template0 子句。(如果相同, + 那么显式指定区域设置就是多余的。) + - 要创建数据库music2,使用不同的区域设置和不同的字符集编码: + + 要创建一个使用不同区域设置和不同字符集编码的数据库 + music2: + CREATE DATABASE music2 LC_COLLATE 'sv_SE.iso885915' LC_CTYPE 'sv_SE.iso885915' ENCODING LATIN9 TEMPLATE template0; -指定的区域设置和编码设置必须匹配,否则将报告错误。 + + 指定的区域设置和编码设置必须匹配,否则会报错。 + 请注意,区域设置名称是特定于操作系统的,因此上述命令未必在所有环境中都以相同方式工作。 diff --git a/zh/12/ref/create_domain.sgml b/zh/12/ref/create_domain.sgml index b3a10dde..916546fd 100644 --- a/zh/12/ref/create_domain.sgml +++ b/zh/12/ref/create_domain.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE DOMAIN 7 - SQL - Language Statements + SQL - 语言语句 @@ -86,7 +86,7 @@ CREATE DOMAIN name [ AS ] 该域的可选排序规则。如果未指定排序规则,则该域的排序规则行为与其 底层数据类型相同。如果指定了COLLATE,则底层 - 类型必须是一种可排序数据类型。 + 类型必须是一种支持排序规则的数据类型。 diff --git a/zh/12/ref/create_event_trigger.sgml b/zh/12/ref/create_event_trigger.sgml index ddf889db..3659259b 100644 --- a/zh/12/ref/create_event_trigger.sgml +++ b/zh/12/ref/create_event_trigger.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE EVENT TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -40,7 +40,7 @@ CREATE EVENT TRIGGER name CREATE EVENT TRIGGER创建一个新的事件触发器。 每当指定的事件发生,并且与该触发器关联的WHEN条件(如果有)得到 满足时,就会执行该触发器函数。有关事件触发器的一般性介绍,见 - 。创建事件触发器的用户将成为其拥有者。 + 。创建事件触发器的用户将成为其所有者。 @@ -77,8 +77,7 @@ CREATE EVENT TRIGGER name - 用于过滤事件的变量名称。这使得可以将触发器限定为只在支持该变量的部 - 分情形下触发。当前唯一支持的 + 用于过滤事件的变量名称。这样可以将触发器限定为只在原本支持的部分情形下触发。当前唯一支持的 filter_variableTAG @@ -168,7 +167,7 @@ CREATE EVENT TRIGGER abort_ddl ON ddl_command_start - 另见 + 参见 diff --git a/zh/12/ref/create_extension.sgml b/zh/12/ref/create_extension.sgml index 69fffd86..338fd980 100644 --- a/zh/12/ref/create_extension.sgml +++ b/zh/12/ref/create_extension.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE EXTENSION 7 - SQL - Language Statements + SQL - 语言语句 @@ -67,7 +67,12 @@ CREATE EXTENSION [ IF NOT EXISTS ] extension_name extension_name - 要安装的扩展的名称。PostgreSQL 将使用 SHAREDIR/extension/extension_name.control 文件中的信息创建扩展。 + + 要安装的扩展名称。PostgreSQL将根据 + SHAREDIR/extension/extension_name.control + 文件中的详细信息创建该扩展。 + @@ -112,7 +117,7 @@ CREATE EXTENSION [ IF NOT EXISTS ] extension_name old_version - FROM old_version 必须在且仅在尝试安装一个替换 旧式模块的扩展时指定,该模块仅是一组未打包为扩展的对象集合。此选项会导致 CREATE EXTENSION 运行一个替代安装脚本,将现有对象吸收进扩展中,而不是创建新对象。请注意 SCHEMA 指定了包含这些预先存在的对象的模式。 + FROM old_version 必须在且仅在尝试安装一个替换 旧式模块的扩展时指定,该模块仅是一组未打包为扩展的对象集合。此选项会导致 CREATE EXTENSION 运行一个替代安装脚本,将现有对象吸收进扩展中,而不是创建新对象。请确保 SCHEMA 指定的是包含这些现有对象的模式。 old_version的值由扩展作者决定,如果存在多个可升级为扩展的旧式模块版本,该值可能会有所不同。对于PostgreSQL 9.1 之前版本提供的标准附加模块,将模块更新为扩展形式时应使用unpackaged作为old_version的值。 @@ -157,7 +162,7 @@ CREATE EXTENSION [ IF NOT EXISTS ] extension_name 会在之后执行编写粗心的扩展脚本时实施攻击,使该用户获得超级用户权限。 不过,只有当特洛伊木马对象在脚本执行期间位于 search_path 中时,它们才会构成危险;这意味着它们 - 位于扩展的安装目标模式中,或位于它所依赖的某个扩展所属的模式中。 + 位于扩展的安装目标模式中,或位于它所依赖的某个扩展的目标模式中。 因此,处理那些脚本尚未经过仔细审查的扩展时,一个经验法则是: 只把它们安装到从未向任何不受信任用户授予、而且今后也不会授予 CREATE 权限的模式中。它们所依赖的任何扩展也应如此。 @@ -179,10 +184,14 @@ CREATE EXTENSION [ IF NOT EXISTS ] extension_name 示例 - 安装hstore扩展到当前数据库,并将其对象放入模式addons: + + 将 hstore 扩展安装到当前数据库中,并把 + 其对象放在 addons 模式中: CREATE EXTENSION hstore SCHEMA addons; -另一种实现相同功能的方法: + + 实现同样效果的另一种方式是: + SET search_path = addons; CREATE EXTENSION hstore; diff --git a/zh/12/ref/create_foreign_data_wrapper.sgml b/zh/12/ref/create_foreign_data_wrapper.sgml index 1eb28864..e7701eb2 100644 --- a/zh/12/ref/create_foreign_data_wrapper.sgml +++ b/zh/12/ref/create_foreign_data_wrapper.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE FOREIGN DATA WRAPPER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/create_foreign_table.sgml b/zh/12/ref/create_foreign_table.sgml index 11b0ef0c..2f8cf42f 100644 --- a/zh/12/ref/create_foreign_table.sgml +++ b/zh/12/ref/create_foreign_table.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE FOREIGN TABLE 7 - SQL - Language Statements + SQL - 语言语句 @@ -135,9 +135,7 @@ WITH ( MODULUS numeric_literal, REM COLLATE collation - - COLLATE子句为该列(必须是一种可排序数据类型)指定一个排序规则。如果未指定,则使用该列数据类型的默认排序规则。 - + COLLATE子句为列指定排序规则(该列必须属于支持排序规则的数据类型)。如果未指定,则使用列数据类型的默认排序规则。 diff --git a/zh/12/ref/create_function.sgml b/zh/12/ref/create_function.sgml index 32df87c2..947b4dce 100644 --- a/zh/12/ref/create_function.sgml +++ b/zh/12/ref/create_function.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE FUNCTION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/create_group.sgml b/zh/12/ref/create_group.sgml index 06195a91..9a6538ed 100644 --- a/zh/12/ref/create_group.sgml +++ b/zh/12/ref/create_group.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE GROUP 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/create_index.sgml b/zh/12/ref/create_index.sgml index 10fbef48..491e963d 100644 --- a/zh/12/ref/create_index.sgml +++ b/zh/12/ref/create_index.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE INDEX 7 - SQL - Language Statements + SQL - 语言语句 @@ -54,7 +54,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] PostgreSQL提供了索引方法 - B-树、哈希、GiST、SP-GiST、GIN 以及 BRIN。用户也可以定义自己的索引 + B-树、hash、GiST、SP-GiST、GIN 以及 BRIN。用户也可以定义自己的索引 方法,但这相当复杂。 @@ -111,7 +111,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] 使用此选项时,PostgreSQL将在构建索引时不获取任何会阻止对表进行并发插入、更新或删除的锁;而标准索引构建会阻塞对表的写入(但不会阻塞读取),直到构建完成。使用此选项时有几个注意事项需要了解—请参见 对于临时表,CREATE INDEX始终是非并发的, - 因为没有其他会话可以访问它们,而且非并发创建索引的成本更低。 + 因为没有其他会话可以访问它们,而且非并发创建索引的代价更低。 @@ -119,20 +119,36 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] IF NOT EXISTS - 如果已存在同名关系,则不要抛出错误。此时会发出通知。请注意,无法保证现有索引与将要创建的索引有任何相似之处。指定IF NOT EXISTS时必须提供索引名称。 + + 如果同名关系已存在,则不抛出错误,而是发出一个提示。注意, + 现有索引并不保证与本应创建的索引有任何相似之处。指定 + IF NOT EXISTS时,必须提供索引名。 + INCLUDE - 可选的INCLUDE子句指定要作为非键列包含在索引中的列列表。非键列不能用于索引扫描的搜索限定条件,索引强制执行的任何唯一性约束或排他约束也会忽略这些列。不过,仅索引扫描可以直接从索引条目取得非键列的内容,无需访问索引所对应的表。因此,添加非键列可以让原本无法使用仅索引扫描的查询使用这种扫描。 + + 可选的INCLUDE子句指定一个列列表,这些列将作为 + 非键列包含在索引中。非键列不能用作索引扫描的 + 搜索限定条件,在索引强制执行的任何唯一性或排他约束中也会被忽略。不过, + 非键列的内容可以由仅索引扫描返回,而无需访问索引对应的表,因为它们 + 可直接从索引项中取得。因此,添加非键列可以让原本无法使用仅索引扫描 + 的查询也能使用它。 + 向索引添加非键列时,谨慎一些是明智的,尤其是宽列。如果索引元组超过该索引类型允许的最大大小,数据插入将失败。无论如何,非键列会复制索引所对应的表中的数据并使索引膨胀,从而可能降低搜索速度。 - INCLUDE子句中列出的列不需要适用的操作符类;对于给定访问方法,如果某些列的数据类型没有定义操作符类,该子句仍可包含这些列。 + + INCLUDE子句中列出的列不需要合适的操作符类; + 该子句可以包含数据类型尚未为给定访问方法定义操作符类的列。 + - 表达式不支持作为包含列,因为它们不能用于仅索引扫描。 + + 不支持将表达式作为包含列,因为它们不能用于仅索引扫描。 + 目前,B-树 和 GiST 索引访问方法支持此功能。在 B-树 和 GiST 索引中,INCLUDE子句中列出的列值会包含在对应堆元组的叶元组中,但不会包含在用于树导航的上层索引条目中。 @@ -148,56 +164,80 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] ONLY - 如果表已分区,则表示创建索引时不要递归到分区。默认情况下会递归。 + + 表示如果该表是分区表,则不要递归地在各分区上创建索引。 + 默认会递归。 + table_name - 要建立索引的表名称(可能包含模式限定)。 + + 要建立索引的表名(可以是模式限定名)。 + method - 要使用的索引方法名称。可选项包括btreehashgistspgistginbrin,以及用户安装的访问方法(例如bloom)。默认方法是btree + + 要使用的索引方法的名称。选择包括btreehash、 + gistspgistgin、 + brin,或用户安装的访问方法,如 + bloom。 + 默认方法是btree。 + column_name - 表的列名称。 + + 一个表列的名称。 + expression - 基于表中一个或多个列的表达式。通常必须按照语法所示,在表达式两侧加上括号。不过,如果表达式采用函数调用的形式,则可以省略括号。 + + 一个基于表中一个或多个列的表达式。通常必须像语法中所示那样写在 + 外围圆括号中。不过,如果该表达式是函数调用形式,则可以省略圆括号。 + collation - 用于索引的排序规则名称。默认情况下,索引使用要建立索引的列所声明的排序规则,或要建立索引的表达式的结果排序规则。具有非默认排序规则的索引对于涉及使用非默认排序规则的表达式的查询可能很有用。 + + 将用于该索引的排序规则名称。默认情况下,索引使用被索引列声明的 + 排序规则,或者被索引表达式的结果排序规则。对于涉及使用非默认排序 + 规则表达式的查询,使用非默认排序规则的索引可能会很有用。 + opclass - 操作符类的名称。详细信息见下文。 + + 一个操作符类的名称。详见下文。 + ASC - 指定升序排序(这是默认值)。 + + 指定升序排序(默认)。 + @@ -211,14 +251,20 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] NULLS FIRST - 指定将空值排在非空值之前。当指定DESC时,这是默认值。 + + 指定把空值排序在非空值前面。在指定DESC时, + 这是默认行为。 + NULLS LAST - 指定将空值排在非空值之后。当未指定DESC时,这是默认值。 + + 指定把空值排序在非空值后面。在没有指定DESC时, + 这是默认行为。 + @@ -232,7 +278,11 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] tablespace_name - 要创建索引的表空间。如果未指定,则查询;对于临时表上的索引,则查询 + + 在其中创建索引的表空间。如果未指定,将查阅 + ;对于临时表上的索引,则查阅 + 。 + @@ -251,6 +301,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] 可选的WITH子句为索引指定存储参数。每一种 索引方法都有其各自允许的存储参数集合。 + B-树、hash、GiST 和 SP-GiST 索引方法都接受以下参数: @@ -263,7 +314,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - B-树、哈希、GiST 和 SP-GiST 索引方法都接受以下参数: + B-树索引还接受以下参数: @@ -276,7 +327,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - B-树索引还接受以下参数: + GiST 索引还接受以下参数: @@ -289,7 +340,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - GiST 索引还接受以下参数: + GIN 索引接受不同的参数: @@ -317,7 +368,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - 为该索引覆盖的全局设置。 + 自定义参数。 该值以千字节为单位。 @@ -325,7 +376,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - BRIN 索引接受以下参数: + BRIN 索引接受不同的参数: @@ -345,7 +396,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - 定义当在下一页范围检测到插入时,是否为前一页范围排队执行一次提要操作 + 定义当在下一页范围检测到插入时,是否为前一页范围排队执行一次范围摘要操作 (详见)。 默认值为off @@ -358,8 +409,8 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] 并发构建索引 - index - building concurrently + 索引 + 并发构建 @@ -385,8 +436,13 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] 在并发索引构建中,索引实际上会在一个事务中录入系统目录,然后在另外两个事务中执行两次表扫描。每次表扫描之前,索引构建都必须等待已修改该表的现有事务结束。第二次扫描之后,索引构建必须等待所有持有早于第二次扫描的快照(参见)的事务结束,其中包括其他表上并发索引构建任一阶段使用的事务。最后,索引才可以标记为可用,CREATE INDEX命令随之结束。不过即便如此,索引也可能无法立即用于查询:在最坏情况下,只要还存在早于索引构建开始的事务,就不能使用它。 - 如果在扫描表时出现问题,例如死锁或唯一索引中的唯一性冲突,CREATE INDEX命令将失败,但会留下一个无效索引。由于该索引可能不完整,查询时会忽略它;但是,它仍会带来更新开销。该psql - \d命令会将此类索引报告为INVALID: + + 如果在扫描表时出现问题,例如死锁或唯一索引中的唯一性违反, + CREATE INDEX命令将失败,但会留下一个 + 无效索引。这个索引在查询时会被忽略,因为它可能不完 + 整;但它仍会带来更新开销。psql + \d命令会将这样的索引报告为 + INVALID postgres=# \d tab @@ -396,7 +452,11 @@ postgres=# \d tab col | integer | | | Indexes: "idx" btree (col) INVALID -在这种情况下,建议的恢复方法是删除索引,然后重新尝试执行CREATE INDEX CONCURRENTLY。(另一种可能性是重建索引,使用REINDEX INDEX CONCURRENTLY)。 + + + 在这种情况下,推荐的恢复方法是删除该索引,然后再次尝试执行 + CREATE INDEX CONCURRENTLY。(另一种做法是用 + REINDEX INDEX CONCURRENTLY重建索引。) @@ -474,12 +534,17 @@ Indexes: 生成这些索引的统计信息。 - 对于大多数索引方法,创建索引的速度取决于的设置。较大的值会减少创建索引所需的时间,但前提是不能将它设得大于实际可用的内存量,否则机器会进入交换。 + + 对于大多数索引方法,索引的创建速度取决于 + 的设置。较大的值将会减少 + 索引创建所需的时间,当然不要把它设置得超过实际可用的内存量(那会迫使 + 机器进行交换)。 + PostgreSQL可以在构建索引时利用多个 CPU, 以便更快处理表中的行。这项特性被称为并行索引构建。 - 对于支持并行构建索引的索引方法(当前为 B-树、GIN 和 BRIN), + 对于支持并行构建索引的索引方法(当前只有 B-树), maintenance_work_mem指定每次索引构建操作整体最多 可使用的内存量,而不管启动了多少工作者进程。通常,代价模型会自动决 定是否需要请求工作者进程,以及请求多少个。 @@ -517,7 +582,11 @@ Indexes: - 虽然带有CONCURRENTLY选项的CREATE INDEX支持并行构建且没有特殊限制,但实际只有第一次表扫描是并行执行的。 + + 虽然带有CONCURRENTLY选项的CREATE INDEX + 在没有特殊限制的情况下支持并行构建,但实际上只有第一次表扫描会以并行 + 方式执行。 + 使用删除索引。 @@ -527,7 +596,12 @@ Indexes: 被移除。 - 早期版本的PostgreSQL也有 R-tree 索引方法。由于它相对于 GiST 方法没有显著优势,该方法已被删除。如果指定USING rtreeCREATE INDEX会将其解释为USING gist,以便简化旧数据库向 GiST 的转换。 + + 早期版本的PostgreSQL还提供过一种 R-tree + 索引方法。该方法已经被移除,因为它相对于 GiST 方法并无明显优势。如果 + 指定了USING rtreeCREATE INDEX + 会将其解释为USING gist,以简化旧数据库向 GiST 的转换。 + diff --git a/zh/12/ref/create_language.sgml b/zh/12/ref/create_language.sgml index afa16d63..18ca6cc1 100644 --- a/zh/12/ref/create_language.sgml +++ b/zh/12/ref/create_language.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE LANGUAGE 7 - SQL - Language Statements + SQL - 语言语句 @@ -55,7 +55,7 @@ CREATE [ OR REPLACE ] [ TRUSTED ] [ PROCEDURAL ] LANGUAGE - 新过程语言的名称。该名称在数据库内必须唯一。 + 新过程语言的名称。该名称不能与数据库中其他语言的名称重复。 diff --git a/zh/12/ref/create_materialized_view.sgml b/zh/12/ref/create_materialized_view.sgml index 8320f7b8..6d0bafbb 100644 --- a/zh/12/ref/create_materialized_view.sgml +++ b/zh/12/ref/create_materialized_view.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE MATERIALIZED VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/create_opclass.sgml b/zh/12/ref/create_opclass.sgml index 0e71beaf..eb57a114 100644 --- a/zh/12/ref/create_opclass.sgml +++ b/zh/12/ref/create_opclass.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE OPERATOR CLASS 7 - SQL - Language Statements + SQL - 语言语句 @@ -236,7 +236,7 @@ CREATE OPERATOR CLASS name [ DEFAUL - 在PostgreSQL 8.4 之前,OPERATOR子句可以包含RECHECK选项。现在不再支持它,因为索引操作符是否有损现在会在运行时动态确定。这使得系统可以高效处理操作符可能有损也可能无损的情况。 + 在PostgreSQL 8.4 之前,OPERATOR子句可以包含RECHECK选项。现在不再支持该选项,因为索引操作符是否有损会在运行时动态确定。这样可以高效处理操作符可能有损也可能无损的情况。 diff --git a/zh/12/ref/create_operator.sgml b/zh/12/ref/create_operator.sgml index f9348de7..71f250c4 100644 --- a/zh/12/ref/create_operator.sgml +++ b/zh/12/ref/create_operator.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE OPERATOR 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/create_opfamily.sgml b/zh/12/ref/create_opfamily.sgml index ebe6fd9c..23f2e669 100644 --- a/zh/12/ref/create_opfamily.sgml +++ b/zh/12/ref/create_opfamily.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE OPERATOR FAMILY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/create_policy.sgml b/zh/12/ref/create_policy.sgml index 2b562dc1..2208cec0 100644 --- a/zh/12/ref/create_policy.sgml +++ b/zh/12/ref/create_policy.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE POLICY 7 - SQL - Language Statements + SQL - 语言语句 @@ -257,17 +257,17 @@ CREATE POLICY name ON 命令 - SELECT/ALL policy - INSERT/ALL policy - UPDATE/ALL policy - DELETE/ALL policy + SELECT/ALL策略 + INSERT/ALL策略 + UPDATE/ALL策略 + DELETE/ALL策略 - USING expression - WITH CHECK expression - USING expression - WITH CHECK expression - USING expression + USING 表达式 + WITH CHECK 表达式 + USING 表达式 + WITH CHECK 表达式 + USING 表达式 diff --git a/zh/12/ref/create_procedure.sgml b/zh/12/ref/create_procedure.sgml index 014109b0..1c87b5f3 100644 --- a/zh/12/ref/create_procedure.sgml +++ b/zh/12/ref/create_procedure.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE PROCEDURE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/create_publication.sgml b/zh/12/ref/create_publication.sgml index b2bf2b7a..ec6a8a06 100644 --- a/zh/12/ref/create_publication.sgml +++ b/zh/12/ref/create_publication.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE PUBLICATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/create_role.sgml b/zh/12/ref/create_role.sgml index 4a379a7a..c25f6fa7 100644 --- a/zh/12/ref/create_role.sgml +++ b/zh/12/ref/create_role.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE ROLE 7 - SQL - Language Statements + SQL - 语言语句 @@ -107,7 +107,7 @@ in sync when changing the above synopsis! 这些子句决定某个角色是否被允许创建、更改、删除其他角色,为其添加注释, - 以及更改其安全标签。关于该权限赋予的具体能力,参见 + 更改其安全标签,以及授予或撤销其中的成员资格。关于该权限赋予的具体能力,参见 。若未指定,默认值是 NOCREATEROLE diff --git a/zh/12/ref/create_rule.sgml b/zh/12/ref/create_rule.sgml index 6367a679..6abd2969 100644 --- a/zh/12/ref/create_rule.sgml +++ b/zh/12/ref/create_rule.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE RULE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/create_schema.sgml b/zh/12/ref/create_schema.sgml index f3dc7a31..fede6380 100644 --- a/zh/12/ref/create_schema.sgml +++ b/zh/12/ref/create_schema.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE SCHEMA 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/create_sequence.sgml b/zh/12/ref/create_sequence.sgml index 24987272..81ad1fe9 100644 --- a/zh/12/ref/create_sequence.sgml +++ b/zh/12/ref/create_sequence.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE SEQUENCE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/create_server.sgml b/zh/12/ref/create_server.sgml index c4b79d02..7f438b0b 100644 --- a/zh/12/ref/create_server.sgml +++ b/zh/12/ref/create_server.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE SERVER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/create_statistics.sgml b/zh/12/ref/create_statistics.sgml index 4c3a0105..70391f17 100644 --- a/zh/12/ref/create_statistics.sgml +++ b/zh/12/ref/create_statistics.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE STATISTICS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/create_subscription.sgml b/zh/12/ref/create_subscription.sgml index 738cf39b..a55439cf 100644 --- a/zh/12/ref/create_subscription.sgml +++ b/zh/12/ref/create_subscription.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE SUBSCRIPTION 7 - SQL - Language Statements + SQL - 语言语句 @@ -32,19 +32,18 @@ CREATE SUBSCRIPTION subscription_name描述 - CREATE SUBSCRIPTION添加一个新的逻辑复制订阅。 - 创建订阅的用户将成为该订阅的所有者。订阅名称必须与当前数据库中 - 任何现有订阅的名称不同。 + CREATE SUBSCRIPTION为当前数据库添加一个新订阅。 + 订阅名称必须与数据库中任何现有订阅的名称不同。 - 订阅表示与发布者的复制连接。因此,除了在本地系统目录中添加定义之外, - 该命令通常还会在发布者上创建一个复制槽。 + 订阅表示与发布者的复制连接。因此,该命令不仅会在本地系统目录中添加定义, + 还会在发布者上创建一个复制槽。 - 除非订阅初始即被禁用,否则在执行该命令所在事务提交时,会启动一个 - 逻辑复制工作进程为新订阅复制数据。 + 在执行该命令所在事务提交时,会启动一个逻辑复制工作进程, + 为新订阅复制数据。 diff --git a/zh/12/ref/create_table.sgml b/zh/12/ref/create_table.sgml index b6235759..ce3dc86f 100644 --- a/zh/12/ref/create_table.sgml +++ b/zh/12/ref/create_table.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TABLE 7 - SQL - Language Statements + SQL - 语言语句 @@ -121,7 +121,7 @@ WITH ( MODULUS numeric_literal, REM 如果给出了模式名(例如 CREATE TABLE myschema.mytable ...),则表将在指定模式中创建。 否则,它将在当前模式中创建。临时表存在于一个特殊模式中,因此创建临时表时不能给出模式名。 - 表名必须与同一模式中任何其他关系(表、序列、索引、视图、物化视图或外部表)的名称不同。 + 表名必须与同一模式中任何其他表、序列、索引、视图或外部表的名称不同。 @@ -147,7 +147,7 @@ WITH ( MODULUS numeric_literal, REM - TEMPORARY or TEMP + TEMPORARYTEMP 如果指定该选项,表将创建为临时表。 @@ -161,7 +161,7 @@ WITH ( MODULUS numeric_literal, REM - 可以在 TEMPORARYTEMP 前写 GLOBALLOCAL。这在当前的 PostgreSQL 中没有区别,而且已废弃;见下文 。 + 可以在 TEMPORARYTEMP 前写 GLOBALLOCAL。这在当前的 PostgreSQL 中没有区别,而且已弃用;见下文 @@ -178,14 +178,18 @@ WITH ( MODULUS numeric_literal, REM IF NOT EXISTS - 如果已存在同名关系,则不抛出错误,而是发出通知。请注意,不能保证现有关系与原本要创建的关系有任何相似之处。 + + 如果已存在同名关系,则不抛出错误,而是发出一条提示。注意,这并不保证现有关系与本应创建出的关系有任何相似之处。 + table_name - 要创建的表的名称(可以带模式限定)。 + + 要创建的表名(可选地带模式限定)。 + @@ -201,14 +205,20 @@ WITH ( MODULUS numeric_literal, REM column_name - 要在新表中创建的列的名称。 + + 要在新表中创建的列名。 + data_type - 列的数据类型,可以包含数组说明符。有关PostgreSQL支持的数据类型的更多信息,请参见 + + 列的数据类型。这可以包括数组说明符。有关 + PostgreSQL 支持的数据类型的更多信息,请参见 。 + @@ -263,15 +273,31 @@ WITH ( MODULUS numeric_literal, REM PARTITION BY { RANGE | LIST | HASH } ( { column_name | ( expression ) } [ opclass ] [, ...] ) - 可选的PARTITION BY子句指定表的分区策略。这样创建的表称为分区表。括号内的列或表达式列表构成该表的分区键。使用范围分区或哈希分区时,分区键可以包含多个列或表达式(最多 32 个,但可以在构建PostgreSQL时更改此限制);对于列表分区,分区键则必须由单个列或表达式组成。 + + 可选的 PARTITION BY 子句指定表的分区策略。 + 这样创建的表称为分区表。 + 括号中的列或表达式列表构成该表的分区键。 + 使用范围分区或哈希分区时,分区键可以包含多个列或表达式(最多 32 个,但该限制可在构建 PostgreSQL 时调整); + 而列表分区的分区键必须由单个列或表达式组成。 + - 范围分区和列表分区需要 B-树操作符类,而哈希分区需要哈希操作符类。如果没有显式指定操作符类,则使用相应类型的默认操作符类;如果不存在默认操作符类,则报错。使用哈希分区时,所用操作符类必须实现支持函数 2(详情见)。 + + 范围分区和列表分区需要 B-树 操作符类,哈希分区则需要 hash 操作符类。 + 如果未显式指定操作符类,将使用相应类型的默认操作符类;若不存在默认操作符类,则会报错。 + 使用哈希分区时,所用操作符类必须实现支持函数 2(详见 )。 + - 分区表划分为多个子表(称为分区),通过单独的CREATE TABLE命令创建。分区表本身为空。插入该表的数据行会根据分区键中列或表达式的值路由到某个分区。如果没有现有分区匹配新行中的值,则会报错。 + + 分区表被划分为多个子表(称为分区),它们使用单独的 CREATE TABLE 命令创建。 + 分区表本身为空。插入到该表的数据行会根据分区键中列或表达式的值被路由到相应分区。 + 如果没有现有分区与新行中的值匹配,就会报错。 + 分区表不支持EXCLUDE约束;不过,可以在各个分区上定义这些约束。 - 关于表分区的更多讨论,请参见 + + 有关表分区的更多讨论,请参阅 。 + @@ -336,13 +362,13 @@ WITH ( MODULUS numeric_literal, REM 还要注意,某些元素类型(如 timestamp)具有 - "infinity" 的概念,那只是另一种可存储的值。这不同于 + “无穷大” 的概念,那只是另一种可存储的值。这不同于 MINVALUEMAXVALUE,后两者并非可存储 的实际值,而只是表示值无界的方式。MAXVALUE 可以视为大于任何 - 其他值,包括 "infinity";MINVALUE 可以视为小于任何 - 其他值,包括 "minus infinity"。因此,范围 + 其他值,包括 “无穷大”;MINVALUE 可以视为小于任何 + 其他值,包括 “负无穷大”。因此,范围 FROM ('infinity') TO (MAXVALUE) 并不是空范围;它只允许存储 - 一个值 — "infinity"。 + 一个值 — “无穷大”。 @@ -398,7 +424,12 @@ WITH ( MODULUS numeric_literal, REM 同样与 INHERITS 不同,由 LIKE 复制的列和约束不会与同名的列和约束合并。如果同一名称被显式指定,或在另一个 LIKE 子句中指定,则会报错。 - 可选的like_option子句指定要复制原表的哪些附加属性。指定INCLUDING会复制该属性,指定EXCLUDING则省略该属性。EXCLUDING为默认值。如果对同一类对象作出多次指定,则使用最后一次指定。可用选项如下: + + 可选的 like_option 子句指定还要复制原表的哪些附加属性。 + 指定 INCLUDING 表示复制该属性,指定 EXCLUDING 表示省略该属性。默认是 EXCLUDING。 + 如果对同一类对象给出了多个说明,则采用最后一个。可用选项如下: + + INCLUDING COMMENTS @@ -535,7 +566,7 @@ WITH ( MODULUS numeric_literal, REM - 一个被标记为NO INHERIT的约束将不会传播到子表。 + 标记为 NO INHERIT 的约束不会传播到子表。 @@ -561,13 +592,17 @@ WITH ( MODULUS numeric_literal, REM - GENERATED ALWAYS AS ( generation_expr ) STOREDgenerated column + GENERATED ALWAYS AS ( generation_expr ) STORED生成列 - 这个子句将该列创建为生成列。不能向该列写入数据,读取时会返回指定表达式的结果。 + + 此子句将列创建为生成列。列不可写入,读取时会返回指定表达式的结果。 + 必须使用关键字STORED,表示该列将在写入时计算并存储在磁盘上。 - 生成表达式可以引用表中的其他列,但不能引用其他生成列。使用的所有函数和操作符都必须是不可变的。不允许引用其他表。 + + 生成表达式可以引用表中的其他列,但不能引用其他生成的列。使用的任何函数和操作符都必须是不可变的。不允许引用其他表。 + @@ -598,19 +633,29 @@ WITH ( MODULUS numeric_literal, REM INCLUDE ( column_name [, ...]) (表约束) - UNIQUE约束指定表中由一个或多个列组成的一组列只能包含唯一值。表级唯一约束的行为与列级唯一约束相同,但还能够跨越多个列。因此,这个约束要求任意两行在这些列中至少有一列不同。 + + UNIQUE 约束指定表中一列或多列组成的一组只能包含唯一值。 + 表级唯一约束的行为与列级唯一约束相同,只是它还能跨越多列。因此,该约束 + 要求任意两行在这些列中至少有一列不同。 + 对于唯一约束,空值不被视为相等。 - 每个唯一约束指定的列集合,都应与为该表定义的任何其他唯一约束或主键约束指定的列集合不同。(否则,冗余的唯一约束会被丢弃。) + + 每个唯一约束都应引用一组列,这组列应不同于该表上任何其他唯一约束或 + 主键约束所引用的列集合。(否则,冗余的唯一约束将被丢弃。) + - 为多级分区层次结构建立唯一约束时,约束定义必须包含目标分区表的分区键中的所有列,以及其所有后代分区表的分区键中的所有列。 + + 在为多级分区层次结构建立唯一约束时,目标分区表分区键中的所有列,以及 + 其所有后代分区表分区键中的所有列,都必须包含在约束定义中。 + 添加唯一约束会自动在约束所用的列或列组上创建唯一 B-树索引。 可选的 INCLUDE 子句会向该索引添加一个或多个仅作为 - payload 的列:对这些列不强制唯一性,而且该索引也不能据此 + 载荷 的列:对这些列不强制唯一性,而且该索引也不能据此 进行搜索。不过,它们可以通过仅索引扫描取回。注意,尽管约束不在包含列上 强制执行,它仍然依赖于这些列。因此,对这类列执行某些操作(例如 DROP COLUMN)可能导致约束和索引被级联删除。 @@ -652,7 +697,7 @@ WITH ( MODULUS numeric_literal, REM 可选的 INCLUDE 子句会向该索引添加一个或多个仅作为 - payload 的列:对这些列不强制唯一性,而且该索引也不能据此 + 载荷 的列:对这些列不强制唯一性,而且该索引也不能据此 进行搜索。不过,它们可以通过仅索引扫描取回。注意,尽管约束不在包含列上 强制执行,它仍然依赖于这些列。因此,对这类列执行某些操作(例如 DROP COLUMN)可能导致约束和索引被级联删除。 @@ -679,11 +724,15 @@ WITH ( MODULUS numeric_literal, REM 访问方法必须支持 amgettuple(见 );目前这意味着不能使用 GIN。 虽然允许,但在排他约束上使用 B-树或 hash 索引意义不大,因为它们做不到 - 比普通唯一约束更好的事情。因此,实践中访问方法几乎总会是 + 比普通唯一约束更好的事情。因此,实践中访问方法总是 GiSTSP-GiST - predicate允许在表的一个子集上指定排他约束;内部会为此创建部分索引。请注意,谓词必须用括号括起来。 + + predicate 允许你只在表的一个 + 子集上指定排他约束;在内部,这会创建一个部分索引。注意, + predicate 周围的圆括号是必需的。 + @@ -700,7 +749,17 @@ WITH ( MODULUS numeric_literal, REM 这些子句指定外键约束,要求新表中由一个或多个列组成的列组只能包含与被引用表中某一行的被引用列中的值相匹配的值。如果省略refcolumn列表,则使用reftable的主键。否则,refcolumn列表必须引用不可延迟的唯一约束或主键约束的列,或者是非部分唯一索引的列。用户必须拥有被引用表的REFERENCES权限(可以针对整个表,也可以针对具体的被引用列)。添加外键约束需要在被引用表上获取SHARE ROW EXCLUSIVE锁。请注意,不能在临时表和永久表之间定义外键约束。 - 插入引用列的值会使用指定的匹配类型,与被引用表的被引用列中的值进行匹配。有三种匹配类型:MATCH FULLMATCH PARTIALMATCH SIMPLE(默认值)。MATCH FULL不允许多列外键中的某一列为空,除非所有外键列都为空;如果全部为空,则不要求该行在被引用表中存在匹配行。MATCH SIMPLE允许任意外键列为空;只要其中任何一列为空,就不要求该行在被引用表中存在匹配行。MATCH PARTIAL尚未实现。(当然,可以对引用列施加NOT NULL约束来防止这些情况发生。) + + 插入到引用列中的值会按照给定的匹配类型,与被引用表及其被引用列中的值进 + 行匹配。共有三种匹配类型:MATCH FULL、 + MATCH PARTIALMATCH SIMPLE + (默认值)。MATCH FULL 不允许多列外键中的某一列为 + 空,除非所有外键列都为空;如果它们都为空,则不要求该行在被引用表中有匹 + 配行。MATCH SIMPLE 允许任意外键列为空;如果其中任何一 + 列为空,则不要求该行在被引用表中有匹配行。 + MATCH PARTIAL 目前尚未实现。(当然,可以对引用列应用 + NOT NULL 约束,以防止出现这些情况。) + 此外,当被引用列中的数据发生变化时,会对本表列中的数据执行某些操作。ON DELETE子句指定删除被引用表中的被引用行时要执行的操作。同样,ON UPDATE子句指定将被引用表中的被引用列更新为新值时要执行的操作。如果行被更新,但被引用列实际上没有变化,则不执行任何操作。除NO ACTION检查以外的引用操作都不能延迟,即使该约束声明为可延迟也是如此。每个子句可以指定以下操作: @@ -720,7 +779,9 @@ WITH ( MODULUS numeric_literal, REM CASCADE - 分别删除引用被删除行的所有行,或将引用列的值更新为被引用列的新值。 + + 分别删除任何引用已删除行的行,或将引用列的值更新为被引用列的新值。 + @@ -763,7 +824,12 @@ WITH ( MODULUS numeric_literal, REM USING method - 此可选子句指定用于存储新表内容的表访问方法;该方法必须是类型为TABLE的访问方法。更多信息请参见。如果未指定此选项,则为新表选择默认表访问方法。更多信息请参见 + + 该可选子句指定存储新表内容所用的表访问方法;该方法必须是类型为 + TABLE 的访问方法。详见 。如果未 + 指定此选项,则会为新表选择默认表访问方法。详见 + 。 + @@ -794,7 +860,11 @@ WITH ( MODULUS numeric_literal, REM ON COMMIT - 临时表在事务块结束时的行为可以使用以下选项控制:ON COMMIT。三个选项是: + + 可以使用 ON COMMIT 控制临时表在事务块结束时的行为。三种 + 选项如下: + + PRESERVE ROWS @@ -858,7 +928,7 @@ WITH ( MODULUS numeric_literal, REM 存储参数 - storage parameters + 存储参数 @@ -880,7 +950,7 @@ WITH ( MODULUS numeric_literal, REM fillfactor (integer) - fillfactor storage parameter + fillfactor 存储参数 @@ -901,7 +971,7 @@ WITH ( MODULUS numeric_literal, REM toast_tuple_target (integer) - toast_tuple_target storage parameter + toast_tuple_target 存储参数 @@ -923,13 +993,13 @@ WITH ( MODULUS numeric_literal, REM parallel_workers (integer) - parallel_workers storage parameter + parallel_workers 存储参数 - 该参数设置在对该表执行并行扫描时可用于辅助扫描的工作进程数量。若未设置, + 该参数设置在对该表执行并行扫描时用于辅助扫描的工作进程数量。若未设置, 系统会根据关系大小决定一个值。规划器或使用并行扫描的实用命令实际选择的 工作进程数量可能更少,例如可能受 设置所限。 @@ -941,7 +1011,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_enabled, toast.autovacuum_enabled (boolean) - autovacuum_enabled storage parameter + autovacuum_enabled 存储参数 @@ -963,7 +1033,7 @@ WITH ( MODULUS numeric_literal, REM vacuum_index_cleanup, toast.vacuum_index_cleanup (boolean) - vacuum_index_cleanup storage parameter + vacuum_index_cleanup 存储参数 @@ -978,7 +1048,7 @@ WITH ( MODULUS numeric_literal, REM - 启用或禁用 vacuum 尝试截断删除此表末尾的空页。默认值为true。如果为trueVACUUM和 autovacuum 会执行截断,并将被截断页面的磁盘空间返还给操作系统。请注意,截断需要对表取得ACCESS EXCLUSIVE锁。如果指定了TRUNCATE参数(属于),则会覆盖此选项的值。 + 允许或禁止清理尝试截断删除此表末尾的空页。默认值为true。如果为trueVACUUM和自动清理会执行截断,并将被截断页面的磁盘空间返还给操作系统。请注意,截断需要对表取得ACCESS EXCLUSIVE锁。如果指定了TRUNCATE参数(属于),则会覆盖此选项的值。 @@ -987,7 +1057,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_vacuum_threshold, toast.autovacuum_vacuum_threshold (integer) autovacuum_vacuum_threshold - storage parameter + 存储参数 @@ -1003,7 +1073,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_vacuum_scale_factor, toast.autovacuum_vacuum_scale_factor (floating point) autovacuum_vacuum_scale_factor - storage parameter + 存储参数 @@ -1019,7 +1089,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_analyze_threshold (integer) autovacuum_analyze_threshold - storage parameter + 存储参数 @@ -1035,7 +1105,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_analyze_scale_factor (floating point) autovacuum_analyze_scale_factor - storage parameter + 存储参数 @@ -1051,7 +1121,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_vacuum_cost_delay, toast.autovacuum_vacuum_cost_delay (floating point) autovacuum_vacuum_cost_delay - storage parameter + 存储参数 @@ -1067,7 +1137,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_vacuum_cost_limit, toast.autovacuum_vacuum_cost_limit (integer) autovacuum_vacuum_cost_limit - storage parameter + 存储参数 @@ -1082,7 +1152,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_freeze_min_age, toast.autovacuum_freeze_min_age (integer) - autovacuum_freeze_min_age storage parameter + autovacuum_freeze_min_age 存储参数 @@ -1100,7 +1170,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_freeze_max_age, toast.autovacuum_freeze_max_age (integer) autovacuum_freeze_max_age - storage parameter + 存储参数 @@ -1117,7 +1187,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_freeze_table_age, toast.autovacuum_freeze_table_age (integer) - autovacuum_freeze_table_age storage parameter + autovacuum_freeze_table_age 存储参数 @@ -1132,7 +1202,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_multixact_freeze_min_age, toast.autovacuum_multixact_freeze_min_age (integer) - autovacuum_multixact_freeze_min_age storage parameter + autovacuum_multixact_freeze_min_age 存储参数 @@ -1151,7 +1221,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_multixact_freeze_max_age, toast.autovacuum_multixact_freeze_max_age (integer) autovacuum_multixact_freeze_max_age - storage parameter + 存储参数 @@ -1169,7 +1239,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_multixact_freeze_table_age, toast.autovacuum_multixact_freeze_table_age (integer) - autovacuum_multixact_freeze_table_age storage parameter + autovacuum_multixact_freeze_table_age 存储参数 @@ -1185,7 +1255,7 @@ WITH ( MODULUS numeric_literal, REM log_autovacuum_min_duration, toast.log_autovacuum_min_duration (integer) log_autovacuum_min_duration - storage parameter + 存储参数 @@ -1200,7 +1270,7 @@ WITH ( MODULUS numeric_literal, REM user_catalog_table (boolean) - user_catalog_table storage parameter + user_catalog_table 存储参数 @@ -1222,7 +1292,7 @@ WITH ( MODULUS numeric_literal, REM 注解 - PostgreSQL为每一个唯一约束和主键约束创建一个索引来强制唯一性。因此,没有必要显式地为主键列创建一个索引(详见)。 + PostgreSQL为每一个唯一约束和主键约束自动创建一个索引来强制唯一性。因此,没有必要显式地为主键列创建一个索引(详见)。 @@ -1634,7 +1704,10 @@ CREATE TABLE cities_partdef 外键约束 - 这是PostgreSQL扩展:外键约束可以引用唯一索引的列,而不是主键或唯一约束的列。 + + 外键约束可以引用唯一索引的列,而不仅限于主键或唯一约束的列,这也是 + PostgreSQL 的扩展。 + @@ -1643,9 +1716,9 @@ CREATE TABLE cities_partdef NULL 约束(实际上并不是约束)是 - PostgreSQL 对 SQL 标准的扩展;它也被其他一些数 - 据库系统采纳,以便兼容(以及与对称的 NOT NULL 约束保持一 - 致)。由于它本来就是任意列的默认值,所以它的存在只是噪声。 + PostgreSQL 对 SQL 标准的扩展;提供它是为了 + 与其他一些数据库系统兼容(以及与 NOT NULL 约束保持 + 对称)。由于它本来就是任意列的默认情况,所以它的存在只是噪声。 @@ -1675,12 +1748,12 @@ CREATE TABLE cities_partdef - 零列表 + 零列的表 PostgreSQL 允许创建没有列的表(例如 CREATE TABLE foo();)。这是对 SQL 标准的扩展,标准不允许 - 零列表。零列表本身并不十分有用,但若禁止它们,就会让 + 零列的表。零列的表本身并不十分有用,但若禁止它们,就会让 ALTER TABLE DROP COLUMN 出现奇怪的特殊情况,因此忽略这 一规范限制看起来更整洁。 @@ -1693,7 +1766,7 @@ CREATE TABLE cities_partdef PostgreSQL 允许一个表拥有多个标识列。 该标准指定一个表最多只能有一个标识列。 - 这主要是为了给模式更改或迁移提供更大的灵活性。 + 放宽这一限制主要是为了给模式更改或迁移提供更大的灵活性。 请注意,INSERT 命令仅支持一个适用于整个语句的覆盖子 句,因此对行为不同的多个标识列支持并不好。 @@ -1743,8 +1816,7 @@ CREATE TABLE cities_partdef 类型化表 - 类型化表实现了 SQL 标准的一个子集。按照标准,类型化表除了具有与底层组合 - 类型相对应的列之外,还应有一个额外的自引用列。 + 类型化表实现了 SQL 标准的一个子集。按照标准,类型化表除了具有与底层复合类型相对应的列之外,还应有一个额外的自引用列PostgreSQL 不显式支持自引用列。 diff --git a/zh/12/ref/create_table_as.sgml b/zh/12/ref/create_table_as.sgml index 978db5d5..1289b355 100644 --- a/zh/12/ref/create_table_as.sgml +++ b/zh/12/ref/create_table_as.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TABLE AS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/create_tablespace.sgml b/zh/12/ref/create_tablespace.sgml index c54f8db6..76908820 100644 --- a/zh/12/ref/create_tablespace.sgml +++ b/zh/12/ref/create_tablespace.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TABLESPACE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/create_transform.sgml b/zh/12/ref/create_transform.sgml index 865b53e5..381e3bcd 100644 --- a/zh/12/ref/create_transform.sgml +++ b/zh/12/ref/create_transform.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TRANSFORM 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/create_trigger.sgml b/zh/12/ref/create_trigger.sgml index 334721da..ec1d9608 100644 --- a/zh/12/ref/create_trigger.sgml +++ b/zh/12/ref/create_trigger.sgml @@ -10,13 +10,13 @@ PostgreSQL documentation 过渡表 - ephemeral named relation + 临时命名关系 CREATE TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -55,7 +55,7 @@ CREATE [ CONSTRAINT ] TRIGGER name UPDATEDELETE之前); 也可以在该操作完成之后引发(即在检查约束以及完成 INSERTUPDATE或 - DELETE之后);或者改为执行该操作 + DELETE之后);或者取代该操作执行 (用于视图上的插入、更新或删除)。如果触发器在事件之前引发,或者改为取代该事件执行, 则它可以跳过对当前行的操作,或者修改待插入的行 (仅适用于INSERTUPDATE操作)。 @@ -111,7 +111,7 @@ CREATE [ CONSTRAINT ] TRIGGER name TRUNCATE - 表和外部表 + @@ -124,7 +124,7 @@ CREATE [ CONSTRAINT ] TRIGGER name TRUNCATE - 表和外部表 + @@ -154,7 +154,7 @@ CREATE [ CONSTRAINT ] TRIGGER name 如果针对同一事件定义了多个同类触发器,它们将按名称的字母顺序引发。 - 当指定CONSTRAINT选项时,此命令会创建一个约束触发器。这与普通触发器相同,只是可以使用调整其触发时机。约束触发器必须是普通表(不是外部表)上的AFTER ROW触发器。它们既可以在导致触发事件的语句结束时触发,也可以在包含它的事务结束时触发;后一种情况称为延迟。也可以使用SET CONSTRAINTS强制挂起的延迟触发立即触发。约束触发器应当在其所实现的约束遭到违反时抛出异常。 + 当指定CONSTRAINT选项时,此命令会创建一个约束触发器。这与普通触发器相同,只是可以使用调整其触发时机。约束触发器必须是普通表(不是外部表)上的AFTER ROW触发器。它们既可以在导致触发事件的语句结束时触发,也可以在包含它的事务结束时触发;后一种情况称为延迟。也可以使用SET CONSTRAINTS强制尚待执行的延迟触发器立即触发。约束触发器应当在其所实现的约束遭到违反时抛出异常。 REFERENCING选项允许收集过渡关系,即包含当前 SQL 语句插入、删除或修改的全部行的行集合。该特性使触发器能够看到该语句所做更改的整体视图,而不是一次只看到一行。该选项仅允许用于不是约束触发器的AFTER触发器;如果触发器是UPDATE触发器,则不得指定column_name列表。OLD TABLE最多只能指定一次,并且只能用于可能在UPDATEDELETE上触发的触发器;它会创建一个过渡关系,其中包含该语句更新或删除的全部行的前映像。同样,NEW TABLE最多只能指定一次,并且只能用于可能在UPDATEINSERT上触发的触发器;它会创建一个过渡关系,其中包含该语句更新或插入的全部行的后映像 @@ -209,12 +209,13 @@ CREATE [ CONSTRAINT ] TRIGGER name - 对于 UPDATE 事件,可以使用以下语法指定列列表: + 对于UPDATE事件,可以使用以下语法指定列列表: UPDATE OF column_name1 [, column_name2 ... ] - 只有当列出的列中至少有一列被列为 UPDATE 命令的目标, - 或者列出的某个生成列依赖于作为 UPDATE 目标的列时,触发器才会触发。 + 只有当列出的列中至少有一列被列为UPDATE命令的目标列时, + 或者列出的列中有某个生成列依赖于作为UPDATE目标的列时, + 该触发器才会引发。 @@ -351,7 +352,7 @@ UPDATE OF column_name1 [, column_name2CREATE TRIGGER的语法中,关键字 FUNCTIONPROCEDURE 是等价的, 但无论如何,被引用的对象都必须是函数而不是过程。 - 这里使用 PROCEDURE 关键字只是出于历史原因,并且已被废弃。 + 这里使用 PROCEDURE 关键字只是出于历史原因,并且已被弃用。 diff --git a/zh/12/ref/create_tsconfig.sgml b/zh/12/ref/create_tsconfig.sgml index ec121658..974ef42a 100644 --- a/zh/12/ref/create_tsconfig.sgml +++ b/zh/12/ref/create_tsconfig.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TEXT SEARCH CONFIGURATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/create_tsdictionary.sgml b/zh/12/ref/create_tsdictionary.sgml index 25935390..2dbca552 100644 --- a/zh/12/ref/create_tsdictionary.sgml +++ b/zh/12/ref/create_tsdictionary.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TEXT SEARCH DICTIONARY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/create_tsparser.sgml b/zh/12/ref/create_tsparser.sgml index 290e30b0..6af67ab8 100644 --- a/zh/12/ref/create_tsparser.sgml +++ b/zh/12/ref/create_tsparser.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TEXT SEARCH PARSER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/create_tstemplate.sgml b/zh/12/ref/create_tstemplate.sgml index 44061296..5dd2e1c0 100644 --- a/zh/12/ref/create_tstemplate.sgml +++ b/zh/12/ref/create_tstemplate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TEXT SEARCH TEMPLATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/create_type.sgml b/zh/12/ref/create_type.sgml index 46fece29..76e85012 100644 --- a/zh/12/ref/create_type.sgml +++ b/zh/12/ref/create_type.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TYPE 7 - SQL - Language Statements + SQL - 语言语句 @@ -91,7 +91,7 @@ CREATE TYPE name 复合类型 - 第一种形式的CREATE TYPE创建复合类型。组合 + 第一种形式的CREATE TYPE创建复合类型。复合 类型由属性名和数据类型列表指定。如果某个属性的数据类型支持排序规 则,还可以指定该属性的排序规则。复合类型本质上与表的行类型相同, 但如果目的只是定义一种类型,使用CREATE TYPE @@ -280,7 +280,7 @@ CREATE TYPE name 数才知道,但仍有若干内部表示属性必须向 PostgreSQL声明。其中最重要的是 internallength。 - 基础数据类型可以是定长的,此时internallength为正整数;也可 以是变长的,此时将internallength设为 @@ -384,7 +384,7 @@ CREATE TYPE name collatable为真,则 该类型的列定义和表达式可以通过COLLATE子句携 带排序规则信息。是否实际使用这些排序规则信息取决于操作该类型的函 - 数实现;仅仅把类型标记为 collatable 并不会自动实现这一点。 + 数实现;仅仅把类型标记为支持排序规则并不会自动实现这一点。 @@ -743,7 +743,7 @@ CREATE TYPE name 以这种方式创建 shell 类型。 - PostgreSQL 7.3 以前的版本中,通常完全不创建壳类型,而是将函数中对类型名的前向引用替换为占位伪类型opaque。在 7.3 以前,cstring参数和结果也必须声明为opaque。为了支持载入旧转储文件,CREATE TYPE会接受使用opaque声明的 I/O 函数,但会发出通知,并修改函数声明以使用正确的类型。 + PostgreSQL 7.3 以前的版本中,通常完全不创建 shell 类型,而是将函数中对类型名的前向引用替换为占位伪类型opaque。在 7.3 以前,cstring参数和结果也必须声明为opaque。为了支持载入旧转储文件,CREATE TYPE会接受使用opaque声明的 I/O 函数,但会发出通知,并修改函数声明以使用正确的类型。 @@ -783,7 +783,7 @@ CREATE TYPE float8_range AS RANGE (subtype = float8, subtype_diff = float8mi); - 这个示例创建基础数据类型box,然后在表定义中使用它: + 这个示例创建基础类型box,然后在表定义中使用它: CREATE TYPE box; diff --git a/zh/12/ref/create_user.sgml b/zh/12/ref/create_user.sgml index 64ee1d8b..3cc56400 100644 --- a/zh/12/ref/create_user.sgml +++ b/zh/12/ref/create_user.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE USER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/create_user_mapping.sgml b/zh/12/ref/create_user_mapping.sgml index 7a16d2d5..d8730f6c 100644 --- a/zh/12/ref/create_user_mapping.sgml +++ b/zh/12/ref/create_user_mapping.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE USER MAPPING 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/create_view.sgml b/zh/12/ref/create_view.sgml index 37244835..e1907d33 100644 --- a/zh/12/ref/create_view.sgml +++ b/zh/12/ref/create_view.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/createdb.sgml b/zh/12/ref/createdb.sgml index e4ef529b..b23fe09b 100644 --- a/zh/12/ref/createdb.sgml +++ b/zh/12/ref/createdb.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation createdb 1 - Application + 应用程序 diff --git a/zh/12/ref/createuser.sgml b/zh/12/ref/createuser.sgml index b223e903..1d216262 100644 --- a/zh/12/ref/createuser.sgml +++ b/zh/12/ref/createuser.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation createuser 1 - Application + 应用程序 @@ -119,13 +119,10 @@ PostgreSQL documentation - (已废弃) + - - 指定新角色应自动成为指定现有角色的成员。 - 可以通过写多个开关来指定多个现有角色。 - + 指定此角色应立即作为新成员加入的现有角色。可以使用多个开关,指定此角色要加入的多个角色。 @@ -275,7 +272,7 @@ PostgreSQL documentation 新用户将不具有REPLICATION权限,关于该权限的更完整说明见。这是默认设置。 + linkend="sql-createrole"/>。 diff --git a/zh/12/ref/deallocate.sgml b/zh/12/ref/deallocate.sgml index 27b9da86..6dea341e 100644 --- a/zh/12/ref/deallocate.sgml +++ b/zh/12/ref/deallocate.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation DEALLOCATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/declare.sgml b/zh/12/ref/declare.sgml index 5f90767f..c1673288 100644 --- a/zh/12/ref/declare.sgml +++ b/zh/12/ref/declare.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation DECLARE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/delete.sgml b/zh/12/ref/delete.sgml index 387df031..11f04710 100644 --- a/zh/12/ref/delete.sgml +++ b/zh/12/ref/delete.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DELETE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/discard.sgml b/zh/12/ref/discard.sgml index 94cb7872..d29a479a 100644 --- a/zh/12/ref/discard.sgml +++ b/zh/12/ref/discard.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DISCARD 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/do.sgml b/zh/12/ref/do.sgml index 2e77e74e..a6ef1768 100644 --- a/zh/12/ref/do.sgml +++ b/zh/12/ref/do.sgml @@ -15,7 +15,7 @@ PostgreSQL documentation DO 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/drop_access_method.sgml b/zh/12/ref/drop_access_method.sgml index 407ec4cd..646100e1 100644 --- a/zh/12/ref/drop_access_method.sgml +++ b/zh/12/ref/drop_access_method.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP ACCESS METHOD 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/drop_aggregate.sgml b/zh/12/ref/drop_aggregate.sgml index 1c8a1122..9fd7ea4b 100644 --- a/zh/12/ref/drop_aggregate.sgml +++ b/zh/12/ref/drop_aggregate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP AGGREGATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/drop_cast.sgml b/zh/12/ref/drop_cast.sgml index 73860e3c..5e330ae0 100644 --- a/zh/12/ref/drop_cast.sgml +++ b/zh/12/ref/drop_cast.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP CAST 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/drop_collation.sgml b/zh/12/ref/drop_collation.sgml index b90849fc..b10b3206 100644 --- a/zh/12/ref/drop_collation.sgml +++ b/zh/12/ref/drop_collation.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP COLLATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/drop_conversion.sgml b/zh/12/ref/drop_conversion.sgml index b63d1291..35009708 100644 --- a/zh/12/ref/drop_conversion.sgml +++ b/zh/12/ref/drop_conversion.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP CONVERSION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/drop_database.sgml b/zh/12/ref/drop_database.sgml index e9e9456d..7d8eea80 100644 --- a/zh/12/ref/drop_database.sgml +++ b/zh/12/ref/drop_database.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP DATABASE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/drop_domain.sgml b/zh/12/ref/drop_domain.sgml index d43f95c6..b292b189 100644 --- a/zh/12/ref/drop_domain.sgml +++ b/zh/12/ref/drop_domain.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP DOMAIN 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/drop_event_trigger.sgml b/zh/12/ref/drop_event_trigger.sgml index 80020f78..f4f0053f 100644 --- a/zh/12/ref/drop_event_trigger.sgml +++ b/zh/12/ref/drop_event_trigger.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP EVENT TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -30,7 +30,7 @@ DROP EVENT TRIGGER [ IF EXISTS ] name DROP EVENT TRIGGER移除一个现有的事件触发器。 - 要执行此命令,当前用户必须是该事件触发器的拥有者。 + 要执行此命令,当前用户必须是该事件触发器的所有者。 @@ -99,7 +99,7 @@ DROP EVENT TRIGGER snitch; - 另见 + 参见 diff --git a/zh/12/ref/drop_extension.sgml b/zh/12/ref/drop_extension.sgml index f01f950b..eb209195 100644 --- a/zh/12/ref/drop_extension.sgml +++ b/zh/12/ref/drop_extension.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP EXTENSION 7 - SQL - Language Statements + SQL - 语言语句 @@ -53,8 +53,8 @@ DROP EXTENSION [ IF EXISTS ] name [ name - 已安装扩展的名称。 - + 一个已安装扩展的名称。 + @@ -85,7 +85,7 @@ DROP EXTENSION [ IF EXISTS ] name [ DROP EXTENSION hstore; - 如果数据库中正在使用hstore的任何对象, + 如果数据库中使用了hstore的任何对象, 例如某些表具有hstore类型的列,则该命令会失败。 加上CASCADE选项可以强制一并移除这些依赖对象。 diff --git a/zh/12/ref/drop_foreign_data_wrapper.sgml b/zh/12/ref/drop_foreign_data_wrapper.sgml index 9902c875..6f781f31 100644 --- a/zh/12/ref/drop_foreign_data_wrapper.sgml +++ b/zh/12/ref/drop_foreign_data_wrapper.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP FOREIGN DATA WRAPPER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/drop_foreign_table.sgml b/zh/12/ref/drop_foreign_table.sgml index 0b4d0bbd..c420e4ba 100644 --- a/zh/12/ref/drop_foreign_table.sgml +++ b/zh/12/ref/drop_foreign_table.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP FOREIGN TABLE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/drop_function.sgml b/zh/12/ref/drop_function.sgml index 97b28a9b..84d45502 100644 --- a/zh/12/ref/drop_function.sgml +++ b/zh/12/ref/drop_function.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP FUNCTION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/drop_group.sgml b/zh/12/ref/drop_group.sgml index 6ca1c03f..a4bace0f 100644 --- a/zh/12/ref/drop_group.sgml +++ b/zh/12/ref/drop_group.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP GROUP 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/drop_index.sgml b/zh/12/ref/drop_index.sgml index b65b810b..d7f892d9 100644 --- a/zh/12/ref/drop_index.sgml +++ b/zh/12/ref/drop_index.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP INDEX 7 - SQL - Language Statements + SQL - 语言语句 @@ -57,7 +57,7 @@ DROP INDEX [ CONCURRENTLY ] [ IF EXISTS ] name 对于临时表,DROP INDEX始终是非并发的, - 因为没有其他会话可以访问它们,而且非并发删除索引的成本更低。 + 因为没有其他会话可以访问它们,而且非并发删除索引的代价更低。 @@ -66,7 +66,7 @@ DROP INDEX [ CONCURRENTLY ] [ IF EXISTS ] nameIF EXISTS - 如果该索引不存在,则不要抛出错误。这种情况下会发出一个提示。 + 如果该索引不存在,则不要抛出错误。这种情况下会发出一条提示。 diff --git a/zh/12/ref/drop_language.sgml b/zh/12/ref/drop_language.sgml index 1dcebc91..55d5fa0b 100644 --- a/zh/12/ref/drop_language.sgml +++ b/zh/12/ref/drop_language.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP LANGUAGE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/drop_materialized_view.sgml b/zh/12/ref/drop_materialized_view.sgml index f3682552..71ad4326 100644 --- a/zh/12/ref/drop_materialized_view.sgml +++ b/zh/12/ref/drop_materialized_view.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP MATERIALIZED VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/drop_opclass.sgml b/zh/12/ref/drop_opclass.sgml index c3dd2e74..9d67dc64 100644 --- a/zh/12/ref/drop_opclass.sgml +++ b/zh/12/ref/drop_opclass.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP OPERATOR CLASS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/drop_operator.sgml b/zh/12/ref/drop_operator.sgml index 64533bef..724a6ffc 100644 --- a/zh/12/ref/drop_operator.sgml +++ b/zh/12/ref/drop_operator.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP OPERATOR 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/drop_opfamily.sgml b/zh/12/ref/drop_opfamily.sgml index 8e7097f9..06223045 100644 --- a/zh/12/ref/drop_opfamily.sgml +++ b/zh/12/ref/drop_opfamily.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP OPERATOR FAMILY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/drop_owned.sgml b/zh/12/ref/drop_owned.sgml index 05e28e68..81bb029c 100644 --- a/zh/12/ref/drop_owned.sgml +++ b/zh/12/ref/drop_owned.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP OWNED 7 - SQL - Language Statements + SQL - 语言语句 @@ -31,7 +31,7 @@ DROP OWNED BY { name | CURRENT_USER DROP OWNED删除当前数据库中由指定角色之一拥有的所有对象。 同时,授予给这些角色的、针对当前数据库中的对象或共享对象 - (数据库、表空间、配置参数)的任何权限也会被撤销。 + (数据库、表空间)的任何权限也会被撤销。 diff --git a/zh/12/ref/drop_policy.sgml b/zh/12/ref/drop_policy.sgml index ee64ffa0..a939a688 100644 --- a/zh/12/ref/drop_policy.sgml +++ b/zh/12/ref/drop_policy.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP POLICY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/drop_procedure.sgml b/zh/12/ref/drop_procedure.sgml index 145a6c99..62c601f7 100644 --- a/zh/12/ref/drop_procedure.sgml +++ b/zh/12/ref/drop_procedure.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP PROCEDURE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/drop_publication.sgml b/zh/12/ref/drop_publication.sgml index 6bc4bf59..048c1756 100644 --- a/zh/12/ref/drop_publication.sgml +++ b/zh/12/ref/drop_publication.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP PUBLICATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/drop_role.sgml b/zh/12/ref/drop_role.sgml index 6e06020f..d85224dd 100644 --- a/zh/12/ref/drop_role.sgml +++ b/zh/12/ref/drop_role.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP ROLE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/drop_routine.sgml b/zh/12/ref/drop_routine.sgml index 5488da87..491d93eb 100644 --- a/zh/12/ref/drop_routine.sgml +++ b/zh/12/ref/drop_routine.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP ROUTINE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/drop_rule.sgml b/zh/12/ref/drop_rule.sgml index ddb561f4..2968d946 100644 --- a/zh/12/ref/drop_rule.sgml +++ b/zh/12/ref/drop_rule.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP RULE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/drop_schema.sgml b/zh/12/ref/drop_schema.sgml index 9f622df3..94843c9a 100644 --- a/zh/12/ref/drop_schema.sgml +++ b/zh/12/ref/drop_schema.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP SCHEMA 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/drop_sequence.sgml b/zh/12/ref/drop_sequence.sgml index 4ba78640..586d3038 100644 --- a/zh/12/ref/drop_sequence.sgml +++ b/zh/12/ref/drop_sequence.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP SEQUENCE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/drop_server.sgml b/zh/12/ref/drop_server.sgml index 0864a4c2..8bdacdc8 100644 --- a/zh/12/ref/drop_server.sgml +++ b/zh/12/ref/drop_server.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP SERVER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/drop_statistics.sgml b/zh/12/ref/drop_statistics.sgml index 3120dc06..4773bfa8 100644 --- a/zh/12/ref/drop_statistics.sgml +++ b/zh/12/ref/drop_statistics.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP STATISTICS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/drop_subscription.sgml b/zh/12/ref/drop_subscription.sgml index ea0f7e7c..455ea597 100644 --- a/zh/12/ref/drop_subscription.sgml +++ b/zh/12/ref/drop_subscription.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP SUBSCRIPTION 7 - SQL - Language Statements + SQL - 语言语句 @@ -32,9 +32,7 @@ DROP SUBSCRIPTION [ IF EXISTS ] nameDROP SUBSCRIPTION从数据库集簇中移除一个订阅。 - - 要执行此命令,用户必须是该订阅的拥有者。 - + 只有超级用户才能删除订阅。 如果订阅与复制槽相关联,则不能在事务块内执行DROP SUBSCRIPTION。(可以使用ALTER SUBSCRIPTION来取消设置该槽。) diff --git a/zh/12/ref/drop_table.sgml b/zh/12/ref/drop_table.sgml index 6193c2e3..50b73e31 100644 --- a/zh/12/ref/drop_table.sgml +++ b/zh/12/ref/drop_table.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TABLE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/drop_tablespace.sgml b/zh/12/ref/drop_tablespace.sgml index c8b09e59..a31fd70f 100644 --- a/zh/12/ref/drop_tablespace.sgml +++ b/zh/12/ref/drop_tablespace.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TABLESPACE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/drop_transform.sgml b/zh/12/ref/drop_transform.sgml index e606b35b..dfba428d 100644 --- a/zh/12/ref/drop_transform.sgml +++ b/zh/12/ref/drop_transform.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TRANSFORM 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/drop_trigger.sgml b/zh/12/ref/drop_trigger.sgml index 1f85cf41..160a5ebd 100644 --- a/zh/12/ref/drop_trigger.sgml +++ b/zh/12/ref/drop_trigger.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -30,7 +30,7 @@ DROP TRIGGER [ IF EXISTS ] name ON DROP TRIGGER移除一个现有触发器的定义。 - 要执行此命令,当前用户必须是定义该触发器的表的拥有者。 + 要执行此命令,当前用户必须是定义该触发器的表的所有者。 @@ -109,7 +109,7 @@ DROP TRIGGER if_dist_exists ON films; - 另见 + 参见 diff --git a/zh/12/ref/drop_tsconfig.sgml b/zh/12/ref/drop_tsconfig.sgml index 2a7cdc52..ea139802 100644 --- a/zh/12/ref/drop_tsconfig.sgml +++ b/zh/12/ref/drop_tsconfig.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TEXT SEARCH CONFIGURATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/drop_tsdictionary.sgml b/zh/12/ref/drop_tsdictionary.sgml index 1eb24189..316c5d00 100644 --- a/zh/12/ref/drop_tsdictionary.sgml +++ b/zh/12/ref/drop_tsdictionary.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TEXT SEARCH DICTIONARY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/drop_tsparser.sgml b/zh/12/ref/drop_tsparser.sgml index 0cfa7acd..a65f47be 100644 --- a/zh/12/ref/drop_tsparser.sgml +++ b/zh/12/ref/drop_tsparser.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TEXT SEARCH PARSER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/drop_tstemplate.sgml b/zh/12/ref/drop_tstemplate.sgml index 282231c5..fa1faab0 100644 --- a/zh/12/ref/drop_tstemplate.sgml +++ b/zh/12/ref/drop_tstemplate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TEXT SEARCH TEMPLATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/drop_type.sgml b/zh/12/ref/drop_type.sgml index dab5bfa0..2f139da5 100644 --- a/zh/12/ref/drop_type.sgml +++ b/zh/12/ref/drop_type.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TYPE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/drop_user.sgml b/zh/12/ref/drop_user.sgml index 48d31af4..32bedce7 100644 --- a/zh/12/ref/drop_user.sgml +++ b/zh/12/ref/drop_user.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP USER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/drop_user_mapping.sgml b/zh/12/ref/drop_user_mapping.sgml index 5cfe0086..029b4362 100644 --- a/zh/12/ref/drop_user_mapping.sgml +++ b/zh/12/ref/drop_user_mapping.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP USER MAPPING 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/drop_view.sgml b/zh/12/ref/drop_view.sgml index 4feb47e5..8f995245 100644 --- a/zh/12/ref/drop_view.sgml +++ b/zh/12/ref/drop_view.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/dropdb.sgml b/zh/12/ref/dropdb.sgml index 88b5710f..84c26ebe 100644 --- a/zh/12/ref/dropdb.sgml +++ b/zh/12/ref/dropdb.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation dropdb 1 - Application + 应用程序 diff --git a/zh/12/ref/dropuser.sgml b/zh/12/ref/dropuser.sgml index b20776af..b3985190 100644 --- a/zh/12/ref/dropuser.sgml +++ b/zh/12/ref/dropuser.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation dropuser 1 - Application + 应用程序 diff --git a/zh/12/ref/ecpg-ref.sgml b/zh/12/ref/ecpg-ref.sgml index 0548b14e..e5a6d1a1 100644 --- a/zh/12/ref/ecpg-ref.sgml +++ b/zh/12/ref/ecpg-ref.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ecpg 1 - Application + 应用程序 diff --git a/zh/12/ref/end.sgml b/zh/12/ref/end.sgml index 1ad9eb4d..5268db6a 100644 --- a/zh/12/ref/end.sgml +++ b/zh/12/ref/end.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation END 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/execute.sgml b/zh/12/ref/execute.sgml index 7537072b..81cf7335 100644 --- a/zh/12/ref/execute.sgml +++ b/zh/12/ref/execute.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation EXECUTE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/explain.sgml b/zh/12/ref/explain.sgml index 6d8e14e6..ecd3b6d2 100644 --- a/zh/12/ref/explain.sgml +++ b/zh/12/ref/explain.sgml @@ -21,7 +21,7 @@ PostgreSQL documentation EXPLAIN 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/fetch.sgml b/zh/12/ref/fetch.sgml index 7e6abb4b..d5392d7f 100644 --- a/zh/12/ref/fetch.sgml +++ b/zh/12/ref/fetch.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation FETCH 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/grant.sgml b/zh/12/ref/grant.sgml index 96dca26e..d88b5098 100644 --- a/zh/12/ref/grant.sgml +++ b/zh/12/ref/grant.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation GRANT 7 - SQL - Language Statements + SQL - 语言语句 @@ -96,7 +96,7 @@ GRANT role_name [, ...] TO 描述 - GRANT 命令有两个基本变体:一种是在数据库对象(表、列、视图、外部表、序列、数据库、外部数据包装器、外部服务器、函数、过程、过程语言、大对象、配置参数、模式、表空间或类型)上授予权限,另一种是授予角色成员资格。这两种变体在许多方面相似,但差异也足够大,因此分别说明。 + GRANT 命令有两个基本变体:一种是在数据库对象(表、列、视图、外部表、序列、数据库、外部数据包装器、外部服务器、函数、过程、过程语言、模式或表空间)上授予权限,另一种是授予角色成员资格。这两种变体在许多方面相似,但差异也足够大,因此分别说明。 @@ -224,7 +224,7 @@ GRANT role_name [, ...] TO - 如果超级用户选择执行 GRANTREVOKE 命令,该命令会像由受影响对象的拥有者发出一样执行。特别是,通过这种命令授予的权限看起来会像是由对象拥有者授予的。(对于角色成员资格,则看起来像是由引导超级用户授予的。) + 如果超级用户选择执行 GRANTREVOKE 命令,该命令会像由受影响对象的拥有者发出一样执行。特别是,通过这种命令授予的权限看起来会像是由对象拥有者授予的。(对于角色成员资格,则看起来像是由被授予成员资格的角色本身授予的。) @@ -302,7 +302,7 @@ GRANT admins TO joe; - 数据库、表空间、模式、语言以及配置参数上的权限都是 PostgreSQL 扩展。 + 数据库、表空间、模式和语言上的权限都是 PostgreSQL 扩展。 diff --git a/zh/12/ref/import_foreign_schema.sgml b/zh/12/ref/import_foreign_schema.sgml index 6e912201..1957d60a 100644 --- a/zh/12/ref/import_foreign_schema.sgml +++ b/zh/12/ref/import_foreign_schema.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation IMPORT FOREIGN SCHEMA 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/initdb.sgml b/zh/12/ref/initdb.sgml index 67179651..9a7d0995 100644 --- a/zh/12/ref/initdb.sgml +++ b/zh/12/ref/initdb.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation initdb 1 - Application + 应用程序 diff --git a/zh/12/ref/insert.sgml b/zh/12/ref/insert.sgml index 5293b5ac..e3883f34 100644 --- a/zh/12/ref/insert.sgml +++ b/zh/12/ref/insert.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation INSERT 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/listen.sgml b/zh/12/ref/listen.sgml index 5b96dd0b..59d96afb 100644 --- a/zh/12/ref/listen.sgml +++ b/zh/12/ref/listen.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation LISTEN 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/load.sgml b/zh/12/ref/load.sgml index bb0adb7c..89bdb114 100644 --- a/zh/12/ref/load.sgml +++ b/zh/12/ref/load.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation LOAD 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/lock.sgml b/zh/12/ref/lock.sgml index 8b49adb5..50085983 100644 --- a/zh/12/ref/lock.sgml +++ b/zh/12/ref/lock.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation LOCK 7 - SQL - Language Statements + SQL - 语言语句 @@ -55,7 +55,7 @@ LOCK [ TABLE ] [ ONLY ] name [ * ] 因为SHARE锁模式与写入者获取的ROW EXCLUSIVE锁冲突, 而LOCK TABLE name IN SHARE MODE - 语句会一直等待,直到任何并发持有ROW EXCLUSIVE模式锁的事务提交或回滚。 + 语句会一直等待,直到所有并发持有ROW EXCLUSIVE模式锁的事务提交或回滚。 因此,一旦获得该锁,就不存在尚未提交的写入;而且在释放该锁之前,也不会有新的写入开始。 diff --git a/zh/12/ref/move.sgml b/zh/12/ref/move.sgml index e90c1b88..961359c8 100644 --- a/zh/12/ref/move.sgml +++ b/zh/12/ref/move.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation MOVE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/notify.sgml b/zh/12/ref/notify.sgml index a90a45ef..938baf9f 100644 --- a/zh/12/ref/notify.sgml +++ b/zh/12/ref/notify.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation NOTIFY 7 - SQL - Language Statements + SQL - 语言语句 @@ -88,7 +88,7 @@ NOTIFY channel [ , 注解 - 系统中有一个队列,用来保存那些已经发送但尚未被所有监听会话处理的通知。如果这个队列被塞满,那么调用NOTIFY的事务会在提交时失败。该队列非常大(标准安装中为 8GB),几乎足以满足所有用例。不过,如果某个会话执行了LISTEN后又长时间停留在一个事务里,就无法进行清理。一旦队列占用超过一半,你就会在日志文件中看到警告,指出究竟是哪个会话阻碍了清理。在这种情况下,应确保该会话结束其当前事务,以便清理能够继续进行。 + 系统中有一个队列,用来保存那些已经发送但尚未被所有监听会话处理的通知。如果这个队列被塞满,那么调用NOTIFY的事务会在提交时失败。该队列非常大(标准安装中为 8GB),几乎足以满足所有用例。不过,如果某个会话执行了LISTEN后又长时间停留在一个事务里,就无法进行清理。一旦队列占用达到一半,你就会在日志文件中看到警告,指出究竟是哪个会话阻碍了清理。在这种情况下,应确保该会话结束其当前事务,以便清理能够继续进行。 函数pg_notification_queue_usage返回当前被待处理通知占用的队列比例。详见。 diff --git a/zh/12/ref/pg_basebackup.sgml b/zh/12/ref/pg_basebackup.sgml index d276b186..8dc3aed7 100644 --- a/zh/12/ref/pg_basebackup.sgml +++ b/zh/12/ref/pg_basebackup.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_basebackup 1 - Application + 应用程序 @@ -37,7 +37,7 @@ PostgreSQL documentation 备份通过使用复制协议的普通PostgreSQL连接进行。建立连接时必须使用超级用户或具有REPLICATION权限(参见)的用户,并且pg_hba.conf必须明确允许复制连接。服务器还必须将设置得足够高,以便至少为备份保留一个可用会话,并在使用 WAL 流式传输时再为其保留一个会话。 - 可以同时运行多个pg_basebackup,但从性能角度来看,通常最好只执行一次备份,然后复制其结果。 + 可以同时运行多个pg_basebackup,但从性能角度来看,最好只执行一次备份,然后复制其结果。 @@ -160,7 +160,7 @@ PostgreSQL documentation - 目前,此选项仅适用于 plain 输出格式;如果选择了 tar 格式,则会被忽略。 + 目前,此选项仅适用于 普通文件 输出格式;如果选择了 tar 格式,则会被忽略。 @@ -168,7 +168,7 @@ PostgreSQL documentation - 指定预写式日志目录的位置。waldir必须是绝对路径。只有在备份采用 plain 模式时,才能指定预写式日志目录。 + 指定预写式日志目录的位置。waldir必须是绝对路径。只有在备份采用 普通文件 模式时,才能指定预写式日志目录。 @@ -238,7 +238,7 @@ PostgreSQL documentation - 启用 tar 文件输出的 gzip 压缩,使用默认压缩级别。压缩仅在使用 tar 格式时可用,并且所有 tar 文件名都会自动添加.gz后缀。 + 启用 tar 文件输出的 gzip 压缩,并指定压缩级别(0 到 9,其中 0 表示不压缩,9 表示最佳压缩)。压缩仅在使用 tar 格式时可用,并且所有 tar 文件名都会自动添加.gz后缀。 @@ -286,7 +286,7 @@ PostgreSQL documentation - 请注意,无论如何表空间目录都不会被清理。 + 请注意,无论是否使用此选项,表空间目录都不会被清理。 @@ -446,7 +446,10 @@ PostgreSQL documentation - 还可以使用其他选项: + + 其他选项也可用: + + @@ -486,18 +489,18 @@ PostgreSQL documentation - 注意 + 注解 在备份开始时,需要在源服务器上执行一次检查点。这可能需要一些时间(尤其是在未使用--checkpoint=fast选项时);在此期间,pg_basebackup看起来会处于空闲状态。 - 备份将包括数据目录和表空间中的所有文件,包括配置文件以及第三方放在这些目录中的任何额外文件,但由 PostgreSQL 管理的某些临时文件和操作系统文件除外。不过,只有普通文件和目录会被复制,但用于表空间的符号链接会被保留。指向 PostgreSQL 已知某些目录的符号链接会被复制为空目录。其他符号链接和特殊设备文件则会被跳过。具体细节见。 + 备份将包括数据目录和表空间中的所有文件,包括配置文件以及第三方放在这些目录中的任何额外文件,但由 PostgreSQL 管理的某些临时文件除外。不过,只有普通文件和目录会被复制,但用于表空间的符号链接会被保留。指向 PostgreSQL 已知某些目录的符号链接会被复制为空目录。其他符号链接和特殊设备文件则会被跳过。具体细节见 - 在 plain 格式中,除非使用了--tablespace-mapping选项,否则表空间会备份到其在源服务器上的相同路径。如果不使用此选项,那么当表空间正在使用时,就无法在与服务器相同的主机上执行 plain 格式的基础备份,因为备份将不得不写入与原始表空间相同的目录位置。 + 在 普通文件 格式中,除非使用了--tablespace-mapping选项,否则表空间会备份到其在源服务器上的相同路径。如果不使用此选项,那么当表空间正在使用时,就无法在与服务器相同的主机上执行 普通文件 格式的基础备份,因为备份将不得不写入与原始表空间相同的目录位置。 使用 tar 格式时,用户有责任在启动 PostgreSQL 服务器之前解包每个 tar 文件。如果存在额外表空间,则其 tar 文件必须解包到正确的位置。在这种情况下,服务器会根据tablespace_map文件的内容,为这些表空间创建符号链接,该文件包含在base.tar文件中。 @@ -541,7 +544,7 @@ PostgreSQL documentation - 参见 + 另见 diff --git a/zh/12/ref/pg_checksums.sgml b/zh/12/ref/pg_checksums.sgml index d81f663a..135038a0 100644 --- a/zh/12/ref/pg_checksums.sgml +++ b/zh/12/ref/pg_checksums.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_checksums 1 - Application + 应用程序 diff --git a/zh/12/ref/pg_config-ref.sgml b/zh/12/ref/pg_config-ref.sgml index 37dd43a8..7ea2f196 100644 --- a/zh/12/ref/pg_config-ref.sgml +++ b/zh/12/ref/pg_config-ref.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_config 1 - Application + 应用程序 diff --git a/zh/12/ref/pg_controldata.sgml b/zh/12/ref/pg_controldata.sgml index 818db6cc..5435edfa 100644 --- a/zh/12/ref/pg_controldata.sgml +++ b/zh/12/ref/pg_controldata.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_controldata 1 - Application + 应用程序 diff --git a/zh/12/ref/pg_ctl-ref.sgml b/zh/12/ref/pg_ctl-ref.sgml index 8807f74f..3017fc06 100644 --- a/zh/12/ref/pg_ctl-ref.sgml +++ b/zh/12/ref/pg_ctl-ref.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_ctl 1 - Application + 应用程序 @@ -158,7 +158,7 @@ PostgreSQL documentation - 模式会关闭在指定数据目录中运行的服务器。可以使用选项选择三种不同的关闭方法。Smart模式不允许新连接,然后等待所有现有客户端断开。如果服务器处于热备状态,那么在所有客户端断开后,恢复和流复制都会终止。Fast模式(默认值)不等待客户端断开。所有活动事务都会回滚,客户端会被强制断开,然后服务器关闭。Immediate模式会立即中止所有服务器进程,而不执行干净关闭。这样会导致服务器在下次启动时进入一次崩溃恢复周期。 + 模式会关闭在指定数据目录中运行的服务器。可以使用选项选择三种不同的关闭方法。Smart模式不允许新连接,然后等待所有现有客户端断开,以及所有在线备份结束。如果服务器处于热备状态,那么在所有客户端断开后,恢复和流复制都会终止。Fast模式(默认值)不等待客户端断开,并会终止正在进行的在线备份。所有活动事务都会回滚,客户端会被强制断开,然后服务器关闭。Immediate模式会立即中止所有服务器进程,而不执行干净关闭。这样会导致服务器在下次启动时进入一次崩溃恢复周期。 diff --git a/zh/12/ref/pg_dump.sgml b/zh/12/ref/pg_dump.sgml index e217de33..2cdc73f1 100644 --- a/zh/12/ref/pg_dump.sgml +++ b/zh/12/ref/pg_dump.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_dump 1 - Application + 应用程序 @@ -290,7 +290,9 @@ PostgreSQL documentation 同步快照特性,就无法保证各个工作任务在各自连接中看到相同的数据,这会 导致备份不一致。 - 如果要对 9.2 之前的服务器执行并行转储,必须确保从主进程连接数据库起,到最后一个工作任务连接数据库为止,数据库内容都不发生变化。最简单的方法是在开始备份之前,暂停所有访问数据库并修改数据的进程(DDL 和 DML)。对 9.2 之前的服务器使用参数也是必需的,即使用pg_dump -j连接这些PostgreSQL服务器时。 + + 如果要对 9.2 之前的服务器执行并行转储,必须确保从主进程连接数据库起,到最后一个工作任务连接数据库为止,数据库内容都不发生变化。最简单的方法是在开始备份之前,暂停所有访问数据库并修改数据的进程(DDL 和 DML)。对 9.2 之前的PostgreSQL服务器运行pg_dump -j时,还必须指定参数。 + diff --git a/zh/12/ref/pg_dumpall.sgml b/zh/12/ref/pg_dumpall.sgml index 0b83496a..a586377f 100644 --- a/zh/12/ref/pg_dumpall.sgml +++ b/zh/12/ref/pg_dumpall.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_dumpall 1 - Application + 应用程序 @@ -32,7 +32,7 @@ PostgreSQL documentation pg_dumpall是一个实用程序,用于写出(转储)一个集簇中的所有PostgreSQL数据库到一个脚本文件中。该脚本文件包含SQL命令,可作为的输入来恢复这些数据库。它通过对集簇中的每个数据库调用来实现这一点。pg_dumpall还会转储所有数据库共有的全局对象,即数据库角色、表空间以及配置参数的权限授予。 + linkend="app-psql"/>的输入来恢复这些数据库。它通过对集簇中的每个数据库调用来实现这一点。pg_dumpall还会转储所有数据库共有的全局对象,即数据库角色、表空间。 (pg_dump不会保存这些对象。) diff --git a/zh/12/ref/pg_isready.sgml b/zh/12/ref/pg_isready.sgml index 31f6aea0..541352d6 100644 --- a/zh/12/ref/pg_isready.sgml +++ b/zh/12/ref/pg_isready.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_isready 1 - Application + 应用程序 diff --git a/zh/12/ref/pg_receivewal.sgml b/zh/12/ref/pg_receivewal.sgml index 0d65f992..093aa95c 100644 --- a/zh/12/ref/pg_receivewal.sgml +++ b/zh/12/ref/pg_receivewal.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_receivewal 1 - Application + 应用程序 diff --git a/zh/12/ref/pg_recvlogical.sgml b/zh/12/ref/pg_recvlogical.sgml index 14d657a5..d2344de3 100644 --- a/zh/12/ref/pg_recvlogical.sgml +++ b/zh/12/ref/pg_recvlogical.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_recvlogical 1 - Application + 应用程序 @@ -60,7 +60,9 @@ PostgreSQL documentation - 删除由指定名称的复制槽,然后退出。 + + 删除由指定名称的复制槽,然后退出。 + @@ -72,9 +74,13 @@ PostgreSQL documentation 如果服务端的更改流因服务器关闭或断开连接而结束,则除非指定了,否则会循环重试。 - 流格式由创建槽时指定的输出插件决定。 + + 流格式由创建该槽时指定的输出插件决定。 + - 必须连接到创建槽时使用的同一个数据库。 + + 该连接必须连到创建该槽时所用的同一个数据库。 + @@ -111,7 +117,9 @@ PostgreSQL documentation - 将接收到的已解码事务数据写入此文件。使用-表示stdout + + 将接收到并解码后的事务数据写入该文件。指定-表示写入stdout。 + @@ -122,7 +130,7 @@ PostgreSQL documentation 指定pg_recvlogical应当以多高的频率发起fsync()调用, - 以确保输出文件被安全地刷入磁盘。 + 以确保输出文件安全刷盘。 @@ -141,14 +149,20 @@ PostgreSQL documentation - 模式下,从给定的 LSN 开始复制。有关其效果的详细信息,请参阅中的文档。在其他模式下忽略此选项。 + + 在模式下,从给定的 LSN 开始复制。关于其影响的详细信息,请参见 + 中的说明。 + 在其他模式下会忽略此选项。 + - 指定且指定名称的槽已存在时,不报错。 + + 当指定且指定名称的槽已存在时,不报错。 + @@ -156,7 +170,9 @@ PostgreSQL documentation - 当与服务器的连接丢失时,不循环重试,直接退出。 + + 当与服务器的连接丢失时,不要循环重试,直接退出。 + @@ -164,7 +180,10 @@ PostgreSQL documentation - 将选项name传递给输出插件,如果指定了选项值value,也一并传递。有哪些选项以及它们的效果取决于所用的输出插件。 + + 将选项name传递给输出插件;如果指定了value, + 则将其用作该选项的值。可用选项及其效果取决于所使用的输出插件。 + @@ -172,7 +191,10 @@ PostgreSQL documentation - 创建槽时,使用指定的逻辑解码输出插件。参见。如果槽已存在,此选项不起作用。 + + 创建该槽时,使用指定的逻辑解码输出插件。参见。 + 如果该槽已经存在,则此选项不起作用。 + @@ -180,7 +202,9 @@ PostgreSQL documentation - 此选项与中同名选项的效果相同。请参阅那里的说明。 + + 该选项与中同名选项的效果相同。参见该处说明。 + @@ -188,7 +212,11 @@ PostgreSQL documentation - 模式下,使用名为slot_name的现有逻辑复制槽。在模式下,创建此名称的槽。在模式下,删除此名称的槽。 + + 在模式下,使用名为slot_name的现有逻辑复制槽。 + 在模式下,以此名称创建该槽。 + 在模式下,删除此名称的槽。 + @@ -196,7 +224,9 @@ PostgreSQL documentation - 启用详细模式。 + + 启用详细模式。 + @@ -240,7 +270,9 @@ PostgreSQL documentation - 连接时使用的用户名。默认为当前操作系统用户名。 + + 用于连接的用户名。默认为当前操作系统用户名。 + @@ -282,7 +314,9 @@ PostgreSQL documentation - 打印pg_recvlogical的版本并退出。 + + 打印pg_recvlogical的版本并退出。 + @@ -290,7 +324,9 @@ PostgreSQL documentation - 显示pg_recvlogical命令行参数的帮助并退出。 + + 显示pg_recvlogical命令行参数的帮助并退出。 + @@ -311,7 +347,7 @@ PostgreSQL documentation - 环境 + 注解 如果源集簇启用了组权限,pg_recvlogical会在接收到的 WAL 文件上保留这些组权限。 diff --git a/zh/12/ref/pg_resetwal.sgml b/zh/12/ref/pg_resetwal.sgml index eaa27a9e..c5c3c18a 100644 --- a/zh/12/ref/pg_resetwal.sgml +++ b/zh/12/ref/pg_resetwal.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_resetwal 1 - Application + 应用程序 diff --git a/zh/12/ref/pg_restore.sgml b/zh/12/ref/pg_restore.sgml index 4b494ede..69d5f9b9 100644 --- a/zh/12/ref/pg_restore.sgml +++ b/zh/12/ref/pg_restore.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_restore 1 - Application + 应用程序 diff --git a/zh/12/ref/pg_rewind.sgml b/zh/12/ref/pg_rewind.sgml index 784de7bd..506d008e 100644 --- a/zh/12/ref/pg_rewind.sgml +++ b/zh/12/ref/pg_rewind.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_rewind 1 - Application + 应用程序 diff --git a/zh/12/ref/pg_waldump.sgml b/zh/12/ref/pg_waldump.sgml index 9a62d259..46d6eb53 100644 --- a/zh/12/ref/pg_waldump.sgml +++ b/zh/12/ref/pg_waldump.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_waldump 1 - Application + 应用程序 diff --git a/zh/12/ref/pgarchivecleanup.sgml b/zh/12/ref/pgarchivecleanup.sgml index ac769603..f8f94822 100644 --- a/zh/12/ref/pgarchivecleanup.sgml +++ b/zh/12/ref/pgarchivecleanup.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_archivecleanup 1 - Application + 应用程序 diff --git a/zh/12/ref/pgbench.sgml b/zh/12/ref/pgbench.sgml index b2ae3ed1..cc418214 100644 --- a/zh/12/ref/pgbench.sgml +++ b/zh/12/ref/pgbench.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pgbench 1 - Application + 应用程序 @@ -1594,7 +1594,7 @@ statement latencies in milliseconds: 安全性 - 如果不可信用户能够访问尚未采用模式的安全使用方式的数据库,就不要在该数据库中运行pgbenchpgbench使用非限定名称,并且不会更改搜索路径。 + 如果不受信任的用户能够访问尚未采用模式的安全使用方式的数据库,就不要在该数据库中运行pgbenchpgbench使用非限定名称,并且不会更改搜索路径。 diff --git a/zh/12/ref/pgtestfsync.sgml b/zh/12/ref/pgtestfsync.sgml index 09c5c82c..0016a024 100644 --- a/zh/12/ref/pgtestfsync.sgml +++ b/zh/12/ref/pgtestfsync.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_test_fsync 1 - Application + 应用程序 diff --git a/zh/12/ref/pgtesttiming.sgml b/zh/12/ref/pgtesttiming.sgml index 5b023c7f..1b7dbeee 100644 --- a/zh/12/ref/pgtesttiming.sgml +++ b/zh/12/ref/pgtesttiming.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_test_timing 1 - Application + 应用程序 diff --git a/zh/12/ref/pgupgrade.sgml b/zh/12/ref/pgupgrade.sgml index 21bf4f1f..9a3ffb45 100644 --- a/zh/12/ref/pgupgrade.sgml +++ b/zh/12/ref/pgupgrade.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_upgrade 1 - Application + 应用程序 @@ -104,7 +104,7 @@ PostgreSQL documentation - 要使用的并发连接和进程/线程数 + 要使用的并发进程或线程数 @@ -331,7 +331,7 @@ NET STOP postgresql-&majorversion; 始终运行新服务器的 pg_upgrade 二进制,而不是旧服务器的。 pg_upgrade 需要指定新旧集簇的数据目录和可执行文件 (bin)目录。你还可以指定用户和端口值,以及是否希望将数据文件 - 链接、克隆或交换,而不是采用默认的复制行为。 + 链接或克隆,而不是采用默认的复制行为。 @@ -339,9 +339,7 @@ NET STOP postgresql-&majorversion; 新集簇,就无法再访问旧集簇。链接模式还要求新旧集簇的数据目录位于同一文件系统中。 (表空间和 pg_wal 可以位于不同文件系统中。)克隆模式具有相同的 速度和磁盘空间优势,但在启动新集簇后不会使旧集簇不可用。克隆模式同样要求新旧数据目录 - 位于同一文件系统中。该模式只在某些操作系统和文件系统上可用。如果关系很多,交换模式 - 可能最快,但一旦文件传输步骤开始,你将无法再访问旧集簇。交换模式也要求新旧集簇的数据 - 目录位于同一文件系统中。 + 位于同一文件系统中。该模式只在某些操作系统和文件系统上可用。 选项允许使用多个 CPU 核心复制/链接文件,并行转储和恢复数据库模式;一个不错的起始值是 CPU 核心数与表空间数量中的较大值。对于运行在多处理器机器上的多数据库服务器,此选项可以显著减少升级时间。 @@ -562,7 +560,7 @@ psql --username=postgres --file=script.sql postgres - 环境 + 注解 pg_upgrade会在当前工作目录中创建各种工作文件,例如模式转储。为安全起见,请确保任何其他用户都无法读取或写入该目录。 @@ -606,7 +604,7 @@ psql --username=postgres --file=script.sql postgres - 注解 + 另见 diff --git a/zh/12/ref/postgres-ref.sgml b/zh/12/ref/postgres-ref.sgml index d6496236..f286d2d2 100644 --- a/zh/12/ref/postgres-ref.sgml +++ b/zh/12/ref/postgres-ref.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation postgres 1 - Application + 应用程序 @@ -97,7 +97,7 @@ PostgreSQL documentation 打印指定运行时参数的值并退出。 - (详情见上面的选项。)这会返回 + (详情见上面的选项。)这个选项可用于正在运行的服务器,它会返回 postgresql.conf中的值,并应用本次调用中提供的任何参数修改。它不反映 集簇启动时提供的参数。 @@ -529,7 +529,7 @@ PostgreSQL documentation - 表明另一台服务器已经在运行的失败消息 + 表明另一个服务器已经在运行的失败消息 应仔细检查,例如可根据你的系统使用下面的命令: $ ps ax | grep postgres @@ -674,16 +674,26 @@ PostgreSQL documentation 示例 - 启动 postgres 时,如需使用默认值并在后台运行,请输入: + + 要使用默认值在后台启动postgres, + 输入: + + $ nohup postgres >logfile 2>&1 </dev/null & - 启动 postgres 并指定端口,例如 1234: + + 要用指定端口启动postgres, + 例如 1234: + $ postgres -p 1234 -要使用 psql 连接到此服务器,请用 -p 选项指定该端口: + + 要使用psql连接到该服务器,请用选项指定这个端口: + $ psql -p 1234 -或者设置环境变量 PGPORT: + + 或者设置环境变量PGPORT $ export PGPORT=1234 $ psql @@ -708,7 +718,7 @@ PostgreSQL documentation - 参见 + 另见 , diff --git a/zh/12/ref/prepare.sgml b/zh/12/ref/prepare.sgml index 2b66c14a..8a4c2f72 100644 --- a/zh/12/ref/prepare.sgml +++ b/zh/12/ref/prepare.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation PREPARE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/prepare_transaction.sgml b/zh/12/ref/prepare_transaction.sgml index 3cc45ab5..493473eb 100644 --- a/zh/12/ref/prepare_transaction.sgml +++ b/zh/12/ref/prepare_transaction.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation PREPARE TRANSACTION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/psql-ref.sgml b/zh/12/ref/psql-ref.sgml index e8bac9a7..e77d7f6a 100644 --- a/zh/12/ref/psql-ref.sgml +++ b/zh/12/ref/psql-ref.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation psql 1 - Application + 应用程序 @@ -533,7 +533,7 @@ testdb=> - 如果不可信用户能够访问尚未采用模式的安全使用方式的数据库,请在会话开始时从search_path中移除所有公众可写的 schema。可以在连接字符串中加入options=-csearch_path=,或者在执行其他 SQL 命令之前发出SELECT pg_catalog.set_config('search_path', '', false)。这种考虑并非psql特有;它适用于任何执行任意 SQL 命令的接口。 + 如果不受信任的用户能够访问尚未采用模式的安全使用方式的数据库,请在会话开始时从search_path中移除所有公众可写的模式。可以在连接字符串中加入options=-csearch_path=,或者在执行其他 SQL 命令之前发出SELECT pg_catalog.set_config('search_path', '', false)。这种考虑并非psql特有;它适用于任何执行任意 SQL 命令的接口。 @@ -1222,11 +1222,7 @@ CREATE INDEX - 生成的查询按照返回的行的顺序执行,并在每行内从左到右执行,如果有多个列。NULL字段将被忽略。生成的查询文字 - 直接发送到服务器进行处理,因此它们不能是psql元命令,也不能包含psql - 变量引用。如果任何单个查询失败,剩余查询的执行将继续,除非设置了ON_ERROR_STOP。每个查询的执行 - 都受ECHO处理的影响。(通常在使用\gexec时,将ECHO设置为 - allqueries是明智的。)查询记录、单步模式、计时和其他查询执行功能也适用于每个生成的查询。 + 生成的查询按照返回行的顺序执行;如果有多列,则在每行内从左到右执行。NULL 字段会被忽略。生成的查询按原样发送到服务器进行处理,因此不能是psql元命令,也不能包含psql变量引用。如果某个查询失败,仍会继续执行其余查询,除非设置了ON_ERROR_STOP。每个查询的执行都受ECHO处理的影响。(通常,在使用\gexec时,适宜将ECHO设为allqueries。)查询日志、单步模式、计时及其他查询执行功能也适用于每个生成的查询。 如果当前查询缓冲区为空,则改为重新执行最近发送的查询。 @@ -2413,7 +2409,7 @@ bar <acronym>SQL</acronym> 中插入变量 - psql变量的一个关键特性是可以把它们替换(插入)到常规SQL语句中,也可以把它们作为元命令的参数。此外,psql还提供了功能来确保被用作 SQL 文字和标识符的变量值会被正确地引用。插入一个值而不需要加引用的语法是在变量名前面加上一个冒号(:)。例如, + psql变量的一个关键特性是可以把它们替换(插入)到常规SQL语句中,也可以把它们作为元命令的参数。此外,psql还提供了功能来确保被用作 SQL 字面量和标识符的变量值会被正确地加引号。插入一个值而不加引号的语法是在变量名前面加上一个冒号(:)。例如, testdb=> \set foo 'my_table' testdb=> SELECT * FROM :foo; diff --git a/zh/12/ref/reassign_owned.sgml b/zh/12/ref/reassign_owned.sgml index b436f800..e3717fea 100644 --- a/zh/12/ref/reassign_owned.sgml +++ b/zh/12/ref/reassign_owned.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation REASSIGN OWNED 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/refresh_materialized_view.sgml b/zh/12/ref/refresh_materialized_view.sgml index 8df289dd..4b8f7812 100644 --- a/zh/12/ref/refresh_materialized_view.sgml +++ b/zh/12/ref/refresh_materialized_view.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation REFRESH MATERIALIZED VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/reindex.sgml b/zh/12/ref/reindex.sgml index f43a17c1..29827dc4 100644 --- a/zh/12/ref/reindex.sgml +++ b/zh/12/ref/reindex.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation REINDEX 7 - SQL - Language Statements + SQL - 语言语句 @@ -29,7 +29,8 @@ REINDEX [ ( VERBOSE ) ] { INDEX | TABLE | SCHEMA | DATABASE | SYSTEM } [ CONCURR 描述 - REINDEX利用索引所属表中存储的数据重建索引,替换该索引的旧副本。以下几种情况适合使用REINDEX: + REINDEX使用索引所属表中存储的数据重建索引, + 并替换索引的旧副本。以下几种场景适合使用REINDEX @@ -104,8 +105,8 @@ REINDEX [ ( VERBOSE ) ] { INDEX | TABLE | SCHEMA | DATABASE | SYSTEM } [ CONCURR - 重新创建当前数据库中除系统目录外的所有索引。 - 系统目录上的索引不会被处理。这种形式的REINDEX不能 + 重新创建当前数据库中的所有索引。 + 共享系统目录上的索引也会被处理。这种形式的REINDEX不能 在事务块内执行。 @@ -130,8 +131,7 @@ REINDEX [ ( VERBOSE ) ] { INDEX | TABLE | SCHEMA | DATABASE | SYSTEM } [ CONCURR 要重新索引的特定索引、表或数据库的名称。索引名和表名可以带模式限 定。目前,REINDEX DATABASE和 - REINDEX SYSTEM只能对当前数据库重新索引。它们的参 - 数是可选的,但如果给出,就必须与当前数据库名匹配。 + REINDEX SYSTEM只能对当前数据库重新索引,所以其参数必须与当前数据库名匹配。 @@ -222,8 +222,8 @@ REINDEX [ ( VERBOSE ) ] { INDEX | TABLE | SCHEMA | DATABASE | SYSTEM } [ CONCURR 并发重建索引 - index - rebuilding concurrently + 索引 + 并发重建 diff --git a/zh/12/ref/reindexdb.sgml b/zh/12/ref/reindexdb.sgml index b48e000d..bf09d92e 100644 --- a/zh/12/ref/reindexdb.sgml +++ b/zh/12/ref/reindexdb.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation reindexdb 1 - Application + 应用程序 @@ -150,7 +150,10 @@ PostgreSQL documentation - 仅重建 index。可以重建多个索引,方法是多次指定 开关。 + + 只重建index。 + 可以通过写多个开关来重建多个索引。 + @@ -178,7 +181,10 @@ PostgreSQL documentation - 仅重建以下对象的索引:schema。可以重建多个模式中的索引,方法是多次指定 开关。 + + 只重建schema中的索引。 + 可以通过写多个开关来重建多个模式中的索引。 + @@ -186,7 +192,10 @@ PostgreSQL documentation - 仅重建以下对象的索引:table。可以重建多个表的索引,方法是多次指定 开关。 + + 只重建table上的索引。 + 可以通过写多个开关来重建多个表上的索引。 + @@ -343,22 +352,24 @@ PostgreSQL documentation - 示例 + 注解 reindexdb 可能需要多次连接到 PostgreSQL 服务器,每次都要求输入密码。在这种情况下,使用 ~/.pgpass 文件会很方便。更多信息见 - 参见 + 示例 - 要重新索引数据库test: + + 要重建数据库test中的索引: $ reindexdb test - 要重新索引表foo和索引bar,其所在数据库名为abcd: + + 要重建名为abcd的数据库中表foo的索引和索引bar $ reindexdb --table=foo --index=bar abcd diff --git a/zh/12/ref/release_savepoint.sgml b/zh/12/ref/release_savepoint.sgml index f060b242..c3b97896 100644 --- a/zh/12/ref/release_savepoint.sgml +++ b/zh/12/ref/release_savepoint.sgml @@ -10,18 +10,18 @@ PostgreSQL documentation 保存点 - releasing + 释放 RELEASE SAVEPOINT 7 - SQL - Language Statements + SQL - 语言语句 RELEASE SAVEPOINT - 释放一个先前定义的保存点 + 销毁一个先前定义的保存点 @@ -48,7 +48,7 @@ RELEASE [ SAVEPOINT ] savepoint_name savepoint_name - 要释放的保存点名称。 + 要销毁的保存点名称。 @@ -74,14 +74,18 @@ RELEASE [ SAVEPOINT ] savepoint_name 示例 - 建立保存点并在之后将其销毁: + + 要建立保存点,并在稍后销毁它: + BEGIN; INSERT INTO table1 VALUES (3); SAVEPOINT my_savepoint; INSERT INTO table1 VALUES (4); RELEASE SAVEPOINT my_savepoint; COMMIT; -上面的事务会同时插入 3 和 4。 + + 上述事务将同时插入 3 和 4。 + diff --git a/zh/12/ref/reset.sgml b/zh/12/ref/reset.sgml index e8aeae8c..5e249ff9 100644 --- a/zh/12/ref/reset.sgml +++ b/zh/12/ref/reset.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation RESET 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/revoke.sgml b/zh/12/ref/revoke.sgml index f0df1116..4bd986af 100644 --- a/zh/12/ref/revoke.sgml +++ b/zh/12/ref/revoke.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation REVOKE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/rollback.sgml b/zh/12/ref/rollback.sgml index 6062ee7b..d80586d7 100644 --- a/zh/12/ref/rollback.sgml +++ b/zh/12/ref/rollback.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ROLLBACK 7 - SQL - Language Statements + SQL - 语言语句 @@ -37,7 +37,7 @@ ROLLBACK [ WORK | TRANSACTION ] [ AND [ NO ] CHAIN ] 参数 - chained transactions + 链式事务 @@ -55,7 +55,7 @@ ROLLBACK [ WORK | TRANSACTION ] [ AND [ NO ] CHAIN ] AND CHAIN - 如果指定了AND CHAIN,则会立即启动一个新的(未中止的)事务, + 如果指定了AND CHAIN,则会立即启动一个新事务, 其事务特征与刚刚结束的事务相同(参见)。 否则,不会启动任何新事务。 diff --git a/zh/12/ref/rollback_prepared.sgml b/zh/12/ref/rollback_prepared.sgml index 3a227014..d126fabb 100644 --- a/zh/12/ref/rollback_prepared.sgml +++ b/zh/12/ref/rollback_prepared.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ROLLBACK PREPARED 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/rollback_to.sgml b/zh/12/ref/rollback_to.sgml index 0242c50b..33d84c77 100644 --- a/zh/12/ref/rollback_to.sgml +++ b/zh/12/ref/rollback_to.sgml @@ -10,13 +10,13 @@ PostgreSQL documentation 保存点 - rolling back + 回滚 ROLLBACK TO SAVEPOINT 7 - SQL - Language Statements + SQL - 语言语句 @@ -34,8 +34,7 @@ ROLLBACK [ WORK | TRANSACTION ] TO [ SAVEPOINT ] savepoint_name描述 - 回滚该保存点建立后执行的所有命令,然后在同一事务层级启动一个新的 - 子事务。该保存点仍然有效,如有需要,之后还可以再次回滚到它。 + 回滚该保存点建立后执行的所有命令。该保存点仍然有效,如有需要,之后还可以再次回滚到它。 diff --git a/zh/12/ref/savepoint.sgml b/zh/12/ref/savepoint.sgml index 99f5a6bc..6b92b9a4 100644 --- a/zh/12/ref/savepoint.sgml +++ b/zh/12/ref/savepoint.sgml @@ -10,13 +10,13 @@ PostgreSQL documentation 保存点 - defining + 定义 SAVEPOINT 7 - SQL - Language Statements + SQL - 语言语句 @@ -102,7 +102,9 @@ COMMIT; 上述事务将同时插入 3 和 4。 - 使用同一个保存点名称: + + 要重复使用同一个保存点名称: + BEGIN; INSERT INTO table1 VALUES (1); SAVEPOINT my_savepoint; @@ -110,18 +112,20 @@ BEGIN; SAVEPOINT my_savepoint; INSERT INTO table1 VALUES (3); - -- rollback to the second savepoint + -- 回滚到第二个保存点 ROLLBACK TO SAVEPOINT my_savepoint; - SELECT * FROM table1; -- shows rows 1 and 2 + SELECT * FROM table1; -- 显示值为 1 和 2 的行 - -- release the second savepoint + -- 释放第二个保存点 RELEASE SAVEPOINT my_savepoint; - -- rollback to the first savepoint + -- 回滚到第一个保存点 ROLLBACK TO SAVEPOINT my_savepoint; - SELECT * FROM table1; -- shows only row 1 + SELECT * FROM table1; -- 仅显示值为 1 的行 COMMIT; -上面的事务展示了先回滚行 3,再回滚行 2。 + + 上述事务展示了先回滚值为 3 的行,再回滚值为 2 的行。 + diff --git a/zh/12/ref/security_label.sgml b/zh/12/ref/security_label.sgml index 488c10d4..3cd85695 100644 --- a/zh/12/ref/security_label.sgml +++ b/zh/12/ref/security_label.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SECURITY LABEL 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/select.sgml b/zh/12/ref/select.sgml index 88c15885..9d9580dd 100644 --- a/zh/12/ref/select.sgml +++ b/zh/12/ref/select.sgml @@ -20,7 +20,7 @@ PostgreSQL documentation SELECT 7 - SQL - Language Statements + SQL - 语言语句 @@ -1372,7 +1372,7 @@ SELECT * FROM (SELECT * FROM mytable FOR UPDATE) ss ORDER BY column1; REPEATABLE READSERIALIZABLE事务隔离级别下, - 这将导致序列化失败(带有SQLSTATE'40001'), + 这将导致串行化失败(SQLSTATE'40001'), 因此在这些隔离级别下不可能接收到无序的行。 diff --git a/zh/12/ref/select_into.sgml b/zh/12/ref/select_into.sgml index 48d78aac..992a1d81 100644 --- a/zh/12/ref/select_into.sgml +++ b/zh/12/ref/select_into.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SELECT INTO 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/set.sgml b/zh/12/ref/set.sgml index e4b8908a..daa090fd 100644 --- a/zh/12/ref/set.sgml +++ b/zh/12/ref/set.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SET 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/set_constraints.sgml b/zh/12/ref/set_constraints.sgml index 53d0c7a0..e5588db7 100644 --- a/zh/12/ref/set_constraints.sgml +++ b/zh/12/ref/set_constraints.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SET CONSTRAINTS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/set_role.sgml b/zh/12/ref/set_role.sgml index e53e261b..7e768998 100644 --- a/zh/12/ref/set_role.sgml +++ b/zh/12/ref/set_role.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SET ROLE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/set_session_auth.sgml b/zh/12/ref/set_session_auth.sgml index 3fb9b989..99525834 100644 --- a/zh/12/ref/set_session_auth.sgml +++ b/zh/12/ref/set_session_auth.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SET SESSION AUTHORIZATION 7 - SQL - Language Statements + SQL - 语言语句 @@ -46,7 +46,7 @@ RESET SESSION AUTHORIZATION - 只有当初始会话用户(即已认证用户)具有超级用户权限时, + 只有当初始会话用户(即已认证用户)最初具有超级用户权限时, 才能更改会话用户标识符。否则,只有当该命令指定的是已认证用户名时, 才会被接受。 diff --git a/zh/12/ref/set_transaction.sgml b/zh/12/ref/set_transaction.sgml index 65c10806..5355df65 100644 --- a/zh/12/ref/set_transaction.sgml +++ b/zh/12/ref/set_transaction.sgml @@ -26,7 +26,7 @@ PostgreSQL documentation SET TRANSACTION 7 - SQL - Language Statements + SQL - 语言语句 @@ -66,7 +66,7 @@ SET SESSION CHARACTERISTICS AS TRANSACTION transa - 一个事务的隔离级别决定当其他事务并行运行时该事务能看见什么数据: + 一个事务的隔离级别决定当其他事务并发运行时该事务能看见什么数据: @@ -137,7 +137,7 @@ SET SESSION CHARACTERISTICS AS TRANSACTION transa 事务属性才会生效。当为一个事务同时选择这三个属性时,该事务在 首次获取其快照时可能会阻塞;在此之后,它便可以运行,而无需承担普通 SERIALIZABLE事务的常规开销,也不会有促成 - 序列化失败或因序列化失败而被取消的风险。这种模式非常适合长时间运行的 + 串行化失败或因串行化失败而被取消的风险。这种模式非常适合长时间运行的 报表或备份。 diff --git a/zh/12/ref/show.sgml b/zh/12/ref/show.sgml index 093d1793..9f542eea 100644 --- a/zh/12/ref/show.sgml +++ b/zh/12/ref/show.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SHOW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/start_transaction.sgml b/zh/12/ref/start_transaction.sgml index e78db715..d85eee63 100644 --- a/zh/12/ref/start_transaction.sgml +++ b/zh/12/ref/start_transaction.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation START TRANSACTION 7 - SQL - Language Statements + SQL - 语言语句 @@ -64,15 +64,16 @@ START TRANSACTION [ transaction_mode - DEFERRABLE 这一 - transaction_mode 是 - PostgreSQL语言扩展。 + DEFERRABLE + transaction_mode + 是PostgreSQL的一种语言扩展。 SQL 标准要求在连续的transaction_modes之间有逗号, - 但出于历史原因PostgreSQL允许省略逗号。 + 但出于历史原因, + PostgreSQL允许省略逗号。 diff --git a/zh/12/ref/truncate.sgml b/zh/12/ref/truncate.sgml index 476f5b6d..ec7894af 100644 --- a/zh/12/ref/truncate.sgml +++ b/zh/12/ref/truncate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation TRUNCATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/unlisten.sgml b/zh/12/ref/unlisten.sgml index fde4a5dd..505b888b 100644 --- a/zh/12/ref/unlisten.sgml +++ b/zh/12/ref/unlisten.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation UNLISTEN 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/update.sgml b/zh/12/ref/update.sgml index 8bc2f9d3..db37844f 100644 --- a/zh/12/ref/update.sgml +++ b/zh/12/ref/update.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation UPDATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/ref/vacuum.sgml b/zh/12/ref/vacuum.sgml index a6bc8aee..7060f1fe 100644 --- a/zh/12/ref/vacuum.sgml +++ b/zh/12/ref/vacuum.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation VACUUM 7 - SQL - Language Statements + SQL - 语言语句 @@ -245,7 +245,7 @@ VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ ANALYZE ] [ mxid_age - 仅对 multixact ID 年龄至少为 mxid_age - 的表执行清理或分析命令。此设置可用于优先处理表,以防止 multixact ID 回卷 + 仅对 多事务 ID 年龄至少为 mxid_age + 的表执行清理或分析命令。此设置可用于优先处理表,以防止 多事务 ID 回卷 (见 )。 - 就此选项而言,一个关系的 multixact ID 年龄,是其主关系及其关联的 + 就此选项而言,一个关系的 多事务 ID 年龄,是其主关系及其关联的 TOAST 表(如果存在)年龄中的较大者。由于 vacuumdb 发出的命令在必要时也会处理该关系的 TOAST 表,因此无需单独考虑它。 @@ -212,7 +212,7 @@ PostgreSQL documentation - 如果有,跳过与待清理表关联的 TOAST 表。 + 跳过那些无法立即加锁并进行处理的关系。 此选项仅适用于运行PostgreSQL 12 及更高版本的服务器。 @@ -279,11 +279,9 @@ PostgreSQL documentation 仅计算供优化器使用的统计信息(不执行清理),类似。使用不同的配置设置运行多个(目前为三个)分析阶段,以便更快地生成可用统计信息。 - 此选项仅在分析当前没有统计信息,或现有统计信息完全错误的数据库时才有用,例如数据库是 - 从恢复出的转储中重新填充,或是通过 pg_upgrade 新建得到的。 - 注意,在已有统计信息的数据库上使用此选项,可能会因为早期阶段采用较低统计目标, - 导致查询优化器的选择暂时变差。 - + 此选项适合分析刚通过恢复转储或pg_upgrade填充的数据库。 + 它会尽快尝试生成一些统计信息,让数据库能够使用,然后在后续阶段生成完整统计信息。 + @@ -426,13 +424,13 @@ PostgreSQL documentation - 示例 + 注解 vacuumdb可能需要多次连接到PostgreSQL服务器,每次都要询问密码。在这种情况下,使用~/.pgpass文件会比较方便。更多信息见 - 参见 + 示例 清理数据库 test diff --git a/zh/12/ref/values.sgml b/zh/12/ref/values.sgml index 98520764..d02d1de6 100644 --- a/zh/12/ref/values.sgml +++ b/zh/12/ref/values.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation VALUES 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/12/reference.sgml b/zh/12/reference.sgml index 8062787c..b45347d0 100644 --- a/zh/12/reference.sgml +++ b/zh/12/reference.sgml @@ -268,6 +268,7 @@ &pgupgrade; &pgwaldump; &postgres; + &postmaster; diff --git a/zh/12/release-12.sgml b/zh/12/release-12.sgml index bdbe61c1..dc587b82 100644 --- a/zh/12/release-12.sgml +++ b/zh/12/release-12.sgml @@ -1631,17 +1631,17 @@ Branch: REL_13_STABLE [e9c8747ee] 2024-06-27 21:08:55 +0300 Branch: REL_12_STABLE [5dea6628b] 2024-06-27 21:09:15 +0300 --> - 修复启动热备服务器时对已准备事务的子事务的处理 + 修复启动热备服务器时对预备事务的子事务的处理 (Heikki Linnakangas) § 当备库的重放从关闭检查点 WAL 记录开始时, - 主库上已准备但尚未提交的事务会被正确理解为仍在进行中。 - 但已准备事务的子事务(由保存点或 + 主库上已预备但尚未提交的事务会被正确理解为仍在进行中。 + 但预备事务的子事务(由保存点或 PL/pgSQL 异常块创建)没有被考虑在内, - 会被视为已中止。如果该已准备事务后来被提交,这会导致不一致。 + 会被视为已中止。如果该预备事务后来被提交,这会导致不一致。 @@ -5085,8 +5085,8 @@ Branch: REL_11_STABLE [0048c3b51] 2023-07-04 09:27:00 +1200 - 使用位图堆扫描、使用 GIN 索引以及检查初始为空的 B-树 索引时可能会遗漏冲突。 - 所有这些情况都可能因不当允许冲突事务提交而导致可序列化失败。 + 使用位图堆扫描、使用 GIN 索引以及检查初始为空的 B-树索引时可能会遗漏冲突。 + 所有这些情况都可能因不当允许相互冲突的事务提交而破坏可串行性。 @@ -15757,7 +15757,7 @@ Branch: REL_12_STABLE [ea9087938] 2020-11-04 12:46:52 +0100 --> 支持对文本数组进行哈希计算(Peter Eisentraut) § - 如果数组元素类型支持排序规则,数组哈希就会失败。尤其是,这使文本数组列无法用作哈希分区的分区键。 + 如果数组元素类型支持排序规则,对数组进行 hash 计算就会失败。尤其是,这使文本数组列无法用作 hash 分区的分区键。 diff --git a/zh/12/runtime.sgml b/zh/12/runtime.sgml index f466c476..dbc03032 100644 --- a/zh/12/runtime.sgml +++ b/zh/12/runtime.sgml @@ -9,7 +9,7 @@ <productname>PostgreSQL</productname>用户账户 - postgres user + postgres 用户 与任何可从外部访问的服务器守护进程一样,建议使用单独的用户账户运行 PostgreSQL。该用户账户应该只拥有服务器管理的数据,不应与其他守护进程共用。(例如,使用 nobody 用户就不是好主意。)不建议将可执行文件安装为由该用户所有,因为系统一旦被攻破,就可能修改自己的二进制文件。 @@ -32,7 +32,7 @@ - 在做任何事情之前,必须先在磁盘上初始化一个数据库存储区域。我们把它称为数据库集簇。(SQL 标准使用术语 catalog cluster。)数据库集簇是由一个正在运行的数据库服务器实例管理的一组数据库。初始化之后,数据库集簇中会包含一个名为postgres的数据库,作为供工具、用户和第三方应用使用的默认数据库。数据库服务器本身并不要求该postgres数据库存在,但许多外部工具程序都假定它存在。初始化期间,集簇中还会创建另一个数据库,名为template1。顾名思义,它会作为后续新建数据库的模板;不应将它用于实际工作。(关于在集簇中创建新数据库的信息,见。) + 在做任何事情之前,必须先在磁盘上初始化一个数据库存储区域。我们把它称为数据库集簇。(SQL 标准使用术语目录集簇(catalog cluster)。)数据库集簇是由一个正在运行的数据库服务器实例管理的一组数据库。初始化之后,数据库集簇中会包含一个名为postgres的数据库,作为供工具、用户和第三方应用使用的默认数据库。数据库服务器本身并不要求该postgres数据库存在,但许多外部工具程序都假定它存在。初始化期间,集簇中还会创建另一个数据库,名为template1。顾名思义,它会作为后续新建数据库的模板;不应将它用于实际工作。(关于在集簇中创建新数据库的信息,见。) 从文件系统角度看,数据库集簇就是一个目录,所有数据都存储在其下。我们将它称为数据目录数据区域。数据存放位置完全由你决定,没有默认值;常用位置包括 /usr/local/pgsql/data/var/lib/pgsql/data。要初始化数据库集簇,请使用命令 initdb该命令随以下产品安装:PostgreSQL。数据库集簇在文件系统中的目标位置通过 选项指定,例如: @@ -125,7 +125,7 @@ postgres$ initdb -D /usr/local/pgsql/data 对于在PostgreSQL中使用NFS,唯一硬性要求是文件系统必须使用hard选项挂载。使用hard选项时,如果出现网络问题,进程可能会无限期地挂起,因此这种配置需要配套谨慎的监控措施。soft选项会在网络问题出现时中断系统调用,但PostgreSQL不会重试以这种方式被中断的系统调用,因此任何此类中断都会导致报告 I/O 错误。 - 没有必要使用 sync 挂载选项。async 选项的行为已经足够,因为 PostgreSQL 会在适当的时候发出 fsync 调用来刷新写缓存。(这和它在本地文件系统上的工作方式类似。)但是,强烈建议在支持该选项的 NFS 服务器端系统上使用 sync 导出选项(主要是 Linux)。否则,NFS 客户端上的 fsync 或等效操作实际上并不能保证数据到达服务器上的持久存储,这可能导致类似于将参数 设为关闭时那样的损坏。这些挂载和导出选项的默认值在不同厂商和版本间并不相同,因此无论如何都建议检查它们,并且最好显式指定,以避免歧义。 + 没有必要使用 sync 挂载选项。async 选项的行为已经足够,因为 PostgreSQL 会在适当的时候发出 fsync 调用将写缓存刷盘。(这和它在本地文件系统上的工作方式类似。)但是,强烈建议在支持该选项的 NFS 服务器端系统上使用 sync 导出选项(主要是 Linux)。否则,NFS 客户端上的 fsync 或等效操作实际上并不能保证数据到达服务器上的持久存储,这可能导致类似于将参数 设为关闭时那样的损坏。这些挂载和导出选项的默认值在不同厂商和版本间并不相同,因此无论如何都建议检查它们,并且最好显式指定,以避免歧义。 在某些情况下,可以通过 NFS 或更底层的协议(例如 iSCSI)访问外部存储产品。在后一种情况下,存储会表现为块设备,可以在其上创建任意可用的文件系统。这种方式或许能让 DBA 不必应对 NFS 的某些特性,但当然,管理远程存储的复杂性会转移到其他层面。 @@ -178,14 +178,14 @@ su postgres -c 'pg_ctl start -D /usr/local/pgsql/data -l serverlog' 对于FreeBSD,请查看PostgreSQL源码发布包中的contrib/start-scripts/freebsd文件。 - FreeBSDstart script + FreeBSD启动脚本 OpenBSD上,把以下内容加入/etc/rc.local: - OpenBSDstart script + OpenBSD启动脚本 if [ -x /usr/local/pgsql/bin/pg_ctl -a -x /usr/local/pgsql/bin/postgres ]; then su -l postgres -c '/usr/local/pgsql/bin/pg_ctl start -s -l /var/postgresql/log -D /usr/local/pgsql/data' @@ -198,7 +198,7 @@ fi Linux系统上,可以把 - Linuxstart script + Linux启动脚本 /usr/local/pgsql/bin/pg_ctl start -l logfile -D /usr/local/pgsql/data @@ -237,14 +237,14 @@ WantedBy=multi-user.target NetBSD上,可根据偏好使用FreeBSDLinux的启动脚本。 - NetBSDstart script + NetBSD启动脚本 Solaris上,创建一个名为/etc/init.d/postgresql的文件,其中包含以下内容: - Solarisstart script + Solaris启动脚本 su - postgres -c "/usr/local/pgsql/bin/pg_ctl start -l logfile -D /usr/local/pgsql/data" @@ -331,7 +331,7 @@ psql: could not connect to server: No such file or directory 管理内核资源 - PostgreSQL有时会耗尽操作系统的各种资源限制,尤其是在同一系统上运行多个服务器副本,或在非常大型的安装环境中时更是如此。本节解释PostgreSQL使用的内核资源,以及你可以采取哪些步骤来解决与内核资源消耗相关的问题。 + PostgreSQL有时会达到操作系统的各种资源上限,尤其是在同一系统上运行多个服务器实例,或在非常大型的安装环境中时更是如此。本节解释PostgreSQL使用的内核资源,以及你可以采取哪些步骤来解决与内核资源消耗相关的问题。 @@ -360,7 +360,7 @@ psql: could not connect to server: No such file or directory - System V IPC 功能通常受系统范围的分配限制约束。当PostgreSQL超出这些限制之一时,服务器会拒绝启动,并留下带有指导性的错误消息,说明问题所在以及应如何处理(另见)。相关内核参数在不同系统上的命名基本一致,给出了概览;不过,设置它们的方法却各不相同。下面给出一些平台上的建议。 + System V IPC 功能通常受系统范围的分配限制约束。当PostgreSQL超出这些限制之一时,服务器会拒绝启动,并应留下带有指导性的错误消息,说明问题所在以及应如何处理(另见)。相关内核参数在不同系统上的命名基本一致,给出了概览;不过,设置它们的方法却各不相同。下面给出一些平台上的建议。
@@ -380,7 +380,7 @@ psql: could not connect to server: No such file or directory SHMMAX 共享内存段的最大尺寸(字节) - 至少 1kB,但是默认值通常要高一些 + 至少 1kB,但是默认值通常高得多 @@ -443,8 +443,8 @@ psql: could not connect to server: No such file or directory
- PostgreSQL要求少量字节的 System V 共享内存(在 64 位平台上通常是 48 字节)用于每一个服务器拷贝。在大多数现代操作系统上,这个量很容易得到。 - 但是,如果你运行了很多个服务器副本,或者显式配置服务器以使用大量 System V 共享内存(参见 ), + PostgreSQL要求少量字节的 System V 共享内存(在 64 位平台上通常是 48 字节)用于每一个服务器实例。在大多数现代操作系统上,这个量很容易得到。 + 但是,如果你运行了很多个服务器实例,或者显式配置服务器以使用大量 System V 共享内存(参见 ), 可能需要增加SHMALL(系统范围内 System V 共享内存的总量)。注意在很多系统上SHMALL是以页面而不是字节来度量。 @@ -459,11 +459,11 @@ psql: could not connect to server: No such file or directory
- 与semaphore undo有关的其他各种设置,如SEMMNUSEMUME,不会影响PostgreSQL。 + 与信号量撤销有关的其他各种设置,如SEMMNUSEMUME,不会影响PostgreSQL - 当使用 POSIX 信号量时,所需数量与 System V 相同,即每个允许连接()、每个允许自动清理工作进程()、每个允许 WAL 发送进程()、每个允许后台进程()等各需一个。在优先使用该实现的平台上,POSIX 信号量数量没有特定内核上限。 + 当使用 POSIX 信号量时,所需数量与 System V 相同,即每个允许连接()、每个允许自动清理工作进程()、每个允许 WAL 发送进程()、每个允许后台进程()各需一个。在优先使用该实现的平台上,POSIX 信号量数量没有特定内核上限。 @@ -485,11 +485,13 @@ psql: could not connect to server: No such file or directory FreeBSDIPC 配置 - 要更改默认 IPC 设置,可以使用 sysctlloader 接口。可以通过 sysctl 设置以下参数: + + 可以使用sysctlloader接口更改默认 IPC 配置。下列参数可用sysctl设置: # sysctl kern.ipc.shmall=32768 # sysctl kern.ipc.shmmax=134217728 -要让这些设置在重启后仍然生效,请修改 /etc/sysctl.conf。 + + 要让这些设置在重启之后也保持,请修改/etc/sysctl.conf 这些信号量相关设置对于 sysctl 是只读的;设置它们时,可修改 /boot/loader.conf: @@ -661,7 +663,9 @@ project.max-msg-ids=(priv,4096,deny) - 此外,如果你正在某个区(zone)中运行 PostgreSQL,可能也需要提高该区的资源使用限制。关于 projectsprctl 的更多信息,请参见 System Administrator's Guide 中的“Chapter2: Projects and Tasks”。 + + 此外,如果你正在某个区(zone)中运行PostgreSQL,可能也需要提高该区的资源使用限制。关于projectsprctl的更多信息,请参见System Administrator's Guide中的 "Chapter 2: Projects and Tasks"。 + @@ -695,7 +699,7 @@ WARNING: could not remove shared memory segment "/PostgreSQL.1450751626": No su - 用户注销可能会作为维护作业的一部分发生,也可能在管理员以postgres用户或类似名称登录时手工触发,因此通常很难彻底防止。 + 用户注销可能会作为维护作业的一部分发生,也可能在管理员以postgres用户登录或执行类似操作时手工触发,因此通常很难彻底防止。 @@ -766,7 +770,7 @@ default:\ - 另一个在支持大量客户端连接时可能需要关注的内核限制,是套接字连接队列的最大长度。如果在很短时间内到达的连接请求超过了这个数量,那么其中一些请求可能会在主管服务器进程来得及处理之前就被拒绝,于是客户端会收到不太有帮助的连接失败错误,例如Resource temporarily unavailableConnection refused。在许多平台上,默认队列长度限制是 128。要提高它,请通过sysctl调整相应的内核参数,然后重新启动主管服务器进程。该参数在不同系统上的名称不同:在 Linux 上是net.core.somaxconn,在较新的 FreeBSD 上是kern.ipc.soacceptqueue,在 macOS 和其他 BSD 变体上是kern.ipc.somaxconn。 + 另一个在支持大量客户端连接时可能需要关注的内核限制,是套接字连接队列的最大长度。如果在很短时间内到达的连接请求超过了这个数量,那么其中一些请求可能会在postmaster来得及处理之前就被拒绝,于是客户端会收到不太有帮助的连接失败错误,例如Resource temporarily unavailableConnection refused。在许多平台上,默认队列长度限制是 128。要提高它,请通过sysctl调整相应的内核参数,然后重新启动postmaster。该参数在不同系统上的名称不同:在 Linux 上是net.core.somaxconn,在较新的 FreeBSD 上是kern.ipc.soacceptqueue,在 macOS 和其他 BSD 变体上是kern.ipc.somaxconn @@ -774,7 +778,7 @@ default:\ Linux 内存过量分配 - memory overcommit + 内存过量分配 @@ -782,7 +786,7 @@ default:\ - overcommit + 过量分配 在 Linux 2.4 及更高版本中,默认的虚拟内存行为对 PostgreSQL 并非最佳。由于内核实现内存过量分配的方式,如果 PostgreSQL 或其他进程的内存需求导致系统耗尽虚拟内存,内核可能会终止 PostgreSQL 的 postmaster(主管服务器进程)。 @@ -799,7 +803,7 @@ Out of Memory: Killed process 12345 (postgres). 避免该问题的一种办法,是让PostgreSQL运行在一台你能确定不会被其他进程耗尽内存的机器上。如果内存紧张,增加操作系统交换空间也有助于避免这个问题,因为内存不足(OOM)杀手只有在物理内存和交换空间都耗尽时才会被触发。 - 如果导致系统耗尽内存的正是 PostgreSQL 自身,那么你可以通过调整配置来避免该问题。在某些情况下,调低与内存相关的配置参数会有帮助,尤其是 shared_bufferswork_mem。在其他情况下,允许数据库服务器接受过多连接也可能导致这一问题。很多时候,更好的做法是减小 max_connections,并转而使用外部连接池软件。 + 如果导致系统耗尽内存的正是 PostgreSQL 自身,那么你可以通过调整配置来避免该问题。在某些情况下,调低与内存相关的配置参数会有帮助,尤其是 shared_bufferswork_mem。在其他情况下,允许数据库服务器接受过多连接也可能导致这一问题。很多时候,更好的做法可能是减小 max_connections,并转而使用外部连接池软件。 在 Linux 2.6 及更高版本中,可以修改内核的行为,使其不会过量分配内存。虽然此设置无法完全阻止 OOM 杀手 被调用,但会显著降低发生概率,从而使系统行为更健壮。方法是选择严格的过量分配模式,使用以下命令:sysctl: @@ -808,12 +812,26 @@ sysctl -w vm.overcommit_memory=2 或者在以下文件中加入等效条目:/etc/sysctl.conf。你可能还希望修改相关设置 vm.overcommit_ratio。详细信息参见内核文档文件 - 另一种方法不要求改变 vm.overcommit_memory,但也可与该设置的修改结合使用:将 postmaster 进程特有的OOM score adjustment值设为 -1000,从而保证它不会成为 OOM 杀手 的目标。最简单的方法是执行: + + 另一种方法可在修改或不修改 vm.overcommit_memory 的情况下使用: + 把 postmaster 进程专属的OOM 评分调整值设为 -1000, + 从而保证它不会成为 OOM 杀手的目标。最简单的做法是在 postmaster + 启动脚本中、调用 postmaster 之前执行: + echo -1000 > /proc/self/oom_score_adj -执行位置是在 postmaster 的启动脚本中,紧接在调用 postmaster 之前。注意,必须以 root 身份执行此操作,否则不会生效;因此,在 root 所有的启动脚本中执行最方便。如果这样做,还应在启动脚本中调用 postmaster 之前设置以下环境变量: + + 请注意,这个操作必须以 root 身份完成,否则不会生效;因此,由 root 拥有的启动脚本是最容易执行该操作的位置。 + 如果这样做,还应在调用 postmaster 之前,在启动脚本中设置以下环境变量: + export PG_OOM_ADJUST_FILE=/proc/self/oom_score_adj export PG_OOM_ADJUST_VALUE=0 -这些设置会使 postmaster 子进程以正常的 OOM 分数调整值零运行,因此 OOM 杀手 仍可在需要时将它们作为目标。你可以为以下变量使用其他值:PG_OOM_ADJUST_VALUE,以使子进程采用其他 OOM 分数调整值。(PG_OOM_ADJUST_VALUE 也可以省略,此时默认为零。)如果不设置 PG_OOM_ADJUST_FILE,子进程将使用与 postmaster 相同的 OOM 分数调整值,这并不明智,因为这样设置的目的就是确保 postmaster 获得优先保护。 + + 这些设置会使 postmaster 子进程以常规的 OOM 评分调整值零运行,以便 OOM 杀手在需要时仍可将它们作为目标。 + 如果希望子进程以其他 OOM 评分调整值运行,也可以为 PG_OOM_ADJUST_VALUE 指定其他值。 + (也可以省略 PG_OOM_ADJUST_VALUE,此时默认为零。) + 如果不设置 PG_OOM_ADJUST_FILE,子进程就会和 postmaster 使用相同的 OOM 评分调整值, + 这并不明智,因为这样做的目的正是确保 postmaster 获得优先保护。 + 较旧的 Linux 内核不提供 /proc/self/oom_score_adj,但可能提供名为 /proc/self/oom_adj 的同类功能的早期版本。其工作方式相同,只是禁用值为 -17 而非 -1000 @@ -843,8 +861,9 @@ $ grep Huge /proc/meminfo - 你可能还需要授予数据库服务器的操作系统用户使用大页的权限,例如通过sysctl设置vm.hugetlb_shm_group,以及/或者授予其使用ulimit -l锁定内存的权限。 - + 可能还需要通过 sysctl 设置 vm.hugetlb_shm_group, + 授予数据库服务器的操作系统用户使用大页的权限,以及/或者通过 ulimit -l 授予其锁定内存的权限。 + PostgreSQL 对大页的默认行为是:只要可能就使用它们;如果失败,则回退到普通页。要强制使用大页,可以在 postgresql.conf 中将 设为 on。请注意,在这种设置下,如果没有足够的大页可用,PostgreSQL 将无法启动。 @@ -870,7 +889,7 @@ $ grep Huge /proc/meminfo 这是智能关闭模式。 收到SIGTERM后,服务器禁止新连接,但允许现有会话正常结束工作。 - 仅在所有会话终止后才会关闭。如果服务器在请求智能关闭时处于恢复状态, + 仅在所有会话终止后才会关闭。如果服务器处于在线备份模式,还会等待该模式结束。在线备份模式生效期间,仍允许新的超级用户连接(这一例外允许超级用户连接以结束在线备份模式),但不允许其他新连接。如果服务器在请求智能关闭时处于恢复状态, 则只有在所有常规会话终止后,恢复和流复制才会停止。 @@ -883,7 +902,7 @@ $ grep Huge /proc/meminfo 这是快速关闭模式。 服务器禁止新连接并向所有现有服务器进程发送SIGTERM, 这将导致它们中止当前事务并迅速退出。然后等待所有服务器进程退出,最后关闭。 - + 如果服务器处于在线备份模式,该模式将被终止,导致备份不可用。 @@ -916,12 +935,12 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`升级 PostgreSQL 集簇 - upgrading + 升级 - version - compatibility + 版本 + 兼容性 @@ -936,10 +955,11 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` - 对于 PostgreSQL版本,内部数据存储格式可能会发生变化,因此升级会更复杂。将数据迁移到新的大版本的传统方法是转储并恢复数据库,不过这可能比较慢。更快的方法是 。此外,也可以使用复制方法,如下所述。 + + 对于PostgreSQL版本,内部数据存储格式可能会发生变化,因此升级会复杂得多。将数据迁移到新的主版本的传统方法是转储并恢复数据库,不过这可能比较慢。更快的方法是。此外,也可以使用复制方法,如下所述。 - 新的主版本通常还会引入一些用户可见的不兼容变化,因此应用程序可能也需要做出修改。所有用户可见的变化都列在发行说明()中;请特别留意标为Migration的小节。虽然你可以从一个主版本直接升级到另一个主版本,而不必逐个升级中间版本,但仍应阅读所有中间版本的主版本发行说明。 + 新的主版本通常还会引入一些用户可见的不兼容变化,因此应用程序可能也需要做出修改。所有用户可见的变化都列在发行说明()中;请特别留意标为迁移(Migration)的小节。虽然你可以从一个主版本直接升级到另一个主版本,而不必逐个升级中间版本,但仍应阅读所有中间版本的主版本发行说明。 @@ -998,7 +1018,7 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` - 这涉及以后端函数 API 为代表的变更,该 API 使用 C 语言编写。这类变更会影响那些深入引用服务器内部后端函数的代码。 + 这涉及使用 C 语言编写的后端函数 API 的变更。这类变更会影响那些深入引用服务器内部后端函数的代码。 @@ -1009,7 +1029,7 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`通过pg_dumpall升级数据 - 一种升级方法是从某个主版本的PostgreSQL导出数据,再在另一个版本中恢复。要这样做,必须使用逻辑备份工具,例如pg_dumpall;文件系统级备份方法不起作用。(系统中有相应检查,会阻止你在不兼容版本的PostgreSQL上使用某个数据目录,因此即便误用错误版本的服务器去启动某个数据目录,通常也不会造成太大损害。) + 一种升级方法是从某个主版本的PostgreSQL转储数据,再在另一个版本中恢复。要这样做,必须使用逻辑备份工具,例如pg_dumpall;文件系统级备份方法不起作用。(系统中有相应检查,会阻止你在不兼容版本的PostgreSQL上使用某个数据目录,因此即便误用错误版本的服务器去启动某个数据目录,通常也不会造成太大损害。) 建议使用来自较新版本 PostgreSQLpg_dumppg_dumpall 程序,以利用这些程序可能包含的改进。当前版本的转储程序可以读取从 8.0 起任意服务器版本的数据。 @@ -1022,13 +1042,13 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` - 如果是在制作备份,请确认数据库此时没有正在进行更新。这不会影响备份的一致性,但那些变更当然不会包含在备份中。必要时,可修改/usr/local/pgsql/data/pg_hba.conf中的访问权限(或采用等效方法),禁止除你之外的其他人访问数据库。有关访问控制的更多信息见。 + 如果是在制作备份,请确认数据库此时没有正在进行更新。更新操作不会影响备份的完整性,但那些变更当然不会包含在备份中。必要时,可修改/usr/local/pgsql/data/pg_hba.conf(或等效文件)中的访问权限,禁止除你之外的其他人访问数据库。有关访问控制的更多信息见 pg_dumpall - use during upgrade + 在升级期间使用 要备份整个数据库安装,请输入: @@ -1049,7 +1069,7 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` pg_ctl stop - 在那些会自动启动PostgreSQL的系统上,可能已经有某个启动脚本能完成同样的工作。例如,在Red Hat Linux系统上,也许下面这条命令就可以: + 在那些会在开机时自动启动PostgreSQL的系统上,可能已经有某个启动脚本能完成同样的工作。例如,在Red Hat Linux系统上,也许下面这条命令就可以: /etc/rc.d/init.d/postgresql stop @@ -1131,7 +1151,9 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 通过复制升级数据 - 也可以使用逻辑复制方法,创建一个运行较新版本 PostgreSQL 的备库。之所以可行,是因为逻辑复制支持不同大版本 PostgreSQL 之间进行复制。该备库可以与旧服务器部署在同一台机器上,也可以部署在不同机器上。一旦它与主库(运行旧版本 PostgreSQL)同步,就可以切换主备角色,让备库成为主库,并关闭旧的数据库实例。这种计划内切换只会为升级带来几秒钟的停机时间。 + + 也可以使用逻辑复制方法,创建一个运行较新版本PostgreSQL的备库。之所以可行,是因为逻辑复制支持不同主版本PostgreSQL之间进行复制。该备库可以与旧服务器部署在同一台机器上,也可以部署在不同机器上。一旦它与主库(运行旧版本PostgreSQL)同步,就可以切换主备角色,让备库提升为主库,并关闭旧的数据库实例。这种切换使升级只需几秒钟的停机时间。 + 这种升级方法既可以使用内置的逻辑复制功能,也可以使用外部逻辑复制系统,例如pglogicalSlonyLondisteBucardo。 @@ -1175,7 +1197,7 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 - PostgreSQL提供了多个层次的加密,并在防止数据因数据库服务器被盗、不可靠的管理员或不安全网络等原因而泄露方面提供了很高的灵活性。对于医疗记录、金融交易等敏感数据,加密也可能是合规要求的一部分。 + PostgreSQL提供了多个层次的加密,并在防止数据因数据库服务器被盗、不诚实的管理员或不安全网络等原因而泄露方面提供了很高的灵活性。为了保护医疗记录、金融交易等敏感数据,也可能需要使用加密。 @@ -1300,7 +1322,7 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 - 如果私钥受密码保护,服务器会提示输入该密码,并在输入之前不会启动。默认情况下,使用密码会禁用无需重启服务器即可更改 SSL 配置的能力,不过参见。此外,在 Windows 上完全无法使用带密码保护的私钥。 + 如果私钥受口令保护,服务器会提示输入该口令,并在输入之前不会启动。默认情况下,使用口令会禁用无需重启服务器即可更改 SSL 配置的能力,不过参见。此外,在 Windows 上完全无法使用带口令保护的私钥。 @@ -1327,7 +1349,7 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 - 使用NULL-SHANULL-MD5密码套件,可以在几乎没有加密开销的情况下完成认证。不过,中间人仍然能够读取并转发客户端与服务器之间的通信。此外,与认证的开销相比,加密开销本身通常很小。基于这些原因,不建议使用 NULL 密码套件。 + 使用NULL-SHANULL-MD5密码套件,可以在没有加密开销的情况下完成认证。不过,中间人仍然能够读取并转发客户端与服务器之间的通信。此外,与认证的开销相比,加密开销本身很小。基于这些原因,不建议使用 NULL 密码套件。 @@ -1578,17 +1600,19 @@ ssh -L 63333:db.foo.com:5432 joe@shell.foo.com - 在 <systemitem class="osname">Windows</systemitem> 上注册 <application>Event Log</application> + 在<systemitem class="osname">Windows</systemitem>上注册<application>事件日志</application> 事件日志 事件日志 - 要向操作系统注册 Windows - event log 库,请执行以下命令: + + 要向操作系统注册一个Windows事件日志库,请执行以下命令: + regsvr32 pgsql_library_directory/pgevent.dll -这会创建事件查看器使用的注册表条目,条目位于默认事件源之下,其名称为 PostgreSQL。 + + 这会创建被事件查看器使用的注册表项,默认事件源命名为PostgreSQL @@ -1598,7 +1622,9 @@ ssh -L 63333:db.foo.com:5432 joe@shell.foo.com - 要从操作系统中注销 event log 库,请执行以下命令: + + 要从操作系统中注销该事件日志库,请执行以下命令: + regsvr32 /u [/i:event_source_name] pgsql_library_directory/pgevent.dll diff --git a/zh/12/spgist.sgml b/zh/12/spgist.sgml index 703d74f5..cab5d7a4 100644 --- a/zh/12/spgist.sgml +++ b/zh/12/spgist.sgml @@ -4,7 +4,7 @@ SP-GiST 索引 - index + 索引 SP-GiST @@ -12,7 +12,7 @@ 简介 - SP-GiST 是 space-partitioned GiST + SP-GiST 是空间分区 GiST 的缩写。SP-GiST 支持分区搜索树,这使得开发多种不同的 非平衡数据结构成为可能,例如四叉树、k-d 树以及基数树(trie)。这些结构 的共同特征是,它们会反复将搜索空间划分为不必等大的分区。与这种划分规则良 @@ -49,7 +49,7 @@ 内置操作符类 - 核心 PostgreSQL 发行版包含了 + PostgreSQL 核心发行版包含了 SP-GiST 操作符类,如 所示。 @@ -60,7 +60,7 @@ 名称 - 索引数据类型 + 被索引数据类型 可索引操作符 排序操作符 @@ -182,11 +182,11 @@ - SP-GiST 核心代码会处理空项。虽然 - SP-GiST 索引确实会为被索引列中的空值存储项,但这一 - 点对索引操作符类代码是隐藏的:不会有空的索引项或搜索条件传递给操作符类 - 方法。(这里假定 SP-GiST 操作符是严格的,因此对空 - 值不可能成功。)因此,这里不再进一步讨论空值。 + SP-GiST 核心代码负责处理值为 null 的索引项。虽然 + SP-GiST 索引会为被索引列中的 null 值存储索引项, + 但索引操作符类代码看不到这些项:值为 null 的索引项或搜索条件绝不会传给 + 操作符类方法。(这里假定 SP-GiST 操作符是严格的, + 因此对 null 值不可能返回真。)所以这里不再讨论 null 值。 @@ -196,7 +196,7 @@ internal 参数,第一个参数是指向某个 C 结构体的指针,其中包 含该支持方法的输入值;第二个参数也是指向某个 C 结构体的指针,方法必须将输 出值写入其中。四个必需方法只返回 void,因为它们的全部结果 - 都体现在输出结构体中;但 leaf_consistent 会返回一个 + 都体现在输出结构体中;但 leaf_consistent 还返回一个 boolean 结果。这些方法不得修改其输入结构体中的任何字段。在 所有情况下,调用用户定义方法之前,输出结构体都会先被清零。可选的第六个方 法 compress 只接受一个待索引的 datum @@ -214,9 +214,16 @@ 返回索引实现的静态信息,包括前缀和结点标签数据类型的 OID。 - SQL声明必须如下所示: + + 该函数的 SQL 声明必须如下所示: + CREATE FUNCTION my_config(internal, internal) RETURNS void ... -第一个参数是一个指向spgConfigInC 结构体的指针,其中包含该函数的输入数据。第二个参数是一个指向spgConfigOutC 结构体的指针,函数必须将结果数据填入其中。 + + 第一个参数是一个指向 spgConfigIn C 结构体的 + 指针,其中包含该函数的输入数据。第二个参数是一个指向 + spgConfigOut C 结构体的指针,函数必须将结果 + 数据填入其中。 + typedef struct spgConfigIn { Oid attType; /* 要被索引的数据类型 */ @@ -227,12 +234,14 @@ typedef struct spgConfigOut Oid prefixType; /* 内部元组前缀的数据类型 */ Oid labelType; /* 内部元组结点标签的数据类型 */ Oid leafType; /* 叶子元组值的数据类型 */ - bool canReturnData; /* 操作符类能重构原始数据 */ - bool longValuesOK; /* 操作符类能处理值 > 1 页 */ + bool canReturnData; /* 操作符类能重建原始数据 */ + bool longValuesOK; /* 操作符类能处理大小 > 1 页的值 */ } spgConfigOut; - attType的传入是为了支持多态索引操作符类;对于普通的固定数据类型操作符类,它始终具有相同的值,因此可以忽略。 + 传入 attType 是为了支持多态索引操作符类; + 对于普通的固定数据类型操作符类,它始终具有相同的值,因此可以忽略。 + 对于不使用前缀的操作符类,可以将 prefixType @@ -246,7 +255,7 @@ typedef struct spgConfigOut )。 - leafType通常与attType相同。出于向后兼容的考虑,config方法可以不初始化leafType;这与将leafType设为等于attType具有相同效果。当attTypeleafType不同时,必须提供可选的compress方法。compress方法负责把待索引的 datum 从attType转换为leafType。注意:两个 consistent 函数都会收到未经改变的scankeys,不会经过compress的转换。 + leafType通常与attType相同。出于向后兼容的考虑,config方法可以不初始化leafType;这与将leafType设为等于attType具有相同效果。当attTypeleafType不同时,必须提供可选的compress方法。compress方法负责把待索引的 datum 从attType转换为leafType。注意:两个一致性检查函数都会收到未经改变的scankeys,不会经过compress的转换。 @@ -257,9 +266,16 @@ typedef struct spgConfigOut 为向内部元组插入新值选择一种方法。 - SQL声明必须如下所示: + + 该函数的 SQL 声明必须如下所示: + CREATE FUNCTION my_choose(internal, internal) RETURNS void ... -第一个参数是一个指向spgChooseInC 结构体的指针,其中包含该函数的输入数据。第二个参数是一个指向spgChooseOutC 结构体的指针,函数必须将结果数据填入其中。 + + 第一个参数是一个指向 spgChooseIn C 结构体的 + 指针,其中包含该函数的输入数据。第二个参数是一个指向 + spgChooseOut C 结构体的指针,函数必须将结果 + 数据填入其中。 + typedef struct spgChooseIn { Datum datum; /* 要被索引的原始 datum */ @@ -267,7 +283,7 @@ typedef struct spgChooseIn int level; /* 当前层级(从零开始计) */ /* 来自当前内部元组的数据 */ - bool allTheSame; /* 元组被标记为 all-the-same? */ + bool allTheSame; /* 元组被标记为全部相同? */ bool hasPrefix; /* 元组有前缀? */ Datum prefixDatum; /* 如果有,前缀值 */ int nNodes; /* 内部元组中的结点数 */ @@ -315,8 +331,27 @@ typedef struct spgChooseOut } spgChooseOut; - datum是要插入索引的原始数据,其类型为spgConfigIn.attTypeleafDatum是一个spgConfigOut.leafType类型的值,其初始值是方法compress应用于datum的结果,前提是提供了方法compress;否则,其值与datum相同。leafDatum可能在树的较低层发生变化,如果choosepicksplit方法对它进行了修改。当插入搜索到达叶页时,leafDatum的当前值将存储到新创建的叶子元组中。level是当前内部元组的层级,根层为零。allTheSame为真,表示当前内部元组被标记为包含多个等价结点(参见)。 - hasPrefix为真时,表示当前内部元组包含前缀;若是如此,prefixDatum就是该前缀值。nNodes是内部元组中包含的子结点数量,而nodeLabels是它们的标签值数组;如果没有标签,则为 NULL。 + datum 是将要插入索引的、类型为 + spgConfigIn.attType + 的原始 datum。leafDatum 是一个类型为 + spgConfigOut.leafType + 的值;如果提供了 compress 方法,它最初是将 + datum 交给 + compress 的结果,否则与 + datum 相同。如果 choose + 或 picksplit 方法修改了它,那么在树的更低层级中 + leafDatum 可能会发生变化。当插入搜索到达 + 叶子页时,leafDatum 的当前值将存储在新创 + 建的叶子元组中。level 是当前内部元组的层 + 级,根层为零。若当前内部元组被标记为包含多个等价结点(参见 + ),则 + allTheSame 为真。若当前内部元组包含前缀, + 则 hasPrefix 为真;若是如此, + prefixDatum 就是该前缀值。 + nNodes 是内部元组中包含的子结点数量, + nodeLabels 是它们的标签值数组;如果没有 + 标签,则为 NULL。 + choose 函数可以判定:新值要么匹配某个现有子结 @@ -385,9 +420,16 @@ typedef struct spgChooseOut 决定如何在一组叶子元组上创建一个新的内部元组。 - SQL声明必须如下所示: + + 该函数的 SQL 声明必须如下所示: + CREATE FUNCTION my_picksplit(internal, internal) RETURNS void ... -第一个参数是一个指向spgPickSplitInC 结构体的指针,其中包含该函数的输入数据。第二个参数是一个指向spgPickSplitOutC 结构体的指针,函数必须将结果数据填入其中。 + + 第一个参数是一个指向 spgPickSplitIn C 结构体的 + 指针,其中包含该函数的输入数据。第二个参数是一个指向 + spgPickSplitOut C 结构体的指针,函数必须将结 + 果数据填入其中。 + typedef struct spgPickSplitIn { int nTuples; /* 叶子元组的数量 */ @@ -408,7 +450,12 @@ typedef struct spgPickSplitOut } spgPickSplitOut; - nTuples是所提供的叶子元组数量。datums是包含这些元组数据值的数组,其中的值属于spgConfigOut.leafType类型。level是所有这些叶子元组当前共同的层级,它将成为新内部元组的层级。 + nTuples 是提供的叶子元组数量。 + datums 是由它们的 datum 值组成的数组,类 + 型为 spgConfigOut.leafType。 + level 是这些叶子元组共享的当前层级,它将 + 成为新内部元组的层级。 + hasPrefix 设为指示新的内部元组是否应 @@ -468,14 +515,14 @@ typedef struct spgInnerConsistentIn int nkeys; /* scankeys 数组的长度 */ int norderbys; /* orderbys 数组的长度 */ - Datum reconstructedValue; /* 在父元组处重构的值 */ + Datum reconstructedValue; /* 在父元组处重建的值 */ void *traversalValue; /* 操作符类特定的遍历值 */ MemoryContext traversalMemoryContext; /* 将新的遍历值放在这里 */ int level; /* 当前层级(从零开始计) */ bool returnData; /* 必须返回原始数据? */ /* 来自当前内部元组的数据 */ - bool allTheSame; /* 元组被标记为 all-the-same? */ + bool allTheSame; /* 元组被标记为全部相同? */ bool hasPrefix; /* 元组有前缀? */ Datum prefixDatum; /* 如果有,前缀值 */ int nNodes; /* 内部元组中的结点数 */ @@ -487,12 +534,12 @@ typedef struct spgInnerConsistentOut int nNodes; /* 需要访问的子结点数 */ int *nodeNumbers; /* 它们在结点数组中的索引 */ int *levelAdds; /* 对每个结点层级增加这么多 */ - Datum *reconstructedValues; /* 关联的重构值 */ + Datum *reconstructedValues; /* 关联的重建值 */ void **traversalValues; /* 操作符类特定的遍历值 */ double **distances; /* 关联距离 */ } spgInnerConsistentOut; -数组scankeys的长度为nkeys,它描述索引搜索条件。这些条件用 AND 组合 — 只有满足全部条件的索引项才是我们关心的。(注意,nkeys= 0 表示所有索引项都满足该查询。)通常 consistent 函数只关心sk_strategysk_argument字段,它们分别给出可索引操作符和比较值。特别地,无需检查sk_flags来判断比较值是否为 NULL,因为 SP-GiST 核心代码会过滤掉这些条件。数组orderbys的长度为norderbys,并以相同方式描述排序操作符(如果有)。reconstructedValue是为父元组重建的值;以下情况下它为(Datum) 0:位于根层,或者inner_consistent函数没有在父层提供该值。reconstructedValue始终属于spgConfigOut.leafType类型。traversalValue是指向任意遍历数据的指针,这些数据由上一次调用inner_consistent处理父索引元组时向下传递;在根层时则为 NULL。traversalMemoryContext是存放输出遍历值(见下文)的内存上下文。level是当前内部元组的层级,根层为零。returnDatatrue表示本查询需要重建数据;这要求config函数明确设置了canReturnData。 - allTheSame为真,表示当前内部元组被标记为all-the-same;在这种情况下,所有结点都具有相同的标签(如果有),因此要么全部匹配该查询,要么全部不匹配(参见)。 +数组scankeys的长度为nkeys,它描述索引搜索条件。这些条件用 AND 组合 — 只有满足全部条件的索引项才是我们关心的。(注意,nkeys= 0 表示所有索引项都满足该查询。)通常一致性检查函数只关心每个数组元素的sk_strategysk_argument字段,它们分别给出可索引操作符和比较值。特别地,无需检查sk_flags来判断比较值是否为 NULL,因为 SP-GiST 核心代码会过滤掉这些条件。数组orderbys的长度为norderbys,并以相同方式描述排序操作符(如果有)。reconstructedValue是为父元组重建的值;以下情况下它为(Datum) 0:位于根层,或者inner_consistent函数没有在父层提供该值。reconstructedValue始终属于spgConfigOut.leafType类型。traversalValue是指向任意遍历数据的指针,这些数据由上一次调用inner_consistent处理父索引元组时向下传递;在根层时则为 NULL。traversalMemoryContext是存放输出遍历值(见下文)的内存上下文。level是当前内部元组的层级,根层为零。returnDatatrue表示本查询需要重建数据;这要求config函数将canReturnData设为真。 + allTheSame为真,表示当前内部元组被标记为全部相同;在这种情况下,所有结点都具有相同的标签(如果有),因此要么全部匹配该查询,要么全部不匹配(参见)。 hasPrefix为真时,表示当前内部元组包含前缀;若是如此,prefixDatum就是该前缀值。nNodes是内部元组中包含的子结点数量,而nodeLabels是它们的标签值数组;如果结点没有标签,则为 NULL。 @@ -542,7 +589,7 @@ typedef struct spgLeafConsistentIn int nkeys; /* scankeys 数组的长度 */ int norderbys; /* orderbys 数组的长度 */ - Datum reconstructedValue; /* 在父元组处重构的值 */ + Datum reconstructedValue; /* 在父元组处重建的值 */ void *traversalValue; /* 操作符类特定的遍历值 */ int level; /* 当前层级(从零开始计) */ bool returnData; /* 必须返回原始数据? */ @@ -552,12 +599,12 @@ typedef struct spgLeafConsistentIn typedef struct spgLeafConsistentOut { - Datum leafValue; /* 重构出的原始数据(如果有) */ + Datum leafValue; /* 重建出的原始数据(如果有) */ bool recheck; /* 如果必须重新检查操作符则设为真 */ bool recheckDistances; /* 如果必须重新检查距离则设为真 */ double *distances; /* 关联距离 */ } spgLeafConsistentOut; -数组scankeys的长度为nkeys,它描述索引搜索条件。这些条件用 AND 组合 — 只有满足全部条件的索引项才满足该查询。(注意,nkeys= 0 表示所有索引项都满足该查询。)通常 consistent 函数只关心sk_strategysk_argument字段,它们分别给出可索引操作符和比较值。特别地,无需检查sk_flags来判断比较值是否为 NULL,因为 SP-GiST 核心代码会过滤掉这些条件。数组orderbys的长度为norderbys,并以相同方式描述排序操作符。reconstructedValue是为父元组重建的值;以下情况下它为(Datum) 0:位于根层,或者inner_consistent函数没有在父层提供该值。reconstructedValue始终属于spgConfigOut.leafType类型。traversalValue是指向任意遍历数据的指针,这些数据由上一次调用inner_consistent处理父索引元组时向下传递;在根层时则为 NULL。level是当前叶子元组的层级,根层为零。returnDatatrue表示本查询需要重建数据;这要求config函数明确设置了canReturnData。 +数组scankeys的长度为nkeys,它描述索引搜索条件。这些条件用 AND 组合 — 只有满足全部条件的索引项才满足该查询。(注意,nkeys= 0 表示所有索引项都满足该查询。)通常一致性检查函数只关心每个数组元素的sk_strategysk_argument字段,它们分别给出可索引操作符和比较值。特别地,无需检查sk_flags来判断比较值是否为 NULL,因为 SP-GiST 核心代码会过滤掉这些条件。数组orderbys的长度为norderbys,并以相同方式描述排序操作符。reconstructedValue是为父元组重建的值;以下情况下它为(Datum) 0:位于根层,或者inner_consistent函数没有在父层提供该值。reconstructedValue始终属于spgConfigOut.leafType类型。traversalValue是指向任意遍历数据的指针,这些数据由上一次调用inner_consistent处理父索引元组时向下传递;在根层时则为 NULL。level是当前叶子元组的层级,根层为零。returnDatatrue表示本查询需要重建数据;这要求config函数将canReturnData设为真。 leafDatum是当前叶元组中存储的键值,其类型为spgConfigOut.leafType @@ -609,7 +656,7 @@ typedef struct spgLeafConsistentOut - 如果被索引列属于可应用排序规则的数据类型,则索引排序规则会通过标准的 + 如果被索引列属于支持排序规则的数据类型,则索引排序规则会通过标准的 PG_GET_COLLATION() 机制传递给所有支持方法。 @@ -687,7 +734,7 @@ typedef struct spgLeafConsistentOut - <quote>All-the-Same</quote> 内部元组 + <quote>全部相同</quote>的内部元组 picksplit 无法把提供的叶子值划分为至少两个结点 diff --git a/zh/12/spi.sgml b/zh/12/spi.sgml index b2dd99fb..fafc7d0f 100644 --- a/zh/12/spi.sgml +++ b/zh/12/spi.sgml @@ -76,7 +76,7 @@ int SPI_connect_ext(int options) SPI_connect 会为某次 C 函数调用打开到 SPI 管理器 的连接。如果要通过 SPI 执行命令,就必须调用此函数。不过,有些 SPI - 实用函数可以在未连接的 C 函数中调用。 + 辅助函数可以在未连接的 C 函数中调用。 @@ -119,7 +119,7 @@ int SPI_connect_ext(int options) SPI_ERROR_CONNECT - 出错时 + 发生错误时 @@ -291,11 +291,11 @@ SPI_execute("INSERT INTO foo SELECT * FROM bar RETURNING *", false, 5); typedef struct { - MemoryContext tuptabcxt; /* memory context of result table */ - uint64 alloced; /* number of alloced vals */ - uint64 free; /* number of free vals */ - TupleDesc tupdesc; /* row descriptor */ - HeapTuple *vals; /* rows */ + MemoryContext tuptabcxt; /* 结果表的内存上下文 */ + uint64 alloced; /* 已分配的 vals 数量 */ + uint64 free; /* 空闲的 vals 数量 */ + TupleDesc tupdesc; /* 行描述符 */ + HeapTuple *vals; /* 行 */ } SPITupleTable; vals 是一个指向行的指针数组。(有效项数为 SPI_processed。) @@ -494,7 +494,7 @@ typedef struct SPI_ERROR_UNCONNECTED - 从未连接的 C 函数中调用 + 如果从一个未连接的 C 函数中调用 @@ -507,9 +507,9 @@ typedef struct 所有 SPI 查询执行函数都会设置 SPI_processed 和 - SPI_tuptable(只设置指针,而不会复制结构体内容)。如果 + SPI_tuptable(只设置指针,而不更改结构体内容)。如果 需要在后续调用之后继续访问 SPI_execute 或其他查询 - 执行函数的结果表,请把这两个全局变量保存到本地 C 函数变量中。 + 执行函数的结果表,请把这两个全局变量保存到 C 函数的局部变量中。 @@ -554,7 +554,7 @@ int SPI_exec(const char * command, long count< const char * command - 包含要执行命令的字符串 + 包含待执行命令的字符串 @@ -563,7 +563,7 @@ int SPI_exec(const char * command, long count< long count - 要返回的最大行数,或者用0表示没有限制 + 要返回的最大行数,或者用 0 表示不限制 @@ -625,7 +625,7 @@ int SPI_execute_with_args(const char *command, SPI_execute_plan 达到类似效果。不过,使用本函数 时,查询计划总会针对所提供的具体参数值进行定制。对于一次性查询执行,应 优先选择本函数。如果同一条命令要用许多不同参数重复执行,则两种方式孰快 - 取决于重新计划的代价与定制计划收益之间的权衡。 + 取决于重新规划的代价与定制计划收益之间的权衡。 @@ -680,9 +680,9 @@ int SPI_execute_with_args(const char *command, 如果 nullsNULL,则 - SPI_execute_with_args 会假定没有参数为 NULL。 - 否则,如果对应参数值非 NULL,则 nulls 数组中 - 的对应项应为 ' ';如果对应参数值为 NULL,则 + SPI_execute_with_args 会假定没有参数为空值。 + 否则,如果对应参数值非空值,则 nulls 数组中 + 的对应项应为 ' ';如果对应参数值为空值,则 对应项应为 'n'。(后一种情况下,对应 values 项中的实际值无关紧要。)注意, nulls 不是文本字符串,而只是一个数组,因此不 @@ -736,7 +736,7 @@ int SPI_execute_with_args(const char *command, SPI_prepare - 准备一个语句,但不执行它 + 准备一个语句,但暂不执行 @@ -815,8 +815,7 @@ SPIPlanPtr SPI_prepare(const char * command, int 返回值 - SPI_prepare 返回一个指向非空 SPIPlan - 的指针,它是表示预备语句的不透明结构体。发生错误时会返回 + SPI_prepare 返回一个非空指针,指向表示预备语句的不透明结构体 SPIPlan。发生错误时会返回 NULL,并将 SPI_result 设为 SPI_execute 所使用的那些错误码之一;但如果 commandNULL,或者 @@ -835,17 +834,16 @@ SPIPlanPtr SPI_prepare(const char * command, int SPI_execute_plan 在最初几次使用时会根据提供的参数 值生成定制计划。当同一个预备语句被使用足够多次之后, SPI_execute_plan 会构建一个通用计划;如果它的代价 - 没有比定制计划高出太多,就会开始改用通用计划,而不是每次都重新计划。如 + 没有比定制计划高出太多,就会开始改用通用计划,而不是每次都重新规划。如 果这种默认行为不合适,可以把 CURSOR_OPT_GENERIC_PLANCURSOR_OPT_CUSTOM_PLAN 标志传给 SPI_prepare_cursor,分别强制使用通用计划或定制计划。 - 尽管预备语句的主要目的在于避免重复进行解析分析和计划,但只要语句中使用 + 尽管预备语句的主要目的在于避免重复进行解析分析和规划,但只要语句中使用 的数据库对象自上次使用该预备语句以来发生了定义性(DDL)变更, - PostgreSQL 就会在再次使用前强制重新分析并重 - 新计划该语句。此外,如果 的值在两次 + PostgreSQL 就会在再次使用前强制重新分析并重新规划该语句。此外,如果 的值在两次 使用之间发生变化,该语句也会基于新的 search_path 重 新解析。(后一种行为是从 PostgreSQL 9.3 开 始引入的。)有关预备语句行为的更多信息,请参见 @@ -931,7 +929,7 @@ SPIPlanPtr SPI_prepare_cursor(const char * command, int < Oid * argtypes - 指向数组的指针,该数组包含参数数据类型的 + 一个数组指针,它指向的数组包含参数的数据类型的 OID @@ -1023,7 +1021,7 @@ SPIPlanPtr SPI_prepare_params(const char * command, ParserSetupHook parserSetup - 语法分析器钩子设置函数 + 解析器钩子设置函数 @@ -1238,8 +1236,8 @@ bool SPI_is_cursor_plan(SPIPlanPtr plan) 返回值 - 如果 plan 能产生游标,则返回 - true;如果不能,则返回 false,并将 + 返回 truefalse,表示 + plan 能否产生游标,同时将 SPI_result 设为零。如果无法确定答案(例如 planNULL 或无效,或者在 未连接到 SPI 时调用),则会将 SPI_result 设为合适 @@ -1311,15 +1309,14 @@ int SPI_execute_plan(SPIPlanPtr plan, Datum * - 如果nullsNULL, - 那么SPI_execute_plan会假设没有参数 - 为空值。否则,如果对应的参数值为非空, - nulls - 数组的每一个项都应该是' ';如果对应参数值为空, - 对应项应为'n'(在后 - 面的情况中,对应的values项中的值没有 - 关系)。注意nulls不是一个文本字符串, - 它只是一个数组:它不需要一个'\0'终止符。 + 如果 nullsNULL,则 + SPI_execute_plan 会假定没有参数为空值。 + 否则,如果对应参数值非空值,则 nulls 数组中 + 的对应项应为 ' ';如果对应参数值为空值,则 + 对应项应为 'n'。(后一种情况下,对应 + values 项中的实际值无关紧要。)注意, + nulls 不是文本字符串,而只是一个数组,因此不 + 需要 '\0' 终止符。 @@ -1450,7 +1447,7 @@ int SPI_execute_plan_with_paramlist(SPIPlanPtr plan, long count - 要返回的最大行数,或者用0表示没有限制 + 要返回的最大行数,或者用 0 表示不限制 @@ -1534,15 +1531,14 @@ int SPI_execp(SPIPlanPtr plan, Datum * values< - 如果nullsNULL, - 那么SPI_execp会假设没有参数 - 为空值。否则,如果对应的参数值为非空, - nulls - 数组的每一个项都应该是' ';如果对应参数值为空, - 对应项应为'n'(在后 - 面的情况中,对应的values项中的值没有 - 关系)。注意nulls不是一个文本字符串, - 它只是一个数组:它不需要一个'\0'终止符。 + 如果 nullsNULL,则 + SPI_execp 会假定没有参数为空值。 + 否则,如果对应参数值非空值,则 nulls 数组中 + 的对应项应为 ' ';如果对应参数值为空值,则 + 对应项应为 'n'。(后一种情况下,对应 + values 项中的实际值无关紧要。)注意, + nulls 不是文本字符串,而只是一个数组,因此不 + 需要 '\0' 终止符。 @@ -1551,7 +1547,7 @@ int SPI_execp(SPIPlanPtr plan, Datum * values< long count - 要返回的最大行数,或者用0表示没有限制 + 要返回的最大行数,或者用 0 表示不限制 @@ -1659,15 +1655,14 @@ Portal SPI_cursor_open(const char * name, SPIPlanPtr - 如果nullsNULL, - 那么SPI_cursor_open会假设没有参数 - 为空值。否则,如果对应的参数值为非空, - nulls - 数组的每一个项都应该是' ';如果对应参数值为空, - 对应项应为'n'(在后 - 面的情况中,对应的values项中的值没有 - 关系)。注意nulls不是一个文本字符串, - 它只是一个数组:它不需要一个'\0'终止符。 + 如果 nullsNULL,则 + SPI_cursor_open 会假定没有参数为空值。 + 否则,如果对应参数值非空值,则 nulls 数组中 + 的对应项应为 ' ';如果对应参数值为空值,则 + 对应项应为 'n'。(后一种情况下,对应 + values 项中的实际值无关紧要。)注意, + nulls 不是文本字符串,而只是一个数组,因此不 + 需要 '\0' 终止符。 @@ -1728,11 +1723,10 @@ Portal SPI_cursor_open_with_args(const char *name, - 对于一次性的查询执行,这个函数应该比 - SPI_prepare_cursor加上其后的 - SPI_cursor_open更好。如果相同的命令 - 要被用很多不同的参数执行,哪种方法更快就要取决于重做计划的 - 代价与定制计划带来的好处之间谁更有利。 + 对于一次性查询执行,应优先使用此函数,而不是先调用 + SPI_prepare_cursor 再调用 + SPI_cursor_open。如果同一条命令要用许多不同参数执行, + 哪种方法更快取决于重新规划的代价与定制计划收益之间的权衡。 @@ -1776,8 +1770,8 @@ Portal SPI_cursor_open_with_args(const char *name, Oid * argtypes - 一个长度为nargs的数组, - 包含参数的数据类型的OID + 一个长度为 nargs 的数组,包含参数数据类型的 + OID @@ -1786,8 +1780,7 @@ Portal SPI_cursor_open_with_args(const char *name, Datum * values - 一个长度为nargs的数组, - 包含实际的参数值 + 一个长度为 nargs 的数组,包含实际参数值 @@ -1796,20 +1789,19 @@ Portal SPI_cursor_open_with_args(const char *name, const char * nulls - 一个长度为nargs的数组, - 描述哪些参数为空值 + 一个长度为 nargs 的数组,用于描述哪些参数为 + 空值 - 如果nullsNULL, - 那么SPI_cursor_open_with_args会假设没有参数 - 为空值。否则,如果对应的参数值为非空, - nulls - 数组的每一个项都应该是' ';如果对应参数值为空, - 对应项应为'n'(在后 - 面的情况中,对应的values项中的值没有 - 关系)。注意nulls不是一个文本字符串, - 它只是一个数组:它不需要一个'\0'终止符。 + 如果 nullsNULL,则 + SPI_cursor_open_with_args 会假定没有参数为空值。 + 否则,如果对应参数值非空值,则 nulls 数组中 + 的对应项应为 ' ';如果对应参数值为空值,则 + 对应项应为 'n'。(后一种情况下,对应 + values 项中的实际值无关紧要。)注意, + nulls 不是文本字符串,而只是一个数组,因此不 + 需要 '\0' 终止符。 @@ -2079,7 +2071,7 @@ void SPI_cursor_fetch(Portal portal, bool forw 如果该游标的计划不是用CURSOR_OPT_SCROLL - 选项创建的,向后获取会失败。 + 选项创建的,向后获取可能失败。 @@ -2153,7 +2145,7 @@ void SPI_cursor_move(Portal portal, bool forwa 如果该游标的计划不是用CURSOR_OPT_SCROLL - 选项创建的,向后移动会失败。 + 选项创建的,向后移动可能失败。 @@ -2249,8 +2241,7 @@ void SPI_scroll_cursor_fetch(Portal portal, FetchDirectio 如果该游标的计划不是用CURSOR_OPT_SCROLL - 选项创建的,除FETCH_FORWARD之外的方向值会 - 失败。 + 选项创建的,除FETCH_FORWARD之外的方向值可能失败。 @@ -2347,8 +2338,7 @@ void SPI_scroll_cursor_move(Portal portal, FetchDirection 如果该游标的计划不是用CURSOR_OPT_SCROLL - 选项创建的,除FETCH_FORWARD之外的方向值会 - 失败。 + 选项创建的,除FETCH_FORWARD之外的方向值可能失败。 @@ -2523,7 +2513,8 @@ SPIPlanPtr SPI_saveplan(SPIPlanPtr plan) 返回值 - 返回指向复制后的语句的指针;如果失败,则返回 NULL。出错时,SPI_result 设置如下: + 复制后语句的指针;如果未成功则返回NULL。 + 错误时,SPI_result会被这样设置: @@ -2569,8 +2560,8 @@ SPIPlanPtr SPI_saveplan(SPIPlanPtr plan) SPI_register_relation - ephemeral named relation - registering with SPI + 临时命名关系 + 向 SPI 注册 @@ -2594,7 +2585,7 @@ int SPI_register_relation(EphemeralNamedRelation enr) SPI_register_relation 使一个带有相关信息的临时命名关 - 系对通过当前 SPI 连接计划和执行的查询可用。 + 系对通过当前 SPI 连接规划和执行的查询可用。 @@ -2674,8 +2665,8 @@ int SPI_register_relation(EphemeralNamedRelation enr) SPI_unregister_relation - ephemeral named relation - unregistering from SPI + 临时命名关系 + 从 SPI 注销 @@ -2722,7 +2713,7 @@ int SPI_unregister_relation(const char * name) 返回值 - 如果该命令的执行成功,则会返回下列(非负)值: + 如果该命令的执行成功,则将返回下列(非负)值: @@ -2777,13 +2768,13 @@ int SPI_unregister_relation(const char * name) SPI_register_trigger_data - ephemeral named relation - registering with SPI + 临时命名关系 + 向 SPI 注册 - transition tables - implementation in PLs + 过渡表 + 在 PL 中实现 @@ -2807,8 +2798,8 @@ int SPI_register_trigger_data(TriggerData *tdata) SPI_register_trigger_data 使触发器捕获的所有临时关系 - 都能在通过当前 SPI 连接计划和执行的查询中使用。目前,这指的是通过 - REFERENCING OLD/NEW TABLE AS ... 子句定义、并由 + 都能在通过当前 SPI 连接规划和执行的查询中使用。目前,这指的是由带有 + REFERENCING OLD/NEW TABLE AS ... 子句的 AFTER 触发器捕获的过渡表。PL 触发器处理函数应在建 立 SPI 连接后调用此函数。 @@ -2834,7 +2825,7 @@ int SPI_register_trigger_data(TriggerData *tdata) 返回值 - 如果命令的执行成功,则会返回下列(非负)值: + 如果该命令的执行成功,则将返回下列(非负)值: @@ -3106,7 +3097,7 @@ char * SPI_getvalue(HeapTuple row, TupleDesc r 返回值 - 列值;如果该列为 NULL、colnumber 超出范围 + 列值;如果该列为空值、colnumber 超出范围 (SPI_result 被设置为 SPI_ERROR_NOATTRIBUTE)或者没有输出函数 可用(SPI_result 被设置为 @@ -3198,8 +3189,8 @@ Datum SPI_getbinval(HeapTuple row, TupleDesc r 返回值 - 返回该列的二进制值。如果该列为 NULL,则 - isnull 指向的变量会被设为 true,否则设为 false。 + 返回该列的二进制值。如果该列为空值,则 + isnull 指向的变量会被设为真,否则设为假。 @@ -3235,7 +3226,7 @@ char * SPI_gettype(TupleDesc rowdesc, int coln SPI_gettype返回该指定列的数据类型名称 - 的拷贝(当你不再需要该拷贝后,可以使用pfree + 的副本(当你不再需要该副本后,可以使用pfree 释放它)。 @@ -3367,7 +3358,7 @@ char * SPI_getrelname(Relation rel) SPI_getrelname返回该指定关系的名称 - 的拷贝(当你不再需要该拷贝后,可以使用pfree + 的副本(当你不再需要该副本后,可以使用pfree 释放它)。 @@ -3460,7 +3451,7 @@ char * SPI_getnspname(Relation rel) SPI_result_code_string - 将结果代码表示为字符串 + 返回错误码的字符串表示 @@ -3474,7 +3465,7 @@ const char * SPI_result_code_string(int code); SPI_result_code_string 返回各种 SPI 函数返回的,或 - 存放在 SPI_result 中的结果代码的字符串表示。 + 存放在 SPI_result 中的结果码的字符串表示。 @@ -3486,7 +3477,7 @@ const char * SPI_result_code_string(int code); int code - 结果代码 + 结果码 @@ -3497,7 +3488,7 @@ const char * SPI_result_code_string(int code); 返回值 - 结果代码的字符串表示。 + 结果码的字符串表示。 @@ -3509,8 +3500,8 @@ const char * SPI_result_code_string(int code); - memory context - in SPI + 内存上下文 + 在 SPI 中 PostgreSQL内存上下文 中分配内存。内存上下文为管理那些在许多不同位置创建、且生命周期各不相同 @@ -3535,7 +3526,7 @@ const char * SPI_result_code_string(int code); 办法是用 SPI_palloc 为返回对象分配内存。 SPI_palloc上层执行器上下文中分配 内存,也就是调用 SPI_connect 时的当前内存上下文; - 这正是从 C 函数返回值最合适的上下文。本节介绍的其他几个实用函数同样会返 + 这正是从 C 函数返回值最合适的上下文。本节介绍的其他几个辅助函数同样会返 回在上层执行器上下文中创建的对象。 @@ -3543,7 +3534,7 @@ const char * SPI_result_code_string(int code); 调用 SPI_connect 时,会把该 C 函数的私有上下文 (由 SPI_connect 创建)设为当前上下文。所有通过 pallocrepalloc 或 SPI - 实用函数分配的内存(本节另有说明的除外)都位于这个上下文中。当 C 函数通 + 辅助函数分配的内存(本节另有说明的除外)都位于这个上下文中。当 C 函数通 过 SPI_finish 与 SPI 管理器断开连接时,当前上下文 会恢复为上层执行器上下文,而在该 C 函数内存上下文中分配的所有内存都会被 释放,之后就不能再使用。 @@ -3738,7 +3729,7 @@ void SPI_pfree(void * pointer) SPI_copytuple - 在上层执行器上下文中创建一行的拷贝 + 在上层执行器上下文中创建一行的副本 @@ -3771,7 +3762,7 @@ HeapTuple SPI_copytuple(HeapTuple row) HeapTuple row - 要拷贝的行 + 要复制的行 @@ -3782,7 +3773,7 @@ HeapTuple SPI_copytuple(HeapTuple row) 返回值 - 拷贝后的行;出错时返回 NULL + 复制后的行;出错时返回 NULL (错误指示见 SPI_result @@ -3838,7 +3829,7 @@ HeapTupleHeader SPI_returntuple(HeapTuple row, TupleDesc HeapTuple row - 要拷贝的行 + 要复制的行 @@ -3847,7 +3838,7 @@ HeapTupleHeader SPI_returntuple(HeapTuple row, TupleDesc TupleDesc rowdesc - 行描述符(若要获得最佳缓存效果,大多数情况下应每次都传入同一个描述符) + 行描述符(若要获得最佳缓存效果,每次都传入同一个描述符) @@ -3858,7 +3849,7 @@ HeapTupleHeader SPI_returntuple(HeapTuple row, TupleDesc 返回值 - 指向拷贝后行的 HeapTupleHeader;出错时返回 + 指向复制后行的 HeapTupleHeader;出错时返回 NULL(错误指示见 SPI_result @@ -3960,13 +3951,14 @@ HeapTuple SPI_modifytuple(Relation rel, HeapTuple - 如果nullsNULL,那么 - SPI_modifytuple假定没有新值为空值。否则, - 如果对应的新值为非空,nulls数组的每一项都应 - 该是' ',而如果对应的新值为空值则为'n'(在 - 后一种情况中,对应的values项中的新值无关紧 - 要)。注意nulls不是一个文本字符串,只是一个 - 数组:它不需要一个'\0'终止符。 + 如果 nullsNULL,则 + SPI_modifytuple 会假定没有新值为空值。 + 否则,如果对应新值非空值,则 nulls 数组中 + 的对应项应为 ' ';如果对应新值为空值,则 + 对应项应为 'n'。(后一种情况下,对应 + values 项中的实际值无关紧要。)注意, + nulls 不是文本字符串,而只是一个数组,因此不 + 需要 '\0' 终止符。 @@ -4045,7 +4037,7 @@ void SPI_freetuple(HeapTuple row) SPI_freetuple释放之前在上层执行器上下文中 - 分配的一个行。 + 分配的一行。 @@ -4343,7 +4335,7 @@ void SPI_start_transaction(void) - 数据改变的可见性 + 数据更改的可见性 下列规则决定了使用 SPI 的函数(以及其他任何 C 函数)中数据更改的可见 @@ -4423,7 +4415,7 @@ execq(PG_FUNCTION_ARGS) int ret; uint64 proc; - /* Convert given text object to a C string */ + /* 把给定的文本对象转换成一个 C 字符串 */ command = text_to_cstring(PG_GETARG_TEXT_PP(0)); cnt = PG_GETARG_INT32(1); @@ -4434,7 +4426,7 @@ execq(PG_FUNCTION_ARGS) proc = SPI_processed; /* - * If some rows were fetched, print them via elog(INFO). + * 如果取出了一些行,通过 elog(INFO) 打印它们。 */ if (ret > 0 && SPI_tuptable != NULL) { @@ -4475,7 +4467,8 @@ CREATE FUNCTION execq(text, integer) RETURNS int8 - 以下是一个示例会话: + 下面是一个示例会话: + => SELECT execq('CREATE TABLE a (x integer)', 0); execq diff --git a/zh/12/stylesheet-speedup-common.xsl b/zh/12/stylesheet-speedup-common.xsl index e3fb582a..403f350c 100644 --- a/zh/12/stylesheet-speedup-common.xsl +++ b/zh/12/stylesheet-speedup-common.xsl @@ -95,6 +95,6 @@ -en +zh_cn diff --git a/zh/12/syntax.sgml b/zh/12/syntax.sgml index 4b553fbd..396f366c 100644 --- a/zh/12/syntax.sgml +++ b/zh/12/syntax.sgml @@ -21,7 +21,7 @@ 词法结构 - token + 词元 @@ -29,7 +29,7 @@ - 一个词元可以是关键词标识符带引号的标识符文字值(或常量),或者特殊字符符号。词元通常由空白(空格、制表符、换行)分隔,但如果不存在歧义,则不必如此(一般只有特殊字符与其他类型的词元相邻时才会这样)。 + 一个词元可以是关键词标识符带引号的标识符字面量(或常量),或者特殊字符符号。词元通常由空白(空格、制表符、换行)分隔,但如果不存在歧义,则不必如此(一般只有特殊字符与其他类型的词元相邻时才会这样)。 @@ -58,18 +58,18 @@ INSERT INTO MY_TABLE VALUES (3, 'hi there'); 标识符和关键词 - identifier - syntax of + 标识符 + 语法 - name - syntax of + 名称 + 语法 - key word - syntax of + 关键词 + 语法 @@ -83,7 +83,7 @@ INSERT INTO MY_TABLE VALUES (3, 'hi there'); - identifierlength + 标识符长度 系统对标识符最多只使用 NAMEDATALEN-1 个字节;在命令中可以写更长的名称,但它们会被截断。默认情况下, NAMEDATALEN 为 64,因此标识符的最大长度是 63 字节。如果这个限制有问题,可以通过修改 src/include/pg_config_manual.h 中的 NAMEDATALEN 常量来提高。 @@ -91,8 +91,8 @@ INSERT INTO MY_TABLE VALUES (3, 'hi there'); - case sensitivity - of SQL commands + 大小写敏感性 + SQL 命令 关键词和未加引号的标识符不区分大小写。因此: @@ -110,8 +110,8 @@ UPDATE my_table SET a = 5; - quotation marks - and identifiers + 引号 + 与标识符 还有第二类标识符:定界标识符带引号的标识符。它通过把任意字符序列括在双引号中形成(")。 定界标识符始终是标识符,绝不会是关键词。因此,"select" 可以用来引用名为 select 的列或表,而不加引号的 select 会被视为关键词,因此在期望表名或列名的位置使用时会导致解析错误。这个示例可以用带引号的标识符写成: @@ -125,7 +125,7 @@ UPDATE "my_table" SET "a" = 5; Unicode 转义 - in identifiers + 在标识符中 @@ -165,7 +165,7 @@ U&"d!0061t!+000061" UESCAPE '!' 常量 - constant + 常量 @@ -176,8 +176,8 @@ U&"d!0061t!+000061" UESCAPE '!' 字符串常量 - character string - constant + 字符串 + 常量 @@ -288,7 +288,7 @@ SELECT 'foo' 'bar'; - 如果配置参数off,那么PostgreSQL对常规字符串常量和转义字符串常量中的反斜线转义都识别。不过,从PostgreSQL 9.1 开始,该参数的默认值为on,意味着只在转义字符串常量中识别反斜线转义。这种行为更兼容标准,但是可能打断依赖于历史行为(反斜线转义总是会被识别)的应用。作为一种变通,你可以设置该参数为off,但是最好迁移到符合新的行为。如果你需要使用一个反斜线转义来表示一个特殊字符,为该字符串常量写上一个E。 + 如果配置参数off,那么PostgreSQL对常规字符串常量和转义字符串常量中的反斜线转义都识别。不过,从PostgreSQL 9.1 开始,该参数的默认值为on,意味着只在转义字符串常量中识别反斜线转义。这种行为更兼容标准,但是可能使依赖历史行为(始终识别反斜线转义)的应用无法正常工作。作为一种变通,你可以设置该参数为off,但最好修改应用,不再使用反斜线转义。如果你需要使用一个反斜线转义来表示一个特殊字符,为该字符串常量写上一个E @@ -306,7 +306,7 @@ SELECT 'foo' 'bar'; Unicode 转义 - in string constants + 在字符串常量中 @@ -346,13 +346,18 @@ U&'d!0061t!+000061' UESCAPE '!' 美元引用的字符串常量 - dollar quoting + 美元引用 - 指定字符串常量的标准语法通常很方便,但当所需字符串包含许多单引号时,就可能难以理解,因为每个单引号都必须写两遍。为了让这类情况下的查询更易读,PostgreSQL提供了另一种编写字符串常量的方法,称为美元引用。美元引用的字符串常量由一个美元符号($)、一个由零个或多个字符组成的可选标签、另一个美元符号、构成字符串内容的任意字符序列、一个美元符号、与该美元引用开头相同的标签,以及一个美元符号组成。例如,对于字符串 Dianne's horse,下面是使用美元引用指定它的两种不同方法: + + 虽然指定字符串常量的标准语法通常很方便,但当目标字符串中包含很多单引号时,就会变得难以阅读,因为每个单引号都必须写成两个。为了在这种情况下让查询更易读, + PostgreSQL 提供了另一种编写字符串常量的方式,称为美元引用(dollar quoting)。一个美元引用字符串常量由美元符号($)、一个由零个或多个字符组成的可选标签、另一个美元符号、组成字符串内容的任意字符序列、一个美元符号、开始该美元引用时使用的同一个标签以及最后一个美元符号组成。例如,下面是使用美元引用指定字符串 Dianne's horse 的两种不同写法: + $$Dianne's horse$$ $SomeTag$Dianne's horse$SomeTag$ -注意,在美元引用的字符串中,单引号不需要转义就可以使用。事实上,美元引用字符串内的任何字符都不会被转义:字符串内容始终按字面书写。反斜线没有特殊含义,美元符号也没有,除非它是与开头标签相匹配的序列的一部分。 + + 注意,在美元引用字符串内部,单引号可以直接使用而无须转义。事实上,美元引用字符串内部的任何字符都不会被转义:字符串内容总是按字面方式书写。反斜线不是特殊字符,美元符号也不是,除非它们构成了与开头标签匹配的序列。 + 可以通过在每个嵌套层级选择不同的标签,来嵌套美元引用字符串常量。这种做法最常见于编写函数定义时。例如: @@ -384,8 +389,8 @@ $function$ 位串常量 - bit string - constant + 位串 + 常量 @@ -405,18 +410,28 @@ $function$ 数字常量 - number - constant + 数字 + 常量 - 数字常量接受下列一般形式: + + 数字常量接受下列一般形式: + digits digits.digitse+-digits digits.digitse+-digits digitse+-digits -其中 digits 是一个或多个十进制数字(0 到 9)。若使用小数点,则小数点前后至少有一侧必须有数字。若使用指数标记(e),其后至少必须有一位数字。常量中不能嵌入空格或其他字符。注意,开头的正号或负号实际上不被视为常量的一部分,而是作用于常量的操作符。 + + 其中 digits 是一个或多个十进制数字(0 到 9)。 + 若使用小数点,则小数点前后至少有一侧必须有数字。若使用指数标记 + (e),其后至少必须有一位数字。常量中不能嵌入空格或 + 其他字符。请注意,前导正号或负号 + 实际上不属于常量本身,而是作用于常量的操作符。 + - 下面是一些有效数字常量的示例: + + 这些是合法数字常量的示例: + 42 3.5 4. @@ -434,12 +449,12 @@ $function$ - 为数字常量最初指定的数据类型,只是类型解析算法的起点。在大多数情况下,常量会根据上下文被自动强制转换成最合适的类型。必要时,你可以通过类型转换强制把一个数值解释为特定的数据类型。type cast + 为数字常量最初指定的数据类型,只是类型解析算法的起点。在大多数情况下,常量会根据上下文被自动强制转换成最合适的类型。必要时,你可以通过类型转换强制把一个数值解释为特定的数据类型。类型转换 例如,可以通过下面的写法强制把一个数值当作类型 realfloat4)处理: -REAL '1.23' -- string style -1.23::REAL -- PostgreSQL (historical) style +REAL '1.23' -- 字符串形式 +1.23::REAL -- PostgreSQL(历史)形式 这些实际上只是下面将要讨论的一般类型转换记法的特例。 @@ -450,8 +465,8 @@ REAL '1.23' -- string style 其他类型的常量 - data type - constant + 数据类型 + 常量 @@ -477,7 +492,7 @@ CAST ( 'string' AS type ) - 如中所述,::CAST() 以及函数调用语法也可以用来指定任意表达式的运行时类型转换。为避免语法歧义,type 'string' 语法只能用来指定简单字面常量的类型。该语法的另一个限制是不能用于数组类型;要指定数组常量的类型,请使用 ::CAST()。 + 如中所述,::CAST() 以及函数调用语法也可以用来指定任意表达式的运行时类型转换。为避免语法歧义,type 'string' 语法只能用来指定简单字面常量的类型。type 'string' 语法的另一个限制是不能用于数组类型;要指定数组常量的类型,请使用 ::CAST() @@ -490,8 +505,8 @@ CAST ( 'string' AS type ) 操作符 - operator - syntax + 操作符 + 语法 @@ -541,7 +556,7 @@ CAST ( 'string' AS type ) - 圆括号(())具有它们通常的含义,用来分组表达式并且强制优先。在某些情况中,圆括号被要求作为一个特定 SQL 命令的固定语法的一部分。 + 圆括号(())具有它们通常的含义,用来对表达式分组并确定运算优先级。在某些情况中,圆括号被要求作为一个特定 SQL 命令的固定语法的一部分。 @@ -559,7 +574,7 @@ CAST ( 'string' AS type ) - 分号(;)结束一个 SQL 命令。它不能出现在一个命令中间的任何位置,除了在一个字符串常量中或者一个被引用的标识符中。 + 分号(;)结束一个 SQL 命令。它不能出现在一个命令中间的任何位置,除了在一个字符串常量中或者一个带引号的标识符中。 @@ -571,7 +586,7 @@ CAST ( 'string' AS type ) - 星号(*)在某些上下文中用来表示表行或组合值的所有字段。当它被用作聚合函数的参数时,还有一种特殊含义,即该聚合不需要任何显式参数。 + 星号(*)在某些上下文中用来表示表行或复合值的所有字段。当它被用作聚合函数的参数时,还有一种特殊含义,即该聚合不需要任何显式参数。 @@ -589,22 +604,22 @@ CAST ( 'string' AS type ) 注释 - comment - in SQL + 注释 + 在 SQL 中 注释是一串以双连字符开始并延伸到行尾的字符,例如: --- This is a standard SQL comment +-- 这是一条标准 SQL 注释 另外,也可以使用 C 风格注释块: -/* multiline comment - * with nesting: /* nested block comment */ +/* 多行注释 + * 包含嵌套:/* 嵌套块注释 */ */ 这里该注释开始于/*并且延伸到匹配出现的*/。这些注释块可按照 SQL 标准中指定的方式嵌套,但和 C 中不同。这样我们可以注释掉一大段可能包含注释块的代码。 @@ -619,8 +634,8 @@ CAST ( 'string' AS type ) 操作符优先级 - operator - precedence + 操作符 + 优先级 展示了 PostgreSQL 中操作符的优先级和结合性。大多数操作符具有相同的优先级,并且是左结合的。操作符的优先级和结合性是固定写在解析器中的。 @@ -667,7 +682,7 @@ SELECT (5 !) - 6; + - - 一元加、一元减 + 一元正号、一元负号 @@ -685,13 +700,13 @@ SELECT (5 !) - 6; ^ - 指数 + 求幂 * / % - 乘、除、模 + 乘、除、取模 @@ -703,7 +718,7 @@ SELECT (5 !) - 6; (任意其他操作符) - 所有其他本地以及用户定义的操作符 + 所有其他内置以及用户定义的操作符 @@ -1389,7 +1404,7 @@ SELECT * FROM tbl WHERE a COLLATE "C" > 'foo'; SELECT * FROM tbl WHERE (a > 'foo') COLLATE "C"; - 因为它尝试把一个排序规则应用到>操作符的结果,而它的数据类型是非可排序数据类型boolean。 + 因为它尝试把一个排序规则应用到>操作符的结果,而它的数据类型是不支持排序规则的数据类型boolean diff --git a/zh/12/textsearch.sgml b/zh/12/textsearch.sgml index 37d9381c..9de29fc4 100644 --- a/zh/12/textsearch.sgml +++ b/zh/12/textsearch.sgml @@ -1965,7 +1965,7 @@ ALTER TEXT SEARCH CONFIGURATION russian 分类词典示例 - 考虑简单的天文词库 thesaurus_astro,其中包含一些天文单词组合: + 考虑简单的天文词库 thesaurus_astro,其中包含一些天文单词组合: supernovae stars : sn @@ -2400,7 +2400,7 @@ ts_debug( config re - 以下是一个简单的示例: + 以下是一个简单的示例: SELECT * FROM ts_debug('english', 'a fat cat sat on a mat - it ate a fat rats'); diff --git a/zh/12/trigger.sgml b/zh/12/trigger.sgml index 2620d4a5..69e6ed13 100644 --- a/zh/12/trigger.sgml +++ b/zh/12/trigger.sgml @@ -4,7 +4,7 @@ 触发器 - trigger + 触发器 @@ -128,18 +128,18 @@ 生成列还有一些额外注意事项。 - generated column在触发器中 + 生成列在触发器中 存储型生成列会在 BEFORE 触发器之后、AFTER 触发器之前计算。因此,可以在 AFTER 触发器中检查生成值。在 BEFORE 触发器中,OLD 行如预期那样包含旧的 生成值,但 NEW 行尚未包含新的生成值,因此不应访问。对于 C 语言接口,此时该列内容未定义;更高层编程语言应阻止在 BEFORE 触发器中访问 NEW 行中的存储型 - 生成列。在 BEFORE 触发器中对生成列值所做的修改会被忽略并随后被覆盖。虚拟生成列在触发器触发时永远不会被计算。在 C 语言接口中,它们在触发器函数中的内容是未定义的;更高层编程语言应阻止在触发器中访问虚拟生成列。 + 生成列。在 BEFORE 触发器中对生成列值所做的修改会被忽略并随后被覆盖。 - 如果在同一关系上的同一事件为其定义了多个触发器,它们会按触发器名称的字母顺序触发。对于 BEFOREINSTEAD OF + 如果为同一关系上的同一事件定义了多个触发器,它们会按触发器名称的字母顺序触发。对于 BEFOREINSTEAD OF 触发器,每个触发器返回的、可能已经被修改过的行都会成为下一个触发器的输入。如果任何一个 BEFOREINSTEAD OF 触发器返回 NULL,则会放弃对该行执行该操作,并且后续触发器(针对该行)都不会再触发。 @@ -168,8 +168,8 @@ - trigger - arguments for trigger functions + 触发器 + 触发器函数的参数 在定义触发器时,可以为它指定参数。在触发器定义中包含参数,是为了让需求相似的不同触发器能够调用同一个函数。举例来说,可以有一个通用触发器函数,它接受两个列名作为参数,把当前用户写入其中一个列,把当前时间戳写入另一个列。只要编写得当,这个触发器函数就应独立于它所作用的具体表。因此,同一个函数可用于任何具有适当列的表上的 INSERT 事件,例如自动跟踪某个事务表中记录的创建。如果把它定义成 UPDATE 触发器,还可以用来跟踪最近更新事件。 @@ -195,7 +195,10 @@ 数据更改的可见性 - 如果你在触发器函数中执行 SQL 命令,而且这些命令访问的是该触发器所在的表,那么就需要了解数据可见性规则,因为这些规则决定了这些 SQL 命令能否看到导致该触发器触发的数据更改。简要来说: + + 如果你在触发器函数中执行 SQL 命令,而这些命令又访问该触发器所属的表,就需要了解数据可见性规则,因为这些规则决定了这些 SQL 命令是否能看到引发触发器的数据更改。简而言之: + + @@ -249,13 +252,13 @@ 用 C 编写触发器函数 - trigger - in C + 触发器 + 在 C 中 - transition tables - referencing from C trigger + 过渡表 + 从 C 触发器中引用 @@ -267,7 +270,7 @@ - 当函数由触发器管理器调用时,不会向它传递任何普通参数,但会传递一个指向 TriggerData 结构体的 context 指针。C 函数可以通过执行下列宏来检查自己是否由触发器管理器调用: + 当函数由触发器管理器调用时,不会向它传递任何普通参数,但会传递一个指向 TriggerData 结构体的 上下文 指针。C 函数可以通过执行下列宏来检查自己是否由触发器管理器调用: CALLED_AS_TRIGGER(fcinfo) @@ -312,14 +315,15 @@ typedef struct TriggerData tg_event - 描述调用该函数所对应的事件。可以使用下列宏来检查tg_event: + + 描述调用函数的事件。可以使用以下宏检查 tg_event TRIGGER_FIRED_BEFORE(tg_event) - 如果触发器在操作之前触发,则返回 true。 + 如果触发器在操作之前触发,则返回真。 @@ -328,7 +332,7 @@ typedef struct TriggerData TRIGGER_FIRED_AFTER(tg_event) - 如果触发器在操作之后触发,则返回 true。 + 如果触发器在操作之后触发,则返回真。 @@ -337,7 +341,7 @@ typedef struct TriggerData TRIGGER_FIRED_INSTEAD(tg_event) - 如果触发器是取代该操作而触发,则返回 true。 + 如果触发器是取代该操作而触发,则返回真。 @@ -346,7 +350,7 @@ typedef struct TriggerData TRIGGER_FIRED_FOR_ROW(tg_event) - 如果触发器是因行级事件触发,则返回 true。 + 如果触发器是因行级事件触发,则返回真。 @@ -355,7 +359,7 @@ typedef struct TriggerData TRIGGER_FIRED_FOR_STATEMENT(tg_event) - 如果触发器是因语句级事件触发,则返回 true。 + 如果触发器是因语句级事件触发,则返回真。 @@ -364,7 +368,7 @@ typedef struct TriggerData TRIGGER_FIRED_BY_INSERT(tg_event) - 如果触发器是由 INSERT 命令触发,则返回 true。 + 如果触发器是由 INSERT 命令触发,则返回真。 @@ -373,7 +377,7 @@ typedef struct TriggerData TRIGGER_FIRED_BY_UPDATE(tg_event) - 如果触发器是由 UPDATE 命令触发,则返回 true。 + 如果触发器是由 UPDATE 命令触发,则返回真。 @@ -382,7 +386,7 @@ typedef struct TriggerData TRIGGER_FIRED_BY_DELETE(tg_event) - 如果触发器是由 DELETE 命令触发,则返回 true。 + 如果触发器是由 DELETE 命令触发,则返回真。 @@ -391,7 +395,7 @@ typedef struct TriggerData TRIGGER_FIRED_BY_TRUNCATE(tg_event) - 如果触发器是由 TRUNCATE 命令触发,则返回 true。 + 如果触发器是由 TRUNCATE 命令触发,则返回真。 @@ -523,16 +527,16 @@ typedef struct Trigger - 一个完整的触发器实例 + 一个完整的触发器示例 这里给出一个非常简单的、用 C 编写的触发器函数示例。(用过程语言编写的触发器示例可见各过程语言的文档。) - 如果某条命令试图向列 x 中插入空值,函数 - trigf 就会报告表 ttest - 中的行数,并跳过实际操作。(这样,这个触发器就起到了非空约束的作用,但不会中止事务。) + 函数 trigf 会报告表 ttest 中的行数, + 并在命令试图向列 x 中插入空值时跳过实际操作。 + (这样,这个触发器就起到了非空约束的作用,但不会中止事务。) @@ -544,7 +548,9 @@ CREATE TABLE ttest ( - 这是触发器函数的源代码: + 下面是触发器函数的源代码: + - 编译完源代码后(参见),声明函数和触发器: + + 编译完这段源代码之后(见 ),声明该函数和这些触发器: + CREATE FUNCTION trigf() RETURNS trigger AS 'filename' LANGUAGE C; diff --git a/zh/12/typeconv.sgml b/zh/12/typeconv.sgml index ce3d5cb7..ab6407d4 100644 --- a/zh/12/typeconv.sgml +++ b/zh/12/typeconv.sgml @@ -28,7 +28,7 @@ -PostgreSQL扫描器/解析器将词法元素分成五个基本类别:整数、非整数数字、字符串、标识符和关键字。大多数非数值类型的常量会先被归类为字符串。SQL语言定义允许用字符串指定类型名,而PostgreSQL可以利用这一机制让解析器从一开始就沿着正确的路径处理。例如,查询: +PostgreSQL扫描器/解析器将词法元素分成五个基本类别:整数、非整数数字、字符串、标识符和关键字。大多数非数值类型的常量会先被归类为字符串。SQL语言定义允许给字符串指定类型名,而PostgreSQL可以利用这一机制让解析器从一开始就沿着正确的路径处理。例如,查询: SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; @@ -39,11 +39,11 @@ SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; (1 row) -包含两个文字常量,它们的类型分别是textpoint。如果没有为某个字符串文字指定类型,那么它最初会被赋予占位类型unknown,并在后文所述的后续阶段解析。 +包含两个字面量,它们的类型分别是textpoint。如果没有为某个字符串字面量指定类型,那么它最初会被赋予占位类型unknown,并在后文所述的后续阶段解析。 -有四种基本的 SQL 结构需要在 PostgreSQL 解析器中使用不同的类型转换规则: +在PostgreSQL解析器中,有四种基本的SQL结构需要采用不同的类型转换规则: @@ -82,7 +82,7 @@ SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; -由于经合并的SELECT语句的所有查询结果都必须出现在同一组列中,因此每个SELECT子句的结果类型必须彼此匹配,并转换为统一的一组类型。类似地,CASE结构中的结果表达式必须转换为某种公共类型,这样整个CASE表达式才有确定的输出类型。其他一些结构,如ARRAY[]以及GREATESTLEAST函数,也同样需要为若干子表达式确定公共类型。 +由于经UNION合并的SELECT语句的所有查询结果都必须出现在同一组列中,因此每个SELECT子句的结果类型必须彼此匹配,并转换为统一的一组类型。类似地,CASE结构中的结果表达式必须转换为某种公共类型,这样整个CASE表达式才有确定的输出类型。其他一些结构,如ARRAY[]以及GREATESTLEAST函数,也同样需要为若干子表达式确定公共类型。 @@ -161,11 +161,11 @@ SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; -检查是否存在一个恰好接受输入参数类型的操作符。如果存在(在被考虑的操作符集合中至多只有一个精确匹配),就使用它。若通过限定名调用(这种情况并不常见)某个允许不可信用户创建对象的模式中的操作符,而又缺少精确匹配,就会带来安全隐患 +检查是否存在一个恰好接受输入参数类型的操作符。如果存在(在被考虑的操作符集合中至多只有一个精确匹配),就使用它。若通过限定名调用(这种情况并不常见)某个允许不受信任的用户创建对象的模式中的操作符,而又缺少精确匹配,就会带来安全隐患 - 对于未带模式限定的名称,不会出现这种隐患,因为包含允许不可信用户创建对象的模式的搜索路径不是一种模式的安全使用方式。 + 对于未带模式限定的名称,不会出现这种隐患,因为包含允许不受信任的用户创建对象的模式的搜索路径不是一种模式的安全使用方式。 。在这种情况下,应通过对参数进行类型转换来强制获得精确匹配。 @@ -180,7 +180,7 @@ SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; -如果二元操作符调用的一个参数是unknown类型,而另一个是域类型,则接着检查是否存在两边都恰好接受该域基类型的操作符;如果有,就使用它。 +如果二元操作符调用的一个参数是unknown类型,而另一个是域类型,则接着检查是否存在两边都恰好接受该域基础类型的操作符;如果有,就使用它。 @@ -194,13 +194,13 @@ SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; -丢弃那些输入类型不匹配,且也无法通过隐式类型转换实现匹配的候选操作符。为此,假定unknown文字可以转换为任何类型。如果只剩一个候选操作符,就使用它;否则继续下一步。 +丢弃那些输入类型不匹配,且也无法通过隐式类型转换实现匹配的候选操作符。为此,假定unknown字面量可以转换为任何类型。如果只剩一个候选操作符,就使用它;否则继续下一步。 -如果任何输入参数是域类型,则在后续所有步骤中都把它当作该域的基类型。这样可以确保在解决操作符歧义时,域的行为与其基类型一致。 +如果任何输入参数是域类型,则在后续所有步骤中都把它当作该域的基础类型。这样可以确保在解决操作符歧义时,域的行为与其基础类型一致。 @@ -212,12 +212,12 @@ SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; -遍历所有候选操作符,保留那些在需要类型转换的最多位置上接受首选类型(属于输入数据类型的类型分类)的候选项。如果没有候选项接受首选类型,则保留全部候选项。如果只剩一个候选操作符,就使用它;否则继续下一步。 +遍历所有候选操作符,在需要类型转换的位置上,保留接受首选类型(属于输入数据类型的类型分类)的位置数最多的候选项。如果没有候选项接受首选类型,则保留全部候选项。如果只剩一个候选操作符,就使用它;否则继续下一步。 -如果有任何输入参数是unknown,就检查剩余候选项在这些参数位置上接受哪些类型分类。在每个位置上,如果有任何候选项接受string分类,就选择该分类。(这种偏向字符串的做法是合适的,因为unknown类型的文字看起来像字符串。)否则,如果所有剩余候选项都接受同一种类型分类,就选择该分类;否则失败,因为在缺少更多线索的情况下无法推断出正确选择。然后丢弃不接受所选类型分类的候选项。此外,如果有任何候选项接受该分类中的首选类型,就丢弃在该参数上接受非首选类型的候选项。如果没有候选项通过这些测试,则保留全部候选项。如果只剩一个候选项,就使用它;否则继续下一步。 +如果有任何输入参数是unknown,就检查剩余候选操作符在这些参数位置上接受哪些类型分类。在每个位置上,如果有任何候选项接受string分类,就选择该分类。(这种偏向字符串的做法是合适的,因为unknown类型的字面量看起来像字符串。)否则,如果所有剩余候选项都接受同一种类型分类,就选择该分类;否则失败,因为在缺少更多线索的情况下无法推断出正确选择。然后丢弃不接受所选类型分类的候选项。此外,如果有任何候选项接受该分类中的首选类型,就丢弃在该参数上接受非首选类型的候选项。如果没有候选项通过这些测试,则保留全部候选项。如果只剩一个候选操作符,就使用它;否则继续下一步。 @@ -265,7 +265,7 @@ SELECT CAST(40 AS bigint) ! AS "40 factorial"; -一个只有一个未指定参数的例子: +一个参数未指定类型的例子: SELECT text 'abc' || 'def' AS "text and unknown"; @@ -293,7 +293,7 @@ SELECT 'abc' || 'def' AS "unspecified"; -这里对使用哪种类型没有初始提示,因为查询中没有指定任何类型。因此,解析器会查找所有候选操作符,并发现既有接受字符串分类输入的候选项,也有接受位串分类输入的候选项。由于在可用时优先选择字符串分类,所以会选中该分类,再使用字符串的首选类型text作为解析这些unknown类型文字的具体类型。 +这里对使用哪种类型没有初始提示,因为查询中没有指定任何类型。因此,解析器会查找所有候选操作符,并发现既有接受字符串分类输入的候选项,也有接受位串分类输入的候选项。由于在可用时优先选择字符串分类,所以会选中该分类,再使用字符串的首选类型text作为解析这些unknown类型字面量的具体类型。 @@ -301,7 +301,7 @@ SELECT 'abc' || 'def' AS "unspecified"; 绝对值与取反操作符类型解析 -在 PostgreSQL 操作符目录中,前缀操作符 @ 有多个条目,分别实现各种数值数据类型的绝对值运算。其中一个条目用于类型 float8,它是数值分类中的首选类型。因此,PostgreSQL 会使用该条目来处理 unknown 输入: +PostgreSQL操作符目录中为前缀操作符@提供了多个条目,它们分别实现各种数值数据类型的绝对值操作。其中一个条目对应float8,它是数值分类中的首选类型。因此,当遇到一个unknown输入时,PostgreSQL会使用该条目: SELECT @ '-4.5' AS "abs"; abs @@ -309,7 +309,7 @@ SELECT @ '-4.5' AS "abs"; 4.5 (1 row) -这里,系统在应用所选操作符之前,已将 unknown 类型文字隐式解析为 float8 类型。我们可以验证所使用的是 float8 而不是其他类型: +这里,系统在应用所选操作符之前,已经把unknown类型字面量隐式解析为float8。我们可以验证使用的确实是float8,而不是其他类型: SELECT @ '-4.5e500' AS "abs"; @@ -351,8 +351,7 @@ SELECT array[1,2] <@ '{1,2,3}' as "is subset"; t (1 row) -在 PostgreSQL 操作符目录中,中缀操作符 <@ 有多个条目,但可能接受左侧为整数数组的只有两个:数组包含(anyarray <@ anyarray)和范围包含(anyelement <@ anyrange)。由于这些多态伪类型(见 )都不是首选类型,解析器无法据此消除歧义。不过, 要求它假定 unknown 类型文字与另一个输入的类型相同,即整数数组。这样,两个操作符中只有一个能够匹配,因此会选择数组包含。(如果选择了范围包含,就会得到错误,因为该字符串的格式不符合范围文字的要求。) +PostgreSQL操作符目录中为中缀操作符<@定义了多个条目,但左侧能够接受整数数组的只有两种:数组包含(anyarray <@ anyarray)和范围包含(anyelement <@ anyrange)。由于这些多态伪类型(见)都不被视为首选类型,解析器无法据此消除歧义。不过,要求它假定unknown类型字面量与另一输入具有相同类型,也就是整数数组。这样两个操作符中只有一个能够匹配,因此会选择数组包含。(如果选中范围包含,就会报错,因为该字符串的格式并不是合法的范围字面量。) @@ -361,7 +360,7 @@ linkend="datatype-pseudo"/>)都不是首选类型,解析器无法据此消 域类型上的自定义操作符 -用户有时会尝试声明只适用于某个域类型的操作符。这是可行的,但远没有看上去那样有用,因为操作符解析规则被设计成优先选择作用于域基类型的操作符。考虑下面的例子: +用户有时会尝试声明只适用于某个域类型的操作符。这是可行的,但远没有看上去那样有用,因为操作符解析规则被设计成优先选择作用于域基础类型的操作符。考虑下面的例子: CREATE DOMAIN mytext AS text CHECK(...); CREATE FUNCTION mytext_eq_text (mytext, text) RETURNS boolean AS ...; @@ -370,11 +369,11 @@ CREATE TABLE mytable (val mytext); SELECT * FROM mytable WHERE val = 'foo'; -这个查询不会使用自定义操作符。解析器首先会检查是否存在mytext = mytext操作符(),但并不存在;然后它会考虑该域的基类型text,并检查是否存在text = text操作符(),而这是存在的;于是它会把unknown类型的文字解析为text,并使用text = text操作符。要让自定义操作符被使用,唯一的方法是显式地对该文字做类型转换: +这个查询不会使用自定义操作符。解析器首先会检查是否存在mytext = mytext操作符(),但并不存在;然后它会考虑该域的基础类型text,并检查是否存在text = text操作符(),而这是存在的;于是它会把unknown类型的字面量解析为text,并使用text = text操作符。要让自定义操作符被使用,唯一的方法是显式地对该字面量做类型转换: SELECT * FROM mytable WHERE val = text 'foo'; -这样就会根据精确匹配规则立即找到mytext = text操作符。如果解析过程进入最佳匹配规则,它们会主动排斥作用于域类型的操作符。如果不是这样,这类操作符会导致过多的操作符歧义失败,因为类型转换规则总是把域视为可以转换到其基类型或从其基类型转换而来,因此域操作符会在所有与基类型上同名操作符相同的场景中都被视为可用。 +这样就会根据精确匹配规则立即找到mytext = text操作符。如果解析过程进入最佳匹配规则,它们会主动排斥作用于域类型的操作符。如果不是这样,这类操作符会导致过多的操作符歧义失败,因为类型转换规则总是把域视为可以转换到其基础类型或从其基础类型转换而来,因此域操作符会在所有与基础类型上同名操作符相同的场景中都被视为可用。 @@ -409,26 +408,26 @@ SELECT * FROM mytable WHERE val = text 'foo'; -如果函数声明了一个VARIADIC数组参数,而调用时没有使用VARIADIC关键字,则把该函数视为其数组参数按需要被其元素类型的一个或多个出现所替换,以匹配该调用。扩展之后,该函数的有效参数类型可能与某个非可变参数函数完全相同。在这种情况下,使用搜索路径中较早出现的函数;如果两个函数位于同一模式,则优先选择非可变参数函数。 +如果函数声明了一个VARIADIC数组参数,而调用时没有使用VARIADIC关键字,则把数组参数视为一个或多个其元素类型的参数,个数按匹配该调用的需要确定。扩展之后,该函数的有效参数类型可能与某个非VARIADIC函数完全相同。在这种情况下,使用搜索路径中较早出现的函数;如果两个函数位于同一模式,则优先选择非VARIADIC函数。 -通过限定名调用某个允许不可信用户创建对象的模式中找到的可变参数函数时,会带来安全隐患 +通过限定名调用某个允许不受信任的用户创建对象的模式中找到的可变参数函数时,会带来安全隐患 - 对于未带模式限定的名称,不会出现这种隐患,因为包含允许不可信用户创建对象的模式的搜索路径不是一种模式的安全使用方式。 + 对于未带模式限定的名称,不会出现这种隐患,因为包含允许不受信任的用户创建对象的模式的搜索路径不是一种模式的安全使用方式。 - 。恶意用户可以借此劫持调用,并以你的身份执行任意 SQL 函数。改为使用带有VARIADIC关键字的调用可以绕过这一隐患。对于填充VARIADIC "any"参数的调用,往往没有包含VARIADIC关键字的等价写法。要安全地发出这类调用,该函数所在模式必须只允许可信用户创建对象。 + 。恶意用户可以借此劫持调用,并以你的身份执行任意 SQL 函数。改为使用带有VARIADIC关键字的调用可以绕过这一隐患。对于填充VARIADIC "any"参数的调用,往往没有包含VARIADIC关键字的等价写法。要安全地发出这类调用,该函数所在模式必须只允许受信任的用户创建对象。 -带有参数默认值的函数,被认为可以匹配任何省略了零个或多个可默认参数位置的调用。如果不止一个这样的函数能匹配某个调用,则使用搜索路径中最早出现的那一个。如果同一模式中存在两个或更多这样的函数,并且它们在未使用默认值的参数位置上的参数类型相同(如果它们具有不同的可默认参数集合,这种情况是可能的),系统就无法判断该偏好哪一个;如果找不到更好的匹配,就会报有歧义的函数调用错误。 +带有参数默认值的函数,被认为可以匹配任何省略了零个或多个可使用默认值的参数位置的调用。如果不止一个这样的函数能匹配某个调用,则使用搜索路径中最早出现的那一个。如果同一模式中存在两个或更多这样的函数,并且它们在未使用默认值的参数位置上的参数类型相同(如果它们具有不同的带有默认值的参数集合,这种情况是可能的),系统就无法判断该偏好哪一个;如果找不到更好的匹配,就会报有歧义的函数调用错误。 -通过限定名调用某个允许不可信用户创建对象的模式中的任意函数时,会带来可用性隐患。恶意用户可以用现有函数的名字创建一个新函数,复制该函数的参数,并附加带有默认值的新参数。这样就会阻止对原始函数的新调用。为避免这种隐患,应把函数放在只允许可信用户创建对象的模式中。 +通过限定名调用某个允许不受信任的用户创建对象的模式中的任意函数时,会带来可用性隐患。恶意用户可以用现有函数的名字创建一个新函数,复制该函数的参数,并附加带有默认值的新参数。这样就会阻止对原始函数的新调用。为避免这种隐患,应把函数放在只允许受信任的用户创建对象的模式中。 @@ -437,13 +436,13 @@ SELECT * FROM mytable WHERE val = text 'foo'; -检查是否存在一个恰好接受输入参数类型的函数。如果存在(在被考虑的函数集合中至多只有一个精确匹配),就使用它。若通过限定名调用某个允许不可信用户创建对象的模式中的函数,而又缺少精确匹配,就会带来安全隐患。在这种情况下,应通过对参数进行类型转换来强制获得精确匹配。(涉及unknown的情况在这一步永远找不到匹配。) +检查是否存在一个恰好接受输入参数类型的函数。如果存在(在被考虑的函数集合中至多只有一个精确匹配),就使用它。若通过限定名调用某个允许不受信任的用户创建对象的模式中的函数,而又缺少精确匹配,就会带来安全隐患。在这种情况下,应通过对参数进行类型转换来强制获得精确匹配。(涉及unknown的情况在这一步永远找不到匹配。) -如果没有找到精确匹配,就检查该函数调用是否看起来像一种特殊的类型转换请求。这种情况发生在:函数调用只有一个参数,且函数名与某个数据类型的(内部)名称相同。此外,函数参数必须是unknown类型文字,或者是一种到该命名数据类型二进制可强制转换的类型,或者是一种可以通过应用其 I/O 函数转换为该命名数据类型的类型(也就是说,该转换要么转到某种标准字符串类型,要么从某种标准字符串类型转来)。满足这些条件时,该函数调用会被当作一种CAST形式。 +如果没有找到精确匹配,就检查该函数调用是否看起来像一种特殊的类型转换请求。这种情况发生在:函数调用只有一个参数,且函数名与某个数据类型的(内部)名称相同。此外,函数参数必须是unknown类型字面量,或者是一种可以二进制强制转换为该命名数据类型的类型,或者是一种可以通过应用其 I/O 函数转换为该命名数据类型的类型(也就是说,该转换要么转到某种标准字符串类型,要么从某种标准字符串类型转来)。满足这些条件时,该函数调用会被当作一种CAST形式。 之所以有这一步,是为了在不存在实际类型转换函数的情况下仍支持函数风格的类型转换写法。如果存在类型转换函数,按惯例它会以其输出类型命名,因此无需为此设置特殊情况。更多说明见。 @@ -459,13 +458,13 @@ SELECT * FROM mytable WHERE val = text 'foo'; -丢弃那些输入类型不匹配,且也无法通过隐式类型转换实现匹配的候选函数。为此,假定unknown文字可以转换为任何类型。如果只剩一个候选函数,就使用它;否则继续下一步。 +丢弃那些输入类型不匹配,且也无法通过隐式类型转换实现匹配的候选函数。为此,假定unknown字面量可以转换为任何类型。如果只剩一个候选函数,就使用它;否则继续下一步。 -如果任何输入参数是域类型,则在后续所有步骤中都把它当作该域的基类型。这样可以确保在解决函数歧义时,域的行为与其基类型一致。 +如果任何输入参数是域类型,则在后续所有步骤中都把它当作该域的基础类型。这样可以确保在解决函数歧义时,域的行为与其基础类型一致。 @@ -477,12 +476,12 @@ SELECT * FROM mytable WHERE val = text 'foo'; -遍历所有候选函数,保留那些在需要类型转换的最多位置上接受首选类型(属于输入数据类型的类型分类)的候选项。如果没有候选项接受首选类型,则保留全部候选项。如果只剩一个候选函数,就使用它;否则继续下一步。 +遍历所有候选函数,在需要类型转换的位置上,保留接受首选类型(属于输入数据类型的类型分类)的位置数最多的候选项。如果没有候选项接受首选类型,则保留全部候选项。如果只剩一个候选函数,就使用它;否则继续下一步。 -如果有任何输入参数是unknown,就检查剩余候选项在这些参数位置上接受哪些类型分类。在每个位置上,如果有任何候选项接受string分类,就选择该分类。(这种偏向字符串的做法是合适的,因为unknown类型的文字看起来像字符串。)否则,如果所有剩余候选项都接受同一种类型分类,就选择该分类;否则失败,因为在缺少更多线索的情况下无法推断出正确选择。然后丢弃不接受所选类型分类的候选项。此外,如果有任何候选项接受该分类中的首选类型,就丢弃在该参数上接受非首选类型的候选项。如果没有候选项通过这些测试,则保留全部候选项。如果只剩一个候选项,就使用它;否则继续下一步。 +如果有任何输入参数是unknown,就检查剩余候选函数在这些参数位置上接受哪些类型分类。在每个位置上,如果有任何候选项接受string分类,就选择该分类。(这种偏向字符串的做法是合适的,因为unknown类型的字面量看起来像字符串。)否则,如果所有剩余候选项都接受同一种类型分类,就选择该分类;否则失败,因为在缺少更多线索的情况下无法推断出正确选择。然后丢弃不接受所选类型分类的候选项。此外,如果有任何候选项接受该分类中的首选类型,就丢弃在该参数上接受非首选类型的候选项。如果没有候选项通过这些测试,则保留全部候选项。如果只剩一个候选函数,就使用它;否则继续下一步。 @@ -539,7 +538,7 @@ CREATE FUNCTION public.variadic_example(VARIADIC numeric[]) RETURNS int CREATE FUNCTION -此函数接受 VARIADIC 关键字,但不要求使用它。它可以接受 integer 和 numeric 参数: +这个函数接受但不要求使用VARIADIC关键字。它既能接受integer参数,也能接受numeric参数: SELECT public.variadic_example(0), @@ -551,7 +550,7 @@ SELECT public.variadic_example(0), (1 row) -不过,如果有更具体的函数,前两个调用会优先选择它们: +但是,如果有更具体的函数可用,第一和第二个调用会优先选择它们: CREATE FUNCTION public.variadic_example(numeric) RETURNS int @@ -571,7 +570,7 @@ SELECT public.variadic_example(0), (1 row) -在默认配置下,如果只存在第一个函数,前两个调用是不安全的。任何用户都可以通过创建第二个或第三个函数来截获它们。由于精确匹配参数类型并使用了 VARIADIC 关键字,第三个调用是安全的。 +在默认配置下,且只存在第一个函数时,第一和第二个调用并不安全。任何用户都可以通过创建第二个或第三个函数来劫持它们。第三个调用由于参数类型精确匹配且使用了VARIADIC关键字,因此是安全的。 @@ -659,7 +658,7 @@ SELECT substr(CAST (1234 AS text), 3); -否则,尝试把表达式转换为目标类型。如果这两种类型之间在pg_cast目录中登记了赋值类型转换(见),就可以这样做。另一种情况是,如果表达式是unknown类型文字,则会把文字字符串的内容送入目标类型的输入转换例程。 +否则,尝试把表达式转换为目标类型。如果这两种类型之间在pg_cast目录中登记了赋值类型转换(见),就可以这样做。另一种情况是,如果表达式是unknown类型字面量,则会把字符串字面量的内容送入目标类型的输入转换例程。 @@ -691,7 +690,7 @@ SELECT v, octet_length(v) FROM vv; -这里实际发生的是,两个unknown类型文字默认都被解析为text,从而使||操作符被解析为text的连接操作。然后,操作符得到的text结果被转换为bpcharblank-padded char,即character数据类型的内部名称),以匹配目标列类型。(由于从textbpchar的转换是二进制可强制转换的,这一步不会插入任何真实的函数调用。)最后,系统目录中找到尺寸调整函数bpchar(bpchar, integer, boolean),并把它应用到操作符结果以及存储列长度上。这个特定于类型的函数会执行所需的长度检查并补齐填充空格。 +这里实际发生的是,两个unknown类型字面量默认都被解析为text,从而使||操作符被解析为text的连接操作。然后,操作符得到的text结果被转换为bpchar用空格填充的字符,blank-padded char,即character数据类型的内部名称),以匹配目标列类型。(由于从textbpchar的转换是二进制可强制转换的,这一步不会插入任何真实的函数调用。)最后,系统从系统目录中找到尺寸调整函数bpchar(bpchar, integer, boolean),并把它应用到操作符结果以及存储列长度上。这个特定于类型的函数会执行所需的长度检查并补齐填充空格。 @@ -746,10 +745,10 @@ SQL 的UNION结构必须让可能不同的类型彼此匹配 -如果任何输入是域类型,则在后续所有步骤中都把它当作该域的基类型。 +如果任何输入是域类型,则在后续所有步骤中都把它当作该域的基础类型。 - 这在某种程度上类似于操作符和函数对域输入的处理方式;只要用户确保所有输入都隐式或显式地正好属于该域类型,这种行为就能让域类型在UNION或类似结构中得以保留。否则,就会使用该域的基类型。 + 这在某种程度上类似于操作符和函数对域输入的处理方式;只要用户确保所有输入都隐式或显式地正好属于该域类型,这种行为就能让域类型在UNION或类似结构中得以保留。否则,就会使用该域的基础类型。 @@ -764,13 +763,13 @@ SQL 的UNION结构必须让可能不同的类型彼此匹配 -如果非unknown输入并非全都属于同一类型分类,则失败。 +如果非unknown输入并非全都属于同一类型分类,则失败。 -选择第一个非unknown输入的类型作为候选类型,然后按从左到右的顺序考虑其余每个非unknown输入类型。 +选择第一个非unknown输入的类型作为候选类型,然后按从左到右的顺序考虑其余每个非unknown输入类型。 出于历史原因,CASE会把其ELSE子句(如果有)视为第一个输入,THEN子句则在其后考虑。其他所有情况中,从左到右都指表达式在查询文本中出现的顺序。 @@ -793,7 +792,7 @@ SQL 的UNION结构必须让可能不同的类型彼此匹配 -UNION 中未充分指定类型时的类型解析 +<literal>UNION</literal> 中未充分指定类型时的类型解析 @@ -805,12 +804,12 @@ SELECT text 'a' AS "text" UNION SELECT 'b'; b (2 rows) -这里,unknown 类型文字 'b' 将被解析为类型 text。 +这里,unknown类型字面量'b'会被解析为text类型。 -简单 UNION 中的类型解析 +简单 <literal>UNION</literal> 中的类型解析 @@ -822,12 +821,12 @@ SELECT 1.2 AS "numeric" UNION SELECT 1; 1.2 (2 rows) -文字常量1.2的类型是numeric,而integer1可以隐式转换为numeric,因此使用该类型。 +字面量1.2的类型是numeric,而integer1可以隐式转换为numeric,因此使用该类型。 -次序对调的 UNION 中的类型解析 +次序对调的 <literal>UNION</literal> 中的类型解析 @@ -839,12 +838,12 @@ SELECT 1 AS "real" UNION SELECT CAST('2.2' AS REAL); 2.2 (2 rows) -这里,由于类型 real 不能隐式转换为 integer,但 integer 可以隐式转换为 real,因此合并结果类型被解析为 real。 +这里,由于real类型不能隐式转换为integer,而integer可以隐式转换为real,因此UNION结果类型被解析为real -嵌套 UNION 中的类型解析 +嵌套 <literal>UNION</literal> 中的类型解析 @@ -874,17 +873,17 @@ ERROR: UNION types text and integer cannot be matched -前面各节给出的规则会为 SQL 查询中的所有表达式赋予非 unknown 数据类型,但作为 SELECT 命令的简单输出列出现的未指定类型文字除外。例如,在 +前面各节给出的规则会为 SQL 查询中的所有表达式赋予非 unknown 数据类型,但作为 SELECT 命令的简单输出列出现的未指定类型字面量除外。例如,在 SELECT 'Hello World'; -中,没有任何信息可用于确定应将该字符串文字视为什么类型。在这种情况下,PostgreSQL 会回退为将该文字的类型解析为 text。 +中,没有任何信息可用于确定应将该字符串字面量视为什么类型。在这种情况下,PostgreSQL 会回退为将该字面量的类型解析为 text -当SELECTUNION(或INTERSECTEXCEPT)结构的一端,或者出现在INSERT ... SELECT中时,这条规则不适用,因为前面各节给出的规则具有更高优先级。在前一种情况下,未指定类型文字的类型可以从UNION的另一侧取得;在后一种情况下,则从目标列取得。 +当SELECTUNION(或INTERSECTEXCEPT)结构的一端,或者出现在INSERT ... SELECT中时,这条规则不适用,因为前面各节给出的规则具有更高优先级。在前一种情况下,未指定类型字面量的类型可以从UNION的另一侧取得;在后一种情况下,则从目标列取得。 @@ -894,7 +893,7 @@ SELECT 'Hello World'; - 在PostgreSQL 10 之前,这条规则并不存在,SELECT输出列表中的未指定类型文字会被保留为unknown类型。这会带来各种不良后果,因此后来做了修改。 + 在PostgreSQL 10 之前,这条规则并不存在,SELECT输出列表中的未指定类型字面量会被保留为unknown类型。这会带来各种不良后果,因此后来做了修改。 diff --git a/zh/12/user-manag.sgml b/zh/12/user-manag.sgml index 42abc036..e430f14b 100644 --- a/zh/12/user-manag.sgml +++ b/zh/12/user-manag.sgml @@ -71,7 +71,7 @@ SELECT rolname FROM pg_roles; - 为了完成数据库系统的初始引导,一个刚初始化的系统总会包含一个预定义的可登录角色。该角色总是一个超级用户,并且除非另行指定了不同名称,否则它的名称与用initdb初始化数据库集簇的操作系统用户相同。这个角色通常命名为postgres。要创建更多角色,必须先以这个初始角色建立连接。 + 为了完成数据库系统的初始引导,一个刚初始化的系统总会包含一个预定义角色。该角色总是一个超级用户,并且除非另行指定了不同名称,否则它的名称与用initdb初始化数据库集簇的操作系统用户相同。这个角色通常命名为postgres。要创建更多角色,必须先以这个初始角色建立连接。 @@ -94,12 +94,12 @@ SELECT rolname FROM pg_roles; 登录权限登录权限 - 只有具有 LOGIN 属性的角色才能用作数据库连接的初始角色名。具有 LOGIN 属性的角色可以视为数据库用户。要创建具有登录权限的角色,可以使用以下任一命令: + 只有具有LOGIN属性的角色才能用作数据库连接的初始角色名。具有LOGIN属性的角色可以被视为数据库用户。要创建具有登录权限的角色,可使用以下任一方式: CREATE ROLE name LOGIN; CREATE USER name; - (CREATE USER 等价于 CREATE ROLE,区别在于 CREATE USER 包含 LOGIN,而 CREATE ROLE 不会如此。) + (CREATE USER等价于CREATE ROLE,不同之处只在于CREATE USER默认包含LOGIN,而CREATE ROLE不包含。) @@ -196,13 +196,12 @@ CREATE USER name; - 角色还可以为 中描述的许多运行时配置设置指定角色专属的默认值。例如,如果出于某种原因,你希望每次连接时都禁用索引扫描(提示:这不是一个好主意),可以使用: + 角色还可以为中描述的许多运行时配置设置指定角色特定默认值。例如,如果出于某种原因你希望每次连接时都禁用索引扫描(提示:这不是个好主意),你可以使用: ALTER ROLE myname SET enable_indexscan TO off; - 这会保存该设置(但不会立即设置它)。此角色后续建立的连接就好像在会话开始前刚执行过 SET enable_indexscan TO off 一样。在会话期间仍然可以更改这一设置;它只是默认值。要移除角色专属的默认设置,请使用 - ALTER ROLE rolename RESET varname。请注意,附加在没有 LOGIN 权限的角色上的角色专属默认值几乎没有用处,因为它们永远不会被调用。 + 这会保存该设置(但不会立即生效)。在该角色后续建立的连接中,它看起来就像在会话开始之前执行了SET enable_indexscan TO off一样。你仍然可以在会话期间更改该设置;它只会作为默认值。要移除角色特定默认设置,使用ALTER ROLE rolename RESET varname。注意,附加到没有LOGIN权限的角色上的角色特定默认值几乎没有用,因为它们永远不会生效。 @@ -309,12 +308,12 @@ ALTER TABLE bobs_table OWNER TO alice; - 一旦有价值的对象都已转移给新拥有者,被删除角色所拥有的其余对象即可使用命令删除。同样,由于该命令不能访问其他数据库中的对象,因此必须在包含该角色所拥有对象的每个数据库中运行它。另外,DROP + 一旦有价值的对象都已转移给新拥有者,待删除角色所拥有的其余对象即可使用命令删除。同样,由于该命令不能访问其他数据库中的对象,因此必须在包含该角色所拥有对象的每个数据库中运行它。另外,DROP OWNED不会删除整个数据库或表空间,因此如果该角色拥有任何尚未转移给新拥有者的数据库或表空间,就必须手工删除它们。 - DROP OWNED还会负责移除授予目标角色、但不属于它自身对象的任何权限。由于REASSIGN OWNED不会处理这类对象,所以通常需要同时运行REASSIGN OWNEDDROP OWNED(按这个顺序!),才能完整移除待删除角色的依赖关系。 + DROP OWNED还会负责移除目标角色在其他角色所拥有的对象上获授的所有权限。由于REASSIGN OWNED不会处理这类对象,所以通常需要同时运行REASSIGN OWNEDDROP OWNED(按这个顺序!),才能完整移除待删除角色的依赖关系。 @@ -367,7 +366,7 @@ DROP ROLE doomed_role; pg_read_all_stats - 读取所有 pg_stat_* 视图,并使用各种与统计信息相关的扩展,即使是那些通常仅对超级用户可见的扩展。 + 读取所有 pg_stat_* 视图,并使用各种与统计信息相关的扩展,包括通常仅对超级用户可见的内容。 pg_stat_scan_tables @@ -406,11 +405,11 @@ DROP ROLE doomed_role; - pg_read_server_filespg_write_server_filespg_execute_server_program角色旨在让管理员能够创建受信任但非超级用户的角色,使其能够以数据库运行所用用户的身份访问文件并在数据库服务器上运行程序。由于这些角色能够访问服务器文件系统上的任意文件,它们在直接访问文件时会绕过所有数据库级权限检查,并且可被用来获得超级用户级别的访问能力,因此向用户授予这些角色时必须极其谨慎。 + pg_read_server_filespg_write_server_filespg_execute_server_program角色旨在让管理员能够使受信任但非超级用户的角色能够以数据库运行所用用户的身份访问文件并在数据库服务器上运行程序。由于这些角色能够访问服务器文件系统上的任意文件,它们在直接访问文件时会绕过所有数据库级权限检查,并且可被用来获得超级用户级别的访问能力,因此向用户授予这些角色时必须极其谨慎。 - 授予这些角色时应当谨慎,确保它们只在需要时使用,并理解这些角色会授予对特权信息的访问。 + 授予这些角色时应当谨慎,确保它们只在需要时使用,并理解这些角色会授予对需要特权才能访问的信息的访问。 @@ -427,7 +426,7 @@ GRANT pg_signal_backend TO admin_user; 函数安全性 - 函数、触发器和行级安全策略允许用户把代码插入后端服务器,而其他用户可能会无意中执行这些代码。因此,这些机制使用户能够相对容易地对其他用户实施特洛伊木马攻击。最强的保护方式是严格控制谁能定义对象。如果这不可行,则应编写只引用拥有者可信对象的查询,并从search_path中移除任何允许不受信任用户创建对象的模式。 + 函数、触发器和行级安全策略允许用户把代码插入后端服务器,而其他用户可能会无意中执行这些代码。因此,这些机制使用户能够相对容易地对其他用户实施特洛伊木马攻击。最强的保护方式是严格控制谁能定义对象。如果这不可行,则应编写只引用拥有者可信的对象的查询,并从search_path中移除 public 模式以及任何其他允许不受信任用户创建对象的模式。 diff --git a/zh/12/vacuumlo.sgml b/zh/12/vacuumlo.sgml index 70a7b1c0..d2deeeed 100644 --- a/zh/12/vacuumlo.sgml +++ b/zh/12/vacuumlo.sgml @@ -8,7 +8,7 @@ vacuumlo 1 - Application + 应用程序 diff --git a/zh/12/wal.sgml b/zh/12/wal.sgml index 4395daad..56732863 100644 --- a/zh/12/wal.sgml +++ b/zh/12/wal.sgml @@ -349,9 +349,9 @@ 检查点检查点 是事务序列中的一些点,在这些点上可以保证堆和索引数据文件已经用检查点之前写入 - 的全部信息进行了更新。执行检查点时,所有脏数据页都会刷写到磁盘,并向 WAL - 文件写入一条特殊的检查点记录。(更改记录此前已经刷入 WAL - 文件。)如果发生崩溃,崩溃恢复过程会查看最新的检查点记录,以确定应该从 WAL + 的全部信息进行了更新。执行检查点时,所有脏数据页都会刷盘,并向 WAL + 文件写入一条特殊的检查点记录。(更改记录此前已写入 WAL + 文件并刷盘。)如果发生崩溃,崩溃恢复过程会查看最新的检查点记录,以确定应该从 WAL 的哪个位置(称为重做记录)开始执行 REDO。该点之前对数据文件所做的任何更改 都保证已经在磁盘上。因此,检查点之后,位于包含重做记录的段之前的 WAL 段不再需要, 可以被回收或删除。(若正在执行 WAL 归档,则这些 WAL 段必 @@ -379,7 +379,7 @@ 减小 checkpoint_timeout 和/或 max_wal_size 会让检查点更频繁地发生。这样可以加快崩溃后 - 恢复,因为需要重做的工作更少。不过,这必须与更频繁刷写脏数据页所增加的成本 + 恢复,因为需要重做的工作更少。不过,这必须与更频繁地将脏数据页刷盘所增加的成本 权衡。如果设置了 (默认就是如此), 还要考虑另一个因素。为了保证数据页一致性,每个检查点之后对某个数据页的首次 修改,都会导致把整页内容写入日志。在这种情况下,更短的检查点间隔会增加输出到 @@ -417,7 +417,7 @@ 在 Linux 和 POSIX 平台上, - 允许在检查点写出的操作系统页面达到可配置的字节数后,强制把它们刷到磁盘。 + 允许在检查点写出的操作系统页面达到可配置的字节数后,强制将它们刷盘。 否则,这些页面可能会停留在操作系统页缓存中,从而在检查点末尾发出 fsync 时引发停顿。这个设置通常有助于降低事务延迟,但也可能 对性能产生不利影响,尤其是在工作负载大于 @@ -453,7 +453,7 @@ 在归档恢复或备库模式下,服务器会周期性地执行 重启点重启点, - 其行为类似于正常运行时的检查点:服务器会强制把自身状态写盘,更新 + 其行为类似于正常运行时的检查点:服务器会强制将其所有状态刷盘,更新 pg_control 文件,以表明已经处理过的 WAL 数据无需再次 扫描,然后回收 pg_wal 目录中的旧 WAL 段文件。重启点的 执行频率不会高于主库上的检查点,因为重启点只能在检查点记录处执行。当到达某条检查点记录且距离上次重启点 @@ -476,7 +476,7 @@ 快。更糟的是,写 WAL 缓冲区还可能迫使系统创建新的 WAL 段, 这会花费更多时间。正常情况下,WAL 缓冲区应由 XLogFlush 请求负责写出并刷盘; - 该请求大多发生在事务提交时,以确保事务记录被刷入持久存储。在 WAL 输出量很高 + 该请求大多发生在事务提交时,以确保事务记录已刷盘至持久存储。在 WAL 输出量很高 的系统上,XLogFlush 请求可能不够频繁,无法避免 XLogInsertRecord 自己去执行写出。在这种系统上,应增加 WAL 缓冲区的数量,具体做法是修改参数 @@ -532,9 +532,9 @@ 参数 决定 PostgreSQL 将如何请求内核把 - WAL 更新强制刷到磁盘。就可靠性而言,所有选项应当都是相同 + WAL 更新强制刷盘。就可靠性而言,所有选项应当都是相同 的;例外是 fsync_writethrough,它有时能够在其他选项做不 - 到时强制刷新磁盘缓存。不过,具体哪个选项速度最快则高度依赖平台。可以使用 + 到时强制将磁盘缓存中的数据刷盘。不过,具体哪个选项速度最快则高度依赖平台。可以使用 程序测试不同选项的速度。请注意,如果 fsync 已被关闭,那么这个参数就没有意义。 diff --git a/zh/12/xaggr.sgml b/zh/12/xaggr.sgml index 8d6eb399..b2293d67 100644 --- a/zh/12/xaggr.sgml +++ b/zh/12/xaggr.sgml @@ -42,11 +42,11 @@ SELECT sum(a) FROM test_complex; - 如果没有非空输入值,上述sum定义将返回零(即初始状态值)。也许我们更希望在这种情况下返回空值 — SQL 标准要求sum这样做。实现这一点只需省略initcond短语,使初始状态值为空。通常这意味着sfunc需要检查输入的状态值是否为空。但对于sum以及maxmin这类其他简单聚合,只需把第一个非空输入值放入状态变量,然后从第二个非空输入值开始应用转移函数即可。如果初始状态值为空,并且转移函数被标记为strict(即不会对空输入调用),PostgreSQL会自动这样做。 + 如果没有非空输入值,上述sum定义将返回零(即初始状态值)。也许我们更希望在这种情况下返回空值 — SQL 标准要求sum这样做。实现这一点只需省略initcond短语,使初始状态值为空值。通常这意味着sfunc需要检查输入的状态值是否为空值。但对于sum以及maxmin这类其他简单聚合,只需把第一个非空输入值放入状态变量,然后从第二个非空输入值开始应用转移函数即可。如果初始状态值为空值,并且转移函数被标记为strict(即不会对空值输入调用),PostgreSQL会自动这样做。 - strict转移函数的另一项默认行为是,只要遇到空输入值,就会保留先前的状态值不变。因此,空值会被忽略。如果你需要对空输入采用其他行为,就不要把转移函数声明为 strict,而应在函数代码中自行检测空输入并完成所需处理。 + strict转移函数的另一项默认行为是,只要遇到空值输入,就会保留先前的状态值不变。因此,空值会被忽略。如果你需要对空值输入采用其他行为,就不要把转移函数声明为 strict,而应在函数代码中自行检测空值输入并完成所需处理。 @@ -71,7 +71,7 @@ CREATE AGGREGATE avg (float8)
- SQL 中的聚合函数调用允许使用DISTINCTORDER BY选项,以控制哪些行会传递给聚合的转移函数,以及传递顺序。这些选项是在后台实现的,并不是聚合支持函数需要关心的事情。 + SQL 中的聚合函数调用允许使用DISTINCTORDER BY选项,以控制哪些行会传递给聚合的转移函数,以及传递顺序。这些选项由系统在内部实现,并不是聚合支持函数需要关心的事情。 @@ -283,7 +283,7 @@ SELECT percentile_disc(0.5) WITHIN GROUP (ORDER BY income) FROM households; - 与普通聚合不同,有序集聚合的输入行排序不是在幕后完成的,而是由聚合的支持函数负责。典型的实现方法是在聚合的状态值中保存一个tuplesort对象的引用,把输入行送入该对象,然后在最终函数中完成排序并读出数据。这样的设计使最终函数可以执行特殊操作,例如向待排序数据中注入额外的假想行。普通聚合通常可以使用由PL/pgSQL或其他 PL 语言编写的支持函数来实现,但有序集聚合通常必须用 C 编写,因为它们的状态值无法定义为任何 SQL 数据类型。(在上面的示例中,注意状态值被声明为internal类型,这很典型。)另外,由于最终函数执行了排序,之后就不可能再通过再次执行转移函数来继续加入输入行。这意味着最终函数不是READ_ONLY;在中,必须将其声明为READ_WRITE,或者如果额外的最终函数调用能够利用已经排好序的状态,则声明为SHAREABLE。 + 与普通聚合不同,有序集聚合的输入行排序不是由系统在内部完成的,而是由聚合的支持函数负责。典型的实现方法是在聚合的状态值中保存一个tuplesort对象的引用,把输入行送入该对象,然后在最终函数中完成排序并读出数据。这样的设计使最终函数可以执行特殊操作,例如向待排序数据中注入额外的假想行。普通聚合通常可以使用由PL/pgSQL或其他 PL 语言编写的支持函数来实现,但有序集聚合通常必须用 C 编写,因为它们的状态值无法定义为任何 SQL 数据类型。(在上面的示例中,注意状态值被声明为internal类型,这很典型。)另外,由于最终函数执行了排序,之后就不可能再通过再次执行转移函数来继续加入输入行。这意味着最终函数不是READ_ONLY;在中,必须将其声明为READ_WRITE,或者如果额外的最终函数调用能够利用已经排好序的状态,则声明为SHAREABLE @@ -347,12 +347,16 @@ SELECT percentile_disc(0.5) WITHIN GROUP (ORDER BY income) FROM households; 支持函数 - 用 C 编写的函数可以通过调用AggCheckCallContext来检测自己是否作为聚合支持函数被调用,例如: + + 用 C 编写的函数可以通过调用AggCheckCallContext来检测自己是否作为聚合支持函数被调用,例如: + if (AggCheckCallContext(fcinfo, NULL)) -进行这种检查的一个原因是:如果结果为真,第一个输入必然是一个临时状态值,因此可以安全地原地修改,而不必分配新的副本。示例可见 int8inc()。(虽然聚合状态转移函数总是允许原地修改状态值,但通常不鼓励聚合最终函数这样做;如果它确实这样做,则必须在创建聚合时声明这种行为。更多细节见 。) + + 进行这种检查的一个原因是:如果结果为真,第一个输入必然是一个临时状态值,因此可以安全地原地修改,而不必分配新的副本。示例可见int8inc()。(虽然聚合转移函数总是允许原地修改状态值,但通常不鼓励聚合最终函数这样做;如果它确实这样做,则必须在创建聚合时声明这种行为。更多细节见。) + - AggCheckCallContext的第二个参数可用于取得保存聚合状态值的内存上下文。这对于希望把扩展对象(见)用作状态值的转移函数很有用。第一次调用时,转移函数应返回一个扩展对象,其内存上下文是聚合状态上下文的子上下文;之后的调用则持续返回同一个扩展对象。示例见array_append()。(array_append()并不是任何内置聚合的转移函数,但它的写法保证了在用作自定义聚合的转移函数时也能高效工作。) + AggCheckCallContext的第二个参数可用于取得保存聚合状态值的内存上下文。这对于希望把展开对象(见)用作状态值的转移函数很有用。第一次调用时,转移函数应返回一个展开对象,其内存上下文是聚合状态上下文的子上下文;之后的调用则持续返回同一个展开对象。示例见array_append()。(array_append()并不是任何内置聚合的转移函数,但它的写法保证了在用作自定义聚合的转移函数时也能高效工作。) diff --git a/zh/12/xfunc.sgml b/zh/12/xfunc.sgml index 976dda5e..0abbb6e3 100644 --- a/zh/12/xfunc.sgml +++ b/zh/12/xfunc.sgml @@ -4,8 +4,8 @@ 用户定义的函数 - function - user-defined + 函数 + 用户定义的 @@ -36,11 +36,11 @@ - 每一类函数可以采用基本类型、复合类型或者它们的组合作为参数。此外,每一类函数可以返回一个基本类型或一个复合类型。函数也能被定义成返回基本类型或复合类型值的集合。 + 每一类函数可以采用基础类型、复合类型或者它们的组合作为参数。此外,每一类函数可以返回一个基础类型或一个复合类型。函数也能被定义成返回基础类型或复合类型值的集合。 - 很多类函数可以接受或者返回特定的伪类型(例如,多态类型),但是可用的功能会变化。详情可以参考每一种函数的描述。 + 很多类函数可以接受或者返回特定的伪类型(例如,多态类型),但是可用的功能因函数类别而异。详情可以参考每一种函数的描述。 定义SQL函数最容易,因此我们将从讨论它们开始。大部分SQL函数的概念也能用到其他类型的函数上。 @@ -55,8 +55,8 @@ 用户定义的过程 - procedure - user-defined + 过程 + 用户定义的 过程是一个类似于函数的数据库对象。关键差异是: @@ -95,7 +95,7 @@ - 函数和过程一起构成了例程routine。 + 函数和过程统称为例程例程。 有这样的命令可以操作函数和过程而不需要知道它们是哪一种。 不过,要注意没有CREATE ROUTINE命令。 @@ -107,7 +107,7 @@ 函数 用户定义的 - in SQL + 在 SQL 中 @@ -121,7 +121,7 @@ SQL 函数的函数体必须是一个由分号分隔的 SQL 语句列表。最后一条语句后的分号是可选的。除非该函数被声明为返回 void,否则最后一条语句必须是 SELECT,或者是 INSERTUPDATEDELETE 并带有 RETURNING 子句。 任意一组 SQL 语言命令都可以打包并定义成函数。除 SELECT 查询外,这些命令还可以包含数据修改查询(INSERT, - UPDATEDELETE),以及其他 SQL 命令。(不能使用事务控制命令,例如 COMMITSAVEPOINT,以及某些实用命令,例如 VACUUM,来编写 SQL 函数。)不过,最后一条命令必须是 SELECT,或者带有 RETURNING 子句,并返回与函数声明返回类型相符的结果。或者,如果你想定义一个执行动作但没有有用返回值的 SQL 函数,也可以把它定义为返回 void。例如,下面这个函数会删除 emp 表中薪资为负的行: + UPDATEDELETE),以及其他 SQL 命令。(不能使用事务控制命令,例如 COMMITSAVEPOINT,以及某些工具命令,例如 VACUUM,来编写 SQL 函数。)不过,最后一条命令必须是 SELECT,或者带有 RETURNING 子句,并返回与函数声明返回类型相符的结果。或者,如果你想定义一个执行动作但没有有用返回值的 SQL 函数,也可以把它定义为返回 void。例如,下面这个函数会删除 emp 表中薪资为负的行: CREATE FUNCTION clean_emp() RETURNS void AS ' DELETE FROM emp WHERE salary < 0; @@ -190,10 +190,10 @@ INSERT INTO $1 VALUES (42); - 基本类型上的<acronym>SQL</acronym>函数 + 基础类型上的<acronym>SQL</acronym>函数 - 最简单的 SQL 函数没有参数,只是返回一个基本类型,例如 + 最简单的 SQL 函数没有参数,只是返回一个基础类型,例如 integer @@ -219,7 +219,7 @@ SELECT one(); - 定义接受基本类型参数的 SQL 函数也几乎同样容易: + 定义接受基础类型参数的 SQL 函数也几乎同样容易: CREATE FUNCTION add_em(x integer, y integer) RETURNS integer AS $$ @@ -349,17 +349,17 @@ SELECT name, double_salary(emp.*) AS dream 注意这里用 $1.salary 语法来选取参数行值中的一个字段。 还要注意,调用时的 SELECT 命令使用 - table_name.* 将表的当前整行取作一个组合值。该表行也可以仅用表名来引用: + table_name.* 将表的当前整行取作一个复合值。该表行也可以仅用表名来引用: SELECT name, double_salary(emp) AS dream FROM emp WHERE emp.cubicle ~= point '(2,1)'; - 但这种用法已被废弃,因为它很容易让人混淆(关于表行组合值这两种记法的更多细节,见)。 + 但这种用法已被弃用,因为它很容易让人混淆(关于表行复合值这两种记法的更多细节,见)。 - 有时候即时构造一个组合参数会很方便。这可以用ROW构造器完成。 + 有时候即时构造一个复合参数值会很方便。这可以用ROW构造器完成。 例如,我们可以调整被传递给函数的数据: SELECT name, double_salary(ROW(name, salary*1.1, age, cubicle)) AS dream @@ -382,9 +382,12 @@ $$ LANGUAGE SQL; 在这个示例中,我们为每一个属性指定了一个常量值,但是可以用任何计算来替换这些常量。 - 定义该函数时要注意两件重要的事情: + + 定义该函数时有两点重要注意事项: + + - 查询中的选择列表顺序必须与列在该复合类型所关联的表中出现的顺序完全相同。(正如我们上面所做的那样,命名列与系统无关。) + 查询中的选择列表顺序必须与列在该复合类型所关联的表中出现的顺序完全相同。(系统不考虑像上面这样指定的列名。) 我们必须确保每个表达式的类型与复合类型中对应列的类型相匹配,必要时插入类型转换。否则,就会得到这样的错误: @@ -462,7 +465,7 @@ SELECT name(new_emp()); - 另一种使用函数返回复合类型的方法是将结果传递给另一个接受正确行类型作为输入的函数: + 另一种使用函数返回复合类型的方法是将结果传递给另一个接受正确行类型作为输入的函数: CREATE FUNCTION getname(emp) RETURNS text AS $$ @@ -550,12 +553,12 @@ DROP FUNCTION sum_n_product (int, int); 带有可变数量参数的<acronym>SQL</acronym>函数 - function - variadic + 函数 + 可变参数 - variadic function + 可变参数函数 @@ -586,27 +589,27 @@ SELECT mleast(ARRAY[10, -1, 5, 4.4]); -- doesn't work - 有时候,能够把一个已经构造好的数组传给 variadic 函数会很有用,尤其是当一个 variadic 函数想把它的数组参数再传给另一个函数时。此外,在允许不受信任用户创建对象的模式中调用 variadic 函数时,这是唯一安全的方式,见。你可以在调用中指定VARIADIC来做到这一点: + 有时候,能够把一个已经构造好的数组传给可变参数函数会很有用,尤其是当一个可变参数函数想把它的数组参数再传给另一个函数时。此外,在允许不受信任用户创建对象的模式中调用可变参数函数时,这是唯一安全的方式,见。你可以在调用中指定VARIADIC来做到这一点: SELECT mleast(VARIADIC ARRAY[10, -1, 5, 4.4]); - 这样会阻止函数的 variadic 参数按其元素类型展开,从而让数组实参能够按常规方式匹配。VARIADIC 只能附加在函数调用的最后一个实参上。 + 这样会阻止函数的可变参数按其元素类型展开,从而让数组实参能够按常规方式匹配。VARIADIC 只能附加在函数调用的最后一个实参上。 - 在调用中指定VARIADIC也是向 variadic 函数传递空数组的唯一方式,例如: + 在调用中指定VARIADIC也是向可变参数函数传递空数组的唯一方式,例如: SELECT mleast(VARIADIC ARRAY[]::numeric[]); - 仅仅写成SELECT mleast()是行不通的,因为 variadic 参数必须匹配至少一个实参。(如果你希望允许这种调用,可以再定义一个同名且不带参数的函数mleast。) + 仅仅写成SELECT mleast()是行不通的,因为可变参数必须匹配至少一个实参。(如果你希望允许这种调用,可以再定义一个同名且不带参数的函数mleast。) - 从 variadic 参数派生出的数组元素参数会被视为没有自己的名字。这意味着除非你指定了 VARIADIC,否则不能使用命名参数来调用 variadic 函数()。例如,下面的调用是可行的: + 从可变参数派生出的数组元素参数会被视为没有自己的名字。这意味着除非你指定了 VARIADIC,否则不能使用命名参数来调用可变参数函数()。例如,下面的调用是可行的: SELECT mleast(VARIADIC arr => ARRAY[10, -1, 5, 4.4]); @@ -625,7 +628,7 @@ SELECT mleast(arr => ARRAY[10, -1, 5, 4.4]); 带有参数默认值的<acronym>SQL</acronym>函数 - function + 函数 参数的默认值 @@ -634,7 +637,7 @@ SELECT mleast(arr => ARRAY[10, -1, 5, 4.4]); 没有给出足够多的实参,就会插入默认值来弥补缺失的实参。由于参数只 能从实参列表的尾部开始被省略,在一个有默认值的参数之后的所有参数 都不得不也具有默认值(尽管使用命名参数记法可以允许放松这种限制, - 这种限制仍然会被强制以便位置参数记法能工作)。不管你是否使用它,这种能力都要求在某些用户不信任其他用户的数据中调用函数时做一些预防措施,见。 + 这种限制仍然会被强制以便位置参数记法能工作)。不管你是否使用它,这种能力都要求在某些用户不信任其他用户的数据库中调用函数时做一些预防措施,见 @@ -677,13 +680,13 @@ ERROR: function foo() does not exist 所有的 SQL 函数都可以被用在查询的FROM子句中,但是 - 对于返回复合类型的函数特别有用。如果函数被定义为返回一种基本类型, + 对于返回复合类型的函数特别有用。如果函数被定义为返回一种基础类型, 该表函数会产生一个单列表。如果该函数被定义为返回一种复合类型,该 表函数会为该复合类型的每一个属性产生一列。 - 以下是一个示例: + 以下是一个示例: CREATE TABLE foo (fooid int, foosubid int, fooname text); @@ -716,8 +719,8 @@ SELECT *, upper(fooname) FROM getfoo(1) AS t1; 返回集合的<acronym>SQL</acronym>函数 - function - with SETOF + 函数 + 使用 SETOF @@ -842,11 +845,16 @@ SELECT name, listchildren(name) FROM nodes; - PostgreSQL对查询选择列表中的集合返回函数的处理方式,几乎与将该函数写在 LATERAL FROM 子句项中时完全相同。例如, + PostgreSQL中,写在查询的选择列表中的集合返回函数的行为几乎和写在LATERAL FROM子句项中的集合返回函数完全一样。例如: + SELECT x, generate_series(1,5) AS g FROM tab; -几乎等价于 + + 几乎等效于 + SELECT x, g FROM tab, LATERAL generate_series(1,5) AS g; -两者本应完全相同,但在这个特定示例中,规划器可以选择将 g 放在嵌套循环连接的外侧,因为 g 实际上并不横向依赖于 tab。这会导致不同的输出行顺序。选择列表中的集合返回函数总是按位于嵌套循环连接内侧的方式求值,与之连接的是其余的 FROM 子句其余部分的嵌套循环连接的内侧,因此在考虑 FROM 子句的下一行之前,这些函数都会运行到完成。 + + 这会是完全一样的,除了在这个特别的示例中,规划器可以选择把g放在嵌套循环连接的外侧,因为gtab没有实际的横向依赖。那会导致一种不同的输出行顺序。选择列表中的集合返回函数总是会被计算,就好像它们在FROM子句剩余部分的嵌套循环连接的内侧一样,因此在考虑来自FROM子句的下一行之前,这些函数会运行到完成。 + 如果在查询的选择列表中有不止一个集合返回函数,则行为类似于把那些函数放到一个单一的LATERAL ROWS FROM( ... ) FROM子句项中的行为。对于来自底层查询的每一行,都有一个用到每个函数首个结果的输出行,然后是一个使用每个函数第二个结果的输出行,以此类推。如果某些集合返回函数产生的输出比其他函数少,会用空值代替缺失的数据,因此为一个底层行形成的总行数等于产生最多输出的集合返回函数的输出行数。因此集合返回函数会步调一致地运行直到它们的输出被耗尽,然后用下一个底层行继续执行。 @@ -865,7 +873,7 @@ SELECT srf1(srf2(x), srf3(y)), srf4(srf5(z)) FROM tab; SELECT x, CASE WHEN x > 0 THEN generate_series(1, 5) ELSE 0 END FROM tab; - 看起来这个语句应该产生满足x > 0的输入行的五次重复,以及不满足的行的一次重复。但实际上,由于在CASE表达时被计算前,generate_series(1, 5)会被运行在一个隐式的LATERAL FROM项中,它会为每个输入行产生五次重复。为了减少混乱,这类情况会产生一个解析时错误。 + 看起来这个语句应该产生满足x > 0的输入行的五次重复,以及不满足的行的一次重复。但实际上,由于在CASE表达式被计算前,generate_series(1, 5)会被运行在一个隐式的LATERAL FROM项中,它会为每个输入行产生五次重复。为了减少混乱,这类情况会产生一个解析时错误。 @@ -877,11 +885,11 @@ SELECT x, CASE WHEN x > 0 THEN generate_series(1, 5) ELSE 0 END FROM tab; 在 PostgreSQL 10 之前,除非多个集合返回函数始终产生相同数量的行,否则把它们放在同一个选择列表中的行为并不合理。 否则,得到的输出行数会是这些集合返回函数各自产生行数的最小公倍数。 此外,嵌套的集合返回函数也不像上文所描述的那样工作;相反,一个集合返回函数至多只能有一个集合返回参数, - 并且每一层嵌套都会独立运行。再加上过去还允许条件执行(即在 CASE 等结构内部使用集合返回函数), + 并且每一组嵌套的集合返回函数都会独立运行。再加上过去还允许条件执行(即在 CASE 等结构内部使用集合返回函数), 事情就更加复杂了。 如果你要编写需要在旧版 PostgreSQL 上运行的查询,建议使用 LATERAL 语法, 因为这样在不同版本之间能够得到一致的结果。 - 如果你的查询依赖于集合返回函数的条件执行,可以把条件判断移动到自定义集合返回函数内部来修复。例如, + 如果你的查询依赖于集合返回函数的条件执行,或许可以把条件判断移动到自定义集合返回函数内部来修复。例如, SELECT x, CASE WHEN y > 0 THEN generate_series(1, z) ELSE 5 END FROM tab; @@ -899,7 +907,7 @@ END$$ LANGUAGE plpgsql; SELECT x, case_generate_series(y > 0, 1, z, 5) FROM tab; - 这种写法在所有版本的 PostgreSQL 中都能正常工作。 + 这种写法在所有版本的 PostgreSQL 中的行为都相同。 @@ -908,7 +916,7 @@ SELECT x, case_generate_series(y > 0, 1, z, 5) FROM tab; 返回<literal>TABLE</literal>的<acronym>SQL</acronym>函数 - function + 函数 RETURNS TABLE @@ -997,7 +1005,7 @@ SELECT * FROM dup(22); - 多态也可以用于 variadic 函数。例如: + 多态也可以用于可变参数函数。例如: CREATE FUNCTION anyleast (VARIADIC anyarray) RETURNS anyelement AS $$ SELECT min($1[i]) FROM generate_subscripts($1, 1) g(i); @@ -1032,11 +1040,11 @@ SELECT concat_values('|', 1, 4, 2); 带有排序规则的<acronym>SQL</acronym>函数 - collation - in SQL functions + 排序规则 + 在 SQL 函数中 - 当一个 SQL 函数有一个或多个可设定排序规则的数据类型参数时,会根据实参所带的排序规则,为每次函数调用确定一个排序规则,详见 。如果能够成功确定(也就是说,参数之间不存在隐式排序规则冲突),那么所有可设定排序规则的参数都会被视为隐式带有该排序规则。这会影响函数中对排序规则敏感的操作的行为。例如,使用上文的 anyleast 函数时, + 当一个 SQL 函数有一个或多个支持排序规则的数据类型参数时,会根据实参所带的排序规则,为每次函数调用确定一个排序规则,详见 。如果能够成功确定(也就是说,参数之间不存在隐式排序规则冲突),那么所有支持排序规则的参数都会被视为隐式带有该排序规则。这会影响函数中对排序规则敏感的操作的行为。例如,使用上文的 anyleast 函数时, SELECT anyleast('abc'::text, 'ABC'); 的结果将取决于数据库的默认排序规则。在 C 区域设置下,结果会是 ABC,但在许多其他区域设置下则会是 abc。可以在任意参数上添加 COLLATE 子句来强制指定要使用的排序规则,例如: SELECT anyleast('abc'::text, 'ABC' COLLATE "C"); @@ -1044,7 +1052,7 @@ SELECT anyleast('abc'::text, 'ABC' COLLATE "C"); CREATE FUNCTION anyleast (VARIADIC anyarray) RETURNS anyelement AS $$ SELECT min($1[i] COLLATE "en_US") FROM generate_subscripts($1, 1) g(i); $$ LANGUAGE SQL; -但请注意,如果把它用于不可设定排序规则的数据类型,就会抛出错误。 +但请注意,如果把它用于不支持排序规则的数据类型,就会抛出错误。 如果无法在实参之间确定共同的排序规则,那么 SQL 函数会把参数视为带有其数据类型的默认排序规则 @@ -1052,7 +1060,7 @@ $$ LANGUAGE SQL; - 这种可设定排序规则参数的行为,可以看作是仅适用于文本数据类型的一种受限多态形式。 + 这种支持排序规则的参数的行为,可以看作是仅适用于文本数据类型的一种受限多态形式。 @@ -1061,8 +1069,8 @@ $$ LANGUAGE SQL; 函数重载 - overloading - functions + 重载 + 函数 @@ -1094,10 +1102,10 @@ CREATE FUNCTION test(smallint, double precision) RETURNS ... - 另一类可能的冲突发生在 variadic 函数和非 variadic 函数之间。例如,可以同时创建 + 另一类可能的冲突发生在可变参数函数和非可变参数函数之间。例如,可以同时创建 foo(numeric)foo(VARIADIC numeric[])。 这时,对于只提供一个 numeric 参数的调用(例如 foo(10.1)),就不清楚该匹配哪个函数。 - 规则是:优先使用在搜索路径中出现较早的那个函数;如果两者位于同一模式中,则优先使用非 variadic 函数。 + 规则是:优先使用在搜索路径中出现较早的那个函数;如果两者位于同一模式中,则优先使用非可变参数函数。 @@ -1124,8 +1132,8 @@ CREATE FUNCTION test(int, int) RETURNS int 函数易变性分类 - volatility - functions + 易变性 + 函数 VOLATILE @@ -1142,7 +1150,7 @@ CREATE FUNCTION test(int, int) RETURNS int 一个VOLATILE函数可以做任何事情,包括修改数据库。在 使用相同的参数连续调用时,它能返回不同的结果。优化器不会对这类函 - 数的行为做任何假定。对于在每一行都需要 volatile 函数值的查询,函数都会被重新求值。 + 数的行为做任何假定。使用易变函数的查询会在需要该函数值的每一行上重新对它求值。 @@ -1190,8 +1198,7 @@ CREATE FUNCTION test(int, int) RETURNS int 在考虑先规划然后立即执行的简单交互式查询时,在STABLEIMMUTABLE分类间的区别相对较小:一个函数是在规划时只 执行一次还是在查询执行开始期间只执行一次没有太大关系。但是如果计划 - 被保存下来然后在后面被重用,区别就大了。如果在不允许过早把一个函数 - 变成规划期间的一个常数时把它标记为IMMUTABLE,会导致 + 被保存下来然后在后面被重用,区别就大了。如果把一个实际上并非不可变的函数标记为IMMUTABLE,就可能在规划期间过早将它折叠成常量,导致 在后续重用该计划时继续使用陈旧的值。在使用预备语句,或使用会缓存执行计划的函数语言(如 PL/pgSQL)时,这会带来严重问题。 @@ -1259,7 +1266,7 @@ CREATE FUNCTION test(int, int) RETURNS int 内部函数 - functioninternal + 函数内部 内部函数由 C 编写并且已经被静态链接到PostgreSQL @@ -1297,9 +1304,9 @@ CREATE FUNCTION square_root(double precision) RETURNS double precision C 语言函数 - function - user-defined - in C + 函数 + 用户定义的 + 在 C 中 @@ -1323,17 +1330,17 @@ CREATE FUNCTION square_root(double precision) RETURNS double precision - 在一个会话中第一次调用一个特定可载入对象文件中的用户定义函数时, - 动态载入器会把那个对象文件载入到内存以便该函数被调用。因此用户 + 在一个会话中第一次调用一个特定可载入目标文件中的用户定义函数时, + 动态载入器会把那个目标文件载入到内存以便该函数被调用。因此用户 定义的 C 函数的CREATE FUNCTION必须 - 为该函数指定两块信息:可载入对象文件的名称,以及要在该对象文件中 + 为该函数指定两块信息:可载入目标文件的名称,以及要在该目标文件中 调用的特定函数的 C 名称(链接符号)。如果没有显式指定 C 名称,则 它被假定为和 SQL 函数名相同。 下面的算法被用来基于CREATE FUNCTION - 命令中给定的名称来定位共享对象文件: + 命令中给定的名称来定位共享目标文件: @@ -1392,16 +1399,17 @@ CREATE FUNCTION square_root(double precision) RETURNS double precision PostgreSQL不会自动编译 C 函数。在 - 从CREATE FUNCTION命令中引用对象文件 + 从CREATE FUNCTION命令中引用目标文件 之前,它必须先被编译好。更多信息请见 - magic block + 魔数块 - 为确保动态装载的对象文件不会被加载到不兼容的服务器中,PostgreSQL会检查该文件是否包含内容适当的magic block。这样服务器就能检测出明显的不兼容情况,例如代码所针对的大版本不同于当前的 PostgreSQL。要加入 magic block,请在模块某一个(且只能一个)源文件中写入下列内容,并事先包含头文件 fmgr.h: + + 为确保动态装载的目标文件不会被加载到不兼容的服务器中,PostgreSQL 会检查该文件是否包含内容正确的魔数块。这样服务器就能检测出明显的不兼容情况,例如代码是针对另一个 PostgreSQL 主版本编译的。要加入魔数块,请在模块某一个(且只能一个)源文件中,在包含头文件 fmgr.h 之后写入: PG_MODULE_MAGIC; @@ -1409,9 +1417,9 @@ PG_MODULE_MAGIC; - 在第一次使用之后,动态载入对象文件会保留在内存中。在同一个会话中, + 在第一次使用之后,动态载入目标文件会保留在内存中。在同一个会话中, 后续对该文件中函数的调用只需付出一次很小的符号表查找开销。如果需要 - 强制重新载入一个对象文件(例如在重新编译之后),就需要开启一个新的会话。 + 强制重新载入一个目标文件(例如在重新编译之后),就需要开启一个新的会话。 @@ -1430,7 +1438,7 @@ PG_MODULE_MAGIC; - C 语言函数中的基本类型 + C 语言函数中的基础类型 数据类型 @@ -1439,16 +1447,16 @@ PG_MODULE_MAGIC; 要了解如何编写 C 语言函数,你需要了解 - PostgreSQL如何在内部表达基本数据类型 + PostgreSQL如何在内部表达基础类型 以及如何与函数传递它们。在内部, - PostgreSQL把基本类型视为一块内存数据块。 + PostgreSQL把基础类型视为一块内存数据块。 你为该类型定义的用户自定义函数,决定了 PostgreSQL 如何操作它。 也就是说,PostgreSQL 只负责把数据存到磁盘、再从磁盘取回, 而数据的输入、处理和输出则依赖你定义的这些函数。 - 基本类型可以有三种内部格式之一: + 基础类型可以有三种内部格式之一: @@ -1513,10 +1521,9 @@ typedef struct 最后,所有变长类型必须也以引用的方式传递。所有变长类型必须用一个 - 正好 4 字节的不透明长度域开始,该域会由SET_VARSIZE - 设置,绝不要直接设置该域!所有要被存储在该类型中的数据必须在内存 - 中接着该长度域的后面存储。长度域包含该结构体的总长度,也就是包括长 - 度域本身的尺寸。 + 正好 4 字节的不透明长度字段开始,该字段会由SET_VARSIZE + 设置,绝不要直接设置该字段!所有要被存储在该类型中的数据必须在内存 + 中接着该长度字段的后面存储。长度字段包含该结构体的总长度,也就是包括长度字段本身的尺寸。 @@ -1566,16 +1573,16 @@ memcpy(destination->data, buffer, 40); VARHDRSZsizeof(int32)一样, - 但是用宏VARHDRSZ来引用变长类型的载荷的 + 但是用宏VARHDRSZ来引用变长类型的额外开销的 尺寸被认为是比较好的风格。还有,必须 - 使用SET_VARSIZE宏来设置长度域,而不是用 + 使用SET_VARSIZE宏来设置长度字段,而不是用 简单的赋值来设置。 展示了 PostgreSQL 中许多内置 SQL 数据类型所对应的 C 类型。 - Defined In列给出了需要包含的头文件,以获取类型定义。 + 定义文件列给出了需要包含的头文件,以获取类型定义。 (实际的定义可能位于所列文件包含的其他文件中。建议用户坚持使用已定义的接口。) 请注意,在服务器代码的任何源文件中,都应该始终首先包含postgres.h, 因为它声明了很多你反正都会用到的内容,而且先包含其他头文件可能会带来可移植性问题。 @@ -1748,8 +1755,7 @@ memcpy(destination->data, buffer, 40); - 现在我们已经复习了基本类型所有可能的结构,现在可以展示一些 - 真实函数的示例了。 + 了解了基础类型所有可能的结构后,就可以看一些实际函数示例。 @@ -1757,7 +1763,7 @@ memcpy(destination->data, buffer, 40); 版本 1 的调用约定 - 版本-1 的调用规范依赖于宏来降低传参数和结果的复杂度。版本-1 函数的 + 版本-1 的调用约定依赖于宏来降低传参数和结果的复杂度。版本-1 函数的 C 声明总是: Datum funcname(PG_FUNCTION_ARGS) @@ -1769,14 +1775,16 @@ PG_FUNCTION_INFO_V1(funcname); 必须出现在同一个源文件中(按惯例会正好写在该函数本身之前)。 这种宏调用不是internal语言函数所需要的,因为 PostgreSQL会假定所有内部函数都使用 - 版本-1 规范。不过,对于动态载入函数是必需的。 + 版本-1 调用约定。不过,对于动态载入函数是必需的。 - 在版本-1 函数中,每一个实参都使用对应于该参数数据类型的PG_GETARG_xxx()宏取得。(在非严格的函数中,需要使用PG_ARGISNULL()对参数是否为空提前做检查;见下文。)结果要用对应于返回类型的PG_RETURN_xxx()宏返回。PG_GETARG_xxx()的参数是要取得的函数参数的编号,从零开始计。PG_RETURN_xxx()的参数是实际要返回的值。 + 在版本-1 函数中,每一个实参都使用对应于该参数数据类型的PG_GETARG_xxx()宏取得。(在非严格的函数中,需要使用PG_ARGISNULL()对参数是否为空值提前做检查;见下文。)结果要用对应于返回类型的PG_RETURN_xxx()宏返回。PG_GETARG_xxx()的参数是要取得的函数参数的编号,从零开始计。PG_RETURN_xxx()的参数是实际要返回的值。 - 下面是一些使用版本-1 调用约定的示例: + + 这里是一些使用版本-1调用约定的示例: + - 注意我们已经把函数指定为strict,这意味着如果有任何输入值为空,系统应该自动假定得到空结果。通过这种做法,我们避免在函数代码中检查空值输入。如果不这样做,我们必须使用PG_ARGISNULL()明确地检查空值输入。 + 注意我们已经把函数指定为strict,这意味着如果有任何输入值为空值,系统应该自动假定结果为空值。通过这种做法,我们避免在函数代码中检查空值输入。如果不这样做,我们必须使用PG_ARGISNULL()明确地检查空值输入。 - 宏PG_ARGISNULL(n)允许一个函数测试是否每一个输入为空(当然,只需要在没有声明为strict的函数中这样做)。和PG_GETARG_xxx()宏一样,输入参数也是从零开始计数。注意应该在验证了一个参数不是空之后才执行PG_GETARG_xxx()。要返回一个空结果,应执行PG_RETURN_NULL(),它对严格的以及非严格的函数都有用。 + 宏PG_ARGISNULL(n)允许一个函数测试是否每一个输入为空值(当然,只需要在没有声明为strict的函数中这样做)。和PG_GETARG_xxx()宏一样,输入参数也是从零开始计数。注意应该在验证了一个参数不是空值之后才执行PG_GETARG_xxx()。要返回空值结果,应执行PG_RETURN_NULL(),它对严格的以及非严格的函数都有用。 @@ -1918,11 +1926,11 @@ CREATE FUNCTION concat_text(text, text) RETURNS text - 在版本-1接口中提供的其他选项是PG_GETARG_xxx()宏的两个变种。其中的第一种是PG_GETARG_xxx_COPY(),它确保返回的指定参数的拷贝可以被安全地写入(通常的宏有时会返回一个指向表中物理存储的值,它不能被写入。使用PG_GETARG_xxx_COPY()宏可以保证得到一个可写的结果)。第二种变种PG_GETARG_xxx_SLICE()宏有三个参数。第一个是函数参数的编号(如上文)。第二个和第三个是要被返回的段的偏移量和长度。偏移量从零开始计算,而负值的长度则表示要求返回该值的剩余部分。当大型值的存储类型为external时,这些宏提供了访问这些大型值的更有效的方法(列的存储类型可以使用ALTER TABLE tablename ALTER COLUMN colname SET STORAGE storagetype来指定。storagetypeplainexternalextended或者main)。 + 在版本-1接口中提供的其他选项是PG_GETARG_xxx()宏的两个变种。其中的第一种是PG_GETARG_xxx_COPY(),它确保返回的指定参数的拷贝可以被安全地写入(通常的宏有时会返回一个指向表中物理存储值的指针,不能写入该值。使用PG_GETARG_xxx_COPY()宏可以保证得到一个可写的结果)。第二种变种PG_GETARG_xxx_SLICE()宏有三个参数。第一个是函数参数的编号(如上文)。第二个和第三个是要被返回的段的偏移量和长度。偏移量从零开始计算,而负值的长度则表示要求返回该值的剩余部分。当大型值的存储类型为external时,这些宏提供了访问这些大型值的部分内容的更有效方法(列的存储类型可以使用ALTER TABLE tablename ALTER COLUMN colname SET STORAGE storagetype来指定。storagetypeplainexternalextended或者main)。 - 最后,版本-1 的函数调用规范可以返回集合结果()、实现触发器函数()和过程语言调用处理器()。更多细节 + 最后,版本-1 的函数调用约定可以返回集合结果()、实现触发器函数()和过程语言调用处理器()。更多细节 可见源代码发布中的src/backend/utils/fmgr/README @@ -1933,18 +1941,24 @@ CREATE FUNCTION concat_text(text, text) RETURNS text 在开始更高级的话题之前,我们应该讨论一下用于 PostgreSQL C 语言函数的编码规则。 - 虽然可以把不是 C 编写的函数载入到 - PostgreSQL中,这通常是很困难的, + 虽然有可能把不是 C 编写的函数载入到 + PostgreSQL中,但即使能够做到,通常也很困难, 因为其他语言(例如 C++、FORTRAN 或者 Pascal)通常不会遵循和 C - 相同的调用规范。也就是说,其他语言不会以同样的方式在函数之间传递 + 相同的调用约定。也就是说,其他语言不会以同样的方式在函数之间传递 参数以及返回值。由于这个原因,我们会假定你的 C 语言函数确实是用 C 编写的。 - 编写和构建 C 函数的基本规则如下: + + 编写和构建 C 语言函数的基本规则如下: + + - 使用pg_config - --includedir-serverpg_config用于用户定义的 C 函数来确定PostgreSQL服务器头文件在你的系统(或用户将要运行的系统)上的安装位置。 + + 使用 pg_config + --includedir-serverpg_config用于用户定义的 C 函数 + 查出 PostgreSQL 服务器头文件在你的系统上(或你的用户将要运行的系统上)安装于何处。 + @@ -1955,7 +1969,7 @@ CREATE FUNCTION concat_text(text, text) RETURNS text - 记得按照中的说明,为你的共享库定义一个magic block。 + 记得按照中的说明,为你的共享库定义一个魔数块 @@ -1981,7 +1995,7 @@ CREATE FUNCTION concat_text(text, text) RETURNS text - 对象文件中定义的符号名不能彼此冲突,也不能与 + 目标文件中定义的符号名不能彼此冲突,也不能与 PostgreSQL 服务器可执行文件中定义的符号冲突。如果你收到这类错误消息,就必须重命名相关函数或变量。 @@ -1992,17 +2006,25 @@ CREATE FUNCTION concat_text(text, text) RETURNS text 复合类型没有像 C 结构体那样的固定布局。复合类型的实例可能包含 - 空值域。此外,继承层次中的复合类型可能具有和同一继承层次中 - 其他成员不同的域。因此, + 空值字段。此外,继承层次中的复合类型可能具有和同一继承层次中 + 其他成员不同的字段。因此, PostgreSQL提供了函数接口 - 来访问 C 的复合类型的域。 + 以便从 C 访问复合类型的字段。 - 假设我们想编写一个函数来回答如下查询: + + 假设我们想要写一个函数来回答查询: + + SELECT name, c_overpaid(emp, 1500) AS overpaid FROM emp WHERE name = 'Bill' OR name = 'Sam'; -使用版本-1 调用约定,我们可以将 c_overpaid 定义为: + + 如果使用版本-1的调用约定,我们可以定义 + c_overpaid为: + + GetAttributeByName 是 - PostgreSQL 的一个系统函数,用于从指定行中取出属性。它有三个参数:传入函数的 HeapTupleHeader 类型参数、所需属性的名称,以及一个用于指示该属性是否为 null 的返回参数。GetAttributeByName 返回一个 Datum 值,你可以用适当的 DatumGetXXX() 函数把它转换为正确的数据类型。注意,如果 null 标志被设置,那么返回值本身没有意义;在尝试对结果做任何处理之前,务必先检查这个 null 标志。 + PostgreSQL 的一个系统函数,用于从指定行中取出属性。它有三个参数:传入函数的 HeapTupleHeader 类型参数、所需属性的名称,以及一个用于指示该属性是否为 null 的返回参数。GetAttributeByName 返回一个 Datum 值,你可以用适当的 DatumGetXXX() 宏把它转换为正确的数据类型。注意,如果 null 标志被设置,那么返回值本身没有意义;在尝试对结果做任何处理之前,务必先检查这个 null 标志。 也有GetAttributeByNum函数,它可以用目标属性 - 的属性号而不是属性名来选择目标属性。 + 的列号而不是属性名来选择目标属性。 @@ -2058,14 +2080,14 @@ CREATE FUNCTION c_overpaid(emp, integer) RETURNS boolean 要从 C 语言函数中返回一行或一个复合类型值,可以使用一套特殊的 API, - 它通过一组宏和函数隐藏了构造组合数据类型时的大部分复杂性。要使用这套 API,源文件中必须包含: + 它通过一组宏和函数隐藏了构造复合数据类型时的大部分复杂性。要使用这套 API,源文件中必须包含: #include "funcapi.h" - 构造组合数据值(下文简称元组)有两种方式: + 构造复合数据值(下文简称元组)有两种方式: 一种是从 Datum 值数组构造,另一种是从 C 字符串数组构造,这些字符串会传给该元组各列数据类型的输入转换函数。 无论采用哪种方式,首先都需要获取或构造描述该元组结构的 TupleDesc。 处理 Datum 时,需要把 TupleDesc 传给 BlessTupleDesc,然后为每一行调用 heap_form_tuple。 @@ -2074,13 +2096,13 @@ CREATE FUNCTION c_overpaid(emp, integer) RETURNS boolean - 有一些辅助函数可以用来设置所需的 TupleDesc。在大多数返回组合值的函数中,推荐的做法是调用: + 有一些辅助函数可以用来设置所需的 TupleDesc。在大多数返回复合值的函数中,推荐的做法是调用: TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc) - 传入与调用函数本身相同的 fcinfo 结构体(这当然要求使用版本 1 调用约定)。 + 传入调用函数本身收到的同一个 fcinfo 结构体(这当然要求使用版本 1 调用约定)。 resultTypeId 可以指定为 NULL,也可以指定为一个本地变量的地址,用于接收函数结果类型的 OID。 resultTupleDesc 应当是一个本地 TupleDesc 变量的地址。 检查返回结果是否为 TYPEFUNC_COMPOSITE;如果是,resultTupleDesc 就会被填入所需的 TupleDesc。 @@ -2099,7 +2121,7 @@ TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, get_call_result_type有一个兄弟 get_expr_result_type,它被用来解析被表示为一棵表达式 - 树的函数调用的输出类型。在尝试确定来自函数外部的结果类型时可以用它。 + 树的函数调用的输出类型。在尝试从函数自身外部确定结果类型时可以用它。 也有一个get_func_result_type,当只有函数的 OID 可用时 可以用它。不过这些函数无法处理被声明为返回record的 函数,并且get_func_result_type无法解析多态类型,因此你 @@ -2108,22 +2130,22 @@ TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, - 更早、现在已被废弃的获取TupleDesc的函数有: + 更早、现在已被弃用的获取TupleDesc的函数有: TupleDesc RelationNameGetTupleDesc(const char *relname) - 它可以为一个提到的关系的行类型得到TupleDesc, + 它可以为一个指定名称的关系的行类型得到TupleDesc, 还有: TupleDesc TypeGetTupleDesc(Oid typeoid, List *colaliases) 可以基于一个类型 OID 得到TupleDesc。这可以被用来 - 为一种基础或者复合类型获得TupleDesc。不过,对于 + 为一种基本或者复合类型获得TupleDesc。不过,对于 返回record的函数它不起作用,并且它无法解析多态类型。 - 一旦有了一个TupleDesc,如果计划处理 Datum可以调用: + 一旦有了一个TupleDesc,如果计划处理 Datum,可以调用: TupleDesc BlessTupleDesc(TupleDesc tupdesc) @@ -2133,7 +2155,7 @@ AttInMetadata *TupleDescGetAttInMetadata(TupleDesc tupdesc) 如果正在编写一个返回集合的函数,你可以把这些函数的结果保存在 FuncCallContext结构体中 — 分别使用 - tuple_desc或者attinmeta域。 + tuple_desc或者attinmeta字段。 @@ -2153,8 +2175,7 @@ HeapTuple BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values) values是一个 C 字符串数组,每一个元素是返回行 的一个属性。每一个 C 字符串应该是该属性数据类型的输入函数所期望 的格式。为了对一个属性返回空值,values数组中对 - 应的指针应该被设置为NULL。对于你返回的每一行都将 - 再次调用这个函数。 + 应的指针应该被设置为NULL。对于你返回的每一行都需要再次调用这个函数。 @@ -2189,19 +2210,25 @@ HeapTupleGetDatum(HeapTuple tuple) 使用 ValuePerCall 模式时,重要的是要记住查询不能保证运行完成; 也就是说,由于诸如LIMIT之类的选项, - 执行程序可能会在获取所有行之前停止调用 set-returning 函数。 + 执行器可能会在获取所有行之前停止调用集合返回函数。 这意味着在最后一次调用中执行清理活动是不安全的,因为这可能永远不会发生。 对于需要访问外部资源(例如文件描述符)的函数,建议使用 Materialize 模式。 - 本节的其余部分记录了一组使用 ValuePerCall 模式的 SRF 常用(尽管不是必须使用)的帮助程序宏。 + 本节的其余部分记录了一组使用 ValuePerCall 模式的 SRF 常用(尽管不是必须使用)的辅助宏。 有关 Materialize 模式的其他详细信息可以在src/backend/utils/fmgr/README中找到。 此外,PostgreSQL源代码分发中的contrib 模块包含许多使用 ValuePerCall 和 Materialize 模式的 SRF 示例。 - 要使用这里描述的 ValuePerCall 支持宏,请包含 funcapi.h。这些宏会用到一个结构体 FuncCallContext,该结构体包含需要跨调用保存的状态。在使用这些宏的 SRF 中,fcinfo->flinfo->fn_extra 用于在调用之间保存指向 FuncCallContext 的指针。宏在第一次使用时自动填充该字段,并期望在后续使用中找到相同的指针。 + + 要使用此处描述的 ValuePerCall 支持宏,请包含funcapi.h。 + 这些宏与结构体FuncCallContext一起使用,该结构体包含需要跨调用保存的状态。 + 在使用这些宏的 SRF 中,fcinfo->flinfo->fn_extra用于在调用之间保存 + 指向FuncCallContext的指针。 + 宏在第一次使用时自动填充该字段,并期望在后续使用中找到相同的指针。 + typedef struct FuncCallContext { /* @@ -2231,7 +2258,7 @@ typedef struct FuncCallContext /* * 可选:指向包含属性类型输入元数据的结构的指针 * - * attinmeta 被用在返回元组(即组合数据类型)时,在返回基本数据类型 + * attinmeta 被用在返回元组(即复合数据类型)时,在返回基础类型 * 时不会使用。只有想用BuildTupleFromCStrings()创建返回元组时才需要它。 */ AttInMetadata *attinmeta; @@ -2248,7 +2275,7 @@ typedef struct FuncCallContext /* * 可选:指向包含元组描述的结构的指针 * - * tuple_desc 被用在返回元组(即组合数据类型)时,并且只有在用 + * tuple_desc 被用在返回元组(即复合数据类型)时,并且只有在用 * heap_form_tuple() 而不是 BuildTupleFromCStrings() 构建元组时才需要它。 * 注意这里存储的 TupleDesc 指针通常已经被先运行过 BlessTupleDesc()。 */ @@ -2352,14 +2379,16 @@ my_set_returning_function(PG_FUNCTION_ARGS) else { /* 这里已经完成了项的返回,所以只报告事实。 */ - /* (不要将清理代码放在这里的。) */ + /* (不要将清理代码放在这里。) */ SRF_RETURN_DONE(funcctx); } } - 下面是一个返回复合类型的简单 SRF 的完整示例: + 一个返回复合类型的简单SRF的完整示例如下: +multi_call_memory_ctx); - /* total number of tuples to be returned */ + /* 要返回的元组总数 */ funcctx->max_calls = PG_GETARG_UINT32(0); - /* Build a tuple descriptor for our result type */ + /* 为我们的结果类型构建一个元组描述符 */ if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), @@ -2393,8 +2422,7 @@ retcomposite(PG_FUNCTION_ARGS) "that cannot accept type record"))); /* - * generate attribute metadata needed later to produce tuples from raw - * C strings + * 生成后续从原始C字符串生成元组所需的属性元数据 */ attinmeta = TupleDescGetAttInMetadata(tupdesc); funcctx->attinmeta = attinmeta; @@ -2402,23 +2430,22 @@ retcomposite(PG_FUNCTION_ARGS) MemoryContextSwitchTo(oldcontext); } - /* stuff done on every call of the function */ + /* 每次函数调用时执行的操作 */ funcctx = SRF_PERCALL_SETUP(); call_cntr = funcctx->call_cntr; max_calls = funcctx->max_calls; attinmeta = funcctx->attinmeta; - if (call_cntr < max_calls) /* do when there is more left to send */ + if (call_cntr < max_calls) /* 当还有更多要发送时执行 */ { char **values; HeapTuple tuple; Datum result; /* - * Prepare a values array for building the returned tuple. - * This should be an array of C strings which will - * be processed later by the type input functions. + * 为构建返回的元组准备一个值数组。 + * 这应该是一个由后续类型输入函数处理的C字符串数组。 */ values = (char **) palloc(3 * sizeof(char *)); values[0] = (char *) palloc(16 * sizeof(char)); @@ -2429,13 +2456,13 @@ retcomposite(PG_FUNCTION_ARGS) snprintf(values[1], 16, "%d", 2 * PG_GETARG_INT32(1)); snprintf(values[2], 16, "%d", 3 * PG_GETARG_INT32(1)); - /* build a tuple */ + /* 构建一个元组 */ tuple = BuildTupleFromCStrings(attinmeta, values); - /* make the tuple into a datum */ + /* 将元组转换为 datum */ result = HeapTupleGetDatum(tuple); - /* clean up (this is not really necessary) */ + /* 清理(这实际上并不是必要的) */ pfree(values[0]); pfree(values[1]); pfree(values[2]); @@ -2443,26 +2470,33 @@ retcomposite(PG_FUNCTION_ARGS) SRF_RETURN_NEXT(funcctx, result); } - else /* do when there is no more left */ + else /* 当没有更多要发送时执行 */ { SRF_RETURN_DONE(funcctx); } } ]]> -在 SQL 中声明该函数的一种方法是: + + + 在SQL中声明此函数的一种方法是: + CREATE TYPE __retcomposite AS (f1 integer, f2 integer, f3 integer); CREATE OR REPLACE FUNCTION retcomposite(integer, integer) RETURNS SETOF __retcomposite AS 'filename', 'retcomposite' LANGUAGE C IMMUTABLE STRICT; -另一种方法是使用 OUT 参数: + + 另一种方法是使用OUT参数: + CREATE OR REPLACE FUNCTION retcomposite(IN integer, IN integer, OUT f1 integer, OUT f2 integer, OUT f3 integer) RETURNS SETOF record AS 'filename', 'retcomposite' LANGUAGE C IMMUTABLE STRICT; -注意,在这种方法中,该函数的输出类型在形式上是一个匿名的 record 类型。 + + 请注意,采用这种方法时,函数的输出类型在形式上是一个匿名的 record 类型。 + @@ -2481,10 +2515,10 @@ CREATE OR REPLACE FUNCTION retcomposite(IN integer, IN integer, fcinfo->flinfo访问。参数argnum则是从零 开始计。get_call_result_type也可被用作 get_fn_expr_rettype的一种替代品。还有 - get_fn_expr_variadic,它可以被用来找出 variadic 参数 + get_fn_expr_variadic,它可以被用来找出可变参数 是否已经被合并到了一个数组中。这主要用于 VARIADIC "any"函数,因为对于接收普通数组类型的 - variadic 函数来说总是会发生这类合并。 + 可变参数函数来说总是会发生这类合并。 @@ -2552,7 +2586,7 @@ CREATE FUNCTION make_array(anyelement) RETURNS anyarray 它与 anyelement 类似,但不会要求不同的 "any" 参数必须是同一种类型,也不会帮助确定函数的结果类型。 C 语言函数还可以把最后一个参数声明为 VARIADIC "any"。 这可以匹配一个或多个任意类型的实参(不必是同一种类型)。 - 这些参数不会像普通 variadic 函数那样被收集成一个数组,而是会单独传给函数。 + 这些参数不会像普通可变参数函数那样被收集成一个数组,而是会单独传给函数。 使用这种特性时,必须结合 PG_NARGS() 宏以及前面介绍的方法来确定实参的个数和类型。 此外,这种函数的用户也可能希望在函数调用中使用 VARIADIC 关键字,以便让函数把数组元素当作独立参数处理。 如果希望支持这种行为,函数本身就必须在使用 get_fn_expr_variadic 检测到实参被标记为 VARIADIC 后自行实现它。 @@ -2560,7 +2594,7 @@ CREATE FUNCTION make_array(anyelement) RETURNS anyarray - 共享内存 + 共享内存与 LWLocks 附加模块可以在服务器启动时预留 LWLock 和一块共享内存。附加模块的共享库必须通过在以下参数中指定它来预装载:shared_preload_libraries。共享内存可以通过下面的调用来预留: void RequestAddinShmemSpace(int size) @@ -2629,9 +2663,9 @@ if (!ptr) - 如果从 C++ 代码调用后端函数,确定 C++ 调用栈值包含传统 C 风格 + 如果从 C++ 代码调用后端函数,确定 C++ 调用栈只包含传统 C 风格 的数据结构(POD)。这是必要的,因为后端错误会 - 产生远距离的longjmp(),它无法正确的退回具有非 + 产生远距离的longjmp(),它无法正确地展开具有非 POD 对象的 C++ 调用栈。 @@ -2650,8 +2684,8 @@ if (!ptr) 函数优化信息 - optimization information - for functions + 优化信息 + 用于函数 @@ -2687,7 +2721,7 @@ supportfn(internal) returns internal - 对于返回 boolean 的目标函数,估计使用该函数的 WHERE 子句会筛选出多少行通常很有用。这可以通过实现 SupportRequestSelectivity 请求类型的支持函数来完成。 + 对于返回 boolean 的目标函数,估计使用该函数的 WHERE 子句筛选出的行所占的比例通常很有用。这可以通过实现 SupportRequestSelectivity 请求类型的支持函数来完成。 diff --git a/zh/12/xindex.sgml b/zh/12/xindex.sgml index 6eddba16..5a88e33a 100644 --- a/zh/12/xindex.sgml +++ b/zh/12/xindex.sgml @@ -22,7 +22,7 @@ pg_am 表为每个索引方法(内部称为访问方法)保存一行。对表进行常规访问的支持内置于 PostgreSQL 中,但所有索引方法都在 pg_am 中描述。可以编写必要的代码,然后在 pg_am 中创建一个条目,从而添加新的索引访问方法 — 但这超出了本章的范围(参见)。 - 索引方法的例程并不直接知道它将处理哪些数据类型。相反,一个操作符类operator class标识了索引方法在处理特定数据类型时需要使用的那组操作。之所以称为操作符类,是因为它指定的一项内容就是可与索引一起使用的 WHERE 子句操作符集合(也就是能被转换成索引扫描条件的操作符)。操作符类还可以指定索引方法内部操作所需的一些支持函数,但这些函数并不直接对应任何可与索引一起使用的 WHERE 子句操作符。 + 索引方法的例程并不直接知道它将处理哪些数据类型。相反,一个操作符类操作符类标识了索引方法在处理特定数据类型时需要使用的那组操作。之所以称为操作符类,是因为它指定的一项内容就是可与索引一起使用的 WHERE 子句操作符集合(也就是能被转换成索引扫描条件的操作符)。操作符类还可以指定索引方法内部操作所需的一些支持函数,但这些函数并不直接对应任何可与索引一起使用的 WHERE 子句操作符。 @@ -310,15 +310,21 @@ - 比较两个键,并返回小于零、等于零或大于零的整数,分别表示第一个键小于、等于或大于第二个键 + + 比较两个键,并返回一个小于零、等于零或大于零的整数,用以表示第一个键是小于、等于还是大于第二个键 + 1 - 返回可从 C 调用的排序支持函数的地址(可选) + + 返回可由 C 调用的排序支持函数地址(可选) + 2 - 将测试值与基准值加上或减去偏移量后的结果进行比较,并根据比较结果返回真或假(可选) + + 将测试值与基准值加上或减去某个偏移量后的结果进行比较,并根据比较结果返回真或假(可选) + 3 @@ -345,7 +351,7 @@ - 给定一个 64 位 salt,计算一个键的 64 位哈希值;如果 salt 为 0,结果的低 32 位必须与函数 1 计算出的值一致(可选) + 给定一个 64 位盐值,计算一个键的 64 位哈希值;如果盐值为 0,结果的低 32 位必须与函数 1 计算出的值一致(可选) 2 @@ -478,7 +484,7 @@ compare - 比较两个键,并返回一个小于零、等于零或大于零的整数,以表示第一个键是小于、等于还是大于第二个键 + 比较两个键,并返回一个小于零、等于零或大于零的整数,用以表示第一个键是小于、等于还是大于第二个键 1 @@ -618,7 +624,10 @@ complex_abs_lt(PG_FUNCTION_ARGS) 其他四个函数的区别只在于它们如何比较内部函数的结果与 0。 - 接下来,在 SQL 中声明这些函数,以及基于这些函数的操作符: + + 接着,我们在 SQL 中声明这些函数以及基于它们的操作符: + + CREATE FUNCTION complex_abs_lt(complex, complex) RETURNS bool AS 'filename', 'complex_abs_lt' LANGUAGE C IMMUTABLE STRICT; @@ -628,7 +637,9 @@ CREATE OPERATOR < ( commutator = > , negator = >= , restrict = scalarltsel, join = scalarltjoinsel ); -必须指定正确的交换操作符和求反操作符,以及合适的限制选择率与连接选择率函数,否则优化器无法有效使用索引。 + + 指定正确的交换子和求反器操作符很重要,同样也要指定合适的限制选择率函数和连接选择率函数,否则优化器将无法有效地利用索引。 + 这里还有几点值得注意: @@ -706,14 +717,14 @@ CREATE OPERATOR CLASS complex_abs_ops - 为了满足这些需求,PostgreSQL使用操作符族operator family这一概念。一个操作符族包含一个或多个操作符类,还可以包含属于整个族、但不属于族中任何单一类的可索引操作符及其相应的支持函数。我们称这样的操作符和函数在该族中是松散的,而不是绑定在某个特定类中。通常,每个操作符类只包含单一数据类型的操作符,而跨数据类型操作符则作为操作符族中的松散成员存在。 + 为了满足这些需求,PostgreSQL使用操作符族操作符族这一概念。一个操作符族包含一个或多个操作符类,还可以包含属于整个族、但不属于族中任何单一类的可索引操作符及其相应的支持函数。我们称这样的操作符和函数在该族中是松散的,而不是绑定在某个特定类中。通常,每个操作符类只包含单一数据类型的操作符,而跨数据类型操作符则作为操作符族中的松散成员存在。 一个操作符族中的所有操作符和函数都必须具有兼容的语义,而兼容性的要求由索引方法设定。因此,你也许会疑惑,为什么还要把该族的某些子集单独划成操作符类;事实上,对很多用途而言,类的划分并不重要,真正有意义的分组只有操作符族。之所以定义操作符类,是因为它们规定了支持特定索引所需的操作符族内容。如果某个索引使用了某个操作符类,那么在不删除该索引的情况下就不能删除该操作符类 — 但操作符族中的其他部分,也就是其他操作符类和松散操作符,则可以被删除。因此,一个操作符类应当只包含在特定数据类型上支持索引所合理需要的最小操作符和函数集合,而那些相关但非必需的操作符,则可以作为操作符族的松散成员加入。 - 例如,PostgreSQL内置了 B 树操作符族integer_ops,其中包含操作符类int8_opsint4_opsint2_ops,它们分别用于以下列类型上的索引:bigintint8), + 例如,PostgreSQL内置了 B-树操作符族integer_ops,其中包含操作符类int8_opsint4_opsint2_ops,它们分别用于以下列类型上的索引:bigintint8), integerint4)和smallintint2)。该操作符族还包含跨数据类型的比较操作符,允许对这些类型中的任意两个进行比较,因此可以使用一种类型的比较值搜索另一种类型上的索引。可以用以下定义复制这个操作符族: -注意,此定义重载了操作符策略编号和支持函数编号:每个编号在操作符族中出现多次。只要同一编号的每个实例具有不同的输入数据类型,这就是允许的。两个输入类型都等于某个操作符类输入类型的实例,是该操作符类的主要操作符和支持函数,通常应声明为操作符类的一部分,而不是操作符族的独立成员。 +注意,此定义重载了操作符策略编号和支持函数编号:每个编号在操作符族中出现多次。只要同一编号的每个实例具有不同的输入数据类型,这就是允许的。两个输入类型都等于某个操作符类输入类型的实例,是该操作符类的主要操作符和支持函数,通常应声明为操作符类的一部分,而不是操作符族的松散成员。 所详述,在一个 B-树操作符族中,该族中的所有操作符都必须以兼容的方式排序。对族中的每一个操作符,都必须有一个具有相同两个输入数据类型的支持函数。建议让操作符族保持完整,也就是说,对每一种数据类型组合都应包含全部操作符。每个操作符类只应包含其数据类型对应的非跨数据类型操作符和支持函数。 - 要构建一个多数据类型的哈希操作符族,必须为该族支持的每一种数据类型创建相互兼容的哈希支持函数。这里的兼容性是指:对任意两个被该族中的等值操作符视为相等的值,这些函数都保证返回相同的哈希码,即使这两个值属于不同类型也是如此。当这些类型具有不同的物理表示时,这通常难以实现,但在某些情况下可以做到。此外,将该操作符族中一种数据类型的值通过隐式或二进制强制转换转换成该族中另一种数据类型时,不应改变所计算出的哈希值。注意,每种数据类型只有一个支持函数,而不是每个等值操作符一个。建议让操作符族保持完整,也就是说,对每一种数据类型组合都提供一个等值操作符。每个操作符类只应包含其数据类型对应的非跨数据类型等值操作符和支持函数。 + 要构建一个多数据类型的哈希操作符族,必须为该族支持的每一种数据类型创建相互兼容的哈希支持函数。这里的兼容性是指:对任意两个被该族中的等值操作符视为相等的值,这些函数都保证返回相同的哈希码,即使这两个值属于不同类型也是如此。当这些类型具有不同的物理表示时,这通常难以实现,但在某些情况下可以做到。此外,将该操作符族中一种数据类型的值通过隐式或二进制强制转换转为该族中另一种数据类型时,不得改变所计算出的哈希值。注意,每种数据类型只有一个支持函数,而不是每个等值操作符一个。建议让操作符族保持完整,也就是说,对每一种数据类型组合都提供一个等值操作符。每个操作符类只应包含其数据类型对应的非跨数据类型等值操作符和支持函数。 @@ -828,7 +839,7 @@ ALTER OPERATOR FAMILY integer_ops USING btree ADD - 在 PostgreSQL 8.3 之前,并没有操作符族这一概念,因此任何打算与索引一起使用的跨数据类型操作符都必须直接绑定到该索引的操作符类中。虽然这种做法仍然有效,但已经废弃,因为它会使索引的依赖关系过于宽泛,而且当两种数据类型都在同一操作符族中拥有操作符时,规划器能更有效地处理跨数据类型比较。 + 在 PostgreSQL 8.3 之前,并没有操作符族这一概念,因此任何打算与索引一起使用的跨数据类型操作符都必须直接绑定到该索引的操作符类中。虽然这种做法仍然有效,但已被弃用,因为它会使索引的依赖关系过于宽泛,而且当两种数据类型都在同一操作符族中拥有操作符时,规划器能更有效地处理跨数据类型比较。 @@ -837,7 +848,7 @@ ALTER OPERATOR FAMILY integer_ops USING btree ADD 系统对操作符类的依赖 - ordering operator + 排序操作符 @@ -845,7 +856,7 @@ ALTER OPERATOR FAMILY integer_ops USING btree ADD - 特别地,ORDER BYDISTINCT等 SQL 特性要求对值的比较和排序。为了在用户定义的数据类型上实现这些特性,PostgreSQL会为数据类型查找默认 B-树操作符类。这个操作符类的equals成员定义了用于GROUP BYDISTINCT的值的等值概念,而该操作符类施加的排序顺序定义了默认的ORDER BY顺序。 + 特别地,ORDER BYDISTINCT等 SQL 特性要求对值的比较和排序。为了在用户定义的数据类型上实现这些特性,PostgreSQL会为数据类型查找默认 B-树操作符类。这个操作符类的相等成员定义了用于GROUP BYDISTINCT的值的等值概念,而该操作符类施加的排序顺序定义了默认的ORDER BY顺序。 @@ -871,11 +882,11 @@ SELECT * FROM mytable ORDER BY somecol USING ~<~; - 用户定义类型的数组比较也依赖于该类型默认 B-树操作符类所定义的语义。如果没有默认 B-树操作符类,但有默认的哈希操作符类,则支持数组相等比较,但不支持顺序比较。 + 用户定义类型的数组比较也依赖于该类型默认 B-树操作符类所定义的语义。如果没有默认 B-树操作符类,但有默认的哈希操作符类,则支持数组相等比较,但不支持排序比较。 - 另一种需要更多数据类型相关知识的 SQL 特性,是窗口函数中的 RANGE offset PRECEDING/FOLLOWING 框架选项(见)。对于下面这样的查询 + 另一种需要更多数据类型相关知识的 SQL 特性,是窗口函数中的 RANGE offset PRECEDING/FOLLOWING 帧选项(见)。对于下面这样的查询 SELECT sum(x) OVER (ORDER BY x RANGE BETWEEN 5 PRECEDING AND 10 FOLLOWING) FROM mytable; @@ -891,19 +902,26 @@ SELECT sum(x) OVER (ORDER BY x RANGE BETWEEN 5 PRECEDING AND 10 FOLLOWING) 排序操作符 - 某些索引访问方法(目前只有 GiST 和 SP-GiST)支持排序操作符的概念。我们到目前为止讨论的是搜索操作符。对于搜索操作符,可以搜索索引以找出满足以下条件的所有行:WHERE + + 有些索引访问方法(目前只有 GiST 和 SP-GiST)支持排序操作符这一概念。到目前为止,我们讨论的都是搜索操作符。对搜索操作符而言,可以搜索索引以找出所有满足 + WHERE indexed_column operator - constant。注意,不保证匹配行的返回顺序。排序操作符则不限制可以返回的行集合,而是确定这些行的顺序。对于排序操作符,可以扫描索引,按以下表达式表示的顺序返回行:ORDER BY + constant 的行。注意,返回匹配行的顺序并没有任何保证。相反,排序操作符并不限制可返回的行集合,而是决定这些行的顺序。对排序操作符而言,可以扫描索引以按如下表达式所表示的顺序返回行: + ORDER BY indexed_column operator - constant。这样定义排序操作符,是因为当操作符用于度量距离时,它可以支持最近邻搜索。例如,如下查询:constant
+ 之所以这样定义排序操作符,是因为如果该操作符能度量距离,它就能支持最近邻搜索。例如,像下面这样的查询 + point '(101,456)' LIMIT 10; ]]> -可以找到距离指定目标点最近的十个地点。location 列上的 GiST 索引能够高效完成此操作,因为<->是排序操作符。 + + 会找出离给定目标点最近的十个位置。对 location 列建立的 GiST 索引可以高效地完成这个查询,因为 <-> 是一个排序操作符。 + - 搜索操作符必须返回布尔结果,而排序操作符通常返回其他类型的结果,例如表示距离的浮点数或数值。这种类型通常不同于被索引的数据类型。为了避免对不同数据类型行为作硬编码假设,在定义排序操作符时,必须指定一个 B-树操作符族,用来说明结果数据类型的排序顺序。正如上一节所述,B-树操作符族定义了 PostgreSQL 的顺序概念,因此这是一种自然的表示方式。由于点的 <-> 操作符返回 float8,因此可以在创建操作符类时这样指定它: + 搜索操作符必须返回布尔结果,而排序操作符通常返回其他类型的结果,例如用于表示距离的 float 或 numeric。这种类型通常不同于被索引的数据类型。为了避免对不同数据类型行为作硬编码假设,在定义排序操作符时,必须指定一个 B-树操作符族,用来说明结果数据类型的排序顺序。正如上一节所述,B-树操作符族定义了 PostgreSQL 的顺序概念,因此这是一种自然的表示方式。由于点的 <-> 操作符返回 float8,因此可以在创建操作符类时这样指定它: (point, point) FOR ORDER BY float_ops ]]> @@ -916,7 +934,7 @@ OPERATOR 15 <-> (point, point) FOR ORDER BY float_ops 操作符类的特殊特性 - 还有两个操作符类的特殊特性我们尚未讨论,主要是因为它们对最常用的索引方法并不太有用。 + 还有两个操作符类的特殊特性我们尚未讨论,主要是因为它们对最常用的索引方法没有用处。 @@ -932,7 +950,7 @@ CREATE OPERATOR CLASS polygon_ops DEFAULT FOR TYPE polygon USING gist AS ... STORAGE box; -目前,只有 GiST、GIN 和 BRIN 索引方法支持与列数据类型不同的STORAGE类型。GiST 的compressdecompress支持函数在使用STORAGE时必须处理数据类型转换。在 GIN 中,STORAGE类型标识key值的类型,通常与被索引列的类型不同。例如,整数数组列的操作符类可以只使用整数作为键。GIN 的extractValueextractQuery支持函数负责从被索引值中提取键。BRIN 与 GIN 类似:STORAGE类型标识所存储摘要值的类型,而操作符类的支持函数负责正确解释这些摘要值。 +目前,只有 GiST、GIN 和 BRIN 索引方法支持与列数据类型不同的STORAGE类型。GiST 的compressdecompress支持函数在使用STORAGE时必须处理数据类型转换。在 GIN 中,STORAGE类型标识值的类型,通常与被索引列的类型不同。例如,整数数组列的操作符类可以只使用整数作为键。GIN 的extractValueextractQuery支持函数负责从被索引值中提取键。BRIN 与 GIN 类似:STORAGE类型标识所存储摘要值的类型,而操作符类的支持函数负责正确解释这些摘要值。 diff --git a/zh/12/xml2.sgml b/zh/12/xml2.sgml index 8b9b8344..33b00e73 100644 --- a/zh/12/xml2.sgml +++ b/zh/12/xml2.sgml @@ -1,7 +1,7 @@ - xml2 — XPath 查询与 XSLT 功能 + xml2 xml2 @@ -43,7 +43,7 @@ bool - 此函数解析其参数中的文档文本,如果文档是格式良好的 XML,则返回 true。(注意:这是标准 PostgreSQL 函数 xml_is_well_formed() 的别名。由于 XML 中有效性和格式良好性具有不同含义,函数名 xml_valid() 在技术上并不正确。) + 此函数解析其参数中的文档文本,如果文档是良构 XML,则返回 true。(注意:这是标准 PostgreSQL 函数 xml_is_well_formed() 的别名。由于 XML 中有效性和良构性具有不同含义,函数名 xml_valid() 在技术上并不正确。) @@ -83,7 +83,7 @@ 该函数计算文档上的查询,并将结果封装在 XML 标签中。如果结果有多个值,输出将如下所示: <toptag> -<itemtag>Value 1 which could be an XML fragment</itemtag> +<itemtag>Value 1(可以是 XML 片段)</itemtag> <itemtag>Value 2....</itemtag> </toptag> 如果toptagitemtag为空字符串,就会省略相应的标签。 @@ -169,7 +169,7 @@ xpath_table(text key, text document, text relation, text xpaths, text criteria) key - key 字段的名称 — 这只是一个作为输出表第一列使用的字段,也就是说,它用于标识每个输出行来自哪条记录(关于多个值,见下文注释) + 字段的名称 — 这只是一个作为输出表第一列使用的字段,也就是说,它用于标识每个输出行来自哪条记录(关于多个值,见下文注释) @@ -200,7 +200,9 @@ xpath_table(text key, text document, text relation, text xpaths, text criteria) criteria - WHERE 子句的内容。这一项不能省略,因此如果你想处理该关系中的所有行,请使用 true1=1 + + WHERE 子句的内容。这一项不能省略,因此如果你想处理该表或视图中的所有行,请使用 true1=1 + @@ -228,7 +230,7 @@ xpath_table('article_id', 'date_entered > ''2003-01-01'' ') AS t(article_id integer, author text, page_count integer, title text); - AS 子句定义了输出表中各列的名称和类型。第一列是 key 字段,其余各列对应 XPath 查询。如果 XPath 查询多于结果列,多出的查询将被忽略。如果结果列多于 XPath 查询,多出的列将为 NULL。 + AS 子句定义了输出表中各列的名称和类型。第一列是 字段,其余各列对应 XPath 查询。如果 XPath 查询多于结果列,多出的查询将被忽略。如果结果列多于 XPath 查询,多出的列将为 NULL。 @@ -257,7 +259,7 @@ WHERE t.author_id = p.person_id; - 在某些情况下,用户会知道某个 XPath 查询只会返回单个结果(例如唯一文档标识符)— 如果它与返回多个结果的 XPath 查询一起使用,这个单值结果只会出现在结果的第一行。解决办法是把 key 字段作为与一个更简单的 XPath 查询结果进行连接的条件之一。例如: + 在某些情况下,用户会知道某个 XPath 查询只会返回单个结果(例如唯一文档标识符)— 如果它与返回多个结果的 XPath 查询一起使用,这个单值结果只会出现在结果的第一行。解决办法是把键字段作为与一个更简单的 XPath 查询结果进行连接的条件之一。例如: CREATE TABLE test ( diff --git a/zh/12/xoper.sgml b/zh/12/xoper.sgml index 231aa84d..a92fae99 100644 --- a/zh/12/xoper.sgml +++ b/zh/12/xoper.sgml @@ -23,7 +23,12 @@ 哪个操作符。 - 下面是创建一个用于将两个复数相加的操作符的示例。假定我们已经创建了类型complex的定义(见)。首先需要一个完成实际工作的函数,然后就可以定义操作符: + + 下面是为两个复数相加创建一个操作符的示例。我们假设已经创建了 + complex类型的定义(见)。首先需要 + 一个完成实际工作的函数,然后才能定义该操作符: + + CREATE FUNCTION complex_add(complex, complex) RETURNS complex AS 'filename', 'complex_add' @@ -119,7 +124,7 @@ SELECT (a + b) AS c FROM test_complex; 转成 tab2.y = tab1.x,否则它就无法生成索引扫描,因为 索引扫描机制要求传给它的操作符左侧必须是已建立索引的列。 PostgreSQL 不会仅凭假 - 设就认为这种转换有效 — = 操作符的创建者必须通过为该操 + 设就认为这种转换有效;= 操作符的创建者必须通过为该操 作符标记交换子信息,明确声明这种转换是有效的。 @@ -173,10 +178,10 @@ SELECT (a + b) AS c FROM test_complex; <literal>RESTRICT</literal> - 如果给出 RESTRICT 子句,它指定该操作符的限制选择度估 + 如果给出 RESTRICT 子句,它指定该操作符的限制选择率估 算函数。(注意,这里是函数名,而不是操作符名。) RESTRICT 子句只对返回 boolean 的二元操 - 作符有意义。限制选择度估算器的作用,是针对当前操作符和某个特定常量值, + 作符有意义。限制选择率估算器的作用,是针对当前操作符和某个特定常量值, 猜测一张表中有多少比例的行会满足如下形式的 WHERE 子句条件: @@ -188,9 +193,9 @@ column OP constant - 编写新的限制选择度估算函数远远超出了本章的范围,不过幸运的是,对于你自 + 编写新的限制选择率估算函数远远超出了本章的范围,不过幸运的是,对于你自 己的很多操作符,通常都可以直接使用系统提供的某个标准估算器。标准的限制 - 选择度估算器如下: + 选择率估算器如下: eqsel 用于 = neqsel 用于 <> @@ -202,7 +207,7 @@ column OP constant - 对于选择度非常高或非常低的操作符,即使它们实际上并不是真正的相等或不等 + 对于选择率非常高或非常低的操作符,即使它们实际上并不是真正的相等或不等 比较,你也常常可以勉强使用 eqselneqsel。例如,几何类型中的近似相等操作符就使用 eqsel,其依据是它们通常只会匹配表中很小一部分项。 @@ -222,7 +227,7 @@ column OP constant src/backend/utils/adt/geo_selfuncs.c 中,还为几 - 何操作符提供了其他选择度估算函数:areasel、 + 何操作符提供了其他选择率估算函数:areaselpositionselcontsel。截至 目前,这些函数都还只是桩实现,但你也许仍会想使用它们(或者更好的是,改 进它们)。 @@ -233,9 +238,9 @@ column OP constant <literal>JOIN</literal> - 如果给出 JOIN 子句,它指定该操作符的连接选择度估算函 + 如果给出 JOIN 子句,它指定该操作符的连接选择率估算函 数。(注意,这里是函数名,而不是操作符名。)JOIN 子 - 句只对返回 boolean 的二元操作符有意义。连接选择度估算器的 + 句只对返回 boolean 的二元操作符有意义。连接选择率估算器的 作用,是针对当前操作符,猜测两张表中有多少比例的行对会满足如下形式的 WHERE 子句条件: @@ -304,7 +309,7 @@ table1.column1 OP table2.column2 一个可参与哈希连接的操作符,必须拥有一个交换子(如果两侧操作数数据类型 - 相同,则可以是它自身;如果不同,则应是相关的相等操作符),并且该交换子 + 相同,则为它自身;如果不同,则应是相关的相等操作符),并且该交换子 也必须出现在同一个操作符族中。否则,在使用该操作符时可能会发生规划器错 误。另外,对于支持多种数据类型的哈希操作符族,最好(虽然并非严格必需) 为每一种数据类型组合都提供相等操作符;这样可以获得更好的优化效果。 @@ -341,7 +346,7 @@ table1.column1 OP table2.column2 - 归并连接的基本思想,是先把左表和右表分别排序,然后并行扫描它们。因此, + 归并连接的基本思想,是先把左表和右表分别排序,然后同步扫描它们。因此, 两种数据类型都必须能够被完全排序,而连接操作符必须只能在那对值位于排序 次序中同一位置时才成功。实际效果上,这意味着连接操作符 必须表现得像相等比较一样。不过,只要两种不同的数据类型在逻辑上兼容,也 @@ -361,7 +366,7 @@ table1.column1 OP table2.column2 一个可参与归并连接的操作符,必须拥有一个交换子(如果两侧操作数数据类型 - 相同,则可以是它自身;如果不同,则应是相关的相等操作符),并且该交换子 + 相同,则为它自身;如果不同,则应是相关的相等操作符),并且该交换子 也必须出现在同一个操作符族中。否则,在使用该操作符时可能会发生规划器错 误。另外,对于支持多种数据类型的 btree 操作符族,最 好(虽然并非严格必需)为每一种数据类型组合都提供相等操作符;这样可以获 diff --git a/zh/12/xplang.sgml b/zh/12/xplang.sgml index 9f7c5b1a..b1068b05 100644 --- a/zh/12/xplang.sgml +++ b/zh/12/xplang.sgml @@ -107,14 +107,27 @@ CREATE FUNCTION validator_function_name(oid) - 最后,必须用如下命令声明该 PL: + + 最后,必须用如下命令声明该 PL: + CREATE TRUSTED LANGUAGE language_name HANDLER handler_function_name INLINE inline_function_name VALIDATOR validator_function_name ; -可选关键字TRUSTED表示,该语言不会授予用户原本不具备的数据访问能力。受信任的语言是为普通数据库用户(即没有超级用户权限的用户)设计的,并允许他们安全地创建函数和过程。由于 PL 函数是在数据库服务器内部执行的,因此TRUSTED标记只应赋予那些不允许访问数据库服务器内部或文件系统的语言。语言PL/pgSQL, - PL/Tcl以及PL/Perl被认为是受信任的;而语言PL/TclU, - PL/PerlU以及PL/PythonU旨在提供无限制的功能,因此应被标记为受信任的。 + + 可选关键字TRUSTED表示,该语言不会授予用户原本不 + 具备的数据访问能力。受信任的语言是为普通数据库用户(即没有超级用户 + 权限的用户)设计的,并允许他们安全地创建函数和过程。由于 PL 函数是 + 在数据库服务器内部执行的,因此只有那些不允许访问数据库服务器内部或 + 文件系统的语言才应带有TRUSTED标记。 + PL/pgSQL、 + PL/Tcl以及 + PL/Perl被认为是受信任的;而 + PL/TclU、 + PL/PerlU以及 + PL/PythonU旨在提供无限制的功能,因此 + 应被标记为受信任的。 + @@ -146,19 +159,23 @@ CREATE FUNCTION plperl_validator(oid) RETURNS void AS - 下面的命令: + + 下面的命令: + CREATE TRUSTED LANGUAGE plperl HANDLER plperl_call_handler INLINE plperl_inline_handler VALIDATOR plperl_validator; -随后指定应为以下函数和过程调用前面声明的函数:其语言属性为plperl。 + + 随后定义了对于语言属性为plperl的函数和过程,应调 + 用前面声明的函数。 在默认的PostgreSQL安装中, PL/pgSQL语言的调用处理器会被构建并安装到 - library目录中;此外, + 目录中;此外, PL/pgSQL语言本身也安装在所有数据库中。如 果在构建时配置了Tcl支持,那么 PL/TclPL/TclU diff --git a/zh/12/xtypes.sgml b/zh/12/xtypes.sgml index 4c081819..90d2fc45 100644 --- a/zh/12/xtypes.sgml +++ b/zh/12/xtypes.sgml @@ -213,7 +213,7 @@ CREATE TYPE complex ( 如果数据类型的内部表示是可变长度的,则这种内部表示必须遵循可变长度数 据的标准布局:前四个字节必须是一个从不直接访问的char[4] 字段(惯例上命名为vl_len_)。必须使用 - SET_VARSIZE()宏在该字段中存储该值的总大小(包括 + SET_VARSIZE()宏在该字段中存储该 datum 的总大小(包括 长度字段本身),并使用VARSIZE()取回它。(这些宏 之所以存在,是因为长度字段可能会随平台不同而采用编码形式。) @@ -255,7 +255,7 @@ CREATE TYPE complex ( PG_DETOAST_DATUM_PACKED(通常通过定义 GETARG_DATATYPE_PP宏来隐藏),并使用 VARSIZE_ANY_EXHDRVARDATA_ANY - 宏访问一个可能采用打包形式的值。再次注意,即使数据类型定义指定了 + 宏访问一个可能采用打包形式的 datum。再次注意,即使数据类型定义指定了 对齐方式,这些宏返回的数据也不是对齐的。如果对齐很重要,就必须使用常 规的PG_DETOAST_DATUM接口。 @@ -266,8 +266,7 @@ CREATE TYPE complex ( 较旧的代码常把vl_len_声明为 int32字段,而不是char[4]字段。只要结构体定 义中还有其他至少按int32对齐的字段,这样做是可以的。但 - 在处理可能未对齐的值时使用这种结构体定义就很危险;编译器可能据此假定该 - 值实际上是对齐的,从而在对齐要求严格的体系结构上导致核心转储。 + 在处理可能未对齐的 datum 时使用这种结构体定义就很危险;编译器可能据此假定该 datum 实际上是对齐的,从而在对齐要求严格的体系结构上导致核心转储。 diff --git a/zh/13/adminpack.sgml b/zh/13/adminpack.sgml index 1e8d3cd9..663beeb2 100644 --- a/zh/13/adminpack.sgml +++ b/zh/13/adminpack.sgml @@ -94,14 +94,14 @@ pg_file_sync - pg_file_sync对由filename指定的文件或目录执行 fsync。失败时会抛出错误(例如,指定的文件不存在)。请注意,对此函数没有影响,因此即使刷新数据库文件失败,也不会引发 PANIC 级别的错误。 + pg_file_sync对由filename指定的文件或目录执行 fsync。失败时会抛出错误(例如,指定的文件不存在)。请注意,对此函数没有影响,因此即使数据库文件刷盘失败,也不会引发 PANIC 级别的错误。 pg_file_rename - pg_file_rename重命名文件。如果省略archivename或其值为 NULL,则它只是将oldname重命名为newname(后者必须尚不存在)。如果提供了archivename,它会先将newname重命名为archivename(后者必须尚不存在),然后再将oldname重命名为newname。如果第二个重命名步骤失败,它会在报告错误之前尝试将archivename再改回newname。成功时返回 true;如果源文件不存在或不可写,则返回 false;其他情况会抛出错误。 + pg_file_rename重命名文件。如果省略archivename或其值为空值,则它只是将oldname重命名为newname(后者必须尚不存在)。如果提供了archivename,它会先将newname重命名为archivename(后者必须尚不存在),然后再将oldname重命名为newname。如果第二个重命名步骤失败,它会在报告错误之前尝试将archivename再改回newname。成功时返回 true;如果源文件不存在或不可写,则返回 false;其他情况会抛出错误。 diff --git a/zh/13/amcheck.sgml b/zh/13/amcheck.sgml index 5ef93526..273cac39 100644 --- a/zh/13/amcheck.sgml +++ b/zh/13/amcheck.sgml @@ -183,7 +183,7 @@ SET client_min_messages = DEBUG1; 这也包括因操作系统排序规则的比较规则发生变化而引起的问题。 - 像text这类可排序类型的数据值之间的比较必须是不可变的 + 像text这类支持排序规则的类型的 datum 之间的比较必须是不可变的 (正如用于 B-树索引扫描的所有比较都必须不可变一样), 这就意味着操作系统排序规则绝不能发生变化。 虽然这种情况比较少见,但操作系统排序规则的更新确实可能导致此类问题。 @@ -257,12 +257,10 @@ SET client_min_messages = DEBUG1; 修复损坏 - 请注意,如果访问某个块时只是命中了共享缓冲区, - 那么amcheck检查的是验证时该页面在某个共享内存缓冲区中的表示。 - 因此,amcheck并不一定会检查验证时从文件系统读入的数据。 - 另请注意,当启用了校验和时,如果某个损坏块被读入缓冲区, - amcheck可能会因为校验和失败而引发错误。 - + amcheck报告的与损坏有关的错误绝不应被当作误报。 + amcheck会在那些按定义绝不应该发生的情况下抛出错误, + 因此通常需要对这类错误进行仔细分析。 + 对于amcheck检测到的问题,并不存在通用的修复方法。 应当查明导致不变式遭到破坏的根本原因。 diff --git a/zh/13/auth-delay.sgml b/zh/13/auth-delay.sgml index c0146092..652355f9 100644 --- a/zh/13/auth-delay.sgml +++ b/zh/13/auth-delay.sgml @@ -1,7 +1,7 @@ - auth_delay — 在认证失败时暂停 + auth_delay auth_delay diff --git a/zh/13/backup-manifest.sgml b/zh/13/backup-manifest.sgml index ce60d974..30e7752f 100644 --- a/zh/13/backup-manifest.sgml +++ b/zh/13/backup-manifest.sgml @@ -4,7 +4,7 @@ 备份清单格式 - Backup Manifest + 备份清单 @@ -68,9 +68,9 @@ 该键总是出现在备份清单文件的最后一行。其对应的值是此前所有行的 - SHA-256 校验和。这里使用固定的校验和方法,是为了让客户端能够对清单进 - 行增量解析。尽管 SHA-256 校验和明显比 CRC-32C 校验和开销更高,但清单 - 通常足够小,因此这些额外计算一般并不重要。 + SHA256 校验和。这里使用固定的校验和方法,是为了让客户端能够对清单进 + 行增量解析。尽管 SHA256 校验和明显比 CRC32C 校验和开销更高,但清单通 + 常足够小,因此这些额外计算一般并不重要。 @@ -167,7 +167,7 @@ Start-LSN - 为了使用该备份,必须在指定时间线上从这个 LSN 开始回放。该 LSN 按 + 为了使用该备份,必须在指定时间线上从这个 LSN 开始重放。该 LSN 按 PostgreSQL 通常使用的格式存储;也就是说, 它是一个字符串,由两段十六进制字符串构成,每段长度在 1 到 8 之间,并 以斜杠分隔。 @@ -179,7 +179,7 @@ End-LSN - 使用该备份时,指定时间线上的回放可结束于此 LSN,而这也是允许的最早 + 使用该备份时,指定时间线上的重放可结束于此 LSN,而这也是允许的最早 LSN。其存储格式与 Start-LSN 相同。 diff --git a/zh/13/backup.sgml b/zh/13/backup.sgml index d3bbdb3c..9e76158f 100644 --- a/zh/13/backup.sgml +++ b/zh/13/backup.sgml @@ -3,7 +3,7 @@ 备份和恢复 - backup + 备份 与任何保存重要数据的系统一样,PostgreSQL数据库也应定期备份。虽然其过程基本简单,但清楚理解其底层技术和前提假设非常重要。 @@ -53,9 +53,13 @@ pg_dump dbname > 恢复转储 - pg_dump 创建的文本文件供 psql 程序使用其默认设置读取。恢复文本转储的通用命令格式是 + + 由pg_dump创建的文本文件是为psql程序在默认设置下读取而设计的。恢复文本转储的一般命令形式是: + psql -X dbname < dumpfile -其中,dumpfile 是由 pg_dump 命令输出的文件。数据库 dbname 不会由此命令创建,因此必须自行基于 template0 创建它,再执行 psql(例如使用 createdb -T template0 dbname)。要确保 psql 使用其默认设置运行,请使用 )选项。psql 支持与 pg_dump 类似的选项,用于指定要连接的数据库服务器及所用的用户名。更多信息参见 参考页面。 + + 其中dumpfilepg_dump命令输出的文件。数据库dbname不会由该命令创建,因此你必须先从template0创建它,然后再执行psql(例如,使用createdb -T template0 dbname)。为确保psql以默认设置运行,请使用)选项。psql也支持与pg_dump类似的选项,用于指定要连接的数据库服务器以及所使用的用户名。更多信息参见参考页。 + 非文本格式的转储应当使用工具恢复。 @@ -65,11 +69,17 @@ psql -X dbname < - 默认情况下,psql 在遇到 SQL 错误后仍会继续执行脚本。可以在运行 psql 时设置 ON_ERROR_STOP 变量来改变这一行为,让 psql 在发生 SQL 错误时以退出状态 3 退出: + + 默认情况下,psql脚本在遇到 SQL 错误后仍会继续执行。你可能希望让psql在设置了ON_ERROR_STOP变量的情况下运行,以改变这一行为,并让psql在发生 SQL 错误时以退出状态码 3 退出: + psql -X --set ON_ERROR_STOP=on dbname < dumpfile -不论采用哪种方式,最终都只会得到部分恢复的数据库。另一种做法是指定将整个转储作为一个事务恢复,这样恢复要么全部完成,要么全部回滚。可通过将命令行选项 传递给 psql 来指定这种模式。使用该模式时要注意,即使是很小的错误,也可能使已经运行数小时的恢复全部回滚。不过,这可能仍比在部分恢复转储后手动清理复杂的数据库更好。 + + 无论采用上述哪种方式,你最终只会得到一个部分恢复的数据库。另一种做法是指定将整个转储作为单个事务恢复,这样恢复要么全部完成,要么全部回滚。可以通过把命令行选项传给psql来启用这种模式。使用这种模式时要注意,即便是一个很小的错误,也可能回滚一个已经运行了许多小时的恢复过程。不过,这仍可能比在部分恢复后手工清理一个复杂数据库更可取。 + - 利用 pg_dumppsql 向管道写入或从管道读取的能力,可以直接将数据库从一台服务器转储到另一台,例如: + + pg_dumppsql能够写入或读取管道,这使得可以把数据库直接从一台服务器转储到另一台服务器,例如: + pg_dump -h host1 dbname | psql -X -h host2 dbname @@ -89,12 +99,16 @@ pg_dump -h host1 dbname | 使用<application>pg_dumpall</application> - pg_dump 每次只转储一个数据库,不转储角色或表空间信息(因为它们属于整个集簇,而非某个数据库)。为了便于转储数据库集簇的全部内容,系统提供了 程序。pg_dumpall 会备份给定集簇中的每个数据库,并保留角色和表空间定义等集簇级数据。该命令的基本用法如下: + pg_dump一次只转储一个数据库,而且不会转储角色或表空间的信息(因为这些是整个集簇级别的,而不是每个数据库各自的)。为了方便地转储整个数据库集簇的全部内容,提供了程序。pg_dumpall会备份给定集簇中的每个数据库,并保留角色定义和表空间定义等集簇范围的数据。该命令的基本用法是: + pg_dumpall > dumpfile -要恢复生成的转储,可以使用 psql: + + 生成的转储可以用psql恢复: psql -X -f dumpfile postgres -(实际上,可以指定任何已存在的数据库名作为起点;但如果装载到空集簇中,通常应使用 postgres。)恢复 pg_dumpall 转储时,必须具有数据库超级用户权限,因为恢复角色和表空间信息需要这些权限。如果使用了表空间,请确保转储中的表空间路径适合新的安装环境。 + + (实际上,可以指定任意一个现有数据库名作为起点,但如果要装载到一个空集簇中,通常应使用postgres。)恢复pg_dumpall转储时始终需要数据库超级用户权限,因为恢复角色和表空间信息必须使用该权限。如果使用了表空间,请确保转储中的表空间路径适合新的安装。 + pg_dumpall的工作方式是先发出重新创建角色、表空间和空数据库的命令,然后针对每个数据库调用pg_dump。这意味着每个数据库本身都是内部一致的,但不同数据库的快照并不同步。 @@ -180,7 +194,7 @@ pg_restore -d dbname - 对于非常大的数据库,你可能需要把split与前两种方法之一结合使用。 + 对于非常大的数据库,你可能需要把split与另外两种方法之一结合使用。 @@ -236,7 +250,7 @@ tar -cf backup.tar /usr/local/pgsql/data - 如果无法获得同时的快照,一种选择是将数据库服务器关闭足够长的时间,以建立所有冻结快照。另一种选择是执行持续归档基础备份(),因为这种备份不受备份期间文件系统变化的影响。这要求只在备份过程中启用持续归档;恢复则使用持续归档恢复()。 + 如果无法获得同时的快照,一种选择是将数据库服务器关闭足够长的时间,以建立所有冻结快照。另一种选择是执行持续归档基础备份(),因为这种备份不受备份期间文件系统变化的影响。这种方法只需在备份期间启用持续归档;恢复则使用持续归档恢复()。 @@ -252,11 +266,11 @@ tar -cf backup.tar /usr/local/pgsql/data 持续归档和时间点恢复(PITR) - continuous archiving + 持续归档 - point-in-time recovery + 时间点恢复 @@ -296,7 +310,7 @@ tar -cf backup.tar /usr/local/pgsql/data - 和普通文件系统备份技术一样,这种方法只能支持整个数据库集簇的恢复,而不支持其中某个子集的恢复。此外,它需要大量归档存储:基础备份可能很庞大,繁忙系统也会产生大量必须归档的 WAL 流量。尽管如此,在很多需要高可靠性的场景中,它仍是首选的备份技术。 + 和普通文件系统备份技术一样,这种方法只能支持整个数据库集簇的恢复,而不支持其中某个子集的恢复。此外,它需要大量归档存储:基础备份可能很庞大,繁忙系统也会产生许多兆字节的、必须归档的 WAL 流量。尽管如此,在很多需要高可靠性的场景中,它仍是首选的备份技术。 @@ -311,7 +325,7 @@ tar -cf backup.tar /usr/local/pgsql/data - 在归档 WAL 数据时,我们需要在每个段文件写满后捕获其内容,并在该段文件被回收重用之前把数据保存到某处。根据应用场景和可用硬件的不同,把数据保存到某处可以有很多不同的方法:可以把段文件复制到另一台机器上的 NFS 挂载目录,把它们写到磁带机中(确保你有办法识别每个文件的原始文件名),把它们批量打包后刻录到 CD 上,或者采用完全不同的方式。为了给数据库管理员提供灵活性,PostgreSQL尽量不对归档方式作任何假设。相反,PostgreSQL允许管理员指定一个 shell 命令或一个归档库,以便把已完成的段文件复制到它应去的地方。这既可以只是一个使用cp的 shell 命令,也可以调用一个复杂的 C 函数,全由你决定。 + 在归档 WAL 数据时,我们需要在每个段文件写满后捕获其内容,并在该段文件被回收重用之前把数据保存到某处。根据应用场景和可用硬件的不同,把数据保存到某处可以有很多不同的方法:可以把段文件复制到另一台机器上的 NFS 挂载目录,把它们写到磁带机中(确保你有办法识别每个文件的原始文件名),把它们批量打包后刻录到 CD 上,或者采用完全不同的方式。为了给数据库管理员提供灵活性,PostgreSQL尽量不对归档方式作任何假设。相反,PostgreSQL允许管理员指定一个 shell 命令,以便把已完成的段文件复制到它应去的地方。该命令可以只是一次简单的cp调用,也可以调用一个复杂的 shell 脚本,全由你决定。 要启用 WAL 归档,请将 配置参数设为 replica 或更高值,将 设为 on,并在 通常应将归档命令设计为拒绝覆盖任何已存在的归档文件。这是一项重要的安全保护措施,能在管理员操作失误时(例如将两台不同服务器的输出发送到同一归档目录)维护归档的完整性。 - 建议测试所拟定的归档命令,确保它确实不会覆盖已有文件,并且在这种情况下返回非零状态。上面给出的 Unix 示例命令通过单独加入一个test步骤,避免覆盖已有归档。在某些 Unix 平台上,cp提供了诸如之类的开关,也可以更简洁地实现同样目的,但在你确认它会返回正确的退出状态之前,不应依赖这些开关。(尤其是 GNU cp在使用且目标文件已存在时会返回状态零,这不是我们想要的行为。) + 建议测试所拟定的归档命令,确保它确实不会覆盖已有文件,并且在这种情况下返回非零状态。上面给出的 Unix 示例命令通过单独加入一个test步骤,确保这两点。在某些 Unix 平台上,cp提供了诸如之类的开关,也可以更简洁地实现同样目的,但在你确认它会返回正确的退出状态之前,不应依赖这些开关。(尤其是 GNU cp在使用且目标文件已存在时会返回状态零,这不是我们想要的行为。) - 在设计归档方案时,请考虑如果归档命令或归档库因为某些环节需要操作员干预,或者归档空间耗尽而反复失败,会发生什么。例如,如果你在没有自动换带器的情况下向磁带写入数据,那么磁带满了以后,在更换磁带之前将无法继续归档。你应确保任何错误情况或对人工操作员的请求都能得到适当报告,以便问题能够比较快地解决。在问题解决之前,pg_wal/目录会继续堆积 WAL 段文件。(如果包含pg_wal/的文件系统被写满,PostgreSQL将执行 PANIC 关闭。不会丢失已提交的事务,但在释放出一些空间之前,数据库会一直离线。) + 在设计归档方案时,请考虑如果归档命令因为某些环节需要操作员干预,或者归档空间耗尽而反复失败,会发生什么。例如,如果你在没有自动换带器的情况下向磁带写入数据,那么磁带满了以后,在更换磁带之前将无法继续归档。你应确保任何错误情况或对人工操作员的请求都能得到适当报告,以便问题能够比较快地解决。在问题解决之前,pg_wal/目录会继续堆积 WAL 段文件。(如果包含pg_wal/的文件系统被写满,PostgreSQL将执行 PANIC 关闭。不会丢失已提交的事务,但在释放出一些空间之前,数据库会一直离线。) - 归档命令或归档库的速度并不重要,只要它能跟上服务器生成 WAL 数据的平均速度即可。即使归档过程稍有滞后,正常操作也会继续。如果归档明显落后,灾难发生时可能丢失的数据量就会增加。这还意味着pg_wal/目录会包含大量尚未归档的段文件,最终可能耗尽可用磁盘空间。建议监控归档过程,确保它按你的预期工作。 + 归档命令的速度并不重要,只要它能跟上服务器生成 WAL 数据的平均速度即可。即使归档过程稍有滞后,正常操作也会继续。如果归档明显落后,灾难发生时可能丢失的数据量就会增加。这还意味着pg_wal/目录会包含大量尚未归档的段文件,最终可能耗尽可用磁盘空间。建议监控归档过程,确保它按你的预期工作。 - 在编写归档命令或归档库时,应假定待归档文件名最长可达 64 个字符,并且可以包含 ASCII 字母、数字和点号的任意组合。无需保留原始相对路径(%p),但必须保留文件名(%f)。 + 在编写归档命令时,应假定待归档文件名最长可达 64 个字符,并且可以包含 ASCII 字母、数字和点号的任意组合。无需保留原始相对路径(%p),但必须保留文件名(%f)。 注意,虽然 WAL 归档允许你恢复对PostgreSQL数据库中数据所做的任何修改,但它不会恢复对配置文件(即postgresql.confpg_hba.confpg_ident.conf)的修改,因为这些文件是手工编辑的,而不是通过 SQL 操作修改的。你可能希望把配置文件放在常规文件系统备份过程能够覆盖的位置。关于如何重定位配置文件,见 - 归档命令只会在已完成的 WAL 段上调用。因此,如果服务器产生的 WAL 流量很小(或者存在这样的低谷期),事务完成到其被安全写入归档存储之间可能会有很长延迟。为了限制未归档数据的最长滞留时间,可以设置 ,强制服务器至少每隔这么长时间切换到一个新的 WAL 段文件。注意,由强制切换而提前归档的文件长度仍与装满的文件相同。因此,把 archive_timeout 设得很短并不明智,这会使归档存储膨胀。将 archive_timeout 设为大约一分钟通常是合理的。 + + 归档命令只会针对已完成的 WAL 段调用。因此,如果服务器产生的 WAL 流量很小(或者存在低谷期),事务完成到其被安全写入归档存储之间可能会有很长延迟。为了限制未归档数据可能有多旧,你可以设置,使服务器强制切换到新 WAL 段文件的间隔不超过这个值。注意,由强制切换而提前归档的文件长度仍与装满的文件相同。因此,把archive_timeout设得很短并不明智,这会使归档存储膨胀。archive_timeout设为大约 1 分钟通常是合理的。 + 此外,如果你希望确保一个刚刚完成的事务尽快被归档,可以使用pg_switch_wal手工强制一次段切换。其他与 WAL 管理相关的实用函数列在中。 - 当wal_levelminimal时,某些 SQL 命令会像中所述那样被优化为避免 WAL 记录。如果在执行这些语句期间启用了归档或流复制,WAL 将不包含归档恢复所需的足够信息。(崩溃恢复不受影响。)因此,wal_level只能在服务器启动时更改。然而,archive_command可以通过重新加载配置文件来更改。如果你通过 shell 进行归档并希望暂时停止归档,一种办法是将archive_command设置为空字符串('')。这会导致 WAL 文件在pg_wal/中累积,直到重新建立可用的archive_command。 + 当wal_levelminimal时,某些 SQL 命令会像中所述那样被优化为避免 WAL 记录。如果在执行这些语句期间启用了归档或流复制,WAL 将不包含归档恢复所需的足够信息。(崩溃恢复不受影响。)因此,wal_level只能在服务器启动时更改。然而,archive_command可以通过重新加载配置文件来更改。如果你希望暂时停止归档,一种办法是将archive_command设置为空字符串('')。这会导致 WAL 文件在pg_wal/中累积,直到重新建立可用的archive_command @@ -385,7 +401,7 @@ test ! -f /mnt/server/archivedir/00000001000000A900000065 && cp pg_wal/0 - 使用低级接口进行基础备份 + 使用低级 API 进行基础备份 使用低级 API 制作基础备份的过程,比 方法多几个步骤,但相对简单。务必按顺序执行这些步骤,并在继续下一步之前确认当前步骤成功。 低级基础备份可以采用非排他或排他方式。建议使用非排他方式;排他方式已弃用,最终将被移除。 @@ -512,7 +528,9 @@ SELECT pg_stop_backup(); 使用持续归档备份进行恢复 - 如果最坏的情况已经发生,需要从备份恢复,请按以下流程操作: + + 现在,最坏的情况发生了,你需要通过备份进行恢复。步骤如下: + 如果服务器仍在运行,就先停止它。 @@ -530,7 +548,7 @@ SELECT pg_stop_backup(); - 如果你正在恢复完整备份,可以把数据库文件直接恢复到目标目录中。务必确保它们以正确的所有者(数据库系统用户,而不是root!)和正确的权限恢复。如果使用了表空间,还应验证pg_tblspc/中的符号链接是否已正确恢复。 + 从文件系统备份中恢复数据库文件。务必确保它们以正确的所有者(数据库系统用户,而不是root!)和正确的权限恢复。如果使用了表空间,还应验证pg_tblspc/中的符号链接是否已正确恢复。 @@ -561,16 +579,16 @@ SELECT pg_stop_backup(); - 整个过程的关键,是设置恢复配置,说明希望如何恢复,以及恢复到什么位置。必须指定的设置是 restore_command,它告诉 PostgreSQL 如何获取已归档的 WAL 段。与 archive_command 一样,它是一个 shell 命令字符串,可以包含 %f,该标记会被替换为所需日志文件的名称;还可以包含 %p,该标记会被替换为日志文件要复制到的路径名。(路径名相对于当前工作目录,即集簇的数据目录。)使用 %% 可以在命令中嵌入实际的 % 字符。最简单的可用命令类似于: + 整个过程的关键,是设置恢复配置,说明希望如何恢复,以及恢复到什么位置。必须指定的设置是 restore_command,它告诉 PostgreSQL 如何获取已归档的 WAL 段文件。与 archive_command 一样,它是一个 shell 命令字符串,可以包含 %f,该标记会被替换为所需日志文件的名称;还可以包含 %p,该标记会被替换为日志文件要复制到的路径名。(路径名相对于当前工作目录,即集簇的数据目录。)使用 %% 可以在命令中嵌入实际的 % 字符。最简单的可用命令类似于: restore_command = 'cp /mnt/server/archivedir/%f %p' 这会复制先前归档的 WAL 段,来源目录为 /mnt/server/archivedir。当然,也可以使用复杂得多的命令,甚至可以使用要求操作人员挂载相应磁带的 shell 脚本。 - 重要的是,该命令在失败时必须返回非零退出状态。系统调用该命令来请求归档中不存在的文件;遇到这种情况时,它就应返回非零值。这不是一种错误情况。例外是,如果该命令被信号终止(用于数据库服务器关闭的SIGTERM除外),或者因 shell 错误(如命令未找到)而失败,那么恢复将中止,服务器也不会启动。 + 重要的是,该命令在失败时必须返回非零退出状态。系统调用该命令来请求归档中不存在的文件;遇到这种情况时,它必须返回非零值。这不是一种错误情况。例外是,如果该命令被信号终止(用于数据库服务器关闭的SIGTERM除外),或者因 shell 错误(如命令未找到)而失败,那么恢复将中止,服务器也不会启动。 - 被请求的文件并不全都是 WAL 段文件;你还应预期会收到对带有.history后缀文件的请求。另外请注意,%p路径的基本文件名会与%f不同;不要指望它们可以互换使用。 + 被请求的文件并不全都是 WAL 段文件;你还应预期会收到对带有.history后缀文件的请求。另外请注意,%p路径的文件名部分会与%f不同;不要指望它们可以互换使用。 @@ -578,16 +596,16 @@ restore_command = 'cp /mnt/server/archivedir/%f %p' - 通常,恢复会处理完所有可用的 WAL 段,从而把数据库恢复到当前时间点(或者在可用 WAL 段所允许的情况下尽可能接近当前时间点)。因此,一次正常恢复通常会以一条file not found消息结束,具体错误文本取决于你选择的restore_command。在恢复开始时,你也可能看到一条针对类似00000001.history文件的错误消息。这同样是正常的,在简单恢复场景中并不表示有问题;相关讨论见。 + 通常,恢复会处理完所有可用的 WAL 段,从而把数据库恢复到当前时间点(或者在可用 WAL 段所允许的情况下尽可能接近当前时间点)。因此,一次正常恢复会以一条file not found消息结束,具体错误文本取决于你选择的restore_command。在恢复开始时,你也可能看到一条针对类似00000001.history文件的错误消息。这同样是正常的,在简单恢复场景中并不表示有问题;相关讨论见 - 如果你希望恢复到过去的某个时间点(例如恢复到那位初级 DBA 删掉你的主事务表之前),只需指定所需的停止点即可。这个停止点也称为恢复目标,可以通过日期/时间、命名恢复点或者某个特定事务 ID 完成时刻来指定。在目前的实现下,只有日期/时间和命名恢复点这两种方式真正比较实用,因为没有工具能够帮助你足够准确地识别应使用哪个事务 ID。 + 如果你希望恢复到过去的某个时间点(例如恢复到那位初级 DBA 删掉你的主事务表之前),只需指定所需的停止点即可。这个停止点也称为恢复目标,可以通过日期/时间、命名恢复点或者某个特定事务 ID 完成时刻来指定。在撰写本文时,只有日期/时间和命名恢复点这两种方式真正比较实用,因为没有工具能够帮助你足够准确地识别应使用哪个事务 ID。 - 停止点必须晚于基础备份的结束时间,也就是pg_stop_backup的结束时间。你不能用某次基础备份恢复到该备份仍在进行中的时间点。(若要恢复到这样的时间点,必须回到更早的一次基础备份,再从那里向前滚动。) + 停止点必须晚于基础备份的结束时间,也就是pg_stop_backup的结束时间。你不能用某次基础备份恢复到该备份仍在进行中的时间点。(若要恢复到这样的时间点,必须回到更早的一次基础备份,再从那里向前重放日志。) @@ -601,14 +619,16 @@ restore_command = 'cp /mnt/server/archivedir/%f %p' 时间线 - timelines + 时间线 能够将数据库恢复到过去某个时间点,也会带来一些类似科幻故事中时间旅行和平行宇宙的复杂情况。例如,假设在数据库原来的历史中,你在周二下午 5:15 删除了一张重要的表,直到周三中午才发现错误。你从容地取出备份,将数据库恢复到周二下午 5:14,然后重新投入运行。在数据库宇宙的这段历史中,你从未删除过那张表。但假设你后来发现这样做不太合适,希望回到原来历史中的周三上午某个时刻。如果数据库恢复运行后覆盖了通往该时刻所需的某些 WAL 段文件,就无法回去了。因此,为了避免这种情况,需要区分时间点恢复后产生的一系列 WAL 记录与数据库原来历史中产生的记录。 为解决这一问题,PostgreSQL 引入了时间线的概念。每当归档恢复完成,系统都会创建一条新时间线,用于标识此次恢复之后产生的一系列 WAL 记录。时间线 ID 是 WAL 段文件名的一部分,因此新时间线不会覆盖旧时间线产生的 WAL 数据。实际上,可以归档许多不同的时间线。这个功能看似没什么用,却常常能救急。比如,你不能确定应该恢复到哪个时间点,需要反复尝试时间点恢复,直到找到脱离旧历史的最佳分支点。没有时间线,这个过程很快就会乱得无法管理。有了时间线,就可以恢复到任何先前的状态,包括早先已放弃的时间线分支中的状态。 - 每次创建新时间线时,PostgreSQL 都会创建一个时间线历史文件,记录它从哪条时间线、在何时分支出来。从包含多条时间线的归档中恢复时,系统需要这些历史文件来选择正确的 WAL 段文件。因此,历史文件与 WAL 段文件一样,也会归档到 WAL 归档区。历史文件只是很小的文本文件,长期保留成本很低,也很合适(不像体积很大的段文件)。如果愿意,可以在历史文件中添加注释,记录这条时间线是如何创建的,以及为什么创建它。当反复试验产生了许多交错的时间线时,这些注释会格外有用。 + + 每当创建一条新的时间线时,PostgreSQL都会创建一个时间线历史文件,记录它是从哪条时间线、在何时分叉出来的。当从包含多条时间线的归档中恢复时,这些历史文件对于系统选取正确的 WAL 段文件是必需的。因此,它们会像 WAL 段文件一样被归档到 WAL 归档区域。历史文件只是很小的文本文件,因此长期保存它们既便宜也合适(而段文件通常很大)。如果你愿意,还可以在历史文件中加入注释,记录创建这条时间线的方式和原因。当你因实验而积累出一批错综复杂的时间线时,这类注释会特别有价值。 + 默认的恢复行为是恢复到归档中找到的最新时间线。如果希望恢复到制作基础备份时的当前时间线,或者某条特定的子时间线(即希望返回到一次恢复尝试之后产生的某个状态),需要在 中指定 current 或目标时间线 ID。不能恢复到在基础备份之前就已分支出去的时间线。 @@ -621,14 +641,14 @@ restore_command = 'cp /mnt/server/archivedir/%f %p' - 单机热备份 + 独立热备份 - 可以利用PostgreSQL的备份设施生成单机热备份。这些备份不能用于时间点恢复,但它们的制作和恢复通常都比pg_dump转储快得多。(它们也比pg_dump转储大得多,因此在某些情况下速度优势可能会被抵消。) + 可以利用PostgreSQL的备份设施生成独立热备份。这些备份不能用于时间点恢复,但它们的制作和恢复通常都比pg_dump转储快得多。(它们也比pg_dump转储大得多,因此在某些情况下速度优势可能会被抵消。) - 和基础备份一样,生成单机热备份最简单的方法是使用工具。如果在调用它时包含-X参数,使用该备份所需的全部预写式日志都会自动包含在备份中,恢复该备份时也不需要额外动作。 + 和基础备份一样,生成独立热备份最简单的方法是使用工具。如果在调用它时包含-X参数,使用该备份所需的全部预写式日志都会自动包含在备份中,恢复该备份时也不需要额外动作。 如果复制备份文件时需要更大的灵活性,也可以使用更低级的流程制作独立热备份。要准备低级独立热备份,请确保将 wal_level 设为 replica 或更高值,将 archive_mode 设为 on,并配置一个 archive_command,使其仅在开关文件存在时执行归档。例如: @@ -669,7 +689,7 @@ archive_command = 'local_backup_script.sh "%p" "%f"' - 脚本中可能需要解决的需求示例包括: + 可以在脚本中处理的需求示例包括: @@ -678,7 +698,7 @@ archive_command = 'local_backup_script.sh "%p" "%f"' - 把 WAL 文件成批处理,使其每三个小时传输一次,而不是每生成一个就传一次 + 把 WAL 文件成批处理,使其每三个小时传输一次,而不是每次只传输一个 @@ -705,7 +725,10 @@ archive_command = 'local_backup_script.sh "%p" "%f"' 注意事项 - 撰写本文时,连续归档技术还有几个限制。这些限制可能会在未来版本中消除: + + 在撰写本文时,持续归档技术还存在若干局限。这些问题很可能会在未来版本中得到修复: + + 如果在进行基础备份时执行了命令,而该CREATE DATABASE所复制的模板数据库又在基础备份尚未结束时被修改,那么恢复时可能会把这些修改也传播到新建数据库中。这当然并不理想。为避免这种风险,最好在进行基础备份时不要修改任何模板数据库。 diff --git a/zh/13/brin.sgml b/zh/13/brin.sgml index 3bd5d8b9..2cf0e4a9 100644 --- a/zh/13/brin.sgml +++ b/zh/13/brin.sgml @@ -4,7 +4,7 @@ BRIN 索引 - index + 索引 BRIN @@ -25,8 +25,7 @@ - 如果索引中存储的摘要信息与查询条件相一致BRIN - 索引就可以通过常规位图索引扫描来满足查询,并返回每个范围内所有页上的全部元组。 + BRIN 索引可以通过常规位图索引扫描来满足查询;对于每个范围,如果索引中存储的摘要信息与查询条件相一致,就会返回该范围内所有页上的全部元组。 查询执行器负责重新检查这些元组,并丢弃不匹配查询条件的元组 — 换句话说,这些索引是有损的。 由于 BRIN 索引非常小,与顺序扫描相比,扫描索引只会带来很小的额外开销, 但可以避免扫描那些已知不包含匹配元组的大块表数据。 @@ -83,7 +82,7 @@ 当启用自动摘要时,一旦检测到向下一个块范围第一页的第一项执行了插入, - 就会向 autovacuum 发送请求,要求对该块范围执行定向摘要。 + 就会向 autovacuum 发送请求,要求对前一个块范围执行定向摘要。 该请求会在同一数据库中的某个 autovacuum 工作进程下一次结束运行时得到处理。 如果请求队列已满,该请求就不会被记录,并会向服务器日志发送一条消息: @@ -329,7 +328,7 @@ LOG: request for BRIN range summarization for index "brin_wi_idx" page 128 was range_inclusion_ops - any range type + 任意范围类型 << &< && &> >> @> <@ -|- = < <= = > >= @@ -454,20 +453,25 @@ LOG: request for BRIN range summarization for index "brin_wi_idx" page 128 was BrinOpcInfo *opcInfo(Oid type_oid) - 返回索引列摘要数据的内部信息。返回值必须指向一个由 palloc 分配的BrinOpcInfo,其定义如下: + + 返回被索引列的摘要数据的内部信息。返回值必须指向一个用 palloc 分配的 + BrinOpcInfo,其定义如下: + typedef struct BrinOpcInfo { - /* Number of columns stored in an index column of this opclass */ + /* 此操作符类在一个索引列中存储的列数 */ uint16 oi_nstored; - /* Opaque pointer for the opclass' private use */ + /* 供操作符类私有使用的不透明指针 */ void *oi_opaque; - /* Type cache entries of the stored columns */ + /* 所存储列的类型缓存条目 */ TypeCacheEntry *oi_typcache[FLEXIBLE_ARRAY_MEMBER]; } BrinOpcInfo; - BrinOpcInfo.oi_opaque可供操作符类函数使用,在索引扫描期间于各支持函数之间传递信息。 + BrinOpcInfo.oi_opaque + 可供操作符类例程在索引扫描期间于各个支持函数之间传递信息。 + @@ -654,62 +658,62 @@ typedef struct BrinOpcInfo 操作符策略 1 - left-of 操作符 + 位于左侧的操作符 操作符策略 4 操作符策略 2 - does-not-extend-to-the-right-of 操作符 + 不延伸到右侧的操作符 操作符策略 5 操作符策略 3 - overlaps 操作符 + 重叠操作符 操作符策略 4 - does-not-extend-to-the-left-of 操作符 + 不延伸到左侧的操作符 操作符策略 1 操作符策略 5 - right-of 操作符 + 位于右侧的操作符 操作符策略 2 - 操作符策略 6, 18 - same-as-or-equal-to 操作符 + 操作符策略 6、18 + 相同或等于操作符 操作符策略 7 - 操作符策略 7, 13, 16, 24, 25 - contains-or-equal-to 操作符 + 操作符策略 7、13、16、24、25 + 包含或等于操作符 - 操作符策略 8, 14, 26, 27 - is-contained-by-or-equal-to 操作符 + 操作符策略 8、14、26、27 + 被包含或等于操作符 操作符策略 3 操作符策略 9 - does-not-extend-above 操作符 + 不延伸到上方的操作符 操作符策略 11 操作符策略 10 - is-below 操作符 + 位于下方的操作符 操作符策略 12 操作符策略 11 - is-above 操作符 + 位于上方的操作符 操作符策略 9 操作符策略 12 - does-not-extend-below 操作符 + 不延伸到下方的操作符 操作符策略 10 diff --git a/zh/13/btree.sgml b/zh/13/btree.sgml index a21e9121..c4180cc2 100644 --- a/zh/13/btree.sgml +++ b/zh/13/btree.sgml @@ -4,7 +4,7 @@ B-树索引 - index + 索引 B-树 @@ -18,10 +18,10 @@ - 由于每个 B-树 操作符类都会为其数据类型施加一种排序顺序,B-树 + 由于每个 B-树操作符类都会为其数据类型施加一种排序顺序,B-树 操作符类(更准确地说,是操作符族)已经成为 PostgreSQL 用来统一表示和理解排序语义的方式。因此,它们具备了一些超出单纯支持 - B-树 索引所需范围的特性,系统中某些与 btree AM + B-树索引所需范围的特性,系统中某些与 B-树 AM 相距甚远的部分也会利用它们。 @@ -55,7 +55,7 @@ - = 操作符必须是一种等价关系;也就是说,对于该数据类型的所有非空值 + = 操作符必须是一种等价关系;也就是说,对于该数据类型的所有非 null 值 ABC: @@ -93,7 +93,7 @@ - < 操作符必须是一种强排序关系;也就是说,对于所有非空值 + < 操作符必须是一种强排序关系;也就是说,对于所有非 null 值 ABC: @@ -123,7 +123,7 @@ - 此外,该顺序还是全序的;也就是说,对于所有非空值 + 此外,该顺序还是全序的;也就是说,对于所有非 null 值 AB: @@ -177,18 +177,18 @@ B-树支持函数 - 如所示,btree 定义了一个必需和五个可选的支持函数。六个用户定义的方法如下: + 如所示,B-树定义了一个必需和四个可选的支持函数。五个用户定义的方法如下: order - 对于 B-树 操作符族为其提供比较操作符的每一种数据类型组合,都必须提供一个比较支持函数。该函数在 + 对于 B-树操作符族为其提供比较操作符的每一种数据类型组合,都必须提供一个比较支持函数。该函数在 pg_amproc 中注册,支持函数编号为 1,并且 amproclefttype/amprocrighttype 要等于该比较的左右数据类型(也就是与匹配操作符在 - pg_amop 中注册时相同的数据类型)。比较函数必须接受两个非空值 + pg_amop 中注册时相同的数据类型)。比较函数必须接受两个非 null 值 AB,并返回一个 int32 值,其值为 < 0、 @@ -197,12 +197,12 @@ < BA = BA - > B。不允许返回空值:该数据类型的所有值都必须可比较。示例见 + > B。不允许返回 null:该数据类型的所有值都必须可比较。示例见 src/backend/access/nbtree/nbtcompare.c - 如果参与比较的值属于可排序数据类型,则会通过标准的 + 如果参与比较的值属于支持排序规则的数据类型,则会通过标准的 PG_GET_COLLATION() 机制,把适当的排序规则 OID 传递给比较支持函数。 @@ -223,11 +223,11 @@ in_range - in_range support functions + in_range 支持函数 - support functions + 支持函数 in_range @@ -242,14 +242,35 @@ offset 值进行加减。 - in_range函数必须具有以下签名: + + in_range 函数必须具有如下签名: + in_range(val type1, base type1, offset type2, sub bool, less bool) returns bool - valbase必须具有相同的类型,且该类型是操作符族支持的类型之一(即该操作符族为其提供排序顺序的类型)。但是,offset可以具有不同的类型,甚至可以是操作符族在其他方面不支持的类型。例如,内置的time_ops操作符族提供一个in_range函数,其中offset的类型为interval。操作符族可以提供in_range函数,用于其支持的任意类型与一种或多种offset类型的组合。每个in_range函数都应登记在pg_amproc中,并使amproclefttype等于type1amprocrighttype等于type2。 + val 和 + base 必须具有相同类型,并且该类型必须是操作符族支持的类型之一(也就是该族为其提供排序的一种类型)。不过, + offset + 可以是另一种类型,而该类型甚至可能不被该族以其他方式支持。例如,内置的 + time_ops 族就提供了一个 in_range + 函数,其 offset 的类型为 + interval。一个族可以提供 in_range + 函数,分别对应其支持的任意类型以及一个或多个 + offset 类型。每个 + in_range 函数都应在 + pg_amproc 中登记,其中 + amproclefttype 等于 + type1,而 + amprocrighttype 等于 + type2 - 对于in_range函数,其核心语义取决于两个布尔标志参数。它应当先对baseoffset做加法或减法,再把val与结果比较,具体如下: + + in_range 函数的核心语义取决于这两个布尔 + 标志参数。它应当先对 base 与 + offset 做加法或减法,再把 + val 与结果比较,具体如下: + 如果 !sub 且 @@ -286,7 +307,15 @@ returns bool offset) - 在此之前,函数应检查offset的符号:如果它小于零,就引发错误ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE(22013),错误文本类似于invalid preceding or following size in window function。(这是 SQL 标准的要求,尽管非标准操作符族或许会选择忽略这一限制,因为从语义上看似乎并没有太大必要。)把这个要求委托给in_range函数,是为了让核心代码无需理解小于零对于某个特定数据类型究竟意味着什么。 + + 在此之前,函数应检查 offset 的符号:如果它小于零,就引发错误 + ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE + (22013),错误文本类似于 + invalid preceding or following size in window function。 + (这是 SQL 标准的要求,尽管非标准操作符族或许会选择忽略这一限制,因为从语义上看似乎并没有太大必要。) + 把这个要求委托给 in_range + 函数,是为了让核心代码无需理解对于某个特定数据类型来说小于零究竟意味着什么。 + 另外还希望 in_range 函数在可行时避免因为 @@ -299,7 +328,11 @@ returns bool in_range 的结果与该操作符族的正常排序顺序一致。 - in_range函数的结果必须与操作符族规定的排序顺序一致。具体而言,对于任意固定的offsetsub值,应满足以下条件: + + in_range 函数的结果必须与操作符族施加的排序顺序保持一致。更精确地说,给定任意固定的 + offset 和 + sub 值,则: + 如果 in_range 在 @@ -344,10 +377,13 @@ returns bool val 相同,它也必须返回假。 - less= false 时,类似的结论成立,但条件相反。 + + 当 less = false + 时,也有条件相反的对应陈述成立。 + - 如果被排序的类型(type1)属于可排序数据类型,则会通过标准的 + 如果被排序的类型(type1)属于支持排序规则的数据类型,则会通过标准的 PG_GET_COLLATION() 机制,把适当的排序规则 OID 传递给 in_range 函数。 @@ -367,14 +403,20 @@ returns bool 4。这些函数允许核心代码判断何时可以安全地应用 B-树 去重优化。目前, equalimage 函数只会在构建或重建索引时被调用。 - equalimage函数必须具有以下签名: + + equalimage 函数必须具有如下签名: + equalimage(opcintype oid) returns bool -返回值是关于操作符类和排序规则的静态信息。返回true表示可以保证:该操作符类的order函数仅在以下情况下返回0参数相等):其AB参数还必须能够互换,且不会损失任何语义信息。若未注册equalimage函数,或者返回false,则表示不能假定此条件成立。 + + 返回值是关于某个操作符类及其排序规则的静态信息。返回 true 表示可以保证:该操作符类的 order 函数只有在其 AB 参数也能够互换而不损失任何语义信息时,才会返回 0参数相等)。如果未注册 + equalimage 函数,或其返回 + false,就表示不能假定该条件成立。 + opcintype 参数是该操作符类所索引数据类型的 pg_type.oid。这只是为了方便在不同操作符类之间复用同一个底层 equalimage 函数。如果 - opcintype 是可排序数据类型,则会通过标准的 + opcintype 是支持排序规则的数据类型,则会通过标准的 PG_GET_COLLATION() 机制,把适当的排序规则 OID 传递给 equalimage 函数。 @@ -406,7 +448,7 @@ equalimage(opcintype oid) returns bool 发行版中包含的操作符类遵循的惯例是:注册一个现成的通用 equalimage 函数。大多数操作符类注册 btequalimage(),这表示去重在无条件下都是安全的。像 - text 这样可排序数据类型的操作符类会注册 + text 这样支持排序规则的数据类型的操作符类会注册 btvarstrequalimage(),这表示在确定性排序规则下去重是安全的。第三方扩展的最佳实践则是注册它们自己的自定义函数,以保留控制权。 @@ -465,7 +507,7 @@ options(relopts local_relopts *) returns 去重通过周期性地把一组组重复元组合并起来,为每一组形成一个 - posting list 元组。在这种表示中,列键值只出现一次,后面跟着一个排好序的 + 倒排列表 元组。在这种表示中,列键值只出现一次,后面跟着一个排好序的 TID 数组,指向表中的各行。这能显著减小那些每个值(或每一种不同列值组合)平均会出现多次的索引的存储大小。查询延迟可能显著降低,整体查询吞吐量也可能显著提升,例行索引清理的开销同样可能显著减少。 @@ -479,14 +521,14 @@ options(relopts local_relopts *) returns 去重过程是惰性发生的:当插入一个放不进现有叶页的新项时,就会进行去重。这会防止(或者至少推迟)叶页拆分。与 - GIN 的 posting list 元组不同,B-树的 posting list - 元组不需要在每次插入新的重复项时都扩展;它们只是叶页原始逻辑内容的一种替代物理表示。这种设计优先考虑混合读写工作负载下的一致性能。大多数客户端应用至少都能从去重中获得适度的性能收益。去重默认启用。 + GIN 的倒排列表元组不同,B-树的倒排列表 + 元组不需要在每次插入新的重复项时都扩展;它们只是叶页原始逻辑内容的一种替代物理表示。这种设计优先考虑混合读写工作负载下的稳定性能。大多数客户端应用至少都能从去重中获得适度的性能收益。去重默认启用。 CREATE INDEXREINDEX - 都会应用去重来创建 posting list - 元组,只是两者采用的策略略有不同。对于从表中取出的已排序输入中遇到的每一组普通重复元组,都会在被加入当前待写入叶页之前先合并成一个 - posting list 元组。每个 posting list 元组都会尽量容纳更多的 + 都会应用去重来创建倒排列表 + 元组,不过它们采用的策略与上述过程略有不同。对于从表中取出的已排序输入中遇到的每一组普通重复元组,都会在被加入当前待写入叶页之前先合并成一个 + 倒排列表元组。每个倒排列表元组都会尽量容纳更多的 TID。叶页按通常方式写出,不需要额外独立的去重过程。由于 CREATE INDEXREINDEX 都是一次性的批处理操作,这种策略非常适合它们。 @@ -495,12 +537,12 @@ options(relopts local_relopts *) returns 如果某个写密集型工作负载由于索引中的重复值很少甚至没有,而无法从去重中获益,那么它会承担很小且固定的性能损耗(除非显式禁用去重)。 deduplicate_items 存储参数可用于在单个索引内禁用去重。而只读工作负载绝不会因此遭受性能损失,因为读取 - posting list 元组至少与读取标准元组表示一样高效。禁用去重通常并没有帮助。 + 倒排列表元组至少与读取标准元组表示一样高效。禁用去重通常并没有帮助。 B-树索引并不直接知道,在 MVCC 下同一个逻辑表行可能存在多个现存版本;对索引来说,每个元组都是一个独立对象,都需要自己的索引项。版本重复项有时会积累起来,并对查询延迟和吞吐量造成不利影响。这通常发生在以UPDATE为主的工作负载中,其中大多数单次更新都无法应用HOT 优化(通常是因为至少一个被索引列发生了修改,因此必须生成一组新的索引元组版本 — 每一个索引都需要一个新元组)。实际上,B-树去重能够缓解版本频繁更替导致的索引膨胀。注意,由于版本频繁更替,即使唯一索引中的元组存储在磁盘上时,也不一定在物理上唯一。去重优化会有选择地应用于唯一索引,针对的是那些看起来存在版本重复项的页面。其总体目标是在版本频繁更替引发一次不必要的页拆分之前,给VACUUM更多运行时间。 - 系统会应用一种特殊的启发式规则,来判定唯一索引中是否应当执行一次去重轮次。它往往可以直接跳到拆分叶页,从而避免把周期浪费在无益的去重过程中而造成性能损耗。如果你担心去重的开销,可以考虑有选择地设置 + 系统会应用一种特殊的启发式规则,来判定唯一索引中是否应当执行一次去重轮次。它往往可以直接跳到拆分叶页,从而避免把处理器周期浪费在无益的去重过程中而造成性能损耗。如果你担心去重的开销,可以考虑有选择地设置 deduplicate_items = off。在唯一索引中保持去重启用,坏处很小。 @@ -524,7 +566,7 @@ options(relopts local_relopts *) returns numeric 不能使用去重。必须保留相等的 datum - 之间的小数位数。 + 之间的显示小数位数。 diff --git a/zh/13/catalogs.sgml b/zh/13/catalogs.sgml index 7da9219a..a347c7cf 100644 --- a/zh/13/catalogs.sgml +++ b/zh/13/catalogs.sgml @@ -668,7 +668,7 @@ t = 表(包括物化视图), - i = 索引. + i = 索引。 @@ -1104,7 +1104,9 @@ attcacheoff int4 - 在存储中总是 -1,但加载到内存中的行描述符后,此值可能被更新,用于缓存该属性在行内的偏移量 + + 在存储中始终为 -1,但装入内存中的行描述符时,可能会更新为该属性在行内偏移量的缓存值 + @@ -1113,7 +1115,7 @@ atttypmod记录了在表创建时提供的类型相关数据(例如一个varchar列的最大长度)。 - 它会被传递给类型相关的输入函数和长度强制函数。对于那些不需要atttypmod的类型,这个值通常总是为-1。 + 它会被传递给类型相关的输入函数和长度强制转换函数。对于那些不需要atttypmod的类型,这个值通常为 -1。 @@ -1150,7 +1152,7 @@ attnotnull bool - 此列具有一个非空约束(可能尚未验证) + 这代表一个非空约束 @@ -1169,8 +1171,7 @@ atthasmissing bool - 该列在行中完全缺失时会用到这个列的值,如果在行创建之后增加一个有非易失DEFAULT值的列,就会发生这种情况。 - 实际使用的值被存放在attmissingval列中。 + 此列有一个值,供该列在数据行中完全缺失时使用;在数据行创建之后添加带有非易失 DEFAULT 值的列时,就会出现这种情况。实际使用的值存储在 attmissingval 列中。 @@ -1190,7 +1191,7 @@ 如果是零字节(''),则不是生成列。 - 否则,s = 存储式(stored)。(将来可能会增加其他值。) + 否则,s = 存储式。(将来可能会添加其他值。) @@ -1199,7 +1200,7 @@ attisdropped bool - 该列被删除且不再有效。一个删除的列仍然物理存在于表中,但是会被分析器忽略并因此无法通过SQL访问。 + 该列被删除且不再有效。一个删除的列仍然物理存在于表中,但是会被解析器忽略并因此无法通过SQL访问。 @@ -1227,7 +1228,7 @@ (引用 pg_collation.oid - 该列被定义的排序规则,如果该列不是一个可排序数据类型则为0。 + 该列定义的排序规则;如果该列的数据类型不支持排序规则,则为零。 @@ -1236,7 +1237,7 @@ attacl aclitem[] - 列级访问权限, 如果此列上已有特别授予的权限 + 列级访问权限,如果此列上已有特别授予的权限 @@ -1264,7 +1265,7 @@ 这个列中是一个含有一个元素的数组,其中的值被用于该列在行中完全缺失时,如果在行创建之后增加一个有非易失DEFAULT值的列,就会发生这种情况。 - 只有当atthasmissing为真时才使用这个值。如果没有值则该列为空。 + 只有当atthasmissing为真时才使用这个值。如果没有值则该列为空值。 @@ -1272,9 +1273,7 @@ - 在一个被删除的列的pg_attribute的项中,atttypid被重置为0,但attlen以及其他从pg_type拷贝的域仍然有效。 - 这种安排用于处理一种情况,即被删除列的数据类型后来被删除,并且因此不再有相应的pg_type行。 - attlen和其他域可以被用来解释表的一行的内容。 + 在被删除列的 pg_attribute 条目中,atttypid 被重置为零,但 attlen 以及其他从 pg_type 复制的字段仍然有效。这种安排用于应对被删除列的数据类型后来也被删除、因而不再有相应 pg_type 行的情况。attlen 和其他字段可用于解释表中一行的内容。 @@ -1403,7 +1402,7 @@ rolconnlimit int4 - 对于可以登录的角色,本列设置该角色可以同时发起最大连接数。-1表示无限制。 + 对于可以登录的角色,本列设置该角色能够建立的最大并发连接数。-1 表示无限制。 @@ -1412,7 +1411,7 @@ rolpassword text - 加密后的密码;如果未设置则为空。其格式取决于所使用的加密方式。 + 加密后的密码;如果未设置则为空值。其格式取决于所使用的加密方式。 @@ -1421,7 +1420,7 @@ rolvaliduntil timestamptz - 密码过期时间(只用于密码鉴定),如果永不过期则为空 + 密码过期时间(仅用于密码认证);不设过期时间时为空值 @@ -1429,7 +1428,7 @@ - 对于一个MD5加密的密码,rolpassword列将由字符串md5后面跟上一个32字符的十六进制MD5哈希值构成。MD5哈希值将是该用户的密码串接上它们的用户名。例如,如果用户joe的密码是xyzzy,则PostgreSQL将存储xyzzyjoe的md5哈希。 + 对于一个MD5加密的密码,rolpassword列将由字符串md5后面跟上一个32字符的十六进制MD5哈希值构成。MD5 哈希值通过在用户密码后拼接用户名再计算得到。例如,如果用户joe的密码是xyzzy,则PostgreSQL将存储xyzzyjoe的md5哈希。 如果密码使用 SCRAM-SHA-256 加密,其格式为: @@ -1525,7 +1524,7 @@ SCRAM-SHA-256$<iteration count>:&l - 需要注意的是,pg_cast并不表示系统知道如何执行的所有类型转换,它只包括那些不能从某些通用规则推导出的转换。例如,一个域及其基类型之间的转换并未显式地在pg_cast中展示。另一个重要的例外是自动的基于 I/O 的类型转换,它们通过数据类型自己的 I/O 函数来转换成(或者转换自)text或其他字符串类型,这些转换也没有显式地在pg_cast中表示。 + 需要注意的是,pg_cast并不表示系统知道如何执行的所有类型转换,它只包括那些不能从某些通用规则推导出的转换。例如,一个域及其基础类型之间的转换并未显式地在pg_cast中展示。另一个重要的例外是自动的基于 I/O 的类型转换,它们通过数据类型自己的 I/O 函数来转换成(或者转换自)text或其他字符串类型,这些转换也没有显式地在pg_cast中表示。 @@ -1630,7 +1629,7 @@ SCRAM-SHA-256$<iteration count>:&l - 目录pg_class描述了具有列或与表类似的其他对象。这包括索引(但请参见pg_index)、序列(但请参见pg_sequence)、视图、物化视图、复合类型和TOAST表;请参见relkind。 + 目录pg_class描述了表以及其他具有列或在其他方面与表类似的对象。这包括索引(但请参见pg_index)、序列(但请参见pg_sequence)、视图、物化视图、复合类型和TOAST表;请参见relkind。 在下面,当我们指的是所有这些类型的对象时,我们称之为关系(relations)。并非所有pg_class的列对所有关系类型都有意义。 @@ -1710,7 +1709,7 @@ SCRAM-SHA-256$<iteration count>:&l relam oid (引用 pg_am.oid) - 如果这是表或索引,则为使用的访问方法(堆、B-树、哈希等) + 如果这是表或索引,则为使用的访问方法(堆、B-树、hash 等) @@ -1798,7 +1797,7 @@ SCRAM-SHA-256$<iteration count>:&l relpersistence char - p = 永久表, u = 不记录 WAL 的表, + p = 永久表,u = 不记录 WAL 的表, t = 临时表 @@ -1893,7 +1892,7 @@ SCRAM-SHA-256$<iteration count>:&l relispopulated bool - 如果表已被填充则为真(对于所有关系该列都为真,但对于某些物化视图却不是) + 如果关系已被填充则为真(对于所有关系该列都为真,但对于某些物化视图却不是) @@ -1946,7 +1945,7 @@ SCRAM-SHA-256$<iteration count>:&l relminmxid xid - 在此之前的多事务ID在表中已经被替换为一个事务ID。这被用于跟踪表是否需要被清理,以阻止 + 在此之前的所有多事务ID在表中已经被替换为一个事务ID。这被用于跟踪表是否需要被清理,以阻止 多事务ID回卷或者允许pg_multixact被收缩。如果关系不是一个表则 为0(InvalidMultiXactId)。 @@ -1975,7 +1974,7 @@ SCRAM-SHA-256$<iteration count>:&l relpartbound pg_node_tree - 如果表示一个分区(见relispartition),则为分区边界的内部表示 + 如果表是一个分区(见relispartition),则为分区边界的内部表示 @@ -1983,7 +1982,7 @@ SCRAM-SHA-256$<iteration count>:&l
- pg_class中的一些逻辑标志被以一种懒惰的方式维护:在正确状态时它们被保证为真,但是当条件不再为真时它们并不会被立刻重置为假。 + pg_class中的一些布尔标志采用延迟维护:当条件成立时,保证它们为真;但当条件不再成立时,可能不会立即将它们重置为假。 例如,relhasindexCREATE INDEX设置,但它从不会被DROP INDEX清除。 作为替代,VACUUM会在找到无索引表后清除其relhasindex。 这种安排避免了竞争条件并且提高了并发性。 @@ -2059,9 +2058,10 @@ SCRAM-SHA-256$<iteration count>:&l collprovider char - 排序规则提供者:d = 数据库默认值, + 排序规则提供程序:d = 数据库默认值, c = libc, - i = icu + i = icu + @@ -2105,7 +2105,7 @@ SCRAM-SHA-256$<iteration count>:&l collversion text - 排序规则的提供者相关的版本。这是在排序规则创建时记录下来的,并且在使用排序规则时会被检查以检测可能导致数据损坏的排序规则定义的改变。 + 提供程序特有的排序规则版本。它会在创建排序规则时记录下来,并在使用时接受检查,以检测可能导致数据损坏的排序规则定义更改。 @@ -2416,9 +2416,9 @@ SCRAM-SHA-256$<iteration count>:&l - 在一个排他约束的情况中, conkey只对约束元素是单一列引用时有用。 - 对于其他情况,conkey中出现一个0且必须查阅相关索引来发现被约束的表达式。 - (对于索引,conkey因此和pg_index.indkey具有相同的内容)。 + 对于排他约束,conkey仅对作为简单列引用的约束元素有用。 + 对于其他情况,conkey中会出现一个 0,必须查阅关联索引来确定被约束的表达式。 + (因此,conkey与该索引的 pg_index.indkey具有相同的内容。) @@ -3765,7 +3765,7 @@ SCRAM-SHA-256$<iteration count>:&l indisunique bool - 如为真, 这是唯一索引 + 如为真, 这是唯一索引 @@ -3873,7 +3873,7 @@ SCRAM-SHA-256$<iteration count>:&l (引用 pg_collation.oid - 对于索引键(indnkeyatts值)中的每一列,这包含要用于该索引的排序规则的OID,如果该列不是一种可排序数据类型则为零。 + 对于索引键(indnkeyatts值)中的每一列,这包含要用于该索引的排序规则的OID,如果该列的数据类型不支持排序规则则为零。 @@ -4870,7 +4870,7 @@ SCRAM-SHA-256$<iteration count>:&l (引用 pg_collation.oid - 对于分区键中的每一个列,这个域包含要用于分区的排序规则的OID,如果该列不是一种可排序数据类型则为零。 + 对于分区键中的每一个列,这个域包含要用于分区的排序规则的OID,如果该列的数据类型不支持排序规则则为零。 @@ -5601,7 +5601,11 @@ SCRAM-SHA-256$<iteration count>:&l - rngsubopc (加上rngcollation,如果元素类型是可排序的)决定了被该范围类型所使用的排序顺序。rngcanonical用于离散类型的元素类型。rngsubdiff是可选的,但是提供它可以提高范围类型上的GiST索引性能。 + rngsubopc(如果元素类型支持排序规则,则还包括 + rngcollation)决定范围类型所用的排序顺序。 + rngcanonical用于元素类型为离散类型的情况。 + rngsubdiff是可选的,但应当提供它, + 以提高范围类型上的 GiST 索引性能。
@@ -6277,8 +6281,8 @@ SCRAM-SHA-256$<iteration count>:&l 通常,每个已分析的表列都有一个条目,其中stainherit = false。 - 如果表具有继承子项或分区,则还会创建第二个条目,其中stainherit = true。 - 此行表示继承树上列的统计信息,即您可以通过SELECT column FROM table*看到的数据的统计信息, + 如果表具有继承子表,则还会创建第二个条目,其中stainherit = true。 + 此行表示继承树上列的统计信息,即你可以通过SELECT column FROM table*看到的数据的统计信息, 而stainherit = false行表示SELECT column FROM ONLY table的结果。 @@ -6287,7 +6291,7 @@ SCRAM-SHA-256$<iteration count>:&l - 因为不同类型的统计信息适用于不同类型的数据, pg_statistic 被设计成不太在意自己存储的是什么类型的统计。 只有极为常用的统计信息(比如NULL的含量)才在pg_statistic里给予专用的字段。 其它所有东西都存储在槽位中,而槽位是一组相关的列, 它们的内容用槽位中的一个列里的代码表示。 更详细的信息请参阅 src/include/catalog/pg_statistic.h。 + 由于不同种类的数据可能适合不同种类的统计信息,pg_statistic 在设计上尽量不对所存储的统计信息种类作出假定。只有极为通用的统计信息(例如空值情况)才在 pg_statistic 中有专用的列。其余统计信息都存储在槽位中。每个槽位都是一组相关的列,其内容由其中一列的代码编号来标识。更多信息见 src/include/catalog/pg_statistic.h @@ -6343,7 +6347,7 @@ SCRAM-SHA-256$<iteration count>:&l stanullfrac float4 - 列的项为空的比例 + 列中空值所占的比例 @@ -6361,8 +6365,8 @@ SCRAM-SHA-256$<iteration count>:&l stadistinct float4 - 列中非空唯一值的数目。一个大于零的值是唯一值的真正数目。 - 一个小于零的值是表中行数的乘数的负值;例如,对于一个 80% 的值为非空且每个非空值平均出现两次的列,可以表示为stadistinct = -0.4。一个0值表示唯一值的数目未知。 + 列中不同非空数据值的数量。一个大于零的值是不同值的真正数目。 + 一个小于零的值是表中行数的乘数的负值;例如,对于一个约 80% 的值为非空且每个非空值平均出现两次的列,可以表示为stadistinct = -0.4。一个0值表示不同值的数目未知。 @@ -6392,8 +6396,8 @@ SCRAM-SHA-256$<iteration count>:&l (引用 pg_collation.oid - 用于导出存储在第N槽位中的统计信息的排序规则。 - 例如,可应用排序规则列的直方图槽会显示定义数据排序顺序的排序规则。对于不可应用排序规则的数据,则为零。 + 用于生成存储在第N槽位中的统计信息的排序规则。 + 例如,支持排序规则的列的直方图槽会显示定义数据排序顺序的排序规则。对于不支持排序规则的数据,则为零。 @@ -6402,7 +6406,7 @@ SCRAM-SHA-256$<iteration count>:&l stanumbersN float4[] - 第N槽位的类型的数值类型统计, 如果该槽位不涉及数值类型则为NULL + 第N槽位中相应种类的数值统计信息;如果该槽位种类不涉及数值,则为 NULL @@ -6412,7 +6416,7 @@ SCRAM-SHA-256$<iteration count>:&l N槽位的类型的列值,如果该槽位类型不存储任何数据值则为 NULL。 - 每个数组的元素值实际上都是指定列的数据类型或者是一个相关类型(如数组元素类型), 因此,除了把这些列的类型定义成anyarray之外别无他法。 + 每个数组的元素值实际上都是指定列的数据类型或者是一个相关类型(如数组元素类型), 因此,无法把这些列的类型定义得比anyarray更具体。 @@ -6504,7 +6508,7 @@ SCRAM-SHA-256$<iteration count>:&l stxstattarget 控制 为该统计信息对象收集统计信息时的细节级别。 零值表示不应收集统计信息。 - 空值表示使用被引用列的统计目标中的最大值(如果有设置),否则使用系统默认统计目标。 + 负值表示使用被引用列的统计目标中的最大值(如果有设置),否则使用系统默认统计目标。 正值 stxstattarget 决定要收集的高频值目标个数。 @@ -6535,8 +6539,8 @@ SCRAM-SHA-256$<iteration count>:&l - pg_statistic_ext条目在CREATE STATISTICS期间完全填充,但是随后不计算实际的统计值。 - 后来ANALYZE命令计算所需的值,并在pg_statistic_ext_data目录中填充条目。 + pg_statistic_ext条目在CREATE STATISTICS期间完全填充,但此时不会计算实际的统计值。 + 后续的ANALYZE命令计算所需的值,并在pg_statistic_ext_data目录中填充条目。 @@ -6610,7 +6614,7 @@ SCRAM-SHA-256$<iteration count>:&l stxdmcv pg_mcv_list - MCV(最频值)列表统计信息,序列化为pg_mcv_list类型 + MCV(高频值)列表统计信息,序列化为pg_mcv_list类型 @@ -7121,7 +7125,7 @@ SCRAM-SHA-256$<iteration count>:&l tgdeferrable bool - 如果约束触发器可推迟则为真 + 如果约束触发器可延迟则为真 @@ -7130,7 +7134,7 @@ SCRAM-SHA-256$<iteration count>:&l tginitdeferred bool - 如果约束触发器初始可推迟则为真 + 如果约束触发器初始处于延迟状态则为真 @@ -7666,7 +7670,7 @@ SCRAM-SHA-256$<iteration count>:&l 目录pg_type存储有关数据类型的信息。 - 基类型和枚举类型(标量类型)使用创建,而域使用创建。 + 基础类型和枚举类型(标量类型)使用创建,而域使用创建。 数据库中的每一个表都会有一个自动创建的复合类型,用于表示表的行结构。 也可以使用CREATE TYPE AS创建复合类型。 @@ -7752,7 +7756,7 @@ SCRAM-SHA-256$<iteration count>:&l typtype可以是: - b表示一个基类型, + b表示一个基础类型, c表示一个复合类型(例如一个表的行类型), d表示一个域, e表示一个枚举类型, @@ -7947,7 +7951,7 @@ SCRAM-SHA-256$<iteration count>:&l - e (外部的): 值可以存储在一个次要 TOAST 关系中 (如果有一个关系, 参见pg_class.reltoastrelid). + e (外部的): 值可以存储在一个次要 TOAST 关系中 (如果有一个关系, 参见pg_class.reltoastrelid). @@ -7988,7 +7992,7 @@ SCRAM-SHA-256$<iteration count>:&l typtypmod int4 - 域使用typtypmod来记录被应用于它们基类型的typmod(如果基类型不使用typmod,则为-1)。如果此类型不是一个域则为-1。 + 域使用typtypmod来记录被应用于它们基础类型的typmod(如果基础类型不使用typmod,则为-1)。如果此类型不是一个域则为-1。 @@ -8008,8 +8012,8 @@ SCRAM-SHA-256$<iteration count>:&l typcollation指定此类型的排序规则。如果类型不支持排序规则,此列为零。 - 支持排序规则的基类型在这里会有一个非零值,典型值为DEFAULT_COLLATION_OID。 - 基于可应用排序规则类型的域,如果为其指定了排序规则 OID,则它的排序规则 OID 可以不同于其基类型。 + 支持排序规则的基础类型在这里会有一个非零值,典型值为DEFAULT_COLLATION_OID。 + 基于支持排序规则的类型的域,如果为其指定了排序规则 OID,则它的排序规则 OID 可以不同于其基础类型的排序规则 OID。 @@ -9131,7 +9135,7 @@ SCRAM-SHA-256$<iteration count>:&l indexdef text - 索引定义(重构出的 CREATE INDEX 命令) + 索引定义(重建出的 CREATE INDEX 命令) @@ -9165,8 +9169,8 @@ SCRAM-SHA-256$<iteration count>:&l 以及一般的数据库对象(由类OID和对象OID标识, 与pg_descriptionpg_depend中的方式相同)。 - 此外,扩展关系的权限被表示为一个单独的可锁定对象,以及更新 - pg_database.datfrozenxid 的更新权限。 + 此外,扩展关系的权利被表示为单独的可锁定对象,更新 + pg_database.datfrozenxid的权利也是如此。 此外,还可以对具有用户定义含义的数字施加咨询锁。 @@ -9212,7 +9216,7 @@ SCRAM-SHA-256$<iteration count>:&l (参考 pg_database.oid) - 锁目标存在的数据库的OID,如果目标是一个共享对象则为0,如果目标是一个事务ID则为空 + 锁目标存在的数据库的OID,如果目标是一个共享对象则为0,如果目标是一个事务ID则为 NULL @@ -9222,7 +9226,7 @@ SCRAM-SHA-256$<iteration count>:&l (参考 pg_class.oid) - 作为锁目标的关系的OID,如果目标不是一个关系或者只是关系的一部分则此列为空 + 作为锁目标的关系的OID,如果目标既不是关系,也不是关系的一部分则此列为 NULL @@ -9231,7 +9235,7 @@ SCRAM-SHA-256$<iteration count>:&l page int4 - 作为锁目标的页在关系中的页号,如果目标不是一个关系页或元组则此列为空 + 作为锁目标的页在关系中的页号,如果目标不是一个关系页或元组则此列为 NULL @@ -9240,7 +9244,7 @@ SCRAM-SHA-256$<iteration count>:&l tuple int2 - 作为锁目标的元组在页中的元组号,如果目标不是一个元组则此列为空 + 作为锁目标的元组在页中的元组号,如果目标不是一个元组则此列为 NULL @@ -9249,7 +9253,7 @@ SCRAM-SHA-256$<iteration count>:&l virtualxid text - 锁定目标事务的虚拟 ID,如果目标不是虚拟事务 ID,则为空 + 锁定目标事务的虚拟 ID,如果目标不是虚拟事务 ID,则为 NULL @@ -9258,7 +9262,7 @@ SCRAM-SHA-256$<iteration count>:&l transactionid xid - 锁定目标事务的标识,如果目标不是事务 ID,则为空 + 锁定目标事务的标识,如果目标不是事务 ID,则为 NULL @@ -9268,7 +9272,7 @@ SCRAM-SHA-256$<iteration count>:&l (参考 pg_class.oid) - 包含锁目标的系统目录的OID,如果目标不是一个普通数据库对象则此列为空 + 包含锁目标的系统目录的OID,如果目标不是一个普通数据库对象则此列为 NULL @@ -9278,7 +9282,7 @@ SCRAM-SHA-256$<iteration count>:&l (参考任意 OID 列) - 锁目标在它的系统目录中的OID,如果目标不是一个普通数据库对象则为空 + 锁目标在它的系统目录中的OID,如果目标不是一个普通数据库对象则为 NULL @@ -9287,7 +9291,7 @@ SCRAM-SHA-256$<iteration count>:&l objsubid int2 - 锁的目标列号(classidobjid指表本身),如果目标是某种其他普通数据库对象则此列为0,如果目标不是一个普通数据库对象则此列为空 + 锁的目标列号(classidobjid指表本身),如果目标是某种其他普通数据库对象则此列为0,如果目标不是一个普通数据库对象则此列为 NULL @@ -9305,7 +9309,7 @@ SCRAM-SHA-256$<iteration count>:&l pid int4 - 保持这个锁或者正在等待这个锁的服务器进程的PID,如果此锁被一个预备事务所持有则此列为空 + 保持这个锁或者正在等待这个锁的服务器进程的PID,如果此锁被一个预备事务所持有则此列为 NULL @@ -9359,8 +9363,8 @@ SCRAM-SHA-256$<iteration count>:&l 咨询锁可以在由单个 bigint 值或两个整数值组成的键上获取。 - 一个bigint键在classid列中显示其高阶半部分, - 在objid列中显示其低阶半部分,并且objsubid等于1。 + 一个bigint键在classid列中显示其高位半部分, + 在objid列中显示其低位半部分,并且objsubid等于1。 可以使用表达式(classid::bigint << 32) | objid::bigint重新组装原始bigint值。 整数键在classid列中显示第一个键,在objid列中显示第二个键, 并且 objsubid 等于 2。键的实际含义由用户自行决定。咨询锁在每个数据库内都是本地的, @@ -9403,15 +9407,15 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx pg_locks视图显示来自常规锁管理器和谓词锁管理器的数据,这两个是独立的系统; - 此外,常规锁管理器将其锁分为常规锁和fast-path锁。 + 此外,常规锁管理器将其锁分为常规锁和快速路径锁。 不能保证这些数据完全一致。 当查询该视图时, - fast-path 锁的数据(具有fastpath = true) + 快速路径锁的数据(具有fastpath = true) 从每个后端逐个收集,而不会冻结整个锁管理器的状态,因此在收集信息时可能会发生锁的获取或释放。 但请注意,这些锁已知不会与当前放置的任何其他锁发生冲突。 - 在查询所有后端的 fast-path 锁后,剩余的常规锁管理器将作为一个单元被锁定,并且所有剩余锁的一致快照将作为一个原子操作收集。 + 在查询所有后端的快速路径锁后,剩余的常规锁管理器将作为一个单元被锁定,并且所有剩余锁的一致快照将作为一个原子操作收集。 解锁常规锁管理器后,谓词锁管理器类似地被锁定,并且所有谓词锁将作为一个原子操作收集。 - 因此,除了 fast-path 锁外,每个锁管理器将提供一致的结果集,但由于我们不同时锁定两个锁管理器,因此在询问常规锁管理器后和在询问谓词锁管理器前,可能会发生锁的获取或释放。 + 因此,除了快速路径锁外,每个锁管理器将提供一致的结果集,但由于我们不同时锁定两个锁管理器,因此在询问常规锁管理器后和在询问谓词锁管理器前,可能会发生锁的获取或释放。 @@ -9514,7 +9518,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx definition text - 物化视图的定义(一个重构的SELECT查询) + 物化视图的定义(一个重建的SELECT查询) @@ -9981,7 +9985,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx plugin name - 包含该逻辑槽所用输出插件的共享对象的基础名称;物理槽为 NULL。 + 包含该逻辑槽所用输出插件的共享对象的基础名称;物理槽为 NULL @@ -10000,7 +10004,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx (参考 pg_database.oid) - 与该槽关联的数据库 OID,或为 NULL。只有逻辑槽才有关联数据库。 + 与该槽关联的数据库 OID,或为 NULL。只有逻辑槽才有关联数据库。 @@ -10010,7 +10014,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx (参考 pg_database.datname) - 与该槽关联的数据库名称,或为 NULL。只有逻辑槽才有关联数据库。 + 与该槽关联的数据库名称,或为 NULL。只有逻辑槽才有关联数据库。 @@ -10028,7 +10032,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx active bool - 如果该槽当前正被用于流送则为真 + 如果该槽当前正在使用中则为真 @@ -10037,7 +10041,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx active_pid int4 - 为该槽流送数据的会话的进程 ID。NULL 表示不活动。 + 如果该槽当前正在使用中,则为使用该槽的会话的进程 ID;不活动时为 NULL @@ -10073,7 +10077,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx confirmed_flush_lsn pg_lsn - 逻辑槽消费者已确认接收到数据的地址(LSN)。早于此地址的数据将不再可用。物理槽为 NULL。 + 逻辑槽消费者已确认接收的数据所到达的地址(LSN)。早于此地址的数据将不再可用。物理槽为 NULL @@ -10092,15 +10096,16 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - unreserved 表示该槽已不再保留所需的 WAL 文件,其中一部分将在下一个检查点被移除。这通常发生在 被设置为非负值时。该状态可以返回为 reservedextended。 + unreserved 表示该槽已不再保留所需的 WAL 文件,其中一部分将在下一个检查点被移除。该状态可以返回为 reservedextended - lost 表示该槽已经不可用。 + lost 表示某些必需的 WAL 文件已被移除,该槽已经不可用。 + 后两种状态仅在 为非负值时出现。 @@ -10109,9 +10114,10 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx safe_wal_size int8 - 还可以写入 WAL 的字节数,使该槽不至于进入“lost”状态。对于已丢失的槽,以及 max_slot_wal_keep_size-1 时,该值为 NULL。 + 还可以写入 WAL 的字节数,使该槽不至于进入“lost”状态。对于已丢失的槽,以及 max_slot_wal_keep_size-1 时,该值为 NULL + @@ -10126,7 +10132,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx 视图pg_roles提供数据库角色的信息。它本质上是 - pg_authid 的公开可读视图,并将密码字段清空。 + pg_authid 的公开可读视图,并隐藏密码字段。 @@ -10212,7 +10218,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx rolconnlimitint4 - 对于可以登录的角色,本列设置该角色可以同时发起最大连接数。-1表示无限制。 + 对于可以登录的角色,本列设置该角色能够建立的最大并发连接数。-1 表示无限制。 @@ -10230,7 +10236,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx rolvaliduntiltimestamptz - 密码过期时间(只用于密码认证),如果永不过期则为空 + 密码过期时间(仅用于密码认证);不设过期时间时为空值 @@ -10328,7 +10334,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx definitiontext - 规则定义(创建命令的重构) + 规则定义(重建的创建命令) @@ -10889,7 +10895,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx 这个名称源于该表不应向公众开放读取,因为它包含密码。 pg_user - 是 pg_shadow 的公开可读视图,并将密码字段清空。 + 是 pg_shadow 的公开可读视图,并隐藏密码字段。
@@ -11678,7 +11684,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx 视图pg_user提供数据库用户的信息。它本质上是 - pg_shadow 的公开可读视图,并将密码字段清空。 + pg_shadow 的公开可读视图,并隐藏密码字段。
@@ -11954,7 +11960,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx definitiontext - 视图定义(一个重构的SELECT查询) + 视图定义(一个重建的SELECT查询) diff --git a/zh/13/charset.sgml b/zh/13/charset.sgml index 4ba4b9e8..188eaf43 100644 --- a/zh/13/charset.sgml +++ b/zh/13/charset.sgml @@ -29,7 +29,7 @@ 区域设置支持 - locale + 区域设置 区域设置支持是指应用程序在字母表、排序、数字格式等 @@ -197,7 +197,7 @@ initdb --locale=sv_SE 以及 POSIX 风格正则表达式);区域设置既会影响大小写不敏感匹配,也会 影响字符类正则表达式中的字符分类 LIKE与区域设置 - regular expressions与区域设置 + 正则表达式与区域设置 @@ -286,10 +286,10 @@ initdb --locale=sv_SE 概念 - 从概念上讲,每个可排序数据类型的表达式都有一个排序规则。(内置的可排序 - 数据类型包括textvarcharchar。 - 用户定义的基本类型也可以标记为可排序,当然,建立在可排序数据类型之上的 - 域也是可排序的。) + 从概念上讲,每个支持排序规则的数据类型的表达式都有一个排序规则。 + (内置的支持排序规则的数据类型包括textvarcharchar。 + 用户定义的基础类型也可以标记为支持排序规则,当然,建立在支持排序规则的数据类型之上的 + 域也支持排序规则。) 如果表达式是列引用,则该表达式的排序规则就是该列定义的排序规则。如果表 达式是常量,则其排序规则就是该常量数据类型的默认排序规则。更复杂表达式 的排序规则则按下文所述,从其输入表达式的排序规则推导出来。 @@ -314,7 +314,7 @@ initdb --locale=sv_SE 对于函数或操作符调用,通过检查参数排序规则推导出的排序规则,会在运行时 - 用于执行指定操作。如果该函数或操作符调用的结果属于可排序数据类型,那么 + 用于执行指定操作。如果该函数或操作符调用的结果属于支持排序规则的数据类型,那么 在解析时它也会被用作该函数或操作符表达式的已定义排序规则,以便在外围表 达式需要知道其排序规则时使用。 @@ -396,7 +396,7 @@ SELECT a || b FROM test1; - 如果函数或操作符返回的是可排序数据类型,那么分配给该函数或操作符组合输 + 如果函数或操作符返回的是支持排序规则的数据类型,那么分配给该函数或操作符组合输 入表达式的排序规则,也被认为适用于其结果。因此,在 SELECT * FROM test1 ORDER BY a || 'foo'; @@ -442,8 +442,7 @@ SELECT * FROM test1 ORDER BY a || b COLLATE "fr_FR"; - 由icu提供的排序规则对象,对应于 ICU 库提供的具名整 - 理器。ICU 不支持将collatectype分开设 + 由icu提供的排序规则对象,对应于 ICU 库提供的具名排序器。ICU 不支持将collatectype分开设 置,因此二者总是相同的。此外,ICU 排序规则与编码无关,因此在一个数据库 中,某个给定名称的 ICU 排序规则始终只有一个。 @@ -532,7 +531,7 @@ SELECT a COLLATE "C" < b COLLATE "POSIX" FROM test1; -x-icu,以便与 libc 区域设置区分开来。 - 以下是可能创建的排序规则示例: + 下面是一些可能创建出来的排序规则示例: de-x-icu @@ -618,7 +617,7 @@ CREATE COLLATION german (provider = libc, locale = 'de_DE'); CREATE COLLATION "de-u-co-phonebk-x-icu" (provider = icu, locale = 'de-u-co-phonebk'); CREATE COLLATION "de-u-co-phonebk-x-icu" (provider = icu, locale = 'de@collation=phonebook'); - 采用电话簿排序类型的德语排序规则 + 德语排序规则,电话簿排序类型 第一个示例使用 BCP 47 定义的语言标签来选择 ICU 区域设置。第二个示例使用传统的 ICU 专有区域设置语法。今后应优先采用第一种形式,但较旧的 ICU 版本不支持它。 注意,可以在 SQL 环境中为排序规则对象任意命名。本例遵循预定义排序规则所采用的命名风格,该风格也遵循 BCP 47,但用户定义的排序规则并不要求如此。 @@ -628,7 +627,9 @@ CREATE COLLATION german (provider = libc, locale = 'de_DE'); CREATE COLLATION "und-u-co-emoji-x-icu" (provider = icu, locale = 'und-u-co-emoji'); CREATE COLLATION "und-u-co-emoji-x-icu" (provider = icu, locale = '@collation=emoji'); - 采用 Unicode 技术标准 #51 所定义 Emoji 排序类型的根排序规则 + + 根排序规则,表情符号排序类型,依据 Unicode 技术标准 #51 + 注意,传统的 ICU 区域设置命名系统使用空字符串来选择根区域设置。 @@ -637,7 +638,9 @@ CREATE COLLATION german (provider = libc, locale = 'de_DE'); CREATE COLLATION latinlast (provider = icu, locale = 'en-u-kr-grek-latn'); CREATE COLLATION latinlast (provider = icu, locale = 'en@colReorder=grek-latn'); - 将希腊字母排在拉丁字母之前。(默认是拉丁字母在希腊字母之前。) + + 将希腊字母排在拉丁字母之前。(默认情况下是拉丁字母排在希腊字母之前。) + @@ -645,7 +648,9 @@ CREATE COLLATION german (provider = libc, locale = 'de_DE'); CREATE COLLATION upperfirst (provider = icu, locale = 'en-u-kf-upper'); CREATE COLLATION upperfirst (provider = icu, locale = 'en@colCaseFirst=upper'); - 将大写字母排在小写字母之前。(默认是小写字母在前。) + + 将大写字母排在小写字母之前。(默认情况下是小写字母在前。) + @@ -653,7 +658,9 @@ CREATE COLLATION german (provider = libc, locale = 'de_DE'); CREATE COLLATION special (provider = icu, locale = 'en-u-kf-upper-kr-grek-latn'); CREATE COLLATION special (provider = icu, locale = 'en@colCaseFirst=upper;colReorder=grek-latn'); - 组合上述两个选项。 + + 结合了以上两个选项。 + @@ -692,7 +699,17 @@ CREATE COLLATION french FROM "fr-x-icu"; 非确定性排序规则 - 排序规则分为确定性非确定性两类。确定性排序规则使用确定性比较,即仅当字符串由相同的字节序列组成时,才认为它们相等。非确定性比较则可能将字节不同的字符串判为相等。典型情况包括不区分大小写的比较、不区分重音的比较,以及采用不同 Unicode 规范形式的字符串之间的比较。这些不敏感的比较由排序规则提供者实际实现;确定性标志只决定是否使用逐字节比较来打破平局。关于术语的更多信息,另见 Unicode 技术标准 10 + + 排序规则要么是确定性的,要么是 + 非确定性的。确定性排序规则使用确定性比较,这 + 意味着只有当两个字符串由完全相同的字节序列组成时,才会认为它们相等。 + 非确定性比较则可能在两个字符串的字节不同的情况下,仍判断它们相等。典型 + 情况包括不区分大小写的比较、不区分重音的比较,以及对采用不同 Unicode + 规范化形式的字符串进行比较。具体是否实现这些不敏感比较,取决于排序规则 + 提供程序;deterministic标志只决定当比较结果相等时, + 是否再使用按字节比较来打破平局。更多术语信息可参见Unicode 技术标准 10。 + 要创建非确定性排序规则,可在CREATE COLLATION中指 @@ -714,7 +731,7 @@ CREATE COLLATION ignore_accents (provider = icu, locale = 'und-u-ks-level1-kc-tr 定性的。虽然非确定性排序规则提供了更正确的行为,尤其是 在考虑 Unicode 的全部能力及其众多特殊情况时,但它们也有一些缺点。首 先,使用它们会带来性能损失。特别要注意的是,B-树不能对使用非确定性排 - 序规则的索引使用去重。此外,某些操作(例如某些模式匹配操作)对非确定性 + 序规则的索引使用去重。此外,某些操作(例如模式匹配操作)对非确定性 排序规则来说是不可行的。因此,只有在确实需要时才应使用它们。 diff --git a/zh/13/client-auth.sgml b/zh/13/client-auth.sgml index f9b2016f..19bd0969 100644 --- a/zh/13/client-auth.sgml +++ b/zh/13/client-auth.sgml @@ -37,7 +37,14 @@ pg_hba.conf - 客户端认证由一个配置文件控制,该文件通常名为 pg_hba.conf,存储在数据库集簇的数据目录中。(HBA 表示基于主机的认证。)initdb 初始化数据目录时,会安装一个默认的 pg_hba.conf 文件。不过,也可以将认证配置文件放在其他位置;参见 配置参数。 + + 客户端认证由一个配置文件控制,该文件按惯例命名为 + pg_hba.conf,并存放在数据库集簇的数据目录中。 + (HBA 代表 host-based authentication,即基于主机的认证。) + 当数据目录由 initdb 初始化时,会安装一个默认的 + pg_hba.conf 文件。不过,也可以把认证配置文件放在别处; + 请参见配置参数 。 + pg_hba.conf 文件的基本格式是一组记录,每行一条。空行和 # 注释字符之后的所有文本都会被忽略。记录不能跨行续写。每条记录由若干字段组成,字段之间用空格和/或制表符分隔。如果字段值用双引号括起来,就可以包含空白。在数据库、用户或地址字段中,将关键字(例如 allreplication)用引号括起来,会使其失去特殊含义,只匹配同名的数据库、用户或主机。 @@ -172,7 +179,7 @@ hostnogssenc database user IP地址范围使用标准的数字表示法来指定起始地址,然后是斜杠(/)和一个CIDR掩码长度。 掩码长度表示客户端IP地址必须匹配的高位比特数。给定IP地址中右侧的比特应为零。 - IP地址、/和CIDR掩码长度之间不得有任何空格。 + IP地址、/和CIDR掩码长度之间不得有任何空白。 @@ -209,12 +216,12 @@ hostnogssenc database user 以点(.)开头的主机名规范匹配实际主机名的后缀。 因此,.example.com将匹配foo.example.com - (但不仅仅是example.com)。 + (但不匹配单独的example.com)。 当在pg_hba.conf中指定主机名时,应确保名称解析相对快速。 - 最好设置一个本地名称解析缓存,如nscd。 + 设置一个本地名称解析缓存可能会有帮助,如nscd。 此外,还可能希望启用配置参数log_hostname,以便在日志中看到客户端的主机名而不是 IP 地址。 @@ -226,7 +233,7 @@ hostnogssenc database user 用户有时会想知道为什么主机名以这种看似复杂的方式处理,包括两次名称解析,其中包括对客户端IP地址的反向查找。 - 如果客户端的反向DNS条目未设置或生成了一些不良的主机名,则使用该功能会变得复杂。 + 如果客户端的反向DNS条目未设置或返回了不符合预期的主机名,则使用该功能会变得复杂。 这主要是为了效率:这样,连接尝试最多需要两次解析器查找,一次反向查找和一次正向查找。 如果某个地址存在解析器问题,那就只会成为该客户端的问题。 一个假设的替代实现只进行正向查找的情况下,在每次连接尝试期间都必须解析pg_hba.conf中提到的每个主机名。 @@ -241,7 +248,7 @@ hostnogssenc database user 请注意,这种行为与其他流行的基于主机名的访问控制实现一致,例如 - Apache HTTP服务器和TCP包装器。 + Apache HTTP 服务器和 TCP Wrappers。 @@ -253,7 +260,7 @@ hostnogssenc database user - 这两个字段可以用作IP地址/掩码长度 + 这两个字段可以用作IP-address/mask-length 表示法的替代方案。而不是指定掩码长度,实际掩码在一个单独的列中指定。 例如,255.0.0.0表示IPv4的CIDR掩码长度为8, 而255.255.255.255表示CIDR掩码长度为32。 @@ -268,7 +275,10 @@ hostnogssenc database user auth-method - 指定连接匹配此记录时使用的认证方法。这里概述可用的选项;详情参见 。所有选项都使用小写且区分大小写,因此即使是 ldap 这样的缩写,也必须使用小写。 + + 指定连接匹配此记录时要使用的认证方法。可选值在此处做了概述;详细说明见 。所有选项都必须使用小写并且区分大小写,因此即使是像 ldap 这样的首字母缩写也必须写成小写。 + + trust @@ -434,7 +444,15 @@ hostnogssenc database user auth-method 字段之后,可以有一个或多个形如 name=value 的字段,用于指定认证方法的选项。下文会详细说明各认证方法有哪些可用选项。 - 除下文列出的各方法专用选项外,还有一个与方法无关的认证选项 clientcert,可以在任何 hostssl 记录中指定。它可以设为 verify-caverify-full。二者都要求客户端提供有效(受信任)的 SSL 证书,而 verify-full 还要求证书中的 cn(通用名称)与用户名或适用的映射相匹配。这与 cert 认证方法(参见 )的行为类似,但可以将客户端证书验证与任何支持 hostssl 条目的认证方法搭配使用。 + + 除了下面列出的特定于方法的选项外,还有一个方法无关的认证选项 clientcert, + 可以在任何hostssl记录中指定。 + 此选项可以设置为verify-caverify-full。 + 这两个选项都要求客户端提供有效(受信任的)SSL证书, + 而verify-full还要求证书中的cn(通用名称)与用户名或适用映射匹配。 + 这种行为类似于 cert 认证方法(见), + 但允许把客户端证书验证与任何支持 hostssl 条目的认证方法配合使用。 + @@ -447,14 +465,14 @@ hostnogssenc database user由于每次连接尝试都会按顺序检查 pg_hba.conf 记录,因此记录的顺序很重要。通常,靠前的记录使用较严格的连接匹配条件和较弱的认证方法,靠后的记录使用较宽松的匹配条件和较强的认证方法。例如,可能希望对本地 TCP/IP 连接使用 trust 认证,而要求远程 TCP/IP 连接提供密码。此时,为来自 127.0.0.1 的连接指定 trust 认证的记录,应放在为更大范围的允许客户端 IP 地址指定密码认证的记录之前。 - 在启动以及主服务器进程收到SIGHUPSIGHUP信号时,pg_hba.conf文件会被读取。 - 如果你在活动的系统上编辑了该文件,你将需要通知 postmaster(使用pg_ctl reload,调用SQL函数pg_reload_conf(),或使用kill -HUP)使其重新读取该文件。 + 在启动时以及主服务器进程收到 SIGHUPSIGHUP 信号时,pg_hba.conf 文件会被读取。 + 如果你在运行中的系统上编辑了该文件,就需要通知 postmaster(使用 pg_ctl reload、调用 SQL 函数 pg_reload_conf(),或者使用 kill -HUP)重新读取该文件。 - 前面的说明在Microsoft Windows上不为真:在Windows上,pg_hba.conf文件中的任何更改会立即被应用到后续的新连接上。 + 前面的说明不适用于 Microsoft Windows:在Windows上,pg_hba.conf文件中的任何更改会立即被应用到后续的新连接上。 @@ -474,95 +492,92 @@ hostnogssenc database user 示例 <filename>pg_hba.conf</filename> 项 -# Allow any user on the local system to connect to any database with -# any database user name using Unix-domain sockets (the default for local -# connections). +# 允许本地系统上的任何用户 +# 通过 Unix 域套接字(本地连接的默认方式)以任意 +# 数据库用户名连接到任意数据库。 # # TYPE DATABASE USER ADDRESS METHOD local all all trust -# The same using local loopback TCP/IP connections. +# 相同的规则,但是使用本地环回 TCP/IP 连接。 # # TYPE DATABASE USER ADDRESS METHOD host all all 127.0.0.1/32 trust -# The same as the previous line, but using a separate netmask column +# 和前一行相同,但是使用了一个独立的掩码列 # # TYPE DATABASE USER IP-ADDRESS IP-MASK METHOD host all all 127.0.0.1 255.255.255.255 trust -# The same over IPv6. +# IPv6 上相同的规则 # # TYPE DATABASE USER ADDRESS METHOD host all all ::1/128 trust -# The same using a host name (would typically cover both IPv4 and IPv6). +# 使用主机名的相同规则(通常同时覆盖 IPv4 和 IPv6)。 # # TYPE DATABASE USER ADDRESS METHOD host all all localhost trust -# Allow any user from any host with IP address 192.168.93.x to connect -# to database "postgres" as the same user name that ident reports for -# the connection (typically the operating system user name). +# 允许来自任意具有 IP 地址192.168.93.x 的主机上任意 +# 用户以 ident 为该连接所报告的相同用户名连接到 +# 数据库 "postgres"(通常是操作系统用户名)。 # # TYPE DATABASE USER ADDRESS METHOD host postgres all 192.168.93.0/24 ident -# Allow any user from host 192.168.12.10 to connect to database -# "postgres" if the user's password is correctly supplied. +# 如果用户的密码被正确提供,允许来自主机 192.168.12.10 +# 的任意用户连接到数据库 "postgres"。 # # TYPE DATABASE USER ADDRESS METHOD host postgres all 192.168.12.10/32 scram-sha-256 -# Allow any user from hosts in the example.com domain to connect to -# any database if the user's password is correctly supplied. +# 如果用户的密码被正确提供,允许 example.com 域中主机上 +# 的任意用户连接到任意数据库。 # -# Require SCRAM authentication for most users, but make an exception -# for user 'mike', who uses an older client that doesn't support SCRAM -# authentication. +# 为大部分用户要求SCRAM认证,但是用户'mike'是个例外, +# 他使用的是不支持SCRAM认证的旧客户端。 # # TYPE DATABASE USER ADDRESS METHOD host all mike .example.com md5 host all all .example.com scram-sha-256 -# In the absence of preceding "host" lines, these three lines will -# reject all connections from 192.168.54.1 (since that entry will be -# matched first), but allow GSSAPI-encrypted connections from anywhere else -# on the Internet. The zero mask causes no bits of the host IP address to -# be considered, so it matches any host. Unencrypted GSSAPI connections -# (which "fall through" to the third line since "hostgssenc" only matches -# encrypted GSSAPI connections) are allowed, but only from 192.168.12.10. +# 如果没有前面的 "host" 行,这三行 +# 将拒绝所有来自 192.168.54.1的连接(因为该条目将首先被匹配), +# 但是允许来自互联网其他任何地方的 +# GSSAPI 加密连接。零掩码表示不会考虑主机 IP 地址中的任何位, +# 因此它会匹配任意主机。未加密的 GSSAPI 连接 +# (由于 "hostgssenc" 只匹配加密的 GSSAPI 连接,因此它们会继续匹配到第三行) +# 也是允许的,但只能来自 192.168.12.10。 # # TYPE DATABASE USER ADDRESS METHOD host all all 192.168.54.1/32 reject hostgssenc all all 0.0.0.0/0 gss host all all 192.168.12.10/32 gss -# Allow users from 192.168.x.x hosts to connect to any database, if -# they pass the ident check. If, for example, ident says the user is -# "bryanh" and he requests to connect as PostgreSQL user "guest1", the -# connection is allowed if there is an entry in pg_ident.conf for map -# "omicron" that says "bryanh" is allowed to connect as "guest1". +# 允许来自 192.168.x.x 主机的用户连接到任意数据库,如果它们能够 +# 通过 ident 检查。例如,假设 ident说用户是 "bryanh" 并且他要求以 +# PostgreSQL 用户 "guest1" 连接,如果在 pg_ident.conf 有一个映射 +# "omicron" 的条目表明 "bryanh" 被允许以 "guest1" 连接,则该连接将被允许。 # # TYPE DATABASE USER ADDRESS METHOD host all all 192.168.0.0/16 ident map=omicron -# If these are the only three lines for local connections, they will -# allow local users to connect only to their own databases (databases -# with the same name as their database user name) except for administrators -# and members of role "support", who can connect to all databases. The file -# $PGDATA/admins contains a list of names of administrators. Passwords -# are required in all cases. +# 如果这些是本地连接的唯一三行,它们将允许本地用户只连接到 +# 自己的数据库(与其数据库用户名同名的数据库),但管理员和 +# 角色 "support" 的成员除外,他们可以连接到所有数据库。 +# 文件 $PGDATA/admins 包含管理员名称列表。 +# 所有情况下都要求提供密码。 # # TYPE DATABASE USER ADDRESS METHOD local sameuser all md5 local all @admins md5 local all +support md5 -# The last two lines above can be combined into a single line: +# 上面的最后两行可以被整合为一行: local all @admins,+support md5 -# The database column can also use lists and file names: +# 数据库列也可以用列表和文件名: local db1,db2,@demodbs all md5 @@ -686,7 +701,7 @@ omicron bryanh guest1 - Peer 认证通常适用于本地连接,不过在某些情况下,信任认证也可能已经足够。 + 通常建议对本地连接使用 Peer 认证,不过在某些情况下,信任认证也可能已经足够。 密码认证是远程连接最容易采用的选择。 其余所有选项都需要某种外部安全基础设施(通常是认证服务器,或用于签发 SSL 证书的证书颁发机构),或者属于平台特定功能。 @@ -705,16 +720,14 @@ omicron bryanh guest1 - trust认证对于单用户工作站的本地连接是非常合适和方便的。通常它本身适用于一台多用户机器。不过,只要你利用文件系统权限限制了对服务器的 Unix 域套接字文件的访问,即使在多用户机器上,你也可以使用trust。 要做这些限制,你可以设置中描述的unix_socket_permissions配置参数(可能还有unix_socket_group)。 或者你可以设置unix_socket_directories配置参数来把 Unix 域套接字文件放在一个经过恰当限制的目录中。 + trust认证对于单用户工作站的本地连接是非常合适和方便的。通常它本身适用于一台多用户机器。不过,只要你利用文件系统权限限制了对服务器的 Unix 域套接字文件的访问,即使在多用户机器上,你也可能可以使用trust。 要做这些限制,你可以设置中描述的unix_socket_permissions配置参数(可能还有unix_socket_group)。 或者你可以设置unix_socket_directories配置参数来把 Unix 域套接字文件放在一个经过恰当限制的目录中。 设置文件系统权限只能有助于 Unix 套接字连接。本地 TCP/IP 连接不会被文件系统权限限制。因此,如果你想利用文件系统权限来控制本地安全,那么从pg_hba.conf中移除host ... 127.0.0.1 ...行,或者把它改为一个非trust认证方法。 - - 如果通过指定trustpg_hba.conf行让你信任每一个被允许连接到服务器的机器上的用户,trust认证只适合 TCP/IP 连接。为任何不是来自localhost(127.0.0.1)的 TCP/IP 连接使用trust很少是合理的。 - + 只有当你信任由 pg_hba.conf 中指定 trust 的行所允许连接的每台机器上的每个用户时,trust 认证才适合用于 TCP/IP 连接。对来自 localhost(127.0.0.1)以外的任何 TCP/IP 连接使用 trust,通常都不合理。 @@ -755,11 +768,9 @@ omicron bryanh guest1 md5 - - 方法md5使用一种自定义的安全性较低的挑战-响应机制。它能防止密码嗅探并且防止密码在服务器上以明文存储,但是无法保护攻击者想办法从服务器上窃取了密码哈希的情况。此外,现在认为MD5哈希算法对于确定攻击已经不再安全。 - + 方法md5使用一种自定义的、安全性较低的挑战-响应机制。它能防止密码嗅探,并避免在服务器上以明文存储密码;但如果攻击者设法从服务器上窃取了密码哈希,它就无法提供保护。此外,如今已不再认为 MD5 哈希算法能抵御有决心的攻击者。 - md5 方法不能与 功能一起使用。 + md5方法不能与功能一起使用。 为了简化从md5方法到较新的SCRAM方法的转变,如果在pg_hba.conf中指定了md5但是用户在服务器上的密码是为SCRAM(见下文)加密的,则将自动选择基于SCRAM的认证。 @@ -787,7 +798,7 @@ omicron bryanh guest1 - 要把现有安装从 md5 升级到 scram-sha-256,需要先确保所有正在使用的客户端库都足够新并支持 SCRAM,然后在 postgresql.conf 中设置 password_encryption = 'scram-sha-256',要求所有用户重新设置密码,并将 pg_hba.conf 中的认证方法说明改为 scram-sha-256。 + 要把现有安装从 md5 升级到 scram-sha-256,需要先确保所有正在使用的客户端库都足够新并支持 SCRAM,然后在 postgresql.conf 中设置 password_encryption = 'scram-sha-256',要求所有用户重新设置密码,并将 pg_hba.conf 中的认证方法设置改为 scram-sha-256 @@ -920,7 +931,8 @@ omicron bryanh guest1 当使用Kerberos认证时,SSPIGSSAPI的工作方式相同,详见。 - 以下配置选项适用于 SSPI: + + SSPI 支持下列配置选项: @@ -939,7 +951,7 @@ omicron bryanh guest1 如果设为 1,则会在 include_realm 选项中使用域的 SAM 兼容名称(也称为 NetBIOS 名称)。这是默认值。如果设为 0,则会使用 Kerberos 用户主体名中的真实 realm 名称。 - 不要禁用这个选项,除非你的服务器运行在一个域账号(这包括一个域成员系统上的虚拟服务账号)下并且所有通过 SSPI 认证的所有客户端也在使用域账号,否则认证将会失败。 + 不要禁用这个选项,除非你的服务器运行在一个域账号(这包括一个域成员系统上的虚拟服务账号)下并且所有通过 SSPI 认证的客户端也在使用域账号,否则认证将会失败。 @@ -959,7 +971,10 @@ omicron bryanh guest1 map - 允许在系统用户名与数据库用户名之间建立映射。详见 。对于 username@EXAMPLE.COM(或较少见的 username/hostbased@EXAMPLE.COM)这样的 SSPI/Kerberos 主体,映射所用的用户名是 username@EXAMPLE.COM(或相应的 username/hostbased@EXAMPLE.COM),除非将 include_realm 设为 0,此时映射所见的系统用户名为 username(或 username/hostbased)。 + + 允许在系统用户名和数据库用户名之间进行映射。详见 。 + 对于 SSPI/Kerberos 主体,例如 username@EXAMPLE.COM(或者较少见的 username/hostbased@EXAMPLE.COM),用于映射的用户名分别是 username@EXAMPLE.COM(或 username/hostbased@EXAMPLE.COM),除非已经将 include_realm 设为 0;在那种情况下,映射时视为系统用户名的是 username(或 username/hostbased)。 + @@ -999,7 +1014,7 @@ omicron bryanh guest1 map - 允许在系统用户和数据库用户名称之间进行映射。详细信息请参见。 + 允许在系统用户名和数据库用户名之间进行映射。详见 @@ -1013,7 +1028,7 @@ omicron bryanh guest1
RFC 1413 - 标识协议的本意不是作为一种认证或访问控制协议。 + 标识协议的本意不是作为一种授权或访问控制协议。
@@ -1040,7 +1055,7 @@ omicron bryanh guest1 map - 允许在系统用户和数据库用户名称之间进行映射。详细信息请参见。 + 允许在系统用户名和数据库用户名之间进行映射。详见 @@ -1060,17 +1075,21 @@ omicron bryanh guest1 LDAP - 这种认证方法与 password 类似,只是使用 LDAP 验证密码。LDAP 仅用于验证用户名与密码的组合。因此,必须先在数据库中创建该用户,才能使用 LDAP 进行认证。 + + 这种认证方法的工作方式与 password 类似,只不过它使用 LDAP 作为密码验证方法。LDAP 只用于验证用户名/密码对。因此,在使用 LDAP 进行认证之前,用户必须已经存在于数据库中。 + LDAP 认证可以在两种模式下工作。第一种模式称为简单绑定模式,服务器会绑定到按 prefix username suffix 形式构造出的可分辨名称。通常,prefix 参数用于指定 cn=,或在 Active Directory 环境中指定 DOMAIN\suffix 则用于指定非 Active Directory 环境中 DN 的剩余部分。 - 第二种模式称为搜索+绑定模式,服务器首先使用由 ldapbinddnldapbindpasswd 指定的固定用户名和密码绑定到 LDAP 目录,并搜索试图登录数据库的用户。如果没有配置用户名和密码,则会尝试对目录进行匿名绑定。搜索会在 ldapbasedn 指定的子树上进行,并尝试对 ldapsearchattribute 指定的属性做精确匹配。一旦在搜索中找到了该用户,服务器就会作为该用户重新绑定到目录,并使用客户端指定的密码来验证登录是否正确。这种模式与 Apache mod_authnz_ldappam_ldap 等软件中的 LDAP 认证方案相同。这种方法使目录中用户对象的位置更具灵活性,但会对 LDAP 服务器额外发起两次请求。 + 第二种模式称为搜索+绑定模式,服务器首先使用由 ldapbinddnldapbindpasswd 指定的固定用户名和密码绑定到 LDAP 目录,并搜索试图登录数据库的用户。如果没有配置用户名和密码,则会尝试对目录进行匿名绑定。搜索会在 ldapbasedn 指定的子树上进行,并尝试对 ldapsearchattribute 指定的属性做精确匹配。一旦在搜索中找到了该用户,服务器会断开连接,再作为该用户重新绑定到目录,并使用客户端指定的密码来验证登录是否正确。这种模式与 Apache mod_authnz_ldappam_ldap 等软件中的 LDAP 认证方案相同。这种方法使目录中用户对象的位置更具灵活性,但会与 LDAP 服务器建立两个独立的连接。 - 以下配置选项适用于两种模式: + + 以下配置选项在两种模式下都使用: + ldapserver @@ -1091,8 +1110,7 @@ omicron bryanh guest1 ldapscheme - 设置为ldaps以使用LDAPS。这是一种非标准的使用LDAP - 进行SSL加密的方式,受一些LDAP服务器实现支持。另请参阅ldaptls + 设置为ldaps以使用LDAPS。这是一种非标准的通过 SSL 使用 LDAP 的方式,受一些LDAP服务器实现支持。另请参阅ldaptls 选项作为替代。 @@ -1110,7 +1128,9 @@ omicron bryanh guest1 注意使用ldapschemeldaptls仅会加密PostgreSQL 服务器和LDAP服务器之间的通信。PostgreSQL 服务器和PostgreSQL客户端之间的连接仍是未加密的,除非也在其上使用SSL。 - 以下选项仅适用于简单绑定模式: + + 下列选项只被用于简单绑定模式: + ldapprefix @@ -1130,7 +1150,9 @@ omicron bryanh guest1 - 以下选项仅适用于搜索加绑定模式: + + 以下选项仅在搜索+绑定模式中使用: + ldapbasedn @@ -1195,7 +1217,9 @@ ldap[s]://host[:port]/ - 将简单绑定的配置选项与搜索加绑定的选项混用会导致错误。 + + 将简单绑定模式的配置选项与搜索+绑定模式的配置选项混用是错误的。 + 在使用搜索+绑定模式时,可以使用由 ldapsearchattribute 指定的单个属性执行搜索,也可以使用由 ldapsearchfilter 指定的自定义搜索过滤器执行搜索。指定 ldapsearchattribute=foo 等价于指定 ldapsearchfilter="(foo=$username)"。如果两个选项都未指定,则默认使用 ldapsearchattribute=uid。 @@ -1205,25 +1229,35 @@ ldap[s]://host[:port]/PostgreSQL 编译时使用了 OpenLDAP 作为 LDAP 客户端库,则可以省略 ldapserver 设置。在这种情况下,会通过 RFC 2782 DNS SRV 记录查找主机名和端口列表。查找的名称是 _ldap._tcp.DOMAIN,其中 DOMAINldapbasedn 中提取。 - 下面是 LDAP 简单绑定配置的示例: + + 下面是一个简单绑定 LDAP 配置示例: + host ... ldap ldapserver=ldap.example.net ldapprefix="cn=" ldapsuffix=", dc=example, dc=net" -当请求以数据库用户 someuser 的身份连接数据库服务器时,PostgreSQL 会尝试使用 DN cn=someuser, dc=example, - dc=net 和客户端提供的密码绑定到 LDAP 服务器。如果连接成功,就会授予数据库访问权限。 + + 当请求以数据库用户 someuser 连接数据库服务器时,PostgreSQL 将尝试使用 DN cn=someuser, dc=example, dc=net 和客户端提供的密码绑定到 LDAP 服务器。如果该连接成功,数据库访问就会被授予。 + 下面是搜索加绑定配置的示例: host ... ldap ldapserver=ldap.example.net ldapbasedn="dc=example, dc=net" ldapsearchattribute=uid 当请求以数据库用户 someuser 的身份连接数据库服务器时,PostgreSQL 会尝试匿名绑定到 LDAP 服务器(因为没有指定 ldapbinddn),并在指定的基础 DN 下搜索 (uid=someuser)。如果找到了条目,就会尝试使用找到的信息和客户端提供的密码进行绑定。如果第二次连接成功,就会授予数据库访问权限。 - 下面是用 URL 表示的相同搜索加绑定配置: + + 下面是以 URL 形式写出的同一个搜索+绑定配置: + host ... ldap ldapurl="ldap://ldap.example.net/dc=example,dc=net?uid?sub" -一些支持 LDAP 认证的其他软件也使用相同的 URL 格式,因此更容易共享配置。 + + 某些支持 LDAP 认证的其他软件也使用相同的 URL 格式,因此共享这类配置会更容易。 + - 下面是搜索加绑定配置的示例,使用 ldapsearchfilter 代替 ldapsearchattribute,以便通过用户 ID 或电子邮件地址进行认证: + + 这里是一个搜索+绑定配置的示例,它使用 ldapsearchfilter 而不是 ldapsearchattribute 来允许用用户 ID 或电子邮件地址进行认证: + host ... ldap ldapserver=ldap.example.net ldapbasedn="dc=example, dc=net" ldapsearchfilter="(|(uid=$username)(mail=$username))" - 下面的搜索加绑定配置通过 DNS SRV 发现来查找 LDAP 服务的主机名和端口,所用域名为 example.net: + + 这是一个搜索+绑定配置的示例,它使用 DNS SRV 发现来查找域名 example.net 的 LDAP 服务的主机名和端口。 host ... ldap ldapbasedn="dc=example,dc=net" @@ -1452,7 +1486,7 @@ FATAL: user "andym" does not exist FATAL: database "testdb" does not exist - 你试图连接的数据库不存在。注意,如果你没有指定数据库名,默认会使用数据库用户名作为数据库名。 + 你试图连接的数据库不存在。注意,如果你没有指定数据库名,默认会使用数据库用户名作为数据库名,但这不一定是所需的数据库名。 diff --git a/zh/13/config.sgml b/zh/13/config.sgml index 8fd9ed96..11487410 100644 --- a/zh/13/config.sgml +++ b/zh/13/config.sgml @@ -17,6 +17,7 @@ 设置参数 + 参数名称和值 @@ -43,11 +44,12 @@ + 字符串: 通常值被包括在单引号内,值内部的任何单引号都需要被双写。不过,如果值是一个简单数字或者 标识符,引号通常可以被省略。 - (与 SQL 关键字匹配的值需要在某些上下文中引用。) + (与 SQL 关键字匹配的值在某些上下文中需要加引号。) @@ -62,8 +64,16 @@ + - 带单位的数字:某些数值参数具有隐含单位,因为它们描述的是内存量或时间量。单位可能是字节、千字节、块(通常为八千字节)、毫秒、秒或分钟。不带修饰的数值会使用该设置的默认单位,可通过pg_settings.unit获知该单位。为方便起见,可以显式指定设置的单位,例如用'120 ms'表示时间值,系统会将它转换为参数的实际单位。注意,使用此功能时必须把值写成字符串(加引号)。单位名称区分大小写,数值和单位之间可以有空白。 + 带单位的数字: + 一些数字参数具有隐含单位,因为它们描述的是内存或时间量。单位可能是字节、千字节、块 + (通常为 8 千字节)、毫秒、秒或分钟。这类设置若给出不带单位的数字值,就会使用该设置的默认单位, + 可以通过 pg_settings.unit 了解该默认单位。为了方便, + 也可以显式指定单位,例如把时间值写成 '120 ms',系统会将其转换为该参数的实际单位。 + 注意,要使用这一特性,值必须写成字符串(带引号)。单位名称区分大小写,并且数字值与单位之间可以有空白。 + + 可用的内存单位是 B(字节)、kB(千字节)、 @@ -81,7 +91,12 @@ h(小时)和d(天)。 - 如果带单位指定了小数值,且存在下一级更小的单位,就会将其舍入为该更小单位的整数倍。例如,30.1 GB会被转换为30822 MB而不是32319628902 B。如果参数属于整数类型,则在所有单位转换之后,最后再舍入为整数。 + + + 如果指定了带单位的小数值,并且存在更小一级的单位,则会将其四舍五入为该更小单位的整数倍。 + 例如,30.1 GB会被转换为30822 MB,而不是32319628902 B。 + 如果参数是整数类型,则在完成所有单位转换之后还会再做一次整数取整。 + @@ -96,15 +111,25 @@ + 通过配置文件影响参数 - 设置这些参数最基本的方法是编辑文件postgresql.confpostgresql.conf,该文件通常保存在数据目录中。初始化数据库集簇目录时会安装一份默认副本。该文件可能如下所示: + + 设置这些参数最基本的方法是编辑文件 + postgresql.confpostgresql.conf, + 它通常位于数据目录中。在数据库集簇目录初始化时,会安装该文件的一个默认副本。其内容示例如下: + # This is a comment log_connections = yes log_destination = 'syslog' search_path = '"$user", public' shared_buffers = 128MB -每行指定一个参数。名称与值之间的等号可以省略。空白没有特殊意义(引号内的参数值除外),空行会被忽略。井号(#)将该行的剩余部分标记为注释。不是简单标识符或数字的参数值必须用单引号括起。要在参数值中嵌入单引号,可以写两个单引号(推荐)或反斜线加单引号。如果文件中包含同一参数的多个条目,则只采用最后一个,忽略其余条目。 + + 每行指定一个参数。名称和值之间的等号是可选的。空白不重要(引号括起的参数值内部除外),空行会被忽略。 + 井号(#)表示该行余下部分是注释。不是简单标识符或数字的参数值必须用单引号括起。 + 要在参数值中嵌入单引号,可以写两个单引号(推荐)或使用反斜线转义单引号。 + 如果文件包含相同参数的多个条目,则忽略除最后一个之外的所有条目。 + 以这种方式设定的参数为集簇提供了默认值。除非这些设置被覆盖,活动会话看到的就是这些设置。 @@ -149,7 +174,8 @@ shared_buffers = 128MB - 通过 SQL 影响参数 + + 通过SQL影响参数 PostgreSQL提供了三个SQL命令来建立配置默认值。 @@ -160,14 +186,16 @@ shared_buffers = 128MB + - 命令允许针对一个数据库覆盖其全局设置。 + 命令允许针对各个数据库覆盖全局设置。 + - 命令允许用用户指定的值来覆盖全局设置和数据库设置。 + 命令允许用针对特定用户设置的值来覆盖全局设置和数据库设置。 @@ -186,6 +214,7 @@ shared_buffers = 128MB + 命令允许察看任何参数的当前值。对应的SQL函数是 current_setting(setting_name text) (参见 )。 @@ -193,6 +222,7 @@ shared_buffers = 128MB + 那些可以在会话本地设置的参数,允许通过命令修改当前会话的参数值;它对其他会话没有影响。 相应的SQL函数是set_config(setting_name, new_value, is_local) @@ -217,9 +247,15 @@ shared_buffers = 128MB - 使用作用于此视图,具体来说就是更新其setting列,就等同于发出SET命令。例如,下述命令: + + + 在这个视图上使用并且指定更新setting + 列,其效果等同于发出SET命令。例如,下面的命令 + SET configuration_parameter TO DEFAULT; -等同于: + + 等效于: + UPDATE pg_settings SET setting = reset_val WHERE name = 'configuration_parameter'; @@ -229,23 +265,38 @@ UPDATE pg_settings SET setting = reset_val WHERE name = 'configuration_parameter + 通过 Shell 影响参数 - 除了在数据库或者角色层面上设置全局默认值或者进行覆盖,你还可以通过 shell 工具把设置 + 除了设置全局默认值或在数据库、角色级别覆盖默认值之外,你还可以通过 shell 工具把设置 传递给PostgreSQL。服务器和libpq 客户端库都能通过 shell 接受参数值。 - 在服务器启动期间,可以通过postgres命令的命令行参数传递参数设置。例如: + + + 在服务器启动期间,可以通过命令行参数把参数设置传递给 + postgres命令。例如: + postgres -c log_connections=yes -c log_destination='syslog' -以这种方式提供的设置会覆盖通过postgresql.confALTER SYSTEM进行的设置,因此不重启服务器就无法全局更改它们。 + + 这种方式提供的设置会覆盖通过postgresql.conf或者 + ALTER SYSTEM提供的设置,因此除了重启服务器之外无法从全局上改变它们。 + - 通过libpq启动客户端会话时,可以用PGOPTIONS环境变量指定参数设置。以这种方式建立的设置成为会话整个生命周期内的默认值,但不影响其他会话。出于历史原因,PGOPTIONS的格式与启动postgres命令时使用的格式相似;具体而言,必须指定标志。例如: + + + 当通过libpq启动一个客户端会话时,可以使用PGOPTIONS + 环境变量指定参数设置。这种方式建立的设置构成了会话生存期间的默认值,但是不会影响 + 其他的会话。由于历史原因,PGOPTIONS的格式和启动 + postgres命令时用到的相似,特别是标志必须被指定。 + 例如: + env PGOPTIONS="-c geqo=off -c statement_timeout=5min" psql @@ -290,7 +341,7 @@ include 'filename' 还有一个 include_if_exists 指令,其行为与 include 相同, 但在被引用文件不存在或无法读取时有所不同。普通的 include 会将其视为错误, - 而 include_if_exists 只会记录一条消息并继续处理引用配置文件。 + 而 include_if_exists 只会记录一条消息并继续处理引用它的配置文件。 @@ -301,21 +352,21 @@ include 'filename' postgresql.conf 文件也可以包含 include_dir 指令, 用来指定一个应被包含的配置文件目录。其用法如下: - include_dir 'directory' - - 非绝对目录名会被解释为相对于引用配置文件所在目录的路径。在指定目录中, +include_dir 'directory' + + 非绝对目录名会被解释为相对于引用它的配置文件所在目录的路径。在指定目录中, 只有名称以 .conf 结尾的非目录文件才会被包含。以 . 开头的文件名也会被忽略,以避免在某些平台上误处理隐藏文件。包含目录中的多个文件会按文件名顺序处理 (依据 C 区域规则排序,即数字在字母之前,大写字母在小写字母之前)。 - 包括文件或目录可以被用来在逻辑上分隔数据库配置的各个部分,而不是用一个很大的postgresql.conf文件。 + 包含文件或目录可以用来在逻辑上分隔数据库配置的各个部分,而不是用一个很大的postgresql.conf文件。 考虑一个有两台数据库服务器的公司,每一个都有不同的内存量。 - 很可能配置的元素都会被共享,例如用于日志的参数。但是两者关于内存的参数将会不同。 + 两者很可能会共享部分配置,例如日志设置。但是两者关于内存的参数将会不同。 并且还可能会有服务器相关的自定义。 一种管理这类情况的方法是将你的站点的自定义配置修改分成三个文件。 - 你可以把下面的内容加入到你的postgresql.conf文件末尾来包括它们: + 你可以把下面的内容加入到你的postgresql.conf文件末尾来包含它们: include 'shared.conf' include 'memory.conf' @@ -376,7 +427,7 @@ include_dir 'conf.d' - 指定用于数据存储的目录。这个选项只能在服务器启动时设置。 + 指定用于数据存储的目录。这个参数只能在服务器启动时设置。 @@ -436,7 +487,7 @@ include_dir 'conf.d' - 指定可被服务器创建的用于管理程序的额外进程 ID(PID)文件。这个参数只能在服务器启动的时候设置。 + 指定服务器应创建的额外进程 ID(PID)文件的名称,供服务器管理程序使用。这个参数只能在服务器启动的时候设置。 @@ -447,15 +498,15 @@ include_dir 'conf.d' - 如果你想把配置文件放在别的地方而不是数据目录中,那么postgres 命令行选项或者环境变量PGDATA必须指向包含配置文件的目录,并且postgresql.conf中(或者命令行上)的data_directory参数必须显示数据目录实际存放的地方。请注意,data_directory将覆盖PGDATA指定的数据目录位置,但是不覆盖配置文件的位置。 + 如果你想把配置文件放在别的地方而不是数据目录中,那么postgres 命令行选项或者环境变量PGDATA必须指向包含配置文件的目录,并且postgresql.conf中(或者命令行上)的data_directory参数必须设置为数据目录的实际位置。请注意,data_directory将覆盖PGDATA指定的数据目录位置,但是不覆盖配置文件的位置。 - 如果你愿意,可以使用选项config_filehba_file和/或ident_file单独指定配置文件名称和位置。config_file只能在postgres命令行上指定,但是其他文件可以在主配置文件中设置。如果所有三个参数外加data_directory被显式地设置,则不必指定PGDATA。 + 如果你愿意,可以使用选项config_filehba_file和/或ident_file单独指定配置文件名称和位置。config_file只能在postgres命令行上指定,但是其他参数可以在主配置文件中设置。如果所有三个参数外加data_directory被显式地设置,则不必指定PGDATA - 在设置任何这些参数时,相对路径将被解释为相对于postgres启动路径的路径。 + 在设置任何这些参数时,相对路径将被解释为相对于启动 postgres 时所在目录的路径。 @@ -477,7 +528,7 @@ include_dir 'conf.d' - 指定服务器用于监听来自客户端应用程序的连接的TCP/IP地址(指服务器网卡IP地址)。 + 指定服务器用于监听来自客户端应用程序的连接的TCP/IP地址。 该值采用逗号分隔的主机名和/或数字IP地址的形式。特殊条目*对应于所有可用的IP接口。 条目0.0.0.0允许监听所有IPv4地址,::允许监听所有IPv6地址。 如果列表为空,则服务器不会在任何IP接口上监听,此时只能使用Unix域套接字进行连接。 @@ -500,11 +551,11 @@ include_dir 'conf.d' - - - 服务器监听的 TCP 端口;默认是 5432 。请注意服务器会同一个端口号监听所有的 IP 地址。这个参数只能在服务器启动时设置。 - - + + 服务器监听的 TCP 端口,默认是 5432。请注意,服务器监听的所有 IP 地址都使用同一个端口号。 + 此参数只能在服务器启动时设置。 + + @@ -600,25 +651,19 @@ include_dir 'conf.d' - 设置 Unix 域套接字的访问权限。Unix 域套接字使用普通的 Unix 文件系统权限集。这个参数值应该是数字的形式,也就是系统调用chmodumask接受的 形式(如果使用自定义的八进制格式,数字必须以一个0(零)开头)。 + 设置 Unix 域套接字的访问权限。Unix 域套接字使用通常的 Unix 文件系统权限集。参数值应是以 chmodumask 系统调用所接受格式指定的数字权限模式。(要使用惯用的八进制格式,数字必须以 0(零)开头。) - - 默认的权限是0777,意思是任何人都可以连接。合理的候选是0770(只有用户和同组的人可以访问, 又见unix_socket_group)和0700(只有用户自己可以访问)(请注意,对于 Unix 域套接字,只有写权限有麻烦,因此没有对读取和执行权限的设置和收回)。 + 默认权限是 0777,表示任何人都可以连接。合理的其他取值包括 0770(仅属主和所属组,另见 unix_socket_group)和 0700(仅属主)。(注意,对 Unix 域套接字而言,只有写权限起作用,因此设置或撤销读权限和执行权限没有意义。) - - 这个访问控制机制与中的用户认证没有关系。 + 此访问控制机制独立于 中描述的机制。 - - 这个参数只能在服务器启动时设置。 + 此参数只能在服务器启动时设置。 - - 这个参数与完全忽略套接字权限的系统无关,尤其是自版本10以上的Solaris。 - 在那些系统上,可以通过把unix_socket_directories指向一个把搜索权限 - 限制给指定用户的目录来实现相似的效果。 + 此参数对完全忽略套接字权限的系统无效,尤其是 Solaris(截至 Solaris 10)。在这些系统上,可以将 unix_socket_directories 指向一个仅向目标用户授予搜索权限的目录,以达到类似效果。 @@ -631,10 +676,8 @@ include_dir 'conf.d' - - 通过Bonjour广告服务器的存在。默认值是关闭。 - 这个参数只能在服务器启动时设置。 + 启用通过 Bonjour 通告服务器存在的功能。默认值为关闭。此参数只能在服务器启动时设置。 @@ -647,11 +690,11 @@ include_dir 'conf.d' - - - 指定Bonjour服务名称。空字符串''(默认值)表示使用计算机名。 如果编译时没有打开Bonjour支持那么将忽略这个参数。这个参数只能在服务器启动时设置。 - - + + 指定 Bonjour 服务名。空字符串 ''(默认值)表示使用计算机名。 + 如果编译时未启用 Bonjour 支持,则此参数会被忽略。此参数只能在服务器启动时设置。 + + @@ -796,7 +839,7 @@ include_dir 'conf.d' 设置服务器的Kerberos密钥文件的位置。 - 默认为FILE:/usr/local/pgsql/etc/krb5.keytab(其中目录部分是在构建时由sysconfdir指定的;用pg_config --sysconfdir来决定)。 + 默认为FILE:/usr/local/pgsql/etc/krb5.keytab(其中目录部分是在构建时由sysconfdir指定的;可用pg_config --sysconfdir来确定该目录)。 如果这个参数被设为空字符串,它将被忽略,并且系统依赖的默认值被应用。 这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 详情请参考。 @@ -819,6 +862,7 @@ include_dir 'conf.d' + db_user_namespace (boolean) @@ -855,14 +899,14 @@ include_dir 'conf.d' - + SSL - 查看以获取有关设置SSL的更多信息。 + 关于 SSL 的设置,参见 @@ -998,7 +1042,7 @@ include_dir 'conf.d' - 可用的密码组细节可能会随着OpenSSL 版本变化。 + 可用的密码套件细节可能会随着OpenSSL 版本变化。 可使用命令 openssl ciphers -v 'HIGH:MEDIUM:+3DES:!aNULL'来查看当前安装的OpenSSL版本的实际细节。 注意这个列表是根据服务器密钥类型在运行时过滤过的。 @@ -1013,17 +1057,16 @@ include_dir 'conf.d' - 指定是否使用服务器的 SSL 密码首选项,而不是用客户端的。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 - 默认值是 on。 + 指定是否使用服务器的 SSL 密码套件优先顺序,而非客户端的优先顺序。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。默认值为 on - - 9.4 之前的PostgreSQL版本没有这个设置并且总是使用客户端的首选项。这个设置主要用于与那些版本 - 的向后兼容性。使用服务器的首选项通常会更好,因为服务器更可能会被合适地配置。 + PostgreSQL 9.4 之前的版本没有此设置,始终采用客户端的优先顺序。此设置主要用于与这些旧版本保持向后兼容。采用服务器的优先顺序通常更好,因为服务器更可能得到适当配置。 + + ssl_ecdh_curve (string) @@ -1032,19 +1075,10 @@ include_dir 'conf.d' - 指定在 ECDH 密钥交换中使用的曲线名称。它需要被所有连接的客户端支持。 - 不必与服务器椭圆曲线密钥所使用的曲线相同。 - 该参数只能在postgresql.conf文件中或服务器命令行上设置。 - 默认值为prime256v1。 + 指定在 ECDH 密钥交换中使用的曲线名称。所有连接的客户端都必须支持该曲线。它不必与服务器椭圆曲线密钥使用的曲线相同。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。默认值为 prime256v1 - - OpenSSL最常见的曲线名称是: - prime256v1 (NIST P-256)、 - secp384r1 (NIST P-384)、 - secp521r1 (NIST P-521)。 - openssl ecparam -list_curves 命令可以显示可用曲线的完整列表, - 但并非所有曲线都可用于 TLS。 + OpenSSL 中最常见的曲线名称为:prime256v1(NIST P-256)、secp384r1(NIST P-384)、secp521r1(NIST P-521)。可以用 openssl ecparam -list_curves 命令显示可用曲线的完整列表,但其中并非所有曲线都能用于 TLS @@ -1057,19 +1091,14 @@ include_dir 'conf.d' - - 设置要使用的最小 SSL/TLS 协议版本。当前可用的版本包括:TLSv1TLSv1.1TLSv1.2TLSv1.3。 - 旧版本的 OpenSSL 库不支持所有值;如果选择了不支持的设置,将会引发错误。 - TLS 1.0 之前的协议版本,也就是 SSL 版本 2 和 3,总是被禁用的。 + 设置要使用的最低 SSL/TLS 协议版本。当前有效值为:TLSv1TLSv1.1TLSv1.2TLSv1.3。较旧版本的 OpenSSL 库不支持所有值;如果选择了不支持的设置,就会报错。TLS 1.0 之前的协议版本,即 SSL 2 和 3,始终被禁用。 - - 默认为TLSv1.2, 在本文撰写时的行业最佳实践。 + 默认值为 TLSv1.2,符合本文撰写时的行业最佳实践。 - - 这个参数只能在postgresql.conf文件中或通过服务器命令行进行设置。 + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 @@ -1082,15 +1111,11 @@ include_dir 'conf.d' - - 设定要使用的最大SSL/TLS协议版本。 - 有效的版本为 , 添加一个空字符串,允许任何协议版本。 - 默认为允许任何版本。设置最大协议版本主要用于测试,或者某个组件在与较新的协议配合工作时出现了问题。 + 设置要使用的最高 SSL/TLS 协议版本。有效值与 相同,此外还可设为空字符串,表示允许任意协议版本。默认允许任意版本。设置最高协议版本主要用于测试,或处理某些组件无法正常配合更新协议工作的问题。 - - 这个参数只能在postgresql.conf文件中或通过服务器命令行进行设置。 + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 @@ -1103,13 +1128,11 @@ include_dir 'conf.d' - - 指定含有用于SSL密码的所谓临时DH家族的Diffie-Hellman参数的文件名。默认值为空,这种情况下将使用内置的默认DH参数。使用自定义的DH参数可以降低攻击者破解众所周知的内置DH参数的风险。可以用命令openssl dhparam -out dhparams.pem 2048创建自己的DH参数文件。 + 指定包含 Diffie-Hellman 参数的文件名,这些参数用于所谓临时 DH 系列的 SSL 密码套件。默认值为空,此时使用编译时内置的默认 DH 参数。如果攻击者破解了众所周知的内置 DH 参数,使用自定义 DH 参数可以降低由此带来的风险。可以用命令 openssl dhparam -out dhparams.pem 2048 创建自己的 DH 参数文件。 - - 这个参数只能在postgresql.conf文件中或通过服务器命令行进行设置。 + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 @@ -1122,21 +1145,17 @@ include_dir 'conf.d' - - 设置当需要一个密码(例如一个私钥)来解密SSL文件时会调用的一个外部命令。默认情况下,这个参数为空,表示使用内置的提示机制。 + 设置获取用于解密私钥等 SSL 文件的口令时要调用的外部命令。默认值为空,表示使用内置的提示机制。 - - 该命令必须将密码打印到标准输出并且以代码0退出。在该参数值中,%p被替换为一个提示字符串(要得到文字%,应该写成%%)。注意该提示字符串将可能含有空格,因此要确保加上适当的引号。如果输出的末尾有单一的新行,它会被剥离掉。 + 该命令必须将口令输出到标准输出,并以退出码 0 结束。参数值中的 %p 会被替换为提示字符串。(要表示字面值 %,应写成 %%。)提示字符串可能包含空白,因此务必正确加引号。如果输出末尾有一个换行符,会将其去掉。 - - 该命令实际上并不一定要提示用户输入一个密码。它可以从文件中读取密码、从钥匙链得到密码等等。确保选中的机制足够安全是用户的责任。 + 该命令不一定要提示用户输入口令,也可以从文件读取口令、从钥匙链获取口令等。用户应自行确保所选机制足够安全。 - - 这个参数只能在postgresql.conf文件中或通过服务器命令行进行设置。 + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 @@ -1149,13 +1168,10 @@ include_dir 'conf.d' - 这个参数决定在配置重载期间如果一个密钥文件需要密码时,是否也调用ssl_passphrase_command设置的密码命令。 - 如果这个参数为off(默认),那么在重载期间将忽略ssl_passphrase_command,如果在此期间需要密码则SSL配置将不会被重载。 - 对于要求一个TTY(当服务器正在运行时可能是不可用的)来进行提示的命令,这种设置是合适的。 - 例如,如果密码是从一个文件中得到的,将这个参数设置为on可能是合适的。 + 此参数决定:配置重载期间,如果密钥文件需要口令,是否也调用 ssl_passphrase_command 设置的口令命令。如果此参数为 off(默认值),则重载时会忽略 ssl_passphrase_command,如果需要口令,就不会重载 SSL 配置。此设置适合需要通过 TTY 提示用户的命令,因为服务器运行期间可能无法使用 TTY。例如,如果从文件中获取口令,则适合将此参数设为 on。 - 这个参数只能在postgresql.conf文件中或通过服务器命令行进行设置。 + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 @@ -1178,22 +1194,15 @@ include_dir 'conf.d' - - 设置数据库服务器将使用的共享内存缓冲区量。默认通常是 128 兆字节(128MB),但是如果你的内核设置不支持(在initdb时决定),那么可以会更少。 - 这个设置必须至少为 128 千字节。不过为了更好的性能,通常会使用明显高于最小值的设置。 - 如果指定值时没有单位,则以块为单位,即BLCKSZ字节,通常为8kB.(BLCKSZ 的非默认值改变最小值。) - 此参数只能在服务器启动时设置。 + 设置数据库服务器用于共享内存缓冲区的内存量。默认值通常为 128 兆字节(128MB),但如果内核设置不支持,则可能更小(在 initdb 期间确定)。此设置必须至少为 128 千字节。不过,要获得良好性能,通常需要远高于该最小值的设置。如果指定值时没有单位,则以块为单位,即 BLCKSZ 字节,通常为 8kB。(BLCKSZ 的非默认值会改变该最小值。)此参数只能在服务器启动时设置。 - - 如果有一个专用的 1GB 或更多内存的数据库服务器,一个合理的shared_buffers开始值是系统内存的 25%。即使更大的shared_buffers有效,也会造成一些工作负载, 但因为PostgreSQL同样依赖操作系统的高速缓冲区,将shared_buffers设置为超过 40% 的RAM不太可能比一个小点值工作得更好。为了能把对写大量新的或改变的数据的处理分布在一个较长的时间段内,shared_buffers更大的设置通常要求对max_wal_size也做相应增加。 + 如果专用数据库服务器具有 1GB 或更多内存,shared_buffers 的合理初始值是系统内存的 25%。对于某些工作负载,将 shared_buffers 设得更大也有效,但由于 PostgreSQL 同时依赖操作系统缓存,将超过 40% 的内存分配给 shared_buffers 不太可能比更小的值效果更好。将 shared_buffers 设得更大时,通常还需要相应增加 max_wal_size,以便将大量新数据或已修改数据的写入过程分散到更长的时间内。 - - 如果系统内存小于 1GB,一个较小的 RAM 百分数是合适的,这样可以为操作系统留下足够的空间。 + 对于内存少于 1GB 的系统,适合使用更小的内存比例,以便为操作系统留出足够空间。 - @@ -1204,6 +1213,7 @@ include_dir 'conf.d' + 控制是否为主共享内存区域请求巨型页。有效值是try(默认)、on以及off。该参数只能在服务器启动时设置。如果huge_pages被设置为try,则服务器将尝试请求巨型页,但是如果失败会退回到默认的方式。如果为on,请求巨型页失败将使得服务器无法启动。如果为off,则不会请求巨型页。 @@ -1214,19 +1224,19 @@ include_dir 'conf.d' - 巨型页面的使用会导致更小的页面表以及花费在内存管理上的 CPU 时间更少,从而提高性能。更多有关Linux上使用巨型页面的细节请见。 + 巨型页的使用会导致更小的页表以及花费在内存管理上的 CPU 时间更少,从而提高性能。更多有关Linux上使用巨型页的细节请见 巨型页在Windows上被称为大页面。 要使用大页面,需要为运行PostgreSQL的Windows用户账号分配在内存中锁定页面的用户权限。 可以使用Windows的组策略工具(gpedit.msc)来分配用户权限在内存中锁定页面。 - 为了在命令窗口以单进程(而不是Windows服务)的方式启动数据库服务器,命令窗口必须以管理员身份运行或者禁用用户访问控制(UAC)。 + 为了在命令窗口以独立进程(而不是Windows服务)的方式启动数据库服务器,命令窗口必须以管理员身份运行或者禁用用户访问控制(UAC)。 当UAC被启用时,普通的命令窗口会在启动时收回用户权限在内存中锁定页面。 - 注意这种设置仅影响主共享内存区域。Linux、FreeBSD以及Illumos之类的操作系统也能为普通内存分配自动使用巨型页(也被称为超级页或者页面),而不需要来自PostgreSQL的显式请求。在Linux上,这被称为transparent huge pagestransparent huge pages(THP,透明巨型页)。已知这种特性对某些Linux版本上的某些用户会导致PostgreSQL的性能退化,因此当前并不鼓励使用它(与huge_pages的显式使用不同)。 + 注意这种设置仅影响主共享内存区域。Linux、FreeBSD以及Illumos之类的操作系统也能为普通内存分配自动使用巨型页(也被称为超级页或者页面),而不需要来自PostgreSQL的显式请求。在Linux上,这被称为transparent huge pages透明巨型页(THP,透明巨型页)。已知这种特性对某些Linux版本上的某些用户会导致PostgreSQL的性能退化,因此当前并不鼓励使用它(与huge_pages的显式使用不同)。 @@ -1239,16 +1249,11 @@ include_dir 'conf.d' - - 为每个数据库会话设置用于临时缓冲区的最大内存。这些缓冲区是仅用于访问临时表的会话本地缓冲区。 - 如果指定值时没有单位,则以块为单位,即BLCKSZ字节,通常为8kB。 - 默认为 8 兆字节(8MB)。(如果BLCKSZ不是 8 kB,则默认值按比例缩放。) - 这个设置可以在独立的会话内部被改变,但是只有在会话第一次使用临时表之前才能改变; 在会话中随后企图改变该值是无效的。 + 设置每个数据库会话用于临时缓冲区的最大内存量。这些是会话本地的缓冲区,仅用于访问临时表。如果指定值时没有单位,则以块为单位,即 BLCKSZ 字节,通常为 8kB。默认值为 8 兆字节(8MB)。(如果 BLCKSZ 不是 8kB,则默认值按比例变化。)可以在单个会话内更改此设置,但必须在该会话首次使用临时表之前更改;此后尝试更改该值,对该会话不会产生影响。 - - 一个会话将按照temp_buffers给出的限制根据需要分配临时缓冲区。如果在一个并不需要大量临时缓冲区的会话里设置一个大的数值, 其开销只是一个缓冲区描述符,或者说temp_buffers每增加一则增加大概 64 字节。不过,如果一个缓冲区被实际使用,那么它就会额外消耗 8192 字节(或者BLCKSZ字节)。 + 会话会按需分配临时缓冲区,上限为 temp_buffers。对于实际不需要很多临时缓冲区的会话,将此参数设得较大时,开销仅为 temp_buffers 每增加一就多分配一个缓冲区描述符,约为 64 字节。不过,如果实际使用了某个缓冲区,还会为它额外消耗 8192 字节(一般而言为 BLCKSZ 字节)。 @@ -1261,16 +1266,13 @@ include_dir 'conf.d' - 设置可以同时处于prepared状态的事务的最大数目(见)。把这个参数设置 为零(这是默认设置)将禁用预备事务特性。这个参数只能在服务器启动时设置。 + 设置可同时处于预备状态的事务的最大数量(见 )。将此参数设为零(默认值)会禁用预备事务功能。此参数只能在服务器启动时设置。 - - 如果你不打算使用预备事务,可以把这个参数设置为零来防止意外创建预备事务。如果你正在使用预备事务,你将希望把max_prepared_transactions至少设置为一样大,因此每一个会话可以有一个预备事务待处理。 + 如果不打算使用预备事务,应将此参数设为零,以防意外创建预备事务。如果使用预备事务,通常应将 max_prepared_transactions 设为不小于 的值,以便每个会话都能有一个待处理的预备事务。 - - 当运行一个备库时,你必须设置这个参数等于或大于主库上的参数。 - 否则,备库上将不允许查询。 + 运行备库时,必须将此参数设为与主库相同或更大的值。否则,备库上将不允许执行查询。 @@ -1283,19 +1285,10 @@ include_dir 'conf.d' - 设置查询操作(如排序或哈希表)在写入临时磁盘文件之前可使用的基本最大内存量。 - 如果未指定单位,则将其视为千字节。默认值为四兆字节(4MB)。 - 请注意,复杂查询可能同时执行多个排序和哈希操作, - 每个操作通常允许在开始将数据写入临时文件之前使用此值指定的内存量。 - 此外,可能有多个正在运行的会话同时执行此类操作。 - 因此,使用的总内存量可能是work_mem值的多倍; - 在选择值时必须牢记这一事实。排序操作用于ORDER BYDISTINCT和合并连接。 - 哈希表用于哈希连接、基于哈希的聚合和IN子查询的基于哈希的处理。 + 设置查询操作(如排序或哈希表)在写入临时磁盘文件之前可使用的基础最大内存量。如果未指定单位,则以千字节为单位。默认值为 4 兆字节(4MB)。请注意,复杂查询可能同时执行多个排序和哈希操作,每个操作在开始向临时文件写入数据之前,通常都可以使用此值指定的内存量。此外,多个正在运行的会话也可能并发执行此类操作。因此,使用的总内存量可能是 work_mem 值的数倍;选择此值时必须考虑这一点。排序操作用于 ORDER BYDISTINCT 和归并连接。哈希表用于哈希连接、基于哈希的聚合、以及基于哈希的 IN 子查询处理。 - 基于哈希的操作通常比等效的基于排序的操作对可用内存更敏感。 - 哈希表的内存限制通过将work_mem乘以hash_mem_multiplier计算。 - 这使得基于哈希的操作可以使用超过通常work_mem基本内存量的内存。 + 与等效的排序操作相比,基于哈希的操作通常对可用内存更敏感。哈希表的内存上限由 work_mem 乘以 hash_mem_multiplier 计算得到。因此,基于哈希的操作可以使用超过通常的 work_mem 基础量的内存。 @@ -1308,17 +1301,11 @@ include_dir 'conf.d' - - 用于计算哈希操作可以使用的最大内存量。最终限制由将work_mem乘以hash_mem_multiplier确定。 - 默认值为1.0,这使得基于哈希的操作与基于排序的操作受到相同的work_mem简单最大值的限制。 + 用于计算基于哈希的操作可以使用的最大内存量。最终上限由 work_mem 乘以 hash_mem_multiplier 确定。默认值为 1.0,此时基于哈希的操作与基于排序的操作一样,都受到 work_mem 这一简单上限的限制。 - - 考虑在查询操作频繁溢出的环境中增加hash_mem_multiplier, - 特别是当简单增加work_mem导致内存压力时(内存压力通常表现为间歇性的内存不足错误)。 - 将设置调到1.5或2.0通常在混合工作负载中有效。在已将work_mem增加到40MB或更高的环境中, - 可以考虑将设置调高至2.0-8.0或更高。 + 如果查询操作经常溢写磁盘,可以考虑增加 hash_mem_multiplier,尤其是在单纯增加 work_mem 会导致内存压力的情况下(内存压力通常表现为间歇性的内存不足错误)。对于混合工作负载,设为 1.5 或 2.0 可能有效。如果 work_mem 已增加到 40MB 或更高,则将该值进一步设为 2.0 - 8.0 或更高可能有效。 @@ -1331,18 +1318,13 @@ include_dir 'conf.d' - 指定维护操作(如 VACUUMCREATE INDEX 和 - ALTER TABLE ADD FOREIGN KEY)可使用的最大内存量。 - 如果指定值时未带单位,则按千字节解释。默认值为 64 兆字节(64MB)。 - 由于数据库会话一次只能执行一个这样的操作,而一个安装通常也不会有很多此类操作并发运行, - 因此把该值设置得明显大于 work_mem 通常是安全的。更大的设置可能改善清理和恢复数据库转储的性能。 + 指定维护操作(如 VACUUMCREATE INDEXALTER TABLE ADD FOREIGN KEY)可使用的最大内存量。如果未指定单位,则以千字节为单位。默认值为 64 兆字节(64MB)。由于一个数据库会话一次只能执行一个此类操作,而一个数据库系统通常也不会并发运行很多此类操作,因此可以安全地将该值设得远大于 work_mem。更大的设置可能改善清理和恢复数据库转储的性能。 - 请注意,当 autovacuum 运行时,分配的内存量最多可能达到此值的倍,因此请小心,不要将默认值设置得过高。 - 单独设置可能有助于控制这一点。 + 注意,自动清理运行时,最多可能分配此内存量的 倍,因此不要将默认值设得过高。单独设置 可能有助于控制这一点。 - 请注意,为收集死元组标识符,VACUUM最多只能使用1GB内存。 + 注意,在收集死元组标识符时,VACUUM 最多只能使用 1GB 内存。 @@ -1355,15 +1337,10 @@ include_dir 'conf.d' - 指定每个自动清理工作者进程能使用的最大内存量。 - 如果指定值时没有单位,则以千字节为单位。 - 其默认值为 -1,表示转而使用 的值。 - 当运行在其他上下文环境中时,这个设置对VACUUM的行为没有影响。 - 这个参数只能在postgresql.conf中或者服务器命令行上设置。 + 指定每个自动清理工作进程可使用的最大内存量。如果未指定单位,则以千字节为单位。默认值为 -1,表示改用 的值。该设置不影响其他上下文中运行的 VACUUM 的行为。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 - 为收集死元组标识符,autovacuum 最多只能使用1GB内存, - 因此将autovacuum_work_mem设置为更高的值,不会影响 autovacuum 扫描表时可以收集的死元组数量。 + 在收集死元组标识符时,自动清理最多只能使用 1GB 内存,因此将 autovacuum_work_mem 设得更高,不会影响自动清理扫描表时能收集的死元组数量。 @@ -1376,13 +1353,10 @@ include_dir 'conf.d' - - 指定逻辑解码要使用的最大内存量,在将某些解码的更改写入本地磁盘之前。 - 这将限制逻辑流复制连接使用的内存量。它默认为 64 兆字节(64MB)。 - 由于每个复制连接仅使用此大小的单个缓冲区,并且安装通常不会同时具有多个此类连接(受 max_wal_senders 的限制),因此将此值设置得明显高于 work_mem是安全的,从而减少写入磁盘的解码更改数量。 + 指定逻辑解码在将部分已解码的更改写入本地磁盘之前可使用的最大内存量。它限制了流式逻辑复制连接使用的内存量。默认值为 64 兆字节(64MB)。由于每个复制连接仅使用一个此大小的缓冲区,而一个数据库系统通常不会同时有很多此类连接(受 max_wal_senders 限制),因此可以安全地将该值设得远高于 work_mem,以减少写入磁盘的已解码更改数量。 - + @@ -1396,11 +1370,11 @@ include_dir 'conf.d' 指定服务器执行栈的最大安全深度。此参数的理想设置是由内核强制执行的实际栈大小限制 - (如由ulimit -s或本地等效设置),减去大约一兆字节的安全边界。 - 需要安全边界是因为服务器中并非每个例程都检查栈深度,而只在关键的潜在递归例程中检查。 + (如由ulimit -s或本地等效设置),减去大约一兆字节的安全余量。 + 需要安全余量是因为服务器中并非每个例程都检查栈深度,而只在关键的潜在递归例程中检查。 如果未指定单位,则将其视为千字节。默认设置为两兆字节(2MB), 这是保守且不太可能引起崩溃的小值。但是,这可能太小,无法执行复杂函数。 - 只有超级用户能更改这个设置。 + 只有超级用户才能更改此设置。 @@ -1417,12 +1391,8 @@ include_dir 'conf.d' - - 指定服务器应用于主共享内存区域的共享内存实现,包括 PostgreSQL 的共享缓冲区和其他共享数据。 - 可能的值为 mmap(对使用 mmap 分配的匿名共享内存)、sysv(通过 shmget 分配的 System V 共享内存)和 windows(Windows 共享内存)。 - 并非在所有平台上都支持全部值;第一个受支持的选项是该平台的默认选项。 - sysv 选项不是任何平台的默认选项,通常不建议使用,因为它通常需要非默认的内核设置来允许大量的地址分配(参见 )。 + 指定服务器用于主共享内存区域的共享内存实现,该区域存放 PostgreSQL 的共享缓冲区及其他共享数据。可选值为 mmap(使用 mmap 分配的匿名共享内存)、sysv(通过 shmget 分配的 System V 共享内存)和 windows(Windows 共享内存)。并非所有平台都支持所有值;第一个受支持的选项是该平台的默认值。sysv 不是任何平台的默认选项,通常不建议使用,因为它一般需要更改内核的默认设置才能分配大量内存(见 )。此参数只能在服务器启动时设置。 @@ -1435,16 +1405,8 @@ include_dir 'conf.d' - - 指定服务器应该使用的动态共享内存实现。可能的值包括posix(使用shm_open分配的POSIX共享内存), - sysv(通过shmget分配的System V共享内存), - windows(用于Windows共享内存), - 和mmap(使用存储在数据目录中的内存映射文件模拟共享内存)。 - 并非所有平台都支持所有值;通常第一个支持的选项是该平台的默认值。 - 通常不建议使用mmap选项,因为操作系统可能会反复将修改的页面写回磁盘,增加系统I/O负载; - 但在调试时,当pg_dynshmem目录存储在RAM磁盘上,或者其他共享内存设施不可用时,可能会有用。 - 该参数只能在服务器启动时设置。 + 指定服务器应使用的动态共享内存实现。可选值为 posix(使用 shm_open 分配的 POSIX 共享内存)、sysv(通过 shmget 分配的 System V 共享内存)、windows(Windows 共享内存)、mmap(使用存放在数据目录中的内存映射文件模拟共享内存)。并非所有平台都支持所有值;第一个受支持的选项是该平台的默认值。mmap 不是任何平台的默认选项,通常不建议使用,因为操作系统可能会反复将修改过的页面写回磁盘,增加系统 I/O 负载;不过,在调试、将 pg_dynshmem 目录存放在 RAM 磁盘上,或其他共享内存设施不可用时,它可能有用。此参数只能在服务器启动时设置。 @@ -1465,17 +1427,11 @@ include_dir 'conf.d' - - 指定进程可以用于临时文件(如排序和哈希临时文件)或保留游标的存储文件的最大磁盘空间。 - 尝试超过此限制的事务将被取消。 - 如果未指定单位,则将其视为千字节。 - -1(默认值)表示没有限制。 - 只有超级用户能更改这个设置。 + 指定一个进程可用于临时文件的最大磁盘空间,例如排序和哈希临时文件,或保留游标的存储文件。尝试超过此限制的事务将被取消。如果未指定单位,则以千字节为单位。-1(默认值)表示没有限制。只有超级用户才能更改此设置。 - - 这个设置约束着一个给定PostgreSQL进程在任何瞬间所使用的所有临时文件的总空间。应该注意的是,与在查询执行中在幕后使用的临时文件相反,显式临时表所用的磁盘空间被这个设置所限制。 + 此设置限制单个 PostgreSQL 进程在任意时刻使用的所有临时文件的总空间。需要注意,显式临时表所用的磁盘空间计入该上限;计入的是查询执行过程中内部使用的临时文件。 @@ -1495,31 +1451,30 @@ include_dir 'conf.d' - 设置每个服务器子进程允许同时打开的最大文件数。默认值是一千个文件。 - 如果内核实施了安全的单进程限制,就不必担心此设置。但在某些平台上 - (尤其是大多数 BSD 系统),内核允许单个进程打开的文件数很多,以至于 - 当多个进程都试图打开这么多文件时,会超过系统实际能够支持的数量。 - 如果遇到Too many open files错误,可以尝试减小此设置。 - 此参数只能在服务器启动时设置。 + 设置每个服务器子进程允许同时打开的最大文件数量。默认值为一千个文件。如果内核强制实施了安全的每进程上限,就不必担心此设置。但在某些平台上(尤其是大多数 BSD 系统),内核允许单个进程打开的文件数量很大,如果很多进程都尝试打开这么多文件,就会远超系统实际能够支持的总量。如果遇到 Too many open files(打开的文件过多)错误,可尝试减小此设置。此参数只能在服务器启动时设置。 - + + 基于代价的清理延迟 - 在命令的执行过程中,系统维持着一个内部计数器来跟踪各种被执行的I/O操作的估算开销。当累计的代价达到一个限制(由vacuum_cost_limit指定),执行这些操作的进程将按照vacuum_cost_delay所指定的休眠一小段时间。然后它将重置计数器并继续执行。 + 执行 命令期间,系统维护一个内部计数器,记录已执行的各种 I/O 操作的估算代价。 + 当累计代价达到上限(由 vacuum_cost_limit 指定)时,执行该操作的进程会休眠一小段时间,时长由 vacuum_cost_delay 指定。 + 随后重置计数器并继续执行。 - 这个特性的出发点是允许管理员降低这些命令对并发的数据库活动产生的I/O影响。在很多情况下,VACUUMANALYZE等维护命令能否快速完成并不重要,而非常重要的是这些命令不会对系统执行其他数据库操作的能力产生显著的影响。基于代价的清理延迟提供了一种方式让管理员能够保证这一点。 + 此功能让管理员能够降低这些命令对并发数据库活动的 I/O 影响。在许多情况下,VACUUMANALYZE 等维护命令是否快速完成并不重要, + 但避免它们显著干扰系统执行其他数据库操作的能力通常很重要。基于代价的清理延迟为管理员提供了实现这一点的方法。 - 对于手动发出的VACUUM命令,该特性默认被禁用。要启用它,只要把vacuum_cost_delay变量设为一个非零值。 + 对于手动执行的 VACUUM 命令,此功能默认禁用。要启用它,将 vacuum_cost_delay 变量设为非零值。 @@ -1531,19 +1486,13 @@ include_dir 'conf.d' - - - 当超出开销限制时进程将要休眠的时间量。如果指定值时没有单位,则以毫秒为单位。 - 其默认值为0,这将禁用基于代价的清理延迟特性。正值将启用基于代价的清理。 - - - - 在使用基于代价的清理时,vacuum_cost_delay的合适值通常很小,也许是小于1毫秒。 - 虽然vacuum_cost_delay可以被设置为毫秒级别的值,但是在较老的平台上可能无法准确地测量这种延迟。 - 在这样的平台上,增加 VACUUM的节流资源消耗在1ms以上,需要改变其他的清理开销参数。 - 尽管如此,你应该保持 vacuum_cost_delay 在平台能持续测量的情况下尽可能小;大延迟没有帮助。 - - + + 超过代价上限后,进程将休眠的时长。如果未指定单位,则以毫秒为单位。默认值为 0,表示禁用基于代价的清理延迟功能。正值会启用基于代价的清理。 + + + 使用基于代价的清理时,vacuum_cost_delay 的合适值通常很小,可能不到 1 毫秒。虽然 vacuum_cost_delay 可以设为以毫秒为单位的小数值,但较旧的平台可能无法准确计量这种延迟。在这些平台上,若要让 VACUUM 的资源用量超过延迟设为 1ms 时的水平,需要调整其他清理代价参数。尽管如此,仍应将 vacuum_cost_delay 设为平台能够稳定计量的尽可能小的值;较大的延迟没有帮助。 + + @@ -1554,11 +1503,10 @@ include_dir 'conf.d' - - - 清理一个在共享缓存中找到的缓冲区的估计代价。它表示锁住缓冲池、查找共享哈希表和扫描页内容的代价。默认值为1。 - - + + 清理在共享缓冲区缓存中找到的缓冲区时所计入的估算代价。它表示锁定缓冲池、查找共享哈希表和扫描页内容的代价。默认值为 1。 + + @@ -1568,12 +1516,10 @@ include_dir 'conf.d' - - 清理一个必须从磁盘上读取的缓冲区的代价。 - 它表示锁住缓冲池、查找共享哈希表、从磁盘读取需要的块以及扫描其内容的代价。 - 默认值为10。 - - + + 清理必须从磁盘读取的缓冲区时所计入的估算代价。它表示锁定缓冲池、查找共享哈希表、从磁盘读取所需数据块并扫描其内容所需的工作量。默认值为 10。 + + @@ -1584,11 +1530,10 @@ include_dir 'conf.d' - - - 当清理修改一个之前干净的块时需要花费的估计代价。它表示再次把脏块刷出到磁盘所需要的额外I/O。默认值为20。 - - + + 清理操作修改原本干净的数据块时所计入的估算代价。它表示再次将脏块刷盘所需的额外 I/O。默认值为 20。 + + @@ -1599,33 +1544,31 @@ include_dir 'conf.d' - - - 将导致清理进程休眠的累计代价。默认值为200。 - - + + 会使清理进程休眠的累计代价。默认值为 200。 + + - - 有些操作会保持关键性的锁,这样可以尽快完成。基于代价的清理延迟在这类操作期间不会发生。因此有可能代价会累计至大大超过指定的限制。为了防止在这种情况下的无意义的长时间延迟,实际延迟的计算方式是vacuum_cost_delay * - accumulated_balance / - vacuum_cost_limit,且最大值是vacuum_cost_delay * 4。 + 某些操作持有关键的锁,因此应尽快完成。这些操作期间不会发生基于代价的清理延迟,所以累计代价可能远超指定上限。 + 为避免此时出现无益的长时间延迟,实际延迟按 vacuum_cost_delay * accumulated_balance / vacuum_cost_limit 计算, + 但最大不超过 vacuum_cost_delay * 4。 - 后台写入器 - 有一个独立的服务器进程,叫做后台写入器,它的功能就是发出写(新的或修改过的)共享缓冲区的命令。 - 当干净的共享缓存数量出现不足时,后台写入器写入一些脏缓存到文件系统,并标记为干净。 - 不过,后台写入器确实会增加 I/O 的总负荷,因为虽然在每个检查点间隔中一个重复弄脏的页面可能只会写出一次,但在同一个间隔中后台写入器可能会把它写出好几次。 - 在这一小节讨论的参数可以被用于调节本地需求的行为。 + 有一个独立的服务器进程,称为后台写入器,负责写出(新的或修改过的)共享缓冲区。 + 当干净的共享缓冲区数量似乎不足时,后台写入器会将一些脏缓冲区写入文件系统,并将其标记为干净。 + 这可以降低处理用户查询的服务器进程找不到干净缓冲区、因而不得不自行写出脏缓冲区的可能性。 + 不过,后台写入器确实会使总体 I/O 负载有所增加:反复变脏的页面原本可能在每个检查点间隔中只写出一次, + 而后台写入器可能在同一间隔内随着它变脏而多次写出。本节参数可用于根据实际需求调整此行为。 @@ -1637,13 +1580,10 @@ include_dir 'conf.d' - - - 指定后台写入器活动轮次之间的延迟。在每个轮次中,写入器都会为一定数量的脏缓冲区发出写操作(可以用下面的参数控制)。 - 然后它就休眠 bgwriter_delay的时长, 然后重复动作。当缓冲池中没有脏缓冲区时,不管 bgwriter_delay,它都会进入更长的休眠。如果指定值时没有单位,则以毫秒为单位。默认值是 200 毫秒(200ms)。 - 注意在许多系统上,休眠延迟的有效解析度是 10 毫秒;因此,为bgwriter_delay设置一个 不是 10 的倍数的值与把它设置为下一个更高的 10 的倍数是一样的效果。这个选项只能在服务器命令行上或者在postgresql.conf文件中设置。 - - + + 指定后台写入器各轮活动之间的延迟。每一轮中,写入器会对一定数量的脏缓冲区发出写操作(由下面的参数控制),然后休眠 bgwriter_delay 指定的时长,再重复此过程。不过,当缓冲池中没有脏缓冲区时,它会进入更长的休眠,而不受 bgwriter_delay 限制。如果未指定单位,则以毫秒为单位。默认值为 200 毫秒(200ms)。注意,在许多系统上,休眠延迟的有效分辨率为 10 毫秒;将 bgwriter_delay 设为不是 10 的倍数的值,可能与将它设为下一个更大的 10 的倍数效果相同。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 + + @@ -1654,11 +1594,10 @@ include_dir 'conf.d' - - - 在每个轮次中,不超过这么多个缓冲区将被后台写入器写出。把这个参数设置为零可禁用后台写出(注意被一个独立、专用辅助进程管理的检查点不受影响)。默认值是 100 个缓冲区。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 - - + + 后台写入器每轮写出的缓冲区数量不会超过此值。设为零会禁用后台写入。(由另一个独立的专用辅助进程管理的检查点不受影响。)默认值为 100 个缓冲区。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 + + @@ -1669,11 +1608,10 @@ include_dir 'conf.d' - - - 每一轮次要写的脏缓冲区的数目基于最近几个轮次中服务器进程需要的新缓冲区的数目。 最近所需的平均值乘以bgwriter_lru_multiplier可以估算下一轮次中将会需要的缓冲区数目。脏缓冲区将被写出直到有很多干净可重用的缓冲区(然而,每一轮次中写出的缓冲区数不超过bgwriter_lru_maxpages)。 因此,设置为 1.0 表示一种刚刚好的策略,这种策略会写出正好符合预测值的数目的缓冲区。 更大大的值可以为需求高峰提供某种缓冲,而更小的值则需要服务进程来处理一些写出操作。默认值是 2.0。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 - - + + 每轮写出的脏缓冲区数量取决于最近几轮服务器进程所需的新缓冲区数量。将近期平均需求乘以 bgwriter_lru_multiplier,即可估算下一轮所需的缓冲区数量。写入器会写出脏缓冲区,直到可用的干净且可重用缓冲区达到这一数量。(不过,每轮写出的缓冲区数量不会超过 bgwriter_lru_maxpages。)因此,设为 1.0 表示采用恰好及时策略,写出的缓冲区数量恰好等于预测需求量。更大的值可为需求突增留出余量,而更小的值则有意将部分写操作留给服务器进程执行。默认值为 2.0。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 + + @@ -1684,18 +1622,16 @@ include_dir 'conf.d' - - - 只要后台写入的数据超过这个数量,尝试强制 OS 把这些写发送到底层存储上。这样做将限制内核页缓存中脏数据的量,降低了在检查点末尾发出一个 fsync 时或者 OS 在后台大批量写回数据时卡住的可能性。 - 那常常会导致大幅度压缩的事务延迟,但是也有一些情况(特别是负载超过但小于 OS 页面高速缓存)的性能会降低。这种设置可能会在某些平台上没有效果。 - 如果指定值时没有单位,则以块为单位,即为BLCKSZ 字节,通常为8kB.合法的范围在0(禁用受控写回)和2MB之间。Linux 上的默认值是512kB,其他平台上是0(如果BLCKSZ不是8kB,则默认值和最大值会按比例缩放至这个值)。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 - - + + 每当后台写入器写出的数据超过此数量时,就尝试强制操作系统将这些写操作发往底层存储。这样可以限制内核页缓存中的脏数据量,降低在检查点结束时调用 fsync,或操作系统在后台以较大批次写回数据时发生停顿的可能性。通常,这能大幅降低事务延迟,但在某些情况下性能可能下降,尤其是工作负载大于 而小于操作系统页缓存时。此设置在某些平台上可能没有效果。如果未指定单位,则以块为单位,即 BLCKSZ 字节,通常为 8kB。有效范围为 0(禁用强制写回)至 2MB。Linux 上的默认值为 512kB,其他平台为 0。(如果 BLCKSZ 不是 8kB,默认值和最大值将按比例变化。)此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 + + - 较小的bgwriter_lru_maxpagesbgwriter_lru_multiplier可以降低由后台写入器造成的额外 I/O 开销。但更可能的是,服务器进程将必须自己发出写入操作,这会延迟交互式查询。 + 较小的 bgwriter_lru_maxpagesbgwriter_lru_multiplier 可以降低后台写入器造成的额外 I/O 负载, + 但也会增加服务器进程必须自行发出写操作的可能性,从而延迟交互式查询。 @@ -1710,29 +1646,19 @@ include_dir 'conf.d' - - 设置PostgreSQL预期可以同时执行的并发磁盘 I/O 操作数量。 - 提高该值会增加任何单个PostgreSQL会话尝试并行发起的 I/O 操作数。 - 允许的范围是 1 到 1000,或者零表示禁用异步 I/O 请求。目前,此设置只影响位图堆扫描。 - - - - 对于磁盘,此设置的一个良好起点是数据库所用的 RAID 0 条带或 RAID 1 镜像中独立磁盘的数量。 - (对于 RAID 5,不应计入奇偶校验盘。)但是,如果数据库经常忙于处理并发会话发出的多个查询,较低的值可能已足以让磁盘阵列保持忙碌。 - 超过使磁盘保持忙碌所需的值只会产生额外的 CPU 开销。 - SSD 和其他基于内存的存储通常可以处理很多并发请求,因此最佳值可能达到数百。 - - - - 异步 I/O 依赖有效的posix_fadvise函数,而某些操作系统缺少该函数。 - 如果不存在该函数,将此参数设置为零以外的任何值都会导致错误。 - 在某些操作系统上(例如 Solaris),该函数虽然存在,但实际上不起任何作用。 - - - - 在支持的系统上默认值为 1,否则为 0。对于位于特定表空间中的表,可以通过设置同名的表空间参数覆盖此值(参见)。 - - + + 设置 PostgreSQL 预期可以同时执行的并发磁盘 I/O 操作数量。提高此值会增加单个 PostgreSQL 会话尝试并行发起的 I/O 操作数量。允许的范围为 1 至 1000,或设为零以禁用异步 I/O 请求。目前,此设置仅影响位图堆扫描。 + + + 对于磁盘,可以将为数据库提供存储的 RAID 0 条带或 RAID 1 镜像中的独立磁盘数量作为合理初始值。(对于 RAID 5,不应计入校验盘。)不过,如果数据库经常忙于执行并发会话发出的多个查询,较小的值可能就足以使磁盘阵列保持繁忙。超过使磁盘保持繁忙所需的值只会增加 CPU 开销。SSD 和其他基于内存的存储通常可以处理大量并发请求,因此最佳值可能达到数百。 + + + 异步 I/O 依赖于有效的 posix_fadvise 函数,而某些操作系统缺少此函数。如果该函数不存在,将此参数设为任何非零值都会报错。在某些操作系统(如 Solaris)上,该函数虽然存在,却实际上不做任何事情。 + + + 支持此功能的系统上默认值为 1,其他系统为 0。对于位于特定表空间中的表,可以通过设置同名的表空间参数覆盖此值(见 )。 + + @@ -1742,13 +1668,13 @@ include_dir 'conf.d' - - 与effective_io_concurrency相似,但用于支持许多客户端会话完成的维护工作。 - - - 在支持的系统上默认值为 10,否则为 0。对于位于特定表空间中的表,可以通过设置同名的表空间参数覆盖此值(参见)。 - - + + 与 effective_io_concurrency 类似,但用于为多个客户端会话执行的维护工作。 + + + 支持此功能的系统上默认值为 10,其他系统为 0。对于位于特定表空间中的表,可以通过设置同名的表空间参数覆盖此值(见 )。 + + @@ -1758,19 +1684,16 @@ include_dir 'conf.d' - - 设置系统能够支持的后台进程的最大数量。这个参数只能在服务器启动时设置。默认值为 8。 + + 设置系统能够支持的后台进程的最大数量。此参数只能在服务器启动时设置。默认值为 8。 - - - 在运行一个备库时,你必须把这个参数设置为等于或者高于主库上的值。 - 否则,备库上将不允许查询。 - - - - 在更改这个值时,考虑也对以及进行调整。 - - + + 运行备库时,必须将此参数设为与主库相同或更大的值。否则,备库上将不允许执行查询。 + + + 更改此值时,也应考虑调整 。 + + @@ -1781,19 +1704,16 @@ include_dir 'conf.d' - - - 设置单个Gather或者Gather Merge节点能够开始的工作者的最大数量。并行工作者会从建立的进程池中取得,数量由限制。注意所要求的工作者数量在运行时可能实际无法被满足。如果这种事情发生,该计划将会以比预期更少的工作者运行,这可能会不太高效。默认值是2。把这个值设置为0将会禁用并行查询执行。 - - - - 注意并行查询可能消耗比非并行查询更多的资源,因为每一个工作者进程时一个完全独立的进程,它对系统产生的影响大致和一个额外的用户会话相同。在为这个设置选择值时,以及配置其他控制资源利用的设置(例如)时,应该把这个因素考虑在内。work_mem之类的资源限制会被独立地应用于每一个工作者,这意味着所有进程的总资源利用可能会比单个进程时高得多。例如,一个使用 4 个工作者的并行查询使用的 CPU 时间、内存、I/O 带宽可能是不使用工作者时的 5 倍之多。 - - - - 并行查询的更多信息请见。 - - + + 设置单个 GatherGather Merge 节点能够启动的工作进程的最大数量。并行工作进程取自 建立的进程池,并受到 的限制。注意,运行时实际可用的工作进程可能不足请求的数量。此时,计划会使用少于预期的工作进程运行,效率可能较低。默认值为 2。设为 0 会禁用并行查询执行。 + + + 注意,并行查询消耗的资源可能远多于非并行查询,因为每个工作进程都是完全独立的进程,对系统的影响大致相当于额外增加一个用户会话。选择此设置的值,以及配置其他控制资源使用的设置(如 )时,都应考虑这一点。work_mem 等资源限制分别应用于每个工作进程,因此所有进程的总资源用量可能远高于单个进程通常的用量。例如,使用 4 个工作进程的并行查询,其 CPU 时间、内存、I/O 带宽等用量可能达到完全不使用工作进程的查询的 5 倍。 + + + 并行查询的更多信息参见 。 + + @@ -1803,18 +1723,13 @@ include_dir 'conf.d' - - - 设置单一工具性命令能够启动的并行工作者的最大数目。 - 当前,支持使用并行工作者的工具性命令是CREATE INDEX,并且只有在构建B-树索引时才能并行,并且 VACUUM 没有 FULL选项。 - 并行工作者从由创建的进程池中取出,数量由控制。 - 注意实际在运行时所请求数量的工作者可能不可用。如果发生这种情况,工具性操作将使用比预期数量少的工作者运行。默认值为2。将这个值设置为0可以禁用工具性命令对并行工作者的使用。 - - - - 注意并行工具性命令不应该消耗比同等数量非并行操作更多的内存。这种策略与并行查询不同,并行查询的资源限制通常是应用在每个工作者进程上。并行工具性命令把资源限制maintenance_work_mem当作对整个工具性命令的限制,而不管其中用到了多少个并行工作者进程。不过,并行工具性命令实际上可能仍会消耗更多的CPU资源和I/O带宽。 - - + + 设置单个工具命令能够启动的并行工作进程的最大数量。目前,支持使用并行工作进程的工具命令包括:构建 B-树索引时的 CREATE INDEX,以及不带 FULL 选项的 VACUUM。并行工作进程取自 建立的进程池,并受到 的限制。注意,运行时实际可用的工作进程可能不足请求的数量。此时,工具操作会使用少于预期的工作进程运行。默认值为 2。设为 0 会禁止工具命令使用并行工作进程。 + + + 注意,并行工具命令的内存消耗不应明显高于等效的非并行操作。这与并行查询的策略不同,后者的资源限制通常分别应用于每个工作进程。并行工具命令将 maintenance_work_mem 视为整个工具命令的资源上限,而不论使用多少个并行工作进程。不过,并行工具命令仍可能消耗多得多的 CPU 资源和 I/O 带宽。 + + @@ -1824,8 +1739,10 @@ include_dir 'conf.d' - 设置系统能够支持的并行操作工作进程最大数量。默认值为 8。增大或减小该值时,也应考虑调整。另外注意,将此值设得高于不会产生效果,因为并行工作进程取自该设置所建立的工作进程池。 - + + 设置系统能够为并行操作提供的工作进程的最大数量。默认值为 8。增大或减小此值时,也应考虑调整 。此外,将此值设得大于 没有效果,因为并行工作进程取自该设置建立的工作进程池。 + + @@ -1836,27 +1753,20 @@ include_dir 'conf.d' - - - 当单个后端写入数据的量超过这个数量时,尝试强制操作系统发送这些写入到底层存储。 - 这样做将限制内核的页面缓存中的脏数据量,降低在检查点末尾发出fsync时暂停的可能性,或者当操作系统在后台大批量的写回数据时。 - 通常的结果会大大减少事务延迟,但也有一些情况,特别是当工作负载大于,但小于操作系统的页面缓存时,性能可能会下降。 - 此设置在某些平台上可能无效。 - 如果指定此值时没有单位,则将其作为块,即BLCKSZ字节,通常为8kB。 - 有效范围在0,禁止强制回写,和2MB之间。 - 默认值是0,即没有强制回写。 - (如果BLCKSZ不是8kB,则最大值按其比例缩放。) - - + + 每当单个后端写出的数据超过此数量时,就尝试强制操作系统将这些写操作发往底层存储。这样可以限制内核页缓存中的脏数据量,降低在检查点结束时调用 fsync,或操作系统在后台以较大批次写回数据时发生停顿的可能性。通常,这能大幅降低事务延迟,但在某些情况下性能可能下降,尤其是工作负载大于 而小于操作系统页缓存时。此设置在某些平台上可能没有效果。如果未指定单位,则以块为单位,即 BLCKSZ 字节,通常为 8kB。有效范围为 0(禁用强制写回)至 2MB。默认值为 0,即不强制写回。(如果 BLCKSZ 不是 8kB,最大值将按比例变化。) + + - - old_snapshot_threshold (integer) - - old_snapshot_threshold配置参数 - - - + + + old_snapshot_threshold (integer) + + old_snapshot_threshold 配置参数 + + + 设置查询快照在使用时不发生snapshot too old错误的最短可用时间。 已死亡超过该阈值的数据允许被清理掉。这有助于在快照长期保持使用时防止膨胀。 @@ -1878,7 +1788,7 @@ include_dir 'conf.d' - 启用此特性后,关系末尾释放出来的空间将不能返还给操作系统,因为那样会移除 + 启用此特性后,关系末尾释放出来的空间将不能返还给操作系统,因为那样可能会移除 检测snapshot too old条件所需的信息。分配给某个关系的全部空间都会一直 归属于该关系,只能在该关系内部重用,除非显式释放(例如使用 VACUUM FULL)。 @@ -1892,8 +1802,8 @@ include_dir 'conf.d' snapshot too old错误的可能性。 - - + + @@ -1919,7 +1829,7 @@ include_dir 'conf.d' wal_level决定多少信息写入到 WAL 中。默认值是replica,它会写入足够的数据以支持WAL归档和复制,包括在备库上运行只读查询。minimal会去掉除从崩溃或者立即关机中进行恢复所需的信息之外的所有记录。最后,logical会增加支持逻辑解码所需的信息。每个层次包括所有更低层次记录的信息。这个参数只能在服务器启动时设置。 - minimal级别生成最少的WAL日志量。它不记录在创建或重写事务中对永久关系的行信息。 + minimal级别生成最少的WAL日志量。对于在当前事务中创建或重写的永久关系,不记录其行信息。 这可以使操作速度更快(参见)。触发此优化的操作包括: ALTER ... SET TABLESPACE @@ -1930,12 +1840,12 @@ include_dir 'conf.d' REINDEX TRUNCATE - 但最少的 WAL 不包含足够的信息来从基础备份和 WAL 日志重建数据,因此必须使用replica或更高级别来启用 WAL 归档 + 但 minimal 级别的 WAL 不包含足够的信息来从基础备份和 WAL 日志重建数据,因此必须使用replica或更高级别来启用 WAL 归档 ()和流复制。 logical级别上,记录与replica相同的信息,以及从WAL中提取逻辑变更集所需的信息。 - 使用logical级别会增加WAL的容量,特别是如果许多表被配置为REPLICA IDENTITY FULL, + 使用logical级别会增加 WAL 的数量,特别是如果许多表被配置为REPLICA IDENTITY FULL, 并且执行了许多UPDATEDELETE语句。 @@ -1962,16 +1872,15 @@ include_dir 'conf.d' - 能安全关闭fsync的环境的示例包括从一个备份文件中初始加载一个新数据库集簇、使用一个数据库集簇来在数据库被删掉并重建之后处理一批数据,或者一个被经常重建并却不用于失效备援的只读数据库克隆。单独的高质量硬件不足以成为关闭fsync的理由。 + 可以安全关闭fsync的情形包括:从备份文件初始装载一个新数据库集簇;用数据库集簇处理一批数据,处理后就丢弃并重建该数据库;或者使用经常重建且不用于故障切换的只读数据库克隆。仅有高质量硬件不足以成为关闭fsync的理由。 - 当把fsync从关闭改成打开时,为了可靠的恢复,需要强制在内核中的所有被修改的缓冲区进入持久化存储。这可以在多个时机来完成: - 在集簇被关闭时或在fsync因为运行initdb --sync-only而打开时、运行sync时、卸载文件系统时或者重启服务器时。 + 为确保将fsync从关闭改为打开后能够可靠恢复,必须将内核中所有已修改的缓冲区强制写入持久存储。可以在集簇已关闭或fsync已开启时,通过运行initdb --sync-only、运行sync、卸载文件系统或重启服务器来完成。 - 在很多情况下,为不重要的事务关闭可以提供很多关闭fsync的潜在性能收益,并不会有的同时, 关闭fsync可以提供很多潜在的性能优势,而不会有伴随着的数据损坏风险。 + 在很多情况下,为非关键事务关闭,可以获得关闭fsync所带来的大部分潜在性能收益,同时避免伴随的数据损坏风险。 @@ -1988,39 +1897,27 @@ include_dir 'conf.d' - 指定数据库服务器返回success指示给客户端之前,必须要完成多少WAL处理。 - 合法的值为remote_apply, on(默认值), remote_write,local, 和 off。 + 指定数据库服务器向客户端返回成功指示之前,必须完成多少 WAL 处理。有效值为remote_applyon(默认值)、remote_writelocaloff - 如果synchronous_standby_names为空,则唯一有意义的设置为onoff ; - remote_applyremote_writelocal都提供与on相同的本地同步级别。 - 所有非off模式的本地行为都是等待WAL的本地刷新到磁盘。 - 在 off模式,无需等待,因此在向客户端报告成功和以后保证事务安全防止服务器崩溃之间可能会出现延迟。 - (最大的延迟是的三倍。) - 不同于,将这个参数设置为off不会产生数据库不一致性的风险:一个操作系统或数据库崩溃可能会造成一些最近据说已提交的事务丢失,但数据库状态是一致的,就像这些事务已经被干净地中止。 - 因此,当性能比完全确保事务的持久性更重要时,关闭synchronous_commit可以作为一个有效的代替手段。更多讨论见。 + 如果synchronous_standby_names为空,只有onoff两种设置有意义;remote_applyremote_writelocal提供的本地同步级别都与on相同。所有非off模式在本地都会等待 WAL 刷写到磁盘。在off模式下则无需等待,因此,向客户端报告成功后,可能还要经过一段时间,才能保证事务不会因服务器崩溃而丢失。(最大延迟为的三倍。)与不同,将此参数设为off不会带来数据库不一致的风险:操作系统或数据库崩溃可能会使一些最近报告已提交的事务丢失,但数据库状态会与这些事务已正常中止时完全相同。因此,当性能比完全确保事务持久性更重要时,关闭synchronous_commit可以是一种有用的替代方案。更多讨论见 - 如果为非空,synchronous_commit也控制是否事务提交将等待它们的 WAL 记录在备库上被处理。 + 如果非空,synchronous_commit还控制事务提交是否等待备库处理其 WAL 记录。 - 当设置为 remote_apply 时,提交将等待,直到来自当前同步备库的答复显示他们已收到事务的提交记录并应用了它,以便它变得对备库上的查询可见,并写入备库上的持久存储。 - 这将导致比以前的设置更大的提交延迟,因为它等待 WAL 重放(replay)。 - 当设置为on时,提交将等待,直到来自于当前同步的备库的回复显示它们已经收到了事务的提交记录并将其刷入了磁盘。 - 这保证事务将不会被丢失,除非主库和所有同步备库都遭受到了数据库存储损坏的问题。 - 当这个参数被设置为remote_write时,提交将等待,直到来自当前的同步备库的回复指示它们已经收到了该事务的提交记录并且已经把该记录写到它们的文件系统,这种设置保证数据得以保存,在PostgreSQL的备库实例崩溃时,但是不能保证备库遭受操作系统级别崩溃时数据能被保持,因为数据不一定必须要在备库上达到持久存储。 - 设置local会导致提交等待本地刷写到磁盘,而不是复制。在使用同步复制时这通常是不可取的,但是为了完整性提供了这个选项。 + 设为remote_apply时,提交会等待当前同步备库回复,确认已收到并应用该事务的提交记录,使其对备库上的查询可见,并且已将其写入备库的持久存储。由于需要等待 WAL 重放,这会比之前的设置产生大得多的提交延迟。设为on时,提交会等待当前同步备库回复,确认已收到事务的提交记录,并已将其刷写到持久存储。这能保证事务不会丢失,除非主库和所有同步备库的数据库存储都损坏。设为remote_write时,提交会等待当前同步备库回复,确认已收到事务的提交记录,并已将其写入各自的文件系统。此设置能保证备库上的PostgreSQL实例崩溃时数据不丢失,但不能保证备库发生操作系统级别崩溃时数据不丢失,因为数据未必已写入备库的持久存储。设为local时,提交会等待本地刷盘,但不等待复制。使用同步复制时通常不希望采用这种设置,提供它是为了使选项完整。 - 这个参数可以随时被修改;任何一个事务的行为由其提交时生效的设置决定。因此,可以同步提交一些事务,同时异步提交其他事务。例如,当默认是相反时,实现一个单一多语句事务的异步提交,在事务中发出SET LOCAL synchronous_commit TO OFF。 + 此参数可以随时更改;每个事务的行为由提交时生效的设置决定。因此,让一些事务同步提交、另一些事务异步提交是可行且有用的。例如,当默认设置要求同步提交时,可以在一个包含多条语句的事务中执行SET LOCAL synchronous_commit TO OFF,使该事务异步提交。 - 概括了 synchronous_commit 各种设置具备的能力。 + 汇总了synchronous_commit各种设置具备的能力。
@@ -2034,9 +1931,9 @@ include_dir 'conf.d' synchronous_commit 设置 - 本地持久提交 - PG 崩溃备库持久提交 - OS 崩溃备库持久提交 + 本地提交持久性 + PG 崩溃后备库提交持久性 + OS 崩溃后备库提交持久性 备库查询一致性 @@ -2100,7 +1997,7 @@ include_dir 'conf.d' - 用来向强制 WAL 更新到磁盘的方法。如果fsync是关闭的,那么这个设置就不相关,因为 WAL 文件更新将根本不会被强制。可能的值是: + 用于将 WAL 更新强制写入磁盘的方法。如果fsync关闭,此设置就没有作用,因为 WAL 文件更新根本不会被强制写入磁盘。可选值为: @@ -2124,7 +2021,7 @@ include_dir 'conf.d' - fsync_writethrough(在每次提交时调用fsync(),强制任何磁盘写高速缓存的直通写) + fsync_writethrough(在每次提交时调用fsync(),强制穿透任何磁盘写缓存) @@ -2136,10 +2033,10 @@ include_dir 'conf.d' - open_* 选项也可以使用O_DIRECT(如果可用)。 + open_* 选项还会使用O_DIRECT(如果可用)。 不是在所有平台上都能使用所有这些选择。 - 默认值是列表中第一个被平台支持的那个, 不过fdatasync是 Linux和FreeBSD中的默认值。 - 默认值不一定是最理想的;有可能需要修改这个设置或系统配置的其他方面来创建一个崩溃-安全的配置,或达到最佳性能。 + 默认值是列表中第一个被平台支持的那个, 不过fdatasync是 Linux 和 FreeBSD 中的默认值。 + 默认值不一定最合适;可能需要更改此设置或系统配置的其他方面,以确保崩溃时的数据安全或达到最佳性能。 这些方面在中讨论。 这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 @@ -2154,11 +2051,11 @@ include_dir 'conf.d' - 当这个参数为打开时,PostgreSQL服务器在一个检查点之后的页面的第一次修改期间将每个页面的全部内容写到 WAL 中。这么做是因为在操作系统崩溃期间正在处理的一次页写入可能只有部分完成,从而导致在一个磁盘页面中混合有新旧数据。在崩溃后的恢复期间,通常存储在 WAL 中的行级改变数据不足以完全恢复这样一个页面。存储整页镜像可以保证页面被正确存储,但代价是增加了必须被写入 WAL 的数据量(因为 WAL 重放总是从一个检查点开始,所以在检查点后每个页面的第一次改变时这样做就够了。因此,一种减小全页面写开销的方法是增加检查点间隔参数值)。 + 启用此参数时,PostgreSQL服务器会在检查点之后首次修改每个磁盘页面时,将该页面的全部内容写入 WAL。这样做是因为,操作系统崩溃时正在进行的页面写入可能只完成了一部分,导致磁盘页面混有新旧数据。通常存储在 WAL 中的行级变更数据不足以在崩溃恢复时完整还原这样的页面。保存整页镜像能保证正确恢复页面,但会增加必须写入 WAL 的数据量。(由于 WAL 重放总是从检查点开始,只需在检查点之后首次修改每个页面时这样做。因此,减少整页写入开销的一种方法是增大检查点间隔参数。) - 把这个参数关闭会加快正常操作,但是在系统失败后可能导致不可恢复的数据损坏,或者静默的数据损坏。其风险类似于关闭fsync, 但是风险较小。并且只有在对该参数建议的相同情况下才应该关闭它。 + 关闭此参数可以加快正常操作,但系统故障后可能出现不可恢复的数据损坏或静默数据损坏。风险与关闭fsync类似,虽然较小,但也只有在该参数建议的相同情形下才应关闭此参数。 @@ -2181,7 +2078,7 @@ include_dir 'conf.d' - 当这个参数为on时,PostgreSQL服务器一个检查点之后页面被第一次修改期间把该磁盘页面的整个内容都写入 WAL,即使对所谓的提示位做非关键修改也会这样做。 + 当这个参数为on时,PostgreSQL服务器在检查点之后首次修改页面时把该磁盘页面的整个内容都写入 WAL,即使对所谓的提示位做非关键修改也会这样做。 @@ -2203,11 +2100,11 @@ include_dir 'conf.d' - 当这个参数为on时,PostgreSQL服务器在打开时或在基础备份期间,压缩写入WAL的整页镜像。在WAL回放期间将对压缩的页面镜像进行解压。默认值是off。只有超级用户能更改这个设置。 + 当这个参数为on时,PostgreSQL服务器会压缩写入 WAL 的整页镜像,例如在启用时、基础备份期间等。在 WAL 重放期间将对压缩的整页镜像进行解压。默认值是off。只有超级用户能更改这个设置。 - 开启这个参数可以在不增加不可恢复的数据损坏风险的情况下减少WAL数据量,但代价是在WAL记录期间用于压缩以及在WAL回放期间用于解压的额外CPU开销。 + 开启此参数可以减少 WAL 数据量,而且不会增加不可恢复的数据损坏风险;代价是在记录 WAL 时压缩、重放 WAL 时解压会额外消耗一些 CPU。 @@ -2222,10 +2119,10 @@ include_dir 'conf.d' - 如果设置为on(默认值),此选项会导致新的 WAL 文件被零填充。 - 在某些文件系统上,这可确保在我们需要写入 WAL 记录之前分配空间。 - 但是,Copy-On-Write(COW)文件系统可能不会从此技术中受益,因此可以选择跳过不必要的工作。 - 如果设置为off,则在创建文件时仅写入最终字节,以便其具有预期大小。 + 如果设置为on(默认值),此选项会导致新的 WAL 文件被零填充。 + 在某些文件系统上,这可确保在我们需要写入 WAL 记录之前分配空间。 + 但是,写时复制(COW)文件系统可能不会从此技术中受益,因此可以选择跳过不必要的工作。 + 如果设置为off,则在创建文件时只写入最后一个字节,以便其具有预期大小。 @@ -2240,8 +2137,8 @@ include_dir 'conf.d' - 如果设置为 on (默认值),此选项通过重命名来回收 WAL 文件,从而避免创建新文件。 - 在 COW 文件系统上,创建新文件系统可能更快,因此提供了禁用此行为的选项。 + 如果设置为 on (默认值),此选项通过重命名来回收 WAL 文件,从而避免创建新文件。 + 在 COW 文件系统上,创建新文件可能更快,因此提供了禁用此行为的选项。 @@ -2259,7 +2156,7 @@ include_dir 'conf.d' - 在每次事务提交时,WAL 缓冲区的内容被写出到磁盘,因此极大的值不可能提供显著的收益。不过,把这个值设置为几个兆字节可以在一个繁忙的服务器(其中很多客户端会在同一时间提交)上提高写性能。由默认设置 -1 选择的自动调节将在大部分情况下得到合理的结果。 + 在每次事务提交时,WAL 缓冲区的内容被写出到磁盘,因此极大的值不太可能带来显著收益。不过,把这个值设置为至少几个兆字节可以在一个繁忙的服务器(其中很多客户端会在同一时间提交)上提高写性能。由默认设置 -1 选择的自动调节将在大部分情况下得到合理的结果。 @@ -2277,9 +2174,9 @@ include_dir 'conf.d' 指定 WAL 写入器刷写 WAL 的频繁程度,以时间为单位。 在刷写WAL之后,写入器将根据wal_writer_delay所给出的时间长度进行睡眠,除非被一个异步提交的事务提前唤醒。 - 如果最近的刷写发生在 wal_writer_delay 之前,并且小于 wal_writer_flush_after WAL的值产生之后,那么WAL只会被写入操作系统,而不会被刷写到磁盘。 + 如果距上次刷盘的时间小于wal_writer_delay,并且自那以后产生的 WAL 数据量小于wal_writer_flush_after,则只将 WAL 写入操作系统,而不刷写到磁盘。 如果指定值时没有单位,则以毫秒作为单位。 - 默认值是 200 毫秒(200ms)。注意在很多系统上,有效的睡眠延迟粒度是 10 毫秒,把wal_writer_delay设置为一个不是 10 的倍数的值,其效果和把它设置为大于该值的下一个 10 的倍数产生的效果相同。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 + 默认值是 200 毫秒(200ms)。注意在很多系统上,有效的睡眠延迟粒度是 10 毫秒,把wal_writer_delay设置为一个不是 10 的倍数的值,其效果可能与将其设置为下一个更大的 10 的倍数相同。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 @@ -2294,8 +2191,8 @@ include_dir 'conf.d' - 指定 WAL 写入器刷写 WAL 的频繁程度,以卷为单位。 - 如果最近的刷写发生在 wal_writer_delay 之前,并且小于 wal_writer_flush_after WAL的值产生之后,那么WAL只会被写入操作系统,而不会被刷写到磁盘。 + 指定 WAL 写入器刷写 WAL 的频繁程度,按数据量衡量。 + 如果距上次刷盘的时间小于wal_writer_delay,并且自那以后产生的 WAL 数据量小于wal_writer_flush_after,则只将 WAL 写入操作系统,而不刷写到磁盘。 如果wal_writer_flush_after被设置为0,则WAL数据总是会被立即刷写。 如果指定值时没有单位,则以WAL块作为单位,即为XLOG_BLCKSZ字节,通常为8kB。 默认是1MB。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 @@ -2313,10 +2210,7 @@ include_dir 'conf.d' - 当wal_levelminimal,并且在创建或重写永久关系之后提交事务时,此设置将确定如何保留新数据。 - 如果数据小于此设置,将其写入 WAL 日志;否则,使用受影响文件的 fsync。 - 根据存储的属性,如果此类提交减慢了并发事务,提高或降低此值可能会有所帮助。 - 如果指定此值时没有单位,则视为千字节。默认为两兆字节(2MB)。 + 当wal_levelminimal,且事务在创建或重写永久关系后提交时,此设置决定如何持久保存新数据。如果数据量小于此设置,就将其写入 WAL;否则,对受影响的文件执行 fsync。如果这类提交拖慢了并发事务,根据存储的特性,增大或减小此值可能有所帮助。未指定单位时以千字节为单位。默认值为两兆字节(2MB)。 @@ -2331,20 +2225,20 @@ include_dir 'conf.d' - 设置commit_delay会在执行WAL刷新之前添加时间延迟。 + 设置commit_delay会在发起 WAL 刷盘之前添加时间延迟。 如果系统负载足够高,使得在给定时间间隔内有更多事务准备提交, - 这可以通过允许更多事务通过单个WAL刷新来提高组提交吞吐量。 - 然而,这也会增加延迟,最多为每个WAL刷新的commit_delay。 - 因为如果没有其他事务准备提交,延迟就是浪费的,所以只有在至少有 - commit_siblings其他事务活动时才会执行延迟, - 当要启动刷新时,如果fsync被禁用,则不会执行延迟。 + 这可以通过允许更多事务通过一次 WAL 刷盘来提高组提交吞吐量。 + 不过,每次 WAL 刷盘的延迟也会因此增加,最多增加commit_delay。 + 如果没有其他事务准备提交,等待就没有意义,因此仅当即将发起刷盘时至少还有 + commit_siblings个其他活动事务,才会等待。 + 此外,如果禁用了fsync,也不会等待。 如果未指定单位,则将其视为微秒。 默认commit_delay为零(无延迟)。 只有超级用户能更改这个设置。 - 在PostgreSQL的 9.3 发布之前,commit_delay的行为不同并且效果更差:它只影响提交,而不是所有 WAL 刷写,并且即使在 WAL 刷写马上就要完成时也会等待一整个配置的延迟。从PostgreSQL 9.3 中开始,第一个准备好刷写的进程会等待配置的间隔,而后续的进程只等到领先者完成刷写操作。 + 在PostgreSQL的 9.3 发布之前,commit_delay的行为不同并且效果更差:它只影响提交,而不是所有 WAL 刷写,并且即使 WAL 刷盘更早完成,也会等待整个配置的延迟时间。从PostgreSQL 9.3 开始,第一个准备好刷写的进程会等待配置的间隔,而后续的进程只等到领先者完成刷写操作。 @@ -2359,7 +2253,7 @@ include_dir 'conf.d' - 在执行commit_delay延迟时,要求的并发活动事务的最小数目。大一些的值会导致在延迟间隔期间更可能有至少另外一个事务准备好提交。默认值是五个事务。 + 执行commit_delay延迟前要求的并发活动事务的最小数目。大一些的值会导致在延迟间隔期间更可能有至少另外一个事务准备好提交。默认值是五个事务。 @@ -2381,7 +2275,7 @@ include_dir 'conf.d' 自动 WAL 检查点之间的最长时间。如果指定值时没有单位,则以秒为单位。 - 合理的范围在 30 秒到 1 天之间。默认是 5 分钟(5min)。增加这个参数的值会增加崩溃恢复所需的时间。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 + 合理的范围在 30 秒到 1 天之间。默认是 5 分钟(5min)。增加这个参数的值可能会增加崩溃恢复所需的时间。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 @@ -2412,7 +2306,7 @@ include_dir 'conf.d' 当执行检查点时写入的数据量超过此数量时,就尝试强制 OS 把这些写发送到底层存储。 这样做将会限制内核页面高速缓存中的脏数据数量,降低在检查点末尾发出fsync或者 OS 在后台大批量写回数据时被卡住的可能性。 - 那常常会导致大幅度压缩的事务延迟,但是也有一些情况(特别是负载超过但小于 OS 页面高速缓存)的性能会降低。 + 这通常能显著降低事务延迟,但是也有一些情况(特别是负载超过但小于 OS 页面高速缓存)的性能会降低。 这种设置可能会在某些平台上没有效果。 如果指定值时没有单位,则以块为单位,即为BLCKSZ 字节,通常为8kB。 合法的范围在0(禁用强制写回)和2MB之间。Linux 上的默认值是256kB,其他平台上是0(如果BLCKSZ不是8kB,则默认值和最大值会按比例缩放到它)。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 @@ -2490,10 +2384,9 @@ include_dir 'conf.d' 当启用archive_mode时,完成的WAL段会通过设置 - 发送到归档存储。除了off, - 要禁用,有两种模式:on和 + 发送到归档存储。除了用于禁用归档的off外,还有两种模式:onalways。在正常操作期间,这两种模式之间没有区别,但当设置为always时, - WAL归档程序在归档恢复或待机模式下也会被启用。在always模式下,从归档中恢复的所有文件 + WAL归档程序在归档恢复或备库模式下也会被启用。在always模式下,从归档中恢复的所有文件 或通过流复制传输的文件将被再次归档。详细信息请参见 @@ -2541,7 +2434,7 @@ include_dir 'conf.d' - 仅在完成的WAL段上调用。 + 只针对已完成的 WAL 段调用。 因此,如果您的服务器生成的WAL流量较少(或者在这样做时有间歇期),在事务完成和安全记录到归档存储之间可能会有很长的延迟。 为了限制未归档数据的年龄,您可以将archive_timeout设置为强制服务器定期切换到新的WAL段文件。 当此参数大于零时,只要自上次段文件切换以来经过了这段时间,并且存在任何数据库活动,包括单个检查点(如果没有数据库活动,则跳过检查点),服务器将切换到新的段文件。 @@ -2561,8 +2454,8 @@ include_dir 'conf.d' 归档恢复 - configuration - of recovery + 配置 + 恢复 一个备库 @@ -2571,7 +2464,7 @@ include_dir 'conf.d' - Recovery 涵盖使用服务器作为备库或用于执行目标恢复。 + 恢复 涵盖使用服务器作为备库或用于执行目标恢复。 通常情况,备库模式用于提供高可用性和/或读可扩展性,而目标恢复用于从数据丢失中恢复。 @@ -2638,7 +2531,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows 这个信息可以被用来把归档截断为支持从当前恢复重启所需的最小值。 对于单一备库配置,模块常常被用在archive_cleanup_command中,例如: archive_cleanup_command = 'pg_archivecleanup /mnt/server/archivedir %r' - 但是注意,如果多个备库正在从同一个归档目录中恢复,你将需要保证只有当任意服务器都不再需要 WAL 文件时才会删除它们。 + 但是注意,如果多个备库正在从同一个归档目录中恢复,你将需要保证只有当所有服务器都不再需要这些 WAL 文件时才会删除它们。 archive_cleanup_command通常被用于一种温备配置(见)中。 要在该命令中嵌入一个真正的%字符,需要写成%% @@ -2691,7 +2584,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows 默认情况下,恢复将会一直恢复到 WAL 日志的末尾。下面的参数可以被用来指定一个更早的停止点。 在recovery_targetrecovery_target_lsnrecovery_target_namerecovery_target_timerecovery_target_xid中, - 最多只能使用一个,如果在配置文件中使用了多个,将会产生一个错误。这个参数只能在服务器启动时设置。 + 最多只能使用一个,如果在配置文件中使用了多个,将会产生一个错误。这些参数只能在服务器启动时设置。 @@ -2724,7 +2617,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows - 这个参数指定(pg_create_restore_point()所创建)的已命名的恢复点,恢复将进入该恢复点。 + 这个参数指定(pg_create_restore_point()所创建)的已命名的恢复点,恢复将进行到该恢复点。 @@ -2739,7 +2632,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows - 此参数指定恢复将执行的时间戳。精确的停止点还受到得影响。 + 此参数指定恢复要进行到的时间戳。精确的停止点还受到的影响。 @@ -2759,7 +2652,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows - 这个参数指定恢复将进入的事务 ID。记住虽然事务 ID 是在事务开始时顺序分配的,但是事务可能以不同的数字顺序完成。 + 这个参数指定恢复要进行到的事务 ID。记住虽然事务 ID 是在事务开始时顺序分配的,但是事务可能以不同的数字顺序完成。 那些在指定事务之前(也可以包括该事务)提交的事务将被恢复。精确的停止点也受到的影响。 @@ -2775,7 +2668,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows - 此参数指定恢复将继续进行的预写日志位置的LSN。精确的停靠点也受 的影响。 + 此参数指定恢复要进行到的预写日志位置的 LSN。精确的停止点也受 的影响。 使用系统数据类型pg_lsn解析此参数。 @@ -2800,28 +2693,33 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows 指定我们是否仅在指定的恢复目标之后停止(on),或者仅在恢复目标之前停止(off)。 适用于或者被指定的情况。 - 这个设置分别控制事务是否有准确的目标WAL位置(LSN)、提交时间或事务ID将被包括在该恢复中。默认值为on。 + 这个设置控制恢复是否包含 WAL 位置(LSN)、提交时间或事务 ID 分别恰好等于目标值的事务。默认值为on + recovery_target_timeline (string) recovery_target_timeline 配置参数 + - 指定恢复到某条时间线。此值可以是数字时间线 ID 或特殊值。 - 值current会沿获取基础备份时的当前时间线恢复。 - 值latest会恢复到归档中找到的最新时间线,这对备库很有用。默认值为latest。 + 指定恢复到一个特定的时间线中。该值可以是数字时间线 ID 或特殊值。 + 值current沿着与执行基础备份时相同的时间线恢复。 + 值latest将恢复到归档中能找到的最新时间线,这在备库中很有用。 + latest是默认值。 + + - 通常只有在复杂的再次恢复情形中才需要设置此参数,也就是需要返回某个本身是在时点恢复之后达到的状态时。 - 相关讨论参见。 + 你通常只需要在复杂的再次恢复场景中设置此参数,也就是当你需要回到某个状态,而该状态本身又是在一次时间点恢复之后达到的。 + 相关讨论见 @@ -2843,14 +2741,14 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows - 使用pause设置的目的是:如果这个恢复目标就是恢复最想要的位置,就允许对数据库执行查询。 + 使用pause设置的目的是允许对数据库执行查询,以检查这个恢复目标是否为最合适的恢复位置。 暂停的状态可以使用pg_wal_replay_resume()(见)继续,这会让恢复终结。 如果这个恢复目标不是想要的停止点,那么关闭服务器,将恢复目标设置改为一个稍后的目标并且重启以继续恢复。 要让实例在想要的重放点那里准备好,shutdown设置可以派上用场。 - 该实例将仍能重放更多 WAL 记录(并且事实上将不得不重放从下一次它被启动后最后一个检查点以来的 WAL 记录)。 + 该实例将仍能重放更多 WAL 记录(并且事实上,下次启动时必须重新回放自上一个检查点以来的 WAL 记录)。 @@ -2861,7 +2759,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows 如果没有设置恢复目标,这个设置没有效果。 如果没有启用pause设置的动作将和shutdown一样。 - 如果在升级期间达到恢复目标,pause 的设置将与 promote的行为相同。 + 如果在备库提升期间达到恢复目标,pause 的设置将与 promote的行为相同。 @@ -2891,23 +2789,26 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows + max_wal_senders (integer) max_wal_senders配置参数 + - 指定来自备库或流式基础备份客户端的并发连接的最大数量(即同时运行 WAL 发送进程的最大数)。 - 默认值是10。值0意味着禁用复制。 - 突然的流式传输客户端断开连接可能留下一个孤立连接槽(知道达到超时),因此这个参数应该设置得略高于最大客户端连接数,这样断开连接的客户端可以立刻重新连接。 - 这个参数只能在服务器启动时被设置。此外,wal_level必须设置为replica或更高级别以允许来自备库的连接。 + 指定来自备库或流式基础备份客户端的最大并发连接数(即同时运行的 WAL 发送进程的最大数量)。 + 默认值为 10。值 0 表示禁用复制。 + 流式客户端突然断开连接后,可能会留下一个孤立连接槽,直到超时才释放。 + 因此,此参数应设置得略高于预期的最大客户端数,使断开连接的客户端能够立即重新连接。 + 此参数只能在服务器启动时设置。此外,wal_level 必须设置为 + replica 或更高级别,才允许来自备库的连接。 - 在运行一个备库时,你必须把这个参数设置为等于或者高于主库上的值。 - 否则,备库上将不允许查询。 - + 运行备库时,必须将此参数设置为大于或等于主库上的值。否则,备库上将不允许查询。 + @@ -2944,16 +2845,19 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows - 指定在备库需要为流复制获取日志段文件的情况下,pg_wal目录下所能保留的过去日志文件段的最小尺寸。 - 如果一个连接到发送服务器的备库落后了超过wal_keep_size兆字节,发送服务器可以移除一个备库仍然需要的 WAL 段,在这种情况下复制连接将被中断。 - 最终结果是下行连接也将最终失败(不过,如果在使用 WAL 归档,备库可以通过从归档获取段来恢复)。 + 指定在 pg_wal 目录中保留的旧 WAL 文件的最小总量, + 以便备库需要时获取这些文件进行流复制。如果连接到发送服务器的备库落后超过 + wal_keep_size 兆字节,发送服务器可能会移除备库仍需要的 WAL 段, + 从而导致复制连接终止。下游连接最终也会因此失败。 + (不过,如果使用了 WAL 归档,备库可以通过从归档获取该段来恢复。) - 只设置pg_wal中保留的文件段的最小尺寸;系统可能需要为 WAL 归档或从一个检查点恢复保留更多段。 - 如果wal_keep_size为零(默认值), 更多的空间来 存放WAL归档或从一个检查点恢复。 - 如果wal_keep_segments是零(缺省), 系统不会为备库目的保留任何多余的段,因此备库可用的旧 WAL 段的数量是一个上个检查点位置和 WAL 归档状态的函数。 - 如果此值被指定时没有单位,则视为兆字节。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 + 此设置只规定 pg_wal 中保留的段的最小总量;系统可能需要为 WAL 归档 + 或从检查点恢复而保留更多段。如果 wal_keep_size 为零(默认值), + 系统不会为备库额外保留任何段,因此备库可用的旧 WAL 段数取决于前一个检查点的位置 + 和 WAL 归档的状态。如果指定值时没有单位,则按兆字节计算。 + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 @@ -2967,14 +2871,18 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows - - 指定在检查点时,replication slots(复制槽)允许在pg_wal目录中保留的WAL文件的最大大小。 - 如果max_slot_wal_keep_size为-1(默认值),复制槽可以保留无限量的WAL文件。否则,如果复制槽的restart_lsn落后于当前LSN超过给定大小, - 使用该槽的备机可能由于所需的WAL文件被删除而无法继续复制。您可以在pg_replication_slots中查看复制槽的WAL可用性。 - 如果未指定单位,则此值将被视为兆字节。此参数只能在postgresql.conf文件或服务器命令行中设置。 - - - + + 指定检查点时复制槽允许在 + pg_wal 目录中保留的 WAL 文件最大总量。 + 如果 max_slot_wal_keep_size 为 -1(默认值),复制槽可以保留无限量的 WAL 文件。 + 否则,如果复制槽的 restart_lsn 落后当前 LSN 超过给定大小,使用该槽的备库可能会 + 因为所需 WAL 文件被移除而无法继续复制。可以在 + pg_replication_slots 中查看复制槽的 WAL 可用情况。 + 如果指定值时没有单位,则按兆字节计算。此参数只能在 + postgresql.conf 文件中或服务器命令行上设置。 + + + @@ -2986,14 +2894,14 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows - 中断那些停止活动超过这个时间量的复制连接。这对发送服务器检测一个费用服务器崩溃或网络中断有用。 - 如果指定值时没有单位,则以毫秒为单位。默认值是 60 秒。值0将禁用超时机制。 + 终止非活动时间超过此值的复制连接。这有助于发送服务器检测备库崩溃或网络中断。 + 如果指定值时没有单位,则按毫秒计算。默认值为 60 秒。值零禁用超时机制。 - 对于跨越多个地理位置分布的集簇,每个位置使用不同的值可以为集簇管理带来更大的灵活性。 - 对于具有低延迟网络连接的备库,较小的值有助于更快的故障检测; - 对于位于远端位置的具有高延迟网络连接的备库,较大的值有助于更好地判断备库的健康状况。 + 对于跨多个地理位置分布的集簇,在各位置使用不同的值可以提高集簇管理的灵活性。 + 对于网络延迟较低的备库,较小的值有助于更快地检测故障; + 对于地处远端、网络延迟较高的备库,较大的值有助于更准确地判断其健康状况。 @@ -3020,7 +2928,10 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows 主库 - 这些参数可以在发送复制数据给一个或多个备库的主库上设置。注意除了这些参数之外,在主库上必须设置合适的,并且也启用可选的 WAL 归档(见)。这些参数值与备库无关,尽管你可能希望为了准备好一个备库转变成主库来设置这些参数。 + 这些参数可以在向一个或多个备库发送复制数据的主库上设置。 + 除这些参数外,还必须在主库上适当设置 , + 也可以选择启用 WAL 归档(见 )。 + 这些参数在备库上的取值不影响备库运行,不过也可以预先设置,以备将来提升为主库。 @@ -3036,15 +2947,17 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows 所述,这个参数指定一个支持同步复制的备库的列表。 - 可能会有一个或者多个活动的同步备库,在这些备库确认收到它们的数据之后,等待提交的事务将被允许继续下去。 - 同步备库是那些名字出现在这个列表前面,并且当前已连接并且正在实时流式传输数据(如pg_stat_replication视图中streaming的状态所示)的服务器。 + 将有一个或多个活动的同步备库,在这些备库确认收到它们的数据之后,等待提交的事务将被允许继续下去。 + 同步备库是那些名字出现在这个列表中,并且当前已连接并且正在实时流式传输数据(如pg_stat_replication视图中streaming的状态所示)的服务器。 指定多于一台同步备库可以得到非常高的可用性并且能防止数据丢失。 用于这一目的的备库的名称是其application_name设置,它在备库的连接信息中设置。 - 在物理复制备库的情况下,这应该被设置在primary_conninfo设置中,如果设置了,默认是的设置,否则为 walreceiver。 - 对于逻辑复制,可以在订阅的连接信息中设置。对于其他复制流消费者,请参考其文档。 + 对于物理复制备库,应在 primary_conninfo 设置中指定。 + 若已设置 ,则默认使用其值;否则默认值为 walreceiver。 + 对于逻辑复制,可以在订阅的连接信息中设置,默认值为订阅名称。 + 对于其他复制流消费者,请参考其文档。 @@ -3058,11 +2971,11 @@ ANY num_sync ( num_sync指定一种基于优先的同步复制,并且会让事务提交等待,直到它们的WAL记录被复制到基于优先级选择的num_sync台同步备库上为止。例如,设置FIRST 3 (s1, s2, s3, s4)将导致每次提交都等待来自三台较高优先级的备库的答复,这三台备库将从备库s1s2s3以及s4中选出。在该列表中出现较早的备库将被给予较高的优先级,并且将被考虑为同步备库。列表中出现的其他备库表示潜在的同步备库。如果当前的任何同步备库因为某种原因断开连接,它将立刻被下一个最高优先级的备库替代。关键词FIRST是可选的。 + 关键词FIRST加上num_sync指定一种基于优先级的同步复制,并且会让事务提交等待,直到它们的WAL记录被复制到基于优先级选择的num_sync台同步备库上为止。例如,设置FIRST 3 (s1, s2, s3, s4)将导致每次提交都等待来自三台较高优先级的备库的答复,这三台备库将从备库s1s2s3以及s4中选出。在该列表中出现较早的备库将被给予较高的优先级,并且将被考虑为同步备库。列表中出现的其他备库表示潜在的同步备库。如果当前的任何同步备库因为某种原因断开连接,它将立刻被下一个最高优先级的备库替代。关键词FIRST是可选的。 - 关键词ANY加上num_sync指定一种基于规定数量的同步复制,并且会让事务提交等待,直到它们的WAL记录被复制到所列出备库中的至少num_sync台上为止。例如,设置ANY 3 (s1, s2, s3, s4)将导致每次提交会在收到s1s2s3以及s4中任意三台备库的回答后立刻继续下去。 + 关键词ANY加上num_sync指定一种基于法定人数的同步复制,并且会让事务提交等待,直到它们的WAL记录被复制到所列出备库中的至少num_sync台上为止。例如,设置ANY 3 (s1, s2, s3, s4)将导致每次提交会在收到s1s2s3以及s4中任意三台备库的回答后立刻继续下去。 @@ -3088,7 +3001,7 @@ ANY num_sync ( 参数设置为localoff。 + 如果这里没有指定同步备库名称,那么不启用同步复制并且事务提交将不会等待复制。这是默认的配置。即便当同步复制被启用时,个体事务也可以被配置为不等待复制,做法是将参数设置为localoff @@ -3097,6 +3010,8 @@ ANY num_sync ( vacuum_defer_cleanup_age (integer) @@ -3120,8 +3035,7 @@ ANY num_sync ( @@ -3171,13 +3085,15 @@ ANY num_sync ( )。 这个参数只能在 postgresql.conf文件或服务器命令行上设置。 - 如果在 WAL 接收进程运行时更改此参数,则会向该进程发送关闭信号,并期望它使用新设置重新启动。 + 如果在 WAL 接收进程运行时更改此参数,则会向该进程发送关闭信号,并预期它使用新设置重新启动。 如果没有设置primary_conninfo或服务器没有处于备库模式,则此设置无效。 - + + + promote_trigger_file (string) promote_trigger_file 配置参数 @@ -3226,9 +3142,7 @@ ANY num_sync ( num_sync ( num_sync ( )。 - 默认为"关闭"。 此参数只能在postgresql.conf文件或服务器命令行中设置。 - 如果在 WAL 接收进程运行时更改此参数,则该进程将发出关机的信号,并预期使用新设置重新启动。 - + 指定在未使用配置要使用的永久复制槽时,WAL 接收进程是否应在远程实例上创建临时复制槽。默认值为 off。此参数只能在postgresql.conf文件中或服务器命令行上设置。如果在 WAL 接收进程运行时更改此参数,则会向该进程发送信号使其关闭,并预期它使用新设置重新启动。 @@ -3282,9 +3190,9 @@ ANY num_sync ( pg_stat_replication视图看到。 - 备库将报告它已经写入的上一个预写式日志位置、它已经刷到磁盘的上一个位置以及它已经应用的最后一个位置。 + 备库将报告最后写入的预写日志位置、最后刷盘的位置以及最后应用的位置。 这个参数的值是报告之间的最大时间量。 - 每次写入或刷出位置改变时会发送状态更新,或者按这个参数的指定的频度发送。 + 每次写入或刷盘位置改变时会发送状态更新,或者至少按这个参数指定的频度发送。 因此,应用位置可能比真实位置略微滞后。 如果指定值时没有单位,则以秒为单位。 默认值是 10 秒。 @@ -3302,7 +3210,7 @@ ANY num_sync ( num_sync ( num_sync ( recovery_min_apply_delay (integer) @@ -3360,39 +3270,32 @@ ANY num_sync ( @@ -3403,7 +3306,7 @@ ANY num_sync ( num_sync ( num_sync ( num_sync ( + + enable_bitmapscan (boolean) - 位图扫描 + 位图扫描 - enable_bitmapscan配置参数 + enable_bitmapscan 配置参数 - - 允许或禁止查询规划器使用位图扫描计划类型。默认值是on。 + 启用或禁用查询规划器对位图扫描计划类型的使用。默认值为 on - - + + + - + enable_gathermerge (boolean) - enable_gathermerge配置参数 + enable_gathermerge 配置参数 - - 启用或者禁用查询规划器对收集归并计划类型的使用。默认值是on。 + 启用或禁用查询规划器对收集归并计划类型的使用。默认值为 on - - + + - + + enable_hashagg (boolean) - enable_hashagg配置参数 + enable_hashagg 配置参数 - - 允许或禁用查询规划器使用哈希聚合计划类型。默认值是on。 + 启用或禁用查询规划器对哈希聚合计划类型的使用。默认值为 on - + + enable_hashjoin (boolean) - enable_hashjoin配置参数 + enable_hashjoin 配置参数 - - 允许或禁止查询规划器使用哈希连接计划类型。默认值是on。 + 启用或禁用查询规划器对哈希连接计划类型的使用。默认值为 on - + + enable_incremental_sort (boolean) enable_incremental_sort 配置参数 - - 启用或禁用查询规划器对增量排序步骤的使用。默认为on。 + 启用或禁用查询规划器对增量排序步骤的使用。默认值为 on + + + + enable_indexscan (boolean) - 索引扫描 + 索引扫描 - enable_indexscan配置参数 + enable_indexscan 配置参数 - 允许或禁止查询规划器使用索引扫描和只用索引扫描计划类型。默认值是on。另见 + + 启用或禁用查询规划器对索引扫描和仅索引扫描计划类型的使用。默认值为 on。另请参见 。 + enable_indexonlyscan (boolean) - enable_indexonlyscan配置参数 + enable_indexonlyscan 配置参数 - 允许或禁止查询规划器使用只用索引扫描计划类型(见)。默认值是on。还必须启用设置,查询规划器才会考虑只用索引扫描。 + + 启用或禁用查询规划器对仅索引扫描计划类型的使用(参见 )。默认值为 on。还必须启用 ,查询规划器才会考虑仅索引扫描。 + - + + enable_material (boolean) - enable_material配置参数 + enable_material 配置参数 @@ -3600,26 +3510,27 @@ ANY num_sync ( + + enable_mergejoin (boolean) - enable_mergejoin配置参数 + enable_mergejoin 配置参数 - - 允许或禁止查询规划器使用归并连接计划类型。默认值是on。 + 启用或禁用查询规划器对归并连接计划类型的使用。默认值为 on - + + enable_nestloop (boolean) - enable_nestloop配置参数 + enable_nestloop 配置参数 @@ -3645,17 +3556,17 @@ ANY num_sync ( + + enable_parallel_hash (boolean) - enable_parallel_hash配置参数 + enable_parallel_hash 配置参数 - - 允许或禁止查询规划器对并行哈希使用哈希连接计划类型。如果哈希连接计划也没有启用,这个参数没有效果。默认值是on。 + 启用或禁用查询规划器对使用并行哈希的哈希连接计划类型的使用。如果没有同时启用哈希连接计划,此参数不起作用。默认值为 on @@ -3675,19 +3586,19 @@ ANY num_sync ( enable_partitionwise_join (boolean) - enable_partitionwise_join配置参数 + enable_partitionwise_join 配置参数 - 允许或者禁止查询规划器使用面向分区的连接,这使得分区表之间的连接以连接匹配的分区的方式来执行。 - 面向分区的连接当前只适用于连接条件包括所有分区键的情况,分区键必须具有相同的数据类型,并且子分区集合必须一一匹配。 - 启用此设置后,最终计划中内存使用量受work_mem限制的节点数可能会随所扫描分区的数量线性增加, - 从而使查询执行时的总内存消耗大幅增加。查询规划在内存和 CPU 方面的代价也会显著增加。 - 默认值为off。 + 启用或禁用查询规划器对分区连接的使用,使分区表之间的连接可以通过连接相匹配的分区来完成。分区连接目前仅适用于连接条件包含所有分区键的情况;这些分区键必须具有相同的数据类型,并且子分区集合必须一一匹配。启用此设置后,最终计划中内存用量受 work_mem 限制的节点数量可能随所扫描分区的数量线性增加。这可能大幅增加查询执行期间的总内存消耗。查询规划在内存和 CPU 方面的开销也会显著增加。默认值为 off @@ -3695,16 +3606,12 @@ ANY num_sync ( enable_partitionwise_aggregate (boolean) - enable_partitionwise_aggregate配置参数 + enable_partitionwise_aggregate 配置参数 - 启用或禁用查询规划器使用分区分组或聚合的功能,该功能允许在分区表上分别对每个分区执行分组或聚合操作。 - 如果GROUP BY子句不包括分区键,那么只能在每个分区的基础上执行部分聚合,并且必须在稍后进行最终化处理。 - 启用此设置后,最终计划中内存使用量受work_mem限制的节点数可能会随所扫描分区的数量线性增加, - 从而使查询执行时的总内存消耗大幅增加。查询规划在内存和 CPU 方面的代价也会显著增加。 - 默认值为off。 + 启用或禁用查询规划器对分区分组或聚合的使用,使分区表上的分组或聚合可以在各个分区上分别执行。如果 GROUP BY 子句不包含分区键,则只能在各分区上执行部分聚合,随后还必须进行最终处理。启用此设置后,最终计划中内存用量受 work_mem 限制的节点数量可能随所扫描分区的数量线性增加。这可能大幅增加查询执行期间的总内存消耗。查询规划在内存和 CPU 方面的开销也会显著增加。默认值为 off @@ -4162,7 +4069,7 @@ ANY num_sync ( parallel_leader_participation (boolean) - parallel_leader_participation 配置参数 + + parallel_leader_participation configuration + parameter + - + - 允许领导者进程执行GatherGather Merge节点之下的查询计划,而不是等待工作者进程。 - 默认值为on。将此值设置为off可以降低工作者因领导者读取元组不够快而阻塞的可能性, - 但也要求领导者进程等待工作者进程启动之后才能产生第一批元组。 - 领导者对性能的帮助或妨碍程度取决于计划类型、工作者数量和查询持续时间。 + 允许领导者进程执行 GatherGather Merge 节点下的查询计划,而不是等待工作进程。默认值为 on。将此值设置为 off,可以降低工作进程因领导者读取元组不够快而被阻塞的可能性,但在产生第一批元组之前,领导者进程必须等待工作进程启动。领导者对性能的帮助或妨碍程度取决于计划类型、工作进程数量和查询持续时间。 @@ -4307,7 +4218,7 @@ SELECT * FROM parent WHERE key = 2400; 更具体地说,将此值设置为on会在任何看起来可以安全并行的查询计划顶部添加一个Gather节点, - 让查询在并行工作者中运行。即使没有可用的并行工作者或无法使用并行工作者, + 让查询在并行工作进程中运行。即使没有可用的并行工作进程或无法使用并行工作进程, 在并行查询上下文中不允许的操作(例如启动子事务)也会被禁止,除非规划器认为这会使查询失败。 如果设置此选项后出现失败或意外结果,查询使用的某些函数可能需要被标记为PARALLEL UNSAFE (也可能是PARALLEL RESTRICTED)。 @@ -4315,7 +4226,7 @@ SELECT * FROM parent WHERE key = 2400; 将此值设置为regress具有设置为on的所有效果,另外还有一些旨在方便自动回归测试的效果。 - 通常,来自并行工作者的消息会包含一行说明这一点的上下文信息,但regress设置会抑制此行,使输出与非并行执行时相同。 + 通常,来自并行工作进程的消息会包含一行说明这一点的上下文信息,但regress设置会抑制此行,使输出与非并行执行时相同。 此外,此设置添加到计划中的Gather节点会在EXPLAIN输出中隐藏, 使输出与此设置为off时的输出一致。 @@ -4924,7 +4835,7 @@ local0.* /var/log/postgresql - application_name可以是任意小于NAMEDATALEN个字符(标准编译中是 64 个字符)的字符串。这通常由一个应用通过到服务器的连接设置。该名称将被显示在pg_stat_activity视图中并被包括在 CSV 日志项中。它也会被通过包括在普通日志项中。只有可打印 ASCII 字符能被使用在application_name之中。其他字符将被替换为问号(?)。 + application_name可以是任意小于NAMEDATALEN个字符(标准编译中是 64 个字符)的字符串。应用通常在连接服务器时设置此值。该名称将被显示在pg_stat_activity视图中并被包括在 CSV 日志项中。它也会被通过包括在普通日志项中。只有可打印 ASCII 字符能被使用在application_name之中。其他字符将被替换为问号(?)。 @@ -5003,7 +4914,7 @@ local0.* /var/log/postgresql - 某些客户端程序(例如psql)在要求密码时会尝试连接两次,因此重复的收到连接消息并不一定表示一个错误。 + 某些客户端程序(例如psql)在判断是否需要密码时会尝试连接两次,因此重复的收到连接消息并不一定表示一个错误。 @@ -5211,7 +5122,7 @@ local0.* /var/log/postgresql %% - 纯文字 % + 字面字符 % @@ -5242,7 +5153,7 @@ FROM pg_stat_activity; - Syslog产生自己的时间戳和进程 ID 信息,因此如果你记录到syslog你可能不希望包括哪些转义。 + Syslog产生自己的时间戳和进程 ID 信息,因此如果你记录到syslog你可能不希望包括那些转义。 @@ -5509,12 +5420,12 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 为不同目的设置标识这个数据库集簇(实例)的名称。此集簇名称出现在该集簇中所有服务器进程的进程标题中。 - 此外,它还是备库连接的默认应用名称。(参见 .) + 设置一个用于各种目的、标识此数据库集簇(实例)的名称。集簇名称会出现在此集簇所有服务器进程的进程标题中。 + 此外,它还是备库连接的默认应用名称(参见)。 - 这个名称可以是任何长度不超过NAMEDATALEN个字符(在标准编译中是 64字符)的任何字符串。只有可打印的 ASCII 字符能被用在cluster_name值中。其他字符将被替换为问号(?)。如果这个参数被设置为空字符串''(也是默认值),将不会显示名称。这个参数只能在服务器启动时设置。 + 这个名称可以是任何长度少于NAMEDATALEN个字符(在标准编译中是 64字符)的任何字符串。只有可打印的 ASCII 字符能被用在cluster_name值中。其他字符将被替换为问号(?)。如果这个参数被设置为空字符串''(也是默认值),将不会显示名称。这个参数只能在服务器启动时设置。 @@ -5544,13 +5455,14 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; 运行时统计数据 - 累积查询和索引统计 + 查询和索引统计信息收集器 - 这些参数控制服务器范围内的累积统计系统。 - 启用后,收集的数据可以通过pg_statpg_statio - 系列系统视图进行访问。有关更多信息,请参阅。 - + 这些参数控制服务器范围内的统计信息收集功能。 + 启用统计信息收集后,产生的数据可以通过pg_stat和 + pg_statio系列系统视图进行访问。 + 更多信息请参阅。 + @@ -5732,7 +5644,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 注意即使该参数被禁用,系统也会在需要防止事务ID回卷时发起清理进程。详情请见。 + 注意即使该参数被禁用,系统也会在需要防止事务ID回卷时发起自动清理进程。详情请见 @@ -5780,7 +5692,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 指定自动清理在任意给定数据库上运行的最小延迟。在每一轮中后台进程检查数据库并根据需要为数据库中的表发出VACUUMANALYZE命令。 + 指定自动清理在任意给定数据库上各次运行之间的最小间隔。在每一轮中后台进程检查数据库并根据需要为数据库中的表发出VACUUMANALYZE命令。 如果指定值时没有单位,则以秒为单位。默认值为1分钟(1min)。该参数只能在postgresql.conf文件或在服务器命令行上设置。 @@ -5953,7 +5865,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 指定用于自动VACUUM操作中的代价限制值。如果指定-1(默认值),则使用值。注意该值被按比例地分配到运行中的自动清理工作者上(如果有多个),因此每一个工作者的限制值之和不会超过这个变量中的值。该参数只能在postgresql.conf文件或在服务器命令中设置。但是对个别表可以通过修改表存储参数来覆盖该设置。 + 指定用于自动VACUUM操作中的代价限制值。如果指定-1(默认值),则使用值。注意该值被按比例地分配到运行中的自动清理工作进程上(如果有多个),因此每一个工作进程的限制值之和不会超过这个变量中的值。该参数只能在postgresql.conf文件或在服务器命令中设置。但是对个别表可以通过修改表存储参数来覆盖该设置。 @@ -5997,7 +5909,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; search_path配置参数 - pathfor schemas + 路径用于模式 @@ -6088,7 +6000,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; default_tablespace配置参数 - tablespacedefault + 表空间默认 @@ -6171,7 +6083,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; default_transaction_isolation (enum) - transaction isolation level + 事务隔离级别 设置默认值 @@ -6194,7 +6106,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; default_transaction_read_only (boolean) - read-only transaction + 只读事务 设置默认值 @@ -6216,7 +6128,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; default_transaction_deferrable (boolean) - deferrable transaction + 可延迟事务 设置默认值 @@ -6242,7 +6154,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; transaction_isolation (enum) - transaction isolation level + 事务隔离级别 transaction_isolation配置参数 @@ -6262,7 +6174,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; transaction_read_only (boolean) - read-only transaction + 只读事务 transaction_read_only 配置参数 @@ -6282,7 +6194,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; transaction_deferrable (boolean) - deferrable transaction + 可延迟事务 transaction_deferrable 配置参数 @@ -6408,7 +6320,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 当表的pg_class.relfrozenxid字段达到该设置指定的年龄时,VACUUM会执行激进扫描。激进扫描与常规VACUUM不同,它会访问每一个可能包含未冻结 XID 或 MXID 的页面,而不仅仅是那些可能包含死元组的页面。默认值是 1.5 亿个事务。尽管用户可以将该值设置为 0 到 20 亿之间的任意值,VACUUM会悄悄将有效值调整为的 95%,从而在触发防回卷 autovacuum 之前仍有机会执行一次常规手工VACUUM。更多信息请参见。 + 当表的pg_class.relfrozenxid字段达到该设置指定的年龄时,VACUUM会执行激进扫描。激进扫描与常规VACUUM不同,它会访问每一个可能包含未冻结 XID 或 MXID 的页面,而不仅仅是那些可能包含死元组的页面。默认值是 1.5 亿个事务。尽管用户可以将该值设置为 0 到 20 亿之间的任意值,VACUUM会悄悄将有效值限制为不超过的 95%,从而在触发防回卷 autovacuum 之前仍有机会执行一次常规手工VACUUM。更多信息请参见 @@ -6421,7 +6333,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 指定VACUUM在扫描表时用来决定是否冻结行版本的切断年龄(以事务计)。默认值是 5000 万个事务。尽管用户可以将该值设置为 0 到 10 亿之间的任意值,VACUUM会悄悄将有效值调整为的一半,这样强制 autovacuum 之间就不会间隔过短。更多信息请参见。 + 指定VACUUM在扫描表时用来决定是否冻结行版本的切断年龄(以事务计)。默认值是 5000 万个事务。尽管用户可以将该值设置为 0 到 10 亿之间的任意值,VACUUM会悄悄将有效值限制为不超过的一半,这样强制 autovacuum 之间就不会间隔过短。更多信息请参见 @@ -6434,7 +6346,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 当表的pg_class.relminmxid字段达到该设置指定的年龄时,VACUUM会执行激进扫描。激进扫描与常规VACUUM不同,它会访问每一个可能包含未冻结 XID 或 MXID 的页面,而不是只扫描那些可能包含死元组的页面。默认值是 1.5 亿个 multixact。尽管用户可以将该值设置为 0 到 20 亿之间的任意值,VACUUM会悄悄将有效值调整为的 95%,从而在触发防回卷 autovacuum 之前仍有机会执行一次常规手工VACUUM。更多信息请参见。 + 当表的pg_class.relminmxid字段达到该设置指定的年龄时,VACUUM会执行激进扫描。激进扫描与常规VACUUM不同,它会访问每一个可能包含未冻结 XID 或 MXID 的页面,而不是只扫描那些可能包含死元组的页面。默认值是 1.5 亿个多事务。尽管用户可以将该值设置为 0 到 20 亿之间的任意值,VACUUM会悄悄将有效值限制为不超过的 95%,从而在触发防回卷 autovacuum 之前仍有机会执行一次常规手工VACUUM。更多信息请参见 @@ -6447,7 +6359,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 指定VACUUM在扫描表时用来决定是否将 multixact ID 替换为较新的事务 ID 或 multixact ID 的切断年龄(以 multixact 计)。默认值是 5000 万个 multixact。尽管用户可以将该值设置为 0 到 10 亿之间的任意值,VACUUM会悄悄将有效值调整为的一半,这样强制 autovacuum 之间就不会间隔过短。更多信息请参见。 + 指定VACUUM在扫描表时用来决定是否将多事务 ID 替换为较新的事务 ID 或多事务 ID 的切断年龄(以多事务计)。默认值是 500 万个多事务。尽管用户可以将该值设置为 0 到 10 亿之间的任意值,VACUUM会悄悄将有效值限制为不超过的一半,这样强制 autovacuum 之间就不会间隔过短。更多信息请参见 @@ -6496,7 +6408,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; SET XML OPTION - XML option + XML 选项 @@ -6534,20 +6446,21 @@ SET XML OPTION { DOCUMENT | CONTENT }; + - restrict_nonsystem_relation_kind (string) - + restrict_nonsystem_relation_kind (string) + restrict_nonsystem_relation_kind 配置参数 - - + + 设置禁止访问非系统关系的关系类型。该值采用关系类型的逗号分隔列表形式。 目前支持的关系类型是viewforeign-table - + @@ -6593,7 +6506,7 @@ SET XML OPTION { DOCUMENT | CONTENT }; TimeZone配置参数 - time zone + 时区 @@ -6609,7 +6522,7 @@ SET XML OPTION { DOCUMENT | CONTENT }; timezone_abbreviations配置参数 - time zone names + 时区名称 @@ -6623,11 +6536,11 @@ SET XML OPTION { DOCUMENT | CONTENT }; extra_float_digits (integer) - significant digits + 有效数字 - floating-point - display + 浮点数 + 显示 extra_float_digits配置参数 @@ -6655,7 +6568,7 @@ SET XML OPTION { DOCUMENT | CONTENT }; - 此参数的含义,以及其默认值,在 PostgreSQL 12 中发生了变化; + 此参数的含义,以及其默认值,在 PostgreSQL 12 中发生了变化; 参见 以便进一步讨论。 @@ -6668,7 +6581,7 @@ SET XML OPTION { DOCUMENT | CONTENT }; client_encoding配置参数 - character set + 字符集 @@ -6987,12 +6900,12 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' deadlock_timeout (integer) - deadlock + 死锁 期间超时 - timeout - deadlock + 超时 + 死锁 deadlock_timeout配置参数 @@ -7027,12 +6940,11 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' 共享锁表跟踪在max_locks_per_transaction * ( + ) 个对象(如表)上的锁。因此,在任何一个时刻,只有不超过这么多个可区分对象能够被锁住。这个参数控制为每个事务分配的对象锁的平均数量。个体事务可以锁住更多对象,数量可以和锁表中能容纳的所有事务的锁一样多。这是能被锁住的行数,那个值是没有限制的。默认值 64 已经被历史证明是足够的,但是如果你有需要在一个事务中使用很多不同表的查询(例如查询一个有很多子表的父表),你可能需要提高这个值。这个参数只能在服务器启动时设置。 + linkend="guc-max-prepared-transactions"/>) 个对象(如表)上的锁。因此,在任何一个时刻,只有不超过这么多个可区分对象能够被锁住。这个参数控制为每个事务分配的对象锁的平均数量。只要所有事务的锁都能放入锁表中,单个事务就可以锁住更多对象。这是能被锁住的行数,那个值是没有限制的。默认值 64 已经被历史证明是足够的,但是如果你有需要在一个事务中使用很多不同表的查询(例如查询一个有很多子表的父表),你可能需要提高这个值。这个参数只能在服务器启动时设置。 - 当运行一个备库时,你必须设置这个参数等于或大于主库上的参数。 - 否则,备库上将不允许查询。 + 运行备库时,必须将此参数设置为大于或等于主库上的值。否则,备库上将不允许查询。 @@ -7049,7 +6961,7 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' 共享谓词锁表跟踪在max_pred_locks_per_transaction * ( + ) 个对象(如表)上的锁。因此,在任何一个时刻,只有不超过这么多个可区分对象能够被锁住。这个参数控制为每个事务分配的对象锁的平均数量。个体事务可以锁住更多对象,数量可以和锁表中能容纳的所有事务的锁一样多。这是能被锁住的行数,那个值是没有限制的。默认值 64 已经在测试中被证明通常是足够的,但是如果你有需要在一个可串行化事务中使用很多不同表的查询(例如查询一个有很多子表的父表),你可能需要提高这个值。这个参数只能在服务器启动时设置。 + linkend="guc-max-prepared-transactions"/>) 个对象(如表)上的锁。因此,在任何一个时刻,只有不超过这么多个可区分对象能够被锁住。这个参数控制为每个事务分配的对象锁的平均数量。只要所有事务的锁都能放入锁表中,单个事务就可以锁住更多对象。这是能被锁住的行数,那个值是没有限制的。默认值 64 已经在测试中被证明通常是足够的,但是如果你有会在单个可串行化事务中访问许多不同表的客户端,则可能需要提高这个值。这个参数只能在服务器启动时设置。 @@ -7116,7 +7028,7 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' backslash_quote (enum) - stringsbackslash quotes + 字符串反斜线引号 backslash_quote配置参数 @@ -7135,7 +7047,7 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' escape_string_warning (boolean) - strings转义警告 + 字符串转义警告 escape_string_warning配置参数 @@ -7210,7 +7122,7 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' standard_conforming_strings (boolean) - stringsstandard conforming + 字符串标准符合 standard_conforming_strings配置参数 @@ -7437,6 +7349,8 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' + + lc_collate (string) @@ -7451,6 +7365,8 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' + + lc_ctype (string) @@ -7531,7 +7447,7 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' server_encoding配置参数 - character set + 字符集 @@ -7772,6 +7688,8 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' + + trace_recovery_messages (enum) diff --git a/zh/13/datatype.sgml b/zh/13/datatype.sgml index 4c8d4b57..8a6f3f7f 100644 --- a/zh/13/datatype.sgml +++ b/zh/13/datatype.sgml @@ -354,19 +354,19 @@ smallint 2字节 小范围整数 - -32768 to +32767 + -32768 到 +32767 integer 4字节 整数的典型选择 - -2147483648 to +2147483647 + -2147483648 到 +2147483647 bigint 8字节 大范围整数 - -9223372036854775808 to +9223372036854775807 + -9223372036854775808 到 +9223372036854775807 @@ -753,7 +753,10 @@ FROM generate_series(-3.5, 3.5, 1) as x; - 本节描述的是 PostgreSQL 特有的创建自动递增列的方法。另一种方法是使用 SQL 标准的标识列特性,参见 + + 本节介绍 PostgreSQL 特有的自动递增列创建方法。 + 另一种方法是使用 SQL 标准的标识列特性,参见。 + @@ -831,7 +834,7 @@ ALTER SEQUENCE tablename_money 类型以固定的小数精度存储货币金额; 参见 。小数精度由数据库的 设置决定。表中显示的范围假定 - 有两位小数。输入支持多种格式,包括整数和浮点文字,以及典型的 + 有两位小数。输入支持多种格式,包括整数字面量和浮点数字面量,以及典型的 货币格式,例如 '$1,000.00'。输出通常也采用 后一种形式,但会受到区域设置影响。 @@ -1236,7 +1239,7 @@ SELECT '\xDEADBEEF'::bytea;
- <type>bytea</type>文字转义字节 + <type>bytea</type>字面量中需要转义的字节 @@ -2432,7 +2435,7 @@ SELECT '2 years 15 months 100 weeks 99 hours 123456789 milliseconds'::interval; 3 years 3 mons 700 days 133:17:36.789 - 这里,周被理解为 7 days,而较小和较大的时间单位 + 这里,周按7 天计算并单独保留,而较小和较大的时间单位 则被合并并规范化了。 @@ -3806,17 +3809,16 @@ a0ee-bc99-9c0b-4ef8-bb6d-6bb9-bd38-0a11 xml 数据类型可用于存储 XML 数据。与把 XML 数据存储在 - text 字段中相比,它的优势在于会检查输入值是否格式 - 良好,并且提供了可执行类型安全操作的支持函数;见 - 。使用该数据类型要求安装时启用 + text 字段中相比,它的优势在于会检查输入值的良构性,并且提供了可执行类型安全操作的支持函数;见 + 。使用该数据类型要求构建时使用 configure --with-libxml - xml 类型既可以存储符合 XML 标准定义的格式良好的 + xml 类型既可以存储 XML 标准所定义的良构 文档,也可以存储 内容 片段;后者是参照 XQuery 和 XPath 数据模型中更宽松的 - document node + 文档节点 概念来定义的。粗略地说,这意味着内容片段可以拥有多个顶层元素或字符 节点。表达式 xmlvalue IS DOCUMENT @@ -3966,7 +3968,7 @@ SET xmloption TO { DOCUMENT | CONTENT }; - 是一种用户定义的数据类型,它基于另一种底层类型。根据需要,它可以有约束来限制其有效值为底层类型所允许值的一个子集。如果没有约束,它的行为就和底层类型一样 — 例如,任何适用于底层类型的操作符或函数都对该域类型有效。底层类型可以是任何内置或者用户定义的基础类型、枚举类型、数组类型、复合类型、范围类型或者另一个域。 + 是一种用户定义的数据类型,它基于另一种底层类型。根据需要,它可以有约束来限制其有效值为底层类型所允许值的一个子集。除此之外,它的行为与底层类型相同 — 例如,任何适用于底层类型的操作符或函数都对该域类型有效。底层类型可以是任何内置或者用户定义的基础类型、枚举类型、数组类型、复合类型、范围类型或者另一个域。 diff --git a/zh/13/dblink.sgml b/zh/13/dblink.sgml index 1d210a1d..8df206fd 100644 --- a/zh/13/dblink.sgml +++ b/zh/13/dblink.sgml @@ -7,9 +7,13 @@ dblink - dblink模块支持在一个数据库会话中连接到其他PostgreSQL数据库。 + + dblink 是一个支持在数据库会话内连接到其他 PostgreSQL 数据库的模块。 + - 另请参阅,它使用更现代、符合标准的基础设施提供了大致相同的功能。 + + 另请参见 ,它使用更现代且更符合标准的基础设施提供了基本相同的功能。 + @@ -91,7 +95,7 @@ dblink_connect(text connname, text connstr) returns text 注解 - 如果不可信用户能够访问一个尚未采用模式的安全使用方式的数据库,则应在每个会话开始时从 + 如果不受信任的用户能够访问一个尚未采用模式的安全使用方式的数据库,则应在每个会话开始时从 search_path 中移除公共可写模式。例如,可以把 options=-csearch_path= 加到 connstr 中。这个注意事项并非 dblink 所特有;它适用于每一种执行任意 SQL 命令的接口。 @@ -125,9 +129,9 @@ SELECT dblink_connect('myconn', 'dbname=postgres options=-csearch_path='); OK (1 row) --- FOREIGN DATA WRAPPER functionality --- Note: local connection must require password authentication for this to work properly --- Otherwise, you will receive the following error from dblink_connect(): +-- FOREIGN DATA WRAPPER 功能 +-- 注意:要使本例正常工作,本地连接必须要求密码认证。 +-- 否则,dblink_connect() 将报告以下错误: -- ERROR: password is required -- DETAIL: Non-superuser cannot connect if the server does not request a password. -- HINT: Target server's authentication method must be changed. @@ -142,13 +146,13 @@ GRANT SELECT ON TABLE foo TO regress_dblink_user; \set ORIGINAL_USER :USER \c - regress_dblink_user SELECT dblink_connect('myconn', 'fdtest'); - dblink_connect + dblink_connect ---------------- OK (1 row) SELECT * FROM dblink('myconn', 'SELECT * FROM foo') AS t(a int, b text, c text[]); - a | b | c + a | b | c ----+---+--------------- 0 | a | {a0,b0,c0} 1 | b | {a1,b1,c1} @@ -390,7 +394,7 @@ SELECT * WHERE proname LIKE 'bytea%'; - FROM 子句中的 alias 部分必须指定该函数将返回的列名和类型。(在别名中指定列名实际上是标准 SQL 语法,但指定列类型则是 + FROM 子句中的 别名 部分必须指定该函数将返回的列名和类型。(在别名中指定列名实际上是标准 SQL 语法,但指定列类型则是 PostgreSQL 的扩展。)这样系统才能在尝试执行该函数之前,就知道 * 应展开成什么,以及 WHERE 子句中的 proname 指的是什么。运行时,如果远程数据库返回的实际查询结果与 diff --git a/zh/13/ddl.sgml b/zh/13/ddl.sgml index 817f6d70..c334d4b9 100644 --- a/zh/13/ddl.sgml +++ b/zh/13/ddl.sgml @@ -1325,7 +1325,7 @@ REVOKE ALL ON accounts FROM PUBLIC;
- 访问控制列表权限缩写 + ACL 权限缩写 diff --git a/zh/13/dfunc.sgml b/zh/13/dfunc.sgml index 784bf1be..d0a7fa1f 100644 --- a/zh/13/dfunc.sgml +++ b/zh/13/dfunc.sgml @@ -46,7 +46,7 @@ FreeBSD - FreeBSDshared library + FreeBSD共享库 @@ -64,7 +64,7 @@ gcc -shared -o foo.so foo.o HP-UX - HP-UXshared library + HP-UX共享库 @@ -91,7 +91,7 @@ ld -b -o foo.sl foo.o Linux - Linuxshared library + Linux共享库 @@ -108,7 +108,7 @@ cc -shared -o foo.so foo.o macOS - macOSshared library + macOS共享库 @@ -124,7 +124,7 @@ cc -bundle -flat_namespace -undefined suppress -o foo.so foo.o NetBSD - NetBSDshared library + NetBSD共享库 @@ -142,7 +142,7 @@ gcc -shared -o foo.so foo.o OpenBSD - OpenBSDshared library + OpenBSD共享库 @@ -159,7 +159,7 @@ ld -Bshareable -o foo.so foo.o Solaris - Solarisshared library + Solaris共享库 diff --git a/zh/13/diskusage.sgml b/zh/13/diskusage.sgml index 69058394..be6f91e6 100644 --- a/zh/13/diskusage.sgml +++ b/zh/13/diskusage.sgml @@ -15,15 +15,15 @@ - 每个表都有一个主堆磁盘文件,其中存储了大部分数据。如果该表有任何值可能较宽的列,还可能会有一个与该表关联的TOAST文件,用于存储宽到无法方便地放入主表中的值(见)。如果存在,还会在TOAST表上有一个有效索引。也可能会有与基表关联的索引。每个表和索引都存储在单独的磁盘文件中 — 如果文件会超过 1 GB,则可能分成多个文件。这些文件的命名约定见。 - + 每个表都有一个主堆磁盘文件,大部分数据都存储在那里。如果表中有任何列可能包含较宽的值,还可能有一个与该表关联的 TOAST 文件,用于存储那些不适合放在主表中的过宽值(参见)。如果该 TOAST 表存在,则它会有一个有效索引。基础表本身也可能带有索引。每个表和索引都存储在单独的磁盘文件中;如果某个文件会超过 1 GB,则可能拆分为多个文件。关于这些文件的命名规则,请参见。 + - 可以通过三种方式监控磁盘空间:使用中列出的 SQL 函数,使用模块,或者手工检查系统目录。SQL 函数最容易使用,通常也是推荐的方法。本节其余部分展示如何通过检查系统目录来完成此事。 - + 你可以通过三种方式监控磁盘空间:使用中列出的 SQL 函数、使用模块,或者手工检查系统目录。SQL 函数最容易使用,通常也是推荐的方法。本节余下内容展示如何通过检查系统目录来完成这项工作。 + - 在最近做过 vacuum 或 analyze 的数据库上使用psql时,可以发出查询以查看任意表的磁盘使用情况: + 在最近进行过清理或分析 的数据库上使用 psql,你可以发出查询来查看任意表的磁盘使用情况: SELECT pg_relation_filepath(oid), relpages FROM pg_class WHERE relname = 'customer'; @@ -32,11 +32,11 @@ SELECT pg_relation_filepath(oid), relpages FROM pg_class WHERE relname = 'custom base/16384/16806 | 60 (1 row) - 每个页通常为 8 KB。(请记住,relpages只会由VACUUMANALYZE以及少数 DDL 命令(如CREATE INDEX)更新。)如果你想直接检查该表的磁盘文件,文件路径名就很有用。 - + 每一页通常是 8 KB。(请记住,relpages 只会由 VACUUMANALYZE 以及少数 DDL 命令如 CREATE INDEX 更新。)如果你想直接检查该表的磁盘文件,那么文件路径名会很有用。 + - 要显示TOAST表使用的空间,可使用如下查询: + 要显示 TOAST 表使用的空间,可以使用如下查询: SELECT relname, relpages FROM pg_class, @@ -54,9 +54,11 @@ ORDER BY relname; pg_toast_16806 | 0 pg_toast_16806_index | 1 - + - 也可以轻松显示索引大小: + + 也可以很容易地显示索引所占空间: + SELECT c2.relname, c2.relpages FROM pg_class c, pg_class c2, pg_index i WHERE c.relname = 'customer' AND @@ -68,10 +70,10 @@ ORDER BY c2.relname; -------------------+---------- customer_id_index | 26 - + - 利用这些信息,可以很容易找出最大的表和索引: + 利用这些信息,你可以很容易地找出最大的表和索引: SELECT relname, relpages FROM pg_class @@ -82,28 +84,28 @@ ORDER BY relpages DESC; bigtable | 3290 customer | 3144 - + 磁盘已满故障 - 数据库管理员最重要的磁盘监控任务,是确保磁盘不会被写满。数据盘被写满不会导致数据损坏,但可能使有用的活动无法继续进行。如果存放 WAL 文件的磁盘逐渐被写满,数据库服务器可能会进入 panic 状态并随后关闭。 - + 数据库管理员最重要的磁盘监控任务,是确保磁盘不会被写满。数据磁盘写满不会导致数据损坏,但可能会阻止有用的活动继续进行。如果保存 WAL 文件的磁盘被写满,则数据库服务器可能会 panic 并随后关闭。 + - 如果无法通过删除其他内容来释放磁盘上的额外空间,可以利用表空间将部分数据库文件移到其他文件系统上。有关更多信息,请参见。 - + 如果你无法通过删除其他文件来释放更多磁盘空间,那么可以利用表空间把部分数据库文件移动到其他文件系统上。详见。 + - 有些文件系统在接近写满时性能很差,因此不要等到磁盘完全写满才采取措施。 - + 有些文件系统在接近写满时性能会明显变差,因此不要等到磁盘完全写满才采取措施。 + - 如果系统支持按用户设置磁盘配额,那么数据库自然会受限于运行服务器的那个用户所被施加的配额。超出配额与磁盘空间完全耗尽会产生同样的不良影响。 - + 如果你的系统支持按用户设置磁盘配额,那么数据库自然也会受到运行服务器的那个用户所拥有配额的限制。超出配额会带来与磁盘空间完全耗尽相同的不良影响。 + diff --git a/zh/13/docguide.sgml b/zh/13/docguide.sgml index 957777ba..56d7f4eb 100644 --- a/zh/13/docguide.sgml +++ b/zh/13/docguide.sgml @@ -212,7 +212,7 @@ checking for dbtoepub... dbtoepub - 使用 Make 构建文档 + 构建文档 一切设置妥当后,切换到doc/src/sgml目录,并运行后续各小节中介绍的某个命令来构建文档。 @@ -230,21 +230,30 @@ checking for dbtoepub... dbtoepub 这也是默认目标。输出位于子目录html中。 - 要生成 HTML 文档,并采用以下站点使用的样式表:postgresql.org,以替代默认的简单样式,请使用: + + 若要使用postgresql.org上所使用的样式表, + 而不是默认的简单样式来生成 HTML 文档,请使用: + doc/src/sgml$ make STYLE=website html - 如果使用STYLE=website选项,生成的 HTML 文件会引用托管在postgresql.org上的样式表,查看时需要访问网络。 + + 如果使用STYLE=website选项,生成的 HTML 文件会包含对托管在 + postgresql.org上的样式表的引用, + 因而查看时需要网络访问。 + 手册页 - 我们使用 DocBook XSL 样式表转换DocBook - refentry页面,生成适用于手册页的 *roff 输出。要创建手册页,请使用以下命令: + + 我们使用 DocBook XSL 样式表将DocBook + refentry页面转换为适合手册页的 *roff 输出。 + 要创建手册页,请使用以下命令: + doc/src/sgml$ make man @@ -253,16 +262,24 @@ checking for dbtoepub... dbtoepub PDF - 要生成 PDF 格式的文档,可以使用FOP,并根据所需纸张格式,选择以下命令之一: + + 要使用FOP生成文档的 PDF 版本, + 可根据所偏好的纸张格式使用下列命令之一: + + - 对于 A4 格式: + + 对于 A4 格式: + doc/src/sgml$ make postgres-A4.pdf - 对于美国信纸格式: + + 对于美国信纸格式: + doc/src/sgml$ make postgres-US.pdf @@ -270,30 +287,50 @@ checking for dbtoepub... dbtoepub - 由于 PostgreSQL 文档相当庞大,FOP需要大量内存。因此,在某些系统上,构建会失败并报告与内存有关的错误。通常可以通过在以下配置文件中调整 Java 堆设置来解决此问题:~/.foprc,例如: -# FOP binary distribution + + 由于 PostgreSQL 文档相当庞大,FOP需要占用相当多的内存。 + 因此,在某些系统上,构建会因内存相关错误而失败。这通常可以通过在配置文件 + ~/.foprc中配置 Java 堆设置来解决,例如: + +# FOP 二进制发行版 FOP_OPTS='-Xmx1500m' # Debian JAVA_ARGS='-Xmx1500m' # Red Hat ADDITIONAL_FLAGS='-Xmx1500m' -所需内存存在一个最低限度,而在一定范围内,更多内存似乎能使构建稍快一些。在内存很少(不足 1 GB)的系统上,构建要么因交换而非常缓慢,要么根本无法进行。 + + 所需内存存在一个最低门槛,而且在一定程度上,内存越多似乎会让构建稍快一些。 + 对于内存很少(小于 1 GB)的系统,构建要么会因交换而非常缓慢,要么根本无法工作。 + - 其他 XSL-FO 处理器也可以手动使用,但自动构建过程只支持 FOP。 + + + 也可以手工使用其他 XSL-FO 处理器,但自动化构建过程只支持 FOP。 + 纯文本文件 - 安装说明也以纯文本形式分发,以便在没有更好阅读工具的情况下使用。INSTALL文件对应于,仅为适应不同语境作了一些小改动。要重新创建该文件,请切换到doc/src/sgml目录并输入make INSTALL。构建文本输出还需要Pandoc 1.13 或更新版本作为额外的构建工具。 + + 安装说明也以纯文本形式分发,以便在没有更好的阅读工具时使用。 + INSTALL文件对应,并针对不同语境作了少量调整。 + 要重新生成该文件,请切换到doc/src/sgml目录,然后输入make INSTALL。 + 构建文本输出还需要Pandoc 1.13 或更新版本作为额外的构建工具。 + - 过去,发布说明和回归测试说明也以纯文本形式分发,但这种做法已经停止。 + + 过去,发行说明和回归测试说明也曾以纯文本形式分发,但现已停止这种做法。 + 语法检查 - 构建文档可能耗时很长。但有一种方法可以只检查文档文件的语法是否正确,只需几秒钟: + + 构建文档可能非常耗时。但有一种方法可以只检查文档文件的语法是否正确, + 这只需要几秒钟: + doc/src/sgml$ make check diff --git a/zh/13/ecpg.sgml b/zh/13/ecpg.sgml index d8cca984..672236c7 100644 --- a/zh/13/ecpg.sgml +++ b/zh/13/ecpg.sgml @@ -1041,7 +1041,7 @@ oid=313780, datname=testdb, size=8183012 - 结构体主变量将列尽数吸收成结构体的域。额外的列可以被分配给其他主变量。例如,上面的程序也可以使用结构体外部的size变量重新构造: + 结构体主变量吸收的列数与结构体的字段数相同。额外的列可以被分配给其他主变量。例如,上面的程序也可以使用结构体外部的size变量改写: EXEC SQL BEGIN DECLARE SECTION; typedef struct @@ -1305,7 +1305,7 @@ while (1) 用户定义的基础类型 - ECPG 并不直接支持新的用户定义的基本类型。你可以使用外部字符串表示以及类型char[]VARCHAR[]的主变量,并且这种方案事实上对很多类型都是合适和足够的。 + ECPG 并不直接支持新的用户定义的基础类型。你可以使用外部字符串表示以及类型char[]VARCHAR[]的主变量,并且这种方案事实上对很多类型都是合适和足够的。 下面的示例使用数据类型 complex,它来自 中的示例。该类型的外部字符串表示为 (%f,%f),由函数 complex_in()complex_out() 定义,见 。以下示例将复数类型的值 (1,1)(3,3) 分别插入列 ab,然后从表中查询它们。 @@ -4510,7 +4510,7 @@ EXEC SQL INCLUDE "filename"; 当前目录 /usr/local/include - PostgreSQL 的包括目录,在编译时定义(例如/usr/local/pgsql/include + PostgreSQL 的头文件目录,在编译时定义(例如/usr/local/pgsql/include /usr/include @@ -4634,7 +4634,7 @@ EXEC SQL UPDATE Tbl SET col = MYNUMBER; - 此示例将完全编译三个SET TIMEZONE命令之一: + 此示例将完全编译三个SET TIMEZONE命令之一: EXEC SQL ifdef TZVAR; EXEC SQL SET TIMEZONE TO TZVAR; @@ -5252,7 +5252,7 @@ DATABASE connection_target 使用 user_name/passworduser_name IDENTIFIED BY password或者 - user_name USING password之一,这个参数也能指定用户名和密码. + user_name USING password之一,这个参数也能指定用户名和密码。 @@ -7261,19 +7261,19 @@ int rjulmdy(date d, short mdy[3]); rdefmtdate - 使用格式掩码将字符字符串转换为日期类型的值。 + 使用格式掩码将字符串转换为日期类型的值。 int rdefmtdate(date *d, char *fmt, char *str); 该函数接收一个指向应该保存操作结果的日期值的指针(d), 用于解析日期的格式掩码(fmt)和包含日期文本表示的C char*字符串 (str)。文本表示应与格式掩码匹配。但是,你不需要将字符串 - 与格式掩码进行一一映射。该函数仅分析顺序顺序,并查找表示年份位置的文字 + 与格式掩码进行一一映射。该函数只分析先后顺序,并查找表示年份位置的字面文本 yyyyyy,表示月份位置的mm 和表示日期位置的dd - 该函数返回以下值: + 该函数返回以下值: diff --git a/zh/13/event-trigger.sgml b/zh/13/event-trigger.sgml index c3918f6f..1feeaf7c 100644 --- a/zh/13/event-trigger.sgml +++ b/zh/13/event-trigger.sgml @@ -20,11 +20,11 @@ - 事件触发器行为概览 + 事件触发器行为概述 只要与事件触发器关联的事件在其定义所在数据库中发生,事件触发器就会被触发。 - 目前唯一支持的事件有 + 目前仅支持以下事件: ddl_command_startddl_command_endtable_rewrite @@ -39,14 +39,14 @@ COMMENTGRANTREVOKE 命令即将执行之前。在事件触发器触发之前,不会检查受影响对象究竟存在还是不存在。 但有一个例外:对于以共享对象 — 数据库、角色和表空间 — - 为目标的 DDL 命令,或者针对事件触发器本身的命令,不会发生该事件。事件触发器机制 + 为目标的 DDL 命令或者针对事件触发器本身的命令,不会发生该事件。事件触发器机制 不支持这些对象类型。 ddl_command_start 也会在 SELECT INTO 命令即将执行之前发生,因为它等价于 CREATE TABLE AS - ddl_command_end 事件发生在与上述同一组命令执行之后。 + ddl_command_end 事件发生在上述同一组命令执行之后。 要获取这些 DDL 操作的更多细节,可在 ddl_command_end 事件触发器代码中使用集合返回函数 pg_event_trigger_ddl_commands()(见 @@ -1059,7 +1059,7 @@ CALLED_AS_EVENT_TRIGGER(fcinfo) ((fcinfo)->context != NULL && IsA((fcinfo)->context, EventTriggerData)) - 如果该宏返回 true,那么就可以安全地将 fcinfo->context + 如果该宏返回真,那么就可以安全地将 fcinfo->context 转换为 EventTriggerData * 类型,并使用它所指向的 EventTriggerData 结构体。该函数 不得修改 EventTriggerData @@ -1067,7 +1067,8 @@ CALLED_AS_EVENT_TRIGGER(fcinfo) - struct EventTriggerData定义在commands/event_trigger.h: + struct EventTriggerData 定义于 + commands/event_trigger.h 中: typedef struct EventTriggerData @@ -1077,7 +1078,11 @@ typedef struct EventTriggerData Node *parsetree; /* parse tree */ CommandTag tag; /* command tag */ } EventTriggerData; -其成员定义如下: + + + 其中各成员定义如下: + + type @@ -1125,7 +1130,7 @@ typedef struct EventTriggerData 事件触发器函数必须返回一个 NULL 指针 (不是 SQL 空值,也就是不要将 - isNull 设为 true)。 + isNull 设为真)。 @@ -1173,7 +1178,9 @@ noddl(PG_FUNCTION_ARGS) ]]> - 编译源代码后(见),声明函数和触发器: + + 编译源代码之后(见 ),声明该函数和触发器: + CREATE FUNCTION noddl() RETURNS event_trigger AS 'noddl' LANGUAGE C; @@ -1182,7 +1189,9 @@ CREATE EVENT TRIGGER noddl ON ddl_command_start - 现在可以测试触发器的工作情况: + + 现在可以测试该触发器的工作情况: + =# \dy List of event triggers Name | Event | Owner | Enabled | Function | Tags @@ -1217,7 +1226,9 @@ COMMIT; 从而只允许在维护窗口内执行重写。 - 下面是一个实现这种策略的示例。 + + 以下是实现这种策略的一个示例。 + CREATE OR REPLACE FUNCTION no_rewrite() RETURNS event_trigger LANGUAGE plpgsql AS diff --git a/zh/13/extend.sgml b/zh/13/extend.sgml index 403e5d1d..d7846cd4 100644 --- a/zh/13/extend.sgml +++ b/zh/13/extend.sgml @@ -39,7 +39,7 @@ - 相关对象包(从 开始) + 相关对象的包(从 开始) @@ -49,11 +49,28 @@ 可扩展性如何运作 - PostgreSQL 之所以具有可扩展性,是因为它的运作由目录驱动。如果你熟悉标准的关系数据库系统,就会知道它们会把数据库、表、列等信息存储在通常所说的系统目录中(有些系统称之为数据字典)。这些目录对用户来说看起来和普通表无异,但 DBMS 会在其中保存自己的内部记账信息。PostgreSQL 与标准关系数据库系统的一个关键区别在于,PostgreSQL在目录中存储了更多信息:不仅包括表和列的信息,还包括数据类型、函数、访问方法等信息。这些表可以由用户修改,而 PostgreSQL 又正是基于这些表运行的,这就意味着用户可以扩展 PostgreSQL。相比之下,传统数据库系统只能通过修改源代码中的硬编码过程,或装入由 DBMS 供应商专门编写的模块来扩展。 + PostgreSQL 之所以具有可扩展性,是因为其 + 运作由系统目录驱动。如果你熟悉标准的关系数据库系统,就会知道它们把 + 有关数据库、表、列等的信息存储在通常所说的系统目录中(有些系统把这 + 称为数据字典)。这些目录对用户而言看起来就像普通表一样,但 + DBMS 会在其中保存自己的内部管理信息。 + PostgreSQL 与标准关系数据库系统的一个关键差别是, + PostgreSQL 在目录中存储的信息要多得多:不仅有关于表和列的信息,还有关于数据 + 类型、函数、访问方法等的信息。这些表可以由用户修改,而 + PostgreSQL 又是基于这些表来运行的,这意味着 + PostgreSQL 可以由用户扩展。相比之下,传统数据库 + 系统只能通过修改源代码中的硬编码过程,或加载由 + DBMS 供应商专门编写的模块来扩展。 - 此外,PostgreSQL 服务器还可以通过动态加载将用户编写的代码纳入自身。也就是说,用户可以指定一个实现新类型或新函数的目标代码文件(例如共享库),而 PostgreSQL 会在需要时加载它。把用 SQL 编写的代码加入服务器就更简单了。这种能够即时修改自身行为的能力,使 PostgreSQL 特别适合用于新应用和新存储结构的快速原型设计。 + 此外,PostgreSQL 服务器还能通过动态加载把用户 + 编写的代码纳入自身。也就是说,用户可以指定一个实现了新类型或新函数 + 的目标代码文件(例如共享库),而 PostgreSQL + 会在需要时加载它。把用 SQL 编写的代码加入服务器就更 + 为简单了。这种能够即时修改自身行为的能力,使 + PostgreSQL 特别适合用于新应用和新存储结构的快速 + 原型设计。 @@ -75,7 +92,7 @@ 数据类型 - 组合 + 复合 @@ -434,7 +451,7 @@ RETURNS anycompatible AS ... 哪些 SQL 对象种类可以成为扩展成员,见 的说明。特别是,数据库集簇范围内的对象,如数据库、角色和表空间,不能 - 成为扩展成员,因为扩展只在单个数据库内可见。(尽管扩展脚本并不禁止创 + 成为扩展成员,因为扩展只在单个数据库内可见。(尽管并不禁止扩展脚本创 建这类对象,但如果这样做,它们不会作为扩展的一部分受到跟踪。)还要注意, 虽然表可以成为扩展成员,但其附属对象(如索引)并不直接被视为扩展成员。 另一个重要点是,模式可以属于扩展,但反过来不成立:扩展本身只有一个非 @@ -475,7 +492,11 @@ RETURNS anycompatible AS ... directory (string) - 包含扩展的 SQL 脚本文件的目录。除非给出绝对路径,否则该名称相对于安装目录的 SHAREDIR 目录。默认行为等价于指定 directory = 'extension' + + 包含扩展 SQL 脚本文件的目录。除非给出的是绝对路 + 径,否则该名称相对于安装的 SHAREDIR 目录。默认行为 + 等价于指定 directory = 'extension'。 + @@ -556,7 +577,7 @@ RETURNS anycompatible AS ... trusted (boolean) - 如果将此参数设为 true(不是默认值),则允许某些非超级用户安装 superuser 设为 true 的扩展。具体而言,当前数据库上具有 CREATE 权限的任何人都可以安装。当执行 CREATE EXTENSION 的用户不是超级用户,但凭借此参数获准安装时,安装或更新脚本会以引导超级用户的身份运行,而不是调用用户的身份。如果 superuserfalse,则此参数无关。通常,对于可能允许访问原本仅限超级用户使用的能力(例如文件系统访问)的扩展,不应将此参数设为真。此外,将扩展标记为可信,需要投入大量额外工作来安全地编写其安装和更新脚本;参见 + 如果将此参数设为 true(不是默认值),则允许某些非超级用户安装 superuser 设为 true 的扩展。具体而言,当前数据库上具有 CREATE 权限的任何人都可以安装。当执行 CREATE EXTENSION 的用户不是超级用户,但凭借此参数获准安装时,安装或更新脚本会以引导超级用户的身份运行,而不是调用用户的身份。如果 superuserfalse,则此参数不起作用。通常,对于可能允许访问原本仅限超级用户使用的能力(例如文件系统访问)的扩展,不应将此参数设为真。此外,将扩展标记为受信任的,需要投入大量额外工作来安全地编写其安装和更新脚本;参见 @@ -614,7 +635,15 @@ RETURNS anycompatible AS ... 而不是作为一个扩展来装载,这种状态恢复起来会有些麻烦。 - 如果扩展脚本包含字符串 @extowner@,该字符串会替换为调用 CREATE EXTENSIONALTER EXTENSION 的用户名,并进行适当引用。标记为可信的扩展通常使用此功能,将选定对象的拥有权赋予调用用户,而不是引导超级用户。(但这样做应当谨慎。例如,将 C 语言函数的拥有权赋予非超级用户,会为该用户提供权限提升的途径。) + + 如果扩展脚本中包含字符串 @extowner@,该字符串会被 + 替换为调用 CREATE EXTENSION 或 + ALTER EXTENSION 的用户名称(会适当加上引号)。通常, + 这个特性被标记为受信任的扩展用来把选定对象的 + 所有权赋给调用用户, + 而不是赋给引导超级用户。(不过这样做时应当谨慎。例如,把一个 C 语言 + 函数的所有权赋给非超级用户,会为该用户创建一条权限提升路径。) + 虽然脚本文件可以包含指定编码允许的任意字符,但控制文件应只包含纯 @@ -657,7 +686,7 @@ RETURNS anycompatible AS ... 扩展,应在控制文件中设置 relocatable = false,并在脚本文件中使用 @extschema@ 来引用目标模式。在脚本执行前,该字符 - 串的每次出现都会被替换为实际目标模式的名称(必要时加双引号)。用户 + 串的每次出现都会被替换为实际目标模式的名称。用户 可以通过 CREATE EXTENSIONSCHEMA 选项设置目标模式。 @@ -669,7 +698,7 @@ RETURNS anycompatible AS ... relocatable = false,并把 schema 设置为预定目标模式的名称。这样将阻止使用 CREATE EXTENSIONSCHEMA - 选项,除非它指定的正是控制文件中命名的那个模式。如果扩展对其模式名 + 选项,除非它指定的正是控制文件中命名的那个模式。如果扩展对模式名 称有无法通过 @extschema@ 替换解决的内部假设,通 常就需要采用这种方式。在这种情况下, @extschema@ 替换机制仍然可用,只是由于模式名由控 @@ -818,7 +847,7 @@ SELECT pg_catalog.pg_extension_config_dump('my_config', 'WHERE NOT standard_entr 在有合适更新脚本可用的前提下, - ALTER EXTENSION UPDATE 命令可以把已安装的扩展更新 + ALTER EXTENSION UPDATE 命令会把已安装的扩展更新 到指定的新版本。更新脚本运行在 CREATE EXTENSION 为安装脚本提供的同一环境中:尤其 是,search_path 的设置方式完全相同,而且脚本创建的 @@ -844,7 +873,7 @@ SELECT pg_catalog.pg_extension_config_dump('my_config', 'WHERE NOT standard_entr 例如,它并不知道 1.1 是否跟在 1.0 之后。它只是匹配可用的版本名,并选择需要应用 更新脚本最少的那条路径。(实际上,版本名可以是任何不包含 - --,且不以前导或尾随 - 结尾的字 + --,且不以 - 开头或结尾的字 符串。) @@ -919,7 +948,7 @@ SELECT * FROM pg_extension_update_paths('extension_namesuperuser 属性设为真的扩展,还必须考虑其安装和更新脚本所执行操作的安全风险。恶意用户可以创建木马对象,破坏以后对编写不慎的扩展脚本的执行,从而获得超级用户权限;这并非特别困难。 - 如果扩展被标记为 trusted,那么安装用户可以选择其安装模式,而该用户可能故意使用不安全的模式,试图获得超级用户权限。因此,从安全角度看,可信扩展面临的风险极高,必须仔细检查其全部脚本命令,确保无法被攻破。 + 如果扩展被标记为 trusted,那么安装用户可以选择其安装模式,而该用户可能故意使用不安全的模式,试图获得超级用户权限。因此,从安全角度看,受信任的扩展面临的风险极高,必须仔细检查其全部脚本命令,确保无法被攻破。 关于如何安全地编写函数,建议见下面的 @@ -967,7 +996,7 @@ SELECT * FROM pg_extension_update_paths('extension_namemyschema.myfunc(bigint),那么像 myschema.myfunc(42) 这样的调用,就可能被恶意函数 myschema.myfunc(integer) 截获。要注意函数和操作符 - 参数的数据类型必须与声明的实参类型精确匹配,必要时请使用显式类型转 + 所传参数的数据类型必须与声明的参数类型精确匹配,必要时请使用显式类型转 换。 @@ -1003,7 +1032,14 @@ SELECT * FROM pg_extension_update_paths('extension_namecontrib 模块中可以找到示例。 - 跨扩展引用极难做到完全安全,部分原因是无法确定另一个扩展位于哪个模式中。如果两个扩展安装在同一模式,风险会降低,因为此时恶意对象无法在安装时的 search_path 中排在被引用扩展之前。不过,目前没有机制强制这一点。目前的最佳做法是:若某个扩展依赖另一个扩展,除非后者始终安装在 pg_catalog 中,否则不要将前者标记为可信。 + + 跨扩展引用要做到完全安全是极其困难的,部分原因是无法确定另一个扩展 + 位于哪个模式中。如果两个扩展都安装在同一个模式中,风险就会降低, + 因为这样恶意对象就无法在安装时的 search_path 中 + 被放到被引用扩展之前。但目前还没有机制来强制要求这一点。就目前而言, + 最佳实践是:如果一个扩展依赖于另一个扩展,就不要将它标记为受信任的, + 除非那个被依赖的扩展始终安装在 pg_catalog 中。 + @@ -1011,7 +1047,7 @@ SELECT * FROM pg_extension_update_paths('extension_name扩展示例 - 下面给出一个纯 SQL 扩展的完整示例:一个双元素组合 + 下面给出一个纯 SQL 扩展的完整示例:一个双元素复合 类型,它可以在两个槽位中存储任意类型的值,这两个槽位名为 kv。非文本值会自动强制转换为文本后 再存储。 @@ -1083,7 +1119,7 @@ include $(PGXS) 如果你打算分发自己的 PostgreSQL 扩展模块, - 那么为它们搭建一个可移植的构建系统会相当困难。因此, + 那么为它们搭建一个可移植的构建系统可能相当困难。因此, PostgreSQL 安装提供了一套称为 PGXS 的扩展构建基础设施,使简单的扩展模块可以针对 已安装好的服务器直接构建。PGXS 主要面向包含 C 代码 @@ -1094,7 +1130,15 @@ include $(PGXS) 可能还是需要自己编写构建系统。 - 要使用PGXS基础设施构建扩展,必须编写一个简单的 makefile。在其中需要设置一些变量,并包含全局PGXSmakefile。下面的示例构建一个扩展模块,名为isbn_issn,由包含一些 C 代码的共享库、扩展控制文件、SQL 脚本、包含文件(仅在其他模块可能需要不经 SQL 访问扩展函数时才需要)以及文档文本文件组成: + + 要为你的扩展使用 PGXS 基础设施,你必须写一个简单 + 的 makefile。在这个 makefile 中,需要设置一些变量并包含全局 + PGXS makefile。下面是一个示例,它构建一个名为 + isbn_issn 的扩展模块,该模块包含一个装有一些 C 代 + 码的共享库、一个扩展控制文件、一个 SQL 脚本、一个头文件(只有当其他 + 模块可能需要绕过 SQL 直接访问扩展函数时才需要),以及一个文档文本文 + 件: + MODULES = isbn_issn EXTENSION = isbn_issn DATA = isbn_issn--1.0.sql @@ -1104,9 +1148,15 @@ HEADERS_isbn_issn = isbn_issn.h PG_CONFIG = pg_config PGXS := $(shell $(PG_CONFIG) --pgxs) include $(PGXS) -最后三行应始终相同。在文件的前面部分,可以给变量赋值或添加自定义的make规则。 + + 最后三行始终都应相同。你应在文件前面的部分设置变量或添加自定义的 + make 规则。 + - 设置这三个变量之一,以指定构建内容: + + 设定下列三个变量中的一个,以指定要构建的内容: + + MODULES @@ -1120,7 +1170,7 @@ include $(PGXS) MODULE_big - 要从多个源文件构建的共享库(在 OBJS 中列出对象 + 要从多个源文件构建的共享库(在 OBJS 中列出目标 文件) @@ -1130,11 +1180,15 @@ include $(PGXS) PROGRAM - 要构建的可执行程序(在 OBJS 中列出对象文件) + 要构建的可执行程序(在 OBJS 中列出目标文件) - 还可以设置以下变量: + + + 还可以设置以下变量: + + EXTENSION @@ -1411,7 +1465,12 @@ include $(PGXS) make 命令行上设置都可以。 - 如果希望将构建目录单独放置,也可以运行make,并将工作目录设在扩展源码树之外。这种做法也称为VPATHVPATH构建。具体方法如下: + + 如果你想保持构建目录与源代码目录分离,也可以在扩展源代码树之外的目录 + 中运行 make。这一过程也称为 + VPATHVPATH + 构建。做法如下: + mkdir build_dir cd build_dir make -f /path/to/extension/source/tree/Makefile @@ -1438,7 +1497,7 @@ make VPATH=/path/to/extension/source/tree install 正在运行的 PostgreSQL 服务器。列在 REGRESS 中的脚本文件必须位于扩展目录下名为 sql/ 的子目录中。这些文件必须具有 - .sql 扩展名,而该扩展名不应出现在 makefile 的 + .sql 扩展名,而该扩展名不能出现在 makefile 的 REGRESS 列表中。对于每个测试,还应在名为 expected/ 的子目录中有一个包含期望输出的文件,其主 干名相同,扩展名为 .out。 @@ -1457,7 +1516,7 @@ make VPATH=/path/to/extension/source/tree install 必须有一个正在运行的 PostgreSQL 服务器。列 在 ISOLATION 中的脚本文件必须位于扩展目录下名为 specs/ 的子目录中。这些文件必须具有 - .spec 扩展名,而该扩展名不应出现在 makefile 的 + .spec 扩展名,而该扩展名不能出现在 makefile 的 ISOLATION 列表中。对于每个测试,还应在名为 expected/ 的子目录中有一个包含期望输出的文件,其主 干名相同,扩展名为 .out。 diff --git a/zh/13/features.sgml b/zh/13/features.sgml index ebb72238..28763f3d 100644 --- a/zh/13/features.sgml +++ b/zh/13/features.sgml @@ -387,7 +387,7 @@ SELECT XMLQUERY('$a is $b' PASSING BY VALUE x AS a, < DOCUMENTCONTENT形式的值。 一个 XQuery/XPath 表达式的上下文项必须是单个 XML 节点或原子值, 但 XPath 1.0 又进一步限制它只能是 XML 节点,并且没有允许CONTENT的节点类型。 - 归根结底,格式良好的DOCUMENT是 + 归根结底,良构的DOCUMENTPostgreSQL能够作为 XPath 上下文项提供的唯一 XML 值形式。 diff --git a/zh/13/func.sgml b/zh/13/func.sgml index c51feded..b21aa80f 100644 --- a/zh/13/func.sgml +++ b/zh/13/func.sgml @@ -34,14 +34,14 @@ repeat('Pg', 4) PgPgPgPg 逻辑操作符 - operator - logical + 操作符 + 逻辑 - Boolean - operators - operators, logical + 布尔 + 操作符 + 操作符,逻辑 可以使用以下常见逻辑操作符: @@ -74,7 +74,7 @@ repeat('Pg', 4) PgPgPgPg NOT boolean boolean - SQL使用由真、假和null构成的三值逻辑系统,其中 NULL 表示未知。请看下面的真值表: + SQL使用由真、假和null构成的三值逻辑系统,其中 null 表示未知。请看下面的真值表: @@ -170,8 +170,8 @@ repeat('Pg', 4) PgPgPgPg 比较函数和操作符 - comparison - operators + 比较 + 操作符 @@ -254,14 +254,14 @@ repeat('Pg', 4) PgPgPgPg - <>not equal 的标准 SQL 符号。 + <>不等于 的标准 SQL 符号。 != 是一个别名,在解析的早期阶段就会被转换为 <>。 因此,不可能让 !=<> 操作符执行不同的操作。 - 这些比较操作符适用于所有具有自然排序的内置数据类型,包括数字、字符串和日期/时间类型。 + 这些比较操作符适用于所有具有自然排序的内置数据类型,包括数值、字符串和日期/时间类型。 此外,如果其组成数据类型具有可比性,则也可以比较数组、复合类型和范围。 @@ -307,7 +307,7 @@ repeat('Pg', 4) PgPgPgPg boolean - 之间(包括范围端点)。 + 位于两者之间(包括范围端点)。 2 BETWEEN 1 AND 3 @@ -403,7 +403,7 @@ repeat('Pg', 4) PgPgPgPg boolean - 测试值是否为空。 + 测试值是否为 null。 1.5 IS NULL @@ -417,7 +417,7 @@ repeat('Pg', 4) PgPgPgPg boolean - 测试值是否不为空。 + 测试值是否不为 null。 'null' IS NOT NULL @@ -431,7 +431,7 @@ repeat('Pg', 4) PgPgPgPg boolean - 测试值是否为空(非标准语法)。 + 测试值是否为 null(非标准语法)。 @@ -441,7 +441,7 @@ repeat('Pg', 4) PgPgPgPgboolean - 测试值是否不为空(非标准语法)。 + 测试值是否不为 null(非标准语法)。 @@ -562,14 +562,14 @@ repeat('Pg', 4) PgPgPgPg BETWEEN SYMMETRIC - BETWEEN谓词可以简化范围测试: + BETWEEN谓词可以简化范围测试: a BETWEEN x AND y 等价于 a >= x AND a <= y 注意,BETWEEN将两个端点值都视为包含在范围内。BETWEEN SYMMETRIC类似于BETWEEN,但不要求AND左侧的参数小于或等于右侧的参数。如果不是这样,这两个参数会自动交换,以确保表示的范围始终非空。 - BETWEEN的各种变量都是以普通比较操作符的方式实现的,因此适用于任何可以比较的数据类型。 + BETWEEN的各种变体都是以普通比较操作符的方式实现的,因此适用于任何可以比较的数据类型。 @@ -588,12 +588,12 @@ repeat('Pg', 4) PgPgPgPg IS NOT DISTINCT FROM - 当有一个输入为空时,普通的比较操作符会得到空(表示未知),而不是真或假。例如,7 = NULL得到空,7 <> NULL也一样。如果这种行为不合适,可以使用IS NOT DISTINCT FROM谓词: + 当任一输入为 null 时,普通的比较操作符会得到 null(表示未知),而不是真或假。例如,7 = NULL得到 null,7 <> NULL也一样。如果这种行为不合适,可以使用IS NOT DISTINCT FROM谓词: a IS DISTINCT FROM b a IS NOT DISTINCT FROM b - 对于非空输入,IS DISTINCT FROM<>操作符一样。不过,如果两个输入都为空,它会返回假。而如果只有一个输入为空,它会返回真。类似地,IS NOT DISTINCT FROM对于非空输入的行为与=相同,但是当两个输入都为空时它返回真,并且当只有一个输入为空时返回假。因此,这些谓词实际上把空值当作一种普通数据值,而不是未知。 + 对于非 null 输入,IS DISTINCT FROM<>操作符一样。不过,如果两个输入都为 null,它会返回假。而如果只有一个输入为 null,它会返回真。类似地,IS NOT DISTINCT FROM对于非 null 输入的行为与=相同,但是当两个输入都为 null 时它返回真,并且当只有一个输入为 null 时返回假。因此,这些谓词实际上把 null 当作一种普通数据值,而不是未知 @@ -609,7 +609,7 @@ repeat('Pg', 4) PgPgPgPg NOTNULL - 要检查一个值是否为空,使用下面的谓词: + 要检查一个值是否为 null,使用下面的谓词: expression IS NULL expression IS NOT NULL @@ -619,7 +619,7 @@ repeat('Pg', 4) PgPgPgPg expression ISNULL expression NOTNULL - null valuecomparing + 空值比较 @@ -629,7 +629,7 @@ repeat('Pg', 4) PgPgPgPg - 有些应用可能要求表达式expression = NULLexpression得出空值时返回真。我们强烈建议这样的应用修改成遵循 SQL 标准。但是,如果这样修改不可能完成,那么我们可以使用配置变量。如果打开它,PostgreSQL将把x = NULL子句转换成x IS NULL。 + 有些应用可能期望表达式expression = NULLexpression求值为 null 时返回真。我们强烈建议此类应用修改为遵循 SQL 标准。但是,如果无法这样修改,那么可以使用配置变量。如果将其打开,PostgreSQL会把x = NULL子句转换成x IS NULL @@ -665,7 +665,7 @@ repeat('Pg', 4) PgPgPgPg boolean_expression IS UNKNOWN boolean_expression IS NOT UNKNOWN - 这些谓词将总是返回真或假,从来不返回空值,即使操作数为空也如此。空值输入被当作逻辑值未知。请注意,IS UNKNOWNIS NOT UNKNOWN实际上分别等同于IS NULLIS NOT NULL,只是输入表达式必须是布尔类型。 + 这些谓词总是返回真或假,从不返回空值,即使操作数为 null 也是如此。null 输入被当作逻辑值未知。请注意,IS UNKNOWNIS NOT UNKNOWN实际上分别等同于IS NULLIS NOT NULL,只是输入表达式必须是布尔类型。 + 正则表达式 + @@ -4511,13 +4506,11 @@ cast(-44 as bit(12)) 111111010100 - SIMILAR TO操作符根据自己的模式是否匹配给定串而返回真或者假。 - 它和LIKE非常类似,只不过它使用 SQL 标准定义的正则表达式理解模式。 - SQL 正则表达式是在LIKE标记和普通的(POSIX)正则表达式标记的奇怪的杂交。 + SIMILAR TO操作符根据其模式是否匹配给定字符串返回真或假。它与LIKE非常相似,但使用 SQL 标准定义的正则表达式来解释模式。SQL 正则表达式是LIKE表示法与普通(POSIX)正则表达式表示法的一种奇特结合。 - 类似LIKESIMILAR TO操作符只有在它的模式匹配整个串的时候才能成功;这一点和普通的 正则表达式的行为不同,在普通的正则表达式里,模式匹配串的任意部分。 和LIKE类似的地方还有,SIMILAR TO使用_%作为分别代表任意单个字符和任意串的通配符(这些可以比得上 POSIX 正则表达式里的..*)。 + 与LIKE类似,SIMILAR TO操作符只有在其模式匹配整个字符串时才算成功;这一点不同于普通正则表达式,后者可以匹配字符串的任意部分。与LIKE相同,SIMILAR TO也使用_%作为通配符,分别匹配任意单个字符和任意字符串(分别类似于 POSIX 正则表达式中的..*)。 @@ -4585,8 +4578,7 @@ cast(-44 as bit(12)) 111111010100 - 另一个非标准扩展是,在转义字符后面跟着一个字母或数字提供了对为POSIX正则表达式定义的转义序列的访问;参见下面的 - ,和 。 + 另一个非标准扩展是在转义字符后跟一个字母或数字,以使用 POSIX 正则表达式定义的转义序列;参见下文的 下面是一些示例: @@ -4610,7 +4602,7 @@ substring(string, pattern, - 作为对SQL标准的扩展,PostgreSQL只允许有一个转义双引号分隔符,在这种情况下,第三个正则表达式被视为空;或者没有分隔符,在这种情况下,第一个和第三个正则表达式被视为空。 + 作为对SQL标准的扩展,PostgreSQL允许仅有一个转义双引号分隔符,在这种情况下,第三个正则表达式被视为空;或者没有分隔符,在这种情况下,第一个和第三个正则表达式被视为空。 下面是一些示例,其中使用#"界定返回字符串: @@ -4624,8 +4616,8 @@ substring('foobar' from '#"o_b#"%' for '#') NULLPOSIX正则表达式 - regular expression - pattern matching + 正则表达式 + 模式匹配 substring @@ -4668,7 +4660,7 @@ substring('foobar' from '#"o_b#"%' for '#') NULLboolean - 字符串匹配正则表达式,大小写敏感 + 字符串匹配正则表达式,区分大小写 'thomas' ~ 't.*ma' @@ -4682,7 +4674,7 @@ substring('foobar' from '#"o_b#"%' for '#') NULLboolean - 字符串匹配正则表达式,大小写不敏感 + 字符串匹配正则表达式,不区分大小写 'thomas' ~* 'T.*ma' @@ -4696,7 +4688,7 @@ substring('foobar' from '#"o_b#"%' for '#') NULLboolean - 字符串不匹配正则表达式,大小写敏感 + 字符串不匹配正则表达式,区分大小写 'thomas' !~ 't.*max' @@ -4710,7 +4702,7 @@ substring('foobar' from '#"o_b#"%' for '#') NULLboolean - 字符串不匹配正则表达式,大小写不敏感 + 字符串不匹配正则表达式,不区分大小写 'thomas' !~* 'T.*ma' @@ -4722,11 +4714,11 @@ substring('foobar' from '#"o_b#"%' for '#') NULL - POSIX正则表达式提供了比LIKESIMILAR TO操作符更强大的含义。许多 Unix 工具,例如egrepsedawk使用一种与我们这里描述的类似的模式匹配语言。 + POSIX正则表达式提供了比LIKESIMILAR TO操作符更强大的模式匹配方式。许多 Unix 工具,例如egrepsedawk,都使用与这里描述的模式匹配语言相似的语言。 - 正则表达式是一个字符序列,它是定义一个串集合 (一个正则集)的缩写。 如果一个串是正则表达式描述的正则集中的一员时, 我们就说这个串匹配该正则表达式。 和LIKE一样,模式字符准确地匹配串字符, 除非在正则表达式语言里有特殊字符 — 不过正则表达式用的 特殊字符和LIKE用的不同。 和LIKE模式不一样的是,正则表达式允许匹配串里的任何位置,除非该正则表达式显式地挂接在串的开头或者结尾。 + 正则表达式是一个字符序列,是定义一组字符串(一个正则集)的简写。如果字符串属于正则表达式描述的正则集,就称该字符串匹配此正则表达式。与LIKE一样,模式中的字符精确匹配字符串中的字符,除非该模式字符在正则表达式语言中有特殊含义 — 但正则表达式使用的特殊字符与LIKE不同。与LIKE模式不同,正则表达式可以匹配字符串中的任意位置,除非显式将其锚定到字符串开头或末尾。 下面是一些示例: @@ -4745,8 +4737,8 @@ substring('foobar' from '#"o_b#"%' for '#') NULL 带两个参数的substring函数,即substring(string from pattern),提供了抽取一个匹配 POSIX 正则表达式模式的子串的方法。 - 如果没有匹配它返回空值,否则就是匹配模式的文本中的第一部分。 - 但是如果该模式包含任何圆括号,那么将返回匹配第一对子表达式(对应第一个左圆括号的) 的文本。 + 如果没有匹配它返回空值,否则返回文本中首次匹配模式的那部分内容。 + 但是如果该模式包含任何圆括号,那么将返回匹配第一个圆括号子表达式(左圆括号最先出现的那个)的文本。 如果你想在表达式里使用圆括号而又不想导致这个例外,那么你可以在整个表达式外边放上一对圆括号。 如果你需要在想抽取的子表达式前有圆括号,参阅后文描述的非捕获性圆括号。 @@ -4770,13 +4762,13 @@ regexp_replace('foobarbaz', 'b(..)', 'X\1Y', 'g') - regexp_match函数返回一个文本数组,其中包含与POSIX正则表达式模式对字符串的第一个匹配的子字符串。它的语法为 + regexp_match函数返回一个文本数组,包含字符串首次匹配 POSIX 正则表达式模式时捕获的子字符串。它的语法为 regexp_match(string, pattern , flags )。 如果没有匹配,结果为NULL。 - 如果找到匹配,并且pattern不包含括号子表达式,则结果是包含与整个模式匹配的子字符串的单元素文本数组。 - 如果找到匹配,并且pattern包含括号子表达式,则结果是一个文本数组,其中第n个元素是匹配 - pattern的第n个括号子表达式的子字符串(不包括非捕获括号;详情见下文)。 + 如果找到匹配,并且pattern不包含圆括号子表达式,则结果是包含与整个模式匹配的子字符串的单元素文本数组。 + 如果找到匹配,并且pattern包含圆括号子表达式,则结果是一个文本数组,其中第n个元素是匹配 + pattern的第n个圆括号子表达式的子字符串(不包括非捕获括号;详情见下文)。 flags参数是一个可选的文本字符串,其中包含零个或多个单个字母标志,用于更改函数的行为。支持的标志在中描述。 @@ -4830,16 +4822,16 @@ SELECT regexp_matches('foobarbequebazilbarfbonk', '(b[^b]+)(b[^b]+)', 'g'); - 在大部分情况下,regexp_matches()应该与g标志一起使用,因为如果只是想要第一个匹配,使用regexp_match()会更加简单高效。不过,regexp_match()仅存在于PostgreSQL版本10以及更高的版本中。当在较老的版本中使用时,一种常用的技巧是把regexp_matches()调用放在子选择中,例如: + 在大部分情况下,regexp_matches()应该与g标志一起使用,因为如果只是想要第一个匹配,使用regexp_match()会更加简单高效。不过,regexp_match()仅存在于PostgreSQL版本10以及更高的版本中。当在较老的版本中使用时,一种常用的技巧是把regexp_matches()调用放在子查询中,例如: SELECT col1, (SELECT regexp_matches(col2, '(bar)(beque)')) FROM tab; - 如果有一个匹配,则这个语句会产生一个文本数组,否则返回NULL,这和regexp_match()的做法一样。如果没有子选择,这个查询对于没有匹配的表行根本不会产生输出,显然那不是想要的行为。 + 如果有一个匹配,则这个语句会产生一个文本数组,否则返回NULL,这和regexp_match()的做法一样。如果没有子查询,这个查询对于没有匹配的表行根本不会产生输出,这通常不是预期行为。 - regexp_split_to_table把一个 POSIX 正则表达式模式当作一个定界符来分离一个串。它的语法形式是regexp_split_to_table(string, pattern , flags )。如果没有与pattern的匹配,该函数返回string。如果有至少有一个匹配,对每一个匹配它都返回从上一个匹配的末尾(或者串的开头)到这次匹配开头之间的文本。当没有更多匹配时,它返回从上一次匹配的末尾到串末尾之间的文本。flags参数是一个可选的文本串,它包含零个或更多单字母标志,这些标识可以改变该函数的行为。regexp_split_to_table能支持的标志在中描述。 + regexp_split_to_table把一个 POSIX 正则表达式模式当作一个定界符来分割字符串。它的语法形式是regexp_split_to_table(string, pattern , flags )。如果没有与pattern的匹配,该函数返回string。如果至少有一个匹配,对每一个匹配它都返回从上一个匹配的末尾(或者串的开头)到这次匹配开头之间的文本。当没有更多匹配时,它返回从上一次匹配的末尾到串末尾之间的文本。flags参数是一个可选的文本串,它包含零个或更多单字母标志,这些标志可以改变该函数的行为。regexp_split_to_table能支持的标志在中描述。 @@ -4892,9 +4884,9 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; - 正如最后一个示例所示,regexp分割函数会忽略出现在字符串开头或结尾 + 正如最后一个示例所示,正则表达式分割函数会忽略出现在字符串开头或结尾 或紧跟在前一个匹配项之后的零长度匹配。这与regexp_matchregexp_matches实现的 - 严格的regexp匹配定义相矛盾,但在实践中通常是最方便的行为。 + 严格的正则表达式匹配定义相矛盾,但在实践中通常是最方便的行为。 其他软件系统如Perl使用类似的定义。 @@ -4928,7 +4920,7 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; - 一个量化原子是一个原子, 后面可能跟着一个量词。没有量词的时候,它匹配一个原子, 有量词的时候,它可以匹配若干个原子。一个原子可以是在里面显示的任何可能。 可能的量词和它们的含义在里显示。 + 一个量化原子是一个原子,后面可以跟一个量词。没有量词时,匹配一次原子所匹配的内容;有量词时,按量词指定的次数匹配原子所匹配的内容。原子可以是列出的任何一种形式。可用量词及其含义见 @@ -4951,12 +4943,12 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; (re) - (其中re是任何正则表达式) 匹配一个对re的匹配,匹配将为可能的报告被记下 + (其中re是任意正则表达式)匹配re所匹配的内容,并记录该匹配,以备输出结果 (?:re) - 同上,但是匹配不会为了报告而被记下 (一个非捕获圆括号集) (只对 ARE) + 同上,但不记录匹配结果(非捕获圆括号;仅适用于 ARE) @@ -4971,17 +4963,17 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; \k - (其中k是一个非字母数字字符) 匹配一个被当作普通字符看待的特定字符, 例如,\\匹配一个反斜线字符 + (其中k既不是字母也不是数字)把该字符视为普通字符并匹配它,例如,\\匹配反斜线字符 \c - 其中c是一个字母数字 (可能跟着其它字符),它是一个转义, 参阅(仅对 ARE; 在 ERE 和 BRE 中,它匹配c + 其中c是字母或数字(后面可能还有其他字符),这是一个转义,参见(仅适用于 ARE;在 ERE 和 BRE 中,它匹配c { - 如果后面跟着一个字符,而不是数字, 那么就匹配左花括弧{;如果跟着一个数字, 那么它是bound的开始(见下文) + 如果后面跟着非数字字符,则匹配左花括号{;如果后面跟着数字,则是bound的开头(见下文) @@ -4999,7 +4991,7 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; - 如果你关掉了,你在文串常量中写的任何反斜线都需要被双写。详见。 + 如果你关掉了,你在字符串常量中写的任何反斜线都需要被双写。详见 @@ -5088,7 +5080,7 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; - 非贪婪的量词(只在 ARE 中可用)匹配对应的正常 (贪婪)模式,区别是它寻找最少的匹配,而不是最多的匹配。详见。 + 非贪婪量词(仅适用于 ARE)与对应的普通(贪婪)量词匹配相同的可能内容,但优先选择最少的匹配次数,而不是最多的匹配次数。详见 @@ -5115,39 +5107,39 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; ^ - 串开头的匹配 + 在字符串开头匹配 $ - 串末尾的匹配 + 在字符串末尾匹配 (?=re) - 在某个位置上,如果从该位置开始的子串能够匹配re,则匹配正向先行断言(仅对 ARE) + 正向先行断言在这样的位置匹配:存在从该位置开始且匹配re的子字符串(仅适用于 ARE) (?!re) - 在某个位置上,如果从该位置开始的子串不能匹配re,则匹配负向先行断言(仅对 ARE) + 负向先行断言在这样的位置匹配:不存在任何从该位置开始且匹配re的子字符串(仅适用于 ARE) (?<=re) - 在某个位置上,如果以该位置结束的某个子串能够匹配re,则匹配正向后行断言(仅对 ARE) + 正向后行断言在这样的位置匹配:存在以该位置结束且匹配re的子字符串(仅适用于 ARE) (?<!re) - 在某个位置上,如果以该位置结束的任何子串都不能匹配re,则匹配负向后行断言(仅对 ARE) + 负向后行断言在这样的位置匹配:不存在任何以该位置结束且匹配re的子字符串(仅适用于 ARE)
- Lookahead 和 lookbehind 约束不能包含反向引用 (参阅),并且其中的所有圆括号 都被认为是非捕获的。 + 先行和后行约束不能包含反向引用(参见),其中的所有圆括号都视为非捕获圆括号。 @@ -5155,11 +5147,11 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; 方括号表达式 - 方括号表达式是一个包围在[]中的字符列表。它通常匹配列表中的任意单个字符(但见下文)。 如果列表以^开头,它匹配任意单个在该列表参与部分中的字符。如果该列表中两个字符用-隔开, 那它就是那两个字符(包括在内)之间的所有字符范围的缩写,例如,在ASCII[0-9]匹配任何十进制数字。两个范围共享一个端点是非法的,例如,a-c-e。范围与字符集关系密切, 可移植的程序应该避免依靠它们。 + 方括号表达式是用[]括起来的字符列表。通常,它匹配列表中的任意单个字符(但请参见下文)。如果列表以^开头,则匹配任意在列表剩余部分中的单个字符。如果列表中的两个字符用-分隔,则表示排序序列中这两个字符之间的完整字符范围(包含两个端点);例如,ASCII中的[0-9]匹配任意十进制数字。两个范围共享一个端点是不合法的,例如a-c-e。范围高度依赖排序序列,因此可移植程序应避免依赖它们。 - 想在列表中包含文本],可以让它做列表的首字符(如果使用了^,需要放在其后)。 想在列表中包含文本-,可以让它做列表的首字符或者尾字符,或者一个范围的第二个端点。 想在列表中把文本-当做范围的起点, 把它用[..]包围起来,这样它就成为一个排序元素(见下文)。 除了这些字符本身、一些用[的组合(见下段)以及转义(只在 ARE 中有效)以外,所有其它特殊字符 在方括号表达式里都失去它们的特殊含义。特别是,在 ERE 和 BRE 规则下\不是特殊的, 但在 ARE 里,它是特殊的(引入一个转义)。 + 想在列表中包含字面字符],可以让它做列表的首字符(如果使用了^,需要放在其后)。 想在列表中包含字面字符-,可以让它做列表的首字符或者尾字符,或者一个范围的第二个端点。 想在列表中把字面字符-当做范围的起点, 把它用[..]包围起来,这样它就成为一个排序元素(见下文)。 除了这些字符本身、一些用[的组合(见下段)以及转义(只在 ARE 中有效)以外,所有其它特殊字符 在方括号表达式里都失去它们的特殊含义。特别是,在 ERE 和 BRE 规则下\不是特殊的, 但在 ARE 里,它是特殊的(引入一个转义)。 @@ -5174,30 +5166,11 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; - 在方括号表达式里,包围在[==]里的排序元素是一个等价类, 代表等效于那一个的所有排序元素的字符序列,包括它本身(如果没有其它等效排序元素,那么就好象封装定界符是[..])。例如,如果o^是一个等价类的成员,那么[[=o=]][[=^=]][o^]都是同义的。一个等价类不能是一个范围的端点。 + 在方括号表达式里,包围在[==]里的排序元素是一个等价类, 代表等效于那一个的所有排序元素的字符序列,包括它本身(如果没有其它等效排序元素,那么就好像封装定界符是[..])。例如,如果o^是一个等价类的成员,那么[[=o=]][[=^=]][o^]都是同义的。一个等价类不能是一个范围的端点。 - 在方括号表达式里,在[::]里面封装的字符类的名字代表属于该类的所有字符的列表。 - 字符类不能作为范围的端点使用。 - POSIX标准定义了这些字符类的名称: - alnum (字母和数字), - alpha (字母), - blank (空格和制表符tab), - cntrl (控制符), - digit (数字), - graph (空格除外可打印字符), - lower (小写字母), - print (包含空格可打印字符), - punct (标点符号), - space (空白), - upper (大写字母), - 和 xdigit (十六进制数). - 对于7位ASCII字符集中的字符来说,这些标准字符类的行为在不同平台上一般是一致的。 - 一个给定的非 ASCII 字符是否被认为属于这些类别中的一个,取决于正则表达式函数或操作符所使用的排序规则(见),或者在默认情况下取决于数据库的LC_CTYPE locale 设置(见)。 - 非ASCII字符的分类在不同的平台上会有不同的分类,即使是在类似命名的locale中也是如此。 - (但C locale从不认为任何非ASCII字符属于上述任何一类)。 - 除了这些标准字符类之外,PostgreSQL定义了ascii字符类,它完全包含7位ASCII字符集。 + 在方括号表达式中,用[::]括起来的字符类名称表示属于该类的所有字符。字符类不能作为范围的端点。POSIX标准定义了以下字符类名称:alnum(字母和数字)、alpha(字母)、blank(空格和制表符)、cntrl(控制字符)、digit(数字)、graph(空格以外的可打印字符)、lower(小写字母)、print(包括空格的可打印字符)、punct(标点符号)、space(任意空白字符)、upper(大写字母)和xdigit(十六进制数字)。对于 7 位 ASCII 字符集中的字符,这些标准字符类在各平台上的行为通常一致。给定的非 ASCII 字符是否属于其中某个类,取决于正则表达式函数或操作符使用的排序规则(参见),默认则取决于数据库的LC_CTYPE区域设置(参见)。即使区域设置名称相似,非 ASCII 字符的分类也可能因平台而异。(但C区域设置不会将任何非 ASCII 字符归入这些类。)除了这些标准字符类,PostgreSQL还定义了恰好包含 7 位 ASCII 字符集的ascii字符类。 @@ -5213,11 +5186,11 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; 正则表达式转义 - 转义是以\开头,后面跟着一个字母数字字符的特殊序列。 转义有好几种变体:字符输入转义、字符类简写转义、约束转义以及反向引用。在 ARE 里, 如果一个\后面跟着一个字母数字,但是并未组成一个合法的转义, 那么它是非法的。在 ERE 中没有转义:在方括号表达式之外,一个后面跟着字母数字字符的\只是表示该字符是一个普通的字符,而且在一个方括号表达式里,\是一个普通的字符(后者实际上在 ERE 和 ARE 不兼容)。 + 转义是以\开头,后面跟着一个字母或数字字符的特殊序列。 转义有好几种变体:字符输入转义、字符类简写转义、约束转义以及反向引用。在 ARE 里, 如果一个\后面跟着一个字母或数字,但是并未组成一个合法的转义, 那么它是非法的。在 ERE 中没有转义:在方括号表达式之外,一个后面跟着字母或数字字符的\只是表示该字符是一个普通的字符,而且在一个方括号表达式里,\是一个普通的字符(后者是 ERE 与 ARE 之间唯一的实际不兼容之处)。 - 字符输入转义用于便于我们在 RE 中声明那些不可打印的或其他习惯的字符。它们显示在中。 + 字符输入转义便于在 RE 中指定不可打印或其他不便输入的字符,见 @@ -5225,13 +5198,13 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; - 约束转义是一个约束,如果满足特定的条件,它匹配该空串。它们显示在中。 + 约束转义是以转义形式书写的约束,在满足特定条件时匹配空字符串,见 反向引用\n)匹配数字n指定的被前面的圆括号子表达式匹配的同一个串 (参阅)。 例如, ([bc])\1匹配bb或者cc, 但是不匹配bc或者cb。 - RE 中子表达式必须完全在反向引用前面。子表达式以它们的先导圆括号的顺序编号。 + RE 中子表达式必须完全在反向引用前面。子表达式以它们的左圆括号的顺序编号。 非捕获圆括号并不定义子表达式。 @@ -5271,7 +5244,7 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; \e - 排序序列名为ESC的字符,如果无法做到该字符为八进制值 033 + 排序序列名称为ESC的字符;若不存在这样的字符,则使用八进制值为033的字符 @@ -5281,7 +5254,7 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; \n - 新行,和 C 中一样 + 换行符,与 C 中相同 @@ -5435,7 +5408,7 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; \Y - 只在一个词的不是开头或末尾的点上匹配 + 只在不属于单词开头或末尾的位置匹配 @@ -5447,7 +5420,7 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo;
- 一个词被定义成在上面[[:<:]][[:>:]]中的声明。在方括号表达式里,约束转义是非法的。 + 单词的定义与上文[[:<:]][[:>:]]的说明相同。方括号表达式中不允许使用约束转义。 @@ -5467,12 +5440,12 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; \m - (其中m是一个非零位)一个到第m个子表达式的反向引用 + (其中m是一个非零数字)一个到第m个子表达式的反向引用 \mnn - (其中m是一个非零位,并且nn是一些更多的位,并且十六进制值mnn不超过目前能看到的封闭捕获圆括号的数目)一个到第mnn个子表达式的反向引用 + (其中m是一个非零数字,并且nn是后续的若干数字,并且十进制值mnn不大于此前已出现的捕获右圆括号数)一个到第mnn个子表达式的反向引用 @@ -5481,7 +5454,7 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; - 在八进制字符输入转义和反向引用之间有一个历史继承的歧义存在,这个歧义是 通过下面的启发式规则解决的,像上面描述地那样。前导零总是表示这是一个八进制转义。 而单个非零数字,如果没有跟着任何其它位,那么总是被认为反向引用。 一个多位的非零开头的序列也被认为是反向引用,只要它出现在合适的子表达式后面 (也就是说,在反向引用的合法范围中的数),否则就被认为是一个八进制。 + 八进制字符输入转义与反向引用之间存在固有歧义,按上文提到的启发式规则解决:前导零始终表示八进制转义。单个非零数字,如果后面没有其他数字,始终视为反向引用。不以零开头的多位数字序列,如果前面已有相应的子表达式(即该数字在反向引用的合法范围内),则视为反向引用,否则视为八进制转义。 @@ -5494,15 +5467,11 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; - RE 可以以两种特殊的引导前缀之一开头。 - 如果 RE 以***:开头,余下部分就被视为 ARE。 - (这在PostgreSQL中通常没有影响,因为 RE 默认被视为 ARE; - 但如果通过正则表达式函数的flags参数指定了 ERE 或 BRE 模式,它就会产生影响。) - 如果 RE 以***=开头,余下部分就被视为字面字符串,所有字符都被视为普通字符。 + RE 可以以两种特殊的引导前缀之一开头。如果 RE 以***:开头,余下部分就被视为 ARE。(这在PostgreSQL中通常没有影响,因为 RE 默认被视为 ARE;但如果通过正则表达式函数的flags参数指定了 ERE 或 BRE 模式,它就会产生影响。)如果 RE 以***=开头,余下部分就作为按字面解释的字符串处理,所有字符都视为普通字符。 - 一个 ARE 可以以嵌入选项开头:一个序列(?xyz)(这里的xyz是一个或多个字母字符)声明影响剩余 RE 的选项。 这些选项覆盖任何前面判断的选项 — 特别地,它们可以覆盖一个正则表达式操作符隐含的大小写敏感的行为,或者覆盖flags参数中的正则表达式函数。可用的选项字母在中显示。注意这些同样的选项字母也被用在正则表达式函数的flags参数中。 + 一个 ARE 可以以嵌入选项开头:一个序列(?xyz)(这里的xyz是一个或多个字母字符)声明影响剩余 RE 的选项。 这些选项覆盖任何先前确定的选项 — 特别地,它们可以覆盖一个正则表达式操作符隐含的大小写敏感的行为,或者覆盖正则表达式函数的flags参数所指定的选项。可用的选项字母在中显示。注意这些同样的选项字母也被用在正则表达式函数的flags参数中。
@@ -5547,32 +5516,32 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; n - 新行敏感的匹配(见 + 换行敏感的匹配(见 p - 部分新行敏感的匹配(见 + 部分换行敏感的匹配(见 q - RE的剩余部分是一个文字(quoted)串,全部是普通字符 + RE 的剩余部分按字面(加引号)解释,所有字符都视为普通字符 s - 非新行敏感的匹配(默认) + 非换行敏感的匹配(默认) t - 紧语法(默认,见下文) + 紧凑语法(默认;见下文) w - 逆部分新行敏感(怪异)的匹配(见 + 逆部分换行敏感(怪异)的匹配(见 @@ -5584,10 +5553,13 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo;
- 嵌入选项在)终止序列时发生作用。它们只在 ARE 的开始处起作用 (在任何可能存在的***:控制器后面)。 + 嵌入选项从结束该序列的)处开始生效。它们只能出现在 ARE 的开头(如果存在***:引导前缀,则位于该前缀之后)。 - 除了通常的()RE 语法(其中所有字符都有意义)之外,还有一种扩展语法,可以通过指定嵌入的x选项来使用。在扩展语法中,RE 中的空白字符会被忽略,同样被忽略的还有#与其后的换行符(或 RE 末尾)之间的所有字符。这使得复杂的 RE 可以分段并添加注释。此基本规则有三个例外: + + 除了通常的紧凑 RE 语法(其中所有字符都有意义)之外,还有一种扩展语法,可以通过指定嵌入的x选项来使用。在扩展语法中,RE 中的空白字符会被忽略,同样被忽略的还有#与其后的换行符(或 RE 末尾)之间的所有字符。这使得复杂的 RE 可以分段并添加注释。此基本规则有三个例外: + + 空白字符或 # 的前面若有 \,该字符就会被保留。 @@ -5601,13 +5573,16 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; 在多字符符号里面不能出现空白和注释,例如(?: - 在这里,空白字符包括空格、制表符、换行符,以及属于space字符类的任何字符。 + + + 在这里,空白字符包括空格、制表符、换行符,以及属于space字符类的任何字符。 +
- 最后,在 ARE 里,方括号表达式外面,序列(?#ttt)(其中ttt是任意不包含一个))的文本)是一个注释, 它被完全忽略。同样,这样的东西是不允许出现在多字符符号的字符中间的,例如 (?:。这种注释更像是一种历史产物而不是一种有用的设施,并且它们的使用已经被废弃;请使用扩展语法来替代。 + 最后,在 ARE 里,方括号表达式外面,序列(?#ttt)(其中ttt是任意不包含一个)的文本)是一个注释, 它被完全忽略。同样,这样的东西是不允许出现在多字符符号的字符中间的,例如 (?:。这种注释更像是一种历史产物而不是一种有用的设施,并且它们的使用已经被废弃;请使用扩展语法来替代。
- 如果声明了一个初始的***=控制器,那么所有这些元语法扩展都不能使用,因为这样表示把用户输入当作一个文字串而不是 RE 对待。 + 如果指定了开头的***=引导前缀,那么这些元语法扩展都不能使用,因为这表示把用户输入作为按字面解释的字符串,而非 RE 处理。 @@ -5623,7 +5598,7 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; - 大多数原子以及所有约束,都没有贪婪属性(因为它们毕竟无法匹配个数变化的文本)。 + 大多数原子以及所有约束,都没有贪婪属性(因为它们毕竟无法匹配长度不定的文本)。 @@ -5675,7 +5650,7 @@ SELECT SUBSTRING('XY1234Z', 'Y*?([0-9]{1,3})'); - 简而言之,如果一个 RE 同时包含贪婪和非贪婪的子表达式,那么总的匹配长度要么是尽可能长,要么是尽可能短,这取决于给整个 RE 赋予的属性。给子表达式赋予的属性只影响在这个匹配里,各个子表达式之间相互允许吃掉的多少。 + 简而言之,如果一个 RE 同时包含贪婪和非贪婪的子表达式,那么总的匹配长度要么是尽可能长,要么是尽可能短,这取决于给整个 RE 赋予的属性。给子表达式赋予的属性只影响在这个匹配里,各个子表达式相对于其他子表达式能吃掉多少内容。 @@ -5709,19 +5684,19 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 如果声明了大小写无关的匹配,那么效果就好像所有大小写区别在字母表中消失了。如果在多个情况中一个字母以一个普通字符的形式出现在方括号表达式外面,那么它实际上被转换成 一个包含大小写的方括号表达式,也就是说,x 变成 [xX]。 如果它出现在一个方括号表达式里面,那么它的所有大小写的同族都被加入 方括号表达式中,也就是说,x变成[xX]。当它出现在一个方括号表达式内时,它的所有大小写副本都被加入到方括号表达式中,例如, [x]会变成[xX],而[^x]会变成[^xX]。 + 如果指定不区分大小写的匹配,其效果近似于字母表中的所有大小写差别都消失了。当存在大小写形式的字母作为普通字符出现在方括号表达式之外时,实际上会转换为包含其大小写形式的方括号表达式,例如x变成[xX]。当它出现在方括号表达式内部时,其所有大小写形式都会加入该表达式,例如[x]变成[xX][^x]变成[^xX] - 如果指定了换行敏感的匹配,.和使用^的方括号表达式 将永远不会匹配换行字符(这样,匹配就不会跨越行,除非 RE 显式地包含了换行)并且^$除了分别匹配串开头和结尾之外,还将分别匹配换行后面和前面的空串。 + 如果指定了换行敏感的匹配,.和使用^的方括号表达式 将永远不会匹配换行字符(这样,匹配就不会跨越行,除非 RE 显式安排了跨行匹配)并且^$除了分别匹配串开头和结尾之外,还将分别匹配换行后面和前面的空串。 但是 ARE 转义\A\Z仍然匹配串的开头和结尾。 - 如果指定了部分新行敏感的匹配,那么它影响.和方括号表达式, 这个时候和新行敏感的匹配一样,但是不影响^$。 + 如果指定了部分换行敏感的匹配,那么它影响.和方括号表达式, 这个时候和换行敏感的匹配一样,但是不影响^$ - 如果指定了逆新行敏感匹配,那么它影响^$,其作用和在新行敏感的匹配里一样,但是不影响.和方括号表达式。这个并不是很有用,只是为了满足对称性而提供的。 + 如果指定了逆部分换行敏感匹配,那么它影响^$,其作用和在换行敏感的匹配里一样,但是不影响.和方括号表达式。这个并不是很有用,只是为了满足对称性而提供的。 @@ -5733,11 +5708,11 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - ARE 实际上和 POSIX ERE 不兼容的唯一的特性是在方括号表达式里\并不失去它特殊的含义。所有其它 ARE 特性都使用在 POSIX ERE 里面是非法或者是未定义、未声明效果的语法;指示器的***就是在 POSIX 的 BRE 和 ERE 之外的语法。 + ARE 与 POSIX ERE 实际不兼容的唯一特性是:\在方括号表达式中不会失去特殊含义。其他所有 ARE 特性所使用的语法,在 POSIX ERE 中都是非法的,或其效果未定义或未指定;引导前缀的***语法同样不属于 POSIX 的 BRE 或 ERE 语法。 - 许多 ARE 扩展都是从 Perl 那里借来的(但是有些被做了修改来清理它们),以及一些 Perl 里没有出现的扩展。要注意的不兼容性包括\b\B、对结尾的新行缺乏特别的处理、对那些被新行敏感匹配的东西附加的补齐方括号表达式、在 lookahead/lookbehind 约束里对圆括号和反向引用的限制以及最长/最短 匹配(而不是第一匹配)的语义。 + 许多 ARE 扩展借鉴自 Perl,但其中一些经过了整理和修改,也未实现少数 Perl 扩展。需要注意的不兼容之处包括\b\B、不对末尾换行符作特殊处理、取反的方括号表达式也受换行敏感匹配影响、先行和后行约束中对圆括号及反向引用的限制,以及采用最长或最短匹配而非首次匹配的语义。 ARE 与旧版 ERE 语法存在两点重要的不兼容,这里比较的是 7.4 之前的PostgreSQL: @@ -5758,7 +5733,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 基本正则表达式 - BREs 在几个方面和 ERE 不太一样。在 BRE 中,|+?都是普通字符并且没有与它们功能等价的东西。范围的定界符是\{\}, 因为 {}本身是普通字符。嵌套的子表达式的圆括号是\(\),因为()自身是普通字符。除非在 RE 开头或者是圆括号子表达式开头,^都是一个普通字符。 除非在 RE 结尾或者是圆括号子表达式的结尾,$是一个普通字符。如果*出现在 RE 开头或者是圆括号封装的子表达式开头 (前面可能有^),那么它是个普通字符。最后,可以用单数字的反向引用,\<\>分别是[[:<:]][[:>:]]的同义词;在 BRE 中没有其它可用的转义。 + BRE 在几个方面和 ERE 不太一样。在 BRE 中,|+?都是普通字符并且没有与它们功能等价的东西。范围的定界符是\{\},而{}本身是普通字符。嵌套的子表达式的圆括号是\(\),而()自身是普通字符。除非在 RE 开头或者是圆括号子表达式开头,^都是一个普通字符。 除非在 RE 结尾或者是圆括号子表达式的结尾,$是一个普通字符。如果*出现在 RE 开头或者是圆括号封装的子表达式开头 (前面可能有^),那么它是个普通字符。最后,可以用单数字的反向引用,\<\>分别是[[:<:]][[:>:]]的同义词;在 BRE 中没有其它可用的转义。 @@ -5788,15 +5763,12 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 使用\p{UnicodeProperty}或其反义\P{UnicodeProperty}来定义XQuery字符类元素是不被支持的。 + 使用\p{UnicodeProperty}或其取反形式\P{UnicodeProperty}来定义XQuery字符类元素是不被支持的。 - POSIX解释字符类,如\w - (参见) - 根据当前区域设置(你可以通过将COLLATE子句附加到操作符或函数上来控制)。 - XQuery通过参考Unicode字符属性来指定这些类别,因此只有遵循Unicode规则的区域设置才能获得等效行为。 + POSIX 根据当前区域设置解释\w等字符类(参见);你可以通过为操作符或函数附加COLLATE子句来控制该区域设置。XQuery 根据 Unicode 字符属性定义这些类,因此只有使用遵循 Unicode 规则的区域设置时,才能得到等效行为。 @@ -5815,7 +5787,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - XQuery没有前瞻或后顾约束,也没有在中描述的任何约束转义。 + XQuery没有先行或后行约束,也没有在中描述的任何约束转义。 @@ -5829,7 +5801,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); XQuery的s(允许点匹配换行符) 和m(允许^ - 和$匹配换行符)标志提供 + 和$在换行处匹配)标志提供 与POSIX的npw标志相同的行为,但它们 匹配POSIX的sm标志的行为。 @@ -5860,11 +5832,11 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 数据类型格式化函数 - formatting + 格式化 - PostgreSQL格式化函数提供一套强大的工具用于把各种数据类型 (日期/时间、整数、浮点、数字) 转换成格式化的字符串以及反过来从格式化的字符串转换成 指定的数据类型。列出了这些函数。这些函数都遵循一个公共的调用规范: 第一个参数是待格式化的值,而第二个是一个定义输出或输入格式的模板。 + PostgreSQL格式化函数提供一套强大的工具用于把各种数据类型 (日期/时间、整数、浮点数、数值) 转换成格式化的字符串以及反过来从格式化的字符串转换成 指定的数据类型。列出了这些函数。这些函数都遵循一个公共的调用规范: 第一个参数是待格式化的值,而第二个是一个定义输出或输入格式的模板。 @@ -5915,7 +5887,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); text - 根据给定的格式将间隔转换为字符串。 + 根据给定的格式将时间间隔转换为字符串。 to_char(interval '15h 2m 12s', 'HH24:MI:SS') @@ -5971,7 +5943,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); numeric - 根据给定的格式将字符串转换为数字。 + 根据给定的格式将字符串转换为数值。 to_number('12,454.8-', '99G999D9S') @@ -6012,7 +5984,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 展示了可以用于格式化日期和时间值的模版。 + 展示了可以用于格式化日期和时间值的模板模式。
@@ -6095,24 +6067,24 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); SSSS, SSSSS - 午夜后的秒 (0–86399) + 自午夜起的秒数 (0–86399) AM, am, - PM or pm - 正午指示器(不带句号) + PMpm + 上午/下午标记(不带句点) A.M., a.m., - P.M. or p.m. - 正午指示器(带句号) + P.M.p.m. + 上午/下午标记(带句点) Y,YYY - 带逗号的年(4 位或者更多位) with comma + 带逗号的年(4 位或者更多位) @@ -6169,17 +6141,17 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); MONTH - 全大写形式的月名(空格补齐到 9 字符) + 大写的月份全称(空格补齐到 9 字符) Month - 全首字母大写形式的月名(空格补齐到 9 字符) + 首字母大写的月份全称(空格补齐到 9 字符) month - 全小写形式的月名(空格补齐到 9 字符) + 小写的月份全称(空格补齐到 9 字符) @@ -6204,72 +6176,72 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); DAY - 全大写形式的日名(空格补齐到 9 字符) + 大写的星期全称(空格补齐到 9 字符) Day - 全首字母大写形式的日名(空格补齐到 9 字符) + 首字母大写的星期全称(空格补齐到 9 字符) day - 全小写形式的日名(空格补齐到 9 字符) + 小写的星期全称(空格补齐到 9 字符) DY - 简写的大写形式的日名(英语 3 字符,本地化长度可变) + 大写的星期简称(英语 3 字符,本地化长度可变) Dy - 简写的首字母大写形式的日名(英语 3 字符,本地化长度可变) + 首字母大写的星期简称(英语 3 字符,本地化长度可变) dy - 简写的小写形式的日名(英语 3 字符,本地化长度可变) + 小写的星期简称(英语 3 字符,本地化长度可变) DDD - 一年中的日(001–366) + 年内日序数(001–366) IDDD - ISO 8601 周编号方式的年中的日 (001–371; 年的第 1 日时第一个 ISO 周的周一) + ISO 8601 周编号方式的年中的日 (001–371; 年的第 1 日是第一个 ISO 周的周一) DD - 月中的日 (01–31) + 月内日序数 (01–31) D - 周中的日,周日 (1) 到周六 (7) + 星期几,周日 (1) 到周六 (7) ID - 周中的 ISO 8601 日,周一 (1) 到周日 (7) + ISO 8601 星期几,周一 (1) 到周日 (7) W - 月中的周 (1–5) (第一周从该月的第一天开始) + 月内周序数 (1–5) (第一周从该月的第一天开始) WW - 年中的周数 (1–53) (第一周从该年的第一天开始) + 年中的周编号 (1–53) (第一周从该年的第一天开始) IW - ISO 8601 周编号方式的年中的周数 (01–53; 新的一年的第一个周四在第一周) + ISO 8601 周编号方式的年中的周编号 (01–53; 新的一年的第一个周四在第一周) @@ -6319,24 +6291,24 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); OF - 从UTC开始的时区偏移(仅在to_char中支持) + 相对于 UTC 的时区偏移(仅在to_char中支持)
- 修饰语可以被应用于模板模式来修改它们的行为。例如,FMMonth就是带着FM修饰语的Month模式。展示了可用于日期/时间格式化的修饰语模式。 + 修饰符可以被应用于模板模式来修改它们的行为。例如,FMMonth就是带着FM修饰符的Month模式。展示了可用于日期/时间格式化的修饰符模式。 - 用于日期/时间格式化的模板模式修饰语 + 用于日期/时间格式化的模板模式修饰符 - 修饰语 + 修饰符 描述 示例 @@ -6344,37 +6316,37 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - FM prefix + FM 前缀 填充模式(抑制前导零和填充的空格) FMMonth - TH suffix + TH 后缀 大写形式的序数后缀 - DDTH, e.g., 12TH + DDTH,例如, 12TH - th suffix + th 后缀 小写形式的序数后缀 - DDth, e.g., 12th + DDth,例如, 12th - FX prefix - 固定的格式化全局选项(见使用须知) + FX 前缀 + 固定格式全局选项(见使用须知) FX Month DD Day - TM prefix - 翻译模式(基于使用本地化的日和月名) + TM 前缀 + 翻译模式(基于使用本地化的星期名和月份名) TMMonth - SP suffix + SP 后缀 拼写模式(未实现) DDSP @@ -6382,14 +6354,14 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}');
- 日期/时间格式化的使用说明: + 日期/时间格式化的使用注意事项: FM抑制了在模式输出中添加前导零和尾随空格的行为,这些前导零和尾随空格 本来会被添加以使输出成为固定宽度。在PostgreSQL中, - FM仅修改下一个规范,而在Oracle中FM影响所有后续 - 规范,并且重复的FM修饰符切换填充模式的开启和关闭。 + FM仅修改下一个格式说明,而在Oracle中FM影响所有后续 + 格式说明,并且重复的FM修饰符切换填充模式的开启和关闭。 @@ -6447,10 +6419,10 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 一个TZH模板模式可以匹配有符号数。 - 没有FX选项,减号可能会有歧义,并且可能被解释为分隔符。 - 此歧义解决如下:如果模板字符串中TZH之前的分隔符数量少于输入字符串中减号之前的分隔符数量, - 则减号被解释为TZH的一部分。 - 否则,减号被视为值之间的分隔符。 + 没有FX选项,负号可能会有歧义,并且可能被解释为分隔符。 + 此歧义解决如下:如果模板字符串中TZH之前的分隔符数量少于输入字符串中负号之前的分隔符数量, + 则负号被解释为TZH的一部分。 + 否则,负号被视为值之间的分隔符。 例如,to_timestamp('2000 -10', 'YYYY TZH')匹配 -10TZH,但 to_timestamp('2000 -10', 'YYYY  TZH') @@ -6461,12 +6433,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 普通文本允许在to_char模板中,并且将被直接输出。您可以将子字符串放在双引号中, - 以强制将其解释为文字文本,即使它包含模板模式。例如,在'"Hello Year "YYYY'中, - YYYY将被年份数据替换,但Year中的单个Y不会被替换。 - 在to_dateto_numberto_timestamp中, - 文本和双引号字符串会导致跳过字符串中包含的字符数;例如"XX"跳过两个输入字符 - (无论它们是否为XX)。 + 普通文本可以出现在to_char模板中,并会按字面输出。可以用双引号括起子串,使其即使包含模式关键字也强制按字面文本解释。例如,在'"Hello Year "YYYY'中,YYYY会被年份数据替换,但Year中单独的Y不会被替换。在to_dateto_numberto_timestamp中,字面文本和双引号字符串会跳过与该字符串所含字符数相同数量的输入字符;例如,"XX"跳过两个输入字符(无论它们是否为XX)。 @@ -6485,7 +6452,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 如果您想在输出中使用双引号,必须在其前面加上反斜杠,例如'\"YYYY Month\"' - 反斜杠在双引号之外不起特殊作用。在双引号字符串内部,反斜杠会使下一个字符被直接解释,无论是什么(但除非下一个字符是双引号或另一个反斜杠,否则没有特殊效果)。 + 反斜杠在双引号之外不起特殊作用。在双引号字符串内部,反斜杠会使下一个字符被按字面解释,无论是什么(但除非下一个字符是双引号或另一个反斜杠,否则没有特殊效果)。 @@ -6548,14 +6515,14 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 年份、周数和星期几:例如to_date('2006-42-4', 'IYYY-IW-ID') + 年份、周编号和星期几:例如to_date('2006-42-4', 'IYYY-IW-ID') 返回日期2006-10-19。 如果省略星期几,则假定为1(星期一)。 - 年份和年内天数:例如to_date('2006-291', 'IYYY-IDDD')也返回2006-10-19。 + 年份和年内日序数:例如to_date('2006-291', 'IYYY-IDDD')也返回2006-10-19 @@ -6563,14 +6530,14 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 尝试使用ISO 8601周编号字段和公历日期字段的混合输入日期是荒谬的,并将导致错误。 - 在ISO 8601周编号年的背景下,月份日期的概念没有意义。 + 在ISO 8601周编号年的背景下,月份月内日序数的概念没有意义。 在公历年的背景下,ISO周没有意义。 - 当to_date拒绝混合使用公历和ISO周编号日期字段时, - to_char不会,因为输出格式规范如YYYY-MM-DD (IYYY-IDDD)可能很有用。 + 虽然to_date会拒绝混合使用公历和ISO周编号日期字段, + 但to_char不会,因为输出格式规范如YYYY-MM-DD (IYYY-IDDD)可能很有用。 但要避免编写类似IYYY-MM-DD的内容;那会在年初附近产生令人惊讶的结果。 (有关更多信息,请参见。) @@ -6589,7 +6556,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 这是一个更复杂的示例: to_timestamp('15:12:02.020.001230', 'HH24:MI:SS.MS.US') - 是15小时,12分钟和2秒 + 20毫秒 + 1230微秒 = 2.021230秒。 + 为15小时12分钟,秒数为2秒 + 20毫秒 + 1230微秒 = 2.021230秒。
@@ -6597,7 +6564,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); to_char(..., 'ID')的星期几编号与extract(isodow from ...)函数匹配, - 但to_char(..., 'D')的不匹配extract(dow from ...)的星期编号。 + 但to_char(..., 'D')的不匹配extract(dow from ...)的星期几编号。 @@ -6614,12 +6581,12 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 展示了可以用于格式化数字值的模版模式。 + 展示了可以用于格式化数值的模板模式。 - 用于数字格式化的模板模式 + 用于数值格式化的模板模式 @@ -6632,21 +6599,21 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 9 - 数位(如果无意义可以被删除) + 数位(非有效位可以被省略) 0 - 数位(即便没有意义也不会被删除) + 数位(即便是非有效位也不会被省略) - . (period) + .(句点) 小数点 - , (comma) + ,(逗号) 分组(千)分隔符 @@ -6657,22 +6624,22 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); S - 带符号的数字(使用区域) + 紧贴数值的正负号(使用区域设置) L - 货币符号(使用区域) + 货币符号(使用区域设置) D - 小数点(使用区域) + 小数点(使用区域设置) G - 分组分隔符(使用区域) + 分组分隔符(使用区域设置) @@ -6696,7 +6663,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - TH or th + THth 序数后缀 @@ -6713,7 +6680,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}');
- 数值格式化的使用说明: + 数值格式化的使用注意事项: @@ -6727,14 +6694,14 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 如果格式提供的小数位数少于被格式化的数字,则to_char()将会将数字四舍五入到指定的小数位数。 + 如果格式指定的小数位数少于被格式化数值的小数位数,to_char()会将该数值舍入到指定的小数位数。 - 模式字符SLDG表示当前区域设置定义的符号、货币符号、小数点和千位分隔符字符 + 模式字符SLDG表示当前区域设置定义的正负号、货币符号、小数点和千位分隔符字符 (参见)。模式字符句点和逗号表示这些确切字符,具有小数点和千位分隔符的含义,不受区域设置影响。 @@ -6743,15 +6710,14 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 如果在to_char()的模式中没有明确指定符号,将为符号保留一列,并将其锚定到(出现在)数字的左侧。 - 如果S出现在一些9的左侧,它也将锚定到数字。 + 如果to_char()的模式中没有明确指定正负号的位置,就会为正负号保留一列,并使其紧贴数值(紧靠数值左侧)。如果S紧邻若干个9的左侧,它同样会紧贴数值。 - 使用SGPLMI格式化的符号不与数字绑定; + 使用SGPLMI格式化的正负号不紧贴数值; 例如,to_char(-12, 'MI9999')会产生'-  12', 但to_char(-12, 'S9999')会产生'  -12'。 (Oracle实现不允许在9之前使用MI,而是要求9MI之前。) @@ -6778,7 +6744,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); to_number函数中,如果使用非数据模板模式,如LTH, - 则会跳过相应数量的输入字符,无论它们是否与模板模式匹配,除非它们是数据字符(即数字、符号、小数点或逗号)。 + 则会跳过相应数量的输入字符,无论它们是否与模板模式匹配,除非它们是数据字符(即数字、正负号、小数点或逗号)。 例如,TH会跳过两个非数据字符。 @@ -6789,7 +6755,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); Vto_char一起, 将输入值乘以10^n, 其中n是跟在V后面的数字位数。 - Vto_number一起以类似的方式除法。 + Vto_number一起以类似的方式进行除法。 to_charto_number不支持与小数点结合使用的V (例如,不允许使用99.9V99)。 @@ -6805,17 +6771,17 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 某些修饰语可以被应用到任何模板来改变其行为。例如,FM99.99是带有FM修饰语的99.99模式。中展示了用于数字格式化模式修饰语。 + 某些修饰符可以被应用到任何模板来改变其行为。例如,FM99.99是带有FM修饰符的99.99模式。中展示了用于数值格式化的模式修饰符。 - 用于数字格式化的模板模式修饰语 + 用于数值格式化的模板模式修饰符 - 修饰语 + 修饰符 描述 示例 @@ -6823,19 +6789,19 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - FM prefix - 填充模式(抑制拖尾零和填充的空白) + FM 前缀 + 填充模式(抑制尾随零和填充的空白) FM99.99 - TH suffix + TH 后缀 大写序数后缀 999TH - th suffix + th 后缀 小写序数后缀 999th @@ -7019,10 +6985,10 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 时间/日期函数和操作符 + 日期/时间函数和操作符 - 展示了可用于处理日期/时间值的函数,其细节在随后的小节中描述。演示了基本算术操作符 (+*等)的行为。 而与格式化相关的函数,可以参考。你应该很熟悉中的日期/时间数据类型的背景知识。 + 展示了可用于处理日期/时间值的函数,其细节在随后的小节中描述。演示了基本算术操作符 (+*等)的行为。 而与格式化相关的函数,可以参考。你应当熟悉中的日期/时间数据类型的背景知识。 @@ -7106,7 +7072,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); interval - 添加时间间隔 + 将两个时间间隔相加 interval '1 day' + interval '1 hour' @@ -7148,7 +7114,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); interval - 取否一个时间间隔 + 对时间间隔取负 - interval '23 hours' @@ -7162,7 +7128,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); integer - 减去日期,生成经过的天数 + 将两个日期相减,得到相隔的天数 date '2001-10-01' - date '2001-09-28' @@ -7204,7 +7170,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); interval - 减去时间 + 将两个时间相减 time '05:00' - time '03:00' @@ -7246,7 +7212,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); interval - 减去时间间隔 + 将两个时间间隔相减 interval '1 day' - interval '1 hour' @@ -7260,7 +7226,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); interval - 减去时间戳(将24小时间隔转换为天数,类似于justify_hours() @@ -7275,7 +7241,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); interval - 将时间间隔乘以数量 + 将时间间隔乘以一个标量 interval '1 second' * 900 @@ -7297,7 +7263,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); interval - 用时间间隔除以数量 + 将时间间隔除以一个标量 interval '1 hour' / 1.5 @@ -7336,7 +7302,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); interval - 减去参数,生成一个使用年和月,而不是只用日的符号化的结果 + 将两个参数相减,生成一个使用年和月,而不是只用日的符号化的结果 age(timestamp '2001-04-10', timestamp '1957-06-13') @@ -7350,7 +7316,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); interval - 从 current_date 减去参数(在午夜) + 从current_date(午夜时刻)减去参数 age(timestamp '1957-06-13') @@ -7413,7 +7379,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); time with time zone - 一天中的当前时间;有限精度;参见 + 一天中的当前时刻,精度受限;参见 current_time(2) @@ -7442,7 +7408,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); timestamp with time zone - 当前日期和时间 (当前事务的开始);有限精度;参见 + 当前日期和时间(当前事务开始时),精度受限;参见 current_timestamp(0) @@ -7459,7 +7425,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); double precision - 获取时间戳字段 (等同于 extract);参见 + 获取时间戳子字段 (等同于 extract);参见 date_part('hour', timestamp '2001-02-16 20:38:40') @@ -7566,7 +7532,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); boolean - 测试有限日期(不是+/-无限) + 测试日期是否有限(不是正负无穷) isfinite(date '2001-02-16') @@ -7580,7 +7546,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); boolean - 测试有限时间戳(不是+/-无限) + 测试时间戳是否有限(不是正负无穷) isfinite(timestamp 'infinity') @@ -7647,7 +7613,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); interval - 使用 justify_daysjustify_hours调整时间间隔; 通过额外的符号调整 + 使用 justify_daysjustify_hours调整时间间隔,并额外调整符号 justify_interval(interval '1 mon -1 hour') @@ -7676,7 +7642,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); time - 一天中的当前时间,有限精度;参见 + 一天中的当前时刻,精度受限;参见 localtime(0) @@ -7705,7 +7671,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); timestamp - 当前日期和时间(当前事务的开始);有限精度;参见 + 当前日期和时间(当前事务开始时),精度受限;参见 localtimestamp(2) @@ -7841,7 +7807,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); timestamp with time zone - 当前日期和时间(当前语句的开始);参见 + 当前日期和时间(当前语句开始时);参见 statement_timestamp() @@ -7891,7 +7857,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); timestamp with time zone - 将Unix纪元转换为带时区的时间戳(从1970-01-01 00:00:00+00开始的秒) + 将 Unix 纪元时间(自 1970-01-01 00:00:00+00 起的秒数)转换为带时区的时间戳 to_timestamp(1284352323) @@ -7911,7 +7877,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); (start1, end1) OVERLAPS (start2, end2) (start1, length1) OVERLAPS (start2, length2) - 这个表达式在两个时间域(用它们的端点定义)重叠的时候得到真,当它们不重叠时得到假。端点可以用一对日期、时间或者时间戳来指定;或者是用一个后面跟着一个间隔的日期、时间或时间戳来指定。当一对值被提供时,起点或终点都可以被写在前面,OVERLAPS会自动地把较早的值作为起点。每一个时间段被认为是表示半开的间隔start <= time < end,除非startend相等,这种情况下它表示单个时间实例。例如这表示两个只有一个共同端点的时间段不重叠。 + 这个表达式在两个时间段(用它们的端点定义)重叠的时候得到真,当它们不重叠时得到假。端点可以用一对日期、时间或者时间戳来指定;或者是用一个后面跟着一个间隔的日期、时间或时间戳来指定。当一对值被提供时,起点或终点都可以被写在前面,OVERLAPS会自动地把较早的值作为起点。每一个时间段被认为是表示半开区间start <= time < end,除非startend相等,这种情况下它表示单个时刻。例如这表示两个只有一个共同端点的时间段不重叠。 @@ -7943,15 +7909,9 @@ SELECT timestamp with time zone '2005-04-02 12:00:00-07' + interval '24 hours'; - 日期和时间戳的减法也可能会很复杂。执行减法的一种概念上很简单的方法是,使用 - EXTRACT(EPOCH FROM ...)把每个值都转换成秒数,然后执行减法, - 这样会得到两个值之间的数。这种方法将会适应每个月中天数、 - 时区改变和夏令时调整。使用-操作符的日期或时间 - 戳减法会返回值之间的天数(24小时)以及时/分/秒,也会做同样的调整。 - age函数会返回年、月、日以及时/分/秒,执行按域的减法,然后对 - 负值域进行调整。下面的查询展示了这些方法的不同。示例中的结果由 - timezone = 'US/Eastern'产生,这使得两个使用的日期之间存在着夏令 - 时的变化: + 日期和时间戳的减法也可能很复杂。一种概念上简单的方法是,先用EXTRACT(EPOCH FROM ...)将各值转换为秒数,然后将结果相减;这样得到的是两个值之间的数。这种方法会针对每个月的天数、时区变化和夏令时变化进行调整。 + 用-操作符将日期或时间戳值相减,会返回两个值之间的天数(每一天为 24 小时)和时/分/秒,也会作相同的调整。age函数返回年、月、日和时/分/秒,它会逐字段相减,然后调整负值字段。 + 以下查询显示了这些方法的差异。示例结果在timezone = 'US/Eastern'设置下产生;所用的两个日期之间发生了夏令时切换: @@ -7997,7 +7957,7 @@ EXTRACT(field FROM source) - 这个世纪;对于interval值,年份字段除以100 + 世纪;对于interval值,年份字段除以100 @@ -8020,7 +7980,7 @@ SELECT EXTRACT(CENTURY FROM INTERVAL '2001 years'); - 月份的日期(1–31);对于interval值,表示天数 + 一个月中的第几天(1–31);对于interval值,表示天数 @@ -8073,7 +8033,7 @@ SELECT EXTRACT(DOW FROM TIMESTAMP '2001-02-16 20:38:40'); - 一年中的日子(1-365/366) + 一年中的第几天(1–365/366) @@ -8087,7 +8047,7 @@ SELECT EXTRACT(DOY FROM TIMESTAMP '2001-02-16 20:38:40'); epoch - 对于timestamp with time zone值,自1970-01-01 00:00:00 UTC以来的秒数(负值表示该时间戳之前的时间); + 对于timestamp with time zone值,自1970-01-01 00:00:00 UTC以来的秒数(早于该时刻的时间戳对应负值); 对于datetimestamp值,自1970-01-01 00:00:00以来的名义秒数,不考虑时区或夏令时规则; 对于interval值,间隔中的总秒数 @@ -8110,8 +8070,8 @@ SELECT to_timestamp(982384720.12); - 注意,将to_timestamp应用于从datetimestamp值中提取的时代可能会产生误导性的结果: - 结果将有效地假定原始值是以UTC时间给出的,这可能并非事实。 + 注意,将to_timestamp应用于从datetimestamp值中提取的 epoch 值可能会产生误导性的结果: + 结果实际上会假定原始值是以UTC时间给出的,这可能并非事实。 @@ -8205,7 +8165,7 @@ SELECT EXTRACT(MICROSECONDS FROM TIME '17:12:28.5'); millennium - 千年; 对于interval值,年份字段除以1000 + 千年; 对于interval值,年份字段除以1000 @@ -8223,7 +8183,7 @@ SELECT EXTRACT(MILLENNIUM FROM INTERVAL '2001 years'); milliseconds - 第二个字段,包括小数部分,乘以1000。请注意,这包括完整的秒数。 + 秒字段,包括小数部分,乘以1000。请注意,这包括完整的秒数。 @@ -8253,7 +8213,7 @@ SELECT EXTRACT(MINUTE FROM TIMESTAMP '2001-02-16 20:38:40'); - 月份在一年中的编号(1-12);对于interval值,月份模12的余数(0-11) + 月份在一年中的编号(1–12);对于interval值,月份模12的余数(0–11) @@ -8272,7 +8232,7 @@ SELECT EXTRACT(MONTH FROM INTERVAL '2 years 13 months'); - 日期所在的年份季度(1-4) + 日期所在的年份季度(1–4) @@ -8313,7 +8273,7 @@ SELECT EXTRACT(SECOND FROM TIME '17:12:28.5'); - 时间区偏移的小时组件 + 时区偏移的小时部分 @@ -8323,7 +8283,7 @@ SELECT EXTRACT(SECOND FROM TIME '17:12:28.5'); - 时间区偏移的分钟组件 + 时区偏移的分钟部分 @@ -8333,16 +8293,11 @@ SELECT EXTRACT(SECOND FROM TIME '17:12:28.5'); - 一年中ISO 8601周编号周的数量。根据定义,ISO周从周一开始, - 一年的第一周包含该年的1月4日。换句话说,一年的第一个星期四在该年的第1周。 + 一年中按ISO 8601 周编号体系计算的周序号。根据定义,ISO 周从周一开始,一年的第一周包含该年的 1 月 4 日。换句话说,一年的第一个星期四在该年的第 1 周。 - 在ISO周编号系统中,早年1月的日期可能属于前一年的第52周或第53周,而 - 晚年12月的日期可能属于下一年的第一周。例如,2005-01-01 - 属于2004年的第53周,2006-01-01 属于2005年的第52周, - 而2012-12-31 属于2013年的第一周。建议同时使用 - isoyear 字段和week以获得一致的结果。 + 在 ISO 周编号体系中,1 月初的日期可能属于前一年的第 52 周或第 53 周,而 12 月末的日期可能属于下一年的第一周。例如,2005-01-01属于 2004 年的第 53 周,2006-01-01属于 2005 年的第 52 周,而2012-12-31属于 2013 年的第一周。建议将isoyear字段与week一起使用,以获得一致的结果。 @@ -8357,7 +8312,7 @@ SELECT EXTRACT(WEEK FROM TIMESTAMP '2001-02-16 20:38:40'); - 年份字段。请记住,没有0 AD,所以要小心地从AD年中减去BC年。 + 年份字段。请记住,没有0 AD,所以把BC年份从AD年份中减去时需要小心。 @@ -8384,7 +8339,7 @@ SELECT EXTRACT(MINUTES FROM INTERVAL '80 minutes'); - 当输入值为 +/-Infinity 时,extract对于单调增的域(epochjulianyearisoyeardecadecentury以及millennium)返回 +/-Infinity。对于其他域返回 NULL。PostgreSQL 9.6 之前的版本对所有输入无穷的情况都返回零。 + 当输入值为 +/-Infinity 时,extract对于单调递增的字段(epochjulianyearisoyeardecadecentury以及millennium)返回 +/-Infinity。对于其他字段返回 NULL。PostgreSQL 9.6 之前的版本对所有输入无穷的情况都返回零。 @@ -8392,10 +8347,11 @@ SELECT EXTRACT(MINUTES FROM INTERVAL '80 minutes'); extract函数主要的用途是做计算性处理。对于用于显示的日期/时间值格式化,参阅。 - date_part函数仿照传统的Ingres实现,后者等价于SQL标准函数extract: + date_part函数仿照传统的Ingres实现,后者对应SQL标准的extract函数: date_part('field', source) -注意,此处的field参数必须是字符串值,而不能是名称。函数date_part的有效字段名与以下函数相同:extract。 + + 注意,此处的field参数必须是字符串值,而不能是名称。date_part的有效字段名与extract相同。 @@ -8422,10 +8378,11 @@ SELECT date_part('hour', INTERVAL '4 hours 3 minutes'); date_trunc(field, source [, time_zone ]) - sourcetimestamptimestamp with time zone,或interval类型的值表达式。(类型为datetime的值会自动转换为timestampinterval,分别对应这两种输入类型。)field选择输入值的截断精度。返回值同样为以下类型:timestamptimestamp with time zone,或interval,其中所有小于所选精度的字段都设为零(日期和月份则设为一)。 + sourcetimestamptimestamp with time zoneinterval类型的值表达式。(datetime类型的值会分别自动转换为timestampinterval。) + field选择输入值的截断精度。返回值同样为timestamptimestamp with time zoneinterval类型,其中低于所选精度的所有字段都设为零(日和月则设为一)。 - field的有效值是∶ + field的有效值是: microseconds milliseconds @@ -8444,7 +8401,7 @@ date_trunc(field, source [ - 当输入值的类型为timestamp with time zone时。截断是针对特定时区进行的。 例如,截断为day,产生的值是 是该区域的午夜。 默认情况下,截断是在以下方面进行的 到当前的设置,但在当前的 可以提供可选的time_zone参数。以指定不同的时区。 可以指定时区名称 中描述的任何一种方式。 + 当输入值为timestamp with time zone类型时,截断会以特定时区为准;例如,截断到day会得到该时区的午夜。默认情况下,截断以当前的设置为准,但可以通过可选的time_zone参数指定其他时区。时区名称可以用中描述的任意方式指定。 @@ -8471,8 +8428,8 @@ SELECT date_trunc('hour', INTERVAL '3 days 02:47:33'); <literal>AT TIME ZONE</literal> - time zone - conversion + 时区 + 转换 @@ -8480,7 +8437,7 @@ SELECT date_trunc('hour', INTERVAL '3 days 02:47:33'); - AT TIME ZONE 操作符可在带时区和不带时区的时间戳之间进行转换,也可将 time with time zone 值转换到不同的时区。 展示了它的各种变体。 + AT TIME ZONE 操作符可将不带时区的时间戳转换为时区的时间戳或反向转换,也可将 time with time zone 值转换到不同的时区。 展示了它的各种变体。
@@ -8564,7 +8521,7 @@ SELECT TIMESTAMP '2001-02-16 20:38:40' AT TIME ZONE 'Asia/Tokyo' AT TIME ZONE 'A 第一个示例为不带时区的值添加时区,并使用当前TimeZone设置显示该值。第二个示例将带时区的时间戳值移到指定时区,并返回不带时区的值。这样就可以存储和显示与当前TimeZone设置不同的值。第三个示例将东京时间转换为芝加哥时间。 - 函数timezone(zone, timestamp)等效于 SQL 兼容的结构timestamp AT TIME ZONE zone。 + 函数timezone(zone, timestamp)等效于符合 SQL 标准的结构timestamp AT TIME ZONE zone @@ -8572,13 +8529,13 @@ SELECT TIMESTAMP '2001-02-16 20:38:40' AT TIME ZONE 'Asia/Tokyo' AT TIME ZONE 'A 当前日期/时间 - date - current + 日期 + 当前 - time - current + 时间 + 当前 @@ -8597,11 +8554,11 @@ LOCALTIMESTAMP(precision) - CURRENT_TIMECURRENT_TIMESTAMP传递带有时区的值;LOCALTIMELOCALTIMESTAMP传递的值不带时区。 + CURRENT_TIMECURRENT_TIMESTAMP返回带时区的值;LOCALTIMELOCALTIMESTAMP返回不带时区的值。 - CURRENT_TIMECURRENT_TIMESTAMPLOCALTIMELOCALTIMESTAMP可以有选择地接受一个精度参数,该精度会使结果的秒字段圆整到指定的小数位数。如果没有精度参数,结果将给出可用的全部精度。 + CURRENT_TIMECURRENT_TIMESTAMPLOCALTIMELOCALTIMESTAMP可以有选择地接受一个精度参数,该精度会使结果的秒字段舍入到指定的小数位数。如果没有精度参数,结果将给出可用的全部精度。 下面是一些示例: @@ -8625,7 +8582,7 @@ SELECT LOCALTIMESTAMP; - 许多其它数据库系统可能会更频繁地推进这些值。 + 其他数据库系统可能会更频繁地推进这些值。 @@ -8642,13 +8599,15 @@ now() - transaction_timestamp()等价于CURRENT_TIMESTAMP,但是其命名清楚地反映了它的返回值。statement_timestamp()返回当前语句的开始时刻(更准确的说是收到 客户端最后一条命令的时间)。statement_timestamp()transaction_timestamp()在一个事务的第一条命令期间返回值相同,但是在随后的命令中却不一定相同。 clock_timestamp()返回真正的当前时间,因此它的值甚至在同一条 SQL 命令中都会变化。timeofday()是一个有历史原因的PostgreSQL函数。和clock_timestamp()相似,它也返回真实的当前时间,但是它的结果是一个格式化的text串,而不是timestamp with time zone值。now()PostgreSQL的一个传统,等效于transaction_timestamp()。 + transaction_timestamp()等价于CURRENT_TIMESTAMP,但是其命名清楚地反映了它的返回值。statement_timestamp()返回当前语句的开始时刻(更准确地说,是接收到客户端最近一条命令消息的时间)。statement_timestamp()transaction_timestamp()在一个事务的第一条语句期间返回值相同,但是在随后的语句中却不一定相同。 clock_timestamp()返回真正的当前时间,因此它的值甚至在同一条 SQL 语句中都会变化。timeofday()是一个有历史原因的PostgreSQL函数。和clock_timestamp()相似,它也返回真实的当前时间,但是它的结果是一个格式化的text串,而不是timestamp with time zone值。now()PostgreSQL中与transaction_timestamp()等价的传统函数。 - 所有日期/时间数据类型也都接受特殊字面值now来指定当前日期和时间(同样解释为事务开始时间)。因此,下面三种写法都返回相同的结果: + + 所有日期/时间数据类型也都接受特殊字面值now来指定当前日期和时间(同样解释为事务开始时间)。因此,下面三种写法都返回相同的结果: + SELECT CURRENT_TIMESTAMP; SELECT now(); -SELECT TIMESTAMP 'now'; -- but see tip below +SELECT TIMESTAMP 'now'; -- 但请参阅下面的提示 @@ -8656,7 +8615,7 @@ SELECT TIMESTAMP 'now'; -- but see tip below 当指定以后要计算的值时,不要使用第三种形式,例如在表列的DEFAULT子句中。 - 系统将在分析这个常量的时候把now转换为一个timestamp, 这样需要默认值时就会得到创建表的时间!而前两种形式要到实际使用缺省值的时候才被计算, 因为它们是函数调用。因此它们可以给出每次插入行的时刻。 + 系统将在分析这个常量的时候把now转换为一个timestamp, 这样需要默认值时就会得到创建表的时间!而前两种形式要到实际使用默认值的时候才被计算, 因为它们是函数调用。因此它们可以给出每次插入行的时刻。 (参见 。) @@ -8675,20 +8634,24 @@ SELECT TIMESTAMP 'now'; -- but see tip below pg_sleep_until - sleep + 休眠 - delay + 延迟 - 以下函数可用于延迟服务器进程的执行: + 以下函数可用于延迟服务器进程的执行: + pg_sleep ( double precision ) pg_sleep_for ( interval ) pg_sleep_until ( timestamp with time zone ) - pg_sleep使当前会话的进程休眠,直到经过指定的秒数。可以指定带小数部分的秒数作为延迟时间。pg_sleep_for是一个便捷函数,允许以如下类型指定休眠时间:interval。 - pg_sleep_until是在需要指定唤醒时间时使用的便利函数。例如: + pg_sleep使当前会话的进程休眠,直到经过指定的秒数。可以指定带小数部分的秒数作为延迟时间。 + pg_sleep_for是一个便捷函数,允许以interval指定休眠时间。 + pg_sleep_until是在需要指定唤醒时间时使用的便捷函数。例如: + + SELECT pg_sleep(1.5); SELECT pg_sleep_for('5 minutes'); SELECT pg_sleep_until('tomorrow 03:00'); @@ -8722,7 +8685,7 @@ SELECT pg_sleep_until('tomorrow 03:00'); 枚举支持函数 - 对于枚举类型(在中描述), 有一些函数允许更清洁的编码,而不需要为一个枚举类型硬写特定的值。它们被列在中。本例假定一个枚举类型被创建为: + 对于枚举类型(见),有些函数可以避免硬编码枚举类型中的特定值,使程序更简洁。这些函数列在中。以下示例假定枚举类型按如下方式创建: CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple'); @@ -8808,8 +8771,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple anyarray - 以一个数组返回在给定两个枚举值之间的范围。值必须来自相同的枚举类型。 - 如果第一个参数为空,其结果将从枚举类型的第一个值开始。如果第二参数为空,其结果将以枚举类型的最后一个值结束。 + 以有序数组返回两个给定枚举值之间的范围。两个值必须来自同一枚举类型。如果第一个参数为 null,结果从该枚举类型的第一个值开始;如果第二个参数为 null,结果以该枚举类型的最后一个值结束。 enum_range('orange'::rainbow, 'green'::rainbow) @@ -8829,8 +8791,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple
- 请注意,除了双参数形式的enum_range外, 这些函数忽略传递给它们的具体值,它们只关心声明的数据类型。 - 空值或类型的一个特定值可以通过,并得到相同的结果。这些函数更多地被用于一个表列或函数参数,而不是一个硬写的类型名,如示例中所使用。 + 请注意,除了enum_range的双参数形式外,这些函数都忽略传入的具体值,只关心其声明的数据类型。传入 null 或该类型的某个具体值,结果都相同。通常会将这些函数用于表列或函数参数,而不是像示例那样使用硬编码的类型名。 @@ -8840,7 +8801,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple 几何类型pointboxlseglinepath、 - polygoncircle有一大堆本地支持函数和操作符,如中所示。 + polygoncircle有大量内置支持函数和操作符,如中所示。 @@ -8883,7 +8844,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple path - 连接两个打开的路径(如果其中一个路径是关闭的,则返回NULL)。 + 连接两个开放路径(如果任一路径是封闭的,则返回NULL)。 path '[(0,0),(1,1)]' + path '[(2,2),(3,3),(4,4)]' @@ -8915,8 +8876,8 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple 将第一个参数的每个点乘上第二个point(将点视为由实部和虚部表示的复数,并执行标准的复数乘法)。 如果将第二个point解释为向量,这等价于将对象的大小和到原点的距离按向量的长度缩放,并以向量与x轴的夹角绕原点逆时针旋转。 适用于pointbox用这些操作符旋转一个盒子,只会移动它的角点:这个盒子仍然被认为有平行于轴的边。 - 因此,盒子的大小并没有像真正的旋转那样得到保留。 + id="functions-geometry-rotation-fn">用这些操作符旋转一个矩形框,只会移动它的角点:这个矩形框仍然被认为有平行于轴的边。 + 因此,矩形框的大小并没有像真正的旋转那样得到保留。 pathcircle @@ -8936,7 +8897,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple 将第一个参数的每个点除以第二个point(将点视为由实部和虚部表示的复数,并执行标准的复数除法)。 - 如果将第二个point解释为向量,这等价于将物体的大小和到原点的距离按向量的长度向下缩放,并以向量与x轴的夹角围绕原点顺时针旋转。 + 如果将第二个point解释为向量,这等价于将对象的大小和到原点的距离按向量长度的倒数缩放,并以向量与x轴的夹角围绕原点顺时针旋转。 适用于 point, box, path,circle @@ -9013,7 +8974,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple box - 计算两个方框的交集,如果没有则为NULL。 + 计算两个矩形框的交集,如果没有则为NULL。 box '(2,2),(-1,-1)' # box '(1,1),(-2,-2)' @@ -9027,7 +8988,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple point - 计算第一个对象上距离第二个对象最近的点。 + 计算第二个对象上距离第一个对象最近的点。 可用于以下类型的配对: (point, box), (point, lseg), @@ -9089,7 +9050,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 第一个对象包含在第二个对象之中还是在第二个对象之上? 适用于这些类型对: + 第一个对象是否位于第二个对象内部或其上? 适用于这些类型对: (point, box), (point, lseg), (point, line), @@ -9189,7 +9150,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 第一个对象是否确定位于第二个对象下面? + 第一个对象是否严格位于第二个对象下面? 适用于 box, polygon, circle @@ -9204,7 +9165,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 第一个对象是否确定位于第二个对象上面? + 第一个对象是否严格位于第二个对象上面? 适用于 box, polygon, circle. @@ -9301,7 +9262,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 这些对象是否相交? 适用于这些类型对: + 这些对象是否相交? 适用于这些类型对: (box, box), (lseg, box), (lseg, lseg), @@ -9326,7 +9287,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 线是水平的? + 线是否水平? ?- lseg '[(-1,0),(1,0)]' @@ -9358,7 +9319,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 线是纵向的? + 线是否竖直? ?| lseg '[(-1,0),(1,0)]' @@ -9390,7 +9351,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 线是垂直的? + 两条线是否互相垂直? lseg '[(0,0),(0,1)]' ?-| lseg '[(0,0),(1,0)]' @@ -9408,7 +9369,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 线是平行的? + 两条线是否平行? lseg '[(-1,0),(1,0)]' ?|| lseg '[(-1,2),(1,2)]' @@ -9437,9 +9398,9 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple - 请注意same as操作符(~=),表示pointboxpolygoncircle类型的一般相等概念。 - 这些类型中的某些还有一个=操作符,但是=只比较相同的面积。 - 其它的标量比较操作符 (<=等等),在这些类型可用的地方,同样比较区域。 + 注意,相同操作符~=表示pointboxpolygoncircle类型通常意义上的相等。 + 某些几何类型还有=操作符,但=仅比较面积是否相等。 + 对于提供其他标量比较操作符(<=等)的类型,这些操作符同样比较面积。 @@ -9738,7 +9699,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple box - 计算内接于圆的方框。 + 计算内接于圆的矩形框。 box(circle '<(0,0),2>') @@ -9797,7 +9758,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple box - 计算两个方框的边界框。 + 计算两个矩形框的边界框。 bound_box(box '(1,1),(0,0)', box '(4,4),(3,3)') @@ -9814,7 +9775,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple circle - 计算包围方框的最小圆。 + 计算包围矩形框的最小圆。 circle(box '(1,1),(0,0)') @@ -9907,7 +9868,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple path - 将多边形转换为具有点的相同列表的封闭路径。 + 将多边形转换为具有相同点列表的封闭路径。 path(polygon '((0,0),(1,1),(2,0))') @@ -10039,7 +10000,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple polygon - 将封闭路径转换为具有点的相同列表的多边形。 + 将封闭路径转换为具有相同点列表的多边形。 polygon(path '((0,0),(1,1),(2,0))') @@ -10052,7 +10013,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple
- 我们可以把一个point的两个组成数字当作具有索引 0 和 1 的数组访问。例如,如果t.p是一个point列,那么SELECT p[0] FROM t检索 X 坐标而 UPDATE t SET p[1] = ...改变 Y 坐标。同样,box或者lseg类型的值可以当作两个point值的数组值看待。 + 可以把一个point当作下标为 0 和 1 的数组,访问它的两个数值分量。例如,如果t.p是一个point列,那么SELECT p[0] FROM t检索 X 坐标而 UPDATE t SET p[1] = ...改变 Y 坐标。同样,box或者lseg类型的值可以当作两个point值组成的数组看待。 @@ -10069,8 +10030,8 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple 任何cidr 值都可以隐式地转换到inet;因此,下面在inet上操作的操作符和函数也可以在cidr值上工作。 - (对于inetcidr有单独的函数,这是因为这两种情况的行为应该是不同的。) - 此外,它允许将inet值转换为cidr。 + (如果inetcidr各有单独的函数,是因为这两种情况下的行为应当不同。) + 此外,也允许将inet值转换为cidr。 当这样做的时候,子网掩码右边的任何位都被静默地置零,以创建一个有效的cidr值。 @@ -10101,8 +10062,8 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean
- 子网是否严格包含在子网中?这个操作符和后续的四个操作符测试子网包含情况。 - 它们只考虑两个地址的网络部分(忽略网络掩码右侧的任何位),并确定一个网络与另一个网络相同或者是相同的子网。 + 子网是否严格包含在另一个子网中?这个操作符和后续四个操作符测试子网包含关系。 + 它们只考虑两个地址的网络部分(忽略网络掩码右侧的所有位),并判断一个网络是否与另一个网络相同,或是另一个网络的子网。 inet '192.168.1.5' << inet '192.168.1/24' @@ -10124,7 +10085,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 子网是否包含或等于子网? + 子网是否被包含于或等于子网? inet '192.168.1/24' <<= inet '192.168.1/24' @@ -10184,7 +10145,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple inet - 计算位 NOT. + 计算按位非。 ~ inet '192.168.1.6' @@ -10198,7 +10159,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple inet - 计算位 AND. + 计算按位与。 inet '192.168.1.6' & inet '0.0.0.255' @@ -10212,7 +10173,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple inet - 计算位 OR. + 计算按位或。 inet '192.168.1.6' | inet '0.0.0.255' @@ -10313,9 +10274,8 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple text - 创建缩写的文本显示格式。 - (结果与inet输出函数产生的结果相同;只有在与显式转换为text的结果相比时它才算是缩写形式, - 由于历史原因,它永远不会抑制子网掩码部分。) + 创建文本形式的缩写显示格式。 + (结果与inet输出函数产生的结果相同;只有与显式类型转换为text的结果相比时,才称为缩写形式。由于历史原因,后一种转换从不省略网络掩码部分。) abbrev(inet '10.1.0.0/32') @@ -10329,7 +10289,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple text - 创建缩写的文本显示格式。(缩写包括从子网掩码的右侧删除所有零字节;更多示例请见 。) + 创建文本形式的缩写显示格式。(缩写形式会省略网络掩码右侧值为零的字节;更多示例见。) abbrev(cidr '10.1.0.0/16') @@ -10448,7 +10408,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple integer - 以比特位返回子网掩码长度。 + 返回子网掩码长度,以位为单位。 masklen(inet '192.168.1.5/24') @@ -10550,7 +10510,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple MAC地址类型, macaddrmacaddr8,支持中所示的常用比较操作符以及中所示的特殊函数。 - 此外,它们支持位元逻辑操作符~, &| (NOT, AND 和 OR),就像上面对IP地址所示的那样。 + 此外,它们支持按位逻辑操作符~&|(非、与和或),就像上面对IP地址所示的那样。 @@ -10614,7 +10574,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple macaddr8 - 将地址的第7位设置为1,创建所谓的modified EUI-64,用于包含在IPv6地址中。 + 将地址的第 7 位设置为 1,生成所谓的修订 EUI-64 格式,以便用于 IPv6 地址。 macaddr8_set7bit(macaddr8 '00:34:56:ab:cd:ef') @@ -10632,7 +10592,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple 文本搜索函数和操作符 - 全文搜索 + 全文检索 函数和操作符 @@ -10645,7 +10605,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple 以及 - 总结了为全文搜索提供的函数和操作符。PostgreSQL的文本搜索功能的详细解释可参考。 + 总结了为全文检索提供的函数和操作符。PostgreSQL的文本搜索功能的详细解释可参考
@@ -10723,7 +10683,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsvector - 连接两个tsvector。如果两个输入都包含词素位置,则相应地调整第二个输入的位置。 + 连接两个tsvector。如果两个输入都包含词位位置,则相应地调整第二个输入的位置。 'a:1 b:2'::tsvector || 'c:1 d:2 b:3'::tsvector @@ -10765,7 +10725,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsquery - 否定tsquery,生成一个与输入查询不匹配的匹配文档的查询。 + 对tsquery取反,生成匹配那些不满足输入查询的文档的查询。 !! 'cat'::tsquery @@ -10779,7 +10739,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsquery - 构造一个短语查询,如果两个输入查询在连续的词素上匹配,该查询将进行匹配。 + 构造一个短语查询;当两个输入查询分别匹配相邻的词位时,该查询匹配。 to_tsquery('fat') <-> to_tsquery('rat') @@ -10793,7 +10753,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 第一个tsquery包含了第二个吗?(这只考虑出现在一个查询中的所有词素是否出现在另一个查询中,忽略了组合操作符。) + 第一个tsquery包含了第二个吗?(这只考虑出现在一个查询中的所有词位是否出现在另一个查询中,忽略了组合操作符。) 'cat'::tsquery @> 'cat & rat'::tsquery @@ -10807,7 +10767,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 第一个tsquery包含在第二个中吗?(这只考虑出现在一个查询中的所有词素是否出现在另一个查询中,而忽略了组合操作符。) + 第一个tsquery包含在第二个中吗?(这只考虑出现在一个查询中的所有词位是否出现在另一个查询中,而忽略了组合操作符。) 'cat'::tsquery <@ 'cat & rat'::tsquery @@ -10824,7 +10784,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple 除了这些专用操作符之外, 中所示的常用比较操作符也适用于tsvectortsquery类型。 - 它们对于文本搜索不是很有用,但是允许使用。例如,建在这些类型列上的唯一索引。 + 这些操作符对文本搜索用处不大,但可以用于其他用途,例如在这些类型的列上建立唯一索引。
@@ -10854,7 +10814,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple array_to_tsvector ( text[] ) tsvector - 将词元数组转换为 tsvector。给定的字符串按原样使用,不做进一步处理。 + 将词位数组转换为 tsvector。给定的字符串按原样使用,不做进一步处理。 array_to_tsvector('{fat,cat,rat}'::text[]) 'cat' 'fat' 'rat' @@ -10923,8 +10883,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsquery - 将文本转换为tsquery,根据指定的或默认配置对单词进行标准化。 - 字符串中的任何标点符号都会被忽略(它不决定查询操作符)。结果查询匹配文本中包含所有非停止词的文档。 + 将文本转换为tsquery,根据指定的或默认配置对单词进行正规化。字符串中的任何标点符号都会被忽略(它们不决定查询操作符)。生成的查询匹配包含文本中所有非停用词的文档。 plainto_tsquery('english', 'The Fat Rats') @@ -10943,8 +10902,8 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsquery - 将文本转换为tsquery,根据指定的或默认配置对单词进行标准化。 - 字符串中的任何标点符号都会被忽略(它不决定查询操作符)。结果查询匹配包含文本中所有非停止词的短语。 + 将文本转换为tsquery,根据指定的或默认配置对单词进行正规化。 + 字符串中的任何标点符号都会被忽略(它不决定查询操作符)。结果查询匹配包含文本中所有非停用词的短语。 phraseto_tsquery('english', 'The Fat Rats') @@ -10967,8 +10926,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsquery - 将文本转换为tsquery,根据指定的或默认配置对单词进行标准化。引用的单词序列被转换为短语测试。 - or一词被理解为产生 OR 操作符,而破折号产生 NOT 操作符;其他标点符号会被忽略。这类似于一些常见网络搜索工具的行为。 + 将文本转换为tsquery,根据指定的或默认配置对单词进行正规化。带引号的单词序列被转换为短语测试。or一词产生 OR 操作符,短横线产生 NOT 操作符;其他标点符号会被忽略。这类似于一些常见网络搜索工具的行为。 websearch_to_tsquery('english', '"fat rat" or cat dog') @@ -11014,7 +10972,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple setweight - 为特定词元设置权重 + 为特定词位设置权重 setweight ( vector tsvector, weight "char", lexemes text[] ) tsvector @@ -11054,7 +11012,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsquery - 将文本转换为tsquery,根据指定的或默认配置对单词进行标准化。单词必须由有效的tsquery操作符组合。 + 将文本转换为tsquery,根据指定的或默认配置对单词进行正规化。单词必须由有效的tsquery操作符组合。 to_tsquery('english', 'The & Fat & Rats') @@ -11073,7 +11031,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsvector - 将文本转换为tsvector,根据指定的或默认配置对单词进行标准化。结果中包含位置信息。 + 将文本转换为tsvector,根据指定的或默认配置对单词进行正规化。结果中包含位置信息。 to_tsvector('english', 'The Fat Rats') @@ -11095,9 +11053,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsvector - 将JSON文档中的每个字符串值转换为tsvector,根据指定的或默认配置对单词进行标准化。 - 然后将结果按文档顺序连接起来以产生输出。位置信息就像在每对字符串值之间存在一个停止词一样生成。 - (注意,当输入为jsonb时,JSON 对象字段的document order取决于具体实现;请注意这些示例中的差异。) + 将 JSON 文档中的每个字符串值转换为tsvector,根据指定的或默认配置对单词进行正规化。然后将结果按文档顺序连接起来以产生输出。生成位置信息时,视为每对字符串值之间存在一个停用词。(注意,当输入为jsonb时,JSON 对象字段的文档顺序取决于具体实现;请注意这些示例中的差异。) to_tsvector('english', '{"aa": "The Fat Rats", "b": "dog"}'::json) @@ -11131,15 +11087,15 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsvector - 选择filter请求的JSON文档中的每个项,并将每个项转换为tsvector,根据指定的或默认配置对单词进行标准化。 - 然后将结果按文档顺序连接起来以产生输出。位置信息就像在每对选定的项目之间存在一个停止词一样生成。 - (注意,当输入为jsonb时,JSON对象字段的document order取决于实现。) - filter必须是一个jsonb数组,其中包含0个或多个关键字: + 选择filter请求的JSON文档中的每个项,并将每个项转换为tsvector,根据指定的或默认配置对单词进行正规化。 + 然后将结果按文档顺序连接起来以产生输出。位置信息就像在每对选定的项目之间存在一个停用词一样生成。 + (注意,当输入为jsonb时,JSON对象字段的文档顺序取决于实现。) + filter必须是一个jsonb数组,其中包含0个或多个关键字: "string"(包括所有字符串值), "numeric"(包括所有数值), "boolean"(包括所有布尔值), "key"(包括所有键),或 - "all"(包括以上所有关键字)。 + "all"(包括以上所有内容)。 作为一种特殊情况,该filter也可以是这些关键字之一的简单JSON值。 @@ -11161,7 +11117,8 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsvector - 从vector中删除给定的lexeme的任何出现。 + 从vector中删除给定的lexeme的所有出现。 + ts_delete('fat:2,4 cat:3 rat:5A'::tsvector, 'fat') 'cat':3 'rat':5A @@ -11173,7 +11130,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple ts_delete ( vector tsvector, lexemes text[] ) tsvector - vector 中删除 lexemes 所列词元的所有出现。 + vector 中删除 lexemes 所列词位的所有出现。 ts_delete('fat:2,4 cat:3 rat:5A'::tsvector, ARRAY['fat','rat']) 'cat':3 @@ -11210,9 +11167,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple text - 以缩写形式显示documentquery的匹配项,该匹配项必须是原始文本,而不是tsvector。 - 在匹配查询之前,文档中的单词将根据指定的或默认的配置进行规范化。 - 中讨论了该函数的使用,还描述了可用的options。 + 以缩略形式显示querydocument中的匹配项;后者必须是原始文本,不能是tsvector。在匹配查询之前,文档中的单词将根据指定的或默认配置进行正规化。中讨论了该函数的使用,还描述了可用的options ts_headline('The fat cat ate the rat.', 'cat') @@ -11238,8 +11193,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple text - 以缩写形式显示匹配JSONdocument中字符串值中的query。 - 更多细节请参阅 。 + 以缩略形式显示query在 JSON document字符串值中的匹配项。更多细节请参见 ts_headline('{"cat":"raining cats and dogs"}'::jsonb, 'cat') @@ -11317,8 +11271,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsquery - 根据目标替换部分query,并替换通过执行SELECT命令获得的查询。 - 详情参见。 + 根据执行SELECT命令得到的目标和替换项,替换query中的相应部分。详情参见 SELECT ts_rewrite('a & b'::tsquery, 'SELECT t,s FROM aliases') @@ -11349,7 +11302,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsquery - 构造一个短语查询,用于搜索query1query2的匹配项,这些匹配项恰好出现在distance词位之间。 + 构造一个短语查询,用于搜索query1query2的匹配项,其匹配位置恰好相距distance个词位。 tsquery_phrase(to_tsquery('fat'), to_tsquery('cat'), 10) @@ -11378,7 +11331,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple unnest - for tsvector + 用于 tsvector unnest ( tsvector ) setof record @@ -11408,7 +11361,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple - 所有接受一个可选的regconfig参数的文本搜索函数在该参数被忽略时,使用由指定的配置。 + 所有接受一个可选的regconfig参数的文本搜索函数在省略该参数时,会使用由指定的配置。 @@ -11453,7 +11406,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple lexemes text[] ) - 根据指定的或默认的文本搜索配置从document中提取和标准化标记,并返回关于每个标记是如何处理的信息。 + 根据指定的或默认的文本搜索配置从document中提取和正规化词元,并返回关于每个词元是如何处理的信息。 详情参见 @@ -11471,8 +11424,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple text[] - 如果字典知道输入标记,则返回替换词元数组;如果字典知道该标记,但它是停止词,则返回空数组;如果它不是已知词,则返回 NULL。 - 详情参见。 + 如果词典识别输入词元,则返回由替换词位组成的数组;如果词典识别该词元,但它是停用词,则返回空数组;如果词典无法识别该词元,则返回NULL。详情参见 ts_lexize('english_stem', 'stars') @@ -11492,7 +11444,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple token text ) - 使用命名的解析器从document中提取标记。详情参见。 + 使用指定名称的解析器从document中提取词元。详情参见 ts_parse('default', 'foo - bar') @@ -11509,7 +11461,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple token text ) - 使用 OID 指定的解析器从document中提取标记。 + 使用 OID 指定的解析器从document中提取词元。 详情参见 @@ -11530,7 +11482,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple description text ) - 返回一个表,该表描述命名解析器可以识别的每种类型的标记。详情参见。 + 返回一个表,该表描述指定名称的解析器可以识别的每种类型的词元。详情参见 ts_token_type('default') @@ -11547,7 +11499,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple description text ) - 返回一个表,该表描述 OID 指定的解析器可以识别的每种标记类型。详情参见。 + 返回一个表,该表描述 OID 指定的解析器可以识别的每种词元类型。详情参见 ts_token_type(3722) @@ -11568,7 +11520,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple nentry integer ) - 执行sqlquery,该查询必须返回单个tsvector列,并返回数据中每个不同词元的统计信息。 + 执行sqlquery,该查询必须返回单个tsvector列,并返回数据中每个不同词位的统计信息。 详情参见 @@ -11595,15 +11547,16 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple - PostgreSQL提供一个生成 UUID 的函数: + PostgreSQL包含一个生成 UUID 的函数: + gen_random_uuid () uuid -该函数返回版本 4(随机)UUID。这是最常用的 UUID 类型,适合大多数应用。 + + 该函数返回版本 4(随机)UUID。这是最常用的 UUID 类型,适用于大多数应用。 - 模块提供了额外的函数,用于实现其他生成 UUID 的标准算法。 + 模块还提供了额外的函数,用于实现其他标准 UUID 生成算法。 - PostgreSQL也为 UUID 提供了 - 中展示的常用比较操作符。 + PostgreSQL也为 UUID 提供了中展示的常用比较操作符。 @@ -12030,7 +11983,7 @@ SELECT xmlexists('//town[text() = ''Toronto'']' PASSING BY VALUE 'T - 示例: + 示例: - 示例: + 示例: test', ARRAY[ARRAY['my', 'http://example.com']]); @@ -12146,7 +12099,7 @@ SELECT xpath('//mydefns:b/text()', 'test - 示例: + 示例: test', ARRAY[ARRAY['my', 'http://example.com']]); @@ -12198,8 +12151,8 @@ SELECT xpath_exists('/my:a/text()', 'test - document_expression提供了上下文。row_expression的项。 - 它必须是一个格式良好的XML文档;不接受片段/森林。BY REFBY VALUE子句 如上文所讨论的那样,被接受但被忽略了,正如在中所讨论的。 + document_expressionrow_expression提供上下文项。 + 它必须是一个良构的 XML 文档;不接受内容片段或森林。BY REFBY VALUE子句会被接受,但会被忽略,如中所述。 @@ -12568,7 +12521,7 @@ table2-mapping - 本节描述: + 本节描述: @@ -12578,14 +12531,16 @@ table2-mapping - SQL/JSON路径语言 + SQL/JSON 路径语言 - 要了解有关SQL/JSON标准的更多信息,请参阅。有关PostgreSQL中支持的JSON类型的详细信息,见 。 + 要了解有关 SQL/JSON 标准的更多信息,请参阅。有关 + PostgreSQL 中支持的 JSON 类型的详细信息,见 + @@ -12743,9 +12698,8 @@ table2-mapping - 还有一些操作符仅适用于jsonb,如表所示。 - 第描述了如何使用这些操作符来有效地搜索索引的jsonb数据。 - + 还有一些操作符仅适用于jsonb,如所示。介绍了如何使用这些操作符有效地搜索已建立索引的jsonb数据。 +
@@ -12820,7 +12774,7 @@ table2-mapping boolean - 文本数组中的字符串是否作为顶级键或数组元素存在? + 文本数组中的任一字符串是否作为顶级键或数组元素存在? '{"a":1, "b":2, "c":3}'::jsonb ?| array['b', 'd'] @@ -12871,7 +12825,7 @@ table2-mapping [{"a": "b"}, 42] - 要将一个数组作为单个条目附加到另一个数组中,请将其包装在另一个数组附加层中,例如: + 要将一个数组作为单个元素追加到另一个数组中,请先在它外面再包装一层数组,例如: '[1, 2]'::jsonb || jsonb_build_array('[3, 4]'::jsonb) @@ -12973,9 +12927,7 @@ table2-mapping - jsonpath操作符@?@@会抑制以下错误:缺少对象字段或数组元素、意外的 JSON 项目类型,以及日期时间和数字错误。 - 还可以告诉以下描述的与jsonpath相关的函数来抑制这些类型的错误。 - 在搜索不同结构的JSON文档集合时,此行为可能会有所帮助。 + jsonpath操作符@?@@会抑制以下错误:缺少对象字段或数组元素、JSON 项类型不符合预期,以及日期时间和数值错误。下文介绍的jsonpath相关函数也可以设置为抑制这些类型的错误。在搜索结构各异的 JSON 文档集合时,这一行为可能很有用。 @@ -13018,14 +12970,14 @@ table2-mapping jsonb - 将任何SQL值转换为jsonjsonb。数组和组合递归地转换为数组和对象(多维数组在JSON中变成数组的数组)。 - 否则,如果存在从SQL数据类型到json的类型转换,则类型转换函数将用于执行转换; + 将任何SQL值转换为jsonjsonb。数组和复合值递归地转换为数组和对象(多维数组在JSON中变成数组的数组)。 + 否则,如果存在从SQL数据类型到json的类型转换,则类型转换函数将用于执行转换; - 例如,扩展有一个从hstorejson的转换,这样通过json创建函数转换的hstore值将被表示为json对象,而不是原始字符串值 + 例如,扩展有一个从hstorejson的类型转换,因此通过 JSON 创建函数转换的hstore值将表示为 JSON 对象,而不是基本的字符串值。 - 否则,将生成一个标量json值。对于除数字、布尔值或空值之外的任何标量,将使用文本表示,并根据需要进行转义,使其成为有效的JSON字符串值。 + 否则,将生成一个标量 JSON 值。对于除数字、布尔值或空值之外的任何标量,将使用文本表示,并根据需要进行转义,使其成为有效的JSON字符串值。 to_json('Fred said "Hi."'::text) @@ -13063,7 +13015,7 @@ table2-mapping json - 将SQL组合值转换为JSON对象。该行为与to_json相同,只是如果可选boolean参数为真,换行符将在顶级元素之间添加。 + 将SQL 复合值转换为JSON对象。该行为与to_json相同,只是如果可选boolean参数为真,换行符将在顶级元素之间添加。 row_to_json(row(1,'foo')) @@ -13136,8 +13088,7 @@ table2-mapping jsonb - 从文本数组构建JSON对象。该数组必须有两个维度,一个维度的成员数为偶数,在这种情况下,它们被视为交替的键/值对; - 另一个维度的成员数为二维,每个内部数组恰好有两个元素,它们被视为键/值对。所有值都转换为JSON字符串。 + 从文本数组构造 JSON 对象。该数组必须是一维且包含偶数个成员,此时将成员按交替的键/值对处理;或者是二维数组,且每个内部数组恰好有两个元素,将这两个元素作为一个键/值对。所有值都转换为 JSON 字符串。 json_object('{a, 1, b, "def", c, 3.5}') @@ -13158,7 +13109,7 @@ table2-mapping jsonb - 这种形式的json_object从单独的文本数组中成对地获取键和值。否则,它与单参数形式相同。 + 这种形式的json_object从单独的文本数组中成对地获取键和值。除此之外,它与单参数形式相同。 json_object('{a,b}', '{1,2}') @@ -13443,46 +13394,48 @@ table2-mapping anyelement - 将顶级 JSON 对象展开为具有 base 参数复合类型的行。JSON 对象将被扫描,查找名称与输出行类型列名匹配的字段,并将其值插入到输出行的对应列中。 - (不对应任何输出列名的字段将被忽略。)在典型用法中,base 的值仅为 NULL,这意味着任何不匹配对象字段的输出列都会被填充为 null。 - 但是,如果base不为NULL,那么它包含的值将用于不匹配的列。 + 将顶级 JSON 对象展开为一个行,其复合类型与base参数相同。系统会扫描该 JSON 对象,查找名称与输出行类型列名匹配的字段,并将其值插入输出中的对应列。 + (不对应任何输出列名的字段会被忽略。)在典型用法中,base的值就是NULL,这意味着凡是不匹配对象字段的输出列都会被填充为空值。 + 但是,如果base不是NULL,那么其中包含的值将用于那些不匹配的列。 - 将 JSON 值转换为输出列的 SQL 类型时,依次应用以下规则: + + 要将 JSON 值转换为输出列的 SQL 类型,需要依次应用以下规则: + - 在所有情况下,JSON空值都会转换为SQL空值。 + 在所有情况下,JSON 空值都会转换为 SQL 空值。 - 如果输出列的类型是jsonjsonb,则会精确地重制JSON值。 + 如果输出列的类型是jsonjsonb,则 JSON 值会被原样保留。 - 如果输出列是复合(行)类型,且JSON值是JSON对象,则该对象的字段将转换为输出行类型的列,通过这些规则的递归应用程序。 + 如果输出列是复合(行)类型,且 JSON 值是 JSON 对象,则该对象的字段会通过递归应用这些规则,被转换为输出行类型的各列。 - 同样,如果输出列是数组类型,而JSON值是JSON数组,则通过这些规则的递归应用程序将JSON数组的元素转换为输出数组的元素。 + 同样,如果输出列是数组类型,而 JSON 值是 JSON 数组,则会通过递归应用这些规则,把 JSON 数组的元素转换为输出数组的元素。 - 否则,如果JSON值是字符串,则将字符串的内容提供给输入转换函数,用以确定列的数据类型。 + 否则,如果 JSON 值是字符串,则会把该字符串的内容送入该列数据类型的输入转换函数。 - 否则,JSON值的普通文本表示将被提供给输入转换函数,以确定列的数据类型。 + 否则,JSON 值的普通文本表示会被送入该列数据类型的输入转换函数。 - 虽然下面的示例使用一个常量JSON值,典型的用法是在查询的FROM子句中从另一个表侧面地引用jsonjsonb列。 - 在FROM子句中编写json_populate_record是一种很好的实践,因为提取的所有列都可以使用,而不需要重复的函数调用。 + 虽然下面的示例使用的是常量 JSON 值,但典型用法是在查询的FROM子句中,以横向方式引用另一个表中的jsonjsonb列。 + 把json_populate_record写在FROM子句中是一种良好实践,因为这样抽取出的所有列都可以直接使用,而不需要重复调用函数。 create type subrowtype as (d int, e text); @@ -13516,8 +13469,7 @@ table2-mapping setof anyelement - 将对象的顶级 JSON 数组展开为一组具有 base 参数复合类型的行。 - 对于json[b]_populate_record,将如上所述处理JSON数组的每个元素。 + 将由对象组成的顶级 JSON 数组展开为一组行,其复合类型与base参数相同。JSON 数组中的每个元素都按照上文对json[b]_populate_record的说明进行处理。 create type twoints as (a int, b int); @@ -13587,7 +13539,7 @@ table2-mapping 将顶级JSON对象数组展开为一组由AS子句定义的复合类型的行。 (与所有返回record的函数一样,调用查询必须使用AS子句显式定义记录的结构。) - 对于json[b]_populate_record,将如上所述处理JSON数组的每个元素。 + JSON 数组中的每个元素都按照上文对json[b]_populate_record的说明进行处理。 select * from json_to_recordset('[{"a":1,"b":"foo"}, {"a":"2","c":"bar"}]') as x(a int, b text) @@ -13613,7 +13565,7 @@ table2-mapping 返回target,将path指定的项替换为new_value, 如果create_if_missing为真(此为默认值)并且path指定的项不存在,则添加new_value。 路径中的所有前面步骤都必须存在,否则将不加改变地返回target。 - 与面向路径操作符一样,负整数出现在JSON数组末尾的path计数中。 + 与面向路径的操作符一样,path中的负整数从 JSON 数组末尾计数。 如果最后一个路径步骤是超出范围的数组索引,并且create_if_missing为真,那么如果索引为负,新值将添加到数组的开头,如果索引为正,则添加到数组的结尾。 @@ -13660,8 +13612,8 @@ table2-mapping 如果path指派的项是一个数组元素,如果 insert_after为假(此为默认值),则new_value将被插入到该项之前,如果 insert_after为真则在该项之后。 如果由path指派的项是一个对象字段,则只在对象不包含该键时才插入 new_value。 路径中的所有前面步骤都必须存在,否则将不加改变地返回target。 - 与面向路径操作符一样,负整数出现在JSON数组末尾的 path计数中。 - 如果最后一个路径步骤是超出范围的数组下标,那么当下标为负时,新值会被添加到数组开头;当下标为正时,新值会被添加到数组结尾。 + 与面向路径的操作符一样,path中的负整数从 JSON 数组末尾计数。 + 如果最后一个路径步骤是超出范围的数组下标,那么当下标为负时,新值会被添加到数组开头;当下标为正时,新值会被添加到数组末尾。 jsonb_insert('{"a": [0,1,2]}', '{a, 1}', '"new_value"') @@ -13704,7 +13656,7 @@ table2-mapping boolean - 检查JSON路径是否返回指定JSON值的任何项。如果指定了vars参数,则它必须是一个JSON对象,并且它的字段提供要替换到jsonpath表达式中的名称值。 + 检查JSON路径是否返回指定JSON值的任何项。如果指定了vars参数,则它必须是一个JSON对象,并且它的字段提供要替换到jsonpath表达式中的具名值。 如果指定了silent参数并为true,函数会抑制与@?@@操作符相同的错误。 @@ -13846,7 +13798,7 @@ table2-mapping text - 将给定的JSON值转换为精美打印的,缩进的文本。 + 将给定的 JSON 值转换为经过美化并带有缩进的文本。 jsonb_pretty('[{"f1":1,"f2":null}, 2]') @@ -13879,7 +13831,7 @@ table2-mapping text - 以文本字符串形式返回顶级JSON值的类型。可能的类型有object, array,string, number,boolean, 和 null。 + 以文本字符串形式返回顶级JSON值的类型。可能的类型有objectarraystringnumberbooleannull。 (null 的结果不应与 SQL NULL 混淆;参见示例。) @@ -13924,13 +13876,11 @@ table2-mapping - 要引用正在查询的JSON值(context item项),在路径表达式中使用$变量。 - 它后面可以跟着一个或多个accessor operators,这些操作符在JSON结构中逐级向下检索上下文项的子项。 - 后面的每个操作符处理前一个求值步骤的结果。 - + 要引用正在查询的 JSON 值(上下文项),请在路径表达式中使用$变量。它后面可以跟一个或多个访问操作符,沿 JSON 结构逐层向下获取上下文项的子项。每个后续操作符都处理上一步求值的结果。 + - 例如,假设你有一些你想要解析的来自GPS跟踪器的JSON数据,例如: + 例如,假设你有一些你想要解析的来自GPS跟踪器的JSON数据,例如: { "track": { @@ -13957,7 +13907,7 @@ $.track.segments - 要检索数组的内容,通常使用[*]操作符。例如,下面的路径将返回所有可用轨道段的位置坐标: + 要检索数组的内容,通常使用[*]操作符。例如,下面的路径将返回所有可用轨迹段的位置坐标: $.track.segments[*].location @@ -13979,10 +13929,10 @@ $.track.segments.size() - 过滤表达式必须在它们应该应用的路径求值步骤之后写入。该步骤的结果将被筛选,以只包括满足所提供条件的那些项。 + 过滤表达式必须在它们应该应用的路径求值步骤之后指定。该步骤的结果会经过过滤,只保留满足给定条件的项。 SQL/JSON定义了三值逻辑,因此条件可以是 true, false,或 unknownunknown值发挥与SQL NULL相同的角色,可以使用is unknown谓词进行测试。 - 进一步的路径求值步骤只使用筛选器表达式返回true的那些项。 + 进一步的路径求值步骤只使用过滤表达式返回true的那些项。 @@ -14018,7 +13968,10 @@ $.track ? (exists(@.segments[*] ? (@.HR > 130))).segments.size() - 路径表达式可以是布尔谓词,尽管 SQL/JSON 标准只允许在过滤器中使用谓词。这是实现以下操作符所必需的:@@。例如,以下jsonpath表达式可用于PostgreSQL: + + 路径表达式可以是布尔谓词,尽管 SQL/JSON 标准只允许在过滤器中使用谓词。 + 这对于实现 @@ 操作符是必要的。例如, + 下面的 jsonpath 表达式在 PostgreSQL 中是有效的: $.track.segments[*].HR < 70 @@ -14036,7 +13989,7 @@ $.track.segments[*].HR < 70 严格模式与宽松模式 当查询JSON数据时,路径表达式可能与实际的JSON数据结构不匹配。 - 试图访问不存在的对象成员或数组元素会导致结构错误。SQL/JSON路径表达式有两种处理结构错误的模式: + 试图访问不存在的对象成员或数组元素会导致结构错误。SQL/JSON路径表达式有两种处理结构错误的模式: @@ -14050,16 +14003,18 @@ $.track.segments[*].HR < 70 - 如果 JSON 数据不符合预期模式,宽松模式有助于使 JSON 文档结构与路径表达式相匹配。如果操作数不满足某个操作的要求,可以在执行该操作之前自动将其包装为 SQL/JSON 数组,或通过将其元素转换为 SQL/JSON 序列来展开。此外,在宽松模式下,比较操作符会自动展开其操作数,因此可以直接比较 SQL/JSON 数组。大小为 1 的数组被视为等于其唯一元素。只有以下情况不会自动展开: + + 如果 JSON 数据不符合预期模式,宽松模式有助于使 JSON 文档结构与路径表达式相匹配。如果操作数不满足某个操作的要求,可以在执行该操作之前自动将其包装为 SQL/JSON 数组,或通过将其元素转换为 SQL/JSON 序列来解包。此外,在宽松模式下,比较操作符会自动解包其操作数,因此可以直接比较 SQL/JSON 数组。大小为 1 的数组被视为等于其唯一元素。以下情况不会自动解包: + - 路径表达式包含type()size()方法,它们分别返回数组中的元素类型和数量。 + 路径表达式包含type()size()方法,它们分别返回类型和数组中的元素数量。 - 查询的JSON数据包含嵌套的数组。在本例中,只有最外层的数组被打开,而所有内部数组保持不变。 - 因此,隐式展开在每个路径求值步骤中只能向下进行一级。 + 查询的JSON数据包含嵌套的数组。在本例中,只有最外层的数组被解包,而所有内部数组保持不变。 + 因此,隐式解包在每个路径求值步骤中只能向下进行一级。 @@ -14070,14 +14025,14 @@ lax $.track.segments.location - 在严格模式下,指定路径必须与所查询 JSON 文档的结构完全匹配,才能返回 SQL/JSON 项,因此使用此路径表达式会导致错误。要得到与宽松模式相同的结果,必须显式展开segments数组: + 在严格模式下,指定路径必须与所查询 JSON 文档的结构完全匹配,才能返回 SQL/JSON 项,因此使用此路径表达式会导致错误。要得到与宽松模式相同的结果,必须显式解包segments数组: strict $.track.segments[*].location .**访问器在宽松模式下可能产生出人意料的结果。例如,下面的查询会选出每个HR值两次: lax $.**.HR -这是因为.**访问器既选择segments数组,又选择其每个元素,而.HR访问器在宽松模式下会自动展开数组。为避免意外结果,建议将.**访问器仅用于严格模式。下面的查询只选出每个HR值一次: +这是因为.**访问器既选择segments数组,又选择其每个元素,而.HR访问器在宽松模式下会自动解包数组。为避免意外结果,建议将.**访问器仅用于严格模式。下面的查询只选出每个HR值一次: strict $.**.HR @@ -14161,7 +14116,7 @@ strict $.**.HR number - 否定;与减法不同,它可以迭代多个值 + 取负;与减法不同,可以遍历多个值。 jsonb_path_query_array('{"x": [2,3,4]}', '- $.x') @@ -14203,7 +14158,7 @@ strict $.**.HR number - 模数 (余数) + 取模(余数) jsonb_path_query('[32]', '$[0] % 10') @@ -14299,7 +14254,7 @@ strict $.**.HR string . datetime() datetime_type - (see note) + (见注) 从字符串转换过来的日期/时间值 @@ -14314,7 +14269,7 @@ strict $.**.HR string . datetime(template) datetime_type - (see note) + (见注) 使用指定的to_timestamp模板从字符串转换过来的日期/时间值 @@ -14351,7 +14306,7 @@ strict $.**.HR datetime()方法依次尝试将其输入字符串与date, timetz, time,timestamptz, 和 timestamp的ISO格式进行匹配。 - 它在第一个匹配格式时停止,并发出相应的数据类型。 + 它在第一个匹配格式时停止,并返回相应数据类型的值。 @@ -14359,26 +14314,26 @@ strict $.**.HR - datetime()datetime(template)方法使用与to_timestamp SQL函数相同的解析规则(see ),但有三个例外。 + datetime()datetime(template)方法使用与to_timestamp SQL函数相同的解析规则(参见),但有三个例外。 首先,这些方法不允许不匹配的模板模式。 - 其次,模板字符串中只允许以下分隔符:减号、句点、solidus(斜杠)、逗号、撇号、分号、冒号和空格。 + 其次,模板字符串中只允许以下分隔符:减号、句点、斜杠、逗号、撇号、分号、冒号和空格。 第三,模板字符串中的分隔符必须与输入字符串完全匹配。 - 如果需要比较不同的日期/时间类型,则应用隐式转换。 + 如果需要比较不同的日期/时间类型,则应用隐式类型转换。 date值可以转换为timestamptimestamptz, timestamp可以转换为timestamptz, time可以转换为timetz。 但是,除了第一个转换外,其他所有转换都依赖于当前设置,因此只能在时区感知的jsonpath函数中执行。 - 显示了适用的过滤器表达式元素。 + 显示了可用的过滤表达式元素。
- <type>jsonpath</type> 过滤器表达式元素 + <type>jsonpath</type> 过滤表达式元素 @@ -14527,7 +14482,7 @@ strict $.**.HR value - JSON常数null(注意,与SQL不同,与null比较可以正常工作) + JSON 常量null(注意,与SQL不同,与null比较可以正常工作) jsonb_path_query('[{"name": "Mary", "job": null}, {"name": "Michael", "job": "driver"}]', '$[*] ? (@.job == null) .name') @@ -14597,7 +14552,7 @@ strict $.**.HR boolean - 测试第一个操作数是否与第二个操作数给出的正则表达式匹配,可选使用由一串flag字符描述的修改(参见)。 + 测试第一个操作数是否与第二个操作数给出的正则表达式匹配;可以用一串flag标志字符调整匹配行为(参见)。 jsonb_path_query_array('["abc", "abd", "aBdC", "abdacb", "babc"]', '$[*] ? (@ like_regex "^ab.*c")') @@ -14652,7 +14607,7 @@ strict $.**.HR LIKE_REGEX - in SQL/JSON + 用于 SQL/JSON SQL/JSON 路径表达式允许使用like_regex过滤器,将文本与正则表达式进行匹配。例如,以下 SQL/JSON 路径查询会以不区分大小写的方式,匹配数组中所有以英语元音字母开头的字符串: @@ -14661,19 +14616,19 @@ $[*] ? (@ like_regex "^[aeiou]" flag "i") - 可选的flag字符串可以包括一个或多个字符i用于不区分大小写的匹配,m允许^$在换行时匹配,s允许.匹配换行符,q引用整个模式(将行为简化为一个简单的子字符串匹配)。 + 可选的flag字符串可以包括一个或多个字符i用于不区分大小写的匹配,m允许^$在换行时匹配,s允许.匹配换行符,q将整个模式按字面量处理(将行为简化为一个简单的子字符串匹配)。 SQL/JSON标准借用了来自LIKE_REGEX操作符的正则表达式定义,其使用了XQuery标准。 PostgreSQL目前不支持LIKE_REGEX操作符。因此,like_regex过滤器是使用中描述的POSIX正则表达式引擎来实现的。 - 这导致了与标准SQL/JSON行为的各种细微差异,这在中进行了分类。 - 但是请注意,这里描述的标志字母不兼容并不适用于SQL/JSON,因为它将XQuery标志字母翻译为符合POSIX引擎的预期。 + 这导致了与标准SQL/JSON行为的各种细微差异,这些差异列在中。 + 但是请注意,这里描述的标志字母不兼容并不适用于SQL/JSON,因为 SQL/JSON 会将 XQuery 标志字母转换为 POSIX 引擎所预期的形式。 - 请记住,like_regex的模式参数是一个JSON路径字符串文字,根据给出的规则编写。 - 这特别意味着在正则表达式中要使用的任何反斜杠都必须加倍。例如,匹配只包含数字的根文档的字符串值: + 请记住,like_regex的模式参数是一个JSON 路径字符串字面量,根据给出的规则编写。 + 这特别意味着在正则表达式中要使用的任何反斜杠都必须加倍。例如,匹配根文档中仅包含数字的字符串值: $.* ? (@ like_regex "^\\d+$") @@ -14686,11 +14641,11 @@ $.* ? (@ like_regex "^\\d+$") 序列操作函数 - sequence + 序列 - 本节描述对序列对象进行操作的函数,也称为序列生成器或简称序列。 + 本节描述用于操作序列对象(也称为序列生成器,或简称序列)的函数。 序列对象是使用创建的特殊单行表。 序列对象通常用于为表中的行生成惟一标识符。在中列出的序列函数,提供了简单的、多用户安全方法,用于从序列对象中获取连续的序列值。 @@ -14722,12 +14677,12 @@ $.* ? (@ like_regex "^\\d+$") bigint - 将序列对象推进到下一个值并返回该值。这是自动完成的:即使多个会话并发地执行nextval,每个会话也会安全地接收到不同的序列值。 - 如果序列对象是用默认形参创建的,则连续的nextval调用将返回以1开始的连续值。 + 将序列对象推进到下一个值并返回该值。这个操作是原子的:即使多个会话并发地执行nextval,每个会话也会安全地接收到不同的序列值。 + 如果序列对象是用默认参数创建的,则连续的nextval调用将返回以1开始的连续值。 其他行为可以通过在命令中使用适当的参数获得。 - 这个函数需要USAGEUPDATE权限在序列上。 + 这个函数需要序列上的USAGEUPDATE权限。 @@ -14740,16 +14695,16 @@ $.* ? (@ like_regex "^\\d+$") bigint - 设置序列对象的当前值,以及可选的它的is_called标志。 + 设置序列对象的当前值,并可选地设置其is_called标志。 双参数形式将序列的last_value字段设置为指定的值,并将其is_called字段设置为true,意味着下一个nextval将在返回值之前推进序列。 currval将报告的值也设置为指定的值。在三参数形式中,is_called可以设置为truefalsetrue与双参数形式具有相同的效果。 - 如果设置为false,下一个nextval将返回指定的值,序列推进从下面的nextval开始。 - 而且,currval报告的值在这种情况下不会改变。例如, + 如果设置为false,下一个nextval将返回指定的值,序列推进从再下一次调用nextval开始。 + 而且,currval报告的值在这种情况下不会改变。例如: -SELECT setval('myseq', 42); Next nextval will return 43 +SELECT setval('myseq', 42); 下一次 nextval 将返回 43 SELECT setval('myseq', 42, true); 同上 -SELECT setval('myseq', 42, false); Next nextval will return 42 +SELECT setval('myseq', 42, false); 下一次 nextval 将返回 42 setval返回的结果就是它的第二个参数的值。 @@ -14767,8 +14722,7 @@ SELECT setval('myseq', 42, false); Next nextvalbigint - 返回nextval在当前会话中为该序列最近获取的值。(如果在这个会话中没有为这个序列调用nextval会报告错误。) - 因为它返回的是一个会话本地值,所以它给出了一个可预测的答案,即自当前会话以来,其他会话是否执行了nextval。 + 返回当前会话中最近一次针对该序列调用nextval所获得的值。(如果当前会话从未针对该序列调用过nextval,则会报错。)由于返回的是会话局部值,无论其他会话是否在当前会话调用之后执行过nextval,结果都是可预测的。 这个函数需要序列上的USAGESELECT权限。 @@ -14833,10 +14787,10 @@ nextval('foo') 在搜索路径中查找 fo PostgreSQL 8.1 之前,序列函数的参数类型是 text,而不是 regclass;上述从文本字符串到 OID 值的转换会在每次调用时于运行期间执行。为保持向后兼容,这种能力仍然存在,但内部现在会在调用函数前,通过从 textregclass 的隐式强制转换来处理。 - 将序列函数的参数写成不加修饰的字符串字面量时,它会成为以下类型的常量:regclass。由于它实际上只是一个 OID,即使后来发生重命名、模式变更等情况,它仍会指向最初标识的序列。这种早绑定行为通常适用于列默认值和视图中的序列引用。但有时你可能希望采用后绑定,在运行时解析序列引用。要获得后期绑定行为,应强制将常量存储为text常量,而不是regclass: + 将序列函数的参数写成不加修饰的字符串字面量时,它会成为以下类型的常量:regclass。由于它实际上只是一个 OID,即使后来发生重命名、模式变更等情况,它仍会指向最初标识的序列。这种早绑定行为通常适用于列默认值和视图中的序列引用。但有时你可能希望采用后绑定,在运行时解析序列引用。要获得后绑定行为,应强制将常量存储为text常量,而不是regclass nextval('foo'::text) foo运行时被查找 -请注意,后期绑定是下列旧版本唯一支持的行为:PostgreSQL8.1 之前的版本,因此可能需要这样做来保留旧应用的语义。 +请注意,后绑定是下列旧版本唯一支持的行为:PostgreSQL8.1 之前的版本,因此可能需要这样做来保留旧应用的语义。 当然,序列函数的参数既可以是常量,也可以是表达式。如果它是文本表达式,隐式强制转换就会导致运行时查找。 @@ -14886,7 +14840,7 @@ CASE WHEN condition THEN result - CASE子句可以用于任何表达式可以出现的地方。每一个condition是一个返回boolean结果的表达式。如果结果为真,那么CASE表达式的结果就是符合条件的result,并且剩下的CASE表达式不会被处理。如果条件的结果不为真,那么以相同方式搜寻任何随后的WHEN子句。如果没有WHEN condition为真,那么CASE表达式的值就是在ELSE子句里的result。如果省略了ELSE子句而且没有条件为真,结果为空。 + CASE子句可以用于任何表达式可以出现的地方。每一个condition是一个返回boolean结果的表达式。如果结果为真,那么CASE表达式的结果就是紧随该条件后的result,并且剩下的CASE表达式不会被处理。如果条件的结果不为真,那么以相同方式搜寻任何随后的WHEN子句。如果没有WHEN condition为真,那么CASE表达式的值就是在ELSE子句里的result。如果省略了ELSE子句而且没有条件为真,结果为 null。 @@ -14930,7 +14884,7 @@ CASE expression END - 第一个expression会被计算,然后与所有在WHEN子句中的每一个value对比,直到找到一个相等的。如果没有找到匹配的,则返回在ELSE子句中的result(或者控制)。 这类似于 C 里的switch语句。 + 第一个expression会被计算,然后与所有在WHEN子句中的每一个value对比,直到找到一个相等的。如果没有找到匹配的,则返回在ELSE子句中的result(或者 null 值)。 这类似于 C 里的switch语句。 @@ -14961,11 +14915,7 @@ SELECT ... WHERE CASE WHEN x <> 0 THEN y/x > 1.5 ELSE false END; - 如中所述,在有几种情况中一个表达式的子表达式 - 会被计算多次,因此CASE只计算必要的表达式这 - 一原则并非不可打破。例如一个常量子表达式1/0通常将会在规划时导致一次 - 除零错误,即便它位于一个执行时永远也不会进入的CASE分支时也是 - 如此。 + 如所述,在多种情况下,表达式中的子表达式会在不同阶段求值,因此CASE只计算必要的子表达式这一原则并非绝对成立。例如,常量子表达式1/0通常会在规划时导致除零错误,即便它位于一个运行时永远不会进入的CASE分支中也是如此。 @@ -14989,17 +14939,19 @@ SELECT ... WHERE CASE WHEN x <> 0 THEN y/x > 1.5 ELSE false END; COALESCE(value , ...) - COALESCE函数返回参数中第一个不为 null 的值。只有所有参数都为 null 时,才返回 null。它常用于在检索数据以供显示时,用默认值替换 null 值。例如: + COALESCE函数返回参数中第一个不为 null 的值。只有所有参数都为 null 时,才返回 null。它常用于在检索数据以供显示时,用默认值替换 null 值。例如: + SELECT COALESCE(description, short_description, '(none)') ... -此表达式返回description,前提是它不为 null,否则返回short_description,前提是它不为 null,否则返回(none)。 + + 此表达式返回description,前提是它不为 null,否则返回short_description,前提是它不为 null,否则返回(none) - 所有参数都必须转换为一个公共数据类型,它将是结果的类型 (详情参见 )。 + 所有参数都必须能转换为同一个数据类型,它将是结果的类型(详情参见)。 - 和CASE表达式一样,COALESCE将不会 计算无助于判断结果的参数;也就是说,在第一个非空参数右边的参数不会被计算。这个 SQL 标准函数提供了类似于NVLIFNULL的能力,它们被用在某些其他数据库系统中。 + 和CASE表达式一样,COALESCE只计算确定结果所需的参数;也就是说,在第一个不为 null 的参数右边的参数不会被计算。这个 SQL 标准函数提供了类似于NVLIFNULL的能力,它们被用在某些其他数据库系统中。 @@ -15015,12 +14967,12 @@ SELECT COALESCE(description, short_description, '(none)') ... - 当value1value2相等时,NULLIF返回一个空值。 + 当value1value2相等时,NULLIF返回 null。 否则它返回value1。 这些可以用于执行前文给出的COALESCE示例的逆操作: SELECT NULLIF(value, '(none)') ... - 在这个示例中,如果value(none),将返回空值,否则返回value的值。 + 在这个示例中,如果value(none),将返回 null,否则返回value的值。 @@ -15055,11 +15007,11 @@ SELECT NULLIF(value, '(none)') ... - GREATESTLEAST函数从一个任意的数字表达式列表里选取最大或者最小的数值。 这些表达式必须都可以转换成一个普通的数据类型,它将会是结果类型 (参阅获取细节)。列表中的 NULL 数值将被忽略。只有所有表达式的结果都是 NULL 的时候,结果才会是 NULL。 + GREATESTLEAST函数从由任意数量的表达式组成的列表中选取最大值或最小值。这些表达式都必须能转换为同一个数据类型,该类型将作为结果类型(详情参见)。列表中的 NULL 值会被忽略。只有所有表达式的求值结果都为 NULL 时,结果才为 NULL。 - 请注意GREATESTLEAST都不是 SQL 标准,但却是很常见的扩展。某些其他数据库让它们在任何参数为 NULL 时返回 NULL,而不是在所有参数都为 NULL 时才返回 NULL。 + 请注意GREATESTLEAST都未包含在 SQL 标准中,但却是很常见的扩展。某些其他数据库让它们在任何参数为 NULL 时返回 NULL,而不是在所有参数都为 NULL 时才返回 NULL。 @@ -15070,9 +15022,9 @@ SELECT NULLIF(value, '(none)') ... 显示了可以用于数组类型的专用的操作符。 除此之外,中所示的常用比较操作符也适用于数组。 - 比较操作符逐个元素的比较数组内容,使用默认的元素数据类型的B-树比较函数,并根据第一个不同之处进行排序。 + 比较操作符逐个元素比较数组内容,使用元素数据类型的默认 B-树比较函数,并根据第一个差异进行排序。 多维数组的元素按照行序进行访问(最后的下标变化最快)。 - 如果两个数组的内容相同但维数不等,那么维度信息中的第一个不同将决定排序顺序。(这与 PostgreSQL 8.2 之前的版本有所不同:旧版本会认为内容相同的两个数组相等,即使它们的维数或下标范围不同。) + 如果两个数组的内容相同但维度信息不同,那么维度信息中的第一个不同将决定排序顺序。(这与 PostgreSQL 8.2 之前的版本有所不同:旧版本会认为内容相同的两个数组相等,即使它们的维数或下标范围不同。)
数组操作符 @@ -15100,7 +15052,7 @@ SELECT NULLIF(value, '(none)') ... 第一个数组是否包含第二个数组,也就是说,出现在第二个数组中的每个元素是否等于第一个数组中的某个元素? - (重复值不需要特殊处理,因此ARRAY[1]ARRAY[1,1]被认为包含对方。) + (重复元素不作特殊处理,因此ARRAY[1]ARRAY[1,1]被认为包含对方。) ARRAY[1,4,3] @> ARRAY[3,1,3] @@ -15142,7 +15094,8 @@ SELECT NULLIF(value, '(none)') ... anyarray - 连接两个数组。连接空(null)或空数组是一个无操作(no-op);否则,数组必须具有相同的维度数(如第一个示例所示),或者维度数相差一个(如第二个示例所示)。 + 连接两个数组。连接 null 或空数组不会产生任何效果;否则,数组必须具有相同的维数(如第一个示例所示),或维数相差一维(如第二个示例所示)。 + ARRAY[1,2,3] || ARRAY[4,5,6,7] {1,2,3,4,5,6,7} @@ -15173,7 +15126,7 @@ SELECT NULLIF(value, '(none)') ... anyarray - 将元素连接到数组的末尾(数组必须为空或一维的[one-dimensional])。 + 将元素连接到数组的末尾(数组必须为空或一维)。 ARRAY[4,5,6] || 7 @@ -15185,7 +15138,7 @@ SELECT NULLIF(value, '(none)') ...
- 参阅获取有关数组操作符行为的更多细节。有关哪些操作符支持被索引的操作,请参阅。 + 参阅获取有关数组操作符行为的更多细节。有关哪些操作符支持索引操作,请参阅 @@ -15272,8 +15225,7 @@ SELECT NULLIF(value, '(none)') ... anyarray - 返回一个包含给定值的拷贝的数组,其维数与第二个参数指定的长度相同。 - 可选的第三个参数提供每个维度的下界值(默认为全部为 1)。 + 返回用给定值的副本填充的数组,各维的长度由第二个参数指定。可选的第三个参数提供各维的下界值(默认均为1)。 array_fill(11, ARRAY[2,3]) @@ -15354,7 +15306,7 @@ SELECT NULLIF(value, '(none)') ... integer - 返回阵列中第二个参数中第一次发生的下标,如果它不存在,则返回NULL。 + 返回第二个参数在数组中首次出现的下标;若不存在,则返回NULL。 如果给出了第三个参数,则搜索从该下标开始。数组必须是一维的。比较是使用IS NOT DISTINCT FROM语义进行的,所以可以搜索NULL @@ -15372,9 +15324,9 @@ SELECT NULLIF(value, '(none)') ... integer[] - 返回作为第一个参数的数组中第二个参数所有出现的下标的数组。 + 返回第二个参数在第一个参数所给数组中所有出现位置的下标数组。 数组必须是一维的。使用IS NOT DISTINCT FROM语义完成比较,所以可以搜索NULL。 - 只有当数组为NULL时才返回NULL;如果在数组中没有找到该值,则返回空数组。 + 只有当数组为NULL时才返回NULL;如果在数组中没有找到该值,则返回空数组。 array_positions(ARRAY['A','A','B','A'], 'A') @@ -15558,7 +15510,7 @@ SELECT NULLIF(value, '(none)') ... - string_to_array 的行为与 PostgreSQL 9.1 之前的版本有两点不同。首先,输入字符串长度为零时,它返回空数组(零个元素),而不是 NULL。其次,如果分隔字符串为 NULL,该函数会将输入拆分为单个字符,而不像以前那样返回 NULL + string_to_array 的行为与 PostgreSQL 9.1 之前的版本有两点不同。首先,输入字符串长度为零时,它返回空数组(零个元素),而不是 NULL。其次,如果分隔符字符串为 NULL,该函数会将输入拆分为单个字符,而不像以前那样返回 NULL @@ -15691,7 +15643,7 @@ SELECT NULLIF(value, '(none)') ... boolean - 第一个范围是否严格符合第二个(范围)? + 第一个范围是否严格地在第二个(范围)的右边? int8range(50,60) >> int8range(20,30) @@ -15775,7 +15727,7 @@ SELECT NULLIF(value, '(none)') ... anyrange - 计算范围的差异。第二个范围必须不能包含在第一个(范围)中,以使差异不是一个单一的范围。 + 计算范围的差集。第二个范围不能被包含在第一个范围中而导致差集无法表示为单个范围。 int8range(5,15) - int8range(10,20) @@ -15837,7 +15789,7 @@ SELECT NULLIF(value, '(none)') ... anyelement - 提取范围的上限(如果范围为空或上限为无限,则为NULL)。 + 提取范围的上界(如果范围为空或上界为无限,则为NULL)。 upper(numrange(1.1,2.2)) @@ -15951,7 +15903,7 @@ SELECT NULLIF(value, '(none)') ... - lower_incupper_inclower_inf、 和 upper_inf 函数对空范围(empty range)都返回假(false)。 + lower_incupper_inclower_infupper_inf 函数对空范围都返回假。 @@ -15964,11 +15916,11 @@ SELECT NULLIF(value, '(none)') ... - 聚合函数从一个输入值的集合计算出一个单一值。 - 内置的通用聚合函数在中列出,而统计性聚合是在中列出。 + 聚合函数从一个输入值的集合计算出一个单一结果。 + 内置的通用聚合函数在中列出,而统计聚合函数在中列出。 内置的组内有序集聚合函数在中列出,而内置的组内假想集聚合在中列出。 与聚合函数紧密相关的分组操作在中列出。 - 中会解释针对聚合函数的特殊语法考虑。额外的介绍信息请参考。 + 中会解释针对聚合函数的特殊语法注意事项。更多入门信息请参考 @@ -16005,7 +15957,7 @@ SELECT NULLIF(value, '(none)') ... 将所有输入值,包括空值,收集到一个数组中。 - No + @@ -16014,15 +15966,15 @@ SELECT NULLIF(value, '(none)') ... anyarray - 将所有输入数组连接到一个更高维度的数组中。(输入必须都具有相同的维度,并且不能为空的(empty)或空值(null)。) + 将所有输入数组连接成维数增加一维的数组。(所有输入的维数必须相同,且不能是空数组或空值(NULL)。) - No + - average + 平均值 avg @@ -16081,7 +16033,7 @@ SELECT NULLIF(value, '(none)') ... bit - 计算所有非空输入值的逐位AND。 + 计算所有非空输入值的按位与。 @@ -16107,7 +16059,7 @@ SELECT NULLIF(value, '(none)') ... bit - 计算所有非空输入值的逐位OR。 + 计算所有非空输入值的按位或。 @@ -16174,7 +16126,7 @@ SELECT NULLIF(value, '(none)') ... boolean - 这是对应bool_and的SQL标准的等效物。 + 这是标准 SQL 中与bool_and等价的函数。 @@ -16197,7 +16149,7 @@ SELECT NULLIF(value, '(none)') ... 收集所有输入值,包括空值,到一个JSON数组。根据to_jsonto_jsonb将值转换为JSON。 - No + @@ -16220,10 +16172,10 @@ SELECT NULLIF(value, '(none)') ... jsonb
- 将所有键/值对收集到一个JSON对象中。关键参数强制转换为文本;值参数按照to_jsonto_jsonb进行转换。 + 将所有键/值对收集到一个JSON对象中。键参数强制转换为文本;值参数按照to_jsonto_jsonb进行转换。 值可以为空,但键不能(为空)。 - No + @@ -16231,8 +16183,8 @@ SELECT NULLIF(value, '(none)') ... 最大值 - max ( see text ) - same as input type + max ( 见说明 ) + 与输入类型相同 计算非空输入值的最大值。适用于任何数字、字符串、日期/时间或枚举类型, @@ -16249,8 +16201,8 @@ SELECT NULLIF(value, '(none)') ... 最小值 - min ( see text ) - same as input type + min ( 见说明 ) + 与输入类型相同 计算非空输入值的最小值。适用于任何数字、字符串、日期/时间或枚举类型, @@ -16277,9 +16229,9 @@ SELECT NULLIF(value, '(none)') ... bytea - 将非 null 输入值连接成一个字符串。第一个值之后的每个值前面都会放置相应的delimiter(如果它不为 null)。 + 将非 NULL 输入值连接成一个字符串。在第一个值之后,每个值前面都会放置相应的delimiter(如果它不为 NULL)。 - No + @@ -16333,31 +16285,24 @@ SELECT NULLIF(value, '(none)') ... xml - 连接非空的XML输入值(参见)。 + 连接非空的 XML 输入值(参见)。 - No + - 应该注意的是,除了count之外,这些函数在没有选择行时返回空值。 - 特别地,行数的sum返回空(null),而不是预期的零,array_agg在没有输入行时返回空(null)而不是空数组。 - coalesce函数可以在必要时用零或空数组代替空(null)。 + 需要注意,除了count之外,这些函数在没有选中任何行时都会返回空值。特别地,sum在没有输入行时返回空值,而不是预期中的零;array_agg在没有输入行时返回空值,而不是空数组。必要时,可以用coalesce函数把空值替换成零或空数组。 - 聚合函数 array_agg,json_agg, jsonb_agg,json_object_agg, jsonb_object_agg, - string_agg,和 xmlagg,以及类似的用户定义的聚合函数,根据输入值的顺序产生富有意义的不同的结果值。 - 默认情况下,这种排序是不指定的,但可以通过在聚合调用中写入ORDER BY子句来控制,如所示。 - 或者,从排序的子查询提供输入值通常也可以。例如: - + 聚合函数array_aggjson_aggjsonb_aggjson_object_aggjsonb_object_aggstring_aggxmlagg,以及类似的用户定义聚合函数,其结果值会随输入值的顺序发生实质性变化。默认情况下,输入顺序未指定,但可以在聚合调用中写入ORDER BY子句来控制,如所示。也可以用已排序的子查询提供输入值,这通常也能奏效。例如: - - 注意,如果外部查询级别包含其他处理,例如关联,则此方法可能会失败,因为这可能导致子查询的输出在计算聚合之前重新排序。 + 需要注意,如果外层查询包含连接等额外处理,这种方法可能失效,因为子查询的输出可能在计算聚合之前被重新排序。 @@ -16380,10 +16325,7 @@ SELECT count(*) FROM sometable; - 显示了统计分析中常用的聚合函数。 - (这些被分离出来仅仅是为了避免使更常用的聚合列表混乱。) - 显示为接受numeric_type的函数可用于所有类型smallint, integer,bigint, numeric, real, 和 double precision。 - 在描述中提及N时,它意味着所有输入表达式都非空的输入行数。在所有情况下,如果计算没有意义,则返回null,例如当N为0时。 + 列出了统计分析中常用的聚合函数。(将它们单独列出,只是为了避免更常用的聚合函数列表过于杂乱。)标为接受numeric_type的函数适用于smallintintegerbigintnumericrealdouble precision这些类型。描述中提到的N表示所有输入表达式都非空的输入行数。无论哪种情况,如果计算没有意义,例如N为 0,就返回 null。 @@ -16417,7 +16359,7 @@ SELECT count(*) FROM sometable; - correlation + 相关性 corr @@ -16428,14 +16370,14 @@ SELECT count(*) FROM sometable; 计算相关系数。 - Yes + - covariance - population + 协方差 + 总体 covar_pop @@ -16446,14 +16388,14 @@ SELECT count(*) FROM sometable; 计算总体协方差。 - Yes + - covariance - sample + 协方差 + 样本 covar_samp @@ -16464,7 +16406,7 @@ SELECT count(*) FROM sometable; 计算样本协方差。 - Yes + @@ -16476,9 +16418,9 @@ SELECT count(*) FROM sometable; double precision - 计算自变量的平均值,sum(X)/N. + 计算自变量的平均值,即sum(X)/N - Yes + @@ -16490,9 +16432,9 @@ SELECT count(*) FROM sometable; double precision - 计算因变量的平均值,sum(Y)/N. + 计算因变量的平均值,即sum(Y)/N - Yes + @@ -16506,13 +16448,13 @@ SELECT count(*) FROM sometable; 计算两个输入都非空的行数。 - Yes + - regression intercept + 回归截距 regr_intercept @@ -16521,9 +16463,9 @@ SELECT count(*) FROM sometable; double precision - 计算由(XY)对决定的最小二乘拟合的线性方程的Y-截距。 + 计算由(XY)数值对确定的最小二乘拟合线性方程的 y 轴截距。 - Yes + @@ -16537,13 +16479,13 @@ SELECT count(*) FROM sometable; 计算相关系数的平方。 - Yes + - regression slope + 回归斜率 regr_slope @@ -16552,9 +16494,9 @@ SELECT count(*) FROM sometable; double precision - 计算由(X, Y)对决定的最小二乘拟合的线性方程的斜率。 + 计算由(XY)数值对确定的最小二乘拟合线性方程的斜率。 - Yes + @@ -16566,10 +16508,9 @@ SELECT count(*) FROM sometable; double precision - 计算自变量的平方和 - sum(X^2) - sum(X)^2/N. + 计算自变量的平方和,即sum(X^2) - sum(X)^2/N - Yes + @@ -16581,10 +16522,9 @@ SELECT count(*) FROM sometable; double precision - 计算独立变量乘以因变量的sum of products, - sum(X*Y) - sum(X) * sum(Y)/N. + 计算自变量与因变量的乘积和,即sum(X*Y) - sum(X) * sum(Y)/N - Yes + @@ -16596,69 +16536,62 @@ SELECT count(*) FROM sometable; double precision - 计算因变量的平方和, - sum(Y^2) - sum(Y)^2/N. + 计算因变量的平方和,即sum(Y^2) - sum(Y)^2/N - Yes + - standard deviation + 标准差 stddev stddev ( numeric_type ) - double precision - for real or double precision, - otherwise numeric + 对于realdouble precision输入,返回double precision;否则返回numeric - 这是stddev_samp的一个历史别称。 + 这是stddev_samp的一个历史别名。 - Yes + - standard deviation - population + 标准差 + 总体 stddev_pop stddev_pop ( numeric_type ) - double precision - for real or double precision, - otherwise numeric + 对于realdouble precision输入,返回double precision;否则返回numeric 计算输入值的总体标准差。 - Yes + - standard deviation - sample + 标准差 + 样本 stddev_samp stddev_samp ( numeric_type ) - double precision - for real or double precision, - otherwise numeric + 对于realdouble precision输入,返回double precision;否则返回numeric 计算输入值的样本标准差。 - Yes + @@ -16667,54 +16600,48 @@ SELECT count(*) FROM sometable; variance variance ( numeric_type ) - double precision - for real or double precision, - otherwise numeric + 对于realdouble precision输入,返回double precision;否则返回numeric - 这是 var_samp 的一个历史别称。 + 这是 var_samp 的一个历史别名。 - Yes + - variance - population + 方差 + 总体 var_pop var_pop ( numeric_type ) - double precision - for real or double precision, - otherwise numeric + 对于realdouble precision输入,返回double precision;否则返回numeric - 计算输入值的总体方差(总体标准差的平方)。 + 计算输入值的总体方差(总体标准差的平方)。 - Yes + - variance - sample + 方差 + 样本 var_samp var_samp ( numeric_type ) - double precision - for real or double precision, - otherwise numeric + 对于realdouble precision输入,返回double precision;否则返回numeric - 计算输入值的样本方差(样本标准差的平方)。 + 计算输入值的样本方差(样本标准差的平方)。 - Yes + @@ -16725,11 +16652,11 @@ SELECT count(*) FROM sometable; 这些函数有时被称为逆分布函数。 它们的聚合输入通过ORDER BY引入,还可以接受未聚合的直接参数,但后者只计算一次。 所有这些函数在其聚合输入中都忽略空(null)值。 - 对于使用fraction参数的函数,分数值必须在 0 到 1 之间;否则会报错。但是,null 的 fraction 值只会产生一个 null 结果。 + 对于使用fraction参数的函数,比例值必须在 0 到 1 之间;否则会报错。但是,null 的 fraction 值只会产生一个 null 结果。 - ordered-set aggregate + 有序集聚合 内置 @@ -16760,16 +16687,16 @@ SELECT count(*) FROM sometable; - mode - statistical + 众数 + 统计 mode () WITHIN GROUP ( ORDER BY anyelement ) anyelement - 计算mode,即聚合参数最频繁的值(如果有多个相同频繁的值,第一个可以任意选择)。聚合参数必须是可排序类型。 + 计算众数,即聚合参数中出现次数最多的值(若多个值的出现次数相同且最多,则任意选择其中第一个)。聚合参数必须是可排序类型。 - No + @@ -16787,9 +16714,9 @@ SELECT count(*) FROM sometable; 计算连续百分位点,该值对应于聚合参数值有序集合中的指定fraction。 - 如果需要,这将在相邻的输入项之间插入。 + 必要时会在相邻输入项之间进行插值。 - No + @@ -16804,7 +16731,7 @@ SELECT count(*) FROM sometable; 计算多个连续百分位点。结果是一个与fractions参数具有相同维度的数组,其中每个非 null 元素都被替换为对应百分位点的值(必要时会进行插值)。 - No + @@ -16820,7 +16747,7 @@ SELECT count(*) FROM sometable; 计算离散百分位数,即聚合参数值的有序集合中的第一个值,该值在排序中的位置等于或超过指定的fraction。 聚合参数必须是可排序类型。 - No + @@ -16833,14 +16760,14 @@ SELECT count(*) FROM sometable; 结果是一个与fractions参数具有相同维数的数组,每个非空元素都被对应于该百分位数的输入值替换。 聚合参数必须是可排序类型。 - No + - hypothetical-set aggregate + 假想集聚合 内置 @@ -16876,52 +16803,52 @@ SELECT count(*) FROM sometable; rank - hypothetical + 假设行 rank ( args ) WITHIN GROUP ( ORDER BY sorted_args ) bigint - 计算假设行的排名,包括间隔,就是说在它的同等行组中第一行的行号。 + 计算假设行的排名,允许空缺;即该行所属同等行组中第一行的行号。 - No + dense_rank - hypothetical + 假设行 dense_rank ( args ) WITHIN GROUP ( ORDER BY sorted_args ) bigint - 计算假设行的排名,没有间隔;这个功能有效地计数同等行组。 + 计算假设行的排名,没有空缺;此函数实际上对同等行组进行计数。 - No + percent_rank - hypothetical + 假设行 percent_rank ( args ) WITHIN GROUP ( ORDER BY sorted_args ) double precision - 计算假设行的相关排行,也就是(rank - 1) / (total rows - 1)。取值范围为 0 到 1(含)。 + 计算假设行的相对排名,即(rank - 1)/(总行数 - 1)。取值范围为 0 到 1(含)。 - No + cume_dist - hypothetical + 假设行 cume_dist ( args ) WITHIN GROUP ( ORDER BY sorted_args ) double precision @@ -16929,7 +16856,7 @@ SELECT count(*) FROM sometable; 计算累积分布,也就是(位于假设行之前或与假设行同等的行数)/(总行数)。取值范围为 1/N 到 1。 - No + @@ -16962,8 +16889,7 @@ SELECT count(*) FROM sometable; integer - 返回一个位掩码以指示哪个GROUP BY表达式没有包含在当前分组集中。 - 比特位分配给最右边的参数,对应于最低有效位;如果对应的表达式包含在生成当前结果行的分组集的分组条件中,则每个位为 0,否则为 1。 + 返回一个位掩码,指示哪些GROUP BY表达式未包含在当前分组集中。分配比特位时,最右侧参数对应最低有效位;如果相应表达式包含在生成当前结果行的分组集的分组条件中,该位为 0,否则为 1。 @@ -17013,7 +16939,7 @@ SELECT count(*) FROM sometable; - 除了这些函数之外,任何内置的或用户定义的普通聚合(例如非有序集或假想集聚合)都可以作为窗口函数使用;关于内置聚合的列表,参见。 + 除了这些函数之外,任何内置的或用户定义的普通聚合(即不属于有序集或假想集聚合)都可以作为窗口函数使用;关于内置聚合的列表,参见。 聚合函数只有在调用后带有OVER子句时才作为窗口函数;否则,它们就是普通聚合,并为整个结果集返回一行。 @@ -17042,7 +16968,7 @@ SELECT count(*) FROM sometable; bigint - 返回其分区内的当前行数,从1开始计数。 + 返回当前行在其分区内的编号,从 1 开始计数。 @@ -17055,7 +16981,7 @@ SELECT count(*) FROM sometable; bigint - 返回当前行的排名,包含间隔;即同等行组中第一行的row_number。 + 返回当前行的排名,允许空缺;即同等行组中第一行的row_number @@ -17068,7 +16994,7 @@ SELECT count(*) FROM sometable; bigint - 返回当前行的排名,不包括间隔;这个功能有效地计数同等行组。 + 返回当前行的排名,没有空缺;此函数实际上对同等行组进行计数。 @@ -17107,7 +17033,7 @@ SELECT count(*) FROM sometable; integer - 返回一个从1到参数值的整数,并将分区划分为尽可能相等的值。 + 返回从 1 到参数值的整数,将分区尽可能均等地划分。 @@ -17122,9 +17048,7 @@ SELECT count(*) FROM sometable; anyelement - 返回分区中在当前行之前offset行的value;如果没有这样的行,则返回default(必须与value相同的类型)。 - offsetdefault都是针对当前行求值的。 - 如果省略,offset默认为1,defaultNULL。 + 返回在分区内当前行之前offset行处计算的value;如果没有这样的行,则返回default(其类型必须与value相同)。offsetdefault都针对当前行求值。如果省略,offset默认为 1,default默认为NULL @@ -17139,10 +17063,7 @@ SELECT count(*) FROM sometable; anyelement - 返回分区中在当前行之后offset行的value; - 如果没有这样的行,则返回default(必须与value相同的类型)。 - offsetdefault都是针对当前行求值的。 - 如果省略,offset默认为1,defaultNULL。 + 返回在分区内当前行之后offset行处计算的value;如果没有这样的行,则返回default(其类型必须与value相同)。offsetdefault都针对当前行求值。如果省略,offset默认为 1,default默认为NULL @@ -17203,8 +17124,8 @@ SELECT count(*) FROM sometable; 当一个聚合函数被用作窗口函数时,它将在当前行的窗口帧内的行上聚合。 - 一个使用ORDER BY和默认窗口帧定义的聚合产生一种运行时求和类型的行为,这可能是或者不是想要的结果。 - 为了获取在整个分区上的聚合,忽略ORDER BY或者使用ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING。 + 一个使用ORDER BY和默认窗口帧定义的聚合产生一种累计求和类型的行为,这可能是或者不是想要的结果。 + 为了获取在整个分区上的聚合,省略ORDER BY或者使用ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING。 其它窗口帧声明可以用来获得其它的效果。 @@ -17213,7 +17134,7 @@ SELECT count(*) FROM sometable; SQL 标准为leadlagfirst_valuelast_valuenth_value定义了一个RESPECT NULLSIGNORE NULLS选项。 这在PostgreSQL中没有实现:行为总是与标准的默认相同,即RESPECT NULLS。 - 同样,标准中用于nth_valueFROM FIRSTFROM LAST选项没有实现: 只有支持默认的FROM FIRST行为(你可以通过反转ORDER BY的排序达到FROM LAST的结果)。 + 同样,标准中用于nth_valueFROM FIRSTFROM LAST选项没有实现: 只支持默认的FROM FIRST行为(你可以通过反转ORDER BY的排序达到FROM LAST的结果)。 @@ -17247,11 +17168,11 @@ SELECT count(*) FROM sometable; - subquery + 子查询 - 本节描述PostgreSQL中可用的SQL兼容的子查询表达式。所有本节中成文的表达式都返回布尔值(真/假)结果。 + 本节描述PostgreSQL中可用的SQL兼容的子查询表达式。本节介绍的所有表达式形式都返回布尔值(真/假)结果。 @@ -17266,7 +17187,7 @@ EXISTS (subquery) - 子查询可以引用来自周围的查询的变量,这些变量在该子查询的任何一次计算中都起常量的作用。 + 子查询可以引用外层查询的变量,这些变量在该子查询的任何一次计算中都起常量的作用。 @@ -17278,7 +17199,7 @@ EXISTS (subquery) - 下面这个简单的示例类似在col2上的一次内联接,但是它为每个 tab1的行生成最多一个输出,即使存在多个匹配tab2的行也如此∶ + 下面这个简单的示例类似在col2上的一次内连接,但是它为每个 tab1的行最多生成一行输出,即使存在多个匹配tab2的行也如此: SELECT col1 FROM tab1 @@ -17295,15 +17216,15 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 右手边是一个圆括弧括起来的子查询, 它必须正好只返回一个列。左手边表达式将被计算并与子查询结果逐行进行比较。 如果找到任何等于子查询行的情况,那么IN的结果就是。 如果没有找到相等行,那么结果是(包括子查询没有返回任何行的情况)。 + 右手边是一个圆括号括起来的子查询,它必须恰好返回一列。左手边表达式会被求值,并与子查询结果逐行比较。如果找到任意相等的子查询行,那么IN的结果就是。如果没有找到相等行,那么结果就是(包括子查询不返回任何行的情况)。 - 请注意如果左手边表达式得到空值,或者没有相等的右手边值, 并且至少有一个右手边行得到空值,那么IN结构的结果将是空值,而不是假。这个行为是遵照 SQL 处理空值的一般规则的。 + 请注意,如果左侧表达式得到空值,或者右侧没有相等的值且至少有一行得到空值,则IN结构的结果将是空值,而不是假。这符合 SQL 对空值布尔组合的一般规则。 - 和EXISTS一样,假设子查询将被完成运行完全是不明智的。 + 和EXISTS一样,假定子查询一定会完整运行并不明智。 @@ -17311,7 +17232,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 这种形式的IN的左手边是一个行构造器, 如中所述。 右手边是一个圆括弧子查询,它必须返回和左手边返回的行中表达式所构成的完全一样多的列。 左手边表达式将被计算并与子查询结果逐行进行比较。如果找到任意相等的子查询行,则IN的结果为。如果没有找到相等行, 那么结果为(包括子查询不返回行的情况)。 + 这种形式的IN左手边是一个行构造器,如中所述。右手边是一个圆括号括起来的子查询,它必须返回与左手边行中表达式数量完全相同的列数。左手边表达式会被求值,并与子查询结果逐行比较。如果找到任意相等的子查询行,则IN的结果为。如果没有找到相等行,那么结果为(包括子查询不返回任何行的情况)。 @@ -17327,15 +17248,15 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 右手边是一个用圆括弧包围的子查询,它必须返回正好一个列。左手边表达式将被计算并与子查询结果逐行进行比较。 如果只找到不相等的子查询行(包括子查询不返回行的情况),那么NOT IN的结果是。 如果找到任何相等行,则结果为。 + 右手边是一个圆括号括起来的子查询,它必须恰好返回一列。左手边表达式会被求值,并与子查询结果逐行比较。如果只找到不相等的子查询行(包括子查询不返回任何行的情况),那么NOT IN的结果是。如果找到任何相等行,则结果为 - 请注意如果左手边表达式得到空值,或者没有相等的右手边值, 并且至少有一个右手边行得到空值,那么NOT IN结构的结果将是空值,而不是真。这个行为是遵照 SQL 处理空值的一般规则的。 + 请注意,如果左侧表达式得到空值,或者右侧没有相等的值且至少有一行得到空值,则NOT IN结构的结果将是空值,而不是真。这符合 SQL 对空值布尔组合的一般规则。 - 和EXISTS一样,假设子查询将被完成运行完全是不明智的。 + 和EXISTS一样,假定子查询一定会完整运行并不明智。 @@ -17343,7 +17264,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 这种形式的NOT IN的左手边是一个行构造器, 如中所述。 右手边是一个圆括弧子查询,它必须返回和左手边返回的行中表达式所构成的完全一样多的列。 左手边表达式将被计算并与子查询结果逐行进行比较。如果找到不等于子查询行的行,则NOT IN的结果为。如果找到相等行, 那么结果为(包括子查询不返回行的情况)。 + 这种形式的NOT IN左侧是一个行构造器,如中所述。右侧是一个用圆括号括起来的子查询,必须返回与左侧行中表达式数量完全相同的列数。对左侧表达式求值后,将其按行与子查询结果的每一行比较。如果只找到不相等的子查询行(包括子查询不返回任何行的情况),则NOT IN的结果为。如果找到任何相等行,则结果为 @@ -17368,11 +17289,11 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 请注意如果没有任何成功并且至少有一个右手边行为该操作符结果生成空值, 那么ANY结构的结果将是空值,而不是假。 这个行为是遵照 SQL 处理空值布尔组合的一般规则制定的。 + 请注意,如果没有任何比较返回真,并且至少有一个右侧行的操作符结果为空值,则ANY结构的结果将是空值,而不是假。这符合 SQL 对空值布尔组合的一般规则。 - 和EXISTS一样,假设子查询将被完成运行完全是不明智的。 + 和EXISTS一样,假定子查询一定会完整运行并不明智。 @@ -17381,7 +17302,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 这种形式的左侧是一个行构造器,如所述。右侧是一个用括号括起来的子查询,它必须返回与左侧行中表达式数量完全相同的列数。左侧表达式会被求值,并使用给定的operator与子查询结果的每一行逐行比较。如果比较对任何子查询行返回真,则ANY的结果为。如果比较对每一个子查询行都返回假,则结果为(包括子查询不返回行的情况)。如果比较对任何行都不返回真,并且至少有一次比较返回 NULL,则结果为 NULL。 + 这种形式的ANY左侧是一个行构造器,如所述。右侧是一个用括号括起来的子查询,它必须返回与左侧行中表达式数量完全相同的列数。左侧表达式会被求值,并使用给定的operator与子查询结果的每一行逐行比较。如果比较对任何子查询行返回真,则ANY的结果为。如果比较对每一个子查询行都返回假,则结果为(包括子查询不返回行的情况)。如果比较对任何行都不返回真,并且至少有一次比较返回 NULL,则结果为 NULL。 @@ -17397,7 +17318,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 这种形式的 ALL 右侧是一个用括号括起来的子查询,它必须只返回一列。左侧表达式会被求值,并使用给定的 operator 与子查询结果的每一行进行比较。该操作符必须产生布尔结果。如果所有行都得到真(包括子查询没有返回任何行的情况),ALL 的结果就是。如果发现任何假值结果,结果就是。如果比较对任何行都不返回假,并且至少有一次比较返回 NULL,则结果为 NULL。 + 右侧是一个用圆括号括起来的子查询,必须恰好返回一列。左侧表达式会被求值,并使用给定的operator与子查询结果的每一行进行比较。该操作符必须产生布尔结果。如果所有行都得到真(包括子查询不返回任何行的情况),则ALL的结果为。如果得到任何假值结果,则结果为。如果与任何子查询行的比较都不返回假,并且至少有一次比较返回 NULL,则结果为 NULL。 @@ -17405,7 +17326,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 和EXISTS一样,假设子查询将被完成运行完全是不明智的。 + 和EXISTS一样,假定子查询一定会完整运行并不明智。 @@ -17434,7 +17355,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 左手边是一个行构造器,如所述。 右手边是一个圆括弧括起来的子查询,该查询必须返回和左手边行中表达式数目完全一样的列。 另外,该子查询不能返回超过一行的数量(如果它返回零行,那么结果就是空值)。 左手边被计算并逐行与右手边的子查询结果行比较。 + 左侧是一个行构造器,如所述。右侧是一个用圆括号括起来的子查询,必须返回与左侧行中表达式数量完全相同的列数。此外,该子查询不能返回超过一行;如果它返回零行,则结果为空值。对左侧求值后,将所得的行与子查询返回的唯一一行进行比较。 @@ -17473,12 +17394,12 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 逐行比较 + 行比较 比较 - 逐行 + 复合类型 @@ -17495,7 +17416,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 本节描述几个特殊的结构,用于在值的组之间进行多重比较。这些形式语法上和前面一节的子查询形式相关,但是不涉及子查询。 这种形式涉及的数组子表达式是PostgreSQL的扩展; 其它的是SQL兼容的。所有本节记录的表达式形式都返回布尔(Boolean)结果(真/假)。 + 本节描述几个特殊的结构,用于在值的组之间进行多重比较。这些形式语法上和前面一节的子查询形式相关,但是不涉及子查询。 涉及数组子表达式的形式是PostgreSQL的扩展; 其余形式是SQL兼容的。本节介绍的所有表达式形式都返回布尔(Boolean)结果(真/假)。 @@ -17505,7 +17426,8 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); expression IN (value , ...) - 右侧是用圆括号括起的表达式列表。结果为true,条件是左侧表达式的结果等于右侧表达式中的任意一个。这是以下写法的简写: + 右侧是一个用圆括号括起来的表达式列表。如果左侧表达式的结果等于右侧任一表达式的结果,则结果为。这等价于以下写法: + expression = value1 OR expression = value2 @@ -17526,7 +17448,8 @@ OR expression NOT IN (value , ...) - 右侧是用圆括号括起的表达式列表。结果为true,条件是左侧表达式的结果与右侧的所有表达式都不相等。这是以下写法的简写: + 右侧是一个用圆括号括起来的表达式列表。如果左侧表达式的结果与右侧所有表达式的结果都不相等,则结果为。这等价于以下写法: + expression <> value1 AND expression <> value2 @@ -17548,7 +17471,7 @@ AND - <literal>ANY</literal>/<literal>SOME</literal> (array) + <literal>ANY</literal>/<literal>SOME</literal>(数组) expression operator ANY (array expression) @@ -17569,7 +17492,7 @@ AND - <literal>ALL</literal> (array) + <literal>ALL</literal>(数组) expression operator ALL (array expression) @@ -17593,20 +17516,7 @@ AND - 每一边都是一个行构造器, - 如在中描述的那样。 - 这两个行构造器必须具有相同数量的字段。 - 给定的operator应用于每一对 - 对应的字段。(由于字段可能是不同类型的,这意味着每对可能选择不同的具体操作符。) - 所有选定的操作符必须是某个B-树操作符类的成员,或者是B-树操作符类的=成员的否定形式, - 这意味着只有当operator是 - =、 - <>、 - <、 - <=、 - >或 - >=时才可能进行行构造器比较, - 或者具有类似于这些操作符的语义。 + 两侧都是行构造器,如所述。两个行构造器必须具有相同数量的字段。给定的operator应用于每一对对应字段。(由于字段可能具有不同的类型,因此可能为各对字段选择不同的具体操作符。)所选操作符必须是某个 B-树操作符类的成员,或者是 B-树操作符类中=成员的否定操作符。这意味着只有当operator=<><<=>>=,或具有与这些操作符类似的语义时,才可以进行行构造器比较。 @@ -17651,21 +17561,21 @@ AND - SQL 规范要求在结果依赖于比较两个 NULL 值或者一个 NULL 与一个非 NULL 时逐行比较返回 NULL。 + SQL 规范要求在结果依赖于比较两个 NULL 值或者一个 NULL 与一个非 NULL 时行比较返回 NULL。 PostgreSQL只有在比较两个行构造器(如)的结果或者比较一个行构造器与一个子查询的输出时才这样做(如中所述)。 - 在其他比较两个复合类型值的环境中,两个 NULL 域值被认为相等,并且一个 NULL 被认为大于一个非 NULL。 + 在其他比较两个复合类型值的环境中,两个 NULL 字段值被认为相等,并且一个 NULL 被认为大于一个非 NULL。 为了得到复合类型的一致的排序和索引行为,这样做是必要的。 - 每一边都会被计算并且它们会被逐行比较。当operator是 + 对两侧分别求值后,按行进行比较。当operator=<><<=>或者 - >=时或者具有与这些类似的语义时,允许复合类型的比较(更准确地说,如果一个操作符是一个 B-树操作符类的成员,或者是一个 B-树操作符类的=成员的否定词,它就可以是一个行比较操作符)。 - 上述操作符的行为与用于行构造器(见)的IS [ NOT ] DISTINCT FROM相同。 + >=时或者具有与这些类似的语义时,允许复合类型的比较(更准确地说,如果一个操作符是一个 B-树操作符类的成员,或者是一个 B-树操作符类的=成员的否定操作符,它就可以是一个行比较操作符)。 + 上述操作符的默认行为与用于行构造器(见)的IS [ NOT ] DISTINCT FROM相同。 @@ -17676,9 +17586,9 @@ AND *<=*>以及 *>=。 - 这些操作符比较两行的内部二进制表达。即使两行用相等操作符的比较为真,两行也可能具有不同的二进制表达。 - 行在这些比较操作符之下的排序是决定性的,其他倒没什么意义。 - 这些操作符在内部被用于物化视图并且可能对其他如复制和B-树复制(参见 )之类的特殊功能有用,但是它们并不打算用在书写查询这类普通用途中。 + 这些操作符比较两行的内部二进制表示。即使两行用相等操作符的比较为真,两行也可能具有不同的二进制表示。 + 使用这些比较操作符得到的行排序是确定的,但除此之外没有其他意义。 + 这些操作符在内部被用于物化视图并且可能对其他如复制和 B-树去重(参见 )之类的特殊功能有用,但是它们并不打算用在书写查询这类普通用途中。 @@ -17692,12 +17602,12 @@ AND - 本节描述那些可能返回多于一行的函数。目前这个类中被使用最广泛的是级数生成函数, 如所述。其他更特殊的集合返回函数在本手册的其他地方描述。 - 组合多集合返回函数的方法可见。 + 本节描述那些可能返回多于一行的函数。目前这个类中被使用最广泛的是序列生成函数, 如所述。其他更特殊的集合返回函数在本手册的其他地方描述。 + 组合多个集合返回函数的方法可见 - 级数生成函数 + 序列生成函数 @@ -17749,7 +17659,8 @@ AND
- step为正数时,如果start大于stop,则返回零行。反之,当step为负数时,如果start小于stop,则返回零行。如果任一输入为NULL,也返回零行。如果step为零,则会报错。下面是一些示例: + step为正数时,如果start大于stop,则返回零行。反之,当step为负数时,如果start小于stop,则返回零行。如果任一输入为NULL,也返回零行。如果step为零,则会报错。下面是一些示例: + SELECT * FROM generate_series(2,4); generate_series ----------------- @@ -17779,7 +17690,7 @@ SELECT generate_series(1.1, 4, 1.3); 3.7 (3 rows) --- this example relies on the date-plus-integer operator: +-- 此示例使用日期加整数的操作符: SELECT current_date + s.a AS dates FROM generate_series(0,14,7) AS s(a); dates ------------ @@ -17832,7 +17743,7 @@ SELECT * FROM generate_series('2008-03-01 00:00'::timestamp, setof integer - 生成一个包含给定数组第dim维度的有效下标的序列。 + 生成一个包含给定数组第dim维的有效下标的序列。 @@ -17842,7 +17753,7 @@ SELECT * FROM generate_series('2008-03-01 00:00'::timestamp, setof integer - 生成一个包含给定数组第dim维度的有效下标的序列。当reverse为真时,以相反的顺序返回序列。 + 生成一个包含给定数组第dim维的有效下标的序列。当reverse为真时,以相反的顺序返回序列。 @@ -17851,9 +17762,9 @@ SELECT * FROM generate_series('2008-03-01 00:00'::timestamp, generate_subscripts是一个快捷函数,它为给定数组的指定维度生成一组合法的下标。 - 对于不具有请求维度的数组返回零行,对于任何输入为NULL数组也返回零行。下面是一些示例: + 如果数组不具有所请求的维度,或者任一输入为NULL,则返回零行。下面是一些示例: --- basic usage: +-- 基本用法: SELECT generate_subscripts('{NULL,1,NULL,2}'::int[], 1) AS s; s --- @@ -17863,8 +17774,8 @@ SELECT generate_subscripts('{NULL,1,NULL,2}'::int[], 1) AS s; 4 (4 rows) --- presenting an array, the subscript and the subscripted --- value requires a subquery: +-- 展示数组、下标和下标对应的值 +-- 需要使用子查询: SELECT * FROM arrays; a -------------------- @@ -17883,7 +17794,7 @@ FROM (SELECT generate_subscripts(a, 1) AS s, a FROM arrays) foo; {100,200,300} | 3 | 300 (5 rows) --- unnest a 2D array: +-- 展开二维数组: CREATE OR REPLACE FUNCTION unnest2(anyarray) RETURNS SETOF anyelement AS $$ select $1[i][j] @@ -17903,13 +17814,12 @@ SELECT * FROM unnest2(ARRAY[[1,2],[3,4]]); - ordinality + 序号 FROM子句中的函数后面加上WITH ORDINALITY时,一个bigint列会追加到函数的输出列中,其值从 1 开始,对函数输出的每一行递增 1。这种方式对集合返回函数尤其有用,例如unnest()。 - --- set returning function WITH ORDINALITY: +-- 集合返回函数与 WITH ORDINALITY: SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); ls | n -----------------+---- @@ -17942,7 +17852,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); 系统信息函数和操作符 - 展示了多个可以抽取会话和系统信息的函数。 + 列出了多个用于提取会话和系统信息的函数。 @@ -17981,7 +17891,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); name - 返回当前数据库的名称。(在SQL标准中数据库被称为catalogs,因此current_catalog是该标准的拼写方式。) + 返回当前数据库的名称。(SQL 标准将数据库称为目录(catalogs),因此current_catalog是标准中的写法。) @@ -17994,7 +17904,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); text - 返回当前所执行查询的文本,由客户端提交的(可能包含一个以上的语句)。 + 返回客户端提交的当前正在执行的查询文本(可能包含多条语句)。 @@ -18017,8 +17927,8 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); current_schema - schema - current + 模式 + 当前 current_schema name @@ -18039,16 +17949,14 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); current_schemas - search path - current + 搜索路径 + 当前 current_schemas ( include_implicit boolean ) name[]
- 返回当前在有效搜索路径中的所有模式的名称的数组,以优先级顺序。 - (当前 设置中与已存在的、可搜索模式不相符的项将被省略。) - 如果布尔参数为true,则类似pg_catalog的隐式搜索的系统模式将包含在结果中。 + 返回当前有效搜索路径中所有模式名称的数组,按优先级排序。(当前设置中不对应于已存在且可搜索的模式的项会被省略。)如果布尔参数为true,结果还会包含pg_catalog等隐式搜索的系统模式。 @@ -18058,8 +17966,8 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); current_user - user - current + 用户 + 当前 current_user name @@ -18078,7 +17986,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); inet
- 返回当前客户端的IP地址,如果当前连接是通过Unix-域套接字则返回NULL + 返回当前客户端的 IP 地址;如果当前连接通过 Unix 域套接字建立,则返回NULL @@ -18091,7 +17999,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); integer
- 返回当前客户端的IP端口号,如果当前连接是通过Unix-域套接字则返回NULL。 + 返回当前客户端的IP端口号,如果当前连接是通过Unix 域套接字则返回NULL @@ -18104,7 +18012,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); inet
- 返回服务器接受当前连接的IP地址,如果当前连接是通过Unix-域套接字则返回NULL。 + 返回服务器接受当前连接的IP地址,如果当前连接是通过Unix 域套接字则返回NULL @@ -18117,7 +18025,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); integer - 返回服务器接受当前连接的IP端口号,如果当前连接是通过Unix-域套接字则返回NULL。 + 返回服务器接受当前连接的IP端口号,如果当前连接是通过Unix 域套接字则返回NULL @@ -18143,12 +18051,10 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); integer[] - 返回阻止服务器进程的会话的进程ID数组,该进程ID与指定的进程ID一起获取锁定,如果没有这样的服务器进程或者没有被阻塞,则返回一个空数组。 + 返回一个数组,包含阻止指定进程 ID 对应的服务器进程获取锁的会话进程 ID;如果不存在这样的服务器进程,或该进程未被阻塞,则返回空数组。 - 如果一个服务器进程持有一个与被阻塞进程的锁请求冲突的锁(硬阻塞),或者正在等待一个与被阻塞进程的锁请求冲突并且在等待队列中位于其前面的锁(软阻塞),那么这个服务器进程就会阻塞另一个服务器进程。 - 当使用并行查询时结果总是列出客户端可见的进程ID(即pg_backend_pid的结果),即使实际的锁是由子工作进程持有或等待的。 - 因此,结果中可能存在重复的pid。还要注意当准备好的事务持有冲突锁时,它将用零进程ID表示。 + 一个服务器进程会在以下情况下阻塞另一个进程:它持有与被阻塞进程请求的锁冲突的锁(硬阻塞);或者它正在等待一个会与被阻塞进程请求的锁冲突的锁,并且在等待队列中位于被阻塞进程之前(软阻塞)。使用并行查询时,即使实际持锁或等待锁的是子工作进程,结果也始终列出客户端可见的进程 ID(即pg_backend_pid的结果)。因此,结果中可能出现重复的 PID。另外,如果持有冲突锁的是一个预备事务,结果中会用进程 ID 0 表示它。 频繁调用这个函数可能会对数据库性能产生一些影响,因为它需要在短时间内独占访问锁管理器的共享状态。 @@ -18164,8 +18070,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); timestamp with time zone - 返回服务器配置文件最后加载的时间。如果当前会话当时是活跃的,那么这将是会话本身重新读取配置文件的时间(因此在不同的会话中读取会稍有不同)。 - 否则,就是postmaster进程重新读取配置文件的时间。 + 返回服务器配置文件最近一次加载的时间。如果当时当前会话已经存在,则返回该会话自身重新读取配置文件的时间(因此不同会话中的返回时间会略有不同)。否则,返回 postmaster 进程重新读取配置文件的时间。 @@ -18175,16 +18080,16 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); pg_current_logfile - Logging - pg_current_logfile函数 + 日志记录 + pg_current_logfile 函数 current_logfiles - 和pg_current_logfile函数 + 和pg_current_logfile 函数 - Logging - current_logfiles文件和pg_current_logfile函数 + 日志记录 + current_logfiles 文件和pg_current_logfile 函数 pg_current_logfile ( text ) text @@ -18262,7 +18167,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); double precision - 返回当前被等待处理的通知所占用的异步通知队列最大尺寸的分数(0–1)。更多信息请参见。 + 返回待处理通知当前占用的空间占异步通知队列最大容量的比例(0–1)。更多信息请参见 @@ -18288,11 +18193,11 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); integer[] - 返回一个进程ID数组,该进程ID是阻塞服务器进程获取安全快照的会话的进程ID数组,如果没有这样的服务器进程或者没有阻塞,则返回一个空数组。 + 返回一个数组,包含阻止指定进程 ID 对应的服务器进程获取安全快照的会话进程 ID;如果不存在这样的服务器进程,或该进程未被阻塞,则返回空数组。 运行SERIALIZABLE事务的会话会阻止SERIALIZABLE READ ONLY DEFERRABLE事务获取快照,直到后者确定可以安全地避免获取谓词锁。 - 关于可串行化和可延迟事务的更多信息,请参见。 + 关于可序列化和可延迟事务的更多信息,请参见 频繁调用这个函数可能会对数据库性能产生一些影响,因为它需要在短时间内访问谓词锁管理器的共享状态。 @@ -18308,7 +18213,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); integer - 返回当前嵌套层次的PostgreSQL触发器(如果没有调用则为 0,直接或间接,从一个触发器内部开始)。 + 返回PostgreSQL触发器的当前嵌套层级(如果不是从触发器内部直接或间接调用,则为 0)。 @@ -18321,7 +18226,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); name - 返回会话用户名. + 返回会话用户名。 @@ -18338,7 +18243,8 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); - + + version @@ -18347,9 +18253,12 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); text - 返回描述PostgreSQL服务器的版本的字符串。 - 你还可以从 中获得此信息,或者对于机器可读的版本,使用。 - 软件开发人员可以使用server_version_num(从8.2起可用)或,而不是解析文本版本。 + 返回描述PostgreSQL + 服务器版本的字符串。你还可以从 + 获得此信息,或者对于机器可读的 + 版本,使用。软件 + 开发人员应该使用server_version_num(自 8.2 起可用) + 或,而不是解析文本版本。 @@ -18359,32 +18268,21 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); - current_catalogcurrent_rolecurrent_schemacurrent_usersession_useruserSQL里有特殊的语法地位: 它们被调用时结尾不要跟着圆括号。 - 在 PostgreSQL 中,圆括号可以有选择性地被用于current_schema,但是不能和其他的一起用。 + current_catalogcurrent_rolecurrent_schemacurrent_usersession_useruserSQL中具有特殊语法:调用时不得在后面加圆括号。在 PostgreSQL 中,current_schema可以选择加圆括号,其他函数则不可以。 - session_user通常是发起当前数据库连接的用户,不过超级用户可以用修改这个设置。 - current_user是用于权限检查的用户标识。通常, 它总是等于会话用户,但是可以被改变。 - 它也会在函数执行的过程中随着属性SECURITY DEFINER的改变而改变。 - 在 Unix 的说法里,那么会话用户是真实用户,而当前用户是有效用户。 - current_role以及usercurrent_user的同义词(SQL标准在current_rolecurrent_user之间做了区分,但PostgreSQL不区分,因为它把用户和角色统一成了一种实体)。 + session_user通常是发起当前数据库连接的用户,但超级用户可以用修改此设置。current_user是用于权限检查的用户标识,通常等于会话用户,但可以用更改。在执行具有SECURITY DEFINER属性的函数期间,它也会改变。用 Unix 的术语来说,会话用户是真实用户,当前用户是有效用户current_roleusercurrent_user的同义词。(SQL 标准区分current_rolecurrent_user,但PostgreSQL不区分,因为它将用户和角色统一为同一种实体。) - privilege - querying + 权限 + 查询 - 列出那些允许编程查询对象访问权限的函数。参阅获取更多有关权限的信息。 - 在这些函数中,可以通过名称或OID (pg_authid.oid)指定被查询权限的用户,或者如果名称被指定为public,则检查PUBLIC伪角色的权限。 - 同样,user参数可以完全省略,在这种情况下,假设为current_user。被查询的对象也可以通过名称或OID来指定。 - 通过名称指定时,可以包含相关的模式名称。感兴趣的访问权限由一个文本字符串指定,它必须计算为对象类型的一个适当的权限关键字(例如,SELECT)。 - 还可以将 WITH GRANT OPTION添加到权限类型中,以测试该权限是否由授予选项持有。 - 同样,可以用逗号分隔列出多个权限类型,在这种情况下,如果所列出的权限中有任何一个被持有,结果将为真。 - (权限字符串的大小写不重要,权限名之间允许有额外的空格,但在权限名中不允许。)一些示例: + 列出了允许以编程方式查询对象访问权限的函数。(关于权限的更多信息,请参见。)在这些函数中,可以通过名称或 OID(pg_authid.oid)指定要查询权限的用户;如果名称为public,则检查 PUBLIC 伪角色的权限。也可以完全省略user参数,此时使用current_user。要查询的对象也可以通过名称或 OID 指定。通过名称指定时,如适用,可以包含模式名。所需访问权限由文本字符串指定,其值必须为适用于该对象类型的权限关键字之一(例如SELECT)。还可以在权限类型后附加WITH GRANT OPTION,以检查是否拥有该权限及其授予选项。也可以用逗号分隔列出多个权限类型;只要拥有列出的任一权限,结果就为真。(权限字符串不区分大小写,权限名之间允许有额外的空白,但权限名内部不允许。)例如: SELECT has_table_privilege('myschema.mytable', 'select'); SELECT has_table_privilege('joe', 'mytable', 'INSERT, SELECT WITH GRANT OPTION'); @@ -18419,9 +18317,7 @@ SELECT has_table_privilege('joe', 'mytable', 'INSERT, SELECT WITH GRANT OPTION') boolean - 用户是否对表的任何列有权限? - 如果对整个表持有权限,或者对至少一个列有列级的权限授予,则会成功。 - 允许的权限类型为SELECT, INSERT,UPDATE, 和 REFERENCES + 用户是否对表的至少一列具有权限?如果拥有整个表的权限,或至少一列获得了该权限的列级授权,则返回真。允许的权限类型为SELECTINSERTUPDATEREFERENCES @@ -18472,7 +18368,7 @@ SELECT has_table_privilege('joe', 'mytable', 'INSERT, SELECT WITH GRANT OPTION') boolean - 用户是否拥有外部数据包装的权限?唯一允许的权限类型是USAGE。 + 用户是否具有外部数据包装器权限?唯一允许的权限类型为USAGE @@ -18542,7 +18438,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); boolean - 用户是否有顺序权限?允许的权限类型有USAGE, SELECT, 和UPDATE。 + 用户是否具有序列权限?允许的权限类型为USAGESELECTUPDATE @@ -18573,7 +18469,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); privilege text ) boolean - 用户是否具有表权限?允许的权限类型为 SELECTINSERTUPDATEDELETETRUNCATEREFERENCESTRIGGER + 用户是否具有表权限?允许的权限类型为SELECTINSERTUPDATEDELETETRUNCATEREFERENCESTRIGGER @@ -18633,7 +18529,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); boolean - 在当前用户和当前环境的上下文之中,指定表的行级安全是活动的吗? + 在当前用户和当前环境的上下文中,指定表的行级安全性是否生效? @@ -18641,8 +18537,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); - 显示了aclitem类型的可用操作符,它是访问权限的目录表示。 - 有关如何读取访问权限值的信息,请参阅 。 + 列出了aclitem类型可用的操作符;该类型是访问权限在系统目录中的表示形式。有关如何解读访问权限值的信息,请参见 @@ -18673,8 +18568,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); boolean - aclitem相等吗?(注意,aclitem类型缺少比较操作符的通常集合;它只有相等。 - 反而言之,aclitem数组只能进行相等比较。) + 两个aclitem是否相等?(注意,aclitem类型没有通常的整套比较操作符,而只支持相等比较。因此,aclitem数组也只能进行相等比较。) 'calvin=r*w/hobbes'::aclitem = 'calvin=r*w*/hobbes'::aclitem @@ -18691,7 +18585,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); boolean - 数组是否包含指定的权限?(如果有一个数组条目与aclitem的被授权人和授予人相匹配,并且至少具有权限的指定集,则此选项为真。) + 数组是否包含指定的权限?(如果数组中存在一个条目,其被授权者和授权者与该aclitem相同,且至少包含指定的全部权限,则返回真。) '{calvin=r*w/hobbes,hobbes=r*w*/postgres}'::aclitem[] @> 'calvin=r*/hobbes'::aclitem @@ -18715,7 +18609,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute');
- 显示了一些额外的函数来管理aclitem类型。 + 列出了一些用于管理aclitem类型的其他函数。 @@ -18745,22 +18639,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); aclitem[] - 构造一个aclitem数组,保存属于具有OID ownerId的角色的对象类型type的默认访问权限。 - 这表示当对象的ACL条目为空时将假定的访问权限。(默认访问权限在中描述。) - type参数必须是以下之一: - 'c'表示COLUMN, - 'r'表示TABLE和类似表的对象, - 's'表示SEQUENCE, - 'd'表示DATABASE, - 'f'表示FUNCTIONPROCEDURE, - 'l'表示LANGUAGE, - 'L'表示LARGE OBJECT, - 'n'表示SCHEMA, - 't'表示TABLESPACE, - 'F'表示FOREIGN DATA WRAPPER, - 'S'表示FOREIGN SERVER, - 或 - 'T'表示TYPEDOMAIN。 + 构造一个aclitem数组,保存类型为type、属于 OID 为ownerId的角色的对象的默认访问权限。当对象的ACL条目为空值时,会采用这些访问权限。(默认访问权限见。)type参数必须为以下值之一:'c' 表示COLUMN,'r' 表示TABLE和类似表的对象,'s' 表示SEQUENCE,'d' 表示DATABASE,'f' 表示FUNCTIONPROCEDURE,'l' 表示LANGUAGE,'L' 表示LARGE OBJECT,'n' 表示SCHEMA,'t' 表示TABLESPACE,'F' 表示FOREIGN DATA WRAPPER,'S' 表示FOREIGN SERVER,'T' 表示TYPEDOMAIN @@ -18777,9 +18656,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); is_grantableboolean ) - 以行集的形式返回aclitem数组。如果受让人是伪角色PUBLIC,则在grantee列中用0表示。 - 每个被授予的权限都表示为SELECT, INSERT等。 - 注意,每个权限被分割成单独的一行,因此在privilege_type列中只出现一个关键字。 + 以行集的形式返回aclitem数组。如果被授权者是伪角色 PUBLIC,则在grantee列中用零表示。每项授予的权限表示为SELECTINSERT等。注意,每项权限都会拆成单独的一行,因此privilege_type列中只会出现一个关键字。 @@ -18944,7 +18821,7 @@ SELECT relname FROM pg_class WHERE pg_table_is_visible(oid); boolean - 文本搜索配置在搜索路径可见吗? + 全文检索配置是否在搜索路径中可见? @@ -18957,7 +18834,7 @@ SELECT relname FROM pg_class WHERE pg_table_is_visible(oid); boolean - 文本搜索字典在搜索路径可见吗? + 全文检索词典是否在搜索路径中可见? @@ -18970,7 +18847,7 @@ SELECT relname FROM pg_class WHERE pg_table_is_visible(oid); boolean - 文本搜索解析器在搜索路径中可见吗? + 全文检索解析器是否在搜索路径中可见? @@ -18983,7 +18860,7 @@ SELECT relname FROM pg_class WHERE pg_table_is_visible(oid); boolean - 文本搜索模板在搜索路径可见吗? + 全文检索模板是否在搜索路径中可见? @@ -19050,7 +18927,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 重构为了约束的创建命令。(这是一个反编译的重构,而不是命令的原始文本。) + 重建约束的创建命令。(这是反编译重建的结果,并非命令的原始文本。) @@ -19063,8 +18940,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 反编译存储在系统目录中的表达式的内部形式,例如列的默认值。 - 如果表达式可能包含变量,则指定它们所指向的关系的OID作为第二个参数;如果没有预期的变量,传递0就可以了。 + 反编译存储在系统目录中的表达式的内部形式,例如列的默认值。如果表达式可能包含 Var 节点,请将它们所引用的关系的 OID 指定为第二个参数;如果预计不含 Var 节点,传入零即可。 @@ -19077,8 +18953,8 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 重构为了函数或过程的创建命令。(这是一个反编译的重构,而不是命令的原始文本。) - 结果是一个完整的CREATE OR REPLACE FUNCTIONCREATE OR REPLACE PROCEDURE语句。 + 重建函数或过程的创建命令。(这是反编译重建的结果,并非命令的原始文本。) + 结果是一条完整的CREATE OR REPLACE FUNCTIONCREATE OR REPLACE PROCEDURE语句。 @@ -19091,7 +18967,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 重新构造函数或过程的参数列表,以其在 CREATE FUNCTION里面需要出现的形式(包括默认值)。 + 重建函数或过程的参数列表,采用其在CREATE FUNCTION中应有的形式(包括默认值)。 @@ -19104,7 +18980,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 重新构造标识函数或过程所需的参数列表,以其应出现在ALTER FUNCTION等命令中的形式。这个表单省略默认值。 + 重建标识函数或过程所需的参数列表,采用其在ALTER FUNCTION等命令中应有的形式。这种形式省略默认值。 @@ -19117,7 +18993,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 重构函数的RETURNS子句,以其需要出现在CREATE FUNCTION中的形式。对于过程,返回NULL。 + 重建函数的RETURNS子句,采用其在CREATE FUNCTION中应有的形式。对于过程,返回NULL @@ -19130,7 +19006,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 重构针对索引的创建命令。(这是一个反编译的重构,而不是命令的原始文本。)如果提供了column而且不为零,则只重构该列的定义。 + 重建索引的创建命令。(这是反编译重建的结果,并非命令的原始文本。)如果提供了column而且不为零,则只重建该列的定义。 @@ -19157,7 +19033,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 重构针对规则的创建命令。(这是一个反编译的重构,而不是命令的原始文本。) + 重建规则的创建命令。(这是反编译重建的结果,并非命令的原始文本。) @@ -19172,15 +19048,15 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); 返回与列相关联的序列名称,如果没有序列与该列相关联则返回NULL。 如果列是标识列,则关联序列是在内部为该列创建的序列。 - 对于使用一种串行类型(serial, smallserial, bigserial)创建的列,它是为该串行列定义创建的序列。 + 对于使用一种 serial 类型(serial, smallserial, bigserial)创建的列,它是为该 serial 列定义创建的序列。 在后一种情况下,可以使用ALTER SEQUENCE OWNED BY修改或删除关联。 - (这个函数可能应该被称为pg_get_owned_sequence;它的当前名称反映了它在历史上曾与串行类型的列一起使用。) + (这个函数可能应该被称为pg_get_owned_sequence;它的当前名称反映了它在历史上曾与 serial 类型的列一起使用。) 第一个参数是具有可选模式的表名,第二个参数是列名。 由于第一个参数可能包含模式名和表名,因此按照通常的SQL规则解析它,这意味着默认情况下它是小写的。 第二个参数只是一个列名,按照字面来处理,因此保留了它的大小写。结果经过了适当的格式化,可以传递给序列函数(参见)。 - 典型的用法是读取序列的当前值以获取标识或串行列,示例如下: + 典型用法是读取标识列或 serial 列所用序列的当前值,例如: SELECT currval(pg_get_serial_sequence('sometable', 'id')); @@ -19196,7 +19072,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); text - 重构针对扩展统计对象的创建命令。(这是一个反编译的重构,而不是命令的原始文本。) + 重建扩展统计对象的创建命令。(这是反编译重建的结果,并非命令的原始文本。) @@ -19209,7 +19085,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); text - 重构针对触发器的创建命令。(这是一个反编译的重构,而不是命令的原始文本。) + 重建触发器的创建命令。(这是反编译重建的结果,并非命令的原始文本。) @@ -19235,7 +19111,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); text - 重构针对视图或物化视图的SELECT命令。(这是一个反编译的重构,而不是命令的原始文本。) + 重建定义视图或物化视图的SELECT命令。(这是反编译重建的结果,并非命令的原始文本。) @@ -19245,8 +19121,8 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); text - 重构针对视图或物化视图的底层SELECT命令。(这是一个反编译的重构,而不是命令的原始文本。) - 在这种形式的函数中,总是启用美观打印,并对长行进行换行,以尽量使它们小于指定的列数。 + 重建定义视图或物化视图的SELECT命令。(这是反编译重建的结果,并非命令的原始文本。) + 这种形式始终启用美化输出,并将长行折行,尽量使每行长度小于指定列数。 @@ -19256,7 +19132,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); text - 根据视图的文本名称而不是它的OID,重构针对视图或物化视图的底层SELECT命令。(这是弃用;请使用OID变体。) + 根据视图的文本名称而不是其 OID,重建定义视图或物化视图的SELECT命令。(此形式已弃用;请使用 OID 变体。) @@ -19269,7 +19145,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); boolean - 测试一个索引列是否具有命名属性。列出了常用索引列属性。 + 测试一个索引列是否具有指定名称的属性。列出了常用索引列属性。 (注意,扩展访问方法可以为其索引定义额外的属性名。) 如果属性名未知或不适用于特定对象,或者OID或列号不能识别有效的对象,则返回NULL @@ -19284,7 +19160,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); boolean - 测试一个索引是否具有命名属性。列出了常用的索引属性。 + 测试一个索引是否具有指定名称的属性。列出了常用的索引属性。 (注意,扩展访问方法可以为其索引定义额外的属性名。) 如果属性名未知或不适用于特定对象,或者OID不能识别有效的对象,则返回NULL @@ -19299,7 +19175,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); boolean - 测试索引访问方法是否具有命名属性。访问方法属性如所示。 + 测试索引访问方法是否具有指定名称的属性。访问方法属性如所示。 如果属性名未知或不适用于特定对象,或者OID不能识别有效的对象,则返回NULL @@ -19328,9 +19204,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); setof oid - 返回具有存储在指定表空间中的对象的数据库的OIDs集。 - 如果这个函数返回了任何行,那么表空间就不是空的,且不能被删除。 - 要识别填充表空间的特定对象,需要连接到由pg_tablespace_databases标识的数据库,并查询它们的pg_class目录。 + 返回在指定表空间中存储了对象的数据库 OID 集合。如果此函数返回任何行,则说明该表空间不为空,不能删除。要查看存放在该表空间中的具体对象,需要连接到pg_tablespace_databases标识的数据库,并查询它们的pg_class系统目录。 @@ -19356,12 +19230,10 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); regtype - 返回传递值给它的数据类型的OID。这对于故障排除或动态构造SQL查询很有帮助。 - 函数声明为返回regtype,它是一个OID别名类型(see ); - 这意味着,为了比较,它与OID相同,但显示为类型名。 + 返回所传入值的数据类型的 OID。这有助于排查问题或动态构造 SQL 查询。函数声明的返回类型是regtype,它是一种 OID 别名类型(参见);这意味着它在比较时与 OID 相同,但显示为类型名。 - 例如: + 例如: SELECT pg_typeof(33); pg_typeof @@ -19385,11 +19257,12 @@ SELECT typlen FROM pg_type WHERE oid = pg_typeof(33); text - 返回传递值给它的排序规则的名称。如果需要,该值会被引号括起来,并使用模式限定。 - 如果没有为参数表达式派生排序规则,则返回NULL。如果参数不是可排序数据类型,则会引发错误。 + 返回传入值的排序规则名称。必要时会为返回的名称加上引号和模式限定。 + 如果无法为参数表达式推导出排序规则,则返回NULL。 + 如果参数不属于支持排序规则的数据类型,则报错。 - 例如: + 例如: SELECT collation for (description) FROM pg_description LIMIT 1; pg_collation_for @@ -19414,7 +19287,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); 将文本关系名转换为它的OID。通过将字符串类型转换为regclass可以得到类似的结果(参见); - 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与类型转换不同的是,它不接受数字OID作为输入。 @@ -19427,8 +19300,8 @@ SELECT collation for ('foo' COLLATE "de_DE"); regcollation - 将文本排序规则名称转换为它的OID。通过将字符串类型转换为regcollation(参见)可以得到类似的结果; - 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 将文本排序规则名称转换为它的OID。通过将字符串类型转换为regcollation(参见)可以得到类似的结果; + 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与类型转换不同的是,它不接受数字OID作为输入。 @@ -19441,8 +19314,8 @@ SELECT collation for ('foo' COLLATE "de_DE"); regnamespace - 将文本模式名转换为它的OID。通过将字符串转换为regnamespace类型(参见)可以得到类似的结果; - 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 将文本模式名转换为它的OID。通过将字符串转换为regnamespace类型(参见)可以得到类似的结果; + 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与类型转换不同的是,它不接受数字OID作为输入。 @@ -19455,8 +19328,8 @@ SELECT collation for ('foo' COLLATE "de_DE"); regoper - 将文本操作符名称转换为它的OID。通过将字符串类型转换为regoper(参见)可以得到类似的结果; - 但是,如果找不到名称或名称有多义性,该函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 将文本操作符名称转换为它的OID。通过将字符串类型转换为regoper(参见)可以得到类似的结果; + 但是,如果找不到名称或名称有歧义,该函数将返回NULL而不会抛出错误。与类型转换不同的是,它不接受数字OID作为输入。 @@ -19469,8 +19342,8 @@ SELECT collation for ('foo' COLLATE "de_DE"); regoperator - 将文本操作符名称(带有参数类型)转换为其OID。通过将字符串转换为regoperator类型(参见节)可以得到类似的结果; - 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 将文本操作符名称(带有参数类型)转换为其OID。通过将字符串转换为regoperator类型(参见节)可以得到类似的结果; + 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与类型转换不同的是,它不接受数字OID作为输入。 @@ -19483,8 +19356,8 @@ SELECT collation for ('foo' COLLATE "de_DE"); regproc - 将文本函数或过程名转换为其OID。通过将字符串转换为regproc类型(参见)可以得到类似的结果; - 但是,如果找不到名称或名称有多义性,该函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 将文本函数或过程名转换为其OID。通过将字符串转换为regproc类型(参见)可以得到类似的结果; + 但是,如果找不到名称或名称有歧义,该函数将返回NULL而不会抛出错误。与类型转换不同的是,它不接受数字OID作为输入。 @@ -19498,7 +19371,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); 将文本函数或过程名(带有参数类型)转换为其OID。通过将字符串类型转换为regprocedure可以得到类似的结果(参见); - 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与类型转换不同的是,它不接受数字OID作为输入。 @@ -19512,7 +19385,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); 将文本角色名转换为它的OID。通过将字符串类型转换为regrole可以得到类似的结果(参见); - 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与类型转换不同的是,它不接受数字OID作为输入。 @@ -19525,8 +19398,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); regtype - 将文本类型名转换为它的OID。通过将字符串类型转换为regtype可以得到类似的结果(参见); - 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 将文本形式的类型名转换为其 OID。将字符串转换为 regtype 类型也能得到类似的结果(参见 );不过,如果找不到该名称,此函数会返回 NULL,而不会报错。与类型转换不同的是,此函数不接受数值 OID 作为输入。 @@ -19534,10 +19406,10 @@ SELECT collation for ('foo' COLLATE "de_DE");
- 大多数重构(反编译)数据库对象的函数都有一个可选的 pretty标志,如果为true,结果将被pretty-printed。 - 美观打印会抑制不必要的圆括号,并为易读性增加空格。 - 美观打印的格式可读性更好,但是默认格式更有可能被PostgreSQL的未来版本以同样的方式解释; - 因此,避免为转储目的使用美观打印的输出。为pretty参数传递false会产生与省略参数相同的结果。 + 大多数重建(反编译)数据库对象的函数都有一个可选的pretty标志;若为true,则对结果进行美化输出。 + 美化输出会省略不必要的圆括号,并增加空白以提高可读性。 + 美化后的格式更易读,但默认格式更有可能被PostgreSQL的未来版本以同样的方式解释,因此用于转储时应避免美化输出。 + 为pretty参数传入false与省略该参数的结果相同。 @@ -19582,19 +19454,20 @@ SELECT collation for ('foo' COLLATE "de_DE"); distance_orderable - 列能否通过一个distance操作符(例如ORDER BY col <-> constant)有序地扫描? + + 能否按距离操作符的结果有序地扫描该列,例如ORDER BY col <-> constant returnable - 列值是否可以通过一次只用索引扫描返回? + 列值是否可以通过一次仅索引扫描返回? search_array - 列是否天然支持col = ANY(array)搜索? + 列是否原生支持col = ANY(array)搜索? @@ -19609,7 +19482,7 @@ SELECT collation for ('foo' COLLATE "de_DE");
- 索引性质 + 索引属性 @@ -19646,7 +19519,7 @@ SELECT collation for ('foo' COLLATE "de_DE");
- 索引访问方法性质 + 索引访问方法属性 @@ -19688,12 +19561,11 @@ SELECT collation for ('foo' COLLATE "de_DE");
- 列出了与数据库对象 - 标识和定位有关的函数。 + 列出了与数据库对象标识和寻址有关的函数。 - 对象信息和定位函数 + 对象信息和寻址函数 @@ -19717,8 +19589,8 @@ SELECT collation for ('foo' COLLATE "de_DE"); text - 返回由目录OID、对象OID和子对象ID(例如表中的列号;引用整个对象时,子对象ID为0)标识的数据库对象的文本描述。 - 这个描述是人类可读的,并且可以根据服务器配置进行翻译。这对于决定pg_depend目录中引用的对象的标识特别有用。 + 返回数据库对象的文本描述,对象由系统目录 OID、对象 OID 和子对象 ID 指定(例如表中的列号;引用整个对象时,子对象 ID 为零)。该描述供人阅读,并可能根据服务器配置被翻译。这对于确定pg_depend系统目录中所引用对象的标识尤其有用。 + @@ -19734,12 +19606,8 @@ SELECT collation for ('foo' COLLATE "de_DE"); identity text ) - 返回包含足够信息的行以唯一标识由目录OID、对象OID和子对象ID指定的数据库对象。 - 这些信息是为了机器可读的,永远不会被翻译。 - type标识数据库对象的类型; - schema是对象所属的模式名,NULL表示不属于模式的对象类型; - name是对象的名称,如果有必要,用引号括起来,如果名称(随着模式名称,如果相关)足以唯一地标识对象,否则为NULL; - identity是完整的对象标识,其精确格式依赖于对象类型,格式中的每个名称都是模式限定的,并在必要时用引号括起来。 + 返回一行,其中包含足以唯一标识数据库对象的信息,该对象由系统目录 OID、对象 OID 和子对象 ID 指定。这些信息供机器读取,永远不会被翻译。type标识数据库对象的类型;schema是对象所属的模式名,对于不属于模式的对象类型则为NULL;如果对象名(以及适用时的模式名)足以唯一标识该对象,name就是对象名,并在必要时加引号,否则为NULLidentity是完整的对象标识,其具体格式取决于对象类型,格式中的每个名称都会根据需要加上模式限定和引号。 + @@ -19754,10 +19622,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); object_args text[] ) - 返回包含足够信息的行以唯一标识由目录OID、对象OID和子对象ID指定的数据库对象。 - 返回的信息独立于当前服务器,也就是说,它可以用于标识另一个服务器中具有相同名称的对象。 - type标识数据库对象的类型;object_namesobject_args是文本数组,它们一起构成对对象的引用。 - 这三个值可以传递给pg_get_object_address以获得对象的内部地址。 + 返回一行,其中包含足以唯一标识数据库对象的信息,该对象由系统目录 OID、对象 OID 和子对象 ID 指定。返回的信息与当前服务器无关,也就是说,它也能用于标识另一台服务器上名称相同的对象。type标识数据库对象的类型;object_namesobject_args是文本数组,共同构成对该对象的引用。将这三个值传给pg_get_object_address可以获得对象的内部地址。 @@ -19773,11 +19638,8 @@ SELECT collation for ('foo' COLLATE "de_DE"); objsubidinteger ) - 返回包含足够信息的行以唯一标识由类型代码、对象名称和参数数组指定的数据库对象。 - 返回的值将在系统目录中使用,例如pg_depend; - 它们可以传递给其他系统函数,比如 pg_describe_objectpg_identify_object。 - classid是包含该对象的系统目录的OID;objid是对象本身的OID, objsubid是子对象的ID,如果没有则为零。 - 这个函数是pg_identify_object_as_address的反向函数。 + 返回一行,其中包含足以唯一标识数据库对象的信息,该对象由类型代码、对象名称数组和参数数组指定。返回的值就是pg_depend等系统目录中使用的值;它们可以传给pg_describe_objectpg_identify_object等其他系统函数。classid是包含该对象的系统目录的 OID;objid是对象自身的 OID;objsubid是子对象 ID,没有子对象时为零。此函数执行pg_identify_object_as_address的逆操作。 + @@ -19789,7 +19651,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); - 中展示的函数抽取注释,注释是由命令在以前存储的。如果对指定参数找不到注释,则返回空值。 + 中的函数用于提取此前通过命令存储的注释。如果找不到与指定参数对应的注释,则返回空值。
@@ -19819,7 +19681,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); text - 返回表列的注释,该注释由该表的OID和列号指定。(obj_description不能用于表的列,因为列没有自己的oid。) + 返回表列的注释,列由所属表的 OID 和列号指定。(obj_description不能用于表列,因为列没有自身的 OID。) @@ -19832,8 +19694,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); text - 返回OID指定的数据库对象的注释和包含该对象的系统目录的名称。 - 例如,obj_description(123456, 'pg_class')将检索OID为123456的表的注释。 + 返回数据库对象的注释,对象由其 OID 和所在系统目录的名称指定。例如,obj_description(123456, 'pg_class')会获取 OID 为 123456 的表的注释。 @@ -19843,8 +19704,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); text - 返回仅由其OID指定的数据库对象的注释。 - 这个已被弃用(deprecated)因为无法保证oid在不同的系统目录中是唯一的;因此,可能会返回错误的注释。 + 返回仅由其 OID 指定的数据库对象的注释。此形式已弃用,因为无法保证 OID 在不同系统目录之间唯一,因而可能返回错误的注释。 @@ -19857,9 +19717,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); text - 返回共享数据库对象的注释,该对象由其OID和包含的系统编目的名称指定。 - 这与obj_description类似,只是它用于检索共享对象(也就是数据库、角色和表空间)上的注释。 - 有些系统编目对每个集簇中的所有数据库都是全局的,其中对象的描述也全局存储。 + 返回共享数据库对象的注释,对象由其 OID 和所在系统目录的名称指定。此函数与obj_description类似,但用于获取共享对象(即数据库、角色和表空间)的注释。有些系统目录由数据库集簇中的所有数据库全局共享,其中对象的描述也全局存储。 @@ -19895,7 +19753,9 @@ SELECT collation for ('foo' COLLATE "de_DE"); age ( xid ) integer - 返回所给事务 ID 与当前事务计数器之间的事务数。 + + 返回给定事务 ID 与当前事务计数器之间的事务数。 + @@ -19906,7 +19766,9 @@ SELECT collation for ('foo' COLLATE "de_DE"); mxid_age ( xid ) integer - 返回所给多事务 ID 与当前多事务计数器之间的多事务 ID 数量。 + + 返回给定多事务 ID 与当前多事务计数器之间的多事务 ID 数。 + @@ -19918,7 +19780,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); xid8 - 返回当前事务的ID。如果当前事务还没有一个ID(因为它还没有执行任何数据库更新),它将分配一个新的事务。 + 返回当前事务的ID。如果当前事务还没有一个ID(因为它还没有执行任何数据库更新),它将分配一个新的事务 ID。 @@ -19945,10 +19807,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); text - 报告最近的事务的提交状态。如果事务为最近的,系统会保留事务的提交状态,则结果是 in progresscommittedaborted。 - 如果该事务的时间足够久,并且系统中没有对该事务的引用,而且提交状态信息已经被丢弃,则结果为NULL。 - 应用可以使用此函数,例如,确定在进行COMMIT时,应用程序和数据库服务器断开连接后,它们的事务是已提交还是中止。 - 注意,准备好的事务报告为in progress的事务;如果应用需要确定一个事务ID是否属于一个准备好的事务,则必须检查pg_prepared_xacts。 + 报告近期事务的提交状态。只要事务足够新,系统仍保留其提交状态,结果就为in progresscommittedaborted。如果事务已足够旧,系统中不再有对它的引用,且提交状态信息已被丢弃,则返回NULL。例如,在COMMIT进行过程中应用与数据库服务器断开连接时,应用可以用此函数判断事务是提交了还是中止了。注意,预备事务被报告为in progress;如果需要确定某个事务 ID 是否为预备事务,应用必须检查pg_prepared_xacts @@ -19961,7 +19820,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); pg_snapshot - 返回当前snapshot,显示哪些事务 ID正在进行中的数据结构。 + 返回当前快照,即显示哪些事务 ID 正在进行中的数据结构。 @@ -20013,8 +19872,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); boolean - 根据此快照,给定的事务ID是否可见(visible)(也就是说,它是否在快照拍摄之前完成)? - 注意,这个函数不会给出子事务ID的正确答案。 + 根据此快照,给定的事务 ID 是否可见(即该事务是否在生成快照之前完成)?注意,此函数无法为子事务 ID 给出正确结果。 @@ -20038,7 +19896,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); 内部事务 ID 类型xid是 32 位宽,每 40 亿个事务就会回卷一次(wrap around)。 - 但是,中所示的函数除 agemxid_agepg_get_multixact_members 外,使用的是 64 位类型xid8,它在一次安装的生命周期内不会回卷,必要时可以通过强制转换将其转换为xid。 + 但是,中所示的函数除 agemxid_agepg_get_multixact_members 外,使用的是 64 位类型xid8,它在一次安装的生命周期内不会回卷,必要时可以通过类型转换将其转换为xid。 数据类型pg_snapshot存储特定时刻事务ID可见性的信息。 其组成如所描述。pg_snapshot的文本表示形式是xmin:xmax:xip_list。 例如10:20:10,14,15表示xmin=10, xmax=20, xip_list=10, 14, 15。 @@ -20061,21 +19919,22 @@ SELECT collation for ('foo' COLLATE "de_DE"); xmin - 仍然处于活动状态的最低事务ID。所有小于xmin的事务 ID要么提交且可见,要么回滚并死亡。 + 仍然处于活动状态的最小事务 ID。所有小于xmin的事务 ID 要么已经提交且可见,要么已经回滚而失效。 xmax - 比最高完成的事务ID还高出一个值。所有大于或等于xmax的事务 ID到快照时还没有完成,因此不可见。 + 已完成事务中的最大事务 ID 加一。所有大于或等于xmax的事务 ID 在生成快照时尚未完成,因此不可见。 xip_list - 快照时正在进行的事务。一个事务ID为xmin <= X < xmax且不在快照时已经完成的列表中,因此根据其提交状态,该事务ID要么是可见的,要么是死的。此列表不包括子事务的事务 ID。 + 生成快照时正在进行的事务。满足xmin <= X < + xmax且不在此列表中的事务 ID 在生成快照时已经完成,因此根据其提交状态,要么可见,要么失效。此列表不包含子事务的事务 ID。 @@ -20264,9 +20123,7 @@ SELECT collation for ('foo' COLLATE "de_DE");
- 中所展示的函数能打印initdb期间初始化的信息,例如目录版本。 - 它们也能显示有关预写式日志和检查点处理的信息。这些信息是集簇范围内的,不与任何特定的一个数据库相关。 - 这些函数提供大致相同的信息,对于同一种来源,就像应用。 + 中的函数显示在initdb期间初始化的信息,例如系统目录版本。它们也显示有关预写式日志和检查点处理的信息。这些信息适用于整个数据库集簇,而非某个特定数据库。这些函数与应用程序从相同来源提供大部分相同的信息。 @@ -20296,7 +20153,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); record - 返回有关当前检查点状态的信息, 如 所展示。 + 返回有关当前检查点状态的信息, 如 所展示。 @@ -20335,7 +20192,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); record - 返回有关恢复状态的信息,如 所展示。 + 返回有关恢复状态的信息,如 所展示。 @@ -20626,9 +20483,9 @@ SELECT collation for ('foo' COLLATE "de_DE"); - configuration - of the server - functions + 配置 + 服务器 + 函数 @@ -20665,7 +20522,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); text - 返回设置的setting_name的当前值。 + 返回设置setting_name的当前值。 如果没有这样的设置,current_setting将抛出一个错误,除非missing_ok被提供并且为true(在此情况下返回NULL)。 这个函数对应于SQL命令 @@ -20687,9 +20544,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); text - 将参数setting_name设置为new_value,并返回该值。 - 如果is_localtrue,新值将仅在当前事务期间应用。 - 如果您希望新值应用于当前会话的其余部分,请使用false代替。这个函数对应于SQL命令。 + 将参数setting_name设置为new_value,并返回该值。如果is_localtrue,新值仅在当前事务期间生效。如果希望新值在当前会话的剩余时间内生效,则使用false。此函数对应 SQL 命令 set_config('log_statement_stats', 'off', false) @@ -20711,7 +20566,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); - 在中展示的函数向其它服务器进程发送控制信号。默认情况下这些函数只能被超级用户使用,但是如果需要,可以利用GRANT把访问权限授予给其他用户。 + 在中展示的函数向其它服务器进程发送控制信号。默认情况下这些函数只能被超级用户使用,但是如果需要,可以利用GRANT把访问权限授予给其他用户(注明的例外除外)。 这些函数在成功时都返回 true,否则返回 false @@ -20742,7 +20597,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); 取消具有指定进程ID的后端进程的会话的当前查询。如果调用角色是被取消的后端进程所属角色的成员, - 或者调用角色具有pg_signal_backend的权限,则也允许执行此操作,但只有超级用户可以取消超级用户后端进程。 + 或者调用角色已被授予pg_signal_backend角色,则也允许执行此操作,但只有超级用户可以取消超级用户后端进程。 @@ -20780,7 +20635,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); boolean - 终止具有指定进程ID的后端进程的会话。如果调用角色是正在终止的后端的角色的成员,或者调用角色具有pg_signal_backend的权限,则也允许执行此操作,但只有超级用户才能终止超级用户后端。 + 终止具有指定进程ID的后端进程的会话。如果调用角色是正在终止的后端的角色的成员,或者调用角色已被授予pg_signal_backend角色,则也允许执行此操作,但只有超级用户才能终止超级用户后端。 @@ -20789,7 +20644,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); pg_cancel_backendpg_terminate_backend向由进程 ID 标识的后端进程发送信号(分别是SIGINTSIGTERM)。 - 一个活动后端的进程 ID可以从pg_stat_activity视图的pid列中找到,或者通过在服务器上列出postgres进程(在 Unix 上使用ps或者在Windows上使用Task Manager)得到。 + 一个活动后端的进程 ID可以从pg_stat_activity视图的pid列中找到,或者通过在服务器上列出postgres进程(在 Unix 上使用ps或者在Windows上使用任务管理器)得到。 一个活动后端的角色可以在pg_stat_activity视图的usename列中找到。 @@ -20799,7 +20654,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); 备份控制函数 - backup + 备份 中列出的函数有助于进行在线备份。这些函数不能在恢复期间执行(非排他模式的 pg_start_backup、非排他模式的 pg_stop_backuppg_is_in_backuppg_backup_start_timepg_wal_lsn_diff 除外)。 @@ -20833,11 +20688,9 @@ SELECT collation for ('foo' COLLATE "de_DE"); pg_lsn - 在预写式日志中创建一个命名标记记录,稍后可以将其用作恢复目标,并返回相应的预写日志位置。 - 然后可以将给定的名称与 一起使用,以指定进行恢复的点。 - 要避免创建多个名称相同的恢复点,因为恢复将在第一个名称与恢复目标匹配的恢复点停止。 + 在预写式日志中创建一条命名标记记录,供以后用作恢复目标,并返回相应的预写式日志位置。随后可以在中使用给定名称,指定恢复到哪一点。应避免创建多个同名恢复点,因为恢复会在第一个名称匹配恢复目标的恢复点停止。 - 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予 EXECUTE 权限以运行它。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -20849,7 +20702,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); pg_lsn - 返回当前预写式日志刷新位置(参见下面的说明)。 + 返回当前预写式日志刷盘位置(参见下文说明)。 @@ -20862,7 +20715,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); pg_lsn - 返回当前预式日志插入位置(参见下面的说明)。 + 返回当前预写式日志插入位置(参见下文说明)。 @@ -20875,7 +20728,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); pg_lsn - 返回当前预写式日志写位置(参见下面的说明)。 + 返回当前预写式日志写入位置(参见下文说明)。 @@ -20892,14 +20745,10 @@ SELECT collation for ('foo' COLLATE "de_DE"); pg_lsn - 准备服务器开始在线备份。唯一必需的参数是备份的任意用户定义标签。 - (通常这将是备份转储文件存储的名称。) - 如果将可选的第二个参数指定为true, - 它将尽快执行pg_start_backup。这将强制立即进行检查点, - 这将导致I/O操作的激增,从而减慢任何同时执行的查询。 + 准备服务器开始在线备份。唯一必需的参数是用户任意指定的备份标签。(通常是备份转储文件将要保存的名称。)如果可选的第二个参数为true,则尽快执行pg_start_backup。这会强制立即执行检查点,使 I/O 操作量陡增,并降低并发执行的查询的速度。可选的第三个参数指定执行排他备份还是非排他备份(默认为排他备份)。 在排他模式下使用时,该函数会将备份标签文件(backup_label)写入数据库集簇的数据目录;如果 pg_tblspc/ 目录中存在任何链接,还会写入表空间映射文件(tablespace_map)。然后它执行一次检查点,并返回备份开始时的预写式日志位置。(用户可以忽略此返回值,但仍会提供它以供需要时使用。)在非排他模式下,这些文件的内容由 pg_stop_backup 函数返回,用户应将其复制到备份区域。 - 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予 EXECUTE 权限以运行它。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -20918,20 +20767,13 @@ SELECT collation for ('foo' COLLATE "de_DE"); 结束排他或非排他的在线备份。exclusive 参数必须与先前调用 pg_start_backup 时的值一致。在排他备份中,pg_stop_backup 会移除由 pg_start_backup 创建的备份标签文件,以及表空间映射文件(如果存在)。在非排他备份中,这些文件所需的内容作为函数结果的一部分返回,应将其写入备份区域中的文件(而不是数据目录)。 - 有一个类型为boolean的可选参数。 - 如果为false,则在备份完成后立即返回,而无需等待WAL进行归档。 - 此行为仅适用于独立监视WAL归档的备份软件。否则,可能会缺少使备份一致所需的WAL,使备份无效。 - 默认情况下或当此参数为true时,pg_stop_backup将在启用归档时等待WAL进行归档。 - (在备库上,这意味着仅当archive_mode = always时才会等待。 - 如果主库上的写入活动较低,则可能有必要在主库上运行pg_switch_wal以触发立即段切换。) + 有一个boolean类型的可选第二参数。如果为 false,该函数会在备份完成后立即返回,不等待 WAL 归档。这种行为只适用于自行监控 WAL 归档的备份软件;否则,可能缺少使备份保持一致所需的 WAL,导致备份无法使用。默认情况下或该参数为 true 时,若已启用归档,pg_stop_backup会等待 WAL 归档。(在备库上,这意味着只有archive_mode = always时才会等待。如果主库的写入活动很少,可以在主库上运行pg_switch_wal,触发立即切换日志段。) - 在主库上执行时,此函数还会在预写式日志归档区域中创建一个备份历史文件。 - 历史文件包括给定给pg_start_backup的标签、备份的起始和结束预写式日志位置,以及备份的起始和结束时间。 - 在记录结束位置后,当前的预写式日志插入点会自动前进到下一个预写式日志文件,以便立即归档结束的预写式日志文件以完成备份。 + 在主库上执行时,该函数还会在预写式日志归档区域创建备份历史文件。历史文件包括传给pg_start_backup的标签、备份的起止预写式日志位置以及备份的起止时间。记录结束位置后,当前预写式日志插入点会自动推进到下一个预写式日志文件,使包含结束位置的预写式日志文件可以立即归档,从而完成备份。 该函数的结果是一条记录。lsn 列保存备份结束时的预写式日志位置(同样可以忽略)。结束排他备份时,第二列和第三列为 NULL;结束非排他备份时,它们保存标签文件和表空间映射文件所需的内容。 - 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予 EXECUTE 权限以运行它。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -20940,7 +20782,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); pg_lsn 结束排他在线备份。这个简化版本等价于 pg_stop_backup(true, true),但只返回 pg_lsn 结果。 - 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予 EXECUTE 权限以运行它。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -20952,7 +20794,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); boolean - 将预写式日志位置转换为保持该位置的WAL文件的名称。 + 如果正在进行在线排他备份,则返回 true。 @@ -20976,11 +20818,9 @@ SELECT collation for ('foo' COLLATE "de_DE"); pg_lsn - 强制服务器切换到一个新的预写式日志文件,这允许对当前文件进行归档(假设你正在使用连续归档)。 - 其结果是在刚刚完成的预写式日志文件中结束预写式日志位置加1。 - 如果自从上次预写式日志切换以来没有提前写日志活动,pg_switch_wal将不做任何操作,并返回当前正在使用的提前写日志文件的起始位置。 + 强制服务器切换到新的预写式日志文件,使当前文件可以归档(假设正在使用连续归档)。返回值是刚完成的预写式日志文件中的结束预写式日志位置加 1。如果自上次切换预写式日志以来没有发生任何预写式日志活动,pg_switch_wal不执行任何操作,并返回当前使用的预写式日志文件的起始位置。 - 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予 EXECUTE 权限以运行它。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -20992,7 +20832,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); text - 将预写式日志位置转换为保持该位置的WAL文件的名称。 + 将预写式日志位置转换为包含该位置的 WAL 文件的名称。 @@ -21020,21 +20860,14 @@ SELECT collation for ('foo' COLLATE "de_DE"); numeric - 计算两个预写式日志位置之间的字节(lsn1 - lsn2)差异。 - 这可以与pg_stat_replication中所示的一些函数一起使用,以获得复制延迟。 + 计算两个预写式日志位置之间的字节差(lsn1 - lsn2)。可以将它与pg_stat_replication中的某些函数配合使用,以获取复制延迟。
- - pg_current_wal_lsn 显示当前预写式日志写位置,与上述函数所用的格式相同。 - 类似地,pg_current_wal_insert_lsn显示当前预写式日志插入位置,pg_current_wal_flush_lsn显示当前预写式日志刷新位置。 - 插入位置是预写式日志在任何时刻的逻辑(logical) 结束,而写位置是已经从服务器内部缓冲区实际写入的内容的结束,而刷新位置是已知的要写入持久化存储的最后一个位置。 - 写位置是可以从服务器外部检查的最后位置,如果你对归档部分完成的预写式日志文件感兴趣,那么它通常就是你想要的位置。 - 插入和刷新位置主要用于服务器调试目的。这些都是只读操作,不需要超级用户权限。 - + pg_current_wal_lsn 显示当前预写式日志写入位置,格式与上述函数相同。类似地,pg_current_wal_insert_lsn 显示当前预写式日志插入位置,pg_current_wal_flush_lsn 显示当前预写式日志刷盘位置。插入位置是预写式日志在任意时刻的逻辑末尾;写入位置是实际从服务器内部缓冲区写出的内容的末尾;刷盘位置则是已知已经写入持久存储的最后位置。写入位置是能从服务器外部检查到的内容的末尾,如果要归档尚未写满的预写式日志文件,通常需要这个位置。插入位置和刷盘位置主要用于服务器调试。这些都是只读操作,不需要超级用户权限。 可以使用pg_walfile_name_offset从一个pg_lsn值中提取相应的预写式日志文件名和字节偏移量。例如: postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); @@ -21092,9 +20925,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); pg_lsn - 返回已接收并通过流复制同步到磁盘的最后一个预写式日志位置。 - 当流复制正在进行时这将单调地增加。如果恢复已经完成,那么在恢复期间,接收到的最后一条WAL记录的位置将保持静态,并同步到磁盘。 - 如果流复制已禁用,或者尚未启动,函数将返回NULL。 + 返回流复制最近接收并同步到磁盘的预写式日志位置。在流复制进行期间,该值单调增加。如果恢复已完成,该值将保持为恢复期间最后接收并同步到磁盘的 WAL 记录的位置。如果禁用了流复制,或者流复制尚未开始,此函数返回 NULL @@ -21107,8 +20938,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); pg_lsn - 返回恢复期间重新播放的最后一个预写式日志位置。如果恢复仍在进行中这将会单调地增加。 - 如果恢复已经完成,那么恢复期间应用的最后WAL记录的位置将保持静态。当服务器正常启动且没有恢复时,函数返回NULL。 + 返回恢复期间最近重放的预写式日志位置。如果恢复仍在进行,该值单调增加。如果恢复已完成,该值将保持为该次恢复期间最后应用的 WAL 记录的位置。如果服务器未经恢复而正常启动,此函数返回 NULL @@ -21121,10 +20951,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); timestamp with time zone - 返回恢复期间重放的最后一个事务的时间戳。这是在主库上为该事务生成提交或中止 WAL记录的时间。 - 如果在恢复期间没有重放任何事务,该函数将返回NULL。否则,如果恢复仍在进行中,这将单调地增加。 - 如果恢复已经完成,那么在恢复期间应用最后一个事务时,这将会保持静态。 - 当服务器正常启动且没有恢复时,函数返回NULL。 + 返回恢复期间最近重放事务的时间戳,即该事务的提交或中止 WAL 记录在主库上生成的时间。如果恢复期间尚未重放任何事务,此函数返回 NULL。否则,如果恢复仍在进行,该值单调增加。如果恢复已完成,该值将保持为该次恢复期间最后应用的事务的时间戳。如果服务器未经恢复而正常启动,此函数返回 NULL @@ -21132,7 +20959,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); - 控制恢复进度的功能如 所示。这些函数只能在恢复过程中执行。 + 列出的函数用于控制恢复进度。这些函数只能在恢复期间执行。 @@ -21172,11 +20999,11 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); 将备库提升为主库状态。 - 当wait设置为true(默认值)时,函数将等待直到升级完成或wait_seconds秒数已过,如果升级成功则返回true,否则返回false。 - 如果wait设置为false,则该函数在向postmaster发送SIGUSR1信号以触发升级后立即返回true。 + 当wait设置为true(默认值)时,函数将等待直到提升完成或wait_seconds秒数已过,如果提升成功则返回true,否则返回false。 + 如果wait设置为false,则该函数在向postmaster发送SIGUSR1信号以触发提升后立即返回true - 默认情况下这个函数仅限超级用户使用,但可以授权给其他用户执行该函数。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -21190,7 +21017,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); 暂停恢复。在恢复暂停期间,不再应用数据库更改。如果热备处于活动状态,所有新查询都会看到相同的一致数据库快照,并且在恢复继续之前不会再产生查询冲突。 - 默认情况下该函数仅限超级用户使用,但可以授权其他用户执行该函数。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -21206,7 +21033,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); 如果暂停了,则重新启动恢复。 - 默认情况下该函数仅限超级用户使用,但可以授权其他用户执行该函数。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -21214,8 +21041,8 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup());
- pg_wal_replay_pausepg_wal_replay_resume不能在提升(promotion)进行时执行。 - 如果在恢复暂停时触发了提升(promotion),则暂停状态结束,升级继续进行。 + pg_wal_replay_pausepg_wal_replay_resume不能在提升进行时执行。 + 如果在恢复暂停时触发了提升,则暂停状态结束,提升继续进行。 @@ -21234,7 +21061,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); - 为了解决这个问题,PostgreSQL允许一个事务导出它正在使用的快照。只要导出的事务仍然保持打开,其他事务可以导入它的快照,并且因此可以保证它们可以看到和第一个事务看到的完全一样的数据库视图。但是注意这些事务中的任何一个对数据库所作的更改对其他事务仍然保持不可见,和未提交事务所作的修改一样。因此这些事务是针对以前存在的数据同步,而对由它们自己所作的更改则采取正常的动作。 + 为了解决这个问题,PostgreSQL允许一个事务导出它正在使用的快照。只要导出快照的事务仍然保持打开,其他事务可以导入它的快照,并且因此可以保证它们可以看到和第一个事务看到的完全一样的数据库视图。但是注意这些事务中的任何一个对数据库所作的更改对其他事务仍然保持不可见,和未提交事务所作的修改一样。因此这些事务是针对以前存在的数据同步,而对由它们自己所作的更改则采取正常的动作。 @@ -21274,7 +21101,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); 如果需要的话,一个事务可以导出多个快照。 请注意,这样做仅在READ COMMITTED事务中有用,因为在REPEATABLE READ和更高的隔离级别中,事务在它们的生命周期中使用相同的快照。 - 一旦事务导出了快照,它就不能用 进行准备。 + 一旦事务导出了快照,它就不能用 进行预备。 @@ -21332,12 +21159,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); lsn pg_lsn ) - 创建一个新的名为slot_name的物理复制槽。 - 第二个参数是可选的,当它为true时,立即为这个物理槽指定要被保留的LSN。 - 否则该LSN会被保留在来自一个流复制客户端的第一个连接上。 - 来自一个物理槽的更改只能通过流复制协议进行流式传输 — 见。 - 当可选的第三参数temporary被设置为真时,指定那个槽不会被持久地存储在磁盘上并且仅对当前会话的使用有意义。 - 临时槽也会在发生任何错误时被释放。这个函数对应于复制协议命令CREATE_REPLICATION_SLOT ... PHYSICAL。 + 创建名为 slot_name 的新物理复制槽。可选的第二个参数为 true 时,指定立即为此复制槽保留 LSN;否则在流复制客户端首次连接时保留 LSN。从物理槽流式传输更改只能使用流复制协议 — 参见。可选的第三个参数 temporary 为真时,指定该槽不永久存储到磁盘,且仅供当前会话使用。发生任何错误时,临时槽也会被释放。此函数对应复制协议命令 CREATE_REPLICATION_SLOT ... PHYSICAL @@ -21350,9 +21172,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); void - 丢弃名为slot_name的物理或逻辑复制槽。 - 和复制协议命令DROP_REPLICATION_SLOT相同。对于逻辑槽, - 在连接到在其中创建该槽的同一个数据库时,必须调用这个函数。 + 删除名为slot_name的物理或逻辑复制槽。与复制协议命令DROP_REPLICATION_SLOT相同。 @@ -21367,7 +21187,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); lsn pg_lsn ) - 创建一个名为slot_name的新逻辑(解码)复制插槽,使用输出插件plugin。可选的第三个参数temporary,当设置为true时,指定插槽不应永久存储到磁盘,仅供当前会话使用。临时插槽也会在任何错误发生时释放。调用此函数的效果与复制协议命令CREATE_REPLICATION_SLOT ... LOGICAL相同。 + 创建一个名为slot_name的新逻辑(解码)复制槽,使用输出插件plugin。可选的第三个参数temporary,当设置为真时,指定槽不应永久存储到磁盘,仅供当前会话使用。临时槽也会在任何错误发生时释放。调用此函数的效果与复制协议命令CREATE_REPLICATION_SLOT ... LOGICAL相同。 @@ -21383,7 +21203,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); 将一个名为src_slot_name的现有物理复制槽复制到一个名为dst_slot_name的物理复制槽。 - 被复制的物理槽开始从与源槽相同的LSN开始保留WAL。temporary是可选的。 + 复制后的物理槽从与源槽相同的LSN开始保留WAL。temporary是可选的。 如果省略了temporary,则使用与源槽相同的值。 @@ -21399,7 +21219,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); lsn pg_lsn ) - 复制一个名为src_slot_name的现有逻辑复制槽到一个名为dst_slot_name的逻辑复制槽,选择性的改变输出插件和持久性。 + 复制一个名为src_slot_name的现有逻辑复制槽到一个名为dst_slot_name的逻辑复制槽,可选地更改输出插件和持久性。 被复制的逻辑槽从与源逻辑槽相同的LSN开始。temporaryplugin都是可选的。 如果它们被省略了,使用与源逻辑槽相同的值。 @@ -21417,11 +21237,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); data text ) - 返回槽slot_name中的改变,从最后一次使用更改的点开始。 - 如果upto_lsnupto_nchanges为 NULL,逻辑解码将一直继续到 WAL 的末尾。 - 如果upto_lsn为非 NULL,解码将只包括那些在指定 LSN 之前提交的事务。 - 如果upto_nchanges为非 NULL,解码将在其产生的行数超过指定值后停止。 - 不过要注意,被返回的实际行数可能更大,因为对这个限制的检查只会在增加了解码每个新的提交事务产生的行之后进行。 + 返回槽 slot_name 中自上次消费更改的位置起的更改。如果 upto_lsnupto_nchanges 都为 NULL,逻辑解码会持续到 WAL 末尾。如果 upto_lsn 非 NULL,解码仅包含在指定 LSN 之前提交的事务。如果 upto_nchanges 非 NULL,解码产生的行数超过指定值时就会停止。不过,实际返回行数可能更大,因为只有在添加完对每个新事务提交进行解码所产生的行后,才会检查此限制。 @@ -21486,9 +21302,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); end_lsn pg_lsn ) - 将复制槽的当前确认的位置提前到名为slot_name的复制槽的当前确认位置。 - 该槽不会向后移动,也不会移动到当前插入位置之外。返回该槽的名称和它被推进到的真实位置。 - 如果有任何进展,则在下一个检查点中写出更新后的槽位置信息。所以如果发生崩溃,该槽位可能会返回到之前的位置。 + 推进名为 slot_name 的复制槽当前已确认的位置。该槽不会后退,也不会越过当前插入位置。返回槽名及其实际推进到的位置。如果发生了推进,更新后的槽位置信息会在下一个检查点写出。因此,发生崩溃时,槽可能回到更早的位置。 @@ -21540,8 +21354,8 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); void - 将当前会话标记为从给定的原点回放,从而允许跟踪回放进度。 - 只能在当前没有选择原点时使用。使用pg_replication_origin_session_reset 命令来撤销。 + 将当前会话标记为从给定的复制源重放,从而允许跟踪重放进度。 + 只能在当前没有选择复制源时使用。使用pg_replication_origin_session_reset来撤销。 @@ -21580,7 +21394,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); pg_lsn - 返回当前会话中选择的复制源的重放位置。参数flush决定对应的本地事务是否被确保已经刷入磁盘。 + 返回当前会话中选择的复制源的重放位置。参数flush决定是否保证对应的本地事务已刷盘。 @@ -21634,7 +21448,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); pg_lsn - 返回给定复制元的重放位置。参数flush决定对应的本地事务是否被确保已经刷入磁盘。 + 返回给定复制源的重放位置。参数flush决定是否保证对应的本地事务已刷盘。 @@ -21651,11 +21465,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); pg_lsn - 发出逻辑解码消息。这可以用于通过WAL将通用消息传递给逻辑解码插件。 - transactional参数指定消息是否应该是当前事务的一部分, - 还是应该立即写入并在逻辑解码器读取记录时立即解码。 - prefix参数是一个文本前缀,逻辑解码插件可以使用它轻松识别对它们有趣的消息。 - content参数是消息的内容,可以以文本或二进制形式给出。 + 发出逻辑解码消息。这可用于通过 WAL 向逻辑解码插件传递通用消息。transactional 参数指定消息是作为当前事务的一部分,还是立即写入并在逻辑解码器读到该记录时立即解码。prefix 参数是一个文本前缀,便于逻辑解码插件识别其关注的消息。content 参数是消息内容,可以文本或二进制形式给出。 @@ -21668,7 +21478,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); 数据库对象管理函数 - 中所示的函数计算数据库对象的磁盘空间使用情况,或帮助表示或理解使用结果。 + 中所示的函数计算数据库对象的磁盘空间使用情况,或帮助展示使用结果。 所有这些函数返回的大小都以字节为单位。 如果将不代表已有对象的OID传递给这些函数之一,则返回NULL @@ -21716,7 +21526,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); 计算具有指定名称或OID的数据库使用的总磁盘空间。要使用此函数,您必须对指定数据库具有CONNECT权限 - (默认情况下授予),或者具有pg_read_all_stats角色的权限。 + (默认情况下授予),或者是pg_read_all_stats角色的成员。 @@ -21742,13 +21552,13 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); bigint - 计算指定关系的一个fork所使用的磁盘空间。 - (注意在大多数情况下,使用更高级的函数 pg_total_relation_sizepg_table_size更方便,它们将所有分叉(forks)的大小相加。) - 使用一个参数,这将返回关系的主数据分叉的大小。第二个参数可以用来指定要检查哪个分叉: + 计算指定关系的一个分支所使用的磁盘空间。 + (注意在大多数情况下,使用更高级的函数 pg_total_relation_sizepg_table_size更方便,它们将所有分支的大小相加。) + 使用一个参数,这将返回关系的主数据分支的大小。第二个参数可以用来指定要检查哪个分支: - main返回关系的主数据分叉的大小。 + main返回关系的主数据分支的大小。 @@ -21763,7 +21573,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); - init 返回初始化分叉的大小,如果有的话,与关系相关。 + init 返回与该关系关联的初始化分支(如有)的大小。 @@ -21779,7 +21589,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); bigint - 将人可阅读的格式的大小(由pg_size_pretty返回)转换为字节。 + 将人类可读格式的大小(由pg_size_pretty返回)转换为字节。 @@ -21796,7 +21606,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); text - 将字节大小转换为更易于人类阅读的格式,带有大小单位(字节,kB,MB,GB,TB或PB)。请注意,单位是2的幂,而不是10的幂,因此1kB是1024字节, + 将字节大小转换为更易于人类阅读的格式,带有大小单位(字节,kB,MB,GB或TB)。请注意,单位是2的幂,而不是10的幂,因此1kB是1024字节, 1MB是10242 = 1048576字节,依此类推。 @@ -21810,7 +21620,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); bigint - 计算指定表所使用的磁盘空间,不包括索引(但包括它的TOAST表,如果有的话,空闲空间映射,以及可见性映射)。 + 计算指定表所使用的磁盘空间,不包括索引(但包括其 TOAST 表(如有)、空闲空间映射和可见性映射)。 @@ -21829,7 +21639,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); 计算具有指定名称或OID的表空间中使用的总磁盘空间。 要使用此函数,您必须对指定的表空间具有CREATE权限, - 或者具有pg_read_all_stats角色的权限, + 或者是pg_read_all_stats角色的成员, 除非它是当前数据库的默认表空间。 @@ -21844,7 +21654,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); 计算指定表所使用的总磁盘空间,包括所有索引和TOAST数据。 - 结果等价pg_table_size + pg_indexes_size。 + 结果等价于pg_table_size + pg_indexes_size @@ -21854,7 +21664,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); 上述操作表和索引的函数接受一个regclass参数,它是该表或索引在pg_class系统目录中的 OID。 你不必手工去查找该 OID,因为regclass数据类型的输入转换器会为你代劳。 - 只写包围在单引号内的表名,这样它看起来像一个文字常量。 + 只写包围在单引号内的表名,这样它看起来像一个字面量。 为了与普通SQL名称的处理相兼容,该字符串将被转换为小写形式,除非其中在表名周围包含双引号。 @@ -21889,7 +21699,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); oid - 返回当前分配给指定关系的filenode数字。文件节点是用于该关系的文件名称的基本组件(更多信息请参阅 )。 + 返回当前分配给指定关系的文件结点编号。文件结点是用于该关系的文件名称的基本组件(更多信息请参阅 )。 对于大多数关系,其结果与pg_class.relfilenode相同,但对于某些系统目录,relfilenode为0,并且必须使用这个函数来获得正确的值。 如果传递的是一个没有存储的关系,例如一个视图,那么函数将返回NULL。 @@ -21904,7 +21714,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); text - 返回关系的完整文件路径名称(相对于数据库集簇的数据目录,即关系的PGDATA)。 + 返回关系的完整文件路径名称(相对于数据库集簇的数据目录,即PGDATA)。 @@ -21917,8 +21727,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); regclass - 返回一个给定表空间OID和存储它的文件节点的关系的OID。这本质上是pg_relation_filepath的反向映射。 - 对于数据库默认表空间中的关系,表空间可以指定为0。如果当前数据库中没有与给定值相关联的关系,则返回 NULL。 + 根据关系所在表空间的 OID 和文件结点返回该关系的 OID。这本质上是pg_relation_filepath的反向映射。对于数据库默认表空间中的关系,表空间可以指定为 0。如果当前数据库中没有与给定值关联的关系,或者该关系是临时关系,则返回NULL @@ -21969,13 +21778,13 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); integer - 基于在操作系统中找到的所有区域环境(locales),加入排序规则到系统目录pg_collation中。 - 这是 initdb 会用到的,更多细节请参考。 - 如果后来在操作系统上安装了额外的区域环境,可以再次运行这个函数加入新区域环境的排序规则。 - 匹配pg_collation中现有条目的区域环境将被跳过(但是这个函数不会移除以在操作系统中不再存在的区域环境为基础的排序规则对象)。 - schema参数通常是pg_catalog,但这并非强制要求,排序规则也可以安装到其他模式中。 - 该函数返回其创建的新排序规则对象的数量。 - 此函数仅限超级用户使用。 + 根据操作系统中找到的所有区域设置,向系统目录pg_collation添加排序规则。 + initdb使用的就是此函数;更多信息见。 + 如果以后在操作系统中安装了其他区域设置,可以再次运行此函数,为新区域设置添加排序规则。 + 与pg_collation中现有条目匹配的区域设置会被跳过。 + (但此函数不会删除基于操作系统中已不存在的区域设置的排序规则对象。) + schema参数通常为pg_catalog,但并非必须如此;也可以将排序规则安装到其他模式中。 + 函数返回新建的排序规则对象数量。此函数仅限超级用户使用。 @@ -22052,7 +21861,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); - 例如,要检查分区表measurement中包含的数据的总大小,可以使用以下查询: + 例如,要检查分区表measurement中包含的数据的总大小,可以使用以下查询: SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size FROM pg_partition_tree('measurement'); @@ -22067,7 +21876,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size 显示了索引维护任务可以使用的函数。 - (注意,这些维护任务通常由自动清理(autovacuum)自动完成;只有在特殊情况下才需要使用这些函数。) + (注意,这些维护任务通常由 autovacuum 自动完成;只有在特殊情况下才需要使用这些函数。) 这些函数在恢复过程中无法执行。这些函数的使用局限于超级用户和给定索引的所有者。 @@ -22098,7 +21907,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size integer - 扫描指定的BRIN索引以查找基表中当前尚未生成索引摘要的页面范围; + 扫描指定的BRIN索引以查找基表中当前尚未生成索引摘要的页面范围; 对于任何这样的范围,它都通过扫描这些表页来创建一个新的摘要索引元组。 返回插入到索引中的新页面范围摘要的数量。 @@ -22114,7 +21923,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size 对覆盖给定块的页面范围执行摘要(如果尚未摘要)。 - 这类似于brin_summarize_new_values,只是它只处理覆盖给定表块数的页范围。 + 这类似于brin_summarize_new_values,区别在于它只处理包含给定表块编号的页面范围。 @@ -22140,9 +21949,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size bigint - 清理指定GIN索引的pending列表,通过移除里面的条目,以大批的方式,到主要的GIN数据结构。 - 返回从挂起列表中删除的页数。如果参数是使用禁用fastupdate选项构建的GIN索引,则不会发生清理,结果为零,因为索引没有挂起的列表。 - 关于挂起列表和fastupdate选项的详细信息,请参见。 + 将指定 GIN 索引的待处理列表中的条目批量移入主 GIN 数据结构,从而清理该列表。返回从待处理列表中移除的页数。如果参数是禁用fastupdate选项构建的 GIN 索引,则不会进行清理,结果为零,因为该索引没有待处理列表。有关待处理列表和fastupdate选项的详细信息,参见 @@ -22156,21 +21963,16 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size 中展示的函数提供了对数据库服务器所在机器上的文件的本地访问。 - 只能访问数据库集簇目录以及log_directory中的文件,除非用户是超级用户或者被授予了角色pg_read_server_files。 + 只能访问数据库集簇目录以及log_directory中的文件,除非用户是超级用户或者被授予了角色pg_read_server_files。 使用相对路径访问集簇目录里面的文件,以及匹配 log_directory配置设置的路径访问日志文件。 - 注意在pg_read_file()或者相关函数上,向用户授予EXECUTE权限, - 以允许他们有能力读取服务器上该数据库服务器进程能读取的任何文件;这些函数会绕过所有的数据库内权限检查。 - 这意味着,例如,具有这种访问的用户能够读取pg_authid表中存储着认证信息的内容,也能读取数据库中的任何表数据。 - 因此,授予对这些函数的访问应该要很仔细地考虑。 + 注意,向用户授予pg_read_file()或相关函数的 EXECUTE 权限,会使其能够读取服务器上数据库服务器进程能读取的任何文件;这些函数会绕过数据库内部的所有权限检查。例如,具有这种访问权限的用户能够读取存储认证信息的pg_authid表的内容,以及数据库中的任何表数据。因此,授予这些函数的访问权限时应仔细考虑。 - 这些函数中的一些函数有可选的missing_ok参数,可以指定当文件或目录不存在时的行为。 - 如果为true,函数返回NULL或着空结果集,根据适合情况。 - 如果为false,会产生一个错误。默认为false。 + 这些函数中的一些函数接受可选的missing_ok参数,用于指定文件或目录不存在时的行为。如果为true,函数会视情况返回NULL或空结果集。如果为false,则会报错。默认为false @@ -22198,12 +22000,12 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size setof text - 返回指定目录中所有文件(和目录以及其他指定文件)的名称。 - include_dot_dirs参数标示在结果集中是否包括...;默认为不包括它们。 - 要包括它们在missing_oktrue时能够有用,以从不存在的目录中辨别一个空目录。 + 返回指定目录中所有文件的名称(包括目录及其他特殊文件)。 + include_dot_dirs参数指示结果集中是否包含...;默认不包含它们。 + 在missing_oktrue时,包含它们有助于区分不存在的目录和空目录。 - 这个函数默认限制为超级用户,但是其他用户可以被授予EXECUTE以运行此函数。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -22222,7 +22024,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size 返回服务器日志目录中每个普通文件的名称、大小和最后修改时间(mtime)。以点开头的文件名、目录和其他特殊文件将被排除。 - 默认情况下,此函数仅限于超级用户和具有pg_monitor角色权限的角色,但其他用户可以被授予EXECUTE权限来运行该函数。 + 默认情况下,此函数仅限超级用户和pg_monitor角色的成员使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -22242,8 +22044,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size 以点开头的文件名、目录和其他特殊文件将被排除。 - 默认情况下,此函数仅限于超级用户和具有pg_monitor角色权限的角色, - 但其他用户可以被授予EXECUTE权限来运行该函数。 + 默认情况下,此函数仅限超级用户和pg_monitor角色的成员使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -22259,11 +22060,11 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size modificationtimestamp with time zone ) - 返回服务器的WAL归档状态目录(pg_wal/archive_status)中的每个普通文件的名称、大小、和最后修改时间(mtime)。 - 文件名以一个点(dot)开始,目录和其他指定的文件不包括。 + 返回服务器 WAL 归档状态目录(pg_wal/archive_status)中每个普通文件的名称、大小和最后修改时间(mtime)。 + 以点号开头的文件名、目录以及其他特殊文件都不会包含在结果中。 - 这个函数默认限制在超级用户和pg_monitor角色的成员,但是其他用户可以被授予EXECUTE以运行此函数。 + 默认情况下,此函数仅限超级用户和pg_monitor角色的成员使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -22280,12 +22081,12 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size modificationtimestamp with time zone ) - 返回针对指定tablespace的临时文件目录中的每个普通文件的名称、大小、和最后修改时间(mtime)。 - 如果tablespace没有提供,pg_default 表空间为被检验的。 - 文件名以一个点(dot)开始,目录和其他指定的文件不包括。 + 返回针对指定tablespace的临时文件目录中每个普通文件的名称、大小和最后修改时间(mtime)。 + 如果未提供tablespace,则检查pg_default表空间。 + 以点号开头的文件名、目录以及其他特殊文件都不会包含在结果中。 - 这个函数默认限制在超级用户和pg_monitor角色的成员,但是其他用户可以被授予EXECUTE以运行此函数。 + 默认情况下,此函数仅限超级用户和pg_monitor角色的成员使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -22298,12 +22099,12 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size text - 返回一个文本文件的全部或部分,开始于给定的字节offset,在最大的length字节返回(如果文件的结尾先达到了则减少)。 - 如果offset为负,他于文件的结尾有关。如果offsetlength 被省略,整个文件被返回。 - 从文件中读的字节在服务器的编码中解释为字符串;如果它们在哪些编码中不是有效的则抛出错误。 + 返回一个文本文件的全部或部分,从给定的字节offset开始,最多返回length字节(如果先到达文件末尾,则返回更少)。 + 如果offset为负,则它相对于文件末尾计算。如果省略offsetlength,则返回整个文件。 + 从文件中读取的字节会按数据库编码解释为字符串;如果它们在该编码下无效,则会抛出错误。 - 这个函数默认限制在超级用户,但是其他用户可以被授予EXECUTE以运行此函数。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -22316,14 +22117,14 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size bytea - 返回文件的全部或部分。这个函数与pg_read_file 是完全相同的,除了它可以读任意的二进制数据,返回结果为bytea而不是text; - 因此,没有编码检查会被执行。 + 返回文件的全部或部分。该函数与pg_read_file完全相同,只是它可以读取任意二进制数据,并返回bytea而不是text; + 因此不会执行编码检查。 - 这个函数默认限制在超级用户,但是其他用户可以被授予EXECUTE以运行此函数。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 - 与 convert_from函数组合,这个函数能被用于以指定的编码读文本文件并转换到数据库的编码: + 与convert_from函数配合使用时,该函数可用于按指定编码读取文本文件,并将其转换为数据库编码: SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); @@ -22345,10 +22146,10 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); isdir boolean ) - 返回一个记录,包含文件的大小、最后访问时间戳、最后修改时间戳,最后文件状态变更时间戳(仅在UNIX平台)、文件建立时间戳(仅Windows),和一个标志旗如果它是一个目录。 + 返回一个记录,包含文件大小、最后访问时间戳、最后修改时间戳、最后文件状态变更时间戳(仅限 Unix 平台)、文件创建时间戳(仅限 Windows)以及一个指示其是否为目录的标志。 - 这个函数默认限制在超级用户,但是其他用户可以被授予EXECUTE以运行此函数。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -22367,11 +22168,11 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); - 所有这些函数都打算用于锁定应用程序定义的资源,可以通过一个64位键值或两个32位键值来标识(注意这两个键空间不能重叠)。 - 如果另一个会话已经在相同的资源标识符上持有一个冲突的锁,函数将等待直到资源变成可用,或者返回一个false结果,合适于函数的。 - 锁可以是共享或排他的:共享锁不会与同一资源上的其他共享锁发生冲突,只会与排他锁发生冲突。 - 锁可以在会话级(这样它们被保持直到释放或会话结束)或在事务级(这样它们被保持直到当前事务结束;没有手动释放的供应)。 - 多个会话级锁请求堆栈,因此如果同一个资源标识符被锁定三次,那么必须有三个解锁请求来释放资源,在会话结束之前。 + 这些函数用于锁定应用程序定义的资源;资源可用一个 64 位键值或两个 32 位键值标识(这两个键空间互不重叠)。 + 如果另一个会话已对同一资源标识符持有冲突锁,函数会根据自身的行为等待资源可用,或返回false。 + 锁可以是共享的或排他的:共享锁不会与同一资源上的其他共享锁冲突,只会与排他锁冲突。 + 锁可以在会话级获取(一直保持到释放或会话结束),也可以在事务级获取(一直保持到当前事务结束,不能手动释放)。 + 多次会话级锁请求会累加,因此,如果同一资源标识符被锁定三次,就必须请求解锁三次,才能在会话结束前释放该资源。
@@ -22522,8 +22323,8 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); boolean - 获取一个排他的会话级咨询锁,如果适用。 - 这将立即获得锁并返回true,或者如果不能立即获取锁则立即返回 false而无需等待。 + 尝试获取一个排他的会话级咨询锁。 + 如果能立即获取到锁,就返回true;否则立即返回false,而不等待。 @@ -22540,8 +22341,8 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); boolean - 获取一个共享的会话级咨询锁,如果适用。 - 这将立即获得锁并返回true,或者如果不能立即获取锁则立即返回 false而无需等待。 + 尝试获取一个共享的会话级咨询锁。 + 如果能立即获取到锁,就返回true;否则立即返回false,而不等待。 @@ -22558,8 +22359,8 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); boolean - 获取一个排他的事务级咨询锁,如果适用。 - 这将立即获得锁并返回true,或者如果不能立即获取锁则立即返回 false而无需等待。 + 尝试获取一个排他的事务级咨询锁。 + 如果能立即获取到锁,就返回true;否则立即返回false,而不等待。 @@ -22576,8 +22377,8 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); boolean - 获取一个共享的事务级咨询锁,如果适用。 - 这将立即获得锁并返回true,或者如果不能立即获取锁则立即返回 false而无需等待。 + 尝试获取一个共享的事务级咨询锁。 + 如果能立即获取到锁,就返回true;否则立即返回false,而不等待。 @@ -22631,7 +22432,7 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); trigger - 阻止不做事的更新操作。详见下文。 + 抑制不改变数据的更新操作。详见下文。 CREATE TRIGGER ... suppress_redundant_updates_trigger() @@ -22647,8 +22448,7 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); trigger - 自动从相关的纯文本文档列更新tsvector列。 - 要使用的文本搜索配置是以名称指定为触发器参数。详情请参见。 + 根据关联的纯文本文档列自动更新tsvector列。所用的全文检索配置以名称形式指定为触发器参数。详见 CREATE TRIGGER ... tsvector_update_trigger(tsvcol, 'pg_catalog.swedish', title, body) @@ -22664,8 +22464,7 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); trigger - 自动从相关的纯文本文档列更新tsvector列。 - 要使用的文本搜索配置取自表的regconfig列。详情请参见。 + 根据关联的纯文本文档列自动更新tsvector列。所用的全文检索配置取自表的regconfig列。详见 CREATE TRIGGER ... tsvector_update_trigger_column(tsvcol, tsconfigcol, title, body) @@ -22682,11 +22481,7 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); - 理想的情况下,你应该避免运行实际上并没有改变记录中数据的更新。 - 冗余更新会花费大量不必要的时间,尤其是如果有大量索引要改变, 并将最终不得不清理被死亡行占用的空间。 - 但是,在客户端代码中检测这种情况并不总是容易的,甚至不可能做到。 而写表达式来检测它们容易产生错误。 - 作为替代,使用suppress_redundant_updates_trigger可以跳过不改变数据的更新。 但是,你需要小心使用它。 - 触发器需要很短但不能忽略的时间来处理每条记录,所以如果受更新影响的大多数记录确实变化了,此触发器的使用将使更新比平均水平运行得更慢。 + 理想情况下,应避免执行实际上不会改变记录中数据的更新。冗余更新会耗费大量不必要的时间,尤其是在需要修改许多索引时;它们还会使死行占用空间,最终需要通过清理回收。但是,在客户端代码中检测这种情况并不总是容易,甚至可能无法做到,而编写用于检测的表达式也容易出错。另一种办法是使用suppress_redundant_updates_trigger,跳过不改变数据的更新。但使用时应当谨慎。此触发器处理每条记录的耗时虽小,却不可忽略,因此如果更新涉及的大多数记录确实会改变,使用此触发器反而会增加更新的平均耗时。 suppress_redundant_updates_trigger函数可以按如下方式添加到表中: @@ -22700,7 +22495,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); 事件触发器函数 - PostgreSQL提供了这些助手函数来从事件触发器检索信息。 + PostgreSQL提供了这些辅助函数来从事件触发器检索信息。 @@ -22722,7 +22517,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); 当在一个ddl_command_end事件触发器的函数中调用时,pg_event_trigger_ddl_commands返回被每一个用户动作执行的DDL命令的列表。 如果在其他任何环境中调用这个函数,会发生错误。 - pg_event_trigger_ddl_commands为每一个被执行的基本命令返回一行,某些只有一个单一 SQL 句子的命令可能会返回多于一行。 + pg_event_trigger_ddl_commands为每一个被执行的基本命令返回一行,某些由单条 SQL 语句构成的命令可能会返回多于一行。 这个函数返回下面的列: @@ -22739,7 +22534,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); classid oid - 对象所属的目录的 OID + 对象所属系统目录的 OID objid @@ -22749,7 +22544,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); objsubid integer - 对象的子-id(例如列的属性号) + 子对象 ID(例如列的属性编号) command_tag @@ -22765,16 +22560,14 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); schema_name text - 该对象所属的模式的名称(如果有),如果没有则为NULL。 - 没有引号。 + 对象所属模式的名称(若有);否则为NULL。不加引号。 object_identity text - 对象标识的文本表现形式,用模式限定。如果必要,出现在 - 该标识中的每一个标识符都会被引用。 + 对象标识的文本表示形式,带模式限定。标识中包含的每个标识符在必要时都会加引号。 @@ -22786,8 +22579,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); command pg_ddl_command - 以内部格式表达的该命令的一个完整表现形式。这不能被直接输出, - 但是可以把它传递给其他函数来得到有关于该命令不同部分的信息。 + 命令的完整内部表示,不能直接输出,但可以将其传给其他函数以获取关于该命令的不同信息。 @@ -22808,8 +22600,8 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); - pg_event_trigger_dropped_objects返回被调用sql_drop事件的命令删除的所有对象的列表。 - 如果调用在任何其他上下文中,会引发一个错误。这个函数返回以下列: + 在命令的sql_drop事件中调用pg_event_trigger_dropped_objects时,它返回该命令删除的所有对象的列表。 + 如果调用在任何其他上下文中,会引发一个错误。这个函数返回以下列: @@ -22825,7 +22617,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); classid oid - 对象所属的目录的 OID + 对象原先所属系统目录的 OID objid @@ -22835,7 +22627,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); objsubid integer - 子对象ID(如列的属性号) + 子对象 ID(例如列的属性编号) original @@ -22846,7 +22638,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); normal boolean - 指示在依赖图中有一个普通依赖关系指向该对象的标志 + 如果依赖图中存在指向该对象的普通依赖关系,则为真。 @@ -22865,29 +22657,28 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); schema_name text - 对象所属模式的名称(如果存在);否则为NULL。不应用引用。 + 对象原先所属模式的名称(若有);否则为NULL。不加引号。 object_name text - 如果模式和名称的组合能被用于对象的一个唯一标识符,则是对象的名称;否则是NULL。不应用引用,并且名称不是模式限定的。 + 如果模式和名称的组合可用作该对象的唯一标识符,则为对象名称;否则为NULL。不加引号,并且该名称永远不带模式限定。 object_identity text - 对象身份的文本表现,模式限定的。每一个以及所有身份中出现的标识符在必要时加引号。 + 对象标识的文本表示形式,带模式限定。标识中包含的每个标识符在必要时都会加引号。 address_names text[] - 一个数组,它可以和object_typeaddress_args, - 一起通过pg_get_object_address函数在一台包含有同类相同名称对象的远程服务器上重建该对象地址。 + 一个数组,可与object_typeaddress_args一起,通过pg_get_object_address函数在包含同类同名对象的远程服务器上重建该对象地址。 @@ -22981,7 +22772,7 @@ CREATE EVENT TRIGGER test_event_trigger_for_drops
- 这些函数可以在事件触发器中使用,就像这样: + 这些函数可以在事件触发器中使用,就像这样: CREATE FUNCTION test_event_trigger_table_rewrite_oid() RETURNS event_trigger @@ -23006,12 +22797,12 @@ CREATE EVENT TRIGGER test_table_rewrite_oid 统计信息函数 - function - statistics + 函数 + 统计信息 - PostgreSQL提供了一个函数来检查使用CREATE STATISTICS命令定义的复杂统计。 + PostgreSQL提供了一个函数来检查使用CREATE STATISTICS命令定义的复杂统计信息。 @@ -23026,7 +22817,7 @@ CREATE EVENT TRIGGER test_table_rewrite_oid - pg_mcv_list_items返回一组记录,描述存储在多列MCV列表中的所有项目。它返回以下列: + pg_mcv_list_items返回一组记录,描述存储在多列MCV列表中的所有项目。它返回以下列: @@ -23062,7 +22853,7 @@ CREATE EVENT TRIGGER test_table_rewrite_oid base_frequency double precision - MCV项目的基本频率 + MCV项目的基础频率 diff --git a/zh/13/gin.sgml b/zh/13/gin.sgml index 81043ae8..51d5fc8a 100644 --- a/zh/13/gin.sgml +++ b/zh/13/gin.sgml @@ -53,7 +53,7 @@ 内置操作符类 - PostgreSQL 核心发布包含 + PostgreSQL 核心发行版包含 所示的 GIN 操作符类。 (在 中描述的一些可选模块还提供额外的 GIN 操作符类。) @@ -64,7 +64,7 @@ 名称 - 索引数据类型 + 被索引数据类型 可索引操作符 @@ -129,7 +129,10 @@ GIN 将可扩展性与通用性、代码重用以及清晰的接口结合在一起。 - GIN中,操作符类必须提供以下两个方法: + + GIN 操作符类必须提供两个方法: + + Datum *extractValue(Datum itemValue, int32 *nkeys, bool **nullFlags) @@ -138,7 +141,7 @@ 给定一个要建立索引的项,返回一个用 palloc 分配的键数组。返回键的数量必须存入 *nkeys。如果任一键可以为 null,还要另外 palloc 一个包含 *nkeysbool 字段的数组,将其地址存入 - *nullFlags,并按需设置这些空值标志。如果所有键都非空, + *nullFlags,并按需设置这些空值标志。如果所有键都不是 null, *nullFlags 可以保持为 NULL(其初始值)。 如果该项不包含任何键,则返回值可以为 NULL @@ -158,7 +161,7 @@ query 的数据类型,以及应采用何种方法提取键值。返回键的数量必须存入 *nkeys。如果任一键可以为 null,还要另外 palloc 一个包含 *nkeysbool 字段的数组,将其地址存入 - *nullFlags,并按需设置这些空值标志。如果所有键都非空, + *nullFlags,并按需设置这些空值标志。如果所有键都不是 null, *nullFlags 可以保持为 NULL(其初始值)。 如果 query 不包含任何键,则返回值可以为 NULL @@ -171,7 +174,7 @@ 被设置为 GIN_SEARCH_MODE_INCLUDE_EMPTY,则除至少包含一个匹配键的项之外, 完全不含任何键的项也会被视为候选匹配。(例如,该模式对于实现是子集操作符很有用。) 若 *searchMode 被设置为 GIN_SEARCH_MODE_ALL, - 则索引中所有非空项都会被视为候选匹配,无论它们是否匹配任一返回键。 + 则索引中所有非 null 项都会被视为候选匹配,无论它们是否匹配任一返回键。 (该模式比前两种选择慢得多,因为它基本上需要扫描整个索引;但为了正确处理某些边界情况, 可能有此必要。在大多数情况下都需要此模式的操作符,大概并不适合作为 GIN 操作符类的候选。)用于设置该模式的符号定义在 @@ -199,7 +202,15 @@ - 操作符类还必须提供一个函数,用于检查被索引项是否匹配查询。它有两种形式:布尔型consistent函数和三值triConsistent函数。triConsistent涵盖两者的功能,因此只提供triConsistent即可。不过,如果布尔版本的计算代价明显更低,同时提供两者可能更有利。如果只提供布尔版本,则会禁用某些优化,这些优化依赖于在获取所有键之前排除不匹配的索引项。 + + + 操作符类还必须提供一个函数,用于检查被索引项是否匹配查询。它有两种形式:布尔型 + consistent 函数,以及三值型 triConsistent 函数。 + triConsistent 覆盖了两者的功能,因此仅提供 triConsistent + 就已经足够。不过,如果布尔变体的计算代价明显更低,那么同时提供两者可能更有利。 + 若只提供布尔变体,则一些依赖于在取回所有键之前先排除索引项的优化将被禁用。 + + bool consistent(bool check[], StrategyNumber n, Datum query, int32 nkeys, Pointer extra_data[], bool *recheck, @@ -211,10 +222,10 @@ 该函数无法直接访问被索引项的值,因为 GIN 并不显式存储项。 它所能利用的是这样一种信息:从查询中提取出的哪些键值出现在给定的被索引项中。 check 数组长度为 nkeys,这与先前针对该 - query 数据由 extractQuery 返回的键数量相同。 + query datum 由 extractQuery 返回的键数量相同。 如果被索引项包含相应查询键,则 check 数组中的对应元素为 true; 也就是说,如果 (check[i] == true),则 extractQuery - 结果数组中的第 i 个键存在于该被索引项中。传入原始 query 数据值, + 结果数组中的第 i 个键存在于该被索引项中。传入原始 query datum, 是为了让 consistent 方法在需要时可以查看它;同样也会传入先前由 extractQuery 返回的 queryKeys[]nullFlags[] 数组。extra_data 则是 @@ -252,7 +263,7 @@ 而 GIN_MAYBE 表示该键是否存在尚不确定。存在 GIN_MAYBE 值时,只有当无论索引项是否包含对应查询键,该项都确定匹配时,函数才应返回 GIN_TRUE。同样,只有当无论是否包含 GIN_MAYBE 键, - 该项都确定不匹配时,函数才必须返回 GIN_FALSE。如果结果依赖于 + 该项都确定不匹配时,函数才能返回 GIN_FALSE。如果结果依赖于 GIN_MAYBE 条目,也就是说,无法根据已知的查询键确认或否定匹配, 则函数必须返回 GIN_MAYBE @@ -266,7 +277,11 @@ - 此外,GIN 必须能够对索引中存储的键值排序。操作符类可以通过指定比较方法来定义排序顺序: + + 此外,GIN 必须有一种方法对存储在索引中的键值进行排序。 + 操作符类可以通过指定一个比较方法来定义这种排序顺序: + + int compare(Datum a, Datum b) @@ -276,9 +291,18 @@ - 或者,如果操作符类没有提供compare方法,GIN 就会查找索引键数据类型的默认 btree 操作符类,并使用其比较函数。对于只适用于一种数据类型的 GIN 操作符类,建议指定比较函数,因为查找 btree 操作符类需要耗费一些处理器周期。但是,多态 GIN 操作符类(例如array_ops)通常无法指定单一的比较函数。 + - GIN中,操作符类可以选择提供以下方法: + 或者,如果操作符类没有提供 compare 方法,GIN + 将查找该索引键数据类型的默认 B-树操作符类,并使用其比较函数。建议在仅面向单一数据类型的 + GIN 操作符类中显式指定比较函数,因为查找 B-树操作符类会消耗少量处理器周期。 + 不过,多态 GIN 操作符类(例如 array_ops)通常无法指定单一比较函数。 + + + + 用于 GIN 的操作符类还可以选择性提供下列方法: + + int comparePartial(Datum partial_key, Datum key, StrategyNumber n, Pointer extra_data) @@ -339,8 +363,8 @@ 在内部,一个 GIN 索引包含一个基于键构建的 B-树索引,其中每个键都是一个或多个被索引项中的某个元素 - (例如数组成员),而叶子页中的每个元组要么包含一个指向堆指针 B-树的指针(posting tree), - 要么在列表足够小、能够连同键值一起放入单个索引元组时,直接包含一个简单的堆指针列表(posting list)。 + (例如数组成员),而叶子页中的每个元组要么包含一个指向堆指针 B-树的指针(倒排树), + 要么在列表足够小、能够连同键值一起放入单个索引元组时,直接包含一个简单的堆指针列表(倒排列表)。 展示了 GIN 索引的这些组成部分。 @@ -387,7 +411,7 @@ - 如果一致的响应时间比更新速度更重要,可以通过关闭 GIN 索引的 + 如果稳定的响应时间比更新速度更重要,可以通过关闭 GIN 索引的 fastupdate 存储参数来禁用待处理列表机制。详见 @@ -423,7 +447,7 @@ 因此,对于向表中执行的批量插入,建议先删除 GIN 索引,待批量插入完成后再重建它。 - PostgreSQL 8.4 开始,由于采用了延迟索引,这项建议已不那么必要(详见)。但对于非常大的更新,最好仍然是删除并重建索引。 + PostgreSQL 8.4 开始,由于采用了延迟索引,这项建议已不那么必要(详见)。但对于非常大的更新,删除并重建索引仍然可能是最佳选择。 @@ -490,14 +514,19 @@ GIN 假定可索引操作符是严格的。这意味着,当项值为 null 时, 根本不会对其调用 extractValue(而是自动创建一个占位符索引项); 当查询值为 null 时,也不会调用 extractQuery(而是认为该查询不可满足)。 - 不过要注意,非空组合项或查询值内部包含的 null 键值仍然受支持。 + 不过要注意,非 null 的组合项或查询值内部包含的 null 键值仍然受支持。 示例 - PostgreSQL核心发行版包含GIN操作符类,见前文。以下contrib模块也包含GIN操作符类: + + PostgreSQL 核心发行版包含前面在 + 中展示过的 GIN 操作符类。 + 下列 contrib 模块也包含 GIN 操作符类: + + btree_gin diff --git a/zh/13/gist.sgml b/zh/13/gist.sgml index d92ad501..24649554 100644 --- a/zh/13/gist.sgml +++ b/zh/13/gist.sgml @@ -4,7 +4,7 @@ GiST 索引 - index + 索引 GiST @@ -45,7 +45,7 @@ 名称 - 索引数据类型 + 被索引数据类型 可索引操作符 排序操作符 @@ -126,7 +126,7 @@ CREATE INDEX ON my_table USING GIST (my_inet_column inet_ops); - 这种可扩展性不应与其他标准搜索树在可处理数据方面的可扩展性相混淆。例如,PostgreSQL支持可扩展的 B-树和哈希索引。这意味着你可以用PostgreSQL在任意数据类型上构建 B-树或哈希索引。但 B-树只支持范围谓词(<=>),而哈希索引只支持等值查询。 + 这种可扩展性不应与其他标准搜索树在可处理数据方面的可扩展性相混淆。例如,PostgreSQL支持可扩展的 B-树和 hash 索引。这意味着你可以用PostgreSQL在任意数据类型上构建 B-树或 hash 索引。但 B-树只支持范围谓词(<=>),而 hash 索引只支持等值查询。 @@ -150,12 +150,19 @@ CREATE INDEX ON my_table USING GIST (my_inet_column inet_ops); indexable_operator q为真。对于叶子索引项,这等同于测试该可索引条件;而对于内部树节点,这决定是否有必要扫描该树节点所表示的索引子树。当结果为true时,还必须返回一个recheck标志。它表示该谓词是确定为真,还是仅可能为真。如果recheck = false,则该索引已经精确测试了谓词条件;如果recheck = true,则该行只是候选匹配。在这种情况下,系统会自动针对实际行值计算indexable_operator,以判断它是否真的匹配。这种约定使GiST能够同时支持无损和有损的索引结构。 - SQL声明必须如下所示: + + 该函数的SQL声明必须如下所示: + + CREATE OR REPLACE FUNCTION my_consistent(internal, data_type, smallint, oid, internal) RETURNS bool AS 'MODULE_PATHNAME' LANGUAGE C STRICT; -C 模块中相应的代码可以采用以下框架: + + + 而 C 模块中的对应代码则可以遵循如下框架: + + PG_FUNCTION_INFO_V1(my_consistent); Datum @@ -170,19 +177,21 @@ my_consistent(PG_FUNCTION_ARGS) bool retval; /* - * determine return value as a function of strategy, key and query. + * 根据 strategy、key 和 query 确定返回值。 * - * Use GIST_LEAF(entry) to know where you're called in the index tree, - * which comes handy when supporting the = operator for example (you could - * check for non empty union() in non-leaf nodes and equality in leaf - * nodes). + * 使用 GIST_LEAF(entry) 判断当前调用位于索引树的哪个位置。 + * 例如,支持 = 操作符时这很有用(可以在非叶节点检查 + * union() 是否非空,在叶节点检查是否相等)。 */ - *recheck = true; /* or false if check is exact */ + *recheck = true; /* 如果检查是精确的,则为 false */ PG_RETURN_BOOL(retval); } -这里,key是索引中的元素,query是要在索引中查找的值。StrategyNumber参数指明正在应用操作符类中的哪个操作符,它对应于CREATE OPERATOR CLASS命令中的某个操作符编号。 + + + 这里,key是索引中的一个元素,而query是在该索引中查找的值。StrategyNumber参数指示应用的是操作符类中的哪个操作符,它对应于CREATE OPERATOR CLASS命令中的某个操作符编号。 + 取决于你在该类中包含了哪些操作符,query的数据类型可能会随操作符而变化,因为它将是操作符右侧的类型,而这可能不同于左侧出现的被索引数据类型。(上面的代码框架假定只可能有一种类型;如果不是这样,获取query参数值的方式就必须依赖于具体的操作符。)建议在consistent函数的 SQL 声明中,对query参数使用该操作符类的被索引数据类型,即使实际类型可能因为操作符不同而有所不同。 @@ -198,12 +207,19 @@ my_consistent(PG_FUNCTION_ARGS) 该方法用于汇总树中的信息。给定一组项,该函数生成一个新的索引项,用来表示所有给定项。 - SQL声明必须如下所示: + + 该函数的SQL声明必须如下所示: + + CREATE OR REPLACE FUNCTION my_union(internal, internal) RETURNS storage_type AS 'MODULE_PATHNAME' LANGUAGE C STRICT; -C 模块中相应的代码可以采用以下框架: + + + 而 C 模块中的对应代码则可以遵循如下框架: + + PG_FUNCTION_INFO_V1(my_union); Datum @@ -261,12 +277,19 @@ my_union(PG_FUNCTION_ARGS) 将一个数据项转换成适合在索引页中物理存储的格式。如果省略compress方法,数据项将不经修改地存储在索引中。 - SQL声明必须如下所示: + + 该函数的SQL声明必须如下所示: + + CREATE OR REPLACE FUNCTION my_compress(internal) RETURNS internal AS 'MODULE_PATHNAME' LANGUAGE C STRICT; -C 模块中相应的代码可以采用以下框架: + + + 而 C 模块中的对应代码则可以遵循如下框架: + + PG_FUNCTION_INFO_V1(my_compress); Datum @@ -277,10 +300,10 @@ my_compress(PG_FUNCTION_ARGS) if (entry->leafkey) { - /* replace entry->key with a compressed version */ + /* 将 entry->key 替换为压缩后的形式 */ compressed_data_type *compressed_data = palloc(sizeof(compressed_data_type)); - /* fill *compressed_data from entry->key ... */ + /* 根据 entry->key 填充 *compressed_data ... */ retval = palloc(sizeof(GISTENTRY)); gistentryinit(*retval, PointerGetDatum(compressed_data), @@ -288,7 +311,7 @@ my_compress(PG_FUNCTION_ARGS) } else { - /* typically we needn't do anything with non-leaf entries */ + /* 通常无需对非叶项做任何处理 */ retval = entry; } @@ -310,12 +333,19 @@ my_compress(PG_FUNCTION_ARGS) 将数据项的存储表示转换成操作符类中其他 GiST 方法能够操作的格式。如果省略decompress方法,就假定其他 GiST 方法可以直接处理存储的数据格式。(decompress不一定是compress方法的逆操作;特别是如果compress是有损的,那么decompress就不可能精确重建原始数据。decompress也不一定等同于fetch,因为其他 GiST 方法未必需要把数据完全重建出来。) - SQL声明必须如下所示: + + 该函数的SQL声明必须如下所示: + + CREATE OR REPLACE FUNCTION my_decompress(internal) RETURNS internal AS 'MODULE_PATHNAME' LANGUAGE C STRICT; -C 模块中相应的代码可以采用以下框架: + + + 而 C 模块中的对应代码则可以遵循如下框架: + + PG_FUNCTION_INFO_V1(my_decompress); Datum @@ -323,7 +353,10 @@ my_decompress(PG_FUNCTION_ARGS) { PG_RETURN_POINTER(PG_GETARG_POINTER(0)); } -上述框架适用于无需解压缩的情况。(当然,完全省略该方法更简单,这种情况下也建议如此。) + + + 上述框架适用于不需要解压的情况。(当然,在这种情况下,直接完全省略该方法会更简单,而且也推荐这么做。) + @@ -334,12 +367,19 @@ my_decompress(PG_FUNCTION_ARGS) 返回一个值,指示把新项插入树中特定分支的代价。项会沿着树中penalty最小的路径插入。penalty返回的值应为非负;如果返回负值,它将被按零处理。 - SQL声明必须如下所示: + + 该函数的SQL声明必须如下所示: + + CREATE OR REPLACE FUNCTION my_penalty(internal, internal, internal) RETURNS internal AS 'MODULE_PATHNAME' -LANGUAGE C STRICT; -- in some cases penalty functions need not be strict -C 模块中相应的代码可以采用以下框架: +LANGUAGE C STRICT; -- 某些情况下 penalty 函数不必是严格函数 + + + 而 C 模块中的对应代码则可以遵循如下框架: + + PG_FUNCTION_INFO_V1(my_penalty); Datum @@ -354,7 +394,10 @@ my_penalty(PG_FUNCTION_ARGS) *penalty = my_penalty_implementation(orig, new); PG_RETURN_POINTER(penalty); } -由于历史原因,penalty函数不能仅仅返回一个float结果,而必须将该值存储到第三个参数指向的位置。函数自身的返回值会被忽略,但通常会返回该参数的地址。 + + + 出于历史原因,penalty函数并不是直接返回一个float结果;相反,它必须把该值存储到第三个参数指示的位置。返回值本身会被忽略,不过通常会返回该参数所指向的地址。 + penalty函数对于索引的良好性能至关重要。它会在插入时用于决定在树中应沿着哪个分支向下,以便选择把新项加到哪里。在查询时,索引越平衡,查找就越快。 @@ -369,12 +412,19 @@ my_penalty(PG_FUNCTION_ARGS) 当索引页必须分裂时,该函数决定页面上的哪些项留在旧页中,哪些移到新页中。 - SQL声明必须如下所示: + + 该函数的SQL声明必须如下所示: + + CREATE OR REPLACE FUNCTION my_picksplit(internal, internal) RETURNS internal AS 'MODULE_PATHNAME' LANGUAGE C STRICT; -C 模块中相应的代码可以采用以下框架: + + + 而 C 模块中的对应代码则可以遵循如下框架: + + PG_FUNCTION_INFO_V1(my_picksplit); Datum @@ -407,7 +457,7 @@ my_picksplit(PG_FUNCTION_ARGS) unionL = NULL; unionR = NULL; - /* Initialize the raw entry vector. */ + /* 初始化原始项向量。 */ raw_entryvec = (GISTENTRY **) malloc(entryvec->n * sizeof(void *)); for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) raw_entryvec[i] = &(entryvec->vector[i]); @@ -420,9 +470,9 @@ my_picksplit(PG_FUNCTION_ARGS) Assert(tmp_union != NULL); /* - * Choose where to put the index entries and update unionL and unionR - * accordingly. Append the entries to either v->spl_left or - * v->spl_right, and care about the counters. + * 选择索引项的存放位置,并相应更新 unionL 和 unionR。 + * 将项追加到 v->spl_left 或 v->spl_right, + * 同时更新计数器。 */ if (my_choice_is_left(unionL, curl, unionR, curr)) @@ -439,7 +489,7 @@ my_picksplit(PG_FUNCTION_ARGS) else { /* - * Same on the right + * 对右侧执行相同操作 */ } } @@ -448,7 +498,9 @@ my_picksplit(PG_FUNCTION_ARGS) v->spl_rdatum = DataTypeGetDatum(unionR); PG_RETURN_POINTER(v); } -注意,picksplit函数通过修改传入的v结构体来传递结果。函数自身的返回值会被忽略,但通常会返回以下结构体的地址:v。 + + + 注意,picksplit函数的结果是通过修改传入的v结构体来传递的。返回值本身会被忽略,不过通常会返回v的地址。 @@ -464,12 +516,19 @@ my_picksplit(PG_FUNCTION_ARGS) 如果两个索引项相同则返回真,否则返回假。(索引项是索引存储类型的值,不一定是原始被索引列的类型。) - SQL声明必须如下所示: + + 该函数的SQL声明必须如下所示: + + CREATE OR REPLACE FUNCTION my_same(storage_type, storage_type, internal) RETURNS internal AS 'MODULE_PATHNAME' LANGUAGE C STRICT; -C 模块中相应的代码可以采用以下框架: + + + 而 C 模块中的对应代码则可以遵循如下框架: + + PG_FUNCTION_INFO_V1(my_same); Datum @@ -482,7 +541,10 @@ my_same(PG_FUNCTION_ARGS) *result = my_eq(v1, v2); PG_RETURN_POINTER(result); } -由于历史原因,same函数不能仅仅返回布尔结果,而必须将该标志存储到第三个参数指向的位置。函数自身的返回值会被忽略,但通常会返回该参数的地址。 + + + 出于历史原因,same函数并不是直接返回一个布尔结果;相反,它必须把该标志存储到第三个参数指示的位置。返回值本身会被忽略,不过通常会返回该参数所指向的地址。 + @@ -493,12 +555,19 @@ my_same(PG_FUNCTION_ARGS) 给定一个索引项p和一个查询值q,该函数确定索引项与查询值之间的距离。如果操作符类包含任何排序操作符,就必须提供此函数。使用排序操作符的查询会优先返回距离值最小的索引项,因此结果必须与该操作符的语义一致。对于叶子索引项,结果仅表示到该索引项的距离;对于内部树节点,结果必须是其任意子项可能具有的最小距离。 - SQL声明必须如下所示: + + 该函数的SQL声明必须如下所示: + + CREATE OR REPLACE FUNCTION my_distance(internal, data_type, smallint, oid, internal) RETURNS float8 AS 'MODULE_PATHNAME' LANGUAGE C STRICT; -C 模块中相应的代码可以采用以下框架: + + + 而 C 模块中的对应代码则可以遵循如下框架: + + PG_FUNCTION_INFO_V1(my_distance); Datum @@ -513,19 +582,22 @@ my_distance(PG_FUNCTION_ARGS) double retval; /* - * determine return value as a function of strategy, key and query. + * 根据 strategy、key 和 query 确定返回值。 */ PG_RETURN_FLOAT8(retval); } -distance函数的参数与consistent函数的参数完全相同。 + + + distance函数的参数与consistent函数的参数完全相同。 + - 在确定距离时允许有一定近似,只要结果永不大于该项的实际距离即可。因此,例如在几何应用中,到外包盒的距离通常就足够了。对于内部树节点,返回的距离不能大于其任一子节点的距离。如果返回的距离不精确,函数必须将*recheck设为 true。(对内部树节点则不必这样做;对它们总是假定计算结果不精确。)在这种情况下,执行器会在从堆中取出元组后计算准确距离,并在必要时重新排序这些元组。 + 在确定距离时允许有一定近似,只要结果永不大于该项的实际距离即可。因此,例如在几何应用中,到包围盒的距离通常就足够了。对于内部树节点,返回的距离不能大于其任一子节点的距离。如果返回的距离不精确,函数必须将*recheck设为 true。(对内部树节点则不必这样做;对它们总是假定计算结果不精确。)在这种情况下,执行器会在从堆中取出元组后计算准确距离,并在必要时重新排序这些元组。 - 如果距离函数对任何叶节点都返回*recheck = true,原始排序操作符的返回类型必须是float8float4,且距离函数的结果值必须能与原始排序操作符的结果进行比较,因为执行器会同时使用距离函数结果和重新计算得到的排序操作符结果进行排序。否则,距离函数的结果值可以是任意有限的float8值,只要这些结果值的相对顺序与排序操作符返回的顺序一致即可。(无穷大和负无穷在内部用于处理空值等情况,因此不建议distance函数返回这些值。) + 如果距离函数对任意一个叶节点返回*recheck = true,原始排序操作符的返回类型必须是float8float4,且距离函数的结果值必须能与原始排序操作符的结果进行比较,因为执行器会同时使用距离函数结果和重新计算得到的排序操作符结果进行排序。否则,距离函数的结果值可以是任意有限的float8值,只要这些结果值的相对顺序与排序操作符返回的顺序一致即可。(无穷大和负无穷在内部用于处理空值等情况,因此不建议distance函数返回这些值。) @@ -538,12 +610,18 @@ my_distance(PG_FUNCTION_ARGS) 为了支持仅索引扫描,将数据项的压缩索引表示转换为原始数据类型。返回的数据必须是最初被索引值的精确、无损副本。 - SQL声明必须如下所示: + + 该函数的SQL声明必须如下所示: + + CREATE OR REPLACE FUNCTION my_fetch(internal) RETURNS internal AS 'MODULE_PATHNAME' LANGUAGE C STRICT; -参数是一个指向GISTENTRY结构体的指针。进入该函数时,它的key字段包含一个压缩形式的非 NULL 叶子 datum。返回值是另一个GISTENTRY结构体,其中的key字段以原始、未压缩形式包含同一个 datum。如果该操作符类的 compress 函数对叶子项不做任何处理,fetch方法可以原样返回参数。如果操作符类没有 compress 函数,则fetch方法也可以省略,因为它必然不会执行任何实际操作。 + + + 参数是一个指向GISTENTRY结构体的指针。进入该函数时,它的key字段包含一个压缩形式的非 NULL 叶子 datum。返回值是另一个GISTENTRY结构体,其key字段以原始、未压缩形式包含同一个 datum。如果该操作符类的 compress 函数对叶子项不做任何处理,fetch方法可以原样返回该参数。或者,如果该操作符类没有 compress 函数,那么fetch方法也可以省略,因为它必然是空操作。 + 而 C 模块中的对应代码则可以遵循如下框架: @@ -563,10 +641,10 @@ my_fetch(PG_FUNCTION_ARGS) fetched_data = palloc(sizeof(fetched_data_type)); /* - * Convert 'fetched_data' into the a Datum of the original datatype. + * 将 'fetched_data' 转换为原始数据类型的 Datum。 */ - /* fill *retval from fetched_data. */ + /* 根据 fetched_data 填充 *retval。 */ gistentryinit(*retval, PointerGetDatum(converted_datum), entry->rel, entry->page, entry->offset, FALSE); @@ -589,7 +667,10 @@ my_fetch(PG_FUNCTION_ARGS) 允许定义用户可见参数,用来控制操作符类的行为。 - SQL声明必须如下所示: + + 该函数的SQL声明必须如下所示: + + CREATE OR REPLACE FUNCTION my_options(internal) RETURNS void AS 'MODULE_PATHNAME' @@ -601,7 +682,10 @@ LANGUAGE C STRICT; 该函数会收到一个指向local_relopts结构体的指针,需要在其中填充一组选项,这些选项是该操作符类特有的。其他支持函数可以使用PG_HAS_OPCLASS_OPTIONS()PG_GET_OPCLASS_OPTIONS()宏来访问这些选项。 - 下面给出了 my_options() 的一个实现示例,以及其他支持函数如何使用这些参数: + + 下面给出了 my_options() 的一个实现示例,以及其他支持函数如何使用这些参数: + + typedef enum MyEnumType { MY_ENUM_ON, @@ -611,26 +695,26 @@ typedef enum MyEnumType typedef struct { - int32 vl_len_; /* varlena header (do not touch directly!) */ - int int_param; /* integer parameter */ - double real_param; /* real parameter */ - MyEnumType enum_param; /* enum parameter */ - int str_param; /* string parameter */ + int32 vl_len_; /* varlena 首部(不要直接操作!) */ + int int_param; /* 整数参数 */ + double real_param; /* 实数参数 */ + MyEnumType enum_param; /* 枚举参数 */ + int str_param; /* 字符串参数 */ } MyOptionsStruct; -/* String representation of enum values */ +/* 枚举值的字符串表示 */ static relopt_enum_elt_def myEnumValues[] = { {"on", MY_ENUM_ON}, {"off", MY_ENUM_OFF}, {"auto", MY_ENUM_AUTO}, - {(const char *) NULL} /* list terminator */ + {(const char *) NULL} /* 列表终止项 */ }; static char *str_param_default = "default"; /* - * Sample validator: checks that string is not longer than 8 bytes. + * 验证器示例:检查字符串长度不超过 8 字节。 */ static void validate_my_string_relopt(const char *value) @@ -642,7 +726,7 @@ validate_my_string_relopt(const char *value) } /* - * Sample filler: switches characters to lower case. + * 填充函数示例:将字符转换为小写。 */ static Size fill_my_string_relopt(const char *value, void *ptr) @@ -695,10 +779,9 @@ my_compress(PG_FUNCTION_ARGS) char *str_param = str_param_default; /* - * Normally, when opclass contains 'options' method, then options are always - * passed to support functions. However, if you add 'options' method to - * existing opclass, previously defined indexes have no options, so the - * check is required. + * 通常,操作符类包含 'options' 方法时,总会把选项传给支持函数。 + * 但是,如果把 'options' 方法添加到已有操作符类中, + * 先前定义的索引没有选项,因此需要进行检查。 */ if (PG_HAS_OPCLASS_OPTIONS()) { @@ -710,7 +793,7 @@ my_compress(PG_FUNCTION_ARGS) str_param = GET_STRING_RELOPTION(options, str_param); } - /* the rest implementation of support function */ + /* 支持函数的其余实现 */ } @@ -750,7 +833,10 @@ my_compress(PG_FUNCTION_ARGS) 示例 - PostgreSQL源码发行包包含若干使用GiST实现索引方法的示例。核心系统目前提供文本搜索支持(为tsvectortsquery建立索引),还为部分内置几何数据类型提供等价于 R 树的功能(参见src/backend/access/gist/gistproc.c)。以下contrib模块也包含GiST操作符类: + + PostgreSQL源代码发行包包含了若干使用GiST实现的索引方法示例。核心系统目前提供了文本搜索支持(为tsvectortsquery建立索引),并为某些内置几何数据类型提供了与 R 树等价的功能(见src/backend/access/gist/gistproc.c)。下列contrib模块中也包含GiST操作符类: + + btree_gist @@ -768,7 +854,7 @@ my_compress(PG_FUNCTION_ARGS) hstore - 用于存储 (key, value) 对的模块 + 用于存储(键,值)对的模块 diff --git a/zh/13/glossary.sgml b/zh/13/glossary.sgml index 788881d4..e91f0223 100644 --- a/zh/13/glossary.sgml +++ b/zh/13/glossary.sgml @@ -255,7 +255,11 @@ 客户端(进程) - 一个可能位于远程的进程,会建立会话,具体方式是连接到一个实例,以便访问数据库。 + + 任何进程,可能是远程的,通过连接到某个 + 实例来建立 + 会话, + 以与一个数据库交互。 @@ -636,7 +640,11 @@ 主机 - 通过网络与其他计算机通信的计算机。有时用作服务器的同义词,也用于指运行客户端进程的计算机。 + + 一台通过网络与其他计算机通信的计算机。这个术语有时被用作 + 服务器的同义词。 + 它也用来指客户端进程运行所在的计算机。 + @@ -671,8 +679,22 @@ 实例 - 通过同一共享内存区域进行通信的一组后端进程和辅助进程。一个postmaster 进程管理该实例;一个实例恰好管理一个数据库集簇及其所有数据库。同一台服务器上可以运行多个实例,只要它们的TCP端口不冲突。 - 实例负责处理DBMS的所有关键功能:读写文件和共享内存、保证ACID属性、维护连接以服务于客户端进程、权限验证、崩溃恢复、复制等。 + + 一组后端进程和 + 辅助进程, + 它们使用同一块共享内存区域进行通信。一个 + postmaster 进程 + 管理该实例;一个实例恰好管理一个 + 数据库集簇 + 及其所有数据库。只要 TCP 端口不冲突, + 同一台服务器上可以运行多个实例。 + + + 实例处理 DBMS 的所有关键特性: + 对文件和共享内存的读写访问、保证 ACID 属性、 + 与客户端进程连接、 + 权限验证、崩溃恢复、复制等。 + @@ -855,10 +877,23 @@ - 分区表而言,分区是包含该分区表一部分数据的表之一;该分区表称为父表。分区本身也是表,因此可以直接查询;同时,分区有时也可以是分区表,从而形成层次结构。 + + 当它用于指代 + 分区表时: + 指各张包含该分区表部分数据的表之一,而该分区表被称为 + 父表。分区本身也是表,因此也可以被直接查询; + 同时,分区有时自身也可以是分区表,从而形成层级结构。 + - 窗口函数查询中的使用而言,分区是一项用户定义的准则,用于确定哪些相邻的(来自查询结果集)可供该函数考虑。 + + 当它用于指代查询中的 + 窗口函数时, + 分区是一种用户定义的准则,用来标识 + 查询结果集中哪些相邻的 + + 可以被该函数考虑在内。 + @@ -1060,7 +1095,12 @@ 角色 - 一组访问权限,其访问对象是实例。角色本身也是一种可以授予其他角色的权限。当多个用户需要相同权限时,常常会采用这种做法,以便于操作或确保权限完整。 + + 对实例的访问权限的集合。 + 角色本身也是一种可以授予给其他角色的权限。 + 当多个用户需要同样的权限时, + 这样做通常是为了方便,或为了保证权限配置完整。 + 更多信息见 diff --git a/zh/13/hash.sgml b/zh/13/hash.sgml index 199395b2..81f5f878 100644 --- a/zh/13/hash.sgml +++ b/zh/13/hash.sgml @@ -1,11 +1,11 @@ -哈希索引 +Hash 索引 索引 - 哈希 + Hash @@ -13,51 +13,51 @@ PostgreSQL - 提供了持久化的磁盘哈希索引实现,并且完全支持崩溃恢复。任何数据类型都可以使用哈希索引,包括那些没有明确定义线性顺序的数据类型。哈希索引只存储被索引数据的哈希值,因此对被索引数据列的大小没有限制。 + 提供了持久化的磁盘 hash 索引实现,并且完全支持崩溃恢复。任何数据类型都可以使用 hash 索引,包括那些没有明确定义线性顺序的数据类型。Hash 索引只存储被索引数据的 hash 值,因此对被索引数据列的大小没有限制。 - 哈希索引仅支持单列索引,也不支持唯一性检查。 + Hash 索引仅支持单列索引,也不支持唯一性检查。 - 哈希索引仅支持=操作符,因此指定范围操作的 WHERE 子句无法利用哈希索引。 + Hash 索引仅支持=操作符,因此指定范围操作的 WHERE 子句无法利用 hash 索引。 - 每个哈希索引元组只存储 4 字节的哈希值,而不存储实际的列值。因此,在为 UUID、URL 等较长的数据项建立索引时,哈希索引可能比 B-树小得多。由于没有列值,所有哈希索引扫描也都是有损的。哈希索引可以参与位图索引扫描和反向扫描。 + 每个 hash 索引元组只存储 4 字节的 hash 值,而不存储实际的列值。因此,在为 UUID、URL 等较长的数据项建立索引时,hash 索引可能比 B-树小得多。由于没有列值,所有 hash 索引扫描也都是有损的。Hash 索引可以参与位图索引扫描和反向扫描。 - 哈希索引最适合于在较大表上执行等值扫描、且以 SELECT 和 UPDATE 为主的工作负载。在 B-树索引中,搜索必须沿树向下直到找到叶页。在拥有数百万行的表中,这种向下遍历会增加访问数据的时间。在哈希索引中,与叶页对应的页称为桶页。相比之下,哈希索引允许直接访问桶页,因此可能减少大表中的索引访问时间。这种“逻辑 I/O”的减少,在索引/数据大于 shared_buffers/RAM 时会更加明显。 + Hash 索引最适合于在较大表上执行等值扫描、且以 SELECT 和 UPDATE 为主的工作负载。在 B-树索引中,搜索必须沿树向下直到找到叶页。在拥有数百万行的表中,这种向下遍历会增加访问数据的时间。在 hash 索引中,与叶页对应的页称为桶页。相比之下,hash 索引允许直接访问桶页,因此可能减少大表中的索引访问时间。这种“逻辑 I/O”的减少,在索引/数据大于 shared_buffers/RAM 时会更加明显。 - 哈希索引在设计上能够应对哈希值分布不均的情况。如果哈希值分布均匀,那么直接访问桶页的效果很好。当插入导致桶页填满时,额外的溢出页就会链接到该特定桶页上,从而在局部扩展用于存放匹配该哈希值的索引元组的空间。查询期间扫描某个哈希桶时,需要遍历其全部溢出页。因此,对于某些数据,不平衡的哈希索引在所需块访问次数方面实际上可能比 B-树更差。 + Hash 索引在设计上能够应对 hash 值分布不均的情况。如果 hash 值分布均匀,那么直接访问桶页的效果很好。当插入导致桶页填满时,额外的溢出页就会链接到该特定桶页上,从而在局部扩展用于存放匹配该 hash 值的索引元组的空间。查询期间扫描某个 hash 桶时,需要遍历其全部溢出页。因此,对于某些数据,不平衡的 hash 索引在所需块访问次数方面实际上可能比 B-树更差。 - 由于会出现这些溢出情况,可以说哈希索引最适合用于唯一值、近乎唯一值,或者每个哈希桶中行数较少的数据。 + 由于会出现这些溢出情况,可以说 hash 索引最适合用于唯一值、近乎唯一值,或者每个 hash 桶中行数较少的数据。 避免问题的一种可能办法,是使用部分索引条件把高度非唯一的值排除在索引之外,但这在很多情况下可能并不适用。 - 与 B-树一样,哈希索引也会执行简单的索引元组删除。这是一种延迟维护操作,用于删除那些已知可以安全删除的索引元组(即其项标识符的 LP_DEAD 位已经被设置的那些元组)。如果插入操作发现页上没有可用空间,我们会尝试通过移除死索引元组来避免创建新的溢出页。如果该页当时已被钉住,就无法执行移除。死索引指针也会在 VACUUM 期间被删除。 + 与 B-树一样,hash 索引也会执行简单的索引元组删除。这是一种延迟维护操作,用于删除那些已知可以安全删除的索引元组(即其项标识符的 LP_DEAD 位已经被设置的那些元组)。如果插入操作发现页上没有可用空间,我们会尝试通过移除死索引元组来避免创建新的溢出页。如果该页当时已被钉住,就无法执行移除。死索引指针也会在 VACUUM 期间被删除。 - 如果可能,VACUUM 还会尝试将索引元组压缩到尽可能少的溢出页上,以最小化溢出链。 + 如果可能,VACUUM 还会尝试将索引元组集中存放在尽可能少的溢出页上,以最小化溢出链。 如果某个溢出页变为空页,该溢出页就可以被回收并在其他桶中重用,不过我们从不将它们返还给操作系统。 - 目前除了使用 REINDEX 重建哈希索引之外,还没有缩小哈希索引的方法。 + 目前除了使用 REINDEX 重建 hash 索引之外,还没有缩小 hash 索引的方法。 同样也没有减少桶数量的方法。 - 随着被索引行数的增长,哈希索引可能会扩展桶页数量。哈希键到桶号的映射经过选择,使得索引能够增量扩展。当需要向索引中添加一个新桶时,恰好只需要“拆分”一个现有桶,并根据更新后的键到桶号映射,将其中一部分元组转移到新桶。 + 随着被索引行数的增长,Hash 索引可能会扩展桶页数量。hash 键到桶号的映射经过选择,使得索引能够增量扩展。当需要向索引中添加一个新桶时,恰好只需要“拆分”一个现有桶,并根据更新后的键到桶号映射,将其中一部分元组转移到新桶。 - 这种扩展是在前台进行的,因此可能会增加用户插入操作的执行时间。因此,哈希索引可能不适合行数快速增长的表。 + 这种扩展是在前台进行的,因此可能会增加用户插入操作的执行时间。因此,hash 索引可能不适合行数快速增长的表。 @@ -66,7 +66,7 @@ 实现 - 哈希索引中有四种页:元页(第零页),其中包含静态分配的控制信息;主桶页;溢出页;以及位图页,后者用于跟踪已被释放且可供重用的溢出页。在寻址时,位图页被视为溢出页的一个子集。 + hash 索引中有四种页:元页(第零页),其中包含静态分配的控制信息;主桶页;溢出页;以及位图页,后者用于跟踪已被释放且可供重用的溢出页。在寻址时,位图页被视为溢出页的一个子集。 @@ -74,15 +74,15 @@ - 主桶页和溢出页是独立分配的,因为任何一个给定索引相对于其桶数,可能需要更多或更少的溢出页。哈希代码使用了一组颇有意思的寻址规则,以支持可变数量的溢出页,同时又不必在主桶页创建后再移动它们。 + 主桶页和溢出页是独立分配的,因为任何一个给定索引相对于其桶数,可能需要更多或更少的溢出页。hash 实现代码使用了一组颇有意思的寻址规则,以支持可变数量的溢出页,同时又不必在主桶页创建后再移动它们。 - 被索引表中的每一行,都由哈希索引中的单个索引元组表示。哈希索引元组存储在桶页中,如果存在溢出页,也会存储在溢出页中。为了加快搜索速度,我们将任一索引页中的索引项按哈希码排序,从而可以在索引页内使用二分查找。但请注意,并不假定同一桶中不同索引页之间的哈希码具有任何相对顺序。 + 被索引表中的每一行,都由 hash 索引中的单个索引元组表示。Hash 索引元组存储在桶页中,如果存在溢出页,也会存储在溢出页中。为了加快搜索速度,我们将任一索引页中的索引项按 hash 码排序,从而可以在索引页内使用二分查找。但请注意,并不假定同一桶中不同索引页之间的 hash 码具有任何相对顺序。 - 用于扩展哈希索引的桶拆分算法过于复杂,这里不再展开说明;但在src/backend/access/hash/README中有更详细的描述。该拆分算法具备崩溃安全性,如果未能成功完成,可以重新启动。 + 用于扩展 hash 索引的桶拆分算法过于复杂,这里不再展开说明;但在src/backend/access/hash/README中有更详细的描述。该拆分算法具备崩溃安全性,如果未能成功完成,可以重新启动。 diff --git a/zh/13/high-availability.sgml b/zh/13/high-availability.sgml index 4dad6137..e9d06f9a 100644 --- a/zh/13/high-availability.sgml +++ b/zh/13/high-availability.sgml @@ -174,8 +174,8 @@ protocol to make nodes agree on a serializable transactional order. 文件系统复制 预写式日志传送 逻辑复制 - 基于触发器的复制 - 基于 SQL 的复制中间件 + 基于触发器&zwsp;的复制 + SQL 复制中间件 异步多主复制 同步多主复制 @@ -256,7 +256,7 @@ protocol to make nodes agree on a serializable transactional order. - 主库失效绝不会丢失数据 + 主库失效时绝不丢失数据 启用同步时 @@ -348,7 +348,7 @@ protocol to make nodes agree on a serializable transactional order. - 连续归档可用于创建一种高可用性(HA)集簇配置,其中有一个或多个备库随时准备在主库失效时接管操作。这种能力通常称为温备日志传送。 + 持续归档可用于创建一种高可用性(HA)集簇配置,其中有一个或多个备库随时准备在主库失效时接管操作。这种能力通常称为温备日志传送 @@ -518,10 +518,13 @@ archive_cleanup_command = 'pg_archivecleanup /path/to/archive %r' 认证 - 正确设置复制访问权限非常重要,因为从 WAL 流中很容易提取出需要权限才能访问的信息,因此必须确保只有受信任的用户才能读取它。备库必须以具有 REPLICATION 权限的账户或超级用户身份向主库认证。建议专门创建一个具有 REPLICATIONLOGIN 权限的用户账户用于复制。虽然 REPLICATION 权限的权限很高,但它并不允许用户修改主系统上的任何数据,而 SUPERUSER 权限则允许。 + 正确设置复制访问权限非常重要,因为从 WAL 流中很容易提取出需要权限才能访问的信息,因此必须确保只有受信任的用户才能读取它。备库必须以具有 REPLICATION 权限的账户或超级用户身份向主库认证。建议专门创建一个具有 REPLICATIONLOGIN 权限的用户账户用于复制。虽然 REPLICATION 权限很高,但它并不允许用户修改主系统上的任何数据,而 SUPERUSER 权限则允许。 - 复制的客户端认证由 pg_hba.conf 中的记录控制。记录要将 replication 指定为 database 字段的值。例如,如果备库所在主机的 IP 地址为 192.168.1.100,用于复制的账户名为 foo,管理员可以将以下行添加到 pg_hba.conf 文件(位于主库)中: + + 复制的客户端认证由 pg_hba.conf 中的一条记录控制,该记录需要把 replication 指定在 database 字段中。例如,如果备库运行在主机 IP 192.168.1.100 上,并且用于复制的账户名为 foo,管理员可以在主库上的 pg_hba.conf 文件中加入下列行: + + # Allow the user "foo" from host 192.168.1.100 to connect to the primary # as a replication standby if the user's password is correctly supplied. # @@ -529,7 +532,10 @@ archive_cleanup_command = 'pg_archivecleanup /path/to/archive %r' host replication foo 192.168.1.100/32 md5 - 主库的主机名、端口号、连接用户名和密码在 中指定。也可以将密码设置在备库的 ~/.pgpass 文件中(将 replication 指定为 database 字段的值)。例如,如果主库所在主机的 IP 地址为 192.168.1.50,端口为 5432,用于复制的账户名为 foo,密码为 foopass,管理员可以将以下行添加到 postgresql.conf 文件(位于备库)中: + + 主库的主机名和端口号、连接用户名以及密码都在 中指定。密码也可以设置在备库上的 ~/.pgpass 文件中(把 replication 指定在 database 字段中)。例如,如果主库运行在主机 IP 192.168.1.50、端口 5432 上,用于复制的账户名为 foo,并且密码是 foopass,管理员可以在备库的 postgresql.conf 文件中加入下列行: + + # The standby connects to the primary that is running on host 192.168.1.50 # and port 5432 as the user "foo" whose password is "foopass". primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass' @@ -543,7 +549,7 @@ primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass' 流复制的一个重要健康指标,是主库上已经生成但尚未在备库上应用的 WAL 记录量。你可以通过比较主库上的当前 WAL 写入位置和备库收到的最后一个 WAL 位置来计算这种滞后。这些位置分别可以用主库上的 pg_current_wal_lsn 和备库上的 pg_last_wal_receive_lsn 取得(详见 )。备库上的最后一个 WAL 接收位置也会显示在 WAL 接收进程的进程状态中,即通过 ps 命令显示的状态(详见 )。 - 你可以通过 pg_stat_replication 视图取得 WAL 发送进程列表。pg_current_wal_lsn 与该视图的 sent_lsn 字段之间存在较大差异,可能表示主库负载很重;而 sent_lsn 与备库上的 pg_last_wal_receive_lsn 之间存在较大差异,则可能表示网络延迟,或者备库负载很重。 + 你可以通过 pg_stat_replication 视图取得 WAL 发送进程列表。pg_current_wal_lsn 与该视图的 sent_lsn 字段之间存在较大差异,可能表示主库负载很重;而 sent_lsn 与备库上的 pg_last_wal_receive_lsn 之间存在差异,则可能表示网络延迟,或者备库负载很重。 在热备上,WAL 接收进程的状态可以通过 @@ -559,7 +565,7 @@ primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass' 流复制 - 复制槽提供了一种自动化方法,以确保主库在所有备库都收到 WAL 段之前不会删除它们,并且即使备库处于断开状态,主库也不会删除可能导致恢复冲突的行。 + 复制槽提供了一种自动化方法,以确保主库在所有备库都收到 WAL 段之前不会删除它们,并且即使备库处于断开状态,主库也不会删除那些一旦删除就可能导致恢复冲突的行。 除了使用复制槽,也可以通过 防止旧 WAL 段被删除,或者使用 将这些段保存在归档中。不过,这些方法通常会保留多于实际所需的 WAL 段,而复制槽只保留已知必需的段数。另一方面,复制槽保留的 WAL 段也可能过多,填满分配给 pg_wal 的空间; 可以限制复制槽保留的 WAL 文件大小。 类似地, 可以保护相关行,避免它们被清理删除,但前者在备库未连接期间无法提供保护,后者则通常需要设为较大的值才能提供充分保护。复制槽克服了这些缺点。 @@ -579,7 +585,9 @@ primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass' 配置示例 - 可以这样创建复制槽: + + 你可以像下面这样创建一个复制槽: + postgres=# SELECT * FROM pg_create_physical_replication_slot('node_a_slot'); slot_name | lsn -------------+----- @@ -590,7 +598,9 @@ postgres=# SELECT slot_name, slot_type, active FROM pg_replication_slots; -------------+-----------+-------- node_a_slot | physical | f (1 row) -要配置备库使用此复制槽,需要将 primary_slot_name 配置在备库上。下面是一个简单的示例: + + 要让备库使用这个槽,应在备库上配置 primary_slot_name。下面是一个简单示例: + primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass' primary_slot_name = 'node_a_slot' @@ -609,7 +619,9 @@ primary_slot_name = 'node_a_slot' 级联复制特性允许一台备库接受复制连接,并像中继器一样把 WAL 记录流式发送给其他备库。这可以用来减少直接连接到主库的连接数,并使站点间的带宽开销最小化。 - 同时充当接收方和发送方的备库称为级联备库。与主库连接更直接的备库称为上游服务器,距离更远的备库则称为下游服务器。级联复制不限制下游服务器的数量或组织方式,不过每个备库只连接一个上游服务器,并最终连接到同一个主库。 + + 一台同时扮演接收者和发送者角色的备库称为级联备库。与主库连接更直接(经过更少级联备库)的备库称为上游服务器,而距离更远的备库称为下游服务器。级联复制并不限制下游服务器的数量和拓扑,不过每台备库只连接到一台上游服务器,而这条链路最终都会通向同一台主库。 + 级联备库不仅发送从主库接收到的 WAL 记录,也会发送那些从归档中恢复的记录。因此,即使某条上游复制连接被中断,只要仍有新的 WAL 记录可用,下游的流复制就会继续。 @@ -623,7 +635,9 @@ primary_slot_name = 'node_a_slot' 热备反馈会向上传播,无论级联拓扑如何。 - 如果某个上游备库被提升为新主库,只要 recovery_target_timeline 设为 'latest'(默认值),下游服务器就会继续从新主库接收流。 + + 如果一台上游备库被提升为新的主库,并且下游服务器的 recovery_target_timeline 被设置为 'latest'(默认值),下游服务器将继续从新的主库接收流。 + 要使用级联复制,需要把级联备库设置为能够接受复制连接(也就是设置 ,并配置 基于主机的认证)。你还需要把下游备库中的 primary_conninfo 设置为指向级联备库。 @@ -649,7 +663,9 @@ primary_slot_name = 'node_a_slot' 请求同步复制时,每个写事务的提交都会等待,直到收到确认,表明该提交已被写入主库和备库磁盘上的预写式日志。数据唯一可能丢失的情况,是主库和备库同时崩溃。这可以提供更高的持久性级别,不过前提是系统管理员必须谨慎地部署和管理这两台服务器。等待确认会增强用户对服务器崩溃时更改不会丢失的信心,但也必然会增加请求事务的响应时间。最短等待时间是主库与备库之间的往返时间。 - 只读事务和事务回滚无需等待备库回复。子事务提交也不等待备库响应,只有顶层提交才会等待。数据加载或索引构建等长时间运行的操作,直到最后的提交消息才会等待。所有两阶段提交操作都需要等待提交,包括准备和提交两个阶段。 + + 只读事务和事务回滚不需要等待备库的回应。子事务提交也不需要等待备库响应,只有顶层提交才需要等待。数据装载或索引构建等长时间运行的动作,直到最终提交时才会等待。所有两阶段提交操作都需要等待提交,包括准备和提交两个阶段。 + 同步备库可以是物理复制备库,也可以是逻辑复制订阅者。它还可以是任何其他物理或逻辑 WAL 复制流的消费者,只要它知道如何发送适当的反馈消息。除了内置的物理和逻辑复制系统之外,还包括pg_receivewalpg_recvlogical之类的专用程序,以及一些第三方复制系统和定制程序。关于同步复制支持的细节,请查看相应文档。 @@ -663,7 +679,7 @@ primary_slot_name = 'node_a_slot' - 当提交记录已经在主库上写入磁盘之后,WAL 记录就会被发送到备库。每当新的一批 WAL 数据被写入磁盘时,备库就会发送回复消息,除非备库上的wal_receiver_status_interval被设置为零。如果synchronous_commit被设置为remote_apply,那么备库会在提交记录被重放时发送回复消息,从而使该事务变得可见。如果根据主库上的synchronous_standby_names设置,该备库被选为同步备库,那么它发出的回复会与其他同步备库的回复一起,用于决定何时释放那些正在等待确认提交记录已被收到的事务。这些参数允许管理员指定哪些备库应作为同步备库。注意,同步复制的配置主要在主库上进行。被命名的备库必须直接连接到主库;主库并不知道使用级联复制的下游备库。 + 当提交记录已经在主库上写入磁盘之后,WAL 记录就会被发送到备库。每当新的一批 WAL 数据被写入磁盘时,备库就会发送回复消息,除非备库上的wal_receiver_status_interval被设置为零。如果synchronous_commit被设置为remote_apply,那么备库会在提交记录被重放、该事务变得可见时发送回复消息。如果根据主库上的synchronous_standby_names设置,该备库被选为同步备库,那么它发出的回复会与其他同步备库的回复一起,用于决定何时释放那些正在等待确认提交记录已被收到的事务。这些参数允许管理员指定哪些备库应作为同步备库。注意,同步复制的配置主要在主库上进行。被命名的备库必须直接连接到主库;主库并不知道使用级联复制的下游备库。 @@ -675,7 +691,7 @@ primary_slot_name = 'node_a_slot' - 如果请求快速关闭,用户将停止等待。不过,与使用异步复制时一样,在所有尚未解决的 WAL 记录传输到当前已连接的备库之前,服务器不会完全关闭。 + 如果请求快速关闭,用户将停止等待。不过,与使用异步复制时一样,在所有尚未传送的 WAL 记录传输到当前已连接的备库之前,服务器不会完全关闭。 @@ -697,14 +713,14 @@ synchronous_standby_names = 'FIRST 2 (s1, s2, s3)' 在这个例子中,如果四台备库s1s2s3s4都在运行,则s1s2会被选为同步备库,因为它们的名字在备库名称列表中出现得更早。s3是潜在的同步备库,当s1s2中的任意一台失效时,它就会接替其角色。由于s4的名称不在列表中,因此它是异步备库。 - ANY方法指定基于法定人数的同步复制,使事务提交等待,直到它们的 WAL 记录被复制到列表中所要求数量的同步备库中的至少这么多台。 + ANY方法指定基于法定人数的同步复制,使事务提交等待,直到它们的 WAL 记录被复制到列表中至少所要求数量的同步备库。 基于法定人数的多同步备库的synchronous_standby_names示例如下: synchronous_standby_names = 'ANY 2 (s1, s2, s3)' - 在这个例子中,如果四台备库s1s2s3s4都在运行,事务提交将等待来自s1s2s3中的任意两台备库的回复。由于s4的名字不在列表中,因此它是异步备库。 + 在这个例子中,如果四台备库s1s2s3s4都在运行,事务提交将等待来自s1s2s3中的至少任意两台备库的回复。由于s4的名字不在列表中,因此它是异步备库。 备库的同步状态可以通过pg_stat_replication视图查看。 @@ -727,7 +743,7 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' - 通过在应用级别(在主库上)指定同步复制选项,我们可以只对最重要的变更提供同步复制,而不会拖慢整体工作负载。应用级别选项是让高性能应用获得同步复制收益的一种重要而实用的工具。 + 通过在应用级别(在主库上)指定同步复制选项,我们可以只对最重要的变更提供同步复制,而不会拖慢大部分工作负载。应用级别选项是让高性能应用获得同步复制收益的一种重要而实用的工具。 @@ -760,7 +776,7 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' - 如果主库在提交正等待确认时重启,这些等待中的事务会在主库恢复后被标记为已完全提交。无法确定在主库崩溃时,所有备库是否已经收到全部尚未处理的 WAL 数据。因此,某些事务可能不会在备库上显示为已提交,即使它们在主库上显示为已提交。我们所提供的保证是:只有在确认 WAL 数据已经被所有同步备库安全接收之后,应用才会收到事务成功提交的显式确认。 + 如果主库在提交正等待确认时重启,这些等待中的事务会在主库恢复后被标记为已完全提交。无法确定在主库崩溃时,所有备库是否已经收到全部待传送的 WAL 数据。因此,某些事务可能不会在备库上显示为已提交,即使它们在主库上显示为已提交。我们所提供的保证是:只有在确认 WAL 数据已经被所有同步备库安全接收之后,应用才会收到事务成功提交的显式确认。 @@ -818,7 +834,7 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' - 一旦故障切换到备库,系统中就只剩下一台服务器在运行。这被称为退化状态。原来的备库现在成为主库,而原来的主库已经停机,并且可能持续停机。要恢复到正常运行状态,就必须重新创建一台备库:要么在原主库恢复后在其上重建,要么在第三台可能是全新的服务器上重建。在大型集簇上,可以使用工具来加快这一过程。一旦完成,就可以认为主库和备库已经交换了角色。有些人会选择使用第三台服务器,在新的备库重建完成之前为新的主库提供备份,但显然这会让系统配置和操作流程更加复杂。 + 一旦故障切换到备库,系统中就只剩下一台服务器在运行。这被称为退化状态。原来的备库现在成为主库,而原来的主库已经停机,并且可能持续停机。要恢复到正常运行状态,就必须重新创建一台备库:要么在原主库恢复后在其上重建,要么在第三台可能是全新的服务器上重建。在大型集簇上,可以使用工具来加快这一过程。一旦完成,就可以认为主库和备库已经交换了角色。有些人会选择使用第三台服务器,在新的备库重建完成之前为新的主库提供后备支持,但显然这会让系统配置和操作流程更加复杂。 @@ -835,7 +851,7 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' 注意,在这种模式下,服务器每次应用一整个 WAL 文件。因此,如果使用备库处理查询(参见热备),主库上的操作与备库上能看到该操作的结果之间,会有一段延迟,其长度相当于写满一个 WAL 文件所需的时间。可以用 archive_timeout 缩短这一延迟。还要注意,这种方法不能与流复制结合使用。 - 主库和备库上执行的操作都是普通的连续归档和恢复任务。两台数据库服务器之间唯一的联系,就是它们共享的 WAL 文件归档:主库写入归档,备库从归档读取。必须确保不同主库的 WAL 归档不会混在一起或弄错。如果归档仅用于备库运行,则无需保留很大的归档。 + 主库和备库上执行的操作都是普通的持续归档和恢复任务。两台数据库服务器之间唯一的联系,就是它们共享的 WAL 文件归档:主库写入归档,备库从归档读取。必须确保不同主库的 WAL 归档不会混在一起或弄错。如果归档仅用于备库运行,则无需保留很大的归档。 让这两台松散耦合的服务器协同工作的关键,只是备库上的 restore_command:当请求下一个 WAL 文件时,它会等待主库提供该文件。正常恢复处理会从 WAL 归档请求文件,如果文件不可用,就报告失败。对备库处理而言,下一个 WAL 文件尚不可用是正常情况,因此备库必须等待它出现。对于以 .history 结尾的文件,则无需等待,必须返回非零返回码。可以编写一个自定义脚本,循环检查下一个 WAL 文件是否存在,从而实现会等待的 restore_command。还必须提供触发故障切换的方法,用来中断 restore_command、跳出循环,并向备库返回文件未找到错误。这会结束恢复,随后备库就会作为普通服务器启动。 @@ -864,7 +880,7 @@ if (!triggered) 尽可能将主库和备库系统配置得相同,包括安装两个完全相同、发行版本一致的 PostgreSQL 副本。 - 配置连续归档,将主库的 WAL 归档到备库上的一个目录。确保在主库上正确设置 (参见 )。 + 配置持续归档,将主库的 WAL 归档到备库上的一个目录。确保在主库上正确设置 (参见 )。 制作主库的基础备份(参见 ),并将这些数据装载到备库上。 @@ -910,14 +926,17 @@ if (!triggered) 用户概览 - 当备库上的参数被设置为真时,一旦恢复把系统带到一致状态并为热备做好准备,它就会开始接受连接。所有这类连接都严格是只读的,甚至不能写入临时表。 + 当备库上的参数被设置为真时,一旦恢复把系统带到一致状态,它就会开始接受连接。所有这类连接都严格是只读的,甚至不能写入临时表。 备库上的数据需要一些时间才能从主库到达,因此主库和备库之间会有可测量的延迟。因此,在主库和备库上几乎同时运行同一查询,可能会返回不同的结果。我们说备库上的数据与主库是最终一致的。一旦某个事务的提交记录在备库上被重放,该事务所做的修改就会对备库上之后取得的所有新快照可见。快照可以在每个查询开始时取得,也可以在每个事务开始时取得,这取决于当前的事务隔离级别。详见 - 热备期间启动的事务可以执行以下命令: + + 在热备期间启动的事务可以发出下列命令: + + 查询访问:SELECTCOPY TO @@ -935,7 +954,7 @@ if (!triggered) - 事务管理命令: + 事务管理命令: @@ -949,7 +968,7 @@ if (!triggered) - EXCEPTION块或其他内部子事务 + EXCEPTION块和其他内部子事务 @@ -980,13 +999,16 @@ if (!triggered) - 热备期间启动的事务不会被分配事务 ID,也不能写入系统的预写式日志。因此,以下操作会产生错误消息: + + 在热备期间启动的事务永远不会被分配事务 ID,也不能写入系统预写式日志。因此,下列动作都会产生错误消息: + + 数据操纵语言(DML):INSERTUPDATEDELETECOPY FROM、 - TRUNCATE。请注意,恢复期间不存在任何允许执行触发器的动作。这个限制甚至适用于临时表,因为不分配事务 ID 就无法读取或写入表行,而这在热备环境中目前是不可能的。 + TRUNCATE。请注意,恢复期间不存在任何允许执行触发器的动作。这个限制甚至适用于临时表,因为不分配事务 ID 就无法读取或写入表行,而目前热备环境中无法分配事务 ID。 @@ -1021,13 +1043,13 @@ if (!triggered) - BEGIN READ WRITE, + BEGIN READ WRITESTART TRANSACTION READ WRITE - SET TRANSACTION READ WRITE, + SET TRANSACTION READ WRITESET SESSION CHARACTERISTICS AS TRANSACTION READ WRITE @@ -1043,7 +1065,7 @@ if (!triggered) 两阶段提交命令:PREPARE TRANSACTIONCOMMIT PREPAREDROLLBACK PREPARED, - 因为即使是只读事务,在 prepare 阶段(两阶段提交的第一阶段)也需要写入 WAL。 + 因为即使是只读事务,在准备阶段(两阶段提交的第一阶段)也需要写入 WAL。 @@ -1127,19 +1149,17 @@ if (!triggered) - 一旦max_standby_archive_delaymax_standby_streaming_delay指定的延迟被超越,冲突查询将被取消。这通常仅导致一个取消错误,尽管在重放一个DROP DATABASE的情况下整个冲突会话都将被中断。另外,如果冲突发生在一个被空闲事务持有的锁上,该冲突会话会被中断(这种行为可能在未来被改变)。 + 一旦max_standby_archive_delaymax_standby_streaming_delay指定的延迟被超越,冲突查询将被取消。这通常仅导致一个取消错误,尽管在重放一个DROP DATABASE的情况下整个冲突会话都将被终止。另外,如果冲突发生在一个被空闲事务持有的锁上,该冲突会话会被终止(这种行为可能在未来被改变)。 - - 被取消的查询可能会立即被重试(当然是在开始一个新的事务后)。因为查询取消依赖于 WAL 记录被重放的本质,如果一个被取消的查询被再次执行,它可能会很好地成功完成。 - + 被取消的查询可以立即重试(当然,要先开始一个新事务)。由于查询取消取决于正在重放的 WAL 记录的性质,被取消的查询再次执行时完全可能成功。 - 记住延迟参数是从 WAL 数据被备库收到后流逝的时间。因此,留给备库上任何一个查询的宽限期从不会超过延迟参数,并且如果备库已经由于等待之前的查询完成而落后或者因为过重的更新负载而无法跟上主库,宽限期可能会更少。 + 请记住,延迟参数要与备库收到 WAL 数据之后经过的时间进行比较。因此,留给备库上任何一个查询的宽限期从不会超过延迟参数,并且如果备库已经由于等待之前的查询完成而落后或者因为过重的更新负载而无法跟上主库,宽限期可能会更少。 - 备库查询与 WAL 重放发生冲突的最常见原因是过早清理。正常情况下,当没有事务需要看到旧行版本时,PostgreSQL允许清理这些旧行版本,以保证按照 MVCC 规则得到正确的数据可见性。不过,这条规则只能应用于在主库上执行的事务。因此,主库上的清理有可能移除某个备库事务仍然可见的行版本。 + 备库查询与 WAL 重放发生冲突的最常见原因是过早清理。正常情况下,当不再有事务需要看到旧行版本来保证符合 MVCC 规则的数据可见性时,PostgreSQL允许清理这些旧行版本。不过,这条规则只能应用于在主库上执行的事务。因此,主库上的清理有可能移除某个备库事务仍然可见的行版本。 有经验的用户应注意,行版本清理和行版本冻结都有可能与备库查询冲突。手动运行 VACUUM FREEZE 很可能导致冲突,即使表中没有更新过或删除过的行也是如此。 @@ -1217,13 +1237,16 @@ LOG: database system is ready to accept read only connections - 主库上写出的事务状态 "hint bits" 不会被 WAL 记录,因此备库上的数据很可能会再次写出这些提示位。这样一来,即使所有用户都是只读的,备库仍然会执行磁盘写操作;不过数据值本身并不会发生变化。用户仍然会写出大型排序临时文件,并重新生成 relcache 信息文件,因此在热备模式下,数据库没有任何部分是真正只读的。还要注意,使用dblink模块写入远程数据库,以及借助 PL 函数执行其他数据库外部操作,依然是可能的,即使该事务在本地是只读的。 + 主库上写出的事务状态“提示位” 不会被 WAL 记录,因此备库上的数据很可能会再次写出这些提示位。这样一来,即使所有用户都是只读的,备库仍然会执行磁盘写操作;不过数据值本身并不会发生变化。用户仍然会写出大型排序临时文件,并重新生成 relcache 信息文件,因此在热备模式下,数据库没有任何部分是真正只读的。还要注意,使用dblink模块写入远程数据库,以及借助 PL 函数执行其他数据库外部操作,依然是可能的,即使该事务在本地是只读的。 - 恢复模式下不接受以下类型的管理命令: + + 在恢复模式下,不接受下列类型的管理命令: + + - 数据定义语言:例如 CREATE INDEX + 数据定义语言(DDL):例如 CREATE INDEX @@ -1281,7 +1304,9 @@ LOG: database system is ready to accept read only connections 不能分配新的 OID,不过某些UUID生成器仍可工作,只要它们不依赖于向数据库写入新的状态。 - 目前,不允许在只读事务中创建临时表,因此现有脚本在某些情况下无法正确运行。未来版本可能会放宽这一限制。这既涉及 SQL 标准兼容性,也涉及技术问题。 + + 目前,在只读事务期间不允许创建临时表,因此某些现有脚本在这种情况下将无法正常运行。这个限制可能会在未来版本中放宽。这既涉及 SQL 标准兼容性问题,也涉及技术问题。 + 只有在表空间为空时DROP TABLESPACE才能成功。某些备库用户可能正在通过他们的temp_tablespaces参数使用该表空间。如果该表空间中存在临时文件,所有活动查询都将被取消,以确保临时文件被移除,这样该表空间才能被移除并且 WAL 重放可以继续。 @@ -1321,9 +1346,15 @@ LOG: database system is ready to accept read only connections 注意事项 - 热备有几个限制。这些限制能够、也很可能会在未来版本中消除: + + 热备有若干限制。 + 这些限制在未来的版本中可以、也很可能会被修复: + + - 必须完整掌握正在运行的事务,才能取得快照。如果事务使用了大量子事务(目前为超过 64 个),只读连接的开始时间就会延迟,直到运行时间最长的写事务完成。发生这种情况时,服务器日志中会记录说明消息。 + + 在能够取得快照之前,必须完整了解正在运行的事务。使用大量子事务(目前超过 64 个)的事务,会把只读连接的启动推迟到持续时间最长的写事务完成之后。如果发生这种情况,服务器日志中会发送解释性消息。 + diff --git a/zh/13/history.sgml b/zh/13/history.sgml index 507e35c3..5b88da1d 100644 --- a/zh/13/history.sgml +++ b/zh/13/history.sgml @@ -156,6 +156,8 @@ 不过各个方面的工作仍在继续。 - 关于此后PostgreSQL发生了哪些变化的详情,可在中查阅。 + + 自那以后 PostgreSQL 发生了哪些变化,可见 。 + diff --git a/zh/13/images/fixup-svg.xsl b/zh/13/images/fixup-svg.xsl index d6c46b36..cf7169bb 100644 --- a/zh/13/images/fixup-svg.xsl +++ b/zh/13/images/fixup-svg.xsl @@ -32,6 +32,11 @@ Fix stroke="transparent" attribute, which is invalid SVG. none + + + 'Alibaba PuHuiTi 3.0',serif + + diff --git a/zh/13/images/gin.gv b/zh/13/images/gin.gv index 097e9102..b8e26542 100644 --- a/zh/13/images/gin.gv +++ b/zh/13/images/gin.gv @@ -1,11 +1,12 @@ digraph "gin" { layout=dot; - node [label="", shape=box, style=filled, fillcolor=gray, width=1.4]; + fontname="Alibaba PuHuiTi 3.0"; + node [fontname="Alibaba PuHuiTi 3.0", label="", shape=box, style=filled, fillcolor=gray, width=1.4]; - m1 [label="meta page"]; + m1 [label="元页"]; subgraph cluster01 { - label="entry tree"; + label="键项树"; subgraph egroup1 { rank=same; e1; @@ -27,13 +28,13 @@ digraph "gin" { e4 -> e8; e4 -> e9; - e6 [fillcolor=green, label="posting list"]; - e8 [fillcolor=green, label="posting list"]; - e9 [fillcolor=green, label="posting list"]; + e6 [fillcolor=green, label="倒排列表"]; + e8 [fillcolor=green, label="倒排列表"]; + e9 [fillcolor=green, label="倒排列表"]; } subgraph cluster02 { - label="posting tree"; + label="倒排树"; subgraph pgroup1 { rank=same; p1; @@ -45,22 +46,22 @@ digraph "gin" { p1 -> p2; p1 -> p3; - p2 [fillcolor=green, label="heap ptr"]; - p3 [fillcolor=green, label="heap ptr"]; + p2 [fillcolor=green, label="堆指针"]; + p3 [fillcolor=green, label="堆指针"]; } subgraph cluster03 { - label="posting tree"; + label="倒排树"; subgraph pgroup3 { rank=same; p4; } - p4 [fillcolor=green, label="heap ptr"]; + p4 [fillcolor=green, label="堆指针"]; } subgraph cluster04 { - label="posting tree"; + label="倒排树"; subgraph pgroup4 { rank=same; p5; @@ -72,12 +73,12 @@ digraph "gin" { p5 -> p6; p5 -> p7; - p6 [fillcolor=green, label="heap ptr"]; - p7 [fillcolor=green, label="heap ptr"]; + p6 [fillcolor=green, label="堆指针"]; + p7 [fillcolor=green, label="堆指针"]; } subgraph cluster05 { - label="pending list"; + label="待处理列表"; node [style=filled, fillcolor=red]; n1 -> n2 -> n3 -> n4; } diff --git a/zh/13/images/gin.svg b/zh/13/images/gin.svg index 04fe85ba..79cf14a9 100644 --- a/zh/13/images/gin.svg +++ b/zh/13/images/gin.svg @@ -9,33 +9,33 @@ cluster01 -entry tree +键项树 cluster02 -posting tree +倒排树 cluster03 -posting tree +倒排树 cluster04 -posting tree +倒排树 cluster05 -pending list +待处理列表 m1 -meta page +元页 @@ -113,7 +113,7 @@ e6 -posting list +倒排列表 @@ -142,7 +142,7 @@ e8 -posting list +倒排列表 @@ -154,7 +154,7 @@ e9 -posting list +倒排列表 @@ -195,7 +195,7 @@ p4 -heap ptr +堆指针 @@ -224,7 +224,7 @@ p2 -heap ptr +堆指针 @@ -236,7 +236,7 @@ p3 -heap ptr +堆指针 @@ -254,7 +254,7 @@ p6 -heap ptr +堆指针 @@ -266,7 +266,7 @@ p7 -heap ptr +堆指针 diff --git a/zh/13/indexam.sgml b/zh/13/indexam.sgml index 4e548c5c..46410695 100644 --- a/zh/13/indexam.sgml +++ b/zh/13/indexam.sgml @@ -42,71 +42,71 @@ typedef struct IndexAmRoutine NodeTag type; /* - * Total number of strategies (operators) by which we can traverse/search - * this AM. Zero if AM does not have a fixed set of strategy assignments. + * 可用于遍历或搜索此 AM 的策略(操作符)总数。 + * 如果 AM 没有固定的一组策略分配,则为零。 */ uint16 amstrategies; - /* total number of support functions that this AM uses */ + /* 此 AM 使用的支持函数总数 */ uint16 amsupport; - /* opclass options support function number or 0 */ + /* 操作符类选项支持函数编号,或为 0 */ uint16 amoptsprocnum; - /* does AM support ORDER BY indexed column's value? */ + /* AM 是否支持按被索引列的值进行 ORDER BY? */ bool amcanorder; - /* does AM support ORDER BY result of an operator on indexed column? */ + /* AM 是否支持按被索引列上操作符的结果进行 ORDER BY? */ bool amcanorderbyop; - /* does AM support backward scanning? */ + /* AM 是否支持反向扫描? */ bool amcanbackward; - /* does AM support UNIQUE indexes? */ + /* AM 是否支持 UNIQUE 索引? */ bool amcanunique; - /* does AM support multi-column indexes? */ + /* AM 是否支持多列索引? */ bool amcanmulticol; - /* does AM require scans to have a constraint on the first index column? */ + /* AM 是否要求扫描必须约束第一个索引列? */ bool amoptionalkey; - /* does AM handle ScalarArrayOpExpr quals? */ + /* AM 是否处理 ScalarArrayOpExpr 限定条件? */ bool amsearcharray; - /* does AM handle IS NULL/IS NOT NULL quals? */ + /* AM 是否处理 IS NULL/IS NOT NULL 限定条件? */ bool amsearchnulls; - /* can index storage data type differ from column data type? */ + /* 索引存储数据类型是否可以不同于列数据类型? */ bool amstorage; - /* can an index of this type be clustered on? */ + /* 是否可以按此类型的索引进行聚簇? */ bool amclusterable; - /* does AM handle predicate locks? */ + /* AM 是否处理谓词锁? */ bool ampredlocks; - /* does AM support parallel scan? */ + /* AM 是否支持并行扫描? */ bool amcanparallel; - /* does AM support columns included with clause INCLUDE? */ + /* AM 是否支持由 INCLUDE 子句包含的列? */ bool amcaninclude; - /* does AM use maintenance_work_mem? */ + /* AM 是否使用 maintenance_work_mem? */ bool amusemaintenanceworkmem; - /* OR of parallel vacuum flags */ + /* 并行清理标志的 OR 组合 */ uint8 amparallelvacuumoptions; - /* type of data stored in index, or InvalidOid if variable */ + /* 索引中存储的数据类型;如果可变,则为 InvalidOid */ Oid amkeytype; - /* interface functions */ + /* 接口函数 */ ambuild_function ambuild; ambuildempty_function ambuildempty; aminsert_function aminsert; ambulkdelete_function ambulkdelete; amvacuumcleanup_function amvacuumcleanup; - amcanreturn_function amcanreturn; /* can be NULL */ + amcanreturn_function amcanreturn; /* 可以为 NULL */ amcostestimate_function amcostestimate; amoptions_function amoptions; - amproperty_function amproperty; /* can be NULL */ - ambuildphasename_function ambuildphasename; /* can be NULL */ + amproperty_function amproperty; /* 可以为 NULL */ + ambuildphasename_function ambuildphasename; /* 可以为 NULL */ amvalidate_function amvalidate; ambeginscan_function ambeginscan; amrescan_function amrescan; - amgettuple_function amgettuple; /* can be NULL */ - amgetbitmap_function amgetbitmap; /* can be NULL */ + amgettuple_function amgettuple; /* 可以为 NULL */ + amgetbitmap_function amgetbitmap; /* 可以为 NULL */ amendscan_function amendscan; - ammarkpos_function ammarkpos; /* can be NULL */ - amrestrpos_function amrestrpos; /* can be NULL */ + ammarkpos_function ammarkpos; /* 可以为 NULL */ + amrestrpos_function amrestrpos; /* 可以为 NULL */ - /* interface functions to support parallel index scans */ - amestimateparallelscan_function amestimateparallelscan; /* can be NULL */ - aminitparallelscan_function aminitparallelscan; /* can be NULL */ - amparallelrescan_function amparallelrescan; /* can be NULL */ + /* 支持并行索引扫描的接口函数 */ + amestimateparallelscan_function amestimateparallelscan; /* 可以为 NULL */ + aminitparallelscan_function aminitparallelscan; /* 可以为 NULL */ + amparallelrescan_function amparallelrescan; /* 可以为 NULL */ } IndexAmRoutine; @@ -184,7 +184,7 @@ ambulkdelete (IndexVacuumInfo *info, IndexBulkDeleteCallback callback, void *callback_state); - 从索引中删除元组。这是一个批量删除操作,通常应通过扫描整个索引并检查每个条目是否应被删除来实现。必须调用传入的 callback 函数,其调用形式为 callback(TID, callback_state) returns bool,以确定由其引用 TID 标识的某个索引条目是否应删除。该函数必须返回 NULL,或者返回一个通过 palloc 分配的结构体,其中包含此次删除操作影响的统计信息。如果不需要向 amvacuumcleanup 传递信息,返回 NULL 也是可以的。 + 从索引中删除元组。这是一个批量删除操作,旨在通过扫描整个索引并检查每个条目是否应被删除来实现。必须调用传入的 callback 函数,其调用形式为 callback(TID, callback_state) returns bool,以确定由其引用 TID 标识的某个索引条目是否应删除。该函数必须返回 NULL,或者返回一个通过 palloc 分配的结构体,其中包含此次删除操作影响的统计信息。如果不需要向 amvacuumcleanup 传递信息,返回 NULL 也是可以的。 @@ -208,8 +208,9 @@ amvacuumcleanup (IndexVacuumInfo *info, bool amcanreturn (Relation indexRelation, int attno); -检查索引是否可以支持仅索引扫描,方法是返回给定列的原始被索引值。属性编号从 1 开始,即第一列的 attno 为 1。支持时返回真,否则返回假。对于包含列(如果支持),此函数应始终返回真,因为无法取回值的包含列没有什么意义。如果访问方法完全不支持仅索引扫描,则其amcanreturn字段在其IndexAmRoutine结构体中可以设为 NULL。 + + 检查索引能否通过返回给定列原始的被索引值,在该列上支持 仅索引扫描。属性编号从 1 开始,也就是说第一列的 attno 为 1。若支持则返回真,否则返回假。如果支持包含列,这个函数应始终对包含列返回真,因为不能取回的包含列几乎没有意义。如果访问方法根本不支持仅索引扫描,那么它的 IndexAmRoutine 结构体中的 amcanreturn 字段可以设为 NULL。 + @@ -222,7 +223,9 @@ amcostestimate (PlannerInfo *root, Selectivity *indexSelectivity, double *indexCorrelation, double *indexPages); -估计一次索引扫描的开销。该函数的完整说明见(见下文)。 + + 估计一次索引扫描的代价。该函数将在后面的 中详细讨论。 + @@ -230,7 +233,7 @@ bytea * amoptions (ArrayType *reloptions, bool validate); - 解析并验证索引的 reloptions 数组。只有当该索引存在非空的 reloptions 数组时才会调用此函数。reloptions 是一个 text 数组,其中的条目形如 name=value。该函数应构造一个 bytea 值,并将其复制到索引 relcache 条目的 rd_options 字段中。这个 bytea 值中的数据内容由访问方法自行定义;大多数标准访问方法使用结构体 StdRdOptions。当 validate 为真时,若存在未识别选项或无效取值,函数应报告合适的错误消息;当 validate 为假时,无效条目应被静默忽略。(当装载已存储在 pg_catalog 中的选项时,validate 为假;此时只有在访问方法改变了选项规则时才可能发现无效条目,而忽略过时条目是合适的。)如果希望采用默认行为,返回 NULL 也是可以的。 + 解析并验证索引的 reloptions 数组。只有当该索引存在非 NULL 的 reloptions 数组时才会调用此函数。reloptions 是一个 text 数组,其中的条目形如 name=value。该函数应构造一个 bytea 值,并将其复制到索引 relcache 条目的 rd_options 字段中。这个 bytea 值中的数据内容由访问方法自行定义;大多数标准访问方法使用结构体 StdRdOptions。当 validate 为真时,若存在未识别选项或无效取值,函数应报告合适的错误消息;当 validate 为假时,无效条目应被静默忽略。(当装载已存储在 pg_catalog 中的选项时,validate 为假;此时只有在访问方法改变了选项规则时才可能发现无效条目,而忽略过时条目是合适的。)如果希望采用默认行为,返回 NULL 也是可以的。 @@ -242,7 +245,7 @@ amproperty (Oid index_oid, int attno, 该amproperty方法允许索引访问方法覆盖pg_index_column_has_property及其相关函数的默认行为。如果访问方法对索引属性查询没有任何特殊行为,那么amproperty字段在其IndexAmRoutine结构体中可以设为 NULL。否则,amproperty方法会收到如下调用参数:index_oidattno均为零,对应pg_indexam_has_property调用;或者index_oid有效且attno为零,对应pg_index_has_property调用;或者index_oid有效且attno大于零,对应pg_index_column_has_property调用。prop是一个枚举值,用来标识当前测试的属性;propname则是原始属性名字符串。如果核心代码不认识该属性名,那么propAMPROP_UNKNOWN。访问方法可以通过检查propname是否匹配来定义自定义属性名(使用pg_strcasecmp进行匹配,以与核心代码保持一致);对于核心代码已知的名称,最好检查prop。如果amproperty方法返回true,则表示它已确定属性测试结果:它必须将*res设为要返回的布尔值,或者把*isnull设为true以返回 NULL。(所引用的两个变量在调用前都初始化为false。)如果amproperty方法返回false,核心代码就会按其正常逻辑确定属性测试结果。 - 支持排序操作符的访问方法应当实现 AMPROP_DISTANCE_ORDERABLE 属性测试,因为核心代码不知道如何完成该测试,只会返回 NULL。若实现成本低于打开索引并调用 amcanreturn(这正是核心代码的默认行为),那么实现 AMPROP_RETURNABLE 测试也可能是有利的。对于其他所有标准属性,默认行为应当已经足够。 + 支持排序操作符的访问方法应当实现 AMPROP_DISTANCE_ORDERABLE 属性测试,因为核心代码不知道如何完成该测试,只会返回 NULL。若完成该测试的代价低于打开索引并调用 amcanreturn(这正是核心代码的默认行为),那么实现 AMPROP_RETURNABLE 测试也可能是有利的。对于其他所有标准属性,默认行为应当已经足够。 @@ -270,7 +273,8 @@ IndexScanDesc ambeginscan (Relation indexRelation, int nkeys, int norderbys); -为索引扫描做准备。nkeysnorderbys参数指明扫描中将使用的限定条件和排序操作符的数量,可用于分配空间。注意,此时尚未提供扫描键的实际值。结果必须是用 palloc 分配的结构体。由于实现方面的原因,索引访问方法必须调用RelationGetIndexScan()来创建此结构体。大多数情况下,ambeginscan除了执行该调用以及可能获取锁之外,几乎不做其他工作;索引扫描启动过程的主要工作位于amrescan。 + + 为一次索引扫描做准备。nkeysnorderbys 参数表示扫描中将使用的限定条件和排序操作符数量,这些信息可能有助于空间分配。请注意,此时还没有提供扫描键的实际值。结果必须是一个通过 palloc 分配的结构体。出于实现上的原因,索引访问方法必须通过调用 RelationGetIndexScan() 来创建这个结构体。大多数情况下,ambeginscan 除了做这次调用以及也许获取一些锁之外,不会做太多工作;索引扫描启动中真正有意思的部分在 amrescan 中。 @@ -290,10 +294,12 @@ amrescan (IndexScanDesc scan, bool amgettuple (IndexScanDesc scan, ScanDirection direction); -沿给定方向(在索引中向前或向后)获取给定扫描中的下一个元组。如果取得元组,则返回 true;如果没有剩余的匹配元组,则返回 false。返回 true 时,将元组 TID 存储到scan结构体中。注意,成功仅表示索引中包含与扫描键匹配的条目,并不表示该元组一定仍存在于堆中,或者能够通过调用方的快照测试。成功时,amgettuple还必须将scan->xs_recheck设为 true 或 false。false 表示可以确定索引条目与扫描键匹配;true 表示尚不确定,在获取堆元组后,必须对它重新检查扫描键所表示的条件。这一规定支持有损索引操作符。注意,重新检查仅针对扫描条件;部分索引谓词(如果有)永远不会由amgettuple的调用方重新检查。 + + 在给定扫描中取出下一个元组,并按给定方向移动(在索引中向前或向后)。若成功取得元组则返回真;若不再有匹配元组则返回假。在返回真时,元组的 TID 会存入 scan 结构体中。请注意,成功仅表示索引中存在一个匹配扫描键的条目,并不表示该元组一定仍然存在于堆中,或者一定能通过调用者的快照测试。成功时,amgettuple 还必须把 scan->xs_recheck 设为真或假。假表示可以确定该索引条目匹配扫描键;真表示这一点并不确定,因此在取到堆元组后必须根据扫描键所代表的条件重新检查它。这一机制支持有损索引操作符。请注意,重检只针对扫描条件;部分索引谓词(如果有)永远不会由 amgettuple 的调用者重新检查。 + - 如果索引支持 仅索引扫描(即其任一列上 amcanreturn 返回真),那么成功时 AM 还必须检查 scan->xs_want_itup;若其为真,就必须返回该索引条目的原始被索引数据。对于 amcanreturn 返回假的列,可以把其值作为 NULL 返回。数据可以通过以下两种形式之一返回:一种是把 IndexTuple 指针存入 scan->xs_itup,其元组描述符为 scan->xs_itupdesc;另一种是把 HeapTuple 指针存入 scan->xs_hitup,其元组描述符为 scan->xs_hitupdesc。(当重建出的数据可能装不进 IndexTuple 时,应使用后一种格式。)无论采用哪种形式,指针所引用数据的管理责任都在访问方法一侧。对这份数据的有效性必须至少保持到该扫描下一次调用 amgettupleamrescanamendscan 为止。 + 如果索引支持 仅索引扫描(即其至少一列上 amcanreturn 返回真),那么成功时 AM 还必须检查 scan->xs_want_itup;若其为真,就必须返回该索引条目的原始被索引数据。对于 amcanreturn 返回假的列,可以把其值作为 NULL 返回。数据可以通过以下两种形式之一返回:一种是把 IndexTuple 指针存入 scan->xs_itup,其元组描述符为 scan->xs_itupdesc;另一种是把 HeapTuple 指针存入 scan->xs_hitup,其元组描述符为 scan->xs_hitupdesc。(当重建出的数据可能装不进 IndexTuple 时,应使用后一种格式。)无论采用哪种形式,指针所引用数据的管理责任都在访问方法一侧。这份数据必须至少保持有效,直到该扫描下一次调用 amgettupleamrescanamendscan @@ -305,7 +311,8 @@ amgettuple (IndexScanDesc scan, int64 amgetbitmap (IndexScanDesc scan, TIDBitmap *tbm); -获取给定扫描中的所有元组,并将其加入调用方提供的TIDBitmap中(即将元组 ID 集合与位图中已有的集合做 OR 运算)。返回获取到的元组数量(可能只是近似值,例如某些访问方法不检测重复项)。向位图插入元组 ID 时,amgetbitmap可以指明需要对特定元组 ID 重新检查扫描条件。这类似于xs_recheck输出参数,它属于amgettuple。注意:在当前实现中,此特性的支持与位图自身有损存储的支持混在一起,因此对于需要重查的元组,调用方会重新检查扫描条件和部分索引谓词(如果有)。但将来未必始终如此。amgetbitmapamgettuple不能在同一次索引扫描中使用;使用amgetbitmap时还有其他限制,详见。 + + 取出给定扫描中的所有元组,并将其加入调用者提供的 TIDBitmap 中(也就是把这组元组 ID 与位图中已有的集合做 OR)。返回值是取得的元组数量(这可能只是近似计数,例如某些 AM 不会检测重复项)。在把元组 ID 插入位图时,amgetbitmap 可以指出某些具体的元组 ID 需要重新检查扫描条件。这类似于 amgettuplexs_recheck 输出参数。注意:在当前实现中,对这一特性的支持与位图自身的有损存储支持混在一起,因此调用者会对需要重检的元组同时重新检查扫描条件和部分索引谓词(如果有)。不过,这并不一定永远如此。amgetbitmapamgettuple 不能在同一次索引扫描中同时使用;使用 amgetbitmap 时还有其他限制,详见 @@ -317,7 +324,7 @@ amgetbitmap (IndexScanDesc scan, void amendscan (IndexScanDesc scan); - 结束一次扫描并释放资源。scan 结构体本身不应被释放,但访问方法内部获取的任何锁或 pin,以及由 ambeginscan 和其他扫描相关函数分配的其他内存,都必须被释放。 + 结束一次扫描并释放资源。scan 结构体本身不应被释放,但必须释放访问方法内部获取的所有锁、解除所有钉住状态,并释放由 ambeginscan 和其他扫描相关函数分配的其他内存。 @@ -434,7 +441,7 @@ amparallelrescan (IndexScanDesc scan); - 除了使用 amgettuple 外,索引扫描也可以使用 amgetbitmap,在一次调用中取出所有元组。与 amgettuple 相比,这通常明显更高效,因为它可以避免访问方法内部的反复加锁和解锁。原则上,amgetbitmap 应具有与重复调用 amgettuple 相同的效果,但为了简化实现,我们施加了若干限制。首先,amgetbitmap 一次性返回全部元组,因此不支持标记或恢复扫描位置。其次,元组是通过一个位图返回的,没有特定顺序,这也是为什么 amgetbitmap 不带 direction 参数的原因。(这种扫描也永远不会提供排序操作符。)此外,使用 amgetbitmap 时也没有仅索引扫描的支持,因为没有办法返回索引元组的内容。最后,amgetbitmap 不保证对返回的元组做任何锁定,其影响见 。 + 除了使用 amgettuple 外,索引扫描也可以使用 amgetbitmap,在一次调用中取出所有元组。与 amgettuple 相比,这可能明显更高效,因为它可以避免访问方法内部的反复加锁和解锁。原则上,amgetbitmap 应具有与重复调用 amgettuple 相同的效果,但为了简化实现,我们施加了若干限制。首先,amgetbitmap 一次性返回全部元组,因此不支持标记或恢复扫描位置。其次,元组是通过一个位图返回的,没有特定顺序,这也是为什么 amgetbitmap 不带 direction 参数的原因。(这种扫描也永远不会提供排序操作符。)此外,使用 amgetbitmap 时也没有仅索引扫描的支持,因为没有办法返回索引元组的内容。最后,amgetbitmap 不保证对返回的元组做任何锁定,其影响见 @@ -451,7 +458,7 @@ amparallelrescan (IndexScanDesc scan); - 构建一种支持并发更新的索引类型,通常需要对所需行为进行大量而细致的分析。对于 B-树和哈希索引类型,可以阅读 src/backend/access/nbtree/READMEsrc/backend/access/hash/README 中涉及的设计决策。 + 构建一种支持并发更新的索引类型,通常需要对所需行为进行大量而细致的分析。对于 B-树和 hash 索引类型,可以阅读 src/backend/access/nbtree/READMEsrc/backend/access/hash/README 中涉及的设计决策。 @@ -470,12 +477,12 @@ amparallelrescan (IndexScanDesc scan); - 索引扫描必须在保存 amgettuple 最近一次返回条目的索引页面上维护一个 pin,而 ambulkdelete 不能从被其他后端钉住的页面中删除条目。下面会解释为什么需要这条规则。 + 索引扫描必须在保存 amgettuple 最近一次返回条目的索引页面上保持钉住状态,而 ambulkdelete 不能从被其他后端钉住的页面中删除条目。下面会解释为什么需要这条规则。
- 如果没有第三条规则,索引读取者就有可能在某个索引条目被 VACUUM 删除之前先看到它,然后在对应的堆条目已被 VACUUM 删除之后才到达那里。如果读取者到达时,该项号仍未被重新使用,就不会造成严重问题,因为空项槽位会被 heap_fetch() 忽略。但如果第三个后端已经把这个项槽位重新用作别的东西呢?在使用 MVCC 兼容快照时不会有问题,因为该槽位的新占用者一定太新,无法通过快照测试。然而,对于非 MVCC 兼容的快照(例如 SnapshotAny),就可能错误地接受并返回一行实际上并不匹配扫描键的数据。我们可以要求在所有情况下都对堆行重新检查扫描键,以防范这种情形,但那样代价太高。于是,我们改为把索引页面上的 pin 作为一种代理,表示读取者可能仍处于从索引条目前往匹配堆条目的飞行中。让 ambulkdelete 在这种 pin 上阻塞,能够保证 VACUUM 不会在读取者处理完之前删除对应的堆条目。这种方案运行时开销很小,只有在真正发生冲突的少数情况下才会增加阻塞开销。 + 如果没有第三条规则,索引读取者就有可能在某个索引条目被 VACUUM 删除之前先看到它,然后在对应的堆条目已被 VACUUM 删除之后才到达那里。如果读取者到达时,该项号仍未被重新使用,就不会造成严重问题,因为空项槽位会被 heap_fetch() 忽略。但如果第三个后端已经把这个项槽位重新用作别的东西呢?在使用 MVCC 兼容快照时不会有问题,因为该槽位的新占用者一定太新,无法通过快照测试。然而,对于非 MVCC 兼容的快照(例如 SnapshotAny),就可能错误地接受并返回一行实际上并不匹配扫描键的数据。我们可以要求在所有情况下都对堆行重新检查扫描键,以防范这种情形,但那样代价太高。于是,我们改为把索引页面的钉住状态作为一种代理,表示读取者从索引条目到匹配堆条目的访问过程可能仍在进行中。让 ambulkdelete 因这种钉住状态而阻塞,能够保证 VACUUM 不会在读取者处理完之前删除对应的堆条目。这种方案运行时开销很小,只有在真正发生冲突的少数情况下才会增加阻塞开销。 @@ -483,7 +490,7 @@ amparallelrescan (IndexScanDesc scan); - 在 amgetbitmap 索引扫描中,访问方法不会在任何返回的元组上保留索引 pin。因此,只有把这种扫描与 MVCC 兼容的快照一起使用才是安全的。 + 在 amgetbitmap 索引扫描中,访问方法不会为任何返回的元组保持索引页面的钉住状态。因此,只有把这种扫描与 MVCC 兼容的快照一起使用才是安全的。 @@ -522,14 +529,17 @@ amparallelrescan (IndexScanDesc scan); - 此外,在按照上述规则报告唯一性违背之前,访问方法必须立即重新检查正在插入那一行的存活性。如果它已经是提交后死亡的状态,就不应报告违背。(这种情况不会出现在插入由当前事务刚创建的行这一普通场景中,但在 CREATE UNIQUE INDEX CONCURRENTLY 期间却可能发生。) + 此外,就在按照上述规则报告唯一性违背之前,访问方法必须重新检查正在插入那一行的存活性。如果它已经是提交后死亡的状态,就不应报告违背。(这种情况不会出现在插入由当前事务刚创建的行这一普通场景中,但在 CREATE UNIQUE INDEX CONCURRENTLY 期间却可能发生。) 我们要求索引访问方法自行应用这些测试,这意味着它必须深入堆中检查那些根据索引内容显示为具有重复键的行的提交状态。毫无疑问,这样做既丑陋又不够模块化,但它避免了重复工作:如果我们单独再做一次探测,那么在寻找新行索引条目插入位置时,查找冲突行的索引搜索实际上就会被重复执行。更何况,除非把冲突检查作为插入新索引条目动作的一个组成部分,否则也没有明显的方法可以避免竞争条件。 - 如果唯一约束可延迟,处理就更复杂:需要能够为新行插入索引条目,同时将唯一性冲突错误延迟到语句结束时甚至更晚。为避免不必要地重复搜索索引,索引访问方法应在首次插入时进行初步唯一性检查。如果确定不存在冲突的存活元组,就已完成检查。否则,应在需要强制执行约束时安排重新检查。如果重新检查时,插入的元组和某个具有相同键的其他元组都仍存活,就必须报告错误。(注意,在此场景中,存活实际表示索引条目 HOT 链中的任一元组是存活的。)为实现这一点,会向aminsert函数传入一个checkUnique参数,其值为以下之一: + + 如果唯一约束是可延迟的,情况会更复杂:我们需要能够为新行插入一个索引条目,但把任何唯一性违背错误延迟到语句结束时甚至更晚才报告。为了避免对索引进行不必要的重复搜索,索引访问方法应在初始插入期间执行一次初步唯一性检查。如果这表明确实不存在冲突的存活元组,那么事情就结束了。否则,我们会安排在真正强制约束时再做一次重检。若在重检时,插入的元组与另外某个具有相同键值的元组都仍然存活,就必须报告错误。(注意,就此用途而言,存活实际上是指索引条目 HOT 链中至少有一个元组是存活的。)为实现这一点,传给 aminsert 函数的 checkUnique 参数会取以下值之一: + + UNIQUE_CHECK_NO 表示不应执行唯一性检查(这不是唯一索引)。 @@ -564,10 +574,10 @@ amparallelrescan (IndexScanDesc scan); - 索引开销估计函数 + 索引代价估算函数 - amcostestimate 函数会收到描述某种可能索引扫描方式的信息,其中包括已经确定可用于该索引的 WHERE 子句和 ORDER BY 子句列表。它必须返回访问该索引的开销估计,以及 WHERE 子句的选择率(也就是在索引扫描期间将从父表中检索出的行所占比例)。对于简单情况,开销估计器几乎所有工作都可以通过调用优化器中的标准例程来完成;之所以提供 amcostestimate 函数,是为了让索引访问方法能够提供与索引类型有关的专门知识,以便在可能时改进标准估计。 + amcostestimate 函数会收到描述某种可能索引扫描方式的信息,其中包括已经确定可用于该索引的 WHERE 子句和 ORDER BY 子句列表。它必须返回访问该索引的代价估算,以及 WHERE 子句选择率的估计值(也就是在索引扫描期间将从父表中检索出的行所占比例)。对于简单情况,代价估算器几乎所有工作都可以通过调用优化器中的标准例程来完成;之所以提供 amcostestimate 函数,是为了让索引访问方法能够提供与索引类型有关的专门知识,以便在可能时改进标准估计。 @@ -601,7 +611,7 @@ amcostestimate (PlannerInfo *root, path - 当前正在考虑的索引访问路径。除开销和选择率字段外,其余字段都有效。 + 当前正在考虑的索引访问路径。除代价和选择率字段外,其余字段都有效。 @@ -610,7 +620,7 @@ amcostestimate (PlannerInfo *root, loop_count - 在开销估计中应计入的索引扫描重复次数。当考虑在嵌套循环连接内部使用参数化扫描时,这个参数通常会大于 1。请注意,开销估计仍应只针对一次扫描;更大的 loop_count 只表示可以适当考虑多次扫描之间的一些缓存效应。 + 在代价估算中应计入的索引扫描重复次数。当考虑在嵌套循环连接内部使用参数化扫描时,这个参数通常会大于 1。请注意,代价估算仍应只针对一次扫描;更大的 loop_count 只表示可以适当考虑多次扫描之间的一些缓存效应。 @@ -625,7 +635,7 @@ amcostestimate (PlannerInfo *root, *indexStartupCost - 设为索引启动处理的开销。 + 设为索引启动处理的代价。 @@ -634,7 +644,7 @@ amcostestimate (PlannerInfo *root, *indexTotalCost - 设为索引处理的总开销。 + 设为索引处理的总代价。 @@ -669,19 +679,19 @@ amcostestimate (PlannerInfo *root, - 请注意,开销估计函数必须用 C 编写,而不能用 SQL 或任何可用的过程语言,因为它们必须访问规划器/优化器的内部数据结构。 + 请注意,代价估算函数必须用 C 编写,而不能用 SQL 或任何可用的过程语言,因为它们必须访问规划器/优化器的内部数据结构。 - 索引访问开销应使用 src/backend/optimizer/path/costsize.c 所采用的参数来计算:顺序磁盘块读取的开销为 seq_page_cost,非顺序读取的开销为 random_page_cost,处理一条索引行的开销通常应取为 cpu_index_tuple_cost。此外,在索引处理期间调用的任何比较操作符(特别是对 indexquals 本身的求值)都应计入适当倍数的 cpu_operator_cost。 + 索引访问代价应使用 src/backend/optimizer/path/costsize.c 所采用的参数来计算:顺序磁盘块读取的代价为 seq_page_cost,非顺序读取的代价为 random_page_cost,处理一条索引行的代价通常应取为 cpu_index_tuple_cost。此外,在索引处理期间调用的任何比较操作符(特别是对 indexquals 本身的求值)都应计入适当倍数的 cpu_operator_cost - 访问开销应包括与扫描索引本身有关的全部磁盘和 CPU 开销,但包括取出或处理由索引标识出的父表行的开销。 + 访问代价应包括与扫描索引本身有关的全部磁盘和 CPU 代价,但包括取出或处理由索引标识出的父表行的代价。 - 启动开销是整个扫描总开销中必须在开始取第一行之前先付出的那一部分。对大多数索引来说,这可以视为零;但启动开销较高的索引类型可能希望把它设为非零。 + 启动代价是整个扫描总代价中必须在开始取第一行之前先付出的那一部分。对大多数索引来说,这可以视为零;但启动代价较高的索引类型可能希望把它设为非零。 @@ -689,7 +699,7 @@ amcostestimate (PlannerInfo *root, - indexCorrelation 应设为索引顺序与表顺序之间的相关性(范围从 -1.0 到 1.0)。该值用于调整从父表取行开销的估计。 + indexCorrelation 应设为索引顺序与表顺序之间的相关性(范围从 -1.0 到 1.0)。该值用于调整从父表取行代价的估计。 @@ -701,9 +711,9 @@ amcostestimate (PlannerInfo *root, - 开销估计 + 代价估算 - 一个典型的开销估计器会按如下步骤进行: + 一个典型的代价估算器会按如下步骤进行: @@ -732,14 +742,14 @@ amcostestimate (PlannerInfo *root, - 计算索引访问开销。一个通用估计器可能会这样做: + 计算索引访问代价。一个通用估计器可能会这样做: /* - * Our generic assumption is that the index pages will be read - * sequentially, so they cost seq_page_cost each, not random_page_cost. - * Also, we charge for evaluation of the indexquals at each index row. - * All the costs are assumed to be paid incrementally during the scan. + * 通用假设是索引页面将按顺序读取, + * 因此每页代价为 seq_page_cost,而非 random_page_cost。 + * 此外,还要计入在每个索引行上对 indexquals 求值的代价。 + * 假定所有代价都在扫描过程中逐步付出。 */ cost_qual_eval(&index_qual_cost, path->indexquals, root); *indexStartupCost = index_qual_cost.startup; @@ -759,7 +769,7 @@ cost_qual_eval(&index_qual_cost, path->indexquals, root); - 开销估计器函数的示例可在 src/backend/utils/adt/selfuncs.c 中找到。 + 代价估算器函数的示例可在 src/backend/utils/adt/selfuncs.c 中找到。 diff --git a/zh/13/indices.sgml b/zh/13/indices.sgml index f5c52f2c..1ff191f9 100644 --- a/zh/13/indices.sgml +++ b/zh/13/indices.sgml @@ -31,7 +31,7 @@ SELECT content FROM test1 WHERE id = constant; - 大多数非小说类书籍也采用了类似的方法:读者经常查找的术语和概念会被收集到书末按字母顺序排列的索引中。感兴趣的读者可以相对快速地浏览索引并翻到相应页面,而不必通读整本书才能找到自己感兴趣的内容。正如作者需要预判读者可能查找哪些条目一样,数据库程序员也需要预见哪些索引会有用。 + 大多数非虚构类书籍也采用了类似的方法:读者经常查找的术语和概念会被收集到书末按字母顺序排列的索引中。感兴趣的读者可以相对快速地浏览索引并翻到相应页面,而不必通读整本书才能找到自己感兴趣的内容。正如作者需要预判读者可能查找哪些条目一样,数据库程序员也需要预见哪些索引会有用。 @@ -71,7 +71,7 @@ CREATE INDEX test1_id_index ON test1 (id); comparison-value operator indexed-column - 那么如果原始operator有一个可交换操作符,并且该操作符属于该索引的操作符类,就可以把它翻转成可索引的形式。 + 那么如果原始operator有一个交换子操作符,并且该操作符属于该索引的操作符类,就可以把它翻转成可索引的形式。 @@ -87,7 +87,7 @@ CREATE INDEX test1_id_index ON test1 (id); 索引类型 - PostgreSQL提供了多种索引类型:B-树、哈希、GiST、SP-GiST、GIN、BRIN,以及扩展bloom。每种索引类型都采用不同的算法,分别最适合不同类型的可索引子句。默认情况下,CREATE INDEX命令创建的是 B-树索引,它适用于最常见的场景。 + PostgreSQL提供了多种索引类型:B-树、Hash、GiST、SP-GiST、GIN、BRIN,以及扩展bloom。每种索引类型都采用不同的算法,分别最适合不同类型的可索引子句。默认情况下,CREATE INDEX命令创建的是 B-树索引,它适用于最常见的场景。 索引 B-树 B-树 索引 B-树能够处理可以按某种顺序排序的数据上的等值查询和范围查询。特别是,只要已索引列参与了下列任一操作符的比较,PostgreSQL查询规划器就会考虑使用 B-树索引: @@ -110,12 +110,12 @@ CREATE INDEX test1_id_index ON test1 (id); 索引 - 哈希 + hash - 哈希 + hash 索引 - 哈希索引只能处理简单的等值比较。只要已索引列参与的是使用=操作符的比较,查询规划器就会考虑使用哈希索引。使用以下命令创建哈希索引: + Hash 索引只能处理简单的等值比较。只要已索引列参与的是使用=操作符的比较,查询规划器就会考虑使用 Hash 索引。使用以下命令创建 Hash 索引: CREATE INDEX name ON table USING HASH (column); @@ -134,7 +134,7 @@ CREATE INDEX name ON table SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10; ]]> - 这会找出距离给定目标点最近的十个地点。是否能做到这一点,同样取决于所使用的具体操作符类。在中,可以按这种方式使用的操作符列在Ordering Operators这一列中。 + 这会找出距离给定目标点最近的十个地点。是否能做到这一点,同样取决于所使用的具体操作符类。在中,可以按这种方式使用的操作符列在排序操作符这一列中。 索引 SP-GiST SP-GiST 索引 @@ -173,8 +173,8 @@ SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10; 多列索引 - index - multicolumn + 索引 + 多列 @@ -205,15 +205,15 @@ CREATE INDEX test2_mm_idx ON test2 (major, minor); - 多列 GIN 索引可以用于涉及索引任意列子集的查询条件。与 B-树或 GiST 不同,无论查询条件使用的是哪一列索引列,GIN 的索引搜索效果都一样。 + 多列 GIN 索引可以用于涉及索引任意列子集的查询条件。与 B-树或 GiST 不同,无论查询条件使用的是哪些索引列,GIN 的索引搜索效果都一样。 - 多列 BRIN 索引可以用于涉及索引任意列子集的查询条件。和 GIN 一样、不同于 B-树或 GiST,无论查询条件使用的是哪一列索引列,索引搜索效果都一样。在单个表上使用多个 BRIN 索引,而不是使用一个多列 BRIN 索引的唯一理由,是需要不同的pages_per_range存储参数。 + 多列 BRIN 索引可以用于涉及索引任意列子集的查询条件。和 GIN 一样、不同于 B-树或 GiST,无论查询条件使用的是哪些索引列,索引搜索效果都一样。在单个表上使用多个 BRIN 索引,而不是使用一个多列 BRIN 索引的唯一理由,是需要不同的pages_per_range存储参数。 - 多列 GIN 索引可以用于涉及索引任意列子集的查询条件。与 B-树或 GiST 不同,无论查询条件使用的是哪一列索引列,GIN 的索引搜索效果都一样。 + 当然,每一列都必须配合适合该索引类型的操作符使用;涉及其他操作符的子句不会被考虑。 @@ -226,8 +226,8 @@ CREATE INDEX test2_mm_idx ON test2 (major, minor); 索引和<literal>ORDER BY</literal> - index - and ORDER BY + 索引 + ORDER BY @@ -235,7 +235,7 @@ CREATE INDEX test2_mm_idx ON test2 (major, minor); - 规划器在满足ORDER BY要求时,会考虑两种方案:扫描一个与该要求匹配的可用索引,或者按物理顺序扫描表再显式排序。对于需要扫描表中很大一部分内容的查询,显式排序通常会比使用索引更快,因为它遵循顺序访问模式,需要的磁盘 I/O 更少。只有在只需取出少量行时,索引才更有价值。一个重要的特例是ORDER BYLIMIT n组合使用:显式排序必须处理所有数据才能找出最前面的n行,而如果有一个与ORDER BY匹配的索引,就可以直接取回前n行,而完全不必扫描剩余数据。 + 规划器在满足ORDER BY要求时,会考虑两种方案:扫描一个与该要求匹配的可用索引,或者按物理顺序扫描表再显式排序。对于需要扫描表中很大一部分内容的查询,显式排序通常会比使用索引更快,因为它遵循顺序访问模式,需要的磁盘 I/O 更少。只需取出少量行时,索引更有价值。一个重要的特例是ORDER BYLIMIT n组合使用:显式排序必须处理所有数据才能找出最前面的n行,而如果有一个与ORDER BY匹配的索引,就可以直接取回前n行,而完全不必扫描剩余数据。 @@ -265,12 +265,12 @@ CREATE INDEX test3_desc_index ON test3 (id DESC NULLS LAST); 组合多个索引 - index - combining multiple indexes + 索引 + 组合多个索引 - bitmap scan + 位图扫描 @@ -297,8 +297,8 @@ CREATE INDEX test3_desc_index ON test3 (id DESC NULLS LAST); 唯一索引 - index - unique + 索引 + 唯一 @@ -329,8 +329,8 @@ CREATE UNIQUE INDEX name ON table表达式索引 - index - on expressions + 索引 + 基于表达式 @@ -377,8 +377,8 @@ CREATE INDEX people_names ON people ((first_name || ' ' || last_name)); 部分索引 - index - partial + 索引 + 部分 @@ -386,7 +386,7 @@ CREATE INDEX people_names ON people ((first_name || ' ' || last_name)); - 使用部分索引的一个主要原因是避免索引常见值。由于搜索常见值的查询(即占全部表行百分之几以上的值)反正也不会使用索引,因此完全没有必要把这些行保留在索引里。这会减小索引尺寸,从而加快那些确实会使用该索引的查询。它也会加快很多表更新操作,因为索引并不需要在所有情况下都更新。展示了这种思路的一种可能应用。 + 使用部分索引的一个主要原因是避免索引常见值。由于搜索常见值(即占全部表行百分之几以上的值)的查询反正也不会使用索引,因此完全没有必要把这些行保留在索引里。这会减小索引尺寸,从而加快那些确实会使用该索引的查询。它也会加快很多表更新操作,因为索引并不需要在所有情况下都更新。展示了这种思路的一种可能应用。 @@ -416,11 +416,15 @@ WHERE NOT (client_ip > inet '192.168.100.0' AND - 一个能够使用此索引的典型查询如下: + + 一个可以使用该索引的典型查询是: + SELECT * FROM access_log WHERE url = '/index.html' AND client_ip = inet '212.78.10.32'; -这里,查询的 IP 地址被部分索引覆盖。下面的查询不能使用该部分索引,因为它使用的 IP 地址被排除在索引之外: + + 这里查询中的 IP 地址落在部分索引覆盖的范围内。下面这个查询则不能使用该部分索引,因为它使用了一个被索引排除掉的 IP 地址: + SELECT * FROM access_log WHERE url = '/index.html' AND client_ip = inet '192.168.100.23'; @@ -470,7 +474,7 @@ SELECT * FROM orders WHERE order_nr = 3501; - 也说明了:索引列和谓词中使用的列不必一致。PostgreSQL支持带任意谓词的部分索引,只要其中只涉及正在建立索引的那张表的列。不过要记住,谓词必须与那些希望从该索引受益的查询中使用的条件相匹配。更准确地说,只有当系统能够识别出查询的WHERE条件在数学上蕴含该索引的谓词时,部分索引才能用于该查询。PostgreSQL并没有一个复杂的定理证明器,来识别那些写法不同但数学上等价的表达式。(不仅构建这样一个通用定理证明器极其困难,而且它很可能也会慢到失去实际用途。)系统可以识别简单的不等式蕴含,例如x < 1蕴含x < 2;否则,谓词条件必须与查询WHERE条件的某一部分完全匹配,否则索引不会被识别为可用。匹配发生在查询规划阶段,而不是运行时。因此,参数化查询子句无法与部分索引配合工作。例如,一个带参数的预备查询可能写成x < ?,而对于参数的所有可能取值,它都不可能蕴含x < 2。 + 也说明了:索引列和谓词中使用的列不必一致。PostgreSQL支持带任意谓词的部分索引,只要其中只涉及正在建立索引的那张表的列。不过要记住,谓词必须与那些希望从该索引受益的查询中使用的条件相匹配。更准确地说,只有当系统能够识别出查询的WHERE条件在数学上蕴含该索引的谓词时,部分索引才能用于该查询。PostgreSQL并没有一个复杂的定理证明器,来识别那些写法不同但数学上等价的表达式。(不仅构建这样一个通用定理证明器极其困难,而且它很可能也会慢到失去实际用途。)系统可以识别简单的不等式蕴含,例如x < 1蕴含x < 2;否则,谓词条件必须与查询WHERE条件的某一部分完全匹配,否则索引不会被识别为可用。匹配发生在查询规划阶段,而不是运行时。因此,参数化查询子句无法与部分索引配合工作。例如,一个带参数的预备查询可能写成x < ?,而它无法保证在参数的所有可能取值下都蕴含x < 2 @@ -481,7 +485,9 @@ SELECT * FROM orders WHERE order_nr = 3501; 建立一个部分唯一索引 - 假设有一个记录测试结果的表。我们希望确保每个给定的测试对象和目标组合只有一个成功条目,但可以有任意数量的失败条目。下面是一种实现方法: + + 假设我们有一张描述测试结果的表。我们希望确保对于给定的测试对象和目标组合,只有一条成功记录,但可以有任意多条失败记录。实现方法之一如下: + CREATE TABLE tests ( subject text, target text, @@ -491,7 +497,9 @@ CREATE TABLE tests ( CREATE UNIQUE INDEX tests_success_constraint ON tests (subject, target) WHERE success; -在成功测试很少而失败测试很多时,这种方法尤其高效。也可以创建一个带有IS NULL限制的唯一部分索引,从而只允许列中出现一个空值。 + + 当成功测试很少而失败测试很多时,这是一种特别高效的方法。也可以通过创建一个带IS NULL限制的唯一部分索引,来让某一列只允许出现一个空值。 + @@ -562,7 +570,10 @@ CREATE INDEX mytable_cat_data ON mytable (category, data); PostgreSQL中的所有索引都是二级索引,也就是说,每个索引都与表的主数据区分开存储(在PostgreSQL术语中,这个主数据区称为表的)。这意味着,在普通索引扫描中,每次取回一行都需要同时从索引和堆中取数据。此外,尽管满足某个可索引WHERE条件的索引项通常在索引中彼此接近,但它们引用的表行却可能分布在堆中的任何位置。因此,索引扫描的堆访问部分会涉及大量对堆的随机访问,这可能很慢,尤其是在传统旋转介质上。(正如中所述,位图扫描试图通过按排序顺序进行堆访问来缓解这项代价,但那也只能缓解到一定程度。) - 为了解决这一性能问题,PostgreSQL支持仅索引扫描,仅通过索引就能完成查询,无需访问堆。其基本思路是直接从各个索引项返回值,而不访问相关联的堆项。使用这种方法有两个基本限制: + + 为了解决这个性能问题,PostgreSQL支持仅索引扫描,它可以仅凭索引而不访问堆来回答查询。基本思路是直接从每个索引项中返回值,而不是再去查对应的堆项。要使用这种方法,有两个根本限制: + + 索引类型必须支持仅索引扫描。B-树索引总是支持。GiST 和 SP-GiST 索引对某些操作符类支持仅索引扫描,但对另一些则不支持。其他索引类型则完全不支持。底层要求是,索引必须实际存储原始数据值,或者至少能够重建出每个索引项对应的原始数据值。反例是 GIN 索引,它不能支持仅索引扫描,因为每个索引项通常只保存原始数据值的一部分。 @@ -570,13 +581,19 @@ CREATE INDEX mytable_cat_data ON mytable (category, data); - 查询只能引用存储在索引中的列。例如,假设某个表的xy列上有一个索引,且该表还有一列z,那么以下查询可以使用仅索引扫描: + + 查询只能引用存储在索引中的列。例如,假设某个表的xy列上有一个索引,且该表还有一列z,那么下面这些查询可以使用仅索引扫描: + SELECT x, y FROM tab WHERE x = 'key'; SELECT x FROM tab WHERE x = 'key' AND y < 42; -但以下查询不能: + + 但下面这些查询则不能: + SELECT x, z FROM tab WHERE x = 'key'; SELECT x FROM tab WHERE x = 'key' AND z < 42; -(表达式索引和部分索引会使这条规则更复杂,下文将作讨论。) + + (表达式索引和部分索引会让这条规则变得更复杂,下文会讨论。) + @@ -593,23 +610,37 @@ SELECT x FROM tab WHERE x = 'key' AND z < 42; INCLUDE 在索引定义中 - 为了有效利用仅索引扫描,可以创建一个覆盖索引,即专门包含某类常用查询所需列的索引。由于查询通常需要取出的列比搜索条件涉及的列更多,PostgreSQL允许创建这样的索引:其中一些列仅用作负载,并非搜索键的一部分。为此,需要添加一个INCLUDE子句,列出这些额外列。例如,如果经常执行如下查询: + + 为了有效利用仅索引扫描特性,你可以选择创建一个覆盖索引,也就是专门设计来包含某一类高频查询所需列的索引。由于查询通常需要取回的列不止是用于搜索的那些列,PostgreSQL允许你创建一种索引,其中某些列只是负载,而不是搜索键的一部分。这是通过添加一个INCLUDE子句列出这些额外列来实现的。例如,如果你经常运行如下查询: + SELECT y FROM tab WHERE x = 'key'; -加快此类查询的传统做法,是仅在以下列上创建索引:x。但是,定义如下的索引: + + 传统上,为了加速这类查询,通常会只在x上创建一个索引。但如果将索引定义为: + CREATE INDEX tab_x_y ON tab(x) INCLUDE (y); -可以通过仅索引扫描处理这些查询,因为y可以直接从索引中取得,无需访问堆。 + + 那么这些查询就可以以仅索引扫描的方式完成,因为y可以直接从索引中取得,而不必访问堆。 + - 由于列y并非索引搜索键的一部分,其数据类型不必是索引能够处理的类型;该列只是存储在索引中,索引机制不会解释它。另外,如果该索引是唯一索引,也就是: + + 由于列y不是索引搜索键的一部分,因此它不必属于该索引能够处理的数据类型;它只是被存储在索引中,而不会被索引机制解释。此外,如果该索引是唯一索引,即 + CREATE UNIQUE INDEX tab_x_y ON tab(x) INCLUDE (y); -那么唯一性条件只应用于列x,而不应用于xy的组合。(INCLUDE子句也可以写在UNIQUEPRIMARY KEY约束中,为建立这样的索引提供另一种语法。) + + 那么唯一性条件只作用于列x,而不作用于xy的组合。(INCLUDE子句也可以写在UNIQUEPRIMARY KEY约束中,作为建立这种索引的另一种语法。) + 向索引中添加非键负载列时,明智的做法是保持保守,尤其是宽列。如果某个索引元组超过该索引类型允许的最大尺寸,数据插入就会失败。无论如何,非键列都会复制索引对应表中的数据并让索引膨胀,因此可能拖慢搜索。另外请记住,除非表变化足够缓慢,以至于仅索引扫描很可能无需访问堆,否则把负载列包含在索引中并没有太大意义。如果反正必须访问堆元组,那么顺便从那里取出该列的值也不会增加额外代价。其他限制包括:当前不支持把表达式作为包含列;并且当前只有 B-树和 GiST 索引支持包含列。 - PostgreSQL支持INCLUDE功能之前,人们有时会将负载列写成普通索引列来创建覆盖索引,也就是写成 + + 在PostgreSQL还没有INCLUDE特性之前,人们有时会通过把负载列写成普通索引列来制作覆盖索引,也就是写成: + CREATE INDEX tab_x_y ON tab(x, y); -尽管他们从未打算将y用作WHERE子句的一部分。只要这些额外列位于末尾,这样做就没有问题;将它们放在前面是不明智的,原因见。但是,如果希望索引强制键列唯一,这种方法就不适用了。 + + 即便他们从没打算把y作为WHERE子句的一部分来使用。只要这些额外列位于尾部,这样做就没问题;如果把它们放到前导位置,则出于中解释的原因,是不明智的。不过,这种方法无法支持你希望索引对键列强制唯一性的场景。 + 后缀截断总会从 B-树 上层移除非键列。作为负载列,它们从不会被用于指导索引扫描。截断过程还会在剩余键列前缀已经足以描述最低 B-树 层上的元组时,移除一个或多个尾随键列。实践中,不带INCLUDE子句的覆盖索引通常也会避免在上层存储那些实际上只是负载的列。不过,把负载列显式定义为非键列,能可靠地让上层中的元组保持较小。 @@ -646,17 +677,19 @@ SELECT target FROM tests WHERE subject = 'some-subject' AND success; 操作符类和操作符族 - operator class + 操作符类 - operator family + 操作符族 - 索引定义可以为索引的每一列指定一个操作符类 + + 一个索引定义可以为索引的每一列指定一个操作符类。 + CREATE INDEX name ON table (column opclass [ ( opclass_options ) ] sort options , ...); -操作符类确定索引针对该列使用哪些操作符。例如,建立在类型int4上的 B-树索引会使用int4_ops类;该操作符类包含针对以下类型的值的比较函数:int4。实际中,列数据类型的默认操作符类通常就足够了。之所以需要操作符类,主要是因为对于某些数据类型,可能存在不止一种有意义的索引行为。例如,可能希望按绝对值或实部对复数数据类型排序。可以为该数据类型定义两个操作符类,并在创建索引时选择合适的类。操作符类决定基本排序顺序(随后可以通过添加排序选项进行调整:COLLATE, - ASC/DESC和/或NULLS FIRST/NULLS LAST)。 + + 操作符类标识该索引在该列上要使用哪些操作符。例如,类型int4上的一个 B-树索引会使用int4_ops类;这个操作符类包含对int4值进行比较所需的函数。实践中,列数据类型的默认操作符类通常已经足够。之所以存在操作符类,主要是因为对某些数据类型来说,可能存在多种有意义的索引行为。例如,我们可能希望按绝对值排序一种复数数据类型,也可能希望按实部排序。我们可以通过为该数据类型定义两个操作符类,并在创建索引时选择合适的那个来做到这一点。操作符类决定了基础排序顺序(之后还可以通过添加排序选项COLLATEASC/DESC和/或NULLS FIRST/NULLS LAST来修改)。 @@ -766,8 +799,8 @@ CREATE INDEX test1c_content_y_index ON test1c (content COLLATE "y"); 检查索引使用情况 - index - examining usage + 索引 + 检查使用情况 diff --git a/zh/13/information_schema.sgml b/zh/13/information_schema.sgml index 8657bc28..39db8d0b 100644 --- a/zh/13/information_schema.sgml +++ b/zh/13/information_schema.sgml @@ -382,7 +382,7 @@ collation_catalog sql_identifier - 包含此属性排序规则的数据库名(总是当前数据库),如果默认或者该属性的数据类型不可排序则为空 + 包含该属性排序规则的数据库名称(总是当前数据库);如果使用默认排序规则,或该属性的数据类型不支持排序规则,则为 null。 @@ -391,7 +391,7 @@ collation_schema sql_identifier - 包含此属性排序规则的模式名,如果默认或者该属性的数据类型不可排序则为空 + 包含该属性排序规则的模式名称;如果使用默认排序规则,或该属性的数据类型不支持排序规则,则为 null。 @@ -400,7 +400,7 @@ collation_name sql_identifier - 该属性排序规则的名称,如果默认或者该属性的数据类型不可排序则为空 + 该属性排序规则的名称;如果使用默认排序规则,或该属性的数据类型不支持排序规则,则为 null。 @@ -1610,7 +1610,7 @@ collation_catalog sql_identifier - 包含此属性排序规则的数据库名(总是当前数据库),如果默认或者该属性的数据类型不可排序则为空 + 包含该列排序规则的数据库名称(总是当前数据库);如果使用默认排序规则,或该列的数据类型不支持排序规则,则为 null。 @@ -1619,7 +1619,7 @@ collation_schema sql_identifier - 该列的包含排序规则的模式名,如果默认或者该列的数据类型不可排序则为空 + 包含该列排序规则的模式名称;如果使用默认排序规则,或该列的数据类型不支持排序规则,则为 null。 @@ -1628,7 +1628,7 @@ collation_name sql_identifier - 该列的排序规则的名称,如果默认或者该列的数据类型不可排序则为空 + 该列排序规则的名称;如果使用默认排序规则,或该列的数据类型不支持排序规则,则为 null。 @@ -2369,7 +2369,7 @@ collation_catalog sql_identifier - 包含此域排序规则的数据库名(总是当前数据库),如果默认或者该域的数据类型不可排序则为空 + 包含该域排序规则的数据库名称(总是当前数据库);如果使用默认排序规则,或该域的数据类型不支持排序规则,则为 null。 @@ -2378,7 +2378,7 @@ collation_schema sql_identifier - 包含此域排序规则的模式名,如果默认或者该域的数据类型不可排序则为空 + 包含该域排序规则的模式名称;如果使用默认排序规则,或该域的数据类型不支持排序规则,则为 null。 @@ -2387,7 +2387,7 @@ collation_name sql_identifier - 该域排序规则的名称,如果默认或者该域的数据类型不可排序则为空 + 该域排序规则的名称;如果使用默认排序规则,或该域的数据类型不支持排序规则,则为 null。 @@ -2542,7 +2542,7 @@ <literal>element_types</literal> - 视图element_types包含数组元素的数据类型描述符。当一个表列、复合类型属性、域、函数参数或函数返回值被定义为一种数组类型,相应的信息模式视图只在列data_type中包含ARRAY。要获得该数组元素类型的信息,你可以连接该相应的视图和这个视图。例如,要显示一个表的列及其数据类型和数组元素类型,你可以: + 视图element_types包含数组元素的数据类型描述符。当一个表列、复合类型属性、域、函数参数或函数返回值被定义为一种数组类型时,相应的信息模式视图只在列data_type中包含ARRAY。要获得该数组元素类型的信息,你可以连接该相应的视图和这个视图。例如,要显示一个表的列及其数据类型和数组元素类型(如果适用),你可以: SELECT c.column_name, c.data_type, e.data_type AS element_type FROM information_schema.columns c LEFT JOIN information_schema.element_types e @@ -2673,7 +2673,7 @@ ORDER BY c.ordinal_position; collation_catalog sql_identifier - 包含元素类型排序规则的数据库名称(总是当前数据库), 如果默认或该元素的数据类型是不可排序的则为空 + 包含该元素类型排序规则的数据库名称(总是当前数据库);如果使用默认排序规则,或该元素类型不支持排序规则,则为 null。 @@ -2682,7 +2682,7 @@ ORDER BY c.ordinal_position; collation_schema sql_identifier - 包含元素类型排序规则的模式名称, 如果默认或该元素的数据类型是不可排序的则为空 + 包含该元素类型排序规则的模式名称;如果使用默认排序规则,或该元素类型不支持排序规则,则为 null。 @@ -2691,7 +2691,7 @@ ORDER BY c.ordinal_position; collation_name sql_identifier - 元素类型的排序规则名, 如果默认或该元素的数据类型是不可排序的则为空 + 该元素类型排序规则的名称;如果使用默认排序规则,或该元素类型不支持排序规则,则为 null。 @@ -2754,7 +2754,7 @@ ORDER BY c.ordinal_position; domain_default character_data - 元素的数据类型所在的数据库名称(总是当前数据库) + 尚未实现 @@ -6698,7 +6698,7 @@ ORDER BY c.ordinal_position; - SQL 了解两种用户定义类型:结构类型(在PostgreSQL中也称为复合类型)以及 distinct 类型(PostgreSQL 尚未实现)。为兼顾将来,请使用列user_defined_type_category来区分它们。其他用户定义类型,如基类型和枚举(两者都是PostgreSQL的扩展),不会在这里显示。域的相关信息见。 + SQL 中有两种用户定义类型:结构类型(在PostgreSQL中也称为复合类型)以及独立类型(distinct type,PostgreSQL 尚未实现)。为兼顾将来,请使用列user_defined_type_category来区分它们。其他用户定义类型,如基础类型和枚举(两者都是PostgreSQL的扩展),不会在这里显示。域的相关信息见 diff --git a/zh/13/install-windows.sgml b/zh/13/install-windows.sgml index 0eb30894..b4877e89 100644 --- a/zh/13/install-windows.sgml +++ b/zh/13/install-windows.sgml @@ -4,8 +4,8 @@ 在 <productname>Windows</productname> 上从源代码安装 - installation - on Windows + 安装 + 在 Windows 上 @@ -48,8 +48,6 @@ https://docs.microsoft.com/en-us/visualstudio/releases/2019/system-requirements For 2022 requirements: https://docs.microsoft.com/en-us/visualstudio/releases/2022/system-requirements - For 2026 requirements: - https://docs.microsoft.com/en-us/visualstudio/releases/2026/vs-system-requirements --> @@ -81,7 +79,10 @@ $ENV{MSBFLAGS}="/m"; 需求 - 以下附加产品是构建 PostgreSQL 所必需的。请使用 config.pl 文件指定各个库所在的目录。 + + 构建PostgreSQL需要以下附加产品。请使用config.pl文件指定这些库所在的目录。 + + Microsoft Windows SDK @@ -101,7 +102,10 @@ $ENV{MSBFLAGS}="/m"; - 开始使用时不需要以下附加产品,但构建完整软件包时需要。请使用 config.pl 文件指定各个库所在的目录。 + + 以下附加产品并非入门所必需,但若要构建完整的软件包则需要它们。请使用config.pl文件指定这些库所在的目录。 + + Magicsplat Tcl @@ -290,7 +294,9 @@ $ENV{CONFIG}="Debug"; 有关回归测试的更多信息,参见 - vcregress bincheck 运行客户端程序的回归测试、用 vcregress recoverycheck 运行恢复测试,或用 vcregress taptest 指定并运行 TAP 测试,都需要另外安装一个 Perl 模块: + + 对客户端程序运行回归测试时使用vcregress bincheck,对恢复测试使用vcregress recoverycheck,或者运行由vcregress taptest指定的 TAP 测试时,需要额外安装一个 Perl 模块: + IPC::Run 撰写本文时,IPC::Run 既未包含在 ActiveState Perl 安装中,也未包含在 ActiveState Perl 软件包管理器(PPM)的库中。要安装它,请下载以下文件:IPC-Run-<version>.tar.gz,这是 CPAN 提供的源码归档,地址为 ,然后将其解压。编辑 buildenv.pl 文件,并添加 PERL5LIB 变量,使其指向解压后归档中的 lib 子目录。例如: @@ -301,7 +307,8 @@ $ENV{PERL5LIB}=$ENV{PERL5LIB} . ';c:\IPC-Run-0.94\lib'; - 部分 TAP 测试依赖一些外部命令,相关测试会根据这些命令是否可用而选择性触发。以下各变量都可以在 buildenv.pl 中设置或取消设置: + + 部分 TAP 测试依赖一些外部命令,相关测试会根据这些命令是否可用而选择性触发。以下各变量都可以在 buildenv.pl 中设置或取消设置: GZIP_PROGRAM diff --git a/zh/13/installation.sgml b/zh/13/installation.sgml index e2b7686c..e4e82411 100644 --- a/zh/13/installation.sgml +++ b/zh/13/installation.sgml @@ -12,7 +12,7 @@ documentation. See standalone-profile.xsl for details. 从源代码安装 - installation + 安装 @@ -37,7 +37,7 @@ su - postgres /usr/local/pgsql/bin/pg_ctl -D /usr/local/pgsql/data -l logfile start /usr/local/pgsql/bin/createdb test /usr/local/pgsql/bin/psql test -详细说明见本。 +详细说明见本的其余部分。 @@ -45,9 +45,14 @@ su - postgres 需求 - 一般来说,现代的 Unix 兼容平台应该能够运行 PostgreSQL。发布时经过具体测试的平台见下方 + + 一般来说,现代的 Unix 兼容平台都应当能够运行 + PostgreSQL。在发布时经过专门测试的平台, + 见下文 。 + - 以下软件包必须备齐,才能构建 PostgreSQL: + + 构建 PostgreSQL 需要下列软件包: @@ -129,13 +134,17 @@ su - postgres - 以下软件包是可选的。默认配置不需要它们,但启用某些构建选项时需要,具体如下: + + 下列软件包是可选的。默认配置不需要它们,但在启用某些构建选项时会用到, + 如下所述: + + 要构建服务器端编程语言 PL/Perl, 你需要一个完整的 Perl 安装, 包括 libperl 库和头文件。 - 最低要求版本是 Perl 5.14。 + 最低要求版本是 Perl 5.8.3。 由于 PL/Perl 是一个共享库,在大多数平台上, libperl libperl 也必须是共享库。这在较新的 @@ -193,11 +202,14 @@ su - postgres - 如果你希望支持使用相应服务进行身份验证,就需要 KerberosOpenLDAP 和/或 PAM + 如果你希望支持使用相应服务进行认证,就需要 KerberosOpenLDAP 和/或 PAM - 构建 PostgreSQL 文档另有一组要求;参见 + + 要构建 PostgreSQL 文档,还需要满足另一组要求; + 见 。 + @@ -245,11 +257,24 @@ su - postgres configure - 安装过程的第一步是为你的系统配置源码树,并选择所需选项。这通过运行以下脚本完成:configure。对于默认安装,只需输入: + + 安装过程的第一步,是针对你的系统配置源码树,并选择你希望使用的选项。 + 这是通过运行 configure 脚本来完成的。 + 对于默认安装,只需输入: + ./configure -此脚本会运行一系列测试,确定各个依赖系统的变量的值,并检测操作系统的特殊之处,最后在构建树中创建若干文件来记录结果。 + + 该脚本会运行一系列测试,以确定各种依赖系统的变量取值,并检测操作系统的特殊之处, + 最后在构建树中创建若干文件,记录它发现的结果。 + - 也可以运行 configure 时使用源码树之外的目录,并在该目录中构建,以将构建目录与原始源码文件分开。这种过程称为 VPATHVPATH 构建。方法如下: + + 如果你希望构建目录与原始源码文件分离,也可以在源码树外部的目录中运行 + configure,然后在那里进行构建。 + 这种过程称为 + VPATHVPATH + 构建。做法如下: + mkdir build_dir cd build_dir /path/to/source/tree/configure [options go here] @@ -278,12 +303,20 @@ su - postgres 构建 - 要开始构建,输入以下任意一条命令: + + 要开始构建,请输入以下任一命令: + make make all -(记得使用 GNU make。)构建需要几分钟,具体取决于硬件。 + + (记得使用 GNU make。) + 构建会花费几分钟时间,具体取决于你的硬件。 + - 如果要构建所有可构建的内容,包括文档(HTML 和 man 页面)及附加模块(contrib),请改为输入: + + 如果你希望构建所有可构建的内容,包括文档(HTML 和手册页)以及附加模块 + (contrib),则改为输入: + make world @@ -314,9 +347,17 @@ build-postgresql: 回归测试 - 如果希望在安装前测试刚构建的服务器,可以在此时运行回归测试。回归测试是一套测试程序,用于验证 PostgreSQL 是否在你的机器上按开发者预期的方式运行。输入: + + 如果你希望在安装之前测试新构建的服务器,可以在此时运行回归测试。 + 回归测试是一套测试,用来验证 PostgreSQL + 是否按开发者预期的方式在你的机器上运行。输入: + make check -(不能以 root 身份运行;请使用非特权用户。)参见 ,其中包含解读测试结果的详细信息。以后任何时候都可以通过执行同一命令来重复此测试。 + + (这不能以 root 身份运行;请使用非特权用户。) + 关于如何解释测试结果的详细信息,见 。 + 在以后的任何时候,你都可以再次执行同样的命令来重复此测试。 + @@ -423,7 +464,7 @@ build-postgresql: <filename>configure</filename> 选项 - 配置选项 + configure 选项 @@ -712,8 +753,8 @@ build-postgresql: - 构建时支持 GSSAPI 认证。要使用 GSSAPI,必须安装 MIT Kerberos。 - 在很多系统上,GSSAPI 系统(MIT Kerberos 安装的一部分)并不位于默认搜索的路径 + 构建时支持 GSSAPI 认证。 + 在很多系统上,GSSAPI 系统(通常是 Kerberos 安装的一部分)并不位于默认搜索的路径 中(例如 /usr/include/usr/lib), 因此除了这个选项之外,你还必须使用 configure @@ -809,7 +850,7 @@ build-postgresql: ,使用 OSSP UUID library + url="http://www.ossp.org/pkg/lib/uuid/">OSSP UUID 库 @@ -828,7 +869,10 @@ build-postgresql: - 使用 libxml2 构建,以启用 SQL/XML 支持。此功能要求 Libxml2 2.6.23 或更高版本。 + + 构建时支持 libxml2,以启用 SQL/XML 支持。 + 这一特性要求 libxml2 2.6.23 或更高版本。 + 为检测所需的编译器和链接器选项,PostgreSQL 会查询 pkg-config,前提是已安装该程序且其中有 libxml2 的信息。否则,如果找到 libxml2 安装的 xml2-config 程序,就会使用它。优先使用 pkg-config,因为它能更好地处理多架构安装。 @@ -863,7 +907,7 @@ build-postgresql: - 反功能 + 禁用特性 本节描述的选项允许禁用某些默认会构建的 @@ -1017,8 +1061,7 @@ build-postgresql: - 不在 PostgreSQL 的可执行文件中标记, - 使其在运行时到安装的库目录中搜索共享库(见 )。 + 不在 PostgreSQL 的可执行文件中添加指示其到安装的库目录中搜索共享库的标记(见 )。 在大多数平台上,这种标记使用库目录的绝对路径,因此如果你之后移动安装位置, 它就没有帮助了。不过这样一来,你就需要通过其他方式让可执行文件找到共享库。 通常这要求配置操作系统的动态链接器搜索该库目录;更多细节见 @@ -1035,7 +1078,7 @@ build-postgresql: 杂项 - 调整默认端口号 相当常见, + 使用 调整默认端口号相当常见, 尤其是在测试性构建中。本节中的其他选项只推荐给高级用户。 @@ -1073,7 +1116,7 @@ build-postgresql: 设置 段大小,单位为 GB。 大表会被分成多个操作系统文件,每个文件的大小等于段大小。 这可以避免很多平台上的文件大小限制问题。默认段大小 1GB 在所有支持的平台上 - 都是安全的。如果你的操作系统支持 largefile + 都是安全的。如果你的操作系统支持 大文件 (如今大多数都支持),你可以使用更大的段大小。 这有助于减少处理超大表时消耗的文件描述符数量。 但请注意不要选择超出你的平台和打算使用的文件系统所支持的值。 @@ -1153,11 +1196,11 @@ build-postgresql: - 在服务器中启用 assertion 检查,用于测试许多 - 不应该发生的条件。这对代码开发非常有价值,但这些测试会显著拖慢 + 在服务器中启用 断言 检查,用于测试许多 + 不可能发生的条件。这对代码开发非常有价值,但这些测试可能会显著拖慢 服务器速度。此外,启用这些测试并不一定会增强服务器稳定性! 断言检查并未按严重程度分类,因此即使某个 bug 相对无害,只要触发了断言失败, - 仍可能导致服务器重启。该选项不建议用于生产环境,但如果你在做开发工作 + 仍会导致服务器重启。该选项不建议用于生产环境,但如果你在做开发工作 或运行测试版,就应当启用它。 @@ -1202,7 +1245,7 @@ build-postgresql: 如果使用 GCC,所有程序和库都会被编译成可进行性能分析的形式。 - 后端退出时,会创建一个子目录,其中包含带有 profile 数据的 + 后端退出时,会创建一个子目录,其中包含带有性能分析数据的 gmon.out 文件。 该选项只适用于 GCC,并且仅在开发工作中使用。 @@ -1252,7 +1295,7 @@ build-postgresql: <filename>configure</filename> 环境变量 - configure environment variables + configure 环境变量 @@ -1283,7 +1326,10 @@ build-postgresql: 你也可以用 CFLAGS 覆盖默认编译器标志。 - 以下是可以通过这种方式设置的重要变量: + + 下面列出可以按这种方式设置的重要变量: + + BISON @@ -1316,7 +1362,7 @@ build-postgresql: 在使用 --with-llvm 编译时, - 用于处理源代码以内联的 clang 程序路径 + 用于处理源代码以进行内联的 clang 程序路径 @@ -1601,10 +1647,17 @@ libpq.so.2.1: cannot open shared object file: No such file or directory PostgreSQL 的使用方便得多。 - 为此,请将以下内容添加到 shell 启动文件中,例如 ~/.bash_profile(或者使用 /etc/profile,使其对所有用户生效): + + 为此,请把下面内容加到你的 shell 启动文件中,例如 + ~/.bash_profile(如果你希望影响所有用户,则用 + /etc/profile): + PATH=/usr/local/pgsql/bin:$PATH export PATH -如果使用 cshtcsh,则使用以下命令: + + 如果你使用的是 cshtcsh, + 则使用这条命令: + set path = ( /usr/local/pgsql/bin $path ) @@ -1648,17 +1701,14 @@ export MANPATH 一般来说,可以预期 PostgreSQL 能在以下 CPU 架构上工作:x86、x86_64、IA64、PowerPC、PowerPC 64、S/390、S/390x、Sparc、Sparc 64、ARM、MIPS、MIPSEL 和 PA-RISC。代码中包含对 M68K、M32R 和 VAX 的支持,但尚不清楚这些架构近期是否经过测试。对于不受支持的 CPU 类型,通常可以通过配置 来构建,但性能会很差。 + 可以预期 PostgreSQL 能在以下操作系统上工作:Linux(所有较新的发行版)、Windows(XP 及更高版本)、FreeBSD、OpenBSD、NetBSD、macOS、AIX、HP/UX 和 Solaris。其他类 Unix 系统也可能可用,但目前未在测试。大多数情况下,某个操作系统所支持的全部 CPU 架构也都可以工作。尤其是在使用较旧系统时,请查看下面的 ,看看是否有针对你的操作系统的特别说明。 + - 可以预期 PostgreSQL 能在这些操作系统的当前版本上工作: - Linux、Windows、FreeBSD、OpenBSD、NetBSD、DragonFlyBSD、macOS、Solaris - 和 illumos。其他类 Unix 系统也可能可用,但目前未在测试。 - 大多数情况下,某个操作系统所支持的全部 CPU 架构也都可以工作。 - 尤其是在使用较旧系统时,请查看下面的 - , - 看看是否有针对你的操作系统的特别说明。 + 如果你在某个平台上遇到安装问题,而根据近期构建农场的结果该平台是受支持的, + 请把问题报告到 pgsql-bugs@lists.postgresql.org。 + 如果你有兴趣把 PostgreSQL 移植到一个新平台, + 那么 pgsql-hackers@lists.postgresql.org 是合适的讨论地点。 - - 如果近期构建农场的结果表明某个平台受支持,但你在该平台上遇到安装问题,请向 pgsql-bugs@lists.postgresql.org 报告。如果你有兴趣将 PostgreSQL 移植到新平台,可以在 pgsql-hackers@lists.postgresql.org 讨论。 @@ -1720,8 +1770,12 @@ ERROR: could not load library "/opt/dbs/pgsql/lib/plperl.so": Bad address 可以使用 Cygwin 这个 Windows 上的类 Linux 环境来构建 PostgreSQL,但这种方式不如原生 Windows 构建(见 ,且如今已不再推荐在 Cygwin 下运行服务器。 - 从源码构建时,请按照 Unix 风格的安装过程操作(即 ./configure; - make 等),同时注意以下 Cygwin 特有的差异: + + 从源代码构建时,请按照 Unix 风格的安装过程(也就是 + ./configure; + make;等等)进行,但要注意下列 Cygwin 特有的差异: + + 请把路径设置成优先使用 Cygwin 的 bin 目录,而不是 Windows 工具目录。 @@ -1764,9 +1818,11 @@ ERROR: could not load library "/opt/dbs/pgsql/lib/plperl.so": Bad address - 并行回归测试(make check)可能因溢出而误报回归测试失败;溢出发生在 listen() 的待处理连接队列中,会导致连接被拒绝的错误或挂起。可以使用 make 变量 MAX_CONNECTIONS 限制连接数,方法如下: + 并行回归测试(make check)可能因 listen() 的待处理连接队列溢出而误报回归测试失败;队列溢出会导致连接被拒绝的错误或挂起。可以使用 make 变量 MAX_CONNECTIONS 限制连接数,方法如下: + make MAX_CONNECTIONS=5 check -(在某些系统上,并发连接数最高可达约 10 个。) + +(在某些系统上,并发连接数最高可达约 10 个。) @@ -1839,7 +1895,7 @@ xcrun --show-sdk-path macOS 的 - System Integrity Protection(SIP)特性会破坏 + 系统完整性保护(SIP)特性会破坏 make check,因为它会阻止把所需的 DYLD_LIBRARY_PATH 设置传递给被测试的可执行文件。 你可以通过在 make check 之前先执行 @@ -1865,7 +1921,7 @@ xcrun --show-sdk-path 安装好所有组件后,建议在 CMD.EXE 下运行 psql,因为 MSYS 控制台存在缓冲问题。 - 收集崩溃转储 + 在 Windows 上收集崩溃转储 如果 PostgreSQL 在 Windows 上崩溃,它能够生成 @@ -1907,7 +1963,7 @@ xcrun --show-sdk-path 你可以从 下载 Sun Studio。许多 GNU 工具已经集成到 Solaris 10 中, - 或者包含在 Solaris companion CD 中。如果你需要适用于较旧 Solaris 版本的 + 或者包含在 Solaris 配套光盘中。如果你需要适用于较旧 Solaris 版本的 软件包,可以到 查找这些工具。 如果你更想要源码,请看 。 @@ -1915,10 +1971,10 @@ xcrun --show-sdk-path - configure 抱怨测试程序失败 + configure 报告测试程序失败 - 如果 configure 抱怨某个测试程序失败, + 如果 configure 报告某个测试程序失败, 这多半是因为运行时链接器找不到某些库,通常是 libz、libreadline, 或其他非标准库如 libssl。要把它指向正确位置,请在 configure 命令行中设置环境变量 LDFLAGS, @@ -1957,7 +2013,9 @@ configure ... LDFLAGS="-R /usr/sfw/lib:/opt/sfw/lib:/usr/local/lib" 是的,可以使用 DTrace。更多信息见 - 如果发现链接 postgres 可执行文件时中止,并出现类似以下错误消息: + + 如果你看到在链接 postgres 可执行文件时中止,并显示如下错误: + Undefined first referenced symbol in file AbortTransaction utils/probes.o @@ -1965,7 +2023,10 @@ CommitTransaction utils/probes.o ld: fatal: Symbol referencing errors. No output written to postgres collect2: ld returned 1 exit status make: *** [postgres] Error 1 -则说明安装的 DTrace 太旧,无法处理静态函数中的探针。需要 Solaris 10u4 或更高版本才能使用 DTrace。 + + 那就说明你的 DTrace 安装太旧,无法处理静态函数中的探针。 + 你需要 Solaris 10u4 或更新版本才能使用 DTrace。 + diff --git a/zh/13/isn.sgml b/zh/13/isn.sgml index 1bc54571..b778fe65 100644 --- a/zh/13/isn.sgml +++ b/zh/13/isn.sgml @@ -1,7 +1,7 @@ - isn — 国际标准编号(ISBN、EAN、UPC 等)的数据类型 + isn isn @@ -215,53 +215,57 @@ - make_valid - make_valid ( isn ) - isn + isn_weak + isn_weak ( boolean ) + boolean - 使一个无效编号变为有效(清除无效标记)。 + 设置弱输入模式,并返回新的设置值。 - is_valid - is_valid ( isn ) + isn_weak () boolean - 检查是否存在无效标记。 + 返回弱模式的当前状态。 - isn_weak - isn_weak ( boolean ) - boolean + make_valid + make_valid ( isn ) + isn - 设置弱输入模式,并返回新的设置值。 + 将无效编号变为有效(清除无效标记)。 - isn_weak () + is_valid + is_valid ( isn ) boolean - 返回弱模式的当前状态。 + 检查是否存在无效标记。
- 模式用于将无效数据插入表中。无效是指校验位错误,而不是编号缺失。 + + 模式用于允许向表中插入无效数据。这里的“无效”指的是校验位错误,而不是缺少数字。 + - 为什么需要使用弱模式?例如,手头可能有一大批 ISBN 编号,数量多到难免会有一些编号因为某些奇怪的原因而带有错误的校验位(也许这些编号是从印刷清单扫描得到的,而 OCR 把数字识别错了;也许这些编号是人工录入的……谁知道呢)。总之,可能想把这些混乱情况清理干净,但同时仍希望先把所有编号都装入数据库,并借助外部工具在数据库中定位无效编号,以便核对信息并更容易完成校验;例如,可能会想把表中所有无效编号都查询出来。 + + 为什么会需要使用弱模式呢?例如,手头可能有一大批 ISBN 编号,数量多到难免会有一些编号因为某些奇怪的原因而带有错误的校验位(也许这些编号是从印刷清单扫描得到的,而 OCR 把数字识别错了;也许这些编号是人工录入的……谁知道呢)。总之,可能想把这些混乱情况清理干净,但同时仍希望先把所有编号都装入数据库,并借助外部工具在数据库中定位无效编号,以便核对信息并更容易完成校验;例如,可能会想把表中所有无效编号都查询出来。 + 当在弱模式下向表中插入无效编号时,实际插入的是校验位已更正的编号,但显示时会在末尾附加一个感叹号(!),例如0-11-000322-5!。可以用is_valid函数检查这个无效标记,并用make_valid函数清除它。 @@ -319,18 +323,26 @@ SELECT isbn13(id) FROM test; 参考文献 - 实现此模块所需的信息收集自多个网站,包括: + + 实现该模块所需的信息收集自若干网站,包括: + - 连字符化使用的前缀也收集自: + + + 用于进行连字符分隔的前缀还整理自: + - 在创建这些算法时十分谨慎,并根据官方 ISBN、ISMN、ISSN 用户手册中建议的算法进行了细致验证。 + + + 在创建这些算法时已十分谨慎,并依据官方 ISBN、ISMN、ISSN 用户手册中建议的算法进行了细致核验。 + diff --git a/zh/13/libpq.sgml b/zh/13/libpq.sgml index 0d60abeb..6af68ed2 100644 --- a/zh/13/libpq.sgml +++ b/zh/13/libpq.sgml @@ -33,7 +33,7 @@ 以下函数用于建立到PostgreSQL后端服务器的连接。应用程序可以同时保持多个后端连接。(这样做的原因之一是访问多个数据库。)每个连接由一个PGconnPGconn对象表示,该对象可以通过以下函数获取:,或。注意,这些函数总是返回非空的对象指针,除非内存不足,甚至无法分配PGconn对象。应调用函数检查返回值,确认连接成功后,再通过连接对象发送查询。 - 如果不可信用户能够访问一个没有采用模式的安全使用方式的数据库,那么每个会话开始时都应从search_path中移除公开可写的模式。可以把参数关键词options设置为-csearch_path=。也可以在连接后发出PQexec(conn, "SELECT pg_catalog.set_config('search_path', '', false)")。这种考虑并非专门针对libpq;它适用于每一种可执行任意 SQL 命令的接口。 + 如果不受信任的用户能够访问一个没有采用模式的安全使用方式的数据库,那么每个会话开始时都应从search_path中移除公开可写的模式。可以把参数关键词options设置为-csearch_path=。也可以在连接后发出PQexec(conn, "SELECT pg_catalog.set_config('search_path', '', false)")。这种考虑并非专门针对libpq;它适用于每一种可执行任意 SQL 命令的接口。 @@ -1602,25 +1602,30 @@ PGTransactionStatusType PQtransactionStatus(const PGconn *conn); - 查找服务器的一个当前参数设置。 + 查找服务器某个参数的当前设置。 const char *PQparameterStatus(const PGconn *conn, const char *paramName); - 某一参数值会被服务器在连接开始或值改变时自动报告。可以被用来询问这些设置。它为已知的参数返回当前值,为未知的参数返回NULL。 + 服务器会在连接启动时,以及某些参数值发生变化时,自动报告这些参数值。可用于查询这些设置。如果已知该参数,则返回其当前值;如果未知,则返回NULL - 当前版本报告的参数包括 server_versionserver_encodingclient_encodingapplication_nameis_superusersession_authorizationDateStyleIntervalStyleTimeZoneinteger_datetimesstandard_conforming_strings。(8.0 之前的版本不报告 server_encodingTimeZoneinteger_datetimes;8.1 之前的版本不报告 standard_conforming_strings;8.4 之前的版本不报告 IntervalStyle;9.0 之前的版本不报告 application_name。)注意,server_versionserver_encodinginteger_datetimes 在启动后不能改变。 + + 当前版本报告的参数包括: + server_versionserver_encodingclient_encodingapplication_nameis_superusersession_authorizationDateStyleIntervalStyleTimeZoneinteger_datetimesstandard_conforming_strings。 + (8.0 之前的版本不报告 server_encodingTimeZoneinteger_datetimes;8.1 之前的版本不报告 standard_conforming_strings;8.4 之前的版本不报告 IntervalStyle;9.0 之前的版本不报告 application_name。) + 注意,server_versionserver_encodinginteger_datetimes 在启动后不能改变。 + 使用 3.0 之前协议的服务器不报告参数设置,但 libpq 仍包含获取 server_versionclient_encoding 值的逻辑。建议应用程序使用 ,而不是专门编写代码来确定这些值。(但要注意,在使用 3.0 之前协议的连接上,连接启动后通过 SET 改变 client_encoding,不会反映在 的结果中。)对于 server_version,另请参见 ,它以数值形式返回此信息,更易于比较。 - 如果没有为standard_conforming_strings报告值,应用能假设它是off,也就是说反斜线会被视为字符串中的转义。还有,这个参数的存在可以被作为转义字符串语法(E'...')被接受的指示。 + 如果服务器未报告standard_conforming_strings的值,应用程序可以假定其为off,即反斜杠在字符串字面量中被视为转义字符。此外,服务器报告此参数也表明它接受转义字符串语法(E'...')。 - 尽管被返回的指针被声明成const,它事实上指向与PGconn结构体相关的可变存储。假定该指针在存储之间保持有效是不明智的。 + 返回的指针虽然被声明为const,但实际上指向与PGconn结构体关联的可变存储。不能假定该指针在执行其他查询后仍然有效。 @@ -1998,7 +2003,7 @@ PGresult *PQexecParams(PGconn *conn, paramTypes[] - 通过 OID 指定要赋予给参数符号的数据类型。如果paramTypesNULL或者该数组中任何特定元素为零,服务器会用对待未知类型文字串的方式为参数符号推测一种数据类型。 + 通过 OID 指定要赋予给参数符号的数据类型。如果paramTypesNULL或者该数组中任何特定元素为零,服务器会用对待未指定类型的字符串字面量的方式为参数符号推测一种数据类型。 @@ -2091,10 +2096,10 @@ PGresult *PQprepare(PGconn *conn, 该函数从query串创建一个名为stmtName的预备语句,该串必须包含一个单一 SQL 命令。 stmtName可以是""来创建一个未命名语句,在这种情况下任何已存在未命名语句将被自动替换。 - 如果语句名称已经在当前会话中被定义,则是一种错误。如果使用了任何参数,它们在查询中以$1$2等引用。 + 否则,如果语句名称已经在当前会话中被定义,则是一种错误。如果使用了任何参数,它们在查询中以$1$2等引用。 nParams是参数的个数,其类型在数组paramTypes[]中被预先指定(当nParams为零时,该数组指针可以是NULL)。 paramTypes[]通过 OID 指定要赋予给参数符号的数据类型。 - 如果paramTypesNULL或者该数组中任何特定元素为零,服务器会用对待未知类型文字串的方式为参数符号推测一种数据类型。 + 如果paramTypesNULL或者该数组中任何特定元素为零,服务器会用对待未指定类型的字符串字面量的方式为参数符号推测一种数据类型。 还有,查询能够使用编号高于nParams的参数符号,它们的数据类型也会被自动推测(找出推测出的数据类型的方法见)。 @@ -2414,7 +2419,7 @@ char *PQresultErrorField(const PGresult *res, int fieldcode); PG_DIAG_MESSAGE_DETAIL - 细节:一个可选的次级错误消息,它携带了关于问题的等多细节。可能有多行。 + 细节:一个可选的次级错误消息,它携带了关于问题的更多细节。可能有多行。 @@ -2432,7 +2437,7 @@ char *PQresultErrorField(const PGresult *res, int fieldcode); PG_DIAG_STATEMENT_POSITION - 包含一个十进制整数的字符串,它表示一个错误游标位置,该位置是原始语句字符串的索引。第一个字符的索引是 1,位置以字符计算而不是以及字节计算。 + 包含一个十进制整数的字符串,它表示一个错误游标位置,该位置是原始语句字符串的索引。第一个字符的索引是 1,位置以字符计算而不是以字节计算。 @@ -3190,8 +3195,8 @@ unsigned char *PQescapeByteaConn(PGconn *conn, - 当某些字节值被用作一个SQL语句中的bytea文字的一部分时,它们必须被转义。 - 转义使用十六进制编码或反斜线转义的字节。详见。 + 当某些字节值被用作一个SQL语句中的bytea字面量的一部分时,它们必须被转义。 + 使用十六进制编码或反斜杠转义来转义这些字节。详见 @@ -3239,7 +3244,8 @@ unsigned char *PQescapeBytea(const unsigned char *from, - 将二进制数据的一个字符串表示转换成二进制数据 — 它是的逆向函数。当检索文本格式的bytea数据时,需要这个函数,但检索二进制个事时则不需要它。 + 将二进制数据的字符串表示转换为二进制数据,这是的逆操作。 + 以文本格式取得bytea数据时需要此操作;以二进制格式取得时则不需要。 unsigned char *PQunescapeBytea(const unsigned char *from, size_t *to_length); @@ -3247,13 +3253,16 @@ unsigned char *PQunescapeBytea(const unsigned char *from, size_t *to_length); - from参数指向一个字符串,例如被应用到一个bytea列上所返回的。 - 把这个串表示转换成它的二进制表示。 - 它返回一个指向用malloc()分配的缓冲区的指针,在错误时返回NULL,并且把缓冲区的尺寸放在to_length中。 - 当结果不再需要时,它必须使用释放。 + from参数指向一个字符串,例如对bytea列调用时返回的字符串。 + 将这个字符串表示转换为二进制表示。 + 它返回指向通过malloc()分配的缓冲区的指针,出错时返回NULL,并将缓冲区大小存入to_length。 + 不再需要结果时,必须使用释放它。 - 此转换并不完全是 的逆操作,因为从 收到的字符串不应已经过转义。具体而言,这意味着无需考虑字符串引号,因此也不需要 PGconn 参数。 + + 此转换并不完全是的逆操作,因为从收到的字符串并非经过转义的形式。 + 具体而言,这意味着无需考虑字符串引号,因此也不需要PGconn参数。 + @@ -3565,7 +3574,7 @@ int PQflush(PGconn *conn); - 分块检索查询结果 + 逐行检索查询结果 libpq @@ -3743,7 +3752,7 @@ typedef struct - 要传递NULL参数到函数,将参数结构体的len字段设置为-1;isintu 字段就不相关了。(但这仅适用于使用协议 3.0 及更高版本的连接。) + 要传递NULL参数到函数,将参数结构体的len字段设置为-1isintu 字段就不相关了。(但这仅适用于使用协议 3.0 及更高版本的连接。) 如果函数返回 NULL,则将 *result_len 设为 -1,而不修改 *result_buf。(这仅适用于使用协议 3.0 及更高版本的连接;在协议 2.0 中,既不修改 *result_len,也不修改 *result_buf。) @@ -4375,7 +4384,7 @@ char *PQencryptPasswordConn(PGconn *conn, const char *passwd, const char *user, char *PQencryptPassword(const char *passwd, const char *user); - 的一个较老的已经被废弃的版本。其差别是不要求一个连接对象,并且总是用md5作为加密算法。 + 的旧版本,现已弃用。其差别是不需要连接对象,并且总是用md5作为加密算法。 @@ -4395,11 +4404,12 @@ PGresult *PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status); 这是libpq内部用于分配并初始化一个空PGresult对象的函数。 - 如果不能分配内存,那么这个函数返回NULL。 - 它也是可以对外使用的,因为一些应用认为它可以用于产生结果对象(特别是带有错误状态的对象)本身。 - 如果conn非空,并且status表示一个错误,那么指定连接的当前错误消息会被复制到PGresult中。 - 如果conn非空,那么连接中的任何已注册事件过程也会被复制到PGresult中(它们不会获得PGEVT_RESULTCREATE调用,但会看到)。 - 注意在该对象上最终应该调用,正如对libpq本身返回的PGresult对象所作的那样。 + 如果无法分配内存,此函数返回NULL。 + 将它导出供外部调用,是因为一些应用需要自行生成结果对象,特别是带有错误状态的对象。 + 如果conn非空,并且status表示错误,指定连接的当前错误消息会被复制到PGresult中。 + 此外,如果conn非空,连接中注册的所有事件过程也会被复制到PGresult中。 + (这些过程不会收到PGEVT_RESULTCREATE调用,但可参见。) + 注意,最终应对该对象调用,就像处理libpq自身返回的PGresult一样。 @@ -4726,13 +4736,25 @@ typedef struct PGEVT_RESULTCREATE - 任何生成结果的查询执行函数都会触发结果创建事件,其中包括。只有成功创建结果后才会触发该事件。 + + 任何生成结果的查询执行函数都会触发结果创建事件,其中包括。 + 只有成功创建结果后才会触发该事件。 + + typedef struct { PGconn *conn; PGresult *result; } PGEventResultCreate; -收到PGEVT_RESULTCREATE事件时,应将evtInfo指针强制转换为PGEventResultCreate *。其中,conn是用于生成结果的连接。这是初始化需要与结果关联的instanceData的理想位置。如果事件处理函数失败,结果会被清除,失败也会向外传递。事件处理函数不得自行调用来清除结果对象。返回失败代码时,必须完成所有清理工作,因为不会发送PGEVT_RESULTDESTROY事件。 + + + 收到PGEVT_RESULTCREATE事件时,应将evtInfo指针转换为PGEventResultCreate *。 + 其中,conn是用于生成结果的连接。 + 这是初始化需要与结果关联的instanceData的理想位置。 + 如果事件过程失败,结果会被清除,失败也会向外传递。 + 事件过程不得自行调用来清除结果对象。 + 返回失败代码时,必须完成所有清理工作,因为不会发送PGEVT_RESULTDESTROY事件。 + @@ -5438,13 +5460,8 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough) - 用户的主目录中的文件.pgpass可以包含密码, - 如果连接需要密码(且未指定其他密码)。在Microsoft Windows中, - 该文件的名称为%APPDATA%\postgresql\pgpass.conf - (其中%APPDATA%指用户配置文件中的应用数据子目录)。 - 或者,可以使用连接参数 - 或环境变量PGPASSFILE指定要使用的密码文件。 - + 用户主目录中的.pgpass文件可保存密码,供连接需要密码且尚未通过其他方式指定密码时使用。在 Microsoft Windows 上,文件名为%APPDATA%\postgresql\pgpass.conf(其中%APPDATA%指用户配置文件中的应用数据子目录)。也可以通过连接参数或环境变量PGPASSFILE指定要使用的密码文件。 + 该文件中的行应采用以下格式: hostname:port:database:username:password @@ -5833,7 +5850,7 @@ ldap://ldap.acme.com/cn=dbserver,cn=hosts?pgconnectinfo?base?(objectclass=*) 构建时带有SSL支持,您应该调用告诉libpq libssl和/或libcrypto库已被您的应用程序初始化,以便 libpq不会再初始化这些库。 - 但是,当使用OpenSSL版本1.1.0或更高版本时,重复初始化不再成问题。 + 但是,当使用OpenSSL版本1.1.0或更高版本时,无需这样做,因为重复初始化不再成问题。 @@ -5857,7 +5874,7 @@ void PQinitOpenSSL(int do_ssl, int do_crypto); - 如果你的应用使用并且初始化OpenSSL或者它的底层libcrypto库,你必须在第一次打开数据库连接前以合适的非零参数调用这个函数。 + 如果你的应用使用并且初始化OpenSSL或者它的底层libcrypto库,你必须在第一次打开数据库连接前调用这个函数,并把相应参数设为零。 同时要确保在打开一个数据库连接前已经完成了初始化。 @@ -5895,8 +5912,8 @@ void PQinitSSL(int do_ssl); 在线程化程序中的行为 - threads - with libpq + 线程 + 用于 libpq libpq 默认是可重入且线程安全的。编译应用程序代码时,可能需要使用特殊的编译器命令行选项。有关如何构建支持线程的应用程序,请参阅系统文档,或查看 src/Makefile.global 中的 PTHREAD_CFLAGSPTHREAD_LIBS。以下函数可用于查询 libpq 的线程安全状态: @@ -5914,7 +5931,7 @@ int PQisthreadsafe(); - 如果libpq是线程安全的则返回 1,否则返回 0。在版本 17 及以上始终返回 1。 + 如果libpq是线程安全的则返回 1,否则返回 0。 diff --git a/zh/13/logical-replication.sgml b/zh/13/logical-replication.sgml index d5fc907b..aeb1dcd7 100644 --- a/zh/13/logical-replication.sgml +++ b/zh/13/logical-replication.sgml @@ -201,7 +201,12 @@ - 数据库模式和DDL命令不会被复制。初始模式可使用pg_dump --schema-only手动复制。后续的模式变更需要手动保持同步。(注意,两端的模式不需要完全相同。)当数据库模式在运行中发生变更时,逻辑复制是健壮的:当发布端模式变更后,复制的数据开始到达订阅端但不符合表的模式时,复制会出错,直到模式被更新。在很多情况下,通过先在订阅端应用增量式模式变更,可以避免间歇性错误。 + 数据库模式和 DDL 命令不会被复制。初始模式可以手工使用 + pg_dump --schema-only 复制。之后的模式更改需要手工保持同步。 + (不过请注意,两端的模式其实不需要绝对一致。)当活动数据库中的模式定义发生变化时, + 逻辑复制仍然能够稳健运行:如果发布端修改了模式,而复制数据开始到达订阅端时 + 与表模式不匹配,复制就会报错,直到模式被更新。在很多情况下,可以通过先在订阅端 + 应用仅添加内容的模式变更来避免间歇性错误。 @@ -245,15 +250,15 @@ - 逻辑复制采用类似于物理流复制的架构(见)。它由walsenderapply进程实现。walsender 进程启动 WAL 的逻辑解码(见),并加载标准逻辑解码输出插件(pgoutput)。该插件将从 WAL 读取的变更转换为逻辑复制协议(见),并根据发布规范过滤数据。然后使用流复制协议将数据持续传输给 apply 工作进程,该工作进程将数据映射到本地表,并按正确的事务顺序逐一应用每个变更。 + 逻辑复制采用类似于物理流复制的架构(见)。它由walsenderapply进程实现。walsender 进程启动 WAL 的逻辑解码(见),并加载标准逻辑解码输出插件(pgoutput)。该插件将从 WAL 读取的变更转换为逻辑复制协议(见),并根据发布规范过滤数据。然后使用流复制协议将数据持续传输给 应用工作进程,该工作进程将数据映射到本地表,并按正确的事务顺序逐一应用每个变更。 - 订阅端数据库上的 apply 进程总是在session_replication_role设置为replica的情况下运行。这意味着默认情况下,触发器和规则不会在订阅端触发。用户可以选择使用ALTER TABLE命令和ENABLE TRIGGERENABLE RULE子句在表上启用触发器和规则。 + 订阅端数据库上的 应用进程总是在session_replication_role设置为replica的情况下运行。这意味着默认情况下,触发器和规则不会在订阅端触发。用户可以选择使用ALTER TABLE命令和ENABLE TRIGGERENABLE RULE子句在表上启用触发器和规则。 - 逻辑复制的apply进程目前只触发行触发器,不触发语句触发器。但初始表同步的实现方式类似于COPY命令,因此会触发INSERT的行触发器和语句触发器。 + 逻辑复制的应用进程目前只触发行触发器,不触发语句触发器。但初始表同步的实现方式类似于COPY命令,因此会触发INSERT的行触发器和语句触发器。 @@ -276,7 +281,7 @@ - 正常情况下,已启用的订阅会有一个apply进程在运行。被禁用或已崩溃的订阅在此视图中将有零行。如果任何表的初始数据同步正在进行中,将有额外的工作进程用于正在同步的表。 + 正常情况下,已启用的订阅会有一个应用进程在运行。被禁用或已崩溃的订阅在此视图中将有零行。如果任何表的初始数据同步正在进行中,将有额外的工作进程用于正在同步的表。 @@ -308,7 +313,7 @@ - 订阅的apply进程将以超级用户的权限在本地数据库上运行。 + 订阅应用进程将以超级用户的权限在本地数据库中运行。 diff --git a/zh/13/maintenance.sgml b/zh/13/maintenance.sgml index edfbc058..a1a3f1f9 100644 --- a/zh/13/maintenance.sgml +++ b/zh/13/maintenance.sgml @@ -397,12 +397,9 @@ SELECT datname, age(datfrozenxid) FROM pg_database; - 虽然 VACUUM 主要扫描自上次清理以来被修改过的页面, - 但它也可能为了冻结它们而积极扫描某些全部可见但未全部冻结的页面; - 不过,只有当表中每一个可能包含未冻结 XID 的页面都被扫描时, - relfrozenxid 才会被推进。当 - relfrozenxid 比 - vacuum_freeze_table_age 旧、使用了 VACUUM 的 + VACUUM通常只扫描自上次清理以来被修改过的页面,但只有当表中每一个可能包含未冻结 XID 的页面都被扫描时, + relfrozenxid 才会被推进。当 + relfrozenxid的年龄超过vacuum_freeze_table_age个事务、使用了 VACUUMFREEZE 选项,或者所有尚未全部冻结的页面碰巧都需要清理以移除死行版本时, 就会发生这种情况。当 VACUUM 扫描了表中每个尚未全部冻结的页面时, 它应把 age(relfrozenxid) 设为略高于所用 @@ -436,22 +433,22 @@ HINT: Stop the postmaster and vacuum that database in single-user mode. 多事务(multitransaction,MultiXact) ID 用于支持多个事务对行加锁。由于元组头中用于存储锁信息的空间有限, 当有多个事务同时锁定一行时,这些信息会被编码为一个多事务 ID, - 简称 multixact ID。某个特定 multixact ID 包含哪些事务 ID 的信息, + 简称 multixact ID。某个特定 多事务 ID 包含哪些事务 ID 的信息, 会单独存放在 pg_multixact 子目录中,而元组头的 - xmax 字段中只出现 multixact ID。和事务 ID 一样, - multixact ID 也是以 32 位计数器及其对应存储实现的,因此同样需要仔细处理老化管理、 - 存储清理和回卷问题。还有一个单独的存储区域保存每个 multixact 的成员列表, + xmax 字段中只出现 多事务 ID。和事务 ID 一样, + 多事务 ID 也是以 32 位计数器及其对应存储实现的,因此同样需要仔细处理老化管理、 + 存储清理和回卷问题。还有一个单独的存储区域保存每个 多事务 的成员列表, 它也使用 32 位计数器,因此同样必须被管理。 中介绍的系统函数 pg_get_multixact_members() - 可用于检查与某个 multixact ID 关联的事务 ID。 + 可用于检查与某个 多事务 ID 关联的事务 ID。 每当 VACUUM 扫描表的任何部分时,它都会把遇到的、早于 - 的任何 multixact ID 替换为另一个值,该值可能是零值、单个事务 ID,或者更新的 multixact ID。 + 的任何 多事务 ID 替换为另一个值,该值可能是零值、单个事务 ID,或者更新的 多事务 ID。 对于每个表,pg_class.relminmxid - 保存该表任何元组中仍可能出现的最老 multixact ID。如果这个值早于 + 保存该表任何元组中仍可能出现的最老 多事务 ID。如果这个值早于 ,就会强制执行一次激进扫描。 正如上一节所述,激进扫描意味着只有那些已知为全部冻结的页面才会被跳过。 可以对 pg_class.relminmxid @@ -460,10 +457,10 @@ HINT: Stop the postmaster and vacuum that database in single-user mode. 无论出于何种原因而发生,激进的 VACUUM 扫描都能推进该表的值。最终,随着所有数据库中的所有表都被扫描, - 并推进其最老的 multixact 值,较老 multixact 的磁盘存储就可以被移除。 + 并推进其最老的 多事务 值,较老 多事务 的磁盘存储就可以被移除。 - 作为一项安全措施,对于 multixact 年龄大于 的任何表,都会执行激进清理扫描。如果已使用的成员存储空间超过可寻址存储空间的 50%,还会从 multixact 年龄最大的表开始,逐步对所有表执行激进清理扫描。即使名义上禁用了自动清理,这两类激进扫描也都会发生。 + 作为一项安全措施,对于 多事务 年龄大于 的任何表,都会执行激进清理扫描。如果已使用的成员存储空间超过可寻址存储空间的 50%,还会从 多事务 年龄最大的表开始,逐步对所有表执行激进清理扫描。即使名义上禁用了自动清理,这两类激进扫描也都会发生。 @@ -703,7 +700,7 @@ pg_ctl start | rotatelogs /var/log/pgsql_log 86400 不过,在很多系统上,syslog 并不十分可靠, 尤其是在日志消息很大时;它可能恰恰在你最需要消息的时候截断或丢弃它们。 此外,在 Linux 上, - syslog 会把每条消息都刷新到磁盘,导致性能较差。 + syslog 会把每条消息都刷盘,导致性能较差。 (你可以在 syslog 配置文件的文件名开头使用一个 - 来禁用同步。) diff --git a/zh/13/monitoring.sgml b/zh/13/monitoring.sgml index 4ec8c701..b634ce44 100644 --- a/zh/13/monitoring.sgml +++ b/zh/13/monitoring.sgml @@ -47,7 +47,9 @@ postgres 15610 0.0 0.0 58772 3056 ? Ss 18:07 0:00 postgres: tgl postgres: user database host activity 在客户端连接的整个生命周期内,用户、数据库和(客户端)主机这几项保持不变,但活动指示符会改变。活动可以是idle(即等待客户端命令)、idle in transaction(在BEGIN块内等待客户端),或者命令类型名称,例如SELECT。此外,服务器进程当前若正在等待另一会话持有的锁,还会附加waiting。在上面的示例中,可以推断进程 15606 正在等待进程 15610 完成事务,从而释放某个锁。(进程 15610 必定是阻塞者,因为不存在其他活动会话。在更复杂的情况下,必须查看pg_locks系统视图,才能确定谁在阻塞谁。) - 如果已配置,集簇名称也会显示在ps的输出中: + + 如果配置了,则集簇名称也会显示在ps输出中: + $ psql -c 'SHOW cluster_name' cluster_name -------------- @@ -76,14 +78,14 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 统计收集器 - statistics + 统计信息 PostgreSQL统计收集器是一个支持收集和报告服务器活动信息的子系统。 - 目前,对表和索引的访问以磁盘块和单个行的术语进行计数。每个表中的总行数, - 以及每个表的清理和分析操作的信息也被计数。如果启用,对用户定义函数的调用 - 和每个函数中花费的总时间也会被计数。 + 目前,对表和索引的访问分别以磁盘块和单行计数。每个表中的总行数, + 以及每个表的清理和分析操作的信息也被计数。它还可以统计对用户定义函数的调用 + 和每个函数中花费的总时间。 @@ -140,7 +142,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - 另一个重要点是,当要求服务器进程显示这些统计信息中的任何一种时,它会先取回收集器进程最近发出的报告,然后在当前事务结束之前,对所有统计视图和函数一直使用这一快照。因此,只要你继续当前事务,统计信息就会显示静态信息。类似地,在事务中第一次请求任意当前会话的查询信息时,就会收集所有会话当前查询的信息,并且在整个事务期间显示的都是同一份信息。这是一个特性,而不是一个错误,因为它允许你对统计信息执行多个查询并对结果做关联,而不必担心数字在你眼前变化。但如果希望每个查询都看到新的结果,请确保在任何事务块之外执行这些查询。或者,也可以调用pg_stat_clear_snapshot(),它会丢弃当前事务的统计快照(如果有)。下一次使用统计信息时,就会获取一个新的快照。 + 另一个重要点是,当要求服务器进程显示这些统计信息中的任何一种时,它会先取回收集器进程最近发出的报告,然后在当前事务结束之前,对所有统计视图和函数一直使用这一快照。因此,只要你继续当前事务,统计信息就会显示静态信息。类似地,在事务中第一次请求这类当前查询信息时,就会收集所有会话当前查询的信息,并且在整个事务期间显示的都是同一份信息。这是一个特性,而不是一个错误,因为它允许你对统计信息执行多个查询并对结果做关联,而不必担心数字在你眼前变化。但如果希望每个查询都看到新的结果,请确保在任何事务块之外执行这些查询。或者,也可以调用pg_stat_clear_snapshot(),它会丢弃当前事务的统计快照(如果有)。下一次使用统计信息时,就会获取一个新的快照。 @@ -152,12 +154,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 相反,它们在事务期间持续更新。 - - 动态统计视图中显示的一些信息在中受到安全限制。 - 普通用户只能查看关于他们自己会话的所有信息(属于他们是成员的角色的会话)。在关于其他会话的行中,许多列将为空。 - 但是,请注意,所有用户都可以看到会话的存在及其一般属性,例如会话用户和数据库。超级用户以及内置角色pg_read_all_stats的成员(另请参阅)可以查看所有会话的全部信息。 - + 所列动态统计视图中的一些信息受到安全限制。普通用户只能查看其自身会话的全部信息(包括属于其所加入角色的会话)。对于其他会话的行,许多列将为空值。不过,会话的存在及其一般属性(例如会话用户和数据库)对所有用户都可见。超级用户和内置角色pg_read_all_stats的成员(另请参阅)可以查看所有会话的全部信息。 动态统计视图 @@ -190,7 +187,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser pg_stat_wal_receiverpg_stat_wal_receiver - 只有一行,显示有关 WAL 接收进程从其连接服务器接收到的统计信息。有关详细信息,请参阅pg_stat_wal_receiver。 + 只有一行,显示 WAL 接收进程从其所连接服务器接收数据的统计信息。有关详细信息,请参阅pg_stat_wal_receiver @@ -259,30 +256,31 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser + pg_stat_archiverpg_stat_archiver 只有一行,显示有关 WAL 归档进程活动的信息。有关详细信息,请参阅pg_stat_archiver - + pg_stat_bgwriterpg_stat_bgwriter 只有一行,显示有关后台写入器活动的信息。有关详细信息,请参阅pg_stat_bgwriter - + pg_stat_databasepg_stat_database 每个数据库一行,显示数据库范围的统计信息。有关详细信息,请参阅pg_stat_database - + pg_stat_database_conflictspg_stat_database_conflicts 每个数据库一行,显示数据库范围内因备库上的恢复冲突而导致查询被取消的统计信息。有关详细信息,请参阅pg_stat_database_conflicts - + pg_stat_all_tablespg_stat_all_tables 当前数据库中每个表一行,显示有关访问指定表的统计信息。详见 @@ -290,102 +288,102 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - + pg_stat_sys_tablespg_stat_sys_tables pg_stat_all_tables一样,但只显示系统表。 - + pg_stat_user_tablespg_stat_user_tables pg_stat_all_tables一样,但只显示用户表。 - + pg_stat_xact_all_tablespg_stat_xact_all_tables - pg_stat_all_tables相似,但计数动作只在当前事务内发生(还没有被包括在pg_stat_all_tables和相关视图中)。用于生存和死亡行数量的列以及清理和分析动作在此视图中不出现。 + pg_stat_all_tables 相似,但只统计当前事务中截至目前执行的操作(这些操作尚计入 pg_stat_all_tables 及相关视图)。此视图不包含存活行和死行数量以及清理、分析操作的列。 - + pg_stat_xact_sys_tablespg_stat_xact_sys_tables pg_stat_xact_all_tables一样,但只显示系统表。 - + pg_stat_xact_user_tablespg_stat_xact_user_tables pg_stat_xact_all_tables一样,但只显示用户表。 - + pg_stat_all_indexespg_stat_all_indexes 当前数据库中的每个索引一行,显示有关访问该特定索引的统计信息。有关详细信息,请参阅pg_stat_all_indexes - + pg_stat_sys_indexespg_stat_sys_indexes pg_stat_all_indexes一样,但只显示系统表上的索引。 - + pg_stat_user_indexespg_stat_user_indexes pg_stat_all_indexes一样,但只显示用户表上的索引。 - + pg_statio_all_tablespg_statio_all_tables 当前数据库中的每个表一行,显示有关访问该特定表的 I/O 统计信息。有关详细信息,请参阅pg_statio_all_tables - + pg_statio_sys_tablespg_statio_sys_tables pg_statio_all_tables一样,但只显示系统表。 - + pg_statio_user_tablespg_statio_user_tables pg_statio_all_tables一样,但只显示用户表。 - + pg_statio_all_indexespg_statio_all_indexes 当前数据库中的每个索引一行,显示有关访问该特定索引的 I/O 统计信息。有关详细信息,请参阅pg_statio_all_indexes - + pg_statio_sys_indexespg_statio_sys_indexes pg_statio_all_indexes一样,但只显示系统表上的索引。 - + pg_statio_user_indexespg_statio_user_indexes pg_statio_all_indexes一样,但只显示用户表上的索引。 - + pg_statio_all_sequencespg_statio_all_sequences 当前数据库中的每个序列一行,显示有关访问该特定序列的 I/O 统计信息。有关详细信息,请参阅pg_statio_all_sequences - + pg_statio_sys_sequencespg_statio_sys_sequences pg_statio_all_sequences一样,但只显示系统序列(目前没有定义系统序列,因此这个视图总是为空)。 - + pg_statio_user_sequencespg_statio_user_sequences pg_statio_all_sequences一样,但只显示用户序列。 - + pg_stat_user_functionspg_stat_user_functions 每个被跟踪的函数一行,显示有关该函数执行的统计信息。有关详细信息,请参阅pg_stat_user_functions - + pg_stat_xact_user_functionspg_stat_xact_user_functions pg_stat_user_functions相似,但是只统计在当前事务期间的调用(还没有被包括在pg_stat_user_functions中)。 - + pg_stat_slrupg_stat_slru 每个 SLRU 一行,显示操作统计信息。有关详细信息,请参阅pg_stat_slru @@ -468,7 +466,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser leader_pid integer - 如果该进程是并行查询工作进程,则为并行组领导者的进程 ID;如果该进程是并行应用工作进程,则为领导应用工作进程的进程 ID。NULL 表示该进程是并行组领导者或领导应用工作进程,或者不参与任何并行操作。 + 如果此进程是并行查询工作进程,则为并行组领导者的进程 ID。如果此进程是并行组领导者或者不参与并行查询,则为NULL @@ -504,7 +502,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser client_addr inet - 连接到这个后端的客户端的 IP 地址。如果这个字段为空,它表示客户端通过服务器机器上的一个 Unix 套接字连接或者这是一个内部进程,如自动清理。 + 连接到这个后端的客户端的 IP 地址。如果这个字段为空值,它表示客户端通过服务器机器上的一个 Unix 套接字连接或者这是一个内部进程,如自动清理。 @@ -523,7 +521,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser client_port integer - 客户端用于与此后端通信的TCP端口号,如果使用Unix套接字,则为-1。如果该字段为空,它表示这是一个内部服务器进程。 + 客户端用于与此后端通信的TCP端口号,如果使用Unix套接字,则为-1。如果该字段为空值,它表示这是一个内部服务器进程。 @@ -541,8 +539,8 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser xact_start timestamp with time zone - 这个进程的当前事务被启动的时间,如果没有活动事务则为空。 - 如果当前查询是它的第一个事务,这一列等于query_start列。 + 这个进程的当前事务被启动的时间,如果没有活动事务则为空值。 + 如果当前查询是其事务中的第一个查询,这一列等于query_start列。 @@ -569,7 +567,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser wait_event_type text - 后端正在等待的事件类型(如果有);否则为NULL。请参阅。 + 后端正在等待的事件类型(如果有);否则为空值。请参阅 @@ -578,7 +576,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser wait_event text - 如果此后端当前正在等待,则返回等待事件名称,否则为NULL。请参阅。 + 如果此后端当前正在等待,则返回等待事件名称,否则为空值。请参阅 @@ -623,7 +621,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser backend_xmin xid - 当前后端的xmin范围。 + 当前后端的xmin视界。 @@ -641,17 +639,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser backend_type text - - 当前后端的类型。可能的类型为 - autovacuum launcher, autovacuum worker, - logical replication launcher, - logical replication worker, - parallel worker, background writer, - client backend, checkpointer, - startup, walreceiver, - walsenderwalwriter。 - 此外,由扩展注册的后台工作进程还可能有额外的类型。 - + 当前后端的类型。可能的类型为autovacuum launcherautovacuum workerlogical replication launcherlogical replication workerparallel workerbackground writerclient backendcheckpointerstartupwalreceiverwalsenderwalwriter。此外,由扩展注册的后台工作进程还可能有额外的类型。 @@ -683,10 +671,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser BufferPin - 服务器进程正在等待对数据缓冲的独占访问。 - 如果另一个进程持有一个打开的游标,该游标最后一次从相关缓冲区读取数据,则缓冲区销等待可能是漫长的。 - 参见。 - + 服务器进程正在等待独占访问一个数据缓冲区。如果另一个进程持有尚未关闭的游标,且该游标最近读取的数据来自此缓冲区,缓冲区钉住等待就可能持续较长时间。参见 Client @@ -701,7 +686,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser IO - 服务器进程正在等待一个I/O操作完成。wait_event将识别特定的等待点;参见。 + 服务器进程正在等待一个 I/O 操作完成。wait_event将识别特定的等待点;参见 @@ -711,16 +696,13 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser Lock - 服务器进程正在等待一个重量级锁。重量级锁,也称为锁管理器锁或简单锁,主要保护表等SQL可见对象。 + 服务器进程正在等待一个重量级锁。重量级锁,也称为锁管理器锁或简称为锁,主要保护表等SQL可见对象。 然而,它们也用于确保某些内部操作的互斥,例如关系扩展。wait_event将识别等待的锁的类型;参见 LWLock - 服务器进程正在等待一个轻量级锁。大多数这样的锁保护共享内存中的特定数据结构。 - wait_event将包含标识轻量级锁用途的名称。 - (有些锁有特定的名称;其他锁是一组锁的一部分,每个锁具有类似的目的。)参见。 - + 服务器进程正在等待一个轻量级锁。大多数这样的锁保护共享内存中的某个特定数据结构。wait_event将包含标识该轻量级锁用途的名称。(有些锁具有专门的名称,另一些锁属于一组用途相似的锁。)参见 Timeout @@ -749,11 +731,11 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser AutoVacuumMain - 在自动清理启动过程的主循环中等待。 + 在自动清理启动进程的主循环中等待。 BgWriterHibernate - 在后台写入器中等待,休眠状态。 + 在后台写入器进程中休眠等待。 BgWriterMain @@ -773,11 +755,11 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser PgStatMain - 流恢复期间,在启动进程主循环等待WAL到达。 + 在统计收集器进程的主循环中等待。 RecoveryWalStream - 流恢复期间,在启动进程主循环等待WAL到达。 + 在流恢复期间,在启动进程的主循环中等待 WAL 到达。 SysLoggerMain @@ -785,7 +767,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser WalReceiverMain - 在WAL 接收进程的主循环中等待。 + 在 WAL 接收进程的主循环中等待。 WalSenderMain @@ -793,7 +775,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser WalWriterMain - 在WAL写入进程的主循环中等待。 + 在 WAL 写入进程的主循环中等待。 @@ -815,7 +797,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser BufferPin - 等待获得缓冲区上的独占销。 + 等待获得缓冲区上的独占钉住。 @@ -847,11 +829,11 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser LibPQWalReceiverConnect - 在WAL 接收进程等待与远程服务器建立连接。 + 在 WAL 接收进程中等待与远程服务器建立连接。 LibPQWalReceiverReceive - 在WAL 接收进程中等待从远程服务器接收数据。 + 在 WAL 接收进程中等待从远程服务器接收数据。 SSLOpenServer @@ -863,7 +845,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser WalSenderWaitForWAL - 在 WAL 发送进程中等待 WAL 被刷新。 + 在 WAL 发送进程中等待 WAL 刷盘。 WalSenderWriteData @@ -921,11 +903,11 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser ControlFileSync - 等待pg_control文件到达持久存储。 + 等待 pg_control 文件同步到持久存储。 ControlFileSyncUpdate - 等待更新pg_control文件以达到持久存储。 + 等待对 pg_control 文件的更新同步到持久存储。 ControlFileWrite @@ -933,7 +915,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser ControlFileWriteUpdate - 等待写入更新pg_control文件。 + 等待写入以更新 pg_control 文件。 CopyFileRead @@ -941,11 +923,11 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser CopyFileWrite - 在文件拷贝操作期间等待写入。 + 在文件复制操作期间等待写入。 DSMFillZeroWrite - 等待用零填充动态共享内存备份(backing)文件。 + 等待用零填充动态共享内存的后备文件。 DataFileExtend @@ -953,11 +935,11 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser DataFileFlush - 等待关系数据文件达到持久存储。 + 等待关系数据文件同步到持久存储。 DataFileImmediateSync - 等待关系数据文件到持久存储的立即同步。 + 等待关系数据文件立即同步到持久存储。 DataFilePrefetch @@ -969,7 +951,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser DataFileSync - 等待对关系数据文件的更改达到持久存储。 + 等待对关系数据文件的更改同步到持久存储。 DataFileTruncate @@ -985,7 +967,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser LockFileAddToDataDirSync - 等待数据到达持久存储,同时向数据目录锁文件添加一行。 + 在向数据目录锁文件中添加一行时,等待数据同步到持久存储。 LockFileAddToDataDirWrite @@ -997,7 +979,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser LockFileCreateSync - 在创建数据目录锁文件时等待数据到达持久存储。 + 在创建数据目录锁文件时,等待数据同步到持久存储。 LockFileCreateWrite @@ -1009,11 +991,11 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser LogicalRewriteCheckpointSync - 等待逻辑重写映射到在检查点到达持久存储。 + 在检查点期间等待逻辑重写映射同步到持久存储。 LogicalRewriteMappingSync - 在逻辑重写期间等待映射数据到达持久存储 + 在逻辑重写期间等待映射数据同步到持久存储。 LogicalRewriteMappingWrite @@ -1021,11 +1003,11 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser LogicalRewriteSync - 等待逻辑重写映射到达持久存储。 + 等待逻辑重写映射同步到持久存储。 LogicalRewriteTruncate - 等待在逻辑重写期间截断映射数据。 + 在逻辑重写期间等待截断映射数据。 LogicalRewriteWrite @@ -1037,7 +1019,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser RelationMapSync - 等待关系映射文件到达持久存储。 + 等待关系映射文件同步到持久存储。 RelationMapWrite @@ -1045,15 +1027,15 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser ReorderBufferRead - 在重新排序缓冲区管理期间等待读取。 + 在重排序缓冲区管理期间等待读取。 ReorderBufferWrite - 在重新排序缓冲区管理期间等待写操作。 + 在重排序缓冲区管理期间等待写入。 ReorderLogicalMappingRead - 在重新排序缓冲区管理期间等待读取逻辑映射。 + 在重排序缓冲区管理期间等待读取逻辑映射。 ReplicationSlotRead @@ -1061,11 +1043,11 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser ReplicationSlotRestoreSync - 等待复制槽控制文件到达持久存储,同时将其恢复到内存中。 + 在将复制槽控制文件恢复到内存期间,等待该文件同步到持久存储。 ReplicationSlotSync - 等待复制槽控制文件到达持久存储。 + 等待复制槽控制文件同步到持久存储。 ReplicationSlotWrite @@ -1073,7 +1055,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser SLRUFlushSync - 在检查点或数据库关闭期间等待SLRU数据到达持久存储。 + 在检查点或数据库关闭期间,等待 SLRU 数据同步到持久存储。 SLRURead @@ -1081,7 +1063,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser SLRUSync - 在写页面后等待SLRU数据到达持久存储。 + 在页面写入后等待 SLRU 数据同步到持久存储。 SLRUWrite @@ -1089,19 +1071,19 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser SnapbuildRead - 等待读取序列化的历史目录快照。 + 等待读取序列化的历史系统目录快照。 SnapbuildSync - 等待序列化历史目录快照到达持久存储。 + 等待序列化的历史系统目录快照同步到持久存储。 SnapbuildWrite - 等待串行历史目录快照的写入。 + 等待写入序列化的历史系统目录快照。 TimelineHistoryFileSync - 等待通过流复制接收的时间线历史文件到达持久存储。 + 等待通过流复制接收的时间线历史文件同步到持久存储。 TimelineHistoryFileWrite @@ -1113,7 +1095,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser TimelineHistorySync - 等待新创建的时间线历史文件到达持久存储。 + 等待新创建的时间线历史文件同步到持久存储。 TimelineHistoryWrite @@ -1125,7 +1107,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser TwophaseFileSync - 等待两阶段状态文件到达持久存储。 + 等待两阶段状态文件同步到持久存储。 TwophaseFileWrite @@ -1133,7 +1115,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser WALBootstrapSync - 在引导过程中等待WAL达到持久存储。 + 在引导过程中等待 WAL 同步到持久存储。 WALBootstrapWrite @@ -1145,7 +1127,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser WALCopySync - 等待通过复制一个已有WAL段到持久存储来创建一个新的WAL段。 + 等待通过复制现有 WAL 段创建的新 WAL 段同步到持久存储。 WALCopyWrite @@ -1153,7 +1135,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser WALInitSync - 等待一个新初始化的WAL文件到持久存储。 + 等待新初始化的 WAL 文件同步到持久存储。 WALInitWrite @@ -1165,19 +1147,19 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser WALSenderTimelineHistoryRead - 在walsender时间线命令期间等待从时间线历史文件读取。 + 在 WAL 发送进程执行时间线命令期间,等待从时间线历史文件读取。 WALSync - 等待WAL文件到达持久存储。 + 等待 WAL 文件同步到持久存储。 WALSyncMethodAssign - 等待数据到达持久存储,同时分配一个新的WAL同步方法。 + 在设置新的 WAL 同步方法时,等待数据同步到持久存储。 WALWrite - 等待写入WAL文件。 + 等待写入 WAL 文件。 @@ -1209,7 +1191,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser BtreePage - 正等待继续并行B-树扫描所需的页号变得可用。 + 等待继续并行 B-树扫描所需的页号变得可用。 CheckpointDone @@ -1221,67 +1203,67 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser ExecuteGather - 在执行Gather 计划节点时,等待子进程的活动。 + 在执行 Gather 计划节点时,等待子进程的活动。 HashBatchAllocate - 等待一个选定的并行哈希参与者分配哈希表。 + 等待选出的 Parallel Hash 参与者分配哈希表。 HashBatchElect - 等待选择一个并行哈希参与者来分配哈希表。 + 等待选出负责分配哈希表的 Parallel Hash 参与者。 HashBatchLoad - 等待其他并行哈希参与者完成哈希表的加载。 + 等待其他 Parallel Hash 参与者完成哈希表的加载。 HashBuildAllocate - 等待一个选定的并行哈希参与者分配初始哈希表。 + 等待选出的 Parallel Hash 参与者分配初始哈希表。 HashBuildElect - 等待选择一个并行哈希参与者来分配初始哈希表。 + 等待选出负责分配初始哈希表的 Parallel Hash 参与者。 HashBuildHashInner - 等待其他并行哈希参与者完成内部关系的散列。 + 等待其他 Parallel Hash 参与者完成对内层关系的哈希处理。 HashBuildHashOuter - 等待其他Parallel 哈希参与者完成对外部关系的分区。 + 等待其他 Parallel Hash 参与者完成对外层关系的分区。 HashGrowBatchesAllocate - 等待选定的并行哈希参与者分配更多批处理。 + 等待选出的 Parallel Hash 参与者分配更多批次。 HashGrowBatchesDecide - 等待选择一个并行哈希参与者来决定未来的批处理增长。 + 等待选出负责决定后续批次增长的 Parallel Hash 参与者。 HashGrowBatchesElect - 等待选择一个Parallel 哈希参与者来分配更多批处理。 + 等待选出负责分配更多批次的 Parallel Hash 参与者。 HashGrowBatchesFinish - 等待当选的平行散列参与者决定未来的批量增长。 + 等待选出的 Parallel Hash 参与者决定后续的批次增长。 HashGrowBatchesRepartition - 等待一个选定的并行哈希参与者决定未来的批处理增长。 + 等待其他 Parallel Hash 参与者完成重新分区。 HashGrowBucketsAllocate - 等待选定的并行哈希参与者完成更多bucket的分配。 + 等待选出的 Parallel Hash 参与者完成更多桶的分配。 HashGrowBucketsElect - 等待选择一个并行哈希参与者来分配更多的buckets。 + 等待选出负责分配更多桶的 Parallel Hash 参与者。 HashGrowBucketsReinsert - 等待其他Parallel 哈希参与者完成将元组插入到新buckets中。 + 等待其他 Parallel Hash 参与者完成向新桶插入元组。 LogicalSyncData @@ -1309,19 +1291,19 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser ParallelBitmapScan - 等待并行位图扫描被初始化。 + 等待并行位图扫描完成初始化。 ParallelCreateIndexScan - 等待并行CREATE INDEX 工作进程完成堆扫描。 + 等待并行 CREATE INDEX 工作进程完成堆扫描。 ParallelFinish - 等待并行工作人员完成计算。 + 等待并行工作进程完成计算。 ProcArrayGroupUpdate - 等待组领导在并行操作结束时清除事务ID。 + 等待组领导者在事务结束时清除事务 ID。 ProcSignalBarrier @@ -1333,11 +1315,11 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser RecoveryConflictSnapshot - 等待vacuum清理的恢复冲突解决。 + 等待解决清理操作引发的恢复冲突。 RecoveryConflictTablespace - 等待恢复冲突解决删除表空间。 + 等待解决删除表空间引发的恢复冲突。 RecoveryPause @@ -1357,11 +1339,11 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser SyncRep - 在同步复制期间等待远程服务器的确认。 + 在同步复制期间等待来自远程服务器的确认。 XactGroupUpdate - 等待分组组长在并行操作结束时更新事务状态。 + 等待组领导者在事务结束时更新事务状态。 @@ -1383,7 +1365,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser advisory - 等待获得一个建议用户锁。 + 等待获取用户咨询锁。 @@ -1393,8 +1375,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser frozenid - 等待升级 pg_database.datfrozenxid - 和 pg_database.datminmxid. + 等待更新 pg_database.datfrozenxidpg_database.datminmxid @@ -1409,12 +1390,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser relation - 等待获得一个关系的锁。 + 等待获取关系上的锁。 spectoken - 等待获取推测的插入锁。 + 等待获取推测插入锁。 @@ -1454,7 +1435,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser AddinShmemInit - 等待管理共享内存中的扩展空间分配。 + 等待管理扩展在共享内存中的空间分配。 AutoFile @@ -1466,7 +1447,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser AutovacuumSchedule - 等待确保选择为自动清理的表仍然需要清理。 + 等待确认选中进行自动清理的表是否仍需清理。 BackgroundWorker @@ -1498,7 +1479,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser CommitTs - 等待读取或更新事务提交时间戳的最后一个值集。 + 等待读取或更新最近设置的事务提交时间戳值。 CommitTsBuffer @@ -1522,35 +1503,35 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser LockManager - 等待读取或更新关于heavyweight锁。 + 等待读取或更新有关重量级锁的信息。 LogicalRepWorker - 等待读取或更新逻辑复制工作器的状态。 + 等待读取或更新逻辑复制工作进程的状态。 MultiXactGen - 等待读取或更新共享的multixact状态。 + 等待读取或更新共享的多事务状态。 MultiXactMemberBuffer - 在multixact成员SLRU缓冲区上等待I/O。 + 等待多事务成员 SLRU 缓冲区上的 I/O。 MultiXactMemberSLRU - 等待访问multixact成员SLRU缓存。 + 等待访问多事务成员 SLRU 缓存。 MultiXactOffsetBuffer - 在multixact 偏移 SLRU缓冲区上等待I/O。 + 等待多事务偏移量 SLRU 缓冲区上的 I/O。 MultiXactOffsetSLRU - 等待访问multixact 偏移 SLRU缓存。 + 等待访问多事务偏移量 SLRU 缓存。 MultiXactTruncation - 等待读取或截断multixact信息。 + 等待读取或截断多事务信息。 NotifyBuffer @@ -1562,7 +1543,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser NotifyQueueTail - 等待NOTIFY消息存储上的更新限制。 + 等待更新 NOTIFY 消息存储的限制。 NotifySLRU @@ -1578,11 +1559,11 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser ParallelAppend - 在并行附加计划执行期间等待选择下一个子计划。 + 在 Parallel Append 计划执行期间等待选择下一个子计划。 ParallelHashJoin - 在并行哈希连接计划执行期间等待同步工作器。 + 在 Parallel Hash Join 计划执行期间等待同步工作进程。 ParallelQueryDSA @@ -1594,11 +1575,11 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser PerSessionRecordType - 等待访问有关复合类型的并行查询信息。 + 等待访问并行查询中有关复合类型的信息。 PerSessionRecordTypmod - 等待访问有关标识匿名记录类型的类型修饰符的并行查询信息。 + 等待访问并行查询中用于标识匿名记录类型的类型修饰符信息。 PerXactPredicateList @@ -1610,7 +1591,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser ProcArray - 等待访问每个进程共享的数据结构(通常情况,是获取快照或报告会话的事务ID)。 + 等待访问各进程的共享数据结构(通常是为了获取快照或报告会话的事务 ID)。 RelationMapping @@ -1674,11 +1655,11 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser SInvalRead - 等待从共享目录失效队列中检索消息。 + 等待从共享系统目录失效队列中取出消息。 SInvalWrite - 等待向共享编目失效队列添加消息。 + 等待向共享系统目录失效队列添加消息。 SubtransBuffer @@ -1702,7 +1683,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser TwoPhaseState - 等待读取或更新已准备事务的状态。 + 等待读取或更新预备事务的状态。 WALBufMapping @@ -1718,7 +1699,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser WrapLimitsVacuum - 等待更新事务 ID和multixact消费的限制。 + 等待更新事务 ID 和多事务消耗量的限制。 XactBuffer @@ -1761,7 +1742,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser BaseBackupThrottle - 当有限流活动时在基础备份期间等待。 + 在基础备份期间因限流而等待。 PgSleep @@ -1777,11 +1758,11 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser RegisterSyncRequest - 在发送同步请求到检查点程序时等待,因为请求队列已满。 + 向检查点进程发送同步请求时,因请求队列已满而等待。 VacuumDelay - 在一个基于代价的清理延迟点。 + 在基于代价的清理延迟点等待。 @@ -1869,7 +1850,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i 连接到这个 WAL 发送进程的客户端的 IP 地址。 - 如果这个域为空,它表示该客户端通过服务器机器上的一个Unix 套接字连接。 + 如果这个字段为空值,它表示该客户端通过服务器机器上的一个Unix 套接字连接。 @@ -1914,30 +1895,33 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i state text - 当前 WAL 发送进程的状态。可能的值为: + + 当前的 WAL 发送进程状态。 + 可能的值是: + - startup: 此 WAL 发送进程正在启动。 + startup: 此 WAL 发送进程正在启动。 - catchup: 与此 WAL 发送进程连接的备库正在赶上主库。 + catchup: 与此 WAL 发送进程连接的备库正在赶上主库。 - streaming: 在其连接的备库赶上主库之后,此 WAL 发送进程正在流式传输更改。 + streaming: 在其连接的备库赶上主库之后,此 WAL 发送进程正在流式传输更改。 - backup: 此 WAL 发送进程正在发送一个备份。 + backup: 此 WAL 发送进程正在发送一个备份。 - stopping: 此 WAL 发送进程正在停止。 + stopping: 此 WAL 发送进程正在停止。 @@ -1984,30 +1968,21 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i write_lag interval - - 从本地刷写最近的 WAL,到收到该备库已写入该 WAL(但尚未刷盘或应用)的通知之间经过的时间。 - 如果该服务器被配置为同步备库,可用此值衡量在提交时 synchronous_commit 级别 remote_write 所导致的延迟。 - + 从在本地将最近的 WAL 刷盘,到收到该备库已写入该 WAL(但尚未刷盘或应用)的通知之间经过的时间。如果该服务器被配置为同步备库,可用此值衡量在提交时synchronous_commit级别remote_write所导致的延迟。 flush_lag interval - - 从本地刷写最近的 WAL,到收到该备库已写入并刷写该 WAL(但尚未应用)的通知之间经过的时间。 - 如果该服务器被配置为同步备库,可用此值衡量在提交时 synchronous_commit 级别 on 所导致的延迟。 - + 从在本地将最近的 WAL 刷盘,到收到该备库已写入该 WAL 并将其刷盘(但尚未应用)的通知之间经过的时间。如果该服务器被配置为同步备库,可用此值衡量在提交时synchronous_commit级别on所导致的延迟。 replay_lag interval - - 从本地刷写最近的 WAL,到收到该备库已写入、刷写并应用该 WAL 的通知之间经过的时间。 - 如果该服务器被配置为同步备库,可用此值衡量在提交时 synchronous_commit 级别 remote_apply 所导致的延迟。 - + 从在本地将最近的 WAL 刷盘,到收到该备库已写入该 WAL、将其刷盘并应用的通知之间经过的时间。如果该服务器被配置为同步备库,可用此值衡量在提交时synchronous_commit级别remote_apply所导致的延迟。 @@ -2023,25 +1998,28 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i sync_state text - 此备库的同步状态。可能的值为: + + 该备库的同步状态。 + 可能的值是: + - async: 该备库是异步的。 + async: 该备库是异步的。 - potential: 该备库当前是异步的,但在当前同步备库失效时可能变为同步的。 + potential: 该备库当前是异步的,但在当前某个同步备库失效时可能变为同步的。 - sync: 该备库是同步的。 + sync: 该备库是同步的。 - quorum: 该备库被作为法定人数同步复制候选备库。 + quorum: 该备库被作为法定人数同步复制候选备库。 @@ -2061,16 +2039,16 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i
- pg_stat_replication视图中报告的滞后时间,是最近的 WAL 被写入、刷写和重放,以及发送端获知这些操作完成所花费时间的度量。如果远程服务器被配置为同步备库,这些时间表示各个同步提交级别带来或可能带来的提交延迟。对于异步备库,replay_lag列是最近事务对查询变得可见所需延迟时间的近似值。如果备库已经完全追上发送服务器且没有新的 WAL 活动,系统会在短时间内继续显示最近测得的滞后时间,随后显示为 NULL。 + pg_stat_replication视图中报告的滞后时间,是最近的 WAL 被写入、刷盘和重放,以及发送端获知这些操作完成所花费时间的度量。如果远程服务器被配置为同步备库,这些时间表示各个同步提交级别带来或可能带来的提交延迟。对于异步备库,replay_lag列是最近事务对查询变得可见所需延迟时间的近似值。如果备库已经完全追上发送服务器且没有新的 WAL 活动,系统会在短时间内继续显示最近测得的滞后时间,随后显示为空值。 - 对于物理复制,滞后时间会自动测量。逻辑解码插件可以选择发出跟踪消息;如果没有这样做,跟踪机制会将滞后显示为 NULL。 + 对于物理复制,滞后时间会自动测量。逻辑解码插件可以选择发出跟踪消息;如果没有这样做,跟踪机制会将滞后显示为空值。 - 报告出的滞后时间并不是根据当前重放速率预测该备库还需多久才能追上发送服务器。在持续生成新 WAL 时,那样的系统可能会显示相近的时间;但当发送端空闲时,就会显示不同的值。特别是当备库已经完全追上时,pg_stat_replication显示的是写入、刷写和重放最近报告的 WAL 位置所花费的时间,而不是某些用户可能预期的零。这样做符合为最近写事务测量同步提交和事务可见性延迟的目的。为减少用户因预期另一种滞后模型而产生的混淆,在一个已完全重放且处于空闲状态的系统上,lag 列会在较短时间后恢复为 NULL。监控系统应自行决定将这种情况表示为缺失数据、零,还是继续显示最近一次已知值。 + 报告出的滞后时间并不是根据当前重放速率预测该备库还需多久才能追上发送服务器。在持续生成新 WAL 时,那样的系统可能会显示相近的时间;但当发送端空闲时,就会显示不同的值。特别是当备库已经完全追上时,pg_stat_replication显示的是写入、刷盘和重放最近报告的 WAL 位置所花费的时间,而不是某些用户可能预期的零。这样做符合为最近写事务测量同步提交和事务可见性延迟的目的。为减少用户因预期另一种滞后模型而产生的混淆,在一个已完全重放且处于空闲状态的系统上,滞后列会在较短时间后恢复为空值。监控系统应自行决定将这种情况表示为缺失数据、零,还是继续显示最近一次已知值。 @@ -2083,9 +2061,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i pg_stat_wal_receiver - - pg_stat_wal_receiver事务只包含一行,它显示了从 WAL 接收进程所连接的服务器得到的有关该接收进程的统计信息。 - + pg_stat_wal_receiver视图只包含一行,显示 WAL 接收进程从其所连接服务器接收数据的统计信息。 @@ -2110,7 +2086,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i pidinteger - WAL 接收进程的进程ID + WAL 接收进程的进程 ID @@ -2119,7 +2095,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i statustext - WAL接收进程的活动状态 + WAL 接收进程的活动状态 @@ -2128,7 +2104,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i receive_start_lsnpg_lsn - WAL 接收进程启动时使用的第一个写前日志位置 + WAL 接收进程启动时使用的第一个预写式日志位置 @@ -2137,7 +2113,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i receive_start_tliinteger - WAL 接收进程启动时使用的第一个时间线数字 + WAL 接收进程启动时使用的第一个时间线编号 @@ -2146,7 +2122,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i written_lsnpg_lsn - 已经接收并写入磁盘的最后一个预写式日志位置,但没有刷入。这不能用于数据完整性检查。 + 已经接收并写入磁盘的最后一个预写式日志位置,但尚未刷盘。此字段不应用于数据完整性检查。 @@ -2155,7 +2131,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i flushed_lsnpg_lsn - 已经接收并刷入到磁盘的最后一个预写式日志位置,该字段的初始值是启动WAL 接收进程时使用的第一个日志位置 + 已经接收并刷入到磁盘的最后一个预写式日志位置,该字段的初始值是启动 WAL 接收进程时使用的第一个日志位置 @@ -2164,7 +2140,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i received_tliinteger - 接收并刷入到磁盘的最后一个预写式日志位置的时间线数字,该字段的初始值为启动WAL 接收进程时使用的第一个日志位置的时间线数字 + 接收并刷入到磁盘的最后一个预写式日志位置的时间线编号,该字段的初始值为启动 WAL 接收进程时使用的第一个日志位置的时间线编号 @@ -2209,7 +2185,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i slot_nametext - 这个WAL 接收进程使用的复制槽的名称 + 这个 WAL 接收进程使用的复制槽的名称 @@ -2218,8 +2194,8 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i sender_hosttext - 这个WAL 接收进程连接到的PostgreSQL实例的主机。 - 这可以是主机名、IP地址,或者目录路径,如果连接是通过Unix套接字进行的。(路径的情况可以区分,因为它总是以/开头的绝对路径。) + 这个 WAL 接收进程连接到的PostgreSQL实例的主机。 + 这可以是主机名、IP地址,或者目录路径,如果连接是通过Unix套接字进行的。(路径的情况可以区分,因为它总是以/开头的绝对路径。) @@ -2228,7 +2204,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i sender_portinteger - 这个WAL 接收进程连接的PostgreSQL实例的端口号。 + 这个 WAL 接收进程连接的PostgreSQL实例的端口号。 @@ -2237,7 +2213,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i conninfotext - 这个WAL 接收进程使用的连接字符串,对安全敏感的字段进行了模糊处理。 + 这个 WAL 接收进程使用的连接字符串,对安全敏感的字段进行了模糊处理。 @@ -2271,6 +2247,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i + subid oid @@ -2280,7 +2257,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i - + subname name @@ -2289,7 +2266,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i - + pid integer @@ -2298,25 +2275,25 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i - + relid oid - 该工作进程正在同步的关系的 OID;主应用工作进程则为 NULL + 该工作进程正在同步的关系的 OID;主应用工作进程则为空值 - + received_lsn pg_lsn - 接收到的最后一个预写式日志位置,该字段的初始值为0 + 接收到的最后一个预写式日志位置,该字段的初始值为 0 - + last_msg_send_time timestamp with time zone @@ -2325,7 +2302,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i - + last_msg_receipt_time timestamp with time zone @@ -2334,7 +2311,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i - + latest_end_lsn pg_lsn @@ -2343,14 +2320,15 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i - + latest_end_time timestamp with time zone - 向 WAL 发送进程报告最后一个预写式日志位置的时间 + 向源 WAL 发送进程报告最后一个预写式日志位置的时间 +
@@ -2408,7 +2386,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i version text
- 使用SSL的版本,如果此连接上没有使用SSL则为NULL + 使用SSL的版本,如果此连接上没有使用SSL则为空值 @@ -2417,7 +2395,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i cipher text
- 正在使用的SSL密码的名称,如果此连接上没有使用SSL则为NULL + 正在使用的SSL 密码套件的名称,如果此连接上没有使用SSL则为空值 @@ -2426,7 +2404,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i bits integer - 使用的加密算法中的位数,如果此连接上没有使用SSL则为NULL + 使用的加密算法中的位数,如果此连接上没有使用SSL则为空值 @@ -2434,7 +2412,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i compression boolean - 使用 SSL 压缩时为真,否则为假;如果此连接未使用 SSL,则为 NULL + 使用 SSL 压缩时为真,否则为假;如果此连接未使用 SSL,则为空值 @@ -2442,8 +2420,8 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i client_dn text - 区别名称(DN,Distinguished Name)字段与使用的客户端证书,如果没有提供客户端证书或在此连接上没有使用SSL,则为NULL。 - 如果DN字段长于NAMEDATALEN(标准构建中为64个字符),则该字段将被截断。 + 所用客户端证书中的区别名称(DN,Distinguished Name)字段,如果没有提供客户端证书或在此连接上没有使用SSL,则为空值。 + 如果DN字段长于NAMEDATALEN(标准构建中为64个字符),则该字段将被截断。 @@ -2452,8 +2430,8 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i client_serial numeric - 客户端证书的序列号,如果没有提供客户端证书或在此连接上没有使用SSL,则为NULL。 - 证书序列号和证书颁发者的组合唯一标识一个证书(除非颁发者错误地重用序列号)。 + 客户端证书的序列号,如果没有提供客户端证书或在此连接上没有使用SSL,则为空值。 + 证书序列号和证书颁发者的组合唯一标识一个证书(除非颁发者错误地重用序列号)。 @@ -2462,7 +2440,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i issuer_dn text - 客户端证书颁发者的区别名称(DN,Distinguished Name),如果没有提供客户端证书或在此连接上没有使用SSL,则为NULL。该字段像client_dn一样被截断。 + 客户端证书颁发者的区别名称(DN,Distinguished Name),如果没有提供客户端证书或在此连接上没有使用SSL,则为空值。该字段像client_dn一样被截断。 @@ -2480,7 +2458,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i pg_stat_gssapi视图将包含每一个后端一个行,显示该连接上的GSSAPI使用情况。 - 它可以加入到pg_stat_activitypg_stat_replication上的pid列,获取更多关于连接的详细信息。 + 可以通过pid列将它与pg_stat_activitypg_stat_replication连接,获取更多关于连接的详细信息。 @@ -2522,8 +2500,8 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i principaltext - 用于验证此连接的主体,如果未使用GSSAPI对此连接进行认证,则为NULL。 - 如果主体长度超过NAMEDATALEN(标准构建中为64个字符),则该字段被截断。 + 用于认证此连接的主体,如果未使用GSSAPI对此连接进行认证,则为空值。 + 如果主体长度超过NAMEDATALEN(标准构建中为64个字符),则该字段被截断。 @@ -2628,9 +2606,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i stats_reset timestamp with time zone - - 这些统计数据最后一次重置的时间 - + 这些统计信息上次被重置的时间 @@ -2646,7 +2622,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i - pg_stat_bgwriter 视图始终只有一行,包含有关集簇后台写入器的数据。 + pg_stat_bgwriter 视图始终只有一行,包含整个集簇的全局数据。
@@ -2728,7 +2704,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i buffers_backend_fsync bigint - 后端必须自行执行fsync调用的次数(通常即使后端自行写入,也由后台写入进程处理这些调用) + 后端必须自行执行fsync调用的次数(通常即使后端自行写入,也由后台写入器处理这些调用) @@ -2744,9 +2720,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i stats_reset timestamp with time zone - - 这些统计信息上次被重置的时间 - + 这些统计信息上次被重置的时间 @@ -2781,6 +2755,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i + datid oid @@ -2790,7 +2765,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i - + datname name @@ -2799,7 +2774,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i - + numbackends integer @@ -2809,7 +2784,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i - + xact_commit bigint @@ -2818,7 +2793,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i - + xact_rollback bigint @@ -2827,7 +2802,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i - + blks_read bigint @@ -2836,7 +2811,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i - + blks_hit bigint @@ -2845,25 +2820,25 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i - + tup_returned bigint - 由顺序扫描获取的活动行数和由索引扫描返回的索引条目数 + 此数据库中的查询返回的行数 - + tup_fetched bigint - 该数据库中由索引扫描检索的活动行数 + 此数据库中的查询获取的行数 - + tup_inserted bigint @@ -2872,7 +2847,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i - + tup_updated bigint @@ -2881,7 +2856,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i - + tup_deleted bigint @@ -2890,7 +2865,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i - + conflicts bigint @@ -2899,7 +2874,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i - + temp_files bigint @@ -2908,7 +2883,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i - + temp_bytes bigint @@ -2917,7 +2892,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i - + deadlocks bigint @@ -2926,7 +2901,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i - + checksum_failures bigint @@ -2935,7 +2910,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i - + checksum_last_failure timestamp with time zone @@ -2944,7 +2919,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i - + blk_read_time double precision @@ -2953,7 +2928,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i - + blk_write_time double precision @@ -2962,7 +2937,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i - + stats_reset timestamp with time zone @@ -2970,6 +2945,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i 这些统计数据最后一次重置的时间 +
@@ -3054,7 +3030,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i confl_bufferpin bigint - 此数据库中由于固定缓冲区而被取消的查询数 + 此数据库中由于缓冲区被钉住而被取消的查询数 @@ -3141,7 +3117,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i seq_tup_read bigint - 连续扫描获取的实时行数 + 顺序扫描获取的存活行数 @@ -3159,7 +3135,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i idx_tup_fetch bigint - 索引扫描获取的实时行数 + 索引扫描获取的存活行数 @@ -3195,7 +3171,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i n_tup_hot_upd bigint - HOT更新的行数(即,不需要单独的索引更新) + HOT 更新的行数(即不需要单独更新索引) @@ -3240,7 +3216,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i last_vacuum timestamp with time zone - 最后一次手动清理这个表(不包括VACUUM FULL) + 最后一次手动清理这个表的时间(不包括VACUUM FULL @@ -3258,7 +3234,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i last_analyze timestamp with time zone - 上一次手动分析这个表 + 上一次手动分析这个表的时间 @@ -3267,7 +3243,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i last_autoanalyze timestamp with time zone - 自动清理守护进程最后一次分析这个表 + 自动清理守护进程最后一次分析这个表的时间 @@ -3276,7 +3252,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i vacuum_count bigint - 这个表被手动清理的次数(VACUUM FULL不计数) + 这个表被手动清理的次数(VACUUM FULL不计数) @@ -3407,7 +3383,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i idx_tup_fetch bigint - 使用此索引进行简单索引扫描获取的活动表行数 + 使用此索引进行简单索引扫描获取的存活表行数 @@ -3415,13 +3391,13 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i - 索引可以被简单索引扫描、位图索引扫描以及优化器使用。在一次位图扫描中,多个索引的输出可以被通过 AND 或 OR 规则组合,因此当使用一次位图扫描时难以将取得的个体堆行与特定的索引关联起来。因此,一次位图扫描会增加它使用的索引的pg_stat_all_indexes.idx_tup_read计数,并且为每个表增加pg_stat_all_tables.idx_tup_fetch计数,但是它不影响pg_stat_all_indexes.idx_tup_fetch。如果所提供的常量值不在优化器统计信息记录的范围之内,优化器也会访问索引来检查,因为优化器统计信息可能已经“不新鲜”了。 + 索引可以被简单索引扫描、位图索引扫描以及优化器使用。在一次位图扫描中,多个索引的输出可以被通过 AND 或 OR 规则组合,因此当使用一次位图扫描时难以将取得的个体堆行与特定的索引关联起来。因此,一次位图扫描会增加它使用的索引的pg_stat_all_indexes.idx_tup_read计数,并且为该表增加pg_stat_all_tables.idx_tup_fetch计数,但是它不影响pg_stat_all_indexes.idx_tup_fetch。如果所提供的常量值不在优化器统计信息记录的范围之内,优化器也会访问索引来检查,因为优化器统计信息可能已经过时。 - 即使不用位图扫描,idx_tup_readidx_tup_fetch计数也可能不同,因为idx_tup_read统计从该索引取得的索引项而idx_tup_fetch统计从表取得的活着的行。如果使用该索引取得了任何死亡行或还未提交的行,或者如果通过一次只用索引扫描的方式避免了任何堆获取,后者将较小。 + 即使不用位图扫描,idx_tup_readidx_tup_fetch计数也可能不同,因为idx_tup_read统计从该索引取得的索引项而idx_tup_fetch统计从表取得的存活行。如果使用该索引取得了任何死亡行或还未提交的行,或者如果通过一次仅索引扫描的方式避免了任何堆获取,后者将较小。 @@ -3524,7 +3500,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i toast_blks_read bigint - 从这个表的TOAST表中读取的磁盘块的数量(如果有的话) + 从这个表的TOAST表中读取的磁盘块的数量(如果有的话) @@ -3533,7 +3509,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i toast_blks_hit bigint - 这个表的TOAST表中的缓冲区命中数(如果有的话) + 这个表的TOAST表中的缓冲区命中数(如果有的话) @@ -3542,7 +3518,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i tidx_blks_read bigint - 从这个表的TOAST表索引中读取的磁盘块的数量(如果有的话) + 从这个表的TOAST表索引中读取的磁盘块的数量(如果有的话) @@ -3551,7 +3527,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i tidx_blks_hit bigint - 这个表的TOAST表索引中的缓冲区命中数(如果有的话) + 这个表的TOAST表索引中的缓冲区命中数(如果有的话) @@ -3838,7 +3814,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i - PostgreSQL通过SLRU(simple least-recently-used,简单的最近-最少-使用)缓存访问某些磁盘上的信息。 + PostgreSQL通过SLRU(simple least-recently-used,简单最近最少使用)缓存访问某些磁盘上的信息。 pg_stat_slru视图将为每个被跟踪的SLRU缓存包含一行,显示关于访问缓存页面的统计信息。 @@ -3883,7 +3859,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i blks_hit bigint - 已经在SLRU中的磁盘块被发现的次数,因此不需要读取(这只包括SLRU中的命中,而不是操作系统的文件系统缓存) + 已经在SLRU中的磁盘块被发现的次数,因此不需要读取(这只包括SLRU中的命中,而不是操作系统的文件系统缓存) @@ -3919,7 +3895,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i flushes bigint - 此SLRU的脏数据刷新数 + 此SLRU的脏数据刷盘次数 @@ -3928,7 +3904,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i truncates bigint - 这个SLRU的截断数 + 这个SLRU的截断次数 @@ -3936,9 +3912,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i stats_reset timestamp with time zone - - 这些统计数据最后一次重置的时间 - + 这些统计信息上次被重置的时间 @@ -4066,9 +4040,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i 将当前数据库的所有统计计数器重置为零。 - - 默认情况下该函数仅限于超级用户,但是其他用户可以被授予EXECUTE来运行此函数。 - + 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 @@ -4080,13 +4052,9 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i void - 根据参数将某些集簇范围的统计计数器重置为零。参数可以是bgwriter, - 用于重置pg_stat_bgwriter视图中显示的所有计数器; - 或者是archiver,用于重置pg_stat_archiver视图中显示的所有计数器。 + 根据参数将一些集簇范围的统计计数器重置为零。参数可以为 bgwriter,用于重置 pg_stat_bgwriter 视图中显示的所有计数器;或 archiver,用于重置 pg_stat_archiver 视图中显示的所有计数器。 - - 默认情况下,此函数仅限超级用户使用,但可以授予其他用户EXECUTE权限来运行该函数。 - + 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 @@ -4100,9 +4068,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i 重置当前数据库中的单个表或索引的统计信息,或者在集簇中跨所有数据库共享的统计信息为零。 - - 默认情况下,此函数仅限超级用户使用,但可以授予其他用户EXECUTE权限来运行该函数。 - + 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 @@ -4116,9 +4082,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i 将当前数据库中单个函数的统计信息重置为零。 - - 默认情况下该函数仅限于超级用户,但是其他用户可以被授予EXECUTE来运行此函数。 - + 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 @@ -4130,15 +4094,9 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i void - 将单个SLRU缓存或集簇中所有SLRU的统计信息重置为零。 - 如果该参数为NULL,则所有SLRU缓存的pg_stat_slru视图中显示的计数器将被重置。 - 参数可以是CommitTsMultiXactMemberMultiXactOffsetNotify、 - SerialSubtrans、 或Xact中的一个,以便只重置该条目的计数器。 - 如果参数是other(或实际上,任何无法识别的名称),那么所有其他SLRU缓存的计数器,如扩展定义的缓存,将被重置。 + 将单个 SLRU 缓存或集簇中所有 SLRU 的统计信息重置为零。如果参数为空值,则重置 pg_stat_slru 视图中所有 SLRU 缓存的全部计数器。参数可以为 CommitTs、&zwsp;MultiXactMember、&zwsp;MultiXactOffset、&zwsp;Notify、&zwsp;Serial、&zwsp;SubtransXact 中的一个,以便只重置对应条目的计数器。如果参数为 other(实际上,任何无法识别的名称都可以),则重置其他所有 SLRU 缓存的计数器,例如扩展定义的缓存。 - - 默认情况下该函数仅限于超级用户,但是其他用户可以被授予EXECUTE来运行此函数。 - + 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 @@ -4283,7 +4241,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, pg_stat_get_backend_start ( integer ) timestamp with time zone - 返回此进程的启动时间。 + 返回该进程开始的时间。 @@ -4308,7 +4266,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, text - 如果后端当前正在等待,则返回等待事件类型名称,否则返回NULL。 + 如果后端当前正在等待,则返回等待事件类型名称,否则返回空值。 请参阅 @@ -4322,7 +4280,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, text - 如果后端当前正在等待,则返回等待事件名称,否则为NULL。 + 如果后端当前正在等待,则返回等待事件名称,否则为空值。 请参阅 @@ -4351,23 +4309,23 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, 查看锁 - lock - monitoring + + 监控 - 监控数据库活动的另外一个有用的工具是pg_locks系统表。这样就允许数据库管理员查看在锁管理器里面未解决的锁的信息。例如,这个功能可以被用于: + 监控数据库活动的另外一个有用的工具是pg_locks系统表。这样就允许数据库管理员查看锁管理器中当前存在的锁的信息。例如,这个功能可以被用于: - 查看当前所有未解决的锁、在一个特定数据库中的关系上所有的锁、在一个特定关系上所有的锁,或者由一个特定PostgreSQL会话持有的所有的锁。 + 查看当前存在的所有锁、在一个特定数据库中的关系上所有的锁、在一个特定关系上所有的锁,或者由一个特定PostgreSQL会话持有的所有的锁。 - 判断当前数据库中带有最多未授予锁的关系(它很可能是数据库客户端的竞争源)。 + 判断当前数据库中带有最多未授予锁的关系(它可能是数据库客户端之间的竞争来源)。 @@ -4549,14 +4507,14 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, acquiring sample rows - 该命令当前正在扫描relid给出的表以获得样例行。 + 该命令当前正在扫描relid给出的表以获得样本行。 acquiring inherited sample rows - 该命令当前正在扫描子表以获得样例行。列child_tables_total,child_tables_done, + 该命令当前正在扫描子表以获得样本行。列child_tables_totalchild_tables_done、 和current_child_table_relid包含此阶段的进度信息。 @@ -4564,14 +4522,14 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, computing statistics - 该命令从表扫描期间获得的样例行计算统计信息。 + 该命令从表扫描期间获得的样本行计算统计信息。 computing extended statistics - 该命令从表扫描期间获得的样例行计算扩展统计信息。 + 该命令从表扫描期间获得的样本行计算扩展统计信息。 @@ -4586,11 +4544,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - - 请注意,如中所述,在分区表上运行ANALYZE时, - 也会递归分析其所有分区。在这种情况下,首先报告父表的ANALYZE进度, - 此时收集其继承统计信息,随后报告各个分区的进度。 - + 请注意,如中所述,当在分区表上运行ANALYZE时,其所有分区也会被递归分析。在这种情况下,会先报告父表的ANALYZE进度,并收集其继承统计信息,随后再报告每个分区的进度。 @@ -4668,8 +4622,8 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, command text - 在运行的命令: CREATE INDEX,CREATE INDEX CONCURRENTLY, - REINDEX, 或 REINDEX CONCURRENTLY. + 在运行的命令: CREATE INDEXCREATE INDEX CONCURRENTLY、 + REINDEXREINDEX CONCURRENTLY @@ -4686,27 +4640,21 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, lockers_total bigint - - 在适用的情况下,需要等待的储物柜总数 - + 在适用的情况下,需要等待的持锁进程总数。 lockers_done bigint - - 已经等待的储物柜数量。 - + 已完成等待的持锁进程数量。 current_locker_pid bigint - - 目前正在等待的储物柜的进程ID。 - + 当前正在等待的持锁进程的进程 ID。 @@ -4714,7 +4662,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, blocks_total bigint - 本阶段要处理的区块总数。 + 本阶段要处理的块总数。 @@ -4723,7 +4671,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, blocks_done bigint - 当前阶段已经处理的区块数量。 + 当前阶段已经处理的块数量。 @@ -4769,7 +4717,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - CREATE INDEX 的阶段 + CREATE INDEX 阶段 @@ -4790,19 +4738,19 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, waiting for writers before build - CREATE INDEX CONCURRENTLYREINDEX CONCURRENTLY正在等待有可能看到表的写锁的事务完成。 当不在并发模式时,这个阶段会被跳过。lockers_totallockers_donecurrent_locker_pid 列包含了这个阶段的进度信息。 + CREATE INDEX CONCURRENTLYREINDEX CONCURRENTLY正在等待持有写锁且可能看到该表的事务结束。 当不在并发模式时,这个阶段会被跳过。lockers_totallockers_donecurrent_locker_pid 列包含了这个阶段的进度信息。 building index - 索引是由访问方法专用代码建立的。 在这一阶段,支持进度报告的访问方法填写自己的进度数据,子阶段在这一栏中表示。 通常情况下,blocks_totalblocks_done将包含进度数据,也可能包含tuples_totaltuples_done。 + 索引是由访问方法专用代码建立的。 在这一阶段,支持进度报告的访问方法填写自己的进度数据,子阶段在这一栏中表示。 通常情况下,blocks_totalblocks_done将包含进度数据,tuples_totaltuples_done也可能包含进度数据。 waiting for writers before validation - CREATE INDEX CONCURRENTLYREINDEX CONCURRENTLY正在等待有可能写入表的事务完成写锁的事务。当不在并发模式时,这个阶段会被跳过。lockers_totallockers_donecurrent_locker_pid 列包含了这个阶段的进度信息。 + CREATE INDEX CONCURRENTLYREINDEX CONCURRENTLY正在等待持有写锁且可能写入该表的事务结束。当不在并发模式时,这个阶段会被跳过。lockers_totallockers_donecurrent_locker_pid 列包含了这个阶段的进度信息。 @@ -4902,7 +4850,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, relid oid - 被vacuum的表的OID。 + 正在清理的表的OID。 @@ -4911,7 +4859,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, phase text - vacuum的当前处理阶段。参见 。 + 清理的当前处理阶段。参见 @@ -4920,7 +4868,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, heap_blks_total bigint - 该表中堆块的总数。这个数字在扫描开始时报告,之后增加的块将不会(并且不需要)被这个VACUUM访问。 + 该表中堆块的总数。这个数字以扫描开始时的数量为准,之后增加的块将不会(并且不需要)被这个VACUUM访问。 @@ -4959,7 +4907,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, max_dead_tuples bigint - 在需要执行索引清理周期之前可存储的死亡元组数据量,取决于。 + 在需要执行索引清理周期之前可存储的死亡元组数量,取决于 @@ -4968,7 +4916,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, num_dead_tuples bigint - 自上一个索引清理周期以来收集到的死亡元组数据量。 + 自上一个索引清理周期以来收集到的死亡元组数量。 @@ -4976,7 +4924,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid,
- VACUUM的阶段 + VACUUM 阶段 @@ -4998,33 +4946,29 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, scanning heap - VACUUM正在扫描堆。如果需要,它将会对每个页面进行修建以及碎片整理,并且可能会执行冻结动作。heap_blks_scanned列可以用来监控扫描的进度。 + VACUUM正在扫描堆。如果需要,它将会对每个页面进行剪枝以及碎片整理,并且可能会执行冻结动作。heap_blks_scanned列可以用来监控扫描的进度。 vacuuming indexes - - VACUUM当前正在清理索引。 - 如果一个表拥有索引,那么每次清理时这个阶段会在堆扫描完成后至少发生一次。 - 如果不足以存放找到的死亡元组(或者, 在autovacuum情况下,如果设置了) ,则每次清理时会多次清理索引。 - + VACUUM当前正在清理索引。如果表有索引,每次清理都会在堆扫描完成后至少执行一次此阶段。如果(或者,对于自动清理,已设置的)不足以存储找到的死亡元组数量,则每次清理可能多次执行此阶段。 vacuuming heap - VACUUM当前正在清理堆。清理堆与扫描堆不是同一个概念,清理堆发生在每一次清理索引的实例之后。如果heap_blks_scanned小于heap_blks_total,系统将在这个阶段完成之后回去扫描堆;否则,系统将在这个阶段完成后开始清理索引。 + VACUUM当前正在清理堆。清理堆与扫描堆不是同一个概念,清理堆发生在每次索引清理之后。如果heap_blks_scanned小于heap_blks_total,系统将在这个阶段完成之后回去扫描堆;否则,系统将在这个阶段完成后开始索引收尾清理。 cleaning up indexes - VACUUM当前正在清除索引。这个阶段发生在堆被完全扫描并且对堆和索引的所有清理都已经完成以后。 + VACUUM当前正在进行索引收尾清理。这个阶段发生在堆被完全扫描并且对堆和索引的所有清理都已经完成以后。 truncating heap - VACUUM正在截断堆,以便把关系尾部的空页面返还给操作系统。这个阶段发生在清除完索引之后。 + VACUUM正在截断堆,以便把关系尾部的空页面返还给操作系统。这个阶段发生在索引收尾清理完成之后。 @@ -5045,7 +4989,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, CLUSTER 进度报告 - 每当CLUSTERVACUUM FULL运行时,pg_stat_progress_cluster视图将包含当前正在运行的每一个后台的记录。下面的表格描述了将被报告的信息,并提供了关于如何解释这些信息的信息。 + 每当CLUSTERVACUUM FULL运行时,pg_stat_progress_cluster视图将为每个当前正在运行这两种命令之一的后端包含一行。下面的表格描述了将被报告的信息,并提供了关于如何解释这些信息的信息。
@@ -5096,7 +5040,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, relidoid - 被集群的表的OID。 + 正在聚簇的表的OID。 @@ -5143,8 +5087,8 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, heap_tuples_writtenbigint - 写入的堆元组的数量。这个计数器只有在阶段为seq scanning heap,index scanning heap - 或 writing new heap时才会前进。 + 写入的堆元组的数量。这个计数器只有在阶段为seq scanning heapindex scanning heap + 或 writing new heap时才会递增。 @@ -5153,7 +5097,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, heap_blks_totalbigint - 表中的堆块总数。 这个数字是在seq scanning heap的开始时报告的。 + 表中的堆块总数。 这个数字以seq scanning heap开始时的数量为准。 @@ -5195,8 +5139,8 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, initializing - 该命令准备开始扫描堆栈。 这个阶段预计会非常短暂。 - + 命令正在准备开始扫描堆。这个阶段预计会非常短暂。 + seq scanning heap @@ -5219,7 +5163,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, writing new heap - CLUSTER目前正在编写新的堆。 + CLUSTER目前正在写入新的堆。 @@ -5298,7 +5242,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, 将被流式传输的数据总量。该值在streaming database files阶段开始时进行估算并报告。 注意,这只是一个近似值,因为数据库可能会在streaming database files阶段期间发生变化,而 WAL 日志也可能在稍后的备份阶段被包含进来。 一旦流式传输的数据量超过了估计的总大小,该值始终与backup_streamed相同。 - 如果在pg_basebackup中禁用估算(也就是说,指定了--no-estimate-size选项),这为NULL。 + 如果在pg_basebackup中禁用估算(也就是说,指定了--no-estimate-size选项),这为NULL @@ -5414,7 +5358,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - 动态追踪的编译 + 为动态追踪编译 默认情况下,探针是不可用的,因此你将需要显式地告诉配置脚本让探针在PostgreSQL中可用。要包括 DTrace 支持,在配置时指定。更多信息请见。 @@ -5426,7 +5370,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, 内置探针 - 如所示,源代码中提供了一些标准探针。显式了在探针中使用的类型。当然,可以增加更多探针来增强PostgreSQL的可观测性。 + 如所示,源代码中提供了一些标准探针。显示了在探针中使用的类型。当然,可以增加更多探针来增强PostgreSQL的可观测性。
@@ -5462,13 +5406,13 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, transaction-abort (LocalTransactionId) - 当一个事务失败完成时触发的探针。arg0 是事务 ID。 + 当一个事务失败结束时触发的探针。arg0 是事务 ID。 query-start (const char *) - 当一个查询的处理被开始时触发的探针。arg0 是查询字符串。 + 当一个查询的处理开始时触发的探针。arg0 是查询字符串。 @@ -5480,7 +5424,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, query-parse-start (const char *) - 当一个查询的解析被开始时触发的探针。arg0 是查询字符串。 + 当一个查询的解析开始时触发的探针。arg0 是查询字符串。 @@ -5492,7 +5436,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, query-rewrite-start (const char *) - 当一个查询的重写被开始时触发的探针。arg0 是查询字符串。 + 当一个查询的重写开始时触发的探针。arg0 是查询字符串。 @@ -5504,7 +5448,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, query-plan-start () - 当一个查询的规划被开始时触发的探针。 + 当一个查询的规划开始时触发的探针。 @@ -5516,7 +5460,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, query-execute-start () - 当一个查询的执行被开始时触发的探针。 + 当一个查询的执行开始时触发的探针。 @@ -5534,19 +5478,19 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, checkpoint-start (int) - 当一个检查点被开始时触发的探针。arg0 传递位标志来区分不同的检查点类型,例如关闭(shutdown)、立即(immediate)或强制(force)。 + 当一个检查点开始时触发的探针。arg0 传递位标志来区分不同的检查点类型,例如关闭(shutdown)、立即(immediate)或强制(force)。 checkpoint-done (int, int, int, int, int) - 当一个检查点完成时触发的探针(检查点处理过程中序列中列出的下一个触发的探针)。arg0 是要写的缓冲区数量。arg1 是缓冲区的总数。arg2、arg3 和 arg4 分别包含了增加、删除和循环回收的 WAL 文件的数量。 + 当一个检查点完成时触发的探针(下面列出的探针会在检查点处理过程中依次触发)。arg0 是已写入的缓冲区数量。arg1 是缓冲区的总数。arg2、arg3 和 arg4 分别包含了增加、删除和循环回收的 WAL 文件的数量。 clog-checkpoint-start (bool) - 当一个检查点的 CLOG 部分被开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 + 当一个检查点的 CLOG 部分开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 @@ -5558,7 +5502,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, subtrans-checkpoint-start (bool) - 当一个检查点的 SUBTRANS 部分被开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 + 当一个检查点的 SUBTRANS 部分开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 @@ -5570,7 +5514,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, multixact-checkpoint-start (bool) - 当一个检查点的 MultiXact 部分被开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 + 当一个检查点的 MultiXact 部分开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 @@ -5582,7 +5526,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, buffer-checkpoint-start (int) - 当一个检查点的写缓冲区部分被开始时触发的探针。arg0 传递位标志来区分不同的检查点类型,例如关闭(shutdown)、立即(immediate)或强制(force)。 + 当一个检查点的写缓冲区部分开始时触发的探针。arg0 传递位标志来区分不同的检查点类型,例如关闭(shutdown)、立即(immediate)或强制(force)。 @@ -5618,7 +5562,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, twophase-checkpoint-start () - 当一个检查点的两阶段部分被开始时触发的探针。 + 当一个检查点的两阶段部分开始时触发的探针。 @@ -5630,19 +5574,19 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, buffer-read-start (ForkNumber, BlockNumber, Oid, Oid, Oid, int, bool) - 当一次缓冲区读被开始时触发的探针。arg0 和 arg1 包含该页的分叉号和块号(如果这是一次关系扩展请求,arg1 为 -1)。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是 InvalidBackendId(-1)。arg6 为真表示一次关系扩展请求,为假表示正常读。 + 当一次缓冲区读开始时触发的探针。arg0 和 arg1 包含该页的分支号和块号(如果这是一次关系扩展请求,arg1 为 -1)。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是 InvalidBackendId(-1)。arg6 为真表示一次关系扩展请求,为假表示正常读。 buffer-read-done (ForkNumber, BlockNumber, Oid, Oid, Oid, int, bool, bool) - 当一次缓冲区读完成时触发的探针。arg0 和 arg1 包含该页的分叉号和块号(如果这是一次关系扩展请求,arg1 现在包含新增加块的块号)。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是 InvalidBackendId(-1)。arg6 为真表示一次关系扩展请求,为假表示正常读。arg7 为真表示在池中找到该缓冲区,为假表示没有找到。 + 当一次缓冲区读完成时触发的探针。arg0 和 arg1 包含该页的分支号和块号(如果这是一次关系扩展请求,arg1 现在包含新增加块的块号)。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是 InvalidBackendId(-1)。arg6 为真表示一次关系扩展请求,为假表示正常读。arg7 为真表示在池中找到该缓冲区,为假表示没有找到。 buffer-flush-start (ForkNumber, BlockNumber, Oid, Oid, Oid) - 在发出对一个共享缓冲区的任意写请求之前触发的探针。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。 + 在发出对一个共享缓冲区的任意写请求之前触发的探针。arg0 和 arg1 包含该页的分支号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。 @@ -5654,7 +5598,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, buffer-write-dirty-start (ForkNumber, BlockNumber, Oid, Oid, Oid) - 当一个服务器进程开始写一个脏缓冲区时触发的探针(如果这经常发生,表示太小,或需要调整后台写入器的控制参数)。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。 + 当一个服务器进程开始写一个脏缓冲区时触发的探针(如果这经常发生,表示太小,或需要调整后台写入器的控制参数)。arg0 和 arg1 包含该页的分支号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。 @@ -5672,13 +5616,13 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, wal-buffer-write-dirty-done () - 当一次脏 WAL 缓冲区完成时触发的探针。 + 当一次脏 WAL 缓冲区写入完成时触发的探针。 wal-insert (unsigned char, unsigned char) - 当一个 WAL 记录被插入时触发的探针。arg0 是该记录的资源管理者(rmid)。arg1 包含 info 标志。 + 当一个 WAL 记录被插入时触发的探针。arg0 是该记录的资源管理器(rmid)。arg1 包含 info 标志。 @@ -5690,31 +5634,31 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, smgr-md-read-start (ForkNumber, BlockNumber, Oid, Oid, Oid, int) - 当开始从一个关系读取一块时触发的探针。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。 + 当开始从一个关系读取一块时触发的探针。arg0 和 arg1 包含该页的分支号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。 smgr-md-read-done (ForkNumber, BlockNumber, Oid, Oid, Oid, int, int, int) - 当一次块读取完成时触发的探针。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。arg6 是实际读取的字节数,而 arg7 是请求读取的字节数(如果两者不同就意味着麻烦)。 + 当一次块读取完成时触发的探针。arg0 和 arg1 包含该页的分支号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。arg6 是实际读取的字节数,而 arg7 是请求读取的字节数(如果两者不同就意味着麻烦)。 smgr-md-write-start (ForkNumber, BlockNumber, Oid, Oid, Oid, int) - 当开始向一个关系中写入一个块时触发的探针。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。 + 当开始向一个关系中写入一个块时触发的探针。arg0 和 arg1 包含该页的分支号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。 smgr-md-write-done (ForkNumber, BlockNumber, Oid, Oid, Oid, int, int, int) - 当一个块写操作完成时触发的探针。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3和arg4 包含表空间、数据库和关系 OID来标识该关系。对于一个本地缓冲区,arg5 是创建临时关系的后端 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。arg6 是实际写的字节数,而 arg7 是要求写的字节数(如果这两者不同,则意味着麻烦)。 + 当一个块写操作完成时触发的探针。arg0 和 arg1 包含该页的分支号和块号。arg2、arg3和arg4 包含表空间、数据库和关系 OID来标识该关系。对于一个本地缓冲区,arg5 是创建临时关系的后端 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。arg6 是实际写的字节数,而 arg7 是要求写的字节数(如果这两者不同,则意味着麻烦)。 sort-start (int, bool, int, int, bool, int) - 当一次排序操作开始时触发的探针。arg0 指示是堆排序、索引排序或数据排序。arg1 为真表示强制唯一值。arg2 是键列数。arg3 是允许使用的工作内存大小(以千字节计)。如果要求随机访问排序结果,则 arg4 为真。arg5 为 0 时表示串行,为 1 时表示并行工作进程,为 2 时表示并行领导者。 + 当一次排序操作开始时触发的探针。arg0 指示是堆排序、索引排序或 datum 排序。arg1 为真表示强制唯一值。arg2 是键列数。arg3 是允许使用的工作内存大小(以千字节计)。如果要求随机访问排序结果,则 arg4 为真。arg5 为 0 时表示串行,为 1 时表示并行工作进程,为 2 时表示并行领导者。 @@ -5728,7 +5672,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, (char *, LWLockMode) 当成功获得一个 LWLock 时触发的探针。 arg0 是该 LWLock 所在的切片(Tranche)。 - arg1 所请求的锁模式,是排他或共享。 + arg1 是所请求的锁模式,是排他或共享。 @@ -5743,34 +5687,34 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, (char *, LWLockMode) 当一个 LWLock不是当即可用并且一个服务器进程因此开始等待该锁变为可用时触发的探针。 arg0 是该 LWLock 所在的切片(Tranche)。 - arg1 请求的锁模式,是排他或共享。 + arg1 是所请求的锁模式,是排他或共享。 lwlock-wait-done (char *, LWLockMode) 当一个进程从对一个 LWLock 的等待中被释放时(它实际还没有得到该锁)时触发的探针。arg0 是该 LWLock 所在的切片(Tranche)。 - arg1 所请求的锁模式,是排他或共享。 + arg1 是所请求的锁模式,是排他或共享。 lwlock-condacquire (char *, LWLockMode) 当调用者指定无需等待而成功获得一个 LWLock 时触发的探针。arg0 是该 LWLock 所在的切片(Tranche)。 - arg1 所请求的锁模式,是排他或共享。 + arg1 是所请求的锁模式,是排他或共享。 lwlock-condacquire-fail (char *, LWLockMode) 当调用者指定无需等待而没有成功获得一个 LWLock 时触发的探针。arg0 是该 LWLock 所在的切片(Tranche)。 - arg1 所请求的锁模式,是排他或共享。 + arg1 是所请求的锁模式,是排他或共享。 lock-wait-start (unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, LOCKMODE) - 当一个重量级锁(lmgr锁)的请求由于锁不可用开始等待时触发的探针。arg0 到 arg3 是标识被锁定对象的标签域。arg4 指示被锁对象的类型。arg5 表示被请求的锁类型。 + 当一个重量级锁(lmgr锁)的请求由于锁不可用开始等待时触发的探针。arg0 到 arg3 是标识被锁定对象的标签字段。arg4 指示被锁对象的类型。arg5 表示被请求的锁类型。 @@ -5791,7 +5735,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid,
- 定义用在探针参数中的类型 + 探针参数中使用的已定义类型 @@ -5885,7 +5829,7 @@ Total time (ns) 2312105013 - 你应该记住,DTrace 脚本需要细心地编写和调试,否则被收集的追踪信息可能会毫无意义。在大部分发现问题的情况中,它就是发生问题的部件,而不是底层系统。当讨论使用动态追踪发现的信息时,一定要附上使用的脚本以便其也被检查和讨论。 + 你应该记住,DTrace 脚本需要细心地编写和调试,否则被收集的追踪信息可能会毫无意义。在大多数发现问题的情况下,出错的是插桩,而不是底层系统。当讨论使用动态追踪发现的信息时,一定要附上使用的脚本以便其也被检查和讨论。 @@ -5901,7 +5845,7 @@ Total time (ns) 2312105013 - 决定探针名称以及探针可用的数据 + 决定探针名称以及要通过探针提供的数据 @@ -5915,7 +5859,7 @@ Total time (ns) 2312105013 - 如果pg_trace.h还不存在于包含该探针点的模块中,包括它,并且在源代码中期望的位置插入TRACE_POSTGRESQL探针宏 + 如果pg_trace.h尚未被包含该探针点的模块引用,则将它包含进来,并且在源代码中期望的位置插入TRACE_POSTGRESQL探针宏 @@ -5951,14 +5895,14 @@ Total time (ns) 2312105013 probe transaction__start(LocalTransactionId); - 注意探针名字中双下划线的使用。在一个使用探针的 DTrace 脚本中,双下划线需要被替换为一个连字符,因此 ,对用户而言transaction-start是文档名。 + 注意探针名字中双下划线的使用。在一个使用探针的 DTrace 脚本中,双下划线需要被替换为一个连字符,因此,文档中应向用户说明的名称是transaction-start - 在编译时,transaction__start被转换成一个宏调用TRACE_POSTGRESQL_TRANSACTION_START(注意这里是单下划线),可以通过包括头文件pg_trace.h获得。将宏调用加入到源代码中的合适位置。在这种情况下,看起来类似: + 在编译时,transaction__start被转换成一个名为TRACE_POSTGRESQL_TRANSACTION_START的宏(注意这里是单下划线),可以通过包含头文件pg_trace.h获得。将宏调用加入到源代码中的合适位置。在这种情况下,看起来类似: TRACE_POSTGRESQL_TRANSACTION_START(vxid.localTransactionId); @@ -5995,7 +5939,7 @@ TRACE_POSTGRESQL_TRANSACTION_START(vxid.localTransactionId); - 在大多数平台上,如果用编译了PostgreSQL,无论何时当控制经过一个追踪宏时,都会评估该宏的参数,即使没有进行追踪也会这样做。通常不需要担心你是否只在报告一些局部变量的值。但是要注意不要将开销大的函数调用放入参数中。如果你需要这样做,考虑通过检查追踪是否真的被启用来保护该宏: + 在大多数平台上,如果用编译了PostgreSQL,无论何时当控制经过一个追踪宏时,都会对该宏的参数求值,即使没有进行追踪也会这样做。如果只是报告少数局部变量的值,通常无需担心这一点。但是要注意不要将开销大的函数调用放入参数中。如果你需要这样做,考虑通过检查追踪是否真的被启用来保护该宏: if (TRACE_POSTGRESQL_TRANSACTION_START_ENABLED()) diff --git a/zh/13/mvcc.sgml b/zh/13/mvcc.sgml index 60e20afa..bcb841d0 100644 --- a/zh/13/mvcc.sgml +++ b/zh/13/mvcc.sgml @@ -4,7 +4,7 @@ 并发控制 - concurrency + 并发 @@ -15,7 +15,7 @@ 介绍 - Multiversion Concurrency Control + 多版本并发控制 @@ -23,7 +23,7 @@ - Serializable Snapshot Isolation + 可串行化快照隔离 @@ -50,7 +50,7 @@ 事务隔离 - transaction isolation + 事务隔离 @@ -61,11 +61,14 @@ (这并不奇怪,如果事务的效果必须与一次只运行一个事务保持一致,又怎么可能看到由相互作用引起的任何现象呢?) - 各隔离级别所禁止的现象如下: + + 在各个级别上被禁止的现象有: + + 脏读 - dirty read + 脏读 @@ -77,7 +80,7 @@ 不可重复读 - nonrepeatable read + 不可重复读 @@ -89,7 +92,7 @@ 幻读 - phantom read + 幻读 @@ -101,7 +104,7 @@ 串行化异常 - serialization anomaly + 串行化异常 @@ -114,7 +117,7 @@ - transaction isolation level + 事务隔离级别 SQL 标准以及 PostgreSQL 实现的事务隔离级别见 @@ -241,12 +244,12 @@ 读已提交隔离级别 - transaction isolation level - read committed + 事务隔离级别 + 读已提交 - read committed + 读已提交 @@ -292,7 +295,7 @@ 由于上述规则,更新命令可能看到一个不一致的快照:它能够看到并发更新命令在它试图更新的同一行上的效果, 却看不到这些命令对数据库中其他行的影响。这种行为使得读已提交模式不适合涉及复杂搜索条件的命令; - 不过,对于较简单的场景它恰到好处。例如,考虑将 100 美元从一个账户转到另一个账户: + 不过,对于较简单的场景它恰到好处。例如,考虑以如下事务更新银行余额: BEGIN; @@ -301,13 +304,13 @@ UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 7534; COMMIT; - 如果另一个事务并发地尝试更改账户 7534 的余额,我们显然希望第二条语句从该账户行的已更新版本开始。 + 如果两个这样的事务并发地尝试更改账户 12345 的余额,我们显然希望第二个事务从该账户行的已更新版本开始。 因为每个命令只影响一个预先确定的行,让它看到该行的已更新版本不会造成任何麻烦的不一致。 在读已提交模式下,更复杂的用法可能产生不理想的结果。例如,考虑一个 - DELETE 命令,它所处理的数据会被另一个命令同时加入和移出其筛选条件。 + DELETE 命令,另一个命令正在修改数据,使某些行开始满足其筛选条件、另一些行不再满足。 假设 website 是一个有两行的表,其中 website.hits 分别等于 910: @@ -315,7 +318,7 @@ COMMIT; BEGIN; UPDATE website SET hits = hits + 1; --- run from another session: DELETE FROM website WHERE hits = 10; +-- 从另一个会话运行: DELETE FROM website WHERE hits = 10; COMMIT; @@ -343,12 +346,12 @@ COMMIT; 可重复读隔离级别 - transaction isolation level - repeatable read + 事务隔离级别 + 可重复读 - repeatable read + 可重复读 @@ -400,9 +403,7 @@ ERROR: could not serialize access due to concurrent update 可重复读模式提供了严格的保证,即每个事务都看到数据库的一个完全稳定的视图。 不过,这个视图并不一定总能与同一级别并发事务的某种串行(一次一个)执行保持一致。 - 例如,即使该级别上的只读事务可能看到一条控制记录被更新,表明某个批处理已经完成, - 但它并不一定能看到作为该批处理逻辑组成部分的某条明细记录, - 因为它读到的是控制记录的较早版本。如果不仔细使用显式锁来阻塞冲突事务, + 例如,即使是该级别的只读事务,也可能看到一条表明某批次已完成的控制记录,却看不到逻辑上属于该批次的某条明细记录,因为创建该明细记录的事务读取了控制记录的较早版本。如果不仔细使用显式锁来阻塞冲突事务, 试图依靠运行在这一隔离级别的事务来强制业务规则,往往无法正确工作。 @@ -410,7 +411,7 @@ ERROR: could not serialize access due to concurrent update 可重复读隔离级别是通过一种技术实现的,这种技术在学术数据库文献中以及某些其他数据库产品中被称为 快照隔离。与使用会降低并发性的传统加锁技术的系统相比, 其行为和性能可能会表现出差异。有些其他系统甚至把可重复读和快照隔离作为两个行为不同的独立隔离级别提供。 - 用来区分这两种技术的允许现象,直到 SQL 标准制定之后才被数据库研究人员正式定义,因此超出了本手册的范围。 + 用来区分这两种技术的允许现象,直到 SQL 标准制定之后才被数据库研究人员正式定义,并且超出了本手册的范围。 完整讨论请参阅 @@ -426,20 +427,20 @@ ERROR: could not serialize access due to concurrent update 可串行化隔离级别 - transaction isolation level - serializable + 事务隔离级别 + 可串行化 - serializable + 可串行化 - predicate locking + 谓词锁 - serialization anomaly + 串行化异常 @@ -469,13 +470,13 @@ ERROR: could not serialize access due to read/write dependencies among transact 当依赖可串行化事务来防止异常时,重要的是:从永久用户表读取的任何数据,在读取它的事务成功提交之前, - 都不应视为有效。即使对于只读事务也是如此;唯一的例外是可推迟只读事务中读取的数据, + 都不应视为有效。即使对于只读事务也是如此;唯一的例外是可延迟只读事务中读取的数据, 它一经读出就可视为有效,因为这种事务会等到能够获取一个保证不存在此类问题的快照后才开始读取数据。 在所有其他情况下,应用不能依赖后来被中止事务中读到的结果;相反,应重试事务直到成功。 - 为了保证真正的可串行化,PostgreSQL 使用了谓词锁, + 为了保证真正的可串行性,PostgreSQL 使用了谓词锁, 也就是说,系统会保留一些锁,以便判断某个写操作如果先发生,是否会影响并发事务先前读取的结果。 在 PostgreSQL 中,这些锁不会造成任何阻塞,因此会参与形成死锁。 它们用于识别并标记并发可串行化事务之间的依赖关系,而这些依赖在某些组合下可能导致串行化异常。 @@ -497,7 +498,7 @@ ERROR: could not serialize access due to read/write dependencies among transact - 持续使用可串行化事务可以简化开发。任何一组成功提交的并发可串行化事务,都保证与把它们一次一个运行的效果相同;这意味着,如果你能够证明某个事务在单独运行时会做正确的事,那么即使不了解其他事务会做什么,也可以相信它在任何可串行化事务的混合执行中也会做正确的事,否则它就不会成功提交。重要的是,采用这种技术的环境应当有一套通用机制来处理串行化失败(其 SQLSTATE 值总是 '40001'),因为很难准确预测究竟哪些事务会对读/写依赖关系有贡献,并因此需要被回滚来防止串行化异常。监视读/写依赖关系会带来开销,被串行化失败中止的事务重新启动也会带来开销;但在把这些开销与显式锁以及 SELECT FOR UPDATESELECT FOR SHARE 所涉及的成本和阻塞进行权衡之后,可串行化事务在某些环境中仍然是性能最佳的选择。 + 统一采用可串行化事务可以简化开发。任何一组成功提交的并发可串行化事务,都保证与把它们一次一个运行的效果相同;这意味着,如果你能够证明某个事务在单独运行时会做正确的事,那么即使不了解其他事务会做什么,也可以相信它在任何可串行化事务的混合执行中也会做正确的事,否则它就不会成功提交。重要的是,采用这种技术的环境应当有一套通用机制来处理串行化失败(其 SQLSTATE 值总是 '40001'),因为很难准确预测究竟哪些事务会对读/写依赖关系有贡献,并因此需要被回滚来防止串行化异常。监视读/写依赖关系会带来开销,被串行化失败中止的事务重新启动也会带来开销;但在把这些开销与显式锁以及 SELECT FOR UPDATESELECT FOR SHARE 所涉及的成本和阻塞进行权衡之后,可串行化事务在某些环境中仍然是性能最佳的选择。 @@ -541,7 +542,7 @@ ERROR: could not serialize access due to read/write dependencies among transact - 当系统因谓词锁表内存不足而被迫把多个页级谓词锁合并为单个关系级谓词锁时,串行化失败的比例可能会上升。你可以通过增加 来避免这种情况。 + 当系统因谓词锁表内存不足而被迫把多个页级谓词锁合并为单个关系级谓词锁时,串行化失败的比例可能会上升。你可以通过增加 和/或 来避免这种情况。 @@ -565,7 +566,7 @@ ERROR: could not serialize access due to read/write dependencies among transact 显式锁定 - lock + @@ -662,7 +663,7 @@ ERROR: could not serialize access due to read/write dependencies among transact CREATE STATISTICSCOMMENT ONREINDEX CONCURRENTLY, 以及某些 ALTER INDEX - 和 ALTER TABLE 变体会获取这种锁 + 和 ALTER TABLE 变体获取这种锁 (完整详情见 )。 @@ -927,7 +928,7 @@ ERROR: could not serialize access due to read/write dependencies among transact - 行为与 FOR SHARE 类似,不过锁更弱:SELECT FOR UPDATE 会被阻塞,但 SELECT FOR NO KEY UPDATE 不会。键共享锁会阻塞其他事务执行会修改键值的 DELETEUPDATE,但不会阻塞其他 UPDATE,也不会阻止 SELECT FOR NO KEY UPDATESELECT FOR SHARESELECT FOR KEY SHARE。 + 行为与 FOR SHARE 类似,不过锁更弱:SELECT FOR UPDATE 会被阻塞,但 SELECT FOR NO KEY UPDATE 不会。键共享锁会阻塞其他事务执行 DELETE 或任何会修改键值的 UPDATE,但不会阻塞其他 UPDATE,也不会阻止 SELECT FOR NO KEY UPDATESELECT FOR SHARESELECT FOR KEY SHARE @@ -1005,7 +1006,7 @@ ERROR: could not serialize access due to read/write dependencies among transact 死锁 - deadlock + 死锁 @@ -1048,12 +1049,12 @@ UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 22222; 咨询锁 - advisory lock + 咨询锁 - lock - advisory + + 咨询 @@ -1085,12 +1086,12 @@ UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 22222; 在某些使用咨询锁的方法中,特别是涉及显式排序和 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(id) FROM foo WHERE id = 12345; -- 可以 +SELECT pg_advisory_lock(id) FROM foo WHERE id > 12345 LIMIT 100; -- 危险! SELECT pg_advisory_lock(q.id) FROM ( SELECT id FROM foo WHERE id > 12345 LIMIT 100 -) q; -- ok +) q; -- 可以 在上面的查询中,第二种形式是危险的,因为不能保证在执行加锁函数之前先应用 LIMIT。 这可能导致获取了一些应用并未预期的锁,因此应用也不会去释放它们(直到会话结束)。 @@ -1108,12 +1109,12 @@ SELECT pg_advisory_lock(q.id) FROM 应用级别的数据一致性检查 - 在读已提交事务下,想要通过业务规则强制数据一致性非常困难,因为数据视图会随每条语句而变化, + 用读已提交事务强制执行有关数据完整性的业务规则非常困难,因为数据视图会随每条语句而变化, 而且一旦发生写冲突,即使是单条语句也未必局限于该语句自己的快照。 - 虽然可重复读事务在整个执行期间都具有稳定的数据视图,但在使用 MVCC 快照进行数据一致性检查时,还存在一个微妙问题,即所谓的读/写冲突。如果一个事务写入数据,而并发事务试图读取相同的数据(无论是在写入之前还是之后),它都看不到另一个事务的工作。于是,读取者看起来就像是先执行的一方,而不管究竟是谁先启动,也不管谁先提交。如果事情只停留在这一步,就没有问题;但如果读取者还写入了数据,而这些数据又被另一个并发事务读取,那么现在就会有一个事务看起来像是在前面提到的任一事务之前执行。如果看起来最后执行的事务实际上最先提交,就很容易在事务执行顺序图中形成一个环。一旦出现这样的环,不借助额外机制,一致性检查就无法正确工作。 + 虽然可重复读事务在整个执行期间都具有稳定的数据视图,但在使用 MVCC 快照进行数据一致性检查时,还存在一个微妙问题,即所谓的读/写冲突。如果一个事务写入数据,而并发事务试图读取相同的数据(无论是在写入之前还是之后),它都看不到另一个事务的工作。于是,读取者看起来就像是先执行的一方,而不管究竟是谁先启动,也不管谁先提交。如果事情只停留在这一步,就没有问题;但如果读取者还写入了数据,而这些数据又被另一个并发事务读取,那么现在就会有一个事务看起来像是在前面提到的任一事务之前执行。如果看起来最后执行的事务实际上最先提交,就很容易在事务执行顺序图中形成一个环。一旦出现这样的环,不借助额外机制,完整性检查就无法正确工作。 @@ -1130,7 +1131,7 @@ SELECT pg_advisory_lock(q.id) FROM - 使用这种技术时,如果应用软件通过某个框架运行,并由该框架自动重试因串行化错误而回滚的事务,就可以避免给应用程序员带来不必要的负担。把 default_transaction_isolation 设置为 serializable 可能是个好主意。通过在触发器中检查事务隔离级别来采取某些措施,以确保不会因为疏忽或为了绕过完整性检查而使用其他事务隔离级别,也是明智的。 + 使用这种技术时,如果应用软件通过某个框架运行,并由该框架自动重试因串行化失败而回滚的事务,就可以避免给应用程序员带来不必要的负担。把 default_transaction_isolation 设置为 serializable 可能是个好主意。通过在触发器中检查事务隔离级别来采取某些措施,以确保不会因为疏忽或为了绕过完整性检查而使用其他事务隔离级别,也是明智的。 @@ -1139,14 +1140,14 @@ SELECT pg_advisory_lock(q.id) FROM - 利用可串行化事务提供的这一层完整性保护,尚未扩展到热备模式()或逻辑副本。 - 因此,使用热备或逻辑复制的用户可能希望在主库上使用可重复读和显式锁定。 + 利用可串行化事务提供的这一层完整性保护,尚未扩展到热备模式()。 + 因此,使用热备的用户可能希望在主库上使用可重复读和显式锁定。 - 使用显式锁定强制一致性 + 使用显式阻塞锁强制一致性 当存在非可串行化写入时,要确保某一行当前仍然有效,并保护它不受并发更新影响, @@ -1169,7 +1170,7 @@ SELECT pg_advisory_lock(q.id) FROM 在非可串行化的 MVCC 环境下,全局有效性检查需要额外考虑。 - 例如,一个银行应用可能希望检查一个表中的所有收入总和等于另一个表中的所有支出总和, + 例如,一个银行应用可能希望检查一个表中的贷方金额总和等于另一个表中的借方金额总和, 而这两个表都在被活跃更新。在读已提交模式下,比较两个连续的 SELECT sum(...) 命令的结果并不可靠,因为第二个查询很可能会包含第一个查询没有统计到的事务提交结果。 在单个可重复读事务中完成这两次求和,只能准确反映在该可重复读事务开始之前已提交事务的效果 @@ -1217,18 +1218,21 @@ SELECT pg_advisory_lock(q.id) FROM 锁定和索引 - index - locks + 索引 + - 虽然PostgreSQL提供了对表数据的非阻塞读写访问,但目前并非所有已实现的索引访问方法都具备这种能力。下面按索引类型说明PostgreSQL的处理方式: + + 尽管 PostgreSQL 为表数据提供了非阻塞的读写访问,但 PostgreSQL 当前实现的索引访问方法并不是每一种都能提供非阻塞的读写访问。各种索引类型的处理方式如下: + + B-树、GiSTSP-GiST 索引 - 读写访问使用短期的页级共享/排他锁。每个索引行在被取出或插入之后,锁都会立即释放。这些索引类型在不存在死锁条件的前提下提供了最高的并发性。 + 读写访问使用短期的页级共享/排他锁。每个索引行在被取出或插入之后,锁都会立即释放。这些索引类型提供最高的并发性,并且不会产生死锁。 @@ -1250,7 +1254,7 @@ SELECT pg_advisory_lock(q.id) FROM - 读写访问使用短期的页级共享/排他锁。每个索引行在被取出或插入之后,锁都会立即释放。但要注意,插入一个 GIN 索引值通常会导致每行产生多个索引键插入,因此 GIN 可能为了插入单个值而做大量工作。 + 读写访问使用短期的页级共享/排他锁。每个索引行在被取出或插入之后,锁都会立即释放。但要注意,插入一个使用 GIN 索引的值通常会导致每行产生多个索引键插入,因此 GIN 可能为了插入单个值而做大量工作。 diff --git a/zh/13/oid2name.sgml b/zh/13/oid2name.sgml index 07413f40..501fb9fd 100644 --- a/zh/13/oid2name.sgml +++ b/zh/13/oid2name.sgml @@ -8,7 +8,7 @@ oid2name 1 - Application + 应用程序 diff --git a/zh/13/pageinspect.sgml b/zh/13/pageinspect.sgml index 797add6f..05dde72a 100644 --- a/zh/13/pageinspect.sgml +++ b/zh/13/pageinspect.sgml @@ -279,7 +279,8 @@ btpo_flags | 3 - bt_page_items返回 B-树索引页中所有项的详细信息。例如: + bt_page_items返回 B-树索引页上所有项的详细信息。例如: + test=# SELECT itemoffset, ctid, itemlen, nulls, vars, data, dead, htid, tids[0:2] AS some_tids FROM bt_page_items('tenk2_hundred', 5); itemoffset | ctid | itemlen | nulls | vars | data | dead | htid | some_tids @@ -298,19 +299,21 @@ test=# SELECT itemoffset, ctid, itemlen, nulls, vars, data, dead, htid, tids[0:2 12 | (16,8292) | 616 | f | f | 2e 00 00 00 00 00 00 00 | f | (0,27) | {"(0,27)","(1,13)"} 13 | (16,8292) | 616 | f | f | 2f 00 00 00 00 00 00 00 | f | (4,17) | {"(4,17)","(4,21)"} (13 rows) -这是一个 B-树叶页。所有指向表的元组恰好都是 posting list 元组(每个都存储了 100 个 6 字节的 TID)。此外还有一个high key元组,位于itemoffset编号 1 处。ctid在本例中用于存储每个元组的编码信息,不过叶页元组通常会将堆 TID 直接存放在ctid字段中。tids是作为 posting list 存储的 TID 列表。 + + 这是一个 B-树叶页。所有指向表的元组恰好都是倒排列表元组(每个都存储了 100 个 6 字节的 TID)。此外,在itemoffset 编号 1 处还有一个高键元组。这个示例中,ctid用于存储每个元组的编码信息,不过叶页元组通常会直接在ctid字段中存储一个堆 TID。tids是作为倒排列表存储的 TID 列表。 + 在内部页(此处未显示)中,ctid的块号部分是一个downlink(下行链接),也就是该索引中另一页的块号。ctid的偏移部分(第二个数字)存储着关于该元组的编码信息,例如实际存在的列数(后缀截断可能移除了不需要的后缀列)。被截断的列被视为具有minus infinity值。 - htid显示该元组的堆 TID,而不考虑底层元组表示形式。这个值可能与ctid相同,也可能是从 posting list 元组以及内部页元组所使用的替代表示中解码出来的。内部页中的元组通常会把实现层面的堆 TID 列截断掉,这会表现为htid值为 NULL。 + htid显示该元组的堆 TID,而不考虑底层元组表示形式。这个值可能与ctid相同,也可能是从倒排列表元组以及内部页元组所使用的替代表示中解码出来的。内部页中的元组通常会把实现层面的堆 TID 列截断掉,这会表现为htid值为 NULL。 - 请注意,任何非最右页(即btpo_next字段值非零的页面)的第一项都是该页的high key,这意味着它的data充当该页上所有项的上界,而它的ctid字段并不指向另一个块。另外,在内部页上,第一个真正的数据项(第一个不是high key的项)一定会把所有列都截断掉,因此其data字段中没有实际值。不过,这样的项在其ctid字段中确实有一个有效的下行链接。 + 请注意,任何非最右页(即btpo_next字段值非零的页面)的第一项都是该页的高键,这意味着它的data充当该页上所有项的上界,而它的ctid字段并不指向另一个块。另外,在内部页上,第一个真正的数据项(第一个不是高键的项)一定会把所有列都截断掉,因此其data字段中没有实际值。不过,这样的项在其ctid字段中确实有一个有效的下行链接。 - 关于 B-树索引结构的更多细节,参见。关于去重和 posting list 的更多细节,参见。关于去重和倒排列表的更多细节,参见 diff --git a/zh/13/parallel.sgml b/zh/13/parallel.sgml index 6d88bc36..b9f4110c 100644 --- a/zh/13/parallel.sgml +++ b/zh/13/parallel.sgml @@ -193,7 +193,7 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%'; - Parallel Append + 并行追加 每当 PostgreSQL 需要将来自多个源的行合并成一个结果集时,它就会使用 AppendMergeAppend 计划节点。这种情况常见于实现 UNION ALL 或扫描分区表时。这样的节点和其他任何计划中的情形一样,也可以用于并行计划。不过,在并行计划中,规划器也可能改用 Parallel Append 节点。 diff --git a/zh/13/pgcrypto.sgml b/zh/13/pgcrypto.sgml index 79eace2e..b27b6928 100644 --- a/zh/13/pgcrypto.sgml +++ b/zh/13/pgcrypto.sgml @@ -214,14 +214,14 @@ gen_salt(type text [, iter_count integer ]) returns text - type参数指定哈希算法。 + type参数指定 hash 算法。 接受的类型有:desxdesmd5bf iter_count参数允许用户为支持该参数的算法指定迭代次数。 - 次数越高,密码哈希所需时间越长,从而破解它所需时间也越长。 - 不过,如果次数过高,计算一个哈希可能需要数年时间 — 这显然不切实际。 + 次数越高,对密码进行 hash 所需的时间越长,从而破解它所需时间也越长。 + 不过,如果次数过高,计算一个 hash 可能需要数年时间 — 这显然不切实际。 若省略iter_count参数,则使用默认迭代次数。 允许的iter_count值取决于算法,如所示。 @@ -259,24 +259,24 @@ gen_salt(type text [, iter_count integer ]) returns text - 为了选择合适的迭代次数,可以考虑原始 DES crypt 在当时硬件上的设计速度是每秒 4 次哈希。 - 低于每秒 4 次哈希可能会影响可用性,而高于每秒 100 次哈希则很可能过快。 + 为了选择合适的迭代次数,可以考虑原始 DES crypt 在当时硬件上的设计速度是每秒 4 次 hash。 + 低于每秒 4 次 hash 可能会影响可用性,而高于每秒 100 次 hash 则很可能过快。 - 概述了不同哈希算法之间的相对速度差异。 + 概述了不同 hash 算法之间的相对速度差异。 该表展示了在 8 字符密码上尝试所有字符组合所需的时间,假定密码只包含小写字母, 或者包含大小写字母和数字。在crypt-bf条目中, 斜杠后的数字是gen_saltiter_count参数值。
- 哈希算法速度 + Hash 算法速度 算法 - 每秒哈希次数 + 每秒 hash 次数 针对[a-z] 针对[A-Za-z0-9] 相对于md5 hash的耗时倍数 diff --git a/zh/13/pgstandby.sgml b/zh/13/pgstandby.sgml index 76be2c6f..df77336e 100644 --- a/zh/13/pgstandby.sgml +++ b/zh/13/pgstandby.sgml @@ -8,7 +8,7 @@ pg_standby 1 - Application + 应用程序 diff --git a/zh/13/plhandler.sgml b/zh/13/plhandler.sgml index 37493d95..40067ef0 100644 --- a/zh/13/plhandler.sgml +++ b/zh/13/plhandler.sgml @@ -17,11 +17,11 @@ - 调用处理器与其他函数一样被调用:它会接收一个指向 FunctionCallInfoBaseData struct 的指针,其中包含参数值以及被调用函数的相关信息;同时它还应返回一个 Datum 结果(如果希望返回 SQL 空值结果,还可以设置 isnull 字段,也就是 FunctionCallInfoBaseData 结构体中的该字段)。调用处理器与普通被调函数之间的区别在于,flinfo->fn_oid 字段在 FunctionCallInfoBaseData 结构体中保存的是实际要调用函数的 OID,而不是调用处理器本身的 OID。调用处理器必须使用这个字段来判定要执行哪个函数。另外,传入的参数列表是按照目标函数而不是调用处理器的声明来设置的。 + 调用处理器与其他函数一样被调用:它会接收一个指向 FunctionCallInfoBaseData struct 的指针,其中包含参数值以及被调用函数的相关信息;同时它还应返回一个 Datum 结果(如果希望返回 SQL 空值结果,还需要设置 isnull 字段,也就是 FunctionCallInfoBaseData 结构体中的该字段)。调用处理器与普通被调函数之间的区别在于,flinfo->fn_oid 字段在 FunctionCallInfoBaseData 结构体中保存的是实际要调用函数的 OID,而不是调用处理器本身的 OID。调用处理器必须使用这个字段来判定要执行哪个函数。另外,传入的参数列表是按照目标函数而不是调用处理器的声明来设置的。 - 调用处理器必须从系统目录 pg_proc 中取出该函数的条目,并分析被调用函数的参数类型和返回类型。该函数的 AS 子句可在其 CREATE FUNCTION 命令对应的 prosrc 列里找到,也就是 pg_proc 行中的该列。这里通常是一段过程语言源文本,但理论上也可以是其他内容,例如某个文件的路径名,或者任何能详细告诉调用处理器该做什么的信息。 + 调用处理器必须从系统目录 pg_proc 中取出该函数的条目,并分析被调用函数的参数类型和返回类型。该函数的 CREATE FUNCTION 命令中的 AS 子句内容,保存在 pg_proc 对应行的 prosrc 列中。这里通常是一段过程语言源文本,但理论上也可以是其他内容,例如某个文件的路径名,或者任何能详细告诉调用处理器该做什么的信息。 @@ -54,7 +54,7 @@ plsample_call_handler(PG_FUNCTION_ARGS) if (CALLED_AS_TRIGGER(fcinfo)) { /* - * Called as a trigger function + * 作为触发器函数调用 */ TriggerData *trigdata = (TriggerData *) fcinfo->context; @@ -63,7 +63,7 @@ plsample_call_handler(PG_FUNCTION_ARGS) else { /* - * Called as a function + * 作为函数调用 */ retval = ... @@ -92,7 +92,7 @@ CREATE LANGUAGE plsample 验证器函数通常应遵循 参数:如果它被关闭,就应跳过任何开销高昂或依赖上下文的检查。如果该语言允许在编译时执行代码,验证器还必须抑制会诱发此类执行的检查。特别是,pg_dump 会关闭这个参数,这样它就可以装载过程语言函数,而不必担心函数体对其他数据库对象的副作用或依赖关系。(正因为有这一要求,调用处理器不应假设验证器已经完整检查了函数。提供验证器的目的,并不是让调用处理器省略检查,而是在 CREATE FUNCTION 命令中存在明显错误时立即通知用户。)虽然究竟检查哪些内容主要由验证器函数自行决定,但要注意,核心 CREATE FUNCTION 代码只会执行附加到函数上的 SET 子句,前提是 check_function_bodies 打开。因此,当 check_function_bodies 关闭时,那些结果可能受 GUC 参数影响的检查肯定都应跳过,以避免在恢复转储时出现虚假的失败。 + linkend="guc-check-function-bodies"/> 参数:如果它被关闭,就应跳过任何开销高昂或依赖上下文的检查。如果该语言允许在编译时执行代码,验证器还必须抑制会诱发此类执行的检查。特别是,pg_dump 会关闭这个参数,这样它就可以装载过程语言函数,而不必担心副作用或函数体对其他数据库对象的依赖关系。(正因为有这一要求,调用处理器不应假设验证器已经完整检查了函数。提供验证器的目的,并不是让调用处理器省略检查,而是在 CREATE FUNCTION 命令中存在明显错误时立即通知用户。)虽然究竟检查哪些内容主要由验证器函数自行决定,但要注意,只有在 check_function_bodies 打开时,核心 CREATE FUNCTION 代码才会执行函数附带的 SET 子句。因此,当 check_function_bodies 关闭时,那些结果可能受 GUC 参数影响的检查肯定都应跳过,以避免在恢复转储时出现虚假的失败。 diff --git a/zh/13/plperl.sgml b/zh/13/plperl.sgml index 5f276157..f28bb40c 100644 --- a/zh/13/plperl.sgml +++ b/zh/13/plperl.sgml @@ -12,7 +12,7 @@ - PL/Perl 是一种可载入的过程语言,它允许使用 + PL/Perl 是一种可加载的过程语言,它允许使用 Perl 编程语言编写 PostgreSQL 函数和过程。 @@ -31,8 +31,7 @@ - 如果把该语言安装到 template1 中,之后创建的所有 - 数据库都会自动安装该语言。 + 如果把某种语言安装到template1中,之后创建的所有数据库都会自动安装该语言。 @@ -48,14 +47,24 @@ PL/Perl 函数和参数 - 要创建 PL/Perl 语言函数,请使用标准的 语法: + + 要用 PL/Perl 语言创建一个函数,可使用标准的 + 语法: + + CREATE FUNCTION funcname (argument-types) RETURNS return-type --- function attributes can go here +-- 函数属性可以写在这里 AS $$ - # PL/Perl function body goes here + # PL/Perl 函数体写在这里 $$ LANGUAGE plperl; -函数体就是普通的 Perl 代码。实际上,PL/Perl 的衔接代码会将其包装在一个 Perl 子例程中。PL/Perl 函数在标量上下文中调用,因此不能返回列表。可以通过返回引用来返回非标量值(数组、记录和集合),详见下文。 + + + 函数的主体就是普通的 Perl 代码。事实上,PL/Perl 的粘合代码会把它 + 包裹在一个 Perl 子程序中。PL/Perl 函数在标量上下文中被调用,因此 + 不能返回列表。如下文所述,可以通过返回引用来返回 + 非标量值(数组、记录和集合)。 + 在 PL/Perl 过程中,Perl 代码返回的任何值都会被忽略。 @@ -66,7 +75,7 @@ $$ LANGUAGE plperl; DO $$ - # PL/Perl code + # PL/Perl 代码 $$ LANGUAGE plperl; @@ -124,15 +133,14 @@ $$ LANGUAGE plperl; 如果一个 SQL 空值空值in PL/Perl被传给一个函数,在 - Perl 中该参数值将呈现为undefined。上述函数定义对于 - 空输入的行为并不理想(实际上,它会把它们当作零)。我们可以在函数 + sortas="PL/Perl">在 PL/Perl 中被传给一个函数,在 + Perl 中该参数值将呈现为未定义。上述函数定义对于 + 空值输入的行为并不理想(实际上,它会把它们当作零)。我们可以在函数 定义中添加 STRICT,让 PostgreSQL 采取更合理的做法:如果传入空值, - 函数将根本不会被调用,而是自动返回空结果。另一种方式是在函数体中 + 函数将根本不会被调用,而是自动返回空值结果。另一种方式是在函数体中 检查未定义输入。例如,假设我们希望在 - perl_max 的两个参数中一个为空、另一个非空时, - 返回非空参数而不是空值: + perl_max 的两个参数中一个为空值、另一个非空值时,返回非空值参数而不是空值: CREATE FUNCTION perl_max (integer, integer) RETURNS integer AS $$ @@ -174,7 +182,7 @@ $$ LANGUAGE plperl; bool_plperl 扩展提供了合适的转换。要使用它, 请先安装该扩展: -CREATE EXTENSION bool_plperl; -- or bool_plperlu for PL/PerlU +CREATE EXTENSION bool_plperl; -- 对于 PL/PerlU,则使用 bool_plperlu 然后对接收或返回 bool 的 PL/Perl 函数使用 TRANSFORM 函数属性,例如: @@ -187,7 +195,7 @@ AS $$ $$ LANGUAGE plperl; 应用该转换后,Perl 会将 bool 参数视为 - 1 或空值,从而能正确表示真或假。如果函数结果类型为 + 1 或空字符串,从而能正确表示真或假。如果函数结果类型为 bool,则其真或假取决于 Perl 是否会将返回值求值为真。 对函数内部执行的 SPI 查询,其布尔查询参数和结果也会进行类似的转换 ()。 @@ -220,12 +228,12 @@ CREATE OR REPLACE FUNCTION concat_array_elements(text[]) RETURNS TEXT AS $$ my $result = ""; return undef if (!defined $arg); - # as an array reference + # 作为数组引用 for (@$arg) { $result .= $_; } - # also works as a string + # 也可以作为字符串使用 $result .= $arg; return $result; @@ -236,7 +244,8 @@ SELECT concat_array_elements(ARRAY['PL','/','Perl']); - 多维数组会以所有 Perl 程序员都熟悉的方式,表示为对低维数组引用的引用。 + 多维数组按 Perl 程序员熟悉的方式表示为指向较低维数组的引用, + 而这些数组的元素又是引用。 @@ -345,11 +354,11 @@ SELECT * FROM perl_set(); 如果希望在代码中使用 strict 编译指示,可以有几种 选择。对于临时的全局用法,可以 SET - plperl.use_strict 为 true。这会影响后续编译的 + plperl.use_strict 为真。这会影响后续编译的 PL/Perl 函数,但不会影响当前会话中已经编译的 函数。对于永久的全局用法,可以在 postgresql.conf 文件中将 - plperl.use_strict 设为 true。 + plperl.use_strict 设为真。 @@ -402,7 +411,7 @@ use strict; spi_exec_query(query [, limit]) spi_exec_query - in PL/Perl + 在 PL/Perl 中 @@ -416,11 +425,19 @@ use strict; -只有在确定结果集会比较小时,才应使用此命令。下面是一个查询(SELECT 命令)的示例,指定了可选的最大行数: +只有在确定结果集会比较小时,才应使用此命令。下面是一个带可选最大行数的查询(SELECT 命令)示例: + + $rv = spi_exec_query('SELECT * FROM my_table', 5); -这会返回最多 5 行,来自表 my_table。如果 my_table 包含列 my_column,就可以取得结果中第 $i 行的该列值,方法如下: + + 这样会从表 my_table 返回最多 5 行。如果 + my_table 有一列 my_column, + 可以像下面这样从结果的第 $i 行取得该值: + $foo = $rv->{rows}[$i]->{my_column}; -要取得 SELECT 查询返回的总行数,可以这样做: + + 可以这样访问 SELECT 查询返回的总行数: + $nrows = $rv->{processed} @@ -478,21 +495,21 @@ SELECT * FROM test_munge(); spi_query(command) spi_query - in PL/Perl + 在 PL/Perl 中 spi_fetchrow(cursor) spi_fetchrow - in PL/Perl + 在 PL/Perl 中 spi_cursor_close(cursor) spi_cursor_close - in PL/Perl + 在 PL/Perl 中 @@ -512,7 +529,7 @@ CREATE OR REPLACE FUNCTION lotsa_md5 (INTEGER) RETURNS SETOF foo_type AS $$ my $file = '/usr/share/dict/words'; my $t = localtime; elog(NOTICE, "opening file $file at $t" ); - open my $fh, '<', $file # ooh, it's a file access! + open my $fh, '<', $file # 注意,这里访问了文件! or elog(ERROR, "cannot open $file for reading: $!"); my @words = <$fh>; close $fh; @@ -551,40 +568,55 @@ SELECT * from lotsa_md5(500); spi_prepare(command, argument types) spi_prepare - in PL/Perl + 在 PL/Perl 中 spi_query_prepared(plan, arguments) spi_query_prepared - in PL/Perl + 在 PL/Perl 中 spi_exec_prepared(plan [, attributes], arguments) spi_exec_prepared - in PL/Perl + 在 PL/Perl 中 spi_freeplan(plan) spi_freeplan - in PL/Perl + 在 PL/Perl 中 - spi_preparespi_query_preparedspi_exec_prepared,以及 spi_freeplan 实现相同的功能,但用于预备查询。spi_prepare 接受包含编号参数占位符($1、$2 等)的查询字符串,以及由参数类型字符串组成的列表: + spi_preparespi_query_prepared、 + spi_exec_preparedspi_freeplan + 提供相同的功能,但用于预备查询。spi_prepare + 接受一个带编号参数占位符($1、$2 等)的查询字符串,以及参数类型的 + 字符串列表: + $plan = spi_prepare('SELECT * FROM test WHERE id > $1 AND name = $2', 'INTEGER', 'TEXT'); -调用 spi_prepare 预备查询计划后,就可以使用该计划代替查询字符串。可以将其用于 spi_exec_prepared,其结果与以下函数返回的结果相同:spi_exec_query;也可以用于 spi_query_prepared,它返回游标,行为与 spi_query 完全相同。随后可以将该游标传给 spi_fetchrowspi_exec_prepared 可选的第二个参数是属性哈希引用;目前唯一支持的属性是 limit,用于设置查询返回的最大行数。省略 limit 或将其指定为零,表示不限制行数。 + + 一旦通过调用 spi_prepare 准备好查询计划,就可以用它 + 代替字符串查询。可以在 spi_exec_prepared 中使用, + 此时结果与 spi_exec_query 返回的结果相同;也可以在 + spi_query_prepared 中使用,它会像 + spi_query 一样返回一个游标,随后可传给 + spi_fetchrowspi_exec_prepared + 的可选第二个参数是属性哈希引用;目前唯一支持的属性是 + limit,它用于设置查询返回的最大行数。省略 + limit 或将其指定为零时,不会限制返回行数。 + - 预处理查询的优点在于,一个准备好的计划可以用于多次查询执行。当计划 + 预备查询的优点在于,一个准备好的计划可以用于多次查询执行。当计划 不再需要时,可以用 spi_freeplan 将其释放: CREATE OR REPLACE FUNCTION init() RETURNS VOID AS $$ @@ -660,14 +692,14 @@ SELECT release_hosts_query(); spi_commit() spi_commit - in PL/Perl + 在 PL/Perl 中 spi_rollback() spi_rollback - in PL/Perl + 在 PL/Perl 中 @@ -706,7 +738,7 @@ CALL transaction_test1(); - PL/Perl 中的工具函数 + PL/Perl 中的辅助函数 @@ -714,7 +746,7 @@ CALL transaction_test1(); elog(level, msg) elog - in PL/Perl + 在 PL/Perl 中 @@ -739,7 +771,7 @@ CALL transaction_test1(); quote_literal(string) quote_literal - in PL/Perl + 在 PL/Perl 中 @@ -759,7 +791,7 @@ CALL transaction_test1(); quote_nullable(string) quote_nullable - in PL/Perl + 在 PL/Perl 中 @@ -777,7 +809,7 @@ CALL transaction_test1(); quote_ident(string) quote_ident - in PL/Perl + 在 PL/Perl 中 @@ -795,7 +827,7 @@ CALL transaction_test1(); decode_bytea(string) decode_bytea - in PL/Perl + 在 PL/Perl 中 @@ -812,7 +844,7 @@ CALL transaction_test1(); encode_bytea(string) encode_bytea - in PL/Perl + 在 PL/Perl 中 @@ -828,7 +860,7 @@ CALL transaction_test1(); encode_array_literal(array) encode_array_literal - in PL/Perl + 在 PL/Perl 中 @@ -850,7 +882,7 @@ CALL transaction_test1(); encode_typed_literal(value, typename) encode_typed_literal - in PL/Perl + 在 PL/Perl 中 @@ -867,7 +899,7 @@ CALL transaction_test1(); encode_array_constructor(array) encode_array_constructor - in PL/Perl + 在 PL/Perl 中 @@ -887,7 +919,7 @@ CALL transaction_test1(); looks_like_number(string) looks_like_number - in PL/Perl + 在 PL/Perl 中 @@ -906,11 +938,15 @@ CALL transaction_test1(); is_array_ref(argument) is_array_ref - in PL/Perl + 在 PL/Perl 中 - 如果给定参数可以作为数组引用处理,即参数的 ref 为 ARRAYPostgreSQL::InServer::ARRAY,则返回真值;否则返回假值。 + + 如果给定参数可被视为数组引用,则返回真值;也就是该参数的 + ref 值为 ARRAY 或 + PostgreSQL::InServer::ARRAY。否则返回假值。 + @@ -959,9 +995,9 @@ CREATE OR REPLACE FUNCTION myfuncs() RETURNS void AS $$ }; $$ LANGUAGE plperl; -SELECT myfuncs(); /* initializes the function */ +SELECT myfuncs(); /* 初始化函数 */ -/* Set up a function that uses the quote function */ +/* 创建一个使用加引号函数的函数 */ CREATE OR REPLACE FUNCTION use_quote(TEXT) RETURNS text AS $$ my $text_to_quote = shift; @@ -976,11 +1012,9 @@ $$ LANGUAGE plperl; - 出于安全原因,PL/Perl 会为某个 SQL 角色调用的函数在该角色专用的独立 - Perl 解释器中执行。这可以防止一个用户意外或恶意地干扰另一个用户的 + 出于安全原因,PL/Perl 会在每个 SQL 角色各自独立的 Perl 解释器中执行该角色调用的函数。这可以防止一个用户意外或恶意地干扰另一个用户的 PL/Perl 函数行为。每个这样的解释器都有自己的 - %_SHARED 变量值和其他全局状态。因此,只有在两个 - PL/Perl 函数都由同一 SQL 角色执行时,它们才会共享 + %_SHARED 变量值和其他全局状态。因此,当且仅当两个 PL/Perl 函数都由同一 SQL 角色执行时,它们才会共享 %_SHARED 的值。在某些应用中,一个会话可能会在多个 SQL 角色下执行代码(通过 SECURITY DEFINER 函数、 使用 SET ROLE 等),这时可能需要显式采取措施, @@ -993,29 +1027,29 @@ $$ LANGUAGE plperl; - 可信与不可信的 PL/Perl + 受信任与不受信任的 PL/Perl - trusted + 受信任的 PL/Perl 通常,PL/Perl 会被安装为一种名为 plperl 的 - 可信编程语言。在这种设置下,为了保持安全性,某些 Perl + 受信任的编程语言。在这种设置下,为了保持安全性,某些 Perl 操作会被禁用。一般来说,受限制的是那些与环境交互的操作,包括文件句柄 操作、requireuse (针对外部模块)。它无法像 C 函数那样访问数据库服务器进程的内部, - 也无法以服务器进程的权限获取操作系统级访问。因此,可以允许任何无权限 + 也无法以服务器进程的权限获取操作系统级访问。因此,可以允许任何无特权 的数据库用户使用这种语言。 - 可信 PL/Perl 依赖 Perl 的 Opcode 模块来维持安全性。 + 受信任的 PL/Perl 依赖 Perl 的 Opcode 模块来维持安全性。 Perl 的 文档 - 指出,该模块对于可信 PL/Perl 这一使用场景并不有效。若你的安全需求 + 指出,该模块对于受信任的 PL/Perl 这一使用场景并不有效。若你的安全需求 不能接受该警告中的不确定性,请考虑执行 REVOKE USAGE ON LANGUAGE plperl FROM PUBLIC @@ -1039,16 +1073,16 @@ $$ LANGUAGE plperl; 有时需要编写不受这些限制的 Perl 函数。例如,可能需要一个能发送邮件的 Perl 函数。为处理这类情况,也可以把 PL/Perl 安装成一种 - 不可信语言(通常称为 + 不受信任的语言(通常称为 PL/PerlUPL/PerlU)。 在这种情况下,完整的 Perl 语言都可用。安装该语言时,使用语言名 - plperlu 就会选择不可信的 PL/Perl 变体。 + plperlu 就会选择不受信任的 PL/Perl 变体。 PL/PerlU 函数的编写者必须注意,函数不能被 用于任何非预期用途,因为它能够执行以数据库管理员身份登录的用户所能 - 做的任何事情。请注意,数据库系统只允许数据库超级用户用不可信语言创建 + 做的任何事情。请注意,数据库系统只允许数据库超级用户用不受信任的语言创建 函数。 @@ -1096,7 +1130,13 @@ $$ LANGUAGE plperl; PL/Perl 触发器 - 可以用 PL/Perl 编写触发器函数。在触发器函数中,哈希引用 $_TD 包含当前触发器事件的信息。$_TD 是全局变量,每次触发器调用都有独立的局部值。以下是 $_TD 哈希引用的字段: + + PL/Perl 可用于编写触发器函数。在触发器函数中,哈希引用 + $_TD 包含有关当前触发器事件的信息。 + $_TD 是一个全局变量,对触发器的每一次调用都会得到 + 一个单独的局部值。$_TD 哈希引用包含以下字段: + + $_TD->{new}{foo} @@ -1176,7 +1216,7 @@ $$ LANGUAGE plperl; $_TD->{relname} - 触发该触发器的表名。该字段已废弃,并且可能会在未来版本中移除。 + 触发该触发器的表名。该字段已弃用,并且可能会在未来版本中移除。 请改用 $_TD->{table_name}。 @@ -1212,7 +1252,10 @@ $$ LANGUAGE plperl; - 行级触发器可以返回以下值之一: + + 行级触发器可以返回下列之一: + + return; @@ -1242,7 +1285,9 @@ $$ LANGUAGE plperl; - 下面的触发器函数示例演示了上述部分内容: + + 下面是一个触发器函数示例,用于说明上述部分内容: + CREATE TABLE test ( i int, v varchar @@ -1250,12 +1295,12 @@ CREATE TABLE test ( CREATE OR REPLACE FUNCTION valid_id() RETURNS trigger AS $$ if (($_TD->{new}{i} >= 100) || ($_TD->{new}{i} <= 0)) { - return "SKIP"; # skip INSERT/UPDATE command + return "SKIP"; # 跳过 INSERT/UPDATE 命令 } elsif ($_TD->{new}{v} ne "immortal") { $_TD->{new}{v} .= "(modified by trigger)"; - return "MODIFY"; # modify row and execute INSERT/UPDATE command + return "MODIFY"; # 修改行并执行 INSERT/UPDATE 命令 } else { - return; # execute INSERT/UPDATE command + return; # 执行 INSERT/UPDATE 命令 } $$ LANGUAGE plperl; @@ -1269,7 +1314,13 @@ CREATE TRIGGER test_valid_id_trig PL/Perl 事件触发器 - 可以用 PL/Perl 编写事件触发器函数。在事件触发器函数中,哈希引用 $_TD 包含当前触发器事件的信息。$_TD 是全局变量,每次触发器调用都有独立的局部值。以下是 $_TD 哈希引用的字段: + + PL/Perl 可用于编写事件触发器函数。在事件触发器函数中,哈希引用 + $_TD 包含有关当前触发器事件的信息。 + $_TD 是一个全局变量,对触发器的每一次调用都会得到 + 一个单独的局部值。$_TD 哈希引用包含以下字段: + + $_TD->{event} @@ -1294,7 +1345,9 @@ CREATE TRIGGER test_valid_id_trig 触发器函数的返回值会被忽略。 - 下面的事件触发器函数示例演示了上述部分内容: + + 下面是一个事件触发器函数示例,用于说明上述部分内容: + CREATE OR REPLACE FUNCTION perlsnitch() RETURNS event_trigger AS $$ elog(NOTICE, "perlsnitch: " . $_TD->{event} . " " . $_TD->{tag} . " "); $$ LANGUAGE plperl; @@ -1402,7 +1455,7 @@ DO 'elog(WARNING, join ", ", sort keys %INC)' LANGUAGE plperl; 也会发生。这是在 plperl.on_init 完成的任何初始化 之后进行的。执行这段代码时 SPI 函数不可用。 plperl.on_plperl_init 中的 Perl 代码是在对解释器 - 进行锁定之后执行的,因此只能执行可信操作。 + 进行锁定之后执行的,因此只能执行受信任的操作。 @@ -1443,7 +1496,10 @@ DO 'elog(WARNING, join ", ", sort keys %INC)' LANGUAGE plperl; 限制与缺失特性 - PL/Perl 目前还缺少以下功能,欢迎贡献这些功能的实现。 + + PL/Perl 目前仍缺少下列特性,但欢迎为此作出贡献。 + + PL/Perl 函数不能直接调用彼此。 diff --git a/zh/13/plpgsql.sgml b/zh/13/plpgsql.sgml index 967c934d..c1b7ff01 100644 --- a/zh/13/plpgsql.sgml +++ b/zh/13/plpgsql.sgml @@ -11,7 +11,9 @@ 概述 - PL/pgSQL是一种可装载的过程语言,适用于PostgreSQL数据库系统。PL/pgSQL的设计目标是创建一种具有以下特点的可装载过程语言: + PL/pgSQL 是一种用于 PostgreSQL 数据库系统的可载入过程语言。PL/pgSQL 的设计目标,是创建一种具备以下特性的可载入过程语言: + + 可用于创建函数、过程和触发器, @@ -140,7 +142,7 @@ CREATE FUNCTION somefunc(integer, text) RETURNS integer AS 'function body text' LANGUAGE plpgsql; - 就 CREATE FUNCTION 而言,函数体目前只是一个字符串字面量。编写函数体时,通常最好使用美元引用(见 ),而不是普通的单引号语法。如果不使用美元引用,函数体中的任何单引号或反斜线都必须通过双写进行转义。本章几乎所有示例的函数体都使用了美元引用。 + 就 CREATE FUNCTION 而言,函数体只是一个字符串字面量。编写函数体时,通常最好使用美元引用(见 ),而不是普通的单引号语法。如果不使用美元引用,函数体中的任何单引号或反斜线都必须通过双写进行转义。本章几乎所有示例的函数体都使用了美元引用。 @@ -323,7 +325,7 @@ $$ LANGUAGE plpgsql; - 当 PL/pgSQL 函数声明了输出参数时,输出参数也会像普通输入参数一样获得 $n 名称和可选别名。输出参数本质上是一个初始值为 NULL 的变量,应在函数执行期间给它赋值。该参数的最终值就是返回值。例如,sales-tax 的示例也可以这样写: + 当 PL/pgSQL 函数声明了输出参数时,输出参数也会像普通输入参数一样获得 $n 名称和可选别名。输出参数本质上是一个初始值为 NULL 的变量,应在函数执行期间给它赋值。该参数的最终值就是返回值。例如,销售税的示例也可以这样写: CREATE FUNCTION sales_tax(subtotal real, OUT tax real) AS $$ @@ -336,14 +338,19 @@ $$ LANGUAGE plpgsql; 注意这里省略了 RETURNS real — 当然也可以写上,但那只是冗余。 - 输出参数在返回多个值时最有用。一个简单的例子是: + + 当需要返回多个值时,输出参数尤其有用。下面是一个简单示例: + + CREATE FUNCTION sum_n_product(x int, y int, OUT sum int, OUT prod int) AS $$ BEGIN sum := x + y; prod := x * y; END; $$ LANGUAGE plpgsql; -所述,这实际上为函数结果创建了一个匿名记录类型。如果给出RETURNS子句,它必须写为RETURNS record。 + + + 如 所述,这实际上会为函数结果创建一个匿名记录类型。如果写了 RETURNS 子句,它必须是 RETURNS record @@ -362,8 +369,10 @@ $$ LANGUAGE plpgsql; 这与声明一个或多个 OUT 参数并指定 RETURNS SETOF sometype 完全等效。 - 如果一个PL/pgSQL函数的返回类型被声明为多态类型(见),就会创建特殊参数$0。其数据类型是函数的实际返回类型,根据实际输入类型推导得出。这使函数可以访问其实际返回类型,方式见。 - $0被初始化为 null,函数可以修改它,因此需要时可以用它保存返回值,但这并不是必需的。$0也可以设置别名。例如,下面的函数适用于任何具有+操作符的数据类型: + + 当 PL/pgSQL 函数的返回类型被声明为多态类型(见 )时,会创建一个特殊参数 $0。它的数据类型是函数的实际返回类型,由实际输入类型推导得出。这使得函数可以像 所示那样访问自身的实际返回类型。$0 会被初始化为 null,并且可以在函数中修改,因此如果需要,也可以用它保存返回值,尽管这并不是必需的。$0 也可以有别名。例如,下面这个函数适用于任何拥有 + 操作符的数据类型: + + CREATE FUNCTION add_three_values(v1 anyelement, v2 anyelement, v3 anyelement) RETURNS anyelement AS $$ DECLARE @@ -390,16 +399,26 @@ $$ LANGUAGE plpgsql; - 实际上,使用anycompatible类型族声明多态函数可能更有用,这样输入参数会被自动提升为一个共同类型。例如: + + 在实践中,使用 anycompatible 类型族来声明多态函数可能更有用,因为这样输入参数会自动提升为共同类型。例如: + + CREATE FUNCTION add_three_values(v1 anycompatible, v2 anycompatible, v3 anycompatible) RETURNS anycompatible AS $$ BEGIN RETURN v1 + v2 + v3; END; $$ LANGUAGE plpgsql; -对于这个例子,以下调用: + + + 在这个示例中,像下面这样的调用 + + SELECT add_three_values(1, 2, 4.7); -可以正常工作,它会自动把整数输入提升为 numeric。使用anyelement的函数则要求手动把三个输入转换为相同类型。 + + + 可以正常工作,并会自动把整数输入提升为 numeric。如果使用 anyelement,则必须手工把这三个输入转换成同一类型。 + @@ -444,7 +463,9 @@ user_id users.user_id%TYPE; 使用 %TYPE 的好处是,你不必知道所引用结构的实际数据类型;更重要的是,如果被引用项的数据类型将来发生变化(例如把 user_id 的类型从 integer 改成 real),你可能就不需要修改函数定义。 - %TYPE在多态函数中特别有用,因为内部变量所需的数据类型可能在各次调用之间发生变化。可以对函数参数或结果占位符应用%TYPE,以创建适当的变量。 + + %TYPE 在多态函数中特别有价值,因为内部变量所需的数据类型可能在不同调用之间变化。可以把 %TYPE 应用到函数参数或结果占位符上,以创建合适的变量。 + @@ -460,9 +481,13 @@ user_id users.user_id%TYPE; 复合类型的变量称为变量(或行类型变量)。只要查询的列集合与该变量声明的类型相匹配,这种变量就可以保存 SELECTFOR 查询结果中的整行。行值的各个字段可以使用通常的点号记法访问,例如 rowvar.field - 可以使用table_name%ROWTYPE记号,将行变量声明为与现有表或视图的行具有相同类型;也可以通过给出复合类型名称来声明它。(因为每个表都有一个同名的关联复合类型,所以在PostgreSQL中,实际上写不写%ROWTYPE都没有区别。但带有%ROWTYPE的形式更易于移植。) + + 行变量既可以通过 table_name%ROWTYPE 记法声明为与现有表或视图的行具有相同类型,也可以通过给出某个复合类型的名称来声明。(由于每个表都有一个同名的关联复合类型,所以在 PostgreSQL 中实际上写不写 %ROWTYPE 并无区别;不过带 %ROWTYPE 的形式可移植性更好。) + - 函数参数可以是复合类型(完整的表行)。在这种情况下,相应的标识符$n将是一个行变量,可以从中选取字段,例如$1.user_id + + 函数参数也可以是复合类型(完整的表行)。在这种情况下,相应的标识符 $n 就是一个行变量,并且可以从中选取字段,例如 $1.user_id。 + 下面是一个使用复合类型的示例。table1table2 是已经存在的表,它们至少包含下面提到的字段: @@ -504,12 +529,12 @@ SELECT merge_fields(t.*) FROM table1 t WHERE ... ; <application>PL/pgSQL</application>变量的排序规则 - collation - in PL/pgSQL + 排序规则 + 在 PL/pgSQL 中 - 当 PL/pgSQL 函数具有一个或多个可排序数据类型参数时,每次函数调用都会根据分配给实际参数的排序规则确定出一个排序规则,如 所述。如果该排序规则能成功确定出来(即参数之间的隐式排序规则没有冲突),那么所有可排序参数都会被视为隐式带有该排序规则。这会影响函数中那些受排序规则影响的操作。例如,考虑 + 当 PL/pgSQL 函数具有一个或多个支持排序规则的数据类型参数时,每次函数调用都会根据分配给实际参数的排序规则确定出一个排序规则,如 所述。如果该排序规则能成功确定出来(即参数之间的隐式排序规则没有冲突),那么所有支持排序规则的参数都会被视为隐式带有该排序规则。这会影响函数中那些受排序规则影响的操作。例如,考虑 CREATE FUNCTION less_than(a text, b text) RETURNS boolean AS $$ @@ -526,7 +551,7 @@ SELECT less_than(text_field_1, text_field_2 COLLATE "C") FROM table1; - 此外,确定出的排序规则也会被视为任何可排序数据类型局部变量的排序规则。因此,即使把这个函数写成下面这样,其行为也不会有任何不同: + 此外,确定出的排序规则也会被视为任何支持排序规则的数据类型局部变量的排序规则。因此,即使把这个函数写成下面这样,其行为也不会有任何不同: CREATE FUNCTION less_than(a text, b text) RETURNS boolean AS $$ @@ -541,11 +566,11 @@ $$ LANGUAGE plpgsql; - 如果函数没有可排序数据类型的参数,或者无法为它们确定共同排序规则,那么参数和局部变量将使用其数据类型的默认排序规则(通常是数据库默认排序规则,但对于域类型变量也可能不同)。 + 如果函数没有支持排序规则的数据类型的参数,或者无法为它们确定共同排序规则,那么参数和局部变量将使用其数据类型的默认排序规则(通常是数据库默认排序规则,但对于域类型变量也可能不同)。 - 通过在可排序数据类型局部变量的声明中加入 COLLATE 选项,可以为其指定不同的排序规则,例如 + 通过在支持排序规则的数据类型局部变量的声明中加入 COLLATE 选项,可以为其指定不同的排序规则,例如 DECLARE @@ -650,12 +675,12 @@ PERFORM create_mv('cs_session_page_requests_mv', my_query); SELECT INTO - in PL/pgSQL + 在 PL/pgSQL 中 RETURNING INTO - in PL/pgSQL + 在 PL/pgSQL 中 产生单行(可能有多列)结果的 SQL 命令,其结果可以赋给记录变量、行类型变量或标量变量列表。方法是在基本 SQL 命令中添加INTO子句。例如: @@ -696,7 +721,7 @@ END; 成功执行带有STRICT的命令总会将FOUND设为真。 - 对于带有RETURNINGINSERT/UPDATE/DELETE/即使没有指定STRICTPL/pgSQL也会针对多于一个返回行的情况报告一个错误。这是因为没有类似于ORDER BY的选项可以用来决定应该返回哪个被影响的行。 + 对于带有RETURNINGINSERT/UPDATE/DELETE,即使没有指定STRICTPL/pgSQL也会针对多于一个返回行的情况报告一个错误。这是因为没有类似于ORDER BY的选项可以用来决定应该返回哪个被影响的行。 如果print_strict_params已为该函数启用,那么当不满足STRICT要求而抛出错误时,错误消息的DETAIL部分将包含传给查询的参数信息。可以为所有函数更改print_strict_params设置,方法是设置plpgsql.print_strict_params,不过只会影响随后编译的函数。也可以通过编译器选项逐函数启用,例如: @@ -733,25 +758,23 @@ CONTEXT: PL/pgSQL function get_userid(text) line 6 at SQL statement 执行动态命令 - 很多时候你将想要在PL/pgSQL函数中产生动态命令,也就是每次执行中会涉及到不同表或不同数据类型的命令。PL/pgSQL通常对于命令所做的缓存计划尝试(如中讨论)在这种情境下无法工作。要处理这一类问题,需要提供EXECUTE语句: + 很多时候你将想要在PL/pgSQL函数中产生动态命令,也就是每次执行中会涉及到不同表或不同数据类型的命令。PL/pgSQL通常对于命令所做的缓存计划尝试(如中讨论)在这种情境下无法工作。要处理这一类问题,提供了EXECUTE语句: EXECUTE command-string INTO STRICT target USING expression , ... ; - 其中command-string是一个能得到一个包含要被执行命令字符串(类型text)的表达式。可选的target是一个记录变量、一个行变量或者一个逗号分隔的简单变量以及记录/行域的列表,该命令的结果将存储在其中。可选的USING表达式提供要被插入到该命令中的值。 + 其中command-string是一个能得到一个包含要被执行命令字符串(类型text)的表达式。可选的target是一个记录变量、一个行变量或者一个逗号分隔的简单变量以及记录/行字段的列表,该命令的结果将存储在其中。可选的USING表达式提供要被插入到该命令中的值。 在计算得到的命令字符串中,不会做PL/pgSQL变量的替换。任何所需的变量值必须在命令字符串被构造时被插入其中,或者你可以使用下面描述的参数。 - - 还有,对于通过EXECUTE执行的命令不会有计划被缓存。该命令反而在每次运行时都会被做计划。因此,该命令字符串可以在执行不同表和列上动作的函数中被动态创建。 - + 此外,通过 EXECUTE 执行的命令不会缓存计划,而是在每次运行该语句时重新规划。因此,可以在函数中动态构造命令字符串,对不同的表和列执行操作。 - INTO子句指定一个返回行的 SQL 命令的结果应该被赋值到哪里。如果提供了一个行或变量列表,它必须完全匹配查询命令结果的结构(当一个记录变量被提供时,它会自动把它自己配置为匹配结果结构)。如果返回多个行,只有第一个行会被赋值给INTO变量。如果没有返回行,NULL 会被赋值给INTO变量。如果没有指定INTO子句,该查询结果会被抛弃。 + INTO子句指定一个返回行的 SQL 命令的结果应该被赋值到哪里。如果提供了一个行变量或变量列表,它必须完全匹配查询命令结果的结构(当一个记录变量被提供时,它会自动把它自己配置为匹配结果结构)。如果返回多个行,只有第一个行会被赋值给INTO变量。如果没有返回行,NULL 会被赋值给INTO变量。如果没有指定INTO子句,该查询结果会被抛弃。 @@ -759,7 +782,7 @@ EXECUTE command-string INT - 命令字符串可以使用参数值,它们在命令中用$1$2等引用。这些符号引用在USING子句中提供的值。这种方法常常更适合于把数据值作为文本插入到命令字符串中:它避免了将该值转换为文本以及转换回来的运行时负荷,并且它更不容易被 SQL 注入攻击,因为不需要引用或转义。一个示例是: + 命令字符串可以使用参数值,它们在命令中用$1$2等引用。这些符号引用在USING子句中提供的值。这种方法通常比把数据值作为文本插入命令字符串更可取:它避免了将该值转换为文本以及转换回来的运行时负荷,并且它更不容易被 SQL 注入攻击,因为不需要引用或转义。一个示例是: EXECUTE 'SELECT count(*) FROM mytable WHERE inserted_by = $1 AND inserted <= $2' INTO c @@ -781,7 +804,7 @@ EXECUTE format('SELECT count(*) FROM %I ' 参数符号的另一个限制是,它们只能用于SELECTINSERTUPDATE以及DELETE命令。在其他语句类型(统称为工具语句)中,即使只是数据值,也必须以文本形式插入。 - 在上面第一个示例中,带有一个简单的常量命令字符串和一些USING参数的EXECUTE命令在功能上等效于直接用PL/pgSQL写的命令,并且允许自动发生PL/pgSQL变量替换。重要的不同之处在于,EXECUTE会在每一次执行时根据当前的参数值重新计划该命令,而PL/pgSQL则是创建一个通用计划并且将其缓存以便重用。在最佳计划强依赖于参数值的情况中,使用EXECUTE来明确地保证不会选择一个通用计划是很有帮助的。 + 在上面第一个示例中,带有一个简单的常量命令字符串和一些USING参数的EXECUTE命令在功能上等效于直接用PL/pgSQL写的命令,并且允许自动发生PL/pgSQL变量替换。重要的不同之处在于,EXECUTE会在每一次执行时根据当前的参数值重新计划该命令,而PL/pgSQL则可能创建一个通用计划并且将其缓存以便重用。在最佳计划强依赖于参数值的情况中,使用EXECUTE来明确地保证不会选择一个通用计划是很有帮助的。 @@ -853,19 +876,19 @@ EXECUTE 'UPDATE tbl SET ' || ' WHERE key = ' || quote_nullable(keyvalue); - 如果正在处理的参数值可能为空,那么通常应该用quote_nullable来代替quote_literal。 + 如果正在处理的参数值可能为空值,那么通常应该用quote_nullable来代替quote_literal - 通常,必须小心地确保查询中的空值不会递送意料之外的结果。例如如果keyvalue为空,下面的WHERE子句 + 通常,必须小心地确保查询中的空值不会产生意料之外的结果。例如如果keyvalue为空值,下面的WHERE子句 'WHERE key = ' || quote_nullable(keyvalue) - 永远不会成功,因为在=操作符中使用空操作数得到的结果总是为空。如果想让空和一个普通键值一样工作,你应该将上面的命令重写成 + 永远不会成功,因为在=操作符中使用空值操作数得到的结果总是空值。如果想让空值像普通键值一样工作,你应该将上面的命令重写成 'WHERE key IS NOT DISTINCT FROM ' || quote_nullable(keyvalue) - (目前,IS NOT DISTINCT FROM的处理效率不如=,因此只有在非常必要时才这样做。关于空和IS DISTINCT的详细信息请见)。 + (目前,IS NOT DISTINCT FROM的处理效率不如=,因此只有在非常必要时才这样做。关于空值和IS DISTINCT的详细信息请见)。 @@ -878,7 +901,7 @@ EXECUTE 'UPDATE tbl SET ' || '$$ WHERE key = ' || quote_literal(keyvalue); - 因为如果newvalue的内容碰巧含有$$,那么这段代码就会出问题。同样的缺点可能适用于你选择的任何其他美元符号引用定界符。因此,要想安全地引用事先不知道的文本,必须恰当地使用quote_literalquote_nullablequote_ident。 + 因为如果newvalue的内容碰巧含有$$,那么这段代码就会出问题。同样的问题也适用于你选择的任何其他美元符号引用定界符。因此,要想安全地引用事先不知道的文本,必须恰当地使用quote_literalquote_nullablequote_ident @@ -916,7 +939,7 @@ EXECUTE format('UPDATE tbl SET %I = $1 WHERE key = $2', colname) GET CURRENT DIAGNOSTICS variable { = | := } item , ... ; - 这条命令允许检索系统状态指示符。CURRENT是一个噪声词(另见中的GET STACKED DIAGNOSTICS)。每个item是一个关键字, 它标识一个要被赋予给指定变量的状态值(变量应具有正确的数据类型来接收状态值)。中展示了当前可用的状态项。冒号等号(:=)可以被用来取代 SQL 标准的=符号。例如: + 这条命令允许检索系统状态指示符。CURRENT是一个噪声词(另见中的GET STACKED DIAGNOSTICS)。每个item是一个关键字, 它标识一个要被赋予给指定variable的状态值(变量应具有正确的数据类型来接收状态值)。中展示了当前可用的状态项。冒号等号(:=)可以被用来取代 SQL 标准的=符号。例如: GET DIAGNOSTICS integer_var = ROW_COUNT; @@ -951,10 +974,15 @@ GET DIAGNOSTICS integer_var = ROW_COUNT;
- 确定命令执行效果的第二种方法是检查名为FOUND的特殊变量,其类型为booleanFOUND的初始值为假,这适用于每次PL/pgSQL函数调用。以下各类语句都会设置它: + + 第二种确定命令效果的方法是检查名为FOUND的特殊变量,类型为boolean。 + 在每次PL/pgSQL函数调用中,FOUND的初始值都是 false。 + 它由以下类型的语句设置: + + - SELECT INTO语句在分配行时将FOUND设置为true, + SELECT INTO语句在为目标赋上一行值时将FOUND设置为true, 如果没有返回行则设置为false。 @@ -983,7 +1011,7 @@ GET DIAGNOSTICS integer_var = ROW_COUNT; FORFOREACH语句在迭代一次或多次时将 FOUND设置为true,否则设置为false。 - 当循环退出时,FOUND被设置为这种方式; + 当循环退出时,FOUND会按上述方式设置; 在循环执行过程中,FOUND不会被循环语句修改, 尽管它可能会被循环体内的其他语句执行修改。 @@ -995,7 +1023,11 @@ GET DIAGNOSTICS integer_var = ROW_COUNT; 如果没有返回行则设置为false。 - 其他PL/pgSQL语句不会改变以下变量的状态:FOUND。特别要注意的是,EXECUTE会改变GET DIAGNOSTICS的输出,但不会改变FOUND。 +
+ + 其他PL/pgSQL语句不会改变FOUND的状态。 + 特别注意,EXECUTE会改变GET DIAGNOSTICS的输出, + 但不会改变FOUND @@ -1015,12 +1047,14 @@ NULL; - 例如,下面两个代码片段是等价的: + + 例如,下面的两段代码是等价的: + BEGIN y := x / 0; EXCEPTION WHEN division_by_zero THEN - NULL; -- ignore the error + NULL; -- 忽略错误 END; @@ -1028,9 +1062,11 @@ END; BEGIN y := x / 0; EXCEPTION - WHEN division_by_zero THEN -- ignore the error + WHEN division_by_zero THEN -- 忽略错误 END; -选用哪一种取决于个人偏好。 + + 究竟使用哪一种取决于各人的喜好。 + @@ -1068,7 +1104,7 @@ RETURN expression; - 如果函数返回的是标量类型,表达式结果会自动转换为函数的返回类型。但如果要返回一个组合(行)值,你必须写出一个恰好生成所需列集合的表达式。这可能需要显式类型转换。 + 如果函数返回的是标量类型,表达式结果会按照赋值部分的说明自动转换为函数的返回类型。但如果要返回一个复合(行)值,你必须写出一个恰好生成所需列集合的表达式。这可能需要显式类型转换。 @@ -1080,17 +1116,20 @@ RETURN expression; - 一个函数的返回值不能是未定义。如果控制到达了函数最顶层的块而没有碰到一个RETURN语句,那么会发生一个运行时错误。不过,这个限制不适用于带输出参数的函数以及返回void的函数。在这些情况中,如果顶层的块结束,将自动执行一个RETURN语句。 + 一个函数的返回值不能是未定义。如果控制到达了函数最顶层块的末尾而没有碰到一个RETURN语句,那么会发生一个运行时错误。不过,这个限制不适用于带输出参数的函数以及返回void的函数。在这些情况中,如果顶层的块结束,将自动执行一个RETURN语句。 - 下面是一些例子: --- functions returning a scalar type + + 一些示例: + + +-- 返回一个标量类型的函数 RETURN 1 + 2; RETURN scalar_var; --- functions returning a composite type +-- 返回一个复合类型的函数 RETURN composite_type_var; -RETURN (1, 2, 'three'::text); -- must cast columns to correct types +RETURN (1, 2, 'three'::text); -- 必须把列类型转换成正确的类型 @@ -1099,11 +1138,11 @@ RETURN (1, 2, 'three'::text); -- must cast columns to correct types <command>RETURN NEXT</command> 和 <command>RETURN QUERY</command> RETURN NEXT - in PL/pgSQL + 在 PL/pgSQL 中 RETURN QUERY - in PL/pgSQL + 在 PL/pgSQL 中 @@ -1113,7 +1152,7 @@ RETURN QUERY EXECUTE command-string < - 当 PL/pgSQL 函数被声明为返回 SETOF sometype 时,返回过程会略有不同。在这种情况下,要返回的各个项通过一系列 RETURN NEXTRETURN QUERY 命令指定,最后再用一个不带参数的 RETURN 命令表明函数已经执行完毕。RETURN NEXT 可用于标量和组合数据类型;对于组合结果类型,会返回完整的结果RETURN QUERY 会把查询执行结果追加到函数的结果集中。在同一个集合返回函数中,RETURN NEXTRETURN QUERY 可以自由混用,此时它们的结果会被串接起来。 + 当 PL/pgSQL 函数被声明为返回 SETOF sometype 时,返回过程会略有不同。在这种情况下,要返回的各个项通过一系列 RETURN NEXTRETURN QUERY 命令指定,最后再用一个不带参数的 RETURN 命令表明函数已经执行完毕。RETURN NEXT 可用于标量和复合数据类型;对于复合结果类型,会返回完整的结果RETURN QUERY 会把查询执行结果追加到函数的结果集中。在同一个集合返回函数中,RETURN NEXTRETURN QUERY 可以自由混用,此时它们的结果会被串接起来。 @@ -1128,7 +1167,8 @@ RETURN QUERY EXECUTE command-string < 如果你声明函数带有输出参数,只需要写不带表达式的RETURN NEXT。在每一次执行时,输出参数变量的当前值将被保存下来用于最终返回为结果的一行。注意为了创建一个带有输出参数的集合返回函数,在有多个输出参数时,你必须声明函数为返回SETOF record;或者如果只有一个类型为sometype的输出参数时,声明函数为SETOF sometype - 下面的函数示例使用了RETURN NEXT: + + 下面是一个使用RETURN NEXT的函数示例: CREATE TABLE foo (fooid INT, foosubid INT, fooname TEXT); @@ -1143,8 +1183,8 @@ BEGIN FOR r IN SELECT * FROM foo WHERE fooid > 0 LOOP - -- can do some processing here - RETURN NEXT r; -- return current row of SELECT + -- 这里可以做一些处理 + RETURN NEXT r; -- 返回 SELECT 的当前行 END LOOP; RETURN; END; @@ -1155,7 +1195,8 @@ SELECT * FROM get_all_foo(); - 下面的函数示例使用了RETURN QUERY: + + 这里是一个使用RETURN QUERY的函数的示例: CREATE FUNCTION get_available_flightid(date) RETURNS SETOF integer AS @@ -1166,8 +1207,8 @@ BEGIN WHERE flightdate >= $1 AND flightdate < ($1 + 1); - -- Since execution is not finished, we can check whether rows were returned - -- and raise exception if not. + -- 因为执行还未结束,我们可以检查是否有行被返回 + -- 如果没有就抛出异常。 IF NOT FOUND THEN RAISE EXCEPTION 'No flight at %.', $1; END IF; @@ -1177,8 +1218,7 @@ BEGIN $BODY$ LANGUAGE plpgsql; --- Returns available flights or raises exception if there are no --- available flights. +-- 返回可用的航班或者在没有可用航班时抛出异常。 SELECT * FROM get_available_flightid(CURRENT_DATE); @@ -1350,7 +1390,7 @@ ELSIF number > 0 THEN ELSIF number < 0 THEN result := 'negative'; ELSE - -- 嗯,唯一的其他可能性是数字为空 + -- 嗯,唯一的其他可能性是 number 为 null result := 'NULL'; END IF; @@ -1453,12 +1493,12 @@ END CASE; 简单循环 - loop + 循环 在 PL/pgSQL 中 - 使用LOOPEXITCONTINUEWHILEFORFOREACH语句,你可以安排PL/pgSQL重复一系列命令。 + 使用LOOPEXITCONTINUEWHILEFORFOREACH语句,你可以安排PL/pgSQL函数重复一系列命令。 @@ -1504,26 +1544,28 @@ EXIT label WHEN BEGIN 块一起使用时,EXIT 会把控制转交给该块结束后的下一条语句。需要注意的是,为此必须使用标签;未加标签的 EXIT 永远不会被视为匹配某个 BEGIN 块。这与 PostgreSQL 8.4 之前的版本不同,旧版本允许未加标签的 EXIT 匹配 BEGIN 块。 - 例如: + + 示例: + LOOP - -- some computations + -- 一些计算 IF count > 0 THEN - EXIT; -- exit loop + EXIT; -- 退出循环 END IF; END LOOP; LOOP - -- some computations - EXIT WHEN count > 0; -- same result as previous example + -- 一些计算 + EXIT WHEN count > 0; -- 和前一个示例相同的结果 END LOOP; <<ablock>> BEGIN - -- some computations + -- 一些计算 IF stocks > 100000 THEN - EXIT ablock; -- causes exit from the BEGIN block + EXIT ablock; -- 导致从 BEGIN 块中退出 END IF; - -- computations here will be skipped when stocks > 100000 + -- 当stocks > 100000时,这里的计算将被跳过 END; @@ -1553,7 +1595,9 @@ CONTINUE label WHEN CONTINUE可以被用在所有类型的循环中,它并不限于在无条件循环中使用。 - 例如: + + 示例: + LOOP -- 一些计算 EXIT WHEN count > 100; @@ -1610,22 +1654,22 @@ END LOOP label ; - 这种形式的FOR会创建一个在一个整数范围上迭代的循环。变量name会自动定义为类型integer并且只在循环内存在(任何该变量名的现有定义在此循环内都将被忽略)。给出范围上下界的两个表达式在进入循环的时候计算一次。如果没有指定BY子句,迭代步长为 1,否则步长是BY中指定的值,该值也只在循环进入时计算一次。如果指定了REVERSE,那么在每次迭代后步长值会被减除而不是增加。 + 这种形式的FOR会创建一个在一个整数范围上迭代的循环。变量name会自动定义为类型integer并且只在循环内存在(任何该变量名的现有定义在此循环内都将被忽略)。给出范围上下界的两个表达式在进入循环的时候计算一次。如果没有指定BY子句,迭代步长为 1,否则步长是BY中指定的值,该值也只在循环进入时计算一次。如果指定了REVERSE,那么在每次迭代后会减去步长,而不是加上步长。 整数FOR循环的一些示例: FOR i IN 1..10 LOOP - -- 我在循环中将取值 1,2,3,4,5,6,7,8,9,10 + -- i 在循环中将取值 1,2,3,4,5,6,7,8,9,10 END LOOP; FOR i IN REVERSE 10..1 LOOP - -- 我在循环中将取值 10,9,8,7,6,5,4,3,2,1 + -- i 在循环中将取值 10,9,8,7,6,5,4,3,2,1 END LOOP; FOR i IN REVERSE 10..1 BY 2 LOOP - -- 我在循环中将取值 10,8,6,4,2 + -- i 在循环中将取值 10,8,6,4,2 END LOOP; @@ -1688,7 +1732,7 @@ $$ LANGUAGE plpgsql; - 在这类 FOR 语句中使用的 query,可以是任何向调用者返回行的 SQL 命令:最常见的是 SELECT,但也可以是带 RETURNING 子句的 INSERTUPDATEDELETE。某些实用程序命令,如 EXPLAIN,也可以用于此处。 + 在这类 FOR 语句中使用的 query,可以是任何向调用者返回行的 SQL 命令:最常见的是 SELECT,但也可以是带 RETURNING 子句的 INSERTUPDATEDELETE。某些工具命令,如 EXPLAIN,也可以用于此处。 PL/pgSQL变量会被替换到查询文本中,并且如中详细讨论的,查询计划会被缓存以用于可能的重用。 @@ -1701,7 +1745,7 @@ FOR target IN EXECUTE text_expressionstatements END LOOP label ; - 这个示例类似前面的形式,只不过源查询被指定为一个字符串表达式,在每次进入FOR循环时都会计算它并且重新计划。这允许程序员在一个预先计划好了的命令的速度和一个动态命令的灵活性之间进行选择,就像一个纯EXECUTE语句那样。在使用EXECUTE时,可以通过USING将参数值插入到动态命令中。 + 这个示例类似前面的形式,只不过源查询被指定为一个字符串表达式,在每次进入FOR循环时都会计算它并且重新计划。这允许程序员在一个预先计划好了的命令的速度和一个动态命令的灵活性之间进行选择,就像一个纯EXECUTE语句那样。与EXECUTE一样,可以通过USING将参数值插入到动态命令中。 @@ -1738,7 +1782,7 @@ END; $$ LANGUAGE plpgsql; - 元素会按存储顺序访问,而不管数组有多少维。尽管target通常只是单个变量,但在遍历组合值(记录)数组时,它也可以是一个变量列表。在这种情况下,每个数组元素都会按组合值的连续列给这些变量赋值。 + 元素会按存储顺序访问,而不管数组有多少维。尽管target通常只是单个变量,但在遍历复合值(记录)数组时,它也可以是一个变量列表。在这种情况下,每个数组元素都会按复合值的连续列给这些变量赋值。 @@ -1770,8 +1814,8 @@ NOTICE: row = {10,11,12} 捕获错误 - exceptions - in PL/pgSQL + 异常 + 在 PL/pgSQL 中 @@ -1830,7 +1874,7 @@ END; - 进入和退出一个包含EXCEPTION子句的块要比不包含该子句的块开销大的多。因此,只在必要的时候使用EXCEPTION。 + 进入和退出一个包含EXCEPTION子句的块要比不包含该子句的块开销大得多。因此,只在必要的时候使用EXCEPTION @@ -1857,9 +1901,9 @@ BEGIN IF found THEN RETURN; END IF; - -- 不在这里,那么尝试插入该键 + -- 该键不存在,因此尝试插入 -- 如果其他某人并发地插入同一个键, - -- 我们可能得到一个唯一键失败 + -- 就可能发生违反唯一约束的错误 BEGIN INSERT INTO db(a,b) VALUES (key, data); RETURN; @@ -1898,7 +1942,7 @@ SELECT merge_db(1, 'dennis'); GET STACKED DIAGNOSTICS variable { = | := } item , ... ; - 每个item是一个关键词,它标识一个被赋予给指定变量(应该具有接收该值的正确数据类型)的状态值。中显示了当前可用的状态项。 + 每个item是一个关键词,它标识一个被赋予给指定variable(应该具有接收该值的正确数据类型)的状态值。中显示了当前可用的状态项。 @@ -2010,7 +2054,7 @@ END; 获得执行位置信息 - GET DIAGNOSTICS(之前在中描述)命令检索有关当前执行状态的信息(反之上文讨论的GET STACKED DIAGNOSTICS命令会把有关执行状态的信息报告成一个以前的错误)。它的PG_CONTEXT状态项可用于标识当前执行位置。状态项PG_CONTEXT将返回一个文本字符串,其中有描述该调用栈的多行文本。第一行会指向当前函数以及当前正在执行GET DIAGNOSTICS的命令。第二行及其后的行表示调用栈中更上层的调用函数。例如: + GET DIAGNOSTICS(之前在中描述)命令检索有关当前执行状态的信息(反之上文讨论的GET STACKED DIAGNOSTICS命令报告先前发生错误时的执行状态信息)。它的PG_CONTEXT状态项可用于标识当前执行位置。状态项PG_CONTEXT将返回一个文本字符串,其中包含一行或多行描述该调用栈的文本。第一行会指向当前函数以及当前正在执行的GET DIAGNOSTICS命令。第二行及其后的行表示调用栈中更上层的调用函数。例如: CREATE OR REPLACE FUNCTION outer_func() RETURNS integer AS $$ @@ -2053,7 +2097,7 @@ CONTEXT: PL/pgSQL function outer_func() line 3 at RETURN 游标 - cursor + 游标 在 PL/pgSQL 中 @@ -2085,7 +2129,7 @@ DECLARE - 当游标查询使用 FOR UPDATE/SHARE 时,不能使用 SCROLL 选项。此外,对于涉及易失函数的查询,最好使用 NO SCROLLSCROLL 的实现假定重新读取查询输出会得到一致的结果,而易失函数并不满足这一假设。 + 当游标查询使用 FOR UPDATE/SHARE 时,不能使用 SCROLL 选项。此外,对于涉及易失函数的查询,最好使用 NO SCROLLSCROLL 的实现假定重新读取查询输出会得到一致的结果,而易失函数可能无法满足这一假设。 @@ -2163,7 +2207,9 @@ OPEN bound_cursorvar ( 位置或命名记号可以传递参数值。在位置记号中,所有参数都必须按照顺序指定。在命名记号中,每一个参数的名字使用:=与参数表达式分隔。类似于中描述的调用函数,也允许混合位置和命名记号。 - 例如(使用前面的游标声明示例): + + 示例(这些示例使用上面示例中的游标声明): + OPEN curs2; OPEN curs3(42); OPEN curs3(key := 42); @@ -2393,12 +2439,17 @@ COMMIT; 遍历游标结果 - 有一种FOR语句的变体可以遍历游标返回的行。其语法为: + + 有一种FOR语句的变体,它允许通过游标返回的行进行迭代。语法是: + + <<label>> FOR recordvar IN bound_cursorvar ( argument_name := argument_value , ... ) LOOP statements END LOOP label ; -游标变量必须在声明时绑定到某个查询,并且此时不能处于已打开状态。FOR语句会自动打开该游标,并在循环退出时将其关闭。当且仅当游标声明为接受参数时,才必须给出实际参数值表达式列表。这些值会被替换到查询中,其方式与执行以下命令时相同:OPEN(见)。 + + + 该游标变量必须在声明时已经被绑定到某个查询,并且它不能已经被打开。FOR语句会自动打开游标,并且在退出循环时自动关闭游标。当且仅当游标被声明要使用参数时,才必须出现一个实际参数值表达式的列表。这些值会被替换到查询中,采用OPEN期间的方式(见)。 @@ -2439,7 +2490,7 @@ CALL transaction_test1(); 连锁的事务 - 在 PL/pgSQL + 在 PL/pgSQL 中 @@ -2503,7 +2554,9 @@ RAISE ; level(如果有)之后,可以指定一个format字符串(必须是简单的字符串字面量,不能是表达式)。格式字符串指定要报告的错误消息文本。格式字符串之后可以跟上可选的参数表达式,其值将被插入消息中。在格式字符串内,%会被替换为下一个可选参数值的字符串表示。写成%%可以输出一个字面的%。参数个数必须与格式字符串中%占位符的个数匹配,否则会在函数编译期间报错。 - 在这个例子中,v_job_id的值会替换字符串中的% + + 在这个示例中,v_job_id的值将替换字符串中的%: + RAISE NOTICE 'Calling cs_create_job(%)', v_job_id; @@ -2515,7 +2568,7 @@ RAISE NOTICE 'Calling cs_create_job(%)', v_job_id; MESSAGE - 设置错误消息文本。如果RAISE采用了在USING之前包含格式字符串的形式,则不能使用此选项。 + 设置错误消息文本。该选项不能用于在USING之前包含格式字符串的RAISE形式。 @@ -2529,14 +2582,14 @@ RAISE NOTICE 'Calling cs_create_job(%)', v_job_id; HINT - 提供提示消息。 + 提供一个提示消息。 ERRCODE - 指定要报告的错误码(SQLSTATE),可以使用中所示的条件名,也可以直接使用五个字符的 SQLSTATE 代码。 + 指定要报告的错误代码(SQLSTATE),可以用中所示的条件名,或者直接作为一个五字符 SQLSTATE 代码。 @@ -2547,7 +2600,7 @@ RAISE NOTICE 'Calling cs_create_job(%)', v_job_id; TABLE SCHEMA - 提供相关对象的名称。 + 提供一个相关对象的名称。 @@ -2559,23 +2612,33 @@ RAISE EXCEPTION 'Nonexistent ID --> %', user_id - 这两个例子展示了设置 SQLSTATE 的等价方式: + + 这两个示例展示了设置 SQLSTATE 的两种等价的方法: + RAISE 'Duplicate user ID: %', user_id USING ERRCODE = 'unique_violation'; RAISE 'Duplicate user ID: %', user_id USING ERRCODE = '23505'; - 还有第二种RAISE语法,其主要参数是要报告的条件名或 SQLSTATE,例如: + + 还有第二种RAISE语法,其中主参数是要报告的条件名或 SQLSTATE,例如: + RAISE division_by_zero; RAISE SQLSTATE '22012'; -在这种语法中,USING可以用来提供自定义的错误消息、详细信息或提示。前面例子的另一种写法是 + + 在这种语法中,USING可以用来提供自定义的错误消息、细节或提示。另一种达到前面示例同样效果的方式是: + RAISE unique_violation USING MESSAGE = 'Duplicate user ID: ' || user_id; - 还有一种变体是写成RAISE USINGRAISE level USING,并把其余所有内容放入USING列表。 + + 还有另一种变体是写RAISE USINGRAISE level USING,并把其余内容都放在USING列表里。 + - 最后一种RAISE变体完全不带参数。这种形式只能用于BEGIN块的EXCEPTION子句内部;它会重新抛出当前正在处理的错误。 + + RAISE的最后一种变体根本没有参数。这种形式只能被用在一个BEGIN块的EXCEPTION子句中,它导致当前正在被处理的错误被重新抛出。 + @@ -2593,7 +2656,7 @@ RAISE unique_violation USING MESSAGE = 'Duplicate user ID: ' || user_id; - 当用 SQLSTATE 代码指定错误代码时,你并不受限于预定义错误代码,而是可以选择任何由五位数字和/或大写 ASCII 字母构成的错误代码,唯一不能使用的是 00000。我们建议尽量避免抛出以三个零结尾的错误代码,因为这些是类别代码,只能用于捕获整个类别。 + 当用 SQLSTATE 代码指定错误代码时,你并不受限于预定义错误代码,而是可以选择任何由五位数字和/或大写 ASCII 字母构成的错误代码,唯一不能使用的是 00000。我们建议尽量避免抛出以三个零结尾的错误代码,因为这些是类别代码,只能通过捕获整个类别来捕获这类错误。 @@ -2605,12 +2668,12 @@ RAISE unique_violation USING MESSAGE = 'Duplicate user ID: ' || user_id; ASSERT - in PL/pgSQL + 在 PL/pgSQL 中 - assertions - in PL/pgSQL + 断言 + 在 PL/pgSQL 中 @@ -2627,15 +2690,14 @@ ASSERT condition , condition是一个布尔 表达式,它被期望总是计算为真。如果确实如此, - ASSERT语句不会再做什么。但如果结果是假 - 或者空,那么将发生一个ASSERT_FAILURE异常(如果在计算 + ASSERT语句不会再做什么。但如果结果是假或者空值,那么将发生一个ASSERT_FAILURE异常(如果在计算 condition时发生错误, 它会被报告为一个普通错误)。 如果提供了可选的message, - 它是一个结果(如果非空)被用来替换默认错误消息文本 + 它是一个结果(如果不为 NULL)被用来替换默认错误消息文本 assertion failed的表达式(如果 condition失败)。 message表达式在 @@ -2789,11 +2851,11 @@ ASSERT condition , - INSTEAD OF触发器(总是行级触发器,并且可能只被用于视图)能够返回空来表示它们没有执行任何更新,并且对该行剩余的操作可以被跳过(即后续的触发器不会被引发,并且该行不会被计入外围INSERT/UPDATE/DELETE的行影响状态中)。否则一个非空值应该被返回用以表示该触发器执行了所请求的操作。对于INSERTUPDATE操作,返回值应该是NEW,触发器函数可能对它进行了修改来支持INSERT RETURNINGUPDATE RETURNING(这也将影响被传递给任何后续触发器的行值,或者被传递给带有ON CONFLICT DO UPDATEINSERT语句中一个特殊的EXCLUDED别名引用)。对于DELETE操作,返回值应该是OLD。 + INSTEAD OF触发器(总是行级触发器,并且只能用于视图)能够返回 null 来表示它们没有执行任何更新,并且对该行剩余的操作应被跳过(即后续的触发器不会被引发,并且该行不会被计入外围INSERT/UPDATE/DELETE的行影响状态中)。否则应该返回一个非 null 值用以表示该触发器执行了所请求的操作。对于INSERTUPDATE操作,返回值应该是NEW,触发器函数可能对它进行了修改来支持INSERT RETURNINGUPDATE RETURNING(这也将影响被传递给任何后续触发器的行值,或者被传递给带有ON CONFLICT DO UPDATEINSERT语句中一个特殊的EXCLUDED别名引用)。对于DELETE操作,返回值应该是OLD - 一个AFTER行级触发器或一个BEFOREAFTER语句级触发器的返回值总是会被忽略,它可能也是空。不过,任何这些类型的触发器可能仍会通过抛出一个错误来中止整个操作。 + 一个AFTER行级触发器或一个BEFOREAFTER语句级触发器的返回值总是会被忽略,因此也可以返回 null。不过,任何这些类型的触发器可能仍会通过抛出一个错误来中止整个操作。 @@ -2968,15 +3030,15 @@ INSTEAD OF INSERT OR UPDATE OR DELETE ON emp_view - 一个 <application>PL/pgSQL</application> 用于维护汇总表的触发器函数 + 一个用于维护汇总表的 <application>PL/pgSQL</application> 触发器函数 - 这里详述的模式有一部分是基于 Ralph Kimball 所作的数据仓工具包中的Grocery Store示例。 + 这里详述的模式有一部分是基于 Ralph Kimball 所作的数据仓库工具包中的Grocery Store示例。 -- --- Main tables - time dimension and sales fact. +-- 主表 - 时间维度和销售事实。 -- CREATE TABLE time_dimension ( time_key integer NOT NULL, @@ -2999,7 +3061,7 @@ CREATE TABLE sales_fact ( CREATE INDEX sales_fact_time ON sales_fact(time_key); -- --- Summary table - sales by time. +-- 汇总表 - 按时间汇总销售 -- CREATE TABLE sales_summary_bytime ( time_key integer NOT NULL, @@ -3010,7 +3072,7 @@ CREATE TABLE sales_summary_bytime ( CREATE UNIQUE INDEX sales_summary_bytime_key ON sales_summary_bytime(time_key); -- --- Function and trigger to amend summarized column(s) on UPDATE, INSERT, DELETE. +-- 在 UPDATE、INSERT、DELETE 时修改汇总列的函数和触发器。 -- CREATE OR REPLACE FUNCTION maint_sales_summary_bytime() RETURNS TRIGGER AS $maint_sales_summary_bytime$ @@ -3021,7 +3083,7 @@ AS $maint_sales_summary_bytime$ delta_amount_cost numeric(15,2); BEGIN - -- Work out the increment/decrement amount(s). + -- 算出增量/减量数。 IF (TG_OP = 'DELETE') THEN delta_time_key = OLD.time_key; @@ -3031,9 +3093,8 @@ AS $maint_sales_summary_bytime$ ELSIF (TG_OP = 'UPDATE') THEN - -- forbid updates that change the time_key - - -- (probably not too onerous, as DELETE + INSERT is how most - -- changes will be made). + -- 禁止修改 time_key + -- (可能不会太麻烦,因为大部分的更改是用 DELETE + INSERT 完成的)。 IF ( OLD.time_key != NEW.time_key) THEN RAISE EXCEPTION 'Update of time_key : % -> % not allowed', OLD.time_key, NEW.time_key; @@ -3053,8 +3114,7 @@ AS $maint_sales_summary_bytime$ END IF; - - -- Insert or update the summary row with the new values. + -- 插入或更新带有新值的汇总行。 <<insert_update>> LOOP UPDATE sales_summary_bytime @@ -3082,7 +3142,7 @@ AS $maint_sales_summary_bytime$ EXCEPTION WHEN UNIQUE_VIOLATION THEN - -- do nothing + -- 什么也不做 END; END LOOP insert_update; @@ -3116,7 +3176,7 @@ SELECT * FROM sales_summary_bytime; 使用过渡表审计 - 这个示例产生和相同的结果,但并未使用一个为每一行都触发的触发器,而是在把相关信息收集到一个过渡表中之后用了一个只为每个语句引发一次的触发器。当调用语句修改了很多行时,这种方法明显比行触发器方法快。注意我们必须为每一种事件建立一个单独的触发器声明,因为每种情况的REFERENCING子句必须不同。但是这并不能阻止我们使用单一的触发器函数(实际上,使用三个单独的函数会更好,因为可以避免在TG_OP上的运行时测试)。 + 这个示例产生和相同的结果,但并未使用一个为每一行都触发的触发器,而是在把相关信息收集到一个过渡表中之后用了一个只为每个语句引发一次的触发器。当调用语句修改了很多行时,这种方法可能显著快于行触发器方法。注意我们必须为每一种事件建立一个单独的触发器声明,因为每种情况的REFERENCING子句必须不同。但是这并不能阻止我们使用单一的触发器函数(实际上,使用三个单独的函数可能会更好,因为可以避免在TG_OP上的运行时测试)。 @@ -3227,9 +3287,7 @@ CREATE EVENT TRIGGER snitch ON ddl_command_start EXECUTE FUNCTION snitch(); <application>PL/pgSQL</application> 内部机制 - - 这一节讨论了一些PL/pgSQL用户应该知道的一些重要的实现细节。 - + 本节讨论一些实现细节,了解这些细节对 PL/pgSQL 用户通常很重要。 变量替换 @@ -3300,7 +3358,7 @@ CREATE FUNCTION stamp_user(id int, comment text) RETURNS void AS $$ END; $$ LANGUAGE plpgsql; - 在UPDATE命令中,curtimecomment以及id将引用该函数的变量和参数,不管users有没有这些名称的列。注意,我们不得不在WHERE子句中对users.id的引用加以限定,以便让它引用表列。但是我们不需要在UPDATE列表中把对comment的引用限定为一个目标,因为语法上那必须是users的一列。我们可以用下面的方式写一个相同的不依赖于variable_conflict设置的函数: + 在UPDATE命令中,curtimecomment以及id将引用该函数的变量和参数,不管users有没有这些名称的列。注意,我们不得不在WHERE子句中对users.id的引用加以限定,以便让它引用表列。但是我们不需要对UPDATE列表中作为目标的comment引用加以限定,因为语法上那必须是users的一列。我们可以用下面的方式写一个相同的不依赖于variable_conflict设置的函数: CREATE FUNCTION stamp_user(id int, comment text) RETURNS void AS $$ <<fn>> @@ -3339,7 +3397,7 @@ $$ LANGUAGE plpgsql; - PL/pgSQL(更准确地说,是 SPI 管理器)还会尝试缓存与某个预备语句相关的执行计划。如果没有使用缓存计划,那么每次执行该语句时都会生成新的执行计划,而当前参数值(也就是 PL/pgSQL 变量值)可用于优化所选计划。如果该语句没有参数,或者会被执行很多次,SPI 管理器就会考虑创建一个不依赖具体参数值的通用计划,并将其缓存起来供重复使用。通常只有在执行计划对其中引用的 PL/pgSQL 变量值不太敏感时,才会这样做。如果执行计划对参数值非常敏感,那么每次重新生成计划总体上反而更划算。关于预备语句的行为,详见 。 + PL/pgSQL(更准确地说,是 SPI 管理器)还可以尝试缓存与某个预备语句相关的执行计划。如果没有使用缓存计划,那么每次执行该语句时都会生成新的执行计划,而当前参数值(也就是 PL/pgSQL 变量值)可用于优化所选计划。如果该语句没有参数,或者会被执行很多次,SPI 管理器就会考虑创建一个不依赖具体参数值的通用计划,并将其缓存起来供重复使用。通常只有在执行计划对其中引用的 PL/pgSQL 变量值不太敏感时,才会这样做。如果执行计划对参数值非常敏感,那么每次重新生成计划总体上反而更划算。关于预备语句的行为,详见 @@ -3388,7 +3446,7 @@ $$ LANGUAGE plpgsql; - 在logfunc2中,PostgreSQL的主解析器不知道应该把'now'解释成什么类型,因此返回一个text类型的数据值,其中包含字符串now。在确定对本地变量curtime的赋值时,PL/pgSQL解释器通过调用用于该转换的textouttimestamp_in函数,把这个字符串转换为timestamp类型。因此,计算得到的时间戳会按程序员预期在每次执行时更新。虽然这恰好能得到预期结果,但效率并不高,因此使用now()函数仍然是更好的主意。 + 在logfunc2中,PostgreSQL的主解析器不知道应该把'now'解释成什么类型,因此返回一个text类型的数据值,其中包含字符串now。在随后给局部变量curtime赋值时,PL/pgSQL解释器通过调用用于该转换的textouttimestamp_in函数,把这个字符串转换为timestamp类型。因此,计算得到的时间戳会按程序员预期在每次执行时更新。虽然这恰好能得到预期结果,但效率并不高,因此使用now()函数仍然是更好的主意。 @@ -3416,14 +3474,14 @@ $$ LANGUAGE plpgsql; - 另一种开发PL/pgSQL的好方法,是使用有助于过程语言开发的 GUI 数据库访问工具。这类工具的一个例子是pgAdmin,当然也有其他工具。它们通常提供一些方便的特性,例如转义单引号,以及让重新创建和调试函数变得更容易。 + 另一种使用PL/pgSQL进行开发的好方法,是使用有助于过程语言开发的 GUI 数据库访问工具。这类工具的一个例子是pgAdmin,当然也有其他工具。它们通常提供一些方便的特性,例如转义单引号,以及让重新创建和调试函数变得更容易。 引号的处理 - 一个PL/pgSQL函数的代码在一个CREATE FUNCTION中被指定为一个字符串。如果你用通常的方式把该字符串写在单引号中间,那么该函数体中的任何单引号都必须被双写;同样任何反斜线也必须被双写(假定使用了转义字符串语法)。双写引号最多有点冗长,并且在更复杂的情况中代码会变得完全无法理解,因为你很容易发现你需要半打或者更多相邻的引号。我们推荐你转而把函数体写成一个美元引用的字符串(见)。在美元引用方法中,你从不需要双写任何引号。但是要注意为你需要的每一层嵌套选择一个不同的美元引用定界符。例如,你可能把CREATE FUNCTION命令写成: + 一个PL/pgSQL函数的代码在一个CREATE FUNCTION中被指定为一个字符串字面量。如果你用通常的方式把该字符串写在单引号中间,那么该函数体中的任何单引号都必须被双写;同样任何反斜线也必须被双写(假定使用了转义字符串语法)。双写引号本身就很繁琐,并且在更复杂的情况中代码会变得完全无法理解,因为你很容易发现你需要半打或者更多相邻的引号。我们推荐你转而把函数体写成一个美元引用的字符串(见)。在美元引用方法中,你从不需要双写任何引号。但是要注意为你需要的每一层嵌套选择一个不同的美元引用定界符。例如,你可能把CREATE FUNCTION命令写成: CREATE OR REPLACE FUNCTION testfunc(integer) RETURNS integer AS $PROC$ .... @@ -3458,7 +3516,7 @@ CREATE FUNCTION foo() RETURNS integer AS ' - 用于函数体内的字符串,例如: + 用于函数体内的字符串字面量,例如: a_output := ''Blah''; SELECT * FROM users WHERE f_name=''foobar''; @@ -3468,7 +3526,7 @@ SELECT * FROM users WHERE f_name=''foobar''; a_output := 'Blah'; SELECT * FROM users WHERE f_name='foobar'; - 这恰好就是PL/pgSQL在两种情况中会看到的。 + 这恰好就是PL/pgSQL解析器在两种情况中会看到的。 @@ -3490,7 +3548,7 @@ a_output := a_output || '' AND name LIKE ''''foobar'''' AND xyz'' a_output := a_output || $$ AND name LIKE 'foobar' AND xyz$$ - 要小心在这周围的任何美元引用定界符不只是$$。 + 要小心在这周围的任何美元引用定界符都不能是$$ @@ -3521,7 +3579,7 @@ a_output := a_output || $$ AND name LIKE 'foobar'$$ - 当你想在一个字符串常量(占 8 个引号)中有两个单引号时并且这会挨着该字符串常量的末尾(另外 2 个)。如果你正在写一个产生其他函数的函数(如中),你将很可能只需要这种。例如: + 当字符串常量中需要两个单引号(这需要 8 个引号),而且它们紧邻该字符串常量的末尾(还需 2 个引号)时。通常只有在编写生成其他函数的函数时(如所示),才会需要这种写法。例如: a_output := a_output || '' if v_'' || referrer_keys.kind || '' like '''''''''' @@ -3562,11 +3620,13 @@ a_output := a_output || $$ if v_$$ || referrer_keys.kind || $$ like '$$ 因此建议你在一个单独的开发环境中进行测试。 - - 根据需要设置 plpgsql.extra_warningsplpgsql.extra_errors,适当情况下,在开发和/或测试环境中可以设置为 "all"。 - + 建议在开发和/或测试环境中,根据需要将 plpgsql.extra_warningsplpgsql.extra_errors 设置为 "all" - 这些额外检查通过配置变量启用,其中plpgsql.extra_warnings用于警告,plpgsql.extra_errors用于错误。两者都可以设为逗号分隔的检查项列表、"none""all"。默认值为"none"。当前可用的检查包括: + + 这些额外的检查通过配置变量plpgsql.extra_warnings来启用警告, + 以及plpgsql.extra_errors来启用错误。两者都可以设置为逗号分隔的检查列表,"none""all"。 + 默认值为"none"。目前可用的检查列表包括: + shadowed_variables @@ -3598,7 +3658,10 @@ a_output := a_output || $$ if v_$$ || referrer_keys.kind || $$ like '$$ - 下面的例子展示了此设置的效果:plpgsql.extra_warnings设为shadowed_variables: + + + 以下示例显示了将plpgsql.extra_warnings设置为 + shadowed_variables的效果: SET plpgsql.extra_warnings TO 'shadowed_variables'; @@ -3613,7 +3676,9 @@ WARNING: variable "f1" shadows a previously defined variable LINE 3: f1 int; ^ CREATE FUNCTION -下面的例子展示了另一设置的效果:plpgsql.extra_warnings设为strict_multi_assignment: + + 以下示例显示了将plpgsql.extra_warnings设置为 + strict_multi_assignment的效果: SET plpgsql.extra_warnings TO 'strict_multi_assignment'; @@ -3675,7 +3740,7 @@ HINT: Make sure the query returns the exact list of columns. - 在PostgreSQL中,函数体必须写成字符串文本。因此你需要使用美元符引用或者转义函数体中的单引号(见)。 + 在PostgreSQL中,函数体必须写成字符串字面量。因此你需要使用美元符引用或者转义函数体中的单引号(见)。 @@ -3764,13 +3829,13 @@ show errors; - 在PostgreSQL中,函数体被认为是一个字符串,所以你需要使用引号或者美元符号包围它。这代替了Oracle 方法中的用于终止的/。 + 在PostgreSQL中,函数体被认为是一个字符串字面量,所以你需要使用引号或者美元引用定界符包围它。这代替了Oracle 方法中的用于终止的/ - 在PostgreSQL中没有show errors命令, 并且也不需要这个命令,因为错误是自动报告的。 + 在PostgreSQL中没有show errors命令, 并且也不需要这个命令,因为错误是自动报告的。 @@ -3801,9 +3866,7 @@ $$ LANGUAGE plpgsql; 从<application>PL/SQL</application>移植一个创建另一个函数的函数到<application>PL/pgSQL</application> - - 下面的过程从一个SELECT语句抓取行,并且为了效率而构建一个带有IF语句中结果的大型函数。 - + 下面的过程从 SELECT 语句读取行,并将结果写入 IF 语句,从而构造一个大型函数,以提高效率。 这是 Oracle 版本: @@ -3881,12 +3944,14 @@ $func$ LANGUAGE plpgsql; 下面的Oracle PL/SQL 过程被用来解析一个 URL 并且返回一些元素(主机、路径和查询)。 - 这是 Oracle 版本: + + 这是 Oracle 版本: + CREATE OR REPLACE PROCEDURE cs_parse_url( v_url IN VARCHAR2, - v_host OUT VARCHAR2, -- This will be passed back - v_path OUT VARCHAR2, -- This one too - v_query OUT VARCHAR2) -- And this one + v_host OUT VARCHAR2, -- 这个值将被返回 + v_path OUT VARCHAR2, -- 这个也是 + v_query OUT VARCHAR2) -- 还有这个 IS a_pos1 INTEGER; a_pos2 INTEGER; @@ -3922,13 +3987,14 @@ show errors; - 下面是一种可行的移植写法,目标语言为PL/pgSQL: + + 这里给出一种可能的 PL/pgSQL 写法: CREATE OR REPLACE FUNCTION cs_parse_url( v_url IN VARCHAR, - v_host OUT VARCHAR, -- This will be passed back - v_path OUT VARCHAR, -- This one too - v_query OUT VARCHAR) -- And this one + v_host OUT VARCHAR, -- 这个值将被返回 + v_path OUT VARCHAR, -- 这个也是 + v_query OUT VARCHAR) -- 还有这个 AS $$ DECLARE a_pos1 INTEGER; @@ -3961,20 +4027,26 @@ BEGIN v_query := substr(v_url, a_pos1 + 1); END; $$ LANGUAGE plpgsql; -该函数可以这样使用: + + + 这个函数可以这样使用: + SELECT * FROM cs_parse_url('http://foobar.com/query.cgi?baz'); - 展示了如何移植一个使用了多种 Oracle 特性的过程。 + 展示了如何移植一个使用了多种 Oracle 专属特性的过程。 从<application>PL/SQL</application>移植一个过程到<application>PL/pgSQL</application> - Oracle 版本: + + Oracle 版本: + + CREATE OR REPLACE PROCEDURE cs_create_job(v_job_id IN INTEGER) IS a_running_job_count INTEGER; BEGIN @@ -3983,7 +4055,7 @@ BEGIN SELECT count(*) INTO a_running_job_count FROM cs_jobs WHERE end_stamp IS NULL; IF a_running_job_count > 0 THEN - COMMIT; -- free lock + COMMIT; -- 释放锁 raise_application_error(-20000, 'Unable to create a new job: a job is currently running.'); END IF; @@ -3994,7 +4066,7 @@ BEGIN BEGIN INSERT INTO cs_jobs (job_id, start_stamp) VALUES (v_job_id, now()); EXCEPTION - WHEN dup_val_on_index THEN NULL; -- don't worry if it already exists + WHEN dup_val_on_index THEN NULL; -- 如果已经存在也不用担心 END; COMMIT; END; @@ -4003,7 +4075,8 @@ show errors - 下面展示了如何移植这个过程,目标语言为PL/pgSQL: + + 下面展示了如何将这个过程移植到PL/pgSQL CREATE OR REPLACE PROCEDURE cs_create_job(v_job_id integer) AS $$ @@ -4015,7 +4088,7 @@ BEGIN SELECT count(*) INTO a_running_job_count FROM cs_jobs WHERE end_stamp IS NULL; IF a_running_job_count > 0 THEN - COMMIT; -- free lock + COMMIT; -- 释放锁 RAISE EXCEPTION 'Unable to create a new job: a job is currently running'; -- END IF; @@ -4026,7 +4099,7 @@ BEGIN INSERT INTO cs_jobs (job_id, start_stamp) VALUES (v_job_id, now()); EXCEPTION WHEN unique_violation THEN -- - -- don't worry if it already exists + -- 如果已经存在不要担心 END; COMMIT; END; @@ -4077,7 +4150,7 @@ EXCEPTION END; - 如果你正在移植一个以这种方式使用SAVEPOINTROLLBACK TO的 Oracle 过程,工作会比较简单:只要忽略SAVEPOINTROLLBACK TO即可。如果你的 Oracle 过程以不同方式使用SAVEPOINTROLLBACK TO,那就需要认真思考了。 + 如果你正在移植一个以这种方式使用SAVEPOINTROLLBACK TO的 Oracle 过程,工作会比较简单:只要省略SAVEPOINTROLLBACK TO即可。如果你的 Oracle 过程以不同方式使用SAVEPOINTROLLBACK TO,那就需要认真思考了。 @@ -4094,11 +4167,11 @@ END; 优化 <application>PL/pgSQL</application> 函数 - PostgreSQL提供了两种函数创建修饰符来优化执行:volatility(对于给定的相同参数,函数是否总是返回相同的结果)以及strictness (如果任何参数为空,函数是否返回空)。详见参考页。 + PostgreSQL提供了两种函数创建修饰符来优化执行:volatility(对于给定的相同参数,函数是否总是返回相同的结果)以及strictness (如果任何参数为空值,函数是否返回空值)。详见参考页。 - 在利用这些优化属性时,你的CREATE FUNCTION语句应该看起来像这样: + 在利用这些优化属性时,你的CREATE FUNCTION语句可能像这样: CREATE FUNCTION foo(...) RETURNS integer AS $$ diff --git a/zh/13/plpython.sgml b/zh/13/plpython.sgml index 06ececbd..14212557 100644 --- a/zh/13/plpython.sgml +++ b/zh/13/plpython.sgml @@ -110,7 +110,7 @@ CREATE FUNCTION funcname (argument-list) RETURNS return-type AS $$ - # PL/Python function body + # PL/Python 函数体 $$ LANGUAGE plpythonu; @@ -150,7 +150,7 @@ def __plpython_procedure_pymax_23456(): CREATE FUNCTION pystrip(x text) RETURNS text AS $$ - x = x.strip() # error + x = x.strip() # 错误 return x $$ LANGUAGE plpythonu; @@ -160,7 +160,7 @@ CREATE FUNCTION pystrip(x text) RETURNS text AS $$ global x - x = x.strip() # ok now + x = x.strip() # 现在可以正常工作 return x $$ LANGUAGE plpythonu; @@ -176,7 +176,10 @@ $$ LANGUAGE plpythonu; 数据类型映射 - 调用 PL/Python 函数时,参数会从 PostgreSQL 数据类型转换为相应的 Python 类型: + + 调用 PL/Python 函数时,其参数会从 PostgreSQL 数据类型转换为相应的 Python 类型: + + PostgreSQL boolean 会转换为 Python bool。 @@ -213,8 +216,9 @@ $$ LANGUAGE plpythonu; - 所有其他数据类型,包括 PostgreSQL 字符串类型, - 都会转换为 Python str(和所有 Python 字符串一样,都是 Unicode)。 + 所有其他数据类型,包括 PostgreSQL 字符串类型,都会转换为 Python + str。在 Python 2 中,该字符串采用 PostgreSQL 服务器编码; + 在 Python 3 中,它与所有字符串一样,都是 Unicode 字符串。 @@ -226,7 +230,10 @@ $$ LANGUAGE plpythonu; - PL/Python 函数返回时,返回值按以下规则转换为该函数声明的 PostgreSQL 返回数据类型: + + 当 PL/Python 函数返回时,其返回值会按如下方式转换成该函数声明的 PostgreSQL 返回数据类型: + + 当 PostgreSQL 返回类型为boolean时,返回值会按照Python规则进行真值判定。也就是说,0 和空字符串为假,但值得注意的是,'f' 为真。 @@ -243,7 +250,10 @@ $$ LANGUAGE plpythonu; - 字符串在传给 PostgreSQL 时,会自动转换为 PostgreSQL 服务器编码。 + Python 2 中的字符串传给 PostgreSQL 时,必须采用 PostgreSQL 服务器编码。 + 在当前服务器编码中无效的字符串会引发错误,但并非所有编码不匹配都能被检测到, + 因此处理不当仍可能产生乱码数据。Unicode 字符串会自动转换为正确的编码, + 因而使用它们可能更安全、更方便。在 Python 3 中,所有字符串都是 Unicode 字符串。 @@ -252,7 +262,10 @@ $$ LANGUAGE plpythonu; 对于非标量数据类型,请参见下文。 - 注意,如果声明的 PostgreSQL 返回类型与实际返回对象的 Python 数据类型在逻辑上不匹配,系统不会提示;无论如何都会转换该值。 + + + 请注意,即使声明的 PostgreSQL 返回类型与实际返回对象的 Python 数据类型在逻辑上并不匹配,也不会报错;无论如何该值都会被转换。 + @@ -354,12 +367,19 @@ $$ LANGUAGE plpythonu; - 从 Python 函数返回行类型或复合类型,有多种方式。以下示例假定已定义: + + 有多种方法可以从 Python 函数返回行类型或复合类型。以下示例假定我们有: + + CREATE TYPE named_value AS ( name text, value integer ); -复合结果可以用以下形式返回: + + + 复合结果可以按以下形式返回: + + 序列类型(元组或列表,但不能是集合,因为集合不可通过索引访问) @@ -368,7 +388,7 @@ CREATE FUNCTION make_pair (name text, value integer) RETURNS named_value AS $$ return ( name, value ) - # or alternatively, as list: return [ name, value ] + # 也可以使用列表: return [ name, value ] $$ LANGUAGE plpythonu; 要为某一列返回 SQL 空值,请将 None 放在对应位置。 @@ -406,7 +426,7 @@ AS $$ self.value = v return named_value(name, value) - # or simply + # 或者简写为 class nv: pass nv.name = name nv.value = value @@ -444,12 +464,19 @@ CALL python_triple(5, 10); 集合返回函数 - 一个 PL/Python 函数也可以返回标量类型或复合类型的集合。实现方式有多种,因为返回对象在内部会被转换为迭代器。以下示例假定已定义复合类型: + + PL/Python函数也可以返回标量类型或复合类型的集合。实现方式有多种,因为返回的对象在内部会被转换成一个迭代器。以下示例假定我们有如下复合类型: + + CREATE TYPE greeting AS ( how text, who text ); -集合结果可以通过以下形式返回: + + + 集合结果可以通过以下对象返回: + + 序列类型(元组、列表、集合) @@ -458,8 +485,8 @@ CREATE TYPE greeting AS ( CREATE FUNCTION greet (how text) RETURNS SETOF greeting AS $$ - # return tuple containing lists as composite types - # all other combinations work also + # 返回包含列表的元组,以列表表示复合类型 + # 其他组合方式也都可用 return ( [ how, "World" ], [ how, "PostgreSQL" ], [ how, "PL/Python" ] ) $$ LANGUAGE plpythonu; @@ -517,7 +544,7 @@ $$ LANGUAGE plpythonu; - 也支持带OUT参数的返回集函数(使用RETURNS SETOF record)。例如: + 也支持带OUT参数的集合返回函数(使用RETURNS SETOF record)。例如: CREATE FUNCTION multiout_simple_setof(n integer, OUT integer, OUT integer) RETURNS SETOF record AS $$ return [(1, 2)] * n @@ -552,7 +579,7 @@ SELECT * FROM multiout_simple_setof(3); DO $$ - # PL/Python code + # PL/Python 代码 $$ LANGUAGE plpythonu; @@ -799,7 +826,7 @@ CREATE FUNCTION usesavedplan() RETURNS trigger AS $$ else: plan = plpy.prepare("SELECT 1") SD["plan"] = plan - # rest of function + # 函数的其余部分 $$ LANGUAGE plpythonu; @@ -816,11 +843,11 @@ $$ LANGUAGE plpythonu; - 游标对象提供fetch方法,它接受一个整数参数并返回结果对象。每次调用fetch,返回对象都会包含下一批行,数量不会超过该参数值。一旦所有行都已取完,fetch就会开始返回空结果对象。游标对象还提供迭代器接口,每次产生一行,直到所有行为止。以这种方式获取的数据不会作为结果对象返回,而是以字典形式返回,每个字典对应一行结果。 + 游标对象提供fetch方法,它接受一个整数参数并返回结果对象。每次调用fetch,返回对象都会包含下一批行,数量不会超过该参数值。一旦所有行都已取完,fetch就会开始返回空结果对象。游标对象还提供迭代器接口,每次产生一行,直到取完所有行。以这种方式获取的数据不会作为结果对象返回,而是以字典形式返回,每个字典对应一行结果。 - 下面示例展示了如何处理大表中的数据: + 下面示例展示了处理大表中数据的两种方式: CREATE FUNCTION count_odd_iterator() RETURNS integer AS $$ odd = 0 @@ -846,7 +873,7 @@ $$ LANGUAGE plpythonu; CREATE FUNCTION count_odd_prepared() RETURNS integer AS $$ odd = 0 plan = plpy.prepare("select num from largetable where num % $1 <> 0", ["integer"]) -rows = list(plpy.cursor(plan, [2])) # or: = list(plan.cursor([2])) +rows = list(plpy.cursor(plan, [2])) # 或者:= list(plan.cursor([2])) return len(rows) $$ LANGUAGE plpythonu; @@ -950,9 +977,9 @@ $$ LANGUAGE plpythonu; - 旧式 Python 2 用法 + 较早的 Python 版本 - 使用 with 关键字的上下文管理器语法,从 Python 2.6 起默认可用。为了兼容更早的 Python 版本,可以调用子事务管理器的 __enter____exit__ 函数,也可以使用它们的便捷别名 enterexit。转账示例函数可以写成: + 使用 with 关键字的上下文管理器语法,从 Python 2.6 起默认可用。为了兼容更早的 Python 版本,可以通过便捷别名 enterexit,调用子事务管理器的 __enter____exit__ 函数。转账示例函数可以写成: CREATE FUNCTION transfer_funds_old() RETURNS void AS $$ try: subxact = plpy.subtransaction() @@ -1012,7 +1039,7 @@ CALL transaction_test1(); - 实用函数 + 辅助函数 plpy模块还提供以下函数: @@ -1066,7 +1093,7 @@ PL/Python function "raise_custom_exception" - 另一组实用函数是plpy.quote_literal(string)plpy.quote_nullable(string)以及plpy.quote_ident(string)。它们等价于中描述的内置引用函数。在构造临时查询时,这些函数很有用。中动态 SQL 的一个 PL/Python 等价写法如下: + 另一组辅助函数是plpy.quote_literal(string)plpy.quote_nullable(string)以及plpy.quote_ident(string)。它们等价于中描述的内置加引号函数。在构造临时查询时,这些函数很有用。中动态 SQL 的一个 PL/Python 等价写法如下: plpy.execute("UPDATE tbl SET %s = %s WHERE key = %s" % ( plpy.quote_ident(colname), diff --git a/zh/13/pltcl.sgml b/zh/13/pltcl.sgml index b00c2386..7fe50022 100644 --- a/zh/13/pltcl.sgml +++ b/zh/13/pltcl.sgml @@ -12,7 +12,7 @@ - PL/Tcl 是一种适用于 PostgreSQL 数据库系统的可载入的过程语言,它允许使用 Tcl 语言 来编写 PostgreSQL 函数和过程。 + PL/Tcl 是一种适用于 PostgreSQL 数据库系统的可加载的过程语言,它允许使用 Tcl 语言 来编写 PostgreSQL 函数和过程。 @@ -53,7 +53,7 @@ CREATE FUNCTION funcname (argument-types) RETURNS return-type AS $$ - # PL/Tcl function body + # PL/Tcl 函数体 $$ LANGUAGE pltcl; @@ -74,11 +74,11 @@ CREATE FUNCTION tcl_max(integer, integer) RETURNS integer AS $$ $$ LANGUAGE pltcl STRICT; - 注意STRICT子句,它让我们不必考虑空输入值:如果传入的是空值,函数根本不会被调用,而是会自动返回空结果。 + 注意STRICT子句,它让我们不必考虑空值输入:如果传入的是空值,函数根本不会被调用,而是会自动返回空值结果。 - 在非严格函数中,如果某个参数的实际值为空,对应的$n变量会被设置为空串。要检测某个特定参数是否为空,可使用函数argisnull。例如,假设我们希望在tcl_max的两个参数中一个为空、一个非空时返回非空参数,而不是返回空值: + 在非严格函数中,如果某个参数的实际值为空值,对应的$n变量会被设置为空串。要检测某个特定参数是否为空值,可使用函数argisnull。例如,假设我们希望在tcl_max的两个参数中一个为空值、一个非空值时返回非空值参数,而不是返回空值: CREATE FUNCTION tcl_max(integer, integer) RETURNS integer AS $$ @@ -98,7 +98,7 @@ $$ LANGUAGE pltcl; - 复合类型参数会作为 Tcl 数组传递给函数。数组元素名就是该复合类型的属性名。如果传入行中的某个属性为 NULL,它就不会出现在数组中。下面是一个示例: + 复合类型参数会作为 Tcl 数组传递给函数。数组元素名就是该复合类型的属性名。如果传入行中的某个属性为空值,它就不会出现在数组中。下面是一个示例: CREATE TABLE employee ( @@ -184,7 +184,7 @@ $$ LANGUAGE pltcl; PL/Tcl 中的数据值 - 提供给 PL/Tcl 函数代码的参数值,只是将输入参数转换成文本形式(就像用SELECT语句将它们显示出来一样)。反过来,returnreturn_next命令会接受任何字符串,只要它是该函数声明结果类型或组合结果类型中指定列的可接受输入格式。 + 提供给 PL/Tcl 函数代码的参数值,只是将输入参数转换成文本形式(就像用SELECT语句将它们显示出来一样)。反过来,returnreturn_next命令会接受任何字符串,只要它是该函数声明结果类型或复合结果类型中指定列的可接受输入格式。 @@ -194,8 +194,8 @@ $$ LANGUAGE pltcl; PL/Tcl 中的全局数据 - global data - in PL/Tcl + 全局数据 + 在 PL/Tcl 中 @@ -222,14 +222,17 @@ $$ LANGUAGE pltcl; 从 PL/Tcl 访问数据库 - 本节遵循 Tcl 的惯例,在语法概要中用问号而不是方括号表示可选元素。在 PL/Tcl 函数体中可以使用以下命令访问数据库: + + 在本节中,我们遵循 Tcl 的通常约定,用问号而不是方括号来表示语法摘要中的可选元素。下列命令可用于从 PL/Tcl 函数体中访问数据库: + + spi_exec -count n -array name command loop-body - 执行以字符串形式给出的 SQL 命令。命令出错时会引发错误。否则,spi_exec的返回值是该命令处理的行数(选出、插入、更新或删除的行),如果命令是实用程序语句则返回零。此外,如果命令是SELECT语句,则所选列的值会按下文所述放入 Tcl 变量中。 + 执行以字符串形式给出的 SQL 命令。命令出错时会引发错误。否则,spi_exec的返回值是该命令处理的行数(选出、插入、更新或删除的行),如果命令是工具语句则返回零。此外,如果命令是SELECT语句,则所选列的值会按下文所述放入 Tcl 变量中。 @@ -270,7 +273,7 @@ spi_exec -array C "SELECT * FROM pg_class" { - 如果查询结果中的某一列为空,则对应的目标变量会被unset,而不是被设值。 + 如果查询结果中的某一列为空值,则对应的目标变量会被unset,而不是被设值。 @@ -282,7 +285,7 @@ spi_exec -array C "SELECT * FROM pg_class" { 准备并保存一个查询计划以供后续执行。保存的计划会在当前会话的整个生命周期内保留。 准备查询 - 在PL/Tcl中 + 在 PL/Tcl 中 @@ -312,7 +315,7 @@ spi_exec -array C "SELECT * FROM pg_class" { 可选的-nulls值是由空格和'n'字符组成的字符串,用来告诉spi_execp哪些参数是空值。 - 如果给出,它的长度必须与value-list完全相同。如果未给出,则所有参数值都视为非空。 + 如果给出,它的长度必须与value-list完全相同。如果未给出,则所有参数值都视为非空值。 @@ -326,7 +329,7 @@ spi_exec -array C "SELECT * FROM pg_class" { CREATE FUNCTION t1_count(integer, integer) RETURNS integer AS $$ if {![ info exists GD(plan) ]} { - # prepare the saved plan on the first call + # 在首次调用时准备并保存计划 set GD(plan) [ spi_prepare \ "SELECT count(*) AS cnt FROM t1 WHERE num >= \$1 AND num <= \$2" \ [ list int4 int4 ] ] @@ -361,7 +364,7 @@ $$ LANGUAGE pltcl; 将给定字符串中的所有单引号和反斜杠字符都加倍。 - 这可用于安全地引用那些要插入到传给spi_execspi_prepare的 SQL 命令中的字符串。 + 这可用于安全地为那些要插入到传给spi_execspi_prepare的 SQL 命令中的字符串加引号。 例如,考虑如下 SQL 命令字符串: @@ -387,7 +390,7 @@ SELECT 'doesn''t' AS ret "SELECT '[ quote $val ]' AS ret" - spi_execp的一个优点是,你不必像这样对参数值做引用,因为这些参数永远不会作为 SQL 命令字符串的一部分被解析。 + spi_execp的一个优点是,你不必像这样给参数值加引号,因为这些参数永远不会作为 SQL 命令字符串的一部分被解析。 @@ -397,7 +400,7 @@ SELECT 'doesn''t' AS ret elog level msg elog - 在PL/Tcl中 + 在 PL/Tcl 中 @@ -428,14 +431,17 @@ SELECT 'doesn''t' AS ret PL/Tcl 中的触发器函数 - trigger - in PL/Tcl + 触发器 + 在 PL/Tcl 中 触发器函数也可以用 PL/Tcl 编写。PostgreSQL要求,凡是要作为触发器调用的函数,都必须声明为无参数且返回类型为trigger - 触发器管理器的信息通过以下变量传入函数体: + + 来自触发器管理器的信息会通过下列变量传递给函数体: + + $TG_name @@ -513,7 +519,7 @@ SELECT 'doesn''t' AS ret $NEW - 对于INSERTUPDATE动作,这是一个包含新表行值的关联数组;对于DELETE则为空。该数组以列名为索引。值为 NULL 的列不会出现在数组中。对于语句级触发器,不会设置这个变量。 + 对于INSERTUPDATE动作,这是一个包含新表行值的关联数组;对于DELETE则为空。该数组以列名为索引。值为空值的列不会出现在数组中。对于语句级触发器,不会设置这个变量。 @@ -522,7 +528,7 @@ SELECT 'doesn''t' AS ret $OLD - 对于UPDATEDELETE动作,这是一个包含旧表行值的关联数组;对于INSERT则为空。该数组以列名为索引。值为 NULL 的列不会出现在数组中。对于语句级触发器,不会设置这个变量。 + 对于UPDATEDELETE动作,这是一个包含旧表行值的关联数组;对于INSERT则为空。该数组以列名为索引。值为空值的列不会出现在数组中。对于语句级触发器,不会设置这个变量。 @@ -585,20 +591,23 @@ CREATE TRIGGER trig_mytab_modcount BEFORE INSERT OR UPDATE ON mytab PL/Tcl 中的事件触发器函数 - event trigger - in PL/Tcl + 事件触发器 + 在 PL/Tcl 中 事件触发器函数也可以用 PL/Tcl 编写。PostgreSQL要求,凡是要作为事件触发器调用的函数,都必须声明为无参数且返回类型为event_trigger - 触发器管理器的信息通过以下变量传入函数体: + + 来自触发器管理器的信息会通过下列变量传递给函数体: + + $TG_event - 触发器因其而被触发的事件名称。 + 该触发器所针对的事件名称。 @@ -607,7 +616,7 @@ CREATE TRIGGER trig_mytab_modcount BEFORE INSERT OR UPDATE ON mytab $TG_tag - 触发器因其而被触发的命令标签。 + 该触发器所针对的命令标签。 @@ -615,10 +624,13 @@ CREATE TRIGGER trig_mytab_modcount BEFORE INSERT OR UPDATE ON mytab - 事件触发器函数的返回值会被忽略。 + 触发器函数的返回值会被忽略。 - 下面是一个简单的事件触发器函数示例,每当执行受支持的命令时,它只发出一条 NOTICE 消息: + + 下面是一个小型事件触发器函数示例。每当执行受支持的命令时,它都会简单地发出一条NOTICE消息: + + CREATE OR REPLACE FUNCTION tclsnitch() RETURNS event_trigger AS $$ elog NOTICE "tclsnitch: $TG_event $TG_tag" $$ LANGUAGE pltcl; @@ -632,8 +644,8 @@ CREATE EVENT TRIGGER tcl_a_snitch ON ddl_command_start EXECUTE FUNCTION tclsnitc PL/Tcl 中的错误处理 - exceptions - in PL/Tcl + 异常 + 在 PL/Tcl 中 @@ -661,9 +673,9 @@ if {[catch { spi_exec $sql_command }]} { if {[lindex $::errorCode 0] == "POSTGRES"} { array set errorArray $::errorCode if {$errorArray(condition) == "undefined_table"} { - # deal with missing table + # 处理表不存在的情况 } else { - # deal with some other type of SQL error + # 处理其他类型的 SQL 错误 } } } @@ -677,8 +689,8 @@ if {[catch { spi_exec $sql_command }]} { PL/Tcl 中的显式子事务 - subtransactions - in PL/Tcl + 子事务 + 在 PL/Tcl 中 @@ -776,7 +788,7 @@ CALL transaction_test1(); pltcl.start_proc (string) - pltcl.start_proc configuration parameter + pltcl.start_proc 配置参数 @@ -804,7 +816,7 @@ CALL transaction_test1(); pltclu.start_proc (string) - pltclu.start_proc configuration parameter + pltclu.start_proc 配置参数 @@ -823,7 +835,7 @@ CALL transaction_test1(); Tcl 过程名 - 在PostgreSQL中,只要参数个数或参数类型不同,就可以复用同一个函数名。不过,Tcl 要求所有过程名都必须不同。PL/Tcl 通过让内部 Tcl 过程名包含系统表pg_proc中该函数的对象 ID 来解决这个问题。因此,名称相同而参数类型不同的PostgreSQL函数,也会对应不同的 Tcl 过程。这通常不是 PL/Tcl 程序员需要关心的事情,但在调试时可能会看到。 + 在PostgreSQL中,只要参数个数或参数类型不同,就可以复用同一个函数名。不过,Tcl 要求所有过程名都必须不同。PL/Tcl 处理这一问题的方式是:在内部 Tcl 过程名中包含系统表 pg_proc 中的函数对象 ID 作为其名称的一部分。因此,名称相同但参数类型不同的PostgreSQL函数,也会对应不同的 Tcl 过程。这通常不是 PL/Tcl 程序员需要关心的事情,但在调试时可能会看见。 diff --git a/zh/13/postgres-fdw.sgml b/zh/13/postgres-fdw.sgml index 116b729b..ce32f25f 100644 --- a/zh/13/postgres-fdw.sgml +++ b/zh/13/postgres-fdw.sgml @@ -272,7 +272,7 @@ OPTIONS (ADD password_required 'false'); 该选项是一个以逗号分隔的 PostgreSQL 扩展 名称列表,这些扩展必须在本地和远程服务器上都已安装且版本兼容。 - 属于列出扩展且为 immutable 的函数和操作符,将被视为可下推到远程服务器 + 属于列出扩展且不可变的函数和操作符,将被视为可下推到远程服务器 执行。该选项只能为外部服务器指定,不能按表指定。 @@ -454,8 +454,7 @@ OPTIONS (ADD password_required 'false'); - 请注意,postgres_fdw 当前不支持将远程事务预备为 - 两阶段提交。 + 请注意,postgres_fdw 当前不支持为两阶段提交预备远程事务。 @@ -466,9 +465,9 @@ OPTIONS (ADD password_required 'false'); postgres_fdw 会尽力优化远程查询,以减少从外部 服务器传输的数据量。这是通过将查询的 WHERE 子句发送到 远程服务器执行,以及不获取当前查询不需要的表列来实现的。为降低查询被 - 错误执行的风险,除非 WHERE 子句仅使用内置数据类型、 - 操作符和函数,或属于外部服务器 extensions 选项列出的 - 扩展,否则不会将其发送到远程服务器。这类子句中的操作符和函数还必须是 + 错误执行的风险,只有当 WHERE 子句使用的所有数据类型、 + 操作符和函数都是内置的,或属于外部服务器 extensions + 选项列出的扩展时,才会将该子句发送到远程服务器。这类子句中的操作符和函数还必须是 IMMUTABLE。对于 UPDATEDELETE 查询,postgres_fdw 会在 查询中不存在无法发送到远程服务器的 WHERE 子句、没有 diff --git a/zh/13/protocol.sgml b/zh/13/protocol.sgml index 2b174232..856f9698 100644 --- a/zh/13/protocol.sgml +++ b/zh/13/protocol.sgml @@ -763,7 +763,12 @@ SELCT 1/0; 只要后端认为前端应当知晓的某个参数的当前有效值发生变化,就会生成 ParameterStatus 消息。最常见的情况是响应前端执行的SET命令,这种情况实际上是同步的;但也可能是管理员修改了配置文件,然后向服务器发送SIGHUP信号,从而导致参数状态发生变化。同样,如果某条SET命令被回滚,也会生成适当的 ParameterStatus 消息,用于报告当前生效的值。 - 目前,会为一组固定的参数生成 ParameterStatus,包括 server_versionserver_encodingclient_encodingapplication_nameis_superusersession_authorizationDateStyleIntervalStyleTimeZoneinteger_datetimesstandard_conforming_strings。(8.0 之前的版本不报告 server_encodingTimeZoneinteger_datetimes;8.1 之前的版本不报告 standard_conforming_strings;8.4 之前的版本不报告 IntervalStyle;9.0 之前的版本不报告 application_name。)注意,server_versionserver_encodinginteger_datetimes 是启动后不能改变的伪参数。这组参数将来可能变化,甚至可能变为可配置。因此,前端应直接忽略其不理解或不关心的参数的 ParameterStatus。 + + 目前,会为一组固定的参数生成 ParameterStatus,参数如下: + server_versionserver_encodingclient_encodingapplication_nameis_superusersession_authorizationDateStyleIntervalStyleTimeZoneinteger_datetimesstandard_conforming_strings。 + (8.0 之前的版本不报告 server_encodingTimeZoneinteger_datetimes;8.1 之前的版本不报告 standard_conforming_strings;8.4 之前的版本不报告 IntervalStyle;9.0 之前的版本不报告 application_name。) + 注意,server_versionserver_encodinginteger_datetimes 是启动后不能改变的伪参数。这组参数将来可能变化,甚至可能变为可配置。因此,前端应直接忽略其不理解或不关心的参数的 ParameterStatus。 + 如果前端发出一个LISTEN命令, 那么无论何时在为同一个通道名NOTIFY时,后端将发送一个NotificationResponse消息(不要和NoticeResponse搞混!)。 @@ -1166,7 +1171,9 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" output_plugin - 用于逻辑解码的输出插件名称(参见 )。 + + 用于逻辑解码的输出插件的名称(参见)。 + @@ -1174,8 +1181,8 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" TEMPORARY - 该命令导出的快照标识符。该快照在此连接上执行下一条命令之前,或复制连接关闭之前有效。如果所创建的是物理复制槽,则为 null。 - + 指定此复制槽为临时槽。临时槽不会保存到磁盘,并且在错误或会话结束时会自动删除。 + @@ -1196,11 +1203,14 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 作为对此命令的响应,服务器会发送仅含一行的结果集,其中包含以下字段: + + 在响应此命令时,服务器将发送一个包含以下字段的单行结果集: slot_name (text) - 新建复制槽的名称。 + + 新创建的复制槽的名称。 + @@ -1217,7 +1227,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" snapshot_name (text) - 该命令导出的快照标识符。该快照在此连接上执行下一条命令之前,或复制连接关闭之前有效。如果所创建的是物理复制槽,则为 null。 + 该命令导出的快照标识符。该快照在此连接上执行下一条命令之前,或复制连接关闭之前有效。如果所创建的是物理复制槽,则为空值。 @@ -1226,7 +1236,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" output_plugin (text) - 新建复制槽所使用的输出插件名称。如果所创建的是物理复制槽,则为 null。 + 新建复制槽所使用的输出插件名称。如果所创建的是物理复制槽,则为空值。 @@ -1550,14 +1560,19 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" BASE_BACKUP - 指示服务器开始以流式方式传输基础备份。备份开始前,系统会自动进入备份模式,并在备份完成后退出该模式。可以使用以下选项: + + 指示服务器开始流式传输基础备份。 + 在备份开始之前,系统将自动进入备份模式,并在备份完成后退出备份模式。 + 接受以下选项: + + LABEL 'label' 设置备份的标签。如果未指定,则将使用base backup作为备份标签。 - 标签的引用规则与打开的标准SQL字符串相同。 + 标签的引号使用规则与打开的标准SQL字符串相同。 @@ -1566,8 +1581,12 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" PROGRESS - 请求生成进度报告所需的信息。这将在每个表空间的头部发回大致大小,可用于计算流式传输的完成进度。此大小通过在传输开始之前枚举所有文件大小来计算,因此可能对性能有负面影响。特别是在第一个数据被发出之前可能需要更长的时间。 - + 请求生成进度报告所需的信息。这将在每个表空间的首部发送一个近似大小, + 可用于计算流式传输的进度。这是通过在传输开始之前先枚举所有文件大小来计算的, + 可能会对性能产生负面影响。特别是,在流式传输数据之前可能需要更长的时间。 + 由于备份期间数据库文件可能会发生变化,因此大小仅为近似值, + 在估算与实际发送文件之间的这段时间里可能会增长或缩小。 + @@ -1584,9 +1603,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" WAL - - 如果设置为true,则在备份中包含必要的WAL段。这将包括在开始和停止备份之间的所有文件在基本目录tar文件的pg_wal目录中。默认值为false。 - + 在备份中包含必要的 WAL 段。这会把开始备份到停止备份之间的所有文件放入基础目录 tar 文件内的pg_wal目录中。 @@ -1614,8 +1631,8 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 如果为true,则在名为tablespace_map的文件中包含目录pg_tblspc中存在的符号链接的信息。 - 表空间映射文件包括目录pg_tblspc/中每个符号链接的名称及该符号链接的完整路径。默认值为false。 + 在名为tablespace_map的文件中包含目录pg_tblspc中存在的符号链接的信息。 + 表空间映射文件包括目录pg_tblspc/中每个符号链接的名称及该符号链接的完整路径。 @@ -1637,7 +1654,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" 除了可能包含的任何WAL文件。它还存储每个文件的大小、最后修改时间, 以及可选的校验和。 值为force-encode会强制对所有文件名进行十六进制编码; - 否则,仅对文件名为非UTF8八位序列的文件执行此类型的编码。 + 否则,仅对文件名为非 UTF8 字节序列的文件执行此类型的编码。 force-encode主要用于测试目的,以确保读取备份清单的客户端 能够处理这种情况。为了与之前的版本兼容,默认值为MANIFEST 'no' @@ -1658,21 +1675,21 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - + 备份开始时,服务器首先发送两个普通结果集,然后发送一个或多个 CopyResponse 结果。 第一个普通结果集包含备份的起始位置,在一个包含两列的单行中。第一列包含以XLogRecPtr格式给出的起始位置,第二列包含相应的时间线ID。 第二个普通结果集中的每个表空间都有一行。 - 这一行中的字段是: + 这一行中的字段是: spcoid (oid) - 表空间的OID,如果是基本目录则为null。 + 表空间的OID,如果是基础目录则为null。 @@ -1681,7 +1698,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" spclocation (text) - 表空间目录的完整路径,如果是基本目录则为null。 + 表空间目录的完整路径,如果是基础目录则为null。 @@ -1723,13 +1740,11 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - - 不记录 WAL 的关系(Unlogged表),除了需要在恢复时重新创建(空的)不记录 WAL 的关系的init fork。 - + 不记录 WAL 的关系,但不包括恢复时重新创建(空的)不记录 WAL 的关系所需的初始化分支。 - pg_wal,包括子目录。如果备份包含WAL文件,则将包含pg_wal的合成版本,但它只包含备份工作所需的文件,而不包含其余内容。 + pg_wal,包括子目录。如果备份包含WAL文件,则将包含pg_wal的合成版本,但它只包含使备份可用所需的文件,而不包含其余内容。 @@ -1742,7 +1757,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 除了常规文件和目录之外的文件,如符号链接(除了上述列出的目录之外的符号链接)以及特殊设备和操作系统文件,将被跳过。(pg_tblspc中的符号链接将被保留。) + 除了普通文件和目录之外的文件,如符号链接(除了上述列出的目录之外的符号链接)以及特殊设备文件,将被跳过。(pg_tblspc中的符号链接将被保留。) @@ -1775,7 +1790,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 逻辑复制参数 + 逻辑流复制参数 使用START_REPLICATION命令,pgoutput接受以下选项: @@ -1788,7 +1803,9 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" publication_names - 要订阅(接收更改)的发布名称列表,以逗号分隔。各个发布名称按标准对象名称处理,必要时可以同样使用引号。至少需要一个发布名称。 + + 要订阅(接收变更)的发布名称列表,以逗号分隔。各个发布名称按标准对象名处理,可按需加引号。至少需要一个发布名称。 + @@ -2436,33 +2453,51 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" -CancelRequest (F) + +CancelRequest (F) + -Int32(16) + + Int32(16) + -消息内容的长度,以字节为单位,包括此长度字段本身。 + + 消息内容的长度,以字节为单位,包括此长度字段本身。 + -Int32(80877102) + + Int32(80877102) + -取消请求代码。此值的最高 16 位为 1234,最低 16 位为 5678。(为避免混淆,此代码不能与任何协议版本号相同。) + + 取消请求代码。此值的最高 16 位为 1234,最低 16 位为 5678。(为避免混淆,此代码不能与任何协议版本号相同。) + -Int32 + + Int32 + -目标后端的进程 ID。 + + 目标后端的进程 ID。 + -Int32 + + Int32 + -目标后端的密钥。 + + 目标后端的密钥。 + @@ -4145,7 +4180,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 严重性: 字段内容为ERROR, FATAL, 或 + 严重性: 字段内容为ERROR, FATAL, 或 PANIC (在错误消息中), 或 WARNING, NOTICE, DEBUG, INFO, 或 LOG (在通知消息中), @@ -4183,7 +4218,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 消息: 主要的人类可读错误消息。 + 消息: 主要的人类可读错误消息。 这应该准确但简洁(通常一行)。 总是存在。 @@ -4205,7 +4240,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 提示: 关于问题应该怎么做的一个可选建议。 + 提示: 关于问题应该怎么做的一个可选建议。 这意在与细节不同,它提供建议(可能不合适)而不是硬性事实。 可能会跨越多行。 @@ -4238,7 +4273,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" q - 内部查询: 一个失败的内部生成命令的文本。 + 内部查询: 一个失败的内部生成命令的文本。 例如,这可能是由PL/pgSQL函数发出的SQL查询。 @@ -4271,7 +4306,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 表名: 如果错误与特定表相关联,则为表的名称。(有关表模式名称的名称,请参考模式名称字段。) + 表名: 如果错误与特定表相关联,则为表的名称。(有关表模式名称的名称,请参考模式名称字段。) @@ -4281,7 +4316,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 列名: 如果错误与特定表列相关联,则为列的名称。(请参考模式和表名字段以识别表。) + 列名: 如果错误与特定表列相关联,则为列的名称。(请参考模式和表名字段以识别表。) @@ -4291,7 +4326,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 数据类型名称: 如果错误与特定数据类型相关联,则为数据类型的名称。 + 数据类型名称: 如果错误与特定数据类型相关联,则为数据类型的名称。 (有关数据类型模式的名称,请参阅模式名称字段。) @@ -4302,7 +4337,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 约束名称: 如果错误与特定约束相关联,则为约束的名称。请参考上面列出的字段,了解相关表或域。 + 约束名称: 如果错误与特定约束相关联,则为约束的名称。请参考上面列出的字段,了解相关表或域。 (为此,即使索引不是使用约束语法创建的,也将其视为约束。) @@ -4313,7 +4348,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 文件: 报告错误的源代码位置的文件名。 + 文件: 报告错误的源代码位置的文件名。 @@ -4866,13 +4901,13 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" -协议 3.0 与之前版本的变化总结 +自协议 2.0 以来的变更总结 - 本节概述了协议 3.0 与之前协议版本之间的变化。这可以帮助那些需要实现同时处理多种协议版本的客户端库的开发者,或仅仅出于好奇的读者。 - + 本节提供一份简要的变更清单,供准备将现有客户端库更新到协议 3.0 的开发者参考。 + -初始启动包采用灵活的字符串列表格式,取代了固定格式。注意,运行时参数的会话默认值现在可以直接在启动包中指定。(实际上,以前也能通过 options 字段实现,但由于 options 的宽度有限,且无法引用值中的空白,这种方法并不稳妥。) +初始启动包采用灵活的字符串列表格式,取代了固定格式。注意,运行时参数的会话默认值现在可以直接在启动包中指定。(实际上,以前也能通过 options 字段实现,但由于 options 的宽度有限,且无法用引号保护值中的空白字符,这种方法并不稳妥。) 现在,所有消息都在消息类型字节之后紧跟一个长度计数(启动包除外,它没有类型字节)。另请注意,PasswordMessage 现在也有类型字节。 diff --git a/zh/13/queries.sgml b/zh/13/queries.sgml index 8e1f3318..25e43080 100644 --- a/zh/13/queries.sgml +++ b/zh/13/queries.sgml @@ -487,7 +487,7 @@ FROM (VALUES ('anne', 'smith'), ('bob', 'jones'), ('joe', 'blow')) - 表函数是那些生成行集合的函数,这些行可以由基本数据类型(标量类型)组成,也可以由复合数据类型(表行)组成。它们在查询的FROM子句中用法类似于表、视图或子查询。表函数返回的列可以像表、视图或子查询的列一样,出现在SELECTJOINWHERE子句中。 + 表函数是那些生成行集合的函数,这些行可以由基础类型(标量类型)组成,也可以由复合数据类型(表行)组成。它们在查询的FROM子句中用法类似于表、视图或子查询。表函数返回的列可以像表、视图或子查询的列一样,出现在SELECTJOINWHERE子句中。 @@ -525,7 +525,7 @@ UNNEST( array_expression , ... - 如果没有提供列的别名,那么对于一个返回基数据类型的函数,列名也与该函数 + 如果没有提供列的别名,那么对于一个返回基础类型的函数,列名也与该函数 名相同。对于一个返回复合类型的函数,结果列会从该类型的属性得到名称。 diff --git a/zh/13/rangetypes.sgml b/zh/13/rangetypes.sgml index 8457287b..e29cda85 100644 --- a/zh/13/rangetypes.sgml +++ b/zh/13/rangetypes.sgml @@ -159,21 +159,25 @@ SELECT '[4,4)'::int4range; 构造范围 - 每个范围类型都有一个与其同名的构造函数。使用构造函数通常比编写范围字面常量更方便,因为无需对边界值额外加引号。构造函数接受两个或三个参数。两个参数的形式构造标准形式的范围(包含下界,不包含上界);三个参数的形式则按第三个参数指定的形式构造范围边界。第三个参数必须是以下字符串之一:(), - (], - [)[]。例如: --- The full form is: lower bound, upper bound, and text argument indicating --- inclusivity/exclusivity of bounds. + + 每种范围类型都有一个与范围类型同名的构造函数。使用构造函数通常比书写范围字面量更方便,因为这样无需为界限值额外加引号。构造函数接受两个或三个参数。两个参数的形式构造标准形式的范围(下界包含,上界排除),而三个参数的形式则按第三个参数指定的界限形式构造范围。第三个参数必须是下列字符串之一: + ()、 + (]、 + [)或者 + []。 + 例如: + + +-- 完整形式为:下界、上界,以及指示界限包含性/排除性的文本参数。 SELECT numrange(1.0, 14.0, '(]'); --- If the third argument is omitted, '[)' is assumed. +-- 如果省略第三个参数,则假定为 '[)'。 SELECT numrange(1.0, 14.0); --- Although '(]' is specified here, on display the value will be converted to --- canonical form, since int8range is a discrete range type (see below). +-- 虽然这里指定的是 '(]',但显示时该值会转换为规范形式,因为 int8range 是离散范围类型(见下文)。 SELECT int8range(1, 14, '(]'); --- Using NULL for either bound causes the range to be unbounded on that side. +-- 任一界限使用 NULL 都会使该侧无界。 SELECT numrange(NULL, 2.2); diff --git a/zh/13/ref/abort.sgml b/zh/13/ref/abort.sgml index b5512cbc..9413e79e 100644 --- a/zh/13/ref/abort.sgml +++ b/zh/13/ref/abort.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ABORT 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/alter_aggregate.sgml b/zh/13/ref/alter_aggregate.sgml index c5bd8344..3daf286a 100644 --- a/zh/13/ref/alter_aggregate.sgml +++ b/zh/13/ref/alter_aggregate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER AGGREGATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/alter_collation.sgml b/zh/13/ref/alter_collation.sgml index 803c5b87..92973ce4 100644 --- a/zh/13/ref/alter_collation.sgml +++ b/zh/13/ref/alter_collation.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER COLLATION 7 - SQL - Language Statements + SQL - 语言语句 @@ -95,7 +95,8 @@ ALTER COLLATION name SET SCHEMA new_sche 注解 - 创建排序规则对象时,该排序规则的提供者特定版本会记录在系统目录中。 + 使用 ICU 库提供的排序规则时,创建排序规则对象会在系统目录中记录 + ICU 给出的排序器版本。 使用该排序规则时,会将当前版本与记录的版本进行比较;如果二者不匹 配,就会发出警告,例如: @@ -105,18 +106,18 @@ HINT: Rebuild all objects affected by this collation and run ALTER COLLATION pg 排序规则定义的变化可能导致索引损坏及其他问题,因为数据库系统依赖已 存储对象具有特定的排序顺序。一般来说应避免这种情况,但在某些合理情 - 形下仍可能发生,例如将操作系统升级到新的主版本,或者使用 + 形下仍可能发生,例如使用 pg_upgrade升级到链接了较新 ICU 版本的服务器二进 制文件时。出现这种情况时,应重建所有依赖该排序规则的对象,例如使用 REINDEX。完成后,可以使用命令 ALTER COLLATION ... REFRESH VERSION刷新排序规则 - 版本。这样会更新系统目录,使其记录当前的排序规则版本,并让该警告消 + 版本。这样会更新系统目录,使其记录当前的排序器版本,并让该警告消 失。请注意,这实际上并不会检查所有受影响对象是否都已被正确重建。 使用libc提供的排序规则时,如果PostgreSQL是使用 GNU C 库构建的,则使用 C 库的版本作为排序规则版本。由于排序规则定义通常只会随 GNU C 库版本发布而更改,这可以在一定程度上防止损坏,但并不完全可靠。 目前,数据库默认排序规则没有版本跟踪。 - 可以使用以下查询找出当前数据库中所有需要刷新的排序规则,以及依赖这些排序规则的对象:以下查询可用于识别当前数据库中所有需要刷新的排序规则,以及依赖它们的对象: ALTER CONVERSION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/alter_database.sgml b/zh/13/ref/alter_database.sgml index 516bc49b..9132cf6d 100644 --- a/zh/13/ref/alter_database.sgml +++ b/zh/13/ref/alter_database.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER DATABASE 7 - SQL - Language Statements + SQL - 语言语句 @@ -59,7 +59,9 @@ ALTER DATABASE name RESET ALL 第三种形式更改数据库的所有者。要更改所有者,必须拥有该数据库,并且还必须是新所有者角色的直接或间接成员,并且必须拥有CREATEDB权限。(请注意,超级用户会自动拥有所有这些权限。) - 第四种形式更改数据库的默认表空间。只有数据库所有者或超级用户可以执行此操作;还必须拥有新表空间的创建权限。此命令会将数据库旧默认表空间中的所有表或索引物理移动到新表空间。对该数据库而言,新默认表空间必须为空,并且不能有任何人连接到该数据库。非默认表空间中的表和索引不受影响。 + + 第四种形式更改数据库的默认表空间。只有数据库拥有者或者超级用户可以这样做;你还必须对新表空间具有创建权限。该命令会将数据库旧默认表空间中的所有表和索引在物理上移动到新表空间中。对于该数据库而言,新默认表空间必须为空,并且不能有人连接到该数据库。位于非默认表空间中的表和索引不受影响。 + 其余形式会更改某个PostgreSQL数据库的运行时配置变量的会话默认值。此后每当在该数据库中启动一个新会话时,指定的值就会成为会话默认值。数据库特定的默认值会覆盖postgresql.conf中的设置,或者从postgres命令行接收到的设置。只有数据库拥有者或者超级用户才能更改该数据库的会话默认值。某些变量不能以这种方式设置,或者只能由超级用户设置。 @@ -82,9 +84,7 @@ ALTER DATABASE name RESET ALL allowconn - - 如果为假,则没有人能连接到这个数据库。 - + 如果为 false,则任何人都不能连接到该数据库。 @@ -100,7 +100,9 @@ ALTER DATABASE name RESET ALL istemplate - 如果为 true,则任何拥有CREATEDB权限的用户都可以克隆该数据库;如果为 false,则只有超级用户或数据库所有者可以克隆它。 + + 如果为 true,则任何具有 CREATEDB 权限的用户都可以克隆该数据库;如果为 false,则只有超级用户或该数据库的拥有者可以克隆它。 + @@ -139,9 +141,17 @@ ALTER DATABASE name RESET ALL configuration_parameter value - 将此数据库的会话默认值设置为指定配置参数的给定值。如果指定valueDEFAULT,或者等效地使用RESET,则删除数据库特定设置,因此新会话将继承系统范围的默认设置。使用RESET ALL清除所有数据库特定设置。SET FROM CURRENT将会话当前参数值保存为数据库特定值。 + + 将此数据库在指定配置参数上的会话默认值设为给定值。如果 + valueDEFAULT,或者等效地使用了 + RESET,则数据库特定设置会被移除,因此新会话将继承系统范围的默认设置。使用 + RESET ALL可清除所有数据库特定设置。 + SET FROM CURRENT会把该参数在当前会话中的值保存为数据库特定值。 + - 有关允许的参数名称和值的更多信息,请参见 + + 关于允许的参数名和值的更多信息,见。 + diff --git a/zh/13/ref/alter_default_privileges.sgml b/zh/13/ref/alter_default_privileges.sgml index ca667c52..ba87960d 100644 --- a/zh/13/ref/alter_default_privileges.sgml +++ b/zh/13/ref/alter_default_privileges.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER DEFAULT PRIVILEGES 7 - SQL - Language Statements + SQL - 语言语句 @@ -122,8 +122,8 @@ REVOKE [ GRANT OPTION FOR ] 一个现有模式的名称。如果指定,将修改以后在该模式中创建的对象的默认权限。 如果省略IN SCHEMA,则修改全局默认权限。 - 在为模式和大对象设置权限时,不允许使用IN SCHEMA, - 因为模式不能嵌套,而大对象不属于任何模式。 + 在为模式设置权限时,不允许使用IN SCHEMA, + 因为模式不能嵌套。 diff --git a/zh/13/ref/alter_domain.sgml b/zh/13/ref/alter_domain.sgml index 664851db..6d969a1a 100644 --- a/zh/13/ref/alter_domain.sgml +++ b/zh/13/ref/alter_domain.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER DOMAIN 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/alter_event_trigger.sgml b/zh/13/ref/alter_event_trigger.sgml index 9c259dbe..86b46ee7 100644 --- a/zh/13/ref/alter_event_trigger.sgml +++ b/zh/13/ref/alter_event_trigger.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER EVENT TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -58,7 +58,7 @@ ALTER EVENT TRIGGER name RENAME TO new_owner - 该事件触发器的新拥有者的用户名。 + 该事件触发器的新所有者的用户名。 @@ -94,7 +94,7 @@ ALTER EVENT TRIGGER name RENAME TO - 另见 + 参见 diff --git a/zh/13/ref/alter_extension.sgml b/zh/13/ref/alter_extension.sgml index dd8eac79..86286dec 100644 --- a/zh/13/ref/alter_extension.sgml +++ b/zh/13/ref/alter_extension.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER EXTENSION 7 - SQL - Language Statements + SQL - 语言语句 @@ -71,7 +71,10 @@ ALTER EXTENSION name DROP 描述 - ALTER EXTENSION更改已安装扩展的定义。有几个子形式: + ALTER EXTENSION更改已安装扩展的定义。 + 其子形式如下: + + UPDATE @@ -112,7 +115,10 @@ ALTER EXTENSION name DROP - 有关这些操作的更多信息。 + + + 有关这些操作的更多信息,见。 + 要使用ALTER EXTENSION,你必须拥有该扩展。 diff --git a/zh/13/ref/alter_foreign_data_wrapper.sgml b/zh/13/ref/alter_foreign_data_wrapper.sgml index 18a2bd3c..7121d9c8 100644 --- a/zh/13/ref/alter_foreign_data_wrapper.sgml +++ b/zh/13/ref/alter_foreign_data_wrapper.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER FOREIGN DATA WRAPPER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/alter_foreign_table.sgml b/zh/13/ref/alter_foreign_table.sgml index c4937234..d3ff2978 100644 --- a/zh/13/ref/alter_foreign_table.sgml +++ b/zh/13/ref/alter_foreign_table.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER FOREIGN TABLE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/alter_function.sgml b/zh/13/ref/alter_function.sgml index 1de1639e..1c756136 100644 --- a/zh/13/ref/alter_function.sgml +++ b/zh/13/ref/alter_function.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER FUNCTION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/alter_group.sgml b/zh/13/ref/alter_group.sgml index 26b7f7c8..37888a95 100644 --- a/zh/13/ref/alter_group.sgml +++ b/zh/13/ref/alter_group.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER GROUP 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/alter_index.sgml b/zh/13/ref/alter_index.sgml index d16de8a2..bf6dc915 100644 --- a/zh/13/ref/alter_index.sgml +++ b/zh/13/ref/alter_index.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER INDEX 7 - SQL - Language Statements + SQL - 语言语句 @@ -38,7 +38,11 @@ ALTER INDEX ALL IN TABLESPACE name 描述 - ALTER INDEX更改现有索引的定义。下面介绍几种子形式。请注意,每种子形式所需的锁级别可能不同。除非明确说明,否则会持有一个ACCESS EXCLUSIVE锁。当列出多个子命令时,持有的锁将是所有子命令中所需的最严格锁。 + ALTER INDEX更改现有索引的定义。下面描述了若干种子形式。 + 请注意,每种子形式所需的锁级别可能不同。除非另有明确说明,否则会持有 + ACCESS EXCLUSIVE锁。若列出多个子命令,则持有的锁将是其中任一子命令所需的最严格锁。 + + RENAME diff --git a/zh/13/ref/alter_language.sgml b/zh/13/ref/alter_language.sgml index f9b7bec8..f1f6efc6 100644 --- a/zh/13/ref/alter_language.sgml +++ b/zh/13/ref/alter_language.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER LANGUAGE 7 - SQL - Language Statements + SQL - 语言语句 @@ -31,8 +31,8 @@ ALTER [ PROCEDURAL ] LANGUAGE name OWNER TO { ALTER LANGUAGE更改一种过程语言的定义。 - 目前唯一的功能是重命名该语言或为其指定新的拥有者。 - 要使用ALTER LANGUAGE,你必须是超级用户或者该语言的拥有者。 + 目前唯一的功能是重命名该语言或为其指定新的所有者。 + 要使用ALTER LANGUAGE,你必须是超级用户或者该语言的所有者。 @@ -62,7 +62,7 @@ ALTER [ PROCEDURAL ] LANGUAGE name OWNER TO { new_owner - 该语言的新拥有者 + 该语言的新所有者 diff --git a/zh/13/ref/alter_large_object.sgml b/zh/13/ref/alter_large_object.sgml index f962ec9e..a703b418 100644 --- a/zh/13/ref/alter_large_object.sgml +++ b/zh/13/ref/alter_large_object.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER LARGE OBJECT 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/alter_materialized_view.sgml b/zh/13/ref/alter_materialized_view.sgml index 50695dee..7c5a43bd 100644 --- a/zh/13/ref/alter_materialized_view.sgml +++ b/zh/13/ref/alter_materialized_view.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER MATERIALIZED VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/alter_opclass.sgml b/zh/13/ref/alter_opclass.sgml index 9ea60c82..6d0da98d 100644 --- a/zh/13/ref/alter_opclass.sgml +++ b/zh/13/ref/alter_opclass.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER OPERATOR CLASS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/alter_operator.sgml b/zh/13/ref/alter_operator.sgml index 0ad43b17..6a7c3bcc 100644 --- a/zh/13/ref/alter_operator.sgml +++ b/zh/13/ref/alter_operator.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER OPERATOR 7 - SQL - Language Statements + SQL - 语言语句 @@ -101,7 +101,7 @@ ALTER OPERATOR name ( { left_type - 注解 + 示例 更改自定义操作符的拥有者,该操作符为a @@ b,类型为text diff --git a/zh/13/ref/alter_opfamily.sgml b/zh/13/ref/alter_opfamily.sgml index 76401850..56efd275 100644 --- a/zh/13/ref/alter_opfamily.sgml +++ b/zh/13/ref/alter_opfamily.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER OPERATOR FAMILY 7 - SQL - Language Statements + SQL - 语言语句 @@ -239,7 +239,9 @@ ALTER OPERATOR FAMILY name USING name RENAME TO < CONNECTION 'conninfo' - 该子句替换最初由设置的连接字符串。 + 该子句更改最初由设置的连接属性。 详情请参见该命令。 diff --git a/zh/13/ref/alter_system.sgml b/zh/13/ref/alter_system.sgml index 72f81233..cc40d0e2 100644 --- a/zh/13/ref/alter_system.sgml +++ b/zh/13/ref/alter_system.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER SYSTEM 7 - SQL - Language Statements + SQL - 语言语句 @@ -80,8 +80,7 @@ ALTER SYSTEM RESET ALL - 对于某些接受列表的参数,带引号的值会生成带双引号的输出,以保留空 - 格和逗号;对于另一些参数,则必须在单引号字符串内部使用双引号才能 + 对于某些接受列表的参数,带引号的值会生成带双引号的输出,以保留空白和逗号;对于另一些参数,则必须在单引号字符串内部使用双引号才能 达到这种效果。 diff --git a/zh/13/ref/alter_table.sgml b/zh/13/ref/alter_table.sgml index 4b833ebb..3f1fd90f 100644 --- a/zh/13/ref/alter_table.sgml +++ b/zh/13/ref/alter_table.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TABLE 7 - SQL - Language Statements + SQL - 语言语句 @@ -751,7 +751,7 @@ WITH ( MODULUS numeric_literal, REM - 若要强制立即回收已删除列所占的空间,可以执行任何一种会导致整表重写的ALTER TABLE形式。这样会重新构造每一行,并用空值替换被删除的列。 + 若要强制立即回收已删除列所占的空间,可以执行任何一种会导致整表重写的ALTER TABLE形式。这样会重建每一行,并用空值替换被删除的列。 diff --git a/zh/13/ref/alter_tablespace.sgml b/zh/13/ref/alter_tablespace.sgml index e9613625..31ddf5f4 100644 --- a/zh/13/ref/alter_tablespace.sgml +++ b/zh/13/ref/alter_tablespace.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TABLESPACE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/alter_trigger.sgml b/zh/13/ref/alter_trigger.sgml index 3b370752..74a12947 100644 --- a/zh/13/ref/alter_trigger.sgml +++ b/zh/13/ref/alter_trigger.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -31,7 +31,9 @@ ALTER TRIGGER name ON ALTER TRIGGER更改现有触发器的属性。RENAME子句更改给定触发器的名称,但不以其他方式更改触发器定义。DEPENDS ON EXTENSION子句将触发器标记为依赖扩展,因此扩展被删除时触发器也会自动删除。 - 要更改触发器的属性,必须拥有触发器所在的表。 + + 若要更改触发器的属性,你必须拥有该触发器所作用的表。 + @@ -113,7 +115,7 @@ ALTER TRIGGER emp_stamp ON emp DEPENDS ON EXTENSION emplib; - 另见 + 参见 diff --git a/zh/13/ref/alter_tsconfig.sgml b/zh/13/ref/alter_tsconfig.sgml index ef8f24cf..453d7ee7 100644 --- a/zh/13/ref/alter_tsconfig.sgml +++ b/zh/13/ref/alter_tsconfig.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TEXT SEARCH CONFIGURATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/alter_tsdictionary.sgml b/zh/13/ref/alter_tsdictionary.sgml index 8c11355e..9fedf32d 100644 --- a/zh/13/ref/alter_tsdictionary.sgml +++ b/zh/13/ref/alter_tsdictionary.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TEXT SEARCH DICTIONARY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/alter_tsparser.sgml b/zh/13/ref/alter_tsparser.sgml index 525064c9..0844cb0a 100644 --- a/zh/13/ref/alter_tsparser.sgml +++ b/zh/13/ref/alter_tsparser.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TEXT SEARCH PARSER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/alter_tstemplate.sgml b/zh/13/ref/alter_tstemplate.sgml index fa4157f9..a3eec599 100644 --- a/zh/13/ref/alter_tstemplate.sgml +++ b/zh/13/ref/alter_tstemplate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TEXT SEARCH TEMPLATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/alter_type.sgml b/zh/13/ref/alter_type.sgml index e8af9480..a783e35a 100644 --- a/zh/13/ref/alter_type.sgml +++ b/zh/13/ref/alter_type.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TYPE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/alter_user.sgml b/zh/13/ref/alter_user.sgml index b6544c05..55150300 100644 --- a/zh/13/ref/alter_user.sgml +++ b/zh/13/ref/alter_user.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER USER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/alter_user_mapping.sgml b/zh/13/ref/alter_user_mapping.sgml index 0083f95b..1e7245a4 100644 --- a/zh/13/ref/alter_user_mapping.sgml +++ b/zh/13/ref/alter_user_mapping.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER USER MAPPING 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/alter_view.sgml b/zh/13/ref/alter_view.sgml index db7bf3f4..a177d971 100644 --- a/zh/13/ref/alter_view.sgml +++ b/zh/13/ref/alter_view.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/analyze.sgml b/zh/13/ref/analyze.sgml index affb3890..319283ca 100644 --- a/zh/13/ref/analyze.sgml +++ b/zh/13/ref/analyze.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ANALYZE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/begin.sgml b/zh/13/ref/begin.sgml index dc5eff7b..8c68c21c 100644 --- a/zh/13/ref/begin.sgml +++ b/zh/13/ref/begin.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation BEGIN 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/call.sgml b/zh/13/ref/call.sgml index 64781670..7582f545 100644 --- a/zh/13/ref/call.sgml +++ b/zh/13/ref/call.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CALL 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/checkpoint.sgml b/zh/13/ref/checkpoint.sgml index e9d12c3a..53544983 100644 --- a/zh/13/ref/checkpoint.sgml +++ b/zh/13/ref/checkpoint.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CHECKPOINT 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/close.sgml b/zh/13/ref/close.sgml index 415ec160..deb8a9be 100644 --- a/zh/13/ref/close.sgml +++ b/zh/13/ref/close.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation CLOSE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/cluster.sgml b/zh/13/ref/cluster.sgml index 55f14ec5..9c7e8a0d 100644 --- a/zh/13/ref/cluster.sgml +++ b/zh/13/ref/cluster.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CLUSTER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/clusterdb.sgml b/zh/13/ref/clusterdb.sgml index 0c56bbd2..9711dbbc 100644 --- a/zh/13/ref/clusterdb.sgml +++ b/zh/13/ref/clusterdb.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation clusterdb 1 - Application + 应用程序 diff --git a/zh/13/ref/comment.sgml b/zh/13/ref/comment.sgml index 52b848b5..89b06fe3 100644 --- a/zh/13/ref/comment.sgml +++ b/zh/13/ref/comment.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation COMMENT 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/commit.sgml b/zh/13/ref/commit.sgml index f2ebcbe7..313a9396 100644 --- a/zh/13/ref/commit.sgml +++ b/zh/13/ref/commit.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation COMMIT 7 - SQL - Language Statements + SQL - 语言语句 @@ -39,7 +39,7 @@ COMMIT [ WORK | TRANSACTION ] [ AND [ NO ] CHAIN ] 参数 - chained transactions + 链式事务 diff --git a/zh/13/ref/commit_prepared.sgml b/zh/13/ref/commit_prepared.sgml index dcdba873..734b2833 100644 --- a/zh/13/ref/commit_prepared.sgml +++ b/zh/13/ref/commit_prepared.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation COMMIT PREPARED 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/copy.sgml b/zh/13/ref/copy.sgml index beca70f7..cef3303f 100644 --- a/zh/13/ref/copy.sgml +++ b/zh/13/ref/copy.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation COPY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/create_access_method.sgml b/zh/13/ref/create_access_method.sgml index 0acbda86..53d00429 100644 --- a/zh/13/ref/create_access_method.sgml +++ b/zh/13/ref/create_access_method.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE ACCESS METHOD 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/create_aggregate.sgml b/zh/13/ref/create_aggregate.sgml index afd121d9..2242b429 100644 --- a/zh/13/ref/create_aggregate.sgml +++ b/zh/13/ref/create_aggregate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE AGGREGATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/create_cast.sgml b/zh/13/ref/create_cast.sgml index 353229a1..84a2ce12 100644 --- a/zh/13/ref/create_cast.sgml +++ b/zh/13/ref/create_cast.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE CAST 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/create_collation.sgml b/zh/13/ref/create_collation.sgml index ed8d7d53..4188f01c 100644 --- a/zh/13/ref/create_collation.sgml +++ b/zh/13/ref/create_collation.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE COLLATION 7 - SQL - Language Statements + SQL - 语言语句 @@ -95,7 +95,7 @@ CREATE COLLATION [ IF NOT EXISTS ] name FROM provider - 指定用于与此排序规则关联的区域设置服务的提供者。可能的值为: icuICU libclibc 是默认值。可用选项取决于操作系统和构建选项。 + 指定用于与此排序规则关联的区域设置服务的提供程序。可能的值为: icuICU libclibc 是默认值。可用选项取决于操作系统和构建选项。 @@ -105,7 +105,9 @@ CREATE COLLATION [ IF NOT EXISTS ] name FROM 指定排序规则是否应使用确定性比较。默认值为 true。确定性比较将字节上不相等的字符串视为不相等,即使它们在逻辑上相等。PostgreSQL 使用字节比较来解决歧义。非确定性比较可以使排序规则变为大小写不敏感或重音不敏感。为此,您需要选择适当的 LOCALE 设置 并且 在此处将排序规则设置为非确定性。 - 非确定性排序规则仅在 ICU 提供者下受支持。 + + 非确定性排序规则仅受 ICU 提供程序支持。 + @@ -173,7 +175,9 @@ CREATE COLLATION french (locale = 'fr_FR.utf8'); - 使用 ICU 提供者并采用德语电话簿排序顺序创建排序规则: + + 使用 ICU 提供程序并采用德语电话簿排序顺序创建一种排序规则: + CREATE COLLATION german_phonebook (provider = icu, locale = 'de-u-co-phonebk'); diff --git a/zh/13/ref/create_conversion.sgml b/zh/13/ref/create_conversion.sgml index cf8c5c08..45c3920a 100644 --- a/zh/13/ref/create_conversion.sgml +++ b/zh/13/ref/create_conversion.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE CONVERSION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/create_database.sgml b/zh/13/ref/create_database.sgml index f26529d3..7ddadb6b 100644 --- a/zh/13/ref/create_database.sgml +++ b/zh/13/ref/create_database.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE DATABASE 7 - SQL - Language Statements + SQL - 语言语句 @@ -65,25 +65,36 @@ CREATE DATABASE name name - 要创建的数据库名称。 + + 要创建的数据库名称。 + user_name - 新数据库所有者的角色名称,或使用 DEFAULT 以使用默认值(即执行命令的用户)。要创建由其他角色拥有的数据库,您必须是该角色的直接或间接成员,或为超级用户。 + 新数据库所有者的角色名称,或使用 DEFAULT 以使用默认值(即执行命令的用户)。要创建由其他角色拥有的数据库,你必须是该角色的直接或间接成员,或为超级用户。 template - 用于创建新数据库的模板名称,或使用 DEFAULT 以使用默认模板(template1)。 + + 用于创建新数据库的模板名称,或者指定 DEFAULT + 以使用默认模板(template1)。 + encoding - 新数据库中使用的字符集编码。指定字符串常量(例如 'SQL_ASCII'),或整数编码编号,或使用 DEFAULT 以使用默认编码(即模板数据库的编码)。PostgreSQL 服务器支持的字符集在 中有描述。请参见下方的附加限制。 + + 新数据库要使用的字符集编码。可指定字符串常量(例如 + 'SQL_ASCII')、整数编码编号,或者指定 + DEFAULT 以使用默认编码(即模板数据库的编码)。 + PostgreSQL 服务器支持的字符集见 + 。其他限制见下文。 + @@ -91,7 +102,13 @@ CREATE DATABASE name 这是同时设置 LC_COLLATELC_CTYPE 的快捷方式。如果使用此选项,则不能指定其中任一参数。 - 其他区域设置 不是按数据库固定的,也不会由该命令设置。如果希望为特定数据库设置它们为默认值,可以使用 ALTER DATABASE ... SET + + 其他区域设置参数 、 + 和 + 并不是按数据库固定的,也不会由此命令设置。 + 如果你希望把它们设为某个特定数据库的默认值,可以使用 + ALTER DATABASE ... SET。 + @@ -110,28 +127,40 @@ CREATE DATABASE name tablespace_name - 将与新数据库关联的表空间名称,或使用 DEFAULT 来使用模板数据库的表空间。该表空间将成为在此数据库中创建的对象的默认表空间。有关更多信息,请参见 + + 将与新数据库关联的表空间名称,或者指定 DEFAULT + 以使用模板数据库的表空间。该表空间将成为在此数据库中创建对象时使用的默认表空间。详见 + 。 + allowconn - 如果为 false,则没有人可以连接到此数据库。默认值为 true,允许连接(除非受其他机制(如 GRANT/REVOKE CONNECT)限制)。 + + 如果为 false,则任何人都不能连接到该数据库。默认值为 true,即允许连接 + (但仍受其他机制限制,例如 + GRANT/REVOKE CONNECT)。 + connlimit - 可以同时连接到此数据库的连接数。-1(默认值)表示无限制。 + + 可对该数据库建立的并发连接数。-1(默认值)表示不受限制。 + istemplate - 如果为 true,则任何拥有 CREATEDB 权限的用户都可以克隆此数据库;如果为 false(默认值),则只有超级用户或数据库所有者才能克隆它。 + + 如果为 true,则任何具有 CREATEDB 权限的用户都可以克隆该数据库;如果为 false(默认值),则只有超级用户或该数据库的拥有者可以克隆它。 + @@ -170,11 +199,24 @@ CREATE DATABASE name - 为新数据库指定的字符集编码必须与所选的区域设置(LC_COLLATELC_CTYPE)兼容。如果区域设置为 C(或等效的 POSIX),则允许所有编码,但其他区域设置仅有一种编码能正常工作。(在 Windows 上,UTF-8 编码可与任何区域设置一起使用。)CREATE DATABASE 允许超级用户指定 SQL_ASCII 编码,而不管区域设置如何,但此选择已弃用,如果在数据库中存储了与区域设置不兼容编码的数据,可能导致字符串函数行为异常。 + + 为新数据库指定的字符集编码必须与所选区域设置(LC_COLLATE + 和 LC_CTYPE)兼容。如果区域设置为 C + (或等价的 POSIX),则允许所有编码;但对于其他区域设置,只有一种编码能够正常工作。(不过,在 Windows 上,UTF-8 编码可与任何区域设置一起使用。) + CREATE DATABASE 允许超级用户不考虑区域设置而指定 + SQL_ASCII 编码,但这种选择已弃用;如果数据库中存储了与该区域设置不兼容编码的数据,字符串函数的行为可能会出错。 + - 编码和区域设置必须与模板数据库匹配,除非使用 template0 作为模板。这是因为其他数据库可能包含与指定编码不匹配的数据,或包含受 LC_COLLATELC_CTYPE 影响排序顺序的索引。复制此类数据将导致数据库在新设置下出现损坏。然而,template0 被确认不包含任何会受影响的数据或索引。 + + 编码和区域设置必须与模板数据库的设置一致,除非使用 + template0 作为模板。这是因为其他数据库可能包含与指定编码不匹配的数据,或者包含排序顺序会受 + LC_COLLATELC_CTYPE 影响的索引。复制这样的数据会导致数据库在新设置下被视为损坏。不过,已知 + template0 不包含任何会受此影响的数据或索引。 + - CONNECTION LIMIT 选项仅近似强制执行;如果两个新会话几乎同时启动,而数据库仅剩一个连接 ,则有可能两者都会失败。此外,该限制对超级用户或后台工作进程不生效。 + + CONNECTION LIMIT 选项只是近似地被强制执行;如果两个新会话几乎同时启动,而该数据库只剩下一个连接,则两者都可能失败。此外,该限制对超级用户或后台工作进程无效。 + @@ -188,25 +230,39 @@ CREATE DATABASE lusiadas; - 要创建数据库sales,其所有者为用户 salesapp,默认表空间为 salesspace: + + 要创建一个由用户 salesapp 拥有、默认表空间为 + salesspace 的数据库 sales CREATE DATABASE sales OWNER salesapp TABLESPACE salesspace; - 要创建数据库music,使用不同的区域设置: + + 要创建一个使用不同区域设置的数据库 music: + + CREATE DATABASE music LOCALE 'sv_SE.utf8' TEMPLATE template0; -在此示例中,TEMPLATE template0子句在指定的区域设置与template1中的区域设置不同时是必需的。(如果相同,则显式指定区域设置是多余的。) + + 在这个示例中,如果指定的区域设置与 template1 中的不同, + 则必须使用 TEMPLATE template0 子句。(如果相同, + 那么显式指定区域设置就是多余的。) + - 要创建数据库music2,使用不同的区域设置和不同的字符集编码: + + 要创建一个使用不同区域设置和不同字符集编码的数据库 + music2: + CREATE DATABASE music2 LOCALE 'sv_SE.iso885915' ENCODING LATIN9 TEMPLATE template0; -指定的区域设置和编码设置必须匹配,否则将报告错误。 + + 指定的区域设置和编码设置必须匹配,否则会报错。 + 请注意,区域设置名称是特定于操作系统的,因此上述命令未必在所有环境中都以相同方式工作。 diff --git a/zh/13/ref/create_domain.sgml b/zh/13/ref/create_domain.sgml index b3a10dde..916546fd 100644 --- a/zh/13/ref/create_domain.sgml +++ b/zh/13/ref/create_domain.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE DOMAIN 7 - SQL - Language Statements + SQL - 语言语句 @@ -86,7 +86,7 @@ CREATE DOMAIN name [ AS ] 该域的可选排序规则。如果未指定排序规则,则该域的排序规则行为与其 底层数据类型相同。如果指定了COLLATE,则底层 - 类型必须是一种可排序数据类型。 + 类型必须是一种支持排序规则的数据类型。 diff --git a/zh/13/ref/create_event_trigger.sgml b/zh/13/ref/create_event_trigger.sgml index ddf889db..3659259b 100644 --- a/zh/13/ref/create_event_trigger.sgml +++ b/zh/13/ref/create_event_trigger.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE EVENT TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -40,7 +40,7 @@ CREATE EVENT TRIGGER name CREATE EVENT TRIGGER创建一个新的事件触发器。 每当指定的事件发生,并且与该触发器关联的WHEN条件(如果有)得到 满足时,就会执行该触发器函数。有关事件触发器的一般性介绍,见 - 。创建事件触发器的用户将成为其拥有者。 + 。创建事件触发器的用户将成为其所有者。 @@ -77,8 +77,7 @@ CREATE EVENT TRIGGER name - 用于过滤事件的变量名称。这使得可以将触发器限定为只在支持该变量的部 - 分情形下触发。当前唯一支持的 + 用于过滤事件的变量名称。这样可以将触发器限定为只在原本支持的部分情形下触发。当前唯一支持的 filter_variableTAG @@ -168,7 +167,7 @@ CREATE EVENT TRIGGER abort_ddl ON ddl_command_start - 另见 + 参见 diff --git a/zh/13/ref/create_extension.sgml b/zh/13/ref/create_extension.sgml index aaa58466..7acc3a5e 100644 --- a/zh/13/ref/create_extension.sgml +++ b/zh/13/ref/create_extension.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE EXTENSION 7 - SQL - Language Statements + SQL - 语言语句 @@ -80,7 +80,12 @@ CREATE EXTENSION [ IF NOT EXISTS ] extension_name extension_name - 要安装的扩展的名称。PostgreSQL 将使用 SHAREDIR/extension/extension_name.control 文件中的信息创建扩展。 + + 要安装的扩展名称。PostgreSQL将根据 + SHAREDIR/extension/extension_name.control + 文件中的详细信息创建该扩展。 + @@ -161,7 +166,7 @@ CREATE EXTENSION [ IF NOT EXISTS ] extension_name 会在之后执行编写粗心的扩展脚本时实施攻击,使该用户获得超级用户权限。 不过,只有当特洛伊木马对象在脚本执行期间位于 search_path 中时,它们才会构成危险;这意味着它们 - 位于扩展的安装目标模式中,或位于它所依赖的某个扩展所属的模式中。 + 位于扩展的安装目标模式中,或位于它所依赖的某个扩展的目标模式中。 因此,处理那些脚本尚未经过仔细审查的扩展时,一个经验法则是: 只把它们安装到从未向任何不受信任用户授予、而且今后也不会授予 CREATE 权限的模式中。它们所依赖的任何扩展也应如此。 @@ -183,10 +188,14 @@ CREATE EXTENSION [ IF NOT EXISTS ] extension_name 示例 - 安装hstore扩展到当前数据库,并将其对象放入模式addons: + + 将 hstore 扩展安装到当前数据库中,并把 + 其对象放在 addons 模式中: CREATE EXTENSION hstore SCHEMA addons; -另一种实现相同功能的方法: + + 实现同样效果的另一种方式是: + SET search_path = addons; CREATE EXTENSION hstore; diff --git a/zh/13/ref/create_foreign_data_wrapper.sgml b/zh/13/ref/create_foreign_data_wrapper.sgml index 1eb28864..e7701eb2 100644 --- a/zh/13/ref/create_foreign_data_wrapper.sgml +++ b/zh/13/ref/create_foreign_data_wrapper.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE FOREIGN DATA WRAPPER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/create_foreign_table.sgml b/zh/13/ref/create_foreign_table.sgml index 2a870548..c35b07a1 100644 --- a/zh/13/ref/create_foreign_table.sgml +++ b/zh/13/ref/create_foreign_table.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE FOREIGN TABLE 7 - SQL - Language Statements + SQL - 语言语句 @@ -135,9 +135,7 @@ WITH ( MODULUS numeric_literal, REM COLLATE collation - - COLLATE子句为该列(必须是一种可排序数据类型)指定一个排序规则。如果未指定,则使用该列数据类型的默认排序规则。 - + COLLATE子句为列指定排序规则(该列必须属于支持排序规则的数据类型)。如果未指定,则使用列数据类型的默认排序规则。 diff --git a/zh/13/ref/create_function.sgml b/zh/13/ref/create_function.sgml index 32df87c2..947b4dce 100644 --- a/zh/13/ref/create_function.sgml +++ b/zh/13/ref/create_function.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE FUNCTION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/create_group.sgml b/zh/13/ref/create_group.sgml index 06195a91..9a6538ed 100644 --- a/zh/13/ref/create_group.sgml +++ b/zh/13/ref/create_group.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE GROUP 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/create_index.sgml b/zh/13/ref/create_index.sgml index 7342e310..8d366606 100644 --- a/zh/13/ref/create_index.sgml +++ b/zh/13/ref/create_index.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE INDEX 7 - SQL - Language Statements + SQL - 语言语句 @@ -54,7 +54,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] PostgreSQL提供了索引方法 - B-树、哈希、GiST、SP-GiST、GIN 以及 BRIN。用户也可以定义自己的索引 + B-树、hash、GiST、SP-GiST、GIN 以及 BRIN。用户也可以定义自己的索引 方法,但这相当复杂。 @@ -119,7 +119,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] 对于临时表,CREATE INDEX始终是非并发的, - 因为没有其他会话可以访问它们,而且非并发创建索引的成本更低。 + 因为没有其他会话可以访问它们,而且非并发创建索引的代价更低。 @@ -127,20 +127,41 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] IF NOT EXISTS - 如果已存在同名关系,则不要抛出错误。此时会发出通知。请注意,无法保证现有索引与将要创建的索引有任何相似之处。指定IF NOT EXISTS时必须提供索引名称。 + + 如果同名关系已存在,则不抛出错误,而是发出一个提示。注意, + 现有索引并不保证与本应创建的索引有任何相似之处。指定 + IF NOT EXISTS时,必须提供索引名。 + INCLUDE - 可选的INCLUDE子句指定要作为非键列包含在索引中的列列表。非键列不能用于索引扫描的搜索限定条件,索引强制执行的任何唯一性约束或排他约束也会忽略这些列。不过,仅索引扫描可以直接从索引条目取得非键列的内容,无需访问索引所对应的表。因此,添加非键列可以让原本无法使用仅索引扫描的查询使用这种扫描。 + + 可选的INCLUDE子句指定一个列列表,这些列将作为 + 非键列包含在索引中。非键列不能用作索引扫描的 + 搜索限定条件,在索引强制执行的任何唯一性或排他约束中也会被忽略。不过, + 非键列的内容可以由仅索引扫描返回,而无需访问索引对应的表,因为它们 + 可直接从索引项中取得。因此,添加非键列可以让原本无法使用仅索引扫描 + 的查询也能使用它。 + - 向索引添加非键列时,谨慎一些是明智的,尤其是宽列。如果索引元组超过该索引类型允许的最大大小,数据插入将失败。无论如何,非键列会复制索引所对应的表中的数据并使索引膨胀,从而可能降低搜索速度。此外,带有非键列的索引永远不会使用 B-树 去重。 + + 对于向索引中添加非键列,采取保守态度是明智的,尤其是宽列。如果索引元组超过 + 该索引类型允许的最大尺寸,数据插入将失败。无论如何,非键列都会 + 复制索引对应表中的数据并增大索引体积,因此可能拖慢搜索。此外, + B-树去重技术绝不会用于带有非键列的索引。 + - INCLUDE子句中列出的列不需要适用的操作符类;对于给定访问方法,如果某些列的数据类型没有定义操作符类,该子句仍可包含这些列。 + + INCLUDE子句中列出的列不需要合适的操作符类; + 该子句可以包含数据类型尚未为给定访问方法定义操作符类的列。 + - 表达式不支持作为包含列,因为它们不能用于仅索引扫描。 + + 不支持将表达式作为包含列,因为它们不能用于仅索引扫描。 + 目前,B-树 和 GiST 索引访问方法支持此功能。在 B-树 和 GiST 索引中,INCLUDE子句中列出的列值会包含在对应堆元组的叶元组中,但不会包含在用于树导航的上层索引条目中。 @@ -156,63 +177,89 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] ONLY - 如果表已分区,则表示创建索引时不要递归到分区。默认情况下会递归。 + + 表示如果该表是分区表,则不要递归地在各分区上创建索引。 + 默认会递归。 + table_name - 要建立索引的表名称(可能包含模式限定)。 + + 要建立索引的表名(可以是模式限定名)。 + method - 要使用的索引方法名称。可选项包括btreehashgistspgistginbrin,以及用户安装的访问方法(例如bloom)。默认方法是btree + + 要使用的索引方法的名称。选择包括btreehash、 + gistspgistgin、 + brin,或用户安装的访问方法,如 + bloom。 + 默认方法是btree。 + column_name - 表的列名称。 + + 一个表列的名称。 + expression - 基于表中一个或多个列的表达式。通常必须按照语法所示,在表达式两侧加上括号。不过,如果表达式采用函数调用的形式,则可以省略括号。 + + 一个基于表中一个或多个列的表达式。通常必须像语法中所示那样写在 + 外围圆括号中。不过,如果该表达式是函数调用形式,则可以省略圆括号。 + collation - 用于索引的排序规则名称。默认情况下,索引使用要建立索引的列所声明的排序规则,或要建立索引的表达式的结果排序规则。具有非默认排序规则的索引对于涉及使用非默认排序规则的表达式的查询可能很有用。 + + 将用于该索引的排序规则名称。默认情况下,索引使用被索引列声明的 + 排序规则,或者被索引表达式的结果排序规则。对于涉及使用非默认排序 + 规则表达式的查询,使用非默认排序规则的索引可能会很有用。 + opclass - 操作符类的名称。详细信息见下文。 + + 一个操作符类的名称。详见下文。 + opclass_parameter - 操作符类参数的名称。详细信息见下文。 + + 一个操作符类参数的名称。详见下文。 + ASC - 指定升序排序(这是默认值)。 + + 指定升序排序(默认)。 + @@ -226,28 +273,41 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] NULLS FIRST - 指定将空值排在非空值之前。当指定DESC时,这是默认值。 + + 指定把空值排序在非空值前面。在指定DESC时, + 这是默认行为。 + NULLS LAST - 指定将空值排在非空值之后。当未指定DESC时,这是默认值。 + + 指定把空值排序在非空值后面。在没有指定DESC时, + 这是默认行为。 + storage_parameter - 索引方法专用存储参数的名称。有关详细信息,请参见下文 + + 索引方法相关的存储参数的名称。详见 + 。 + tablespace_name - 要创建索引的表空间。如果未指定,则查询;对于临时表上的索引,则查询 + + 在其中创建索引的表空间。如果未指定,将查阅 + ;对于临时表上的索引,则查阅 + 。 + @@ -266,6 +326,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] 可选的WITH子句为索引指定存储参数。每一种 索引方法都有其各自允许的存储参数集合。 + B-树、hash、GiST 和 SP-GiST 索引方法都接受以下参数: @@ -282,7 +343,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - B-树、哈希、GiST 和 SP-GiST 索引方法都接受以下参数: + B-树索引还接受以下参数: @@ -315,7 +376,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - B-树索引还接受以下参数: + GiST 索引还接受以下参数: @@ -332,7 +393,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - GiST 索引还接受以下参数: + GIN 索引接受不同的参数: @@ -346,8 +407,8 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - 控制中描述的快速更新技术的使用。 - ON 启用快速更新,OFF 禁用快速更新。 + 此设置控制中描述的快速更新技术的使用。 + 这是一个布尔参数:ON 启用快速更新,OFF 禁用快速更新。 默认值为ON @@ -376,7 +437,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - 为该索引覆盖的全局设置。 + 自定义参数。 该值以千字节为单位。 @@ -384,7 +445,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - BRIN 索引接受以下参数: + BRIN 索引接受不同的参数: @@ -414,7 +475,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - 定义当在下一页范围检测到插入时,是否为前一页范围排队执行一次提要操作 + 定义当在下一页范围检测到插入时,是否为前一页范围排队执行一次范围摘要操作 (详见)。 默认值为off @@ -427,8 +488,8 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] 并发构建索引 - index - building concurrently + 索引 + 并发构建 @@ -454,8 +515,13 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] 在并发索引构建中,索引实际上会在一个事务中录入系统目录,然后在另外两个事务中执行两次表扫描。每次表扫描之前,索引构建都必须等待已修改该表的现有事务结束。第二次扫描之后,索引构建必须等待所有持有早于第二次扫描的快照(参见)的事务结束,其中包括其他表上并发索引构建任一阶段使用的事务。最后,索引才可以标记为可用,CREATE INDEX命令随之结束。不过即便如此,索引也可能无法立即用于查询:在最坏情况下,只要还存在早于索引构建开始的事务,就不能使用它。 - 如果在扫描表时出现问题,例如死锁或唯一索引中的唯一性冲突,CREATE INDEX命令将失败,但会留下一个无效索引。由于该索引可能不完整,查询时会忽略它;但是,它仍会带来更新开销。该psql - \d命令会将此类索引报告为INVALID: + + 如果在扫描表时出现问题,例如死锁或唯一索引中的唯一性违反, + CREATE INDEX命令将失败,但会留下一个 + 无效索引。这个索引在查询时会被忽略,因为它可能不完 + 整;但它仍会带来更新开销。psql + \d命令会将这样的索引报告为 + INVALID postgres=# \d tab @@ -465,7 +531,11 @@ postgres=# \d tab col | integer | | | Indexes: "idx" btree (col) INVALID -在这种情况下,建议的恢复方法是删除索引,然后重新尝试执行CREATE INDEX CONCURRENTLY。(另一种可能性是重建索引,使用REINDEX INDEX CONCURRENTLY)。 + + + 在这种情况下,推荐的恢复方法是删除该索引,然后再次尝试执行 + CREATE INDEX CONCURRENTLY。(另一种做法是用 + REINDEX INDEX CONCURRENTLY重建索引。) @@ -553,12 +623,17 @@ Indexes: 生成这些索引的统计信息。 - 对于大多数索引方法,创建索引的速度取决于的设置。较大的值会减少创建索引所需的时间,但前提是不能将它设得大于实际可用的内存量,否则机器会进入交换。 + + 对于大多数索引方法,索引的创建速度取决于 + 的设置。较大的值将会减少 + 索引创建所需的时间,当然不要把它设置得超过实际可用的内存量(那会迫使 + 机器进行交换)。 + PostgreSQL可以在构建索引时利用多个 CPU, 以便更快处理表中的行。这项特性被称为并行索引构建。 - 对于支持并行构建索引的索引方法(当前为 B-树、GIN 和 BRIN), + 对于支持并行构建索引的索引方法(当前只有 B-树), maintenance_work_mem指定每次索引构建操作整体最多 可使用的内存量,而不管启动了多少工作者进程。通常,代价模型会自动决 定是否需要请求工作者进程,以及请求多少个。 @@ -596,7 +671,11 @@ Indexes: - 虽然带有CONCURRENTLY选项的CREATE INDEX支持并行构建且没有特殊限制,但实际只有第一次表扫描是并行执行的。 + + 虽然带有CONCURRENTLY选项的CREATE INDEX + 在没有特殊限制的情况下支持并行构建,但实际上只有第一次表扫描会以并行 + 方式执行。 + 使用删除索引。 @@ -606,7 +685,12 @@ Indexes: 被移除。 - 早期版本的PostgreSQL也有 R-tree 索引方法。由于它相对于 GiST 方法没有显著优势,该方法已被删除。如果指定USING rtreeCREATE INDEX会将其解释为USING gist,以便简化旧数据库向 GiST 的转换。 + + 早期版本的PostgreSQL还提供过一种 R-tree + 索引方法。该方法已经被移除,因为它相对于 GiST 方法并无明显优势。如果 + 指定了USING rtreeCREATE INDEX + 会将其解释为USING gist,以简化旧数据库向 GiST 的转换。 + diff --git a/zh/13/ref/create_language.sgml b/zh/13/ref/create_language.sgml index 1bc00cc9..1b384815 100644 --- a/zh/13/ref/create_language.sgml +++ b/zh/13/ref/create_language.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE LANGUAGE 7 - SQL - Language Statements + SQL - 语言语句 @@ -96,7 +96,7 @@ CREATE [ OR REPLACE ] [ TRUSTED ] [ PROCEDURAL ] LANGUAGE name [ DEFAUL - 在PostgreSQL 8.4 之前,OPERATOR子句可以包含RECHECK选项。现在不再支持它,因为索引操作符是否有损现在会在运行时动态确定。这使得系统可以高效处理操作符可能有损也可能无损的情况。 + 在PostgreSQL 8.4 之前,OPERATOR子句可以包含RECHECK选项。现在不再支持该选项,因为索引操作符是否有损会在运行时动态确定。这样可以高效处理操作符可能有损也可能无损的情况。 diff --git a/zh/13/ref/create_operator.sgml b/zh/13/ref/create_operator.sgml index f9348de7..71f250c4 100644 --- a/zh/13/ref/create_operator.sgml +++ b/zh/13/ref/create_operator.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE OPERATOR 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/create_opfamily.sgml b/zh/13/ref/create_opfamily.sgml index ebe6fd9c..23f2e669 100644 --- a/zh/13/ref/create_opfamily.sgml +++ b/zh/13/ref/create_opfamily.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE OPERATOR FAMILY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/create_policy.sgml b/zh/13/ref/create_policy.sgml index 2b562dc1..2208cec0 100644 --- a/zh/13/ref/create_policy.sgml +++ b/zh/13/ref/create_policy.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE POLICY 7 - SQL - Language Statements + SQL - 语言语句 @@ -257,17 +257,17 @@ CREATE POLICY name ON 命令 - SELECT/ALL policy - INSERT/ALL policy - UPDATE/ALL policy - DELETE/ALL policy + SELECT/ALL策略 + INSERT/ALL策略 + UPDATE/ALL策略 + DELETE/ALL策略 - USING expression - WITH CHECK expression - USING expression - WITH CHECK expression - USING expression + USING 表达式 + WITH CHECK 表达式 + USING 表达式 + WITH CHECK 表达式 + USING 表达式 diff --git a/zh/13/ref/create_procedure.sgml b/zh/13/ref/create_procedure.sgml index 014109b0..1c87b5f3 100644 --- a/zh/13/ref/create_procedure.sgml +++ b/zh/13/ref/create_procedure.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE PROCEDURE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/create_publication.sgml b/zh/13/ref/create_publication.sgml index 10f9dc07..49e926f2 100644 --- a/zh/13/ref/create_publication.sgml +++ b/zh/13/ref/create_publication.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE PUBLICATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/create_role.sgml b/zh/13/ref/create_role.sgml index 4a379a7a..c25f6fa7 100644 --- a/zh/13/ref/create_role.sgml +++ b/zh/13/ref/create_role.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE ROLE 7 - SQL - Language Statements + SQL - 语言语句 @@ -107,7 +107,7 @@ in sync when changing the above synopsis! 这些子句决定某个角色是否被允许创建、更改、删除其他角色,为其添加注释, - 以及更改其安全标签。关于该权限赋予的具体能力,参见 + 更改其安全标签,以及授予或撤销其中的成员资格。关于该权限赋予的具体能力,参见 。若未指定,默认值是 NOCREATEROLE diff --git a/zh/13/ref/create_rule.sgml b/zh/13/ref/create_rule.sgml index 6367a679..6abd2969 100644 --- a/zh/13/ref/create_rule.sgml +++ b/zh/13/ref/create_rule.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE RULE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/create_schema.sgml b/zh/13/ref/create_schema.sgml index f3dc7a31..fede6380 100644 --- a/zh/13/ref/create_schema.sgml +++ b/zh/13/ref/create_schema.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE SCHEMA 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/create_sequence.sgml b/zh/13/ref/create_sequence.sgml index 200a24ee..9fdd3d8b 100644 --- a/zh/13/ref/create_sequence.sgml +++ b/zh/13/ref/create_sequence.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE SEQUENCE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/create_server.sgml b/zh/13/ref/create_server.sgml index c4b79d02..7f438b0b 100644 --- a/zh/13/ref/create_server.sgml +++ b/zh/13/ref/create_server.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE SERVER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/create_statistics.sgml b/zh/13/ref/create_statistics.sgml index 4c3a0105..70391f17 100644 --- a/zh/13/ref/create_statistics.sgml +++ b/zh/13/ref/create_statistics.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE STATISTICS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/create_subscription.sgml b/zh/13/ref/create_subscription.sgml index cb4be237..8d79c112 100644 --- a/zh/13/ref/create_subscription.sgml +++ b/zh/13/ref/create_subscription.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE SUBSCRIPTION 7 - SQL - Language Statements + SQL - 语言语句 @@ -32,19 +32,18 @@ CREATE SUBSCRIPTION subscription_name描述 - CREATE SUBSCRIPTION添加一个新的逻辑复制订阅。 - 创建订阅的用户将成为该订阅的所有者。订阅名称必须与当前数据库中 - 任何现有订阅的名称不同。 + CREATE SUBSCRIPTION为当前数据库添加一个新订阅。 + 订阅名称必须与数据库中任何现有订阅的名称不同。 - 订阅表示与发布者的复制连接。因此,除了在本地系统目录中添加定义之外, - 该命令通常还会在发布者上创建一个复制槽。 + 订阅表示与发布者的复制连接。因此,该命令不仅会在本地系统目录中添加定义, + 还会在发布者上创建一个复制槽。 - 除非订阅初始即被禁用,否则在执行该命令所在事务提交时,会启动一个 - 逻辑复制工作进程为新订阅复制数据。 + 在执行该命令所在事务提交时,会启动一个逻辑复制工作进程, + 为新订阅复制数据。 diff --git a/zh/13/ref/create_table.sgml b/zh/13/ref/create_table.sgml index 835c7858..93441820 100644 --- a/zh/13/ref/create_table.sgml +++ b/zh/13/ref/create_table.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TABLE 7 - SQL - Language Statements + SQL - 语言语句 @@ -121,7 +121,7 @@ WITH ( MODULUS numeric_literal, REM 如果给出了模式名(例如 CREATE TABLE myschema.mytable ...),则表将在指定模式中创建。 否则,它将在当前模式中创建。临时表存在于一个特殊模式中,因此创建临时表时不能给出模式名。 - 表名必须与同一模式中任何其他关系(表、序列、索引、视图、物化视图或外部表)的名称不同。 + 表名必须与同一模式中任何其他表、序列、索引、视图或外部表的名称不同。 @@ -147,7 +147,7 @@ WITH ( MODULUS numeric_literal, REM - TEMPORARY or TEMP + TEMPORARYTEMP 如果指定该选项,表将创建为临时表。 @@ -161,7 +161,7 @@ WITH ( MODULUS numeric_literal, REM - 可以在 TEMPORARYTEMP 前写 GLOBALLOCAL。这在当前的 PostgreSQL 中没有区别,而且已废弃;见下文 。 + 可以在 TEMPORARYTEMP 前写 GLOBALLOCAL。这在当前的 PostgreSQL 中没有区别,而且已弃用;见下文 @@ -178,14 +178,18 @@ WITH ( MODULUS numeric_literal, REM IF NOT EXISTS - 如果已存在同名关系,则不抛出错误,而是发出通知。请注意,不能保证现有关系与原本要创建的关系有任何相似之处。 + + 如果已存在同名关系,则不抛出错误,而是发出一条提示。注意,这并不保证现有关系与本应创建出的关系有任何相似之处。 + table_name - 要创建的表的名称(可以带模式限定)。 + + 要创建的表名(可选地带模式限定)。 + @@ -201,14 +205,20 @@ WITH ( MODULUS numeric_literal, REM column_name - 要在新表中创建的列的名称。 + + 要在新表中创建的列名。 + data_type - 列的数据类型,可以包含数组说明符。有关PostgreSQL支持的数据类型的更多信息,请参见 + + 列的数据类型。这可以包括数组说明符。有关 + PostgreSQL 支持的数据类型的更多信息,请参见 。 + @@ -263,15 +273,31 @@ WITH ( MODULUS numeric_literal, REM PARTITION BY { RANGE | LIST | HASH } ( { column_name | ( expression ) } [ opclass ] [, ...] ) - 可选的PARTITION BY子句指定表的分区策略。这样创建的表称为分区表。括号内的列或表达式列表构成该表的分区键。使用范围分区或哈希分区时,分区键可以包含多个列或表达式(最多 32 个,但可以在构建PostgreSQL时更改此限制);对于列表分区,分区键则必须由单个列或表达式组成。 + + 可选的 PARTITION BY 子句指定表的分区策略。 + 这样创建的表称为分区表。 + 括号中的列或表达式列表构成该表的分区键。 + 使用范围分区或哈希分区时,分区键可以包含多个列或表达式(最多 32 个,但该限制可在构建 PostgreSQL 时调整); + 而列表分区的分区键必须由单个列或表达式组成。 + - 范围分区和列表分区需要 B-树操作符类,而哈希分区需要哈希操作符类。如果没有显式指定操作符类,则使用相应类型的默认操作符类;如果不存在默认操作符类,则报错。使用哈希分区时,所用操作符类必须实现支持函数 2(详情见)。 + + 范围分区和列表分区需要 B-树 操作符类,哈希分区则需要 hash 操作符类。 + 如果未显式指定操作符类,将使用相应类型的默认操作符类;若不存在默认操作符类,则会报错。 + 使用哈希分区时,所用操作符类必须实现支持函数 2(详见 )。 + - 分区表划分为多个子表(称为分区),通过单独的CREATE TABLE命令创建。分区表本身为空。插入该表的数据行会根据分区键中列或表达式的值路由到某个分区。如果没有现有分区匹配新行中的值,则会报错。 + + 分区表被划分为多个子表(称为分区),它们使用单独的 CREATE TABLE 命令创建。 + 分区表本身为空。插入到该表的数据行会根据分区键中列或表达式的值被路由到相应分区。 + 如果没有现有分区与新行中的值匹配,就会报错。 + 分区表不支持EXCLUDE约束;不过,可以在各个分区上定义这些约束。 - 关于表分区的更多讨论,请参见 + + 有关表分区的更多讨论,请参阅 。 + @@ -336,13 +362,13 @@ WITH ( MODULUS numeric_literal, REM 还要注意,某些元素类型(如 timestamp)具有 - "infinity" 的概念,那只是另一种可存储的值。这不同于 + “无穷大” 的概念,那只是另一种可存储的值。这不同于 MINVALUEMAXVALUE,后两者并非可存储 的实际值,而只是表示值无界的方式。MAXVALUE 可以视为大于任何 - 其他值,包括 "infinity";MINVALUE 可以视为小于任何 - 其他值,包括 "minus infinity"。因此,范围 + 其他值,包括 “无穷大”;MINVALUE 可以视为小于任何 + 其他值,包括 “负无穷大”。因此,范围 FROM ('infinity') TO (MAXVALUE) 并不是空范围;它只允许存储 - 一个值 — "infinity"。 + 一个值 — “无穷大”。 @@ -398,7 +424,12 @@ WITH ( MODULUS numeric_literal, REM 同样与 INHERITS 不同,由 LIKE 复制的列和约束不会与同名的列和约束合并。如果同一名称被显式指定,或在另一个 LIKE 子句中指定,则会报错。 - 可选的like_option子句指定要复制原表的哪些附加属性。指定INCLUDING会复制该属性,指定EXCLUDING则省略该属性。EXCLUDING为默认值。如果对同一类对象作出多次指定,则使用最后一次指定。可用选项如下: + + 可选的 like_option 子句指定还要复制原表的哪些附加属性。 + 指定 INCLUDING 表示复制该属性,指定 EXCLUDING 表示省略该属性。默认是 EXCLUDING。 + 如果对同一类对象给出了多个说明,则采用最后一个。可用选项如下: + + INCLUDING COMMENTS @@ -535,7 +566,7 @@ WITH ( MODULUS numeric_literal, REM - 一个被标记为NO INHERIT的约束将不会传播到子表。 + 标记为 NO INHERIT 的约束不会传播到子表。 @@ -561,13 +592,17 @@ WITH ( MODULUS numeric_literal, REM - GENERATED ALWAYS AS ( generation_expr ) STOREDgenerated column + GENERATED ALWAYS AS ( generation_expr ) STORED生成列 - 这个子句将该列创建为生成列。不能向该列写入数据,读取时会返回指定表达式的结果。 + + 此子句将列创建为生成列。列不可写入,读取时会返回指定表达式的结果。 + 必须使用关键字STORED,表示该列将在写入时计算并存储在磁盘上。 - 生成表达式可以引用表中的其他列,但不能引用其他生成列。使用的所有函数和操作符都必须是不可变的。不允许引用其他表。 + + 生成表达式可以引用表中的其他列,但不能引用其他生成的列。使用的任何函数和操作符都必须是不可变的。不允许引用其他表。 + @@ -610,19 +645,29 @@ WITH ( MODULUS numeric_literal, REM INCLUDE ( column_name [, ...]) (表约束) - UNIQUE约束指定表中由一个或多个列组成的一组列只能包含唯一值。表级唯一约束的行为与列级唯一约束相同,但还能够跨越多个列。因此,这个约束要求任意两行在这些列中至少有一列不同。 + + UNIQUE 约束指定表中一列或多列组成的一组只能包含唯一值。 + 表级唯一约束的行为与列级唯一约束相同,只是它还能跨越多列。因此,该约束 + 要求任意两行在这些列中至少有一列不同。 + 对于唯一约束,空值不被视为相等。 - 每个唯一约束指定的列集合,都应与为该表定义的任何其他唯一约束或主键约束指定的列集合不同。(否则,冗余的唯一约束会被丢弃。) + + 每个唯一约束都应引用一组列,这组列应不同于该表上任何其他唯一约束或 + 主键约束所引用的列集合。(否则,冗余的唯一约束将被丢弃。) + - 为多级分区层次结构建立唯一约束时,约束定义必须包含目标分区表的分区键中的所有列,以及其所有后代分区表的分区键中的所有列。 + + 在为多级分区层次结构建立唯一约束时,目标分区表分区键中的所有列,以及 + 其所有后代分区表分区键中的所有列,都必须包含在约束定义中。 + 添加唯一约束会自动在约束所用的列或列组上创建唯一 B-树索引。 可选的 INCLUDE 子句会向该索引添加一个或多个仅作为 - payload 的列:对这些列不强制唯一性,而且该索引也不能据此 + 载荷 的列:对这些列不强制唯一性,而且该索引也不能据此 进行搜索。不过,它们可以通过仅索引扫描取回。注意,尽管约束不在包含列上 强制执行,它仍然依赖于这些列。因此,对这类列执行某些操作(例如 DROP COLUMN)可能导致约束和索引被级联删除。 @@ -664,7 +709,7 @@ WITH ( MODULUS numeric_literal, REM 可选的 INCLUDE 子句会向该索引添加一个或多个仅作为 - payload 的列:对这些列不强制唯一性,而且该索引也不能据此 + 载荷 的列:对这些列不强制唯一性,而且该索引也不能据此 进行搜索。不过,它们可以通过仅索引扫描取回。注意,尽管约束不在包含列上 强制执行,它仍然依赖于这些列。因此,对这类列执行某些操作(例如 DROP COLUMN)可能导致约束和索引被级联删除。 @@ -687,7 +732,7 @@ WITH ( MODULUS numeric_literal, REM - 排他约束通过一个与约束同名的索引来实现,因此每个指定操作符都必须与 + 排他约束通过索引来实现,因此每个指定操作符都必须与 索引访问方法 index_method 的适当操作符类关联 (见 )。每个 exclude_element 都定义了索引的一 @@ -699,11 +744,15 @@ WITH ( MODULUS numeric_literal, REM 访问方法必须支持 amgettuple(见 );目前这意味着不能使用 GIN。 虽然允许,但在排他约束上使用 B-树或 hash 索引意义不大,因为它们做不到 - 比普通唯一约束更好的事情。因此,实践中访问方法几乎总会是 + 比普通唯一约束更好的事情。因此,实践中访问方法总是 GiSTSP-GiST - predicate允许在表的一个子集上指定排他约束;内部会为此创建部分索引。请注意,谓词必须用括号括起来。 + + predicate 允许你只在表的一个 + 子集上指定排他约束;在内部,这会创建一个部分索引。注意, + predicate 周围的圆括号是必需的。 + @@ -720,7 +769,17 @@ WITH ( MODULUS numeric_literal, REM 这些子句指定外键约束,要求新表中由一个或多个列组成的列组只能包含与被引用表中某一行的被引用列中的值相匹配的值。如果省略refcolumn列表,则使用reftable的主键。否则,refcolumn列表必须引用不可延迟的唯一约束或主键约束的列,或者是非部分唯一索引的列。用户必须拥有被引用表的REFERENCES权限(可以针对整个表,也可以针对具体的被引用列)。添加外键约束需要在被引用表上获取SHARE ROW EXCLUSIVE锁。请注意,不能在临时表和永久表之间定义外键约束。 - 插入引用列的值会使用指定的匹配类型,与被引用表的被引用列中的值进行匹配。有三种匹配类型:MATCH FULLMATCH PARTIALMATCH SIMPLE(默认值)。MATCH FULL不允许多列外键中的某一列为空,除非所有外键列都为空;如果全部为空,则不要求该行在被引用表中存在匹配行。MATCH SIMPLE允许任意外键列为空;只要其中任何一列为空,就不要求该行在被引用表中存在匹配行。MATCH PARTIAL尚未实现。(当然,可以对引用列施加NOT NULL约束来防止这些情况发生。) + + 插入到引用列中的值会按照给定的匹配类型,与被引用表及其被引用列中的值进 + 行匹配。共有三种匹配类型:MATCH FULL、 + MATCH PARTIALMATCH SIMPLE + (默认值)。MATCH FULL 不允许多列外键中的某一列为 + 空,除非所有外键列都为空;如果它们都为空,则不要求该行在被引用表中有匹 + 配行。MATCH SIMPLE 允许任意外键列为空;如果其中任何一 + 列为空,则不要求该行在被引用表中有匹配行。 + MATCH PARTIAL 目前尚未实现。(当然,可以对引用列应用 + NOT NULL 约束,以防止出现这些情况。) + 此外,当被引用列中的数据发生变化时,会对本表列中的数据执行某些操作。ON DELETE子句指定删除被引用表中的被引用行时要执行的操作。同样,ON UPDATE子句指定将被引用表中的被引用列更新为新值时要执行的操作。如果行被更新,但被引用列实际上没有变化,则不执行任何操作。除NO ACTION检查以外的引用操作都不能延迟,即使该约束声明为可延迟也是如此。每个子句可以指定以下操作: @@ -740,7 +799,9 @@ WITH ( MODULUS numeric_literal, REM CASCADE - 分别删除引用被删除行的所有行,或将引用列的值更新为被引用列的新值。 + + 分别删除任何引用已删除行的行,或将引用列的值更新为被引用列的新值。 + @@ -783,7 +844,12 @@ WITH ( MODULUS numeric_literal, REM USING method - 此可选子句指定用于存储新表内容的表访问方法;该方法必须是类型为TABLE的访问方法。更多信息请参见。如果未指定此选项,则为新表选择默认表访问方法。更多信息请参见 + + 该可选子句指定存储新表内容所用的表访问方法;该方法必须是类型为 + TABLE 的访问方法。详见 。如果未 + 指定此选项,则会为新表选择默认表访问方法。详见 + 。 + @@ -815,7 +881,11 @@ WITH ( MODULUS numeric_literal, REM ON COMMIT - 临时表在事务块结束时的行为可以使用以下选项控制:ON COMMIT。三个选项是: + + 可以使用 ON COMMIT 控制临时表在事务块结束时的行为。三种 + 选项如下: + + PRESERVE ROWS @@ -879,7 +949,7 @@ WITH ( MODULUS numeric_literal, REM 存储参数 - storage parameters + 存储参数 @@ -901,7 +971,7 @@ WITH ( MODULUS numeric_literal, REM fillfactor (integer) - fillfactor storage parameter + fillfactor 存储参数 @@ -923,7 +993,7 @@ WITH ( MODULUS numeric_literal, REM toast_tuple_target (integer) - toast_tuple_target storage parameter + toast_tuple_target 存储参数 @@ -931,7 +1001,7 @@ WITH ( MODULUS numeric_literal, REM toast_tuple_target 指定在尝试压缩和/或将长列值移入 TOAST 表之前所需的最小元组长度,同时也是一旦开始 TOAST 化后试图将长度 - 缩减到的目标长度。这会影响标记为 External(用于移动)、Main(用于压缩) + 缩减到其以下的目标长度。这会影响标记为 External(用于移动)、Main(用于压缩) 或 Extended(用于两者)的列,并且只适用于新元组。对现有行没有影响。默认 情况下,该参数被设置为至少允许每个块容纳 4 个元组,在默认块大小下即为 2040 字节。有效值介于 128 字节与(块大小减去页头)之间,默认上限为 @@ -946,13 +1016,13 @@ WITH ( MODULUS numeric_literal, REM parallel_workers (integer) - parallel_workers storage parameter + parallel_workers 存储参数 - 该参数设置在对该表执行并行扫描时可用于辅助扫描的工作进程数量。若未设置, + 该参数设置在对该表执行并行扫描时用于辅助扫描的工作进程数量。若未设置, 系统会根据关系大小决定一个值。规划器或使用并行扫描的实用命令实际选择的 工作进程数量可能更少,例如可能受 设置所限。 @@ -964,7 +1034,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_enabled, toast.autovacuum_enabled (boolean) - autovacuum_enabled storage parameter + autovacuum_enabled 存储参数 @@ -986,7 +1056,7 @@ WITH ( MODULUS numeric_literal, REM vacuum_index_cleanup, toast.vacuum_index_cleanup (boolean) - vacuum_index_cleanup storage parameter + vacuum_index_cleanup 存储参数 @@ -1001,7 +1071,7 @@ WITH ( MODULUS numeric_literal, REM - 启用或禁用 vacuum 尝试截断删除此表末尾的空页。默认值为true。如果为trueVACUUM和 autovacuum 会执行截断,并将被截断页面的磁盘空间返还给操作系统。请注意,截断需要对表取得ACCESS EXCLUSIVE锁。如果指定了TRUNCATE参数(属于),则会覆盖此选项的值。 + 允许或禁止清理尝试截断删除此表末尾的空页。默认值为true。如果为trueVACUUM和自动清理会执行截断,并将被截断页面的磁盘空间返还给操作系统。请注意,截断需要对表取得ACCESS EXCLUSIVE锁。如果指定了TRUNCATE参数(属于),则会覆盖此选项的值。 @@ -1010,7 +1080,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_vacuum_threshold, toast.autovacuum_vacuum_threshold (integer) autovacuum_vacuum_threshold - storage parameter + 存储参数 @@ -1026,7 +1096,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_vacuum_scale_factor, toast.autovacuum_vacuum_scale_factor (floating point) autovacuum_vacuum_scale_factor - storage parameter + 存储参数 @@ -1042,7 +1112,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_vacuum_insert_threshold, toast.autovacuum_vacuum_insert_threshold (integer) autovacuum_vacuum_insert_threshold - storage parameter + 存储参数 @@ -1059,7 +1129,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_vacuum_insert_scale_factor, toast.autovacuum_vacuum_insert_scale_factor (floating point) autovacuum_vacuum_insert_scale_factor - storage parameter + 存储参数 @@ -1075,7 +1145,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_analyze_threshold (integer) autovacuum_analyze_threshold - storage parameter + 存储参数 @@ -1091,7 +1161,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_analyze_scale_factor (floating point) autovacuum_analyze_scale_factor - storage parameter + 存储参数 @@ -1107,7 +1177,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_vacuum_cost_delay, toast.autovacuum_vacuum_cost_delay (floating point) autovacuum_vacuum_cost_delay - storage parameter + 存储参数 @@ -1123,7 +1193,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_vacuum_cost_limit, toast.autovacuum_vacuum_cost_limit (integer) autovacuum_vacuum_cost_limit - storage parameter + 存储参数 @@ -1138,7 +1208,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_freeze_min_age, toast.autovacuum_freeze_min_age (integer) - autovacuum_freeze_min_age storage parameter + autovacuum_freeze_min_age 存储参数 @@ -1156,7 +1226,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_freeze_max_age, toast.autovacuum_freeze_max_age (integer) autovacuum_freeze_max_age - storage parameter + 存储参数 @@ -1173,7 +1243,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_freeze_table_age, toast.autovacuum_freeze_table_age (integer) - autovacuum_freeze_table_age storage parameter + autovacuum_freeze_table_age 存储参数 @@ -1188,7 +1258,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_multixact_freeze_min_age, toast.autovacuum_multixact_freeze_min_age (integer) - autovacuum_multixact_freeze_min_age storage parameter + autovacuum_multixact_freeze_min_age 存储参数 @@ -1207,7 +1277,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_multixact_freeze_max_age, toast.autovacuum_multixact_freeze_max_age (integer) autovacuum_multixact_freeze_max_age - storage parameter + 存储参数 @@ -1225,7 +1295,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_multixact_freeze_table_age, toast.autovacuum_multixact_freeze_table_age (integer) - autovacuum_multixact_freeze_table_age storage parameter + autovacuum_multixact_freeze_table_age 存储参数 @@ -1241,7 +1311,7 @@ WITH ( MODULUS numeric_literal, REM log_autovacuum_min_duration, toast.log_autovacuum_min_duration (integer) log_autovacuum_min_duration - storage parameter + 存储参数 @@ -1256,7 +1326,7 @@ WITH ( MODULUS numeric_literal, REM user_catalog_table (boolean) - user_catalog_table storage parameter + user_catalog_table 存储参数 @@ -1278,7 +1348,7 @@ WITH ( MODULUS numeric_literal, REM 注解 - PostgreSQL为每一个唯一约束和主键约束创建一个索引来强制唯一性。因此,没有必要显式地为主键列创建一个索引(详见)。 + PostgreSQL为每一个唯一约束和主键约束自动创建一个索引来强制唯一性。因此,没有必要显式地为主键列创建一个索引(详见)。 @@ -1690,7 +1760,10 @@ CREATE TABLE cities_partdef 外键约束 - 这是PostgreSQL扩展:外键约束可以引用唯一索引的列,而不是主键或唯一约束的列。 + + 外键约束可以引用唯一索引的列,而不仅限于主键或唯一约束的列,这也是 + PostgreSQL 的扩展。 + @@ -1699,9 +1772,9 @@ CREATE TABLE cities_partdef NULL 约束(实际上并不是约束)是 - PostgreSQL 对 SQL 标准的扩展;它也被其他一些数 - 据库系统采纳,以便兼容(以及与对称的 NOT NULL 约束保持一 - 致)。由于它本来就是任意列的默认值,所以它的存在只是噪声。 + PostgreSQL 对 SQL 标准的扩展;提供它是为了 + 与其他一些数据库系统兼容(以及与 NOT NULL 约束保持 + 对称)。由于它本来就是任意列的默认情况,所以它的存在只是噪声。 @@ -1731,12 +1804,12 @@ CREATE TABLE cities_partdef - 零列表 + 零列的表 PostgreSQL 允许创建没有列的表(例如 CREATE TABLE foo();)。这是对 SQL 标准的扩展,标准不允许 - 零列表。零列表本身并不十分有用,但若禁止它们,就会让 + 零列的表。零列的表本身并不十分有用,但若禁止它们,就会让 ALTER TABLE DROP COLUMN 出现奇怪的特殊情况,因此忽略这 一规范限制看起来更整洁。 @@ -1749,7 +1822,7 @@ CREATE TABLE cities_partdef PostgreSQL 允许一个表拥有多个标识列。 该标准指定一个表最多只能有一个标识列。 - 这主要是为了给模式更改或迁移提供更大的灵活性。 + 放宽这一限制主要是为了给模式更改或迁移提供更大的灵活性。 请注意,INSERT 命令仅支持一个适用于整个语句的覆盖子 句,因此对行为不同的多个标识列支持并不好。 @@ -1799,8 +1872,7 @@ CREATE TABLE cities_partdef 类型化表 - 类型化表实现了 SQL 标准的一个子集。按照标准,类型化表除了具有与底层组合 - 类型相对应的列之外,还应有一个额外的自引用列。 + 类型化表实现了 SQL 标准的一个子集。按照标准,类型化表除了具有与底层复合类型相对应的列之外,还应有一个额外的自引用列PostgreSQL 不显式支持自引用列。 diff --git a/zh/13/ref/create_table_as.sgml b/zh/13/ref/create_table_as.sgml index 0f3e2de4..5ffbc1f1 100644 --- a/zh/13/ref/create_table_as.sgml +++ b/zh/13/ref/create_table_as.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TABLE AS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/create_tablespace.sgml b/zh/13/ref/create_tablespace.sgml index fd556c23..308f7dc3 100644 --- a/zh/13/ref/create_tablespace.sgml +++ b/zh/13/ref/create_tablespace.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TABLESPACE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/create_transform.sgml b/zh/13/ref/create_transform.sgml index 865b53e5..381e3bcd 100644 --- a/zh/13/ref/create_transform.sgml +++ b/zh/13/ref/create_transform.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TRANSFORM 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/create_trigger.sgml b/zh/13/ref/create_trigger.sgml index 7169fa9a..6314ecb4 100644 --- a/zh/13/ref/create_trigger.sgml +++ b/zh/13/ref/create_trigger.sgml @@ -10,13 +10,13 @@ PostgreSQL documentation 过渡表 - ephemeral named relation + 临时命名关系 CREATE TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -55,7 +55,7 @@ CREATE [ CONSTRAINT ] TRIGGER name UPDATEDELETE之前); 也可以在该操作完成之后引发(即在检查约束以及完成 INSERTUPDATE或 - DELETE之后);或者改为执行该操作 + DELETE之后);或者取代该操作执行 (用于视图上的插入、更新或删除)。如果触发器在事件之前引发,或者改为取代该事件执行, 则它可以跳过对当前行的操作,或者修改待插入的行 (仅适用于INSERTUPDATE操作)。 @@ -111,7 +111,7 @@ CREATE [ CONSTRAINT ] TRIGGER name TRUNCATE - 表和外部表 + @@ -124,7 +124,7 @@ CREATE [ CONSTRAINT ] TRIGGER name TRUNCATE - 表和外部表 + @@ -154,7 +154,7 @@ CREATE [ CONSTRAINT ] TRIGGER name 如果针对同一事件定义了多个同类触发器,它们将按名称的字母顺序引发。 - 当指定CONSTRAINT选项时,此命令会创建一个约束触发器。这与普通触发器相同,只是可以使用调整其触发时机。约束触发器必须是普通表(不是外部表)上的AFTER ROW触发器。它们既可以在导致触发事件的语句结束时触发,也可以在包含它的事务结束时触发;后一种情况称为延迟。也可以使用SET CONSTRAINTS强制挂起的延迟触发立即触发。约束触发器应当在其所实现的约束遭到违反时抛出异常。 + 当指定CONSTRAINT选项时,此命令会创建一个约束触发器。这与普通触发器相同,只是可以使用调整其触发时机。约束触发器必须是普通表(不是外部表)上的AFTER ROW触发器。它们既可以在导致触发事件的语句结束时触发,也可以在包含它的事务结束时触发;后一种情况称为延迟。也可以使用SET CONSTRAINTS强制尚待执行的延迟触发器立即触发。约束触发器应当在其所实现的约束遭到违反时抛出异常。 REFERENCING选项允许收集过渡关系, @@ -223,12 +223,13 @@ CREATE [ CONSTRAINT ] TRIGGER name - 对于 UPDATE 事件,可以使用以下语法指定列列表: + 对于UPDATE事件,可以使用以下语法指定列列表: UPDATE OF column_name1 [, column_name2 ... ] - 只有当列出的列中至少有一列被列为 UPDATE 命令的目标, - 或者列出的某个生成列依赖于作为 UPDATE 目标的列时,触发器才会触发。 + 只有当列出的列中至少有一列被列为UPDATE命令的目标列时, + 或者列出的列中有某个生成列依赖于作为UPDATE目标的列时, + 该触发器才会引发。 @@ -365,7 +366,7 @@ UPDATE OF column_name1 [, column_name2CREATE TRIGGER的语法中,关键字 FUNCTIONPROCEDURE 是等价的, 但无论如何,被引用的对象都必须是函数而不是过程。 - 这里使用 PROCEDURE 关键字只是出于历史原因,并且已被废弃。 + 这里使用 PROCEDURE 关键字只是出于历史原因,并且已被弃用。 diff --git a/zh/13/ref/create_tsconfig.sgml b/zh/13/ref/create_tsconfig.sgml index ec121658..974ef42a 100644 --- a/zh/13/ref/create_tsconfig.sgml +++ b/zh/13/ref/create_tsconfig.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TEXT SEARCH CONFIGURATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/create_tsdictionary.sgml b/zh/13/ref/create_tsdictionary.sgml index 25935390..2dbca552 100644 --- a/zh/13/ref/create_tsdictionary.sgml +++ b/zh/13/ref/create_tsdictionary.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TEXT SEARCH DICTIONARY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/create_tsparser.sgml b/zh/13/ref/create_tsparser.sgml index 290e30b0..6af67ab8 100644 --- a/zh/13/ref/create_tsparser.sgml +++ b/zh/13/ref/create_tsparser.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TEXT SEARCH PARSER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/create_tstemplate.sgml b/zh/13/ref/create_tstemplate.sgml index 44061296..5dd2e1c0 100644 --- a/zh/13/ref/create_tstemplate.sgml +++ b/zh/13/ref/create_tstemplate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TEXT SEARCH TEMPLATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/create_type.sgml b/zh/13/ref/create_type.sgml index 446657a8..26516e01 100644 --- a/zh/13/ref/create_type.sgml +++ b/zh/13/ref/create_type.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TYPE 7 - SQL - Language Statements + SQL - 语言语句 @@ -91,7 +91,7 @@ CREATE TYPE name 复合类型 - 第一种形式的CREATE TYPE创建复合类型。组合 + 第一种形式的CREATE TYPE创建复合类型。复合 类型由属性名和数据类型列表指定。如果某个属性的数据类型支持排序规 则,还可以指定该属性的排序规则。复合类型本质上与表的行类型相同, 但如果目的只是定义一种类型,使用CREATE TYPE @@ -280,7 +280,7 @@ CREATE TYPE name 数才知道,但仍有若干内部表示属性必须向 PostgreSQL声明。其中最重要的是 internallength。 - 基础数据类型可以是定长的,此时internallength为正整数;也可 以是变长的,此时将internallength设为 @@ -384,7 +384,7 @@ CREATE TYPE name collatable为真,则 该类型的列定义和表达式可以通过COLLATE子句携 带排序规则信息。是否实际使用这些排序规则信息取决于操作该类型的函 - 数实现;仅仅把类型标记为 collatable 并不会自动实现这一点。 + 数实现;仅仅把类型标记为支持排序规则并不会自动实现这一点。 @@ -781,7 +781,7 @@ CREATE TYPE float8_range AS RANGE (subtype = float8, subtype_diff = float8mi); - 这个示例创建基础数据类型box,然后在表定义中使用它: + 这个示例创建基础类型box,然后在表定义中使用它: CREATE TYPE box; diff --git a/zh/13/ref/create_user.sgml b/zh/13/ref/create_user.sgml index 64ee1d8b..3cc56400 100644 --- a/zh/13/ref/create_user.sgml +++ b/zh/13/ref/create_user.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE USER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/create_user_mapping.sgml b/zh/13/ref/create_user_mapping.sgml index 7a16d2d5..d8730f6c 100644 --- a/zh/13/ref/create_user_mapping.sgml +++ b/zh/13/ref/create_user_mapping.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE USER MAPPING 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/create_view.sgml b/zh/13/ref/create_view.sgml index fa2e9474..ccd9ea6d 100644 --- a/zh/13/ref/create_view.sgml +++ b/zh/13/ref/create_view.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/createdb.sgml b/zh/13/ref/createdb.sgml index e4ef529b..b23fe09b 100644 --- a/zh/13/ref/createdb.sgml +++ b/zh/13/ref/createdb.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation createdb 1 - Application + 应用程序 diff --git a/zh/13/ref/createuser.sgml b/zh/13/ref/createuser.sgml index b223e903..1d216262 100644 --- a/zh/13/ref/createuser.sgml +++ b/zh/13/ref/createuser.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation createuser 1 - Application + 应用程序 @@ -119,13 +119,10 @@ PostgreSQL documentation - (已废弃) + - - 指定新角色应自动成为指定现有角色的成员。 - 可以通过写多个开关来指定多个现有角色。 - + 指定此角色应立即作为新成员加入的现有角色。可以使用多个开关,指定此角色要加入的多个角色。 @@ -275,7 +272,7 @@ PostgreSQL documentation 新用户将不具有REPLICATION权限,关于该权限的更完整说明见。这是默认设置。 + linkend="sql-createrole"/>。 diff --git a/zh/13/ref/deallocate.sgml b/zh/13/ref/deallocate.sgml index 27b9da86..6dea341e 100644 --- a/zh/13/ref/deallocate.sgml +++ b/zh/13/ref/deallocate.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation DEALLOCATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/declare.sgml b/zh/13/ref/declare.sgml index b3d9d8d8..1daae5a3 100644 --- a/zh/13/ref/declare.sgml +++ b/zh/13/ref/declare.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation DECLARE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/delete.sgml b/zh/13/ref/delete.sgml index 527a35d7..bfe9a28b 100644 --- a/zh/13/ref/delete.sgml +++ b/zh/13/ref/delete.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DELETE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/discard.sgml b/zh/13/ref/discard.sgml index 94cb7872..d29a479a 100644 --- a/zh/13/ref/discard.sgml +++ b/zh/13/ref/discard.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DISCARD 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/do.sgml b/zh/13/ref/do.sgml index 2ea6566a..cdbf189e 100644 --- a/zh/13/ref/do.sgml +++ b/zh/13/ref/do.sgml @@ -15,7 +15,7 @@ PostgreSQL documentation DO 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/drop_access_method.sgml b/zh/13/ref/drop_access_method.sgml index 407ec4cd..646100e1 100644 --- a/zh/13/ref/drop_access_method.sgml +++ b/zh/13/ref/drop_access_method.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP ACCESS METHOD 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/drop_aggregate.sgml b/zh/13/ref/drop_aggregate.sgml index 1c8a1122..9fd7ea4b 100644 --- a/zh/13/ref/drop_aggregate.sgml +++ b/zh/13/ref/drop_aggregate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP AGGREGATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/drop_cast.sgml b/zh/13/ref/drop_cast.sgml index 73860e3c..5e330ae0 100644 --- a/zh/13/ref/drop_cast.sgml +++ b/zh/13/ref/drop_cast.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP CAST 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/drop_collation.sgml b/zh/13/ref/drop_collation.sgml index b90849fc..b10b3206 100644 --- a/zh/13/ref/drop_collation.sgml +++ b/zh/13/ref/drop_collation.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP COLLATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/drop_conversion.sgml b/zh/13/ref/drop_conversion.sgml index b63d1291..35009708 100644 --- a/zh/13/ref/drop_conversion.sgml +++ b/zh/13/ref/drop_conversion.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP CONVERSION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/drop_database.sgml b/zh/13/ref/drop_database.sgml index 9bbd949f..10817b69 100644 --- a/zh/13/ref/drop_database.sgml +++ b/zh/13/ref/drop_database.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP DATABASE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/drop_domain.sgml b/zh/13/ref/drop_domain.sgml index d43f95c6..b292b189 100644 --- a/zh/13/ref/drop_domain.sgml +++ b/zh/13/ref/drop_domain.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP DOMAIN 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/drop_event_trigger.sgml b/zh/13/ref/drop_event_trigger.sgml index 80020f78..f4f0053f 100644 --- a/zh/13/ref/drop_event_trigger.sgml +++ b/zh/13/ref/drop_event_trigger.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP EVENT TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -30,7 +30,7 @@ DROP EVENT TRIGGER [ IF EXISTS ] name DROP EVENT TRIGGER移除一个现有的事件触发器。 - 要执行此命令,当前用户必须是该事件触发器的拥有者。 + 要执行此命令,当前用户必须是该事件触发器的所有者。 @@ -99,7 +99,7 @@ DROP EVENT TRIGGER snitch; - 另见 + 参见 diff --git a/zh/13/ref/drop_extension.sgml b/zh/13/ref/drop_extension.sgml index 3a1d9136..73cedeb7 100644 --- a/zh/13/ref/drop_extension.sgml +++ b/zh/13/ref/drop_extension.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP EXTENSION 7 - SQL - Language Statements + SQL - 语言语句 @@ -53,8 +53,8 @@ DROP EXTENSION [ IF EXISTS ] name [ name - 已安装扩展的名称。 - + 一个已安装扩展的名称。 + @@ -89,7 +89,7 @@ DROP EXTENSION [ IF EXISTS ] name [ DROP EXTENSION hstore; - 如果数据库中正在使用hstore的任何对象, + 如果数据库中使用了hstore的任何对象, 例如某些表具有hstore类型的列,则该命令会失败。 加上CASCADE选项可以强制一并移除这些依赖对象。 diff --git a/zh/13/ref/drop_foreign_data_wrapper.sgml b/zh/13/ref/drop_foreign_data_wrapper.sgml index 9902c875..6f781f31 100644 --- a/zh/13/ref/drop_foreign_data_wrapper.sgml +++ b/zh/13/ref/drop_foreign_data_wrapper.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP FOREIGN DATA WRAPPER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/drop_foreign_table.sgml b/zh/13/ref/drop_foreign_table.sgml index 0b4d0bbd..c420e4ba 100644 --- a/zh/13/ref/drop_foreign_table.sgml +++ b/zh/13/ref/drop_foreign_table.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP FOREIGN TABLE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/drop_function.sgml b/zh/13/ref/drop_function.sgml index 91756487..58c13a69 100644 --- a/zh/13/ref/drop_function.sgml +++ b/zh/13/ref/drop_function.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP FUNCTION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/drop_group.sgml b/zh/13/ref/drop_group.sgml index 6ca1c03f..a4bace0f 100644 --- a/zh/13/ref/drop_group.sgml +++ b/zh/13/ref/drop_group.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP GROUP 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/drop_index.sgml b/zh/13/ref/drop_index.sgml index b65b810b..d7f892d9 100644 --- a/zh/13/ref/drop_index.sgml +++ b/zh/13/ref/drop_index.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP INDEX 7 - SQL - Language Statements + SQL - 语言语句 @@ -57,7 +57,7 @@ DROP INDEX [ CONCURRENTLY ] [ IF EXISTS ] name 对于临时表,DROP INDEX始终是非并发的, - 因为没有其他会话可以访问它们,而且非并发删除索引的成本更低。 + 因为没有其他会话可以访问它们,而且非并发删除索引的代价更低。 @@ -66,7 +66,7 @@ DROP INDEX [ CONCURRENTLY ] [ IF EXISTS ] nameIF EXISTS - 如果该索引不存在,则不要抛出错误。这种情况下会发出一个提示。 + 如果该索引不存在,则不要抛出错误。这种情况下会发出一条提示。 diff --git a/zh/13/ref/drop_language.sgml b/zh/13/ref/drop_language.sgml index 1dcebc91..55d5fa0b 100644 --- a/zh/13/ref/drop_language.sgml +++ b/zh/13/ref/drop_language.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP LANGUAGE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/drop_materialized_view.sgml b/zh/13/ref/drop_materialized_view.sgml index f3682552..71ad4326 100644 --- a/zh/13/ref/drop_materialized_view.sgml +++ b/zh/13/ref/drop_materialized_view.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP MATERIALIZED VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/drop_opclass.sgml b/zh/13/ref/drop_opclass.sgml index c3dd2e74..9d67dc64 100644 --- a/zh/13/ref/drop_opclass.sgml +++ b/zh/13/ref/drop_opclass.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP OPERATOR CLASS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/drop_operator.sgml b/zh/13/ref/drop_operator.sgml index 64533bef..724a6ffc 100644 --- a/zh/13/ref/drop_operator.sgml +++ b/zh/13/ref/drop_operator.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP OPERATOR 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/drop_opfamily.sgml b/zh/13/ref/drop_opfamily.sgml index 8e7097f9..06223045 100644 --- a/zh/13/ref/drop_opfamily.sgml +++ b/zh/13/ref/drop_opfamily.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP OPERATOR FAMILY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/drop_owned.sgml b/zh/13/ref/drop_owned.sgml index 05e28e68..81bb029c 100644 --- a/zh/13/ref/drop_owned.sgml +++ b/zh/13/ref/drop_owned.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP OWNED 7 - SQL - Language Statements + SQL - 语言语句 @@ -31,7 +31,7 @@ DROP OWNED BY { name | CURRENT_USER DROP OWNED删除当前数据库中由指定角色之一拥有的所有对象。 同时,授予给这些角色的、针对当前数据库中的对象或共享对象 - (数据库、表空间、配置参数)的任何权限也会被撤销。 + (数据库、表空间)的任何权限也会被撤销。 diff --git a/zh/13/ref/drop_policy.sgml b/zh/13/ref/drop_policy.sgml index ee64ffa0..a939a688 100644 --- a/zh/13/ref/drop_policy.sgml +++ b/zh/13/ref/drop_policy.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP POLICY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/drop_procedure.sgml b/zh/13/ref/drop_procedure.sgml index 4aa5aeb3..076093c4 100644 --- a/zh/13/ref/drop_procedure.sgml +++ b/zh/13/ref/drop_procedure.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP PROCEDURE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/drop_publication.sgml b/zh/13/ref/drop_publication.sgml index 6bc4bf59..048c1756 100644 --- a/zh/13/ref/drop_publication.sgml +++ b/zh/13/ref/drop_publication.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP PUBLICATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/drop_role.sgml b/zh/13/ref/drop_role.sgml index 6e06020f..d85224dd 100644 --- a/zh/13/ref/drop_role.sgml +++ b/zh/13/ref/drop_role.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP ROLE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/drop_routine.sgml b/zh/13/ref/drop_routine.sgml index dac09949..d2647512 100644 --- a/zh/13/ref/drop_routine.sgml +++ b/zh/13/ref/drop_routine.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP ROUTINE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/drop_rule.sgml b/zh/13/ref/drop_rule.sgml index ddb561f4..2968d946 100644 --- a/zh/13/ref/drop_rule.sgml +++ b/zh/13/ref/drop_rule.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP RULE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/drop_schema.sgml b/zh/13/ref/drop_schema.sgml index 9f622df3..94843c9a 100644 --- a/zh/13/ref/drop_schema.sgml +++ b/zh/13/ref/drop_schema.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP SCHEMA 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/drop_sequence.sgml b/zh/13/ref/drop_sequence.sgml index 4ba78640..586d3038 100644 --- a/zh/13/ref/drop_sequence.sgml +++ b/zh/13/ref/drop_sequence.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP SEQUENCE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/drop_server.sgml b/zh/13/ref/drop_server.sgml index 0864a4c2..8bdacdc8 100644 --- a/zh/13/ref/drop_server.sgml +++ b/zh/13/ref/drop_server.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP SERVER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/drop_statistics.sgml b/zh/13/ref/drop_statistics.sgml index 3120dc06..4773bfa8 100644 --- a/zh/13/ref/drop_statistics.sgml +++ b/zh/13/ref/drop_statistics.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP STATISTICS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/drop_subscription.sgml b/zh/13/ref/drop_subscription.sgml index ea0f7e7c..455ea597 100644 --- a/zh/13/ref/drop_subscription.sgml +++ b/zh/13/ref/drop_subscription.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP SUBSCRIPTION 7 - SQL - Language Statements + SQL - 语言语句 @@ -32,9 +32,7 @@ DROP SUBSCRIPTION [ IF EXISTS ] nameDROP SUBSCRIPTION从数据库集簇中移除一个订阅。 - - 要执行此命令,用户必须是该订阅的拥有者。 - + 只有超级用户才能删除订阅。 如果订阅与复制槽相关联,则不能在事务块内执行DROP SUBSCRIPTION。(可以使用ALTER SUBSCRIPTION来取消设置该槽。) diff --git a/zh/13/ref/drop_table.sgml b/zh/13/ref/drop_table.sgml index 6193c2e3..50b73e31 100644 --- a/zh/13/ref/drop_table.sgml +++ b/zh/13/ref/drop_table.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TABLE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/drop_tablespace.sgml b/zh/13/ref/drop_tablespace.sgml index c8b09e59..a31fd70f 100644 --- a/zh/13/ref/drop_tablespace.sgml +++ b/zh/13/ref/drop_tablespace.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TABLESPACE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/drop_transform.sgml b/zh/13/ref/drop_transform.sgml index e606b35b..dfba428d 100644 --- a/zh/13/ref/drop_transform.sgml +++ b/zh/13/ref/drop_transform.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TRANSFORM 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/drop_trigger.sgml b/zh/13/ref/drop_trigger.sgml index 1f85cf41..160a5ebd 100644 --- a/zh/13/ref/drop_trigger.sgml +++ b/zh/13/ref/drop_trigger.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -30,7 +30,7 @@ DROP TRIGGER [ IF EXISTS ] name ON DROP TRIGGER移除一个现有触发器的定义。 - 要执行此命令,当前用户必须是定义该触发器的表的拥有者。 + 要执行此命令,当前用户必须是定义该触发器的表的所有者。 @@ -109,7 +109,7 @@ DROP TRIGGER if_dist_exists ON films; - 另见 + 参见 diff --git a/zh/13/ref/drop_tsconfig.sgml b/zh/13/ref/drop_tsconfig.sgml index 2a7cdc52..ea139802 100644 --- a/zh/13/ref/drop_tsconfig.sgml +++ b/zh/13/ref/drop_tsconfig.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TEXT SEARCH CONFIGURATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/drop_tsdictionary.sgml b/zh/13/ref/drop_tsdictionary.sgml index 1eb24189..316c5d00 100644 --- a/zh/13/ref/drop_tsdictionary.sgml +++ b/zh/13/ref/drop_tsdictionary.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TEXT SEARCH DICTIONARY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/drop_tsparser.sgml b/zh/13/ref/drop_tsparser.sgml index 0cfa7acd..a65f47be 100644 --- a/zh/13/ref/drop_tsparser.sgml +++ b/zh/13/ref/drop_tsparser.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TEXT SEARCH PARSER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/drop_tstemplate.sgml b/zh/13/ref/drop_tstemplate.sgml index 282231c5..fa1faab0 100644 --- a/zh/13/ref/drop_tstemplate.sgml +++ b/zh/13/ref/drop_tstemplate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TEXT SEARCH TEMPLATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/drop_type.sgml b/zh/13/ref/drop_type.sgml index dab5bfa0..2f139da5 100644 --- a/zh/13/ref/drop_type.sgml +++ b/zh/13/ref/drop_type.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TYPE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/drop_user.sgml b/zh/13/ref/drop_user.sgml index 48d31af4..32bedce7 100644 --- a/zh/13/ref/drop_user.sgml +++ b/zh/13/ref/drop_user.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP USER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/drop_user_mapping.sgml b/zh/13/ref/drop_user_mapping.sgml index 5cfe0086..029b4362 100644 --- a/zh/13/ref/drop_user_mapping.sgml +++ b/zh/13/ref/drop_user_mapping.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP USER MAPPING 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/drop_view.sgml b/zh/13/ref/drop_view.sgml index 4feb47e5..8f995245 100644 --- a/zh/13/ref/drop_view.sgml +++ b/zh/13/ref/drop_view.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/dropdb.sgml b/zh/13/ref/dropdb.sgml index 4fb744b1..338400d3 100644 --- a/zh/13/ref/dropdb.sgml +++ b/zh/13/ref/dropdb.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation dropdb 1 - Application + 应用程序 diff --git a/zh/13/ref/dropuser.sgml b/zh/13/ref/dropuser.sgml index b20776af..b3985190 100644 --- a/zh/13/ref/dropuser.sgml +++ b/zh/13/ref/dropuser.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation dropuser 1 - Application + 应用程序 diff --git a/zh/13/ref/ecpg-ref.sgml b/zh/13/ref/ecpg-ref.sgml index 0548b14e..e5a6d1a1 100644 --- a/zh/13/ref/ecpg-ref.sgml +++ b/zh/13/ref/ecpg-ref.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ecpg 1 - Application + 应用程序 diff --git a/zh/13/ref/end.sgml b/zh/13/ref/end.sgml index 1ad9eb4d..5268db6a 100644 --- a/zh/13/ref/end.sgml +++ b/zh/13/ref/end.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation END 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/execute.sgml b/zh/13/ref/execute.sgml index 2aed0669..5e7274ff 100644 --- a/zh/13/ref/execute.sgml +++ b/zh/13/ref/execute.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation EXECUTE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/explain.sgml b/zh/13/ref/explain.sgml index ac0e259e..1595c04e 100644 --- a/zh/13/ref/explain.sgml +++ b/zh/13/ref/explain.sgml @@ -21,7 +21,7 @@ PostgreSQL documentation EXPLAIN 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/fetch.sgml b/zh/13/ref/fetch.sgml index 7e6abb4b..d5392d7f 100644 --- a/zh/13/ref/fetch.sgml +++ b/zh/13/ref/fetch.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation FETCH 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/grant.sgml b/zh/13/ref/grant.sgml index 96dca26e..d88b5098 100644 --- a/zh/13/ref/grant.sgml +++ b/zh/13/ref/grant.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation GRANT 7 - SQL - Language Statements + SQL - 语言语句 @@ -96,7 +96,7 @@ GRANT role_name [, ...] TO 描述 - GRANT 命令有两个基本变体:一种是在数据库对象(表、列、视图、外部表、序列、数据库、外部数据包装器、外部服务器、函数、过程、过程语言、大对象、配置参数、模式、表空间或类型)上授予权限,另一种是授予角色成员资格。这两种变体在许多方面相似,但差异也足够大,因此分别说明。 + GRANT 命令有两个基本变体:一种是在数据库对象(表、列、视图、外部表、序列、数据库、外部数据包装器、外部服务器、函数、过程、过程语言、模式或表空间)上授予权限,另一种是授予角色成员资格。这两种变体在许多方面相似,但差异也足够大,因此分别说明。 @@ -224,7 +224,7 @@ GRANT role_name [, ...] TO - 如果超级用户选择执行 GRANTREVOKE 命令,该命令会像由受影响对象的拥有者发出一样执行。特别是,通过这种命令授予的权限看起来会像是由对象拥有者授予的。(对于角色成员资格,则看起来像是由引导超级用户授予的。) + 如果超级用户选择执行 GRANTREVOKE 命令,该命令会像由受影响对象的拥有者发出一样执行。特别是,通过这种命令授予的权限看起来会像是由对象拥有者授予的。(对于角色成员资格,则看起来像是由被授予成员资格的角色本身授予的。) @@ -302,7 +302,7 @@ GRANT admins TO joe; - 数据库、表空间、模式、语言以及配置参数上的权限都是 PostgreSQL 扩展。 + 数据库、表空间、模式和语言上的权限都是 PostgreSQL 扩展。 diff --git a/zh/13/ref/import_foreign_schema.sgml b/zh/13/ref/import_foreign_schema.sgml index 6e912201..1957d60a 100644 --- a/zh/13/ref/import_foreign_schema.sgml +++ b/zh/13/ref/import_foreign_schema.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation IMPORT FOREIGN SCHEMA 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/initdb.sgml b/zh/13/ref/initdb.sgml index f26afbef..067e24f9 100644 --- a/zh/13/ref/initdb.sgml +++ b/zh/13/ref/initdb.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation initdb 1 - Application + 应用程序 diff --git a/zh/13/ref/insert.sgml b/zh/13/ref/insert.sgml index 7de3fd9b..2cedfe9a 100644 --- a/zh/13/ref/insert.sgml +++ b/zh/13/ref/insert.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation INSERT 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/listen.sgml b/zh/13/ref/listen.sgml index 8c31cae2..7451cf82 100644 --- a/zh/13/ref/listen.sgml +++ b/zh/13/ref/listen.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation LISTEN 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/load.sgml b/zh/13/ref/load.sgml index bb0adb7c..89bdb114 100644 --- a/zh/13/ref/load.sgml +++ b/zh/13/ref/load.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation LOAD 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/lock.sgml b/zh/13/ref/lock.sgml index e534eed3..f737a436 100644 --- a/zh/13/ref/lock.sgml +++ b/zh/13/ref/lock.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation LOCK 7 - SQL - Language Statements + SQL - 语言语句 @@ -55,7 +55,7 @@ LOCK [ TABLE ] [ ONLY ] name [ * ] 因为SHARE锁模式与写入者获取的ROW EXCLUSIVE锁冲突, 而LOCK TABLE name IN SHARE MODE - 语句会一直等待,直到任何并发持有ROW EXCLUSIVE模式锁的事务提交或回滚。 + 语句会一直等待,直到所有并发持有ROW EXCLUSIVE模式锁的事务提交或回滚。 因此,一旦获得该锁,就不存在尚未提交的写入;而且在释放该锁之前,也不会有新的写入开始。 @@ -157,9 +157,7 @@ LOCK [ TABLE ] [ ONLY ] name [ * ] 这些模式名称通常应理解为:用户打算在被锁定的表中获取行级锁。 此外,ROW EXCLUSIVE模式本身也是一种可共享的表锁。 请记住,就LOCK TABLE而言,所有锁模式的语义完全相同, - 差别只在于哪些模式彼此冲突。关于如何获取真正的行级锁,请参阅 - 文档中的和 - 。 + 差别只在于哪些模式彼此冲突。关于如何获取真正的行级锁,请参阅 (后者位于文档中)。 diff --git a/zh/13/ref/move.sgml b/zh/13/ref/move.sgml index e90c1b88..961359c8 100644 --- a/zh/13/ref/move.sgml +++ b/zh/13/ref/move.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation MOVE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/notify.sgml b/zh/13/ref/notify.sgml index 2aa6095b..a2df6be2 100644 --- a/zh/13/ref/notify.sgml +++ b/zh/13/ref/notify.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation NOTIFY 7 - SQL - Language Statements + SQL - 语言语句 @@ -88,7 +88,7 @@ NOTIFY channel [ , 注解 - 系统中有一个队列,用来保存那些已经发送但尚未被所有监听会话处理的通知。如果这个队列被塞满,那么调用NOTIFY的事务会在提交时失败。该队列非常大(标准安装中为 8GB),几乎足以满足所有用例。不过,如果某个会话执行了LISTEN后又长时间停留在一个事务里,就无法进行清理。一旦队列占用超过一半,你就会在日志文件中看到警告,指出究竟是哪个会话阻碍了清理。在这种情况下,应确保该会话结束其当前事务,以便清理能够继续进行。 + 系统中有一个队列,用来保存那些已经发送但尚未被所有监听会话处理的通知。如果这个队列被塞满,那么调用NOTIFY的事务会在提交时失败。该队列非常大(标准安装中为 8GB),几乎足以满足所有用例。不过,如果某个会话执行了LISTEN后又长时间停留在一个事务里,就无法进行清理。一旦队列占用达到一半,你就会在日志文件中看到警告,指出究竟是哪个会话阻碍了清理。在这种情况下,应确保该会话结束其当前事务,以便清理能够继续进行。 函数pg_notification_queue_usage返回当前被待处理通知占用的队列比例。详见。 diff --git a/zh/13/ref/pg_basebackup.sgml b/zh/13/ref/pg_basebackup.sgml index a9ec3846..9f3aa005 100644 --- a/zh/13/ref/pg_basebackup.sgml +++ b/zh/13/ref/pg_basebackup.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_basebackup 1 - Application + 应用程序 @@ -33,7 +33,7 @@ PostgreSQL documentation - 在任何模式下,pg_basebackup都会确保服务器自动进入和退出备份模式。备份始终针对整个数据库集簇;不可能只备份单个数据库或数据库对象。对于选择性备份,必须使用诸如之类的其他工具。 + pg_basebackup会精确复制数据库集簇的文件,同时确保服务器自动进入和退出备份模式。备份始终针对整个数据库集簇;不可能只备份单个数据库或数据库对象。对于选择性备份,必须使用诸如之类的其他工具。 @@ -48,7 +48,10 @@ PostgreSQL documentation pg_basebackup不仅可以从主库获取基础备份,也可以从备库获取。要从备库获取备份,需要将备库配置为能够接受复制连接(即设置max_wal_senders,并适当地配置其pg_hba.conf)。还需要在主库上启用 - 注意,从备库获取备份时有一些限制: + + 请注意,从备库获取备份存在一些限制: + + 备份历史文件不会在被备份的数据库集簇中创建。 @@ -166,7 +169,7 @@ PostgreSQL documentation - 目前,此选项仅适用于 plain 输出格式;如果选择了 tar 格式,则会被忽略。 + 目前,此选项仅适用于 普通文件 输出格式;如果选择了 tar 格式,则会被忽略。 @@ -176,7 +179,7 @@ PostgreSQL documentation - 设置写入 WAL(预写式日志)文件的目录。默认情况下,WAL 文件会放在目标目录的pg_wal子目录中,但此选项可用于将其放在其他位置。waldir必须是绝对路径。与主目标目录一样,waldir不必事先存在,但如果存在则必须为空。只有当备份采用 plain 格式时,才能指定此选项。 + 设置写入 WAL(预写式日志)文件的目录。默认情况下,WAL 文件会放在目标目录的pg_wal子目录中,但此选项可用于将其放在其他位置。waldir必须是绝对路径。与主目标目录一样,waldir不必事先存在,但如果存在则必须为空。只有当备份采用 普通文件 格式时,才能指定此选项。 @@ -188,7 +191,10 @@ PostgreSQL documentation 在备份中包含所需的 WAL(预写式日志)文件。这将包括备份期间生成的所有预写式日志。除非指定方法none,否则就可以在目标目录中启动 postmaster,而无需查阅 WAL 归档,从而使输出成为一个完全独立的备份。 - 支持以下 method 来收集预写式日志: + + 支持以下用于收集预写式日志的method值: + + n none @@ -227,7 +233,8 @@ PostgreSQL documentation - + + @@ -248,7 +255,7 @@ PostgreSQL documentation - 启用 tar 文件输出的 gzip 压缩,使用默认压缩级别。压缩仅在使用 tar 格式时可用,并且所有 tar 文件名都会自动添加.gz后缀。 + 启用 tar 文件输出的 gzip 压缩,并指定压缩级别(0 到 9,其中 0 表示不压缩,9 表示最佳压缩)。压缩仅在使用 tar 格式时可用,并且所有 tar 文件名都会自动添加.gz后缀。 @@ -299,7 +306,7 @@ PostgreSQL documentation - 请注意,无论如何表空间目录都不会被清理。 + 请注意,无论是否使用此选项,表空间目录都不会被清理。 @@ -347,7 +354,7 @@ PostgreSQL documentation - 此选项只能与-X stream一起使用。它会使 WAL 流式传输使用指定的复制槽。如果此基础备份打算用作使用复制槽的流复制备库,那么该备库应使用与相同的复制槽名称。这样可以确保主库在基础备份结束与新备库开始流复制之间的这段时间内,不会移除任何必需的 WAL 数据。 + 此选项只能与-X stream一起使用。它会使 WAL 流式传输使用指定的复制槽。如果此基础备份打算用作使用复制槽的流复制备库,那么该备库应将同一个复制槽名称用作的值。这样可以确保主库在基础备份结束与新备库开始流复制之间的这段时间内,不会移除任何必需的 WAL 数据。 @@ -384,7 +391,7 @@ PostgreSQL documentation - 对于希望验证备份未被篡改的用户,使用 SHA 哈希函数可以为每个文件提供具有密码学安全性的摘要;而 CRC-32C 算法提供的校验和计算速度要快得多,虽然它很适合发现由于意外改动造成的错误,但并不能抵御恶意修改。请注意,要想对能够访问备份的攻击者形成防护,备份清单就需要安全地保存在其他地方,或者以其他方式确认自备份完成后未被修改。 + 对于希望验证备份未被篡改的用户,使用 SHA hash 函数可以为每个文件提供具有密码学安全性的摘要;而 CRC32C 算法提供的校验和计算速度要快得多,虽然它很适合发现由于意外改动造成的错误,但并不能抵御恶意修改。请注意,要想对能够访问备份的攻击者形成防护,备份清单就需要安全地保存在其他地方,或者以其他方式确认自备份完成后未被修改。 @@ -465,7 +472,10 @@ PostgreSQL documentation - 以下命令行选项控制与源服务器的连接: + + 以下命令行选项控制到源服务器的连接: + + @@ -543,7 +553,10 @@ PostgreSQL documentation - 还可以使用其他选项: + + 其他选项也可用: + + @@ -583,18 +596,18 @@ PostgreSQL documentation - 注意 + 注解 在备份开始时,需要在源服务器上执行一次检查点。这可能需要一些时间(尤其是在未使用--checkpoint=fast选项时);在此期间,pg_basebackup看起来会处于空闲状态。 - 备份将包括数据目录和表空间中的所有文件,包括配置文件以及第三方放在这些目录中的任何额外文件,但由 PostgreSQL 管理的某些临时文件和操作系统文件除外。不过,只有普通文件和目录会被复制,但用于表空间的符号链接会被保留。指向 PostgreSQL 已知某些目录的符号链接会被复制为空目录。其他符号链接和特殊设备文件则会被跳过。具体细节见。 + 备份将包括数据目录和表空间中的所有文件,包括配置文件以及第三方放在这些目录中的任何额外文件,但由 PostgreSQL 管理的某些临时文件除外。不过,只有普通文件和目录会被复制,但用于表空间的符号链接会被保留。指向 PostgreSQL 已知某些目录的符号链接会被复制为空目录。其他符号链接和特殊设备文件则会被跳过。具体细节见 - 在 plain 格式中,除非使用了--tablespace-mapping选项,否则表空间会备份到其在源服务器上的相同路径。如果不使用此选项,那么当表空间正在使用时,就无法在与服务器相同的主机上执行 plain 格式的基础备份,因为备份将不得不写入与原始表空间相同的目录位置。 + 在 普通文件 格式中,除非使用了--tablespace-mapping选项,否则表空间会备份到其在源服务器上的相同路径。如果不使用此选项,那么当表空间正在使用时,就无法在与服务器相同的主机上执行 普通文件 格式的基础备份,因为备份将不得不写入与原始表空间相同的目录位置。 @@ -634,14 +647,15 @@ PostgreSQL documentation (如果该数据库中有多个表空间,此命令将失败。) - 要为本地数据库创建备份,并把位于 /opt/ts 的表空间重定位到 ./backup/ts: + + 要创建一个本地数据库的备份,并将位于/opt/ts中的表空间重定位到./backup/ts $ pg_basebackup -D backup/data -T /opt/ts=$(pwd)/backup/ts - 参见 + 另见 diff --git a/zh/13/ref/pg_checksums.sgml b/zh/13/ref/pg_checksums.sgml index d81f663a..135038a0 100644 --- a/zh/13/ref/pg_checksums.sgml +++ b/zh/13/ref/pg_checksums.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_checksums 1 - Application + 应用程序 diff --git a/zh/13/ref/pg_config-ref.sgml b/zh/13/ref/pg_config-ref.sgml index 37dd43a8..7ea2f196 100644 --- a/zh/13/ref/pg_config-ref.sgml +++ b/zh/13/ref/pg_config-ref.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_config 1 - Application + 应用程序 diff --git a/zh/13/ref/pg_controldata.sgml b/zh/13/ref/pg_controldata.sgml index 818db6cc..5435edfa 100644 --- a/zh/13/ref/pg_controldata.sgml +++ b/zh/13/ref/pg_controldata.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_controldata 1 - Application + 应用程序 diff --git a/zh/13/ref/pg_ctl-ref.sgml b/zh/13/ref/pg_ctl-ref.sgml index 8807f74f..3017fc06 100644 --- a/zh/13/ref/pg_ctl-ref.sgml +++ b/zh/13/ref/pg_ctl-ref.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_ctl 1 - Application + 应用程序 @@ -158,7 +158,7 @@ PostgreSQL documentation - 模式会关闭在指定数据目录中运行的服务器。可以使用选项选择三种不同的关闭方法。Smart模式不允许新连接,然后等待所有现有客户端断开。如果服务器处于热备状态,那么在所有客户端断开后,恢复和流复制都会终止。Fast模式(默认值)不等待客户端断开。所有活动事务都会回滚,客户端会被强制断开,然后服务器关闭。Immediate模式会立即中止所有服务器进程,而不执行干净关闭。这样会导致服务器在下次启动时进入一次崩溃恢复周期。 + 模式会关闭在指定数据目录中运行的服务器。可以使用选项选择三种不同的关闭方法。Smart模式不允许新连接,然后等待所有现有客户端断开,以及所有在线备份结束。如果服务器处于热备状态,那么在所有客户端断开后,恢复和流复制都会终止。Fast模式(默认值)不等待客户端断开,并会终止正在进行的在线备份。所有活动事务都会回滚,客户端会被强制断开,然后服务器关闭。Immediate模式会立即中止所有服务器进程,而不执行干净关闭。这样会导致服务器在下次启动时进入一次崩溃恢复周期。 diff --git a/zh/13/ref/pg_dump.sgml b/zh/13/ref/pg_dump.sgml index 2f023433..d5c91c7e 100644 --- a/zh/13/ref/pg_dump.sgml +++ b/zh/13/ref/pg_dump.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_dump 1 - Application + 应用程序 @@ -300,7 +300,9 @@ PostgreSQL documentation 同步快照特性,就无法保证各个工作任务在各自连接中看到相同的数据,这会 导致备份不一致。 - 如果要对 9.2 之前的服务器执行并行转储,必须确保从主进程连接数据库起,到最后一个工作任务连接数据库为止,数据库内容都不发生变化。最简单的方法是在开始备份之前,暂停所有访问数据库并修改数据的进程(DDL 和 DML)。对 9.2 之前的服务器使用参数也是必需的,即使用pg_dump -j连接这些PostgreSQL服务器时。 + + 如果要对 9.2 之前的服务器执行并行转储,必须确保从主进程连接数据库起,到最后一个工作任务连接数据库为止,数据库内容都不发生变化。最简单的方法是在开始备份之前,暂停所有访问数据库并修改数据的进程(DDL 和 DML)。对 9.2 之前的PostgreSQL服务器运行pg_dump -j时,还必须指定参数。 + diff --git a/zh/13/ref/pg_dumpall.sgml b/zh/13/ref/pg_dumpall.sgml index 02e64f0f..09ff5c5b 100644 --- a/zh/13/ref/pg_dumpall.sgml +++ b/zh/13/ref/pg_dumpall.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_dumpall 1 - Application + 应用程序 @@ -32,7 +32,7 @@ PostgreSQL documentation pg_dumpall是一个实用程序,用于写出(转储)一个集簇中的所有PostgreSQL数据库到一个脚本文件中。该脚本文件包含SQL命令,可作为的输入来恢复这些数据库。它通过对集簇中的每个数据库调用来实现这一点。pg_dumpall还会转储所有数据库共有的全局对象,即数据库角色、表空间以及配置参数的权限授予。 + linkend="app-psql"/>的输入来恢复这些数据库。它通过对集簇中的每个数据库调用来实现这一点。pg_dumpall还会转储所有数据库共有的全局对象,即数据库角色、表空间。 (pg_dump不会保存这些对象。) diff --git a/zh/13/ref/pg_isready.sgml b/zh/13/ref/pg_isready.sgml index 31f6aea0..541352d6 100644 --- a/zh/13/ref/pg_isready.sgml +++ b/zh/13/ref/pg_isready.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_isready 1 - Application + 应用程序 diff --git a/zh/13/ref/pg_receivewal.sgml b/zh/13/ref/pg_receivewal.sgml index 0d65f992..093aa95c 100644 --- a/zh/13/ref/pg_receivewal.sgml +++ b/zh/13/ref/pg_receivewal.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_receivewal 1 - Application + 应用程序 diff --git a/zh/13/ref/pg_recvlogical.sgml b/zh/13/ref/pg_recvlogical.sgml index a410ca0d..162e0196 100644 --- a/zh/13/ref/pg_recvlogical.sgml +++ b/zh/13/ref/pg_recvlogical.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_recvlogical 1 - Application + 应用程序 @@ -67,7 +67,9 @@ PostgreSQL documentation - 删除由指定名称的复制槽,然后退出。 + + 删除由指定名称的复制槽,然后退出。 + @@ -79,9 +81,13 @@ PostgreSQL documentation 如果服务端的更改流因服务器关闭或断开连接而结束,则除非指定了,否则会循环重试。 - 流格式由创建槽时指定的输出插件决定。 + + 流格式由创建该槽时指定的输出插件决定。 + - 必须连接到创建槽时使用的同一个数据库。 + + 该连接必须连到创建该槽时所用的同一个数据库。 + @@ -118,7 +124,9 @@ PostgreSQL documentation - 将接收到的已解码事务数据写入此文件。使用-表示stdout + + 将接收到并解码后的事务数据写入该文件。指定-表示写入stdout。 + @@ -129,7 +137,7 @@ PostgreSQL documentation 指定pg_recvlogical应当以多高的频率发起fsync()调用, - 以确保输出文件被安全地刷入磁盘。 + 以确保输出文件安全刷盘。 @@ -148,14 +156,20 @@ PostgreSQL documentation - 模式下,从给定的 LSN 开始复制。有关其效果的详细信息,请参阅中的文档。在其他模式下忽略此选项。 + + 在模式下,从给定的 LSN 开始复制。关于其影响的详细信息,请参见 + 中的说明。 + 在其他模式下会忽略此选项。 + - 指定且指定名称的槽已存在时,不报错。 + + 当指定且指定名称的槽已存在时,不报错。 + @@ -163,7 +177,9 @@ PostgreSQL documentation - 当与服务器的连接丢失时,不循环重试,直接退出。 + + 当与服务器的连接丢失时,不要循环重试,直接退出。 + @@ -171,7 +187,10 @@ PostgreSQL documentation - 将选项name传递给输出插件,如果指定了选项值value,也一并传递。有哪些选项以及它们的效果取决于所用的输出插件。 + + 将选项name传递给输出插件;如果指定了value, + 则将其用作该选项的值。可用选项及其效果取决于所使用的输出插件。 + @@ -179,7 +198,10 @@ PostgreSQL documentation - 创建槽时,使用指定的逻辑解码输出插件。参见。如果槽已存在,此选项不起作用。 + + 创建该槽时,使用指定的逻辑解码输出插件。参见。 + 如果该槽已经存在,则此选项不起作用。 + @@ -187,7 +209,9 @@ PostgreSQL documentation - 此选项与中同名选项的效果相同。请参阅那里的说明。 + + 该选项与中同名选项的效果相同。参见该处说明。 + @@ -195,7 +219,11 @@ PostgreSQL documentation - 模式下,使用名为slot_name的现有逻辑复制槽。在模式下,创建此名称的槽。在模式下,删除此名称的槽。 + + 在模式下,使用名为slot_name的现有逻辑复制槽。 + 在模式下,以此名称创建该槽。 + 在模式下,删除此名称的槽。 + @@ -203,7 +231,9 @@ PostgreSQL documentation - 启用详细模式。 + + 启用详细模式。 + @@ -247,7 +277,9 @@ PostgreSQL documentation - 连接时使用的用户名。默认为当前操作系统用户名。 + + 用于连接的用户名。默认为当前操作系统用户名。 + @@ -289,7 +321,9 @@ PostgreSQL documentation - 打印pg_recvlogical的版本并退出。 + + 打印pg_recvlogical的版本并退出。 + @@ -297,7 +331,9 @@ PostgreSQL documentation - 显示pg_recvlogical命令行参数的帮助并退出。 + + 显示pg_recvlogical命令行参数的帮助并退出。 + @@ -318,7 +354,7 @@ PostgreSQL documentation - 环境 + 注解 如果源集簇启用了组权限,pg_recvlogical会在接收到的 WAL 文件上保留这些组权限。 diff --git a/zh/13/ref/pg_resetwal.sgml b/zh/13/ref/pg_resetwal.sgml index eaa27a9e..c5c3c18a 100644 --- a/zh/13/ref/pg_resetwal.sgml +++ b/zh/13/ref/pg_resetwal.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_resetwal 1 - Application + 应用程序 diff --git a/zh/13/ref/pg_restore.sgml b/zh/13/ref/pg_restore.sgml index 42f9cba8..39e6331a 100644 --- a/zh/13/ref/pg_restore.sgml +++ b/zh/13/ref/pg_restore.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_restore 1 - Application + 应用程序 diff --git a/zh/13/ref/pg_rewind.sgml b/zh/13/ref/pg_rewind.sgml index 4b28a85e..b71167e3 100644 --- a/zh/13/ref/pg_rewind.sgml +++ b/zh/13/ref/pg_rewind.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_rewind 1 - Application + 应用程序 diff --git a/zh/13/ref/pg_verifybackup.sgml b/zh/13/ref/pg_verifybackup.sgml index 46c42ea5..e2768edc 100644 --- a/zh/13/ref/pg_verifybackup.sgml +++ b/zh/13/ref/pg_verifybackup.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_verifybackup 1 - Application + 应用程序 @@ -28,13 +28,12 @@ PostgreSQL documentation 描述 - pg_verifybackup用于检查通过pg_basebackup获取的数据库集簇备份的完整性,检查依据是服务器在备份时生成的backup_manifest。备份必须以“plain”格式存储;“tar”格式的备份可以在解包后检查。 + pg_verifybackup用于检查通过pg_basebackup获取的数据库集簇备份的完整性,检查依据是服务器在备份时生成的backup_manifest。备份必须以“普通文件”格式存储;“tar”格式的备份可以在解包后检查。 需要注意,pg_verifybackup执行的验证并未、也 不可能涵盖运行中的服务器在尝试使用该备份时会执行的每一项检查。即使使 - 用了此工具,你仍应进行测试恢复,并确认生成的数据库按预期工作且包含正 - 确的数据。不过,pg_verifybackup能够检测出 + 用了此工具,你仍应进行测试恢复,并确认生成的数据库按预期工作且看起来包含正确的数据。不过,pg_verifybackup能够检测出 许多因存储问题或用户错误而常见的问题。 @@ -171,7 +170,10 @@ PostgreSQL documentation - 还可以使用其他选项: + + 其他选项也可用: + + @@ -202,7 +204,7 @@ PostgreSQL documentation 示例 - 要在mydbserver上创建服务器的基础备份,并验证该备 + 要为位于mydbserver的服务器创建基础备份,并验证该备 份的完整性: $ pg_basebackup -h mydbserver -D /usr/local/pgsql/data @@ -211,7 +213,7 @@ PostgreSQL documentation - 要在mydbserver上创建服务器的基础备份,将备份清单 + 要为位于mydbserver的服务器创建基础备份,将备份清单 移到备份目录之外的位置,然后验证该备份: $ pg_basebackup -h mydbserver -D /usr/local/pgsql/backup1234 diff --git a/zh/13/ref/pg_waldump.sgml b/zh/13/ref/pg_waldump.sgml index 2031a761..e9bbb708 100644 --- a/zh/13/ref/pg_waldump.sgml +++ b/zh/13/ref/pg_waldump.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_waldump 1 - Application + 应用程序 diff --git a/zh/13/ref/pgarchivecleanup.sgml b/zh/13/ref/pgarchivecleanup.sgml index ac769603..f8f94822 100644 --- a/zh/13/ref/pgarchivecleanup.sgml +++ b/zh/13/ref/pgarchivecleanup.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_archivecleanup 1 - Application + 应用程序 diff --git a/zh/13/ref/pgbench.sgml b/zh/13/ref/pgbench.sgml index 1d30d1f7..8cf1c187 100644 --- a/zh/13/ref/pgbench.sgml +++ b/zh/13/ref/pgbench.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pgbench 1 - Application + 应用程序 @@ -1546,7 +1546,7 @@ SELECT 4 AS four \; SELECT 5 AS five \aset greatest ( number , ... ) - double 如果任何参数是双精度的,否则 integer + 若任一参数为 double,则为 double,否则为 integer 选择参数中的最大值。 @@ -1616,7 +1616,7 @@ SELECT 4 AS four \; SELECT 5 AS five \aset least ( number , ... ) - double 如果任何参数是双精度的,否则 integer + 若任一参数为 double,则为 double,否则为 integer 选择参数中的最小值。 @@ -2005,7 +2005,7 @@ statement latencies in milliseconds: 安全性 - 如果不可信用户能够访问尚未采用模式的安全使用方式的数据库,就不要在该数据库中运行pgbenchpgbench使用非限定名称,并且不会更改搜索路径。 + 如果不受信任的用户能够访问尚未采用模式的安全使用方式的数据库,就不要在该数据库中运行pgbenchpgbench使用非限定名称,并且不会更改搜索路径。 diff --git a/zh/13/ref/pgtestfsync.sgml b/zh/13/ref/pgtestfsync.sgml index 09c5c82c..0016a024 100644 --- a/zh/13/ref/pgtestfsync.sgml +++ b/zh/13/ref/pgtestfsync.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_test_fsync 1 - Application + 应用程序 diff --git a/zh/13/ref/pgtesttiming.sgml b/zh/13/ref/pgtesttiming.sgml index 5b023c7f..1b7dbeee 100644 --- a/zh/13/ref/pgtesttiming.sgml +++ b/zh/13/ref/pgtesttiming.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_test_timing 1 - Application + 应用程序 diff --git a/zh/13/ref/pgupgrade.sgml b/zh/13/ref/pgupgrade.sgml index 59774581..930c9ea3 100644 --- a/zh/13/ref/pgupgrade.sgml +++ b/zh/13/ref/pgupgrade.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_upgrade 1 - Application + 应用程序 @@ -110,7 +110,7 @@ PostgreSQL documentation - 要使用的并发连接和进程/线程数 + 要使用的并发进程或线程数 @@ -337,7 +337,7 @@ NET STOP postgresql-&majorversion; 始终运行新服务器的 pg_upgrade 二进制,而不是旧服务器的。 pg_upgrade 需要指定新旧集簇的数据目录和可执行文件 (bin)目录。你还可以指定用户和端口值,以及是否希望将数据文件 - 链接、克隆或交换,而不是采用默认的复制行为。 + 链接或克隆,而不是采用默认的复制行为。 @@ -345,9 +345,7 @@ NET STOP postgresql-&majorversion; 新集簇,就无法再访问旧集簇。链接模式还要求新旧集簇的数据目录位于同一文件系统中。 (表空间和 pg_wal 可以位于不同文件系统中。)克隆模式具有相同的 速度和磁盘空间优势,但在启动新集簇后不会使旧集簇不可用。克隆模式同样要求新旧数据目录 - 位于同一文件系统中。该模式只在某些操作系统和文件系统上可用。如果关系很多,交换模式 - 可能最快,但一旦文件传输步骤开始,你将无法再访问旧集簇。交换模式也要求新旧集簇的数据 - 目录位于同一文件系统中。 + 位于同一文件系统中。该模式只在某些操作系统和文件系统上可用。 选项允许使用多个 CPU 核心复制/链接文件,并行转储和恢复数据库模式;一个不错的起始值是 CPU 核心数与表空间数量中的较大值。对于运行在多处理器机器上的多数据库服务器,此选项可以显著减少升级时间。 @@ -566,7 +564,7 @@ psql --username=postgres --file=script.sql postgres - 环境 + 注解 pg_upgrade会在当前工作目录中创建各种工作文件,例如模式转储。为安全起见,请确保任何其他用户都无法读取或写入该目录。 @@ -624,7 +622,7 @@ psql --username=postgres --file=script.sql postgres - 注解 + 另见 diff --git a/zh/13/ref/postgres-ref.sgml b/zh/13/ref/postgres-ref.sgml index b20c42dc..616718cf 100644 --- a/zh/13/ref/postgres-ref.sgml +++ b/zh/13/ref/postgres-ref.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation postgres 1 - Application + 应用程序 @@ -97,7 +97,7 @@ PostgreSQL documentation 打印指定运行时参数的值并退出。 - (详情见上面的选项。)这会返回 + (详情见上面的选项。)这个选项可用于正在运行的服务器,它会返回 postgresql.conf中的值,并应用本次调用中提供的任何参数修改。它不反映 集簇启动时提供的参数。 @@ -537,7 +537,7 @@ PostgreSQL documentation - 表明另一台服务器已经在运行的失败消息 + 表明另一个服务器已经在运行的失败消息 应仔细检查,例如可根据你的系统使用下面的命令: $ ps ax | grep postgres @@ -682,16 +682,26 @@ PostgreSQL documentation 示例 - 启动 postgres 时,如需使用默认值并在后台运行,请输入: + + 要使用默认值在后台启动postgres, + 输入: + + $ nohup postgres >logfile 2>&1 </dev/null & - 启动 postgres 并指定端口,例如 1234: + + 要用指定端口启动postgres, + 例如 1234: + $ postgres -p 1234 -要使用 psql 连接到此服务器,请用 -p 选项指定该端口: + + 要使用psql连接到该服务器,请用选项指定这个端口: + $ psql -p 1234 -或者设置环境变量 PGPORT: + + 或者设置环境变量PGPORT $ export PGPORT=1234 $ psql @@ -716,7 +726,7 @@ PostgreSQL documentation - 参见 + 另见 , diff --git a/zh/13/ref/prepare.sgml b/zh/13/ref/prepare.sgml index 917dff06..6537ed4e 100644 --- a/zh/13/ref/prepare.sgml +++ b/zh/13/ref/prepare.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation PREPARE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/prepare_transaction.sgml b/zh/13/ref/prepare_transaction.sgml index 90d8e778..2705a55f 100644 --- a/zh/13/ref/prepare_transaction.sgml +++ b/zh/13/ref/prepare_transaction.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation PREPARE TRANSACTION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/psql-ref.sgml b/zh/13/ref/psql-ref.sgml index 34540b3f..c71a8faa 100644 --- a/zh/13/ref/psql-ref.sgml +++ b/zh/13/ref/psql-ref.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation psql 1 - Application + 应用程序 @@ -532,7 +532,7 @@ testdb=> - 如果不可信用户能够访问尚未采用模式的安全使用方式的数据库,请在会话开始时从search_path中移除所有公众可写的 schema。可以在连接字符串中加入options=-csearch_path=,或者在执行其他 SQL 命令之前发出SELECT pg_catalog.set_config('search_path', '', false)。这种考虑并非psql特有;它适用于任何执行任意 SQL 命令的接口。 + 如果不受信任的用户能够访问尚未采用模式的安全使用方式的数据库,请在会话开始时从search_path中移除所有公众可写的模式。可以在连接字符串中加入options=-csearch_path=,或者在执行其他 SQL 命令之前发出SELECT pg_catalog.set_config('search_path', '', false)。这种考虑并非psql特有;它适用于任何执行任意 SQL 命令的接口。 @@ -1263,11 +1263,7 @@ CREATE INDEX - 生成的查询按照返回的行的顺序执行,并在每行内从左到右执行,如果有多个列。NULL字段将被忽略。生成的查询文字 - 直接发送到服务器进行处理,因此它们不能是psql元命令,也不能包含psql - 变量引用。如果任何单个查询失败,剩余查询的执行将继续,除非设置了ON_ERROR_STOP。每个查询的执行 - 都受ECHO处理的影响。(通常在使用\gexec时,将ECHO设置为 - allqueries是明智的。)查询记录、单步模式、计时和其他查询执行功能也适用于每个生成的查询。 + 生成的查询按照返回行的顺序执行;如果有多列,则在每行内从左到右执行。NULL 字段会被忽略。生成的查询按原样发送到服务器进行处理,因此不能是psql元命令,也不能包含psql变量引用。如果某个查询失败,仍会继续执行其余查询,除非设置了ON_ERROR_STOP。每个查询的执行都受ECHO处理的影响。(通常,在使用\gexec时,适宜将ECHO设为allqueries。)查询日志、单步模式、计时及其他查询执行功能也适用于每个生成的查询。 如果当前查询缓冲区为空,则改为重新执行最近发送的查询。 @@ -2480,7 +2476,7 @@ bar <acronym>SQL</acronym> 中插入变量 - psql变量的一个关键特性是可以把它们替换(插入)到常规SQL语句中,也可以把它们作为元命令的参数。此外,psql还提供了功能来确保被用作 SQL 文字和标识符的变量值会被正确地引用。插入一个值而不需要加引用的语法是在变量名前面加上一个冒号(:)。例如, + psql变量的一个关键特性是可以把它们替换(插入)到常规SQL语句中,也可以把它们作为元命令的参数。此外,psql还提供了功能来确保被用作 SQL 字面量和标识符的变量值会被正确地加引号。插入一个值而不加引号的语法是在变量名前面加上一个冒号(:)。例如, testdb=> \set foo 'my_table' testdb=> SELECT * FROM :foo; diff --git a/zh/13/ref/reassign_owned.sgml b/zh/13/ref/reassign_owned.sgml index b436f800..e3717fea 100644 --- a/zh/13/ref/reassign_owned.sgml +++ b/zh/13/ref/reassign_owned.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation REASSIGN OWNED 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/refresh_materialized_view.sgml b/zh/13/ref/refresh_materialized_view.sgml index 8df289dd..4b8f7812 100644 --- a/zh/13/ref/refresh_materialized_view.sgml +++ b/zh/13/ref/refresh_materialized_view.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation REFRESH MATERIALIZED VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/reindex.sgml b/zh/13/ref/reindex.sgml index 2df68def..6e21191e 100644 --- a/zh/13/ref/reindex.sgml +++ b/zh/13/ref/reindex.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation REINDEX 7 - SQL - Language Statements + SQL - 语言语句 @@ -23,7 +23,7 @@ PostgreSQL documentation REINDEX [ ( option [, ...] ) ] { INDEX | TABLE | SCHEMA | DATABASE | SYSTEM } [ CONCURRENTLY ] name -其中option为以下之一: +其中 option 可以是以下之一: VERBOSE @@ -33,7 +33,8 @@ REINDEX [ ( option [, ...] ) ] { IN 描述 - REINDEX利用索引所属表中存储的数据重建索引,替换该索引的旧副本。以下几种情况适合使用REINDEX: + REINDEX使用索引所属表中存储的数据重建索引, + 并替换索引的旧副本。以下几种场景适合使用REINDEX @@ -108,8 +109,8 @@ REINDEX [ ( option [, ...] ) ] { IN - 重新创建当前数据库中除系统目录外的所有索引。 - 系统目录上的索引不会被处理。这种形式的REINDEX不能 + 重新创建当前数据库中的所有索引。 + 共享系统目录上的索引也会被处理。这种形式的REINDEX不能 在事务块内执行。 @@ -134,8 +135,7 @@ REINDEX [ ( option [, ...] ) ] { IN 要重新索引的特定索引、表或数据库的名称。索引名和表名可以带模式限 定。目前,REINDEX DATABASE和 - REINDEX SYSTEM只能对当前数据库重新索引。它们的参 - 数是可选的,但如果给出,就必须与当前数据库名匹配。 + REINDEX SYSTEM只能对当前数据库重新索引,所以其参数必须与当前数据库名匹配。 @@ -233,8 +233,8 @@ REINDEX [ ( option [, ...] ) ] { IN 并发重建索引 - index - rebuilding concurrently + 索引 + 并发重建 @@ -315,7 +315,13 @@ REINDEX [ ( option [, ...] ) ] { IN - 如果重建索引时出现问题,例如唯一索引违反唯一性约束,REINDEX命令会失败,但除了原有索引外,还会留下一个无效的新索引。查询时会忽略该索引,因为它可能不完整;但它仍会产生更新开销。psql \d命令会将这种索引报告为INVALID: + + 如果在重建索引时出现问题,例如唯一索引上发生唯一性违反, + REINDEX命令会失败,但除了原有索引外,还会留下一个 + 无效的新索引。这个索引在查询时会被忽略,因为它可能不 + 完整;不过它仍会带来更新开销。psql的 + \d命令会把这样的索引报告为 + INVALID postgres=# \d tab @@ -326,8 +332,17 @@ postgres=# \d tab Indexes: "idx" btree (col) "idx_ccnew" btree (col) INVALID -如果标记为INVALID的索引带有后缀_ccnew,则它对应的是在并发操作期间创建的临时索引,建议的恢复方法是使用DROP INDEX将其删除,然后再次尝试REINDEX CONCURRENTLY。如果无效索引带有的后缀是_ccold,则它对应于未能删除的原始索引;建议的恢复方法是直接删除该索引,因为重建本身已成功。无效索引名称的后缀可能会追加非零数字,以保持名称唯一,例如 _ccnew1, - _ccold2 等。 + + + 如果被标记为INVALID的索引带有 + _ccnew后缀,那么它对应于并发操作期间创建的临时索 + 引,推荐的恢复方法是使用DROP INDEX将其删除,然后 + 再次尝试REINDEX CONCURRENTLY。如果无效索引带有 + _ccold后缀,则它对应于未能删除的原始索引;由于重 + 建本身实际上已经成功,推荐的恢复方法就是直接删除该索引。为了保持名 + 称唯一,无效索引名的后缀后还可能附加非零数字,例如 + _ccnew1_ccold2等。 + 常规索引构建允许同一张表上的其他常规索引构建同时进行,但一张表在同一 diff --git a/zh/13/ref/reindexdb.sgml b/zh/13/ref/reindexdb.sgml index 4e63840f..e0f7f7a4 100644 --- a/zh/13/ref/reindexdb.sgml +++ b/zh/13/ref/reindexdb.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation reindexdb 1 - Application + 应用程序 @@ -150,7 +150,10 @@ PostgreSQL documentation - 仅重建 index。可以重建多个索引,方法是多次指定 开关。 + + 只重建index。 + 可以通过写多个开关来重建多个索引。 + @@ -193,7 +196,10 @@ PostgreSQL documentation - 仅重建以下对象的索引:schema。可以重建多个模式中的索引,方法是多次指定 开关。 + + 只重建schema中的索引。 + 可以通过写多个开关来重建多个模式中的索引。 + @@ -201,7 +207,10 @@ PostgreSQL documentation - 仅重建以下对象的索引:table。可以重建多个表的索引,方法是多次指定 开关。 + + 只重建table上的索引。 + 可以通过写多个开关来重建多个表上的索引。 + @@ -358,22 +367,24 @@ PostgreSQL documentation - 示例 + 注解 reindexdb 可能需要多次连接到 PostgreSQL 服务器,每次都要求输入密码。在这种情况下,使用 ~/.pgpass 文件会很方便。更多信息见 - 参见 + 示例 - 要重新索引数据库test: + + 要重建数据库test中的索引: $ reindexdb test - 要重新索引表foo和索引bar,其所在数据库名为abcd: + + 要重建名为abcd的数据库中表foo的索引和索引bar $ reindexdb --table=foo --index=bar abcd diff --git a/zh/13/ref/release_savepoint.sgml b/zh/13/ref/release_savepoint.sgml index f060b242..c3b97896 100644 --- a/zh/13/ref/release_savepoint.sgml +++ b/zh/13/ref/release_savepoint.sgml @@ -10,18 +10,18 @@ PostgreSQL documentation 保存点 - releasing + 释放 RELEASE SAVEPOINT 7 - SQL - Language Statements + SQL - 语言语句 RELEASE SAVEPOINT - 释放一个先前定义的保存点 + 销毁一个先前定义的保存点 @@ -48,7 +48,7 @@ RELEASE [ SAVEPOINT ] savepoint_name savepoint_name - 要释放的保存点名称。 + 要销毁的保存点名称。 @@ -74,14 +74,18 @@ RELEASE [ SAVEPOINT ] savepoint_name 示例 - 建立保存点并在之后将其销毁: + + 要建立保存点,并在稍后销毁它: + BEGIN; INSERT INTO table1 VALUES (3); SAVEPOINT my_savepoint; INSERT INTO table1 VALUES (4); RELEASE SAVEPOINT my_savepoint; COMMIT; -上面的事务会同时插入 3 和 4。 + + 上述事务将同时插入 3 和 4。 + diff --git a/zh/13/ref/reset.sgml b/zh/13/ref/reset.sgml index e8aeae8c..5e249ff9 100644 --- a/zh/13/ref/reset.sgml +++ b/zh/13/ref/reset.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation RESET 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/revoke.sgml b/zh/13/ref/revoke.sgml index f0df1116..4bd986af 100644 --- a/zh/13/ref/revoke.sgml +++ b/zh/13/ref/revoke.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation REVOKE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/rollback.sgml b/zh/13/ref/rollback.sgml index 6062ee7b..d80586d7 100644 --- a/zh/13/ref/rollback.sgml +++ b/zh/13/ref/rollback.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ROLLBACK 7 - SQL - Language Statements + SQL - 语言语句 @@ -37,7 +37,7 @@ ROLLBACK [ WORK | TRANSACTION ] [ AND [ NO ] CHAIN ] 参数 - chained transactions + 链式事务 @@ -55,7 +55,7 @@ ROLLBACK [ WORK | TRANSACTION ] [ AND [ NO ] CHAIN ] AND CHAIN - 如果指定了AND CHAIN,则会立即启动一个新的(未中止的)事务, + 如果指定了AND CHAIN,则会立即启动一个新事务, 其事务特征与刚刚结束的事务相同(参见)。 否则,不会启动任何新事务。 diff --git a/zh/13/ref/rollback_prepared.sgml b/zh/13/ref/rollback_prepared.sgml index 7ffe1af8..7438d9cc 100644 --- a/zh/13/ref/rollback_prepared.sgml +++ b/zh/13/ref/rollback_prepared.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ROLLBACK PREPARED 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/rollback_to.sgml b/zh/13/ref/rollback_to.sgml index 0242c50b..33d84c77 100644 --- a/zh/13/ref/rollback_to.sgml +++ b/zh/13/ref/rollback_to.sgml @@ -10,13 +10,13 @@ PostgreSQL documentation 保存点 - rolling back + 回滚 ROLLBACK TO SAVEPOINT 7 - SQL - Language Statements + SQL - 语言语句 @@ -34,8 +34,7 @@ ROLLBACK [ WORK | TRANSACTION ] TO [ SAVEPOINT ] savepoint_name描述 - 回滚该保存点建立后执行的所有命令,然后在同一事务层级启动一个新的 - 子事务。该保存点仍然有效,如有需要,之后还可以再次回滚到它。 + 回滚该保存点建立后执行的所有命令。该保存点仍然有效,如有需要,之后还可以再次回滚到它。 diff --git a/zh/13/ref/savepoint.sgml b/zh/13/ref/savepoint.sgml index 99f5a6bc..6b92b9a4 100644 --- a/zh/13/ref/savepoint.sgml +++ b/zh/13/ref/savepoint.sgml @@ -10,13 +10,13 @@ PostgreSQL documentation 保存点 - defining + 定义 SAVEPOINT 7 - SQL - Language Statements + SQL - 语言语句 @@ -102,7 +102,9 @@ COMMIT; 上述事务将同时插入 3 和 4。 - 使用同一个保存点名称: + + 要重复使用同一个保存点名称: + BEGIN; INSERT INTO table1 VALUES (1); SAVEPOINT my_savepoint; @@ -110,18 +112,20 @@ BEGIN; SAVEPOINT my_savepoint; INSERT INTO table1 VALUES (3); - -- rollback to the second savepoint + -- 回滚到第二个保存点 ROLLBACK TO SAVEPOINT my_savepoint; - SELECT * FROM table1; -- shows rows 1 and 2 + SELECT * FROM table1; -- 显示值为 1 和 2 的行 - -- release the second savepoint + -- 释放第二个保存点 RELEASE SAVEPOINT my_savepoint; - -- rollback to the first savepoint + -- 回滚到第一个保存点 ROLLBACK TO SAVEPOINT my_savepoint; - SELECT * FROM table1; -- shows only row 1 + SELECT * FROM table1; -- 仅显示值为 1 的行 COMMIT; -上面的事务展示了先回滚行 3,再回滚行 2。 + + 上述事务展示了先回滚值为 3 的行,再回滚值为 2 的行。 + diff --git a/zh/13/ref/security_label.sgml b/zh/13/ref/security_label.sgml index 2280bc3e..14db7ee1 100644 --- a/zh/13/ref/security_label.sgml +++ b/zh/13/ref/security_label.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SECURITY LABEL 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/select.sgml b/zh/13/ref/select.sgml index 8eaa9580..352cff37 100644 --- a/zh/13/ref/select.sgml +++ b/zh/13/ref/select.sgml @@ -20,7 +20,7 @@ PostgreSQL documentation SELECT 7 - SQL - Language Statements + SQL - 语言语句 @@ -1387,7 +1387,7 @@ SELECT * FROM (SELECT * FROM mytable FOR UPDATE) ss ORDER BY column1; REPEATABLE READSERIALIZABLE事务隔离级别下, - 这将导致序列化失败(带有SQLSTATE'40001'), + 这将导致串行化失败(SQLSTATE'40001'), 因此在这些隔离级别下不可能接收到无序的行。 diff --git a/zh/13/ref/select_into.sgml b/zh/13/ref/select_into.sgml index 48d78aac..992a1d81 100644 --- a/zh/13/ref/select_into.sgml +++ b/zh/13/ref/select_into.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SELECT INTO 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/set.sgml b/zh/13/ref/set.sgml index ffb4381c..6b7e6b06 100644 --- a/zh/13/ref/set.sgml +++ b/zh/13/ref/set.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SET 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/set_constraints.sgml b/zh/13/ref/set_constraints.sgml index 53d0c7a0..e5588db7 100644 --- a/zh/13/ref/set_constraints.sgml +++ b/zh/13/ref/set_constraints.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SET CONSTRAINTS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/set_role.sgml b/zh/13/ref/set_role.sgml index e53e261b..7e768998 100644 --- a/zh/13/ref/set_role.sgml +++ b/zh/13/ref/set_role.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SET ROLE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/set_session_auth.sgml b/zh/13/ref/set_session_auth.sgml index 3fb9b989..99525834 100644 --- a/zh/13/ref/set_session_auth.sgml +++ b/zh/13/ref/set_session_auth.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SET SESSION AUTHORIZATION 7 - SQL - Language Statements + SQL - 语言语句 @@ -46,7 +46,7 @@ RESET SESSION AUTHORIZATION - 只有当初始会话用户(即已认证用户)具有超级用户权限时, + 只有当初始会话用户(即已认证用户)最初具有超级用户权限时, 才能更改会话用户标识符。否则,只有当该命令指定的是已认证用户名时, 才会被接受。 diff --git a/zh/13/ref/set_transaction.sgml b/zh/13/ref/set_transaction.sgml index 65c10806..5355df65 100644 --- a/zh/13/ref/set_transaction.sgml +++ b/zh/13/ref/set_transaction.sgml @@ -26,7 +26,7 @@ PostgreSQL documentation SET TRANSACTION 7 - SQL - Language Statements + SQL - 语言语句 @@ -66,7 +66,7 @@ SET SESSION CHARACTERISTICS AS TRANSACTION transa - 一个事务的隔离级别决定当其他事务并行运行时该事务能看见什么数据: + 一个事务的隔离级别决定当其他事务并发运行时该事务能看见什么数据: @@ -137,7 +137,7 @@ SET SESSION CHARACTERISTICS AS TRANSACTION transa 事务属性才会生效。当为一个事务同时选择这三个属性时,该事务在 首次获取其快照时可能会阻塞;在此之后,它便可以运行,而无需承担普通 SERIALIZABLE事务的常规开销,也不会有促成 - 序列化失败或因序列化失败而被取消的风险。这种模式非常适合长时间运行的 + 串行化失败或因串行化失败而被取消的风险。这种模式非常适合长时间运行的 报表或备份。 diff --git a/zh/13/ref/show.sgml b/zh/13/ref/show.sgml index 171fd4cb..6559643b 100644 --- a/zh/13/ref/show.sgml +++ b/zh/13/ref/show.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SHOW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/start_transaction.sgml b/zh/13/ref/start_transaction.sgml index e78db715..d85eee63 100644 --- a/zh/13/ref/start_transaction.sgml +++ b/zh/13/ref/start_transaction.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation START TRANSACTION 7 - SQL - Language Statements + SQL - 语言语句 @@ -64,15 +64,16 @@ START TRANSACTION [ transaction_mode - DEFERRABLE 这一 - transaction_mode 是 - PostgreSQL语言扩展。 + DEFERRABLE + transaction_mode + 是PostgreSQL的一种语言扩展。 SQL 标准要求在连续的transaction_modes之间有逗号, - 但出于历史原因PostgreSQL允许省略逗号。 + 但出于历史原因, + PostgreSQL允许省略逗号。 diff --git a/zh/13/ref/truncate.sgml b/zh/13/ref/truncate.sgml index 476f5b6d..ec7894af 100644 --- a/zh/13/ref/truncate.sgml +++ b/zh/13/ref/truncate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation TRUNCATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/unlisten.sgml b/zh/13/ref/unlisten.sgml index fde4a5dd..505b888b 100644 --- a/zh/13/ref/unlisten.sgml +++ b/zh/13/ref/unlisten.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation UNLISTEN 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/update.sgml b/zh/13/ref/update.sgml index c876a210..1e1d41aa 100644 --- a/zh/13/ref/update.sgml +++ b/zh/13/ref/update.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation UPDATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/ref/vacuum.sgml b/zh/13/ref/vacuum.sgml index cbed321a..c6179dfc 100644 --- a/zh/13/ref/vacuum.sgml +++ b/zh/13/ref/vacuum.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation VACUUM 7 - SQL - Language Statements + SQL - 语言语句 @@ -71,7 +71,7 @@ VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ ANALYZE ] [ VACUUM会显著增加 I/O 流量,这可能导致其他活动会话性能变差。 - 因此,有时建议使用基于代价的清理延迟特性。对于并行清理,每个工作者的睡眠时长 - 都与该工作者完成的工作量成比例。详见。 + 因此,有时建议使用基于代价的清理延迟特性。对于并行清理,每个工作进程的睡眠时长 + 都与该工作进程完成的工作量成比例。详见 PostgreSQL提供了一个自动清理(autovacuum)机制,可以自动执行常规清理维护。有关自动与手动清理的更多信息,参见 @@ -281,7 +281,7 @@ VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ ANALYZE ] [ mxid_age - 仅对 multixact ID 年龄至少为 mxid_age - 的表执行清理或分析命令。此设置可用于优先处理表,以防止 multixact ID 回卷 + 仅对 多事务 ID 年龄至少为 mxid_age + 的表执行清理或分析命令。此设置可用于优先处理表,以防止 多事务 ID 回卷 (见 )。 - 就此选项而言,一个关系的 multixact ID 年龄,是其主关系及其关联的 + 就此选项而言,一个关系的 多事务 ID 年龄,是其主关系及其关联的 TOAST 表(如果存在)年龄中的较大者。由于 vacuumdb 发出的命令在必要时也会处理该关系的 TOAST 表,因此无需单独考虑它。 @@ -226,7 +226,7 @@ PostgreSQL documentation - 如果有,跳过与待清理表关联的 TOAST 表。 + 跳过那些无法立即加锁并进行处理的关系。 此选项仅适用于运行PostgreSQL 12 及更高版本的服务器。 @@ -293,11 +293,9 @@ PostgreSQL documentation 仅计算供优化器使用的统计信息(不执行清理),类似。使用不同的配置设置运行多个(目前为三个)分析阶段,以便更快地生成可用统计信息。 - 此选项仅在分析当前没有统计信息,或现有统计信息完全错误的数据库时才有用,例如数据库是 - 从恢复出的转储中重新填充,或是通过 pg_upgrade 新建得到的。 - 注意,在已有统计信息的数据库上使用此选项,可能会因为早期阶段采用较低统计目标, - 导致查询优化器的选择暂时变差。 - + 此选项适合分析刚通过恢复转储或pg_upgrade填充的数据库。 + 它会尽快尝试生成一些统计信息,让数据库能够使用,然后在后续阶段生成完整统计信息。 + @@ -440,13 +438,13 @@ PostgreSQL documentation - 示例 + 注解 vacuumdb可能需要多次连接到PostgreSQL服务器,每次都要询问密码。在这种情况下,使用~/.pgpass文件会比较方便。更多信息见 - 参见 + 示例 清理数据库 test diff --git a/zh/13/ref/values.sgml b/zh/13/ref/values.sgml index b5be36e4..6fe819ae 100644 --- a/zh/13/ref/values.sgml +++ b/zh/13/ref/values.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation VALUES 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/13/reference.sgml b/zh/13/reference.sgml index a46c5660..4b83e497 100644 --- a/zh/13/reference.sgml +++ b/zh/13/reference.sgml @@ -269,6 +269,7 @@ &pgupgrade; &pgwaldump; &postgres; + &postmaster; diff --git a/zh/13/release-13.sgml b/zh/13/release-13.sgml index 9b9b1f90..d75bbfa8 100644 --- a/zh/13/release-13.sgml +++ b/zh/13/release-13.sgml @@ -2595,7 +2595,7 @@ Branch: REL_14_STABLE [5144e1f8f] 2025-03-11 12:50:35 +0100 Branch: REL_13_STABLE [f5b4a0b49] 2025-03-11 12:50:35 +0100 --> - 检测 BRIN 索引操作符类中缺失的支持过程,并报告错误而不是崩溃 + 检测 BRIN 索引操作符类中缺失的支持函数,并报告错误而不是崩溃 (Álvaro Herrera) § @@ -3567,7 +3567,7 @@ Branch: REL_14_STABLE [d9d5e1b48] 2024-12-07 14:28:16 -0500 Branch: REL_13_STABLE [531cbd8b7] 2024-12-07 14:28:16 -0500 --> - 修复操作符族成员操作符或支持过程可能成为悬空引用的情况 + 修复操作符族成员操作符或支持函数可能成为悬空引用的情况 (Tom Lane) § § @@ -5934,17 +5934,17 @@ Branch: REL_13_STABLE [e9c8747ee] 2024-06-27 21:08:55 +0300 Branch: REL_12_STABLE [5dea6628b] 2024-06-27 21:09:15 +0300 --> - 修复启动热备服务器时对已准备事务的子事务的处理 + 修复启动热备服务器时对预备事务的子事务的处理 (Heikki Linnakangas) § 当备库的重放从关闭检查点 WAL 记录开始时, - 主库上已准备但尚未提交的事务会被正确理解为仍在进行中。 - 但已准备事务的子事务(由保存点或 + 主库上已预备但尚未提交的事务会被正确理解为仍在进行中。 + 但预备事务的子事务(由保存点或 PL/pgSQL 异常块创建)没有被考虑在内, - 会被视为已中止。如果该已准备事务后来被提交,这会导致不一致。 + 会被视为已中止。如果该预备事务后来被提交,这会导致不一致。 @@ -9551,8 +9551,8 @@ Branch: REL_11_STABLE [0048c3b51] 2023-07-04 09:27:00 +1200 - 使用位图堆扫描、使用 GIN 索引以及检查初始为空的 B-树 索引时可能会遗漏冲突。 - 所有这些情况都可能因不当允许冲突事务提交而导致可序列化失败。 + 使用位图堆扫描、使用 GIN 索引以及检查初始为空的 B-树索引时可能会遗漏冲突。 + 所有这些情况都可能因不当允许相互冲突的事务提交而破坏可串行性。 @@ -17341,7 +17341,7 @@ Branch: REL_14_STABLE [6cac34339] 2021-10-27 13:09:01 -0700 Branch: REL_13_STABLE [d5a2ffbce] 2021-10-27 13:09:00 -0700 --> - 增加更多围绕 B-树 posting list 分裂的防御性检查(Peter Geoghegan) + 增加更多围绕 B-树倒排列表分裂的防御性检查(Peter Geoghegan) § § @@ -21291,7 +21291,7 @@ Branch: REL_12_STABLE [ea9087938] 2020-11-04 12:46:52 +0100 --> 支持对文本数组进行哈希计算(Peter Eisentraut) § - 如果数组元素类型支持排序规则,数组哈希就会失败。尤其是,这使文本数组列无法用作哈希分区的分区键。 + 如果数组元素类型支持排序规则,对数组进行 hash 计算就会失败。尤其是,这使文本数组列无法用作 hash 分区的分区键。 diff --git a/zh/13/runtime.sgml b/zh/13/runtime.sgml index 63b8be6d..aea94e8c 100644 --- a/zh/13/runtime.sgml +++ b/zh/13/runtime.sgml @@ -16,7 +16,7 @@ <productname>PostgreSQL</productname>用户账户 - postgres user + postgres 用户 @@ -45,7 +45,7 @@ - 在做任何事情之前,必须先在磁盘上初始化一个数据库存储区域。我们把它称为数据库集簇。(SQL 标准使用术语 catalog cluster。)数据库集簇是由一个正在运行的数据库服务器实例管理的一组数据库。初始化之后,数据库集簇中会包含一个名为postgres的数据库,作为供工具、用户和第三方应用使用的默认数据库。数据库服务器本身并不要求该postgres数据库存在,但许多外部工具程序都假定它存在。初始化期间,集簇中还会创建另一个数据库,名为template1。顾名思义,它会作为后续新建数据库的模板;不应将它用于实际工作。(关于在集簇中创建新数据库的信息,见。) + 在做任何事情之前,必须先在磁盘上初始化一个数据库存储区域。我们把它称为数据库集簇。(SQL 标准使用术语目录集簇(catalog cluster)。)数据库集簇是由一个正在运行的数据库服务器实例管理的一组数据库。初始化之后,数据库集簇中会包含一个名为postgres的数据库,作为供工具、用户和第三方应用使用的默认数据库。数据库服务器本身并不要求该postgres数据库存在,但许多外部工具程序都假定它存在。初始化期间,集簇中还会创建另一个数据库,名为template1。顾名思义,它会作为后续新建数据库的模板;不应将它用于实际工作。(关于在集簇中创建新数据库的信息,见。) @@ -56,9 +56,13 @@ 如果你使用的是预打包的 PostgreSQL,它很可能对数据目录的位置有固定约定,并且还可能提供创建数据目录的脚本。在这种情况下,应优先使用该脚本,而不是直接运行 initdb。详细信息请查阅该软件包级别的文档。 - 要手动初始化数据库集簇,请运行 initdb,并将数据库集簇在文件系统中的目标位置通过 选项指定,例如: + + 要手工初始化数据库集簇,请运行 initdb,并用 选项指定数据库集簇所在的文件系统位置,例如: + $ initdb -D /usr/local/pgsql/data -注意,必须先登录 PostgreSQL 用户账户,再执行此命令。该账户已在上一节介绍。 + + 请注意,执行该命令时必须已登录到上一节所述的 PostgreSQL 用户账户。 + @@ -146,7 +150,7 @@ postgres$ initdb -D /usr/local/pgsql/data 对于在PostgreSQL中使用NFS,唯一硬性要求是文件系统必须使用hard选项挂载。使用hard选项时,如果出现网络问题,进程可能会无限期地挂起,因此这种配置需要配套谨慎的监控措施。soft选项会在网络问题出现时中断系统调用,但PostgreSQL不会重试以这种方式被中断的系统调用,因此任何此类中断都会导致报告 I/O 错误。 - 没有必要使用 sync 挂载选项。async 选项的行为已经足够,因为 PostgreSQL 会在适当的时候发出 fsync 调用来刷新写缓存。(这和它在本地文件系统上的工作方式类似。)但是,强烈建议在支持该选项的 NFS 服务器端系统上使用 sync 导出选项(主要是 Linux)。否则,NFS 客户端上的 fsync 或等效操作实际上并不能保证数据到达服务器上的持久存储,这可能导致类似于将参数 设为关闭时那样的损坏。这些挂载和导出选项的默认值在不同厂商和版本间并不相同,因此无论如何都建议检查它们,并且最好显式指定,以避免歧义。 + 没有必要使用 sync 挂载选项。async 选项的行为已经足够,因为 PostgreSQL 会在适当的时候发出 fsync 调用将写缓存刷盘。(这和它在本地文件系统上的工作方式类似。)但是,强烈建议在支持该选项的 NFS 服务器端系统上使用 sync 导出选项(主要是 Linux)。否则,NFS 客户端上的 fsync 或等效操作实际上并不能保证数据到达服务器上的持久存储,这可能导致类似于将参数 设为关闭时那样的损坏。这些挂载和导出选项的默认值在不同厂商和版本间并不相同,因此无论如何都建议检查它们,并且最好显式指定,以避免歧义。 在某些情况下,可以通过 NFS 或更底层的协议(例如 iSCSI)访问外部存储产品。在后一种情况下,存储会表现为块设备,可以在其上创建任意可用的文件系统。这种方式或许能让 DBA 不必应对 NFS 的某些特性,但当然,管理远程存储的复杂性会转移到其他层面。 @@ -167,9 +171,13 @@ postgres$ initdb -D /usr/local/pgsql/data 如果你使用的是预打包的 PostgreSQL,它几乎肯定已经按你的操作系统惯例提供了将服务器作为后台任务运行的机制。使用软件包自带的机制来启动服务器,比自己摸索如何操作要省事得多。详细信息请查阅该软件包级别的文档。 - 手动启动服务器最基本的方法,是直接调用 postgres,并将数据目录位置通过 选项指定,例如: + + 手工启动服务器的最基本方法是直接调用 postgres,并用 选项指定数据目录的位置,例如: + $ postgres -D /usr/local/pgsql/data -这会让服务器在前台运行。必须先登录 PostgreSQL 用户账户再执行此操作。如果不使用 ,服务器会尝试使用环境变量所指定的数据目录,该变量为 PGDATA。如果也未提供该变量,则会失败。 + + 这样服务器会在前台运行。执行这一步时也必须已登录到 PostgreSQL 用户账户。如果不使用 选项,服务器会尝试使用环境变量 PGDATA 指定的数据目录;如果该变量也未设置,启动就会失败。 + 通常最好在后台启动postgres。做法是使用常见的 Unix shell 语法: @@ -192,7 +200,7 @@ pg_ctl start -l logfile - 通常,你会希望在计算机启动时就启动数据库服务器。booting启动服务器时自动启动脚本依赖于操作系统。PostgreSQLcontrib/start-scripts 目录中附带了一些示例脚本。安装这些脚本需要 root 权限。 + 通常,你会希望在计算机启动时就启动数据库服务器。引导期间启动服务器自动启动脚本依赖于操作系统。PostgreSQLcontrib/start-scripts 目录中附带了一些示例脚本。安装这些脚本需要 root 权限。 @@ -209,14 +217,14 @@ su postgres -c 'pg_ctl start -D /usr/local/pgsql/data -l serverlog' 对于FreeBSD,请查看PostgreSQL源码发布包中的contrib/start-scripts/freebsd文件。 - FreeBSDstart script + FreeBSD启动脚本 OpenBSD上,把以下内容加入/etc/rc.local: - OpenBSDstart script + OpenBSD启动脚本 if [ -x /usr/local/pgsql/bin/pg_ctl -a -x /usr/local/pgsql/bin/postgres ]; then su -l postgres -c '/usr/local/pgsql/bin/pg_ctl start -s -l /var/postgresql/log -D /usr/local/pgsql/data' @@ -229,7 +237,7 @@ fi Linux系统上,可以把 - Linuxstart script + Linux启动脚本 /usr/local/pgsql/bin/pg_ctl start -l logfile -D /usr/local/pgsql/data @@ -268,14 +276,14 @@ WantedBy=multi-user.target NetBSD上,可根据偏好使用FreeBSDLinux的启动脚本。 - NetBSDstart script + NetBSD启动脚本 Solaris上,创建一个名为/etc/init.d/postgresql的文件,其中包含以下内容: - Solarisstart script + Solaris启动脚本 su - postgres -c "/usr/local/pgsql/bin/pg_ctl start -l logfile -D /usr/local/pgsql/data" @@ -312,10 +320,14 @@ FATAL: could not create any TCP/IP sockets - 像下面这样的消息: + + 像下面这样的消息: + FATAL: could not create shared memory segment: Invalid argument DETAIL: Failed system call was shmget(key=5440001, size=4011376640, 03600). -可能表示内核对共享内存大小的限制小于 PostgreSQL 尝试创建的工作区(本例中为 4011376640 字节)。这种情况通常只会在你将 shared_memory_type 设为 sysv 时发生。此时,可以尝试以少于通常数量的缓冲区启动服务器(),或者重新配置内核,增大允许的共享内存大小。如果尝试在同一台机器上启动多个服务器,而它们请求的总空间超出内核限制,也可能看到这条消息。 + + 很可能表示你的内核对共享内存段大小的限制,小于PostgreSQL试图创建的工作区大小(本例中是 4011376640 字节)。这种情况通常只会在你将 shared_memory_type 设为 sysv 时发生。在这种情况下,可以尝试用比平常更少的缓冲区()启动服务器,或者重新配置内核以增大允许的共享内存大小。如果你试图在同一台机器上启动多个服务器,而它们请求的总空间超过了内核限制,也可能看到这条消息。 + 像下面这样的错误: @@ -360,7 +372,7 @@ psql: could not connect to server: No such file or directory 管理内核资源 - PostgreSQL有时会耗尽操作系统的各种资源限制,尤其是在同一系统上运行多个服务器副本,或在非常大型的安装环境中时更是如此。本节解释PostgreSQL使用的内核资源,以及你可以采取哪些步骤来解决与内核资源消耗相关的问题。 + PostgreSQL有时会达到操作系统的各种资源上限,尤其是在同一系统上运行多个服务器实例,或在非常大型的安装环境中时更是如此。本节解释PostgreSQL使用的内核资源,以及你可以采取哪些步骤来解决与内核资源消耗相关的问题。 @@ -383,7 +395,7 @@ psql: could not connect to server: No such file or directory - System V IPC 功能通常受系统范围的分配限制约束。当PostgreSQL超出这些限制之一时,服务器会拒绝启动,并留下带有指导性的错误消息,说明问题所在以及应如何处理(另见)。相关内核参数在不同系统上的命名基本一致,给出了概览;不过,设置它们的方法却各不相同。下面给出一些平台上的建议。 + System V IPC 功能通常受系统范围的分配限制约束。当PostgreSQL超出这些限制之一时,服务器会拒绝启动,并应留下带有指导性的错误消息,说明问题所在以及应如何处理(另见)。相关内核参数在不同系统上的命名基本一致,给出了概览;不过,设置它们的方法却各不相同。下面给出一些平台上的建议。
@@ -406,7 +418,7 @@ psql: could not connect to server: No such file or directory SHMMAX 共享内存段的最大尺寸(字节) - 至少 1kB,但是默认值通常要高一些 + 至少 1kB,但是默认值通常高得多 @@ -469,8 +481,8 @@ psql: could not connect to server: No such file or directory
- PostgreSQL要求少量字节的 System V 共享内存(在 64 位平台上通常是 48 字节)用于每一个服务器拷贝。在大多数现代操作系统上,这个量很容易得到。 - 但是,如果你运行了很多个服务器副本,或者显式配置服务器以使用大量 System V 共享内存(参见 ), + PostgreSQL要求少量字节的 System V 共享内存(在 64 位平台上通常是 48 字节)用于每一个服务器实例。在大多数现代操作系统上,这个量很容易得到。 + 但是,如果你运行了很多个服务器实例,或者显式配置服务器以使用大量 System V 共享内存(参见 ), 可能需要增加SHMALL(系统范围内 System V 共享内存的总量)。注意在很多系统上SHMALL是以页面而不是字节来度量。 @@ -485,11 +497,11 @@ psql: could not connect to server: No such file or directory
- 与semaphore undo有关的其他各种设置,如SEMMNUSEMUME,不会影响PostgreSQL。 + 与信号量撤销有关的其他各种设置,如SEMMNUSEMUME,不会影响PostgreSQL - 当使用 POSIX 信号量时,所需数量与 System V 相同,即每个允许连接()、每个允许自动清理工作进程()、每个允许 WAL 发送进程()、每个允许后台进程()等各需一个。在优先使用该实现的平台上,POSIX 信号量数量没有特定内核上限。 + 当使用 POSIX 信号量时,所需数量与 System V 相同,即每个允许连接()、每个允许自动清理工作进程()、每个允许 WAL 发送进程()、每个允许后台进程()各需一个。在优先使用该实现的平台上,POSIX 信号量数量没有特定内核上限。 @@ -499,7 +511,9 @@ psql: could not connect to server: No such file or directory AIXIPC 配置 - 应该不需要对 SHMMAX 等参数进行任何特殊配置,因为它似乎已配置为允许将全部内存用作共享内存。这也是 DB/2 等其他数据库常用的配置。 + + 对于 SHMMAX 之类的参数,通常不需要任何特殊配置,因为看起来系统已经配置为允许将所有内存都用作共享内存。这类配置也常用于其他数据库,例如 DB/2。 + 不过,可能需要修改 /etc/security/limits 中的全局 ulimit 信息,因为文件大小(fsize)和文件数量(nofiles)的默认硬限制可能过低。 @@ -515,11 +529,13 @@ psql: could not connect to server: No such file or directory 默认共享内存设置通常就足够了,除非你已将 shared_memory_type 设置为 sysv。此平台不使用 System V 信号量。 - 要更改默认 IPC 设置,可以使用 sysctlloader 接口。可以通过 sysctl 设置以下参数: + + 可以使用sysctlloader接口更改默认 IPC 配置。下列参数可用sysctl设置: # sysctl kern.ipc.shmall=32768 # sysctl kern.ipc.shmmax=134217728 -要让这些设置在重启后仍然生效,请修改 /etc/sysctl.conf。 + + 要让这些设置在重启之后也保持,请修改/etc/sysctl.conf @@ -540,9 +556,12 @@ psql: could not connect to server: No such file or directory 默认共享内存设置通常就足够了,除非你已将 shared_memory_type 设置为 sysv。通常需要增大 kern.ipc.semmnikern.ipc.semmns,因为 NetBSD 对这两项的默认设置小得不便使用。 - 可以使用以下命令调整 IPC 参数:sysctl。例如: + + 可以使用 sysctl 调整 IPC 参数,例如: + # sysctl -w kern.ipc.semmni=100 -要让这些设置在重启后仍然生效,请修改 /etc/sysctl.conf。 + + 要使这些设置在重新启动后保持不变,请修改 /etc/sysctl.conf @@ -558,9 +577,12 @@ psql: could not connect to server: No such file or directory 默认共享内存设置通常已经足够,除非你将 shared_memory_type 设为 sysv。通常需要增大 kern.seminfo.semmnikern.seminfo.semmns,因为 OpenBSD 对这两项的默认设置小得令人担忧。 - 可以使用以下命令调整 IPC 参数:sysctl。例如: + + 可以使用 sysctl 调整 IPC 参数,例如: + # sysctl kern.seminfo.semmni=100 -要让这些设置在重启后仍然生效,请修改 /etc/sysctl.conf。 + + 要使这些设置在重新启动后保持不变,请修改 /etc/sysctl.conf @@ -584,10 +606,13 @@ psql: could not connect to server: No such file or directory 默认共享内存设置通常已经足够,除非你将 shared_memory_type 设为 sysv;即便如此,也通常只会在默认值较低的旧内核版本上遇到问题。此平台不使用 System V 信号量。 - 可以通过以下接口更改共享内存大小设置:sysctl。例如,要允许 16 GB: + + 共享内存大小设置可以通过sysctl接口更改。例如,允许 16 GB: + $ sysctl -w kernel.shmmax=17179869184 $ sysctl -w kernel.shmall=4194304 -要让这些设置在重启后仍然生效,请参见 /etc/sysctl.conf。 + + 要使这些设置在重新启动时保持不变,请参见/etc/sysctl.conf @@ -631,7 +656,8 @@ kern.sysv.shmall=1024 Solaris illumos - 默认共享内存和信号量设置通常足以满足大多数 PostgreSQL 应用的需求。Solaris 默认将 SHMMAX 设为系统 RAM 的四分之一。要进一步调整此设置,请使用与以下用户关联的项目设置:postgres。例如,执行以下命令时使用的用户为 root: + + 默认的共享内存和信号量设置对于大多数 PostgreSQL 应用通常已经足够。Solaris 将SHMMAX的默认值设为系统 RAM 的四分之一。要进一步调整这一设置,可使用与postgres用户关联的项目设置。例如,以root运行下列命令: projadd -c "PostgreSQL DB User" -K "project.max-shm-memory=(privileged,8GB,deny)" -U postgres -G postgres user.postgres @@ -650,7 +676,9 @@ project.max-msg-ids=(priv,4096,deny) - 此外,如果你正在某个区(zone)中运行 PostgreSQL,可能也需要提高该区的资源使用限制。关于 projectsprctl 的更多信息,请参见 System Administrator's Guide 中的“Chapter2: Projects and Tasks”。 + + 此外,如果你正在某个区(zone)中运行PostgreSQL,可能也需要提高该区的资源使用限制。关于projectsprctl的更多信息,请参见System Administrator's Guide中的 "Chapter 2: Projects and Tasks"。 + @@ -684,7 +712,7 @@ WARNING: could not remove shared memory segment "/PostgreSQL.1450751626": No su - 用户注销可能会作为维护作业的一部分发生,也可能在管理员以postgres用户或类似名称登录时手工触发,因此通常很难彻底防止。 + 用户注销可能会作为维护作业的一部分发生,也可能在管理员以postgres用户登录或执行类似操作时手工触发,因此通常很难彻底防止。 @@ -755,7 +783,7 @@ default:\ - 另一个在支持大量客户端连接时可能需要关注的内核限制,是套接字连接队列的最大长度。如果在很短时间内到达的连接请求超过了这个数量,那么其中一些请求可能会在主管服务器进程来得及处理之前就被拒绝,于是客户端会收到不太有帮助的连接失败错误,例如Resource temporarily unavailableConnection refused。在许多平台上,默认队列长度限制是 128。要提高它,请通过sysctl调整相应的内核参数,然后重新启动主管服务器进程。该参数在不同系统上的名称不同:在 Linux 上是net.core.somaxconn,在较新的 FreeBSD 上是kern.ipc.soacceptqueue,在 macOS 和其他 BSD 变体上是kern.ipc.somaxconn。 + 另一个在支持大量客户端连接时可能需要关注的内核限制,是套接字连接队列的最大长度。如果在很短时间内到达的连接请求超过了这个数量,那么其中一些请求可能会在postmaster来得及处理之前就被拒绝,于是客户端会收到不太有帮助的连接失败错误,例如Resource temporarily unavailableConnection refused。在许多平台上,默认队列长度限制是 128。要提高它,请通过sysctl调整相应的内核参数,然后重新启动postmaster。该参数在不同系统上的名称不同:在 Linux 上是net.core.somaxconn,在较新的 FreeBSD 上是kern.ipc.soacceptqueue,在 macOS 和其他 BSD 变体上是kern.ipc.somaxconn @@ -763,7 +791,7 @@ default:\ Linux 内存过量分配 - memory overcommit + 内存过量分配 @@ -771,7 +799,7 @@ default:\ - overcommit + 过量分配 Linux 上默认的虚拟内存行为对 PostgreSQL 并非最佳。由于内核实现内存过量分配的方式,如果 PostgreSQL 或其他进程的内存需求导致系统耗尽虚拟内存,内核可能会终止 PostgreSQL 的 postmaster(主管服务器进程)。 @@ -789,22 +817,37 @@ Out of Memory: Killed process 12345 (postgres). - 如果导致系统耗尽内存的正是PostgreSQL自身,那么你可以通过调整配置来避免该问题。在某些情况下,调低与内存相关的配置参数会有帮助,尤其是shared_bufferswork_memhash_mem_multiplier。在其他情况下,允许数据库服务器接受过多连接也可能导致这一问题。很多时候,更好的做法是减小max_connections,并转而使用外部连接池软件。 + 如果导致系统耗尽内存的正是PostgreSQL自身,那么你可以通过调整配置来避免该问题。在某些情况下,调低与内存相关的配置参数会有帮助,尤其是shared_bufferswork_memhash_mem_multiplier。在其他情况下,允许数据库服务器接受过多连接也可能导致这一问题。很多时候,更好的做法可能是减小max_connections,并转而使用外部连接池软件。 - 可以修改内核的行为,使其不会过量分配内存。虽然此设置无法完全阻止 OOM 杀手 被调用,但会显著降低发生概率,从而使系统行为更健壮。方法是通过 sysctl 选择严格的过量分配模式: + + 还可以修改内核行为,使其不再过量分配内存。尽管这种设置无法彻底阻止OOM 杀手被触发,但能显著降低其发生概率,从而得到更稳健的系统行为。这可以通过使用sysctl选择严格的过量分配模式来实现: sysctl -w vm.overcommit_memory=2 -或者在以下文件中加入等效条目:/etc/sysctl.conf。你可能还希望修改相关设置 vm.overcommit_ratio。详细信息参见内核文档文件 。 + + 或者在/etc/sysctl.conf中加入等效设置。你可能还希望修改相关设置vm.overcommit_ratio。详细信息请参阅内核文档中的文件。 - 另一种方法不要求改变 vm.overcommit_memory,但也可与该设置的修改结合使用:将 postmaster 进程特有的OOM score adjustment值设为 -1000,从而保证它不会成为 OOM 杀手 的目标。最简单的方法是执行: + + 另一种方法可在修改或不修改 vm.overcommit_memory 的情况下使用: + 把 postmaster 进程专属的OOM 评分调整值设为 -1000, + 从而保证它不会成为 OOM 杀手的目标。最简单的做法是在 postmaster + 启动脚本中、调用 postmaster 之前执行: + echo -1000 > /proc/self/oom_score_adj -执行位置是在 postmaster 的启动脚本中,紧接在调用 postmaster 之前。注意,必须以 root 身份执行此操作,否则不会生效;因此,在 root 所有的启动脚本中执行最方便。如果这样做,还应在启动脚本中调用 postmaster 之前设置以下环境变量: + + 请注意,这个操作必须以 root 身份完成,否则不会生效;因此,由 root 拥有的启动脚本是最容易执行该操作的位置。 + 如果这样做,还应在调用 postmaster 之前,在启动脚本中设置以下环境变量: + export PG_OOM_ADJUST_FILE=/proc/self/oom_score_adj export PG_OOM_ADJUST_VALUE=0 -这些设置会使 postmaster 子进程以正常的 OOM 分数调整值零运行,因此 OOM 杀手 仍可在需要时将它们作为目标。你可以为以下变量使用其他值:PG_OOM_ADJUST_VALUE,以使子进程采用其他 OOM 分数调整值。(PG_OOM_ADJUST_VALUE 也可以省略,此时默认为零。)如果不设置 PG_OOM_ADJUST_FILE,子进程将使用与 postmaster 相同的 OOM 分数调整值,这并不明智,因为这样设置的目的就是确保 postmaster 获得优先保护。 + + 这些设置会使 postmaster 子进程以常规的 OOM 评分调整值零运行,以便 OOM 杀手在需要时仍可将它们作为目标。 + 如果希望子进程以其他 OOM 评分调整值运行,也可以为 PG_OOM_ADJUST_VALUE 指定其他值。 + (也可以省略 PG_OOM_ADJUST_VALUE,此时默认为零。) + 如果不设置 PG_OOM_ADJUST_FILE,子进程就会和 postmaster 使用相同的 OOM 评分调整值, + 这并不明智,因为这样做的目的正是确保 postmaster 获得优先保护。 + @@ -829,8 +872,9 @@ $ grep Huge /proc/meminfo - 你可能还需要授予数据库服务器的操作系统用户使用大页的权限,例如通过sysctl设置vm.hugetlb_shm_group,以及/或者授予其使用ulimit -l锁定内存的权限。 - + 可能还需要通过 sysctl 设置 vm.hugetlb_shm_group, + 授予数据库服务器的操作系统用户使用大页的权限,以及/或者通过 ulimit -l 授予其锁定内存的权限。 + PostgreSQL 对大页的默认行为是:只要可能就使用它们;如果失败,则回退到普通页。要强制使用大页,可以在 postgresql.conf 中将 设为 on。请注意,在这种设置下,如果没有足够的大页可用,PostgreSQL 将无法启动。 @@ -850,21 +894,24 @@ $ grep Huge /proc/meminfo - 有几种关闭数据库服务器的方法。在后台,它们都简化为向主管 postgres 进程发送信号。 + 有几种关闭数据库服务器的方法。这些方法在内部都是向主管 postgres 进程发送信号。 如果你使用的是预打包的 PostgreSQL,并且是按照其提供的机制来启动服务器的,那么停止服务器时也应采用同样的机制。详细信息请查阅该软件包级别的文档。 - 直接管理服务器时,可以通过发送不同信号来控制关闭类型,信号发给 postgres 进程: + + 当直接管理服务器时,你可以通过向postgres进程发送不同的信号来控制关闭类型: + + SIGTERMSIGTERM 这是智能关闭模式。 收到SIGTERM后,服务器禁止新连接,但允许现有会话正常结束工作。 - 仅在所有会话终止后才会关闭。如果服务器在请求智能关闭时处于恢复状态, + 仅在所有会话终止后才会关闭。如果服务器处于在线备份模式,还会等待该模式结束。在线备份模式生效期间,仍允许新的超级用户连接(这一例外允许超级用户连接以结束在线备份模式),但不允许其他新连接。如果服务器在请求智能关闭时处于恢复状态, 则只有在所有常规会话终止后,恢复和流复制才会停止。 @@ -877,7 +924,7 @@ $ grep Huge /proc/meminfo 这是快速关闭模式。 服务器禁止新连接并向所有现有服务器进程发送SIGTERM, 这将导致它们中止当前事务并迅速退出。然后等待所有服务器进程退出,最后关闭。 - + 如果服务器处于在线备份模式,该模式将被终止,导致备份不可用。 @@ -910,12 +957,12 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`升级 PostgreSQL 集簇 - upgrading + 升级 - version - compatibility + 版本 + 兼容性 @@ -935,7 +982,7 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` - 新的主版本通常还会引入一些用户可见的不兼容变化,因此应用程序可能也需要做出修改。所有用户可见的变化都列在发行说明()中;请特别留意标为Migration的小节。虽然你可以从一个主版本直接升级到另一个主版本,而不必逐个升级中间版本,但仍应阅读所有中间版本的主版本发行说明。 + 新的主版本通常还会引入一些用户可见的不兼容变化,因此应用程序可能也需要做出修改。所有用户可见的变化都列在发行说明()中;请特别留意标为迁移(Migration)的小节。虽然你可以从一个主版本直接升级到另一个主版本,而不必逐个升级中间版本,但仍应阅读所有中间版本的主版本发行说明。 @@ -994,7 +1041,7 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` - 这涉及以后端函数 API 为代表的变更,该 API 使用 C 语言编写。这类变更会影响那些深入引用服务器内部后端函数的代码。 + 这涉及使用 C 语言编写的后端函数 API 的变更。这类变更会影响那些深入引用服务器内部后端函数的代码。 @@ -1005,7 +1052,7 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`通过pg_dumpall升级数据 - 一种升级方法是从某个主版本的PostgreSQL导出数据,再在另一个版本中恢复。要这样做,必须使用逻辑备份工具,例如pg_dumpall;文件系统级备份方法不起作用。(系统中有相应检查,会阻止你在不兼容版本的PostgreSQL上使用某个数据目录,因此即便误用错误版本的服务器去启动某个数据目录,通常也不会造成太大损害。) + 一种升级方法是从某个主版本的PostgreSQL转储数据,再在另一个版本中恢复。要这样做,必须使用逻辑备份工具,例如pg_dumpall;文件系统级备份方法不起作用。(系统中有相应检查,会阻止你在不兼容版本的PostgreSQL上使用某个数据目录,因此即便误用错误版本的服务器去启动某个数据目录,通常也不会造成太大损害。) 建议使用来自较新版本 PostgreSQLpg_dumppg_dumpall 程序,以利用这些程序可能包含的改进。当前版本的转储程序可以读取从 8.0 起任意服务器版本的数据。 @@ -1018,13 +1065,13 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` - 如果是在制作备份,请确认数据库此时没有正在进行更新。这不会影响备份的一致性,但那些变更当然不会包含在备份中。必要时,可修改/usr/local/pgsql/data/pg_hba.conf中的访问权限(或采用等效方法),禁止除你之外的其他人访问数据库。有关访问控制的更多信息见。 + 如果是在制作备份,请确认数据库此时没有正在进行更新。更新操作不会影响备份的完整性,但那些变更当然不会包含在备份中。必要时,可修改/usr/local/pgsql/data/pg_hba.conf(或等效文件)中的访问权限,禁止除你之外的其他人访问数据库。有关访问控制的更多信息见 pg_dumpall - use during upgrade + 在升级期间使用 要备份整个数据库安装,请输入: @@ -1045,7 +1092,7 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` pg_ctl stop - 在那些会自动启动PostgreSQL的系统上,可能已经有某个启动脚本能完成同样的工作。例如,在Red Hat Linux系统上,也许下面这条命令就可以: + 在那些会在开机时自动启动PostgreSQL的系统上,可能已经有某个启动脚本能完成同样的工作。例如,在Red Hat Linux系统上,也许下面这条命令就可以: /etc/rc.d/init.d/postgresql stop @@ -1127,7 +1174,9 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 通过复制升级数据 - 也可以使用逻辑复制方法,创建一个运行较新版本 PostgreSQL 的备库。之所以可行,是因为逻辑复制支持不同大版本 PostgreSQL 之间进行复制。该备库可以与旧服务器部署在同一台机器上,也可以部署在不同机器上。一旦它与主库(运行旧版本 PostgreSQL)同步,就可以切换主备角色,让备库成为主库,并关闭旧的数据库实例。这种计划内切换只会为升级带来几秒钟的停机时间。 + + 也可以使用逻辑复制方法,创建一个运行较新版本PostgreSQL的备库。之所以可行,是因为逻辑复制支持不同主版本PostgreSQL之间进行复制。该备库可以与旧服务器部署在同一台机器上,也可以部署在不同机器上。一旦它与主库(运行旧版本PostgreSQL)同步,就可以切换主备角色,让备库提升为主库,并关闭旧的数据库实例。这种切换使升级只需几秒钟的停机时间。 + 这种升级方法既可以使用内置的逻辑复制功能,也可以使用外部逻辑复制系统,例如pglogicalSlonyLondisteBucardo。 @@ -1171,7 +1220,7 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 - PostgreSQL提供了多个层次的加密,并在防止数据因数据库服务器被盗、不可靠的管理员或不安全网络等原因而泄露方面提供了很高的灵活性。对于医疗记录、金融交易等敏感数据,加密也可能是合规要求的一部分。 + PostgreSQL提供了多个层次的加密,并在防止数据因数据库服务器被盗、不诚实的管理员或不安全网络等原因而泄露方面提供了很高的灵活性。为了保护医疗记录、金融交易等敏感数据,也可能需要使用加密。 @@ -1296,7 +1345,7 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 - 如果私钥受密码保护,服务器会提示输入该密码,并在输入之前不会启动。默认情况下,使用密码会禁用无需重启服务器即可更改 SSL 配置的能力,不过参见。此外,在 Windows 上完全无法使用带密码保护的私钥。 + 如果私钥受口令保护,服务器会提示输入该口令,并在输入之前不会启动。默认情况下,使用口令会禁用无需重启服务器即可更改 SSL 配置的能力,不过参见。此外,在 Windows 上完全无法使用带口令保护的私钥。 @@ -1323,7 +1372,7 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 - 使用NULL-SHANULL-MD5密码套件,可以在几乎没有加密开销的情况下完成认证。不过,中间人仍然能够读取并转发客户端与服务器之间的通信。此外,与认证的开销相比,加密开销本身通常很小。基于这些原因,不建议使用 NULL 密码套件。 + 使用NULL-SHANULL-MD5密码套件,可以在没有加密开销的情况下完成认证。不过,中间人仍然能够读取并转发客户端与服务器之间的通信。此外,与认证的开销相比,加密开销本身很小。基于这些原因,不建议使用 NULL 密码套件。 @@ -1578,17 +1627,19 @@ ssh -L 63333:db.foo.com:5432 joe@shell.foo.com - 在 <systemitem class="osname">Windows</systemitem> 上注册 <application>Event Log</application> + 在<systemitem class="osname">Windows</systemitem>上注册<application>事件日志</application> 事件日志 事件日志 - 要向操作系统注册 Windows - event log 库,请执行以下命令: + + 要向操作系统注册一个Windows事件日志库,请执行以下命令: + regsvr32 pgsql_library_directory/pgevent.dll -这会创建事件查看器使用的注册表条目,条目位于默认事件源之下,其名称为 PostgreSQL。 + + 这会创建被事件查看器使用的注册表项,默认事件源命名为PostgreSQL @@ -1598,7 +1649,9 @@ ssh -L 63333:db.foo.com:5432 joe@shell.foo.com - 要从操作系统中注销 event log 库,请执行以下命令: + + 要从操作系统中注销该事件日志库,请执行以下命令: + regsvr32 /u [/i:event_source_name] pgsql_library_directory/pgevent.dll diff --git a/zh/13/spgist.sgml b/zh/13/spgist.sgml index 5b5ebdff..f1afde10 100644 --- a/zh/13/spgist.sgml +++ b/zh/13/spgist.sgml @@ -4,7 +4,7 @@ SP-GiST 索引 - index + 索引 SP-GiST @@ -12,7 +12,7 @@ 简介 - SP-GiST 是 space-partitioned GiST + SP-GiST 是空间分区 GiST 的缩写。SP-GiST 支持分区搜索树,这使得开发多种不同的 非平衡数据结构成为可能,例如四叉树、k-d 树以及基数树(trie)。这些结构 的共同特征是,它们会反复将搜索空间划分为不必等大的分区。与这种划分规则良 @@ -49,7 +49,7 @@ 内置操作符类 - 核心 PostgreSQL 发行版包含了 + PostgreSQL 核心发行版包含了 SP-GiST 操作符类,如 所示。 @@ -60,7 +60,7 @@ 名称 - 索引数据类型 + 被索引数据类型 可索引操作符 排序操作符 @@ -183,11 +183,11 @@ - SP-GiST 核心代码会处理空项。虽然 - SP-GiST 索引确实会为被索引列中的空值存储项,但这一 - 点对索引操作符类代码是隐藏的:不会有空的索引项或搜索条件传递给操作符类 - 方法。(这里假定 SP-GiST 操作符是严格的,因此对空 - 值不可能成功。)因此,这里不再进一步讨论空值。 + SP-GiST 核心代码负责处理值为 null 的索引项。虽然 + SP-GiST 索引会为被索引列中的 null 值存储索引项, + 但索引操作符类代码看不到这些项:值为 null 的索引项或搜索条件绝不会传给 + 操作符类方法。(这里假定 SP-GiST 操作符是严格的, + 因此对 null 值不可能返回真。)所以这里不再讨论 null 值。 @@ -217,9 +217,16 @@ 返回索引实现的静态信息,包括前缀和结点标签数据类型的 OID。 - SQL声明必须如下所示: + + 该函数的 SQL 声明必须如下所示: + CREATE FUNCTION my_config(internal, internal) RETURNS void ... -第一个参数是一个指向spgConfigInC 结构体的指针,其中包含该函数的输入数据。第二个参数是一个指向spgConfigOutC 结构体的指针,函数必须将结果数据填入其中。 + + 第一个参数是一个指向 spgConfigIn C 结构体的 + 指针,其中包含该函数的输入数据。第二个参数是一个指向 + spgConfigOut C 结构体的指针,函数必须将结果 + 数据填入其中。 + typedef struct spgConfigIn { Oid attType; /* 要被索引的数据类型 */ @@ -230,12 +237,14 @@ typedef struct spgConfigOut Oid prefixType; /* 内部元组前缀的数据类型 */ Oid labelType; /* 内部元组结点标签的数据类型 */ Oid leafType; /* 叶子元组值的数据类型 */ - bool canReturnData; /* 操作符类能重构原始数据 */ - bool longValuesOK; /* 操作符类能处理值 > 1 页 */ + bool canReturnData; /* 操作符类能重建原始数据 */ + bool longValuesOK; /* 操作符类能处理大小 > 1 页的值 */ } spgConfigOut; - attType的传入是为了支持多态索引操作符类;对于普通的固定数据类型操作符类,它始终具有相同的值,因此可以忽略。 + 传入 attType 是为了支持多态索引操作符类; + 对于普通的固定数据类型操作符类,它始终具有相同的值,因此可以忽略。 + 对于不使用前缀的操作符类,可以将 prefixType @@ -249,7 +258,7 @@ typedef struct spgConfigOut )。 - leafType通常与attType相同。出于向后兼容的考虑,config方法可以不初始化leafType;这与将leafType设为等于attType具有相同效果。当attTypeleafType不同时,必须提供可选的compress方法。compress方法负责把待索引的 datum 从attType转换为leafType。注意:两个 consistent 函数都会收到未经改变的scankeys,不会经过compress的转换。 + leafType通常与attType相同。出于向后兼容的考虑,config方法可以不初始化leafType;这与将leafType设为等于attType具有相同效果。当attTypeleafType不同时,必须提供可选的compress方法。compress方法负责把待索引的 datum 从attType转换为leafType。注意:两个一致性检查函数都会收到未经改变的scankeys,不会经过compress的转换。 @@ -260,9 +269,16 @@ typedef struct spgConfigOut 为向内部元组插入新值选择一种方法。 - SQL声明必须如下所示: + + 该函数的 SQL 声明必须如下所示: + CREATE FUNCTION my_choose(internal, internal) RETURNS void ... -第一个参数是一个指向spgChooseInC 结构体的指针,其中包含该函数的输入数据。第二个参数是一个指向spgChooseOutC 结构体的指针,函数必须将结果数据填入其中。 + + 第一个参数是一个指向 spgChooseIn C 结构体的 + 指针,其中包含该函数的输入数据。第二个参数是一个指向 + spgChooseOut C 结构体的指针,函数必须将结果 + 数据填入其中。 + typedef struct spgChooseIn { Datum datum; /* 要被索引的原始 datum */ @@ -270,7 +286,7 @@ typedef struct spgChooseIn int level; /* 当前层级(从零开始计) */ /* 来自当前内部元组的数据 */ - bool allTheSame; /* 元组被标记为 all-the-same? */ + bool allTheSame; /* 元组被标记为全部相同? */ bool hasPrefix; /* 元组有前缀? */ Datum prefixDatum; /* 如果有,前缀值 */ int nNodes; /* 内部元组中的结点数 */ @@ -318,8 +334,27 @@ typedef struct spgChooseOut } spgChooseOut; - datum是要插入索引的原始数据,其类型为spgConfigIn.attTypeleafDatum是一个spgConfigOut.leafType类型的值,其初始值是方法compress应用于datum的结果,前提是提供了方法compress;否则,其值与datum相同。leafDatum可能在树的较低层发生变化,如果choosepicksplit方法对它进行了修改。当插入搜索到达叶页时,leafDatum的当前值将存储到新创建的叶子元组中。level是当前内部元组的层级,根层为零。allTheSame为真,表示当前内部元组被标记为包含多个等价结点(参见)。 - hasPrefix为真时,表示当前内部元组包含前缀;若是如此,prefixDatum就是该前缀值。nNodes是内部元组中包含的子结点数量,而nodeLabels是它们的标签值数组;如果没有标签,则为 NULL。 + datum 是将要插入索引的、类型为 + spgConfigIn.attType + 的原始 datum。leafDatum 是一个类型为 + spgConfigOut.leafType + 的值;如果提供了 compress 方法,它最初是将 + datum 交给 + compress 的结果,否则与 + datum 相同。如果 choose + 或 picksplit 方法修改了它,那么在树的更低层级中 + leafDatum 可能会发生变化。当插入搜索到达 + 叶子页时,leafDatum 的当前值将存储在新创 + 建的叶子元组中。level 是当前内部元组的层 + 级,根层为零。若当前内部元组被标记为包含多个等价结点(参见 + ),则 + allTheSame 为真。若当前内部元组包含前缀, + 则 hasPrefix 为真;若是如此, + prefixDatum 就是该前缀值。 + nNodes 是内部元组中包含的子结点数量, + nodeLabels 是它们的标签值数组;如果没有 + 标签,则为 NULL。 + choose 函数可以判定:新值要么匹配某个现有子结 @@ -388,9 +423,16 @@ typedef struct spgChooseOut 决定如何在一组叶子元组上创建一个新的内部元组。 - SQL声明必须如下所示: + + 该函数的 SQL 声明必须如下所示: + CREATE FUNCTION my_picksplit(internal, internal) RETURNS void ... -第一个参数是一个指向spgPickSplitInC 结构体的指针,其中包含该函数的输入数据。第二个参数是一个指向spgPickSplitOutC 结构体的指针,函数必须将结果数据填入其中。 + + 第一个参数是一个指向 spgPickSplitIn C 结构体的 + 指针,其中包含该函数的输入数据。第二个参数是一个指向 + spgPickSplitOut C 结构体的指针,函数必须将结 + 果数据填入其中。 + typedef struct spgPickSplitIn { int nTuples; /* 叶子元组的数量 */ @@ -411,7 +453,12 @@ typedef struct spgPickSplitOut } spgPickSplitOut; - nTuples是所提供的叶子元组数量。datums是包含这些元组数据值的数组,其中的值属于spgConfigOut.leafType类型。level是所有这些叶子元组当前共同的层级,它将成为新内部元组的层级。 + nTuples 是提供的叶子元组数量。 + datums 是由它们的 datum 值组成的数组,类 + 型为 spgConfigOut.leafType。 + level 是这些叶子元组共享的当前层级,它将 + 成为新内部元组的层级。 + hasPrefix 设为指示新的内部元组是否应 @@ -471,14 +518,14 @@ typedef struct spgInnerConsistentIn int nkeys; /* scankeys 数组的长度 */ int norderbys; /* orderbys 数组的长度 */ - Datum reconstructedValue; /* 在父元组处重构的值 */ + Datum reconstructedValue; /* 在父元组处重建的值 */ void *traversalValue; /* 操作符类特定的遍历值 */ MemoryContext traversalMemoryContext; /* 将新的遍历值放在这里 */ int level; /* 当前层级(从零开始计) */ bool returnData; /* 必须返回原始数据? */ /* 来自当前内部元组的数据 */ - bool allTheSame; /* 元组被标记为 all-the-same? */ + bool allTheSame; /* 元组被标记为全部相同? */ bool hasPrefix; /* 元组有前缀? */ Datum prefixDatum; /* 如果有,前缀值 */ int nNodes; /* 内部元组中的结点数 */ @@ -490,12 +537,12 @@ typedef struct spgInnerConsistentOut int nNodes; /* 需要访问的子结点数 */ int *nodeNumbers; /* 它们在结点数组中的索引 */ int *levelAdds; /* 对每个结点层级增加这么多 */ - Datum *reconstructedValues; /* 关联的重构值 */ + Datum *reconstructedValues; /* 关联的重建值 */ void **traversalValues; /* 操作符类特定的遍历值 */ double **distances; /* 关联距离 */ } spgInnerConsistentOut; -数组scankeys的长度为nkeys,它描述索引搜索条件。这些条件用 AND 组合 — 只有满足全部条件的索引项才是我们关心的。(注意,nkeys= 0 表示所有索引项都满足该查询。)通常 consistent 函数只关心sk_strategysk_argument字段,它们分别给出可索引操作符和比较值。特别地,无需检查sk_flags来判断比较值是否为 NULL,因为 SP-GiST 核心代码会过滤掉这些条件。数组orderbys的长度为norderbys,并以相同方式描述排序操作符(如果有)。reconstructedValue是为父元组重建的值;以下情况下它为(Datum) 0:位于根层,或者inner_consistent函数没有在父层提供该值。reconstructedValue始终属于spgConfigOut.leafType类型。traversalValue是指向任意遍历数据的指针,这些数据由上一次调用inner_consistent处理父索引元组时向下传递;在根层时则为 NULL。traversalMemoryContext是存放输出遍历值(见下文)的内存上下文。level是当前内部元组的层级,根层为零。returnDatatrue表示本查询需要重建数据;这要求config函数明确设置了canReturnData。 - allTheSame为真,表示当前内部元组被标记为all-the-same;在这种情况下,所有结点都具有相同的标签(如果有),因此要么全部匹配该查询,要么全部不匹配(参见)。 +数组scankeys的长度为nkeys,它描述索引搜索条件。这些条件用 AND 组合 — 只有满足全部条件的索引项才是我们关心的。(注意,nkeys= 0 表示所有索引项都满足该查询。)通常一致性检查函数只关心每个数组元素的sk_strategysk_argument字段,它们分别给出可索引操作符和比较值。特别地,无需检查sk_flags来判断比较值是否为 NULL,因为 SP-GiST 核心代码会过滤掉这些条件。数组orderbys的长度为norderbys,并以相同方式描述排序操作符(如果有)。reconstructedValue是为父元组重建的值;以下情况下它为(Datum) 0:位于根层,或者inner_consistent函数没有在父层提供该值。reconstructedValue始终属于spgConfigOut.leafType类型。traversalValue是指向任意遍历数据的指针,这些数据由上一次调用inner_consistent处理父索引元组时向下传递;在根层时则为 NULL。traversalMemoryContext是存放输出遍历值(见下文)的内存上下文。level是当前内部元组的层级,根层为零。returnDatatrue表示本查询需要重建数据;这要求config函数将canReturnData设为真。 + allTheSame为真,表示当前内部元组被标记为全部相同;在这种情况下,所有结点都具有相同的标签(如果有),因此要么全部匹配该查询,要么全部不匹配(参见)。 hasPrefix为真时,表示当前内部元组包含前缀;若是如此,prefixDatum就是该前缀值。nNodes是内部元组中包含的子结点数量,而nodeLabels是它们的标签值数组;如果结点没有标签,则为 NULL。 @@ -545,7 +592,7 @@ typedef struct spgLeafConsistentIn int nkeys; /* scankeys 数组的长度 */ int norderbys; /* orderbys 数组的长度 */ - Datum reconstructedValue; /* 在父元组处重构的值 */ + Datum reconstructedValue; /* 在父元组处重建的值 */ void *traversalValue; /* 操作符类特定的遍历值 */ int level; /* 当前层级(从零开始计) */ bool returnData; /* 必须返回原始数据? */ @@ -555,12 +602,12 @@ typedef struct spgLeafConsistentIn typedef struct spgLeafConsistentOut { - Datum leafValue; /* 重构出的原始数据(如果有) */ + Datum leafValue; /* 重建出的原始数据(如果有) */ bool recheck; /* 如果必须重新检查操作符则设为真 */ bool recheckDistances; /* 如果必须重新检查距离则设为真 */ double *distances; /* 关联距离 */ } spgLeafConsistentOut; -数组scankeys的长度为nkeys,它描述索引搜索条件。这些条件用 AND 组合 — 只有满足全部条件的索引项才满足该查询。(注意,nkeys= 0 表示所有索引项都满足该查询。)通常 consistent 函数只关心sk_strategysk_argument字段,它们分别给出可索引操作符和比较值。特别地,无需检查sk_flags来判断比较值是否为 NULL,因为 SP-GiST 核心代码会过滤掉这些条件。数组orderbys的长度为norderbys,并以相同方式描述排序操作符。reconstructedValue是为父元组重建的值;以下情况下它为(Datum) 0:位于根层,或者inner_consistent函数没有在父层提供该值。reconstructedValue始终属于spgConfigOut.leafType类型。traversalValue是指向任意遍历数据的指针,这些数据由上一次调用inner_consistent处理父索引元组时向下传递;在根层时则为 NULL。level是当前叶子元组的层级,根层为零。returnDatatrue表示本查询需要重建数据;这要求config函数明确设置了canReturnData。 +数组scankeys的长度为nkeys,它描述索引搜索条件。这些条件用 AND 组合 — 只有满足全部条件的索引项才满足该查询。(注意,nkeys= 0 表示所有索引项都满足该查询。)通常一致性检查函数只关心每个数组元素的sk_strategysk_argument字段,它们分别给出可索引操作符和比较值。特别地,无需检查sk_flags来判断比较值是否为 NULL,因为 SP-GiST 核心代码会过滤掉这些条件。数组orderbys的长度为norderbys,并以相同方式描述排序操作符。reconstructedValue是为父元组重建的值;以下情况下它为(Datum) 0:位于根层,或者inner_consistent函数没有在父层提供该值。reconstructedValue始终属于spgConfigOut.leafType类型。traversalValue是指向任意遍历数据的指针,这些数据由上一次调用inner_consistent处理父索引元组时向下传递;在根层时则为 NULL。level是当前叶子元组的层级,根层为零。returnDatatrue表示本查询需要重建数据;这要求config函数将canReturnData设为真。 leafDatum是当前叶元组中存储的键值,其类型为spgConfigOut.leafType @@ -607,7 +654,10 @@ typedef struct spgLeafConsistentOut 定义一组用户可见参数,用于控制操作符类的行为。 - SQL声明必须如下所示: + + 该函数的 SQL 声明必须如下所示: + + CREATE OR REPLACE FUNCTION my_options(internal) RETURNS void AS 'MODULE_PATHNAME' @@ -640,7 +690,7 @@ LANGUAGE C STRICT; - 如果被索引列属于可应用排序规则的数据类型,则索引排序规则会通过标准的 + 如果被索引列属于支持排序规则的数据类型,则索引排序规则会通过标准的 PG_GET_COLLATION() 机制传递给所有支持方法。 @@ -718,7 +768,7 @@ LANGUAGE C STRICT; - <quote>All-the-Same</quote> 内部元组 + <quote>全部相同</quote>的内部元组 picksplit 无法把提供的叶子值划分为至少两个结点 diff --git a/zh/13/spi.sgml b/zh/13/spi.sgml index 89fcf637..9d47843a 100644 --- a/zh/13/spi.sgml +++ b/zh/13/spi.sgml @@ -76,7 +76,7 @@ int SPI_connect_ext(int options) SPI_connect 会为某次 C 函数调用打开到 SPI 管理器 的连接。如果要通过 SPI 执行命令,就必须调用此函数。不过,有些 SPI - 实用函数可以在未连接的 C 函数中调用。 + 辅助函数可以在未连接的 C 函数中调用。 @@ -119,7 +119,7 @@ int SPI_connect_ext(int options) SPI_ERROR_CONNECT - 出错时 + 发生错误时 @@ -287,24 +287,30 @@ SPI_execute("INSERT INTO foo SELECT * FROM bar RETURNING *", false, 5); - 结构 SPITupleTable 定义如下: + 结构体 SPITupleTable 定义如下: typedef struct SPITupleTable { - /* Public members */ - TupleDesc tupdesc; /* tuple descriptor */ - HeapTuple *vals; /* array of tuples */ - uint64 numvals; /* number of valid tuples */ - - /* Private members, not intended for external callers */ - uint64 alloced; /* allocated length of vals array */ - MemoryContext tuptabcxt; /* memory context of result table */ - slist_node next; /* link for internal bookkeeping */ - SubTransactionId subid; /* subxact in which tuptable was created */ + /* 公共成员 */ + TupleDesc tupdesc; /* 元组描述符 */ + HeapTuple *vals; /* 元组数组 */ + uint64 numvals; /* 有效元组数 */ + + /* 私有成员,不供外部调用者使用 */ + uint64 alloced; /* vals 数组的已分配长度 */ + MemoryContext tuptabcxt; /* 结果表的内存上下文 */ + slist_node next; /* 用于内部管理的链接 */ + SubTransactionId subid; /* 创建 tuptable 的子事务 */ } SPITupleTable; -字段 tupdesc, - valsnumvals 可由 SPI 调用者使用;其余字段供内部使用。vals 是一个指向行的指针数组。行数由 numvals 给出(出于某些历史原因,这个计数也会在以下变量中返回:SPI_processed)。 - tupdesc 是一个行描述符,可以传给处理行的 SPI 函数。 + + SPI 调用者可以使用 tupdesc、 + valsnumvals + 字段;其余字段属于内部实现。vals 是一个指向 + 各行的指针数组。行数由 numvals 给出(出于一 + 些历史原因,这个计数也会通过 SPI_processed 返回)。 + tupdesc 是行描述符,可以传给那些处理行的 SPI + 函数。 + SPI_finish 会释放当前 C 函数调用期间分配的全部 @@ -497,7 +503,7 @@ typedef struct SPITupleTable SPI_ERROR_UNCONNECTED - 从未连接的 C 函数中调用 + 如果从一个未连接的 C 函数中调用 @@ -510,9 +516,9 @@ typedef struct SPITupleTable 所有 SPI 查询执行函数都会设置 SPI_processed 和 - SPI_tuptable(只设置指针,而不会复制结构体内容)。如果 + SPI_tuptable(只设置指针,而不更改结构体内容)。如果 需要在后续调用之后继续访问 SPI_execute 或其他查询 - 执行函数的结果表,请把这两个全局变量保存到本地 C 函数变量中。 + 执行函数的结果表,请把这两个全局变量保存到 C 函数的局部变量中。 @@ -557,7 +563,7 @@ int SPI_exec(const char * command, long count< const char * command - 包含要执行命令的字符串 + 包含待执行命令的字符串 @@ -566,7 +572,7 @@ int SPI_exec(const char * command, long count< long count - 要返回的最大行数,或者用0表示没有限制 + 要返回的最大行数,或者用 0 表示不限制 @@ -628,7 +634,7 @@ int SPI_execute_with_args(const char *command, SPI_execute_plan 达到类似效果。不过,使用本函数 时,查询计划总会针对所提供的具体参数值进行定制。对于一次性查询执行,应 优先选择本函数。如果同一条命令要用许多不同参数重复执行,则两种方式孰快 - 取决于重新计划的代价与定制计划收益之间的权衡。 + 取决于重新规划的代价与定制计划收益之间的权衡。 @@ -683,9 +689,9 @@ int SPI_execute_with_args(const char *command, 如果 nullsNULL,则 - SPI_execute_with_args 会假定没有参数为 NULL。 - 否则,如果对应参数值非 NULL,则 nulls 数组中 - 的对应项应为 ' ';如果对应参数值为 NULL,则 + SPI_execute_with_args 会假定没有参数为空值。 + 否则,如果对应参数值非空值,则 nulls 数组中 + 的对应项应为 ' ';如果对应参数值为空值,则 对应项应为 'n'。(后一种情况下,对应 values 项中的实际值无关紧要。)注意, nulls 不是文本字符串,而只是一个数组,因此不 @@ -739,7 +745,7 @@ int SPI_execute_with_args(const char *command, SPI_prepare - 准备一个语句,但不执行它 + 准备一个语句,但暂不执行 @@ -818,8 +824,7 @@ SPIPlanPtr SPI_prepare(const char * command, int 返回值 - SPI_prepare 返回一个指向非空 SPIPlan - 的指针,它是表示预备语句的不透明结构体。发生错误时会返回 + SPI_prepare 返回一个非空指针,指向表示预备语句的不透明结构体 SPIPlan。发生错误时会返回 NULL,并将 SPI_result 设为 SPI_execute 所使用的那些错误码之一;但如果 commandNULL,或者 @@ -838,17 +843,16 @@ SPIPlanPtr SPI_prepare(const char * command, int SPI_execute_plan 在最初几次使用时会根据提供的参数 值生成定制计划。当同一个预备语句被使用足够多次之后, SPI_execute_plan 会构建一个通用计划;如果它的代价 - 没有比定制计划高出太多,就会开始改用通用计划,而不是每次都重新计划。如 + 没有比定制计划高出太多,就会开始改用通用计划,而不是每次都重新规划。如 果这种默认行为不合适,可以把 CURSOR_OPT_GENERIC_PLANCURSOR_OPT_CUSTOM_PLAN 标志传给 SPI_prepare_cursor,分别强制使用通用计划或定制计划。 - 尽管预备语句的主要目的在于避免重复进行解析分析和计划,但只要语句中使用 + 尽管预备语句的主要目的在于避免重复进行解析分析和规划,但只要语句中使用 的数据库对象自上次使用该预备语句以来发生了定义性(DDL)变更, - PostgreSQL 就会在再次使用前强制重新分析并重 - 新计划该语句。此外,如果 的值在两次 + PostgreSQL 就会在再次使用前强制重新分析并重新规划该语句。此外,如果 的值在两次 使用之间发生变化,该语句也会基于新的 search_path 重 新解析。(后一种行为是从 PostgreSQL 9.3 开 始引入的。)有关预备语句行为的更多信息,请参见 @@ -934,7 +938,7 @@ SPIPlanPtr SPI_prepare_cursor(const char * command, int < Oid * argtypes - 指向数组的指针,该数组包含参数数据类型的 + 一个数组指针,它指向的数组包含参数的数据类型的 OID @@ -1026,7 +1030,7 @@ SPIPlanPtr SPI_prepare_params(const char * command, ParserSetupHook parserSetup - 语法分析器钩子设置函数 + 解析器钩子设置函数 @@ -1241,8 +1245,8 @@ bool SPI_is_cursor_plan(SPIPlanPtr plan) 返回值 - 如果 plan 能产生游标,则返回 - true;如果不能,则返回 false,并将 + 返回 truefalse,表示 + plan 能否产生游标,同时将 SPI_result 设为零。如果无法确定答案(例如 planNULL 或无效,或者在 未连接到 SPI 时调用),则会将 SPI_result 设为合适 @@ -1314,15 +1318,14 @@ int SPI_execute_plan(SPIPlanPtr plan, Datum * - 如果nullsNULL, - 那么SPI_execute_plan会假设没有参数 - 为空值。否则,如果对应的参数值为非空, - nulls - 数组的每一个项都应该是' ';如果对应参数值为空, - 对应项应为'n'(在后 - 面的情况中,对应的values项中的值没有 - 关系)。注意nulls不是一个文本字符串, - 它只是一个数组:它不需要一个'\0'终止符。 + 如果 nullsNULL,则 + SPI_execute_plan 会假定没有参数为空值。 + 否则,如果对应参数值非空值,则 nulls 数组中 + 的对应项应为 ' ';如果对应参数值为空值,则 + 对应项应为 'n'。(后一种情况下,对应 + values 项中的实际值无关紧要。)注意, + nulls 不是文本字符串,而只是一个数组,因此不 + 需要 '\0' 终止符。 @@ -1453,7 +1456,7 @@ int SPI_execute_plan_with_paramlist(SPIPlanPtr plan, long count - 要返回的最大行数,或者用0表示没有限制 + 要返回的最大行数,或者用 0 表示不限制 @@ -1537,15 +1540,14 @@ int SPI_execp(SPIPlanPtr plan, Datum * values< - 如果nullsNULL, - 那么SPI_execp会假设没有参数 - 为空值。否则,如果对应的参数值为非空, - nulls - 数组的每一个项都应该是' ';如果对应参数值为空, - 对应项应为'n'(在后 - 面的情况中,对应的values项中的值没有 - 关系)。注意nulls不是一个文本字符串, - 它只是一个数组:它不需要一个'\0'终止符。 + 如果 nullsNULL,则 + SPI_execp 会假定没有参数为空值。 + 否则,如果对应参数值非空值,则 nulls 数组中 + 的对应项应为 ' ';如果对应参数值为空值,则 + 对应项应为 'n'。(后一种情况下,对应 + values 项中的实际值无关紧要。)注意, + nulls 不是文本字符串,而只是一个数组,因此不 + 需要 '\0' 终止符。 @@ -1554,7 +1556,7 @@ int SPI_execp(SPIPlanPtr plan, Datum * values< long count - 要返回的最大行数,或者用0表示没有限制 + 要返回的最大行数,或者用 0 表示不限制 @@ -1662,15 +1664,14 @@ Portal SPI_cursor_open(const char * name, SPIPlanPtr - 如果nullsNULL, - 那么SPI_cursor_open会假设没有参数 - 为空值。否则,如果对应的参数值为非空, - nulls - 数组的每一个项都应该是' ';如果对应参数值为空, - 对应项应为'n'(在后 - 面的情况中,对应的values项中的值没有 - 关系)。注意nulls不是一个文本字符串, - 它只是一个数组:它不需要一个'\0'终止符。 + 如果 nullsNULL,则 + SPI_cursor_open 会假定没有参数为空值。 + 否则,如果对应参数值非空值,则 nulls 数组中 + 的对应项应为 ' ';如果对应参数值为空值,则 + 对应项应为 'n'。(后一种情况下,对应 + values 项中的实际值无关紧要。)注意, + nulls 不是文本字符串,而只是一个数组,因此不 + 需要 '\0' 终止符。 @@ -1731,11 +1732,10 @@ Portal SPI_cursor_open_with_args(const char *name, - 对于一次性的查询执行,这个函数应该比 - SPI_prepare_cursor加上其后的 - SPI_cursor_open更好。如果相同的命令 - 要被用很多不同的参数执行,哪种方法更快就要取决于重做计划的 - 代价与定制计划带来的好处之间谁更有利。 + 对于一次性查询执行,应优先使用此函数,而不是先调用 + SPI_prepare_cursor 再调用 + SPI_cursor_open。如果同一条命令要用许多不同参数执行, + 哪种方法更快取决于重新规划的代价与定制计划收益之间的权衡。 @@ -1779,8 +1779,8 @@ Portal SPI_cursor_open_with_args(const char *name, Oid * argtypes - 一个长度为nargs的数组, - 包含参数的数据类型的OID + 一个长度为 nargs 的数组,包含参数数据类型的 + OID @@ -1789,8 +1789,7 @@ Portal SPI_cursor_open_with_args(const char *name, Datum * values - 一个长度为nargs的数组, - 包含实际的参数值 + 一个长度为 nargs 的数组,包含实际参数值 @@ -1799,20 +1798,19 @@ Portal SPI_cursor_open_with_args(const char *name, const char * nulls - 一个长度为nargs的数组, - 描述哪些参数为空值 + 一个长度为 nargs 的数组,用于描述哪些参数为 + 空值 - 如果nullsNULL, - 那么SPI_cursor_open_with_args会假设没有参数 - 为空值。否则,如果对应的参数值为非空, - nulls - 数组的每一个项都应该是' ';如果对应参数值为空, - 对应项应为'n'(在后 - 面的情况中,对应的values项中的值没有 - 关系)。注意nulls不是一个文本字符串, - 它只是一个数组:它不需要一个'\0'终止符。 + 如果 nullsNULL,则 + SPI_cursor_open_with_args 会假定没有参数为空值。 + 否则,如果对应参数值非空值,则 nulls 数组中 + 的对应项应为 ' ';如果对应参数值为空值,则 + 对应项应为 'n'。(后一种情况下,对应 + values 项中的实际值无关紧要。)注意, + nulls 不是文本字符串,而只是一个数组,因此不 + 需要 '\0' 终止符。 @@ -2082,7 +2080,7 @@ void SPI_cursor_fetch(Portal portal, bool forw 如果该游标的计划不是用CURSOR_OPT_SCROLL - 选项创建的,向后获取会失败。 + 选项创建的,向后获取可能失败。 @@ -2156,7 +2154,7 @@ void SPI_cursor_move(Portal portal, bool forwa 如果该游标的计划不是用CURSOR_OPT_SCROLL - 选项创建的,向后移动会失败。 + 选项创建的,向后移动可能失败。 @@ -2252,8 +2250,7 @@ void SPI_scroll_cursor_fetch(Portal portal, FetchDirectio 如果该游标的计划不是用CURSOR_OPT_SCROLL - 选项创建的,除FETCH_FORWARD之外的方向值会 - 失败。 + 选项创建的,除FETCH_FORWARD之外的方向值可能失败。 @@ -2350,8 +2347,7 @@ void SPI_scroll_cursor_move(Portal portal, FetchDirection 如果该游标的计划不是用CURSOR_OPT_SCROLL - 选项创建的,除FETCH_FORWARD之外的方向值会 - 失败。 + 选项创建的,除FETCH_FORWARD之外的方向值可能失败。 @@ -2526,7 +2522,8 @@ SPIPlanPtr SPI_saveplan(SPIPlanPtr plan) 返回值 - 返回指向复制后的语句的指针;如果失败,则返回 NULL。出错时,SPI_result 设置如下: + 复制后语句的指针;如果未成功则返回NULL。 + 错误时,SPI_result会被这样设置: @@ -2572,8 +2569,8 @@ SPIPlanPtr SPI_saveplan(SPIPlanPtr plan) SPI_register_relation - ephemeral named relation - registering with SPI + 临时命名关系 + 向 SPI 注册 @@ -2597,7 +2594,7 @@ int SPI_register_relation(EphemeralNamedRelation enr) SPI_register_relation 使一个带有相关信息的临时命名关 - 系对通过当前 SPI 连接计划和执行的查询可用。 + 系对通过当前 SPI 连接规划和执行的查询可用。 @@ -2677,8 +2674,8 @@ int SPI_register_relation(EphemeralNamedRelation enr) SPI_unregister_relation - ephemeral named relation - unregistering from SPI + 临时命名关系 + 从 SPI 注销 @@ -2725,7 +2722,7 @@ int SPI_unregister_relation(const char * name) 返回值 - 如果该命令的执行成功,则会返回下列(非负)值: + 如果该命令的执行成功,则将返回下列(非负)值: @@ -2780,13 +2777,13 @@ int SPI_unregister_relation(const char * name) SPI_register_trigger_data - ephemeral named relation - registering with SPI + 临时命名关系 + 向 SPI 注册 - transition tables - implementation in PLs + 过渡表 + 在 PL 中实现 @@ -2810,8 +2807,8 @@ int SPI_register_trigger_data(TriggerData *tdata) SPI_register_trigger_data 使触发器捕获的所有临时关系 - 都能在通过当前 SPI 连接计划和执行的查询中使用。目前,这指的是通过 - REFERENCING OLD/NEW TABLE AS ... 子句定义、并由 + 都能在通过当前 SPI 连接规划和执行的查询中使用。目前,这指的是由带有 + REFERENCING OLD/NEW TABLE AS ... 子句的 AFTER 触发器捕获的过渡表。PL 触发器处理函数应在建 立 SPI 连接后调用此函数。 @@ -2837,7 +2834,7 @@ int SPI_register_trigger_data(TriggerData *tdata) 返回值 - 如果命令的执行成功,则会返回下列(非负)值: + 如果该命令的执行成功,则将返回下列(非负)值: @@ -3109,7 +3106,7 @@ char * SPI_getvalue(HeapTuple row, TupleDesc r 返回值 - 列值;如果该列为 NULL、colnumber 超出范围 + 列值;如果该列为空值、colnumber 超出范围 (SPI_result 被设置为 SPI_ERROR_NOATTRIBUTE)或者没有输出函数 可用(SPI_result 被设置为 @@ -3201,8 +3198,8 @@ Datum SPI_getbinval(HeapTuple row, TupleDesc r 返回值 - 返回该列的二进制值。如果该列为 NULL,则 - isnull 指向的变量会被设为 true,否则设为 false。 + 返回该列的二进制值。如果该列为空值,则 + isnull 指向的变量会被设为真,否则设为假。 @@ -3238,7 +3235,7 @@ char * SPI_gettype(TupleDesc rowdesc, int coln SPI_gettype返回该指定列的数据类型名称 - 的拷贝(当你不再需要该拷贝后,可以使用pfree + 的副本(当你不再需要该副本后,可以使用pfree 释放它)。 @@ -3370,7 +3367,7 @@ char * SPI_getrelname(Relation rel) SPI_getrelname返回该指定关系的名称 - 的拷贝(当你不再需要该拷贝后,可以使用pfree + 的副本(当你不再需要该副本后,可以使用pfree 释放它)。 @@ -3463,7 +3460,7 @@ char * SPI_getnspname(Relation rel) SPI_result_code_string - 将结果代码表示为字符串 + 返回错误码的字符串表示 @@ -3477,7 +3474,7 @@ const char * SPI_result_code_string(int code); SPI_result_code_string 返回各种 SPI 函数返回的,或 - 存放在 SPI_result 中的结果代码的字符串表示。 + 存放在 SPI_result 中的结果码的字符串表示。 @@ -3489,7 +3486,7 @@ const char * SPI_result_code_string(int code); int code - 结果代码 + 结果码 @@ -3500,7 +3497,7 @@ const char * SPI_result_code_string(int code); 返回值 - 结果代码的字符串表示。 + 结果码的字符串表示。 @@ -3512,8 +3509,8 @@ const char * SPI_result_code_string(int code); - memory context - in SPI + 内存上下文 + 在 SPI 中 PostgreSQL内存上下文 中分配内存。内存上下文为管理那些在许多不同位置创建、且生命周期各不相同 @@ -3538,7 +3535,7 @@ const char * SPI_result_code_string(int code); 办法是用 SPI_palloc 为返回对象分配内存。 SPI_palloc上层执行器上下文中分配 内存,也就是调用 SPI_connect 时的当前内存上下文; - 这正是从 C 函数返回值最合适的上下文。本节介绍的其他几个实用函数同样会返 + 这正是从 C 函数返回值最合适的上下文。本节介绍的其他几个辅助函数同样会返 回在上层执行器上下文中创建的对象。 @@ -3546,7 +3543,7 @@ const char * SPI_result_code_string(int code); 调用 SPI_connect 时,会把该 C 函数的私有上下文 (由 SPI_connect 创建)设为当前上下文。所有通过 pallocrepalloc 或 SPI - 实用函数分配的内存(本节另有说明的除外)都位于这个上下文中。当 C 函数通 + 辅助函数分配的内存(本节另有说明的除外)都位于这个上下文中。当 C 函数通 过 SPI_finish 与 SPI 管理器断开连接时,当前上下文 会恢复为上层执行器上下文,而在该 C 函数内存上下文中分配的所有内存都会被 释放,之后就不能再使用。 @@ -3741,7 +3738,7 @@ void SPI_pfree(void * pointer) SPI_copytuple - 在上层执行器上下文中创建一行的拷贝 + 在上层执行器上下文中创建一行的副本 @@ -3774,7 +3771,7 @@ HeapTuple SPI_copytuple(HeapTuple row) HeapTuple row - 要拷贝的行 + 要复制的行 @@ -3785,7 +3782,7 @@ HeapTuple SPI_copytuple(HeapTuple row) 返回值 - 拷贝后的行;出错时返回 NULL + 复制后的行;出错时返回 NULL (错误指示见 SPI_result @@ -3841,7 +3838,7 @@ HeapTupleHeader SPI_returntuple(HeapTuple row, TupleDesc HeapTuple row - 要拷贝的行 + 要复制的行 @@ -3850,7 +3847,7 @@ HeapTupleHeader SPI_returntuple(HeapTuple row, TupleDesc TupleDesc rowdesc - 行描述符(若要获得最佳缓存效果,大多数情况下应每次都传入同一个描述符) + 行描述符(若要获得最佳缓存效果,每次都传入同一个描述符) @@ -3861,7 +3858,7 @@ HeapTupleHeader SPI_returntuple(HeapTuple row, TupleDesc 返回值 - 指向拷贝后行的 HeapTupleHeader;出错时返回 + 指向复制后行的 HeapTupleHeader;出错时返回 NULL(错误指示见 SPI_result @@ -3963,13 +3960,14 @@ HeapTuple SPI_modifytuple(Relation rel, HeapTuple - 如果nullsNULL,那么 - SPI_modifytuple假定没有新值为空值。否则, - 如果对应的新值为非空,nulls数组的每一项都应 - 该是' ',而如果对应的新值为空值则为'n'(在 - 后一种情况中,对应的values项中的新值无关紧 - 要)。注意nulls不是一个文本字符串,只是一个 - 数组:它不需要一个'\0'终止符。 + 如果 nullsNULL,则 + SPI_modifytuple 会假定没有新值为空值。 + 否则,如果对应新值非空值,则 nulls 数组中 + 的对应项应为 ' ';如果对应新值为空值,则 + 对应项应为 'n'。(后一种情况下,对应 + values 项中的实际值无关紧要。)注意, + nulls 不是文本字符串,而只是一个数组,因此不 + 需要 '\0' 终止符。 @@ -4048,7 +4046,7 @@ void SPI_freetuple(HeapTuple row) SPI_freetuple释放之前在上层执行器上下文中 - 分配的一个行。 + 分配的一行。 @@ -4346,7 +4344,7 @@ void SPI_start_transaction(void) - 数据改变的可见性 + 数据更改的可见性 下列规则决定了使用 SPI 的函数(以及其他任何 C 函数)中数据更改的可见 @@ -4478,7 +4476,8 @@ CREATE FUNCTION execq(text, integer) RETURNS int8 - 以下是一个示例会话: + 下面是一个示例会话: + => SELECT execq('CREATE TABLE a (x integer)', 0); execq diff --git a/zh/13/stylesheet-speedup-common.xsl b/zh/13/stylesheet-speedup-common.xsl index e3fb582a..403f350c 100644 --- a/zh/13/stylesheet-speedup-common.xsl +++ b/zh/13/stylesheet-speedup-common.xsl @@ -95,6 +95,6 @@ -en +zh_cn diff --git a/zh/13/syntax.sgml b/zh/13/syntax.sgml index f291bad5..ff541c03 100644 --- a/zh/13/syntax.sgml +++ b/zh/13/syntax.sgml @@ -21,7 +21,7 @@ 词法结构 - token + 词元 @@ -29,7 +29,7 @@ - 一个词元可以是关键词标识符带引号的标识符文字值(或常量),或者特殊字符符号。词元通常由空白(空格、制表符、换行)分隔,但如果不存在歧义,则不必如此(一般只有特殊字符与其他类型的词元相邻时才会这样)。 + 一个词元可以是关键词标识符带引号的标识符字面量(或常量),或者特殊字符符号。词元通常由空白(空格、制表符、换行)分隔,但如果不存在歧义,则不必如此(一般只有特殊字符与其他类型的词元相邻时才会这样)。 @@ -58,18 +58,18 @@ INSERT INTO MY_TABLE VALUES (3, 'hi there'); 标识符和关键词 - identifier - syntax of + 标识符 + 语法 - name - syntax of + 名称 + 语法 - key word - syntax of + 关键词 + 语法 @@ -83,7 +83,7 @@ INSERT INTO MY_TABLE VALUES (3, 'hi there'); - identifierlength + 标识符长度 系统对标识符最多只使用 NAMEDATALEN-1 个字节;在命令中可以写更长的名称,但它们会被截断。默认情况下, NAMEDATALEN 为 64,因此标识符的最大长度是 63 字节。如果这个限制有问题,可以通过修改 src/include/pg_config_manual.h 中的 NAMEDATALEN 常量来提高。 @@ -91,8 +91,8 @@ INSERT INTO MY_TABLE VALUES (3, 'hi there'); - case sensitivity - of SQL commands + 大小写敏感性 + SQL 命令 关键词和未加引号的标识符不区分大小写。因此: @@ -110,8 +110,8 @@ UPDATE my_table SET a = 5; - quotation marks - and identifiers + 引号 + 与标识符 还有第二类标识符:定界标识符带引号的标识符。它通过把任意字符序列括在双引号中形成(")。 定界标识符始终是标识符,绝不会是关键词。因此,"select" 可以用来引用名为 select 的列或表,而不加引号的 select 会被视为关键词,因此在期望表名或列名的位置使用时会导致解析错误。这个示例可以用带引号的标识符写成: @@ -133,7 +133,7 @@ UPDATE "my_table" SET "a" = 5; Unicode 转义 - in identifiers + 在标识符中 @@ -149,9 +149,14 @@ U&"\0441\043B\043E\043D" - 如果想使用反斜线以外的转义字符,可以在字符串后用 UESCAPEUESCAPE 子句指定,例如: + + 如果希望使用其他字符而不是反斜线作为转义字符,可以在字符串之后使用 + UESCAPEUESCAPE 子句来指定,例如: + U&"d!0061t!+000061" UESCAPE '!' -转义字符可以是任意单个字符,但不能是十六进制数字、加号、单引号、双引号或空白字符。注意,转义字符要用单引号而不是双引号括起,写在以下关键字之后:UESCAPE。 + + 转义字符可以是除十六进制数字、加号、单引号、双引号或空白字符之外的任意单个字符。注意,转义字符在 + UESCAPE 之后用单引号而不是双引号书写。 @@ -172,7 +177,7 @@ U&"d!0061t!+000061" UESCAPE '!' 常量 - constant + 常量 @@ -183,8 +188,8 @@ U&"d!0061t!+000061" UESCAPE '!' 字符串常量 - character string - constant + 字符串 + 常量 @@ -295,7 +300,7 @@ SELECT 'foo' 'bar'; - 如果配置参数off,那么PostgreSQL对常规字符串常量和转义字符串常量中的反斜线转义都识别。不过,从PostgreSQL 9.1 开始,该参数的默认值为on,意味着只在转义字符串常量中识别反斜线转义。这种行为更兼容标准,但是可能打断依赖于历史行为(反斜线转义总是会被识别)的应用。作为一种变通,你可以设置该参数为off,但是最好迁移到符合新的行为。如果你需要使用一个反斜线转义来表示一个特殊字符,为该字符串常量写上一个E。 + 如果配置参数off,那么PostgreSQL对常规字符串常量和转义字符串常量中的反斜线转义都识别。不过,从PostgreSQL 9.1 开始,该参数的默认值为on,意味着只在转义字符串常量中识别反斜线转义。这种行为更兼容标准,但是可能使依赖历史行为(始终识别反斜线转义)的应用无法正常工作。作为一种变通,你可以设置该参数为off,但最好修改应用,不再使用反斜线转义。如果你需要使用一个反斜线转义来表示一个特殊字符,为该字符串常量写上一个E @@ -313,7 +318,7 @@ SELECT 'foo' 'bar'; Unicode 转义 - in string constants + 在字符串常量中 @@ -359,13 +364,18 @@ U&'d!0061t!+000061' UESCAPE '!' 美元引用的字符串常量 - dollar quoting + 美元引用 - 指定字符串常量的标准语法通常很方便,但当所需字符串包含许多单引号时,就可能难以理解,因为每个单引号都必须写两遍。为了让这类情况下的查询更易读,PostgreSQL提供了另一种编写字符串常量的方法,称为美元引用。美元引用的字符串常量由一个美元符号($)、一个由零个或多个字符组成的可选标签、另一个美元符号、构成字符串内容的任意字符序列、一个美元符号、与该美元引用开头相同的标签,以及一个美元符号组成。例如,对于字符串 Dianne's horse,下面是使用美元引用指定它的两种不同方法: + + 虽然指定字符串常量的标准语法通常很方便,但当目标字符串中包含很多单引号时,就会变得难以阅读,因为每个单引号都必须写成两个。为了在这种情况下让查询更易读, + PostgreSQL 提供了另一种编写字符串常量的方式,称为美元引用(dollar quoting)。一个美元引用字符串常量由美元符号($)、一个由零个或多个字符组成的可选标签、另一个美元符号、组成字符串内容的任意字符序列、一个美元符号、开始该美元引用时使用的同一个标签以及最后一个美元符号组成。例如,下面是使用美元引用指定字符串 Dianne's horse 的两种不同写法: + $$Dianne's horse$$ $SomeTag$Dianne's horse$SomeTag$ -注意,在美元引用的字符串中,单引号不需要转义就可以使用。事实上,美元引用字符串内的任何字符都不会被转义:字符串内容始终按字面书写。反斜线没有特殊含义,美元符号也没有,除非它是与开头标签相匹配的序列的一部分。 + + 注意,在美元引用字符串内部,单引号可以直接使用而无须转义。事实上,美元引用字符串内部的任何字符都不会被转义:字符串内容总是按字面方式书写。反斜线不是特殊字符,美元符号也不是,除非它们构成了与开头标签匹配的序列。 + 可以通过在每个嵌套层级选择不同的标签,来嵌套美元引用字符串常量。这种做法最常见于编写函数定义时。例如: @@ -397,8 +407,8 @@ $function$ 位串常量 - bit string - constant + 位串 + 常量 @@ -418,18 +428,28 @@ $function$ 数字常量 - number - constant + 数字 + 常量 - 数字常量接受下列一般形式: + + 数字常量接受下列一般形式: + digits digits.digitse+-digits digits.digitse+-digits digitse+-digits -其中 digits 是一个或多个十进制数字(0 到 9)。若使用小数点,则小数点前后至少有一侧必须有数字。若使用指数标记(e),其后至少必须有一位数字。常量中不能嵌入空格或其他字符。注意,开头的正号或负号实际上不被视为常量的一部分,而是作用于常量的操作符。 + + 其中 digits 是一个或多个十进制数字(0 到 9)。 + 若使用小数点,则小数点前后至少有一侧必须有数字。若使用指数标记 + (e),其后至少必须有一位数字。常量中不能嵌入空格或 + 其他字符。请注意,前导正号或负号 + 实际上不属于常量本身,而是作用于常量的操作符。 + - 下面是一些有效数字常量的示例: + + 这些是合法数字常量的示例: + 42 3.5 4. @@ -447,12 +467,12 @@ $function$ - 为数字常量最初指定的数据类型,只是类型解析算法的起点。在大多数情况下,常量会根据上下文被自动强制转换成最合适的类型。必要时,你可以通过类型转换强制把一个数值解释为特定的数据类型。type cast + 为数字常量最初指定的数据类型,只是类型解析算法的起点。在大多数情况下,常量会根据上下文被自动强制转换成最合适的类型。必要时,你可以通过类型转换强制把一个数值解释为特定的数据类型。类型转换 例如,可以通过下面的写法强制把一个数值当作类型 realfloat4)处理: -REAL '1.23' -- string style -1.23::REAL -- PostgreSQL (historical) style +REAL '1.23' -- 字符串形式 +1.23::REAL -- PostgreSQL(历史)形式 这些实际上只是下面将要讨论的一般类型转换记法的特例。 @@ -463,8 +483,8 @@ REAL '1.23' -- string style 其他类型的常量 - data type - constant + 数据类型 + 常量 @@ -490,7 +510,7 @@ CAST ( 'string' AS type ) - 如中所述,::CAST() 以及函数调用语法也可以用来指定任意表达式的运行时类型转换。为避免语法歧义,type 'string' 语法只能用来指定简单字面常量的类型。该语法的另一个限制是不能用于数组类型;要指定数组常量的类型,请使用 ::CAST()。 + 如中所述,::CAST() 以及函数调用语法也可以用来指定任意表达式的运行时类型转换。为避免语法歧义,type 'string' 语法只能用来指定简单字面常量的类型。type 'string' 语法的另一个限制是不能用于数组类型;要指定数组常量的类型,请使用 ::CAST() @@ -503,8 +523,8 @@ CAST ( 'string' AS type ) 操作符 - operator - syntax + 操作符 + 语法 @@ -554,7 +574,7 @@ CAST ( 'string' AS type ) - 圆括号(())具有它们通常的含义,用来分组表达式并且强制优先。在某些情况中,圆括号被要求作为一个特定 SQL 命令的固定语法的一部分。 + 圆括号(())具有它们通常的含义,用来对表达式分组并确定运算优先级。在某些情况中,圆括号被要求作为一个特定 SQL 命令的固定语法的一部分。 @@ -572,7 +592,7 @@ CAST ( 'string' AS type ) - 分号(;)结束一个 SQL 命令。它不能出现在一个命令中间的任何位置,除了在一个字符串常量中或者一个被引用的标识符中。 + 分号(;)结束一个 SQL 命令。它不能出现在一个命令中间的任何位置,除了在一个字符串常量中或者一个带引号的标识符中。 @@ -584,7 +604,7 @@ CAST ( 'string' AS type ) - 星号(*)在某些上下文中用来表示表行或组合值的所有字段。当它被用作聚合函数的参数时,还有一种特殊含义,即该聚合不需要任何显式参数。 + 星号(*)在某些上下文中用来表示表行或复合值的所有字段。当它被用作聚合函数的参数时,还有一种特殊含义,即该聚合不需要任何显式参数。 @@ -602,22 +622,22 @@ CAST ( 'string' AS type ) 注释 - comment - in SQL + 注释 + 在 SQL 中 注释是一串以双连字符开始并延伸到行尾的字符,例如: --- This is a standard SQL comment +-- 这是一条标准 SQL 注释 另外,也可以使用 C 风格注释块: -/* multiline comment - * with nesting: /* nested block comment */ +/* 多行注释 + * 包含嵌套:/* 嵌套块注释 */ */ 这里该注释开始于/*并且延伸到匹配出现的*/。这些注释块可按照 SQL 标准中指定的方式嵌套,但和 C 中不同。这样我们可以注释掉一大段可能包含注释块的代码。 @@ -632,8 +652,8 @@ CAST ( 'string' AS type ) 操作符优先级 - operator - precedence + 操作符 + 优先级 @@ -677,7 +697,7 @@ CAST ( 'string' AS type ) + - - 一元加、一元减 + 一元正号、一元负号 @@ -695,13 +715,13 @@ CAST ( 'string' AS type ) ^ - 指数 + 求幂 * / % - 乘、除、模 + 乘、除、取模 @@ -713,7 +733,7 @@ CAST ( 'string' AS type ) (任意其他操作符) - 所有其他本地以及用户定义的操作符 + 所有其他内置以及用户定义的操作符 @@ -1399,7 +1419,7 @@ SELECT * FROM tbl WHERE a COLLATE "C" > 'foo'; SELECT * FROM tbl WHERE (a > 'foo') COLLATE "C"; - 因为它尝试把一个排序规则应用到>操作符的结果,而它的数据类型是非可排序数据类型boolean。 + 因为它尝试把一个排序规则应用到>操作符的结果,而它的数据类型是不支持排序规则的数据类型boolean diff --git a/zh/13/textsearch.sgml b/zh/13/textsearch.sgml index ce57d94f..5766af8c 100644 --- a/zh/13/textsearch.sgml +++ b/zh/13/textsearch.sgml @@ -2003,7 +2003,7 @@ ALTER TEXT SEARCH CONFIGURATION russian 分类词典示例 - 考虑简单的天文词库 thesaurus_astro,其中包含一些天文单词组合: + 考虑简单的天文词库 thesaurus_astro,其中包含一些天文单词组合: supernovae stars : sn @@ -2438,7 +2438,7 @@ ts_debug( config re - 以下是一个简单的示例: + 以下是一个简单的示例: SELECT * FROM ts_debug('english', 'a fat cat sat on a mat - it ate a fat rats'); diff --git a/zh/13/trigger.sgml b/zh/13/trigger.sgml index 5f3c8854..a8a54a4b 100644 --- a/zh/13/trigger.sgml +++ b/zh/13/trigger.sgml @@ -4,7 +4,7 @@ 触发器 - trigger + 触发器 @@ -128,18 +128,18 @@ 生成列还有一些额外注意事项。 - generated column在触发器中 + 生成列在触发器中 存储型生成列会在 BEFORE 触发器之后、AFTER 触发器之前计算。因此,可以在 AFTER 触发器中检查生成值。在 BEFORE 触发器中,OLD 行如预期那样包含旧的 生成值,但 NEW 行尚未包含新的生成值,因此不应访问。对于 C 语言接口,此时该列内容未定义;更高层编程语言应阻止在 BEFORE 触发器中访问 NEW 行中的存储型 - 生成列。在 BEFORE 触发器中对生成列值所做的修改会被忽略并随后被覆盖。虚拟生成列在触发器触发时永远不会被计算。在 C 语言接口中,它们在触发器函数中的内容是未定义的;更高层编程语言应阻止在触发器中访问虚拟生成列。 + 生成列。在 BEFORE 触发器中对生成列值所做的修改会被忽略并随后被覆盖。 - 如果在同一关系上的同一事件为其定义了多个触发器,它们会按触发器名称的字母顺序触发。对于 BEFOREINSTEAD OF + 如果为同一关系上的同一事件定义了多个触发器,它们会按触发器名称的字母顺序触发。对于 BEFOREINSTEAD OF 触发器,每个触发器返回的、可能已经被修改过的行都会成为下一个触发器的输入。如果任何一个 BEFOREINSTEAD OF 触发器返回 NULL,则会放弃对该行执行该操作,并且后续触发器(针对该行)都不会再触发。 @@ -168,8 +168,8 @@ - trigger - arguments for trigger functions + 触发器 + 触发器函数的参数 在定义触发器时,可以为它指定参数。在触发器定义中包含参数,是为了让需求相似的不同触发器能够调用同一个函数。举例来说,可以有一个通用触发器函数,它接受两个列名作为参数,把当前用户写入其中一个列,把当前时间戳写入另一个列。只要编写得当,这个触发器函数就应独立于它所作用的具体表。因此,同一个函数可用于任何具有适当列的表上的 INSERT 事件,例如自动跟踪某个事务表中记录的创建。如果把它定义成 UPDATE 触发器,还可以用来跟踪最近更新事件。 @@ -195,7 +195,10 @@ 数据更改的可见性 - 如果你在触发器函数中执行 SQL 命令,而且这些命令访问的是该触发器所在的表,那么就需要了解数据可见性规则,因为这些规则决定了这些 SQL 命令能否看到导致该触发器触发的数据更改。简要来说: + + 如果你在触发器函数中执行 SQL 命令,而这些命令又访问该触发器所属的表,就需要了解数据可见性规则,因为这些规则决定了这些 SQL 命令是否能看到引发触发器的数据更改。简而言之: + + @@ -249,13 +252,13 @@ 用 C 编写触发器函数 - trigger - in C + 触发器 + 在 C 中 - transition tables - referencing from C trigger + 过渡表 + 从 C 触发器中引用 @@ -267,7 +270,7 @@ - 当函数由触发器管理器调用时,不会向它传递任何普通参数,但会传递一个指向 TriggerData 结构体的 context 指针。C 函数可以通过执行下列宏来检查自己是否由触发器管理器调用: + 当函数由触发器管理器调用时,不会向它传递任何普通参数,但会传递一个指向 TriggerData 结构体的 上下文 指针。C 函数可以通过执行下列宏来检查自己是否由触发器管理器调用: CALLED_AS_TRIGGER(fcinfo) @@ -283,7 +286,8 @@ CALLED_AS_TRIGGER(fcinfo) - struct TriggerData定义在commands/trigger.h: + struct TriggerData 定义在 + commands/trigger.h 中: typedef struct TriggerData @@ -300,7 +304,11 @@ typedef struct TriggerData Tuplestorestate *tg_newtable; const Bitmapset *tg_updatedcols; } TriggerData; -其中各成员的定义如下: + + + 其中各成员定义如下: + + type @@ -313,14 +321,15 @@ typedef struct TriggerData tg_event - 描述调用该函数所对应的事件。可以使用下列宏来检查tg_event: + + 描述调用函数的事件。可以使用以下宏检查 tg_event TRIGGER_FIRED_BEFORE(tg_event) - 如果触发器在操作之前触发,则返回 true。 + 如果触发器在操作之前触发,则返回真。 @@ -329,7 +338,7 @@ typedef struct TriggerData TRIGGER_FIRED_AFTER(tg_event) - 如果触发器在操作之后触发,则返回 true。 + 如果触发器在操作之后触发,则返回真。 @@ -338,7 +347,7 @@ typedef struct TriggerData TRIGGER_FIRED_INSTEAD(tg_event) - 如果触发器是取代该操作而触发,则返回 true。 + 如果触发器是取代该操作而触发,则返回真。 @@ -347,7 +356,7 @@ typedef struct TriggerData TRIGGER_FIRED_FOR_ROW(tg_event) - 如果触发器是因行级事件触发,则返回 true。 + 如果触发器是因行级事件触发,则返回真。 @@ -356,7 +365,7 @@ typedef struct TriggerData TRIGGER_FIRED_FOR_STATEMENT(tg_event) - 如果触发器是因语句级事件触发,则返回 true。 + 如果触发器是因语句级事件触发,则返回真。 @@ -365,7 +374,7 @@ typedef struct TriggerData TRIGGER_FIRED_BY_INSERT(tg_event) - 如果触发器是由 INSERT 命令触发,则返回 true。 + 如果触发器是由 INSERT 命令触发,则返回真。 @@ -374,7 +383,7 @@ typedef struct TriggerData TRIGGER_FIRED_BY_UPDATE(tg_event) - 如果触发器是由 UPDATE 命令触发,则返回 true。 + 如果触发器是由 UPDATE 命令触发,则返回真。 @@ -383,7 +392,7 @@ typedef struct TriggerData TRIGGER_FIRED_BY_DELETE(tg_event) - 如果触发器是由 DELETE 命令触发,则返回 true。 + 如果触发器是由 DELETE 命令触发,则返回真。 @@ -392,7 +401,7 @@ typedef struct TriggerData TRIGGER_FIRED_BY_TRUNCATE(tg_event) - 如果触发器是由 TRUNCATE 命令触发,则返回 true。 + 如果触发器是由 TRUNCATE 命令触发,则返回真。 @@ -439,7 +448,9 @@ typedef struct TriggerData tg_trigger - 一个指向Trigger类型结构体的指针,该结构体定义在utils/reltrigger.h: + + 一个指向 Trigger 类型结构体的指针,该结构体定义在 + utils/reltrigger.h 中: typedef struct Trigger @@ -464,7 +475,13 @@ typedef struct Trigger char *tgoldtable; char *tgnewtable; } Trigger; -其中tgname是触发器名称,tgnargstgargs中参数的数量,而tgargs是一个指针数组,指向CREATE TRIGGER语句中指定的参数。其他成员仅供内部使用。 + + + 其中 tgname 是触发器名称, + tgnargstgargs + 中参数的数量,而 tgargs 是一个指针数组,指向 + CREATE TRIGGER 语句中指定的参数。其他成员仅供内部使用。 + @@ -543,16 +560,16 @@ typedef struct Trigger - 一个完整的触发器实例 + 一个完整的触发器示例 这里给出一个非常简单的、用 C 编写的触发器函数示例。(用过程语言编写的触发器示例可见各过程语言的文档。) - 如果某条命令试图向列 x 中插入空值,函数 - trigf 就会报告表 ttest - 中的行数,并跳过实际操作。(这样,这个触发器就起到了非空约束的作用,但不会中止事务。) + 函数 trigf 会报告表 ttest 中的行数, + 并在命令试图向列 x 中插入空值时跳过实际操作。 + (这样,这个触发器就起到了非空约束的作用,但不会中止事务。) @@ -564,7 +581,9 @@ CREATE TABLE ttest ( - 这是触发器函数的源代码: + 下面是触发器函数的源代码: + - 编译完源代码后(参见),声明函数和触发器: + + 编译完这段源代码之后(见 ),声明该函数和这些触发器: + CREATE FUNCTION trigf() RETURNS trigger AS 'filename' LANGUAGE C; diff --git a/zh/13/typeconv.sgml b/zh/13/typeconv.sgml index 75fc5271..6ee4b641 100644 --- a/zh/13/typeconv.sgml +++ b/zh/13/typeconv.sgml @@ -28,7 +28,7 @@ -PostgreSQL扫描器/解析器将词法元素分成五个基本类别:整数、非整数数字、字符串、标识符和关键字。大多数非数值类型的常量会先被归类为字符串。SQL语言定义允许用字符串指定类型名,而PostgreSQL可以利用这一机制让解析器从一开始就沿着正确的路径处理。例如,查询: +PostgreSQL扫描器/解析器将词法元素分成五个基本类别:整数、非整数数字、字符串、标识符和关键字。大多数非数值类型的常量会先被归类为字符串。SQL语言定义允许给字符串指定类型名,而PostgreSQL可以利用这一机制让解析器从一开始就沿着正确的路径处理。例如,查询: SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; @@ -39,11 +39,11 @@ SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; (1 row) -包含两个文字常量,它们的类型分别是textpoint。如果没有为某个字符串文字指定类型,那么它最初会被赋予占位类型unknown,并在后文所述的后续阶段解析。 +包含两个字面量,它们的类型分别是textpoint。如果没有为某个字符串字面量指定类型,那么它最初会被赋予占位类型unknown,并在后文所述的后续阶段解析。 -有四种基本的 SQL 结构需要在 PostgreSQL 解析器中使用不同的类型转换规则: +在PostgreSQL解析器中,有四种基本的SQL结构需要采用不同的类型转换规则: @@ -82,7 +82,7 @@ SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; -由于经合并的SELECT语句的所有查询结果都必须出现在同一组列中,因此每个SELECT子句的结果类型必须彼此匹配,并转换为统一的一组类型。类似地,CASE结构中的结果表达式必须转换为某种公共类型,这样整个CASE表达式才有确定的输出类型。其他一些结构,如ARRAY[]以及GREATESTLEAST函数,也同样需要为若干子表达式确定公共类型。 +由于经UNION合并的SELECT语句的所有查询结果都必须出现在同一组列中,因此每个SELECT子句的结果类型必须彼此匹配,并转换为统一的一组类型。类似地,CASE结构中的结果表达式必须转换为某种公共类型,这样整个CASE表达式才有确定的输出类型。其他一些结构,如ARRAY[]以及GREATESTLEAST函数,也同样需要为若干子表达式确定公共类型。 @@ -161,11 +161,11 @@ SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; -检查是否存在一个恰好接受输入参数类型的操作符。如果存在(在被考虑的操作符集合中至多只有一个精确匹配),就使用它。若通过限定名调用(这种情况并不常见)某个允许不可信用户创建对象的模式中的操作符,而又缺少精确匹配,就会带来安全隐患 +检查是否存在一个恰好接受输入参数类型的操作符。如果存在(在被考虑的操作符集合中至多只有一个精确匹配),就使用它。若通过限定名调用(这种情况并不常见)某个允许不受信任的用户创建对象的模式中的操作符,而又缺少精确匹配,就会带来安全隐患 - 对于未带模式限定的名称,不会出现这种隐患,因为包含允许不可信用户创建对象的模式的搜索路径不是一种模式的安全使用方式。 + 对于未带模式限定的名称,不会出现这种隐患,因为包含允许不受信任的用户创建对象的模式的搜索路径不是一种模式的安全使用方式。 。在这种情况下,应通过对参数进行类型转换来强制获得精确匹配。 @@ -180,7 +180,7 @@ SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; -如果二元操作符调用的一个参数是unknown类型,而另一个是域类型,则接着检查是否存在两边都恰好接受该域基类型的操作符;如果有,就使用它。 +如果二元操作符调用的一个参数是unknown类型,而另一个是域类型,则接着检查是否存在两边都恰好接受该域基础类型的操作符;如果有,就使用它。 @@ -194,13 +194,13 @@ SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; -丢弃那些输入类型不匹配,且也无法通过隐式类型转换实现匹配的候选操作符。为此,假定unknown文字可以转换为任何类型。如果只剩一个候选操作符,就使用它;否则继续下一步。 +丢弃那些输入类型不匹配,且也无法通过隐式类型转换实现匹配的候选操作符。为此,假定unknown字面量可以转换为任何类型。如果只剩一个候选操作符,就使用它;否则继续下一步。 -如果任何输入参数是域类型,则在后续所有步骤中都把它当作该域的基类型。这样可以确保在解决操作符歧义时,域的行为与其基类型一致。 +如果任何输入参数是域类型,则在后续所有步骤中都把它当作该域的基础类型。这样可以确保在解决操作符歧义时,域的行为与其基础类型一致。 @@ -212,12 +212,12 @@ SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; -遍历所有候选操作符,保留那些在需要类型转换的最多位置上接受首选类型(属于输入数据类型的类型分类)的候选项。如果没有候选项接受首选类型,则保留全部候选项。如果只剩一个候选操作符,就使用它;否则继续下一步。 +遍历所有候选操作符,在需要类型转换的位置上,保留接受首选类型(属于输入数据类型的类型分类)的位置数最多的候选项。如果没有候选项接受首选类型,则保留全部候选项。如果只剩一个候选操作符,就使用它;否则继续下一步。 -如果有任何输入参数是unknown,就检查剩余候选项在这些参数位置上接受哪些类型分类。在每个位置上,如果有任何候选项接受string分类,就选择该分类。(这种偏向字符串的做法是合适的,因为unknown类型的文字看起来像字符串。)否则,如果所有剩余候选项都接受同一种类型分类,就选择该分类;否则失败,因为在缺少更多线索的情况下无法推断出正确选择。然后丢弃不接受所选类型分类的候选项。此外,如果有任何候选项接受该分类中的首选类型,就丢弃在该参数上接受非首选类型的候选项。如果没有候选项通过这些测试,则保留全部候选项。如果只剩一个候选项,就使用它;否则继续下一步。 +如果有任何输入参数是unknown,就检查剩余候选操作符在这些参数位置上接受哪些类型分类。在每个位置上,如果有任何候选项接受string分类,就选择该分类。(这种偏向字符串的做法是合适的,因为unknown类型的字面量看起来像字符串。)否则,如果所有剩余候选项都接受同一种类型分类,就选择该分类;否则失败,因为在缺少更多线索的情况下无法推断出正确选择。然后丢弃不接受所选类型分类的候选项。此外,如果有任何候选项接受该分类中的首选类型,就丢弃在该参数上接受非首选类型的候选项。如果没有候选项通过这些测试,则保留全部候选项。如果只剩一个候选操作符,就使用它;否则继续下一步。 @@ -237,8 +237,8 @@ SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; 平方根操作符类型解析 -标准目录中只定义了一个平方根操作符(前缀|/),它接受一个类型为 -double precision 的参数。扫描器为以下查询表达式中的参数赋予初始类型 integer: + +标准目录中只定义了一个平方根操作符(前缀|/),它接受一个double precision类型的参数。在下面这个查询表达式中,扫描器会把该参数的初始类型指定为integer SELECT |/ 40 AS "square root of 40"; square root of 40 @@ -247,7 +247,7 @@ SELECT |/ 40 AS "square root of 40"; (1 row) -因此,解析器会对操作数进行类型转换,该查询等价于: +因此,解析器会对操作数执行一次类型转换,该查询等价于: SELECT |/ CAST(40 AS double precision) AS "square root of 40"; @@ -263,7 +263,7 @@ SELECT |/ CAST(40 AS double precision) AS "square root of 40"; -一个只有一个未指定参数的例子: +一个参数未指定类型的例子: SELECT text 'abc' || 'def' AS "text and unknown"; @@ -291,7 +291,7 @@ SELECT 'abc' || 'def' AS "unspecified"; -这里对使用哪种类型没有初始提示,因为查询中没有指定任何类型。因此,解析器会查找所有候选操作符,并发现既有接受字符串分类输入的候选项,也有接受位串分类输入的候选项。由于在可用时优先选择字符串分类,所以会选中该分类,再使用字符串的首选类型text作为解析这些unknown类型文字的具体类型。 +这里对使用哪种类型没有初始提示,因为查询中没有指定任何类型。因此,解析器会查找所有候选操作符,并发现既有接受字符串分类输入的候选项,也有接受位串分类输入的候选项。由于在可用时优先选择字符串分类,所以会选中该分类,再使用字符串的首选类型text作为解析这些unknown类型字面量的具体类型。 @@ -299,7 +299,7 @@ SELECT 'abc' || 'def' AS "unspecified"; 绝对值与取反操作符类型解析 -在 PostgreSQL 操作符目录中,前缀操作符 @ 有多个条目,分别实现各种数值数据类型的绝对值运算。其中一个条目用于类型 float8,它是数值分类中的首选类型。因此,PostgreSQL 会使用该条目来处理 unknown 输入: +PostgreSQL操作符目录中为前缀操作符@提供了多个条目,它们分别实现各种数值数据类型的绝对值操作。其中一个条目对应float8,它是数值分类中的首选类型。因此,当遇到一个unknown输入时,PostgreSQL会使用该条目: SELECT @ '-4.5' AS "abs"; abs @@ -307,7 +307,7 @@ SELECT @ '-4.5' AS "abs"; 4.5 (1 row) -这里,系统在应用所选操作符之前,已将 unknown 类型文字隐式解析为 float8 类型。我们可以验证所使用的是 float8 而不是其他类型: +这里,系统在应用所选操作符之前,已经把unknown类型字面量隐式解析为float8。我们可以验证使用的确实是float8,而不是其他类型: SELECT @ '-4.5e500' AS "abs"; @@ -349,8 +349,7 @@ SELECT array[1,2] <@ '{1,2,3}' as "is subset"; t (1 row) -在 PostgreSQL 操作符目录中,中缀操作符 <@ 有多个条目,但可能接受左侧为整数数组的只有两个:数组包含(anyarray <@ anyarray)和范围包含(anyelement <@ anyrange)。由于这些多态伪类型(见 )都不是首选类型,解析器无法据此消除歧义。不过, 要求它假定 unknown 类型文字与另一个输入的类型相同,即整数数组。这样,两个操作符中只有一个能够匹配,因此会选择数组包含。(如果选择了范围包含,就会得到错误,因为该字符串的格式不符合范围文字的要求。) +PostgreSQL操作符目录中为中缀操作符<@定义了多个条目,但左侧能够接受整数数组的只有两种:数组包含(anyarray <@ anyarray)和范围包含(anyelement <@ anyrange)。由于这些多态伪类型(见)都不被视为首选类型,解析器无法据此消除歧义。不过,要求它假定unknown类型字面量与另一输入具有相同类型,也就是整数数组。这样两个操作符中只有一个能够匹配,因此会选择数组包含。(如果选中范围包含,就会报错,因为该字符串的格式并不是合法的范围字面量。) @@ -359,7 +358,7 @@ linkend="datatype-pseudo"/>)都不是首选类型,解析器无法据此消 域类型上的自定义操作符 -用户有时会尝试声明只适用于某个域类型的操作符。这是可行的,但远没有看上去那样有用,因为操作符解析规则被设计成优先选择作用于域基类型的操作符。考虑下面的例子: +用户有时会尝试声明只适用于某个域类型的操作符。这是可行的,但远没有看上去那样有用,因为操作符解析规则被设计成优先选择作用于域基础类型的操作符。考虑下面的例子: CREATE DOMAIN mytext AS text CHECK(...); CREATE FUNCTION mytext_eq_text (mytext, text) RETURNS boolean AS ...; @@ -368,11 +367,11 @@ CREATE TABLE mytable (val mytext); SELECT * FROM mytable WHERE val = 'foo'; -这个查询不会使用自定义操作符。解析器首先会检查是否存在mytext = mytext操作符(),但并不存在;然后它会考虑该域的基类型text,并检查是否存在text = text操作符(),而这是存在的;于是它会把unknown类型的文字解析为text,并使用text = text操作符。要让自定义操作符被使用,唯一的方法是显式地对该文字做类型转换: +这个查询不会使用自定义操作符。解析器首先会检查是否存在mytext = mytext操作符(),但并不存在;然后它会考虑该域的基础类型text,并检查是否存在text = text操作符(),而这是存在的;于是它会把unknown类型的字面量解析为text,并使用text = text操作符。要让自定义操作符被使用,唯一的方法是显式地对该字面量做类型转换: SELECT * FROM mytable WHERE val = text 'foo'; -这样就会根据精确匹配规则立即找到mytext = text操作符。如果解析过程进入最佳匹配规则,它们会主动排斥作用于域类型的操作符。如果不是这样,这类操作符会导致过多的操作符歧义失败,因为类型转换规则总是把域视为可以转换到其基类型或从其基类型转换而来,因此域操作符会在所有与基类型上同名操作符相同的场景中都被视为可用。 +这样就会根据精确匹配规则立即找到mytext = text操作符。如果解析过程进入最佳匹配规则,它们会主动排斥作用于域类型的操作符。如果不是这样,这类操作符会导致过多的操作符歧义失败,因为类型转换规则总是把域视为可以转换到其基础类型或从其基础类型转换而来,因此域操作符会在所有与基础类型上同名操作符相同的场景中都被视为可用。 @@ -407,26 +406,26 @@ SELECT * FROM mytable WHERE val = text 'foo'; -如果函数声明了一个VARIADIC数组参数,而调用时没有使用VARIADIC关键字,则把该函数视为其数组参数按需要被其元素类型的一个或多个出现所替换,以匹配该调用。扩展之后,该函数的有效参数类型可能与某个非可变参数函数完全相同。在这种情况下,使用搜索路径中较早出现的函数;如果两个函数位于同一模式,则优先选择非可变参数函数。 +如果函数声明了一个VARIADIC数组参数,而调用时没有使用VARIADIC关键字,则把数组参数视为一个或多个其元素类型的参数,个数按匹配该调用的需要确定。扩展之后,该函数的有效参数类型可能与某个非VARIADIC函数完全相同。在这种情况下,使用搜索路径中较早出现的函数;如果两个函数位于同一模式,则优先选择非VARIADIC函数。 -通过限定名调用某个允许不可信用户创建对象的模式中找到的可变参数函数时,会带来安全隐患 +通过限定名调用某个允许不受信任的用户创建对象的模式中找到的可变参数函数时,会带来安全隐患 - 对于未带模式限定的名称,不会出现这种隐患,因为包含允许不可信用户创建对象的模式的搜索路径不是一种模式的安全使用方式。 + 对于未带模式限定的名称,不会出现这种隐患,因为包含允许不受信任的用户创建对象的模式的搜索路径不是一种模式的安全使用方式。 - 。恶意用户可以借此劫持调用,并以你的身份执行任意 SQL 函数。改为使用带有VARIADIC关键字的调用可以绕过这一隐患。对于填充VARIADIC "any"参数的调用,往往没有包含VARIADIC关键字的等价写法。要安全地发出这类调用,该函数所在模式必须只允许可信用户创建对象。 + 。恶意用户可以借此劫持调用,并以你的身份执行任意 SQL 函数。改为使用带有VARIADIC关键字的调用可以绕过这一隐患。对于填充VARIADIC "any"参数的调用,往往没有包含VARIADIC关键字的等价写法。要安全地发出这类调用,该函数所在模式必须只允许受信任的用户创建对象。 -带有参数默认值的函数,被认为可以匹配任何省略了零个或多个可默认参数位置的调用。如果不止一个这样的函数能匹配某个调用,则使用搜索路径中最早出现的那一个。如果同一模式中存在两个或更多这样的函数,并且它们在未使用默认值的参数位置上的参数类型相同(如果它们具有不同的可默认参数集合,这种情况是可能的),系统就无法判断该偏好哪一个;如果找不到更好的匹配,就会报有歧义的函数调用错误。 +带有参数默认值的函数,被认为可以匹配任何省略了零个或多个可使用默认值的参数位置的调用。如果不止一个这样的函数能匹配某个调用,则使用搜索路径中最早出现的那一个。如果同一模式中存在两个或更多这样的函数,并且它们在未使用默认值的参数位置上的参数类型相同(如果它们具有不同的带有默认值的参数集合,这种情况是可能的),系统就无法判断该偏好哪一个;如果找不到更好的匹配,就会报有歧义的函数调用错误。 -通过限定名调用某个允许不可信用户创建对象的模式中的任意函数时,会带来可用性隐患。恶意用户可以用现有函数的名字创建一个新函数,复制该函数的参数,并附加带有默认值的新参数。这样就会阻止对原始函数的新调用。为避免这种隐患,应把函数放在只允许可信用户创建对象的模式中。 +通过限定名调用某个允许不受信任的用户创建对象的模式中的任意函数时,会带来可用性隐患。恶意用户可以用现有函数的名字创建一个新函数,复制该函数的参数,并附加带有默认值的新参数。这样就会阻止对原始函数的新调用。为避免这种隐患,应把函数放在只允许受信任的用户创建对象的模式中。 @@ -435,13 +434,13 @@ SELECT * FROM mytable WHERE val = text 'foo'; -检查是否存在一个恰好接受输入参数类型的函数。如果存在(在被考虑的函数集合中至多只有一个精确匹配),就使用它。若通过限定名调用某个允许不可信用户创建对象的模式中的函数,而又缺少精确匹配,就会带来安全隐患。在这种情况下,应通过对参数进行类型转换来强制获得精确匹配。(涉及unknown的情况在这一步永远找不到匹配。) +检查是否存在一个恰好接受输入参数类型的函数。如果存在(在被考虑的函数集合中至多只有一个精确匹配),就使用它。若通过限定名调用某个允许不受信任的用户创建对象的模式中的函数,而又缺少精确匹配,就会带来安全隐患。在这种情况下,应通过对参数进行类型转换来强制获得精确匹配。(涉及unknown的情况在这一步永远找不到匹配。) -如果没有找到精确匹配,就检查该函数调用是否看起来像一种特殊的类型转换请求。这种情况发生在:函数调用只有一个参数,且函数名与某个数据类型的(内部)名称相同。此外,函数参数必须是unknown类型文字,或者是一种到该命名数据类型二进制可强制转换的类型,或者是一种可以通过应用其 I/O 函数转换为该命名数据类型的类型(也就是说,该转换要么转到某种标准字符串类型,要么从某种标准字符串类型转来)。满足这些条件时,该函数调用会被当作一种CAST形式。 +如果没有找到精确匹配,就检查该函数调用是否看起来像一种特殊的类型转换请求。这种情况发生在:函数调用只有一个参数,且函数名与某个数据类型的(内部)名称相同。此外,函数参数必须是unknown类型字面量,或者是一种可以二进制强制转换为该命名数据类型的类型,或者是一种可以通过应用其 I/O 函数转换为该命名数据类型的类型(也就是说,该转换要么转到某种标准字符串类型,要么从某种标准字符串类型转来)。满足这些条件时,该函数调用会被当作一种CAST形式。 之所以有这一步,是为了在不存在实际类型转换函数的情况下仍支持函数风格的类型转换写法。如果存在类型转换函数,按惯例它会以其输出类型命名,因此无需为此设置特殊情况。更多说明见。 @@ -457,13 +456,13 @@ SELECT * FROM mytable WHERE val = text 'foo'; -丢弃那些输入类型不匹配,且也无法通过隐式类型转换实现匹配的候选函数。为此,假定unknown文字可以转换为任何类型。如果只剩一个候选函数,就使用它;否则继续下一步。 +丢弃那些输入类型不匹配,且也无法通过隐式类型转换实现匹配的候选函数。为此,假定unknown字面量可以转换为任何类型。如果只剩一个候选函数,就使用它;否则继续下一步。 -如果任何输入参数是域类型,则在后续所有步骤中都把它当作该域的基类型。这样可以确保在解决函数歧义时,域的行为与其基类型一致。 +如果任何输入参数是域类型,则在后续所有步骤中都把它当作该域的基础类型。这样可以确保在解决函数歧义时,域的行为与其基础类型一致。 @@ -475,12 +474,12 @@ SELECT * FROM mytable WHERE val = text 'foo'; -遍历所有候选函数,保留那些在需要类型转换的最多位置上接受首选类型(属于输入数据类型的类型分类)的候选项。如果没有候选项接受首选类型,则保留全部候选项。如果只剩一个候选函数,就使用它;否则继续下一步。 +遍历所有候选函数,在需要类型转换的位置上,保留接受首选类型(属于输入数据类型的类型分类)的位置数最多的候选项。如果没有候选项接受首选类型,则保留全部候选项。如果只剩一个候选函数,就使用它;否则继续下一步。 -如果有任何输入参数是unknown,就检查剩余候选项在这些参数位置上接受哪些类型分类。在每个位置上,如果有任何候选项接受string分类,就选择该分类。(这种偏向字符串的做法是合适的,因为unknown类型的文字看起来像字符串。)否则,如果所有剩余候选项都接受同一种类型分类,就选择该分类;否则失败,因为在缺少更多线索的情况下无法推断出正确选择。然后丢弃不接受所选类型分类的候选项。此外,如果有任何候选项接受该分类中的首选类型,就丢弃在该参数上接受非首选类型的候选项。如果没有候选项通过这些测试,则保留全部候选项。如果只剩一个候选项,就使用它;否则继续下一步。 +如果有任何输入参数是unknown,就检查剩余候选函数在这些参数位置上接受哪些类型分类。在每个位置上,如果有任何候选项接受string分类,就选择该分类。(这种偏向字符串的做法是合适的,因为unknown类型的字面量看起来像字符串。)否则,如果所有剩余候选项都接受同一种类型分类,就选择该分类;否则失败,因为在缺少更多线索的情况下无法推断出正确选择。然后丢弃不接受所选类型分类的候选项。此外,如果有任何候选项接受该分类中的首选类型,就丢弃在该参数上接受非首选类型的候选项。如果没有候选项通过这些测试,则保留全部候选项。如果只剩一个候选函数,就使用它;否则继续下一步。 @@ -537,7 +536,7 @@ CREATE FUNCTION public.variadic_example(VARIADIC numeric[]) RETURNS int CREATE FUNCTION -此函数接受 VARIADIC 关键字,但不要求使用它。它可以接受 integer 和 numeric 参数: +这个函数接受但不要求使用VARIADIC关键字。它既能接受integer参数,也能接受numeric参数: SELECT public.variadic_example(0), @@ -549,7 +548,7 @@ SELECT public.variadic_example(0), (1 row) -不过,如果有更具体的函数,前两个调用会优先选择它们: +但是,如果有更具体的函数可用,第一和第二个调用会优先选择它们: CREATE FUNCTION public.variadic_example(numeric) RETURNS int @@ -569,7 +568,7 @@ SELECT public.variadic_example(0), (1 row) -在默认配置下,如果只存在第一个函数,前两个调用是不安全的。任何用户都可以通过创建第二个或第三个函数来截获它们。由于精确匹配参数类型并使用了 VARIADIC 关键字,第三个调用是安全的。 +在默认配置下,且只存在第一个函数时,第一和第二个调用并不安全。任何用户都可以通过创建第二个或第三个函数来劫持它们。第三个调用由于参数类型精确匹配且使用了VARIADIC关键字,因此是安全的。 @@ -657,7 +656,7 @@ SELECT substr(CAST (1234 AS text), 3); -否则,尝试把表达式转换为目标类型。如果这两种类型之间在pg_cast目录中登记了赋值类型转换(见),就可以这样做。另一种情况是,如果表达式是unknown类型文字,则会把文字字符串的内容送入目标类型的输入转换例程。 +否则,尝试把表达式转换为目标类型。如果这两种类型之间在pg_cast目录中登记了赋值类型转换(见),就可以这样做。另一种情况是,如果表达式是unknown类型字面量,则会把字符串字面量的内容送入目标类型的输入转换例程。 @@ -689,7 +688,7 @@ SELECT v, octet_length(v) FROM vv; -这里实际发生的是,两个unknown类型文字默认都被解析为text,从而使||操作符被解析为text的连接操作。然后,操作符得到的text结果被转换为bpcharblank-padded char,即character数据类型的内部名称),以匹配目标列类型。(由于从textbpchar的转换是二进制可强制转换的,这一步不会插入任何真实的函数调用。)最后,系统目录中找到尺寸调整函数bpchar(bpchar, integer, boolean),并把它应用到操作符结果以及存储列长度上。这个特定于类型的函数会执行所需的长度检查并补齐填充空格。 +这里实际发生的是,两个unknown类型字面量默认都被解析为text,从而使||操作符被解析为text的连接操作。然后,操作符得到的text结果被转换为bpchar用空格填充的字符,blank-padded char,即character数据类型的内部名称),以匹配目标列类型。(由于从textbpchar的转换是二进制可强制转换的,这一步不会插入任何真实的函数调用。)最后,系统从系统目录中找到尺寸调整函数bpchar(bpchar, integer, boolean),并把它应用到操作符结果以及存储列长度上。这个特定于类型的函数会执行所需的长度检查并补齐填充空格。 @@ -744,10 +743,10 @@ SQL 的UNION结构必须让可能不同的类型彼此匹配 -如果任何输入是域类型,则在后续所有步骤中都把它当作该域的基类型。 +如果任何输入是域类型,则在后续所有步骤中都把它当作该域的基础类型。 - 这在某种程度上类似于操作符和函数对域输入的处理方式;只要用户确保所有输入都隐式或显式地正好属于该域类型,这种行为就能让域类型在UNION或类似结构中得以保留。否则,就会使用该域的基类型。 + 这在某种程度上类似于操作符和函数对域输入的处理方式;只要用户确保所有输入都隐式或显式地正好属于该域类型,这种行为就能让域类型在UNION或类似结构中得以保留。否则,就会使用该域的基础类型。 @@ -762,13 +761,13 @@ SQL 的UNION结构必须让可能不同的类型彼此匹配 -如果非unknown输入并非全都属于同一类型分类,则失败。 +如果非unknown输入并非全都属于同一类型分类,则失败。 -选择第一个非unknown输入的类型作为候选类型,然后按从左到右的顺序考虑其余每个非unknown输入类型。 +选择第一个非unknown输入的类型作为候选类型,然后按从左到右的顺序考虑其余每个非unknown输入类型。 出于历史原因,CASE会把其ELSE子句(如果有)视为第一个输入,THEN子句则在其后考虑。其他所有情况中,从左到右都指表达式在查询文本中出现的顺序。 @@ -791,7 +790,7 @@ SQL 的UNION结构必须让可能不同的类型彼此匹配 -UNION 中未充分指定类型时的类型解析 +<literal>UNION</literal> 中未充分指定类型时的类型解析 @@ -803,12 +802,12 @@ SELECT text 'a' AS "text" UNION SELECT 'b'; b (2 rows) -这里,unknown 类型文字 'b' 将被解析为类型 text。 +这里,unknown类型字面量'b'会被解析为text类型。 -简单 UNION 中的类型解析 +简单 <literal>UNION</literal> 中的类型解析 @@ -820,12 +819,12 @@ SELECT 1.2 AS "numeric" UNION SELECT 1; 1.2 (2 rows) -文字常量1.2的类型是numeric,而integer1可以隐式转换为numeric,因此使用该类型。 +字面量1.2的类型是numeric,而integer1可以隐式转换为numeric,因此使用该类型。 -次序对调的 UNION 中的类型解析 +次序对调的 <literal>UNION</literal> 中的类型解析 @@ -837,12 +836,12 @@ SELECT 1 AS "real" UNION SELECT CAST('2.2' AS REAL); 2.2 (2 rows) -这里,由于类型 real 不能隐式转换为 integer,但 integer 可以隐式转换为 real,因此合并结果类型被解析为 real。 +这里,由于real类型不能隐式转换为integer,而integer可以隐式转换为real,因此UNION结果类型被解析为real -嵌套 UNION 中的类型解析 +嵌套 <literal>UNION</literal> 中的类型解析 @@ -872,17 +871,17 @@ ERROR: UNION types text and integer cannot be matched -前面各节给出的规则会为 SQL 查询中的所有表达式赋予非 unknown 数据类型,但作为 SELECT 命令的简单输出列出现的未指定类型文字除外。例如,在 +前面各节给出的规则会为 SQL 查询中的所有表达式赋予非 unknown 数据类型,但作为 SELECT 命令的简单输出列出现的未指定类型字面量除外。例如,在 SELECT 'Hello World'; -中,没有任何信息可用于确定应将该字符串文字视为什么类型。在这种情况下,PostgreSQL 会回退为将该文字的类型解析为 text。 +中,没有任何信息可用于确定应将该字符串字面量视为什么类型。在这种情况下,PostgreSQL 会回退为将该字面量的类型解析为 text -当SELECTUNION(或INTERSECTEXCEPT)结构的一端,或者出现在INSERT ... SELECT中时,这条规则不适用,因为前面各节给出的规则具有更高优先级。在前一种情况下,未指定类型文字的类型可以从UNION的另一侧取得;在后一种情况下,则从目标列取得。 +当SELECTUNION(或INTERSECTEXCEPT)结构的一端,或者出现在INSERT ... SELECT中时,这条规则不适用,因为前面各节给出的规则具有更高优先级。在前一种情况下,未指定类型字面量的类型可以从UNION的另一侧取得;在后一种情况下,则从目标列取得。 @@ -892,7 +891,7 @@ SELECT 'Hello World'; - 在PostgreSQL 10 之前,这条规则并不存在,SELECT输出列表中的未指定类型文字会被保留为unknown类型。这会带来各种不良后果,因此后来做了修改。 + 在PostgreSQL 10 之前,这条规则并不存在,SELECT输出列表中的未指定类型字面量会被保留为unknown类型。这会带来各种不良后果,因此后来做了修改。 diff --git a/zh/13/user-manag.sgml b/zh/13/user-manag.sgml index 4210c6a8..a3bd1abc 100644 --- a/zh/13/user-manag.sgml +++ b/zh/13/user-manag.sgml @@ -71,7 +71,7 @@ SELECT rolname FROM pg_roles; - 为了完成数据库系统的初始引导,一个刚初始化的系统总会包含一个预定义的可登录角色。该角色总是一个超级用户,并且除非另行指定了不同名称,否则它的名称与用initdb初始化数据库集簇的操作系统用户相同。这个角色通常命名为postgres。要创建更多角色,必须先以这个初始角色建立连接。 + 为了完成数据库系统的初始引导,一个刚初始化的系统总会包含一个预定义角色。该角色总是一个超级用户,并且除非另行指定了不同名称,否则它的名称与用initdb初始化数据库集簇的操作系统用户相同。这个角色通常命名为postgres。要创建更多角色,必须先以这个初始角色建立连接。 @@ -94,12 +94,12 @@ SELECT rolname FROM pg_roles; 登录权限登录权限 - 只有具有 LOGIN 属性的角色才能用作数据库连接的初始角色名。具有 LOGIN 属性的角色可以视为数据库用户。要创建具有登录权限的角色,可以使用以下任一命令: + 只有具有LOGIN属性的角色才能用作数据库连接的初始角色名。具有LOGIN属性的角色可以被视为数据库用户。要创建具有登录权限的角色,可使用以下任一方式: CREATE ROLE name LOGIN; CREATE USER name; - (CREATE USER 等价于 CREATE ROLE,区别在于 CREATE USER 包含 LOGIN,而 CREATE ROLE 不会如此。) + (CREATE USER等价于CREATE ROLE,不同之处只在于CREATE USER默认包含LOGIN,而CREATE ROLE不包含。) @@ -196,13 +196,12 @@ CREATE USER name; - 角色还可以为 中描述的许多运行时配置设置指定角色专属的默认值。例如,如果出于某种原因,你希望每次连接时都禁用索引扫描(提示:这不是一个好主意),可以使用: + 角色还可以为中描述的许多运行时配置设置指定角色特定默认值。例如,如果出于某种原因你希望每次连接时都禁用索引扫描(提示:这不是个好主意),你可以使用: ALTER ROLE myname SET enable_indexscan TO off; - 这会保存该设置(但不会立即设置它)。此角色后续建立的连接就好像在会话开始前刚执行过 SET enable_indexscan TO off 一样。在会话期间仍然可以更改这一设置;它只是默认值。要移除角色专属的默认设置,请使用 - ALTER ROLE rolename RESET varname。请注意,附加在没有 LOGIN 权限的角色上的角色专属默认值几乎没有用处,因为它们永远不会被调用。 + 这会保存该设置(但不会立即生效)。在该角色后续建立的连接中,它看起来就像在会话开始之前执行了SET enable_indexscan TO off一样。你仍然可以在会话期间更改该设置;它只会作为默认值。要移除角色特定默认设置,使用ALTER ROLE rolename RESET varname。注意,附加到没有LOGIN权限的角色上的角色特定默认值几乎没有用,因为它们永远不会生效。 @@ -309,12 +308,12 @@ ALTER TABLE bobs_table OWNER TO alice; - 一旦有价值的对象都已转移给新拥有者,被删除角色所拥有的其余对象即可使用命令删除。同样,由于该命令不能访问其他数据库中的对象,因此必须在包含该角色所拥有对象的每个数据库中运行它。另外,DROP + 一旦有价值的对象都已转移给新拥有者,待删除角色所拥有的其余对象即可使用命令删除。同样,由于该命令不能访问其他数据库中的对象,因此必须在包含该角色所拥有对象的每个数据库中运行它。另外,DROP OWNED不会删除整个数据库或表空间,因此如果该角色拥有任何尚未转移给新拥有者的数据库或表空间,就必须手工删除它们。 - DROP OWNED还会负责移除授予目标角色、但不属于它自身对象的任何权限。由于REASSIGN OWNED不会处理这类对象,所以通常需要同时运行REASSIGN OWNEDDROP OWNED(按这个顺序!),才能完整移除待删除角色的依赖关系。 + DROP OWNED还会负责移除目标角色在其他角色所拥有的对象上获授的所有权限。由于REASSIGN OWNED不会处理这类对象,所以通常需要同时运行REASSIGN OWNEDDROP OWNED(按这个顺序!),才能完整移除待删除角色的依赖关系。 @@ -369,7 +368,7 @@ DROP ROLE doomed_role; pg_read_all_stats - 读取所有 pg_stat_* 视图,并使用各种与统计信息相关的扩展,即使是那些通常仅对超级用户可见的扩展。 + 读取所有 pg_stat_* 视图,并使用各种与统计信息相关的扩展,包括通常仅对超级用户可见的内容。 pg_stat_scan_tables @@ -408,11 +407,11 @@ DROP ROLE doomed_role; - pg_read_server_filespg_write_server_filespg_execute_server_program角色旨在让管理员能够创建受信任但非超级用户的角色,使其能够以数据库运行所用用户的身份访问文件并在数据库服务器上运行程序。由于这些角色能够访问服务器文件系统上的任意文件,它们在直接访问文件时会绕过所有数据库级权限检查,并且可被用来获得超级用户级别的访问能力,因此向用户授予这些角色时必须极其谨慎。 + pg_read_server_filespg_write_server_filespg_execute_server_program角色旨在让管理员能够使受信任但非超级用户的角色能够以数据库运行所用用户的身份访问文件并在数据库服务器上运行程序。由于这些角色能够访问服务器文件系统上的任意文件,它们在直接访问文件时会绕过所有数据库级权限检查,并且可被用来获得超级用户级别的访问能力,因此向用户授予这些角色时必须极其谨慎。 - 授予这些角色时应当谨慎,确保它们只在需要时使用,并理解这些角色会授予对特权信息的访问。 + 授予这些角色时应当谨慎,确保它们只在需要时使用,并理解这些角色会授予对需要特权才能访问的信息的访问。 @@ -429,7 +428,7 @@ GRANT pg_signal_backend TO admin_user; 函数安全性 - 函数、触发器和行级安全策略允许用户把代码插入后端服务器,而其他用户可能会无意中执行这些代码。因此,这些机制使用户能够相对容易地对其他用户实施特洛伊木马攻击。最强的保护方式是严格控制谁能定义对象。如果这不可行,则应编写只引用拥有者可信对象的查询,并从search_path中移除任何允许不受信任用户创建对象的模式。 + 函数、触发器和行级安全策略允许用户把代码插入后端服务器,而其他用户可能会无意中执行这些代码。因此,这些机制使用户能够相对容易地对其他用户实施特洛伊木马攻击。最强的保护方式是严格控制谁能定义对象。如果这不可行,则应编写只引用拥有者可信的对象的查询,并从search_path中移除 public 模式以及任何其他允许不受信任用户创建对象的模式。 diff --git a/zh/13/vacuumlo.sgml b/zh/13/vacuumlo.sgml index 46e231ff..cabeb08c 100644 --- a/zh/13/vacuumlo.sgml +++ b/zh/13/vacuumlo.sgml @@ -8,7 +8,7 @@ vacuumlo 1 - Application + 应用程序 diff --git a/zh/13/wal.sgml b/zh/13/wal.sgml index c2558c79..3348a810 100644 --- a/zh/13/wal.sgml +++ b/zh/13/wal.sgml @@ -349,9 +349,9 @@ 检查点检查点 是事务序列中的一些点,在这些点上可以保证堆和索引数据文件已经用检查点之前写入 - 的全部信息进行了更新。执行检查点时,所有脏数据页都会刷写到磁盘,并向 WAL - 文件写入一条特殊的检查点记录。(更改记录此前已经刷入 WAL - 文件。)如果发生崩溃,崩溃恢复过程会查看最新的检查点记录,以确定应该从 WAL + 的全部信息进行了更新。执行检查点时,所有脏数据页都会刷盘,并向 WAL + 文件写入一条特殊的检查点记录。(更改记录此前已写入 WAL + 文件并刷盘。)如果发生崩溃,崩溃恢复过程会查看最新的检查点记录,以确定应该从 WAL 的哪个位置(称为重做记录)开始执行 REDO。该点之前对数据文件所做的任何更改 都保证已经在磁盘上。因此,检查点之后,位于包含重做记录的段之前的 WAL 段不再需要, 可以被回收或删除。(若正在执行 WAL 归档,则这些 WAL 段必 @@ -379,7 +379,7 @@ 减小 checkpoint_timeout 和/或 max_wal_size 会让检查点更频繁地发生。这样可以加快崩溃后 - 恢复,因为需要重做的工作更少。不过,这必须与更频繁刷写脏数据页所增加的成本 + 恢复,因为需要重做的工作更少。不过,这必须与更频繁地将脏数据页刷盘所增加的成本 权衡。如果设置了 (默认就是如此), 还要考虑另一个因素。为了保证数据页一致性,每个检查点之后对某个数据页的首次 修改,都会导致把整页内容写入日志。在这种情况下,更短的检查点间隔会增加输出到 @@ -417,7 +417,7 @@ 在 Linux 和 POSIX 平台上, - 允许在检查点写出的操作系统页面达到可配置的字节数后,强制把它们刷到磁盘。 + 允许在检查点写出的操作系统页面达到可配置的字节数后,强制将它们刷盘。 否则,这些页面可能会停留在操作系统页缓存中,从而在检查点末尾发出 fsync 时引发停顿。这个设置通常有助于降低事务延迟,但也可能 对性能产生不利影响,尤其是在工作负载大于 @@ -453,7 +453,7 @@ 在归档恢复或备库模式下,服务器会周期性地执行 重启点重启点, - 其行为类似于正常运行时的检查点:服务器会强制把自身状态写盘,更新 + 其行为类似于正常运行时的检查点:服务器会强制将其所有状态刷盘,更新 pg_control 文件,以表明已经处理过的 WAL 数据无需再次 扫描,然后回收 pg_wal 目录中的旧 WAL 段文件。重启点的 执行频率不会高于主库上的检查点,因为重启点只能在检查点记录处执行。当到达某条检查点记录且距离上次重启点 @@ -476,7 +476,7 @@ 快。更糟的是,写 WAL 缓冲区还可能迫使系统创建新的 WAL 段, 这会花费更多时间。正常情况下,WAL 缓冲区应由 XLogFlush 请求负责写出并刷盘; - 该请求大多发生在事务提交时,以确保事务记录被刷入持久存储。在 WAL 输出量很高 + 该请求大多发生在事务提交时,以确保事务记录已刷盘至持久存储。在 WAL 输出量很高 的系统上,XLogFlush 请求可能不够频繁,无法避免 XLogInsertRecord 自己去执行写出。在这种系统上,应增加 WAL 缓冲区的数量,具体做法是修改参数 @@ -532,9 +532,9 @@ 参数 决定 PostgreSQL 将如何请求内核把 - WAL 更新强制刷到磁盘。就可靠性而言,所有选项应当都是相同 + WAL 更新强制刷盘。就可靠性而言,所有选项应当都是相同 的;例外是 fsync_writethrough,它有时能够在其他选项做不 - 到时强制刷新磁盘缓存。不过,具体哪个选项速度最快则高度依赖平台。可以使用 + 到时强制将磁盘缓存中的数据刷盘。不过,具体哪个选项速度最快则高度依赖平台。可以使用 程序测试不同选项的速度。请注意,如果 fsync 已被关闭,那么这个参数就没有意义。 diff --git a/zh/13/xaggr.sgml b/zh/13/xaggr.sgml index 8d6eb399..b2293d67 100644 --- a/zh/13/xaggr.sgml +++ b/zh/13/xaggr.sgml @@ -42,11 +42,11 @@ SELECT sum(a) FROM test_complex; - 如果没有非空输入值,上述sum定义将返回零(即初始状态值)。也许我们更希望在这种情况下返回空值 — SQL 标准要求sum这样做。实现这一点只需省略initcond短语,使初始状态值为空。通常这意味着sfunc需要检查输入的状态值是否为空。但对于sum以及maxmin这类其他简单聚合,只需把第一个非空输入值放入状态变量,然后从第二个非空输入值开始应用转移函数即可。如果初始状态值为空,并且转移函数被标记为strict(即不会对空输入调用),PostgreSQL会自动这样做。 + 如果没有非空输入值,上述sum定义将返回零(即初始状态值)。也许我们更希望在这种情况下返回空值 — SQL 标准要求sum这样做。实现这一点只需省略initcond短语,使初始状态值为空值。通常这意味着sfunc需要检查输入的状态值是否为空值。但对于sum以及maxmin这类其他简单聚合,只需把第一个非空输入值放入状态变量,然后从第二个非空输入值开始应用转移函数即可。如果初始状态值为空值,并且转移函数被标记为strict(即不会对空值输入调用),PostgreSQL会自动这样做。 - strict转移函数的另一项默认行为是,只要遇到空输入值,就会保留先前的状态值不变。因此,空值会被忽略。如果你需要对空输入采用其他行为,就不要把转移函数声明为 strict,而应在函数代码中自行检测空输入并完成所需处理。 + strict转移函数的另一项默认行为是,只要遇到空值输入,就会保留先前的状态值不变。因此,空值会被忽略。如果你需要对空值输入采用其他行为,就不要把转移函数声明为 strict,而应在函数代码中自行检测空值输入并完成所需处理。 @@ -71,7 +71,7 @@ CREATE AGGREGATE avg (float8)
- SQL 中的聚合函数调用允许使用DISTINCTORDER BY选项,以控制哪些行会传递给聚合的转移函数,以及传递顺序。这些选项是在后台实现的,并不是聚合支持函数需要关心的事情。 + SQL 中的聚合函数调用允许使用DISTINCTORDER BY选项,以控制哪些行会传递给聚合的转移函数,以及传递顺序。这些选项由系统在内部实现,并不是聚合支持函数需要关心的事情。 @@ -283,7 +283,7 @@ SELECT percentile_disc(0.5) WITHIN GROUP (ORDER BY income) FROM households; - 与普通聚合不同,有序集聚合的输入行排序不是在幕后完成的,而是由聚合的支持函数负责。典型的实现方法是在聚合的状态值中保存一个tuplesort对象的引用,把输入行送入该对象,然后在最终函数中完成排序并读出数据。这样的设计使最终函数可以执行特殊操作,例如向待排序数据中注入额外的假想行。普通聚合通常可以使用由PL/pgSQL或其他 PL 语言编写的支持函数来实现,但有序集聚合通常必须用 C 编写,因为它们的状态值无法定义为任何 SQL 数据类型。(在上面的示例中,注意状态值被声明为internal类型,这很典型。)另外,由于最终函数执行了排序,之后就不可能再通过再次执行转移函数来继续加入输入行。这意味着最终函数不是READ_ONLY;在中,必须将其声明为READ_WRITE,或者如果额外的最终函数调用能够利用已经排好序的状态,则声明为SHAREABLE。 + 与普通聚合不同,有序集聚合的输入行排序不是由系统在内部完成的,而是由聚合的支持函数负责。典型的实现方法是在聚合的状态值中保存一个tuplesort对象的引用,把输入行送入该对象,然后在最终函数中完成排序并读出数据。这样的设计使最终函数可以执行特殊操作,例如向待排序数据中注入额外的假想行。普通聚合通常可以使用由PL/pgSQL或其他 PL 语言编写的支持函数来实现,但有序集聚合通常必须用 C 编写,因为它们的状态值无法定义为任何 SQL 数据类型。(在上面的示例中,注意状态值被声明为internal类型,这很典型。)另外,由于最终函数执行了排序,之后就不可能再通过再次执行转移函数来继续加入输入行。这意味着最终函数不是READ_ONLY;在中,必须将其声明为READ_WRITE,或者如果额外的最终函数调用能够利用已经排好序的状态,则声明为SHAREABLE @@ -347,12 +347,16 @@ SELECT percentile_disc(0.5) WITHIN GROUP (ORDER BY income) FROM households; 支持函数 - 用 C 编写的函数可以通过调用AggCheckCallContext来检测自己是否作为聚合支持函数被调用,例如: + + 用 C 编写的函数可以通过调用AggCheckCallContext来检测自己是否作为聚合支持函数被调用,例如: + if (AggCheckCallContext(fcinfo, NULL)) -进行这种检查的一个原因是:如果结果为真,第一个输入必然是一个临时状态值,因此可以安全地原地修改,而不必分配新的副本。示例可见 int8inc()。(虽然聚合状态转移函数总是允许原地修改状态值,但通常不鼓励聚合最终函数这样做;如果它确实这样做,则必须在创建聚合时声明这种行为。更多细节见 。) + + 进行这种检查的一个原因是:如果结果为真,第一个输入必然是一个临时状态值,因此可以安全地原地修改,而不必分配新的副本。示例可见int8inc()。(虽然聚合转移函数总是允许原地修改状态值,但通常不鼓励聚合最终函数这样做;如果它确实这样做,则必须在创建聚合时声明这种行为。更多细节见。) + - AggCheckCallContext的第二个参数可用于取得保存聚合状态值的内存上下文。这对于希望把扩展对象(见)用作状态值的转移函数很有用。第一次调用时,转移函数应返回一个扩展对象,其内存上下文是聚合状态上下文的子上下文;之后的调用则持续返回同一个扩展对象。示例见array_append()。(array_append()并不是任何内置聚合的转移函数,但它的写法保证了在用作自定义聚合的转移函数时也能高效工作。) + AggCheckCallContext的第二个参数可用于取得保存聚合状态值的内存上下文。这对于希望把展开对象(见)用作状态值的转移函数很有用。第一次调用时,转移函数应返回一个展开对象,其内存上下文是聚合状态上下文的子上下文;之后的调用则持续返回同一个展开对象。示例见array_append()。(array_append()并不是任何内置聚合的转移函数,但它的写法保证了在用作自定义聚合的转移函数时也能高效工作。) diff --git a/zh/13/xfunc.sgml b/zh/13/xfunc.sgml index 80a0ba36..d89a0e9a 100644 --- a/zh/13/xfunc.sgml +++ b/zh/13/xfunc.sgml @@ -4,8 +4,8 @@ 用户定义的函数 - function - user-defined + 函数 + 用户定义的 @@ -36,11 +36,11 @@ - 每一类函数可以采用基本类型、复合类型或者它们的组合作为参数。此外,每一类函数可以返回一个基本类型或一个复合类型。函数也能被定义成返回基本类型或复合类型值的集合。 + 每一类函数可以采用基础类型、复合类型或者它们的组合作为参数。此外,每一类函数可以返回一个基础类型或一个复合类型。函数也能被定义成返回基础类型或复合类型值的集合。 - 很多类函数可以接受或者返回特定的伪类型(例如,多态类型),但是可用的功能会变化。详情可以参考每一种函数的描述。 + 很多类函数可以接受或者返回特定的伪类型(例如,多态类型),但是可用的功能因函数类别而异。详情可以参考每一种函数的描述。 定义SQL函数最容易,因此我们将从讨论它们开始。大部分SQL函数的概念也能用到其他类型的函数上。 @@ -55,8 +55,8 @@ 用户定义的过程 - procedure - user-defined + 过程 + 用户定义的 过程是一个类似于函数的数据库对象。关键差异是: @@ -95,7 +95,7 @@ - 函数和过程一起构成了例程routine。 + 函数和过程统称为例程例程。 有这样的命令可以操作函数和过程而不需要知道它们是哪一种。 不过,要注意没有CREATE ROUTINE命令。 @@ -107,7 +107,7 @@ 函数 用户定义的 - in SQL + 在 SQL 中 @@ -121,7 +121,7 @@ SQL 函数的函数体必须是一个由分号分隔的 SQL 语句列表。最后一条语句后的分号是可选的。除非该函数被声明为返回 void,否则最后一条语句必须是 SELECT,或者是 INSERTUPDATEDELETE 并带有 RETURNING 子句。 任意一组 SQL 语言命令都可以打包并定义成函数。除 SELECT 查询外,这些命令还可以包含数据修改查询(INSERT, - UPDATEDELETE),以及其他 SQL 命令。(不能使用事务控制命令,例如 COMMITSAVEPOINT,以及某些实用命令,例如 VACUUM,来编写 SQL 函数。)不过,最后一条命令必须是 SELECT,或者带有 RETURNING 子句,并返回与函数声明返回类型相符的结果。或者,如果你想定义一个执行动作但没有有用返回值的 SQL 函数,也可以把它定义为返回 void。例如,下面这个函数会删除 emp 表中薪资为负的行: + UPDATEDELETE),以及其他 SQL 命令。(不能使用事务控制命令,例如 COMMITSAVEPOINT,以及某些工具命令,例如 VACUUM,来编写 SQL 函数。)不过,最后一条命令必须是 SELECT,或者带有 RETURNING 子句,并返回与函数声明返回类型相符的结果。或者,如果你想定义一个执行动作但没有有用返回值的 SQL 函数,也可以把它定义为返回 void。例如,下面这个函数会删除 emp 表中薪资为负的行: CREATE FUNCTION clean_emp() RETURNS void AS ' DELETE FROM emp WHERE salary < 0; @@ -190,10 +190,10 @@ INSERT INTO $1 VALUES (42); - 基本类型上的<acronym>SQL</acronym>函数 + 基础类型上的<acronym>SQL</acronym>函数 - 最简单的 SQL 函数没有参数,只是返回一个基本类型,例如 + 最简单的 SQL 函数没有参数,只是返回一个基础类型,例如 integer @@ -219,7 +219,7 @@ SELECT one(); - 定义接受基本类型参数的 SQL 函数也几乎同样容易: + 定义接受基础类型参数的 SQL 函数也几乎同样容易: CREATE FUNCTION add_em(x integer, y integer) RETURNS integer AS $$ @@ -344,17 +344,17 @@ SELECT name, double_salary(emp.*) AS dream 注意这里用 $1.salary 语法来选取参数行值中的一个字段。 还要注意,调用时的 SELECT 命令使用 - table_name.* 将表的当前整行取作一个组合值。该表行也可以仅用表名来引用: + table_name.* 将表的当前整行取作一个复合值。该表行也可以仅用表名来引用: SELECT name, double_salary(emp) AS dream FROM emp WHERE emp.cubicle ~= point '(2,1)'; - 但这种用法已被废弃,因为它很容易让人混淆(关于表行组合值这两种记法的更多细节,见)。 + 但这种用法已被弃用,因为它很容易让人混淆(关于表行复合值这两种记法的更多细节,见)。 - 有时候即时构造一个组合参数会很方便。这可以用ROW构造器完成。 + 有时候即时构造一个复合参数值会很方便。这可以用ROW构造器完成。 例如,我们可以调整被传递给函数的数据: SELECT name, double_salary(ROW(name, salary*1.1, age, cubicle)) AS dream @@ -377,10 +377,13 @@ $$ LANGUAGE SQL; 在这个示例中,我们为每一个属性指定了一个常量值,但是可以用任何计算来替换这些常量。 - 定义该函数时要注意两件重要的事情: + + 定义该函数时有两点重要注意事项: + + - 查询中的选择列表顺序必须与列在复合类型中出现的顺序完全相同。(正如我们上面所做的那样,命名列与系统无关。) + 查询中的选择列表顺序必须与列在复合类型中出现的顺序完全相同。(系统不考虑像上面这样指定的列名。) @@ -392,17 +395,27 @@ ERROR: return type mismatch in function declared to return emp DETAIL: Final statement returns text instead of point at column 4. - 与基本类型的情况一样,系统不会自动插入显式转换,只会插入隐式或赋值转换。 + 与基础类型的情况一样,系统不会自动插入显式转换,只会插入隐式或赋值转换。 - 定义同一个函数的另一种方法是: + + 定义同样的函数的一种不同的方法是: + + CREATE FUNCTION new_emp() RETURNS emp AS $$ SELECT ROW('None', 1000.0, 25, '(2,2)')::emp; $$ LANGUAGE SQL; -这里我们编写了一个 SELECT,使其只返回一个具有正确复合类型的列。在这个场景中,这种方式并没有更好,但在某些情况下它是一种方便的替代方法 — 例如,需要调用另一个返回所需复合值的函数来计算结果时。另一个例子是,如果要编写的函数返回复合类型上的域,而不是普通的复合类型,就始终必须将其写成返回单列的形式,因为无法对整行结果进行强制类型转换。 + + + 这里我们写了一个只返回单列、且该列具有正确复合类型的 SELECT。 + 在这种场景下,这样写并不见得更好,但在某些情况下会很方便 + — 例如,需要通过调用另一个返回目标复合值的函数来计算结果时。 + 还有一种情况是,如果我们要编写的函数返回的是基于复合类型的域,而不是普通复合类型, + 那么就必须写成返回单列的形式,因为没有办法让整行结果发生所需的强制转换。 + 我们既可以把这个函数直接当作值表达式调用: @@ -464,7 +477,7 @@ SELECT name(new_emp()); - 另一种使用函数返回复合类型的方法是将结果传递给另一个接受正确行类型作为输入的函数: + 另一种使用函数返回复合类型的方法是将结果传递给另一个接受正确行类型作为输入的函数: CREATE FUNCTION getname(emp) RETURNS text AS $$ @@ -552,12 +565,12 @@ DROP FUNCTION sum_n_product (int, int); 带有可变数量参数的<acronym>SQL</acronym>函数 - function - variadic + 函数 + 可变参数 - variadic function + 可变参数函数 @@ -588,27 +601,27 @@ SELECT mleast(ARRAY[10, -1, 5, 4.4]); -- doesn't work - 有时候,能够把一个已经构造好的数组传给 variadic 函数会很有用,尤其是当一个 variadic 函数想把它的数组参数再传给另一个函数时。此外,在允许不受信任用户创建对象的模式中调用 variadic 函数时,这是唯一安全的方式,见。你可以在调用中指定VARIADIC来做到这一点: + 有时候,能够把一个已经构造好的数组传给可变参数函数会很有用,尤其是当一个可变参数函数想把它的数组参数再传给另一个函数时。此外,在允许不受信任用户创建对象的模式中调用可变参数函数时,这是唯一安全的方式,见。你可以在调用中指定VARIADIC来做到这一点: SELECT mleast(VARIADIC ARRAY[10, -1, 5, 4.4]); - 这样会阻止函数的 variadic 参数按其元素类型展开,从而让数组实参能够按常规方式匹配。VARIADIC 只能附加在函数调用的最后一个实参上。 + 这样会阻止函数的可变参数按其元素类型展开,从而让数组实参能够按常规方式匹配。VARIADIC 只能附加在函数调用的最后一个实参上。 - 在调用中指定VARIADIC也是向 variadic 函数传递空数组的唯一方式,例如: + 在调用中指定VARIADIC也是向可变参数函数传递空数组的唯一方式,例如: SELECT mleast(VARIADIC ARRAY[]::numeric[]); - 仅仅写成SELECT mleast()是行不通的,因为 variadic 参数必须匹配至少一个实参。(如果你希望允许这种调用,可以再定义一个同名且不带参数的函数mleast。) + 仅仅写成SELECT mleast()是行不通的,因为可变参数必须匹配至少一个实参。(如果你希望允许这种调用,可以再定义一个同名且不带参数的函数mleast。) - 从 variadic 参数派生出的数组元素参数会被视为没有自己的名字。这意味着除非你指定了 VARIADIC,否则不能使用命名参数来调用 variadic 函数()。例如,下面的调用是可行的: + 从可变参数派生出的数组元素参数会被视为没有自己的名字。这意味着除非你指定了 VARIADIC,否则不能使用命名参数来调用可变参数函数()。例如,下面的调用是可行的: SELECT mleast(VARIADIC arr => ARRAY[10, -1, 5, 4.4]); @@ -627,7 +640,7 @@ SELECT mleast(arr => ARRAY[10, -1, 5, 4.4]); 带有参数默认值的<acronym>SQL</acronym>函数 - function + 函数 参数的默认值 @@ -636,7 +649,7 @@ SELECT mleast(arr => ARRAY[10, -1, 5, 4.4]); 没有给出足够多的实参,就会插入默认值来弥补缺失的实参。由于参数只 能从实参列表的尾部开始被省略,在一个有默认值的参数之后的所有参数 都不得不也具有默认值(尽管使用命名参数记法可以允许放松这种限制, - 这种限制仍然会被强制以便位置参数记法能工作)。不管你是否使用它,这种能力都要求在某些用户不信任其他用户的数据中调用函数时做一些预防措施,见。 + 这种限制仍然会被强制以便位置参数记法能工作)。不管你是否使用它,这种能力都要求在某些用户不信任其他用户的数据库中调用函数时做一些预防措施,见 @@ -679,13 +692,13 @@ ERROR: function foo() does not exist 所有的 SQL 函数都可以被用在查询的FROM子句中,但是 - 对于返回复合类型的函数特别有用。如果函数被定义为返回一种基本类型, + 对于返回复合类型的函数特别有用。如果函数被定义为返回一种基础类型, 该表函数会产生一个单列表。如果该函数被定义为返回一种复合类型,该 表函数会为该复合类型的每一个属性产生一列。 - 以下是一个示例: + 以下是一个示例: CREATE TABLE foo (fooid int, foosubid int, fooname text); @@ -718,8 +731,8 @@ SELECT *, upper(fooname) FROM getfoo(1) AS t1; 返回集合的<acronym>SQL</acronym>函数 - function - with SETOF + 函数 + 使用 SETOF @@ -844,11 +857,16 @@ SELECT name, listchildren(name) FROM nodes; - PostgreSQL对查询选择列表中的集合返回函数的处理方式,几乎与将该函数写在 LATERAL FROM 子句项中时完全相同。例如, + PostgreSQL中,写在查询的选择列表中的集合返回函数的行为几乎和写在LATERAL FROM子句项中的集合返回函数完全一样。例如: + SELECT x, generate_series(1,5) AS g FROM tab; -几乎等价于 + + 几乎等效于 + SELECT x, g FROM tab, LATERAL generate_series(1,5) AS g; -两者本应完全相同,但在这个特定示例中,规划器可以选择将 g 放在嵌套循环连接的外侧,因为 g 实际上并不横向依赖于 tab。这会导致不同的输出行顺序。选择列表中的集合返回函数总是按位于嵌套循环连接内侧的方式求值,与之连接的是其余的 FROM 子句其余部分的嵌套循环连接的内侧,因此在考虑 FROM 子句的下一行之前,这些函数都会运行到完成。 + + 这会是完全一样的,除了在这个特别的示例中,规划器可以选择把g放在嵌套循环连接的外侧,因为gtab没有实际的横向依赖。那会导致一种不同的输出行顺序。选择列表中的集合返回函数总是会被计算,就好像它们在FROM子句剩余部分的嵌套循环连接的内侧一样,因此在考虑来自FROM子句的下一行之前,这些函数会运行到完成。 + 如果在查询的选择列表中有不止一个集合返回函数,则行为类似于把那些函数放到一个单一的LATERAL ROWS FROM( ... ) FROM子句项中的行为。对于来自底层查询的每一行,都有一个用到每个函数首个结果的输出行,然后是一个使用每个函数第二个结果的输出行,以此类推。如果某些集合返回函数产生的输出比其他函数少,会用空值代替缺失的数据,因此为一个底层行形成的总行数等于产生最多输出的集合返回函数的输出行数。因此集合返回函数会步调一致地运行直到它们的输出被耗尽,然后用下一个底层行继续执行。 @@ -867,7 +885,7 @@ SELECT srf1(srf2(x), srf3(y)), srf4(srf5(z)) FROM tab; SELECT x, CASE WHEN x > 0 THEN generate_series(1, 5) ELSE 0 END FROM tab; - 看起来这个语句应该产生满足x > 0的输入行的五次重复,以及不满足的行的一次重复。但实际上,由于在CASE表达时被计算前,generate_series(1, 5)会被运行在一个隐式的LATERAL FROM项中,它会为每个输入行产生五次重复。为了减少混乱,这类情况会产生一个解析时错误。 + 看起来这个语句应该产生满足x > 0的输入行的五次重复,以及不满足的行的一次重复。但实际上,由于在CASE表达式被计算前,generate_series(1, 5)会被运行在一个隐式的LATERAL FROM项中,它会为每个输入行产生五次重复。为了减少混乱,这类情况会产生一个解析时错误。 @@ -879,11 +897,11 @@ SELECT x, CASE WHEN x > 0 THEN generate_series(1, 5) ELSE 0 END FROM tab; 在 PostgreSQL 10 之前,除非多个集合返回函数始终产生相同数量的行,否则把它们放在同一个选择列表中的行为并不合理。 否则,得到的输出行数会是这些集合返回函数各自产生行数的最小公倍数。 此外,嵌套的集合返回函数也不像上文所描述的那样工作;相反,一个集合返回函数至多只能有一个集合返回参数, - 并且每一层嵌套都会独立运行。再加上过去还允许条件执行(即在 CASE 等结构内部使用集合返回函数), + 并且每一组嵌套的集合返回函数都会独立运行。再加上过去还允许条件执行(即在 CASE 等结构内部使用集合返回函数), 事情就更加复杂了。 如果你要编写需要在旧版 PostgreSQL 上运行的查询,建议使用 LATERAL 语法, 因为这样在不同版本之间能够得到一致的结果。 - 如果你的查询依赖于集合返回函数的条件执行,可以把条件判断移动到自定义集合返回函数内部来修复。例如, + 如果你的查询依赖于集合返回函数的条件执行,或许可以把条件判断移动到自定义集合返回函数内部来修复。例如, SELECT x, CASE WHEN y > 0 THEN generate_series(1, z) ELSE 5 END FROM tab; @@ -901,7 +919,7 @@ END$$ LANGUAGE plpgsql; SELECT x, case_generate_series(y > 0, 1, z, 5) FROM tab; - 这种写法在所有版本的 PostgreSQL 中都能正常工作。 + 这种写法在所有版本的 PostgreSQL 中的行为都相同。 @@ -910,7 +928,7 @@ SELECT x, case_generate_series(y > 0, 1, z, 5) FROM tab; 返回<literal>TABLE</literal>的<acronym>SQL</acronym>函数 - function + 函数 RETURNS TABLE @@ -959,10 +977,9 @@ SELECT make_array(1, 2) AS intarray, make_array('a'::text, 'b') AS textarray; 注意类型转换'a'::text的使用是为了指定该参数的类型 - 是text。如果该参数只是一个字符串这就是必须的,因为 + 是text。如果该参数只是一个字符串字面量,这就是必须的,因为 否则它会被当作unknown类型,并且 - unknown的数组也不是一种合法的类型。如果没有改类型 - 类型转换,将得到这样的错误: + unknown的数组也不是一种合法的类型。如果没有该类型转换,将得到这样的错误: ERROR: could not determine polymorphic type because input has type unknown @@ -1033,7 +1050,7 @@ SELECT * FROM dup(22); - 多态也可以用于 variadic 函数。例如: + 多态也可以用于可变参数函数。例如: CREATE FUNCTION anyleast (VARIADIC anyarray) RETURNS anyelement AS $$ SELECT min($1[i]) FROM generate_subscripts($1, 1) g(i); @@ -1068,11 +1085,11 @@ SELECT concat_values('|', 1, 4, 2); 带有排序规则的<acronym>SQL</acronym>函数 - collation - in SQL functions + 排序规则 + 在 SQL 函数中 - 当一个 SQL 函数有一个或多个可设定排序规则的数据类型参数时,会根据实参所带的排序规则,为每次函数调用确定一个排序规则,详见 。如果能够成功确定(也就是说,参数之间不存在隐式排序规则冲突),那么所有可设定排序规则的参数都会被视为隐式带有该排序规则。这会影响函数中对排序规则敏感的操作的行为。例如,使用上文的 anyleast 函数时, + 当一个 SQL 函数有一个或多个支持排序规则的数据类型参数时,会根据实参所带的排序规则,为每次函数调用确定一个排序规则,详见 。如果能够成功确定(也就是说,参数之间不存在隐式排序规则冲突),那么所有支持排序规则的参数都会被视为隐式带有该排序规则。这会影响函数中对排序规则敏感的操作的行为。例如,使用上文的 anyleast 函数时, SELECT anyleast('abc'::text, 'ABC'); 的结果将取决于数据库的默认排序规则。在 C 区域设置下,结果会是 ABC,但在许多其他区域设置下则会是 abc。可以在任意参数上添加 COLLATE 子句来强制指定要使用的排序规则,例如: SELECT anyleast('abc'::text, 'ABC' COLLATE "C"); @@ -1080,7 +1097,7 @@ SELECT anyleast('abc'::text, 'ABC' COLLATE "C"); CREATE FUNCTION anyleast (VARIADIC anyarray) RETURNS anyelement AS $$ SELECT min($1[i] COLLATE "en_US") FROM generate_subscripts($1, 1) g(i); $$ LANGUAGE SQL; -但请注意,如果把它用于不可设定排序规则的数据类型,就会抛出错误。 +但请注意,如果把它用于不支持排序规则的数据类型,就会抛出错误。 如果无法在实参之间确定共同的排序规则,那么 SQL 函数会把参数视为带有其数据类型的默认排序规则 @@ -1088,7 +1105,7 @@ $$ LANGUAGE SQL; - 这种可设定排序规则参数的行为,可以看作是仅适用于文本数据类型的一种受限多态形式。 + 这种支持排序规则的参数的行为,可以看作是仅适用于文本数据类型的一种受限多态形式。 @@ -1097,8 +1114,8 @@ $$ LANGUAGE SQL; 函数重载 - overloading - functions + 重载 + 函数 @@ -1130,10 +1147,10 @@ CREATE FUNCTION test(smallint, double precision) RETURNS ... - 另一类可能的冲突发生在 variadic 函数和非 variadic 函数之间。例如,可以同时创建 + 另一类可能的冲突发生在可变参数函数和非可变参数函数之间。例如,可以同时创建 foo(numeric)foo(VARIADIC numeric[])。 这时,对于只提供一个 numeric 参数的调用(例如 foo(10.1)),就不清楚该匹配哪个函数。 - 规则是:优先使用在搜索路径中出现较早的那个函数;如果两者位于同一模式中,则优先使用非 variadic 函数。 + 规则是:优先使用在搜索路径中出现较早的那个函数;如果两者位于同一模式中,则优先使用非可变参数函数。 @@ -1160,8 +1177,8 @@ CREATE FUNCTION test(int, int) RETURNS int 函数易变性分类 - volatility - functions + 易变性 + 函数 VOLATILE @@ -1178,7 +1195,7 @@ CREATE FUNCTION test(int, int) RETURNS int 一个VOLATILE函数可以做任何事情,包括修改数据库。在 使用相同的参数连续调用时,它能返回不同的结果。优化器不会对这类函 - 数的行为做任何假定。对于在每一行都需要 volatile 函数值的查询,函数都会被重新求值。 + 数的行为做任何假定。使用易变函数的查询会在需要该函数值的每一行上重新对它求值。 @@ -1226,8 +1243,7 @@ CREATE FUNCTION test(int, int) RETURNS int 在考虑先规划然后立即执行的简单交互式查询时,在STABLEIMMUTABLE分类间的区别相对较小:一个函数是在规划时只 执行一次还是在查询执行开始期间只执行一次没有太大关系。但是如果计划 - 被保存下来然后在后面被重用,区别就大了。如果在不允许过早把一个函数 - 变成规划期间的一个常数时把它标记为IMMUTABLE,会导致 + 被保存下来然后在后面被重用,区别就大了。如果把一个实际上并非不可变的函数标记为IMMUTABLE,就可能在规划期间过早将它折叠成常量,导致 在后续重用该计划时继续使用陈旧的值。在使用预备语句,或使用会缓存执行计划的函数语言(如 PL/pgSQL)时,这会带来严重问题。 @@ -1295,7 +1311,7 @@ CREATE FUNCTION test(int, int) RETURNS int 内部函数 - functioninternal + 函数内部 内部函数由 C 编写并且已经被静态链接到PostgreSQL @@ -1333,9 +1349,9 @@ CREATE FUNCTION square_root(double precision) RETURNS double precision C 语言函数 - function - user-defined - in C + 函数 + 用户定义的 + 在 C 中 @@ -1359,17 +1375,17 @@ CREATE FUNCTION square_root(double precision) RETURNS double precision - 在一个会话中第一次调用一个特定可载入对象文件中的用户定义函数时, - 动态载入器会把那个对象文件载入到内存以便该函数被调用。因此用户 + 在一个会话中第一次调用一个特定可载入目标文件中的用户定义函数时, + 动态载入器会把那个目标文件载入到内存以便该函数被调用。因此用户 定义的 C 函数的CREATE FUNCTION必须 - 为该函数指定两块信息:可载入对象文件的名称,以及要在该对象文件中 + 为该函数指定两块信息:可载入目标文件的名称,以及要在该目标文件中 调用的特定函数的 C 名称(链接符号)。如果没有显式指定 C 名称,则 它被假定为和 SQL 函数名相同。 下面的算法被用来基于CREATE FUNCTION - 命令中给定的名称来定位共享对象文件: + 命令中给定的名称来定位共享目标文件: @@ -1428,16 +1444,17 @@ CREATE FUNCTION square_root(double precision) RETURNS double precision PostgreSQL不会自动编译 C 函数。在 - 从CREATE FUNCTION命令中引用对象文件 + 从CREATE FUNCTION命令中引用目标文件 之前,它必须先被编译好。更多信息请见 - magic block + 魔数块 - 为确保动态装载的对象文件不会被加载到不兼容的服务器中,PostgreSQL会检查该文件是否包含内容适当的magic block。这样服务器就能检测出明显的不兼容情况,例如代码所针对的大版本不同于当前的 PostgreSQL。要加入 magic block,请在模块某一个(且只能一个)源文件中写入下列内容,并事先包含头文件 fmgr.h: + + 为确保动态装载的目标文件不会被加载到不兼容的服务器中,PostgreSQL 会检查该文件是否包含内容正确的魔数块。这样服务器就能检测出明显的不兼容情况,例如代码是针对另一个 PostgreSQL 主版本编译的。要加入魔数块,请在模块某一个(且只能一个)源文件中,在包含头文件 fmgr.h 之后写入: PG_MODULE_MAGIC; @@ -1445,9 +1462,9 @@ PG_MODULE_MAGIC; - 在第一次使用之后,动态载入对象文件会保留在内存中。在同一个会话中, + 在第一次使用之后,动态载入目标文件会保留在内存中。在同一个会话中, 后续对该文件中函数的调用只需付出一次很小的符号表查找开销。如果需要 - 强制重新载入一个对象文件(例如在重新编译之后),就需要开启一个新的会话。 + 强制重新载入一个目标文件(例如在重新编译之后),就需要开启一个新的会话。 @@ -1466,7 +1483,7 @@ PG_MODULE_MAGIC; - C 语言函数中的基本类型 + C 语言函数中的基础类型 数据类型 @@ -1475,16 +1492,16 @@ PG_MODULE_MAGIC; 要了解如何编写 C 语言函数,你需要了解 - PostgreSQL如何在内部表达基本数据类型 + PostgreSQL如何在内部表达基础类型 以及如何与函数传递它们。在内部, - PostgreSQL把基本类型视为一块内存数据块。 + PostgreSQL把基础类型视为一块内存数据块。 你为该类型定义的用户自定义函数,决定了 PostgreSQL 如何操作它。 也就是说,PostgreSQL 只负责把数据存到磁盘、再从磁盘取回, 而数据的输入、处理和输出则依赖你定义的这些函数。 - 基本类型可以有三种内部格式之一: + 基础类型可以有三种内部格式之一: @@ -1549,10 +1566,9 @@ typedef struct 最后,所有变长类型必须也以引用的方式传递。所有变长类型必须用一个 - 正好 4 字节的不透明长度域开始,该域会由SET_VARSIZE - 设置,绝不要直接设置该域!所有要被存储在该类型中的数据必须在内存 - 中接着该长度域的后面存储。长度域包含该结构体的总长度,也就是包括长 - 度域本身的尺寸。 + 正好 4 字节的不透明长度字段开始,该字段会由SET_VARSIZE + 设置,绝不要直接设置该字段!所有要被存储在该类型中的数据必须在内存 + 中接着该长度字段的后面存储。长度字段包含该结构体的总长度,也就是包括长度字段本身的尺寸。 @@ -1602,16 +1618,16 @@ memcpy(destination->data, buffer, 40); VARHDRSZsizeof(int32)一样, - 但是用宏VARHDRSZ来引用变长类型的载荷的 + 但是用宏VARHDRSZ来引用变长类型的额外开销的 尺寸被认为是比较好的风格。还有,必须 - 使用SET_VARSIZE宏来设置长度域,而不是用 + 使用SET_VARSIZE宏来设置长度字段,而不是用 简单的赋值来设置。 展示了 PostgreSQL 中许多内置 SQL 数据类型所对应的 C 类型。 - Defined In列给出了需要包含的头文件,以获取类型定义。 + 定义文件列给出了需要包含的头文件,以获取类型定义。 (实际的定义可能位于所列文件包含的其他文件中。建议用户坚持使用已定义的接口。) 请注意,在服务器代码的任何源文件中,都应该始终首先包含postgres.h, 因为它声明了很多你反正都会用到的内容,而且先包含其他头文件可能会带来可移植性问题。 @@ -1787,8 +1803,7 @@ memcpy(destination->data, buffer, 40); - 现在我们已经复习了基本类型所有可能的结构,现在可以展示一些 - 真实函数的示例了。 + 了解了基础类型所有可能的结构后,就可以看一些实际函数示例。 @@ -1796,7 +1811,7 @@ memcpy(destination->data, buffer, 40); 版本 1 的调用约定 - 版本-1 的调用规范依赖于宏来降低传参数和结果的复杂度。版本-1 函数的 + 版本-1 的调用约定依赖于宏来降低传参数和结果的复杂度。版本-1 函数的 C 声明总是: Datum funcname(PG_FUNCTION_ARGS) @@ -1808,14 +1823,16 @@ PG_FUNCTION_INFO_V1(funcname); 必须出现在同一个源文件中(按惯例会正好写在该函数本身之前)。 这种宏调用不是internal语言函数所需要的,因为 PostgreSQL会假定所有内部函数都使用 - 版本-1 规范。不过,对于动态载入函数是必需的。 + 版本-1 调用约定。不过,对于动态载入函数是必需的。 - 在版本-1 函数中,每一个实参都使用对应于该参数数据类型的PG_GETARG_xxx()宏取得。(在非严格的函数中,需要使用PG_ARGISNULL()对参数是否为空提前做检查;见下文。)结果要用对应于返回类型的PG_RETURN_xxx()宏返回。PG_GETARG_xxx()的参数是要取得的函数参数的编号,从零开始计。PG_RETURN_xxx()的参数是实际要返回的值。 + 在版本-1 函数中,每一个实参都使用对应于该参数数据类型的PG_GETARG_xxx()宏取得。(在非严格的函数中,需要使用PG_ARGISNULL()对参数是否为空值提前做检查;见下文。)结果要用对应于返回类型的PG_RETURN_xxx()宏返回。PG_GETARG_xxx()的参数是要取得的函数参数的编号,从零开始计。PG_RETURN_xxx()的参数是实际要返回的值。 - 下面是一些使用版本-1 调用约定的示例: + + 这里是一些使用版本-1调用约定的示例: + - 注意我们已经把函数指定为strict,这意味着如果有任何输入值为空,系统应该自动假定得到空结果。通过这种做法,我们避免在函数代码中检查空值输入。如果不这样做,我们必须使用PG_ARGISNULL()明确地检查空值输入。 + 注意我们已经把函数指定为strict,这意味着如果有任何输入值为空值,系统应该自动假定结果为空值。通过这种做法,我们避免在函数代码中检查空值输入。如果不这样做,我们必须使用PG_ARGISNULL()明确地检查空值输入。 - 宏PG_ARGISNULL(n)允许一个函数测试是否每一个输入为空(当然,只需要在没有声明为strict的函数中这样做)。和PG_GETARG_xxx()宏一样,输入参数也是从零开始计数。注意应该在验证了一个参数不是空之后才执行PG_GETARG_xxx()。要返回一个空结果,应执行PG_RETURN_NULL(),它对严格的以及非严格的函数都有用。 + 宏PG_ARGISNULL(n)允许一个函数测试是否每一个输入为空值(当然,只需要在没有声明为strict的函数中这样做)。和PG_GETARG_xxx()宏一样,输入参数也是从零开始计数。注意应该在验证了一个参数不是空值之后才执行PG_GETARG_xxx()。要返回空值结果,应执行PG_RETURN_NULL(),它对严格的以及非严格的函数都有用。 @@ -1957,11 +1974,11 @@ CREATE FUNCTION concat_text(text, text) RETURNS text - 在版本-1接口中提供的其他选项是PG_GETARG_xxx()宏的两个变种。其中的第一种是PG_GETARG_xxx_COPY(),它确保返回的指定参数的拷贝可以被安全地写入(通常的宏有时会返回一个指向表中物理存储的值,它不能被写入。使用PG_GETARG_xxx_COPY()宏可以保证得到一个可写的结果)。第二种变种PG_GETARG_xxx_SLICE()宏有三个参数。第一个是函数参数的编号(如上文)。第二个和第三个是要被返回的段的偏移量和长度。偏移量从零开始计算,而负值的长度则表示要求返回该值的剩余部分。当大型值的存储类型为external时,这些宏提供了访问这些大型值的更有效的方法(列的存储类型可以使用ALTER TABLE tablename ALTER COLUMN colname SET STORAGE storagetype来指定。storagetypeplainexternalextended或者main)。 + 在版本-1接口中提供的其他选项是PG_GETARG_xxx()宏的两个变种。其中的第一种是PG_GETARG_xxx_COPY(),它确保返回的指定参数的拷贝可以被安全地写入(通常的宏有时会返回一个指向表中物理存储值的指针,不能写入该值。使用PG_GETARG_xxx_COPY()宏可以保证得到一个可写的结果)。第二种变种PG_GETARG_xxx_SLICE()宏有三个参数。第一个是函数参数的编号(如上文)。第二个和第三个是要被返回的段的偏移量和长度。偏移量从零开始计算,而负值的长度则表示要求返回该值的剩余部分。当大型值的存储类型为external时,这些宏提供了访问这些大型值的部分内容的更有效方法(列的存储类型可以使用ALTER TABLE tablename ALTER COLUMN colname SET STORAGE storagetype来指定。storagetypeplainexternalextended或者main)。 - 最后,版本-1 的函数调用规范可以返回集合结果()、实现触发器函数()和过程语言调用处理器()。更多细节 + 最后,版本-1 的函数调用约定可以返回集合结果()、实现触发器函数()和过程语言调用处理器()。更多细节 可见源代码发布中的src/backend/utils/fmgr/README @@ -1972,18 +1989,24 @@ CREATE FUNCTION concat_text(text, text) RETURNS text 在开始更高级的话题之前,我们应该讨论一下用于 PostgreSQL C 语言函数的编码规则。 - 虽然可以把不是 C 编写的函数载入到 - PostgreSQL中,这通常是很困难的, + 虽然有可能把不是 C 编写的函数载入到 + PostgreSQL中,但即使能够做到,通常也很困难, 因为其他语言(例如 C++、FORTRAN 或者 Pascal)通常不会遵循和 C - 相同的调用规范。也就是说,其他语言不会以同样的方式在函数之间传递 + 相同的调用约定。也就是说,其他语言不会以同样的方式在函数之间传递 参数以及返回值。由于这个原因,我们会假定你的 C 语言函数确实是用 C 编写的。 - 编写和构建 C 函数的基本规则如下: + + 编写和构建 C 语言函数的基本规则如下: + + - 使用pg_config - --includedir-serverpg_config用于用户定义的 C 函数来确定PostgreSQL服务器头文件在你的系统(或用户将要运行的系统)上的安装位置。 + + 使用 pg_config + --includedir-serverpg_config用于用户定义的 C 函数 + 查出 PostgreSQL 服务器头文件在你的系统上(或你的用户将要运行的系统上)安装于何处。 + @@ -1994,7 +2017,7 @@ CREATE FUNCTION concat_text(text, text) RETURNS text - 记得按照中的说明,为你的共享库定义一个magic block。 + 记得按照中的说明,为你的共享库定义一个魔数块 @@ -2020,7 +2043,7 @@ CREATE FUNCTION concat_text(text, text) RETURNS text - 对象文件中定义的符号名不能彼此冲突,也不能与 + 目标文件中定义的符号名不能彼此冲突,也不能与 PostgreSQL 服务器可执行文件中定义的符号冲突。如果你收到这类错误消息,就必须重命名相关函数或变量。 @@ -2031,17 +2054,25 @@ CREATE FUNCTION concat_text(text, text) RETURNS text 复合类型没有像 C 结构体那样的固定布局。复合类型的实例可能包含 - 空值域。此外,继承层次中的复合类型可能具有和同一继承层次中 - 其他成员不同的域。因此, + 空值字段。此外,继承层次中的复合类型可能具有和同一继承层次中 + 其他成员不同的字段。因此, PostgreSQL提供了函数接口 - 来访问 C 的复合类型的域。 + 以便从 C 访问复合类型的字段。 - 假设我们想编写一个函数来回答如下查询: + + 假设我们想要写一个函数来回答查询: + + SELECT name, c_overpaid(emp, 1500) AS overpaid FROM emp WHERE name = 'Bill' OR name = 'Sam'; -使用版本-1 调用约定,我们可以将 c_overpaid 定义为: + + 如果使用版本-1的调用约定,我们可以定义 + c_overpaid为: + + GetAttributeByName 是 - PostgreSQL 的一个系统函数,用于从指定行中取出属性。它有三个参数:传入函数的 HeapTupleHeader 类型参数、所需属性的名称,以及一个用于指示该属性是否为 null 的返回参数。GetAttributeByName 返回一个 Datum 值,你可以用适当的 DatumGetXXX() 函数把它转换为正确的数据类型。注意,如果 null 标志被设置,那么返回值本身没有意义;在尝试对结果做任何处理之前,务必先检查这个 null 标志。 + PostgreSQL 的一个系统函数,用于从指定行中取出属性。它有三个参数:传入函数的 HeapTupleHeader 类型参数、所需属性的名称,以及一个用于指示该属性是否为 null 的返回参数。GetAttributeByName 返回一个 Datum 值,你可以用适当的 DatumGetXXX() 宏把它转换为正确的数据类型。注意,如果 null 标志被设置,那么返回值本身没有意义;在尝试对结果做任何处理之前,务必先检查这个 null 标志。 也有GetAttributeByNum函数,它可以用目标属性 - 的属性号而不是属性名来选择目标属性。 + 的列号而不是属性名来选择目标属性。 @@ -2097,14 +2128,14 @@ CREATE FUNCTION c_overpaid(emp, integer) RETURNS boolean 要从 C 语言函数中返回一行或一个复合类型值,可以使用一套特殊的 API, - 它通过一组宏和函数隐藏了构造组合数据类型时的大部分复杂性。要使用这套 API,源文件中必须包含: + 它通过一组宏和函数隐藏了构造复合数据类型时的大部分复杂性。要使用这套 API,源文件中必须包含: #include "funcapi.h" - 构造组合数据值(下文简称元组)有两种方式: + 构造复合数据值(下文简称元组)有两种方式: 一种是从 Datum 值数组构造,另一种是从 C 字符串数组构造,这些字符串会传给该元组各列数据类型的输入转换函数。 无论采用哪种方式,首先都需要获取或构造描述该元组结构的 TupleDesc。 处理 Datum 时,需要把 TupleDesc 传给 BlessTupleDesc,然后为每一行调用 heap_form_tuple。 @@ -2113,13 +2144,13 @@ CREATE FUNCTION c_overpaid(emp, integer) RETURNS boolean - 有一些辅助函数可以用来设置所需的 TupleDesc。在大多数返回组合值的函数中,推荐的做法是调用: + 有一些辅助函数可以用来设置所需的 TupleDesc。在大多数返回复合值的函数中,推荐的做法是调用: TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc) - 传入与调用函数本身相同的 fcinfo 结构体(这当然要求使用版本 1 调用约定)。 + 传入调用函数本身收到的同一个 fcinfo 结构体(这当然要求使用版本 1 调用约定)。 resultTypeId 可以指定为 NULL,也可以指定为一个本地变量的地址,用于接收函数结果类型的 OID。 resultTupleDesc 应当是一个本地 TupleDesc 变量的地址。 检查返回结果是否为 TYPEFUNC_COMPOSITE;如果是,resultTupleDesc 就会被填入所需的 TupleDesc。 @@ -2138,7 +2169,7 @@ TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, get_call_result_type有一个兄弟 get_expr_result_type,它被用来解析被表示为一棵表达式 - 树的函数调用的输出类型。在尝试确定来自函数外部的结果类型时可以用它。 + 树的函数调用的输出类型。在尝试从函数自身外部确定结果类型时可以用它。 也有一个get_func_result_type,当只有函数的 OID 可用时 可以用它。不过这些函数无法处理被声明为返回record的 函数,并且get_func_result_type无法解析多态类型,因此你 @@ -2147,22 +2178,22 @@ TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, - 更早、现在已被废弃的获取TupleDesc的函数有: + 更早、现在已被弃用的获取TupleDesc的函数有: TupleDesc RelationNameGetTupleDesc(const char *relname) - 它可以为一个提到的关系的行类型得到TupleDesc, + 它可以为一个指定名称的关系的行类型得到TupleDesc, 还有: TupleDesc TypeGetTupleDesc(Oid typeoid, List *colaliases) 可以基于一个类型 OID 得到TupleDesc。这可以被用来 - 为一种基础或者复合类型获得TupleDesc。不过,对于 + 为一种基本或者复合类型获得TupleDesc。不过,对于 返回record的函数它不起作用,并且它无法解析多态类型。 - 一旦有了一个TupleDesc,如果计划处理 Datum可以调用: + 一旦有了一个TupleDesc,如果计划处理 Datum,可以调用: TupleDesc BlessTupleDesc(TupleDesc tupdesc) @@ -2172,7 +2203,7 @@ AttInMetadata *TupleDescGetAttInMetadata(TupleDesc tupdesc) 如果正在编写一个返回集合的函数,你可以把这些函数的结果保存在 FuncCallContext结构体中 — 分别使用 - tuple_desc或者attinmeta域。 + tuple_desc或者attinmeta字段。 @@ -2192,8 +2223,7 @@ HeapTuple BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values) values是一个 C 字符串数组,每一个元素是返回行 的一个属性。每一个 C 字符串应该是该属性数据类型的输入函数所期望 的格式。为了对一个属性返回空值,values数组中对 - 应的指针应该被设置为NULL。对于你返回的每一行都将 - 再次调用这个函数。 + 应的指针应该被设置为NULL。对于你返回的每一行都需要再次调用这个函数。 @@ -2228,19 +2258,25 @@ HeapTupleGetDatum(HeapTuple tuple) 使用 ValuePerCall 模式时,重要的是要记住查询不能保证运行完成; 也就是说,由于诸如LIMIT之类的选项, - 执行程序可能会在获取所有行之前停止调用 set-returning 函数。 + 执行器可能会在获取所有行之前停止调用集合返回函数。 这意味着在最后一次调用中执行清理活动是不安全的,因为这可能永远不会发生。 对于需要访问外部资源(例如文件描述符)的函数,建议使用 Materialize 模式。 - 本节的其余部分记录了一组使用 ValuePerCall 模式的 SRF 常用(尽管不是必须使用)的帮助程序宏。 + 本节的其余部分记录了一组使用 ValuePerCall 模式的 SRF 常用(尽管不是必须使用)的辅助宏。 有关 Materialize 模式的其他详细信息可以在src/backend/utils/fmgr/README中找到。 此外,PostgreSQL源代码分发中的contrib 模块包含许多使用 ValuePerCall 和 Materialize 模式的 SRF 示例。 - 要使用这里描述的 ValuePerCall 支持宏,请包含 funcapi.h。这些宏会用到一个结构体 FuncCallContext,该结构体包含需要跨调用保存的状态。在使用这些宏的 SRF 中,fcinfo->flinfo->fn_extra 用于在调用之间保存指向 FuncCallContext 的指针。宏在第一次使用时自动填充该字段,并期望在后续使用中找到相同的指针。 + + 要使用此处描述的 ValuePerCall 支持宏,请包含funcapi.h。 + 这些宏与结构体FuncCallContext一起使用,该结构体包含需要跨调用保存的状态。 + 在使用这些宏的 SRF 中,fcinfo->flinfo->fn_extra用于在调用之间保存 + 指向FuncCallContext的指针。 + 宏在第一次使用时自动填充该字段,并期望在后续使用中找到相同的指针。 + typedef struct FuncCallContext { /* @@ -2270,7 +2306,7 @@ typedef struct FuncCallContext /* * 可选:指向包含属性类型输入元数据的结构的指针 * - * attinmeta 被用在返回元组(即组合数据类型)时,在返回基本数据类型 + * attinmeta 被用在返回元组(即复合数据类型)时,在返回基础类型 * 时不会使用。只有想用BuildTupleFromCStrings()创建返回元组时才需要它。 */ AttInMetadata *attinmeta; @@ -2287,7 +2323,7 @@ typedef struct FuncCallContext /* * 可选:指向包含元组描述的结构的指针 * - * tuple_desc 被用在返回元组(即组合数据类型)时,并且只有在用 + * tuple_desc 被用在返回元组(即复合数据类型)时,并且只有在用 * heap_form_tuple() 而不是 BuildTupleFromCStrings() 构建元组时才需要它。 * 注意这里存储的 TupleDesc 指针通常已经被先运行过 BlessTupleDesc()。 */ @@ -2391,14 +2427,16 @@ my_set_returning_function(PG_FUNCTION_ARGS) else { /* 这里已经完成了项的返回,所以只报告事实。 */ - /* (不要将清理代码放在这里的。) */ + /* (不要将清理代码放在这里。) */ SRF_RETURN_DONE(funcctx); } } - 下面是一个返回复合类型的简单 SRF 的完整示例: + 一个返回复合类型的简单SRF的完整示例如下: +multi_call_memory_ctx); - /* total number of tuples to be returned */ + /* 要返回的元组总数 */ funcctx->max_calls = PG_GETARG_UINT32(0); - /* Build a tuple descriptor for our result type */ + /* 为我们的结果类型构建一个元组描述符 */ if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), @@ -2432,8 +2470,7 @@ retcomposite(PG_FUNCTION_ARGS) "that cannot accept type record"))); /* - * generate attribute metadata needed later to produce tuples from raw - * C strings + * 生成后续从原始C字符串生成元组所需的属性元数据 */ attinmeta = TupleDescGetAttInMetadata(tupdesc); funcctx->attinmeta = attinmeta; @@ -2441,23 +2478,22 @@ retcomposite(PG_FUNCTION_ARGS) MemoryContextSwitchTo(oldcontext); } - /* stuff done on every call of the function */ + /* 每次函数调用时执行的操作 */ funcctx = SRF_PERCALL_SETUP(); call_cntr = funcctx->call_cntr; max_calls = funcctx->max_calls; attinmeta = funcctx->attinmeta; - if (call_cntr < max_calls) /* do when there is more left to send */ + if (call_cntr < max_calls) /* 当还有更多要发送时执行 */ { char **values; HeapTuple tuple; Datum result; /* - * Prepare a values array for building the returned tuple. - * This should be an array of C strings which will - * be processed later by the type input functions. + * 为构建返回的元组准备一个值数组。 + * 这应该是一个由后续类型输入函数处理的C字符串数组。 */ values = (char **) palloc(3 * sizeof(char *)); values[0] = (char *) palloc(16 * sizeof(char)); @@ -2468,13 +2504,13 @@ retcomposite(PG_FUNCTION_ARGS) snprintf(values[1], 16, "%d", 2 * PG_GETARG_INT32(1)); snprintf(values[2], 16, "%d", 3 * PG_GETARG_INT32(1)); - /* build a tuple */ + /* 构建一个元组 */ tuple = BuildTupleFromCStrings(attinmeta, values); - /* make the tuple into a datum */ + /* 将元组转换为 datum */ result = HeapTupleGetDatum(tuple); - /* clean up (this is not really necessary) */ + /* 清理(这实际上并不是必要的) */ pfree(values[0]); pfree(values[1]); pfree(values[2]); @@ -2482,26 +2518,33 @@ retcomposite(PG_FUNCTION_ARGS) SRF_RETURN_NEXT(funcctx, result); } - else /* do when there is no more left */ + else /* 当没有更多要发送时执行 */ { SRF_RETURN_DONE(funcctx); } } ]]> -在 SQL 中声明该函数的一种方法是: + + + 在SQL中声明此函数的一种方法是: + CREATE TYPE __retcomposite AS (f1 integer, f2 integer, f3 integer); CREATE OR REPLACE FUNCTION retcomposite(integer, integer) RETURNS SETOF __retcomposite AS 'filename', 'retcomposite' LANGUAGE C IMMUTABLE STRICT; -另一种方法是使用 OUT 参数: + + 另一种方法是使用OUT参数: + CREATE OR REPLACE FUNCTION retcomposite(IN integer, IN integer, OUT f1 integer, OUT f2 integer, OUT f3 integer) RETURNS SETOF record AS 'filename', 'retcomposite' LANGUAGE C IMMUTABLE STRICT; -注意,在这种方法中,该函数的输出类型在形式上是一个匿名的 record 类型。 + + 请注意,采用这种方法时,函数的输出类型在形式上是一个匿名的 record 类型。 + @@ -2520,10 +2563,10 @@ CREATE OR REPLACE FUNCTION retcomposite(IN integer, IN integer, fcinfo->flinfo访问。参数argnum则是从零 开始计。get_call_result_type也可被用作 get_fn_expr_rettype的一种替代品。还有 - get_fn_expr_variadic,它可以被用来找出 variadic 参数 + get_fn_expr_variadic,它可以被用来找出可变参数 是否已经被合并到了一个数组中。这主要用于 VARIADIC "any"函数,因为对于接收普通数组类型的 - variadic 函数来说总是会发生这类合并。 + 可变参数函数来说总是会发生这类合并。 @@ -2591,7 +2634,7 @@ CREATE FUNCTION make_array(anyelement) RETURNS anyarray 它与 anyelement 类似,但不会要求不同的 "any" 参数必须是同一种类型,也不会帮助确定函数的结果类型。 C 语言函数还可以把最后一个参数声明为 VARIADIC "any"。 这可以匹配一个或多个任意类型的实参(不必是同一种类型)。 - 这些参数不会像普通 variadic 函数那样被收集成一个数组,而是会单独传给函数。 + 这些参数不会像普通可变参数函数那样被收集成一个数组,而是会单独传给函数。 使用这种特性时,必须结合 PG_NARGS() 宏以及前面介绍的方法来确定实参的个数和类型。 此外,这种函数的用户也可能希望在函数调用中使用 VARIADIC 关键字,以便让函数把数组元素当作独立参数处理。 如果希望支持这种行为,函数本身就必须在使用 get_fn_expr_variadic 检测到实参被标记为 VARIADIC 后自行实现它。 @@ -2599,7 +2642,7 @@ CREATE FUNCTION make_array(anyelement) RETURNS anyarray - 共享内存 + 共享内存与 LWLocks 附加模块可以在服务器启动时预留 LWLock 和一块共享内存。附加模块的共享库必须通过在以下参数中指定它来预装载:shared_preload_libraries。共享内存可以通过下面的调用来预留: void RequestAddinShmemSpace(int size) @@ -2668,9 +2711,9 @@ if (!ptr) - 如果从 C++ 代码调用后端函数,确定 C++ 调用栈值包含传统 C 风格 + 如果从 C++ 代码调用后端函数,确定 C++ 调用栈只包含传统 C 风格 的数据结构(POD)。这是必要的,因为后端错误会 - 产生远距离的longjmp(),它无法正确的退回具有非 + 产生远距离的longjmp(),它无法正确地展开具有非 POD 对象的 C++ 调用栈。 @@ -2689,8 +2732,8 @@ if (!ptr) 函数优化信息 - optimization information - for functions + 优化信息 + 用于函数 @@ -2726,7 +2769,7 @@ supportfn(internal) returns internal - 对于返回 boolean 的目标函数,估计使用该函数的 WHERE 子句会筛选出多少行通常很有用。这可以通过实现 SupportRequestSelectivity 请求类型的支持函数来完成。 + 对于返回 boolean 的目标函数,估计使用该函数的 WHERE 子句筛选出的行所占的比例通常很有用。这可以通过实现 SupportRequestSelectivity 请求类型的支持函数来完成。 diff --git a/zh/13/xindex.sgml b/zh/13/xindex.sgml index 40dd6ac0..c5e00561 100644 --- a/zh/13/xindex.sgml +++ b/zh/13/xindex.sgml @@ -22,7 +22,7 @@ pg_am 表为每个索引方法(内部称为访问方法)保存一行。对表进行常规访问的支持内置于 PostgreSQL 中,但所有索引方法都在 pg_am 中描述。可以编写必要的代码,然后在 pg_am 中创建一个条目,从而添加新的索引访问方法 — 但这超出了本章的范围(参见)。 - 索引方法的例程并不直接知道它将处理哪些数据类型。相反,一个操作符类operator class标识了索引方法在处理特定数据类型时需要使用的那组操作。之所以称为操作符类,是因为它指定的一项内容就是可与索引一起使用的 WHERE 子句操作符集合(也就是能被转换成索引扫描条件的操作符)。操作符类还可以指定索引方法内部操作所需的一些支持函数,但这些函数并不直接对应任何可与索引一起使用的 WHERE 子句操作符。 + 索引方法的例程并不直接知道它将处理哪些数据类型。相反,一个操作符类操作符类标识了索引方法在处理特定数据类型时需要使用的那组操作。之所以称为操作符类,是因为它指定的一项内容就是可与索引一起使用的 WHERE 子句操作符集合(也就是能被转换成索引扫描条件的操作符)。操作符类还可以指定索引方法内部操作所需的一些支持函数,但这些函数并不直接对应任何可与索引一起使用的 WHERE 子句操作符。 @@ -319,19 +319,27 @@ - 比较两个键,并返回小于零、等于零或大于零的整数,分别表示第一个键小于、等于或大于第二个键 + + 比较两个键,并返回一个小于零、等于零或大于零的整数,用以表示第一个键是小于、等于还是大于第二个键 + 1 - 返回可从 C 调用的排序支持函数的地址(可选) + + 返回可由 C 调用的排序支持函数地址(可选) + 2 - 将测试值与基准值加上或减去偏移量后的结果进行比较,并根据比较结果返回真或假(可选) + + 将测试值与基准值加上或减去某个偏移量后的结果进行比较,并根据比较结果返回真或假(可选) + 3 - 确定使用该操作符类的索引能否安全地应用 B-树去重优化(可选) + + 确定对使用该操作符类的索引应用 B-树去重优化是否安全(可选) + 4 @@ -366,7 +374,7 @@ - 给定一个 64 位 salt,计算一个键的 64 位哈希值;如果 salt 为 0,结果的低 32 位必须与函数 1 计算出的值一致(可选) + 给定一个 64 位盐值,计算一个键的 64 位哈希值;如果盐值为 0,结果的低 32 位必须与函数 1 计算出的值一致(可选) 2 @@ -528,7 +536,7 @@ compare - 比较两个键,并返回一个小于零、等于零或大于零的整数,以表示第一个键是小于、等于还是大于第二个键 + 比较两个键,并返回一个小于零、等于零或大于零的整数,用以表示第一个键是小于、等于还是大于第二个键 1 @@ -688,7 +696,10 @@ complex_abs_lt(PG_FUNCTION_ARGS) 其他四个函数的区别只在于它们如何比较内部函数的结果与 0。 - 接下来,在 SQL 中声明这些函数,以及基于这些函数的操作符: + + 接着,我们在 SQL 中声明这些函数以及基于它们的操作符: + + CREATE FUNCTION complex_abs_lt(complex, complex) RETURNS bool AS 'filename', 'complex_abs_lt' LANGUAGE C IMMUTABLE STRICT; @@ -698,7 +709,9 @@ CREATE OPERATOR < ( commutator = > , negator = >= , restrict = scalarltsel, join = scalarltjoinsel ); -必须指定正确的交换操作符和求反操作符,以及合适的限制选择率与连接选择率函数,否则优化器无法有效使用索引。 + + 指定正确的交换子和求反器操作符很重要,同样也要指定合适的限制选择率函数和连接选择率函数,否则优化器将无法有效地利用索引。 + 这里还有几点值得注意: @@ -776,15 +789,17 @@ CREATE OPERATOR CLASS complex_abs_ops - 为了满足这些需求,PostgreSQL使用操作符族operator family这一概念。一个操作符族包含一个或多个操作符类,还可以包含属于整个族、但不属于族中任何单一类的可索引操作符及其相应的支持函数。我们称这样的操作符和函数在该族中是松散的,而不是绑定在某个特定类中。通常,每个操作符类只包含单一数据类型的操作符,而跨数据类型操作符则作为操作符族中的松散成员存在。 + 为了满足这些需求,PostgreSQL使用操作符族操作符族这一概念。一个操作符族包含一个或多个操作符类,还可以包含属于整个族、但不属于族中任何单一类的可索引操作符及其相应的支持函数。我们称这样的操作符和函数在该族中是松散的,而不是绑定在某个特定类中。通常,每个操作符类只包含单一数据类型的操作符,而跨数据类型操作符则作为操作符族中的松散成员存在。 一个操作符族中的所有操作符和函数都必须具有兼容的语义,而兼容性的要求由索引方法设定。因此,你也许会疑惑,为什么还要把该族的某些子集单独划成操作符类;事实上,对很多用途而言,类的划分并不重要,真正有意义的分组只有操作符族。之所以定义操作符类,是因为它们规定了支持特定索引所需的操作符族内容。如果某个索引使用了某个操作符类,那么在不删除该索引的情况下就不能删除该操作符类 — 但操作符族中的其他部分,也就是其他操作符类和松散操作符,则可以被删除。因此,一个操作符类应当只包含在特定数据类型上支持索引所合理需要的最小操作符和函数集合,而那些相关但非必需的操作符,则可以作为操作符族的松散成员加入。 - 例如,PostgreSQL内置了 B 树操作符族integer_ops,其中包含操作符类int8_opsint4_opsint2_ops,它们分别用于以下列类型上的索引:bigintint8), - integerint4)和smallintint2)。该操作符族还包含跨数据类型的比较操作符,允许对这些类型中的任意两个进行比较,因此可以使用一种类型的比较值搜索另一种类型上的索引。可以用以下定义复制这个操作符族: + 例如,PostgreSQL内置了一个 B-树操作符族 integer_ops,其中包含操作符类 int8_opsint4_opsint2_ops,它们分别用于 bigintint8)、integerint4)和 smallintint2)列上的索引。该操作符族还包含跨数据类型比较操作符,允许比较这三种类型中的任意两种,因此可以用一种类型的比较值搜索另一种类型上的索引。下面这些定义可以复现该操作符族: + + -注意,此定义重载了操作符策略编号和支持函数编号:每个编号在操作符族中出现多次。只要同一编号的每个实例具有不同的输入数据类型,这就是允许的。两个输入类型都等于某个操作符类输入类型的实例,是该操作符类的主要操作符和支持函数,通常应声明为操作符类的一部分,而不是操作符族的独立成员。 + + + 注意,这个定义对操作符策略号和支持函数号进行了重载:每个编号在该族内都会出现多次。只要某个编号的每次出现都具有不同的输入数据类型,这就是允许的。那些两个输入类型都等于某个操作符类输入类型的实例,就是该操作符类的主要操作符和支持函数;在大多数情况下,它们应当被声明为该操作符类的一部分,而不是该族的松散成员。 + 所详述,在一个 B-树操作符族中,该族中的所有操作符都必须以兼容的方式排序。对族中的每一个操作符,都必须有一个具有相同两个输入数据类型的支持函数。建议让操作符族保持完整,也就是说,对每一种数据类型组合都应包含全部操作符。每个操作符类只应包含其数据类型对应的非跨数据类型操作符和支持函数。 - 要构建一个多数据类型的哈希操作符族,必须为该族支持的每一种数据类型创建相互兼容的哈希支持函数。这里的兼容性是指:对任意两个被该族中的等值操作符视为相等的值,这些函数都保证返回相同的哈希码,即使这两个值属于不同类型也是如此。当这些类型具有不同的物理表示时,这通常难以实现,但在某些情况下可以做到。此外,将该操作符族中一种数据类型的值通过隐式或二进制强制转换转换成该族中另一种数据类型时,不应改变所计算出的哈希值。注意,每种数据类型只有一个支持函数,而不是每个等值操作符一个。建议让操作符族保持完整,也就是说,对每一种数据类型组合都提供一个等值操作符。每个操作符类只应包含其数据类型对应的非跨数据类型等值操作符和支持函数。 + 要构建一个多数据类型的哈希操作符族,必须为该族支持的每一种数据类型创建相互兼容的哈希支持函数。这里的兼容性是指:对任意两个被该族中的等值操作符视为相等的值,这些函数都保证返回相同的哈希码,即使这两个值属于不同类型也是如此。当这些类型具有不同的物理表示时,这通常难以实现,但在某些情况下可以做到。此外,将该操作符族中一种数据类型的值通过隐式或二进制强制转换转为该族中另一种数据类型时,不得改变所计算出的哈希值。注意,每种数据类型只有一个支持函数,而不是每个等值操作符一个。建议让操作符族保持完整,也就是说,对每一种数据类型组合都提供一个等值操作符。每个操作符类只应包含其数据类型对应的非跨数据类型等值操作符和支持函数。 @@ -901,7 +919,7 @@ ALTER OPERATOR FAMILY integer_ops USING btree ADD - 在 PostgreSQL 8.3 之前,并没有操作符族这一概念,因此任何打算与索引一起使用的跨数据类型操作符都必须直接绑定到该索引的操作符类中。虽然这种做法仍然有效,但已经废弃,因为它会使索引的依赖关系过于宽泛,而且当两种数据类型都在同一操作符族中拥有操作符时,规划器能更有效地处理跨数据类型比较。 + 在 PostgreSQL 8.3 之前,并没有操作符族这一概念,因此任何打算与索引一起使用的跨数据类型操作符都必须直接绑定到该索引的操作符类中。虽然这种做法仍然有效,但已被弃用,因为它会使索引的依赖关系过于宽泛,而且当两种数据类型都在同一操作符族中拥有操作符时,规划器能更有效地处理跨数据类型比较。 @@ -910,7 +928,7 @@ ALTER OPERATOR FAMILY integer_ops USING btree ADD 系统对操作符类的依赖 - ordering operator + 排序操作符 @@ -918,7 +936,7 @@ ALTER OPERATOR FAMILY integer_ops USING btree ADD - 特别地,ORDER BYDISTINCT等 SQL 特性要求对值的比较和排序。为了在用户定义的数据类型上实现这些特性,PostgreSQL会为数据类型查找默认 B-树操作符类。这个操作符类的equals成员定义了用于GROUP BYDISTINCT的值的等值概念,而该操作符类施加的排序顺序定义了默认的ORDER BY顺序。 + 特别地,ORDER BYDISTINCT等 SQL 特性要求对值的比较和排序。为了在用户定义的数据类型上实现这些特性,PostgreSQL会为数据类型查找默认 B-树操作符类。这个操作符类的相等成员定义了用于GROUP BYDISTINCT的值的等值概念,而该操作符类施加的排序顺序定义了默认的ORDER BY顺序。 @@ -944,11 +962,11 @@ SELECT * FROM mytable ORDER BY somecol USING ~<~; - 用户定义类型的数组比较也依赖于该类型默认 B-树操作符类所定义的语义。如果没有默认 B-树操作符类,但有默认的哈希操作符类,则支持数组相等比较,但不支持顺序比较。 + 用户定义类型的数组比较也依赖于该类型默认 B-树操作符类所定义的语义。如果没有默认 B-树操作符类,但有默认的哈希操作符类,则支持数组相等比较,但不支持排序比较。 - 另一种需要更多数据类型相关知识的 SQL 特性,是窗口函数中的 RANGE offset PRECEDING/FOLLOWING 框架选项(见)。对于下面这样的查询 + 另一种需要更多数据类型相关知识的 SQL 特性,是窗口函数中的 RANGE offset PRECEDING/FOLLOWING 帧选项(见)。对于下面这样的查询 SELECT sum(x) OVER (ORDER BY x RANGE BETWEEN 5 PRECEDING AND 10 FOLLOWING) FROM mytable; @@ -964,19 +982,26 @@ SELECT sum(x) OVER (ORDER BY x RANGE BETWEEN 5 PRECEDING AND 10 FOLLOWING) 排序操作符 - 某些索引访问方法(目前只有 GiST 和 SP-GiST)支持排序操作符的概念。我们到目前为止讨论的是搜索操作符。对于搜索操作符,可以搜索索引以找出满足以下条件的所有行:WHERE + + 有些索引访问方法(目前只有 GiST 和 SP-GiST)支持排序操作符这一概念。到目前为止,我们讨论的都是搜索操作符。对搜索操作符而言,可以搜索索引以找出所有满足 + WHERE indexed_column operator - constant。注意,不保证匹配行的返回顺序。排序操作符则不限制可以返回的行集合,而是确定这些行的顺序。对于排序操作符,可以扫描索引,按以下表达式表示的顺序返回行:ORDER BY + constant 的行。注意,返回匹配行的顺序并没有任何保证。相反,排序操作符并不限制可返回的行集合,而是决定这些行的顺序。对排序操作符而言,可以扫描索引以按如下表达式所表示的顺序返回行: + ORDER BY indexed_column operator - constant。这样定义排序操作符,是因为当操作符用于度量距离时,它可以支持最近邻搜索。例如,如下查询:constant
+ 之所以这样定义排序操作符,是因为如果该操作符能度量距离,它就能支持最近邻搜索。例如,像下面这样的查询 + point '(101,456)' LIMIT 10; ]]> -可以找到距离指定目标点最近的十个地点。location 列上的 GiST 索引能够高效完成此操作,因为<->是排序操作符。 + + 会找出离给定目标点最近的十个位置。对 location 列建立的 GiST 索引可以高效地完成这个查询,因为 <-> 是一个排序操作符。 + - 搜索操作符必须返回布尔结果,而排序操作符通常返回其他类型的结果,例如表示距离的浮点数或数值。这种类型通常不同于被索引的数据类型。为了避免对不同数据类型行为作硬编码假设,在定义排序操作符时,必须指定一个 B-树操作符族,用来说明结果数据类型的排序顺序。正如上一节所述,B-树操作符族定义了 PostgreSQL 的顺序概念,因此这是一种自然的表示方式。由于点的 <-> 操作符返回 float8,因此可以在创建操作符类时这样指定它: + 搜索操作符必须返回布尔结果,而排序操作符通常返回其他类型的结果,例如用于表示距离的 float 或 numeric。这种类型通常不同于被索引的数据类型。为了避免对不同数据类型行为作硬编码假设,在定义排序操作符时,必须指定一个 B-树操作符族,用来说明结果数据类型的排序顺序。正如上一节所述,B-树操作符族定义了 PostgreSQL 的顺序概念,因此这是一种自然的表示方式。由于点的 <-> 操作符返回 float8,因此可以在创建操作符类时这样指定它: (point, point) FOR ORDER BY float_ops ]]> @@ -989,7 +1014,7 @@ OPERATOR 15 <-> (point, point) FOR ORDER BY float_ops 操作符类的特殊特性 - 还有两个操作符类的特殊特性我们尚未讨论,主要是因为它们对最常用的索引方法并不太有用。 + 还有两个操作符类的特殊特性我们尚未讨论,主要是因为它们对最常用的索引方法没有用处。 @@ -1005,7 +1030,7 @@ CREATE OPERATOR CLASS polygon_ops DEFAULT FOR TYPE polygon USING gist AS ... STORAGE box; -目前,只有 GiST、GIN 和 BRIN 索引方法支持与列数据类型不同的STORAGE类型。GiST 的compressdecompress支持函数在使用STORAGE时必须处理数据类型转换。在 GIN 中,STORAGE类型标识key值的类型,通常与被索引列的类型不同。例如,整数数组列的操作符类可以只使用整数作为键。GIN 的extractValueextractQuery支持函数负责从被索引值中提取键。BRIN 与 GIN 类似:STORAGE类型标识所存储摘要值的类型,而操作符类的支持函数负责正确解释这些摘要值。 +目前,只有 GiST、GIN 和 BRIN 索引方法支持与列数据类型不同的STORAGE类型。GiST 的compressdecompress支持函数在使用STORAGE时必须处理数据类型转换。在 GIN 中,STORAGE类型标识值的类型,通常与被索引列的类型不同。例如,整数数组列的操作符类可以只使用整数作为键。GIN 的extractValueextractQuery支持函数负责从被索引值中提取键。BRIN 与 GIN 类似:STORAGE类型标识所存储摘要值的类型,而操作符类的支持函数负责正确解释这些摘要值。 diff --git a/zh/13/xml2.sgml b/zh/13/xml2.sgml index 09b32dc2..3e646071 100644 --- a/zh/13/xml2.sgml +++ b/zh/13/xml2.sgml @@ -1,7 +1,7 @@ - xml2 — XPath 查询与 XSLT 功能 + xml2 xml2 @@ -86,12 +86,16 @@ xpath_nodeset ( document text, query text, toptag text, itemtag text ) text - 对文档执行查询,并将结果包裹在 XML 标签中。如果结果包含多个值,输出将类似于: + + 对文档执行该查询,并将结果包在 XML 标签中。如果结果包含多个值,输出将类似于: + <toptag> -<itemtag>Value 1 which could be an XML fragment</itemtag> +<itemtag>Value 1(可以是 XML 片段)</itemtag> <itemtag>Value 2....</itemtag> </toptag> -如果toptagitemtag为空字符串,就会省略相应的标签。 + + 如果 toptagitemtag 为空字符串,则省略相应的标签。 + @@ -169,7 +173,7 @@ xpath_table(text key, text document, text relation, text xpaths, text criteria) key - key 字段的名称 — 这只是一个作为输出表第一列使用的字段,也就是说,它用于标识每个输出行来自哪条记录(关于多个值,见下文注释) + 字段的名称 — 这只是一个作为输出表第一列使用的字段,也就是说,它用于标识每个输出行来自哪条记录(关于多个值,见下文注释) @@ -200,7 +204,9 @@ xpath_table(text key, text document, text relation, text xpaths, text criteria) criteria - WHERE 子句的内容。这一项不能省略,因此如果你想处理该关系中的所有行,请使用 true1=1 + + WHERE 子句的内容。这一项不能省略,因此如果你想处理该表或视图中的所有行,请使用 true1=1 + @@ -228,7 +234,7 @@ xpath_table('article_id', 'date_entered > ''2003-01-01'' ') AS t(article_id integer, author text, page_count integer, title text); - AS 子句定义了输出表中各列的名称和类型。第一列是 key 字段,其余各列对应 XPath 查询。如果 XPath 查询多于结果列,多出的查询将被忽略。如果结果列多于 XPath 查询,多出的列将为 NULL。 + AS 子句定义了输出表中各列的名称和类型。第一列是 字段,其余各列对应 XPath 查询。如果 XPath 查询多于结果列,多出的查询将被忽略。如果结果列多于 XPath 查询,多出的列将为 NULL。 @@ -257,7 +263,7 @@ WHERE t.author_id = p.person_id; - 在某些情况下,用户会知道某个 XPath 查询只会返回单个结果(例如唯一文档标识符)— 如果它与返回多个结果的 XPath 查询一起使用,这个单值结果只会出现在结果的第一行。解决办法是把 key 字段作为与一个更简单的 XPath 查询结果进行连接的条件之一。例如: + 在某些情况下,用户会知道某个 XPath 查询只会返回单个结果(例如唯一文档标识符)— 如果它与返回多个结果的 XPath 查询一起使用,这个单值结果只会出现在结果的第一行。解决办法是把键字段作为与一个更简单的 XPath 查询结果进行连接的条件之一。例如: CREATE TABLE test ( diff --git a/zh/13/xoper.sgml b/zh/13/xoper.sgml index 0a206fb4..2c2a9585 100644 --- a/zh/13/xoper.sgml +++ b/zh/13/xoper.sgml @@ -23,7 +23,12 @@ 哪个操作符。 - 下面是创建一个用于将两个复数相加的操作符的示例。假定我们已经创建了类型complex的定义(见)。首先需要一个完成实际工作的函数,然后就可以定义操作符: + + 下面是为两个复数相加创建一个操作符的示例。我们假设已经创建了 + complex类型的定义(见)。首先需要 + 一个完成实际工作的函数,然后才能定义该操作符: + + CREATE FUNCTION complex_add(complex, complex) RETURNS complex AS 'filename', 'complex_add' @@ -119,7 +124,7 @@ SELECT (a + b) AS c FROM test_complex; 转成 tab2.y = tab1.x,否则它就无法生成索引扫描,因为 索引扫描机制要求传给它的操作符左侧必须是已建立索引的列。 PostgreSQL 不会仅凭假 - 设就认为这种转换有效 — = 操作符的创建者必须通过为该操 + 设就认为这种转换有效;= 操作符的创建者必须通过为该操 作符标记交换子信息,明确声明这种转换是有效的。 @@ -173,10 +178,10 @@ SELECT (a + b) AS c FROM test_complex; <literal>RESTRICT</literal> - 如果给出 RESTRICT 子句,它指定该操作符的限制选择度估 + 如果给出 RESTRICT 子句,它指定该操作符的限制选择率估 算函数。(注意,这里是函数名,而不是操作符名。) RESTRICT 子句只对返回 boolean 的二元操 - 作符有意义。限制选择度估算器的作用,是针对当前操作符和某个特定常量值, + 作符有意义。限制选择率估算器的作用,是针对当前操作符和某个特定常量值, 猜测一张表中有多少比例的行会满足如下形式的 WHERE 子句条件: @@ -188,9 +193,9 @@ column OP constant - 编写新的限制选择度估算函数远远超出了本章的范围,不过幸运的是,对于你自 + 编写新的限制选择率估算函数远远超出了本章的范围,不过幸运的是,对于你自 己的很多操作符,通常都可以直接使用系统提供的某个标准估算器。标准的限制 - 选择度估算器如下: + 选择率估算器如下: eqsel 用于 = neqsel 用于 <> @@ -202,7 +207,7 @@ column OP constant - 对于选择度非常高或非常低的操作符,即使它们实际上并不是真正的相等或不等 + 对于选择率非常高或非常低的操作符,即使它们实际上并不是真正的相等或不等 比较,你也常常可以勉强使用 eqselneqsel。例如,几何类型中的近似相等操作符就使用 eqsel,其依据是它们通常只会匹配表中很小一部分项。 @@ -221,7 +226,7 @@ column OP constant - 另一个有用的内置选择度估算函数是 matchingsel。只要 + 另一个有用的内置选择率估算函数是 matchingsel。只要 已为输入数据类型收集了标准的 MCV 和/或直方图统计信息,它几乎就适用于任 何二元操作符。它的默认估计值被设定为 eqsel 所用默认 估计值的两倍,因此最适合那些比相等比较稍微宽松一些的比较操作符。(或者 @@ -231,7 +236,7 @@ column OP constant src/backend/utils/adt/geo_selfuncs.c 中,还为几 - 何操作符提供了其他选择度估算函数:areasel、 + 何操作符提供了其他选择率估算函数:areaselpositionselcontsel。截至 目前,这些函数都还只是桩实现,但你也许仍会想使用它们(或者更好的是,改 进它们)。 @@ -242,9 +247,9 @@ column OP constant <literal>JOIN</literal> - 如果给出 JOIN 子句,它指定该操作符的连接选择度估算函 + 如果给出 JOIN 子句,它指定该操作符的连接选择率估算函 数。(注意,这里是函数名,而不是操作符名。)JOIN 子 - 句只对返回 boolean 的二元操作符有意义。连接选择度估算器的 + 句只对返回 boolean 的二元操作符有意义。连接选择率估算器的 作用,是针对当前操作符,猜测两张表中有多少比例的行对会满足如下形式的 WHERE 子句条件: @@ -255,7 +260,7 @@ table1.column1 OP table2.column2 - 与前面一样,本章不会尝试解释如何编写连接选择度估算函数,而只是建议你在 + 与前面一样,本章不会尝试解释如何编写连接选择率估算函数,而只是建议你在 适用时使用某个标准估算器: eqjoinsel 用于 = @@ -314,7 +319,7 @@ table1.column1 OP table2.column2 一个可参与哈希连接的操作符,必须拥有一个交换子(如果两侧操作数数据类型 - 相同,则可以是它自身;如果不同,则应是相关的相等操作符),并且该交换子 + 相同,则为它自身;如果不同,则应是相关的相等操作符),并且该交换子 也必须出现在同一个操作符族中。否则,在使用该操作符时可能会发生规划器错 误。另外,对于支持多种数据类型的哈希操作符族,最好(虽然并非严格必需) 为每一种数据类型组合都提供相等操作符;这样可以获得更好的优化效果。 @@ -351,7 +356,7 @@ table1.column1 OP table2.column2 - 归并连接的基本思想,是先把左表和右表分别排序,然后并行扫描它们。因此, + 归并连接的基本思想,是先把左表和右表分别排序,然后同步扫描它们。因此, 两种数据类型都必须能够被完全排序,而连接操作符必须只能在那对值位于排序 次序中同一位置时才成功。实际效果上,这意味着连接操作符 必须表现得像相等比较一样。不过,只要两种不同的数据类型在逻辑上兼容,也 @@ -371,7 +376,7 @@ table1.column1 OP table2.column2 一个可参与归并连接的操作符,必须拥有一个交换子(如果两侧操作数数据类型 - 相同,则可以是它自身;如果不同,则应是相关的相等操作符),并且该交换子 + 相同,则为它自身;如果不同,则应是相关的相等操作符),并且该交换子 也必须出现在同一个操作符族中。否则,在使用该操作符时可能会发生规划器错 误。另外,对于支持多种数据类型的 btree 操作符族,最 好(虽然并非严格必需)为每一种数据类型组合都提供相等操作符;这样可以获 diff --git a/zh/13/xplang.sgml b/zh/13/xplang.sgml index 11e68571..78e25d43 100644 --- a/zh/13/xplang.sgml +++ b/zh/13/xplang.sgml @@ -107,14 +107,27 @@ CREATE FUNCTION validator_function_name(oid) - 最后,必须用如下命令声明该 PL: + + 最后,必须用如下命令声明该 PL: + CREATE TRUSTED LANGUAGE language_name HANDLER handler_function_name INLINE inline_function_name VALIDATOR validator_function_name ; -可选关键字TRUSTED表示,该语言不会授予用户原本不具备的数据访问能力。受信任的语言是为普通数据库用户(即没有超级用户权限的用户)设计的,并允许他们安全地创建函数和过程。由于 PL 函数是在数据库服务器内部执行的,因此TRUSTED标记只应赋予那些不允许访问数据库服务器内部或文件系统的语言。语言PL/pgSQL, - PL/Tcl以及PL/Perl被认为是受信任的;而语言PL/TclU, - PL/PerlU以及PL/PythonU旨在提供无限制的功能,因此应被标记为受信任的。 + + 可选关键字TRUSTED表示,该语言不会授予用户原本不 + 具备的数据访问能力。受信任的语言是为普通数据库用户(即没有超级用户 + 权限的用户)设计的,并允许他们安全地创建函数和过程。由于 PL 函数是 + 在数据库服务器内部执行的,因此只有那些不允许访问数据库服务器内部或 + 文件系统的语言才应带有TRUSTED标记。 + PL/pgSQL、 + PL/Tcl以及 + PL/Perl被认为是受信任的;而 + PL/TclU、 + PL/PerlU以及 + PL/PythonU旨在提供无限制的功能,因此 + 应被标记为受信任的。 + @@ -146,19 +159,23 @@ CREATE FUNCTION plperl_validator(oid) RETURNS void AS - 下面的命令: + + 下面的命令: + CREATE TRUSTED LANGUAGE plperl HANDLER plperl_call_handler INLINE plperl_inline_handler VALIDATOR plperl_validator; -随后指定应为以下函数和过程调用前面声明的函数:其语言属性为plperl。 + + 随后定义了对于语言属性为plperl的函数和过程,应调 + 用前面声明的函数。 在默认的PostgreSQL安装中, PL/pgSQL语言的调用处理器会被构建并安装到 - library目录中;此外, + 目录中;此外, PL/pgSQL语言本身也安装在所有数据库中。如 果在构建时配置了Tcl支持,那么 PL/TclPL/TclU diff --git a/zh/13/xtypes.sgml b/zh/13/xtypes.sgml index 4c081819..90d2fc45 100644 --- a/zh/13/xtypes.sgml +++ b/zh/13/xtypes.sgml @@ -213,7 +213,7 @@ CREATE TYPE complex ( 如果数据类型的内部表示是可变长度的,则这种内部表示必须遵循可变长度数 据的标准布局:前四个字节必须是一个从不直接访问的char[4] 字段(惯例上命名为vl_len_)。必须使用 - SET_VARSIZE()宏在该字段中存储该值的总大小(包括 + SET_VARSIZE()宏在该字段中存储该 datum 的总大小(包括 长度字段本身),并使用VARSIZE()取回它。(这些宏 之所以存在,是因为长度字段可能会随平台不同而采用编码形式。) @@ -255,7 +255,7 @@ CREATE TYPE complex ( PG_DETOAST_DATUM_PACKED(通常通过定义 GETARG_DATATYPE_PP宏来隐藏),并使用 VARSIZE_ANY_EXHDRVARDATA_ANY - 宏访问一个可能采用打包形式的值。再次注意,即使数据类型定义指定了 + 宏访问一个可能采用打包形式的 datum。再次注意,即使数据类型定义指定了 对齐方式,这些宏返回的数据也不是对齐的。如果对齐很重要,就必须使用常 规的PG_DETOAST_DATUM接口。 @@ -266,8 +266,7 @@ CREATE TYPE complex ( 较旧的代码常把vl_len_声明为 int32字段,而不是char[4]字段。只要结构体定 义中还有其他至少按int32对齐的字段,这样做是可以的。但 - 在处理可能未对齐的值时使用这种结构体定义就很危险;编译器可能据此假定该 - 值实际上是对齐的,从而在对齐要求严格的体系结构上导致核心转储。 + 在处理可能未对齐的 datum 时使用这种结构体定义就很危险;编译器可能据此假定该 datum 实际上是对齐的,从而在对齐要求严格的体系结构上导致核心转储。 diff --git a/zh/14/adminpack.sgml b/zh/14/adminpack.sgml index 1e8d3cd9..663beeb2 100644 --- a/zh/14/adminpack.sgml +++ b/zh/14/adminpack.sgml @@ -94,14 +94,14 @@ pg_file_sync - pg_file_sync对由filename指定的文件或目录执行 fsync。失败时会抛出错误(例如,指定的文件不存在)。请注意,对此函数没有影响,因此即使刷新数据库文件失败,也不会引发 PANIC 级别的错误。 + pg_file_sync对由filename指定的文件或目录执行 fsync。失败时会抛出错误(例如,指定的文件不存在)。请注意,对此函数没有影响,因此即使数据库文件刷盘失败,也不会引发 PANIC 级别的错误。 pg_file_rename - pg_file_rename重命名文件。如果省略archivename或其值为 NULL,则它只是将oldname重命名为newname(后者必须尚不存在)。如果提供了archivename,它会先将newname重命名为archivename(后者必须尚不存在),然后再将oldname重命名为newname。如果第二个重命名步骤失败,它会在报告错误之前尝试将archivename再改回newname。成功时返回 true;如果源文件不存在或不可写,则返回 false;其他情况会抛出错误。 + pg_file_rename重命名文件。如果省略archivename或其值为空值,则它只是将oldname重命名为newname(后者必须尚不存在)。如果提供了archivename,它会先将newname重命名为archivename(后者必须尚不存在),然后再将oldname重命名为newname。如果第二个重命名步骤失败,它会在报告错误之前尝试将archivename再改回newname。成功时返回 true;如果源文件不存在或不可写,则返回 false;其他情况会抛出错误。 diff --git a/zh/14/amcheck.sgml b/zh/14/amcheck.sgml index a7c3816e..32da7245 100644 --- a/zh/14/amcheck.sgml +++ b/zh/14/amcheck.sgml @@ -340,7 +340,7 @@ SET client_min_messages = DEBUG1; 这也包括因操作系统排序规则的比较规则发生变化而引起的问题。 - 像text这类可排序类型的数据值之间的比较必须是不可变的 + 像text这类支持排序规则的类型的 datum 之间的比较必须是不可变的 (正如用于 B-树索引扫描的所有比较都必须不可变一样), 这就意味着操作系统排序规则绝不能发生变化。 虽然这种情况比较少见,但操作系统排序规则的更新确实可能导致此类问题。 diff --git a/zh/14/appendix-obsolete-recovery-config.sgml b/zh/14/appendix-obsolete-recovery-config.sgml index 45732753..5862f25b 100644 --- a/zh/14/appendix-obsolete-recovery-config.sgml +++ b/zh/14/appendix-obsolete-recovery-config.sgml @@ -29,7 +29,7 @@ promote_trigger_file 设置已被重命名为 - promote_trigger_file。 + diff --git a/zh/14/auth-delay.sgml b/zh/14/auth-delay.sgml index 01f3f0e7..639c7544 100644 --- a/zh/14/auth-delay.sgml +++ b/zh/14/auth-delay.sgml @@ -1,7 +1,7 @@ - auth_delay — 在认证失败时暂停 + auth_delay auth_delay diff --git a/zh/14/backup-manifest.sgml b/zh/14/backup-manifest.sgml index ce60d974..30e7752f 100644 --- a/zh/14/backup-manifest.sgml +++ b/zh/14/backup-manifest.sgml @@ -4,7 +4,7 @@ 备份清单格式 - Backup Manifest + 备份清单 @@ -68,9 +68,9 @@ 该键总是出现在备份清单文件的最后一行。其对应的值是此前所有行的 - SHA-256 校验和。这里使用固定的校验和方法,是为了让客户端能够对清单进 - 行增量解析。尽管 SHA-256 校验和明显比 CRC-32C 校验和开销更高,但清单 - 通常足够小,因此这些额外计算一般并不重要。 + SHA256 校验和。这里使用固定的校验和方法,是为了让客户端能够对清单进 + 行增量解析。尽管 SHA256 校验和明显比 CRC32C 校验和开销更高,但清单通 + 常足够小,因此这些额外计算一般并不重要。 @@ -167,7 +167,7 @@ Start-LSN - 为了使用该备份,必须在指定时间线上从这个 LSN 开始回放。该 LSN 按 + 为了使用该备份,必须在指定时间线上从这个 LSN 开始重放。该 LSN 按 PostgreSQL 通常使用的格式存储;也就是说, 它是一个字符串,由两段十六进制字符串构成,每段长度在 1 到 8 之间,并 以斜杠分隔。 @@ -179,7 +179,7 @@ End-LSN - 使用该备份时,指定时间线上的回放可结束于此 LSN,而这也是允许的最早 + 使用该备份时,指定时间线上的重放可结束于此 LSN,而这也是允许的最早 LSN。其存储格式与 Start-LSN 相同。 diff --git a/zh/14/backup.sgml b/zh/14/backup.sgml index 870fd682..2cc1986c 100644 --- a/zh/14/backup.sgml +++ b/zh/14/backup.sgml @@ -3,7 +3,7 @@ 备份和恢复 - backup + 备份 与任何保存重要数据的系统一样,PostgreSQL数据库也应定期备份。虽然其过程基本简单,但清楚理解其底层技术和前提假设非常重要。 @@ -74,7 +74,7 @@ psql -X dbname < psql -X --set ON_ERROR_STOP=on dbname < dumpfile - 无论如何,你最终只会得到一个部分恢复的数据库。另一种做法是指定将整个转储作为单个事务恢复,这样恢复要么全部完成,要么全部回滚。可以通过把命令行选项传给psql来启用这种模式。使用这种模式时要注意,即便是一个很小的错误,也可能回滚一个已经运行了许多小时的恢复过程。不过,这仍可能比在部分恢复后手工清理一个复杂数据库更可取。 + 无论采用上述哪种方式,你最终只会得到一个部分恢复的数据库。另一种做法是指定将整个转储作为单个事务恢复,这样恢复要么全部完成,要么全部回滚。可以通过把命令行选项传给psql来启用这种模式。使用这种模式时要注意,即便是一个很小的错误,也可能回滚一个已经运行了许多小时的恢复过程。不过,这仍可能比在部分恢复后手工清理一个复杂数据库更可取。 @@ -194,7 +194,7 @@ pg_restore -d dbname - 对于非常大的数据库,你可能需要把split与前两种方法之一结合使用。 + 对于非常大的数据库,你可能需要把split与另外两种方法之一结合使用。 @@ -250,7 +250,7 @@ tar -cf backup.tar /usr/local/pgsql/data - 如果无法获得同时的快照,一种选择是将数据库服务器关闭足够长的时间,以建立所有冻结快照。另一种选择是执行持续归档基础备份(),因为这种备份不受备份期间文件系统变化的影响。这要求只在备份过程中启用持续归档;恢复则使用持续归档恢复()。 + 如果无法获得同时的快照,一种选择是将数据库服务器关闭足够长的时间,以建立所有冻结快照。另一种选择是执行持续归档基础备份(),因为这种备份不受备份期间文件系统变化的影响。这种方法只需在备份期间启用持续归档;恢复则使用持续归档恢复()。 @@ -266,11 +266,11 @@ tar -cf backup.tar /usr/local/pgsql/data 持续归档和时间点恢复(PITR) - continuous archiving + 持续归档 - point-in-time recovery + 时间点恢复 @@ -310,7 +310,7 @@ tar -cf backup.tar /usr/local/pgsql/data - 和普通文件系统备份技术一样,这种方法只能支持整个数据库集簇的恢复,而不支持其中某个子集的恢复。此外,它需要大量归档存储:基础备份可能很庞大,繁忙系统也会产生大量必须归档的 WAL 流量。尽管如此,在很多需要高可靠性的场景中,它仍是首选的备份技术。 + 和普通文件系统备份技术一样,这种方法只能支持整个数据库集簇的恢复,而不支持其中某个子集的恢复。此外,它需要大量归档存储:基础备份可能很庞大,繁忙系统也会产生许多兆字节的、必须归档的 WAL 流量。尽管如此,在很多需要高可靠性的场景中,它仍是首选的备份技术。 @@ -325,60 +325,42 @@ tar -cf backup.tar /usr/local/pgsql/data - 在归档 WAL 数据时,我们需要在每个段文件写满后捕获其内容,并在该段文件被回收重用之前把数据保存到某处。根据应用场景和可用硬件的不同,把数据保存到某处可以有很多不同的方法:可以把段文件复制到另一台机器上的 NFS 挂载目录,把它们写到磁带机中(确保你有办法识别每个文件的原始文件名),把它们批量打包后刻录到 CD 上,或者采用完全不同的方式。为了给数据库管理员提供灵活性,PostgreSQL尽量不对归档方式作任何假设。相反,PostgreSQL允许管理员指定一个 shell 命令或一个归档库,以便把已完成的段文件复制到它应去的地方。这既可以只是一个使用cp的 shell 命令,也可以调用一个复杂的 C 函数,全由你决定。 + 在归档 WAL 数据时,我们需要在每个段文件写满后捕获其内容,并在该段文件被回收重用之前把数据保存到某处。根据应用场景和可用硬件的不同,把数据保存到某处可以有很多不同的方法:可以把段文件复制到另一台机器上的 NFS 挂载目录,把它们写到磁带机中(确保你有办法识别每个文件的原始文件名),把它们批量打包后刻录到 CD 上,或者采用完全不同的方式。为了给数据库管理员提供灵活性,PostgreSQL尽量不对归档方式作任何假设。相反,PostgreSQL允许管理员指定一个 shell 命令,以便把已完成的段文件复制到它应去的地方。该命令可以只是一次简单的cp调用,也可以调用一个复杂的 shell 脚本,全由你决定。 - - 要启用 WAL 归档,请将配置参数设置为replica或更高,将设置为on,并在配置参数中指定要使用的 shell 命令。实际上,这些设置通常都会放在postgresql.conf文件中。 - - - - 在archive_command中,%p会被替换为待归档文件的路径名,而%f只会被替换为文件名。(该路径名相对于当前工作目录,也就是集簇的数据目录。)如果需要在命令中嵌入实际的%字符,请使用%%。最简单而有用的命令类似如下: - + 要启用 WAL 归档,请将 配置参数设为 replica 或更高值,将 设为 on,并在 配置参数中指定要执行的 shell 命令。实际使用中,这些设置始终放在 postgresql.conf 文件中。对于 archive_command, + %p 会被替换为要归档文件的路径名,而 %f 只会被替换为文件名。(路径名相对于当前工作目录,即集簇的数据目录。)使用 %% 可以在命令中嵌入实际的 % 字符。最简单的可用命令类似于: archive_command = 'test ! -f /mnt/server/archivedir/%f && cp %p /mnt/server/archivedir/%f' # Unix archive_command = 'copy "%p" "C:\\server\\archivedir\\%f"' # Windows - - 它会把可归档的 WAL 段复制到目录/mnt/server/archivedir中。(这只是一个示例,不是推荐做法,而且未必适用于所有平台。)在替换了%p%f参数之后,实际执行的命令可能类似于: - +这会将可归档的 WAL 段复制到目录 /mnt/server/archivedir。(这只是示例,并非推荐做法,而且不一定适用于所有平台。)在替换 %p%f 参数后,实际执行的命令可能如下: test ! -f /mnt/server/archivedir/00000001000000A900000065 && cp pg_wal/00000001000000A900000065 /mnt/server/archivedir/00000001000000A900000065 - - 对每个新的待归档文件都会生成一条类似的命令。 - - - - 归档命令会以运行PostgreSQL服务器的同一操作系统用户身份执行。由于这一系列被归档的 WAL 文件实际上包含了数据库中的几乎全部内容,因此你应确保归档数据不会被他人窥探;例如,把它归档到一个不向组或所有用户开放读权限的目录中。 - +每个需要归档的新文件都会生成一条类似的命令。 - - 重要的是,归档命令只有在成功时才返回零退出状态。收到零结果后,PostgreSQL会认为该文件已经成功归档,并会将其删除或回收。相反,非零状态会告诉PostgreSQL该文件尚未归档;系统会周期性重试,直到成功为止。 - + 归档命令将以运行 PostgreSQL 服务器的同一用户身份执行。由于归档的一系列 WAL 文件实际上包含数据库中的全部内容,应确保归档数据不会被他人窥视;例如,将其归档到不允许所属组或其他用户读取的目录。 - - 当归档命令被信号终止(用于服务器关闭流程的SIGTERM除外),或者 shell 因退出状态大于 125 的错误(例如命令未找到)而失败,或者归档函数发出ERRORFATAL时,归档器进程会中止,并由 postmaster 重新启动。在这种情况下,失败不会记录到中。 - + 归档命令必须当且仅当成功时才返回退出状态零。收到零状态后,PostgreSQL 会认为该文件已成功归档,并将其删除或回收。非零状态则告诉 PostgreSQL 该文件尚未归档;它会定期重试,直到成功。 - 归档命令和归档库通常都应设计为拒绝覆盖任何已存在的归档文件。这是一项重要的安全特性,可在管理员出错时保护归档的完整性(例如把两台不同服务器的输出发送到同一个归档目录)。建议测试你打算使用的归档库,以确保它不会覆盖已有文件。 + 当归档命令被信号终止(用于服务器关闭流程的SIGTERM除外),或者因 shell 报错(例如命令未找到)而以大于 125 的状态退出时,归档器进程会中止,并由 postmaster 重新启动。在这种情况下,失败不会记录到中。 - - 在少数情况下,PostgreSQL可能会尝试重新归档一个此前已经归档过的 WAL 文件。例如,如果系统在服务器把归档成功持久记录下来之前崩溃,服务器在重启后会再次尝试归档该文件(前提是归档仍然启用)。当归档命令或归档库遇到一个已存在的文件时,如果该文件与待归档 WAL 文件内容完全相同,且先前归档的文件已经完全持久化到存储,则前者应分别返回零状态或true。如果已存在文件的内容与正在归档的 WAL 文件不同,则归档命令或归档库必须分别返回非零状态或false。 - + 通常应将归档命令设计为拒绝覆盖任何已存在的归档文件。这是一项重要的安全保护措施,能在管理员操作失误时(例如将两台不同服务器的输出发送到同一归档目录)维护归档的完整性。 - 上面给出的 Unix 示例命令通过单独加入一个test步骤,避免覆盖已有归档。在某些 Unix 平台上,cp提供了诸如之类的开关,也可以更简洁地实现同样目的,但在你确认它会返回正确的退出状态之前,不应依赖这些开关。(尤其是 GNU cp在使用且目标文件已存在时会返回状态零,这不是我们想要的行为。) + 建议测试所拟定的归档命令,确保它确实不会覆盖已有文件,并且在这种情况下返回非零状态。上面给出的 Unix 示例命令通过单独加入一个test步骤,确保这两点。在某些 Unix 平台上,cp提供了诸如之类的开关,也可以更简洁地实现同样目的,但在你确认它会返回正确的退出状态之前,不应依赖这些开关。(尤其是 GNU cp在使用且目标文件已存在时会返回状态零,这不是我们想要的行为。) - 在设计归档方案时,请考虑如果归档命令或归档库因为某些环节需要操作员干预,或者归档空间耗尽而反复失败,会发生什么。例如,如果你在没有自动换带器的情况下向磁带写入数据,那么磁带满了以后,在更换磁带之前将无法继续归档。你应确保任何错误情况或对人工操作员的请求都能得到适当报告,以便问题能够比较快地解决。在问题解决之前,pg_wal/目录会继续堆积 WAL 段文件。(如果包含pg_wal/的文件系统被写满,PostgreSQL将执行 PANIC 关闭。不会丢失已提交的事务,但在释放出一些空间之前,数据库会一直离线。) + 在设计归档方案时,请考虑如果归档命令因为某些环节需要操作员干预,或者归档空间耗尽而反复失败,会发生什么。例如,如果你在没有自动换带器的情况下向磁带写入数据,那么磁带满了以后,在更换磁带之前将无法继续归档。你应确保任何错误情况或对人工操作员的请求都能得到适当报告,以便问题能够比较快地解决。在问题解决之前,pg_wal/目录会继续堆积 WAL 段文件。(如果包含pg_wal/的文件系统被写满,PostgreSQL将执行 PANIC 关闭。不会丢失已提交的事务,但在释放出一些空间之前,数据库会一直离线。) - 归档命令或归档库的速度并不重要,只要它能跟上服务器生成 WAL 数据的平均速度即可。即使归档过程稍有滞后,正常操作也会继续。如果归档明显落后,灾难发生时可能丢失的数据量就会增加。这还意味着pg_wal/目录会包含大量尚未归档的段文件,最终可能耗尽可用磁盘空间。建议监控归档过程,确保它按你的预期工作。 + 归档命令的速度并不重要,只要它能跟上服务器生成 WAL 数据的平均速度即可。即使归档过程稍有滞后,正常操作也会继续。如果归档明显落后,灾难发生时可能丢失的数据量就会增加。这还意味着pg_wal/目录会包含大量尚未归档的段文件,最终可能耗尽可用磁盘空间。建议监控归档过程,确保它按你的预期工作。 - 在编写归档命令或归档库时,应假定待归档文件名最长可达 64 个字符,并且可以包含 ASCII 字母、数字和点号的任意组合。无需保留原始相对路径(%p),但必须保留文件名(%f)。 + 在编写归档命令时,应假定待归档文件名最长可达 64 个字符,并且可以包含 ASCII 字母、数字和点号的任意组合。无需保留原始相对路径(%p),但必须保留文件名(%f)。 @@ -386,7 +368,7 @@ test ! -f /mnt/server/archivedir/00000001000000A900000065 && cp pg_wal/0 - 归档命令或归档函数只会在完整的 WAL 段上被调用。因此,如果服务器产生的 WAL 流量很小(或者存在低谷期),事务完成到其被安全写入归档存储之间可能会有很长延迟。为了限制未归档数据可能有多旧,你可以设置,强制服务器至少隔这么长时间切换到一个新的 WAL 段文件。注意,由强制切换而提前归档的文件长度仍与装满的文件相同。因此,把archive_timeout设得很短并不明智,这会使归档存储膨胀。archive_timeout设为大约 1 分钟通常是合理的。 + 归档命令只会针对已完成的 WAL 段调用。因此,如果服务器产生的 WAL 流量很小(或者存在低谷期),事务完成到其被安全写入归档存储之间可能会有很长延迟。为了限制未归档数据可能有多旧,你可以设置,使服务器强制切换到新 WAL 段文件的间隔不超过这个值。注意,由强制切换而提前归档的文件长度仍与装满的文件相同。因此,把archive_timeout设得很短并不明智,这会使归档存储膨胀。archive_timeout设为大约 1 分钟通常是合理的。 @@ -394,7 +376,7 @@ test ! -f /mnt/server/archivedir/00000001000000A900000065 && cp pg_wal/0 - 当wal_levelminimal时,某些 SQL 命令会像中所述那样被优化为避免 WAL 记录。如果在执行这些语句期间启用了归档或流复制,WAL 将不包含归档恢复所需的足够信息。(崩溃恢复不受影响。)因此,wal_level只能在服务器启动时更改。然而,archive_command可以通过重新加载配置文件来更改。如果你通过 shell 进行归档并希望暂时停止归档,一种办法是将archive_command设置为空字符串('')。这会导致 WAL 文件在pg_wal/中累积,直到重新建立可用的archive_command。 + 当wal_levelminimal时,某些 SQL 命令会像中所述那样被优化为避免 WAL 记录。如果在执行这些语句期间启用了归档或流复制,WAL 将不包含归档恢复所需的足够信息。(崩溃恢复不受影响。)因此,wal_level只能在服务器启动时更改。然而,archive_command可以通过重新加载配置文件来更改。如果你希望暂时停止归档,一种办法是将archive_command设置为空字符串('')。这会导致 WAL 文件在pg_wal/中累积,直到重新建立可用的archive_command @@ -423,13 +405,13 @@ test ! -f /mnt/server/archivedir/00000001000000A900000065 && cp pg_wal/0 - 使用低级接口进行基础备份 - - 除了使用进行基础备份之外,你还可以使用低级接口制作基础备份。这个过程比pg_basebackup方法多几个步骤,但相对简单。极其重要的是,这些步骤必须按顺序执行,并且在进行下一步之前必须确认当前步骤已经成功。 - - - 多个备份可以并发运行(无论是通过该备份接口启动的,还是通过启动的)。 - + 使用低级 API 进行基础备份 + 使用低级 API 制作基础备份的过程,比 方法多几个步骤,但相对简单。务必按顺序执行这些步骤,并在继续下一步之前确认当前步骤成功。 + 低级基础备份可以采用非排他或排他方式。建议使用非排他方式;排他方式已弃用,最终将被移除。 + + + 制作非排他低级备份 + 非排他低级备份允许同时运行其他备份,包括使用同一备份 API 启动的备份和使用 启动的备份。 @@ -438,18 +420,13 @@ test ! -f /mnt/server/archivedir/00000001000000A900000065 && cp pg_wal/0 - - 以具有执行pg_start_backup权限的用户身份连接到服务器(连接哪个数据库并不重要)(超级用户,或者在该函数上被授予EXECUTE权限的用户),并发出以下命令: - -SELECT pg_start_backup(label => 'label', fast => false); - - 其中label是你想用来唯一标识此次备份操作的任意字符串。调用pg_start_backup的连接必须保持到备份结束,否则备份会自动中止。 - + 以有权运行 pg_start_backup 的用户身份(超级用户,或已被授予该函数 EXECUTE 权限的用户)连接到服务器(连接哪个数据库都可以),并执行命令: +SELECT pg_start_backup('label', false, false); +其中,label 是用于唯一标识此次备份操作的任意字符串。调用 pg_start_backup 的连接必须一直保持到备份结束,否则备份会自动中止。 - - 在线备份总是从一个检查点的开始处启动。默认情况下,pg_start_backup会等待下一个按计划执行的检查点完成,这可能需要很长时间(见配置参数)。这通常更可取,因为它能把对运行系统的影响降到最低。如果你希望尽快开始备份,可将true作为第二个参数传给pg_start_backup;它会请求立即执行检查点,并尽可能快地完成,尽可能多地使用 I/O。 - + 默认情况下,pg_start_backup 可能需要很长时间才能完成。这是因为它会执行一次检查点,而检查点所需的 I/O 会分散在较长时间内,默认是检查点间隔的一半(参见配置参数 )。这通常是理想的行为,因为它尽量减少了对查询处理的影响。如果希望尽快开始备份,请将第二个参数改为 true,这会尽可能利用可用 I/O 立即执行检查点。 + 第三个参数为 false,会告知 pg_start_backup 启动非排他基础备份。 @@ -457,13 +434,9 @@ SELECT pg_start_backup(label => 'label', fast => false); - - 在与之前相同的连接中,发出以下命令: - -SELECT * FROM pg_stop_backup(wait_for_archive => true); - - 这会终止备份模式。在主库上,它还会自动切换到下一个 WAL 段。在备库上,无法自动切换 WAL 段,因此你可能希望在主库上运行pg_switch_wal手工执行切换。进行该切换是为了使在备份区间内写入的最后一个 WAL 段文件准备好进行归档。 - + 在之前的同一个连接中,执行命令: +SELECT * FROM pg_stop_backup(false, true); +这会终止备份模式。在主库上,还会自动切换到下一个 WAL 段。在备库上,无法自动切换 WAL 段,因此可以运行 pg_switch_wal,在主库上手动切换。切换的目的是让备份期间写入的最后一个 WAL 段文件准备好归档。 pg_stop_backup会返回一行,包含三个值。其中第二个字段应写入备份根目录下名为backup_label的文件中。第三个字段除非为空,否则应写入名为tablespace_map的文件中。这些文件对备份能否正常工作至关重要,必须逐字节原样写入,不能做任何修改,这可能意味着需要以二进制模式打开文件。 @@ -478,6 +451,50 @@ SELECT * FROM pg_stop_backup(wait_for_archive => true); + + + 制作排他低级备份 + + + 排他备份方法已弃用,应避免使用。在 PostgreSQL 9.6 之前,这是唯一可用的低级方法,但现在建议所有用户更新脚本,改用非排他备份。 + + + 排他备份的过程与非排他备份基本相同,但有几个关键步骤不同。这种备份只能在主库上进行,且不允许并发备份。此外,由于它会创建下文所述的备份标签文件,可能会阻止主库在崩溃后自动重启。另一方面,误删备份或备库中的此文件也是一种常见错误,可能导致严重的数据损坏。如果必须使用这种方法,可以按以下步骤操作。 + + + + + 确保 WAL 归档已启用并正常工作。 + + + + 以有权运行 pg_start_backup 的用户身份(超级用户,或已被授予该函数 EXECUTE 权限的用户)连接到服务器(连接哪个数据库都可以),并执行命令: +SELECT pg_start_backup('label'); +其中,label 是用于唯一标识此次备份操作的任意字符串。pg_start_backup 会创建一个备份标签文件,名为 backup_label,位于集簇目录中,包含备份信息,例如开始时间和标签字符串。该函数还会创建一个表空间映射文件,名为 tablespace_map,位于集簇目录中,包含 pg_tblspc/ 中表空间符号链接的信息(如果存在一个或多个这样的链接)。如果需要从备份恢复,这两个文件对备份的完整性都至关重要。 + + 默认情况下,pg_start_backup 可能需要很长时间才能完成。这是因为它会执行一次检查点,而检查点所需的 I/O 会分散在较长时间内,默认是检查点间隔的一半(参见配置参数 )。这通常是理想的行为,因为它尽量减少了对查询处理的影响。如果希望尽快开始备份,请使用: +SELECT pg_start_backup('label', true); +这会强制尽快完成检查点。 + + + + 使用任何方便的文件系统备份工具执行备份,例如tarcpio(不要使用pg_dumppg_dumpall)。在此过程中既没有必要,也不希望停止数据库的正常运行。关于执行此备份时需要注意的事项,见。 + + 如上所述,如果服务器在备份期间崩溃,可能必须手动删除 PGDATA 目录中的 backup_label 文件后才能重启。务必注意,在恢复备份时绝不能删除 backup_label 文件,否则会导致数据损坏。使用这种方法时,混淆何时应删除此文件是造成数据损坏的常见原因;务必确认只在现有主库上删除此文件,绝不能在创建备库或恢复备份时删除,即使所创建的备库随后会被提升为新主库也不例外。 + + + 再次以有权运行 pg_stop_backup 的用户身份(超级用户,或已被授予该函数 EXECUTE 权限的用户)连接到数据库,并执行命令: +SELECT pg_stop_backup(); +该函数会终止备份模式,并自动切换到下一个 WAL 段。切换的目的是让备份期间写入的最后一个 WAL 段准备好归档。 + + + 备份期间处于活动状态的 WAL 段文件全部归档后,备份就完成了。pg_stop_backup 返回结果所标识的文件,是构成完整备份文件集所需的最后一个段。如果启用了 archive_modepg_stop_backup 会等到最后一个段归档后才返回。由于已经配置了 archive_command,这些文件会自动归档。大多数情况下,归档很快就能完成,但建议监控归档系统,确保没有延迟。如果归档进程因归档命令失败而落后,它会不断重试,直到归档成功、备份完成。 + + 使用排他备份模式时,必须确保 pg_stop_backup 在备份结束时成功完成。即使备份本身失败(例如磁盘空间不足),未调用 pg_stop_backup 也会使服务器无限期地处于备份模式,导致后续备份失败,并增加 backup_label 存在期间重启失败的风险。 + + + + 备份数据目录 @@ -496,9 +513,7 @@ SELECT * FROM pg_stop_backup(wait_for_archive => true); 通常也最好省略集簇pg_replslot/目录中的文件,以免主库上的复制槽成为备份的一部分。否则,之后用该备份创建备库时,可能导致该备库上的 WAL 文件无限期保留;如果启用了热备反馈,也可能导致主库膨胀,因为使用这些复制槽的客户端仍会连接到并更新主库上的槽,而不是备库上的槽。即使该备份只是用来创建新的主库,复制这些复制槽通常也没有多大意义,因为等新主库上线时,这些槽的内容很可能已经严重过时。 - - 目录pg_dynshmem/pg_notify/pg_serial/pg_snapshots/pg_stat_tmp/pg_subtrans/的内容(但不包括这些目录本身)都可以从备份中省略,因为它们会在 postmaster 启动时初始化。 - + 备份可以省略 pg_dynshmem/pg_notify/pg_serial/pg_snapshots/pg_stat_tmp/pg_subtrans/ 目录中的内容(但不能省略目录本身),因为它们会在 postmaster 启动时初始化。如果设置了 且该目录位于数据目录中,也可以省略其内容。 任何以pgsql_tmp开头的文件或目录都可以从备份中省略。这些文件会在 postmaster 启动时被删除,而这些目录也会在需要时重新创建。 @@ -541,7 +556,7 @@ SELECT * FROM pg_stop_backup(wait_for_archive => true); - 如果你正在恢复完整备份,可以把数据库文件直接恢复到目标目录中。务必确保它们以正确的所有者(数据库系统用户,而不是root!)和正确的权限恢复。如果使用了表空间,还应验证pg_tblspc/中的符号链接是否已正确恢复。 + 从文件系统备份中恢复数据库文件。务必确保它们以正确的所有者(数据库系统用户,而不是root!)和正确的权限恢复。如果使用了表空间,还应验证pg_tblspc/中的符号链接是否已正确恢复。 @@ -572,20 +587,16 @@ SELECT * FROM pg_stop_backup(wait_for_archive => true); - - 这一切的关键在于设置一个恢复配置,描述你希望如何恢复,以及恢复应运行到什么位置。其中绝对必须指定的一项是restore_command,它告诉PostgreSQL如何检索已归档的 WAL 文件段。像archive_command一样,它也是一个 shell 命令字符串。它可以包含%f,会被替换为所需 WAL 文件的名称;也可以包含%p,会被替换为复制该 WAL 文件时要使用的路径名。(该路径名相对于当前工作目录,也就是集簇的数据目录。)如果需要在命令中嵌入实际的%字符,请写成%%。最简单而有用的命令类似如下: - + 整个过程的关键,是设置恢复配置,说明希望如何恢复,以及恢复到什么位置。必须指定的设置是 restore_command,它告诉 PostgreSQL 如何获取已归档的 WAL 段文件。与 archive_command 一样,它是一个 shell 命令字符串,可以包含 %f,该标记会被替换为所需日志文件的名称;还可以包含 %p,该标记会被替换为日志文件要复制到的路径名。(路径名相对于当前工作目录,即集簇的数据目录。)使用 %% 可以在命令中嵌入实际的 % 字符。最简单的可用命令类似于: restore_command = 'cp /mnt/server/archivedir/%f %p' - - 它会从目录/mnt/server/archivedir中复制先前归档的 WAL 段。当然,你也可以使用复杂得多的方案,甚至写一个 shell 脚本来要求操作员装载合适的磁带。 - +这会复制先前归档的 WAL 段,来源目录为 /mnt/server/archivedir。当然,也可以使用复杂得多的命令,甚至可以使用要求操作人员挂载相应磁带的 shell 脚本。 - 重要的是,该命令在失败时必须返回非零退出状态。系统调用该命令来请求归档中不存在的文件;遇到这种情况时,它就应返回非零值。这不是一种错误情况。例外是,如果该命令被信号终止(用于数据库服务器关闭的SIGTERM除外),或者因 shell 错误(如命令未找到)而失败,那么恢复将中止,服务器也不会启动。 + 重要的是,该命令在失败时必须返回非零退出状态。系统调用该命令来请求归档中不存在的文件;遇到这种情况时,它必须返回非零值。这不是一种错误情况。例外是,如果该命令被信号终止(用于数据库服务器关闭的SIGTERM除外),或者因 shell 错误(如命令未找到)而失败,那么恢复将中止,服务器也不会启动。 - 被请求的文件并不全都是 WAL 段文件;你还应预期会收到对带有.history后缀文件的请求。另外请注意,%p路径的基本文件名会与%f不同;不要指望它们可以互换使用。 + 被请求的文件并不全都是 WAL 段文件;你还应预期会收到对带有.history后缀文件的请求。另外请注意,%p路径的文件名部分会与%f不同;不要指望它们可以互换使用。 @@ -593,16 +604,16 @@ restore_command = 'cp /mnt/server/archivedir/%f %p' - 通常,恢复会处理完所有可用的 WAL 段,从而把数据库恢复到当前时间点(或者在可用 WAL 段所允许的情况下尽可能接近当前时间点)。因此,一次正常恢复通常会以一条file not found消息结束,具体错误文本取决于你选择的restore_command。在恢复开始时,你也可能看到一条针对类似00000001.history文件的错误消息。这同样是正常的,在简单恢复场景中并不表示有问题;相关讨论见。 + 通常,恢复会处理完所有可用的 WAL 段,从而把数据库恢复到当前时间点(或者在可用 WAL 段所允许的情况下尽可能接近当前时间点)。因此,一次正常恢复会以一条file not found消息结束,具体错误文本取决于你选择的restore_command。在恢复开始时,你也可能看到一条针对类似00000001.history文件的错误消息。这同样是正常的,在简单恢复场景中并不表示有问题;相关讨论见 - 如果你希望恢复到过去的某个时间点(例如恢复到那位初级 DBA 删掉你的主事务表之前),只需指定所需的停止点即可。这个停止点也称为恢复目标,可以通过日期/时间、命名恢复点或者某个特定事务 ID 完成时刻来指定。在目前的实现下,只有日期/时间和命名恢复点这两种方式真正比较实用,因为没有工具能够帮助你足够准确地识别应使用哪个事务 ID。 + 如果你希望恢复到过去的某个时间点(例如恢复到那位初级 DBA 删掉你的主事务表之前),只需指定所需的停止点即可。这个停止点也称为恢复目标,可以通过日期/时间、命名恢复点或者某个特定事务 ID 完成时刻来指定。在撰写本文时,只有日期/时间和命名恢复点这两种方式真正比较实用,因为没有工具能够帮助你足够准确地识别应使用哪个事务 ID。 - 停止点必须晚于基础备份的结束时间,也就是pg_stop_backup的结束时间。你不能用某次基础备份恢复到该备份仍在进行中的时间点。(若要恢复到这样的时间点,必须回到更早的一次基础备份,再从那里向前滚动。) + 停止点必须晚于基础备份的结束时间,也就是pg_stop_backup的结束时间。你不能用某次基础备份恢复到该备份仍在进行中的时间点。(若要恢复到这样的时间点,必须回到更早的一次基础备份,再从那里向前重放日志。) @@ -616,28 +627,18 @@ restore_command = 'cp /mnt/server/archivedir/%f %p' 时间线 - timelines + 时间线 - - 把数据库恢复到过去某个时间点的能力,会带来一些复杂性,颇有点像关于时间旅行和平行宇宙的科幻小说。例如,在数据库的原始历史中,假设你在星期二晚上 5:15 删掉了一张关键表,但直到星期三中午才意识到自己的错误。于是你拿出备份,把系统恢复到星期二晚上 5:14,并重新上线运行。在数据库宇宙的这条历史中,你从未删掉那张表。但如果你后来发现这并不是个好主意,并且想回到原始历史中的星期三上午某个时间点,就办不到了,因为在数据库重新上线运行期间,它可能已经覆盖了某些 WAL 段文件,而这些文件本来能把你带回到现在想回去的那个时刻。因此,为了避免这种情况,你需要把时间点恢复之后生成的那一串 WAL 记录,与数据库原始历史中生成的那些 WAL 记录区分开来。 - + 能够将数据库恢复到过去某个时间点,也会带来一些类似科幻故事中时间旅行和平行宇宙的复杂情况。例如,假设在数据库原来的历史中,你在周二下午 5:15 删除了一张重要的表,直到周三中午才发现错误。你从容地取出备份,将数据库恢复到周二下午 5:14,然后重新投入运行。在数据库宇宙的这段历史中,你从未删除过那张表。但假设你后来发现这样做不太合适,希望回到原来历史中的周三上午某个时刻。如果数据库恢复运行后覆盖了通往该时刻所需的某些 WAL 段文件,就无法回去了。因此,为了避免这种情况,需要区分时间点恢复后产生的一系列 WAL 记录与数据库原来历史中产生的记录。 - - 为了解决这个问题,PostgreSQL引入了时间线的概念。每当一次归档恢复完成时,系统都会创建一条新的时间线,用来标识此次恢复之后生成的 WAL 记录序列。时间线 ID 是 WAL 段文件名的一部分,因此新的时间线不会覆盖先前时间线产生的 WAL 数据。例如,在 WAL 文件名0000000100001234000055CD中,开头的00000001就是十六进制表示的时间线 ID。(注意,在服务器日志消息等其他场合,时间线 ID 通常以十进制打印。) - - - - 实际上,完全可以归档许多不同的时间线。虽然这看起来像是个没什么用的特性,但它往往能救命。设想这样一种情况:你不太确定应恢复到哪个时间点,因此不得不通过反复试验做几次时间点恢复,直到找到从旧历史分叉出去的最佳位置。如果没有时间线,这个过程很快就会变成一团无法管理的混乱。有了时间线,你可以恢复到任何先前状态,包括那些你早先已经放弃的时间线分支上的状态。 - + 为解决这一问题,PostgreSQL 引入了时间线的概念。每当归档恢复完成,系统都会创建一条新时间线,用于标识此次恢复之后产生的一系列 WAL 记录。时间线 ID 是 WAL 段文件名的一部分,因此新时间线不会覆盖旧时间线产生的 WAL 数据。实际上,可以归档许多不同的时间线。这个功能看似没什么用,却常常能救急。比如,你不能确定应该恢复到哪个时间点,需要反复尝试时间点恢复,直到找到脱离旧历史的最佳分支点。没有时间线,这个过程很快就会乱得无法管理。有了时间线,就可以恢复到任何先前的状态,包括早先已放弃的时间线分支中的状态。 每当创建一条新的时间线时,PostgreSQL都会创建一个时间线历史文件,记录它是从哪条时间线、在何时分叉出来的。当从包含多条时间线的归档中恢复时,这些历史文件对于系统选取正确的 WAL 段文件是必需的。因此,它们会像 WAL 段文件一样被归档到 WAL 归档区域。历史文件只是很小的文本文件,因此长期保存它们既便宜也合适(而段文件通常很大)。如果你愿意,还可以在历史文件中加入注释,记录创建这条时间线的方式和原因。当你因实验而积累出一批错综复杂的时间线时,这类注释会特别有价值。 - - 恢复的默认行为是恢复到归档中找到的最新时间线。如果你希望恢复到执行基础备份时的当前时间线,或者恢复到某个指定的子时间线(也就是说,你想回到某个本身就是在一次恢复尝试之后才产生的状态),就需要指定current,或者在中指定目标时间线 ID。你不能恢复到那些在基础备份之前就已经分叉出去的时间线。 - + 默认的恢复行为是恢复到归档中找到的最新时间线。如果希望恢复到制作基础备份时的当前时间线,或者某条特定的子时间线(即希望返回到一次恢复尝试之后产生的某个状态),需要在 中指定 current 或目标时间线 ID。不能恢复到在基础备份之前就已分支出去的时间线。 @@ -648,15 +649,29 @@ restore_command = 'cp /mnt/server/archivedir/%f %p' - 单机热备份 + 独立热备份 - 可以利用PostgreSQL的备份设施生成单机热备份。这些备份不能用于时间点恢复,但它们的制作和恢复通常都比pg_dump转储快得多。(它们也比pg_dump转储大得多,因此在某些情况下速度优势可能会被抵消。) + 可以利用PostgreSQL的备份设施生成独立热备份。这些备份不能用于时间点恢复,但它们的制作和恢复通常都比pg_dump转储快得多。(它们也比pg_dump转储大得多,因此在某些情况下速度优势可能会被抵消。) - 和基础备份一样,生成单机热备份最简单的方法是使用工具。如果在调用它时包含-X参数,使用该备份所需的全部预写式日志都会自动包含在备份中,恢复该备份时也不需要额外动作。 + 和基础备份一样,生成独立热备份最简单的方法是使用工具。如果在调用它时包含-X参数,使用该备份所需的全部预写式日志都会自动包含在备份中,恢复该备份时也不需要额外动作。 + + 如果复制备份文件时需要更大的灵活性,也可以使用更低级的流程制作独立热备份。要准备低级独立热备份,请确保将 wal_level 设为 replica 或更高值,将 archive_mode 设为 on,并配置一个 archive_command,使其仅在开关文件存在时执行归档。例如: +archive_command = 'test ! -f /var/lib/pgsql/backup_in_progress || (test ! -f /var/lib/pgsql/archive/%f && cp %p /var/lib/pgsql/archive/%f)' +/var/lib/pgsql/backup_in_progress 存在时,这条命令会执行归档;否则会静默地返回零退出状态(允许 PostgreSQL 回收不需要的 WAL 文件)。 + + 做好上述准备后,就可以使用类似下面的脚本进行备份: +touch /var/lib/pgsql/backup_in_progress +psql -c "select pg_start_backup('hot_backup');" +tar -cf /var/lib/pgsql/backup.tar /var/lib/pgsql/data/ +psql -c "select pg_stop_backup();" +rm /var/lib/pgsql/backup_in_progress +tar -rf /var/lib/pgsql/backup.tar /var/lib/pgsql/archive/ +首先创建开关文件 /var/lib/pgsql/backup_in_progress,以启用已完成 WAL 文件的归档。备份完成后删除该开关文件。随后将已归档的 WAL 文件加入备份,使基础备份与所有必需的 WAL 文件都包含在同一个 tar 文件中。请记得在备份脚本中加入错误处理。 + @@ -686,7 +701,7 @@ archive_command = 'local_backup_script.sh "%p" "%f"' - 脚本中可能需要解决的需求示例包括: + 可以在脚本中处理的需求示例包括: @@ -695,7 +710,7 @@ archive_command = 'local_backup_script.sh "%p" "%f"' - 把 WAL 文件成批处理,使其每三个小时传输一次,而不是每生成一个就传一次 + 把 WAL 文件成批处理,使其每三个小时传输一次,而不是每次只传输一个 diff --git a/zh/14/brin.sgml b/zh/14/brin.sgml index 57c3e540..c953f120 100644 --- a/zh/14/brin.sgml +++ b/zh/14/brin.sgml @@ -4,7 +4,7 @@ BRIN 索引 - index + 索引 BRIN @@ -25,8 +25,7 @@ - 如果索引中存储的摘要信息与查询条件相一致BRIN - 索引就可以通过常规位图索引扫描来满足查询,并返回每个范围内所有页上的全部元组。 + BRIN 索引可以通过常规位图索引扫描来满足查询;对于每个范围,如果索引中存储的摘要信息与查询条件相一致,就会返回该范围内所有页上的全部元组。 查询执行器负责重新检查这些元组,并丢弃不匹配查询条件的元组 — 换句话说,这些索引是有损的。 由于 BRIN 索引非常小,与顺序扫描相比,扫描索引只会带来很小的额外开销, 但可以避免扫描那些已知不包含匹配元组的大块表数据。 @@ -68,9 +67,7 @@ - 最后,还可以使用下列函数(这些函数运行期间, - 会临时改为 - pg_catalog, pg_temp): + 最后,还可以使用下列函数: brin_summarize_new_values(regclass) @@ -85,7 +82,7 @@ 当启用自动摘要时,一旦检测到向下一个块范围第一页的第一项执行了插入, - 就会向 autovacuum 发送请求,要求对该块范围执行定向摘要。 + 就会向 autovacuum 发送请求,要求对前一个块范围执行定向摘要。 该请求会在同一数据库中的某个 autovacuum 工作进程下一次结束运行时得到处理。 如果请求队列已满,该请求就不会被记录,并会向服务器日志发送一条消息: @@ -790,13 +787,13 @@ LOG: request for BRIN range summarization for index "brin_wi_idx" page 128 was typedef struct BrinOpcInfo { - /* Number of columns stored in an index column of this opclass */ + /* 此操作符类在一个索引列中存储的列数 */ uint16 oi_nstored; - /* Opaque pointer for the opclass' private use */ + /* 供操作符类私有使用的不透明指针 */ void *oi_opaque; - /* Type cache entries of the stored columns */ + /* 所存储列的类型缓存条目 */ TypeCacheEntry *oi_typcache[FLEXIBLE_ARRAY_MEMBER]; } BrinOpcInfo; @@ -1012,62 +1009,62 @@ typedef struct BrinOpcInfo 操作符策略 1 - left-of 操作符 + 位于左侧的操作符 操作符策略 4 操作符策略 2 - does-not-extend-to-the-right-of 操作符 + 不延伸到右侧的操作符 操作符策略 5 操作符策略 3 - overlaps 操作符 + 重叠操作符 操作符策略 4 - does-not-extend-to-the-left-of 操作符 + 不延伸到左侧的操作符 操作符策略 1 操作符策略 5 - right-of 操作符 + 位于右侧的操作符 操作符策略 2 - 操作符策略 6, 18 - same-as-or-equal-to 操作符 + 操作符策略 6、18 + 相同或等于操作符 操作符策略 7 - 操作符策略 7, 16, 24, 25 - contains-or-equal-to 操作符 + 操作符策略 7、16、24、25 + 包含或等于操作符 - 操作符策略 8, 26, 27 - is-contained-by-or-equal-to 操作符 + 操作符策略 8、26、27 + 被包含或等于操作符 操作符策略 3 操作符策略 9 - does-not-extend-above 操作符 + 不延伸到上方的操作符 操作符策略 11 操作符策略 10 - is-below 操作符 + 位于下方的操作符 操作符策略 12 操作符策略 11 - is-above 操作符 + 位于上方的操作符 操作符策略 9 操作符策略 12 - does-not-extend-below 操作符 + 不延伸到下方的操作符 操作符策略 10 @@ -1113,12 +1110,12 @@ typedef struct BrinOpcInfo 要为仅实现等值操作符且支持哈希的数据类型编写操作符类,可以按 - 所示,将 bloom 支持过程与相应操作符一起使用。 - 所有操作符类成员(过程和操作符)都是必需的。 + 所示,将 bloom 支持函数与相应操作符一起使用。 + 所有操作符类成员(函数和操作符)都是必需的。 - bloom 操作符类的过程和支持编号 + bloom 操作符类的函数和支持编号 @@ -1128,28 +1125,28 @@ typedef struct BrinOpcInfo - 支持过程 1 + 支持函数 1 内部函数brin_bloom_opcinfo() - 支持过程 2 + 支持函数 2 内部函数brin_bloom_add_value() - 支持过程 3 + 支持函数 3 内部函数brin_bloom_consistent() - 支持过程 4 + 支持函数 4 内部函数brin_bloom_union() - 支持过程 5 + 支持函数 5 内部函数brin_bloom_options() - 支持过程 11 - 计算元素哈希值的函数 + 支持函数 11 + 计算元素 hash 值的函数 操作符策略 1 @@ -1160,20 +1157,20 @@ typedef struct BrinOpcInfo
- 支持过程编号 1 至 10 保留给 BRIN 内部函数,因此 SQL 层函数从编号 11 开始。 + 支持函数编号 1 至 10 保留给 BRIN 内部函数,因此 SQL 层函数从编号 11 开始。 支持函数 11 是构建索引所需的主要函数。 - 它应接受一个与操作符类数据类型相同的参数,并返回该值的哈希值。 + 它应接受一个与操作符类数据类型相同的参数,并返回该值的 hash 值。 minmax-multi 操作符类也面向实现全序集的数据类型,可以看作 minmax 操作符类的简单扩展。 minmax 操作符类把每个块范围中的值摘要为单个连续区间,而 minmax-multi 则允许将其摘要为多个较小区间,以改进对离群值的处理。 - 可以按 所示,将 minmax-multi 支持过程与相应操作符一起使用。 - 所有操作符类成员(过程和操作符)都是必需的。 + 可以按 所示,将 minmax-multi 支持函数与相应操作符一起使用。 + 所有操作符类成员(函数和操作符)都是必需的。 - minmax-multi 操作符类的过程和支持编号 + minmax-multi 操作符类的函数和支持编号 @@ -1183,27 +1180,27 @@ typedef struct BrinOpcInfo - 支持过程 1 + 支持函数 1 内部函数brin_minmax_multi_opcinfo() - 支持过程 2 + 支持函数 2 内部函数brin_minmax_multi_add_value() - 支持过程 3 + 支持函数 3 内部函数brin_minmax_multi_consistent() - 支持过程 4 + 支持函数 4 内部函数brin_minmax_multi_union() - 支持过程 5 + 支持函数 5 内部函数brin_minmax_multi_options() - 支持过程 11 + 支持函数 11 计算两个值之间距离(范围长度)的函数 diff --git a/zh/14/btree.sgml b/zh/14/btree.sgml index eebcf495..fb64d627 100644 --- a/zh/14/btree.sgml +++ b/zh/14/btree.sgml @@ -4,7 +4,7 @@ B-树索引 - index + 索引 B-树 @@ -18,10 +18,10 @@ - 由于每个 B-树 操作符类都会为其数据类型施加一种排序顺序,B-树 + 由于每个 B-树操作符类都会为其数据类型施加一种排序顺序,B-树 操作符类(更准确地说,是操作符族)已经成为 PostgreSQL 用来统一表示和理解排序语义的方式。因此,它们具备了一些超出单纯支持 - B-树 索引所需范围的特性,系统中某些与 btree AM + B-树索引所需范围的特性,系统中某些与 B-树 AM 相距甚远的部分也会利用它们。 @@ -55,7 +55,7 @@ - = 操作符必须是一种等价关系;也就是说,对于该数据类型的所有非空值 + = 操作符必须是一种等价关系;也就是说,对于该数据类型的所有非 null 值 ABC: @@ -93,7 +93,7 @@ - < 操作符必须是一种强排序关系;也就是说,对于所有非空值 + < 操作符必须是一种强排序关系;也就是说,对于所有非 null 值 ABC: @@ -123,7 +123,7 @@ - 此外,该顺序还是全序的;也就是说,对于所有非空值 + 此外,该顺序还是全序的;也就是说,对于所有非 null 值 AB: @@ -177,18 +177,18 @@ B-树支持函数 - 如所示,btree 定义了一个必需和五个可选的支持函数。六个用户定义的方法如下: + 如所示,B-树定义了一个必需和四个可选的支持函数。五个用户定义的方法如下: order - 对于 B-树 操作符族为其提供比较操作符的每一种数据类型组合,都必须提供一个比较支持函数。该函数在 + 对于 B-树操作符族为其提供比较操作符的每一种数据类型组合,都必须提供一个比较支持函数。该函数在 pg_amproc 中注册,支持函数编号为 1,并且 amproclefttype/amprocrighttype 要等于该比较的左右数据类型(也就是与匹配操作符在 - pg_amop 中注册时相同的数据类型)。比较函数必须接受两个非空值 + pg_amop 中注册时相同的数据类型)。比较函数必须接受两个非 null 值 AB,并返回一个 int32 值,其值为 < 0、 @@ -197,12 +197,12 @@ < BA = BA - > B。不允许返回空值:该数据类型的所有值都必须可比较。示例见 + > B。不允许返回 null:该数据类型的所有值都必须可比较。示例见 src/backend/access/nbtree/nbtcompare.c - 如果参与比较的值属于可排序数据类型,则会通过标准的 + 如果参与比较的值属于支持排序规则的数据类型,则会通过标准的 PG_GET_COLLATION() 机制,把适当的排序规则 OID 传递给比较支持函数。 @@ -223,11 +223,11 @@ in_range - in_range support functions + in_range 支持函数 - support functions + 支持函数 in_range @@ -266,7 +266,7 @@ returns bool - in_range 函数的核心语义取决于这两个 Boolean + in_range 函数的核心语义取决于这两个布尔 标志参数。它应当先对 baseoffset 做加法或减法,再把 val 与结果比较,具体如下: @@ -383,7 +383,7 @@ returns bool - 如果被排序的类型(type1)属于可排序数据类型,则会通过标准的 + 如果被排序的类型(type1)属于支持排序规则的数据类型,则会通过标准的 PG_GET_COLLATION() 机制,把适当的排序规则 OID 传递给 in_range 函数。 @@ -408,12 +408,7 @@ returns bool equalimage(opcintype oid) returns bool - 返回值是关于某个操作符类及其排序规则的静态信息。返回 - true 表示:该操作符类的 - order 函数被保证只有在返回 - 0arguments are equal)时,其 - AB - 参数才是可以互换而不损失任何语义信息的。如果未注册 + 返回值是关于某个操作符类及其排序规则的静态信息。返回 true 表示可以保证:该操作符类的 order 函数只有在其 AB 参数也能够互换而不损失任何语义信息时,才会返回 0参数相等)。如果未注册 equalimage 函数,或其返回 false,就表示不能假定该条件成立。 @@ -421,7 +416,7 @@ equalimage(opcintype oid) returns bool opcintype 参数是该操作符类所索引数据类型的 pg_type.oid。这只是为了方便在不同操作符类之间复用同一个底层 equalimage 函数。如果 - opcintype 是可排序数据类型,则会通过标准的 + opcintype 是支持排序规则的数据类型,则会通过标准的 PG_GET_COLLATION() 机制,把适当的排序规则 OID 传递给 equalimage 函数。 @@ -453,7 +448,7 @@ equalimage(opcintype oid) returns bool 发行版中包含的操作符类遵循的惯例是:注册一个现成的通用 equalimage 函数。大多数操作符类注册 btequalimage(),这表示去重在无条件下都是安全的。像 - text 这样可排序数据类型的操作符类会注册 + text 这样支持排序规则的数据类型的操作符类会注册 btvarstrequalimage(),这表示在确定性排序规则下去重是安全的。第三方扩展的最佳实践则是注册它们自己的自定义函数,以保留控制权。 @@ -489,26 +484,6 @@ options(relopts local_relopts *) returns - - skipsupport - - - 可选地,B-树 操作符族可以提供skip 支持函数,注册为支持函数编号 - 6。这些函数为 B-树 - 代码提供了一种按键空间顺序遍历某个操作符类底层输入类型所能表示的全部可能值的方法。当核心代码应用跳过扫描优化时,就会用到它。相关 - API 定义在 src/include/utils/skipsupport.h - 中。 - - - 没有提供 skip 支持函数的操作符类,仍然可以使用跳过扫描。核心代码仍可采用其后备策略,尽管对于某些离散类型来说,这种策略可能并非最优。对于连续类型上的操作符类,提供 - skip 支持函数通常没有意义(甚至可能不可行)。 - - - 操作符族注册跨类型的 skipsupport - 函数并不合理,尝试这样做会导致错误。因为要确定下一个可被索引的值,必须通过递增一个从索引元组复制出来的值来完成。所生成的值都必须属于同一种底层数据类型(也就是被跳过的索引列的 opclass 输入类型)。 - - - @@ -547,7 +522,7 @@ options(relopts local_relopts *) returns B-树索引会通过执行自底向上索引删除轮次,增量地删除这类版本频繁更替产生的索引元组。每一轮删除都是因预期中的版本频繁更替页拆分而触发的。这只会发生在那些没有被 - UPDATE 语句逻辑修改的索引上,否则过时版本就会集中积累在某些特定页面中。通常可以避免页拆分,不过也可能出现某些实现层面的启发式规则甚至一个垃圾索引元组都识别不出来、删不掉的情况(这时就要靠页拆分或一次去重轮次来解决新元组放不进叶页的问题)。任何一次索引扫描在单个逻辑行上必须穿越的最坏版本数,是影响整个系统响应能力和吞吐量的重要因素。一次自底向上索引删除轮次会基于涉及逻辑行与版本的定性区别,针对单个叶页中疑似垃圾的元组。这与自动清理工作进程执行的自顶向下索引清理不同,后者是在超出某些定量的表级阈值时触发的(见)。 + UPDATE 语句逻辑修改的索引上;如果不执行这类删除,过时版本就会集中积累在某些特定页面中。通常可以避免页拆分,不过也可能出现某些实现层面的启发式规则甚至一个垃圾索引元组都识别不出来、删不掉的情况(这时就要靠页拆分或一次去重轮次来解决新元组放不进叶页的问题)。任何一次索引扫描在单个逻辑行上必须穿越的最坏版本数,是影响整个系统响应能力和吞吐量的重要因素。一次自底向上索引删除轮次会基于涉及逻辑行与版本的定性区别,针对单个叶页中疑似垃圾的元组。这与自动清理工作进程执行的自顶向下索引清理不同,后者是在超出某些定量的表级阈值时触发的(见)。 @@ -587,7 +562,7 @@ options(relopts local_relopts *) returns 去重通过周期性地把一组组重复元组合并起来,为每一组形成一个 - posting list 元组。在这种表示中,列键值只出现一次,后面跟着一个排好序的 + 倒排列表 元组。在这种表示中,列键值只出现一次,后面跟着一个排好序的 TID 数组,指向表中的各行。这能显著减小那些每个值(或每一种不同列值组合)平均会出现多次的索引的存储大小。查询延迟可能显著降低,整体查询吞吐量也可能显著提升,例行索引清理的开销同样可能显著减少。 @@ -601,14 +576,14 @@ options(relopts local_relopts *) returns 去重过程是惰性发生的:当插入一个放不进现有叶页的新项时,只有在索引元组删除也无法为该新项释放足够空间的情况下,才会进行去重(通常只会短暂考虑删除,然后就跳过)。与 - GIN 的 posting list 元组不同,B-树的 posting list - 元组不需要在每次插入新的重复项时都扩展;它们只是叶页原始逻辑内容的一种替代物理表示。这种设计优先考虑混合读写工作负载下的一致性能。大多数客户端应用至少都能从去重中获得适度的性能收益。去重默认启用。 + GIN 的倒排列表元组不同,B-树的倒排列表 + 元组不需要在每次插入新的重复项时都扩展;它们只是叶页原始逻辑内容的一种替代物理表示。这种设计优先考虑混合读写工作负载下的稳定性能。大多数客户端应用至少都能从去重中获得适度的性能收益。去重默认启用。 CREATE INDEXREINDEX - 都会应用去重来创建 posting list - 元组,只是两者采用的策略略有不同。对于从表中取出的已排序输入中遇到的每一组普通重复元组,都会在被加入当前待写入叶页之前先合并成一个 - posting list 元组。每个 posting list 元组都会尽量容纳更多的 + 都会应用去重来创建倒排列表 + 元组,不过它们采用的策略与上述过程略有不同。对于从表中取出的已排序输入中遇到的每一组普通重复元组,都会在被加入当前待写入叶页之前先合并成一个 + 倒排列表元组。每个倒排列表元组都会尽量容纳更多的 TID。叶页按通常方式写出,不需要额外独立的去重过程。由于 CREATE INDEXREINDEX 都是一次性的批处理操作,这种策略非常适合它们。 @@ -617,14 +592,14 @@ options(relopts local_relopts *) returns 如果某个写密集型工作负载由于索引中的重复值很少甚至没有,而无法从去重中获益,那么它会承担很小且固定的性能损耗(除非显式禁用去重)。 deduplicate_items 存储参数可用于在单个索引内禁用去重。而只读工作负载绝不会因此遭受性能损失,因为读取 - posting list 元组至少与读取标准元组表示一样高效。禁用去重通常并没有帮助。 + 倒排列表元组至少与读取标准元组表示一样高效。禁用去重通常并没有帮助。 有时唯一索引(以及唯一约束)也可以使用去重。这允许叶页临时吸收因版本频繁更替产生的额外重复项。唯一索引中的去重能够增强自底向上索引删除,特别是在长事务持有阻塞垃圾回收的快照时。其目标是为自底向上索引删除策略再次发挥作用争取时间。把页拆分推迟到某个单独的长事务自然结束之后,可能使一次自底向上删除轮次在较早一次失败的地方获得成功。 - 系统会应用一种特殊的启发式规则,来判定唯一索引中是否应当执行一次去重轮次。它往往可以直接跳到拆分叶页,从而避免把周期浪费在无益的去重过程中而造成性能损耗。如果你担心去重的开销,可以考虑有选择地设置 + 系统会应用一种特殊的启发式规则,来判定唯一索引中是否应当执行一次去重轮次。它往往可以直接跳到拆分叶页,从而避免把处理器周期浪费在无益的去重过程中而造成性能损耗。如果你担心去重的开销,可以考虑有选择地设置 deduplicate_items = off。在唯一索引中保持去重启用,坏处很小。 @@ -648,7 +623,7 @@ options(relopts local_relopts *) returns numeric 不能使用去重。必须保留相等的 datum - 之间的小数位数。 + 之间的显示小数位数。 diff --git a/zh/14/catalogs.sgml b/zh/14/catalogs.sgml index 976311c2..5e74b5ee 100644 --- a/zh/14/catalogs.sgml +++ b/zh/14/catalogs.sgml @@ -668,7 +668,7 @@ t = 表(包括物化视图), - i = 索引. + i = 索引。 @@ -921,7 +921,7 @@
- amproclefttypeamprocrighttype列的通常解释是它们标识了一个特定支持过程所支持的操作符的左右输入类型。对于某些访问方法它们和支持过程本身的输入数据类型相匹配,而对其他的则不会匹配。对于一个索引有一个默认支持过程的概念,这些支持过程的amproclefttypeamprocrighttype都等于索引操作符类的opcintype。 + amproclefttypeamprocrighttype列的通常解释是它们标识了一个特定支持函数所支持的操作符的左右输入类型。对于某些访问方法它们和支持函数本身的输入数据类型相匹配,而对其他的则不会匹配。对于一个索引有一个默认支持函数的概念,这些支持函数的amproclefttypeamprocrighttype都等于索引操作符类的opcintype
@@ -1058,6 +1058,20 @@ + + + attstattarget int4 + + + attstattarget 控制 + ANALYZE 为该列收集统计信息时的细节级别。 + 零值表示不应收集统计信息。 + 负值表示使用系统默认统计目标。 + 正值的确切含义依赖于数据类型。 + 对于标量数据类型,attstattarget 既是要收集的高频值目标个数,也是要创建的直方图桶目标个数。 + + + attlen int2 @@ -1078,21 +1092,30 @@ - atttypmod int4 + attndims int4 - atttypmod记录了在表创建时提供的类型相关数据(例如一个varchar列的最大长度)。 - 它会被传递给类型相关的输入函数和长度强制函数。对于那些不需要atttypmod的类型,这个值通常总是为-1。 + 如果该列是数组类型,则为维数;否则为 0。 + (目前并不会强制检查数组维数,因此任何非零值实际上都只意味着这是一个数组。) - attndims int2 + attcacheoff int4 - 如果该列是数组类型,则为维数;否则为 0。 - (目前并不会强制检查数组维数,因此任何非零值实际上都只意味着这是一个数组。) + 在存储中始终为 -1,但装入内存中的行描述符时,可能会更新为该属性在行内偏移量的缓存值 + + + + + + atttypmod int4 + + + atttypmod记录了在表创建时提供的类型相关数据(例如一个varchar列的最大长度)。 + 它会被传递给类型相关的输入函数和长度强制转换函数。对于那些不需要atttypmod的类型,这个值通常为 -1。 @@ -1141,7 +1164,7 @@ attnotnull bool - 此列具有一个非空约束(可能尚未验证) + 这代表一个非空约束 @@ -1160,8 +1183,7 @@ atthasmissing bool - 该列在行中完全缺失时会用到这个列的值,如果在行创建之后增加一个有非易失DEFAULT值的列,就会发生这种情况。 - 实际使用的值被存放在attmissingval列中。 + 此列有一个值,供该列在数据行中完全缺失时使用;在数据行创建之后添加带有非易失 DEFAULT 值的列时,就会出现这种情况。实际使用的值存储在 attmissingval 列中。 @@ -1181,7 +1203,7 @@ 如果是零字节(''),则不是生成列。 - 否则,s = 存储式(stored)。(将来可能会增加其他值。) + 否则,s = 存储式。(将来可能会添加其他值。) @@ -1190,7 +1212,7 @@ attisdropped bool - 该列被删除且不再有效。一个删除的列仍然物理存在于表中,但是会被分析器忽略并因此无法通过SQL访问。 + 该列被删除且不再有效。一个删除的列仍然物理存在于表中,但是会被解析器忽略并因此无法通过SQL访问。 @@ -1205,7 +1227,7 @@ - attinhcount int2 + attinhcount int4 该列直接祖先的数量。祖先数量非零的列不能被删除,也不能被重命名。 @@ -1218,21 +1240,7 @@ (引用 pg_collation.oid - 该列被定义的排序规则,如果该列不是一个可排序数据类型则为0。 - - - - - - attstattarget int2 - - - attstattarget 控制 - ANALYZE 为该列收集统计信息时的细节级别。 - 零值表示不应收集统计信息。 - 空值表示使用系统默认统计目标。 - 正值的确切含义依赖于数据类型。 - 对于标量数据类型,attstattarget 既是要收集的高频值目标个数,也是要创建的直方图桶目标个数。 + 该列定义的排序规则;如果该列的数据类型不支持排序规则,则为零。 @@ -1241,7 +1249,7 @@ attacl aclitem[] - 列级访问权限, 如果此列上已有特别授予的权限 + 列级访问权限,如果此列上已有特别授予的权限 @@ -1269,7 +1277,7 @@ 这个列中是一个含有一个元素的数组,其中的值被用于该列在行中完全缺失时,如果在行创建之后增加一个有非易失DEFAULT值的列,就会发生这种情况。 - 只有当atthasmissing为真时才使用这个值。如果没有值则该列为空。 + 只有当atthasmissing为真时才使用这个值。如果没有值则该列为空值。 @@ -1277,9 +1285,7 @@ - 在一个被删除的列的pg_attribute的项中,atttypid被重置为0,但attlen以及其他从pg_type拷贝的域仍然有效。 - 这种安排用于处理一种情况,即被删除列的数据类型后来被删除,并且因此不再有相应的pg_type行。 - attlen和其他域可以被用来解释表的一行的内容。 + 在被删除列的 pg_attribute 条目中,atttypid 被重置为零,但 attlen 以及其他从 pg_type 复制的字段仍然有效。这种安排用于应对被删除列的数据类型后来也被删除、因而不再有相应 pg_type 行的情况。attlen 和其他字段可用于解释表中一行的内容。 @@ -1408,7 +1414,7 @@ rolconnlimit int4 - 对于可以登录的角色,本列设置该角色可以同时发起最大连接数。-1表示无限制。 + 对于可以登录的角色,本列设置该角色能够建立的最大并发连接数。-1 表示无限制。 @@ -1417,7 +1423,7 @@ rolpassword text - 加密后的密码;如果未设置则为空。其格式取决于所使用的加密方式。 + 加密后的密码;如果未设置则为空值。其格式取决于所使用的加密方式。 @@ -1426,7 +1432,7 @@ rolvaliduntil timestamptz - 密码过期时间(只用于密码鉴定),如果永不过期则为空 + 密码过期时间(仅用于密码认证);不设过期时间时为空值 @@ -1434,7 +1440,7 @@ - 对于一个MD5加密的密码,rolpassword列将由字符串md5后面跟上一个32字符的十六进制MD5哈希值构成。MD5哈希值将是该用户的密码串接上它们的用户名。例如,如果用户joe的密码是xyzzy,则PostgreSQL将存储xyzzyjoe的md5哈希。 + 对于一个MD5加密的密码,rolpassword列将由字符串md5后面跟上一个32字符的十六进制MD5哈希值构成。MD5 哈希值通过在用户密码后拼接用户名再计算得到。例如,如果用户joe的密码是xyzzy,则PostgreSQL将存储xyzzyjoe的md5哈希。 @@ -1479,14 +1485,7 @@ SCRAM-SHA-256$<iteration count>:&l - - - oid oid - - - 行标识符 - - + @@ -1527,25 +1526,9 @@ SCRAM-SHA-256$<iteration count>:&l - - - inherit_option bool - - - 如果成员会自动继承被授予角色的权限,则为真 - - - - - set_option bool - - - 如果成员可以 - SET ROLE - 到被授予的角色,则为真 - - + + @@ -1565,7 +1548,7 @@ SCRAM-SHA-256$<iteration count>:&l - 需要注意的是,pg_cast并不表示系统知道如何执行的所有类型转换,它只包括那些不能从某些通用规则推导出的转换。例如,一个域及其基类型之间的转换并未显式地在pg_cast中展示。另一个重要的例外是自动的基于 I/O 的类型转换,它们通过数据类型自己的 I/O 函数来转换成(或者转换自)text或其他字符串类型,这些转换也没有显式地在pg_cast中表示。 + 需要注意的是,pg_cast并不表示系统知道如何执行的所有类型转换,它只包括那些不能从某些通用规则推导出的转换。例如,一个域及其基础类型之间的转换并未显式地在pg_cast中展示。另一个重要的例外是自动的基于 I/O 的类型转换,它们通过数据类型自己的 I/O 函数来转换成(或者转换自)text或其他字符串类型,这些转换也没有显式地在pg_cast中表示。 @@ -1670,7 +1653,7 @@ SCRAM-SHA-256$<iteration count>:&l - 目录pg_class描述了具有列或与表类似的其他对象。这包括索引(但请参见pg_index)、序列(但请参见pg_sequence)、视图、物化视图、复合类型和TOAST表;请参见relkind。 + 目录pg_class描述了表以及其他具有列或在其他方面与表类似的对象。这包括索引(但请参见pg_index)、序列(但请参见pg_sequence)、视图、物化视图、复合类型和TOAST表;请参见relkind。 在下面,当我们指的是所有这些类型的对象时,我们称之为关系(relations)。并非所有pg_class的列对所有关系类型都有意义。 @@ -1722,9 +1705,7 @@ SCRAM-SHA-256$<iteration count>:&l reltype oid (引用 pg_type.oid) - - 该关系可能对应的表行类型的数据类型 OID;对索引为 0,而序列和 TOAST 表没有pg_type项 - + 与此表的行类型对应的数据类型的 OID(如有);索引、序列和 TOAST 表没有pg_type项,此值为零 @@ -1752,9 +1733,7 @@ SCRAM-SHA-256$<iteration count>:&l relam oid (引用 pg_am.oid) - - 用于访问该表或索引的访问方法。如果该关系是序列或者没有磁盘文件,则此字段无意义;分区表除外,对于分区表,如果设置了该字段,则在创建命令未指定时,它优先于 default_table_access_method 来决定用于创建分区的访问方法。 - + 如果这是表或索引,则为使用的访问方法(堆、B-树、hash 等);否则为零(序列以及没有存储的关系,如视图,此值为零) @@ -1810,20 +1789,7 @@ SCRAM-SHA-256$<iteration count>:&l - - - relallfrozen int4 - - - 表的可见性映射中被标记为全冻结的页数。这只是一个用于触发自动清理的估计值。 - 它也可以与 relallvisible 一起,用于安排手工清理以及调优清理冻结行为。 - 它会被 - VACUUM、 - ANALYZE - 以及一些 DDL 命令(例如 CREATE INDEX)更新。 - - + @@ -1859,7 +1825,7 @@ SCRAM-SHA-256$<iteration count>:&l relpersistence char - p = 永久表, u = 不记录 WAL 的表, + p = 永久表,u = 不记录 WAL 的表, t = 临时表 @@ -1954,7 +1920,7 @@ SCRAM-SHA-256$<iteration count>:&l relispopulated bool - 如果表已被填充则为真(对于所有关系该列都为真,但对于某些物化视图却不是) + 如果关系已被填充则为真(对于所有关系该列都为真,但对于某些物化视图却不是) @@ -1996,7 +1962,7 @@ SCRAM-SHA-256$<iteration count>:&l relfrozenxid xid - 在此之前的所有事务ID在表中已经被替换为一个永久的(冻结的) 事务ID。 + 在此之前的所有事务ID在表中已经被替换为一个永久的(冻结的)事务ID。 这用于跟踪表是否需要被清理,以便阻止事务ID回卷或者允许pg_xact被收缩。 如果该关系不是一个表则为0(InvalidTransactionId)。 @@ -2007,7 +1973,7 @@ SCRAM-SHA-256$<iteration count>:&l relminmxid xid - 在此之前的多事务ID在表中已经被替换为一个事务ID。这被用于跟踪表是否需要被清理,以阻止 + 在此之前的所有多事务ID在表中已经被替换为一个事务ID。这被用于跟踪表是否需要被清理,以阻止 多事务ID回卷或者允许pg_multixact被收缩。如果关系不是一个表则 为0(InvalidMultiXactId)。 @@ -2036,7 +2002,7 @@ SCRAM-SHA-256$<iteration count>:&l relpartbound pg_node_tree - 如果表示一个分区(见relispartition),则为分区边界的内部表示 + 如果表是一个分区(见relispartition),则为分区边界的内部表示 @@ -2044,9 +2010,9 @@ SCRAM-SHA-256$<iteration count>:&l
- pg_class中的一些逻辑标志被以一种懒惰的方式维护:在正确状态时它们被保证为真,但是当条件不再为真时它们并不会被立刻重置为假。 + pg_class中的一些布尔标志采用延迟维护:当条件成立时,保证它们为真;但当条件不再成立时,可能不会立即将它们重置为假。 例如,relhasindexCREATE INDEX设置,但它从不会被DROP INDEX清除。 - 作为替代,VACUUM会在找到无索引表后清除其relhasindex。 + 作为替代,VACUUM会在找到无索引表后清除其relhasindex。 这种安排避免了竞争条件并且提高了并发性。 @@ -2120,9 +2086,10 @@ SCRAM-SHA-256$<iteration count>:&l collprovider char - 排序规则提供者:d = 数据库默认值, - b = builtin,c = libc, - i = icu + 排序规则提供程序:d = 数据库默认值, +c = libc, + i = icu + @@ -2166,7 +2133,7 @@ SCRAM-SHA-256$<iteration count>:&l collversion text - 排序规则的提供者相关的版本。这是在排序规则创建时记录下来的,并且在使用排序规则时会被检查以检测可能导致数据损坏的排序规则定义的改变。 + 提供程序特有的排序规则版本。它会在创建排序规则时记录下来,并在使用时接受检查,以检测可能导致数据损坏的排序规则定义更改。 @@ -2192,8 +2159,9 @@ SCRAM-SHA-256$<iteration count>:&l - 目录pg_constraint存储表上的检查约束、非空约束、主键约束、唯一约束、外键约束和排他约束。 + 目录pg_constraint存储表上的检查约束、主键约束、唯一约束、外键约束和排他约束。 (列约束不会被特殊对待。每一个列约束都等价于某种表约束。) + 非空约束在pg_attribute目录中表示,而不是在这里。 @@ -2254,7 +2222,6 @@ SCRAM-SHA-256$<iteration count>:&l c = 检查约束, f = 外键约束, - n = 非空约束, p = 主键约束, u = 唯一约束, t = 约束触发器, @@ -2280,15 +2247,6 @@ SCRAM-SHA-256$<iteration count>:&l - - - conenforced bool - - - 该约束是否会被强制执行? - - - convalidated bool @@ -2399,7 +2357,7 @@ SCRAM-SHA-256$<iteration count>:&l - coninhcount int2 + coninhcount int4 该约束直接继承自多少个祖先。祖先数量非零的约束不能被删除,也不能被重命名。 @@ -2415,17 +2373,6 @@ SCRAM-SHA-256$<iteration count>:&l - - - conperiod bool - - - 如果该约束被定义为 WITHOUT OVERLAPS - (主键或唯一约束)或 PERIOD - (外键),则为真。 - - - conkey int2[] @@ -2481,10 +2428,7 @@ SCRAM-SHA-256$<iteration count>:&l conexclop oid[] (引用 pg_operator.oid - - 如果是排他约束或 WITHOUT OVERLAPS - 主键/唯一约束,则这里列出每列的排他操作符。 - + 如果是排他约束,则列出每列的排他操作符 @@ -2500,9 +2444,9 @@ SCRAM-SHA-256$<iteration count>:&l - 在一个排他约束的情况中, conkey只对约束元素是单一列引用时有用。 - 对于其他情况,conkey为0且必须查阅相关索引来发现被约束的表达式。 - (对于索引,conkey因此和pg_index.indkey具有相同的内容)。 + 对于排他约束,conkey仅对作为简单列引用的约束元素有用。 + 对于其他情况,conkey中会出现一个 0,必须查阅关联索引来确定被约束的表达式。 + (因此,conkey与该索引的 pg_index.indkey具有相同的内容。) @@ -3856,17 +3800,7 @@ SCRAM-SHA-256$<iteration count>:&l indisunique bool - 如为真, 这是唯一索引 - - - - - - indnullsnotdistinct bool - - - 该值只用于唯一索引。如果为 false,则该唯一索引会将 null 值视为非重复值(因此索引中可以包含多个 null 值,这是 PostgreSQL 的默认行为)。 - 如果为 true,则会将 null 值视为相等(因此索引中只能包含一个 null 值)。 + 如为真, 这是唯一索引 @@ -3974,7 +3908,7 @@ SCRAM-SHA-256$<iteration count>:&l (引用 pg_collation.oid - 对于索引键(indnkeyatts值)中的每一列,这包含要用于该索引的排序规则的OID,如果该列不是一种可排序数据类型则为零。 + 对于索引键(indnkeyatts值)中的每一列,这包含要用于该索引的排序规则的OID,如果该列的数据类型不支持排序规则则为零。 @@ -4981,7 +4915,7 @@ SCRAM-SHA-256$<iteration count>:&l (引用 pg_collation.oid - 对于分区键中的每一个列,这个域包含要用于分区的排序规则的OID,如果该列不是一种可排序数据类型则为零。 + 对于分区键中的每一个列,这个域包含要用于分区的排序规则的OID,如果该列的数据类型不支持排序规则则为零。 @@ -5735,7 +5669,11 @@ SCRAM-SHA-256$<iteration count>:&l - rngsubopc (加上rngcollation,如果元素类型是可排序的)决定了被该范围类型所使用的排序顺序。rngcanonical用于离散类型的元素类型。rngsubdiff是可选的,但是提供它可以提高范围类型上的GiST索引性能。 + rngsubopc(如果元素类型支持排序规则,则还包括 + rngcollation)决定范围类型所用的排序顺序。 + rngcanonical用于元素类型为离散类型的情况。 + rngsubdiff是可选的,但应当提供它, + 以提高范围类型上的 GiST 索引性能。 @@ -6423,8 +6361,8 @@ SCRAM-SHA-256$<iteration count>:&l 通常,每个已分析的表列都有一个条目,其中stainherit = false。 - 如果表具有继承子项或分区,则还会创建第二个条目,其中stainherit = true。 - 此行表示继承树上列的统计信息,即您可以通过SELECT column FROM table*看到的数据的统计信息, + 如果表具有继承子表,则还会创建第二个条目,其中stainherit = true。 + 此行表示继承树上列的统计信息,即你可以通过SELECT column FROM table*看到的数据的统计信息, 而stainherit = false行表示SELECT column FROM ONLY table的结果。 @@ -6433,7 +6371,7 @@ SCRAM-SHA-256$<iteration count>:&l - 因为不同类型的统计信息适用于不同类型的数据, pg_statistic 被设计成不太在意自己存储的是什么类型的统计。 只有极为常用的统计信息(比如NULL的含量)才在pg_statistic里给予专用的字段。 其它所有东西都存储在槽位中,而槽位是一组相关的列, 它们的内容用槽位中的一个列里的代码表示。 更详细的信息请参阅 src/include/catalog/pg_statistic.h。 + 由于不同种类的数据可能适合不同种类的统计信息,pg_statistic 在设计上尽量不对所存储的统计信息种类作出假定。只有极为通用的统计信息(例如空值情况)才在 pg_statistic 中有专用的列。其余统计信息都存储在槽位中。每个槽位都是一组相关的列,其内容由其中一列的代码编号来标识。更多信息见 src/include/catalog/pg_statistic.h @@ -6489,7 +6427,7 @@ SCRAM-SHA-256$<iteration count>:&l stanullfrac float4 - 列的项为空的比例 + 列中空值所占的比例 @@ -6507,8 +6445,8 @@ SCRAM-SHA-256$<iteration count>:&l stadistinct float4 - 列中非空唯一值的数目。一个大于零的值是唯一值的真正数目。 - 一个小于零的值是表中行数的乘数的负值;例如,对于一个 80% 的值为非空且每个非空值平均出现两次的列,可以表示为stadistinct = -0.4。一个0值表示唯一值的数目未知。 + 列中不同非空数据值的数量。一个大于零的值是不同值的真正数目。 + 一个小于零的值是表中行数的乘数的负值;例如,对于一个约 80% 的值为非空且每个非空值平均出现两次的列,可以表示为stadistinct = -0.4。一个0值表示不同值的数目未知。 @@ -6539,8 +6477,8 @@ SCRAM-SHA-256$<iteration count>:&l (引用 pg_collation.oid - 用于导出存储在第N槽位中的统计信息的排序规则。 - 例如,可应用排序规则列的直方图槽会显示定义数据排序顺序的排序规则。对于不可应用排序规则的数据,则为零。 + 用于生成存储在第N槽位中的统计信息的排序规则。 + 例如,支持排序规则的列的直方图槽会显示定义数据排序顺序的排序规则。对于不支持排序规则的数据,则为零。 @@ -6549,7 +6487,7 @@ SCRAM-SHA-256$<iteration count>:&l stanumbersN float4[] - 第N槽位的类型的数值类型统计, 如果该槽位不涉及数值类型则为NULL + 第N槽位中相应种类的数值统计信息;如果该槽位种类不涉及数值,则为 NULL @@ -6559,7 +6497,7 @@ SCRAM-SHA-256$<iteration count>:&l N槽位的类型的列值,如果该槽位类型不存储任何数据值则为 NULL。 - 每个数组的元素值实际上都是指定列的数据类型或者是一个相关类型(如数组元素类型), 因此,除了把这些列的类型定义成anyarray之外别无他法。 + 每个数组的元素值实际上都是指定列的数据类型或者是一个相关类型(如数组元素类型), 因此,无法把这些列的类型定义得比anyarray更具体。 @@ -6645,24 +6583,24 @@ SCRAM-SHA-256$<iteration count>:&l - stxkeys int2vector - (引用 pg_attribute.attnum) + stxstattarget int4 - 一个属性编号的数组,表示哪些表列被这个统计信息对象覆盖。例如值1 3表示第一个和第三个表列被覆盖 + stxstattarget 控制 + ANALYZE 为该统计信息对象收集统计信息时的细节级别。 + 零值表示不应收集统计信息。 + 负值表示使用被引用列的统计目标中的最大值(如果有设置),否则使用系统默认统计目标。 + 正值 stxstattarget 决定要收集的高频值目标个数。 - stxstattarget int2 + stxkeys int2vector + (引用 pg_attribute.attnum - stxstattarget 控制 - ANALYZE 为该统计信息对象收集统计信息时的细节级别。 - 零值表示不应收集统计信息。 - 空值表示使用被引用列的统计目标中的最大值(如果有设置),否则使用系统默认统计目标。 - 正值 stxstattarget 决定要收集的高频值目标个数。 + 一个属性编号的数组,表示哪些表列被这个统计信息对象覆盖。例如值1 3表示第一个和第三个表列被覆盖 @@ -6686,7 +6624,7 @@ SCRAM-SHA-256$<iteration count>:&l 统计信息对象属性中那些不是简单列引用的表达式树,以 nodeToString() 表示。 这是一个列表,每个表达式占一个元素。 - 如果所有统计信息对象属性都是简单引用,则为空。 + 如果所有统计信息对象属性都是简单引用,则为空值。 @@ -6695,8 +6633,8 @@ SCRAM-SHA-256$<iteration count>:&l - pg_statistic_ext条目在CREATE STATISTICS期间完全填充,但是随后不计算实际的统计值。 - 后来ANALYZE命令计算所需的值,并在pg_statistic_ext_data目录中填充条目。 + pg_statistic_ext条目在CREATE STATISTICS期间完全填充,但此时不会计算实际的统计值。 + 后续的ANALYZE命令计算所需的值,并在pg_statistic_ext_data目录中填充条目。 @@ -6710,17 +6648,6 @@ SCRAM-SHA-256$<iteration count>:&l 目录pg_statistic_ext_data保存在pg_statistic_ext中定义的扩展规划器统计信息的数据。 该目录的每一行对应用CREATE STATISTICS创建的一个统计信息对象。 - - - - 通常,每个已分析的统计对象都有一个条目,其中stxdinherit = - false。如果表具有继承子项或分区,还会创建第二个条目,其中 - stxdinherit = true。此行表示继承树上的统计对象,即, - 您将看到的数据的统计信息 - SELECT * FROM table*, - 而stxdinherit = false行 - 表示 - SELECT * FROM ONLY table的结果。 @@ -6758,15 +6685,6 @@ SCRAM-SHA-256$<iteration count>:&l - - - stxdinherit bool - - - 如果为真,则统计信息包括子表中的值,而不仅仅是指定关系中的值 - - - stxdndistinct pg_ndistinct @@ -6790,7 +6708,7 @@ SCRAM-SHA-256$<iteration count>:&l stxdmcv pg_mcv_list - MCV(最频值)列表统计信息,序列化为pg_mcv_list类型 + MCV(高频值)列表统计信息,序列化为pg_mcv_list类型 @@ -6944,17 +6862,6 @@ SCRAM-SHA-256$<iteration count>:&l - - - suborigin text - - - 来源值必须是 none 或 - any 之一。默认值是 any。 - 如果为 none,订阅会请求发布者只发送没有来源的更改。 - 如果为 any,发布者会发送更改,而不管其来源如何。 - - @@ -7341,7 +7248,7 @@ SCRAM-SHA-256$<iteration count>:&l tgdeferrable bool - 如果约束触发器可推迟则为真 + 如果约束触发器可延迟则为真 @@ -7350,7 +7257,7 @@ SCRAM-SHA-256$<iteration count>:&l tginitdeferred bool - 如果约束触发器初始可推迟则为真 + 如果约束触发器初始处于延迟状态则为真 @@ -7886,7 +7793,7 @@ SCRAM-SHA-256$<iteration count>:&l 目录pg_type存储有关数据类型的信息。 - 基类型和枚举类型(标量类型)使用CREATE TYPE创建,而域使用CREATE DOMAIN创建。 + 基础类型和枚举类型(标量类型)使用CREATE TYPE创建,而域使用CREATE DOMAIN创建。 数据库中的每一个表都会有一个自动创建的复合类型,用于表示表的行结构。 也可以使用CREATE TYPE AS创建复合类型。 @@ -7972,7 +7879,7 @@ SCRAM-SHA-256$<iteration count>:&l typtype可以是: - b表示一个基类型, + b表示一个基础类型, c表示一个复合类型(例如一个表的行类型), d表示一个域, e表示一个枚举类型, @@ -8178,7 +8085,7 @@ SCRAM-SHA-256$<iteration count>:&l - e (外部的): 值可以存储在一个次要 TOAST 关系中 (如果有一个关系, 参见pg_class.reltoastrelid). + e (外部的): 值可以存储在一个次要 TOAST 关系中 (如果有一个关系, 参见pg_class.reltoastrelid). @@ -8221,7 +8128,7 @@ SCRAM-SHA-256$<iteration count>:&l typtypmod int4 - 域使用typtypmod来记录被应用于它们基类型的typmod(如果基类型不使用typmod,则为-1)。如果此类型不是一个域则为-1。 + 域使用typtypmod来记录被应用于它们基础类型的typmod(如果基础类型不使用typmod,则为-1)。如果此类型不是一个域则为-1。 @@ -8241,8 +8148,8 @@ SCRAM-SHA-256$<iteration count>:&l typcollation指定此类型的排序规则。如果类型不支持排序规则,此列为零。 - 支持排序规则的基类型在这里会有一个非零值,典型值为DEFAULT_COLLATION_OID。 - 基于可应用排序规则类型的域,如果为其指定了排序规则 OID,则它的排序规则 OID 可以不同于其基类型。 + 支持排序规则的基础类型在这里会有一个非零值,典型值为DEFAULT_COLLATION_OID。 + 基于支持排序规则的类型的域,如果为其指定了排序规则 OID,则它的排序规则 OID 可以不同于其基础类型的排序规则 OID。 @@ -8359,10 +8266,6 @@ SCRAM-SHA-256$<iteration count>:&l X unknown 类型 - - Z - 内部使用类型 - @@ -8878,10 +8781,10 @@ SCRAM-SHA-256$<iteration count>:&l - type text + parent text - 内存上下文类型 + 此内存上下文的父上下文名称 @@ -8890,18 +8793,7 @@ SCRAM-SHA-256$<iteration count>:&l level int4 - 该上下文在内存上下文层次中的层级,从 1 开始计数。上下文的层级也表示该上下文在 - path 列中的位置。 - - - - - - path int4[] - - - 由瞬态数字标识符组成的数组,用于描述内存上下文层次。第一个元素对应 - TopMemoryContext,后续元素包含中间父上下文,最后一个元素包含当前上下文的标识符。 + 与上下文树中 TopMemoryContext 的距离 @@ -8954,25 +8846,7 @@ SCRAM-SHA-256$<iteration count>:&l - 默认情况下,pg_backend_memory_contexts视图只能被超级用户或具有pg_read_all_stats角色权限的角色读取。 - - - - 由于内存上下文会在查询运行期间创建和销毁,因此存储在 path 列中的标识符,在同一查询中多次调用该视图时可能不稳定。下面的示例展示了该列的一种有效用法,并计算 - CacheMemoryContext 及其全部子上下文所使用的总字节数: - - -WITH memory_contexts AS ( - SELECT * FROM pg_backend_memory_contexts -) -SELECT sum(c1.total_bytes) -FROM memory_contexts c1, memory_contexts c2 -WHERE c2.name = 'CacheMemoryContext' -AND c1.path[c2.level] = c2.path[c2.level]; - - - 这里使用了通用表表达式,以确保对视图进行两次求值时, - path 列中的上下文 ID 能够对应一致。 + 默认情况下,pg_backend_memory_contexts视图只能被超级用户读取。 @@ -9369,30 +9243,12 @@ AND c1.path[c2.level] = c2.path[c2.level]; - - - rule_number int4 - - - 如果该规则有效,则为其编号;否则为 NULL。这表示认证期间在找到匹配项之前,各条规则被考虑的顺序。 - - - - - - file_name text - - - 包含此规则的文件名称 - - - line_number int4 - 该规则在 file_name 中的行号 + 该规则在 pg_hba.conf 中的行号 @@ -9551,7 +9407,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; indexdef text - 索引定义(重构出的 命令) + 索引定义(重建出的 命令) @@ -9585,8 +9441,8 @@ AND c1.path[c2.level] = c2.path[c2.level]; 以及一般的数据库对象(由类OID和对象OID标识, 与pg_descriptionpg_depend中的方式相同)。 - 此外,扩展关系的权限被表示为一个单独的可锁定对象,以及更新 - pg_database.datfrozenxid 的更新权限。 + 此外,扩展关系的权利被表示为单独的可锁定对象,更新 + pg_database.datfrozenxid的权利也是如此。 此外,还可以对具有用户定义含义的数字施加咨询锁。 @@ -9621,8 +9477,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; spectoken, object, userlock, - advisory 或 - applytransaction。 + advisory。 (另请参见。) @@ -9633,7 +9488,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; (参考 pg_database.oid) - 锁目标存在的数据库的OID,如果目标是一个共享对象则为0,如果目标是一个事务ID则为空 + 锁目标存在的数据库的OID,如果目标是一个共享对象则为0,如果目标是一个事务ID则为 NULL @@ -9643,7 +9498,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; (参考 pg_class.oid) - 作为锁目标的关系的OID,如果目标不是一个关系或者只是关系的一部分则此列为空 + 作为锁目标的关系的OID,如果目标既不是关系,也不是关系的一部分则此列为 NULL @@ -9652,7 +9507,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; page int4 - 作为锁目标的页在关系中的页号,如果目标不是一个关系页或元组则此列为空 + 作为锁目标的页在关系中的页号,如果目标不是一个关系页或元组则此列为 NULL @@ -9661,7 +9516,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; tuple int2 - 作为锁目标的元组在页中的元组号,如果目标不是一个元组则此列为空 + 作为锁目标的元组在页中的元组号,如果目标不是一个元组则此列为 NULL @@ -9670,7 +9525,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; virtualxid text - 锁定目标事务的虚拟 ID,如果目标不是虚拟事务 ID,则为空 + 锁定目标事务的虚拟 ID,如果目标不是虚拟事务 ID,则为 NULL @@ -9679,7 +9534,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; transactionid xid - 锁定目标事务的标识,如果目标不是事务 ID,则为空 + 锁定目标事务的标识,如果目标不是事务 ID,则为 NULL @@ -9689,7 +9544,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; (参考 pg_class.oid) - 包含锁目标的系统目录的OID,如果目标不是一个普通数据库对象则此列为空 + 包含锁目标的系统目录的OID,如果目标不是一个普通数据库对象则此列为 NULL @@ -9699,7 +9554,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; (参考任意 OID 列) - 锁目标在它的系统目录中的OID,如果目标不是一个普通数据库对象则为空 + 锁目标在它的系统目录中的OID,如果目标不是一个普通数据库对象则为 NULL @@ -9708,7 +9563,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; objsubid int2 - 锁的目标列号(classidobjid指表本身),如果目标是某种其他普通数据库对象则此列为0,如果目标不是一个普通数据库对象则此列为空 + 锁的目标列号(classidobjid指表本身),如果目标是某种其他普通数据库对象则此列为0,如果目标不是一个普通数据库对象则此列为 NULL @@ -9726,7 +9581,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; pid int4 - 保持这个锁或者正在等待这个锁的服务器进程的PID,如果此锁被一个预备事务所持有则此列为空 + 保持这个锁或者正在等待这个锁的服务器进程的PID,如果此锁被一个预备事务所持有则此列为 NULL @@ -9762,8 +9617,8 @@ AND c1.path[c2.level] = c2.path[c2.level]; waitstart timestamptz - 服务器进程开始等待该锁的时间;如果锁已被授予则为空。 - 注意,在开始等待之后,即使grantedfalse,该值在极短时间内也可能仍为空。 + 服务器进程开始等待该锁的时间;如果锁已被授予则为 NULL。 + 注意,在开始等待之后,即使grantedfalse,该值在极短时间内也可能仍为 NULL。 @@ -9788,27 +9643,16 @@ AND c1.path[c2.level] = c2.path[c2.level]; 如果一个进程正在等待行级锁,它通常会出现在视图中,等待当前持有该行锁的永久事务ID。 - - 推测插入锁由事务 ID 和推测插入令牌组成。推测插入令牌显示在 - objid 列中。 - - 咨询锁可以在由单个 bigint 值或两个整数值组成的键上获取。 - 一个bigint键在classid列中显示其高阶半部分, - 在objid列中显示其低阶半部分,并且objsubid等于1。 + 一个bigint键在classid列中显示其高位半部分, + 在objid列中显示其低位半部分,并且objsubid等于1。 可以使用表达式(classid::bigint << 32) | objid::bigint重新组装原始bigint值。 整数键在classid列中显示第一个键,在objid列中显示第二个键, 并且 objsubid 等于 2。键的实际含义由用户自行决定。咨询锁在每个数据库内都是本地的, 因此 database 列对于咨询锁是有意义的。 - - 应用事务锁用于在并行模式下应用逻辑复制中的事务。远程事务 ID 显示在 - transactionid 列中。objsubid - 显示锁子类型:用于同步一组变更的锁其值为 0;用于等待事务完成以确保提交顺序的锁其值为 1。 - - pg_locks提供了集簇中所有锁的全局视图,不仅包括与当前数据库相关的锁。 虽然它的relation列可以与pg_class.oid 连接来识别被锁定的关系,但这仅对当前数据库中的关系有效(即 database 列为当前数据库的 OID 或零的那些关系)。 @@ -9845,15 +9689,15 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx pg_locks视图显示来自常规锁管理器和谓词锁管理器的数据,这两个是独立的系统; - 此外,常规锁管理器将其锁分为常规锁和fast-path锁。 + 此外,常规锁管理器将其锁分为常规锁和快速路径锁。 不能保证这些数据完全一致。 当查询该视图时, - fast-path 锁的数据(具有fastpath = true) + 快速路径锁的数据(具有fastpath = true) 从每个后端逐个收集,而不会冻结整个锁管理器的状态,因此在收集信息时可能会发生锁的获取或释放。 但请注意,这些锁已知不会与当前放置的任何其他锁发生冲突。 - 在查询所有后端的 fast-path 锁后,剩余的常规锁管理器将作为一个单元被锁定,并且所有剩余锁的一致快照将作为一个原子操作收集。 + 在查询所有后端的快速路径锁后,剩余的常规锁管理器将作为一个单元被锁定,并且所有剩余锁的一致快照将作为一个原子操作收集。 解锁常规锁管理器后,谓词锁管理器类似地被锁定,并且所有谓词锁将作为一个原子操作收集。 - 因此,除了 fast-path 锁外,每个锁管理器将提供一致的结果集,但由于我们不同时锁定两个锁管理器,因此在询问常规锁管理器后和在询问谓词锁管理器前,可能会发生锁的获取或释放。 + 因此,除了快速路径锁外,每个锁管理器将提供一致的结果集,但由于我们不同时锁定两个锁管理器,因此在询问常规锁管理器后和在询问谓词锁管理器前,可能会发生锁的获取或释放。 @@ -9956,7 +9800,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx definition text - 物化视图的定义(一个重构的查询) + 物化视图的定义(一个重建的查询) @@ -10141,16 +9985,6 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - - - result_types regtype[] - - - 该预备语句返回列的类型,以 regtype 数组形式表示。该数组中某个元素对应的 OID 可以通过将 - regtype 值转换为 oid 获得。如果预备语句不提供结果(例如 DML 语句),则该字段为空。 - - - from_sql bool @@ -10284,8 +10118,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx 视图pg_publication_tables提供发布与其所包含表之间映射关系的信息。与底层目录 pg_publication_rel不同,该视图会展开定义为 - FOR ALL TABLES - 和 FOR TABLES IN SCHEMA 的发布, + FOR ALL TABLES 的发布, 因此对于这类发布,每个符合条件的表都会有一行。 @@ -10499,7 +10332,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx active bool - 如果该槽当前正被用于流送则为真 + 如果该槽当前正在使用中则为真 @@ -10508,7 +10341,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx active_pid int4 - 为该槽流送数据的会话的进程 ID。NULL 表示不活动。 + 如果该槽当前正在使用中,则为使用该槽的会话的进程 ID;不活动时为 NULL @@ -10544,7 +10377,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx confirmed_flush_lsn pg_lsn - 逻辑槽消费者已确认接收到数据的地址(LSN)。在此 LSN 之前提交的事务所对应的数据将不再可用。物理槽为 NULL。 + 逻辑槽消费者已确认接收的数据所到达的地址(LSN)。早于此地址的数据将不再可用。物理槽为 NULL @@ -10563,15 +10396,16 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - unreserved 表示该槽已不再保留所需的 WAL 文件,其中一部分将在下一个检查点被移除。这通常发生在 被设置为非负值时。该状态可以返回为 reservedextended。 + unreserved 表示该槽已不再保留所需的 WAL 文件,其中一部分将在下一个检查点被移除。该状态可以返回为 reservedextended - lost 表示该槽已经不可用。 + lost 表示某些必需的 WAL 文件已被移除,该槽已经不可用。 + 后两种状态仅在 为非负值时出现。 @@ -10592,6 +10426,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx 如果该槽启用了预备事务解码则为真。物理槽始终为假。 + @@ -10606,7 +10441,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx 视图pg_roles提供数据库角色的信息。它本质上是 - pg_authid 的公开可读视图,并将密码字段清空。 + pg_authid 的公开可读视图,并隐藏密码字段。 @@ -10692,7 +10527,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx rolconnlimitint4 - 对于可以登录的角色,本列设置该角色可以同时发起最大连接数。-1表示无限制。 + 对于可以登录的角色,本列设置该角色能够建立的最大并发连接数。-1 表示无限制。 @@ -10710,7 +10545,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx rolvaliduntiltimestamptz - 密码过期时间(只用于密码认证),如果永不过期则为空 + 密码过期时间(仅用于密码认证);不设过期时间时为空值 @@ -10808,7 +10643,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx definitiontext - 规则定义(创建命令的重构) + 规则定义(重建的创建命令) @@ -11403,7 +11238,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx 这个名称源于该表不应向公众开放读取,因为它包含密码。 pg_user - 是 pg_shadow 的公开可读视图,并将密码字段清空。 + 是 pg_shadow 的公开可读视图,并隐藏密码字段。
@@ -11756,38 +11591,6 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - - - range_length_histogram anyarray - - - 范围类型列中非空且非 NULL 的范围值长度直方图。(对非范围类型为空。) - - - 该直方图使用范围函数 subtype_diff 计算,而不考虑范围边界是否包含端点。 - - - - - - range_empty_frac float4 - - - 列项中值为空范围的比例。(对非范围类型为空。) - - - - - - range_bounds_histogram anyarray - - - 非空且非 NULL 的范围值下界和上界的直方图。(对非范围类型为空。) - - - 这两个直方图表示为单个数组列,其中下半部分表示下界的直方图,上半部分表示上界的直方图。 - -
@@ -11916,16 +11719,6 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - - - inherited bool - (参考 pg_statistic_ext_data.stxdinherit) - - - 如果为真,则统计信息包括子表中的值,而不仅仅是指定关系中的值 - - - n_distinct pg_ndistinct @@ -12088,16 +11881,6 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - - - inherited bool - (参考 pg_statistic_ext_data.stxdinherit) - - - 如果为真,则统计信息包括子表中的值,而不仅仅是指定关系中的值 - - - null_frac float4 @@ -12460,7 +12243,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx 视图pg_user提供数据库用户的信息。它本质上是 - pg_shadow 的公开可读视图,并将密码字段清空。 + pg_shadow 的公开可读视图,并隐藏密码字段。 @@ -12738,7 +12521,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx definitiontext - 视图定义(一个重构的查询) + 视图定义(一个重建的查询) diff --git a/zh/14/charset.sgml b/zh/14/charset.sgml index c5254a40..7b8c122a 100644 --- a/zh/14/charset.sgml +++ b/zh/14/charset.sgml @@ -29,7 +29,7 @@ 区域设置支持 - locale + 区域设置 区域设置支持是指应用程序在字母表、排序、数字格式等 @@ -197,7 +197,7 @@ initdb --locale=sv_SE 以及 POSIX 风格正则表达式);区域设置既会影响大小写不敏感匹配,也会 影响字符类正则表达式中的字符分类 LIKE与区域设置 - regular expressions与区域设置 + 正则表达式与区域设置 @@ -232,284 +232,11 @@ initdb --locale=sv_SE - - 选择区域设置 - - 区域设置可以根据需要在不同范围内进行选择。上面的概述展示了如何使用 - initdb为整个集簇设置默认值。下面的列表给出了可以选 - 择区域设置的位置。每一项都会为后续项提供默认值,而越靠后的项允许以更细 - 粒度覆盖这些默认值。 - - - - - - 如上所述,操作系统环境会为新初始化的数据库集簇提供区域设置默认值。在 - 很多情况下,这已经足够:如果操作系统配置为所需的语言/地区,那么 - PostgreSQL默认也会遵循该区域设置的行为。 - - - - - - 如上所示,initdb的命令行选项可为新初始化的数据库 - 集簇指定区域设置。如果操作系统没有提供数据库系统所需的区域设置配置, - 就应使用这种方式。 - - - - - - 每个数据库都可以单独选择区域设置。SQL 命令CREATE DATABASE - 及其命令行等效程序createdb都提供了相应选项。例 - 如,如果一个数据库集簇中承载了多个租户的数据库,而这些租户有不同的需 - 求,就可以使用这种方式。 - - - - - - 区域设置还可以针对单个表列设置。这使用一个名为排序规则 - 的 SQL 对象,详见。例如,可用它对不同语 - 言的数据进行排序,或自定义某个特定表的排序顺序。 - - - - - - 最后,还可以为单个查询选择区域设置。同样,这也是通过 SQL 排序规则对象 - 实现的。它可以用于根据运行时选择改变排序顺序,或进行临时实验。 - - - - - - - 区域设置提供程序 - - - 区域设置提供程序指定由哪个库来定义排序规则和字符分类的区域设置行为。 - - - - 如上所述,用于选择区域设置的命令和工具都提供了选择区域设置提供程序的选 - 项。下面是一个使用 ICU 提供程序初始化数据库集簇的示例: - -initdb --locale-provider=icu --icu-locale=en - - 有关详细信息,请参阅相应命令和程序的说明。请注意,你可以在不同粒度上混 - 合使用区域设置提供程序,例如集簇默认使用libc,但其 - 中某个数据库使用icu提供程序,而该数据库内部的排序规 - 则对象又可以使用任一提供程序。 - - - - 无论使用哪种区域设置提供程序,操作系统仍会用于提供某些区域设置相关的行 - 为,例如消息(参见)。 - - - - 可用的区域设置提供程序如下: - - - - - builtin - - - builtin提供程序使用内置操作。此提供程序仅支持 - CC.UTF-8和 - PG_UNICODE_FAST区域设置。 - - - C区域设置的行为与 libc 提供程序中的 - C区域设置相同。使用该区域设置时,其行为可能取决于 - 数据库编码。 - - - C.UTF-8区域设置仅在数据库编码为 - UTF-8时可用,并且其行为基于 Unicode。排序规则仅使 - 用代码点值。正则表达式字符类基于“POSIX 兼容”语义,大小写映射使用 - “简单”变体。 - - - PG_UNICODE_FAST区域设置仅在数据库编码为 - UTF-8时可用,并且其行为基于 Unicode。排序规则仅使 - 用代码点值。正则表达式字符类基于“标准”语义,大小写映射使用“完整” - 变体。 - - - - - icu - - - icu提供程序使用外部 - ICUICU库。 - PostgreSQL必须在构建时配置了 ICU 支持。 - - - ICU 提供与操作系统和数据库编码无关的排序与字符分类行为。如果你希望将 - 来迁移到其他平台而不改变结果,这通常更可取。LC_COLLATE - 和LC_CTYPE可以独立于 ICU 区域设置进行设置。 - - - - 对于 ICU 提供程序,结果可能取决于所使用的 ICU 库版本,因为该库会随 - 时间推移更新,以反映自然语言的变化。 - - - - - - libc - - - libc提供程序使用操作系统的 C 库。排序与字符分类行 - 为由LC_COLLATELC_CTYPE设置控 - 制,因此它们不能独立设置。 - - - - 使用 libc 提供程序时,同一个区域设置名称在不同平台上可能表现不同。 - - - - - - - - ICU 区域设置 - - ICU 区域设置名称 - - - ICU 格式的区域设置名称采用语言标签。 - - -CREATE COLLATION mycollation1 (provider = icu, locale = 'ja-JP'); -CREATE COLLATION mycollation2 (provider = icu, locale = 'fr'); - - - - - - 区域设置规范化和验证 - - - 在定义新的 ICU 排序规则对象,或者定义以 ICU 为提供程序的数据库时,给 - 定的区域设置名称如果还不是语言标签形式,就会被转换(“规范化”)成语言 - 标签。例如: - - -CREATE COLLATION mycollation3 (provider = icu, locale = 'en-US-u-kn-true'); -NOTICE: using standard form "en-US-u-kn" for locale "en-US-u-kn-true" -CREATE COLLATION mycollation4 (provider = icu, locale = 'de_DE.utf8'); -NOTICE: using standard form "de-DE" for locale "de_DE.utf8" - - - 如果看到这类通知,请确认providerlocale - 是否符合预期。为了在使用 ICU 提供程序时获得一致结果,应直接指定规范化 - 的语言标签,而不要依赖这种转换。 - - - - 没有语言名称的区域设置,或特殊语言名root,会被转换 - 成语言und(“未定义”)。 - - - - ICU 可以将大多数 libc 区域设置名称以及一些其他格式转换为语言标签,这有 - 助于更容易地迁移到 ICU。如果在 ICU 中使用 libc 风格的区域设置名称,其 - 行为可能与 libc 中并不完全一致。 - - - - 如果在解释区域设置名称时出现问题,或者该区域设置名称表示 ICU 无法识别 - 的语言或地区,你会看到如下警告: - - -CREATE COLLATION nonsense (provider = icu, locale = 'nonsense'); -WARNING: ICU locale "nonsense" has unknown language "nonsense" -HINT: To disable ICU locale validation, set parameter icu_validation_level to DISABLED. -CREATE COLLATION - - - 控制消息的报告方式。除非将其设为 - ERROR,否则排序规则仍会被创建,但其行为可能不是用户 - 所期望的。 - - - - - 语言标签 - - - 语言标签在 BCP 47 中定义,是一种用于标识语言、地区以及其他区域设置信息 - 的标准化标识符。 - - - - 基本语言标签就是 - language-region; - 甚至也可以只有language。 - language是语言代码(例如法语为 - fr),region是地区代码 - (例如加拿大为CA)。例如:ja-JP、 - defr-CA。 - - - - 语言标签中还可以包含排序设置,以自定义排序行为。ICU 允许非常广泛的定 - 制,例如对重音、大小写和标点的敏感性(或不敏感性)、文本中数字的处理 - 方式,以及许多其他选项,以满足不同用途。 - - - - 若要在语言标签中包含这些附加排序信息,请附加-u,表 - 示存在附加排序设置,后跟一个或多个 - -key-value - 对。key排序设置的键, - value则是该设置的有效值。对于布尔设置,可以 - 只写-key而省略对应的 - -value,这意味着其值为 - true。 - - - - 例如,语言标签en-US-u-kn-ks-level2表示美国区域的英 - 语区域设置,其中排序设置kntrue, - kslevel2。这些设置意味着该排 - 序规则不区分大小写,并把一串数字视为一个整体数字: - - -CREATE COLLATION mycollation5 (provider = icu, deterministic = false, locale = 'en-US-u-kn-ks-level2'); -SELECT 'aB' = 'Ab' COLLATE mycollation5 as result; - result --------- - t -(1 row) - -SELECT 'N-45' < 'N-123' COLLATE mycollation5 as result; - result --------- - t -(1 row) - - - - - 有关详细信息以及在区域设置中使用带自定义排序信息的语言标签的更多示 - 例,请参见。 - - - 问题 @@ -565,10 +292,10 @@ SELECT 'N-45' < 'N-123' COLLATE mycollation5 as result; 概念 - 从概念上讲,每个可排序数据类型的表达式都有一个排序规则。(内置的可排序 - 数据类型包括textvarcharchar。 - 用户定义的基本类型也可以标记为可排序,当然,建立在可排序数据类型之上的 - 域也是可排序的。) + 从概念上讲,每个支持排序规则的数据类型的表达式都有一个排序规则。 + (内置的支持排序规则的数据类型包括textvarcharchar。 + 用户定义的基础类型也可以标记为支持排序规则,当然,建立在支持排序规则的数据类型之上的 + 域也支持排序规则。) 如果表达式是列引用,则该表达式的排序规则就是该列定义的排序规则。如果表 达式是常量,则其排序规则就是该常量数据类型的默认排序规则。更复杂表达式 的排序规则则按下文所述,从其输入表达式的排序规则推导出来。 @@ -593,7 +320,7 @@ SELECT 'N-45' < 'N-123' COLLATE mycollation5 as result; 对于函数或操作符调用,通过检查参数排序规则推导出的排序规则,会在运行时 - 用于执行指定操作。如果该函数或操作符调用的结果属于可排序数据类型,那么 + 用于执行指定操作。如果该函数或操作符调用的结果属于支持排序规则的数据类型,那么 在解析时它也会被用作该函数或操作符表达式的已定义排序规则,以便在外围表 达式需要知道其排序规则时使用。 @@ -675,7 +402,7 @@ SELECT a || b FROM test1; - 如果函数或操作符返回的是可排序数据类型,那么分配给该函数或操作符组合输 + 如果函数或操作符返回的是支持排序规则的数据类型,那么分配给该函数或操作符组合输 入表达式的排序规则,也被认为适用于其结果。因此,在 SELECT * FROM test1 ORDER BY a || 'foo'; @@ -721,8 +448,7 @@ SELECT * FROM test1 ORDER BY a || b COLLATE "fr_FR"; - 由icu提供的排序规则对象,对应于 ICU 库提供的具名整 - 理器。ICU 不支持将collatectype分开设 + 由icu提供的排序规则对象,对应于 ICU 库提供的具名排序器。ICU 不支持将collatectype分开设 置,因此二者总是相同的。此外,ICU 排序规则与编码无关,因此在一个数据库 中,某个给定名称的 ICU 排序规则始终只有一个。 @@ -730,101 +456,10 @@ SELECT * FROM test1 ORDER BY a || b COLLATE "fr_FR"; 标准排序规则 - - 在所有平台上,都支持以下排序规则: + 所有平台都提供名为 defaultCPOSIX 的排序规则。根据操作系统支持情况,还可能提供其他排序规则。default 排序规则选择创建数据库时指定的 LC_COLLATELC_CTYPE 值。CPOSIX 排序规则都采用传统 C行为,仅将 ASCII 字母 AZ 视为字母,并严格按字符编码的字节值排序。 - - - unicode - - - 此 SQL 标准排序规则使用 Unicode 排序算法和默认 Unicode 排序元素表进 - 行排序。它在所有编码中都可用。 - 使用此排序规则需要 ICU 支持,并且如果 - PostgreSQL使用不同版本的 ICU 构建,其 - 行为可能会发生变化。(此排序规则与 ICU 根区域设置具有相同的行为;参 - 见。) - - - - - - ucs_basic - - - 此 SQL 标准排序规则使用 Unicode 代码点值而不是自然语言顺序进行排 - 序,并且只有 ASCII 字母A到 - Z会被视为字母。其行为高效且在所 - 有版本中都稳定。仅适用于UTF8编码。(此排序规则 - 与UTF8编码下 libc 区域设置规范C - 的行为相同。) - - - - - - pg_unicode_fast - - - 此排序规则按 Unicode 代码点值而不是自然语言顺序进行排序。对于 - lowerinitcap和 - upper函数,它使用 Unicode 完整大小写映射。对 - 于模式匹配(包括正则表达式),它使用 Unicode 兼容属性 - 的标准变体。其行为在 - Postgres主版本内高效且稳定。仅适用于 - UTF8编码。 - - - - - - pg_c_utf8 - - - 此排序规则按 Unicode 代码点值而不是自然语言顺序进行排序。对于 - lowerinitcap和 - upper函数,它使用 Unicode 简单大小写映射。对 - 于模式匹配(包括正则表达式),它使用 Unicode 兼容属性 - 的 POSIX 兼容变体。其行为在 - PostgreSQL主版本内高效且稳定。此排序规 - 则仅适用于UTF8编码。 - - - - - - C(等同于POSIX - - - CPOSIX排序规则基于 - 传统 C行为。它们按字节值而不是自然语言顺序排序,并且 - 只有 ASCII 字母A到 - Z会被视为字母。对于给定的数据库 - 编码,其行为高效且在所有版本中都稳定,但在不同数据库编码之间可能会 - 有所不同。 - - - - - - default - - - default排序规则会选择数据库创建时指定的区域设 - 置。 - - - - - - - - 根据操作系统支持情况,还可能存在其他排序规则。这些附加排序规则的效率和 - 稳定性取决于排序规则提供程序、提供程序版本以及区域设置。 - - + 此外,编码 UTF8 还可以使用 SQL 标准排序规则名 ucs_basic。它等价于 C,按 Unicode 码点排序。 + 预定义排序规则 @@ -946,23 +581,23 @@ SELECT a COLLATE "C" < b COLLATE "POSIX" FROM test1; - 创建新的排序规则对象 + 创建新的排序规则对象 - + 如果标准和预定义排序规则不足以满足需求,用户可以使用 SQL 命令创建自己的排序规则对象。 - + 与所有预定义对象一样,标准和预定义排序规则都位于模式 pg_catalog中。用户定义的排序规则应当创建在用户模式 中。这也能确保它们被pg_dump保存。 - - libc 排序规则 + + libc 排序规则 - + 新的 libc 排序规则可以这样创建: CREATE COLLATION german (provider = libc, locale = 'de_DE'); @@ -971,7 +606,7 @@ CREATE COLLATION german (provider = libc, locale = 'de_DE'); 类 Unix 系统上,命令locale -a会给出一个列表。 - + 由于预定义的 libc 排序规则已经包含了数据库实例初始化时操作系统中定义 的所有排序规则,因此通常不需要手工创建新的排序规则。可能需要这样做的 原因包括希望采用不同的命名系统(这种情况下另见pg_import_system_collations())。 - + - - ICU 排序规则 + + ICU 排序规则 - - ICU 排序规则可以这样创建: - -CREATE COLLATION german (provider = icu, locale = 'de-DE'); - - ICU 区域设置使用 BCP 47 语言标签 - 指定,但也接受大多数 libc 风格的区域设置名称。如果可能,libc 风格的区 - 域设置名称会被转换为语言标签。 - + 除了 initdb 预装载的基本语言与国家组合外,ICU 还允许进一步定制排序规则。建议用户定义自己的排序规则对象,利用这些功能使排序行为满足自己的需求。关于 ICU 区域设置名称的信息,参见 。可接受的名称和属性集合取决于具体的 ICU 版本。 - - 新的 ICU 排序规则可以通过在语言标签中包含排序属性来广泛定制排序行为。 - 详细信息和示例见。 - - + 以下是一些示例: + + CREATE COLLATION "de-u-co-phonebk-x-icu" (provider = icu, locale = 'de-u-co-phonebk'); + CREATE COLLATION "de-u-co-phonebk-x-icu" (provider = icu, locale = 'de@collation=phonebook'); + + 德语排序规则,电话簿排序类型 + 第一个示例使用 BCP 47 定义的语言标签来选择 ICU 区域设置。第二个示例使用传统的 ICU 专有区域设置语法。今后应优先采用第一种形式,但较旧的 ICU 版本不支持它。 + 注意,可以在 SQL 环境中为排序规则对象任意命名。本例遵循预定义排序规则所采用的命名风格,该风格也遵循 BCP 47,但用户定义的排序规则并不要求如此。 + + + + + CREATE COLLATION "und-u-co-emoji-x-icu" (provider = icu, locale = 'und-u-co-emoji'); + CREATE COLLATION "und-u-co-emoji-x-icu" (provider = icu, locale = '@collation=emoji'); + + + 根排序规则,表情符号排序类型,依据 Unicode 技术标准 #51 + + 注意,传统的 ICU 区域设置命名系统使用空字符串来选择根区域设置。 + + + + + CREATE COLLATION latinlast (provider = icu, locale = 'en-u-kr-grek-latn'); + CREATE COLLATION latinlast (provider = icu, locale = 'en@colReorder=grek-latn'); + + + 将希腊字母排在拉丁字母之前。(默认情况下是拉丁字母排在希腊字母之前。) + + + + + + CREATE COLLATION upperfirst (provider = icu, locale = 'en-u-kf-upper'); + CREATE COLLATION upperfirst (provider = icu, locale = 'en@colCaseFirst=upper'); + + + 将大写字母排在小写字母之前。(默认情况下是小写字母在前。) + + + + + + CREATE COLLATION special (provider = icu, locale = 'en-u-kf-upper-kr-grek-latn'); + CREATE COLLATION special (provider = icu, locale = 'en@colCaseFirst=upper;colReorder=grek-latn'); + + + 结合了以上两个选项。 + + + + + + CREATE COLLATION numeric (provider = icu, locale = 'en-u-kn-true'); + CREATE COLLATION numeric (provider = icu, locale = 'en@colNumeric=yes'); + + 数值排序,按数值对数字序列排序,例如:A-21 < A-123(也称自然排序)。 + + + 参见Unicode 技术标准 #35BCP 47了解详情。可用排序类型列表(co子标签)可在以下位置找到:CLDR 仓库。 + + + 注意,虽然此系统允许创建忽略大小写忽略重音等排序规则(使用 ks 键),但要让这些排序规则真正不区分大小写或重音,还必须在 CREATE COLLATION 中将它们声明为非确定性排序规则;参见 。否则,按排序规则比较相等、但字节不相等的字符串,仍会按字节值排序。 + + + ICU 的设计允许接受几乎任何字符串作为区域设置名,并按照其文档描述的回退流程,匹配到它能够提供的最接近区域设置。因此,如果排序规则定义使用了当前 ICU 安装实际不支持的功能,不会得到直接反馈。所以建议创建应用层面的测试用例,以检查排序规则定义是否满足需求。 + + - + 复制排序规则 @@ -1050,7 +740,7 @@ CREATE COLLATION ignore_accents (provider = icu, locale = 'und-u-ks-level1-kc-tr 定性的。虽然非确定性排序规则提供了更正确的行为,尤其是 在考虑 Unicode 的全部能力及其众多特殊情况时,但它们也有一些缺点。首 先,使用它们会带来性能损失。特别要注意的是,B-树不能对使用非确定性排 - 序规则的索引使用去重。此外,某些操作(例如某些模式匹配操作)对非确定性 + 序规则的索引使用去重。此外,某些操作(例如模式匹配操作)对非确定性 排序规则来说是不可行的。因此,只有在确实需要时才应使用它们。 @@ -1065,492 +755,7 @@ CREATE COLLATION ignore_accents (provider = icu, locale = 'und-u-ks-level1-kc-tr - - ICU 自定义排序规则 - - - ICU 允许通过把排序设置作为语言标签的一部分,定义新的排序规则,从而对排 - 序规则行为进行广泛控制。这些设置可以修改排序顺序,以适应各种需求。例如: - - --- ignore differences in accents and case -CREATE COLLATION ignore_accent_case (provider = icu, deterministic = false, locale = 'und-u-ks-level1'); -SELECT 'Å' = 'A' COLLATE ignore_accent_case; -- true -SELECT 'z' = 'Z' COLLATE ignore_accent_case; -- true - --- upper case letters sort before lower case. -CREATE COLLATION upper_first (provider = icu, locale = 'und-u-kf-upper'); -SELECT 'B' < 'b' COLLATE upper_first; -- true - --- treat digits numerically and ignore punctuation -CREATE COLLATION num_ignore_punct (provider = icu, deterministic = false, locale = 'und-u-ka-shifted-kn'); -SELECT 'id-45' < 'id-123' COLLATE num_ignore_punct; -- true -SELECT 'w;x*y-z' = 'wxyz' COLLATE num_ignore_punct; -- true - - - 许多可用选项会在中说明;更详尽的 - 细节则可参见。 - - - - ICU 比较级别 - - - ICU 中两个字符串的比较(排序)由一个多级过程决定,其中各种文本特征被 - 分组为级别。每个级别的处理由排序规则设置控制。级别 - 越高,对文本特征的区分就越细。 - - - - 显示了在给定级别判断相等性时,哪 - 些文本特征差异会被认为是重要的。Unicode 字符U+2063 - 是不可见分隔符,如表中所示,在低于identic的所有比 - 较级别都会被忽略。 - - -
- ICU 排序规则级别 - - - - - - - - - - - - - 级别 - 描述 - 'f' = 'f' - 'ab' = U&'a\2063b' - 'x-y' = 'x_y' - 'g' = 'G' - 'n' = 'ñ' - 'y' = 'z' - - - - - - level1 - 基本字符 - true - true - true - true - true - false - - - level2 - 重音 - true - true - true - true - false - false - - - level3 - 大小写/变体 - true - true - true - false - false - false - - - level4 - 标点符号仅在 - ka-shifted时;见 - true - true - false - false - false - false - - - identic - 全部 - true - false - false - false - false - false - - - -
- - - 在每个级别上,即使关闭了完全规范化,也会执行基本规范化。例如, - 'á'既可能由代码点序列 - U&'\0061\0301'表示,也可能由单个代码点 - U&'\00E1'表示;即使在identic - 级别,这两种表示也会被视为相等。若要把代码点表示上的任何差异都视为不同, - 请使用将deterministic设为true创 - 建的排序规则。 - - - - 排序规则级别示例 - - -CREATE COLLATION level3 (provider = icu, deterministic = false, locale = 'und-u-ka-shifted-ks-level3'); -CREATE COLLATION level4 (provider = icu, deterministic = false, locale = 'und-u-ka-shifted-ks-level4'); -CREATE COLLATION identic (provider = icu, deterministic = false, locale = 'und-u-ka-shifted-ks-identic'); - --- invisible separator ignored at all levels except identic -SELECT 'ab' = U&'a\2063b' COLLATE level4; -- true -SELECT 'ab' = U&'a\2063b' COLLATE identic; -- false - --- punctuation ignored at level3 but not at level 4 -SELECT 'x-y' = 'x_y' COLLATE level3; -- true -SELECT 'x-y' = 'x_y' COLLATE level4; -- false - - - - - - ICU 区域设置的排序规则设置 - - - 显示了可用的排序规则设置,这 - 些设置可以作为语言标签的一部分,用来定制排序规则。 - - - - ICU 排序规则设置 - - - - - - - - - - - 默认 - 描述 - - - - - - co - emoji, phonebk, standard, ... - standard - - 排序规则类型。有关其他选项和详细信息,请参见。 - - - - - ka - noignore, shifted - noignore - - 如果设为shifted,某些字符(例如标点或空格)在比 - 较时会被忽略。要使其生效,键ks必须设为 - level3或更低。可通过设置键kv - 来控制忽略哪些字符类别。 - - - - - kb - true, false - false - - 对 2 级差异进行反向比较。例如,区域设置und-u-kb - 会把'àe'排在'aé'之前。 - - - - - kc - true, false - false - - - 将大小写分离成一个介于重音和其他 3 级特征之间的 - 2.5 级。 - - - 如果其值为trueks设为 - level1,则会忽略重音,但仍考虑大小写。 - - - - - - kf - - upper, lower, - false - - false - - 若设为upper,大写字母排在小写字母之前;若设为 - lower,小写字母排在大写字母之前;若设为 - false,排序顺序则取决于该区域设置的规则。 - - - - - kn - true, false - false - - 如果设为true,字符串中的数字会被视为单个数值, - 而不是一串数字。例如,'id-45'会排在 - 'id-123'之前。 - - - - - kk - true, false - false - - - 启用完全规范化;这可能影响性能。即使其值为 - false,也会执行基本规范化。对那些需要完全规范 - 化的语言来说,其区域设置通常会默认启用这一选项。 - - - 在某些情况下,完全规范化很重要,例如多个重音符应用于同一个字符 - 时。比如,代码点序列U&'\0065\0323\0302'和 - U&'\0065\0302\0323'都表示一个 - e,只不过其抑扬符和下点重音的应用顺序不同。启 - 用完全规范化后,这两个代码点序列会被视为相等;否则则不相等。 - - - - - - kr - - space, punct, - symbol, currency, - digit, script-id - - - - - 可设为一个或多个有效值,或者任何 BCP 47 - script-id,例如latn - (拉丁)或grek希腊)。 - 多个值之间用-分隔。 - - - 它会重新定义字符类别的排序顺序;列表中较早出现的字符类别,会排在 - 列表中较晚类别的前面。例如,值 - digit-currency-space(作为语言标签 - und-u-kr-digit-currency-space的一部分)会让 - 标点符号排在数字和空格之前。 - - - - - - ks - level1, level2, level3, level4, identic - level3 - - 用于确定相等性时的敏感度(或强度),其中 - level1对差异最不敏感,而 - identic对差异最敏感。详见。 - - - - - kv - - space, punct, - symbol, currency - - punct - - 在 3 级比较时会被忽略的字符类别。设为更靠后的值时也会包含更靠前的 - 值;例如symbol也会把punct - 和space包含在要忽略的字符中。要使其生效,键 - ka必须设为shifted,且键 - ks必须设为level3或更低。 - - - - -
- - - 默认值可能依赖于具体区域设置。上表并非意在穷举所有情况。有关其他选项和 - 详细信息,请参见。 - - - - - 对于许多排序规则设置,必须在创建排序规则时把 - 设为false,这些设 - 置才能产生预期效果(参见)。此外,某些设置只有在键 - ka设为shifted时才会生效(参见 - )。 - - -
- - - 排序规则设置示例 - - - - CREATE COLLATION "de-u-co-phonebk-x-icu" (provider = icu, locale = 'de-u-co-phonebk'); - - 德语排序规则,电话簿排序类型 - - - - - CREATE COLLATION "und-u-co-emoji-x-icu" (provider = icu, locale = 'und-u-co-emoji'); - - - 根排序规则,表情符号排序类型,依据 Unicode 技术标准 #51 - - - - - - CREATE COLLATION latinlast (provider = icu, locale = 'en-u-kr-grek-latn'); - - - 将希腊字母排在拉丁字母之前。(默认情况下是拉丁字母排在希腊字母之前。) - - - - - - CREATE COLLATION upperfirst (provider = icu, locale = 'en-u-kf-upper'); - - - 将大写字母排在小写字母之前。(默认情况下是小写字母在前。) - - - - - - CREATE COLLATION special (provider = icu, locale = 'en-u-kf-upper-kr-grek-latn'); - - - 结合了以上两个选项。 - - - - - - - - ICU 定制规则 - - - 如果上面列出的排序规则设置所提供的选项仍然不够用,可以用定制规则改变排 - 序元素的顺序,其语法详见。 - - - - 下面这个小例子基于根区域设置创建了一个带定制规则的排序规则: - - - - 按照这条规则,字母W会排在V之后,但被视 - 为类似重音那样的次要差异。某些语言的区域设置定义中就包含类似这样的规 - 则。(当然,如果某个区域设置定义本身已经包含了所需规则,就无需再次显式 - 指定。) - - - - 下面是一个更复杂的例子。以下语句设置了一个名为ebcdic - 的排序规则,其规则会按照 EBCDIC 编码的顺序对 US-ASCII 字符进行排序。 - - -' < '?' -< '`' < ':' < '#' < '@' < \' < '=' < '"' -<*a-r < '~' <*s-z < '^' < '[' < ']' -< '{' <*A-I < '}' <*J-R < '\' <*S-Z <*0-9 -$$);]]> - -SELECT c -FROM (VALUES ('a'), ('b'), ('A'), ('B'), ('1'), ('2'), ('!'), ('^')) AS x(c) -ORDER BY c COLLATE ebcdic; - c ---- - ! - a - b - ^ - A - B - 1 - 2 - - - - - - ICU 的外部参考 - - - 本节()只是对 ICU 行为和语言标 - 签的简要概述。有关技术细节、其他选项和新的行为,请参阅以下文档: - - - - - - Unicode 技术标准 #35 - - - - - BCP 47 - - - - - CLDR 存储库 - - - - - - - - - - - - - - - diff --git a/zh/14/client-auth.sgml b/zh/14/client-auth.sgml index e853cc7c..14bffa53 100644 --- a/zh/14/client-auth.sgml +++ b/zh/14/client-auth.sgml @@ -43,7 +43,7 @@ 客户端认证由一个配置文件控制,该文件按惯例命名为 pg_hba.conf,并存放在数据库集簇的数据目录中。 (HBA 代表 host-based authentication,即基于主机的认证。) - 当数据目录由 初始化时,会安装一个默认的 + 当数据目录由 initdb 初始化时,会安装一个默认的 pg_hba.conf 文件。不过,也可以把认证配置文件放在别处; 请参见配置参数
@@ -62,14 +62,7 @@ 每条认证记录都指定一种连接类型、一个客户端 IP 地址范围(如果该连接类型需要)、一个数据库名、一个用户名,以及对匹配这些参数的连接要使用的认证方法。第一条同时匹配连接类型、客户端地址、请求数据库和用户名的记录会被用来执行认证。这里不存在 继续向后匹配后备 机制:如果选中某条记录而认证失败,就不会再考虑后续记录。如果没有任何记录匹配,则拒绝访问。 - - 一条记录可以是 include 指令,也可以是认证记录。include 指令用于指定可被包含的文件,这些文件中可以含有额外记录;这些记录会插入到 include 指令所在的位置。include 指令只有两个字段:includeinclude_if_existsinclude_dir 指令本身,以及要包含的文件或目录。文件或目录既可以是相对路径,也可以是绝对路径,并且都可以用双引号括起。对于 include_dir 形式,将包含所有文件名不以 . 开头且以 .conf 结尾的文件。include 目录中的多个文件会按照文件名顺序处理(依据 C locale 规则,即数字排在字母前,大写字母排在小写字母前)。 - - - - 一条记录可以有多种格式: - - + 记录可以采用以下几种格式: local database user auth-method auth-options host database user address auth-method auth-options hostssl database user address auth-method auth-options @@ -81,14 +74,7 @@ hostssl database userdatabase user IP-address IP-mask auth-method auth-options hostgssenc database user IP-address IP-mask auth-method auth-options hostnogssenc database user IP-address IP-mask auth-method auth-options -include file -include_if_exists file -include_dir directory - - - 字段的含义如下: - - +各字段的含义如下: local @@ -181,50 +167,14 @@ include_dir directory database - - - 指定此记录匹配的数据库名称。值all指定匹配所有数据库。 - 值sameuser指定如果请求的数据库与请求的用户具有相同的名称,则记录匹配。 - 值samerole指定请求的用户必须是与请求的数据库具有相同名称的角色的成员。 - (samegroupsamerole的一种过时但仍被接受的写法。) - 对于 samerole 而言,超级用户并不会仅因其超级用户身份就被视为某个角色的成员;只有当其显式地直接或间接属于该角色时,才会被视为成员。 - 值replication表示当请求的是物理复制连接时匹配,但不匹配逻辑复制连接。请注意,物理复制连接不指定任何特定数据库,而逻辑复制连接会指定数据库。 - 否则,这里可以是某个特定PostgreSQL数据库的名称,或者一个正则表达式。 - 多个数据库名和/或正则表达式可以用逗号分隔提供。 - - - - 如果数据库名以斜线(/)开头,则其余部分会被视为一个正则表达式。 - (关于 PostgreSQL 正则表达式语法的细节,见 。) - - - - 也可以通过在文件名前加上@来指定一个单独文件,该文件中包含数据库名和/或正则表达式。 - + 指定此记录匹配的数据库名称。all 表示匹配所有数据库。sameuser 表示请求的数据库与请求的用户同名时才匹配。samerole 要求请求的用户是与所请求数据库同名的角色的成员。(samegroupsamerole 已过时但仍被接受的写法。)对于 samerole,只有显式地直接或间接属于该角色,超级用户才被视为其成员,仅凭超级用户身份并不算。replication 表示请求物理复制连接时匹配此记录,但不匹配逻辑复制连接。注意,物理复制连接不指定任何特定数据库,而逻辑复制连接会指定数据库。其他值则表示某个特定的 PostgreSQL 数据库的名称。可以用逗号分隔多个数据库名称。也可以在文件名前加 @,指定一个单独存放数据库名称的文件。 user - - - 指定此记录匹配哪些数据库用户名。值all表示匹配所有用户。 - 否则,这里可以是某个特定数据库用户的名称、一个正则表达式(以斜线(/)开头时),或者一个以前缀 + 标识的组名。 - (请记住,在PostgreSQL中,用户和组之间并没有真正区别; - + 标记实际上表示匹配直接或间接属于该角色的任意角色,而没有 + 标记的名称只匹配该特定角色。) - 为此目的,只有在超级用户显式地直接或间接属于该角色时,才会被视为该角色的成员,而不会仅因其超级用户身份而被视为成员。 - 多个用户名和/或正则表达式可以用逗号分隔提供。 - - - - 如果用户名以斜线(/)开头,则其余部分会被视为一个正则表达式。 - (关于 PostgreSQL 正则表达式语法的细节,见 。) - - - - 也可以通过在文件名前加上@来指定一个单独文件,该文件中包含用户名和/或正则表达式。 - + 指定此记录匹配的数据库用户名。all 表示匹配所有用户。其他值可以是某个特定数据库用户的名称,也可以是前面带 + 的组名。(请记住,在 PostgreSQL 中,用户和组并无实质区别;+ 实际表示匹配直接或间接属于此角色的任何角色,而不带 + 的名称仅匹配该角色本身。)为此,只有显式地直接或间接属于该角色,超级用户才被视为其成员,仅凭超级用户身份并不算。可以用逗号分隔多个用户名。也可以在文件名前加 @,指定一个单独存放用户名的文件。 @@ -239,7 +189,7 @@ include_dir directory IP地址范围使用标准的数字表示法来指定起始地址,然后是斜杠(/)和一个CIDR掩码长度。 掩码长度表示客户端IP地址必须匹配的高位比特数。给定IP地址中右侧的比特应为零。 - IP地址、/和CIDR掩码长度之间不得有任何空格。 + IP地址、/和CIDR掩码长度之间不得有任何空白。 @@ -276,12 +226,12 @@ include_dir directory 以点(.)开头的主机名规范匹配实际主机名的后缀。 因此,.example.com将匹配foo.example.com - (但不仅仅是example.com)。 + (但不匹配单独的example.com)。 当在pg_hba.conf中指定主机名时,应确保名称解析相对快速。 - 最好设置一个本地名称解析缓存,如nscd。 + 设置一个本地名称解析缓存可能会有帮助,如nscd。 此外,还可能希望启用配置参数log_hostname,以便在日志中看到客户端的主机名而不是 IP 地址。 @@ -293,7 +243,7 @@ include_dir directory 用户有时会想知道为什么主机名以这种看似复杂的方式处理,包括两次名称解析,其中包括对客户端IP地址的反向查找。 - 如果客户端的反向DNS条目未设置或生成了一些不良的主机名,则使用该功能会变得复杂。 + 如果客户端的反向DNS条目未设置或返回了不符合预期的主机名,则使用该功能会变得复杂。 这主要是为了效率:这样,连接尝试最多需要两次解析器查找,一次反向查找和一次正向查找。 如果某个地址存在解析器问题,那就只会成为该客户端的问题。 一个假设的替代实现只进行正向查找的情况下,在每次连接尝试期间都必须解析pg_hba.conf中提到的每个主机名。 @@ -308,7 +258,7 @@ include_dir directory 请注意,这种行为与其他流行的基于主机名的访问控制实现一致,例如 - Apache HTTP服务器和TCP包装器。 + Apache HTTP 服务器和 TCP Wrappers。 @@ -320,7 +270,7 @@ include_dir directory - 这两个字段可以用作IP地址/掩码长度 + 这两个字段可以用作IP-address/mask-length 表示法的替代方案。而不是指定掩码长度,实际掩码在一个单独的列中指定。 例如,255.0.0.0表示IPv4的CIDR掩码长度为8, 而255.255.255.255表示CIDR掩码长度为32。 @@ -503,11 +453,7 @@ include_dir directory auth-options - - - 在auth-method字段之后,可以是形如name=value的字段, - 用于指定认证方法的选项。关于哪些选项适用于哪些认证方法的详细信息见下文。 - + auth-method 字段之后,可以有一个或多个形如 name=value 的字段,用于指定认证方法的选项。下文会详细说明各认证方法有哪些可用选项。 除了下面列出的特定于方法的选项外,还有一个方法无关的认证选项 clientcert, @@ -520,7 +466,7 @@ include_dir directory - 对于任何使用客户端证书认证的记录(即使用 cert 认证方法的记录,或使用 clientcert 选项的记录),都可以通过 clientname 选项指定要匹配客户端证书凭据中的哪一部分。此选项有两个可选值。如果指定 clientname=CN,这也是默认值,则用户名将与证书的 Common Name (CN) 匹配。如果改为指定 clientname=DN,则用户名将与证书的完整 Distinguished Name (DN) 匹配。此选项通常最好与用户名映射配合使用。比较时使用的是 RFC 2253 格式的 DN。要查看以这种格式表示的客户端证书 DN,请执行 + 对于任何使用客户端证书认证的记录(即使用 cert 认证方法的记录,或使用 clientcert 选项的记录),都可以通过 clientname 选项指定要匹配客户端证书凭据中的哪一部分。此选项有两个可选值。如果指定 clientname=CN,这也是默认值,则用户名将与证书的 Common Name (CN) 匹配。如果改为指定 clientname=DN,则用户名将与证书的完整 Distinguished Name (DN) 匹配。此选项可能更适合与用户名映射配合使用。比较时使用的是 RFC 2253 格式的 DN。要查看以这种格式表示的客户端证书 DN,请执行 openssl x509 -in myclient.crt -noout -subject -nameopt RFC2253 | sed "s/^subject=//" @@ -528,33 +474,6 @@ openssl x509 -in myclient.crt -noout -subject -nameopt RFC2253 | sed "s/^subject - - - include - - - 这一行会被给定文件的内容替换。 - - - - - - include_if_exists - - - 如果给定文件存在,这一行会被该文件的内容替换;否则会记录一条消息,说明该文件已被跳过。 - - - - - - include_dir - - - 这一行会被目录中找到的所有文件内容替换,前提是这些文件名不以 . 开头并且以 .conf 结尾;这些文件会按照文件名字典序处理(依据 C locale 规则,即数字排在字母前,大写字母排在小写字母前)。 - - - @@ -562,19 +481,17 @@ openssl x509 -in myclient.crt -noout -subject -nameopt RFC2253 | sed "s/^subject 由 @ 构造引用的文件会被读取为名称列表,其中的名称可以用空白或逗号分隔。注释仍然用 # 引入,与 pg_hba.conf 中相同,并且允许嵌套的 @ 构造。除非 @ 后面的文件名是绝对路径,否则它会被视为相对于引用它的文件所在目录。 - - 因为每一次连接尝试都会顺序地检查pg_hba.conf记录,所以这些记录的顺序是非常关键的。通常,靠前的记录有比较严的连接匹配参数和比较弱的认证方法,而靠后的记录有比较松的匹配参数和比较强的认证方法。 例如,我们希望对本地 TCP/IP 连接使用trust认证,而对远程 TCP/IP 连接要求密码。在这种情况下为来自于 127.0.0.1 的连接指定trust认证的记录将出现在为一个更宽范围的客户端 IP 地址指定密码认证的记录前面。 - + 由于每次连接尝试都会按顺序检查 pg_hba.conf 记录,因此记录的顺序很重要。通常,靠前的记录使用较严格的连接匹配条件和较弱的认证方法,靠后的记录使用较宽松的匹配条件和较强的认证方法。例如,可能希望对本地 TCP/IP 连接使用 trust 认证,而要求远程 TCP/IP 连接提供密码。此时,为来自 127.0.0.1 的连接指定 trust 认证的记录,应放在为更大范围的允许客户端 IP 地址指定密码认证的记录之前。 - 在启动以及主服务器进程收到SIGHUPSIGHUP信号时,pg_hba.conf文件会被读取。 - 如果你在活动的系统上编辑了该文件,你将需要通知 postmaster(使用pg_ctl reload,调用SQL函数pg_reload_conf(),或使用kill -HUP)使其重新读取该文件。 + 在启动时以及主服务器进程收到 SIGHUPSIGHUP 信号时,pg_hba.conf 文件会被读取。 + 如果你在运行中的系统上编辑了该文件,就需要通知 postmaster(使用 pg_ctl reload、调用 SQL 函数 pg_reload_conf(),或者使用 kill -HUP)重新读取该文件。 - 前面的说明在Microsoft Windows上不为真:在Windows上,pg_hba.conf文件中的任何更改会立即被应用到后续的新连接上。 + 前面的说明不适用于 Microsoft Windows:在Windows上,pg_hba.conf文件中的任何更改会立即被应用到后续的新连接上。 @@ -589,9 +506,7 @@ openssl x509 -in myclient.crt -noout -subject -nameopt RFC2253 | sed "s/^subject - - 中展示了pg_hba.conf项的一些示例。不同认证方法的详情请见下一节。 - + 展示了一些 pg_hba.conf 条目示例。有关不同认证方法的详细信息,参见下一节。 @@ -599,8 +514,8 @@ openssl x509 -in myclient.crt -noout -subject -nameopt RFC2253 | sed "s/^subject # 允许本地系统上的任何用户 -# 通过 Unix 域套接字以任意 -# 数据库用户名连接到任意数据库(本地连接的默认值)。 +# 通过 Unix 域套接字(本地连接的默认方式)以任意 +# 数据库用户名连接到任意数据库。 # # TYPE DATABASE USER ADDRESS METHOD local all all trust @@ -625,13 +540,6 @@ host all all ::1/128 trust # TYPE DATABASE USER ADDRESS METHOD host all all localhost trust -# 使用 DATABASE 正则表达式的相同规则,它允许连接到任何 -# 名称以 "db" 开头并以两到四位数字结尾的数据库 -# (例如 "db1234" 或 "db12")。 -# -# TYPE DATABASE USER ADDRESS METHOD -host "/^db\d{2,4}$" all localhost trust - # 允许来自任意具有 IP 地址192.168.93.x 的主机上任意 # 用户以 ident 为该连接所报告的相同用户名连接到 # 数据库 "postgres"(通常是操作系统用户名)。 @@ -645,7 +553,7 @@ host postgres all 192.168.93.0/24 ident # TYPE DATABASE USER ADDRESS METHOD host postgres all 192.168.12.10/32 scram-sha-256 -# 如果用户的密码被正确提供,允许 example.com 中主机上 +# 如果用户的密码被正确提供,允许 example.com 域中主机上 # 的任意用户连接到任意数据库。 # # 为大部分用户要求SCRAM认证,但是用户'mike'是个例外, @@ -656,7 +564,7 @@ host all mike .example.com md5 host all all .example.com scram-sha-256 # 如果没有前面的 "host" 行,这三行 -# 将拒绝所有来自 192.168.54.1的连接(因为那些项将首先被匹配), +# 将拒绝所有来自 192.168.54.1的连接(因为该条目将首先被匹配), # 但是允许来自互联网其他任何地方的 # GSSAPI 加密连接。零掩码表示不会考虑主机 IP 地址中的任何位, # 因此它会匹配任意主机。未加密的 GSSAPI 连接 @@ -671,28 +579,27 @@ host all all 192.168.12.10/32 gss # 允许来自 192.168.x.x 主机的用户连接到任意数据库,如果它们能够 # 通过 ident 检查。例如,假设 ident说用户是 "bryanh" 并且他要求以 # PostgreSQL 用户 "guest1" 连接,如果在 pg_ident.conf 有一个映射 -# "omicron" 的选项说 "bryanh" 被允许以 "guest1" 连接,则该连接将被允许。 +# "omicron" 的条目表明 "bryanh" 被允许以 "guest1" 连接,则该连接将被允许。 # # TYPE DATABASE USER ADDRESS METHOD host all all 192.168.0.0/16 ident map=omicron -# 如果这些是本地连接的唯一四行,它们将允许本地用户只连接到它们 -# 自己的数据库(与其数据库用户名同名的数据库),不过用户名以 -# "helpdesk" 结尾的用户、管理员以及角色 "support" 的成员除外 -# (它们可以连接到所有数据库)。文件 $PGDATA/admins 包含一个 -# 管理员名字的列表。在所有情况下都要求密码。 +# 如果这些是本地连接的唯一三行,它们将允许本地用户只连接到 +# 自己的数据库(与其数据库用户名同名的数据库),但管理员和 +# 角色 "support" 的成员除外,他们可以连接到所有数据库。 +# 文件 $PGDATA/admins 包含管理员名称列表。 +# 所有情况下都要求提供密码。 # # TYPE DATABASE USER ADDRESS METHOD -local sameuser all scram-sha-256 -local all /^.*helpdesk$ scram-sha-256 -local all @admins scram-sha-256 -local all +support scram-sha-256 +local sameuser all md5 +local all @admins md5 +local all +support md5 # 上面的最后两行可以被整合为一行: -local all @admins,+support scram-sha-256 +local all @admins,+support md5 # 数据库列也可以用列表和文件名: -local db1,db2,@demodbs all scram-sha-256 +local db1,db2,@demodbs all md5 @@ -709,44 +616,14 @@ local db1,db2,@demodbs all scram-sha-256 当使用 Ident 或 GSSAPI 之类的外部认证系统时,发起连接的操作系统用户名可能不同于要使用的数据库用户(角色)。在这种情况下,可以通过用户名映射把操作系统用户名映射为数据库用户。要使用用户名映射,需要在 pg_hba.conf 的选项字段中指定 map=map-name。此选项适用于所有会接收外部用户名的认证方法。由于不同连接可能需要不同映射,在 pg_hba.conf 中通过 map-name 参数指定要使用的映射,以表明每个连接应使用哪个映射。 - - 用户名映射定义在 ident 映射文件中,该文件默认名为 pg_ident.confpg_ident.conf,并存放在集簇的数据目录中。(当然,也可以把该映射文件放在别处;见配置参数 。) - ident 映射文件中的行通常有如下形式: - + 用户名映射在 ident 映射文件中定义。该文件默认名为 pg_ident.confpg_ident.conf,存储在集簇的数据目录中。(也可以将映射文件放在其他位置;参见 配置参数。)ident 映射文件中各行的基本格式如下: map-name system-username database-username -include file -include_if_exists file -include_dir directory - - 注释、空白以及续行的处理方式与 pg_hba.conf 完全相同。 - map-name 是一个任意名称,用于在 pg_hba.conf 中引用该映射。 - 其余两个字段分别指定一个操作系统用户名和一个与之匹配的数据库用户名。 - 同一个 map-name 可以重复使用,以便在同一映射中定义多条用户映射。 - - - - 与 pg_hba.conf 一样,此文件中的各行也可以是 include 指令,并遵循相同的规则。 - - - - 对于给定的一个操作系统用户可以对应多少个数据库用户,没有任何限制,反之亦然。因此,映射中的条目应理解为该操作系统用户被允许以该数据库用户身份连接,而不是意味着两者等价。只要存在任何一条映射项把外部认证系统获得的用户名与用户请求连接时使用的数据库用户名配对起来,该连接就会被允许。值 all 还可以用作 database-username,表示只要 system-username 匹配,该用户就被允许以任意现有数据库用户身份登录。若给 all 加上引号,则它会失去该特殊含义。 - - - - 如果 database-username 字段以 + 开头,则该操作系统用户可以以属于该角色的任意用户身份登录,这与 pg_hba.conf 中以 + 开头的用户名处理方式类似。因此,+ 标记表示匹配直接或间接属于该角色的任意角色,而没有 + 标记的名称只匹配该特定角色。对以 + 开头的用户名加上引号,会让 + 失去其特殊含义。 - - - - 如果 system-username 字段以斜线(/)开头,则该字段的其余部分会被视为一个正则表达式。(关于 PostgreSQL 正则表达式语法的细节,见 。)该正则表达式可以包含一个捕获组,也就是用圆括号括起来的子表达式;捕获到的系统用户名片段随后可以在 database-username 字段中通过 \1(反斜线一)引用。这使得在一行中映射多个用户名成为可能,特别适合简单的语法替换。例如,下面这些条目 - +注释、空白和续行的处理方式与 pg_hba.conf 相同。map-name 是任意名称,用于在 pg_hba.conf 中引用此映射。另两个字段指定操作系统用户名及与之匹配的数据库用户名。同一个 map-name 可以重复使用,以便在一项映射中指定多个用户对应关系。 + 一个操作系统用户可以对应多少个数据库用户,没有限制,反之亦然。因此,映射中的条目应理解为此操作系统用户可以作为此数据库用户连接,而不是说二者等同。只要存在一个映射条目,将从外部认证系统取得的用户名与用户请求连接时使用的数据库用户名配对,就会允许该连接。 + 如果 system-username 字段以斜杠(/)开头,该字段的其余部分就会被视为正则表达式。(参见 ,其中介绍了 PostgreSQL 的正则表达式语法。)正则表达式可以包含一个捕获,即用圆括号括起来的子表达式。系统用户名中与捕获匹配的部分,可以在 database-username 字段中使用 \1(反斜杠加数字一)来引用。这样就可以在一行中映射多个用户名,对简单的语法替换尤其有用。例如,以下条目 mymap /^(.*)@mydomain\.com$ \1 mymap /^(.*)@otherdomain\.com$ guest - - 会去掉系统用户名中以 @mydomain.com 结尾的域名部分,并允许任何系统名以 @otherdomain.com 结尾的用户以 guest 身份登录。对包含 \1database-username 加上引号,并不会\1 失去其特殊含义。 - - - - 如果 database-username 字段以斜线(/)开头,则该字段其余部分会被视为一个正则表达式。当 database-username 字段是正则表达式时,不能在其中使用 \1 来引用 system-username 字段中的捕获组。 +会去掉系统用户名中的域名部分(如果用户名以 @mydomain.com 结尾),并允许系统用户名以 @otherdomain.com 结尾的任何用户登录为 guest @@ -854,7 +731,7 @@ omicron bryanh guest1 - Peer 认证通常适用于本地连接,不过在某些情况下,信任认证也可能已经足够。 + 通常建议对本地连接使用 Peer 认证,不过在某些情况下,信任认证也可能已经足够。 密码认证是远程连接最容易采用的选择。 其余所有选项都需要某种外部安全基础设施(通常是认证服务器,或用于签发 SSL 证书的证书颁发机构),或者属于平台特定功能。 @@ -873,16 +750,14 @@ omicron bryanh guest1 - trust认证对于单用户工作站的本地连接是非常合适和方便的。通常它本身适用于一台多用户机器。不过,只要你利用文件系统权限限制了对服务器的 Unix 域套接字文件的访问,即使在多用户机器上,你也可以使用trust。 要做这些限制,你可以设置中描述的unix_socket_permissions配置参数(可能还有unix_socket_group)。 或者你可以设置unix_socket_directories配置参数来把 Unix 域套接字文件放在一个经过恰当限制的目录中。 + trust认证对于单用户工作站的本地连接是非常合适和方便的。通常它本身适用于一台多用户机器。不过,只要你利用文件系统权限限制了对服务器的 Unix 域套接字文件的访问,即使在多用户机器上,你也可能可以使用trust。 要做这些限制,你可以设置中描述的unix_socket_permissions配置参数(可能还有unix_socket_group)。 或者你可以设置unix_socket_directories配置参数来把 Unix 域套接字文件放在一个经过恰当限制的目录中。 设置文件系统权限只能有助于 Unix 套接字连接。本地 TCP/IP 连接不会被文件系统权限限制。因此,如果你想利用文件系统权限来控制本地安全,那么从pg_hba.conf中移除host ... 127.0.0.1 ...行,或者把它改为一个非trust认证方法。 - - 如果通过指定trustpg_hba.conf行让你信任每一个被允许连接到服务器的机器上的用户,trust认证只适合 TCP/IP 连接。为任何不是来自localhost(127.0.0.1)的 TCP/IP 连接使用trust很少是合理的。 - + 只有当你信任由 pg_hba.conf 中指定 trust 的行所允许连接的每台机器上的每个用户时,trust 认证才适合用于 TCP/IP 连接。对来自 localhost(127.0.0.1)以外的任何 TCP/IP 连接使用 trust,通常都不合理。 @@ -927,9 +802,9 @@ omicron bryanh guest1 md5 - - 方法md5使用一种自定义的安全性较低的挑战-响应机制。它能防止密码嗅探并且防止密码在服务器上以明文存储,但是无法保护攻击者想办法从服务器上窃取了密码哈希的情况。此外,现在认为MD5哈希算法对于确定攻击已经不再安全。 - + 方法md5使用一种自定义的、安全性较低的挑战-响应机制。它能防止密码嗅探,并避免在服务器上以明文存储密码;但如果攻击者设法从服务器上窃取了密码哈希,它就无法提供保护。此外,如今已不再认为 MD5 哈希算法能抵御有决心的攻击者。 + + md5方法不能与功能一起使用。 为了简化从md5方法到较新的SCRAM方法的转变,如果在pg_hba.conf中指定了md5但是用户在服务器上的密码是为SCRAM(见下文)加密的,则将自动选择基于SCRAM的认证。 @@ -957,7 +832,7 @@ omicron bryanh guest1 - 要把现有安装从 md5 升级到 scram-sha-256,需要先确保所有正在使用的客户端库都足够新并支持 SCRAM,然后在 postgresql.conf 中设置 password_encryption = 'scram-sha-256',要求所有用户重新设置密码,并将 pg_hba.conf 中的认证方法说明改为 scram-sha-256。 + 要把现有安装从 md5 升级到 scram-sha-256,需要先确保所有正在使用的客户端库都足够新并支持 SCRAM,然后在 postgresql.conf 中设置 password_encryption = 'scram-sha-256',要求所有用户重新设置密码,并将 pg_hba.conf 中的认证方法设置改为 scram-sha-256 @@ -1099,7 +974,9 @@ omicron bryanh guest1 include_realm - 如果设为 0,则在通过用户名映射()之前,会先从已认证用户的主体名中去掉 realm 名称。不建议这样做;它主要是为了向后兼容而保留的,因为在多 realm 环境中这并不安全,除非同时使用了 krb_realm。建议将 include_realm 保持为默认值(1),并在 pg_ident.conf 中提供显式映射,把主体名转换成 PostgreSQL 用户名。 + 如果设为 0,则在通过用户名映射()之前,会先从已认证用户的主体名中去掉 realm 名称。 + 不建议这样做;它主要是为了向后兼容而保留的,因为在多 realm 环境中这并不安全,除非同时使用了 krb_realm。 + 建议将 include_realm 保持为默认值(1),并在 pg_ident.conf 中提供显式映射,把主体名转换成 PostgreSQL 用户名。 @@ -1111,7 +988,7 @@ omicron bryanh guest1 如果设为 1,则会在 include_realm 选项中使用域的 SAM 兼容名称(也称为 NetBIOS 名称)。这是默认值。如果设为 0,则会使用 Kerberos 用户主体名中的真实 realm 名称。 - 不要禁用这个选项,除非你的服务器运行在一个域账号(这包括一个域成员系统上的虚拟服务账号)下并且所有通过 SSPI 认证的所有客户端也在使用域账号,否则认证将会失败。 + 不要禁用这个选项,除非你的服务器运行在一个域账号(这包括一个域成员系统上的虚拟服务账号)下并且所有通过 SSPI 认证的客户端也在使用域账号,否则认证将会失败。 @@ -1169,14 +1046,13 @@ omicron bryanh guest1 - - ident 支持下列配置选项: + 以下配置选项适用于 ident map - 允许在系统用户和数据库用户名称之间进行映射。详细信息请参见。 + 允许在系统用户名和数据库用户名之间进行映射。详见 @@ -1199,7 +1075,7 @@ omicron bryanh guest1
RFC 1413 - 标识协议的本意不是作为一种认证或访问控制协议。 + 标识协议的本意不是作为一种授权或访问控制协议。
@@ -1221,14 +1097,13 @@ omicron bryanh guest1 Peer 认证通过从内核获取客户端的操作系统用户名,并把它用作被允许的数据库用户名(可结合可选的用户名映射)来工作。这种方法只支持本地连接。
- - peer 支持下列配置选项: + 以下配置选项适用于 peer map - 允许在系统用户和数据库用户名称之间进行映射。详细信息请参见。 + 允许在系统用户名和数据库用户名之间进行映射。详见 @@ -1258,7 +1133,7 @@ omicron bryanh guest1 - 第二种模式称为搜索+绑定模式,服务器首先使用由 ldapbinddnldapbindpasswd 指定的固定用户名和密码绑定到 LDAP 目录,并搜索试图登录数据库的用户。如果没有配置用户名和密码,则会尝试对目录进行匿名绑定。搜索会在 ldapbasedn 指定的子树上进行,并尝试对 ldapsearchattribute 指定的属性做精确匹配。一旦在搜索中找到了该用户,服务器就会作为该用户重新绑定到目录,并使用客户端指定的密码来验证登录是否正确。这种模式与 Apache mod_authnz_ldappam_ldap 等软件中的 LDAP 认证方案相同。这种方法使目录中用户对象的位置更具灵活性,但会对 LDAP 服务器额外发起两次请求。 + 第二种模式称为搜索+绑定模式,服务器首先使用由 ldapbinddnldapbindpasswd 指定的固定用户名和密码绑定到 LDAP 目录,并搜索试图登录数据库的用户。如果没有配置用户名和密码,则会尝试对目录进行匿名绑定。搜索会在 ldapbasedn 指定的子树上进行,并尝试对 ldapsearchattribute 指定的属性做精确匹配。一旦在搜索中找到了该用户,服务器会断开连接,再作为该用户重新绑定到目录,并使用客户端指定的密码来验证登录是否正确。这种模式与 Apache mod_authnz_ldappam_ldap 等软件中的 LDAP 认证方案相同。这种方法使目录中用户对象的位置更具灵活性,但会与 LDAP 服务器建立两个独立的连接。 @@ -1284,8 +1159,7 @@ omicron bryanh guest1 ldapscheme - 设置为ldaps以使用LDAPS。这是一种非标准的使用LDAP - 进行SSL加密的方式,受一些LDAP服务器实现支持。另请参阅ldaptls + 设置为ldaps以使用LDAPS。这是一种非标准的通过 SSL 使用 LDAP 的方式,受一些LDAP服务器实现支持。另请参阅ldaptls 选项作为替代。 @@ -1378,16 +1252,14 @@ omicron bryanh guest1 一个RFC 4516 - LDAP URL。这是以更紧凑和标准形式编写其他LDAP选项的替代方式。格式为 + LDAP URL。这是以更紧凑和标准形式编写部分其他 LDAP 选项的替代方式。格式为 ldap[s]://host[:port]/basedn[?[attribute][?[scope][?[filter]]]] scope必须是baseonesub中的一个,通常是最后一个。(默认为base,在此应用中通常无用。)attribute可以指定单个属性,此时将用作ldapsearchattribute的值。如果attribute为空,则filter可用作ldapsearchfilter的值。 - - URL方案ldaps选择了通过SSL进行LDAP连接的LDAPS方法,相当于使用ldapscheme=ldaps。要使用StartTLS操作进行加密LDAP连接,请使用正常的URL方案ldap并另外指定ldaptls选项。 - + URL 方案 ldaps 会选择 LDAPS 方法,通过 SSL 建立 LDAP 连接,等同于使用 ldapscheme=ldaps。要通过 StartTLS 操作使用加密的 LDAP 连接,请使用普通的 URL 方案 ldap,并在 ldapurl 之外指定 ldaptls 选项。 对于非匿名绑定,必须将ldapbinddnldapbindpasswd指定为单独的选项。 @@ -1402,7 +1274,7 @@ ldap[s]://host[:port]/ - 将简单绑定选项与搜索+绑定选项混用是错误的。若要在简单绑定模式下使用 ldapurl,该 URL 中不能包含 basedn 或查询元素。 + 将简单绑定模式的配置选项与搜索+绑定模式的配置选项混用是错误的。 @@ -1421,21 +1293,9 @@ host ... ldap ldapserver=ldap.example.net ldapprefix="cn=" ldapsuffix=", dc=exam 当请求以数据库用户 someuser 连接数据库服务器时,PostgreSQL 将尝试使用 DN cn=someuser, dc=example, dc=net 和客户端提供的密码绑定到 LDAP 服务器。如果该连接成功,数据库访问就会被授予。 - - 下面是另一种简单绑定配置,它使用 LDAPS 方案和自定义端口号,并以 URL 形式写出: - -host ... ldap ldapurl="ldaps://ldap.example.net:49151" ldapprefix="cn=" ldapsuffix=", dc=example, dc=net" - - 这种写法比单独指定 ldapserverldapschemeldapport 稍微更紧凑。 - - - - 下面是一个搜索+绑定配置示例: - + 下面是搜索加绑定配置的示例: host ... ldap ldapserver=ldap.example.net ldapbasedn="dc=example, dc=net" ldapsearchattribute=uid - - 当请求以数据库用户 someuser 连接数据库服务器时,PostgreSQL 将尝试对 LDAP 服务器进行匿名绑定(因为未指定 ldapbinddn),并在指定的基础 DN 下执行一次 (uid=someuser) 搜索。如果找到了对应条目,随后就会尝试使用该条目的信息以及客户端提供的密码进行绑定。如果第二次绑定成功,数据库访问就会被授予。 - +当请求以数据库用户 someuser 的身份连接数据库服务器时,PostgreSQL 会尝试匿名绑定到 LDAP 服务器(因为没有指定 ldapbinddn),并在指定的基础 DN 下搜索 (uid=someuser)。如果找到了条目,就会尝试使用找到的信息和客户端提供的密码进行绑定。如果第二次连接成功,就会授予数据库访问权限。 下面是以 URL 形式写出的同一个搜索+绑定配置: @@ -1682,7 +1542,7 @@ FATAL: user "andym" does not exist FATAL: database "testdb" does not exist - 你试图连接的数据库不存在。注意,如果你没有指定数据库名,默认会使用数据库用户名作为数据库名。 + 你试图连接的数据库不存在。注意,如果你没有指定数据库名,默认会使用数据库用户名作为数据库名,但这不一定是所需的数据库名。 diff --git a/zh/14/config.sgml b/zh/14/config.sgml index a85833f1..300baec5 100644 --- a/zh/14/config.sgml +++ b/zh/14/config.sgml @@ -51,7 +51,7 @@ 字符串: 通常值被包括在单引号内,值内部的任何单引号都需要被双写。不过,如果值是一个简单数字或者 标识符,引号通常可以被省略。 - (与 SQL 关键字匹配的值需要在某些上下文中引用。) + (与 SQL 关键字匹配的值在某些上下文中需要加引号。) @@ -70,7 +70,7 @@ 带单位的数字: 一些数字参数具有隐含单位,因为它们描述的是内存或时间量。单位可能是字节、千字节、块 - (通常为 8 千字节)、毫秒、秒或分钟。这类设置若给出不带修饰的数字值,就会使用该设置的默认单位, + (通常为 8 千字节)、毫秒、秒或分钟。这类设置若给出不带单位的数字值,就会使用该设置的默认单位, 可以通过 pg_settings.unit 了解该默认单位。为了方便, 也可以显式指定单位,例如把时间值写成 '120 ms',系统会将其转换为该参数的实际单位。 注意,要使用这一特性,值必须写成字符串(带引号)。单位名称区分大小写,并且数字值与单位之间可以有空白。 @@ -122,7 +122,7 @@ 它通常位于数据目录中。在数据库集簇目录初始化时,会安装该文件的一个默认副本。其内容示例如下: # This is a comment -log_connections = all +log_connections = yes log_destination = 'syslog' search_path = '"$user", public' shared_buffers = 128MB @@ -162,7 +162,7 @@ shared_buffers = 128MB 外部工具也可以修改 postgresql.auto.conf。 - 除非将 设为 off,否则不建议在服务器运行时这样做, + 不建议在服务器运行时这样做, 因为并发的 ALTER SYSTEM 命令可能会覆盖这些更改。 这类工具可能只是简单地在文件末尾追加新设置,也可能选择删除重复设置和/或注释 (正如 ALTER SYSTEM 那样)。 @@ -175,9 +175,10 @@ shared_buffers = 128MB - + - 通过 SQL 影响参数 + 通过SQL影响参数 + PostgreSQL提供了三个SQL命令来建立配置默认值。 @@ -190,14 +191,14 @@ shared_buffers = 128MB - ALTER DATABASE命令允许针对一个数据库覆盖其全局设置。 + ALTER DATABASE命令允许针对各个数据库覆盖全局设置。 - ALTER ROLE命令允许用用户指定的值来覆盖全局设置和数据库设置。 + ALTER ROLE命令允许用针对特定用户设置的值来覆盖全局设置和数据库设置。 @@ -271,7 +272,7 @@ UPDATE pg_settings SET setting = reset_val WHERE name = 'configuration_parameter 通过 Shell 影响参数 - 除了在数据库或者角色层面上设置全局默认值或者进行覆盖,你还可以通过 shell 工具把设置 + 除了设置全局默认值或在数据库、角色级别覆盖默认值之外,你还可以通过 shell 工具把设置 传递给PostgreSQL。服务器和libpq 客户端库都能通过 shell 接受参数值。 @@ -283,7 +284,7 @@ UPDATE pg_settings SET setting = reset_val WHERE name = 'configuration_parameter 在服务器启动期间,可以通过命令行参数把参数设置传递给 postgres命令。例如: -postgres -c log_connections=all --log-destination='syslog' +postgres -c log_connections=yes -c log_destination='syslog' 这种方式提供的设置会覆盖通过postgresql.conf或者 ALTER SYSTEM提供的设置,因此除了重启服务器之外无法从全局上改变它们。 @@ -299,7 +300,7 @@ postgres -c log_connections=all --log-destination='syslog' postgres命令时用到的相似,特别是标志必须被指定。 例如: -env PGOPTIONS="-c geqo=off --statement-timeout=5min" psql +env PGOPTIONS="-c geqo=off -c statement_timeout=5min" psql @@ -343,7 +344,7 @@ include 'filename' 还有一个 include_if_exists 指令,其行为与 include 相同, 但在被引用文件不存在或无法读取时有所不同。普通的 include 会将其视为错误, - 而 include_if_exists 只会记录一条消息并继续处理引用配置文件。 + 而 include_if_exists 只会记录一条消息并继续处理引用它的配置文件。 @@ -354,21 +355,21 @@ include 'filename' postgresql.conf 文件也可以包含 include_dir 指令, 用来指定一个应被包含的配置文件目录。其用法如下: - include_dir 'directory' - - 非绝对目录名会被解释为相对于引用配置文件所在目录的路径。在指定目录中, +include_dir 'directory' + + 非绝对目录名会被解释为相对于引用它的配置文件所在目录的路径。在指定目录中, 只有名称以 .conf 结尾的非目录文件才会被包含。以 . 开头的文件名也会被忽略,以避免在某些平台上误处理隐藏文件。包含目录中的多个文件会按文件名顺序处理 (依据 C 区域规则排序,即数字在字母之前,大写字母在小写字母之前)。 - 包括文件或目录可以被用来在逻辑上分隔数据库配置的各个部分,而不是用一个很大的postgresql.conf文件。 + 包含文件或目录可以用来在逻辑上分隔数据库配置的各个部分,而不是用一个很大的postgresql.conf文件。 考虑一个有两台数据库服务器的公司,每一个都有不同的内存量。 - 很可能配置的元素都会被共享,例如用于日志的参数。但是两者关于内存的参数将会不同。 + 两者很可能会共享部分配置,例如日志设置。但是两者关于内存的参数将会不同。 并且还可能会有服务器相关的自定义。 一种管理这类情况的方法是将你的站点的自定义配置修改分成三个文件。 - 你可以把下面的内容加入到你的postgresql.conf文件末尾来包括它们: + 你可以把下面的内容加入到你的postgresql.conf文件末尾来包含它们: include 'shared.conf' include 'memory.conf' @@ -429,7 +430,7 @@ include_dir 'conf.d' - 指定用于数据存储的目录。这个选项只能在服务器启动时设置。 + 指定用于数据存储的目录。这个参数只能在服务器启动时设置。 @@ -489,7 +490,7 @@ include_dir 'conf.d' - 指定可被服务器创建的用于管理程序的额外进程 ID(PID)文件。这个参数只能在服务器启动的时候设置。 + 指定服务器应创建的额外进程 ID(PID)文件的名称,供服务器管理程序使用。这个参数只能在服务器启动的时候设置。 @@ -500,24 +501,22 @@ include_dir 'conf.d' - 如果你想把配置文件放在别的地方而不是数据目录中,那么postgres 命令行选项或者环境变量PGDATA必须指向包含配置文件的目录,并且postgresql.conf中(或者命令行上)的data_directory参数必须显示数据目录实际存放的地方。请注意,data_directory将覆盖PGDATA指定的数据目录位置,但是不覆盖配置文件的位置。 + 如果你想把配置文件放在别的地方而不是数据目录中,那么postgres 命令行选项或者环境变量PGDATA必须指向包含配置文件的目录,并且postgresql.conf中(或者命令行上)的data_directory参数必须设置为数据目录的实际位置。请注意,data_directory将覆盖PGDATA指定的数据目录位置,但是不覆盖配置文件的位置。 - 如果你愿意,可以使用选项config_filehba_file和/或ident_file单独指定配置文件名称和位置。config_file只能在postgres命令行上指定,但是其他文件可以在主配置文件中设置。如果所有三个参数外加data_directory被显式地设置,则不必指定PGDATA。 + 如果你愿意,可以使用选项config_filehba_file和/或ident_file单独指定配置文件名称和位置。config_file只能在postgres命令行上指定,但是其他参数可以在主配置文件中设置。如果所有三个参数外加data_directory被显式地设置,则不必指定PGDATA - 在设置任何这些参数时,相对路径将被解释为相对于postgres启动路径的路径。 + 在设置任何这些参数时,相对路径将被解释为相对于启动 postgres 时所在目录的路径。 - 连接和认证 - 连接设置 @@ -532,7 +531,7 @@ include_dir 'conf.d' - 指定服务器用于监听来自客户端应用程序的连接的TCP/IP地址(指服务器网卡IP地址)。 + 指定服务器用于监听来自客户端应用程序的连接的TCP/IP地址。 该值采用逗号分隔的主机名和/或数字IP地址的形式。特殊条目*对应于所有可用的IP接口。 条目0.0.0.0允许监听所有IPv4地址,::允许监听所有IPv6地址。 如果列表为空,则服务器不会在任何IP接口上监听,此时只能使用Unix域套接字进行连接。 @@ -555,11 +554,11 @@ include_dir 'conf.d' - - - 服务器监听的 TCP 端口;默认是 5432 。请注意服务器会同一个端口号监听所有的 IP 地址。这个参数只能在服务器启动时设置。 - - + + 服务器监听的 TCP 端口,默认是 5432。请注意,服务器监听的所有 IP 地址都使用同一个端口号。 + 此参数只能在服务器启动时设置。 + + @@ -570,22 +569,16 @@ include_dir 'conf.d' - 决定数据库服务器允许的最大并发连接数。默认值通常是 100 个连接,但如果内核设置不支持 (在 initdb 期间确定),则可能更少。这个参数只能在服务器启动时设置。 - - PostgreSQL 会直接根据 max_connections 的值来确定某些资源的规模。 - 增大该值会导致这些资源(包括共享内存)的分配随之增加。 - - 当运行一个备库时,你必须设置这个参数等于或大于主库上的参数。 - 否则,备库上可能无法允许查询。 + 否则,备库上将不允许查询。 - + - - 设置 Unix 域套接字的访问权限。Unix 域套接字使用普通的 Unix 文件系统权限集。这个参数值应该是数字的形式,也就是系统调用chmodumask接受的 形式(如果使用自定义的八进制格式,数字必须以一个0(零)开头)。 + 设置 Unix 域套接字的访问权限。Unix 域套接字使用通常的 Unix 文件系统权限集。参数值应是以 chmodumask 系统调用所接受格式指定的数字权限模式。(要使用惯用的八进制格式,数字必须以 0(零)开头。) - - 默认的权限是0777,意思是任何人都可以连接。合理的候选是0770(只有用户和同组的人可以访问, 又见unix_socket_group)和0700(只有用户自己可以访问)(请注意,对于 Unix 域套接字,只有写权限有麻烦,因此没有对读取和执行权限的设置和收回)。 + 默认权限是 0777,表示任何人都可以连接。合理的其他取值包括 0770(仅属主和所属组,另见 unix_socket_group)和 0700(仅属主)。(注意,对 Unix 域套接字而言,只有写权限起作用,因此设置或撤销读权限和执行权限没有意义。) - - 这个访问控制机制与中的用户认证没有关系。 + 此访问控制机制独立于 中描述的机制。 - - 这个参数只能在服务器启动时设置。 + 此参数只能在服务器启动时设置。 - - 这个参数与完全忽略套接字权限的系统无关,尤其是自版本10以上的Solaris。 - 在那些系统上,可以通过把unix_socket_directories指向一个把搜索权限 - 限制给指定用户的目录来实现相似的效果。 + 此参数对完全忽略套接字权限的系统无效,尤其是 Solaris(截至 Solaris 10)。在这些系统上,可以将 unix_socket_directories 指向一个仅向目标用户授予搜索权限的目录,以达到类似效果。 - - 抽象命名空间中的套接字没有文件权限,所以这种情况下这个设置也会被忽略。 + 抽象命名空间中的套接字没有文件权限,因此这种情况下也会忽略此设置。 @@ -715,10 +700,8 @@ include_dir 'conf.d' - - 通过Bonjour广告服务器的存在。默认值是关闭。 - 这个参数只能在服务器启动时设置。 + 启用通过 Bonjour 通告服务器存在的功能。默认值为关闭。此参数只能在服务器启动时设置。 @@ -731,20 +714,14 @@ include_dir 'conf.d' - - - 指定Bonjour服务名称。空字符串''(默认值)表示使用计算机名。 如果编译时没有打开Bonjour支持那么将忽略这个参数。这个参数只能在服务器启动时设置。 - - + + 指定 Bonjour 服务名。空字符串 ''(默认值)表示使用计算机名。 + 如果编译时未启用 Bonjour 支持,则此参数会被忽略。此参数只能在服务器启动时设置。 + + - - - - - TCP 设置 - - + tcp_keepalives_idle (integer) @@ -753,14 +730,17 @@ include_dir 'conf.d' - 指定在多久没有网络活动后,操作系统应向客户端发送 TCP keepalive 消息。 - 如果指定值时没有单位,则以秒为单位。值 0(默认值)表示选择操作系统默认值。 - 在 Windows 上,将该值设为 0 会把此参数设为 2 小时,因为 Windows 不提供读取系统默认值的方法。 + 如果指定值时没有单位,则以秒为单位。值 0(默认值)表示选择操作系统默认值。 这个参数只有在支持 TCP_KEEPIDLE 或等效套接字选项的系统以及 Windows 上才可用; 在其他系统上,它必须为零。在通过 Unix 域套接字连接的会话中,这个参数会被忽略,并始终读作零。 + + + 在 Windows 上,值 0 会将此参数设置为 2 小时,因为 Windows 不提供读取系统默认值的方法。 + + @@ -772,14 +752,17 @@ include_dir 'conf.d' - 指定未被客户端确认收到的 TCP keepalive 消息在多久之后应被重传。 - 如果指定值时没有单位,则以秒为单位。值 0(默认值)表示选择操作系统默认值。 - 在 Windows 上,将该值设为 0 会把此参数设为 1 秒,因为 Windows 不提供读取系统默认值的方法。 + 如果指定值时没有单位,则以秒为单位。值 0(默认值)表示选择操作系统默认值。 这个参数只有在支持 TCP_KEEPINTVL 或等效套接字选项的系统以及 Windows 上才可用; 在其他系统上,它必须为零。在通过 Unix 域套接字连接的会话中,这个参数会被忽略,并始终读作零。 + + + 在 Windows 上,值 0 会将此参数设置为 1 秒,因为 Windows 不提供读取系统默认值的方法。 + + @@ -791,14 +774,18 @@ include_dir 'conf.d' - 指定在服务器与客户端之间的连接被视为中断之前,可以丢失多少个 TCP keepalive 消息。 - 值 0(默认值)表示选择操作系统默认值。 + 值 0(默认值)表示选择操作系统默认值。 这个参数只有在支持 TCP_KEEPCNT 或等效套接字选项的系统上才可用 - (不包括 Windows);在其他系统上,它必须为零。在通过 Unix 域套接字连接的会话中, + ;在其他系统上,它必须为零。在通过 Unix 域套接字连接的会话中, 这个参数会被忽略,并始终读作零。 + + + Windows 不支持此参数,它必须为零。 + + @@ -810,13 +797,17 @@ include_dir 'conf.d' - 指定已发送的数据在 TCP 连接被强制关闭之前最多可以保持未确认状态多长时间。 - 如果指定值时没有单位,则以毫秒为单位。值 0(默认值)表示选择操作系统默认值。 - 这个参数只在支持 TCP_USER_TIMEOUT 的系统上受支持(不包括 Windows); + 如果指定值时没有单位,则以毫秒为单位。值 0(默认值)表示选择操作系统默认值。 + 这个参数只在支持 TCP_USER_TIMEOUT 的系统上受支持; 在其他系统上,它必须为零。在通过 Unix 域套接字连接的会话中,此参数会被忽略,并始终读作零。 + + + Windows 不支持此参数,它必须为零。 + + @@ -828,106 +819,17 @@ include_dir 'conf.d' - - - 在运行查询时,设置检查客户端是否保持连接的可选检查的时间间隔。 - 这个检查通过轮询套接字来执行,并且在内核报告该连接关闭时,允许长时间运行的查询可以尽快中止。 - - - - 此选项目前仅在支持非标准POLLRDHUP扩展的 - poll系统调用的系统上可用,包括Linux。 - - - - 如果指定的值没有单位,则以毫秒为单位。 - 默认值为0,代表禁用连接检查。 - 没有连接检查,服务器将只在与套接字的下一次交互时检测连接的丢失,当它等待、接收或发送数据时。 - - - - 为了让内核本身能够在包括网络故障在内的所有场景中,在已知的时间范围内可靠地检测丢失的TCP连接,它可能还需要调整操作系统的TCP保持连接设置, - 或者PostgreSQL, 设置。 - - - - - - file_copy_method (enum) - - file_copy_method配置参数 - - - - - 指定用于复制文件的方法。可能的值包括 COPY(默认)和 - CLONE(如果操作系统支持)。 - - 此参数会影响: + 设置查询执行期间可选的客户端连接检查的时间间隔,用于检查客户端是否仍然连接。检查通过轮询套接字执行;如果内核报告连接已经关闭,就可以更早中止长时间运行的查询。 - - - - CREATE DATABASE ... STRATEGY=FILE_COPY - - - - - ALTER DATABASE ... SET TABLESPACE ... - - - - CLONE 使用 copy_file_range()(Linux、FreeBSD) - 或 copyfile(macOS)系统调用,让内核有机会共享磁盘块, - 或把工作下推到某些文件系统的较低层。 + 此选项目前仅在支持 poll 系统调用的非标准 POLLRDHUP 扩展的系统(包括 Linux)上可用。 - - - - - file_extend_method (enum) - - file_extend_method配置参数 - - - - 指定在诸如COPY这类批量操作期间扩展数据文件时所使用的方法。 - 默认会根据操作系统选择第一个可用选项: - - - - posix_fallocate(Unix)使用标准 POSIX 接口分配磁盘空间,但某些系统缺少该接口。 - 如果接口存在但底层文件系统不支持,本选项会静默回退到write_zeros。 - 已知当前版本的 BTRFS 在使用该选项时会禁用压缩。 - 在提供该函数的系统上,这是默认值。 - - - - - write_zeros通过写出零字节块来扩展文件。 - 在不提供posix_fallocate函数的系统上,这是默认值。 - - - - 当数据文件扩展的块数不超过 8 个时,总是使用write_zeros方法。 + 如果指定值时没有单位,则以毫秒计。默认值为 0,表示禁用连接检查。如果不进行连接检查,服务器只有在下一次与套接字交互(等待、接收或发送数据)时,才会检测到连接丢失。 - - - - - max_notify_queue_pages (integer) - - max_notify_queue_pages配置参数 - - - - 指定 / 队列可分配页面的最大数量。 - 默认值是 1048576。对于 8 KB 页面,这允许最多消耗 8 GB 的磁盘空间。 - 此参数只能在服务器启动时设置。 + 要让内核本身在包括网络故障在内的所有场景中,能够在确定的时间范围内可靠地检测到 TCP 连接丢失,可能还需要调整操作系统的 TCP keepalive 设置,或 PostgreSQL 设置。 @@ -936,7 +838,6 @@ include_dir 'conf.d' - 认证 @@ -980,43 +881,6 @@ include_dir 'conf.d' 请注意,较旧的客户端可能缺少对 SCRAM 认证机制的支持,因此无法使用以 SCRAM-SHA-256 加密的密码。 详情参见 - - - 对 MD5 加密密码的支持已被弃用,并将在未来的 PostgreSQL 版本中移除。 - 关于迁移到其他密码类型的细节,请参见 。 - - - - - - - scram_iterations (integer) - - scram_iterations配置参数 - - - - - 使用 SCRAM-SHA-256 加密密码时执行的计算迭代次数。默认值为 - 4096。更高的迭代次数可以对存储密码遭受暴力破解攻击提供额外保护, - 但也会使认证变慢。更改此值不会影响现有的 SCRAM-SHA-256 加密密码, - 因为迭代次数在加密时就已经固定。要利用更改后的值,必须设置新密码。 - - - - - - md5_password_warnings (boolean) - - md5_password_warnings配置参数 - - - - - 控制在CREATE ROLEALTER ROLE语句设置 - MD5 加密密码时,是否生成有关 MD5 密码已弃用的WARNING。 - 默认值为on。 - @@ -1031,7 +895,7 @@ include_dir 'conf.d' 设置服务器的Kerberos密钥文件的位置。 - 默认为FILE:/usr/local/pgsql/etc/krb5.keytab(其中目录部分是在构建时由sysconfdir指定的;用pg_config --sysconfdir来决定)。 + 默认为FILE:/usr/local/pgsql/etc/krb5.keytab(其中目录部分是在构建时由sysconfdir指定的;可用pg_config --sysconfdir来确定该目录)。 如果这个参数被设为空字符串,它将被忽略,并且系统依赖的默认值被应用。 这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 详情请参考。 @@ -1054,31 +918,50 @@ include_dir 'conf.d' - - gss_accept_delegation (boolean) + + db_user_namespace (boolean) - gss_accept_delegation配置参数 + db_user_namespace 配置参数 - 设置是否应接受来自客户端的 GSSAPI 代理。默认值为off, - 这表示不会接受客户端的凭据。将其改为on会使服务器接受 - 客户端代理给它的凭据。此参数只能在postgresql.conf文件 - 或服务器命令行中设置。 + 此参数启用各数据库独立的用户名。默认关闭。 + 此参数只能在postgresql.conf文件中或在服务器命令行上设置。 + + + + 如果启用此参数,你应以username@dbname的形式创建用户。 + 连接的客户端传入username时,会在用户名后附加@和数据库名, + 然后由服务器查找此数据库专属的用户名。请注意,在 SQL 环境中创建名称包含@的用户时,需要用引号括起用户名。 + + + + 启用此参数后,仍然可以创建普通的全局用户。只需在客户端指定用户名时附加@,例如joe@。 + 服务器查找用户名之前会去掉@。 + + + + db_user_namespace会使客户端和服务器的用户名表示形式不同。 + 认证检查始终使用服务器端的用户名,因此认证方法必须针对服务器端的用户名配置,而不是客户端的用户名。 + 由于md5在客户端和服务器上都使用用户名作为盐值,md5不能与db_user_namespace一起使用。 + + + + 此特性旨在作为找到完整解决方案之前的临时措施。届时将移除此选项。 + + - - SSL - 查看以获取有关设置SSL的更多信息。 + 关于 SSL 的设置,参见 @@ -1162,13 +1045,13 @@ include_dir 'conf.d' 这个目录需要用OpenSSL 命令 openssl rehashc_rehash来准备。 - 详情参阅相应文档 + 详情参阅相应文档。 - 当使用此设置时,在连接时会按需加载指定目录下的CRLs。 - 新的CRLs可以添加到该目录中,并可以立即使用。 - 这与不同,那个会导致文件中的CRL在服务器启动时间或重新加载配置时加载。 + 当使用此设置时,在连接时会按需加载指定目录下的CRL。 + 新的CRL可以添加到该目录中,并可以立即使用。 + 这与不同,那个会导致文件中的CRL在服务器启动时或重新加载配置时加载。 两个设置可以一起使用。 @@ -1189,23 +1072,6 @@ include_dir 'conf.d' - - ssl_tls13_ciphers (string) - - ssl_tls13_ciphers配置参数 - - - - - 指定允许用于 TLS 版本 1.3 连接的密码套件列表。可以使用冒号分隔的列表指定多个密码套件。 - 如果留空,将使用OpenSSL的默认密码套件集。 - - - 此参数只能在postgresql.conf文件或服务器命令行中设置。 - - - - ssl_ciphers (string) @@ -1216,11 +1082,12 @@ include_dir 'conf.d' - 指定允许用于 TLS 1.2 及更低版本连接的 SSL 密码套件列表; - 对于 TLS 1.3 连接,请参见 。 + 指定允许 SSL 连接使用的 SSL 密码套件列表。 该设置的语法及支持的值列表可参见 OpenSSL 包中的 ciphers 手册页。 - 默认值是HIGH:MEDIUM:+3DES:!aNULL。除非你有特定的安全需求,否则这个默认值通常是合理的选择。 + 只有使用 TLS 1.2 及更低版本的连接会受到影响。目前还没有控制 + TLS 1.3 连接所用密码选择的设置。默认值是 + HIGH:MEDIUM:+3DES:!aNULL。除非你有特定的安全需求,否则这个默认值通常是合理的选择。 @@ -1272,7 +1139,7 @@ include_dir 'conf.d' - 可用的密码组细节可能会随着OpenSSL 版本变化。 + 可用的密码套件细节可能会随着OpenSSL 版本变化。 可使用命令 openssl ciphers -v 'HIGH:MEDIUM:+3DES:!aNULL'来查看当前安装的OpenSSL版本的实际细节。 注意这个列表是根据服务器密钥类型在运行时过滤过的。 @@ -1287,47 +1154,27 @@ include_dir 'conf.d' - - 指定是否使用服务器的 SSL 密码首选项,而不是用客户端的。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 - 默认值是 on。 + 指定是否使用服务器的 SSL 密码套件优先顺序,而非客户端的优先顺序。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。默认值为 on - - 老的PostgreSQL版本没有这个设置并且总是使用客户端的首选项。这个设置主要用于与那些版本 - 的向后兼容性。使用服务器的首选项通常会更好,因为服务器更可能会被合适地配置。 + PostgreSQL 9.4 之前的版本没有此设置,始终采用客户端的优先顺序。此设置主要用于与这些旧版本保持向后兼容。采用服务器的优先顺序通常更好,因为服务器更可能得到适当配置。 - - - ssl_groups (string) + + ssl_ecdh_curve (string) - ssl_groups配置参数 + ssl_ecdh_curve 配置参数 - - - 指定在 ECDH 密钥交换中使用的曲线名称。它需要被所有连接的客户端支持。 - 可以使用冒号分隔的列表指定多个曲线。不必与服务器椭圆曲线密钥所使用的曲线相同。 - 该参数只能在postgresql.conf文件中或服务器命令行上设置。 - 默认值为X25519:prime256v1。 - - - OpenSSL最常见的曲线名称是: - prime256v1 (NIST P-256)、 - secp384r1 (NIST P-384)、 - secp521r1 (NIST P-521)。 - openssl ecparam -list_curves 命令可以显示可用曲线的完整列表, - 但并非所有曲线都可用于 TLS,而且许多受支持的组名和别名并未列出。 + 指定在 ECDH 密钥交换中使用的曲线名称。所有连接的客户端都必须支持该曲线。它不必与服务器椭圆曲线密钥使用的曲线相同。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。默认值为 prime256v1 - - 在 PostgreSQL 18.0 之前,这个设置名为 ssl_ecdh_curve, - 并且只接受单个值。 + OpenSSL 中最常见的曲线名称为:prime256v1(NIST P-256)、secp384r1(NIST P-384)、secp521r1(NIST P-521)。可以用 openssl ecparam -list_curves 命令显示可用曲线的完整列表,但其中并非所有曲线都能用于 TLS @@ -1340,19 +1187,14 @@ include_dir 'conf.d' - - 设置要使用的最小 SSL/TLS 协议版本。当前可用的版本包括:TLSv1TLSv1.1TLSv1.2TLSv1.3。 - 旧版本的 OpenSSL 库不支持所有值;如果选择了不支持的设置,将会引发错误。 - TLS 1.0 之前的协议版本,也就是 SSL 版本 2 和 3,总是被禁用的。 + 设置要使用的最低 SSL/TLS 协议版本。当前有效值为:TLSv1TLSv1.1TLSv1.2TLSv1.3。较旧版本的 OpenSSL 库不支持所有值;如果选择了不支持的设置,就会报错。TLS 1.0 之前的协议版本,即 SSL 2 和 3,始终被禁用。 - - 默认为TLSv1.2, 在本文撰写时的行业最佳实践。 + 默认值为 TLSv1.2,符合本文撰写时的行业最佳实践。 - - 这个参数只能在postgresql.conf文件中或通过服务器命令行进行设置。 + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 @@ -1365,15 +1207,11 @@ include_dir 'conf.d' - - 设定要使用的最大SSL/TLS协议版本。 - 有效的版本为 , 添加一个空字符串,允许任何协议版本。 - 默认为允许任何版本。设置最大协议版本主要用于测试,或者某个组件在与较新的协议配合工作时出现了问题。 + 设置要使用的最高 SSL/TLS 协议版本。有效值与 相同,此外还可设为空字符串,表示允许任意协议版本。默认允许任意版本。设置最高协议版本主要用于测试,或处理某些组件无法正常配合更新协议工作的问题。 - - 这个参数只能在postgresql.conf文件中或通过服务器命令行进行设置。 + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 @@ -1386,13 +1224,11 @@ include_dir 'conf.d' - - 指定含有用于SSL密码的所谓临时DH家族的Diffie-Hellman参数的文件名。默认值为空,这种情况下将使用内置的默认DH参数。使用自定义的DH参数可以降低攻击者破解众所周知的内置DH参数的风险。可以用命令openssl dhparam -out dhparams.pem 2048创建自己的DH参数文件。 + 指定包含 Diffie-Hellman 参数的文件名,这些参数用于所谓临时 DH 系列的 SSL 密码套件。默认值为空,此时使用编译时内置的默认 DH 参数。如果攻击者破解了众所周知的内置 DH 参数,使用自定义 DH 参数可以降低由此带来的风险。可以用命令 openssl dhparam -out dhparams.pem 2048 创建自己的 DH 参数文件。 - - 这个参数只能在postgresql.conf文件中或通过服务器命令行进行设置。 + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 @@ -1405,21 +1241,17 @@ include_dir 'conf.d' - - 设置当需要一个密码(例如一个私钥)来解密SSL文件时会调用的一个外部命令。默认情况下,这个参数为空,表示使用内置的提示机制。 + 设置获取用于解密私钥等 SSL 文件的口令时要调用的外部命令。默认值为空,表示使用内置的提示机制。 - - 该命令必须将密码打印到标准输出并且以代码0退出。在该参数值中,%p被替换为一个提示字符串(要得到文字%,应该写成%%)。注意该提示字符串将可能含有空格,因此要确保加上适当的引号。如果输出的末尾有单一的新行,它会被剥离掉。 + 该命令必须将口令输出到标准输出,并以退出码 0 结束。参数值中的 %p 会被替换为提示字符串。(要表示字面值 %,应写成 %%。)提示字符串可能包含空白,因此务必正确加引号。如果输出末尾有一个换行符,会将其去掉。 - - 该命令实际上并不一定要提示用户输入一个密码。它可以从文件中读取密码、从钥匙链得到密码等等。确保选中的机制足够安全是用户的责任。 + 该命令不一定要提示用户输入口令,也可以从文件读取口令、从钥匙链获取口令等。用户应自行确保所选机制足够安全。 - - 这个参数只能在postgresql.conf文件中或通过服务器命令行进行设置。 + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 @@ -1432,20 +1264,14 @@ include_dir 'conf.d' - - 这个参数决定在配置重载期间如果一个密钥文件需要密码时,是否也调用ssl_passphrase_command设置的密码命令。 - 如果这个参数为off(默认),那么在重载期间将忽略ssl_passphrase_command,如果在此期间需要密码则SSL配置将不会被重载。 - 对于要求一个TTY(当服务器正在运行时可能是不可用的)来进行提示的命令,这种设置是合适的。 - 例如,如果密码是从一个文件中得到的,将这个参数设置为on可能是合适的。 + 此参数决定:配置重载期间,如果密钥文件需要口令,是否也调用 ssl_passphrase_command 设置的口令命令。如果此参数为 off(默认值),则重载时会忽略 ssl_passphrase_command,如果需要口令,就不会重载 SSL 配置。此设置适合需要通过 TTY 提示用户的命令,因为服务器运行期间可能无法使用 TTY。例如,如果从文件中获取口令,则适合将此参数设为 on。 - 在Windows上运行时,必须将该参数设为on, - 因为该平台采用不同的进程模型,所有连接都会触发配置重载。 + 在 Windows 上运行时,必须将此参数设为 on,因为该平台的进程模型不同,每个连接都会执行配置重载。 - - 这个参数只能在postgresql.conf文件中或通过服务器命令行进行设置。 + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 @@ -1470,22 +1296,15 @@ include_dir 'conf.d' - - 设置数据库服务器将使用的共享内存缓冲区量。默认通常是 128 兆字节(128MB),但是如果你的内核设置不支持(在initdb时决定),那么可以会更少。 - 这个设置必须至少为 128 千字节。不过为了更好的性能,通常会使用明显高于最小值的设置。 - 如果指定值时没有单位,则以块为单位,即BLCKSZ字节,通常为8kB.(BLCKSZ 的非默认值改变最小值。) - 此参数只能在服务器启动时设置。 + 设置数据库服务器用于共享内存缓冲区的内存量。默认值通常为 128 兆字节(128MB),但如果内核设置不支持,则可能更小(在 initdb 期间确定)。此设置必须至少为 128 千字节。不过,要获得良好性能,通常需要远高于该最小值的设置。如果指定值时没有单位,则以块为单位,即 BLCKSZ 字节,通常为 8kB。(BLCKSZ 的非默认值会改变该最小值。)此参数只能在服务器启动时设置。 - - 如果有一个专用的 1GB 或更多内存的数据库服务器,一个合理的shared_buffers开始值是系统内存的 25%。即使更大的shared_buffers有效,也会造成一些工作负载, 但因为PostgreSQL同样依赖操作系统的高速缓冲区,将shared_buffers设置为超过 40% 的RAM不太可能比一个小点值工作得更好。为了能把对写大量新的或改变的数据的处理分布在一个较长的时间段内,shared_buffers更大的设置通常要求对max_wal_size也做相应增加。 + 如果专用数据库服务器具有 1GB 或更多内存,shared_buffers 的合理初始值是系统内存的 25%。对于某些工作负载,将 shared_buffers 设得更大也有效,但由于 PostgreSQL 同时依赖操作系统缓存,将超过 40% 的内存分配给 shared_buffers 不太可能比更小的值效果更好。将 shared_buffers 设得更大时,通常还需要相应增加 max_wal_size,以便将大量新数据或已修改数据的写入过程分散到更长的时间内。 - - 如果系统内存小于 1GB,一个较小的 RAM 百分数是合适的,这样可以为操作系统留下足够的空间。 + 对于内存少于 1GB 的系统,适合使用更小的内存比例,以便为操作系统留出足够空间。 - @@ -1508,19 +1327,19 @@ include_dir 'conf.d' - 巨型页面的使用会导致更小的页面表以及花费在内存管理上的 CPU 时间更少,从而提高性能。更多有关Linux上使用巨型页面的细节请见。 + 巨型页的使用会导致更小的页表以及花费在内存管理上的 CPU 时间更少,从而提高性能。更多有关Linux上使用巨型页的细节请见 巨型页在Windows上被称为大页面。 要使用大页面,需要为运行PostgreSQL的Windows用户账号分配在内存中锁定页面的用户权限。 可以使用Windows的组策略工具(gpedit.msc)来分配用户权限在内存中锁定页面。 - 为了在命令窗口以单进程(而不是Windows服务)的方式启动数据库服务器,命令窗口必须以管理员身份运行或者禁用用户访问控制(UAC)。 + 为了在命令窗口以独立进程(而不是Windows服务)的方式启动数据库服务器,命令窗口必须以管理员身份运行或者禁用用户访问控制(UAC)。 当UAC被启用时,普通的命令窗口会在启动时收回用户权限在内存中锁定页面 - 注意这种设置仅影响主共享内存区域。Linux、FreeBSD以及Illumos之类的操作系统也能为普通内存分配自动使用巨型页(也被称为超级页或者页面),而不需要来自PostgreSQL的显式请求。在Linux上,这被称为transparent huge pagestransparent huge pages(THP,透明巨型页)。已知这种特性对某些Linux版本上的某些用户会导致PostgreSQL的性能退化,因此当前并不鼓励使用它(与huge_pages的显式使用不同)。 + 注意这种设置仅影响主共享内存区域。Linux、FreeBSD以及Illumos之类的操作系统也能为普通内存分配自动使用巨型页(也被称为超级页或者页面),而不需要来自PostgreSQL的显式请求。在Linux上,这被称为transparent huge pages透明巨型页(THP,透明巨型页)。已知这种特性对某些Linux版本上的某些用户会导致PostgreSQL的性能退化,因此当前并不鼓励使用它(与huge_pages的显式使用不同)。 @@ -1533,24 +1352,14 @@ include_dir 'conf.d' - - 控制巨型页的大小,当他们通过时。 - 默认为零 (0)。 - 当设置为0时,将使用系统默认的巨型页大小。 - 这个参数只能在服务器启动时设置。 + 控制通过 启用巨型页时所使用的页大小。默认值为零(0)。设置为 0 时,使用系统默认的巨型页大小。此参数只能在服务器启动时设置。 - - 一些现代64位服务器体系结构上常用的有效页尺寸包括: - 2MB1GB (Intel and AMD), - 16MB16GB (IBM POWER), - 还有 64kB, 2MB,32MB1GB (ARM). - 关于使用和支持的更多信息,参见。 + 现代 64 位服务器体系结构上常见的页大小包括:2MB1GB(Intel 和 AMD),16MB16GB(IBM POWER),以及 64kB2MB32MB1GB(ARM)。关于使用和支持的更多信息,参见 - - 非默认设置当前仅在Linux上支持。 + 目前只有 Linux 支持非默认设置。 @@ -1563,16 +1372,11 @@ include_dir 'conf.d' - - 为每个数据库会话设置用于临时缓冲区的最大内存。这些缓冲区是仅用于访问临时表的会话本地缓冲区。 - 如果指定值时没有单位,则以块为单位,即BLCKSZ字节,通常为8kB。 - 默认为 8 兆字节(8MB)。(如果BLCKSZ不是 8 kB,则默认值按比例缩放。) - 这个设置可以在独立的会话内部被改变,但是只有在会话第一次使用临时表之前才能改变; 在会话中随后企图改变该值是无效的。 + 设置每个数据库会话用于临时缓冲区的最大内存量。这些是会话本地的缓冲区,仅用于访问临时表。如果指定值时没有单位,则以块为单位,即 BLCKSZ 字节,通常为 8kB。默认值为 8 兆字节(8MB)。(如果 BLCKSZ 不是 8kB,则默认值按比例变化。)可以在单个会话内更改此设置,但必须在该会话首次使用临时表之前更改;此后尝试更改该值,对该会话不会产生影响。 - - 一个会话将按照temp_buffers给出的限制根据需要分配临时缓冲区。如果在一个并不需要大量临时缓冲区的会话里设置一个大的数值, 其开销只是一个缓冲区描述符,或者说temp_buffers每增加一则增加大概 64 字节。不过,如果一个缓冲区被实际使用,那么它就会额外消耗 8192 字节(或者BLCKSZ字节)。 + 会话会按需分配临时缓冲区,上限为 temp_buffers。对于实际不需要很多临时缓冲区的会话,将此参数设得较大时,开销仅为 temp_buffers 每增加一就多分配一个缓冲区描述符,约为 64 字节。不过,如果实际使用了某个缓冲区,还会为它额外消耗 8192 字节(一般而言为 BLCKSZ 字节)。 @@ -1585,18 +1389,14 @@ include_dir 'conf.d' - - 设置可以同时处于prepared状态的事务的最大数目(见)。把这个参数设置 为零(这是默认设置)将禁用预备事务特性。这个参数只能在服务器启动时设置。 + 设置可同时处于预备状态的事务的最大数量(见 )。将此参数设为零(默认值)会禁用预备事务功能。此参数只能在服务器启动时设置。 - - 如果你不打算使用预备事务,可以把这个参数设置为零来防止意外创建预备事务。如果你正在使用预备事务,你将希望把max_prepared_transactions至少设置为一样大,因此每一个会话可以有一个预备事务待处理。 + 如果不打算使用预备事务,应将此参数设为零,以防意外创建预备事务。如果使用预备事务,通常应将 max_prepared_transactions 设为不小于 的值,以便每个会话都能有一个待处理的预备事务。 - - 当运行一个备库时,你必须设置这个参数等于或大于主库上的参数。 - 否则,备库上可能无法允许查询。 + 运行备库时,必须将此参数设为与主库相同或更大的值。否则,备库上将不允许执行查询。 @@ -1609,23 +1409,11 @@ include_dir 'conf.d' - - 设置查询操作(如排序或哈希表)在写入临时磁盘文件之前可使用的基本最大内存量。 - 如果未指定单位,则将其视为千字节。默认值为四兆字节(4MB)。 - 请注意,复杂查询可能同时执行多个排序和哈希操作, - 每个操作通常允许在开始将数据写入临时文件之前使用此值指定的内存量。 - 此外,可能有多个正在运行的会话同时执行此类操作。 - 因此,使用的总内存量可能是work_mem值的多倍; - 在选择值时必须牢记这一事实。排序操作用于ORDER BYDISTINCT和合并连接。 - 哈希表用于哈希连接、基于哈希的聚合、记忆节点和IN子查询的基于哈希的处理。 + 设置查询操作(如排序或哈希表)在写入临时磁盘文件之前可使用的基础最大内存量。如果未指定单位,则以千字节为单位。默认值为 4 兆字节(4MB)。请注意,复杂查询可能同时执行多个排序和哈希操作,每个操作在开始向临时文件写入数据之前,通常都可以使用此值指定的内存量。此外,多个正在运行的会话也可能并发执行此类操作。因此,使用的总内存量可能是 work_mem 值的数倍;选择此值时必须考虑这一点。排序操作用于 ORDER BYDISTINCT 和归并连接。哈希表用于哈希连接、基于哈希的聚合、Memoize 节点以及基于哈希的 IN 子查询处理。 - - 基于哈希的操作通常比等效的基于排序的操作更加敏感于内存可用性。 - 哈希表的可用内存通过将work_mem乘以 - hash_mem_multiplier来计算。默认值为 - 1.0,这使得基于哈希的操作受到与基于排序的操作相同的简单work_mem最大值的限制。 + 与等效的排序操作相比,基于哈希的操作通常对可用内存更敏感。哈希表的内存上限由 work_mem 乘以 hash_mem_multiplier 计算得到。因此,基于哈希的操作可以使用超过通常的 work_mem 基础量的内存。 @@ -1638,17 +1426,11 @@ include_dir 'conf.d' - - 用于计算哈希操作可以使用的最大内存量。最终限制由将work_mem乘以hash_mem_multiplier确定。 - 默认值为1.0,这使得基于哈希的操作与基于排序的操作受到相同的work_mem简单最大值的限制。 + 用于计算基于哈希的操作可以使用的最大内存量。最终上限由 work_mem 乘以 hash_mem_multiplier 确定。默认值为 1.0,此时基于哈希的操作与基于排序的操作一样,都受到 work_mem 这一简单上限的限制。 - - 考虑在查询操作频繁溢出的环境中增加hash_mem_multiplier, - 特别是当简单增加work_mem导致内存压力时(内存压力通常表现为间歇性的内存不足错误)。 - 将设置调到1.5或2.0通常在混合工作负载中有效。在已将work_mem增加到40MB或更高的环境中, - 可以考虑将设置调高至2.0-8.0或更高。 + 如果查询操作经常溢写磁盘,可以考虑增加 hash_mem_multiplier,尤其是在单纯增加 work_mem 会导致内存压力的情况下(内存压力通常表现为间歇性的内存不足错误)。对于混合工作负载,设为 1.5 或 2.0 可能有效。如果 work_mem 已增加到 40MB 或更高,则将该值进一步设为 2.0 - 8.0 或更高可能有效。 @@ -1661,19 +1443,14 @@ include_dir 'conf.d' - - 指定维护操作(如 VACUUMCREATE INDEX 和 - ALTER TABLE ADD FOREIGN KEY)可使用的最大内存量。 - 如果指定值时未带单位,则按千字节解释。默认值为 64 兆字节(64MB)。 - 由于数据库会话一次只能执行一个这样的操作,而一个安装通常也不会有很多此类操作并发运行, - 因此把该值设置得明显大于 work_mem 通常是安全的。更大的设置可能改善清理和恢复数据库转储的性能。 + 指定维护操作(如 VACUUMCREATE INDEXALTER TABLE ADD FOREIGN KEY)可使用的最大内存量。如果未指定单位,则以千字节为单位。默认值为 64 兆字节(64MB)。由于一个数据库会话一次只能执行一个此类操作,而一个数据库系统通常也不会并发运行很多此类操作,因此可以安全地将该值设得远大于 work_mem。更大的设置可能改善清理和恢复数据库转储的性能。 + + + 注意,自动清理运行时,最多可能分配此内存量的 倍,因此不要将默认值设得过高。单独设置 可能有助于控制这一点。 - - 注意当自动清理运行时,可能会分配最多达这个内存的倍,因此要小心不要把该默认值设置得太高。 - 通过独立地设置可能会对控制这种情况 - 有所帮助。 + 注意,在收集死元组标识符时,VACUUM 最多只能使用 1GB 内存。 @@ -1686,15 +1463,13 @@ include_dir 'conf.d' - - 指定每个自动清理工作者进程能使用的最大内存量。 - 如果指定值时没有单位,则以千字节为单位。 - 其默认值为 -1,表示转而使用 的值。 - 当运行在其他上下文环境中时,这个设置对VACUUM的行为没有影响。 - 这个参数只能在postgresql.conf中或者服务器命令行上设置。 + 指定每个自动清理工作进程可使用的最大内存量。如果未指定单位,则以千字节为单位。默认值为 -1,表示改用 的值。该设置不影响其他上下文中运行的 VACUUM 的行为。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 - + + 在收集死元组标识符时,自动清理最多只能使用 1GB 内存,因此将 autovacuum_work_mem 设得更高,不会影响自动清理扫描表时能收集的死元组数量。 + + @@ -1705,205 +1480,88 @@ include_dir 'conf.d' - - 指定逻辑解码要使用的最大内存量,在将某些解码的更改写入本地磁盘之前。 - 这将限制逻辑流复制连接使用的内存量。它默认为 64 兆字节(64MB)。 - 由于每个复制连接仅使用此大小的单个缓冲区,并且安装通常不会同时具有多个此类连接(受 max_wal_senders 的限制),因此将此值设置得明显高于 work_mem是安全的,从而减少写入磁盘的解码更改数量。 + 指定逻辑解码在将部分已解码的更改写入本地磁盘之前可使用的最大内存量。它限制了流式逻辑复制连接使用的内存量。默认值为 64 兆字节(64MB)。由于每个复制连接仅使用一个此大小的缓冲区,而一个数据库系统通常不会同时有很多此类连接(受 max_wal_senders 限制),因此可以安全地将该值设得远高于 work_mem,以减少写入磁盘的已解码更改数量。 - + - - commit_timestamp_buffers (integer) + + + + + + + + + + + + + + + + + max_stack_depth (integer) - commit_timestamp_buffers配置参数 + max_stack_depth配置参数 + - 指定用于缓存pg_commit_ts内容的内存量 - (参见)。如果未指定单位,则视为块, - 即BLCKSZ字节,通常为 8KB。默认值为0, - 这会请求shared_buffers/512,最多 1024 个块、最少 16 个块。 - 此参数只能在服务器启动时设置。 + 指定服务器执行栈的最大安全深度。此参数的理想设置是由内核强制执行的实际栈大小限制 + (如由ulimit -s或本地等效设置),减去大约一兆字节的安全余量。 + 需要安全余量是因为服务器中并非每个例程都检查栈深度,而只在关键的潜在递归例程中检查。 + 如果未指定单位,则将其视为千字节。默认设置为两兆字节(2MB), + 这是保守且不太可能引起崩溃的小值。但是,这可能太小,无法执行复杂函数。 + 只有超级用户才能更改此设置。 + + + + 把max_stack_depth参数设置得高于实际的内核限制将意味着一个失控的递归函数可能会导致一个独立的后端进程崩溃。 在PostgreSQL能够检测内核限制的平台上, 服务器将不允许把这个参数设置为一个不安全的值。不过,并非所有平台都能提供该信息,所以我们还是建议你在选择值时要小心。 - - multixact_member_buffers (integer) + + + shared_memory_type (enum) - multixact_member_buffers配置参数 + shared_memory_type 配置参数 - 指定用于缓存pg_multixact/members内容的共享内存量 - (参见)。如果未指定单位,则视为块, - 即BLCKSZ字节,通常为 8KB。默认值为 32。此参数只能在服务器启动时设置。 + 指定服务器用于主共享内存区域的共享内存实现,该区域存放 PostgreSQL 的共享缓冲区及其他共享数据。可选值为 mmap(使用 mmap 分配的匿名共享内存)、sysv(通过 shmget 分配的 System V 共享内存)和 windows(Windows 共享内存)。并非所有平台都支持所有值;第一个受支持的选项是该平台的默认值。sysv 不是任何平台的默认选项,通常不建议使用,因为它一般需要更改内核的默认设置才能分配大量内存(见 )。此参数只能在服务器启动时设置。 - - multixact_offset_buffers (integer) + + + dynamic_shared_memory_type (enum) - multixact_offset_buffers配置参数 + dynamic_shared_memory_type配置参数 - 指定用于缓存pg_multixact/offsets内容的共享内存量 - (参见)。如果未指定单位,则视为块, - 即BLCKSZ字节,通常为 8KB。默认值为 16。此参数只能在服务器启动时设置。 + 指定服务器应使用的动态共享内存实现。可选值为 posix(使用 shm_open 分配的 POSIX 共享内存)、sysv(通过 shmget 分配的 System V 共享内存)、windows(Windows 共享内存)、mmap(使用存放在数据目录中的内存映射文件模拟共享内存)。并非所有平台都支持所有值;第一个受支持的选项是该平台的默认值。mmap 不是任何平台的默认选项,通常不建议使用,因为操作系统可能会反复将修改过的页面写回磁盘,增加系统 I/O 负载;不过,在调试、将 pg_dynshmem 目录存放在 RAM 磁盘上,或其他共享内存设施不可用时,它可能有用。此参数只能在服务器启动时设置。 - - notify_buffers (integer) + + + min_dynamic_shared_memory (integer) - notify_buffers配置参数 + min_dynamic_shared_memory 配置参数 - 指定用于缓存pg_notify内容的共享内存量 - (参见)。如果未指定单位,则视为块, - 即BLCKSZ字节,通常为 8KB。默认值为 16。此参数只能在服务器启动时设置。 - - - - - - serializable_buffers (integer) - - serializable_buffers配置参数 - - - - - 指定用于缓存pg_serial内容的共享内存量 - (参见)。如果未指定单位,则视为块, - 即BLCKSZ字节,通常为 8KB。默认值为 32。此参数只能在服务器启动时设置。 - - - - - - subtransaction_buffers (integer) - - subtransaction_buffers配置参数 - - - - - 指定用于缓存pg_subtrans内容的共享内存量 - (参见)。如果未指定单位,则视为块, - 即BLCKSZ字节,通常为 8KB。默认值为0, - 这会请求shared_buffers/512,最多 1024 个块、最少 16 个块。 - 此参数只能在服务器启动时设置。 - - - - - - transaction_buffers (integer) - - transaction_buffers配置参数 - - - - - 指定用于缓存pg_xact内容的共享内存量 - (参见)。如果未指定单位,则视为块, - 即BLCKSZ字节,通常为 8KB。默认值为0, - 这会请求shared_buffers/512,最多 1024 个块、最少 16 个块。 - 此参数只能在服务器启动时设置。 - - - - - - - max_stack_depth (integer) - - max_stack_depth配置参数 - - - - - - 指定服务器执行栈的最大安全深度。此参数的理想设置是由内核强制执行的实际栈大小限制 - (如由ulimit -s或本地等效设置),减去大约一兆字节的安全边界。 - 需要安全边界是因为服务器中并非每个例程都检查栈深度,而只在关键的潜在递归例程中检查。 - 如果未指定单位,则将其视为千字节。默认设置为两兆字节(2MB), - 这是保守且不太可能引起崩溃的小值。但是,这可能太小,无法执行复杂函数。 - 只有超级用户能更改这个设置。 - - - - 把max_stack_depth参数设置得高于实际的内核限制将意味着一个失控的递归函数可能会导致一个独立的后端进程崩溃。 在PostgreSQL能够检测内核限制的平台上, 服务器将不允许把这个参数设置为一个不安全的值。不过,并非所有平台都能提供该信息,所以我们还是建议你在选择值时要小心。 - - - - - - - shared_memory_type (enum) - - shared_memory_type 配置参数 - - - - - - 指定服务器应用于主共享内存区域的共享内存实现,包括 PostgreSQL 的共享缓冲区和其他共享数据。 - 可能的值为 mmap(对使用 mmap 分配的匿名共享内存)、sysv(通过 shmget 分配的 System V 共享内存)和 windows(Windows 共享内存)。 - 并非在所有平台上都支持全部值;第一个受支持的选项是该平台的默认选项。 - sysv 选项不是任何平台的默认选项,通常不建议使用,因为它通常需要非默认的内核设置来允许大量的地址分配(参见 )。 - - - - - - - dynamic_shared_memory_type (enum) - - dynamic_shared_memory_type配置参数 - - - - - - 指定服务器应该使用的动态共享内存实现。可能的值包括posix(使用shm_open分配的POSIX共享内存), - sysv(通过shmget分配的System V共享内存), - windows(用于Windows共享内存), - 和mmap(使用存储在数据目录中的内存映射文件模拟共享内存)。 - 并非所有平台都支持所有值;通常第一个支持的选项是该平台的默认值。 - 通常不建议使用mmap选项,因为操作系统可能会反复将修改的页面写回磁盘,增加系统I/O负载; - 但在调试时,当pg_dynshmem目录存储在RAM磁盘上,或者其他共享内存设施不可用时,可能会有用。 - 该参数只能在服务器启动时设置。 - - - - - - - min_dynamic_shared_memory (integer) - - min_dynamic_shared_memory 配置参数 - - - - - - 指定在服务器启动时将要分配给并行查询使用的内存容量。 - 当此内存区域不够用或被并发查询耗尽时,新的并行查询尝试使用dynamic_shared_memory_type配置的方法从操作系统临时分配额外的共享内存,由于内存管理开销该方法可能慢一些。 - 在启动时由min_dynamic_shared_memory分配的内存受到操作系统上所支持的huge_pages设置的影响,并且在自动管理的操作系统上更可能从较大的页面中受益。 - 默认值是0(无)。 - 该参数只能在服务器启动时设置。 + 指定服务器启动时为并行查询分配的内存量。当此内存区域不足或被并发查询耗尽时,新的并行查询会尝试使用 dynamic_shared_memory_type 配置的方法,临时向操作系统分配额外的共享内存;由于内存管理开销,这可能较慢。在支持 huge_pages 设置的操作系统上,启动时通过 min_dynamic_shared_memory 分配的内存会受到该设置的影响;在自动管理巨型页的操作系统上,这些内存也可能更容易受益于较大的页。默认值为 0(不分配)。此参数只能在服务器启动时设置。 @@ -1924,17 +1582,11 @@ include_dir 'conf.d' - - 指定进程可以用于临时文件(如排序和哈希临时文件)或保留游标的存储文件的最大磁盘空间。 - 尝试超过此限制的事务将被取消。 - 如果未指定单位,则将其视为千字节。 - -1(默认值)表示没有限制。 - 只有超级用户能更改这个设置。 + 指定一个进程可用于临时文件的最大磁盘空间,例如排序和哈希临时文件,或保留游标的存储文件。尝试超过此限制的事务将被取消。如果未指定单位,则以千字节为单位。-1(默认值)表示没有限制。只有超级用户才能更改此设置。 - - 这个设置约束着一个给定PostgreSQL进程在任何瞬间所使用的所有临时文件的总空间。应该注意的是,与在查询执行中在幕后使用的临时文件相反,显式临时表所用的磁盘空间被这个设置所限制。 + 此设置限制单个 PostgreSQL 进程在任意时刻使用的所有临时文件的总空间。需要注意,显式临时表所用的磁盘空间计入该上限;计入的是查询执行过程中内部使用的临时文件。 @@ -1955,35 +1607,31 @@ include_dir 'conf.d' - - - 设置每个服务器子进程允许同时打开的最大文件数。默认值是一千个文件。 - - 如果内核强制实施了安全的每进程上限,你通常不必担心这个设置。但在某些平台上 - (尤其是大多数 BSD 系统),如果许多进程都尝试打开大量文件,内核可能允许单个进程打开的文件数 - 远超系统在整体上真正能够支持的数量。如果你看到打开的文件过多之类的失败, - 可以尝试减小这个设置。这个参数只能在服务器启动时设置。 + 设置每个服务器子进程允许同时打开的最大文件数量。默认值为一千个文件。如果内核强制实施了安全的每进程上限,就不必担心此设置。但在某些平台上(尤其是大多数 BSD 系统),内核允许单个进程打开的文件数量很大,如果很多进程都尝试打开这么多文件,就会远超系统实际能够支持的总量。如果遇到 Too many open files(打开的文件过多)错误,可尝试减小此设置。此参数只能在服务器启动时设置。 - + 基于代价的清理延迟 - 在命令的执行过程中,系统维持着一个内部计数器来跟踪各种被执行的I/O操作的估算开销。当累计的代价达到一个限制(由vacuum_cost_limit指定),执行这些操作的进程将按照vacuum_cost_delay所指定的休眠一小段时间。然后它将重置计数器并继续执行。 + 执行 命令期间,系统维护一个内部计数器,记录已执行的各种 I/O 操作的估算代价。 + 当累计代价达到上限(由 vacuum_cost_limit 指定)时,执行该操作的进程会休眠一小段时间,时长由 vacuum_cost_delay 指定。 + 随后重置计数器并继续执行。 - 这个特性的出发点是允许管理员降低这些命令对并发的数据库活动产生的I/O影响。在很多情况下,VACUUMANALYZE等维护命令能否快速完成并不重要,而非常重要的是这些命令不会对系统执行其他数据库操作的能力产生显著的影响。基于代价的清理延迟提供了一种方式让管理员能够保证这一点。 + 此功能让管理员能够降低这些命令对并发数据库活动的 I/O 影响。在许多情况下,VACUUMANALYZE 等维护命令是否快速完成并不重要, + 但避免它们显著干扰系统执行其他数据库操作的能力通常很重要。基于代价的清理延迟为管理员提供了实现这一点的方法。 - 对于手动发出的VACUUM命令,该特性默认被禁用。要启用它,只要把vacuum_cost_delay变量设为一个非零值。 + 对于手动执行的 VACUUM 命令,此功能默认禁用。要启用它,将 vacuum_cost_delay 变量设为非零值。 @@ -1995,19 +1643,13 @@ include_dir 'conf.d' - - - 当超出开销限制时进程将要休眠的时间量。如果指定值时没有单位,则以毫秒为单位。 - 其默认值为0,这将禁用基于代价的清理延迟特性。正值将启用基于代价的清理。 - - - - 在使用基于代价的清理时,vacuum_cost_delay的合适值通常很小,也许是小于1毫秒。 - 虽然vacuum_cost_delay可以被设置为毫秒级别的值,但是在较老的平台上可能无法准确地测量这种延迟。 - 在这样的平台上,增加 VACUUM的节流资源消耗在1ms以上,需要改变其他的清理开销参数。 - 尽管如此,你应该保持 vacuum_cost_delay 在平台能持续测量的情况下尽可能小;大延迟没有帮助。 - - + + 超过代价上限后,进程将休眠的时长。如果未指定单位,则以毫秒为单位。默认值为 0,表示禁用基于代价的清理延迟功能。正值会启用基于代价的清理。 + + + 使用基于代价的清理时,vacuum_cost_delay 的合适值通常很小,可能不到 1 毫秒。虽然 vacuum_cost_delay 可以设为以毫秒为单位的小数值,但较旧的平台可能无法准确计量这种延迟。在这些平台上,若要让 VACUUM 的资源用量超过延迟设为 1ms 时的水平,需要调整其他清理代价参数。尽管如此,仍应将 vacuum_cost_delay 设为平台能够稳定计量的尽可能小的值;较大的延迟没有帮助。 + + @@ -2018,11 +1660,10 @@ include_dir 'conf.d' - - - 清理一个在共享缓存中找到的缓冲区的估计代价。它表示锁住缓冲池、查找共享哈希表和扫描页内容的代价。默认值为1。 - - + + 清理在共享缓冲区缓存中找到的缓冲区时所计入的估算代价。它表示锁定缓冲池、查找共享哈希表和扫描页内容的代价。默认值为 1。 + + @@ -2033,13 +1674,10 @@ include_dir 'conf.d' - - - 清理一个必须从磁盘上读取的缓冲区的代价。 - 它表示锁住缓冲池、查找共享哈希表、从磁盘读取需要的块以及扫描其内容的代价。 - 默认值为2。 - - + + 清理必须从磁盘读取的缓冲区时所计入的估算代价。它表示锁定缓冲池、查找共享哈希表、从磁盘读取所需数据块并扫描其内容所需的工作量。默认值为 2。 + + @@ -2050,11 +1688,10 @@ include_dir 'conf.d' - - - 当清理修改一个之前干净的块时需要花费的估计代价。它表示再次把脏块刷出到磁盘所需要的额外I/O。默认值为20。 - - + + 清理操作修改原本干净的数据块时所计入的估算代价。它表示再次将脏块刷盘所需的额外 I/O。默认值为 20。 + + @@ -2065,33 +1702,31 @@ include_dir 'conf.d' - - - 将导致清理进程休眠的累计代价。默认值为200。 - - + + 会使清理进程休眠的累计代价。默认值为 200。 + + - - 有些操作会保持关键性的锁,这样可以尽快完成。基于代价的清理延迟在这类操作期间不会发生。因此有可能代价会累计至大大超过指定的限制。为了防止在这种情况下的无意义的长时间延迟,实际延迟的计算方式是vacuum_cost_delay * - accumulated_balance / - vacuum_cost_limit,且最大值是vacuum_cost_delay * 4。 + 某些操作持有关键的锁,因此应尽快完成。这些操作期间不会发生基于代价的清理延迟,所以累计代价可能远超指定上限。 + 为避免此时出现无益的长时间延迟,实际延迟按 vacuum_cost_delay * accumulated_balance / vacuum_cost_limit 计算, + 但最大不超过 vacuum_cost_delay * 4。 - 后台写入器 - 有一个独立的服务器进程,叫做后台写入器,它的功能就是发出写(新的或修改过的)共享缓冲区的命令。 - 当干净的共享缓存数量出现不足时,后台写入器写入一些脏缓存到文件系统,并标记为干净。 - 不过,后台写入器确实会增加 I/O 的总负荷,因为虽然在每个检查点间隔中一个重复弄脏的页面可能只会写出一次,但在同一个间隔中后台写入器可能会把它写出好几次。 - 在这一小节讨论的参数可以被用于调节本地需求的行为。 + 有一个独立的服务器进程,称为后台写入器,负责写出(新的或修改过的)共享缓冲区。 + 当干净的共享缓冲区数量似乎不足时,后台写入器会将一些脏缓冲区写入文件系统,并将其标记为干净。 + 这可以降低处理用户查询的服务器进程找不到干净缓冲区、因而不得不自行写出脏缓冲区的可能性。 + 不过,后台写入器确实会使总体 I/O 负载有所增加:反复变脏的页面原本可能在每个检查点间隔中只写出一次, + 而后台写入器可能在同一间隔内随着它变脏而多次写出。本节参数可用于根据实际需求调整此行为。 @@ -2103,13 +1738,10 @@ include_dir 'conf.d' - - - 指定后台写入器活动轮次之间的延迟。在每个轮次中,写入器都会为一定数量的脏缓冲区发出写操作(可以用下面的参数控制)。 - 然后它就休眠 bgwriter_delay的时长, 然后重复动作。当缓冲池中没有脏缓冲区时,不管 bgwriter_delay,它都会进入更长的休眠。如果指定值时没有单位,则以毫秒为单位。默认值是 200 毫秒(200ms)。 - 注意在许多系统上,休眠延迟的有效解析度是 10 毫秒;因此,为bgwriter_delay设置一个 不是 10 的倍数的值与把它设置为下一个更高的 10 的倍数是一样的效果。这个选项只能在服务器命令行上或者在postgresql.conf文件中设置。 - - + + 指定后台写入器各轮活动之间的延迟。每一轮中,写入器会对一定数量的脏缓冲区发出写操作(由下面的参数控制),然后休眠 bgwriter_delay 指定的时长,再重复此过程。不过,当缓冲池中没有脏缓冲区时,它会进入更长的休眠,而不受 bgwriter_delay 限制。如果未指定单位,则以毫秒为单位。默认值为 200 毫秒(200ms)。注意,在许多系统上,休眠延迟的有效分辨率为 10 毫秒;将 bgwriter_delay 设为不是 10 的倍数的值,可能与将它设为下一个更大的 10 的倍数效果相同。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 + + @@ -2120,11 +1752,10 @@ include_dir 'conf.d' - - - 在每个轮次中,不超过这么多个缓冲区将被后台写入器写出。把这个参数设置为零可禁用后台写出(注意被一个独立、专用辅助进程管理的检查点不受影响)。默认值是 100 个缓冲区。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 - - + + 后台写入器每轮写出的缓冲区数量不会超过此值。设为零会禁用后台写入。(由另一个独立的专用辅助进程管理的检查点不受影响。)默认值为 100 个缓冲区。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 + + @@ -2135,11 +1766,10 @@ include_dir 'conf.d' - - - 每一轮次要写的脏缓冲区的数目基于最近几个轮次中服务器进程需要的新缓冲区的数目。 最近所需的平均值乘以bgwriter_lru_multiplier可以估算下一轮次中将会需要的缓冲区数目。脏缓冲区将被写出直到有很多干净可重用的缓冲区(然而,每一轮次中写出的缓冲区数不超过bgwriter_lru_maxpages)。 因此,设置为 1.0 表示一种刚刚好的策略,这种策略会写出正好符合预测值的数目的缓冲区。 更大大的值可以为需求高峰提供某种缓冲,而更小的值则需要服务进程来处理一些写出操作。默认值是 2.0。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 - - + + 每轮写出的脏缓冲区数量取决于最近几轮服务器进程所需的新缓冲区数量。将近期平均需求乘以 bgwriter_lru_multiplier,即可估算下一轮所需的缓冲区数量。写入器会写出脏缓冲区,直到可用的干净且可重用缓冲区达到这一数量。(不过,每轮写出的缓冲区数量不会超过 bgwriter_lru_maxpages。)因此,设为 1.0 表示采用恰好及时策略,写出的缓冲区数量恰好等于预测需求量。更大的值可为需求突增留出余量,而更小的值则有意将部分写操作留给服务器进程执行。默认值为 2.0。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 + + @@ -2150,25 +1780,21 @@ include_dir 'conf.d' - - - 只要后台写入的数据超过这个数量,尝试强制 OS 把这些写发送到底层存储上。这样做将限制内核页缓存中脏数据的量,降低了在检查点末尾发出一个 fsync 时或者 OS 在后台大批量写回数据时卡住的可能性。 - 那常常会导致大幅度压缩的事务延迟,但是也有一些情况(特别是负载超过但小于 OS 页面高速缓存)的性能会降低。这种设置可能会在某些平台上没有效果。 - 如果指定值时没有单位,则以块为单位,即为BLCKSZ 字节,通常为8kB.合法的范围在0(禁用受控写回)和2MB之间。Linux 上的默认值是512kB,其他平台上是0(如果BLCKSZ不是8kB,则默认值和最大值会按比例缩放至这个值)。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 - - + + 每当后台写入器写出的数据超过此数量时,就尝试强制操作系统将这些写操作发往底层存储。这样可以限制内核页缓存中的脏数据量,降低在检查点结束时调用 fsync,或操作系统在后台以较大批次写回数据时发生停顿的可能性。通常,这能大幅降低事务延迟,但在某些情况下性能可能下降,尤其是工作负载大于 而小于操作系统页缓存时。此设置在某些平台上可能没有效果。如果未指定单位,则以块为单位,即 BLCKSZ 字节,通常为 8kB。有效范围为 0(禁用强制写回)至 2MB。Linux 上的默认值为 512kB,其他平台为 0。(如果 BLCKSZ 不是 8kB,默认值和最大值将按比例变化。)此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 + + - 较小的bgwriter_lru_maxpagesbgwriter_lru_multiplier可以降低由后台写入器造成的额外 I/O 开销。但更可能的是,服务器进程将必须自己发出写入操作,这会延迟交互式查询。 + 较小的 bgwriter_lru_maxpagesbgwriter_lru_multiplier 可以降低后台写入器造成的额外 I/O 负载, + 但也会增加服务器进程必须自行发出写操作的可能性,从而延迟交互式查询。 - - - 异步行为 - + + 异步行为<anchor id="runtime-config-resource-io" xreflabel="异步行为"/><anchor id="runtime-config-resource-worker-processes" xreflabel="工作进程"/> @@ -2178,18 +1804,10 @@ include_dir 'conf.d' - - - 当单个后端写入数据的量超过这个数量时,尝试强制操作系统发送这些写入到底层存储。 - 这样做将限制内核的页面缓存中的脏数据量,降低在检查点末尾发出fsync时暂停的可能性,或者当操作系统在后台大批量的写回数据时。 - 通常的结果会大大减少事务延迟,但也有一些情况,特别是当工作负载大于,但小于操作系统的页面缓存时,性能可能会下降。 - 此设置在某些平台上可能无效。 - 如果指定此值时没有单位,则将其作为块,即BLCKSZ字节,通常为8kB。 - 有效范围在0,禁止强制回写,和2MB之间。 - 默认值是0,即没有强制回写。 - (如果BLCKSZ不是8kB,则最大值按其比例缩放。) - - + + 每当单个后端写出的数据超过此数量时,就尝试强制操作系统将这些写操作发往底层存储。这样可以限制内核页缓存中的脏数据量,降低在检查点结束时调用 fsync,或操作系统在后台以较大批次写回数据时发生停顿的可能性。通常,这能大幅降低事务延迟,但在某些情况下性能可能下降,尤其是工作负载大于 而小于操作系统页缓存时。此设置在某些平台上可能没有效果。如果未指定单位,则以块为单位,即 BLCKSZ 字节,通常为 8kB。有效范围为 0(禁用强制写回)至 2MB。默认值为 0,即不强制写回。(如果 BLCKSZ 不是 8kB,最大值将按比例变化。) + + @@ -2200,23 +1818,19 @@ include_dir 'conf.d' - - - 设置PostgreSQL预期可以同时执行的并发存储 I/O 操作数量。提高该值会增加任何单个PostgreSQL会话尝试并行发起的 I/O 操作数。允许的范围是11000,或者0表示禁用异步 I/O 请求。默认值是16。 - - - - 较高的值对高延迟存储和高 IOPS 设备影响最大,否则查询会经历明显的 I/O 停顿。不必要地设置过高,可能会增加系统中所有查询的 I/O 延迟。 - - - - 在支持预取建议的系统上,effective_io_concurrency还控制预取距离。 - - - - 对于位于特定表空间中的表,可以通过设置同名的表空间参数覆盖该值(见)。 - - + + 设置 PostgreSQL 预期可以同时执行的并发磁盘 I/O 操作数量。提高此值会增加单个 PostgreSQL 会话尝试并行发起的 I/O 操作数量。允许的范围为 1 至 1000,或设为零以禁用异步 I/O 请求。目前,此设置仅影响位图堆扫描。 + + + 对于磁盘,可以将为数据库提供存储的 RAID 0 条带或 RAID 1 镜像中的独立磁盘数量作为合理初始值。(对于 RAID 5,不应计入校验盘。)不过,如果数据库经常忙于执行并发会话发出的多个查询,较小的值可能就足以使磁盘阵列保持繁忙。超过使磁盘保持繁忙所需的值只会增加 CPU 开销。SSD 和其他基于内存的存储通常可以处理大量并发请求,因此最佳值可能达到数百。 + + + 异步 I/O 依赖于有效的 posix_fadvise 函数,而某些操作系统缺少此函数。如果该函数不存在,将此参数设为任何非零值都会报错。在某些操作系统(如 Solaris)上,该函数虽然存在,却实际上不做任何事情。 + + + 支持此功能的系统上默认值为 1,其他系统为 0。对于位于特定表空间中的表,可以通过设置同名的表空间参数覆盖此值(见 )。 + + @@ -2227,134 +1841,15 @@ include_dir 'conf.d' - - - 与effective_io_concurrency相似,但用于支持许多客户端会话完成的维护工作。 - - - 默认值是16。对于位于特定表空间中的表,可以通过设置同名的表空间参数覆盖该值(见)。 - - - - - - io_max_combine_limit (integer) - - io_max_combine_limit配置参数 - - - - - 控制合并 I/O 操作时允许的最大 I/O 大小,并会静默限制用户可设置的参数 - io_combine_limit。该参数只能在服务器启动时设置。 - 如果该值未指定单位,则按块计算,也就是 BLCKSZ 字节,通常为 8kB。 - 最大可能值取决于操作系统和块大小,但在 Unix 上通常为 1MB,在 Windows 上通常为 128kB。 - 默认值是 128kB。 - - - - - - io_combine_limit (integer) - - io_combine_limit配置参数 - - - + 与 effective_io_concurrency 类似,但用于为多个客户端会话执行的维护工作。 + - 控制合并 I/O 操作时允许的最大 I/O 大小。如果设置值高于 - io_max_combine_limit 参数,则会静默使用较低的那个值, - 因此如果要增大 I/O 大小,可能需要同时提高这两个参数。 - 如果该值未指定单位,则按块计算,也就是 BLCKSZ 字节,通常为 8kB。 - 最大可能值取决于操作系统和块大小,但在 Unix 上通常为 1MB,在 Windows 上通常为 128kB。 - 默认值是 128kB。 + 支持此功能的系统上默认值为 10,其他系统为 0。对于位于特定表空间中的表,可以通过设置同名的表空间参数覆盖此值(见 )。 - - - - io_max_concurrency (integer) - - io_max_concurrency配置参数 - - - - - 控制一个进程可以同时执行的最大 I/O 操作数。 - - - 默认设置 -1 会根据 以及最大进程数 - (、 - ) - 来选择一个值,但不会超过 64。 - - - 此参数只能在服务器启动时设置。 - - - - io_method (enum) - - io_method配置参数 - - - - - 选择执行异步 I/O 的方法。可能的值有: - - - - worker(使用工作进程执行异步 I/O) - - - - - io_uring(使用 io_uring 执行异步 I/O,需要以 - / - 进行构建) - - - - - sync(将可异步执行的 I/O 同步执行) - - - - 默认值为 worker。 - - - 此参数只能在服务器启动时设置。 - - - - - - io_workers (integer) - - io_workers配置参数 - - - - - 选择要使用的 I/O 工作进程数量。默认值为 3。此参数只能在 - postgresql.conf文件中或服务器命令行中设置。 - - - 仅当设置为worker时才有效。 - - - - - - - - - 工作进程 - - max_worker_processes (integer) @@ -2363,20 +1858,16 @@ include_dir 'conf.d' - - - 设置系统能够支持的后台进程的最大数量。这个参数只能在服务器启动时设置。默认值为 8。 - - - - 在运行一个备库时,你必须把这个参数设置为等于或者高于主库上的值。 - 否则,备库上可能不会允许查询。 - - - - 在更改这个值时,考虑也对以及进行调整。 - - + + 设置系统能够支持的后台进程的最大数量。此参数只能在服务器启动时设置。默认值为 8。 + + + 运行备库时,必须将此参数设为与主库相同或更大的值。否则,备库上将不允许执行查询。 + + + 更改此值时,也应考虑调整 、&zwsp;、&zwsp;。 + + @@ -2387,19 +1878,16 @@ include_dir 'conf.d' - - - 设置单个Gather或者Gather Merge节点能够开始的工作者的最大数量。并行工作者会从建立的进程池中取得,数量由限制。注意所要求的工作者数量在运行时可能实际无法被满足。如果这种事情发生,该计划将会以比预期更少的工作者运行,这可能会不太高效。默认值是2。把这个值设置为0将会禁用并行查询执行。 - - - - 注意并行查询可能消耗比非并行查询更多的资源,因为每一个工作者进程时一个完全独立的进程,它对系统产生的影响大致和一个额外的用户会话相同。在为这个设置选择值时,以及配置其他控制资源利用的设置(例如)时,应该把这个因素考虑在内。work_mem之类的资源限制会被独立地应用于每一个工作者,这意味着所有进程的总资源利用可能会比单个进程时高得多。例如,一个使用 4 个工作者的并行查询使用的 CPU 时间、内存、I/O 带宽可能是不使用工作者时的 5 倍之多。 - - - - 并行查询的更多信息请见。 - - + + 设置单个 GatherGather Merge 节点能够启动的工作进程的最大数量。并行工作进程取自 建立的进程池,并受到 的限制。注意,运行时实际可用的工作进程可能不足请求的数量。此时,计划会使用少于预期的工作进程运行,效率可能较低。默认值为 2。设为 0 会禁用并行查询执行。 + + + 注意,并行查询消耗的资源可能远多于非并行查询,因为每个工作进程都是完全独立的进程,对系统的影响大致相当于额外增加一个用户会话。选择此设置的值,以及配置其他控制资源使用的设置(如 )时,都应考虑这一点。work_mem 等资源限制分别应用于每个工作进程,因此所有进程的总资源用量可能远高于单个进程通常的用量。例如,使用 4 个工作进程的并行查询,其 CPU 时间、内存、I/O 带宽等用量可能达到完全不使用工作进程的查询的 5 倍。 + + + 并行查询的更多信息参见 。 + + @@ -2410,18 +1898,13 @@ include_dir 'conf.d' - - - 设置单一工具性命令能够启动的并行工作者的最大数目。 - 当前,支持使用并行工作者的工具性命令是CREATE INDEX,并且只有在构建B-树索引时才能并行,并且 VACUUM 没有 FULL选项。 - 并行工作者从由创建的进程池中取出,数量由控制。 - 注意实际在运行时所请求数量的工作者可能不可用。如果发生这种情况,工具性操作将使用比预期数量少的工作者运行。默认值为2。将这个值设置为0可以禁用工具性命令对并行工作者的使用。 - - - - 注意并行工具性命令不应该消耗比同等数量非并行操作更多的内存。这种策略与并行查询不同,并行查询的资源限制通常是应用在每个工作者进程上。并行工具性命令把资源限制maintenance_work_mem当作对整个工具性命令的限制,而不管其中用到了多少个并行工作者进程。不过,并行工具性命令实际上可能仍会消耗更多的CPU资源和I/O带宽。 - - + + 设置单个工具命令能够启动的并行工作进程的最大数量。目前,支持使用并行工作进程的工具命令包括:构建 B-树索引时的 CREATE INDEX,以及不带 FULL 选项的 VACUUM。并行工作进程取自 建立的进程池,并受到 的限制。注意,运行时实际可用的工作进程可能不足请求的数量。此时,工具操作会使用少于预期的工作进程运行。默认值为 2。设为 0 会禁止工具命令使用并行工作进程。 + + + 注意,并行工具命令的内存消耗不应明显高于等效的非并行操作。这与并行查询的策略不同,后者的资源限制通常分别应用于每个工作进程。并行工具命令将 maintenance_work_mem 视为整个工具命令的资源上限,而不论使用多少个并行工作进程。不过,并行工具命令仍可能消耗多得多的 CPU 资源和 I/O 带宽。 + + @@ -2432,36 +1915,76 @@ include_dir 'conf.d' + + 设置系统能够为并行操作提供的工作进程的最大数量。默认值为 8。增大或减小此值时,也应考虑调整 。此外,将此值设得大于 没有效果,因为并行工作进程取自该设置建立的工作进程池。 + + + - - 设置系统为并行操作所支持的工作者的最大数量。默认值为8。 - 在增加或者减小这个值时,也要考虑对以及进行调整。 - 此外,要注意将这个值设置得大于将不会产生效果,因为并行工作者进程都是从所建立的工作者进程池中取出来的。 - - + + + + + + parallel_leader_participation (boolean) + + parallel_leader_participation 配置参数 + + + + + 允许领导者进程执行 GatherGather Merge 节点下的查询计划,而不是等待工作进程。默认值为 on。将此值设置为 off,可以降低工作进程因领导者读取元组不够快而被阻塞的可能性,但在产生第一批元组之前,领导者进程必须等待工作进程启动。领导者对性能的帮助或妨碍程度取决于计划类型、工作进程数量和查询持续时间。 + + - + + old_snapshot_threshold (integer) + + old_snapshot_threshold 配置参数 + + + + + 设置查询快照在使用时不发生snapshot too old错误的最短可用时间。 + 已死亡超过该阈值的数据允许被清理掉。这有助于在快照长期保持使用时防止膨胀。 + 为了避免因清理本应对该快照可见的数据而得到错误结果,当快照年龄超过该阈值, + 并且该快照被用于读取某个自其建立以来已被修改过的页面时,就会报错。 + + + + 如果指定值时没有单位,则以分钟为单位。值为 -1 + (默认值)会禁用此特性,相当于把快照年龄上限设为无穷大。 + 该参数只能在服务器启动时设置。 + + + + 对生产环境而言,有用的取值大概从几个小时到几天不等。较小的值 + (例如 01min)之所以被允许, + 只是因为它们有时可用于测试。虽然允许设置到 60d 这么高, + 但请注意,在许多工作负载中,严重膨胀或事务 ID 回卷可能会在更短时间内发生。 + - - parallel_leader_participation (boolean) - - parallel_leader_participation 配置参数 - - - + + 启用此特性后,关系末尾释放出来的空间将不能返还给操作系统,因为那样可能会移除 + 检测snapshot too old条件所需的信息。分配给某个关系的全部空间都会一直 + 归属于该关系,只能在该关系内部重用,除非显式释放(例如使用 + VACUUM FULL)。 + - - 允许 leader 进程在GatherGather Merge节点下参与执行查询计划,而不是仅仅等待 worker 进程。 - 默认值是on。 - 将其设置为off可以降低 worker 因 leader 读取元组速度不够快而被阻塞的可能性, - 但在生成第一条元组之前,leader 进程将需要等待 worker 进程启动。 - leader 对性能的帮助或拖累程度取决于计划类型、worker 数量以及查询持续时间。 - - + + 该设置并不尝试保证在任何特定情况下都一定会产生错误。实际上,如果仍能从 + 某个对象(例如已经物化结果集的游标)生成正确结果,那么即使被引用表中的底层行 + 已经被清理掉,也不会报错。有些表不能安全地提前清理,因此不会受此设置影响, + 例如系统目录。对这类表来说,此设置既不会减少膨胀,也不会在扫描时引入 + snapshot too old错误的可能性。 + + - + + + @@ -2491,7 +2014,7 @@ include_dir 'conf.d' - minimal级别生成最少的WAL日志量。它不记录在创建或重写事务中对永久关系的行信息。 + minimal级别生成最少的WAL日志量。对于在当前事务中创建或重写的永久关系,不记录其行信息。 这可以使操作速度更快(参见)。触发此优化的操作包括: ALTER ... SET TABLESPACE @@ -2502,15 +2025,15 @@ include_dir 'conf.d' REINDEX TRUNCATE - 然而,最小的WAL不包含足够的信息用于时点恢复,因此必须使用replica或更高级别来启用持续归档 + 然而,minimal 级别的 WAL 不包含足够的信息用于时间点恢复,因此必须使用replica或更高级别来启用持续归档 ()和流式二进制复制。 实际上,如果max_wal_senders不为零,服务器甚至不会以此模式启动。 - 请注意,将wal_level更改为minimal会使先前的基本备份无法用于时点恢复和备库。 + 请注意,将wal_level更改为minimal会使先前的基础备份无法用于时间点恢复和备库。 logical级别上,记录与replica相同的信息,以及从WAL中提取逻辑变更集所需的信息。 - 使用logical级别会增加WAL的容量,特别是如果许多表被配置为REPLICA IDENTITY FULL, + 使用logical级别会增加 WAL 的数量,特别是如果许多表被配置为REPLICA IDENTITY FULL, 并且执行了许多UPDATEDELETE语句。 @@ -2538,16 +2061,15 @@ include_dir 'conf.d' - 能安全关闭fsync的环境的示例包括从一个备份文件中初始加载一个新数据库集簇、使用一个数据库集簇来在数据库被删掉并重建之后处理一批数据,或者一个被经常重建并却不用于失效备援的只读数据库克隆。单独的高质量硬件不足以成为关闭fsync的理由。 + 可以安全关闭fsync的情形包括:从备份文件初始装载一个新数据库集簇;用数据库集簇处理一批数据,处理后就丢弃并重建该数据库;或者使用经常重建且不用于故障切换的只读数据库克隆。仅有高质量硬件不足以成为关闭fsync的理由。 - 当把fsync从关闭改成打开时,为了可靠的恢复,需要强制在内核中的所有被修改的缓冲区进入持久化存储。这可以在多个时机来完成: - 在集簇被关闭时或在fsync因为运行initdb --sync-only而打开时、运行sync时、卸载文件系统时或者重启服务器时。 + 为确保将fsync从关闭改为打开后能够可靠恢复,必须将内核中所有已修改的缓冲区强制写入持久存储。可以在集簇已关闭或fsync已开启时,通过运行initdb --sync-only、运行sync、卸载文件系统或重启服务器来完成。 - 在很多情况下,为不重要的事务关闭可以提供很多关闭fsync的潜在性能收益,并不会有的同时, 关闭fsync可以提供很多潜在的性能优势,而不会有伴随着的数据损坏风险。 + 在很多情况下,为非关键事务关闭,可以获得关闭fsync所带来的大部分潜在性能收益,同时避免伴随的数据损坏风险。 @@ -2566,39 +2088,27 @@ include_dir 'conf.d' - 指定数据库服务器返回success指示给客户端之前,必须要完成多少WAL处理。 - 合法的值为remote_apply, on(默认值), remote_write,local, 和 off。 + 指定数据库服务器向客户端返回成功指示之前,必须完成多少 WAL 处理。有效值为remote_applyon(默认值)、remote_writelocaloff - 如果synchronous_standby_names为空,则唯一有意义的设置为onoff ; - remote_applyremote_writelocal都提供与on相同的本地同步级别。 - 所有非off模式的本地行为都是等待WAL的本地刷新到磁盘。 - 在 off模式,无需等待,因此在向客户端报告成功和以后保证事务安全防止服务器崩溃之间可能会出现延迟。 - 当设置为off时,在向客户端报告成功和真正保证事务不会被服务器崩溃威胁之间会有延迟(最大的延迟是的三倍)。 - 不同于,将这个参数设置为off不会产生数据库不一致性的风险:一个操作系统或数据库崩溃可能会造成一些最近据说已提交的事务丢失,但数据库状态是一致的,就像这些事务已经被干净地中止。 - 因此,当性能比完全确保事务的持久性更重要时,关闭synchronous_commit可以作为一个有效的代替手段。更多讨论见。 + 如果synchronous_standby_names为空,只有onoff两种设置有意义;remote_applyremote_writelocal提供的本地同步级别都与on相同。所有非off模式在本地都会等待 WAL 刷写到磁盘。在off模式下则无需等待,因此,向客户端报告成功后,可能还要经过一段时间,才能保证事务不会因服务器崩溃而丢失。(最大延迟为的三倍。)与不同,将此参数设为off不会带来数据库不一致的风险:操作系统或数据库崩溃可能会使一些最近报告已提交的事务丢失,但数据库状态会与这些事务已正常中止时完全相同。因此,当性能比完全确保事务持久性更重要时,关闭synchronous_commit可以是一种有用的替代方案。更多讨论见 - 如果为非空,synchronous_commit也控制是否事务提交将等待它们的 WAL 记录在备库上被处理。 + 如果非空,synchronous_commit还控制事务提交是否等待备库处理其 WAL 记录。 - 当设置为 remote_apply 时,提交将等待,直到来自当前同步备库的答复显示他们已收到事务的提交记录并应用了它,以便它变得对备库上的查询可见,并写入备库上的持久存储。 - 这将导致比以前的设置更大的提交延迟,因为它等待 WAL 重放(replay)。 - 当设置为on时,提交将等待,直到来自于当前同步的备库的回复显示它们已经收到了事务的提交记录并将其刷入了磁盘。 - 这保证事务将不会被丢失,除非主库和所有同步备库都遭受到了数据库存储损坏的问题。 - 当这个参数被设置为remote_write时,提交将等待,直到来自当前的同步备库的回复指示它们已经收到了该事务的提交记录并且已经把该记录写到它们的文件系统,这种设置保证数据得以保存,在PostgreSQL的备库实例崩溃时,但是不能保证备库遭受操作系统级别崩溃时数据能被保持,因为数据不一定必须要在备库上达到持久存储。 - 设置local会导致提交等待本地刷写到磁盘,而不是复制。在使用同步复制时这通常是不可取的,但是为了完整性提供了这个选项。 + 设为remote_apply时,提交会等待当前同步备库回复,确认已收到并应用该事务的提交记录,使其对备库上的查询可见,并且已将其写入备库的持久存储。由于需要等待 WAL 重放,这会比之前的设置产生大得多的提交延迟。设为on时,提交会等待当前同步备库回复,确认已收到事务的提交记录,并已将其刷写到持久存储。这能保证事务不会丢失,除非主库和所有同步备库的数据库存储都损坏。设为remote_write时,提交会等待当前同步备库回复,确认已收到事务的提交记录,并已将其写入各自的文件系统。此设置能保证备库上的PostgreSQL实例崩溃时数据不丢失,但不能保证备库发生操作系统级别崩溃时数据不丢失,因为数据未必已写入备库的持久存储。设为local时,提交会等待本地刷盘,但不等待复制。使用同步复制时通常不希望采用这种设置,提供它是为了使选项完整。 - 这个参数可以随时被修改;任何一个事务的行为由其提交时生效的设置决定。因此,可以同步提交一些事务,同时异步提交其他事务。例如,当默认是相反时,实现一个单一多语句事务的异步提交,在事务中发出SET LOCAL synchronous_commit TO OFF。 + 此参数可以随时更改;每个事务的行为由提交时生效的设置决定。因此,让一些事务同步提交、另一些事务异步提交是可行且有用的。例如,当默认设置要求同步提交时,可以在一个包含多条语句的事务中执行SET LOCAL synchronous_commit TO OFF,使该事务异步提交。 - 概括了 synchronous_commit 各种设置具备的能力。 + 汇总了synchronous_commit各种设置具备的能力。 @@ -2614,9 +2124,9 @@ include_dir 'conf.d' synchronous_commit 设置 - 本地持久提交 - PG 崩溃备库持久提交 - OS 崩溃备库持久提交 + 本地提交持久性 + PG 崩溃后备库提交持久性 + OS 崩溃后备库提交持久性 备库查询一致性 @@ -2670,49 +2180,7 @@ include_dir 'conf.d' - - old_snapshot_threshold (integer) - - old_snapshot_threshold配置参数 - - - - - 设置查询快照在使用时不发生snapshot too old错误的最短可用时间。 - 已死亡超过该阈值的数据允许被清理掉。这有助于在快照长期保持使用时防止膨胀。 - 为了避免因清理本应对该快照可见的数据而得到错误结果,当快照年龄超过该阈值, - 并且该快照被用于读取某个自其建立以来已被修改过的页面时,就会报错。 - - - - 如果指定值时没有单位,则以分钟为单位。值为 -1 - (默认值)会禁用此特性,相当于把快照年龄上限设为无穷大。 - 该参数只能在服务器启动时设置。 - - - - 对生产环境而言,有用的取值大概从几个小时到几天不等。较小的值 - (例如 01min)之所以被允许, - 只是因为它们有时可用于测试。虽然允许设置到 60d 这么高, - 但请注意,在许多工作负载中,严重膨胀或事务 ID 回卷可能会在更短时间内发生。 - - - - 启用此特性后,关系末尾释放出来的空间将不能返还给操作系统,因为那样会移除 - 检测snapshot too old条件所需的信息。分配给某个关系的全部空间都会一直 - 归属于该关系,只能在该关系内部重用,除非显式释放(例如使用 - VACUUM FULL)。 - - - 该设置并不尝试保证在任何特定情况下都一定会产生错误。实际上,如果仍能从 - 某个对象(例如已经物化结果集的游标)生成正确结果,那么即使被引用表中的底层行 - 已经被清理掉,也不会报错。有些表不能安全地提前清理,因此不会受此设置影响, - 例如系统目录。对这类表来说,此设置既不会减少膨胀,也不会在扫描时引入 - snapshot too old错误的可能性。 - - - @@ -2724,7 +2192,7 @@ include_dir 'conf.d' - 用来向强制 WAL 更新到磁盘的方法。如果fsync是关闭的,那么这个设置就不相关,因为 WAL 文件更新将根本不会被强制。可能的值是: + 用于将 WAL 更新强制写入磁盘的方法。如果fsync关闭,此设置就没有作用,因为 WAL 文件更新根本不会被强制写入磁盘。可选值为: @@ -2748,7 +2216,7 @@ include_dir 'conf.d' - fsync_writethrough(在每次提交时调用fsync(),强制任何磁盘写高速缓存的直通写) + fsync_writethrough(在每次提交时调用fsync(),强制穿透任何磁盘写缓存) @@ -2760,10 +2228,10 @@ include_dir 'conf.d' - open_* 选项也可以使用O_DIRECT(如果可用)。 + open_* 选项还会使用O_DIRECT(如果可用)。 不是在所有平台上都能使用所有这些选择。 - 默认值是列表中第一个被平台支持的那个, 不过fdatasync是 Linux和FreeBSD中的默认值。 - 默认值不一定是最理想的;有可能需要修改这个设置或系统配置的其他方面来创建一个崩溃-安全的配置,或达到最佳性能。 + 默认值是列表中第一个被平台支持的那个, 不过fdatasync是 Linux 和 FreeBSD 中的默认值。 + 默认值不一定最合适;可能需要更改此设置或系统配置的其他方面,以确保崩溃时的数据安全或达到最佳性能。 这些方面在中讨论。 这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 @@ -2780,11 +2248,11 @@ include_dir 'conf.d' - 当这个参数为打开时,PostgreSQL服务器在一个检查点之后的页面的第一次修改期间将每个页面的全部内容写到 WAL 中。这么做是因为在操作系统崩溃期间正在处理的一次页写入可能只有部分完成,从而导致在一个磁盘页面中混合有新旧数据。在崩溃后的恢复期间,通常存储在 WAL 中的行级改变数据不足以完全恢复这样一个页面。存储整页镜像可以保证页面被正确存储,但代价是增加了必须被写入 WAL 的数据量(因为 WAL 重放总是从一个检查点开始,所以在检查点后每个页面的第一次改变时这样做就够了。因此,一种减小全页面写开销的方法是增加检查点间隔参数值)。 + 启用此参数时,PostgreSQL服务器会在检查点之后首次修改每个磁盘页面时,将该页面的全部内容写入 WAL。这样做是因为,操作系统崩溃时正在进行的页面写入可能只完成了一部分,导致磁盘页面混有新旧数据。通常存储在 WAL 中的行级变更数据不足以在崩溃恢复时完整还原这样的页面。保存整页镜像能保证正确恢复页面,但会增加必须写入 WAL 的数据量。(由于 WAL 重放总是从检查点开始,只需在检查点之后首次修改每个页面时这样做。因此,减少整页写入开销的一种方法是增大检查点间隔参数。) - 把这个参数关闭会加快正常操作,但是在系统失败后可能导致不可恢复的数据损坏,或者静默的数据损坏。其风险类似于关闭fsync, 但是风险较小。并且只有在可关闭fsync的情况下才应该关闭它。 + 关闭此参数可以加快正常操作,但系统故障后可能出现不可恢复的数据损坏或静默数据损坏。风险与关闭fsync类似,虽然较小,但也只有在该参数建议的相同情形下才应关闭此参数。 @@ -2807,7 +2275,7 @@ include_dir 'conf.d' - 当这个参数为on时,PostgreSQL服务器一个检查点之后页面被第一次修改期间把该磁盘页面的整个内容都写入 WAL,即使对所谓的提示位做非关键修改也会这样做。 + 当这个参数为on时,PostgreSQL服务器在检查点之后首次修改页面时把该磁盘页面的整个内容都写入 WAL,即使对所谓的提示位做非关键修改也会这样做。 @@ -2831,11 +2299,11 @@ include_dir 'conf.d' - 当这个参数为on时,PostgreSQL服务器在打开时或在基础备份期间,压缩写入WAL的整页镜像。在WAL回放期间将对压缩的页面镜像进行解压。默认值是off。只有超级用户能更改这个设置。 + 当这个参数为on时,PostgreSQL服务器会压缩写入 WAL 的整页镜像,例如在启用时、基础备份期间等。在 WAL 重放期间将对压缩的整页镜像进行解压。默认值是off。只有超级用户能更改这个设置。 - 开启这个参数可以在不增加不可恢复的数据损坏风险的情况下减少WAL数据量,但代价是在WAL记录期间用于压缩以及在WAL回放期间用于解压的额外CPU开销。 + 开启此参数可以减少 WAL 数据量,而且不会增加不可恢复的数据损坏风险;代价是在记录 WAL 时压缩、重放 WAL 时解压会额外消耗一些 CPU。 @@ -2850,10 +2318,10 @@ include_dir 'conf.d' - 如果设置为on(默认值),此选项会导致新的 WAL 文件被零填充。 - 在某些文件系统上,这可确保在我们需要写入 WAL 记录之前分配空间。 - 但是,Copy-On-Write(COW)文件系统可能不会从此技术中受益,因此可以选择跳过不必要的工作。 - 如果设置为off,则在创建文件时仅写入最终字节,以便其具有预期大小。 + 如果设置为on(默认值),此选项会导致新的 WAL 文件被零填充。 + 在某些文件系统上,这可确保在我们需要写入 WAL 记录之前分配空间。 + 但是,写时复制(COW)文件系统可能不会从此技术中受益,因此可以选择跳过不必要的工作。 + 如果设置为off,则在创建文件时只写入最后一个字节,以便其具有预期大小。 @@ -2868,8 +2336,8 @@ include_dir 'conf.d' - 如果设置为 on (默认值),此选项通过重命名来回收 WAL 文件,从而避免创建新文件。 - 在 COW 文件系统上,创建新文件系统可能更快,因此提供了禁用此行为的选项。 + 如果设置为 on (默认值),此选项通过重命名来回收 WAL 文件,从而避免创建新文件。 + 在 COW 文件系统上,创建新文件可能更快,因此提供了禁用此行为的选项。 @@ -2884,12 +2352,12 @@ include_dir 'conf.d' - 用于还未写入磁盘的 WAL 数据的共享内存量。默认值 -1 选择等于的 1/32 的尺寸(大约3%),但是不小于64kB也不大于 WAL 段的尺寸(通常为16MB)。如果自动的选择太大或太小可以手工设置该值,但是任何小于32kB的正值都将被当作32kB。 + 用于还未写入磁盘的 WAL 数据的共享内存量。默认值 -1 选择等于的 1/32 的尺寸(大约3%),但是不小于64kB也不大于 WAL 段的尺寸(通常为16MB)。如果自动的选择太大或太小可以手工设置该值,但是任何小于32kB的正值都将被当作32kB。 如果指定值时没有单位,则以WAL块作为单位,即为 XLOG_BLCKSZ 字节,通常为8kB。这个参数只能在服务器启动时设置。 - 在每次事务提交时,WAL 缓冲区的内容被写出到磁盘,因此极大的值不可能提供显著的收益。不过,把这个值设置为几个兆字节可以在一个繁忙的服务器(其中很多客户端会在同一时间提交)上提高写性能。由默认设置 -1 选择的自动调节将在大部分情况下得到合理的结果。 + 在每次事务提交时,WAL 缓冲区的内容被写出到磁盘,因此极大的值不太可能带来显著收益。不过,把这个值设置为至少几个兆字节可以在一个繁忙的服务器(其中很多客户端会在同一时间提交)上提高写性能。由默认设置 -1 选择的自动调节将在大部分情况下得到合理的结果。 @@ -2907,9 +2375,9 @@ include_dir 'conf.d' 指定 WAL 写入器刷写 WAL 的频繁程度,以时间为单位。 在刷写WAL之后,写入器将根据wal_writer_delay所给出的时间长度进行睡眠,除非被一个异步提交的事务提前唤醒。 - 如果最近的刷写发生在 wal_writer_delay 之前,并且小于 wal_writer_flush_after WAL的值产生之后,那么WAL只会被写入操作系统,而不会被刷写到磁盘。 + 如果距上次刷盘的时间小于wal_writer_delay,并且自那以后产生的 WAL 数据量小于wal_writer_flush_after,则只将 WAL 写入操作系统,而不刷写到磁盘。 如果指定值时没有单位,则以毫秒作为单位。 - 默认值是 200 毫秒(200ms)。注意在很多系统上,有效的睡眠延迟粒度是 10 毫秒,把wal_writer_delay设置为一个不是 10 的倍数的值,其效果和把它设置为大于该值的下一个 10 的倍数产生的效果相同。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 + 默认值是 200 毫秒(200ms)。注意在很多系统上,有效的睡眠延迟粒度是 10 毫秒,把wal_writer_delay设置为一个不是 10 的倍数的值,其效果可能与将其设置为下一个更大的 10 的倍数相同。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 @@ -2924,8 +2392,8 @@ include_dir 'conf.d' - 指定 WAL 写入器刷写 WAL 的频繁程度,以卷为单位。 - 如果最近的刷写发生在 wal_writer_delay 之前,并且小于 wal_writer_flush_after WAL的值产生之后,那么WAL只会被写入操作系统,而不会被刷写到磁盘。 + 指定 WAL 写入器刷写 WAL 的频繁程度,按数据量衡量。 + 如果距上次刷盘的时间小于wal_writer_delay,并且自那以后产生的 WAL 数据量小于wal_writer_flush_after,则只将 WAL 写入操作系统,而不刷写到磁盘。 如果wal_writer_flush_after被设置为0,则WAL数据总是会被立即刷写。 如果指定值时没有单位,则以WAL块作为单位,即为XLOG_BLCKSZ字节,通常为8kB。 默认是1MB。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 @@ -2943,10 +2411,7 @@ include_dir 'conf.d' - 当wal_levelminimal,并且在创建或重写永久关系之后提交事务时,此设置将确定如何保留新数据。 - 如果数据小于此设置,将其写入 WAL 日志;否则,使用受影响文件的 fsync。 - 根据存储的属性,如果此类提交减慢了并发事务,提高或降低此值可能会有所帮助。 - 如果指定此值时没有单位,则视为千字节。默认为两兆字节(2MB)。 + 当wal_levelminimal,且事务在创建或重写永久关系后提交时,此设置决定如何持久保存新数据。如果数据量小于此设置,就将其写入 WAL;否则,对受影响的文件执行 fsync。如果这类提交拖慢了并发事务,根据存储的特性,增大或减小此值可能有所帮助。未指定单位时以千字节为单位。默认值为两兆字节(2MB)。 @@ -2961,20 +2426,20 @@ include_dir 'conf.d' - 设置commit_delay会在执行WAL刷新之前添加时间延迟。 + 设置commit_delay会在发起 WAL 刷盘之前添加时间延迟。 如果系统负载足够高,使得在给定时间间隔内有更多事务准备提交, - 这可以通过允许更多事务通过单个WAL刷新来提高组提交吞吐量。 - 然而,这也会增加延迟,最多为每个WAL刷新的commit_delay。 - 因为如果没有其他事务准备提交,延迟就是浪费的,所以只有在至少有 - commit_siblings其他事务活动时才会执行延迟, - 当要启动刷新时,如果fsync被禁用,则不会执行延迟。 + 这可以通过允许更多事务通过一次 WAL 刷盘来提高组提交吞吐量。 + 不过,每次 WAL 刷盘的延迟也会因此增加,最多增加commit_delay。 + 如果没有其他事务准备提交,等待就没有意义,因此仅当即将发起刷盘时至少还有 + commit_siblings个其他活动事务,才会等待。 + 此外,如果禁用了fsync,也不会等待。 如果未指定单位,则将其视为微秒。 默认commit_delay为零(无延迟)。 只有超级用户能更改这个设置。 - 在PostgreSQL的 9.3 发布之前,commit_delay的行为不同并且效果更差:它只影响提交,而不是所有 WAL 刷写,并且即使在 WAL 刷写马上就要完成时也会等待一整个配置的延迟。从PostgreSQL 9.3 中开始,第一个准备好刷写的进程会等待配置的间隔,而后续的进程只等到领先者完成刷写操作。 + 在PostgreSQL的 9.3 发布之前,commit_delay的行为不同并且效果更差:它只影响提交,而不是所有 WAL 刷写,并且即使 WAL 刷盘更早完成,也会等待整个配置的延迟时间。从PostgreSQL 9.3 开始,第一个准备好刷写的进程会等待配置的间隔,而后续的进程只等到领先者完成刷写操作。 @@ -2989,7 +2454,7 @@ include_dir 'conf.d' - 在执行commit_delay延迟时,要求的并发活动事务的最小数目。大一些的值会导致在延迟间隔期间更可能有至少另外一个事务准备好提交。默认值是五个事务。 + 执行commit_delay延迟前要求的并发活动事务的最小数目。大一些的值会导致在延迟间隔期间更可能有至少另外一个事务准备好提交。默认值是五个事务。 @@ -3012,7 +2477,7 @@ include_dir 'conf.d' 自动 WAL 检查点之间的最长时间。如果指定值时没有单位,则以秒为单位。 - 合理的范围在 30 秒到 1 天之间。默认是 5 分钟(5min)。增加这个参数的值会增加崩溃恢复所需的时间。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 + 合理的范围在 30 秒到 1 天之间。默认是 5 分钟(5min)。增加这个参数的值可能会增加崩溃恢复所需的时间。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 @@ -3027,11 +2492,11 @@ include_dir 'conf.d' - 指定检查点完成的目标,作为检查点之间总时间的一部分。 - 默认是 0.9,这将把检查点分布在几乎所有可用的时间间隔上,提供公平一致的I/O负载,同时也为检查点完成开销留下了一些时间。 - 减少此参数是不被推荐的,因为这会导致检查点完成得更快。 - 这个造成处于在检查点和下一个计划检查点之间较少IO之后的检查点会有更高的IO比例。 - 这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 + 指定检查点完成所用时间的目标值,以检查点之间总时间的比例表示。 + 默认值为 0.9,这会把检查点工作分散到几乎整个可用间隔内,使 I/O 负载较为平稳, + 同时为检查点完成时的额外工作留出一些时间。不建议减小此参数,因为这样会让检查点更快完成, + 导致检查点期间的 I/O 速率更高,而在检查点完成后到下一个计划检查点开始前的一段时间内 I/O 较少。 + 此参数只能在postgresql.conf文件中或服务器命令行上设置。 @@ -3048,7 +2513,7 @@ include_dir 'conf.d' 当执行检查点时写入的数据量超过此数量时,就尝试强制 OS 把这些写发送到底层存储。 这样做将会限制内核页面高速缓存中的脏数据数量,降低在检查点末尾发出fsync或者 OS 在后台大批量写回数据时被卡住的可能性。 - 那常常会导致大幅度压缩的事务延迟,但是也有一些情况(特别是负载超过但小于 OS 页面高速缓存)的性能会降低。 + 这通常能显著降低事务延迟,但是也有一些情况(特别是负载超过但小于 OS 页面高速缓存)的性能会降低。 这种设置可能会在某些平台上没有效果。 如果指定值时没有单位,则以块为单位,即为BLCKSZ 字节,通常为8kB。 合法的范围在0(禁用强制写回)和2MB之间。Linux 上的默认值是256kB,其他平台上是0(如果BLCKSZ不是8kB,则默认值和最大值会按比例缩放到它)。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 @@ -3127,10 +2592,9 @@ include_dir 'conf.d' 当启用archive_mode时,完成的WAL段会通过设置 - 发送到归档存储。除了off, - 要禁用,有两种模式:on和 + 发送到归档存储。除了用于禁用归档的off外,还有两种模式:onalways。在正常操作期间,这两种模式之间没有区别,但当设置为always时, - WAL归档程序在归档恢复或待机模式下也会被启用。在always模式下,从归档中恢复的所有文件 + WAL归档程序在归档恢复或备库模式下也会被启用。在always模式下,从归档中恢复的所有文件 或通过流复制传输的文件将被再次归档。详细信息请参见 @@ -3180,7 +2644,7 @@ include_dir 'conf.d' - 仅在完成的WAL段上调用。 + 只针对已完成的 WAL 段调用。 因此,如果您的服务器生成的WAL流量较少(或者在这样做时有间歇期),在事务完成和安全记录到归档存储之间可能会有很长的延迟。 为了限制未归档数据的年龄,您可以将archive_timeout设置为强制服务器定期切换到新的WAL段文件。 当此参数大于零时,只要自上次段文件切换以来经过了这段时间,并且存在任何数据库活动,包括单个检查点(如果没有数据库活动,则跳过检查点),服务器将切换到新的段文件。 @@ -3195,74 +2659,15 @@ include_dir 'conf.d' - - - 恢复 - - - 配置 - 恢复的 - 一般设置 - - - - 本节描述了适用于一般恢复的设置,影响崩溃恢复、流复制和基于归档的复制。 - - - - - - recovery_prefetch (enum) - - recovery_prefetch配置参数 - - - - - - 是否在恢复期间尝试预取在WAL中引用但尚未在缓冲池中的块。有效值为 - offon和 - try(默认值)。设置 - try仅在操作系统提供 - posix_fadvise函数时才启用 - 预取,该函数目前用于实现预取。请注意,一些操作系统提供该 - 函数,但它不起作用。 - - - - 预取即将需要的块可以减少某些工作负载下恢复期间的I/O等待时间。 - 另请参阅和 - 设置,限制预取活动。 - - - - - - wal_decode_buffer_size (integer) - - wal_decode_buffer_size配置参数 - - - - - - 服务器可以在WAL中查找预取块的最大提前量限制。如果未指定单位,则将其视为字节。 - 默认值为512kB。该参数只能在服务器启动时设置。 - - - - - - 归档恢复 - configuration - of recovery + 配置 + 恢复 一个备库 @@ -3271,7 +2676,7 @@ include_dir 'conf.d' - Recovery 涵盖使用服务器作为备库或用于执行目标恢复。 + 恢复 涵盖使用服务器作为备库或用于执行目标恢复。 通常情况,备库模式用于提供高可用性和/或读可扩展性,而目标恢复用于从数据丢失中恢复。 @@ -3340,7 +2745,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows 这个信息可以被用来把归档截断为支持从当前恢复重启所需的最小值。 对于单一备库配置,模块常常被用在archive_cleanup_command中,例如: archive_cleanup_command = 'pg_archivecleanup /mnt/server/archivedir %r' - 但是注意,如果多个备库正在从同一个归档目录中恢复,你将需要保证只有当任意服务器都不再需要 WAL 文件时才会删除它们。 + 但是注意,如果多个备库正在从同一个归档目录中恢复,你将需要保证只有当所有服务器都不再需要这些 WAL 文件时才会删除它们。 archive_cleanup_command通常被用于一种温备配置(见)中。 要在该命令中嵌入一个真正的%字符,需要写成%% @@ -3393,7 +2798,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows 默认情况下,恢复将会一直恢复到 WAL 日志的末尾。下面的参数可以被用来指定一个更早的停止点。 在recovery_targetrecovery_target_lsnrecovery_target_namerecovery_target_timerecovery_target_xid中, - 最多只能使用一个,如果在配置文件中使用了多个,将会产生一个错误。这个参数只能在服务器启动时设置。 + 最多只能使用一个,如果在配置文件中使用了多个,将会产生一个错误。这些参数只能在服务器启动时设置。 @@ -3426,7 +2831,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows - 这个参数指定(pg_create_restore_point()所创建)的已命名的恢复点,恢复将进入该恢复点。 + 这个参数指定(pg_create_restore_point()所创建)的已命名的恢复点,恢复将进行到该恢复点。 @@ -3441,7 +2846,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows - 此参数指定恢复将执行的时间戳。精确的停止点还受到得影响。 + 此参数指定恢复要进行到的时间戳。精确的停止点还受到的影响。 @@ -3461,7 +2866,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows - 这个参数指定恢复将进入的事务 ID。记住虽然事务 ID 是在事务开始时顺序分配的,但是事务可能以不同的数字顺序完成。 + 这个参数指定恢复要进行到的事务 ID。记住虽然事务 ID 是在事务开始时顺序分配的,但是事务可能以不同的数字顺序完成。 那些在指定事务之前(也可以包括该事务)提交的事务将被恢复。精确的停止点也受到的影响。 @@ -3477,7 +2882,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows - 此参数指定恢复将继续进行的预写日志位置的LSN。精确的停靠点也受 的影响。 + 此参数指定恢复要进行到的预写日志位置的 LSN。精确的停止点也受 的影响。 使用系统数据类型pg_lsn解析此参数。 @@ -3502,7 +2907,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows 指定我们是否仅在指定的恢复目标之后停止(on),或者仅在恢复目标之前停止(off)。 适用于或者被指定的情况。 - 这个设置分别控制事务是否有准确的目标WAL位置(LSN)、提交时间或事务ID将被包括在该恢复中。默认值为on。 + 这个设置控制恢复是否包含 WAL 位置(LSN)、提交时间或事务 ID 分别恰好等于目标值的事务。默认值为on @@ -3519,17 +2924,12 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows 指定恢复到一个特定的时间线中。该值可以是数字时间线 ID 或特殊值。 - 值current沿着与执行基本备份时相同的时间线恢复。 + 值current沿着与执行基础备份时相同的时间线恢复。 值latest将恢复到归档中能找到的最新时间线,这在备库中很有用。 latest是默认值。 - - 如果要以十六进制指定时间线 ID(例如从 WAL 文件名或历史文件中提取),请在前面加上 - 0x。例如,如果 WAL 文件名为 - 00000011000000A10000004F,那么时间线 ID 就是 - 0x11(十进制为 17)。 - + 你通常只需要在复杂的再次恢复场景中设置此参数,也就是当你需要回到某个状态,而该状态本身又是在一次时间点恢复之后达到的。 @@ -3555,14 +2955,14 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows - 使用pause设置的目的是:如果这个恢复目标就是恢复最想要的位置,就允许对数据库执行查询。 + 使用pause设置的目的是允许对数据库执行查询,以检查这个恢复目标是否为最合适的恢复位置。 暂停的状态可以使用pg_wal_replay_resume()(见)继续,这会让恢复终结。 如果这个恢复目标不是想要的停止点,那么关闭服务器,将恢复目标设置改为一个稍后的目标并且重启以继续恢复。 要让实例在想要的重放点那里准备好,shutdown设置可以派上用场。 - 该实例将仍能重放更多 WAL 记录(并且事实上将不得不重放从下一次它被启动后最后一个检查点以来的 WAL 记录)。 + 该实例将仍能重放更多 WAL 记录(并且事实上,下次启动时必须重新回放自上一个检查点以来的 WAL 记录)。 @@ -3573,7 +2973,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows 如果没有设置恢复目标,这个设置没有效果。 如果没有启用pause设置的动作将和shutdown一样。 - 如果在升级期间达到恢复目标,pause 的设置将与 promote的行为相同。 + 如果在备库提升期间达到恢复目标,pause 的设置将与 promote的行为相同。 @@ -3614,28 +3014,27 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows - 指定来自备库或流式基础备份客户端的并发连接的最大数量(即同时运行 WAL 发送进程的最大数)。 - 默认值是10。值0意味着禁用复制。 - 突然的流式传输客户端断开连接可能留下一个孤立连接槽(知道达到超时),因此这个参数应该设置得略高于最大客户端连接数,这样断开连接的客户端可以立刻重新连接。 - 这个参数只能在服务器启动时被设置。此外,wal_level必须设置为replica或更高级别以允许来自备库的连接。 + 指定来自备库或流式基础备份客户端的最大并发连接数(即同时运行的 WAL 发送进程的最大数量)。 + 默认值为 10。值 0 表示禁用复制。 + 流式客户端突然断开连接后,可能会留下一个孤立连接槽,直到超时才释放。 + 因此,此参数应设置得略高于预期的最大客户端数,使断开连接的客户端能够立即重新连接。 + 此参数只能在服务器启动时设置。此外,wal_level 必须设置为 + replica 或更高级别,才允许来自备库的连接。 - 在运行一个备库时,你必须把这个参数设置为等于或者高于主库上的值。 - 否则,备库上可能不会允许查询。 - + 运行备库时,必须将此参数设置为大于或等于主库上的值。否则,备库上将不允许查询。 + - max_replication_slots (integer) max_replication_slots配置参数 - 指定服务器可以支持的复制槽(见) 最大数量。默认值为10。这个参数只能在服务器启动时设置。将它设置为一个比当前已有复制槽要少的值会阻碍服务器启动。此外,要允许使用复制槽, @@ -3643,8 +3042,14 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows 更高。 - - + + 在订阅者端,指定可以同时跟踪多少个复制源(参见),从而限制可以在服务器上创建的逻辑复制订阅数。 + 如果将其设置为低于当前正在跟踪的复制源数量的值(该数量反映在 + pg_replication_origin_status 中, + 而不是 pg_replication_origin 中),服务器将无法启动。 + + + output_plugin_libraries (string) @@ -3702,16 +3107,19 @@ HINT: If it is safe for all REPLICATION users to use this library as an output - 指定在备库需要为流复制获取日志段文件的情况下,pg_wal目录下所能保留的过去日志文件段的最小尺寸。 - 如果一个连接到发送服务器的备库落后了超过wal_keep_size兆字节,发送服务器可以移除一个备库仍然需要的 WAL 段,在这种情况下复制连接将被中断。 - 最终结果是下行连接也将最终失败(不过,如果在使用 WAL 归档,备库可以通过从归档获取段来恢复)。 + 指定在 pg_wal 目录中保留的旧 WAL 文件的最小总量, + 以便备库需要时获取这些文件进行流复制。如果连接到发送服务器的备库落后超过 + wal_keep_size 兆字节,发送服务器可能会移除备库仍需要的 WAL 段, + 从而导致复制连接终止。下游连接最终也会因此失败。 + (不过,如果使用了 WAL 归档,备库可以通过从归档获取该段来恢复。) - 只设置pg_wal中保留的文件段的最小尺寸;系统可能需要为 WAL 归档或从一个检查点恢复保留更多段。 - 如果wal_keep_size为零(默认值), 更多的空间来 存放WAL归档或从一个检查点恢复。 - 如果wal_keep_segments是零(缺省), 系统不会为备库目的保留任何多余的段,因此备库可用的旧 WAL 段的数量是一个上个检查点位置和 WAL 归档状态的函数。 - 如果此值被指定时没有单位,则视为兆字节。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 + 此设置只规定 pg_wal 中保留的段的最小总量;系统可能需要为 WAL 归档 + 或从检查点恢复而保留更多段。如果 wal_keep_size 为零(默认值), + 系统不会为备库额外保留任何段,因此备库可用的旧 WAL 段数取决于前一个检查点的位置 + 和 WAL 归档的状态。如果指定值时没有单位,则按兆字节计算。 + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 @@ -3725,41 +3133,20 @@ HINT: If it is safe for all REPLICATION users to use this library as an output - - 指定在检查点时,replication slots(复制槽)允许在pg_wal目录中保留的WAL文件的最大大小。 - 如果max_slot_wal_keep_size为-1(默认值),复制槽可以保留无限量的WAL文件。否则,如果复制槽的restart_lsn落后于当前LSN超过给定大小, - 使用该槽的备机可能由于所需的WAL文件被删除而无法继续复制。您可以在pg_replication_slots中查看复制槽的WAL可用性。 - 如果未指定单位,则此值将被视为兆字节。此参数只能在postgresql.conf文件或服务器命令行中设置。 - - - - - - idle_replication_slot_timeout (integer) - - idle_replication_slot_timeout配置参数 - - - - - 使保持空闲状态(未被复制连接使用)超过此持续时间的复制槽失效。 - 如果指定值时没有单位,则以秒为单位。零值(默认值)将禁用空闲超时失效机制。 - 该参数只能在postgresql.conf文件中或服务器命令行上设置。 - - - 由于空闲超时导致的槽失效会在检查点期间发生。由于检查点每隔 - checkpoint_timeout触发一次,因此从 - idle_replication_slot_timeout超时到下一个检查点使槽失效之间可能会有一些延迟。 - 若要避免这种延迟,用户可以强制执行检查点,以便及时使不活动的槽失效。槽的不活动时间根据其 - pg_replication_slots.inactive_since值计算。 - - - 请注意,空闲超时失效机制不适用于不保留 WAL 的槽,也不适用于正在从主库同步的备库上的槽 - (即pg_replication_slots.synced - 值为true的备库槽)。已同步的槽总是被视为空闲,因为它们不会执行逻辑解码来生成变更。 - - - + + 指定检查点时复制槽允许在 + pg_wal 目录中保留的 WAL 文件最大总量。 + 如果 max_slot_wal_keep_size 为 -1(默认值),复制槽可以保留无限量的 WAL 文件。 + 否则,如果复制槽的 restart_lsn 落后当前 LSN 超过给定大小,使用该槽的备库可能会 + 因为所需 WAL 文件被移除而无法继续复制。可以在 + pg_replication_slots 中查看复制槽的 WAL 可用情况。 + 如果指定值时没有单位,则按兆字节计算。此参数只能在 + postgresql.conf 文件中或服务器命令行上设置。 + + + + + @@ -3771,14 +3158,14 @@ HINT: If it is safe for all REPLICATION users to use this library as an output - 中断那些停止活动超过这个时间量的复制连接。这对发送服务器检测一个费用服务器崩溃或网络中断有用。 - 如果指定值时没有单位,则以毫秒为单位。默认值是 60 秒。值0将禁用超时机制。 + 终止非活动时间超过此值的复制连接。这有助于发送服务器检测备库崩溃或网络中断。 + 如果指定值时没有单位,则按毫秒计算。默认值为 60 秒。值零禁用超时机制。 - 对于跨越多个地理位置分布的集簇,每个位置使用不同的值可以为集簇管理带来更大的灵活性。 - 对于具有低延迟网络连接的备库,较小的值有助于更快的故障检测; - 对于位于远端位置的具有高延迟网络连接的备库,较大的值有助于更好地判断备库的健康状况。 + 对于跨多个地理位置分布的集簇,在各位置使用不同的值可以提高集簇管理的灵活性。 + 对于网络延迟较低的备库,较小的值有助于更快地检测故障; + 对于地处远端、网络延迟较高的备库,较大的值有助于更准确地判断其健康状况。 @@ -3806,7 +3193,10 @@ HINT: If it is safe for all REPLICATION users to use this library as an output 主库 - 这些参数可以在发送复制数据给一个或多个备库的主库上设置。注意除了这些参数之外,在主库上必须设置合适的,并且也启用可选的 WAL 归档(见)。这些参数值与备库无关,尽管你可能希望为了准备好一个备库转变成主库来设置这些参数。 + 这些参数可以在向一个或多个备库发送复制数据的主库上设置。 + 除这些参数外,还必须在主库上适当设置 , + 也可以选择启用 WAL 归档(见 )。 + 这些参数在备库上的取值不影响备库运行,不过也可以预先设置,以备将来提升为主库。 @@ -3822,15 +3212,17 @@ HINT: If it is safe for all REPLICATION users to use this library as an output 所述,这个参数指定一个支持同步复制的备库的列表。 - 可能会有一个或者多个活动的同步备库,在这些备库确认收到它们的数据之后,等待提交的事务将被允许继续下去。 - 同步备库是那些名字出现在这个列表前面,并且当前已连接并且正在实时流式传输数据(如pg_stat_replication视图中streaming的状态所示)的服务器。 + 将有一个或多个活动的同步备库,在这些备库确认收到它们的数据之后,等待提交的事务将被允许继续下去。 + 同步备库是那些名字出现在这个列表中,并且当前已连接并且正在实时流式传输数据(如pg_stat_replication视图中streaming的状态所示)的服务器。 指定多于一台同步备库可以得到非常高的可用性并且能防止数据丢失。 用于这一目的的备库的名称是其application_name设置,它在备库的连接信息中设置。 - 在物理复制备库的情况下,这应该被设置在primary_conninfo设置中,如果设置了,默认是的设置,否则为 walreceiver。 - 对于逻辑复制,可以在订阅的连接信息中设置。对于其他复制流消费者,请参考其文档。 + 对于物理复制备库,应在 primary_conninfo 设置中指定。 + 若已设置 ,则默认使用其值;否则默认值为 walreceiver。 + 对于逻辑复制,可以在订阅的连接信息中设置,默认值为订阅名称。 + 对于其他复制流消费者,请参考其文档。 @@ -3844,11 +3236,11 @@ ANY num_sync ( num_sync指定一种基于优先的同步复制,并且会让事务提交等待,直到它们的WAL记录被复制到基于优先级选择的num_sync台同步备库上为止。例如,设置FIRST 3 (s1, s2, s3, s4)将导致每次提交都等待来自三台较高优先级的备库的答复,这三台备库将从备库s1s2s3以及s4中选出。在该列表中出现较早的备库将被给予较高的优先级,并且将被考虑为同步备库。列表中出现的其他备库表示潜在的同步备库。如果当前的任何同步备库因为某种原因断开连接,它将立刻被下一个最高优先级的备库替代。关键词FIRST是可选的。 + 关键词FIRST加上num_sync指定一种基于优先级的同步复制,并且会让事务提交等待,直到它们的WAL记录被复制到基于优先级选择的num_sync台同步备库上为止。例如,设置FIRST 3 (s1, s2, s3, s4)将导致每次提交都等待来自三台较高优先级的备库的答复,这三台备库将从备库s1s2s3以及s4中选出。在该列表中出现较早的备库将被给予较高的优先级,并且将被考虑为同步备库。列表中出现的其他备库表示潜在的同步备库。如果当前的任何同步备库因为某种原因断开连接,它将立刻被下一个最高优先级的备库替代。关键词FIRST是可选的。 - 关键词ANY加上num_sync指定一种基于规定数量的同步复制,并且会让事务提交等待,直到它们的WAL记录被复制到所列出备库中的至少num_sync台上为止。例如,设置ANY 3 (s1, s2, s3, s4)将导致每次提交会在收到s1s2s3以及s4中任意三台备库的回答后立刻继续下去。 + 关键词ANY加上num_sync指定一种基于法定人数的同步复制,并且会让事务提交等待,直到它们的WAL记录被复制到所列出备库中的至少num_sync台上为止。例如,设置ANY 3 (s1, s2, s3, s4)将导致每次提交会在收到s1s2s3以及s4中任意三台备库的回答后立刻继续下去。 @@ -3874,7 +3266,7 @@ ANY num_sync ( 参数设置为localoff。 + 如果这里没有指定同步备库名称,那么不启用同步复制并且事务提交将不会等待复制。这是默认的配置。即便当同步复制被启用时,个体事务也可以被配置为不等待复制,做法是将参数设置为localoff @@ -3883,33 +3275,32 @@ ANY num_sync ( - synchronized_standby_slots (string) - - synchronized_standby_slots配置参数 - - - - - 逻辑 WAL 发送进程将等待的流复制备库槽名称的逗号分隔列表。 - 逻辑 WAL 发送进程仅在指定复制槽确认接收 WAL 后,才会把解码后的更改发送给插件。 - 这可以确保逻辑复制故障切换槽在相应物理备库接收并刷写这些更改之前,不会消耗这些更改。 - 如果逻辑复制连接旨在故障切换到物理备库,则该备库的物理复制槽应当列在这里。 - 请注意,如果synchronized_standby_slots中指定的槽不存在或无效,逻辑复制将不会继续。 - 此外,使用逻辑故障切换槽的复制管理函数 - pg_replication_slot_advance、 - pg_logical_slot_get_changes和 - pg_logical_slot_peek_changes - 将阻塞,直到synchronized_standby_slots中列出的所有物理槽都确认接收到了 WAL。 - - - 与synchronized_standby_slots中物理复制槽对应的备库必须配置 - sync_replication_slots = true,这样它们才能从主库接收逻辑故障切换槽的更改。 - - - - + + + vacuum_defer_cleanup_age (integer) + + vacuum_defer_cleanup_age 配置参数 + + + + + 指定VACUUMHOT更新延迟清理死行版本的事务数。默认值为零个事务, + 意味着可以尽快移除死行版本,也就是在它们不再对任何打开的事务可见时立即移除。 + 如所述,在为热备服务器提供支持的主库上,你可能希望将此参数设置为非零值。 + 这让备库上的查询有更多时间完成,而不会因过早清理行而发生冲突。 + 但是,由于此值以主库上发生的写事务数计量,很难预测会给备库查询带来多少额外的宽限时间。 + 此参数只能在postgresql.conf文件中或在服务器命令行上设置。 + + + 你也应考虑在备库上设置hot_standby_feedback,作为使用此参数的替代方案。 + + + 这不会阻止清理已经达到old_snapshot_threshold指定年龄的死行。 + + + + @@ -3931,20 +3322,18 @@ ANY num_sync ( 中描述。 如果在这个字符串中有任何选项未被指定,那么将检查相应的环境变量(见)。 如果环境变量也没有被设置,则使用默认值。 - 连接字符串应当指定发送服务器的主机名(或地址),以及端口号(如果它与备库的默认端口不同)。 还要指定发送服务器上具有适当权限的角色所对应的用户名(见)。 如果发送端要求密码认证,还需要提供密码。它既可以直接写在 primary_conninfo 字符串中, 也可以写在备库上的独立 ~/.pgpass 文件中(数据库名使用 replication)。 + 不要在primary_conninfo字符串中指定数据库名。 - 这个参数只能在 postgresql.conf 文件或服务器命令行上设置。 如果在 WAL 接收进程运行时修改该参数,则会向该进程发送信号使其关闭,并期望它使用新设置重新启动 @@ -3965,11 +3354,26 @@ ANY num_sync ( )。 这个参数只能在 postgresql.conf文件或服务器命令行上设置。 - 如果在 WAL 接收进程运行时更改此参数,则该进程将发出关机信号,并预期使用新设置重新启动(除非primary_conninfo为空字符串)。 + 如果在 WAL 接收进程运行时更改此参数,则会向该进程发送关闭信号,并预期它使用新设置重新启动。 如果没有设置primary_conninfo或服务器没有处于备库模式,则此设置无效。 + + promote_trigger_file (string) + + promote_trigger_file 配置参数 + + + + + 指定一个触发文件,该文件的存在会结束备库上的恢复。即使未设置此值,你仍然可以使用pg_ctl promote或调用 + pg_promote()来提升备库。 + 这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 + + + + hot_standby (boolean) @@ -4004,9 +3408,7 @@ ANY num_sync ( num_sync ( num_sync ( )。 - 默认为"关闭"。 此参数只能在postgresql.conf文件或服务器命令行中设置。 - 如果在 WAL 接收进程运行时更改此参数,则该进程将发出关机的信号,并预期使用新设置重新启动。 - + 指定在未使用配置要使用的永久复制槽时,WAL 接收进程是否应在远程实例上创建临时复制槽。默认值为 off。此参数只能在postgresql.conf文件中或服务器命令行上设置。如果在 WAL 接收进程运行时更改此参数,则会向该进程发送信号使其关闭,并预期它使用新设置重新启动。 @@ -4062,9 +3458,9 @@ ANY num_sync ( pg_stat_replication视图看到。 - 备库将报告它已经写入的上一个预写式日志位置、它已经刷到磁盘的上一个位置以及它已经应用的最后一个位置。 + 备库将报告最后写入的预写日志位置、最后刷盘的位置以及最后应用的位置。 这个参数的值是报告之间的最大时间量。 - 每次写入或刷出位置改变时会发送状态更新,或者按这个参数的指定的频度发送,如果设置为非零值。 + 每次写入或刷盘位置改变时会发送状态更新,或者按这个参数的指定的频度发送,如果设置为非零值。 在其他情况下发送更新时忽略此参数;例如,当现有的WAL处理完成或当synchronous_commit设置为remote_apply时。 因此,应用位置可能比真实位置略微滞后。 如果指定值时没有单位,则以秒为单位。 @@ -4084,16 +3480,18 @@ ANY num_sync ( num_sync ( num_sync ( - - recovery_min_apply_delay (integer) - - recovery_min_apply_delay 配置参数 - - - - - - 默认情况下,备库会尽快恢复来自于发送服务器的 WAL 记录。有一份数据的延时拷贝是有用的,它能提供机会纠正数据丢失错误。 - 这个参数允许你将恢复延迟一段指定的时间量。 - 例如,如果你设置这个参数为5min,对于一个事务提交,只有当备库上的系统时钟超过主库报告的提交时间至少 5分钟时,备库才会重放该事务。 - 如果指定值时没有单位,则以毫秒为单位。默认为0,不增加延迟。 - - - - 有可能服务器之间的复制延迟会超过这个参数的值,在这种情况下则不会增加延迟。 - 注意延迟是根据主库上写 WAL 的时间戳以及备库上的当前时间来计算。 - 由于网络延迟或者级联复制配置导致的传输延迟可能会显著地减少实际等待时间。 - 如果主库和备库上的系统时钟不同步,这会导致恢复比预期的更早应用记录。 - 但这不是一个主要问题,因为这个参数有用的设置比服务器之间的典型事件偏差要大得多。 - - - - 只有在事务提交的 WAL 记录上才会发生延迟。其他记录还是会被尽可能快地重放,这不会成为问题,因为 MVCC 可见性规则确保了在对应的提交记录被应用之前它们的效果不会被看到。 - - - - 一旦恢复中的数据库已经达到一致状态,延迟就会产生,直到备库被提升或者触发。在那之后,备库将会结束恢复并且不再等待。 - - - - WAL记录必须保留在备库上,直到准备好应用。因此,较长的延迟将导致WAL文件的积累增加,增加备库的pg_wal目录的磁盘空间需求。 - - - - 这个参数的目的是和流复制部署一起使用,但是,如果指定了该参数,除了崩溃恢复之外所有的情况下都会遵守它。 - 使用这个特性也会让hot_standby_feedback被延迟,这可能导致主库的膨胀,两者一起使用时要小心。 - - - - 当synchronous_commit被设置为remote_apply时,同步复制会受到这个设置的影响,每一个COMMIT都需要等待被应用。 - - - - - - 这个参数只能在postgresql.conf文件中或通过服务器命令行进行设置。 - - - - - - sync_replication_slots (boolean) - - sync_replication_slots配置参数 - - - - - 使物理备库能够从主库同步逻辑故障切换槽,以便逻辑订阅者在故障切换后能够从新的主库恢复复制。 - - - 默认情况下该参数被禁用。该参数只能在postgresql.conf文件中或服务器命令行上设置。 - - - - - - createrole_self_grant (string) - - createrole_self_grant配置参数 - - - - - 如果一个拥有CREATEROLE但不拥有SUPERUSER权限的用户创建了角色,并且此选项被设置为非空值,则新创建的角色将以指定选项授予创建者。 - 该值必须是setinherit或它们的逗号分隔列表。默认值为空字符串,这会禁用此功能。 - - - 此选项的目的是允许非超级用户的CREATEROLE用户自动继承或自动获得对新创建角色执行SET ROLE的能力。 - 由于CREATEROLE用户始终会隐式获得其所创建角色的ADMIN OPTION,因此该用户总是可以通过执行GRANT语句达到相同效果,但自动授予在可用性上更方便。 - 超级用户会自动继承每个角色的权限,并且始终可以切换到任何角色;此设置可用于为CREATEROLE用户提供类似行为。 - - - - - - event_triggers (boolean) - - event_triggers配置参数 - - - - - 允许临时禁用事件触发器的执行,以便对有故障的事件触发器进行故障排查和修复。 - 将其设置为false会禁用所有事件触发器;设置为true则允许所有事件触发器触发,这也是默认值。 - 只有超级用户能更改这个设置。 - - - - - - restrict_nonsystem_relation_kind (string) - - restrict_nonsystem_relation_kind配置参数 - - - - - 设置禁止访问非系统关系的关系类型。该值采用关系类型的逗号分隔列表形式。 - 目前支持的关系类型是viewforeign-table。 - - - - - + + + + + + + + + recovery_min_apply_delay (integer) + + recovery_min_apply_delay 配置参数 + + + + + 默认情况下,备库会尽快恢复来自发送服务器的 WAL 记录。保留一份延迟的数据副本可能很有用,因为它提供了纠正数据丢失错误的机会。此参数允许将恢复延迟指定的时间。例如,将此参数设置为 5min 时,只有当备库系统时间比主库报告的提交时间至少晚五分钟,备库才会重放各事务的提交。如果没有指定单位,则以毫秒计。默认值为零,不增加延迟。 + + + 服务器之间的复制延迟可能超过此参数的值,这种情况下不会增加延迟。注意,延迟根据主库写入的 WAL 时间戳与备库当前时间之差计算。网络延迟或级联复制配置导致的传输延迟,可能显著缩短实际等待时间。如果主库和备库的系统时钟不同步,恢复时可能比预期更早应用记录;但这通常不是主要问题,因为此参数的实用取值远大于服务器间常见的时间偏差。 + + + 延迟仅发生在事务提交的 WAL 记录上。其他记录会尽快重放;这不会造成问题,因为 MVCC 可见性规则确保在对应提交记录被应用之前,它们的效果不会可见。 + + + 恢复中的数据库达到一致状态后开始延迟,直到备库被提升或触发。此后,备库会结束恢复,不再等待。 + + + 此参数旨在用于流复制部署;不过,只要指定了此参数,它就会在除崩溃恢复以外的所有情况下生效。使用此功能也会延迟 hot_standby_feedback,可能导致主库膨胀;同时使用两者时应谨慎。 + + + 当 synchronous_commit 设置为 remote_apply 时,同步复制会受到此设置影响;每个 COMMIT 都必须等待提交被应用。 + + + + + + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 + + + + @@ -4269,30 +3587,16 @@ ANY num_sync ( - max_active_replication_origins (integer) - - max_active_replication_origins配置参数 - - - - - 指定同时可以跟踪多少个复制源(参见),从而实际上限制了服务器上可以创建多少逻辑复制订阅。 - 将其设置为低于当前正在跟踪的复制源数量(体现在pg_replication_origin_status中)会阻止服务器启动。 - 默认值为 10。该参数只能在服务器启动时设置。 - max_active_replication_origins至少必须设置为订阅者上要添加的订阅数量,再加上一些用于表同步的预留。 - - - + - max_logical_replication_workers (integer) + max_logical_replication_workers (int) max_logical_replication_workers配置参数 @@ -4300,16 +3604,15 @@ ANY num_sync ( num_sync ( - max_parallel_apply_workers_per_subscription (integer) - - max_parallel_apply_workers_per_subscription配置参数 - - - - - 每个订阅可使用的并行应用工作进程最大数。该参数控制订阅参数 - streaming = parallel时,对正在进行中的事务流进行并行应用的程度。 - - - 并行应用工作进程从由max_logical_replication_workers定义的池中获取。 - - - 默认值为 2。该参数只能在postgresql.conf文件中或服务器命令行上设置。 - - - + @@ -4403,150 +3687,127 @@ ANY num_sync ( + + + + enable_bitmapscan (boolean) - 位图扫描 + 位图扫描 - enable_bitmapscan配置参数 + enable_bitmapscan 配置参数 - - 允许或禁止查询规划器使用位图扫描计划类型。默认值是on。 + 启用或禁用查询规划器对位图扫描计划类型的使用。默认值为 on - - + + + - - enable_distinct_reordering (boolean) - - enable_distinct_reordering配置参数 - - - - - 启用或禁用查询规划器重新排序DISTINCT键以匹配输入路径路径键的能力。默认值为on。 - - - - + + enable_gathermerge (boolean) - enable_gathermerge配置参数 + enable_gathermerge 配置参数 - - 启用或者禁用查询规划器对收集归并计划类型的使用。默认值是on。 + 启用或禁用查询规划器对收集归并计划类型的使用。默认值为 on - - + + - - enable_group_by_reordering (boolean) - - enable_group_by_reordering配置参数 - - - - - 控制查询规划器是否生成让GROUP BY键按照计划子节点(例如索引扫描)的键顺序排序的计划。 - 禁用时,规划器只会按ORDER BY子句(如果存在)来安排GROUP BY键的顺序。 - 启用时,规划器会尝试生成更高效的计划。默认值为on。 - - - - + enable_hashagg (boolean) - enable_hashagg配置参数 + enable_hashagg 配置参数 - - 允许或禁用查询规划器使用哈希聚合计划类型。默认值是on。 + 启用或禁用查询规划器对哈希聚合计划类型的使用。默认值为 on - + + enable_hashjoin (boolean) - enable_hashjoin配置参数 + enable_hashjoin 配置参数 - - 允许或禁止查询规划器使用哈希连接计划类型。默认值是on。 + 启用或禁用查询规划器对哈希连接计划类型的使用。默认值为 on - + + enable_incremental_sort (boolean) enable_incremental_sort 配置参数 - - 启用或禁用查询规划器对增量排序步骤的使用。默认为on。 + 启用或禁用查询规划器对增量排序步骤的使用。默认值为 on - + + + + enable_indexscan (boolean) - 索引扫描 + 索引扫描 - enable_indexscan配置参数 + enable_indexscan 配置参数 - - 允许或禁止查询规划器使用索引扫描计划类型。默认值是on。 + 启用或禁用查询规划器对索引扫描和仅索引扫描计划类型的使用。默认值为 on。另请参见 - enable_indexonlyscan (boolean) - enable_indexonlyscan配置参数 + enable_indexonlyscan 配置参数 - - 允许或禁止查询规划器使用只用索引扫描计划类型(见)。默认值是on。 + 启用或禁用查询规划器对仅索引扫描计划类型的使用(参见 )。默认值为 on。还必须启用 ,查询规划器才会考虑仅索引扫描。 - + + enable_material (boolean) - enable_material配置参数 + enable_material 配置参数 @@ -4557,8 +3818,9 @@ ANY num_sync ( + + enable_memoize (boolean) enable_memoize 配置参数 @@ -4575,26 +3837,27 @@ ANY num_sync ( + + enable_mergejoin (boolean) - enable_mergejoin配置参数 + enable_mergejoin 配置参数 - - 允许或禁止查询规划器使用归并连接计划类型。默认值是on。 + 启用或禁用查询规划器对归并连接计划类型的使用。默认值为 on - + + enable_nestloop (boolean) - enable_nestloop配置参数 + enable_nestloop 配置参数 @@ -4620,17 +3883,17 @@ ANY num_sync ( + + enable_parallel_hash (boolean) - enable_parallel_hash配置参数 + enable_parallel_hash 配置参数 - - 允许或禁止查询规划器对并行哈希使用哈希连接计划类型。如果哈希连接计划也没有启用,这个参数没有效果。默认值是on。 + 启用或禁用查询规划器对使用并行哈希的哈希连接计划类型的使用。如果没有同时启用哈希连接计划,此参数不起作用。默认值为 on @@ -4650,70 +3913,41 @@ ANY num_sync ( + + + + + + + + enable_partitionwise_join (boolean) - enable_partitionwise_join配置参数 + enable_partitionwise_join 配置参数 - - 允许或者禁止查询规划器使用面向分区的连接,这使得分区表之间的连接以连接匹配的分区的方式来执行。 - 面向分区的连接当前只适用于连接条件包括所有分区键的情况,连接条件必须是相同的数据类型并且子分区集合要1对1匹配。 - 由于面向分区的连接规划在规划期间会使用可观的CPU时间和内存,所以默认值为off。 + 启用或禁用查询规划器对分区连接的使用,使分区表之间的连接可以通过连接相匹配的分区来完成。分区连接目前仅适用于连接条件包含所有分区键的情况;这些分区键必须具有相同的数据类型,并且子分区集合必须一一匹配。启用此设置后,最终计划中内存用量受 work_mem 限制的节点数量可能随所扫描分区的数量线性增加。这可能大幅增加查询执行期间的总内存消耗。查询规划在内存和 CPU 方面的开销也会显著增加。默认值为 off - enable_partitionwise_aggregate (boolean) - enable_partitionwise_aggregate配置参数 + enable_partitionwise_aggregate 配置参数 - - 启用或禁用查询规划器使用分区分组或聚合的功能,该功能允许在分区表上分别对每个分区执行分组或聚合操作。 - 如果GROUP BY子句不包括分区键,那么只能在每个分区的基础上执行部分聚合,并且必须在稍后进行最终化处理。 - 由于分区分组或聚合在规划期间可能会使用更多的CPU时间和内存,因此默认情况下为off。 + 启用或禁用查询规划器对分区分组或聚合的使用,使分区表上的分组或聚合可以在各个分区上分别执行。如果 GROUP BY 子句不包含分区键,则只能在各分区上执行部分聚合,随后还必须进行最终处理。启用此设置后,最终计划中内存用量受 work_mem 限制的节点数量可能随所扫描分区的数量线性增加。这可能大幅增加查询执行期间的总内存消耗。查询规划在内存和 CPU 方面的开销也会显著增加。默认值为 off - - - - - enable_presorted_aggregate (boolean) - - enable_presorted_aggregate配置参数 - - - - - 控制查询规划器是否生成能够提供预排序行的计划,以满足带有ORDER BYDISTINCT的聚合函数所要求的输入顺序。 - 禁用时,执行器在执行这类聚合函数前总是需要先排序。启用时,规划器会尝试生成更高效的计划。 - 默认值为on。 - - - - - - enable_self_join_elimination (boolean) - - enable_self_join_elimination配置参数 - - - - - 启用或禁用查询规划器的一项优化,该优化会分析查询树并将自连接替换为语义等价的单次扫描。 - 目前只考虑普通表。默认值为on。 - - - + + - + enable_seqscan (boolean) @@ -5167,7 +4401,7 @@ ANY num_sync ( + plan_cache_mode (enum) @@ -5299,24 +4533,7 @@ SELECT * FROM parent WHERE key = 2400; - - - recursive_worktable_factor (floating point) - - recursive_worktable_factor配置参数 - - - - - 设置规划器对递归查询 - 的工作表的平均大小的估计值,作为查询初始非递归项的估计大小的倍数。 - 这有助于规划器选择将工作表与查询的其他表连接的最合适方法。 - 默认值为10.0。当递归从一步到下一步的fan-out较低时,如最短路径查询中的示例,使用较小的值(如1.0)可能有所帮助。 - 图分析查询可能会从大于默认值的设置中受益。 - - - @@ -5836,30 +5053,7 @@ local0.* /var/log/postgresql - - - log_startup_progress_interval (integer) - - log_startup_progress_interval配置参数 - - - - - - 设置启动进程在长时间运行的操作仍在进行时记录消息的时间间隔, - 以及该操作进一步进展消息之间的间隔时间。默认值为10秒。 - 设置为0会禁用该功能。如果未指定单位, - 则将其视为毫秒。此设置分别应用于每个操作。 - 此参数只能在postgresql.conf文件或服务器命令行中设置。 - - - 例如,如果同步数据目录需要25秒,然后重置不记录 WAL 的关系需要8秒,如果此设置的默认值为10秒, - 那么在数据目录同步进行了10秒后,将记录一条消息,再在进行了20秒后记录一条消息, - 但对于重置不记录 WAL 的关系不会记录任何消息。 - - - @@ -5970,7 +5164,7 @@ local0.* /var/log/postgresql - application_name可以是任意小于NAMEDATALEN个字符(标准编译中是 64 个字符)的字符串。这通常由一个应用通过到服务器的连接设置。该名称将被显示在pg_stat_activity视图中并被包括在 CSV 日志项中。它也会被通过包括在普通日志项中。只有可打印 ASCII 字符能被使用在application_name之中。其他字符将被替换为问号(?)。 + application_name可以是任意小于NAMEDATALEN个字符(标准编译中是 64 个字符)的字符串。应用通常在连接服务器时设置此值。该名称将被显示在pg_stat_activity视图中并被包括在 CSV 日志项中。它也会被通过包括在普通日志项中。只有可打印 ASCII 字符能被使用在application_name之中。其他字符将被替换为问号(?)。 @@ -6032,10 +5226,10 @@ local0.* /var/log/postgresql 每次由自动清理执行的操作都会被记录,如果运行时间至少达到指定时间。将此设置为零会记录所有自动清理操作。 - -1会禁用记录自动清理操作。如果未指定单位,则将其视为毫秒。 + -1(默认值)会禁用记录自动清理操作。如果未指定单位,则将其视为毫秒。 例如,如果将其设置为250ms,则所有运行时间为250ms或更长的自动清理和分析都将被记录。 此外,当此参数设置为任何值而不是-1时,如果由于冲突的锁定或同时删除的关系而跳过自动清理操作,则会记录消息。 - 默认值为10min。启用此参数可帮助跟踪自动清理活动。 + 启用此参数可帮助跟踪自动清理活动。 此参数只能在postgresql.conf文件或服务器命令行中设置;但可以通过更改表存储参数来覆盖对单个表的设置。 @@ -6059,77 +5253,22 @@ local0.* /var/log/postgresql - - log_connections (string) + log_connections (boolean) - log_connections配置参数 + log_connections 配置参数 - - - 控制是否记录服务器每次连接的各个阶段。默认值为空字符串 - '',表示禁用所有连接日志。下列选项既可以单独指定, - 也可以用逗号分隔的列表指定: - - -
- 连接日志选项 - - - - - - 名称 - 说明 - - - - - receipt - 记录收到连接。 - - - authentication - 记录认证方法用于识别用户的原始身份。在大多数情况下,该身份字符串与PostgreSQL用户名一致,但某些第三方认证方法可能会在服务器存储之前修改原始用户标识符。无论此设置为何值,认证失败始终都会被记录。 - - - authorization - 记录授权成功完成。此时连接已经建立,但后端尚未完全初始化。日志消息会包含授权后的用户名,以及数据库名和应用名(如果适用)。 - - - setup_durations - 记录从 postmaster 接受传入连接开始,到连接准备好执行第一条查询为止,建立连接并完成后端初始化所花费的时间。日志消息会包含三个时长:总设置时长、fork 新后端所花费的时间,以及用户认证所花费的时间。 - - - all - 一个便捷别名,相当于指定所有选项。如果在其他选项列表中包含all,则会记录连接的所有方面。 - - - -
- - - 断开连接的日志由单独控制。 - - - - 出于向后兼容性考虑,onoff、 - truefalseyes、 - no10仍然受支持。 - 正向值等价于指定receiptauthentication和 - authorization选项。 - - - 只有超级用户和具有适当SET权限的用户可以在会话开始时更改此参数, - 并且在会话内部完全不能更改。 + 记录每次尝试连接服务器的操作,以及客户端认证(如有必要)和授权的成功完成。 + 只有超级用户可以在会话开始时更改此参数,在会话期间则完全不能更改。 + 默认值为 off - - 某些客户端程序(例如psql)在要求密码时会尝试连接两次,因此重复的收到连接消息并不一定表示一个错误。 + 某些客户端程序(例如 psql)在判断是否需要密码时会尝试连接两次, + 因此重复的收到连接消息并不一定表示有问题。
@@ -6372,7 +5511,7 @@ local0.* /var/log/postgresql %% - 纯文字 % + 字面字符 % @@ -6406,7 +5545,7 @@ FROM pg_stat_activity; - Syslog产生自己的时间戳和进程 ID 信息,因此如果你记录到syslog你可能不希望包括哪些转义。 + Syslog产生自己的时间戳和进程 ID 信息,因此如果你记录到syslog你可能不希望包括那些转义。 @@ -6468,20 +5607,7 @@ log_line_prefix = '%m [%p] %q%u@%d/%a ' - - log_lock_failures (boolean) - - log_lock_failures配置参数 - - - - - 控制当获取锁失败时是否生成详细日志消息。这有助于分析锁失败的原因。 - 目前,仅支持由于SELECT NOWAIT导致的锁失败。 - 默认值为off。只有超级用户能更改这个设置。 - - - + @@ -6955,12 +6081,12 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 为不同目的设置标识这个数据库集簇(实例)的名称。此集簇名称出现在该集簇中所有服务器进程的进程标题中。 - 此外,它还是备库连接的默认应用名称。(参见 .) + 设置一个用于各种目的、标识此数据库集簇(实例)的名称。集簇名称会出现在此集簇所有服务器进程的进程标题中。 + 此外,它还是备库连接的默认应用名称(参见)。 - 这个名称可以是任何长度不超过NAMEDATALEN个字符(在标准编译中是 64字符)的任何字符串。只有可打印的 ASCII 字符能被用在cluster_name值中。其他字符将被替换为问号(?)。如果这个参数被设置为空字符串''(也是默认值),将不会显示名称。这个参数只能在服务器启动时设置。 + 这个名称可以是任何长度少于NAMEDATALEN个字符(在标准编译中是 64字符)的任何字符串。只有可打印的 ASCII 字符能被用在cluster_name值中。其他字符将被替换为问号(?)。如果这个参数被设置为空字符串''(也是默认值),将不会显示名称。这个参数只能在服务器启动时设置。 @@ -6990,15 +6116,17 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; 运行时统计数据 - + - 累积查询和索引统计 + 查询和索引统计信息收集器 + - 这些参数控制服务器范围内的累积统计系统。 - 启用后,收集的数据可以通过pg_statpg_statio - 系列系统视图进行访问。有关更多信息,请参阅。 - + 这些参数控制服务器范围内的统计信息收集功能。 + 启用统计信息收集后,产生的数据可以通过pg_stat和 + pg_statio系列系统视图进行访问。 + 更多信息请参阅。 +
@@ -7054,40 +6182,24 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - - track_cost_delay_timing (boolean) - - track_cost_delay_timing配置参数 - - - - - 启用基于成本的清理延迟计时(参见)。 - 默认情况下该参数关闭,因为它需要反复查询操作系统当前时间,在某些平台上可能带来显著开销。 - 你可以使用pg_test_timing来衡量系统上的计时开销。 - 基于成本的清理延迟计时信息会显示在pg_stat_progress_vacuum、 - pg_stat_progress_analyze中, - 也会显示在带有VERBOSE选项的VACUUMANALYZE输出中, - 并且当设置了时,autovacuum 还会为自动清理和自动分析记录这些信息。 - 只有超级用户能更改这个设置。 - - - - + track_io_timing (boolean) - track_io_timing配置参数 + track_io_timing 配置参数 - - 启用数据库I/O调用的计时。 默认情况下,此参数处于关闭状态,因为它将重复查询操作系统的当前时间,这可能会在某些平台上造成显著的开销。 您可以使用工具来测量系统上计时的开销。 - I/O计时信息显示在 - pg_stat_database中,在的输出中,当使用BUFFERS选项时,在的输出中,当使用VERBOSE选项时,由autovacuum执行自动清理和自动分析时,当设置了时,以及由。 - 只有超级用户能更改这个设置。 + 启用数据库 I/O 调用的计时。此参数默认关闭,因为计时需要反复向操作系统查询 + 当前时间,在某些平台上可能会产生显著开销。可以使用 工具 + 测量本系统上的计时开销。I/O 计时信息会显示在 + pg_stat_database 中、 + 使用 BUFFERS 选项的 输出中, + autovacuum 也会在执行自动清理和自动分析时输出这些信息 + (需设置 ), + 同样提供这些信息。只有超级用户可以更改此设置。 @@ -7102,14 +6214,8 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 启用WAL I/O调用的定时。此参数默认关闭,因为它将重复查询操作系统的当前时间, - 这可能会在某些平台上造成显著的开销。 - 您可以使用pg_test_timing工具来 - 测量系统上定时的开销。 - I/O定时信息显示在 - pg_stat_wal中。 - 只有超级用户能更改这个设置。 - + 启用 WAL I/O 调用的计时。此参数默认关闭,因为它会反复向操作系统查询当前时间,可能在某些平台上产生显著开销。可以使用 pg_test_timing 工具测量系统上的计时开销。I/O 计时信息显示在 pg_stat_wal 中。只有超级用户才能更改此设置。 + @@ -7137,36 +6243,23 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - - - stats_fetch_consistency (enum) + + stats_temp_directory (string) - stats_fetch_consistency配置参数 + stats_temp_directory配置参数 - - 确定在事务中多次访问累积统计信息时的行为。当设置为 - none时,每次访问都会重新从共享内存中获取计数器。 - 当设置为cache时,对对象的统计信息的第一次访问会将这些统计信息缓存, - 直到事务结束,除非调用pg_stat_clear_snapshot()。 - 当设置为snapshot时,第一次访问统计信息会缓存当前数据库中所有可访问的统计信息, - 直到事务结束,除非调用pg_stat_clear_snapshot()。 - 在事务中更改此参数会丢弃统计快照。默认值为cache。 + 设置存放临时统计信息数据的目录。它既可以是相对于数据目录的路径,也可以是绝对路径。默认值是 + pg_stat_tmp。将其指向基于 RAM 的文件系统可以减少物理 I/O 需求,并可能提升性能。 + 这个参数只能在postgresql.conf文件中或服务器命令行上设置。 - - - - none适用于监控系统。如果值只被访问一次,它是最有效的。 - cache确保重复访问产生相同的值,这对涉及自连接的查询很重要。 - snapshot在交互式检查统计信息时可能很有用,但开销较高, - 特别是存在许多数据库对象时。 - - + + @@ -7204,7 +6297,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 确认只有一个查询标识符被计算和显示,如果一个查询标识符已经被计算,扩展计算标识符将抛出一个错误。 + 为确保只有一个查询标识符被计算和显示,计算查询标识符的扩展在查询标识符已被计算时应当抛出一个错误。 @@ -7251,21 +6344,13 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv;
- - - 清理 + + 自动清理 自动清理 - 配置参数 - - - - 这些参数控制清理的行为。有关清理的目的和职责的更多信息,请参阅。 - - - - 自动清理 + 配置参数 + 这些设置控制autovacuum特性的行为。详情请参考 @@ -7292,27 +6377,12 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 注意即使该参数被禁用,系统也会在需要防止事务ID回卷时发起清理进程。详情请见。 + 注意即使该参数被禁用,系统也会在需要防止事务ID回卷时发起自动清理进程。详情请见 - - autovacuum_worker_slots (integer) - - autovacuum_worker_slots配置参数 - - - - - 指定为 autovacuum 工作进程保留的后端槽位数。默认通常是 16 个槽位,但如果内核设置不支持(如 initdb 期间所判定),则可能少于此数。 - 该参数只能在服务器启动时设置。 - - - 更改该值时,也应考虑调整。 - - - + @@ -7326,9 +6396,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; 指定能同时运行的自动清理进程(除了自动清理启动器之外)的最大数量。默认值为3。该参数只能在服务器启动时设置。 - - 请注意,如果该值被设置得高于,将不会产生任何效果,因为 autovacuum 工作进程是从该设置建立的槽位池中获取的。 - + @@ -7342,29 +6410,13 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 指定自动清理在任意给定数据库上运行的最小延迟。在每一轮中后台进程检查数据库并根据需要为数据库中的表发出VACUUMANALYZE命令。 + 指定自动清理在任意给定数据库上各次运行之间的最小间隔。在每一轮中后台进程检查数据库并根据需要为数据库中的表发出VACUUMANALYZE命令。 如果指定值时没有单位,则以秒为单位。默认值为1分钟(1min)。该参数只能在postgresql.conf文件或在服务器命令行上设置。 - - autovacuum_vacuum_max_threshold (integer) - - autovacuum_vacuum_max_threshold配置参数 - - - - - 指定在任意一个表上触发VACUUM所需更新或删除元组数的最大值,也就是对 - autovacuum_vacuum_threshold和 - autovacuum_vacuum_scale_factor计算结果所施加的上限。 - 默认值为 100,000,000 个元组。如果指定为-1,autovacuum 将不会对触发 - VACUUM所需的更新或删除元组数强制施加最大值。 - 该参数只能在postgresql.conf文件中或服务器命令行上设置;但可以通过更改表存储参数覆盖单个表的该设置。 - - - + @@ -7533,160 +6585,13 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 指定用于自动VACUUM操作中的代价限制值。如果指定-1(默认值),则使用值。注意该值被按比例地分配到运行中的自动清理工作者上(如果有多个),因此每一个工作者的限制值之和不会超过这个变量中的值。该参数只能在postgresql.conf文件或在服务器命令中设置。但是对个别表可以通过修改表存储参数来覆盖该设置。 - - - - - - - - - 默认行为 - - - - vacuum_truncate (boolean) - - vacuum_truncate配置参数 - - - - - 启用或禁用 vacuum 尝试截断表末尾的空页。默认值为true。 - 如果为true,则VACUUM和 autovacuum 会执行截断,并将这些页面占用的磁盘空间返还给操作系统。 - 请注意,截断需要获取表上的ACCESS EXCLUSIVE锁。 - 如果在VACUUM中指定了TRUNCATE参数,它将覆盖该参数的值。 - 也可以通过修改表存储参数来为单个表覆盖此设置。 - - - - - - - - 冻结 - - - 这些设置控制旧行版本的冻结。更多信息请参阅。 - - - - - vacuum_freeze_table_age (integer) - - vacuum_freeze_table_age配置参数 - - - - - 当表的pg_class.relfrozenxid字段达到该设置指定的年龄时,VACUUM会执行激进扫描。激进扫描与常规VACUUM不同,它会访问每一个可能包含未冻结 XID 或 MXID 的页面,而不仅仅是那些可能包含死元组的页面。默认值是 1.5 亿个事务。尽管用户可以将该值设置为 0 到 20 亿之间的任意值,VACUUM会悄悄将有效值调整为的 95%,从而在触发防回卷 autovacuum 之前仍有机会执行一次常规手工VACUUM。更多信息请参见。 - - - - - - vacuum_freeze_min_age (integer) - - vacuum_freeze_min_age配置参数 - - - - - 指定VACUUM在扫描表时用来决定是否冻结行版本的切断年龄(以事务计)。默认值是 5000 万个事务。尽管用户可以将该值设置为 0 到 10 亿之间的任意值,VACUUM会悄悄将有效值调整为的一半,这样强制 autovacuum 之间就不会间隔过短。更多信息请参见。 - - - - - - vacuum_failsafe_age (integer) - - vacuum_failsafe_age配置参数 - - - - - 指定表的pg_class.relfrozenxid字段在VACUUM采取特别措施以避免系统范围事务 ID 回卷失败之前所允许达到的最大年龄(以事务计)。这是VACUUM的最后防线。失效保护通常会在防止事务 ID 回卷的 autovacuum 已经运行了一段时间后触发,但也有可能在任何VACUUM期间触发。 - - - 当失效保护被触发时,将不再应用任何有效的基于成本的延迟,并且会跳过进一步的非关键维护任务(例如索引 vacuum)。 - - - 默认值为 16 亿个事务。尽管用户可以将该值设置为 0 到 21 亿之间的任意值,VACUUM会悄悄将有效值调整为不低于的 105%。 - - - - - - vacuum_multixact_freeze_table_age (integer) - - vacuum_multixact_freeze_table_age配置参数 - - - - - 当表的pg_class.relminmxid字段达到该设置指定的年龄时,VACUUM会执行激进扫描。激进扫描与常规VACUUM不同,它会访问每一个可能包含未冻结 XID 或 MXID 的页面,而不是只扫描那些可能包含死元组的页面。默认值是 1.5 亿个 multixact。尽管用户可以将该值设置为 0 到 20 亿之间的任意值,VACUUM会悄悄将有效值调整为的 95%,从而在触发防回卷 autovacuum 之前仍有机会执行一次常规手工VACUUM。更多信息请参见。 - - - - - - vacuum_multixact_freeze_min_age (integer) - - vacuum_multixact_freeze_min_age配置参数 - - - - - 指定VACUUM在扫描表时用来决定是否将 multixact ID 替换为较新的事务 ID 或 multixact ID 的切断年龄(以 multixact 计)。默认值是 5000 万个 multixact。尽管用户可以将该值设置为 0 到 10 亿之间的任意值,VACUUM会悄悄将有效值调整为的一半,这样强制 autovacuum 之间就不会间隔过短。更多信息请参见。 - - - - - - vacuum_multixact_failsafe_age (integer) - - vacuum_multixact_failsafe_age配置参数 - - - - - 指定表的pg_class.relminmxid字段在VACUUM采取特别措施以避免系统范围 multixact ID 回卷失败之前所允许达到的最大年龄(以 multixact 计)。这是VACUUM的最后防线。失效保护通常会在防止事务 ID 回卷的 autovacuum 已经运行了一段时间后触发,但也有可能在任何VACUUM期间触发。 - - - 当失效保护被触发时,将不再应用任何有效的基于成本的延迟,并且会跳过进一步的非关键维护任务(例如索引 vacuum)。 - - - 默认值为 16 亿个 multixact。尽管用户可以将该值设置为 0 到 21 亿之间的任意值,VACUUM会悄悄将有效值调整为不低于的 105%。 + 指定用于自动VACUUM操作中的代价限制值。如果指定-1(默认值),则使用值。注意该值被按比例地分配到运行中的自动清理工作进程上(如果有多个),因此每一个工作进程的限制值之和不会超过这个变量中的值。该参数只能在postgresql.conf文件或在服务器命令中设置。但是对个别表可以通过修改表存储参数来覆盖该设置。 - - vacuum_max_eager_freeze_failure_rate (floating point) - - vacuum_max_eager_freeze_failure_rate配置参数 - - - - - 指定VACUUM在积极扫描模式下可以扫描但未能在可见性映射中设置为 all-frozen 的页面数量占整个关系总页面数的比例,超过该比例后就会禁用积极扫描。值0表示完全禁用积极扫描。默认值为0.03(3%)。 - - - 请注意,当积极扫描启用时,只有冻结失败才会计入上限,成功的冻结不会计入。成功冻结的页面在内部会被限制为关系中所有 all-visible 但未 all-frozen 页面数的 20%。对成功冻结页面设置上限有助于将成本分摊到多次常规 vacuum 中,并限制在下次积极 vacuum 之前页面再次被修改时积极冻结可能带来的浪费。 - - - 这个参数只能在postgresql.conf文件中或服务器命令行上设置; - 但也可以通过修改 - 对应的表存储参数 - 为单个表覆盖该设置。关于调整清理冻结行为的更多信息,见 - 。 - - - - - + @@ -7727,7 +6632,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; search_path配置参数 - pathfor schemas + 路径用于模式 @@ -7820,7 +6725,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; default_tablespace配置参数 - tablespacedefault + 表空间默认 @@ -7925,7 +6830,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; default_transaction_isolation (enum) - transaction isolation level + 事务隔离级别 设置默认值 @@ -7948,7 +6853,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; default_transaction_read_only (boolean) - read-only transaction + 只读事务 设置默认值 @@ -7971,7 +6876,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; default_transaction_deferrable (boolean) - deferrable transaction + 可延迟事务 设置默认值 @@ -7998,7 +6903,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; transaction_isolation (enum) - transaction isolation level + 事务隔离级别 transaction_isolation配置参数 @@ -8018,7 +6923,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; transaction_read_only (boolean) - read-only transaction + 只读事务 transaction_read_only 配置参数 @@ -8038,7 +6943,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; transaction_deferrable (boolean) - deferrable transaction + 可延迟事务 transaction_deferrable 配置参数 @@ -8114,30 +7019,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - - transaction_timeout (integer) - - transaction_timeout配置参数 - - - - - 终止任何在一个事务中运行时间超过指定时长的会话。该限制既适用于显式事务(以BEGIN开始),也适用于与单条语句对应的隐式事务。 - 如果指定值时没有单位,则以毫秒为单位。零值(默认值)将禁用该超时。 - - - 如果transaction_timeout短于或等于idle_in_transaction_session_timeoutstatement_timeout,则较长的超时将被忽略。 - - - 不建议在postgresql.conf中设置transaction_timeout,因为它会影响所有会话。 - - - - 预备事务不受该超时影响。 - - - - + @@ -8160,61 +7042,151 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 我们不推荐在postgresql.conf中设置lock_timeout,因为它会影响所有会话。 + 我们不推荐在postgresql.conf中设置lock_timeout,因为它会影响所有会话。 + + + + + + + idle_in_transaction_session_timeout (integer) + + idle_in_transaction_session_timeout 配置参数 + + + + + + 终止任何已经闲置(这是指,等待客户端查询)超过这个参数所指定时间量的打开事务的会话。 + 如果这个值指定时没有单位,它被设为毫秒。 + 零值(默认)禁用超时。 + + + + 此选项可以用于确保空闲会话不会在不合理的时间内持有锁。 + 即使在没有持有重要锁的时候,打开的事务也会阻止清理最近死亡、且可能只对该事务可见的元组;所以长时间保持空闲会导致表膨胀。 + 详见。 + + + + + + + idle_session_timeout (integer) + + idle_session_timeout 配置参数 + + + + + + 终止任何空闲的会话(也就是,等待客户端查询),但不在打开的事务中,且超过指定的时间量。 + 如果指定值时不带单位,其单位采用毫秒。 + 零值时(默认)禁用超时。 + + + + 不像打开事务的情况,没有事务的空闲会话不会给服务器带来很大的开销,因此启用此超时的需要比idle_in_transaction_session_timeout更少。 + + + + 注意不要对通过连接池软件或其他中间件建立的连接强制执行此超时,因为这样的层可能不会很好地响应意外的连接关闭。 + 只对交互会话启用此超时可能是帮助的,也许只对特定用户应用它。 + + + + + + vacuum_freeze_table_age (integer) + + vacuum_freeze_table_age配置参数 + + + + + 当表的pg_class.relfrozenxid字段达到该设置指定的年龄时,VACUUM会执行激进扫描。激进扫描与常规VACUUM不同,它会访问每一个可能包含未冻结 XID 或 MXID 的页面,而不仅仅是那些可能包含死元组的页面。默认值是 1.5 亿个事务。尽管用户可以将该值设置为 0 到 20 亿之间的任意值,VACUUM会悄悄将有效值限制为不超过的 95%,从而在触发防回卷 autovacuum 之前仍有机会执行一次常规手工VACUUM。更多信息请参见。 + + + + + + vacuum_freeze_min_age (integer) + + vacuum_freeze_min_age配置参数 + + + + + 指定VACUUM在扫描表时用来决定是否冻结行版本的切断年龄(以事务计)。默认值是 5000 万个事务。尽管用户可以将该值设置为 0 到 10 亿之间的任意值,VACUUM会悄悄将有效值限制为不超过的一半,这样强制 autovacuum 之间就不会间隔过短。更多信息请参见。 + + + + + + vacuum_failsafe_age (integer) + + vacuum_failsafe_age配置参数 + + + + + 指定表的pg_class.relfrozenxid字段在VACUUM采取特别措施以避免系统范围事务 ID 回卷失败之前所允许达到的最大年龄(以事务计)。这是VACUUM的最后防线。失效保护通常会在防止事务 ID 回卷的 autovacuum 已经运行了一段时间后触发,但也有可能在任何VACUUM期间触发。 + + + 当失效保护被触发时,将不再应用任何有效的基于代价的延迟,并且会跳过进一步的非关键维护任务(例如索引清理)。 + + + 默认值为 16 亿个事务。尽管用户可以将该值设置为 0 到 21 亿之间的任意值,VACUUM会悄悄将有效值调整为不低于的 105%。 + + + + + + vacuum_multixact_freeze_table_age (integer) + + vacuum_multixact_freeze_table_age配置参数 + + + + + 当表的pg_class.relminmxid字段达到该设置指定的年龄时,VACUUM会执行激进扫描。激进扫描与常规VACUUM不同,它会访问每一个可能包含未冻结 XID 或 MXID 的页面,而不是只扫描那些可能包含死元组的页面。默认值是 1.5 亿个多事务。尽管用户可以将该值设置为 0 到 20 亿之间的任意值,VACUUM会悄悄将有效值限制为不超过的 95%,从而在触发防回卷 autovacuum 之前仍有机会执行一次常规手工VACUUM。更多信息请参见 - - - idle_in_transaction_session_timeout (integer) + + vacuum_multixact_freeze_min_age (integer) - idle_in_transaction_session_timeout 配置参数 + vacuum_multixact_freeze_min_age配置参数 - - - 终止任何已经闲置(这是指,等待客户端查询)超过这个参数所指定时间量的打开事务的会话。 - 如果这个值指定时没有单位,它被设为毫秒。 - 零值(默认)禁用超时。 - - - 此选项可以用于确保空闲会话不会在不合理的时间内持有锁。 - 即使在没有持有重要锁的时候,打开的事务也会阻止清理最近死亡、且可能只对该事务可见的元组;所以长时间保持空闲会导致表膨胀。 - 详见。 + 指定VACUUM在扫描表时用来决定是否将多事务 ID 替换为较新的事务 ID 或多事务 ID 的切断年龄(以多事务计)。默认值是 500 万个多事务。尽管用户可以将该值设置为 0 到 10 亿之间的任意值,VACUUM会悄悄将有效值限制为不超过的一半,这样强制 autovacuum 之间就不会间隔过短。更多信息请参见 - - - idle_session_timeout (integer) + + vacuum_multixact_failsafe_age (integer) - idle_session_timeout 配置参数 + vacuum_multixact_failsafe_age 配置参数 - - 终止任何空闲的会话(也就是,等待客户端查询),但不在打开的事务中,且超过指定的时间量。 - 如果指定值时不带单位,其单位采用毫秒。 - 零值时(默认)禁用超时。 + 指定表的 pg_class.relminmxid 字段在 VACUUM 采取特别措施避免系统范围的多事务 ID 回卷故障之前,所能达到的最大年龄(以多事务计)。这是 VACUUM 的最后手段。失效保护通常会在防止事务 ID 回卷的自动清理已经运行一段时间后触发,但也可能在任何 VACUUM 期间触发。 - - 不像打开事务的情况,没有事务的空闲会话不会给服务器带来很大的开销,因此启用此超时的需要比idle_in_transaction_session_timeout更少。 + 触发失效保护后,任何正在生效的基于代价的延迟都将不再应用,后续非必要的维护任务(例如索引清理)也会被跳过。 - - 注意不要对通过连接池软件或其他中间件建立的连接强制执行此超时,因为这样的层可能不会很好地响应意外的连接关闭。 - 只对交互会话启用此超时可能是帮助的,也许只对特定用户应用它。 + 默认值为 16 亿个多事务。虽然用户可以将此值设置为 0 到 21 亿之间的任意值,VACUUM 仍会将实际生效值自动调整为不低于 的 105%。 - + bytea_output (enum) @@ -8258,7 +7230,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; SET XML OPTION - XML option + XML 选项 @@ -8296,6 +7268,20 @@ SET XML OPTION { DOCUMENT | CONTENT }; + + restrict_nonsystem_relation_kind (string) + + restrict_nonsystem_relation_kind配置参数 + + + + + 设置禁止访问非系统关系的关系类型。该值采用关系类型的逗号分隔列表形式。 + 目前支持的关系类型是viewforeign-table。 + + + + @@ -8344,7 +7330,7 @@ SET XML OPTION { DOCUMENT | CONTENT }; TimeZone配置参数 - time zone + 时区 @@ -8360,7 +7346,7 @@ SET XML OPTION { DOCUMENT | CONTENT }; timezone_abbreviations配置参数 - time zone names + 时区名称 @@ -8374,11 +7360,11 @@ SET XML OPTION { DOCUMENT | CONTENT }; extra_float_digits (integer) - significant digits + 有效数字 - floating-point - display + 浮点数 + 显示 extra_float_digits配置参数 @@ -8406,7 +7392,7 @@ SET XML OPTION { DOCUMENT | CONTENT }; - 此参数的含义,以及其默认值,在 PostgreSQL 12 中发生了变化; + 此参数的含义,以及其默认值,在 PostgreSQL 12 中发生了变化; 参见 以便进一步讨论。 @@ -8419,7 +7405,7 @@ SET XML OPTION { DOCUMENT | CONTENT }; client_encoding配置参数 - character set + 字符集 @@ -8497,22 +7483,7 @@ SET XML OPTION { DOCUMENT | CONTENT }; - - icu_validation_level (enum) - - icu_validation_level配置参数 - - - - - 控制在遇到 ICU 区域设置验证问题时使用何种消息严重级别报告该问题。 - 有效值包括DISABLEDDEBUG5DEBUG4DEBUG3DEBUG2DEBUG1INFONOTICEWARNINGERRORLOG。 - - - 如果设置为DISABLED,则不会报告任何验证问题;否则,将以给定的消息级别报告问题。默认值为WARNING。 - - - + @@ -8675,20 +7646,6 @@ SET XML OPTION { DOCUMENT | CONTENT }; - - stats_temp_directory (string) - - stats_temp_directory配置参数 - - - - - 设置存放临时统计信息数据的目录。它既可以是相对于数据目录的路径,也可以是绝对路径。默认值是 - pg_stat_tmp。将其指向基于 RAM 的文件系统可以减少物理 I/O 需求,并可能提升性能。 - 这个参数只能在postgresql.conf文件中或服务器命令行上设置。 - - - @@ -8755,49 +7712,7 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' - - extension_control_path (string) - - extension_control_path配置参数 - - - - - 搜索扩展的路径,特别是扩展控制文件(name.control)。其余扩展脚本和辅助控制文件会从找到主控制文件的同一目录中加载。详情请参见。 - - - extension_control_path 的值必须是绝对目录路径列表,各路径以冒号分隔 - (在 Windows 上使用分号)。如果某个列表元素以特殊字符串 $system 开头, - 则 $system 会被替换为编译时确定的 PostgreSQL 扩展目录, - 也就是标准版 PostgreSQL 所提供扩展的安装位置。 - (可使用 pg_config --sharedir 查找该目录名称。)例如: - -extension_control_path = '/usr/local/share/postgresql:/home/my_project/share:$system' - - 或者在 Windows 环境中: - -extension_control_path = 'C:\tools\postgresql;H:\my_project\share;$system' - - 请注意,指定的每个路径元素都应当包含一个 extension 子目录,其中放置 - .control.sql 文件;系统会自动为每个路径元素追加 - extension 后缀。 - - - 该参数的默认值是 '$system'。如果将其设置为空字符串,也会视为默认的 - '$system'。 - - - 如果配置路径中的多个目录中存在同名扩展,则只会使用路径中最先找到的那个。 - - - 该参数可以由超级用户和具有适当SET权限的用户在运行时更改,但这种方式下的设置只会持续到客户端连接结束,因此这种方法应保留用于开发目的。 - 推荐在postgresql.conf中设置该参数。 - - - 请注意,如果你设置该参数以便从非标准位置加载扩展,那么通常还需要把设置为相应的位置。 - - - + @@ -8828,12 +7743,12 @@ extension_control_path = 'C:\tools\postgresql;H:\my_project\share;$system' deadlock_timeout (integer) - deadlock + 死锁 期间超时 - timeout - deadlock + 超时 + 死锁 deadlock_timeout配置参数 @@ -8870,12 +7785,11 @@ extension_control_path = 'C:\tools\postgresql;H:\my_project\share;$system' 共享锁表跟踪在max_locks_per_transaction * ( + ) 个对象(如表)上的锁。因此,在任何一个时刻,只有不超过这么多个可区分对象能够被锁住。这个参数控制为每个事务分配的对象锁的平均数量。个体事务可以锁住更多对象,数量可以和锁表中能容纳的所有事务的锁一样多。这是能被锁住的行数,那个值是没有限制的。默认值 64 已经被历史证明是足够的,但是如果你有需要在一个事务中使用很多不同表的查询(例如查询一个有很多子表的父表),你可能需要提高这个值。这个参数只能在服务器启动时设置。 + linkend="guc-max-prepared-transactions"/>) 个对象(如表)上的锁。因此,在任何一个时刻,只有不超过这么多个可区分对象能够被锁住。这个参数控制为每个事务分配的对象锁的平均数量。只要所有事务的锁都能放入锁表中,单个事务就可以锁住更多对象。这是能被锁住的行数,那个值是没有限制的。默认值 64 已经被历史证明是足够的,但是如果你有需要在一个事务中使用很多不同表的查询(例如查询一个有很多子表的父表),你可能需要提高这个值。这个参数只能在服务器启动时设置。 - 当运行一个备库时,你必须设置这个参数等于或大于主库上的参数。 - 否则,备库上可能无法允许查询。 + 运行备库时,必须将此参数设置为大于或等于主库上的值。否则,备库上将不允许查询。 @@ -8892,7 +7806,7 @@ extension_control_path = 'C:\tools\postgresql;H:\my_project\share;$system' 共享谓词锁表跟踪在max_pred_locks_per_transaction * ( + ) 个对象(如表)上的锁。因此,在任何一个时刻,只有不超过这么多个可区分对象能够被锁住。这个参数控制为每个事务分配的对象锁的平均数量。个体事务可以锁住更多对象,数量可以和锁表中能容纳的所有事务的锁一样多。这是能被锁住的行数,那个值是没有限制的。默认值 64 已经在测试中被证明通常是足够的,但是如果你有需要在一个可串行化事务中使用很多不同表的查询(例如查询一个有很多子表的父表),你可能需要提高这个值。这个参数只能在服务器启动时设置。 + linkend="guc-max-prepared-transactions"/>) 个对象(如表)上的锁。因此,在任何一个时刻,只有不超过这么多个可区分对象能够被锁住。这个参数控制为每个事务分配的对象锁的平均数量。只要所有事务的锁都能放入锁表中,单个事务就可以锁住更多对象。这是能被锁住的行数,那个值是没有限制的。默认值 64 已经在测试中被证明通常是足够的,但是如果你有会在单个可串行化事务中访问许多不同表的客户端,则可能需要提高这个值。这个参数只能在服务器启动时设置。 @@ -8962,7 +7876,7 @@ extension_control_path = 'C:\tools\postgresql;H:\my_project\share;$system' backslash_quote (enum) - stringsbackslash quotes + 字符串反斜线引号 backslash_quote配置参数 @@ -8982,7 +7896,7 @@ extension_control_path = 'C:\tools\postgresql;H:\my_project\share;$system' escape_string_warning (boolean) - strings转义警告 + 字符串转义警告 escape_string_warning配置参数 @@ -9038,7 +7952,7 @@ extension_control_path = 'C:\tools\postgresql;H:\my_project\share;$system' standard_conforming_strings (boolean) - stringsstandard conforming + 字符串标准符合 standard_conforming_strings配置参数 @@ -9102,37 +8016,7 @@ extension_control_path = 'C:\tools\postgresql;H:\my_project\share;$system' - - allow_alter_system (boolean) - - allow_alter_system配置参数 - - - - - 当allow_alter_system被设置为off时,执行ALTER SYSTEM命令会返回错误。 - 这个参数只能在postgresql.conf文件或服务器命令行中设置。默认值为on。 - - - - 请注意,这个设置不应被视为一种安全特性。它只会禁用ALTER SYSTEM命令, - 不会阻止超级用户使用其他 SQL 命令修改配置。超级用户有很多办法在操作系统层面执行 shell 命令, - 因而无论此设置为何值,都可以修改postgresql.auto.conf。 - - - - 关闭这个设置主要适用于由外部工具管理PostgreSQL配置的环境。 - 在这样的环境中,出于好意的超级用户可能会误用ALTER SYSTEM - 来修改配置,而不是通过外部工具进行管理。这可能导致意外行为,例如外部工具稍后更新配置时覆盖这些更改。 - 将此参数设置为off有助于避免这类错误。 - - - 这个参数只控制ALTER SYSTEM的使用。即使allow_alter_system - 被设置为off,存储在postgresql.auto.conf中的设置仍然会生效。 - - - @@ -9316,21 +8200,7 @@ extension_control_path = 'C:\tools\postgresql;H:\my_project\share;$system' - - huge_pages_status (enum) - - huge_pages_status配置参数 - - - - - 报告当前实例中大页的状态:onoff 或 - unknown(当通过postgres -C查看时)。 - 这个参数有助于确定在huge_pages=try时分配大页是否成功。 - 更多信息参见。 - - - + @@ -9364,6 +8234,34 @@ extension_control_path = 'C:\tools\postgresql;H:\my_project\share;$system' + + lc_collate (string) + + lc_collate 配置参数 + + + + + 报告对文本数据进行排序所使用的区域设置。更多信息参见。 + 此值在创建数据库时确定。 + + + + + + lc_ctype (string) + + lc_ctype 配置参数 + + + + + 报告决定字符分类的区域设置。更多信息参见。 + 此值在创建数据库时确定。通常它与lc_collate相同,但特殊应用可能将它设置为不同的值。 + + + + max_function_args (integer) @@ -9409,20 +8307,7 @@ extension_control_path = 'C:\tools\postgresql;H:\my_project\share;$system' - - num_os_semaphores (integer) - - num_os_semaphores配置参数 - - - - - 根据配置的最大连接数()、允许的自动清理工作进程数()、 - 允许的 WAL 发送进程数()、允许的后台进程数()等, - 报告服务器所需的信号量数量。 - - - + @@ -9445,7 +8330,7 @@ extension_control_path = 'C:\tools\postgresql;H:\my_project\share;$system' server_encoding配置参数 - character set + 字符集 @@ -9485,42 +8370,9 @@ extension_control_path = 'C:\tools\postgresql;H:\my_project\share;$system' - - - shared_memory_size (integer) - - shared_memory_size配置参数 - - - - - - 报告主共享内存区域的大小,四舍五入到最接近的兆字节。 - - - - - - - shared_memory_size_in_huge_pages (integer) - - shared_memory_size_in_huge_pages配置参数 - - - - - 报告基于指定的所需的主共享内存区域的大页数。 - 如果不支持大页,这将是-1。 - - - 这个设置仅在Linux上受支持。在其他平台上,它始终设置为-1。 - 有关在Linux上使用大页的更多详细信息,请参见。 - - - @@ -9663,24 +8515,7 @@ extension_control_path = 'C:\tools\postgresql;H:\my_project\share;$system' - - debug_copy_parse_plan_trees (boolean) - - debug_copy_parse_plan_trees配置参数 - - - - - 启用该选项会强制所有解析树和计划树都经过copyObject()处理, - 以便更容易发现copyObject()中的错误和遗漏。默认值为关闭。 - - - 只有在编译时定义了DEBUG_NODE_TESTS_ENABLED时,这个参数才可用; - 使用configure选项时会自动定义该宏。 - - - @@ -9711,103 +8546,42 @@ extension_control_path = 'C:\tools\postgresql;H:\my_project\share;$system' - - debug_io_direct (string) - - debug_io_direct配置参数 - - - - - 要求内核使用O_DIRECT(大多数类 Unix 系统)、F_NOCACHE(macOS) - 或FILE_FLAG_NO_BUFFERING(Windows),尽量减小关系数据和 WAL 文件缓存的影响。 - - - - 可以将其设置为空字符串(默认值)以禁用直接 I/O,也可以设置为应使用直接 I/O 的操作列表, - 各项之间用逗号分隔。有效选项包括data(主数据文件)、 - wal(WAL 文件)和wal_init(WAL 文件初始分配时)。 - 这个参数只能在服务器启动时设置。 - - - 某些操作系统和文件系统不支持直接 I/O,因此非默认设置可能会在启动时被拒绝或导致错误。 - - - 目前该特性会降低性能,仅用于开发人员测试。 - - - - - debug_parallel_query (enum) - - debug_parallel_query 配置参数 - - - - - 允许出于测试目的使用并行查询,即使预计不会带来性能收益也是如此。 - debug_parallel_query的允许值为off(仅在预期会提高性能时使用并行模式), - on(对所有被认为安全的查询强制使用并行查询), - 以及regress(类似于on,但有下文所述的额外行为变化)。 - - - 更具体地说,将该值设置为on会在任何看起来安全的查询计划顶部添加一个 - Gather节点,以便查询在并行工作进程中运行。即使并行工作进程不可用或 - 无法使用,启动子事务等在并行查询上下文中被禁止的操作也将被禁止,除非规划器认为这样会导致查询失败。 - 如果设置此选项时出现故障或意外结果,则可能需要将查询使用的一些函数标记为 - PARALLEL UNSAFE(或可能是PARALLEL RESTRICTED)。 - - - 将该值设置为regress会产生与设置为on相同的所有效果, - 并额外启用一些行为,以便自动回归测试。通常,来自并行工作进程的消息会包含一行上下文说明, - 但regress会抑制这一行,因此输出与非并行执行时相同。 - 此外,由该设置添加到计划中的Gather节点会在EXPLAIN输出中被隐藏, - 以便输出与此设置为off时得到的结果一致。 - - - - - debug_raw_expression_coverage_test (boolean) + + force_parallel_mode (enum) - debug_raw_expression_coverage_test配置参数 + force_parallel_mode 配置参数 - 启用该选项会强制所有 DML 语句的原始解析树都经过raw_expression_tree_walker()扫描, - 以便更容易发现该函数中的错误和遗漏。默认值为关闭。 - - - - 只有在编译时定义了DEBUG_NODE_TESTS_ENABLED时,这个参数才可用; - 使用configure选项时会自动定义该宏。 + 允许为测试目的使用并行查询,即使预期不会带来性能收益。 + force_parallel_mode允许的值包括 + off(仅在预期能提高性能时使用并行模式)、 + on(对所有被认为可以安全并行的查询强制使用并行查询),以及 + regress(类似于on,但还有下文说明的额外行为变化)。 - - - - debug_write_read_parse_plan_trees (boolean) - - debug_write_read_parse_plan_trees配置参数 - - - - 启用该选项会强制所有解析树和计划树都经过outfuncs.c/readfuncs.c处理, - 以便更容易发现这些模块中的错误和遗漏。默认值为关闭。 + 更具体地说,将此值设置为on会在任何看起来可以安全并行的查询计划顶部添加一个Gather节点, + 让查询在并行工作进程中运行。即使没有可用的并行工作进程或无法使用并行工作进程, + 在并行查询上下文中不允许的操作(例如启动子事务)也会被禁止,除非规划器认为这会使查询失败。 + 如果设置此选项后出现失败或意外结果,查询使用的某些函数可能需要被标记为PARALLEL UNSAFE + (也可能是PARALLEL RESTRICTED)。 - 只有在编译时定义了DEBUG_NODE_TESTS_ENABLED时,这个参数才可用; - 使用configure选项时会自动定义该宏。 + 将此值设置为regress具有设置为on的所有效果,另外还有一些旨在方便自动回归测试的效果。 + 通常,来自并行工作进程的消息会包含一行说明这一点的上下文信息,但regress设置会抑制此行,使输出与非并行执行时相同。 + 此外,此设置添加到计划中的Gather节点会在EXPLAIN输出中隐藏, + 使输出与此设置为off时的输出一致。 @@ -9873,6 +8647,24 @@ extension_control_path = 'C:\tools\postgresql;H:\my_project\share;$system' + + trace_recovery_messages (enum) + + trace_recovery_messages 配置参数 + + + + + 启用原本不会记录的恢复相关调试输出。此参数允许用户覆盖的常规设置,但仅针对特定消息。 + 它旨在用于调试热备。有效值为DEBUG5DEBUG4、 + DEBUG3DEBUG2DEBUG1LOG。 + 默认值LOG完全不影响是否记录消息的决定。其他值会让该优先级或更高优先级的恢复相关调试消息 + 按LOG优先级记录;对于log_min_messages的常见设置,这会无条件地将它们发送到服务器日志。 + 此参数只能在postgresql.conf文件中或在服务器命令行上设置。 + + + + trace_sort (boolean) @@ -10236,71 +9028,11 @@ LOG: CleanUpLock: deleting: lock(0xb7acd844) id(24688,24696,0,0,0,1) - - send_abort_for_crash (boolean) - - send_abort_for_crash配置参数 - - - - - 默认情况下,后端崩溃后,主进程会向其余子进程发送SIGQUIT信号使其停止, - 这样它们可以较为平稳地退出。当该选项设置为on时,则改为发送SIGABRT。 - 这通常会让每个这类子进程生成一个 core dump 文件。这有助于在崩溃后调查其他进程的状态。 - 但在反复崩溃时,它也可能消耗大量磁盘空间,因此不要在未严密监控的系统上启用它。 - 请注意,系统并不支持自动清理这些 core 文件。这个参数只能在postgresql.conf文件中或服务器命令行中设置。 - - - - - send_abort_for_kill (boolean) - - send_abort_for_kill配置参数 - - - - - 默认情况下,在尝试用SIGQUIT停止子进程之后,主进程会等待五秒, - 然后发送SIGKILL强制立即终止。当该选项设置为on时, - 则会发送SIGABRT而不是SIGKILL。 - 这通常会让每个这类子进程生成一个 core dump 文件。这有助于调查那些卡住的子进程状态。 - 但在反复崩溃时,它也可能消耗大量磁盘空间,因此不要在未严密监控的系统上启用它。 - 请注意,系统并不支持自动清理这些 core 文件。这个参数只能在postgresql.conf文件中或服务器命令行中设置。 - - - - - debug_logical_replication_streaming (enum) - - debug_logical_replication_streaming配置参数 - - - - - 允许值为bufferedimmediate。默认值为buffered。 - 这个参数旨在用于测试逻辑解码以及大型事务的复制。 - debug_logical_replication_streaming对发布端和订阅端的影响不同。 - - - 在发布端,debug_logical_replication_streaming允许在逻辑解码中立即流式传输或序列化更改。 - 当设置为immediate时,如果 - streaming选项在 - CREATE SUBSCRIPTION中已启用, - 则每条更改都会被流式传输;否则会序列化每条更改。设置为buffered时, - 会在达到logical_decoding_work_mem后再流式传输或序列化更改。 - - - 在订阅端,如果streaming选项被设置为parallel, - 则debug_logical_replication_streaming可用于控制主应用工作进程是将更改发送到共享内存队列, - 还是将所有更改序列化到文件。设置为buffered时,主进程通过共享内存队列将更改发送给并行应用工作进程。 - 设置为immediate时,主进程会将所有更改序列化到文件,并通知并行应用工作进程在事务结束时读取并应用这些更改。 - - - + diff --git a/zh/14/contrib.sgml b/zh/14/contrib.sgml index 504a816b..9e2d12d7 100644 --- a/zh/14/contrib.sgml +++ b/zh/14/contrib.sgml @@ -109,6 +109,7 @@ CREATE EXTENSION extension_name; 详情见各组件文档。 +&adminpack; &amcheck; &auth-delay; &auto-explain; diff --git a/zh/14/datatype.sgml b/zh/14/datatype.sgml index 1675a8a0..9f720564 100644 --- a/zh/14/datatype.sgml +++ b/zh/14/datatype.sgml @@ -354,19 +354,19 @@ smallint 2字节 小范围整数 - -32768 to +32767 + -32768 到 +32767
integer 4字节 整数的典型选择 - -2147483648 to +2147483647 + -2147483648 到 +2147483647 bigint 8字节 大范围整数 - -9223372036854775808 to +9223372036854775807 + -9223372036854775808 到 +9223372036854775807 @@ -839,9 +839,8 @@ FROM generate_series(-3.5, 3.5, 1) as x; - 本节描述的是 PostgreSQL 特有的创建 - 自动递增列的方法。另一种方法是使用 SQL 标准的标识列特性, - 参见 。 + 本节介绍 PostgreSQL 特有的自动递增列创建方法。 + 另一种方法是使用 SQL 标准的标识列特性,参见 @@ -920,7 +919,7 @@ ALTER SEQUENCE tablename_money 类型以固定的小数精度存储货币金额; 参见 。小数精度由数据库的 设置决定。表中显示的范围假定 - 有两位小数。输入支持多种格式,包括整数和浮点文字,以及典型的 + 有两位小数。输入支持多种格式,包括整数字面量和浮点数字面量,以及典型的 货币格式,例如 '$1,000.00'。输出通常也采用 后一种形式,但会受到区域设置影响。 @@ -1329,7 +1328,7 @@ SELECT '\xDEADBEEF'::bytea; - <type>bytea</type>文字转义字节 + <type>bytea</type>字面量中需要转义的字节 @@ -2594,7 +2593,7 @@ SELECT '2 years 15 months 100 weeks 99 hours 123456789 milliseconds'::interval; 3 years 3 mons 700 days 133:17:36.789 - 这里,周被理解为 7 days,而较小和较大的时间单位 + 这里,周按7 天计算并单独保留,而较小和较大的时间单位 则被合并并规范化了。 @@ -4013,17 +4012,16 @@ a0ee-bc99-9c0b-4ef8-bb6d-6bb9-bd38-0a11 xml 数据类型可用于存储 XML 数据。与把 XML 数据存储在 - text 字段中相比,它的优势在于会检查输入值是否格式 - 良好,并且提供了可执行类型安全操作的支持函数;见 - 。使用该数据类型要求安装时启用 + text 字段中相比,它的优势在于会检查输入值的良构性,并且提供了可执行类型安全操作的支持函数;见 + 。使用该数据类型要求构建时使用 configure --with-libxml - xml 类型既可以存储符合 XML 标准定义的格式良好的 + xml 类型既可以存储 XML 标准所定义的良构 文档,也可以存储 内容 片段;后者是参照 XQuery 和 XPath 数据模型中更宽松的 - document node + 文档节点 概念来定义的。粗略地说,这意味着内容片段可以拥有多个顶层元素或字符 节点。表达式 xmlvalue IS DOCUMENT @@ -4192,7 +4190,7 @@ SET xmloption TO { DOCUMENT | CONTENT }; - 是一种用户定义的数据类型,它基于另一种底层类型。根据需要,它可以有约束来限制其有效值为底层类型所允许值的一个子集。如果没有约束,它的行为就和底层类型一样 — 例如,任何适用于底层类型的操作符或函数都对该域类型有效。底层类型可以是任何内置或者用户定义的基础类型、枚举类型、数组类型、复合类型、范围类型或者另一个域。 + 是一种用户定义的数据类型,它基于另一种底层类型。根据需要,它可以有约束来限制其有效值为底层类型所允许值的一个子集。除此之外,它的行为与底层类型相同 — 例如,任何适用于底层类型的操作符或函数都对该域类型有效。底层类型可以是任何内置或者用户定义的基础类型、枚举类型、数组类型、复合类型、范围类型或者另一个域。 diff --git a/zh/14/dblink.sgml b/zh/14/dblink.sgml index bd331731..f9e88ad2 100644 --- a/zh/14/dblink.sgml +++ b/zh/14/dblink.sgml @@ -11,39 +11,6 @@ dblink 是一个支持在数据库会话内连接到其他 PostgreSQL 数据库的模块。 - - dblink 可以在 Extension 等待事件类型下报告以下等待事件。 - - - - - DblinkConnect - - - 等待与远程服务器建立连接。 - - - - - - DblinkGetConnect - - - 当在已打开连接列表中找不到该连接时,等待建立与远程服务器的连接。 - - - - - - DblinkGetResult - - - 等待接收来自远程服务器的查询结果。 - - - - - 另请参见 ,它使用更现代且更符合标准的基础设施提供了基本相同的功能。 @@ -65,8 +32,8 @@ -dblink_connect(text connstr) 返回 text -dblink_connect(text connname, text connstr) 返回 text +dblink_connect(text connstr) returns text +dblink_connect(text connname, text connstr) returns text @@ -128,22 +95,13 @@ dblink_connect(text connname, text connstr) 返回 text 注解 - 如果不可信用户能够访问一个尚未采用模式的安全使用方式的数据库,则应在每个会话开始时从 + 如果不受信任的用户能够访问一个尚未采用模式的安全使用方式的数据库,则应在每个会话开始时从 search_path 中移除公共可写模式。例如,可以把 options=-csearch_path= 加到 connstr 中。这个注意事项并非 dblink 所特有;它适用于每一种执行任意 SQL 命令的接口。 - - 外部数据包装器 dblink_fdw 还有一个额外的布尔选项 - use_scram_passthrough,用于控制 - dblink 是否在连接远程数据库时使用 SCRAM 透传认证。 - 使用 SCRAM 透传认证时,dblink 会使用 SCRAM 哈希后的凭据,而不是明文用户密码来连接远程服务器。 - 这样可以避免在 PostgreSQL 系统目录中存储明文用户密码。关于更多细节和限制,请参见 - postgres_fdw 中对应的 - use_scram_passthrough - 选项文档。 - + 只有超级用户才能使用 dblink_connect 创建不使用密码认证的连接。 @@ -173,10 +131,9 @@ SELECT dblink_connect('myconn', 'dbname=postgres options=-csearch_path='); OK (1 row) --- FOREIGN DATA WRAPPER functionality --- Note: local connections that don't use SCRAM pass-through require password --- authentication for this to work properly. Otherwise, you will receive --- the following error from dblink_connect(): +-- FOREIGN DATA WRAPPER 功能 +-- 注意:要使本例正常工作,本地连接必须要求密码认证。 +-- 否则,dblink_connect() 将报告以下错误: -- ERROR: password is required -- DETAIL: Non-superuser cannot connect if the server does not request a password. -- HINT: Target server's authentication method must be changed. @@ -239,8 +196,8 @@ DROP SERVER fdtest; -dblink_connect_u(text connstr) 返回 text -dblink_connect_u(text connname, text connstr) 返回 text +dblink_connect_u(text connstr) returns text +dblink_connect_u(text connname, text connstr) returns text @@ -260,7 +217,7 @@ dblink_connect_u(text connname, text connstr) 返回 text 因此,dblink_connect_u() 在初始安装时会撤销 PUBLIC 的全部权限,从而除了超级用户之外无法调用它。 在某些情况下,可能适合向被认为可信的特定用户授予 - EXECUTE 权限,但必须谨慎操作。还建议服务器用户的任何 + dblink_connect_u()EXECUTE 权限,但必须谨慎操作。还建议服务器用户的任何 ~/.pgpass 文件不要包含指定通配主机名的记录。 @@ -287,8 +244,8 @@ dblink_connect_u(text connname, text connstr) 返回 text -dblink_disconnect() 返回 text -dblink_disconnect(text connname) 返回 text +dblink_disconnect() returns text +dblink_disconnect(text connname) returns text @@ -360,9 +317,9 @@ SELECT dblink_disconnect('myconn'); -dblink(text connname, text sql [, bool fail_on_error]) 返回 setof record -dblink(text connstr, text sql [, bool fail_on_error]) 返回 setof record -dblink(text sql [, bool fail_on_error]) 返回 setof record +dblink(text connname, text sql [, bool fail_on_error]) returns setof record +dblink(text connstr, text sql [, bool fail_on_error]) returns setof record +dblink(text sql [, bool fail_on_error]) returns setof record @@ -439,7 +396,7 @@ SELECT * WHERE proname LIKE 'bytea%'; - FROM 子句中的 alias 部分必须指定该函数将返回的列名和类型。(在别名中指定列名实际上是标准 SQL 语法,但指定列类型则是 + FROM 子句中的 别名 部分必须指定该函数将返回的列名和类型。(在别名中指定列名实际上是标准 SQL 语法,但指定列类型则是 PostgreSQL 的扩展。)这样系统才能在尝试执行该函数之前,就知道 * 应展开成什么,以及 WHERE 子句中的 proname 指的是什么。运行时,如果远程数据库返回的实际查询结果与 @@ -559,9 +516,9 @@ SELECT * FROM dblink('myconn', 'select proname, prosrc from pg_proc') -dblink_exec(text connname, text sql [, bool fail_on_error]) 返回 text -dblink_exec(text connstr, text sql [, bool fail_on_error]) 返回 text -dblink_exec(text sql [, bool fail_on_error]) 返回 text +dblink_exec(text connname, text sql [, bool fail_on_error]) returns text +dblink_exec(text connstr, text sql [, bool fail_on_error]) returns text +dblink_exec(text sql [, bool fail_on_error]) returns text @@ -686,8 +643,8 @@ DETAIL: ERROR: null value in column "relnamespace" violates not-null constrain -dblink_open(text cursorname, text sql [, bool fail_on_error]) 返回 text -dblink_open(text connname, text cursorname, text sql [, bool fail_on_error]) 返回 text +dblink_open(text cursorname, text sql [, bool fail_on_error]) returns text +dblink_open(text connname, text cursorname, text sql [, bool fail_on_error]) returns text @@ -800,8 +757,8 @@ SELECT dblink_open('foo', 'select proname, prosrc from pg_proc'); -dblink_fetch(text cursorname, int howmany [, bool fail_on_error]) 返回 setof record -dblink_fetch(text connname, text cursorname, int howmany [, bool fail_on_error]) 返回 setof record +dblink_fetch(text cursorname, int howmany [, bool fail_on_error]) returns setof record +dblink_fetch(text connname, text cursorname, int howmany [, bool fail_on_error]) returns setof record @@ -943,8 +900,8 @@ SELECT * FROM dblink_fetch('foo', 5) AS (funcname name, source text); -dblink_close(text cursorname [, bool fail_on_error]) 返回 text -dblink_close(text connname, text cursorname [, bool fail_on_error]) 返回 text +dblink_close(text cursorname [, bool fail_on_error]) returns text +dblink_close(text connname, text cursorname [, bool fail_on_error]) returns text @@ -1049,7 +1006,7 @@ SELECT dblink_close('foo'); -dblink_get_connections() 返回 text[] +dblink_get_connections() returns text[] @@ -1065,7 +1022,7 @@ dblink_get_connections() 返回 text[] 返回值 - 返回一个包含连接名称的 text[];如果没有,则返回空值。 + 返回一个包含连接名称的 text[];如果没有连接,则返回 NULL。 @@ -1094,7 +1051,7 @@ SELECT dblink_get_connections(); -dblink_error_message(text connname) 返回 text +dblink_error_message(text connname) returns text @@ -1165,7 +1122,7 @@ SELECT dblink_error_message('dtest1'); -dblink_send_query(text connname, text sql) 返回 int +dblink_send_query(text connname, text sql) returns int @@ -1240,7 +1197,7 @@ SELECT dblink_send_query('dtest1', 'SELECT * FROM foo WHERE f1 < 3'); -dblink_is_busy(text connname) 返回 int +dblink_is_busy(text connname) returns int @@ -1302,8 +1259,8 @@ SELECT dblink_is_busy('dtest1'); -dblink_get_notify() 返回 setof (notify_name text, be_pid int, extra text) -dblink_get_notify(text connname) 返回 setof (notify_name text, be_pid int, extra text) +dblink_get_notify() returns setof (notify_name text, be_pid int, extra text) +dblink_get_notify(text connname) returns setof (notify_name text, be_pid int, extra text) @@ -1382,7 +1339,7 @@ SELECT * FROM dblink_get_notify(); -dblink_get_result(text connname [, bool fail_on_error]) 返回 setof record +dblink_get_result(text connname [, bool fail_on_error]) returns setof record @@ -1528,7 +1485,7 @@ contrib_regression=# SELECT * FROM dblink_get_result('dtest1') AS t1(f1 int, f2 -dblink_cancel_query(text connname) 返回 text +dblink_cancel_query(text connname) returns text @@ -1591,7 +1548,7 @@ SELECT dblink_cancel_query('dtest1'); -dblink_get_pkey(text relname) 返回 setof dblink_pkey_results +dblink_get_pkey(text relname) returns setof dblink_pkey_results @@ -1680,7 +1637,7 @@ dblink_build_sql_insert(text relname, int2vector primary_key_attnums, integer num_primary_key_atts, text[] src_pk_att_vals_array, - text[] tgt_pk_att_vals_array) 返回 text + text[] tgt_pk_att_vals_array) returns text @@ -1796,7 +1753,7 @@ SELECT dblink_build_sql_insert('foo', '1 2', 2, '{"1", "a"}', '{"1", "b''a"}'); dblink_build_sql_delete(text relname, int2vector primary_key_attnums, integer num_primary_key_atts, - text[] tgt_pk_att_vals_array) 返回 text + text[] tgt_pk_att_vals_array) returns text @@ -1904,7 +1861,7 @@ dblink_build_sql_update(text relname, int2vector primary_key_attnums, integer num_primary_key_atts, text[] src_pk_att_vals_array, - text[] tgt_pk_att_vals_array) 返回 text + text[] tgt_pk_att_vals_array) returns text diff --git a/zh/14/ddl.sgml b/zh/14/ddl.sgml index b249ad31..e178e863 100644 --- a/zh/14/ddl.sgml +++ b/zh/14/ddl.sgml @@ -232,19 +232,17 @@ INSERT INTO people (id, name, address) VALUES (DEFAULT, 'C' 生成列是一种特殊列,其值总是根据其他列计算得出。因此,对列而言,它就像视图对表一样。生成列有两种:存储型和虚拟型。存储型生成列在写入时(插入或更新时)计算,并像普通列一样占用存储空间。虚拟生成列不占用存储空间,而是在读取时计算。因此,虚拟生成列类似于视图,存储型生成列类似于物化视图(只是它总会自动更新)。 + PostgreSQL 目前只实现了存储型生成列。 - - 要创建生成列,可在CREATE TABLE中使用GENERATED ALWAYS AS子句,例如: - + 要创建生成列,可使用GENERATED ALWAYS + AS子句,在CREATE TABLE中,例如: CREATE TABLE people ( ..., height_cm numeric, - height_in numeric GENERATED ALWAYS AS (height_cm / 2.54) + height_in numeric GENERATED ALWAYS AS (height_cm / 2.54) STORED ); - - 生成列默认是虚拟型。使用关键字VIRTUALSTORED可以显式指定类型。更多细节见。 - +必须指定关键字STORED来选择存储型生成列。参见了解更多细节。 生成列不能直接写入。在INSERTUPDATE命令中,不能为生成列指定值,但可以指定关键字DEFAULT。 @@ -273,11 +271,7 @@ CREATE TABLE people ( 生成表达式不能引用系统列,tableoid 除外。 - - - 虚拟生成列不能使用用户定义类型,并且其生成表达式不得引用用户定义函数或类型,也就是说,它只能使用内置函数或类型。该限制也包括间接使用的情况,例如操作符或类型转换背后的函数或类型。(这一限制不适用于存储型生成列。) - - + 生成列不能具有列默认值或标识定义。 @@ -294,36 +288,16 @@ CREATE TABLE people ( - 对于继承和分区: + 对于继承: - - 如果父列是生成列,其子列也必须是同种类(存储型或虚拟型)的生成列;不过,子列可以使用不同的生成表达式。 - - - - 对于存储型生成列,在插入或更新一行时,实际应用的是该行所在物理表关联的生成表达式。(这与列默认值不同:默认值使用的是查询中所指名表关联的默认值。)对于虚拟生成列,在读取表时,应用的是查询中所指名表的生成表达式。 - + 如果父列是生成列,则子列也必须是使用相同表达式的生成列。在子列的定义中,应省略GENERATED子句,因为它会从父列复制。 - - 如果父列不是生成列,其子列也不能是生成列。 - + 在多重继承的情况下,如果某个父列是生成列,则所有父列都必须是生成列,并且使用相同的表达式。 - - 对于继承表,如果在CREATE TABLE ... INHERITS中编写子列定义时未写任何GENERATED子句,则会自动从父列复制该GENERATED子句。ALTER TABLE ... INHERIT要求父列和子列在是否为生成列这一点上已经匹配,但不要求它们的生成表达式相同。 - - - - - 类似地,对于分区表,如果在CREATE TABLE ... PARTITION OF中编写子列定义时未写任何GENERATED子句,则会自动从父列复制该子句。ALTER TABLE ... ATTACH PARTITION要求父列和子列在生成状态上已经匹配,但不要求它们的生成表达式相同。 - - - - - 在多重继承的情况下,如果某个父列是生成列,则所有父列都必须是生成列。如果它们的生成表达式并不完全相同,则必须为子列显式指定所需的表达式。 - + 如果父列不是生成列,则子列可以定义为生成列,也可以不是生成列。 @@ -338,24 +312,16 @@ CREATE TABLE people ( 生成列与其底层基础列分别维护访问权限。因此,可以安排成某个角色能够读取生成列,但不能读取底层基础列。 - - 对于虚拟生成列,只有在生成表达式只使用防泄漏函数时,这种安排才完全安全(见),但系统不会强制检查这一点。 - - - - - 生成表达式中所用函数的权限,会在表达式实际执行时分别在写入或读取时检查,就像生成表达式是由使用生成列的查询直接调用的一样。生成列的用户必须拥有调用生成表达式中所有函数的权限。生成表达式中的函数是以执行查询的用户的权限还是函数所有者的权限来执行,取决于这些函数被定义为SECURITY INVOKER还是SECURITY DEFINER。 - + + 从概念上说,生成列会在BEFORE触发器运行之后更新。因此,BEFORE触发器中对基础列所做的修改会反映到生成列中。反过来,在BEFORE触发器中访问生成列是不允许的。 - - 生成列会在逻辑复制时被跳过,也不能在CREATE PUBLICATION的列列表中指定。 - + 逻辑复制会跳过生成列。 @@ -1417,8 +1383,7 @@ ALTER TABLE products RENAME TO items; 有不同种类的权限:SELECTINSERTUPDATEDELETETRUNCATEREFERENCESTRIGGERCREATECONNECT、 - TEMPORARYEXECUTEUSAGE、 - SETALTER SYSTEM以及MAINTAIN。 + TEMPORARYEXECUTEUSAGE。 适用于特定对象的权限取决于对象的类型(表、函数等)。 有关这些权限含义的更多详细信息如下所示。 后续的各节和各章还将展示这些权限是如何使用的。 @@ -1434,7 +1399,7 @@ ALTER TABLE products RENAME TO items; ALTER TABLE table_name OWNER TO new_owner; - 超级用户总是可以做到这点,普通角色只有在同时是对象的当前所有者(或者继承拥有角色的权限)并且能够对新的拥有角色执行SET ROLE时,才能做同样的事。旧所有者的所有对象权限会随所有权一起转移给新所有者。 + 超级用户总是可以做到这点,普通角色只有在同时是对象的当前所有者(或拥有者角色的成员)并且是新拥有者角色的成员时,才能做同样的事。旧所有者的所有对象权限会随所有权一起转移给新所有者。 @@ -1645,38 +1610,8 @@ REVOKE ALL ON accounts FROM PUBLIC; - - SET - - - 允许在当前会话中将服务器配置参数设置为新值。 - (虽然可以授予此权限在任何参数上,但除了通常需要超级用户权限设置的参数外,这是没有意义的。) - - - - - - ALTER SYSTEM - - - - 允许使用命令将服务器配置参数配置为新值。 - - - - - - MAINTAIN - - - 允许在关系上执行VACUUMANALYZE、 - CLUSTERREFRESH MATERIALIZED VIEW、 - REINDEXLOCK TABLE,以及数据库对象统计信息操作函数(见)。 - - - 其他命令所需的权限列在各自命令的参考页面上。 @@ -1706,7 +1641,7 @@ REVOKE ALL ON accounts FROM PUBLIC;
- 访问控制列表权限缩写 + ACL 权限缩写 @@ -1809,21 +1744,6 @@ REVOKE ALL ON accounts FROM PUBLIC; TYPE - - SET - s - PARAMETER - - - ALTER SYSTEM - A - PARAMETER - - - MAINTAIN - m - TABLE -
@@ -1895,16 +1815,9 @@ REVOKE ALL ON accounts FROM PUBLIC; LARGE OBJECT rw - \dl+ +
- - PARAMETER - sA - - \dconfig+ - - SCHEMA UC @@ -1921,7 +1834,7 @@ REVOKE ALL ON accounts FROM PUBLIC; TABLE(以及类似表的对象) - arwdDxtm + arwdDxt \dp @@ -3436,7 +3349,16 @@ ALTER INDEX measurement_city_id_logdate_key - 创建表,所有的表都将从它继承。这个表将不包含数据。不要在这个表上定义任何检查约束,除非想让它们应用到所有的子表上。同样,在这个表上定义索引或者唯一约束也没有意义。对于我们的示例来说,根表是最初定义的measurement表。 + 创建表,所有的表都将从它继承。这个表将不包含数据。不要在这个表上定义任何检查约束,除非想让它们应用到所有的子表上。同样,在这个表上定义索引或者唯一约束也没有意义。对于我们的示例来说,根表是最初定义的measurement表: + + +CREATE TABLE measurement ( + city_id int not null, + logdate date not null, + peaktemp int, + unitsales int +); + @@ -4045,7 +3967,7 @@ DROP TABLE products CASCADE; - 对于一个将其主体定义为字符串文字的用户定义函数或过程,PostgreSQL会跟踪与函数的外部可见属性相关的依赖关系,例如其参数和结果类型,但不会跟踪只有通过检查函数主体才能知道的依赖关系。例如,考虑以下情况: + 对于一个将其主体定义为字符串字面量的用户定义函数或过程,PostgreSQL会跟踪与函数的外部可见属性相关的依赖关系,例如其参数和结果类型,但不会跟踪只有通过检查函数主体才能知道的依赖关系。例如,考虑以下情况: CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', diff --git a/zh/14/dfunc.sgml b/zh/14/dfunc.sgml index 784bf1be..d0a7fa1f 100644 --- a/zh/14/dfunc.sgml +++ b/zh/14/dfunc.sgml @@ -46,7 +46,7 @@ FreeBSD - FreeBSDshared library + FreeBSD共享库 @@ -64,7 +64,7 @@ gcc -shared -o foo.so foo.o HP-UX - HP-UXshared library + HP-UX共享库 @@ -91,7 +91,7 @@ ld -b -o foo.sl foo.o Linux - Linuxshared library + Linux共享库 @@ -108,7 +108,7 @@ cc -shared -o foo.so foo.o macOS - macOSshared library + macOS共享库 @@ -124,7 +124,7 @@ cc -bundle -flat_namespace -undefined suppress -o foo.so foo.o NetBSD - NetBSDshared library + NetBSD共享库 @@ -142,7 +142,7 @@ gcc -shared -o foo.so foo.o OpenBSD - OpenBSDshared library + OpenBSD共享库 @@ -159,7 +159,7 @@ ld -Bshareable -o foo.so foo.o Solaris - Solarisshared library + Solaris共享库 diff --git a/zh/14/diskusage.sgml b/zh/14/diskusage.sgml index cfcd855d..be6f91e6 100644 --- a/zh/14/diskusage.sgml +++ b/zh/14/diskusage.sgml @@ -15,15 +15,15 @@ - 每个表都有一个主堆磁盘文件,其中存储了大部分数据。如果该表有任何值可能较宽的列,还可能会有一个与该表关联的TOAST文件,用于存储宽到无法方便地放入主表中的值(见)。如果存在,还会在TOAST表上有一个有效索引。也可能会有与基表关联的索引。每个表和索引都存储在单独的磁盘文件中 — 如果文件会超过 1 GB,则可能分成多个文件。这些文件的命名约定见。 - + 每个表都有一个主堆磁盘文件,大部分数据都存储在那里。如果表中有任何列可能包含较宽的值,还可能有一个与该表关联的 TOAST 文件,用于存储那些不适合放在主表中的过宽值(参见)。如果该 TOAST 表存在,则它会有一个有效索引。基础表本身也可能带有索引。每个表和索引都存储在单独的磁盘文件中;如果某个文件会超过 1 GB,则可能拆分为多个文件。关于这些文件的命名规则,请参见。 + - 可以通过三种方式监控磁盘空间:使用中列出的 SQL 函数,使用模块,或者手工检查系统目录。SQL 函数最容易使用,通常也是推荐的方法。本节其余部分展示如何通过检查系统目录来完成此事。 - + 你可以通过三种方式监控磁盘空间:使用中列出的 SQL 函数、使用模块,或者手工检查系统目录。SQL 函数最容易使用,通常也是推荐的方法。本节余下内容展示如何通过检查系统目录来完成这项工作。 + - 在最近做过 vacuum 或 analyze 的数据库上使用psql时,可以发出查询以查看任意表的磁盘使用情况: + 在最近进行过清理或分析 的数据库上使用 psql,你可以发出查询来查看任意表的磁盘使用情况: SELECT pg_relation_filepath(oid), relpages FROM pg_class WHERE relname = 'customer'; @@ -32,11 +32,11 @@ SELECT pg_relation_filepath(oid), relpages FROM pg_class WHERE relname = 'custom base/16384/16806 | 60 (1 row) - 每个页通常为 8 KB。(请记住,relpages只会由VACUUMANALYZE以及少数 DDL 命令(如CREATE INDEX)更新。)如果你想直接检查该表的磁盘文件,文件路径名就很有用。 - + 每一页通常是 8 KB。(请记住,relpages 只会由 VACUUMANALYZE 以及少数 DDL 命令如 CREATE INDEX 更新。)如果你想直接检查该表的磁盘文件,那么文件路径名会很有用。 + - 要显示TOAST表使用的空间,可使用如下查询: + 要显示 TOAST 表使用的空间,可以使用如下查询: SELECT relname, relpages FROM pg_class, @@ -54,10 +54,10 @@ ORDER BY relname; pg_toast_16806 | 0 pg_toast_16806_index | 1 - + - 也可以很容易地显示索引大小: + 也可以很容易地显示索引所占空间: SELECT c2.relname, c2.relpages FROM pg_class c, pg_class c2, pg_index i @@ -70,10 +70,10 @@ ORDER BY c2.relname; -------------------+---------- customer_id_index | 26 - + - 利用这些信息,可以很容易找出最大的表和索引: + 利用这些信息,你可以很容易地找出最大的表和索引: SELECT relname, relpages FROM pg_class @@ -84,28 +84,28 @@ ORDER BY relpages DESC; bigtable | 3290 customer | 3144 - + 磁盘已满故障 - 数据库管理员最重要的磁盘监控任务,是确保磁盘不会被写满。数据盘被写满不会导致数据损坏,但可能使有用的活动无法继续进行。如果存放 WAL 文件的磁盘逐渐被写满,数据库服务器可能会进入 panic 状态并随后关闭。 - + 数据库管理员最重要的磁盘监控任务,是确保磁盘不会被写满。数据磁盘写满不会导致数据损坏,但可能会阻止有用的活动继续进行。如果保存 WAL 文件的磁盘被写满,则数据库服务器可能会 panic 并随后关闭。 + - 如果无法通过删除其他内容来释放磁盘上的额外空间,可以利用表空间将部分数据库文件移到其他文件系统上。有关更多信息,请参见。 - + 如果你无法通过删除其他文件来释放更多磁盘空间,那么可以利用表空间把部分数据库文件移动到其他文件系统上。详见。 + - 有些文件系统在接近写满时性能很差,因此不要等到磁盘完全写满才采取措施。 - + 有些文件系统在接近写满时性能会明显变差,因此不要等到磁盘完全写满才采取措施。 + - 如果系统支持按用户设置磁盘配额,那么数据库自然会受限于运行服务器的那个用户所被施加的配额。超出配额与磁盘空间完全耗尽会产生同样的不良影响。 - + 如果你的系统支持按用户设置磁盘配额,那么数据库自然也会受到运行服务器的那个用户所拥有配额的限制。超出配额会带来与磁盘空间完全耗尽相同的不良影响。 + diff --git a/zh/14/docguide.sgml b/zh/14/docguide.sgml index 75a61241..ead28e7a 100644 --- a/zh/14/docguide.sgml +++ b/zh/14/docguide.sgml @@ -231,16 +231,11 @@ checking for dbtoepub... dbtoepub - - 如果你更愿意使用 Meson 构建PostgreSQL,则请按说明运行 - meson setup(见), - 然后参见。 - - 使用 Make 构建文档 + 构建文档 一切设置妥当后,切换到doc/src/sgml目录,并运行后续各小节中介绍的某个命令来构建文档。 @@ -306,7 +301,7 @@ checking for dbtoepub... dbtoepub - 对于 U.S. letter 格式: + 对于美国信纸格式: doc/src/sgml$ make postgres-US.pdf @@ -320,7 +315,7 @@ checking for dbtoepub... dbtoepub 因此,在某些系统上,构建会因内存相关错误而失败。这通常可以通过在配置文件 ~/.foprc中配置 Java 堆设置来解决,例如: -# FOP binary distribution +# FOP 二进制发行版 FOP_OPTS='-Xmx1500m' # Debian JAVA_ARGS='-Xmx1500m' @@ -331,17 +326,24 @@ ADDITIONAL_FLAGS='-Xmx1500m' 对于内存很少(小于 1 GB)的系统,构建要么会因交换而非常缓慢,要么根本无法工作。 + - 在默认配置下,FOP会为每一页输出一条INFO消息。 - 日志级别可通过~/.foprc修改: - -LOGCHOICE=-Dorg.apache.commons.logging.Log=&zwsp;org.apache.commons.logging.impl.SimpleLog -LOGLEVEL=-Dorg.apache.commons.logging.simplelog.defaultlog=WARN - + 也可以手工使用其他 XSL-FO 处理器,但自动化构建过程只支持 FOP。 + + + + 纯文本文件 - 也可以手工使用其他 XSL-FO 处理器,但自动化构建过程只支持 FOP。 + 安装说明也以纯文本形式分发,以便在没有更好的阅读工具时使用。 + INSTALL文件对应,并针对不同语境作了少量调整。 + 要重新生成该文件,请切换到doc/src/sgml目录,然后输入make INSTALL。 + 构建文本输出还需要Pandoc 1.13 或更新版本作为额外的构建工具。 + + + + 过去,发行说明和回归测试说明也曾以纯文本形式分发,但现已停止这种做法。 diff --git a/zh/14/ecpg.sgml b/zh/14/ecpg.sgml index 48624969..e6641896 100644 --- a/zh/14/ecpg.sgml +++ b/zh/14/ecpg.sgml @@ -1139,7 +1139,7 @@ oid=313780, datname=testdb, size=8183012 - 结构体主变量将列尽数吸收成结构体的域。额外的列可以被分配给其他主变量。例如,上面的程序也可以使用结构体外部的size变量重新构造: + 结构体主变量吸收的列数与结构体的字段数相同。额外的列可以被分配给其他主变量。例如,上面的程序也可以使用结构体外部的size变量改写: EXEC SQL BEGIN DECLARE SECTION; typedef struct @@ -1440,7 +1440,7 @@ while (1) 用户定义的基础类型 - ECPG 并不直接支持新的用户定义的基本类型。你可以使用外部字符串表示以及类型char[]VARCHAR[]的主变量,并且这种方案事实上对很多类型都是合适和足够的。 + ECPG 并不直接支持新的用户定义的基础类型。你可以使用外部字符串表示以及类型char[]VARCHAR[]的主变量,并且这种方案事实上对很多类型都是合适和足够的。 @@ -3980,8 +3980,8 @@ datdba = 10 (type: 1) encoding = 0 (type: 5) datistemplate = t (type: 1) datallowconn = t (type: 1) -dathasloginevt = f (type: 1) datconnlimit = -1 (type: 5) +datlastsysoid = 11510 (type: 1) datfrozenxid = 379 (type: 1) dattablespace = 1663 (type: 1) datconfig = (type: 1) @@ -4005,8 +4005,8 @@ datdba = 10 (type: 1) encoding = 0 (type: 5) datistemplate = f (type: 1) datallowconn = t (type: 1) -dathasloginevt = f (type: 1) datconnlimit = -1 (type: 5) +datlastsysoid = 11510 (type: 1) datfrozenxid = 379 (type: 1) dattablespace = 1663 (type: 1) datconfig = (type: 1) @@ -4743,7 +4743,7 @@ EXEC SQL INCLUDE "filename"; 当前目录 /usr/local/include - PostgreSQL 的包括目录,在编译时定义(例如/usr/local/pgsql/include + PostgreSQL 的头文件目录,在编译时定义(例如/usr/local/pgsql/include /usr/include @@ -4870,7 +4870,7 @@ EXEC SQL UPDATE Tbl SET col = MYNUMBER; - 此示例将完全编译三个SET TIMEZONE命令之一: + 此示例将完全编译三个SET TIMEZONE命令之一: EXEC SQL ifdef TZVAR; EXEC SQL SET TIMEZONE TO TZVAR; @@ -5498,7 +5498,7 @@ DATABASE connection_target 使用 user_name/passworduser_name IDENTIFIED BY password或者 - user_name USING password之一,这个参数也能指定用户名和密码. + user_name USING password之一,这个参数也能指定用户名和密码。 @@ -6078,9 +6078,7 @@ EXECUTE IMMEDIATE string - 如果你使用文字字符串,请注意任何你可能希望在SQL语句中包括的双引号必须写为八进制转义(\042) ,而不是通常的C惯语\"。 - 这是因为字符串在EXEC SQL段里面,所以ECPG 语法分析器根据SQL规则而不是C规则来解析它。 - 任何内嵌的反斜杠后续将按照C规格处理;但是\"会造成直接语法错误,因为它被视为文字的终结。 + 如果使用字符串字面量,请注意,要在 SQL 语句中包含的双引号必须写为八进制转义(\042),而不是通常的 C 写法\"。这是因为字符串位于EXEC SQL段中,ECPG 词法分析器会按照 SQL 规则而非 C 规则解析它。内嵌的反斜杠随后会按照 C 规则处理;但\"会被视为字面量的结束,因此会立即引起语法错误。 @@ -6413,9 +6411,7 @@ PREPARE prepared_name FROM - 如果你使用文字字符串,请注意任何你可能希望在SQL语句中包括的双引号必须写为八进制转义(\042) ,而不是通常的C惯语\"。 - 这是因为字符串在EXEC SQL段里面,所以ECPG 语法分析器根据SQL规则而不是C规则来解析它。 - 任何内嵌的反斜杠后续将按照C规格处理;但是\"会造成直接语法错误,因为它被视为文字的终结。 + 如果使用字符串字面量,请注意,要在 SQL 语句中包含的双引号必须写为八进制转义(\042),而不是通常的 C 写法\"。这是因为字符串位于EXEC SQL段中,ECPG 词法分析器会按照 SQL 规则而非 C 规则解析它。内嵌的反斜杠随后会按照 C 规则处理;但\"会被视为字面量的结束,因此会立即引起语法错误。 @@ -7672,19 +7668,19 @@ int rjulmdy(date d, short mdy[3]); rdefmtdate - 使用格式掩码将字符字符串转换为日期类型的值。 + 使用格式掩码将字符串转换为日期类型的值。 int rdefmtdate(date *d, char *fmt, char *str); 该函数接收一个指向应该保存操作结果的日期值的指针(d), 用于解析日期的格式掩码(fmt)和包含日期文本表示的C char*字符串 (str)。文本表示应与格式掩码匹配。但是,你不需要将字符串 - 与格式掩码进行一一映射。该函数仅分析顺序顺序,并查找表示年份位置的文字 + 与格式掩码进行一一映射。该函数只分析先后顺序,并查找表示年份位置的字面文本 yyyyyy,表示月份位置的mm 和表示日期位置的dd - 该函数返回以下值: + 该函数返回以下值: diff --git a/zh/14/event-trigger.sgml b/zh/14/event-trigger.sgml index 4367cc74..8edef841 100644 --- a/zh/14/event-trigger.sgml +++ b/zh/14/event-trigger.sgml @@ -20,11 +20,11 @@ - 事件触发器行为概览 + 事件触发器行为概述 只要与事件触发器关联的事件在其定义所在数据库中发生,事件触发器就会被触发。 - 目前唯一支持的事件有 + 目前仅支持以下事件: ddl_command_startddl_command_endtable_rewrite @@ -39,14 +39,14 @@ COMMENTGRANTREVOKE 命令即将执行之前。在事件触发器触发之前,不会检查受影响对象究竟存在还是不存在。 但有一个例外:对于以共享对象 — 数据库、角色和表空间 — - 为目标的 DDL 命令,或者针对事件触发器本身的命令,不会发生该事件。事件触发器机制 + 为目标的 DDL 命令或者针对事件触发器本身的命令,不会发生该事件。事件触发器机制 不支持这些对象类型。 ddl_command_start 也会在 SELECT INTO 命令即将执行之前发生,因为它等价于 CREATE TABLE AS - ddl_command_end 事件发生在与上述同一组命令执行之后。 + ddl_command_end 事件发生在上述同一组命令执行之后。 要获取这些 DDL 操作的更多细节,可在 ddl_command_end 事件触发器代码中使用集合返回函数 pg_event_trigger_ddl_commands()(见 @@ -1060,7 +1060,7 @@ CALLED_AS_EVENT_TRIGGER(fcinfo) ((fcinfo)->context != NULL && IsA((fcinfo)->context, EventTriggerData)) - 如果该宏返回 true,那么就可以安全地将 fcinfo->context + 如果该宏返回真,那么就可以安全地将 fcinfo->context 转换为 EventTriggerData * 类型,并使用它所指向的 EventTriggerData 结构体。该函数 不得修改 EventTriggerData @@ -1131,7 +1131,7 @@ typedef struct EventTriggerData 事件触发器函数必须返回一个 NULL 指针 (不是 SQL 空值,也就是不要将 - isNull 设为 true)。 + isNull 设为真)。 @@ -1150,13 +1150,11 @@ typedef struct EventTriggerData 中提到的例外)。 - - 以下是该触发器函数的源代码: -下面是触发器函数的源代码: - 相关对象包(从 开始) + 相关对象的包(从 开始) @@ -49,11 +49,28 @@ 可扩展性如何运作 - PostgreSQL 之所以具有可扩展性,是因为它的运作由目录驱动。如果你熟悉标准的关系数据库系统,就会知道它们会把数据库、表、列等信息存储在通常所说的系统目录中(有些系统称之为数据字典)。这些目录对用户来说看起来和普通表无异,但 DBMS 会在其中保存自己的内部记账信息。PostgreSQL 与标准关系数据库系统的一个关键区别在于,它在目录中存储了更多信息:不仅包括表和列的信息,还包括数据类型、函数、访问方法等信息。这些表可以由用户修改,而 PostgreSQL 又正是基于这些表运行的,这就意味着用户可以扩展 PostgreSQL。相比之下,传统数据库系统通常只能通过修改源代码中的硬编码过程,或装入由 DBMS 供应商专门编写的模块来扩展。 + PostgreSQL 之所以具有可扩展性,是因为其 + 运作由系统目录驱动。如果你熟悉标准的关系数据库系统,就会知道它们把 + 有关数据库、表、列等的信息存储在通常所说的系统目录中(有些系统把这 + 称为数据字典)。这些目录对用户而言看起来就像普通表一样,但 + DBMS 会在其中保存自己的内部管理信息。 + PostgreSQL 与标准关系数据库系统的一个关键差别是, + PostgreSQL 在目录中存储的信息要多得多:不仅有关于表和列的信息,还有关于数据 + 类型、函数、访问方法等的信息。这些表可以由用户修改,而 + PostgreSQL 又是基于这些表来运行的,这意味着 + PostgreSQL 可以由用户扩展。相比之下,传统数据库 + 系统只能通过修改源代码中的硬编码过程,或加载由 + DBMS 供应商专门编写的模块来扩展。 - 此外,PostgreSQL 服务器还可以通过动态加载将用户编写的代码纳入自身。也就是说,用户可以指定一个实现新类型或新函数的目标代码文件(例如共享库),而 PostgreSQL 会在需要时加载它。把用 SQL 编写的代码加入服务器就更简单了。这种能够即时修改自身行为的能力,使 PostgreSQL 特别适合用于新应用和新存储结构的快速原型设计。 + 此外,PostgreSQL 服务器还能通过动态加载把用户 + 编写的代码纳入自身。也就是说,用户可以指定一个实现了新类型或新函数 + 的目标代码文件(例如共享库),而 PostgreSQL + 会在需要时加载它。把用 SQL 编写的代码加入服务器就更 + 为简单了。这种能够即时修改自身行为的能力,使 + PostgreSQL 特别适合用于新应用和新存储结构的快速 + 原型设计。 @@ -75,7 +92,7 @@ 数据类型 - 组合 + 复合 @@ -500,7 +517,7 @@ RETURNS anycompatible AS ... 哪些 SQL 对象种类可以成为扩展成员,见 ALTER EXTENSION 的说明。特别是,数据库集簇范围内的对象,如数据库、角色和表空间,不能 - 成为扩展成员,因为扩展只在单个数据库内可见。(尽管扩展脚本并不禁止创 + 成为扩展成员,因为扩展只在单个数据库内可见。(尽管并不禁止扩展脚本创 建这类对象,但如果这样做,它们不会作为扩展的一部分受到跟踪。)还要注意, 虽然表可以成为扩展成员,但其附属对象(如索引)并不直接被视为扩展成员。 另一个重要点是,模式可以属于扩展,但反过来不成立:扩展本身只有一个非 @@ -535,10 +552,7 @@ RETURNS anycompatible AS ... 件指定不同的目录。 - - 扩展控制文件的其他查找位置可通过参数 - 配置。 - + 扩展控制文件的格式与 postgresql.conf 文件相同, @@ -558,8 +572,8 @@ RETURNS anycompatible AS ... 包含扩展 SQL 脚本文件的目录。除非给出的是绝对路 - 径,否则该名称相对于找到控制文件的目录。默认情况下,会在找到控制 - 文件的同一目录中查找脚本文件。 + 径,否则该名称相对于安装的 SHAREDIR 目录。默认行为 + 等价于指定 directory = 'extension' @@ -604,8 +618,8 @@ RETURNS anycompatible AS ... 该参数的值会替换脚本文件中每次出现的 MODULE_PATHNAME。如果未设置该参数,则不会进行替 - 换。通常会把它设置为简单的 - shared_library_name, + 换。通常会把它设置为 + $libdir/shared_library_name, 然后在 C 语言函数的 CREATE FUNCTION 命令中使用 MODULE_PATHNAME,这样脚本文件就无需把共享库的名 字硬编码进去。 @@ -624,19 +638,7 @@ RETURNS anycompatible AS ... - - no_relocate (string) - - - 本扩展所依赖且应禁止通过 - ALTER EXTENSION ... SET SCHEMA 更改其模式的扩展 - 名称列表。如果本扩展的脚本以无法跟踪重命名的方式引用了某个依赖扩展 - 的模式名(使用 - @extschema:name@ 语法), - 就需要设置它。 - - - + superuser (boolean) @@ -655,21 +657,7 @@ RETURNS anycompatible AS ... trusted (boolean) - - 如果该参数被设为 true(默认并非如此),则允许某些 - 非超级用户安装 superuser 设为 - true 的扩展。具体来说,任何在当前数据库上具有 - CREATE 权限的用户都被允许安装。当执行 - CREATE EXTENSION 的用户不是超级用户,但因该参数 - 而被允许安装时,安装或更新脚本会以引导超级用户的身份运行,而不是以 - 调用用户的身份运行。如果 superuser 为 - false,这个参数就没有意义。一般来说,对于可能让 - 用户访问原本只有超级用户才能使用的能力(如文件系统访问)的扩展,不 - 应把它设为 true。此外,把一个扩展标记为 - trusted,还需要付出大量额外努力来确保安装和更 - 新脚本写得足够安全;见 - 。 - + 如果将此参数设为 true(不是默认值),则允许某些非超级用户安装 superuser 设为 true 的扩展。具体而言,当前数据库上具有 CREATE 权限的任何人都可以安装。当执行 CREATE EXTENSION 的用户不是超级用户,但凭借此参数获准安装时,安装或更新脚本会以引导超级用户的身份运行,而不是调用用户的身份。如果 superuserfalse,则此参数不起作用。通常,对于可能允许访问原本仅限超级用户使用的能力(例如文件系统访问)的扩展,不应将此参数设为真。此外,将扩展标记为受信任的,需要投入大量额外工作来安全地编写其安装和更新脚本;参见 @@ -730,8 +718,8 @@ RETURNS anycompatible AS ... 如果扩展脚本中包含字符串 @extowner@,该字符串会被 替换为调用 CREATE EXTENSION 或 - ALTER EXTENSION 的用户名称(会作适当引用)。通常, - 这个特性被标记为 trusted 的扩展用来把选定对象的 + ALTER EXTENSION 的用户名称(会适当加上引号)。通常, + 这个特性被标记为受信任的扩展用来把选定对象的 所有权赋给调用用户, 而不是赋给引导超级用户。(不过这样做时应当谨慎。例如,把一个 C 语言 函数的所有权赋给非超级用户,会为该用户创建一条权限提升路径。) @@ -778,7 +766,7 @@ RETURNS anycompatible AS ... 扩展,应在控制文件中设置 relocatable = false,并在脚本文件中使用 @extschema@ 来引用目标模式。在脚本执行前,该字符 - 串的每次出现都会被替换为实际目标模式的名称(必要时加双引号)。用户 + 串的每次出现都会被替换为实际目标模式的名称。用户 可以通过 CREATE EXTENSIONSCHEMA 选项设置目标模式。 @@ -790,7 +778,7 @@ RETURNS anycompatible AS ... relocatable = false,并把 schema 设置为预定目标模式的名称。这样将阻止使用 CREATE EXTENSIONSCHEMA - 选项,除非它指定的正是控制文件中命名的那个模式。如果扩展对其模式名 + 选项,除非它指定的正是控制文件中命名的那个模式。如果扩展对模式名 称有无法通过 @extschema@ 替换解决的内部假设,通 常就需要采用这种方式。在这种情况下, @extschema@ 替换机制仍然可用,只是由于模式名由控 @@ -840,22 +828,7 @@ SET LOCAL search_path TO @extschema@, pg_temp; 合起来会比较方便。 - - 如果一个扩展引用了属于另一个扩展的对象,建议对这些引用加上模式限定。 - 做法是在扩展脚本文件中写 - @extschema:name@,其中 - name 是另一个扩展的名称(它必须列在本扩展的 - requires 列表中)。该字符串会被替换为那个扩展目标 - 模式的名称(必要时加双引号)。虽然这种记法避免了在扩展脚本文件中对模 - 式名作硬编码假设,但它的使用也可能把另一个扩展的模式名嵌入到本扩展安 - 装后生成的对象中。(典型情况是 - @extschema:name@ 出现 - 在字符串字面量中,例如函数体或 search_path 设置中。 - 在其他情况下,对象引用会在解析时简化为 OID,不需要后续查找。)如果另 - 一个扩展的模式名以这种方式被嵌入,那么在本扩展安装完成后,你应当通过 - 把那个扩展的名称加入本扩展的 no_relocate 列表,阻 - 止它再被重定位。 - + @@ -956,7 +929,7 @@ SELECT pg_catalog.pg_extension_config_dump('my_config', 'WHERE NOT standard_entr 在有合适更新脚本可用的前提下, - ALTER EXTENSION UPDATE 命令可以把已安装的扩展更新 + ALTER EXTENSION UPDATE 命令会把已安装的扩展更新 到指定的新版本。更新脚本运行在 CREATE EXTENSION 为安装脚本提供的同一环境中:尤其 是,search_path 的设置方式完全相同,而且脚本创建的 @@ -982,7 +955,7 @@ SELECT pg_catalog.pg_extension_config_dump('my_config', 'WHERE NOT standard_entr 例如,它并不知道 1.1 是否跟在 1.0 之后。它只是匹配可用的版本名,并选择需要应用 更新脚本最少的那条路径。(实际上,版本名可以是任何不包含 - --,且不以前导或尾随 - 结尾的字 + --,且不以 - 开头或结尾的字 符串。) @@ -1055,19 +1028,9 @@ SELECT * FROM pg_extension_update_paths('extension_name - - 将 superuser 属性设为 true 的 - 扩展,还必须考虑其安装脚本和更新脚本中操作所带来的安全风险。恶意用户并不难创建出特洛伊木 - 马对象,从而在后续粗心编写的扩展脚本执行时造成破坏,并借此获得超级用 - 户权限。 - + superuser 属性设为真的扩展,还必须考虑其安装和更新脚本所执行操作的安全风险。恶意用户可以创建木马对象,破坏以后对编写不慎的扩展脚本的执行,从而获得超级用户权限;这并非特别困难。 - - 如果一个扩展被标记为 trusted,那么安装用户可以自己 - 选择安装模式,而该用户可能会有意使用不安全的模式,希望借此获得超级用 - 户权限。因此,从安全角度看,trusted 扩展暴露程度 - 极高,必须仔细审查其所有脚本命令,确保不存在任何可被利用之处。 - + 如果扩展被标记为 trusted,那么安装用户可以选择其安装模式,而该用户可能故意使用不安全的模式,试图获得超级用户权限。因此,从安全角度看,受信任的扩展面临的风险极高,必须仔细检查其全部脚本命令,确保无法被攻破。 关于如何安全地编写函数,建议见下面的 @@ -1115,7 +1078,7 @@ SELECT * FROM pg_extension_update_paths('extension_namemyschema.myfunc(bigint),那么像 myschema.myfunc(42) 这样的调用,就可能被恶意函数 myschema.myfunc(integer) 截获。要注意函数和操作符 - 参数的数据类型必须与声明的实参类型精确匹配,必要时请使用显式类型转 + 所传参数的数据类型必须与声明的参数类型精确匹配,必要时请使用显式类型转 换。 @@ -1152,10 +1115,12 @@ SELECT * FROM pg_extension_update_paths('extension_name - 安全的跨扩展引用通常要求使用 - @extschema:name@ 语法为其 - 他扩展对象的名称加上模式限定,并且还要仔细匹配函数和操作符的参数类 - 型。 + 跨扩展引用要做到完全安全是极其困难的,部分原因是无法确定另一个扩展 + 位于哪个模式中。如果两个扩展都安装在同一个模式中,风险就会降低, + 因为这样恶意对象就无法在安装时的 search_path 中 + 被放到被引用扩展之前。但目前还没有机制来强制要求这一点。就目前而言, + 最佳实践是:如果一个扩展依赖于另一个扩展,就不要将它标记为受信任的, + 除非那个被依赖的扩展始终安装在 pg_catalog 中。 @@ -1164,7 +1129,7 @@ SELECT * FROM pg_extension_update_paths('extension_name扩展示例 - 下面给出一个纯 SQL 扩展的完整示例:一个双元素组合 + 下面给出一个纯 SQL 扩展的完整示例:一个双元素复合 类型,它可以在两个槽位中存储任意类型的值,这两个槽位名为 kv。非文本值会自动强制转换为文本后 再存储。 @@ -1245,7 +1210,7 @@ include $(PGXS) 如果你打算分发自己的 PostgreSQL 扩展模块, - 那么为它们搭建一个可移植的构建系统会相当困难。因此, + 那么为它们搭建一个可移植的构建系统可能相当困难。因此, PostgreSQL 安装提供了一套称为 PGXS 的扩展构建基础设施,使简单的扩展模块可以针对 已安装好的服务器直接构建。PGXS 主要面向包含 C 代码 @@ -1296,7 +1261,7 @@ include $(PGXS) MODULE_big - 要从多个源文件构建的共享库(在 OBJS 中列出对象 + 要从多个源文件构建的共享库(在 OBJS 中列出目标 文件) @@ -1306,7 +1271,7 @@ include $(PGXS) PROGRAM - 要构建的可执行程序(在 OBJS 中列出对象文件) + 要构建的可执行程序(在 OBJS 中列出目标文件) @@ -1601,33 +1566,7 @@ include $(PGXS) make 命令行上设置都可以。 - - 你还可以在执行 make install 时,通过设置 - make 变量 prefix 来选择一个独立 - 的目录前缀,以安装扩展文件,例如: - -make install prefix=/usr/local/postgresql - - 这样会把扩展控制文件和 SQL 文件安装到 - /usr/local/postgresql/share,把共享模块安装到 - /usr/local/postgresql/lib。如果该前缀不包含 - postgrespgsql 字符串,例如: - -make install prefix=/usr/local/extras - - 那么 postgresql 会被附加到目录名中,从而把控制文件 - 和 SQL 文件安装到 - /usr/local/extras/share/postgresql/extension, - 把共享模块安装到 - /usr/local/extras/lib/postgresql。无论哪种情况, - 你都需要设置 和 - ,以便 - PostgreSQL 服务器能找到这些文件: - -extension_control_path = '/usr/local/extras/share/postgresql:$system' -dynamic_library_path = '/usr/local/extras/lib/postgresql:$libdir' - - + 如果你想保持构建目录与源代码目录分离,也可以在扩展源代码树之外的目录 @@ -1661,7 +1600,7 @@ make VPATH=/path/to/extension/source/tree install 正在运行的 PostgreSQL 服务器。列在 REGRESS 中的脚本文件必须位于扩展目录下名为 sql/ 的子目录中。这些文件必须具有 - .sql 扩展名,而该扩展名不应出现在 makefile 的 + .sql 扩展名,而该扩展名不能出现在 makefile 的 REGRESS 列表中。对于每个测试,还应在名为 expected/ 的子目录中有一个包含期望输出的文件,其主 干名相同,扩展名为 .out。 @@ -1680,7 +1619,7 @@ make VPATH=/path/to/extension/source/tree install 必须有一个正在运行的 PostgreSQL 服务器。列 在 ISOLATION 中的脚本文件必须位于扩展目录下名为 specs/ 的子目录中。这些文件必须具有 - .spec 扩展名,而该扩展名不应出现在 makefile 的 + .spec 扩展名,而该扩展名不能出现在 makefile 的 ISOLATION 列表中。对于每个测试,还应在名为 expected/ 的子目录中有一个包含期望输出的文件,其主 干名相同,扩展名为 .out。 diff --git a/zh/14/features.sgml b/zh/14/features.sgml index 5a589af3..147a2225 100644 --- a/zh/14/features.sgml +++ b/zh/14/features.sgml @@ -406,7 +406,7 @@ SELECT XMLQUERY('$a is $b' PASSING BY VALUE x AS a, < DOCUMENTCONTENT形式的值。 一个 XQuery/XPath 表达式的上下文项必须是单个 XML 节点或原子值, 但 XPath 1.0 又进一步限制它只能是 XML 节点,并且没有允许CONTENT的节点类型。 - 归根结底,格式良好的DOCUMENT是 + 归根结底,良构的DOCUMENTPostgreSQL能够作为 XPath 上下文项提供的唯一 XML 值形式。 diff --git a/zh/14/func.sgml b/zh/14/func.sgml index 51943716..2a1c07d9 100644 --- a/zh/14/func.sgml +++ b/zh/14/func.sgml @@ -39,20 +39,17 @@ repeat('Pg', 4) PgPgPgPg 逻辑操作符 - operator - logical + 操作符 + 逻辑 - Boolean - operators - operators, logical + 布尔 + 操作符 + 操作符,逻辑 - - 常用的逻辑操作符有: - - + 可以使用以下常见逻辑操作符: AND(操作符) @@ -65,15 +62,15 @@ repeat('Pg', 4) PgPgPgPg - conjunction + 合取 - disjunction + 析取 - negation + 否定 @@ -82,9 +79,7 @@ repeat('Pg', 4) PgPgPgPg NOT boolean boolean - SQL使用三值的逻辑系统,包括真、假和nullnull表示未知。观察下面的真值表: - - + SQL使用由真、假和null构成的三值逻辑系统,其中null表示未知。请看下面的真值表: @@ -181,8 +176,8 @@ repeat('Pg', 4) PgPgPgPg 比较函数和操作符 - comparison - operators + 比较 + 操作符 @@ -265,14 +260,14 @@ repeat('Pg', 4) PgPgPgPg - <>not equal 的标准 SQL 符号。 + <>不等于 的标准 SQL 符号。 != 是一个别名,在解析的早期阶段就会被转换为 <>。 因此,不可能让 !=<> 操作符执行不同的操作。 - 这些比较操作符适用于所有具有自然排序的内置数据类型,包括数字、字符串和日期/时间类型。 + 这些比较操作符适用于所有具有自然排序的内置数据类型,包括数值、字符串和日期/时间类型。 此外,如果其组成数据类型具有可比性,则也可以比较数组、复合类型和范围。 @@ -318,7 +313,7 @@ repeat('Pg', 4) PgPgPgPg boolean - 之间(包括范围端点)。 + 位于两者之间(包括范围端点)。 2 BETWEEN 1 AND 3 @@ -414,7 +409,7 @@ repeat('Pg', 4) PgPgPgPg boolean - 测试值是否为空。 + 测试值是否为 null。 1.5 IS NULL @@ -428,7 +423,7 @@ repeat('Pg', 4) PgPgPgPg boolean - 测试值是否不为空。 + 测试值是否不为 null。 'null' IS NOT NULL @@ -442,7 +437,7 @@ repeat('Pg', 4) PgPgPgPg boolean - 测试值是否为空(非标准语法)。 + 测试值是否为 null(非标准语法)。 @@ -452,7 +447,7 @@ repeat('Pg', 4) PgPgPgPg boolean - 测试值是否不为空(非标准语法)。 + 测试值是否不为 null(非标准语法)。 @@ -573,22 +568,14 @@ repeat('Pg', 4) PgPgPgPg BETWEEN SYMMETRIC - - BETWEEN谓词可以简化范围测试: - + BETWEEN谓词可以简化范围测试: a BETWEEN x AND y - - 等效于 - +等价于 a >= x AND a <= y - - 注意BETWEEN认为终点值是包含在范围内的。 - BETWEEN SYMMETRIC 就像BETWEEN,除了没有要求AND的左边的参数小于或等于右边的参数。 - 如果不是的话,这两个参数将自动交换,因此总是隐含一个非空范围。 - +注意,BETWEEN将两个端点值都视为包含在范围内。BETWEEN SYMMETRIC类似于BETWEEN,但不要求AND左侧的参数小于或等于右侧的参数。如果不是这样,这两个参数会自动交换,以确保表示的范围始终非空。 - BETWEEN的各种变量都是以普通比较操作符的方式实现的,因此适用于任何可以比较的数据类型。 + BETWEEN的各种变体都是以普通比较操作符的方式实现的,因此适用于任何可以比较的数据类型。 @@ -607,12 +594,12 @@ repeat('Pg', 4) PgPgPgPg IS NOT DISTINCT FROM - 当有一个输入为空时,普通的比较操作符会得到空(表示未知),而不是真或假。例如,7 = NULL得到空,7 <> NULL也一样。如果这种行为不合适,可以使用IS NOT DISTINCT FROM谓词: + 当任一输入为 null 时,普通的比较操作符会得到 null(表示未知),而不是真或假。例如,7 = NULL得到 null,7 <> NULL也一样。如果这种行为不合适,可以使用IS NOT DISTINCT FROM谓词: a IS DISTINCT FROM b a IS NOT DISTINCT FROM b - 对于非空输入,IS DISTINCT FROM<>操作符一样。不过,如果两个输入都为空,它会返回假。而如果只有一个输入为空,它会返回真。类似地,IS NOT DISTINCT FROM对于非空输入的行为与=相同,但是当两个输入都为空时它返回真,并且当只有一个输入为空时返回假。因此,这些谓词实际上把空值当作一种普通数据值,而不是未知。 + 对于非 null 输入,IS DISTINCT FROM<>操作符一样。不过,如果两个输入都为 null,它会返回假。而如果只有一个输入为 null,它会返回真。类似地,IS NOT DISTINCT FROM对于非 null 输入的行为与=相同,但是当两个输入都为 null 时它返回真,并且当只有一个输入为 null 时返回假。因此,这些谓词实际上把 null 当作一种普通数据值,而不是未知 @@ -628,7 +615,7 @@ repeat('Pg', 4) PgPgPgPg NOTNULL - 要检查一个值是否为空,使用下面的谓词: + 要检查一个值是否为 null,使用下面的谓词: expression IS NULL expression IS NOT NULL @@ -638,7 +625,7 @@ repeat('Pg', 4) PgPgPgPg expression ISNULL expression NOTNULL - null valuecomparing + 空值比较 @@ -648,24 +635,12 @@ repeat('Pg', 4) PgPgPgPg - 有些应用可能要求表达式expression = NULLexpression得出空值时返回真。我们强烈建议这样的应用修改成遵循 SQL 标准。但是,如果这样修改不可能完成,那么我们可以使用配置变量。如果打开它,PostgreSQL将把x = NULL子句转换成x IS NULL。 + 有些应用可能期望表达式expression = NULLexpression求值为 null 时返回真。我们强烈建议此类应用修改为遵循 SQL 标准。但是,如果无法这样修改,那么可以使用配置变量。如果将其打开,PostgreSQL会把x = NULL子句转换成x IS NULL - 如果expression是行值,那么当行表达式本身为 null 或其所有字段都为 null 时,IS NULL 为真;而当行表达式本身非 null 且其所有字段都非 null 时,IS NOT NULL 为真。由于这种行为,IS NULLIS NOT NULL并不总是对行值表达式返回相反的结果;特别是,一个同时包含 null 和非 null 字段的行值表达式会对这两种测试都返回假。例如: - - -SELECT ROW(1,2.5,'this is a test') = ROW(1, 3, 'not the same'); - -SELECT ROW(table.*) IS NULL FROM table; -- detect all-null rows - -SELECT ROW(table.*) IS NOT NULL FROM table; -- detect all-non-null rows - -SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in rows - - - 在某些情况下,写成row IS DISTINCT FROM NULL或者row IS NOT DISTINCT FROM NULL可能更合适,因为它们只会检查整个行值是否为 null,而不会再对行字段做额外测试。 + 如果expression是行值,那么当行表达式本身为 null 或其所有字段都为 null 时,IS NULL 为真;而当行表达式本身非 null 且其所有字段都非 null 时,IS NOT NULL 为真。由于这种行为,IS NULLIS NOT NULL并不总是对行值表达式返回相反的结果;特别是,一个同时包含 null 和非 null 字段的行值表达式会对这两种测试都返回假。在某些情况下,写成row IS DISTINCT FROM NULL或者row IS NOT DISTINCT FROM NULL可能更合适,因为它们只会检查整个行值是否为 null,而不会再对行字段做额外测试。 @@ -696,7 +671,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in boolean_expression IS UNKNOWN boolean_expression IS NOT UNKNOWN - 这些谓词将总是返回真或假,从来不返回空值,即使操作数为空也如此。空值输入被当作逻辑值未知。请注意,IS UNKNOWNIS NOT UNKNOWN实际上分别等同于IS NULLIS NOT NULL,只是输入表达式必须是布尔类型。 + 这些谓词总是返回真或假,从不返回空值,即使操作数为 null 也是如此。null 输入被当作逻辑值未知。请注意,IS UNKNOWNIS NOT UNKNOWN实际上分别等同于IS NULLIS NOT NULL,只是输入表达式必须是布尔类型。 @@ -733,7 +708,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in integer - 返回非空参数的数量。 + 返回非 null 参数的数量。 num_nonnulls(1, NULL, 2) @@ -750,7 +725,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in integer - 返回空参数的数量。 + 返回 null 参数的数量。 num_nulls(1, NULL, 2) @@ -768,11 +743,11 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in 数学函数和操作符 - PostgreSQL为很多类型提供了数学操作符。对于那些没有标准数学表达的类型(如日期/时间类型),我们将在后续小节中描述实际的行为。 + PostgreSQL为很多类型提供了数学操作符。对于那些没有标准数学惯例的类型(如日期/时间类型),我们将在后续小节中描述实际的行为。 - 显示了可用于标准数字类型的数学操作符。 + 显示了可用于标准数值类型的数学操作符。 除非另有说明,显示为可接受 numeric_type 的操作符对所有的 smallintintegerbigintnumericrealdouble precision 类型都可用。 显示为可接受 integral_type 的操作符对 smallintintegerbigint类型是可用的。 除了特别说明之处,操作符的每种形式都返回与其参数相同的数据类型。 @@ -821,7 +796,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in numeric_type - 一元加(无操作) + 一元正号(不执行操作) + 3.5 @@ -849,7 +824,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in numeric_type - 否定 + 取负 - (-4) @@ -877,7 +852,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in numeric_type - 除(对于整型,除法将结果截断为零) + 除法(对于整数类型,除法将结果向零截断) 5.0 / 2 @@ -917,14 +892,14 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in double precision - 指数 + 求幂 2 ^ 3 8 - 不像典型的数学实践,多次使用 ^ 将会默认从左到右关联: + 与通常的数学惯例不同,多次使用^时默认从左到右结合: 2 ^ 3 ^ 3 @@ -984,7 +959,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in integral_type - 按位与(AND) + 按位与 91 & 15 @@ -998,7 +973,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in integral_type - 按位或(OR) + 按位或 32 | 3 @@ -1012,7 +987,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in integral_type - 按位异或(exclusive OR) + 按位异或 17 # 5 @@ -1026,7 +1001,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in integral_type - 按位求反(NOT) + 按位非 ~1 @@ -1071,7 +1046,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in 许多这样的函数以多种具有不同的参数类型的形式提供。 除非注明,任何给定形式的函数都返回与其参数相同的数据类型;跨类型情况的解决方法与上述对操作符的解释相同。 使用double precision数据的函数大多是在主机系统的 C 库上实现的; - 因此,边界情况下的准确性和行为会因主机系统的区别而不同。 + 因此,精度和边界情况下的行为可能因主机系统而异。 @@ -1202,7 +1177,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in numeric - y/x 的整数商(截断为零位) + y/x 的整数商(向零截断) div(9, 4) @@ -1223,7 +1198,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in double precision - 指数 (e 的给定次方) + 指数函数(e的给定次幂) exp(1.0) @@ -1273,26 +1248,6 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in - - - - gamma - - gamma ( double precision ) - double precision - - - 伽马函数 - - - gamma(0.5) - 1.772453850905516 - - - gamma(6) - 120 - - @@ -1328,22 +1283,6 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in - - - - lgamma - - lgamma ( double precision ) - double precision - - - 伽马函数绝对值的自然对数 - - - lgamma(1000) - 5905.220423209181 - - @@ -1432,7 +1371,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in integer - 精确表示所提供值所需的最小刻度(小数位数) + 精确表示给定值所需的最少小数位数 min_scale(8.4100) @@ -1529,7 +1468,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in double precision - 四舍五入到最近的整数。 + 舍入到最接近的整数。 对于numeric,遇到恰好位于中点的情况时按远离零的方向舍入。 对于double precision,中点取舍规则取决于平台,但舍入到最接近的偶数是最常见的规则。 @@ -1566,7 +1505,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in integer - 参数的刻度(小数点后的位数) + 参数的小数位数(小数部分的十进制位数) scale(8.4100) @@ -1625,7 +1564,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in numeric - 通过删除尾数部分的零来降低值的刻度(小数位数) + 通过移除尾随零来减少值的小数位数 trim_scale(8.4100) @@ -1646,7 +1585,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in double precision - 截断整数 (向零靠近) + 向零截断为整数 trunc(42.8) @@ -1664,7 +1603,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in numeric - 截断 vs 位小数位置的数字 + 将v截断到s位小数 trunc(42.4382, 2) @@ -1777,7 +1716,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in
- random()函数使用确定性伪随机数生成器。 + random()函数使用简单的线性同余算法。 它速度快,但不适用于加密应用;请参阅模块以获取更安全的替代方案。 如果调用setseed(),则当前会话中后续random()调用的结果序列可以通过使用相同参数重新发出setseed()来重复。 在同一会话中没有任何先前的setseed()调用时,第一个random()调用从平台相关的随机位源获取种子。 @@ -2090,7 +2029,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in - 另一种使用以角度度量的角的方法是使用早前展示的单位转换函数radians()degrees()。不过,使用基于角度的三角函数更好,因为这类方法能避免sind(30)等特殊情况下的舍入偏差。 + 另一种使用以角度度量的角的方法是使用早前展示的单位转换函数radians()degrees()。不过,使用基于角度的三角函数更好,因为这类方法能避免sind(30)等特殊情况下的舍入误差。 @@ -2163,7 +2102,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in double precision - 双曲切线 + 双曲正切 tanh(1) @@ -2214,7 +2153,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in double precision - 反双曲切线 + 反双曲正切 atanh(0.5) @@ -2236,7 +2175,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in 这里的字符串包括charactercharacter varyingtext类型的值。 除非另有说明,这些函数和操作符都声明为接受并返回text类型。 它们也可互换地接受character varying参数。 - 在应用函数或操作符之前,character类型的值会先转换为text,因此会去除其尾随空格。 + 在应用函数或操作符之前,character类型的值会先转换为text,因此会去除 character 值的尾随空格。 @@ -2247,7 +2186,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in 字符串串接操作符(||)将接受非字符串输入,只要至少一个输入是一种字符串类型,如所示。 - 对于其他情况,向text插入一个显式强制,可用于接受非字符串输入。 + 对于其他情况,可以添加到text的显式强制转换,以接受非字符串输入。
@@ -2275,14 +2214,14 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in - character string - concatenation + 字符串 + 串接 text || text text - 连接两个字符串。 + 串接两个字符串。 'Post' || 'greSQL' @@ -2300,8 +2239,8 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 将非字符串输入转换为文本,然后将两个字符串串联在一起。 - (非字符串输入不能为数组类型,因为这将在||操作符的数组中造成歧义。如果你想连接一个数组的文本相等的,请显式地将其转换为text 。) + 将非字符串输入转换为文本,然后将两个字符串串接起来。 + (非字符串输入不能是数组类型,因为那样会与数组的||操作符产生歧义。如果要串接数组的文本表示,请显式地将其转换为text。) 'Value: ' || 42 @@ -2312,10 +2251,10 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in - normalized + 规范化 - Unicode normalization + Unicode 规范化 text IS NOT form NORMALIZED boolean @@ -2355,13 +2294,13 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in char_length - character string - length + 字符串 + 长度 - length + 长度 字符串 - character string, length + 字符串,长度 char_length ( text ) integer @@ -2391,7 +2330,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 根据数据库的语言环境规则,将字符串转换为全部小写。 + 根据数据库的区域设置规则,将字符串转换为全部小写。 lower('TOM') @@ -2405,16 +2344,14 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in normalize - Unicode normalization + Unicode 规范化 normalize ( text , form ) text - 将字符串转换为指定的 Unicode 规范化形式。 - 可选的form关键字指定如下形式:NFC(默认)、NFDNFKCNFKD。 - 该函数只能在服务器编码为UTF8时使用。 + 将字符串转换为指定的 Unicode 规范化形式。可选的 form 关键字指定如下形式:NFC(默认值)、NFDNFKCNFKD。该函数只能在服务器编码为 UTF8 时使用。 normalize(U&'\0061\0308bc', NFC) @@ -2465,8 +2402,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 替换stringstart字符开始的子串,并用newsubstring扩展到count字符。 - 如果省略了count,则默认为newsubstring的长度。 + 用newsubstring替换string中从第start个字符开始、长度为count个字符的子字符串。如果省略count,则默认为newsubstring的长度。 overlay('Txxxxas' placing 'hom' from 2 for 4) @@ -2483,7 +2419,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in integer - 返回string中指定的substring的第一个起始索引,如果不存在则返回零,。 + 返回substringstring中首次出现的位置;如果不存在则返回零。 position('om' in 'Thomas') @@ -2500,9 +2436,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 如果已指定,提取stringstart字符开始的子串, - 并且在count字符后停止。如果已指定的话。 - 提供至少一个startcount中的至少一个。 + 提取string的子字符串:若指定了起始位置,则从第start个字符开始;若指定了长度,则在提取count个字符后停止。startcount至少需要指定一个。 substring('Thomas' from 2 for 3) @@ -2524,7 +2458,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 提取匹配POSIX正则表达式的第一个子字符串; 参见 。 + 提取匹配 POSIX 正则表达式的第一个子字符串;参见 substring('Thomas' from '...$') @@ -2542,8 +2476,8 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 提取匹配 SQL 正则表达式的第一个字串;参见 。 - 第一种形式自从SQL:2003被指定,第二种形式仅在SQL:1999中,并应认为是废弃的。 + 提取匹配 SQL 正则表达式的第一个子字符串;参见 。 + 第一种形式自 SQL:2003 起由标准规定;第二种形式只出现在 SQL:1999 中,应视为已过时。 substring('Thomas' similar '%#"o_a#"_' escape '#') @@ -2595,7 +2529,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 根据数据库的定位规则,将字符串转换为所有大写。 + 根据数据库的区域设置规则,将字符串转换为全部大写。 upper('tom') @@ -2606,21 +2540,17 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in - - 还有其他字符串操作函数和操作符,列在中。 - (其中一些用于内部实现中列出的SQL标准字符串函数。) - 此外,中还描述了模式匹配操作符,中则描述了全文搜索操作符。 - + 还有其他字符串操作函数,列在 中。其中一些用于内部实现 中列出的 SQL 标准字符串函数。 - 其他字符串函数和操作符 + 其他字符串函数 - 函数/操作符 + 函数 描述 @@ -2633,25 +2563,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in - - - - - 字符串 - 前缀测试 - - text ^@ text - boolean - - - 如果第一个字符串以第二个字符串开头,则返回true(等同于starts_with()函数)。 - - - 'alphabet' ^@ 'alph' - t - - - + @@ -2662,7 +2574,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in integer - 返回参数的第一个字符的数字代码。在UTF8编码中,返回该字符的Unicode代码点。 + 返回参数的第一个字符的数字代码。在UTF8编码中,返回该字符的Unicode 码点。 在其他多字节编码中,该参数必须是一个ASCII字符。 @@ -2671,6 +2583,8 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in + + @@ -2681,7 +2595,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 从string的开头或结尾删除最长的只包含characters(默认是一个空格)的字符串 + 从string的开头和结尾移除仅由characters中字符(默认为空格)组成的最长字符串。 btrim('xyxtrimyyx', 'xyz') @@ -2698,7 +2612,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 返回给定代码的字符。在UTF8编码中该参数被视作一个Unicode代码点。 + 返回给定代码的字符。在UTF8编码中该参数被视作一个Unicode 码点。 在其他多字节编码中该参数必须指定一个ASCII字符。 chr(0) 字符不被允许,因为文本数据类型不能存储这种字符。 @@ -2718,7 +2632,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 连接所有参数的文本表示。空参数被忽略。 + 串接所有参数的文本表示。NULL 参数被忽略。 concat('abcde', 2, NULL, 22) @@ -2737,7 +2651,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 用分隔符连接除第一个参数外的所有参数。第一个参数用作分隔符字符串,不应为NULL。其他NULL参数将被忽略。 + 用分隔符串接除第一个参数外的所有参数。第一个参数用作分隔符字符串,不应为NULL。其他NULL参数将被忽略。 concat_ws(',', 'abcde', 2, NULL, 22) @@ -2791,7 +2705,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 以字符串返回第一个 n 字符,或在 n 为负时, 返回最后 |n| 个字符之外的全部字符。 + 返回字符串最左侧的 n 个字符;如果 n 为负,则返回除最后 |n| 个字符之外的全部字符。 left('abcde', 2) @@ -2816,6 +2730,8 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in + + @@ -2827,8 +2743,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 将string扩展为长度length,通过前置字符fill(默认空格)。 - 如果string已经超过length那么它将被截断(在右侧)。 + 在string前面添加字符fill(默认为空格),将其填充到长度length。如果string已经长于length,则从右侧截断。 lpad('hi', 5, 'xy') @@ -2836,6 +2751,8 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in + + @@ -2846,7 +2763,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 从string开始删除包含characters(默认空格)中仅包含字符的最长字符串。 + 从string的开头移除仅由characters中字符(默认为空格)组成的最长字符串。 ltrim('zzzytest', 'xyz') @@ -2881,10 +2798,10 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text[] - 将qualified_identifier拆分为一个标识符数组,删除单个标识符的任何引用。 + 将qualified_identifier拆分为一个标识符数组,去除各个标识符的引号。 默认情况下,最后一个标识符之后的额外字符被视为错误;但是,如果第二个参数为false,则忽略这些额外的字符。 (这种行为对于解析类似函数的对象的名称有作用。) - 请注意,此函数不会截断超长标识符。如果你想截断,你可以把结果给到name[]。 + 请注意,此函数不会截断超长标识符。如果你想截断,你可以将结果转换为name[] parse_ident('"SomeSchema".someTable') @@ -2918,9 +2835,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 返回适合引用的给定字符串,作为SQL语句字符串中的标识符。 - 只有在必要的情况下才添加引号(例如,如果字符串包含非标识符字符或将被大小写折叠)。 - 嵌入的引号被适当地加双引号。参见。 + 为给定字符串添加适当的引号并返回,使其可用作SQL语句字符串中的标识符。仅在必要时(即字符串包含不能用于标识符的字符,或会发生大小写折叠时)添加引号。内嵌的引号会被适当地双写。另见 quote_ident('Foo bar') @@ -2937,9 +2852,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 返回在SQL语句字符串中适当引用的给定字符串,用作字符串文字使用。 - 嵌入式单引号和反斜线适当的翻倍(转双引号或双斜线)。 - 请注意,quote_literal在参数为 null 时返回 null;如果这个参数可能为空,quote_nullable通常更合适。另请参阅。 + 为给定字符串添加适当的引号并返回,使其可用作SQL语句字符串中的字符串字面量。内嵌的单引号和反斜杠会被适当地双写。注意,quote_literal在输入为 null 时返回 null;如果参数可能为 null,quote_nullable通常更合适。另见 quote_literal(E'O\'Reilly') @@ -2953,8 +2866,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 将给定的值转换为文本,然后将其作为字面量引用。 - 内嵌的单引号和反斜杠被适当地翻倍。 + 将给定值转换为文本,然后作为字面量加引号。内嵌的单引号和反斜杠会被适当地双写。 quote_literal(42.5) @@ -2971,8 +2883,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 返回在SQL语句字符串中经过适当引用的给定字符串文字;或者,如果参数为空值,则返回NULL。 - 内嵌的单引号和反斜杠被适当地翻倍。参见。 + 为给定字符串添加适当的引号并返回,使其可用作SQL语句字符串中的字符串字面量;如果参数为 null,则返回NULL。内嵌的单引号和反斜杠会被适当地双写。另见 quote_nullable(NULL) @@ -2986,8 +2897,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 将给定值转换为文本,然后将其作为字面量引用;或者,如果参数为null,则返回NULL。 - 内嵌的单引号和反斜杠被适当地翻倍。 + 将给定值转换为文本,然后作为字面量加引号;如果参数为 null,则返回NULL。内嵌的单引号和反斜杠会被适当地双写。 quote_nullable(42.5) @@ -2995,68 +2905,8 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in - - - - regexp_count - - regexp_count ( string text, pattern text - [, start integer - [, flags text ] ] ) - integer - - - 返回 POSIX 正则表达式patternstring中匹配的次数;参见。 - - - regexp_count('123456789012', '\d\d\d', 2) - 3 - - - - - - regexp_instr - - regexp_instr ( string text, pattern text - [, start integer - [, N integer - [, endoption integer - [, flags text - [, subexpr integer ] ] ] ] ] ) - integer - - - 返回string中第N个匹配项的POSIX正则表达式pattern出现的位置,如果没有这样的匹配项,则返回零;参见。 - - - regexp_instr('ABCDEF', 'c(.)(..)', 1, 1, 0, 'i') - 3 - - - regexp_instr('ABCDEF', 'c(.)(..)', 1, 1, 0, 'i', 2) - 5 - - - - - - regexp_like - - regexp_like ( string text, pattern text - [, flags text ] ) - boolean - - - 检查 POSIX 正则表达式pattern是否在string中出现;参见。 - - - regexp_like('Hello World', 'world$', 'i') - t - - @@ -3066,9 +2916,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in regexp_match ( string text, pattern text [, flags text ] ) text[] - - 返回第一个匹配的POSIX正则表达式patternstring中的子字符串;参见。 - + 返回 POSIX 正则表达式首次匹配 string 时捕获的子字符串;参见 regexp_match('foobarbequebaz', '(bar)(beque)') {bar,beque} @@ -3083,10 +2931,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in regexp_matches ( string text, pattern text [, flags text ] ) setof text[] - - 返回第一个匹配的 POSIX 正则表达式patternstring中的子字符串,或者如果使用了g标志,则返回所有匹配的子字符串; - 参见。 - + 返回 POSIX 正则表达式首次匹配 string 时捕获的子字符串;如果使用 g 标志,则返回多次匹配捕获的子字符串;参见 regexp_matches('foobarbequebaz', 'ba.', 'g') @@ -3097,18 +2942,18 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in + + regexp_replace - regexp_replace ( string text, pattern text, replacement text - [, start integer ] - [, flags text ] ) + regexp_replace ( string text, pattern text, replacement text [, flags text ] ) text - 替换第一个与 POSIX 正则表达式pattern匹配的子字符串,如果使用了g标志,则替换所有这样的匹配;参见。 + 替换第一个与 POSIX 正则表达式匹配的子字符串,如果使用了g标志,则替换所有这样的匹配;参见 regexp_replace('Thomas', '.[mN]a.', 'M') @@ -3116,23 +2961,6 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in - - - regexp_replace ( string text, pattern text, replacement text, - start integer, - N integer - [, flags text ] ) - text - - - 替换字符串中第N个与 POSIX 正则表达式pattern匹配的子字符串,如果N为零,则替换所有匹配项;参见。 - - - regexp_replace('Thomas', '.', 'X', 3, 2) - ThoXas - - - @@ -3171,31 +2999,6 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in - - - - regexp_substr - - regexp_substr ( string text, pattern text - [, start integer - [, N integer - [, flags text - [, subexpr integer ] ] ] ] ) - text - - - 返回string中与第N个出现的POSIX正则表达式pattern匹配的子字符串, - 如果没有这样的匹配,则返回NULL;参见。 - - - regexp_substr('ABCDEF', 'c(.)(..)', 1, 1, 'i') - CDEF - - - regexp_substr('ABCDEF', 'c(.)(..)', 1, 1, 'i', 2) - EF - - @@ -3225,7 +3028,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 将string 中当前的子串from替换为子串to。 + 将string中所有出现的子字符串from替换为子字符串to replace('abcdefabcdef', 'cd', 'XX') @@ -3260,7 +3063,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 返回字符串中的最后n个字符,或者在n>为负时,返回除了前面的|n|字符之外的所有字符。 + 返回字符串中的最后n个字符;如果n为负数,则返回除前 |n| 个字符之外的全部字符。 right('abcde', 2) @@ -3268,6 +3071,8 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in + + @@ -3279,8 +3084,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 扩展 string 到长度 length,通过追加fill 字符(默认为空格). - 如果string 已经比 length 长,则截断它。 + 在string后面追加字符fill(默认为空格),将其填充到长度length。如果string已经长于length,则截断它。 rpad('hi', 5, 'xy') @@ -3288,6 +3092,8 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in + + @@ -3298,7 +3104,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 从string末尾删除包含characters(默认为空格)中仅包含字符的最长字符串。 + 从string的结尾移除仅由characters中字符(默认为空格)组成的最长字符串。 rtrim('testxxzx', 'xyz') @@ -3317,7 +3123,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 在delimiter出现时拆分string,并且返回第n个字段(从一计数),或者当n为负数时,返回|n|'th-from-last 字段。 + 在出现delimiter时拆分string,并返回第n个字段(从一开始计数);如果n为负数,则返回倒数第 |n| 个字段。 split_part('abc~@~def~@~ghi', '~@~', 2) @@ -3329,6 +3135,44 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in + + + + strpos + + strpos ( string text, substring text ) + integer + + + 返回substringstring中首次出现的位置;如果不存在则返回零。(与position(substring in string)相同,但请注意参数顺序相反。) + + + strpos('high', 'ig') + 2 + + + + + + + substr + + substr ( string text, start integer , count integer ) + text + + + 提取string中从第start个字符开始的子字符串;若指定了长度,则提取count个字符。(与substring(string from start for count)相同。) + + + substr('alphabet', 3) + phabet + + + substr('alphabet', 3, 2) + ph + + + @@ -3359,7 +3203,6 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in 如果delimiterNULL,则string中的每个字符将成为数组中的一个单独元素。 如果delimiter是空字符串,则string被视为单个字段。 如果提供了null_string且不是NULL,则匹配该字符串的字段将被NULL替换。 - 另请参见array_to_string string_to_array('xx~~yy~~zz', '~~', 'yy') @@ -3392,46 +3235,6 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in - - - - strpos - - strpos ( string text, substring text ) - integer - - - 返回在string中指定的substring的第一个起始索引,如果不存在则为零。 - (与(substringstring中的)位置相同,但是请注意反转的参数顺序) - - - strpos('high', 'ig') - 2 - - - - - - - substr - - substr ( string text, start integer , count integer ) - text - - - 提取stringstart字符开始的子字符串,并扩展count字符,如果指定了的话。 - (与 子字符串(stringstart 开始计数 count)相同。) - - - substr('alphabet', 3) - phabet - - - substr('alphabet', 3, 2) - ph - - - @@ -3451,10 +3254,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 将string从另一个编码中转换为ASCII,该编码可按名称或编号标识。 - 如果encoding被省略,则假定数据库编码(这在实践中是唯一有用的案例)。转换主要包括降音。 - 转换仅支持来自 LATIN1LATIN2LATIN9、 和 WIN1250 的编码. - (其他请参见 模块, 更灵活的解决方案。) + 将string从其他编码转换为ASCII,源编码可以用名称或编号指定。如果省略encoding,则使用数据库编码(实际上,这也是唯一有用的情况)。转换主要是去除重音符号。只支持从LATIN1LATIN2LATIN9WIN1250编码转换。(另一种更灵活的解决方案参见模块。) to_ascii('Karél') @@ -3495,7 +3295,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in string中与from集合中匹配的每个字符替换为to集合中相应的字符。 - 如果from长于tofrom中出现的额外字符被删除。 + 如果from长于to,输入中出现的from中的额外字符会被删除。 translate('12345', '143', 'ax') @@ -3512,10 +3312,10 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 计算参数中的转义Unicode字符。 + 解析参数中转义的 Unicode 字符。 Unicode字符可以被指定为\XXXX (4个十六进制数字),\+XXXXXX(6个十六进制数字),\uXXXX(4个十六进制数字),或\UXXXXXXXX (8个十六进制数字)。 要指定反斜杠,请写入两个反斜杠。 - 所有其他字符都是按字面意义的。 + 所有其他字符均按字面解释。 @@ -3523,7 +3323,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in - 这个函数提供了一个(非标准的)替代到Unicode转义的字符串常量(参见)。 + 此函数提供了带 Unicode 转义的字符串常量的另一种(非标准)写法(参见)。 @@ -3541,12 +3341,12 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in
- concatconcat_wsformat函数是可变的,因此可以把要串接或格式化的值作为一个标记了VARIADIC关键字的数组进行传递(见)。 - 数组的元素被当作函数的独立普通参数一样处理。如果可变数组参数为 NULL,concatconcat_ws返回 NULL,但format把 NULL 当作一个零元素数组。 + concatconcat_wsformat是可变参数函数,因此可以把要串接或格式化的值作为一个标记了VARIADIC关键字的数组进行传递(见)。 + 数组的元素被当作函数的独立普通参数一样处理。如果可变参数数组为 NULL,concatconcat_ws返回 NULL,但format把 NULL 当作一个零元素数组。 - 还可以参阅中的string_agg,以及中的字符串和bytea类型之间转换的功能。 + 还可以参阅中的聚合函数string_agg,以及中的字符串和bytea类型之间转换的函数。 @@ -3564,22 +3364,22 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in format(formatstr text [, formatarg "any" [, ...] ]) - formatstr是一个格式字符串,它指定了结果应该如何被格式化。格式字符串中的文本被直接复制到结果中,除了使用格式说明符的地方。格式说明符在字符串中扮演着占位符的角色,它定义后续的函数参数如何被格式化及插入到结果中。每一个formatarg参数会被根据其数据类型的常规输出规则转换为文本,并接着根据格式说明符被格式化和插入到结果字符串中。 + formatstr是指定结果格式的字符串。格式字符串中的文本会直接复制到结果中,但格式说明符所在的位置除外。格式说明符充当字符串中的占位符,定义如何格式化后续函数参数并将其插入结果。每个formatarg参数都按照其数据类型通常的输出规则转换为文本,再根据格式说明符进行格式化并插入结果字符串。
- 格式说明符由一个%字符开始并且有这样的形式 + 格式说明符以%字符开头,格式如下: %[position][flags][width]type - 其中的各组件域是: + 其中各组成字段为: position(可选) - 一个形式为n$的字符串,其中n是要打印的参数的索引。索引 1 表示formatstr之后的第一个参数。如果position被忽略,默认会使用序列中的下一个参数。 + 一个形式为n$的字符串,其中n是要打印的参数的索引。索引 1 表示formatstr之后的第一个参数。如果position被省略,默认会使用序列中的下一个参数。 @@ -3587,9 +3387,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in flags(可选) - - 控制格式说明符的输出如何被格式化的附加选项。当前唯一支持的标志是一个负号(-),它将导致格式说明符的输出会被左对齐(left-justified)。除非width域也被指定,否者这个域不会产生任何效果。 - + 用于控制格式说明符输出格式的附加选项。目前唯一支持的标志是减号(-),它使格式说明符的输出左对齐。只有同时指定了width字段时,它才有效。 @@ -3601,8 +3399,8 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in - 如果宽度来自于一个函数参数,则参数在被格式说明符的值使用之前就被消耗掉了。如果宽度参数是负值,结果会在长度为abs(width)的域中被左对齐(如果-标志被指定)。 - + 如果宽度来自一个函数参数,会先使用该宽度参数,再使用作为格式说明符值的参数。如果宽度参数为负数,结果会在长度为abs(width)的字段中左对齐(如同指定了-标志)。 +
@@ -3619,12 +3417,12 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in - I将参数值视作 SQL 标识符,并在必要时用双写引号包围它。如果参数为空,将会是一个错误(等效于quote_ident)。 + I将参数值视作 SQL 标识符,并在必要时用双引号包围它。如果参数为 null,则会报错(等效于quote_ident)。 - L将参数值引用为 SQL 文字。一个空值将被显示为不带引号的字符串NULL(等效于quote_nullable)。 + L将参数值作为 SQL 字面量加引号。null 值显示为不带引号的字符串NULL(等效于quote_nullable)。 @@ -3635,13 +3433,10 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in - 除了以上所述的格式说明符之外,要输出一个文字形式的%字符,可以使用特殊序列%%。 + 除了以上所述的格式说明符之外,要输出一个字面形式的%字符,可以使用特殊序列%% - - 下面有一些基本的格式转换的示例: - - + 下面是一些基本格式转换的示例: SELECT format('Hello %s', 'World'); 结果:Hello World @@ -3652,14 +3447,11 @@ SELECT format('INSERT INTO %I VALUES(%L)', 'Foo bar', E'O\'Reilly'); 结果:INSERT INTO "Foo bar" VALUES('O''Reilly') SELECT format('INSERT INTO %I VALUES(%L)', 'locations', 'C:\Program Files'); -结果:INSERT INTO locations VALUES(E'C:\\Program Files') +结果:INSERT INTO locations VALUES('C:\Program Files') - - 下面是使用width域和-标志的示例: - - + 下面是使用width字段和-标志的示例: SELECT format('|%10s|', 'foo'); 结果:| foo| @@ -3680,10 +3472,7 @@ SELECT format('|%-*s|', -10, 'foo'); - - 这些示例展示了position域的示例: - - + 这些示例展示了如何使用position字段: SELECT format('Testing %3$s, %2$s, %1$s', 'one', 'two', 'three'); 结果:Testing three, two, one @@ -3695,10 +3484,8 @@ SELECT format('|%1$*2$s|', 'foo', 10, 'bar'); - - 不同于标准的 C 函数sprintfPostgreSQLformat函数允许将带有或者不带有position域的格式说明符被混在同一个格式字符串中。一个不带有position域的格式说明符总是使用最后一个被消耗的参数的下一个参数。另外,format函数不要求所有函数参数都被用在格式字符串中。例如: - - + 不同于标准 C 函数sprintf, + PostgreSQLformat函数允许在同一个格式字符串中,混合使用带有或不带有position字段的格式说明符。不带position字段的格式说明符,总是使用最后一个已使用参数之后的下一个参数。此外,format函数不要求格式字符串使用全部函数参数。例如: SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); 结果:Testing three, two, three @@ -3716,17 +3503,17 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); 二进制串函数和操作符 - binary data - functions + 二进制数据 + 函数 - 本节描述那些检查和操作二进制字符串的函数和操作符,这是类型bytea的值。 + 本节描述用于检查和操作二进制字符串(即bytea类型的值)的函数和操作符。 其中许多函数在用途和语法上都与上一节中描述的文本字符串函数等效。 - SQL定义了一些使用关键字而不是逗号来分割参数的串函数。详情请见PostgreSQL也提供了这些函数使用常规函数调用语法的版本(参阅)。 + SQL定义了一些使用关键字而不是逗号来分隔参数的字符串函数。详情请见PostgreSQL也提供了这些函数使用常规函数调用语法的版本(参阅)。 @@ -3753,14 +3540,14 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); - binary string - concatenation + 二进制串 + 串接 bytea || bytea bytea - 连接两个二进制字符串。 + 串接两个二进制字符串。 '\x123456'::bytea || '\x789a00bcde'::bytea @@ -3811,8 +3598,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bytea - 将bytes的子字符串替换为newsubstring,该子字符串从start字节开始,并以count字节扩展。 - 如果忽略了count,则默认为newsubstring的长度。 + 用newsubstring替换bytes中从第start个字节开始、长度为count个字节的子字符串。如果省略count,则默认为newsubstring的长度。 overlay('\x1234567890'::bytea placing '\002\003'::bytea from 2 for 3) @@ -3829,7 +3615,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); integer - 返回bytes中指定的substring的第一个起始索引,如果不存在,则为零。 + 返回substringbytes中首次出现的位置;如果不存在则返回零。 position('\x5678'::bytea in '\x1234567890'::bytea) @@ -3846,8 +3632,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bytea - 提取bytesstart字节开始的子字符串,如果指定了,并且在count字节之后停止,如果指定了的话。 - 至少提供startcount中的一个。 + 提取bytes的子字符串:若指定了起始位置,则从第start个字节开始;若指定了长度,则在提取count个字节后停止。startcount至少需要指定一个。 substring('\x1234567890'::bytea from 3 for 2) @@ -3866,7 +3651,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bytea - 删除bytesremoved中只包含字节的最长字符串,从bytes的开始、结束,或两端(BOTH 为默认的)。 + 从bytes的开头、结尾或两端(默认为BOTH)移除仅由bytesremoved中字节组成的最长字符串。 trim('\x9012'::bytea from '\x1234567890'::bytea) @@ -3882,7 +3667,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bytea - 这是trim()的非标准语法。 + 这是一个非标准的trim()语法。 trim(both from '\x1234567890'::bytea, '\x9012'::bytea) @@ -3894,7 +3679,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three');
- 还有一些二进制串处理函数可以使用,在列出。 其中有一些是在内部使用,用于实现列出的 SQL 标准串函数。 + 还有一些二进制串处理函数可以使用,在列出。 其中有一些是在内部使用,用于实现列出的 SQL 标准串函数。 @@ -3931,7 +3716,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bigint - 返回二进制字符串中设置的位数(也被认为popcount)。 + 返回二进制字符串中被置位的位数(也称为popcount)。 bit_count('\x1234567890'::bytea) @@ -3939,6 +3724,8 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); + + @@ -3949,7 +3736,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bytea - 从bytes的开始和结束处删除只包含bytesremoved中出现的字节的最长字符串 + 从bytes的开头和结尾移除仅由bytesremoved中字节组成的最长字符串。 btrim('\x1234567890'::bytea, '\x9012'::bytea) @@ -3967,7 +3754,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); integer - 从二进制字符串中提取 n'th 位。 + 从二进制字符串中提取 编号为 n 的 位。 get_bit('\x1234567890'::bytea, 30) @@ -3985,7 +3772,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); integer - 从二进制字符串中提取 n'th 字节。 + 从二进制字符串中提取 编号为 n 的 字节。 get_byte('\x1234567890'::bytea, 4) @@ -3999,13 +3786,13 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); length - binary string - length + 二进制串 + 长度 - length - 二进制字符串 - binary strings, length + 长度 + 二进制串 + 二进制串,长度 length ( bytea ) integer @@ -4034,6 +3821,8 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); + + @@ -4044,8 +3833,8 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bytea - 从bytes开头移除出现在bytesremoved中的只包含字节的最长字符串。 - + 从bytes的开头移除仅由bytesremoved中字节组成的最长字符串。 + ltrim('\x1234567890'::bytea, '\x9012'::bytea) \x34567890 @@ -4069,6 +3858,8 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); + + @@ -4079,8 +3870,8 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bytea - 从bytes结尾移除出现在bytesremoved中的只包含字节的最长字符串。 - + 从bytes的结尾移除仅由bytesremoved中字节组成的最长字符串。 + rtrim('\x1234567890'::bytea, '\x9012'::bytea) \x12345678 @@ -4098,7 +3889,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bytea - 设置二进制字符串中的n'th位为newvalue。 + 设置二进制字符串中的编号为 n 的位为newvalue set_bit('\x1234567890'::bytea, 30, 0) @@ -4117,7 +3908,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bytea - 设置二进制字符串中的 n'th 字节到 newvalue。 + 设置二进制字符串中的 编号为 n 的 字节到 newvalue set_byte('\x1234567890'::bytea, 4, 64) @@ -4172,7 +3963,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); sha384('abc'::bytea) - \xcb00753f45a35e8bb5a03d699ac65007&zwsp;272c32ab0ed1631a8b605a43ff5bed&zwsp;8086072ba1e7cc2358baeca134c825a7 + \xcb00753f45a35e8bb5a03d699ac65007&zwsp;272c32ab0eded1631a8b605a43ff5bed&zwsp;8086072ba1e7cc2358baeca134c825a7 @@ -4189,7 +3980,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); sha512('abc'::bytea) - \xddaf35a193617abacc417349ae204131&zwsp;12e6fa4e89a97ea20a9ee64b55d39a&zwsp;2192992a274fc1a836ba3c23a3feebbd&zwsp;454d4423643ce80e2a9ac94fa54ca49f + \xddaf35a193617abacc417349ae204131&zwsp;12e6fa4e89a97ea20a9eeee64b55d39a&zwsp;2192992a274fc1a836ba3c23a3feebbd&zwsp;454d4423643ce80e2a9ac94fa54ca49f @@ -4202,8 +3993,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bytea - 从start字节开始提取bytes的子字符串,并扩展为count字节,如果这是指定的。 - (与 substring(bytesstartcount) 相同.) + 提取bytes中从第start个字节开始的子字符串;若指定了长度,则提取count个字节。(与substring(bytes from start for count)相同。) substr('\x1234567890'::bytea, 3, 2) @@ -4215,7 +4005,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three');
- 函数get_byteset_byte把一个二进制串中的一个字节计数为字节 0。 + 函数get_byteset_byte把二进制串中的第一个字节编号为字节 0。 函数get_bitset_bit在每一个字节中从右边起计数位; 例如位 0 是第一个字节的最低有效位,而位 15 是第二个字节的最高有效位。 @@ -4223,16 +4013,16 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); 由于历史原因,函数md5返回的是一个十六进制编码的text值,而SHA-2函数返回类型bytea。 可以使用函数encodedecode在两者之间转换。 - 例如encode(sha256('abc'),'hex')可以得到一个十六进制编码的文本表示,或者decode(md5('abc'), 'hex')得到一个bytea 值。 + 例如encode(sha256('abc'), 'hex')可以得到一个十六进制编码的文本表示,或者decode(md5('abc'), 'hex')得到一个bytea 值。 - character string + 字符串 转换为二进制字符串 - binary string + 二进制串 转换为字符串 用于在不同字符集(编码)之间转换字符串的函数,以及用于以文本形式表示任意二进制数据的函数,在中显示。 @@ -4241,7 +4031,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); - 文本/字符串转换函数 + 文本/二进制串转换函数 @@ -4373,9 +4163,9 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); base64格式是RFC 2045第6.8节中描述的。根据RFC,编码行在76个字符处换行。 - 然而,与MIME CRLF换行符不同,结尾只使用换行符。 + 然而,与MIME CRLF换行符不同,行尾只使用一个换行符。 decode函数会忽略回车、换行、空格和制表符。 - 否则,当decode提供无效的base64数据时,包括尾部填充不正确时,会引发错误。 + 否则,当向decode传入无效的 base64 数据时,包括尾部填充不正确时,会引发错误。 @@ -4387,8 +4177,8 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); - escape格式将零字节和高位设置的字节转换为八进制转义序列 - (\nnn),并将反斜杠加倍。 + escape格式将零字节和最高位被置位的字节转换为八进制转义序列 + (\nnn),并将反斜杠双写。 其他字节值会直接表示。如果反斜杠后面不是第二个反斜杠或三个八进制数字,则decode函数会引发错误; 它会接受其他字节值不变。 @@ -4403,10 +4193,10 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); hex格式将每4位数据表示为一个十六进制数字,0f, - 先写入每个字节的高阶数字。 encode函数以小写输出a-f十六进制数字。 + 先写入每个字节的高位数字。 encode函数以小写输出a-f十六进制数字。 因为数据的最小单位是8位,所以encode总是返回偶数个字符。 decode函数接受a-f字符的大小写。 - 当decode提供无效的十六进制数据时,包括提供奇数个字符时,会引发错误。 + 当向decode传入无效的十六进制数据时,包括提供奇数个字符时,会引发错误。 @@ -4423,14 +4213,14 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); 位串函数和操作符 - bit strings - functions + 位串 + 函数 本节描述用于检查和操作位串的函数和操作符,也就是操作类型为bitbit varying的值的函数和操作符。 - (虽然这些表中只提到了bit类型,但bit varying类型的值可以互换使用。) - 位字符串支持中显示的常用比较操作符,就像中显示的操作符。 + (虽然这些表中只提到了bit类型,但bit varying类型的值可以互换使用。) + 位串支持中显示的常用比较操作符,以及中显示的操作符。
@@ -4460,7 +4250,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bit - 连接 + 串接 B'10001' || B'011' @@ -4516,7 +4306,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bit - 按位求反 + 按位非 ~ B'10001' @@ -4556,12 +4346,12 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three');
- 一些可用于二进制字符串的函数也可用于位字符串,如中所示。 + 一些可用于二进制字符串的函数也可用于位串,如中所示。 - 位字符串函数 + 位串函数 @@ -4589,7 +4379,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bigint - 返回位字符串中设置的位数(也被视为popcount)。 + 返回位串中被置位的位数(也称为popcount)。 bit_count(B'10111') @@ -4606,7 +4396,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); integer - 返回位字符串中的位数。 + 返回位串中的位数。 bit_length(B'10111') @@ -4620,14 +4410,14 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); length - bit string - length + 位串 + 长度 length ( bit ) integer - 返回位字符串中的位数。 + 返回位串中的位数。 length(B'10111') @@ -4644,7 +4434,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); integer - 返回位字符串中的字节数。 + 返回位串中的字节数。 octet_length(B'1011111011') @@ -4661,8 +4451,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bit - 替换从start位开始的bits的子字符串,并将newsubstring扩展count位。 - 如果count被省略,默认为newsubstring的长度。 + 用newsubstring替换bits中从第start位开始、长度为count位的子串。如果省略count,则默认为newsubstring的长度。 overlay(B'01010101010101010' placing B'11111' from 2 for 3) @@ -4679,7 +4468,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); integer - 按返回指定substring的第一个起始索引,以bits为单位,如果不存在则返回0。 + 返回substringbits中首次出现的位置;如果不存在则返回零。 position(B'010' in B'000001101011') @@ -4696,8 +4485,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bit - 如果指定了起始位,则提取从start位开始的bits的子字符串,如果指定了计数位,则在count位之后停止。 - startcount至少提供一个。 + 提取bits的子串:若指定了起始位置,则从第start位开始;若指定了长度,则在提取count位后停止。startcount至少需要指定一个。 substring(B'110010111111' from 3 for 2) @@ -4715,7 +4503,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); integer - 从位字符串中提取第n位;第一个(最左)位为第0位。 + 从位串中提取编号为n的位;第一位(最左侧的位)编号为位 0。 get_bit(B'101010101010101010', 6) @@ -4734,7 +4522,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bit - 将位字符串中的第n位设置为newvalue;第一个(最左)位是第0位。 + 将位串中编号为n的位设置为newvalue;第一位(最左侧的位)编号为位 0。 set_bit(B'101010101010101010', 6, 0) @@ -4745,18 +4533,12 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three');
- - 另外,我们可以在整数和bit之间来回转换。 - 将一个整数转换为bit(n)会复制最右边的n位。 - 将一个整数转换为比整数本身更宽的位字符串宽度将在左边进行符号扩展。一些示例: - + 此外,还可以在整数值与bit类型之间进行类型转换。将整数转换为bit(n)会复制最右侧的n位。将整数转换为宽度超过该整数自身位宽的位串时,会在左侧进行符号扩展。下面是一些示例: 44::bit(10) 0000101100 44::bit(3) 100 cast(-44 as bit(12)) 111111010100 '1110'::bit(4)::integer 14 - - 请注意,如果只是转换为bit,意思是转换成bit(1),因此只会转换整数的最低有效位。 - +注意,仅转换为bit意味着转换为bit(1),因此只会得到该整数的最低有效位。 @@ -4764,11 +4546,11 @@ cast(-44 as bit(12)) 111111010100 模式匹配 - pattern matching + 模式匹配 - PostgreSQL提供了三种独立的实现模式匹配的方法:SQL LIKE操作符、更近一些的SIMILAR TO操作符(SQL:1999 里添加进来的)和POSIX-风格的正则表达式。除了这些基本的这个串匹配这个模式吗?操作符外,还有一些函数可用于提取或替换匹配子串并在匹配位置分离一个串。 + PostgreSQL提供了三种独立的模式匹配方法:传统的SQL LIKE操作符、较新的SIMILAR TO操作符(在 SQL:1999 中加入),以及POSIX风格的正则表达式。除了用于判断这个字符串是否匹配这个模式?的基本操作符外,还提供了提取或替换匹配子字符串、在匹配位置分割字符串的函数。 @@ -4781,25 +4563,20 @@ cast(-44 as bit(12)) 111111010100 - 虽然大部分的正则表达式搜索都能被很快地执行,但是正则表达式仍可能被 - 人为地弄成需要任意长的时间和任意量的内存进行处理。要当心从不怀好意 - 的来源接受正则表达式搜索模式。如果必须这样做,建议加上语句超时限制。 + 虽然大多数正则表达式搜索都能很快完成,但特意构造的正则表达式可能需要任意长的处理时间和任意多的内存。接受来自恶意来源的正则表达式搜索模式时应当谨慎。如果必须这样做,建议设置语句超时。 - 使用SIMILAR TO模式的搜索具有同样的安全性危险, - 因为SIMILAR TO提供了很多和 - POSIX-风格正则表达式相同的能力。 + 使用SIMILAR TO模式进行搜索具有同样的安全风险,因为SIMILAR TO提供了许多与POSIX风格正则表达式相同的能力。 - LIKE搜索比其他两种选项简单得多,因此在使用 - 不怀好意的模式来源时要更安全些。 + LIKE搜索比另外两种方法简单得多,因此,当模式可能来自恶意来源时,使用它更安全。 - SIMILAR TOPOSIX-风格正则表达式不支持非确定性排序规则。如果需要的话,可以使用LIKE或在表达式中应用不同的排序规则来绕过这个限制。 + 这三种模式匹配操作符都不支持非确定性排序规则。如有需要,可以对表达式应用不同的排序规则来绕过这一限制。 @@ -4819,7 +4596,11 @@ cast(-44 as bit(12)) 111111010100
- 如果pattern不包含百分号或者下划线,那么该模式只代表它本身的串;这时候LIKE的行为就象等号操作符。在pattern里的下划线 (_)代表(匹配)任何单个字符; 而一个百分号(%)匹配任何零或更多个字符的序列。 + 如果pattern不包含百分号或下划线,那么该模式只表示它 + 本身的字符串;在这种情况下,LIKE的行为就像等号操作符。 + pattern中的下划线(_)代表 + (匹配)任意单个字符;百分号(%)匹配任意由零个或多个 + 字符组成的序列。 @@ -4833,23 +4614,26 @@ cast(-44 as bit(12)) 111111010100 - LIKE模式匹配总是覆盖整个串。因此,要匹配在串内任何位置的序列,该模式必须以百分号开头和结尾。 + LIKE模式匹配总是覆盖整个字符串。因此,如果想要匹配字符串内 + 任意位置上的一个序列,该模式就必须以百分号开头并以百分号结尾。 - 要匹配文本的下划线或者百分号,而不是匹配其它字符, 在pattern里相应的字符必须 前导转义字符。缺省的转义字符是反斜线,但是你可以用ESCAPE子句指定一个不同的转义字符。 要匹配转义字符本身,写两个转义字符。 + 要匹配字面量下划线或百分号而不是把它们当作通配符, + pattern中相应的字符前面必须带有转义字符。 + 默认的转义字符是反斜线,但也可以使用ESCAPE子句选择其他 + 转义字符。要匹配转义字符本身,请写两个转义字符。 - 如果你关掉了,你在文串常量中写的任何反斜线都需要被双写。详见。 + 如果你关掉了,你在字符串常量中写的任何反斜线都需要被双写。详见 - 请注意反斜线在串文本里已经有特殊含义了,所以如果你写一个 包含反斜线的模式常量,那你就要在 SQL 语句里写两个反斜线。 因此,写一个匹配单个反斜线的模式实际上要在语句里写四个反斜线。 你可以通过用 ESCAPE 选择一个不同的转义字符 来避免这样;这样反斜线就不再是 LIKE 的特殊字符了。 但仍然是字符文本分析器的特殊字符,所以你还是需要两个反斜线。) - 我们也可以通过写ESCAPE ''的方式不选择转义字符,这样可以有效地禁用转义机制,但是没有办法关闭下划线和百分号在模式中的特殊含义。 + 也可以通过写 ESCAPE '' 来选择不使用转义字符。这会禁用转义机制,从而无法关闭模式中下划线和百分号的特殊含义。 @@ -4858,7 +4642,7 @@ cast(-44 as bit(12)) 111111010100 - 关键字ILIKE可以用于替换LIKE,它令该匹配根据活动区域成为大小写无关。(但这不支持非确定性排序规则。)这个不属于SQL标准而是一个PostgreSQL扩展。 + 可以用关键字 ILIKE 代替 LIKE,使匹配根据当前区域设置忽略大小写。这不属于 SQL 标准,而是 PostgreSQL 的扩展。 @@ -4869,14 +4653,11 @@ cast(-44 as bit(12)) 111111010100 - 短语LIKEILIKENOT LIKE,和 NOT ILIKEPostgreSQL语法中通常被视为操作符; - 例如,它们可以用于expression operator的任何(subquery)构造,尽管这里不能包含ESCAPE子句。 - 在某些晦涩难懂的情况下,可能需要用底层操作符名称替代。 + 在 PostgreSQL 语法中,LIKEILIKENOT LIKENOT ILIKE 通常被当作操作符;例如,它们可以用于 expression operator ANY (subquery) 构造,但其中不能包含 ESCAPE 子句。在某些不常见的情况下,可能需要改用底层操作符名称。 - 另请参阅以^@开头的操作符和相应的starts_with()函数, - 在需要简单匹配字符串开头的情况下非常有用。 + 另请参见前缀操作符 ^@ 和相应的 starts_with 函数,它们适用于只需匹配字符串开头的情况。 @@ -4885,8 +4666,8 @@ cast(-44 as bit(12)) 111111010100 <function>SIMILAR TO</function>正则表达式 - regular expression - + 正则表达式 + @@ -4903,13 +4684,11 @@ cast(-44 as bit(12)) 111111010100 - SIMILAR TO操作符根据自己的模式是否匹配给定串而返回真或者假。 - 它和LIKE非常类似,只不过它使用 SQL 标准定义的正则表达式理解模式。 - SQL 正则表达式是在LIKE标记和普通的(POSIX)正则表达式标记的奇怪的杂交。 + SIMILAR TO操作符根据其模式是否匹配给定字符串返回真或假。它与LIKE非常相似,但使用 SQL 标准定义的正则表达式来解释模式。SQL 正则表达式是LIKE表示法与普通(POSIX)正则表达式表示法的一种奇特结合。 - 类似LIKESIMILAR TO操作符只有在它的模式匹配整个串的时候才能成功;这一点和普通的 正则表达式的行为不同,在普通的正则表达式里,模式匹配串的任意部分。 和LIKE类似的地方还有,SIMILAR TO使用_%作为分别代表任意单个字符和任意串的通配符(这些可以比得上 POSIX 正则表达式里的..*)。 + 与LIKE类似,SIMILAR TO操作符只有在其模式匹配整个字符串时才算成功;这一点不同于普通正则表达式,后者可以匹配字符串的任意部分。与LIKE相同,SIMILAR TO也使用_%作为通配符,分别匹配任意单个字符和任意字符串(分别类似于 POSIX 正则表达式中的..*)。 @@ -4977,8 +4756,7 @@ cast(-44 as bit(12)) 111111010100 - 另一个非标准扩展是,在转义字符后面跟着一个字母或数字提供了对为POSIX正则表达式定义的转义序列的访问;参见下面的 - ,和 。 + 另一个非标准扩展是在转义字符后跟一个字母或数字,以使用 POSIX 正则表达式定义的转义序列;参见下文的 @@ -4994,19 +4772,19 @@ cast(-44 as bit(12)) 111111010100 - 带有三个参数的substring函数可以提取匹配SQL正则表达式模式的子字符串。 该函数可以按照标准SQL99语法编写。 + 带有三个参数的substring函数可以提取匹配 SQL 正则表达式模式的子字符串。该函数可以按照标准 SQL 语法书写: substring(string similar pattern escape escape-character) - 或使用现在废除的 SQL:1999 语法: + 也可以使用现已过时的 SQL:1999 语法: substring(string from pattern for escape-character) - 或作为一个普通的三参数函数: + 或写成普通的三参数函数: substring(string, pattern, escape-character) - 与SIMILAR TO一样,指定的模式必须与整个数据字符串匹配,否则函数失败并返回空值。 为了表示匹配的数据子字符串的模式中,模式中应该包含两个转义字符的出现,并在后面加上一个双引号(")。 匹配成功后,将返回与这些分隔符之间的模式部分匹配的文本。 + 与SIMILAR TO一样,指定的模式必须匹配整个数据字符串,否则函数失败并返回空值。为了指明要提取的子字符串所对应的模式部分,模式中应包含两个分隔符,每个分隔符都由转义字符后跟双引号(")组成。匹配成功时,返回与这两个分隔符之间的模式部分匹配的文本。 @@ -5014,7 +4792,7 @@ substring(string, pattern, - 作为对SQL标准的扩展,PostgreSQL只允许有一个转义双引号分隔符,在这种情况下,第三个正则表达式被视为空;或者没有分隔符,在这种情况下,第一个和第三个正则表达式被视为空。 + 作为对SQL标准的扩展,PostgreSQL允许仅有一个转义双引号分隔符,在这种情况下,第三个正则表达式被视为空;或者没有分隔符,在这种情况下,第一个和第三个正则表达式被视为空。 @@ -5027,64 +4805,31 @@ substring('foobar' similar '#"o_b#"%' escape '#') NULL - <acronym>POSIX</acronym>正则表达式 - regular expression - pattern matching + 正则表达式 + 模式匹配 - substring + regexp_replace + regexp_match + regexp_matches + regexp_split_to_table + regexp_split_to_array - - regexp_count - + + 列出了所有可用于 POSIX 正则表达式模式匹配的操作符。 + - - regexp_instr - + - - regexp_like - + 正则表达式匹配操作符 - - regexp_match - - - - regexp_matches - - - - regexp_replace - - - - regexp_split_to_table - - - - regexp_split_to_array - - - - regexp_substr - - - - 列出了所有可用于 POSIX 正则表达式模式匹配的操作符。 - - -
- - 正则表达式匹配操作符 - - - + + @@ -5107,7 +4852,7 @@ substring('foobar' similar '#"o_b#"%' escape '#') NULLboolean - 字符串匹配正则表达式,大小写敏感 + 字符串匹配正则表达式,区分大小写 'thomas' ~ 't.*ma' @@ -5121,7 +4866,7 @@ substring('foobar' similar '#"o_b#"%' escape '#') NULLboolean - 字符串匹配正则表达式,大小写不敏感 + 字符串匹配正则表达式,不区分大小写 'thomas' ~* 'T.*ma' @@ -5135,7 +4880,7 @@ substring('foobar' similar '#"o_b#"%' escape '#') NULLboolean - 字符串不匹配正则表达式,大小写敏感 + 字符串不匹配正则表达式,区分大小写 'thomas' !~ 't.*max' @@ -5149,7 +4894,7 @@ substring('foobar' similar '#"o_b#"%' escape '#') NULLboolean - 字符串不匹配正则表达式,大小写不敏感 + 字符串不匹配正则表达式,不区分大小写 'thomas' !~* 'T.*ma' @@ -5161,16 +4906,14 @@ substring('foobar' similar '#"o_b#"%' escape '#') NULL - POSIX正则表达式提供了比LIKESIMILAR TO操作符更强大的含义。许多 Unix 工具,例如egrepsedawk使用一种与我们这里描述的类似的模式匹配语言。 + POSIX正则表达式提供了比LIKESIMILAR TO操作符更强大的模式匹配方式。许多 Unix 工具,例如egrepsedawk,都使用与这里描述的模式匹配语言相似的语言。 - 正则表达式是一个字符序列,它是定义一个串集合 (一个正则集)的缩写。 如果一个串是正则表达式描述的正则集中的一员时, 我们就说这个串匹配该正则表达式。 和LIKE一样,模式字符准确地匹配串字符, 除非在正则表达式语言里有特殊字符 — 不过正则表达式用的 特殊字符和LIKE用的不同。 和LIKE模式不一样的是,正则表达式允许匹配串里的任何位置,除非该正则表达式显式地挂接在串的开头或者结尾。 + 正则表达式是一个字符序列,是定义一组字符串(一个正则集)的简写。如果字符串属于正则表达式描述的正则集,就称该字符串匹配此正则表达式。与LIKE一样,模式中的字符精确匹配字符串中的字符,除非该模式字符在正则表达式语言中有特殊含义 — 但正则表达式使用的特殊字符与LIKE不同。与LIKE模式不同,正则表达式可以匹配字符串中的任意位置,除非显式将其锚定到字符串开头或末尾。 - - 一些示例: - + 下面是一些示例: 'abcd' ~ 'bc' true 'abcd' ~ 'a.c' true — 点号匹配任意单个字符 'abcd' ~ 'a.*d' true — * 重复前一个模式项 @@ -5186,106 +4929,42 @@ substring('foobar' similar '#"o_b#"%' escape '#') NULL 带两个参数的substring函数,即substring(string from pattern),提供了抽取一个匹配 POSIX 正则表达式模式的子串的方法。 - 如果没有匹配它返回空值,否则就是匹配模式的文本中的第一部分。 - 但是如果该模式包含任何圆括号,那么将返回匹配第一对子表达式(对应第一个左圆括号的) 的文本。 + 如果没有匹配它返回空值,否则返回文本中首次匹配模式的那部分内容。 + 但是如果该模式包含任何圆括号,那么将返回匹配第一个圆括号子表达式(左圆括号最先出现的那个)的文本。 如果你想在表达式里使用圆括号而又不想导致这个例外,那么你可以在整个表达式外边放上一对圆括号。 如果你需要在想抽取的子表达式前有圆括号,参阅后文描述的非捕获性圆括号。 - - 一些示例: - + 下面是一些示例: substring('foobar' from 'o.b') oob substring('foobar' from 'o(.)b') o - - regexp_count函数计算 POSIX 正则表达式模式与字符串匹配的次数。 - 它的语法为 - regexp_count(string, - pattern - , start - , flags - )。 - patternstring中进行搜索, - 通常从字符串的开头开始,但如果提供了start参数,则从该字符索引开始。 - flags参数是一个可选的文本字符串,包含零个或多个单字母标志,改变函数的行为。 - 例如,在flags中包含i指定不区分大小写匹配。 - 支持的标志在中描述。 - - - - 一些示例: - -regexp_count('ABCABCAXYaxy', 'A.') 3 -regexp_count('ABCABCAXYaxy', 'A.', 1, 'i') 4 - - - - - regexp_instr函数返回字符串中第N个匹配项的起始或结束位置,如果没有这样的匹配项则返回零。 - 它的语法为regexp_instr(string, pattern - , start - , N - , endoption - , flags - , subexpr - ). - 在string中搜索pattern,通常从字符串的开头开始,但如果提供了start参数,则从该字符索引开始。 - 如果指定了N,则定位模式的第N个匹配项,否则定位第一个匹配项。 - 如果省略了endoption参数或将其指定为0,则函数返回匹配项的第一个字符的位置。否则,endoption - 必须为1,函数返回匹配项后面字符的位置。 - flags参数是一个可选的文本字符串,包含零个或多个单字母标志,可以改变函数的行为。支持的标志在中描述。 - 对于包含括号子表达式的模式,subexpr是一个整数,表示感兴趣的子表达式:结果标识与该子表达式匹配的子字符串的位置。 - 子表达式按其前导括号的顺序编号。 - 当省略或将subexpr指定为零时,结果标识整个匹配的位置,而不考虑括号子表达式。 - - - - 一些示例: - -regexp_instr('number of your street, town zip, FR', '[^,]+', 1, 2) - 23 -regexp_instr('ABCDEFGHI', '(c..)(...)', 1, 1, 0, 'i', 2) - 6 - - - - - regexp_like函数检查字符串中是否存在 POSIX 正则表达式模式的匹配, - 返回布尔值 true 或 false。它的语法为 - regexp_like(string, - pattern - , flags )。 - flags参数是一个可选的文本字符串,包含零个或多个单字母标志, - 可以改变函数的行为。支持的标志在中描述。 - 如果没有指定标志,此函数的结果与~操作符相同。 - 如果只指定了i标志,则结果与~*操作符相同。 - + regexp_replace函数用新文本替换匹配 POSIX 正则表达式模式的子字符串。它的语法为 regexp_replace(source, pattern, replacement , flags )。如果没有与 pattern 匹配的内容,则原样返回 source 字符串。如果存在匹配,则返回将匹配子字符串替换为 replacement 字符串后的 source 字符串。replacement 字符串可以包含 \n,其中 n 为 1 至 9,表示应插入与模式中第 n 个圆括号子表达式匹配的源子字符串;它也可以包含 \&,表示应插入与整个模式匹配的子字符串。如果需要在替换文本中放置字面的反斜杠,应写成 \\flags 参数是可选的文本字符串,其中包含零个或多个改变函数行为的单字母标志。标志 i 指定不区分大小写的匹配,而标志 g 指定替换每个匹配的子字符串,而不仅是第一个。支持的标志(不包括 g)在中描述。 - - 一些示例: - -regexp_like('Hello World', 'world') false -regexp_like('Hello World', 'world', 'i') true + 下面是一些示例: +regexp_replace('foobarbaz', 'b..', 'X') + fooXbaz +regexp_replace('foobarbaz', 'b..', 'X', 'g') + fooXX +regexp_replace('foobarbaz', 'b(..)', 'X\1Y', 'g') + fooXarYXazY - + - regexp_match函数返回一个文本数组,其中包含与POSIX正则表达式模式对字符串的第一个匹配的子字符串。它的语法为 + regexp_match函数返回一个文本数组,包含字符串首次匹配 POSIX 正则表达式模式时捕获的子字符串。它的语法为 regexp_match(string, pattern , flags )。 如果没有匹配,结果为NULL。 - 如果找到匹配,并且pattern不包含括号子表达式,则结果是包含与整个模式匹配的子字符串的单元素文本数组。 - 如果找到匹配,并且pattern包含括号子表达式,则结果是一个文本数组,其中n的元素是匹配 - pattern的第n个括号子表达式的子字符串(不包括非捕获括号;详情见下文)。 + 如果找到匹配,并且pattern不包含圆括号子表达式,则结果是包含与整个模式匹配的子字符串的单元素文本数组。 + 如果找到匹配,并且pattern包含圆括号子表达式,则结果是一个文本数组,其中第n个元素是匹配 + pattern的第n个圆括号子表达式的子字符串(不包括非捕获括号;详情见下文)。 flags参数是一个可选的文本字符串,其中包含零个或多个单个字母标志,用于更改函数的行为。支持的标志在中描述。 - - 一些示例: - + 下面是一些示例: SELECT regexp_match('foobarbequebaz', 'bar.*que'); regexp_match -------------- @@ -5297,26 +4976,14 @@ SELECT regexp_match('foobarbequebaz', '(bar)(beque)'); -------------- {bar,beque} (1 row) - - - - - - - 在通常情况下,当您只想要整个匹配的子字符串或NULL表示没有匹配时, - 最好的解决方案是使用regexp_substr()。 - 然而,在PostgreSQL版本15及以上版本中才存在 - regexp_substr()。在旧版本中工作时,您可以提取 - regexp_match()结果的第一个元素,例如: - +通常,如果只想得到整个匹配的子字符串,或在没有匹配时得到NULL,可以写成如下形式: SELECT (regexp_match('foobarbequebaz', 'bar.*que'))[1]; regexp_match -------------- barbeque (1 row) - - + regexp_matches函数返回一个文本数组的集合,其中包含与POSIX正则表达式模式匹配的子字符串。 @@ -5329,9 +4996,7 @@ SELECT (regexp_match('foobarbequebaz', 'bar.*que'))[1]; 还接受g标志,该标志命令它返回所有匹配项,而不仅仅是第一个匹配项。 - - 一些示例: - + 下面是一些示例: SELECT regexp_matches('foo', 'not there'); regexp_matches ---------------- @@ -5349,69 +5014,24 @@ SELECT regexp_matches('foobarbequebazilbarfbonk', '(b[^b]+)(b[^b]+)', 'g'); - 在大部分情况下,regexp_matches()应该与g标志一起使用,因为如果只是想要第一个匹配,使用regexp_match()会更加简单高效。不过,regexp_match()仅存在于PostgreSQL版本10以及更高的版本中。当在较老的版本中使用时,一种常用的技巧是把regexp_matches()调用放在子选择中,例如: + 在大部分情况下,regexp_matches()应该与g标志一起使用,因为如果只是想要第一个匹配,使用regexp_match()会更加简单高效。不过,regexp_match()仅存在于PostgreSQL版本10以及更高的版本中。当在较老的版本中使用时,一种常用的技巧是把regexp_matches()调用放在子查询中,例如: SELECT col1, (SELECT regexp_matches(col2, '(bar)(beque)')) FROM tab; - 如果有一个匹配,则这个语句会产生一个文本数组,否则返回NULL,这和regexp_match()的做法一样。如果没有子选择,这个查询对于没有匹配的表行根本不会产生输出,显然那不是想要的行为。 + 如果有一个匹配,则这个语句会产生一个文本数组,否则返回NULL,这和regexp_match()的做法一样。如果没有子查询,这个查询对于没有匹配的表行根本不会产生输出,这通常不是预期行为。 - regexp_replace函数提供了对匹配POSIX正则表达式模式的子字符串进行替换的功能。 - 它的语法为 - regexp_replace(source, - pattern, replacement - , start - , N - - , flags ). - (注意,除非指定了start,否则无法指定N, - 但flags可以在任何情况下给出。) - 如果pattern没有匹配到source字符串, - 则返回未更改的source字符串。如果有匹配,则返回带有 - replacement字符串替换匹配子字符串的source字符串。 - replacement字符串可以包含\n, - 其中n为1至9,表示应插入与模式的第n个括号子表达式匹配的源子字符串, - 也可以包含\&表示应插入与整个模式匹配的子字符串。 - 如果需要在替换文本中放置一个字面上的反斜杠,则写\\。 - 在string中搜索pattern, - 通常从字符串的开头开始,但如果提供了start参数,则从该字符索引开始。 - 默认情况下,只替换模式的第一个匹配项。 - 如果指定了N且大于零,则替换模式的第N个匹配项。 - 如果给出了g标志,或者指定了N且为零,则在或之后的所有匹配项 - 位置都将被替换。 (当指定了N时,g标志将被忽略。) - flags参数是一个可选的文本字符串,包含零个或多个单字母标志,用于更改函数的行为。 - 支持的标志(尽管不包括g)在中描述。 - - - - 一些示例: - -regexp_replace('foobarbaz', 'b..', 'X') - fooXbaz -regexp_replace('foobarbaz', 'b..', 'X', 'g') - fooXX -regexp_replace('foobarbaz', 'b(..)', 'X\1Y', 'g') - fooXarYXazY -regexp_replace('A PostgreSQL function', 'a|e|i|o|u', 'X', 1, 0, 'i') - X PXstgrXSQL fXnctXXn -regexp_replace('A PostgreSQL function', 'a|e|i|o|u', 'X', 1, 3, 'i') - A PostgrXSQL function - - - - - regexp_split_to_table把一个 POSIX 正则表达式模式当作一个定界符来分离一个串。它的语法形式是regexp_split_to_table(string, pattern , flags )。如果没有与pattern的匹配,该函数返回string。如果有至少有一个匹配,对每一个匹配它都返回从上一个匹配的末尾(或者串的开头)到这次匹配开头之间的文本。当没有更多匹配时,它返回从上一次匹配的末尾到串末尾之间的文本。flags参数是一个可选的文本串,它包含零个或更多单字母标志,这些标识可以改变该函数的行为。regexp_split_to_table能支持的标志在中描述。 + regexp_split_to_table把一个 POSIX 正则表达式模式当作一个定界符来分割字符串。它的语法形式是regexp_split_to_table(string, pattern , flags )。如果没有与pattern的匹配,该函数返回string。如果至少有一个匹配,对每一个匹配它都返回从上一个匹配的末尾(或者串的开头)到这次匹配开头之间的文本。当没有更多匹配时,它返回从上一次匹配的末尾到串末尾之间的文本。flags参数是一个可选的文本串,它包含零个或更多单字母标志,这些标志可以改变该函数的行为。regexp_split_to_table能支持的标志在中描述。 regexp_split_to_array函数的行为和regexp_split_to_table相同,不过regexp_split_to_array会把它的结果以一个text数组的形式返回。它的语法是regexp_split_to_array(string, pattern , flags )。这些参数和regexp_split_to_table的相同。 - - 一些示例: - + 下面是一些示例: + SELECT foo FROM regexp_split_to_table('the quick brown fox jumps over the lazy dog', '\s+') AS foo; foo ------- @@ -5456,43 +5076,12 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; - 正如最后一个示例所示,regexp分割函数会忽略出现在字符串开头或结尾 - 或紧跟在前一个匹配项之后的零长度匹配。这与其他regexp函数实现的 - 严格的regexp匹配定义相矛盾,但在实践中通常是最方便的行为。 + 正如最后一个示例所示,正则表达式分割函数会忽略出现在字符串开头或结尾 + 或紧跟在前一个匹配项之后的零长度匹配。这与regexp_matchregexp_matches实现的 + 严格的正则表达式匹配定义相矛盾,但在实践中通常是最方便的行为。 其他软件系统如Perl使用类似的定义。 - - regexp_substr函数返回与POSIX正则表达式模式匹配的子字符串, - 如果没有匹配,则返回NULL。它的语法为 - regexp_substr(string, - pattern - , start - , N - , flags - , subexpr - )。 - patternstring中进行搜索, - 通常从字符串的开头开始,但如果提供了start参数,则从该字符索引开始。 - 如果指定了N,则返回模式的第N次匹配, - 否则返回第一次匹配。参数flags是一个可选文本字符串, - 包含零个或多个单字母标志,可以改变函数的行为。支持的标志在中描述。 - 对于包含括号子表达式的模式,subexpr是一个整数, - 表示感兴趣的子表达式:结果是与该子表达式匹配的子字符串。 - 子表达式按其前导括号的顺序编号。 - 当省略或为零时,subexpr的结果是整个匹配,而不考虑括号子表达式。 - - - - 一些示例: - -regexp_substr('number of your street, town zip, FR', '[^,]+', 1, 2) - 城镇 邮编 -regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - FGH - - - @@ -5524,7 +5113,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 一个量化原子是一个原子, 后面可能跟着一个量词。没有量词的时候,它匹配一个原子, 有量词的时候,它可以匹配若干个原子。一个原子可以是在里面显示的任何可能。 可能的量词和它们的含义在里显示。 + 一个量化原子是一个原子,后面可以跟一个量词。没有量词时,匹配一次原子所匹配的内容;有量词时,按量词指定的次数匹配原子所匹配的内容。原子可以是列出的任何一种形式。可用量词及其含义见 @@ -5548,12 +5137,12 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) (re) - (其中re是任何正则表达式) 匹配一个对re的匹配,匹配将为可能的报告被记下 + (其中re是任意正则表达式)匹配re所匹配的内容,并记录该匹配,以备输出结果 (?:re) - 同上,但是匹配不会为了报告而被记下 (一个非捕获圆括号集) (只对 ARE) + 同上,但不记录匹配结果(非捕获圆括号;仅适用于 ARE) @@ -5568,17 +5157,17 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) \k - (其中k是一个非字母数字字符) 匹配一个被当作普通字符看待的特定字符, 例如,\\匹配一个反斜线字符 + (其中k既不是字母也不是数字)把该字符视为普通字符并匹配它,例如,\\匹配反斜线字符 \c - 其中c是一个字母数字 (可能跟着其它字符),它是一个转义, 参阅(仅对 ARE; 在 ERE 和 BRE 中,它匹配c + 其中c是字母或数字(后面可能还有其他字符),这是一个转义,参见(仅适用于 ARE;在 ERE 和 BRE 中,它匹配c { - 如果后面跟着一个字符,而不是数字, 那么就匹配左花括弧{;如果跟着一个数字, 那么它是range的开始(见下文) + 如果后面跟着非数字字符,则匹配左花括号{;如果后面跟着数字,则是bound的开头(见下文) @@ -5596,7 +5185,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 如果你关掉了,你在文串常量中写的任何反斜线都需要被双写。详见。 + 如果你关掉了,你在字符串常量中写的任何反斜线都需要被双写。详见 @@ -5685,7 +5274,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 非贪婪的量词(只在 ARE 中可用)匹配对应的正常 (贪婪)模式,区别是它寻找最少的匹配,而不是最多的匹配。详见。 + 非贪婪量词(仅适用于 ARE)与对应的普通(贪婪)量词匹配相同的可能内容,但优先选择最少的匹配次数,而不是最多的匹配次数。详见 @@ -5712,39 +5301,39 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) ^ - 串开头的匹配 + 在字符串开头匹配 $ - 串末尾的匹配 + 在字符串末尾匹配 (?=re) - 在某个位置上,如果从该位置开始的子串能够匹配re,则匹配正向先行断言(仅对 ARE) + 正向先行断言在这样的位置匹配:存在从该位置开始且匹配re的子字符串(仅适用于 ARE) (?!re) - 在某个位置上,如果从该位置开始的子串不能匹配re,则匹配负向先行断言(仅对 ARE) + 负向先行断言在这样的位置匹配:不存在任何从该位置开始且匹配re的子字符串(仅适用于 ARE) (?<=re) - 在某个位置上,如果以该位置结束的某个子串能够匹配re,则匹配正向后行断言(仅对 ARE) + 正向后行断言在这样的位置匹配:存在以该位置结束且匹配re的子字符串(仅适用于 ARE) (?<!re) - 在某个位置上,如果以该位置结束的任何子串都不能匹配re,则匹配负向后行断言(仅对 ARE) + 负向后行断言在这样的位置匹配:不存在任何以该位置结束且匹配re的子字符串(仅适用于 ARE)
- Lookahead 和 lookbehind 约束不能包含反向引用 (参阅),并且其中的所有圆括号 都被认为是非捕获的。 + 先行和后行约束不能包含反向引用(参见),其中的所有圆括号都视为非捕获圆括号。 @@ -5753,11 +5342,11 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) 方括号表达式 - 方括号表达式是一个包围在[]中的字符列表。它通常匹配列表中的任意单个字符(但见下文)。 如果列表以^开头,它匹配任意单个在该列表参与部分中的字符。如果该列表中两个字符用-隔开, 那它就是那两个字符(包括在内)之间的所有字符范围的缩写,例如,在ASCII[0-9]匹配任何十进制数字。两个范围共享一个端点是非法的,例如,a-c-e。范围与字符集关系密切, 可移植的程序应该避免依靠它们。 + 方括号表达式是用[]括起来的字符列表。通常,它匹配列表中的任意单个字符(但请参见下文)。如果列表以^开头,则匹配任意在列表剩余部分中的单个字符。如果列表中的两个字符用-分隔,则表示排序序列中这两个字符之间的完整字符范围(包含两个端点);例如,ASCII中的[0-9]匹配任意十进制数字。两个范围共享一个端点是不合法的,例如a-c-e。范围高度依赖排序序列,因此可移植程序应避免依赖它们。 - 想在列表中包含文本],可以让它做列表的首字符(如果使用了^,需要放在其后)。 想在列表中包含文本-,可以让它做列表的首字符或者尾字符,或者一个范围的第二个端点。 想在列表中把文本-当做范围的起点, 把它用[..]包围起来,这样它就成为一个排序元素(见下文)。 除了这些字符本身、一些用[的组合(见下段)以及转义(只在 ARE 中有效)以外,所有其它特殊字符 在方括号表达式里都失去它们的特殊含义。特别是,在 ERE 和 BRE 规则下\不是特殊的, 但在 ARE 里,它是特殊的(引入一个转义)。 + 想在列表中包含字面字符],可以让它做列表的首字符(如果使用了^,需要放在其后)。 想在列表中包含字面字符-,可以让它做列表的首字符或者尾字符,或者一个范围的第二个端点。 想在列表中把字面字符-当做范围的起点, 把它用[..]包围起来,这样它就成为一个排序元素(见下文)。 除了这些字符本身、一些用[的组合(见下段)以及转义(只在 ARE 中有效)以外,所有其它特殊字符 在方括号表达式里都失去它们的特殊含义。特别是,在 ERE 和 BRE 规则下\不是特殊的, 但在 ARE 里,它是特殊的(引入一个转义)。 @@ -5772,30 +5361,11 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 在方括号表达式里,包围在[==]里的排序元素是一个等价类, 代表等效于那一个的所有排序元素的字符序列,包括它本身(如果没有其它等效排序元素,那么就好象封装定界符是[..])。例如,如果o^是一个等价类的成员,那么[[=o=]][[=^=]][o^]都是同义的。一个等价类不能是一个范围的端点。 + 在方括号表达式里,包围在[==]里的排序元素是一个等价类, 代表等效于那一个的所有排序元素的字符序列,包括它本身(如果没有其它等效排序元素,那么就好像封装定界符是[..])。例如,如果o^是一个等价类的成员,那么[[=o=]][[=^=]][o^]都是同义的。一个等价类不能是一个范围的端点。 - 在方括号表达式里,在[::]里面封装的字符类的名字代表属于该类的所有字符的列表。 - 字符类不能作为范围的端点使用。 - POSIX标准定义了这些字符类的名称: - alnum (字符和数字), - alpha (字符), - blank (空格和制表符tab), - cntrl (控制符), - digit (数位数), - graph (空格除外可打印字符), - lower (小写字母), - print (包含空格可打印字符), - punct (标点符号), - space (空白), - upper (大写字母), - 和 xdigit (十六进制数). - 对于7位ASCII字符集中的字符来说,这些标准字符类的行为在不同平台上一般是一致的。 - 一个给定的非 ASCII 字符是否被认为属于这些类别中的一个,取决于正则表达式函数或操作符所使用的排序规则(见),或者在默认情况下取决于数据库的LC_CTYPE locale 设置(见)。 - 非ASCII字符的分类在不同的平台上会有不同的分类,即使是在类似命名的locale中也是如此。 - (但C locale从不认为任何非ASCII字符属于上述任何一类)。 - 除了这些标准字符类之外,PostgreSQL定义了word字符类,等同于alnum加上下划线(_), 以及ascii字符类,它完全包含7位ASCII字符集。 + 在方括号表达式中,用[::]括起来的字符类名称表示属于该类的所有字符。字符类不能作为范围的端点。POSIX标准定义了以下字符类名称:alnum(字母和数字)、alpha(字母)、blank(空格和制表符)、cntrl(控制字符)、digit(数字)、graph(空格以外的可打印字符)、lower(小写字母)、print(包括空格的可打印字符)、punct(标点符号)、space(任意空白字符)、upper(大写字母)和xdigit(十六进制数字)。对于 7 位 ASCII 字符集中的字符,这些标准字符类在各平台上的行为通常一致。给定的非 ASCII 字符是否属于其中某个类,取决于正则表达式函数或操作符使用的排序规则(参见),默认则取决于数据库的LC_CTYPE区域设置(参见)。即使区域设置名称相似,非 ASCII 字符的分类也可能因平台而异。(但C区域设置不会将任何非 ASCII 字符归入这些类。)除了这些标准字符类,PostgreSQL还定义了word字符类,即alnum加上下划线(_),以及恰好包含 7 位 ASCII 字符集的ascii字符类。 @@ -5812,11 +5382,11 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) 正则表达式转义 - 转义是以\开头,后面跟着一个字母数字字符的特殊序列。 转义有好几种变体:字符输入转义、字符类简写转义、约束转义以及反向引用。在 ARE 里, 如果一个\后面跟着一个字母数字,但是并未组成一个合法的转义, 那么它是非法的。在 ERE 中没有转义:在方括号表达式之外,一个后面跟着字母数字字符的\只是表示该字符是一个普通的字符,而且在一个方括号表达式里,\是一个普通的字符(后者实际上在 ERE 和 ARE 不兼容)。 + 转义是以\开头,后面跟着一个字母或数字字符的特殊序列。 转义有好几种变体:字符输入转义、字符类简写转义、约束转义以及反向引用。在 ARE 里, 如果一个\后面跟着一个字母或数字,但是并未组成一个合法的转义, 那么它是非法的。在 ERE 中没有转义:在方括号表达式之外,一个后面跟着字母或数字字符的\只是表示该字符是一个普通的字符,而且在一个方括号表达式里,\是一个普通的字符(后者是 ERE 与 ARE 之间唯一的实际不兼容之处)。 - 字符输入转义用于便于我们在 RE 中声明那些不可打印的或其他习惯的字符。它们显示在中。 + 字符输入转义便于在 RE 中指定不可打印或其他不便输入的字符,见 @@ -5824,13 +5394,13 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 约束转义是一个约束,如果满足特定的条件,它匹配该空串。它们显示在中。 + 约束转义是以转义形式书写的约束,在满足特定条件时匹配空字符串,见 - 反向引用\n)匹配数字\n指定的被前面的圆括号子表达式匹配的同一个串 (参阅)。 + 反向引用\n)匹配前面编号为n的圆括号子表达式所匹配的同一字符串 (参阅)。 例如, ([bc])\1匹配bb或者cc, 但是不匹配bc或者cb。 - RE 中子表达式必须完全在反向引用前面。子表达式以它们的先导圆括号的顺序编号。 + RE 中子表达式必须完全在反向引用前面。子表达式以它们的左圆括号的顺序编号。 非捕获圆括号并不定义子表达式。 反向引用仅考虑被引用的子表达式匹配的字符串字符,而不考虑其中包含的任何约束。 例如,(^\d)\1 将匹配 22。 @@ -5873,7 +5443,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) \e - 排序序列名为ESC的字符,如果无法做到该字符为八进制值 033 + 排序序列名称为ESC的字符;若不存在这样的字符,则使用八进制值为033的字符 @@ -5883,7 +5453,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) \n - 新行,和 C 中一样 + 换行符,与 C 中相同 @@ -6007,7 +5577,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 类-缩写转义也适用于括号表达式,尽管上面显示的定义在该上下文中在语法上并不完全有效。 + 字符类简写转义也适用于括号表达式,尽管上面显示的定义在该上下文中在语法上并不完全有效。 例如,[a-c\d] 等同于 [a-c[:digit:]] @@ -6048,7 +5618,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) \Y - 只在一个词的不是开头或末尾的点上匹配 + 只在不属于单词开头或末尾的位置匹配 @@ -6060,7 +5630,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 一个词被定义成在上面[[:<:]][[:>:]]中的声明。在方括号表达式里,约束转义是非法的。 + 单词的定义与上文[[:<:]][[:>:]]的说明相同。方括号表达式中不允许使用约束转义。 @@ -6080,12 +5650,12 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) \m - (其中m是一个非零位)一个到第m个子表达式的反向引用 + (其中m是一个非零数字)一个到第m个子表达式的反向引用 \mnn - (其中m是一个非零位,并且nn是一些更多的位,并且十六进制值mnn不超过目前能看到的封闭捕获圆括号的数目)一个到第mnn个子表达式的反向引用 + (其中m是一个非零数字,并且nn是后续的若干数字,并且十进制值mnn不大于此前已出现的捕获右圆括号数)一个到第mnn个子表达式的反向引用 @@ -6094,7 +5664,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 在八进制字符输入转义和反向引用之间有一个历史继承的歧义存在,这个歧义是 通过下面的启发式规则解决的,像上面描述地那样。前导零总是表示这是一个八进制转义。 而单个非零数字,如果没有跟着任何其它位,那么总是被认为反向引用。 一个多位的非零开头的序列也被认为是反向引用,只要它出现在合适的子表达式后面 (也就是说,在反向引用的合法范围中的数),否则就被认为是一个八进制。 + 八进制字符输入转义与反向引用之间存在固有歧义,按上文提到的启发式规则解决:前导零始终表示八进制转义。单个非零数字,如果后面没有其他数字,始终视为反向引用。不以零开头的多位数字序列,如果前面已有相应的子表达式(即该数字在反向引用的合法范围内),则视为反向引用,否则视为八进制转义。 @@ -6108,11 +5678,11 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 如果一个 RE 以***:开头,那么剩下的 RE 都被当作 ARE(这在PostgreSQL中通常是无效的,因为 RE 被假定为 ARE,但是如果 ERE 或 BRE 模式通过flags参数被指定为一个正则表达式函数时,它确实能产生效果)。如果一个 RE 以***=开头, 那么剩下的 RE 被当作一个文本串,所有的字符都被认为是一个普通字符。 + RE 可以以两种特殊的引导前缀之一开头。如果 RE 以***:开头,余下部分就被视为 ARE。(这在PostgreSQL中通常没有影响,因为 RE 默认被视为 ARE;但如果通过正则表达式函数的flags参数指定了 ERE 或 BRE 模式,它就会产生影响。)如果 RE 以***=开头,余下部分就作为按字面解释的字符串处理,所有字符都视为普通字符。 - 一个 ARE 可以以嵌入选项开头:一个序列(?xyz)(这里的xyz是一个或多个字母字符)声明影响剩余 RE 的选项。 这些选项覆盖任何前面判断的选项 — 特别地,它们可以覆盖一个正则表达式操作符隐含的大小写敏感的行为,或者覆盖flags参数中的正则表达式函数。可用的选项字母在中显示。注意这些同样的选项字母也被用在正则表达式函数的flags参数中。 + 一个 ARE 可以以嵌入选项开头:一个序列(?xyz)(这里的xyz是一个或多个字母字符)声明影响剩余 RE 的选项。 这些选项覆盖任何先前确定的选项 — 特别地,它们可以覆盖一个正则表达式操作符隐含的大小写敏感的行为,或者覆盖正则表达式函数的flags参数所指定的选项。可用的选项字母在中显示。注意这些同样的选项字母也被用在正则表达式函数的flags参数中。
@@ -6157,32 +5727,32 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) n - 新行敏感的匹配(见 + 换行敏感的匹配(见 p - 部分新行敏感的匹配(见 + 部分换行敏感的匹配(见 q - RE的剩余部分是一个文字(quoted)串,全部是普通字符 + RE 的剩余部分按字面(加引号)解释,所有字符都视为普通字符 s - 非新行敏感的匹配(默认) + 非换行敏感的匹配(默认) t - 紧语法(默认,见下文) + 紧凑语法(默认;见下文) w - 逆部分新行敏感(怪异)的匹配(见 + 逆部分换行敏感(怪异)的匹配(见 @@ -6194,16 +5764,16 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2)
- 嵌入选项在)终止序列时发生作用。它们只在 ARE 的开始处起作用 (在任何可能存在的***:控制器后面)。 + 嵌入选项从结束该序列的)处开始生效。它们只能出现在 ARE 的开头(如果存在***:引导前缀,则位于该前缀之后)。 - 除了通常的()RE 语法(这种情况下所有字符都有效), 还有一种扩展语法,可以通过声明嵌入的x选项获得。在扩展语法里,RE 中的空白字符被忽略,就像那些在#和其后的新行(或 RE 的末尾)之间的字符一样。这样就允许我们给一个复杂的 RE 分段和注释。不过这个基本规则有三种例外: + 除了通常的紧凑 RE 语法(其中所有字符都有意义)之外,还有一种扩展语法,可以通过指定嵌入的x选项来使用。在扩展语法中,RE 中的空白字符会被忽略,同样被忽略的还有#与其后的换行符(或 RE 末尾)之间的所有字符。这使得复杂的 RE 可以分段并添加注释。此基本规则有三个例外: - 空白字符或前置了\#将被保留 + 空白字符或 # 的前面若有 \,该字符就会被保留。 @@ -6218,14 +5788,14 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 为了这个目的,空白是空格、制表符、新行以及任何属于 whitespace 字符类的字符。 + 在这里,空白字符包括空格、制表符、换行符,以及属于space字符类的任何字符。 - 最后,在 ARE 里,方括号表达式外面,序列(?#ttt)(其中ttt是任意不包含一个))的文本)是一个注释, 它被完全忽略。同样,这样的东西是不允许出现在多字符符号的字符中间的,例如 (?:。这种注释更像是一种历史产物而不是一种有用的设施,并且它们的使用已经被废弃;请使用扩展语法来替代。 + 最后,在 ARE 里,方括号表达式外面,序列(?#ttt)(其中ttt是任意不包含一个)的文本)是一个注释, 它被完全忽略。同样,这样的东西是不允许出现在多字符符号的字符中间的,例如 (?:。这种注释更像是一种历史产物而不是一种有用的设施,并且它们的使用已经被废弃;请使用扩展语法来替代。
- 如果声明了一个初始的***=控制器,那么所有这些元语法扩展都不能使用,因为这样表示把用户输入当作一个文字串而不是 RE 对待。 + 如果指定了开头的***=引导前缀,那么这些元语法扩展都不能使用,因为这表示把用户输入作为按字面解释的字符串,而非 RE 处理。 @@ -6242,7 +5812,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 大多数原子以及所有约束,都没有贪婪属性(因为它们毕竟无法匹配个数变化的文本)。 + 大多数原子以及所有约束,都没有贪婪属性(因为它们毕竟无法匹配长度不定的文本)。 @@ -6294,7 +5864,7 @@ SELECT SUBSTRING('XY1234Z', 'Y*?([0-9]{1,3})');
- 简而言之,如果一个 RE 同时包含贪婪和非贪婪的子表达式,那么总的匹配长度要么是尽可能长,要么是尽可能短,这取决于给整个 RE 赋予的属性。给子表达式赋予的属性只影响在这个匹配里,各个子表达式之间相互允许吃掉的多少。 + 简而言之,如果一个 RE 同时包含贪婪和非贪婪的子表达式,那么总的匹配长度要么是尽可能长,要么是尽可能短,这取决于给整个 RE 赋予的属性。给子表达式赋予的属性只影响在这个匹配里,各个子表达式相对于其他子表达式能吃掉多少内容。 @@ -6328,23 +5898,23 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 如果声明了大小写无关的匹配,那么效果就好像所有大小写区别在字母表中消失了。如果在多个情况中一个字母以一个普通字符的形式出现在方括号表达式外面,那么它实际上被转换成 一个包含大小写的方括号表达式,也就是说,x 变成 [xX]。 如果它出现在一个方括号表达式里面,那么它的所有大小写的同族都被加入 方括号表达式中,也就是说,x变成[xX]。当它出现在一个方括号表达式内时,它的所有大小写副本都被加入到方括号表达式中,例如, [x]会变成[xX],而[^x]会变成[^xX]。 + 如果指定不区分大小写的匹配,其效果近似于字母表中的所有大小写差别都消失了。当存在大小写形式的字母作为普通字符出现在方括号表达式之外时,实际上会转换为包含其大小写形式的方括号表达式,例如x变成[xX]。当它出现在方括号表达式内部时,其所有大小写形式都会加入该表达式,例如[x]变成[xX][^x]变成[^xX] 如果指定了换行敏感的匹配,.和使用^的方括号表达式 将永远不会匹配换行字符(这样,匹配就不会跨越行,除非 RE 显式地包含了换行)并且^$除了分别匹配串开头和结尾之外,还将分别匹配换行后面和前面的空串。 但是 ARE 转义\A\Z仍然匹配串的开头和结尾。 - 此外,字符类缩写符\D\W将匹配换行,而无论这种模式如何。 + 此外,字符类简写\D\W将匹配换行,而无论这种模式如何。 (在PostgreSQL 14之前,它们在换行敏感模式下不匹配换行。 写入[^[:digit:]][^[:word:]]以获取旧的行为。) - 如果指定了部分新行敏感的匹配,那么它影响.和方括号表达式, 这个时候和新行敏感的匹配一样,但是不影响^$。 + 如果指定了部分换行敏感的匹配,那么它影响.和方括号表达式, 这个时候和换行敏感的匹配一样,但是不影响^$ - 如果指定了逆新行敏感匹配,那么它影响^$,其作用和在新行敏感的匹配里一样,但是不影响.和方括号表达式。这个并不是很有用,只是为了满足对称性而提供的。 + 如果指定了逆部分换行敏感匹配,那么它影响^$,其作用和在换行敏感的匹配里一样,但是不影响.和方括号表达式。这个并不是很有用,只是为了满足对称性而提供的。 @@ -6357,11 +5927,11 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}');
- ARE 实际上和 POSIX ERE 不兼容的唯一的特性是在方括号表达式里\并不失去它特殊的含义。所有其它 ARE 特性都使用在 POSIX ERE 里面是非法或者是未定义、未声明效果的语法;指示器的***就是在 POSIX 的 BRE 和 ERE 之外的语法。 + ARE 与 POSIX ERE 实际不兼容的唯一特性是:\在方括号表达式中不会失去特殊含义。其他所有 ARE 特性所使用的语法,在 POSIX ERE 中都是非法的,或其效果未定义或未指定;引导前缀的***语法同样不属于 POSIX 的 BRE 或 ERE 语法。 - 许多 ARE 扩展都是从 Perl 那里借来的(但是有些被做了修改来清理它们),以及一些 Perl 里没有出现的扩展。要注意的不兼容性包括\b\B、对结尾的新行缺乏特别的处理、对那些被新行敏感匹配的东西附加的补齐方括号表达式、在 lookahead/lookbehind 约束里对圆括号和反向引用的限制以及最长/最短 匹配(而不是第一匹配)的语义。 + 许多 ARE 扩展借鉴自 Perl,但其中一些经过了整理和修改,也未实现少数 Perl 扩展。需要注意的不兼容之处包括\b\B、不对末尾换行符作特殊处理、取反的方括号表达式也受换行敏感匹配影响、先行和后行约束中对圆括号及反向引用的限制,以及采用最长或最短匹配而非首次匹配的语义。 @@ -6370,177 +5940,75 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 基本正则表达式 - BREs 在几个方面和 ERE 不太一样。在 BRE 中,|+?都是普通字符并且没有与它们功能等价的东西。范围的定界符是\{\}, 因为 {}本身是普通字符。嵌套的子表达式的圆括号是\(\),因为()自身是普通字符。除非在 RE 开头或者是圆括号子表达式开头,^都是一个普通字符。 除非在 RE 结尾或者是圆括号子表达式的结尾,$是一个普通字符。如果*出现在 RE 开头或者是圆括号封装的子表达式开头 (前面可能有^),那么它是个普通字符。最后,可以用单数字的反向引用,\<\>分别是[[:<:]][[:>:]]的同义词;在 BRE 中没有其它可用的转义。 + BRE 在几个方面和 ERE 不太一样。在 BRE 中,|+?都是普通字符并且没有与它们功能等价的东西。范围的定界符是\{\},而{}本身是普通字符。嵌套的子表达式的圆括号是\(\),而()自身是普通字符。除非在 RE 开头或者是圆括号子表达式开头,^都是一个普通字符。 除非在 RE 结尾或者是圆括号子表达式的结尾,$是一个普通字符。如果*出现在 RE 开头或者是圆括号封装的子表达式开头 (前面可能有^),那么它是个普通字符。最后,可以用单数字的反向引用,\<\>分别是[[:<:]][[:>:]]的同义词;在 BRE 中没有其它可用的转义。 - - 与 SQL 标准和 XQuery 的区别 - - - LIKE_REGEX - - - - OCCURRENCES_REGEX - + 与 XQuery(<literal>LIKE_REGEX</literal>)的区别 - POSITION_REGEX - - - - SUBSTRING_REGEX - - - - TRANSLATE_REGEX - - - - XQuery正则表达式 + LIKE_REGEX - - 自 SQL:2008 起,SQL 标准包含了正则表达式操作符和函数,它们依据 XQuery 正则表达式标准进行模式匹配: - - LIKE_REGEX - OCCURRENCES_REGEX - POSITION_REGEX - SUBSTRING_REGEX - TRANSLATE_REGEX - - PostgreSQL目前尚未实现这些操作符和函数。你可以在每种情况下获得近似等效的功能,如中所示。(此表中已省略了双方的各种可选子句。) - - - - - 正则表达式函数等效性 - - - - - - SQL标准 - PostgreSQL - - - - - - - string LIKE_REGEX pattern - regexp_like(string, pattern)string ~ pattern - - - - OCCURRENCES_REGEX(pattern IN string) - regexp_count(string, pattern) - - - - POSITION_REGEX(pattern IN string) - regexp_instr(string, pattern) - - - - SUBSTRING_REGEX(pattern IN string) - regexp_substr(string, pattern) - + XQuery 正则表达式 - - TRANSLATE_REGEX(pattern IN string WITH replacement) - regexp_replace(string, pattern, replacement) - - - -
- - - 与PostgreSQL提供的类似的正则表达式函数在许多其他SQL实现中也可用,而SQL标准函数并不如此广泛实现。 - 每个实现中正则表达式语法的一些细节可能会有所不同。 - + 自 SQL:2008 起,SQL 标准包含一个按 XQuery 正则表达式标准执行模式匹配的 LIKE_REGEX 操作符。PostgreSQL 尚未实现此操作符,但使用 regexp_match() 函数可以得到非常相似的行为,因为 XQuery 正则表达式与前述 ARE 语法十分接近。 - - SQL 标准操作符和函数使用 XQuery 正则表达式,这些正则表达式与上述 ARE 语法非常接近。现有基于 POSIX 的正则表达式功能与 XQuery 正则表达式之间的显著差异包括: - + 现有基于 POSIX 的正则表达式功能与 XQuery 正则表达式之间的显著区别包括: - XQuery字符类减法不受支持。一个示例是使用以下内容仅匹配英语辅音:[a-z-[aeiou]] - XQuery字符类简写\c\C\i\I不受支持。 - - 使用\p{UnicodeProperty}或其反义\P{UnicodeProperty}来定义XQuery字符类元素是不被支持的。 + 使用\p{UnicodeProperty}或其取反形式\P{UnicodeProperty}来定义XQuery字符类元素是不被支持的。 - - POSIX解释字符类,如\w - (参见) - 根据当前区域设置(你可以通过将COLLATE子句附加到操作符或函数上来控制)。 - XQuery通过参考Unicode字符属性来指定这些类别,因此只有遵循Unicode规则的区域设置才能获得等效行为。 + POSIX 根据当前区域设置解释\w等字符类(参见);你可以通过为操作符或函数附加COLLATE子句来控制该区域设置。XQuery 根据 Unicode 字符属性定义这些类,因此只有使用遵循 Unicode 规则的区域设置时,才能得到等效行为。 - SQL标准(而不是XQuery本身)试图适应比POSIX更多的换行符变体。上面描述的换行符敏感匹配选项只考虑ASCII NL(\n)为换行符,但SQL要求我们将CR(\r)、CRLF(\r\n)(Windows风格的换行符)以及一些仅限于Unicode的字符,如LINE SEPARATOR(U+2028),也视为换行符。 值得注意的是,.\s应该根据SQL的规定将\r\n视为一个字符而不是两个字符。 - - - 在描述的字符输入转义中 - 中, - XQuery仅支持\n\r, - 和\t。 - + 描述的字符输入转义中,XQuery 仅支持 \n\r\t - XQuery不支持方括号表达式中的字符类[:name:]语法。 - - XQuery没有前瞻或后顾约束,也没有在中描述的任何约束转义。 + XQuery没有先行或后行约束,也没有在中描述的任何约束转义。 - 在XQuery中不存在中描述的元语法形式。 - - - XQuery定义的正则表达式标志字母与POSIX的选项字母相关,但并不相同 - ()。虽然 - iq选项的行为相同,其他选项则不同: - + XQuery 定义的正则表达式标志字母与 POSIX 的选项字母相关,但并不相同()。虽然iq选项的行为相同,但其他选项并非如此: XQuery的s(允许点匹配换行符) 和m(允许^ - 和$匹配换行符)标志提供 + 和$在换行处匹配)标志提供 与POSIX的npw标志相同的行为,但它们 匹配POSIX的sm标志的行为。 @@ -6571,11 +6039,11 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 数据类型格式化函数 - formatting + 格式化 - PostgreSQL格式化函数提供一套强大的工具用于把各种数据类型 (日期/时间、整数、浮点、数字) 转换成格式化的字符串以及反过来从格式化的字符串转换成 指定的数据类型。列出了这些函数。这些函数都遵循一个公共的调用规范: 第一个参数是待格式化的值,而第二个是一个定义输出或输入格式的模板。 + PostgreSQL格式化函数提供一套强大的工具用于把各种数据类型 (日期/时间、整数、浮点数、数值) 转换成格式化的字符串以及反过来从格式化的字符串转换成 指定的数据类型。列出了这些函数。这些函数都遵循一个公共的调用规范: 第一个参数是待格式化的值,而第二个是一个定义输出或输入格式的模板。 @@ -6626,7 +6094,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); text - 根据给定的格式将间隔转换为字符串。 + 根据给定的格式将时间间隔转换为字符串。 to_char(interval '15h 2m 12s', 'HH24:MI:SS') @@ -6682,7 +6150,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); numeric - 根据给定的格式将字符串转换为数字。 + 根据给定的格式将字符串转换为数值。 to_number('12,454.8-', '99G999D9S') @@ -6723,7 +6191,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 展示了可以用于格式化日期和时间值的模版。 + 展示了可以用于格式化日期和时间值的模板模式。
@@ -6806,24 +6274,24 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); SSSS, SSSSS - 午夜后的秒 (0–86399) + 自午夜起的秒数 (0–86399) AM, am, - PM or pm - 正午指示器(不带句号) + PMpm + 上午/下午标记(不带句点) A.M., a.m., - P.M. or p.m. - 正午指示器(带句号) + P.M.p.m. + 上午/下午标记(带句点) Y,YYY - 带逗号的年(4 位或者更多位) with comma + 带逗号的年(4 位或者更多位) @@ -6880,17 +6348,17 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); MONTH - 全大写形式的月名(空格补齐到 9 字符) + 大写的月份全称(空格补齐到 9 字符) Month - 全首字母大写形式的月名(空格补齐到 9 字符) + 首字母大写的月份全称(空格补齐到 9 字符) month - 全小写形式的月名(空格补齐到 9 字符) + 小写的月份全称(空格补齐到 9 字符) @@ -6915,72 +6383,72 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); DAY - 全大写形式的日名(空格补齐到 9 字符) + 大写的星期全称(空格补齐到 9 字符) Day - 全首字母大写形式的日名(空格补齐到 9 字符) + 首字母大写的星期全称(空格补齐到 9 字符) day - 全小写形式的日名(空格补齐到 9 字符) + 小写的星期全称(空格补齐到 9 字符) DY - 简写的大写形式的日名(英语 3 字符,本地化长度可变) + 大写的星期简称(英语 3 字符,本地化长度可变) Dy - 简写的首字母大写形式的日名(英语 3 字符,本地化长度可变) + 首字母大写的星期简称(英语 3 字符,本地化长度可变) dy - 简写的小写形式的日名(英语 3 字符,本地化长度可变) + 小写的星期简称(英语 3 字符,本地化长度可变) DDD - 一年中的日(001–366) + 年内日序数(001–366) IDDD - ISO 8601 周编号方式的年中的日 (001–371; 年的第 1 日时第一个 ISO 周的周一) + ISO 8601 周编号方式的年中的日 (001–371; 年的第 1 日是第一个 ISO 周的周一) DD - 月中的日 (01–31) + 月内日序数 (01–31) D - 周中的日,周日 (1) 到周六 (7) + 星期几,周日 (1) 到周六 (7) ID - 周中的 ISO 8601 日,周一 (1) 到周日 (7) + ISO 8601 星期几,周一 (1) 到周日 (7) W - 月中的周 (1–5) (第一周从该月的第一天开始) + 月内周序数 (1–5) (第一周从该月的第一天开始) WW - 年中的周数 (1–53) (第一周从该年的第一天开始) + 年中的周编号 (1–53) (第一周从该年的第一天开始) IW - ISO 8601 周编号方式的年中的周数 (01–53; 新的一年的第一个周四在第一周) + ISO 8601 周编号方式的年中的周编号 (01–53; 新的一年的第一个周四在第一周) @@ -7030,24 +6498,24 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); OF - 从UTC开始的时区偏移(仅在to_char中支持) + 相对于 UTC 的时区偏移(仅在to_char中支持)
- 修饰语可以被应用于模板模式来修改它们的行为。例如,FMMonth就是带着FM修饰语的Month模式。展示了可用于日期/时间格式化的修饰语模式。 + 修饰符可以被应用于模板模式来修改它们的行为。例如,FMMonth就是带着FM修饰符的Month模式。展示了可用于日期/时间格式化的修饰符模式。 - 用于日期/时间格式化的模板模式修饰语 + 用于日期/时间格式化的模板模式修饰符 - 修饰语 + 修饰符 描述 示例 @@ -7055,37 +6523,37 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - FM prefix + FM 前缀 填充模式(抑制前导零和填充的空格) FMMonth - TH suffix + TH 后缀 大写形式的序数后缀 - DDTH, e.g., 12TH + DDTH,例如, 12TH - th suffix + th 后缀 小写形式的序数后缀 - DDth, e.g., 12th + DDth,例如, 12th - FX prefix - 固定的格式化全局选项(见使用须知) + FX 前缀 + 固定格式全局选项(见使用须知) FX Month DD Day - TM prefix - 翻译模式(基于使用本地化的日和月名) + TM 前缀 + 翻译模式(基于使用本地化的星期名和月份名) TMMonth - SP suffix + SP 后缀 拼写模式(未实现) DDSP @@ -7102,8 +6570,8 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); FM抑制了在模式输出中添加前导零和尾随空格的行为,这些前导零和尾随空格 本来会被添加以使输出成为固定宽度。在PostgreSQL中, - FM仅修改下一个规范,而在Oracle中FM影响所有后续 - 规范,并且重复的FM修饰符切换填充模式的开启和关闭。 + FM仅修改下一个格式说明,而在Oracle中FM影响所有后续 + 格式说明,并且重复的FM修饰符切换填充模式的开启和关闭。 @@ -7161,10 +6629,10 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 一个TZH模板模式可以匹配有符号数。 - 没有FX选项,减号可能会有歧义,并且可能被解释为分隔符。 - 此歧义解决如下:如果模板字符串中TZH之前的分隔符数量少于输入字符串中减号之前的分隔符数量, - 则减号被解释为TZH的一部分。 - 否则,减号被视为值之间的分隔符。 + 没有FX选项,负号可能会有歧义,并且可能被解释为分隔符。 + 此歧义解决如下:如果模板字符串中TZH之前的分隔符数量少于输入字符串中负号之前的分隔符数量, + 则负号被解释为TZH的一部分。 + 否则,负号被视为值之间的分隔符。 例如,to_timestamp('2000 -10', 'YYYY TZH')匹配 -10TZH,但 to_timestamp('2000 -10', 'YYYY  TZH') @@ -7175,12 +6643,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 普通文本允许在to_char模板中,并且将被直接输出。您可以将子字符串放在双引号中, - 以强制将其解释为文字文本,即使它包含模板模式。例如,在'"Hello Year "YYYY'中, - YYYY将被年份数据替换,但Year中的单个Y不会被替换。 - 在to_dateto_numberto_timestamp中, - 文本和双引号字符串会导致跳过字符串中包含的字符数;例如"XX"跳过两个输入字符 - (无论它们是否为XX)。 + 普通文本可以出现在to_char模板中,并会按字面输出。可以用双引号括起子串,使其即使包含模式关键字也强制按字面文本解释。例如,在'"Hello Year "YYYY'中,YYYY会被年份数据替换,但Year中单独的Y不会被替换。在to_dateto_numberto_timestamp中,字面文本和双引号字符串会跳过与该字符串所含字符数相同数量的输入字符;例如,"XX"跳过两个输入字符(无论它们是否为XX)。 @@ -7199,7 +6662,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 如果您想在输出中使用双引号,必须在其前面加上反斜杠,例如'\"YYYY Month\"' - 反斜杠在双引号之外不起特殊作用。在双引号字符串内部,反斜杠会使下一个字符被直接解释,无论是什么(但除非下一个字符是双引号或另一个反斜杠,否则没有特殊效果)。 + 反斜杠在双引号之外不起特殊作用。在双引号字符串内部,反斜杠会使下一个字符被按字面解释,无论是什么(但除非下一个字符是双引号或另一个反斜杠,否则没有特殊效果)。 @@ -7262,14 +6725,14 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 年份、周数和星期几:例如to_date('2006-42-4', 'IYYY-IW-ID') + 年份、周编号和星期几:例如to_date('2006-42-4', 'IYYY-IW-ID') 返回日期2006-10-19。 如果省略星期几,则假定为1(星期一)。 - 年份和年内天数:例如to_date('2006-291', 'IYYY-IDDD')也返回2006-10-19。 + 年份和年内日序数:例如to_date('2006-291', 'IYYY-IDDD')也返回2006-10-19 @@ -7277,14 +6740,14 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 尝试使用ISO 8601周编号字段和公历日期字段的混合输入日期是荒谬的,并将导致错误。 - 在ISO 8601周编号年的背景下,月份日期的概念没有意义。 + 在ISO 8601周编号年的背景下,月份月内日序数的概念没有意义。 在公历年的背景下,ISO周没有意义。 - 当to_date拒绝混合使用公历和ISO周编号日期字段时, - to_char不会,因为输出格式规范如YYYY-MM-DD (IYYY-IDDD)可能很有用。 + 虽然to_date会拒绝混合使用公历和ISO周编号日期字段, + 但to_char不会,因为输出格式规范如YYYY-MM-DD (IYYY-IDDD)可能很有用。 但要避免编写类似IYYY-MM-DD的内容;那会在年初附近产生令人惊讶的结果。 (有关更多信息,请参见。) @@ -7303,7 +6766,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 这是一个更复杂的示例: to_timestamp('15:12:02.020.001230', 'HH24:MI:SS.MS.US') - 是15小时,12分钟和2秒 + 20毫秒 + 1230微秒 = 2.021230秒。 + 为15小时12分钟,秒数为2秒 + 20毫秒 + 1230微秒 = 2.021230秒。 @@ -7311,7 +6774,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); to_char(..., 'ID')的星期几编号与extract(isodow from ...)函数匹配, - 但to_char(..., 'D')的不匹配extract(dow from ...)的星期编号。 + 但to_char(..., 'D')的不匹配extract(dow from ...)的星期几编号。 @@ -7328,12 +6791,12 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 展示了可以用于格式化数字值的模版模式。 + 展示了可以用于格式化数值的模板模式。
- 用于数字格式化的模板模式 + 用于数值格式化的模板模式 @@ -7346,21 +6809,21 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 9 - 数位(如果无意义可以被删除) + 数位(非有效位可以被省略) 0 - 数位(即便没有意义也不会被删除) + 数位(即便是非有效位也不会被省略) - . (period) + .(句点) 小数点 - , (comma) + ,(逗号) 分组(千)分隔符 @@ -7371,22 +6834,22 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); S - 带符号的数字(使用区域) + 紧贴数值的正负号(使用区域设置) L - 货币符号(使用区域) + 货币符号(使用区域设置) D - 小数点(使用区域) + 小数点(使用区域设置) G - 分组分隔符(使用区域) + 分组分隔符(使用区域设置) @@ -7410,7 +6873,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - TH or th + THth 序数后缀 @@ -7428,7 +6891,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}');
- 数字格式化的使用注意事项: + 数值格式化的使用注意事项: @@ -7444,14 +6907,14 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 如果格式提供的小数位数少于被格式化的数字,则to_char()将会将数字四舍五入到指定的小数位数。 + 如果格式指定的小数位数少于被格式化数值的小数位数,to_char()会将该数值舍入到指定的小数位数。 - 模式字符SLDG表示当前区域设置定义的符号、货币符号、小数点和千位分隔符字符 + 模式字符SLDG表示当前区域设置定义的正负号、货币符号、小数点和千位分隔符字符 (参见)。模式字符句点和逗号表示这些确切字符,具有小数点和千位分隔符的含义,不受区域设置影响。 @@ -7460,15 +6923,14 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 如果在to_char()的模式中没有明确指定符号,将为符号保留一列,并将其锚定到(出现在)数字的左侧。 - 如果S出现在一些9的左侧,它也将锚定到数字。 + 如果to_char()的模式中没有明确指定正负号的位置,就会为正负号保留一列,并使其紧贴数值(紧靠数值左侧)。如果S紧邻若干个9的左侧,它同样会紧贴数值。 - 使用SGPLMI格式化的符号不与数字绑定; + 使用SGPLMI格式化的正负号不紧贴数值; 例如,to_char(-12, 'MI9999')会产生'-  12', 但to_char(-12, 'S9999')会产生'  -12'。 (Oracle实现不允许在9之前使用MI,而是要求9MI之前。) @@ -7495,7 +6957,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); to_number函数中,如果使用非数据模板模式,如LTH, - 则会跳过相应数量的输入字符,无论它们是否与模板模式匹配,除非它们是数据字符(即数字、符号、小数点或逗号)。 + 则会跳过相应数量的输入字符,无论它们是否与模板模式匹配,除非它们是数据字符(即数字、正负号、小数点或逗号)。 例如,TH会跳过两个非数据字符。 @@ -7506,7 +6968,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); Vto_char一起, 将输入值乘以10^n, 其中n是跟在V后面的数字位数。 - Vto_number一起以类似的方式除法。 + Vto_number一起以类似的方式进行除法。 to_charto_number不支持与小数点结合使用的V (例如,不允许使用99.9V99)。 @@ -7522,17 +6984,17 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}');
- 某些修饰语可以被应用到任何模板来改变其行为。例如,FM99.99是带有FM修饰语的99.99模式。中展示了用于数字格式化模式修饰语。 + 某些修饰符可以被应用到任何模板来改变其行为。例如,FM99.99是带有FM修饰符的99.99模式。中展示了用于数值格式化的模式修饰符。 - 用于数字格式化的模板模式修饰语 + 用于数值格式化的模板模式修饰符 - 修饰语 + 修饰符 描述 示例 @@ -7540,19 +7002,19 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - FM prefix - 填充模式(抑制拖尾零和填充的空白) + FM 前缀 + 填充模式(抑制尾随零和填充的空白) FM99.99 - TH suffix + TH 后缀 大写序数后缀 999TH - th suffix + th 后缀 小写序数后缀 999th @@ -7736,10 +7198,10 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 时间/日期函数和操作符 + 日期/时间函数和操作符 - 展示了可用于处理日期/时间值的函数,其细节在随后的小节中描述。演示了基本算术操作符 (+*等)的行为。 而与格式化相关的函数,可以参考。你应该很熟悉中的日期/时间数据类型的背景知识。 + 展示了可用于处理日期/时间值的函数,其细节在随后的小节中描述。演示了基本算术操作符 (+*等)的行为。 而与格式化相关的函数,可以参考。你应当熟悉中的日期/时间数据类型的背景知识。 @@ -7825,7 +7287,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); interval - 添加时间间隔 + 将两个时间间隔相加 interval '1 day' + interval '1 hour' @@ -7867,7 +7329,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); interval - 取否一个时间间隔 + 对时间间隔取负 - interval '23 hours' @@ -7881,7 +7343,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); integer - 减去日期,生成经过的天数 + 将两个日期相减,得到相隔的天数 date '2001-10-01' - date '2001-09-28' @@ -7923,7 +7385,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); interval - 减去时间 + 将两个时间相减 time '05:00' - time '03:00' @@ -7965,7 +7427,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); interval - 减去时间间隔 + 将两个时间间隔相减 interval '1 day' - interval '1 hour' @@ -7979,12 +7441,12 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); interval - 减去时间戳(将24小时间隔转换为天数,类似于justify_hours() - 时间戳 '2001-09-29 03:00' - 时间戳 '2001-07-27 12:00' - 63 天 15:00:00 + timestamp '2001-09-29 03:00' - timestamp '2001-07-27 12:00' + 63 days 15:00:00 @@ -7994,7 +7456,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); interval - 将时间间隔乘以数量 + 将时间间隔乘以一个标量 interval '1 second' * 900 @@ -8016,7 +7478,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); interval - 用时间间隔除以数量 + 将时间间隔除以一个标量 interval '1 hour' / 1.5 @@ -8057,7 +7519,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); interval - 减去参数,生成一个使用年和月,而不是只用日的符号化的结果 + 将两个参数相减,生成一个使用年和月,而不是只用日的符号化的结果 age(timestamp '2001-04-10', timestamp '1957-06-13') @@ -8071,7 +7533,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); interval - 从 current_date 减去参数(在午夜) + 从current_date(午夜时刻)减去参数 age(timestamp '1957-06-13') @@ -8122,7 +7584,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); time with time zone - 一天中的当前时间;参见 + 一天中的当前时刻;参见 current_time @@ -8136,7 +7598,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); time with time zone - 一天中的当前时间;有限精度;参见 + 一天中的当前时刻,精度受限;参见 current_time(2) @@ -8153,7 +7615,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); timestamp with time zone - 当前日期和时间 (当前事务的开始);参见 + 当前日期和时间(当前事务开始时);参见 current_timestamp @@ -8167,7 +7629,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); timestamp with time zone - 当前日期和时间 (当前事务的开始);有限精度;参见 + 当前日期和时间(当前事务开始时),精度受限;参见 current_timestamp(0) @@ -8198,7 +7660,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); double precision - 获取时间戳字段 (等同于 extract);参见 + 获取时间戳子字段 (等同于 extract);参见 date_part('hour', timestamp '2001-02-16 20:38:40') @@ -8305,7 +7767,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); boolean - 测试有限日期(不是+/-无限) + 测试日期是否有限(不是正负无穷) isfinite(date '2001-02-16') @@ -8319,7 +7781,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); boolean - 测试有限时间戳(不是+/-无限) + 测试时间戳是否有限(不是正负无穷) isfinite(timestamp 'infinity') @@ -8386,7 +7848,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); interval - 使用 justify_daysjustify_hours调整时间间隔; 通过额外的符号调整 + 使用 justify_daysjustify_hours调整时间间隔,并额外调整符号 justify_interval(interval '1 mon -1 hour') @@ -8403,7 +7865,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); time - 一天中当前时间;参见 + 一天中的当前时刻;参见 localtime @@ -8417,7 +7879,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); time - 一天中的当前时间,有限精度;参见 + 一天中的当前时刻,精度受限;参见 localtime(0) @@ -8434,7 +7896,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); timestamp - 当前日期和时间(当前事务的开始);参见 + 当前日期和时间(当前事务开始时);参见 localtimestamp @@ -8448,7 +7910,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); timestamp - 当前日期和时间(当前事务的开始);有限精度;参见 + 当前日期和时间(当前事务开始时),精度受限;参见 localtimestamp(2) @@ -8576,7 +8038,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); timestamp with time zone - 当前日期和时间(当前事务的开始);参见 + 当前日期和时间(当前事务开始时);参见 now() @@ -8593,7 +8055,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); timestamp with time zone - 当前日期和时间(当前语句的开始);参见 + 当前日期和时间(当前语句开始时);参见 statement_timestamp() @@ -8628,7 +8090,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); timestamp with time zone - 当前日期和时间(当前事务的开始);参见 + 当前日期和时间(当前事务开始时);参见 transaction_timestamp() @@ -8645,7 +8107,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); timestamp with time zone - 将Unix纪元转换为带时区的时间戳(从1970-01-01 00:00:00+00开始的秒) + 将 Unix 纪元时间(自 1970-01-01 00:00:00+00 起的秒数)转换为带时区的时间戳 to_timestamp(1284352323) @@ -8665,7 +8127,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); (start1, end1) OVERLAPS (start2, end2) (start1, length1) OVERLAPS (start2, length2) - 这个表达式在两个时间域(用它们的端点定义)重叠的时候得到真,当它们不重叠时得到假。端点可以用一对日期、时间或者时间戳来指定;或者是用一个后面跟着一个间隔的日期、时间或时间戳来指定。当一对值被提供时,起点或终点都可以被写在前面,OVERLAPS会自动地把较早的值作为起点。每一个时间段被认为是表示半开的间隔start <= time < end,除非startend相等,这种情况下它表示单个时间实例。例如这表示两个只有一个共同端点的时间段不重叠。 + 这个表达式在两个时间段(用它们的端点定义)重叠的时候得到真,当它们不重叠时得到假。端点可以用一对日期、时间或者时间戳来指定;或者是用一个后面跟着一个间隔的日期、时间或时间戳来指定。当一对值被提供时,起点或终点都可以被写在前面,OVERLAPS会自动地把较早的值作为起点。每一个时间段被认为是表示半开区间start <= time < end,除非startend相等,这种情况下它表示单个时刻。例如这表示两个只有一个共同端点的时间段不重叠。 @@ -8684,16 +8146,13 @@ SELECT (DATE '2001-10-30', DATE '2001-10-30') OVERLAPS - 当把一个interval值添加到timestamp with time zone上(或从中减去)时,天这一部分会按照指定的天数增减该timestamp with time zone的日期,同时保持一天中的时间不变。 - 对于跨越夏令时变更的情况(当会话时区被设置为能够识别 DST 的时区时),这意味着interval '1 day'并不一定等于interval '24 hours'。 - 例如,当会话的时区设置为America/Denver时: + 当把一个interval值加到某个时间戳上(或从该时间戳中减去一个interval值)时,如果该时间戳为timestamp with time zone类型,天数部分会相应增加或减少timestamp with time zone的日期,变化天数为所指定的天数,而一天中的时刻保持不变。当跨越夏令时变化时(会话时区设为识别夏令时的时区),这意味着interval '1 day'不一定等于interval '24 hours'。例如,当会话时区设置为America/Denver SELECT timestamp with time zone '2005-04-02 12:00:00-07' + interval '1 day'; 结果:2005-04-03 12:00:00-06 SELECT timestamp with time zone '2005-04-02 12:00:00-07' + interval '24 hours'; 结果:2005-04-03 13:00:00-06 - - 发生这种情况是因为在America/Denver时区,夏令时在2005-04-03 02:00:00发生切换,导致跳过了一个小时。 +出现这种情况,是因为夏令时变化跳过了一个小时;变化发生的时间为2005-04-03 02:00:00,所在时区为America/Denver @@ -8701,15 +8160,9 @@ SELECT timestamp with time zone '2005-04-02 12:00:00-07' + interval '24 hours'; - 日期和时间戳的减法也可能会很复杂。执行减法的一种概念上很简单的方法是,使用 - EXTRACT(EPOCH FROM ...)把每个值都转换成秒数,然后执行减法, - 这样会得到两个值之间的数。这种方法将会适应每个月中天数、 - 时区改变和夏令时调整。使用-操作符的日期或时间 - 戳减法会返回值之间的天数(24小时)以及时/分/秒,也会做同样的调整。 - age函数会返回年、月、日以及时/分/秒,执行按域的减法,然后对 - 负值域进行调整。下面的查询展示了这些方法的不同。示例中的结果由 - timezone = 'US/Eastern'产生,这使得两个使用的日期之间存在着夏令 - 时的变化: + 日期和时间戳的减法也可能很复杂。一种概念上简单的方法是,先用EXTRACT(EPOCH FROM ...)将各值转换为秒数,然后将结果相减;这样得到的是两个值之间的数。这种方法会针对每个月的天数、时区变化和夏令时变化进行调整。 + 用-操作符将日期或时间戳值相减,会返回两个值之间的天数(每一天为 24 小时)和时/分/秒,也会作相同的调整。age函数返回年、月、日和时/分/秒,它会逐字段相减,然后调整负值字段。 + 以下查询显示了这些方法的差异。示例结果在timezone = 'US/Eastern'设置下产生;所用的两个日期之间发生了夏令时切换: @@ -8761,7 +8214,7 @@ EXTRACT(field FROM source) - 这个世纪;对于interval值,年份字段除以100 + 世纪;对于interval值,年份字段除以100 @@ -8784,7 +8237,7 @@ SELECT EXTRACT(CENTURY FROM INTERVAL '2001 years'); - 月份的日期(1–31);对于interval值,表示天数 + 一个月中的第几天(1–31);对于interval值,表示天数 @@ -8837,7 +8290,7 @@ SELECT EXTRACT(DOW FROM TIMESTAMP '2001-02-16 20:38:40'); - 一年中的日子(1-365/366) + 一年中的第几天(1–365/366) @@ -8852,7 +8305,7 @@ SELECT EXTRACT(DOY FROM TIMESTAMP '2001-02-16 20:38:40'); - 对于timestamp with time zone值,自1970-01-01 00:00:00 UTC以来的秒数(负值表示该时间戳之前的时间); + 对于timestamp with time zone值,自1970-01-01 00:00:00 UTC以来的秒数(早于该时刻的时间戳对应负值); 对于datetimestamp值,自1970-01-01 00:00:00以来的名义秒数,不考虑时区或夏令时规则; 对于interval值,间隔中的总秒数 @@ -8876,8 +8329,8 @@ SELECT to_timestamp(982384720.12); - 注意,将to_timestamp应用于从datetimestamp值中提取的时代可能会产生误导性的结果: - 结果将有效地假定原始值是以UTC时间给出的,这可能并非事实。 + 注意,将to_timestamp应用于从datetimestamp值中提取的 epoch 值可能会产生误导性的结果: + 结果实际上会假定原始值是以UTC时间给出的,这可能并非事实。 @@ -8933,8 +8386,7 @@ SELECT EXTRACT(ISOYEAR FROM DATE '2006-01-02'); - 每个ISO 8601周编号年从包含1月4日的星期一开始,因此在一月初或十二月底,ISO年可能与格里高利年不同。 - 有关更多信息,请参见week字段。 + 每个 ISO 8601 周编号年都从包含 1 月 4 日的那一周的星期一开始,因此在 1 月初或 12 月末,ISO 年可能与格里高利年不同。更多信息请参见 week 字段。 @@ -8977,7 +8429,7 @@ SELECT EXTRACT(MICROSECONDS FROM TIME '17:12:28.5'); - 千年; 对于interval值,年份字段除以1000 + 千年; 对于interval值,年份字段除以1000 @@ -8988,7 +8440,7 @@ SELECT EXTRACT(MILLENNIUM FROM INTERVAL '2001 years'); - 20世纪的年份在第二个千年。第三个千年从2001年1月1日开始。 + 1900 年代的年份属于第二个千年。第三个千年始于 2001 年 1 月 1 日。 @@ -8998,7 +8450,7 @@ SELECT EXTRACT(MILLENNIUM FROM INTERVAL '2001 years'); - 第二个字段,包括小数部分,乘以1000。请注意,这包括完整的秒数。 + 秒字段,包括小数部分,乘以1000。请注意,这包括完整的秒数。 @@ -9028,7 +8480,7 @@ SELECT EXTRACT(MINUTE FROM TIMESTAMP '2001-02-16 20:38:40'); - 月份在一年中的编号(1-12);对于interval值,月份模12的余数(0-11) + 月份在一年中的编号(1–12);对于interval值,月份模12的余数(0–11) @@ -9047,7 +8499,7 @@ SELECT EXTRACT(MONTH FROM INTERVAL '2 years 13 months'); - 日期所在的年份季度(1-4) + 日期所在的年份季度(1–4) @@ -9089,7 +8541,7 @@ SELECT EXTRACT(SECOND FROM TIME '17:12:28.5'); - 时间区偏移的小时组件 + 时区偏移的小时部分 @@ -9099,7 +8551,7 @@ SELECT EXTRACT(SECOND FROM TIME '17:12:28.5'); - 时间区偏移的分钟组件 + 时区偏移的分钟部分 @@ -9109,16 +8561,11 @@ SELECT EXTRACT(SECOND FROM TIME '17:12:28.5'); - 一年中ISO 8601周编号周的数量。根据定义,ISO周从周一开始, - 一年的第一周包含该年的1月4日。换句话说,一年的第一个星期四在该年的第1周。 + 一年中按ISO 8601 周编号体系计算的周序号。根据定义,ISO 周从周一开始,一年的第一周包含该年的 1 月 4 日。换句话说,一年的第一个星期四在该年的第 1 周。 - 在ISO周编号系统中,早年1月的日期可能属于前一年的第52周或第53周,而 - 晚年12月的日期可能属于下一年的第一周。例如,2005-01-01 - 属于2004年的第53周,2006-01-01 属于2005年的第52周, - 而2012-12-31 属于2013年的第一周。建议同时使用 - isoyear 字段和week以获得一致的结果。 + 在 ISO 周编号体系中,1 月初的日期可能属于前一年的第 52 周或第 53 周,而 12 月末的日期可能属于下一年的第一周。例如,2005-01-01属于 2004 年的第 53 周,2006-01-01属于 2005 年的第 52 周,而2012-12-31属于 2013 年的第一周。建议将isoyear字段与week一起使用,以获得一致的结果。 @@ -9133,7 +8580,7 @@ SELECT EXTRACT(WEEK FROM TIMESTAMP '2001-02-16 20:38:40'); - 年份字段。请记住,没有0 AD,所以要小心地从AD年中减去BC年。 + 年份字段。请记住,没有0 AD,所以把BC年份从AD年份中减去时需要小心。 @@ -9160,7 +8607,7 @@ SELECT EXTRACT(MINUTES FROM INTERVAL '80 minutes'); - 当输入值为 +/-Infinity 时,extract对于单调增的域(epochjulianyearisoyeardecadecentury以及millennium)返回 +/-Infinity。对于其他域返回 NULL。PostgreSQL 9.6 之前的版本对所有输入无穷的情况都返回零。 + 当输入值为 +/-Infinity 时,extract对于单调递增的字段(epochjulianyearisoyeardecadecentury以及millennium)返回 +/-Infinity。对于其他字段返回 NULL。PostgreSQL 9.6 之前的版本对所有输入无穷的情况都返回零。 @@ -9169,15 +8616,12 @@ SELECT EXTRACT(MINUTES FROM INTERVAL '80 minutes'); - 在传统的Ingres上建模的date_part函数等价于SQL标准函数extract: + date_part函数仿照传统的Ingres实现,后者对应SQL标准的extract函数: date_part('field', source) - 请注意这里的field参数必须是一个串值,而不是一个名字。 - 有效的date_part域名 和extract相同。 - 由于历史原因,date_part函数返回double precision类型的值。 - 这可能导致在某些使用中损失精度。 - 建议使用extract替代。 + 注意,此处的field参数必须是字符串值,而不能是名称。date_part的有效字段名与extract相同。 + 由于历史原因,date_part函数返回double precision类型的值,可能在某些用途中损失精度。建议改用extract @@ -9204,11 +8648,12 @@ SELECT date_part('hour', INTERVAL '4 hours 3 minutes'); date_trunc(field, source [, time_zone ]) - source是类型timestampinterval的值表达式(类型datetime的值都分别被自动转换成timestamp, timestamp with time zone,或者interval)。field选择对输入值选用什么样的精度进行截断。返回的值是timestamp, timestamp with time zone,类型或者所有小于选定的 精度的域都设置为零(或者一,对于日期和月份)的interval。 + sourcetimestamptimestamp with time zoneinterval类型的值表达式。(datetime类型的值会分别自动转换为timestampinterval。) + field选择输入值的截断精度。返回值同样为timestamptimestamp with time zoneinterval类型,其中低于所选精度的所有字段都设为零(日和月则设为一)。 - field的有效值是∶ + field的有效值是: microseconds milliseconds @@ -9227,7 +8672,7 @@ date_trunc(field, source [ - 当输入值的类型为timestamp with time zone时。截断是针对特定时区进行的。 例如,截断为day,产生的值是 是该区域的午夜。 默认情况下,截断是在以下方面进行的 到当前的设置,但在当前的 可以提供可选的time_zone参数。以指定不同的时区。 可以指定时区名称 中描述的任何一种方式。 + 当输入值为timestamp with time zone类型时,截断会以特定时区为准;例如,截断到day会得到该时区的午夜。默认情况下,截断以当前的设置为准,但可以通过可选的time_zone参数指定其他时区。时区名称可以用中描述的任意方式指定。 @@ -9269,11 +8714,11 @@ date_bin(stride, source, < sourcetimestamptimestamp with time zone类型的值表达式。 (类型date的值会自动转换为timestamp。) strideinterval类型的值表达式。 - 返回值同样是timestamptimestamp with time zone类型,并且它标记着放置source的bin的开始。 + 返回值同样是timestamptimestamp with time zone类型,并且它表示source所在分箱的起点。 - 示例: + 示例: SELECT date_bin('15 minutes', TIMESTAMP '2020-02-11 15:44:17', TIMESTAMP '2001-01-01'); 结果: 2020-02-11 15:30:00 @@ -9292,28 +8737,24 @@ SELECT date_bin('15 minutes', TIMESTAMP '2020-02-11 15:44:17', TIMESTAMP '2001-0 - <literal>AT TIME ZONE</literal> 和 <literal>AT LOCAL</literal> + <literal>AT TIME ZONE</literal> - time zone - conversion + 时区 + 转换 AT TIME ZONE - - AT LOCAL - - - AT TIME ZONE 操作符可在带时区和不带时区的时间戳之间进行转换,也可将 time with time zone 值转换到不同的时区。 展示了它的各种变体。 + AT TIME ZONE 操作符可将不带时区的时间戳转换为时区的时间戳或反向转换,也可将 time with time zone 值转换到不同的时区。 展示了它的各种变体。
- <literal>AT TIME ZONE</literal> 和 <literal>AT LOCAL</literal> 变体 + <literal>AT TIME ZONE</literal> 变体 @@ -9346,20 +8787,6 @@ SELECT date_bin('15 minutes', TIMESTAMP '2020-02-11 15:44:17', TIMESTAMP '2001-0 - - - timestamp without time zone AT LOCAL - timestamp with time zone - - - 将给定的不带时区时间戳转换为带时区时间戳,所用时区为会话的 TimeZone 值。 - - - timestamp '2001-02-16 20:38:40' at local - 2001-02-17 03:38:40+00 - - - timestamp with time zone AT TIME ZONE zone @@ -9374,20 +8801,6 @@ SELECT date_bin('15 minutes', TIMESTAMP '2020-02-11 15:44:17', TIMESTAMP '2001-0 - - - timestamp with time zone AT LOCAL - timestamp without time zone - - - 将给定的带时区时间戳转换为无时区时间戳,所用时区为会话的 TimeZone 值。 - - - timestamp with time zone '2001-02-16 20:38:40-05' at local - 2001-02-16 18:38:40 - - - time with time zone AT TIME ZONE zone @@ -9402,22 +8815,6 @@ SELECT date_bin('15 minutes', TIMESTAMP '2020-02-11 15:44:17', TIMESTAMP '2001-0 - - - time with time zone AT LOCAL - time with time zone - - - 将给定的带时区时间转换到新的时区,所用时区为会话的 TimeZone 值。由于没有提供日期,这会使用会话 TimeZone 当前生效的 UTC 偏移量。 - - - 假定会话的 TimeZone 设为 UTC: - - - time with time zone '05:34:17-05' at local - 10:34:17+00 - -
@@ -9428,12 +8825,7 @@ SELECT date_bin('15 minutes', TIMESTAMP '2020-02-11 15:44:17', TIMESTAMP '2001-0 使用间隔值只对与 UTC 存在固定偏移量的时区有意义,因此在实践中并不常见。
- - 语法 AT LOCAL 可以作为 AT TIME ZONE local 的简写,其中 local 是会话的 TimeZone 值。 - - - - 示例(假设当前的设置为America/Los_Angeles): + 示例(假设当前设置为America/Los_Angeles): SELECT TIMESTAMP '2001-02-16 20:38:40' AT TIME ZONE 'America/Denver'; 结果:2001-02-16 19:38:40-08 @@ -9441,36 +8833,10 @@ SELECT TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40-05' AT TIME ZONE 'America/D 结果:2001-02-16 18:38:40 SELECT TIMESTAMP '2001-02-16 20:38:40' AT TIME ZONE 'Asia/Tokyo' AT TIME ZONE 'America/Chicago'; 结果:2001-02-16 05:38:40 -SELECT TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40-05' AT LOCAL; -结果:2001-02-16 17:38:40 -SELECT TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40-05' AT TIME ZONE '+05'; -结果:2001-02-17 06:38:40 -SELECT TIME WITH TIME ZONE '20:38:40-05' AT LOCAL; -结果:17:38:40-08 - - 第一个示例为缺少时区的值添加时区,并使用当前的 TimeZone 设置显示该值。 - 第二个示例将带时区的时间戳值转换到指定时区,并返回无时区的值。 - 这允许存储和显示与当前 TimeZone 设置不同的值。第三个示例将东京时间转换为芝加哥时间。第四个示例展示了 AT LOCAL 的用法。第五个示例使用数值型 UTC 偏移量作为时区。最后一个示例展示了 time with time zone 值转换为会话本地时区的结果。 - - - - 函数timezone(zone, timestamp)等效于 SQL 兼容的结构timestamp AT TIME ZONE zone。 - - - - 结构 timestamp AT LOCAL 等效于 timestamp AT TIME ZONE local。 - +
第一个示例为不带时区的值添加时区,并使用当前TimeZone设置显示该值。第二个示例将带时区的时间戳值移到指定时区,并返回不带时区的值。这样就可以存储和显示与当前TimeZone设置不同的值。第三个示例将东京时间转换为芝加哥时间。
- 函数timezone(zone, timestamp with time zone)等效于 SQL 兼容的结构timestamp with time zone AT TIME ZONE zone。 - - - - 结构 timestamp with time zone AT LOCAL 等效于 timestamp with time zone AT TIME ZONE local。 - - - - 函数timezone(zone, time with time zone)等效于 SQL 兼容的结构time with time zone AT TIME ZONE zone。结构 time with time zone AT LOCAL 等效于 time with time zone AT TIME ZONE local。 + 函数timezone(zone, timestamp)等效于符合 SQL 标准的结构timestamp AT TIME ZONE zone @@ -9479,13 +8845,13 @@ SELECT TIME WITH TIME ZONE '20:38:40-05' AT LOCAL; 当前日期/时间 - date - current + 日期 + 当前 - time - current + 时间 + 当前 @@ -9504,15 +8870,15 @@ LOCALTIMESTAMP(precision) - CURRENT_TIMECURRENT_TIMESTAMP传递带有时区的值;LOCALTIMELOCALTIMESTAMP传递的值不带时区。 + CURRENT_TIMECURRENT_TIMESTAMP返回带时区的值;LOCALTIMELOCALTIMESTAMP返回不带时区的值。 - CURRENT_TIMECURRENT_TIMESTAMPLOCALTIMELOCALTIMESTAMP可以有选择地接受一个精度参数,该精度会使结果的秒字段圆整到指定的小数位数。如果没有精度参数,结果将给出可用的全部精度。 + CURRENT_TIMECURRENT_TIMESTAMPLOCALTIMELOCALTIMESTAMP可以有选择地接受一个精度参数,该精度会使结果的秒字段舍入到指定的小数位数。如果没有精度参数,结果将给出可用的全部精度。 - 一些示例: + 一些示例: SELECT CURRENT_TIME; 结果: 14:39:53.662522-05 @@ -9534,7 +8900,7 @@ SELECT LOCALTIMESTAMP; - 许多其它数据库系统可能会更频繁地推进这些值。 + 其他数据库系统可能会更频繁地推进这些值。 @@ -9551,11 +8917,11 @@ now() - transaction_timestamp()等价于CURRENT_TIMESTAMP,但是其命名清楚地反映了它的返回值。statement_timestamp()返回当前语句的开始时刻(更准确的说是收到 客户端最后一条命令的时间)。statement_timestamp()transaction_timestamp()在一个事务的第一条命令期间返回值相同,但是在随后的命令中却不一定相同。 clock_timestamp()返回真正的当前时间,因此它的值甚至在同一条 SQL 命令中都会变化。timeofday()是一个有历史原因的PostgreSQL函数。和clock_timestamp()相似,timeofday()也返回真实的当前时间,但是它的结果是一个格式化的text串,而不是timestamp with time zone值。now()PostgreSQL的一个传统,等效于transaction_timestamp()。 + transaction_timestamp()等价于CURRENT_TIMESTAMP,但是其命名清楚地反映了它的返回值。statement_timestamp()返回当前语句的开始时刻(更准确地说,是接收到客户端最近一条命令消息的时间)。statement_timestamp()transaction_timestamp()在一个事务的第一条语句期间返回值相同,但是在随后的语句中却不一定相同。 clock_timestamp()返回真正的当前时间,因此它的值甚至在同一条 SQL 语句中都会变化。timeofday()是一个有历史原因的PostgreSQL函数。和clock_timestamp()相似,它也返回真实的当前时间,但是它的结果是一个格式化的text串,而不是timestamp with time zone值。now()PostgreSQL中与transaction_timestamp()等价的传统函数。 - 所有日期/时间类型还接受特殊的文字值now,用于指定当前的日期和时间(重申,被解释为当前事务的开始时刻)。 因此,下面三个都返回相同的结果: + 所有日期/时间数据类型也都接受特殊字面值now来指定当前日期和时间(同样解释为事务开始时间)。因此,下面三种写法都返回相同的结果: SELECT CURRENT_TIMESTAMP; SELECT now(); @@ -9567,7 +8933,7 @@ SELECT TIMESTAMP 'now'; -- 但请参阅下面的提示 当指定以后要计算的值时,不要使用第三种形式,例如在表列的DEFAULT子句中。 - 系统将在分析这个常量的时候把now转换为一个timestamp, 这样需要默认值时就会得到创建表的时间!而前两种形式要到实际使用缺省值的时候才被计算, 因为它们是函数调用。因此它们可以给出每次插入行的时刻。 + 系统将在分析这个常量的时候把now转换为一个timestamp, 这样需要默认值时就会得到创建表的时间!而前两种形式要到实际使用默认值的时候才被计算, 因为它们是函数调用。因此它们可以给出每次插入行的时刻。 (参见 。) @@ -9590,24 +8956,24 @@ SELECT TIMESTAMP 'now'; -- 但请参阅下面的提示 - sleep + 休眠 - delay + 延迟 - 下面的这些函数可以用于让服务器进程延时执行: + 以下函数可用于延迟服务器进程的执行: pg_sleep ( double precision ) pg_sleep_for ( interval ) pg_sleep_until ( timestamp with time zone ) - pg_sleep使当前会话的进程休眠,直到过去给定的秒数。可以指定几分之一秒的延迟。 - pg_sleep_for是一个方便的函数,允许将睡眠时间指定为时间间隔。 - pg_sleep_until是一个方便的函数,用于需要特定的唤醒时间。例如: + pg_sleep使当前会话的进程休眠,直到经过指定的秒数。可以指定带小数部分的秒数作为延迟时间。 + pg_sleep_for是一个便捷函数,允许以interval指定休眠时间。 + pg_sleep_until是在需要指定唤醒时间时使用的便捷函数。例如: SELECT pg_sleep(1.5); @@ -9642,7 +9008,7 @@ SELECT pg_sleep_until('tomorrow 03:00'); 枚举支持函数 - 对于枚举类型(在中描述), 有一些函数允许更清洁的编码,而不需要为一个枚举类型硬写特定的值。它们被列在中。本例假定一个枚举类型被创建为: + 对于枚举类型(见),有些函数可以避免硬编码枚举类型中的特定值,使程序更简洁。这些函数列在中。以下示例假定枚举类型按如下方式创建: CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple'); @@ -9728,8 +9094,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple anyarray - 以一个数组返回在给定两个枚举值之间的范围。值必须来自相同的枚举类型。 - 如果第一个参数为空,其结果将从枚举类型的第一个值开始。如果第二参数为空,其结果将以枚举类型的最后一个值结束。 + 以有序数组返回两个给定枚举值之间的范围。两个值必须来自同一枚举类型。如果第一个参数为 null,结果从该枚举类型的第一个值开始;如果第二个参数为 null,结果以该枚举类型的最后一个值结束。 enum_range('orange'::rainbow, 'green'::rainbow) @@ -9749,8 +9114,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple - 请注意,除了双参数形式的enum_range外, 这些函数忽略传递给它们的具体值,它们只关心声明的数据类型。 - 空值或类型的一个特定值可以通过,并得到相同的结果。这些函数更多地被用于一个表列或函数参数,而不是一个硬写的类型名,如示例中所使用。 + 请注意,除了enum_range的双参数形式外,这些函数都忽略传入的具体值,只关心其声明的数据类型。传入 null 或该类型的某个具体值,结果都相同。通常会将这些函数用于表列或函数参数,而不是像示例那样使用硬编码的类型名。 @@ -9761,7 +9125,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple 几何类型pointboxlseglinepath、 - polygoncircle有一大堆本地支持函数和操作符,如中所示。 + polygoncircle有大量内置支持函数和操作符,如中所示。 @@ -9806,7 +9170,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple path - 连接两个打开的路径(如果其中一个路径是关闭的,则返回NULL)。 + 连接两个开放路径(如果任一路径是封闭的,则返回NULL)。 path '[(0,0),(1,1)]' + path '[(2,2),(3,3),(4,4)]' @@ -9835,11 +9199,11 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple geometric_type - 将第一个参数的每个点乘上第二个point(将点视为由实部和虚部表示的复数,并执行标准的复数乘法)。 + 将第一个参数的每个点乘上第二个point(将点视为由实部和虚部表示的复数,并执行标准的复数乘法)。 如果将第二个point解释为向量,这等价于将对象的大小和到原点的距离按向量的长度缩放,并以向量与x轴的夹角绕原点逆时针旋转。 适用于pointboxRotating 用这些操作符“旋转”一个盒子,只会移动它的角点:这个盒子仍然被认为有平行于轴的边。 - 因此,盒子的大小并没有像真正的旋转那样得到保留。 + id="functions-geometry-rotation-fn">用这些操作符旋转一个矩形框,只会移动它的角点:这个矩形框仍然被认为有平行于轴的边。 + 因此,矩形框的大小并没有像真正的旋转那样得到保留。 pathcircle @@ -9859,7 +9223,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple 将第一个参数的每个点除以第二个point(将点视为由实部和虚部表示的复数,并执行标准的复数除法)。 - 如果将第二个point解释为向量,这等价于将物体的大小和到原点的距离按向量的长度向下缩放,并以向量与x轴的夹角围绕原点顺时针旋转。 + 如果将第二个point解释为向量,这等价于将对象的大小和到原点的距离按向量长度的倒数缩放,并以向量与x轴的夹角围绕原点顺时针旋转。 适用于 point, box, path,circle @@ -9936,7 +9300,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple box - 计算两个方框的交集,如果没有则为NULL。 + 计算两个矩形框的交集,如果没有则为NULL。 box '(2,2),(-1,-1)' # box '(1,1),(-2,-2)' @@ -9950,7 +9314,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple point - 计算第一个对象上距离第二个对象最近的点。 + 计算第二个对象上距离第一个对象最近的点。 可用于以下类型的配对: (point, box), (point, lseg), @@ -9972,7 +9336,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple 计算对象之间的距离。 - 对于所有七种几何类型,所有point与另一种几何类型的组合, + 适用于除 polygon 之外的所有几何类型,所有point与另一种几何类型的组合, 以及以下这些额外的类型对: (box, lseg), (lseg, line), @@ -10012,7 +9376,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 第一个对象包含在第二个对象之中还是在第二个对象之上? 适用于这些类型对: + 第一个对象是否位于第二个对象内部或其上? 适用于这些类型对: (point, box), (point, lseg), (point, line), @@ -10112,7 +9476,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 第一个对象是否确定位于第二个对象下面? + 第一个对象是否严格位于第二个对象下面? 适用于 point, box, polygon, circle @@ -10127,7 +9491,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 第一个对象是否确定位于第二个对象上面? + 第一个对象是否严格位于第二个对象上面? 适用于 point, box, polygon, circle. @@ -10200,7 +9564,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 这些对象是否相交? 适用于这些类型对: + 这些对象是否相交? 适用于这些类型对: (box, box), (lseg, box), (lseg, lseg), @@ -10225,7 +9589,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 线是水平的? + 线是否水平? ?- lseg '[(-1,0),(1,0)]' @@ -10257,7 +9621,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 线是纵向的? + 线是否竖直? ?| lseg '[(-1,0),(1,0)]' @@ -10289,7 +9653,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 线是垂直的? + 两条线是否互相垂直? lseg '[(0,0),(0,1)]' ?-| lseg '[(0,0),(1,0)]' @@ -10307,7 +9671,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 线是平行的? + 两条线是否平行? lseg '[(-1,0),(1,0)]' ?|| lseg '[(-1,2),(1,2)]' @@ -10336,16 +9700,16 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple - 请注意same as操作符(~=),表示pointboxpolygoncircle类型的一般相等概念。 - 这些类型中的某些还有一个=操作符,但是=只比较相同的面积。 - 其它的标量比较操作符 (<=等等),在这些类型可用的地方,同样比较区域。 + 注意,相同操作符~=表示pointboxpolygoncircle类型通常意义上的相等。 + 某些几何类型还有=操作符,但=仅比较面积是否相等。 + 对于提供其他标量比较操作符(<=等)的类型,这些操作符同样比较面积。 - 在PostgreSQL14之前, 该点严格低于/高于比较操作符 point <<| pointpoint |>> point 分别被称为 <^>^。 + 在PostgreSQL14之前, 用于判断点是否严格位于另一点下方/上方的比较操作符 point <<| pointpoint |>> point 分别被称为 <^>^。 这些名字仍然可以使用,但是已被弃用并且最终将被移除。 @@ -10642,7 +10006,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple box - 计算内接于圆的方框。 + 计算内接于圆的矩形框。 box(circle '<(0,0),2>') @@ -10701,7 +10065,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple box - 计算两个方框的边界框。 + 计算两个矩形框的边界框。 bound_box(box '(1,1),(0,0)', box '(4,4),(3,3)') @@ -10718,7 +10082,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple circle - 计算包围方框的最小圆。 + 计算包围矩形框的最小圆。 circle(box '(1,1),(0,0)') @@ -10811,7 +10175,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple path - 将多边形转换为具有点的相同列表的封闭路径。 + 将多边形转换为具有相同点列表的封闭路径。 path(polygon '((0,0),(1,1),(2,0))') @@ -10919,7 +10283,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple polygon(circle '<(0,0),2>') - (-2,0,)&zwsp; (-1.73205080758774,0.9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999998999998989898989676868686887898999999999998989898989898999978987878787808070876888788989898989898989898989898989898989898989898968686868688768686887878989896868686889899999999999990000890000899900000000890000890000890000000000000000 + ((-2,0),&zwsp;(-1.7320508075688774,0.9999999999999999),&zwsp;(-1.0000000000000002,1.7320508075688772),&zwsp;(-1.2246063538223773e-16,2),&zwsp;(0.9999999999999996,1.7320508075688774),&zwsp;(1.732050807568877,1.0000000000000007),&zwsp;(2,2.4492127076447545e-16),&zwsp;(1.7320508075688776,-0.9999999999999994),&zwsp;(1.0000000000000009,-1.7320508075688767),&zwsp;(3.673819061467132e-16,-2),&zwsp;(-0.9999999999999987,-1.732050807568878),&zwsp;(-1.7320508075688767,-1.0000000000000009)) @@ -10933,7 +10297,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple polygon(4, circle '<(3,0),1>') - ((2,0,)&zwsp; (3,1,)&zwsp; (4,1.2246063538223773e-16), &zwsp; (3,-1)). + ((2,0),&zwsp;(3,1),&zwsp;(4,1.2246063538223773e-16),&zwsp;(3,-1)) @@ -10943,7 +10307,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple polygon - 将封闭路径转换为具有点的相同列表的多边形。 + 将封闭路径转换为具有相同点列表的多边形。 polygon(path '((0,0),(1,1),(2,0))') @@ -10956,7 +10320,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple
- 我们可以把一个point的两个组成数字当作具有索引 0 和 1 的数组访问。例如,如果t.p是一个point列,那么SELECT p[0] FROM t检索 X 坐标而 UPDATE t SET p[1] = ...改变 Y 坐标。同样,box或者lseg类型的值可以当作两个point值的数组值看待。 + 可以把一个point当作下标为 0 和 1 的数组,访问它的两个数值分量。例如,如果t.p是一个point列,那么SELECT p[0] FROM t检索 X 坐标而 UPDATE t SET p[1] = ...改变 Y 坐标。同样,box或者lseg类型的值可以当作两个point值组成的数组看待。 @@ -10972,8 +10336,8 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple 任何cidr 值都可以隐式地转换到inet;因此,下面在inet上操作的操作符和函数也可以在cidr值上工作。 - (对于inetcidr有单独的函数,这是因为这两种情况的行为应该是不同的。) - 此外,它允许将inet值转换为cidr。 + (如果inetcidr各有单独的函数,是因为这两种情况下的行为应当不同。) + 此外,也允许将inet值转换为cidr。 当这样做的时候,子网掩码右边的任何位都被静默地置零,以创建一个有效的cidr值。 @@ -11004,8 +10368,8 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean
- 子网是否严格包含在子网中?这个操作符和后续的四个操作符测试子网包含情况。 - 它们只考虑两个地址的网络部分(忽略网络掩码右侧的任何位),并确定一个网络与另一个网络相同或者是相同的子网。 + 子网是否严格包含在另一个子网中?这个操作符和后续四个操作符测试子网包含关系。 + 它们只考虑两个地址的网络部分(忽略网络掩码右侧的所有位),并判断一个网络是否与另一个网络相同,或是另一个网络的子网。 inet '192.168.1.5' << inet '192.168.1/24' @@ -11027,7 +10391,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 子网是否包含或等于子网? + 子网是否被包含于或等于子网? inet '192.168.1/24' <<= inet '192.168.1/24' @@ -11087,7 +10451,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple inet - 计算位 NOT. + 计算按位非。 ~ inet '192.168.1.6' @@ -11101,7 +10465,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple inet - 计算位 AND. + 计算按位与。 inet '192.168.1.6' & inet '0.0.0.255' @@ -11115,7 +10479,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple inet - 计算位 OR. + 计算按位或。 inet '192.168.1.6' | inet '0.0.0.255' @@ -11216,9 +10580,8 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple text - 创建缩写的文本显示格式。 - (结果与inet输出函数产生的结果相同;只有在与显式转换为text的结果相比时它才算是缩写形式, - 由于历史原因,它永远不会抑制子网掩码部分。) + 创建文本形式的缩写显示格式。 + (结果与inet输出函数产生的结果相同;只有与显式类型转换为text的结果相比时,才称为缩写形式。由于历史原因,后一种转换从不省略网络掩码部分。) abbrev(inet '10.1.0.0/32') @@ -11232,7 +10595,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple text - 创建缩写的文本显示格式。(缩写包括从子网掩码的右侧删除所有零字节;更多示例请见 。) + 创建文本形式的缩写显示格式。(缩写形式会省略网络掩码右侧值为零的字节;更多示例见。) abbrev(cidr '10.1.0.0/16') @@ -11351,7 +10714,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple integer - 以比特位返回子网掩码长度。 + 返回子网掩码长度,以位为单位。 masklen(inet '192.168.1.5/24') @@ -11453,7 +10816,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple MAC地址类型, macaddrmacaddr8,支持中所示的常用比较操作符以及中所示的特殊函数。 - 此外,它们支持位元逻辑操作符~, &| (NOT, AND 和 OR),就像上面对IP地址所示的那样。 + 此外,它们支持按位逻辑操作符~&|(非、与和或),就像上面对IP地址所示的那样。 @@ -11517,7 +10880,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple macaddr8 - 将地址的第7位设置为1,创建所谓的modified EUI-64,用于包含在IPv6地址中。 + 将地址的第 7 位设置为 1,生成所谓的修订 EUI-64 格式,以便用于 IPv6 地址。 macaddr8_set7bit(macaddr8 '00:34:56:ab:cd:ef') @@ -11535,7 +10898,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple 文本搜索函数和操作符 - 全文搜索 + 全文检索 函数和操作符 @@ -11548,7 +10911,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple 以及 - 总结了为全文搜索提供的函数和操作符。PostgreSQL的文本搜索功能的详细解释可参考。 + 总结了为全文检索提供的函数和操作符。PostgreSQL的文本搜索功能的详细解释可参考
@@ -11628,11 +10991,11 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsvector - 连接两个tsvector。如果两个输入都包含词素位置,则相应地调整第二个输入的位置。 + 连接两个tsvector。如果两个输入都包含词位位置,则相应地调整第二个输入的位置。 'a:1 b:2'::tsvector || 'c:1 d:2 b:3'::tsvector - 'a':1'b':2,5'c':3'd':4 + 'a':1 'b':2,5 'c':3 'd':4 @@ -11670,7 +11033,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsquery - 否定tsquery,生成一个与输入查询不匹配的匹配文档的查询。 + 对tsquery取反,生成匹配那些不满足输入查询的文档的查询。 !! 'cat'::tsquery @@ -11684,7 +11047,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsquery - 构造一个短语查询,如果两个输入查询在连续的词素上匹配,该查询将进行匹配。 + 构造一个短语查询;当两个输入查询分别匹配相邻的词位时,该查询匹配。 to_tsquery('fat') <-> to_tsquery('rat') @@ -11698,7 +11061,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 第一个tsquery包含了第二个吗?(这只考虑出现在一个查询中的所有词素是否出现在另一个查询中,忽略了组合操作符。) + 第一个tsquery包含了第二个吗?(这只考虑出现在一个查询中的所有词位是否出现在另一个查询中,忽略了组合操作符。) 'cat'::tsquery @> 'cat & rat'::tsquery @@ -11712,7 +11075,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 第一个tsquery包含在第二个中吗?(这只考虑出现在一个查询中的所有词素是否出现在另一个查询中,而忽略了组合操作符。) + 第一个tsquery包含在第二个中吗?(这只考虑出现在一个查询中的所有词位是否出现在另一个查询中,而忽略了组合操作符。) 'cat'::tsquery <@ 'cat & rat'::tsquery @@ -11729,7 +11092,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple 除了这些专用操作符之外, 中所示的常用比较操作符也适用于tsvectortsquery类型。 - 它们对于文本搜索不是很有用,但是允许使用。例如,建在这些类型列上的唯一索引。 + 这些操作符对文本搜索用处不大,但可以用于其他用途,例如在这些类型的列上建立唯一索引。
@@ -11762,9 +11125,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsvector - 将文本字符串数组转换为tsvector。 - 给定的字符串被直接用作词元,不经过进一步处理。数组元素不得为空字符串 - 或NULL。 + 将词位数组转换为 tsvector。给定的字符串按原样使用,不做进一步处理。 array_to_tsvector('{fat,cat,rat}'::text[]) @@ -11834,8 +11195,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsquery - 将文本转换为tsquery,根据指定的或默认配置对单词进行标准化。 - 字符串中的任何标点符号都会被忽略(它不决定查询操作符)。结果查询匹配文本中包含所有非停止词的文档。 + 将文本转换为tsquery,根据指定的或默认配置对单词进行正规化。字符串中的任何标点符号都会被忽略(它们不决定查询操作符)。生成的查询匹配包含文本中所有非停用词的文档。 plainto_tsquery('english', 'The Fat Rats') @@ -11854,8 +11214,8 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsquery - 将文本转换为tsquery,根据指定的或默认配置对单词进行标准化。 - 字符串中的任何标点符号都会被忽略(它不决定查询操作符)。结果查询匹配包含文本中所有非停止词的短语。 + 将文本转换为tsquery,根据指定的或默认配置对单词进行正规化。 + 字符串中的任何标点符号都会被忽略(它不决定查询操作符)。结果查询匹配包含文本中所有非停用词的短语。 phraseto_tsquery('english', 'The Fat Rats') @@ -11878,8 +11238,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsquery - 将文本转换为tsquery,根据指定的或默认配置对单词进行标准化。引用的单词序列被转换为短语测试。 - or一词被理解为产生 OR 操作符,而破折号产生 NOT 操作符;其他标点符号会被忽略。这类似于一些常见网络搜索工具的行为。 + 将文本转换为tsquery,根据指定的或默认配置对单词进行正规化。带引号的单词序列被转换为短语测试。or一词产生 OR 操作符,短横线产生 NOT 操作符;其他标点符号会被忽略。这类似于一些常见网络搜索工具的行为。 websearch_to_tsquery('english', '"fat rat" or cat dog') @@ -11925,14 +11284,13 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple setweight - 为特定词元设置权重 + 为特定词位设置权重 setweight ( vector tsvector, weight "char", lexemes text[] ) tsvector - 为vector中列出的lexemes赋予指定的weight。 - lexemes中的字符串被视为词元,不经过进一步处理。不匹配vector中任何词元的字符串将被忽略。 + 为 vector 中列在 lexemes 内的元素赋予指定的 weight setweight('fat:2,4 cat:3 rat:5,6B'::tsvector, 'A', '{cat,rat}') @@ -11968,7 +11326,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsquery - 将文本转换为tsquery,根据指定的或默认配置对单词进行标准化。单词必须由有效的tsquery操作符组合。 + 将文本转换为tsquery,根据指定的或默认配置对单词进行正规化。单词必须由有效的tsquery操作符组合。 to_tsquery('english', 'The & Fat & Rats') @@ -11987,7 +11345,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsvector - 将文本转换为tsvector,根据指定的或默认配置对单词进行标准化。结果中包含位置信息。 + 将文本转换为tsvector,根据指定的或默认配置对单词进行正规化。结果中包含位置信息。 to_tsvector('english', 'The Fat Rats') @@ -12009,9 +11367,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsvector - 将JSON文档中的每个字符串值转换为tsvector,根据指定的或默认配置对单词进行标准化。 - 然后将结果按文档顺序连接起来以产生输出。位置信息就像在每对字符串值之间存在一个停止词一样生成。 - (注意,当输入为jsonb时,JSON 对象字段的document order取决于具体实现;请注意这些示例中的差异。) + 将 JSON 文档中的每个字符串值转换为tsvector,根据指定的或默认配置对单词进行正规化。然后将结果按文档顺序连接起来以产生输出。生成位置信息时,视为每对字符串值之间存在一个停用词。(注意,当输入为jsonb时,JSON 对象字段的文档顺序取决于具体实现;请注意这些示例中的差异。) to_tsvector('english', '{"aa": "The Fat Rats", "b": "dog"}'::json) @@ -12045,15 +11401,15 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsvector - 选择filter请求的JSON文档中的每个项,并将每个项转换为tsvector,根据指定的或默认配置对单词进行标准化。 - 然后将结果按文档顺序连接起来以产生输出。位置信息就像在每对选定的项目之间存在一个停止词一样生成。 - (注意,当输入为jsonb时,JSON对象字段的document order取决于实现。) - filter必须是一个jsonb数组,其中包含0个或多个关键字: + 选择filter请求的JSON文档中的每个项,并将每个项转换为tsvector,根据指定的或默认配置对单词进行正规化。 + 然后将结果按文档顺序连接起来以产生输出。位置信息就像在每对选定的项目之间存在一个停用词一样生成。 + (注意,当输入为jsonb时,JSON对象字段的文档顺序取决于实现。) + filter必须是一个jsonb数组,其中包含0个或多个关键字: "string"(包括所有字符串值), "numeric"(包括所有数值), "boolean"(包括所有布尔值), "key"(包括所有键),或 - "all"(包括以上所有关键字)。 + "all"(包括以上所有内容)。 作为一种特殊情况,该filter也可以是这些关键字之一的简单JSON值。 @@ -12075,8 +11431,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsvector - 从vector中删除给定的lexeme的任何出现。 - lexeme字符串被视为原样的词元,不经过进一步处理。 + 从vector中删除给定的lexeme的所有出现。 ts_delete('fat:2,4 cat:3 rat:5A'::tsvector, 'fat') @@ -12090,9 +11445,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsvector - 从vector中删除lexemes中的任何出现。 - lexemes中的字符串被视为词元,不经过进一步处理。 - 不匹配vector中任何词元的字符串将被忽略。 + 从 vector 中删除 lexemes 所列词位的所有出现。 ts_delete('fat:2,4 cat:3 rat:5A'::tsvector, ARRAY['fat','rat']) @@ -12130,9 +11483,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple text - 以缩写形式显示documentquery的匹配项,该匹配项必须是原始文本,而不是tsvector。 - 在匹配查询之前,文档中的单词将根据指定的或默认的配置进行规范化。 - 中讨论了该函数的使用,还描述了可用的options。 + 以缩略形式显示querydocument中的匹配项;后者必须是原始文本,不能是tsvector。在匹配查询之前,文档中的单词将根据指定的或默认配置进行正规化。中讨论了该函数的使用,还描述了可用的options ts_headline('The fat cat ate the rat.', 'cat') @@ -12158,8 +11509,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple text - 以缩写形式显示匹配JSONdocument中字符串值中的query。 - 更多细节请参阅 。 + 以缩略形式显示query在 JSON document字符串值中的匹配项。更多细节请参见 ts_headline('{"cat":"raining cats and dogs"}'::jsonb, 'cat') @@ -12237,8 +11587,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsquery - 根据目标替换部分query,并替换通过执行SELECT命令获得的查询。 - 详情参见。 + 根据执行SELECT命令得到的目标和替换项,替换query中的相应部分。详情参见 SELECT ts_rewrite('a & b'::tsquery, 'SELECT t,s FROM aliases') @@ -12269,7 +11618,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsquery - 构造一个短语查询,用于搜索query1query2的匹配项,这些匹配项恰好出现在distance词位之间。 + 构造一个短语查询,用于搜索query1query2的匹配项,其匹配位置恰好相距distance个词位。 tsquery_phrase(to_tsquery('fat'), to_tsquery('cat'), 10) @@ -12298,7 +11647,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple unnest - for tsvector + 用于 tsvector unnest ( tsvector ) setof record @@ -12328,7 +11677,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple - 所有接受一个可选的regconfig参数的文本搜索函数在该参数被忽略时,使用由指定的配置。 + 所有接受一个可选的regconfig参数的文本搜索函数在省略该参数时,会使用由指定的配置。 @@ -12375,7 +11724,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple lexemes text[] ) - 根据指定的或默认的文本搜索配置从document中提取和标准化标记,并返回关于每个标记是如何处理的信息。 + 根据指定的或默认的文本搜索配置从document中提取和正规化词元,并返回关于每个词元是如何处理的信息。 详情参见 @@ -12393,8 +11742,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple text[] - 如果字典知道输入标记,则返回替换词位数组;如果字典知道该标记,但它是停止词,则返回空数组;如果它不是已知词,则返回 NULL。 - 详情参见。 + 如果词典识别输入词元,则返回由替换词位组成的数组;如果词典识别该词元,但它是停用词,则返回空数组;如果词典无法识别该词元,则返回NULL。详情参见 ts_lexize('english_stem', 'stars') @@ -12414,7 +11762,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple token text ) - 使用命名的解析器从document中提取标记。详情参见。 + 使用指定名称的解析器从document中提取词元。详情参见 ts_parse('default', 'foo - bar') @@ -12431,7 +11779,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple token text ) - 使用 OID 指定的解析器从document中提取标记。 + 使用 OID 指定的解析器从document中提取词元。 详情参见 @@ -12452,7 +11800,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple description text ) - 返回一个表,该表描述命名解析器可以识别的每种类型的标记。详情参见。 + 返回一个表,该表描述指定名称的解析器可以识别的每种类型的词元。详情参见 ts_token_type('default') @@ -12469,7 +11817,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple description text ) - 返回一个表,该表描述 OID 指定的解析器可以识别的每种标记类型。详情参见。 + 返回一个表,该表描述 OID 指定的解析器可以识别的每种词元类型。详情参见 ts_token_type(3722) @@ -12490,7 +11838,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple nentry integer ) - 执行sqlquery,该查询必须返回单个tsvector列,并返回数据中每个不同词元的统计信息。 + 执行sqlquery,该查询必须返回单个tsvector列,并返回数据中每个不同词位的统计信息。 详情参见 @@ -12505,10 +11853,9 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple - UUID 函数 - + UUID 生成 @@ -12517,184 +11864,37 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple gen_random_uuid - - uuidv4 - + + PostgreSQL包含一个生成 UUID 的函数: + +gen_random_uuid () uuid + + 该函数返回版本 4(随机)UUID。这是最常用的 UUID 类型,适用于大多数应用。 + + 模块还提供了额外的函数,用于实现其他标准 UUID 生成算法。 + + + PostgreSQL也为 UUID 提供了中展示的常用比较操作符。 + + + + + + XML 函数 - uuidv7 + XML 函数 - 展示了PostgreSQL - 中可用于生成 UUID 的函数。 + 本节中描述的函数以及类函数表达式都作用于类型 xml 的值。关于 xml 类型的详细信息请参见。用于在值与类型 xml 之间转换的类函数表达式 xmlparsexmlserialize 记录在该节中,而不是本节。 + + + + 使用大部分这些函数要求PostgreSQL使用了configure --with-libxml进行编译。 -
- <acronym>UUID</acronym> 生成函数 - - - - - 函数 - - - 描述 - - - 示例 - - - - - - - - gen_random_uuid ( ) - uuid - - - uuidv4 ( ) - uuid - - - 生成一个版本 4(随机)的 UUID - - - gen_random_uuid() - 5b30857f-0bfa-48b5-ac0b-5c64e28078d1 - - - uuidv4() - b42410ee-132f-42ee-9e4f-09a6485c95b8 - - - - - uuidv7 - ( shift interval ) - uuid - - - 生成一个版本 7(按时间排序)的 UUID。其时间戳由 UNIX 时间戳 - (毫秒精度)加上亚毫秒时间戳和随机值计算得到。可选参数 - shift会按给定的interval - 偏移计算出的时间戳。 - - - uuidv7() - 019535d9-3df7-79fb-b466-fa907fa17f9e - - - - -
- - - - 模块还提供了额外的函数,用于实现其他标准 UUID 生成算法。 - - - - - 展示了PostgreSQL - 中可用于从 UUID 提取信息的函数。 - - - - <acronym>UUID</acronym> 提取函数 - - - - - 函数 - - - 描述 - - - 示例 - - - - - - - - - uuid_extract_timestamp - - uuid_extract_timestamp - ( uuid ) - timestamp with time zone - - - 从版本 1 或 7 的 UUID 中提取 - timestamp with time zone。对于其他版本, - 该函数返回 null。注意,提取出的时间戳不一定与 UUID 生成时刻完全一致; - 这取决于生成该 UUID 的实现。 - - - uuid_extract_timestamp('019535d9-3df7-79fb-b466-&zwsp;fa907fa17f9e'::uuid) - 2025-02-23 21:46:24.503-05 - - - - - - uuid_extract_version - - uuid_extract_version - ( uuid ) - smallint - - - 从符合 - RFC 9562 - 所描述某一变体的 UUID 中提取版本号。对于其他变体,该函数返回 null。 - 例如,对于由gen_random_uuid()生成的 UUID, - 该函数将返回 4。 - - - uuid_extract_version('41db1265-8bc1-4ab3-992f-&zwsp;885799a4af1d'::uuid) - 4 - - - uuid_extract_version('019535d9-3df7-79fb-b466-&zwsp;fa907fa17f9e'::uuid) - 7 - - - - -
- - - PostgreSQL也为 UUID 提供了 - 中展示的常用比较操作符。 - - - 关于PostgreSQLuuid数据类型的细节,请参见 - 。 - - - - - - XML 函数 - - - XML 函数 - - - - 本节中描述的函数以及类函数表达式都作用于类型 xml 的值。关于 xml 类型的详细信息请参见。用于在值与类型 xml 之间转换的类函数表达式 xmlparsexmlserialize 记录在该节中,而不是本节。 - - - - 使用大部分这些函数要求PostgreSQL使用了configure --with-libxml进行编译。 - - - + 产生 XML 内容 @@ -13112,7 +12312,7 @@ SELECT xmlexists('//town[text() = ''Toronto'']' PASSING BY VALUE 'T
- 示例: + 示例: - 示例: + 示例: test', ARRAY[ARRAY['my', 'http://example.com']]); @@ -13229,7 +12429,7 @@ SELECT xpath('//mydefns:b/text()', 'test - 示例: + 示例: test', ARRAY[ARRAY['my', 'http://example.com']]); @@ -13281,8 +12481,8 @@ SELECT xpath_exists('/my:a/text()', 'test - document_expression提供了上下文。row_expression的项。 - 它必须是一个格式良好的XML文档;不接受片段/森林。BY REFBY VALUE子句 如上文所讨论的那样,被接受但被忽略了,正如在中所讨论的。 + document_expressionrow_expression提供上下文项。 + 它必须是一个良构的 XML 文档;不接受内容片段或森林。BY REFBY VALUE子句会被接受,但会被忽略,如中所述。 @@ -13331,7 +12531,7 @@ SELECT xpath_exists('/my:a/text()', 'test - 一个XML元素的字符串值是字符串值的协整,按文档的顺序。该元素中包含的所有文本节点及其子节点。字符串 元素的值是一个没有下级文本节点的元素的值是一个 空字符串(不是NULL)。任何xsi:nil属性都会被忽略。请注意,两个非文本之间的text()节点只用空格,而两个非文本 元素,并且保留了text()上的前导白格。节点不被扁平化。XPath 1.0中的string函数可以参考XPath 1.0中的 定义其他XML节点类型和非XML值的字符串值的规则。 + 一个 XML 元素的字符串值,是该元素及其所有后代中包含的文本节点按文档顺序拼接而成的字符串。没有后代文本节点的元素,其字符串值为空字符串(不是 NULL)。所有 xsi:nil 属性都会被忽略。注意,两个非文本元素之间仅含空白的 text() 节点会被保留,text() 节点的前导空白也不会被折叠。其他 XML 节点类型及非 XML 值的字符串值定义规则,可参考 XPath 1.0 的 string 函数。 @@ -13351,7 +12551,7 @@ SELECT xpath_exists('/my:a/text()', 'test - 示例: + 示例: - 下面的示例展示了多个text()节点的连接,列名作为XPath过滤器的使用,以及对空格、XML注释和处理指令的处理: + 下面的示例展示了多个text()节点的连接,列名作为XPath过滤器的使用,以及对空格、XML注释和处理指令的处理: - 本节描述: + 本节描述: @@ -13687,14 +12887,16 @@ table2-mapping - SQL/JSON路径语言 + SQL/JSON 路径语言 - 要了解有关SQL/JSON标准的更多信息,请参阅。有关PostgreSQL中支持的JSON类型的详细信息,见 。 + 要了解有关 SQL/JSON 标准的更多信息,请参阅。有关 + PostgreSQL 中支持的 JSON 类型的详细信息,见 + @@ -13849,14 +13051,13 @@ table2-mapping - 如果 JSON 输入没有匹配请求的正确结构,字段/元素/路径提取操作符会返回 NULL,而不是失败;例如,如果不存在这样的键或数组元素。 + 如果 JSON 输入没有匹配请求的正确结构,字段/元素/路径提取操作符会返回 NULL,而不是失败;例如,如果不存在这样的键或数组元素。 - 还有一些操作符仅适用于jsonb,如表所示。 - 第描述了如何使用这些操作符来有效地搜索索引的jsonb数据。 - + 还有一些操作符仅适用于jsonb,如所示。介绍了如何使用这些操作符有效地搜索已建立索引的jsonb数据。 + @@ -13931,7 +13132,7 @@ table2-mapping boolean - 文本数组中的字符串是否作为顶级键或数组元素存在? + 文本数组中的任一字符串是否作为顶级键或数组元素存在? '{"a":1, "b":2, "c":3}'::jsonb ?| array['b', 'd'] @@ -13982,7 +13183,7 @@ table2-mapping [{"a": "b"}, 42] - 要将一个数组作为单个条目附加到另一个数组中,请将其包装在另一个数组附加层中,例如: + 要将一个数组作为单个元素追加到另一个数组中,请先在它外面再包装一层数组,例如: '[1, 2]'::jsonb || jsonb_build_array('[3, 4]'::jsonb) @@ -14084,9 +13285,7 @@ table2-mapping - jsonpath操作符@?@@会抑制以下错误:缺少对象字段或数组元素、意外的 JSON 项目类型,以及日期时间和数字错误。 - 还可以告诉以下描述的与jsonpath相关的函数来抑制这些类型的错误。 - 在搜索不同结构的JSON文档集合时,此行为可能会有所帮助。 + jsonpath操作符@?@@会抑制以下错误:缺少对象字段或数组元素、JSON 项类型不符合预期,以及日期时间和数值错误。下文介绍的jsonpath相关函数也可以设置为抑制这些类型的错误。在搜索结构各异的 JSON 文档集合时,这一行为可能很有用。 @@ -14131,14 +13330,14 @@ table2-mapping jsonb - 将任何SQL值转换为jsonjsonb。数组和组合递归地转换为数组和对象(多维数组在JSON中变成数组的数组)。 - 否则,如果存在从SQL数据类型到json的类型转换,则类型转换函数将用于执行转换; + 将任何SQL值转换为jsonjsonb。数组和复合值递归地转换为数组和对象(多维数组在JSON中变成数组的数组)。 + 否则,如果存在从SQL数据类型到json的类型转换,则类型转换函数将用于执行转换; - 例如,扩展有一个从hstorejson的转换,这样通过json创建函数转换的hstore值将被表示为json对象,而不是原始字符串值 + 例如,扩展有一个从hstorejson的类型转换,因此通过 JSON 创建函数转换的hstore值将表示为 JSON 对象,而不是基本的字符串值。 - 否则,将生成一个标量json值。对于除数字、布尔值或空值之外的任何标量,将使用文本表示,并根据需要进行转义,使其成为有效的JSON字符串值。 + 否则,将生成一个标量 JSON 值。对于除数字、布尔值或空值之外的任何标量,将使用文本表示,并根据需要进行转义,使其成为有效的JSON字符串值。 to_json('Fred said "Hi."'::text) @@ -14146,7 +13345,7 @@ table2-mapping to_jsonb(row(42, 'Fred said "Hi."'::text)) - {"f1":42,"f2":"Fred said \"Hi.\""} + {"f1": 42, "f2": "Fred said \"Hi.\""} @@ -14176,7 +13375,7 @@ table2-mapping json - 将SQL组合值转换为JSON对象。该行为与to_json相同,只是如果可选boolean参数为真,换行符将在顶级元素之间添加。 + 将SQL 复合值转换为JSON对象。该行为与to_json相同,只是如果可选boolean参数为真,换行符将在顶级元素之间添加。 row_to_json(row(1,'foo')) @@ -14249,8 +13448,7 @@ table2-mapping jsonb - 从文本数组构建JSON对象。该数组必须有两个维度,一个维度的成员数为偶数,在这种情况下,它们被视为交替的键/值对; - 另一个维度的成员数为二维,每个内部数组恰好有两个元素,它们被视为键/值对。所有值都转换为JSON字符串。 + 从文本数组构造 JSON 对象。该数组必须是一维且包含偶数个成员,此时将成员按交替的键/值对处理;或者是二维数组,且每个内部数组恰好有两个元素,将这两个元素作为一个键/值对。所有值都转换为 JSON 字符串。 json_object('{a, 1, b, "def", c, 3.5}') @@ -14271,7 +13469,7 @@ table2-mapping jsonb - 这种形式的json_object从单独的文本数组中成对地获取键和值。否则,它与单参数形式相同。 + 这种形式的json_object从单独的文本数组中成对地获取键和值。除此之外,它与单参数形式相同。 json_object('{a,b}', '{1,2}') @@ -14558,48 +13756,48 @@ table2-mapping anyelement - 将顶级 JSON 对象展开为具有 base 参数复合类型的行。JSON 对象将被扫描,查找名称与输出行类型列名匹配的字段,并将其值插入到输出行的对应列中。 - (不对应任何输出列名的字段将被忽略。)在典型用法中,base 的值仅为 NULL,这意味着任何不匹配对象字段的输出列都会被填充为 null。 - 但是,如果base不为NULL,那么它包含的值将用于不匹配的列。 + 将顶级 JSON 对象展开为一个行,其复合类型与base参数相同。系统会扫描该 JSON 对象,查找名称与输出行类型列名匹配的字段,并将其值插入输出中的对应列。 + (不对应任何输出列名的字段会被忽略。)在典型用法中,base的值就是NULL,这意味着凡是不匹配对象字段的输出列都会被填充为空值。 + 但是,如果base不是NULL,那么其中包含的值将用于那些不匹配的列。 - 要将JSON值转换为输出列的SQL类型,需要按次序应用以下规则: + 要将 JSON 值转换为输出列的 SQL 类型,需要依次应用以下规则: - 在所有情况下,JSON空值都会转换为SQL空值。 + 在所有情况下,JSON 空值都会转换为 SQL 空值。 - 如果输出列的类型是jsonjsonb,则会精确地重制JSON值。 + 如果输出列的类型是jsonjsonb,则 JSON 值会被原样保留。 - 如果输出列是复合(行)类型,且JSON值是JSON对象,则该对象的字段将转换为输出行类型的列,通过这些规则的递归应用程序。 + 如果输出列是复合(行)类型,且 JSON 值是 JSON 对象,则该对象的字段会通过递归应用这些规则,被转换为输出行类型的各列。 - 同样,如果输出列是数组类型,而JSON值是JSON数组,则通过这些规则的递归应用程序将JSON数组的元素转换为输出数组的元素。 + 同样,如果输出列是数组类型,而 JSON 值是 JSON 数组,则会通过递归应用这些规则,把 JSON 数组的元素转换为输出数组的元素。 - 否则,如果JSON值是字符串,则将字符串的内容提供给输入转换函数,用以确定列的数据类型。 + 否则,如果 JSON 值是字符串,则会把该字符串的内容送入该列数据类型的输入转换函数。 - 否则,JSON值的普通文本表示将被提供给输入转换函数,以确定列的数据类型。 + 否则,JSON 值的普通文本表示会被送入该列数据类型的输入转换函数。 - 虽然下面的示例使用一个常量JSON值,典型的用法是在查询的FROM子句中从另一个表侧面地引用jsonjsonb列。 - 在FROM子句中编写json_populate_record是一种很好的实践,因为提取的所有列都可以使用,而不需要重复的函数调用。 + 虽然下面的示例使用的是常量 JSON 值,但典型用法是在查询的FROM子句中,以横向方式引用另一个表中的jsonjsonb列。 + 把json_populate_record写在FROM子句中是一种良好实践,因为这样抽取出的所有列都可以直接使用,而不需要重复调用函数。 create type subrowtype as (d int, e text); @@ -14633,8 +13831,7 @@ table2-mapping setof anyelement - 将对象的顶级 JSON 数组展开为一组具有 base 参数复合类型的行。 - 对于json[b]_populate_record,将如上所述处理JSON数组的每个元素。 + 将由对象组成的顶级 JSON 数组展开为一组行,其复合类型与base参数相同。JSON 数组中的每个元素都按照上文对json[b]_populate_record的说明进行处理。 create type twoints as (a int, b int); @@ -14703,8 +13900,8 @@ table2-mapping 将顶级JSON对象数组展开为一组由AS子句定义的复合类型的行。 - (与所有返回record的函数一样,调用查询必须使用AS子句显式定义记录的结构。) - 对于json[b]_populate_record,将如上所述处理JSON数组的每个元素。 + (与所有返回record的函数一样,调用查询必须使用AS子句显式定义记录的结构。) + JSON 数组中的每个元素都按照上文对json[b]_populate_record的说明进行处理。 select * from json_to_recordset('[{"a":1,"b":"foo"}, {"a":"2","c":"bar"}]') as x(a int, b text) @@ -14730,7 +13927,7 @@ table2-mapping 返回target,将path指定的项替换为new_value, 如果create_if_missing为真(此为默认值)并且path指定的项不存在,则添加new_value。 路径中的所有前面步骤都必须存在,否则将不加改变地返回target。 - 与面向路径操作符一样,负整数出现在JSON数组末尾的path计数中。 + 与面向路径的操作符一样,path中的负整数从 JSON 数组末尾计数。 如果最后一个路径步骤是超出范围的数组索引,并且create_if_missing为真,那么如果索引为负,新值将添加到数组的开头,如果索引为正,则添加到数组的结尾。 @@ -14777,8 +13974,8 @@ table2-mapping 如果path指派的项是一个数组元素,如果 insert_after为假(此为默认值),则new_value将被插入到该项之前,如果 insert_after为真则在该项之后。 如果由path指派的项是一个对象字段,则只在对象不包含该键时才插入 new_value。 路径中的所有前面步骤都必须存在,否则将不加改变地返回target。 - 与面向路径操作符一样,负整数出现在JSON数组末尾的 path计数中。 - 如果最后一个路径步骤是超出范围的数组下标,那么当下标为负时,新值会被添加到数组开头;当下标为正时,新值会被添加到数组结尾。 + 与面向路径的操作符一样,path中的负整数从 JSON 数组末尾计数。 + 如果最后一个路径步骤是超出范围的数组下标,那么当下标为负时,新值会被添加到数组开头;当下标为正时,新值会被添加到数组末尾。 jsonb_insert('{"a": [0,1,2]}', '{a, 1}', '"new_value"') @@ -14795,26 +13992,20 @@ table2-mapping json_strip_nulls - json_strip_nulls ( target json ,strip_in_arrays boolean ) + json_strip_nulls ( json ) json jsonb_strip_nulls - jsonb_strip_nulls ( target jsonb ,strip_in_arrays boolean ) + jsonb_strip_nulls ( jsonb ) jsonb - - 递归地删除给定 JSON 值中所有值为 null 的对象字段。如果 strip_in_arrays 为 true(默认值为 false),那么数组中的 null 元素也会被删除;否则不会删除。裸露的 null 值永远不会被删除。 - + 递归删除给定 JSON 值中所有值为 null 的对象字段。不是对象字段的 null 值保持不变。 json_strip_nulls('[{"f1":1, "f2":null}, 2, null, 3]') [{"f1":1},2,null,3] - - - jsonb_strip_nulls('[1,2,null,3,4]', true) - [1,2,3,4] @@ -14827,7 +14018,7 @@ table2-mapping boolean - 检查JSON路径是否返回指定JSON值的任何项。如果指定了vars参数,则它必须是一个JSON对象,并且它的字段提供要替换到jsonpath表达式中的名称值。 + 检查JSON路径是否返回指定JSON值的任何项。如果指定了vars参数,则它必须是一个JSON对象,并且它的字段提供要替换到jsonpath表达式中的具名值。 如果指定了silent参数并为true,函数会抑制与@?@@操作符相同的错误。 @@ -14969,7 +14160,7 @@ table2-mapping text - 将给定的JSON值转换为精美打印的,缩进的文本。 + 将给定的 JSON 值转换为经过美化并带有缩进的文本。 jsonb_pretty('[{"f1":1,"f2":null}, 2]') @@ -15002,7 +14193,7 @@ table2-mapping text - 以文本字符串形式返回顶级JSON值的类型。可能的类型有object, array,string, number,boolean, 和 null。 + 以文本字符串形式返回顶级JSON值的类型。可能的类型有objectarraystringnumberbooleannull。 (null 的结果不应与 SQL NULL 混淆;参见示例。) @@ -15048,13 +14239,11 @@ table2-mapping - 要引用正在查询的JSON值(context item项),在路径表达式中使用$变量。 - 它后面可以跟着一个或多个accessor operators,这些操作符在JSON结构中逐级向下检索上下文项的子项。 - 后面的每个操作符处理前一个求值步骤的结果。 - + 要引用正在查询的 JSON 值(上下文项),请在路径表达式中使用$变量。它后面可以跟一个或多个访问操作符,沿 JSON 结构逐层向下获取上下文项的子项。每个后续操作符都处理上一步求值的结果。 + - 例如,假设你有一些你想要解析的来自GPS跟踪器的JSON数据,例如: + 例如,假设你有一些你想要解析的来自GPS跟踪器的JSON数据,例如: { "track": { @@ -15075,50 +14264,38 @@ table2-mapping - - 为了检索可用的轨迹段,你需要使用.key访问操作符来向下浏览周边的JSON对象: - + 要获取可用的轨迹片段,需要使用.key访问操作符,逐层访问外围的 JSON 对象: $.track.segments - 要检索数组的内容,通常使用[*]操作符。例如,下面的路径将返回所有可用轨道段的位置坐标: + 要检索数组的内容,通常使用[*]操作符。例如,下面的路径将返回所有可用轨迹段的位置坐标: $.track.segments[*].location - - 要只返回第一个段的坐标,可以在[]访问操作符中指定相应的下标。重新调用相对于0的JSON数组索引: - + 要仅返回第一个片段的坐标,可以在[]访问操作符中指定相应下标。注意,JSON 数组下标从 0 开始: $.track.segments[0].location - - 每个路径求值步骤的结果可以由中列出的一个或多个jsonpath操作符和方法来处理。 - 每个方法名之前必须有一个点。例如,你可以得到一个数组的大小: - + 每一步路径求值的结果都可以使用一个或多个jsonpath操作符和方法处理,它们列于。每个方法名之前都必须有一个点。例如,可以获取数组的大小: $.track.segments.size() - - 在路径表达式中使用jsonpath操作符和方法的更多示例见下面。 +有关在路径表达式中使用jsonpath操作符和方法的更多示例,见下文 - - 在定义路径时,还可以使用一个或多个与SQL中的WHERE子句类似的filter expressions。 - 过滤器表达式以问号开头,并在圆括号中提供条件: - - + 定义路径时,还可以使用一个或多个过滤表达式,其作用类似于 SQL 中的WHERE子句。过滤表达式以问号开头,并在圆括号中提供条件: ? (condition) - 过滤表达式必须在它们应该应用的路径求值步骤之后写入。该步骤的结果将被筛选,以只包括满足所提供条件的那些项。 + 过滤表达式必须在它们应该应用的路径求值步骤之后指定。该步骤的结果会经过过滤,只保留满足给定条件的项。 SQL/JSON定义了三值逻辑,因此条件可以是 true, false,或 unknownunknown值发挥与SQL NULL相同的角色,可以使用is unknown谓词进行测试。 - 进一步的路径求值步骤只使用筛选器表达式返回true的那些项。 + 进一步的路径求值步骤只使用过滤表达式返回true的那些项。 @@ -15126,153 +14303,104 @@ $.track.segments.size() 在一个过滤表达式中,@变量表示被过滤的值(也就是说,前面路径步骤的一个结果)。你可以在 @后面写访问操作符来检索组件项。 - - 例如,假设你想要检索所有高于130的心率值。你可以使用下面的表达式来实现这一点: - + 例如,假设你想检索所有高于 130 的心率值。可以用下面的表达式实现: $.track.segments[*].HR ? (@ > 130) - - 为了获得具有这些值的片段的开始时间,必须在返回开始时间之前过滤掉不相关的片段,所以过滤表达式应用于上一步,条件中使用的路径不同: - + 为了获得具有这些值的轨迹段的开始时间,必须先过滤掉不相关的轨迹段,再返回开始时间。因此,过滤表达式应用于上一步,条件中使用的路径也不同: $.track.segments[*] ? (@.HR > 130)."start time" - - 如果需要,可以按顺序使用几个过滤器表达式。例如,下面的表达式选择所有包含有相关坐标和高心率值的位置的段的开始时间: - + 如有需要,可以依次使用多个过滤表达式。例如,下面的表达式选择位置坐标符合要求且心率较高的所有轨迹段的开始时间: $.track.segments[*] ? (@.location[1] < 13.4) ? (@.HR > 130)."start time" - - 也允许在不同嵌套层级中使用过滤器表达式。下面的示例首先根据位置筛选所有的片段,然后返回这些片段的高心率值,如果适用的话: - + 也可以在不同嵌套层级使用过滤表达式。下面的示例先按位置筛选所有轨迹段,再返回这些轨迹段中的高心率值(如果存在): $.track.segments[*] ? (@.location[1] < 13.4).HR ? (@ > 130) - - 你也可以在彼此之间嵌套过滤器表达式: - + 还可以将过滤表达式相互嵌套: $.track ? (exists(@.segments[*] ? (@.HR > 130))).segments.size() - - 如果包含任何具有高心率值的片段,则该表达式返回曲目的大小,否则返回空序列。 - +如果轨迹包含任何具有高心率值的轨迹段,该表达式返回轨迹的大小,否则返回空序列。 - - 与 SQL 标准的偏差 - - - PostgreSQL 对 SQL/JSON 路径语言的实现与 SQL/JSON 标准有以下偏差。 - + PostgreSQL 对 SQL/JSON 路径语言的实现与 SQL/JSON 标准有以下偏差: - - 布尔谓词检查表达式 + + - 作为对 SQL 标准的扩展,PostgreSQL 的路径表达式可以是布尔谓词,而 SQL 标准只允许在过滤器内部使用谓词。SQL 标准路径表达式返回被查询 JSON 值中的相关元素,而谓词检查表达式返回该谓词的单个三值 jsonb 结果:truefalsenull。例如,下面是一个符合 SQL 标准的过滤表达式: - -=> select jsonb_path_query(:'json', '$.track.segments ?(@[*].HR > 130)'); - jsonb_path_query ------------------------------------------------------------&zwsp;---------------------- - {"HR": 135, "location": [47.706, 13.2635], "start time": "2018-10-14 10:39:21"} - - 类似的谓词检查表达式则会直接返回 true,表示存在匹配项: - -=> select jsonb_path_query(:'json', '$.track.segments[*].HR > 130'); - jsonb_path_query ------------------- - true - + 路径表达式可以是布尔谓词,尽管 SQL/JSON 标准只允许在过滤器中使用谓词。 + 这对于实现 @@ 操作符是必要的。例如, + 下面的 jsonpath 表达式在 PostgreSQL 中是有效的: + +$.track.segments[*].HR < 70 + + - - - 谓词检查表达式是 @@ 操作符(以及 jsonb_path_match 函数)所必需的,不应与 @? 操作符(或 jsonb_path_exists 函数)一起使用。 - - - - - - 正则表达式解释 + 对于 like_regex 过滤器中使用的正则表达式模式,其解释方式存在一些细微差异,详见 - - + + - + 严格模式与宽松模式 + 当查询JSON数据时,路径表达式可能与实际的JSON数据结构不匹配。 - 试图访问不存在的对象成员或数组元素会导致结构错误。SQL/JSON路径表达式有两种处理结构错误的模式: + 试图访问不存在的对象成员或数组元素会导致结构错误。SQL/JSON路径表达式有两种处理结构错误的模式: - 不严格的(lax)(默认)—路径引擎隐式地将查询的数据适配到指定的路径。任何剩余的结构错误都将被抑制并转换为空SQL/JSON序列。 + 宽松模式(lax,默认)—路径引擎隐式地将查询的数据适配到指定的路径。任何剩余的结构错误都将被抑制并转换为空SQL/JSON序列。 - - 严格的(strict) —如果发生了结构错误,则会引发错误。 - + 严格模式(strict)— 如果发生结构错误,就会引发错误。 - 如果JSON数据不符合期望的模式,不严格的(lax)模式有助于匹配JSON文档结构和路径表达式。 - 如果操作不匹配特定操作的要求,可以自动将其包装为SQL/JSON数组,也可以在执行该操作之前将其元素转换为SQL/JSON序列来解包装。 - 此外,比较操作符会自动以lax模式打开它们的操作数,因此你可以开包即用的就能比较SQL/JSON数组。 - 大小为1的数组被认为等于它的唯一元素。只有在以下情况下才不会自动展开: + 如果 JSON 数据不符合预期模式,宽松模式有助于使 JSON 文档结构与路径表达式相匹配。如果操作数不满足某个操作的要求,可以在执行该操作之前自动将其包装为 SQL/JSON 数组,或通过将其元素转换为 SQL/JSON 序列来解包。此外,在宽松模式下,比较操作符会自动解包其操作数,因此可以直接比较 SQL/JSON 数组。大小为 1 的数组被视为等于其唯一元素。以下情况不会自动解包: - 路径表达式包含type()size()方法,它们分别返回数组中的元素类型和数量。 + 路径表达式包含type()size()方法,它们分别返回类型和数组中的元素数量。 - 查询的JSON数据包含嵌套的数组。在本例中,只有最外层的数组被打开,而所有内部数组保持不变。 - 因此,隐式展开在每个路径求值步骤中只能向下进行一级。 + 查询的JSON数据包含嵌套的数组。在本例中,只有最外层的数组被解包,而所有内部数组保持不变。 + 因此,隐式解包在每个路径求值步骤中只能向下进行一级。 - - 例如,当查询上面列出的GPS数据时,当使用不严格的(lax)模式时,你可以从它存储了一组片段的事实中抽象出来: - + 例如,查询上面列出的 GPS 数据时,使用宽松模式可以不必关心它将轨迹段存储为数组这一细节: lax $.track.segments.location - - 在严格的(strict)模式中,指定的路径必须与查询的JSON文档的结构完全匹配才能返回SQL/JSON项,因此使用该路径表达式会导致错误。 - 要得到与不严格的(lax)模式相同的结果,你必须显式地打开segments数组: - + 在严格模式下,指定路径必须与所查询 JSON 文档的结构完全匹配,才能返回 SQL/JSON 项,因此使用此路径表达式会导致错误。要得到与宽松模式相同的结果,必须显式解包segments数组: strict $.track.segments[*].location - - .**访问器在使用lax模式时可能导致令人惊讶的结果。 - 例如,下面的查询选择每个HR值两次: - + .**访问器在宽松模式下可能产生出人意料的结果。例如,下面的查询会选出每个HR值两次: lax $.**.HR - - 发生这个,是因为.**访问器会全部选择segments数组和它的每个元素。 - 而当使用lax模式时,.HR访问器会自动打开数组。 - 为了避免意外的结果,我们建议仅在严格模式下使用.**访问器。 - 下面的查询选择每个HR值仅一次: - +这是因为.**访问器既选择segments数组,又选择其每个元素,而.HR访问器在宽松模式下会自动解包数组。为避免意外结果,建议将.**访问器仅用于严格模式。下面的查询只选出每个HR值一次: strict $.**.HR @@ -15284,7 +14412,7 @@ strict $.**.HR SQL/JSON 路径操作符和方法 - 显示了jsonpath中可用的操作符和方法。 + 显示了jsonpath中可用的操作符和方法。 请注意,虽然一元操作符和方法可以应用于由前一个路径步骤产生的多个值,二元操作符(加法等)只能应用于单个值。 @@ -15357,7 +14485,7 @@ strict $.**.HR number - 否定;与减法不同,它可以迭代多个值 + 取负;与减法不同,可以遍历多个值。 jsonb_path_query_array('{"x": [2,3,4]}', '- $.x') @@ -15399,7 +14527,7 @@ strict $.**.HR number - 模数 (余数) + 取模(余数) jsonb_path_query('[32]', '$[0] % 10') @@ -15495,7 +14623,7 @@ strict $.**.HR string . datetime() datetime_type - (see note) + (见注) 从字符串转换过来的日期/时间值 @@ -15510,7 +14638,7 @@ strict $.**.HR string . datetime(template) datetime_type - (see note) + (见注) 使用指定的to_timestamp模板从字符串转换过来的日期/时间值 @@ -15547,7 +14675,7 @@ strict $.**.HR datetime()方法依次尝试将其输入字符串与date, timetz, time,timestamptz, 和 timestamp的ISO格式进行匹配。 - 它在第一个匹配格式时停止,并发出相应的数据类型。 + 它在第一个匹配格式时停止,并返回相应数据类型的值。 @@ -15555,26 +14683,26 @@ strict $.**.HR - datetime()datetime(template)方法使用与to_timestamp SQL函数相同的解析规则(see ),但有三个例外。 + datetime()datetime(template)方法使用与to_timestamp SQL函数相同的解析规则(参见),但有三个例外。 首先,这些方法不允许不匹配的模板模式。 - 其次,模板字符串中只允许以下分隔符:减号、句点、solidus(斜杠)、逗号、撇号、分号、冒号和空格。 + 其次,模板字符串中只允许以下分隔符:减号、句点、斜杠、逗号、撇号、分号、冒号和空格。 第三,模板字符串中的分隔符必须与输入字符串完全匹配。 - 如果需要比较不同的日期/时间类型,则应用隐式转换。 + 如果需要比较不同的日期/时间类型,则应用隐式类型转换。 date值可以转换为timestamptimestamptz, timestamp可以转换为timestamptz, time可以转换为timetz。 但是,除了第一个转换外,其他所有转换都依赖于当前设置,因此只能在时区感知的jsonpath函数中执行。 - 显示了适用的过滤器表达式元素。 + 显示了可用的过滤表达式元素。
- <type>jsonpath</type> 过滤器表达式元素 + <type>jsonpath</type> 过滤表达式元素 @@ -15723,7 +14851,7 @@ strict $.**.HR value - JSON常数null(注意,与SQL不同,与null比较可以正常工作) + JSON 常量null(注意,与SQL不同,与null比较可以正常工作) jsonb_path_query('[{"name": "Mary", "job": null}, {"name": "Michael", "job": "driver"}]', '$[*] ? (@.job == null) .name') @@ -15793,7 +14921,7 @@ strict $.**.HR boolean - 测试第一个操作数是否与第二个操作数给出的正则表达式匹配,可选使用由一串flag字符描述的修改(参见)。 + 测试第一个操作数是否与第二个操作数给出的正则表达式匹配;可以用一串flag标志字符调整匹配行为(参见)。 jsonb_path_query_array('["abc", "abd", "aBdC", "abdacb", "babc"]', '$[*] ? (@ like_regex "^ab.*c")') @@ -15830,794 +14958,56 @@ strict $.**.HR jsonb_path_query('{"x": [1, 2], "y": [2, 4]}', 'strict $.* ? (exists (@ ? (@[*] > 2)))') - [2, 4] - - - jsonb_path_query_array('{"value": 41}', 'strict $ ? (exists (@.name)) .name') - [] - - - - -
- - - - - - SQL/JSON 正则表达式 - - - LIKE_REGEX - in SQL/JSON - - - - SQL/JSON路径表达式允许通过like_regex过滤器将文本匹配为正则表达式。 - 例如,下面的SQL/JSON路径查询将不区分大小写地匹配以英语元音开头的数组中的所有字符串: - -$[*] ? (@ like_regex "^[aeiou]" flag "i") - - - - - 可选的flag字符串可以包括一个或多个字符i用于不区分大小写的匹配,m允许^$在换行时匹配,s允许.匹配换行符,q引用整个模式(将行为简化为一个简单的子字符串匹配)。 - - - - SQL/JSON标准借用了来自LIKE_REGEX操作符的正则表达式定义,其使用了XQuery标准。 - PostgreSQL目前不支持LIKE_REGEX操作符。因此,like_regex过滤器是使用中描述的POSIX正则表达式引擎来实现的。 - 这导致了与标准SQL/JSON行为的各种细微差异,这在中进行了分类。 - 但是请注意,这里描述的标志字母不兼容并不适用于SQL/JSON,因为它将XQuery标志字母翻译为符合POSIX引擎的预期。 - - - - 请记住,like_regex的模式参数是一个JSON路径字符串文字,根据给出的规则编写。 - 这特别意味着在正则表达式中要使用的任何反斜杠都必须加倍。例如,匹配只包含数字的根文档的字符串值: - -$.* ? (@ like_regex "^\\d+$") - - - - - - - SQL/JSON 查询函数 - - 中描述的 SQL/JSON 函数 JSON_EXISTS()、 - JSON_QUERY()JSON_VALUE() - 可用于查询 JSON 文档。每个这样的函数都会将 - path_expression(一个 SQL/JSON 路径查询)应用到 - context_item(该文档)上。关于 - path_expression 可以包含哪些内容的更多细节,请参见 - 。 - path_expression 还可以引用变量, - 这些变量的值通过各函数所支持的 PASSING 子句,以各自的名称指定。 - context_item 可以是一个 jsonb 值, - 也可以是一个能够成功强制转换为 jsonb 的字符串。 - - - - SQL/JSON 查询函数 - - - - - 函数签名 - - - 描述 - - - 示例 - - - - - - - json_exists - -JSON_EXISTS ( -context_item, path_expression - PASSING { value AS varname } , ... -{ TRUE | FALSE | UNKNOWN | ERROR } ON ERROR ) boolean - - - - - - 如果将 SQL/JSON path_expression - 应用于 context_item 后产生了任何项, - 则返回 true,否则返回 false。 - - - - - ON ERROR 子句指定在计算 - path_expression 期间发生错误时的行为。 - 指定 ERROR 将导致抛出带有相应消息的错误。 - 其他选项包括返回 booleanFALSE 或 - TRUE,或者返回值 UNKNOWN, - 它实际上是一个 SQL NULL。在未指定 ON ERROR - 子句时,默认返回 boolean 值 - FALSE。 - - - - - 示例: - - - JSON_EXISTS(jsonb '{"key1": [1,2,3]}', 'strict $.key1[*] ? (@ > $x)' PASSING 2 AS x) - t - - - JSON_EXISTS(jsonb '{"a": [1,2,3]}', 'lax $.a[5]' ERROR ON ERROR) - f - - - JSON_EXISTS(jsonb '{"a": [1,2,3]}', 'strict $.a[5]' ERROR ON ERROR) - - -ERROR: jsonpath array subscript is out of bounds - - - - - - json_query - -JSON_QUERY ( -context_item, path_expression - PASSING { value AS varname } , ... - RETURNING data_type FORMAT JSON ENCODING UTF8 - { WITHOUT | WITH { CONDITIONAL | UNCONDITIONAL } } ARRAY WRAPPER - { KEEP | OMIT } QUOTES ON SCALAR STRING - { ERROR | NULL | EMPTY { ARRAY | OBJECT } | DEFAULT expression } ON EMPTY - { ERROR | NULL | EMPTY { ARRAY | OBJECT } | DEFAULT expression } ON ERROR ) jsonb - - - - - - 返回将 SQL/JSON - path_expression 应用于 - context_item 的结果。 - - - - - 默认情况下,结果以 jsonb 类型的值返回, - 不过也可以使用 RETURNING 子句将其返回为 - 其他能够成功强制转换到的类型。 - - - - - 如果路径表达式可能返回多个值,可能有必要使用 - WITH WRAPPER 子句将这些值包装起来, - 使其成为一个合法的 JSON 字符串,因为默认行为是不对它们进行包装, - 就像指定了 WITHOUT WRAPPER 一样。 - WITH WRAPPER 子句默认被视为 - WITH UNCONDITIONAL WRAPPER,这意味着即使只有一个结果值也会被包装起来。 - 如果只想在存在多个值时应用包装,请指定 - WITH CONDITIONAL WRAPPER。 - 如果指定了 WITHOUT WRAPPER, - 则结果中出现多个值会被视为错误。 - - - - - 如果结果是一个标量字符串,则默认返回值会被双引号包围, - 从而使其成为一个合法的 JSON 值。指定 KEEP QUOTES - 可以将这一行为显式化。反过来,也可以通过指定 - OMIT QUOTES 来省略引号。 - 为了保证结果是一个合法的 JSON 值, - 当同时指定了 WITH WRAPPER 时, - 不能再指定 OMIT QUOTES。 - - - - - ON EMPTY 子句指定在计算 - path_expression 得到空集时的行为。 - ON ERROR 子句指定以下情况下的行为: - 计算 path_expression 时发生错误、 - 将结果值强制转换为 RETURNING 类型时发生错误, - 或者当 path_expression 的计算返回空集时, - 在计算 ON EMPTY 表达式时发生错误。 - - - - - 对于 ON EMPTYON ERROR, - 指定 ERROR 都会导致抛出带有相应消息的错误。 - 其他选项包括返回 SQL NULL、空数组 - (EMPTY ARRAY)、 - 空对象(EMPTY OBJECT),或用户指定的表达式 - (DEFAULT expression), - 该表达式可以被强制转换为 jsonb 或 RETURNING 中指定的类型。 - 在未指定 ON EMPTYON ERROR 时, - 默认返回 SQL NULL 值。 - - - - - 示例: - - - JSON_QUERY(jsonb '[1,[2,3],null]', 'lax $[*][$off]' PASSING 1 AS off WITH CONDITIONAL WRAPPER) - 3 - - - JSON_QUERY(jsonb '{"a": "[1, 2]"}', 'lax $.a' OMIT QUOTES) - [1, 2] - - - JSON_QUERY(jsonb '{"a": "[1, 2]"}', 'lax $.a' RETURNING int[] OMIT QUOTES ERROR ON ERROR) - - -ERROR: malformed array literal: "[1, 2]" -DETAIL: Missing "]" after array dimensions. - - - - - - - json_value - -JSON_VALUE ( -context_item, path_expression - PASSING { value AS varname } , ... - RETURNING data_type - { ERROR | NULL | DEFAULT expression } ON EMPTY - { ERROR | NULL | DEFAULT expression } ON ERROR ) text - - - - - - 返回将 SQL/JSON - path_expression 应用于 - context_item 的结果。 - - - - - 只有在预期提取出的值是单个 SQL/JSON 标量项时, - 才应使用 JSON_VALUE();如果得到多个值, - 会被视为错误。如果你预计提取出的值可能是对象或数组, - 应改用 JSON_QUERY 函数。 - - - - - 默认情况下,结果必须是单个标量值,并以 text 类型的值返回, - 不过可以使用 RETURNING 子句将其返回为 - 其他能够成功强制转换到的类型。 - - - - - ON ERRORON EMPTY - 子句的语义与 JSON_QUERY 描述中的语义类似, - 只是用来代替抛出错误而返回的值集合不同。 - - - - - 请注意,JSON_VALUE 返回的标量字符串 - 总是去掉引号,这等价于在 JSON_QUERY 中指定 - OMIT QUOTES。 - - - - - 示例: - - - JSON_VALUE(jsonb '"123.45"', '$' RETURNING float) - 123.45 - - - JSON_VALUE(jsonb '"03:04 2015-02-01"', '$.datetime("HH24:MI YYYY-MM-DD")' RETURNING date) - 2015-02-01 - - - JSON_VALUE(jsonb '[1,2]', 'strict $[$off]' PASSING 1 as off) - 2 - - - JSON_VALUE(jsonb '[1,2]', 'strict $[*]' DEFAULT 9 ON ERROR) - 9 - - - - - -
- - - 如果 context_item 表达式的类型还不是 - jsonb,则会通过隐式强制转换将其转换为 jsonb。 - 但请注意,在该转换期间发生的任何解析错误都会无条件抛出, - 也就是说,不会按照(显式指定或隐含的)ON ERROR - 子句来处理。 - - - - - 如果 path_expression 返回 JSON - null,则 JSON_VALUE() 返回 SQL NULL, - 而 JSON_QUERY() 则按原样返回 JSON null。 - - -
- - - JSON_TABLE - - json_table - - - - JSON_TABLE 是一个 SQL/JSON 函数, - 用于查询 JSON 数据, - 并将结果表示为关系视图,从而可以像访问常规 SQL 表一样访问它。 - 你可以在 SELECTUPDATE 或 - DELETEFROM 子句中使用 - JSON_TABLE,也可以在 MERGE - 语句中将其用作数据源。 - - - - JSON_TABLE 以 JSON 数据作为输入,使用 JSON 路径表达式从给定数据中提取一部分, - 将其用作所构造视图的行模式。行模式给出的每个 SQL/JSON - 值都作为所构造视图中单独一行的来源。 - - - - 为了将行模式拆分为列,JSON_TABLE - 提供了定义所创建视图结构的 COLUMNS 子句。 - 对于每一列,都可以指定一个单独的 JSON 路径表达式, - 相对于行模式进行计算,以得到一个 SQL/JSON 值, - 该值将成为给定输出行中指定列的值。 - - - - 存储在行模式嵌套层级中的 JSON 数据可以通过 - NESTED PATH 子句提取。每个 - NESTED PATH 子句都可以利用行模式某个嵌套层级中的数据生成一个或多个 - 列。这些列可以通过一个看起来与顶层 COLUMNS 子句类似的 - COLUMNS 子句来指定。由 - NESTED COLUMNS 构造的行称为子行,它们会与父 - COLUMNS 子句中指定的列所构造的行联接, - 从而得到最终视图中的行。子列自身也可以包含 - NESTED PATH 说明,因此可以提取位于任意嵌套层级中的数据。 - 在同一层级上由多个 NESTED PATH 生成的列彼此视为 - 兄弟,它们在与父行联接后的行通过 - UNION 进行组合。 - - - - 由 JSON_TABLE 生成的行会与生成它们的行进行横向联接, - 因此你无需显式地将构造出来的视图与保存 JSON - 数据的原始表进行联接。 - - - - 语法如下: - - - -JSON_TABLE ( - context_item, path_expression AS json_path_name PASSING { value AS varname } , ... - COLUMNS ( json_table_column , ... ) - { ERROR | EMPTY ARRAY} ON ERROR -) - - -其中 json_table_column 为: - - name FOR ORDINALITY - | name type - FORMAT JSON ENCODING UTF8 - PATH path_expression - { WITHOUT | WITH { CONDITIONAL | UNCONDITIONAL } } ARRAY WRAPPER - { KEEP | OMIT } QUOTES ON SCALAR STRING - { ERROR | NULL | EMPTY { ARRAY | OBJECT } | DEFAULT expression } ON EMPTY - { ERROR | NULL | EMPTY { ARRAY | OBJECT } | DEFAULT expression } ON ERROR - | name type EXISTS PATH path_expression - { ERROR | TRUE | FALSE | UNKNOWN } ON ERROR - | NESTED PATH path_expression AS json_path_name COLUMNS ( json_table_column , ... ) - - - - 下面更详细地说明每个语法元素。 - - - - - - context_item, path_expression AS json_path_name PASSING { value AS varname } , ... - - - - context_item 指定要查询的输入文档, - path_expression 是定义查询的 SQL/JSON - 路径表达式,而 json_path_name - 是 path_expression 的可选名称。 - 可选的 PASSING 子句为 - path_expression 中提到的变量提供数据值。 - 使用上述元素对输入数据求值得到的结果称为行模式, - 它被用作构造视图中各行取值的来源。 - - - - - - - COLUMNS ( json_table_column , ... ) - - + [2, 4] +
+ + jsonb_path_query_array('{"value": 41}', 'strict $ ? (exists (@.name)) .name') + [] +
+
+ + + - - 定义构造视图结构的 COLUMNS 子句。在该子句中, - 你可以指定每一列使用将 JSON 路径表达式应用于行模式所获得的 SQL/JSON 值来填充。 - json_table_column 有以下几种变体: - + - - - - name FOR ORDINALITY - - - - 增加一个序号列,提供从 1 开始的连续行编号。每个 - NESTED PATH(见下文)都会为其中任何嵌套的序号列维护自己的计数器。 - - - - - - - name type - FORMAT JSON ENCODING UTF8 - PATH path_expression - - - - 将通过把 path_expression 应用于行模式而得到的 SQL/JSON 值, - 在强制转换为指定的 type 之后, - 插入到视图的输出行中。 - - - 指定 FORMAT JSON 可以显式表明你期望该值是一个合法的 - json 对象。只有当 type 是 - bpcharbyteacharacter varying、 - namejsonjsonbtext - 之一,或者是这些类型上的域时,指定 FORMAT JSON 才有意义。 - - - 你还可以选择指定 WRAPPER 和 - QUOTES 子句来格式化输出。请注意, - 如果也指定了 FORMAT JSON,那么指定 - OMIT QUOTES 会覆盖它,因为不带引号的字面量 - 不构成合法的 json 值。 - - - 你还可以选择使用 ON EMPTY 和 - ON ERROR 子句来指定: - 当 JSON 路径求值结果为空时,以及当 JSON 路径求值期间发生错误, - 或将 SQL/JSON 值强制转换为指定类型时发生错误时,是抛出错误还是返回指定的值。 - 这两者的默认行为都是返回 NULL 值。 - - - - 该子句在内部会被转换为 JSON_VALUE 或 - JSON_QUERY,并具有相同的语义。 - 如果指定的类型不是标量类型,或者出现了 - FORMAT JSONWRAPPER 或 - QUOTES 子句中的任意一个,则会转换为后者。 - - - - + - - - name type - EXISTS PATH path_expression - - - - 将通过把 path_expression 应用于行模式而得到的布尔值, - 在强制转换为指定的 type 之后, - 插入到视图的输出行中。 - - - 该值对应于将 PATH 表达式应用到行模式后是否产生任何值。 - - - 指定的 type 应当具有从 - boolean 类型进行强制转换的能力。 - - - 你还可以选择使用 ON ERROR 来指定: - 当 JSON 路径求值期间发生错误,或者将 SQL/JSON 值强制转换为指定类型时发生错误时, - 是抛出错误还是返回指定的值。默认返回布尔值 - FALSE。 - - - - 该子句在内部会被转换为 JSON_EXISTS, - 并具有相同的语义。 - - - - + SQL/JSON 正则表达式 - - - NESTED PATH path_expression AS json_path_name - COLUMNS ( json_table_column , ... ) - - + + LIKE_REGEX + 用于 SQL/JSON + - - 从行模式的嵌套层级中提取 SQL/JSON 值, - 按照 COLUMNS 子子句的定义生成一个或多个列, - 并将提取出的 SQL/JSON 值插入这些列中。 - COLUMNS 子子句中的 json_table_column - 表达式使用与父级 COLUMNS 子句相同的语法。 + SQL/JSON 路径表达式允许使用like_regex过滤器,将文本与正则表达式进行匹配。例如,以下 SQL/JSON 路径查询会以不区分大小写的方式,匹配数组中所有以英语元音字母开头的字符串: +$[*] ? (@ like_regex "^[aeiou]" flag "i") + - NESTED PATH 的语法是递归的, - 因此你可以通过相互嵌套地指定多个 - NESTED PATH 子子句来向下进入多个嵌套层级。 - 这使得你可以在一次函数调用中展开 JSON 对象和数组的层次结构, - 而不必在 SQL 语句中串联多个 - JSON_TABLE 表达式。 + 可选的flag字符串可以包括一个或多个字符i用于不区分大小写的匹配,m允许^$在换行时匹配,s允许.匹配换行符,q将整个模式按字面量处理(将行为简化为一个简单的子字符串匹配)。 - - - - - - - 对于上面描述的每一种 json_table_column 变体, - 如果省略了 PATH 子句,则使用路径表达式 - $.name,其中 - name 是提供的列名。 - - - - - - - - - AS json_path_name - - - 可选的 json_path_name 用作所提供的 - path_expression 的标识符。 - 该名称必须唯一,并且不得与列名相同。 + SQL/JSON标准借用了来自LIKE_REGEX操作符的正则表达式定义,其使用了XQuery标准。 + PostgreSQL目前不支持LIKE_REGEX操作符。因此,like_regex过滤器是使用中描述的POSIX正则表达式引擎来实现的。 + 这导致了与标准SQL/JSON行为的各种细微差异,这些差异列在中。 + 但是请注意,这里描述的标志字母不兼容并不适用于SQL/JSON,因为 SQL/JSON 会将 XQuery 标志字母转换为 POSIX 引擎所预期的形式。 - - - - - - { ERROR | EMPTY } ON ERROR - - - 可选的 ON ERROR 可用于指定在计算顶层 - path_expression 时如何处理错误。 - 如果你希望错误被抛出,请使用 ERROR; - 使用 EMPTY 则返回一个空表,也就是一个包含 0 行的表。 - 请注意,该子句不会影响计算列时发生的错误; - 对于列中的错误,其行为取决于对应列上是否指定了 - ON ERROR 子句。 - - - - - - 示例 - - - 在下面的示例中,将使用下表,其中包含 JSON 数据: - - -CREATE TABLE my_films ( js jsonb ); - -INSERT INTO my_films VALUES ( -'{ "favorites" : [ - { "kind" : "comedy", "films" : [ - { "title" : "Bananas", - "director" : "Woody Allen"}, - { "title" : "The Dinner Game", - "director" : "Francis Veber" } ] }, - { "kind" : "horror", "films" : [ - { "title" : "Psycho", - "director" : "Alfred Hitchcock" } ] }, - { "kind" : "thriller", "films" : [ - { "title" : "Vertigo", - "director" : "Alfred Hitchcock" } ] }, - { "kind" : "drama", "films" : [ - { "title" : "Yojimbo", - "director" : "Akira Kurosawa" } ] } - ] }'); - - - - - 下面的查询展示了如何使用 JSON_TABLE - 将 my_films 表中的 JSON 对象转换为一个视图, - 其中包含原始 JSON 中的键 kind、 - titledirector 对应的列, - 以及一个序号列: - - -SELECT jt.* FROM - my_films, - JSON_TABLE (js, '$.favorites[*]' COLUMNS ( - id FOR ORDINALITY, - kind text PATH '$.kind', - title text PATH '$.films[*].title' WITH WRAPPER, - director text PATH '$.films[*].director' WITH WRAPPER)) AS jt; - - - - id | kind | title | director -----+----------+--------------------------------+---------------------------------- - 1 | comedy | ["Bananas", "The Dinner Game"] | ["Woody Allen", "Francis Veber"] - 2 | horror | ["Psycho"] | ["Alfred Hitchcock"] - 3 | thriller | ["Vertigo"] | ["Alfred Hitchcock"] - 4 | drama | ["Yojimbo"] | ["Akira Kurosawa"] -(4 rows) - - - - - 下面是在上述查询基础上的修改版本,用来展示顶层 JSON 路径表达式中指定的过滤条件里 - 如何使用 PASSING 参数,以及各个列的不同选项: - - -SELECT jt.* FROM - my_films, - JSON_TABLE (js, '$.favorites[*] ? (@.films[*].director == $filter)' - PASSING 'Alfred Hitchcock' AS filter - COLUMNS ( - id FOR ORDINALITY, - kind text PATH '$.kind', - title text FORMAT JSON PATH '$.films[*].title' OMIT QUOTES, - director text PATH '$.films[*].director' KEEP QUOTES)) AS jt; - - - - id | kind | title | director -----+----------+---------+-------------------- - 1 | horror | Psycho | "Alfred Hitchcock" - 2 | thriller | Vertigo | "Alfred Hitchcock" -(2 rows) - - - - - 下面是在上述查询基础上的修改版本,用来展示如何使用 - NESTED PATH 填充 title 和 director - 列,并说明它们如何与父列 id 和 kind 联接: - - -SELECT jt.* FROM - my_films, - JSON_TABLE ( js, '$.favorites[*] ? (@.films[*].director == $filter)' - PASSING 'Alfred Hitchcock' AS filter - COLUMNS ( - id FOR ORDINALITY, - kind text PATH '$.kind', - NESTED PATH '$.films[*]' COLUMNS ( - title text FORMAT JSON PATH '$.title' OMIT QUOTES, - director text PATH '$.director' KEEP QUOTES))) AS jt; - - - - id | kind | title | director -----+----------+---------+-------------------- - 1 | horror | Psycho | "Alfred Hitchcock" - 2 | thriller | Vertigo | "Alfred Hitchcock" -(2 rows) - - - - - - 下面是同一个查询,但去掉了根路径中的过滤条件: - + 请记住,like_regex的模式参数是一个JSON 路径字符串字面量,根据给出的规则编写。 + 这特别意味着在正则表达式中要使用的任何反斜杠都必须加倍。例如,匹配根文档中仅包含数字的字符串值: -SELECT jt.* FROM - my_films, - JSON_TABLE ( js, '$.favorites[*]' - COLUMNS ( - id FOR ORDINALITY, - kind text PATH '$.kind', - NESTED PATH '$.films[*]' COLUMNS ( - title text FORMAT JSON PATH '$.title' OMIT QUOTES, - director text PATH '$.director' KEEP QUOTES))) AS jt; +$.* ? (@ like_regex "^\\d+$") + + + - - id | kind | title | director -----+----------+-----------------+-------------------- - 1 | comedy | Bananas | "Woody Allen" - 1 | comedy | The Dinner Game | "Francis Veber" - 2 | horror | Psycho | "Alfred Hitchcock" - 3 | thriller | Vertigo | "Alfred Hitchcock" - 4 | drama | Yojimbo | "Akira Kurosawa" -(5 rows) - - - - - - 下面展示了另一个以不同 JSON - 对象作为输入的查询。它展示了 NESTED - 路径 $.movies[*] 和 - $.books[*] 之间通过 UNION 实现的“兄弟联接”, - 以及在 NESTED 层级上使用 - FOR ORDINALITY 列(列 movie_idbook_id - 和 author_id): - - -SELECT * FROM JSON_TABLE ( -'{"favorites": - [{"movies": - [{"name": "One", "director": "John Doe"}, - {"name": "Two", "director": "Don Joe"}], - "books": - [{"name": "Mystery", "authors": [{"name": "Brown Dan"}]}, - {"name": "Wonder", "authors": [{"name": "Jun Murakami"}, {"name":"Craig Doe"}]}] -}]}'::json, '$.favorites[*]' -COLUMNS ( - user_id FOR ORDINALITY, - NESTED '$.movies[*]' - COLUMNS ( - movie_id FOR ORDINALITY, - mname text PATH '$.name', - director text), - NESTED '$.books[*]' - COLUMNS ( - book_id FOR ORDINALITY, - bname text PATH '$.name', - NESTED '$.authors[*]' - COLUMNS ( - author_id FOR ORDINALITY, - author_name text PATH '$.name')))); - - - user_id | movie_id | mname | director | book_id | bname | author_id | author_name ----------+----------+-------+----------+---------+---------+-----------+-------------- - 1 | 1 | One | John Doe | | | | - 1 | 2 | Two | Don Joe | | | | - 1 | | | | 1 | Mystery | 1 | Brown Dan - 1 | | | | 2 | Wonder | 1 | Jun Murakami - 1 | | | | 2 | Wonder | 2 | Craig Doe -(5 rows) - - - @@ -16625,11 +15015,11 @@ COLUMNS ( 序列操作函数 - sequence + 序列 - 本节描述对序列对象进行操作的函数,也称为序列生成器或简称序列。 + 本节描述用于操作序列对象(也称为序列生成器,或简称序列)的函数。 序列对象是使用创建的特殊单行表。 序列对象通常用于为表中的行生成惟一标识符。在中列出的序列函数,提供了简单的、多用户安全方法,用于从序列对象中获取连续的序列值。 @@ -16661,12 +15051,12 @@ COLUMNS ( bigint - 将序列对象推进到下一个值并返回该值。这是自动完成的:即使多个会话并发地执行nextval,每个会话也会安全地接收到不同的序列值。 - 如果序列对象是用默认形参创建的,则连续的nextval调用将返回以1开始的连续值。 + 将序列对象推进到下一个值并返回该值。这个操作是原子的:即使多个会话并发地执行nextval,每个会话也会安全地接收到不同的序列值。 + 如果序列对象是用默认参数创建的,则连续的nextval调用将返回以1开始的连续值。 其他行为可以通过在命令中使用适当的参数获得。 - 这个函数需要USAGEUPDATE权限在序列上。 + 这个函数需要序列上的USAGEUPDATE权限。 @@ -16679,16 +15069,16 @@ COLUMNS ( bigint - 设置序列对象的当前值,以及可选的它的is_called标志。 + 设置序列对象的当前值,并可选地设置其is_called标志。 双参数形式将序列的last_value字段设置为指定的值,并将其is_called字段设置为true,意味着下一个nextval将在返回值之前推进序列。 currval将报告的值也设置为指定的值。在三参数形式中,is_called可以设置为truefalsetrue与双参数形式具有相同的效果。 - 如果设置为false,下一个nextval将返回指定的值,序列推进从下面的nextval开始。 - 而且,currval报告的值在这种情况下不会改变。例如, + 如果设置为false,下一个nextval将返回指定的值,序列推进从再下一次调用nextval开始。 + 而且,currval报告的值在这种情况下不会改变。例如: -SELECT setval('myseq', 42); Next nextval will return 43 +SELECT setval('myseq', 42); 下一次 nextval 将返回 43 SELECT setval('myseq', 42, true); 同上 -SELECT setval('myseq', 42, false); Next nextval will return 42 +SELECT setval('myseq', 42, false); 下一次 nextval 将返回 42 setval返回的结果就是它的第二个参数的值。 @@ -16706,8 +15096,7 @@ SELECT setval('myseq', 42, false); Next nextvalbigint - 返回nextval在当前会话中为该序列最近获取的值。(如果在这个会话中没有为这个序列调用nextval会报告错误。) - 因为它返回的是一个会话本地值,所以它给出了一个可预测的答案,即自当前会话以来,其他会话是否执行了nextval。 + 返回当前会话中最近一次针对该序列调用nextval所获得的值。(如果当前会话从未针对该序列调用过nextval,则会报错。)由于返回的是会话局部值,无论其他会话是否在当前会话调用之后执行过nextval,结果都是可预测的。 这个函数需要序列上的USAGESELECT权限。 @@ -16759,9 +15148,7 @@ SELECT setval('myseq', 42, false); Next nextval - 序列函数所要操作的序列由regclass参数指定,该参数只是pg_class系统目录中序列的OID。 - 你不必手工查找OID,不过,因为regclass数据类型的输入转换器将为您完成这项工作。 - 详见 + 序列函数所要操作的序列由regclass参数指定,该参数就是序列在pg_class系统目录中的 OID。不过,不必手动查找 OID,因为regclass数据类型的输入转换器会完成这项工作。详见 @@ -16808,7 +15195,7 @@ CASE WHEN condition THEN result - CASE子句可以用于任何表达式可以出现的地方。每一个condition是一个返回boolean结果的表达式。如果结果为真,那么CASE表达式的结果就是符合条件的result,并且剩下的CASE表达式不会被处理。如果条件的结果不为真,那么以相同方式搜寻任何随后的WHEN子句。如果没有WHEN condition为真,那么CASE表达式的值就是在ELSE子句里的result。如果省略了ELSE子句而且没有条件为真,结果为空。 + CASE子句可以用于任何表达式可以出现的地方。每一个condition是一个返回boolean结果的表达式。如果结果为真,那么CASE表达式的结果就是紧随该条件后的result,并且剩下的CASE表达式不会被处理。如果条件的结果不为真,那么以相同方式搜寻任何随后的WHEN子句。如果没有WHEN condition为真,那么CASE表达式的值就是在ELSE子句里的result。如果省略了ELSE子句而且没有条件为真,结果为 null。 @@ -16852,7 +15239,7 @@ CASE expression END - 第一个expression会被计算,然后与所有在WHEN子句中的每一个value对比,直到找到一个相等的。如果没有找到匹配的,则返回在ELSE子句中的result(或者控制)。 这类似于 C 里的switch语句。 + 第一个expression会被计算,然后与所有在WHEN子句中的每一个value对比,直到找到一个相等的。如果没有找到匹配的,则返回在ELSE子句中的result(或者 null 值)。 这类似于 C 里的switch语句。 @@ -16883,11 +15270,7 @@ SELECT ... WHERE CASE WHEN x <> 0 THEN y/x > 1.5 ELSE false END; - 如中所述,在有几种情况中一个表达式的子表达式 - 会被计算多次,因此CASE只计算必要的表达式这 - 一原则并非不可打破。例如一个常量子表达式1/0通常将会在规划时导致一次 - 除零错误,即便它位于一个执行时永远也不会进入的CASE分支时也是 - 如此。 + 如所述,在多种情况下,表达式中的子表达式会在不同阶段求值,因此CASE只计算必要的子表达式这一原则并非绝对成立。例如,常量子表达式1/0通常会在规划时导致除零错误,即便它位于一个运行时永远不会进入的CASE分支中也是如此。 @@ -16912,19 +15295,19 @@ SELECT ... WHERE CASE WHEN x <> 0 THEN y/x > 1.5 ELSE false END; - COALESCE函数返回它的第一个非空参数的值。当且仅当所有参数都为空时才会返回空。它常用于在为显示目的检索数据时用缺省值替换空值。例如: + COALESCE函数返回参数中第一个不为 null 的值。只有所有参数都为 null 时,才返回 null。它常用于在检索数据以供显示时,用默认值替换 null 值。例如: SELECT COALESCE(description, short_description, '(none)') ... - 如果description不为空,这将会返回它的值,否则如果short_description非空则返回short_description的值,如果前两个都为空则返回(none)。 + 此表达式返回description,前提是它不为 null,否则返回short_description,前提是它不为 null,否则返回(none) - 所有参数都必须转换为一个公共数据类型,它将是结果的类型 (详情参见 )。 + 所有参数都必须能转换为同一个数据类型,它将是结果的类型(详情参见)。 - 和CASE表达式一样,COALESCE将不会 计算无助于判断结果的参数;也就是说,在第一个非空参数右边的参数不会被计算。这个 SQL 标准函数提供了类似于NVLIFNULL的能力,它们被用在某些其他数据库系统中。 + 和CASE表达式一样,COALESCE只计算确定结果所需的参数;也就是说,在第一个不为 null 的参数右边的参数不会被计算。这个 SQL 标准函数提供了类似于NVLIFNULL的能力,它们被用在某些其他数据库系统中。 @@ -16940,12 +15323,12 @@ SELECT COALESCE(description, short_description, '(none)') ... - 当value1value2相等时,NULLIF返回一个空值。 + 当value1value2相等时,NULLIF返回 null。 否则它返回value1。 这些可以用于执行前文给出的COALESCE示例的逆操作: SELECT NULLIF(value, '(none)') ... - 在这个示例中,如果value(none),将返回空值,否则返回value的值。 + 在这个示例中,如果value(none),将返回 null,否则返回value的值。 @@ -16980,11 +15363,11 @@ SELECT NULLIF(value, '(none)') ... - GREATESTLEAST函数从一个任意的数字表达式列表里选取最大或者最小的数值。 这些表达式必须都可以转换成一个普通的数据类型,它将会是结果类型 (参阅获取细节)。列表中的 NULL 数值将被忽略。只有所有表达式的结果都是 NULL 的时候,结果才会是 NULL。 + GREATESTLEAST函数从由任意数量的表达式组成的列表中选取最大值或最小值。这些表达式都必须能转换为同一个数据类型,该类型将作为结果类型(详情参见)。列表中的 NULL 值会被忽略。只有所有表达式的求值结果都为 NULL 时,结果才为 NULL。 - 请注意GREATESTLEAST都不是 SQL 标准,但却是很常见的扩展。某些其他数据库让它们在任何参数为 NULL 时返回 NULL,而不是在所有参数都为 NULL 时才返回 NULL。 + 请注意GREATESTLEAST都未包含在 SQL 标准中,但却是很常见的扩展。某些其他数据库让它们在任何参数为 NULL 时返回 NULL,而不是在所有参数都为 NULL 时才返回 NULL。 @@ -16996,9 +15379,9 @@ SELECT NULLIF(value, '(none)') ... 显示了可以用于数组类型的专用的操作符。 除此之外,中所示的常用比较操作符也适用于数组。 - 比较操作符逐个元素的比较数组内容,使用默认的元素数据类型的B-树比较函数,并根据第一个差值进行排序。 + 比较操作符逐个元素比较数组内容,使用元素数据类型的默认 B-树比较函数,并根据第一个差异进行排序。 多维数组的元素按照行序进行访问(最后的下标变化最快)。 - 如果两个数组的内容相同但维数不等,那么维度信息中的第一个不同将决定排序顺序。 + 如果两个数组的内容相同但维度信息不同,那么维度信息中的第一个不同将决定排序顺序。 @@ -17029,7 +15412,7 @@ SELECT NULLIF(value, '(none)') ... 第一个数组是否包含第二个数组,也就是说,出现在第二个数组中的每个元素是否等于第一个数组中的某个元素? - (重复值不需要特殊处理,因此ARRAY[1]ARRAY[1,1]被认为包含对方。) + (重复元素不作特殊处理,因此ARRAY[1]ARRAY[1,1]被认为包含对方。) ARRAY[1,4,3] @> ARRAY[3,1,3] @@ -17071,8 +15454,7 @@ SELECT NULLIF(value, '(none)') ... anycompatiblearray - 连接两个数组。连接空(null)或空数组是一个无操作(no-op);否则,数组必须具有相同的维度数(如第一个示例所示),或者维度数相差一个(如第二个示例所示)。 - 如果数组不是完全相同的元素类型,它们将被强制转换成一个共同的类型(参见)。 + 连接两个数组。连接 null 或空数组不会产生任何效果;否则,数组必须具有相同的维数(如第一个示例所示),或维数相差一维(如第二个示例所示)。如果数组的元素类型不同,则会将它们强制转换为同一个类型(参见)。 ARRAY[1,2,3] || ARRAY[4,5,6,7] @@ -17104,7 +15486,7 @@ SELECT NULLIF(value, '(none)') ... anycompatiblearray - 将元素连接到数组的末尾(数组必须为空或一维的[one-dimensional])。 + 将元素连接到数组的末尾(数组必须为空或一维)。 ARRAY[4,5,6] || 7 @@ -17116,7 +15498,7 @@ SELECT NULLIF(value, '(none)') ...
- 参阅获取有关数组操作符行为的更多细节。有关哪些操作符支持被索引的操作,请参阅。 + 参阅获取有关数组操作符行为的更多细节。有关哪些操作符支持索引操作,请参阅 @@ -17205,8 +15587,7 @@ SELECT NULLIF(value, '(none)') ... anyarray - 返回一个包含给定值的拷贝的数组,其维数与第二个参数指定的长度相同。 - 可选的第三个参数提供每个维度的下界值(默认为全部为 1)。 + 返回用给定值的副本填充的数组,各维的长度由第二个参数指定。可选的第三个参数提供各维的下界值(默认均为1)。 array_fill(11, ARRAY[2,3]) @@ -17287,7 +15668,7 @@ SELECT NULLIF(value, '(none)') ... integer - 返回阵列中第二个参数中第一次发生的下标,如果它不存在,则返回NULL。 + 返回第二个参数在数组中首次出现的下标;若不存在,则返回NULL。 如果给出了第三个参数,则搜索从该下标开始。数组必须是一维的。比较是使用IS NOT DISTINCT FROM语义进行的,所以可以搜索NULL @@ -17305,9 +15686,9 @@ SELECT NULLIF(value, '(none)') ... integer[] - 返回作为第一个参数的数组中第二个参数所有出现的下标的数组。 + 返回第二个参数在第一个参数所给数组中所有出现位置的下标数组。 数组必须是一维的。使用IS NOT DISTINCT FROM语义完成比较,所以可以搜索NULL。 - 只有当数组为NULL时才返回NULL;如果在数组中没有找到该值,则返回空数组。 + 只有当数组为NULL时才返回NULL;如果在数组中没有找到该值,则返回空数组。 array_positions(ARRAY['A','A','B','A'], 'A') @@ -17377,7 +15758,6 @@ SELECT NULLIF(value, '(none)') ... 将每个数组元素转换为其文本表示,并将它们用delimiter字符串分隔连接起来。 如果提供了null_string且不是NULL,则NULL数组条目将用该字符串表示;否则将被省略。 - 另请参见string_to_array array_to_string(ARRAY[1, 2, 3, NULL, 5], ',', '*') @@ -17428,7 +15808,7 @@ SELECT NULLIF(value, '(none)') ... anyarray - 通过删除最后的n元素来裁剪数组。 + 通过删除最后的n个元素来裁剪数组。 如果数组是多维的,则只裁剪第一个维度。 @@ -17495,6 +15875,10 @@ SELECT NULLIF(value, '(none)') ... + + string_to_array 的行为与 PostgreSQL 9.1 之前的版本有两点不同。首先,输入字符串长度为零时,它返回空数组(零个元素),而不是 NULL。其次,如果分隔符字符串为 NULL,该函数会将输入拆分为单个字符,而不像以前那样返回 NULL + + 也可参见了解用于数组的聚合函数array_agg @@ -17628,7 +16012,7 @@ SELECT NULLIF(value, '(none)') ... boolean - 第一个范围是否严格符合第二个(范围)? + 第一个范围是否严格地在第二个(范围)的右边? int8range(50,60) >> int8range(20,30) @@ -17712,7 +16096,7 @@ SELECT NULLIF(value, '(none)') ... anyrange - 计算范围的差异。第二个范围必须不能包含在第一个(范围)中,以使差异不是一个单一的范围。 + 计算范围的差集。第二个范围不能被包含在第一个范围中而导致差集无法表示为单个范围。 int8range(5,15) - int8range(10,20) @@ -17806,7 +16190,7 @@ SELECT NULLIF(value, '(none)') ... boolean - 第一个多范围是否被第二个所包括? + 第一个多范围是否被第二个所包含? '{[2,4)}'::int4multirange <@ '{[1,7)}'::int4multirange @@ -17820,7 +16204,7 @@ SELECT NULLIF(value, '(none)') ... boolean - 多范围是否被范围所包括。 + 多范围是否被范围所包含? '{[2,4)}'::int4multirange <@ int4range(1,7) @@ -17834,7 +16218,7 @@ SELECT NULLIF(value, '(none)') ... boolean - 范围是否被多范围所包括? + 范围是否被多范围所包含? int4range(2,4) <@ '{[1,7)}'::int4multirange @@ -17932,7 +16316,7 @@ SELECT NULLIF(value, '(none)') ... boolean - 范围是否完全的在多范围左边? + 范围是否完全在多范围左边? int8range(1,10) << '{[100,110)}'::int8multirange @@ -17974,7 +16358,7 @@ SELECT NULLIF(value, '(none)') ... boolean - 范围是否完全在多范围右边。 + 范围是否完全在多范围右边? int8range(50,60) >> '{[20,30)}'::int8multirange @@ -18142,7 +16526,7 @@ SELECT NULLIF(value, '(none)') ... anymultirange - 计算多范围的差异。 + 计算多范围的差集。 '{[5,20)}'::int8multirange - '{[10,15)}'::int8multirange @@ -18154,21 +16538,21 @@ SELECT NULLIF(value, '(none)') ... - 当涉及一个空范围或多范围时,左部/右部/相邻操作符总是返回假;即一个空范围被认为不在任何其他范围前面或者后面。 + 涉及空范围或空多范围时,左侧、右侧和相邻操作符总是返回假;也就是说,空范围不被视为位于任何其他范围之前或之后。 - 在其他地方,空范围和多范围被视为加法标识:与空值的任何交集都是它自己。 - 任何减去空值的都是它自己。 - 空的多范围与空的范围具有完全相同的点。 + 在其他运算中,空范围和空多范围被视为加法单位元:任何值与空值求并集,结果仍是该值本身。 + 任何值减去空值,结果也仍是该值本身。 + 空多范围与空范围具有完全相同的点。 每个范围都包含空范围。 每个多范围包含任意多个空范围。 - 范围交集和差异操作符将失败,如果结果范围需要包含两个不相交的子范围,因为这样的范围无法表示。 - 还有用于求交集和差集的单独操作符,它们接受多范围参数并返回多范围,即使参数彼此不相交也不会失败。 - 因此,如果需要对可能不相交的范围进行交集或差异操作,你可以通过首先将范围转换为多范围来避免错误。 + 如果结果范围需要包含两个不相交的子范围,范围并集和差集操作符会失败,因为这样的范围无法表示。 + 另有接受多范围参数并返回多范围的并集和差集操作符,即使参数彼此不相交,也不会失败。 + 因此,如果需要对可能不相交的范围求并集或差集,可以先将范围转换为多范围来避免错误。 @@ -18223,7 +16607,7 @@ SELECT NULLIF(value, '(none)') ... anyelement - 提取范围的上限(如果范围为空或上限为无限,则为NULL)。 + 提取范围的上界(如果范围为空或上界为无限,则为NULL)。 upper(numrange(1.1,2.2)) @@ -18365,7 +16749,7 @@ SELECT NULLIF(value, '(none)') ... anyelement - 提取多范围的下界 (NULL 如果多范围为空或下界为无穷的)。 + 提取多范围的下界(如果多范围为空或下界为无穷,则返回NULL)。 lower('{[1.1,2.2)}'::nummultirange) @@ -18382,7 +16766,7 @@ SELECT NULLIF(value, '(none)') ... anyelement - 提取多范围的上界 (NULL 如果多范围为空或上界为无穷的)。 + 提取多范围的上界(如果多范围为空或上界为无穷,则返回NULL)。 upper('{[1.1,2.2)}'::nummultirange) @@ -18416,7 +16800,7 @@ SELECT NULLIF(value, '(none)') ... boolean - 多范围的下界是否包括? + 多范围的下界是否包含在内? lower_inc('{[1.1,2.2)}'::nummultirange) @@ -18433,7 +16817,7 @@ SELECT NULLIF(value, '(none)') ... boolean - 多范围的上界是否包括? + 多范围的上界是否包含在内? upper_inc('{[1.1,2.2)}'::nummultirange) @@ -18495,7 +16879,7 @@ SELECT NULLIF(value, '(none)') ... - multirange (function) + multirange(函数) multirange ( anyrange ) anymultirange @@ -18513,14 +16897,14 @@ SELECT NULLIF(value, '(none)') ... unnest - for multirange + 用于多范围 unnest ( anymultirange ) setof anyrange - 扩展多范围为一组范围。 - 范围按存储顺序读出(升序)。 + 将多范围展开为一组范围。 + 范围按存储顺序(升序)读出。 unnest('{[1,2), [3,4)}'::int4multirange) @@ -18536,7 +16920,7 @@ SELECT NULLIF(value, '(none)') ... - lower_incupper_inclower_inf、 和 upper_inf 函数对空范围(empty range)或多范围都返回假(false)。 + lower_incupper_inclower_infupper_inf 函数对空范围或空多范围都返回假。 @@ -18550,11 +16934,11 @@ SELECT NULLIF(value, '(none)') ... - 聚合函数从一个输入值的集合计算出一个单一值。 - 内置的通用聚合函数在中列出,而统计性聚合是在中列出。 + 聚合函数从一个输入值的集合计算出一个单一结果。 + 内置的通用聚合函数在中列出,而统计聚合函数在中列出。 内置的组内有序集聚合函数在中列出,而内置的组内假想集聚合在中列出。 与聚合函数紧密相关的分组操作在中列出。 - 中会解释针对聚合函数的特殊语法考虑。额外的介绍信息请参考。 + 中会解释针对聚合函数的特殊语法注意事项。更多入门信息请参考 @@ -18593,7 +16977,7 @@ SELECT NULLIF(value, '(none)') ... 将所有输入值,包括空值,收集到一个数组中。 - No + @@ -18602,15 +16986,15 @@ SELECT NULLIF(value, '(none)') ... anyarray - 将所有输入数组连接到一个更高维度的数组中。(输入必须都具有相同的维度,并且不能为空的(empty)或空值(null)。) + 将所有输入数组连接成维数增加一维的数组。(所有输入的维数必须相同,且不能是空数组或空值(NULL)。) - No + - average + 平均值 avg @@ -18645,7 +17029,7 @@ SELECT NULLIF(value, '(none)') ... 计算所有非空输入值的平均值(算术平均值)。 - Yes + @@ -18669,9 +17053,9 @@ SELECT NULLIF(value, '(none)') ... bit - 计算所有非空输入值的逐位AND。 + 计算所有非空输入值的按位与。 - Yes + @@ -18695,9 +17079,9 @@ SELECT NULLIF(value, '(none)') ... bit - 计算所有非空输入值的逐位OR。 + 计算所有非空输入值的按位或。 - Yes + @@ -18724,7 +17108,7 @@ SELECT NULLIF(value, '(none)') ... 计算所有非空输入值的按位异或。 可用作一组无序的值集合的校验和。
- Yes + @@ -18738,7 +17122,7 @@ SELECT NULLIF(value, '(none)') ... 如果全部非空输入值都为真则返回真,否则返回假。 - Yes + @@ -18752,7 +17136,7 @@ SELECT NULLIF(value, '(none)') ... 如果任何非空输入值为真则返回真,否则返回假。 - Yes + @@ -18766,7 +17150,7 @@ SELECT NULLIF(value, '(none)') ... 计算输入行的数量。 - Yes + @@ -18777,7 +17161,7 @@ SELECT NULLIF(value, '(none)') ... 计算输入值不为空的输入行的数量。 - Yes + @@ -18789,9 +17173,9 @@ SELECT NULLIF(value, '(none)') ... boolean
- 这是对应bool_and的SQL标准的等效物。 + 这是标准 SQL 中与bool_and等价的函数。 - Yes + @@ -18812,7 +17196,7 @@ SELECT NULLIF(value, '(none)') ... 收集所有输入值,包括空值,到一个JSON数组。根据to_jsonto_jsonb将值转换为JSON。 - No + @@ -18835,10 +17219,10 @@ SELECT NULLIF(value, '(none)') ... jsonb - 将所有键/值对收集到一个JSON对象中。关键参数强制转换为文本;值参数按照to_jsonto_jsonb进行转换。 + 将所有键/值对收集到一个JSON对象中。键参数强制转换为文本;值参数按照to_jsonto_jsonb进行转换。 值可以为空,但键不能(为空)。 - No + @@ -18846,14 +17230,12 @@ SELECT NULLIF(value, '(none)') ... 最大值 - max ( see text ) - same as input type + max ( 见说明 ) + 与输入类型相同 计算非空输入值的最大值。适用于任何数字、字符串、日期/时间或枚举类型, - 以及inetinterval、 - moneyoidpg_lsn、 - tidxid8, + 以及inetintervalmoneyoidpg_lsntid, 以及这些类型的数组。 @@ -18864,14 +17246,12 @@ SELECT NULLIF(value, '(none)') ... 最小值 - min ( see text ) - same as input type + min ( 见说明 ) + 与输入类型相同 计算非空输入值的最小值。适用于任何数字、字符串、日期/时间或枚举类型, - 以及inetinterval、 - moneyoidpg_lsn、 - tidxid8, + 以及inetintervalmoneyoidpg_lsntid, 以及这些类型的数组。 @@ -18886,15 +17266,10 @@ SELECT NULLIF(value, '(none)') ... anyrange ) anymultirange - - range_agg ( value - anymultirange ) - anymultirange - 计算非空输入值的并集。 - No + @@ -18914,7 +17289,7 @@ SELECT NULLIF(value, '(none)') ... 计算非空输入值的交集。 - No + @@ -18932,9 +17307,9 @@ SELECT NULLIF(value, '(none)') ... bytea - 将非 null 输入值连接成一个字符串。第一个值之后的每个值前面都会放置相应的delimiter(如果它不为 null)。 + 将非 NULL 输入值连接成一个字符串。在第一个值之后,每个值前面都会放置相应的delimiter(如果它不为 NULL)。 - No + @@ -18976,7 +17351,7 @@ SELECT NULLIF(value, '(none)') ... 计算非空输入值的总和。 - Yes + @@ -18988,31 +17363,24 @@ SELECT NULLIF(value, '(none)') ... xml - 连接非空的XML输入值(参见)。 + 连接非空的 XML 输入值(参见)。 - No + - 应该注意的是,除了count之外,这些函数在没有选择行时返回空值。 - 特别地,行数的sum返回空(null),而不是预期的零,array_agg在没有输入行时返回空(null)而不是空数组。 - coalesce函数可以在必要时用零或空数组代替空(null)。 + 需要注意,除了count之外,这些函数在没有选中任何行时都会返回空值。特别地,sum在没有输入行时返回空值,而不是预期中的零;array_agg在没有输入行时返回空值,而不是空数组。必要时,可以用coalesce函数把空值替换成零或空数组。 - 聚合函数 array_agg,json_agg, jsonb_agg,json_object_agg, jsonb_object_agg, - string_agg,和 xmlagg,以及类似的用户定义的聚合函数,根据输入值的顺序产生富有意义的不同的结果值。 - 默认情况下,这种排序是不指定的,但可以通过在聚合调用中写入ORDER BY子句来控制,如所示。 - 或者,从排序的子查询提供输入值通常也可以。例如: - + 聚合函数array_aggjson_aggjsonb_aggjson_object_aggjsonb_object_aggstring_aggxmlagg,以及类似的用户定义聚合函数,其结果值会随输入值的顺序发生实质性变化。默认情况下,输入顺序未指定,但可以在聚合调用中写入ORDER BY子句来控制,如所示。也可以用已排序的子查询提供输入值,这通常也能奏效。例如: - - 注意,如果外部查询级别包含其他处理,例如关联,则此方法可能会失败,因为这可能导致子查询的输出在计算聚合之前重新排序。 + 需要注意,如果外层查询包含连接等额外处理,这种方法可能失效,因为子查询的输出可能在计算聚合之前被重新排序。 @@ -19026,31 +17394,24 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; - 布尔聚合 bool_andbool_or 对应于标准SQL聚合 everyanysome. - PostgreSQL 支持 every, 但不支持 anysome, 因为标准语法中存在模糊性: - + 布尔聚合bool_andbool_or对应于标准 SQL 聚合everyanysome。 + PostgreSQL支持every,但不支持anysome,因为标准语法中存在歧义: SELECT b1 = ANY((SELECT b2 FROM t2 ...)) FROM t1 ...; - - 这里ANY可以被认为是引入子查询,或者是聚合函数,如果子查询返回一行布尔值。因此,不能为这些聚合提供标准名称。 +此处的ANY既可以被视为引入一个子查询,也可以在该子查询返回一行布尔值时被视为聚合函数。因此,不能将标准名称用于这些聚合。 - 习惯使用其他SQL数据库管理系统的用户可能会对count聚合应用于整个表时的性能感到失望。一个类似下面的查询: - + 习惯于其他 SQL 数据库管理系统的用户,可能会对count聚合用于整个表时的性能感到失望。如下查询: SELECT count(*) FROM sometable; - - 将需要与表大小成比例的工作:PostgreSQL将需要扫描整个表或包含表中所有行的索引。 +所需的工作量与表大小成正比:PostgreSQL需要扫描整个表,或者完整扫描一个包含表中所有行的索引。 - 显示了统计分析中常用的聚合函数。 - (这些被分离出来仅仅是为了避免使更常用的聚合列表混乱。) - 显示为接受numeric_type的函数可用于所有类型smallint, integer,bigint, numeric, real, 和 double precision。 - 在描述中提及N时,它意味着所有输入表达式都非空的输入行数。在所有情况下,如果计算没有意义,则返回null,例如当N为0时。 + 列出了统计分析中常用的聚合函数。(将它们单独列出,只是为了避免更常用的聚合函数列表过于杂乱。)标为接受numeric_type的函数适用于smallintintegerbigintnumericrealdouble precision这些类型。描述中提到的N表示所有输入表达式都非空的输入行数。无论哪种情况,如果计算没有意义,例如N为 0,就返回 null。 @@ -19085,7 +17446,7 @@ SELECT count(*) FROM sometable; - correlation + 相关性 corr @@ -19096,14 +17457,14 @@ SELECT count(*) FROM sometable; 计算相关系数。 - Yes + - covariance - population + 协方差 + 总体 covar_pop @@ -19114,14 +17475,14 @@ SELECT count(*) FROM sometable; 计算总体协方差。 - Yes + - covariance - sample + 协方差 + 样本 covar_samp @@ -19132,7 +17493,7 @@ SELECT count(*) FROM sometable; 计算样本协方差。 - Yes + @@ -19144,9 +17505,9 @@ SELECT count(*) FROM sometable; double precision - 计算自变量的平均值,sum(X)/N. + 计算自变量的平均值,即sum(X)/N - Yes + @@ -19158,9 +17519,9 @@ SELECT count(*) FROM sometable; double precision - 计算因变量的平均值,sum(Y)/N. + 计算因变量的平均值,即sum(Y)/N - Yes + @@ -19174,13 +17535,13 @@ SELECT count(*) FROM sometable; 计算两个输入都非空的行数。 - Yes + - regression intercept + 回归截距 regr_intercept @@ -19189,9 +17550,9 @@ SELECT count(*) FROM sometable; double precision - 计算由(XY)对决定的最小二乘拟合的线性方程的Y-截距。 + 计算由(XY)数值对确定的最小二乘拟合线性方程的 y 轴截距。 - Yes + @@ -19205,13 +17566,13 @@ SELECT count(*) FROM sometable; 计算相关系数的平方。 - Yes + - regression slope + 回归斜率 regr_slope @@ -19220,9 +17581,9 @@ SELECT count(*) FROM sometable; double precision - 计算由(X, Y)对决定的最小二乘拟合的线性方程的斜率。 + 计算由(XY)数值对确定的最小二乘拟合线性方程的斜率。 - Yes + @@ -19234,10 +17595,9 @@ SELECT count(*) FROM sometable; double precision - 计算自变量的平方和 - sum(X^2) - sum(X)^2/N. + 计算自变量的平方和,即sum(X^2) - sum(X)^2/N - Yes + @@ -19249,10 +17609,9 @@ SELECT count(*) FROM sometable; double precision - 计算独立变量乘以因变量的sum of products, - sum(X*Y) - sum(X) * sum(Y)/N. + 计算自变量与因变量的乘积和,即sum(X*Y) - sum(X) * sum(Y)/N - Yes + @@ -19264,69 +17623,62 @@ SELECT count(*) FROM sometable; double precision - 计算因变量的平方和, - sum(Y^2) - sum(Y)^2/N. + 计算因变量的平方和,即sum(Y^2) - sum(Y)^2/N - Yes + - standard deviation + 标准差 stddev stddev ( numeric_type ) - double precision - for real or double precision, - otherwise numeric + 对于realdouble precision输入,返回double precision;否则返回numeric - 这是stddev_samp的一个历史别称。 + 这是stddev_samp的一个历史别名。 - Yes + - standard deviation - population + 标准差 + 总体 stddev_pop stddev_pop ( numeric_type ) - double precision - for real or double precision, - otherwise numeric + 对于realdouble precision输入,返回double precision;否则返回numeric 计算输入值的总体标准差。 - Yes + - standard deviation - sample + 标准差 + 样本 stddev_samp stddev_samp ( numeric_type ) - double precision - for real or double precision, - otherwise numeric + 对于realdouble precision输入,返回double precision;否则返回numeric 计算输入值的样本标准差。 - Yes + @@ -19335,54 +17687,48 @@ SELECT count(*) FROM sometable; variance variance ( numeric_type ) - double precision - for real or double precision, - otherwise numeric + 对于realdouble precision输入,返回double precision;否则返回numeric - 这是 var_samp 的一个历史别称。 + 这是 var_samp 的一个历史别名。 - Yes + - variance - population + 方差 + 总体 var_pop var_pop ( numeric_type ) - double precision - for real or double precision, - otherwise numeric + 对于realdouble precision输入,返回double precision;否则返回numeric - 计算输入值的总体方差(总体标准差的平方)。 + 计算输入值的总体方差(总体标准差的平方)。 - Yes + - variance - sample + 方差 + 样本 var_samp var_samp ( numeric_type ) - double precision - for real or double precision, - otherwise numeric + 对于realdouble precision输入,返回double precision;否则返回numeric - 计算输入值的样本方差(样本标准差的平方)。 + 计算输入值的样本方差(样本标准差的平方)。 - Yes + @@ -19393,11 +17739,11 @@ SELECT count(*) FROM sometable; 这些函数有时被称为逆分布函数。 它们的聚合输入通过ORDER BY引入,还可以接受未聚合的直接参数,但后者只计算一次。 所有这些函数在其聚合输入中都忽略空(null)值。 - 对于使用fraction参数的函数,分数值必须在 0 到 1 之间;否则会报错。但是,null 的 fraction 值只会产生一个 null 结果。 + 对于使用fraction参数的函数,比例值必须在 0 到 1 之间;否则会报错。但是,null 的 fraction 值只会产生一个 null 结果。 - ordered-set aggregate + 有序集聚合 内置 @@ -19429,16 +17775,16 @@ SELECT count(*) FROM sometable; - mode - statistical + 众数 + 统计 mode () WITHIN GROUP ( ORDER BY anyelement ) anyelement - 计算mode,即聚合参数最频繁的值(如果有多个相同频繁的值,第一个可以任意选择)。聚合参数必须是可排序类型。 + 计算众数,即聚合参数中出现次数最多的值(若多个值的出现次数相同且最多,则任意选择其中第一个)。聚合参数必须是可排序类型。 - No + @@ -19456,9 +17802,9 @@ SELECT count(*) FROM sometable; 计算连续百分位点,该值对应于聚合参数值有序集合中的指定fraction。 - 如果需要,这将在相邻的输入项之间插入。 + 必要时会在相邻输入项之间进行插值。 - No + @@ -19473,7 +17819,7 @@ SELECT count(*) FROM sometable; 计算多个连续百分位点。结果是一个与fractions参数具有相同维度的数组,其中每个非 null 元素都被替换为对应百分位点的值(必要时会进行插值)。 - No + @@ -19489,7 +17835,7 @@ SELECT count(*) FROM sometable; 计算离散百分位数,即聚合参数值的有序集合中的第一个值,该值在排序中的位置等于或超过指定的fraction。 聚合参数必须是可排序类型。 - No + @@ -19502,14 +17848,14 @@ SELECT count(*) FROM sometable; 结果是一个与fractions参数具有相同维数的数组,每个非空元素都被对应于该百分位数的输入值替换。 聚合参数必须是可排序类型。 - No + - hypothetical-set aggregate + 假想集聚合 内置 @@ -19545,52 +17891,52 @@ SELECT count(*) FROM sometable; rank - hypothetical + 假设行 rank ( args ) WITHIN GROUP ( ORDER BY sorted_args ) bigint - 计算假设行的排名,包括间隔,就是说在它的同等行组中第一行的行号。 + 计算假设行的排名,允许空缺;即该行所属同等行组中第一行的行号。 - No + dense_rank - hypothetical + 假设行 dense_rank ( args ) WITHIN GROUP ( ORDER BY sorted_args ) bigint - 计算假设行的排名,没有间隔;这个功能有效地计数同等行组。 + 计算假设行的排名,没有空缺;此函数实际上对同等行组进行计数。 - No + percent_rank - hypothetical + 假设行 percent_rank ( args ) WITHIN GROUP ( ORDER BY sorted_args ) double precision - 计算假设行的相关排行,也就是(rank - 1) / (total rows - 1)。取值范围为 0 到 1(含)。 + 计算假设行的相对排名,即(rank - 1)/(总行数 - 1)。取值范围为 0 到 1(含)。 - No + cume_dist - hypothetical + 假设行 cume_dist ( args ) WITHIN GROUP ( ORDER BY sorted_args ) double precision @@ -19598,7 +17944,7 @@ SELECT count(*) FROM sometable; 计算累积分布,也就是(位于假设行之前或与假设行同等的行数)/(总行数)。取值范围为 1/N 到 1。 - No + @@ -19631,8 +17977,7 @@ SELECT count(*) FROM sometable; integer - 返回一个位掩码以指示哪个GROUP BY表达式没有包含在当前分组集中。 - 比特位分配给最右边的参数,对应于最低有效位;如果对应的表达式包含在生成当前结果行的分组集的分组条件中,则每个位为 0,否则为 1。 + 返回一个位掩码,指示哪些GROUP BY表达式未包含在当前分组集中。分配比特位时,最右侧参数对应最低有效位;如果相应表达式包含在生成当前结果行的分组集的分组条件中,该位为 0,否则为 1。 @@ -19640,9 +17985,7 @@ SELECT count(*) FROM sometable; - 所示的分组操作与分组集(参见)共同使用,以区分结果行。 - GROUPING函数的参数实际上并不求值,但它们必须与相关查询级别的GROUP BY子句中给出的表达式完全匹配。例如: - + 在中列出的分组操作与分组集配合使用(参见),以区分结果行。传给GROUPING函数的参数不会实际求值,但它们必须与相关查询层级的GROUP BY子句中的表达式完全匹配。例如: => SELECT * FROM items_sold; make | model | sales -------+-------+------- @@ -19663,9 +18006,7 @@ SELECT count(*) FROM sometable; Bar | | 1 | 20 | | 3 | 50 (7 rows) - - 在这里,前四行中的grouping0表明这些已经正常分组,在两个分组列上。 - 值1表示model没有在倒数两行中分组,值3表示无论是make还是model都没有在最后一行中分组(因此,这是所有输入行的聚合)。 +这里,前四行的grouping值为0,表明这些行按两个分组列正常分组。值1表明model未用于倒数第二、第三行的分组,值3则表明最后一行既未按make分组,也未按model分组(因此该行聚合了全部输入行)。 @@ -19689,7 +18030,7 @@ SELECT count(*) FROM sometable; - 除了这些函数之外,任何内置的或用户定义的普通聚合(例如非有序集或假想集聚合)都可以作为窗口函数使用;关于内置聚合的列表,参见。 + 除了这些函数之外,任何内置的或用户定义的普通聚合(即不属于有序集或假想集聚合)都可以作为窗口函数使用;关于内置聚合的列表,参见。 聚合函数只有在调用后带有OVER子句时才作为窗口函数;否则,它们就是普通聚合,并为整个结果集返回一行。 @@ -19720,7 +18061,7 @@ SELECT count(*) FROM sometable; bigint - 返回其分区内的当前行数,从1开始计数。 + 返回当前行在其分区内的编号,从 1 开始计数。 @@ -19733,7 +18074,7 @@ SELECT count(*) FROM sometable; bigint - 返回当前行的排名,包含间隔;即同等行组中第一行的row_number。 + 返回当前行的排名,允许空缺;即同等行组中第一行的row_number @@ -19746,7 +18087,7 @@ SELECT count(*) FROM sometable; bigint - 返回当前行的排名,不包括间隔;这个功能有效地计数同等行组。 + 返回当前行的排名,没有空缺;此函数实际上对同等行组进行计数。 @@ -19785,7 +18126,7 @@ SELECT count(*) FROM sometable; integer - 返回一个从1到参数值的整数,并将分区划分为尽可能相等的值。 + 返回从 1 到参数值的整数,将分区尽可能均等地划分。 @@ -19800,9 +18141,7 @@ SELECT count(*) FROM sometable; anycompatible - 返回分区中在当前行之前offset行的value;如果没有这样的行,则返回default(必须与value相兼容的类型)。 - offsetdefault都是针对当前行求值的。 - 如果省略,offset默认为1,defaultNULL。 + 返回在分区内当前行之前offset行处计算的value;如果没有这样的行,则返回default(其类型必须与value兼容)。offsetdefault都针对当前行求值。如果省略,offset默认为 1,default默认为NULL @@ -19817,10 +18156,7 @@ SELECT count(*) FROM sometable; anycompatible - 返回分区中在当前行之后offset行的value; - 如果没有这样的行,则返回default(必须与value兼容的类型)。 - offsetdefault都是针对当前行求值的。 - 如果省略,offset默认为1,defaultNULL。 + 返回在分区内当前行之后offset行处计算的value;如果没有这样的行,则返回default(其类型必须与value兼容)。offsetdefault都针对当前行求值。如果省略,offset默认为 1,default默认为NULL @@ -19875,14 +18211,14 @@ SELECT count(*) FROM sometable; 注意first_valuelast_valuenth_value只考虑窗口帧内的行,它默认情况下包含从分区的开始行直到当前行的最后一个同等行。 这对last_value可能不会给出有用的结果,有时对nth_value也一样。 - 你可以通过向OVER子句增加一个合适的帧声明(RANGEGROUPS)来重定义帧。 + 你可以通过向OVER子句增加一个合适的帧声明(RANGEROWSGROUPS)来重定义帧。 关于帧声明的更多信息请参考 当一个聚合函数被用作窗口函数时,它将在当前行的窗口帧内的行上聚合。 - 一个使用ORDER BY和默认窗口帧定义的聚合产生一种运行时求和类型的行为,这可能是或者不是想要的结果。 - 为了获取在整个分区上的聚合,忽略ORDER BY或者使用ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING。 + 一个使用ORDER BY和默认窗口帧定义的聚合产生一种累计求和类型的行为,这可能是或者不是想要的结果。 + 为了获取在整个分区上的聚合,省略ORDER BY或者使用ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING。 其它窗口帧声明可以用来获得其它的效果。 @@ -19891,7 +18227,7 @@ SELECT count(*) FROM sometable; SQL 标准为leadlagfirst_valuelast_valuenth_value定义了一个RESPECT NULLSIGNORE NULLS选项。 这在PostgreSQL中没有实现:行为总是与标准的默认相同,即RESPECT NULLS。 - 同样,标准中用于nth_valueFROM FIRSTFROM LAST选项没有实现: 只有支持默认的FROM FIRST行为(你可以通过反转ORDER BY的排序达到FROM LAST的结果)。 + 同样,标准中用于nth_valueFROM FIRSTFROM LAST选项没有实现: 只支持默认的FROM FIRST行为(你可以通过反转ORDER BY的排序达到FROM LAST的结果)。 @@ -19926,11 +18262,11 @@ SELECT count(*) FROM sometable; - subquery + 子查询 - 本节描述PostgreSQL中可用的SQL兼容的子查询表达式。所有本节中成文的表达式都返回布尔值(真/假)结果。 + 本节描述PostgreSQL中可用的SQL兼容的子查询表达式。本节介绍的所有表达式形式都返回布尔值(真/假)结果。 @@ -19945,7 +18281,7 @@ EXISTS (subquery) - 子查询可以引用来自周围的查询的变量,这些变量在该子查询的任何一次计算中都起常量的作用。 + 子查询可以引用外层查询的变量,这些变量在该子查询的任何一次计算中都起常量的作用。 @@ -19957,7 +18293,7 @@ EXISTS (subquery) - 下面这个简单的示例类似在col2上的一次内联接,但是它为每个 tab1的行生成最多一个输出,即使存在多个匹配tab2的行也如此∶ + 下面这个简单的示例类似在col2上的一次内连接,但是它为每个 tab1的行最多生成一行输出,即使存在多个匹配tab2的行也如此: SELECT col1 FROM tab1 @@ -19974,15 +18310,15 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 右手边是一个圆括弧括起来的子查询, 它必须正好只返回一个列。左手边表达式将被计算并与子查询结果逐行进行比较。 如果找到任何等于子查询行的情况,那么IN的结果就是。 如果没有找到相等行,那么结果是(包括子查询没有返回任何行的情况)。 + 右手边是一个圆括号括起来的子查询,它必须恰好返回一列。左手边表达式会被求值,并与子查询结果逐行比较。如果找到任意相等的子查询行,那么IN的结果就是。如果没有找到相等行,那么结果就是(包括子查询不返回任何行的情况)。 - 请注意如果左手边表达式得到空值,或者没有相等的右手边值, 并且至少有一个右手边行得到空值,那么IN结构的结果将是空值,而不是假。这个行为是遵照 SQL 处理空值的一般规则的。 + 请注意,如果左侧表达式得到空值,或者右侧没有相等的值且至少有一行得到空值,则IN结构的结果将是空值,而不是假。这符合 SQL 对空值布尔组合的一般规则。 - 和EXISTS一样,假设子查询将被完成运行完全是不明智的。 + 和EXISTS一样,假定子查询一定会完整运行并不明智。 @@ -19990,7 +18326,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 这种形式的IN的左手边是一个行构造器, 如中所述。 右手边是一个圆括弧子查询,它必须返回和左手边返回的行中表达式所构成的完全一样多的列。 左手边表达式将被计算并与子查询结果逐行进行比较。如果找到任意相等的子查询行,则IN的结果为。如果没有找到相等行, 那么结果为(包括子查询不返回行的情况)。 + 这种形式的IN左手边是一个行构造器,如中所述。右手边是一个圆括号括起来的子查询,它必须返回与左手边行中表达式数量完全相同的列数。左手边表达式会被求值,并与子查询结果逐行比较。如果找到任意相等的子查询行,则IN的结果为。如果没有找到相等行,那么结果为(包括子查询不返回任何行的情况)。 @@ -20006,15 +18342,15 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 右手边是一个用圆括弧包围的子查询,它必须返回正好一个列。左手边表达式将被计算并与子查询结果逐行进行比较。 如果只找到不相等的子查询行(包括子查询不返回行的情况),那么NOT IN的结果是。 如果找到任何相等行,则结果为。 + 右手边是一个圆括号括起来的子查询,它必须恰好返回一列。左手边表达式会被求值,并与子查询结果逐行比较。如果只找到不相等的子查询行(包括子查询不返回任何行的情况),那么NOT IN的结果是。如果找到任何相等行,则结果为 - 请注意如果左手边表达式得到空值,或者没有相等的右手边值, 并且至少有一个右手边行得到空值,那么NOT IN结构的结果将是空值,而不是真。这个行为是遵照 SQL 处理空值的一般规则的。 + 请注意,如果左侧表达式得到空值,或者右侧没有相等的值且至少有一行得到空值,则NOT IN结构的结果将是空值,而不是真。这符合 SQL 对空值布尔组合的一般规则。 - 和EXISTS一样,假设子查询将被完成运行完全是不明智的。 + 和EXISTS一样,假定子查询一定会完整运行并不明智。 @@ -20022,7 +18358,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 这种形式的NOT IN的左手边是一个行构造器, 如中所述。 右手边是一个圆括弧子查询,它必须返回和左手边返回的行中表达式所构成的完全一样多的列。 左手边表达式将被计算并与子查询结果逐行进行比较。如果找到不等于子查询行的行,则NOT IN的结果为。如果找到相等行, 那么结果为(包括子查询不返回行的情况)。 + 这种形式的NOT IN左侧是一个行构造器,如中所述。右侧是一个用圆括号括起来的子查询,必须返回与左侧行中表达式数量完全相同的列数。对左侧表达式求值后,将其按行与子查询结果的每一行比较。如果只找到不相等的子查询行(包括子查询不返回任何行的情况),则NOT IN的结果为。如果找到任何相等行,则结果为 @@ -20040,7 +18376,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 这种形式的右侧是一个用括号括起来的子查询,它必须恰好返回一列。左侧表达式会被求值,并使用给定的 operator 与子查询结果的每一行进行比较。如果得到任何真值结果,那么ANY的结果就是。如果没有找到真值结果,那么结果是(包括子查询没有返回任何行的情况)。 + 这种形式的右侧是一个用括号括起来的子查询,它必须恰好返回一列。左侧表达式会被求值,并使用给定的 operator 与子查询结果的每一行进行比较。该操作符必须产生布尔结果。如果得到任何真值结果,那么ANY的结果就是。如果没有找到真值结果,那么结果是(包括子查询没有返回任何行的情况)。 @@ -20048,11 +18384,11 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 请注意如果没有任何成功并且至少有一个右手边行为该操作符结果生成空值, 那么ANY结构的结果将是空值,而不是假。 这个行为是遵照 SQL 处理空值布尔组合的一般规则制定的。 + 请注意,如果没有任何比较返回真,并且至少有一个右侧行的操作符结果为空值,则ANY结构的结果将是空值,而不是假。这符合 SQL 对空值布尔组合的一般规则。 - 和EXISTS一样,假设子查询将被完成运行完全是不明智的。 + 和EXISTS一样,假定子查询一定会完整运行并不明智。 @@ -20061,7 +18397,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 这种形式的左侧是一个行构造器,如所述。右侧是一个用括号括起来的子查询,它必须返回与左侧行中表达式数量完全相同的列数。左侧表达式会被求值,并使用给定的operator与子查询结果的每一行逐行比较。如果比较对任何子查询行返回真,则ANY的结果为。如果比较对每一个子查询行都返回假,则结果为(包括子查询不返回行的情况)。如果比较对任何行都不返回真,并且至少有一次比较返回 NULL,则结果为 NULL。 + 这种形式的ANY左侧是一个行构造器,如所述。右侧是一个用括号括起来的子查询,它必须返回与左侧行中表达式数量完全相同的列数。左侧表达式会被求值,并使用给定的operator与子查询结果的每一行逐行比较。如果比较对任何子查询行返回真,则ANY的结果为。如果比较对每一个子查询行都返回假,则结果为(包括子查询不返回行的情况)。如果比较对任何行都不返回真,并且至少有一次比较返回 NULL,则结果为 NULL。 @@ -20077,7 +18413,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 这种形式的 ALL 右侧是一个用括号括起来的子查询,它必须只返回一列。左侧表达式会被求值,并使用给定的 operator 与子查询结果的每一行进行比较。该操作符必须产生布尔结果。如果所有行都得到真(包括子查询没有返回任何行的情况),ALL 的结果就是。如果发现任何假值结果,结果就是。如果比较对任何行都不返回假,并且至少有一次比较返回 NULL,则结果为 NULL。 + 右侧是一个用圆括号括起来的子查询,必须恰好返回一列。左侧表达式会被求值,并使用给定的operator与子查询结果的每一行进行比较。该操作符必须产生布尔结果。如果所有行都得到真(包括子查询不返回任何行的情况),则ALL的结果为。如果得到任何假值结果,则结果为。如果与任何子查询行的比较都不返回假,并且至少有一次比较返回 NULL,则结果为 NULL。 @@ -20085,7 +18421,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 和EXISTS一样,假设子查询将被完成运行完全是不明智的。 + 和EXISTS一样,假定子查询一定会完整运行并不明智。 @@ -20115,7 +18451,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 左手边是一个行构造器,如所述。 右手边是一个圆括弧括起来的子查询,该查询必须返回和左手边行中表达式数目完全一样的列。 另外,该子查询不能返回超过一行的数量(如果它返回零行,那么结果就是空值)。 左手边被计算并逐行与右手边的子查询结果行比较。 + 左侧是一个行构造器,如所述。右侧是一个用圆括号括起来的子查询,必须返回与左侧行中表达式数量完全相同的列数。此外,该子查询不能返回超过一行;如果它返回零行,则结果为空值。对左侧求值后,将所得的行与子查询返回的唯一一行进行比较。 @@ -20154,12 +18490,12 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 逐行比较 + 行比较 比较 - 逐行 + 复合类型 @@ -20176,7 +18512,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 本节描述几个特殊的结构,用于在值的组之间进行多重比较。这些形式语法上和前面一节的子查询形式相关,但是不涉及子查询。 这种形式涉及的数组子表达式是PostgreSQL的扩展; 其它的是SQL兼容的。所有本节记录的表达式形式都返回布尔(Boolean)结果(真/假)。 + 本节描述几个特殊的结构,用于在值的组之间进行多重比较。这些形式语法上和前面一节的子查询形式相关,但是不涉及子查询。 涉及数组子表达式的形式是PostgreSQL的扩展; 其余形式是SQL兼容的。本节介绍的所有表达式形式都返回布尔(Boolean)结果(真/假)。 @@ -20187,14 +18523,12 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 右侧是一个用括号括起来的表达式列表。如果左侧表达式的结果等于右侧任何一个表达式的结果,则结果为true。 - 这是一个简写表示法,如下所示: - + 右侧是一个用圆括号括起来的表达式列表。如果左侧表达式的结果等于右侧任一表达式的结果,则结果为。这等价于以下写法: expression = value1 -或 +OR expression = value2 -或 +OR ... @@ -20212,9 +18546,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 右侧是一个用括号括起来的表达式列表。如果左侧表达式的结果与所有右侧表达式都不相等,则结果为true。 - 这是一个简写表示法,用于 - + 右侧是一个用圆括号括起来的表达式列表。如果左侧表达式的结果与右侧所有表达式的结果都不相等,则结果为。这等价于以下写法: expression <> value1 AND @@ -20238,7 +18570,7 @@ AND - <literal>ANY</literal>/<literal>SOME</literal> (array) + <literal>ANY</literal>/<literal>SOME</literal>(数组) expression operator ANY (array expression) @@ -20260,7 +18592,7 @@ AND - <literal>ALL</literal> (array) + <literal>ALL</literal>(数组) expression operator ALL (array expression) @@ -20284,20 +18616,7 @@ AND - 每一边都是一个行构造器, - 如在中描述的那样。 - 这两个行构造器必须具有相同数量的字段。 - 给定的operator应用于每一对 - 对应的字段。(由于字段可能是不同类型的,这意味着每对可能选择不同的具体操作符。) - 所有选定的操作符必须是某个B-树操作符类的成员,或者是B-树操作符类的=成员的否定形式, - 这意味着只有当operator是 - =、 - <>、 - <、 - <=、 - >或 - >=时才可能进行行构造器比较, - 或者具有类似于这些操作符的语义。 + 两侧都是行构造器,如所述。两个行构造器必须具有相同数量的字段。给定的operator应用于每一对对应字段。(由于字段可能具有不同的类型,因此可能为各对字段选择不同的具体操作符。)所选操作符必须是某个 B-树操作符类的成员,或者是 B-树操作符类中=成员的否定操作符。这意味着只有当operator=<><<=>>=,或具有与这些操作符类似的语义时,才可以进行行构造器比较。 @@ -20342,21 +18661,21 @@ AND - SQL 规范要求在结果依赖于比较两个 NULL 值或者一个 NULL 与一个非 NULL 时逐行比较返回 NULL。 + SQL 规范要求在结果依赖于比较两个 NULL 值或者一个 NULL 与一个非 NULL 时行比较返回 NULL。 PostgreSQL只有在比较两个行构造器(如)的结果或者比较一个行构造器与一个子查询的输出时才这样做(如中所述)。 - 在其他比较两个复合类型值的环境中,两个 NULL 域值被认为相等,并且一个 NULL 被认为大于一个非 NULL。 + 在其他比较两个复合类型值的环境中,两个 NULL 字段值被认为相等,并且一个 NULL 被认为大于一个非 NULL。 为了得到复合类型的一致的排序和索引行为,这样做是必要的。 - 每一边都会被计算并且它们会被逐行比较。当operator是 + 对两侧分别求值后,按行进行比较。当operator=<><<=>或者 - >=时或者具有与这些类似的语义时,允许复合类型的比较(更准确地说,如果一个操作符是一个 B-树操作符类的成员,或者是一个 B-树操作符类的=成员的否定词,它就可以是一个行比较操作符)。 - 上述操作符的行为与用于行构造器(见)的IS [ NOT ] DISTINCT FROM相同。 + >=时或者具有与这些类似的语义时,允许复合类型的比较(更准确地说,如果一个操作符是一个 B-树操作符类的成员,或者是一个 B-树操作符类的=成员的否定操作符,它就可以是一个行比较操作符)。 + 上述操作符的默认行为与用于行构造器(见)的IS [ NOT ] DISTINCT FROM相同。 @@ -20367,9 +18686,9 @@ AND *<=*>以及 *>=。 - 这些操作符比较两行的内部二进制表达。即使两行用相等操作符的比较为真,两行也可能具有不同的二进制表达。 - 行在这些比较操作符之下的排序是决定性的,其他倒没什么意义。 - 这些操作符在内部被用于物化视图并且可能对其他如复制和B-树复制(参见 )之类的特殊功能有用,但是它们并不打算用在书写查询这类普通用途中。 + 这些操作符比较两行的内部二进制表示。即使两行用相等操作符的比较为真,两行也可能具有不同的二进制表示。 + 使用这些比较操作符得到的行排序是确定的,但除此之外没有其他意义。 + 这些操作符在内部被用于物化视图并且可能对其他如复制和 B-树去重(参见 )之类的特殊功能有用,但是它们并不打算用在书写查询这类普通用途中。 @@ -20384,13 +18703,13 @@ AND - 本节描述那些可能返回多于一行的函数。目前这个类中被使用最广泛的是级数生成函数, 如所述。其他更特殊的集合返回函数在本手册的其他地方描述。 - 组合多集合返回函数的方法可见。 + 本节描述那些可能返回多于一行的函数。目前这个类中被使用最广泛的是序列生成函数, 如所述。其他更特殊的集合返回函数在本手册的其他地方描述。 + 组合多个集合返回函数的方法可见 - 级数生成函数 + 序列生成函数 @@ -20433,12 +18752,11 @@ AND setof timestamp - generate_series ( start timestamp with time zone, stop timestamp with time zone, step interval , timezone text ) + generate_series ( start timestamp with time zone, stop timestamp with time zone, step interval ) setof timestamp with time zone startstop生成一系列的值,步长为step。 - 在带时区形式中,一天中的时刻以及夏令时调整会根据timezone参数指定的时区来计算;如果省略该参数,则使用当前的设置。 @@ -20446,9 +18764,7 @@ AND
- 当step为正时,如果start大于stop则返回零行。 - 相反,当step为负时,如果start小于stop则返回零行。 - 如果任何输入为NULL也会返回零行。step为零是一个错误。下面是一些示例: + 当step为正数时,如果start大于stop,则返回零行。反之,当step为负数时,如果start小于stop,则返回零行。如果任一输入为NULL,也返回零行。如果step为零,则会报错。下面是一些示例: SELECT * FROM generate_series(2,4); generate_series @@ -20479,7 +18795,7 @@ SELECT generate_series(1.1, 4, 1.3); 3.7 (3 rows) --- this example relies on the date-plus-integer operator: +-- 此示例使用日期加整数的操作符: SELECT current_date + s.a AS dates FROM generate_series(0,14,7) AS s(a); dates ------------ @@ -20502,25 +18818,6 @@ SELECT * FROM generate_series('2008-03-01 00:00'::timestamp, 2008-03-03 22:00:00 2008-03-04 08:00:00 (9 rows) - --- 此示例假定 TimeZone 设置为 UTC;注意 DST 转换: -SELECT * FROM generate_series('2001-10-22 00:00 -04:00'::timestamptz, - '2001-11-01 00:00 -05:00'::timestamptz, - '1 day'::interval, 'America/New_York'); - generate_series ------------------------- - 2001-10-22 04:00:00+00 - 2001-10-23 04:00:00+00 - 2001-10-24 04:00:00+00 - 2001-10-25 04:00:00+00 - 2001-10-26 04:00:00+00 - 2001-10-27 04:00:00+00 - 2001-10-28 04:00:00+00 - 2001-10-29 05:00:00+00 - 2001-10-30 05:00:00+00 - 2001-10-31 05:00:00+00 - 2001-11-01 05:00:00+00 -(11 rows) @@ -20551,7 +18848,7 @@ SELECT * FROM generate_series('2001-10-22 00:00 -04:00'::timestamptz, setof integer
- 生成一个包含给定数组第dim维度的有效下标的序列。 + 生成一个包含给定数组第dim维的有效下标的序列。 @@ -20561,7 +18858,7 @@ SELECT * FROM generate_series('2001-10-22 00:00 -04:00'::timestamptz, setof integer
- 生成一个包含给定数组第dim维度的有效下标的序列。当reverse为真时,以相反的顺序返回序列。 + 生成一个包含给定数组第dim维的有效下标的序列。当reverse为真时,以相反的顺序返回序列。 @@ -20570,9 +18867,9 @@ SELECT * FROM generate_series('2001-10-22 00:00 -04:00'::timestamptz, generate_subscripts是一个快捷函数,它为给定数组的指定维度生成一组合法的下标。 - 对于不具有请求维度的数组返回零行,对于任何输入为NULL数组也返回零行。下面是一些示例: + 如果数组不具有所请求的维度,或者任一输入为NULL,则返回零行。下面是一些示例: --- basic usage: +-- 基本用法: SELECT generate_subscripts('{NULL,1,NULL,2}'::int[], 1) AS s; s --- @@ -20582,8 +18879,8 @@ SELECT generate_subscripts('{NULL,1,NULL,2}'::int[], 1) AS s; 4 (4 rows) --- presenting an array, the subscript and the subscripted --- value requires a subquery: +-- 展示数组、下标和下标对应的值 +-- 需要使用子查询: SELECT * FROM arrays; a -------------------- @@ -20602,7 +18899,7 @@ FROM (SELECT generate_subscripts(a, 1) AS s, a FROM arrays) foo; {100,200,300} | 3 | 300 (5 rows) --- unnest a 2D array: +-- 展开二维数组: CREATE OR REPLACE FUNCTION unnest2(anyarray) RETURNS SETOF anyelement AS $$ select $1[i][j] @@ -20622,15 +18919,13 @@ SELECT * FROM unnest2(ARRAY[[1,2],[3,4]]); - ordinality + 序号 - 当FROM子句中的函数以WITH ORDINALITY作为后缀时,将在函数的输出列上附加一个bigint列,该列从1开始,函数输出的每一行加1。 - 这在 unnest()等集合返回函数的情况下最有用。 - + 当FROM子句中的函数后面加上WITH ORDINALITY时,一个bigint列会追加到函数的输出列中,其值从 1 开始,对函数输出的每一行递增 1。这种方式对集合返回函数尤其有用,例如unnest() --- set returning function WITH ORDINALITY: +-- 集合返回函数与 WITH ORDINALITY: SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); ls | n -----------------+---- @@ -20664,7 +18959,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); 系统信息函数和操作符 - 展示了多个可以抽取会话和系统信息的函数。 + 列出了多个用于提取会话和系统信息的函数。 @@ -20705,7 +19000,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); name - 返回当前数据库的名称。(在SQL标准中数据库被称为catalogs,因此current_catalog是该标准的拼写方式。) + 返回当前数据库的名称。(SQL 标准将数据库称为目录(catalogs),因此current_catalog是标准中的写法。) @@ -20718,7 +19013,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); text - 返回当前所执行查询的文本,由客户端提交的(可能包含一个以上的语句)。 + 返回客户端提交的当前正在执行的查询文本(可能包含多条语句)。 @@ -20741,8 +19036,8 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); current_schema - schema - current + 模式 + 当前 current_schema name @@ -20763,16 +19058,14 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); current_schemas - search path - current + 搜索路径 + 当前 current_schemas ( include_implicit boolean ) name[]
- 返回当前在有效搜索路径中的所有模式的名称的数组,以优先级顺序。 - (当前 设置中与已存在的、可搜索模式不相符的项将被省略。) - 如果布尔参数为true,则类似pg_catalog的隐式搜索的系统模式将包含在结果中。 + 返回当前有效搜索路径中所有模式名称的数组,按优先级排序。(当前设置中不对应于已存在且可搜索的模式的项会被省略。)如果布尔参数为true,结果还会包含pg_catalog等隐式搜索的系统模式。 @@ -20782,8 +19075,8 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); current_user - user - current + 用户 + 当前 current_user name @@ -20802,7 +19095,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); inet
- 返回当前客户端的IP地址,如果当前连接是通过Unix-域套接字则返回NULL + 返回当前客户端的 IP 地址;如果当前连接通过 Unix 域套接字建立,则返回NULL @@ -20815,7 +19108,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); integer
- 返回当前客户端的IP端口号,如果当前连接是通过Unix-域套接字则返回NULL。 + 返回当前客户端的IP端口号,如果当前连接是通过Unix 域套接字则返回NULL @@ -20828,7 +19121,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); inet
- 返回服务器接受当前连接的IP地址,如果当前连接是通过Unix-域套接字则返回NULL。 + 返回服务器接受当前连接的IP地址,如果当前连接是通过Unix 域套接字则返回NULL @@ -20841,7 +19134,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); integer - 返回服务器接受当前连接的IP端口号,如果当前连接是通过Unix-域套接字则返回NULL。 + 返回服务器接受当前连接的IP端口号,如果当前连接是通过Unix 域套接字则返回NULL @@ -20867,12 +19160,10 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); integer[] - 返回阻止服务器进程的会话的进程ID数组,该进程ID与指定的进程ID一起获取锁定,如果没有这样的服务器进程或者没有被阻塞,则返回一个空数组。 + 返回一个数组,包含阻止指定进程 ID 对应的服务器进程获取锁的会话进程 ID;如果不存在这样的服务器进程,或该进程未被阻塞,则返回空数组。 - 如果一个服务器进程持有一个与被阻塞进程的锁请求冲突的锁(硬阻塞),或者正在等待一个与被阻塞进程的锁请求冲突并且在等待队列中位于其前面的锁(软阻塞),那么这个服务器进程就会阻塞另一个服务器进程。 - 当使用并行查询时结果总是列出客户端可见的进程ID(即pg_backend_pid的结果),即使实际的锁是由子工作进程持有或等待的。 - 因此,结果中可能存在重复的pid。还要注意当准备好的事务持有冲突锁时,它将用零进程ID表示。 + 一个服务器进程会在以下情况下阻塞另一个进程:它持有与被阻塞进程请求的锁冲突的锁(硬阻塞);或者它正在等待一个会与被阻塞进程请求的锁冲突的锁,并且在等待队列中位于被阻塞进程之前(软阻塞)。使用并行查询时,即使实际持锁或等待锁的是子工作进程,结果也始终列出客户端可见的进程 ID(即pg_backend_pid的结果)。因此,结果中可能出现重复的 PID。另外,如果持有冲突锁的是一个预备事务,结果中会用进程 ID 0 表示它。 频繁调用这个函数可能会对数据库性能产生一些影响,因为它需要在短时间内独占访问锁管理器的共享状态。 @@ -20888,8 +19179,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); timestamp with time zone - 返回服务器配置文件最后加载的时间。如果当前会话当时是活跃的,那么这将是会话本身重新读取配置文件的时间(因此在不同的会话中读取会稍有不同)。 - 否则,就是postmaster进程重新读取配置文件的时间。 + 返回服务器配置文件最近一次加载的时间。如果当时当前会话已经存在,则返回该会话自身重新读取配置文件的时间(因此不同会话中的返回时间会略有不同)。否则,返回 postmaster 进程重新读取配置文件的时间。 @@ -20899,16 +19189,16 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); pg_current_logfile - Logging - pg_current_logfile函数 + 日志记录 + pg_current_logfile 函数 current_logfiles - 和pg_current_logfile函数 + 和pg_current_logfile 函数 - Logging - current_logfiles文件和pg_current_logfile函数 + 日志记录 + current_logfiles 文件和pg_current_logfile 函数 pg_current_logfile ( text ) text @@ -20917,32 +19207,15 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); 返回当前由日志收集器使用的日志文件的路径名。路径包括目录和单独的日志文件名。 如果日志收集器已禁用,则结果为NULL。 当存在多个日志文件,每个以不同格式存在时,不带参数的pg_current_logfile返回有序列表中找到的第一个格式的文件路径: - stderrcsvlogjsonlog。 + stderrcsvlog。 如果没有任何日志文件具有这些格式,则返回NULL。 - 要请求有关特定日志文件格式的信息,请将csvlogjsonlogstderr作为可选参数的值。 + 要请求有关特定日志文件格式的信息,请将csvlogstderr作为可选参数的值。 如果请求的日志格式未在中配置,则结果为NULL。 结果反映current_logfiles文件的内容。 - - 默认情况下,此函数仅限于超级用户以及具有pg_monitor角色权限的角色,但可以向其他用户授予 EXECUTE 权限以运行该函数。 - + - - - - pg_get_loaded_modules - - pg_get_loaded_modules () - setof record - ( module_name text, - version text, - file_name text ) - - - 返回当前服务器会话中已加载的可加载模块列表。除非模块作者使用 PG_MODULE_MAGIC_EXT 宏提供了这些值,否则 module_nameversion 字段为 NULL。file_name 字段给出模块(共享库)的文件名。 - - @@ -20983,18 +19256,6 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); - - - - pg_numa_available - - pg_numa_available () - boolean - - - 如果服务器在编译时启用了 NUMA 支持,则返回真。 - - @@ -21018,7 +19279,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); double precision - 返回当前被等待处理的通知所占用的异步通知队列最大尺寸的分数(0–1)。更多信息请参见。 + 返回待处理通知当前占用的空间占异步通知队列最大容量的比例(0–1)。更多信息请参见 @@ -21044,11 +19305,11 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); integer[] - 返回一个进程ID数组,该进程ID是阻塞服务器进程获取安全快照的会话的进程ID数组,如果没有这样的服务器进程或者没有阻塞,则返回一个空数组。 + 返回一个数组,包含阻止指定进程 ID 对应的服务器进程获取安全快照的会话进程 ID;如果不存在这样的服务器进程,或该进程未被阻塞,则返回空数组。 运行SERIALIZABLE事务的会话会阻止SERIALIZABLE READ ONLY DEFERRABLE事务获取快照,直到后者确定可以安全地避免获取谓词锁。 - 关于可串行化和可延迟事务的更多信息,请参见。 + 关于可序列化和可延迟事务的更多信息,请参见 频繁调用这个函数可能会对数据库性能产生一些影响,因为它需要在短时间内访问谓词锁管理器的共享状态。 @@ -21064,7 +19325,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); integer - 返回当前嵌套层次的PostgreSQL触发器(如果没有调用则为 0,直接或间接,从一个触发器内部开始)。 + 返回PostgreSQL触发器的当前嵌套层级(如果不是从触发器内部直接或间接调用,则为 0)。 @@ -21077,7 +19338,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); name - 返回会话用户名. + 返回会话用户名。 @@ -21094,7 +19355,8 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); - + + version @@ -21103,9 +19365,12 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); text - 返回描述PostgreSQL服务器的版本的字符串。 - 你还可以从 中获得此信息,或者对于机器可读的版本,使用。 - 软件开发人员可以使用server_version_num(从8.2起可用)或,而不是解析文本版本。 + 返回描述PostgreSQL + 服务器版本的字符串。你还可以从 + 获得此信息,或者对于机器可读的 + 版本,使用。软件 + 开发人员应该使用server_version_num(自 8.2 起可用) + 或,而不是解析文本版本。 @@ -21115,32 +19380,21 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); - current_catalogcurrent_rolecurrent_schemacurrent_usersession_useruserSQL里有特殊的语法地位: 它们被调用时结尾不要跟着圆括号。 - 在 PostgreSQL 中,圆括号可以有选择性地被用于current_schema,但是不能和其他的一起用。 + current_catalogcurrent_rolecurrent_schemacurrent_usersession_useruserSQL中具有特殊语法:调用时不得在后面加圆括号。在 PostgreSQL 中,current_schema可以选择加圆括号,其他函数则不可以。 - session_user通常是发起当前数据库连接的用户,不过超级用户可以用修改这个设置。 - current_user是用于权限检查的用户标识。通常, 它总是等于会话用户,但是可以被改变。 - 它也会在函数执行的过程中随着属性SECURITY DEFINER的改变而改变。 - 在 Unix 的说法里,那么会话用户是真实用户,而当前用户是有效用户。 - current_role以及usercurrent_user的同义词(SQL标准在current_rolecurrent_user之间做了区分,但PostgreSQL不区分,因为它把用户和角色统一成了一种实体)。 + session_user通常是发起当前数据库连接的用户,但超级用户可以用修改此设置。current_user是用于权限检查的用户标识,通常等于会话用户,但可以用更改。在执行具有SECURITY DEFINER属性的函数期间,它也会改变。用 Unix 的术语来说,会话用户是真实用户,当前用户是有效用户current_roleusercurrent_user的同义词。(SQL 标准区分current_rolecurrent_user,但PostgreSQL不区分,因为它将用户和角色统一为同一种实体。) - privilege - querying + 权限 + 查询 - 列出那些允许编程查询对象访问权限的函数。参阅获取更多有关权限的信息。 - 在这些函数中,可以通过名称或OID (pg_authid.oid)指定被查询权限的用户,或者如果名称被指定为public,则检查PUBLIC伪角色的权限。 - 同样,user参数可以完全省略,在这种情况下,假设为current_user。被查询的对象也可以通过名称或OID来指定。 - 通过名称指定时,可以包含相关的模式名称。感兴趣的访问权限由一个文本字符串指定,它必须计算为对象类型的一个适当的权限关键字(例如,SELECT)。 - 还可以将 WITH GRANT OPTION添加到权限类型中,以测试该权限是否由授予选项持有。 - 同样,可以用逗号分隔列出多个权限类型,在这种情况下,如果所列出的权限中有任何一个被持有,结果将为真。 - (权限字符串的大小写不重要,权限名之间允许有额外的空格,但在权限名中不允许。)一些示例: + 列出了允许以编程方式查询对象访问权限的函数。(关于权限的更多信息,请参见。)在这些函数中,可以通过名称或 OID(pg_authid.oid)指定要查询权限的用户;如果名称为public,则检查 PUBLIC 伪角色的权限。也可以完全省略user参数,此时使用current_user。要查询的对象也可以通过名称或 OID 指定。通过名称指定时,如适用,可以包含模式名。所需访问权限由文本字符串指定,其值必须为适用于该对象类型的权限关键字之一(例如SELECT)。还可以在权限类型后附加WITH GRANT OPTION,以检查是否拥有该权限及其授予选项。也可以用逗号分隔列出多个权限类型;只要拥有列出的任一权限,结果就为真。(权限字符串不区分大小写,权限名之间允许有额外的空白,但权限名内部不允许。)例如: SELECT has_table_privilege('myschema.mytable', 'select'); SELECT has_table_privilege('joe', 'mytable', 'INSERT, SELECT WITH GRANT OPTION'); @@ -21177,9 +19431,7 @@ SELECT has_table_privilege('joe', 'mytable', 'INSERT, SELECT WITH GRANT OPTION') boolean - 用户是否对表的任何列有权限? - 如果对整个表持有权限,或者对至少一个列有列级的权限授予,则会成功。 - 允许的权限类型为SELECT, INSERT,UPDATE, 和 REFERENCES + 用户是否对表的至少一列具有权限?如果拥有整个表的权限,或至少一列获得了该权限的列级授权,则返回真。允许的权限类型为SELECTINSERTUPDATEREFERENCES @@ -21230,7 +19482,7 @@ SELECT has_table_privilege('joe', 'mytable', 'INSERT, SELECT WITH GRANT OPTION') boolean - 用户是否拥有外部数据包装的权限?唯一允许的权限类型是USAGE。 + 用户是否具有外部数据包装器权限?唯一允许的权限类型为USAGE @@ -21272,39 +19524,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); - - - - has_largeobject_privilege - - has_largeobject_privilege ( - user name or oid, - largeobject oid, - privilege text ) - boolean - - - 用户是否拥有大对象的权限?可用的权限类型是 SELECTUPDATE。 - - - - - - has_parameter_privilege - - has_parameter_privilege ( - user name or oid, - parameter text, - privilege text ) - boolean - - - 用户是否具有配置参数的权限? - 参数名称不区分大小写。 - 允许的权限类型为SETALTER SYSTEM。 - - @@ -21334,7 +19554,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); boolean - 用户是否有顺序权限?允许的权限类型有USAGE, SELECT, 和UPDATE。 + 用户是否具有序列权限?允许的权限类型为USAGESELECTUPDATE @@ -21366,7 +19586,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); boolean - 用户对表有权限吗?允许的权限类型有SELECTINSERTUPDATEDELETETRUNCATEREFERENCESTRIGGERMAINTAIN。 + 用户是否具有表权限?允许的权限类型为SELECTINSERTUPDATEDELETETRUNCATEREFERENCESTRIGGER @@ -21414,13 +19634,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); privilege text ) boolean - - 用户对角色有权限吗?允许的权限类型有MEMBERUSAGESET。 - MEMBER表示对该角色的直接或间接成员资格,而不考虑由此授予的具体权限。 - USAGE表示该角色的权限是否无需执行SET ROLE即可立即使用,而SET表示是否可以使用SET ROLE命令切换到该角色。 - 任一权限类型后面都可以附加WITH ADMIN OPTIONWITH GRANT OPTION,用于测试是否持有 ADMIN 权限(这六种写法测试的都是同一件事)。 - 此函数不允许特殊情况下将user设置为public,因为PUBLIC伪角色永远不能成为真实角色的成员。 - + 用户是否具有角色权限?允许的权限类型为 MEMBERUSAGEMEMBER 表示该角色的直接或间接成员资格(即执行 SET ROLE 的权限),而 USAGE 表示无需执行 SET ROLE 就能立即使用该角色的权限。任一权限类型后面都可以附加 WITH ADMIN OPTIONWITH GRANT OPTION,以测试是否持有 ADMIN 权限(这四种写法测试的都是同一件事)。此函数不允许将 user 设置为 public 这一特殊情况,因为 PUBLIC 伪角色永远不能成为实际角色的成员。 @@ -21433,7 +19647,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); boolean - 在当前用户和当前环境的上下文之中,指定表的行级安全是活动的吗? + 在当前用户和当前环境的上下文中,指定表的行级安全性是否生效? @@ -21441,8 +19655,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); - 显示了aclitem类型的可用操作符,它是访问权限的目录表示。 - 有关如何读取访问权限值的信息,请参阅 。 + 列出了aclitem类型可用的操作符;该类型是访问权限在系统目录中的表示形式。有关如何解读访问权限值的信息,请参见 @@ -21475,8 +19688,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); boolean - aclitem相等吗?(注意,aclitem类型缺少比较操作符的通常集合;它只有相等。 - 反而言之,aclitem数组只能进行相等比较。) + 两个aclitem是否相等?(注意,aclitem类型没有通常的整套比较操作符,而只支持相等比较。因此,aclitem数组也只能进行相等比较。) 'calvin=r*w/hobbes'::aclitem = 'calvin=r*w*/hobbes'::aclitem @@ -21493,7 +19705,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); boolean - 数组是否包含指定的权限?(如果有一个数组条目与aclitem的被授权人和授予人相匹配,并且至少具有权限的指定集,则此选项为真。) + 数组是否包含指定的权限?(如果数组中存在一个条目,其被授权者和授权者与该aclitem相同,且至少包含指定的全部权限,则返回真。) '{calvin=r*w/hobbes,hobbes=r*w*/postgres}'::aclitem[] @> 'calvin=r*/hobbes'::aclitem @@ -21505,7 +19717,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute');
- 显示了一些额外的函数来管理aclitem类型。 + 列出了一些用于管理aclitem类型的其他函数。 @@ -21537,23 +19749,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); aclitem[] - 构造一个aclitem数组,保存属于具有OID ownerId的角色的对象类型type的默认访问权限。 - 这表示当对象的ACL条目为空时将假定的访问权限。(默认访问权限在中描述。) - type参数必须是以下之一: - 'c'表示COLUMN, - 'r'表示TABLE和类似表的对象, - 's'表示SEQUENCE, - 'd'表示DATABASE, - 'f'表示FUNCTIONPROCEDURE, - 'l'表示LANGUAGE, - 'L'表示LARGE OBJECT, - 'n'表示SCHEMA, - 'p'表示PARAMETER, - 't'表示TABLESPACE, - 'F'表示FOREIGN DATA WRAPPER, - 'S'表示FOREIGN SERVER, - 或 - 'T'表示TYPEDOMAIN。 + 构造一个aclitem数组,保存类型为type、属于 OID 为ownerId的角色的对象的默认访问权限。当对象的ACL条目为空值时,会采用这些访问权限。(默认访问权限见。)type参数必须为以下值之一:'c' 表示COLUMN,'r' 表示TABLE和类似表的对象,'s' 表示SEQUENCE,'d' 表示DATABASE,'f' 表示FUNCTIONPROCEDURE,'l' 表示LANGUAGE,'L' 表示LARGE OBJECT,'n' 表示SCHEMA,'t' 表示TABLESPACE,'F' 表示FOREIGN DATA WRAPPER,'S' 表示FOREIGN SERVER,'T' 表示TYPEDOMAIN @@ -21570,9 +19766,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); is_grantableboolean ) - 以行集的形式返回aclitem数组。如果受让人是伪角色PUBLIC,则在grantee列中用0表示。 - 每个被授予的权限都表示为SELECT, INSERT等。 - 注意,每个权限被分割成单独的一行,因此在privilege_type列中只出现一个关键字。 + 以行集的形式返回aclitem数组。如果被授权者是伪角色 PUBLIC,则在grantee列中用零表示。每项授予的权限表示为SELECTINSERT等。注意,每项权限都会拆成单独的一行,因此privilege_type列中只会出现一个关键字。 @@ -21597,14 +19791,9 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute');
- 展示了决定是否一个特定对象在当前模式搜索路径中可见的函数。 - 例如,如果一个表所在的模式在当前搜索路径中并且在它之前没有出现过相同的名字,这个表就被说是可见的。 - 这等价于在语句中表可以被用名称引用但不加显式的模式限定。因此,要列出所有可见表的名字: - + 列出了判断某个特定对象是否可见的函数,其判断依据是当前模式搜索路径。例如,如果表所在的模式位于搜索路径中,并且在搜索路径的更前面没有同名表,就称该表可见。这等价于说,可以只通过表名引用该表,而不必显式地用模式限定。因此,要列出所有可见表的名称: SELECT relname FROM pg_class WHERE pg_table_is_visible(oid); - - 对于函数和操作符,如果路径前面没有相同名称和参数数据类型的对象,那么搜索路径中的对象就是可见的。 - 对于操作符类和操作符族,要考虑名称和关联的索引访问方法。 +对于函数和操作符,只要搜索路径中更靠前的位置没有对象具有与被检查对象相同的名称和参数数据类型,就称被检查对象可见。对于操作符类和操作符族,会同时考虑名称及关联的索引访问方法。 @@ -21743,7 +19932,7 @@ SELECT relname FROM pg_class WHERE pg_table_is_visible(oid); boolean - 文本搜索配置在搜索路径可见吗? + 全文检索配置是否在搜索路径中可见? @@ -21756,7 +19945,7 @@ SELECT relname FROM pg_class WHERE pg_table_is_visible(oid); boolean - 文本搜索字典在搜索路径可见吗? + 全文检索词典是否在搜索路径中可见? @@ -21769,7 +19958,7 @@ SELECT relname FROM pg_class WHERE pg_table_is_visible(oid); boolean - 文本搜索解析器在搜索路径中可见吗? + 全文检索解析器是否在搜索路径中可见? @@ -21782,7 +19971,7 @@ SELECT relname FROM pg_class WHERE pg_table_is_visible(oid); boolean - 文本搜索模板在搜索路径可见吗? + 全文检索模板是否在搜索路径中可见? @@ -21803,11 +19992,10 @@ SELECT relname FROM pg_class WHERE pg_table_is_visible(oid); - 所有这些函数都要求用对象 OID 来标识将被检查的对象。如果你想用名称来测试一个对象,使用 OID 别名类型(regclassregtyperegprocedureregoperatorregconfigregdictionary)将会很方便。例如: - + 所有这些函数都需要用对象 OID 标识要检查的对象。如果想按名称测试对象,使用 OID 别名类型会很方便(regclassregtype, + regprocedureregoperatorregconfig,或regdictionary),例如: SELECT pg_type_is_visible('myschema.widget'::regtype); - - 注意以这种方式测试一个非模式限定的类型名没什么意义 — 如果该名称完全能被识别,它必须是可见的。 +注意,用这种方式测试不带模式限定的类型名并没有太大意义:只要该名称能够被识别,它就必然可见。 @@ -21841,38 +20029,12 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 返回由其类型OID和可能的类型修饰符标识的数据类型的SQL名称。如果没有已知的类型修饰符,则传递NULL值给类型修饰符。 - - - - - - - pg_char_to_encoding - - pg_char_to_encoding ( encoding name ) - integer - - - 将提供的编码名称转换为表示在某些系统目录表中使用的内部标识符的整数。 - 如果提供了未知的编码名称,则返回-1。 - - - - - - - pg_encoding_to_char - - pg_encoding_to_char ( encoding integer ) - name - - - 将在某些系统目录表中用作编码内部标识符的整数转换为可读的字符串。 - 如果提供了无效的编码编号,则返回空字符串。 + 返回由其类型OID和可能的类型修饰符标识的数据类型的SQL名称。如果没有已知的类型修饰符,则传递NULL值给类型修饰符。 + + @@ -21891,7 +20053,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); 返回一组记录,描述存在于PostgreSQL系统目录中的外键关系。 fktable 列包含引用目录的名称,fkcols列包含引用列的名称。 类似地,pktable列包含被引用目录的名称,而pkcols列包含被引用列的名称。 - 如果is_array为真,则最后一个引用列是一个数组,其每个元素都应该与引用目录中的某个条目匹配。 + 如果is_array为真,则最后一个引用列是一个数组,其每个元素都应该与被引用目录中的某个条目匹配。 如果is_opt为真,则允许引用列包含零而不是有效引用。 @@ -21905,7 +20067,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 重构为了约束的创建命令。(这是一个反编译的重构,而不是命令的原始文本。) + 重建约束的创建命令。(这是反编译重建的结果,并非命令的原始文本。) @@ -21918,8 +20080,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 反编译存储在系统目录中的表达式的内部形式,例如列的默认值。 - 如果表达式可能包含变量,则指定它们所指向的关系的OID作为第二个参数;如果没有预期的变量,传递0就可以了。 + 反编译存储在系统目录中的表达式的内部形式,例如列的默认值。如果表达式可能包含 Var 节点,请将它们所引用的关系的 OID 指定为第二个参数;如果预计不含 Var 节点,传入零即可。 @@ -21932,8 +20093,8 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 重构为了函数或过程的创建命令。(这是一个反编译的重构,而不是命令的原始文本。) - 结果是一个完整的CREATE OR REPLACE FUNCTIONCREATE OR REPLACE PROCEDURE语句。 + 重建函数或过程的创建命令。(这是反编译重建的结果,并非命令的原始文本。) + 结果是一条完整的CREATE OR REPLACE FUNCTIONCREATE OR REPLACE PROCEDURE语句。 @@ -21946,7 +20107,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 重新构造函数或过程的参数列表,以其在 CREATE FUNCTION里面需要出现的形式(包括默认值)。 + 重建函数或过程的参数列表,采用其在CREATE FUNCTION中应有的形式(包括默认值)。 @@ -21959,7 +20120,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 重新构造标识函数或过程所需的参数列表,以其应出现在ALTER FUNCTION等命令中的形式。这个表单省略默认值。 + 重建标识函数或过程所需的参数列表,采用其在ALTER FUNCTION等命令中应有的形式。这种形式省略默认值。 @@ -21972,7 +20133,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 重构函数的RETURNS子句,以其需要出现在CREATE FUNCTION中的形式。对于过程,返回NULL。 + 重建函数的RETURNS子句,采用其在CREATE FUNCTION中应有的形式。对于过程,返回NULL @@ -21985,7 +20146,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 重构针对索引的创建命令。(这是一个反编译的重构,而不是命令的原始文本。)如果提供了column而且不为零,则只重构该列的定义。 + 重建索引的创建命令。(这是反编译重建的结果,并非命令的原始文本。)如果提供了column而且不为零,则只重建该列的定义。 @@ -22003,11 +20164,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); baredesc text ) - 返回一组描述服务器识别的SQL关键字的记录。word列包含关键字。 - catcode列包含一个类别代码:U表示无保留关键字,C表示可以是列名的关键字,T表示可以是类型或函数名的关键字,或者R表示完全保留关键字。 - 如果关键字可以在SELECT列表中用作bare列标签,则barelabel列包含true,或者false,如果它只能在AS之后使用。 - catdesc列包含可能本地化字符串,描述关键字的类别。 - baredesc列包含可能本地化的字符串,描述关键字的列标签状态。 + 返回描述服务器所识别 SQL 关键字的一组记录。word列包含关键字。catcode列包含类别代码:U表示非保留关键字,C表示可用作列名的关键字,T表示可用作类型名或函数名的关键字,R表示完全保留的关键字。如果关键字可以在SELECT列表中用作列标签,barelabel列为true;如果只能在AS之后使用,则为falsecatdesc列包含描述关键字类别的字符串,该字符串可能已被本地化。baredesc列包含描述关键字列标签状态的字符串,该字符串可能已被本地化。 @@ -22019,8 +20176,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 重构分区约束的定义。 - (这是反编译得到的重构结果,而不是命令的原始文本。) + 重建分区约束的定义。(这是反编译重建的结果,并非命令的原始文本。) @@ -22033,7 +20189,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 重构针对规则的创建命令。(这是一个反编译的重构,而不是命令的原始文本。) + 重建规则的创建命令。(这是反编译重建的结果,并非命令的原始文本。) @@ -22048,15 +20204,15 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); 返回与列相关联的序列名称,如果没有序列与该列相关联则返回NULL。 如果列是标识列,则关联序列是在内部为该列创建的序列。 - 对于使用一种串行类型(serial, smallserial, bigserial)创建的列,它是为该串行列定义创建的序列。 + 对于使用一种 serial 类型(serial, smallserial, bigserial)创建的列,它是为该 serial 列定义创建的序列。 在后一种情况下,可以使用ALTER SEQUENCE OWNED BY修改或删除关联。 - (这个函数可能应该被称为pg_get_owned_sequence;它的当前名称反映了它在历史上曾与串行类型的列一起使用。) + (这个函数可能应该被称为pg_get_owned_sequence;它的当前名称反映了它在历史上曾与 serial 类型的列一起使用。) 第一个参数是具有可选模式的表名,第二个参数是列名。 由于第一个参数可能包含模式名和表名,因此按照通常的SQL规则解析它,这意味着默认情况下它是小写的。 第二个参数只是一个列名,按照字面来处理,因此保留了它的大小写。结果经过了适当的格式化,可以传递给序列函数(参见)。 - 典型的用法是读取序列的当前值以获取标识或串行列,示例如下: + 典型用法是读取标识列或 serial 列所用序列的当前值,例如: SELECT currval(pg_get_serial_sequence('sometable', 'id')); @@ -22072,7 +20228,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); text - 重构针对扩展统计对象的创建命令。(这是一个反编译的重构,而不是命令的原始文本。) + 重建扩展统计对象的创建命令。(这是反编译重建的结果,并非命令的原始文本。) @@ -22085,7 +20241,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); text - 重构针对触发器的创建命令。(这是一个反编译的重构,而不是命令的原始文本。) + 重建触发器的创建命令。(这是反编译重建的结果,并非命令的原始文本。) @@ -22111,7 +20267,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); text - 重构针对视图或物化视图的SELECT命令。(这是一个反编译的重构,而不是命令的原始文本。) + 重建定义视图或物化视图的SELECT命令。(这是反编译重建的结果,并非命令的原始文本。) @@ -22121,8 +20277,8 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); text - 重构针对视图或物化视图的底层SELECT命令。(这是一个反编译的重构,而不是命令的原始文本。) - 在这种形式的函数中,总是启用美观打印,并对长行进行换行,以尽量使它们小于指定的列数。 + 重建定义视图或物化视图的SELECT命令。(这是反编译重建的结果,并非命令的原始文本。) + 这种形式始终启用美化输出,并将长行折行,尽量使每行长度小于指定列数。 @@ -22132,7 +20288,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); text - 根据视图的文本名称而不是它的OID,重构针对视图或物化视图的底层SELECT命令。(这是弃用;请使用OID变体。) + 根据视图的文本名称而不是其 OID,重建定义视图或物化视图的SELECT命令。(此形式已弃用;请使用 OID 变体。) @@ -22145,7 +20301,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); boolean - 测试一个索引列是否具有命名属性。列出了常用索引列属性。 + 测试一个索引列是否具有指定名称的属性。列出了常用索引列属性。 (注意,扩展访问方法可以为其索引定义额外的属性名。) 如果属性名未知或不适用于特定对象,或者OID或列号不能识别有效的对象,则返回NULL @@ -22160,7 +20316,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); boolean - 测试一个索引是否具有命名属性。列出了常用的索引属性。 + 测试一个索引是否具有指定名称的属性。列出了常用的索引属性。 (注意,扩展访问方法可以为其索引定义额外的属性名。) 如果属性名未知或不适用于特定对象,或者OID不能识别有效的对象,则返回NULL @@ -22175,7 +20331,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); boolean - 测试索引访问方法是否具有命名属性。访问方法属性如所示。 + 测试索引访问方法是否具有指定名称的属性。访问方法属性如所示。 如果属性名未知或不适用于特定对象,或者OID不能识别有效的对象,则返回NULL @@ -22195,20 +20351,6 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); - - - - pg_settings_get_flags - - pg_settings_get_flags ( guc text ) - text[] - - - 返回与给定GUC相关联的标志数组,如果不存在则返回NULL。 - 如果GUC存在但没有要显示的标志,则结果为空数组。 - 仅公开列出在中最有用的标志。 - - @@ -22219,9 +20361,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); setof oid - 返回具有存储在指定表空间中的对象的数据库的OIDs集。 - 如果这个函数返回了任何行,那么表空间就不是空的,且不能被删除。 - 要识别填充表空间的特定对象,需要连接到由pg_tablespace_databases标识的数据库,并查询它们的pg_class目录。 + 返回在指定表空间中存储了对象的数据库 OID 集合。如果此函数返回任何行,则说明该表空间不为空,不能删除。要查看存放在该表空间中的具体对象,需要连接到pg_tablespace_databases标识的数据库,并查询它们的pg_class系统目录。 @@ -22247,12 +20387,10 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); regtype - 返回传递值给它的数据类型的OID。这对于故障排除或动态构造SQL查询很有帮助。 - 函数声明为返回regtype,它是一个OID别名类型(see ); - 这意味着,为了比较,它与OID相同,但显示为类型名。 + 返回所传入值的数据类型的 OID。这有助于排查问题或动态构造 SQL 查询。函数声明的返回类型是regtype,它是一种 OID 别名类型(参见);这意味着它在比较时与 OID 相同,但显示为类型名。 - 例如: + 例如: SELECT pg_typeof(33); pg_typeof @@ -22276,11 +20414,12 @@ SELECT typlen FROM pg_type WHERE oid = pg_typeof(33); text - 返回传递值给它的排序规则的名称。如果需要,该值会被引号括起来,并使用模式限定。 - 如果没有为参数表达式派生排序规则,则返回NULL。如果参数不是可排序数据类型,则会引发错误。 + 返回传入值的排序规则名称。必要时会为返回的名称加上引号和模式限定。 + 如果无法为参数表达式推导出排序规则,则返回NULL。 + 如果参数不属于支持排序规则的数据类型,则报错。 - 例如: + 例如: SELECT collation for (description) FROM pg_description LIMIT 1; pg_collation_for @@ -22305,7 +20444,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); 将文本关系名转换为它的OID。通过将字符串类型转换为regclass可以得到类似的结果(参见); - 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与类型转换不同的是,它不接受数字OID作为输入。 @@ -22318,8 +20457,8 @@ SELECT collation for ('foo' COLLATE "de_DE"); regcollation - 将文本排序规则名称转换为它的OID。通过将字符串类型转换为regcollation(参见)可以得到类似的结果; - 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 将文本排序规则名称转换为它的OID。通过将字符串类型转换为regcollation(参见)可以得到类似的结果; + 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与类型转换不同的是,它不接受数字OID作为输入。 @@ -22332,8 +20471,8 @@ SELECT collation for ('foo' COLLATE "de_DE"); regnamespace - 将文本模式名转换为它的OID。通过将字符串转换为regnamespace类型(参见)可以得到类似的结果; - 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 将文本模式名转换为它的OID。通过将字符串转换为regnamespace类型(参见)可以得到类似的结果; + 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与类型转换不同的是,它不接受数字OID作为输入。 @@ -22346,8 +20485,8 @@ SELECT collation for ('foo' COLLATE "de_DE"); regoper - 将文本操作符名称转换为它的OID。通过将字符串类型转换为regoper(参见)可以得到类似的结果; - 但是,如果找不到名称或名称有多义性,该函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 将文本操作符名称转换为它的OID。通过将字符串类型转换为regoper(参见)可以得到类似的结果; + 但是,如果找不到名称或名称有歧义,该函数将返回NULL而不会抛出错误。与类型转换不同的是,它不接受数字OID作为输入。 @@ -22360,8 +20499,8 @@ SELECT collation for ('foo' COLLATE "de_DE"); regoperator - 将文本操作符名称(带有参数类型)转换为其OID。通过将字符串转换为regoperator类型(参见节)可以得到类似的结果; - 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 将文本操作符名称(带有参数类型)转换为其OID。通过将字符串转换为regoperator类型(参见节)可以得到类似的结果; + 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与类型转换不同的是,它不接受数字OID作为输入。 @@ -22374,8 +20513,8 @@ SELECT collation for ('foo' COLLATE "de_DE"); regproc - 将文本函数或过程名转换为其OID。通过将字符串转换为regproc类型(参见)可以得到类似的结果; - 但是,如果找不到名称或名称有多义性,该函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 将文本函数或过程名转换为其OID。通过将字符串转换为regproc类型(参见)可以得到类似的结果; + 但是,如果找不到名称或名称有歧义,该函数将返回NULL而不会抛出错误。与类型转换不同的是,它不接受数字OID作为输入。 @@ -22389,7 +20528,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); 将文本函数或过程名(带有参数类型)转换为其OID。通过将字符串类型转换为regprocedure可以得到类似的结果(参见); - 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与类型转换不同的是,它不接受数字OID作为输入。 @@ -22403,7 +20542,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); 将文本角色名转换为它的OID。通过将字符串类型转换为regrole可以得到类似的结果(参见); - 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与类型转换不同的是,它不接受数字OID作为输入。 @@ -22416,8 +20555,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); regtype - 将文本类型名转换为它的OID。通过将字符串类型转换为regtype可以得到类似的结果(参见); - 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 将文本形式的类型名转换为其 OID。将字符串转换为 regtype 类型也能得到类似的结果(参见 );不过,如果找不到该名称,此函数会返回 NULL,而不会报错。与类型转换不同的是,此函数不接受数值 OID 作为输入。 @@ -22425,10 +20563,10 @@ SELECT collation for ('foo' COLLATE "de_DE"); - 大多数重构(反编译)数据库对象的函数都有一个可选的 pretty标志,如果为true,结果将被pretty-printed。 - 美观打印会抑制不必要的圆括号,并为易读性增加空格。 - 美观打印的格式可读性更好,但是默认格式更有可能被PostgreSQL的未来版本以同样的方式解释; - 因此,避免为转储目的使用美观打印的输出。为pretty参数传递false会产生与省略参数相同的结果。 + 大多数重建(反编译)数据库对象的函数都有一个可选的pretty标志;若为true,则对结果进行美化输出。 + 美化输出会省略不必要的圆括号,并增加空白以提高可读性。 + 美化后的格式更易读,但默认格式更有可能被PostgreSQL的未来版本以同样的方式解释,因此用于转储时应避免美化输出。 + 为pretty参数传入false与省略该参数的结果相同。 @@ -22473,19 +20611,20 @@ SELECT collation for ('foo' COLLATE "de_DE"); distance_orderable - 列能否通过一个distance操作符(例如ORDER BY col <-> constant)有序地扫描? + + 能否按距离操作符的结果有序地扫描该列,例如ORDER BY col <-> constant returnable - 列值是否可以通过一次只用索引扫描返回? + 列值是否可以通过一次仅索引扫描返回? search_array - 列是否天然支持col = ANY(array)搜索? + 列是否原生支持col = ANY(array)搜索? @@ -22500,7 +20639,7 @@ SELECT collation for ('foo' COLLATE "de_DE");
- 索引性质 + 索引属性 @@ -22537,7 +20676,7 @@ SELECT collation for ('foo' COLLATE "de_DE");
- 索引访问方法性质 + 索引访问方法属性 @@ -22578,54 +20717,14 @@ SELECT collation for ('foo' COLLATE "de_DE");
- - - GUC 标志 - - - - 标志描述 - - - - - EXPLAIN - 带有此标志的参数包含在EXPLAIN (SETTINGS)命令中。 - - - - NO_SHOW_ALL - 具有此标志的参数将被排除在SHOW ALL命令之外。 - - - - NO_RESET_ALL - 具有此标志的参数将被排除在RESET ALL命令之外。 - - - - NOT_IN_SAMPLE - 带有此标志的参数默认情况下不包含在 - postgresql.conf中。 - - - - - RUNTIME_COMPUTED - 具有此标志的参数是在运行时计算的参数。 - - - -
- 列出了与数据库对象 - 标识和定位有关的函数。 + 列出了与数据库对象标识和寻址有关的函数。 - 对象信息和定位函数 + 对象信息和寻址函数 @@ -22650,9 +20749,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); text - 返回由目录OID、对象OID和子对象ID(例如表中的列号)标识的数据库对象的文本描述;当引用整个对象时,子对象ID为0)。 - 这个描述是人类可读的,并且可以根据服务器配置进行翻译。这对于决定pg_depend目录中引用的对象的标识特别有用。 - 此函数对于未定义的对象返回NULL值 + 返回数据库对象的文本描述,对象由系统目录 OID、对象 OID 和子对象 ID 指定(例如表中的列号;引用整个对象时,子对象 ID 为零)。该描述供人阅读,并可能根据服务器配置被翻译。这对于确定pg_depend系统目录中所引用对象的标识尤其有用。对于未定义的对象,此函数返回NULL @@ -22669,13 +20766,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); identitytext ) - 返回包含足够信息的行以唯一标识由目录OID、对象OID和子对象ID指定的数据库对象。 - 这些信息是为了机器可读的,永远不会被翻译。 - type标识数据库对象的类型; - schema是对象所属的模式名,NULL表示不属于模式的对象类型; - name是对象的名称,如果有必要,用引号括起来,如果名称(随着模式名称,如果相关)足以唯一地标识对象,否则为NULL; - identity是完整的对象标识,其精确格式依赖于对象类型,格式中的每个名称都是模式限定的,并在必要时用引号括起来。 - 未定义的对象由NULL值标识。 + 返回一行,其中包含足以唯一标识数据库对象的信息,该对象由系统目录 OID、对象 OID 和子对象 ID 指定。这些信息供机器读取,永远不会被翻译。type标识数据库对象的类型;schema是对象所属的模式名,对于不属于模式的对象类型则为NULL;如果对象名(以及适用时的模式名)足以唯一标识该对象,name就是对象名,并在必要时加引号,否则为NULLidentity是完整的对象标识,其具体格式取决于对象类型,格式中的每个名称都会根据需要加上模式限定和引号。未定义的对象以NULL值标识。 @@ -22691,10 +20782,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); object_argstext[] ) - 返回包含足够信息的行以唯一标识由目录OID、对象OID和子对象ID指定的数据库对象。 - 返回的信息独立于当前服务器,也就是说,它可以用于标识另一个服务器中具有相同名称的对象。 - type标识数据库对象的类型;object_namesobject_args是文本数组,它们一起构成对对象的引用。 - 这三个值可以传递给pg_get_object_address以获得对象的内部地址。 + 返回一行,其中包含足以唯一标识数据库对象的信息,该对象由系统目录 OID、对象 OID 和子对象 ID 指定。返回的信息与当前服务器无关,也就是说,它也能用于标识另一台服务器上名称相同的对象。type标识数据库对象的类型;object_namesobject_args是文本数组,共同构成对该对象的引用。将这三个值传给pg_get_object_address可以获得对象的内部地址。 @@ -22710,12 +20798,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); objsubidinteger ) - 返回包含足够信息的行以唯一标识由类型代码、对象名称和参数数组指定的数据库对象。 - 返回的值将在系统目录中使用,例如pg_depend; - 它们可以传递给其他系统函数,比如 pg_describe_objectpg_identify_object。 - classid是包含该对象的系统目录的OID;objid是对象本身的OID, objsubid是子对象的ID,如果没有则为零。 - 这个函数是pg_identify_object_as_address的反向函数。 - 未定义的对象以NULL值标识。 + 返回一行,其中包含足以唯一标识数据库对象的信息,该对象由类型代码、对象名称数组和参数数组指定。返回的值就是pg_depend等系统目录中使用的值;它们可以传给pg_describe_objectpg_identify_object等其他系统函数。classid是包含该对象的系统目录的 OID;objid是对象自身的 OID;objsubid是子对象 ID,没有子对象时为零。此函数执行pg_identify_object_as_address的逆操作。未定义的对象以NULL值标识。 @@ -22728,7 +20811,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); - 中展示的函数抽取注释,注释是由命令在以前存储的。如果对指定参数找不到注释,则返回空值。 + 中的函数用于提取此前通过命令存储的注释。如果找不到与指定参数对应的注释,则返回空值。
@@ -22758,7 +20841,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); text - 返回表列的注释,该注释由该表的OID和列号指定。(obj_description不能用于表的列,因为列没有自己的oid。) + 返回表列的注释,列由所属表的 OID 和列号指定。(obj_description不能用于表列,因为列没有自身的 OID。) @@ -22771,8 +20854,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); text - 返回OID指定的数据库对象的注释和包含该对象的系统目录的名称。 - 例如,obj_description(123456, 'pg_class')将检索OID为123456的表的注释。 + 返回数据库对象的注释,对象由其 OID 和所在系统目录的名称指定。例如,obj_description(123456, 'pg_class')会获取 OID 为 123456 的表的注释。 @@ -22782,8 +20864,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); text - 返回仅由其OID指定的数据库对象的注释。 - 这个已被弃用(deprecated)因为无法保证oid在不同的系统目录中是唯一的;因此,可能会返回错误的注释。 + 返回仅由其 OID 指定的数据库对象的注释。此形式已弃用,因为无法保证 OID 在不同系统目录之间唯一,因而可能返回错误的注释。 @@ -22796,9 +20877,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); text - 返回共享数据库对象的注释,该对象由其OID和包含的系统编目的名称指定。 - 这与obj_description类似,只是它用于检索共享对象(也就是数据库、角色和表空间)上的注释。 - 有些系统编目对每个集簇中的所有数据库都是全局的,其中对象的描述也全局存储。 + 返回共享数据库对象的注释,对象由其 OID 和所在系统目录的名称指定。此函数与obj_description类似,但用于获取共享对象(即数据库、角色和表空间)的注释。有些系统目录由数据库集簇中的所有数据库全局共享,其中对象的描述也全局存储。 @@ -22828,6 +20907,32 @@ SELECT collation for ('foo' COLLATE "de_DE"); + + + + age + + age ( xid ) + integer + + + 返回给定事务 ID 与当前事务计数器之间的事务数。 + + + + + + + mxid_age + + mxid_age ( xid ) + integer + + + 返回给定多事务 ID 与当前多事务计数器之间的多事务 ID 数。 + + + @@ -22837,7 +20942,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); xid8 - 返回当前事务的ID。如果当前事务还没有一个ID(因为它还没有执行任何数据库更新),它将分配一个新的事务。 + 返回当前事务的ID。如果当前事务还没有一个ID(因为它还没有执行任何数据库更新),它将分配一个新的事务 ID。 @@ -22864,10 +20969,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); text - 报告最近的事务的提交状态。如果事务为最近的,系统会保留事务的提交状态,则结果是 in progresscommittedaborted。 - 如果该事务的时间足够久,并且系统中没有对该事务的引用,而且提交状态信息已经被丢弃,则结果为NULL。 - 应用可以使用此函数,例如,确定在进行COMMIT时,应用程序和数据库服务器断开连接后,它们的事务是已提交还是中止。 - 注意,准备好的事务报告为in progress的事务;如果应用需要确定一个事务ID是否属于一个准备好的事务,则必须检查pg_prepared_xacts。 + 报告近期事务的提交状态。只要事务足够新,系统仍保留其提交状态,结果就为in progresscommittedaborted。如果事务已足够旧,系统中不再有对它的引用,且提交状态信息已被丢弃,则返回NULL。例如,在COMMIT进行过程中应用与数据库服务器断开连接时,应用可以用此函数判断事务是提交了还是中止了。注意,预备事务被报告为in progress;如果需要确定某个事务 ID 是否为预备事务,应用必须检查pg_prepared_xacts @@ -22880,7 +20982,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); pg_snapshot - 返回当前snapshot,显示哪些事务 ID正在进行中的数据结构。 + 返回当前快照,即显示哪些事务 ID 正在进行中的数据结构。 @@ -22932,8 +21034,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); boolean - 根据此快照,给定的事务ID是否可见(visible)(也就是说,它是否在快照拍摄之前完成)? - 注意,这个函数不会给出子事务ID的正确答案。 + 根据此快照,给定的事务 ID 是否可见(即该事务是否在生成快照之前完成)?注意,此函数无法为子事务 ID 给出正确结果。 @@ -22957,7 +21058,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); 内部事务 ID 类型xid是 32 位宽,每 40 亿个事务就会回卷一次(wrap around)。 - 但是,中所示的函数使用的是 64 位类型xid8,它在一次安装的生命周期内不会回卷,必要时可以通过强制转换将其转换为xid。 + 但是,中所示的函数除 agemxid_agepg_get_multixact_members 外,使用的是 64 位类型xid8,它在一次安装的生命周期内不会回卷,必要时可以通过类型转换将其转换为xid。 数据类型pg_snapshot存储特定时刻事务ID可见性的信息。 其组成如所描述。pg_snapshot的文本表示形式是xmin:xmax:xip_list。 例如10:20:10,14,15表示xmin=10, xmax=20, xip_list=10, 14, 15。 @@ -22980,21 +21081,22 @@ SELECT collation for ('foo' COLLATE "de_DE"); xmin - 仍然处于活动状态的最低事务ID。所有小于xmin的事务 ID要么提交且可见,要么回滚并死亡。 + 仍然处于活动状态的最小事务 ID。所有小于xmin的事务 ID 要么已经提交且可见,要么已经回滚而失效。 xmax - 比最高完成的事务ID还高出一个值。所有大于或等于xmax的事务 ID到快照时还没有完成,因此不可见。 + 已完成事务中的最大事务 ID 加一。所有大于或等于xmax的事务 ID 在生成快照时尚未完成,因此不可见。 xip_list - 快照时正在进行的事务。一个事务ID为xmin <= X < xmax且不在快照时已经完成的列表中,因此根据其提交状态,该事务ID要么是可见的,要么是死的。此列表不包括子事务的事务 ID。 + 生成快照时正在进行的事务。满足xmin <= X < + xmax且不在此列表中的事务 ID 在生成快照时已经完成,因此根据其提交状态,要么可见,要么失效。此列表不包含子事务的事务 ID。 @@ -23179,7 +21281,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); roidentoid) - 返回事务的提交时间戳和复制起源。 + 返回事务的提交时间戳和复制源。 @@ -23195,7 +21297,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); roidentoid ) - 返回最近提交的事务的事务ID、提交时间戳和复制源头。 + 返回最近提交事务的事务 ID、提交时间戳和复制源。 @@ -23203,9 +21305,7 @@ SELECT collation for ('foo' COLLATE "de_DE");
- 中所展示的函数能打印initdb期间初始化的信息,例如目录版本。 - 它们也能显示有关预写式日志和检查点处理的信息。这些信息是集簇范围内的,不与任何特定的一个数据库相关。 - 这些函数提供大致相同的信息,对于同一种来源,就像应用。 + 中的函数显示在initdb期间初始化的信息,例如系统目录版本。它们也显示有关预写式日志和检查点处理的信息。这些信息适用于整个数据库集簇,而非某个特定数据库。这些函数与应用程序从相同来源提供大部分相同的信息。 @@ -23235,7 +21335,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); record - 返回有关当前检查点状态的信息, 如 所展示。 + 返回有关当前检查点状态的信息, 如 所展示。 @@ -23274,7 +21374,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); record - 返回有关恢复状态的信息,如 所展示。 + 返回有关恢复状态的信息,如 所展示。 @@ -23566,9 +21666,9 @@ SELECT collation for ('foo' COLLATE "de_DE"); - configuration - of the server - functions + 配置 + 服务器 + 函数 @@ -23605,7 +21705,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); text - 返回设置的setting_name的当前值。 + 返回设置setting_name的当前值。 如果没有这样的设置,current_setting将抛出一个错误,除非missing_ok被提供并且为true(在此情况下返回NULL)。 这个函数对应于SQL命令 @@ -23627,9 +21727,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); text - 将参数setting_name设置为new_value,并返回该值。 - 如果is_localtrue,新值将仅在当前事务期间应用。 - 如果您希望新值应用于当前会话的其余部分,请使用false代替。这个函数对应于SQL命令。 + 将参数setting_name设置为new_value,并返回该值。如果is_localtrue,新值仅在当前事务期间生效。如果希望新值在当前会话的剩余时间内生效,则使用false。此函数对应 SQL 命令 set_config('log_statement_stats', 'off', false) @@ -23652,7 +21750,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); - 在中展示的函数向其它服务器进程发送控制信号。默认情况下这些函数只能被超级用户使用,但是如果需要,可以利用GRANT把访问权限授予给其他用户。 + 在中展示的函数向其它服务器进程发送控制信号。默认情况下这些函数只能被超级用户使用,但是如果需要,可以利用GRANT把访问权限授予给其他用户(注明的例外除外)。 @@ -23687,7 +21785,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); 取消具有指定进程ID的后端进程的会话的当前查询。如果调用角色是被取消的后端进程所属角色的成员, - 或者调用角色具有pg_signal_backend的权限,则也允许执行此操作,但只有超级用户可以取消超级用户后端进程。 + 或者调用角色已被授予pg_signal_backend角色,则也允许执行此操作,但只有超级用户可以取消超级用户后端进程。 @@ -23700,11 +21798,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); boolean - 请求记录具有指定进程ID的后端的内存上下文。此函数可以将请求发送到后端和辅助进程,但不包括记录器。这些内存上下文将以 - LOG消息级别记录。它们将根据设置的日志配置出现在服务器日志中 - (有关更多信息,请参见), - 但无论如何都不会发送给客户端 - ()。 + 请求记录具有指定进程 ID 的后端进程的内存上下文。这些内存上下文将以LOG消息级别记录,并根据日志配置出现在服务器日志中(详见);无论如何设置,都不会发送给客户端。只有超级用户可以请求记录内存上下文。 @@ -23749,10 +21843,10 @@ SELECT collation for ('foo' COLLATE "de_DE"); boolean - 终止具有指定进程ID的后端进程的会话。如果调用角色是正在终止的后端的角色的成员,或者调用角色具有pg_signal_backend的权限,则也允许执行此操作,但只有超级用户才能终止超级用户后端。 + 终止具有指定进程ID的后端进程的会话。如果调用角色是正在终止的后端的角色的成员,或者调用角色已被授予pg_signal_backend角色,则也允许执行此操作,但只有超级用户才能终止超级用户后端。 - 如果未指定或超时timeout为零,则此函数无论进程是否实际终止,都将返回true,仅表示信号发送成功。如果指定了timeout(以毫秒为单位)且大于零,则函数将等待直到进程实际终止或直到给定时间已过。如果进程被终止,函数将返回true。在超时时,会发出警告并返回false。 + 如果未指定timeout或其值为零,则此函数无论进程是否实际终止,都将返回true,仅表示信号发送成功。如果指定了timeout(以毫秒为单位)且大于零,则函数将等待直到进程实际终止或直到给定时间已过。如果进程被终止,函数将返回true。在超时时,会发出警告并返回false @@ -23801,14 +21895,10 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 备份控制函数 - backup + 备份 - - 在中显示的函数有助于进行在线备份。 - 这些函数在恢复过程中无法执行(除了pg_start_backup、 - pg_stop_backuppg_wal_lsn_diff)。 - + 中列出的函数有助于进行在线备份。这些函数不能在恢复期间执行(非排他模式的 pg_start_backup、非排他模式的 pg_stop_backuppg_is_in_backuppg_backup_start_timepg_wal_lsn_diff 除外)。 有关正确使用这些函数的详细信息,参见。 @@ -23831,7 +21921,6 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 - @@ -23841,13 +21930,9 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 pg_lsn - 在预写式日志中创建一个命名标记记录,稍后可以将其用作恢复目标,并返回相应的预写日志位置。 - 然后可以将给定的名称与 一起使用,以指定进行恢复的点。 - 要避免创建多个名称相同的恢复点,因为恢复将在第一个名称与恢复目标匹配的恢复点停止。 + 在预写式日志中创建一条命名标记记录,供以后用作恢复目标,并返回相应的预写式日志位置。随后可以在中使用给定名称,指定恢复到哪一点。应避免创建多个同名恢复点,因为恢复会在第一个名称匹配恢复目标的恢复点停止。 - - 默认情况下,该函数仅限超级用户使用,但可以授权给其他用户执行该函数。 - + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -23859,7 +21944,7 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 pg_lsn - 返回当前预写式日志刷新位置(参见下面的说明)。 + 返回当前预写式日志刷盘位置(参见下文说明)。 @@ -23872,7 +21957,7 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 pg_lsn - 返回当前预式日志插入位置(参见下面的说明)。 + 返回当前预写式日志插入位置(参见下文说明)。 @@ -23885,7 +21970,7 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 pg_lsn - 返回当前预写式日志写位置(参见下面的说明)。 + 返回当前预写式日志写入位置(参见下文说明)。 @@ -23897,19 +21982,15 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 pg_start_backup ( labeltext, fast boolean - ) + , exclusive boolean + ) pg_lsn - 准备服务器开始在线备份。唯一必需的参数是备份的任意用户定义标签。 - (通常这将是备份转储文件存储的名称。) - 如果将可选的第二个参数指定为true, - 它将尽快执行pg_start_backup。这将强制立即进行检查点, - 这将导致I/O操作的激增,从而减慢任何同时执行的查询。 + 准备服务器开始在线备份。唯一必需的参数是用户任意指定的备份标签。(通常是备份转储文件将要保存的名称。)如果可选的第二个参数为true,则尽快执行pg_start_backup。这会强制立即执行检查点,使 I/O 操作量陡增,并降低并发执行的查询的速度。可选的第三个参数指定执行排他备份还是非排他备份(默认为排他备份)。 - - 默认情况下,此函数仅限于超级用户,但可以授予其他用户执行权限以运行该函数。 - + 在排他模式下使用时,该函数会将备份标签文件(backup_label)写入数据库集簇的数据目录;如果 pg_tblspc/ 目录中存在任何链接,还会写入表空间映射文件(tablespace_map)。然后它执行一次检查点,并返回备份开始时的预写式日志位置。(用户可以忽略此返回值,但仍会提供它以供需要时使用。)在非排他模式下,这些文件的内容由 pg_stop_backup 函数返回,用户应将其复制到备份区域。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -23918,41 +21999,58 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 pg_stop_backup pg_stop_backup ( - wait_for_archive boolean + exclusive boolean + , wait_for_archive boolean ) - record + setof record ( lsn pg_lsn, labelfile text, spcmapfile text ) + 结束排他或非排他的在线备份。exclusive 参数必须与先前调用 pg_start_backup 时的值一致。在排他备份中,pg_stop_backup 会移除由 pg_start_backup 创建的备份标签文件,以及表空间映射文件(如果存在)。在非排他备份中,这些文件所需的内容作为函数结果的一部分返回,应将其写入备份区域中的文件(而不是数据目录)。 - 完成在线备份。函数的结果中返回备份标签文件和表空间映射文件的期望内容,并必须写入备份区域的文件中。 - 这些文件不得写入实时数据目录(这样做将导致PostgreSQL在崩溃时无法重新启动)。 + 有一个boolean类型的可选第二参数。如果为 false,该函数会在备份完成后立即返回,不等待 WAL 归档。这种行为只适用于自行监控 WAL 归档的备份软件;否则,可能缺少使备份保持一致所需的 WAL,导致备份无法使用。默认情况下或该参数为 true 时,若已启用归档,pg_stop_backup会等待 WAL 归档。(在备库上,这意味着只有archive_mode = always时才会等待。如果主库的写入活动很少,可以在主库上运行pg_switch_wal,触发立即切换日志段。) - 有一个类型为boolean的可选参数。 - 如果为false,则在备份完成后立即返回,而无需等待WAL进行归档。 - 此行为仅适用于独立监视WAL归档的备份软件。否则,可能会缺少使备份一致所需的WAL,使备份无效。 - 默认情况下或当此参数为true时,pg_stop_backup将在启用归档时等待WAL进行归档。 - (在备库上,这意味着仅当archive_mode = always时才会等待。 - 如果主库上的写入活动较低,则可能有必要在主库上运行pg_switch_wal以触发立即段切换。) + 在主库上执行时,该函数还会在预写式日志归档区域创建备份历史文件。历史文件包括传给pg_start_backup的标签、备份的起止预写式日志位置以及备份的起止时间。记录结束位置后,当前预写式日志插入点会自动推进到下一个预写式日志文件,使包含结束位置的预写式日志文件可以立即归档,从而完成备份。 - - 在主库上执行时,此函数还会在预写式日志归档区域中创建一个备份历史文件。 - 历史文件包括给定给pg_start_backup的标签、备份的起始和结束预写式日志位置,以及备份的起始和结束时间。 - 在记录结束位置后,当前的预写式日志插入点会自动前进到下一个预写式日志文件,以便立即归档结束的预写式日志文件以完成备份。 + 该函数的结果是一条记录。lsn 列保存备份结束时的预写式日志位置(同样可以忽略)。结束排他备份时,第二列和第三列为 NULL;结束非排他备份时,它们保存标签文件和表空间映射文件所需的内容。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 + + + + + pg_stop_backup () + pg_lsn - - 函数的结果是一个记录。 - lsn列保存备份的结束预写式日志位置(可以忽略)。 - 第二列返回备份标签文件的内容,第三列返回表空间映射文件的内容。 - 这些必须作为备份的一部分存储,并作为恢复过程的一部分。 + 结束排他在线备份。这个简化版本等价于 pg_stop_backup(true, true),但只返回 pg_lsn 结果。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 + + + + + + pg_is_in_backup + + pg_is_in_backup () + boolean - 默认情况下,此函数仅限于超级用户,但可以授予其他用户EXECUTE权限来运行该函数。 + 如果正在进行在线排他备份,则返回 true。 + + + + pg_backup_start_time + + pg_backup_start_time () + timestamp with time zone + + 如果正在进行在线排他备份,返回其开始时间,否则返回 NULL + + @@ -23962,13 +22060,9 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 pg_lsn - 强制服务器切换到一个新的预写式日志文件,这允许对当前文件进行归档(假设你正在使用连续归档)。 - 其结果是在刚刚完成的预写式日志文件中结束预写式日志位置加1。 - 如果自从上次预写式日志切换以来没有提前写日志活动,pg_switch_wal将不做任何操作,并返回当前正在使用的提前写日志文件的起始位置。 + 强制服务器切换到新的预写式日志文件,使当前文件可以归档(假设正在使用连续归档)。返回值是刚完成的预写式日志文件中的结束预写式日志位置加 1。如果自上次切换预写式日志以来没有发生任何预写式日志活动,pg_switch_wal不执行任何操作,并返回当前使用的预写式日志文件的起始位置。 - - 默认情况下该函数仅限超级用户使用,但可以授权其他用户执行该函数。 - + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -23980,7 +22074,7 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 text - 将预写式日志位置转换为保持该位置的WAL文件的名称。 + 将预写式日志位置转换为包含该位置的 WAL 文件的名称。 @@ -24008,35 +22102,22 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 numeric - 计算两个预写式日志位置之间的字节(lsn1 - lsn2)差异。 - 这可以与pg_stat_replication中所示的一些函数一起使用,以获得复制延迟。 + 计算两个预写式日志位置之间的字节差(lsn1 - lsn2)。可以将它与pg_stat_replication中的某些函数配合使用,以获取复制延迟。
- - pg_current_wal_lsn 显示当前预写式日志写位置,与上述函数所用的格式相同。 - 类似地,pg_current_wal_insert_lsn显示当前预写式日志插入位置,pg_current_wal_flush_lsn显示当前预写式日志刷新位置。 - 插入位置是预写式日志在任何时刻的逻辑(logical) 结束,而写位置是已经从服务器内部缓冲区实际写入的内容的结束,而刷新位置是已知的要写入持久化存储的最后一个位置。 - 写位置是可以从服务器外部检查的最后位置,如果你对归档部分完成的预写式日志文件感兴趣,那么它通常就是你想要的位置。 - 插入和刷新位置主要用于服务器调试目的。这些都是只读操作,不需要超级用户权限。 - + pg_current_wal_lsn 显示当前预写式日志写入位置,格式与上述函数相同。类似地,pg_current_wal_insert_lsn 显示当前预写式日志插入位置,pg_current_wal_flush_lsn 显示当前预写式日志刷盘位置。插入位置是预写式日志在任意时刻的逻辑末尾;写入位置是实际从服务器内部缓冲区写出的内容的末尾;刷盘位置则是已知已经写入持久存储的最后位置。写入位置是能从服务器外部检查到的内容的末尾,如果要归档尚未写满的预写式日志文件,通常需要这个位置。插入位置和刷盘位置主要用于服务器调试。这些都是只读操作,不需要超级用户权限。 - - 您可以使用pg_walfile_name_offsetpg_lsn值中提取相应的预写式日志文件名和字节偏移量。例如: - -postgres=# SELECT * FROM pg_walfile_name_offset((pg_stop_backup()).lsn); + 可以使用pg_walfile_name_offset从一个pg_lsn值中提取相应的预写式日志文件名和字节偏移量。例如: +postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); file_name | file_offset --------------------------+------------- 00000001000000000000000D | 4039624 (1 row) - - 类似地,pg_walfile_name仅提取预写式日志文件名。 - 当给定的预写式日志位置恰好位于预写式日志文件边界时,这两个函数都会返回前一个预写式日志文件的名称。 - 这通常是管理预写式日志归档行为的期望行为,因为前一个文件是当前需要归档的最后一个文件。 - +类似地,pg_walfile_name仅提取预写式日志文件名。当指定的预写式日志位置恰好位于预写式日志文件边界时,这两个函数都返回前一个预写式日志文件的名称。这通常正是管理预写式日志归档时所需的行为,因为前一个文件是当前需要归档的最后一个文件。
@@ -24089,9 +22170,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_stop_backup()).lsn); pg_lsn - 返回已接收并通过流复制同步到磁盘的最后一个预写式日志位置。 - 当流复制正在进行时这将单调地增加。如果恢复已经完成,那么在恢复期间,接收到的最后一条WAL记录的位置将保持静态,并同步到磁盘。 - 如果流复制已禁用,或者尚未启动,函数将返回NULL。 + 返回流复制最近接收并同步到磁盘的预写式日志位置。在流复制进行期间,该值单调增加。如果恢复已完成,该值将保持为恢复期间最后接收并同步到磁盘的 WAL 记录的位置。如果禁用了流复制,或者流复制尚未开始,此函数返回 NULL @@ -24104,8 +22183,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_stop_backup()).lsn); pg_lsn - 返回恢复期间重新播放的最后一个预写式日志位置。如果恢复仍在进行中这将会单调地增加。 - 如果恢复已经完成,那么恢复期间应用的最后WAL记录的位置将保持静态。当服务器正常启动且没有恢复时,函数返回NULL。 + 返回恢复期间最近重放的预写式日志位置。如果恢复仍在进行,该值单调增加。如果恢复已完成,该值将保持为该次恢复期间最后应用的 WAL 记录的位置。如果服务器未经恢复而正常启动,此函数返回 NULL @@ -24118,34 +22196,16 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_stop_backup()).lsn); timestamp with time zone - 返回恢复期间重放的最后一个事务的时间戳。这是在主库上为该事务生成提交或中止 WAL记录的时间。 - 如果在恢复期间没有重放任何事务,该函数将返回NULL。否则,如果恢复仍在进行中,这将单调地增加。 - 如果恢复已经完成,那么在恢复期间应用最后一个事务时,这将会保持静态。 - 当服务器正常启动且没有恢复时,函数返回NULL。 + 返回恢复期间最近重放事务的时间戳,即该事务的提交或中止 WAL 记录在主库上生成的时间。如果恢复期间尚未重放任何事务,此函数返回 NULL。否则,如果恢复仍在进行,该值单调增加。如果恢复已完成,该值将保持为该次恢复期间最后应用的事务的时间戳。如果服务器未经恢复而正常启动,此函数返回 NULL - - - - pg_get_wal_resource_managers - - pg_get_wal_resource_managers () - setof record - ( rm_id integer, - rm_name text, - rm_builtin boolean ) - - - 返回系统中当前加载的 WAL 资源管理器。列rm_builtin指示它是内置资源管理器还是由扩展加载的自定义资源管理器。 - - - 控制恢复进度的功能如 所示。这些函数只能在恢复过程中执行。 + 列出的函数用于控制恢复进度。这些函数只能在恢复期间执行。 @@ -24175,7 +22235,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_stop_backup()).lsn); boolean - 如果请求了恢复暂停了则返回真。 + 如果已请求暂停恢复,则返回真。 @@ -24189,7 +22249,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_stop_backup()).lsn); 返回恢复暂停状态。 - 如果没有请求pause,返回值是not paused,如果请求暂停但恢复还没有暂停,返回值是pause requested,如果恢复实际已经暂停,返回值是paused。 + 如果没有请求暂停,返回值是not paused,如果请求暂停但恢复还没有暂停,返回值是pause requested,如果恢复实际已经暂停,返回值是paused @@ -24203,11 +22263,11 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_stop_backup()).lsn); 将备库提升为主库状态。 - 当wait设置为true(默认值)时,函数将等待直到升级完成或wait_seconds秒数已过,如果升级成功则返回true,否则返回false。 - 如果wait设置为false,则该函数在向postmaster发送SIGUSR1信号以触发升级后立即返回true。 + 当wait设置为true(默认值)时,函数将等待直到提升完成或wait_seconds秒数已过,如果提升成功则返回true,否则返回false。 + 如果wait设置为false,则该函数在向postmaster发送SIGUSR1信号以触发提升后立即返回true - 默认情况下这个函数仅限超级用户使用,但可以授权给其他用户执行该函数。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -24228,7 +22288,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_stop_backup()).lsn); 如果热备是激活的,所有新查询将看到相同的一致的数据库快照,并且在恢复继续之前不会生成进一步的查询冲突。 - 默认情况下该函数仅限超级用户使用,但可以授权其他用户执行该函数。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -24244,7 +22304,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_stop_backup()).lsn); 如果暂停了,则重新启动恢复。 - 默认情况下该函数仅限超级用户使用,但可以授权其他用户执行该函数。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -24252,8 +22312,8 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_stop_backup()).lsn);
- pg_wal_replay_pausepg_wal_replay_resume不能在提升(promotion)进行时执行。 - 如果在恢复暂停时触发了提升(promotion),则暂停状态结束,升级继续进行。 + pg_wal_replay_pausepg_wal_replay_resume不能在提升进行时执行。 + 如果在恢复暂停时触发了提升,则暂停状态结束,提升继续进行。 @@ -24272,7 +22332,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_stop_backup()).lsn); - 为了解决这个问题,PostgreSQL允许一个事务导出它正在使用的快照。只要导出的事务仍然保持打开,其他事务可以导入它的快照,并且因此可以保证它们可以看到和第一个事务看到的完全一样的数据库视图。但是注意这些事务中的任何一个对数据库所作的更改对其他事务仍然保持不可见,和未提交事务所作的修改一样。因此这些事务是针对以前存在的数据同步,而对由它们自己所作的更改则采取正常的动作。 + 为了解决这个问题,PostgreSQL允许一个事务导出它正在使用的快照。只要导出快照的事务仍然保持打开,其他事务可以导入它的快照,并且因此可以保证它们可以看到和第一个事务看到的完全一样的数据库视图。但是注意这些事务中的任何一个对数据库所作的更改对其他事务仍然保持不可见,和未提交事务所作的修改一样。因此这些事务是针对以前存在的数据同步,而对由它们自己所作的更改则采取正常的动作。 @@ -24312,7 +22372,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_stop_backup()).lsn); 如果需要的话,一个事务可以导出多个快照。 请注意,这样做仅在READ COMMITTED事务中有用,因为在REPEATABLE READ和更高的隔离级别中,事务在它们的生命周期中使用相同的快照。 - 一旦事务导出了快照,它就不能用 进行准备。 + 一旦事务导出了快照,它就不能用 进行预备。 @@ -24328,7 +22388,6 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_stop_backup()).lsn); 中展示的函数用于控制以及与复制特性交互。 有关底层特性的信息请见以及。 - 复制原点函数的使用仅限于超级用户。 默认只允许超级用户使用复制源的函数,但可以通过GRANT命令允许其他用户使用。 复制槽的函数只限于超级用户和拥有REPLICATION权限的用户。 @@ -24374,12 +22433,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_stop_backup()).lsn); lsn pg_lsn ) - 创建一个新的名为slot_name的物理复制槽。 - 第二个参数是可选的,当它为true时,立即为这个物理槽指定要被保留的LSN。 - 否则该LSN会被保留在来自一个流复制客户端的第一个连接上。 - 来自一个物理槽的更改只能通过流复制协议进行流式传输 — 见。 - 当可选的第三参数temporary被设置为真时,指定那个槽不会被持久地存储在磁盘上并且仅对当前会话的使用有意义。 - 临时槽也会在发生任何错误时被释放。这个函数对应于复制协议命令CREATE_REPLICATION_SLOT ... PHYSICAL。 + 创建名为 slot_name 的新物理复制槽。可选的第二个参数为 true 时,指定立即为此复制槽保留 LSN;否则在流复制客户端首次连接时保留 LSN。从物理槽流式传输更改只能使用流复制协议 — 参见。可选的第三个参数 temporary 为真时,指定该槽不永久存储到磁盘,且仅供当前会话使用。发生任何错误时,临时槽也会被释放。此函数对应复制协议命令 CREATE_REPLICATION_SLOT ... PHYSICAL @@ -24392,9 +22446,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_stop_backup()).lsn); void - 丢弃名为slot_name的物理或逻辑复制槽。 - 和复制协议命令DROP_REPLICATION_SLOT相同。对于逻辑槽, - 在连接到在其中创建该槽的同一个数据库时,必须调用这个函数。 + 删除名为slot_name的物理或逻辑复制槽。与复制协议命令DROP_REPLICATION_SLOT相同。 @@ -24403,13 +22455,13 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_stop_backup()).lsn); pg_create_logical_replication_slot - pg_create_logical_replication_slot ( slot_name name, plugin name , temporary boolean, twophase boolean, failover boolean ) + pg_create_logical_replication_slot ( slot_name name, plugin name , temporary boolean, twophase boolean ) record ( slot_name name, lsn pg_lsn ) - 创建一个名为slot_name的新逻辑(解码)复制插槽,使用输出插件plugin。可选的第三个参数temporary,当设置为true时,指定插槽不应永久存储到磁盘,仅供当前会话使用。临时插槽也会在任何错误发生时释放。可选的第四个参数twophase,当设置为true时,指定为此插槽启用已准备事务的解码。可选的第五个参数failover,当设置为true时,指定启用此插槽同步到备库,以便在故障切换后可以恢复逻辑复制。调用此函数的效果与复制协议命令CREATE_REPLICATION_SLOT ... LOGICAL相同。 + 创建一个名为slot_name的新逻辑(解码)复制槽,使用输出插件plugin。可选的第三个参数temporary,当设置为真时,指定槽不应永久存储到磁盘,仅供当前会话使用。临时槽也会在任何错误发生时释放。可选的第四个参数twophase,当设置为真时,指定为此槽启用预备事务的解码。调用此函数的效果与复制协议命令CREATE_REPLICATION_SLOT ... LOGICAL相同。 @@ -24425,7 +22477,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_stop_backup()).lsn); 将一个名为src_slot_name的现有物理复制槽复制到一个名为dst_slot_name的物理复制槽。 - 被复制的物理槽开始从与源槽相同的LSN开始保留WAL。temporary是可选的。 + 复制后的物理槽从与源槽相同的LSN开始保留WAL。temporary是可选的。 如果省略了temporary,则使用与源槽相同的值。 @@ -24441,7 +22493,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_stop_backup()).lsn); lsn pg_lsn ) - 复制一个名为src_slot_name的现有逻辑复制槽到一个名为dst_slot_name的逻辑复制槽,选择性的改变输出插件和持久性。 + 复制一个名为src_slot_name的现有逻辑复制槽到一个名为dst_slot_name的逻辑复制槽,可选地更改输出插件和持久性。 被复制的逻辑槽从与源逻辑槽相同的LSN开始。temporaryplugin都是可选的。 如果它们被省略了,使用与源逻辑槽相同的值。 @@ -24459,11 +22511,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_stop_backup()).lsn); data text ) - 返回槽slot_name中的改变,从最后一次使用更改的点开始。 - 如果upto_lsnupto_nchanges为 NULL,逻辑解码将一直继续到 WAL 的末尾。 - 如果upto_lsn为非 NULL,解码将只包括那些在指定 LSN 之前提交的事务。 - 如果upto_nchanges为非 NULL,解码将在其产生的行数超过指定值后停止。 - 不过要注意,被返回的实际行数可能更大,因为对这个限制的检查只会在增加了解码每个新的提交事务产生的行之后进行。 + 返回槽 slot_name 中自上次消费更改的位置起的更改。如果 upto_lsnupto_nchanges 都为 NULL,逻辑解码会持续到 WAL 末尾。如果 upto_lsn 非 NULL,解码仅包含在指定 LSN 之前提交的事务。如果 upto_nchanges 非 NULL,解码产生的行数超过指定值时就会停止。不过,实际返回行数可能更大,因为只有在添加完对每个新事务提交进行解码所产生的行后,才会检查此限制。 @@ -24528,9 +22576,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_stop_backup()).lsn); end_lsn pg_lsn ) - 将复制槽的当前确认的位置提前到名为slot_name的复制槽的当前确认位置。 - 该槽不会向后移动,也不会移动到当前插入位置之外。返回该槽的名称和它被推进到的真实位置。 - 如果有任何进展,则在下一个检查点中写出更新后的槽位置信息。所以如果发生崩溃,该槽位可能会返回到之前的位置。 + 推进名为 slot_name 的复制槽当前已确认的位置。该槽不会后退,也不会越过当前插入位置。返回槽名及其实际推进到的位置。如果发生了推进,更新后的槽位置信息会在下一个检查点写出。因此,发生崩溃时,槽可能回到更早的位置。 @@ -24582,8 +22628,8 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_stop_backup()).lsn); void - 将当前会话标记为从给定的原点回放,从而允许跟踪回放进度。 - 只能在当前没有选择原点时使用。使用pg_replication_origin_session_reset 命令来撤销。 + 将当前会话标记为从给定的复制源重放,从而允许跟踪重放进度。 + 只能在当前没有选择复制源时使用。使用pg_replication_origin_session_reset来撤销。 @@ -24622,7 +22668,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_stop_backup()).lsn); pg_lsn - 返回当前会话中选择的复制源的重放位置。参数flush决定对应的本地事务是否被确保已经刷入磁盘。 + 返回当前会话中选择的复制源的重放位置。参数flush决定是否保证对应的本地事务已刷盘。 @@ -24676,7 +22722,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_stop_backup()).lsn); pg_lsn - 返回给定复制元的重放位置。参数flush决定对应的本地事务是否被确保已经刷入磁盘。 + 返回给定复制源的重放位置。参数flush决定是否保证对应的本地事务已刷盘。 @@ -24693,11 +22739,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_stop_backup()).lsn); pg_lsn - 发出逻辑解码消息。这可以用于通过WAL将通用消息传递给逻辑解码插件。 - transactional参数指定消息是否应该是当前事务的一部分, - 还是应该立即写入并在逻辑解码器读取记录时立即解码。 - prefix参数是一个文本前缀,逻辑解码插件可以使用它轻松识别对它们有趣的消息。 - content参数是消息的内容,可以以文本或二进制形式给出。 + 发出逻辑解码消息。这可用于通过 WAL 向逻辑解码插件传递通用消息。transactional 参数指定消息是作为当前事务的一部分,还是立即写入并在逻辑解码器读到该记录时立即解码。prefix 参数是一个文本前缀,便于逻辑解码插件识别其关注的消息。content 参数是消息内容,可以文本或二进制形式给出。 @@ -24776,7 +22818,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_stop_backup()).lsn); 计算具有指定名称或OID的数据库使用的总磁盘空间。要使用此函数,您必须对指定数据库具有CONNECT权限 - (默认情况下授予),或者具有pg_read_all_stats角色的权限。 + (默认情况下授予),或者是pg_read_all_stats角色的成员。 @@ -24802,13 +22844,13 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_stop_backup()).lsn); bigint - 计算指定关系的一个fork所使用的磁盘空间。 - (注意在大多数情况下,使用更高级的函数 pg_total_relation_sizepg_table_size更方便,它们将所有分叉(forks)的大小相加。) - 使用一个参数,这将返回关系的主数据分叉的大小。第二个参数可以用来指定要检查哪个分叉: + 计算指定关系的一个分支所使用的磁盘空间。 + (注意在大多数情况下,使用更高级的函数 pg_total_relation_sizepg_table_size更方便,它们将所有分支的大小相加。) + 使用一个参数,这将返回关系的主数据分支的大小。第二个参数可以用来指定要检查哪个分支: - main返回关系的主数据分叉的大小。 + main返回关系的主数据分支的大小。 @@ -24823,7 +22865,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_stop_backup()).lsn); - init 返回初始化分叉的大小,如果有的话,与关系相关。 + init 返回与该关系关联的初始化分支(如有)的大小。 @@ -24839,7 +22881,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_stop_backup()).lsn); bigint - 将人可阅读的格式的大小(由pg_size_pretty返回)转换为字节。 + 将人类可读格式的大小(由pg_size_pretty返回)转换为字节。 @@ -24856,7 +22898,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_stop_backup()).lsn); text - 将字节大小转换为更易于人类阅读的格式,带有大小单位(字节,kB,MB,GB,TB或PB)。请注意,单位是2的幂,而不是10的幂,因此1kB是1024字节, + 将字节大小转换为更易于人类阅读的格式,带有大小单位(字节,kB,MB,GB或TB)。请注意,单位是2的幂,而不是10的幂,因此1kB是1024字节, 1MB是10242 = 1048576字节,依此类推。 @@ -24870,7 +22912,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_stop_backup()).lsn); bigint - 计算指定表所使用的磁盘空间,不包括索引(但包括它的TOAST表,如果有的话,空闲空间映射,以及可见性映射)。 + 计算指定表所使用的磁盘空间,不包括索引(但包括其 TOAST 表(如有)、空闲空间映射和可见性映射)。 @@ -24889,7 +22931,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_stop_backup()).lsn); 计算具有指定名称或OID的表空间中使用的总磁盘空间。 要使用此函数,您必须对指定的表空间具有CREATE权限, - 或者具有pg_read_all_stats角色的权限, + 或者是pg_read_all_stats角色的成员, 除非它是当前数据库的默认表空间。 @@ -24904,7 +22946,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_stop_backup()).lsn); 计算指定表所使用的总磁盘空间,包括所有索引和TOAST数据。 - 结果等价pg_table_size + pg_indexes_size。 + 结果等价于pg_table_size + pg_indexes_size @@ -24912,11 +22954,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_stop_backup()).lsn); - 上述操作表和索引的函数接受一个regclass参数,它是该表或索引在pg_class系统目录中的 OID。 - 你不必手工去查找该 OID,因为regclass数据类型的输入转换器会为你代劳。 - 只写包围在单引号内的表名,这样它看起来像一个文字常量。 - 为了与普通SQL名称的处理相兼容,该字符串将被转换为小写形式,除非其中在表名周围包含双引号。 - 详见。 + 上述操作表和索引的函数接受一个regclass参数,即该表或索引在pg_class系统目录中的 OID。不必手工查找该 OID,因为regclass数据类型的输入转换器会代为查找。详见 @@ -24950,7 +22988,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_stop_backup()).lsn); oid - 返回当前分配给指定关系的filenode数字。文件节点是用于该关系的文件名称的基本组件(更多信息请参阅 )。 + 返回当前分配给指定关系的文件结点编号。文件结点是用于该关系的文件名称的基本组件(更多信息请参阅 )。 对于大多数关系,其结果与pg_class.relfilenode相同,但对于某些系统目录,relfilenode为0,并且必须使用这个函数来获得正确的值。 如果传递的是一个没有存储的关系,例如一个视图,那么函数将返回NULL。 @@ -24965,7 +23003,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_stop_backup()).lsn); text - 返回关系的完整文件路径名称(相对于数据库集簇的数据目录,即关系的PGDATA)。 + 返回关系的完整文件路径名称(相对于数据库集簇的数据目录,即PGDATA)。 @@ -24978,8 +23016,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_stop_backup()).lsn); regclass - 返回一个给定表空间OID和存储它的文件节点的关系的OID。这本质上是pg_relation_filepath的反向映射。 - 对于数据库默认表空间中的关系,表空间可以指定为0。如果当前数据库中没有与给定值相关联的关系,则返回 NULL。 + 根据关系所在表空间的 OID 和文件结点返回该关系的 OID。这本质上是pg_relation_filepath的反向映射。对于数据库默认表空间中的关系,表空间可以指定为 0。如果当前数据库中没有与给定值关联的关系,或者该关系是临时关系,则返回NULL @@ -25023,19 +23060,6 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_stop_backup()).lsn); - - - - pg_database_collation_actual_version - - pg_database_collation_actual_version ( oid ) - text - - - 返回数据库当前在操作系统中安装的排序规则的实际版本。如果这与pg_database.datcollversion中的值不同,则依赖于排序规则的对象可能需要重新构建。 - 参见。 - - @@ -25046,181 +23070,20 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_stop_backup()).lsn); integer - 基于在操作系统中找到的所有区域环境(locales),加入排序规则到系统目录pg_collation中。 - 这是 initdb 会用到的,更多细节请参考。 - 如果后来在操作系统上安装了额外的区域环境,可以再次运行这个函数加入新区域环境的排序规则。 - 匹配pg_collation中现有条目的区域环境将被跳过(但是这个函数不会移除以在操作系统中不再存在的区域环境为基础的排序规则对象)。 - schema参数通常是pg_catalog,但这并非强制要求,排序规则也可以安装到其他模式中。 - 该函数返回其创建的新排序规则对象的数量。 - 此函数仅限超级用户使用。 + 根据操作系统中找到的所有区域设置,向系统目录pg_collation添加排序规则。 + initdb使用的就是此函数;更多信息见。 + 如果以后在操作系统中安装了其他区域设置,可以再次运行此函数,为新区域设置添加排序规则。 + 与pg_collation中现有条目匹配的区域设置会被跳过。 + (但此函数不会删除基于操作系统中已不存在的区域设置的排序规则对象。) + schema参数通常为pg_catalog,但并非必须如此;也可以将排序规则安装到其他模式中。 + 函数返回新建的排序规则对象数量。此函数仅限超级用户使用。 - - 列出用于操纵统计信息的函数。 - 这些函数不能在恢复期间执行。 - - - 由这些统计信息操纵函数所做的更改可能会被autovacuum(或手动 - VACUUMANALYZE)覆盖,应视为临时性的。 - - - - - - 数据库对象统计信息操纵函数 - - - - - 函数 - - - 描述 - - - - - - - - - pg_restore_relation_stats - - pg_restore_relation_stats ( - VARIADIC kwargs "any" ) - boolean - - - 更新表级统计信息。通常这些统计信息由自动收集或作为的一部分更新,因此不必调用此函数。但它在恢复后很有用,可以在尚未运行ANALYZE时帮助优化器选择更好的计划。 - - - 被跟踪的统计信息可能因版本而异,所以参数以argnameargvalue对的形式传递: - -SELECT pg_restore_relation_stats( - 'arg1name', 'arg1value'::arg1type, - 'arg2name', 'arg2value'::arg2type, - 'arg3name', 'arg3value'::arg3type); - - - - 例如,要设置表mytablerelpagesreltuples值: - -SELECT pg_restore_relation_stats( - 'schemaname', 'myschema', - 'relname', 'mytable', - 'relpages', 173::integer, - 'reltuples', 10000::real); - - - - 参数schemanamerelname是必需的,用于指定表。其他参数是与pg_class中某些列对应的统计信息的名称和值。当前支持的关系统计信息包括:integer类型的relpagesreal类型的reltuplesinteger类型的relallvisible以及integer类型的relallfrozen。 - - - 此外,此函数还接受integer类型的参数名version,指定统计信息来源的服务器版本。这有助于从旧版本的PostgreSQL移植统计信息。 - - - 次要错误会以WARNING报告并被忽略,其余统计信息仍将被恢复。如果所有指定的统计信息都成功恢复,则返回true,否则返回false。 - - - 调用者必须对该表拥有MAINTAIN权限或者是数据库的所有者。 - - - - - - - - - pg_clear_relation_stats - - pg_clear_relation_stats ( schemaname text, relname text ) - void - - - 清除给定关系的表级统计信息,就像该表是新创建的一样。 - - - 调用者必须对该表拥有MAINTAIN权限或者是数据库的所有者。 - - - - - - - - pg_restore_attribute_stats - - pg_restore_attribute_stats ( - VARIADIC kwargs "any" ) - boolean - - - 创建或更新列级统计信息。通常这些统计信息由自动收集或作为的一部分更新,因此不必调用此函数。但它在恢复后很有用,可以在尚未运行ANALYZE时帮助优化器选择更好的计划。 - - - 被跟踪的统计信息可能因版本而异,所以参数以argnameargvalue对的形式传递: - -SELECT pg_restore_attribute_stats( - 'arg1name', 'arg1value'::arg1type, - 'arg2name', 'arg2value'::arg2type, - 'arg3name', 'arg3value'::arg3type); - - - - 例如,要设置表mytable的属性col1avg_widthnull_frac值: - -SELECT pg_restore_attribute_stats( - 'schemaname', 'myschema', - 'relname', 'mytable', - 'attname', 'col1', - 'inherited', false, - 'avg_width', 125::integer, - 'null_frac', 0.5::real); - - - - 必需的参数包括:text类型的schemanamerelname,用于指定表;text类型的attnamesmallint类型的attnum,用于指定列;以及inherited,指定统计信息是否包含来自子表的值。其他参数是与pg_stats中的列对应的统计信息的名称和值。 - - - 此外,此函数还接受integer类型的参数名version,指定统计信息来源的服务器版本。这有助于从旧版本的PostgreSQL移植统计信息。 - - - 次要错误会以WARNING报告并被忽略,其余统计信息仍将被恢复。如果所有指定的统计信息都成功恢复,则返回true,否则返回false。 - - - 调用者必须对该表拥有MAINTAIN权限或者是数据库的所有者。 - - - - - - - - pg_clear_attribute_stats - - pg_clear_attribute_stats ( - schemaname text, - relname text, - attname text, - inherited boolean ) - void - - - 清除给定关系和属性的列级统计信息,就像该表是新创建的一样。 - - - 调用者必须对该表拥有MAINTAIN权限或者是数据库的所有者。 - - - - - -
列出提供有关分区表结构信息的函数。 @@ -25294,7 +23157,7 @@ SELECT pg_restore_attribute_stats( - 例如,要检查分区表measurement中包含的数据的总大小,可以使用以下查询: + 例如,要检查分区表measurement中包含的数据的总大小,可以使用以下查询: SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size FROM pg_partition_tree('measurement'); @@ -25309,7 +23172,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size 显示了索引维护任务可以使用的函数。 - (注意,这些维护任务通常由自动清理(autovacuum)自动完成;只有在特殊情况下才需要使用这些函数。) + (注意,这些维护任务通常由 autovacuum 自动完成;只有在特殊情况下才需要使用这些函数。) 这些函数在恢复过程中无法执行。这些函数的使用局限于超级用户和给定索引的所有者。 @@ -25340,7 +23203,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size integer - 扫描指定的BRIN索引以查找基表中当前尚未生成索引摘要的页面范围; + 扫描指定的BRIN索引以查找基表中当前尚未生成索引摘要的页面范围; 对于任何这样的范围,它都通过扫描这些表页来创建一个新的摘要索引元组。 返回插入到索引中的新页面范围摘要的数量。 @@ -25356,7 +23219,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size 对覆盖给定块的页面范围执行摘要(如果尚未摘要)。 - 这类似于brin_summarize_new_values,只是它只处理覆盖给定表块数的页范围。 + 这类似于brin_summarize_new_values,区别在于它只处理包含给定表块编号的页面范围。 @@ -25382,9 +23245,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size bigint - 清理指定GIN索引的pending列表,通过移除里面的条目,以大批的方式,到主要的GIN数据结构。 - 返回从挂起列表中删除的页数。如果参数是使用禁用fastupdate选项构建的GIN索引,则不会发生清理,结果为零,因为索引没有挂起的列表。 - 关于挂起列表和fastupdate选项的详细信息,请参见。 + 将指定 GIN 索引的待处理列表中的条目批量移入主 GIN 数据结构,从而清理该列表。返回从待处理列表中移除的页数。如果参数是禁用fastupdate选项构建的 GIN 索引,则不会进行清理,结果为零,因为该索引没有待处理列表。有关待处理列表和fastupdate选项的详细信息,参见 @@ -25399,21 +23260,16 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size 中展示的函数提供了对数据库服务器所在机器上的文件的本地访问。 - 只能访问数据库集簇目录以及log_directory中的文件,除非用户是超级用户或者被授予了角色pg_read_server_files。 + 只能访问数据库集簇目录以及log_directory中的文件,除非用户是超级用户或者被授予了角色pg_read_server_files。 使用相对路径访问集簇目录里面的文件,以及匹配 log_directory配置设置的路径访问日志文件。 - 注意在pg_read_file()或者相关函数上,向用户授予EXECUTE权限, - 以允许他们有能力读取服务器上该数据库服务器进程能读取的任何文件;这些函数会绕过所有的数据库内权限检查。 - 这意味着,例如,具有这种访问的用户能够读取pg_authid表中存储着认证信息的内容,也能读取数据库中的任何表数据。 - 因此,授予对这些函数的访问应该要很仔细地考虑。 + 注意,向用户授予pg_read_file()或相关函数的 EXECUTE 权限,会使其能够读取服务器上数据库服务器进程能读取的任何文件;这些函数会绕过数据库内部的所有权限检查。例如,具有这种访问权限的用户能够读取存储认证信息的pg_authid表的内容,以及数据库中的任何表数据。因此,授予这些函数的访问权限时应仔细考虑。 - 这些函数中的一些函数有可选的missing_ok参数,可以指定当文件或目录不存在时的行为。 - 如果为true,函数返回NULL或着空结果集,根据适合情况。 - 如果为false,会产生一个错误。默认为false。 + 这些函数中的一些函数接受可选的missing_ok参数,用于指定文件或目录不存在时的行为。如果为true,函数会视情况返回NULL或空结果集。如果为false,则会报错。默认为false @@ -25443,12 +23299,12 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size setof text - 返回指定目录中所有文件(和目录以及其他指定文件)的名称。 - include_dot_dirs参数标示在结果集中是否包括...;默认为不包括它们。 - 要包括它们在missing_oktrue时能够有用,以从不存在的目录中辨别一个空目录。 + 返回指定目录中所有文件的名称(包括目录及其他特殊文件)。 + include_dot_dirs参数指示结果集中是否包含...;默认不包含它们。 + 在missing_oktrue时,包含它们有助于区分不存在的目录和空目录。 - 这个函数默认限制为超级用户,但是其他用户可以被授予EXECUTE以运行此函数。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -25467,7 +23323,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size 返回服务器日志目录中每个普通文件的名称、大小和最后修改时间(mtime)。以点开头的文件名、目录和其他特殊文件将被排除。 - 默认情况下,此函数仅限于超级用户和具有pg_monitor角色权限的角色,但其他用户可以被授予EXECUTE权限来运行该函数。 + 默认情况下,此函数仅限超级用户和pg_monitor角色的成员使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -25487,70 +23343,12 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size 以点开头的文件名、目录和其他特殊文件将被排除。 - 默认情况下,此函数仅限于超级用户和具有pg_monitor角色权限的角色, - 但其他用户可以被授予EXECUTE权限来运行该函数。 + 默认情况下,此函数仅限超级用户和pg_monitor角色的成员使用,但可以向其他用户授予EXECUTE权限以运行它。 - - - - pg_ls_logicalmapdir - - pg_ls_logicalmapdir () - setof record - ( name text, - size bigint, - modification timestamp with time zone ) - - - 返回服务器的pg_logical/mappings目录中每个普通文件的名称、大小和最后修改时间(mtime)。 - 以点开头的文件名、目录和其他特殊文件将被排除。 - - - 默认情况下,此函数仅限于超级用户和pg_monitor角色的成员,但其他用户可以被授予EXECUTE权限来运行该函数。 - - - - - - pg_ls_logicalsnapdir - - pg_ls_logicalsnapdir () - setof record - ( name text, - size bigint, - modification timestamp with time zone ) - - - 返回服务器的pg_logical/snapshots目录中每个普通文件的名称、大小和最后修改时间(mtime)。 - 以点开头的文件名、目录和其他特殊文件将被排除。 - - - 默认情况下,此函数仅限于超级用户和pg_monitor角色的成员,但其他用户可以被授予EXECUTE权限来运行该函数。 - - - - - - pg_ls_replslotdir - - pg_ls_replslotdir ( slot_name text ) - setof record - ( name text, - size bigint, - modification timestamp with time zone ) - - - 返回服务器的pg_replslot/slot_name目录中每个普通文件的名称、大小和最后修改时间(mtime), - 其中slot_name是作为函数输入提供的复制槽的名称。以点开头的文件名、目录和其他特殊文件将被排除。 - - - 默认情况下,此函数仅限于超级用户和pg_monitor角色的成员,但其他用户可以被授予EXECUTE权限来运行该函数。 - - @@ -25564,11 +23362,11 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size modification timestamp with time zone ) - 返回服务器的WAL归档状态目录(pg_wal/archive_status)中的每个普通文件的名称、大小、和最后修改时间(mtime)。 - 文件名以一个点(dot)开始,目录和其他指定的文件不包括。 + 返回服务器 WAL 归档状态目录(pg_wal/archive_status)中每个普通文件的名称、大小和最后修改时间(mtime)。 + 以点号开头的文件名、目录以及其他特殊文件都不会包含在结果中。 - 这个函数默认限制在超级用户和pg_monitor角色的成员,但是其他用户可以被授予EXECUTE以运行此函数。 + 默认情况下,此函数仅限超级用户和pg_monitor角色的成员使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -25585,12 +23383,12 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size modificationtimestamp with time zone ) - 返回针对指定tablespace的临时文件目录中的每个普通文件的名称、大小、和最后修改时间(mtime)。 - 如果tablespace没有提供,pg_default 表空间为被检验的。 - 文件名以一个点(dot)开始,目录和其他指定的文件不包括。 + 返回针对指定tablespace的临时文件目录中每个普通文件的名称、大小和最后修改时间(mtime)。 + 如果未提供tablespace,则检查pg_default表空间。 + 以点号开头的文件名、目录以及其他特殊文件都不会包含在结果中。 - 这个函数默认限制在超级用户和pg_monitor角色的成员,但是其他用户可以被授予EXECUTE以运行此函数。 + 默认情况下,此函数仅限超级用户和pg_monitor角色的成员使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -25603,12 +23401,12 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size text - 返回一个文本文件的全部或部分,开始于给定的字节offset,在最大的length字节返回(如果文件的结尾先达到了则减少)。 - 如果offset为负,他于文件的结尾有关。如果offsetlength 被省略,整个文件被返回。 - 从文件中读的字节在服务器的编码中解释为字符串;如果它们在哪些编码中不是有效的则抛出错误。 + 返回一个文本文件的全部或部分,从给定的字节offset开始,最多返回length字节(如果先到达文件末尾,则返回更少)。 + 如果offset为负,则它相对于文件末尾计算。如果省略offsetlength,则返回整个文件。 + 从文件中读取的字节会按数据库编码解释为字符串;如果它们在该编码下无效,则会抛出错误。 - 这个函数默认限制在超级用户,但是其他用户可以被授予EXECUTE以运行此函数。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -25621,14 +23419,14 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size bytea - 返回文件的全部或部分。这个函数与pg_read_file 是完全相同的,除了它可以读任意的二进制数据,返回结果为bytea而不是text; - 因此,没有编码检查会被执行。 + 返回文件的全部或部分。该函数与pg_read_file完全相同,只是它可以读取任意二进制数据,并返回bytea而不是text; + 因此不会执行编码检查。 - 这个函数默认限制在超级用户,但是其他用户可以被授予EXECUTE以运行此函数。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 - 与 convert_from函数组合,这个函数能被用于以指定的编码读文本文件并转换到数据库的编码: + 与convert_from函数配合使用时,该函数可用于按指定编码读取文本文件,并将其转换为数据库编码: SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); @@ -25650,10 +23448,10 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); isdir boolean ) - 返回一个记录,包含文件的大小、最后访问时间戳、最后修改时间戳,最后文件状态变更时间戳(仅在UNIX平台)、文件建立时间戳(仅Windows),和一个标志旗如果它是一个目录。 + 返回一个记录,包含文件大小、最后访问时间戳、最后修改时间戳、最后文件状态变更时间戳(仅限 Unix 平台)、文件创建时间戳(仅限 Windows)以及一个指示其是否为目录的标志。 - 这个函数默认限制在超级用户,但是其他用户可以被授予EXECUTE以运行此函数。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -25673,11 +23471,11 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); - 所有这些函数都打算用于锁定应用程序定义的资源,可以通过一个64位键值或两个32位键值来标识(注意这两个键空间不能重叠)。 - 如果另一个会话已经在相同的资源标识符上持有一个冲突的锁,函数将等待直到资源变成可用,或者返回一个false结果,合适于函数的。 - 锁可以是共享或排他的:共享锁不会与同一资源上的其他共享锁发生冲突,只会与排他锁发生冲突。 - 锁可以在会话级(这样它们被保持直到释放或会话结束)或在事务级(这样它们被保持直到当前事务结束;没有手动释放的供应)。 - 多个会话级锁请求堆栈,因此如果同一个资源标识符被锁定三次,那么必须有三个解锁请求来释放资源,在会话结束之前。 + 这些函数用于锁定应用程序定义的资源;资源可用一个 64 位键值或两个 32 位键值标识(这两个键空间互不重叠)。 + 如果另一个会话已对同一资源标识符持有冲突锁,函数会根据自身的行为等待资源可用,或返回false。 + 锁可以是共享的或排他的:共享锁不会与同一资源上的其他共享锁冲突,只会与排他锁冲突。 + 锁可以在会话级获取(一直保持到释放或会话结束),也可以在事务级获取(一直保持到当前事务结束,不能手动释放)。 + 多次会话级锁请求会累加,因此,如果同一资源标识符被锁定三次,就必须请求解锁三次,才能在会话结束前释放该资源。
@@ -25828,8 +23626,8 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); boolean - 获取一个排他的会话级咨询锁,如果适用。 - 这将立即获得锁并返回true,或者如果不能立即获取锁则立即返回 false而无需等待。 + 尝试获取一个排他的会话级咨询锁。 + 如果能立即获取到锁,就返回true;否则立即返回false,而不等待。 @@ -25846,8 +23644,8 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); boolean - 获取一个共享的会话级咨询锁,如果适用。 - 这将立即获得锁并返回true,或者如果不能立即获取锁则立即返回 false而无需等待。 + 尝试获取一个共享的会话级咨询锁。 + 如果能立即获取到锁,就返回true;否则立即返回false,而不等待。 @@ -25864,8 +23662,8 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); boolean - 获取一个排他的事务级咨询锁,如果适用。 - 这将立即获得锁并返回true,或者如果不能立即获取锁则立即返回 false而无需等待。 + 尝试获取一个排他的事务级咨询锁。 + 如果能立即获取到锁,就返回true;否则立即返回false,而不等待。 @@ -25882,8 +23680,8 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); boolean - 获取一个共享的事务级咨询锁,如果适用。 - 这将立即获得锁并返回true,或者如果不能立即获取锁则立即返回 false而无需等待。 + 尝试获取一个共享的事务级咨询锁。 + 如果能立即获取到锁,就返回true;否则立即返回false,而不等待。 @@ -25938,7 +23736,7 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); trigger - 阻止不做事的更新操作。详见下文。 + 抑制不改变数据的更新操作。详见下文。 CREATE TRIGGER ... suppress_redundant_updates_trigger() @@ -25954,8 +23752,7 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); trigger - 自动从相关的纯文本文档列更新tsvector列。 - 要使用的文本搜索配置是以名称指定为触发器参数。详情请参见。 + 根据关联的纯文本文档列自动更新tsvector列。所用的全文检索配置以名称形式指定为触发器参数。详见 CREATE TRIGGER ... tsvector_update_trigger(tsvcol, 'pg_catalog.swedish', title, body) @@ -25971,8 +23768,7 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); trigger - 自动从相关的纯文本文档列更新tsvector列。 - 要使用的文本搜索配置取自表的regconfig列。详情请参见。 + 根据关联的纯文本文档列自动更新tsvector列。所用的全文检索配置取自表的regconfig列。详见 CREATE TRIGGER ... tsvector_update_trigger_column(tsvcol, tsconfigcol, title, body) @@ -25989,23 +23785,15 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); - 理想的情况下,你应该避免运行实际上并没有改变记录中数据的更新。 - 冗余更新会花费大量不必要的时间,尤其是如果有大量索引要改变, 并将最终不得不清理被死亡行占用的空间。 - 但是,在客户端代码中检测这种情况并不总是容易的,甚至不可能做到。 而写表达式来检测它们容易产生错误。 - 作为替代,使用suppress_redundant_updates_trigger可以跳过不改变数据的更新。 但是,你需要小心使用它。 - 触发器需要很短但不能忽略的时间来处理每条记录,所以如果受更新影响的大多数记录确实变化了,此触发器的使用将使更新比平均水平运行得更慢。 + 理想情况下,应避免执行实际上不会改变记录中数据的更新。冗余更新会耗费大量不必要的时间,尤其是在需要修改许多索引时;它们还会使死行占用空间,最终需要通过清理回收。但是,在客户端代码中检测这种情况并不总是容易,甚至可能无法做到,而编写用于检测的表达式也容易出错。另一种办法是使用suppress_redundant_updates_trigger,跳过不改变数据的更新。但使用时应当谨慎。此触发器处理每条记录的耗时虽小,却不可忽略,因此如果更新涉及的大多数记录确实会改变,使用此触发器反而会增加更新的平均耗时。 - suppress_redundant_updates_trigger函数可以像这样添加到表中: - + 该suppress_redundant_updates_trigger函数可以按如下方式添加到表中: CREATE TRIGGER z_min_update BEFORE UPDATE ON tablename FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); - - 在大多数情况下,你需要为每一行最后触发这个触发器,这样它就不会覆盖可能希望更改该行的其他触发器。 - 请记住,触发器是按照名称顺序触发的,你将为此选择一个触发器名称,该名称位于表中可能存在的任何其他触发器的名称之后。 - (因此在示例中使用了z前缀。) +大多数情况下,需要让该触发器对每一行最后触发,以免覆盖其他可能修改该行的触发器的效果。由于触发器按名称顺序触发,应选择一个排序位于表上其他所有触发器名称之后的名称。(这就是示例中使用z前缀的原因。) @@ -26014,7 +23802,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); 事件触发器函数 - PostgreSQL提供了这些助手函数来从事件触发器检索信息。 + PostgreSQL提供了这些辅助函数来从事件触发器检索信息。 @@ -26036,7 +23824,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); 当在一个ddl_command_end事件触发器的函数中调用时,pg_event_trigger_ddl_commands返回被每一个用户动作执行的DDL命令的列表。 如果在其他任何环境中调用这个函数,会发生错误。 - pg_event_trigger_ddl_commands为每一个被执行的基本命令返回一行,某些只有一个单一 SQL 句子的命令可能会返回多于一行。 + pg_event_trigger_ddl_commands为每一个被执行的基本命令返回一行,某些由单条 SQL 语句构成的命令可能会返回多于一行。 这个函数返回下面的列: @@ -26053,7 +23841,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); classid oid - 对象所属的目录的 OID + 对象所属系统目录的 OID objid @@ -26063,7 +23851,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); objsubid integer - 对象的子-id(例如列的属性号) + 子对象 ID(例如列的属性编号) command_tag @@ -26079,16 +23867,14 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); schema_name text - 该对象所属的模式的名称(如果有),如果没有则为NULL。 - 没有引号。 + 对象所属模式的名称(若有);否则为NULL。不加引号。 object_identity text - 对象标识的文本表现形式,用模式限定。如果必要,出现在 - 该标识中的每一个标识符都会被引用。 + 对象标识的文本表示形式,带模式限定。标识中包含的每个标识符在必要时都会加引号。 @@ -26100,8 +23886,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); command pg_ddl_command - 以内部格式表达的该命令的一个完整表现形式。这不能被直接输出, - 但是可以把它传递给其他函数来得到有关于该命令不同部分的信息。 + 命令的完整内部表示,不能直接输出,但可以将其传给其他函数以获取关于该命令的不同信息。 @@ -26123,8 +23908,8 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); - pg_event_trigger_dropped_objects返回被调用sql_drop事件的命令删除的所有对象的列表。 - 如果调用在任何其他上下文中,会引发一个错误。这个函数返回以下列: + 在命令的sql_drop事件中调用pg_event_trigger_dropped_objects时,它返回该命令删除的所有对象的列表。 + 如果调用在任何其他上下文中,会引发一个错误。这个函数返回以下列: @@ -26140,7 +23925,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); classid oid - 对象所属的目录的 OID + 对象原先所属系统目录的 OID objid @@ -26150,7 +23935,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); objsubid integer - 子对象ID(如列的属性号) + 子对象 ID(例如列的属性编号) original @@ -26161,7 +23946,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); normal boolean - 指示在依赖图中有一个普通依赖关系指向该对象的标志 + 如果依赖图中存在指向该对象的普通依赖关系,则为真。 @@ -26180,29 +23965,28 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); schema_name text - 对象所属模式的名称(如果存在);否则为NULL。不应用引用。 + 对象原先所属模式的名称(若有);否则为NULL。不加引号。 object_name text - 如果模式和名称的组合能被用于对象的一个唯一标识符,则是对象的名称;否则是NULL。不应用引用,并且名称不是模式限定的。 + 如果模式和名称的组合可用作该对象的唯一标识符,则为对象名称;否则为NULL。不加引号,并且该名称永远不带模式限定。 object_identity text - 对象身份的文本表现,模式限定的。每一个以及所有身份中出现的标识符在必要时加引号。 + 对象标识的文本表示形式,带模式限定。标识中包含的每个标识符在必要时都会加引号。 address_names text[] - 一个数组,它可以和object_typeaddress_args, - 一起通过pg_get_object_address函数在一台包含有同类相同名称对象的远程服务器上重建该对象地址。 + 一个数组,可与object_typeaddress_args一起,通过pg_get_object_address函数在包含同类同名对象的远程服务器上重建该对象地址。 @@ -26301,7 +24085,7 @@ CREATE EVENT TRIGGER test_event_trigger_for_drops
- 这些函数可以在事件触发器中使用,就像这样: + 这些函数可以在事件触发器中使用,就像这样: CREATE FUNCTION test_event_trigger_table_rewrite_oid() RETURNS event_trigger @@ -26327,12 +24111,12 @@ CREATE EVENT TRIGGER test_table_rewrite_oid 统计信息函数 - function - statistics + 函数 + 统计信息 - PostgreSQL提供了一个函数来检查使用CREATE STATISTICS命令定义的复杂统计。 + PostgreSQL提供了一个函数来检查使用CREATE STATISTICS命令定义的复杂统计信息。 @@ -26348,7 +24132,7 @@ CREATE EVENT TRIGGER test_table_rewrite_oid - pg_mcv_list_items返回一组记录,描述存储在多列MCV列表中的所有项目。它返回以下列: + pg_mcv_list_items返回一组记录,描述存储在多列MCV列表中的所有项目。它返回以下列: @@ -26384,7 +24168,7 @@ CREATE EVENT TRIGGER test_table_rewrite_oid base_frequency double precision - MCV项目的基本频率 + MCV项目的基础频率 @@ -26392,7 +24176,7 @@ CREATE EVENT TRIGGER test_table_rewrite_oid - pg_mcv_list_items函数可以这样使用: + pg_mcv_list_items函数可以这样使用: SELECT m.* FROM pg_statistic_ext join pg_statistic_ext_data on (oid = stxoid), diff --git a/zh/14/gin.sgml b/zh/14/gin.sgml index af33cb78..7e69942d 100644 --- a/zh/14/gin.sgml +++ b/zh/14/gin.sgml @@ -53,7 +53,7 @@ 内置操作符类 - PostgreSQL 核心发布包含 + PostgreSQL 核心发行版包含 所示的 GIN 操作符类。 (在 中描述的一些可选模块还提供额外的 GIN 操作符类。) @@ -111,9 +111,12 @@ @@ (jsonb,jsonpath) - tsvector_ops + tsvector_ops @@ (tsvector,tsquery) + + @@@ (tsvector,tsquery) + @@ -152,7 +155,7 @@ 给定一个要建立索引的项,返回一个用 palloc 分配的键数组。返回键的数量必须存入 *nkeys。如果任一键可以为 null,还要另外 palloc 一个包含 *nkeysbool 字段的数组,将其地址存入 - *nullFlags,并按需设置这些空值标志。如果所有键都非空, + *nullFlags,并按需设置这些空值标志。如果所有键都不是 null, *nullFlags 可以保持为 NULL(其初始值)。 如果该项不包含任何键,则返回值可以为 NULL @@ -172,7 +175,7 @@ query 的数据类型,以及应采用何种方法提取键值。返回键的数量必须存入 *nkeys。如果任一键可以为 null,还要另外 palloc 一个包含 *nkeysbool 字段的数组,将其地址存入 - *nullFlags,并按需设置这些空值标志。如果所有键都非空, + *nullFlags,并按需设置这些空值标志。如果所有键都不是 null, *nullFlags 可以保持为 NULL(其初始值)。 如果 query 不包含任何键,则返回值可以为 NULL @@ -185,7 +188,7 @@ 被设置为 GIN_SEARCH_MODE_INCLUDE_EMPTY,则除至少包含一个匹配键的项之外, 完全不含任何键的项也会被视为候选匹配。(例如,该模式对于实现是子集操作符很有用。) 若 *searchMode 被设置为 GIN_SEARCH_MODE_ALL, - 则索引中所有非空项都会被视为候选匹配,无论它们是否匹配任一返回键。 + 则索引中所有非 null 项都会被视为候选匹配,无论它们是否匹配任一返回键。 (该模式比前两种选择慢得多,因为它基本上需要扫描整个索引;但为了正确处理某些边界情况, 可能有此必要。在大多数情况下都需要此模式的操作符,大概并不适合作为 GIN 操作符类的候选。)用于设置该模式的符号定义在 @@ -218,7 +221,7 @@ 操作符类还必须提供一个函数,用于检查被索引项是否匹配查询。它有两种形式:布尔型 consistent 函数,以及三值型 triConsistent 函数。 triConsistent 覆盖了两者的功能,因此仅提供 triConsistent - 就已经足够。不过,如果布尔变体的计算明显更便宜,那么同时提供两者会更有利。 + 就已经足够。不过,如果布尔变体的计算代价明显更低,那么同时提供两者可能更有利。 若只提供布尔变体,则一些依赖于在取回所有键之前先排除索引项的优化将被禁用。 @@ -233,10 +236,10 @@ 该函数无法直接访问被索引项的值,因为 GIN 并不显式存储项。 它所能利用的是这样一种信息:从查询中提取出的哪些键值出现在给定的被索引项中。 check 数组长度为 nkeys,这与先前针对该 - query 数据由 extractQuery 返回的键数量相同。 + query datum 由 extractQuery 返回的键数量相同。 如果被索引项包含相应查询键,则 check 数组中的对应元素为 true; 也就是说,如果 check[i] == true,则 extractQuery - 结果数组中的第 i 个键存在于该被索引项中。传入原始 query 数据值, + 结果数组中的第 i 个键存在于该被索引项中。传入原始 query datum, 是为了让 consistent 方法在需要时可以查看它;同样也会传入先前由 extractQuery 返回的 queryKeys[]nullFlags[] 数组。extra_data 则是 @@ -274,7 +277,7 @@ 而 GIN_MAYBE 表示该键是否存在尚不确定。存在 GIN_MAYBE 值时,只有当无论索引项是否包含对应查询键,该项都确定匹配时,函数才应返回 GIN_TRUE。同样,只有当无论是否包含 GIN_MAYBE 键, - 该项都确定不匹配时,函数才必须返回 GIN_FALSE。如果结果依赖于 + 该项都确定不匹配时,函数才能返回 GIN_FALSE。如果结果依赖于 GIN_MAYBE 条目,也就是说,无法根据已知的查询键确认或否定匹配, 则函数必须返回 GIN_MAYBE。 @@ -306,7 +309,7 @@ 或者,如果操作符类没有提供 compare 方法,GIN 将查找该索引键数据类型的默认 B-树操作符类,并使用其比较函数。建议在仅面向单一数据类型的 - GIN 操作符类中显式指定比较函数,因为查找 B-树操作符类会消耗少量周期。 + GIN 操作符类中显式指定比较函数,因为查找 B-树操作符类会消耗少量处理器周期。 不过,多态 GIN 操作符类(例如 array_ops)通常无法指定单一比较函数。 @@ -374,8 +377,8 @@ 在内部,一个 GIN 索引包含一个基于键构建的 B-树索引,其中每个键都是一个或多个被索引项中的某个元素 - (例如数组成员),而叶子页中的每个元组要么包含一个指向堆指针 B-树的指针(posting tree), - 要么在列表足够小、能够连同键值一起放入单个索引元组时,直接包含一个简单的堆指针列表(posting list)。 + (例如数组成员),而叶子页中的每个元组要么包含一个指向堆指针 B-树的指针(倒排树), + 要么在列表足够小、能够连同键值一起放入单个索引元组时,直接包含一个简单的堆指针列表(倒排列表)。 展示了 GIN 索引的这些组成部分。 @@ -422,7 +425,7 @@ - 如果一致的响应时间比更新速度更重要,可以通过关闭 GIN 索引的 + 如果稳定的响应时间比更新速度更重要,可以通过关闭 GIN 索引的 fastupdate 存储参数来禁用待处理列表机制。详见 @@ -461,7 +464,7 @@ 当为 GIN 启用 fastupdate 时 (详见 ),这种代价会比未启用时小一些。 - 但对于非常大的更新,最好仍然是删除并重建索引。 + 但对于非常大的更新,删除并重建索引仍然可能是最佳选择。 @@ -529,7 +532,7 @@ GIN 假定可索引操作符是严格的。这意味着,当项值为 null 时, 根本不会对其调用 extractValue(而是自动创建一个占位符索引项); 当查询值为 null 时,也不会调用 extractQuery(而是认为该查询不可满足)。 - 不过要注意,非空组合项或查询值内部包含的 null 键值仍然受支持。 + 不过要注意,非 null 的组合项或查询值内部包含的 null 键值仍然受支持。 @@ -537,7 +540,7 @@ 示例 - PostgreSQL 核心发布包含前面在 + PostgreSQL 核心发行版包含前面在 中展示过的 GIN 操作符类。 下列 contrib 模块也包含 GIN 操作符类: diff --git a/zh/14/gist.sgml b/zh/14/gist.sgml index b25fbd35..fa8263bc 100644 --- a/zh/14/gist.sgml +++ b/zh/14/gist.sgml @@ -4,7 +4,7 @@ GiST 索引 - index + 索引 GiST @@ -211,7 +211,7 @@ CREATE INDEX ON my_table USING GIST (my_inet_column inet_ops); - 这种可扩展性不应与其他标准搜索树在可处理数据方面的可扩展性相混淆。例如,PostgreSQL支持可扩展的 B-树和哈希索引。这意味着你可以用PostgreSQL在任意数据类型上构建 B-树或哈希索引。但 B-树只支持范围谓词(<=>),而哈希索引只支持等值查询。 + 这种可扩展性不应与其他标准搜索树在可处理数据方面的可扩展性相混淆。例如,PostgreSQL支持可扩展的 B-树和 hash 索引。这意味着你可以用PostgreSQL在任意数据类型上构建 B-树或 hash 索引。但 B-树只支持范围谓词(<=>),而 hash 索引只支持等值查询。 @@ -262,15 +262,14 @@ my_consistent(PG_FUNCTION_ARGS) bool retval; /* - * determine return value as a function of strategy, key and query. + * 根据 strategy、key 和 query 确定返回值。 * - * Use GIST_LEAF(entry) to know where you're called in the index tree, - * which comes handy when supporting the = operator for example (you could - * check for non empty union() in non-leaf nodes and equality in leaf - * nodes). + * 使用 GIST_LEAF(entry) 判断当前调用位于索引树的哪个位置。 + * 例如,支持 = 操作符时这很有用(可以在非叶节点检查 + * union() 是否非空,在叶节点检查是否相等)。 */ - *recheck = true; /* or false if check is exact */ + *recheck = true; /* 如果检查是精确的,则为 false */ PG_RETURN_BOOL(retval); } @@ -386,10 +385,10 @@ my_compress(PG_FUNCTION_ARGS) if (entry->leafkey) { - /* replace entry->key with a compressed version */ + /* 将 entry->key 替换为压缩后的形式 */ compressed_data_type *compressed_data = palloc(sizeof(compressed_data_type)); - /* fill *compressed_data from entry->key ... */ + /* 根据 entry->key 填充 *compressed_data ... */ retval = palloc(sizeof(GISTENTRY)); gistentryinit(*retval, PointerGetDatum(compressed_data), @@ -397,7 +396,7 @@ my_compress(PG_FUNCTION_ARGS) } else { - /* typically we needn't do anything with non-leaf entries */ + /* 通常无需对非叶项做任何处理 */ retval = entry; } @@ -460,7 +459,7 @@ my_decompress(PG_FUNCTION_ARGS) CREATE OR REPLACE FUNCTION my_penalty(internal, internal, internal) RETURNS internal AS 'MODULE_PATHNAME' -LANGUAGE C STRICT; -- in some cases penalty functions need not be strict +LANGUAGE C STRICT; -- 某些情况下 penalty 函数不必是严格函数 而 C 模块中的对应代码则可以遵循如下框架: @@ -482,7 +481,7 @@ my_penalty(PG_FUNCTION_ARGS) } - 出于历史原因,penalty函数并不是直接返回一个float结果;相反,它必须把该值存储到第三个参数指示的位置。返回值本身会被忽略,不过通常会返回该参数的地址。 + 出于历史原因,penalty函数并不是直接返回一个float结果;相反,它必须把该值存储到第三个参数指示的位置。返回值本身会被忽略,不过通常会返回该参数所指向的地址。 @@ -543,7 +542,7 @@ my_picksplit(PG_FUNCTION_ARGS) unionL = NULL; unionR = NULL; - /* Initialize the raw entry vector. */ + /* 初始化原始项向量。 */ raw_entryvec = (GISTENTRY **) malloc(entryvec->n * sizeof(void *)); for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) raw_entryvec[i] = &(entryvec->vector[i]); @@ -556,9 +555,9 @@ my_picksplit(PG_FUNCTION_ARGS) Assert(tmp_union != NULL); /* - * Choose where to put the index entries and update unionL and unionR - * accordingly. Append the entries to either v->spl_left or - * v->spl_right, and care about the counters. + * 选择索引项的存放位置,并相应更新 unionL 和 unionR。 + * 将项追加到 v->spl_left 或 v->spl_right, + * 同时更新计数器。 */ if (my_choice_is_left(unionL, curl, unionR, curr)) @@ -575,7 +574,7 @@ my_picksplit(PG_FUNCTION_ARGS) else { /* - * Same on the right + * 对右侧执行相同操作 */ } } @@ -629,7 +628,7 @@ my_same(PG_FUNCTION_ARGS) } - 出于历史原因,same函数并不是直接返回一个布尔结果;相反,它必须把该标志存储到第三个参数指示的位置。返回值本身会被忽略,不过通常会返回该参数的地址。 + 出于历史原因,same函数并不是直接返回一个布尔结果;相反,它必须把该标志存储到第三个参数指示的位置。返回值本身会被忽略,不过通常会返回该参数所指向的地址。 @@ -668,7 +667,7 @@ my_distance(PG_FUNCTION_ARGS) double retval; /* - * determine return value as a function of strategy, key and query. + * 根据 strategy、key 和 query 确定返回值。 */ PG_RETURN_FLOAT8(retval); @@ -679,11 +678,11 @@ my_distance(PG_FUNCTION_ARGS) - 在确定距离时允许有一定近似,只要结果永不大于该项的实际距离即可。因此,例如在几何应用中,到外包盒的距离通常就足够了。对于内部树节点,返回的距离不能大于其任一子节点的距离。如果返回的距离不精确,函数必须将*recheck设为 true。(对内部树节点则不必这样做;对它们总是假定计算结果不精确。)在这种情况下,执行器会在从堆中取出元组后计算准确距离,并在必要时重新排序这些元组。 + 在确定距离时允许有一定近似,只要结果永不大于该项的实际距离即可。因此,例如在几何应用中,到包围盒的距离通常就足够了。对于内部树节点,返回的距离不能大于其任一子节点的距离。如果返回的距离不精确,函数必须将*recheck设为 true。(对内部树节点则不必这样做;对它们总是假定计算结果不精确。)在这种情况下,执行器会在从堆中取出元组后计算准确距离,并在必要时重新排序这些元组。 - 如果距离函数对任何叶节点都返回*recheck = true,原始排序操作符的返回类型必须是float8float4,且距离函数的结果值必须能与原始排序操作符的结果进行比较,因为执行器会同时使用距离函数结果和重新计算得到的排序操作符结果进行排序。否则,距离函数的结果值可以是任意有限的float8值,只要这些结果值的相对顺序与排序操作符返回的顺序一致即可。(无穷大和负无穷在内部用于处理空值等情况,因此不建议distance函数返回这些值。) + 如果距离函数对任意一个叶节点返回*recheck = true,原始排序操作符的返回类型必须是float8float4,且距离函数的结果值必须能与原始排序操作符的结果进行比较,因为执行器会同时使用距离函数结果和重新计算得到的排序操作符结果进行排序。否则,距离函数的结果值可以是任意有限的float8值,只要这些结果值的相对顺序与排序操作符返回的顺序一致即可。(无穷大和负无穷在内部用于处理空值等情况,因此不建议distance函数返回这些值。) @@ -727,10 +726,10 @@ my_fetch(PG_FUNCTION_ARGS) fetched_data = palloc(sizeof(fetched_data_type)); /* - * Convert 'fetched_data' into the a Datum of the original datatype. + * 将 'fetched_data' 转换为原始数据类型的 Datum。 */ - /* fill *retval from fetched_data. */ + /* 根据 fetched_data 填充 *retval。 */ gistentryinit(*retval, PointerGetDatum(converted_datum), entry->rel, entry->page, entry->offset, FALSE); @@ -781,26 +780,26 @@ typedef enum MyEnumType typedef struct { - int32 vl_len_; /* varlena header (do not touch directly!) */ - int int_param; /* integer parameter */ - double real_param; /* real parameter */ - MyEnumType enum_param; /* enum parameter */ - int str_param; /* string parameter */ + int32 vl_len_; /* varlena 首部(不要直接操作!) */ + int int_param; /* 整数参数 */ + double real_param; /* 实数参数 */ + MyEnumType enum_param; /* 枚举参数 */ + int str_param; /* 字符串参数 */ } MyOptionsStruct; -/* String representation of enum values */ +/* 枚举值的字符串表示 */ static relopt_enum_elt_def myEnumValues[] = { {"on", MY_ENUM_ON}, {"off", MY_ENUM_OFF}, {"auto", MY_ENUM_AUTO}, - {(const char *) NULL} /* list terminator */ + {(const char *) NULL} /* 列表终止项 */ }; static char *str_param_default = "default"; /* - * Sample validator: checks that string is not longer than 8 bytes. + * 验证器示例:检查字符串长度不超过 8 字节。 */ static void validate_my_string_relopt(const char *value) @@ -812,7 +811,7 @@ validate_my_string_relopt(const char *value) } /* - * Sample filler: switches characters to lower case. + * 填充函数示例:将字符转换为小写。 */ static Size fill_my_string_relopt(const char *value, void *ptr) @@ -821,7 +820,7 @@ fill_my_string_relopt(const char *value, void *ptr) int len = strlen(tmp); if (ptr) - strcpy(ptr, tmp); + strcpy((char *) ptr, tmp); pfree(tmp); return len + 1; @@ -865,10 +864,9 @@ my_compress(PG_FUNCTION_ARGS) char *str_param = str_param_default; /* - * Normally, when opclass contains 'options' method, then options are always - * passed to support functions. However, if you add 'options' method to - * existing opclass, previously defined indexes have no options, so the - * check is required. + * 通常,操作符类包含 'options' 方法时,总会把选项传给支持函数。 + * 但是,如果把 'options' 方法添加到已有操作符类中, + * 先前定义的索引没有选项,因此需要进行检查。 */ if (PG_HAS_OPCLASS_OPTIONS()) { @@ -880,7 +878,7 @@ my_compress(PG_FUNCTION_ARGS) str_param = GET_STRING_RELOPTION(options, str_param); } - /* the rest implementation of support function */ + /* 支持函数的其余实现 */ } @@ -924,7 +922,7 @@ PG_FUNCTION_INFO_V1(my_sortsupport); static int my_fastcmp(Datum x, Datum y, SortSupport ssup) { - /* establish order between x and y by computing some sorting value z */ + /* 通过计算某个排序值 z 来确定 x 和 y 的顺序 */ int z1 = ComputeSpatialCode(x); int z2 = ComputeSpatialCode(y); @@ -960,7 +958,7 @@ my_sortsupport(PG_FUNCTION_ARGS) GiST 索引构建方法 - 构建 GiST 索引最简单的方法就是把所有项逐个插入。这对于大型索引往往很慢,因为如果索引元组分散在整个索引中,而索引又大到无法放入缓存,就需要大量随机 I/O。PostgreSQL支持两种用于 GiST 索引初始构建的替代方法:sortedbuffered模式。 + 构建 GiST 索引最简单的方法就是把所有项逐个插入。这对于大型索引往往很慢,因为如果索引元组分散在整个索引中,而索引又大到无法放入缓存,就需要大量随机 I/O。PostgreSQL支持两种用于 GiST 索引初始构建的替代方法:排序缓冲模式。 @@ -1006,7 +1004,7 @@ my_sortsupport(PG_FUNCTION_ARGS) hstore - 用于存储 (key, value) 对的模块 + 用于存储(键,值)对的模块 diff --git a/zh/14/glossary.sgml b/zh/14/glossary.sgml index ee8b0ce0..f99db873 100644 --- a/zh/14/glossary.sgml +++ b/zh/14/glossary.sgml @@ -267,7 +267,7 @@ 客户端(进程) - 任何进程,可能是远程的,通过连接到某个 + 任何进程,可能是远程的,通过连接到某个 实例来建立 会话, 以与一个数据库交互。 @@ -654,7 +654,7 @@ 一台通过网络与其他计算机通信的计算机。这个术语有时被用作 服务器的同义词。 - 它也用来指客户端进程运行所在的计算机。 + 它也用来指客户端进程运行所在的计算机。 @@ -691,7 +691,7 @@ 实例 - 一组后端和 + 一组后端进程和 辅助进程, 它们使用同一块共享内存区域进行通信。一个 postmaster 进程 @@ -703,7 +703,7 @@ 实例处理 DBMS 的所有关键特性: 对文件和共享内存的读写访问、保证 ACID 属性、 - 与客户端进程的连接、 + 与客户端进程连接、 权限验证、崩溃恢复、复制等。 @@ -905,7 +905,7 @@ - 当它用于指代查询中的 + 当它用于指代查询中的 窗口函数时, 分区是一种用户定义的准则,用来标识 查询结果集中哪些相邻的 diff --git a/zh/14/hash.sgml b/zh/14/hash.sgml index 199395b2..81f5f878 100644 --- a/zh/14/hash.sgml +++ b/zh/14/hash.sgml @@ -1,11 +1,11 @@ -哈希索引 +Hash 索引 索引 - 哈希 + Hash @@ -13,51 +13,51 @@ PostgreSQL - 提供了持久化的磁盘哈希索引实现,并且完全支持崩溃恢复。任何数据类型都可以使用哈希索引,包括那些没有明确定义线性顺序的数据类型。哈希索引只存储被索引数据的哈希值,因此对被索引数据列的大小没有限制。 + 提供了持久化的磁盘 hash 索引实现,并且完全支持崩溃恢复。任何数据类型都可以使用 hash 索引,包括那些没有明确定义线性顺序的数据类型。Hash 索引只存储被索引数据的 hash 值,因此对被索引数据列的大小没有限制。 - 哈希索引仅支持单列索引,也不支持唯一性检查。 + Hash 索引仅支持单列索引,也不支持唯一性检查。 - 哈希索引仅支持=操作符,因此指定范围操作的 WHERE 子句无法利用哈希索引。 + Hash 索引仅支持=操作符,因此指定范围操作的 WHERE 子句无法利用 hash 索引。 - 每个哈希索引元组只存储 4 字节的哈希值,而不存储实际的列值。因此,在为 UUID、URL 等较长的数据项建立索引时,哈希索引可能比 B-树小得多。由于没有列值,所有哈希索引扫描也都是有损的。哈希索引可以参与位图索引扫描和反向扫描。 + 每个 hash 索引元组只存储 4 字节的 hash 值,而不存储实际的列值。因此,在为 UUID、URL 等较长的数据项建立索引时,hash 索引可能比 B-树小得多。由于没有列值,所有 hash 索引扫描也都是有损的。Hash 索引可以参与位图索引扫描和反向扫描。 - 哈希索引最适合于在较大表上执行等值扫描、且以 SELECT 和 UPDATE 为主的工作负载。在 B-树索引中,搜索必须沿树向下直到找到叶页。在拥有数百万行的表中,这种向下遍历会增加访问数据的时间。在哈希索引中,与叶页对应的页称为桶页。相比之下,哈希索引允许直接访问桶页,因此可能减少大表中的索引访问时间。这种“逻辑 I/O”的减少,在索引/数据大于 shared_buffers/RAM 时会更加明显。 + Hash 索引最适合于在较大表上执行等值扫描、且以 SELECT 和 UPDATE 为主的工作负载。在 B-树索引中,搜索必须沿树向下直到找到叶页。在拥有数百万行的表中,这种向下遍历会增加访问数据的时间。在 hash 索引中,与叶页对应的页称为桶页。相比之下,hash 索引允许直接访问桶页,因此可能减少大表中的索引访问时间。这种“逻辑 I/O”的减少,在索引/数据大于 shared_buffers/RAM 时会更加明显。 - 哈希索引在设计上能够应对哈希值分布不均的情况。如果哈希值分布均匀,那么直接访问桶页的效果很好。当插入导致桶页填满时,额外的溢出页就会链接到该特定桶页上,从而在局部扩展用于存放匹配该哈希值的索引元组的空间。查询期间扫描某个哈希桶时,需要遍历其全部溢出页。因此,对于某些数据,不平衡的哈希索引在所需块访问次数方面实际上可能比 B-树更差。 + Hash 索引在设计上能够应对 hash 值分布不均的情况。如果 hash 值分布均匀,那么直接访问桶页的效果很好。当插入导致桶页填满时,额外的溢出页就会链接到该特定桶页上,从而在局部扩展用于存放匹配该 hash 值的索引元组的空间。查询期间扫描某个 hash 桶时,需要遍历其全部溢出页。因此,对于某些数据,不平衡的 hash 索引在所需块访问次数方面实际上可能比 B-树更差。 - 由于会出现这些溢出情况,可以说哈希索引最适合用于唯一值、近乎唯一值,或者每个哈希桶中行数较少的数据。 + 由于会出现这些溢出情况,可以说 hash 索引最适合用于唯一值、近乎唯一值,或者每个 hash 桶中行数较少的数据。 避免问题的一种可能办法,是使用部分索引条件把高度非唯一的值排除在索引之外,但这在很多情况下可能并不适用。 - 与 B-树一样,哈希索引也会执行简单的索引元组删除。这是一种延迟维护操作,用于删除那些已知可以安全删除的索引元组(即其项标识符的 LP_DEAD 位已经被设置的那些元组)。如果插入操作发现页上没有可用空间,我们会尝试通过移除死索引元组来避免创建新的溢出页。如果该页当时已被钉住,就无法执行移除。死索引指针也会在 VACUUM 期间被删除。 + 与 B-树一样,hash 索引也会执行简单的索引元组删除。这是一种延迟维护操作,用于删除那些已知可以安全删除的索引元组(即其项标识符的 LP_DEAD 位已经被设置的那些元组)。如果插入操作发现页上没有可用空间,我们会尝试通过移除死索引元组来避免创建新的溢出页。如果该页当时已被钉住,就无法执行移除。死索引指针也会在 VACUUM 期间被删除。 - 如果可能,VACUUM 还会尝试将索引元组压缩到尽可能少的溢出页上,以最小化溢出链。 + 如果可能,VACUUM 还会尝试将索引元组集中存放在尽可能少的溢出页上,以最小化溢出链。 如果某个溢出页变为空页,该溢出页就可以被回收并在其他桶中重用,不过我们从不将它们返还给操作系统。 - 目前除了使用 REINDEX 重建哈希索引之外,还没有缩小哈希索引的方法。 + 目前除了使用 REINDEX 重建 hash 索引之外,还没有缩小 hash 索引的方法。 同样也没有减少桶数量的方法。 - 随着被索引行数的增长,哈希索引可能会扩展桶页数量。哈希键到桶号的映射经过选择,使得索引能够增量扩展。当需要向索引中添加一个新桶时,恰好只需要“拆分”一个现有桶,并根据更新后的键到桶号映射,将其中一部分元组转移到新桶。 + 随着被索引行数的增长,Hash 索引可能会扩展桶页数量。hash 键到桶号的映射经过选择,使得索引能够增量扩展。当需要向索引中添加一个新桶时,恰好只需要“拆分”一个现有桶,并根据更新后的键到桶号映射,将其中一部分元组转移到新桶。 - 这种扩展是在前台进行的,因此可能会增加用户插入操作的执行时间。因此,哈希索引可能不适合行数快速增长的表。 + 这种扩展是在前台进行的,因此可能会增加用户插入操作的执行时间。因此,hash 索引可能不适合行数快速增长的表。 @@ -66,7 +66,7 @@ 实现 - 哈希索引中有四种页:元页(第零页),其中包含静态分配的控制信息;主桶页;溢出页;以及位图页,后者用于跟踪已被释放且可供重用的溢出页。在寻址时,位图页被视为溢出页的一个子集。 + hash 索引中有四种页:元页(第零页),其中包含静态分配的控制信息;主桶页;溢出页;以及位图页,后者用于跟踪已被释放且可供重用的溢出页。在寻址时,位图页被视为溢出页的一个子集。 @@ -74,15 +74,15 @@ - 主桶页和溢出页是独立分配的,因为任何一个给定索引相对于其桶数,可能需要更多或更少的溢出页。哈希代码使用了一组颇有意思的寻址规则,以支持可变数量的溢出页,同时又不必在主桶页创建后再移动它们。 + 主桶页和溢出页是独立分配的,因为任何一个给定索引相对于其桶数,可能需要更多或更少的溢出页。hash 实现代码使用了一组颇有意思的寻址规则,以支持可变数量的溢出页,同时又不必在主桶页创建后再移动它们。 - 被索引表中的每一行,都由哈希索引中的单个索引元组表示。哈希索引元组存储在桶页中,如果存在溢出页,也会存储在溢出页中。为了加快搜索速度,我们将任一索引页中的索引项按哈希码排序,从而可以在索引页内使用二分查找。但请注意,并不假定同一桶中不同索引页之间的哈希码具有任何相对顺序。 + 被索引表中的每一行,都由 hash 索引中的单个索引元组表示。Hash 索引元组存储在桶页中,如果存在溢出页,也会存储在溢出页中。为了加快搜索速度,我们将任一索引页中的索引项按 hash 码排序,从而可以在索引页内使用二分查找。但请注意,并不假定同一桶中不同索引页之间的 hash 码具有任何相对顺序。 - 用于扩展哈希索引的桶拆分算法过于复杂,这里不再展开说明;但在src/backend/access/hash/README中有更详细的描述。该拆分算法具备崩溃安全性,如果未能成功完成,可以重新启动。 + 用于扩展 hash 索引的桶拆分算法过于复杂,这里不再展开说明;但在src/backend/access/hash/README中有更详细的描述。该拆分算法具备崩溃安全性,如果未能成功完成,可以重新启动。 diff --git a/zh/14/high-availability.sgml b/zh/14/high-availability.sgml index ed95c368..2b00f529 100644 --- a/zh/14/high-availability.sgml +++ b/zh/14/high-availability.sgml @@ -19,7 +19,7 @@ - 某些方案通过只允许一台服务器修改数据来处理同步。能够修改数据的服务器称为读/写、主库(master)主库(primary)服务器。跟踪主库变更的服务器称为备库。只能在被提升为主库之后才能连接的备库称为温备,而能够接受连接并提供只读查询的备库称为热备。 + 某些方案通过只允许一台服务器修改数据来处理同步。能够修改数据的服务器称为读/写、主库(master)主库(primary)服务器。跟踪主库变更的服务器称为备库(standby)备库(secondary)。只能在被提升为主库之后才能连接的备库称为温备,而能够接受连接并提供只读查询的备库称为热备 @@ -102,7 +102,7 @@ protocol to make nodes agree on a serializable transactional order. - 基于触发器的主库-备库复制 + 基于触发器的主备复制 @@ -180,8 +180,8 @@ protocol to make nodes agree on a serializable transactional order. 文件系统复制 预写式日志传送 逻辑复制 - 基于触发器的复制 - 基于 SQL 的复制中间件 + 基于触发器&zwsp;的复制 + SQL 复制中间件 异步多主复制 同步多主复制 @@ -238,7 +238,7 @@ protocol to make nodes agree on a serializable transactional order. - 主库无额外负载 + 主库无额外开销 @@ -354,7 +354,7 @@ protocol to make nodes agree on a serializable transactional order. - 连续归档可用于创建一种高可用性(HA)集簇配置,其中有一个或多个备库随时准备在主库失效时接管操作。这种能力通常称为温备日志传送。 + 持续归档可用于创建一种高可用性(HA)集簇配置,其中有一个或多个备库随时准备在主库失效时接管操作。这种能力通常称为温备日志传送 @@ -428,9 +428,7 @@ protocol to make nodes agree on a serializable transactional order. 启动时,备库首先通过调用 restore_command 恢复归档位置中所有可用的 WAL。一旦到达其中可用 WAL 的末尾,并且 restore_command 失败,它就会尝试恢复 pg_wal 目录中可用的任何 WAL。如果这也失败,并且已经配置了流复制,备库就会尝试连接到主库,并从归档或 pg_wal 中找到的最后一条有效记录开始流式接收 WAL。如果这仍然失败,或者没有配置流复制,或者连接后来断开,备库就会返回第 1 步,再次尝试从归档恢复文件。这样在归档、pg_wal 以及流复制之间循环重试,直到服务器停止或被提升。 - - 当执行 pg_ctl promote 或调用 pg_promote() 时,将退出备库模式,服务器切换到正常运行。在故障切换之前,会先恢复归档中或 pg_wal 中立即可用的所有 WAL,但不会尝试连接主库。 - + 运行 pg_ctl promote、调用 pg_promote(),或发现触发文件(promote_trigger_file)时,服务器会退出备库模式,切换到正常运行。在故障切换前,会恢复归档或 pg_wal 中能立即获取的所有 WAL,但不会尝试连接主库。 @@ -528,7 +526,7 @@ archive_cleanup_command = 'pg_archivecleanup /path/to/archive %r' 认证 - 正确设置复制访问权限非常重要,因为从 WAL 流中很容易提取出需要权限才能访问的信息,因此必须确保只有受信任的用户才能读取它。备库必须以具有 REPLICATION 权限的账户或超级用户身份向主库认证。建议专门创建一个具有 REPLICATIONLOGIN 权限的用户账户用于复制。虽然 REPLICATION 权限的权限很高,但它并不允许用户修改主系统上的任何数据,而 SUPERUSER 权限则允许。 + 正确设置复制访问权限非常重要,因为从 WAL 流中很容易提取出需要权限才能访问的信息,因此必须确保只有受信任的用户才能读取它。备库必须以具有 REPLICATION 权限的账户或超级用户身份向主库认证。建议专门创建一个具有 REPLICATIONLOGIN 权限的用户账户用于复制。虽然 REPLICATION 权限很高,但它并不允许用户修改主系统上的任何数据,而 SUPERUSER 权限则允许。 @@ -539,7 +537,7 @@ archive_cleanup_command = 'pg_archivecleanup /path/to/archive %r' # as a replication standby if the user's password is correctly supplied. # # TYPE DATABASE USER ADDRESS METHOD -host replication foo 192.168.1.100/32 scram-sha-256 +host replication foo 192.168.1.100/32 md5 @@ -559,7 +557,7 @@ primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass' 流复制的一个重要健康指标,是主库上已经生成但尚未在备库上应用的 WAL 记录量。你可以通过比较主库上的当前 WAL 写入位置和备库收到的最后一个 WAL 位置来计算这种滞后。这些位置分别可以用主库上的 pg_current_wal_lsn 和备库上的 pg_last_wal_receive_lsn 取得(详见 )。备库上的最后一个 WAL 接收位置也会显示在 WAL 接收进程的进程状态中,即通过 ps 命令显示的状态(详见 )。 - 你可以通过 pg_stat_replication 视图取得 WAL 发送进程列表。pg_current_wal_lsn 与该视图的 sent_lsn 字段之间存在较大差异,可能表示主库负载很重;而 sent_lsn 与备库上的 pg_last_wal_receive_lsn 之间存在较大差异,则可能表示网络延迟,或者备库负载很重。 + 你可以通过 pg_stat_replication 视图取得 WAL 发送进程列表。pg_current_wal_lsn 与该视图的 sent_lsn 字段之间存在较大差异,可能表示主库负载很重;而 sent_lsn 与备库上的 pg_last_wal_receive_lsn 之间存在差异,则可能表示网络延迟,或者备库负载很重。 在热备上,WAL 接收进程的状态可以通过 @@ -575,21 +573,10 @@ primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass' 流复制 - 复制槽提供了一种自动化方法,以确保主库在所有备库都收到 WAL 段之前不会删除它们,并且即使备库处于断开状态,主库也不会删除可能导致恢复冲突的行。 - - - 如果不使用复制槽,也可以通过阻止旧的 WAL 段被移除,或者通过把这些段保存到归档中。这些方法的一个缺点是,它们通常会保留多于实际所需数量的 WAL 段,而复制槽只会保留已知确实需要的段数。 - - - 类似地,如果不配合复制槽单独使用 ,它虽然能防止相关的行被清理而避免因清理产生的问题,但在备库未连接的那段时间内并不能提供保护。 + 复制槽提供了一种自动化方法,以确保主库在所有备库都收到 WAL 段之前不会删除它们,并且即使备库处于断开状态,主库也不会删除那些一旦删除就可能导致恢复冲突的行。 - - - - 注意,复制槽可能会导致服务器保留过多的 WAL 段,以至于占满分配给pg_wal的空间。可以使用来限制复制槽保留的 WAL 文件大小。 - - - + 除了使用复制槽,也可以通过 防止旧 WAL 段被删除,或者使用 将这些段保存在归档中。不过,这些方法通常会保留多于实际所需的 WAL 段,而复制槽只保留已知必需的段数。另一方面,复制槽保留的 WAL 段也可能过多,填满分配给 pg_wal 的空间; 可以限制复制槽保留的 WAL 文件大小。 + 类似地, 可以保护相关行,避免它们被清理删除,但前者在备库未连接期间无法提供保护,后者则通常需要设为较大的值才能提供充分保护。复制槽克服了这些缺点。 查询和管理复制槽 @@ -604,7 +591,7 @@ primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass' 复制槽可以通过流复制协议(见)或者 SQL 函数(见)创建和删除。 - + 配置示例 你可以像下面这样创建一个复制槽: @@ -685,7 +672,7 @@ primary_slot_name = 'node_a_slot' - 只读事务和事务回滚不需要等待备库的回应。子事务提交也不需要等待备库响应,只有顶层提交才需要等待。数据装载或索引构建等长时间运行的动作,不会一直等到最终提交消息。所有两阶段提交操作都需要等待提交,包括 prepare 和 commit。 + 只读事务和事务回滚不需要等待备库的回应。子事务提交也不需要等待备库响应,只有顶层提交才需要等待。数据装载或索引构建等长时间运行的动作,直到最终提交时才会等待。所有两阶段提交操作都需要等待提交,包括准备和提交两个阶段。 @@ -700,7 +687,7 @@ primary_slot_name = 'node_a_slot' - 当提交记录已经在主库上写入磁盘之后,WAL 记录就会被发送到备库。每当新的一批 WAL 数据被写入磁盘时,备库就会发送回复消息,除非备库上的wal_receiver_status_interval被设置为零。如果synchronous_commit被设置为remote_apply,那么备库会在提交记录被重放时发送回复消息,从而使该事务变得可见。如果根据主库上的synchronous_standby_names设置,该备库被选为同步备库,那么它发出的回复会与其他同步备库的回复一起,用于决定何时释放那些正在等待确认提交记录已被收到的事务。这些参数允许管理员指定哪些备库应作为同步备库。注意,同步复制的配置主要在主库上进行。被命名的备库必须直接连接到主库;主库并不知道使用级联复制的下游备库。 + 当提交记录已经在主库上写入磁盘之后,WAL 记录就会被发送到备库。每当新的一批 WAL 数据被写入磁盘时,备库就会发送回复消息,除非备库上的wal_receiver_status_interval被设置为零。如果synchronous_commit被设置为remote_apply,那么备库会在提交记录被重放、该事务变得可见时发送回复消息。如果根据主库上的synchronous_standby_names设置,该备库被选为同步备库,那么它发出的回复会与其他同步备库的回复一起,用于决定何时释放那些正在等待确认提交记录已被收到的事务。这些参数允许管理员指定哪些备库应作为同步备库。注意,同步复制的配置主要在主库上进行。被命名的备库必须直接连接到主库;主库并不知道使用级联复制的下游备库。 @@ -712,7 +699,7 @@ primary_slot_name = 'node_a_slot' - 如果请求快速关闭,用户将停止等待。不过,与使用异步复制时一样,在所有尚未解决的 WAL 记录传输到当前已连接的备库之前,服务器不会完全关闭。 + 如果请求快速关闭,用户将停止等待。不过,与使用异步复制时一样,在所有尚未传送的 WAL 记录传输到当前已连接的备库之前,服务器不会完全关闭。 @@ -734,14 +721,14 @@ synchronous_standby_names = 'FIRST 2 (s1, s2, s3)' 在这个例子中,如果四台备库s1s2s3s4都在运行,则s1s2会被选为同步备库,因为它们的名字在备库名称列表中出现得更早。s3是潜在的同步备库,当s1s2中的任意一台失效时,它就会接替其角色。由于s4的名称不在列表中,因此它是异步备库。 - ANY方法指定基于法定人数的同步复制,使事务提交等待,直到它们的 WAL 记录被复制到列表中所要求数量的同步备库中的至少这么多台。 + ANY方法指定基于法定人数的同步复制,使事务提交等待,直到它们的 WAL 记录被复制到列表中至少所要求数量的同步备库。 基于法定人数的多同步备库的synchronous_standby_names示例如下: synchronous_standby_names = 'ANY 2 (s1, s2, s3)' - 在这个例子中,如果四台备库s1s2s3s4都在运行,事务提交将等待来自s1s2s3中的任意两台备库的回复。由于s4的名字不在列表中,因此它是异步备库。 + 在这个例子中,如果四台备库s1s2s3s4都在运行,事务提交将等待来自s1s2s3中的至少任意两台备库的回复。由于s4的名字不在列表中,因此它是异步备库。 备库的同步状态可以通过pg_stat_replication视图查看。 @@ -764,7 +751,7 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' - 通过在应用级别(在主库上)指定同步复制选项,我们可以只对最重要的变更提供同步复制,而不会拖慢整体工作负载。应用级别选项是让高性能应用获得同步复制收益的一种重要而实用的工具。 + 通过在应用级别(在主库上)指定同步复制选项,我们可以只对最重要的变更提供同步复制,而不会拖慢大部分工作负载。应用级别选项是让高性能应用获得同步复制收益的一种重要而实用的工具。 @@ -797,7 +784,7 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' - 如果主库在提交正等待确认时重启,这些等待中的事务会在主库恢复后被标记为已完全提交。无法确定在主库崩溃时,所有备库是否已经收到全部尚未处理的 WAL 数据。因此,某些事务可能不会在备库上显示为已提交,即使它们在主库上显示为已提交。我们所提供的保证是:只有在确认 WAL 数据已经被所有同步备库安全接收之后,应用才会收到事务成功提交的显式确认。 + 如果主库在提交正等待确认时重启,这些等待中的事务会在主库恢复后被标记为已完全提交。无法确定在主库崩溃时,所有备库是否已经收到全部待传送的 WAL 数据。因此,某些事务可能不会在备库上显示为已提交,即使它们在主库上显示为已提交。我们所提供的保证是:只有在确认 WAL 数据已经被所有同步备库安全接收之后,应用才会收到事务成功提交的显式确认。 @@ -808,9 +795,7 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' 如果主库与剩余的备库隔离开了,你应当故障切换到那些剩余备库中最佳的候选者。 - - 如果你需要在事务正在等待时重新创建一台备库,请确保pg_start_backup()pg_stop_backup()是在一个把synchronous_commit设置为off的会话中运行的,否则这些请求将永远等待备库出现。 - + 如果需要在事务等待期间重新创建备库,请确保在 synchronous_commit = off 的会话中运行 pg_start_backup() 和 pg_stop_backup() 命令,否则这些请求会一直等待备库出现。 @@ -831,43 +816,41 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' 如果archive_mode被设置为on,那么归档器在恢复期间或备库模式下不会启用。如果备库被提升,它会在提升后开始归档,但不会归档任何不是由它自己生成的 WAL 或时间线历史文件。要在归档中获得完整的一系列 WAL 文件,就必须确保所有 WAL 在到达备库之前已经被归档。对于基于文件的日志传送,这天然成立,因为备库只能恢复归档中找到的文件;但在启用流复制时则不是这样。当服务器不处于恢复模式时,onalways模式之间没有区别。 - + - - 故障切换 + + 故障切换 - + 如果主库失效,备库就应该开始执行故障切换过程。 - + 如果备库失效,则不需要发生故障切换。如果备库能够重新启动,即使是在稍后某个时间点,恢复过程也可以立即重新开始,从而利用可重启恢复的优势。如果备库无法重新启动,则应创建一个全新的备库实例。 - + 如果主库失效,而备库成为新的主库,那么旧主库之后如果重新启动,你必须有一种机制通知它,它已经不再是主库。这有时被称为STONITH(Shoot The Other Node In The Head),它对于避免两个系统都认为自己是主库的情况至关重要,因为那种情况会导致混乱,并最终造成数据丢失。 - + 许多故障切换系统只使用两个系统,即主库和备库,并通过某种心跳机制连接它们,以持续验证两者之间的连通性以及主库的可用性。也可以使用第三个系统(称为见证服务器)来防止某些不恰当的故障切换,但除非设置得足够谨慎并经过严格测试,否则额外增加的复杂性可能并不值得。 - + PostgreSQL并不提供用于识别主库故障并通知备库的系统软件。现在已经存在许多这样的工具,并且它们通常能很好地与成功故障切换所需的操作系统设施整合在一起,例如 IP 地址迁移。 - - 一旦故障切换到备库,系统中就只剩下一台服务器在运行。这被称为退化状态。原来的备库现在成为主库,而原来的主库已经停机,并且可能持续停机。要恢复到正常运行状态,就必须重新创建一台备库:要么在原主库恢复后在其上重建,要么在第三台可能是全新的服务器上重建。在大型集簇上,可以使用工具来加快这一过程。一旦完成,就可以认为主库和备库已经交换了角色。有些人会选择使用第三台服务器,在新的备库重建完成之前为新的主库提供备份,但显然这会让系统配置和操作流程更加复杂。 + + 一旦故障切换到备库,系统中就只剩下一台服务器在运行。这被称为退化状态。原来的备库现在成为主库,而原来的主库已经停机,并且可能持续停机。要恢复到正常运行状态,就必须重新创建一台备库:要么在原主库恢复后在其上重建,要么在第三台可能是全新的服务器上重建。在大型集簇上,可以使用工具来加快这一过程。一旦完成,就可以认为主库和备库已经交换了角色。有些人会选择使用第三台服务器,在新的备库重建完成之前为新的主库提供后备支持,但显然这会让系统配置和操作流程更加复杂。 - + 因此,从主库切换到备库可以很快,但重新准备故障切换集簇仍然需要时间。定期在主库与备库之间进行切换是有益的,因为它允许每个系统定期停机维护。这也相当于对故障切换机制进行测试,以确保真正需要它时它能够正常工作。建议编写书面的管理操作规程。 - - 要触发日志传送备库的故障切换,请运行pg_ctl promote或调用pg_promote()。如果你设置的是仅用于从主库卸载只读查询的报表服务器,而不是用于高可用目的,那么就不需要执行提升。 - - + 要触发日志传送备库的故障切换,可以运行 pg_ctl promote、调用 pg_promote(),或按照 promote_trigger_file 指定的文件名和路径创建触发文件。如果计划通过运行 pg_ctl promote 或调用 pg_promote() 进行故障切换,就不需要设置 promote_trigger_file。如果所配置的报表服务器只是用来分担主库的只读查询,而不用于高可用,则不需要提升它。 + 热备 @@ -888,7 +871,7 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' 用户概览 - 当备库上的参数被设置为真时,一旦恢复把系统带到一致状态并为热备做好准备,它就会开始接受连接。所有这类连接都严格是只读的,甚至不能写入临时表。 + 当备库上的参数被设置为真时,一旦恢复把系统带到一致状态,它就会开始接受连接。所有这类连接都严格是只读的,甚至不能写入临时表。 @@ -916,7 +899,7 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' - 事务管理命令: + 事务管理命令: @@ -930,7 +913,7 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' - EXCEPTION块或其他内部子事务 + EXCEPTION块和其他内部子事务 @@ -970,7 +953,7 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' 数据操纵语言(DML):INSERTUPDATEDELETECOPY FROM、 - TRUNCATE。请注意,恢复期间不存在任何允许执行触发器的动作。这个限制甚至适用于临时表,因为不分配事务 ID 就无法读取或写入表行,而这在热备环境中目前是不可能的。 + TRUNCATE。请注意,恢复期间不存在任何允许执行触发器的动作。这个限制甚至适用于临时表,因为不分配事务 ID 就无法读取或写入表行,而目前热备环境中无法分配事务 ID。 @@ -1005,13 +988,13 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' - BEGIN READ WRITE, + BEGIN READ WRITESTART TRANSACTION READ WRITE - SET TRANSACTION READ WRITE, + SET TRANSACTION READ WRITESET SESSION CHARACTERISTICS AS TRANSACTION READ WRITE @@ -1027,7 +1010,7 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' 两阶段提交命令:PREPARE TRANSACTIONCOMMIT PREPAREDROLLBACK PREPARED, - 因为即使是只读事务,在 prepare 阶段(两阶段提交的第一阶段)也需要写入 WAL。 + 因为即使是只读事务,在准备阶段(两阶段提交的第一阶段)也需要写入 WAL。 @@ -1113,25 +1096,20 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' - 一旦max_standby_archive_delaymax_standby_streaming_delay指定的延迟被超越,冲突查询将被取消。这通常仅导致一个取消错误,尽管在重放一个DROP DATABASE的情况下整个冲突会话都将被中断。另外,如果冲突发生在一个被空闲事务持有的锁上,该冲突会话会被中断(这种行为可能在未来被改变)。 + 一旦max_standby_archive_delaymax_standby_streaming_delay指定的延迟被超越,冲突查询将被取消。这通常仅导致一个取消错误,尽管在重放一个DROP DATABASE的情况下整个冲突会话都将被终止。另外,如果冲突发生在一个被空闲事务持有的锁上,该冲突会话会被终止(这种行为可能在未来被改变)。 - - 被取消的查询可能会立即被重试(当然是在开始一个新的事务后)。因为查询取消依赖于 WAL 记录被重放的本质,如果一个被取消的查询被再次执行,它可能会很好地成功完成。 - + 被取消的查询可以立即重试(当然,要先开始一个新事务)。由于查询取消取决于正在重放的 WAL 记录的性质,被取消的查询再次执行时完全可能成功。 - 记住延迟参数是从 WAL 数据被备库收到后流逝的时间。因此,留给备库上任何一个查询的宽限期从不会超过延迟参数,并且如果备库已经由于等待之前的查询完成而落后或者因为过重的更新负载而无法跟上主库,宽限期可能会更少。 + 请记住,延迟参数要与备库收到 WAL 数据之后经过的时间进行比较。因此,留给备库上任何一个查询的宽限期从不会超过延迟参数,并且如果备库已经由于等待之前的查询完成而落后或者因为过重的更新负载而无法跟上主库,宽限期可能会更少。 - 备库查询与 WAL 重放发生冲突的最常见原因是过早清理。正常情况下,当没有事务需要看到旧行版本时,PostgreSQL允许清理这些旧行版本,以保证按照 MVCC 规则得到正确的数据可见性。不过,这条规则只能应用于在主库上执行的事务。因此,主库上的清理有可能移除某个备库事务仍然可见的行版本。 + 备库查询与 WAL 重放发生冲突的最常见原因是过早清理。正常情况下,当不再有事务需要看到旧行版本来保证符合 MVCC 规则的数据可见性时,PostgreSQL允许清理这些旧行版本。不过,这条规则只能应用于在主库上执行的事务。因此,主库上的清理有可能移除某个备库事务仍然可见的行版本。 - - 行版本清理并不是与备库查询发生冲突的唯一潜在原因。所有仅索引扫描(包括在备库上运行的那些)都必须使用一个MVCC快照,它与可见性映射一致。因此,每当VACUUM在可见性映射中把某个页面标记为全可见,而该页面中包含一行或多行对所有备库查询都不可见的数据时,就必须产生冲突。所以,即使针对一个没有更新或删除任何需要清理行的表执行VACUUM,也可能导致冲突。 - + 有经验的用户应注意,行版本清理和行版本冻结都有可能与备库查询冲突。手动运行 VACUUM FREEZE 很可能导致冲突,即使表中没有更新过或删除过的行也是如此。 用户应当清楚,主库上经常并且大量更新的表,会很快导致备库上的长时间运行查询被取消。在这种情况下,把max_standby_archive_delaymax_standby_streaming_delay设置为有限值,可以视作类似于设置statement_timeout。 @@ -1141,6 +1119,8 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' 如果备库查询被取消的次数多得令人无法接受,也存在补救办法。第一种选择是设置hot_standby_feedback参数,它会阻止VACUUM移除最近死亡的行,因此不会发生清理冲突。如果这样做,你应当注意这会延迟主库上死行的清理,从而可能导致不希望出现的表膨胀。不过,清理情况不会比直接在主库上运行这些备库查询更糟,而且你仍然可以获得把执行卸载到备库上的好处。如果备库经常连接又断开,你可能还需要进行一些调整,以应对无法提供hot_standby_feedback反馈的那段时间。例如,可以考虑增大max_standby_archive_delay,使查询在断开期间不会因为 WAL 归档文件中的冲突而被迅速取消。你也应考虑增大max_standby_streaming_delay,以避免重新连接后由于新到达的流式 WAL 条目而被快速取消。 + 另一种选择是增大主库上的 ,使死行不会像通常那样很快被清理。这样,无需将 max_standby_streaming_delay 设得很大,就能让备库查询在被取消前有更多执行时间。不过,这种方法难以保证具体的执行时间窗口,因为 vacuum_defer_cleanup_age 是按主库上执行的事务数来衡量的。 + 查询取消的数量及其原因可以通过备库上的pg_stat_database_conflicts系统视图查看。pg_stat_database系统视图也包含汇总信息。 @@ -1165,7 +1145,7 @@ LOG: consistent recovery state reached LOG: database system is ready to accept read-only connections - 一致性信息在主库上每个检查点时记录一次。在主库的wal_level未设置为replicalogical期间所写入的 WAL 被读取时,无法启用热备。即使已经达到一致状态,如果同时满足下列两个条件,恢复快照也可能还没有准备好用于热备,从而推迟接受只读连接。要启用热备,就需要在主库上结束那些包含超过 64 个子事务的长生命周期写事务。 + 一致性信息在主库上每个检查点时记录一次。在主库的wal_level未设置为replicalogical期间所写入的 WAL 被读取时,无法启用热备。如果同时存在以下两种情况,达到一致状态也可能会被推迟: @@ -1233,7 +1213,7 @@ HINT: You can then restart the server after making the necessary configuration - 主库上写出的事务状态 "hint bits" 不会被 WAL 记录,因此备库上的数据很可能会再次写出这些提示位。这样一来,即使所有用户都是只读的,备库仍然会执行磁盘写操作;不过数据值本身并不会发生变化。用户仍然会写出大型排序临时文件,并重新生成 relcache 信息文件,因此在热备模式下,数据库没有任何部分是真正只读的。还要注意,使用dblink模块写入远程数据库,以及借助 PL 函数执行其他数据库外部操作,依然是可能的,即使该事务在本地是只读的。 + 主库上写出的事务状态“提示位” 不会被 WAL 记录,因此备库上的数据很可能会再次写出这些提示位。这样一来,即使所有用户都是只读的,备库仍然会执行磁盘写操作;不过数据值本身并不会发生变化。用户仍然会写出大型排序临时文件,并重新生成 relcache 信息文件,因此在热备模式下,数据库没有任何部分是真正只读的。还要注意,使用dblink模块写入远程数据库,以及借助 PL 函数执行其他数据库外部操作,依然是可能的,即使该事务在本地是只读的。 @@ -1242,7 +1222,7 @@ HINT: You can then restart the server after making the necessary configuration - 数据定义语言:例如 CREATE INDEX + 数据定义语言(DDL):例如 CREATE INDEX @@ -1316,9 +1296,7 @@ HINT: You can then restart the server after making the necessary configuration 在普通(非恢复)模式下,如果你对一个具有登录能力的角色执行DROP USERDROP ROLE,而该用户仍然处于连接状态,那么已连接用户不会发生任何变化 — 他们会继续保持连接,不过之后不能重新连接。这种行为在恢复期间同样适用,因此在主库上执行一次DROP USER并不会断开备库上的该用户连接。 - - 累积统计系统在恢复期间是活动的。所有扫描、读取、块访问、索引使用等,都会在备库上照常记录。不过,WAL 重放不会增加关系和数据库级别的特定计数器。也就是说,重放不会增加pg_stat_all_tables中的列(例如n_tup_ins),启动进程执行的读写也不会被记录到pg_statio_视图中,相关的pg_stat_database列也不会增加。 - + 统计收集器在恢复期间保持活动状态。所有扫描、读取、块、索引使用情况等,都会在备库上正常记录。重放操作不会重复记录其在主库上产生的统计影响,因此重放一次插入不会增加 pg_stat_user_tables 的 Inserts 列。统计文件会在恢复开始时被删除,因此主库和备库的统计信息不同;这是特性,不是缺陷。 恢复期间自动清理不会运行。它会在恢复结束时正常启动。 @@ -1336,13 +1314,9 @@ HINT: You can then restart the server after making the necessary configuration 多个参数已经在中提到过。 - - 在主库上,可以使用参数。如果设置在主库上,则不会生效。 - + 在主库上,可以使用 参数。 在主库上设置时没有效果。 - - 在备库上,可以使用这几个参数。 - + 在备库上,可以使用 参数。只要服务器仍处于备库模式, 就没有效果,不过备库成为主库后,它就会起作用。 diff --git a/zh/14/history.sgml b/zh/14/history.sgml index 33c6b198..174abe22 100644 --- a/zh/14/history.sgml +++ b/zh/14/history.sgml @@ -163,8 +163,7 @@ - 关于此后每个 PostgreSQL 发布版本发生了哪些变化的详情,可在 - https://www.postgresql.org/docs/release/ 查阅。 + 自那以后 PostgreSQL 发生了哪些变化,可见 diff --git a/zh/14/images/fixup-svg.xsl b/zh/14/images/fixup-svg.xsl index d6c46b36..cf7169bb 100644 --- a/zh/14/images/fixup-svg.xsl +++ b/zh/14/images/fixup-svg.xsl @@ -32,6 +32,11 @@ Fix stroke="transparent" attribute, which is invalid SVG. none + + + 'Alibaba PuHuiTi 3.0',serif + + diff --git a/zh/14/images/gin.gv b/zh/14/images/gin.gv index 097e9102..b8e26542 100644 --- a/zh/14/images/gin.gv +++ b/zh/14/images/gin.gv @@ -1,11 +1,12 @@ digraph "gin" { layout=dot; - node [label="", shape=box, style=filled, fillcolor=gray, width=1.4]; + fontname="Alibaba PuHuiTi 3.0"; + node [fontname="Alibaba PuHuiTi 3.0", label="", shape=box, style=filled, fillcolor=gray, width=1.4]; - m1 [label="meta page"]; + m1 [label="元页"]; subgraph cluster01 { - label="entry tree"; + label="键项树"; subgraph egroup1 { rank=same; e1; @@ -27,13 +28,13 @@ digraph "gin" { e4 -> e8; e4 -> e9; - e6 [fillcolor=green, label="posting list"]; - e8 [fillcolor=green, label="posting list"]; - e9 [fillcolor=green, label="posting list"]; + e6 [fillcolor=green, label="倒排列表"]; + e8 [fillcolor=green, label="倒排列表"]; + e9 [fillcolor=green, label="倒排列表"]; } subgraph cluster02 { - label="posting tree"; + label="倒排树"; subgraph pgroup1 { rank=same; p1; @@ -45,22 +46,22 @@ digraph "gin" { p1 -> p2; p1 -> p3; - p2 [fillcolor=green, label="heap ptr"]; - p3 [fillcolor=green, label="heap ptr"]; + p2 [fillcolor=green, label="堆指针"]; + p3 [fillcolor=green, label="堆指针"]; } subgraph cluster03 { - label="posting tree"; + label="倒排树"; subgraph pgroup3 { rank=same; p4; } - p4 [fillcolor=green, label="heap ptr"]; + p4 [fillcolor=green, label="堆指针"]; } subgraph cluster04 { - label="posting tree"; + label="倒排树"; subgraph pgroup4 { rank=same; p5; @@ -72,12 +73,12 @@ digraph "gin" { p5 -> p6; p5 -> p7; - p6 [fillcolor=green, label="heap ptr"]; - p7 [fillcolor=green, label="heap ptr"]; + p6 [fillcolor=green, label="堆指针"]; + p7 [fillcolor=green, label="堆指针"]; } subgraph cluster05 { - label="pending list"; + label="待处理列表"; node [style=filled, fillcolor=red]; n1 -> n2 -> n3 -> n4; } diff --git a/zh/14/images/gin.svg b/zh/14/images/gin.svg index 04fe85ba..79cf14a9 100644 --- a/zh/14/images/gin.svg +++ b/zh/14/images/gin.svg @@ -9,33 +9,33 @@ cluster01 -entry tree +键项树 cluster02 -posting tree +倒排树 cluster03 -posting tree +倒排树 cluster04 -posting tree +倒排树 cluster05 -pending list +待处理列表 m1 -meta page +元页 @@ -113,7 +113,7 @@ e6 -posting list +倒排列表 @@ -142,7 +142,7 @@ e8 -posting list +倒排列表 @@ -154,7 +154,7 @@ e9 -posting list +倒排列表 @@ -195,7 +195,7 @@ p4 -heap ptr +堆指针 @@ -224,7 +224,7 @@ p2 -heap ptr +堆指针 @@ -236,7 +236,7 @@ p3 -heap ptr +堆指针 @@ -254,7 +254,7 @@ p6 -heap ptr +堆指针 @@ -266,7 +266,7 @@ p7 -heap ptr +堆指针 diff --git a/zh/14/indexam.sgml b/zh/14/indexam.sgml index d5407b99..fe638d40 100644 --- a/zh/14/indexam.sgml +++ b/zh/14/indexam.sgml @@ -21,7 +21,7 @@ - 索引本质上是从一些数据键值到行版本(元组)在索引父表中的元组标识符TID)的映射。一个 TID 由块号以及该块中的项号组成(见 元组标识符(TIDs)的映射。一个 TID 由块号以及该块中的项号组成(见 )。这些信息足以从表中取出某个特定的行版本。索引并不直接知道在 MVCC 之下同一逻辑行可能会存在多个现存版本;对索引来说,每个元组都是一个独立对象,需要它自己的索引条目。因此,对一行的更新总会为该行创建全新的索引条目,即使键值并未改变也是如此。(HOT 元组是这一说法的例外;但索引同样不直接处理它们。)当死元组自身被回收时(通过清理),它们对应的索引条目也会被回收。 @@ -44,89 +44,72 @@ typedef struct IndexAmRoutine NodeTag type; /* - * Total number of strategies (operators) by which we can traverse/search - * this AM. Zero if AM does not have a fixed set of strategy assignments. + * 可用于遍历或搜索此 AM 的策略(操作符)总数。 + * 如果 AM 没有固定的一组策略分配,则为零。 */ uint16 amstrategies; - /* total number of support functions that this AM uses */ + /* 此 AM 使用的支持函数总数 */ uint16 amsupport; - /* opclass options support function number or 0 */ + /* 操作符类选项支持函数编号,或为 0 */ uint16 amoptsprocnum; - /* does AM support ORDER BY indexed column's value? */ + /* AM 是否支持按被索引列的值进行 ORDER BY? */ bool amcanorder; - /* does AM support ORDER BY result of an operator on indexed column? */ + /* AM 是否支持按被索引列上操作符的结果进行 ORDER BY? */ bool amcanorderbyop; - /* does AM support hashing using API consistent with the hash AM? */ - bool amcanhash; - /* do operators within an opfamily have consistent equality semantics? */ - bool amconsistentequality; - /* do operators within an opfamily have consistent ordering semantics? */ - bool amconsistentordering; - /* does AM support backward scanning? */ + /* AM 是否支持反向扫描? */ bool amcanbackward; - /* does AM support UNIQUE indexes? */ + /* AM 是否支持 UNIQUE 索引? */ bool amcanunique; - /* does AM support multi-column indexes? */ + /* AM 是否支持多列索引? */ bool amcanmulticol; - /* does AM require scans to have a constraint on the first index column? */ + /* AM 是否要求扫描必须约束第一个索引列? */ bool amoptionalkey; - /* does AM handle ScalarArrayOpExpr quals? */ + /* AM 是否处理 ScalarArrayOpExpr 限定条件? */ bool amsearcharray; - /* does AM handle IS NULL/IS NOT NULL quals? */ + /* AM 是否处理 IS NULL/IS NOT NULL 限定条件? */ bool amsearchnulls; - /* can index storage data type differ from column data type? */ + /* 索引存储数据类型是否可以不同于列数据类型? */ bool amstorage; - /* can an index of this type be clustered on? */ + /* 是否可以按此类型的索引进行聚簇? */ bool amclusterable; - /* does AM handle predicate locks? */ + /* AM 是否处理谓词锁? */ bool ampredlocks; - /* does AM support parallel scan? */ + /* AM 是否支持并行扫描? */ bool amcanparallel; - /* does AM support parallel build? */ - bool amcanbuildparallel; - /* does AM support columns included with clause INCLUDE? */ + /* AM 是否支持由 INCLUDE 子句包含的列? */ bool amcaninclude; - /* does AM use maintenance_work_mem? */ + /* AM 是否使用 maintenance_work_mem? */ bool amusemaintenanceworkmem; - /* does AM summarize tuples, with at least all tuples in the block - * summarized in one summary */ - bool amsummarizing; - /* OR of parallel vacuum flags */ + /* 并行清理标志的 OR 组合 */ uint8 amparallelvacuumoptions; - /* type of data stored in index, or InvalidOid if variable */ + /* 索引中存储的数据类型;如果可变,则为 InvalidOid */ Oid amkeytype; - /* interface functions */ + /* 接口函数 */ ambuild_function ambuild; ambuildempty_function ambuildempty; aminsert_function aminsert; - aminsertcleanup_function aminsertcleanup; /* can be NULL */ ambulkdelete_function ambulkdelete; amvacuumcleanup_function amvacuumcleanup; - amcanreturn_function amcanreturn; /* can be NULL */ + amcanreturn_function amcanreturn; /* 可以为 NULL */ amcostestimate_function amcostestimate; - amgettreeheight_function amgettreeheight; /* can be NULL */ amoptions_function amoptions; - amproperty_function amproperty; /* can be NULL */ - ambuildphasename_function ambuildphasename; /* can be NULL */ + amproperty_function amproperty; /* 可以为 NULL */ + ambuildphasename_function ambuildphasename; /* 可以为 NULL */ amvalidate_function amvalidate; - amadjustmembers_function amadjustmembers; /* can be NULL */ + amadjustmembers_function amadjustmembers; /* 可以为 NULL */ ambeginscan_function ambeginscan; amrescan_function amrescan; - amgettuple_function amgettuple; /* can be NULL */ - amgetbitmap_function amgetbitmap; /* can be NULL */ + amgettuple_function amgettuple; /* 可以为 NULL */ + amgetbitmap_function amgetbitmap; /* 可以为 NULL */ amendscan_function amendscan; - ammarkpos_function ammarkpos; /* can be NULL */ - amrestrpos_function amrestrpos; /* can be NULL */ + ammarkpos_function ammarkpos; /* 可以为 NULL */ + amrestrpos_function amrestrpos; /* 可以为 NULL */ - /* interface functions to support parallel index scans */ - amestimateparallelscan_function amestimateparallelscan; /* can be NULL */ - aminitparallelscan_function aminitparallelscan; /* can be NULL */ - amparallelrescan_function amparallelrescan; /* can be NULL */ - - /* interface functions to support planning */ - amtranslate_strategy_function amtranslatestrategy; /* can be NULL */ - amtranslate_cmptype_function amtranslatecmptype; /* can be NULL */ + /* 支持并行索引扫描的接口函数 */ + amestimateparallelscan_function amestimateparallelscan; /* 可以为 NULL */ + aminitparallelscan_function aminitparallelscan; /* 可以为 NULL */ + amparallelrescan_function amparallelrescan; /* 可以为 NULL */ } IndexAmRoutine; @@ -140,17 +123,13 @@ typedef struct IndexAmRoutine - IndexAmRoutine 的某些标志字段还有一些不那么直观的含义。amcanunique 的要求见 amcanmulticol 标志表明该访问方法支持多键列索引,而 amoptionalkey 表明它允许在第一索引列上没有给出可索引限制子句时进行扫描。当 amcanmulticol 为假时,amoptionalkey 实质上表示该访问方法是否支持没有任何限制子句的全索引扫描。支持多个索引列的访问方法必须支持在第一列之后省略任意一个或全部列限制条件的扫描;但它们可以要求第一索引列必须出现某种限制条件,这通过把 amoptionalkey 设为假来表示。索引 AM 可能把 amoptionalkey 设为假的一个原因,是它不索引 NULL 值。由于大多数可索引操作符都是严格的(strict),因此对 NULL 输入不可能返回 true,所以乍看之下不存储 NULL 值的索引条目似乎很有吸引力:无论如何,这些条目似乎都不可能被索引扫描返回。然而,当某个索引扫描对给定索引列没有限制子句时,这个论证就不成立了。实践中这意味着,若索引把 amoptionalkey 设为真,就必须索引 NULL 值,因为规划器可能决定在完全没有扫描键的情况下使用这种索引。与此相关的另一个限制是,支持多个索引列的索引访问方法必须支持对第一列之后各列中的 NULL 值建立索引,因为规划器会假定该索引可用于不限制这些列的查询。例如,考虑一个在 (a,b) 上的索引以及查询 WHERE a = 4。系统会假定该索引可用于扫描满足 a = 4 的行;如果索引省略了 b 为 NULL 的行,这个假定就是错误的。不过,省略第一索引列为 NULL 的行是可以的。对 NULL 值建立索引的索引访问方法还可以设置 amsearchnulls,表示它支持把 IS NULLIS NOT NULL 子句作为搜索条件。 + IndexAmRoutine 的某些标志字段还有一些不那么直观的含义。amcanunique 的要求见 amcanmulticol 标志表明该访问方法支持多键列索引,而 amoptionalkey 表明它允许在第一索引列上没有给出可索引限制子句时进行扫描。当 amcanmulticol 为假时,amoptionalkey 实质上表示该访问方法是否支持没有任何限制子句的全索引扫描。支持多个索引列的访问方法必须支持在第一列之后省略任意一个或全部列限制条件的扫描;但它们可以要求第一索引列必须出现某种限制条件,这通过把 amoptionalkey 设为假来表示。索引 AM 可能把 amoptionalkey 设为假的一个原因,是它不索引 NULL 值。由于大多数可索引操作符都是严格的(strict),因此对 NULL 输入不可能返回 true,所以乍看之下不存储 NULL 值的索引条目似乎很有吸引力:无论如何,这些条目似乎都不可能被索引扫描返回。然而,当某个索引扫描对给定索引列没有限制子句时,这个论证就不成立了。实践中这意味着,若索引把 amoptionalkey 设为真,就必须索引 NULL 值,因为规划器可能决定在完全没有扫描键的情况下使用这种索引。与此相关的另一个限制是,支持多个索引列的索引访问方法必须支持对第一列之后各列中的 NULL 值建立索引,因为规划器会假定该索引可用于不限制这些列的查询。例如,考虑一个在 (a,b) 上的索引以及查询 WHERE a = 4。系统会假定该索引可用于扫描满足 a = 4 的行;如果索引省略了 b 为 NULL 的行,这个假定就是错误的。不过,省略第一索引列为 NULL 的行是可以的。对 NULL 值建立索引的索引访问方法还可以设置 amsearchnulls,表示它支持把 IS NULLIS NOT NULL 子句作为搜索条件。 amcaninclude 标志指示该访问方法是否支持包含列,也就是说,它是否能在键列之外额外存储其他列而不对其进行处理。上一段中的要求只适用于键列。特别是,amcanmulticol=falseamcaninclude=true 的组合是合理的:这表示只能有一个键列,但仍然可以有包含列。此外,不论 amoptionalkey 的取值如何,包含列都必须允许为 NULL。 - - amsummarizing 标志指示该访问方法是否会对被索引元组做提要化,并且提要粒度至少达到每个块一个提要。不指向单个元组,而是指向块范围(例如 BRIN)的访问方法,可能允许继续使用 HOT 优化。这不适用于索引谓词中引用的属性,对这类属性的更新总会禁用 HOT。 - - @@ -166,9 +145,7 @@ IndexBuildResult * ambuild (Relation heapRelation, Relation indexRelation, IndexInfo *indexInfo); - - 构建一个新索引。索引关系已经在物理上创建,但还是空的。它必须填入访问方法所需的任何固定数据,以及表中所有现有元组对应的条目。通常,ambuild 函数会调用 table_index_build_scan() 来扫描表中已有的元组,并计算需要插入索引的键值。该函数必须返回一个通过 palloc 分配的结构体,其中包含有关新索引的统计信息。amcanbuildparallel 标志指示该访问方法是否支持并行索引构建。设为 true 时,系统会尝试为构建分配并行工作进程。只支持非并行索引构建的访问方法应把该标志保留为 false。 - +构建新索引。索引关系已在物理上创建,但内容为空。必须填入访问方法所需的固定数据,以及表中所有已有元组对应的条目。通常,ambuild函数会调用table_index_build_scan()扫描表中现有的元组,并计算需要插入索引的键。函数必须返回一个通过 palloc 分配的结构体,其中包含新索引的统计信息。 @@ -206,16 +183,7 @@ aminsert (Relation indexRelation, - 如果索引 AM 希望在一条 SQL 语句中的连续索引插入之间缓存数据,它可以在 indexInfo->ii_Context 中分配空间,并把数据指针存入 indexInfo->ii_AmCache(该指针初始为 NULL)。如果在索引插入后需要释放内存之外的资源,可以提供 aminsertcleanup,它会在内存释放之前被调用。 - - - - -void -aminsertcleanup (Relation indexRelation, - IndexInfo *indexInfo); - - 清理由 indexInfo->ii_AmCache 在连续插入之间维护的状态。如果这些数据需要额外的清理步骤(例如释放已钉住的缓冲区),而仅释放内存还不够,那么这个函数就很有用。 + 如果索引 AM 希望在一条 SQL 语句中的连续索引插入之间缓存数据,它可以在 indexInfo->ii_Context 中分配空间,并把数据指针存入 indexInfo->ii_AmCache(该指针初始为 NULL)。 @@ -226,7 +194,7 @@ ambulkdelete (IndexVacuumInfo *info, IndexBulkDeleteCallback callback, void *callback_state); - 从索引中删除元组。这是一个批量删除操作,通常应通过扫描整个索引并检查每个条目是否应被删除来实现。必须调用传入的 callback 函数,其调用形式为 callback(TID, callback_state) returns bool,以确定由其引用 TID 标识的某个索引条目是否应删除。该函数必须返回 NULL,或者返回一个通过 palloc 分配的结构体,其中包含此次删除操作影响的统计信息。如果不需要向 amvacuumcleanup 传递信息,返回 NULL 也是可以的。 + 从索引中删除元组。这是一个批量删除操作,旨在通过扫描整个索引并检查每个条目是否应被删除来实现。必须调用传入的 callback 函数,其调用形式为 callback(TID, callback_state) returns bool,以确定由其引用 TID 标识的某个索引条目是否应删除。该函数必须返回 NULL,或者返回一个通过 palloc 分配的结构体,其中包含此次删除操作影响的统计信息。如果不需要向 amvacuumcleanup 传递信息,返回 NULL 也是可以的。 @@ -251,8 +219,7 @@ amvacuumcleanup (IndexVacuumInfo *info, bool amcanreturn (Relation indexRelation, int attno); - 检查索引是否能够在给定列上支持 仅索引扫描,做法是返回该列原始的被索引值。属性编号从 1 开始,也就是说第一列的 attno 为 1。若支持则返回真,否则返回假。如果支持包含列,这个函数应始终对包含列返回真,因为不能取回的包含列几乎没有意义。如果访问方法根本不支持仅索引扫描,那么它的 IndexAmRoutine 结构体中的 amcanreturn 字段可以设为 NULL。 + 检查索引能否通过返回给定列原始的被索引值,在该列上支持 仅索引扫描。属性编号从 1 开始,也就是说第一列的 attno 为 1。若支持则返回真,否则返回假。如果支持包含列,这个函数应始终对包含列返回真,因为不能取回的包含列几乎没有意义。如果访问方法根本不支持仅索引扫描,那么它的 IndexAmRoutine 结构体中的 amcanreturn 字段可以设为 NULL。 @@ -267,15 +234,7 @@ amcostestimate (PlannerInfo *root, double *indexCorrelation, double *indexPages); - 估计一次索引扫描的开销。该函数将在后面的 中详细讨论。 - - - - -int -amgettreeheight (Relation rel); - - 计算树形索引的高度。这一信息会通过 path->indexinfo->tree_height 提供给 amcostestimate 函数,可用于支持开销估计。其结果不会在其他地方使用,因此这个函数实际上也可以用来计算索引上任何一种适合装入整数、且开销估计函数可能想知道的数据。如果计算代价较高,把结果缓存到 RelationData.rd_amcache 中可能会有用。 + 估计一次索引扫描的代价。该函数将在后面的 中详细讨论。 @@ -284,7 +243,7 @@ bytea * amoptions (ArrayType *reloptions, bool validate); - 解析并验证索引的 reloptions 数组。只有当该索引存在非空的 reloptions 数组时才会调用此函数。reloptions 是一个 text 数组,其中的条目形如 name=value。该函数应构造一个 bytea 值,并将其复制到索引 relcache 条目的 rd_options 字段中。这个 bytea 值中的数据内容由访问方法自行定义;大多数标准访问方法使用结构体 StdRdOptions。当 validate 为真时,若存在未识别选项或无效取值,函数应报告合适的错误消息;当 validate 为假时,无效条目应被静默忽略。(当装载已存储在 pg_catalog 中的选项时,validate 为假;此时只有在访问方法改变了选项规则时才可能发现无效条目,而忽略过时条目是合适的。)如果希望采用默认行为,返回 NULL 也是可以的。 + 解析并验证索引的 reloptions 数组。只有当该索引存在非 NULL 的 reloptions 数组时才会调用此函数。reloptions 是一个 text 数组,其中的条目形如 name=value。该函数应构造一个 bytea 值,并将其复制到索引 relcache 条目的 rd_options 字段中。这个 bytea 值中的数据内容由访问方法自行定义;大多数标准访问方法使用结构体 StdRdOptions。当 validate 为真时,若存在未识别选项或无效取值,函数应报告合适的错误消息;当 validate 为假时,无效条目应被静默忽略。(当装载已存储在 pg_catalog 中的选项时,validate 为假;此时只有在访问方法改变了选项规则时才可能发现无效条目,而忽略过时条目是合适的。)如果希望采用默认行为,返回 NULL 也是可以的。 @@ -298,7 +257,7 @@ amproperty (Oid index_oid, int attno, - 支持排序操作符的访问方法应当实现 AMPROP_DISTANCE_ORDERABLE 属性测试,因为核心代码不知道如何完成该测试,只会返回 NULL。若实现成本低于打开索引并调用 amcanreturn(这正是核心代码的默认行为),那么实现 AMPROP_RETURNABLE 测试也可能是有利的。对于其他所有标准属性,默认行为应当已经足够。 + 支持排序操作符的访问方法应当实现 AMPROP_DISTANCE_ORDERABLE 属性测试,因为核心代码不知道如何完成该测试,只会返回 NULL。若完成该测试的代价低于打开索引并调用 amcanreturn(这正是核心代码的默认行为),那么实现 AMPROP_RETURNABLE 测试也可能是有利的。对于其他所有标准属性,默认行为应当已经足够。 @@ -360,11 +319,11 @@ bool amgettuple (IndexScanDesc scan, ScanDirection direction); - 在给定扫描中取出下一个元组,并按给定方向移动(在索引中向前或向后)。若成功取得元组则返回真;若不再有匹配元组则返回假。在返回真时,元组的 TID 会存入 scan 结构体中。请注意,成功仅表示索引中存在一个匹配扫描键的条目,并不表示该元组一定仍然存在于堆中,或者一定能通过调用者的快照测试。成功时,amgettuple 还必须把 scan->xs_recheck 设为真或假。假表示可以确定该索引条目匹配扫描键;真表示这一点并不确定,因此在取到堆元组后必须根据扫描键所代表的条件重新检查它。这一机制支持有损索引操作符。请注意,重检只会扩展到扫描条件;部分索引谓词(如果有)永远不会由 amgettuple 的调用者重新检查。 + 在给定扫描中取出下一个元组,并按给定方向移动(在索引中向前或向后)。若成功取得元组则返回真;若不再有匹配元组则返回假。在返回真时,元组的 TID 会存入 scan 结构体中。请注意,成功仅表示索引中存在一个匹配扫描键的条目,并不表示该元组一定仍然存在于堆中,或者一定能通过调用者的快照测试。成功时,amgettuple 还必须把 scan->xs_recheck 设为真或假。假表示可以确定该索引条目匹配扫描键;真表示这一点并不确定,因此在取到堆元组后必须根据扫描键所代表的条件重新检查它。这一机制支持有损索引操作符。请注意,重检只针对扫描条件;部分索引谓词(如果有)永远不会由 amgettuple 的调用者重新检查。 - 如果索引支持 仅索引扫描(即其任一列上 amcanreturn 返回真),那么成功时 AM 还必须检查 scan->xs_want_itup;若其为真,就必须返回该索引条目的原始被索引数据。对于 amcanreturn 返回假的列,可以把其值作为 NULL 返回。数据可以通过以下两种形式之一返回:一种是把 IndexTuple 指针存入 scan->xs_itup,其元组描述符为 scan->xs_itupdesc;另一种是把 HeapTuple 指针存入 scan->xs_hitup,其元组描述符为 scan->xs_hitupdesc。(当重建出的数据可能装不进 IndexTuple 时,应使用后一种格式。)无论采用哪种形式,指针所引用数据的管理责任都在访问方法一侧。对这份数据的有效性必须至少保持到该扫描下一次调用 amgettupleamrescanamendscan 为止。 + 如果索引支持 仅索引扫描(即其至少一列上 amcanreturn 返回真),那么成功时 AM 还必须检查 scan->xs_want_itup;若其为真,就必须返回该索引条目的原始被索引数据。对于 amcanreturn 返回假的列,可以把其值作为 NULL 返回。数据可以通过以下两种形式之一返回:一种是把 IndexTuple 指针存入 scan->xs_itup,其元组描述符为 scan->xs_itupdesc;另一种是把 HeapTuple 指针存入 scan->xs_hitup,其元组描述符为 scan->xs_hitupdesc。(当重建出的数据可能装不进 IndexTuple 时,应使用后一种格式。)无论采用哪种形式,指针所引用数据的管理责任都在访问方法一侧。这份数据必须至少保持有效,直到该扫描下一次调用 amgettupleamrescanamendscan @@ -377,7 +336,7 @@ int64 amgetbitmap (IndexScanDesc scan, TIDBitmap *tbm); - 取出给定扫描中的所有元组,并将其加入调用者提供的 TIDBitmap 中(也就是把这组元组 ID 与位图中已有的集合做 OR)。返回值是取得的元组数量(这可能只是近似计数,例如某些 AM 不会检测重复项)。在把元组 ID 插入位图时,amgetbitmap 可以指出某些具体的元组 ID 需要重新检查扫描条件。这类似于 amgettuplexs_recheck 输出参数。注意:在当前实现中,对这一特性的支持与位图自身的有损存储支持混在一起,因此调用者会对可重检元组同时重新检查扫描条件和部分索引谓词(如果有)。不过,这并不一定永远如此。amgetbitmapamgettuple 不能在同一次索引扫描中同时使用;使用 amgetbitmap 时还有其他限制,详见 。 + 取出给定扫描中的所有元组,并将其加入调用者提供的 TIDBitmap 中(也就是把这组元组 ID 与位图中已有的集合做 OR)。返回值是取得的元组数量(这可能只是近似计数,例如某些 AM 不会检测重复项)。在把元组 ID 插入位图时,amgetbitmap 可以指出某些具体的元组 ID 需要重新检查扫描条件。这类似于 amgettuplexs_recheck 输出参数。注意:在当前实现中,对这一特性的支持与位图自身的有损存储支持混在一起,因此调用者会对需要重检的元组同时重新检查扫描条件和部分索引谓词(如果有)。不过,这并不一定永远如此。amgetbitmapamgettuple 不能在同一次索引扫描中同时使用;使用 amgetbitmap 时还有其他限制,详见 @@ -389,7 +348,7 @@ amgetbitmap (IndexScanDesc scan, void amendscan (IndexScanDesc scan); - 结束一次扫描并释放资源。scan 结构体本身不应被释放,但访问方法内部获取的任何锁或 pin,以及由 ambeginscan 和其他扫描相关函数分配的其他内存,都必须被释放。 + 结束一次扫描并释放资源。scan 结构体本身不应被释放,但必须释放访问方法内部获取的所有锁、解除所有钉住状态,并释放由 ambeginscan 和其他扫描相关函数分配的其他内存。 @@ -423,15 +382,8 @@ amrestrpos (IndexScanDesc scan); Size -amestimateparallelscan (Relation indexRelation, - int nkeys, - int norderbys); - - 估计并返回执行并行扫描时该访问方法所需动态共享内存的字节数。(这个数字是额外需求,并不替代 ParallelIndexScanDescData 中 AM 无关数据所需的空间。) - - - - nkeysnorderbys 参数表示扫描中将使用的限定条件和排序操作符数量;同样的数值也会传给 amrescan。请注意,此时还没有提供扫描键的实际值。 +amestimateparallelscan (void); +估算并返回访问方法执行并行扫描所需的动态共享内存字节数。(此数值是额外需要的空间,不包括以下结构体中与访问方法无关的数据所需的空间:ParallelIndexScanDescData。) @@ -458,17 +410,6 @@ amparallelrescan (IndexScanDesc scan); 如果实现了此函数,当并行索引扫描必须重新开始时就会调用它。它应重置由 aminitparallelscan 建立的任何共享状态,以便扫描从头开始重新执行。 - - -CompareType -amtranslatestrategy (StrategyNumber strategy, Oid opfamily, Oid opcintype); - -StrategyNumber -amtranslatecmptype (CompareType cmptype, Oid opfamily, Oid opcintype); - - 如果实现了这些函数,规划器和执行器就会调用它们,在固定的 CompareType 值与访问方法所使用的特定策略编号之间进行转换。提供了与内置 btree 或 hash 访问方法相似功能的访问方法可以实现这些函数;通过实现这些转换,系统就能理解该访问方法操作的语义,并在多个地方把它们当作 btree 或 hash 索引的替代。如果该访问方法的功能与这些内置访问方法并不相似,就不需要实现这些函数。若不实现,访问方法会在某些规划器和执行器决策中被忽略,但除此之外仍然完全可用。 - - @@ -524,7 +465,7 @@ amtranslatecmptype (CompareType cmptype, Oid opfamily, Oid opcintype); - 除了使用 amgettuple 外,索引扫描也可以使用 amgetbitmap,在一次调用中取出所有元组。与 amgettuple 相比,这通常明显更高效,因为它可以避免访问方法内部的反复加锁和解锁。原则上,amgetbitmap 应具有与重复调用 amgettuple 相同的效果,但为了简化实现,我们施加了若干限制。首先,amgetbitmap 一次性返回全部元组,因此不支持标记或恢复扫描位置。其次,元组是通过一个位图返回的,没有特定顺序,这也是为什么 amgetbitmap 不带 direction 参数的原因。(这种扫描也永远不会提供排序操作符。)此外,使用 amgetbitmap 时也没有仅索引扫描的支持,因为没有办法返回索引元组的内容。最后,amgetbitmap 不保证对返回的元组做任何锁定,其影响见 。 + 除了使用 amgettuple 外,索引扫描也可以使用 amgetbitmap,在一次调用中取出所有元组。与 amgettuple 相比,这可能明显更高效,因为它可以避免访问方法内部的反复加锁和解锁。原则上,amgetbitmap 应具有与重复调用 amgettuple 相同的效果,但为了简化实现,我们施加了若干限制。首先,amgetbitmap 一次性返回全部元组,因此不支持标记或恢复扫描位置。其次,元组是通过一个位图返回的,没有特定顺序,这也是为什么 amgetbitmap 不带 direction 参数的原因。(这种扫描也永远不会提供排序操作符。)此外,使用 amgetbitmap 时也没有仅索引扫描的支持,因为没有办法返回索引元组的内容。最后,amgetbitmap 不保证对返回的元组做任何锁定,其影响见 @@ -541,7 +482,7 @@ amtranslatecmptype (CompareType cmptype, Oid opfamily, Oid opcintype); - 构建一种支持并发更新的索引类型,通常需要对所需行为进行大量而细致的分析。对于 B-树和哈希索引类型,可以阅读 src/backend/access/nbtree/READMEsrc/backend/access/hash/README 中涉及的设计决策。 + 构建一种支持并发更新的索引类型,通常需要对所需行为进行大量而细致的分析。对于 B-树和 hash 索引类型,可以阅读 src/backend/access/nbtree/READMEsrc/backend/access/hash/README 中涉及的设计决策。 @@ -560,12 +501,12 @@ amtranslatecmptype (CompareType cmptype, Oid opfamily, Oid opcintype); - 索引扫描必须在保存 amgettuple 最近一次返回条目的索引页面上维护一个 pin,而 ambulkdelete 不能从被其他后端钉住的页面中删除条目。下面会解释为什么需要这条规则。 + 索引扫描必须在保存 amgettuple 最近一次返回条目的索引页面上保持钉住状态,而 ambulkdelete 不能从被其他后端钉住的页面中删除条目。下面会解释为什么需要这条规则。 - 如果没有第三条规则,索引读取者就有可能在某个索引条目被 VACUUM 删除之前先看到它,然后在对应的堆条目已被 VACUUM 删除之后才到达那里。如果读取者到达时,该项号仍未被重新使用,就不会造成严重问题,因为空项槽位会被 heap_fetch() 忽略。但如果第三个后端已经把这个项槽位重新用作别的东西呢?在使用 MVCC 兼容快照时不会有问题,因为该槽位的新占用者一定太新,无法通过快照测试。然而,对于非 MVCC 兼容的快照(例如 SnapshotAny),就可能错误地接受并返回一行实际上并不匹配扫描键的数据。我们可以要求在所有情况下都对堆行重新检查扫描键,以防范这种情形,但那样代价太高。于是,我们改为把索引页面上的 pin 作为一种代理,表示读取者可能仍处于从索引条目前往匹配堆条目的飞行中。让 ambulkdelete 在这种 pin 上阻塞,能够保证 VACUUM 不会在读取者处理完之前删除对应的堆条目。这种方案运行时开销很小,只有在真正发生冲突的少数情况下才会增加阻塞开销。 + 如果没有第三条规则,索引读取者就有可能在某个索引条目被 VACUUM 删除之前先看到它,然后在对应的堆条目已被 VACUUM 删除之后才到达那里。如果读取者到达时,该项号仍未被重新使用,就不会造成严重问题,因为空项槽位会被 heap_fetch() 忽略。但如果第三个后端已经把这个项槽位重新用作别的东西呢?在使用 MVCC 兼容快照时不会有问题,因为该槽位的新占用者一定太新,无法通过快照测试。然而,对于非 MVCC 兼容的快照(例如 SnapshotAny),就可能错误地接受并返回一行实际上并不匹配扫描键的数据。我们可以要求在所有情况下都对堆行重新检查扫描键,以防范这种情形,但那样代价太高。于是,我们改为把索引页面的钉住状态作为一种代理,表示读取者从索引条目到匹配堆条目的访问过程可能仍在进行中。让 ambulkdelete 因这种钉住状态而阻塞,能够保证 VACUUM 不会在读取者处理完之前删除对应的堆条目。这种方案运行时开销很小,只有在真正发生冲突的少数情况下才会增加阻塞开销。 @@ -573,7 +514,7 @@ amtranslatecmptype (CompareType cmptype, Oid opfamily, Oid opcintype); - 在 amgetbitmap 索引扫描中,访问方法不会在任何返回的元组上保留索引 pin。因此,只有把这种扫描与 MVCC 兼容的快照一起使用才是安全的。 + 在 amgetbitmap 索引扫描中,访问方法不会为任何返回的元组保持索引页面的钉住状态。因此,只有把这种扫描与 MVCC 兼容的快照一起使用才是安全的。 @@ -612,7 +553,7 @@ amtranslatecmptype (CompareType cmptype, Oid opfamily, Oid opcintype); - 此外,在按照上述规则报告唯一性违背之前,访问方法必须立即重新检查正在插入那一行的存活性。如果它已经是提交后死亡的状态,就不应报告违背。(这种情况不会出现在插入由当前事务刚创建的行这一普通场景中,但在 CREATE UNIQUE INDEX CONCURRENTLY 期间却可能发生。) + 此外,就在按照上述规则报告唯一性违背之前,访问方法必须重新检查正在插入那一行的存活性。如果它已经是提交后死亡的状态,就不应报告违背。(这种情况不会出现在插入由当前事务刚创建的行这一普通场景中,但在 CREATE UNIQUE INDEX CONCURRENTLY 期间却可能发生。) @@ -620,7 +561,7 @@ amtranslatecmptype (CompareType cmptype, Oid opfamily, Oid opcintype); - 如果唯一约束是可延迟的,情况会更复杂:我们需要能够为新行插入一个索引条目,但把任何唯一性违背错误延迟到语句结束时甚至更晚才报告。为了避免对索引进行不必要的重复搜索,索引访问方法应在初始插入期间执行一次初步唯一性检查。如果这表明确实不存在冲突的存活元组,那么事情就结束了。否则,我们会安排在真正强制约束时再做一次重检。若在重检时,插入的元组与另外某个具有相同键值的元组都仍然存活,就必须报告错误。(注意,就此用途而言,存活实际上是指索引条目 HOT 链中的任一元组是存活的。)为实现这一点,传给 aminsert 函数的 checkUnique 参数会取以下值之一: + 如果唯一约束是可延迟的,情况会更复杂:我们需要能够为新行插入一个索引条目,但把任何唯一性违背错误延迟到语句结束时甚至更晚才报告。为了避免对索引进行不必要的重复搜索,索引访问方法应在初始插入期间执行一次初步唯一性检查。如果这表明确实不存在冲突的存活元组,那么事情就结束了。否则,我们会安排在真正强制约束时再做一次重检。若在重检时,插入的元组与另外某个具有相同键值的元组都仍然存活,就必须报告错误。(注意,就此用途而言,存活实际上是指索引条目 HOT 链中至少有一个元组是存活的。)为实现这一点,传给 aminsert 函数的 checkUnique 参数会取以下值之一: @@ -657,10 +598,10 @@ amtranslatecmptype (CompareType cmptype, Oid opfamily, Oid opcintype); - 索引开销估计函数 + 索引代价估算函数 - amcostestimate 函数会收到描述某种可能索引扫描方式的信息,其中包括已经确定可用于该索引的 WHERE 子句和 ORDER BY 子句列表。它必须返回访问该索引的开销估计,以及 WHERE 子句的选择率(也就是在索引扫描期间将从父表中检索出的行所占比例)。对于简单情况,开销估计器几乎所有工作都可以通过调用优化器中的标准例程来完成;之所以提供 amcostestimate 函数,是为了让索引访问方法能够提供与索引类型有关的专门知识,以便在可能时改进标准估计。 + amcostestimate 函数会收到描述某种可能索引扫描方式的信息,其中包括已经确定可用于该索引的 WHERE 子句和 ORDER BY 子句列表。它必须返回访问该索引的代价估算,以及 WHERE 子句选择率的估计值(也就是在索引扫描期间将从父表中检索出的行所占比例)。对于简单情况,代价估算器几乎所有工作都可以通过调用优化器中的标准例程来完成;之所以提供 amcostestimate 函数,是为了让索引访问方法能够提供与索引类型有关的专门知识,以便在可能时改进标准估计。 @@ -694,7 +635,7 @@ amcostestimate (PlannerInfo *root, path - 当前正在考虑的索引访问路径。除开销和选择率字段外,其余字段都有效。 + 当前正在考虑的索引访问路径。除代价和选择率字段外,其余字段都有效。 @@ -703,7 +644,7 @@ amcostestimate (PlannerInfo *root, loop_count - 在开销估计中应计入的索引扫描重复次数。当考虑在嵌套循环连接内部使用参数化扫描时,这个参数通常会大于 1。请注意,开销估计仍应只针对一次扫描;更大的 loop_count 只表示可以适当考虑多次扫描之间的一些缓存效应。 + 在代价估算中应计入的索引扫描重复次数。当考虑在嵌套循环连接内部使用参数化扫描时,这个参数通常会大于 1。请注意,代价估算仍应只针对一次扫描;更大的 loop_count 只表示可以适当考虑多次扫描之间的一些缓存效应。 @@ -718,7 +659,7 @@ amcostestimate (PlannerInfo *root, *indexStartupCost - 设为索引启动处理的开销。 + 设为索引启动处理的代价。 @@ -727,7 +668,7 @@ amcostestimate (PlannerInfo *root, *indexTotalCost - 设为索引处理的总开销。 + 设为索引处理的总代价。 @@ -762,19 +703,19 @@ amcostestimate (PlannerInfo *root, - 请注意,开销估计函数必须用 C 编写,而不能用 SQL 或任何可用的过程语言,因为它们必须访问规划器/优化器的内部数据结构。 + 请注意,代价估算函数必须用 C 编写,而不能用 SQL 或任何可用的过程语言,因为它们必须访问规划器/优化器的内部数据结构。 - 索引访问开销应使用 src/backend/optimizer/path/costsize.c 所采用的参数来计算:顺序磁盘块读取的开销为 seq_page_cost,非顺序读取的开销为 random_page_cost,处理一条索引行的开销通常应取为 cpu_index_tuple_cost。此外,在索引处理期间调用的任何比较操作符(特别是对 indexquals 本身的求值)都应计入适当倍数的 cpu_operator_cost。 + 索引访问代价应使用 src/backend/optimizer/path/costsize.c 所采用的参数来计算:顺序磁盘块读取的代价为 seq_page_cost,非顺序读取的代价为 random_page_cost,处理一条索引行的代价通常应取为 cpu_index_tuple_cost。此外,在索引处理期间调用的任何比较操作符(特别是对 indexquals 本身的求值)都应计入适当倍数的 cpu_operator_cost - 访问开销应包括与扫描索引本身有关的全部磁盘和 CPU 开销,但包括取出或处理由索引标识出的父表行的开销。 + 访问代价应包括与扫描索引本身有关的全部磁盘和 CPU 代价,但包括取出或处理由索引标识出的父表行的代价。 - 启动开销是整个扫描总开销中必须在开始取第一行之前先付出的那一部分。对大多数索引来说,这可以视为零;但启动开销较高的索引类型可能希望把它设为非零。 + 启动代价是整个扫描总代价中必须在开始取第一行之前先付出的那一部分。对大多数索引来说,这可以视为零;但启动代价较高的索引类型可能希望把它设为非零。 @@ -782,7 +723,7 @@ amcostestimate (PlannerInfo *root, - indexCorrelation 应设为索引顺序与表顺序之间的相关性(范围从 -1.0 到 1.0)。该值用于调整从父表取行开销的估计。 + indexCorrelation 应设为索引顺序与表顺序之间的相关性(范围从 -1.0 到 1.0)。该值用于调整从父表取行代价的估计。 @@ -794,9 +735,9 @@ amcostestimate (PlannerInfo *root, - 开销估计 + 代价估算 - 一个典型的开销估计器会按如下步骤进行: + 一个典型的代价估算器会按如下步骤进行: @@ -825,14 +766,14 @@ amcostestimate (PlannerInfo *root, - 计算索引访问开销。一个通用估计器可能会这样做: + 计算索引访问代价。一个通用估计器可能会这样做: /* - * Our generic assumption is that the index pages will be read - * sequentially, so they cost seq_page_cost each, not random_page_cost. - * Also, we charge for evaluation of the indexquals at each index row. - * All the costs are assumed to be paid incrementally during the scan. + * 通用假设是索引页面将按顺序读取, + * 因此每页代价为 seq_page_cost,而非 random_page_cost。 + * 此外,还要计入在每个索引行上对 indexquals 求值的代价。 + * 假定所有代价都在扫描过程中逐步付出。 */ cost_qual_eval(&index_qual_cost, path->indexquals, root); *indexStartupCost = index_qual_cost.startup; @@ -852,7 +793,7 @@ cost_qual_eval(&index_qual_cost, path->indexquals, root); - 开销估计器函数的示例可在 src/backend/utils/adt/selfuncs.c 中找到。 + 代价估算器函数的示例可在 src/backend/utils/adt/selfuncs.c 中找到。 diff --git a/zh/14/indices.sgml b/zh/14/indices.sgml index 15fb27f2..4f5190de 100644 --- a/zh/14/indices.sgml +++ b/zh/14/indices.sgml @@ -31,7 +31,7 @@ SELECT content FROM test1 WHERE id = constant; - 大多数非小说类书籍也采用了类似的方法:读者经常查找的术语和概念会被收集到书末按字母顺序排列的索引中。感兴趣的读者可以相对快速地浏览索引并翻到相应页面,而不必通读整本书才能找到自己感兴趣的内容。正如作者需要预判读者可能查找哪些条目一样,数据库程序员也需要预见哪些索引会有用。 + 大多数非虚构类书籍也采用了类似的方法:读者经常查找的术语和概念会被收集到书末按字母顺序排列的索引中。感兴趣的读者可以相对快速地浏览索引并翻到相应页面,而不必通读整本书才能找到自己感兴趣的内容。正如作者需要预判读者可能查找哪些条目一样,数据库程序员也需要预见哪些索引会有用。 @@ -71,7 +71,7 @@ CREATE INDEX test1_id_index ON test1 (id); comparison-value operator indexed-column - 那么如果原始operator有一个可交换操作符,并且该操作符属于该索引的操作符类,就可以把它翻转成可索引的形式。 + 那么如果原始operator有一个交换子操作符,并且该操作符属于该索引的操作符类,就可以把它翻转成可索引的形式。 @@ -88,9 +88,9 @@ CREATE INDEX test1_id_index ON test1 (id); 索引类型 - PostgreSQL提供了多种索引类型:B-树、哈希、GiST、SP-GiST、GIN、BRIN,以及扩展PostgreSQL提供了多种索引类型:B-树、Hash、GiST、SP-GiST、GIN、BRIN,以及扩展bloom。每种索引类型都采用不同的算法,分别最适合不同类型的可索引子句。默认情况下,CREATE - INDEX命令创建的是 B-树索引,它适用于最常见的场景。其他索引类型则通过写出关键字USING并跟上索引类型名称来选择。例如,要创建一个哈希索引: + INDEX命令创建的是 B-树索引,它适用于最常见的场景。其他索引类型则通过写出关键字USING并跟上索引类型名称来选择。例如,要创建一个 Hash 索引: CREATE INDEX name ON table USING HASH (column); @@ -100,12 +100,12 @@ CREATE INDEX name ON table B-树 - index + 索引 B-树 B-树 - index + 索引 @@ -130,19 +130,19 @@ CREATE INDEX name ON table - 哈希 + Hash - index - 哈希 + 索引 + hash - 哈希 - index + hash + 索引 - 哈希索引存储从索引列值派生出的 32 位哈希码。因此,这类索引只能处理简单的等值比较。只要已索引列参与的是使用等号操作符的比较,查询规划器就会考虑使用哈希索引: + Hash 索引存储从索引列值派生出的 32 位哈希码。因此,这类索引只能处理简单的等值比较。只要已索引列参与的是使用等号操作符的比较,查询规划器就会考虑使用 Hash 索引: = @@ -154,12 +154,12 @@ CREATE INDEX name ON table GiST - index + 索引 GiST GiST - index + 索引 @@ -178,7 +178,7 @@ CREATE INDEX name ON table SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10; ]]> - 这会找出距离给定目标点最近的十个地点。是否能做到这一点,同样取决于所使用的具体操作符类。在中,可以按这种方式使用的操作符列在Ordering Operators这一列中。 + 这会找出距离给定目标点最近的十个地点。是否能做到这一点,同样取决于所使用的具体操作符类。在中,可以按这种方式使用的操作符列在排序操作符这一列中。 @@ -186,12 +186,12 @@ SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10; SP-GiST - index + 索引 SP-GiST SP-GiST - index + 索引 @@ -205,7 +205,7 @@ SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10; - 与 GiST 一样,SP-GiST 支持最近邻搜索。对于支持距离排序的 SP-GiST 操作符类,相应操作符列在Ordering Operators列中。 + 与 GiST 一样,SP-GiST 支持最近邻搜索。对于支持距离排序的 SP-GiST 操作符类,相应操作符列在排序操作符列中。 @@ -213,12 +213,12 @@ SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10; GIN - index + 索引 GIN GIN - index + 索引 @@ -240,16 +240,16 @@ SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10; BRIN - index + 索引 BRIN BRIN - index + 索引 - BRIN 索引(块范围索引,Block Range Indexes)存储的是关于表中连续物理块范围内所保存值的摘要信息。因此,它最适用于那些列值与表行物理顺序高度相关的列。与 GiST、SP-GiST 和 GIN 一样,BRIN 也可以支持多种不同的索引策略,而 BRIN 索引可使用哪些具体操作符取决于所采用的索引策略。对于具有线性排序顺序的数据类型,每个块范围上被索引的数据对应于该列值的最小值和最大值。这支持使用下列操作符的索引化查询: + BRIN 索引(Block Range INdexes 的缩写)存储的是关于表中连续物理块范围内所保存值的摘要信息。因此,它最适用于那些列值与表行物理顺序高度相关的列。与 GiST、SP-GiST 和 GIN 一样,BRIN 也可以支持多种不同的索引策略,而 BRIN 索引可使用哪些具体操作符取决于所采用的索引策略。对于具有线性排序顺序的数据类型,每个块范围上被索引的数据对应于该列值的最小值和最大值。这支持使用下列操作符的索引化查询: <   <=   =   >=   > @@ -265,8 +265,8 @@ SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10; 多列索引 - index - multicolumn + 索引 + 多列 @@ -292,28 +292,18 @@ CREATE INDEX test2_mm_idx ON test2 (major, minor); 当前,只有 B-树、GiST、GIN 和 BRIN 索引类型支持多键列索引。能否有多个键列,与索引中能否添加INCLUDE列无关。索引最多可以有 32 列,包括INCLUDE列。(这个限制在构建PostgreSQL时可以修改;参见文件pg_config_manual.h。) - - 多列 B-树索引可以用于涉及索引任意列子集的查询条件,但当对前导(最左)列存在约束时,索引效率最高。精确的规则是:对前导列的等值约束,再加上第一个没有等值约束列上的任意不等约束,总会被用来限制被扫描的索引范围。这些列右侧列上的约束会在索引中进行检查,因此总能减少访问表本体的次数,但不一定会减少必须扫描的索引范围。如果 B-树索引扫描能够有效应用跳过扫描优化,那么它在通过反复的索引搜索遍历索引时,会利用每一列约束。这可能减少需要读取的索引部分,即便一个或多个列(位于查询谓词中最低有效索引列之前)缺少常规的等值约束。跳过扫描的工作方式是内部生成一个动态的等值约束,使其匹配索引列中的每个可能值(不过这只适用于某个列缺少来自查询谓词的等值约束,且生成的约束能够与查询谓词中较后列的约束联合使用时)。 - - - - 例如,给定一个(x, y)上的索引和查询条件WHERE y = 7700,B-树索引扫描可能能够应用跳过扫描优化。这通常发生在查询规划器预计:针对每个可能的N反复执行WHERE x = N AND y = 7700搜索(或者针对索引中实际存储的每个x值),在当前表上可用索引的前提下,这是最快的方法。一般来说,只有当不同的x值很少,以致规划器预计扫描能跳过索引的大部分内容时,才会采用这种方法(因为大多数叶子页都不可能包含相关元组)。如果不同的x值很多,那么就必须扫描整个索引,因此在大多数情况下,规划器会更倾向于顺序扫描表而不是使用该索引。 - - - - 在至少具有一部分来自查询谓词的有用约束的 B-树扫描中,跳过扫描优化也可以被选择性地应用。例如,给定一个(a, b, c)上的索引和查询条件WHERE a = 5 AND b >= 42 AND c < 77,该索引可能必须从第一个a = 5 且b = 42 的条目扫描,一直到最后一个a = 5 的条目。c >= 77 的索引项永远不需要在表层面进行过滤,但是否值得在索引内部跳过它们,则未必。发生跳过时,扫描会启动一次新的索引搜索,把自身从当前a = 5 且b = N 分组的末尾重新定位(也就是索引中第一个a = 5 AND b = N AND c >= 77元组出现的位置),移动到下一个这类分组的起始位置(也就是索引中第一个a = 5 AND b = N + 1元组出现的位置)。 - + 多列 B-树索引可以用于涉及索引任意列子集的查询条件,但当对前导(最左)列存在约束时,索引效率最高。精确的规则是:对前导列的等值约束,再加上第一个没有等值约束的列上的任何不等约束,会被用来限制索引扫描的范围。这些列右侧列上的约束会在索引中进行检查,因此可以减少访问表本体的次数,但不会缩小必须扫描的索引范围。例如,给定一个 (a, b, c) 上的索引和查询条件 WHERE a = 5 AND b >= 42 AND c < 77,索引必须从第一个 a = 5 且 b = 42 的条目扫描到最后一个 a = 5 的条目。c >= 77 的索引项会被排除,但仍然必须扫描这些项。原则上,这个索引也可以用于只对 b 和/或 c 有约束、而对 a 没有约束的查询,但必须扫描整个索引,因此在大多数情况下,规划器会倾向于顺序扫描表,而不是使用该索引。 多列 GiST 索引可以用于涉及索引任意列子集的查询条件。附加列上的条件会限制索引返回的项,但决定索引需要扫描多少内容的,最重要的仍是第一列上的条件。如果第一列只有很少几个非重复值,即使其他列有很多非重复值,GiST 索引也会相对低效。 - 多列 GIN 索引可以用于涉及索引任意列子集的查询条件。与 B-树或 GiST 不同,无论查询条件使用的是哪一列索引列,GIN 的索引搜索效果都一样。 + 多列 GIN 索引可以用于涉及索引任意列子集的查询条件。与 B-树或 GiST 不同,无论查询条件使用的是哪些索引列,GIN 的索引搜索效果都一样。 - 多列 BRIN 索引可以用于涉及索引任意列子集的查询条件。和 GIN 一样、不同于 B-树或 GiST,无论查询条件使用的是哪一列索引列,索引搜索效果都一样。在单个表上使用多个 BRIN 索引,而不是使用一个多列 BRIN 索引的唯一理由,是需要不同的pages_per_range存储参数。 + 多列 BRIN 索引可以用于涉及索引任意列子集的查询条件。和 GIN 一样、不同于 B-树或 GiST,无论查询条件使用的是哪些索引列,索引搜索效果都一样。在单个表上使用多个 BRIN 索引,而不是使用一个多列 BRIN 索引的唯一理由,是需要不同的pages_per_range存储参数。 @@ -330,8 +320,8 @@ CREATE INDEX test2_mm_idx ON test2 (major, minor); 索引和<literal>ORDER BY</literal> - index - and ORDER BY + 索引 + ORDER BY @@ -339,7 +329,7 @@ CREATE INDEX test2_mm_idx ON test2 (major, minor); - 规划器在满足ORDER BY要求时,会考虑两种方案:扫描一个与该要求匹配的可用索引,或者按物理顺序扫描表再显式排序。对于需要扫描表中很大一部分内容的查询,显式排序通常会比使用索引更快,因为它遵循顺序访问模式,需要的磁盘 I/O 更少。只有在只需取出少量行时,索引才更有价值。一个重要的特例是ORDER BYLIMIT n组合使用:显式排序必须处理所有数据才能找出最前面的n行,而如果有一个与ORDER BY匹配的索引,就可以直接取回前n行,而完全不必扫描剩余数据。 + 规划器在满足ORDER BY要求时,会考虑两种方案:扫描一个与该要求匹配的可用索引,或者按物理顺序扫描表再显式排序。对于需要扫描表中很大一部分内容的查询,显式排序通常会比使用索引更快,因为它遵循顺序访问模式,需要的磁盘 I/O 更少。只需取出少量行时,索引更有价值。一个重要的特例是ORDER BYLIMIT n组合使用:显式排序必须处理所有数据才能找出最前面的n行,而如果有一个与ORDER BY匹配的索引,就可以直接取回前n行,而完全不必扫描剩余数据。 @@ -369,12 +359,12 @@ CREATE INDEX test3_desc_index ON test3 (id DESC NULLS LAST); 组合多个索引 - index - combining multiple indexes + 索引 + 组合多个索引 - bitmap scan + 位图扫描 @@ -391,7 +381,7 @@ CREATE INDEX test3_desc_index ON test3 (id DESC NULLS LAST); - 除了最简单的应用之外,通常会有多种可能有用的索引组合,数据库开发者必须权衡决定提供哪些索引。有时多列索引最好,但有时创建独立索引并依赖索引组合功能会更合适。例如,如果你的工作负载包含一组查询:有时只涉及列x,有时只涉及列y,有时同时涉及两列,那么你可以选择分别在xy上创建两个独立索引,并依赖索引组合来处理同时使用两列的查询。你也可以创建一个(x, y)上的多列索引。对于同时涉及两列的查询,这个索引通常会比索引组合更高效,但正如中所讨论的,它对于只涉及y的查询就没那么有用了。具体能有多大用处,取决于 B-树索引跳过扫描优化的效果;如果x的非重复值不超过几百个,跳过扫描会让针对特定y值的搜索仍然具有相当不错的效率。再加上一个(x, y)上的多列索引和一个单独的y索引,也可能工作得相当好。对于只涉及x的查询,多列索引也可以使用,但它会比单独的x索引更大,因此更慢。最后一种选择是同时创建这三个索引,但这大概只有在该表被搜索的频率远高于被更新的频率,并且三类查询都很常见时才合理。如果其中一种查询远没有另外两种常见,那么你大概只需创建最适合常见查询类型的两个索引即可。 + 除了最简单的应用之外,通常会有多种可能有用的索引组合,数据库开发者必须权衡决定提供哪些索引。有时多列索引最好,但有时创建独立索引并依赖索引组合功能会更合适。例如,如果你的工作负载包含一组查询:有时只涉及列x,有时只涉及列y,有时同时涉及两列,那么你可以选择分别在xy上创建两个独立索引,并依赖索引组合来处理同时使用两列的查询。你也可以创建一个(x, y)上的多列索引。对于同时涉及两列的查询,这个索引通常会比索引组合更高效,但正如中所讨论的,它对于只涉及y的查询几乎没有用处,因此不应只创建这一个索引。将这个多列索引与一个单独的y索引组合起来,能够取得相当好的效果。对于只涉及x的查询,多列索引也可以使用,但它会比单独的x索引更大,因此更慢。最后一种选择是同时创建这三个索引,但这大概只有在该表被搜索的频率远高于被更新的频率,并且三类查询都很常见时才合理。如果其中一种查询远没有另外两种常见,那么你大概只需创建最适合常见查询类型的两个索引即可。 @@ -401,8 +391,8 @@ CREATE INDEX test3_desc_index ON test3 (id DESC NULLS LAST); 唯一索引 - index - unique + 索引 + 唯一 @@ -433,8 +423,8 @@ CREATE UNIQUE INDEX name ON table表达式索引 - index - on expressions + 索引 + 基于表达式 @@ -481,8 +471,8 @@ CREATE INDEX people_names ON people ((first_name || ' ' || last_name)); 部分索引 - index - partial + 索引 + 部分 @@ -490,7 +480,7 @@ CREATE INDEX people_names ON people ((first_name || ' ' || last_name)); - 使用部分索引的一个主要原因是避免索引常见值。由于搜索常见值的查询(即占全部表行百分之几以上的值)反正也不会使用索引,因此完全没有必要把这些行保留在索引里。这会减小索引尺寸,从而加快那些确实会使用该索引的查询。它也会加快很多表更新操作,因为索引并不需要在所有情况下都更新。展示了这种思路的一种可能应用。 + 使用部分索引的一个主要原因是避免索引常见值。由于搜索常见值(即占全部表行百分之几以上的值)的查询反正也不会使用索引,因此完全没有必要把这些行保留在索引里。这会减小索引尺寸,从而加快那些确实会使用该索引的查询。它也会加快很多表更新操作,因为索引并不需要在所有情况下都更新。展示了这种思路的一种可能应用。 @@ -578,7 +568,7 @@ SELECT * FROM orders WHERE order_nr = 3501; - 也说明了:索引列和谓词中使用的列不必一致。PostgreSQL支持带任意谓词的部分索引,只要其中只涉及正在建立索引的那张表的列。不过要记住,谓词必须与那些希望从该索引受益的查询中使用的条件相匹配。更准确地说,只有当系统能够识别出查询的WHERE条件在数学上蕴含该索引的谓词时,部分索引才能用于该查询。PostgreSQL并没有一个复杂的定理证明器,来识别那些写法不同但数学上等价的表达式。(不仅构建这样一个通用定理证明器极其困难,而且它很可能也会慢到失去实际用途。)系统可以识别简单的不等式蕴含,例如x < 1蕴含x < 2;否则,谓词条件必须与查询WHERE条件的某一部分完全匹配,否则索引不会被识别为可用。匹配发生在查询规划阶段,而不是运行时。因此,参数化查询子句无法与部分索引配合工作。例如,一个带参数的预备查询可能写成x < ?,而对于参数的所有可能取值,它都不可能蕴含x < 2。 + 也说明了:索引列和谓词中使用的列不必一致。PostgreSQL支持带任意谓词的部分索引,只要其中只涉及正在建立索引的那张表的列。不过要记住,谓词必须与那些希望从该索引受益的查询中使用的条件相匹配。更准确地说,只有当系统能够识别出查询的WHERE条件在数学上蕴含该索引的谓词时,部分索引才能用于该查询。PostgreSQL并没有一个复杂的定理证明器,来识别那些写法不同但数学上等价的表达式。(不仅构建这样一个通用定理证明器极其困难,而且它很可能也会慢到失去实际用途。)系统可以识别简单的不等式蕴含,例如x < 1蕴含x < 2;否则,谓词条件必须与查询WHERE条件的某一部分完全匹配,否则索引不会被识别为可用。匹配发生在查询规划阶段,而不是运行时。因此,参数化查询子句无法与部分索引配合工作。例如,一个带参数的预备查询可能写成x < ?,而它无法保证在参数的所有可能取值下都蕴含x < 2 @@ -590,7 +580,7 @@ SELECT * FROM orders WHERE order_nr = 3501; 建立一个部分唯一索引 - 假设我们有一张描述测试结果的表。我们希望确保对于给定的subjecttarget组合,只有一条成功记录,但可以有任意多条失败记录。实现方法之一如下: + 假设我们有一张描述测试结果的表。我们希望确保对于给定的测试对象和目标组合,只有一条成功记录,但可以有任意多条失败记录。实现方法之一如下: CREATE TABLE tests ( subject text, @@ -686,7 +676,7 @@ CREATE INDEX mytable_cat_data ON mytable (category, data); - 查询只能引用存储在索引中的列。例如,给定一个表,它有列xyz,而索引建立在xy上,那么下面这些查询可以使用仅索引扫描: + 查询只能引用存储在索引中的列。例如,假设某个表的xy列上有一个索引,且该表还有一列z,那么下面这些查询可以使用仅索引扫描: SELECT x, y FROM tab WHERE x = 'key'; SELECT x FROM tab WHERE x = 'key' AND y < 42; @@ -713,7 +703,7 @@ SELECT x FROM tab WHERE x = 'key' AND z < 42; INCLUDE - in index definitions + 在索引定义中 为了有效利用仅索引扫描特性,你可以选择创建一个覆盖索引,也就是专门设计来包含某一类高频查询所需列的索引。由于查询通常需要取回的列不止是用于搜索的那些列,PostgreSQL允许你创建一种索引,其中某些列只是负载,而不是搜索键的一部分。这是通过添加一个INCLUDE子句列出这些额外列来实现的。例如,如果你经常运行如下查询: @@ -781,11 +771,11 @@ SELECT target FROM tests WHERE subject = 'some-subject' AND success; 操作符类和操作符族 - operator class + 操作符类 - operator family + 操作符族 @@ -903,8 +893,8 @@ CREATE INDEX test1c_content_y_index ON test1c (content COLLATE "y"); 检查索引使用情况 - index - examining usage + 索引 + 检查使用情况 diff --git a/zh/14/information_schema.sgml b/zh/14/information_schema.sgml index 2bc12c99..396b127f 100644 --- a/zh/14/information_schema.sgml +++ b/zh/14/information_schema.sgml @@ -388,7 +388,7 @@ collation_catalog sql_identifier - 包含此属性排序规则的数据库名(总是当前数据库),如果默认或者该属性的数据类型不可排序则为空 + 包含该属性排序规则的数据库名称(总是当前数据库);如果使用默认排序规则,或该属性的数据类型不支持排序规则,则为 null。 @@ -397,7 +397,7 @@ collation_schema sql_identifier - 包含此属性排序规则的模式名,如果默认或者该属性的数据类型不可排序则为空 + 包含该属性排序规则的模式名称;如果使用默认排序规则,或该属性的数据类型不支持排序规则,则为 null。 @@ -406,7 +406,7 @@ collation_name sql_identifier - 该属性排序规则的名称,如果默认或者该属性的数据类型不可排序则为空 + 该属性排序规则的名称;如果使用默认排序规则,或该属性的数据类型不支持排序规则,则为 null。 @@ -1626,7 +1626,7 @@ collation_catalog sql_identifier - 包含此属性排序规则的数据库名(总是当前数据库),如果默认或者该属性的数据类型不可排序则为空 + 包含该列排序规则的数据库名称(总是当前数据库);如果使用默认排序规则,或该列的数据类型不支持排序规则,则为 null。 @@ -1635,7 +1635,7 @@ collation_schema sql_identifier - 该列的包含排序规则的模式名,如果默认或者该列的数据类型不可排序则为空 + 包含该列排序规则的模式名称;如果使用默认排序规则,或该列的数据类型不支持排序规则,则为 null。 @@ -1644,7 +1644,7 @@ collation_name sql_identifier - 该列的排序规则的名称,如果默认或者该列的数据类型不可排序则为空 + 该列排序规则的名称;如果使用默认排序规则,或该列的数据类型不支持排序规则,则为 null。 @@ -2385,7 +2385,7 @@ collation_catalog sql_identifier - 包含此域排序规则的数据库名(总是当前数据库),如果默认或者该域的数据类型不可排序则为空 + 包含该域排序规则的数据库名称(总是当前数据库);如果使用默认排序规则,或该域的数据类型不支持排序规则,则为 null。 @@ -2394,7 +2394,7 @@ collation_schema sql_identifier - 包含此域排序规则的模式名,如果默认或者该域的数据类型不可排序则为空 + 包含该域排序规则的模式名称;如果使用默认排序规则,或该域的数据类型不支持排序规则,则为 null。 @@ -2403,7 +2403,7 @@ collation_name sql_identifier - 该域排序规则的名称,如果默认或者该域的数据类型不可排序则为空 + 该域排序规则的名称;如果使用默认排序规则,或该域的数据类型不支持排序规则,则为 null。 @@ -2558,7 +2558,7 @@ <literal>element_types</literal> - 视图element_types包含数组元素的数据类型描述符。当一个表列、复合类型属性、域、函数参数或函数返回值被定义为一种数组类型,相应的信息模式视图只在列data_type中包含ARRAY。要获得该数组元素类型的信息,你可以连接该相应的视图和这个视图。例如,要显示一个表的列及其数据类型和数组元素类型,你可以: + 视图element_types包含数组元素的数据类型描述符。当一个表列、复合类型属性、域、函数参数或函数返回值被定义为一种数组类型时,相应的信息模式视图只在列data_type中包含ARRAY。要获得该数组元素类型的信息,你可以连接该相应的视图和这个视图。例如,要显示一个表的列及其数据类型和数组元素类型(如果适用),你可以: SELECT c.column_name, c.data_type, e.data_type AS element_type FROM information_schema.columns c LEFT JOIN information_schema.element_types e @@ -2689,7 +2689,7 @@ ORDER BY c.ordinal_position; collation_catalog sql_identifier - 包含元素类型排序规则的数据库名称(总是当前数据库), 如果默认或该元素的数据类型是不可排序的则为空 + 包含该元素类型排序规则的数据库名称(总是当前数据库);如果使用默认排序规则,或该元素类型不支持排序规则,则为 null。 @@ -2698,7 +2698,7 @@ ORDER BY c.ordinal_position; collation_schema sql_identifier - 包含元素类型排序规则的模式名称, 如果默认或该元素的数据类型是不可排序的则为空 + 包含该元素类型排序规则的模式名称;如果使用默认排序规则,或该元素类型不支持排序规则,则为 null。 @@ -2707,7 +2707,7 @@ ORDER BY c.ordinal_position; collation_name sql_identifier - 元素类型的排序规则名, 如果默认或该元素的数据类型是不可排序的则为空 + 该元素类型排序规则的名称;如果使用默认排序规则,或该元素类型不支持排序规则,则为 null。 @@ -2765,6 +2765,15 @@ ORDER BY c.ordinal_position; + + + domain_default character_data + + + 尚未实现 + + + udt_catalog sql_identifier @@ -6291,7 +6300,7 @@ ORDER BY c.ordinal_position; enforced yes_or_no - 如果该约束被强制执行,则为YES,否则为NO + 适用于PostgreSQL尚不提供的功能(当前总是YES @@ -7136,7 +7145,7 @@ ORDER BY c.ordinal_position; - SQL 了解两种用户定义类型:结构类型(在PostgreSQL中也称为复合类型)以及 distinct 类型(PostgreSQL 尚未实现)。为兼顾将来,请使用列user_defined_type_category来区分它们。其他用户定义类型,如基类型和枚举(两者都是PostgreSQL的扩展),不会在这里显示。域的相关信息见。 + SQL 中有两种用户定义类型:结构类型(在PostgreSQL中也称为复合类型)以及独立类型(distinct type,PostgreSQL 尚未实现)。为兼顾将来,请使用列user_defined_type_category来区分它们。其他用户定义类型,如基础类型和枚举(两者都是PostgreSQL的扩展),不会在这里显示。域的相关信息见 diff --git a/zh/14/install-windows.sgml b/zh/14/install-windows.sgml index 3c93563a..76932145 100644 --- a/zh/14/install-windows.sgml +++ b/zh/14/install-windows.sgml @@ -4,8 +4,8 @@ 在 <productname>Windows</productname> 上从源代码安装 - installation - on Windows + 安装 + 在 Windows 上 @@ -116,8 +116,7 @@ $ENV{MSBFLAGS}="/m"; - Bison and - Flex + BisonFlex 从 Git 构建需要BisonFlex,但从发布文件构建则不需要。只有 Bison 1.875 或 2.2 及以上版本可以工作。Flex必须为 2.5.31 或更高版本。 @@ -162,8 +161,7 @@ $ENV{MSBFLAGS}="/m"; - libxml2 and - libxslt + libxml2libxslt XML 支持需要它们。二进制文件可从下载,源代码可从获取。请注意,libxml2 需要 iconv,而它可从相同的下载位置获得。 @@ -282,9 +280,7 @@ $ENV{CONFIG}="Debug"; 运行回归测试 - - 要运行回归测试,请首先确保已完成所有必需部分的构建。同时,要确保加载系统所有部分所需的 DLL(例如过程语言所需的 Perl 和 Python DLL)已经出现在系统路径中。如果没有,请通过buildenv.pl文件进行设置。要运行测试,请从src\tools\msvc目录运行以下命令之一: - + 要运行回归测试,请先确保已完成所有必需部分的构建。此外,还要确保加载系统各部分所需的 DLL(例如过程语言所用的 Perl 和 Python DLL)都能在系统路径中找到。如果不能,请通过 buildenv.pl 文件设置路径。要运行测试,请在 src\tools\msvc 目录中执行以下命令之一: vcregress check vcregress installcheck vcregress plcheck @@ -296,19 +292,13 @@ $ENV{CONFIG}="Debug"; vcregress recoverycheck vcregress taptest vcregress upgradecheck - - - 若要更改所使用的调度(默认为 parallel),可像下面这样将其追加到命令行: - +要更改所用的测试调度方式(默认为 parallel),请将其追加到命令行,例如: vcregress check serial - vcregress taptest可用于运行某个目标目录的 TAP 测试,例如: - + vcregress taptest 可用于运行目标目录中的 TAP 测试,例如: vcregress taptest src\bin\initdb\ - - - 有关回归测试的更多信息,请参见。 +有关回归测试的更多信息,参见 @@ -316,9 +306,7 @@ $ENV{CONFIG}="Debug"; IPC::Run - - 截至本文写作时,IPC::Run既未包含在 ActiveState Perl 安装中,也未包含在 ActiveState Perl Package Manager(PPM)库中。要安装它,请从 CPAN 下载IPC-Run-<version>.tar.gz源代码归档文件,即,并解压。编辑buildenv.pl文件,并增加一个 PERL5LIB 变量,使其指向解压后目录中的lib子目录。例如: - + 撰写本文时,IPC::Run 既未包含在 ActiveState Perl 安装中,也未包含在 ActiveState Perl 软件包管理器(PPM)的库中。要安装它,请下载以下文件:IPC-Run-<version>.tar.gz,这是 CPAN 提供的源码归档,地址为 ,然后将其解压。编辑 buildenv.pl 文件,并添加 PERL5LIB 变量,使其指向解压后归档中的 lib 子目录。例如: $ENV{PERL5LIB}=$ENV{PERL5LIB} . ';c:\IPC-Run-0.94\lib'; @@ -341,7 +329,7 @@ $ENV{PROVE_TESTS}='t/020*.pl t/010*.pl' - 某些 TAP 测试依赖一组外部命令,这些命令会选择性触发与其相关的测试。每个这样的变量都可以在buildenv.pl中设置或取消设置: + 部分 TAP 测试依赖一些外部命令,相关测试会根据这些命令是否可用而选择性触发。以下各变量都可以在 buildenv.pl 中设置或取消设置: GZIP_PROGRAM diff --git a/zh/14/installation.sgml b/zh/14/installation.sgml index a31eb1e7..61043bb8 100644 --- a/zh/14/installation.sgml +++ b/zh/14/installation.sgml @@ -1,12 +1,21 @@ + 从源代码安装 - installation + 安装 + 本章介绍如何使用源代码发布包安装 PostgreSQL。如果你安装的是预打包的发行版, @@ -14,6 +23,31 @@ + 如果你要为 Microsoft Windows 构建 PostgreSQL,并打算使用 MinGW 或 Cygwin,请阅读本章;但如果打算使用 Microsoft 的 Visual C++,请改为参见 + + + 简要说明 + + + + +./configure +make +su +make install +adduser postgres +mkdir /usr/local/pgsql/data +chown postgres /usr/local/pgsql/data +su - postgres +/usr/local/pgsql/bin/initdb -D /usr/local/pgsql/data +/usr/local/pgsql/bin/pg_ctl -D /usr/local/pgsql/data -l logfile start +/usr/local/pgsql/bin/createdb test +/usr/local/pgsql/bin/psql test +详细说明见本的其余部分。 + + + + 需求 @@ -46,26 +80,6 @@ - - - - Meson - - - 另一种方式是使用 Meson - 构建 PostgreSQL。这是在 Windows 上通过 - Visual Studio 构建 - PostgreSQL 的唯一方法。对于其他平台, - 使用 Meson 目前仍属于实验性功能。如果你选择使用 - Meson,则不需要 GNU - make,但下面列出的其他要求仍然适用。 - - - - Meson 的最低要求版本是 0.54。 - - - 你需要一个 ISO/ANSI C 编译器 @@ -83,40 +97,6 @@ - - - - flex - - - lex - - - bison - - - yacc - - - 需要 FlexBison。 - 不能使用其他 lex 和 - yacc 程序。 - Bison 至少需要 2.3 版本。 - - - - - - - perl - - - 在构建过程中以及运行某些测试套件时,需要 Perl - 5.14 或更高版本。(这一要求与构建 PL/Perl - 的要求是分开的;见下文。) - - - @@ -157,34 +137,6 @@ 对压缩归档的支持。 - - - - 默认使用 ICU 库。如果你不想使用它,则必须给 - configure 指定 - 选项。使用这个选项将禁用 ICU 排序规则特性的支持(见 - )。 - - - ICU 支持要求安装 ICU4C 软件包。 - 当前 ICU4C 的最低要求版本是 4.2。 - - - - 默认情况下,将使用 - pkg-configpkg-config - 查找所需的编译选项。这适用于 ICU4C 4.6 及更高版本。 - 对于较旧版本,或者如果 pkg-config 不可用, - 可以把 ICU_CFLAGSICU_LIBS - 变量传给 configure,例如: - -./configure ... ICU_CFLAGS='-I/some/where/include' ICU_LIBS='-L/some/where/lib -licui18n -licuuc -licudata' - - (如果 ICU4C 位于编译器的默认搜索路径中, - 你仍然需要指定非空字符串,以避免使用 pkg-config, - 例如 ICU_CFLAGS=' '。) - - @@ -198,7 +150,7 @@ 要构建服务器端编程语言 PL/Perl, 你需要一个完整的 Perl 安装, 包括 libperl 库和头文件。 - 最低要求版本是 Perl 5.14。 + 最低要求版本是 Perl 5.8.3。 由于 PL/Perl 是一个共享库,在大多数平台上, libperl libperl 也必须是共享库。这在较新的 @@ -221,12 +173,7 @@ - - 要构建 PL/Python 服务器端编程语言, - 你需要带有头文件以及 sysconfig 模块的 - Python 安装。最低支持版本是 - Python 3.6.8。 - + 要构建 PL/Python 服务器端编程语言,你需要带有头文件以及 sysconfig 模块的 Python 安装。最低要求版本是 Python 2.7。支持 3.2 及更高版本的 Python 3;但使用 Python 3 时请参见 由于 PL/Python 是一个共享库,在大多数平台上, @@ -269,55 +216,45 @@ - - 如果你希望支持加密的客户端连接,就需要 OpenSSL。 - 在没有 /dev/urandom 的平台上(Windows 除外), - 生成随机数也需要 OpenSSL。 - 最低要求版本是 1.1.1。 - - - 此外,也支持通过 OpenSSL 兼容层使用 - LibreSSL。最低要求版本是 3.4 - (来自 OpenBSD 7.0)。 - + 如果你希望支持加密的客户端连接,就需要 OpenSSL。在没有 /dev/urandom 的平台上(Windows 除外),生成随机数也需要 OpenSSL。最低要求版本是 1.0.1。 - - 如果你希望支持使用这些服务进行认证,则需要 - MIT Kerberos(用于 GSSAPI)、 - OpenLDAP 和/或 PAM。 - + 如果你希望支持使用相应服务进行认证,就需要 KerberosOpenLDAP 和/或 PAM - 你需要 Curl 来构建一个可选模块, - 该模块为客户端应用实现了 - OAuth 设备授权流程。 + 如果你希望支持用这种方法压缩数据,就需要 LZ4; + 见 - 如果你希望支持用该方法压缩数据,就需要 LZ4; - 见 。 + 要构建 PostgreSQL 文档,还需要满足另一组要求; + 见 + + + 如果你从 Git 树构建,而不是使用已发布的源码包,或者你要进行服务器开发,还需要以下软件包: - - 如果你希望支持用该方法压缩数据,就需要 Zstandard; - 见 。 - 最低要求版本是 1.4.0。 - + + flex + + lex + + bison + + yacc + 从 Git 检出构建,或者修改了扫描器和解析器的实际定义文件时,需要 FlexBison。如果需要它们,请确保使用 Flex 2.5.31 或更高版本,以及 Bison 1.875 或更高版本。不能使用其他 lexyacc 程序。 - - - 要构建 PostgreSQL 文档,还需要满足另一组要求; - 见 。 - + + perl + 从 Git 检出构建,或者修改了使用 Perl 脚本的任何构建步骤的输入文件时,需要 Perl 5.8.3 或更高版本。在 Windows 上构建时,无论如何都需要 Perl。运行某些测试套件也需要 Perl @@ -328,63 +265,24 @@ ),或者直接从 获取。 + + 还要检查磁盘空间是否充足。编译期间,源码树需要约 350 MB,安装目录需要约 60 MB。空数据库集簇约占 40 MB;数据库所需空间大约是存储相同数据的纯文本文件的五倍。如果要运行回归测试,还会临时额外需要最多 300 MB。使用 df 命令检查可用磁盘空间。 获取源代码 - - 已发布版本的 PostgreSQL 源代码可以从 - 我们网站的下载区获取: - 。 - 下载你感兴趣的 - postgresql-version.tar.gz - 或 - postgresql-version.tar.bz2 - 文件,然后解开: - -tar xf postgresql-version.tar.bz2 - - 这会在当前目录下创建一个名为 - postgresql-version - 的目录,其中包含 PostgreSQL 源码。 - 在后续安装过程中,请切换到该目录。 - + 要获取 PostgreSQL &version; 的源码,请访问网站的下载区:。你应该取得一个名为 postgresql-&version;.tar.gzpostgresql-&version;.tar.bz2 的文件。取得文件后,将其解包: +gunzip postgresql-&version;.tar.gz +tar xf postgresql-&version;.tar +(可使用 bunzip2 代替 gunzip 来解压 .bz2 文件。另外,注意大多数现代版本的 tar 可以直接解包压缩归档,因此实际上不需要单独执行 gunzipbunzip2 步骤。)这会在当前目录下创建目录 postgresql-&version;,其中包含 PostgreSQL 源码。切换到该目录,继续完成其余安装过程。 - - 另一种方式是使用 Git 版本控制系统;更多信息见 - 。 - + 你也可以直接从版本控制仓库获取源码,参见 - - 使用 Autoconf 和 Make 进行构建和安装 - - - 简短版本 - - - -./configure -make -su -make install -adduser postgres -mkdir /usr/local/pgsql/data -chown postgres /usr/local/pgsql/data -su - postgres -/usr/local/pgsql/bin/initdb -D /usr/local/pgsql/data -/usr/local/pgsql/bin/pg_ctl -D /usr/local/pgsql/data -l logfile start -/usr/local/pgsql/bin/createdb test -/usr/local/pgsql/bin/psql test - - 较长版本见本其余部分。 - - - - - + 安装过程 + @@ -600,13 +498,12 @@ build-postgresql: make distclean 是一个好主意。否则,你对配置选项所做的更改 可能不会传播到所有需要它们的地方。 - <filename>configure</filename> 选项 - 配置选项 + configure 选项 @@ -853,22 +750,24 @@ build-postgresql: + + + + 构建时支持 ICUICU 库,以使用 ICU 排序规则功能(见 。这要求已安装 ICU4C 软件包。当前 ICU4C 的最低要求版本是 4.2。 + + 默认情况下,pkg-configpkg-config 用于查找所需的编译选项。此方式支持 ICU4C 4.6 及更高版本。对于更早的版本,或者当 pkg-config 不可用时,可以将变量 ICU_CFLAGSICU_LIBS 指定给 configure,如下例所示: +./configure ... --with-icu ICU_CFLAGS='-I/some/where/include' ICU_LIBS='-L/some/where/lib -licui18n -licuuc -licudata' +(如果 ICU4C 位于编译器的默认搜索路径中,仍需要指定非空字符串,以避免使用 pkg-config,例如 ICU_CFLAGS=' '。) + + + + + 构建时支持基于 LLVMJIT 编译(见 。这要求已安装 LLVM 库。当前 LLVM 的最低要求版本是 3.9。 - 构建时支持基于 LLVM 的 - JIT 编译(见 )。 - 这要求已安装 LLVM 库。 - 当前 LLVM 的最低要求版本是 14。 - - - llvm-configllvm-config - 将用于查找所需的编译选项。系统会在你的 PATH 中搜索 - llvm-config。如果这样找不到你想要的程序,请使用 - LLVM_CONFIG 指定正确的 llvm-config - 路径。例如: - + llvm-configllvm-config 用于查找所需的编译选项。首先查找 llvm-config,然后查找 llvm-config-$major-$minor(遍历所有受支持版本),搜索位置为 PATH。如果这样无法找到所需程序,请使用 LLVM_CONFIG 指定正确程序的路径,即 llvm-config。例如: ./configure ... --with-llvm LLVM_CONFIG='/path/to/llvm/bin/llvm-config' @@ -887,16 +786,7 @@ build-postgresql: 构建时支持 LZ4 压缩。 - - - - - - - - - 构建时支持 Zstandard 压缩。 - + 这允许使用 LZ4 压缩表数据。 @@ -910,10 +800,8 @@ build-postgresql: 构建时支持 SSL(加密)连接。 - 唯一支持的 LIBRARY, - 它同时适用于 OpenSSL 和 - LibreSSL。这要求安装 - OpenSSL 软件包。 + 唯一支持的 LIBRARY。 + 这要求安装 OpenSSL 软件包。 configure 会检查所需的头文件和库, 以确认你的 OpenSSL 安装足够后才继续。 @@ -933,8 +821,8 @@ build-postgresql: - 构建时支持 GSSAPI 认证。要使用 GSSAPI,必须安装 MIT Kerberos。 - 在很多系统上,GSSAPI 系统(MIT Kerberos 安装的一部分)并不位于默认搜索的路径 + 构建时支持 GSSAPI 认证。 + 在很多系统上,GSSAPI 系统(通常是 Kerberos 安装的一部分)并不位于默认搜索的路径 中(例如 /usr/include/usr/lib), 因此除了这个选项之外,你还必须使用 configure @@ -988,7 +876,7 @@ build-postgresql: 构建时支持 systemdsystemd 服务通知。如果服务器是在 systemd 下启动, - 这会改进集成;否则没有影响。更多信息见 。 + 这会改进集成;否则没有影响。更多信息见 要使用此选项,需要安装 libsystemd 及其相关头文件。 @@ -1030,7 +918,7 @@ build-postgresql: ,使用 OSSP UUID library + url="http://www.ossp.org/pkg/lib/uuid/">OSSP UUID 库 @@ -1046,45 +934,6 @@ build-postgresql: - - - - - 构建时支持 libcurl,用于 OAuth 2.0 客户端流程。 - 此特性要求 libcurl 7.61.0 或更高版本。 - 使用该选项构建时,会检查所需的头文件和库,以确认你的 - curl 安装足够后才继续。 - - - - - - - - - 构建时支持 libnuma,用于基础 NUMA 支持。 - 仅在实现了 libnuma 库的平台上受支持。 - - - - - - - - - 构建时支持 liburing,以启用异步 I/O 的 io_uring 支持。 - - - 为了检测所需的编译器和链接器选项,PostgreSQL 会查询 - pkg-config。 - - - 如果 liburing 安装在不常见的位置,你可以设置与 - pkg-config 相关的环境变量(见其文档)。 - - - - @@ -1093,13 +942,7 @@ build-postgresql: 这一特性要求 libxml2 2.6.23 或更高版本。 - - 为了检测所需的编译器和链接器选项,如果系统已安装 - pkg-config 且知道 libxml2,PostgreSQL - 会查询 pkg-config。否则,如果找得到由 libxml2 - 安装的 xml2-config 程序,就会使用它。 - 优先使用 pkg-config,因为它能更好地处理多架构安装。 - + 为检测所需的编译器和链接器选项,PostgreSQL 会查询 pkg-config,前提是已安装该程序且其中有 libxml2 的信息。否则,如果找到 libxml2 安装的 xml2-config 程序,就会使用它。优先使用 pkg-config,因为它能更好地处理多架构安装。 如果 libxml2 安装在不常见的位置,你可以设置与 @@ -1127,21 +970,12 @@ build-postgresql: - - - - - 构建时支持 SElinux,以启用 扩展。 - - - - - 反功能 + 禁用特性 本节描述的选项允许禁用某些默认会构建的 @@ -1151,18 +985,6 @@ build-postgresql: - - - - - 构建时不支持 - ICUICU - 库,从而禁用 ICU 排序规则特性(见 )。 - - - - @@ -1200,6 +1022,27 @@ build-postgresql: + + + + 即使 PostgreSQL 不支持该平台的 CPU 自旋锁,也允许构建成功。缺少自旋锁支持会导致性能极差;因此,仅应在构建中止并告知平台缺少自旋锁支持时使用此选项。如果在你的平台上构建 PostgreSQL 必须使用此选项,请向 PostgreSQL 开发者报告该问题。 + + + + + + + 禁用 CPU 原子操作。在不支持此类操作的平台上,此选项不产生影响。在支持的平台上,它会导致性能下降。此选项仅用于调试或性能比较。 + + + + + + + 禁用客户端库的线程安全性。这会使 libpqECPG 程序中的并发线程无法安全地控制各自私有的连接句柄。仅在缺乏完善线程支持的平台上使用此选项。 + + + @@ -1286,8 +1129,7 @@ build-postgresql: - 不在 PostgreSQL 的可执行文件中标记, - 使其在运行时到安装的库目录中搜索共享库(见 )。 + 不在 PostgreSQL 的可执行文件中添加指示其到安装的库目录中搜索共享库的标记(见 )。 在大多数平台上,这种标记使用库目录的绝对路径,因此如果你之后移动安装位置, 它就没有帮助了。不过这样一来,你就需要通过其他方式让可执行文件找到共享库。 通常这要求配置操作系统的动态链接器搜索该库目录;更多细节见 @@ -1304,7 +1146,7 @@ build-postgresql: 杂项 - 调整默认端口号 相当常见, + 使用 调整默认端口号相当常见, 尤其是在测试性构建中。本节中的其他选项只推荐给高级用户。 @@ -1342,7 +1184,7 @@ build-postgresql: 设置 段大小,单位为 GB。 大表会被分成多个操作系统文件,每个文件的大小等于段大小。 这可以避免很多平台上的文件大小限制问题。默认段大小 1GB 在所有支持的平台上 - 都是安全的。如果你的操作系统支持 largefile + 都是安全的。如果你的操作系统支持 大文件 (如今大多数都支持),你可以使用更大的段大小。 这有助于减少处理超大表时消耗的文件描述符数量。 但请注意不要选择超出你的平台和打算使用的文件系统所支持的值。 @@ -1422,11 +1264,11 @@ build-postgresql: - 在服务器中启用 assertion 检查,用于测试许多 - 不应该发生的条件。这对代码开发非常有价值,但这些测试会显著拖慢 + 在服务器中启用 断言 检查,用于测试许多 + 不可能发生的条件。这对代码开发非常有价值,但这些测试可能会显著拖慢 服务器速度。此外,启用这些测试并不一定会增强服务器稳定性! 断言检查并未按严重程度分类,因此即使某个 bug 相对无害,只要触发了断言失败, - 仍可能导致服务器重启。该选项不建议用于生产环境,但如果你在做开发工作 + 仍会导致服务器重启。该选项不建议用于生产环境,但如果你在做开发工作 或运行测试版,就应当启用它。 @@ -1437,7 +1279,7 @@ build-postgresql: 启用使用 Perl TAP 工具的测试。这要求安装 Perl 以及 Perl 模块 - IPC::Run。更多信息见 。 + IPC::Run更多信息见 @@ -1460,7 +1302,7 @@ build-postgresql: 如果使用 GCC,所有程序和库都会带代码覆盖率测试插桩进行编译。 运行时,它们会在构建目录中生成包含代码覆盖率指标的文件。 - 更多信息见 。 + 更多信息见 该选项只适用于 GCC,并且仅在开发工作中使用。 @@ -1471,7 +1313,7 @@ build-postgresql: 如果使用 GCC,所有程序和库都会被编译成可进行性能分析的形式。 - 后端退出时,会创建一个子目录,其中包含带有 profile 数据的 + 后端退出时,会创建一个子目录,其中包含带有性能分析数据的 gmon.out 文件。 该选项只适用于 GCC,并且仅在开发工作中使用。 @@ -1486,7 +1328,7 @@ build-postgresql: DTracePostgreSQL 编译为支持动态跟踪工具 DTrace。 - 更多信息见 。 + 更多信息见 @@ -1511,32 +1353,6 @@ build-postgresql: - - - - - - 将 PostgreSQL 编译为支持服务器中的注入点。 - 注入点允许在预定义的代码路径中,从服务器内部运行用户定义的代码。 - 这有助于以受控方式测试并研究并发场景。该选项默认关闭。 - 更多细节见 。 - 该选项仅供开发人员测试使用。 - - - - - - - - - 以块数指定关系段大小。如果同时指定了 - 和这个选项,则以后者为准。 - - 该选项仅供开发人员测试与段相关的代码。 - - - - @@ -1547,7 +1363,7 @@ build-postgresql: <filename>configure</filename> 环境变量 - configure environment variables + configure 环境变量 @@ -1614,7 +1430,7 @@ build-postgresql: 在使用 --with-llvm 编译时, - 用于处理源代码以内联的 clang 程序路径 + 用于处理源代码以进行内联的 clang 程序路径 @@ -1741,11 +1557,7 @@ build-postgresql: PYTHON - - Python 解释器程序。它将用于确定构建 PL/Python 所需的依赖。 - 如果未设置,则会按以下顺序探测: - python3 python。 - + Python 解释器程序。它将用于确定构建 PL/Python 所需的依赖。此外,这里指定(或以其他方式隐式选择)Python 2 还是 3,决定了可用的 PL/Python 语言变体。更多信息参见 。如果未设置,则会按以下顺序探测:python python3 python2 @@ -1772,21 +1584,9 @@ build-postgresql: - - 有时,在事后把额外的编译器标志加入到 - configure 选定的那组选项中会很有用。 - 一个重要例子是,gcc - 不能包含在传给 configureCFLAGS 中, - 因为这会破坏 configure 的很多内置测试。 - 要添加这类标志,请在运行 make 时把它们放入环境变量 - COPTCOPT 的内容会被附加到 - configure 设置好的 CFLAGS、 - CXXFLAGSLDFLAGS 上。例如,你可以这样做: - + 有时,事后补充编译器标志会很有用;原有标志由 configure 选定。一个重要的例子是 gcc 选项不能包含在以下变量中:CFLAGS(该变量会传给 configure),因为它会破坏 configure 的许多内置测试。要添加此类标志,请将其放入 COPT 环境变量,再运行 makeCOPT 的内容会被加入以下两组选项:CFLAGSLDFLAGS;这两组选项原本由以下程序设置:configure。例如,你可以执行: make COPT='-Werror' - - 或者: - +或者: export COPT='-Werror' make @@ -1814,1170 +1614,25 @@ build-postgresql: - - 使用 Meson 构建和安装 - - - 简短版本 - - - -meson setup build --prefix=/usr/local/pgsql -cd build -ninja -su -ninja install -adduser postgres -mkdir /usr/local/pgsql/data -chown postgres /usr/local/pgsql/data -su - postgres -/usr/local/pgsql/bin/initdb -D /usr/local/pgsql/data -/usr/local/pgsql/bin/pg_ctl -D /usr/local/pgsql/data -l logfile start -/usr/local/pgsql/bin/createdb test -/usr/local/pgsql/bin/psql test - - 较长版本见本其余部分。 - - - - - 安装过程 - - + + 安装后设置 - - 配置 + + 共享库 - - 安装过程的第一步,是针对你的系统配置构建树,并选择你需要的选项。 - 要创建并配置构建目录,可以从 meson setup 命令开始: - -meson setup build - - setup 命令接受 builddirsrcdir - 两个参数。如果未给出 srcdir,Meson 会根据当前目录以及 - meson.build 的位置推导出 srcdir。 - builddir 是必需的。 - + + 共享库 + - 运行 meson setup 会加载构建配置文件并设置构建目录。 - 此外,你也可以向 Meson 传递多个构建选项。后续章节会介绍一些常用选项。例如: - - -# configure with a different installation prefix -meson setup build --prefix=/home/user/pg-install - -# configure to generate a debug build -meson setup build --buildtype=debug - -# configure to build with OpenSSL support -meson setup build -Dssl=openssl - - - - - 设置构建目录是一次性步骤。如果要在新的构建前重新配置,只需使用 - meson configure 命令: - -meson configure -Dcassert=true - - meson configure 的常用命令行选项见 - 。 - - - - - 构建 - - - 默认情况下,Meson 使用 - Ninja 作为构建工具。 - 要使用 Meson 从源代码构建 PostgreSQL, - 只需在构建目录中运行 ninja 命令: - -ninja - - Ninja 会自动检测你的计算机 CPU 数量,并据此并行执行。 - 你也可以用命令行参数 -j 覆盖并行进程数。 - - - - 需要注意的是,在最初的配置步骤之后,ninja 就是你编译时 - 唯一需要输入的命令。不管你如何修改源码树(只要不是把它移动到全新的位置), - Meson 都会检测变化并相应重新生成自己。如果你有多个构建目录,这一点尤其方便。 - 通常其中一个用于开发(调试构建),而另一些只在偶尔需要时使用 - (比如 静态分析构建)。任何配置都只需切换到对应目录, - 然后运行 Ninja 即可完成构建。 - - - - 如果你希望使用 ninja 之外的后端进行构建,可以在配置时使用 - 选项进行选择,然后通过 - meson compile 来构建。要进一步了解这些后端, - 以及你可以传给 ninja 的其他参数,可参考 - - Meson 文档。 - - - - - 回归测试 - - - 回归测试 - - - - 如果你希望在安装之前测试新构建的服务器,可以在此时运行回归测试。 - 回归测试是一套测试,用来验证 PostgreSQL - 是否按开发者预期的方式在你的机器上运行。输入: - -meson test - - (这不能以 root 身份运行;请使用非特权用户。) - 关于如何解释测试结果的详细信息,见 。 - 在以后的任何时候,你都可以再次执行同样的命令来重复此测试。 - - - - 如果要针对正在运行的 postgres 实例运行 pg_regress 和 - pg_isolation_regress 测试,请向 meson test - 传入参数 --setup running。 - - - - - 安装文件 - - - - 如果你是在升级已有系统,请务必阅读 - ,其中包含关于升级集簇的说明。 - - - - - PostgreSQL 构建完成后,只需运行 ninja install 命令即可安装: - -ninja install - - - - - 这会把文件安装到 中指定的目录。 - 请确保你有权限写入该区域。你可能需要以 root 身份执行这一步。 - 另一种做法是预先创建目标目录,并安排授予适当权限。 - 标准安装会提供客户端应用开发以及服务器端程序开发所需的全部头文件, - 例如用 C 编写的自定义函数或数据类型。 - - - - 在大多数情况下,ninja install 都能正常工作; - 但如果你希望使用更多选项(例如 以抑制额外输出), - 也可以改用 meson install。关于 - meson install - 及其选项的更多信息,请参见 Meson 文档。 - - - - - - 卸载: - - 要撤销安装,可以使用 ninja uninstall 命令。 - - - - - 清理: - - 安装完成后,可以通过 ninja clean 命令从源码树中删除 - 已构建文件,以释放磁盘空间。 - - - - - - <literal>meson setup</literal> 选项 - - - 下面解释 meson setup 的命令行选项。 - 这个列表并不完整(可使用 meson configure --help - 获取完整列表)。此处未涉及的选项主要用于高级用例,并记录在标准 - Meson - 文档中。这些参数也可用于 meson setup。 - - - - 安装位置 - - - 这些选项控制 ninja install(或 - meson install)将文件安装到哪里。 - 选项(示例见 ) - 对大多数情况来说已经足够。如果你有特殊需求,可以使用本节中描述的其他选项 - 定制安装子目录。但请注意,更改不同子目录之间的相对位置可能会使安装变得 - 不可重定位,也就是安装后无法再移动。(man 和 - doc 的位置不受这一限制影响。) - 对于可重定位安装,你可能希望使用稍后介绍的 - -Drpath=false 选项。 - - - - - - - - 把所有文件安装到目录 PREFIX 下, - 而不是安装到 /usr/local/pgsql - (类 Unix 系统)或 - 当前驱动器盘符:/usr/local/pgsql - (Windows)下。实际文件会安装到各个子目录中;不会有任何文件直接安装到 - PREFIX 目录中。 - - - - - - - - - 指定可执行程序的目录。默认是 - PREFIX/bin。 - - - - - - - - - 设置各种配置文件的目录,默认是 - PREFIX/etc。 - - - - - - - - - 设置安装库和动态可加载模块的位置。默认是 - PREFIX/lib。 - - - - - - - - - 设置安装 C 和 C++ 头文件的目录。默认是 - PREFIX/include。 - - - - - - - - - 设置已安装程序使用的只读数据文件目录。默认是 - PREFIX/share。 - 注意,这与数据库文件实际存放的位置无关。 - - - - - - - - - 设置安装区域设置数据的目录,尤其是消息翻译目录文件。 - 默认是 DATADIR/locale。 - - - - - - - - - PostgreSQL 附带的手册页将安装到这个目录下 - 各自对应的 manx - 子目录中。默认是 DATADIR/man。 - - - - - - - - - 为了能把 PostgreSQL 安装到共享安装位置 - (例如 /usr/local/include),同时又不干扰系统其他部分的 - 名字空间,我们做了特别处理。首先,除非完整展开后的目录名已经包含字符串 - postgres 或 - pgsql,否则会自动把字符串 - /postgresql 追加到 - datadirsysconfdir 和 - docdir 上。例如,如果你选择 - /usr/local 作为前缀,那么文档会安装到 - /usr/local/doc/postgresql;但如果前缀是 - /opt/postgres,那么它会安装到 - /opt/postgres/doc。客户端接口的公共 C 头文件 - 会安装到 includedir 中,并且不会污染名字空间。 - 内部头文件和服务器头文件则会安装到 includedir - 下的私有目录中。关于如何访问这些头文件,请参见各接口自己的文档。 - 最后,如果有需要,也会在 libdir 下创建私有子目录, - 用于存放动态可加载模块。 - - - - - - <productname>PostgreSQL</productname> 特性 - - - 本节描述的选项用于启用各种可选的 - PostgreSQL 特性。 - 其中大多数需要额外的软件,如 - 所述;如果找到了所需软件,这些特性会自动启用。 - 你可以通过手工把这些特性设为 enabled(要求必须构建) - 或 disabled(不构建),来改变这种行为。 - - - - 要指定 PostgreSQL 特有的选项,选项名必须以 -D 为前缀。 - - - - - - - - 启用或禁用本地语言支持(NLS),也就是以非英语语言显示 - 程序消息的能力。默认值是 auto;如果找到了 - Gettext API 的实现,就会自动启用。 - - - - - - - - - 构建 PL/Perl 服务器端语言。 - 默认值是 auto。 - - - - - - - - - 构建 PL/Python 服务器端语言。 - 默认值是 auto。 - - - - - - - - - 构建 PL/Tcl 服务器端语言。 - 默认值是 auto。 - - - - - - - - - 指定构建 PL/Tcl 时要使用的 Tcl 版本。 - - - - - - - - - 构建时支持 - ICUICU - 库,从而启用 ICU 排序规则特性(见 )。默认值是 auto,并且要求安装 - ICU4C 软件包。当前 - ICU4C 的最低要求版本是 4.2。 - - - - - - - - - 构建时支持基于 LLVM 的 - JIT 编译(见 )。 - 这要求已安装 LLVM 库。 - 当前 LLVM 的最低要求版本是 14。 - 默认禁用。 - - - - llvm-configllvm-config - 将用于查找所需的编译选项。系统会先在你的 PATH 中搜索 - llvm-config,然后再搜索各个受支持版本对应的 - llvm-config-$version。如果这样找不到你想要的程序, - 请使用 LLVM_CONFIG 指定正确的 - llvm-config 路径。 - - - - - - - - - 构建时支持 LZ4 压缩。 - 默认值是 auto。 - - - - - - - - - 构建时支持 Zstandard 压缩。 - 默认值是 auto。 - - - - - - - - OpenSSL - SSL - - - - - 构建时支持 SSL(加密)连接。 - 唯一受支持的 LIBRARY。 - 这要求安装 OpenSSL 软件包。 - 使用该选项构建时,会检查所需的头文件和库,以确认你的 - OpenSSL 安装足够后才继续。 - 该选项的默认值是 auto。 - - - - - - - - - 构建时支持 GSSAPI 认证。要使用 GSSAPI,必须安装 MIT Kerberos。 - 在很多系统上,GSSAPI 系统(MIT Kerberos 安装的一部分)并不位于默认搜索的路径 - 中(例如 /usr/include/usr/lib)。 - 在这种情况下,PostgreSQL 会查询 pkg-config - 来检测所需的编译器和链接器选项。默认值是 auto。 - meson configure 会检查所需的头文件和库, - 以确认你的 GSSAPI 安装足够后才继续。 - - - - - - - - - 构建时支持 - LDAPLDAP - 认证和连接参数查找(更多信息见 - 和 - )。在 Unix 上,这要求安装 - OpenLDAP 软件包。在 Windows 上,使用默认的 - WinLDAP 库。默认值是 auto。 - meson configure 会检查所需的头文件和库, - 以确认你的 OpenLDAP 安装足够后才继续。 - - - - - - - - - 构建时支持 - PAMPAM - (可插拔认证模块)。默认值是 auto。 - - - - - - - - - 构建时支持 BSD 认证。(BSD 认证框架目前仅在 OpenBSD 上可用。) - 默认值是 auto。 - - - - - - - - - 构建时支持 - systemdsystemd - 服务通知。如果服务器是在 systemd 下启动, - 这会改进集成;否则没有影响。更多信息见 - 。默认值是 auto。 - 要使用此选项,需要安装 libsystemd - 及其相关头文件。 - - - - - - - - - 构建时支持 Bonjour 自动服务发现。默认值是 auto,并要求你的操作系统支持 - Bonjour。在 macOS 上推荐启用。 - - - - - - - - - 构建 模块 - (它提供生成 UUID 的函数),并使用指定的 UUID 库。 - UUID - LIBRARY 必须是以下之一: - - - - - ,不构建 uuid 模块。这是默认值。 - - - - - ,使用 FreeBSD 以及其他某些 BSD 衍生系统中的 UUID 函数 - - - - - ,使用 e2fsprogs 项目创建的 UUID 库; - 该库存在于大多数 Linux 系统和 macOS 中,也可用于其他平台 - - - - - ,使用 OSSP UUID library - - - - - - - - - - - 构建时支持 libcurl,用于 OAuth 2.0 客户端流程。 - 此特性要求 libcurl 7.61.0 或更高版本。 - 使用该选项构建时,会检查所需的头文件和库,以确认你的 - Curl 安装足够后才继续。 - 该选项的默认值是 auto。 - - - - - - - - - 构建时支持 liburing,以启用异步 I/O 的 io_uring 支持。 - 默认值是 auto。 - - - - 如果 liburing 安装在不常见的位置,你可以设置与 - pkg-config 相关的环境变量(见其文档)。 - - - - - - - - - 构建时支持 libnuma,用于基础 NUMA 支持。 - 仅在实现了 libnuma 库的平台上受支持。 - 该选项的默认值是 auto。 - - - - - - - - - 构建时支持 libxml2,以启用 SQL/XML 支持。 - 默认值是 auto。该特性要求 libxml2 2.6.23 或更高版本。 - - - - 如果 libxml2 安装在不常见的位置,你可以设置与 - pkg-config 相关的环境变量(见其文档)。 - - - - - - - - - 构建时支持 libxslt,以启用 - - 模块对 XML 执行 XSL 转换。 - 同时还必须指定 。 - 默认值是 auto。 - - - - - - - - - 构建时支持 SElinux,以启用 扩展。 - 默认值是 auto。 - - - - - - - - - 反功能 - - - - - - - 允许使用 Readline 库(以及 - libedit)。该选项默认值为 auto, - 会为 psql 启用命令行编辑和历史记录, - 强烈推荐保留。 - - - - - - - - - 将此值设为 true 时,会优先使用 BSD 许可的 - libedit 库,而不是 GPL 许可的 - Readline。只有在两个库都已安装时, - 该选项才有意义;默认值是 false,也就是使用 - Readline。 - - - - - - - - - - zlib - - 启用 Zlib 库的使用。 - 该选项默认值为 auto,会为 pg_dump、 - pg_restore 和 - pg_basebackup 启用压缩归档支持,推荐保留。 - - - - - - - - - 构建过程细节 - - - - - - - 设置这个选项,可以覆盖所有 auto 特性的取值 - (也就是那些在找到所需软件时会自动启用的特性)。 - 当你想一次性禁用或启用所有 optional 特性, - 而不必逐个手工设置时,这会很有用。 - 该参数的默认值是 auto。 - - - - - - - - - Meson 默认使用的后端是 ninja,这对大多数用例已经足够。 - 不过,如果你希望与 Visual Studio 完全集成,可以把 - BACKEND 设为 vs。 - - - - - - - - - 这个选项可用于向 C 编译器传递额外选项。 - - - - - - - - - 这个选项可用于向 C 链接器传递额外选项。 - - - - - - - - - DIRECTORIES 是一个以逗号分隔的目录列表, - 这些目录会被加入编译器搜索头文件的路径中。 - 如果你把可选软件包(如 GNU Readline) - 安装在非标准位置,就必须使用此选项,并且通常还要使用对应的 - 选项。 - - - - 例如: - -Dextra_include_dirs=/opt/gnu/include,/usr/sup/include。 - - - - - - - - - DIRECTORIES 是一个以逗号分隔的目录列表, - 用于搜索库文件。如果你把软件包安装在非标准位置, - 很可能需要使用这个选项(以及对应的 - )。 - - - 例如:-Dextra_lib_dirs=/opt/gnu/lib,/usr/sup/lib。 - - - - - - - - 时区数据 - - - - - PostgreSQL 自带了日期和时间操作所需的时区数据库。 - 这个时区数据库实际上与很多操作系统(如 FreeBSD、Linux 和 Solaris) - 提供的 IANA 时区数据库兼容,因此再次安装它是多余的。使用此选项时, - 将使用位于 DIRECTORY 的系统提供时区数据库, - 而不是 PostgreSQL 源码发布中自带的那一份。 - DIRECTORY 必须是绝对路径。 - 在某些操作系统上,/usr/share/zoneinfo - 是一个可能的目录。请注意,安装过程不会检测时区数据是否不匹配或有误。 - 如果你使用该选项,建议运行回归测试,以验证你指定的时区数据能够与 - PostgreSQL 正常配合工作。 - - - 交叉编译 - - - 这个选项主要面向那些非常了解其目标操作系统的二进制包发布者。 - 使用该选项的主要优点是,当本地众多夏令时规则中的任何一条发生变化时, - PostgreSQL 软件包都无需升级。另一个优点是,如果安装时不需要构建 - 时区数据库文件,那么 PostgreSQL 的交叉编译也会更直接。 - - - - - - - - - 将 STRING 追加到 PostgreSQL 版本号后面。 - 例如,你可以用它给从未发布的 Git 快照构建出来的 - 二进制文件、或包含自定义补丁的二进制文件,添加额外版本字符串作为标记, - 例如 git describe 标识符或发行包版本号。 - - - - - - - - - 该选项默认值是 true。如果设为 false,则不会在 - PostgreSQL 的可执行文件中标记, - 使其在运行时到安装的库目录中搜索共享库(见 )。 - 在大多数平台上,这种标记使用库目录的绝对路径,因此如果你之后移动安装位置, - 它就没有帮助了。不过这样一来,你就需要通过其他方式让可执行文件找到共享库。 - 通常这要求配置操作系统的动态链接器搜索该库目录;更多细节见 - 。 - - - - - - - - - 如果构建 PostgreSQL(无论是否启用可选标志)所需的某个程序位于非标准路径, - 你可以手工把它指定给 meson configure。 - 支持这样指定的程序完整列表,可通过运行 - meson configure 查看。例如: -meson configure -DBISON=PATH_TO_BISON - - - - - - - - 文档 - - - 关于构建文档所需的工具,见 。 - - - - - - - - - 启用构建 HTMLman - 格式的文档。默认值是 auto。 - - - - - - - - - 启用构建 PDF 格式的文档。默认值是 auto。 - - - - - - - - - 控制使用哪种 CSS 样式表。默认值是 - simple。如果设为 website, - HTML 文档将引用 - postgresql.org - 的样式表。 - - - - - - - - - 杂项 - - - - - - - 将 NUMBER 设为服务器和客户端的默认端口号。 - 默认值是 5432。端口号以后始终都可以修改,但如果在这里指定, - 那么服务器和客户端都会编译进同一个默认值,这可能很方便。 - 通常选择非默认值的唯一合理原因,是你打算在同一台机器上运行多个 - PostgreSQL 服务器。 - - - - - - - - - GSSAPI 所使用的 Kerberos 服务主体的默认名称。 - 默认是 postgres。通常没有理由修改它, - 除非你是在为 Windows 环境构建,在那种情况下它必须被设为大写的 - POSTGRES。 - - - - - - - - - 设置 段大小,单位为 GB。 - 大表会被分成多个操作系统文件,每个文件的大小等于段大小。 - 这可以避免很多平台上的文件大小限制问题。默认段大小 1GB 在所有支持的平台上 - 都是安全的。如果你的操作系统支持 largefile - (如今大多数都支持),你可以使用更大的段大小。 - 这有助于减少处理超大表时消耗的文件描述符数量。 - 但请注意不要选择超出你的平台和打算使用的文件系统所支持的值。 - 你可能想用到的其他工具,例如 tar, - 也可能对可用文件大小施加限制。推荐(但不是绝对要求)把这个值设为 2 的幂。 - - - - - - - - - 设置 块大小,单位为 KB。 - 这是表内部存储和 I/O 的单位。默认值 8KB 适合大多数场景, - 但在特殊情况下,其他取值也可能有用。 - 该值必须是 1 到 32(KB)之间的 2 的幂。 - - - - - - - - - 设置 WAL 块大小,单位为 KB。 - 这是 WAL 日志内部存储和 I/O 的单位。默认值 8KB 适合大多数场景, - 但在特殊情况下,其他取值也可能有用。 - 该值必须是 1 到 64(KB)之间的 2 的幂。 - - - - - - - - 开发人员选项 - - - 本节中的大多数选项只对开发或调试 - PostgreSQL 有意义。 - 除 外,不建议在生产构建中使用它们; - 不过,如果你不幸遇到 bug,该选项有助于获得更详细的 bug 报告。 - 在支持 DTrace 的平台上, - 也可能适合在生产环境中使用。 - - - - 如果构建的安装将用于开发服务器内部代码,建议至少使用 - 。 - - - - - - - - 这个选项可用于指定要使用的构建类型;默认值是 - 。如果你希望对调试符号和优化级别 - 进行比该选项更细粒度的控制,可以参考 - 标志。 - - - - 常用的构建类型包括:、 - 和 - 。关于它们的更多信息,可参见 - Meson - 文档。 - - - - - - - - - 将所有程序和库编译为带调试符号的版本。这意味着你可以在调试器中运行程序, - 以分析问题。这会显著增大安装后的可执行文件大小,而且在非 GCC 编译器上, - 通常还会禁用编译器优化,从而导致变慢。不过,保留这些符号对于处理可能出现的 - 各种问题极其有帮助。目前,只有在你使用 GCC 的情况下,才建议在生产安装中使用 - 该选项。但如果你在做开发工作或运行测试版,就应始终启用它。 - - - - - - =LEVEL - - - 指定优化级别。 可以设为 - {0,g,1,2,3,s} 中任意一个。 - - - - - - - - - 设置该选项后,编译器会把警告当作错误处理。 - 这对代码开发很有用。 - - - - - - - - - 在服务器中启用 assertion 检查,用于测试许多 - 不应该发生的条件。这对代码开发非常有价值,但这些测试会显著拖慢 - 服务器速度。此外,启用这些测试并不一定会增强服务器稳定性! - 断言检查并未按严重程度分类,因此即使某个 bug 相对无害,只要触发了断言失败, - 仍可能导致服务器重启。该选项不建议用于生产环境,但如果你在做开发工作 - 或运行测试版,就应当启用它。 - - - - - - - - - 启用使用 Perl TAP 工具的测试。默认值是 auto,并要求安装 Perl 以及 - Perl 模块 IPC::Run。更多信息见 - 。 - - - - - - - - - 启用额外测试套件;这些测试默认不会运行,因为它们不适合在多用户系统上运行、 - 需要特殊软件,或者资源消耗较大。该参数是以空白分隔的测试名称列表。 - 详见 。如果在运行测试时设置了 - PG_TEST_EXTRA 环境变量,那么它会覆盖这个构建时选项。 - - - - - - - - - 如果使用 GCC,所有程序和库都会带代码覆盖率测试插桩进行编译。 - 运行时,它们会在构建目录中生成包含代码覆盖率指标的文件。 - 更多信息见 。 - 该选项只适用于 GCC,并且仅在开发工作中使用。 - - - - - - - - - - DTrace - - 启用该选项会将 PostgreSQL 编译为支持动态跟踪工具 - DTrace。更多信息见 。 - - - - 如果要指向 dtrace 程序,可以设置 - 选项。这通常是必要的,因为 - dtrace 往往安装在 /usr/sbin 下, - 而该目录可能不在你的 PATH 中。 - - - - - - - - - 将 PostgreSQL 编译为支持服务器中的注入点。 - 注入点允许在预定义的代码路径中,从服务器内部运行用户定义的代码。 - 这有助于以受控方式测试并研究并发场景。该选项默认关闭。 - 更多细节见 。 - 该选项仅供开发人员测试使用。 - - - - - - - - - 以块数指定关系段大小。如果同时指定了 - 和这个选项,则以后者为准。 - - 该选项仅供开发人员测试与段相关的代码。 - - - - - - - - - - - - 安装后设置 - - - 共享库 - - - 共享库 - - - - 在某些使用共享库的系统上,你需要告诉系统如何找到新安装的共享库。 - 需要这样做的系统包括 - FreeBSD、 - Linux、 - NetBSD、 - OpenBSD 和 - Solaris。 + 在某些使用共享库的系统上,你需要告诉系统如何找到新安装的共享库。 + 需要这样做的系统包括 + FreeBSD、 + HP-UX、 + Linux、 + NetBSD、 + OpenBSD 和 + Solaris @@ -3112,21 +1767,9 @@ export MANPATH 成员机器,以便持续确保兼容性。 - - 一般来说,可以预期 PostgreSQL 能在以下 CPU - 架构上工作:x86、PowerPC、S/390、SPARC、ARM、MIPS 和 RISC-V, - 以及在适用情况下的大端、小端、32 位和 64 位变体。 - + 一般来说,可以预期 PostgreSQL 能在以下 CPU 架构上工作:x86、x86_64、IA64、PowerPC、PowerPC 64、S/390、S/390x、Sparc、Sparc 64、ARM、MIPS、MIPSEL 和 PA-RISC。代码中包含对 M68K、M32R 和 VAX 的支持,但尚不清楚这些架构近期是否经过测试。对于不受支持的 CPU 类型,通常可以通过配置 来构建,但性能会很差。 - - 可以预期 PostgreSQL 能在这些操作系统的当前版本上工作: - Linux、Windows、FreeBSD、OpenBSD、NetBSD、DragonFlyBSD、macOS、Solaris - 和 illumos。其他类 Unix 系统也可能可用,但目前未在测试。 - 大多数情况下,某个操作系统所支持的全部 CPU 架构也都可以工作。 - 尤其是在使用较旧系统时,请查看下面的 - , - 看看是否有针对你的操作系统的特别说明。 - + 可以预期 PostgreSQL 能在以下操作系统上工作:Linux(所有较新的发行版)、Windows(XP 及更高版本)、FreeBSD、OpenBSD、NetBSD、macOS、AIX、HP/UX 和 Solaris。其他类 Unix 系统也可能可用,但目前未在测试。大多数情况下,某个操作系统所支持的全部 CPU 架构也都可以工作。尤其是在使用较旧系统时,请查看下面的 ,看看是否有针对你的操作系统的特别说明。 如果你在某个平台上遇到安装问题,而根据近期构建农场的结果该平台是受支持的, @@ -3134,14 +1777,6 @@ export MANPATH 如果你有兴趣把 PostgreSQL 移植到一个新平台, 那么 pgsql-hackers@lists.postgresql.org 是合适的讨论地点。 - - - 历史版本的 PostgreSQL 或 POSTGRES 也曾运行在 - Alpha、Itanium、M32R、M68K、M88K、NS32K、PA-RISC、SuperH 和 VAX 等 - CPU 架构上,以及 4.3BSD、AIX、BEOS、BSD/OS、DG/UX、Dynix、HP-UX、IRIX、 - NeXTSTEP、QNX、SCO、SINIX、Sprite、SunOS、Tru64 UNIX 和 ULTRIX 等 - 操作系统上。 - @@ -3157,6 +1792,42 @@ export MANPATH 这里未列出的平台,目前没有已知的平台特定安装问题。 + + AIX + + + AIX + 在其上安装 + + + PostgreSQL 可以在 AIX 上运行,但大约 6.1 之前的 AIX 版本存在各种问题,不建议使用。你可以使用 GCC 或原生 IBM 编译器 xlc + + + 内存管理 + + + AIX 的内存管理方式有些特殊。服务器可能有数 GB 乃至更多的空闲 RAM,但运行应用程序时仍会出现内存不足或地址空间错误。例如,加载扩展可能因不寻常的错误而失败。以下是以 PostgreSQL 安装所有者身份运行的例子: +=# CREATE EXTENSION plperl; +ERROR: could not load library "/opt/dbs/pgsql/lib/plperl.so": A memory address is not in the address space for the process. +以 PostgreSQL 安装所属组中非所有者的成员身份运行: +=# CREATE EXTENSION plperl; +ERROR: could not load library "/opt/dbs/pgsql/lib/plperl.so": Bad address +另一个例子是 PostgreSQL 服务器日志中的内存不足错误,此时每次接近或超过 256 MB 的内存分配都会失败。 + + 这些问题的总体原因是服务器进程使用的默认位数和内存模型。默认情况下,在 AIX 上构建的所有二进制文件都是 32 位的。这与硬件类型或所用内核无关。这些 32 位进程的内存上限为 4 GB,按几种模型之一以 256 MB 的段布局。默认情况下,堆与栈共享一个段,因此堆可用空间不足 256 MB。 + + 对于上面的 plperl 示例,请检查你的 umask 和 PostgreSQL 安装中二进制文件的权限。该示例涉及的二进制文件是 32 位的,安装时使用模式 750 而非 755。由于权限以这种方式设置,只有所有者或所属组的成员可以加载该库。因为它不是所有用户可读,加载器会将该对象放入进程的堆中,而不是通常应放置的共享库段。 + + 这个问题的理想解决办法是使用 64 位构建的 PostgreSQL,但这并非总是可行,因为采用 32 位处理器的系统可以构建 64 位二进制文件,却无法运行它们。 + + 如果需要 32 位二进制文件,请在启动 PostgreSQL 服务器之前,将 LDR_CNTRL 设为 MAXDATA=0xn0000000,其中 1 <= n <= 8,并尝试不同的值及 postgresql.conf 设置,找到能令人满意地工作的配置。这样使用 LDR_CNTRL 会告知 AIX,为服务器的堆预留 MAXDATA 字节,按 256 MB 的段分配。找到可用配置后,可以使用 ldedit 修改二进制文件,使其默认使用所需的堆大小。也可以重新构建 PostgreSQL,传入 configure LDFLAGS="-Wl,-bmaxdata:0xn0000000" 来达到相同效果。 + + 对于 64 位构建,将 OBJECT_MODE 设为 64,并向 configure 传入 CC="gcc -maix64"LDFLAGS="-Wl,-bbigtoc"。(xlc 的选项可能不同。)如果未导出 OBJECT_MODE,构建可能因链接器错误而失败。设置 OBJECT_MODE 后,它会告知 AIX 的 arasld 等构建工具默认处理哪种对象。 + + 默认情况下,可能发生分页空间过量分配。虽然我们尚未见过这种情况,但当内存耗尽且访问了过量分配的空间时,AIX 会终止进程。我们遇到过最接近的情况是,系统认为没有足够内存容纳另一个进程,导致 fork 失败。与 AIX 的许多其他部分一样,如果这成为问题,可以在系统或进程级别配置分页空间分配方式和内存不足时终止进程的行为。 + + + Cygwin @@ -3165,10 +1836,7 @@ export MANPATH 在其上安装 - - 可以使用 Cygwin 这个 Windows 上的类 Linux 环境来构建 PostgreSQL, - 但这种方式不如原生 Windows 构建,且如今已不再推荐在 Cygwin 下运行服务器。 - + 可以使用 Cygwin 这个 Windows 上的类 Linux 环境来构建 PostgreSQL,但这种方式不如原生 Windows 构建(见 ,且如今已不再推荐在 Cygwin 下运行服务器。 从源代码构建时,请按照 Unix 风格的安装过程(也就是 @@ -3184,17 +1852,11 @@ export MANPATH - - 不支持 adduser 命令;请使用 Windows 中相应的 - 用户管理应用。除此之外,跳过这一步即可。 - + 不支持 adduser 命令;请使用 Windows NT、2000 或 XP 中相应的用户管理应用。如果不是这些系统,则跳过此步骤。 - - 不支持 su 命令;请在 Windows 上使用 ssh 来模拟 su。 - 除此之外,跳过这一步即可。 - + 不支持 su 命令;请在 Windows NT、2000 或 XP 上使用 ssh 模拟 su。如果不是这些系统,则跳过此步骤。 @@ -3224,16 +1886,11 @@ export MANPATH - - 并行回归测试(make check)可能会因为 - listen() backlog 队列溢出而产生伪造的回归测试失败, - 进而导致连接拒绝错误或挂起。你可以像下面这样使用 make 变量 - MAX_CONNECTIONS 来限制连接数: + 并行回归测试(make check)可能因 listen() 的待处理连接队列溢出而误报回归测试失败;队列溢出会导致连接被拒绝的错误或挂起。可以使用 make 变量 MAX_CONNECTIONS 限制连接数,方法如下: make MAX_CONNECTIONS=5 check - (在某些系统上,同时连接数大致最多可达到 10 个。) - +(在某些系统上,并发连接数最高可达约 10 个。) @@ -3306,7 +1963,7 @@ xcrun --show-sdk-path macOS 的 - System Integrity Protection(SIP)特性会破坏 + 系统完整性保护(SIP)特性会破坏 make check,因为它会阻止把所需的 DYLD_LIBRARY_PATH 设置传递给被测试的可执行文件。 你可以通过在 make check 之前先执行 @@ -3316,21 +1973,23 @@ xcrun --show-sdk-path - MinGW + MinGW/原生 Windows MinGW 在其上安装 - - 可以使用 MinGW 这个 Windows 上的类 Unix 构建环境来构建 Windows 版 - PostgreSQL。推荐为此使用 MSYS2 环境,并安装所需的前置软件包。 - + Windows 版 PostgreSQL 可以使用 MinGW(用于 Microsoft 操作系统的类 Unix 构建环境)构建,也可以使用 Microsoft 的 Visual C++ 编译器套件构建。MinGW 构建过程使用本章介绍的常规构建系统;Visual C++ 构建方式完全不同,详见 + + 原生 Windows 移植版本要求 32 位或 64 位的 Windows 2000 或更高版本。更早的操作系统没有足够的基础设施(但可以在其上使用 Cygwin)。可以从 下载 MinGW 这一类 Unix 构建工具,以及 MSYS 这一运行 configure 等 shell 脚本所需的 Unix 工具集。运行生成的二进制文件不需要它们;只有创建二进制文件时才需要。 + + 要使用 MinGW 构建 64 位二进制文件,请从 安装 64 位工具集,将其 bin 目录放入 PATH,并使用 --host=x86_64-w64-mingw32 选项运行 configure - - 收集崩溃转储 + 安装好所有组件后,建议在 CMD.EXE 下运行 psql,因为 MSYS 控制台存在缓冲问题。 + + + 在 Windows 上收集崩溃转储 如果 PostgreSQL 在 Windows 上崩溃,它能够生成 @@ -3372,7 +2031,7 @@ xcrun --show-sdk-path 你可以从 下载 Sun Studio。许多 GNU 工具已经集成到 Solaris 10 中, - 或者包含在 Solaris companion CD 中。如果你需要适用于较旧 Solaris 版本的 + 或者包含在 Solaris 配套光盘中。如果你需要适用于较旧 Solaris 版本的 软件包,可以到 查找这些工具。 如果你更想要源码,请看 。 @@ -3380,10 +2039,10 @@ xcrun --show-sdk-path - configure 抱怨测试程序失败 + configure 报告测试程序失败 - 如果 configure 抱怨某个测试程序失败, + 如果 configure 报告某个测试程序失败, 这多半是因为运行时链接器找不到某些库,通常是 libz、libreadline, 或其他非标准库如 libssl。要把它指向正确位置,请在 configure 命令行中设置环境变量 LDFLAGS, @@ -3438,248 +2097,6 @@ make: *** [postgres] Error 1 - - - Visual Studio - - - Visual Studio - 在其上安装 - - - - 建议大多数用户直接下载 Windows 的二进制发行版,它以图形化安装程序的形式发布在 - PostgreSQL 网站上: - 。 - 从源代码构建只适合开发 PostgreSQL - 或扩展的人。 - - - - Windows 上配合 Visual Studio 的 PostgreSQL 可以使用 Meson 构建, - 如 所述。 - 原生 Windows 移植要求 Windows 10 或更高版本的 32 位或 64 位系统。 - - - - 原生构建的 psql 不支持命令行编辑。 - Cygwin 构建支持命令行编辑,因此如果需要在 - Windows 上交互式使用 psql, - 应使用 Cygwin 构建。 - - - - PostgreSQL 可以使用 Microsoft 的 Visual C++ 编译器套件构建。 - 这些编译器可以来自 Visual Studio、 - Visual Studio Express,或某些版本的 - Microsoft Windows SDK。 - 如果你还没有搭建好 Visual Studio 环境, - 最简单的办法是使用 Visual Studio 2022 中的编译器, - 或者 Windows SDK 10 中的编译器; - 它们都可以从 Microsoft 免费下载。 - - - - Microsoft 编译器套件既可以进行 32 位构建,也可以进行 64 位构建。 - 32 位 PostgreSQL 可使用 Visual Studio 2015 到 - Visual Studio 2022 构建,也可使用独立发布的 - Windows SDK 10 及更高版本。64 位 PostgreSQL 构建则支持 - Microsoft Windows SDK 10 及更高版本, - 或 Visual Studio 2015 及更高版本。 - - - - - 如果你的构建环境没有附带受支持版本的 - Microsoft Windows SDK,建议升级到最新版本 - (当前是 10 版),可从 - 下载。 - - - - 你必须始终安装 SDK 中的 - Windows Headers and Libraries 部分。 - 如果你安装的 Windows SDK 包含 - Visual C++ Compilers,那么即使没有 - Visual Studio 也可以完成构建。 - 请注意,自 8.0a 版本起,Windows SDK 已不再附带完整的命令行构建环境。 - - - - 需求 - - 在 Windows 上构建 PostgreSQL 还需要下列附加产品。 - - - - Strawberry Perl - - 运行构建生成脚本需要 Strawberry Perl。MinGW Perl 或 Cygwin Perl 都不行。 - 它还必须位于 PATH 中。二进制文件可从 - 下载。 - - - - - Bison 和 - Flex - - - BisonFlex - 的二进制文件可以从 下载。 - - - - - - - - 下列附加产品虽然不是开始构建所必需的,但要构建完整软件包则需要它们。 - - - - Magicsplat Tcl - - 构建 PL/Tcl 所需。 - 二进制文件可从 - 下载。 - - - - - Diff - - 运行回归测试需要 Diff,可从 - 下载。 - - - - - Gettext - - 构建 NLS 支持需要 Gettext,可从 - 下载。 - 请注意,二进制文件、依赖项和开发文件都需要。 - - - - - MIT Kerberos - - GSSAPI 认证支持所需。MIT Kerberos 可从 - 下载。 - - - - - libxml2 和 - libxslt - - XML 支持所需。二进制文件可从 - 下载, - 源代码可从 下载。 - 请注意,libxml2 需要 iconv,而它也可在同一下载位置获得。 - - - - - LZ4 - - 支持 LZ4 压缩所需。 - 二进制文件和源代码可从 - 下载。 - - - - - Zstandard - - 支持 Zstandard 压缩所需。 - 二进制文件和源代码可从 - 下载。 - - - - - OpenSSL - - SSL 支持所需。二进制文件可从 - 下载, - 源代码可从 下载。 - - - - - ossp-uuid - - UUID-OSSP 支持(仅限 contrib)所需。源代码可从 - 下载。 - - - - - Python - - 构建 PL/Python 所需。 - 二进制文件可从 下载。 - - - - - zlib - - pg_dumppg_restore - 的压缩支持所需。二进制文件可从 下载。 - - - - - - - - - 64 位 Windows 的特别注意事项 - - PostgreSQL 在 64 位 Windows 上只能构建为 x64 架构。 - - - 不支持在同一个构建树中混用 32 位和 64 位版本。 - 构建系统会自动检测自己当前运行在 32 位还是 64 位环境中,并据此构建 PostgreSQL。 - 因此,在开始构建前,启动正确的命令提示符非常重要。 - - - 如果要使用服务器端第三方库,例如 Python 或 - OpenSSL,那么该库也必须 - 是 64 位的。64 位服务器不支持加载 32 位库。PostgreSQL 支持的若干第三方库 - 可能只提供 32 位版本,在这种情况下,它们无法与 64 位 PostgreSQL 一起使用。 - - - - - 收集崩溃转储 - - - 如果 PostgreSQL 在 Windows 上崩溃,它能够生成 - minidumps,可用于追踪崩溃原因, - 类似于 Unix 上的核心转储。这些转储可以使用 - Windows Debugger Tools 或 - Visual Studio 读取。 - 要在 Windows 上启用转储生成,请在集簇数据目录中创建一个名为 - crashdumps 的子目录。随后,转储会以唯一名称写入该目录, - 该名称基于崩溃进程的标识符以及崩溃发生时的当前时间。 - - - diff --git a/zh/14/isn.sgml b/zh/14/isn.sgml index fa876f36..8a9e9270 100644 --- a/zh/14/isn.sgml +++ b/zh/14/isn.sgml @@ -1,7 +1,7 @@ - isn — 国际标准编号(ISBN、EAN、UPC 等)的数据类型 + isn isn @@ -215,69 +215,53 @@ - make_valid - make_valid ( isn ) - isn + isn_weak + isn_weak ( boolean ) + boolean - 使一个无效编号变为有效(清除无效标记)。 + 设置弱输入模式,并返回新的设置值。 - is_valid - is_valid ( isn ) + isn_weak () boolean - 检查是否存在无效标记。 + 返回弱模式的当前状态。 - isn_weak - isn_weak ( boolean ) - boolean + make_valid + make_valid ( isn ) + isn - 设置弱输入模式,并返回新的设置值。 + 将无效编号变为有效(清除无效标记)。 - isn_weak () + is_valid + is_valid ( isn ) boolean - 返回弱模式的当前状态。 + 检查是否存在无效标记。
- - - 配置参数 - - - - - isn.weak (boolean) - - isn.weak 配置参数 - - - - - isn.weak启用弱输入模式,使得即使 ISN 输入值的校验位有误也会被接受。默认值为false,此时会拒绝无效校验位。 - - - - + + 模式用于允许向表中插入无效数据。这里的“无效”指的是校验位错误,而不是缺少数字。 + 为什么会需要使用弱模式呢?例如,手头可能有一大批 ISBN 编号,数量多到难免会有一些编号因为某些奇怪的原因而带有错误的校验位(也许这些编号是从印刷清单扫描得到的,而 OCR 把数字识别错了;也许这些编号是人工录入的……谁知道呢)。总之,可能想把这些混乱情况清理干净,但同时仍希望先把所有编号都装入数据库,并借助外部工具在数据库中定位无效编号,以便核对信息并更容易完成校验;例如,可能会想把表中所有无效编号都查询出来。 @@ -288,7 +272,7 @@ - 即使未启用弱模式,也可以通过在编号末尾附加!字符来强制插入被标记为无效的编号。 + 即使未启用弱模式,也可以通过在编号末尾附加 ! 字符来强制插入无效编号。 diff --git a/zh/14/libpq.sgml b/zh/14/libpq.sgml index 62187982..7c618301 100644 --- a/zh/14/libpq.sgml +++ b/zh/14/libpq.sgml @@ -41,7 +41,7 @@ - 如果不可信用户能够访问一个没有采用模式的安全使用方式的数据库,那么每个会话开始时都应从search_path中移除公开可写的模式。可以把参数关键词options设置为-csearch_path=。也可以在连接后发出PQexec(conn, "SELECT pg_catalog.set_config('search_path', '', false)")。这种考虑并非专门针对libpq;它适用于每一种可执行任意 SQL 命令的接口。 + 如果不受信任的用户能够访问一个没有采用模式的安全使用方式的数据库,那么每个会话开始时都应从search_path中移除公开可写的模式。可以把参数关键词options设置为-csearch_path=。也可以在连接后发出PQexec(conn, "SELECT pg_catalog.set_config('search_path', '', false)")。这种考虑并非专门针对libpq;它适用于每一种可执行任意 SQL 命令的接口。 @@ -214,7 +214,7 @@ PostgresPollingStatusType PQconnectPoll(PGconn *conn); - hostaddrhost参数必须被合适地使用,以防止做DNS查询。详见中这些参数的文档。 + 必须正确使用 hostaddr 参数,以避免执行 DNS 查询。详细信息请参见中该参数的说明。 @@ -779,7 +779,7 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname 参数关键词 - 目前被识别的参数关键字包括: + 目前被识别的参数关键字包括: @@ -919,93 +919,7 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname - - require_auth - - - 指定客户端要求服务器采用的认证方法。如果服务器没有使用所要求的方法来认证客户端,或者服务器没有完整完成认证握手,则连接将失败。也可以提供一个以逗号分隔的方法列表,此时服务器必须准确使用其中一种方法,连接才会成功。默认情况下接受任意认证方法,并且服务器也可以完全跳过认证。 - - - 可以在方法名前加上!前缀以表示否定,此时服务器不得尝试所列方法;除此之外,任何其他方法都可接受,并且服务器也可以完全不认证客户端。如果提供的是逗号分隔列表,服务器不得尝试其中任何一个被否定的方法。否定形式和非否定形式不能在同一设置中混用。 - - - 最后还有一种特殊情况:none方法要求服务器不使用认证质询。(它也可以被否定,用来要求必须进行某种认证。) - - - 可指定的方法如下: - - - - password - - - 服务器必须请求明文密码认证。 - - - - - - md5 - - - 服务器必须请求 MD5 哈希密码认证。 - - - - 对 MD5 加密密码的支持已被废弃,并将在未来的PostgreSQL版本中移除。关于迁移到其他密码类型的细节,请参见。 - - - - - - - gss - - - 服务器必须通过GSSAPI请求 Kerberos 握手,或者建立一个经过GSS加密的通道(另见)。 - - - - - - sspi - - - 服务器必须请求 Windows SSPI 认证。 - - - - - - scram-sha-256 - - - 服务器必须与客户端成功完成一次 SCRAM-SHA-256 认证交换。 - - - - - - oauth - - - 服务器必须向客户端请求 OAuth Bearer 令牌。 - - - - - none - - - 服务器不得提示客户端执行认证交换。(这并不禁止通过 TLS 进行客户端证书认证,也不禁止通过其加密传输进行 GSS 认证。) - - - - - - - channel_binding @@ -1354,34 +1268,7 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname - - sslnegotiation - - - 如果使用 SSL,此选项控制如何与服务器协商 SSL 加密。在默认的postgres模式下,客户端会先询问服务器是否支持 SSL;在direct模式下,客户端会在建立 TCP/IP 连接后直接开始标准 SSL 握手。传统的PostgreSQL协议协商能兼容更多不同的服务器配置;如果已知服务器支持直接SSL连接,则后一种方式可以减少一次往返,从而降低连接延迟,也允许使用与协议无关的 SSL 网络工具。直接 SSL 选项是在PostgreSQL 17 中引入的。 - - - - - postgres - - - 执行PostgreSQL协议协商。如果未提供该选项,这是默认值。 - - - - - direct - - - 在建立 TCP/IP 连接后直接开始 SSL 握手。仅当sslmode=require或更高时才允许使用该模式,因为更弱的设置可能在服务器不支持直接 SSL 握手时导致意外回退到明文认证。 - - - - - - sslcompression @@ -1429,19 +1316,7 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname - - sslkeylogfile - - - 这个参数指定libpq记录此 SSL 上下文所用密钥的位置。这对于调试PostgreSQL协议交互,或者借助Wireshark之类的网络检查工具分析客户端连接很有用。如果未建立 SSL 连接,或者使用的是LibreSSL(其不支持密钥记录),则会忽略此参数。密钥将按NSS格式记录。 - - - 密钥记录会在 keylog 文件中暴露潜在敏感信息。应当像处理文件一样谨慎处理 keylog 文件。 - - - - - + sslpassword @@ -1468,49 +1343,7 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname - - sslcertmode - - - 此选项决定是否可以向服务器发送客户端证书,以及服务器是否必须请求客户端证书。共有三种模式: - - - - disable - - - 即使客户端有可用证书(默认位置或通过提供),也绝不发送客户端证书。 - - - - - - allow(默认) - - - 如果服务器请求证书且客户端有证书可发,则可以发送证书。 - - - - - - require - - - 服务器必须请求证书。如果客户端没有发送证书而服务器仍成功认证了客户端,则连接将失败。 - - - - - - - - sslcertmode=require不会增加额外的安全性,因为无法保证服务器一定正确验证了证书;PostgreSQL服务器通常无论是否验证,都会向客户端请求 TLS 证书。该选项在排查更复杂的 TLS 配置时可能有用。 - - - - sslrootcert @@ -1617,47 +1450,9 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname - - min_protocol_version - - - 这个参数指定该连接允许的最低协议版本。默认情况下,允许使用 - libpq所支持的任何 - PostgreSQL协议版本, - 目前即3.0。如果服务器至少不支持这一协议版本, - 则连接将被关闭。 - - - 当前支持的值是3.03.2 - 和latestlatest等价于 - 正在使用的libpq版本所支持的最新协议版本, - 目前即3.2。 - - - - - max_protocol_version - - - 这个参数指定要向服务器请求的协议版本。默认会使用 - PostgreSQL协议的3.0版本; - 但如果连接字符串指定了依赖更高协议版本的特性,则会使用 - libpq支持的最新版本。如果服务器不支持客户端请求的协议版本, - 连接会自动降级为服务器支持的较低次版本协议。连接尝试完成后, - 你可以使用PQfullProtocolVersion()来确定 - 最终协商得到的确切协议版本。 - - - 当前支持的值是3.03.2 - 和latestlatest等价于 - 正在使用的libpq版本所支持的最新协议版本, - 目前即3.2。 - - - krbsrvname @@ -1690,32 +1485,11 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname - - gssdelegation - - - 将 GSS 凭证转发(委派)给服务器。默认值为0,表示不向服务器转发凭证。将其设置为1时,会在可能的情况下转发凭证。 - - - - - scram_client_key - - - 以 Base64 编码的 SCRAM client key。外部数据包装器或类似中间件可以利用它启用透传式 SCRAM 认证。一个实现示例见。普通用户或客户端应用不应直接指定它。 - - - - - scram_server_key - - - 以 Base64 编码的 SCRAM server key。外部数据包装器或类似中间件可以利用它启用透传式 SCRAM 认证。一个实现示例见。普通用户或客户端应用不应直接指定它。 - - - + + + service @@ -1797,98 +1571,15 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname - - load_balance_hosts - - - 控制客户端尝试连接可用主机和地址的顺序。一旦某次连接尝试成功,就不会再尝试其他主机和地址。该参数通常与多个主机名或返回多个 IP 地址的 DNS 记录一起使用。它还可以与组合使用,例如只在备库之间进行负载均衡。连接一旦成功建立,随后在返回的连接上发出的所有查询都会发送到同一台服务器。目前有两种模式: - - - - disable(默认) - - - 不在主机之间执行负载均衡。主机会按提供的顺序进行尝试,地址会按从 DNS 或 hosts 文件获得的顺序进行尝试。 - - - - - - random - - - 按随机顺序尝试主机和地址。这个值主要适用于同时打开多个连接的场景,甚至这些连接来自不同机器。这样就可以把连接负载分散到多个PostgreSQL服务器上。 - - - 虽然随机负载均衡由于其随机性几乎不会得到完全均匀的分布,但统计上会相当接近。这里有一个重要点:该算法使用两级随机选择。首先,主机会按随机顺序解析。其次,在解析下一个主机之前,会按随机顺序尝试当前主机解析得到的全部地址。在某些情况下,这种行为会显著偏斜各节点获得的连接数量,例如某些主机解析出的地址比其他主机更多时。但这种偏斜也可以被有意利用,例如通过在主机字符串中多次提供某台更大服务器的主机名,来增加它获得的连接数量。 - - - 使用这个值时,建议同时为配置一个合理的值。这样,如果某个参与负载均衡的节点没有响应,就会继续尝试新的节点。 - - - - - - - - - oauth_issuer - - - 如果服务器为该连接请求 OAuth 令牌,要联系的受信任签发者的 HTTPS URL。所有 OAuth 连接都必须设置此参数;它应当与服务器 HBA 配置中的issuer设置完全一致。 - - - 作为标准认证握手的一部分,libpq会向服务器请求一个发现文档,也就是一个提供一组 OAuth 配置参数的 URL。服务器必须提供一个可由oauth_issuer的各组成部分直接构造出来的 URL,并且该值必须与发现文档自身声明的签发者标识符完全一致,否则连接会失败。这是为了防止 OAuth 客户端遭受一类 - “混淆攻击(mix-up attacks)”。 - - - 你也可以显式把oauth_issuer设置为 OAuth 发现所使用的/.well-known/ URI。在这种情况下,如果服务器要求使用不同的 URL,连接就会失败;不过,自定义 OAuth 流程也许能够通过使用先前缓存的令牌来加速标准握手。(此时也建议设置,因为客户端将没有机会向服务器询问正确的 scope 设置,而令牌的默认 scope 可能不足以完成连接。)libpq当前支持以下 well-known 端点: - - /.well-known/openid-configuration - /.well-known/oauth-authorization-server - - - - - 在 OAuth 连接握手期间,签发者拥有极高的权限。经验法则是:如果你不会信任某个 URL 的运营者来处理你对服务器的访问,或者不会信任其直接冒充你,那么这个 URL 就不应被信任为oauth_issuer。 - - - - - - oauth_client_id - - - 由授权服务器发放的 OAuth 2.0 客户端标识符。如果PostgreSQL服务器为该连接请求 OAuth 令牌,并且没有安装自定义 OAuth 钩子来提供该令牌,那么就必须设置此参数;否则连接会失败。 - - - - - oauth_client_secret - - - 与 OAuth 授权服务器通信时要使用的客户端密码(如果有)。该参数是否必需由 OAuth 提供者决定;“public” 客户端通常不使用 secret,而 “confidential” 客户端通常会使用。 - - - - - oauth_scope - - - 发送给授权服务器的访问请求 scope,以 OAuth scope 标识符的空格分隔列表指定(该列表可以为空)。该参数是可选的,面向高级用法。 - - - 通常客户端会从PostgreSQL服务器获得合适的 scope 设置。如果使用这个参数,服务器请求的 scope 列表会被忽略。这可以防止不那么受信任的服务器向最终用户请求不恰当的访问 scope。不过,如果客户端的 scope 设置不包含服务器所要求的 scope,服务器很可能会拒绝已经签发的令牌,连接也会失败。 - - - 空 scope 列表的含义取决于提供者。OAuth 授权服务器可以选择签发带有“默认 scope”的令牌,不管那具体是什么;也可以完全拒绝该令牌请求。 - - - + + + + + @@ -1955,7 +1646,7 @@ char *PQpass(const PGconn *conn); 将返回连接参数中指定的密码,如果连接参数中没有密码并且能从密码文件中得到密码,则它将返回得到的密码。 - 在后一种情况中,如果连接参数中指定了多个主机,在连接被建立之前都不能依赖的结果。连接的状态可以用函数检查。 + 在后一种情况中,如果连接参数中指定了多个主机,在连接被建立之前都不能依赖的结果。连接的状态可以用函数检查。 @@ -2109,46 +1800,28 @@ PGTransactionStatusType PQtransactionStatus(const PGconn *conn); - 查找服务器的一个当前参数设置。 + 查找服务器某个参数的当前设置。 const char *PQparameterStatus(const PGconn *conn, const char *paramName); - 某一参数值会被服务器在连接开始或值改变时自动报告。可以被用来询问这些设置。它为已知的参数返回当前值,为未知的参数返回NULL。 + 服务器会在连接启动时,以及某些参数值发生变化时,自动报告这些参数值。可用于查询这些设置。如果已知该参数,则返回其当前值;如果未知,则返回NULL - 自当前发布开始会被报告的参数包括 - server_version、 - server_encoding、 - client_encoding、 - application_name、 - default_transaction_read_only, - in_hot_standby, - is_superuser、 - session_authorization、 - DateStyle、 - IntervalStyle、 - TimeZone、 - integer_datetimes以及 - standard_conforming_strings。 - (server_encodingTimeZone以及integer_datetimes在 8.0 以前的发布中不被报告; - standard_conforming_strings在 8.1 以前的发布中不被报告; - IntervalStyle在 8.4 以前的发布中不被报告; - application_name在 9.0 以前的发布中不被报告; - default_transaction_read_onlyin_hot_standby 在14以前的发布中不被报告) - 注意 server_version、 - server_encoding以及 - integer_datetimes在启动之后无法改变。 + 当前版本报告的参数包括: + server_versionserver_encodingclient_encodingapplication_namedefault_transaction_read_onlyin_hot_standbyis_superusersession_authorizationDateStyleIntervalStyleTimeZoneinteger_datetimesstandard_conforming_strings。 + (8.0 之前的版本不报告 server_encodingTimeZoneinteger_datetimes;8.1 之前的版本不报告 standard_conforming_strings;8.4 之前的版本不报告 IntervalStyle;9.0 之前的版本不报告 application_name;14 之前的版本不报告 default_transaction_read_onlyin_hot_standby。) + 注意,server_versionserver_encodinginteger_datetimes 在启动后不能改变。 - 如果没有为standard_conforming_strings报告值,应用能假设它是off,也就是说反斜线会被视为字符串中的转义。还有,这个参数的存在可以被作为转义字符串语法(E'...')被接受的指示。 + 如果服务器未报告standard_conforming_strings的值,应用程序可以假定其为off,即反斜杠在字符串字面量中被视为转义字符。此外,服务器报告此参数也表明它接受转义字符串语法(E'...')。 - 尽管被返回的指针被声明成const,它事实上指向与PGconn结构体相关的可变存储。假定该指针在存储之间保持有效是不明智的。 + 返回的指针虽然被声明为const,但实际上指向与PGconn结构体关联的可变存储。不能假定该指针在执行其他查询后仍然有效。 @@ -2569,7 +2242,7 @@ PGresult *PQexecParams(PGconn *conn, paramTypes[] - 通过 OID 指定要赋予给参数符号的数据类型。如果paramTypesNULL或者该数组中任何特定元素为零,服务器会用对待未知类型文字串的方式为参数符号推测一种数据类型。 + 通过 OID 指定要赋予给参数符号的数据类型。如果paramTypesNULL或者该数组中任何特定元素为零,服务器会用对待未指定类型的字符串字面量的方式为参数符号推测一种数据类型。 @@ -2663,10 +2336,10 @@ PGresult *PQprepare(PGconn *conn, 该函数从query串创建一个名为stmtName的预备语句,该串必须包含一个单一 SQL 命令。 stmtName可以是""来创建一个未命名语句,在这种情况下任何已存在未命名语句将被自动替换。 - 如果语句名称已经在当前会话中被定义,则是一种错误。如果使用了任何参数,它们在查询中以$1$2等引用。 + 否则,如果语句名称已经在当前会话中被定义,则是一种错误。如果使用了任何参数,它们在查询中以$1$2等引用。 nParams是参数的个数,其类型在数组paramTypes[]中被预先指定(当nParams为零时,该数组指针可以是NULL)。 paramTypes[]通过 OID 指定要赋予给参数符号的数据类型。 - 如果paramTypesNULL或者该数组中任何特定元素为零,服务器会用对待未知类型文字串的方式为参数符号推测一种数据类型。 + 如果paramTypesNULL或者该数组中任何特定元素为零,服务器会用对待未指定类型的字符串字面量的方式为参数符号推测一种数据类型。 还有,查询能够使用编号高于nParams的参数符号,它们的数据类型也会被自动推测(找出推测出的数据类型的方法见)。 @@ -2774,47 +2447,9 @@ PGresult *PQdescribePortal(PGconn *conn, const char *portalName); - - PQclosePreparedPQclosePrepared - - - - 提交一个请求以关闭指定的预备语句,并等待完成。 - -PGresult *PQclosePrepared(PGconn *conn, const char *stmtName); - - - - - 允许应用程序关闭先前准备好的预备语句。关闭语句会释放它在服务器上的全部相关资源,并允许重复使用其名称。 - - - - stmtName可以是""NULL来引用未命名语句。如果不存在该名称的语句也没有关系;在这种情况下,该操作不会执行任何操作。成功时,会返回一个状态为PGRES_COMMAND_OKPGresult。 - - - - - - PQclosePortalPQclosePortal - - - 提交一个请求以关闭指定的 portal,并等待完成。 - -PGresult *PQclosePortal(PGconn *conn, const char *portalName); - - - - 允许应用程序关闭先前创建的 portal。关闭 portal 会释放它在服务器上的全部相关资源,并允许重复使用其名称。(libpq不直接提供对 portal 的访问,但你可以使用这个函数来关闭通过DECLARE CURSOR SQL 命令创建的游标。) - - - portalName可以是""NULL来引用未命名的 portal。如果不存在该名称的 portal 也没有关系;在这种情况下,该操作不会执行任何操作。成功时,会返回一个状态为PGRES_COMMAND_OKPGresult。 - - -
@@ -3076,7 +2711,7 @@ char *PQresultErrorField(const PGresult *res, int fieldcode); PG_DIAG_MESSAGE_DETAIL - 细节:一个可选的次级错误消息,它携带了关于问题的等多细节。可能有多行。 + 细节:一个可选的次级错误消息,它携带了关于问题的更多细节。可能有多行。 @@ -3094,7 +2729,7 @@ char *PQresultErrorField(const PGresult *res, int fieldcode); PG_DIAG_STATEMENT_POSITION - 包含一个十进制整数的字符串,它表示一个错误游标位置,该位置是原始语句字符串的索引。第一个字符的索引是 1,位置以字符计算而不是以及字节计算。 + 包含一个十进制整数的字符串,它表示一个错误游标位置,该位置是原始语句字符串的索引。第一个字符的索引是 1,位置以字符计算而不是以字节计算。 @@ -3888,8 +3523,8 @@ unsigned char *PQescapeByteaConn(PGconn *conn, - 当某些字节值被用作一个SQL语句中的bytea文字的一部分时,它们必须被转义。 - 转义使用十六进制编码或反斜线转义的字节。详见。 + 当某些字节值被用作一个SQL语句中的bytea字面量的一部分时,它们必须被转义。 + 使用十六进制编码或反斜杠转义来转义这些字节。详见 @@ -3939,7 +3574,8 @@ unsigned char *PQescapeBytea(const unsigned char *from, - 将二进制数据的一个字符串表示转换成二进制数据 — 它是的逆向函数。当检索文本格式的bytea数据时,需要这个函数,但检索二进制个事时则不需要它。 + 将二进制数据的字符串表示转换为二进制数据,这是的逆操作。 + 以文本格式取得bytea数据时需要此操作;以二进制格式取得时则不需要。 unsigned char *PQunescapeBytea(const unsigned char *from, size_t *to_length); @@ -3947,14 +3583,15 @@ unsigned char *PQunescapeBytea(const unsigned char *from, size_t *to_length); - from参数指向一个字符串,例如被应用到一个bytea列上所返回的。 - 把这个串表示转换成它的二进制表示。 - 它返回一个指向用malloc()分配的缓冲区的指针,在错误时返回NULL,并且把缓冲区的尺寸放在to_length中。 - 当结果不再需要时,它必须使用释放。 + from参数指向一个字符串,例如对bytea列调用时返回的字符串。 + 将这个字符串表示转换为二进制表示。 + 它返回指向通过malloc()分配的缓冲区的指针,出错时返回NULL,并将缓冲区大小存入to_length。 + 不再需要结果时,必须使用释放它。 - 这种转换并不完全是PQescapeBytea的逆函数,因为当从PQgetvalue接收到字符串时,我们并不能期待它被转义。特别地这意味着不需要考虑字符串引用,并且因此也不需要一个参数。 + 此转换并不完全是的逆操作,因为从收到的字符串并非经过转义的形式。 + 具体而言,这意味着无需考虑字符串引号,因此也不需要PGconn参数。 @@ -4003,26 +3640,13 @@ unsigned char *PQunescapeBytea(const unsigned char *from, size_t *to_length); - - 不喜欢这些限制的应用程序可以使用构建自的底层函数: - 。 - 还有 - , - , - , - , - , - 以及 - , - 它们可以与配合使用,分别复制 - , - , - , - , - , - 和 - - 的功能。 + 如果应用程序不希望受到这些限制,可以改用构成的底层函数:。此外,还有, + , + , + ,以及,它们可以与配合使用,分别实现以下函数的功能:, + , + , + ,以及 @@ -4160,35 +3784,9 @@ int PQsendDescribePortal(PGconn *conn, const char *portalName); - - PQsendClosePreparedPQsendClosePrepared - - - - 提交一个关闭指定预备语句的请求,而不等待完成。 - -int PQsendClosePrepared(PGconn *conn, const char *stmtName); - - - 这是的异步版本:如果成功分派请求则返回 1,否则返回 0。调用成功后,使用获取结果。其参数处理方式与相同。 - - - - - PQsendClosePortalPQsendClosePortal - - - 提交一个关闭指定 portal 的请求,而不等待完成。 - -int PQsendClosePortal(PGconn *conn, const char *portalName); - - 这是的异步版本:如果成功分派请求则返回 1,否则返回 0。调用成功后,使用获取结果。其参数处理方式与相同。 - - - @@ -4473,68 +4071,46 @@ int PQflush(PGconn *conn); - 发出查询 - 进入管道模式后,应用程序使用或其姊妹函数来分派请求。 - 这些请求在客户端排队,直到刷新到服务器端;当使用建立管道中的同步点时,或者调用时,会发生这种情况。 - 函数在管道模式下也可以工作。 - 结果处理如下所述。 + 进入管道模式后,应用程序使用 、&zwsp; 或其处理预备查询的对应函数 发送请求。这些请求在客户端排队,直到发送到服务器;使用 在管道中建立同步点,或调用 时会发送它们。函数 、&zwsp; 也可用于管道模式。结果处理方式见下文。 - 服务器执行语句,并返回结果,按客户端发送它们的顺序。 - 服务器将立即开始执行管道中的命令,不等待管道的结束。 - 注意,结果被缓冲在服务器端;当使用PQpipelineSync建立同步点时,或者调用了PQsendFlushRequest时,服务器会刷新该缓冲区。 - 如果任何语句遇到错误,服务器将中止当前事务,并且不执行队列中的任何后续命令,直到下一个同步点;对于每一个这样的命令,都会产生一个PGRES_PIPELINE_ABORTED结果。 - (即使管道中的命令将回滚事务,依然如此。) - 查询处理在同步点之后恢复。 + 服务器按客户端发送的顺序执行语句并返回结果。服务器会立即开始执行管道中的命令,无需等待管道结束。结果会缓存在服务器端;使用 PQpipelineSync 建立同步点,或调用 PQsendFlushRequest 时,服务器会发送该缓冲区中的数据。如果任何语句发生错误,服务器会中止当前事务,并停止执行队列中的后续命令,直到下一个同步点;每条被跳过的命令都会产生一个 PGRES_PIPELINE_ABORTED 结果。(即使管道中的命令会回滚事务,也仍然如此。)到达同步点后,查询处理恢复。 - 一个操作依赖于前一个操作的结果并没有问题; - 例如,一个查询可以定义一个同一管道中的下一个查询将用到的表。 - 类似地,应用可以创建一个命名的预备语句,并在同一管道中与后续语句一起执行它。 + 一个操作可以依赖先前操作的结果;例如,一个查询可以定义一张表,供同一管道中的下一个查询使用。类似地,应用程序可以创建命名的预备语句,并通过同一管道中后续的语句执行它。 - 处理结果 - 为了在管道中处理一个查询的结果,应用重复调用PQgetResult并处理每个结果,直到PQgetResult返回空。 - 可以再次使用PQgetResult检索管道中下一个查询的结果,并且循环重复 - 应用像通常一样处理单个语句结果。 - 当管道中所有查询的结果都返回时,PQgetResult返回一个结果,其包含状态值PGRES_PIPELINE_SYNC。 + 要处理管道中一个查询的结果,应用程序应重复调用 PQgetResult 并处理每个结果,直到 PQgetResult 返回空指针。然后再次调用 PQgetResult 获取管道中下一个查询的结果,重复这一过程。应用程序按通常方式处理各条语句的结果。当管道中所有查询的结果都已返回时,PQgetResult 会返回一个包含状态值 PGRES_PIPELINE_SYNC 的结果。 - 客户端可以选择延迟结果处理,直到完整的管道被发送,或者与管道中发送的更多查询交错在一起;参见。 + 客户端可以等到整条管道发送完毕后再处理结果,也可以在继续发送管道中的查询时交错处理结果;参见 - 要进入单行模式,在使用PQgetResult检索结果之前调用PQsetSingleRowMode。 - 此模式选择仅对当前处理的查询有效。 - 有关使用PQsetSingleRowMode的更多信息,请参阅。 + 要进入单行模式,应在使用 PQgetResult 获取结果之前调用 PQsetSingleRowMode。该模式选择仅对当前正在处理的查询有效。关于 PQsetSingleRowMode 的更多信息,参见 - PQgetResult行为与普通异步处理相同,除了它可能包含新的PGresult类型PGRES_PIPELINE_SYNCPGRES_PIPELINE_ABORTED。 - 对于每个在管道中相应的点的PQpipelineSyncPGRES_PIPELINE_SYNC确定报告一次。 - PGRES_PIPELINE_ABORTED在第一个错误和所有后续结果的正常查询结果中发出,直到下一个PGRES_PIPELINE_SYNC;参见。 + PQgetResult 的行为与普通异步处理相同,只是返回结果可能具有新的 PGresult 类型 PGRES_PIPELINE_SYNCPGRES_PIPELINE_ABORTED。对于每次 PQpipelineSync 调用,都会在管道中的对应位置恰好报告一次 PGRES_PIPELINE_SYNC。对于第一个错误及其后的所有结果,会用 PGRES_PIPELINE_ABORTED 代替正常查询结果,直到下一个 PGRES_PIPELINE_SYNC;参见 - PQisBusyPQconsumeInput、等正常操作,在处理管道结果时。 - 特别是,在管道中间调用PQisBusy 时,如果到目前为止发出的所有查询的结果都已被消耗,则返回0。 + PQisBusyPQconsumeInput 等函数在处理管道结果时照常工作。特别地,在管道处理过程中调用 PQisBusy 时,如果到目前为止已发出查询的所有结果均已被消费,则返回 0。 - libpq不向应用提供有关当前正在处理的查询的任何信息(除了PQgetResult返回空,以表示我们开始返回下一个查询的结果)。 - 应用必须保持跟踪它发送查询的顺序,以将它们与相应的结果相关联。 - 应用通常会为此使用状态机或FIFO队列。 + libpq 不向应用程序提供当前正在处理哪个查询的信息(除了 PQgetResult 返回空指针,表示开始返回下一个查询的结果)。应用程序必须跟踪查询的发送顺序,以便将查询与对应结果关联起来。应用程序通常会使用状态机或 FIFO 队列实现这一点。 @@ -4612,7 +4188,7 @@ PGpipelineStatus PQpipelineStatus(const PGconn *conn); - PQpipelineStatus 可以返回下列值中的一个: + PQpipelineStatus 可以返回下列值中的一个: @@ -4720,22 +4296,7 @@ int PQpipelineSync(PGconn *conn); - - PQsendPipelineSyncPQsendPipelineSync - - - - 通过发送sync message但不刷新发送缓冲区,来标记管道中的一个同步点。它可作为隐式事务的分界符和错误恢复点;参见。 - -int PQsendPipelineSync(PGconn *conn); - - - - 成功时返回 1。如果连接不处于管道模式,或者发送sync message失败,则返回 0。请注意,该消息本身不会自动刷新到服务器;必要时请使用PQflush。 - - - @@ -4797,7 +4358,7 @@ SELECT x FROM mytable WHERE id = 42 FOR UPDATE; UPDATE mytable SET x = 3 WHERE id = 42; COMMIT; - 可以更有效地开展以下工作: + 可以更有效地开展以下工作: UPDATE mytable SET x = x + 1 WHERE id = 42; @@ -4810,29 +4371,18 @@ UPDATE mytable SET x = x + 1 WHERE id = 42; - 分块检索查询结果 - - - libpq - single-row mode - + 逐行检索查询结果 libpq - chunked mode + 单行模式 - - 通常,libpq会收集一条 SQL 命令的完整结果,并将其作为单个PGresult返回给应用程序。对于返回大量行的命令,这可能并不适用。对于这类情况,应用程序可以将用于单行模式分块模式。在这些模式下,结果行会在从服务器收到时立即返回给应用程序;单行模式每次返回一行,分块模式则每次返回一组行。 - + 通常,libpq 会收集一条 SQL 命令的完整结果,并将其作为单个 PGresult 返回给应用程序。对于返回大量行的命令,这种方式可能不可行。在这种情况下,应用程序可以在单行模式下使用 。此模式在从服务器收到结果行时,每次将一行返回给应用程序。 - - 要进入这些模式之一,请在成功调用(或其兄弟函数)后立即调用。这种模式选择只对当前正在执行的查询生效。然后按所述,反复调用直到其返回空指针。如果查询返回了任何行,这些行会作为一个或多个PGresult对象返回。它们看起来与普通查询结果相同,只是状态码在单行模式下为PGRES_SINGLE_TUPLE,在分块模式下为PGRES_TUPLES_CHUNK,而不是PGRES_TUPLES_OK。每个PGRES_SINGLE_TUPLE对象恰好包含一行结果,而PGRES_TUPLES_CHUNK对象至少包含一行、至多包含指定的每块行数。最后一行之后,或者如果查询返回零行,则会返回一个状态为PGRES_TUPLES_OK且不含行的对象,表示不会再有更多行到达。(但请注意,仍然必须继续调用直到其返回空指针。)所有这些PGresult对象都会包含与普通查询结果相同的行描述数据(列名、类型等)。每个对象在使用完之后都应像往常一样通过释放。 - + 要进入单行模式,请在成功调用 (或其同类函数)后,立即调用 。此模式选择仅对当前正在执行的查询生效。然后按照 所述,反复调用 ,直到返回空指针。如果查询返回了行,每一行都作为独立的 PGresult 对象返回。这些对象看起来与普通查询结果相同,只是状态码为 PGRES_SINGLE_TUPLE,而不是 PGRES_TUPLES_OK。最后一行之后,或者查询返回零行时立即返回一个不含行、状态为 PGRES_TUPLES_OK 的对象,表示不会再有更多行到达。(但注意,仍然必须继续调用 ,直到返回空指针。)所有这些 PGresult 对象都包含与该查询普通 PGresult 对象相同的行描述数据(列名、类型等)。每个对象都应像往常一样使用 释放。 - - 在使用管道模式时,必须在用PQgetResult提取该查询结果之前,为管道中的每个查询分别激活单行模式或分块模式。更多信息见。 - + 在使用管道模式时,必须在用 PQgetResult 获取某个查询的结果之前,为管道中的该查询激活单行模式。更多信息见 @@ -4853,32 +4403,12 @@ int PQsetSingleRowMode(PGconn *conn); + + - - PQsetChunkedRowsModePQsetChunkedRowsMode - - - - 为当前正在执行的查询选择分块模式。 - - -int PQsetChunkedRowsMode(PGconn *conn, int chunkSize); - - - - - 该函数与类似,不同之处在于它指定每个PGresult最多返回chunkSize行,而不一定只返回一行。此函数也只能在调用或其某个兄弟函数之后立即调用,并且必须在该连接上执行任何其他操作之前调用,例如。如果调用时机正确,该函数会为当前查询激活分块模式并返回 1;否则模式保持不变并返回 0。无论如何,当前查询结束后都会恢复为普通模式。 - - - - - - - - - 在处理一个查询的过程中,服务器可能先返回一些行,然后遇到错误并中止该查询。通常,libpq会丢弃这些行,只报告错误。但在单行模式或分块模式下,部分行可能已经返回给应用程序。因此,应用程序可能会先看到一些PGRES_SINGLE_TUPLEPGRES_TUPLES_CHUNKPGresult对象,然后再看到一个PGRES_FATAL_ERROR对象。为了获得正确的事务语义,如果查询最终失败,应用程序必须能丢弃或撤销之前对这些已处理行所做的操作。 - - + + 处理查询时,服务器可能先返回一些行,然后遇到错误,导致查询中止。通常,libpq 会丢弃这些行,只报告错误。但在单行模式下,这些行已经返回给了应用程序。因此,应用程序会先看到一些 PGRES_SINGLE_TUPLE PGresult 对象,随后看到一个 PGRES_FATAL_ERROR 对象。为了保证正确的事务行为,如果查询最终失败,应用程序必须能够丢弃或撤销此前对这些行所做的全部操作。 + @@ -4886,287 +4416,16 @@ int PQsetChunkedRowsMode(PGconn *conn, int chunkSize); 取消进行中的查询 - canceling SQL queries + 取消 + SQL 命令 - - query cancellation - - - - 发送取消请求的函数 - - - PQcancelCreatePQcancelCreate - - - 准备用于发送取消请求的连接。 - -PGcancelConn *PQcancelCreate(PGconn *conn); - - - - - 创建一个PGcancelConnPGcancelConn对象,但不会立即通过这条连接发送取消请求。可以使用以阻塞方式发送取消请求,或者使用以非阻塞方式发送。返回值可以传给,以检查该PGcancelConn对象是否成功创建。PGcancelConn是不透明结构,不应由应用程序直接访问。它可用于以线程安全的方式取消原始连接上正在执行的查询。 - - - - 在为取消请求建立连接时,会重用原始客户端连接的许多连接参数。特别是,如果原始连接要求对连接进行加密和/或验证目标主机(通过sslmodegssencmode),则取消请求连接也会使用同样的要求。不过,仅在客户端认证期间或认证后才会用到的连接选项会被忽略,因为取消请求不需要认证,并且提交取消请求后该连接就会立即关闭。 - - - - 请注意,当PQcancelCreate返回非空指针时,你必须在使用完毕后调用,以释放该结构及其关联内存块。即使取消请求失败或被放弃,也必须这样做。 - - - - - - PQcancelBlockingPQcancelBlocking - - - - 以阻塞方式请求服务器放弃处理当前命令。 - -int PQcancelBlocking(PGcancelConn *cancelConn); - - - - - 请求通过给定的PGcancelConn发送,该对象必须由创建。成功分派取消请求时返回 1,否则返回 0。若失败,可通过获取错误信息。 - - - - 取消请求成功分派并不保证一定会产生效果。如果取消成功,被取消的命令会提前终止并返回一个错误结果;如果取消失败(例如服务器已经处理完该命令),则不会有任何可见结果。 - - - - - - PQcancelStartPQcancelStart - PQcancelPollPQcancelPoll - - - - 以非阻塞方式请求服务器放弃处理当前命令。 - -int PQcancelStart(PGcancelConn *cancelConn); - -PostgresPollingStatusType PQcancelPoll(PGcancelConn *cancelConn); - - - - - 请求通过给定的PGcancelConn发送,该对象必须由创建。能够启动取消请求时返回 1,否则返回 0。若失败,可通过获取错误信息。 - - - - 如果PQcancelStart成功,下一阶段就是轮询libpq,使其继续推进取消连接序列。使用获取底层套接字描述符。(注意:不要假定该套接字在多次调用PQcancelPoll之间保持不变。)循环规则如下:如果PQcancelPoll(cancelConn)上一次返回PGRES_POLLING_READING,就等待该套接字准备好可读(由select()poll()或类似系统函数指示),然后再次调用PQcancelPoll(cancelConn)。反之,如果其上一次返回PGRES_POLLING_WRITING,就等待套接字准备好可写,然后再次调用。第一次迭代时,也就是尚未调用过PQcancelPoll(cancelConn)时,按其上次返回PGRES_POLLING_WRITING来处理。持续这一循环,直到PQcancelPoll(cancelConn)返回PGRES_POLLING_FAILED,表示连接过程失败,或者返回PGRES_POLLING_OK,表示取消请求已成功分派。 - - - - 取消请求成功分派并不保证一定会产生效果。如果取消成功,被取消的命令会提前终止并返回一个错误结果;如果取消失败(例如服务器已经处理完该命令),则不会有任何可见结果。 - - - - 在连接期间的任意时刻,都可以通过调用检查取消连接的状态。如果返回CONNECTION_BAD,则取消过程失败;如果返回CONNECTION_OK,则取消请求已成功分派。这两种状态同样可以从前面描述的PQcancelPoll返回值中检测到。其他状态也可能仅在异步取消过程中出现,它们表示连接过程的当前阶段,并可能有助于向用户提供反馈。这些状态如下: - - - - CONNECTION_ALLOCATED - - - 等待调用以真正打开套接字。这是刚调用之后的连接状态。此时尚未开始与服务器建立连接。要真正开始发送取消请求,请使用。 - - - - - - CONNECTION_STARTED - - - 等待连接建立。 - - - - - - CONNECTION_MADE - - - 连接正常,等待发送。 - - - - - - CONNECTION_AWAITING_RESPONSE - - - 等待服务器响应。 - - - - - - CONNECTION_SSL_STARTUP - - - 协商 SSL 加密。 - - - - - - CONNECTION_GSS_STARTUP - - - 协商 GSS 加密。 - - - - - - 请注意,尽管这些常量会继续保留(为了保持兼容性),应用程序也绝不应依赖它们按某个特定顺序出现,甚至不应依赖它们一定会出现,或者依赖状态值始终属于这些已记录的取值之一。应用程序可以这样写: - -switch(PQcancelStatus(conn)) -{ - case CONNECTION_STARTED: - feedback = "Connecting..."; - break; - - case CONNECTION_MADE: - feedback = "Connected to server..."; - break; -. -. -. - default: - feedback = "Connecting..."; -} - - - - - 在使用PQcancelPoll时,连接参数connect_timeout会被忽略;是否已经过去过长时间应由应用程序自行判断。除此之外,PQcancelStart后接PQcancelPoll循环,等效于。 - - - - - - PQcancelStatusPQcancelStatus - - - - 返回取消连接的状态。 - -ConnStatusType PQcancelStatus(const PGcancelConn *cancelConn); - - - - - 该状态可以是多种取值之一。不过,在异步取消过程之外只能看到三种:CONNECTION_ALLOCATEDCONNECTION_OKCONNECTION_BAD。使用成功创建的PGcancelConn初始状态为CONNECTION_ALLOCATED。成功分派取消请求后状态为CONNECTION_OK;取消失败则表现为CONNECTION_BAD。处于 OK 状态时,会一直保持到调用。 - - - - 其他可能返回的状态代码,请参见条目。 - - - - 取消请求成功分派并不保证一定会产生效果。如果取消成功,被取消的命令会提前终止并返回一个错误结果;如果取消失败(例如服务器已经处理完该命令),则不会有任何可见结果。 - - - - - - PQcancelSocketPQcancelSocket - - - - 获取到服务器的取消连接套接字的文件描述符编号。 - -int PQcancelSocket(const PGcancelConn *cancelConn); - - - - - 有效描述符将大于等于 0;结果为 -1 表示当前没有打开到服务器的连接。对该PGcancelConn调用本节中的任意函数(PQcancelSocket自身除外)都可能改变这一状态。 - - - - - - - PQcancelErrorMessagePQcancelErrorMessage - error messagein PGcancelConn - - - - - 返回最近一次针对取消连接执行操作时生成的错误消息。 - -char *PQcancelErrorMessage(const PGcancelConn *cancelconn); - - - - - 几乎所有接受PGcancelConn参数的libpq函数在失败时都会为设置消息。按照libpq的约定,非空的结果可能包含多行,并带有结尾换行符。调用者不应直接释放该结果;当关联的PGcancelConn句柄传给时,它会被释放。也不应假定该结果字符串在多次对PGcancelConn结构执行操作之间保持不变。 - - - - - - PQcancelFinishPQcancelFinish - - - 关闭取消连接(如果它尚未完成发送取消请求),同时释放PGcancelConn对象使用的内存。 - -void PQcancelFinish(PGcancelConn *cancelConn); - - - - - 请注意,即使取消尝试失败(由指示),应用程序也应调用来释放PGcancelConn对象使用的内存。在调用后,不得再次使用该PGcancelConn指针。 - - - - - - PQcancelResetPQcancelReset - - - 重置PGcancelConn,以便将其重新用于新的取消连接。 - -void PQcancelReset(PGcancelConn *cancelConn); - - - - - 如果PGcancelConn当前正用于发送取消请求,则会关闭该连接。随后它会将PGcancelConn对象重新准备好,使其能够用于发送新的取消请求。 - - - - 这使得可以为一个PGconn创建一个PGcancelConn,并在原始PGconn的整个生命周期中重复使用它。 - - - - - - - - 发送取消请求的过时函数 - - - 这些函数代表较旧的取消请求发送方式。虽然它们仍然可以工作,但由于即使原始连接通过sslmodegssencmode要求加密,它们发送取消请求时也不会以加密方式进行,因此已被废弃。因此,强烈不建议在新代码中继续使用这些旧方法,已有代码也建议迁移到新的函数。 - - - + 客户端应用程序可以使用本节介绍的函数,请求取消服务器仍在处理的命令。 PQgetCancelPQgetCancel - - 创建一个数据结构,其中包含使用取消命令所需的信息。 - + 创建一个数据结构,其中包含取消通过特定数据库连接发出的命令所需的信息。 PGcancel *PQgetCancel(PGconn *conn); @@ -5238,7 +4497,7 @@ int PQrequestCancel(PGconn *conn); - + @@ -5296,7 +4555,7 @@ typedef struct - 要传递NULL参数到函数,将参数结构体的len字段设置为-1;isintu 字段就不相关了。 + 要传递NULL参数到函数,将参数结构体的len字段设置为-1isintu 字段就不相关了。 @@ -5553,7 +4812,7 @@ int PQgetCopyData(PGconn *conn, 当async为真时(非零),将不会阻塞等待输入; 如果COPY仍在处理过程中并且没有可用的完整行,那么它将返回零 (在这种情况下等待读准备好,然后在再次调用之前,调用)。 - 当async为假(零)时,PQgetCopyData将阻塞,直到数据可用或者操作完成。 + 当async为假(零)时,将阻塞,直到数据可用或者操作完成。 @@ -5994,27 +5253,7 @@ char *PQencryptPasswordConn(PGconn *conn, const char *passwd, const char *user, - - PQchangePasswordPQchangePassword - - - 修改一个PostgreSQL密码。 - -PGresult *PQchangePassword(PGconn *conn, const char *user, const char *passwd); - - 此函数使用PQencryptPasswordConn构造并执行ALTER USER ... PASSWORD '...'命令,从而更改该用户的密码。它存在的原因与PQencryptPasswordConn相同,但更方便,因为它会替你同时构造并执行命令。传给的算法参数是NULL,因此会按照服务器的设置进行加密。 - - - - userpasswd参数分别是目标用户的 SQL 名称以及新的明文密码。 - - - - 返回一个表示ALTER USER命令结果的PGresult指针;如果例程在发出任何命令前就失败,则返回空指针。应调用检查返回值中是否有错误(包括空指针的情况,此时它会返回PGRES_FATAL_ERROR)。可使用获取更多错误信息。 - - - @@ -6027,7 +5266,7 @@ PGresult *PQchangePassword(PGconn *conn, const char *user, const char *passwd); char *PQencryptPassword(const char *passwd, const char *user); - 的一个较老的已经被废弃的版本。其差别是不要求一个连接对象,并且总是用md5作为加密算法。 + 的旧版本,现已弃用。其差别是不需要连接对象,并且总是用md5作为加密算法。 @@ -6047,11 +5286,12 @@ PGresult *PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status); 这是libpq内部用于分配并初始化一个空PGresult对象的函数。 - 如果不能分配内存,那么这个函数返回NULL。 - 它也是可以对外使用的,因为一些应用认为它可以用于产生结果对象(特别是带有错误状态的对象)本身。 - 如果conn非空,并且status表示一个错误,那么指定连接的当前错误消息会被复制到PGresult中。 - 如果conn非空,那么连接中的任何已注册事件过程也会被复制到PGresult中(它们不会获得PGEVT_RESULTCREATE调用,但会看到)。 - 注意在该对象上最终应该调用,正如对libpq本身返回的PGresult对象所作的那样。 + 如果无法分配内存,此函数返回NULL。 + 将它导出供外部调用,是因为一些应用需要自行生成结果对象,特别是带有错误状态的对象。 + 如果conn非空,并且status表示错误,指定连接的当前错误消息会被复制到PGresult中。 + 此外,如果conn非空,连接中注册的所有事件过程也会被复制到PGresult中。 + (这些过程不会收到PGEVT_RESULTCREATE调用,但可参见。) + 注意,最终应对该对象调用,就像处理libpq自身返回的PGresult一样。 @@ -6411,8 +5651,8 @@ typedef struct - 结果创建事件是响应任何生成结果的查询执行函数而触发的,包括 - 。此事件只会在结果成功创建后触发。 + 任何生成结果的查询执行函数都会触发结果创建事件,其中包括。 + 只有成功创建结果后才会触发该事件。 typedef struct @@ -6422,14 +5662,12 @@ typedef struct } PGEventResultCreate; - 当接收到PGEVT_RESULTCREATE事件时, - 应将evtInfo指针转换为 - PGEventResultCreate *。 - conn是用于生成结果的连接。 - 这是初始化需要与结果关联的任何instanceData的理想位置。 - 如果事件过程失败(返回零),那么该事件过程将在结果的剩余生命周期内被忽略; - 也就是说,它将不会接收到针对此结果或从中复制的结果的 - PGEVT_RESULTCOPYPGEVT_RESULTDESTROY事件。 + 收到PGEVT_RESULTCREATE事件时,应将evtInfo指针转换为PGEventResultCreate *。 + 其中,conn是用于生成结果的连接。 + 这是初始化需要与结果关联的instanceData的理想位置。 + 如果事件过程失败,结果会被清除,失败也会向外传递。 + 事件过程不得自行调用来清除结果对象。 + 返回失败代码时,必须完成所有清理工作,因为不会发送PGEVT_RESULTDESTROY事件。 @@ -7195,20 +6433,15 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough) - 用户的主目录中的文件.pgpass可以包含密码, - 如果连接需要密码(且未指定其他密码)。在Microsoft Windows中, - 该文件的名称为%APPDATA%\postgresql\pgpass.conf - (其中%APPDATA%指用户配置文件中的应用数据子目录)。 - 或者,可以使用连接参数 - 或环境变量PGPASSFILE指定要使用的密码文件。 - + 用户主目录中的.pgpass文件可保存密码,供连接需要密码且尚未通过其他方式指定密码时使用。在 Microsoft Windows 上,文件名为%APPDATA%\postgresql\pgpass.conf(其中%APPDATA%指用户配置文件中的应用数据子目录)。也可以通过连接参数或环境变量PGPASSFILE指定要使用的密码文件。 + 这个文件应该包含下列格式的行: hostname:port:database:username:password - (你可以向该文件增加一个提醒:把上面的行复制到该文件并且在前面加上#)。前四个域的每一个都可以是文字值或者匹配任何东西的*。第一个匹配当前连接参数的行中的密码域将被使用(因此,在使用通配符时把更特殊的项放在前面)。如果一个条目需要包含:或者\,用\对该字符转义。如果指定了host连接参数,主机名字段会被匹配到host,否则如果指定了hostaddr参数则匹配到hostaddr,如果两者都没有给出,则会搜索主机名localhost。当连接是一个Unix域套接字连接并且host参数匹配libpq的默认套接字目录路径时,也会搜索主机名localhost。在一台备库上,值为replication的数据库字段匹配连接到主库的流复制连接。否则数据库字段的用途有限,因为用户对同一个集簇中的所有数据库都有相同的密码。 + (你可以向该文件增加一个提醒:把上面的行复制到该文件并且在前面加上#)。前四个字段的每一个都可以是字面值或者匹配任何东西的*。第一个匹配当前连接参数的行中的密码字段将被使用(因此,在使用通配符时把更特殊的项放在前面)。如果一个条目需要包含:或者\,用\对该字符转义。如果指定了host连接参数,主机名字段会被匹配到host,否则如果指定了hostaddr参数则匹配到hostaddr,如果两者都没有给出,则会搜索主机名localhost。当连接是一个Unix域套接字连接并且host参数匹配libpq的默认套接字目录路径时,也会搜索主机名localhost。在一台备库上,值为replication的数据库字段匹配连接到主库的流复制连接。否则数据库字段的用途有限,因为用户对同一个集簇中的所有数据库都有相同的密码。 @@ -7645,7 +6878,7 @@ ldap://ldap.acme.com/cn=dbserver,cn=hosts?pgconnectinfo?base?(objectclass=*) 构建时带有SSL支持,您应该调用告诉libpq libssl和/或libcrypto库已被您的应用程序初始化,以便 libpq不会再初始化这些库。 - 但是,当使用OpenSSL版本1.1.0或更高版本时,重复初始化不再成问题。 + 但是,当使用OpenSSL版本1.1.0或更高版本时,无需这样做,因为重复初始化不再成问题。 @@ -7669,7 +6902,7 @@ void PQinitOpenSSL(int do_ssl, int do_crypto); - 如果你的应用使用并且初始化OpenSSL或者它的底层libcrypto库,你必须在第一次打开数据库连接前以合适的非零参数调用这个函数。 + 如果你的应用使用并且初始化OpenSSL或者它的底层libcrypto库,你必须在第一次打开数据库连接前调用这个函数,并把相应参数设为零。 同时要确保在打开一个数据库连接前已经完成了初始化。 @@ -7702,240 +6935,17 @@ void PQinitSSL(int do_ssl); - - OAuth 支持 - - - libpq通过一个可选模块实现了对 OAuth v2 Device Authorization 客户端流程的支持,该流程记录在 - RFC 8628中。关于如何启用内置的 Device Authorization 流程,请参见安装文档。 - - - 当启用支持并安装该可选模块后,如果服务器在认证期间请求 Bearer 令牌,libpq默认会使用内置流程。即使运行客户端应用的系统没有可用的 Web 浏览器,例如通过SSH运行客户端时,也可以使用这一流程。 - - - 内置流程默认会打印一个需要访问的 URL 以及一个要在该处输入的用户代码: - -$ psql 'dbname=postgres oauth_issuer=https://example.com oauth_client_id=...' -Visit https://example.com/device and enter the code: ABCD-EFGH - - (这一提示可以被定制。)然后,用户将在其 OAuth 提供者处登录,提供者会询问是否允许 libpq 和服务器代表其执行操作。在继续之前,始终应当仔细检查显示的 URL 和权限,确认它们符合预期。不要向不受信任的第三方授予权限。 - - - 客户端应用可以实现自己的流程,以定制交互方式以及与应用程序的集成。关于如何向libpq添加自定义流程的更多信息,请参见。 - - - 要使某个 OAuth 客户端流程可用,连接字符串至少必须包含。(这些设置由你所在组织的 OAuth 提供者决定。)此外,内置流程还要求 OAuth 授权服务器发布一个设备授权端点。 - - - - - 当前 Windows 上尚不支持内置的 Device Authorization 流程。不过,仍然可以实现自定义客户端流程。 - - - - - Authdata 钩子 - - - 客户端可以通过下面的钩子 API 修改或替换 OAuth 流程的行为: - - - - PQsetAuthDataHookPQsetAuthDataHook - - - - 设置PGauthDataHook,以覆盖libpq对其 OAuth 客户端流程一个或多个方面的处理。 - -void PQsetAuthDataHook(PQauthDataHook_type hook); - - 如果hookNULL,则会重新安装默认处理器。否则,应用程序需要传入一个回调函数指针,其签名如下: - -int hook_fn(PGauthData type, PGconn *conn, void *data); - - 当应用程序需要执行某个动作时,libpq会调用该回调。type描述所提出的请求,conn是正在认证的连接句柄,而data指向该请求特有的元数据。这个指针所指内容由type决定;支持的列表见。 - - - 钩子可以串联起来,以支持协作式和/或回退式行为。一般来说,钩子实现应检查传入的type(以及可能的请求元数据和/或当前conn的设置),以决定是否处理某一项 authdata。如果不处理,则应把请求委托给链中的前一个钩子(可通过PQgetAuthDataHook获取)。 - - - 返回一个大于零的整数表示成功。返回负整数表示发生错误并放弃此次连接尝试。(值零保留给默认实现。) - - - - - - PQgetAuthDataHookPQgetAuthDataHook - - - - 获取当前的PGauthDataHook值。 - -PQauthDataHook_type PQgetAuthDataHook(void); - - 在初始化阶段(即首次调用PQsetAuthDataHook之前),该函数会返回PQdefaultAuthDataHook。 - - - - - - - - 钩子类型 - - 下面定义了这些PGauthData类型及其对应的data结构: - - - - - PQAUTHDATA_PROMPT_OAUTH_DEVICE - PQAUTHDATA_PROMPT_OAUTH_DEVICE - - - - 在内置的设备授权客户端流程期间,替换默认的用户提示。data指向一个PGpromptOAuthDevice实例: - -typedef struct _PGpromptOAuthDevice -{ - const char *verification_uri; /* verification URI to visit */ - const char *user_code; /* user code to enter */ - const char *verification_uri_complete; /* optional combination of URI and - * code, or NULL */ - int expires_in; /* seconds until user code expires */ -} PGpromptOAuthDevice; - - - - 可被包含在libpq中的 OAuth Device Authorization 流程要求最终用户使用浏览器访问一个 URL,然后输入一个代码,以允许libpq代表其连接到服务器。默认提示只是把verification_uriuser_code打印到标准错误。替换实现可以按任意偏好的方式展示这些信息,例如使用 GUI。 - - - 该回调只会在内置设备授权流程中被调用。如果应用程序安装了自定义 OAuth 流程,或者libpq构建时未启用内置流程支持,则不会使用这种 authdata 类型。 - - - 如果提供了非空的verification_uri_complete,则可以选择把它用于非文本形式的验证(例如显示二维码)。在这种情况下,仍应向最终用户显示 URL 和用户代码,因为该代码需要由提供者手工确认,而 URL 也使得用户在无法使用非文本方式时仍可继续。更多信息见 - RFC 8628 第 3.3.1 节。 - - - - - - - PQAUTHDATA_OAUTH_BEARER_TOKEN - PQAUTHDATA_OAUTH_BEARER_TOKEN - - - - 添加一个自定义流程实现;如果内置流程已安装,则用它替换内置流程。该钩子应当要么直接返回一个适用于当前 user/issuer/scope 组合的 Bearer 令牌(如果能在不阻塞的情况下获得),要么设置一个异步回调来获取令牌。 - - - data指向一个PGoauthBearerRequest实例,应该由实现填充: - -typedef struct PGoauthBearerRequest -{ - /* Hook inputs (constant across all calls) */ - const char *openid_configuration; /* OIDC discovery URL */ - const char *scope; /* required scope(s), or NULL */ - - /* Hook outputs */ - - /* - * Callback implementing a custom asynchronous OAuth flow. The signature is - * platform-dependent: PQ_SOCKTYPE is SOCKET on Windows, and int everywhere - * else. - */ - PostgresPollingStatusType (*async) (PGconn *conn, - struct PGoauthBearerRequest *request, - PQ_SOCKTYPE *altsock); - - /* Callback to clean up custom allocations. */ - void (*cleanup) (PGconn *conn, struct PGoauthBearerRequest *request); - - char *token; /* acquired Bearer token */ - void *user; /* hook-defined allocated data */ -} PGoauthBearerRequest; - - - - libpq会向该钩子提供两项信息:openid_configuration包含描述授权服务器所支持流程的 OAuth 发现文档 URL,而scope包含访问服务器所需的 OAuth scope 列表(以空格分隔,可以为空)。两者中的任意一个或两个都可能为NULL,表示无法发现该信息。(在这种情况下,实现可以通过其他预先配置的知识来确定要求,或者选择失败。) - - - 该钩子的最终输出是token,它必须指向一个可在该连接上使用的有效 Bearer 令牌。(该令牌应由所指定的发行者签发,并持有所请求的 scope,否则连接会被服务器的验证器模块拒绝。)分配得到的令牌字符串必须在libpq完成连接之前始终有效;该钩子应设置cleanup回调,以便在libpq不再需要该令牌时调用。 - - - 如果某个实现无法在首次调用钩子时立即产生token,则应设置async回调,以处理与授权服务器之间的非阻塞通信。 - - - 在PQAUTHDATA_OAUTH_BEARER_TOKEN钩子回调中执行阻塞操作,会干扰诸如PQconnectPoll之类的非阻塞连接 API,并阻止并发连接继续推进。那些只使用同步连接原语(例如PQconnectdb)的应用程序,可以在钩子中同步获取令牌,而不是实现async回调,但这样它们必然一次只能处理一个连接。 - - - 从钩子返回后,将立即调用该回调以启动流程。当回调在不阻塞的情况下无法继续推进时,它应在设置*altsock后返回PGRES_POLLING_READINGPGRES_POLLING_WRITING,其中*altsock是当可以再次取得进展时会被标记为可读/可写的文件描述符。(然后,这个描述符会通过PQsocket()提供给顶层轮询循环。)当流程完成时,在设置好token之后返回PGRES_POLLING_OK;如果失败,则返回PGRES_POLLING_FAILED。 - - - 实现可能希望在多次调用asynccleanup回调之间保存额外的数据用于记账。为此提供了user指针;libpq不会触碰其内容,应用程序可以按自己的需要使用它。(记得在令牌清理时释放相关分配。) - - - - - - - - - - 调试与开发者设置 - - - 通过设置环境变量PGOAUTHDEBUG=UNSAFE,可以启用一种危险的调试模式。该功能仅用于便于本地开发和测试。它会做一些你绝不会希望生产系统去做的事情: - - - - 允许在与 OAuth 提供者交互期间使用未加密的 HTTP - - - - - 允许使用环境变量PGOAUTHCAFILE完全替换系统受信任的 CA 列表 - - - - - 在 OAuth 流程期间把 HTTP 流量(其中包含多个关键机密)打印到标准错误 - - - - - 允许使用零秒重试间隔,这可能导致客户端忙等并无谓地消耗 CPU - - - - - - - 不要把 OAuth 流量的输出分享给第三方。它包含可被用来攻击你的客户端和服务器的机密。 - - - - 在线程化程序中的行为 - threads - with libpq + 线程 + 用于 libpq - - 从版本 17 起,libpq始终是可重入且线程安全的。不过仍有一条限制:不得有两个线程同时操作同一个PGconn对象。特别是,不能从不同线程通过同一个连接对象并发发出命令。(如果需要并发运行命令,请使用多个连接。) - - - - PGresult对象在创建后通常是只读的,因此可以在线程之间自由传递。不过,如果你使用中描述的任何会修改PGresult的函数,则需要自行避免对同一个PGresult执行并发操作。 - - - - 在较早版本中,libpq能否提供线程支持取决于编译选项。下面这个函数允许查询libpq的线程安全状态: - + libpq 默认是可重入且线程安全的。编译应用程序代码时,可能需要使用特殊的编译器命令行选项。有关如何构建支持线程的应用程序,请参阅系统文档,或查看 src/Makefile.global 中的 PTHREAD_CFLAGSPTHREAD_LIBS。以下函数可用于查询 libpq 的线程安全状态: @@ -7950,22 +6960,22 @@ int PQisthreadsafe(); - 如果libpq是线程安全的则返回 1,否则返回 0。在版本 17 及以上始终返回 1。 + 如果libpq是线程安全的则返回 1,否则返回 0。 - - 已废弃的函数不是线程安全的,不应在多线程程序中使用。可以用替代;可以用替代。 - + 线程使用的一项限制是:两个线程不能同时操作同一个 PGconn 对象。尤其不能通过同一个连接对象从不同线程并发发出命令。(如果需要并发执行命令,请使用多个连接。) - 如果你在应用程序中使用 Kerberos(除了libpq内部之外),则需要在 Kerberos 调用周围加锁,因为 Kerberos 函数不是线程安全的。可参考libpq源代码中的PQregisterThreadLock函数,它提供了一种在libpq与应用程序之间协作加锁的方法。 + PGresult对象在创建后通常是只读的,因此可以在线程之间自由传递。不过,如果你使用中描述的任何会修改PGresult的函数,则需要自行避免对同一个PGresult执行并发操作。 + 已弃用的 函数不是线程安全的,不应在多线程程序中使用。可以用 替代 ,用 替代 + - 同样地,如果你在应用程序中使用Curl,并且在启动新线程之前还没有先对 libcurl 进行全局初始化,那么你也需要通过PQregisterThreadLock协作地为任何可能初始化 libcurl 的代码加锁。对于支持线程安全初始化的较新版本Curl,这一限制已被解除;这类构建可以通过其版本元数据中声明的threadsafe特性识别出来。 + 如果你在应用程序中使用 Kerberos(除了libpq内部之外),则需要在 Kerberos 调用周围加锁,因为 Kerberos 函数不是线程安全的。可参考libpq源代码中的PQregisterThreadLock函数,它提供了一种在libpq与应用程序之间协作加锁的方法。 diff --git a/zh/14/logical-replication.sgml b/zh/14/logical-replication.sgml index a772ed13..84ccfbf0 100644 --- a/zh/14/logical-replication.sgml +++ b/zh/14/logical-replication.sgml @@ -154,7 +154,11 @@ 如前所述,每个(活动的)订阅都从远程(发布端)的一个复制槽接收变更。 - 额外的表同步槽通常是瞬态的,由系统内部创建以执行初始表同步,并在不再需要时自动删除。这些表同步槽的名称是自动生成的:pg_%u_sync_%u_%llu(参数分别为:订阅oid、表relid、系统标识sysid)。 + 额外的表同步槽通常只会短暂存在,由系统内部创建用于执行初始表同步,在不再需要时 + 自动删除。这些表同步槽的名称是自动生成的: + pg_%u_sync_%u_%llu + (参数分别为:订阅 oid、 + 表 relid、系统标识符 sysid)。 通常,使用CREATE SUBSCRIPTION创建订阅时会自动创建远程复制槽,使用DROP SUBSCRIPTION删除订阅时会自动删除复制槽。但在某些情况下,分别操控订阅和底层复制槽会很有用,甚至是必要的。以下是一些场景: @@ -214,7 +218,12 @@ - 数据库模式和DDL命令不会被复制。初始模式可使用pg_dump --schema-only手动复制。后续的模式变更需要手动保持同步。(注意,两端的模式不需要完全相同。)当数据库模式在运行中发生变更时,逻辑复制是健壮的:当发布端模式变更后,复制的数据开始到达订阅端但不符合表的模式时,复制会出错,直到模式被更新。在很多情况下,通过先在订阅端应用增量式模式变更,可以避免间歇性错误。 + 数据库模式和 DDL 命令不会被复制。初始模式可以手工使用 + pg_dump --schema-only 复制。之后的模式更改需要手工保持同步。 + (不过请注意,两端的模式其实不需要绝对一致。)当活动数据库中的模式定义发生变化时, + 逻辑复制仍然能够稳健运行:如果发布端修改了模式,而复制数据开始到达订阅端时 + 与表模式不匹配,复制就会报错,直到模式被更新。在很多情况下,可以通过先在订阅端 + 应用仅添加内容的模式变更来避免间歇性错误。 @@ -258,21 +267,21 @@ - 逻辑复制采用类似于物理流复制的架构(见)。它由walsenderapply进程实现。walsender 进程启动 WAL 的逻辑解码(见),并加载标准逻辑解码输出插件(pgoutput)。该插件将从 WAL 读取的变更转换为逻辑复制协议(见),并根据发布规范过滤数据。然后使用流复制协议将数据持续传输给 apply 工作进程,该工作进程将数据映射到本地表,并按正确的事务顺序逐一应用每个变更。 + 逻辑复制采用类似于物理流复制的架构(见)。它由walsenderapply进程实现。walsender 进程启动 WAL 的逻辑解码(见),并加载标准逻辑解码输出插件(pgoutput)。该插件将从 WAL 读取的变更转换为逻辑复制协议(见),并根据发布规范过滤数据。然后使用流复制协议将数据持续传输给 应用工作进程,该工作进程将数据映射到本地表,并按正确的事务顺序逐一应用每个变更。 - 订阅端数据库上的 apply 进程总是在session_replication_role设置为replica的情况下运行。这意味着默认情况下,触发器和规则不会在订阅端触发。用户可以选择使用ALTER TABLE命令和ENABLE TRIGGERENABLE RULE子句在表上启用触发器和规则。 + 订阅端数据库上的 应用进程总是在session_replication_role设置为replica的情况下运行。这意味着默认情况下,触发器和规则不会在订阅端触发。用户可以选择使用ALTER TABLE命令和ENABLE TRIGGERENABLE RULE子句在表上启用触发器和规则。 - 逻辑复制的apply进程目前只触发行触发器,不触发语句触发器。但初始表同步的实现方式类似于COPY命令,因此会触发INSERT的行触发器和语句触发器。 + 逻辑复制的应用进程目前只触发行触发器,不触发语句触发器。但初始表同步的实现方式类似于COPY命令,因此会触发INSERT的行触发器和语句触发器。 初始快照 - 已订阅表中的初始数据由一种特殊的apply进程的并行实例建立快照并复制。该进程将创建自己的复制槽并复制现有数据。一旦复制完成,表的内容就对其他后端可见了。现有数据复制完成后,工作进程进入同步模式,通过使用标准逻辑复制流式传输初始数据复制期间发生的所有变更,确保该表与主apply进程同步。在此同步阶段,变更会按照在发布端发生的顺序被应用和提交。同步完成后,该表的复制控制权交还给主apply进程,此后复制照常继续。 + 已订阅表中的初始数据由一种特殊的应用进程的并行实例建立快照并复制。该进程将创建自己的复制槽并复制现有数据。一旦复制完成,表的内容就对其他后端可见了。现有数据复制完成后,工作进程进入同步模式,通过使用标准逻辑复制流式传输初始数据复制期间发生的所有变更,确保该表与主应用进程同步。在此同步阶段,变更会按照在发布端发生的顺序被应用和提交。同步完成后,该表的复制控制权交还给主应用进程,此后复制照常继续。 @@ -289,7 +298,7 @@ - 正常情况下,已启用的订阅会有一个apply进程在运行。被禁用或已崩溃的订阅在此视图中将有零行。如果任何表的初始数据同步正在进行中,将有额外的工作进程用于正在同步的表。 + 正常情况下,已启用的订阅会有一个应用进程在运行。被禁用或已崩溃的订阅在此视图中将有零行。如果任何表的初始数据同步正在进行中,将有额外的工作进程用于正在同步的表。 @@ -328,7 +337,7 @@ - 订阅的apply进程将以超级用户的权限在本地数据库上运行。 + 订阅应用进程将以超级用户的权限在本地数据库中运行。 diff --git a/zh/14/maintenance.sgml b/zh/14/maintenance.sgml index 745af2b3..c5138a54 100644 --- a/zh/14/maintenance.sgml +++ b/zh/14/maintenance.sgml @@ -371,27 +371,15 @@ 增大这个设置可以避免不必要的工作;而减小这个设置,则会增加在表必须再次被清理之前可以流逝的事务数量。 - - VACUUM 使用可见性映射 - 来确定表中的哪些页面必须扫描。通常,即使某些页面仍然含有带旧 XID 值的行版本, - 只要这些页面没有任何死行版本,它也会跳过。因此,普通的 VACUUM - 不一定会冻结表中的每一个旧行版本。VACUUM 会定期执行激进清理,只跳过那些既没有死行也没有任何未冻结 XID 或 MXID 值的页面。 - + VACUUM 使用可见性映射来确定必须扫描表的哪些页面。通常,它会跳过没有死行版本的页面,即使其中可能仍有 XID 值很旧的行版本。因此,普通的 VACUUM 不一定会冻结表中的每一个旧行版本。VACUUM 会定期执行激进清理,只跳过既没有死行,也没有任何未冻结 XID 或 MXID 值的页面。 控制 VACUUM 何时执行这种操作:如果距离上一次此类扫描经过的事务数,大于 vacuum_freeze_table_age 减去 vacuum_freeze_min_age,就会扫描全部可见但未全部冻结的页面。将 vacuum_freeze_table_age 设为 0,会强制 VACUUM 对所有扫描都采用这种更激进的策略。 + - - - 控制VACUUM何时采用这种更激进的策略。如果距离上一次这类扫描以来经过的事务数大于 - vacuum_freeze_table_age 减去 - vacuum_freeze_min_age,就会对所有扫描使用这种更激进的策略。 - 把 vacuum_freeze_table_age 设为 0 会强制 - VACUUM 始终采用其更激进的策略。 - 一个表在不被清理的情况下所能维持的最长时间,是最后一次激进扫描时的 vacuum_freeze_min_age 值从 20 亿事务中扣除后的结果。 如果超过这个时间仍不清理,就可能导致数据丢失。为了确保不会发生这种情况, - 任何可能包含未冻结行且其 XID 早于配置参数 所指定年龄的表,都会触发自动清理。 (即使自动清理已被禁用,也会如此。) @@ -467,12 +455,9 @@ SELECT datname, age(datfrozenxid) FROM pg_database; - 虽然 VACUUM 主要扫描自上次清理以来被修改过的页面, - 但它也可能为了冻结它们而积极扫描某些全部可见但未全部冻结的页面; - 不过,只有当表中每一个可能包含未冻结 XID 的页面都被扫描时, - relfrozenxid 才会被推进。当 - relfrozenxid 比 - vacuum_freeze_table_age 旧、使用了 VACUUM 的 + VACUUM通常只扫描自上次清理以来被修改过的页面,但只有当表中每一个可能包含未冻结 XID 的页面都被扫描时, + relfrozenxid 才会被推进。当 + relfrozenxid的年龄超过vacuum_freeze_table_age个事务、使用了 VACUUMFREEZE 选项,或者所有尚未全部冻结的页面碰巧都需要清理以移除死行版本时, 就会发生这种情况。当 VACUUM 扫描了表中每个尚未全部冻结的页面时, 它应把 age(relfrozenxid) 设为略高于所用 @@ -489,7 +474,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; WARNING: database "mydb" must be vacuumed within 39985967 transactions -HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. +HINT: To avoid a database shutdown, execute a database-wide VACUUM in that database. (如提示所建议,手工执行 VACUUM 应能解决问题;但要注意, @@ -498,13 +483,13 @@ HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that 如果忽略这些警告,一旦距离回卷只剩不到三百万个事务,系统就会拒绝分配新的 XID: -ERROR: database is not accepting commands that assign new XIDs to avoid wraparound data loss in database "mydb" -HINT: Execute a database-wide VACUUM in that database. +ERROR: database is not accepting commands to avoid wraparound data loss in database "mydb" +HINT: Stop the postmaster and vacuum that database in single-user mode. 在这种状态下,已经在进行中的事务可以继续,但只能启动只读事务。 修改数据库记录或截断关系的操作都会失败。VACUUM 命令仍然可以正常执行。 - 请注意,与早期版本中有时给出的建议相反,为了恢复正常运行, + 与提示内容相反,为了恢复正常运行, 不需要也不希望停止 postmaster 或进入单用户模式。相反,请按以下步骤操作: @@ -569,22 +554,22 @@ HINT: Execute a database-wide VACUUM in that database. 多事务(multitransaction,MultiXact) ID 用于支持多个事务对行加锁。由于元组头中用于存储锁信息的空间有限, 当有多个事务同时锁定一行时,这些信息会被编码为一个多事务 ID, - 简称 multixact ID。某个特定 multixact ID 包含哪些事务 ID 的信息, + 简称 multixact ID。某个特定 多事务 ID 包含哪些事务 ID 的信息, 会单独存放在 pg_multixact 子目录中,而元组头的 - xmax 字段中只出现 multixact ID。和事务 ID 一样, - multixact ID 也是以 32 位计数器及其对应存储实现的,因此同样需要仔细处理老化管理、 - 存储清理和回卷问题。还有一个单独的存储区域保存每个 multixact 的成员列表, + xmax 字段中只出现 多事务 ID。和事务 ID 一样, + 多事务 ID 也是以 32 位计数器及其对应存储实现的,因此同样需要仔细处理老化管理、 + 存储清理和回卷问题。还有一个单独的存储区域保存每个 多事务 的成员列表, 它也使用 32 位计数器,因此同样必须被管理。 中介绍的系统函数 pg_get_multixact_members() - 可用于检查与某个 multixact ID 关联的事务 ID。 + 可用于检查与某个 多事务 ID 关联的事务 ID。 每当 VACUUM 扫描表的任何部分时,它都会把遇到的、早于 - 的任何 multixact ID 替换为另一个值,该值可能是零值、单个事务 ID,或者更新的 multixact ID。 + 的任何 多事务 ID 替换为另一个值,该值可能是零值、单个事务 ID,或者更新的 多事务 ID。 对于每个表,pg_class.relminmxid - 保存该表任何元组中仍可能出现的最老 multixact ID。如果这个值早于 + 保存该表任何元组中仍可能出现的最老 多事务 ID。如果这个值早于 ,就会强制执行一次激进扫描。 正如上一节所述,激进扫描意味着只有那些已知为全部冻结的页面才会被跳过。 可以对 pg_class.relminmxid @@ -593,14 +578,14 @@ HINT: Execute a database-wide VACUUM in that database. 无论出于何种原因而发生,激进的 VACUUM 扫描都能推进该表的值。最终,随着所有数据库中的所有表都被扫描, - 并推进其最老的 multixact 值,较老 multixact 的磁盘存储就可以被移除。 + 并推进其最老的 多事务 值,较老 多事务 的磁盘存储就可以被移除。 - 作为一项安全措施,对于 multixact 年龄大于 的任何表,都会进行一次激进扫描。 - 此外,如果 multixact 成员占用的存储超过大约 10GB,则会更频繁地对所有表进行激进扫描, - 从 multixact 年龄最老的表开始。即便自动清理名义上被禁用,这两类激进扫描也都会发生。 + 此外,如果 多事务 成员占用的存储超过大约 10GB,则会更频繁地对所有表进行激进扫描, + 从 多事务 年龄最老的表开始。即便自动清理名义上被禁用,这两类激进扫描也都会发生。 成员存储区域在到达回卷之前最多可增长到大约 20GB。 @@ -617,11 +602,11 @@ HINT: Execute a database-wide VACUUM in that database. - 如果没有可能出现在 multixact 中,那么正在运行的事务和预备事务都可以忽略。 + 如果没有可能出现在 多事务 中,那么正在运行的事务和预备事务都可以忽略。 - 与事务 ID 回卷不同,复制槽不会直接阻止 multixact 清理。 - 因此,删除陈旧的复制槽通常与解决 multixact ID 回卷问题无关。 + 与事务 ID 回卷不同,复制槽不会直接阻止 多事务 清理。 + 因此,删除陈旧的复制槽通常与解决 多事务 ID 回卷问题无关。 MXID 信息不会直接出现在诸如 pg_stat_activity 这样的系统视图中; @@ -676,50 +661,15 @@ HINT: Execute a database-wide VACUUM in that database. 的限制。 - - 对于 relfrozenxid 值早于 - 个事务的表,总是会执行清理 - (这也适用于那些通过存储参数修改了冻结最大年龄的表,见下文)。 - 否则,如果自上次 VACUUM 以来已经失效的元组数超过了 - 清理阈值,就会对该表执行清理。清理阈值定义如下: - -vacuum threshold = Minimum(vacuum max threshold, vacuum base threshold + vacuum scale factor * number of tuples) - - 其中,vacuum max threshold 是 - , - vacuum base threshold 是 - , - vacuum scale factor 是 - , - 而元组数是 - pg_class.reltuples。 + 凡是 relfrozenxid 值的年龄超过 个事务的表,始终都会被清理(这也适用于通过存储参数修改了最大冻结年龄的表,见下文)。否则,如果自上次 VACUUM 以来失效的元组数超过清理阈值,就会清理该表。清理阈值定义为: +vacuum threshold = vacuum base threshold + vacuum scale factor * number of tuples +其中,清理基础阈值为 ,清理比例因子为 ,元组数为 pg_class.reltuples - - 如果自上次清理以来插入的元组数超过了定义的插入阈值,也会对该表执行清理,该阈值定义如下: - -vacuum insert threshold = vacuum base insert threshold + vacuum insert scale factor * number of tuples * percent of table not frozen - - 其中,vacuum insert base threshold 是 - , - vacuum insert scale factor 是 - , - 元组数是 - pg_class.reltuples, - 而表中未冻结部分的百分比是 - 1 - pg_class.relallfrozen / pg_class.relpages。 - 这样的清理可能使表的一部分被标记为全部可见, - 并且也允许元组被冻结,从而减少后续清理所需的工作。对于只接收 - INSERT 操作、但没有或几乎没有 UPDATE / - DELETE 操作的表,降低该表的 - 可能是有益的, - 因为这会让元组在更早的清理中被冻结。过时元组数和插入元组数取自统计收集器; - 这是一个由每次 UPDATEDELETE 和 - INSERT 操作更新的最终一致计数。如果该表的 - relfrozenxid 值早于 - vacuum_freeze_table_age 个事务,就会执行一次激进扫描, - 以冻结旧元组并推进 relfrozenxid。 - + 如果自上次清理以来插入的元组数超过了定义的插入阈值,也会清理该表。插入阈值定义为: +vacuum insert threshold = vacuum base insert threshold + vacuum insert scale factor * number of tuples +其中,清理插入基础阈值为 ,清理插入比例因子为 。这种清理可以将表的部分区域标记为全部可见,并允许冻结元组,从而减少后续清理所需的工作。对于有 INSERT 操作,但没有或几乎没有 UPDATE/DELETE 操作的表,降低表的 可能有益,因为这可能让元组在更早的清理中被冻结。失效元组数和插入元组数来自统计收集器;这些计数只是近似值,由每次 UPDATE, + DELETEINSERT 操作更新。(之所以只是近似值,是因为高负载下可能丢失部分信息。)如果表的 relfrozenxid 值的年龄超过 vacuum_freeze_table_age 个事务,就会执行激进清理,冻结旧元组并推进 relfrozenxid;否则,只扫描自上次清理以来被修改过的页面。 对于分析操作,也使用了一个类似的条件:其阈值定义如下: @@ -917,7 +867,7 @@ pg_ctl start | rotatelogs /var/log/pgsql_log 86400 不过,在很多系统上,syslog 并不十分可靠, 尤其是在日志消息很大时;它可能恰恰在你最需要消息的时候截断或丢弃它们。 此外,在 Linux 上, - syslog 会把每条消息都刷新到磁盘,导致性能较差。 + syslog 会把每条消息都刷盘,导致性能较差。 (你可以在 syslog 配置文件的文件名开头使用一个 - 来禁用同步。) diff --git a/zh/14/monitoring.sgml b/zh/14/monitoring.sgml index 4776dd9a..a70d558e 100644 --- a/zh/14/monitoring.sgml +++ b/zh/14/monitoring.sgml @@ -34,29 +34,20 @@ 监控活动 - - 在大多数 Unix 平台上,PostgreSQL会修改ps命令报告的进程标题,以便单独的服务器进程能够被方便地识别。一个示例显示如下: - - + 在大多数 Unix 平台上,PostgreSQL会修改由ps报告的命令标题,以便轻松识别各个服务器进程。以下是一个显示示例: $ ps auxww | grep ^postgres postgres 15551 0.0 0.1 57536 7132 pts/0 S 18:02 0:00 postgres -i postgres 15554 0.0 0.0 57536 1184 ? Ss 18:02 0:00 postgres: background writer postgres 15555 0.0 0.0 57536 916 ? Ss 18:02 0:00 postgres: checkpointer postgres 15556 0.0 0.0 57536 916 ? Ss 18:02 0:00 postgres: walwriter postgres 15557 0.0 0.0 58504 2244 ? Ss 18:02 0:00 postgres: autovacuum launcher +postgres 15558 0.0 0.0 17512 1068 ? Ss 18:02 0:00 postgres: stats collector postgres 15582 0.0 0.0 58772 3080 ? Ss 18:04 0:00 postgres: joe runbug 127.0.0.1 idle postgres 15606 0.0 0.0 58772 3052 ? Ss 18:07 0:00 postgres: tgl regression [local] SELECT waiting postgres 15610 0.0 0.0 58772 3056 ? Ss 18:07 0:00 postgres: tgl regression [local] idle in transaction - - - (ps的正确调用方式因平台而异,显示细节也不同。此示例来自一个较新的 Linux 系统。)此处列出的第一个进程是主服务器进程。它显示的命令参数是启动时使用的参数。接下来的五个进程是由主进程自动启动的后台工作进程。(如果您已将系统设置为不运行自动清理,则不会出现autovacuum launcher进程。)其余的每个进程都是处理一个客户端连接的服务器进程。每个此类进程都会将其命令行显示为 - - +ps的适当调用方式随平台而异,显示内容的细节也是如此。此示例来自较新的 Linux 系统。)这里列出的第一个进程是主服务器进程。显示的命令参数与启动该进程时使用的参数相同。接下来的五个进程是主进程自动启动的后台工作进程。(如果系统被设置为不启动统计收集器,则不会出现stats collector进程;同样,也可以禁用autovacuum launcher进程。)其余每个进程都是处理一个客户端连接的服务器进程。每个这样的进程都将其命令行显示设置为以下形式: postgres: user database host activity - - - 用户、数据库和(客户端)主机项在客户端连接的整个生命周期内保持不变,但活动指示器会发生变化。活动可以是idle(即等待客户端命令)、idle in transaction(在BEGIN块内等待客户端)或命令类型名称,例如SELECT。此外,如果服务器进程当前正在等待另一个会话持有的锁,则会附加waiting。在上例中,我们可以推断进程 15606 正在等待进程 15610 完成其事务,从而释放某些锁。(进程 15610 必须是阻塞者,因为没有其他活动会话。在更复杂的情况下,有必要查看pg_locks系统视图以确定谁在阻塞谁。) - +在客户端连接的整个生命周期内,用户、数据库和(客户端)主机这几项保持不变,但活动指示符会改变。活动可以是idle(即等待客户端命令)、idle in transaction(在BEGIN块内等待客户端),或者命令类型名称,例如SELECT。此外,服务器进程当前若正在等待另一会话持有的锁,还会附加waiting。在上面的示例中,可以推断进程 15606 正在等待进程 15610 完成事务,从而释放某个锁。(进程 15610 必定是阻塞者,因为不存在其他活动会话。在更复杂的情况下,必须查看pg_locks系统视图,才能确定谁在阻塞谁。) 如果配置了,则集簇名称也会显示在ps输出中: @@ -90,14 +81,14 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 统计收集器 - statistics + 统计信息 PostgreSQL统计收集器是一个支持收集和报告服务器活动信息的子系统。 - 目前,对表和索引的访问以磁盘块和单个行的术语进行计数。每个表中的总行数, - 以及每个表的清理和分析操作的信息也被计数。如果启用,对用户定义函数的调用 - 和每个函数中花费的总时间也会被计数。 + 目前,对表和索引的访问分别以磁盘块和单行计数。每个表中的总行数, + 以及每个表的清理和分析操作的信息也被计数。它还可以统计对用户定义函数的调用 + 和每个函数中花费的总时间。 @@ -129,9 +120,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 参数启用对块读取和写入时间的监控。 - - 参数启用对 WAL 写入时间的监控。 - + 参数启用对 WAL 写入时间的监控。 通常,这些参数会设置在postgresql.conf中,以便它们适用于所有服务器进程,但也可以在单个会话中使用命令打开或关闭它们。(为防止普通用户隐藏其活动不被管理员发现,只有超级用户才能使用SET更改这些参数。) @@ -160,7 +149,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - 另一个重要点是,当要求服务器进程显示这些统计信息中的任何一种时,它会先取回收集器进程最近发出的报告,然后在当前事务结束之前,对所有统计视图和函数一直使用这一快照。因此,只要你继续当前事务,统计信息就会显示静态信息。类似地,在事务中第一次请求任意当前会话的查询信息时,就会收集所有会话当前查询的信息,并且在整个事务期间显示的都是同一份信息。这是一个特性,而不是一个错误,因为它允许你对统计信息执行多个查询并对结果做关联,而不必担心数字在你眼前变化。但如果希望每个查询都看到新的结果,请确保在任何事务块之外执行这些查询。或者,也可以调用pg_stat_clear_snapshot(),它会丢弃当前事务的统计快照(如果有)。下一次使用统计信息时,就会获取一个新的快照。 + 另一个重要点是,当要求服务器进程显示这些统计信息中的任何一种时,它会先取回收集器进程最近发出的报告,然后在当前事务结束之前,对所有统计视图和函数一直使用这一快照。因此,只要你继续当前事务,统计信息就会显示静态信息。类似地,在事务中第一次请求这类当前查询信息时,就会收集所有会话当前查询的信息,并且在整个事务期间显示的都是同一份信息。这是一个特性,而不是一个错误,因为它允许你对统计信息执行多个查询并对结果做关联,而不必担心数字在你眼前变化。但如果希望每个查询都看到新的结果,请确保在任何事务块之外执行这些查询。或者,也可以调用pg_stat_clear_snapshot(),它会丢弃当前事务的统计快照(如果有)。下一次使用统计信息时,就会获取一个新的快照。 @@ -172,11 +161,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 相反,它们在事务期间持续更新。 - - 动态统计视图中显示的一些信息在中受到安全限制。 - 普通用户只能查看关于他们自己会话的所有信息(属于他们是成员的角色的会话)。在关于其他会话的行中,许多列将为空。 - 但是,请注意,所有用户都可以看到会话的存在及其一般属性,例如会话用户和数据库。超级用户以及内置角色pg_read_all_stats的成员(另请参阅)可以查看所有会话的全部信息。 - + 所列动态统计视图中的一些信息受到安全限制。普通用户只能查看其自身会话的全部信息(包括属于其所加入角色的会话)。对于其他会话的行,许多列将为空值。不过,会话的存在及其一般属性(例如会话用户和数据库)对所有用户都可见。超级用户和内置角色pg_read_all_stats的成员(另请参阅)可以查看所有会话的全部信息。 @@ -211,17 +196,11 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser pg_stat_wal_receiverpg_stat_wal_receiver - 只有一行,显示有关 WAL 接收进程从其连接服务器接收到的统计信息。有关详细信息,请参阅pg_stat_wal_receiver。 + 只有一行,显示 WAL 接收进程从其所连接服务器接收数据的统计信息。有关详细信息,请参阅pg_stat_wal_receiver - - pg_stat_recovery_prefetchpg_stat_recovery_prefetch - 只有一行,显示了恢复过程中预取的块的统计信息。 - 详细信息请参见 - pg_stat_recovery_prefetch。 - - + pg_stat_subscriptionpg_stat_subscription @@ -301,42 +280,30 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - + pg_stat_bgwriterpg_stat_bgwriter 只有一行,显示有关后台写入器活动的信息。有关详细信息,请参阅pg_stat_bgwriter - - pg_stat_checkpointerpg_stat_checkpointer - 只有一行,显示有关检查点进程活动的信息。有关详细信息,请参阅pg_stat_checkpointer。 - - - - - pg_stat_iopg_stat_io - 对于每种后端类型、上下文和目标对象的组合各有一行,包含集簇范围的 I/O 统计信息。有关详细信息,请参阅pg_stat_io。 - - - - + pg_stat_walpg_stat_wal 只有一行,显示有关 WAL 活动的统计信息。有关详细信息,请参阅pg_stat_wal - + pg_stat_databasepg_stat_database 每个数据库一行,显示数据库范围的统计信息。有关详细信息,请参阅pg_stat_database - + pg_stat_database_conflictspg_stat_database_conflicts 每个数据库一行,显示数据库范围内因备库上的恢复冲突而导致查询被取消的统计信息。有关详细信息,请参阅pg_stat_database_conflicts - + pg_stat_all_tablespg_stat_all_tables 当前数据库中每个表一行,显示有关访问指定表的统计信息。详见 @@ -344,116 +311,111 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - + pg_stat_sys_tablespg_stat_sys_tables pg_stat_all_tables一样,但只显示系统表。 - + pg_stat_user_tablespg_stat_user_tables pg_stat_all_tables一样,但只显示用户表。 - + pg_stat_xact_all_tablespg_stat_xact_all_tables - pg_stat_all_tables相似,但计数动作只在当前事务内发生(还没有被包括在pg_stat_all_tables和相关视图中)。用于生存和死亡行数量的列以及清理和分析动作在此视图中不出现。 + pg_stat_all_tables 相似,但只统计当前事务中截至目前执行的操作(这些操作尚计入 pg_stat_all_tables 及相关视图)。此视图不包含存活行和死行数量以及清理、分析操作的列。 - + pg_stat_xact_sys_tablespg_stat_xact_sys_tables pg_stat_xact_all_tables一样,但只显示系统表。 - + pg_stat_xact_user_tablespg_stat_xact_user_tables pg_stat_xact_all_tables一样,但只显示用户表。 - + pg_stat_all_indexespg_stat_all_indexes 当前数据库中的每个索引一行,显示有关访问该特定索引的统计信息。有关详细信息,请参阅pg_stat_all_indexes - + pg_stat_sys_indexespg_stat_sys_indexes pg_stat_all_indexes一样,但只显示系统表上的索引。 - + pg_stat_user_indexespg_stat_user_indexes pg_stat_all_indexes一样,但只显示用户表上的索引。 - + pg_statio_all_tablespg_statio_all_tables 当前数据库中的每个表一行,显示有关访问该特定表的 I/O 统计信息。有关详细信息,请参阅pg_statio_all_tables - + pg_statio_sys_tablespg_statio_sys_tables pg_statio_all_tables一样,但只显示系统表。 - + pg_statio_user_tablespg_statio_user_tables pg_statio_all_tables一样,但只显示用户表。 - + pg_statio_all_indexespg_statio_all_indexes 当前数据库中的每个索引一行,显示有关访问该特定索引的 I/O 统计信息。有关详细信息,请参阅pg_statio_all_indexes - + pg_statio_sys_indexespg_statio_sys_indexes pg_statio_all_indexes一样,但只显示系统表上的索引。 - + pg_statio_user_indexespg_statio_user_indexes pg_statio_all_indexes一样,但只显示用户表上的索引。 - + pg_statio_all_sequencespg_statio_all_sequences 当前数据库中的每个序列一行,显示有关访问该特定序列的 I/O 统计信息。有关详细信息,请参阅pg_statio_all_sequences - + pg_statio_sys_sequencespg_statio_sys_sequences pg_statio_all_sequences一样,但只显示系统序列(目前没有定义系统序列,因此这个视图总是为空)。 - + pg_statio_user_sequencespg_statio_user_sequences pg_statio_all_sequences一样,但只显示用户序列。 - + pg_stat_user_functionspg_stat_user_functions 每个被跟踪的函数一行,显示有关该函数执行的统计信息。有关详细信息,请参阅pg_stat_user_functions - + pg_stat_xact_user_functionspg_stat_xact_user_functions pg_stat_user_functions相似,但是只统计在当前事务期间的调用(还没有被包括在pg_stat_user_functions中)。 - + pg_stat_slrupg_stat_slru 每个 SLRU 一行,显示操作统计信息。有关详细信息,请参阅pg_stat_slru - + pg_stat_replication_slotspg_stat_replication_slots 每个复制槽一行,显示有关复制槽使用情况的统计信息。有关详细信息,请参阅pg_stat_replication_slots - - pg_stat_subscription_statspg_stat_subscription_stats - 每个订阅一行,显示有关错误和冲突的统计信息。有关详细信息,请参阅pg_stat_subscription_stats - -
@@ -463,8 +425,13 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser
- pg_stat_iopg_statio_ 系列视图对于确定缓冲区缓存的有效性很有用,它们可用于计算缓存命中率。请注意,尽管PostgreSQL 的 I/O 统计信息捕获了内核被调用以执行 I/O 的大多数情况,但它们并不区分必须从磁盘读取的数据和已经存在于内核页面缓存中的数据。建议将PostgreSQL统计视图与操作系统工具结合使用,以更全面地了解数据库的 I/O 性能。 - + pg_statio_视图主要用于判断缓冲区缓存的有效性。 + 如果实际磁盘读取次数远少于缓冲区命中次数,缓存就能满足大多数读取请求,而无需调用内核。 + 不过,这些统计信息并不能反映全部情况:由于PostgreSQL处理磁盘 I/O 的方式, + 不在PostgreSQL缓冲区缓存中的数据仍可能驻留在内核的 I/O 缓存中, + 因而仍可在不执行物理读取的情况下取得。对于希望更详细地了解PostgreSQL I/O 行为的用户, + 建议将PostgreSQL统计收集器与能够深入查看内核 I/O 处理情况的操作系统工具结合使用。 +
@@ -529,7 +496,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser leader_pid integer
- 如果该进程是并行查询工作进程,则为并行组领导者的进程 ID;如果该进程是并行应用工作进程,则为领导应用工作进程的进程 ID。NULL 表示该进程是并行组领导者或领导应用工作进程,或者不参与任何并行操作。 + 如果此进程是并行查询工作进程,则为并行组领导者的进程 ID。如果此进程是并行组领导者或者不参与并行查询,则为NULL @@ -565,7 +532,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser client_addr inet - 连接到这个后端的客户端的 IP 地址。如果这个字段为空,它表示客户端通过服务器机器上的一个 Unix 套接字连接或者这是一个内部进程,如自动清理。 + 连接到这个后端的客户端的 IP 地址。如果这个字段为空值,它表示客户端通过服务器机器上的一个 Unix 套接字连接或者这是一个内部进程,如自动清理。 @@ -584,7 +551,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser client_port integer - 客户端用于与此后端通信的TCP端口号,如果使用Unix套接字,则为-1。如果该字段为空,它表示这是一个内部服务器进程。 + 客户端用于与此后端通信的TCP端口号,如果使用Unix套接字,则为-1。如果该字段为空值,它表示这是一个内部服务器进程。 @@ -602,8 +569,8 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser xact_start timestamp with time zone - 这个进程的当前事务被启动的时间,如果没有活动事务则为空。 - 如果当前查询是它的第一个事务,这一列等于query_start列。 + 这个进程的当前事务被启动的时间,如果没有活动事务则为空值。 + 如果当前查询是其事务中的第一个查询,这一列等于query_start列。 @@ -630,7 +597,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser wait_event_type text - 后端正在等待的事件类型(如果有);否则为NULL。请参阅。 + 后端正在等待的事件类型(如果有);否则为空值。请参阅 @@ -639,7 +606,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser wait_event text - 如果此后端当前正在等待,则返回等待事件名称,否则为NULL。请参阅。 + 如果此后端当前正在等待,则返回等待事件名称,否则为空值。请参阅 @@ -647,44 +614,24 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser state text - - 这个后端的当前总体状态。可能的值为: - - - - starting: 后端正处于初始启动阶段。客户端认证在此阶段执行。 - - + 该后端当前的总体状态。可能的值为: - - active: 后端正在执行一个查询。 - + active:后端正在执行一个查询。 - - idle: 后端正在等待一个新的客户端命令。 - + idle:后端正在等待新的客户端命令。 - - idle in transaction: 后端在一个事务中,但是当前没有正在执行一个查询。 - + idle in transaction:后端处于事务中,但当前没有执行查询。 - - idle in transaction (aborted): 这个状态与 - idle in transaction相似,除了在该事务中的一个语句导致了一个错误。 - + idle in transaction (aborted):该状态与idle in transaction类似,但事务中的某个语句导致了错误。 - - fastpath function call: 后端正在执行一个 fast-path 函数。 - + fastpath function call:后端正在执行一个快速路径函数。 - - disabled: 如果在这个后端中被禁用,则报告这个状态。 - + disabled:如果在此后端中禁用了,就会报告此状态。 @@ -704,7 +651,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser backend_xmin xid - 当前后端的xmin范围。 + 当前后端的xmin视界。 @@ -716,7 +663,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 这个后端的最近查询的标识符。 如果stateactive,这个字段显示当前正在执行的查询的标识符。 在所有其他状态,它显示执行的最后一个查询的标识符。 - 默认不计算查询标识符,因此该字段将为空,除非启用参数或配置了计算查询标识符的第三方模块。 + 默认不计算查询标识符,因此该字段将为空值,除非启用参数或配置了计算查询标识符的第三方模块。 @@ -734,19 +681,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser backend_type text - - 当前后端的类型。可能的类型为 - autovacuum launcher, autovacuum worker, - logical replication launcher, - logical replication worker, - parallel worker, background writer, - client backend, checkpointer, - archiver, standalone backend, - startup, walreceiver, - walsender, walwriter 以及 - walsummarizer。 - 此外,由扩展注册的后台工作进程还可能有额外的类型。 - + 当前后端的类型。可能的类型为autovacuum launcherautovacuum workerlogical replication launcherlogical replication workerparallel workerbackground writerclient backendcheckpointerarchiverstartupwalreceiverwalsenderwalwriter。此外,由扩展注册的后台工作进程还可能有额外的类型。 @@ -755,7 +690,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - wait_eventstate列彼此独立。如果某个后端处于active状态,它既可能正在等待某个事件,也可能没有等待。如果状态为activewait_event非空,就意味着某个查询正在执行,但在系统中的某处被阻塞了。为将报告开销保持在较低水平,系统不会尝试为某个后端同步活动数据的不同方面。因此,视图各列之间可能暂时存在不一致。 + wait_eventstate列彼此独立。如果某个后端处于active状态,它可能在等待(waiting)某个事件,也可能没有等待。如果状态为activewait_event非空,就意味着某个查询正在执行,但在系统中的某处被阻塞了。 @@ -782,10 +717,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser BufferPin - 服务器进程正在等待对数据缓冲的独占访问。 - 如果另一个进程持有一个打开的游标,该游标最后一次从相关缓冲区读取数据,则缓冲区销等待可能是漫长的。 - 参见。 - + 服务器进程正在等待独占访问一个数据缓冲区。如果另一个进程持有尚未关闭的游标,且该游标最近读取的数据来自此缓冲区,缓冲区钉住等待就可能持续较长时间。参见 @@ -801,14 +733,11 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - - InjectionPoint - 服务器进程正在等待某个注入点在测试中达到预定义结果。更多细节请参见。该类型没有预定义的等待点。 - + IO - 服务器进程正在等待一个I/O操作完成。wait_event将识别特定的等待点;参见。 + 服务器进程正在等待一个 I/O 操作完成。wait_event将识别特定的等待点;参见 @@ -820,17 +749,14 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser Lock - 服务器进程正在等待一个重量级锁。重量级锁,也称为锁管理器锁或简单锁,主要保护表等SQL可见对象。 + 服务器进程正在等待一个重量级锁。重量级锁,也称为锁管理器锁或简称为锁,主要保护表等SQL可见对象。 然而,它们也用于确保某些内部操作的互斥,例如关系扩展。wait_event将识别等待的锁的类型;参见 LWLock - 服务器进程正在等待一个轻量级锁。大多数这样的锁保护共享内存中的特定数据结构。 - wait_event将包含标识轻量级锁用途的名称。 - (有些锁有特定的名称;其他锁是一组锁的一部分,每个锁具有类似的目的。)参见。 - + 服务器进程正在等待一个轻量级锁。大多数这样的锁保护共享内存中的某个特定数据结构。wait_event将包含标识该轻量级锁用途的名称。(有些锁具有专门的名称,另一些锁属于一组用途相似的锁。)参见 @@ -863,12 +789,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser AutoVacuumMain - 在自动清理启动过程的主循环中等待。 + 在自动清理启动进程的主循环中等待。 BgWriterHibernate - 在后台写入器中等待,休眠状态。 + 在后台写入器进程中休眠等待。 @@ -891,9 +817,14 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 在逻辑复制启动器进程的主循环中等待。 + + PgStatMain + 在统计收集器进程的主循环中等待。 + + RecoveryWalStream - 流恢复期间,在启动进程主循环等待WAL到达。 + 在流恢复期间,在启动进程的主循环中等待 WAL 到达。 @@ -903,7 +834,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser WalReceiverMain - 在WAL 接收进程的主循环中等待。 + 在 WAL 接收进程的主循环中等待。 @@ -913,7 +844,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser WalWriterMain - 在WAL写入进程的主循环中等待。 + 在 WAL 写入进程的主循环中等待。 @@ -935,7 +866,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser BufferPin - 等待获得缓冲区上的独占销。 + 等待获得缓冲区上的独占钉住。 @@ -972,12 +903,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser LibPQWalReceiverConnect - 在WAL 接收进程等待与远程服务器建立连接。 + 在 WAL 接收进程中等待与远程服务器建立连接。 LibPQWalReceiverReceive - 在WAL 接收进程中等待从远程服务器接收数据。 + 在 WAL 接收进程中等待从远程服务器接收数据。 @@ -987,7 +918,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser WalSenderWaitForWAL - 在 WAL 发送进程中等待 WAL 被刷新。 + 在 WAL 发送进程中等待 WAL 刷盘。 @@ -1039,16 +970,6 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 等待基础备份从文件中读取。 - - BaseBackupSync - 等待由基础备份写入的数据达到持久存储。 - - - - BaseBackupWrite - 等待基础备份写入文件。 - - BufFileRead 等待从缓冲文件中读取。 @@ -1071,12 +992,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser ControlFileSync - 等待pg_control文件到达持久存储。 + 等待 pg_control 文件同步到持久存储。 ControlFileSyncUpdate - 等待更新pg_control文件以达到持久存储。 + 等待对 pg_control 文件的更新同步到持久存储。 @@ -1086,7 +1007,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser ControlFileWriteUpdate - 等待写入更新pg_control文件。 + 等待写入以更新 pg_control 文件。 @@ -1096,12 +1017,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser CopyFileWrite - 在文件拷贝操作期间等待写入。 + 在文件复制操作期间等待写入。 DSMFillZeroWrite - 等待用零填充动态共享内存备份(backing)文件。 + 等待用零填充动态共享内存的后备文件。 @@ -1111,12 +1032,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser DataFileFlush - 等待关系数据文件达到持久存储。 + 等待关系数据文件同步到持久存储。 DataFileImmediateSync - 等待关系数据文件到持久存储的立即同步。 + 等待关系数据文件立即同步到持久存储。 @@ -1131,7 +1052,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser DataFileSync - 等待对关系数据文件的更改达到持久存储。 + 等待对关系数据文件的更改同步到持久存储。 @@ -1151,7 +1072,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser LockFileAddToDataDirSync - 等待数据到达持久存储,同时向数据目录锁文件添加一行。 + 在向数据目录锁文件中添加一行时,等待数据同步到持久存储。 @@ -1166,7 +1087,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser LockFileCreateSync - 在创建数据目录锁文件时等待数据到达持久存储。 + 在创建数据目录锁文件时,等待数据同步到持久存储。 @@ -1181,12 +1102,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser LogicalRewriteCheckpointSync - 等待逻辑重写映射到在检查点到达持久存储。 + 在检查点期间等待逻辑重写映射同步到持久存储。 LogicalRewriteMappingSync - 在逻辑重写期间等待映射数据到达持久存储 + 在逻辑重写期间等待映射数据同步到持久存储。 @@ -1196,12 +1117,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser LogicalRewriteSync - 等待逻辑重写映射到达持久存储。 + 等待逻辑重写映射同步到持久存储。 LogicalRewriteTruncate - 等待在逻辑重写期间截断映射数据。 + 在逻辑重写期间等待截断映射数据。 @@ -1216,7 +1137,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser RelationMapSync - 等待关系映射文件到达持久存储。 + 等待关系映射文件同步到持久存储。 @@ -1226,17 +1147,17 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser ReorderBufferRead - 在重新排序缓冲区管理期间等待读取。 + 在重排序缓冲区管理期间等待读取。 ReorderBufferWrite - 在重新排序缓冲区管理期间等待写操作。 + 在重排序缓冲区管理期间等待写入。 ReorderLogicalMappingRead - 在重新排序缓冲区管理期间等待读取逻辑映射。 + 在重排序缓冲区管理期间等待读取逻辑映射。 @@ -1246,12 +1167,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser ReplicationSlotRestoreSync - 等待复制槽控制文件到达持久存储,同时将其恢复到内存中。 + 在将复制槽控制文件恢复到内存期间,等待该文件同步到持久存储。 ReplicationSlotSync - 等待复制槽控制文件到达持久存储。 + 等待复制槽控制文件同步到持久存储。 @@ -1261,7 +1182,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser SLRUFlushSync - 在检查点或数据库关闭期间等待SLRU数据到达持久存储。 + 在检查点或数据库关闭期间,等待 SLRU 数据同步到持久存储。 @@ -1271,7 +1192,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser SLRUSync - 在写页面后等待SLRU数据到达持久存储。 + 在页面写入后等待 SLRU 数据同步到持久存储。 @@ -1281,22 +1202,22 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser SnapbuildRead - 等待读取序列化的历史目录快照。 + 等待读取序列化的历史系统目录快照。 SnapbuildSync - 等待序列化历史目录快照到达持久存储。 + 等待序列化的历史系统目录快照同步到持久存储。 SnapbuildWrite - 等待串行历史目录快照的写入。 + 等待写入序列化的历史系统目录快照。 TimelineHistoryFileSync - 等待通过流复制接收的时间线历史文件到达持久存储。 + 等待通过流复制接收的时间线历史文件同步到持久存储。 @@ -1311,7 +1232,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser TimelineHistorySync - 等待新创建的时间线历史文件到达持久存储。 + 等待新创建的时间线历史文件同步到持久存储。 @@ -1326,7 +1247,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser TwophaseFileSync - 等待两阶段状态文件到达持久存储。 + 等待两阶段状态文件同步到持久存储。 @@ -1334,19 +1255,9 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 等待对两阶段状态文件的写入。 - - VersionFileSync - 等待版本文件达到持久存储,同时创建数据库。 - - - - VersionFileWrite - 在创建数据库时等待版本文件被写入。 - - WALBootstrapSync - 在引导过程中等待WAL达到持久存储。 + 在引导过程中等待 WAL 同步到持久存储。 @@ -1361,7 +1272,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser WALCopySync - 等待通过复制一个已有WAL段到持久存储来创建一个新的WAL段。 + 等待通过复制现有 WAL 段创建的新 WAL 段同步到持久存储。 @@ -1371,7 +1282,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser WALInitSync - 等待一个新初始化的WAL文件到持久存储。 + 等待新初始化的 WAL 文件同步到持久存储。 @@ -1386,22 +1297,42 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser WALSenderTimelineHistoryRead - 在walsender时间线命令期间等待从时间线历史文件读取。 + 在 WAL 发送进程执行时间线命令期间,等待从时间线历史文件读取。 WALSync - 等待WAL文件到达持久存储。 + 等待 WAL 文件同步到持久存储。 WALSyncMethodAssign - 等待数据到达持久存储,同时分配一个新的WAL同步方法。 + 在设置新的 WAL 同步方法时,等待数据同步到持久存储。 WALWrite - 等待写入WAL文件。 + 等待写入 WAL 文件。 + + + + LogicalChangesRead + 等待从逻辑变更文件读取。 + + + + LogicalChangesWrite + 等待写入逻辑变更文件。 + + + + LogicalSubxactRead + 等待从逻辑子事务文件读取。 + + + + LogicalSubxactWrite + 等待写入逻辑子事务文件。 @@ -1426,16 +1357,6 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 等待 Append 计划节点的子计划节点准备好。 - - ArchiveCleanupCommand - 等待完成。 - - - - ArchiveCommand - 等待完成。 - - BackendTermination 等待另一个后端终止。 @@ -1458,12 +1379,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser BtreePage - 正等待继续并行B-树扫描所需的页号变得可用。 + 等待继续并行 B-树扫描所需的页号变得可用。 BufferIO - 等待缓冲I/O结束。 + 等待缓冲区 I/O 完成。 @@ -1478,82 +1399,82 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser ExecuteGather - 在执行Gather 计划节点时,等待子进程的活动。 + 在执行 Gather 计划节点时,等待子进程的活动。 HashBatchAllocate - 等待一个选定的并行哈希参与者分配哈希表。 + 等待选出的 Parallel Hash 参与者分配哈希表。 HashBatchElect - 等待选择一个并行哈希参与者来分配哈希表。 + 等待选出负责分配哈希表的 Parallel Hash 参与者。 HashBatchLoad - 等待其他并行哈希参与者完成哈希表的加载。 + 等待其他 Parallel Hash 参与者完成哈希表的加载。 HashBuildAllocate - 等待一个选定的并行哈希参与者分配初始哈希表。 + 等待选出的 Parallel Hash 参与者分配初始哈希表。 HashBuildElect - 等待选择一个并行哈希参与者来分配初始哈希表。 + 等待选出负责分配初始哈希表的 Parallel Hash 参与者。 HashBuildHashInner - 等待其他并行哈希参与者完成内部关系的散列。 + 等待其他 Parallel Hash 参与者完成对内层关系的哈希处理。 HashBuildHashOuter - 等待其他Parallel 哈希参与者完成对外部关系的分区。 + 等待其他 Parallel Hash 参与者完成对外层关系的分区。 HashGrowBatchesAllocate - 等待选定的并行哈希参与者分配更多批处理。 + 等待选出的 Parallel Hash 参与者分配更多批次。 HashGrowBatchesDecide - 等待选择一个并行哈希参与者来决定未来的批处理增长。 + 等待选出负责决定后续批次增长的 Parallel Hash 参与者。 HashGrowBatchesElect - 等待选择一个Parallel 哈希参与者来分配更多批处理。 + 等待选出负责分配更多批次的 Parallel Hash 参与者。 HashGrowBatchesFinish - 等待当选的平行散列参与者决定未来的批量增长。 + 等待选出的 Parallel Hash 参与者决定后续的批次增长。 HashGrowBatchesRepartition - 等待一个选定的并行哈希参与者决定未来的批处理增长。 + 等待其他 Parallel Hash 参与者完成重新分区。 HashGrowBucketsAllocate - 等待选定的并行哈希参与者完成更多bucket的分配。 + 等待选出的 Parallel Hash 参与者完成更多桶的分配。 HashGrowBucketsElect - 等待选择一个并行哈希参与者来分配更多的buckets。 + 等待选出负责分配更多桶的 Parallel Hash 参与者。 HashGrowBucketsReinsert - 等待其他Parallel 哈希参与者完成将元组插入到新buckets中。 + 等待其他 Parallel Hash 参与者完成向新桶插入元组。 @@ -1588,22 +1509,22 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser ParallelBitmapScan - 等待并行位图扫描被初始化。 + 等待并行位图扫描完成初始化。 ParallelCreateIndexScan - 等待并行CREATE INDEX 工作进程完成堆扫描。 + 等待并行 CREATE INDEX 工作进程完成堆扫描。 ParallelFinish - 等待并行工作人员完成计算。 + 等待并行工作进程完成计算。 ProcArrayGroupUpdate - 等待组领导在并行操作结束时清除事务ID。 + 等待组领导者在事务结束时清除事务 ID。 @@ -1618,17 +1539,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser RecoveryConflictSnapshot - 等待vacuum清理的恢复冲突解决。 + 等待解决清理操作引发的恢复冲突。 RecoveryConflictTablespace - 等待恢复冲突解决删除表空间。 - - - - RecoveryEndCommand - 等待完成。 + 等待解决删除表空间引发的恢复冲突。 @@ -1646,11 +1562,6 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 等待复制槽变为非活动状态,以便可以删除它。 - - RestoreCommand - 等待完成。 - - SafeSnapshot 等待获取READ ONLY DEFERRABLE事务的有效快照。 @@ -1658,7 +1569,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser SyncRep - 在同步复制期间等待远程服务器的确认。 + 在同步复制期间等待来自远程服务器的确认。 @@ -1673,7 +1584,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser XactGroupUpdate - 等待分组组长在并行操作结束时更新事务状态。 + 等待组领导者在事务结束时更新事务状态。 @@ -1695,7 +1606,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser advisory - 等待获得一个建议用户锁。 + 等待获取用户咨询锁。 @@ -1705,8 +1616,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser frozenid - 等待升级 pg_database.datfrozenxid - 和 pg_database.datminmxid. + 等待更新 pg_database.datfrozenxidpg_database.datminmxid @@ -1721,12 +1631,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser relation - 等待获得一个关系的锁。 + 等待获取关系上的锁。 spectoken - 等待获取推测的插入锁。 + 等待获取推测插入锁。 @@ -1768,7 +1678,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser AddinShmemInit - 等待管理共享内存中的扩展空间分配。 + 等待管理扩展在共享内存中的空间分配。 @@ -1783,7 +1693,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser AutovacuumSchedule - 等待确保选择为自动清理的表仍然需要清理。 + 等待确认选中进行自动清理的表是否仍需清理。 @@ -1813,7 +1723,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser CommitTs - 等待读取或更新事务提交时间戳的最后一个值集。 + 等待读取或更新最近设置的事务提交时间戳值。 @@ -1843,42 +1753,42 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser LockManager - 等待读取或更新关于heavyweight锁。 + 等待读取或更新有关重量级锁的信息。 LogicalRepWorker - 等待读取或更新逻辑复制工作器的状态。 + 等待读取或更新逻辑复制工作进程的状态。 MultiXactGen - 等待读取或更新共享的multixact状态。 + 等待读取或更新共享的多事务状态。 MultiXactMemberBuffer - 在multixact成员SLRU缓冲区上等待I/O。 + 等待多事务成员 SLRU 缓冲区上的 I/O。 MultiXactMemberSLRU - 等待访问multixact成员SLRU缓存。 + 等待访问多事务成员 SLRU 缓存。 MultiXactOffsetBuffer - 在multixact 偏移 SLRU缓冲区上等待I/O。 + 等待多事务偏移量 SLRU 缓冲区上的 I/O。 MultiXactOffsetSLRU - 等待访问multixact 偏移 SLRU缓存。 + 等待访问多事务偏移量 SLRU 缓存。 MultiXactTruncation - 等待读取或截断multixact信息。 + 等待读取或截断多事务信息。 @@ -1893,7 +1803,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser NotifyQueueTail - 等待NOTIFY消息存储上的更新限制。 + 等待更新 NOTIFY 消息存储的限制。 @@ -1913,12 +1823,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser ParallelAppend - 在并行附加计划执行期间等待选择下一个子计划。 + 在 Parallel Append 计划执行期间等待选择下一个子计划。 ParallelHashJoin - 在并行哈希连接计划执行期间等待同步工作器。 + 在 Parallel Hash Join 计划执行期间等待同步工作进程。 @@ -1933,12 +1843,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser PerSessionRecordType - 等待访问有关复合类型的并行查询信息。 + 等待访问并行查询中有关复合类型的信息。 PerSessionRecordTypmod - 等待访问有关标识匿名记录类型的类型修饰符的并行查询信息。 + 等待访问并行查询中用于标识匿名记录类型的类型修饰符信息。 @@ -1953,7 +1863,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser ProcArray - 等待访问每个进程共享的数据结构(通常情况,是获取快照或报告会话的事务ID)。 + 等待访问各进程的共享数据结构(通常是为了获取快照或报告会话的事务 ID)。 @@ -2006,21 +1916,6 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 等待访问可串行化事务持有的谓词锁列表。 - - PgStatsDSA - 等待统计动态共享内存分配器访问 - - - - PgStatsHash - 等待统计共享内存哈希表访问 - - - - PgStatsData - 等待共享内存统计数据访问 - - SerializableXactHash 等待读取或更新关于可串行化事务的信息。 @@ -2048,12 +1943,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser SInvalRead - 等待从共享目录失效队列中检索消息。 + 等待从共享系统目录失效队列中取出消息。 SInvalWrite - 等待向共享编目失效队列添加消息。 + 等待向共享系统目录失效队列添加消息。 @@ -2083,7 +1978,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser TwoPhaseState - 等待读取或更新已准备事务的状态。 + 等待读取或更新预备事务的状态。 @@ -2103,7 +1998,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser WrapLimitsVacuum - 等待更新事务 ID和multixact消费的限制。 + 等待更新事务 ID 和多事务消耗量的限制。 @@ -2132,8 +2027,8 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - 扩展可以将ExtensionInjectionPointLWLock 类型添加到所示的列表中。 - 在某些情况下,扩展分配的 LWLock 名称无法在所有服务器进程中使用;因此,LWLock 等待事件可能只会被报告为extension,而不是扩展分配的名称。 + 扩展可以将LWLock 类型添加到所示的列表中。 + 在某些情况下,扩展分配的名称无法在所有服务器进程中使用;因此,LWLock 等待事件可能只会被报告为extension,而不是扩展分配的名称。 @@ -2153,12 +2048,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser BaseBackupThrottle - 当有限流活动时在基础备份期间等待。 + 在基础备份期间因限流而等待。 CheckpointWriteDelay - 在执行检查点时写入之间的等待时间。 + 在执行检查点时,在各次写入之间等待。 @@ -2178,24 +2073,19 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser RegisterSyncRequest - 在发送同步请求到检查点程序时等待,因为请求队列已满。 + 向检查点进程发送同步请求时,因请求队列已满而等待。 VacuumDelay - 在一个基于代价的清理延迟点。 - - - - VacuumTruncate - 等待获取独占锁以截断被清理的表末尾的空页面。 + 在基于代价的清理延迟点等待。 - 这里是一个查看等待事件的示例: + 以下示例展示如何查看等待事件: SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event is NOT NULL; @@ -2206,17 +2096,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i (2 rows) - -SELECT a.pid, a.wait_event, w.description - FROM pg_stat_activity a JOIN - pg_wait_events w ON (a.wait_event_type = w.type AND - a.wait_event = w.name) - WHERE a.wait_event is NOT NULL and a.state = 'active'; --[ RECORD 1 ]------------------------------------------------------&zwsp;------------ -pid | 686674 -wait_event | WALInitSync -description | Waiting for a newly initialized WAL file to reach durable storage - + @@ -2293,7 +2173,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage 连接到这个 WAL 发送进程的客户端的 IP 地址。 - 如果这个域为空,它表示该客户端通过服务器机器上的一个Unix 套接字连接。 + 如果这个字段为空值,它表示该客户端通过服务器机器上的一个Unix 套接字连接。 @@ -2344,27 +2224,27 @@ description | Waiting for a newly initialized WAL file to reach durable storage - startup: 此 WAL 发送进程正在启动。 + startup: 此 WAL 发送进程正在启动。 - catchup: 与此 WAL 发送进程连接的备库正在赶上主库。 + catchup: 与此 WAL 发送进程连接的备库正在赶上主库。 - streaming: 在其连接的备库赶上主库之后,此 WAL 发送进程正在流式传输更改。 + streaming: 在其连接的备库赶上主库之后,此 WAL 发送进程正在流式传输更改。 - backup: 此 WAL 发送进程正在发送一个备份。 + backup: 此 WAL 发送进程正在发送一个备份。 - stopping: 此 WAL 发送进程正在停止。 + stopping: 此 WAL 发送进程正在停止。 @@ -2411,30 +2291,21 @@ description | Waiting for a newly initialized WAL file to reach durable storage write_lag interval - - 从本地刷写最近的 WAL,到收到该备库已写入该 WAL(但尚未刷盘或应用)的通知之间经过的时间。 - 如果该服务器被配置为同步备库,可用此值衡量在提交时 synchronous_commit 级别 remote_write 所导致的延迟。 - + 从在本地将最近的 WAL 刷盘,到收到该备库已写入该 WAL(但尚未刷盘或应用)的通知之间经过的时间。如果该服务器被配置为同步备库,可用此值衡量在提交时synchronous_commit级别remote_write所导致的延迟。 flush_lag interval - - 从本地刷写最近的 WAL,到收到该备库已写入并刷写该 WAL(但尚未应用)的通知之间经过的时间。 - 如果该服务器被配置为同步备库,可用此值衡量在提交时 synchronous_commit 级别 on 所导致的延迟。 - + 从在本地将最近的 WAL 刷盘,到收到该备库已写入该 WAL 并将其刷盘(但尚未应用)的通知之间经过的时间。如果该服务器被配置为同步备库,可用此值衡量在提交时synchronous_commit级别on所导致的延迟。 replay_lag interval - - 从本地刷写最近的 WAL,到收到该备库已写入、刷写并应用该 WAL 的通知之间经过的时间。 - 如果该服务器被配置为同步备库,可用此值衡量在提交时 synchronous_commit 级别 remote_apply 所导致的延迟。 - + 从在本地将最近的 WAL 刷盘,到收到该备库已写入该 WAL、将其刷盘并应用的通知之间经过的时间。如果该服务器被配置为同步备库,可用此值衡量在提交时synchronous_commit级别remote_apply所导致的延迟。 @@ -2456,22 +2327,22 @@ description | Waiting for a newly initialized WAL file to reach durable storage - async: 该备库是异步的。 + async: 该备库是异步的。 - potential: 该备库当前是异步的,但在当前同步备库失效时可能变为同步的。 + potential: 该备库当前是异步的,但在当前某个同步备库失效时可能变为同步的。 - sync: 该备库是同步的。 + sync: 该备库是同步的。 - quorum: 该备库被作为法定人数同步复制候选备库。 + quorum: 该备库被作为法定人数同步复制候选备库。 @@ -2480,7 +2351,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - reply_time 带时区的时间戳 + reply_time timestamp with time zone 从备库收到的最后一条回复消息的发送时间 @@ -2491,17 +2362,17 @@ description | Waiting for a newly initialized WAL file to reach durable storage - pg_stat_replication视图中报告的滞后时间,是最近的 WAL 被写入、刷写和重放,以及发送端获知这些操作完成所花费时间的度量。如果远程服务器被配置为同步备库,这些时间表示各个同步提交级别带来或可能带来的提交延迟。对于异步备库,replay_lag列是最近事务对查询变得可见所需延迟时间的近似值。如果备库已经完全追上发送服务器且没有新的 WAL 活动,系统会在短时间内继续显示最近测得的滞后时间,随后显示为 NULL。 + pg_stat_replication视图中报告的滞后时间,是最近的 WAL 被写入、刷盘和重放,以及发送端获知这些操作完成所花费时间的度量。如果远程服务器被配置为同步备库,这些时间表示各个同步提交级别带来或可能带来的提交延迟。对于异步备库,replay_lag列是最近事务对查询变得可见所需延迟时间的近似值。如果备库已经完全追上发送服务器且没有新的 WAL 活动,系统会在短时间内继续显示最近测得的滞后时间,随后显示为 空值。 - 对于物理复制,滞后时间会自动测量。逻辑解码插件可以选择发出跟踪消息;如果没有这样做,跟踪机制会将滞后显示为 NULL。 + 对于物理复制,滞后时间会自动测量。逻辑解码插件可以选择发出跟踪消息;如果没有这样做,跟踪机制会将滞后显示为 空值。 - 报告出的滞后时间并不是根据当前重放速率预测该备库还需多久才能追上发送服务器。在持续生成新 WAL 时,那样的系统可能会显示相近的时间;但当发送端空闲时,就会显示不同的值。特别是当备库已经完全追上时,pg_stat_replication显示的是写入、刷写和重放最近报告的 WAL 位置所花费的时间,而不是某些用户可能预期的零。这样做符合为最近写事务测量同步提交和事务可见性延迟的目的。为减少用户因预期另一种滞后模型而产生的混淆,在一个已完全重放且处于空闲状态的系统上,lag 列会在较短时间后恢复为 NULL。监控系统应自行决定将这种情况表示为缺失数据、零,还是继续显示最近一次已知值。 + 报告出的滞后时间并不是根据当前重放速率预测该备库还需多久才能追上发送服务器。在持续生成新 WAL 时,那样的系统可能会显示相近的时间;但当发送端空闲时,就会显示不同的值。特别是当备库已经完全追上时,pg_stat_replication显示的是写入、刷盘和重放最近报告的 WAL 位置所花费的时间,而不是某些用户可能预期的零。这样做符合为最近写事务测量同步提交和事务可见性延迟的目的。为减少用户因预期另一种滞后模型而产生的混淆,在一个已完全重放且处于空闲状态的系统上,滞后列会在较短时间后恢复为 空值。监控系统应自行决定将这种情况表示为缺失数据、零,还是继续显示最近一次已知值。 @@ -2540,19 +2411,14 @@ description | Waiting for a newly initialized WAL file to reach durable storage slot_name text - - 唯一的,复制槽的集簇范围标识符 - + 复制槽在整个集簇范围内的唯一标识符 spill_txns bigint - - 当逻辑解码在解码来自WAL的更改时所使用的内存超过logical_decoding_work_mem,溢出到磁盘的事务数。 - 顶级事务和子事务的计数器都是递增的。 - + 当逻辑解码从 WAL 解码更改时所使用的内存超过logical_decoding_work_mem后,溢出到磁盘的事务数。顶层事务和子事务都会使此计数器递增。 @@ -2560,7 +2426,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage spill_count bigint - 在为该槽位解码来自WAL的更改时,事务溢出到磁盘的次数。 + 在为该槽解码来自WAL的更改时,事务溢出到磁盘的次数。 此计数器在每次事务被溢出时递增,并且同一事务可能被溢出多次。 @@ -2569,20 +2435,14 @@ description | Waiting for a newly initialized WAL file to reach durable storage spill_bytes bigint - - 在对来自WAL的更改执行解码时,已解码的事务数据溢出到磁盘的数量。 - 这个和其他溢出计数器可用于测量逻辑解码期间发生的I/O,并且允许调优logical_decoding_work_mem。 - + 为此槽从 WAL 解码更改时,溢出到磁盘的已解码事务数据量。此计数器及其他溢出计数器可用于衡量逻辑解码期间发生的 I/O,并用于调优logical_decoding_work_mem stream_txns bigint - - 在逻辑解码在解码来自该槽位的WAL更改的时候,所使用的内存超过logical_decoding_work_mem之后,流式传输到解码输出插件的正在进行的事务数。 - 流式传输仅对顶级事务有效(子事务不能独立进行流式传输),因此子事务的计数器不会增加。 - + 当逻辑解码为此槽从 WAL 解码更改时所使用的内存超过logical_decoding_work_mem后,流式传输到解码输出插件的进行中事务数。流式传输仅适用于顶层事务(子事务不能单独进行流式传输),因此子事务不会使此计数器递增。 @@ -2590,7 +2450,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage stream_countbigint - 在为该槽位解码来自WAL的更改时,将正在进行的事务流式传输到解码输出插件的次数。 + 在为该槽解码来自WAL的更改时,将进行中事务流式传输到解码输出插件的次数。 此计数器在每次事务流式传输时递增,并且同一事务可能被流式传输多次。 @@ -2600,8 +2460,8 @@ description | Waiting for a newly initialized WAL file to reach durable storage stream_bytesbigint - 在为该槽位解码来自WAL的更改时,为将正在进行的事务流式传输到解码输出插件而解码的事务数据的数量。 - 这个和针对此槽位的其他流式传输计数器可用于调优logical_decoding_work_mem。 + 在为该槽解码来自WAL的更改时,为将进行中事务流式传输到解码输出插件而解码的事务数据量。 + 这个和针对此槽的其他流式传输计数器可用于调优logical_decoding_work_mem @@ -2612,7 +2472,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage 针对此槽的,发送到解码输出插件的已解码事务数。 - 这只计算顶级事务,对子事务不会增加。 + 这只计算顶层事务,对子事务不会增加。 注意,这包括流式传输和/或溢出的事务。 @@ -2622,7 +2482,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage total_bytesbigint - 在对此槽位的WAL进行解码时,为将事务发送到解码输出插件而解码的事务数据量。 + 在为此槽从 WAL 解码更改时,为将事务发送到解码输出插件而解码的事务数据量。 注意这包括流式传输和/或溢出的数据。 @@ -2632,9 +2492,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage stats_reset timestamp with time zone - - 这些统计最后重置的时间 - + 这些统计信息上次被重置的时间 @@ -2649,9 +2507,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage pg_stat_wal_receiver - - pg_stat_wal_receiver事务只包含一行,它显示了从 WAL 接收进程所连接的服务器得到的有关该接收进程的统计信息。 - + pg_stat_wal_receiver视图只包含一行,显示 WAL 接收进程从其所连接服务器接收数据的统计信息。 @@ -2676,7 +2532,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage pidinteger - WAL 接收进程的进程ID + WAL 接收进程的进程 ID @@ -2685,7 +2541,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage statustext - WAL接收进程的活动状态 + WAL 接收进程的活动状态 @@ -2694,7 +2550,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage receive_start_lsnpg_lsn - WAL 接收进程启动时使用的第一个写前日志位置 + WAL 接收进程启动时使用的第一个预写式日志位置 @@ -2703,7 +2559,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage receive_start_tliinteger - WAL 接收进程启动时使用的第一个时间线数字 + WAL 接收进程启动时使用的第一个时间线编号 @@ -2712,7 +2568,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage written_lsnpg_lsn - 已经接收并写入磁盘的最后一个预写式日志位置,但没有刷入。这不能用于数据完整性检查。 + 已经接收并写入磁盘的最后一个预写式日志位置,但尚未刷盘。此字段不应用于数据完整性检查。 @@ -2721,7 +2577,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage flushed_lsnpg_lsn - 已经接收并刷入到磁盘的最后一个预写式日志位置,该字段的初始值是启动WAL 接收进程时使用的第一个日志位置 + 已经接收并刷入到磁盘的最后一个预写式日志位置,该字段的初始值是启动 WAL 接收进程时使用的第一个日志位置 @@ -2730,7 +2586,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage received_tliinteger - 接收并刷入到磁盘的最后一个预写式日志位置的时间线数字,该字段的初始值为启动WAL 接收进程时使用的第一个日志位置的时间线数字 + 接收并刷入到磁盘的最后一个预写式日志位置的时间线编号,该字段的初始值为启动 WAL 接收进程时使用的第一个日志位置的时间线编号 @@ -2775,7 +2631,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage slot_nametext - 这个WAL 接收进程使用的复制槽的名称 + 这个 WAL 接收进程使用的复制槽的名称 @@ -2784,8 +2640,8 @@ description | Waiting for a newly initialized WAL file to reach durable storage sender_hosttext - 这个WAL 接收进程连接到的PostgreSQL实例的主机。 - 这可以是主机名、IP地址,或者目录路径,如果连接是通过Unix套接字进行的。(路径的情况可以区分,因为它总是以/开头的绝对路径。) + 这个 WAL 接收进程连接到的PostgreSQL实例的主机。 + 这可以是主机名、IP地址,或者目录路径,如果连接是通过Unix套接字进行的。(路径的情况可以区分,因为它总是以/开头的绝对路径。) @@ -2794,7 +2650,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage sender_portinteger - 这个WAL 接收进程连接的PostgreSQL实例的端口号。 + 这个 WAL 接收进程连接的PostgreSQL实例的端口号。 @@ -2803,7 +2659,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage conninfotext - 这个WAL 接收进程使用的连接字符串,对安全敏感的字段进行了模糊处理。 + 这个 WAL 接收进程使用的连接字符串,对安全敏感的字段进行了模糊处理。 @@ -2812,152 +2668,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - - <structname>pg_stat_recovery_prefetch</structname> - - - pg_stat_recovery_prefetch - - - - pg_stat_recovery_prefetch视图将只包含一行。 - wal_distanceblock_distance和 - io_depth列显示当前值,其他列显示可以使用 - pg_stat_reset_shared函数重置的累积计数器。 - - -
- - <structname>pg_stat_recovery_prefetch</structname> 视图 - - - - - - 列类型 - - - 描述 - - - - - - - - - - stats_reset timestamp with time zone - - - 这些统计数据上次重置的时间 - - - - - - - - prefetch bigint - - - 因为不在缓冲池中,所以预取的块数 - - - - - - - - hit bigint - - - 因为它们已经在缓冲池中,所以未预取的块数 - - - - - - - - skip_init bigint - - - 未预取的块数,因为它们将被初始化为零 - - - - - - - - skip_new bigint - - - 未预取的块数,因为它们尚不存在 - - - - - - - - skip_fpw bigint - - - 由于WAL中包含整页镜像而未预取的块数 - - - - - - - - skip_rep bigint - - - 由于最近已经预取过而未预取的块数 - - - - - - - - wal_distance int - - - 预取器向前查看多少字节 - - - - - - - - block_distance int - - - 预取器正在查看多少个块之前 - - - - - - - - io_depth int - - - 已启动但尚未完成的预取数量 - - - - - -
- <structname>pg_stat_subscription</structname> @@ -2966,6 +2677,8 @@ description | Waiting for a newly initialized WAL file to reach durable storage pg_stat_subscription + pg_stat_subscription视图为每个订阅的主工作进程包含一行(如果该工作进程未运行,则 PID 为空),并为处理订阅表初始数据复制的工作进程包含额外的行。 + <structname>pg_stat_subscription</structname> 视图 @@ -2993,7 +2706,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + subname name @@ -3002,43 +2715,34 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + - worker_type text + pid integer - 订阅工作进程的类型。可能的类型有 applyparallel applytable synchronization。 + 订阅工作进程的进程 ID - + - pid integer + relid oid - 订阅工作进程的进程 ID + 该工作进程正在同步的关系的 OID;主应用工作进程则为 空值 - - - relid oid - - - 该工作进程正在同步的关系的 OID;主应用工作进程则为 NULL - - - - + received_lsn pg_lsn - 接收到的最后一个预写式日志位置,该字段的初始值为0 + 接收到的最后一个预写式日志位置,该字段的初始值为 0 - + last_msg_send_time timestamp with time zone @@ -3047,7 +2751,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + last_msg_receipt_time timestamp with time zone @@ -3056,7 +2760,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + latest_end_lsn pg_lsn @@ -3065,98 +2769,22 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + latest_end_time timestamp with time zone - 向 WAL 发送进程报告最后一个预写式日志位置的时间 + 向源 WAL 发送进程报告最后一个预写式日志位置的时间 +
- - <structname>pg_stat_subscription_stats</structname> - - - pg_stat_subscription_stats - - - - pg_stat_subscription_stats视图将包含每个订阅的一行。 - - - - -<structname>pg_stat_subscription_stats</structname> 视图 - - - - - - 列类型 - - - 描述 - - - - - - - - - subid oid - - - 订阅的OID - - - - - - subname name - - - 订阅的名称 - - - - - - apply_error_count bigint - - - 应用更改时发生错误的次数 - - - - - sync_error_count bigint - - - 在初始表同步期间发生错误的次数 - - - - - - stats_reset timestamp with time zone - - - 这些统计数据最后一次重置的时间 - - - - -
- -
<structname>pg_stat_ssl</structname> @@ -3211,7 +2839,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage version text - 使用SSL的版本,如果此连接上没有使用SSL则为NULL + 使用SSL的版本,如果此连接上没有使用SSL则为空值
@@ -3220,7 +2848,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage cipher text - 正在使用的SSL密码的名称,如果此连接上没有使用SSL则为NULL + 正在使用的SSL 密码套件的名称,如果此连接上没有使用SSL则为空值
@@ -3229,7 +2857,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage bits integer - 使用的加密算法中的位数,如果此连接上没有使用SSL则为NULL + 使用的加密算法中的位数,如果此连接上没有使用SSL则为空值
@@ -3238,8 +2866,8 @@ description | Waiting for a newly initialized WAL file to reach durable storage client_dn text - 区别名称(DN,Distinguished Name)字段与使用的客户端证书,如果没有提供客户端证书或在此连接上没有使用SSL,则为NULL。 - 如果DN字段长于NAMEDATALEN(标准构建中为64个字符),则该字段将被截断。 + 所用客户端证书中的区别名称(DN,Distinguished Name)字段,如果没有提供客户端证书或在此连接上没有使用SSL,则为空值。 + 如果DN字段长于NAMEDATALEN(标准构建中为64个字符),则该字段将被截断。
@@ -3248,8 +2876,8 @@ description | Waiting for a newly initialized WAL file to reach durable storage client_serial numeric - 客户端证书的序列号,如果没有提供客户端证书或在此连接上没有使用SSL,则为NULL。 - 证书序列号和证书颁发者的组合唯一标识一个证书(除非颁发者错误地重用序列号)。 + 客户端证书的序列号,如果没有提供客户端证书或在此连接上没有使用SSL,则为空值。 + 证书序列号和证书颁发者的组合唯一标识一个证书(除非颁发者错误地重用序列号)。
@@ -3258,7 +2886,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage issuer_dn text - 客户端证书颁发者的区别名称(DN,Distinguished Name),如果没有提供客户端证书或在此连接上没有使用SSL,则为NULL。该字段像client_dn一样被截断。 + 客户端证书颁发者的区别名称(DN,Distinguished Name),如果没有提供客户端证书或在此连接上没有使用SSL,则为空值。该字段像client_dn一样被截断。
@@ -3276,7 +2904,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage pg_stat_gssapi视图将包含每一个后端一个行,显示该连接上的GSSAPI使用情况。 - 它可以加入到pg_stat_activitypg_stat_replication上的pid列,获取更多关于连接的详细信息。 + 可以通过pid列将它与pg_stat_activitypg_stat_replication连接,获取更多关于连接的详细信息。 @@ -3320,8 +2948,8 @@ description | Waiting for a newly initialized WAL file to reach durable storage principaltext - 用于验证此连接的主体,如果未使用GSSAPI对此连接进行认证,则为NULL。 - 如果主体长度超过NAMEDATALEN(标准构建中为64个字符),则该字段被截断。 + 用于认证此连接的主体,如果未使用GSSAPI对此连接进行认证,则为空值。 + 如果主体长度超过NAMEDATALEN(标准构建中为64个字符),则该字段被截断。 @@ -3334,14 +2962,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - - - credentials_delegated boolean - - - 如果此连接上已委派 GSSAPI 凭据,则为真 - - +
@@ -3435,362 +3056,17 @@ description | Waiting for a newly initialized WAL file to reach durable storage stats_reset timestamp with time zone - - 这些统计数据最后一次重置的时间 - + 这些统计信息上次被重置的时间
- - 通常,WAL 文件会按从最旧到最新的顺序归档,但这并无保证,也不适用于某些特殊情况,例如备库提升或崩溃恢复之后。因此,不能安全地假设所有早于 - last_archived_wal的文件也已成功归档。 - - - - - - <structname>pg_stat_io</structname> - - - pg_stat_io - - - - pg_stat_io 视图对每种后端类型、目标 I/O 对象和 I/O 上下文的组合各提供一行,显示整个集簇范围内的 I/O 统计信息。没有意义的组合会被省略。 - - - - 目前会跟踪关系(例如表、索引)的 I/O 以及 WAL 活动。不过,绕过共享缓冲区的关系 I/O(例如将表从一个表空间移动到另一个表空间时)目前不会被跟踪。 - - - - <structname>pg_stat_io</structname> 视图 - - - - - - 列类型 - - - 描述 - - - - - - - - - backend_type text - - - 后端类型(例如后台工作进程、autovacuum 工作进程)。有关 backend_type 的更多信息,请参阅pg_stat_activity。某些 backend_type 不会累计 I/O 操作统计信息,因此不会出现在该视图中。 - - - - - - - - object text - - - I/O 操作的目标对象。可能的值有: - - - - - relation:永久关系。 - - - - - temp relation:临时关系。 - - - - - wal:预写式日志。 - - - - - - - - - - context text - - - I/O 操作的上下文。可能的值有: - - - - - normal:某类 I/O 操作的默认或标准 context。例如,默认情况下关系数据会读入共享缓冲区并从共享缓冲区写出,因此关系数据与共享缓冲区之间的读写会在 contextnormal 时跟踪。 - - - - - init:创建 WAL 段时执行的 I/O 操作会在 contextinit 时跟踪。 - - - - - vacuum:对永久关系执行 vacuum 和 analyze 时,在共享缓冲区之外执行的 I/O 操作。临时表 vacuum 与其他临时表 I/O 操作共用同一本地缓冲池,因此会在 contextnormal 时跟踪。 - - - - - bulkread:某些在共享缓冲区之外执行的大型读取 I/O 操作,例如对大表的顺序扫描。 - - - - - bulkwrite:某些在共享缓冲区之外执行的大型写入 I/O 操作,例如 COPY。 - - - - - - - - - - reads bigint - - - 读取操作的数量。 - - - - - - - read_bytes numeric - - - 读取操作的总大小(以字节为单位)。 - - - - - - - - read_time double precision - - - 等待读取操作所花费的时间,以毫秒计(如果启用了 object 不是 wal,或者启用了 objectwal;否则为零)。 - - - - - - - writes bigint - - - 写入操作的数量。 - - - - - - - - write_bytes numeric - - - 写入操作的总大小(以字节为单位)。 - - - - - - - - write_time double precision - - - 等待写入操作所花费的时间,以毫秒计(如果启用了 object 不是 wal,或者启用了 objectwal;否则为零)。 - - - - - - - - writebacks bigint - - - 进程请求内核写出到永久存储的、大小为 BLCKSZ(通常为 8kB)的单位数量。 - - - - - - - - writeback_time double precision - - - 等待写回操作所花费的时间,以毫秒计(如果启用了 ,否则为零)。这包括排队写出请求所花费的时间,以及可能实际写出脏数据所花费的时间。 - - - - - - - - extends bigint - - - 关系扩展操作的数量。 - - - - - - - - extend_bytes numeric - - - 关系扩展操作的总大小(以字节为单位)。 - - - - - - - - extend_time double precision - - - 等待扩展操作所花费的时间,以毫秒计(如果启用了 object 不是 wal,或者启用了 objectwal;否则为零)。 - - - - - - - - hits bigint - - - 在共享缓冲区中找到所需块的次数。 - - - - - - - - evictions bigint - - - 为了腾出空间供其他用途而将块从共享或本地缓冲区写出的次数。 - - - 在 contextnormal 时,这会统计块从缓冲区中被驱逐并由另一个块替换的次数。在 contextbulkwritebulkreadvacuum 时,这会统计块从共享缓冲区中被驱逐,从而把该共享缓冲区加入到单独的、大小受限的环形缓冲区中以供批量 I/O 操作使用的次数。 - - - - - - - - reuses bigint - - - 在 bulkreadbulkwritevacuum 这些 context 中,作为 I/O 操作一部分,位于共享缓冲区之外的大小受限环形缓冲区中已有缓冲区被重用的次数。 - - - - - - - - fsyncs bigint - - - fsync 调用次数。这些只会在 contextnormal 时被跟踪。 - - - - - - - - fsync_time double precision - - - 等待 fsync 操作所花费的时间,以毫秒计(如果启用了 object 不是 wal,或者启用了 objectwal;否则为零)。 - - - - - - - - stats_reset timestamp with time zone - - - 这些统计信息上次被重置的时间。 - - - - - -
- - - 某些后端类型永远不会对某些 I/O 对象和/或在某些 I/O 上下文中执行 I/O 操作,这些行会从视图中省略。例如,检查点进程不会对临时表执行检查点,因此不会出现 backend_typecheckpointerobjecttemp relation 的行。 - - - - 此外,某些 I/O 操作永远不会由某些后端类型执行,或者永远不会针对某些 I/O 对象和/或在某些 I/O 上下文中执行。这些单元格会是 NULL。例如,临时表不会执行 fsync,因此当 objecttemp relation 时,fsyncs 将为 NULL。又如,后台写入器不会执行读取,因此当 backend_typebackground writer 时,reads 将为 NULL。 - - - - 对于 objectwal 的行,fsyncsfsync_time 跟踪在 issue_xlog_fsync 中完成的 WAL 文件 fsync 活动;writeswrite_time 跟踪在 XLogWrite 中完成的 WAL 文件写入活动。更多信息请参阅。 - - - - pg_stat_io 可用于指导数据库调优。例如: - - - - 较高的 evictions 计数可能表明应增大共享缓冲区。 - - - - - 客户端后端依赖检查点进程确保数据持久化到永久存储。客户端后端出现大量 fsyncs 可能表明共享缓冲区或检查点进程配置不当。有关配置检查点进程的更多信息,请参阅。 - - - - - 通常,客户端后端应尽可能依赖检查点进程和后台写入器等辅助进程去写出脏数据。客户端后端出现大量写入可能表明共享缓冲区或检查点进程配置不当。有关配置检查点进程的更多信息,请参阅。 - - - - +
- - - 跟踪 I/O 等待时间的列只有在启用 时才会非零。若自上次统计信息重置以来的整个时间段内并未始终启用 track_io_timing,则用户在将这些列与对应的 I/O 操作结合引用时应格外小心。 - - - <structname>pg_stat_bgwriter</structname> @@ -3800,7 +3076,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - pg_stat_bgwriter 视图始终只有一行,包含有关集簇后台写入器的数据。 + pg_stat_bgwriter 视图始终只有一行,包含整个集簇的全局数据。 @@ -3820,158 +3096,77 @@ description | Waiting for a newly initialized WAL file to reach durable storage - buffers_clean bigint + checkpoints_timed bigint - - 后台写入器写入的缓冲区数量 - + 已执行的计划检查点数 - maxwritten_clean bigint + checkpoints_req bigint - - 后台写入器因写入了过多缓冲区而停止清理扫描的次数 - + 已执行的请求检查点数 - buffers_alloc bigint + checkpoint_write_time double precision - - 分配的缓冲区数量 - + 检查点处理中将文件写入磁盘部分所花费的总时间,单位为毫秒 - stats_reset timestamp with time zone + checkpoint_sync_time double precision - - 这些统计信息上次被重置的时间 - + 检查点处理中将文件同步到磁盘部分所花费的总时间,单位为毫秒 - - -
-
- - - <structname>pg_stat_checkpointer</structname> - - - pg_stat_checkpointer - - - - pg_stat_checkpointer 视图始终只有一行,包含有关集簇检查点进程的数据。 - - - - <structname>pg_stat_checkpointer</structname> 视图 - - - 列类型 + buffers_checkpoint bigint - - 描述 - + 检查点期间写入的缓冲区数 - - - num_timed bigint - - - 因超时而安排的检查点数量 - - - - - - num_requested bigint - - - 被请求执行的检查点数量 - - - - - - num_done bigint - - - 已执行的检查点数量 - - - - - - restartpoints_timed bigint - - - 因超时或上次尝试执行失败后而安排的重启点数量 - - - - - - restartpoints_req bigint - - - 被请求执行的重启点数量 - - - - - - restartpoints_done bigint + buffers_clean bigint - 已执行的重启点数量 + 后台写入器写入的缓冲区数量 - write_time double precision + maxwritten_clean bigint - 处理检查点和重启点时,将文件写入磁盘阶段所花费的总时间,以毫秒计 + 后台写入器因写入了过多缓冲区而停止清理扫描的次数 - sync_time double precision + buffers_backend bigint - - 处理检查点和重启点时,将文件同步到磁盘阶段所花费的总时间,以毫秒计 - + 后端直接写入的缓冲区数 - buffers_written bigint + buffers_backend_fsync bigint - - 在检查点和重启点期间写入的共享缓冲区数量 - + 后端必须自行执行fsync调用的次数(通常即使后端自行写入,也由后台写入器处理这些调用) - slru_written bigint + buffers_alloc bigint - 在检查点和重启点期间写入的 SLRU 缓冲区数量 + 分配的缓冲区数量 @@ -3979,20 +3174,16 @@ description | Waiting for a newly initialized WAL file to reach durable storage stats_reset timestamp with time zone - - 这些统计信息上次被重置的时间 - + 这些统计信息上次被重置的时间
- - 如果服务器自上次检查点以来一直处于空闲状态,则检查点可能会被跳过。num_timednum_requested 统计的是已完成和已跳过的检查点,而 num_done 只跟踪实际完成的检查点。类似地,如果最后一个重放的检查点记录已经是最后一个重启点,则重启点也可能被跳过。restartpoints_timedrestartpoints_req 统计的是已完成和已跳过的重启点,而 restartpoints_done 只跟踪实际完成的重启点。 - -
+ + <structname>pg_stat_wal</structname> @@ -4045,7 +3236,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage wal_bytes numeric - 生成的WAL总数,以字节计 + 生成的 WAL 总量,以字节计
@@ -4054,7 +3245,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage wal_buffers_full bigint - 因为缓冲区已满,WAL数据被写入磁盘的次数 + 因为 WAL 缓冲区已满,WAL 数据被写入磁盘的次数
@@ -4073,7 +3264,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage wal_sync bigint - 通过issue_xlog_fsync 请求将WAL文件同步到磁盘的次数(如果onfdatasync, fsyncfsync_writethrough,否则为零)。 + 通过issue_xlog_fsync 请求将WAL文件同步到磁盘的次数(如果onfdatasyncfsyncfsync_writethrough,否则为零)。 有关内部WAL函数issue_xlog_fsync的更多信息,参见
@@ -4083,7 +3274,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage wal_write_time double precision - 通过XLogWrite请求将WAL缓冲区写入磁盘所消耗的总时间,以毫秒计(如果是启用的,否则为零)。 + 通过XLogWrite请求将WAL缓冲区写入磁盘所消耗的总时间,以毫秒计(如果是启用的,否则为零)。 这包括当wal_sync_methodopen_datasyncopen_sync时的同步时间。
@@ -4093,7 +3284,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage wal_sync_time double precision - 通过issue_xlog_fsync请求将WAL文件同步到磁盘所消耗的总时间,以毫秒计(如果 track_wal_io_timing 被启用,fsync is on, 和 wal_sync_methodfdatasync, fsyncfsync_writethrough, 否则为零). + 通过 issue_xlog_fsync 请求将 WAL 文件同步到磁盘所花费的总时间,以毫秒计(如果启用了 track_wal_io_timingfsyncon,且 wal_sync_methodfdatasyncfsyncfsync_writethrough,否则为零)。
@@ -4101,9 +3292,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage stats_reset timestamp with time zone - - 这些统计数据最后一次重置的时间 - + 这些统计信息上次被重置的时间
@@ -4149,7 +3338,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage
- + datname name @@ -4158,7 +3347,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + numbackends integer @@ -4168,7 +3357,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + xact_commit bigint @@ -4177,7 +3366,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + xact_rollback bigint @@ -4186,7 +3375,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + blks_read bigint @@ -4195,7 +3384,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + blks_hit bigint @@ -4204,25 +3393,25 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + tup_returned bigint - 由顺序扫描获取的活动行数和由索引扫描返回的索引条目数 + 此数据库中的查询返回的行数 - + tup_fetched bigint - 该数据库中由索引扫描检索的活动行数 + 此数据库中的查询获取的行数 - + tup_inserted bigint @@ -4231,7 +3420,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + tup_updated bigint @@ -4240,7 +3429,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + tup_deleted bigint @@ -4249,7 +3438,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + conflicts bigint @@ -4258,7 +3447,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + temp_files bigint @@ -4267,7 +3456,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + temp_bytes bigint @@ -4276,7 +3465,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + deadlocks bigint @@ -4285,7 +3474,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + checksum_failures bigint @@ -4294,7 +3483,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + checksum_last_failure timestamp with time zone @@ -4303,7 +3492,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + blk_read_time double precision @@ -4312,34 +3501,16 @@ description | Waiting for a newly initialized WAL file to reach durable storage - - - blk_write_time double precision - - - 在这个数据库中通过后端写数据文件块所花费的时间,以毫秒为单位(如果启用了,否则为零) - - - - - - parallel_workers_to_launch bigint - - - 计划由该数据库上的查询启动的并行工作进程数 - - - - + - parallel_workers_launched bigint + blk_write_time double precision - 由该数据库上的查询启动的并行工作进程数 + 在这个数据库中通过后端写数据文件块所花费的时间,以毫秒为单位(如果启用了,否则为零) - + session_time double precision @@ -4348,7 +3519,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + active_time double precision @@ -4357,7 +3528,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + idle_in_transaction_time double precision @@ -4366,7 +3537,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + sessions bigint @@ -4375,7 +3546,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + sessions_abandoned bigint @@ -4384,7 +3555,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + sessions_fatal bigint @@ -4393,7 +3564,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + sessions_killed bigint @@ -4402,7 +3573,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + stats_reset timestamp with time zone @@ -4410,6 +3581,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage 这些统计数据最后一次重置的时间 + @@ -4496,7 +3668,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage confl_bufferpin bigint - 此数据库中由于固定缓冲区而被取消的查询数 + 此数据库中由于缓冲区被钉住而被取消的查询数 @@ -4509,14 +3681,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - - - confl_active_logicalslot bigint - - - 此数据库中因旧快照或主库上的 太低而被取消的逻辑槽使用次数 - - + @@ -4589,21 +3754,14 @@ description | Waiting for a newly initialized WAL file to reach durable storage - - - last_seq_scan timestamp with time zone - - - 此表上最后一次顺序扫描的时间,基于最近的事务停止时间 - - + seq_tup_read bigint - 连续扫描获取的实时行数 + 顺序扫描获取的存活行数 @@ -4616,21 +3774,14 @@ description | Waiting for a newly initialized WAL file to reach durable storage - - - last_idx_scan timestamp with time zone - - - 此表上最后一次索引扫描的时间,基于最近的事务停止时间 - - + idx_tup_fetch bigint - 索引扫描获取的实时行数 + 索引扫描获取的存活行数 @@ -4666,18 +3817,11 @@ description | Waiting for a newly initialized WAL file to reach durable storage n_tup_hot_upd bigint - HOT更新的行数(即,不需要单独的索引更新) + HOT 更新的行数(即不需要单独更新索引) - - - n_tup_newpage_upd bigint - - - 更新的行数,其中后继版本转到新的堆页,留下一个原始版本,其t_ctid字段指向不同的堆页。这些始终是非 HOT 更新。 - - + @@ -4720,7 +3864,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage last_vacuum timestamp with time zone - 最后一次手动清理这个表(不包括VACUUM FULL) + 最后一次手动清理这个表的时间(不包括VACUUM FULL @@ -4738,7 +3882,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage last_analyze timestamp with time zone - 上一次手动分析这个表 + 上一次手动分析这个表的时间 @@ -4747,7 +3891,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage last_autoanalyze timestamp with time zone - 自动清理守护进程最后一次分析这个表 + 自动清理守护进程最后一次分析这个表的时间 @@ -4756,7 +3900,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage vacuum_count bigint - 这个表被手动清理的次数(VACUUM FULL不计数) + 这个表被手动清理的次数(VACUUM FULL不计数) @@ -4787,41 +3931,13 @@ description | Waiting for a newly initialized WAL file to reach durable storage - - - total_vacuum_time double precision - - - 手动 VACUUM 此表所花费的总时间,以毫秒计(不包括 VACUUM FULL)。(这包括由于基于成本的延迟而睡眠的时间。) - - - - - total_autovacuum_time double precision - - - 自动清理守护进程对该表执行 VACUUM 所花费的总时间,以毫秒计。(这包括由于基于成本的延迟而睡眠的时间。) - - - - - total_analyze_time double precision - - - 手动分析该表所花费的总时间,以毫秒计。(这包括由于基于成本的延迟而睡眠的时间。) - - - - - total_autoanalyze_time double precision - - - 自动清理守护进程分析该表所花费的总时间,以毫秒计。(这包括由于基于成本的延迟而睡眠的时间。) - - + + + + @@ -4911,14 +4027,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - - - last_idx_scan timestamp with time zone - - - 此索引上最后一次扫描的时间,基于最近的事务停止时间 - - + @@ -4934,7 +4043,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage idx_tup_fetch bigint - 使用此索引进行简单索引扫描获取的活动表行数 + 使用此索引进行简单索引扫描获取的存活表行数 @@ -4942,13 +4051,13 @@ description | Waiting for a newly initialized WAL file to reach durable storage - 索引可以被简单索引扫描、位图索引扫描以及优化器使用。在一次位图扫描中,多个索引的输出可以被通过 AND 或 OR 规则组合,因此当使用一次位图扫描时难以将取得的个体堆行与特定的索引关联起来。因此,一次位图扫描会增加它使用的索引的pg_stat_all_indexes.idx_tup_read计数,并且为每个表增加pg_stat_all_tables.idx_tup_fetch计数,但是它不影响pg_stat_all_indexes.idx_tup_fetch。如果所提供的常量值不在优化器统计信息记录的范围之内,优化器也会访问索引来检查,因为优化器统计信息可能已经“不新鲜”了。 + 索引可以被简单索引扫描、位图索引扫描以及优化器使用。在一次位图扫描中,多个索引的输出可以被通过 AND 或 OR 规则组合,因此当使用一次位图扫描时难以将取得的个体堆行与特定的索引关联起来。因此,一次位图扫描会增加它使用的索引的pg_stat_all_indexes.idx_tup_read计数,并且为该表增加pg_stat_all_tables.idx_tup_fetch计数,但是它不影响pg_stat_all_indexes.idx_tup_fetch。如果所提供的常量值不在优化器统计信息记录的范围之内,优化器也会访问索引来检查,因为优化器统计信息可能已经过时。 - 即使不用位图扫描,idx_tup_readidx_tup_fetch计数也可能不同,因为idx_tup_read统计从该索引取得的索引项而idx_tup_fetch统计从表取得的活着的行。如果使用该索引取得了任何死亡行或还未提交的行,或者如果通过一次只用索引扫描的方式避免了任何堆获取,后者将较小。 + 即使不用位图扫描,idx_tup_readidx_tup_fetch计数也可能不同,因为idx_tup_read统计从该索引取得的索引项而idx_tup_fetch统计从表取得的存活行。如果使用该索引取得了任何死亡行或还未提交的行,或者如果通过一次仅索引扫描的方式避免了任何堆获取,后者将较小。 @@ -5051,7 +4160,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage toast_blks_read bigint - 从这个表的TOAST表中读取的磁盘块的数量(如果有的话) + 从这个表的TOAST表中读取的磁盘块的数量(如果有的话) @@ -5060,7 +4169,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage toast_blks_hit bigint - 这个表的TOAST表中的缓冲区命中数(如果有的话) + 这个表的TOAST表中的缓冲区命中数(如果有的话) @@ -5069,7 +4178,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage tidx_blks_read bigint - 从这个表的TOAST表索引中读取的磁盘块的数量(如果有的话) + 从这个表的TOAST表索引中读取的磁盘块的数量(如果有的话) @@ -5078,7 +4187,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage tidx_blks_hit bigint - 这个表的TOAST表索引中的缓冲区命中数(如果有的话) + 这个表的TOAST表索引中的缓冲区命中数(如果有的话) @@ -5365,7 +4474,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - PostgreSQL通过SLRU(simple least-recently-used,简单的最近-最少-使用)缓存访问某些磁盘上的信息。 + PostgreSQL通过SLRU(simple least-recently-used,简单最近最少使用)缓存访问某些磁盘上的信息。 pg_stat_slru视图将为每个被跟踪的SLRU缓存包含一行,显示关于访问缓存页面的统计信息。 @@ -5410,7 +4519,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage blks_hit bigint - 已经在SLRU中的磁盘块被发现的次数,因此不需要读取(这只包括SLRU中的命中,而不是操作系统的文件系统缓存) + 已经在SLRU中的磁盘块被发现的次数,因此不需要读取(这只包括SLRU中的命中,而不是操作系统的文件系统缓存) @@ -5446,7 +4555,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage flushes bigint - 此SLRU的脏数据刷新数 + 此SLRU的脏数据刷盘次数 @@ -5455,7 +4564,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage truncates bigint - 这个SLRU的截断数 + 这个SLRU的截断次数 @@ -5463,9 +4572,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage stats_reset timestamp with time zone - - 这些统计数据最后一次重置的时间 - + 这些统计信息上次被重置的时间 @@ -5517,21 +4624,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - - - - pg_stat_get_backend_io - - pg_stat_get_backend_io ( integer ) - setof record - - - 返回指定进程 ID 的后端的 I/O 统计信息。输出字段与 pg_stat_io 视图中的字段完全相同。 - - - 该函数不会返回检查点进程、后台写入器、启动进程和 自动清理启动器的 I/O 统计信息,因为这些统计信息已经在 pg_stat_io 视图中可见,而且每种都只有一个。 - - + @@ -5547,21 +4640,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - - - - pg_stat_get_backend_wal - - pg_stat_get_backend_wal ( integer ) - record - - - 返回指定进程 ID 的后端的 WAL 统计信息。输出字段与 pg_stat_wal 视图中的字段完全相同。 - - - 该函数不会返回检查点进程、后台写入器、启动进程和 自动清理启动器的 WAL 统计信息。 - - + @@ -5628,9 +4707,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage 将当前数据库的所有统计计数器重置为零。 - - 默认情况下该函数仅限于超级用户,但是其他用户可以被授予EXECUTE来运行此函数。 - + 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 @@ -5642,32 +4719,12 @@ description | Waiting for a newly initialized WAL file to reach durable storage void - 根据参数将一些集簇范围的统计计数器重置为零。参数可以是bgwriter, - 用于重置在pg_stat_bgwriter视图中显示的所有计数器, - archiver,用于重置在pg_stat_archiver视图中显示的所有计数器, - wal,用于重置在pg_stat_wal视图中显示的所有计数器, - 或recovery_prefetch,用于重置在pg_stat_recovery_prefetch视图中显示的所有计数器。 + 根据参数将一些集簇范围的统计计数器重置为零。参数可以为 bgwriter,用于重置 pg_stat_bgwriter 视图中显示的所有计数器;archiver,用于重置 pg_stat_archiver 视图中显示的所有计数器;或 wal,用于重置 pg_stat_wal 视图中显示的所有计数器。 - - 默认情况下,此函数仅限超级用户使用,但可以授予其他用户EXECUTE权限来运行该函数。 - + 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 - - - - pg_stat_reset_backend_stats - - pg_stat_reset_backend_stats ( integer ) - void - - - 将指定进程 ID 的单个后端进程的统计信息重置为零。 - - - 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 - - + @@ -5680,9 +4737,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage 重置当前数据库中的单个表或索引的统计信息,或者在集簇中跨所有数据库共享的统计信息为零。 - - 默认情况下,此函数仅限超级用户使用,但可以授予其他用户EXECUTE权限来运行该函数。 - + 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 @@ -5696,9 +4751,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage 将当前数据库中单个函数的统计信息重置为零。 - - 默认情况下该函数仅限于超级用户,但是其他用户可以被授予EXECUTE来运行此函数。 - + 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 @@ -5710,15 +4763,9 @@ description | Waiting for a newly initialized WAL file to reach durable storage void - 将单个SLRU缓存或集簇中所有SLRU的统计信息重置为零。 - 如果该参数为NULL,则所有SLRU缓存的pg_stat_slru视图中显示的计数器将被重置。 - 参数可以是CommitTsMultiXactMemberMultiXactOffsetNotify、 - SerialSubtrans、 或Xact中的一个,以便只重置该条目的计数器。 - 如果参数是other(或实际上,任何无法识别的名称),那么所有其他SLRU缓存的计数器,如扩展定义的缓存,将被重置。 + 将单个 SLRU 缓存或集簇中所有 SLRU 的统计信息重置为零。如果参数为空值,则重置 pg_stat_slru 视图中所有 SLRU 缓存的全部计数器。参数可以为 CommitTs、&zwsp;MultiXactMember、&zwsp;MultiXactOffset、&zwsp;Notify、&zwsp;Serial、&zwsp;SubtransXact 中的一个,以便只重置对应条目的计数器。如果参数为 other(实际上,任何无法识别的名称都可以),则重置其他所有 SLRU 缓存的计数器,例如扩展定义的缓存。 - - 默认情况下该函数仅限于超级用户,但是其他用户可以被授予EXECUTE来运行此函数。 - + 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 @@ -5733,27 +4780,10 @@ description | Waiting for a newly initialized WAL file to reach durable storage 重置由参数定义的复制槽的统计信息。 如果参数为NULL,则重置所有复制槽的统计信息。 - - 该函数默认仅限于超级用户,但可以授予其他用户EXECUTE权限来运行该函数。 - + 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 - - - - pg_stat_reset_subscription_stats - - pg_stat_reset_subscription_stats ( oid ) - void - - - 重置pg_stat_subscription_stats视图中显示的单个订阅的统计信息为零。 - 如果参数是NULL,则重置所有订阅的统计信息。 - - - 默认情况下,此函数仅限超级用户使用,但其他用户可以被授予EXECUTE权限来运行该函数。 - - + @@ -5832,7 +4862,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, pg_stat_get_backend_activity_start pg_stat_get_backend_activity_start ( integer ) - 有时区的时间戳 + timestamp with time zone 返回后端最近一次查询开始的时间。 @@ -5897,25 +4927,12 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, pg_stat_get_backend_start pg_stat_get_backend_start ( integer ) - 有时区的时间戳 + timestamp with time zone - - 返回该进程开始的时间。 - + 返回该进程开始的时间。 - - - - pg_stat_get_backend_subxact - - pg_stat_get_backend_subxact ( integer ) - record - - - 返回指定 ID 的后端进程的子事务信息记录。返回的字段包括 subxact_count(该后端进程子事务缓存中的子事务数量)以及 subxact_overflow(指示该后端进程的子事务缓存是否已溢出)。 - - + @@ -5939,7 +4956,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, text - 如果后端当前正在等待,则返回等待事件类型名称,否则返回NULL。 + 如果后端当前正在等待,则返回等待事件类型名称,否则返回空值。 请参阅 @@ -5953,7 +4970,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, text - 如果后端当前正在等待,则返回等待事件名称,否则为NULL。 + 如果后端当前正在等待,则返回等待事件名称,否则为空值。 请参阅 @@ -5964,7 +4981,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, pg_stat_get_backend_xact_start pg_stat_get_backend_xact_start ( integer ) - 有时区的时间戳 + timestamp with time zone 返回后端当前事务开始的时间。 @@ -5982,23 +4999,23 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, 查看锁 - lock - monitoring + + 监控 - 监控数据库活动的另外一个有用的工具是pg_locks系统表。这样就允许数据库管理员查看在锁管理器里面未解决的锁的信息。例如,这个功能可以被用于: + 监控数据库活动的另外一个有用的工具是pg_locks系统表。这样就允许数据库管理员查看锁管理器中当前存在的锁的信息。例如,这个功能可以被用于: - 查看当前所有未解决的锁、在一个特定数据库中的关系上所有的锁、在一个特定关系上所有的锁,或者由一个特定PostgreSQL会话持有的所有的锁。 + 查看当前存在的所有锁、在一个特定数据库中的关系上所有的锁、在一个特定关系上所有的锁,或者由一个特定PostgreSQL会话持有的所有的锁。 - 判断当前数据库中带有最多未授予锁的关系(它很可能是数据库客户端的竞争源)。 + 判断当前数据库中带有最多未授予锁的关系(它可能是数据库客户端之间的竞争来源)。 @@ -6160,14 +5177,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - - - delay_time double precision - - - 因基于成本的延迟而睡眠的总时间(参见),以毫秒计(如果启用了 ,否则为零)。 - - + @@ -6197,14 +5207,14 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, acquiring sample rows - 该命令当前正在扫描relid给出的表以获得样例行。 + 该命令当前正在扫描relid给出的表以获得样本行。 acquiring inherited sample rows - 该命令当前正在扫描子表以获得样例行。列child_tables_total,child_tables_done, + 该命令当前正在扫描子表以获得样本行。列child_tables_totalchild_tables_done、 和current_child_table_relid包含此阶段的进度信息。 @@ -6212,14 +5222,14 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, computing statistics - 该命令从表扫描期间获得的样例行计算统计信息。 + 该命令从表扫描期间获得的样本行计算统计信息。 computing extended statistics - 该命令从表扫描期间获得的样例行计算扩展统计信息。 + 该命令从表扫描期间获得的样本行计算扩展统计信息。 @@ -6235,10 +5245,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - - 注意当在分区表上运行ANALYZE时,它的所有分区也会被递归分析。 - 在这种情况下,首先报告父表的ANALYZE进度,收集它的继承统计信息,然后是每个分区的(继承统计信息)。 - + 请注意,当在分区表上运行ANALYZE时,其所有分区也会被递归分析。在这种情况下,会先报告父表的ANALYZE进度,并收集其继承统计信息,随后再报告每个分区的进度。 @@ -6323,8 +5330,8 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, command text - 在运行的命令: CREATE INDEX,CREATE INDEX CONCURRENTLY, - REINDEX, 或 REINDEX CONCURRENTLY. + 在运行的命令: CREATE INDEXCREATE INDEX CONCURRENTLY、 + REINDEXREINDEX CONCURRENTLY @@ -6341,27 +5348,21 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, lockers_total bigint - - 在适用的情况下,需要等待的储物柜总数 - + 在适用的情况下,需要等待的持锁进程总数。 lockers_done bigint - - 已经等待的储物柜数量。 - + 已完成等待的持锁进程数量。 current_locker_pid bigint - - 目前正在等待的储物柜的进程ID。 - + 当前正在等待的持锁进程的进程 ID。 @@ -6369,7 +5370,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, blocks_total bigint - 本阶段要处理的区块总数。 + 本阶段要处理的块总数。 @@ -6378,7 +5379,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, blocks_done bigint - 当前阶段已经处理的区块数量。 + 当前阶段已经处理的块数量。 @@ -6425,7 +5426,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - CREATE INDEX 的阶段 + CREATE INDEX 阶段 @@ -6439,70 +5440,70 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - 初始化 + initializing CREATE INDEXREINDEX正在准备创建索引。 这个阶段预计会非常短暂。 - 构建前等待读写器 + waiting for writers before build - CREATE INDEX CONCURRENTLYREINDEX CONCURRENTLY正在等待有可能看到表的写锁的事务完成。 当不在并发模式时,这个阶段会被跳过。lockers_totallockers_donecurrent_locker_pid 列包含了这个阶段的进度信息。 + CREATE INDEX CONCURRENTLYREINDEX CONCURRENTLY正在等待持有写锁且可能看到该表的事务结束。 当不在并发模式时,这个阶段会被跳过。lockers_totallockers_donecurrent_locker_pid 列包含了这个阶段的进度信息。 - 新建索引 + building index - 索引是由访问方法专用代码建立的。 在这一阶段,支持进度报告的访问方法填写自己的进度数据,子阶段在这一栏中表示。 通常情况下,blocks_totalblocks_done将包含进度数据,也可能包含tuples_totaltuples_done。 + 索引是由访问方法专用代码建立的。 在这一阶段,支持进度报告的访问方法填写自己的进度数据,子阶段在这一栏中表示。 通常情况下,blocks_totalblocks_done将包含进度数据,tuples_totaltuples_done也可能包含进度数据。 - 在验证前等待读写器 + waiting for writers before validation - CREATE INDEX CONCURRENTLYREINDEX CONCURRENTLY正在等待有可能写入表的事务完成写锁的事务。当不在并发模式时,这个阶段会被跳过。lockers_totallockers_donecurrent_locker_pid 列包含了这个阶段的进度信息。 + CREATE INDEX CONCURRENTLYREINDEX CONCURRENTLY正在等待持有写锁且可能写入该表的事务结束。当不在并发模式时,这个阶段会被跳过。lockers_totallockers_donecurrent_locker_pid 列包含了这个阶段的进度信息。 - 索引验证:扫描索引 + index validation: scanning index CREATE INDEX CONCURRENTLY正在扫描索引,搜索需要验证的元组。如果不是并发模式,则会跳过此阶段。列 blocks_total(设为索引总大小)和 blocks_done 包含该阶段的进度信息。 - 索引验证:排序元组 + index validation: sorting tuples CREATE INDEX CONCURRENTLY正在对索引扫描阶段的输出进行排序。 - 索引验证:扫描表 + index validation: scanning table CREATE INDEX CONCURRENTLY正在扫描表,以验证前两个阶段收集的索引元组。如果不是并发模式,则会跳过此阶段。blocks_total 列(设为表总大小)和 blocks_done 列包含该阶段的进度信息。 - 等待旧照 + waiting for old snapshots CREATE INDEX CONCURRENTLYREINDEX CONCURRENTLY正在等待可能看到表的事务释放快照。 当不处于并发模式时,这个阶段会被跳过。 lockers_totallockers_donecurrent_locker_pid 列包含了这个阶段的进度信息。 - 标记 dead之前等待readers + waiting for readers before marking dead REINDEX CONCURRENTLY等待表上有读锁的事务完成后,再将旧索引标记为死索引。当不在并发模式时,这个阶段被跳过。lockers_totallockers_donecurrent_locker_pid 列包含了这个阶段的进度信息。 - 在 dropping之前等待readers + waiting for readers before dropping REINDEX CONCURRENTLY等待表上有读锁的事务完成后,再丢弃旧索引。当不在并发模式时,这个阶段被跳过。列 lockers_totallockers_donecurrent_locker_pid包含了这个阶段的进度信息。 @@ -6575,7 +5576,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, relid oid - 被vacuum的表的OID。 + 正在清理的表的OID。 @@ -6584,7 +5585,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, phasetext - vacuum的当前处理阶段。参见 。 + 清理的当前处理阶段。参见 @@ -6593,7 +5594,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, heap_blks_totalbigint - 该表中堆块的总数。这个数字在扫描开始时报告,之后增加的块将不会(并且不需要)被这个VACUUM访问。 + 该表中堆块的总数。这个数字以扫描开始时的数量为准,之后增加的块将不会(并且不需要)被这个VACUUM访问。 @@ -6602,9 +5603,9 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, heap_blks_scannedbigint - 被扫描的堆块数量。由于visibility map被用来优化扫描,一些块将被跳过而不做检查, + 被扫描的堆块数量。由于可见性映射被用来优化扫描,一些块将被跳过而不做检查, 被跳过的块会被包括在这个总数中,因此当清理完成时这个数字最终将会等于heap_blks_total。 - 仅当处于扫描堆阶段时这个计数器才会前进。 + 仅当处于scanning heap阶段时这个计数器才会前进。 @@ -6613,7 +5614,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, heap_blks_vacuumedbigint - 被清理的堆块数量。除非表没有索引,这个计数器仅在处于清理堆阶段时才会前进。 + 被清理的堆块数量。除非表没有索引,这个计数器仅在处于vacuuming heap阶段时才会前进。 不包含死亡元组的块会被跳过,因此这个计数器可能有时会向前跳跃一个比较大的增量。 @@ -6629,64 +5630,40 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - max_dead_tuple_bytes bigint + max_dead_tuples bigint - 在需要执行索引清理周期之前可存储的死亡元组数据量,取决于。 + 在需要执行索引清理周期之前可存储的死亡元组数量,取决于 - dead_tuple_bytes bigint + num_dead_tuples bigint - 自上一个索引清理周期以来收集到的死亡元组数据量。 + 自上一个索引清理周期以来收集到的死亡元组数量。 - - - num_dead_item_ids bigint - - - 自上一个索引清理周期以来收集到的死项标识符数量。 - - - - - indexes_total bigint - - - 将要执行 vacuum 或清理的索引总数。该数字会在 vacuuming indexescleaning up indexes 阶段开始时报告。 - - - - - indexes_processed bigint - - - 已处理的索引数量。该计数器只会在 vacuuming indexescleaning up indexes 阶段推进。 - - - - - delay_time double precision - - - 因基于成本的延迟而睡眠的总时间(参见),以毫秒计(如果启用了 ,否则为零)。这包括任何相关并行工作进程的睡眠时间;不过,并行工作进程最多每秒才会上报一次自己的睡眠时间,因此该值可能略有滞后。 - - + + + + + + + +
- VACUUM的阶段 + VACUUM 阶段 @@ -6701,51 +5678,47 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - 初始化 + initializing VACUUM正在准备开始扫描堆。这个阶段应该很简短。 - 扫描堆 + scanning heap - VACUUM正在扫描堆。如果需要,它将会对每个页面进行修建以及碎片整理,并且可能会执行冻结动作。heap_blks_scanned列可以用来监控扫描的进度。 + VACUUM正在扫描堆。如果需要,它将会对每个页面进行剪枝以及碎片整理,并且可能会执行冻结动作。heap_blks_scanned列可以用来监控扫描的进度。 - 清理索引 - - VACUUM当前正在清理索引。 - 如果一个表拥有索引,那么每次清理时这个阶段会在堆扫描完成后至少发生一次。 - 如果不足以存放找到的死亡元组(或者, 在autovacuum情况下,如果设置了) ,则每次清理时会多次清理索引。 - + vacuuming indexes + VACUUM当前正在清理索引。如果表有索引,每次清理都会在堆扫描完成后至少执行一次此阶段。如果(或者,对于自动清理,已设置的)不足以存储找到的死亡元组数量,则每次清理可能多次执行此阶段。 - 清理堆 + vacuuming heap - VACUUM当前正在清理堆。清理堆与扫描堆不是同一个概念,清理堆发生在每一次清理索引的实例之后。如果heap_blks_scanned小于heap_blks_total,系统将在这个阶段完成之后回去扫描堆;否则,系统将在这个阶段完成后开始清理索引。 + VACUUM当前正在清理堆。清理堆与扫描堆不是同一个概念,清理堆发生在每次索引清理之后。如果heap_blks_scanned小于heap_blks_total,系统将在这个阶段完成之后回去扫描堆;否则,系统将在这个阶段完成后开始索引收尾清理。 - 清除索引 + cleaning up indexes - VACUUM当前正在清除索引。这个阶段发生在堆被完全扫描并且对堆和索引的所有清理都已经完成以后。 + VACUUM当前正在进行索引收尾清理。这个阶段发生在堆被完全扫描并且对堆和索引的所有清理都已经完成以后。 - 截断堆 + truncating heap - VACUUM正在截断堆,以便把关系尾部的空页面返还给操作系统。这个阶段发生在清除完索引之后。 + VACUUM正在截断堆,以便把关系尾部的空页面返还给操作系统。这个阶段发生在索引收尾清理完成之后。 - 执行最终清理 + performing final cleanup VACUUM正在执行最终清理。在此阶段,VACUUM将清理空闲空间映射, 更新pg_class中的统计信息,并向统计收集器报告统计信息。当此阶段完成时, @@ -6767,7 +5740,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - 每当CLUSTERVACUUM FULL运行时,pg_stat_progress_cluster视图将包含当前正在运行的每一个后台的记录。下面的表格描述了将被报告的信息,并提供了关于如何解释这些信息的信息。 + 每当CLUSTERVACUUM FULL运行时,pg_stat_progress_cluster视图将为每个当前正在运行这两种命令之一的后端包含一行。下面的表格描述了将被报告的信息,并提供了关于如何解释这些信息的信息。
@@ -6820,7 +5793,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, relidoid - 被集群的表的OID。 + 正在聚簇的表的OID。 @@ -6867,8 +5840,8 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, heap_tuples_writtenbigint - 写入的堆元组的数量。这个计数器只有在阶段为seq scanning heap,index scanning heap - 或 writing new heap时才会前进。 + 写入的堆元组的数量。这个计数器只有在阶段为seq scanning heapindex scanning heap + 或 writing new heap时才会递增。 @@ -6877,7 +5850,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, heap_blks_totalbigint - 表中的堆块总数。 这个数字是在seq scanning heap的开始时报告的。 + 表中的堆块总数。 这个数字以seq scanning heap开始时的数量为准。 @@ -6895,7 +5868,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, index_rebuild_countbigint - 已重建的索引数。该计数器仅在重建索引阶段时才会递增。 + 已重建的索引数。该计数器仅在rebuilding index阶段时才会递增。 @@ -6919,56 +5892,56 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - 初始化 + initializing - 该命令准备开始扫描堆栈。 这个阶段预计会非常短暂。 - + 命令正在准备开始扫描堆。这个阶段预计会非常短暂。 + - seq扫描堆 + seq scanning heap 该命令目前采用顺序扫描的方式对表进行扫描。 - 索引扫描堆 + index scanning heap CLUSTER目前正在使用索引扫描表。 - 元组排序 + sorting tuples CLUSTER目前正在对元组进行排序。 - 新写入堆 + writing new heap - CLUSTER目前正在编写新的堆。 + CLUSTER目前正在写入新的堆。 - 交换关系文件 + swapping relation files 目前,该命令正在将新建立的文件调换到位。 - 重建索引 + rebuilding index 该命令目前正在重建一个索引。 - 清理 + performing final cleanup 该命令正在执行最后的清理工作。 当此阶段完成后,CLUSTERVACUUM FULL将结束。 @@ -7036,7 +6009,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, 将被流式传输的数据总量。该值在streaming database files阶段开始时进行估算并报告。 注意,这只是一个近似值,因为数据库可能会在streaming database files阶段期间发生变化,而 WAL 日志也可能在稍后的备份阶段被包含进来。 一旦流式传输的数据量超过了估计的总大小,该值始终与backup_streamed相同。 - 如果在pg_basebackup中禁用估算(也就是说,指定了--no-estimate-size选项),这为NULL。 + 如果在pg_basebackup中禁用估算(也就是说,指定了--no-estimate-size选项),这为NULL @@ -7093,9 +6066,9 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - 等待检查点完成 + waiting for checkpoint to finish - WAL 发送进程当前正在执行pg_backup_start以准备进行基础备份,并等待备份起始检查点完成。 + WAL 发送进程当前正在执行pg_start_backup以准备进行基础备份,并等待备份起始检查点完成。 @@ -7114,9 +6087,9 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - 等待wal归档完成 + waiting for wal archiving to finish - WAL发送进程当前正在执行pg_backup_stop以完成备份, + WAL发送进程当前正在执行pg_stop_backup以完成备份, 并等待基础备份所需的所有 WAL 文件成功归档。 如果在pg_basebackup中指定了--wal-method=none--wal-method=stream,备份将在此阶段完成时结束。 @@ -7209,7 +6182,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, command text - 正在运行的命令: COPY FROM, 或 COPY TO。 + 正在运行的命令: COPY FROMCOPY TO @@ -7217,9 +6190,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, type text - - 数据被读取或写入的io类型:FILE, PROGRAM, PIPE (对于COPY FROM STDINCOPY TO STDOUT),或 CALLBACK(例如在逻辑复制中初始表同步期间使用)。 - + 读取或写入数据的 I/O 类型:FILEPROGRAMPIPE(用于COPY FROM STDINCOPY TO STDOUT),或CALLBACK(例如在逻辑复制的初始表同步期间使用)。 @@ -7259,14 +6230,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - - - tuples_skipped bigint - - - 因包含格式错误的数据而被跳过的元组数。只有当 ON_ERROR 选项指定的值不是 stop 时,此计数器才会递增。 - - +
@@ -7297,10 +6261,10 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - 动态追踪的编译 + 为动态追踪编译 - 默认情况下,探针是不可用的,因此你将需要显式地告诉配置脚本让探针在PostgreSQL中可用。要包括 DTrace 支持,在配置时指定。更多信息请见。 + 默认情况下,探针是不可用的,因此你将需要显式地告诉配置脚本让探针在PostgreSQL中可用。要包括 DTrace 支持,在配置时指定。更多信息请见 @@ -7309,7 +6273,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, 内置探针 - 如所示,源代码中提供了一些标准探针。显式了在探针中使用的类型。当然,可以增加更多探针来增强PostgreSQL的可观测性。 + 如所示,源代码中提供了一些标准探针。显示了在探针中使用的类型。当然,可以增加更多探针来增强PostgreSQL的可观测性。 @@ -7345,13 +6309,13 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, transaction-abort (LocalTransactionId) - 当一个事务失败完成时触发的探针。arg0 是事务 ID。 + 当一个事务失败结束时触发的探针。arg0 是事务 ID。 query-start (const char *) - 当一个查询的处理被开始时触发的探针。arg0 是查询字符串。 + 当一个查询的处理开始时触发的探针。arg0 是查询字符串。 @@ -7363,7 +6327,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, query-parse-start (const char *) - 当一个查询的解析被开始时触发的探针。arg0 是查询字符串。 + 当一个查询的解析开始时触发的探针。arg0 是查询字符串。 @@ -7375,7 +6339,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, query-rewrite-start (const char *) - 当一个查询的重写被开始时触发的探针。arg0 是查询字符串。 + 当一个查询的重写开始时触发的探针。arg0 是查询字符串。 @@ -7387,7 +6351,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, query-plan-start () - 当一个查询的规划被开始时触发的探针。 + 当一个查询的规划开始时触发的探针。 @@ -7399,7 +6363,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, query-execute-start () - 当一个查询的执行被开始时触发的探针。 + 当一个查询的执行开始时触发的探针。 @@ -7417,19 +6381,19 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, checkpoint-start (int) - 当一个检查点被开始时触发的探针。arg0 传递位标志来区分不同的检查点类型,例如关闭(shutdown)、立即(immediate)或强制(force)。 + 当一个检查点开始时触发的探针。arg0 传递位标志来区分不同的检查点类型,例如关闭(shutdown)、立即(immediate)或强制(force)。 checkpoint-done (int, int, int, int, int) - 当一个检查点完成时触发的探针(检查点处理过程中序列中列出的下一个触发的探针)。arg0 是要写的缓冲区数量。arg1 是缓冲区的总数。arg2、arg3 和 arg4 分别包含了增加、删除和循环回收的 WAL 文件的数量。 + 当一个检查点完成时触发的探针(下面列出的探针会在检查点处理过程中依次触发)。arg0 是已写入的缓冲区数量。arg1 是缓冲区的总数。arg2、arg3 和 arg4 分别包含了增加、删除和循环回收的 WAL 文件的数量。 clog-checkpoint-start (bool) - 当一个检查点的 CLOG 部分被开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 + 当一个检查点的 CLOG 部分开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 @@ -7441,7 +6405,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, subtrans-checkpoint-start (bool) - 当一个检查点的 SUBTRANS 部分被开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 + 当一个检查点的 SUBTRANS 部分开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 @@ -7453,7 +6417,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, multixact-checkpoint-start (bool) - 当一个检查点的 MultiXact 部分被开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 + 当一个检查点的 MultiXact 部分开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 @@ -7465,7 +6429,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, buffer-checkpoint-start (int) - 当一个检查点的写缓冲区部分被开始时触发的探针。arg0 传递位标志来区分不同的检查点类型,例如关闭(shutdown)、立即(immediate)或强制(force)。 + 当一个检查点的写缓冲区部分开始时触发的探针。arg0 传递位标志来区分不同的检查点类型,例如关闭(shutdown)、立即(immediate)或强制(force)。 @@ -7501,7 +6465,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, twophase-checkpoint-start () - 当一个检查点的两阶段部分被开始时触发的探针。 + 当一个检查点的两阶段部分开始时触发的探针。 @@ -7513,19 +6477,19 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, buffer-read-start (ForkNumber, BlockNumber, Oid, Oid, Oid, int, bool) - 当一次缓冲区读被开始时触发的探针。arg0 和 arg1 包含该页的分叉号和块号(如果这是一次关系扩展请求,arg1 为 -1)。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是 InvalidBackendId(-1)。arg6 为真表示一次关系扩展请求,为假表示正常读。 + 当一次缓冲区读开始时触发的探针。arg0 和 arg1 包含该页的分支号和块号(如果这是一次关系扩展请求,arg1 为 -1)。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是 InvalidBackendId(-1)。arg6 为真表示一次关系扩展请求,为假表示正常读。 buffer-read-done (ForkNumber, BlockNumber, Oid, Oid, Oid, int, bool, bool) - 当一次缓冲区读完成时触发的探针。arg0 和 arg1 包含该页的分叉号和块号(如果这是一次关系扩展请求,arg1 现在包含新增加块的块号)。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是 InvalidBackendId(-1)。arg6 为真表示一次关系扩展请求,为假表示正常读。arg7 为真表示在池中找到该缓冲区,为假表示没有找到。 + 当一次缓冲区读完成时触发的探针。arg0 和 arg1 包含该页的分支号和块号(如果这是一次关系扩展请求,arg1 现在包含新增加块的块号)。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是 InvalidBackendId(-1)。arg6 为真表示一次关系扩展请求,为假表示正常读。arg7 为真表示在池中找到该缓冲区,为假表示没有找到。 buffer-flush-start (ForkNumber, BlockNumber, Oid, Oid, Oid) - 在发出对一个共享缓冲区的任意写请求之前触发的探针。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。 + 在发出对一个共享缓冲区的任意写请求之前触发的探针。arg0 和 arg1 包含该页的分支号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。 @@ -7537,7 +6501,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, buffer-write-dirty-start (ForkNumber, BlockNumber, Oid, Oid, Oid) - 当一个服务器进程开始写一个脏缓冲区时触发的探针(如果这经常发生,表示太小,或需要调整后台写入器的控制参数)。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。 + 当一个服务器进程开始写一个脏缓冲区时触发的探针(如果这经常发生,表示太小,或需要调整后台写入器的控制参数)。arg0 和 arg1 包含该页的分支号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。 @@ -7555,13 +6519,13 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, wal-buffer-write-dirty-done () - 当一次脏 WAL 缓冲区完成时触发的探针。 + 当一次脏 WAL 缓冲区写入完成时触发的探针。 wal-insert (unsigned char, unsigned char) - 当一个 WAL 记录被插入时触发的探针。arg0 是该记录的资源管理者(rmid)。arg1 包含 info 标志。 + 当一个 WAL 记录被插入时触发的探针。arg0 是该记录的资源管理器(rmid)。arg1 包含 info 标志。 @@ -7573,31 +6537,31 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, smgr-md-read-start (ForkNumber, BlockNumber, Oid, Oid, Oid, int) - 当开始从一个关系读取一块时触发的探针。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。 + 当开始从一个关系读取一块时触发的探针。arg0 和 arg1 包含该页的分支号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。 smgr-md-read-done (ForkNumber, BlockNumber, Oid, Oid, Oid, int, int, int) - 当一次块读取完成时触发的探针。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。arg6 是实际读取的字节数,而 arg7 是请求读取的字节数(如果两者不同就意味着麻烦)。 + 当一次块读取完成时触发的探针。arg0 和 arg1 包含该页的分支号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。arg6 是实际读取的字节数,而 arg7 是请求读取的字节数(如果两者不同就意味着麻烦)。 smgr-md-write-start (ForkNumber, BlockNumber, Oid, Oid, Oid, int) - 当开始向一个关系中写入一个块时触发的探针。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。 + 当开始向一个关系中写入一个块时触发的探针。arg0 和 arg1 包含该页的分支号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。 smgr-md-write-done (ForkNumber, BlockNumber, Oid, Oid, Oid, int, int, int) - 当一个块写操作完成时触发的探针。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3和arg4 包含表空间、数据库和关系 OID来标识该关系。对于一个本地缓冲区,arg5 是创建临时关系的后端 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。arg6 是实际写的字节数,而 arg7 是要求写的字节数(如果这两者不同,则意味着麻烦)。 + 当一个块写操作完成时触发的探针。arg0 和 arg1 包含该页的分支号和块号。arg2、arg3和arg4 包含表空间、数据库和关系 OID来标识该关系。对于一个本地缓冲区,arg5 是创建临时关系的后端 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。arg6 是实际写的字节数,而 arg7 是要求写的字节数(如果这两者不同,则意味着麻烦)。 sort-start (int, bool, int, int, bool, int) - 当一次排序操作开始时触发的探针。arg0 指示是堆排序、索引排序或数据排序。arg1 为真表示强制唯一值。arg2 是键列数。arg3 是允许使用的工作内存大小(以千字节计)。如果要求随机访问排序结果,则 arg4 为真。arg5 为 0 时表示串行,为 1 时表示并行工作进程,为 2 时表示并行领导者。 + 当一次排序操作开始时触发的探针。arg0 指示是堆排序、索引排序或 datum 排序。arg1 为真表示强制唯一值。arg2 是键列数。arg3 是允许使用的工作内存大小(以千字节计)。如果要求随机访问排序结果,则 arg4 为真。arg5 为 0 时表示串行,为 1 时表示并行工作进程,为 2 时表示并行领导者。 @@ -7611,7 +6575,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, (char *, LWLockMode) 当成功获得一个 LWLock 时触发的探针。 arg0 是该 LWLock 所在的切片(Tranche)。 - arg1 所请求的锁模式,是排他或共享。 + arg1 是所请求的锁模式,是排他或共享。 @@ -7626,34 +6590,34 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, (char *, LWLockMode) 当一个 LWLock不是当即可用并且一个服务器进程因此开始等待该锁变为可用时触发的探针。 arg0 是该 LWLock 所在的切片(Tranche)。 - arg1 请求的锁模式,是排他或共享。 + arg1 是所请求的锁模式,是排他或共享。 lwlock-wait-done (char *, LWLockMode) 当一个进程从对一个 LWLock 的等待中被释放时(它实际还没有得到该锁)时触发的探针。arg0 是该 LWLock 所在的切片(Tranche)。 - arg1 所请求的锁模式,是排他或共享。 + arg1 是所请求的锁模式,是排他或共享。 lwlock-condacquire (char *, LWLockMode) 当调用者指定无需等待而成功获得一个 LWLock 时触发的探针。arg0 是该 LWLock 所在的切片(Tranche)。 - arg1 所请求的锁模式,是排他或共享。 + arg1 是所请求的锁模式,是排他或共享。 lwlock-condacquire-fail (char *, LWLockMode) 当调用者指定无需等待而没有成功获得一个 LWLock 时触发的探针。arg0 是该 LWLock 所在的切片(Tranche)。 - arg1 所请求的锁模式,是排他或共享。 + arg1 是所请求的锁模式,是排他或共享。 lock-wait-start (unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, LOCKMODE) - 当一个重量级锁(lmgr锁)的请求由于锁不可用开始等待时触发的探针。arg0 到 arg3 是标识被锁定对象的标签域。arg4 指示被锁对象的类型。arg5 表示被请求的锁类型。 + 当一个重量级锁(lmgr锁)的请求由于锁不可用开始等待时触发的探针。arg0 到 arg3 是标识被锁定对象的标签字段。arg4 指示被锁对象的类型。arg5 表示被请求的锁类型。 @@ -7674,7 +6638,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid,
- 定义用在探针参数中的类型 + 探针参数中使用的已定义类型 @@ -7768,7 +6732,7 @@ Total time (ns) 2312105013 - 你应该记住,DTrace 脚本需要细心地编写和调试,否则被收集的追踪信息可能会毫无意义。在大部分发现问题的情况中,它就是发生问题的部件,而不是底层系统。当讨论使用动态追踪发现的信息时,一定要附上使用的脚本以便其也被检查和讨论。 + 你应该记住,DTrace 脚本需要细心地编写和调试,否则被收集的追踪信息可能会毫无意义。在大多数发现问题的情况下,出错的是插桩,而不是底层系统。当讨论使用动态追踪发现的信息时,一定要附上使用的脚本以便其也被检查和讨论。 @@ -7784,7 +6748,7 @@ Total time (ns) 2312105013 - 决定探针名称以及探针可用的数据 + 决定探针名称以及要通过探针提供的数据 @@ -7798,7 +6762,7 @@ Total time (ns) 2312105013 - 如果pg_trace.h还不存在于包含该探针点的模块中,包括它,并且在源代码中期望的位置插入TRACE_POSTGRESQL探针宏 + 如果pg_trace.h尚未被包含该探针点的模块引用,则将它包含进来,并且在源代码中期望的位置插入TRACE_POSTGRESQL探针宏 @@ -7834,14 +6798,14 @@ Total time (ns) 2312105013 probe transaction__start(LocalTransactionId); - 注意探针名字中双下划线的使用。在一个使用探针的 DTrace 脚本中,双下划线需要被替换为一个连字符,因此 ,对用户而言transaction-start是文档名。 + 注意探针名字中双下划线的使用。在一个使用探针的 DTrace 脚本中,双下划线需要被替换为一个连字符,因此,文档中应向用户说明的名称是transaction-start - 在编译时,transaction__start被转换成一个宏调用TRACE_POSTGRESQL_TRANSACTION_START(注意这里是单下划线),可以通过包括头文件pg_trace.h获得。将宏调用加入到源代码中的合适位置。在这种情况下,看起来类似: + 在编译时,transaction__start被转换成一个名为TRACE_POSTGRESQL_TRANSACTION_START的宏(注意这里是单下划线),可以通过包含头文件pg_trace.h获得。将宏调用加入到源代码中的合适位置。在这种情况下,看起来类似: TRACE_POSTGRESQL_TRANSACTION_START(vxid.localTransactionId); @@ -7878,7 +6842,7 @@ TRACE_POSTGRESQL_TRANSACTION_START(vxid.localTransactionId); - 在大多数平台上,如果用编译了PostgreSQL,无论何时当控制经过一个追踪宏时,都会评估该宏的参数,即使没有进行追踪也会这样做。通常不需要担心你是否只在报告一些局部变量的值。但是要注意不要将开销大的函数调用放入参数中。如果你需要这样做,考虑通过检查追踪是否真的被启用来保护该宏: + 在大多数平台上,如果用编译了PostgreSQL,无论何时当控制经过一个追踪宏时,都会对该宏的参数求值,即使没有进行追踪也会这样做。如果只是报告少数局部变量的值,通常无需担心这一点。但是要注意不要将开销大的函数调用放入参数中。如果你需要这样做,考虑通过检查追踪是否真的被启用来保护该宏: if (TRACE_POSTGRESQL_TRANSACTION_START_ENABLED()) @@ -7896,114 +6860,6 @@ if (TRACE_POSTGRESQL_TRANSACTION_START_ENABLED()) - - 监控磁盘使用情况 - - - 本节讨论如何监控 PostgreSQL 数据库系统的磁盘使用情况。 - - - - 确定磁盘使用情况 - - - disk usage - - - - 每个表都有一个主堆磁盘文件,大部分数据都存储在那里。如果表中有任何列可能包含较宽的值,还可能有一个与该表关联的 TOAST 文件,用于存储那些不适合放在主表中的过宽值(参见)。如果该 TOAST 表存在,则它会有一个有效索引。基础表本身也可能带有索引。每个表和索引都存储在单独的磁盘文件中;如果某个文件会超过 1 GB,则可能拆分为多个文件。关于这些文件的命名规则,请参见。 - - - - 你可以通过三种方式监控磁盘空间:使用中列出的 SQL 函数、使用模块,或者手工检查系统目录。SQL 函数最容易使用,通常也是推荐的方法。本节余下内容展示如何通过检查系统目录来完成这项工作。 - - - - 在最近执行过 VACUUMANALYZE 的数据库上使用 psql,你可以发出查询来查看任意表的磁盘使用情况: - -SELECT pg_relation_filepath(oid), relpages FROM pg_class WHERE relname = 'customer'; - - pg_relation_filepath | relpages -----------------------+---------- - base/16384/16806 | 60 -(1 row) - - 每一页通常是 8 KB。(请记住,relpages 只会由 VACUUMANALYZE 以及少数 DDL 命令如 CREATE INDEX 更新。)如果你想直接检查该表的磁盘文件,那么文件路径名会很有用。 - - - - 要显示 TOAST 表使用的空间,可以使用如下查询: - -SELECT relname, relpages -FROM pg_class, - (SELECT reltoastrelid - FROM pg_class - WHERE relname = 'customer') AS ss -WHERE oid = ss.reltoastrelid OR - oid = (SELECT indexrelid - FROM pg_index - WHERE indrelid = ss.reltoastrelid) -ORDER BY relname; - - relname | relpages -----------------------+---------- - pg_toast_16806 | 0 - pg_toast_16806_index | 1 - - - - - 也可以很容易地显示索引所占空间: - -SELECT c2.relname, c2.relpages -FROM pg_class c, pg_class c2, pg_index i -WHERE c.relname = 'customer' AND - c.oid = i.indrelid AND - c2.oid = i.indexrelid -ORDER BY c2.relname; - - relname | relpages --------------------+---------- - customer_id_index | 26 - - - - - 利用这些信息,你可以很容易地找出最大的表和索引: - -SELECT relname, relpages -FROM pg_class -ORDER BY relpages DESC; - - relname | relpages -----------------------+---------- - bigtable | 3290 - customer | 3144 - - - - - - 磁盘已满故障 - - - 数据库管理员最重要的磁盘监控任务,是确保磁盘不会被写满。数据磁盘写满不会导致数据损坏,但可能会阻止有用的活动继续进行。如果保存 WAL 文件的磁盘被写满,则数据库服务器可能会 panic 并随后关闭。 - - - - 如果你无法通过删除其他文件来释放更多磁盘空间,那么可以利用表空间把部分数据库文件移动到其他文件系统上。详见。 - - - - - 有些文件系统在接近写满时性能会明显变差,因此不要等到磁盘完全写满才采取措施。 - - - - 如果你的系统支持按用户设置磁盘配额,那么数据库自然也会受到运行服务器的那个用户所拥有配额的限制。超出配额会带来与磁盘空间完全耗尽相同的不良影响。 - - - diff --git a/zh/14/mvcc.sgml b/zh/14/mvcc.sgml index 3716b101..65044600 100644 --- a/zh/14/mvcc.sgml +++ b/zh/14/mvcc.sgml @@ -4,7 +4,7 @@ 并发控制 - concurrency + 并发 @@ -15,7 +15,7 @@ 介绍 - Multiversion Concurrency Control + 多版本并发控制 @@ -23,7 +23,7 @@ - Serializable Snapshot Isolation + 可串行化快照隔离 @@ -50,7 +50,7 @@ 事务隔离 - transaction isolation + 事务隔离 @@ -68,7 +68,7 @@ 脏读 - dirty read + 脏读 @@ -80,7 +80,7 @@ 不可重复读 - nonrepeatable read + 不可重复读 @@ -92,7 +92,7 @@ 幻读 - phantom read + 幻读 @@ -104,7 +104,7 @@ 串行化异常 - serialization anomaly + 串行化异常 @@ -117,7 +117,7 @@ - transaction isolation level + 事务隔离级别 SQL 标准以及 PostgreSQL 实现的事务隔离级别见 @@ -244,12 +244,12 @@ 读已提交隔离级别 - transaction isolation level - read committed + 事务隔离级别 + 读已提交 - read committed + 读已提交 @@ -295,7 +295,7 @@ 由于上述规则,更新命令可能看到一个不一致的快照:它能够看到并发更新命令在它试图更新的同一行上的效果, 却看不到这些命令对数据库中其他行的影响。这种行为使得读已提交模式不适合涉及复杂搜索条件的命令; - 不过,对于较简单的场景它恰到好处。例如,考虑将 100 美元从一个账户转到另一个账户: + 不过,对于较简单的场景它恰到好处。例如,考虑以如下事务更新银行余额: BEGIN; @@ -304,13 +304,13 @@ UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 7534; COMMIT; - 如果另一个事务并发地尝试更改账户 7534 的余额,我们显然希望第二条语句从该账户行的已更新版本开始。 + 如果两个这样的事务并发地尝试更改账户 12345 的余额,我们显然希望第二个事务从该账户行的已更新版本开始。 因为每个命令只影响一个预先确定的行,让它看到该行的已更新版本不会造成任何麻烦的不一致。 在读已提交模式下,更复杂的用法可能产生不理想的结果。例如,考虑一个 - DELETE 命令,它所处理的数据会被另一个命令同时加入和移出其筛选条件。 + DELETE 命令,另一个命令正在修改数据,使某些行开始满足其筛选条件、另一些行不再满足。 假设 website 是一个有两行的表,其中 website.hits 分别等于 910: @@ -318,7 +318,7 @@ COMMIT; BEGIN; UPDATE website SET hits = hits + 1; --- run from another session: DELETE FROM website WHERE hits = 10; +-- 从另一个会话运行: DELETE FROM website WHERE hits = 10; COMMIT; @@ -346,12 +346,12 @@ COMMIT; 可重复读隔离级别 - transaction isolation level - repeatable read + 事务隔离级别 + 可重复读 - repeatable read + 可重复读 @@ -403,9 +403,7 @@ ERROR: could not serialize access due to concurrent update 可重复读模式提供了严格的保证,即每个事务都看到数据库的一个完全稳定的视图。 不过,这个视图并不一定总能与同一级别并发事务的某种串行(一次一个)执行保持一致。 - 例如,即使该级别上的只读事务可能看到一条控制记录被更新,表明某个批处理已经完成, - 但它并不一定能看到作为该批处理逻辑组成部分的某条明细记录, - 因为它读到的是控制记录的较早版本。如果不仔细使用显式锁来阻塞冲突事务, + 例如,即使是该级别的只读事务,也可能看到一条表明某批次已完成的控制记录,却看不到逻辑上属于该批次的某条明细记录,因为创建该明细记录的事务读取了控制记录的较早版本。如果不仔细使用显式锁来阻塞冲突事务, 试图依靠运行在这一隔离级别的事务来强制业务规则,往往无法正确工作。 @@ -413,7 +411,7 @@ ERROR: could not serialize access due to concurrent update 可重复读隔离级别是通过一种技术实现的,这种技术在学术数据库文献中以及某些其他数据库产品中被称为 快照隔离。与使用会降低并发性的传统加锁技术的系统相比, 其行为和性能可能会表现出差异。有些其他系统甚至把可重复读和快照隔离作为两个行为不同的独立隔离级别提供。 - 用来区分这两种技术的允许现象,直到 SQL 标准制定之后才被数据库研究人员正式定义,因此超出了本手册的范围。 + 用来区分这两种技术的允许现象,直到 SQL 标准制定之后才被数据库研究人员正式定义,并且超出了本手册的范围。 完整讨论请参阅 @@ -429,20 +427,20 @@ ERROR: could not serialize access due to concurrent update 可串行化隔离级别 - transaction isolation level - serializable + 事务隔离级别 + 可串行化 - serializable + 可串行化 - predicate locking + 谓词锁 - serialization anomaly + 串行化异常 @@ -455,48 +453,30 @@ ERROR: could not serialize access due to concurrent update 一旦检测到可能导致串行化异常的条件,就会触发串行化失败 - - 例如,考虑一张表 mytab,其初始内容为: - + 例如,考虑表mytab,它最初包含以下内容: class | value -------+------- 1 | 10 1 | 20 2 | 100 2 | 200 - - 假设可串行化事务 A 计算: - +假设可串行化事务 A 执行以下计算: SELECT SUM(value) FROM mytab WHERE class = 1; - - 然后将结果(30)作为一条新行的 value 插入,并把 - class 设为 2。与此同时,可串行化事务 B 计算: - +然后将结果(30)作为新行的value插入,且该行满足class = 2。与此同时,可串行化事务 B 执行以下计算: SELECT SUM(value) FROM mytab WHERE class = 2; - - 并得到结果 300,再把它插入为一条新行,其 - class1。然后两个事务都尝试提交。 - 如果任一事务是在可重复读隔离级别下运行,则二者都可以提交; - 但由于不存在与该结果一致的串行执行顺序,使用可串行化事务时将允许其中一个事务提交, - 并按如下消息回滚另一个事务: - - +得到结果 300,并将它插入一个新行,该行满足class = 1。然后两个事务都尝试提交。如果任一事务运行在可重复读隔离级别,两个事务都可以提交;但由于不存在与该结果一致的串行执行顺序,使用可串行化事务时,只会允许一个事务提交,另一个则会被回滚,并收到以下消息: ERROR: could not serialize access due to read/write dependencies among transactions - - - 这是因为,如果 A 先于 B 执行,B 算出的和将是 330 而不是 300; - 反过来,另一种顺序也会使 A 算出不同的和。 - +这是因为,如果 A 在 B 之前执行,B 算出的总和应该是 330,而不是 300;同样,按另一种顺序执行,A 算出的总和也会不同。 当依赖可串行化事务来防止异常时,重要的是:从永久用户表读取的任何数据,在读取它的事务成功提交之前, - 都不应视为有效。即使对于只读事务也是如此;唯一的例外是可推迟只读事务中读取的数据, + 都不应视为有效。即使对于只读事务也是如此;唯一的例外是可延迟只读事务中读取的数据, 它一经读出就可视为有效,因为这种事务会等到能够获取一个保证不存在此类问题的快照后才开始读取数据。 在所有其他情况下,应用不能依赖后来被中止事务中读到的结果;相反,应重试事务直到成功。 - 为了保证真正的可串行化,PostgreSQL 使用了谓词锁, + 为了保证真正的可串行性,PostgreSQL 使用了谓词锁, 也就是说,系统会保留一些锁,以便判断某个写操作如果先发生,是否会影响并发事务先前读取的结果。 在 PostgreSQL 中,这些锁不会造成任何阻塞,因此会参与形成死锁。 它们用于识别并标记并发可串行化事务之间的依赖关系,而这些依赖在某些组合下可能导致串行化异常。 @@ -518,7 +498,7 @@ ERROR: could not serialize access due to read/write dependencies among transact - 持续使用可串行化事务可以简化开发。任何一组成功提交的并发可串行化事务,都保证与把它们一次一个运行的效果相同;这意味着,如果你能够证明某个事务在单独运行时会做正确的事,那么即使不了解其他事务会做什么,也可以相信它在任何可串行化事务的混合执行中也会做正确的事,否则它就不会成功提交。重要的是,采用这种技术的环境应当有一套通用机制来处理串行化失败(其 SQLSTATE 值总是 40001),因为很难准确预测究竟哪些事务会对读/写依赖关系有贡献,并因此需要被回滚来防止串行化异常。监视读/写依赖关系会带来开销,被串行化失败中止的事务重新启动也会带来开销;但在把这些开销与显式锁以及 SELECT FOR UPDATESELECT FOR SHARE 所涉及的成本和阻塞进行权衡之后,可串行化事务在某些环境中仍然是性能最佳的选择。 + 统一采用可串行化事务可以简化开发。任何一组成功提交的并发可串行化事务,都保证与把它们一次一个运行的效果相同;这意味着,如果你能够证明某个事务在单独运行时会做正确的事,那么即使不了解其他事务会做什么,也可以相信它在任何可串行化事务的混合执行中也会做正确的事,否则它就不会成功提交。重要的是,采用这种技术的环境应当有一套通用机制来处理串行化失败(其 SQLSTATE 值总是 40001),因为很难准确预测究竟哪些事务会对读/写依赖关系有贡献,并因此需要被回滚来防止串行化异常。监视读/写依赖关系会带来开销,被串行化失败中止的事务重新启动也会带来开销;但在把这些开销与显式锁以及 SELECT FOR UPDATESELECT FOR SHARE 所涉及的成本和阻塞进行权衡之后,可串行化事务在某些环境中仍然是性能最佳的选择。 @@ -562,7 +542,7 @@ ERROR: could not serialize access due to read/write dependencies among transact - 当系统因谓词锁表内存不足而被迫把多个页级谓词锁合并为单个关系级谓词锁时,串行化失败的比例可能会上升。你可以通过增加 来避免这种情况。 + 当系统因谓词锁表内存不足而被迫把多个页级谓词锁合并为单个关系级谓词锁时,串行化失败的比例可能会上升。你可以通过增加 和/或 来避免这种情况。 @@ -586,7 +566,7 @@ ERROR: could not serialize access due to read/write dependencies among transact 显式锁定 - lock + @@ -649,13 +629,7 @@ ERROR: could not serialize access due to read/write dependencies among transact 与 EXCLUSIVEACCESS EXCLUSIVE 锁模式冲突。 - - 当 SELECT 命令在某个表上指定了 、 - 或 - 选项时,会在该表上获取这种锁模式 - (此外,对于任何其他被引用但没有显式 加锁选项的表, - 则会获取 ACCESS SHARE 锁)。 - + SELECT FOR UPDATESELECT FOR SHARE 命令会在目标表上获取这种模式的锁(此外,对于引用到但没有用 选取的其他表,还会获取 ACCESS SHARE 锁)。 @@ -689,7 +663,7 @@ ERROR: could not serialize access due to read/write dependencies among transact CREATE STATISTICSCOMMENT ONREINDEX CONCURRENTLY, 以及某些 ALTER INDEX - 和 ALTER TABLE 变体会获取这种锁 + 和 ALTER TABLE 变体获取这种锁 (有关详细信息,请参阅这些命令的文档)。 @@ -954,7 +928,7 @@ ERROR: could not serialize access due to read/write dependencies among transact - 行为与 FOR SHARE 类似,不过锁更弱:SELECT FOR UPDATE 会被阻塞,但 SELECT FOR NO KEY UPDATE 不会。键共享锁会阻塞其他事务执行会修改键值的 DELETEUPDATE,但不会阻塞其他 UPDATE,也不会阻止 SELECT FOR NO KEY UPDATESELECT FOR SHARESELECT FOR KEY SHARE。 + 行为与 FOR SHARE 类似,不过锁更弱:SELECT FOR UPDATE 会被阻塞,但 SELECT FOR NO KEY UPDATE 不会。键共享锁会阻塞其他事务执行 DELETE 或任何会修改键值的 UPDATE,但不会阻塞其他 UPDATE,也不会阻止 SELECT FOR NO KEY UPDATESELECT FOR SHARESELECT FOR KEY SHARE @@ -1032,7 +1006,7 @@ ERROR: could not serialize access due to read/write dependencies among transact 死锁 - deadlock + 死锁 @@ -1075,12 +1049,12 @@ UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 22222; 咨询锁 - advisory lock + 咨询锁 - lock - advisory + + 咨询 @@ -1112,12 +1086,12 @@ UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 22222; 在某些使用咨询锁的方法中,特别是涉及显式排序和 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(id) FROM foo WHERE id = 12345; -- 可以 +SELECT pg_advisory_lock(id) FROM foo WHERE id > 12345 LIMIT 100; -- 危险! SELECT pg_advisory_lock(q.id) FROM ( SELECT id FROM foo WHERE id > 12345 LIMIT 100 -) q; -- ok +) q; -- 可以 在上面的查询中,第二种形式是危险的,因为不能保证在执行加锁函数之前先应用 LIMIT。 这可能导致获取了一些应用并未预期的锁,因此应用也不会去释放它们(直到会话结束)。 @@ -1135,12 +1109,12 @@ SELECT pg_advisory_lock(q.id) FROM 应用级别的数据一致性检查 - 在读已提交事务下,想要通过业务规则强制数据一致性非常困难,因为数据视图会随每条语句而变化, + 用读已提交事务强制执行有关数据完整性的业务规则非常困难,因为数据视图会随每条语句而变化, 而且一旦发生写冲突,即使是单条语句也未必局限于该语句自己的快照。 - 虽然可重复读事务在整个执行期间都具有稳定的数据视图,但在使用 MVCC 快照进行数据一致性检查时,还存在一个微妙问题,即所谓的读/写冲突。如果一个事务写入数据,而并发事务试图读取相同的数据(无论是在写入之前还是之后),它都看不到另一个事务的工作。于是,读取者看起来就像是先执行的一方,而不管究竟是谁先启动,也不管谁先提交。如果事情只停留在这一步,就没有问题;但如果读取者还写入了数据,而这些数据又被另一个并发事务读取,那么现在就会有一个事务看起来像是在前面提到的任一事务之前执行。如果看起来最后执行的事务实际上最先提交,就很容易在事务执行顺序图中形成一个环。一旦出现这样的环,不借助额外机制,一致性检查就无法正确工作。 + 虽然可重复读事务在整个执行期间都具有稳定的数据视图,但在使用 MVCC 快照进行数据一致性检查时,还存在一个微妙问题,即所谓的读/写冲突。如果一个事务写入数据,而并发事务试图读取相同的数据(无论是在写入之前还是之后),它都看不到另一个事务的工作。于是,读取者看起来就像是先执行的一方,而不管究竟是谁先启动,也不管谁先提交。如果事情只停留在这一步,就没有问题;但如果读取者还写入了数据,而这些数据又被另一个并发事务读取,那么现在就会有一个事务看起来像是在前面提到的任一事务之前执行。如果看起来最后执行的事务实际上最先提交,就很容易在事务执行顺序图中形成一个环。一旦出现这样的环,不借助额外机制,完整性检查就无法正确工作。 @@ -1157,7 +1131,7 @@ SELECT pg_advisory_lock(q.id) FROM - 使用这种技术时,如果应用软件通过某个框架运行,并由该框架自动重试因串行化错误而回滚的事务,就可以避免给应用程序员带来不必要的负担。把 default_transaction_isolation 设置为 serializable 可能是个好主意。通过在触发器中检查事务隔离级别来采取某些措施,以确保不会因为疏忽或为了绕过完整性检查而使用其他事务隔离级别,也是明智的。 + 使用这种技术时,如果应用软件通过某个框架运行,并由该框架自动重试因串行化失败而回滚的事务,就可以避免给应用程序员带来不必要的负担。把 default_transaction_isolation 设置为 serializable 可能是个好主意。通过在触发器中检查事务隔离级别来采取某些措施,以确保不会因为疏忽或为了绕过完整性检查而使用其他事务隔离级别,也是明智的。 @@ -1165,16 +1139,15 @@ SELECT pg_advisory_lock(q.id) FROM - 警告:可串行化事务和数据复制 - 利用可串行化事务提供的这一层完整性保护,尚未扩展到热备模式()或逻辑副本。 - 因此,使用热备或逻辑复制的用户可能希望在主库上使用可重复读和显式锁定。 + 利用可串行化事务提供的这一层完整性保护,尚未扩展到热备模式()。 + 因此,使用热备的用户可能希望在主库上使用可重复读和显式锁定。 - 使用显式锁定强制一致性 + 使用显式阻塞锁强制一致性 当存在非可串行化写入时,要确保某一行当前仍然有效,并保护它不受并发更新影响, @@ -1197,7 +1170,7 @@ SELECT pg_advisory_lock(q.id) FROM 在非可串行化的 MVCC 环境下,全局有效性检查需要额外考虑。 - 例如,一个银行应用可能希望检查一个表中的所有收入总和等于另一个表中的所有支出总和, + 例如,一个银行应用可能希望检查一个表中的贷方金额总和等于另一个表中的借方金额总和, 而这两个表都在被活跃更新。在读已提交模式下,比较两个连续的 SELECT sum(...) 命令的结果并不可靠,因为第二个查询很可能会包含第一个查询没有统计到的事务提交结果。 在单个可重复读事务中完成这两次求和,只能准确反映在该可重复读事务开始之前已提交事务的效果 @@ -1221,54 +1194,6 @@ SELECT pg_advisory_lock(q.id) FROM - - 串行化失败处理 - - - serialization failure - - - retryable error - - - - 可重复读和可串行化隔离级别都可能产生旨在防止串行化异常的错误。 - 如前所述,使用这些级别的应用必须准备好重试因串行化错误而失败的事务。 - 这类错误的消息文本会随具体情况而变化,但其 SQLSTATE 代码始终是 - 40001serialization_failure)。 - - - - 重试因死锁而失败的事务也可能是明智的。这类错误的 SQLSTATE 代码为 - 40P01deadlock_detected)。 - - - - 在某些情况下,重试唯一键违例也是合适的,这类错误的 SQLSTATE 代码为 - 23505unique_violation);重试排除约束违例也可能合适, - 其 SQLSTATE 代码为 23P01exclusion_violation)。 - 例如,如果应用在检查当前已存储键值之后,为主键列选择了一个新值, - 那么另一个应用实例并发选择了同一个新键时,就可能发生唯一键违例。 - 这实际上是一种串行化失败,但服务器不会把它识别为此类错误, - 因为它无法看到插入值与先前读取之间的联系。 - 还有一些边缘情况,在这些情况下,即使原则上服务器拥有足够的信息来判断根本原因是串行化问题, - 它也仍会报出唯一键或排除约束错误。虽然建议无条件重试 - serialization_failure 错误,但在重试这些其他错误代码时需要更加谨慎, - 因为它们可能代表持久性错误,而不是瞬态失败。 - - - - 重试完整事务非常重要,其中应包括决定发出哪些 SQL 和/或使用哪些值的全部逻辑。 - 因此,PostgreSQL 不提供自动重试功能,因为它无法在正确性上作出保证。 - - - - 重试事务并不保证重试后的事务一定能够完成;可能需要多次重试。 - 在争用非常激烈的情况下,完成一个事务可能需要尝试很多次。 - 如果涉及相互冲突的已准备事务,那么在已准备事务提交或回滚之前,可能根本无法取得进展。 - - - 注意事项 @@ -1293,8 +1218,8 @@ SELECT pg_advisory_lock(q.id) FROM 锁定和索引 - index - locks + 索引 + @@ -1307,7 +1232,7 @@ SELECT pg_advisory_lock(q.id) FROM - 读写访问使用短期的页级共享/排他锁。每个索引行在被取出或插入之后,锁都会立即释放。这些索引类型在不存在死锁条件的前提下提供了最高的并发性。 + 读写访问使用短期的页级共享/排他锁。每个索引行在被取出或插入之后,锁都会立即释放。这些索引类型提供最高的并发性,并且不会产生死锁。 @@ -1329,7 +1254,7 @@ SELECT pg_advisory_lock(q.id) FROM - 读写访问使用短期的页级共享/排他锁。每个索引行在被取出或插入之后,锁都会立即释放。但要注意,插入一个 GIN 索引值通常会导致每行产生多个索引键插入,因此 GIN 可能为了插入单个值而做大量工作。 + 读写访问使用短期的页级共享/排他锁。每个索引行在被取出或插入之后,锁都会立即释放。但要注意,插入一个使用 GIN 索引的值通常会导致每行产生多个索引键插入,因此 GIN 可能为了插入单个值而做大量工作。 diff --git a/zh/14/nls.sgml b/zh/14/nls.sgml index d3b92c80..2e0a05e1 100644 --- a/zh/14/nls.sgml +++ b/zh/14/nls.sgml @@ -299,6 +299,14 @@ fprintf(stderr, gettext("panic level %d\n"), lvl); + + AVAIL_LANGUAGES + + + 已提供的翻译列表 — 最初为空。 + + + GETTEXT_FILES diff --git a/zh/14/oid2name.sgml b/zh/14/oid2name.sgml index c51044e5..dada32b1 100644 --- a/zh/14/oid2name.sgml +++ b/zh/14/oid2name.sgml @@ -8,7 +8,7 @@ oid2name 1 - Application + 应用程序 diff --git a/zh/14/pageinspect.sgml b/zh/14/pageinspect.sgml index b1d632fd..e4b7d30a 100644 --- a/zh/14/pageinspect.sgml +++ b/zh/14/pageinspect.sgml @@ -370,20 +370,20 @@ test=# SELECT itemoffset, ctid, itemlen, nulls, vars, data, dead, htid, tids[0:2 13 | (16,8292) | 616 | f | f | 2f 00 00 00 00 00 00 00 | f | (4,17) | {"(4,17)","(4,21)"} (13 rows) - 这是一个 B-树叶页。所有指向表的元组恰好都是 posting list 元组(它们总共存储了 100 个 6 字节的 TID)。此外,在itemoffset 编号 1 处还有一个high key元组。这个示例中,ctid用于存储每个元组的编码信息,不过叶页元组通常会直接在ctid字段中存储一个堆 TID。tids是作为 posting list 存储的 TID 列表。 + 这是一个 B-树叶页。所有指向表的元组恰好都是倒排列表元组(每个都存储了 100 个 6 字节的 TID)。此外,在itemoffset 编号 1 处还有一个高键元组。这个示例中,ctid用于存储每个元组的编码信息,不过叶页元组通常会直接在ctid字段中存储一个堆 TID。tids是作为倒排列表存储的 TID 列表。 在内部页(此处未显示)中,ctid的块号部分是一个downlink(下行链接),也就是该索引中另一页的块号。ctid的偏移部分(第二个数字)存储着关于该元组的编码信息,例如实际存在的列数(后缀截断可能移除了不需要的后缀列)。被截断的列被视为具有minus infinity值。 - htid显示该元组的堆 TID,而不考虑底层元组表示形式。这个值可能与ctid相同,也可能是从 posting list 元组以及内部页元组所使用的替代表示中解码出来的。内部页中的元组通常会把实现层面的堆 TID 列截断掉,这会表现为htid值为 NULL。 + htid显示该元组的堆 TID,而不考虑底层元组表示形式。这个值可能与ctid相同,也可能是从倒排列表元组以及内部页元组所使用的替代表示中解码出来的。内部页中的元组通常会把实现层面的堆 TID 列截断掉,这会表现为htid值为 NULL。 - 请注意,任何非最右页(即btpo_next字段值非零的页面)的第一项都是该页的high key,这意味着它的data充当该页上所有项的上界,而它的ctid字段并不指向另一个块。另外,在内部页上,第一个真正的数据项(第一个不是high key的项)一定会把所有列都截断掉,因此其data字段中没有实际值。不过,这样的项在其ctid字段中确实有一个有效的下行链接。 + 请注意,任何非最右页(即btpo_next字段值非零的页面)的第一项都是该页的高键,这意味着它的data充当该页上所有项的上界,而它的ctid字段并不指向另一个块。另外,在内部页上,第一个真正的数据项(第一个不是高键的项)一定会把所有列都截断掉,因此其data字段中没有实际值。不过,这样的项在其ctid字段中确实有一个有效的下行链接。 - 关于 B-树索引结构的更多细节,参见。关于去重和 posting list 的更多细节,参见。关于去重和倒排列表的更多细节,参见 diff --git a/zh/14/parallel.sgml b/zh/14/parallel.sgml index 424f847e..e3832749 100644 --- a/zh/14/parallel.sgml +++ b/zh/14/parallel.sgml @@ -222,7 +222,7 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%'; - Parallel Append + 并行追加 每当 PostgreSQL 需要将来自多个源的行合并成一个结果集时,它就会使用 AppendMergeAppend 计划节点。这种情况常见于实现 UNION ALL 或扫描分区表时。这样的节点和其他任何计划中的情形一样,也可以用于并行计划。不过,在并行计划中,规划器也可能改用 Parallel Append 节点。 @@ -286,9 +286,11 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%'; - - 引用相关 SubPlan 的计划节点。 - + 附带 InitPlan 的计划节点。 + + + + 引用相关 SubPlan 的计划节点。 @@ -300,7 +302,7 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%'; - 如果函数或聚合会写数据库、修改事务状态(而不是通过子事务进行错误恢复)、访问序列,或者对设置做持久更改,那么它们必须标记为 PARALLEL UNSAFE。类似地,如果函数访问临时表、客户端连接状态、游标、预备语句,或者系统无法在工作进程之间同步的各种后端本地状态,那么它必须标记为 PARALLEL RESTRICTED。例如,setseedrandom 就因为最后一个原因而属于并行受限。 + 如果函数或聚合会写入数据库、访问序列、修改事务状态(即使只是临时修改,例如 PL/pgSQL 函数建立 EXCEPTION 块来捕获错误),或者对设置作出持久更改,那么它们必须标记为 PARALLEL UNSAFE。类似地,如果函数访问临时表、客户端连接状态、游标、预备语句,或者系统无法在工作进程之间同步的各种后端本地状态,那么它必须标记为 PARALLEL RESTRICTED。例如,setseedrandom 就因为最后一个原因而属于并行受限。 diff --git a/zh/14/pgcrypto.sgml b/zh/14/pgcrypto.sgml index a19afeca..178ede84 100644 --- a/zh/14/pgcrypto.sgml +++ b/zh/14/pgcrypto.sgml @@ -222,14 +222,14 @@ gen_salt(type text [, iter_count integer ]) returns text - type参数指定哈希算法。 + type参数指定 hash 算法。 接受的类型有:desxdesmd5bf iter_count参数允许用户为支持该参数的算法指定迭代次数。 - 次数越高,密码哈希所需时间越长,从而破解它所需时间也越长。 - 不过,如果次数过高,计算一个哈希可能需要数年时间 — 这显然不切实际。 + 次数越高,对密码进行 hash 所需的时间越长,从而破解它所需时间也越长。 + 不过,如果次数过高,计算一个 hash 可能需要数年时间 — 这显然不切实际。 若省略iter_count参数,则使用默认迭代次数。 允许的iter_count值取决于算法,如所示。 @@ -267,24 +267,24 @@ gen_salt(type text [, iter_count integer ]) returns text - 为了选择合适的迭代次数,可以考虑原始 DES crypt 在当时硬件上的设计速度是每秒 4 次哈希。 - 低于每秒 4 次哈希可能会影响可用性,而高于每秒 100 次哈希则很可能过快。 + 为了选择合适的迭代次数,可以考虑原始 DES crypt 在当时硬件上的设计速度是每秒 4 次 hash。 + 低于每秒 4 次 hash 可能会影响可用性,而高于每秒 100 次 hash 则很可能过快。 - 概述了不同哈希算法之间的相对速度差异。 + 概述了不同 hash 算法之间的相对速度差异。 该表展示了在 8 字符密码上尝试所有字符组合所需的时间,假定密码只包含小写字母, 或者包含大小写字母和数字。在crypt-bf条目中, 斜杠后的数字是gen_saltiter_count参数值。
- 哈希算法速度 + Hash 算法速度 算法 - 每秒哈希次数 + 每秒 hash 次数 针对[a-z] 针对[A-Za-z0-9] 相对于md5 hash的耗时倍数 diff --git a/zh/14/plhandler.sgml b/zh/14/plhandler.sgml index 38562e46..4048d572 100644 --- a/zh/14/plhandler.sgml +++ b/zh/14/plhandler.sgml @@ -17,11 +17,11 @@ - 调用处理器与其他函数一样被调用:它会接收一个指向 FunctionCallInfoBaseData struct 的指针,其中包含参数值以及被调用函数的相关信息;同时它还应返回一个 Datum 结果(如果希望返回 SQL 空值结果,还可以设置 isnull 字段,也就是 FunctionCallInfoBaseData 结构体中的该字段)。调用处理器与普通被调函数之间的区别在于,flinfo->fn_oid 字段在 FunctionCallInfoBaseData 结构体中保存的是实际要调用函数的 OID,而不是调用处理器本身的 OID。调用处理器必须使用这个字段来判定要执行哪个函数。另外,传入的参数列表是按照目标函数而不是调用处理器的声明来设置的。 + 调用处理器与其他函数一样被调用:它会接收一个指向 FunctionCallInfoBaseData struct 的指针,其中包含参数值以及被调用函数的相关信息;同时它还应返回一个 Datum 结果(如果希望返回 SQL 空值结果,还需要设置 isnull 字段,也就是 FunctionCallInfoBaseData 结构体中的该字段)。调用处理器与普通被调函数之间的区别在于,flinfo->fn_oid 字段在 FunctionCallInfoBaseData 结构体中保存的是实际要调用函数的 OID,而不是调用处理器本身的 OID。调用处理器必须使用这个字段来判定要执行哪个函数。另外,传入的参数列表是按照目标函数而不是调用处理器的声明来设置的。 - 调用处理器必须从系统目录 pg_proc 中取出该函数的条目,并分析被调用函数的参数类型和返回类型。该函数的 AS 子句可在其 CREATE FUNCTION 命令对应的 prosrc 列里找到,也就是 pg_proc 行中的该列。这里通常是一段过程语言源文本,但理论上也可以是其他内容,例如某个文件的路径名,或者任何能详细告诉调用处理器该做什么的信息。 + 调用处理器必须从系统目录 pg_proc 中取出该函数的条目,并分析被调用函数的参数类型和返回类型。该函数的 CREATE FUNCTION 命令中的 AS 子句内容,保存在 pg_proc 对应行的 prosrc 列中。这里通常是一段过程语言源文本,但理论上也可以是其他内容,例如某个文件的路径名,或者任何能详细告诉调用处理器该做什么的信息。 @@ -46,7 +46,7 @@ 验证器函数通常应遵循 参数:如果它被关闭,就应跳过任何开销高昂或依赖上下文的检查。如果该语言允许在编译时执行代码,验证器还必须抑制会诱发此类执行的检查。特别是,pg_dump 会关闭这个参数,这样它就可以装载过程语言函数,而不必担心函数体对其他数据库对象的副作用或依赖关系。(正因为有这一要求,调用处理器不应假设验证器已经完整检查了函数。提供验证器的目的,并不是让调用处理器省略检查,而是在 CREATE FUNCTION 命令中存在明显错误时立即通知用户。)虽然究竟检查哪些内容主要由验证器函数自行决定,但要注意,核心 CREATE FUNCTION 代码只会执行附加到函数上的 SET 子句,前提是 check_function_bodies 打开。因此,当 check_function_bodies 关闭时,那些结果可能受 GUC 参数影响的检查肯定都应跳过,以避免在恢复转储时出现虚假的失败。 + linkend="guc-check-function-bodies"/> 参数:如果它被关闭,就应跳过任何开销高昂或依赖上下文的检查。如果该语言允许在编译时执行代码,验证器还必须抑制会诱发此类执行的检查。特别是,pg_dump 会关闭这个参数,这样它就可以装载过程语言函数,而不必担心副作用或函数体对其他数据库对象的依赖关系。(正因为有这一要求,调用处理器不应假设验证器已经完整检查了函数。提供验证器的目的,并不是让调用处理器省略检查,而是在 CREATE FUNCTION 命令中存在明显错误时立即通知用户。)虽然究竟检查哪些内容主要由验证器函数自行决定,但要注意,只有在 check_function_bodies 打开时,核心 CREATE FUNCTION 代码才会执行函数附带的 SET 子句。因此,当 check_function_bodies 关闭时,那些结果可能受 GUC 参数影响的检查肯定都应跳过,以避免在恢复转储时出现虚假的失败。 diff --git a/zh/14/plperl.sgml b/zh/14/plperl.sgml index 7fc5b272..a7da7851 100644 --- a/zh/14/plperl.sgml +++ b/zh/14/plperl.sgml @@ -13,7 +13,7 @@ - PL/Perl 是一种可载入的过程语言,它允许使用 + PL/Perl 是一种可加载的过程语言,它允许使用 Perl 编程语言编写 PostgreSQL 函数和过程。 @@ -32,8 +32,7 @@ - 如果把该语言安装到 template1 中,之后创建的所有 - 数据库都会自动安装该语言。 + 如果把某种语言安装到template1中,之后创建的所有数据库都会自动安装该语言。 @@ -57,9 +56,9 @@ CREATE FUNCTION funcname (argument-types) RETURNS return-type --- function attributes can go here +-- 函数属性可以写在这里 AS $$ - # PL/Perl function body goes here + # PL/Perl 函数体写在这里 $$ LANGUAGE plperl; @@ -78,7 +77,7 @@ $$ LANGUAGE plperl; DO $$ - # PL/Perl code + # PL/Perl 代码 $$ LANGUAGE plperl; @@ -136,15 +135,14 @@ $$ LANGUAGE plperl; 如果一个 SQL 空值空值in PL/Perl被传给一个函数,在 - Perl 中该参数值将呈现为undefined。上述函数定义对于 - 空输入的行为并不理想(实际上,它会把它们当作零)。我们可以在函数 + sortas="PL/Perl">在 PL/Perl 中被传给一个函数,在 + Perl 中该参数值将呈现为未定义。上述函数定义对于 + 空值输入的行为并不理想(实际上,它会把它们当作零)。我们可以在函数 定义中添加 STRICT,让 PostgreSQL 采取更合理的做法:如果传入空值, - 函数将根本不会被调用,而是自动返回空结果。另一种方式是在函数体中 + 函数将根本不会被调用,而是自动返回空值结果。另一种方式是在函数体中 检查未定义输入。例如,假设我们希望在 - perl_max 的两个参数中一个为空、另一个非空时, - 返回非空参数而不是空值: + perl_max 的两个参数中一个为空值、另一个非空值时,返回非空值参数而不是空值: CREATE FUNCTION perl_max (integer, integer) RETURNS integer AS $$ @@ -186,7 +184,7 @@ $$ LANGUAGE plperl; bool_plperl 扩展提供了合适的转换。要使用它, 请先安装该扩展: -CREATE EXTENSION bool_plperl; -- or bool_plperlu for PL/PerlU +CREATE EXTENSION bool_plperl; -- 对于 PL/PerlU,则使用 bool_plperlu 然后对接收或返回 bool 的 PL/Perl 函数使用 TRANSFORM 函数属性,例如: @@ -199,7 +197,7 @@ AS $$ $$ LANGUAGE plperl; 应用该转换后,Perl 会将 bool 参数视为 - 1 或空值,从而能正确表示真或假。如果函数结果类型为 + 1 或空字符串,从而能正确表示真或假。如果函数结果类型为 bool,则其真或假取决于 Perl 是否会将返回值求值为真。 对函数内部执行的 SPI 查询,其布尔查询参数和结果也会进行类似的转换 ()。 @@ -232,12 +230,12 @@ CREATE OR REPLACE FUNCTION concat_array_elements(text[]) RETURNS TEXT AS $$ my $result = ""; return undef if (!defined $arg); - # as an array reference + # 作为数组引用 for (@$arg) { $result .= $_; } - # also works as a string + # 也可以作为字符串使用 $result .= $arg; return $result; @@ -248,7 +246,8 @@ SELECT concat_array_elements(ARRAY['PL','/','Perl']); - 多维数组会以所有 Perl 程序员都熟悉的方式,表示为对低维数组引用的引用。 + 多维数组按 Perl 程序员熟悉的方式表示为指向较低维数组的引用, + 而这些数组的元素又是引用。 @@ -357,11 +356,11 @@ SELECT * FROM perl_set(); 如果希望在代码中使用 strict 编译指示,可以有几种 选择。对于临时的全局用法,可以 SET - plperl.use_strict 为 true。这会影响后续编译的 + plperl.use_strict 为真。这会影响后续编译的 PL/Perl 函数,但不会影响当前会话中已经编译的 函数。对于永久的全局用法,可以在 postgresql.conf 文件中将 - plperl.use_strict 设为 true。 + plperl.use_strict 设为真。 @@ -417,7 +416,7 @@ use strict; spi_exec_query(query [, limit]) spi_exec_query - in PL/Perl + 在 PL/Perl 中 @@ -503,7 +502,7 @@ SELECT * FROM test_munge(); spi_query(command) spi_query - in PL/Perl + 在 PL/Perl 中 @@ -511,7 +510,7 @@ SELECT * FROM test_munge(); spi_fetchrow(cursor) spi_fetchrow - in PL/Perl + 在 PL/Perl 中 @@ -519,7 +518,7 @@ SELECT * FROM test_munge(); spi_cursor_close(cursor) spi_cursor_close - in PL/Perl + 在 PL/Perl 中 @@ -539,7 +538,7 @@ CREATE OR REPLACE FUNCTION lotsa_md5 (INTEGER) RETURNS SETOF foo_type AS $$ my $file = '/usr/share/dict/words'; my $t = localtime; elog(NOTICE, "opening file $file at $t" ); - open my $fh, '<', $file # ooh, it's a file access! + open my $fh, '<', $file # 注意,这里访问了文件! or elog(ERROR, "cannot open $file for reading: $!"); my @words = <$fh>; close $fh; @@ -579,7 +578,7 @@ SELECT * from lotsa_md5(500); spi_prepare(command, argument types) spi_prepare - in PL/Perl + 在 PL/Perl 中 @@ -587,7 +586,7 @@ SELECT * from lotsa_md5(500); spi_query_prepared(plan, arguments) spi_query_prepared - in PL/Perl + 在 PL/Perl 中 @@ -595,7 +594,7 @@ SELECT * from lotsa_md5(500); spi_exec_prepared(plan [, attributes], arguments) spi_exec_prepared - in PL/Perl + 在 PL/Perl 中 @@ -603,7 +602,7 @@ SELECT * from lotsa_md5(500); spi_freeplan(plan) spi_freeplan - in PL/Perl + 在 PL/Perl 中 @@ -612,7 +611,7 @@ SELECT * from lotsa_md5(500); spi_preparespi_query_preparedspi_exec_preparedspi_freeplan - 提供相同的功能,但用于预处理查询。spi_prepare + 提供相同的功能,但用于预备查询。spi_prepare 接受一个带编号参数占位符($1、$2 等)的查询字符串,以及参数类型的 字符串列表: @@ -631,7 +630,7 @@ $plan = spi_prepare('SELECT * FROM test WHERE id > $1 AND name = $2', - 预处理查询的优点在于,一个准备好的计划可以用于多次查询执行。当计划 + 预备查询的优点在于,一个准备好的计划可以用于多次查询执行。当计划 不再需要时,可以用 spi_freeplan 将其释放: CREATE OR REPLACE FUNCTION init() RETURNS VOID AS $$ @@ -708,7 +707,7 @@ SELECT release_hosts_query(); spi_commit() spi_commit - in PL/Perl + 在 PL/Perl 中 @@ -716,7 +715,7 @@ SELECT release_hosts_query(); spi_rollback() spi_rollback - in PL/Perl + 在 PL/Perl 中 @@ -756,7 +755,7 @@ CALL transaction_test1(); - PL/Perl 中的工具函数 + PL/Perl 中的辅助函数 @@ -765,7 +764,7 @@ CALL transaction_test1(); elog(level, msg) elog - in PL/Perl + 在 PL/Perl 中 @@ -791,7 +790,7 @@ CALL transaction_test1(); quote_literal(string) quote_literal - in PL/Perl + 在 PL/Perl 中 @@ -812,7 +811,7 @@ CALL transaction_test1(); quote_nullable(string) quote_nullable - in PL/Perl + 在 PL/Perl 中 @@ -831,7 +830,7 @@ CALL transaction_test1(); quote_ident(string) quote_ident - in PL/Perl + 在 PL/Perl 中 @@ -850,7 +849,7 @@ CALL transaction_test1(); decode_bytea(string) decode_bytea - in PL/Perl + 在 PL/Perl 中 @@ -868,7 +867,7 @@ CALL transaction_test1(); encode_bytea(string) encode_bytea - in PL/Perl + 在 PL/Perl 中 @@ -885,7 +884,7 @@ CALL transaction_test1(); encode_array_literal(array) encode_array_literal - in PL/Perl + 在 PL/Perl 中 @@ -908,7 +907,7 @@ CALL transaction_test1(); encode_typed_literal(value, typename) encode_typed_literal - in PL/Perl + 在 PL/Perl 中 @@ -926,7 +925,7 @@ CALL transaction_test1(); encode_array_constructor(array) encode_array_constructor - in PL/Perl + 在 PL/Perl 中 @@ -947,7 +946,7 @@ CALL transaction_test1(); looks_like_number(string) looks_like_number - in PL/Perl + 在 PL/Perl 中 @@ -967,7 +966,7 @@ CALL transaction_test1(); is_array_ref(argument) is_array_ref - in PL/Perl + 在 PL/Perl 中 @@ -1025,9 +1024,9 @@ CREATE OR REPLACE FUNCTION myfuncs() RETURNS void AS $$ }; $$ LANGUAGE plperl; -SELECT myfuncs(); /* initializes the function */ +SELECT myfuncs(); /* 初始化函数 */ -/* Set up a function that uses the quote function */ +/* 创建一个使用加引号函数的函数 */ CREATE OR REPLACE FUNCTION use_quote(TEXT) RETURNS text AS $$ my $text_to_quote = shift; @@ -1042,11 +1041,9 @@ $$ LANGUAGE plperl; - 出于安全原因,PL/Perl 会为某个 SQL 角色调用的函数在该角色专用的独立 - Perl 解释器中执行。这可以防止一个用户意外或恶意地干扰另一个用户的 + 出于安全原因,PL/Perl 会在每个 SQL 角色各自独立的 Perl 解释器中执行该角色调用的函数。这可以防止一个用户意外或恶意地干扰另一个用户的 PL/Perl 函数行为。每个这样的解释器都有自己的 - %_SHARED 变量值和其他全局状态。因此,只有在两个 - PL/Perl 函数都由同一 SQL 角色执行时,它们才会共享 + %_SHARED 变量值和其他全局状态。因此,当且仅当两个 PL/Perl 函数都由同一 SQL 角色执行时,它们才会共享 %_SHARED 的值。在某些应用中,一个会话可能会在多个 SQL 角色下执行代码(通过 SECURITY DEFINER 函数、 使用 SET ROLE 等),这时可能需要显式采取措施, @@ -1059,29 +1056,29 @@ $$ LANGUAGE plperl; - 可信与不可信的 PL/Perl + 受信任与不受信任的 PL/Perl - trusted + 受信任的 PL/Perl 通常,PL/Perl 会被安装为一种名为 plperl 的 - 可信编程语言。在这种设置下,为了保持安全性,某些 Perl + 受信任的编程语言。在这种设置下,为了保持安全性,某些 Perl 操作会被禁用。一般来说,受限制的是那些与环境交互的操作,包括文件句柄 操作、requireuse (针对外部模块)。它无法像 C 函数那样访问数据库服务器进程的内部, - 也无法以服务器进程的权限获取操作系统级访问。因此,可以允许任何无权限 + 也无法以服务器进程的权限获取操作系统级访问。因此,可以允许任何无特权 的数据库用户使用这种语言。 - 可信 PL/Perl 依赖 Perl 的 Opcode 模块来维持安全性。 + 受信任的 PL/Perl 依赖 Perl 的 Opcode 模块来维持安全性。 Perl 的 文档 - 指出,该模块对于可信 PL/Perl 这一使用场景并不有效。若你的安全需求 + 指出,该模块对于受信任的 PL/Perl 这一使用场景并不有效。若你的安全需求 不能接受该警告中的不确定性,请考虑执行 REVOKE USAGE ON LANGUAGE plperl FROM PUBLIC @@ -1105,16 +1102,16 @@ $$ LANGUAGE plperl; 有时需要编写不受这些限制的 Perl 函数。例如,可能需要一个能发送邮件的 Perl 函数。为处理这类情况,也可以把 PL/Perl 安装成一种 - 不可信语言(通常称为 + 不受信任的语言(通常称为 PL/PerlUPL/PerlU)。 在这种情况下,完整的 Perl 语言都可用。安装该语言时,使用语言名 - plperlu 就会选择不可信的 PL/Perl 变体。 + plperlu 就会选择不受信任的 PL/Perl 变体。 PL/PerlU 函数的编写者必须注意,函数不能被 用于任何非预期用途,因为它能够执行以数据库管理员身份登录的用户所能 - 做的任何事情。请注意,数据库系统只允许数据库超级用户用不可信语言创建 + 做的任何事情。请注意,数据库系统只允许数据库超级用户用不受信任的语言创建 函数。 @@ -1249,7 +1246,7 @@ $$ LANGUAGE plperl; $_TD->{relname} - 触发该触发器的表名。该字段已废弃,并且可能会在未来版本中移除。 + 触发该触发器的表名。该字段已弃用,并且可能会在未来版本中移除。 请改用 $_TD->{table_name}。 @@ -1328,12 +1325,12 @@ CREATE TABLE test ( CREATE OR REPLACE FUNCTION valid_id() RETURNS trigger AS $$ if (($_TD->{new}{i} >= 100) || ($_TD->{new}{i} <= 0)) { - return "SKIP"; # skip INSERT/UPDATE command + return "SKIP"; # 跳过 INSERT/UPDATE 命令 } elsif ($_TD->{new}{v} ne "immortal") { $_TD->{new}{v} .= "(modified by trigger)"; - return "MODIFY"; # modify row and execute INSERT/UPDATE command + return "MODIFY"; # 修改行并执行 INSERT/UPDATE 命令 } else { - return; # execute INSERT/UPDATE command + return; # 执行 INSERT/UPDATE 命令 } $$ LANGUAGE plperl; @@ -1490,7 +1487,7 @@ DO 'elog(WARNING, join ", ", sort keys %INC)' LANGUAGE plperl; 也会发生。这是在 plperl.on_init 完成的任何初始化 之后进行的。执行这段代码时 SPI 函数不可用。 plperl.on_plperl_init 中的 Perl 代码是在对解释器 - 进行锁定之后执行的,因此只能执行可信操作。 + 进行锁定之后执行的,因此只能执行受信任的操作。 diff --git a/zh/14/plpgsql.sgml b/zh/14/plpgsql.sgml index 357ffc93..a6e7a642 100644 --- a/zh/14/plpgsql.sgml +++ b/zh/14/plpgsql.sgml @@ -144,7 +144,7 @@ CREATE FUNCTION somefunc(integer, text) RETURNS integer AS 'function body text' LANGUAGE plpgsql; - 就 CREATE FUNCTION 而言,函数体目前只是一个字符串字面量。编写函数体时,通常最好使用美元引用(见 ),而不是普通的单引号语法。如果不使用美元引用,函数体中的任何单引号或反斜线都必须通过双写进行转义。本章几乎所有示例的函数体都使用了美元引用。 + 就 CREATE FUNCTION 而言,函数体只是一个字符串字面量。编写函数体时,通常最好使用美元引用(见 ),而不是普通的单引号语法。如果不使用美元引用,函数体中的任何单引号或反斜线都必须通过双写进行转义。本章几乎所有示例的函数体都使用了美元引用。 @@ -259,24 +259,13 @@ arow RECORD; 变量的默认值会在每次进入该块时重新计算并赋给该变量,而不是每次函数调用只计算一次。因此,例如把 now() 赋给一个 timestamp 类型变量,会使该变量得到当前函数调用时的时间,而不是函数预编译时的时间。 - - 示例: - + 例如: quantity integer DEFAULT 32; url varchar := 'http://mysite.com'; user_id CONSTANT integer := 10; - - 一旦声明,变量的值可以在同一块中的后续初始化表达式中使用,例如: - -DECLARE - x integer := 1; - y integer := x + 1; - - - 声明函数参数 @@ -340,7 +329,7 @@ $$ LANGUAGE plpgsql; - 当 PL/pgSQL 函数声明了输出参数时,输出参数也会像普通输入参数一样获得 $n 名称和可选别名。输出参数本质上是一个初始值为 NULL 的变量,应在函数执行期间给它赋值。该参数的最终值就是返回值。例如,sales-tax 的示例也可以这样写: + 当 PL/pgSQL 函数声明了输出参数时,输出参数也会像普通输入参数一样获得 $n 名称和可选别名。输出参数本质上是一个初始值为 NULL 的变量,应在函数执行期间给它赋值。该参数的最终值就是返回值。例如,销售税的示例也可以这样写: CREATE FUNCTION sales_tax(subtotal real, OUT tax real) AS $$ @@ -465,7 +454,7 @@ $$ LANGUAGE plpgsql; SELECT add_three_values(1, 2, 4.7); - 可以正常工作,并会自动把整数输入提升为 numeric。如果使用 anyelement,则必须手工把这三个输入转换成同一类型。 + 可以正常工作,并会自动把整数输入提升为 numeric。如果使用 anyelement,则必须手工把这三个输入转换成同一类型。 @@ -499,26 +488,15 @@ DECLARE 复制类型 -name table.column%TYPE -name variable%TYPE +variable%TYPE - %TYPE 提供表列或先前已声明的 PL/pgSQL 变量的数据类型。你可以用它来声明用于保存数据库值的变量。例如,假设 users 表中有一个名为 user_id 的列。要声明一个与 users.user_id 具有相同数据类型的变量,可以这样写: - + %TYPE提供变量或表列的数据类型。可以用它声明将保存数据库值的变量。例如,假设有一个名为user_id的列,位于users表中。要声明一个数据类型与users.user_id相同的变量,可以写: user_id users.user_id%TYPE; - - 也可以在 %TYPE 后写数组修饰,从而创建保存被引用类型数组的变量: - -user_ids users.user_id%TYPE[]; -user_ids users.user_id%TYPE ARRAY[4]; -- 等价于上面一行 - - 与声明数组表列时一样,写多个方括号还是写具体数组维度都无关紧要:PostgreSQL 会把同一元素类型的所有数组都视为同一种类型,而不考虑维度数。(见 。) - - 使用 %TYPE 的好处是,你不必知道所引用结构的实际数据类型;更重要的是,如果被引用项的数据类型将来发生变化(例如把 user_id 的类型从 integer 改成 real),你可能就不需要修改函数定义。 @@ -546,10 +524,6 @@ user_ids users.user_id%TYPE ARRAY[4]; -- 等价于上面一行 行变量既可以通过 table_name%ROWTYPE 记法声明为与现有表或视图的行具有相同类型,也可以通过给出某个复合类型的名称来声明。(由于每个表都有一个同名的关联复合类型,所以在 PostgreSQL 中实际上写不写 %ROWTYPE 并无区别;不过带 %ROWTYPE 的形式可移植性更好。) - - 与 %TYPE 一样,%ROWTYPE 后也可以跟数组修饰,用于声明保存被引用复合类型数组的变量。 - - 函数参数也可以是复合类型(完整的表行)。在这种情况下,相应的标识符 $n 就是一个行变量,并且可以从中选取字段,例如 $1.user_id @@ -594,12 +568,12 @@ SELECT merge_fields(t.*) FROM table1 t WHERE ... ; <application>PL/pgSQL</application>变量的排序规则 - collation - in PL/pgSQL + 排序规则 + 在 PL/pgSQL 中 - 当 PL/pgSQL 函数具有一个或多个可排序数据类型参数时,每次函数调用都会根据分配给实际参数的排序规则确定出一个排序规则,如 所述。如果该排序规则能成功确定出来(即参数之间的隐式排序规则没有冲突),那么所有可排序参数都会被视为隐式带有该排序规则。这会影响函数中那些受排序规则影响的操作。例如,考虑 + 当 PL/pgSQL 函数具有一个或多个支持排序规则的数据类型参数时,每次函数调用都会根据分配给实际参数的排序规则确定出一个排序规则,如 所述。如果该排序规则能成功确定出来(即参数之间的隐式排序规则没有冲突),那么所有支持排序规则的参数都会被视为隐式带有该排序规则。这会影响函数中那些受排序规则影响的操作。例如,考虑 CREATE FUNCTION less_than(a text, b text) RETURNS boolean AS $$ @@ -616,7 +590,7 @@ SELECT less_than(text_field_1, text_field_2 COLLATE "C") FROM table1; - 此外,确定出的排序规则也会被视为任何可排序数据类型局部变量的排序规则。因此,即使把这个函数写成下面这样,其行为也不会有任何不同: + 此外,确定出的排序规则也会被视为任何支持排序规则的数据类型局部变量的排序规则。因此,即使把这个函数写成下面这样,其行为也不会有任何不同: CREATE FUNCTION less_than(a text, b text) RETURNS boolean AS $$ @@ -631,11 +605,11 @@ $$ LANGUAGE plpgsql; - 如果函数没有可排序数据类型的参数,或者无法为它们确定共同排序规则,那么参数和局部变量将使用其数据类型的默认排序规则(通常是数据库默认排序规则,但对于域类型变量也可能不同)。 + 如果函数没有支持排序规则的数据类型的参数,或者无法为它们确定共同排序规则,那么参数和局部变量将使用其数据类型的默认排序规则(通常是数据库默认排序规则,但对于域类型变量也可能不同)。 - 通过在可排序数据类型局部变量的声明中加入 COLLATE 选项,可以为其指定不同的排序规则,例如 + 通过在支持排序规则的数据类型局部变量的声明中加入 COLLATE 选项,可以为其指定不同的排序规则,例如 DECLARE @@ -666,7 +640,7 @@ $$ LANGUAGE plpgsql; 表达式 - PL/pgSQL语句中使用的所有表达式都会由服务器的主SQL执行器处理。例如,当你写下这样一条PL/pgSQL语句时: + PL/pgSQL 语句中使用的所有表达式都会由服务器的主 SQL 执行器处理。例如,当写下这样一条 PL/pgSQL 语句时: IF expression THEN ... @@ -674,7 +648,7 @@ IF expression THEN ... SELECT expression - 来计算该表达式。如中详细讨论的那样,在构造该SELECT命令时,PL/pgSQL变量名的每一次出现都会被替换成查询参数。这使得该SELECT的查询计划只需准备一次,然后就能在后续以不同变量值求值时重用。因此,表达式第一次被使用时,实际发生的事情本质上相当于执行了一条PREPARE命令。例如,如果已经声明了两个整数变量xy,并写下 + 来计算该表达式。如 中详细讨论的那样,在构造该 SELECT 命令时,PL/pgSQL 变量名的每一次出现都会被替换成查询参数。这使得该 SELECT 的查询计划只需准备一次,然后就能在后续以不同变量值求值时重用。因此,表达式第一次被使用时,实际发生的事情本质上相当于执行了一条 PREPARE 命令。例如,如果已经声明了两个整数变量 xy,并写下 IF x < y THEN ... @@ -682,7 +656,7 @@ IF x < y THEN ... PREPARE statement_name(integer, integer) AS SELECT $1 < $2; - 然后,在每次执行IF语句时,这条预备语句都会以当前PL/pgSQL变量值作为参数值被EXECUTE。通常这些细节对PL/pgSQL用户并不重要,但在诊断问题时了解它们会很有帮助。更多信息见。 + 然后,在每次执行 IF 语句时,这条预备语句都会以当前 PL/pgSQL 变量值作为参数值由 EXECUTE 执行。通常这些细节对 PL/pgSQL 用户并不重要,但在诊断问题时了解它们会很有帮助。更多信息见 @@ -699,7 +673,7 @@ PREPARE statement_name(integer, integer) AS SELECT $1 基本语句 - 在这一节和接下来的小节中,我们会描述PL/pgSQL能明确理解的所有语句类型。任何不被识别为这些语句类型之一的被假定为是一个 SQL 命令,并且会被发送给主数据库引擎执行,具体如中所述。 + 在这一节和接下来的小节中,我们会描述 PL/pgSQL 能明确理解的所有语句类型。任何不被识别为这些语句类型之一的语句都被视为 SQL 命令,并会被发送给主数据库引擎执行,具体如 中所述。 @@ -715,8 +689,7 @@ PREPARE statement_name(integer, integer) AS SELECT $1 SELECT命令被发送到主数据库引擎的方式计算。 该表达式必须得到一个单一值(如果该变量是一个行或记录变量, 它可能是一个行值)。该目标变量可以是一个简单变量( - 可以选择用一个块名限定)、一个行或记录变量的域或是一个简单 - 变量或域的数组的元素或者数组的切片。 + 可以选择用一个块名限定)、行或记录目标的字段,或者数组目标的元素或切片。 等号(=)可以被用来代替 PL/SQL-兼容的 := @@ -757,8 +730,8 @@ complex_array[n].realpart = 12.3; - 如果命令返回行(例如 SELECT,或者带 RETURNINGINSERT/UPDATE/DELETE/MERGE),有两种方式处理。 - 当命令最多返回一行,或者你只关心第一行的输出时,像往常一样编写命令,但要添加一个INTO子句来捕获输出,如中所述。为了处理所有的输出行,把命令写成FOR循环的数据源,如 中所述。 + 如果命令返回行(例如 SELECT,或者带 RETURNINGINSERT/UPDATE/DELETE),有两种方式处理。 + 当命令最多返回一行,或者只关心第一行的输出时,可照常编写该命令,但要添加一个 INTO 子句来捕获输出,如 中所述。要处理所有输出行,可将该命令写成 FOR 循环的数据源,如 中所述。 @@ -766,29 +739,29 @@ complex_array[n].realpart = 12.3; - PL/pgSQL变量值可以自动插入到可优化的SQL命令中,这些命令包括SELECTINSERTUPDATEDELETE以及某些包含其中之一的实用程序命令,比如EXPLAINCREATE TABLE ... AS SELECT。在这些命令中,命令文本中出现的任何PL/pgSQL变量名都会被查询参数替换,然后变量的当前值会在运行时作为参数值提供。这与前面描述的表达式处理完全相同;详情请参见。 + PL/pgSQL 变量值可以自动插入可优化的 SQL 命令中,这些命令包括 SELECTINSERTUPDATEDELETE 以及某些包含其中之一的工具命令,比如 EXPLAINCREATE TABLE ... AS SELECT。在这些命令中,命令文本中出现的任何 PL/pgSQL 变量名都会被查询参数替换,然后变量的当前值会在运行时作为参数值提供。这与前面描述的表达式处理完全相同;详情请参见 - 当以这种方式执行一个可优化的 SQL 命令时,如中讨论的,PL/pgSQL会为该命令缓存并重用执行计划。 + 当以这种方式执行一个可优化的 SQL 命令时,如中讨论的,PL/pgSQL可能会为该命令缓存并重用执行计划。 - 不可优化的SQL命令(也称为实用命令)不能够接受查询参数。 所以自动替换PL/pgSQL的变量在这类命令中不起作用。 要在从PL/pgSQL执行的实用程序命令中包含非常量文本,你必须将实用程序命令构建为一个字符串,然后EXECUTE它,如中所讨论的。 + 不可优化的 SQL 命令(也称为工具命令)不能接受查询参数。因此,自动替换 PL/pgSQL 变量在这类命令中不起作用。要在从 PL/pgSQL 执行的工具命令中包含非常量文本,必须将工具命令构建为一个字符串,然后用 EXECUTE 执行它,如 中所讨论的。 - EXECUTE也必须使用,如果你想以某种其他方式修改命令,而不是提供数据值,例如改变表名。 + 如果想通过其他方式修改命令,而不只是提供数据值,例如改变表名,也必须使用 EXECUTE - 有时候计算一个表达式或SELECT查询但抛弃其结果是有用的,例如调用一个有副作用但是没有有用的结果值的函数。在PL/pgSQL中要这样做,可使用PERFORM语句: + 有时需要计算一个表达式或 SELECT 查询但丢弃其结果,例如调用一个有副作用但没有有用结果值的函数。要在 PL/pgSQL 中这样做,可使用 PERFORM 语句: PERFORM query; - 这会执行query并且丢弃掉结果。以写一个SQL SELECT命令相同的方式写该query,并且将初始的关键词SELECT替换为PERFORM。对于WITH查询,使用PERFORM并且接着把该查询放在圆括号中(在这种情况中,该查询只能返回一行)。PL/pgSQL变量将被替换到该查询中,正如上面描述的查询,并且计划被以相同的方式被缓存。还有,如果该查询产生至少一行,特殊变量FOUND会被设置为真,而如果它不产生行则设置为假(见)。 + 这会执行 query 并丢弃结果。query 的写法与 SQL SELECT 命令相同,只需把开头的关键词 SELECT 替换为 PERFORM。对于 WITH 查询,使用 PERFORM 并将该查询放在圆括号中(在这种情况下,该查询只能返回一行)。PL/pgSQL 变量会像上文所述那样替换到查询中,计划也会以相同方式缓存。此外,如果该查询产生至少一行,特殊变量 FOUND 会被设置为真;如果不产生行,则设置为假(见 )。 @@ -812,12 +785,12 @@ PERFORM create_mv('cs_session_page_requests_mv', my_query); SELECT INTO - in PL/pgSQL + 在 PL/pgSQL 中 RETURNING INTO - in PL/pgSQL + 在 PL/pgSQL 中 @@ -828,10 +801,9 @@ SELECT select_expressions INTO STRICTexpressions INTO STRICT target; UPDATE ... RETURNING expressions INTO STRICT target; DELETE ... RETURNING expressions INTO STRICT target; -MERGE ... RETURNING expressions INTO STRICT target; - 其中target可以是记录变量、行变量,或者由简单变量和记录/行字段组成的逗号分隔列表。PL/pgSQL变量会像前文所述那样替换进命令的其余部分(也就是除了INTO子句之外的所有部分),并且计划也会以同样的方式缓存。这适用于SELECT、带有RETURNINGINSERT/UPDATE/DELETE/以及某些返回行集的工具命令,例如EXPLAIN。除了INTO子句之外,该 SQL 命令的写法与在PL/pgSQL之外完全相同。 + 其中target可以是记录变量、行变量,或者由简单变量和记录/行字段组成的逗号分隔列表。PL/pgSQL变量会像前文所述那样替换进命令的其余部分(也就是除了INTO子句之外的所有部分),并且计划也会以同样的方式缓存。这适用于SELECT、带有RETURNINGINSERT/UPDATE/DELETE,以及某些返回行集的工具命令,例如EXPLAIN。除了INTO子句之外,该 SQL 命令的写法与在PL/pgSQL之外完全相同。 @@ -842,7 +814,7 @@ MERGE ... RETURNING expressions INTO STRICT - 如果一个行变量或一个变量列表被用作目标,该命令的结果列必须完全匹配该结果的结构,包括数量和数据类型,否则会发生一个运行时错误。当一个记录变量是目标时,它会自动地把自身配置成命令的结果列组成的行类型。 + 如果一个行变量或一个变量列表被用作目标,该命令的结果列必须完全匹配该目标的结构,包括数量和数据类型,否则会发生一个运行时错误。当一个记录变量是目标时,它会自动地把自身配置成命令的结果列组成的行类型。 @@ -850,7 +822,7 @@ MERGE ... RETURNING expressions INTO STRICT - 如果STRICT没有在INTO子句中被指定,那么target将被设置为该命令返回的第一个行,或者在该命令不返回行时设置为空(注意除非使用了ORDER BY,否则第一行的界定并不清楚)。第一行之后的任何结果行都会被抛弃。你可以检查特殊的FOUND变量(见)来确定是否返回了一行: + 如果STRICT没有在INTO子句中被指定,那么target将被设置为该命令返回的第一个行,或者在该命令不返回行时设置为空值(注意除非使用了ORDER BY,否则第一行的界定并不清楚)。第一行之后的任何结果行都会被抛弃。你可以检查特殊的FOUND变量(见)来确定是否返回了一行: SELECT * INTO myrec FROM emp WHERE empname = myname; @@ -875,11 +847,11 @@ END; - 对于带有RETURNINGINSERT/UPDATE/DELETE/即使没有指定STRICTPL/pgSQL也会针对多于一个返回行的情况报告一个错误。这是因为没有类似于ORDER BY的选项可以用来决定应该返回哪个被影响的行。 + 对于带有RETURNINGINSERT/UPDATE/DELETE,即使没有指定STRICTPL/pgSQL也会针对多于一个返回行的情况报告一个错误。这是因为没有类似于ORDER BY的选项可以用来决定应该返回哪个被影响的行。 - 如果为函数启用了print_strict_params,那么当由于不满足STRICT要求而抛出错误时,错误消息的DETAIL部分将包含传给该命令的参数信息。你可以通过设置plpgsql.print_strict_params来修改所有函数的print_strict_params设置,不过只有此后重新编译的函数才会受影响。也可以通过编译器选项按函数启用它,例如: + 如果为函数启用了print_strict_params,那么当由于不满足STRICT要求而抛出错误时,错误消息的DETAIL部分将包含传给该命令的参数信息。你可以通过设置plpgsql.print_strict_params来修改所有函数的print_strict_params设置,不过该设置只会影响此后编译的函数。也可以通过编译器选项按函数启用它,例如: CREATE FUNCTION get_userid(username text) RETURNS int AS $$ @@ -915,33 +887,31 @@ CONTEXT: PL/pgSQL function get_userid(text) line 6 at SQL statement 执行动态命令 - 很多时候你将想要在PL/pgSQL函数中产生动态命令,也就是每次执行中会涉及到不同表或不同数据类型的命令。PL/pgSQL通常对于命令所做的缓存计划尝试(如中讨论)在这种情境下无法工作。要处理这一类问题,需要提供EXECUTE语句: + 很多时候你将想要在PL/pgSQL函数中产生动态命令,也就是每次执行中会涉及到不同表或不同数据类型的命令。PL/pgSQL通常对于命令所做的缓存计划尝试(如中讨论)在这种情境下无法工作。要处理这一类问题,提供了EXECUTE语句: EXECUTE command-string INTO STRICT target USING expression , ... ; - 其中command-string是一个能得到一个包含要被执行命令字符串(类型text)的表达式。可选的target是一个记录变量、一个行变量或者一个逗号分隔的简单变量以及记录/行域的列表,该命令的结果将存储在其中。可选的USING表达式提供要被插入到该命令中的值。 + 其中command-string是一个能得到一个包含要被执行命令字符串(类型text)的表达式。可选的target是一个记录变量、一个行变量或者一个逗号分隔的简单变量以及记录/行字段的列表,该命令的结果将存储在其中。可选的USING表达式提供要被插入到该命令中的值。 在计算得到的命令字符串中,不会做PL/pgSQL变量的替换。任何所需的变量值必须在命令字符串被构造时被插入其中,或者你可以使用下面描述的参数。 - - 还有,对于通过EXECUTE执行的命令不会有计划被缓存。该命令反而在每次运行时都会被做计划。因此,该命令字符串可以在执行不同表和列上动作的函数中被动态创建。 - + 此外,通过 EXECUTE 执行的命令不会缓存计划,而是在每次运行该语句时重新规划。因此,可以在函数中动态构造命令字符串,对不同的表和列执行操作。 - INTO子句指定一个返回行的 SQL 命令的结果应该被赋值到哪里。如果提供了一个行或变量列表,它必须完全匹配查询命令结果的结构(当一个记录变量被提供时,它会自动把它自己配置为匹配结果结构)。如果返回多个行,只有第一个行会被赋值给INTO变量。如果没有返回行,NULL 会被赋值给INTO变量。如果没有指定INTO变量,该查询结果会被抛弃。 + INTO子句指定一个返回行的 SQL 命令的结果应该被赋值到哪里。如果提供了一个行变量或变量列表,它必须完全匹配查询命令结果的结构(当一个记录变量被提供时,它会自动把它自己配置为匹配结果结构)。如果返回多个行,只有第一个行会被赋值给INTO变量。如果没有返回行,NULL 会被赋值给INTO变量。如果没有指定INTO子句,该查询结果会被抛弃。 - 如果给出了STRICT选项,除非该查询刚好产生一行,否则将会报告一个错误。 + 如果给出了STRICT选项,除非该命令刚好产生一行,否则将会报告一个错误。 - 命令字符串可以使用参数值,它们在命令中用$1$2等引用。这些符号引用在USING子句中提供的值。这种方法常常更适合于把数据值作为文本插入到命令字符串中:它避免了将该值转换为文本以及转换回来的运行时负荷,并且它更不容易被 SQL 注入攻击,因为不需要引用或转义。一个示例是: + 命令字符串可以使用参数值,它们在命令中用$1$2等引用。这些符号引用在USING子句中提供的值。这种方法通常比把数据值作为文本插入命令字符串更可取:它避免了将该值转换为文本以及转换回来的运行时负荷,并且它更不容易被 SQL 注入攻击,因为不需要引用或转义。一个示例是: EXECUTE 'SELECT count(*) FROM mytable WHERE inserted_by = $1 AND inserted <= $2' INTO c @@ -959,25 +929,25 @@ EXECUTE 'SELECT count(*) FROM ' USING checked_user, checked_date; 一种更干净的方法是使用format()的 - %I规范,插入自带引号的表名或者列名: + %I 格式说明符,插入表名或列名并自动为其加上引号: EXECUTE format('SELECT count(*) FROM %I ' 'WHERE inserted_by = $1 AND inserted <= $2', tabname) INTO c USING checked_user, checked_date; - (此示例依赖于隐式连接由换行符分隔的字符串文字的 SQL 规则) + (此示例依赖于隐式连接由换行符分隔的字符串字面量的 SQL 规则) 参数符号的另一个限制是它们仅适用于可优化的SQL命令 (SELECT, INSERT, UPDATE, - DELETE, MERGE以及包含其中一个的某些命令)。 - 在其他语句类型(通称为实用程序语句)中,即使它们只是数据值,您也必须以文本方式插入值。 + DELETE以及包含其中一个的某些命令)。 + 在其他语句类型(通称为工具语句)中,即使它们只是数据值,你也必须以文本方式插入值。 - 在上面第一个示例中,带有一个简单的常量命令字符串和一些USING参数的EXECUTE命令在功能上等效于直接用PL/pgSQL写的命令,并且允许自动发生PL/pgSQL变量替换。重要的不同之处在于,EXECUTE会在每一次执行时根据当前的参数值重新计划该命令,而PL/pgSQL则是创建一个通用计划并且将其缓存以便重用。在最佳计划强依赖于参数值的情况中,使用EXECUTE来明确地保证不会选择一个通用计划是很有帮助的。 + 在上面第一个示例中,带有一个简单的常量命令字符串和一些USING参数的EXECUTE命令在功能上等效于直接用PL/pgSQL写的命令,并且允许自动发生PL/pgSQL变量替换。重要的不同之处在于,EXECUTE会在每一次执行时根据当前的参数值重新计划该命令,而PL/pgSQL则可能创建一个通用计划并且将其缓存以便重用。在最佳计划强依赖于参数值的情况中,使用EXECUTE来明确地保证不会选择一个通用计划是很有帮助的。 @@ -985,10 +955,7 @@ EXECUTE format('SELECT count(*) FROM %I ' - - - PL/pgSQL中的EXECUTE语句与EXECUTE PostgreSQL服务器支持的 SQL 语句无关。服务器的EXECUTE语句不能直接在PL/pgSQL函数中使用(并且也没有必要)。 - + PL/pgSQLEXECUTE 语句与 PostgreSQL 服务器支持的 SQL EXECUTE 语句无关。服务器的 EXECUTE 语句不能直接用于 PL/pgSQL 函数中(也没有这个必要)。 @@ -1052,19 +1019,19 @@ EXECUTE 'UPDATE tbl SET ' || ' WHERE key = ' || quote_nullable(keyvalue); - 如果正在处理的参数值可能为空,那么通常应该用quote_nullable来代替quote_literal。 + 如果正在处理的参数值可能为空值,那么通常应该用quote_nullable来代替quote_literal - 通常,必须小心地确保查询中的空值不会递送意料之外的结果。例如如果keyvalue为空,下面的WHERE子句 + 通常,必须小心地确保查询中的空值不会产生意料之外的结果。例如如果keyvalue为空值,下面的WHERE子句 'WHERE key = ' || quote_nullable(keyvalue) - 永远不会成功,因为在=操作符中使用空操作数得到的结果总是为空。如果想让空和一个普通键值一样工作,你应该将上面的命令重写成 + 永远不会成功,因为在=操作符中使用空值操作数得到的结果总是空值。如果想让空值像普通键值一样工作,你应该将上面的命令重写成 'WHERE key IS NOT DISTINCT FROM ' || quote_nullable(keyvalue) - (目前,IS NOT DISTINCT FROM的处理效率不如=,因此只有在非常必要时才这样做。关于空和IS DISTINCT的详细信息请见)。 + (目前,IS NOT DISTINCT FROM的处理效率不如=,因此只有在非常必要时才这样做。关于空值和IS DISTINCT的详细信息请见)。 @@ -1077,7 +1044,7 @@ EXECUTE 'UPDATE tbl SET ' || '$$ WHERE key = ' || quote_literal(keyvalue); - 因为如果newvalue的内容碰巧含有$$,那么这段代码就会出问题。同样的缺点可能适用于你选择的任何其他美元符号引用定界符。因此,要想安全地引用事先不知道的文本,必须恰当地使用quote_literalquote_nullablequote_ident。 + 因为如果newvalue的内容碰巧含有$$,那么这段代码就会出问题。同样的问题也适用于你选择的任何其他美元符号引用定界符。因此,要想安全地引用事先不知道的文本,必须恰当地使用quote_literalquote_nullablequote_ident @@ -1116,7 +1083,7 @@ EXECUTE format('UPDATE tbl SET %I = $1 WHERE key = $2', colname) GET CURRENT DIAGNOSTICS variable { = | := } item , ... ; - 这条命令允许检索系统状态指示符。CURRENT是一个噪声词(另见中的GET STACKED DIAGNOSTICS)。每个item是一个关键字, 它标识一个要被赋予给指定变量的状态值(变量应具有正确的数据类型来接收状态值)。中展示了当前可用的状态项。冒号等号(:=)可以被用来取代 SQL 标准的=符号。例如: + 这条命令允许检索系统状态指示符。CURRENT是一个噪声词(另见中的GET STACKED DIAGNOSTICS)。每个item是一个关键字, 它标识一个要被赋予给指定variable的状态值(变量应具有正确的数据类型来接收状态值)。中展示了当前可用的状态项。冒号等号(:=)可以被用来取代 SQL 标准的=符号。例如: GET DIAGNOSTICS integer_var = ROW_COUNT; @@ -1150,24 +1117,19 @@ GET DIAGNOSTICS integer_var = ROW_COUNT; text 描述当前调用栈的文本行(见 - - PG_ROUTINE_OID - oid - 当前函数的 OID -
第二种确定命令效果的方法是检查名为FOUND的特殊变量,类型为boolean。 - 在每次PL/pgSQL函数调用中,FOUND都是以 false 开头。 + 在每次PL/pgSQL函数调用中,FOUND的初始值都是 false。 它由以下类型的语句设置: - SELECT INTO语句在分配行时将FOUND设置为true, + SELECT INTO语句在为目标赋上一行值时将FOUND设置为true, 如果没有返回行则设置为false。 @@ -1178,10 +1140,7 @@ GET DIAGNOSTICS integer_var = ROW_COUNT; - - UPDATEINSERTDELETEMERGE - 语句在至少影响一行时将FOUND设置为true,如果没有影响行则设置为false。 - + UPDATEINSERTDELETE语句在至少影响一行时将FOUND设置为真,如果没有影响行则设置为假。 @@ -1199,7 +1158,7 @@ GET DIAGNOSTICS integer_var = ROW_COUNT; FORFOREACH语句在迭代一次或多次时将 FOUND设置为true,否则设置为false。 - 当循环退出时,FOUND被设置为这种方式; + 当循环退出时,FOUND会按上述方式设置; 在循环执行过程中,FOUND不会被循环语句修改, 尽管它可能会被循环体内的其他语句执行修改。 @@ -1295,7 +1254,7 @@ RETURN expression; - 如果函数返回的是标量类型,表达式结果会自动转换为函数的返回类型。但如果要返回一个组合(行)值,你必须写出一个恰好生成所需列集合的表达式。这可能需要显式类型转换。 + 如果函数返回的是标量类型,表达式结果会按照赋值部分的说明自动转换为函数的返回类型。但如果要返回一个复合(行)值,你必须写出一个恰好生成所需列集合的表达式。这可能需要显式类型转换。 @@ -1307,7 +1266,7 @@ RETURN expression; - 一个函数的返回值不能是未定义。如果控制到达了函数最顶层的块而没有碰到一个RETURN语句,那么会发生一个运行时错误。不过,这个限制不适用于带输出参数的函数以及返回void的函数。在这些情况中,如果顶层的块结束,将自动执行一个RETURN语句。 + 一个函数的返回值不能是未定义。如果控制到达了函数最顶层块的末尾而没有碰到一个RETURN语句,那么会发生一个运行时错误。不过,这个限制不适用于带输出参数的函数以及返回void的函数。在这些情况中,如果顶层的块结束,将自动执行一个RETURN语句。 @@ -1331,12 +1290,12 @@ RETURN (1, 2, 'three'::text); -- 必须把列类型转换成正确的类型 RETURN NEXT - in PL/pgSQL + 在 PL/pgSQL 中 RETURN QUERY - in PL/pgSQL + 在 PL/pgSQL 中 @@ -1346,7 +1305,7 @@ RETURN QUERY EXECUTE command-string < - 当 PL/pgSQL 函数被声明为返回 SETOF sometype 时,返回过程会略有不同。在这种情况下,要返回的各个项通过一系列 RETURN NEXTRETURN QUERY 命令指定,最后再用一个不带参数的 RETURN 命令表明函数已经执行完毕。RETURN NEXT 可用于标量和组合数据类型;对于组合结果类型,会返回完整的结果RETURN QUERY 会把查询执行结果追加到函数的结果集中。在同一个集合返回函数中,RETURN NEXTRETURN QUERY 可以自由混用,此时它们的结果会被串接起来。 + 当 PL/pgSQL 函数被声明为返回 SETOF sometype 时,返回过程会略有不同。在这种情况下,要返回的各个项通过一系列 RETURN NEXTRETURN QUERY 命令指定,最后再用一个不带参数的 RETURN 命令表明函数已经执行完毕。RETURN NEXT 可用于标量和复合数据类型;对于复合结果类型,会返回完整的结果RETURN QUERY 会把查询执行结果追加到函数的结果集中。在同一个集合返回函数中,RETURN NEXTRETURN QUERY 可以自由混用,此时它们的结果会被串接起来。 @@ -1511,7 +1470,7 @@ END IF; - IF-THEN语句是IF的最简单形式。 如果条件为真,在THENEND IF之间的语句将被执行。否则,将忽略它们。 + IF-THEN语句是IF的最简单形式。 如果条件为真,在THENEND IF之间的语句将被执行。否则,将忽略它们。 @@ -1594,7 +1553,7 @@ ELSIF number > 0 THEN ELSIF number < 0 THEN result := 'negative'; ELSE - -- 嗯,唯一的其他可能性是数字为空 + -- 嗯,唯一的其他可能性是 number 为 null result := 'NULL'; END IF; @@ -1690,9 +1649,7 @@ END CASE; - - 这种形式的CASEIF-THEN-ELSIF完全等价,唯一的区别是:如果省略了ELSE子句,CASE会报错,而不是简单地什么也不做。 - + 这种形式的CASEIF-THEN-ELSIF完全等价,唯一的区别是:如果执行到被省略的ELSE子句,就会报错,而不是简单地什么也不做。 @@ -1702,12 +1659,12 @@ END CASE; 简单循环 - loop + 循环 在 PL/pgSQL 中 - 使用LOOPEXITCONTINUEWHILEFORFOREACH语句,你可以安排PL/pgSQL重复一系列命令。 + 使用LOOPEXITCONTINUEWHILEFORFOREACH语句,你可以安排PL/pgSQL函数重复一系列命令。 @@ -1862,22 +1819,22 @@ END LOOP label ; - 这种形式的FOR会创建一个在一个整数范围上迭代的循环。变量name会自动定义为类型integer并且只在循环内存在(任何该变量名的现有定义在此循环内都将被忽略)。给出范围上下界的两个表达式在进入循环的时候计算一次。如果没有指定BY子句,迭代步长为 1,否则步长是BY中指定的值,该值也只在循环进入时计算一次。如果指定了REVERSE,那么在每次迭代后步长值会被减除而不是增加。 + 这种形式的FOR会创建一个在一个整数范围上迭代的循环。变量name会自动定义为类型integer并且只在循环内存在(任何该变量名的现有定义在此循环内都将被忽略)。给出范围上下界的两个表达式在进入循环的时候计算一次。如果没有指定BY子句,迭代步长为 1,否则步长是BY中指定的值,该值也只在循环进入时计算一次。如果指定了REVERSE,那么在每次迭代后会减去步长,而不是加上步长。 整数FOR循环的一些示例: FOR i IN 1..10 LOOP - -- 我在循环中将取值 1,2,3,4,5,6,7,8,9,10 + -- i 在循环中将取值 1,2,3,4,5,6,7,8,9,10 END LOOP; FOR i IN REVERSE 10..1 LOOP - -- 我在循环中将取值 10,9,8,7,6,5,4,3,2,1 + -- i 在循环中将取值 10,9,8,7,6,5,4,3,2,1 END LOOP; FOR i IN REVERSE 10..1 BY 2 LOOP - -- 我在循环中将取值 10,8,6,4,2 + -- i 在循环中将取值 10,8,6,4,2 END LOOP; @@ -1941,7 +1898,7 @@ $$ LANGUAGE plpgsql; - 在这类 FOR 语句中使用的 query,可以是任何向调用者返回行的 SQL 命令:最常见的是 SELECT,但也可以是带 RETURNING 子句的 INSERTUPDATEDELETEMERGE。某些实用程序命令,如 EXPLAIN,也可以用于此处。 + 在这类 FOR 语句中使用的 query,可以是任何向调用者返回行的 SQL 命令:最常见的是 SELECT,但也可以是带 RETURNING 子句的 INSERTUPDATEDELETE。某些工具命令,如 EXPLAIN,也可以用于此处。 @@ -1956,7 +1913,7 @@ FOR target IN EXECUTE text_expressionstatements END LOOP label ; - 这个示例类似前面的形式,只不过源查询被指定为一个字符串表达式,在每次进入FOR循环时都会计算它并且重新计划。这允许程序员在一个预先计划好了的命令的速度和一个动态命令的灵活性之间进行选择,就像一个纯EXECUTE语句那样。在使用EXECUTE时,可以通过USING将参数值插入到动态命令中。 + 这个示例类似前面的形式,只不过源查询被指定为一个字符串表达式,在每次进入FOR循环时都会计算它并且重新计划。这允许程序员在一个预先计划好了的命令的速度和一个动态命令的灵活性之间进行选择,就像一个纯EXECUTE语句那样。与EXECUTE一样,可以通过USING将参数值插入到动态命令中。 @@ -1969,7 +1926,7 @@ END LOOP label ; 遍历数组 - FOREACH循环很像FOR循环,但它不是遍历 SQL 查询返回的行,而是遍历数组值的元素。(一般来说,FOREACH用于遍历组合值表达式的组成部分;未来还可能加入遍历数组以外其他组合值的变体。)用于遍历数组的FOREACH语句如下: + FOREACH循环很像FOR循环,但它不是遍历 SQL 查询返回的行,而是遍历数组值的元素。(一般来说,FOREACH用于遍历复合值表达式的组成部分;未来还可能加入遍历数组以外其他复合值的变体。)用于遍历数组的FOREACH语句如下: <<label>> @@ -1997,7 +1954,7 @@ END; $$ LANGUAGE plpgsql; - 元素会按存储顺序访问,而不管数组有多少维。尽管target通常只是单个变量,但在遍历组合值(记录)数组时,它也可以是一个变量列表。在这种情况下,每个数组元素都会按组合值的连续列给这些变量赋值。 + 元素会按存储顺序访问,而不管数组有多少维。尽管target通常只是单个变量,但在遍历复合值(记录)数组时,它也可以是一个变量列表。在这种情况下,每个数组元素都会按复合值的连续列给这些变量赋值。 @@ -2030,8 +1987,8 @@ NOTICE: row = {10,11,12} 捕获错误 - exceptions - in PL/pgSQL + 异常 + 在 PL/pgSQL 中 @@ -2054,7 +2011,7 @@ END; - 如果没有发生错误,这种形式的块只是简单地执行所有statements, 并且接着控制转到END之后的下一个语句。但是如果在statements内发生了一个错误,则会放弃对statements的进一步处理,然后控制会转到EXCEPTION列表。系统会在列表中寻找匹配所发生错误的第一个condition。如果找到一个匹配,则执行对应的handler_statements,并且接着把控制转到END之后的下一个语句。如果没有找到匹配,该错误就会传播出去,就好像根本没有EXCEPTION一样:错误可以被一个带有EXCEPTION的闭合块捕捉,如果没有EXCEPTION则中止该函数的处理。 + 如果没有发生错误,这种形式的块只是简单地执行所有statements, 并且接着控制转到END之后的下一个语句。但是如果在statements内发生了一个错误,则会放弃对statements的进一步处理,然后控制会转到EXCEPTION列表。系统会在列表中寻找匹配所发生错误的第一个condition。如果找到一个匹配,则执行对应的handler_statements,并且接着把控制转到END之后的下一个语句。如果没有找到匹配,该错误就会传播出去,就好像根本没有EXCEPTION一样:错误可以被一个带有EXCEPTION的外围块捕捉,如果没有这样的块则中止该函数的处理。 @@ -2091,7 +2048,7 @@ END; - 进入和退出一个包含EXCEPTION子句的块要比不包含EXCEPTION的块开销大的多。因此,只在必要的时候使用EXCEPTION。 + 进入和退出一个包含EXCEPTION子句的块要比不包含该子句的块开销大得多。因此,只在必要的时候使用EXCEPTION @@ -2118,9 +2075,9 @@ BEGIN IF found THEN RETURN; END IF; - -- 不在这里,那么尝试插入该键 + -- 该键不存在,因此尝试插入 -- 如果其他某人并发地插入同一个键, - -- 我们可能得到一个唯一键失败 + -- 就可能发生违反唯一约束的错误 BEGIN INSERT INTO db(a,b) VALUES (key, data); RETURN; @@ -2159,7 +2116,7 @@ SELECT merge_db(1, 'dennis'); GET STACKED DIAGNOSTICS variable { = | := } item , ... ; - 每个item是一个关键词,它标识一个被赋予给指定变量(应该具有接收该值的正确数据类型)的状态值。中显示了当前可用的状态项。 + 每个item是一个关键词,它标识一个被赋予给指定variable(应该具有接收该值的正确数据类型)的状态值。中显示了当前可用的状态项。 @@ -2271,7 +2228,7 @@ END; 获得执行位置信息 - GET DIAGNOSTICS(之前在中描述)命令检索有关当前执行状态的信息(反之上文讨论的GET STACKED DIAGNOSTICS命令会把有关执行状态的信息报告成一个以前的错误)。它的PG_CONTEXT状态项可用于标识当前执行位置。状态项PG_CONTEXT将返回一个文本字符串,其中有描述该调用栈的多行文本。第一行会指向当前函数以及当前正在执行GET DIAGNOSTICS的命令。第二行及其后的行表示调用栈中更上层的调用函数。例如: + GET DIAGNOSTICS(之前在中描述)命令检索有关当前执行状态的信息(反之上文讨论的GET STACKED DIAGNOSTICS命令报告先前发生错误时的执行状态信息)。它的PG_CONTEXT状态项可用于标识当前执行位置。状态项PG_CONTEXT将返回一个文本字符串,其中包含一行或多行描述该调用栈的文本。第一行会指向当前函数以及当前正在执行的GET DIAGNOSTICS命令。第二行及其后的行表示调用栈中更上层的调用函数。例如: CREATE OR REPLACE FUNCTION outer_func() RETURNS integer AS $$ @@ -2315,7 +2272,7 @@ CONTEXT: PL/pgSQL function outer_func() line 3 at RETURN 游标 - cursor + 游标 在 PL/pgSQL 中 @@ -2347,7 +2304,7 @@ DECLARE - 当游标查询使用 FOR UPDATE/SHARE 时,不能使用 SCROLL 选项。此外,对于涉及易失函数的查询,最好使用 NO SCROLLSCROLL 的实现假定重新读取查询输出会得到一致的结果,而易失函数并不满足这一假设。 + 当游标查询使用 FOR UPDATE/SHARE 时,不能使用 SCROLL 选项。此外,对于涉及易失函数的查询,最好使用 NO SCROLLSCROLL 的实现假定重新读取查询输出会得到一致的结果,而易失函数可能无法满足这一假设。 @@ -2356,25 +2313,16 @@ DECLARE 打开游标 - 在能够使用游标检索行之前,必须先将其打开(这等效于 SQL 命令DECLARE CURSOR)。PL/pgSQL有三种形式的OPEN命令,其中两种用于未绑定游标变量,另一种用于已绑定游标变量。 + 在能够使用游标检索行之前,必须先将其打开(这等效于 SQL 命令DECLARE CURSOR)。PL/pgSQL有三种形式的OPEN命令,其中两种用于未绑定游标变量,另一种用于已绑定游标变量。 - 可以通过中描述的FOR语句在不显式打开游标的情况下使用已绑定的游标变量。FOR 循环会打开该游标,并在循环完成时再次关闭它。 + 可以通过中描述的FOR语句在不显式打开游标的情况下使用已绑定的游标变量。 - - portal - 在 PL/pgSQL 中 - - - - 打开游标会创建一个称为 portal 的服务器内部数据结构,它保存游标查询的执行状态。portal 具有一个名称,在其存在期间该名称在会话内必须唯一。默认情况下,PL/pgSQL 会为其创建的每个 portal 分配唯一名称。不过,如果你给游标变量赋一个非空字符串值,该字符串会被用作 portal 名称。这个特性可用于中描述的用法。 - - <command>OPEN FOR</command> <replaceable>query</replaceable> @@ -2422,7 +2370,7 @@ OPEN curs1 FOR EXECUTE format('SELECT * FROM %I WHERE col1 = $1',tabname) USING 打开已绑定游标 -OPEN bound_cursorvar ( argument_name { := | => } argument_value , ... ) ; +OPEN bound_cursorvar ( argument_name := argument_value , ... ) ; @@ -2434,7 +2382,7 @@ OPEN bound_cursorvar ( - 使用位置命名记号可以传递参数值。在位置记号中,所有参数都必须按照顺序指定。在命名记号中,每一个参数的名字使用:==>与参数表达式分隔。类似于中描述的调用函数,也允许混合位置和命名记号。 + 使用位置命名记号可以传递参数值。在位置记号中,所有参数都必须按照顺序指定。在命名记号中,每一个参数的名字使用:=与参数表达式分隔。类似于中描述的调用函数,也允许混合位置和命名记号。 @@ -2443,7 +2391,6 @@ OPEN bound_cursorvar ( @@ -2498,7 +2445,7 @@ FETCH direction { FROM | IN } RELATIVE countFORWARD或者 BACKWARD。 - 省略direction和指定NEXT是一样的。在使用count的形式中,count可以是任意的整数值表达式(与SQL命令FETCH不一样,FETCH仅允许整数常量)。除非游标被使用SCROLL选项声明或打开,否则要求反向移动的direction值很可能会失败。 + 省略direction和指定NEXT是一样的。在使用count的形式中,count可以是任意的整数值表达式(与SQL命令FETCH不一样,后者仅允许整数常量)。除非游标被使用SCROLL选项声明或打开,否则要求反向移动的direction值很可能会失败。 @@ -2678,7 +2625,7 @@ COMMIT; <<label>> -FOR recordvar IN bound_cursorvar ( argument_name { := | => } argument_value , ... ) LOOP +FOR recordvar IN bound_cursorvar ( argument_name := argument_value , ... ) LOOP statements END LOOP label ; @@ -2725,7 +2672,7 @@ CALL transaction_test1(); 连锁的事务 - 在 PL/pgSQL + 在 PL/pgSQL 中 @@ -2737,13 +2684,7 @@ CALL transaction_test1(); 只有在从顶层调用的CALLDO中才能进行事务控制,在没有任何其他中间命令的嵌套CALLDO调用中也能进行事务控制。例如,如果调用栈是CALL proc1()CALL proc2()CALL proc3(),那么第二个和第三个过程可以执行事务控制动作。但是如果调用栈是CALL proc1()SELECT func2()CALL proc3(),则最后一个过程不能做事务控制,因为中间有SELECT - - PL/pgSQL 不支持保存点(SAVEPOINT/ROLLBACK TO SAVEPOINT/RELEASE SAVEPOINT)。保存点的典型用法可以用带异常处理器的代码块替代(见)。在内部,实现为带异常处理器的代码块会形成一个子事务,这意味着在这类代码块内部不能结束事务。 - - - - 对于游标循环,还有一些特殊注意事项。请看下面这个示例: - + 游标循环需要特别考虑。来看这个例子: CREATE PROCEDURE transaction_test2() LANGUAGE plpgsql AS $$ @@ -2758,13 +2699,13 @@ END; $$; CALL transaction_test2(); - - 通常,游标会在事务提交时自动关闭。但是,作为这类循环一部分创建的游标,会在第一次 COMMITROLLBACK 时自动转换为可保持游标。这意味着该游标会在第一次 COMMITROLLBACK 时被完整求值,而不是逐行求值。循环结束后,该游标仍会被自动移除,因此这一点对用户通常不可见。但必须注意,游标查询获取的任何表锁或行锁,在第一次 COMMITROLLBACK 之后都不再保持。 - +通常,游标会在事务提交时自动关闭。但是,在这样的循环中创建的游标,会自动转换为可保持游标,转换发生于第一次COMMITROLLBACK。这意味着,游标将在第一次执行以下命令时被完整求值:COMMITROLLBACK,而不是逐行求值。循环结束后游标仍然会被自动移除,因此这些行为对用户大多是不可见的。 由非只读命令(例如 UPDATE ... RETURNING)驱动的游标循环中,不允许使用事务命令。 + + 不能在带有异常处理器的块中结束事务。 @@ -2785,28 +2726,17 @@ CALL transaction_test2(); 在 PL/pgSQL 中 - - 使用RAISE语句报告消息以及抛出错误。 - - -RAISE level 'format' , expression , ... USING option { = | := } expression , ... ; -RAISE level condition_name USING option { = | := } expression , ... ; -RAISE level SQLSTATE 'sqlstate' USING option { = | := } expression , ... ; -RAISE level USING option { = | := } expression , ... ; + 使用RAISE语句报告消息和抛出错误。 +RAISE level 'format' , expression , ... USING option = expression , ... ; +RAISE level condition_name USING option = expression , ... ; +RAISE level SQLSTATE 'sqlstate' USING option = expression , ... ; +RAISE level USING option = expression , ... ; RAISE ; - +其中,level选项指定错误的严重程度。允许的级别为DEBUG, + LOGINFO, + NOTICEWARNING以及EXCEPTION,其中EXCEPTION是默认值。EXCEPTION会抛出错误(通常会中止当前事务);其他级别只会生成不同优先级的消息。特定优先级的消息是报告给客户端、写入服务器日志,还是两者都做,由配置变量控制。更多信息见中的说明。 - level选项指定了错误的严重性。允许的级别有DEBUGLOGINFONOTICE, WARNING以及EXCEPTION,默认级别是EXCEPTIONEXCEPTION会抛出一个错误(通常会中止当前事务)。其他级别仅仅是产生不同优先级的消息。不管一个特定优先级的消息是被报告给客户端、还是写到服务器日志、亦或是二者同时都做,这都由配置变量控制。详见。 - - - - 在第一种语法变体中,在level之后(如果有),写一个format字符串 - (必须是一个简单的字符串文字,而不是一个表达式)。格式字符串指定要报告的错误消息文本。 - 格式字符串后跟要插入到消息中的可选参数表达式。 - 在格式字符串中,%将被下一个可选参数的值的字符串表示替换。写 - %%以发出一个字面上的%。 - 参数的数量必须与格式字符串中的%占位符的数量匹配,否则在函数编译期间会引发错误。 - + level(如果有)之后,可以指定一个format字符串(必须是简单的字符串字面量,不能是表达式)。格式字符串指定要报告的错误消息文本。格式字符串之后可以跟上可选的参数表达式,其值将被插入消息中。在格式字符串内,%会被替换为下一个可选参数值的字符串表示。写成%%可以输出一个字面的%。参数个数必须与格式字符串中%占位符的个数匹配,否则会在函数编译期间报错。 在这个示例中,v_job_id的值将替换字符串中的%: @@ -2815,36 +2745,21 @@ RAISE NOTICE 'Calling cs_create_job(%)', v_job_id; - - 在第二和第三种语法变体中,condition_name 和 - sqlstate 分别指定错误条件名称或五字符 SQLSTATE 代码。 - 有效的错误条件名称和预定义 SQLSTATE 代码见 。 - - - - 下面是 condition_name 和 - sqlstate 的用法示例: - -RAISE division_by_zero; -RAISE WARNING SQLSTATE '22012'; - - - - - 在任意一种语法变体中,都可以通过写一个后面跟着option = expression项的USING,为错误报告附加额外信息。每一个expression可以是任意字符串值的表达式。允许的option关键词是: - - + 可以为错误报告附加额外信息,方法是写出USING,后面跟上option = expression项目。每个expression都可以是任意字符串值表达式。允许的option关键字为: MESSAGE - 设置错误消息文本。该选项不能用于第一种语法变体,因为消息文本已经给出。 + 设置错误消息文本。该选项不能用于在USING之前包含格式字符串的RAISE形式。 DETAIL - 提供一个错误的细节消息。 + 提供错误的详细信息。 @@ -2858,7 +2773,7 @@ RAISE WARNING SQLSTATE '22012'; ERRCODE - 指定要报告的错误代码(SQLSTATE),可以用中所示的条件名,或者直接作为一个五字符 SQLSTATE 代码。该选项不能用于第二和第三种语法变体,因为错误代码已经给出。 + 指定要报告的错误代码(SQLSTATE),可以用中所示的条件名,或者直接作为一个五字符 SQLSTATE 代码。 @@ -2875,9 +2790,7 @@ RAISE WARNING SQLSTATE '22012'; - - 这个示例将用给定的错误消息和提示中止事务: - + 这个例子会中止事务,并给出指定的错误消息和提示: RAISE EXCEPTION 'Nonexistent ID --> %', user_id USING HINT = 'Please check your user ID'; @@ -2892,14 +2805,19 @@ RAISE 'Duplicate user ID: %', user_id USING ERRCODE = '23505'; - 另一种得到前面示例相同结果的方式是: + 还有第二种RAISE语法,其中主参数是要报告的条件名或 SQLSTATE,例如: + +RAISE division_by_zero; +RAISE SQLSTATE '22012'; + + 在这种语法中,USING可以用来提供自定义的错误消息、细节或提示。另一种达到前面示例同样效果的方式是: RAISE unique_violation USING MESSAGE = 'Duplicate user ID: ' || user_id; - 如第四种语法变体所示,也可以写成RAISE USINGRAISE level USING,并把其余内容都放在USING列表里。 + 还有另一种变体是写RAISE USINGRAISE level USING,并把其余内容都放在USING列表里。 @@ -2922,7 +2840,7 @@ RAISE unique_violation USING MESSAGE = 'Duplicate user ID: ' || user_id; - 当用 SQLSTATE 代码指定错误代码时,你并不受限于预定义错误代码,而是可以选择任何由五位数字和/或大写 ASCII 字母构成的错误代码,唯一不能使用的是 00000。我们建议尽量避免抛出以三个零结尾的错误代码,因为这些是类别代码,只能用于捕获整个类别。 + 当用 SQLSTATE 代码指定错误代码时,你并不受限于预定义错误代码,而是可以选择任何由五位数字和/或大写 ASCII 字母构成的错误代码,唯一不能使用的是 00000。我们建议尽量避免抛出以三个零结尾的错误代码,因为这些是类别代码,只能通过捕获整个类别来捕获这类错误。 @@ -2934,12 +2852,12 @@ RAISE unique_violation USING MESSAGE = 'Duplicate user ID: ' || user_id; ASSERT - in PL/pgSQL + 在 PL/pgSQL 中 - assertions - in PL/pgSQL + 断言 + 在 PL/pgSQL 中 @@ -2956,15 +2874,14 @@ ASSERT condition , condition是一个布尔 表达式,它被期望总是计算为真。如果确实如此, - ASSERT语句不会再做什么。但如果结果是假 - 或者空,那么将发生一个ASSERT_FAILURE异常(如果在计算 + ASSERT语句不会再做什么。但如果结果是假或者空值,那么将发生一个ASSERT_FAILURE异常(如果在计算 condition时发生错误, 它会被报告为一个普通错误)。 如果提供了可选的message, - 它是一个结果(如果非空)被用来替换默认错误消息文本 + 它是一个结果(如果不为 NULL)被用来替换默认错误消息文本 assertion failed的表达式(如果 condition失败)。 message表达式在 @@ -2997,7 +2914,7 @@ ASSERT condition , - PL/pgSQL可以被用来在数据更改或者数据库事件上定义触发器函数。触发器函数用CREATE FUNCTION命令创建,它被声明为一个没有参数并且返回类型为trigger(对于数据更改触发器)或者event_trigger(对于数据库事件触发器)的函数。名为PG_something的特殊局部变量将被自动创建用以描述触发该调用的条件。 + PL/pgSQL可以被用来在数据更改或者数据库事件上定义触发器函数。触发器函数用CREATE FUNCTION命令创建,它被声明为一个没有参数并且返回类型为trigger(对于数据更改触发器)或者event_trigger(对于数据库事件触发器)的函数。名为TG_something的特殊局部变量将被自动创建用以描述触发该调用的条件。 @@ -3008,115 +2925,104 @@ ASSERT condition , 数据更改触发器被声明为一个没有参数并且返回类型为trigger的函数。注意,如下所述,即便该函数准备接收一些在CREATE TRIGGER中指定的参数 — 这类参数通过TG_ARGV传递,也必须把它声明为没有参数。 - - 当一个PL/pgSQL函数当做触发器调用时,在顶层块会自动创建一些特殊变量。它们是: - - + 当一个PL/pgSQL函数作为触发器被调用时,会在顶层块中自动创建一些特殊变量。它们是: - NEW record + NEW - - 行级触发器中用于 INSERT/UPDATE 操作的新数据行。在语句级触发器和 DELETE 操作中,该变量为 null。 - + 数据类型为RECORD;该变量保存行级触发器中用于INSERT/UPDATE操作的新数据行。在语句级触发器和DELETE操作中,该变量为 null。 - OLD record + OLD - - 行级触发器中用于 UPDATE/DELETE 操作的旧数据行。在语句级触发器和 INSERT 操作中,该变量为 null。 - + 数据类型为RECORD;该变量保存行级触发器中用于UPDATE/DELETE操作的旧数据行。在语句级触发器和INSERT操作中,该变量为 null。 - TG_NAME name + TG_NAME - 被触发的触发器名称。 + 数据类型为 name;包含实际触发的触发器名称的变量。 - TG_WHEN text + TG_WHEN - 根据触发器定义,其值为 BEFOREAFTERINSTEAD OF。 + 数据类型为 text;根据触发器定义,其值为字符串 BEFOREAFTERINSTEAD OF - TG_LEVEL text + TG_LEVEL - 根据触发器定义,其值为 ROWSTATEMENT。 + 数据类型为 text;根据触发器定义,其值为字符串 ROWSTATEMENT - TG_OP text + TG_OP - 触发器对应的操作:INSERTUPDATEDELETETRUNCATE。 + 数据类型为 text;表示触发器对应操作的字符串:INSERTUPDATEDELETETRUNCATE - TG_RELID oid(引用 pg_class.oid + TG_RELID - - 导致触发器调用的表的对象 ID。 - + 数据类型为oid;导致触发器调用的表的对象 ID。 - TG_RELNAME name + TG_RELNAME - 导致触发器调用的表名。该变量已弃用,未来版本可能移除;请改用 TG_TABLE_NAME。 + 数据类型为 name;导致触发器调用的表名。该变量已弃用,未来版本可能移除;请改用 TG_TABLE_NAME - TG_TABLE_NAME name + TG_TABLE_NAME - 导致触发器调用的表名。 + 数据类型为 name;导致触发器调用的表名。 - TG_TABLE_SCHEMA name + TG_TABLE_SCHEMA - 导致触发器调用的表所在模式名。 + 数据类型为 name;导致触发器调用的表所在模式名。 - TG_NARGS integer + TG_NARGS - CREATE TRIGGER 语句中传给触发器函数的参数个数。 + 数据类型为 integerCREATE TRIGGER 语句中传给触发器函数的参数个数。 - TG_ARGV text[] + TG_ARGV[] - - 来自 CREATE TRIGGER 语句的参数。索引从 0 开始;非法索引(小于 0 或大于等于 tg_nargs)返回 null。 - + 数据类型为text数组;来自CREATE TRIGGER语句的参数。索引从 0 开始;非法索引(小于 0 或大于等于tg_nargs)返回 null。 @@ -3131,11 +3037,11 @@ ASSERT condition , - INSTEAD OF触发器(总是行级触发器,并且可能只被用于视图)能够返回空来表示它们没有执行任何更新,并且对该行剩余的操作可以被跳过(即后续的触发器不会被引发,并且该行不会被计入外围INSERT/UPDATE/DELETE的行影响状态中)。否则一个非空值应该被返回用以表示该触发器执行了所请求的操作。对于INSERTUPDATE操作,返回值应该是NEW,触发器函数可能对它进行了修改来支持INSERT RETURNINGUPDATE RETURNING(这也将影响被传递给任何后续触发器的行值,或者被传递给带有ON CONFLICT DO UPDATEINSERT语句中一个特殊的EXCLUDED别名引用)。对于DELETE操作,返回值应该是OLD。 + INSTEAD OF触发器(总是行级触发器,并且只能用于视图)能够返回 null 来表示它们没有执行任何更新,并且对该行剩余的操作应被跳过(即后续的触发器不会被引发,并且该行不会被计入外围INSERT/UPDATE/DELETE的行影响状态中)。否则应该返回一个非 null 值用以表示该触发器执行了所请求的操作。对于INSERTUPDATE操作,返回值应该是NEW,触发器函数可能对它进行了修改来支持INSERT RETURNINGUPDATE RETURNING(这也将影响被传递给任何后续触发器的行值,或者被传递给带有ON CONFLICT DO UPDATEINSERT语句中一个特殊的EXCLUDED别名引用)。对于DELETE操作,返回值应该是OLD - 一个AFTER行级触发器或一个BEFOREAFTER语句级触发器的返回值总是会被忽略,它可能也是空。不过,任何这些类型的触发器可能仍会通过抛出一个错误来中止整个操作。 + 一个AFTER行级触发器或一个BEFOREAFTER语句级触发器的返回值总是会被忽略,因此也可以返回 null。不过,任何这些类型的触发器可能仍会通过抛出一个错误来中止整个操作。 @@ -3309,11 +3215,10 @@ INSTEAD OF INSERT OR UPDATE OR DELETE ON emp_view - - 一个 <application>PL/pgSQL</application> 用于维护汇总表的触发器函数 + 一个用于维护汇总表的 <application>PL/pgSQL</application> 触发器函数 - 这里详述的模式有一部分是基于 Ralph Kimball 所作的数据仓工具包中的Grocery Store示例。 + 这里详述的模式有一部分是基于 Ralph Kimball 所作的数据仓库工具包中的Grocery Store示例。 @@ -3456,7 +3361,7 @@ SELECT * FROM sales_summary_bytime; 使用过渡表审计 - 这个示例产生和相同的结果,但并未使用一个为每一行都触发的触发器,而是在把相关信息收集到一个过渡表中之后用了一个只为每个语句引发一次的触发器。当调用语句修改了很多行时,这种方法明显比行触发器方法快。注意我们必须为每一种事件建立一个单独的触发器声明,因为每种情况的REFERENCING子句必须不同。但是这并不能阻止我们使用单一的触发器函数(实际上,使用三个单独的函数会更好,因为可以避免在TG_OP上的运行时测试)。 + 这个示例产生和相同的结果,但并未使用一个为每一行都触发的触发器,而是在把相关信息收集到一个过渡表中之后用了一个只为每个语句引发一次的触发器。当调用语句修改了很多行时,这种方法可能显著快于行触发器方法。注意我们必须为每一种事件建立一个单独的触发器声明,因为每种情况的REFERENCING子句必须不同。但是这并不能阻止我们使用单一的触发器函数(实际上,使用三个单独的函数可能会更好,因为可以避免在TG_OP上的运行时测试)。 @@ -3518,24 +3423,21 @@ CREATE TRIGGER emp_audit_del PL/pgSQL可以被用来定义事件触发器。PostgreSQL要求一个可以作为事件触发器调用的函数必须被声明为没有参数并且返回类型为event_trigger - - 当一个PL/pgSQL函数被作为一个事件触发器调用,在顶层块中会自动创建一些特殊变量。它们是: - - + 当一个PL/pgSQL函数作为事件触发器被调用时,会在顶层块中自动创建一些特殊变量。它们是: - TG_EVENT text + TG_EVENT - 触发器被触发时对应的事件。 + 数据类型为 text;表示触发器被触发时对应事件的字符串。 - TG_TAG text + TG_TAG - 触发该触发器的命令标签。 + 数据类型为 text;包含触发该触发器的命令标签的变量。 @@ -3572,9 +3474,7 @@ CREATE EVENT TRIGGER snitch ON ddl_command_start EXECUTE FUNCTION snitch(); <application>PL/pgSQL</application> 内部机制 - - 这一节讨论了一些PL/pgSQL用户应该知道的一些重要的实现细节。 - + 本节讨论一些实现细节,了解这些细节对 PL/pgSQL 用户通常很重要。 @@ -3652,7 +3552,7 @@ CREATE FUNCTION stamp_user(id int, comment text) RETURNS void AS $$ END; $$ LANGUAGE plpgsql; - 在UPDATE命令中,curtimecomment以及id将引用该函数的变量和参数,不管users有没有这些名称的列。注意,我们不得不在WHERE子句中对users.id的引用加以限定,以便让它引用表列。但是我们不需要在UPDATE列表中把对comment的引用限定为一个目标,因为语法上那必须是users的一列。我们可以用下面的方式写一个相同的不依赖于variable_conflict设置的函数: + 在UPDATE命令中,curtimecomment以及id将引用该函数的变量和参数,不管users有没有这些名称的列。注意,我们不得不在WHERE子句中对users.id的引用加以限定,以便让它引用表列。但是我们不需要对UPDATE列表中作为目标的comment引用加以限定,因为语法上那必须是users的一列。我们可以用下面的方式写一个相同的不依赖于variable_conflict设置的函数: CREATE FUNCTION stamp_user(id int, comment text) RETURNS void AS $$ <<fn>> @@ -3671,7 +3571,7 @@ $$ LANGUAGE plpgsql; - 目前,变量替换只在 SELECTINSERTUPDATEDELETE 以及包含其中之一的命令中生效(例如 EXPLAINCREATE TABLE ... AS SELECT),因为主 SQL 引擎只允许在这些命令中使用查询参数。若要在其他语句类型(统称为实用语句)中使用非常量名称或值,就必须把该实用语句构造为字符串,再用 EXECUTE 执行。 + 目前,变量替换只在 SELECTINSERTUPDATEDELETE 以及包含其中之一的命令中生效(例如 EXPLAINCREATE TABLE ... AS SELECT),因为主 SQL 引擎只允许在这些命令中使用查询参数。若要在其他语句类型(统称为工具语句)中使用非常量名称或值,就必须把该工具语句构造为字符串,再用 EXECUTE 执行。 @@ -3693,7 +3593,7 @@ $$ LANGUAGE plpgsql; - PL/pgSQL(更准确地说,是 SPI 管理器)还会尝试缓存与某个预备语句相关的执行计划。如果没有使用缓存计划,那么每次执行该语句时都会生成新的执行计划,而当前参数值(也就是 PL/pgSQL 变量值)可用于优化所选计划。如果该语句没有参数,或者会被执行很多次,SPI 管理器就会考虑创建一个不依赖具体参数值的通用计划,并将其缓存起来供重复使用。通常只有在执行计划对其中引用的 PL/pgSQL 变量值不太敏感时,才会这样做。如果执行计划对参数值非常敏感,那么每次重新生成计划总体上反而更划算。关于预备语句的行为,详见 。 + PL/pgSQL(更准确地说,是 SPI 管理器)还可以尝试缓存与某个预备语句相关的执行计划。如果没有使用缓存计划,那么每次执行该语句时都会生成新的执行计划,而当前参数值(也就是 PL/pgSQL 变量值)可用于优化所选计划。如果该语句没有参数,或者会被执行很多次,SPI 管理器就会考虑创建一个不依赖具体参数值的通用计划,并将其缓存起来供重复使用。通常只有在执行计划对其中引用的 PL/pgSQL 变量值不太敏感时,才会这样做。如果执行计划对参数值非常敏感,那么每次重新生成计划总体上反而更划算。关于预备语句的行为,详见 @@ -3742,7 +3642,7 @@ $$ LANGUAGE plpgsql; - 在logfunc2中,PostgreSQL的主解析器不知道应该把'now'解释成什么类型,因此返回一个text类型的数据值,其中包含字符串now。在确定对本地变量curtime的赋值时,PL/pgSQL解释器通过调用用于该转换的textouttimestamp_in函数,把这个字符串转换为timestamp类型。因此,计算得到的时间戳会按程序员预期在每次执行时更新。虽然这恰好能得到预期结果,但效率并不高,因此使用now()函数仍然是更好的主意。 + 在logfunc2中,PostgreSQL的主解析器不知道应该把'now'解释成什么类型,因此返回一个text类型的数据值,其中包含字符串now。在随后给局部变量curtime赋值时,PL/pgSQL解释器通过调用用于该转换的textouttimestamp_in函数,把这个字符串转换为timestamp类型。因此,计算得到的时间戳会按程序员预期在每次执行时更新。虽然这恰好能得到预期结果,但效率并不高,因此使用now()函数仍然是更好的主意。 @@ -3771,7 +3671,7 @@ $$ LANGUAGE plpgsql; - 另一种开发PL/pgSQL的好方法,是使用有助于过程语言开发的 GUI 数据库访问工具。这类工具的一个例子是pgAdmin,当然也有其他工具。它们通常提供一些方便的特性,例如转义单引号,以及让重新创建和调试函数变得更容易。 + 另一种使用PL/pgSQL进行开发的好方法,是使用有助于过程语言开发的 GUI 数据库访问工具。这类工具的一个例子是pgAdmin,当然也有其他工具。它们通常提供一些方便的特性,例如转义单引号,以及让重新创建和调试函数变得更容易。 @@ -3779,7 +3679,7 @@ $$ LANGUAGE plpgsql; 引号的处理 - 一个PL/pgSQL函数的代码在一个CREATE FUNCTION中被指定为一个字符串。如果你用通常的方式把该字符串写在单引号中间,那么该函数体中的任何单引号都必须被双写;同样任何反斜线也必须被双写(假定使用了转义字符串语法)。双写引号最多有点冗长,并且在更复杂的情况中代码会变得完全无法理解,因为你很容易发现你需要半打或者更多相邻的引号。我们推荐你转而把函数体写成一个美元引用的字符串(见)。在美元引用方法中,你从不需要双写任何引号。但是要注意为你需要的每一层嵌套选择一个不同的美元引用定界符。例如,你可能把CREATE FUNCTION命令写成: + 一个PL/pgSQL函数的代码在一个CREATE FUNCTION中被指定为一个字符串字面量。如果你用通常的方式把该字符串写在单引号中间,那么该函数体中的任何单引号都必须被双写;同样任何反斜线也必须被双写(假定使用了转义字符串语法)。双写引号本身就很繁琐,并且在更复杂的情况中代码会变得完全无法理解,因为你很容易发现你需要半打或者更多相邻的引号。我们推荐你转而把函数体写成一个美元引用的字符串(见)。在美元引用方法中,你从不需要双写任何引号。但是要注意为你需要的每一层嵌套选择一个不同的美元引用定界符。例如,你可能把CREATE FUNCTION命令写成: CREATE OR REPLACE FUNCTION testfunc(integer) RETURNS integer AS $PROC$ .... @@ -3816,7 +3716,7 @@ CREATE FUNCTION foo() RETURNS integer AS ' - 用于函数体内的字符串,例如: + 用于函数体内的字符串字面量,例如: a_output := ''Blah''; SELECT * FROM users WHERE f_name=''foobar''; @@ -3826,7 +3726,7 @@ SELECT * FROM users WHERE f_name=''foobar''; a_output := 'Blah'; SELECT * FROM users WHERE f_name='foobar'; - 这恰好就是PL/pgSQL在两种情况中会看到的。 + 这恰好就是PL/pgSQL解析器在两种情况中会看到的。 @@ -3849,7 +3749,7 @@ a_output := a_output || '' AND name LIKE ''''foobar'''' AND xyz'' a_output := a_output || $$ AND name LIKE 'foobar' AND xyz$$ - 要小心在这周围的任何美元引用定界符不只是$$。 + 要小心在这周围的任何美元引用定界符都不能是$$ @@ -3882,7 +3782,7 @@ a_output := a_output || $$ AND name LIKE 'foobar'$$ - 当你想在一个字符串常量(占 8 个引号)中有两个单引号时并且这会挨着该字符串常量的末尾(另外 2 个)。如果你正在写一个产生其他函数的函数(如中),你将很可能只需要这种。例如: + 当字符串常量中需要两个单引号(这需要 8 个引号),而且它们紧邻该字符串常量的末尾(还需 2 个引号)时。通常只有在编写生成其他函数的函数时(如所示),才会需要这种写法。例如: a_output := a_output || '' if v_'' || referrer_keys.kind || '' like '''''''''' @@ -3924,9 +3824,7 @@ a_output := a_output || $$ if v_$$ || referrer_keys.kind || $$ like '$$ 因此建议你在一个单独的开发环境中进行测试。 - - 根据需要设置 plpgsql.extra_warningsplpgsql.extra_errors,适当情况下,在开发和/或测试环境中可以设置为 "all"。 - + 建议在开发和/或测试环境中,根据需要将 plpgsql.extra_warningsplpgsql.extra_errors 设置为 "all" 这些额外的检查通过配置变量plpgsql.extra_warnings来启用警告, @@ -3946,10 +3844,10 @@ a_output := a_output || $$ if v_$$ || referrer_keys.kind || $$ like '$$ strict_multi_assignment - 一些PL/pgSQL命令允许一次为多个变量赋值, + 一些PL/PgSQL命令允许一次为多个变量赋值, 例如SELECT INTO。通常,目标变量的数量和源变量的数量应该匹配, - 尽管PL/pgSQL会对缺失的值使用NULL, - 并且额外的变量会被忽略。启用此检查将导致PL/pgSQL + 尽管PL/PgSQL会对缺失的值使用NULL, + 并且额外的变量会被忽略。启用此检查将导致PL/PgSQL 在目标变量的数量和源变量的数量不同时抛出WARNINGERROR @@ -3959,7 +3857,7 @@ a_output := a_output || $$ if v_$$ || referrer_keys.kind || $$ like '$$ too_many_rows - 启用此检查将导致PL/pgSQL检查给定查询在使用INTO子句时是否返回多行。 + 启用此检查将导致PL/PgSQL检查给定查询在使用INTO子句时是否返回多行。 由于INTO语句只会使用一行,当查询返回多行时通常是低效和/或不确定性的,因此很可能是错误的。 @@ -4040,18 +3938,16 @@ HINT: Make sure the query returns the exact list of columns. - PL/pgSQL与 PL/SQL 在许多方面都非常类似。它是一种块结构的、命令式的语言并且所有变量必须先被声明。赋值、循环和条件则很类似。在从PL/SQLPL/pgSQL移植时必须记住一些事情: - - + PL/pgSQL在许多方面都与 PL/SQL 类似。它是一种具有块结构的命令式语言,所有变量都必须声明。赋值、循环和条件语句也都很相似。在从PL/SQL移植到PL/pgSQL时,应当记住以下主要差异: - 如果一个 SQL 命令中使用的名字可能是一个表的列名或者是对一个函数中变量的引用,那么PL/SQL会将它当作一个列名。默认情况下, PL/pgSQL会抛出名称模糊的错误, 你可以指定plpgsql.variable_conflict=use_column来改变这一行为以匹配PL/SQL。如中所述。通常最好是首先避免这种歧义,但如果不得不移植依赖于该行为的大量代码,那么设置variable_conflict将是最好的方案。 + 如果一个 SQL 命令中使用的名字可能是一个表的列名或者是对一个函数中变量的引用,那么PL/SQL会将它当作一个列名。默认情况下, PL/pgSQL会抛出名称有歧义的错误, 你可以指定plpgsql.variable_conflict=use_column来改变这一行为以匹配PL/SQL。如中所述。通常最好是首先避免这种歧义,但如果不得不移植依赖于该行为的大量代码,那么设置variable_conflict可能是最好的方案。 - 在PostgreSQL中,函数体必须写成字符串文本。因此你需要使用美元符引用或者转义函数体中的单引号(见)。 + 在PostgreSQL中,函数体必须写成字符串字面量。因此你需要使用美元符引用或者转义函数体中的单引号(见)。 @@ -4141,13 +4037,13 @@ show errors; - 在PostgreSQL中,函数体被认为是一个字符串,所以你需要使用引号或者美元符号包围它。这代替了Oracle 方法中的用于终止的/。 + 在PostgreSQL中,函数体被认为是一个字符串字面量,所以你需要使用引号或者美元引用定界符包围它。这代替了Oracle 方法中的用于终止的/ - 在PostgreSQL中没有show errors命令, 并且也不需要这个命令,因为错误是自动报告的。 + 在PostgreSQL中没有show errors命令, 并且也不需要这个命令,因为错误是自动报告的。 @@ -4179,9 +4075,7 @@ $$ LANGUAGE plpgsql; 从<application>PL/SQL</application>移植一个创建另一个函数的函数到<application>PL/pgSQL</application> - - 下面的过程从一个SELECT语句抓取行,并且为了效率而构建一个带有IF语句中结果的大型函数。 - + 下面的过程从 SELECT 语句读取行,并将结果写入 IF 语句,从而构造一个大型函数,以提高效率。 这是 Oracle 版本: @@ -4212,8 +4106,7 @@ show errors; - - 这里是PostgreSQL的版本: + 下面是这个函数的最终移植结果,目标数据库为PostgreSQL CREATE OR REPLACE PROCEDURE cs_update_referrer_type_proc() AS $func$ DECLARE @@ -4246,9 +4139,7 @@ BEGIN EXECUTE func_cmd; END; $func$ LANGUAGE plpgsql; - - 请注意,这里先单独构造了函数体,再通过 quote_literal 传入,以便把其中的引号正确双写。之所以需要这种技术,是因为我们无法安全地使用美元引用来定义新函数:我们并不确切知道会从 referrer_key.key_string 字段插入什么字符串。(这里假定 referrer_key.kind 始终可信地只会是 hostdomainurl,但 referrer_key.key_string 可能是任意内容,尤其可能包含美元符号。)实际上,这个函数比 Oracle 原版还有改进,因为当 referrer_key.key_stringreferrer_key.referrer_type 中包含引号时,它也不会生成无效代码。 - +注意,这里单独构造函数体,然后将其传给quote_literal,使其中的每个引号都变成两个。这种技术是必需的,因为不能安全地使用美元引用来定义新函数:我们无法确定会插入什么字符串,其来源是referrer_key.key_string字段。(这里假定referrer_key.kind可信,其值总是hostdomainurl,但是referrer_key.key_string可能是任何内容,尤其可能包含美元符号。)这个函数实际上改进了 Oracle 原版:当referrer_key.key_stringreferrer_key.referrer_type中包含引号时,它也不会生成有问题的代码。 @@ -4268,7 +4159,7 @@ $func$ LANGUAGE plpgsql; CREATE OR REPLACE PROCEDURE cs_parse_url( v_url IN VARCHAR2, - v_host OUT VARCHAR2, -- 这将被传回去 + v_host OUT VARCHAR2, -- 这个值将被返回 v_path OUT VARCHAR2, -- 这个也是 v_query OUT VARCHAR2) -- 还有这个 IS @@ -4311,9 +4202,9 @@ show errors; CREATE OR REPLACE FUNCTION cs_parse_url( v_url IN VARCHAR, - v_host OUT VARCHAR, -- 这将被传递回去 + v_host OUT VARCHAR, -- 这个值将被返回 v_path OUT VARCHAR, -- 这个也是 - v_query OUT VARCHAR) -- 以及这个 + v_query OUT VARCHAR) -- 还有这个 AS $$ DECLARE a_pos1 INTEGER; @@ -4356,7 +4247,7 @@ SELECT * FROM cs_parse_url('http://foobar.com/query.cgi?baz'); - 展示了如何移植一个使用了多种 Oracle 特性的过程。 + 展示了如何移植一个使用了多种 Oracle 专属特性的过程。 @@ -4396,7 +4287,7 @@ show errors - 这是我们如何将这个过程移植到PL/pgSQL: + 下面展示了如何将这个过程移植到PL/pgSQL CREATE OR REPLACE PROCEDURE cs_create_job(v_job_id integer) AS $$ @@ -4471,7 +4362,7 @@ EXCEPTION END; - 如果你正在移植一个以这种方式使用SAVEPOINTROLLBACK TO的 Oracle 过程,工作会比较简单:只要忽略SAVEPOINTROLLBACK TO即可。如果你的 Oracle 过程以不同方式使用SAVEPOINTROLLBACK TO,那就需要认真思考了。 + 如果你正在移植一个以这种方式使用SAVEPOINTROLLBACK TO的 Oracle 过程,工作会比较简单:只要省略SAVEPOINTROLLBACK TO即可。如果你的 Oracle 过程以不同方式使用SAVEPOINTROLLBACK TO,那就需要认真思考了。 @@ -4488,11 +4379,11 @@ END; 优化 <application>PL/pgSQL</application> 函数 - PostgreSQL提供了两种函数创建修饰符来优化执行:volatility(对于给定的相同参数,函数是否总是返回相同的结果)以及strictness (如果任何参数为空,函数是否返回空)。详见参考页。 + PostgreSQL提供了两种函数创建修饰符来优化执行:volatility(对于给定的相同参数,函数是否总是返回相同的结果)以及strictness (如果任何参数为空值,函数是否返回空值)。详见参考页。 - 在利用这些优化属性时,你的CREATE FUNCTION语句应该看起来像这样: + 在利用这些优化属性时,你的CREATE FUNCTION语句可能像这样: CREATE FUNCTION foo(...) RETURNS integer AS $$ diff --git a/zh/14/plpython.sgml b/zh/14/plpython.sgml index 348d1035..e8eefc51 100644 --- a/zh/14/plpython.sgml +++ b/zh/14/plpython.sgml @@ -73,14 +73,9 @@ - - 由此产生了以下使用和迁移策略: - - + 由此可以采用以下使用和迁移策略: - - 现有用户以及目前对 Python 3 不感兴趣的用户可以使用语言名称plpythonu,在可预见的将来不需要做任何改变。建议通过逐步迁移到 Python 2.6/2.7 来面向未来地准备代码,以简化最终向 Python 3 的迁移。 - + 现有用户和目前不打算使用 Python 3 的用户,可以使用语言名 plpythonu,在可预见的将来无需更改任何内容。建议通过迁移到 Python 2.6/2.7,逐步让代码适应未来,以简化最终迁移到 Python 3 的工作。 实际上,许多 PL/Python 函数只需很少或不做改动即可迁移到 Python 3。 @@ -88,24 +83,22 @@ - - 已知自己拥有大量依赖 Python 2 的代码,且不打算修改的用户,可以使用plpython2u语言名称,以在默认值变为 Python 3 后仍然可用。 - + 如果用户清楚自己的代码严重依赖 Python 2,且不打算更改,可以使用语言名 plpython2u。它在很久以后仍会继续工作,直到 PostgreSQL 可能完全停止支持 Python 2。 - - 希望直接开始使用 Python 3 的用户可以使用plpython3u语言名称,它从今天起就一直可用。在遥远的将来,当默认值改为 Python 3 时,为了对正向兼容性做出让步,除了plpython3u之外可能还会继续接受plpythonu。 - + 希望开始使用 Python 3 的用户可以使用语言名 plpython3u,按照目前的标准,它会一直可用。在遥远的未来,当 Python 3 可能成为默认版本时,用户也许会出于美观而去掉名称中的3 - - 希望代码能在 Python 2 和 Python 3 上都运行的用户可以使用plpythonu语言名称,以在切换到最终新默认值时能够受益,但他们需要自己负责使代码与两个 Python 大版本兼容。 - + 希望构建仅包含 Python 3 的操作系统环境的大胆用户,可以修改 plpythonu 的扩展控制文件和脚本文件,使 plpythonu 等同于 plpython3u,但要记住,这会使该安装环境与绝大多数其他环境不兼容。 + + 有关迁移到 Python 3 的更多信息,也可参见文档 Python 3.0 的新变化 + + 不允许在同一个会话中同时使用基于 Python 2 和基于 Python 3 的 PL/Python,因为动态模块中的符号会冲突,可能导致 PostgreSQL 服务器进程崩溃。系统会检查同一会话是否混用了不同的 Python 大版本,如果发现不匹配,就会中止会话。不过,可以在同一数据库的不同会话中分别使用这两种 PL/Python。 @@ -119,7 +112,7 @@ CREATE FUNCTION funcname (argument-list) RETURNS return-type AS $$ - # PL/Python function body + # PL/Python 函数体 $$ LANGUAGE plpythonu; @@ -159,7 +152,7 @@ def __plpython_procedure_pymax_23456(): CREATE FUNCTION pystrip(x text) RETURNS text AS $$ - x = x.strip() # error + x = x.strip() # 错误 return x $$ LANGUAGE plpythonu; @@ -169,7 +162,7 @@ CREATE FUNCTION pystrip(x text) RETURNS text AS $$ global x - x = x.strip() # ok now + x = x.strip() # 现在可以正常工作 return x $$ LANGUAGE plpythonu; @@ -200,10 +193,7 @@ $$ LANGUAGE plpythonu; - - PostgreSQL smallintintbigint - 和 oid 会转换为 Python int。 - + PostgreSQL 的 smallintint 转换为 Python 的 int。PostgreSQL 的 bigintoid 在 Python 2 中转换为 long,在 Python 3 中转换为 int @@ -227,15 +217,14 @@ $$ LANGUAGE plpythonu; - - PostgreSQL bytea 会转换为 Python bytes。 - + PostgreSQL 的 bytea 在 Python 2 中转换为 str,在 Python 3 中转换为 bytes。在 Python 2 中,应将该字符串视为不带任何字符编码的字节序列。 - 所有其他数据类型,包括 PostgreSQL 字符串类型, - 都会转换为 Python str(和所有 Python 字符串一样,都是 Unicode)。 + 所有其他数据类型,包括 PostgreSQL 字符串类型,都会转换为 Python + str。在 Python 2 中,该字符串采用 PostgreSQL 服务器编码; + 在 Python 3 中,它与所有字符串一样,都是 Unicode 字符串。 @@ -258,9 +247,7 @@ $$ LANGUAGE plpythonu; - - 当 PostgreSQL 返回类型为bytea时,返回值会通过相应的 Python 内置函数转换成 Python bytes,再将结果转换成bytea。 - + 如果 PostgreSQL 返回类型是 bytea,会先使用相应的 Python 内置函数,将返回值转换为字符串(Python 2)或 bytes(Python 3),再将结果转换为 bytea @@ -269,7 +256,10 @@ $$ LANGUAGE plpythonu; - 字符串在传给 PostgreSQL 时,会自动转换为 PostgreSQL 服务器编码。 + Python 2 中的字符串传给 PostgreSQL 时,必须采用 PostgreSQL 服务器编码。 + 在当前服务器编码中无效的字符串会引发错误,但并非所有编码不匹配都能被检测到, + 因此处理不当仍可能产生乱码数据。Unicode 字符串会自动转换为正确的编码, + 因而使用它们可能更安全、更方便。在 Python 3 中,所有字符串都是 Unicode 字符串。 @@ -290,7 +280,7 @@ $$ LANGUAGE plpythonu; 如果把 SQL 空值空值在 PL/Python 中传给函数,参数值在 Python 中会显示为None。例如,中展示的pymax定义在处理空输入时就会返回错误结果。我们可以在函数定义中添加STRICT,让PostgreSQL做出更合理的处理:如果传入空值,函数根本不会被调用,而是自动返回空结果。另一种办法是在函数体中检查空输入: + sortas="PL/Python">在 PL/Python 中传给函数,参数值在 Python 中会显示为None。例如,中展示的pymax定义在处理空值输入时就会返回错误结果。我们可以在函数定义中添加STRICT,让PostgreSQL做出更合理的处理:如果传入空值,函数根本不会被调用,而是自动返回空值结果。另一种办法是在函数体中检查空值输入: CREATE FUNCTION pymax (a integer, b integer) @@ -403,26 +393,20 @@ CREATE TYPE named_value AS ( ); - 组合结果可以按以下形式返回: + 复合结果可以按以下形式返回: 序列类型(元组或列表,但不能是集合,因为集合不可通过索引访问) - - 返回的序列对象必须包含与组合结果类型字段数相同的项。索引为 0 的项会赋给复合类型的第一个字段,索引为 1 的项赋给第二个字段,依此类推。例如: - - + 返回的序列对象,其项目数必须与复合结果类型的字段数相同。索引 0 的项目赋给复合类型的第一个字段,索引 1 的项目赋给第二个字段,依此类推。例如: CREATE FUNCTION make_pair (name text, value integer) RETURNS named_value AS $$ return ( name, value ) - # or alternatively, as list: return [ name, value ] + # 也可以使用列表: return [ name, value ] $$ LANGUAGE plpythonu; - - - 要为任意列返回 SQL 空值,请在相应位置插入None。 - +要为某一列返回 SQL 空值,请将 None 放在对应位置。 当返回复合类型数组时,不能将其表示为列表,因为这样无法区分 Python 列表表示的是复合类型还是另一个数组维度。 @@ -432,20 +416,13 @@ $$ LANGUAGE plpythonu; 映射(字典) - - 每个结果类型列的值都从该映射中取出,列名作为键。例如: - - + 结果类型中每一列的值,都使用列名作为键从映射中取得。例如: CREATE FUNCTION make_pair (name text, value integer) RETURNS named_value AS $$ return { "name": name, "value": value } $$ LANGUAGE plpythonu; - - - 额外的字典键/值对会被忽略。缺失的键会被视为错误。 - 要为任意列返回 SQL 空值,请使用相应列名作为键插入None。 - +字典中多余的键值对会被忽略,缺少键则会被视为错误。要为某一列返回 SQL 空值,请插入 None,并以对应列名为键。 @@ -465,7 +442,7 @@ AS $$ self.value = v return named_value(name, value) - # or simply + # 或者简写为 class nv: pass nv.name = name nv.value = value @@ -526,8 +503,8 @@ CREATE TYPE greeting AS ( CREATE FUNCTION greet (how text) RETURNS SETOF greeting AS $$ - # return tuple containing lists as composite types - # all other combinations work also + # 返回包含列表的元组,以列表表示复合类型 + # 其他组合方式也都可用 return ( [ how, "World" ], [ how, "PostgreSQL" ], [ how, "PL/Python" ] ) $$ LANGUAGE plpythonu; @@ -536,7 +513,7 @@ $$ LANGUAGE plpythonu; - 迭代器(任何提供__iter____next__方法的对象) + 迭代器(任何提供 __iter__next 方法的对象) @@ -552,7 +529,7 @@ AS $$ def __iter__ (self): return self - def __next__(self): + def next (self): self.ndx += 1 if self.ndx == len(self.who): raise StopIteration @@ -585,7 +562,7 @@ $$ LANGUAGE plpythonu; - 也支持带OUT参数的返回集函数(使用RETURNS SETOF record)。例如: + 也支持带OUT参数的集合返回函数(使用RETURNS SETOF record)。例如: CREATE FUNCTION multiout_simple_setof(n integer, OUT integer, OUT integer) RETURNS SETOF record AS $$ return [(1, 2)] * n @@ -620,7 +597,7 @@ SELECT * FROM multiout_simple_setof(3); DO $$ - # PL/Python code + # PL/Python 代码 $$ LANGUAGE plpythonu; @@ -869,7 +846,7 @@ CREATE FUNCTION usesavedplan() RETURNS trigger AS $$ else: plan = plpy.prepare("SELECT 1") SD["plan"] = plan - # rest of function + # 函数的其余部分 $$ LANGUAGE plpythonu; @@ -886,11 +863,11 @@ $$ LANGUAGE plpythonu; - 游标对象提供fetch方法,它接受一个整数参数并返回结果对象。每次调用fetch,返回对象都会包含下一批行,数量不会超过该参数值。一旦所有行都已取完,fetch就会开始返回空结果对象。游标对象还提供迭代器接口,每次产生一行,直到所有行为止。以这种方式获取的数据不会作为结果对象返回,而是以字典形式返回,每个字典对应一行结果。 + 游标对象提供fetch方法,它接受一个整数参数并返回结果对象。每次调用fetch,返回对象都会包含下一批行,数量不会超过该参数值。一旦所有行都已取完,fetch就会开始返回空结果对象。游标对象还提供迭代器接口,每次产生一行,直到取完所有行。以这种方式获取的数据不会作为结果对象返回,而是以字典形式返回,每个字典对应一行结果。 - 下面示例展示了如何处理大表中的数据: + 下面示例展示了处理大表中数据的两种方式: CREATE FUNCTION count_odd_iterator() RETURNS integer AS $$ odd = 0 @@ -916,7 +893,7 @@ $$ LANGUAGE plpythonu; CREATE FUNCTION count_odd_prepared() RETURNS integer AS $$ odd = 0 plan = plpy.prepare("select num from largetable where num % $1 <> 0", ["integer"]) -rows = list(plpy.cursor(plan, [2])) # or: = list(plan.cursor([2])) +rows = list(plpy.cursor(plan, [2])) # 或者:= list(plan.cursor([2])) return len(rows) $$ LANGUAGE plpythonu; @@ -957,9 +934,7 @@ $$ LANGUAGE plpythonu; - - 实际抛出的异常类对应于引起错误的具体条件。可能的条件列表见。模块plpy.spiexceptions为每一种PostgreSQL条件都定义了一个异常类,其名称派生自条件名。例如,division_by_zero会变成DivisionByZerounique_violation会变成UniqueViolationfdw_error会变成FdwError,等等。每个异常类都继承自SPIError。这种区分让处理特定错误更容易,例如: - + 所抛出异常的实际类,对应引发错误的具体条件。参见 中列出的可能条件。模块 plpy.spiexceptions 为每种 PostgreSQL 条件定义了一个异常类,类名由条件名派生。例如,division_by_zero 变为 DivisionByZerounique_violation 变为 UniqueViolationfdw_error 变为 FdwError,依此类推。所有这些异常类都继承自 SPIError。这样区分之后,更容易处理特定错误,例如: CREATE FUNCTION insert_fraction(numerator int, denominator int) RETURNS text AS $$ from plpy import spiexceptions try: @@ -974,9 +949,7 @@ except plpy.SPIError as e: else: return "fraction inserted" $$ LANGUAGE plpythonu; - - 请注意,由于plpy.spiexceptions模块中的所有异常都继承自SPIError,处理它的except子句会捕获任何数据库访问错误。 - +注意,因为 plpy.spiexceptions 模块中的所有异常都继承自 SPIError,所以处理它的 except 子句会捕获任何数据库访问错误。 作为处理不同错误情况的另一种方法,你可以捕获SPIError异常,并在except块中通过查看异常对象的sqlstate属性来判断具体的错误条件。该属性是一个包含SQLSTATE错误代码的字符串值。这种方法大体上提供了相同的功能。 @@ -996,9 +969,7 @@ $$ LANGUAGE plpythonu; 子事务上下文管理器 - - 考虑一个在两个账户之间转账的函数: - + 考虑以下实现两个账户之间转账的函数: CREATE FUNCTION transfer_funds() RETURNS void AS $$ try: plpy.execute("UPDATE accounts SET balance = balance - 100 WHERE account_name = 'joe'") @@ -1010,14 +981,9 @@ else: plan = plpy.prepare("INSERT INTO operations (result) VALUES ($1)", ["text"]) plpy.execute(plan, [result]) $$ LANGUAGE plpythonu; - - 如果第二个UPDATE语句导致抛出异常,该函数会报告错误,但第一个UPDATE的结果仍然会被提交。换句话说,资金会从 Joe 的账户中扣除,却不会转入 Mary 的账户。 - +如果第二条 UPDATE 语句引发异常,此函数会报告错误,但第一条 UPDATE 的结果仍会提交。换句话说,资金会从 Joe 的账户中扣除,却不会转入 Mary 的账户。 - - 为避免这种问题,可以把plpy.execute调用包装在显式子事务中。plpy模块提供了一个用于管理显式子事务的辅助对象,它通过plpy.subtransaction()函数创建。该函数创建的对象实现了 - 上下文管理器接口。使用显式子事务后,我们可以将函数重写如下: - + 为避免此类问题,可以将 plpy.execute 调用放在显式子事务中。plpy 模块提供了用于管理显式子事务的辅助对象,可通过 plpy.subtransaction() 函数创建。此函数创建的对象实现了上下文管理器接口。使用显式子事务后,可以将函数改写为: CREATE FUNCTION transfer_funds2() RETURNS void AS $$ try: with plpy.subtransaction(): @@ -1030,17 +996,13 @@ else: plan = plpy.prepare("INSERT INTO operations (result) VALUES ($1)", ["text"]) plpy.execute(plan, [result]) $$ LANGUAGE plpythonu; - - 请注意,仍然需要使用try/except。否则,异常会传播到 Python 栈顶,并以PostgreSQL错误的形式导致整个函数中止,从而使operations表中不会插入任何行。子事务上下文管理器不会捕获错误,它只是确保其作用域内执行的所有数据库操作会被原子地提交或回滚。子事务块在任何类型的异常退出时都会回滚,而不仅仅是由数据库访问引起的错误。在显式子事务块中引发的普通 Python 异常也会导致子事务回滚。 - +注意,仍需要使用 try/except。否则,异常会传播到 Python 调用栈顶层,使整个函数因 PostgreSQL 错误而中止,从而不会向 operations 表插入任何行。子事务上下文管理器不会捕获错误,只保证在其作用域内执行的所有数据库操作以原子方式提交或回滚。任何异常退出都会使子事务块回滚,并不限于数据库访问错误。显式子事务块中抛出的普通 Python 异常,也会导致该子事务回滚。 - 旧式 Python 2 用法 + 较早的 Python 版本 - - 如果使用的 Python 版本早于 2.6,仍然可以通过enterexit便捷别名手动调用子事务管理器的__enter____exit__函数来使用显式子事务。转账示例函数可以写成: - + 使用 with 关键字的上下文管理器语法,从 Python 2.6 起默认可用。为了兼容更早的 Python 版本,可以通过便捷别名 enterexit,调用子事务管理器的 __enter____exit__ 函数。转账示例函数可以写成: CREATE FUNCTION transfer_funds_old() RETURNS void AS $$ try: subxact = plpy.subtransaction() @@ -1099,9 +1061,7 @@ CALL transaction_test1(); - - 实用函数 - + 辅助函数 plpy模块还提供以下函数: @@ -1154,7 +1114,7 @@ PL/Python function "raise_custom_exception" - 另一组实用函数是plpy.quote_literal(string)plpy.quote_nullable(string)以及plpy.quote_ident(string)。它们等价于中描述的内置引用函数。在构造临时查询时,这些函数很有用。中动态 SQL 的一个 PL/Python 等价写法如下: + 另一组辅助函数是plpy.quote_literal(string)plpy.quote_nullable(string)以及plpy.quote_ident(string)。它们等价于中描述的内置加引号函数。在构造临时查询时,这些函数很有用。中动态 SQL 的一个 PL/Python 等价写法如下: plpy.execute("UPDATE tbl SET %s = %s WHERE key = %s" % ( plpy.quote_ident(colname), diff --git a/zh/14/pltcl.sgml b/zh/14/pltcl.sgml index 8746424e..19d660db 100644 --- a/zh/14/pltcl.sgml +++ b/zh/14/pltcl.sgml @@ -13,7 +13,7 @@ - PL/Tcl 是一种适用于 PostgreSQL 数据库系统的可载入的过程语言,它允许使用 Tcl 语言 来编写 PostgreSQL 函数和过程。 + PL/Tcl 是一种适用于 PostgreSQL 数据库系统的可加载的过程语言,它允许使用 Tcl 语言 来编写 PostgreSQL 函数和过程。 @@ -54,7 +54,7 @@ CREATE FUNCTION funcname (argument-types) RETURNS return-type AS $$ - # PL/Tcl function body + # PL/Tcl 函数体 $$ LANGUAGE pltcl; @@ -75,11 +75,11 @@ CREATE FUNCTION tcl_max(integer, integer) RETURNS integer AS $$ $$ LANGUAGE pltcl STRICT; - 注意STRICT子句,它让我们不必考虑空输入值:如果传入的是空值,函数根本不会被调用,而是会自动返回空结果。 + 注意STRICT子句,它让我们不必考虑空值输入:如果传入的是空值,函数根本不会被调用,而是会自动返回空值结果。 - 在非严格函数中,如果某个参数的实际值为空,对应的$n变量会被设置为空串。要检测某个特定参数是否为空,可使用函数argisnull。例如,假设我们希望在tcl_max的两个参数中一个为空、一个非空时返回非空参数,而不是返回空值: + 在非严格函数中,如果某个参数的实际值为空值,对应的$n变量会被设置为空串。要检测某个特定参数是否为空值,可使用函数argisnull。例如,假设我们希望在tcl_max的两个参数中一个为空值、一个非空值时返回非空值参数,而不是返回空值: CREATE FUNCTION tcl_max(integer, integer) RETURNS integer AS $$ @@ -99,7 +99,7 @@ $$ LANGUAGE pltcl; - 复合类型参数会作为 Tcl 数组传递给函数。数组元素名就是该复合类型的属性名。如果传入行中的某个属性为 NULL,它就不会出现在数组中。下面是一个示例: + 复合类型参数会作为 Tcl 数组传递给函数。数组元素名就是该复合类型的属性名。如果传入行中的某个属性为空值,它就不会出现在数组中。下面是一个示例: CREATE TABLE employee ( @@ -185,7 +185,7 @@ $$ LANGUAGE pltcl; PL/Tcl 中的数据值 - 提供给 PL/Tcl 函数代码的参数值,只是将输入参数转换成文本形式(就像用SELECT语句将它们显示出来一样)。反过来,returnreturn_next命令会接受任何字符串,只要它是该函数声明结果类型或组合结果类型中指定列的可接受输入格式。 + 提供给 PL/Tcl 函数代码的参数值,只是将输入参数转换成文本形式(就像用SELECT语句将它们显示出来一样)。反过来,returnreturn_next命令会接受任何字符串,只要它是该函数声明结果类型或复合结果类型中指定列的可接受输入格式。 @@ -195,8 +195,8 @@ $$ LANGUAGE pltcl; PL/Tcl 中的全局数据 - global data - in PL/Tcl + 全局数据 + 在 PL/Tcl 中 @@ -234,7 +234,7 @@ $$ LANGUAGE pltcl; - 执行以字符串形式给出的 SQL 命令。命令出错时会引发错误。否则,spi_exec的返回值是该命令处理的行数(选出、插入、更新或删除的行),如果命令是实用程序语句则返回零。此外,如果命令是SELECT语句,则所选列的值会按下文所述放入 Tcl 变量中。 + 执行以字符串形式给出的 SQL 命令。命令出错时会引发错误。否则,spi_exec的返回值是该命令处理的行数(选出、插入、更新或删除的行),如果命令是工具语句则返回零。此外,如果命令是SELECT语句,则所选列的值会按下文所述放入 Tcl 变量中。 @@ -275,7 +275,7 @@ spi_exec -array C "SELECT * FROM pg_class" { - 如果查询结果中的某一列为空,则对应的目标变量会被unset,而不是被设值。 + 如果查询结果中的某一列为空值,则对应的目标变量会被unset,而不是被设值。 @@ -287,7 +287,7 @@ spi_exec -array C "SELECT * FROM pg_class" { 准备并保存一个查询计划以供后续执行。保存的计划会在当前会话的整个生命周期内保留。 准备查询 - 在PL/Tcl中 + 在 PL/Tcl 中 @@ -317,7 +317,7 @@ spi_exec -array C "SELECT * FROM pg_class" { 可选的-nulls值是由空格和'n'字符组成的字符串,用来告诉spi_execp哪些参数是空值。 - 如果给出,它的长度必须与value-list完全相同。如果未给出,则所有参数值都视为非空。 + 如果给出,它的长度必须与value-list完全相同。如果未给出,则所有参数值都视为非空值。 @@ -331,7 +331,7 @@ spi_exec -array C "SELECT * FROM pg_class" { CREATE FUNCTION t1_count(integer, integer) RETURNS integer AS $$ if {![ info exists GD(plan) ]} { - # prepare the saved plan on the first call + # 在首次调用时准备并保存计划 set GD(plan) [ spi_prepare \ "SELECT count(*) AS cnt FROM t1 WHERE num >= \$1 AND num <= \$2" \ [ list int4 int4 ] ] @@ -367,7 +367,7 @@ $$ LANGUAGE pltcl; 将给定字符串中的所有单引号和反斜杠字符都加倍。 - 这可用于安全地引用那些要插入到传给spi_execspi_prepare的 SQL 命令中的字符串。 + 这可用于安全地为那些要插入到传给spi_execspi_prepare的 SQL 命令中的字符串加引号。 例如,考虑如下 SQL 命令字符串: @@ -393,7 +393,7 @@ SELECT 'doesn''t' AS ret "SELECT '[ quote $val ]' AS ret" - spi_execp的一个优点是,你不必像这样对参数值做引用,因为这些参数永远不会作为 SQL 命令字符串的一部分被解析。 + spi_execp的一个优点是,你不必像这样给参数值加引号,因为这些参数永远不会作为 SQL 命令字符串的一部分被解析。 @@ -404,7 +404,7 @@ SELECT 'doesn''t' AS ret elog level msg elog - 在PL/Tcl中 + 在 PL/Tcl 中 @@ -436,8 +436,8 @@ SELECT 'doesn''t' AS ret PL/Tcl 中的触发器函数 - trigger - in PL/Tcl + 触发器 + 在 PL/Tcl 中 @@ -525,7 +525,7 @@ SELECT 'doesn''t' AS ret $NEW - 对于INSERTUPDATE动作,这是一个包含新表行值的关联数组;对于DELETE则为空。该数组以列名为索引。值为 NULL 的列不会出现在数组中。对于语句级触发器,不会设置这个变量。 + 对于INSERTUPDATE动作,这是一个包含新表行值的关联数组;对于DELETE则为空。该数组以列名为索引。值为空值的列不会出现在数组中。对于语句级触发器,不会设置这个变量。 @@ -534,7 +534,7 @@ SELECT 'doesn''t' AS ret $OLD - 对于UPDATEDELETE动作,这是一个包含旧表行值的关联数组;对于INSERT则为空。该数组以列名为索引。值为 NULL 的列不会出现在数组中。对于语句级触发器,不会设置这个变量。 + 对于UPDATEDELETE动作,这是一个包含旧表行值的关联数组;对于INSERT则为空。该数组以列名为索引。值为空值的列不会出现在数组中。对于语句级触发器,不会设置这个变量。 @@ -598,8 +598,8 @@ CREATE TRIGGER trig_mytab_modcount BEFORE INSERT OR UPDATE ON mytab PL/Tcl 中的事件触发器函数 - event trigger - in PL/Tcl + 事件触发器 + 在 PL/Tcl 中 @@ -615,7 +615,7 @@ CREATE TRIGGER trig_mytab_modcount BEFORE INSERT OR UPDATE ON mytab $TG_event - 触发器因其而被触发的事件名称。 + 该触发器所针对的事件名称。 @@ -624,7 +624,7 @@ CREATE TRIGGER trig_mytab_modcount BEFORE INSERT OR UPDATE ON mytab $TG_tag - 触发器因其而被触发的命令标签。 + 该触发器所针对的命令标签。 @@ -632,7 +632,7 @@ CREATE TRIGGER trig_mytab_modcount BEFORE INSERT OR UPDATE ON mytab - 事件触发器函数的返回值会被忽略。 + 触发器函数的返回值会被忽略。 @@ -653,8 +653,8 @@ CREATE EVENT TRIGGER tcl_a_snitch ON ddl_command_start EXECUTE FUNCTION tclsnitc PL/Tcl 中的错误处理 - exceptions - in PL/Tcl + 异常 + 在 PL/Tcl 中 @@ -682,9 +682,9 @@ if {[catch { spi_exec $sql_command }]} { if {[lindex $::errorCode 0] == "POSTGRES"} { array set errorArray $::errorCode if {$errorArray(condition) == "undefined_table"} { - # deal with missing table + # 处理表不存在的情况 } else { - # deal with some other type of SQL error + # 处理其他类型的 SQL 错误 } } } @@ -698,8 +698,8 @@ if {[catch { spi_exec $sql_command }]} { PL/Tcl 中的显式子事务 - subtransactions - in PL/Tcl + 子事务 + 在 PL/Tcl 中 @@ -797,7 +797,7 @@ CALL transaction_test1(); pltcl.start_proc (string) - pltcl.start_proc configuration parameter + pltcl.start_proc 配置参数 @@ -825,7 +825,7 @@ CALL transaction_test1(); pltclu.start_proc (string) - pltclu.start_proc configuration parameter + pltclu.start_proc 配置参数 @@ -844,7 +844,7 @@ CALL transaction_test1(); Tcl 过程名 - 在PostgreSQL中,只要参数个数或参数类型不同,就可以复用同一个函数名。不过,Tcl 要求所有过程名都必须不同。PL/Tcl 通过让内部 Tcl 过程名包含系统表pg_proc中该函数的对象 ID 来解决这个问题。因此,名称相同而参数类型不同的PostgreSQL函数,也会对应不同的 Tcl 过程。这通常不是 PL/Tcl 程序员需要关心的事情,但在调试时可能会看到。 + 在PostgreSQL中,只要参数个数或参数类型不同,就可以复用同一个函数名。不过,Tcl 要求所有过程名都必须不同。PL/Tcl 处理这一问题的方式是:在内部 Tcl 过程名中包含系统表 pg_proc 中的函数对象 ID 作为其名称的一部分。因此,名称相同但参数类型不同的PostgreSQL函数,也会对应不同的 Tcl 过程。这通常不是 PL/Tcl 程序员需要关心的事情,但在调试时可能会看见。 diff --git a/zh/14/postgres-fdw.sgml b/zh/14/postgres-fdw.sgml index 221b62b6..90d39fa3 100644 --- a/zh/14/postgres-fdw.sgml +++ b/zh/14/postgres-fdw.sgml @@ -98,13 +98,7 @@ 连接选项 - - 使用 postgres_fdw 外部数据包装器的外部服务器, - 可以使用 libpq 在连接字符串中接受的相同选项, - 详见 ;但以下选项不允许使用, - 或会被特殊处理: - - + 使用postgres_fdw外部数据包装器的外部服务器,可以使用与libpq连接字符串所接受的相同选项,详见,但以下选项不被允许,或会受到特殊处理: userpassword 和 @@ -116,18 +110,6 @@ client_encoding(会根据本地服务器编码自动设置) - - - application_name 可以出现在连接选项和 - 中的任一处,或同时出现在 - 二者中。 - 如果两者都存在,postgres_fdw.application_name - 会覆盖连接设置。与 libpq 不同, - postgres_fdw 允许 application_name - 包含逃逸序列。详见 - 。 - - fallback_application_name(始终设置为 @@ -148,22 +130,11 @@ 只有超级用户才能创建或修改带有 sslcertsslkey 设置的用户映射。 - - 非超级用户可以通过密码认证或使用 GSSAPI 委派凭据连接到外部服务器, - 因此在需要密码认证的场景中,应为属于非超级用户的用户映射指定 - password 选项。 - - - 超级用户可以通过设置用户映射选项 - password_required 'false' 按用户映射单独覆盖此检查, - 例如: - + 只有超级用户才能不使用密码认证连接到外部服务器,因此应始终为属于非超级用户的用户映射指定 password 选项。 + 超级用户可以通过设置用户映射选项password_required 'false',按用户映射单独覆盖此检查。例如: ALTER USER MAPPING FOR some_non_superuser SERVER loopback_nopw OPTIONS (ADD password_required 'false'); - - 为了防止非特权用户利用 postgres 服务器所运行的 unix 用户的认证权限 - 提升到超级用户权限,只有超级用户才能在用户映射上设置此选项。 - +为了防止非特权用户利用 postgres 服务器所运行的 unix 用户的认证权限,提升到超级用户权限,只有超级用户才能在用户映射上设置此选项。 必须谨慎确保这不会使被映射用户能够以超级用户身份连接到被映射的数据库, 以避免触发 CVE-2007-3278 和 CVE-2007-6601 所述问题。不要在 @@ -171,7 +142,7 @@ OPTIONS (ADD password_required 'false'); password_required=false。还要记住,被映射用户可能 使用 postgres 服务器所运行的系统用户 unix 主目录中的任何客户端证书、 .pgpass.pg_service.conf - 等文件。(有关如何查找主目录的细节,见 。) + 等文件。 他们还可以利用通过 peerident 等认证方式授予的任何信任关系。 @@ -189,7 +160,7 @@ OPTIONS (ADD password_required 'false'); - schema_name (string) + schema_name 该选项可为外部表指定,用于给出在远程服务器上为该外部表使用的模式名。 @@ -199,7 +170,7 @@ OPTIONS (ADD password_required 'false'); - table_name (string) + table_name 该选项可为外部表指定,用于给出在远程服务器上为该外部表使用的表名。 @@ -209,7 +180,7 @@ OPTIONS (ADD password_required 'false'); - column_name (string) + column_name 该选项可为外部表的某个列指定,用于给出在远程服务器上为该列使用的列名。 @@ -237,7 +208,7 @@ OPTIONS (ADD password_required 'false'); - use_remote_estimate (boolean) + use_remote_estimate 该选项可为外部表或外部服务器指定,用于控制 @@ -249,7 +220,7 @@ OPTIONS (ADD password_required 'false'); - fdw_startup_cost (floating point) + fdw_startup_cost 该选项可为外部服务器指定,是一个浮点值,会被加到该服务器上任何 @@ -260,13 +231,13 @@ OPTIONS (ADD password_required 'false'); - fdw_tuple_cost (floating point) + fdw_tuple_cost 该选项可为外部服务器指定,是一个浮点值,用作该服务器上外部表扫描的 每个元组的额外代价。它表示服务器之间数据传输的额外开销。可以增大或 减小该数值,以反映到远程服务器更高或更低的网络延迟。默认值为 - 0.2。 + 0.01 @@ -287,36 +258,6 @@ OPTIONS (ADD password_required 'false'); 但如果远程表经常更新,本地统计信息很快就会过时。 - - 以下选项控制这种 ANALYZE 操作的行为: - - - - - - analyze_sampling (string) - - - 该选项可为外部表或外部服务器指定,用于决定在外部表上执行 - ANALYZE 时,是在远程端对数据采样,还是读取并传输 - 所有数据后在本地采样。支持的取值为 off、 - randomsystem、 - bernoulliauto。 - off 禁用远程采样,因此所有数据都会被传输并在本地 - 采样。random 使用 random() - 函数选择返回的行,从而在远程端执行采样,而 system 和 - bernoulli 则依赖同名的内置 - TABLESAMPLE 方法。random 适用于 - 所有远程服务器版本,而 TABLESAMPLE 仅从 9.5 起 - 受支持。auto(默认值)会自动选择推荐的采样方法; - 当前意味着根据远程服务器版本选择 bernoulli 或 - random。 - - - - - - @@ -333,12 +274,12 @@ OPTIONS (ADD password_required 'false'); - extensions (string) + extensions 该选项是一个以逗号分隔的 PostgreSQL 扩展 名称列表,这些扩展必须在本地和远程服务器上都已安装且版本兼容。 - 属于列出扩展且为 immutable 的函数和操作符,将被视为可下推到远程服务器 + 属于列出扩展且不可变的函数和操作符,将被视为可下推到远程服务器 执行。该选项只能为外部服务器指定,不能按表指定。 @@ -351,7 +292,7 @@ OPTIONS (ADD password_required 'false'); - fetch_size (integer) + fetch_size 该选项指定 postgres_fdw 在每次取回操作中应获取的 @@ -362,7 +303,7 @@ OPTIONS (ADD password_required 'false'); - batch_size (integer) + batch_size 该选项指定 postgres_fdw 在每次插入操作中应插入的 @@ -379,12 +320,6 @@ OPTIONS (ADD password_required 'false'); 会被调整,以避免报错。 - - 该选项也适用于向外部表执行 COPY。在这种情况下, - postgres_fdw 实际一次复制的行数会以与插入场景 - 类似的方式确定,但由于 COPY 命令的实现限制, - 最多只能为 1000 行。 - @@ -404,7 +339,7 @@ OPTIONS (ADD password_required 'false'); - async_capable (boolean) + async_capable 该选项控制 postgres_fdw 是否允许为异步执行而 @@ -434,58 +369,7 @@ OPTIONS (ADD password_required 'false'); - - 事务管理选项 - - - 如“事务管理”一节所述,在 postgres_fdw 中, - 事务是通过创建对应的远程事务来管理的,子事务则通过创建对应的远程 - 子事务来管理。当当前本地事务涉及多个远程事务时,默认情况下, - postgres_fdw 会在本地事务提交或中止时串行提交 - 或中止这些远程事务。当当前本地子事务涉及多个远程子事务时,默认情况下, - postgres_fdw 也会在本地子事务提交或中止时串行 - 提交或中止这些远程子事务。使用以下选项可以改善性能: - - - - - parallel_commit (boolean) - - - 该选项控制在本地事务提交时,postgres_fdw - 是否并行提交该本地事务中在某个外部服务器上打开的远程事务。 - 此设置也适用于远程子事务和本地子事务。该选项只能为外部服务器指定, - 不能按表指定。默认值为 false。 - - - - - - parallel_abort (boolean) - - - 该选项控制在本地事务中止时,postgres_fdw - 是否并行中止该本地事务中在某个外部服务器上打开的远程事务。 - 此设置也适用于远程子事务和本地子事务。该选项只能为外部服务器指定, - 不能按表指定。默认值为 false。 - - - - - - - - 如果启用了这些选项的多个外部服务器参与同一个本地事务,那么在本地事务 - 提交或中止时,这些外部服务器上的多个远程事务会跨服务器并行提交或中止。 - - - - 启用这些选项后,若某个外部服务器涉及很多远程事务,则在本地事务提交 - 或中止时,该外部服务器上的性能可能会受到负面影响。 - - - 可更新性选项 @@ -498,7 +382,7 @@ OPTIONS (ADD password_required 'false'); - updatable (boolean) + updatable 该选项控制 postgres_fdw 是否允许使用 @@ -531,7 +415,7 @@ OPTIONS (ADD password_required 'false'); - truncatable (boolean) + truncatable 该选项控制 postgres_fdw 是否允许使用 @@ -565,15 +449,14 @@ OPTIONS (ADD password_required 'false'); - import_collate (boolean) + import_collate 该选项控制从外部服务器导入的外部表定义中是否包含列的 COLLATE 选项。默认值为 true。 如果远程服务器的排序规则名称集合与本地服务器不同,则可能需要关闭此 选项;如果远程服务器运行在不同操作系统上,这种情况尤其可能发生。 - 不过,如果这样做,导入表列的排序规则极有可能与底层数据不匹配, - 从而导致查询行为异常。 + 不过,如果这样做,导入表列的排序规则就存在与底层数据不匹配的严重风险,从而导致查询行为异常。 @@ -585,7 +468,7 @@ OPTIONS (ADD password_required 'false'); - import_default (boolean) + import_default 该选项控制从外部服务器导入的外部表定义中是否包含列的 @@ -598,7 +481,7 @@ OPTIONS (ADD password_required 'false'); - import_generated (boolean) + import_generated 该选项控制从外部服务器导入的外部表定义中是否包含列的 @@ -609,7 +492,7 @@ OPTIONS (ADD password_required 'false'); - import_not_null (boolean) + import_not_null 该选项控制从外部服务器导入的外部表定义中是否包含列的 @@ -650,7 +533,7 @@ OPTIONS (ADD password_required 'false'); - keep_connections (boolean) + keep_connections 该选项控制 postgres_fdw 是否保持与外部服务器的 @@ -660,68 +543,6 @@ OPTIONS (ADD password_required 'false'); - - - use_scram_passthrough (boolean) - - - 该选项控制 postgres_fdw 在连接到外部服务器时 - 是否使用 SCRAM 透传认证。使用 SCRAM 透传认证时, - postgres_fdw 使用 SCRAM 哈希后的凭据,而不是 - 明文用户密码连接远程服务器。这样可以避免在 PostgreSQL 系统目录中 - 存储明文用户密码。 - - - - 要使用 SCRAM 透传认证: - - - - 远程服务器必须请求 scram-sha-256 认证方法; - 否则连接将失败。 - - - - - - 远程服务器可以是任何支持 SCRAM 的 PostgreSQL 版本。 - 对 use_scram_passthrough 的支持只要求客户端 - 一侧(FDW 侧)具备。 - - - - - - 用户映射密码不会被使用。 - - - - - - 运行 postgres_fdw 的服务器与远程服务器, - 必须针对用于在 postgres_fdw 上认证到外部 - 服务器的该用户,拥有完全相同的 SCRAM secret(加密密码) - (盐值和迭代次数都必须相同,而不仅仅是密码相同)。 - - - - 因而,如果要建立到多个主机的 FDW 连接,例如用于分区外部表或分片, - 则所有主机都必须为相关用户保存完全相同的 SCRAM secret。 - - - - - - 发起对外 FDW 连接的 PostgreSQL 实例中,当前会话的传入客户端连接 - 也必须使用 SCRAM 认证。(因此称为透传:SCRAM - 必须在进入和离开时都被使用。)这是 SCRAM 协议的技术要求。 - - - - - - - @@ -730,111 +551,22 @@ OPTIONS (ADD password_required 'false'); 函数 - - postgres_fdw_get_connections( - IN check_conn boolean DEFAULT false, OUT server_name text, - OUT user_name text, OUT valid boolean, OUT used_in_xact boolean, - OUT closed boolean, OUT remote_backend_pid int4) - returns setof record - - - 此函数返回 postgres_fdw 从本地会话到外部服务器所建立的所有打开连接的 - 信息。如果没有打开的连接,则不返回任何记录。 - - - 如果将 check_conn 设置为 true, - 该函数会检查每个连接的状态,并在 closed 列中显示 - 结果。该特性当前仅在支持对 poll 系统调用的非标准 - POLLRDHUP 扩展的系统上可用,包括 Linux。 - 这对于检查事务中使用的所有连接是否仍然打开很有帮助。如果任一连接已经 - 关闭,该事务将无法成功提交,因此在检测到关闭连接后,最好尽快回滚, - 而不是继续执行到末尾。如果函数报告的某个连接同时满足 - used_in_xactclosed 都为 - true,用户即可立即回滚事务。 - - - 此函数的用法示例: + + postgres_fdw_get_connections(OUT server_name text, OUT valid boolean) returns setof record + + + 此函数返回postgres_fdw从本地会话向外部服务器建立的所有打开连接的外部服务器名称。它还返回每个连接是否有效。如果外部服务器连接在当前本地事务中被使用,但其外部服务器或用户映射被更改或删除,则返回false(注意,如果服务器被删除,无效连接的服务器名称将为NULL),然后这样的无效连接将在该事务结束时被关闭。否则返回true。如果没有打开的连接,则不返回任何记录。 + 该函数的用法示例: -postgres=# SELECT * FROM postgres_fdw_get_connections(true); - server_name | user_name | valid | used_in_xact | closed | remote_backend_pid --------------+-----------+-------+--------------+----------------------------- - loopback1 | postgres | t | t | f | 1353340 - loopback2 | public | t | t | f | 1353120 - loopback3 | | f | t | f | 1353156 +postgres=# SELECT * FROM postgres_fdw_get_connections() ORDER BY 1; + server_name | valid +-------------+------- + loopback1 | t + loopback2 | f - 输出列见 。 - - -
- <function>postgres_fdw_get_connections</function> 输出列 - - - - - 类型 - 描述 - - - - - - server_name - text - - 此连接的外部服务器名称。如果服务器已被删除但连接仍保持打开 - (即被标记为无效),则该值为 NULL。 - - - - user_name - text - - 映射到此连接所属外部服务器的本地用户名称;如果使用的是 public - 映射,则为 public。 - 如果用户映射已被删除但连接仍保持打开(即被标记为无效),则该值为 - NULL。 - - - - valid - boolean - - 如果此连接无效,则为假;无效意味着它在当前事务中被使用,但其外部 - 服务器或用户映射已被更改或删除。无效连接将在事务结束时关闭。 - 否则返回真。 - - - - used_in_xact - boolean - - 如果此连接在当前事务中被使用,则为真。 - - - - closed - boolean - - 如果此连接已关闭,则为真,否则为假。如果 - check_conn 被设置为 false, - 或当前平台不提供连接状态检查,则返回 NULL。 - - - - remote_backend_pid - int4 - - 外部服务器上处理此连接的远程后端进程 ID。如果远程后端已终止且 - 连接已关闭(closedtrue), - 此处仍会显示该已终止后端的进程 ID。 - - - - -
- -
- + + + postgres_fdw_disconnect(server_name text) returns boolean @@ -929,8 +661,7 @@ postgres=# SELECT postgres_fdw_disconnect_all(); - 请注意,postgres_fdw 当前不支持将远程事务预备为 - 两阶段提交。 + 请注意,postgres_fdw 当前不支持为两阶段提交预备远程事务。 @@ -941,9 +672,9 @@ postgres=# SELECT postgres_fdw_disconnect_all(); postgres_fdw 会尽力优化远程查询,以减少从外部 服务器传输的数据量。这是通过将查询的 WHERE 子句发送到 远程服务器执行,以及不获取当前查询不需要的表列来实现的。为降低查询被 - 错误执行的风险,除非 WHERE 子句仅使用内置数据类型、 - 操作符和函数,或属于外部服务器 extensions 选项列出的 - 扩展,否则不会将其发送到远程服务器。这类子句中的操作符和函数还必须是 + 错误执行的风险,只有当 WHERE 子句使用的所有数据类型、 + 操作符和函数都是内置的,或属于外部服务器 extensions + 选项列出的扩展时,才会将该子句发送到远程服务器。这类子句中的操作符和函数还必须是 IMMUTABLE。对于 UPDATEDELETE 查询,postgres_fdw 会在 查询中不存在无法发送到远程服务器的 WHERE 子句、没有 @@ -1028,8 +759,6 @@ postgres=# SELECT postgres_fdw_disconnect_all(); postgres_fdw 可用于最早追溯到 PostgreSQL 8.3 的远程服务器。只读能力可追溯到 8.1。 - - 不过有一个限制是,postgres_fdw 通常假定: 如果外部表的 WHERE 子句中出现不可变的内置函数和 操作符,那么把它们发送到远程服务器执行是安全的。因此,某个在远程服务器 @@ -1039,146 +768,11 @@ postgres=# SELECT postgres_fdw_disconnect_all(); OFFSET 0 的子 SELECT 中,作为优化 栅栏,并将有问题的函数或操作符放到子 SELECT 之外。 - - 另一个限制是,在外部表上执行 INSERT 语句并带有 - ON CONFLICT DO NOTHING 子句时,远程服务器必须运行 - PostgreSQL 9.5 或更高版本,因为更早版本 - 不支持此特性。 - - - - - 等待事件 - - - postgres_fdw 可以在等待事件类型 - Extension 下报告以下等待事件: - - - - - PostgresFdwCleanupResult - - - 等待远程服务器上的事务中止。 - - - - - - PostgresFdwConnect - - - 等待与远程服务器建立连接。 - - - - - - PostgresFdwGetResult - - - 等待接收来自远程服务器的查询结果。 - - - - - - 配置参数 - - - - - postgres_fdw.application_name (string) - - postgres_fdw.application_name configuration parameter - - - - - 指定用于 配置参数的值, - 该值会在 postgres_fdw 建立到外部服务器的连接时使用。这会覆盖 - 服务器对象的 application_name 选项。请注意, - 修改此参数不会影响任何现有连接,除非这些连接重新建立。 - - - postgres_fdw.application_name 可以是任意长度的任意 - 字符串,甚至可以包含非 ASCII 字符。不过,当它被传递并作为外部服务器中 - 的 application_name 使用时,请注意它会被截断到少于 - NAMEDATALEN 个字符。所有不可打印 ASCII 字符都会被 - 替换为C 风格的十六进制逃逸。 - 有关细节见 。 - - - - % 字符表示逃逸序列的开始,并会按下述方式 - 替换为状态信息。未识别的逃逸会被忽略。其他字符会原样复制到应用名中。 - 请注意,不允许在 % 与选项字母之间指定正负号或数字 - 字面量来进行对齐和填充。 - - - - - - 逃逸序列 - 效果 - - - - - %a - 本地服务器上的应用名 - - - %c - - 本地服务器上的会话 ID - (细节见 ) - - - - %C - - 本地服务器上的集簇名 - (细节见 ) - - - - %u - 本地服务器上的用户名 - - - %d - 本地服务器上的数据库名 - - - %p - 本地服务器上后端的进程 ID - - - %% - 字面值 % - - - - - - 例如,假设用户 local_user 以用户 - foreign_user 身份,从数据库 - local_db 建立到 foreign_db 的连接, - 则设置 'db=%d, user=%u' 会被替换为 - 'db=local_db, user=local_user'。 - - - - - 示例 diff --git a/zh/14/postgres.sgml b/zh/14/postgres.sgml index 3c7171a2..d78bb30d 100644 --- a/zh/14/postgres.sgml +++ b/zh/14/postgres.sgml @@ -114,6 +114,7 @@ &installbin; &installation; + &installw; &runtime; &config; &client-auth; @@ -124,6 +125,7 @@ &backup; &high-availability; &monitoring; + &diskusage; &wal; &logical-replication; &jit; diff --git a/zh/14/protocol.sgml b/zh/14/protocol.sgml index 128501d5..1d964377 100644 --- a/zh/14/protocol.sgml +++ b/zh/14/protocol.sgml @@ -776,28 +776,10 @@ SELCT 1/0; - 目前,系统会为以下参数发送 ParameterStatus: - - application_name - client_encoding - DateStyle - default_transaction_read_only - in_hot_standby - integer_datetimes - IntervalStyle - is_superuser - scram_iterations - search_path - server_encoding - server_version - session_authorization - standard_conforming_strings - TimeZone - - (default_transaction_read_onlyin_hot_standby 在 14 之前不报告; - scram_iterations 在 16 之前不报告; - search_path 在 18 之前不报告。) - 注意 server_versionserver_encodinginteger_datetimes 是启动后不可更改的伪参数。未来该集合可能变化,甚至可能变为可配置。因此,前端应忽略其不理解或不关心的 ParameterStatus。 + 目前,会为一组固定的参数生成 ParameterStatus,参数如下: + server_versionserver_encodingclient_encodingapplication_namedefault_transaction_read_onlyin_hot_standbyis_superusersession_authorizationDateStyleIntervalStyleTimeZoneinteger_datetimesstandard_conforming_strings。 + (8.0 之前的版本不报告 server_encodingTimeZoneinteger_datetimes;8.1 之前的版本不报告 standard_conforming_strings;8.4 之前的版本不报告 IntervalStyle;9.0 之前的版本不报告 application_name;14 之前的版本不报告 default_transaction_read_onlyin_hot_standby。) + 注意,server_versionserver_encodinginteger_datetimes 是启动后不能改变的伪参数。这组参数将来可能变化,甚至可能变为可配置。因此,前端应直接忽略其不理解或不关心的参数的 ParameterStatus。 @@ -1250,50 +1232,94 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" CREATE_REPLICATION_SLOT - - + 创建一个物理或逻辑复制槽。查看了解更多关于复制槽的信息。 + + + slot_name + + + 要创建的复制槽名称。必须是合法的复制槽名称(参见)。 + + + - + + output_plugin + + + 用于逻辑解码的输出插件的名称(参见)。 + + + + + + TEMPORARY + + + 指定此复制槽为临时槽。临时槽不会保存到磁盘,并且在错误或会话结束时会自动删除。 + + + + + + RESERVE_WAL + + 指定此物理复制槽立即保留 WAL。否则,只有在流复制客户端连接时才会保留 WAL + + + + + EXPORT_SNAPSHOT + NOEXPORT_SNAPSHOT + USE_SNAPSHOT + + 决定如何处理初始化逻辑复制槽时创建的快照。默认选项 EXPORT_SNAPSHOT 会导出快照供其他会话使用,此选项不能在事务内使用。USE_SNAPSHOT 会将快照用于执行该命令的当前事务;此选项必须在事务内使用,且 CREATE_REPLICATION_SLOT 必须是该事务中执行的第一条命令。最后,NOEXPORT_SNAPSHOT 只会像平常一样将快照用于逻辑解码,不会对其执行其他操作。 + + + + + + 在响应此命令时,服务器将发送一个包含以下字段的单行结果集: - slot_name + slot_name (text) - - 要创建的复制槽名称。必须是合法的复制槽名称(参见)。 - + 新创建的复制槽的名称。 + - - consistent_point (text) - - + + consistent_point (text) + + 复制槽达到一致状态时的 WAL 位置。这是可从该复制槽开始流式传输的最早位置。 - - + + - - snapshot_name (text) - - - 该命令导出的快照标识符。该快照在此连接上执行下一条命令之前,或复制连接关闭之前有效。如果所创建的是物理复制槽,则为 null。 + + snapshot_name (text) + + + 该命令导出的快照标识符。该快照在此连接上执行下一条命令之前,或复制连接关闭之前有效。如果所创建的是物理复制槽,则为空值。 - - + + - - output_plugin (text) - - - 新建复制槽所使用的输出插件名称。如果所创建的是物理复制槽,则为 null。 + + output_plugin (text) + + + 新建复制槽所使用的输出插件名称。如果所创建的是物理复制槽,则为空值。 - - - - + + + + + @@ -1714,39 +1740,40 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - - BASE_BACKUP [ LABEL 'label' ] [ PROGRESS ] [ FAST ] [ WAL ] [ NOWAIT ] [ MAX_RATE rate ] [ TABLESPACE_MAP ] [ NOVERIFY_CHECKSUMS ] [ MANIFEST manifest_option ] [ MANIFEST_CHECKSUMS checksum_algorithm ] + BASE_BACKUP [ LABEL 'label' ] [ PROGRESS ] [ FAST ] [ WAL ] [ NOWAIT ] [ MAX_RATE rate ] [ TABLESPACE_MAP ] [ NOVERIFY_CHECKSUMS ] [ MANIFEST manifest_option ] [ MANIFEST_CHECKSUMS checksum_algorithm ] BASE_BACKUP - - - - 指示服务器开始流式传输基本备份。 + + + 指示服务器开始流式传输基础备份。 在备份开始之前,系统将自动进入备份模式,并在备份完成后退出备份模式。 接受以下选项: - - LABEL 'label' - - - + + LABEL 'label' + + 设置备份的标签。如果未指定,则将使用base backup作为备份标签。 - 标签的引用规则与打开的标准SQL字符串相同。 + 标签的引号使用规则与打开的标准SQL字符串相同。 - - + + - - PROGRESS - - - 请求生成进度报告所需的信息。这将在每个表空间的头部发回大致大小,可用于计算流式传输的完成进度。此大小通过在传输开始之前枚举所有文件大小来计算,因此可能对性能有负面影响。特别是在第一个数据被发出之前可能需要更长的时间。 - - - + + PROGRESS + + + 请求生成进度报告所需的信息。这将在每个表空间的首部发送一个近似大小, + 可用于计算流式传输的进度。这是通过在传输开始之前先枚举所有文件大小来计算的, + 可能会对性能产生负面影响。特别是,在流式传输数据之前可能需要更长的时间。 + 由于备份期间数据库文件可能会发生变化,因此大小仅为近似值, + 在估算与实际发送文件之间的这段时间里可能会增长或缩小。 + + + - + FAST @@ -1755,29 +1782,21 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - - WAL [ boolean ] - - - - 如果设置为true,则在备份中包含必要的WAL段。这将包括在开始和停止备份之间的所有文件在基本目录tar文件的pg_wal目录中。默认值为false。 - - - - - - WAIT [ boolean ] - + + WAL + + 在备份中包含必要的 WAL 段。这会把开始备份到停止备份之间的所有文件放入基础目录 tar 文件内的pg_wal目录中。 + + - - 如果设置为 true,备份会等待直到最后一个所需 WAL 段已归档;若未启用 WAL 归档则发出警告。 - 如果设置为 false,备份既不等待也不警告,而由客户端负责确保所需 WAL 可用。 - 默认值为true。 - - - + + NOWAIT + + 默认情况下,备份会等待最后一个必需的 WAL 段完成归档;如果未启用日志归档,则发出警告。指定 NOWAIT 会同时禁用等待和警告,由客户端负责确保所需日志可用。 + + - + MAX_RATE rate @@ -1789,45 +1808,40 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - - TABLESPACE_MAP [ boolean ] - - - - 如果为true,则在名为tablespace_map的文件中包含目录pg_tblspc中存在的符号链接的信息。 - 表空间映射文件包括目录pg_tblspc/中每个符号链接的名称及该符号链接的完整路径。默认值为false。 - - - - - - VERIFY_CHECKSUMS [ boolean ] - - - - 如果为true,则在进行基本备份时验证校验和(如果已启用)。如果为false,则跳过此步骤。默认值为true。 + + TABLESPACE_MAP + + + 在名为tablespace_map的文件中包含目录pg_tblspc中存在的符号链接的信息。 + 表空间映射文件包括目录pg_tblspc/中每个符号链接的名称及该符号链接的完整路径。 - - + + - - MANIFEST manifest_option - + + NOVERIFY_CHECKSUMS + + 默认情况下,如果启用了校验和,基础备份期间就会验证校验和。指定 NOVERIFY_CHECKSUMS 会禁用此项验证。 + + - + + MANIFEST manifest_option + + 当指定此选项的值为yesforce-encode时, 将创建一个备份清单并随备份一起发送。该清单是备份中每个文件的列表, 除了可能包含的任何WAL文件。它还存储每个文件的大小、最后修改时间, 以及可选的校验和。 值为force-encode会强制对所有文件名进行十六进制编码; - 否则,仅对文件名为非UTF8八位序列的文件执行此类型的编码。 + 否则,仅对文件名为非 UTF8 字节序列的文件执行此类型的编码。 force-encode主要用于测试目的,以确保读取备份清单的客户端 能够处理这种情况。为了与之前的版本兼容,默认值为MANIFEST 'no' - - + + - + MANIFEST_CHECKSUMS checksum_algorithm @@ -1840,176 +1854,80 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - + - - + 当备份开始时,服务器将首先发送两个普通的结果集,然后是一个或多个CopyOutResponse结果。 - - + 第一个普通结果集包含备份的起始位置,在一个包含两列的单行中。第一列包含以XLogRecPtr格式给出的起始位置,第二列包含相应的时间线ID。 - - + 第二个普通结果集中的每个表空间都有一行。 - 这一行中的字段是: + 这一行中的字段是: - - spcoid (oid) - - - 表空间的OID,如果是基本目录则为null。 - - - - - - spclocation (text) - - - 表空间目录的完整路径,如果是基本目录则为null。 - - - - - - size (int8) - - - 表空间的大致大小,以千字节(1024字节)为单位,如果已请求进度报告;否则为null。 - - - - - - - - 在第二个常规结果集之后,将发送一个CopyOutResponse。 - 每个CopyData消息的有效负载将包含以下格式之一的消息: - - - - - manifest (B) + spcoid (oid) - - - - Byte1('m') - - - - 标识消息表示备份清单的开始。 - - - - + + 表空间的OID,如果是基础目录则为null。 + - - - 归档或清单数据 (B) + spclocation (text) - - - - Byte1('d') - - - - 标识消息包含归档或清单数据。 - - - - - - - Byten - - - - 数据字节。 - - - - + + 表空间目录的完整路径,如果是基础目录则为null。 + - - - progress report (B) - - - - - Byte1('p') - - - - 标识消息为进度报告。 - - - - - - - Int64 - - - - 已完成处理的来自当前表空间的字节数。 - - - - - - + size (int8) + + + 表空间的大致大小,以千字节(1024字节)为单位,如果已请求进度报告;否则为null。 + + + - - - 在发送了CopyOutResponse或所有这些响应之后,将发送最终的普通结果集,其中包含备份的WAL结束位置,格式与起始位置相同。 + 第二个普通结果集之后,会发送一个或多个 CopyOutResponse 结果:主数据目录对应一个,除 pg_defaultpg_global 之外的每个附加表空间各对应一个。CopyOutResponse 结果中的数据是表空间内容的 tar 格式转储(遵循 POSIX 1003.1-2008 标准规定的 ustar interchange format),但省略了标准要求的末尾两个全零块。tar 数据传输完成后,如果请求了备份清单,还会再发送一个 CopyOutResponse 结果,其中包含当前基础备份的清单数据。无论如何,最后都会发送一个普通结果集,包含备份的 WAL 结束位置,格式与起始位置相同。 - + 数据目录和每个表空间的tar归档将包含目录中的所有文件,无论它们是PostgreSQL文件还是添加到同一目录的其他文件。唯一排除的文件是: - + postmaster.pid - + postmaster.opts - + pg_internal.init(在多个目录中找到) - + PostgreSQL 服务器运行期间创建的各种临时文件和目录,例如以pgsql_tmp开头的任何文件或目录以及临时关系。 - - - 不记录 WAL 的关系(Unlogged表),除了需要在恢复时重新创建(空的)不记录 WAL 的关系的init fork。 - - - - - pg_wal,包括子目录。如果备份包含WAL文件,则将包含pg_wal的合成版本,但它只包含备份工作所需的文件,而不包含其余内容。 + + 不记录 WAL 的关系,但不包括恢复时重新创建(空的)不记录 WAL 的关系所需的初始化分支。 + + + + pg_wal,包括子目录。如果备份包含WAL文件,则将包含pg_wal的合成版本,但它只包含使备份可用所需的文件,而不包含其余内容。 - - + + pg_dynshmempg_notifypg_replslotpg_serial, @@ -2017,16 +1935,16 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" pg_subtrans将作为空目录复制(即使它们是符号链接)。 - - - 除了常规文件和目录之外的文件,如符号链接(除了上述列出的目录之外的符号链接)以及特殊设备和操作系统文件,将被跳过。(pg_tblspc中的符号链接将被保留。) + + + 除了普通文件和目录之外的文件,如符号链接(除了上述列出的目录之外的符号链接)以及特殊设备文件,将被跳过。(pg_tblspc中的符号链接将被保留。) - - + + 如果服务器上的底层文件系统支持,将设置所有者、组和文件模式。 - - + + @@ -2052,7 +1970,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 逻辑复制参数 + 逻辑流复制参数 使用 START_REPLICATION 命令时,pgoutput 接受以下选项: @@ -2075,8 +1993,29 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 用于订阅(接收更改)的发布名称的逗号分隔列表。各个发布名称按标准对象名处理,可按需加引号。 - 至少需要一个发布名称。 + 要订阅(接收变更)的发布名称列表,以逗号分隔。各个发布名称按标准对象名处理,可按需加引号。至少需要一个发布名称。 + + + + + + + binary + + + + 使用二进制传输模式的布尔选项。二进制模式比文本模式更快,但稳健性略差。 + + + + + + + messages + + + + 布尔选项,用于启用发送由 pg_logical_emit_message 写入的消息。 @@ -2094,9 +2033,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - - 在上述命令中,若参数类型为 boolean,可省略 value 部分;省略等同于指定 TRUE。 - + @@ -2938,58 +2875,58 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" + +CancelRequest (F) + + + - CancelRequest (F) - - - - - Int32 - - - - 消息内容的长度(以字节为单位),包括其自身。 + + + + Int32(16) + + + + 消息内容的长度,以字节为单位,包括此长度字段本身。 - - - - - - Int32(80877102) - - - - 取消请求代码。该值被选择为在最高的16位中包含1234,在最低的16位中包含5678。 - (为避免混淆,此代码不得与任何协议版本号相同。) + + + + + Int32(80877102) + + + + 取消请求代码。此值的最高 16 位为 1234,最低 16 位为 5678。(为避免混淆,此代码不能与任何协议版本号相同。) - - - - - - Int32 - - - - 目标后端的进程ID。 + + + + + Int32 + + + + 目标后端的进程 ID。 - - - - - - Int32 - - - - 目标后端的 secret key。该字段长度由消息总长度决定并延伸至消息末尾,最大长度为 256 字节。 + + + + + Int32 + + + + 目标后端的密钥。 - - - + + + - - + + + @@ -5067,7 +5004,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 严重性: 字段内容为ERROR, FATAL, 或 + 严重性: 字段内容为ERROR, FATAL, 或 PANIC (在错误消息中), 或 WARNING, NOTICE, DEBUG, INFO, 或 LOG (在通知消息中), @@ -5105,7 +5042,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 消息: 主要的人类可读错误消息。 + 消息: 主要的人类可读错误消息。 这应该准确但简洁(通常一行)。 总是存在。 @@ -5127,7 +5064,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 提示: 关于问题应该怎么做的一个可选建议。 + 提示: 关于问题应该怎么做的一个可选建议。 这意在与细节不同,它提供建议(可能不合适)而不是硬性事实。 可能会跨越多行。 @@ -5161,7 +5098,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 内部查询: 一个失败的内部生成命令的文本。 + 内部查询: 一个失败的内部生成命令的文本。 例如,这可能是由PL/pgSQL函数发出的SQL查询。 @@ -5194,7 +5131,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 表名: 如果错误与特定表相关联,则为表的名称。(有关表模式名称的名称,请参考模式名称字段。) + 表名: 如果错误与特定表相关联,则为表的名称。(有关表模式名称的名称,请参考模式名称字段。) @@ -5204,7 +5141,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 列名: 如果错误与特定表列相关联,则为列的名称。(请参考模式和表名字段以识别表。) + 列名: 如果错误与特定表列相关联,则为列的名称。(请参考模式和表名字段以识别表。) @@ -5214,7 +5151,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 数据类型名称: 如果错误与特定数据类型相关联,则为数据类型的名称。 + 数据类型名称: 如果错误与特定数据类型相关联,则为数据类型的名称。 (有关数据类型模式的名称,请参阅模式名称字段。) @@ -5225,7 +5162,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 约束名称: 如果错误与特定约束相关联,则为约束的名称。请参考上面列出的字段,了解相关表或域。 + 约束名称: 如果错误与特定约束相关联,则为约束的名称。请参考上面列出的字段,了解相关表或域。 (为此,即使索引不是使用约束语法创建的,也将其视为约束。) @@ -5236,7 +5173,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 文件: 报告错误的源代码位置的文件名。 + 文件: 报告错误的源代码位置的文件名。 @@ -5374,7 +5311,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 标志; 逻辑解码消息是非事务性的时为0,是事务性的时为1。 + 标志; 逻辑解码消息是非事务性的时为0,是事务性的时为1。 @@ -5448,7 +5385,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 标志; 目前未使用。 + 标志; 目前未使用。 @@ -6146,7 +6083,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 标志; 目前未使用。 + 标志; 目前未使用。 @@ -6324,15 +6261,36 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 协议 3.0 与之前版本的变化总结 + 自协议 2.0 以来的变更总结 - - 本节概述了协议 3.0 与之前协议版本之间的变化。这可以帮助那些需要实现同时处理多种协议版本的客户端库的开发者,或仅仅出于好奇的读者。 - + + 本节提供一份简要的变更清单,供准备将现有客户端库更新到协议 3.0 的开发者参考。 + - - 本文档的初始版本描述了协议 3.0。该协议是在PostgreSQL 7.4 中引入的,至今仍然基本保持不变。有关之前协议版本的变化的详细信息,请参阅相应PostgreSQL版本的文档。 - + 初始启动包采用灵活的字符串列表格式,取代了固定格式。注意,运行时参数的会话默认值现在可以直接在启动包中指定。(实际上,以前也能通过 options 字段实现,但由于 options 的宽度有限,且无法用引号保护值中的空白字符,这种方法并不稳妥。) - + 现在,所有消息都在消息类型字节之后紧跟一个长度计数(启动包除外,它没有类型字节)。另请注意,PasswordMessage 现在也有类型字节。 + + ErrorResponse 和 NoticeResponse('E' 和 'N')消息现在包含多个字段,客户端代码可以利用这些字段组合出所需详细程度的错误消息。注意,各字段通常不会以换行符结束,而旧协议发送的单个字符串总是以换行符结束。 + + ReadyForQuery('Z')消息包含一个事务状态指示器。 + + BinaryRow 与 DataRow 消息类型不再有区别;单一的 DataRow 消息类型用于返回所有格式的数据。注意,DataRow 的布局已经改变,使其更容易解析。另外,二进制值的表示方式也已改变,不再直接取决于服务器内部的表示方式。 + + 新增了扩展查询子协议,其中增加了前端消息类型 Parse、Bind、Execute、Describe、Close、Flush 和 Sync,以及后端消息类型 ParseComplete、BindComplete、PortalSuspended、ParameterDescription、NoData 和 CloseComplete。现有客户端不必关注这个子协议,但使用它可能有助于改善性能或功能。 + + COPY 数据现在封装在 CopyData 和 CopyDone 消息中。COPY 期间的错误恢复已有明确定义的方法。不再需要特殊的最后一行 \.COPY OUT 期间也不再发送它。(在 COPY IN 期间仍会将它识别为终止符,但这种用法已弃用,最终将被移除。)现已支持二进制 COPY。CopyInResponse 和 CopyOutResponse 消息包含了表示列数及各列格式的字段。 + + FunctionCall 和 FunctionCallResponse 消息的布局已经改变。FunctionCall 现在支持向函数传递 NULL 参数,也可以使用文本或二进制格式传递参数和取得结果。由于它不再提供对服务器内部数据表示的直接访问,因此也不再有理由将 FunctionCall 视为潜在的安全漏洞。 + + 在连接启动期间,后端会为其认为客户端库关注的所有参数发送 ParameterStatus('S')消息。之后,只要这些参数中任何一个的当前值发生变化,就会发送一条 ParameterStatus 消息。 + + RowDescription('T')消息针对所描述行中的每一列,增加了表 OID 和列编号字段,并显示各列的格式代码。 + + 后端不再生成 CursorResponse('P')消息。 + + NotificationResponse('A')消息增加了一个字符串字段,可以携带 NOTIFY 事件发送者传来的载荷字符串。 + + EmptyQueryResponse('I')消息以前包含一个空字符串参数,现在已将其移除。 + diff --git a/zh/14/queries.sgml b/zh/14/queries.sgml index 2051c520..198cfd82 100644 --- a/zh/14/queries.sgml +++ b/zh/14/queries.sgml @@ -509,7 +509,7 @@ FROM (VALUES ('anne', 'smith'), ('bob', 'jones'), ('joe', 'blow')) - 表函数是那些生成行集合的函数,这些行可以由基本数据类型(标量类型)组成,也可以由复合数据类型(表行)组成。它们在查询的FROM子句中用法类似于表、视图或子查询。表函数返回的列可以像表、视图或子查询的列一样,出现在SELECTJOINWHERE子句中。 + 表函数是那些生成行集合的函数,这些行可以由基础类型(标量类型)组成,也可以由复合数据类型(表行)组成。它们在查询的FROM子句中用法类似于表、视图或子查询。表函数返回的列可以像表、视图或子查询的列一样,出现在SELECTJOINWHERE子句中。 @@ -547,7 +547,7 @@ UNNEST( array_expression , ... - 如果没有提供列的别名,那么对于一个返回基数据类型的函数,列名也与该函数 + 如果没有提供列的别名,那么对于一个返回基础类型的函数,列名也与该函数 名相同。对于一个返回复合类型的函数,结果列会从该类型的属性得到名称。 diff --git a/zh/14/rangetypes.sgml b/zh/14/rangetypes.sgml index f60e0af7..68409fa3 100644 --- a/zh/14/rangetypes.sgml +++ b/zh/14/rangetypes.sgml @@ -209,7 +209,7 @@ SELECT '{[3,7), [8,9)}'::int4multirange; 构造范围和多范围 - 每种范围类型都有一个与范围类型同名的构造函数。使用构造函数通常比书写范围文字常量更方便,因为这样无需对界限值进行额外引用。构造函数接受两个或三个参数。两个参数的形式构造标准形式的范围(下界包含,上界排除),而三个参数的形式则按第三个参数指定的界限形式构造范围。第三个参数必须是下列字符串之一: + 每种范围类型都有一个与范围类型同名的构造函数。使用构造函数通常比书写范围字面量更方便,因为这样无需为界限值额外加引号。构造函数接受两个或三个参数。两个参数的形式构造标准形式的范围(下界包含,上界排除),而三个参数的形式则按第三个参数指定的界限形式构造范围。第三个参数必须是下列字符串之一: ()(][)或者 diff --git a/zh/14/ref/abort.sgml b/zh/14/ref/abort.sgml index 95835c70..caed1f42 100644 --- a/zh/14/ref/abort.sgml +++ b/zh/14/ref/abort.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ABORT 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/allfiles.sgml b/zh/14/ref/allfiles.sgml index 883cd94a..88a37081 100644 --- a/zh/14/ref/allfiles.sgml +++ b/zh/14/ref/allfiles.sgml @@ -202,10 +202,8 @@ PostgreSQL documentation - - @@ -220,8 +218,8 @@ PostgreSQL documentation - + diff --git a/zh/14/ref/alter_aggregate.sgml b/zh/14/ref/alter_aggregate.sgml index 6e6d9e05..c021ff23 100644 --- a/zh/14/ref/alter_aggregate.sgml +++ b/zh/14/ref/alter_aggregate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER AGGREGATE 7 - SQL - Language Statements + SQL - 语言语句 @@ -41,13 +41,7 @@ ALTER AGGREGATE name ( aggregate_signatu ALTER AGGREGATE更改聚合函数的定义。 - - 要使用ALTER AGGREGATE,你必须拥有该聚合函数。 - 要更改聚合函数的模式,你还必须在新模式上具有 - CREATE权限。要更改拥有者,你必须能够对新的拥有角色执行 - SET ROLE,并且该角色必须在该聚合函数所在模式上具有 - CREATE权限。(这些限制确保更改拥有者不会做出任何你无法通过删除并重新创建该聚合函数来完成的事情。不过,超级用户无论如何都可以更改任何聚合函数的所有权。) - + 要使用ALTER AGGREGATE,必须拥有该聚合函数。要更改聚合函数的模式,还必须在新模式上拥有CREATE权限。要更改所有者,还必须是新所有者角色的直接或间接成员,并且该角色必须在聚合函数所在模式上拥有CREATE权限。(这些限制确保更改所有者不会执行任何无法通过删除并重新创建聚合函数完成的操作。不过,超级用户无论如何都可以更改任何聚合函数的所有权。) diff --git a/zh/14/ref/alter_collation.sgml b/zh/14/ref/alter_collation.sgml index 85fd5517..5b2914c0 100644 --- a/zh/14/ref/alter_collation.sgml +++ b/zh/14/ref/alter_collation.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER COLLATION 7 - SQL - Language Statements + SQL - 语言语句 @@ -36,14 +36,7 @@ ALTER COLLATION name SET SCHEMA new_sche ALTER COLLATION更改排序规则的定义。 - - 要使用ALTER COLLATION,你必须拥有该排序规则。 - 要更改拥有者,你必须能够对新的拥有角色执行SET ROLE, - 并且该角色必须在该排序规则所在模式上具有CREATE权限。 - (这些限制确保更改拥有者不会做出任何你无法通过删除并重新创建该排序 - 规则来完成的事情。不过,超级用户无论如何都可以更改任何排序规则的所 - 有权。) - + 要使用ALTER COLLATION,必须拥有该排序规则。要更改所有者,还必须是新所有者角色的直接或间接成员,并且该角色必须在排序规则所在模式上拥有CREATE权限。(这些限制确保更改所有者不会执行任何无法通过删除并重新创建排序规则完成的操作。不过,超级用户无论如何都可以更改任何排序规则的所有权。) @@ -102,7 +95,8 @@ ALTER COLLATION name SET SCHEMA new_sche 注解 - 创建排序规则对象时,该排序规则的提供者特定版本会记录在系统目录中。 + 使用 ICU 库提供的排序规则时,创建排序规则对象会在系统目录中记录 + ICU 给出的排序器版本。 使用该排序规则时,会将当前版本与记录的版本进行比较;如果二者不匹 配,就会发出警告,例如: @@ -112,19 +106,17 @@ HINT: Rebuild all objects affected by this collation and run ALTER COLLATION pg 排序规则定义的变化可能导致索引损坏及其他问题,因为数据库系统依赖已 存储对象具有特定的排序顺序。一般来说应避免这种情况,但在某些合理情 - 形下仍可能发生,例如将操作系统升级到新的主版本,或者使用 + 形下仍可能发生,例如使用 pg_upgrade升级到链接了较新 ICU 版本的服务器二进 制文件时。出现这种情况时,应重建所有依赖该排序规则的对象,例如使用 REINDEX。完成后,可以使用命令 ALTER COLLATION ... REFRESH VERSION刷新排序规则 - 版本。这样会更新系统目录,使其记录当前的排序规则版本,并让该警告消 + 版本。这样会更新系统目录,使其记录当前的排序器版本,并让该警告消 失。请注意,这实际上并不会检查所有受影响对象是否都已被正确重建。 当使用libc提供的排序规则时,在使用 GNU C 库 (大多数 Linux 系统)、FreeBSD 和 Windows 的系统上会记录版本信息。 - 当使用 ICU 提供的排序规则时,版本信息由 ICU 库提供,并且在所有平台 - 上都可用。 @@ -138,10 +130,7 @@ HINT: Rebuild all objects affected by this collation and run ALTER COLLATION pg 义的排序规则,例如en-US - - 对于数据库默认排序规则,有一个对应的命令 - ALTER DATABASE ... REFRESH COLLATION VERSION。 - + 目前,数据库默认排序规则没有版本跟踪。 以下查询可用于识别当前数据库中所有需要刷新的排序规则,以及依赖它们 diff --git a/zh/14/ref/alter_conversion.sgml b/zh/14/ref/alter_conversion.sgml index d6c8e82c..979ef1e2 100644 --- a/zh/14/ref/alter_conversion.sgml +++ b/zh/14/ref/alter_conversion.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER CONVERSION 7 - SQL - Language Statements + SQL - 语言语句 @@ -34,13 +34,7 @@ ALTER CONVERSION name SET SCHEMA new_sch ALTER CONVERSION更改一个转换的定义。 - - 要使用ALTER CONVERSION,你必须拥有该转换。 - 要更改拥有者,你必须能够对新的拥有者角色执行SET ROLE, - 并且该角色必须在转换所在模式上具有CREATE权限。 - (这些限制确保更改拥有者不会做出任何你无法通过删除并重新创建该转换 - 来完成的事情。不过,超级用户仍然可以更改任何转换的所有权。) - + 要使用ALTER CONVERSION,必须拥有该转换。要更改所有者,还必须是新所有者角色的直接或间接成员,并且该角色必须在转换所在模式上拥有CREATE权限。(这些限制确保更改所有者不会执行任何无法通过删除并重新创建转换完成的操作。不过,超级用户无论如何都可以更改任何转换的所有权。) diff --git a/zh/14/ref/alter_database.sgml b/zh/14/ref/alter_database.sgml index 41dcd0fe..f6e12b7e 100644 --- a/zh/14/ref/alter_database.sgml +++ b/zh/14/ref/alter_database.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER DATABASE 7 - SQL - Language Statements + SQL - 语言语句 @@ -35,8 +35,6 @@ ALTER DATABASE name OWNER TO { name
SET TABLESPACE new_tablespace -ALTER DATABASE name REFRESH COLLATION VERSION - ALTER DATABASE name SET configuration_parameter { TO | = } { value | DEFAULT } ALTER DATABASE name SET configuration_parameter FROM CURRENT ALTER DATABASE name RESET configuration_parameter @@ -59,14 +57,10 @@ ALTER DATABASE name RESET ALL 第二种形式更改数据库的名称。只有数据库拥有者或者超级用户可以重命名数据库;非超级用户拥有者还必须具有CREATEDB权限。当前连接的数据库不能被重命名(如果需要这样做,请连接到另一个数据库)。 - - 第三种形式更改数据库的拥有者。要修改拥有者,你必须能够对新拥有者角色执行 - SET ROLE,并且还必须具有CREATEDB权限。 - (注意,超级用户会自动拥有这些权限。) - + 第三种形式更改数据库的所有者。要更改所有者,必须拥有该数据库,并且还必须是新所有者角色的直接或间接成员,并且必须拥有CREATEDB权限。(请注意,超级用户会自动拥有所有这些权限。) - 第四种形式更改数据库的默认表空间。只有数据库拥有者或者超级用户可以这样做;你还必须对新表空间具有创建权限。该命令会将数据库旧默认表空间中的所有表和索引在物理上移动到新表空间中。对于该数据库而言,新默认表空间必须为空,并且不能有人连接到该数据库。位于非默认表空间中的表和索引不受影响。复制文件到新表空间所使用的方法会受到设置的影响。 + 第四种形式更改数据库的默认表空间。只有数据库拥有者或者超级用户可以这样做;你还必须对新表空间具有创建权限。该命令会将数据库旧默认表空间中的所有表和索引在物理上移动到新表空间中。对于该数据库而言,新默认表空间必须为空,并且不能有人连接到该数据库。位于非默认表空间中的表和索引不受影响。 @@ -90,9 +84,7 @@ ALTER DATABASE name RESET ALL allowconn - - 如果为假,则没有人能连接到这个数据库。 - + 如果为 false,则任何人都不能连接到该数据库。 @@ -109,7 +101,7 @@ ALTER DATABASE name RESET ALL istemplate - 如果为真,则任何具有CREATEDB权限的用户都可以从这个数据库克隆。如果为假,则只有超级用户或者该数据库的拥有者可以克隆它。 + 如果为 true,则任何具有 CREATEDB 权限的用户都可以克隆该数据库;如果为 false,则只有超级用户或该数据库的拥有者可以克隆它。 @@ -145,15 +137,7 @@ ALTER DATABASE name RESET ALL - - REFRESH COLLATION VERSION - - - 更新数据库排序规则版本。背景信息见。 - - - + configuration_parameter diff --git a/zh/14/ref/alter_default_privileges.sgml b/zh/14/ref/alter_default_privileges.sgml index 2fca3f17..644de19c 100644 --- a/zh/14/ref/alter_default_privileges.sgml +++ b/zh/14/ref/alter_default_privileges.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER DEFAULT PRIVILEGES 7 - SQL - Language Statements + SQL - 语言语句 @@ -121,7 +121,7 @@ REVOKE [ GRANT OPTION FOR ] - 当前,只有模式、表(包括视图和外部表)、序列、函数、类型(包括域)以及大对象的权限可以修改。 + 当前,只有模式、表(包括视图和外部表)、序列、函数、类型(包括域)的权限可以修改。 对于此命令,函数包括聚合函数和过程。此命令中的FUNCTIONSROUTINES等价。(今后更推荐使用ROUTINES, 因为这是同时指代函数和过程的标准术语。在较早的PostgreSQL版本中, @@ -156,8 +156,8 @@ REVOKE [ GRANT OPTION FOR ] 一个现有模式的名称。如果指定,将修改以后在该模式中创建的对象的默认权限。 如果省略IN SCHEMA,则修改全局默认权限。 - 在为模式和大对象设置权限时,不允许使用IN SCHEMA, - 因为模式不能嵌套,而大对象不属于任何模式。 + 在为模式设置权限时,不允许使用IN SCHEMA, + 因为模式不能嵌套。 diff --git a/zh/14/ref/alter_domain.sgml b/zh/14/ref/alter_domain.sgml index a0fe964c..6d5c8f70 100644 --- a/zh/14/ref/alter_domain.sgml +++ b/zh/14/ref/alter_domain.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER DOMAIN 7 - SQL - Language Statements + SQL - 语言语句 @@ -148,13 +148,7 @@ ALTER DOMAIN name - - 要使用ALTER DOMAIN,你必须拥有该域。要更改域的模式, - 你还必须在新模式上具有CREATE权限。要更改拥有者,你必须能够对 - 新的拥有角色执行SET ROLE,并且该角色必须在该域所在的模式上具有 - CREATE权限。(这些限制确保更改拥有者不会做出任何你不能通过 - 删除并重新创建该域来完成的事情。不过,超级用户无论如何都可以更改任何域的所有权。) - + 要使用ALTER DOMAIN,必须拥有该域。要更改域的模式,还必须在新模式上拥有CREATE权限。要更改所有者,还必须是新所有者角色的直接或间接成员,并且该角色必须在域所在模式上拥有CREATE权限。(这些限制确保更改所有者不会执行任何无法通过删除并重新创建域完成的操作。不过,超级用户无论如何都可以更改任何域的所有权。) diff --git a/zh/14/ref/alter_event_trigger.sgml b/zh/14/ref/alter_event_trigger.sgml index 326f30e1..b9407346 100644 --- a/zh/14/ref/alter_event_trigger.sgml +++ b/zh/14/ref/alter_event_trigger.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER EVENT TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -58,7 +58,7 @@ ALTER EVENT TRIGGER name RENAME TO new_owner - 该事件触发器的新拥有者的用户名。 + 该事件触发器的新所有者的用户名。 @@ -94,7 +94,7 @@ ALTER EVENT TRIGGER name RENAME TO - 另见 + 参见 diff --git a/zh/14/ref/alter_extension.sgml b/zh/14/ref/alter_extension.sgml index 9471390f..3ceae003 100644 --- a/zh/14/ref/alter_extension.sgml +++ b/zh/14/ref/alter_extension.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER EXTENSION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/alter_foreign_data_wrapper.sgml b/zh/14/ref/alter_foreign_data_wrapper.sgml index 06bdb8be..52dbfc7e 100644 --- a/zh/14/ref/alter_foreign_data_wrapper.sgml +++ b/zh/14/ref/alter_foreign_data_wrapper.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER FOREIGN DATA WRAPPER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/alter_foreign_table.sgml b/zh/14/ref/alter_foreign_table.sgml index 14958ed9..a8e47a75 100644 --- a/zh/14/ref/alter_foreign_table.sgml +++ b/zh/14/ref/alter_foreign_table.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER FOREIGN TABLE 7 - SQL - Language Statements + SQL - 语言语句 @@ -286,15 +286,7 @@ ALTER FOREIGN TABLE [ IF EXISTS ] name - - 你必须拥有该表才能使用ALTER FOREIGN TABLE。 - 要更改外部表的模式,你还必须在新模式上具有CREATE权限。 - 要更改拥有者,你必须能够对新的拥有角色执行SET ROLE, - 并且该角色必须在该表所在模式上具有CREATE权限。 - (这些限制确保更改拥有者不会做出任何你无法通过删除并重新创建该表来完成的事情。 - 不过,超级用户仍然可以更改任何表的所有权。) - 要添加列或更改列类型,你还必须在该数据类型上具有USAGE权限。 - + 要使用ALTER FOREIGN TABLE,必须拥有该表。要更改外部表的模式,还必须在新模式上拥有CREATE权限。要更改所有者,还必须是新所有者角色的直接或间接成员,并且该角色必须在表所在模式上拥有CREATE权限。(这些限制确保更改所有者不会执行任何无法通过删除并重新创建该表完成的操作。不过,超级用户无论如何都可以更改任何表的所有权。)要添加列或更改列类型,还必须在数据类型上拥有USAGE权限。 diff --git a/zh/14/ref/alter_function.sgml b/zh/14/ref/alter_function.sgml index 5de95078..c23e0831 100644 --- a/zh/14/ref/alter_function.sgml +++ b/zh/14/ref/alter_function.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation ALTER FUNCTION 7 - SQL - Language Statements + SQL - 语言语句 @@ -59,14 +59,7 @@ ALTER FUNCTION name [ ( [ [ group_name RENAME TO 组的角色授予或撤销成员资格, 因此更推荐使用GRANTREVOKE。 - 请注意,GRANTREVOKE还提供了此命令没有的附加选项, - 例如可以授予和撤销ADMIN OPTION,以及指定授权者(grantor)。 diff --git a/zh/14/ref/alter_index.sgml b/zh/14/ref/alter_index.sgml index 06134114..978d61e1 100644 --- a/zh/14/ref/alter_index.sgml +++ b/zh/14/ref/alter_index.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER INDEX 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/alter_language.sgml b/zh/14/ref/alter_language.sgml index 7af98f20..000fe499 100644 --- a/zh/14/ref/alter_language.sgml +++ b/zh/14/ref/alter_language.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER LANGUAGE 7 - SQL - Language Statements + SQL - 语言语句 @@ -31,8 +31,8 @@ ALTER [ PROCEDURAL ] LANGUAGE name OWNER TO { ALTER LANGUAGE更改一种过程语言的定义。 - 目前唯一的功能是重命名该语言或为其指定新的拥有者。 - 要使用ALTER LANGUAGE,你必须是超级用户或者该语言的拥有者。 + 目前唯一的功能是重命名该语言或为其指定新的所有者。 + 要使用ALTER LANGUAGE,你必须是超级用户或者该语言的所有者。 @@ -62,7 +62,7 @@ ALTER [ PROCEDURAL ] LANGUAGE name OWNER TO { new_owner - 该语言的新拥有者 + 该语言的新所有者 diff --git a/zh/14/ref/alter_large_object.sgml b/zh/14/ref/alter_large_object.sgml index ad3f61f7..6805cd38 100644 --- a/zh/14/ref/alter_large_object.sgml +++ b/zh/14/ref/alter_large_object.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER LARGE OBJECT 7 - SQL - Language Statements + SQL - 语言语句 @@ -32,12 +32,7 @@ ALTER LARGE OBJECT large_object_oid ALTER LARGE OBJECT更改一个大对象的定义。 - - 要使用ALTER LARGE OBJECT,你必须是该大对象的拥有者。 - 要修改其拥有者,你还必须能够对新的拥有者角色执行SET ROLE。 - (不过,超级用户无论如何都可以修改任何大对象。) - 当前唯一提供的功能是指定新的拥有者,因此这两项限制始终都适用。 - + 要使用ALTER LARGE OBJECT,必须拥有该大对象。要更改所有者,还必须是新所有者角色的直接或间接成员。(不过,超级用户无论如何都可以更改任何大对象。)目前唯一的功能是指定新的所有者,因此两项限制始终适用。 diff --git a/zh/14/ref/alter_materialized_view.sgml b/zh/14/ref/alter_materialized_view.sgml index 71ac3ade..6d22460b 100644 --- a/zh/14/ref/alter_materialized_view.sgml +++ b/zh/14/ref/alter_materialized_view.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER MATERIALIZED VIEW 7 - SQL - Language Statements + SQL - 语言语句 @@ -59,14 +59,7 @@ ALTER MATERIALIZED VIEW ALL IN TABLESPACE name - - 要使用ALTER MATERIALIZED VIEW,你必须拥有该物化视图。 - 要更改一个物化视图的模式,你还必须具有新模式上的CREATE权限。 - 要更改拥有者,你必须能够对新拥有角色执行SET ROLE, - 并且该角色必须具有该物化视图所在模式上的CREATE权限。 - (这些限制确保,更改拥有者不会做到你无法通过删除并重新创建该物化视图来完成的事情。 - 不过,超级用户无论如何都可以更改任何视图的所有权。) - + 要使用ALTER MATERIALIZED VIEW,必须拥有该物化视图。要更改物化视图的模式,还必须在新模式上拥有CREATE权限。要更改所有者,还必须是新所有者角色的直接或间接成员,并且该角色必须在物化视图所在模式上拥有CREATE权限。(这些限制确保更改所有者不会执行任何无法通过删除并重新创建物化视图完成的操作。不过,超级用户无论如何都可以更改任何视图的所有权。) 可用于ALTER MATERIALIZED VIEW的语句形式和动作是 diff --git a/zh/14/ref/alter_opclass.sgml b/zh/14/ref/alter_opclass.sgml index b1872b37..e6ab8643 100644 --- a/zh/14/ref/alter_opclass.sgml +++ b/zh/14/ref/alter_opclass.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER OPERATOR CLASS 7 - SQL - Language Statements + SQL - 语言语句 @@ -39,13 +39,7 @@ ALTER OPERATOR CLASS name USING res_proc | NONE } | JOIN = { join_proc | NONE } - | COMMUTATOR = com_op - | NEGATOR = neg_op - | HASHES - | MERGES - } [, ... ] ) + } [, ... ] ) @@ -45,13 +41,7 @@ ALTER OPERATOR name ( { left_typeALTER OPERATOR更改一个操作符的定义。 - - 要使用ALTER OPERATOR,你必须拥有该操作符。 - 要修改拥有者,你必须能够对新拥有角色执行SET ROLE, - 并且该角色必须在该操作符所在模式上具有CREATE权限。 - (这些限制确保更改拥有者不会让你做到那些不能通过删除并重建该操作符来做到的事情。 - 不过,超级用户始终可以更改任何操作符的所有权。) - + 要使用ALTER OPERATOR,必须拥有该操作符。要更改所有者,还必须是新所有者角色的直接或间接成员,并且该角色必须在操作符所在模式上拥有CREATE权限。(这些限制确保更改所有者不会执行任何无法通过删除并重新创建操作符完成的操作。不过,超级用户无论如何都可以更改任何操作符的所有权。) @@ -122,63 +112,19 @@ ALTER OPERATOR name ( { left_type - - com_op - - - 该操作符的交换子。只有当该操作符当前没有交换子时,才能修改此项。 - - - - - neg_op - - - 该操作符的求反器。只有当该操作符当前没有求反器时,才能修改此项。 - - - - - HASHES - - - 表示该操作符可以支持哈希连接。该属性只能启用,不能禁用。 - - - - - MERGES - - - 表示该操作符可以支持归并连接。该属性只能启用,不能禁用。 - - - - - - - 注解 - - 更多信息请参见和 - 。 - - - 由于交换子总是成对出现、彼此互为交换子, - ALTER OPERATOR SET COMMUTATOR也会把 - com_op的交换子设置为目标操作符。 - 同样,ALTER OPERATOR SET NEGATOR也会把 - neg_op的求反器设置为目标操作符。 - 因此,你不仅必须拥有目标操作符,也必须拥有其交换子或求反器操作符。 - + + + + 示例 @@ -193,16 +139,11 @@ ALTER OPERATOR @@ (text, text) OWNER TO joe; 更改类型int[]上的自定义操作符a && b的 限制和连接选择度估算函数: -ALTER OPERATOR && (int[], int[]) SET (RESTRICT = _int_contsel, JOIN = _int_contjoinsel); +ALTER OPERATOR && (_int4, _int4) SET (RESTRICT = _int_contsel, JOIN = _int_contjoinsel); - - 将&&操作符标记为其自身的交换子: - -ALTER OPERATOR && (int[], int[]) SET (COMMUTATOR = &&); - - + diff --git a/zh/14/ref/alter_opfamily.sgml b/zh/14/ref/alter_opfamily.sgml index a0b755c2..45e5007b 100644 --- a/zh/14/ref/alter_opfamily.sgml +++ b/zh/14/ref/alter_opfamily.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER OPERATOR FAMILY 7 - SQL - Language Statements + SQL - 语言语句 @@ -247,6 +247,9 @@ ALTER OPERATOR FAMILY name USING ALTER PROCEDURE更改过程的定义。 - - 要使用ALTER PROCEDURE,你必须拥有该过程。要更改 - 过程的模式,你还必须在新模式上具有CREATE权限。 - 要更改拥有者,你必须能够对新的拥有角色执行SET ROLE, - 并且该角色必须在过程所在模式上具有CREATE权限。 - (这些限制确保更改拥有者不会做出任何你无法通过删除并重新创建该过程 - 来完成的事情。不过,超级用户仍然可以更改任何过程的所有权)。 - + 要使用ALTER PROCEDURE,必须拥有该过程。要更改过程的模式,还必须在新模式上拥有CREATE权限。要更改所有者,还必须是新所有者角色的直接或间接成员,并且该角色必须在过程所在模式上拥有CREATE权限。(这些限制确保更改所有者不会执行任何无法通过删除并重新创建过程完成的操作。不过,超级用户无论如何都可以更改任何过程的所有权。) diff --git a/zh/14/ref/alter_publication.sgml b/zh/14/ref/alter_publication.sgml index 146b7061..9cde4166 100644 --- a/zh/14/ref/alter_publication.sgml +++ b/zh/14/ref/alter_publication.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER PUBLICATION 7 - SQL - Language Statements + SQL - 语言语句 @@ -21,26 +21,12 @@ PostgreSQL documentation -ALTER PUBLICATION name ADD publication_object [, ...] -ALTER PUBLICATION name SET publication_object [, ...] -ALTER PUBLICATION name DROP publication_drop_object [, ...] +ALTER PUBLICATION name ADD TABLE [ ONLY ] table_name [ * ] [, ...] +ALTER PUBLICATION name SET TABLE [ ONLY ] table_name [ * ] [, ...] +ALTER PUBLICATION name DROP TABLE [ ONLY ] table_name [ * ] [, ...] ALTER PUBLICATION name SET ( publication_parameter [= value] [, ... ] ) ALTER PUBLICATION name OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } ALTER PUBLICATION name RENAME TO new_name - -其中publication_object可以是: - - TABLE table_and_columns [, ... ] - TABLES IN SCHEMA { schema_name | CURRENT_SCHEMA } [, ... ] - -其中publication_drop_object可以是: - - TABLE [ ONLY ] table_name [ * ] [, ... ] - TABLES IN SCHEMA { schema_name | CURRENT_SCHEMA } [, ... ] - -其中table_and_columns是: - - [ ONLY ] table_name [ * ] [ ( column_name [, ... ] ) ] [ WHERE ( expression ) ] @@ -51,18 +37,7 @@ ALTER PUBLICATION name RENAME TO ALTER PUBLICATION命令可更改发布的属性。 - - 前三种形式会更改哪些表或模式属于该发布。SET子句 - 会用指定列表替换发布中的表或模式列表;原先已在该发布中的表或模式将 - 被移除。ADDDROP子句则会向发 - 布中添加或移除一个或多个表或模式。请注意,向已经被订阅的发布中添加 - 表或模式后,需要在订阅端执行 - ALTER SUBSCRIPTION ... REFRESH PUBLICATION - 操作后才会生效。还要注意,DROP TABLES IN SCHEMA - 不会移除那些通过 - FOR TABLE/ADD TABLE - 指定的模式中的表。 - + 前三种形式会更改哪些表属于该发布。SET TABLE子句会用指定列表替换发布中的表列表。ADD TABLEDROP TABLE子句会向发布添加或从发布移除一个或多个表。请注意,向已被订阅的发布添加表,需要在订阅端执行ALTER SUBSCRIPTION ... REFRESH PUBLICATION操作后才会生效。 提要中列出的第四种形式可更改 @@ -73,23 +48,9 @@ ALTER PUBLICATION name RENAME TO - - 要使用ALTER PUBLICATION,你必须拥有该发布。 - 向发布中添加表还要求拥有该表。对发布执行 - ADD TABLES IN SCHEMA和 - SET TABLES IN SCHEMA要求调用用户为超级用户。 - 要更改所有者,你必须能够对新的拥有角色执行SET ROLE, - 并且该角色必须在数据库上具有CREATE权限。此外, - FOR ALL TABLES - 或FOR TABLES IN SCHEMA - 发布的新所有者也必须是超级用户。不过,超级用户可以不受这些限制而更 - 改发布的所有权。 - + 要使用ALTER PUBLICATION,必须拥有该发布。向发布添加表还要求拥有该表。要更改所有者,还必须是新所有者角色的直接或间接成员。新所有者必须在数据库上拥有CREATE权限。此外,FOR ALL TABLES发布的新所有者必须是超级用户。不过,超级用户无论这些限制如何都可以更改发布的所有权。 + - - 如果某个发布还发布了带列列表的表,则不支持向其中添加或设置任何模 - 式;反之亦然。 - @@ -115,25 +76,12 @@ ALTER PUBLICATION name RENAME TO - - 如果指定了可选的WHERE子句,则 - expression计算结果为 - false 或 null 的行不会被发布。请注意,表达式外围必须有括号。 - expression会使用复制连 - 接所用的角色来求值。 - - - - - schema_name - - - 现有模式的名称。 - + + SET ( publication_parameter [= value] [, ... ] ) @@ -141,20 +89,7 @@ ALTER PUBLICATION name RENAME TO 设置的 发布参数。详见该命令的说明。 - - - 更改 publish_via_partition_root 参数可能导致订 - 阅端发生数据丢失或重复,因为它会改变已发布表的标识和模式。请注 - 意,只有当根分区表被指定为复制目标时,才会发生此问题。 - - - 可通过以下方式避免此问题:在执行 - ALTER PUBLICATION ... SET之后、执行 - ALTER SUBSCRIPTION ... REFRESH PUBLICATION - 之前,不修改分区叶子表;并且刷新时仅使用 - copy_data = off选项。 - - + @@ -181,41 +116,14 @@ ALTER PUBLICATION name RENAME TO 示例 - - 将发布修改为只发布删除和更新: - + 将发布更改为只发布删除和更新操作: ALTER PUBLICATION noinsert SET (publish = 'update, delete'); - - 向发布中添加一些表: - -ALTER PUBLICATION mypublication ADD TABLE users (user_id, firstname), departments; + 向发布添加一些表: +ALTER PUBLICATION mypublication ADD TABLE users, departments; - - - 更改某个表所发布的列集合: - -ALTER PUBLICATION mypublication SET TABLE users (user_id, firstname, lastname), TABLE departments; - - - - 将模式marketingsales - 添加到发布sales_publication中: - -ALTER PUBLICATION sales_publication ADD TABLES IN SCHEMA marketing, sales; - - - - - 将表usersdepartments和模式 - production添加到发布 - production_publication中: - -ALTER PUBLICATION production_publication ADD TABLE users, departments, TABLES IN SCHEMA production; - - diff --git a/zh/14/ref/alter_role.sgml b/zh/14/ref/alter_role.sgml index cb589085..5be2fab2 100644 --- a/zh/14/ref/alter_role.sgml +++ b/zh/14/ref/alter_role.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation ALTER ROLE 7 - SQL - Language Statements + SQL - 语言语句 @@ -76,14 +76,7 @@ ALTER ROLE { role_specification | A 且非复制角色。普通角色只能更改自己的密码。 - - 第二种形式更改角色的名称。数据库超级用户可以重命名任何角色。具有 - CREATEROLE权限的角色可以重命名其已被授予 - ADMIN OPTION的非超级用户角色。当前会话用户不能被重命名。 - (如果需要这样做,请以其他用户连接。) - 由于MD5加密的密码使用角色名作为密码学盐值,如果该密码采用 - MD5加密,重命名角色会清除其密码。 - + 第二种形式更改角色的名称。数据库超级用户可以重命名任何角色。拥有CREATEROLE权限的角色可以重命名非超级用户角色。当前会话用户不能被重命名。(如果需要这样做,请以其他用户连接。)由于MD5加密的密码使用角色名作为密码学盐,重命名角色会清除其密码(如果密码使用MD5加密)。 其余形式更改角色针对配置变量的会话默认值,可以针对所有数据库,也可以在指定 @@ -103,12 +96,7 @@ ALTER ROLE { role_specification | A 或特定角色的设置会覆盖针对所有角色的设置。 - - 超级用户可以更改任何角色的会话默认值。具有CREATEROLE权限的角色 - 可以更改其已被授予ADMIN OPTION的非超级用户角色的默认值。 - 普通角色只能为自己设置默认值。某些配置变量不能以这种方式设置,或者只有由超级用户 - 发出该命令时才能设置。只有超级用户才能更改所有数据库中所有角色的设置。 - + 超级用户可以更改任何人的会话默认值。拥有CREATEROLE权限的角色可以更改非超级用户角色的默认值。普通角色只能为自己设置默认值。某些配置变量不能以这种方式设置,或者只能由超级用户执行命令来设置。只有超级用户可以更改所有数据库中所有角色的设置。 diff --git a/zh/14/ref/alter_routine.sgml b/zh/14/ref/alter_routine.sgml index 4fc3e18d..79191e1e 100644 --- a/zh/14/ref/alter_routine.sgml +++ b/zh/14/ref/alter_routine.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER ROUTINE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/alter_rule.sgml b/zh/14/ref/alter_rule.sgml index 9449d787..9397274c 100644 --- a/zh/14/ref/alter_rule.sgml +++ b/zh/14/ref/alter_rule.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER RULE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/alter_schema.sgml b/zh/14/ref/alter_schema.sgml index 2baf518d..c711f199 100644 --- a/zh/14/ref/alter_schema.sgml +++ b/zh/14/ref/alter_schema.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER SCHEMA 7 - SQL - Language Statements + SQL - 语言语句 @@ -33,13 +33,7 @@ ALTER SCHEMA name OWNER TO { new_ownerALTER SCHEMA更改一个模式的定义。 - - 要使用ALTER SCHEMA,你必须拥有该模式。 - 要重命名一个模式,你还必须具有该数据库的CREATE权限。 - 要更改拥有者,你必须能够对新的拥有者角色执行SET ROLE, - 并且该角色还必须具有该数据库的CREATE权限。 - (注意,超级用户会自动拥有所有这些权限。) - + 要使用ALTER SCHEMA,必须拥有该模式。要重命名模式,还必须在数据库上拥有CREATE权限。要更改所有者,还必须是新所有者角色的直接或间接成员,并且必须在数据库上拥有CREATE权限。(请注意,超级用户会自动拥有所有这些权限。) diff --git a/zh/14/ref/alter_sequence.sgml b/zh/14/ref/alter_sequence.sgml index d25e854d..a2c648fb 100644 --- a/zh/14/ref/alter_sequence.sgml +++ b/zh/14/ref/alter_sequence.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER SEQUENCE 7 - SQL - Language Statements + SQL - 语言语句 @@ -47,13 +47,7 @@ ALTER SEQUENCE [ IF EXISTS ] name S ALTER SEQUENCE命令中未明确设置的参数,会保留其原有设置。 - - 要使用ALTER SEQUENCE,你必须拥有该序列。要更改序列所在的模式, - 你还必须在新模式上具有CREATE权限。要更改拥有者,你必须能够对新的拥有角色执行 - SET ROLE,并且该角色必须在该序列所在模式上具有CREATE权限。 - (这些限制确保更改拥有者不会做出任何你不能通过删除并重建该序列来完成的事情。 - 不过,超级用户无论如何都可以更改任何序列的所有权。) - + 要使用ALTER SEQUENCE,必须拥有该序列。要更改序列的模式,还必须在新模式上拥有CREATE权限。要更改所有者,还必须是新所有者角色的直接或间接成员,并且该角色必须在序列所在模式上拥有CREATE权限。(这些限制确保更改所有者不会执行任何无法通过删除并重新创建序列完成的操作。不过,超级用户无论如何都可以更改任何序列的所有权。) diff --git a/zh/14/ref/alter_server.sgml b/zh/14/ref/alter_server.sgml index 5d870833..c500ff22 100644 --- a/zh/14/ref/alter_server.sgml +++ b/zh/14/ref/alter_server.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER SERVER 7 - SQL - Language Statements + SQL - 语言语句 @@ -37,12 +37,7 @@ ALTER SERVER name RENAME TO - - 要更改服务器,你必须是该服务器的拥有者。此外,要更改拥有者,你必须 - 能够对新的拥有角色执行SET ROLE,并且必须在该服 - 务器的外部数据包装器上具有USAGE权限。(注意, - 超级用户会自动满足所有这些条件。) - + 要更改服务器,必须是服务器的所有者。此外,要更改所有者,还必须拥有该服务器,是新所有者角色的直接或间接成员,并且必须在服务器的外部数据包装器上拥有USAGE权限。(请注意,超级用户会自动满足所有这些条件。) diff --git a/zh/14/ref/alter_statistics.sgml b/zh/14/ref/alter_statistics.sgml index 315ff6b7..f98f20b2 100644 --- a/zh/14/ref/alter_statistics.sgml +++ b/zh/14/ref/alter_statistics.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER STATISTICS 7 - SQL - Language Statements + SQL - 语言语句 @@ -38,14 +38,7 @@ ALTER STATISTICS name SET STATISTIC 凡未在ALTER STATISTICS命令中明确设置的参数,都会保留其原有设置。 - - 要使用ALTER STATISTICS,你必须拥有该统计对象。 - 要更改统计对象的模式,你还必须在新模式上具有CREATE权限。 - 要更改所有者,你必须能够对新的拥有角色执行SET ROLE, - 并且该角色必须在统计对象所在的模式上具有CREATE权限。 - (这些限制确保更改所有者不会做出任何你无法通过删除并重新创建该统计对象来完成的事情。 - 不过,超级用户无论如何都可以更改任何统计对象的所有权。) - + 要使用ALTER STATISTICS,必须拥有该统计对象。要更改统计对象的模式,还必须在新模式上拥有CREATE权限。要更改所有者,还必须是新所有者角色的直接或间接成员,并且该角色必须在统计对象所在模式上拥有CREATE权限。(这些限制确保更改所有者不会执行任何无法通过删除并重新创建统计对象完成的操作。不过,超级用户无论如何都可以更改任何统计对象的所有权。) diff --git a/zh/14/ref/alter_subscription.sgml b/zh/14/ref/alter_subscription.sgml index f69d2743..07975852 100644 --- a/zh/14/ref/alter_subscription.sgml +++ b/zh/14/ref/alter_subscription.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER SUBSCRIPTION 7 - SQL - Language Statements + SQL - 语言语句 @@ -29,7 +29,6 @@ ALTER SUBSCRIPTION name REFRESH PUB ALTER SUBSCRIPTION name ENABLE ALTER SUBSCRIPTION name DISABLE ALTER SUBSCRIPTION name SET ( subscription_parameter [= value] [, ... ] ) -ALTER SUBSCRIPTION name SKIP ( skip_option = value ) ALTER SUBSCRIPTION name OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } ALTER SUBSCRIPTION name RENAME TO new_name @@ -43,13 +42,7 @@ ALTER SUBSCRIPTION name RENAME TO < 中指定的订阅属性。 - - 要使用ALTER SUBSCRIPTION,你必须拥有该订阅。 - 要重命名订阅或更改其所有者,你必须在数据库上具有 - CREATE权限。此外,要更改所有者,你必须能够对新的拥有角色执行 - SET ROLE。如果该订阅具有 - password_required=false,则只有超级用户可以修改它。 - + 要使用ALTER SUBSCRIPTION,必须拥有该订阅。要更改所有者,还必须是新所有者角色的直接或间接成员。新所有者必须是超级用户。(目前,所有订阅所有者都必须是超级用户,因此实际上会绕过所有者检查。但将来可能会改变。) 刷新发布时,会移除不再属于该发布的关系;如果存在表同步槽,也会一并删除。 @@ -84,7 +77,7 @@ ALTER SUBSCRIPTION name RENAME TO < CONNECTION 'conninfo' - 该子句替换最初由设置的连接字符串。 + 该子句更改最初由设置的连接属性。 详情请参见该命令。 @@ -98,8 +91,7 @@ ALTER SUBSCRIPTION name RENAME TO < 这些形式会更改已订阅发布的列表。SET用新列表替换整个发布列表, ADD向发布列表中添加额外的发布,而DROP - 从发布列表中移除发布。在ADDSET变体中, - 允许指定不存在的发布,以便用户稍后再创建这些发布。详情请参见 + 从发布列表中移除发布。详情请参见 。默认情况下,此命令还会执行与 REFRESH PUBLICATION类似的操作。 @@ -131,7 +123,7 @@ ALTER SUBSCRIPTION name RENAME TO < 从发布者获取缺失的表信息。这将开始复制自 - CREATE SUBSCRIPTION + CREATE SUBSCRIPTION 或上次执行REFRESH PUBLICATION以来添加到已订阅发布中的表。 @@ -185,37 +177,7 @@ ALTER SUBSCRIPTION name RENAME TO < - - SKIP ( skip_option = value ) - - - 跳过应用远端事务的所有更改。如果传入数据违反任何约束,逻辑复制会停止,直到问题解决。 - 通过使用ALTER SUBSCRIPTION ... SKIP命令,逻辑复制工作进程会跳过 - 该事务中的所有数据修改操作。若订阅者上启用了 - two_phase,则此选项对因在订阅者上启用该参数而已经预备的事务没有作用。逻辑复制工作进程成功跳过该事务或完成一个事务后, - LSN(存储在pg_subscription.subskiplsn中) - 会被清除。有关逻辑复制冲突的详细信息,请参见 - 。 - - - skip_option指定此操作的选项。 - 支持的选项有: - - - - lsn (pg_lsn) - - - 指定逻辑复制工作进程要跳过其更改的远端事务的完成 LSN。完成 LSN 是该事务 - 提交或预备时所在的 LSN。不支持跳过单个子事务。设置 - NONE会重置该 LSN。 - - - - - - new_owner @@ -236,11 +198,7 @@ ALTER SUBSCRIPTION name RENAME TO < - - 当指定boolean类型的参数时,可以省略 - = value - 部分,这等价于指定TRUE。 - + diff --git a/zh/14/ref/alter_system.sgml b/zh/14/ref/alter_system.sgml index 22c645e6..da612e29 100644 --- a/zh/14/ref/alter_system.sgml +++ b/zh/14/ref/alter_system.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER SYSTEM 7 - SQL - Language Statements + SQL - 语言语句 @@ -52,12 +52,7 @@ ALTER SYSTEM RESET ALL SIGHUP信号来触发。 - - 只有超级用户以及在某个参数上被授予ALTER SYSTEM - 权限的用户,才能使用ALTER SYSTEM更改该参数。另 - 外,由于该命令直接作用于文件系统且不能回滚,因此不允许在事务块或函 - 数内部使用。 - + 只有超级用户可以使用ALTER SYSTEM。此外,由于此命令直接作用于文件系统且无法回滚,因此不允许在事务块或函数中使用。 @@ -85,8 +80,7 @@ ALTER SYSTEM RESET ALL - 对于某些接受列表的参数,带引号的值会生成带双引号的输出,以保留空 - 格和逗号;对于另一些参数,则必须在单引号字符串内部使用双引号才能 + 对于某些接受列表的参数,带引号的值会生成带双引号的输出,以保留空白和逗号;对于另一些参数,则必须在单引号字符串内部使用双引号才能 达到这种效果。 @@ -97,22 +91,13 @@ ALTER SYSTEM RESET ALL 注解 - - 不能用这个命令来设置、 - ,以及不允许出现在 - postgresql.conf中的参数(例如 - 预置选项)。 - + 此命令不能用于设置,也不能用于设置postgresql.conf中不允许的参数(例如预设选项)。 关于设置这些参数的其他方法,见 - - 可以通过把设置为 - off来禁用ALTER SYSTEM,但这 - 并不是一种安全机制(该参数的文档中对此有详细说明)。 - + diff --git a/zh/14/ref/alter_table.sgml b/zh/14/ref/alter_table.sgml index 4798657b..d00286a1 100644 --- a/zh/14/ref/alter_table.sgml +++ b/zh/14/ref/alter_table.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TABLE 7 - SQL - Language Statements + SQL - 语言语句 @@ -742,9 +742,7 @@ WITH ( MODULUS numeric_literal, REM 所有作用于单个表的ALTER TABLE形式,除RENAMESET SCHEMAATTACH PARTITIONDETACH PARTITION外,都可以组合成一个多项修改列表,一并执行。例如,可以在一条命令中添加多个列并且/或者修改多个列的类型。对于大型表,这一点尤其有用,因为这样只需对表执行一次遍历。 - - 要使用ALTER TABLE,你必须拥有该表。要更改表的模式或表空间,你还必须在新模式或新表空间上拥有CREATE权限。要把一个表作为父表的新子表加入,你还必须拥有该父表。此外,要把一个表附加为另一个表的新分区,你必须拥有被附加的表。要更改所有者,你必须能够对新的拥有角色执行SET ROLE,并且该角色必须在该表所在模式上具有CREATE权限。(这些限制确保更改所有者不会做出任何你不能通过删除并重建该表来完成的事情。不过,超级用户无论如何都可以更改任何表的所有权。)要添加列、修改列类型或使用OF子句,你还必须在相应数据类型上具有USAGE权限。 - + 要使用ALTER TABLE,必须拥有该表。要更改表的模式或表空间,还必须在新模式或表空间上拥有CREATE权限。要将表作为父表的新子表添加,还必须拥有父表。要将表作为表的新分区附加,还必须拥有要附加的表。要更改所有者,还必须是新所有者角色的直接或间接成员,并且该角色必须在表所在模式上拥有CREATE权限。(这些限制确保更改所有者不会执行任何无法通过删除并重新创建表完成的操作。不过,超级用户无论如何都可以更改任何表的所有权。)要添加列、更改列类型或使用OF子句,还必须在数据类型上拥有USAGE权限。 @@ -1011,7 +1009,7 @@ WITH ( MODULUS numeric_literal, REM - 若要强制立即回收已删除列所占的空间,可以执行任何一种会导致整表重写的ALTER TABLE形式。这样会重新构造每一行,并用空值替换被删除的列。 + 若要强制立即回收已删除列所占的空间,可以执行任何一种会导致整表重写的ALTER TABLE形式。这样会重建每一行,并用空值替换被删除的列。 diff --git a/zh/14/ref/alter_tablespace.sgml b/zh/14/ref/alter_tablespace.sgml index f0297481..8fd7b94c 100644 --- a/zh/14/ref/alter_tablespace.sgml +++ b/zh/14/ref/alter_tablespace.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TABLESPACE 7 - SQL - Language Statements + SQL - 语言语句 @@ -35,10 +35,7 @@ ALTER TABLESPACE name RESET ( name ON 描述 - - ALTER TRIGGER更改现有触发器的属性。 - - - - RENAME子句更改给定触发器的名称,而不改变该触发器定义的其他部分。 - 如果该触发器所在的表是分区表,则各分区中的对应克隆触发器也会一并重命名。 - - - - DEPENDS ON EXTENSION子句将触发器标记为依赖于某个扩展, - 这样在删除该扩展时,该触发器也会自动删除。 - + ALTER TRIGGER更改现有触发器的属性。RENAME子句更改给定触发器的名称,但不以其他方式更改触发器定义。DEPENDS ON EXTENSION子句将触发器标记为依赖扩展,因此扩展被删除时触发器也会自动删除。 若要更改触发器的属性,你必须拥有该触发器所作用的表。 @@ -127,7 +115,7 @@ ALTER TRIGGER emp_stamp ON emp DEPENDS ON EXTENSION emplib; - 另见 + 参见 diff --git a/zh/14/ref/alter_tsconfig.sgml b/zh/14/ref/alter_tsconfig.sgml index 7ae05dd5..891dce66 100644 --- a/zh/14/ref/alter_tsconfig.sgml +++ b/zh/14/ref/alter_tsconfig.sgml @@ -13,7 +13,7 @@ PostgreSQL documentation ALTER TEXT SEARCH CONFIGURATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/alter_tsdictionary.sgml b/zh/14/ref/alter_tsdictionary.sgml index 9679697e..163d788b 100644 --- a/zh/14/ref/alter_tsdictionary.sgml +++ b/zh/14/ref/alter_tsdictionary.sgml @@ -13,7 +13,7 @@ PostgreSQL documentation ALTER TEXT SEARCH DICTIONARY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/alter_tsparser.sgml b/zh/14/ref/alter_tsparser.sgml index 525064c9..0844cb0a 100644 --- a/zh/14/ref/alter_tsparser.sgml +++ b/zh/14/ref/alter_tsparser.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TEXT SEARCH PARSER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/alter_tstemplate.sgml b/zh/14/ref/alter_tstemplate.sgml index fa4157f9..a3eec599 100644 --- a/zh/14/ref/alter_tstemplate.sgml +++ b/zh/14/ref/alter_tstemplate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TEXT SEARCH TEMPLATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/alter_type.sgml b/zh/14/ref/alter_type.sgml index 58063799..6599b699 100644 --- a/zh/14/ref/alter_type.sgml +++ b/zh/14/ref/alter_type.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation ALTER TYPE 7 - SQL - Language Statements + SQL - 语言语句 @@ -229,16 +229,7 @@ ALTER TYPE name SET ( - - 要使用 ALTER TYPE,你必须拥有该类型。 - 要更改类型所在的模式,你还必须在新模式上拥有 CREATE 权限。 - 要更改拥有者,你必须能够对新的拥有角色执行 SET ROLE, - 并且该角色必须在该类型所在的模式上拥有 CREATE 权限。 - (这些限制确保,更改拥有者不会做出任何你不能通过删除并重新创建该类型来完成的事情。 - 不过,超级用户仍然可以更改任何类型的所有权。) - 要添加属性或更改属性的数据类型,你还必须对该属性的数据类型拥有 - USAGE 权限。 - + 要使用ALTER TYPE,必须拥有该类型。要更改类型的模式,还必须在新模式上拥有CREATE权限。要更改所有者,还必须是新所有者角色的直接或间接成员,并且该角色必须在类型所在模式上拥有CREATE权限。(这些限制确保更改所有者不会执行任何无法通过删除并重新创建类型完成的操作。不过,超级用户无论如何都可以更改任何类型的所有权。)要添加属性或更改属性类型,还必须在该属性的数据类型上拥有USAGE权限。 diff --git a/zh/14/ref/alter_user.sgml b/zh/14/ref/alter_user.sgml index 362b5518..5a4f5dd4 100644 --- a/zh/14/ref/alter_user.sgml +++ b/zh/14/ref/alter_user.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER USER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/alter_user_mapping.sgml b/zh/14/ref/alter_user_mapping.sgml index 6bbeffc6..b1fc6606 100644 --- a/zh/14/ref/alter_user_mapping.sgml +++ b/zh/14/ref/alter_user_mapping.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER USER MAPPING 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/alter_view.sgml b/zh/14/ref/alter_view.sgml index 020f864b..a67abd6f 100644 --- a/zh/14/ref/alter_view.sgml +++ b/zh/14/ref/alter_view.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER VIEW 7 - SQL - Language Statements + SQL - 语言语句 @@ -41,15 +41,7 @@ ALTER VIEW [ IF EXISTS ] name RESET CREATE OR REPLACE VIEW。) - - 要使用 ALTER VIEW,你必须是该视图的拥有者。 - 要更改视图的模式,你还必须拥有新模式上的 CREATE - 权限。要更改拥有者,你必须能够对新的拥有角色执行 - SET ROLE,并且该角色必须拥有该视图所在模式上的 - CREATE 权限。(这些限制确保,更改拥有者不会做出任何 - 你不能通过删除并重新创建该视图来完成的事情。不过,超级用户无论如何都可以 - 更改任何视图的所有权。) - + 要使用ALTER VIEW,必须拥有该视图。要更改视图的模式,还必须在新模式上拥有CREATE权限。要更改所有者,还必须是新所有者角色的直接或间接成员,并且该角色必须在视图所在模式上拥有CREATE权限。(这些限制确保更改所有者不会执行任何无法通过删除并重新创建视图完成的操作。不过,超级用户无论如何都可以更改任何视图的所有权。) diff --git a/zh/14/ref/analyze.sgml b/zh/14/ref/analyze.sgml index 89f9e1a6..abadbb25 100644 --- a/zh/14/ref/analyze.sgml +++ b/zh/14/ref/analyze.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ANALYZE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/begin.sgml b/zh/14/ref/begin.sgml index 2343e66c..fc8fb312 100644 --- a/zh/14/ref/begin.sgml +++ b/zh/14/ref/begin.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation BEGIN 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/call.sgml b/zh/14/ref/call.sgml index 4a12245b..7dca6405 100644 --- a/zh/14/ref/call.sgml +++ b/zh/14/ref/call.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CALL 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/checkpoint.sgml b/zh/14/ref/checkpoint.sgml index e9d12c3a..53544983 100644 --- a/zh/14/ref/checkpoint.sgml +++ b/zh/14/ref/checkpoint.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CHECKPOINT 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/close.sgml b/zh/14/ref/close.sgml index 53c793c4..788e2c9a 100644 --- a/zh/14/ref/close.sgml +++ b/zh/14/ref/close.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation CLOSE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/cluster.sgml b/zh/14/ref/cluster.sgml index f22017f1..fb0c44b0 100644 --- a/zh/14/ref/cluster.sgml +++ b/zh/14/ref/cluster.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CLUSTER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/clusterdb.sgml b/zh/14/ref/clusterdb.sgml index fd83c9ba..ada12058 100644 --- a/zh/14/ref/clusterdb.sgml +++ b/zh/14/ref/clusterdb.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation clusterdb 1 - Application + 应用程序 diff --git a/zh/14/ref/comment.sgml b/zh/14/ref/comment.sgml index baa2f239..5148556c 100644 --- a/zh/14/ref/comment.sgml +++ b/zh/14/ref/comment.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation COMMENT 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/commit.sgml b/zh/14/ref/commit.sgml index 046c6d84..596d1550 100644 --- a/zh/14/ref/commit.sgml +++ b/zh/14/ref/commit.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation COMMIT 7 - SQL - Language Statements + SQL - 语言语句 @@ -39,7 +39,7 @@ COMMIT [ WORK | TRANSACTION ] [ AND [ NO ] CHAIN ] 参数 - chained transactions + 链式事务 diff --git a/zh/14/ref/commit_prepared.sgml b/zh/14/ref/commit_prepared.sgml index dcdba873..734b2833 100644 --- a/zh/14/ref/commit_prepared.sgml +++ b/zh/14/ref/commit_prepared.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation COMMIT PREPARED 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/copy.sgml b/zh/14/ref/copy.sgml index 2f4465e2..537cfe5a 100644 --- a/zh/14/ref/copy.sgml +++ b/zh/14/ref/copy.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation COPY 7 - SQL - Language Statements + SQL - 语言语句 @@ -496,15 +496,10 @@ COPY count 注解 - - COPY TO可用于普通表和已填充的物化视图。例如, - COPY table TO - 复制的行与 - SELECT * FROM ONLY table - 相同。但它不直接支持其他关系类型,如分区表、继承子表或视图。 - 要复制这类关系的全部行,请使用 - COPY (SELECT * FROM table) TO。 - + COPY TO 只能用于普通表,不能用于视图,且不会复制子表或子分区中的行。例如,COPY table TO 复制的行与 SELECT * FROM ONLY table 相同。语法 COPY (SELECT * FROM table) TO ... 可用于导出继承层次结构、分区表或视图中的所有行。 COPY FROM可用于普通表、外部表、分区表,以及具有 diff --git a/zh/14/ref/create_access_method.sgml b/zh/14/ref/create_access_method.sgml index d4cb6d2c..7f2d9d8e 100644 --- a/zh/14/ref/create_access_method.sgml +++ b/zh/14/ref/create_access_method.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE ACCESS METHOD 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/create_aggregate.sgml b/zh/14/ref/create_aggregate.sgml index 3b890824..252f9fab 100644 --- a/zh/14/ref/create_aggregate.sgml +++ b/zh/14/ref/create_aggregate.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation CREATE AGGREGATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/create_cast.sgml b/zh/14/ref/create_cast.sgml index 1e2c9275..94e78f9e 100644 --- a/zh/14/ref/create_cast.sgml +++ b/zh/14/ref/create_cast.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation CREATE CAST 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/create_collation.sgml b/zh/14/ref/create_collation.sgml index 6bb3f7ab..a232fef9 100644 --- a/zh/14/ref/create_collation.sgml +++ b/zh/14/ref/create_collation.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE COLLATION 7 - SQL - Language Statements + SQL - 语言语句 @@ -27,7 +27,6 @@ CREATE COLLATION [ IF NOT EXISTS ] name ( [ LC_CTYPE = lc_ctype, ] [ PROVIDER = provider, ] [ DETERMINISTIC = boolean, ] - [ RULES = rules, ] [ VERSION = version ] ) CREATE COLLATION [ IF NOT EXISTS ] name FROM existing_collation @@ -81,24 +80,7 @@ CREATE COLLATION [ IF NOT EXISTS ] name FROM locale - - 该排序规则的区域设置名称。详见。 - - - 如果providerlibc, - 这相当于同时设置LC_COLLATE和 - LC_CTYPE。如果指定了 - locale,则不能再指定这两个参数中的任何 - 一个。 - - - 如果providerbuiltin, - 则必须指定locale,且其值只能是 - CC.UTF-8或 - PG_UNICODE_FAST。 - + 这是同时设置 LC_COLLATELC_CTYPE 的快捷方式。如果指定了此选项,则不能指定这两个参数中的任何一个。 @@ -106,11 +88,7 @@ CREATE COLLATION [ IF NOT EXISTS ] name FROM lc_collate - - 如果providerlibc, - 则对LC_COLLATE区域类别使用指定的操作系统区域设 - 置。 - + LC_COLLATE 区域类别使用指定的操作系统区域设置。 @@ -118,10 +96,7 @@ CREATE COLLATION [ IF NOT EXISTS ] name FROM lc_ctype - - 如果providerlibc, - 则对LC_CTYPE区域类别使用指定的操作系统区域设置。 - + LC_CTYPE 区域类别使用指定的操作系统区域设置。 @@ -129,14 +104,7 @@ CREATE COLLATION [ IF NOT EXISTS ] name FROM provider - - 指定与该排序规则关联的区域设置服务所使用的提供者。可能的值是 - builtin、 - icuICU - (如果服务器在构建时启用了 ICU 支持)或libc。 - 默认值是libc。详见。 - + 指定用于与此排序规则关联的区域设置服务的提供程序。可能的值为: icuICU libclibc 是默认值。可用选项取决于操作系统和构建选项。 @@ -154,22 +122,12 @@ CREATE COLLATION [ IF NOT EXISTS ] name FROM - 非确定性排序规则仅受 ICU 提供者支持。 + 非确定性排序规则仅受 ICU 提供程序支持。 - - rules - - - 指定额外的定制规则,以自定义该排序规则的行为。这仅受 ICU 支持。 - 详见 - 。 - - - version @@ -238,20 +196,13 @@ CREATE COLLATION french (locale = 'fr_FR.utf8'); - 使用 ICU 提供者并采用德语电话簿排序顺序创建一种排序规则: + 使用 ICU 提供程序并采用德语电话簿排序顺序创建一种排序规则: CREATE COLLATION german_phonebook (provider = icu, locale = 'de-u-co-phonebk'); - - 使用 ICU 提供者、基于 ICU 根区域设置并带有自定义规则创建一种排序规 - 则: - - - - 关于规则语法的更多细节和示例,见。 - + 通过复制现有排序规则来创建一种排序规则: diff --git a/zh/14/ref/create_conversion.sgml b/zh/14/ref/create_conversion.sgml index da83218a..3fcb4447 100644 --- a/zh/14/ref/create_conversion.sgml +++ b/zh/14/ref/create_conversion.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE CONVERSION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/create_database.sgml b/zh/14/ref/create_database.sgml index 0aaa9268..526b8821 100644 --- a/zh/14/ref/create_database.sgml +++ b/zh/14/ref/create_database.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE DATABASE 7 - SQL - Language Statements + SQL - 语言语句 @@ -25,20 +25,13 @@ CREATE DATABASE name [ WITH ] [ OWNER [=] user_name ] [ TEMPLATE [=] template ] [ ENCODING [=] encoding ] - [ STRATEGY [=] strategy ] [ LOCALE [=] locale ] [ LC_COLLATE [=] lc_collate ] [ LC_CTYPE [=] lc_ctype ] - [ BUILTIN_LOCALE [=] builtin_locale ] - [ ICU_LOCALE [=] icu_locale ] - [ ICU_RULES [=] icu_rules ] - [ LOCALE_PROVIDER [=] locale_provider ] - [ COLLATION_VERSION = collation_version ] [ TABLESPACE [=] tablespace_name ] [ ALLOW_CONNECTIONS [=] allowconn ] [ CONNECTION LIMIT [=] connlimit ] [ IS_TEMPLATE [=] istemplate ] - [ OID [=] oid ] @@ -80,11 +73,7 @@ CREATE DATABASE name user_name - - 将成为新数据库拥有者的用户角色名,或者指定 DEFAULT - 以使用默认值(即执行该命令的用户)。要创建由其他角色拥有的数据库, - 你必须能够对该角色执行 SET ROLE。 - + 新数据库所有者的角色名称,或使用 DEFAULT 以使用默认值(即执行命令的用户)。要创建由其他角色拥有的数据库,你必须是该角色的直接或间接成员,或为超级用户。 @@ -108,43 +97,11 @@ CREATE DATABASE name - - strategy - - - 创建新数据库时使用的策略。如果使用 WAL_LOG - 策略,数据库将按块复制,并且每个块都会分别写入预写式日志。当模板数据库较小时,这是最高效的策略,因此也是默认策略。较早的 - FILE_COPY 策略也可用。该策略会为目标数据库使用的每个表空间向预写式日志写入一条较小的记录,每条记录都表示在文件系统层面把整个目录复制到一个新位置。虽然这样能大幅减少预写式日志量,特别是在模板数据库很大时更是如此,但它也会迫使系统在创建新数据库之前和之后各执行一次检查点。在某些情况下,这可能会对整体系统性能产生明显的负面影响。 - FILE_COPY 策略受 设置影响。 - - - + locale - - 设置新数据库中的默认排序规则和字符分类。排序规则会影响应用于字符串的排序顺序, - 例如带有 ORDER BY 的查询,以及文本列索引中使用的顺序。字符分类会影响字符的类别划分,例如小写、大写和数字。它还会设置操作系统环境中相应的 - LC_COLLATELC_CTYPE。 - 默认值与模板数据库中的设置相同。详见 - 和 - 。 - - - 也可以通过分别设置 、 - 、 - 或 - 来覆盖它。 - - - 如果 是 - builtin,则必须指定 - locale 或 - builtin_locale,并将其设为 - CC.UTF-8 或 - PG_UNICODE_FAST之一。 - + 这是同时设置 LC_COLLATELC_CTYPE 的快捷方式。如果使用此选项,则不能指定其中任一参数。 其他区域设置参数 、 @@ -159,106 +116,25 @@ CREATE DATABASE name lc_collate - - 在数据库服务器的操作系统环境中设置 LC_COLLATE。 - 默认值为 的设置(如果已指定), - 否则与模板数据库中的设置相同。其他限制见下文。 - - - 如果 是 - libc,它还会设置新数据库中使用的默认排序规则, - 从而覆盖 的设置。 - + 新数据库中使用的排序规则(LC_COLLATE)。这会影响字符串的排序顺序,例如在带有 ORDER BY 的查询中,以及文本列索引中使用的顺序。默认值是使用模板数据库的排序规则。请参见下文的其他限制。 lc_ctype - - 在数据库服务器的操作系统环境中设置 LC_CTYPE。 - 默认值为 的设置(如果已指定), - 否则与模板数据库中的设置相同。其他限制见下文。 - - - 如果 是 - libc,它还会设置新数据库中使用的默认字符分类, - 从而覆盖 的设置。 - + 新数据库中使用的字符分类(LC_CTYPE)。这会影响字符的分类,例如小写、大写和数字。默认值是使用模板数据库的字符分类。请参见下文的其他限制。 - - builtin_locale - - - 指定用于数据库默认排序规则和字符分类的 builtin 提供程序区域设置, - 从而覆盖 的设置。 - 区域设置提供程序 - 必须是 builtin。默认值为 - 的设置(如果已指定),否则与模板数据库中的设置相同。 - - - builtin 提供程序可用的区域设置有 - CC.UTF-8 和 - PG_UNICODE_FAST。 - - - - - icu_locale - - - 指定 ICU 区域设置(见 ), - 用于数据库默认排序规则和字符分类,从而覆盖 - 的设置。 - 区域设置提供程序 - 必须是 ICU。默认值为 的设置 - (如果已指定),否则与模板数据库中的设置相同。 - - - - - icu_rules - - - 指定附加的排序规则,用以定制该数据库默认排序规则的行为。该选项仅支持 - ICU。详见 。 - - - - - locale_provider - - - 指定该数据库默认排序规则使用的提供程序。可能的值为 builtin、 - icuICU - (如果服务器构建时启用了 ICU 支持)或 libc。 - 默认情况下,该值与 - 的区域设置提供程序相同。详见 - 。 - - - - - collation_version - - - 指定要与数据库一起存储的排序规则版本字符串。通常应省略此选项, - 这样系统会根据操作系统提供的数据库排序规则实际版本来计算该版本。 - 此选项主要供 pg_upgrade 使用,以便从现有安装中复制该版本。 - - - 另见 ,了解如何处理数据库排序规则版本不匹配。 - - - + + tablespace_name @@ -299,17 +175,7 @@ CREATE DATABASE name - - oid - - - 要用于新数据库的对象标识符。如果未指定此参数, - PostgreSQL 将自动选择一个合适的 OID。 - 此参数主要供 pg_upgrade 内部使用,且只有 - pg_upgrade 才能指定小于 16384 的值。 - - - + @@ -359,7 +225,7 @@ CREATE DATABASE nameLC_CTYPE)兼容。如果区域设置为 C (或等价的 POSIX),则允许所有编码;但对于其他区域设置,只有一种编码能够正常工作。(不过,在 Windows 上,UTF-8 编码可与任何区域设置一起使用。) CREATE DATABASE 允许超级用户不考虑区域设置而指定 - SQL_ASCII 编码,但这种选择已被废弃;如果数据库中存储了与该区域设置不兼容编码的数据,字符串函数的行为可能会出错。 + SQL_ASCII 编码,但这种选择已弃用;如果数据库中存储了与该区域设置不兼容编码的数据,字符串函数的行为可能会出错。 @@ -369,11 +235,7 @@ CREATE DATABASE name template0 不包含任何会受此影响的数据或索引。 - - 目前还没有选项可以让数据库区域设置使用非确定性比较(解释见 - CREATE - COLLATION)。如果需要这样做,则必须使用逐列排序规则。 - + CONNECTION LIMIT 选项只是近似地被强制执行;如果两个新会话几乎同时启动,而该数据库只剩下一个连接,则两者都可能失败。此外,该限制对超级用户或后台工作进程无效。 @@ -409,7 +271,7 @@ CREATE DATABASE music TEMPLATE template0; 在这个示例中,如果指定的区域设置与 template1 中的不同, - 则必须使用 TEMPLATE template0 子句。(如果并不不同, + 则必须使用 TEMPLATE template0 子句。(如果相同, 那么显式指定区域设置就是多余的。) diff --git a/zh/14/ref/create_domain.sgml b/zh/14/ref/create_domain.sgml index 905dd30d..420bbf83 100644 --- a/zh/14/ref/create_domain.sgml +++ b/zh/14/ref/create_domain.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE DOMAIN 7 - SQL - Language Statements + SQL - 语言语句 @@ -86,7 +86,7 @@ CREATE DOMAIN name [ AS ] 该域的可选排序规则。如果未指定排序规则,则该域的排序规则行为与其 底层数据类型相同。如果指定了COLLATE,则底层 - 类型必须是一种可排序数据类型。 + 类型必须是一种支持排序规则的数据类型。 diff --git a/zh/14/ref/create_event_trigger.sgml b/zh/14/ref/create_event_trigger.sgml index 0d45c2be..d1bcd047 100644 --- a/zh/14/ref/create_event_trigger.sgml +++ b/zh/14/ref/create_event_trigger.sgml @@ -13,7 +13,7 @@ PostgreSQL documentation CREATE EVENT TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -44,7 +44,7 @@ CREATE EVENT TRIGGER name CREATE EVENT TRIGGER创建一个新的事件触发器。 每当指定的事件发生,并且与该触发器关联的WHEN条件(如果有)得到 满足时,就会执行该触发器函数。有关事件触发器的一般性介绍,见 - 。创建事件触发器的用户将成为其拥有者。 + 。创建事件触发器的用户将成为其所有者。 @@ -83,8 +83,7 @@ CREATE EVENT TRIGGER name - 用于过滤事件的变量名称。这使得可以将触发器限定为只在支持该变量的部 - 分情形下触发。当前唯一支持的 + 用于过滤事件的变量名称。这样可以将触发器限定为只在原本支持的部分情形下触发。当前唯一支持的 filter_variableTAG @@ -142,14 +141,7 @@ CREATE EVENT TRIGGER name - - 在单用户模式(见)下,以及当 - 被设置为false时, - 事件触发器都会被禁用。如果某个错误的事件触发器使数据库严重不可用, - 甚至无法删除该触发器,可以在将 - 设置为false的情况下重启,以临时禁用事件触发器, - 或者以单用户模式重启,这样就可以删除它。 - + 事件触发器在单用户模式下被禁用(参见 )。如果错误的事件触发器导致数据库严重失效,以至于无法删除触发器,可以重启到单用户模式,然后就能执行删除操作。 @@ -194,7 +186,7 @@ CREATE EVENT TRIGGER abort_ddl ON ddl_command_start - 另见 + 参见 diff --git a/zh/14/ref/create_extension.sgml b/zh/14/ref/create_extension.sgml index 1503df25..7acc3a5e 100644 --- a/zh/14/ref/create_extension.sgml +++ b/zh/14/ref/create_extension.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE EXTENSION 7 - SQL - Language Statements + SQL - 语言语句 @@ -82,10 +82,9 @@ CREATE EXTENSION [ IF NOT EXISTS ] extension_name 要安装的扩展名称。PostgreSQL将根据 - 文件 extension_name.control - 中的详细信息创建该扩展;该文件通过服务器的扩展控制路径找到 - (由 设置)。 + SHAREDIR/extension/extension_name.control + 文件中的详细信息创建该扩展。 @@ -167,7 +166,7 @@ CREATE EXTENSION [ IF NOT EXISTS ] extension_name 会在之后执行编写粗心的扩展脚本时实施攻击,使该用户获得超级用户权限。 不过,只有当特洛伊木马对象在脚本执行期间位于 search_path 中时,它们才会构成危险;这意味着它们 - 位于扩展的安装目标模式中,或位于它所依赖的某个扩展所属的模式中。 + 位于扩展的安装目标模式中,或位于它所依赖的某个扩展的目标模式中。 因此,处理那些脚本尚未经过仔细审查的扩展时,一个经验法则是: 只把它们安装到从未向任何不受信任用户授予、而且今后也不会授予 CREATE 权限的模式中。它们所依赖的任何扩展也应如此。 diff --git a/zh/14/ref/create_foreign_data_wrapper.sgml b/zh/14/ref/create_foreign_data_wrapper.sgml index bfa097ef..0611709d 100644 --- a/zh/14/ref/create_foreign_data_wrapper.sgml +++ b/zh/14/ref/create_foreign_data_wrapper.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE FOREIGN DATA WRAPPER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/create_foreign_table.sgml b/zh/14/ref/create_foreign_table.sgml index 787d3748..5e7768bf 100644 --- a/zh/14/ref/create_foreign_table.sgml +++ b/zh/14/ref/create_foreign_table.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE FOREIGN TABLE 7 - SQL - Language Statements + SQL - 语言语句 @@ -143,9 +143,7 @@ WITH ( MODULUS numeric_literal, REM COLLATE collation - - COLLATE子句为该列(必须是一种可排序数据类型)指定一个排序规则。如果未指定,则使用该列数据类型的默认排序规则。 - + COLLATE子句为列指定排序规则(该列必须属于支持排序规则的数据类型)。如果未指定,则使用列数据类型的默认排序规则。 diff --git a/zh/14/ref/create_function.sgml b/zh/14/ref/create_function.sgml index b6447707..5b894c32 100644 --- a/zh/14/ref/create_function.sgml +++ b/zh/14/ref/create_function.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation CREATE FUNCTION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/create_group.sgml b/zh/14/ref/create_group.sgml index 06195a91..9a6538ed 100644 --- a/zh/14/ref/create_group.sgml +++ b/zh/14/ref/create_group.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE GROUP 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/create_index.sgml b/zh/14/ref/create_index.sgml index 1c525288..456ee728 100644 --- a/zh/14/ref/create_index.sgml +++ b/zh/14/ref/create_index.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation CREATE INDEX 7 - SQL - Language Statements + SQL - 语言语句 @@ -26,7 +26,6 @@ PostgreSQL documentation CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] name ] ON [ ONLY ] table_name [ USING method ] ( { column_name | ( expression ) } [ COLLATE collation ] [ opclass [ ( opclass_parameter = value [, ... ] ) ] ] [ ASC | DESC ] [ NULLS { FIRST | LAST } ] [, ...] ) [ INCLUDE ( column_name [, ...] ) ] - [ NULLS [ NOT ] DISTINCT ] [ WITH ( storage_parameter [= value] [, ... ] ) ] [ TABLESPACE tablespace_name ] [ WHERE predicate ] @@ -57,7 +56,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] PostgreSQL提供了索引方法 - B-树、哈希、GiST、SP-GiST、GIN 以及 BRIN。用户也可以定义自己的索引 + B-树、hash、GiST、SP-GiST、GIN 以及 BRIN。用户也可以定义自己的索引 方法,但这相当复杂。 @@ -123,7 +122,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] 对于临时表,CREATE INDEX始终是非并发的, - 因为没有其他会话可以访问它们,而且非并发创建索引的成本更低。 + 因为没有其他会话可以访问它们,而且非并发创建索引的代价更低。 @@ -180,12 +179,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] name - - - 要创建的索引的名称。这里不能包含模式名称;索引总是在其父表所在的模式中创建。 - 索引的名称必须与该模式中的任何其他关系(表、序列、索引、视图、物化视图或外部表)的名称不同。 - 如果省略名称,PostgreSQL会根据父表的名称和索引列的名称选择一个合适的名称。 - + 要创建的索引名称。此处不能包含模式名称;索引始终创建在其父表所在的同一模式中。如果省略名称,PostgreSQL会根据父表名称和被索引的列名选择合适的名称。 @@ -319,18 +313,6 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - - NULLS DISTINCT - NULLS NOT DISTINCT - - - - 指定对于唯一索引,是否应将空值视为不同(而非相等)。默认情况下,它们是不同的, - 因此唯一索引可以在列中包含多个空值。 - - - - storage_parameter @@ -373,10 +355,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] 可选的WITH子句为索引指定存储参数。每一种 索引方法都有其各自允许的存储参数集合。 - - - - B-树、哈希、GiST 和 SP-GiST 索引方法都接受以下参数: + B-树、hash、GiST 和 SP-GiST 索引方法都接受以下参数: @@ -390,7 +369,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - 控制索引方法尝试将索引页填充到多满。对于 B-树,在初始构建索引时, + 索引的填充因子是一个百分比,用于确定索引方法尝试将索引页填充到多满。对于 B-树,在初始构建索引时, 以及在右侧扩展索引(加入新的最大键值)时,叶子页都会填充到这一 百分比。如果页面随后变成全满,就会发生分裂,从而导致磁盘上的 索引结构碎片化。B-树默认使用 90 的填充因子,但也可以选择 10 到 @@ -471,7 +450,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - 控制是否使用中描述的缓冲构建技术 + 确定是否使用中描述的缓冲构建技术 来构建索引。设置为OFF时禁用缓冲构建,设置为 ON时启用,设置为AUTO时初始为 禁用,但一旦索引大小达到, @@ -484,7 +463,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - GIN 索引接受以下参数: + GIN 索引接受不同的参数: @@ -498,8 +477,8 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - 控制中描述的快速更新技术的使用。 - ON 启用快速更新,OFF 禁用快速更新。 + 此设置控制中描述的快速更新技术的使用。 + 这是一个布尔参数:ON 启用快速更新,OFF 禁用快速更新。 默认值为ON @@ -528,7 +507,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - 为该索引覆盖的全局设置。 + 自定义参数。 该值以千字节为单位。 @@ -536,7 +515,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - BRIN 索引接受以下参数: + BRIN 索引接受不同的参数: @@ -566,7 +545,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - 定义当在下一页范围检测到插入时,是否为前一页范围排队执行一次提要操作 + 定义当在下一页范围检测到插入时,是否为前一页范围排队执行一次范围摘要操作 (详见)。 默认值为off @@ -580,8 +559,8 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] 并发构建索引 - index - building concurrently + 索引 + 并发构建 @@ -733,11 +712,6 @@ Indexes: 生成这些索引的统计信息。 - - 在 CREATE INDEX 执行期间, - 会被临时设置为 pg_catalog, pg_temp。 - - 对于大多数索引方法,索引的创建速度取决于 的设置。较大的值将会减少 @@ -748,7 +722,7 @@ Indexes: PostgreSQL可以在构建索引时利用多个 CPU, 以便更快处理表中的行。这项特性被称为并行索引构建。 - 对于支持并行构建索引的索引方法(当前为 B-树、GIN 和 BRIN), + 对于支持并行构建索引的索引方法(当前只有 B-树), maintenance_work_mem指定每次索引构建操作整体最多 可使用的内存量,而不管启动了多少工作者进程。通常,代价模型会自动决 定是否需要请求工作者进程,以及请求多少个。 diff --git a/zh/14/ref/create_language.sgml b/zh/14/ref/create_language.sgml index fca9e159..5d737764 100644 --- a/zh/14/ref/create_language.sgml +++ b/zh/14/ref/create_language.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE LANGUAGE 7 - SQL - Language Statements + SQL - 语言语句 @@ -96,7 +96,7 @@ CREATE [ OR REPLACE ] [ TRUSTED ] [ PROCEDURAL ] LANGUAGE name [ DEFAUL 会妨碍优化器识别该查询匹配一个索引。 + + 在PostgreSQL 8.4 之前,OPERATOR子句可以包含RECHECK选项。现在不再支持该选项,因为索引操作符是否有损会在运行时动态确定。这样可以高效处理操作符可能有损也可能无损的情况。 + diff --git a/zh/14/ref/create_operator.sgml b/zh/14/ref/create_operator.sgml index faae3140..9ea345ed 100644 --- a/zh/14/ref/create_operator.sgml +++ b/zh/14/ref/create_operator.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE OPERATOR 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/create_opfamily.sgml b/zh/14/ref/create_opfamily.sgml index 1577f0c1..9d31bb01 100644 --- a/zh/14/ref/create_opfamily.sgml +++ b/zh/14/ref/create_opfamily.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE OPERATOR FAMILY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/create_policy.sgml b/zh/14/ref/create_policy.sgml index 9a5fc65e..da8a5754 100644 --- a/zh/14/ref/create_policy.sgml +++ b/zh/14/ref/create_policy.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE POLICY 7 - SQL - Language Statements + SQL - 语言语句 @@ -53,8 +53,7 @@ CREATE POLICY name ON - 对于INSERTUPDATE和 - MERGE语句, + 对于INSERTUPDATE语句, WITH CHECK表达式会在BEFORE 触发器触发后、在进行任何实际数据修改之前强制执行。因此, BEFORE ROW触发器可以修改待插入的数据,从而影响 @@ -236,8 +235,8 @@ CREATE POLICY name ON SELECT查询,以及在其定义所在关系上需要 SELECT权限的任何场景。结果是,只有通过 SELECT策略的那些行才会在 - SELECT查询中返回,而像UPDATE、 - DELETEMERGE这类需要 + SELECT查询中返回,而像UPDATE和 + DELETE这类需要 SELECT权限的查询,也只能看到 SELECT策略允许的那些行。 SELECT策略不能带有 @@ -263,14 +262,6 @@ CREATE POLICY name ON SELECT策略进行检查;如果不满足,同样会报错 (辅助的UPDATE绝不会被静默跳过)。 - - MERGE命令要求在源关系和目标关系上都具有 - SELECT权限,因此每个关系的SELECT策略 - 都会在连接它们之前被应用,而MERGE动作也只能看到这些策略允许的行。 - 另外,如果执行了UPDATE动作,则目标关系的 - SELECT策略会像独立的UPDATE那样应用到更新后的行; - 不满足时会报错。 - @@ -279,8 +270,7 @@ CREATE POLICY name ON 对策略使用INSERT,意味着它将适用于 - INSERT命令,以及包含INSERT动作的 - MERGE命令。插入的行如果未通过该策略, + INSERT命令。插入的行如果未通过该策略, 将导致策略违规错误,并且整个INSERT命令将被 中止。INSERT策略不能带有 USING表达式,因为它只适用于向关系添加行 @@ -302,8 +292,7 @@ CREATE POLICY name ON UPDATE,意味着它将适用于 UPDATESELECT FOR UPDATESELECT FOR SHARE命令,以及INSERT命令中 - 辅助的ON CONFLICT DO UPDATE子句,还适用于包含 - UPDATE动作的MERGE命令。 + 辅助的ON CONFLICT DO UPDATE子句。 由于UPDATE命令需要取出现有行并用修改后的 新行替换它,因此UPDATE策略同时接受 USING表达式和 @@ -344,7 +333,6 @@ CREATE POLICY name ON UPDATE命令不同,如果现有行没有通过 USING表达式检查,就会报错 (UPDATE路径绝不会被静默跳过)。 - 对MERGE命令中的UPDATE动作也是如此。 @@ -354,14 +342,10 @@ CREATE POLICY name ON 对策略使用DELETE,意味着它将适用于 - DELETE命令,以及包含DELETE动作的 - MERGE命令。对于DELETE命令,只有通过 + DELETE命令。只有通过 该策略的行才会被DELETE命令看到。 可能存在一些通过SELECT策略可见,但由于未通过 DELETE策略的USING表达式而不能删除的行。 - 但请注意,在MERGE命令中的DELETE动作会看到 - 通过SELECT策略可见的行;如果某一行未通过 - DELETE策略,就会报错。 @@ -505,40 +489,6 @@ CREATE POLICY name ON - - MERGE - 筛选源行和目标行 - - - - - - - MERGE ... THEN INSERT - - 检查新行  - - 检查新行 - - - - - - MERGE ... THEN UPDATE - 检查新行 - - 检查现有行 - 检查新行 - - - - MERGE ... THEN DELETE - - - - - 检查现有行 - @@ -650,13 +600,6 @@ AND CREATE VIEW)。 - - 对于MERGE,不存在单独的策略。相反,执行 - MERGE时会根据实际执行的动作,应用为 - SELECTINSERT、 - UPDATEDELETE定义的策略。 - - 更多讨论和实际示例见 diff --git a/zh/14/ref/create_procedure.sgml b/zh/14/ref/create_procedure.sgml index eaa88de6..fe20673f 100644 --- a/zh/14/ref/create_procedure.sgml +++ b/zh/14/ref/create_procedure.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation CREATE PROCEDURE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/create_publication.sgml b/zh/14/ref/create_publication.sgml index a8903bfa..0987f56f 100644 --- a/zh/14/ref/create_publication.sgml +++ b/zh/14/ref/create_publication.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE PUBLICATION 7 - SQL - Language Statements + SQL - 语言语句 @@ -22,18 +22,9 @@ PostgreSQL documentation CREATE PUBLICATION name - [ FOR ALL TABLES - | FOR publication_object [, ... ] ] + [ FOR TABLE [ ONLY ] table_name [ * ] [, ...] + | FOR ALL TABLES ] [ WITH ( publication_parameter [= value] [, ... ] ) ] - -其中publication_object可以是: - - TABLE table_and_columns [, ... ] - TABLES IN SCHEMA { schema_name | CURRENT_SCHEMA } [, ... ] - -其中table_and_columns为: - - [ ONLY ] table_name [ * ] [ ( column_name [, ... ] ) ] [ WHERE ( expression ) ] @@ -68,43 +59,11 @@ CREATE PUBLICATION name FOR TABLE - - 指定要加入该发布的表列表。如果在表名前指定了ONLY, - 则只有该表会被加入发布。如果未指定ONLY, - 则该表及其所有后代表(如果有)都会被加入。也可以在表名后指定 - *,以显式表明包含后代表。不过,这不适用于分区表。 - 分区表的各个分区始终会被隐式视为发布的一部分,因此永远不会被显式加入发布。 - + 指定要添加到发布中的表列表。如果在表名之前指定ONLY,则仅将该表添加到发布中。如果未指定ONLY,则将该表及其所有后代表(如果有)添加到发布中。也可以在表名后指定*,以明确表示包含后代表。不过,这不适用于分区表。分区表的分区始终会被隐式视为发布的一部分,因此不会将它们显式添加到发布中。 - - 如果指定了可选的WHERE子句,它会定义一个 - 行过滤器表达式。对于 - expression求值为 - falseNULL的行,不会被发布。 - 注意,表达式外必须加括号。它对TRUNCATE命令没有影响。 - - - - 指定列列表时,只复制其中列出的列。列列表也可以包含存储生成列。 - 如果省略列列表,则该发布默认复制所有非生成列(包括今后新增的列)。 - 如果将publish_generated_columns设为 - stored,也可以复制存储生成列。指定列列表对 - TRUNCATE命令没有影响。 - + 只有持久基表和分区表可以成为发布的一部分。临时表、不记录 WAL 的表、外部表、物化视图和普通视图不能成为发布的一部分。 - - 只有持久基表和分区表才能成为发布的一部分。临时表、不记录 WAL 的表、 - 外部表、物化视图和常规视图都不能成为发布的一部分。 - - - - 如果该发布还包含FOR TABLES IN SCHEMA,则不支持指定列列表。 - - - - 将分区表加入发布时,其所有现有分区和未来分区都会被隐式视为发布的一部分。 - 因此,即使直接在某个分区上执行的操作,也会通过其祖先表所在的发布进行发布。 - + 将分区表添加到发布时,其所有现有分区和未来分区都会被隐式视为发布的一部分。因此,直接在分区上执行的操作也会通过其祖先表所属的发布进行发布。 @@ -117,29 +76,7 @@ CREATE PUBLICATION name - - FOR TABLES IN SCHEMA - - - 将该发布标记为复制指定模式列表中所有表的更改,包括未来创建的表。 - - - 如果该发布还发布带有列列表的表,则不支持指定模式。 - - - - 只有该模式中的持久基表和分区表会被纳入发布。该模式中的临时表、 - 不记录 WAL 的表、外部表、物化视图和常规视图都不会成为发布的一部分。 - - - - 当通过模式级发布来发布分区表时,其所有现有分区和未来分区都会被隐式视为 - 发布的一部分,无论这些分区是否位于该发布模式中。因此,即使直接在某个分区上 - 执行的操作,也会通过其祖先表所在的发布进行发布。 - - - WITH ( publication_parameter [= value] [, ... ] ) @@ -158,11 +95,7 @@ CREATE PUBLICATION name 因此该选项的默认值为 'insert, update, delete, truncate'。 - - 该参数只影响 DML 操作。特别是,逻辑复制的初始数据同步 - (参见)在复制现有表数据时 - 不会考虑该参数。 - + @@ -177,16 +110,9 @@ CREATE PUBLICATION name 非分区表,或者复制到分区结构与发布端不同的分区表。 - - 订阅可能会组合多个发布。如果任一已订阅发布以 - publish_via_partition_root = true发布某个分区表, - 那么该分区表(或其分区)上的更改将使用该分区表本身的标识和模式来发布, - 而不是使用各个分区的标识和模式。 - - - 该参数还会影响为分区选择行过滤器和列列表的方式;详见下文。 - + + 如果启用该选项,直接对分区执行的TRUNCATE操作不会被复制。 @@ -199,21 +125,13 @@ CREATE PUBLICATION name - - 指定boolean类型的参数时, - 可以省略= value - 部分,这等价于指定TRUE。 - + 注意 - - 如果未指定FOR TABLEFOR ALL TABLES或 - FOR TABLES IN SCHEMA,则该发布开始时不包含任何表。 - 这在稍后还要添加表或模式时很有用。 - + 如果既未指定FOR TABLE也未指定FOR ALL TABLES,则该发布开始时不包含任何表。这对于稍后添加表很有用。 创建发布不会启动复制。它只为未来的订阅者定义分组和过滤逻辑。 @@ -224,10 +142,7 @@ CREATE PUBLICATION name (当然,超级用户会绕过这一检查。) - - 要向发布中添加表,调用用户必须拥有该表。使用FOR ALL TABLES - 和FOR TABLES IN SCHEMA子句要求调用用户是超级用户。 - + 要向发布中添加表,调用用户必须拥有该表。FOR ALL TABLES子句要求调用用户是超级用户。 如果某个发布发布UPDATE和/或DELETE @@ -235,42 +150,15 @@ CREATE PUBLICATION name 否则,在这些表上将不允许执行这些操作。 - - 任何列列表都必须包含REPLICA IDENTITY列,这样 - UPDATEDELETE操作才能被发布。 - 如果该发布只发布INSERT操作,则列列表没有限制。 - - - 行过滤表达式(即WHERE子句)必须只包含 - REPLICA IDENTITY所覆盖的列,这样 - UPDATEDELETE操作才能被发布。 - 对于发布INSERT操作,可以在WHERE - 表达式中使用任何列。行过滤器只允许简单表达式。它不能包含用户定义的函数、 - 操作符、类型和排序规则、系统列引用,或非不可变内置函数。 - - - 属于REPLICA IDENTITY的生成列必须被显式发布, - 即要么将其列入列列表,要么启用publish_generated_columns - 选项,这样UPDATEDELETE - 操作才能被发布。 - - - 如果指定了FOR TABLES IN SCHEMA,并且该表属于所引用的模式, - 那么该表上的行过滤器就是多余的。 - - - 对于已发布的分区表,如果发布参数publish_via_partition_root - 为true,则每个分区的行过滤器取自已发布的分区表; - 如果为false(默认值), - 则取自分区本身。类似地,对于已发布的分区表, - 如果发布参数publish_via_partition_roottrue, - 则每个分区的列列表取自已发布的分区表;如果为false, - 则取自分区本身。 - + + + + + 对于INSERT ... ON CONFLICT命令,发布会发布该命令实际产生的 @@ -278,10 +166,7 @@ CREATE PUBLICATION name UPDATE,也可能根本不被发布。 - - 对于MERGE命令,发布会为每一行被插入、更新或删除的记录发布一个 - INSERTUPDATEDELETE。 - + 将表ATTACH到某个分区树中,而该分区树的根通过 @@ -297,9 +182,7 @@ CREATE PUBLICATION name DDL操作不会被发布。 - - WHERE子句表达式会使用复制连接所用的同一角色来执行。 - + @@ -312,12 +195,7 @@ CREATE PUBLICATION mypublication FOR TABLE users, departments; - - 创建一个发布,发布活跃部门中的所有更改: - -CREATE PUBLICATION active_departments FOR TABLE departments WHERE (active IS TRUE); - - + 创建一个发布,发布所有表的所有更改: @@ -334,29 +212,11 @@ CREATE PUBLICATION insert_only FOR TABLE mydata - - 创建一个发布,发布表usersdepartments - 的所有更改,以及模式production中所有表的所有更改: - -CREATE PUBLICATION production_publication FOR TABLE users, departments, TABLES IN SCHEMA production; - - - - 创建一个发布,发布模式marketing和 - sales中所有表的所有更改: - -CREATE PUBLICATION sales_publication FOR TABLES IN SCHEMA marketing, sales; - - - - 创建一个发布,发布表users的所有更改,但只复制 - user_idfirstname两列: - -CREATE PUBLICATION users_filtered FOR TABLE users (user_id, firstname); - - + + + diff --git a/zh/14/ref/create_role.sgml b/zh/14/ref/create_role.sgml index 1a777c5c..b863f2c5 100644 --- a/zh/14/ref/create_role.sgml +++ b/zh/14/ref/create_role.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE ROLE 7 - SQL - Language Statements + SQL - 语言语句 @@ -36,8 +36,10 @@ CREATE ROLE name [ [ WITH ] password' | PASSWORD NULL | VALID UNTIL 'timestamp' | IN ROLE role_name [, ...] + | IN GROUP role_name [, ...] | ROLE role_name [, ...] | ADMIN role_name [, ...] + | USER role_name [, ...] | SYSID uid @@ -64,13 +66,7 @@ in sync when changing the above synopsis! 注意,角色是在数据库集簇级别定义的,因此在该集簇中的所有数据库里都有效。 - - 在创建角色时,可以立即将新建角色加入现有角色,也可以将现有角色加入新建角色。 - 关于初始角色成员资格会启用哪些选项,其规则见下文 - IN ROLEROLEADMIN - 子句的说明。命令在创建成员资格时提供了更细粒度 - 的选项控制,也可以在新角色创建后修改这些选项。 - + @@ -103,13 +99,7 @@ in sync when changing the above synopsis! CREATEDB NOCREATEDB - - 这些子句定义角色创建数据库的能力。如果指定CREATEDB, - 正在定义的角色将被允许创建新数据库。指定NOCREATEDB - 则会禁止该角色创建数据库。若未指定,默认值是 - NOCREATEDB。只有超级用户角色或拥有 - CREATEDB属性的角色才能指定CREATEDB。 - + 这些子句定义角色创建数据库的能力。如果指定CREATEDB,则允许正在定义的角色创建新数据库。指定NOCREATEDB会禁止角色创建数据库。如果未指定,默认值为NOCREATEDB @@ -119,7 +109,7 @@ in sync when changing the above synopsis! 这些子句决定某个角色是否被允许创建、更改、删除其他角色,为其添加注释, - 以及更改其安全标签。关于该权限赋予的具体能力,参见 + 更改其安全标签,以及授予或撤销其中的成员资格。关于该权限赋予的具体能力,参见 。若未指定,默认值是 NOCREATEROLE @@ -130,19 +120,7 @@ in sync when changing the above synopsis! INHERIT NOINHERIT - - 这会影响该角色在本命令以及后续命令中被加入为其他角色成员时,其成员资格 - 的继承状态。具体来说,它控制通过本命令中的IN ROLE - 子句添加的成员资格的继承状态,以及通过后续命令中的ROLE - 子句添加的成员资格的继承状态。使用GRANT命令把该角色 - 添加为成员时,它也会被用作默认继承状态。若未指定,默认值是 - INHERIT。 - - - - 在PostgreSQL 16 之前的版本中,继承是一个 - 角色级属性,用于控制该角色在运行时的所有成员资格检查。 - + 这些子句决定角色是否继承其所属角色的权限。具有INHERIT属性的角色可以自动使用直接或间接所属的所有角色获得的任何数据库权限。没有INHERIT时,成为另一个角色的成员只授予对该角色执行SET ROLE的能力;另一个角色的权限只有在执行该操作后才可用。如果未指定,默认值为INHERIT @@ -150,15 +128,7 @@ in sync when changing the above synopsis! LOGIN NOLOGIN - - 这些子句决定一个角色是否允许登录,也就是说,该角色能否在客户端连接时 - 被用作初始会话授权标识符。具有LOGIN属性的角色可以视为 - 用户。没有这个属性的角色对于管理数据库权限很有用,但并不是通常意义上的 - 用户。若未指定,默认值是NOLOGIN;但当 - CREATE ROLE以其另一种拼写 - CREATE USER - 调用时,默认值是LOGIN。 - + 这些子句决定是否允许角色登录;也就是说,在客户端连接期间,是否可以将该角色作为初始会话授权名称。具有LOGIN属性的角色可以视为用户。没有该属性的角色可用于管理数据库权限,但通常意义上不属于用户。如果未指定,默认值为NOLOGIN,但通过其另一种拼写CREATE USER调用CREATE ROLE时除外。 @@ -166,14 +136,7 @@ in sync when changing the above synopsis! REPLICATION NOREPLICATION - - 这些子句决定一个角色是否为复制角色。角色必须拥有该属性(或本身是超级用户), - 才能以复制模式(物理复制或逻辑复制)连接到服务器,也才能创建或删除复制槽。 - 具有REPLICATION属性的角色权限非常高,因此应只用于 - 实际承担复制任务的角色。若未指定,默认值是 - NOREPLICATION。只有超级用户角色或拥有 - REPLICATION属性的角色才能指定REPLICATION。 - + 这些子句决定角色是否为复制角色。角色必须具有此属性(或是超级用户),才能以复制模式(物理复制或逻辑复制)连接到服务器,以及创建或删除复制槽。具有REPLICATION属性的角色权限非常高,因此该属性只应赋予实际用于复制的角色。如果未指定,默认值为NOREPLICATION。要创建具有REPLICATION属性的新角色,必须是超级用户。 @@ -181,11 +144,7 @@ in sync when changing the above synopsis! BYPASSRLS NOBYPASSRLS - - 这些子句决定一个角色是否绕过所有行级安全(RLS)策略。默认值是 - NOBYPASSRLS。只有超级用户角色或拥有 - BYPASSRLS属性的角色才能指定BYPASSRLS。 - + 这些子句决定角色是否绕过每个行级安全(RLS)策略。NOBYPASSRLS是默认值。要创建具有BYPASSRLS属性的新角色,必须是超级用户。 注意,pg_dump 默认会把row_security设置为 @@ -233,13 +192,7 @@ in sync when changing the above synopsis! 的值是什么,它都会按原样存储(因为系统无法解密指定的已加密密码字符串, 再将其改用其他格式加密)。这样便可在转储/恢复期间重新装载已加密的密码。 - - - 对 MD5 加密密码的支持已被弃用,并将在未来的 - PostgreSQL版本中移除。关于迁移到其他密码类型 - 的细节,参见。 - - + @@ -257,9 +210,15 @@ in sync when changing the above synopsis! IN ROLE role_name - IN ROLE子句会使新角色自动成为指定现有角色的成员。 - 新建的成员资格将启用SET选项,并禁用ADMIN选项。 - 除非指定了NOINHERIT选项,否则还会启用INHERIT选项。 + IN ROLE子句列出一个或多个现有角色,新角色会立即被添加为这些角色的新成员。(注意,没有选项能将新角色添加为管理员;请另行使用GRANT命令执行此操作。) + + + + + + IN GROUP role_name + + IN GROUPIN ROLE的过时拼写。 @@ -268,11 +227,7 @@ in sync when changing the above synopsis! ROLE role_name - ROLE子句会使一个或多个指定的现有角色自动成为新角色 - 的成员,并启用SET选项。这实际上会使新角色成为一个 - 。在该子句中命名且具有角色级INHERIT - 属性的角色,其新建成员资格将启用INHERIT选项。新建 - 成员资格的ADMIN选项将被禁用。 + ROLE子句列出一个或多个现有角色,它们会被自动添加为新角色的成员。(这实际上使新角色成为一个。) @@ -281,9 +236,17 @@ in sync when changing the above synopsis! ADMIN role_name - ADMIN子句与ROLE效果相同,但被命名的 - 角色会作为新角色的成员加入,并启用ADMIN选项,从而使 - 它们有权将新角色的成员资格授予其他角色。 + ADMIN子句与ROLE类似,但所列角色会以WITH ADMIN + OPTION加入新角色,从而有权向其他人授予此角色的成员资格。 + + + + + + USER role_name + + + USER子句是ROLE子句的过时拼写。 @@ -321,18 +284,10 @@ in sync when changing the above synopsis! - 这里定义的角色属性都是不可继承的。也就是说,成为一个例如具有 - CREATEDB属性的角色成员,并不会让该成员在其成员资格授予 - 带有INHERIT选项的情况下也能创建新数据库。当然,如果该成员资格 - 带有SET选项,成员角色仍然可以 - SET ROLE切换到具有 - CREATEDB属性的角色,然后再创建新数据库。 + INHERIT属性控制可授予权限的继承(即数据库对象的访问权限和角色成员资格)。它不适用于通过CREATE ROLEALTER ROLE设置的特殊角色属性。例如,成为具有CREATEDB权限的角色的成员,并不会立即获得创建数据库的能力,即使设置了INHERIT也是如此;必须先通过SET ROLE成为该角色,才能创建数据库。 - - 通过IN ROLEROLEADMIN - 子句创建的成员资格,其授权者就是执行此命令的角色。 - + 之所以默认采用INHERIT属性,是出于向后兼容的考虑:在 @@ -340,6 +295,10 @@ in sync when changing the above synopsis! 全部权限。不过,NOINHERIT更接近 SQL 标准规定的语义。 + + 请谨慎对待CREATEROLE权限。对于具有CREATEROLE的角色的权限,没有继承的概念。这意味着,即使某个角色不具有某项权限,只要允许它创建其他角色,它就可以轻易创建权限与自身不同的另一个角色(但不能创建具有超级用户权限的角色)。例如,如果角色user具有CREATEROLE权限而没有CREATEDB权限,它仍然可以创建具有CREATEDB权限的新角色。因此,应将具有CREATEROLE权限的角色视为近乎超级用户的角色。 + + PostgreSQL包含一个程序,其功能与CREATE ROLE相同 @@ -415,25 +374,13 @@ CREATE ROLE name [ WITH ADMIN - 若要最接近 SQL 标准规定的行为,可以将 SQL 标准中的用户创建为带有 - NOINHERIT选项的PostgreSQL - 角色,而将 SQL 标准中的角色创建为带有INHERIT选项的 - PostgreSQL角色。 + 将用户赋予 NOINHERIT 属性,而将角色赋予 + INHERIT 属性,最接近 SQL 标准规定的行为。 - - USER子句的行为与ROLE相同,但已经被弃用: - -USER role_name [, ...] - - - - IN GROUP子句的行为与IN ROLE相同,但已经被弃用: - -IN GROUP role_name [, ...] - - + + @@ -446,7 +393,6 @@ IN GROUP role_name [, ...] - diff --git a/zh/14/ref/create_rule.sgml b/zh/14/ref/create_rule.sgml index 6d1486c9..e8b37c6d 100644 --- a/zh/14/ref/create_rule.sgml +++ b/zh/14/ref/create_rule.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE RULE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/create_schema.sgml b/zh/14/ref/create_schema.sgml index 74944401..8b36ce72 100644 --- a/zh/14/ref/create_schema.sgml +++ b/zh/14/ref/create_schema.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE SCHEMA 7 - SQL - Language Statements + SQL - 语言语句 @@ -77,9 +77,7 @@ CREATE SCHEMA IF NOT EXISTS AUTHORIZATION role_sp user_name - 将拥有新模式的用户的角色名。如果省略,则默认为执行该命令的用户。要创建 - 由另一个角色拥有的模式,你必须能够对该角色执行 - SET ROLE。 + 将拥有新模式的用户的角色名。如果省略,则默认为执行该命令的用户。要创建由另一个角色拥有的模式,你必须是该角色的直接或间接成员,或者是超级用户。 diff --git a/zh/14/ref/create_sequence.sgml b/zh/14/ref/create_sequence.sgml index 41e8dba8..3be68584 100644 --- a/zh/14/ref/create_sequence.sgml +++ b/zh/14/ref/create_sequence.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation CREATE SEQUENCE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/create_server.sgml b/zh/14/ref/create_server.sgml index 586067b0..0cb4f9ed 100644 --- a/zh/14/ref/create_server.sgml +++ b/zh/14/ref/create_server.sgml @@ -13,7 +13,7 @@ PostgreSQL documentation CREATE SERVER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/create_statistics.sgml b/zh/14/ref/create_statistics.sgml index ecafe6c6..f007156a 100644 --- a/zh/14/ref/create_statistics.sgml +++ b/zh/14/ref/create_statistics.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE STATISTICS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/create_subscription.sgml b/zh/14/ref/create_subscription.sgml index 352a4bce..c62bd7fb 100644 --- a/zh/14/ref/create_subscription.sgml +++ b/zh/14/ref/create_subscription.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE SUBSCRIPTION 7 - SQL - Language Statements + SQL - 语言语句 @@ -32,25 +32,21 @@ CREATE SUBSCRIPTION subscription_name描述 - CREATE SUBSCRIPTION添加一个新的逻辑复制订阅。 - 创建订阅的用户将成为该订阅的所有者。订阅名称必须与当前数据库中 - 任何现有订阅的名称不同。 + CREATE SUBSCRIPTION为当前数据库添加一个新订阅。 + 订阅名称必须与数据库中任何现有订阅的名称不同。 - 订阅表示与发布者的复制连接。因此,除了在本地系统目录中添加定义之外, - 该命令通常还会在发布者上创建一个复制槽。 + 订阅表示与发布者的复制连接。因此,该命令不仅会在本地系统目录中添加定义, + 还会在发布者上创建一个复制槽。 - 除非订阅初始即被禁用,否则在执行该命令所在事务提交时,会启动一个 - 逻辑复制工作进程为新订阅复制数据。 + 在执行该命令所在事务提交时,会启动一个逻辑复制工作进程, + 为新订阅复制数据。 - - 要能够创建订阅,必须具有pg_create_subscription角色的权限, - 以及当前数据库上的CREATE权限。 - + 关于订阅以及整个逻辑复制的更多信息,请参见 @@ -84,7 +80,7 @@ CREATE SUBSCRIPTION subscription_name - PUBLICATION publication_name [, ...] + PUBLICATION publication_name 要订阅的发布者上的发布名称。 diff --git a/zh/14/ref/create_table.sgml b/zh/14/ref/create_table.sgml index d3b0d042..3389b084 100644 --- a/zh/14/ref/create_table.sgml +++ b/zh/14/ref/create_table.sgml @@ -4,7 +4,6 @@ PostgreSQL documentation --> - CREATE TABLE @@ -12,7 +11,7 @@ PostgreSQL documentation CREATE TABLE 7 - SQL - Language Statements + SQL - 语言语句 @@ -23,7 +22,7 @@ PostgreSQL documentation CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXISTS ] table_name ( [ - { column_name data_type [ STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN | DEFAULT } ] [ COMPRESSION compression_method ] [ COLLATE collation ] [ column_constraint [ ... ] ] + { column_name data_type [ COMPRESSION compression_method ] [ COLLATE collation ] [ column_constraint [ ... ] ] | table_constraint | LIKE source_table [ like_option ... ] } [, ... ] @@ -59,64 +58,58 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI [ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ] [ TABLESPACE tablespace_name ] -where column_constraint is: +其中column_constraint为: [ CONSTRAINT constraint_name ] -{ NOT NULL [ NO INHERIT ] | +{ NOT NULL | NULL | CHECK ( expression ) [ NO INHERIT ] | DEFAULT default_expr | - GENERATED ALWAYS AS ( generation_expr ) [ STORED | VIRTUAL ] | + GENERATED ALWAYS AS ( generation_expr ) STORED | GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( sequence_options ) ] | - UNIQUE [ NULLS [ NOT ] DISTINCT ] index_parameters | + UNIQUE index_parameters | PRIMARY KEY index_parameters | REFERENCES reftable [ ( refcolumn ) ] [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE referential_action ] [ ON UPDATE referential_action ] } -[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ] [ ENFORCED | NOT ENFORCED ] +[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ] -and table_constraint is: +table_constraint为: [ CONSTRAINT constraint_name ] { CHECK ( expression ) [ NO INHERIT ] | - NOT NULL column_name [ NO INHERIT ] | - UNIQUE [ NULLS [ NOT ] DISTINCT ] ( column_name [, ... ] [, column_name WITHOUT OVERLAPS ] ) index_parameters | - PRIMARY KEY ( column_name [, ... ] [, column_name WITHOUT OVERLAPS ] ) index_parameters | + UNIQUE ( column_name [, ... ] ) index_parameters | + PRIMARY KEY ( column_name [, ... ] ) index_parameters | EXCLUDE [ USING index_method ] ( exclude_element WITH operator [, ... ] ) index_parameters [ WHERE ( predicate ) ] | - FOREIGN KEY ( column_name [, ... ] [, PERIOD column_name ] ) REFERENCES reftable [ ( refcolumn [, ... ] [, PERIOD refcolumn ] ) ] + FOREIGN KEY ( column_name [, ... ] ) REFERENCES reftable [ ( refcolumn [, ... ] ) ] [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE referential_action ] [ ON UPDATE referential_action ] } -[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ] [ ENFORCED | NOT ENFORCED ] +[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ] -and like_option is: +like_option为: { INCLUDING | EXCLUDING } { COMMENTS | COMPRESSION | CONSTRAINTS | DEFAULTS | GENERATED | IDENTITY | INDEXES | STATISTICS | STORAGE | ALL } -and partition_bound_spec is: +partition_bound_spec为: IN ( partition_bound_expr [, ...] ) | FROM ( { partition_bound_expr | MINVALUE | MAXVALUE } [, ...] ) TO ( { partition_bound_expr | MINVALUE | MAXVALUE } [, ...] ) | WITH ( MODULUS numeric_literal, REMAINDER numeric_literal ) -index_parameters in UNIQUE, PRIMARY KEY, and EXCLUDE constraints are: +UNIQUEPRIMARY KEYEXCLUDE约束中的index_parameters为: [ INCLUDE ( column_name [, ... ] ) ] [ WITH ( storage_parameter [= value] [, ... ] ) ] [ USING INDEX TABLESPACE tablespace_name ] -exclude_element in an EXCLUDE constraint is: +EXCLUDE约束中的exclude_element为: { column_name | ( expression ) } [ COLLATE collation ] [ opclass [ ( opclass_parameter = value [, ... ] ) ] ] [ ASC | DESC ] [ NULLS { FIRST | LAST } ] - -referential_action in a FOREIGN KEY/REFERENCES constraint is: - -{ NO ACTION | RESTRICT | CASCADE | SET NULL [ ( column_name [, ... ] ) ] | SET DEFAULT [ ( column_name [, ... ] ) ] } - 描述 @@ -127,7 +120,7 @@ WITH ( MODULUS numeric_literal, REM 如果给出了模式名(例如 CREATE TABLE myschema.mytable ...),则表将在指定模式中创建。 否则,它将在当前模式中创建。临时表存在于一个特殊模式中,因此创建临时表时不能给出模式名。 - 表名必须与同一模式中任何其他关系(表、序列、索引、视图、物化视图或外部表)的名称不同。 + 表名必须与同一模式中任何其他表、序列、索引、视图或外部表的名称不同。 @@ -148,16 +141,13 @@ WITH ( MODULUS numeric_literal, REM - 参数 - - TEMPORARY or TEMP + TEMPORARYTEMP - 如果指定该选项,表将创建为临时表。 临时表会在会话结束时自动删除,或者也可在当前事务结束时删除(见下文 ON COMMIT)。 @@ -170,7 +160,7 @@ WITH ( MODULUS numeric_literal, REM - 可以在 TEMPORARYTEMP 前写 GLOBALLOCAL。这在当前的 PostgreSQL 中没有区别,而且已废弃;见下文 。 + 可以在 TEMPORARYTEMP 前写 GLOBALLOCAL。这在当前的 PostgreSQL 中没有区别,而且已弃用;见下文 @@ -178,18 +168,9 @@ WITH ( MODULUS numeric_literal, REM UNLOGGED - 如果指定该选项,表将创建为不记录 WAL 的表。写入不记录 WAL 的表的数据不会写入预写式日志(见 ),因此它们比普通表快得多。不过,它们不具备崩溃安全性:在崩溃或非正常关闭后,不记录 WAL 的表会被自动截断。不记录 WAL 的表的内容也不会复制到备库。在不记录 WAL 的表上创建的任何索引也都会自动成为不记录 WAL 的。 - - - 如果指定该选项,与不记录 WAL 的表一起创建的任何序列(用于标识列或 serial 列)也会创建为不记录日志的。 - - - - 这种形式不支持分区表。 - @@ -216,14 +197,9 @@ WITH ( MODULUS numeric_literal, REM OF type_name + 创建一个类型化表,其结构取自指定的复合类型(名称可以带模式限定)。类型化表与其类型绑定;例如,如果删除该类型(使用DROP TYPE ... CASCADE),该表也会被删除。 - - 创建一个类型化表,其结构取自指定的独立复合类型(即通过 创建的类型),同时该表自身也会生成一个新的复合类型。该表会依赖于所引用的类型,这意味着对该类型执行级联的 ALTER 或 DROP 操作会传播到该表。 - - - - 类型化表的列名和数据类型始终与其派生类型相同,因此不能再指定额外的列。但 CREATE TABLE 命令仍可为该表添加默认值和约束,并指定存储参数。 - + 创建类型化表时,列的数据类型由底层复合类型决定,不由CREATE TABLE命令指定。不过,CREATE TABLE命令可以为表添加默认值和约束,并指定存储参数。 @@ -252,26 +228,7 @@ WITH ( MODULUS numeric_literal, REM COLLATE collation - - - COLLATE 子句为该列(必须是一种可排序数据类型)赋予一个排序规则。 - 如果没有指定,将使用该列数据类型的默认排序规则。 - - - - - - - STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN | DEFAULT } - - TOAST - per-column storage settings - - - - - 该形式设置列的存储模式,用于控制该列是以内联形式存储还是存入二级 TOAST 表,以及数据是否压缩。PLAIN 必须用于诸如 integer 的定长值,表示内联且不压缩。MAIN 用于内联且可压缩的数据。EXTERNAL 用于外部且不压缩的数据,EXTENDED 用于外部且压缩的数据。写成 DEFAULT 则将存储模式设置为该列数据类型的默认模式。对大多数支持非 PLAIN 存储的数据类型,默认是 EXTENDED。使用 EXTERNAL 可提高超大 textbytea 值上的子串操作速度,但代价是占用更多存储空间。详见 。 - + COLLATE子句为列指定排序规则(该列必须属于支持排序规则的数据类型)。如果未指定,则使用列数据类型的默认排序规则。 @@ -335,7 +292,6 @@ WITH ( MODULUS numeric_literal, REM PARTITION BY { RANGE | LIST | HASH } ( { column_name | ( expression ) } [ opclass ] [, ...] ) - 可选的 PARTITION BY 子句指定表的分区策略。 这样创建的表称为分区表。 @@ -356,6 +312,8 @@ WITH ( MODULUS numeric_literal, REM 如果没有现有分区与新行中的值匹配,就会报错。 + 分区表不支持EXCLUDE约束;不过,可以在各个分区上定义这些约束。 + 有关表分区的更多讨论,请参阅 @@ -366,7 +324,6 @@ WITH ( MODULUS numeric_literal, REM PARTITION OF parent_table { FOR VALUES partition_bound_spec | DEFAULT } - 将该表创建为指定父表的分区。 可以使用 FOR VALUES 将其创建为特定值的分区,也可以使用 DEFAULT 创建为默认分区。 @@ -424,13 +381,13 @@ WITH ( MODULUS numeric_literal, REM 还要注意,某些元素类型(如 timestamp)具有 - "infinity" 的概念,那只是另一种可存储的值。这不同于 + “无穷大” 的概念,那只是另一种可存储的值。这不同于 MINVALUEMAXVALUE,后两者并非可存储 的实际值,而只是表示值无界的方式。MAXVALUE 可以视为大于任何 - 其他值,包括 "infinity";MINVALUE 可以视为小于任何 - 其他值,包括 "minus infinity"。因此,范围 + 其他值,包括 “无穷大”;MINVALUE 可以视为小于任何 + 其他值,包括 “负无穷大”。因此,范围 FROM ('infinity') TO (MAXVALUE) 并不是空范围;它只允许存储 - 一个值 — "infinity"。 + 一个值 — “无穷大”。 @@ -488,19 +445,15 @@ WITH ( MODULUS numeric_literal, REM LIKE source_table [ like_option ... ] - LIKE 子句指定一个表,新表会自动从中复制所有列名、数据类型及其非空约束。 - INHERITS 不同,新表和原表在创建完成后就完全脱钩了。对原表的修改不会应用到新表,也不可能在扫描原表时包含新表的数据。 - 同样与 INHERITS 不同,由 LIKE 复制的列和约束不会与同名的列和约束合并。如果同一名称被显式指定,或在另一个 LIKE 子句中指定,则会报错。 - 可选的 like_option 子句指定还要复制原表的哪些附加属性。 指定 INCLUDING 表示复制该属性,指定 EXCLUDING 表示省略该属性。默认是 EXCLUDING。 @@ -548,7 +501,7 @@ WITH ( MODULUS numeric_literal, REM INCLUDING GENERATED - 会复制被复制列定义中的生成表达式以及 STORED/VIRTUAL 的选择。默认情况下,新列将是常规基表列。 + 会复制被复制列定义中的生成表达式。默认情况下,新列将是普通基础列。 @@ -621,16 +574,11 @@ WITH ( MODULUS numeric_literal, REM - NOT NULL [ NO INHERIT ] + NOT NULL - 该列不允许包含空值。 - - - 标记为 NO INHERIT 的约束不会传播到子表。 - @@ -651,7 +599,6 @@ WITH ( MODULUS numeric_literal, REM CHECK ( expression ) [ NO INHERIT ] - CHECK 子句指定一个产生布尔结果的表达式。要使插入或更新成功,新行或更新后的行必须满足该表达式。计算结果为 TRUE 或 UNKNOWN 的表达式视为成功。如果插入或更新操作中的任何一行得到 FALSE 结果,就会抛出错误异常,并且插入或更新不会修改数据库。作为列约束指定的检查约束只应引用该列的值,而出现在表约束中的表达式可以引用多个列。 @@ -661,7 +608,7 @@ WITH ( MODULUS numeric_literal, REM - 一个被标记为NO INHERIT的约束将不会传播到子表。 + 标记为 NO INHERIT 的约束不会传播到子表。 @@ -687,32 +634,23 @@ WITH ( MODULUS numeric_literal, REM - - GENERATED ALWAYS AS ( generation_expr ) [ STORED | VIRTUAL ]generated column + GENERATED ALWAYS AS ( generation_expr ) STORED生成列 - 此子句将列创建为生成列。列不可写入,读取时会返回指定表达式的结果。 - - 指定 VIRTUAL 时,列会在读取时计算且不占用存储;指定 STORED 时,列会在写入时计算并存储在磁盘上。默认是 VIRTUAL。 - + 必须使用关键字STORED,表示该列将在写入时计算并存储在磁盘上。 生成表达式可以引用表中的其他列,但不能引用其他生成的列。使用的任何函数和操作符都必须是不可变的。不允许引用其他表。 - - - 虚拟生成列不能使用用户定义类型,且其生成表达式不得引用用户定义函数或类型,也就是只能使用内置函数或类型。此限制也包含间接使用(例如操作符或类型转换背后的函数或类型)。该限制不适用于存储型生成列。 - GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( sequence_options ) ] - 该子句将列创建为标识列。 它会隐式附带一个序列,并且在新插入的行中,该列会自动取得分配给它的序列值。 @@ -739,68 +677,39 @@ WITH ( MODULUS numeric_literal, REM (UPDATE 命令没有 OVERRIDING 子句。) - - 可选的 sequence_options 子句可用于覆盖序列参数。可用选项包括 中展示的选项,另外还包括 SEQUENCE NAME nameLOGGEDUNLOGGED,用于选择序列名称及持久化级别。不指定 SEQUENCE NAME 时,系统会为该序列选择一个未使用名称。不指定 LOGGEDUNLOGGED 时,序列将与表具有相同的持久化级别。 - + 可选的sequence_options子句可用于覆盖序列的选项。详情见 - - UNIQUE [ NULLS [ NOT ] DISTINCT ](列约束) - - - UNIQUE [ NULLS [ NOT ] DISTINCT ] ( column_name [, ... ] [, column_name WITHOUT OVERLAPS ] ) - INCLUDE ( column_name [, ...]) (表约束) - + UNIQUE(列约束) + UNIQUE ( column_name [, ... ] ) + INCLUDE ( column_name [, ...]) (表约束) - UNIQUE 约束指定表中一列或多列组成的一组只能包含唯一值。 表级唯一约束的行为与列级唯一约束相同,只是它还能跨越多列。因此,该约束 要求任意两行在这些列中至少有一列不同。 - - 如果为最后一列指定了 WITHOUT OVERLAPS 选项,则该列检查的 - 是是否重叠,而不是是否相等。在这种情况下,只要重复值在 - WITHOUT OVERLAPS 列上不发生重叠,约束中的其他列就允许重 - 复。(如果该列是日期或时间戳范围,这有时被称为时态键;但 - PostgreSQL 允许在任意基础类型上定义范围。) - 实际上,这种约束是通过 EXCLUDE 约束而不是 - UNIQUE 约束来强制的。例如, - UNIQUE (id, valid_at WITHOUT OVERLAPS) 的行为类似于 - EXCLUDE USING GIST (id WITH =, valid_at WITH &&)。 - WITHOUT OVERLAPS 列必须是范围类型或多范围类型,且不允许 - 为空范围或空多范围。该约束中不带 WITHOUT OVERLAPS 的列可以 - 是任何可在 GiST 索引中按相等性比较的类型。默认仅支持范围类型,但可通过安装 - 扩展来使用其他类型(这也是该特性的预期用法)。 - - - - 就唯一约束而言,空值不被视为相等,除非指定了 - NULLS NOT DISTINCT。 - + 对于唯一约束,空值不被视为相等。 每个唯一约束都应引用一组列,这组列应不同于该表上任何其他唯一约束或 主键约束所引用的列集合。(否则,冗余的唯一约束将被丢弃。) + 在为多级分区层次结构建立唯一约束时,目标分区表分区键中的所有列,以及 其所有后代分区表分区键中的所有列,都必须包含在约束定义中。 - - 添加唯一约束会自动在约束所用的列或列组上创建唯一 B-树索引;但如果该约束 - 包含 WITHOUT OVERLAPS 子句,则会使用 GiST 索引。所创建 - 的索引与该唯一约束同名。 - + 添加唯一约束会自动在约束所用的列或列组上创建唯一 B-树索引。 可选的 INCLUDE 子句会向该索引添加一个或多个仅作为 - payload 的列:对这些列不强制唯一性,而且该索引也不能据此 + 载荷 的列:对这些列不强制唯一性,而且该索引也不能据此 进行搜索。不过,它们可以通过仅索引扫描取回。注意,尽管约束不在包含列上 强制执行,它仍然依赖于这些列。因此,对这类列执行某些操作(例如 DROP COLUMN)可能导致约束和索引被级联删除。 @@ -809,13 +718,10 @@ WITH ( MODULUS numeric_literal, REM - PRIMARY KEY(列约束) - - PRIMARY KEY ( column_name [, ... ] [, column_name WITHOUT OVERLAPS ] ) - INCLUDE ( column_name [, ...]) (表约束) + PRIMARY KEY ( column_name [, ... ] ) + INCLUDE ( column_name [, ...]) (表约束) - PRIMARY KEY 约束指定表的一列或多列只能包含唯一 (不重复)且非空的值。无论作为列约束还是表约束,一个表都只能指定一个 @@ -841,13 +747,11 @@ WITH ( MODULUS numeric_literal, REM 添加 PRIMARY KEY 约束会自动在约束所用的列或列组上创建 - 唯一 B-树索引;如果指定了 WITHOUT OVERLAPS,则会创建 - GiST 索引。 - + 唯一 B-树索引。 可选的 INCLUDE 子句会向该索引添加一个或多个仅作为 - payload 的列:对这些列不强制唯一性,而且该索引也不能据此 + 载荷 的列:对这些列不强制唯一性,而且该索引也不能据此 进行搜索。不过,它们可以通过仅索引扫描取回。注意,尽管约束不在包含列上 强制执行,它仍然依赖于这些列。因此,对这类列执行某些操作(例如 DROP COLUMN)可能导致约束和索引被级联删除。 @@ -858,7 +762,6 @@ WITH ( MODULUS numeric_literal, REM EXCLUDE [ USING index_method ] ( exclude_element WITH operator [, ... ] ) index_parameters [ WHERE ( predicate ) ] - EXCLUDE 子句定义一个排他约束。它保证如果任意两行在 指定列或表达式上使用指定操作符进行比较,这些比较不会全部返回 @@ -871,7 +774,7 @@ WITH ( MODULUS numeric_literal, REM - 排他约束通过一个与约束同名的索引来实现,因此每个指定操作符都必须与 + 排他约束通过索引来实现,因此每个指定操作符都必须与 索引访问方法 index_method 的适当操作符类关联 (见 )。每个 exclude_element 都定义了索引的一 @@ -883,7 +786,7 @@ WITH ( MODULUS numeric_literal, REM 访问方法必须支持 amgettuple(见 );目前这意味着不能使用 GIN。 虽然允许,但在排他约束上使用 B-树或 hash 索引意义不大,因为它们做不到 - 比普通唯一约束更好的事情。因此,实践中访问方法几乎总会是 + 比普通唯一约束更好的事情。因此,实践中访问方法总是 GiSTSP-GiST @@ -892,67 +795,21 @@ WITH ( MODULUS numeric_literal, REM 子集上指定排他约束;在内部,这会创建一个部分索引。注意, predicate 周围的圆括号是必需的。 - - 在为多级分区层次结构建立排他约束时,目标分区表分区键中的所有列,以及其 - 所有后代分区表分区键中的所有列,都必须包含在约束定义中。此外,这些列必 - 须使用等值操作符进行比较。这些限制保证潜在冲突的行会落在同一分区中。约 - 束也可以引用不属于任何分区键的其他列,这些列可以使用任何合适的操作符来 - 比较。 - - REFERENCES reftable [ ( refcolumn ) ] [ MATCH matchtype ] [ ON DELETE referential_action ] [ ON UPDATE referential_action ](列约束) - FOREIGN KEY ( column_name [, ... ] [, PERIOD column_name ] ) - REFERENCES reftable [ ( refcolumn [, ... ] [, PERIOD refcolumn ] ) ] - [ MATCH matchtype ] - [ ON DELETE referential_action ] - [ ON UPDATE referential_action ] + FOREIGN KEY ( column_name [, ... ] ) + REFERENCES reftable [ ( refcolumn [, ... ] ) ] + [ MATCH matchtype ] + [ ON DELETE referential_action ] + [ ON UPDATE referential_action ] (表约束) - - - 这些子句指定外键约束,要求新表的一列或多列组成的一组只能包含与被引用 - 表某一行的被引用列中值相匹配的值。若省略 - refcolumn 列表,则使用 - reftable 的主键。否则, - refcolumn 列表必须引用某个不可延 - 迟的唯一约束或主键约束的列,或者引用某个非部分唯一索引的列。 - - - - 如果最后一列标记为 PERIOD,则会按特殊方式处理。非 - PERIOD 列按相等性比较(并且至少需要一列),而 - PERIOD 列则不会。取而代之的是,只有当被引用表中基于键的 - 非 PERIOD 部分相匹配的记录,其合并后的 - PERIOD 值能够完整覆盖引用记录的 - PERIOD 值时,约束才算满足。换言之,该引用在其整个持续区 - 间内都必须有对应的被引用对象。该列必须是范围类型或多范围类型。此外,被 - 引用表必须具有用 WITHOUT OVERLAPS 声明的主键或唯一约 - 束。最后,如果外键包含 PERIOD - column_name 说明,则对应的 - refcolumn(如果存在)也必须标记 - 为 PERIOD。如果省略 - refcolumn 子句,从而选择 - reftable 的主键约束,则该主键的最后一列必须标记为 - WITHOUT OVERLAPS。 - - - - 对于每一对引用列和被引用列,如果它们属于可排序数据类型,则两者的排序规 - 则要么都必须是确定性的,要么必须完全相同。这样可以确保两列对“相等”具 - 有一致的定义。 - - - 用户必须对被引用表拥有 REFERENCES 权限(对整张表,或对 - 特定的被引用列)。添加外键约束需要在被引用表上获取 - SHARE ROW EXCLUSIVE 锁。注意,不能在临时表和永久表之间 - 定义外键约束。 - + 这些子句指定外键约束,要求新表中由一个或多个列组成的列组只能包含与被引用表中某一行的被引用列中的值相匹配的值。如果省略refcolumn列表,则使用reftable的主键。否则,refcolumn列表必须引用不可延迟的唯一约束或主键约束的列,或者是非部分唯一索引的列。用户必须拥有被引用表的REFERENCES权限(可以针对整个表,也可以针对具体的被引用列)。添加外键约束需要在被引用表上获取SHARE ROW EXCLUSIVE锁。请注意,不能在临时表和永久表之间定义外键约束。 插入到引用列中的值会按照给定的匹配类型,与被引用表及其被引用列中的值进 @@ -966,39 +823,18 @@ WITH ( MODULUS numeric_literal, REM NOT NULL 约束,以防止出现这些情况。) - - 此外,当被引用列中的数据发生变化时,会对本表列中的数据执行某些操作。 - ON DELETE 子句指定当被引用表中的被引用行被删除时要执行 - 的操作。同样,ON UPDATE 子句指定当被引用表中的被引用列 - 被更新为新值时要执行的操作。如果更新了行,但被引用列实际上并未改变,则 - 不执行任何操作。引用动作作为数据更改命令的一部分执行,即使该约束是延迟 - 的也一样。每个子句可用的操作如下: - - + 此外,当被引用列中的数据发生变化时,会对本表列中的数据执行某些操作。ON DELETE子句指定删除被引用表中的被引用行时要执行的操作。同样,ON UPDATE子句指定将被引用表中的被引用列更新为新值时要执行的操作。如果行被更新,但被引用列实际上没有变化,则不执行任何操作。除NO ACTION检查以外的引用操作都不能延迟,即使该约束声明为可延迟也是如此。每个子句可以指定以下操作: NO ACTION - - 如果删除或更新会导致外键约束违规,则产生错误。如果约束被延迟,且到 - 约束检查时仍然存在任何引用行,就会产生此错误。 - 这是默认操作。 - + 产生错误,指出删除或更新会违反外键约束。如果该约束被延迟,则会在约束检查时仍存在引用行的情况下产生这个错误。这是默认操作。 RESTRICT - - 如果待删除或更新的行在引用表中有匹配行,则产生错误。即使操作完成后 - 的状态并不违反外键约束,也会阻止该操作。特别地,它会阻止将被引用行 - 更新为“值不同但比较相等”的情况。(但不会阻止把列更新为相同值的 - 无操作更新。) - - - - 对于时态外键,该选项不受支持。 - + 产生错误,指出删除或更新会违反外键约束。这与NO ACTION相同,但检查不能延迟。 @@ -1008,48 +844,26 @@ WITH ( MODULUS numeric_literal, REM 分别删除任何引用已删除行的行,或将引用列的值更新为被引用列的新值。 - - - 对于时态外键,该选项不受支持。 - - SET NULL [ ( column_name [, ... ] ) ] + SET NULL - - 将全部引用列,或指定的引用列子集,设置为空值。只有 - ON DELETE 动作才能指定列子集。 - - - - 对于时态外键,该选项不受支持。 - + 将引用列设置为空值。 - SET DEFAULT [ ( column_name [, ... ] ) ] + SET DEFAULT - - 将全部引用列,或指定的引用列子集,设置为其默认值。只有 - ON DELETE 动作才能指定列子集。(如果默认值不是空 - 值,则被引用表中必须有一行与这些默认值匹配,否则该操作会失败。) - - - - 对于时态外键,该选项不受支持。 - + 将引用列设置为其默认值。(如果默认值不为空,则被引用表中必须存在与这些默认值匹配的行,否则操作会失败。) - - 如果被引用列经常发生变化,那么最好在引用列上添加一个索引,以便更高效地 - 执行与该外键约束相关的引用动作。 - + 如果被引用列经常变化,可以考虑在引用列上添加索引,使与外键约束关联的引用操作能够更高效地执行。 @@ -1088,38 +902,15 @@ WITH ( MODULUS numeric_literal, REM - - ENFORCED - NOT ENFORCED - - - 当约束为 ENFORCED 时,数据库系统会在适当时机检查该约束(按需要在每条语句后或事务结束时),这是默认行为。若约束为 NOT ENFORCED,数据库系统将不再检查该约束,改由应用代码保证约束成立。对于不影响结果正确性的优化决策,数据库系统仍可能假定数据满足该约束。 - - - - NOT ENFORCED 约束可作为文档用途,适用于运行时检查约束代价过高的场景。 - - - - 当前该能力仅支持外键约束与 CHECK 约束。 - - - - USING method - 该可选子句指定存储新表内容所用的表访问方法;该方法必须是类型为 TABLE 的访问方法。详见 。如果未 指定此选项,则会为新表选择默认表访问方法。详见 - - - 创建分区时,若其分区表已设置表访问方法,则该分区会使用分区表的访问方法。 - @@ -1221,11 +1012,10 @@ WITH ( MODULUS numeric_literal, REM - 存储参数 - storage parameters + 存储参数 @@ -1244,10 +1034,9 @@ WITH ( MODULUS numeric_literal, REM - fillfactor (integer) - fillfactor storage parameter + fillfactor 存储参数 @@ -1266,18 +1055,16 @@ WITH ( MODULUS numeric_literal, REM - toast_tuple_target (integer) - toast_tuple_target storage parameter + toast_tuple_target 存储参数 - toast_tuple_target 指定在尝试压缩和/或将长列值移入 TOAST 表之前所需的最小元组长度,同时也是一旦开始 TOAST 化后试图将长度 - 缩减到的目标长度。这会影响标记为 External(用于移动)、Main(用于压缩) + 缩减到其以下的目标长度。这会影响标记为 External(用于移动)、Main(用于压缩) 或 Extended(用于两者)的列,并且只适用于新元组。对现有行没有影响。默认 情况下,该参数被设置为至少允许每个块容纳 4 个元组,在默认块大小下即为 2040 字节。有效值介于 128 字节与(块大小减去页头)之间,默认上限为 @@ -1289,16 +1076,14 @@ WITH ( MODULUS numeric_literal, REM - parallel_workers (integer) - parallel_workers storage parameter + parallel_workers 存储参数 - - 该参数设置在对该表执行并行扫描时可用于辅助扫描的工作进程数量。若未设置, + 该参数设置在对该表执行并行扫描时用于辅助扫描的工作进程数量。若未设置, 系统会根据关系大小决定一个值。规划器或使用并行扫描的实用命令实际选择的 工作进程数量可能更少,例如可能受 设置所限。 @@ -1307,10 +1092,9 @@ WITH ( MODULUS numeric_literal, REM - autovacuum_enabled, toast.autovacuum_enabled (boolean) - autovacuum_enabled storage parameter + autovacuum_enabled 存储参数 @@ -1330,10 +1114,9 @@ WITH ( MODULUS numeric_literal, REM - vacuum_index_cleanup, toast.vacuum_index_cleanup (enum) - vacuum_index_cleanup storage parameter + vacuum_index_cleanup 存储参数 @@ -1353,29 +1136,28 @@ WITH ( MODULUS numeric_literal, REM - vacuum_truncate, toast.vacuum_truncate (boolean) - vacuum_truncate - storage parameter + vacuum_truncate 存储参数 - - 参数的每表取值。若 - VACUUM 指定了 - TRUNCATE 参数,将覆盖此选项的值。 + 允许或禁止清理尝试截去该表末尾的空页。默认值为 + true。若为 true, + VACUUM 和自动清理都会执行截断,并将被截断页面占用的磁盘空间返还给操作系统。注意,截断操作需要对表持有 + ACCESS EXCLUSIVE 锁。若在 + VACUUM 中指定了 + TRUNCATE 参数,则会覆盖此选项的值。 - autovacuum_vacuum_threshold, toast.autovacuum_vacuum_threshold (integer) autovacuum_vacuum_threshold - storage parameter + 存储参数 @@ -1384,28 +1166,13 @@ WITH ( MODULUS numeric_literal, REM 参数的每表取值。 - - - - autovacuum_vacuum_max_threshold, toast.autovacuum_vacuum_max_threshold (integer) - - autovacuum_vacuum_max_threshold - storage parameter - - - - - 参数的每表取值。 - - - + - autovacuum_vacuum_scale_factor, toast.autovacuum_vacuum_scale_factor (floating point) autovacuum_vacuum_scale_factor - storage parameter + 存储参数 @@ -1417,11 +1184,10 @@ WITH ( MODULUS numeric_literal, REM - autovacuum_vacuum_insert_threshold, toast.autovacuum_vacuum_insert_threshold (integer) autovacuum_vacuum_insert_threshold - storage parameter + 存储参数 @@ -1434,11 +1200,10 @@ WITH ( MODULUS numeric_literal, REM - autovacuum_vacuum_insert_scale_factor, toast.autovacuum_vacuum_insert_scale_factor (floating point) autovacuum_vacuum_insert_scale_factor - storage parameter + 存储参数 @@ -1450,11 +1215,10 @@ WITH ( MODULUS numeric_literal, REM - autovacuum_analyze_threshold (integer) autovacuum_analyze_threshold - storage parameter + 存储参数 @@ -1466,11 +1230,10 @@ WITH ( MODULUS numeric_literal, REM - autovacuum_analyze_scale_factor (floating point) autovacuum_analyze_scale_factor - storage parameter + 存储参数 @@ -1482,11 +1245,10 @@ WITH ( MODULUS numeric_literal, REM - autovacuum_vacuum_cost_delay, toast.autovacuum_vacuum_cost_delay (floating point) autovacuum_vacuum_cost_delay - storage parameter + 存储参数 @@ -1498,11 +1260,10 @@ WITH ( MODULUS numeric_literal, REM - autovacuum_vacuum_cost_limit, toast.autovacuum_vacuum_cost_limit (integer) autovacuum_vacuum_cost_limit - storage parameter + 存储参数 @@ -1514,10 +1275,9 @@ WITH ( MODULUS numeric_literal, REM - autovacuum_freeze_min_age, toast.autovacuum_freeze_min_age (integer) - autovacuum_freeze_min_age storage parameter + autovacuum_freeze_min_age 存储参数 @@ -1531,11 +1291,10 @@ WITH ( MODULUS numeric_literal, REM - autovacuum_freeze_max_age, toast.autovacuum_freeze_max_age (integer) autovacuum_freeze_max_age - storage parameter + 存储参数 @@ -1549,10 +1308,9 @@ WITH ( MODULUS numeric_literal, REM - autovacuum_freeze_table_age, toast.autovacuum_freeze_table_age (integer) - autovacuum_freeze_table_age storage parameter + autovacuum_freeze_table_age 存储参数 @@ -1564,10 +1322,9 @@ WITH ( MODULUS numeric_literal, REM - autovacuum_multixact_freeze_min_age, toast.autovacuum_multixact_freeze_min_age (integer) - autovacuum_multixact_freeze_min_age storage parameter + autovacuum_multixact_freeze_min_age 存储参数 @@ -1582,11 +1339,10 @@ WITH ( MODULUS numeric_literal, REM - autovacuum_multixact_freeze_max_age, toast.autovacuum_multixact_freeze_max_age (integer) autovacuum_multixact_freeze_max_age - storage parameter + 存储参数 @@ -1601,10 +1357,9 @@ WITH ( MODULUS numeric_literal, REM - autovacuum_multixact_freeze_table_age, toast.autovacuum_multixact_freeze_table_age (integer) - autovacuum_multixact_freeze_table_age storage parameter + autovacuum_multixact_freeze_table_age 存储参数 @@ -1616,11 +1371,10 @@ WITH ( MODULUS numeric_literal, REM - log_autovacuum_min_duration, toast.log_autovacuum_min_duration (integer) log_autovacuum_min_duration - storage parameter + 存储参数 @@ -1629,27 +1383,12 @@ WITH ( MODULUS numeric_literal, REM 参数的每表取值。 - - - - vacuum_max_eager_freeze_failure_rate, toast.vacuum_max_eager_freeze_failure_rate (floating point) - - vacuum_max_eager_freeze_failure_rate - storage parameter - - - - - 参数的每表取值。 - - - user_catalog_table (boolean) - user_catalog_table storage parameter + user_catalog_table 存储参数 @@ -1667,11 +1406,9 @@ WITH ( MODULUS numeric_literal, REM - 注解 - - PostgreSQL为每一个唯一约束和主键约束创建一个索引来强制唯一性。因此,没有必要显式地为主键列创建一个索引(详见)。 + PostgreSQL为每一个唯一约束和主键约束自动创建一个索引来强制唯一性。因此,没有必要显式地为主键列创建一个索引(详见)。 @@ -1684,6 +1421,7 @@ WITH ( MODULUS numeric_literal, REM + 示例 @@ -1993,7 +1731,6 @@ CREATE TABLE cities_partdef - 兼容性 @@ -2081,14 +1818,8 @@ CREATE TABLE cities_partdef - 外键约束 - - 在外键动作 SET DEFAULTSET NULL - 中指定列列表的能力,是 PostgreSQL 的扩展。 - - 外键约束可以引用唯一索引的列,而不仅限于主键或唯一约束的列,这也是 PostgreSQL 的扩展。 @@ -2096,19 +1827,17 @@ CREATE TABLE cities_partdef - <literal>NULL</literal> <quote>约束</quote> NULL 约束(实际上并不是约束)是 - PostgreSQL 对 SQL 标准的扩展;它也被其他一些数 - 据库系统采纳,以便兼容(以及与对称的 NOT NULL 约束保持一 - 致)。由于它本来就是任意列的默认值,所以它的存在只是噪声。 + PostgreSQL 对 SQL 标准的扩展;提供它是为了 + 与其他一些数据库系统兼容(以及与 NOT NULL 约束保持 + 对称)。由于它本来就是任意列的默认情况,所以它的存在只是噪声。 - 约束命名 @@ -2120,6 +1849,7 @@ CREATE TABLE cities_partdef 名,而索引名称在同一模式内的所有关系之间必须唯一。 + 目前,PostgreSQL根本不会为NOT NULL约束记录名称,因此它们不受唯一性限制。这种情况可能会在未来版本中改变。 @@ -2132,38 +1862,33 @@ CREATE TABLE cities_partdef - - 零列表 + 零列的表 PostgreSQL 允许创建没有列的表(例如 CREATE TABLE foo();)。这是对 SQL 标准的扩展,标准不允许 - 零列表。零列表本身并不十分有用,但若禁止它们,就会让 + 零列的表。零列的表本身并不十分有用,但若禁止它们,就会让 ALTER TABLE DROP COLUMN 出现奇怪的特殊情况,因此忽略这 一规范限制看起来更整洁。 - 多个标识列 PostgreSQL 允许一个表拥有多个标识列。 该标准指定一个表最多只能有一个标识列。 - 这主要是为了给模式更改或迁移提供更大的灵活性。 + 放宽这一限制主要是为了给模式更改或迁移提供更大的灵活性。 请注意,INSERT 命令仅支持一个适用于整个语句的覆盖子 句,因此对行为不同的多个标识列支持并不好。 - 生成列 - - STOREDVIRTUAL 选项都不是标准的一部分,但其他 SQL 实现也会使用。SQL 标准并不规定生成列的存储方式。 - + STORED选项不是标准的一部分,但其他 SQL 实现也使用它。SQL 标准没有规定生成列的存储方式。 @@ -2200,12 +1925,10 @@ CREATE TABLE cities_partdef - 类型化表 - 类型化表实现了 SQL 标准的一个子集。按照标准,类型化表除了具有与底层组合 - 类型相对应的列之外,还应有一个额外的自引用列。 + 类型化表实现了 SQL 标准的一个子集。按照标准,类型化表除了具有与底层复合类型相对应的列之外,还应有一个额外的自引用列PostgreSQL 不显式支持自引用列。 @@ -2232,6 +1955,7 @@ CREATE TABLE cities_partdef + 另见 diff --git a/zh/14/ref/create_table_as.sgml b/zh/14/ref/create_table_as.sgml index 7d80a1f0..03a60483 100644 --- a/zh/14/ref/create_table_as.sgml +++ b/zh/14/ref/create_table_as.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation CREATE TABLE AS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/create_tablespace.sgml b/zh/14/ref/create_tablespace.sgml index 32b0dbb1..88106ccd 100644 --- a/zh/14/ref/create_tablespace.sgml +++ b/zh/14/ref/create_tablespace.sgml @@ -13,7 +13,7 @@ PostgreSQL documentation CREATE TABLESPACE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/create_transform.sgml b/zh/14/ref/create_transform.sgml index 247e6a0f..ecea2c1e 100644 --- a/zh/14/ref/create_transform.sgml +++ b/zh/14/ref/create_transform.sgml @@ -13,7 +13,7 @@ PostgreSQL documentation CREATE TRANSFORM 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/create_trigger.sgml b/zh/14/ref/create_trigger.sgml index 236c79c4..4146e2ba 100644 --- a/zh/14/ref/create_trigger.sgml +++ b/zh/14/ref/create_trigger.sgml @@ -11,13 +11,13 @@ PostgreSQL documentation 过渡表 - ephemeral named relation + 临时命名关系 CREATE TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -70,7 +70,7 @@ CREATE [ OR REPLACE ] [ CONSTRAINT ] TRIGGER name UPDATEDELETE之前); 也可以在该操作完成之后引发(即在检查约束以及完成 INSERTUPDATE或 - DELETE之后);或者改为执行该操作 + DELETE之后);或者取代该操作执行 (用于视图上的插入、更新或删除)。如果触发器在事件之前引发,或者改为取代该事件执行, 则它可以跳过对当前行的操作,或者修改待插入的行 (仅适用于INSERTUPDATE操作)。 @@ -126,7 +126,7 @@ CREATE [ OR REPLACE ] [ CONSTRAINT ] TRIGGER name TRUNCATE - 表和外部表 + @@ -139,7 +139,7 @@ CREATE [ OR REPLACE ] [ CONSTRAINT ] TRIGGER name TRUNCATE - 表和外部表 + @@ -178,7 +178,7 @@ CREATE [ OR REPLACE ] [ CONSTRAINT ] TRIGGER name 调整其引发时机。约束触发器必须是普通表(不是外部表)上的 AFTER ROW 触发器。它们既可以在导致触发事件的语句结束时引发, 也可以在包含它的事务结束时引发;后一种情况称为延迟。 - 也可以使用SET CONSTRAINTS强制挂起的延迟触发立即引发。 + 也可以使用SET CONSTRAINTS强制尚待执行的延迟触发器立即引发。 约束触发器应当在其所实现的约束遭到违反时抛出异常。 @@ -394,7 +394,7 @@ UPDATE OF column_name1 [, column_name2CREATE TRIGGER的语法中,关键字 FUNCTIONPROCEDURE 是等价的, 但无论如何,被引用的对象都必须是函数而不是过程。 - 这里使用 PROCEDURE 关键字只是出于历史原因,并且已被废弃。 + 这里使用 PROCEDURE 关键字只是出于历史原因,并且已被弃用。 diff --git a/zh/14/ref/create_tsconfig.sgml b/zh/14/ref/create_tsconfig.sgml index 52c43127..52970b36 100644 --- a/zh/14/ref/create_tsconfig.sgml +++ b/zh/14/ref/create_tsconfig.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TEXT SEARCH CONFIGURATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/create_tsdictionary.sgml b/zh/14/ref/create_tsdictionary.sgml index 7a06b430..c45a7240 100644 --- a/zh/14/ref/create_tsdictionary.sgml +++ b/zh/14/ref/create_tsdictionary.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TEXT SEARCH DICTIONARY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/create_tsparser.sgml b/zh/14/ref/create_tsparser.sgml index d0c11ba5..358152ce 100644 --- a/zh/14/ref/create_tsparser.sgml +++ b/zh/14/ref/create_tsparser.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TEXT SEARCH PARSER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/create_tstemplate.sgml b/zh/14/ref/create_tstemplate.sgml index 947b18b9..702233e4 100644 --- a/zh/14/ref/create_tstemplate.sgml +++ b/zh/14/ref/create_tstemplate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TEXT SEARCH TEMPLATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/create_type.sgml b/zh/14/ref/create_type.sgml index 45a4d93a..2e1ba18d 100644 --- a/zh/14/ref/create_type.sgml +++ b/zh/14/ref/create_type.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation CREATE TYPE 7 - SQL - Language Statements + SQL - 语言语句 @@ -96,7 +96,7 @@ CREATE TYPE name 复合类型 - 第一种形式的CREATE TYPE创建复合类型。组合 + 第一种形式的CREATE TYPE创建复合类型。复合 类型由属性名和数据类型列表指定。如果某个属性的数据类型支持排序规 则,还可以指定该属性的排序规则。复合类型本质上与表的行类型相同, 但如果目的只是定义一种类型,使用CREATE TYPE @@ -322,7 +322,7 @@ CREATE TYPE name 数才知道,但仍有若干内部表示属性必须向 PostgreSQL声明。其中最重要的是 internallength。 - 基础数据类型可以是定长的,此时internallength为正整数;也可 以是变长的,此时将internallength设为 @@ -427,7 +427,7 @@ CREATE TYPE name collatable为真,则 该类型的列定义和表达式可以通过COLLATE子句携 带排序规则信息。是否实际使用这些排序规则信息取决于操作该类型的函 - 数实现;仅仅把类型标记为 collatable 并不会自动实现这一点。 + 数实现;仅仅把类型标记为支持排序规则并不会自动实现这一点。 @@ -829,15 +829,6 @@ CREATE TYPE name 以这种方式创建 shell 类型。 - - 在PostgreSQL 16 及更高版本中,基础类 - 型的输入函数最好使用新的 - errsave()/ereturn()机 - 制返回错误,而不是像早期版本那样抛出 - ereport()异常。更多信息见 - src/backend/utils/fmgr/README。 - - @@ -876,7 +867,7 @@ CREATE TYPE float8_range AS RANGE (subtype = float8, subtype_diff = float8mi); - 这个示例创建基础数据类型box,然后在表定义中使用它: + 这个示例创建基础类型box,然后在表定义中使用它: CREATE TYPE box; diff --git a/zh/14/ref/create_user.sgml b/zh/14/ref/create_user.sgml index 218c51eb..9548a147 100644 --- a/zh/14/ref/create_user.sgml +++ b/zh/14/ref/create_user.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE USER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/create_user_mapping.sgml b/zh/14/ref/create_user_mapping.sgml index fe556318..1abe6abd 100644 --- a/zh/14/ref/create_user_mapping.sgml +++ b/zh/14/ref/create_user_mapping.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE USER MAPPING 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/create_view.sgml b/zh/14/ref/create_view.sgml index 80c6d1ab..292b1a4b 100644 --- a/zh/14/ref/create_view.sgml +++ b/zh/14/ref/create_view.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation CREATE VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/createdb.sgml b/zh/14/ref/createdb.sgml index 554d7377..d81095ee 100644 --- a/zh/14/ref/createdb.sgml +++ b/zh/14/ref/createdb.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation createdb 1 - Application + 应用程序 @@ -114,12 +114,7 @@ PostgreSQL documentation - - - 指定该数据库要使用的区域设置。这等同于为、 - 指定相同的值。 - 某些区域设置仅对 ICU 有效,必须通过设置。 - + 指定此数据库要使用的区域设置。这相当于同时指定 @@ -143,44 +138,13 @@ PostgreSQL documentation - - - - - 当使用 builtin 提供程序时,指定区域设置名称。区域设置支持的说明见 - 。 - - - - - - - - 如果选择了 ICU 区域设置提供程序,则指定该数据库要使用的 ICU 区域设置 ID。 - - - - - - - - 指定附加的排序规则,用以定制该数据库默认排序规则的行为。该选项仅支持 ICU。 - - - - - - - - 指定数据库默认排序规则所使用的区域设置提供程序。 - - - + + @@ -194,16 +158,6 @@ PostgreSQL documentation - - - - - - - 指定数据库创建策略。详见。 - - - diff --git a/zh/14/ref/createuser.sgml b/zh/14/ref/createuser.sgml index 0451cadd..9c8b0f3a 100644 --- a/zh/14/ref/createuser.sgml +++ b/zh/14/ref/createuser.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation createuser 1 - Application + 应用程序 @@ -70,16 +70,7 @@ PostgreSQL documentation - - - - - - 指定一个现有角色,使其自动作为带有 ADMIN OPTION 的成员加入新角色,从而有权将新角色的成员资格授予其他角色。 - 可以通过写多个开关来指定多个现有角色。 - - - + @@ -138,14 +129,10 @@ PostgreSQL documentation - - (已废弃) + - - 指定新角色应自动成为指定现有角色的成员。 - 可以通过写多个开关来指定多个现有角色。 - + 指定此角色应立即作为新成员加入的现有角色。可以使用多个开关,指定此角色要加入的多个角色。 @@ -210,16 +197,7 @@ PostgreSQL documentation - - - - - - 指定一个现有角色,使其自动作为成员加入新角色。 - 可以通过写多个开关来指定多个现有角色。 - - - + @@ -239,7 +217,7 @@ PostgreSQL documentation - 允许新用户创建、更改、删除其他角色,对其添加注释,以及更改其安全标签;也就是说, + 允许新用户创建、更改、删除其他角色,对其添加注释,更改其安全标签,以及授予或撤销其他角色的成员资格;也就是说, 该用户将具有CREATEROLE权限。 关于该权限赋予哪些能力的更多细节,见 @@ -279,16 +257,7 @@ PostgreSQL documentation - - - - - - 设置一个日期和时间,在此之后该角色的密码将不再有效。 - 默认不设置密码过期日期。 - - - + @@ -301,23 +270,9 @@ PostgreSQL documentation - - - - - 新用户将绕过每一条行级安全(RLS)策略。 - - - - - - - - 新用户将不会绕过行级安全(RLS)策略。这是默认设置。 - - - + + @@ -336,7 +291,7 @@ PostgreSQL documentation 新用户将不具有REPLICATION权限,关于该权限的更完整说明见。这是默认设置。 + linkend="sql-createrole"/>。 @@ -502,7 +457,7 @@ PostgreSQL documentation $ createuser -P -s -e joe Enter password for new role: xyzzy Enter it again: xyzzy -CREATE ROLE joe PASSWORD 'SCRAM-SHA-256$4096:44560wPMLfjqiAzyPDZ/eQ==$4CA054rZlSFEq8Z3FEhToBTa2X6KnWFxFkPwIbKoDe0=:L/nbSZRCjp6RhOhKK56GoR1zibCCSePKshCJ9lnl3yw=' SUPERUSER CREATEDB CREATEROLE INHERIT LOGIN NOREPLICATION NOBYPASSRLS; +CREATE ROLE joe PASSWORD 'SCRAM-SHA-256$4096:44560wPMLfjqiAzyPDZ/eQ==$4CA054rZlSFEq8Z3FEhToBTa2X6KnWFxFkPwIbKoDe0=:L/nbSZRCjp6RhOhKK56GoR1zibCCSePKshCJ9lnl3yw=' SUPERUSER CREATEDB CREATEROLE INHERIT LOGIN; 在上面的示例中,输入新密码时实际上不会回显它,但为清楚起见,这里展示了输入的内容。 可以看到,该密码在发送给客户端之前就已经被加密了。 @@ -516,7 +471,6 @@ PostgreSQL documentation - diff --git a/zh/14/ref/deallocate.sgml b/zh/14/ref/deallocate.sgml index 27b9da86..6dea341e 100644 --- a/zh/14/ref/deallocate.sgml +++ b/zh/14/ref/deallocate.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation DEALLOCATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/declare.sgml b/zh/14/ref/declare.sgml index ed389e4d..9276a0e3 100644 --- a/zh/14/ref/declare.sgml +++ b/zh/14/ref/declare.sgml @@ -22,7 +22,7 @@ PostgreSQL documentation DECLARE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/delete.sgml b/zh/14/ref/delete.sgml index 4a79783c..653e86a2 100644 --- a/zh/14/ref/delete.sgml +++ b/zh/14/ref/delete.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DELETE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/discard.sgml b/zh/14/ref/discard.sgml index 29d4ea8d..f6572252 100644 --- a/zh/14/ref/discard.sgml +++ b/zh/14/ref/discard.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DISCARD 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/do.sgml b/zh/14/ref/do.sgml index 2ea6566a..cdbf189e 100644 --- a/zh/14/ref/do.sgml +++ b/zh/14/ref/do.sgml @@ -15,7 +15,7 @@ PostgreSQL documentation DO 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/drop_access_method.sgml b/zh/14/ref/drop_access_method.sgml index 407ec4cd..646100e1 100644 --- a/zh/14/ref/drop_access_method.sgml +++ b/zh/14/ref/drop_access_method.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP ACCESS METHOD 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/drop_aggregate.sgml b/zh/14/ref/drop_aggregate.sgml index 1c8a1122..9fd7ea4b 100644 --- a/zh/14/ref/drop_aggregate.sgml +++ b/zh/14/ref/drop_aggregate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP AGGREGATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/drop_cast.sgml b/zh/14/ref/drop_cast.sgml index 73860e3c..5e330ae0 100644 --- a/zh/14/ref/drop_cast.sgml +++ b/zh/14/ref/drop_cast.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP CAST 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/drop_collation.sgml b/zh/14/ref/drop_collation.sgml index b90849fc..b10b3206 100644 --- a/zh/14/ref/drop_collation.sgml +++ b/zh/14/ref/drop_collation.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP COLLATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/drop_conversion.sgml b/zh/14/ref/drop_conversion.sgml index b63d1291..35009708 100644 --- a/zh/14/ref/drop_conversion.sgml +++ b/zh/14/ref/drop_conversion.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP CONVERSION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/drop_database.sgml b/zh/14/ref/drop_database.sgml index 9bbd949f..10817b69 100644 --- a/zh/14/ref/drop_database.sgml +++ b/zh/14/ref/drop_database.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP DATABASE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/drop_domain.sgml b/zh/14/ref/drop_domain.sgml index d43f95c6..b292b189 100644 --- a/zh/14/ref/drop_domain.sgml +++ b/zh/14/ref/drop_domain.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP DOMAIN 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/drop_event_trigger.sgml b/zh/14/ref/drop_event_trigger.sgml index 80020f78..f4f0053f 100644 --- a/zh/14/ref/drop_event_trigger.sgml +++ b/zh/14/ref/drop_event_trigger.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP EVENT TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -30,7 +30,7 @@ DROP EVENT TRIGGER [ IF EXISTS ] name DROP EVENT TRIGGER移除一个现有的事件触发器。 - 要执行此命令,当前用户必须是该事件触发器的拥有者。 + 要执行此命令,当前用户必须是该事件触发器的所有者。 @@ -99,7 +99,7 @@ DROP EVENT TRIGGER snitch; - 另见 + 参见 diff --git a/zh/14/ref/drop_extension.sgml b/zh/14/ref/drop_extension.sgml index 5eb04c04..ccccb0b1 100644 --- a/zh/14/ref/drop_extension.sgml +++ b/zh/14/ref/drop_extension.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP EXTENSION 7 - SQL - Language Statements + SQL - 语言语句 @@ -59,8 +59,8 @@ DROP EXTENSION [ IF EXISTS ] name [ name - 已安装扩展的名称。 - + 一个已安装扩展的名称。 + @@ -95,7 +95,7 @@ DROP EXTENSION [ IF EXISTS ] name [ DROP EXTENSION hstore; - 如果数据库中正在使用hstore的任何对象, + 如果数据库中使用了hstore的任何对象, 例如某些表具有hstore类型的列,则该命令会失败。 加上CASCADE选项可以强制一并移除这些依赖对象。 diff --git a/zh/14/ref/drop_foreign_data_wrapper.sgml b/zh/14/ref/drop_foreign_data_wrapper.sgml index 9902c875..6f781f31 100644 --- a/zh/14/ref/drop_foreign_data_wrapper.sgml +++ b/zh/14/ref/drop_foreign_data_wrapper.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP FOREIGN DATA WRAPPER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/drop_foreign_table.sgml b/zh/14/ref/drop_foreign_table.sgml index 0b4d0bbd..c420e4ba 100644 --- a/zh/14/ref/drop_foreign_table.sgml +++ b/zh/14/ref/drop_foreign_table.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP FOREIGN TABLE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/drop_function.sgml b/zh/14/ref/drop_function.sgml index 32e1de58..f80cc1d8 100644 --- a/zh/14/ref/drop_function.sgml +++ b/zh/14/ref/drop_function.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP FUNCTION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/drop_group.sgml b/zh/14/ref/drop_group.sgml index f43389ca..4ee8fc55 100644 --- a/zh/14/ref/drop_group.sgml +++ b/zh/14/ref/drop_group.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP GROUP 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/drop_index.sgml b/zh/14/ref/drop_index.sgml index b65b810b..d7f892d9 100644 --- a/zh/14/ref/drop_index.sgml +++ b/zh/14/ref/drop_index.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP INDEX 7 - SQL - Language Statements + SQL - 语言语句 @@ -57,7 +57,7 @@ DROP INDEX [ CONCURRENTLY ] [ IF EXISTS ] name 对于临时表,DROP INDEX始终是非并发的, - 因为没有其他会话可以访问它们,而且非并发删除索引的成本更低。 + 因为没有其他会话可以访问它们,而且非并发删除索引的代价更低。 @@ -66,7 +66,7 @@ DROP INDEX [ CONCURRENTLY ] [ IF EXISTS ] nameIF EXISTS - 如果该索引不存在,则不要抛出错误。这种情况下会发出一个提示。 + 如果该索引不存在,则不要抛出错误。这种情况下会发出一条提示。 diff --git a/zh/14/ref/drop_language.sgml b/zh/14/ref/drop_language.sgml index 9696f612..8fb4de3f 100644 --- a/zh/14/ref/drop_language.sgml +++ b/zh/14/ref/drop_language.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP LANGUAGE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/drop_materialized_view.sgml b/zh/14/ref/drop_materialized_view.sgml index f3682552..71ad4326 100644 --- a/zh/14/ref/drop_materialized_view.sgml +++ b/zh/14/ref/drop_materialized_view.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP MATERIALIZED VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/drop_opclass.sgml b/zh/14/ref/drop_opclass.sgml index c3dd2e74..9d67dc64 100644 --- a/zh/14/ref/drop_opclass.sgml +++ b/zh/14/ref/drop_opclass.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP OPERATOR CLASS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/drop_operator.sgml b/zh/14/ref/drop_operator.sgml index 3cfb069c..19e93d4e 100644 --- a/zh/14/ref/drop_operator.sgml +++ b/zh/14/ref/drop_operator.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP OPERATOR 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/drop_opfamily.sgml b/zh/14/ref/drop_opfamily.sgml index 8e7097f9..06223045 100644 --- a/zh/14/ref/drop_opfamily.sgml +++ b/zh/14/ref/drop_opfamily.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP OPERATOR FAMILY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/drop_owned.sgml b/zh/14/ref/drop_owned.sgml index 2bc659bf..7f3c40ae 100644 --- a/zh/14/ref/drop_owned.sgml +++ b/zh/14/ref/drop_owned.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP OWNED 7 - SQL - Language Statements + SQL - 语言语句 @@ -31,7 +31,7 @@ DROP OWNED BY { name | CURRENT_ROLE DROP OWNED删除当前数据库中由指定角色之一拥有的所有对象。 同时,授予给这些角色的、针对当前数据库中的对象或共享对象 - (数据库、表空间、配置参数)的任何权限也会被撤销。 + (数据库、表空间)的任何权限也会被撤销。 diff --git a/zh/14/ref/drop_policy.sgml b/zh/14/ref/drop_policy.sgml index ee64ffa0..a939a688 100644 --- a/zh/14/ref/drop_policy.sgml +++ b/zh/14/ref/drop_policy.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP POLICY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/drop_procedure.sgml b/zh/14/ref/drop_procedure.sgml index 178e6684..19708931 100644 --- a/zh/14/ref/drop_procedure.sgml +++ b/zh/14/ref/drop_procedure.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP PROCEDURE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/drop_publication.sgml b/zh/14/ref/drop_publication.sgml index 6bc4bf59..048c1756 100644 --- a/zh/14/ref/drop_publication.sgml +++ b/zh/14/ref/drop_publication.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP PUBLICATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/drop_role.sgml b/zh/14/ref/drop_role.sgml index 6f3dd022..9fbfa99e 100644 --- a/zh/14/ref/drop_role.sgml +++ b/zh/14/ref/drop_role.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP ROLE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/drop_routine.sgml b/zh/14/ref/drop_routine.sgml index 4f2be77f..db15d5d2 100644 --- a/zh/14/ref/drop_routine.sgml +++ b/zh/14/ref/drop_routine.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP ROUTINE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/drop_rule.sgml b/zh/14/ref/drop_rule.sgml index ddb561f4..2968d946 100644 --- a/zh/14/ref/drop_rule.sgml +++ b/zh/14/ref/drop_rule.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP RULE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/drop_schema.sgml b/zh/14/ref/drop_schema.sgml index 9f622df3..94843c9a 100644 --- a/zh/14/ref/drop_schema.sgml +++ b/zh/14/ref/drop_schema.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP SCHEMA 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/drop_sequence.sgml b/zh/14/ref/drop_sequence.sgml index 4ba78640..586d3038 100644 --- a/zh/14/ref/drop_sequence.sgml +++ b/zh/14/ref/drop_sequence.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP SEQUENCE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/drop_server.sgml b/zh/14/ref/drop_server.sgml index 0864a4c2..8bdacdc8 100644 --- a/zh/14/ref/drop_server.sgml +++ b/zh/14/ref/drop_server.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP SERVER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/drop_statistics.sgml b/zh/14/ref/drop_statistics.sgml index 3120dc06..4773bfa8 100644 --- a/zh/14/ref/drop_statistics.sgml +++ b/zh/14/ref/drop_statistics.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP STATISTICS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/drop_subscription.sgml b/zh/14/ref/drop_subscription.sgml index 67421595..01a6c5f0 100644 --- a/zh/14/ref/drop_subscription.sgml +++ b/zh/14/ref/drop_subscription.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP SUBSCRIPTION 7 - SQL - Language Statements + SQL - 语言语句 @@ -32,14 +32,12 @@ DROP SUBSCRIPTION [ IF EXISTS ] nameDROP SUBSCRIPTION从数据库集簇中移除一个订阅。 - - 要执行此命令,用户必须是该订阅的拥有者。 - + 只有超级用户才能删除订阅。 如果该订阅与复制槽相关联,则不能在事务块内执行 DROP SUBSCRIPTION。 - (可以使用ALTER SUBSCRIPTION + (可以使用ALTER SUBSCRIPTION 来取消设置该槽。) @@ -90,11 +88,9 @@ DROP SUBSCRIPTION [ IF EXISTS ] nameDROP SUBSCRIPTION命令都会失败。 要在这种情况下继续,首先执行 - - ALTER SUBSCRIPTION ... DISABLE + ALTER SUBSCRIPTION ... DISABLE 禁用订阅,然后执行 - - ALTER SUBSCRIPTION ... SET (slot_name = NONE) + ALTER SUBSCRIPTION ... SET (slot_name = NONE) 将其与复制槽解除关联。此后,DROP SUBSCRIPTION将不会尝试删除订阅自身的复制槽。 如果还有某些表同步尚未完成,它仍可能连接到发布者,以删除由系统内部创建的表同步槽; 如果发布者不可达,则必须手工删除这些槽(以及仍然存在的主复制槽)。否则,这些槽会继续保留 WAL, diff --git a/zh/14/ref/drop_table.sgml b/zh/14/ref/drop_table.sgml index a2634c54..bdfbabf4 100644 --- a/zh/14/ref/drop_table.sgml +++ b/zh/14/ref/drop_table.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TABLE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/drop_tablespace.sgml b/zh/14/ref/drop_tablespace.sgml index c8b09e59..a31fd70f 100644 --- a/zh/14/ref/drop_tablespace.sgml +++ b/zh/14/ref/drop_tablespace.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TABLESPACE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/drop_transform.sgml b/zh/14/ref/drop_transform.sgml index be84b60c..09a3c9c7 100644 --- a/zh/14/ref/drop_transform.sgml +++ b/zh/14/ref/drop_transform.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TRANSFORM 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/drop_trigger.sgml b/zh/14/ref/drop_trigger.sgml index 1f85cf41..160a5ebd 100644 --- a/zh/14/ref/drop_trigger.sgml +++ b/zh/14/ref/drop_trigger.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -30,7 +30,7 @@ DROP TRIGGER [ IF EXISTS ] name ON DROP TRIGGER移除一个现有触发器的定义。 - 要执行此命令,当前用户必须是定义该触发器的表的拥有者。 + 要执行此命令,当前用户必须是定义该触发器的表的所有者。 @@ -109,7 +109,7 @@ DROP TRIGGER if_dist_exists ON films; - 另见 + 参见 diff --git a/zh/14/ref/drop_tsconfig.sgml b/zh/14/ref/drop_tsconfig.sgml index 2a7cdc52..ea139802 100644 --- a/zh/14/ref/drop_tsconfig.sgml +++ b/zh/14/ref/drop_tsconfig.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TEXT SEARCH CONFIGURATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/drop_tsdictionary.sgml b/zh/14/ref/drop_tsdictionary.sgml index 1eb24189..316c5d00 100644 --- a/zh/14/ref/drop_tsdictionary.sgml +++ b/zh/14/ref/drop_tsdictionary.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TEXT SEARCH DICTIONARY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/drop_tsparser.sgml b/zh/14/ref/drop_tsparser.sgml index 0cfa7acd..a65f47be 100644 --- a/zh/14/ref/drop_tsparser.sgml +++ b/zh/14/ref/drop_tsparser.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TEXT SEARCH PARSER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/drop_tstemplate.sgml b/zh/14/ref/drop_tstemplate.sgml index 282231c5..fa1faab0 100644 --- a/zh/14/ref/drop_tstemplate.sgml +++ b/zh/14/ref/drop_tstemplate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TEXT SEARCH TEMPLATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/drop_type.sgml b/zh/14/ref/drop_type.sgml index dab5bfa0..2f139da5 100644 --- a/zh/14/ref/drop_type.sgml +++ b/zh/14/ref/drop_type.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TYPE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/drop_user.sgml b/zh/14/ref/drop_user.sgml index 00d1d5f4..2e61d6ef 100644 --- a/zh/14/ref/drop_user.sgml +++ b/zh/14/ref/drop_user.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP USER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/drop_user_mapping.sgml b/zh/14/ref/drop_user_mapping.sgml index 2a79a65b..d23b0a16 100644 --- a/zh/14/ref/drop_user_mapping.sgml +++ b/zh/14/ref/drop_user_mapping.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP USER MAPPING 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/drop_view.sgml b/zh/14/ref/drop_view.sgml index 4feb47e5..8f995245 100644 --- a/zh/14/ref/drop_view.sgml +++ b/zh/14/ref/drop_view.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/dropdb.sgml b/zh/14/ref/dropdb.sgml index 70ad776f..10f79ed2 100644 --- a/zh/14/ref/dropdb.sgml +++ b/zh/14/ref/dropdb.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation dropdb 1 - Application + 应用程序 diff --git a/zh/14/ref/dropuser.sgml b/zh/14/ref/dropuser.sgml index 55aa53fa..3cdd48c0 100644 --- a/zh/14/ref/dropuser.sgml +++ b/zh/14/ref/dropuser.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation dropuser 1 - Application + 应用程序 diff --git a/zh/14/ref/ecpg-ref.sgml b/zh/14/ref/ecpg-ref.sgml index 002b8ef1..506be589 100644 --- a/zh/14/ref/ecpg-ref.sgml +++ b/zh/14/ref/ecpg-ref.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ecpg 1 - Application + 应用程序 diff --git a/zh/14/ref/end.sgml b/zh/14/ref/end.sgml index d042a740..10947ab0 100644 --- a/zh/14/ref/end.sgml +++ b/zh/14/ref/end.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation END 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/execute.sgml b/zh/14/ref/execute.sgml index 2aed0669..5e7274ff 100644 --- a/zh/14/ref/execute.sgml +++ b/zh/14/ref/execute.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation EXECUTE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/explain.sgml b/zh/14/ref/explain.sgml index 5d6ad75a..bb06dcca 100644 --- a/zh/14/ref/explain.sgml +++ b/zh/14/ref/explain.sgml @@ -21,7 +21,7 @@ PostgreSQL documentation EXPLAIN 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/fetch.sgml b/zh/14/ref/fetch.sgml index 71c12406..9ab88c49 100644 --- a/zh/14/ref/fetch.sgml +++ b/zh/14/ref/fetch.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation FETCH 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/grant.sgml b/zh/14/ref/grant.sgml index 90d2b6aa..8768a424 100644 --- a/zh/14/ref/grant.sgml +++ b/zh/14/ref/grant.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation GRANT 7 - SQL - Language Statements + SQL - 语言语句 @@ -22,7 +22,7 @@ PostgreSQL documentation -GRANT { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER | MAINTAIN } +GRANT { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER } [, ...] | ALL [ PRIVILEGES ] } ON { [ TABLE ] table_name [, ...] | ALL TABLES IN SCHEMA schema_name [, ...] } @@ -78,10 +78,6 @@ GRANT { { SELECT | UPDATE } [, ...] | ALL [ PRIVILEGES ] } TO role_specification [, ...] [ WITH GRANT OPTION ] [ GRANTED BY role_specification ] -GRANT { { SET | ALTER SYSTEM } [, ... ] | ALL [ PRIVILEGES ] } - ON PARAMETER configuration_parameter [, ...] - TO role_specification [, ...] [ WITH GRANT OPTION ] - [ GRANTED BY role_specification ] GRANT { { CREATE | USAGE } [, ...] | ALL [ PRIVILEGES ] } ON SCHEMA schema_name [, ...] @@ -99,10 +95,10 @@ GRANT { USAGE | ALL [ PRIVILEGES ] } [ GRANTED BY role_specification ] GRANT role_name [, ...] TO role_specification [, ...] - [ WITH { ADMIN | INHERIT | SET } { OPTION | TRUE | FALSE } ] + [ WITH ADMIN OPTION ] [ GRANTED BY role_specification ] -where role_specification can be: +其中role_specification可以是: [ GROUP ] role_name | PUBLIC @@ -117,7 +113,7 @@ GRANT role_name [, ...] TO 描述 - GRANT 命令有两个基本变体:一种是在数据库对象(表、列、视图、外部表、序列、数据库、外部数据包装器、外部服务器、函数、过程、过程语言、大对象、配置参数、模式、表空间或类型)上授予权限,另一种是授予角色成员资格。这两种变体在许多方面相似,但差异也足够大,因此分别说明。 + GRANT 命令有两个基本变体:一种是在数据库对象(表、列、视图、外部表、序列、数据库、外部数据包装器、外部服务器、函数、过程、过程语言、模式或表空间)上授予权限,另一种是授予角色成员资格。这两种变体在许多方面相似,但差异也足够大,因此分别说明。 @@ -165,9 +161,6 @@ GRANT role_name [, ...] TO TEMPORARY EXECUTE USAGE - SET - ALTER SYSTEM - MAINTAIN 具体的权限类型见 。 @@ -207,39 +200,23 @@ GRANT role_name [, ...] TO - 角色上的 GRANT - 这种 GRANT 命令变体把一个角色的成员资格授予一个或多个其他角色,并修改成员资格选项 SETINHERITADMIN;详见 。角色成员资格之所以重要,是因为它可能使成员能够访问授予给该角色的权限,也可能使其能够对该角色本身作出更改。不过,实际赋予的权限取决于该授权所关联的选项。要修改现有成员资格的这些选项,只需再次指定该成员资格并给出更新后的选项值即可。 - - - - 下面描述的每个选项都可以设为 TRUEFALSE。关键字 OPTION 可作为 TRUE 的同义词,因此 WITH ADMIN OPTION 等同于 WITH ADMIN TRUE。修改现有成员资格时,省略某个选项表示保留其当前值。 - - - - ADMIN 选项允许成员随后将该角色的成员资格授予其他人,也允许撤销该角色中的成员资格。没有该选项时,普通用户不能这样做。角色不被视为在其自身上持有 WITH ADMIN OPTION。数据库超级用户可以向任何人授予或撤销任何角色的成员资格。该选项默认为 FALSE。 - - - - INHERIT 选项控制新成员资格的继承状态;有关继承的细节见 。如果设为 TRUE,会使新成员从被授予的角色继承权限;如果设为 FALSE,新成员就不会继承。创建新的角色成员资格时,如果未指定该选项,则默认采用新成员的继承属性。 - - - - 如果 SET 选项设为 TRUE,成员就可以使用SET ROLE 命令切换到被授予的角色。如果一个角色是另一个角色的间接成员,那么只有在整条授权链上的每一次授权都带有 SET TRUE 时,它才能使用 SET ROLE 切换到该角色。该选项默认为 TRUE。 + 这种GRANT命令变体把一个角色的成员资格授予一个或多个其他角色。角色成员资格之所以重要,是因为它会把授予该角色的权限传递给其每个成员。 - 若要创建由其他角色拥有的对象,或把现有对象的所有权赋给其他角色,必须具备切换为该角色的能力,即能够对该角色执行 SET ROLE;否则,诸如 ALTER ... OWNER TOCREATE DATABASE ... OWNER 之类的命令都会失败。不过,一个继承了某角色权限但不能对其执行 SET ROLE 的用户,仍可能通过操纵该角色拥有的现有对象而获得对该角色的完全访问能力(例如,可以把现有函数重定义为特洛伊木马)。因此,如果某个角色的权限应当可继承,但不应通过 SET ROLE 访问,那么它就不应拥有任何 SQL 对象。 + 如果指定了WITH ADMIN OPTION,成员就可以将该角色的成员资格继续授予其他人,也可以撤销该角色的成员资格。没有管理选项时,普通用户不能这样做。一个角色不被认为在其自身上持有WITH ADMIN + OPTION,但是在会话用户与该角色相符的数据库会话中,它可以把自身角色的成员资格授予其他角色,或撤销这种资格。数据库超级用户可以向任何人授予或撤销任何角色的成员资格。具有CREATEROLE权限的角色可以授予或撤销任何非超级用户角色的成员资格。 - 如果指定了 GRANTED BY,该授权会被记录为由指定角色执行。只有在用户拥有该角色权限时,才能把授权记为来自另一个角色。除非该角色是引导超级用户,否则被记录为授权者的角色必须对目标角色持有 ADMIN OPTION。当授权被记录为由引导超级用户以外的某个授权者发出时,该授权依赖于授权者继续持有该角色上的 ADMIN OPTION;因此,如果 ADMIN OPTION 被撤销,依赖的授权也必须一并撤销。 + 如果指定了GRANTED BY,该授权会记录为由指定角色执行。只有数据库超级用户可以使用此选项,除非指定的是执行命令的同一角色。 - 与权限的情况不同,角色成员资格不能授予给 PUBLIC。还要注意,这种形式的命令不允许在 role_specification 中使用噪声词 GROUP。 + 与权限不同,角色成员资格不能授予PUBLIC。还要注意,这种形式的命令不允许把无实际作用的GROUP一词用于role_specification中。 @@ -269,7 +246,7 @@ GRANT role_name [, ...] TO - 如果超级用户选择执行 GRANTREVOKE 命令,该命令会像由受影响对象的拥有者发出一样执行。特别是,通过这种命令授予的权限看起来会像是由对象拥有者授予的。(对于角色成员资格,则看起来像是由引导超级用户授予的。) + 如果超级用户选择执行 GRANTREVOKE 命令,该命令会像由受影响对象的拥有者发出一样执行。特别是,通过这种命令授予的权限看起来会像是由对象拥有者授予的。(对于角色成员资格,则看起来像是由被授予成员资格的角色本身授予的。) @@ -348,7 +325,7 @@ GRANT admins TO joe; - 数据库、表空间、模式、语言以及配置参数上的权限都是 PostgreSQL 扩展。 + 数据库、表空间、模式和语言上的权限都是 PostgreSQL 扩展。 diff --git a/zh/14/ref/import_foreign_schema.sgml b/zh/14/ref/import_foreign_schema.sgml index 6e912201..1957d60a 100644 --- a/zh/14/ref/import_foreign_schema.sgml +++ b/zh/14/ref/import_foreign_schema.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation IMPORT FOREIGN SCHEMA 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/initdb.sgml b/zh/14/ref/initdb.sgml index 4b0066f1..134e90ed 100644 --- a/zh/14/ref/initdb.sgml +++ b/zh/14/ref/initdb.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation initdb 1 - Application + 应用程序 @@ -74,37 +74,15 @@ PostgreSQL documentation - initdb会初始化数据库集簇的默认区域设置和字符集编码。这些设置也可以在 - 创建每个数据库时分别设置。initdb为模板数据库确定这些设置,它们将 - 作为所有其他数据库的默认值。 + initdb会初始化数据库集簇的默认区域设置和字符集编码。字符集编码、排序顺序(LC_COLLATE)和字符集分类(LC_CTYPE,例如大写、小写、数字)可以在创建数据库时单独设置。initdbtemplate1数据库确定这些设置,它们将作为所有其他数据库的默认值。 - 默认情况下,initdb使用libc区域设置提供程序 - (见)。libc区域设置提供程序会 - 从环境中获取区域设置,并根据区域设置确定编码。 + 要更改默认排序顺序或字符集分类,请使用选项。使用CPOSIX之外的排序顺序也会带来性能损失。因此,在运行initdb时选择正确的区域设置很重要。 - 要为集簇选择不同的区域设置,请使用。此外还有单独的 - 选项(见下文),用于为各个 - 区域设置类别设置值。请注意,不同区域设置类别之间若设置不一致,可能产生不合理的结果,因此应谨慎使用。 - - - - 另一种方式是指定--locale-provider=icu,让initdb - 使用 ICU 库提供区域设置服务。服务器必须在构建时启用 ICU 支持。要选择具体要应用的 ICU - 区域设置 ID,请使用。请注意,出于实现原因以及对旧代码的支持, - 在使用 ICU 区域设置提供程序时,initdb仍会选择并初始化 libc 区域设置。 - - - - initdb运行时会打印出它选择的区域设置。如果有复杂需求或者指定了多个选项, - 建议检查结果是否符合预期。 - - - - 有关区域设置的更多细节见。 + 其余区域设置类别可以在以后启动服务器时更改。还可以使用设置所有区域设置类别的默认值,包括排序顺序和字符集分类。所有服务器区域设置值(lc_*)都可以通过SHOW ALL显示。更多细节见 @@ -178,16 +156,7 @@ PostgreSQL documentation - 选择模板数据库的编码。这也将成为以后创建的任何数据库的默认编码,除非在创建时覆盖它。 - PostgreSQL服务器支持的字符集见 - 。 - - - 默认情况下,模板数据库的编码从区域设置派生。如果指定了 - (或者等价地,区域设置为 - CPOSIX),那么 ICU 提供程序的默认值为 - UTF8,而 libc 提供程序的默认值为 - SQL_ASCII。 + 选择模板数据库的编码。这也会成为以后创建的任何数据库的默认编码,除非在创建时覆盖它。默认值由区域设置推导而来,如果无法推导,则使用SQL_ASCIIPostgreSQL服务器支持的字符集在中介绍。 @@ -204,24 +173,9 @@ PostgreSQL documentation - - - - - 当使用 ICU 提供程序时,指定 ICU 区域设置 ID。区域设置支持见 - 。 - - - - - - - - 指定附加的排序规则,以定制默认排序规则的行为。该选项仅支持 ICU。 - - - + + @@ -250,12 +204,6 @@ PostgreSQL documentation initdb运行时所在的环境。区域设置支持见 - - 如果builtin, - 则必须指定, - 并将其设置为CC.UTF-8或 - PG_UNICODE_FAST。 - @@ -283,26 +231,9 @@ PostgreSQL documentation - - - - - 当使用 builtin 提供程序时,指定区域设置名称。区域设置支持见 - 。 - - - - - - - - 该选项设置新集簇中创建的数据库所使用的区域设置提供程序。后续创建新数据库时, - 可以在CREATE DATABASE命令中覆盖它。默认值为 - libc(见)。 - - - + + diff --git a/zh/14/ref/insert.sgml b/zh/14/ref/insert.sgml index 8ad8cff2..5acfb9c0 100644 --- a/zh/14/ref/insert.sgml +++ b/zh/14/ref/insert.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation INSERT 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/listen.sgml b/zh/14/ref/listen.sgml index 0a7c6e23..7451cf82 100644 --- a/zh/14/ref/listen.sgml +++ b/zh/14/ref/listen.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation LISTEN 7 - SQL - Language Statements + SQL - 语言语句 @@ -129,7 +129,6 @@ Asynchronous notification "virtual" received from server process with PID 8448. - diff --git a/zh/14/ref/load.sgml b/zh/14/ref/load.sgml index bb0adb7c..89bdb114 100644 --- a/zh/14/ref/load.sgml +++ b/zh/14/ref/load.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation LOAD 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/lock.sgml b/zh/14/ref/lock.sgml index bc45eec4..b48bb23a 100644 --- a/zh/14/ref/lock.sgml +++ b/zh/14/ref/lock.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation LOCK 7 - SQL - Language Statements + SQL - 语言语句 @@ -55,7 +55,7 @@ LOCK [ TABLE ] [ ONLY ] name [ * ] 因为SHARE锁模式与写入者获取的ROW EXCLUSIVE锁冲突, 而LOCK TABLE name IN SHARE MODE - 语句会一直等待,直到任何并发持有ROW EXCLUSIVE模式锁的事务提交或回滚。 + 语句会一直等待,直到所有并发持有ROW EXCLUSIVE模式锁的事务提交或回滚。 因此,一旦获得该锁,就不存在尚未提交的写入;而且在释放该锁之前,也不会有新的写入开始。 @@ -136,21 +136,12 @@ LOCK [ TABLE ] [ ONLY ] name [ * ] 注解 - 要锁定一个表,用户必须拥有与所指定lockmode对应的权限。 - 如果用户在该表上拥有MAINTAINUPDATE、 - DELETETRUNCATE权限,则允许使用任意 - lockmode。 - 如果用户在该表上拥有INSERT权限,则允许使用ROW EXCLUSIVE MODE - (或冲突更少的锁模式,见)。 - 如果用户在该表上拥有SELECT权限,则允许使用ACCESS SHARE MODE。 + LOCK TABLE ... IN ACCESS SHARE MODE要求对目标表具有SELECT权限。LOCK TABLE ... IN ROW EXCLUSIVE + MODE要求对目标表具有INSERTUPDATEDELETETRUNCATE权限。所有其他形式的LOCK都要求具有表级UPDATEDELETETRUNCATE权限。 - 在视图上执行锁定操作的用户必须对该视图拥有相应权限。此外,默认情况下, - 视图所有者必须对底层基关系拥有相关权限,而执行锁定操作的用户不需要对底层基关系拥有任何权限。 - 但是,如果视图的security_invoker设置为true - (参见CREATE VIEW), - 那么必须由执行锁定操作的用户而不是视图所有者,对底层基关系拥有相关权限。 + 在视图上执行锁定操作的用户必须对该视图拥有相应权限。此外,视图所有者必须对底层基关系拥有相关权限,而执行锁定操作的用户不需要对底层基关系拥有任何权限。 @@ -166,9 +157,7 @@ LOCK [ TABLE ] [ ONLY ] name [ * ] 这些模式名称通常应理解为:用户打算在被锁定的表中获取行级锁。 此外,ROW EXCLUSIVE模式本身也是一种可共享的表锁。 请记住,就LOCK TABLE而言,所有锁模式的语义完全相同, - 差别只在于哪些模式彼此冲突。关于如何获取真正的行级锁,请参阅 - 文档中的和 - 。 + 差别只在于哪些模式彼此冲突。关于如何获取真正的行级锁,请参阅 (后者位于文档中)。 diff --git a/zh/14/ref/merge.sgml b/zh/14/ref/merge.sgml deleted file mode 100644 index c57732bd..00000000 --- a/zh/14/ref/merge.sgml +++ /dev/null @@ -1,683 +0,0 @@ - - - - - MERGE - - - - MERGE - 7 - SQL - Language Statements - - - - MERGE - 有条件地插入、更新或删除表中的行 - - - - -[ WITH with_query [, ...] ] -MERGE INTO [ ONLY ] target_table_name [ * ] [ [ AS ] target_alias ] - USING data_source ON join_condition - when_clause [...] - [ RETURNING [ WITH ( { OLD | NEW } AS output_alias [, ...] ) ] - { * | output_expression [ [ AS ] output_name ] } [, ...] ] - -where data_source is: - - { [ ONLY ] source_table_name [ * ] | ( source_query ) } [ [ AS ] source_alias ] - -and when_clause is: - - { WHEN MATCHED [ AND condition ] THEN { merge_update | merge_delete | DO NOTHING } | - WHEN NOT MATCHED BY SOURCE [ AND condition ] THEN { merge_update | merge_delete | DO NOTHING } | - WHEN NOT MATCHED [ BY TARGET ] [ AND condition ] THEN { merge_insert | DO NOTHING } } - -and merge_insert is: - - INSERT [( column_name [, ...] )] - [ OVERRIDING { SYSTEM | USER } VALUE ] - { VALUES ( { expression | DEFAULT } [, ...] ) | DEFAULT VALUES } - -and merge_update is: - - UPDATE SET { column_name = { expression | DEFAULT } | - ( column_name [, ...] ) = [ ROW ] ( { expression | DEFAULT } [, ...] ) | - ( column_name [, ...] ) = ( sub-SELECT ) - } [, ...] - -and merge_delete is: - - DELETE - - - - - 描述 - - - MERGE使用data_source - 对由target_table_name标识的目标表中的行执行修改动作。 - MERGE提供了一条单独的SQL语句, - 可按条件对行执行INSERTUPDATEDELETE; - 否则,这项工作通常需要多条过程语言语句。 - - - - 首先,MERGE命令会将data_source - 与目标表执行连接,生成零个或多个候选变更行。对于每个候选变更行, - 系统只会确定一次其状态是MATCHED、 - NOT MATCHED BY SOURCE还是 - NOT MATCHED [BY TARGET],然后按指定顺序对 - WHEN子句求值。对于每个候选变更行, - 只执行第一个求值为真的子句。任何候选变更行都不会执行多个 - WHEN子句。 - - - - MERGE中的各个动作,与常规的 - UPDATEINSERT或 - DELETE同名命令具有相同效果。不过这些动作的语法有所不同, - 尤其是没有WHERE子句,也不指定表名。 - 所有动作都针对目标表,不过也可以借助触发器修改其他表。 - - - - 当指定DO NOTHING时,源行会被跳过。由于动作会按其指定顺序求值, - DO NOTHING有助于在进行更细粒度处理之前跳过不需要关注的源行。 - - - - 可选的RETURNING子句会让MERGE - 针对每个被插入、更新或删除的行计算并返回值。可以计算任何使用源表或目标表列的表达式, - 也可以调用merge_action()函数。 - 默认情况下,执行INSERTUPDATE动作时, - 使用目标表各列的新值;执行DELETE动作时,使用目标表各列的旧值, - 但也可以显式请求旧值和新值。RETURNING列表的语法与 - SELECT的输出列表完全相同。 - - - - 没有单独的MERGE权限。 - 如果指定更新动作,则必须对目标表中SET子句所引用的列具有UPDATE权限。 - 如果指定插入动作,则必须对目标表具有INSERT权限。 - 如果指定删除动作,则必须对目标表具有DELETE权限。 - 如果指定DO NOTHING动作,则必须对目标表中至少一列具有SELECT权限。 - 对于data_source以及目标表中在任何 - condition(包括join_condition)或 - expression中引用的列,你还必须具有SELECT权限。 - 权限只会在语句开始时测试一次,而且无论特定的WHEN子句是否执行,都会进行检查。 - - - - 如果目标表是物化视图、外部表,或者其上定义了任何规则,则不支持MERGE。 - - - - - 参数 - - - - with_query - - - WITH子句允许你指定一个或多个子查询, - 以便在MERGE查询中按名称引用它们。 - 有关细节请参见。 - 请注意,MERGE不支持WITH RECURSIVE。 - - - - - - target_table_name - - - 要合并到其中的目标表或视图名称(可选模式限定)。 - 如果在表名前指定ONLY,则匹配行只会在该命名表中被更新或删除。 - 如果未指定ONLY,则匹配行还会在继承自该命名表的任何表中被更新或删除。 - 也可以在表名后指定*,以显式表明包含后代表。 - ONLY关键字和*选项不会影响插入动作, - 因为插入动作始终只会插入到该命名表中。 - - - - 如果target_table_name是一个视图, - 它必须要么是没有INSTEAD OF触发器的自动可更新视图, - 要么为WHEN子句中指定的每一种动作类型 - (INSERTUPDATEDELETE) - 都定义了INSTEAD OF触发器。 - 不支持带有规则的视图。 - - - - - - target_alias - - - 目标表的替代名称。提供别名后,它会完全隐藏表的实际名称。 - 例如,给定MERGE INTO foo AS f, - 则MERGE语句的其余部分必须将该表称为f, - 而不是foo。 - - - - - - source_table_name - - - 源表、视图或过渡表的名称(可选模式限定)。 - 如果在表名前指定ONLY,则只包含来自该命名表的匹配行。 - 如果未指定ONLY,则还会包含来自继承自该命名表的任何表的匹配行。 - 也可以在表名后指定*,以显式表明包含后代表。 - - - - - - source_query - - - 一个查询(SELECT语句或VALUES语句), - 用于提供要合并到目标表中的行。其语法说明请参见 - 语句或语句。 - - - - - - source_alias - - - 数据源的替代名称。提供别名后,它会完全隐藏表的实际名称, - 或者隐藏此处实际使用的是一个查询这一事实。 - - - - - - join_condition - - - join_condition是一个返回 - boolean类型值的表达式(类似于WHERE子句), - 用于指定data_source中的哪些行 - 与目标表中的行匹配。 - - - - 只有那些用于尝试将data_source行 - 与目标表行匹配的目标表列,才应出现在join_condition中。 - 只引用目标表列的join_condition子表达式 - 可能影响所采取的动作,而且常常会令人意外。 - - - 如果同时指定了WHEN NOT MATCHED BY SOURCE和 - WHEN NOT MATCHED [BY TARGET]子句, - MERGE命令将对data_source - 与目标表执行FULL连接。要做到这一点, - 至少有一个join_condition子表达式 - 必须使用可支持哈希连接的操作符,或者所有子表达式都必须使用可支持归并连接的操作符。 - - - - - - - when_clause - - - 至少需要一个WHEN子句。 - - - WHEN子句可以指定WHEN MATCHED、 - WHEN NOT MATCHED BY SOURCE或 - WHEN NOT MATCHED [BY TARGET]。 - 请注意,SQL标准只定义了WHEN MATCHED和 - WHEN NOT MATCHED(后者定义为没有匹配的目标行)。 - WHEN NOT MATCHED BY SOURCE是对SQL标准的扩展, - 而给WHEN NOT MATCHED追加BY TARGET选项 - 也是扩展,用以使其含义更加明确。 - - - 如果WHEN子句指定了WHEN MATCHED, - 并且候选变更行表示data_source中的一行 - 与目标表中的一行相匹配,那么如果 - condition未指定, - 或其求值结果为true,就会执行该WHEN子句。 - - - 如果WHEN子句指定了WHEN NOT MATCHED BY SOURCE, - 并且候选变更行表示目标表中的某一行与 - data_source中的任何行都不匹配, - 那么如果condition未指定, - 或其求值结果为true,就会执行该WHEN子句。 - - - 如果WHEN子句指定了WHEN NOT MATCHED [BY TARGET], - 并且候选变更行表示data_source中的某一行 - 与目标表中的任何行都不匹配,那么如果 - condition未指定, - 或其求值结果为true,就会执行该WHEN子句。 - - - - - - condition - - - 一个返回boolean类型值的表达式。 - 如果某个WHEN子句中的这个表达式返回true, - 则会对该行执行该子句对应的动作。 - - - WHEN MATCHED子句上的条件可以引用源关系和目标关系中的列。 - WHEN NOT MATCHED BY SOURCE子句上的条件只能引用目标关系中的列, - 因为按定义不存在匹配的源行。 - WHEN NOT MATCHED [BY TARGET]子句上的条件只能引用源关系中的列, - 因为按定义不存在匹配的目标行。 - 只能访问目标表的系统属性。 - - - - - - merge_insert - - - 用于向目标表插入一行的INSERT动作规范。 - 目标列名可以按任意顺序列出。如果根本没有给出列名列表, - 则默认为按声明顺序使用该表的所有列。 - - - 每个未出现在显式或隐式列列表中的列都将填充为默认值, - 即其声明的默认值;如果没有默认值,则为NULL。 - - - 如果目标表是分区表,则每一行都会被路由到适当的分区并插入其中。 - 如果目标表本身是一个分区,而任何输入行违反了分区约束,就会报错。 - - - 列名不得指定多次。INSERT动作不能包含子查询。 - - - 只能指定一个VALUES子句。 - VALUES子句只能引用源关系中的列, - 因为按定义不存在匹配的目标行。 - - - - - - merge_update - - - 用于更新目标表当前行的UPDATE动作规范。 - 列名不得指定多次。 - - - 既不允许表名,也不允许WHERE子句。 - - - - - - merge_delete - - - 指定一个DELETE动作,用于删除目标表的当前行。 - 不要像通常编写命令那样包含表名或其他子句。 - - - - - - column_name - - - 目标表中某一列的名称。如有需要,列名可以使用子字段名或数组下标进行限定。 - (只向组合列的部分字段插入值会使其余字段为NULL。) - 在指定目标列时不要包含表名。 - - - - - - OVERRIDING SYSTEM VALUE - - - 如果没有这个子句,那么为定义为GENERATED ALWAYS的标识列 - 指定显式值(除DEFAULT外)会报错。 - 这个子句会覆盖该限制。 - - - - - - OVERRIDING USER VALUE - - - 如果指定了这个子句,那么为定义为GENERATED BY DEFAULT的标识列 - 提供的任何值都会被忽略,并应用默认的序列生成值。 - - - - - - DEFAULT VALUES - - - 所有列都将填充其默认值。 - (这种形式不允许使用OVERRIDING子句。) - - - - - - expression - - - 赋给该列的表达式。如果用于WHEN MATCHED子句, - 该表达式可以使用目标表中原始行的值以及 - data_source行的值。 - 如果用于WHEN NOT MATCHED BY SOURCE子句, - 该表达式只能使用目标表中原始行的值。 - 如果用于WHEN NOT MATCHED [BY TARGET]子句, - 该表达式只能使用data_source行的值。 - - - - - - DEFAULT - - - 将该列设为其默认值(如果没有为其指定特定的默认表达式,则为NULL)。 - - - - - - sub-SELECT - - - 一个SELECT子查询,其输出列数必须与它前面的括号列列表中列出的数量相同。 - 执行时,该子查询最多只能产生一行。如果产生一行,其列值会赋给目标列; - 如果不产生任何行,则向目标列赋NULL值。 - 如果用于WHEN MATCHED子句,子查询可以引用目标表中原始行的值, - 以及data_source行的值。 - 如果用于WHEN NOT MATCHED BY SOURCE子句, - 子查询只能引用目标表中原始行的值。 - - - - - - output_alias - - - RETURNING列表中OLDNEW行的可选替代名称。 - - - 默认情况下,可以通过写 - OLD.column_name - 或OLD.*返回目标表中的旧值,也可以通过写 - NEW.column_name - 或NEW.*返回新值。提供别名后,这些名称会被隐藏, - 此时必须使用该别名来引用旧行或新行。例如 - RETURNING WITH (OLD AS o, NEW AS n) o.*, n.*。 - - - - - - output_expression - - - 由MERGE命令在每一行发生变化后 - (无论是插入、更新还是删除)计算并返回的表达式。 - 该表达式可以使用源表或目标表的任意列,也可以使用 - merge_action()函数 - 返回关于已执行动作的附加信息。 - - - 写成*将返回源表的全部列,然后返回目标表的全部列。 - 这往往会导致大量重复,因为源表和目标表通常有很多相同的列。 - 可以通过使用源表或目标表的名称或别名限定*来避免这一点。 - - - 列名或*也可以用OLDNEW, - 或者用它们对应的output_alias来限定, - 以返回目标表中的旧值或新值。来自目标表的未限定列名, - 或者使用目标表名或别名限定的列名或 - *,会在INSERTUPDATE动作中返回新值, - 在DELETE动作中返回旧值。 - - - - - - output_name - - - 返回列所使用的名称。 - - - - - - - - - 输出 - - - 成功完成时,MERGE命令返回如下形式的命令标签: - -MERGE total_count - - total_count是发生变化的总行数 - (无论是插入、更新还是删除)。 - 如果total_count为 0, - 则没有任何行以任何方式发生变化。 - - - - 如果MERGE命令包含RETURNING子句, - 则其结果将类似于一条SELECT语句, - 包含RETURNING列表中定义的列和值, - 这些值是针对该命令插入、更新或删除的行计算得到的。 - - - - - 注解 - - - 在执行MERGE期间会发生以下步骤: - - - - 对所有已指定的动作执行任何BEFORE STATEMENT触发器, - 无论其WHEN子句是否匹配。 - - - - - 执行从源到目标表的连接。生成的查询会按常规方式优化,并产生一组候选变更行。 - 对于每个候选变更行, - - - - 判定该行是MATCHED、 - NOT MATCHED BY SOURCE还是 - NOT MATCHED [BY TARGET]。 - - - - - 按指定顺序测试每个WHEN条件,直到有一个返回true。 - - - - - 当某个条件返回true时,执行以下动作: - - - - 执行为该动作事件类型触发的任何BEFORE ROW触发器。 - - - - - 执行指定的动作,并对目标表应用任何检查约束。 - - - - - 执行为该动作事件类型触发的任何AFTER ROW触发器。 - - - - 如果目标关系是一个视图,并且为该动作的事件类型定义了 - INSTEAD OF ROW触发器,则改由这些触发器执行该动作。 - - - - - - - 对已指定的动作执行任何AFTER STATEMENT触发器, - 无论这些动作是否实际发生。这类似于一条未修改任何行的 - UPDATE语句的行为。 - - - - 总之,只要我们指定了某种动作, - 对应事件类型(例如INSERT)的语句级触发器就会被触发。 - 相反,行级触发器只会针对实际被执行的特定事件类型触发。 - 因此,一条MERGE命令可能同时触发 - UPDATEINSERT的语句级触发器, - 即使实际上只触发了UPDATE的行级触发器。 - - - - 你应确保该连接对每个目标行最多只生成一个候选变更行。 - 换句话说,一个目标行不应连接到多于一个数据源行。 - 如果发生这种情况,则只会使用其中一个候选变更行来修改目标行; - 随后再次尝试修改该行会导致错误。 - 如果行级触发器对目标表进行了修改,而随后这些已被修改的行又被 - MERGE再次修改,也可能发生这种情况。 - 如果重复的动作是INSERT,则会导致唯一性违例错误; - 而重复的UPDATEDELETE则会导致基数违规; - 后者是SQL标准要求的行为。 - 这不同于PostgreSQL历史上在 - UPDATEDELETE语句中处理连接的行为: - 对同一行的第二次及后续修改尝试会被直接忽略。 - - - - 如果某个WHEN子句省略了AND子句, - 它就会成为该类型(MATCHED、 - NOT MATCHED BY SOURCE或 - NOT MATCHED [BY TARGET])最后一个可达的子句。 - 如果之后又指定了同一类型的WHEN子句, - 则可证明它不可达,并会引发错误。 - 如果这三类中都没有指定最后一个可达子句,则候选变更行可能不会执行任何动作。 - - - - 默认情况下,从数据源生成行的顺序是不确定的。 - 如果需要,可以使用source_query指定一致的排序, - 这可能有助于避免并发事务之间的死锁。 - - - - 当MERGE与其他修改目标表的命令并发运行时, - 适用通常的事务隔离规则;请参见, - 了解各个隔离级别下的行为说明。 - 你也可以考虑使用INSERT ... ON CONFLICT作为替代语句, - 它提供了在发生并发INSERT时执行UPDATE的能力。 - 这两种语句类型之间存在各种差异和限制,因此不能互换。 - - - - - 示例 - - - 根据新的recent_transactions对 - customer_accounts执行维护。 - - -MERGE INTO customer_account ca -USING recent_transactions t -ON t.customer_id = ca.customer_id -WHEN MATCHED THEN - UPDATE SET balance = balance + transaction_value -WHEN NOT MATCHED THEN - INSERT (customer_id, balance) - VALUES (t.customer_id, t.transaction_value); - - - - - 尝试插入一个新的库存项及其库存数量。如果该项已存在, - 则改为更新现有项的库存数量。不允许库存为零的条目。 - 返回所有已发生更改的详细信息。 - -MERGE INTO wines w -USING wine_stock_changes s -ON s.winename = w.winename -WHEN NOT MATCHED AND s.stock_delta > 0 THEN - INSERT VALUES(s.winename, s.stock_delta) -WHEN MATCHED AND w.stock + s.stock_delta > 0 THEN - UPDATE SET stock = w.stock + s.stock_delta -WHEN MATCHED THEN - DELETE -RETURNING merge_action(), w.winename, old.stock AS old_stock, new.stock AS new_stock; - - - 例如,wine_stock_changes表可能是一个刚装载到数据库中的临时表。 - - - - 根据替换后的酒单更新wines:为任何新库存插入行, - 更新已修改的库存条目,并删除新列表中不存在的任何葡萄酒。 - -MERGE INTO wines w -USING new_wine_list s -ON s.winename = w.winename -WHEN NOT MATCHED BY TARGET THEN - INSERT VALUES(s.winename, s.stock) -WHEN MATCHED AND w.stock != s.stock THEN - UPDATE SET stock = s.stock -WHEN NOT MATCHED BY SOURCE THEN - DELETE; - - - - - - - 兼容性 - - 这个命令符合SQL标准。 - - - WITH子句、WHEN NOT MATCHED上的 - BY SOURCEBY TARGET限定词、 - DO NOTHING动作以及RETURNING子句, - 都是对SQL标准的扩展。 - - - diff --git a/zh/14/ref/move.sgml b/zh/14/ref/move.sgml index e90c1b88..961359c8 100644 --- a/zh/14/ref/move.sgml +++ b/zh/14/ref/move.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation MOVE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/notify.sgml b/zh/14/ref/notify.sgml index 502baccc..a2df6be2 100644 --- a/zh/14/ref/notify.sgml +++ b/zh/14/ref/notify.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation NOTIFY 7 - SQL - Language Statements + SQL - 语言语句 @@ -88,7 +88,7 @@ NOTIFY channel [ , 注解 - 系统中有一个队列,用来保存那些已经发送但尚未被所有监听会话处理的通知。如果这个队列被塞满,那么调用NOTIFY的事务会在提交时失败。该队列非常大(标准安装中为 8GB),几乎足以满足所有用例。不过,如果某个会话执行了LISTEN后又长时间停留在一个事务里,就无法进行清理。一旦队列占用超过一半,你就会在日志文件中看到警告,指出究竟是哪个会话阻碍了清理。在这种情况下,应确保该会话结束其当前事务,以便清理能够继续进行。 + 系统中有一个队列,用来保存那些已经发送但尚未被所有监听会话处理的通知。如果这个队列被塞满,那么调用NOTIFY的事务会在提交时失败。该队列非常大(标准安装中为 8GB),几乎足以满足所有用例。不过,如果某个会话执行了LISTEN后又长时间停留在一个事务里,就无法进行清理。一旦队列占用达到一半,你就会在日志文件中看到警告,指出究竟是哪个会话阻碍了清理。在这种情况下,应确保该会话结束其当前事务,以便清理能够继续进行。 函数pg_notification_queue_usage返回当前被待处理通知占用的队列比例。详见。 @@ -143,7 +143,6 @@ Asynchronous notification "foo" with payload "payload" received from server proc - diff --git a/zh/14/ref/pg_amcheck.sgml b/zh/14/ref/pg_amcheck.sgml index 855c42dd..cde2a403 100644 --- a/zh/14/ref/pg_amcheck.sgml +++ b/zh/14/ref/pg_amcheck.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_amcheck 1 - Application + 应用程序 @@ -34,9 +34,7 @@ PostgreSQL documentation pg_amcheck支持针对一个或多个数据库运行的损坏检查函数,并提供选项来选择要检查哪些模式、表和索引、执行哪些检查,以及是否并行执行这些检查;如果并行执行,还可指定要建立并使用的并行连接数。 - - 当前仅支持普通表关系、TOAST 表关系、物化视图、序列以及 B-树索引。其他关系类型会被静默跳过。 - + 当前仅支持表关系和 B-树索引。其他关系类型会被静默跳过。 如果指定了dbname,它应是要检查的单个数据库的名称,并且不应再出现其他数据库选择选项。否则,如果存在任何数据库选择选项,就会检查所有匹配的数据库。如果不存在这类选项,则检查默认数据库。数据库选择选项包括。它们还包括,但仅限于这些选项与三部分模式一起使用时(例如 )。最后,当与两部分模式一起使用时(例如 ),它们也属于数据库选择选项。 @@ -91,9 +89,7 @@ PostgreSQL documentation 检查匹配指定pattern的索引,除非另有排除。此选项可指定多次。 - - 这与选项类似,但它只适用于索引,不适用于其他关系类型。 - + 这与选项类似,但它只适用于索引,不适用于表。 @@ -104,9 +100,7 @@ PostgreSQL documentation 排除匹配指定pattern的索引。此选项可指定多次。 - - 这与选项类似,但它只适用于索引,不适用于其他关系类型。 - + 这与选项类似,但它只适用于索引,不适用于表。 @@ -172,9 +166,7 @@ PostgreSQL documentation 检查匹配指定pattern的表,除非另有排除。此选项可指定多次。 - - 这与选项类似,但它只适用于表、物化视图和序列,不适用于索引。 - + 这与选项类似,但它只适用于表,不适用于索引。 @@ -185,9 +177,7 @@ PostgreSQL documentation 排除匹配指定pattern的表。此选项可指定多次。 - - 这与选项类似,但它只适用于表、物化视图和序列,不适用于索引。 - + 这与选项类似,但它只适用于表,不适用于索引。 @@ -284,14 +274,7 @@ PostgreSQL documentation 下列命令行选项控制 B-树索引的检查: - - - - - 对于检查的每个带唯一约束的索引,使用选项,验证重复条目中在索引里可见的项不超过一个。 - - - + @@ -488,17 +471,7 @@ PostgreSQL documentation - - 环境 - - 与大多数其他PostgreSQL工具一样,pg_amcheck也使用libpq支持的环境变量(见)。 - - - - 环境变量PG_COLOR指定是否在诊断消息中使用颜色。可能的值为alwaysautonever。 - - 注意 diff --git a/zh/14/ref/pg_basebackup.sgml b/zh/14/ref/pg_basebackup.sgml index 057c8cbb..11ca88d9 100644 --- a/zh/14/ref/pg_basebackup.sgml +++ b/zh/14/ref/pg_basebackup.sgml @@ -4,7 +4,6 @@ PostgreSQL documentation --> - pg_basebackup @@ -12,7 +11,7 @@ PostgreSQL documentation pg_basebackup 1 - Application + 应用程序 @@ -28,15 +27,13 @@ PostgreSQL documentation - 描述 - pg_basebackup用于获取正在运行的PostgreSQL数据库集簇的基础备份。备份过程不会影响数据库的其他客户端,并且该备份既可用于时间点恢复(见),也可用作日志传送或流复制备库的起点(见)。 - 在任何模式下,pg_basebackup都会确保服务器自动进入和退出备份模式。备份始终针对整个数据库集簇;不可能只备份单个数据库或数据库对象。对于选择性备份,必须使用诸如之类的其他工具。 + pg_basebackup会精确复制数据库集簇的文件,同时确保服务器自动进入和退出备份模式。备份始终针对整个数据库集簇;不可能只备份单个数据库或数据库对象。对于选择性备份,必须使用诸如之类的其他工具。 @@ -75,10 +72,7 @@ PostgreSQL documentation - - 备份所需的所有 WAL 记录都必须包含足够的全页写入, - 因此必须在主库上启用full_page_writes。 - + 备份所需的所有 WAL 记录都必须包含足够的整页写入,因此必须在主库上启用full_page_writes,并且不能把pg_compresslog之类的工具用作archive_command,从 WAL 文件中移除整页写入。 @@ -89,7 +83,6 @@ PostgreSQL documentation - 选项 @@ -165,22 +158,7 @@ PostgreSQL documentation 创建standby.signal standby.signalpg_basebackup --write-recovery-conf文件,并将连接设置追加到目标目录中的postgresql.auto.conf文件中(如果使用 tar 格式,则追加到基础归档文件内)。这样可以更方便地利用备份结果搭建备库。 - - - - - - - - - - - 指示服务器将基础备份放到哪里。默认目标是client,表示备份应发送到运行pg_basebackup的那台机器。如果目标改为server:/some/path,则备份会存储在服务器运行所在机器的/some/path目录中。将备份存储在服务器上需要超级用户权限,或拥有pg_write_server_files角色的权限。如果目标设置为blackhole,则内容会被丢弃,不会存储到任何地方。这只应用于测试目的,因为最终不会得到实际备份。 - - - - 由于 WAL 流是由pg_basebackup而不是服务器实现的,因此此选项不能与-Xstream一起使用。由于后者是默认值,所以指定此选项时,还必须同时指定-Xfetch-Xnone之一。 - + postgresql.auto.conf文件会记录pg_basebackup所用的连接设置,以及复制槽(如果指定了),以便流复制以后使用相同的设置。 @@ -189,7 +167,6 @@ PostgreSQL documentation - 在备份期间,将目录olddir中的表空间重定位到newdir。要使此选项生效,olddir必须与源服务器上定义的该表空间路径完全一致。(但如果源服务器上在olddir中没有表空间,也不算错误。)与此同时,newdir是接收主机文件系统中的一个目录。与主目标目录一样,newdir不必事先存在,但如果存在则必须为空。olddirnewdir都必须是绝对路径。如果任一路径中需要包含等号(=),请在其前面加上反斜杠。可以多次指定此选项,以处理多个表空间。 @@ -199,7 +176,7 @@ PostgreSQL documentation - 目前,此选项仅适用于 plain 输出格式;如果选择了 tar 格式,则会被忽略。 + 目前,此选项仅适用于 普通文件 输出格式;如果选择了 tar 格式,则会被忽略。 @@ -207,9 +184,8 @@ PostgreSQL documentation - - 设置写入 WAL(预写式日志)文件的目录。默认情况下,WAL 文件会放在目标目录的pg_wal子目录中,但此选项可用于将其放在其他位置。waldir必须是绝对路径。与主目标目录一样,waldir不必事先存在,但如果存在则必须为空。只有当备份采用 plain 格式时,才能指定此选项。 + 设置写入 WAL(预写式日志)文件的目录。默认情况下,WAL 文件会放在目标目录的pg_wal子目录中,但此选项可用于将其放在其他位置。waldir必须是绝对路径。与主目标目录一样,waldir不必事先存在,但如果存在则必须为空。只有当备份采用 普通文件 格式时,才能指定此选项。 @@ -283,42 +259,22 @@ PostgreSQL documentation - - - - - 请求对备份进行压缩。如果包含clientserver,则指定压缩执行的位置。在服务器端压缩会减少传输带宽占用,但会增加服务器 CPU 消耗。默认值是client,但使用--target时除外;此时备份不会发送到客户端,因此只有服务器端压缩才有意义。使用默认的-Xstream时,服务器端压缩不会应用于 WAL。若要压缩 WAL,请使用客户端压缩,或者指定-Xfetch。 - - - - 压缩方法可以设置为gziplz4zstdnone(不压缩),也可以直接指定一个整数(0 表示不压缩,大于 0 表示gzip)。还可以选择性地指定压缩细节字符串。如果细节字符串是整数,则表示压缩级别;否则,它应为逗号分隔的项目列表,每项的形式为keywordkeyword=value。目前支持的关键字有levellongworkers。当压缩方法以纯整数形式指定时,不能再使用细节字符串。 - - - - 如果未指定压缩级别,则使用默认压缩级别。如果只指定了级别而未指定算法,那么级别大于 0 时使用gzip压缩,级别为 0 时则不压缩。 - - - - 当 tar 格式配合gziplz4zstd使用时,所有 tar 文件名都会分别自动加上.gz.lz4.zst后缀。使用 plain 格式时,不能指定客户端压缩,但仍可以请求服务器端压缩。这样做时,服务器会先压缩备份再传输,而客户端会对其进行解压并提取。 - - - 当此选项与-Xstream组合使用时,如果选择了客户端 gzip 压缩,则pg_wal.tar会使用gzip压缩;但如果选择了其他压缩算法,或者选择了服务器端压缩,则不会被压缩。 + 启用 tar 文件输出的 gzip 压缩,并指定压缩级别(0 到 9,其中 0 表示不压缩,9 表示最佳压缩)。压缩仅在使用 tar 格式时可用,并且所有 tar 文件名都会自动添加.gz后缀。 - 以下命令行选项控制备份的生成和程序的调用: - - + + @@ -354,13 +310,12 @@ PostgreSQL documentation - 默认情况下,当pg_basebackup因错误中止时,它会删除在发现自己无法完成任务之前可能已创建的所有目录(例如目标目录和预写式日志目录)。此选项会禁止这种清理,因此对调试很有帮助。 - 请注意,无论如何表空间目录都不会被清理。 + 请注意,无论是否使用此选项,表空间目录都不会被清理。 @@ -406,36 +361,18 @@ PostgreSQL documentation - - 此选项只能与-X stream一起使用。它会使 WAL 流式传输使用指定的复制槽。如果此基础备份打算用作使用复制槽的流复制备库,那么该备库应使用与相同的复制槽名称。这样可以确保主库在基础备份结束与新备库开始流复制之间的这段时间内,不会移除任何必需的 WAL 数据。 + 此选项只能与-X stream一起使用。它会使 WAL 流式传输使用指定的复制槽。如果此基础备份打算用作使用复制槽的流复制备库,那么该备库应将同一个复制槽名称用作的值。这样可以确保主库在基础备份结束与新备库开始流复制之间的这段时间内,不会移除任何必需的 WAL 数据。 - 指定的复制槽必须已经存在,除非还同时使用了 - 如果未指定此选项,并且服务器支持临时复制槽(10 及以上版本),则会自动使用临时复制槽进行 WAL 流式传输。 - - - - - 设置为fsync(默认)时,pg_basebackup会递归打开并同步备份目录中的所有文件。使用 plain 格式时,查找文件会跟随 WAL 目录和各已配置表空间的符号链接。 - - - 在 Linux 上,也可以使用syncfs,让操作系统同步包含备份目录的整个文件系统。使用 plain 格式时,pg_basebackup还会同步包含 WAL 文件和各表空间的文件系统。关于使用syncfs时需要注意的限制,见。 - - - 使用时,此选项无效。 - - - - @@ -450,19 +387,15 @@ PostgreSQL documentation - 指定应用到备份清单中每个文件的校验和算法。目前可用的算法有NONECRC32CSHA224SHA256SHA384SHA512。默认值为CRC32C - 如果选择NONE,备份清单将不包含任何校验和。否则,它将包含使用指定算法为备份中每个文件计算的校验和。此外,清单始终会包含其自身内容的SHA256校验和。SHA算法明显比CRC32C更耗费 CPU,因此选择其中一种可能会增加完成备份所需的时间。 - - 对于希望验证备份未被篡改的用户,使用 SHA 哈希函数可以为每个文件提供具有密码学安全性的摘要;而 CRC-32C 算法提供的校验和计算速度要快得多,虽然它很适合发现由于意外改动造成的错误,但并不能抵御恶意修改。请注意,要想对能够访问备份的攻击者形成防护,备份清单就需要安全地保存在其他地方,或者以其他方式确认自备份完成后未被修改。 + 对于希望验证备份未被篡改的用户,使用 SHA hash 函数可以为每个文件提供具有密码学安全性的摘要;而 CRC32C 算法提供的校验和计算速度要快得多,虽然它很适合发现由于意外改动造成的错误,但并不能抵御恶意修改。请注意,要想对能够访问备份的攻击者形成防护,备份清单就需要安全地保存在其他地方,或者以其他方式确认自备份完成后未被修改。 - 可以使用根据备份清单检查备份的完整性。 @@ -552,9 +485,7 @@ PostgreSQL documentation 连接字符串的形式指定用于连接服务器的参数;这些参数会覆盖任何相互冲突的命令行选项。 - - 出于与其他客户端应用保持一致的考虑,此选项名为--dbname;但由于pg_basebackup并不连接到集簇中的某个特定数据库,连接字符串中包含的数据库名会被服务器忽略。不过,以这种方式提供的数据库名会覆盖默认数据库名(replication),从而用于在~/.pgpass中查找复制连接的密码。类似地,连接PostgreSQL时使用的中间件或代理,也可能出于连接路由等目的使用该名称。 - + 出于与其他客户端应用保持一致的考虑,此选项名为--dbname;但由于pg_basebackup并不连接到集簇中的某个特定数据库,连接字符串中的任何数据库名都会被忽略。 @@ -667,28 +598,25 @@ PostgreSQL documentation - - 注意 + 注解 在备份开始时,需要在源服务器上执行一次检查点。这可能需要一些时间(尤其是在未使用--checkpoint=fast选项时);在此期间,pg_basebackup看起来会处于空闲状态。 - 备份将包括数据目录和表空间中的所有文件,包括配置文件以及第三方放在这些目录中的任何额外文件,但由 PostgreSQL 管理的某些临时文件和操作系统文件除外。不过,只有普通文件和目录会被复制,但用于表空间的符号链接会被保留。指向 PostgreSQL 已知某些目录的符号链接会被复制为空目录。其他符号链接和特殊设备文件则会被跳过。具体细节见。 + 备份将包括数据目录和表空间中的所有文件,包括配置文件以及第三方放在这些目录中的任何额外文件,但由 PostgreSQL 管理的某些临时文件除外。不过,只有普通文件和目录会被复制,但用于表空间的符号链接会被保留。指向 PostgreSQL 已知某些目录的符号链接会被复制为空目录。其他符号链接和特殊设备文件则会被跳过。具体细节见 - 在 plain 格式中,除非使用了--tablespace-mapping选项,否则表空间会备份到其在源服务器上的相同路径。如果不使用此选项,那么当表空间正在使用时,就无法在与服务器相同的主机上执行 plain 格式的基础备份,因为备份将不得不写入与原始表空间相同的目录位置。 + 在 普通文件 格式中,除非使用了--tablespace-mapping选项,否则表空间会备份到其在源服务器上的相同路径。如果不使用此选项,那么当表空间正在使用时,就无法在与服务器相同的主机上执行 普通文件 格式的基础备份,因为备份将不得不写入与原始表空间相同的目录位置。 使用 tar 格式时,用户有责任在启动使用这些数据的 PostgreSQL 服务器之前解压每一个 tar 文件。如果存在额外表空间,则这些表空间对应的 tar 文件必须解压到正确的位置。在这种情况下,服务器会根据包含在base.tar文件中的tablespace_map文件内容,为这些表空间创建符号链接。 - - pg_basebackup可以与相同主版本或更低主版本的服务器配合工作,最低支持到 9.1。不过,WAL 流式传输模式(-X stream)仅适用于 9.3 及以上版本服务器,tar 格式(--format=tar)仅适用于 9.5 及以上版本服务器,而增量备份(--incremental)仅适用于 17 及以上版本服务器。 - + pg_basebackup可以与相同主版本或更低主版本的服务器配合工作,最低支持到 9.1。不过,WAL 流式传输模式(-X stream)仅适用于 9.3 及以上版本服务器,tar 格式(--format=tar)仅适用于 9.5 及以上版本服务器。 如果源集簇启用了数据文件的组权限,pg_basebackup会保留这些组权限。 @@ -697,7 +625,6 @@ PostgreSQL documentation - 示例 @@ -727,19 +654,10 @@ PostgreSQL documentation $ pg_basebackup -D backup/data -T /opt/ts=$(pwd)/backup/ts - - - 要为本地服务器创建一个备份,为每个表空间生成一个 tar 文件,并使用gzip以 9 级压缩后存储到目录backup中: - -$ pg_basebackup -D backup -Ft --compress=gzip:9 - - - - - 参见 + 另见 diff --git a/zh/14/ref/pg_checksums.sgml b/zh/14/ref/pg_checksums.sgml index bba74354..a22b9125 100644 --- a/zh/14/ref/pg_checksums.sgml +++ b/zh/14/ref/pg_checksums.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_checksums 1 - Application + 应用程序 @@ -33,7 +33,7 @@ PostgreSQL documentation - + 描述 pg_checksums用于在PostgreSQL数据库集簇中检查、启用或禁用数据校验和。运行pg_checksums之前,必须先将服务器干净关闭。验证校验和时,如果没有校验和错误,则退出状态为零;如果检测到至少一个校验和失败,则退出状态为非零。启用或禁用校验和时,如果操作失败,则退出状态为非零。 diff --git a/zh/14/ref/pg_combinebackup.sgml b/zh/14/ref/pg_combinebackup.sgml deleted file mode 100644 index 5ae1aa14..00000000 --- a/zh/14/ref/pg_combinebackup.sgml +++ /dev/null @@ -1,325 +0,0 @@ - - - - - pg_combinebackup - - - - pg_combinebackup - 1 - Application - - - - pg_combinebackup - 从增量备份及其所依赖的备份重建完整备份 - - - - - pg_combinebackup - option - backup_directory - - - - - 描述 - - pg_combinebackup用于从 - 增量备份及其所依赖的 - 更早备份中重建一个合成的完整备份。 - - - - 请在命令行上按照从旧到新的顺序指定所有必需的备份。 - 也就是说,第一个备份目录应当是完整备份的路径, - 最后一个应当是您希望恢复的最终增量备份的路径。 - 重建后的备份将写入由选项指定的输出目录。 - - - - pg_combinebackup会尝试验证您指定的这些备份 - 是否构成一条合法的备份链,并且能否据此重建出正确的完整备份。 - 但它并不是为帮助您跟踪哪些备份依赖于哪些其他备份而设计的。 - 如果您删除了增量备份所依赖的一个或多个先前备份, - 就无法恢复该增量备份。 - 此外,pg_combinebackup只会尝试验证这些备份 - 相互之间的关系是否正确,而不会验证每个单独备份本身是否完好; - 如需完成该项验证,请使用 - 。 - - - - 由于pg_combinebackup的输出是一个合成完整备份, - 因此它可以作为将来调用pg_combinebackup时的输入。 - 在这种情况下,可以在命令行上指定这个合成完整备份, - 以代替原先用于重建它的那条备份链。 - - - - - 选项 - - - - - - - - - 在stderr上输出大量调试日志。 - - - - - - - - - - 在合成备份中使用硬链接,而不是复制文件。 - 这样重建合成备份可能更快(因为无需复制文件), - 并且占用更少磁盘空间;但在使用输出目录时必须格外小心, - 因为对该目录的任何修改(例如启动服务器)也可能影响输入目录。 - 同样,对输入目录的更改(例如在完整备份上启动服务器) - 也可能影响输出目录。 - 因此,此选项最适合输入目录只是副本、并且会在 - pg_combinebackup完成后被删除的场景。 - - - - 要求输入备份和输出目录位于同一文件系统中。 - - - - 如果备份清单不可用,或者其中不包含正确类型的校验和, - 仍会创建硬链接,但也会按块读取文件以计算校验和。 - - - - - - - - - - /会让 - pg_combinebackup确定将要执行哪些操作, - 而不实际创建目标目录或任何输出文件。 - 该选项与组合时尤其有用。 - - - - - - - - - - 默认情况下,pg_combinebackup会等待所有文件都被安全写入磁盘。 - 此选项会使pg_combinebackup不经等待就直接返回,因此速度更快, - 但这意味着如果随后操作系统崩溃,输出备份可能会损坏。 - 通常,此选项适合测试,但不应用于创建生产环境安装。 - - - - - - - - - - 指定合成完整备份写入的输出目录。 - 当前该参数是必需的。 - - - - - - - - - - 在重建备份期间,将目录olddir中的表空间重定位到 - newdir。 - olddir是命令行指定的最终备份中该表空间的绝对路径, - newdir是重建备份中要使用的绝对路径。 - 若路径中需要包含等号(=),请在其前加反斜杠。 - 可多次指定此选项以映射多个表空间。 - - - - - - - - - 使用高效的文件克隆(某些系统将其称为reflink), - 代替向新数据目录复制文件,这样可能实现几乎瞬时的数据文件复制。 - - - - 如果备份清单不可用,或者其中不包含正确类型的校验和, - 仍会使用文件克隆来复制文件,但也会按块读取该文件以计算校验和。 - - - - 文件克隆仅在某些操作系统和文件系统上受支持。 - 如果选择了该选项,但系统并不支持, - pg_combinebackup运行时将报错。 - 目前,它在 Linux(内核 4.5 及以上)上的 Btrfs 和 XFS - (在创建时启用了 reflink 支持的文件系统)以及 macOS 上的 APFS - 上受支持。 - - - - - - - - - 执行常规文件复制。这是默认行为。 - (另见 - 和/。) - - - - - - - - - 使用copy_file_range系统调用进行高效复制。 - 在某些文件系统上,这会得到与类似的结果, - 即共享物理磁盘块;而在其他文件系统上,它仍可能复制数据块, - 但会通过优化后的路径进行。目前支持 Linux 和 FreeBSD。 - - - - 如果备份清单不可用,或者其中不包含正确类型的校验和, - 仍会使用copy_file_range复制文件, - 但也会按块读取该文件以计算校验和。 - - - - - - - - - 与一样, - pg_combinebackup会在输出目录中写入备份清单。 - 此选项指定对清单中每个文件使用的校验和算法。 - 当前可用算法为NONECRC32C、 - SHA224SHA256、 - SHA384SHA512。 - 默认值为CRC32C。 - - - - - - - - - 禁用备份清单的生成。 - 若未指定该选项,则会将重建备份的清单写入输出目录。 - - - - - - - - - 当设置为fsync(这是默认值)时, - pg_combinebackup会递归打开并同步备份目录中的所有文件。 - 使用 plain 格式时,搜索文件时会跟随 WAL 目录和每个已配置表空间的符号链接。 - - - 在 Linux 上,也可以改用syncfs, - 让操作系统同步包含备份目录的整个文件系统。 - 使用 plain 格式时,pg_combinebackup - 还会同步包含 WAL 文件和各表空间的文件系统。 - 关于使用syncfs时需要注意的事项,请参见 - 。 - - - 当使用时,此选项无效。 - - - - - - - - - - 打印pg_combinebackup版本并退出。 - - - - - - - - - - 显示pg_combinebackup命令行参数帮助并退出。 - - - - - - - - - - - 限制 - - - pg_combinebackup在写入输出目录时不会重新计算页面校验和。 - 因此,如果用于重建的某些备份是在禁用校验和时创建的, - 而最终备份是在启用校验和时创建的, - 则生成的目录中可能包含校验和无效的页面。 - - - - 为避免这个问题,建议在使用 - 更改集簇的校验和状态之后重新创建一次新的完整备份。 - 否则,您也可以对由pg_combinebackup生成的目录 - 先禁用校验和,然后再按需重新启用,以修正这个问题。 - - - - - 环境 - - - 与多数PostgreSQL工具一样, - 本工具使用libpq支持的环境变量 - (参见)。 - - - - 环境变量PG_COLOR指定诊断消息是否使用颜色。 - 可选值为alwaysauto和 - never。 - - - - - 另见 - - - - - - - diff --git a/zh/14/ref/pg_config-ref.sgml b/zh/14/ref/pg_config-ref.sgml index 565638d9..b157f24c 100644 --- a/zh/14/ref/pg_config-ref.sgml +++ b/zh/14/ref/pg_config-ref.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation pg_config 1 - Application + 应用程序 diff --git a/zh/14/ref/pg_controldata.sgml b/zh/14/ref/pg_controldata.sgml index 818db6cc..5435edfa 100644 --- a/zh/14/ref/pg_controldata.sgml +++ b/zh/14/ref/pg_controldata.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_controldata 1 - Application + 应用程序 diff --git a/zh/14/ref/pg_createsubscriber.sgml b/zh/14/ref/pg_createsubscriber.sgml deleted file mode 100644 index 29d634f9..00000000 --- a/zh/14/ref/pg_createsubscriber.sgml +++ /dev/null @@ -1,542 +0,0 @@ - - - - - pg_createsubscriber - - - - pg_createsubscriber - 1 - Application - - - - pg_createsubscriber - 将物理副本转换为新的逻辑副本 - - - - - pg_createsubscriber - option - - - - - - dbname - - - - - datadir - - - - - connstr - - - - - - 描述 - - - pg_createsubscriber从物理备库创建新的逻辑副本。 - 指定数据库中的所有表都会包含在逻辑复制配置中。 - 每个数据库都会创建一对发布和订阅对象。 - 该工具必须在目标服务器上运行。 - - - - 成功运行后,目标服务器的状态类似于一个全新的逻辑复制配置。 - 逻辑复制配置与pg_createsubscriber之间的主要区别在于 - 数据同步的完成方式。pg_createsubscriber - 不会复制初始表数据。它只执行同步阶段,以确保每个表都达到同步状态。 - - - - pg_createsubscriber主要面向大型数据库系统, - 因为在逻辑复制配置中,大部分时间都花在复制初始数据上。 - 此外,在数据同步上花费较长时间的一个副作用通常是,会有大量在初始数据复制期间产生的更改需要应用, - 这会进一步延后逻辑副本可用的时间。对于较小的数据库,建议建立带初始数据同步的逻辑复制。 - 详见CREATE SUBSCRIPTION的 - - copy_data选项。 - - - - - - 选项 - - - pg_createsubscriber接受以下命令行参数: - - - - - - - - 在目标服务器上的每个数据库中创建一个订阅。 - 模板数据库以及不允许连接的数据库除外。 - 为发现所有数据库的列表,工具会使用 - 连接字符串中指定的数据库名连接到源服务器;如果未指定,则使用 - postgres数据库;如果该数据库不存在,则使用 - template1。 - 指定此选项时,会使用自动生成的订阅、发布和复制槽名称。 - 此选项不能与、 - 一起使用。 - - - - - - - - - - 要在其中创建订阅的数据库名称。通过多次指定 - 可以选择多个数据库。此选项不能与一起使用。 - 如果未提供选项,数据库名将从 - 选项中获取。如果在选项或 - 选项中都未指定数据库名,且又未指定选项, - 则会报告错误。 - - - - - - - - - - 包含物理副本中的集簇目录的目标目录。 - - - - - - - - - - 执行除实际修改目标目录之外的所有步骤。 - - - - - - - - - - 目标服务器监听连接的端口号。 - 默认为让目标服务器在 50432 端口上运行,以避免意外的客户端连接。 - - - - - - - - - - 到发布者的连接字符串。详情见。 - - - - - - - - - - 目标服务器上 postmaster 套接字所使用的目录。 - 默认值为当前目录。 - - - - - - - - - - 等待恢复结束的最大秒数。设为 0 表示禁用。 - 默认值为 0。 - - - - - - - - - - 为订阅启用 two_phase 两阶段提交。 - 当指定多个数据库时,此选项会统一应用于在这些数据库上创建的所有订阅。 - 默认值为false。 - - - - - - - - - - 连接目标服务器所使用的用户名。 - 默认是当前操作系统用户名。 - - - - - - - - - - 启用详细模式。这将使 - pg_createsubscriber向标准错误输出进度消息 - 以及每个步骤的详细信息。重复指定该选项会让更多调试级消息出现在标准错误中。 - - - - - - - - - 从目标服务器上的指定数据库中删除指定类型的所有对象。 - - - - - - publications: - 为该订阅者建立的FOR ALL TABLES发布总是会被删除; - 指定此对象类型还会删除从源服务器复制过来的其他所有发布。 - - - - - - 被选中要删除的对象都会逐个记录到日志中,包括在 - 期间也是如此。没有机会干预或停止这些对象的删除,因此可以考虑使用 - pg_dump先对它们进行备份。 - - - - - - - - - 为目标数据目录使用指定的主配置文件。 - pg_createsubscriber在内部使用 - pg_ctl命令来启动和停止目标服务器。 - 如果实际的postgresql.conf配置文件存放在数据目录之外, - 此选项允许你显式指定它。 - - - - - - - - - 用于建立逻辑复制的发布名称。通过多次指定 - 可以指定多个发布。发布名称的数量必须与指定的数据库数量一致, - 否则会报告错误。多个发布名称开关的顺序必须与数据库开关的顺序一致。 - 如果未指定此选项,则会为发布分配一个生成的名称。此选项不能与 - 一起使用。 - - - - - - - - - 用于建立逻辑复制的复制槽名称。通过多次指定 - 可以指定多个复制槽。复制槽名称的数量必须与指定的数据库数量一致, - 否则会报告错误。多个复制槽名称开关的顺序必须与数据库开关的顺序一致。 - 如果未指定此选项,则使用订阅名称作为复制槽名称。此选项不能与 - 一起使用。 - - - - - - - - - 用于建立逻辑复制的订阅名称。通过多次指定 - 可以指定多个订阅。订阅名称的数量必须与指定的数据库数量一致, - 否则会报告错误。多个订阅名称开关的顺序必须与数据库开关的顺序一致。 - 如果未指定此选项,则会为订阅分配一个生成的名称。此选项不能与 - 一起使用。 - - - - - - - - - - 打印pg_createsubscriber版本并退出。 - - - - - - - - - - 显示pg_createsubscriber命令行参数的帮助并退出。 - - - - - - - - - 注意 - - - 前置条件 - - - 要让pg_createsubscriber将目标服务器转换为逻辑副本, - 需要满足一些前提条件。如果不满足这些条件,就会报告错误。 - 源服务器和目标服务器的主版本必须与 - pg_createsubscriber相同。 - 给定的目标数据目录必须与源数据目录具有相同的系统标识符。 - 为目标数据目录指定的数据库用户必须具备创建订阅以及使用pg_replication_origin_advance() - 的权限。 - - - - 目标服务器必须作为物理备库使用。 - 目标服务器必须将配置为大于等于指定数据库数量的值。 - 目标服务器必须将配置为大于指定数据库数量的值。 - 目标服务器必须接受本地连接。如果计划使用 - 开关,还需要适当地设置。 - - - - 源服务器必须接受来自目标服务器的连接。源服务器不能处于恢复中。 - 源服务器必须将设置为logical。 - 源服务器必须将配置为 - 大于等于指定数据库数量加现有复制槽数量的值。源服务器必须将配置为大于等于指定数据库数量与现有 WAL 发送器 - 进程数量之和的值。 - - - - - 警告 - - - 若pg_createsubscriber在目标服务器被提升后失败, - 数据目录很可能已处于不可恢复状态。此时建议重新创建新的备库。 - - - - 在转换过程中,pg_createsubscriber通常会使用不同的连接设置 - 来启动目标服务器。因此,对目标服务器的连接应该会失败。 - - - - 由于逻辑复制不复制 DDL 命令, - 运行pg_createsubscriber期间应避免执行会更改数据库模式的 DDL 命令。 - 若目标服务器已转换为逻辑副本,相关 DDL 可能不会被复制,从而引发错误。 - - - - 若pg_createsubscriber处理过程中失败, - 会删除在源服务器上创建的对象(发布、复制槽)。 - 如果目标服务器无法连接到源服务器,删除可能失败。 - 在这种情况下,警告消息会提示遗留的对象。 - 如果目标服务器正在运行,它会被停止。 - - - - 若复制使用了, - 在逻辑复制配置完成后会从源服务器移除该复制槽。 - - - - 如果目标服务器是同步副本, - 运行pg_createsubscriber期间, - 主库上的事务提交可能会在等待复制时阻塞。 - - - - 除非指定, - pg_createsubscriber会在禁用两阶段提交的情况下建立逻辑复制。 - 这意味着任何预备事务都会在COMMIT PREPARED时被复制, - 而不会事先进行预备。配置完成后,你可以手动删除并重新创建订阅, - 并启用 two_phase 选项。 - - - - pg_createsubscriber会使用pg_resetwal - 修改系统标识符。 - 这样可以避免目标服务器可能使用源服务器的 WAL 文件。 - 如果目标服务器还有备库,复制将会中断,应创建一个新的备库。 - - - - 若缺少必需 WAL 文件,复制可能失败。 - 为避免该问题,源服务器应将 - 设置为-1, - 以确保必需 WAL 文件不会被提前移除。 - - - - - 工作原理 - - - 基本思路是从源服务器获得复制起点,并从该位置开始建立逻辑复制: - - - - - - 使用指定命令行选项启动目标服务器。 - 若目标服务器已在运行,pg_createsubscriber会报错终止。 - - - - - - 检查目标服务器是否可以转换,同时也会对源服务器进行一些检查。 - 若任一前置条件不满足,pg_createsubscriber会报错终止。 - - - - - - 在源服务器上为每个指定的数据库创建一个发布和一个复制槽。 - 每个发布都以FOR ALL - TABLES创建。 - 若未指定,发布名称模式为 - pg_createsubscriber_%u_%x - (参数:数据库oid、随机int)。 - 若未指定,复制槽的名称模式如下: - pg_createsubscriber_%u_%x - (参数:数据库oid、随机int)。 - 这些复制槽将在后续步骤中被订阅使用。最后一个复制槽的 LSN 会在 - 参数中用作停止点,也会被订阅用作复制起点。 - 这样可以保证不会丢失任何事务。 - - - - - - 将恢复参数写入目标数据目录并重启目标服务器。 - 它指定了恢复将推进到的预写式日志位置的 LSN()。 - 它还将promote指定为服务器在达到恢复目标后应执行的动作。 - 为了避免恢复过程中出现意外行为,还会添加其他恢复参数,例如在达到一致状态后就结束恢复 - (实际上 WAL 应继续应用到复制起始位置)以及因多个恢复目标而导致失败。 - 当服务器退出备库模式并接受读写事务时,该步骤结束。 - 如果设置了选项,而恢复在给定秒数内没有结束, - pg_createsubscriber就会终止。 - - - - - - 在目标服务器上为每个指定数据库创建订阅。 - 若未指定,名称模式为 - pg_createsubscriber_%u_%x - (参数:数据库oid、随机int)。 - 该订阅不会复制源服务器上的现有数据,也不会创建复制槽, - 而是使用前一步中创建的复制槽。订阅会被创建,但尚不启用, - 因为必须在启动复制之前先将复制进度设置到复制起点。 - - - - - - 删除在目标服务器上被复制过来的发布(这些发布是在复制起点前创建的), - 它们在订阅者上没有用途。 - - - - - - 将每个订阅的复制进度设置为复制起点。 - 当目标服务器开始恢复过程时,它会追赶到复制起点。 - 这正是每个订阅要用作初始复制位置的 LSN。 - 由于订阅已经创建,因此可以取得复制源名称。 - 使用复制源名称和复制起点调用 - pg_replication_origin_advance() - 以设置初始复制位置。 - - - - - - 在目标服务器上启用每个指定数据库的订阅。 - 订阅将从复制起点开始应用事务。 - - - - - - 若备库使用了, - 该复制槽之后不再有用,故将其删除。 - - - - - - 更新目标服务器上的系统标识符。会运行 - 来修改系统标识符。由于pg_resetwal的要求,目标服务器会被停止。 - - - - - - - - 示例 - - - 要从位于foo的物理副本为数据库 - hrfinance创建逻辑副本: - -$ pg_createsubscriber -D /usr/local/pgsql/data -P "host=foo" -d hr -d finance - - - - - - 另见 - - - - - - diff --git a/zh/14/ref/pg_ctl-ref.sgml b/zh/14/ref/pg_ctl-ref.sgml index 6085da56..3ca8066b 100644 --- a/zh/14/ref/pg_ctl-ref.sgml +++ b/zh/14/ref/pg_ctl-ref.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation pg_ctl 1 - Application + 应用程序 @@ -158,7 +158,7 @@ PostgreSQL documentation - 模式会关闭在指定数据目录中运行的服务器。可以使用选项选择三种不同的关闭方法。Smart模式不允许新连接,然后等待所有现有客户端断开。如果服务器处于热备状态,那么在所有客户端断开后,恢复和流复制都会终止。Fast模式(默认值)不等待客户端断开。所有活动事务都会回滚,客户端会被强制断开,然后服务器关闭。Immediate模式会立即中止所有服务器进程,而不执行干净关闭。这样会导致服务器在下次启动时进入一次崩溃恢复周期。 + 模式会关闭在指定数据目录中运行的服务器。可以使用选项选择三种不同的关闭方法。Smart模式不允许新连接,然后等待所有现有客户端断开,以及所有在线备份结束。如果服务器处于热备状态,那么在所有客户端断开后,恢复和流复制都会终止。Fast模式(默认值)不等待客户端断开,并会终止正在进行的在线备份。所有活动事务都会回滚,客户端会被强制断开,然后服务器关闭。Immediate模式会立即中止所有服务器进程,而不执行干净关闭。这样会导致服务器在下次启动时进入一次崩溃恢复周期。 diff --git a/zh/14/ref/pg_dump.sgml b/zh/14/ref/pg_dump.sgml index 12744c5b..31f71136 100644 --- a/zh/14/ref/pg_dump.sgml +++ b/zh/14/ref/pg_dump.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_dump 1 - Application + 应用程序 @@ -351,7 +351,7 @@ PostgreSQL documentation pg_dump 只能中止转储。 - 要执行并行转储,数据库服务器需要支持同步快照。这一特性是在 + 要获得一致的备份,数据库服务器需要支持同步快照。这一特性是在 PostgreSQL 9.2 中为主库引入的,在 10 中为 备库引入。有了这个特性,数据库客户端即使使用不同连接,也能保证 看到相同的数据集。pg_dump -j 会使用多个数据库连接: @@ -359,6 +359,9 @@ PostgreSQL documentation 同步快照特性,就无法保证各个工作任务在各自连接中看到相同的数据,这会 导致备份不一致。 + + 如果要对 9.2 之前的服务器执行并行转储,必须确保从领导者进程连接数据库起,到最后一个工作任务连接数据库为止,数据库内容都不发生变化。最简单的方法是在开始备份之前,暂停所有访问数据库并修改数据的进程(DDL 和 DML)。对 9.2 之前的PostgreSQL服务器运行pg_dump -j时,还必须指定参数。 + @@ -1043,6 +1046,13 @@ PostgreSQL documentation + + + + 此选项允许对 9.2 之前的服务器运行pg_dump -j,更多详情请参阅参数的文档。 + + + diff --git a/zh/14/ref/pg_dumpall.sgml b/zh/14/ref/pg_dumpall.sgml index bdec2662..831f8592 100644 --- a/zh/14/ref/pg_dumpall.sgml +++ b/zh/14/ref/pg_dumpall.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_dumpall 1 - Application + 应用程序 @@ -32,7 +32,7 @@ PostgreSQL documentation pg_dumpall是一个实用程序,用于写出(转储)一个集簇中的所有PostgreSQL数据库到一个脚本文件中。该脚本文件包含SQL命令,可作为的输入来恢复这些数据库。它通过对集簇中的每个数据库调用来实现这一点。pg_dumpall还会转储所有数据库共有的全局对象,即数据库角色、表空间以及配置参数的权限授予。 + linkend="app-psql"/>的输入来恢复这些数据库。它通过对集簇中的每个数据库调用来实现这一点。pg_dumpall还会转储所有数据库共有的全局对象,即数据库角色、表空间。 (pg_dump不会保存这些对象。) diff --git a/zh/14/ref/pg_isready.sgml b/zh/14/ref/pg_isready.sgml index 2e93dde1..a09f7745 100644 --- a/zh/14/ref/pg_isready.sgml +++ b/zh/14/ref/pg_isready.sgml @@ -13,7 +13,7 @@ PostgreSQL documentation pg_isready 1 - Application + 应用程序 diff --git a/zh/14/ref/pg_receivewal.sgml b/zh/14/ref/pg_receivewal.sgml index 0aa360f8..23f9f189 100644 --- a/zh/14/ref/pg_receivewal.sgml +++ b/zh/14/ref/pg_receivewal.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation pg_receivewal 1 - Application + 应用程序 diff --git a/zh/14/ref/pg_recvlogical.sgml b/zh/14/ref/pg_recvlogical.sgml index 993fc2a9..a9830c1f 100644 --- a/zh/14/ref/pg_recvlogical.sgml +++ b/zh/14/ref/pg_recvlogical.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation pg_recvlogical 1 - Application + 应用程序 @@ -44,11 +44,7 @@ PostgreSQL documentation pg_recvlogical没有与逻辑解码 SQL 接口中 peek 和 get 模式等价的功能。它会在接收数据期间惰性地为这些数据发送回放确认,并在正常退出时发送确认。若要在不消费数据的情况下检查某个槽上的待处理数据,请使用pg_logical_slot_peek_changes - - 在没有致命错误的情况下,pg_recvlogical会一直运行,直到收到 - SIGINTControlC) - 或 SIGTERM 信号。 - + pg_recvlogical 收到 SIGHUP 信号时, @@ -74,14 +70,6 @@ PostgreSQL documentation 为由指定的数据库,使用指定的输出插件, 创建一个名称由指定的新逻辑复制槽。 - - - 此操作必须指定 。 - - - - 可与 一起指定 选项。 - @@ -91,9 +79,6 @@ PostgreSQL documentation 删除由指定名称的复制槽,然后退出。 - - 此操作必须指定 。 - @@ -105,10 +90,6 @@ PostgreSQL documentation 如果服务端的更改流因服务器关闭或断开连接而结束,则除非指定了,否则会循环重试。 - - 此操作必须指定 。 - - 流格式由创建该槽时指定的输出插件决定。 @@ -134,7 +115,6 @@ PostgreSQL documentation - 模式下,当接收达到指定的 LSN 时,自动停止复制,并以正常退出状态 0 退出。 如果在非模式下指定,则会报错。 @@ -151,26 +131,15 @@ PostgreSQL documentation - - - - - 启用后会将该槽同步到备库。此选项只能与 一起指定。 - - - + - 将接收到并解码后的事务数据写入该文件。指定-表示写入stdout - - 此参数对于 操作是必需的。 - @@ -178,10 +147,9 @@ PostgreSQL documentation - 指定pg_recvlogical应当以多高的频率发起fsync()调用, - 以确保输出文件被安全地刷入磁盘。 + 以确保输出文件安全刷盘。 @@ -200,7 +168,6 @@ PostgreSQL documentation - 模式下,从给定的 LSN 开始复制。关于其影响的详细信息,请参见 中的说明。 @@ -212,7 +179,6 @@ PostgreSQL documentation - 当指定且指定名称的槽已存在时,不报错。 @@ -223,7 +189,6 @@ PostgreSQL documentation - 当与服务器的连接丢失时,不要循环重试,直接退出。 @@ -234,7 +199,6 @@ PostgreSQL documentation - 将选项name传递给输出插件;如果指定了value, 则将其用作该选项的值。可用选项及其效果取决于所使用的输出插件。 @@ -246,7 +210,6 @@ PostgreSQL documentation - 创建该槽时,使用指定的逻辑解码输出插件。参见。 如果该槽已经存在,则此选项不起作用。 @@ -258,7 +221,6 @@ PostgreSQL documentation - 该选项与中同名选项的效果相同。参见该处说明。 @@ -269,35 +231,20 @@ PostgreSQL documentation - 模式下,使用名为slot_name的现有逻辑复制槽。 在模式下,以此名称创建该槽。 在模式下,删除此名称的槽。 - - 此参数对于任何一种操作都是必需的。 - - - - - (已废弃) - - - 启用对预备事务的解码。此选项只能与一起指定。 - - - - 启用详细模式。 @@ -314,14 +261,7 @@ PostgreSQL documentation - - 要连接到的数据库。其具体含义请参见各操作的说明。 - dbname可以是一个连接字符串。 - 如果是这种情况,连接字符串参数将覆盖任何冲突的命令行选项。 - - - 此参数在 操作中是必需的。 - + 要连接的数据库。有关其具体含义,请参阅各操作的说明。dbname可以是一个连接字符串。如果如此,连接字符串参数会覆盖任何与之冲突的命令行选项。默认值为用户名。 @@ -329,7 +269,7 @@ PostgreSQL documentation - + 指定服务器运行所在机器的主机名。如果该值以斜杠开头, 则它会被用作 Unix 域套接字的目录。默认值取自 PGHOST环境变量(如果已设置), @@ -342,7 +282,7 @@ PostgreSQL documentation - + 指定服务器监听连接所用的 TCP 端口,或本地 Unix 域套接字文件扩展名。 默认值取自PGPORT环境变量(如果已设置), 否则使用编译时的默认值。 @@ -354,7 +294,7 @@ PostgreSQL documentation - + 用于连接的用户名。默认为当前操作系统用户名。 @@ -364,7 +304,7 @@ PostgreSQL documentation - + 绝不提示输入密码。如果服务器要求密码认证,而密码又无法通过 .pgpass文件等其他方式获得, 则连接尝试将失败。此选项适用于批处理作业和脚本, @@ -377,7 +317,7 @@ PostgreSQL documentation - + 强制pg_recvlogical在连接数据库之前提示输入密码。 @@ -411,7 +351,7 @@ PostgreSQL documentation - + 显示pg_recvlogical命令行参数的帮助并退出。 @@ -420,14 +360,7 @@ PostgreSQL documentation - - 退出状态 - - 当收到 SIGINTSIGTERM 信号终止时, - pg_recvlogical会以状态 0 退出。(这是其正常结束方式,因此不视为错误。) - 遇到致命错误或其他信号时,退出状态为非零。 - - + diff --git a/zh/14/ref/pg_resetwal.sgml b/zh/14/ref/pg_resetwal.sgml index 9deadc8c..7dee0bce 100644 --- a/zh/14/ref/pg_resetwal.sgml +++ b/zh/14/ref/pg_resetwal.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_resetwal 1 - Application + 应用程序 diff --git a/zh/14/ref/pg_restore.sgml b/zh/14/ref/pg_restore.sgml index 7ae86b39..8cd4af1a 100644 --- a/zh/14/ref/pg_restore.sgml +++ b/zh/14/ref/pg_restore.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_restore 1 - Application + 应用程序 diff --git a/zh/14/ref/pg_rewind.sgml b/zh/14/ref/pg_rewind.sgml index 16ffc2e9..93617f49 100644 --- a/zh/14/ref/pg_rewind.sgml +++ b/zh/14/ref/pg_rewind.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation pg_rewind 1 - Application + 应用程序 diff --git a/zh/14/ref/pg_verifybackup.sgml b/zh/14/ref/pg_verifybackup.sgml index a2afbec0..6cbb79a6 100644 --- a/zh/14/ref/pg_verifybackup.sgml +++ b/zh/14/ref/pg_verifybackup.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_verifybackup 1 - Application + 应用程序 @@ -28,32 +28,16 @@ PostgreSQL documentation 描述 - - pg_verifybackup用于依据服务器在备份时生成的 - backup_manifest,检查使用 - pg_basebackup获取的数据库集簇备份的完整性。备份 - 既可以采用“plain”格式,也可以采用“tar”格式;其中也包括使用 - pg_basebackup支持的任意算法压缩的 tar 格 - 式备份。不过,目前仅支持对 plain 格式备份执行WAL - 验证。因此,如果备份采用 tar 格式存储,应使用 - -n, --no-parse-wal选项。 - + pg_verifybackup用于检查通过pg_basebackup获取的数据库集簇备份的完整性,检查依据是服务器在备份时生成的backup_manifest。备份必须以“普通文件”格式存储;“tar”格式的备份可以在解包后检查。 需要注意,pg_verifybackup执行的验证并未、也 不可能涵盖运行中的服务器在尝试使用该备份时会执行的每一项检查。即使使 - 用了此工具,你仍应进行测试恢复,并确认生成的数据库按预期工作且包含正 - 确的数据。不过,pg_verifybackup能够检测出 + 用了此工具,你仍应进行测试恢复,并确认生成的数据库按预期工作且看起来包含正确的数据。不过,pg_verifybackup能够检测出 许多因存储问题或用户错误而常见的问题。 - - 备份验证分为四个阶段。首先,pg_verifybackup读取 - backup_manifest文件。如果该文件不存在、无法读取、 - 格式不正确、其系统标识符与备份目录中的pg_control - 不匹配,或者未能通过其自身内部校验和的验证, - pg_verifybackup就会以致命错误终止。 - + 备份验证分为四个阶段。首先,pg_verifybackup读取backup_manifest文件。如果该文件不存在、无法读取、格式不正确,或者未能通过其自身内部校验和的验证,pg_verifybackup就会以致命错误终止。 其次,pg_verifybackup将尝试验证当前存储在磁盘上 @@ -118,41 +102,6 @@ PostgreSQL documentation - - - - - - 指定备份格式。format可以是下列值之一: - - - - p - plain - - - 备份由普通文件组成,其布局与源服务器的数据目录和表空间相同。 - - - - - - t - tar - - - 备份由 tar 文件组成,这些文件可以经过压缩。有效的备份包括名为 - base.tar的主数据目录、名为 - pg_wal.tar的 WAL 文件,以及每个表空间 - 对应的单独 tar 文件,这些文件以该表空间的 OID 命名。如果备份 - 被压缩,则会在每个文件名末尾追加相应的压缩扩展名。 - - - - - - - @@ -188,19 +137,6 @@ PostgreSQL documentation - - - - - - 启用进度报告。启用此选项后,在验证校验和时会输出进度报告。 - - - 此选项不能与一起使用。 - - - - @@ -237,9 +173,9 @@ PostgreSQL documentation - 还提供下列其他选项: + 其他选项也可用: - + @@ -270,7 +206,7 @@ PostgreSQL documentation 示例 - 要在mydbserver上创建服务器的基础备份,并验证该备 + 要为位于mydbserver的服务器创建基础备份,并验证该备 份的完整性: $ pg_basebackup -h mydbserver -D /usr/local/pgsql/data @@ -279,7 +215,7 @@ PostgreSQL documentation - 要在mydbserver上创建服务器的基础备份,将备份清单 + 要为位于mydbserver的服务器创建基础备份,将备份清单 移到备份目录之外的位置,然后验证该备份: $ pg_basebackup -h mydbserver -D /usr/local/pgsql/backup1234 diff --git a/zh/14/ref/pg_waldump.sgml b/zh/14/ref/pg_waldump.sgml index a4433e63..baa4bb42 100644 --- a/zh/14/ref/pg_waldump.sgml +++ b/zh/14/ref/pg_waldump.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_waldump 1 - Application + 应用程序 diff --git a/zh/14/ref/pg_walsummary.sgml b/zh/14/ref/pg_walsummary.sgml deleted file mode 100644 index b3abba5e..00000000 --- a/zh/14/ref/pg_walsummary.sgml +++ /dev/null @@ -1,125 +0,0 @@ - - - - - pg_walsummary - - - - pg_walsummary - 1 - Application - - - - pg_walsummary - 打印 WAL 汇总文件的内容 - - - - - pg_walsummary - option - file - - - - - 描述 - - pg_walsummary用于打印 WAL 汇总文件的内容。 - 这些二进制文件位于数据目录下的pg_wal/summaries子目录中, - 可使用本工具将其转换为文本。 - 通常并无此必要,因为 WAL 汇总文件主要是为了支持 - 增量备份而存在的, - 但在调试时可能会很有用。 - - - - WAL 汇总文件按表空间 OID、关系 OID 以及关系分支(fork)建立索引。 - 对于每个关系分支,它都存储该文件所汇总范围内被 WAL 修改的块列表。 - 它还可以存储一个limit block: - 如果该关系分支在相关 WAL 范围内被创建或截断,则其值为 0; - 否则,其值为该关系分支被截断后的最短长度。 - 如果该关系分支在相关 WAL 范围内未被创建、删除或截断, - 则 limit block 未定义,或者为无穷大,本工具不会打印它。 - - - - - 选项 - - - - - - - - - 默认情况下,pg_walsummary会为每个由一个或多个连续已修改块构成的范围输出一行。 - 这样可以使输出简洁得多,因为如果某个关系中从 0 到 999 的所有块都被修改了, - 则只会输出一行,而不是 1000 行单独的输出。 - 该选项要求为每个已修改块分别输出一行。 - - - - - - - - - - 除错误之外不打印任何输出。 - 当只想知道某个 WAL 汇总文件能否被成功解析,而并不关心其内容时,这会很有用。 - - - - - - - - - - 显示版本信息,然后退出。 - - - - - - - - - - 显示pg_walsummary命令行参数的帮助并退出。 - - - - - - - - - - - 环境 - - - 环境变量PG_COLOR用于指定是否在诊断消息中使用颜色。 - 可能的值为alwaysauto和 - never。 - - - - - 另见 - - - - - - - - diff --git a/zh/14/ref/pgarchivecleanup.sgml b/zh/14/ref/pgarchivecleanup.sgml index 5c2c0a53..fd4da23e 100644 --- a/zh/14/ref/pgarchivecleanup.sgml +++ b/zh/14/ref/pgarchivecleanup.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_archivecleanup 1 - Application + 应用程序 diff --git a/zh/14/ref/pgbench.sgml b/zh/14/ref/pgbench.sgml index cbade471..e0fa9e55 100644 --- a/zh/14/ref/pgbench.sgml +++ b/zh/14/ref/pgbench.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation pgbench 1 - Application + 应用程序 @@ -1685,7 +1685,7 @@ SELECT 4 AS four \; SELECT 5 AS five \aset greatest ( number , ... ) - double 如果任何参数是双精度的,否则 integer + 若任一参数为 double,则为 double,否则为 integer 选择参数中的最大值。 @@ -1755,7 +1755,7 @@ SELECT 4 AS four \; SELECT 5 AS five \aset least ( number , ... ) - double 如果任何参数是双精度的,否则 integer + 若任一参数为 double,则为 double,否则为 integer 选择参数中的最小值。 @@ -2602,7 +2602,7 @@ PGOPTIONS='-c default_table_access_method=wuzza' 安全性 - 如果不可信用户能够访问尚未采用模式的安全使用方式的数据库,就不要在该数据库中运行pgbenchpgbench使用非限定名称,并且不会更改搜索路径。 + 如果不受信任的用户能够访问尚未采用模式的安全使用方式的数据库,就不要在该数据库中运行pgbenchpgbench使用非限定名称,并且不会更改搜索路径。 diff --git a/zh/14/ref/pgtestfsync.sgml b/zh/14/ref/pgtestfsync.sgml index 86e69b30..6055bccf 100644 --- a/zh/14/ref/pgtestfsync.sgml +++ b/zh/14/ref/pgtestfsync.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_test_fsync 1 - Application + 应用程序 diff --git a/zh/14/ref/pgtesttiming.sgml b/zh/14/ref/pgtesttiming.sgml index f652980f..dc7208fc 100644 --- a/zh/14/ref/pgtesttiming.sgml +++ b/zh/14/ref/pgtesttiming.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_test_timing 1 - Application + 应用程序 diff --git a/zh/14/ref/pgupgrade.sgml b/zh/14/ref/pgupgrade.sgml index de30fcdc..beb0bfea 100644 --- a/zh/14/ref/pgupgrade.sgml +++ b/zh/14/ref/pgupgrade.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_upgrade 1 - Application + 应用程序 @@ -40,8 +40,8 @@ PostgreSQL documentation pg_upgrade(以前称为 pg_migrator)允许将存储在 PostgreSQL 数据文件中的数据升级到更新的 PostgreSQL主版本,而无需执行主版本升级通常所需的数据转储/恢复, - 例如从 12.14 升级到 13.10,或从 14.9 升级到 15.5。它不用于次版本升级, - 例如从 12.7 升级到 12.8 或从 14.1 升级到 14.5。 + 例如从 9.5.8 升级到 9.6.4,或从 10.7 升级到 11.2。次版本升级不需要使用它, + 例如从 9.6.2 升级到 9.6.3 或从 10.1 升级到 10.2。 @@ -59,7 +59,7 @@ PostgreSQL documentation - pg_upgrade 支持从 9.2.X 及更高版本升级到当前 + pg_upgrade 支持从 9.0.X 及更高版本升级到当前 PostgreSQL主版本,包括快照版和 beta 版。 @@ -112,7 +112,7 @@ PostgreSQL documentation - 要使用的并发连接和进程/线程数 + 要使用的并发进程或线程数 @@ -122,17 +122,7 @@ PostgreSQL documentation 使用硬链接而不是把文件复制到新集簇 - - - - - - 默认情况下,pg_upgrade 会等待升级后集簇的所有文件都被安全地写入磁盘。 - 该选项会使 pg_upgrade 不等待即返回,这样更快,但也意味着后续若发生 - 操作系统崩溃,数据目录可能会损坏。通常来说,这个选项适用于测试,但不应在生产安装中使用。 - - - + options @@ -206,118 +196,17 @@ PostgreSQL documentation - - - - - 将文件复制到新集簇。这是默认行为。(另见 - 、 - 。) - - - - - - - - 使用 copy_file_range 系统调用进行高效复制。在某些文件系统上, - 这会产生与 类似的结果,即共享物理磁盘块;在另一些文件系统上, - 它仍然会复制块,但会通过优化路径完成。目前,它在 Linux 和 FreeBSD 上受支持。 - - - - - - - - 不要把旧集簇中的统计信息恢复到新集簇中。 - - - - - option - - - 手工设置新集簇默认的 char 有符号性。可选值为 - signedunsigned。 - - - 在 C 语言中,char 类型在未显式指定时的默认有符号性因平台而异。 - 例如,在 x86 CPU 上 char 默认是 signed char, - 而在 ARM CPU 上默认是 unsigned char。 - - - 从 PostgreSQL 18 开始,数据库集簇会维护自身默认的 - char 有符号性设置,可用于确保在默认 char 有符号性不同的平台之间保持一致行为。 - 默认情况下,pg_upgrade 在从现有集簇升级时会保留该有符号性设置。 - 然而,从 PostgreSQL 17 或更早版本升级时, - pg_upgrade 会采用其构建所在平台的 char 有符号性。 - - - 该选项允许你显式设置新集簇默认的 char 有符号性,以覆盖任何继承值。 - 该选项主要适用于以下两种场景: - - - - 如果你计划在升级后迁移到不同平台,则不应使用该选项。在这种情况下,默认行为才是正确的。 - 应当先在原平台上不带此选项完成升级,然后再迁移集簇。这是推荐且最安全的方法。 - - - - - 如果你已经将集簇迁移到了默认 char 有符号性不同的平台上 - (例如从基于 x86 的系统迁移到基于 ARM 的系统),则应使用该选项来指定与原平台 - 默认 char 有符号性相匹配的值。此外,从迁移数据文件到运行 - pg_upgrade 之间,切勿修改任何数据文件。 - pg_upgrade 应当是新平台上首次启动该集簇的操作。 - - - - - - - - - - - 将数据目录从旧集簇移动到新集簇,然后用为新集簇生成的系统目录文件替换原有目录文件。 - 该模式的性能可能优于 、 - ,尤其是在关系很多的集簇上。 - - - 但是,这种模式会在旧集簇中产生大量垃圾文件,如果使用 - ,可能会延长文件同步步骤。因此, - 建议在 模式下使用 。 - - - 此外,一旦文件传输步骤开始,旧集簇就会被破坏性修改,因此不再能安全启动。 - 详见 。 - - - - - method - - - 设置为 fsync(默认)时,pg_upgrade 会递归打开并同步 - 升级后集簇数据目录中的所有文件。查找文件时会跟随 WAL 目录和各个已配置表空间的符号链接。 - - - 在 Linux 上,也可以使用 syncfs,让操作系统同步包含升级后集簇数据目录、 - 其 WAL 文件以及各个表空间的整个文件系统。见 - 了解使用 syncfs - 时需要注意的事项。 - - - 当使用 时,此选项无效。 - - - + + + + + + @@ -433,18 +322,11 @@ make prefix=/usr/local/pgsql.new install 停止两个服务器 - - 确保两个数据库服务器都已停止,在 Unix 上例如: - - -pg_ctl -D /opt/PostgreSQL/12 stop + 确保两个数据库服务器都已停止。例如,在 Unix 上使用: +pg_ctl -D /opt/PostgreSQL/9.6 stop pg_ctl -D /opt/PostgreSQL/&majorversion; stop - - - 或者在 Windows 上使用合适的服务名: - - -NET STOP postgresql-12 +或者在 Windows 上使用正确的服务名: +NET STOP postgresql-9.6 NET STOP postgresql-&majorversion; @@ -473,7 +355,7 @@ NET STOP postgresql-&majorversion; 始终运行新服务器的 pg_upgrade 二进制,而不是旧服务器的。 pg_upgrade 需要指定新旧集簇的数据目录和可执行文件 (bin)目录。你还可以指定用户和端口值,以及是否希望将数据文件 - 链接、克隆或交换,而不是采用默认的复制行为。 + 链接或克隆,而不是采用默认的复制行为。 @@ -481,37 +363,21 @@ NET STOP postgresql-&majorversion; 新集簇,就无法再访问旧集簇。链接模式还要求新旧集簇的数据目录位于同一文件系统中。 (表空间和 pg_wal 可以位于不同文件系统中。)克隆模式具有相同的 速度和磁盘空间优势,但在启动新集簇后不会使旧集簇不可用。克隆模式同样要求新旧数据目录 - 位于同一文件系统中。该模式只在某些操作系统和文件系统上可用。如果关系很多,交换模式 - 可能最快,但一旦文件传输步骤开始,你将无法再访问旧集簇。交换模式也要求新旧集簇的数据 - 目录位于同一文件系统中。 - - - - 将 设置为 2 或更高可以让 pg_upgrade 并行处理多个数据库和表空间。 - 一个不错的起始值是机器上的 CPU 核心数。对于多数据库、多表空间的服务器,此选项可以显著 - 减少升级时间。 + 位于同一文件系统中。该模式只在某些操作系统和文件系统上可用。 - - 对于 Windows 用户,必须登录到管理员账户,然后以带引号的目录运行 - pg_upgrade,例如: + 选项允许使用多个 CPU 核心复制/链接文件,并行转储和恢复数据库模式;一个不错的起始值是 CPU 核心数与表空间数量中的较大值。对于运行在多处理器机器上的多数据库服务器,此选项可以显著减少升级时间。 - + Windows 用户必须先登录管理员帐号,然后以 postgres 用户身份启动 shell,并设置正确的路径: +RUNAS /USER:postgres "CMD.EXE" +SET PATH=%PATH%;C:\Program Files\PostgreSQL\&majorversion;\bin; +然后运行 pg_upgrade,并用引号括起目录,例如: pg_upgrade.exe - --old-datadir "C:/Program Files/PostgreSQL/12/data" + --old-datadir "C:/Program Files/PostgreSQL/9.6/data" --new-datadir "C:/Program Files/PostgreSQL/&majorversion;/data" - --old-bindir "C:/Program Files/PostgreSQL/12/bin" + --old-bindir "C:/Program Files/PostgreSQL/9.6/bin" --new-bindir "C:/Program Files/PostgreSQL/&majorversion;/bin" - - - 启动后,pg_upgrade 会验证两个集簇是否兼容,然后执行升级。 - 即使旧服务器仍在运行,也可以使用 pg_upgrade --check 仅执行检查。 - pg_upgrade --check 还会概述升级后需要手工进行的调整。如果你打算 - 使用链接、克隆、copy-file-range 或交换模式,则应将 、 - 或 - 一起使用,以启用对应模式的专用检查。 - pg_upgrade 需要对当前目录具有写权限。 - +启动后,pg_upgrade会验证两个集簇是否兼容,然后执行升级。你可以使用 pg_upgrade --check 仅执行检查,即使旧服务器仍在运行。pg_upgrade --check还会概述升级后需要手工进行的调整。如果你打算使用链接或克隆模式,则应将选项 一起使用,以启用对应模式的专用检查。pg_upgrade需要对当前目录具有写权限。 显然,在升级期间不应有人访问这些集簇。pg_upgrade @@ -592,30 +458,12 @@ pg_upgrade.exe 运行 <application>rsync</application> - - 在使用链接模式时,可以通过 rsync 快速升级备库。 - 为此,在主库上选择一个位于新旧数据库集簇目录之上的目录,并在 - 主库上针对每个备库运行: - - + 在使用链接模式时,可以通过 rsync 快速升级备库。为此,在主库上选择一个位于新旧数据库集簇目录之上的目录,并在主库上针对每个备库运行: rsync --archive --delete --hard-links --size-only --no-inc-recursive old_cluster new_cluster remote_dir - - - 其中, 是相对于 - 主库当前目录的路径, 则是备库上位于新旧集簇目录 - 上层的目录。主库和备库在指定目录下的目录结构必须一致。 - 关于如何指定远程目录的细节,请参阅 rsync 手册页,例如: - - -rsync --archive --delete --hard-links --size-only --no-inc-recursive /opt/PostgreSQL/12 \ - /opt/PostgreSQL/&majorversion; standby.example.com:/opt/PostgreSQL - - - 你可以使用 rsync 选项来验证 - 命令将执行什么操作。尽管至少要在主库上为一个备库运行 - rsync,但只要某个已升级的备库尚未启动,也可以在该备库上 - 运行 rsync 来升级其他备库。 - +其中, 是相对于主库当前目录的路径,则是备库上位于新旧集簇目录上层的目录。主库和备库在指定目录下的目录结构必须一致。请参阅 rsync 手册页,了解如何指定远程目录,例如: +rsync --archive --delete --hard-links --size-only --no-inc-recursive /opt/PostgreSQL/9.5 \ + /opt/PostgreSQL/9.6 standby.example.com:/opt/PostgreSQL +你可以使用 rsync 选项来验证命令将执行什么操作。尽管至少要在主库上为一个备库运行 rsync,但也可以运行 rsync 来升级其他备库,运行位置是某个已升级且尚未启动的备库。 其原理是记录主库上新旧集簇文件之间由 pg_upgrade @@ -625,31 +473,16 @@ rsync --archive --delete --hard-links --size-only --no-inc-recursive /opt/Postgr 临时表和不记录 WAL 的表相关的文件,因为这些文件通常不存在于备库上。 - - 如果你有表空间,则需要对每个表空间目录运行类似的 - rsync 命令,例如: - - -rsync --archive --delete --hard-links --size-only --no-inc-recursive /vol1/pg_tblsp/PG_12_201909212 \ - /vol1/pg_tblsp/PG_&majorversion;_202307071 standby.example.com:/vol1/pg_tblsp - - - 如果你把 pg_wal 迁移到了数据目录之外,也必须对这些目录运行 - rsync。 - + 如果你有表空间,则需要对每个表空间目录运行类似的 rsync 命令,例如: +rsync --archive --delete --hard-links --size-only --no-inc-recursive /vol1/pg_tblsp/PG_9.5_201510051 \ + /vol1/pg_tblsp/PG_9.6_201608131 standby.example.com:/vol1/pg_tblsp +如果你把 pg_wal 迁移到了数据目录之外,也必须对这些目录运行 rsync 配置流复制和日志传送备库 - - 为服务器配置日志传送。(由于备库仍与主库保持同步,因此无需运行 - pg_backup_start()pg_backup_stop(), - 也无需进行文件系统备份。)如果旧主库早于 17.0,则主库上的任何槽都不会复制到新备库, - 因此旧备库上的所有槽都必须手工重建。如果旧主库为 17.0 或更高版本, - 则只有主库上的逻辑槽会复制到新备库,而旧备库上的其他槽不会复制, - 因此也必须手工重建。 - + 为服务器配置日志传送。(由于备库仍与主库保持同步,因此无需运行pg_start_backup()pg_stop_backup(),也无需进行文件系统备份。)复制槽不会被复制,必须重建。 @@ -700,28 +533,13 @@ psql --username=postgres --file=script.sql postgres 统计信息 - - 除非指定 pg_upgrade 会将大多数 - 优化器统计信息从旧集簇传输到新集簇。但这不会传输所有统计信息,例如通过 - 显式创建的统计信息、扩展添加的自定义统计信息, - 或由累积统计系统收集的统计信息。 - - - 由于并非所有统计信息都会由 pg_upgrade 传输,升级结束时你会被要求 - 运行命令来重新生成这些信息。你可能需要设置连接参数以匹配新集簇。 - - - 首先,使用 - vacuumdb --all --analyze-in-stages --missing-stats-only - 为尚无统计信息的关系快速生成最基本的优化器统计信息。然后,使用 - vacuumdb --all --analyze-only 以确保所有关系都拥有最新的累积统计信息, - 用于触发 vacuum 和 analyze。对于这两个命令,使用 都可以加快速度。 - 如果 vacuum_cost_delay 被设置为非零值,可以通过 - PGOPTIONS 覆盖它来加快统计信息生成,例如 PGOPTIONS='-c - vacuum_cost_delay=0' vacuumdb ...。 - + + + + + 由于优化器统计信息不会由pg_upgrade传输,升级结束时你会被要求运行命令来重新生成这些信息。你可能需要设置连接参数以匹配新集簇。 @@ -748,10 +566,7 @@ psql --username=postgres --file=script.sql postgres - - 如果既没有使用 ,也没有使用 , - 旧集簇不会被修改;可以重新启动。 - + 如果选项没有被使用,旧集簇就未被修改,可以重新启动。 @@ -786,142 +601,19 @@ psql --username=postgres --file=script.sql postgres - - - 如果使用了 选项,旧集簇可能已经被破坏性修改: - - - - 如果 pg_upgrade 在报告旧集簇不再能安全启动之前中止, - 则旧集簇没有被修改;可以重新启动。 - - - - - - 如果 pg_upgrade 已报告旧集簇不再能安全启动, - 则旧集簇已经被破坏性修改。在这种情况下,旧集簇必须从备份恢复。 - - - - - - - 环境 - - - 一些环境变量可以为命令行选项提供默认值: - - - - PGBINOLD - - - - 旧 PostgreSQL 可执行文件目录;选项 - /。 - - - - - - PGBINNEW - - - - 新 PostgreSQL 可执行文件目录;选项 - /。 - - - - - - PGDATAOLD - - - - 旧数据库集簇配置目录;选项 - /。 - - - - - - PGDATANEW - - - - 新数据库集簇配置目录;选项 - /。 - - - - - - PGPORTOLD - - - - 旧集簇端口号;选项 - /。 - - - - - - PGPORTNEW - - - 新集簇端口号;选项 - /。 - - - - - - PGSOCKETDIR - - - - 升级期间用于 postmaster 套接字的目录;选项 - /。 - - - - - - PGUSER - - - - 集簇安装用户名称;选项 - /。 - - - - - - 注解 - - pg_upgrade 会创建各种工作文件,例如模式转储,并将它们存放在 - 新集簇目录下的 pg_upgrade_output.d 中。每次运行都会新建一个 - 以 ISO 8601 格式时间戳(%Y%m%dT%H%M%S)命名的子目录,其中保存 - 该次运行生成的全部文件。pg_upgrade_output.d 及其中的文件会在 - pg_upgrade 成功完成后被自动删除;但如果出现问题, - 那里的文件可能提供有用的调试信息。 - + pg_upgrade会在当前工作目录中创建各种工作文件,例如模式转储。为安全起见,请确保任何其他用户都无法读取或写入该目录。 pg_upgrade 会在新旧数据目录中启动短生命周期的 postmaster。 @@ -958,6 +650,10 @@ psql --username=postgres --file=script.sql postgres (regclassregroleregtype 可以升级。) + 如果正在升级PostgreSQL 9.2 之前的集簇,而且它使用了只包含配置文件的目录,就必须把实际数据目录的位置传给pg_upgrade,并把配置目录的位置传给服务器,例如-d /real-data-directory -o '-D /configuration-directory' + + 如果旧服务器早于 9.1,而且使用非默认的 Unix 域套接字目录,或者其默认目录与新集簇的默认目录不同,请将PGHOST设置为旧服务器的套接字位置。(这与 Windows 无关。) + 如果你想使用链接模式,又不希望在启动新集簇时修改旧集簇,可以考虑使用克隆模式。 如果不可用,可以先复制旧集簇,再对该副本使用链接模式升级。要创建旧集簇的有效副本, diff --git a/zh/14/ref/postgres-ref.sgml b/zh/14/ref/postgres-ref.sgml index b62740d6..2e225e27 100644 --- a/zh/14/ref/postgres-ref.sgml +++ b/zh/14/ref/postgres-ref.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation postgres 1 - Application + 应用程序 @@ -97,18 +97,11 @@ PostgreSQL documentation 打印指定运行时参数的值并退出。 - (详情见上面的选项。)这会返回 + (详情见上面的选项。)这个选项可用于正在运行的服务器,它会返回 postgresql.conf中的值,并应用本次调用中提供的任何参数修改。它不反映 集簇启动时提供的参数。 - - 对于大多数参数,这个选项可以在运行中的服务器上使用。不过,对于某些在运行时计算出的参数, - 服务器必须先关闭(例如、 - 和 - )。 - - 该选项供其他与服务器实例交互的程序(例如)查询配置参数值之用。面向用户的应用则应使用SHOWpg_settings视图。 @@ -340,6 +333,13 @@ PostgreSQL documentation + + + + 此选项用于调试导致服务器进程异常终止的问题。在这种情况下,通常的策略是通知所有其他服务器进程必须终止,然后重新初始化共享内存和信号量。这是因为出错的服务器进程可能在终止前破坏了某些共享状态。此选项指定postgres不重新初始化共享数据结构。经验丰富的系统程序员随后可以使用调试器检查共享内存和信号量的状态。 + + + @@ -373,12 +373,7 @@ PostgreSQL documentation - - 该选项用于调试导致服务器 - 进程异常终止的问题。在这种情况下,通常的策略是通过向所有其他服务器进程发送SIGQUIT - 信号,通知它们必须终止。使用此选项时,则会改为发送SIGABRT, - 从而生成核心转储文件。 - + 此选项用于调试导致服务器进程异常终止的问题。在这种情况下,通常的策略是通知所有其他服务器进程必须终止,然后重新初始化共享内存和信号量。这是因为出错的服务器进程可能在终止前破坏了某些共享状态。此选项指定postgres通过发送SIGSTOP信号暂停所有其他服务器进程,但不使它们终止。这允许系统程序员手工收集所有服务器进程的核心转储。 @@ -532,7 +527,7 @@ PostgreSQL documentation - 表明另一台服务器已经在运行的失败消息 + 表明另一个服务器已经在运行的失败消息 应仔细检查,例如可根据你的系统使用下面的命令: $ ps ax | grep postgres @@ -721,7 +716,7 @@ PostgreSQL documentation - 参见 + 另见 , diff --git a/zh/14/ref/postmaster.sgml b/zh/14/ref/postmaster.sgml new file mode 100644 index 00000000..9e210cc1 --- /dev/null +++ b/zh/14/ref/postmaster.sgml @@ -0,0 +1,42 @@ + + + + + postmaster + + + + postmaster + 1 + 应用程序 + + + + postmaster + PostgreSQL数据库服务器 + + + + + postmaster + option + + + + + 描述 + + postmasterpostgres的一个已弃用别名。 + + + + 另见 + + + + + + diff --git a/zh/14/ref/prepare.sgml b/zh/14/ref/prepare.sgml index 6c456821..92ac658a 100644 --- a/zh/14/ref/prepare.sgml +++ b/zh/14/ref/prepare.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation PREPARE 7 - SQL - Language Statements + SQL - 语言语句 @@ -119,7 +119,7 @@ PREPARE name [ ( - 默认情况下,也就是当 设置为 + 默认情况下,也就是当 设置为 auto 时,服务器会自动为带参数的预备语句选择使用通 用计划还是自定义计划。当前规则是:前五次执行使用自定义计划,并计算这些 计划的平均估计代价;然后创建一个通用计划,并将其估计代价与自定义计划的 diff --git a/zh/14/ref/prepare_transaction.sgml b/zh/14/ref/prepare_transaction.sgml index 10d018b0..75776dab 100644 --- a/zh/14/ref/prepare_transaction.sgml +++ b/zh/14/ref/prepare_transaction.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation PREPARE TRANSACTION 7 - SQL - Language Statements + SQL - 语言语句 @@ -72,7 +72,7 @@ PREPARE TRANSACTION transaction_id - 当前不允许将执行过以下任一操作的事务置为预备状态:涉及临时表或会话临时命名空间的操作、创建任何WITH HOLD游标,或执行过LISTENUNLISTENNOTIFY。这些特性与当前会话绑定得过于紧密,因此在要进入预备状态的事务中没有意义。 + 当前不允许对执行过以下任一操作的事务执行PREPARE:涉及临时表或会话临时命名空间的操作、创建任何WITH HOLD游标,或执行过LISTENUNLISTENNOTIFY。这些特性与当前会话绑定得过于紧密,因此在要进入预备状态的事务中没有意义。 diff --git a/zh/14/ref/psql-ref.sgml b/zh/14/ref/psql-ref.sgml index f7651da7..3077773a 100644 --- a/zh/14/ref/psql-ref.sgml +++ b/zh/14/ref/psql-ref.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation psql 1 - Application + 应用程序 @@ -534,7 +534,7 @@ testdb=> - 如果不可信用户能够访问尚未采用模式的安全使用方式的数据库,请在会话开始时从search_path中移除所有公众可写的 schema。可以在连接字符串中加入options=-csearch_path=,或者在执行其他 SQL 命令之前发出SELECT pg_catalog.set_config('search_path', '', false)。这种考虑并非psql特有;它适用于任何执行任意 SQL 命令的接口。 + 如果不受信任的用户能够访问尚未采用模式的安全使用方式的数据库,请在会话开始时从search_path中移除所有公众可写的模式。可以在连接字符串中加入options=-csearch_path=,或者在执行其他 SQL 命令之前发出SELECT pg_catalog.set_config('search_path', '', false)。这种考虑并非psql特有;它适用于任何执行任意 SQL 命令的接口。 @@ -582,12 +582,9 @@ testdb=> 很多元命令作用在当前查询缓冲区上。这就是一个缓冲区而已,它保存任何已经被键入但是还没有发送到服务器执行的SQL命令文本。这将包括之前输入的行以及在该元命令同一行上出现在前面的任何文本。 - - 许多元命令还允许在命令名后追加 x 作为选项。这会使结果以扩展模式显示,就像使用了 \x\pset expanded 一样。 - - 定义了以下元命令: + 定义了以下元命令: @@ -599,56 +596,7 @@ testdb=> - - \bind [ parameter ] ... - - - - 为下一次查询执行设置查询参数,并将指定参数传给任意参数占位符($1 等)。 - - - - 示例: - -INSERT INTO tbl1 VALUES ($1, $2) \bind 'first value' 'second value' \g - - - - - 这对除 \g 之外的查询执行命令也有效,例如 \gx 和 - \gset。 - - - 此命令会使用扩展查询协议(参见),不同于psql通常使用的简单查询协议。因此,可以用它在psql中测试扩展查询协议。(即使查询没有参数,而且此命令指定了零个参数,也会使用扩展查询协议。)此命令只影响下一条被执行的查询;之后的所有查询默认仍会使用简单查询协议。 - - - - - - \bind_named statement_name [ parameter ] ... - - - - \bind_named 等同于 \bind,不同之处在于它把现有预备语句的名称作为第一个参数。空字符串表示未命名的预备语句。 - - - - 示例: - -INSERT INTO tbls1 VALUES ($1, $2) \parse stmt1 -\bind_named stmt1 'first value' 'second value' \g - - - - - 此命令会使用扩展查询协议(参见 - ),不同于psql通常使用的简单查询协议。因此,可以用它在psql中测试扩展查询协议。 - - - - \c\connect [ -reuse-previous=on|off ] [ dbname [ username ] [ host ] [ port ] | conninfo ] @@ -686,7 +634,7 @@ INSERT INTO tbls1 VALUES ($1, $2) \parse stmt1 - 示例: + 示例: => \c mydb myuser host.dom 6432 @@ -726,28 +674,6 @@ INSERT INTO tbls1 VALUES ($1, $2) \parse stmt1 - - \close_prepared prepared_statement_name - - - - 关闭指定的预备语句。空字符串表示未命名的预备语句。如果不存在该名称的预备语句,则该操作不执行任何操作。 - - - - 示例: - -SELECT $1 \parse stmt1 -\close_prepared stmt1 - - - - - 此命令会使用扩展查询协议,不同于psql通常使用的简单查询协议。因此,可以用它在psql中测试扩展查询协议。 - - - - \conninfo @@ -881,7 +807,7 @@ SELECT $1 \parse stmt1 - \d[Sx+] [ pattern ] + \d[S+] [ pattern ] @@ -914,66 +840,62 @@ SELECT $1 \parse stmt1 它等同于\dtvmsE,它将显示所有可见的表、视图、物化视图、序列和外部表的列表。 这纯粹是一种便利措施。 - - 与许多其他命令一样,如果在命令名后追加 x,结果会以扩展模式显示。但请注意,这只适用于不带 pattern 参数的 \d;并且 x 修饰符不能直接紧跟在 \d 后面(因为 \dx 是另一个命令)。x 只能出现在 S+ 修饰符之后。例如,\d+x 等同于 \dtvmsE+x,并以扩展模式显示所有关系的列表。 - - \da[Sx] [ pattern ] + \da[S] [ pattern ] 列出聚合函数,以及它们的返回类型和所作用的数据类型。如果指定了 pattern,则只显示名称与模式匹配的聚合。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。如果在命令名后追加 x,结果会以扩展模式显示。 - + class="parameter">pattern,则只显示名称与模式匹配的聚合。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。 - \dA[x+] [ pattern ] + \dA[+] [ pattern ] 列出访问方法。如果指定了 pattern,则只显示名称与模式匹配的访问方法。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则每个访问方法都会连同其关联的处理器函数和描述一起列出。 + class="parameter">pattern,则只显示名称与模式匹配的访问方法。如果在命令名后追加 +,则每个访问方法都会连同其关联的处理器函数和描述一起列出。 - \dAc[x+] + \dAc[+] [access-method-pattern [input-type-pattern]] - 列出操作符类(参见 )。如果指定了 access-method-pattern,则只列出与名称匹配该模式的访问方法关联的操作符类。如果指定了 input-type-pattern,则只列出与名称匹配该模式的输入类型关联的操作符类。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则每个操作符类都会连同其关联的操作符族和所有者一起列出。 + 列出操作符类(参见 )。如果指定了 access-method-pattern,则只列出与名称匹配该模式的访问方法关联的操作符类。如果指定了 input-type-pattern,则只列出与名称匹配该模式的输入类型关联的操作符类。如果在命令名后追加 +,则每个操作符类都会连同其关联的操作符族和所有者一起列出。 - \dAf[x+] + \dAf[+] [access-method-pattern [input-type-pattern]] - 列出操作符族(参见 )。如果指定了 access-method-pattern,则只列出与名称匹配该模式的访问方法关联的操作符族。如果指定了 input-type-pattern,则只列出与名称匹配该模式的输入类型关联的操作符族。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则每个操作符族都会连同其所有者一起列出。 + 列出操作符族(参见 )。如果指定了 access-method-pattern,则只列出与名称匹配该模式的访问方法关联的操作符族。如果指定了 input-type-pattern,则只列出与名称匹配该模式的输入类型关联的操作符族。如果在命令名后追加 +,则每个操作符族都会连同其所有者一起列出。 - \dAo[x+] + \dAo[+] [access-method-pattern [operator-family-pattern]] @@ -981,69 +903,61 @@ SELECT $1 \parse stmt1 - 列出与操作符族关联的操作符(参见 )。如果指定了 access-method-pattern,则只列出与名称匹配该模式的访问方法所关联的操作符族成员。如果指定了 operator-family-pattern,则只列出名称与该模式匹配的操作符族成员。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则每个操作符都会连同其排序操作符族(如果它是排序操作符)以及其底层函数是否防漏一起列出。 + 列出与操作符族关联的操作符(参见 )。如果指定了 access-method-pattern,则只列出与名称匹配该模式的访问方法所关联的操作符族成员。如果指定了 operator-family-pattern,则只列出名称与该模式匹配的操作符族成员。如果在命令名后追加 +,则每个操作符都会连同其排序操作符族(如果它是排序操作符)以及其底层函数是否防漏一起列出。 - \dAp[x+] + \dAp[+] [access-method-pattern [operator-family-pattern]] - 列出与操作符族关联的支持函数(参见 )。如果指定了 access-method-pattern,则只列出与名称匹配该模式的访问方法所关联的操作符族函数。如果指定了 operator-family-pattern,则只列出名称与该模式匹配的操作符族函数。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,函数会以详细形式显示,并带有其实际参数列表。 + 列出与操作符族关联的支持函数(参见 )。如果指定了 access-method-pattern,则只列出与名称匹配该模式的访问方法所关联的操作符族函数。如果指定了 operator-family-pattern,则只列出名称与该模式匹配的操作符族函数。如果在命令名后追加 +,函数会以详细形式显示,并带有其实际参数列表。 - \db[x+] [ pattern ] + \db[+] [ pattern ] 列出表空间。如果指定了 pattern,则只显示名称与模式匹配的表空间。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则每个表空间都会连同其关联选项、磁盘大小、权限和描述一起列出。 + class="parameter">pattern,则只显示名称与模式匹配的表空间。如果在命令名后追加 +,则每个表空间都会连同其关联选项、磁盘大小、权限和描述一起列出。 - \dc[Sx+] [ pattern ] + \dc[S+] [ pattern ] - 列出字符集编码之间的转换。如果指定了 pattern,则只列出名称与模式匹配的转换。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则每个对象都会连同其相关描述一起列出。 + 列出字符集编码之间的转换。如果指定了 pattern,则只列出名称与模式匹配的转换。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。如果在命令名后追加 +,则每个对象都会连同其相关描述一起列出。 - - \dconfig[x+] [ pattern ] - - - 列出服务器配置参数及其值。如果指定了 pattern,则只列出名称与模式匹配的参数。不带 pattern 时,只列出被设置为非默认值的参数。(使用 \dconfig * 可查看所有参数。)如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则每个参数都会连同其数据类型、该参数可设置的上下文以及访问权限(如果已授予非默认访问权限)一起列出。 - - - - \dC[x+] [ pattern ] + \dC[+] [ pattern ] - 列出类型转换。如果指定了 pattern,则只列出其源类型或目标类型与模式匹配的类型转换。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则会显示每个类型转换的附加信息,包括其底层函数是否防漏,以及该类型转换的描述。 + 列出类型转换。如果指定了 pattern,则只列出其源类型或目标类型与模式匹配的类型转换。如果在命令名后追加 +,则会显示每个类型转换的附加信息,包括其底层函数是否防漏,以及该类型转换的描述。 - \dd[Sx] [ pattern ] + \dd[S] [ pattern ] 显示constraintoperator class、 @@ -1052,8 +966,7 @@ SELECT $1 \parse stmt1 \dd 显示与 - pattern 匹配的对象描述;如果没有给出参数,则显示相应类型的可见对象的描述。但无论哪种情况,只列出那些已有描述的对象。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。如果在命令名后追加 x,结果会以扩展模式显示。 - + pattern 匹配的对象描述;如果没有给出参数,则显示相应类型的可见对象的描述。但无论哪种情况,只列出那些已有描述的对象。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。 可以使用 COMMENT SQL 命令创建对象的描述。 @@ -1063,22 +976,21 @@ SELECT $1 \parse stmt1 - \dD[Sx+] [ pattern ] + \dD[S+] [ pattern ] 列出域。如果指定了 pattern,则只显示名称与模式匹配的域。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则每个对象都会连同其相关权限和描述一起列出。 + class="parameter">pattern
,则只显示名称与模式匹配的域。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。如果在命令名后追加 +,则每个对象都会连同其相关权限和描述一起列出。 - \ddp[x] [ pattern ] + \ddp[ pattern ] - 列出默认访问权限设置。对于每个默认权限设置已偏离内置默认值的角色(以及适用时的模式),都会显示一条记录。如果指定了 pattern,则只列出角色名或模式名与模式匹配的记录。如果在命令名后追加 x,结果会以扩展模式显示。 - + 列出默认访问权限设置。对于每个默认权限设置已偏离内置默认值的角色(以及适用时的模式),都会显示一条记录。如果指定了 pattern,则只列出角色名或模式名与模式匹配的记录。 ALTER DEFAULT @@ -1089,51 +1001,51 @@ SELECT $1 \parse stmt1 - \dE[Sx+] [ pattern ] - \di[Sx+] [ pattern ] - \dm[Sx+] [ pattern ] - \ds[Sx+] [ pattern ] - \dt[Sx+] [ pattern ] - \dv[Sx+] [ pattern ] + \dE[S+] [ pattern ] + \di[S+] [ pattern ] + \dm[S+] [ pattern ] + \ds[S+] [ pattern ] + \dt[S+] [ pattern ] + \dv[S+] [ pattern ] 在这组命令中,字母 Eimstv - 分别表示外部表、索引、物化视图、序列、表和视图。你可以按任意顺序指定其中任意一个或多个字母,以获取这些类型对象的列表。例如,\dti 会列出表和索引。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则每个对象都会连同其持久性状态(永久、临时或不记录 WAL)、磁盘上的物理大小以及相关描述(如果有)一起列出。如果指定了 pattern,则只列出名称与模式匹配的对象。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。 + 分别表示外部表、索引、物化视图、序列、表和视图。你可以按任意顺序指定其中任意一个或多个字母,以获取这些类型对象的列表。例如,\dti 会列出表和索引。如果在命令名后追加 +,则每个对象都会连同其持久性状态(永久、临时或不记录 WAL)、磁盘上的物理大小以及相关描述(如果有)一起列出。如果指定了 pattern,则只列出名称与模式匹配的对象。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。 - \des[x+] [ pattern ] + \des[+] [ pattern ] 列出外部服务器(助记符:external - servers)。如果指定了 pattern,则只列出名称与模式匹配的服务器。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则会显示每个服务器的完整描述,包括服务器的访问权限、类型、版本、选项和描述。 + servers)。如果指定了 pattern,则只列出名称与模式匹配的服务器。如果在命令名后追加 +,则会显示每个服务器的完整描述,包括服务器的访问权限、类型、版本、选项和描述。 - \det[x+] [ pattern ] + \det[+] [ pattern ] - 列出外部表(助记符:external tables)。如果指定了 pattern,则只列出表名或模式名与模式匹配的条目。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则还会显示通用选项以及外部表描述。 + 列出外部表(助记符:external tables)。如果指定了 pattern,则只列出表名或模式名与模式匹配的条目。如果在命令名后追加 +,则还会显示通用选项以及外部表描述。 - \deu[x+] [ pattern ] + \deu[+] [ pattern ] 列出用户映射(助记符:external - users)。如果指定了 pattern,则只列出用户名与模式匹配的映射。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则会显示每个映射的附加信息。 + users)。如果指定了 pattern,则只列出用户名与模式匹配的映射。如果在命令名后追加 +,则会显示每个映射的附加信息。 @@ -1146,136 +1058,135 @@ SELECT $1 \parse stmt1 - \dew[x+] [ pattern ] + \dew[+] [ pattern ] 列出外部数据包装器(助记符:external - wrappers)。如果指定了 pattern,则只列出名称与模式匹配的外部数据包装器。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则还会显示外部数据包装器的访问权限、选项和描述。 + wrappers)。如果指定了 pattern,则只列出名称与模式匹配的外部数据包装器。如果在命令名后追加 +,则还会显示外部数据包装器的访问权限、选项和描述。 - \df[anptwSx+] [ pattern [ arg_pattern ... ] ] + \df[anptwS+] [ pattern [ arg_pattern ... ] ] 列出函数,以及它们的结果数据类型、参数数据类型和函数类型,函数类型分为 agg(聚合)、normalproceduretriggerwindow。要只显示特定类型的函数,请在命令后添加相应的字母 anptw。如果指定了 pattern,则只显示名称与模式匹配的函数。任何附加参数都是类型名模式,分别与函数第一、第二等参数的类型名匹配。(匹配到的函数可以比你指定的参数更多;若要防止这种情况,可将破折号 - 写成最后一个 arg_pattern。)默认情况下,只显示用户创建的对象;提供模式或 S - 修饰符可包括系统对象。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则会显示每个函数的附加信息,包括易变性、并行安全性、所有者、安全分类、是否防漏、访问权限、语言、内部名称(仅适用于 C 和 internal 函数)以及描述。特定函数的源代码可通过 \sf 查看。 + 修饰符可包括系统对象。如果在命令名后追加 +,则会显示每个函数的附加信息,包括易变性、并行安全性、所有者、安全分类、是否防漏、访问权限、语言、内部名称(仅适用于 C 和 internal 函数)以及描述。特定函数的源代码可通过 \sf 查看。 - \dF[x+] [ pattern ] + \dF[+] [ pattern ] - 列出文本搜索配置。如果指定了 pattern,则只显示名称与模式匹配的配置。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则会显示每个配置的完整描述,包括底层文本搜索解析器以及每种记号类型对应的词典列表。 + 列出文本搜索配置。如果指定了 pattern,则只显示名称与模式匹配的配置。如果在命令名后追加 +,则会显示每个配置的完整描述,包括底层文本搜索解析器以及每种记号类型对应的词典列表。 - \dFd[x+] [ pattern ] + \dFd[+] [ pattern ] - 列出文本搜索词典。如果指定了 pattern,则只显示名称与模式匹配的词典。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则会显示每个所选词典的附加信息,包括底层文本搜索模板和选项值。 + 列出文本搜索词典。如果指定了 pattern,则只显示名称与模式匹配的词典。如果在命令名后追加 +,则会显示每个所选词典的附加信息,包括底层文本搜索模板和选项值。 - \dFp[x+] [ pattern ] + \dFp[+] [ pattern ] - 列出文本搜索解析器。如果指定了 pattern,则只显示名称与模式匹配的解析器。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则会显示每个解析器的完整描述,包括底层函数和已识别的记号类型列表。 + 列出文本搜索解析器。如果指定了 pattern,则只显示名称与模式匹配的解析器。如果在命令名后追加 +,则会显示每个解析器的完整描述,包括底层函数和已识别的记号类型列表。 - \dFt[x+] [ pattern ] + \dFt[+] [ pattern ] - 列出文本搜索模板。如果指定了 pattern,则只显示名称与模式匹配的模板。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则会显示每个模板的附加信息,包括底层函数名。 + 列出文本搜索模板。如果指定了 pattern,则只显示名称与模式匹配的模板。如果在命令名后追加 +,则会显示每个模板的附加信息,包括底层函数名。 - \dg[Sx+] [ pattern ] + \dg[S+] [ pattern ] 列出数据库角色。(由于 usersgroups 的概念已经统一为 roles,此命令现在等同于 \du。)默认情况下,只显示用户创建的角色;提供 - S 修饰符可包括系统角色。如果指定了 pattern,则只列出名称与模式匹配的角色。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则会显示每个角色的附加信息;目前这会增加每个角色的注释。 + S 修饰符可包括系统角色。如果指定了 pattern,则只列出名称与模式匹配的角色。如果在命令名后追加 +,则会显示每个角色的附加信息;目前这会增加每个角色的注释。 - \dl[x+] + \dl - 这是 \lo_list 的别名,后者会显示大对象列表。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则会列出每个大对象的相关权限(如果有)。 + 这是 \lo_list 的别名,后者会显示大对象列表。 - \dL[Sx+] [ pattern ] + \dL[S+] [ pattern ] 列出过程语言。如果指定了 pattern,则只列出名称与模式匹配的语言。默认情况下,只显示用户创建的语言;提供 S 修饰符可包括系统对象。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则每种语言都会连同其调用处理器、验证器、访问权限以及它是否为系统对象一起列出。 + class="parameter">pattern
,则只列出名称与模式匹配的语言。默认情况下,只显示用户创建的语言;提供 S 修饰符可包括系统对象。如果在命令名后追加 +,则每种语言都会连同其调用处理器、验证器、访问权限以及它是否为系统对象一起列出。 - \dn[Sx+] [ pattern ] + \dn[S+] [ pattern ] 列出模式(命名空间)。如果指定了 pattern,则只列出名称与模式匹配的模式。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则每个对象都会连同其相关权限和描述(如果有)一起列出。 + class="parameter">pattern
,则只列出名称与模式匹配的模式。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。如果在命令名后追加 +,则每个对象都会连同其相关权限和描述(如果有)一起列出。 - \do[Sx+] [ pattern [ arg_pattern [ arg_pattern ] ] ] + \do[S+] [ pattern [ arg_pattern [ arg_pattern ] ] ] - 列出操作符及其操作数类型和结果类型。如果指定了 pattern,则只列出名称与模式匹配的操作符。如果指定了一个 arg_pattern,则只列出其右参数类型名称与该模式匹配的前缀操作符。如果指定了两个 arg_pattern,则只列出参数类型名称与这些模式匹配的二元操作符。(对于一元操作符未使用的参数,也可以写成 -。)默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则会显示每个操作符的附加信息,包括底层函数名以及它是否防漏。 + 列出操作符及其操作数类型和结果类型。如果指定了 pattern,则只列出名称与模式匹配的操作符。如果指定了一个 arg_pattern,则只列出其右参数类型名称与该模式匹配的前缀操作符。如果指定了两个 arg_pattern,则只列出参数类型名称与这些模式匹配的二元操作符。(对于一元操作符未使用的参数,也可以写成 -。)默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。如果在命令名后追加 +,则会显示每个操作符的附加信息,包括底层函数名以及它是否防漏。 - \dO[Sx+] [ pattern ] + \dO[S+] [ pattern ] - 列出排序规则。如果指定了 pattern,则只列出名称与模式匹配的排序规则。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则每个排序规则都会连同其相关描述(如果有)一起列出。请注意,只会显示与当前数据库编码兼容的排序规则,因此在同一安装中的不同数据库里结果可能不同。 + 列出排序规则。如果指定了 pattern,则只列出名称与模式匹配的排序规则。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。如果在命令名后追加 +,则每个排序规则都会连同其相关描述(如果有)一起列出。请注意,只会显示与当前数据库编码兼容的排序规则,因此在同一安装中的不同数据库里结果可能不同。 - \dp[Sx] [ pattern ] + \dp [ pattern ] - 列出表、视图和序列及其相关访问权限。如果指定了 pattern,则只列出名称与模式匹配的表、视图和序列。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。如果在命令名后追加 x,结果会以扩展模式显示。 - + 列出表、视图和序列及其相关访问权限。如果指定了 pattern,则只列出名称与模式匹配的表、视图和序列。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。 GRANT和 @@ -1288,7 +1199,7 @@ SELECT $1 \parse stmt1 - \dP[itnx+] [ pattern ] + \dP[itn+] [ pattern ] 列出分区关系。 @@ -1305,20 +1216,19 @@ SELECT $1 \parse stmt1 - 如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则还会显示每个关系分区大小的总和以及关系描述。如果 n+ 组合使用,则会显示两个大小:一个包括直接附加的叶分区的总大小,另一个显示包括间接附加子分区在内的所有分区总大小。 +如果在命令名后追加 +,则还会显示每个关系分区大小的总和以及关系描述。如果 n+ 组合使用,则会显示两个大小:一个包括直接附加的叶分区的总大小,另一个显示包括间接附加子分区在内的所有分区总大小。 - \drds[x] [ role-pattern [ database-pattern ] ] + \drds[ role-pattern [ database-pattern ] ] 列出已定义的配置设置。这些设置可以是特定于角色、特定于数据库,或者两者兼有。role-patterndatabase-pattern 分别用于选择要列出的特定角色和数据库。如果省略,或者指定了 - *,则会列出所有设置,包括那些未指定角色或数据库的设置。如果在命令名后追加 x,结果会以扩展模式显示。 - + *,则会列出所有设置,包括那些未指定角色或数据库的设置。 ALTER ROLE和 @@ -1329,75 +1239,60 @@ SELECT $1 \parse stmt1 - - \drg[Sx] [ pattern ] - - - 列出每个被授予角色成员身份的信息,包括被授予的选项(ADMIN、 - INHERIT 和/或 SET)以及授予者。关于角色成员身份,参见 GRANT - 命令。 - - - 默认情况下,只显示授予用户创建角色的成员身份;提供 - S 修饰符可包括系统角色。如果指定了 pattern,则只列出名称与模式匹配的角色。如果在命令名后追加 x,结果会以扩展模式显示。 - - - - \dRp[x+] [ pattern ] + \dRp[+] [ pattern ] - 列出逻辑复制发布。如果指定了 pattern,则只列出名称与模式匹配的发布。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则还会显示与每个发布关联的表和模式。 + 列出逻辑复制发布。如果指定了 pattern,则只列出名称与模式匹配的发布。如果在命令名后追加 +,则还会显示与每个发布关联的表和模式。 - \dRs[x+] [ pattern ] + \dRs[+] [ pattern ] - 列出逻辑复制订阅。如果指定了 pattern,则只列出名称与模式匹配的订阅。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则会显示订阅的其他属性。 + 列出逻辑复制订阅。如果指定了 pattern,则只列出名称与模式匹配的订阅。如果在命令名后追加 +,则会显示订阅的其他属性。 - \dT[Sx+] [ pattern ] + \dT[S+] [ pattern ] - 列出数据类型。如果指定了 pattern,则只列出名称与模式匹配的类型。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则每个类型都会连同其内部名称和大小一起列出;对于 enum 类型,还会显示其允许值以及相关权限。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。 + 列出数据类型。如果指定了 pattern,则只列出名称与模式匹配的类型。如果在命令名后追加 +,则每个类型都会连同其内部名称和大小一起列出;对于 enum 类型,还会显示其允许值以及相关权限。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。 - \du[Sx+] [ pattern ] + \du[S+] [ pattern ] 列出数据库角色。(由于 usersgroups 的概念已经统一为 roles,此命令现在等同于 \dg。)默认情况下,只显示用户创建的角色;提供 - S 修饰符可包括系统角色。如果指定了 pattern,则只列出名称与模式匹配的角色。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则会显示每个角色的附加信息;目前这会增加每个角色的注释。 + S 修饰符可包括系统角色。如果指定了 pattern,则只列出名称与模式匹配的角色。如果在命令名后追加 +,则会显示每个角色的附加信息;目前这会增加每个角色的注释。 - \dx[x+] [ pattern ] + \dx[+] [ pattern ] - 列出已安装的扩展。如果指定了 pattern,则只列出名称与模式匹配的扩展。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则会列出属于每个匹配扩展的全部对象。 + 列出已安装的扩展。如果指定了 pattern,则只列出名称与模式匹配的扩展。如果在命令名后追加 +,则会列出属于每个匹配扩展的全部对象。 - \dX[x] [ pattern ] + \dX[ pattern ] - 列出扩展统计信息。如果指定了 pattern,则只列出名称与模式匹配的扩展统计信息。如果在命令名后追加 x,结果会以扩展模式显示。 - + 列出扩展统计信息。如果指定了 pattern,则只列出名称与模式匹配的扩展统计信息。 每种扩展统计信息的状态显示在以其统计类型命名的列中(例如 Ndistinct)。 @@ -1408,10 +1303,10 @@ SELECT $1 \parse stmt1 - \dy[x+] [ pattern ] + \dy[+] [ pattern ] - 列出事件触发器。如果指定了 pattern,则只列出名称与模式匹配的事件触发器。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则每个对象都会连同其相关描述一起列出。 + 列出事件触发器。如果指定了 pattern,则只列出名称与模式匹配的事件触发器。如果在命令名后追加 +,则每个对象都会连同其相关描述一起列出。 @@ -1621,20 +1516,6 @@ Tue Oct 26 21:40:57 CEST 1999 - - \getenv psql_var env_var - - - - 获取环境变量env_var的值,并将其赋给psql变量psql_var。 - 如果env_varpsql进程的环境中未定义,psql_var不会被改变。示例: - -=> \getenv home HOME -=> \echo :home -/home/postgres - - - @@ -1658,11 +1539,7 @@ CREATE INDEX - 生成的查询按照返回的行的顺序执行,并在每行内从左到右执行,如果有多个列。NULL字段将被忽略。生成的查询文字 - 直接发送到服务器进行处理,因此它们不能是psql元命令,也不能包含psql - 变量引用。如果任何单个查询失败,剩余查询的执行将继续,除非设置了ON_ERROR_STOP。每个查询的执行 - 都受ECHO处理的影响。(通常在使用\gexec时,将ECHO设置为 - allqueries是明智的。)查询记录、单步模式、计时和其他查询执行功能也适用于每个生成的查询。 + 生成的查询按照返回行的顺序执行;如果有多列,则在每行内从左到右执行。NULL 字段会被忽略。生成的查询按原样发送到服务器进行处理,因此不能是psql元命令,也不能包含psql变量引用。如果某个查询失败,仍会继续执行其余查询,除非设置了ON_ERROR_STOP。每个查询的执行都受ECHO处理的影响。(通常,在使用\gexec时,适宜将ECHO设为allqueries。)查询日志、单步模式、计时及其他查询执行功能也适用于每个生成的查询。 如果当前查询缓冲区为空,则重新执行最近发送的查询。 @@ -1868,10 +1745,10 @@ SELECT - \l[x+] or \list[x+] [ pattern ] + \l[+] or \list[+] [ pattern ] - 列出服务器中的数据库,并显示其名称、所有者、字符集编码和访问权限。如果指定了 pattern,则只列出名称与模式匹配的数据库。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则还会显示数据库大小、默认表空间和描述。当前用户对其拥有 CONNECT 权限的数据库可以显示大小信息;如果当前用户是超级用户或具有 pg_read_all_stats 角色的权限,也可以显示大小信息。 + 列出服务器中的数据库,并显示其名称、所有者、字符集编码和访问权限。如果指定了 pattern,则只列出名称与模式匹配的数据库。如果在命令名后追加 +,则还会显示数据库大小、默认表空间和描述。当前用户对其拥有 CONNECT 权限的数据库可以显示大小信息;如果当前用户是超级用户或具有 pg_read_all_stats 角色的权限,也可以显示大小信息。 @@ -1902,7 +1779,7 @@ SELECT - 将文件存储到一个PostgreSQL大对象中。可选地,它将给定的注释与对象关联起来。例如: + 将文件存储到一个PostgreSQL大对象中。可选地,它将给定的注释与对象关联起来。例如: foo=> \lo_import '/home/peter/pictures/photo.xcf' 'a picture of me' lo_import 152801 @@ -1917,11 +1794,11 @@ lo_import 152801 - \lo_list[x+] + \lo_list 显示当前存储在数据库中的全部 PostgreSQL - 大对象列表,以及为它们提供的任何注释。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则会列出每个大对象的相关权限(如果有)。 + 大对象列表,以及为它们提供的任何注释。 @@ -1981,28 +1858,6 @@ lo_import 152801 - - \parse statement_name - - - 基于目标预备语句对象的名称,从当前查询缓冲区创建一个预备语句。空字符串表示未命名的预备语句。 - - - - 示例: - -SELECT $1 \parse stmt1 - - - - - 此命令会使用扩展查询协议,不同于psql通常使用的简单查询协议。该命令会发出一条 - - 消息,因此可用于在psql中测试扩展查询协议。此命令只影响下一条被执行的查询;之后的所有查询默认仍会使用简单查询协议。 - - - - \password [ username ] @@ -2048,7 +1903,7 @@ SELECT $1 \parse stmt1 - 可调整打印选项有: + 可调整打印选项有: border @@ -2148,7 +2003,7 @@ SELECT $1 \parse stmt1 允许使用唯一缩写。 - aligned格式是标准的、人类可读的、格式良好的文本输出;这是默认设置。 + aligned格式是标准的、适合人阅读且排版整齐的文本输出;这是默认格式。 unaligned格式将一行中的所有列写在一行上,由当前活动的字段分隔符分隔。这对于创建可能被其他程序读取的输出很有用,例如,制表符分隔或逗号分隔格式。然而,如果字段分隔符字符出现在列的值中,则不会被特殊处理;因此,CSV格式可能更适合这些目的。 @@ -2565,61 +2420,6 @@ testdb=> \setenv LESS -imx4F - - \startpipeline - \sendpipeline - \syncpipeline - \endpipeline - \flushrequest - \flush - \getresults [ number_results ] - - - - 这组命令实现 SQL 语句的管道化。一个管道必须以 \startpipeline 开始,并以 \endpipeline 结束。其间可以出现任意数量的 \syncpipeline 命令,它会发送一条同步消息,但不会结束当前管道,并会刷新发送缓冲区。在管道模式下,语句会被发送到服务器,而不等待前面语句的结果。更多细节见 。 - - - - 管道进行期间执行的所有查询都使用扩展查询协议。以分号结束的查询会被追加到管道中。元命令 \bind、 - \bind_named\close_prepared 和 - \parse 可以在进行中的管道里使用。管道进行期间,\sendpipeline 会将当前查询缓冲区追加到管道中。其他元命令,如 - \g\gx 或 - \gdesc,则不允许在管道模式中使用。 - - - - \flushrequest 会向管道追加一条 flush 命令,使得可以在不发送 sync 或结束管道的情况下通过 - \getresults 读取结果。\getresults 会自动将尚未发送的数据推送到服务器。\flush 可用于手动推送未发送的数据。 - - - - \getresults 接受一个可选的 - number_results 参数。如果提供,则只读取前 - number_results 个待处理结果。若省略该参数或其值为 0,则读取所有待处理结果。 - - - - 当管道模式处于活动状态时,可使用一个专用的提示符变量来报告管道状态。详见 。 - - - - COPY 在管道模式中不支持。 - - - - 示例: - -\startpipeline -SELECT * FROM pg_class; -SELECT 1 \bind \sendpipeline -\flushrequest -\getresults -\endpipeline - - - - - @@ -2718,12 +2518,10 @@ SELECT 1 \bind \sendpipeline - \watch [ i[nterval]=seconds ] [ c[ount]=times ] [ m[in_rows]=rows ] [ seconds ] + \watch [ seconds ] - 重复执行当前查询缓冲区(如同 \g 一样),直到被中断、查询失败、达到执行次数上限(如果给定)或查询返回的行数低于最小要求。两次执行之间等待指定的秒数(默认 2 秒)。默认等待时间可通过变量 - 修改。为保持向后兼容, - seconds 可以带或不带 interval= 前缀。每次查询结果都会带有一个头部,其中包含 \pset title + 重复执行当前查询缓冲区(如同 \g 一样),直到被中断或查询失败。两次执行之间等待指定的秒数(默认 2 秒)。每次查询结果都会带有一个头部,其中包含 \pset title 字符串(如果有)、查询开始时的时间以及延迟间隔。 @@ -2744,11 +2542,10 @@ SELECT 1 \bind \sendpipeline - \z[Sx] [ pattern ] + \z [ pattern ] - 列出表、视图和序列及其相关访问权限。如果指定了 pattern,则只列出名称与模式匹配的表、视图和序列。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。如果在命令名后追加 x,结果会以扩展模式显示。 - + 列出表、视图和序列及其相关访问权限。如果指定了 pattern,则只列出名称与模式匹配的表、视图和序列。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。 这是\dp的别名(显示权限)。 @@ -3126,34 +2923,8 @@ bar - - PIPELINE_COMMAND_COUNT - - - 正在运行的管道中排队的命令数 。 - - - - - PIPELINE_RESULT_COUNT - - - 正在进行的管道中,有多少条命令后面跟着 \flushrequest 或 - \syncpipeline,从而强制服务器发送结果。这些结果可以通过 - \getresults 取回。 - - - - - PIPELINE_SYNC_COUNT - - - 正在运行的管道中排队的同步消息数量 。 - - - PORT @@ -3203,48 +2974,9 @@ bar - - SERVICE - - - 服务名称(如果适用)。 - - - - - SHELL_ERROR - - - 如果最后一个 shell 命令失败,则为 true;如果成功,则为 false。这适用于通过 \!、 - \g\o\w - 和 \copy 元命令调用的 shell 命令,也适用于反引号(`)展开。请注意,对于 \o,该变量会在下一个 \o 命令关闭输出管道时更新。 - 另见 SHELL_EXIT_CODE。 - - - - - SHELL_EXIT_CODE - - - 最后一个 shell 命令返回的退出状态。0–127 表示程序退出码,128–255 表示因信号而终止,-1 表示未能启动程序或未能取得其退出状态。这适用于通过 \!、 - \g\o\w - 和 \copy 元命令调用的 shell 命令,也适用于反引号(`)展开。请注意,对于 \o,该变量会在下一个 \o 命令关闭输出管道时更新。 - 另见 SHELL_ERROR。 - - - - - SHOW_ALL_RESULTS - - - 当此变量被设为 off 时,组合查询(\;)只显示最后一个结果,而不是显示全部结果。默认值为 on。设为 off 的行为是为了兼容旧版本的 - psql。 - - - SHOW_CONTEXT @@ -3312,14 +3044,6 @@ bar - - WATCH_INTERVAL - - - 此变量设置\watch在两次执行查询之间等待的默认间隔,单位为秒。默认值为 2 秒。若在命令中指定了间隔,则会覆盖此变量。 - - - @@ -3329,7 +3053,7 @@ bar <acronym>SQL</acronym> 中插入变量 - psql变量的一个关键特性是可以把它们替换(插入)到常规SQL语句中,也可以把它们作为元命令的参数。此外,psql还提供了功能来确保被用作 SQL 文字和标识符的变量值会被正确地引用。插入一个值而不需要加引用的语法是在变量名前面加上一个冒号(:)。例如, + psql变量的一个关键特性是可以把它们替换(插入)到常规SQL语句中,也可以把它们作为元命令的参数。此外,psql还提供了功能来确保被用作 SQL 字面量和标识符的变量值会被正确地加引号。插入一个值而不加引号的语法是在变量名前面加上一个冒号(:)。例如, testdb=> \set foo 'my_table' testdb=> SELECT * FROM :foo; @@ -3416,10 +3140,6 @@ testdb=> INSERT INTO my_table VALUES (:'content'); - - %s - 服务名称。 - %/ @@ -3450,16 +3170,6 @@ testdb=> INSERT INTO my_table VALUES (:'content'); - - %P - - - 管道状态:不在管道中时为 off, - 在进行中的管道中时为 on, - 在已中止的管道中时为 abort。 - - - %R @@ -3989,28 +3699,6 @@ testdb=> \df int*pl * bigint - - 这里,+ 选项用于显示其中一个函数的附加信息,而 x 用于以扩展模式显示结果: - -testdb=> \df+x int*pl integer bigint -List of functions --[ RECORD 1 ]-------+----------------------------- -Schema | pg_catalog -Name | int48pl -Result data type | bigint -Argument data types | integer, bigint -Type | func -Volatility | immutable -Parallel | safe -Owner | postgres -Security | invoker -Leakproof? | no -Access privileges | -Language | internal -Internal name | int48pl -Description | implementation of + operator - - 在适合的情况下,可以使用 \crosstabview 命令将查询结果显示为交叉表: diff --git a/zh/14/ref/reassign_owned.sgml b/zh/14/ref/reassign_owned.sgml index 824834b8..ba7d9f7b 100644 --- a/zh/14/ref/reassign_owned.sgml +++ b/zh/14/ref/reassign_owned.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation REASSIGN OWNED 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/refresh_materialized_view.sgml b/zh/14/ref/refresh_materialized_view.sgml index 2ccb7ac0..7d0fed7a 100644 --- a/zh/14/ref/refresh_materialized_view.sgml +++ b/zh/14/ref/refresh_materialized_view.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation REFRESH MATERIALIZED VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/reindex.sgml b/zh/14/ref/reindex.sgml index d2708ed6..bc834be9 100644 --- a/zh/14/ref/reindex.sgml +++ b/zh/14/ref/reindex.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation REINDEX 7 - SQL - Language Statements + SQL - 语言语句 @@ -23,8 +23,7 @@ PostgreSQL documentation -REINDEX [ ( option [, ...] ) ] { INDEX | TABLE | SCHEMA } [ CONCURRENTLY ] name -REINDEX [ ( option [, ...] ) ] { DATABASE | SYSTEM } [ CONCURRENTLY ] [ name ] +REINDEX [ ( option [, ...] ) ] { INDEX | TABLE | SCHEMA | DATABASE | SYSTEM } [ CONCURRENTLY ] name 其中 option 可以是以下之一: @@ -125,8 +124,8 @@ REINDEX [ ( option [, ...] ) ] { DA - 重新创建当前数据库中除系统目录外的所有索引。 - 系统目录上的索引不会被处理。这种形式的REINDEX不能 + 重新创建当前数据库中的所有索引。 + 共享系统目录上的索引也会被处理。这种形式的REINDEX不能 在事务块内执行。 @@ -151,8 +150,7 @@ REINDEX [ ( option [, ...] ) ] { DA 要重新索引的特定索引、表或数据库的名称。索引名和表名可以带模式限 定。目前,REINDEX DATABASE和 - REINDEX SYSTEM只能对当前数据库重新索引。它们的参 - 数是可选的,但如果给出,就必须与当前数据库名匹配。 + REINDEX SYSTEM只能对当前数据库重新索引,所以其参数必须与当前数据库名匹配。 @@ -188,10 +186,7 @@ REINDEX [ ( option [, ...] ) ] { DA VERBOSE - - - 在每个索引被重建时,以 INFO 级别打印进度报告。 - + 在每个索引被重建时打印进度报告。 @@ -264,10 +259,7 @@ REINDEX [ ( option [, ...] ) ] { DA 从头重建的。不过,两者在锁方面的考量相当不同。 REINDEX会阻止该索引所属表上的写入,但不阻止读取。它 还会对正在处理的特定索引获取ACCESS EXCLUSIVE锁, - 从而阻塞试图使用该索引的读取。尤其是,无论查询内容如何,查询规划器都 - 会尝试对该表的每个索引获取ACCESS SHARE锁,因此 - REINDEX实际上会阻塞几乎所有查询,只有那些计划已缓 - 存且不使用这个索引的某些预备查询除外。相比之下, + 从而阻塞试图使用该索引的读取。相比之下, DROP INDEX会短暂地对父表获取 ACCESS EXCLUSIVE锁,同时阻塞写入和读取。随后的 CREATE INDEX会阻止写入但不阻止读取;由于索引不存 @@ -275,12 +267,6 @@ REINDEX [ ( option [, ...] ) ] { DA 的顺序扫描。 - - 在REINDEX运行期间,会临时改为pg_catalog, - pg_temp。 - - 对单个索引或表重新索引,要求用户是该索引或表的拥有者。对模式或数据库 重新索引,则要求用户是该模式或数据库的拥有者。特别要注意,这意味着 @@ -301,7 +287,7 @@ REINDEX [ ( option [, ...] ) ] { DA 当对分区索引或分区表执行带TABLESPACE子句的 REINDEX时,只有叶分区的表空间引用会被更新。由于 - 分区索引本身不会更新,建议另外对相应的分区表单独执行 + 分区索引本身不会更新,建议另外对这些分区索引单独执行 ALTER TABLE ONLY,以便后续附加的任何新分区都继承 新表空间。如果命令失败,可能不会把所有索引都移动到新表空间。重新运行 该命令将重建所有叶分区,并把先前未处理的索引移动到新表空间。 @@ -319,8 +305,8 @@ REINDEX [ ( option [, ...] ) ] { DA 并发重建索引 - index - rebuilding concurrently + 索引 + 并发重建 diff --git a/zh/14/ref/reindexdb.sgml b/zh/14/ref/reindexdb.sgml index 20dc32bf..c9d7bfeb 100644 --- a/zh/14/ref/reindexdb.sgml +++ b/zh/14/ref/reindexdb.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation reindexdb 1 - Application + 应用程序 @@ -55,22 +55,30 @@ PostgreSQL documentation - - - - - - - - + dbname + - - - dbname - - - - + + reindexdb + connection-option + option + + + + + + + + + reindexdb + connection-option + option + + + + + + dbname @@ -162,9 +170,7 @@ PostgreSQL documentation reindexdb将打开njobs个到数据库的连接,因此请确保设置足够高,能容纳所有连接。 - - 注意,该选项与选项不兼容。 - + 注意,该选项与 选项不兼容。 @@ -373,6 +379,12 @@ PostgreSQL documentation + + 注解 + + reindexdb 可能需要多次连接到 PostgreSQL 服务器,每次都要求输入密码。在这种情况下,使用 ~/.pgpass 文件会很方便。更多信息见 + + 示例 diff --git a/zh/14/ref/release_savepoint.sgml b/zh/14/ref/release_savepoint.sgml index 59f96e68..30956601 100644 --- a/zh/14/ref/release_savepoint.sgml +++ b/zh/14/ref/release_savepoint.sgml @@ -10,18 +10,18 @@ PostgreSQL documentation 保存点 - releasing + 释放 RELEASE SAVEPOINT 7 - SQL - Language Statements + SQL - 语言语句 RELEASE SAVEPOINT - 释放一个先前定义的保存点 + 销毁一个先前定义的保存点 @@ -33,11 +33,11 @@ RELEASE [ SAVEPOINT ] savepoint_name 描述 - - RELEASE SAVEPOINT释放指定名称的保存点,以及在该保存点之后创建且仍处于活动状态的所有保存点,并释放它们占用的资源。 - 自该保存点创建以来所做、且之前尚未被回滚的所有更改,都会并入在创建该保存点时处于活动状态的事务或保存点中。 - 在RELEASE SAVEPOINT之后所做的更改,也将成为该活动事务或保存点的一部分。 - + RELEASE SAVEPOINT 销毁先前在当前事务中定义的保存点。 + + 销毁保存点后,就不能再将它用作回滚点,但除此之外没有其他用户可见的行为。它不会撤销保存点建立之后执行的命令的效果。(要这样做,请参见 。)在不再需要保存点时将其销毁,可以让系统在事务结束之前回收一些资源。 + + RELEASE SAVEPOINT 还会销毁在指定保存点建立之后建立的所有保存点。 @@ -48,7 +48,7 @@ RELEASE [ SAVEPOINT ] savepoint_name savepoint_name - 要释放的保存点名称。 + 要销毁的保存点名称。 @@ -62,9 +62,7 @@ RELEASE [ SAVEPOINT ] savepoint_name 指定一个此前未定义的保存点名称是一种错误。 - - 当事务处于已中止状态时,不能释放保存点;要这样做,请使用。 - + 当事务处于已中止状态时,不能释放保存点。 如果有多个保存点使用相同名称,则只会释放最近定义且尚未释放的那个。 @@ -77,7 +75,7 @@ RELEASE [ SAVEPOINT ] savepoint_name 示例 - 建立并随后释放一个保存点: + 要建立保存点,并在稍后销毁它: BEGIN; INSERT INTO table1 VALUES (3); @@ -86,32 +84,7 @@ BEGIN; RELEASE SAVEPOINT my_savepoint; COMMIT; - 上面的事务将插入 3 和 4。 - - - - 一个包含多个嵌套子事务的更复杂示例: - -BEGIN; - INSERT INTO table1 VALUES (1); - SAVEPOINT sp1; - INSERT INTO table1 VALUES (2); - SAVEPOINT sp2; - INSERT INTO table1 VALUES (3); - RELEASE SAVEPOINT sp2; - INSERT INTO table1 VALUES (4))); -- generates an error - - 在这个例子中,应用程序请求释放保存点sp2,值 3 是在其中插入的。 - 这样会把该插入操作的事务上下文改为sp1。 - 当试图插入值 4 的语句产生错误时,2 和 4 的插入都会丢失,因为它们位于同一个随后被回滚的保存点中, - 而值 3 现在也位于同一事务上下文中,因此同样会丢失。 - 由于此后所有其他命令都会被忽略,应用程序现在只能在以下两个命令中选择一个: - -ROLLBACK; -ROLLBACK TO SAVEPOINT sp1; - - 选择ROLLBACK将中止所有内容,包括值 1; - 而ROLLBACK TO SAVEPOINT sp1会保留值 1,并允许事务继续。 + 上述事务将同时插入 3 和 4。 diff --git a/zh/14/ref/reset.sgml b/zh/14/ref/reset.sgml index e8aeae8c..5e249ff9 100644 --- a/zh/14/ref/reset.sgml +++ b/zh/14/ref/reset.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation RESET 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/revoke.sgml b/zh/14/ref/revoke.sgml index 8d7945a5..60945379 100644 --- a/zh/14/ref/revoke.sgml +++ b/zh/14/ref/revoke.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation REVOKE 7 - SQL - Language Statements + SQL - 语言语句 @@ -23,7 +23,7 @@ PostgreSQL documentation REVOKE [ GRANT OPTION FOR ] - { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER | MAINTAIN } + { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER } [, ...] | ALL [ PRIVILEGES ] } ON { [ TABLE ] table_name [, ...] | ALL TABLES IN SCHEMA schema_name [, ...] } @@ -98,12 +98,6 @@ REVOKE [ GRANT OPTION FOR ] [ GRANTED BY role_specification ] [ CASCADE | RESTRICT ] -REVOKE [ GRANT OPTION FOR ] - { { SET | ALTER SYSTEM } [, ...] | ALL [ PRIVILEGES ] } - ON PARAMETER configuration_parameter [, ...] - FROM role_specification [, ...] - [ GRANTED BY role_specification ] - [ CASCADE | RESTRICT ] REVOKE [ GRANT OPTION FOR ] { { CREATE | USAGE } [, ...] | ALL [ PRIVILEGES ] } @@ -126,12 +120,12 @@ REVOKE [ GRANT OPTION FOR ] [ GRANTED BY role_specification ] [ CASCADE | RESTRICT ] -REVOKE [ { ADMIN | INHERIT | SET } OPTION FOR ] +REVOKE [ ADMIN OPTION FOR ] role_name [, ...] FROM role_specification [, ...] [ GRANTED BY role_specification ] [ CASCADE | RESTRICT ] -where role_specification can be: +其中role_specification可以是: [ GROUP ] role_name | PUBLIC @@ -186,21 +180,9 @@ REVOKE [ { ADMIN | INHERIT | SET } OPTION FOR ] 权限不会产生任何效果。 - - 在撤销角色成员资格时,GRANT OPTION 改称为 - ADMIN OPTION,但行为类似。请注意,在 - PostgreSQL 16 之前的版本中,系统不会跟踪 - 角色成员资格授权所产生的依赖权限,因此 CASCADE 对 - 角色成员资格没有效果。现在情况已不再如此。另请注意,这种形式的命令不允许在 - role_specification - 中使用噪声词 GROUP。 - + 在撤销角色成员资格时,GRANT OPTION 改称为 ADMIN OPTION,但行为类似。这种形式的命令还允许使用 GRANTED BY 选项,但目前会忽略该选项(只检查所指定角色是否存在)。另请注意,这种形式的命令不允许把噪声词 GROUP 写在 role_specification 中。 + - - 正如可以从现有角色成员资格授权中移除 ADMIN OPTION 一样, - 也可以撤销 INHERIT OPTIONSET OPTION。 - 这等价于将相应选项的值设为 FALSE。 - @@ -228,9 +210,7 @@ REVOKE [ { ADMIN | INHERIT | SET } OPTION FOR ] 如果超级用户选择执行 GRANTREVOKE - 命令,则该命令会像由受影响对象的拥有者发出那样执行。(由于角色没有 - 拥有者,在 GRANT 角色成员资格时,该命令会像由引导 - 超级用户发出那样执行。)由于所有权限最终都来自对象拥有者 + 命令,则该命令会像由受影响对象的拥有者发出那样执行。由于所有权限最终都来自对象拥有者 (可能经由授予选项链间接传递),超级用户可以撤销所有权限,但如上所述, 这可能需要使用 CASCADE diff --git a/zh/14/ref/rollback.sgml b/zh/14/ref/rollback.sgml index d1c8fdd2..17b9c070 100644 --- a/zh/14/ref/rollback.sgml +++ b/zh/14/ref/rollback.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ROLLBACK 7 - SQL - Language Statements + SQL - 语言语句 @@ -37,7 +37,7 @@ ROLLBACK [ WORK | TRANSACTION ] [ AND [ NO ] CHAIN ] 参数 - chained transactions + 链式事务 @@ -55,7 +55,7 @@ ROLLBACK [ WORK | TRANSACTION ] [ AND [ NO ] CHAIN ] AND CHAIN - 如果指定了AND CHAIN,则会立即启动一个新的(未中止的)事务, + 如果指定了AND CHAIN,则会立即启动一个新事务, 其事务特征与刚刚结束的事务相同(参见)。 否则,不会启动任何新事务。 diff --git a/zh/14/ref/rollback_prepared.sgml b/zh/14/ref/rollback_prepared.sgml index 7ffe1af8..7438d9cc 100644 --- a/zh/14/ref/rollback_prepared.sgml +++ b/zh/14/ref/rollback_prepared.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ROLLBACK PREPARED 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/rollback_to.sgml b/zh/14/ref/rollback_to.sgml index 843a612e..e3f305b7 100644 --- a/zh/14/ref/rollback_to.sgml +++ b/zh/14/ref/rollback_to.sgml @@ -10,13 +10,13 @@ PostgreSQL documentation 保存点 - rolling back + 回滚 ROLLBACK TO SAVEPOINT 7 - SQL - Language Statements + SQL - 语言语句 @@ -34,8 +34,7 @@ ROLLBACK [ WORK | TRANSACTION ] TO [ SAVEPOINT ] savepoint_name描述 - 回滚该保存点建立后执行的所有命令,然后在同一事务层级启动一个新的 - 子事务。该保存点仍然有效,如有需要,之后还可以再次回滚到它。 + 回滚该保存点建立后执行的所有命令。该保存点仍然有效,如有需要,之后还可以再次回滚到它。 @@ -73,8 +72,8 @@ ROLLBACK [ WORK | TRANSACTION ] TO [ SAVEPOINT ] savepoint_name 就保存点而言,游标带有一些非事务性的行为。凡是在某个保存点内打开的游标, 在回滚该保存点时都会被关闭。如果先前打开的游标在某个随后又被回滚的保存点内受到了 - FETCHMOVE命令的影响,那么该游标会保留在这些命令使其指向的位置上 - (也就是说,由FETCHMOVE引起的游标移动不会被回滚)。 + FETCHMOVE命令的影响,那么该游标会保留在FETCH使其指向的位置上 + (也就是说,由FETCH引起的游标移动不会被回滚)。 关闭游标同样不会因回滚而撤销。不过,如果游标查询导致了其他副作用(例如该查询调用的 易变函数带来的副作用),且这些副作用发生在后来被回滚的保存点期间,那么它们 被回滚。如果某个游标的执行导致事务中止,该游标会进入不可执行状态, diff --git a/zh/14/ref/savepoint.sgml b/zh/14/ref/savepoint.sgml index fdca4151..5f9bea25 100644 --- a/zh/14/ref/savepoint.sgml +++ b/zh/14/ref/savepoint.sgml @@ -10,13 +10,13 @@ PostgreSQL documentation 保存点 - defining + 定义 SAVEPOINT 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/security_label.sgml b/zh/14/ref/security_label.sgml index fc969a4a..9c2b13d0 100644 --- a/zh/14/ref/security_label.sgml +++ b/zh/14/ref/security_label.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SECURITY LABEL 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/select.sgml b/zh/14/ref/select.sgml index 1b47aa6d..19abe844 100644 --- a/zh/14/ref/select.sgml +++ b/zh/14/ref/select.sgml @@ -21,7 +21,7 @@ PostgreSQL documentation SELECT 7 - SQL - Language Statements + SQL - 语言语句 @@ -1485,7 +1485,7 @@ SELECT * FROM (SELECT * FROM mytable FOR UPDATE) ss ORDER BY column1; REPEATABLE READSERIALIZABLE事务隔离级别下, - 这将导致序列化失败(带有SQLSTATE'40001'), + 这将导致串行化失败(SQLSTATE'40001'), 因此在这些隔离级别下不可能接收到无序的行。 diff --git a/zh/14/ref/select_into.sgml b/zh/14/ref/select_into.sgml index a05e57e8..12a48774 100644 --- a/zh/14/ref/select_into.sgml +++ b/zh/14/ref/select_into.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SELECT INTO 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/set.sgml b/zh/14/ref/set.sgml index ab67075e..9702d560 100644 --- a/zh/14/ref/set.sgml +++ b/zh/14/ref/set.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SET 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/set_constraints.sgml b/zh/14/ref/set_constraints.sgml index 53d0c7a0..e5588db7 100644 --- a/zh/14/ref/set_constraints.sgml +++ b/zh/14/ref/set_constraints.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SET CONSTRAINTS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/set_role.sgml b/zh/14/ref/set_role.sgml index ed65dec8..f9139dbc 100644 --- a/zh/14/ref/set_role.sgml +++ b/zh/14/ref/set_role.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SET ROLE 7 - SQL - Language Statements + SQL - 语言语句 @@ -30,23 +30,9 @@ RESET ROLE 描述 - - 这个命令将当前 SQL 会话的当前用户标识符设置为 - role_name。 - 角色名既可以写成标识符,也可以写成字符串字面量。 - 执行SET ROLE之后,对 SQL 命令的权限检查会按照 - 最初登录的就是该角色那样进行。注意, - SET ROLE和 - SET SESSION AUTHORIZATION是例外:对这两个命令的权限检查, - 分别仍然使用当前会话用户和初始会话用户(即已认证用户)。 - + 该命令把当前 SQL 会话的当前用户标识符设置为 role_name。角色名可以写成标识符或字符串字面量。在 SET ROLE 之后,SQL 命令的权限检查会视同指定角色是最初登录的角色。 - - 当前会话用户必须对指定的 - role_name拥有SET选项, - 这可以是直接拥有,也可以通过带有SET选项的成员关系链间接拥有。 - (如果会话用户是超级用户,则可以选择任意角色。) - + 当前会话用户必须是指定的 role_name 角色的成员。(如果会话用户是超级用户,则可以选择任意角色。) SESSIONLOCAL修饰符的作用与常规的 @@ -68,18 +54,9 @@ RESET ROLE 注解 - - 使用这个命令,既可以增加权限,也可以限制自己的权限。 - 如果会话用户角色获得的是WITH INHERIT TRUE的成员关系, - 它会自动拥有每个此类角色的全部权限。在这种情况下, - SET ROLE实际上会去掉除目标角色直接拥有或继承而来的权限之外的所有权限。 - 另一方面,如果会话用户角色获得的是WITH INHERIT FALSE的成员关系, - 默认就不能使用被授予角色的权限。但是,如果该角色是以 - WITH SET TRUE授予的,则会话用户可以使用 - SET ROLE放弃直接分配给自己的权限,转而获得该角色可用的权限。 - 如果该角色是以WITH INHERIT FALSE, SET FALSE授予的, - 那么无论是否使用SET ROLE,该角色的权限都无法行使。 - + 使用这个命令,既可以增加权限,也可以限制自己的权限。如果会话用户角色具有 INHERIT 属性,它会自动拥有每个可通过 SET ROLE 切换到的角色的全部权限;在这种情况下,SET ROLE 实际上会去掉直接分配给会话用户及其所属其他角色的全部权限,只保留指定角色可用的权限。另一方面,如果会话用户角色具有 NOINHERIT 属性,SET ROLE 会放弃直接分配给会话用户的权限,转而获得指定角色可用的权限。 + + 特别是,当超级用户选择通过 SET ROLE 切换到非超级用户角色时,会失去其超级用户权限。 SET ROLE的效果与 diff --git a/zh/14/ref/set_session_auth.sgml b/zh/14/ref/set_session_auth.sgml index e520dd49..9ec07ce6 100644 --- a/zh/14/ref/set_session_auth.sgml +++ b/zh/14/ref/set_session_auth.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SET SESSION AUTHORIZATION 7 - SQL - Language Statements + SQL - 语言语句 @@ -46,7 +46,7 @@ RESET SESSION AUTHORIZATION - 只有当初始会话用户(即已认证用户)具有超级用户权限时, + 只有当初始会话用户(即已认证用户)最初具有超级用户权限时, 才能更改会话用户标识符。否则,只有当该命令指定的是已认证用户名时, 才会被接受。 diff --git a/zh/14/ref/set_transaction.sgml b/zh/14/ref/set_transaction.sgml index ca7f3e50..5355df65 100644 --- a/zh/14/ref/set_transaction.sgml +++ b/zh/14/ref/set_transaction.sgml @@ -26,7 +26,7 @@ PostgreSQL documentation SET TRANSACTION 7 - SQL - Language Statements + SQL - 语言语句 @@ -66,7 +66,7 @@ SET SESSION CHARACTERISTICS AS TRANSACTION transa - 一个事务的隔离级别决定当其他事务并行运行时该事务能看见什么数据: + 一个事务的隔离级别决定当其他事务并发运行时该事务能看见什么数据: @@ -112,7 +112,7 @@ SET SESSION CHARACTERISTICS AS TRANSACTION transa 在事务执行第一条查询或数据修改语句(SELECTINSERTDELETE, - UPDATEMERGE, + UPDATEFETCH,或 COPY)之后,事务隔离级别就不能再更改。有关事务隔离和并发控制的更多信息,请参见 。 @@ -120,9 +120,9 @@ SET SESSION CHARACTERISTICS AS TRANSACTION transa 事务访问模式决定事务是读/写还是只读。读/写是默认值。当事务为只读时, - 下列 SQL 命令会被禁止:INSERTUPDATE、 - DELETEMERGE 以及 - COPY FROM,前提是它们要写入的表不是临时表; + 下列 SQL 命令会被禁止:INSERTUPDATE、 + DELETE 以及 + COPY FROM,前提是它们要写入的表不是临时表; 所有 CREATEALTERDROP 命令;COMMENTGRANTREVOKE、 @@ -137,7 +137,7 @@ SET SESSION CHARACTERISTICS AS TRANSACTION transa 事务属性才会生效。当为一个事务同时选择这三个属性时,该事务在 首次获取其快照时可能会阻塞;在此之后,它便可以运行,而无需承担普通 SERIALIZABLE事务的常规开销,也不会有促成 - 序列化失败或因序列化失败而被取消的风险。这种模式非常适合长时间运行的 + 串行化失败或因串行化失败而被取消的风险。这种模式非常适合长时间运行的 报表或备份。 @@ -153,7 +153,7 @@ SET SESSION CHARACTERISTICS AS TRANSACTION transa SET TRANSACTION SNAPSHOT只能在事务开始时执行,也就是在 事务的第一条查询或数据修改语句(SELECTINSERTDELETE、 - UPDATEMERGE、 + UPDATEFETCHCOPY)之前。 此外,事务还必须已经设置为 SERIALIZABLEREPEATABLE READ 隔离级别(否则,快照会被立即丢弃, diff --git a/zh/14/ref/show.sgml b/zh/14/ref/show.sgml index 3b4be6bd..b27c2145 100644 --- a/zh/14/ref/show.sgml +++ b/zh/14/ref/show.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SHOW 7 - SQL - Language Statements + SQL - 语言语句 @@ -73,6 +73,20 @@ SHOW ALL + + LC_COLLATE + + 显示数据库用于排序规则(文本排序)的区域设置。目前,该参数可以显示但不能设置,因为该设置在数据库创建时就已确定。 + + + + + LC_CTYPE + + 显示数据库用于字符分类的区域设置。目前,该参数可以显示但不能设置,因为该设置在数据库创建时就已确定。 + + + IS_SUPERUSER diff --git a/zh/14/ref/start_transaction.sgml b/zh/14/ref/start_transaction.sgml index 57a74b2f..5026fa70 100644 --- a/zh/14/ref/start_transaction.sgml +++ b/zh/14/ref/start_transaction.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation START TRANSACTION 7 - SQL - Language Statements + SQL - 语言语句 @@ -64,15 +64,16 @@ START TRANSACTION [ transaction_mode - DEFERRABLE 这一 - transaction_mode 是 - PostgreSQL语言扩展。 + DEFERRABLE + transaction_mode + 是PostgreSQL的一种语言扩展。 SQL 标准要求在连续的transaction_modes之间有逗号, - 但出于历史原因PostgreSQL允许省略逗号。 + 但出于历史原因, + PostgreSQL允许省略逗号。 diff --git a/zh/14/ref/truncate.sgml b/zh/14/ref/truncate.sgml index aa2ce51c..ff1e0bc9 100644 --- a/zh/14/ref/truncate.sgml +++ b/zh/14/ref/truncate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation TRUNCATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/unlisten.sgml b/zh/14/ref/unlisten.sgml index 5e73e99e..6b52f1af 100644 --- a/zh/14/ref/unlisten.sgml +++ b/zh/14/ref/unlisten.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation UNLISTEN 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/ref/update.sgml b/zh/14/ref/update.sgml index a3c965df..4ace7c49 100644 --- a/zh/14/ref/update.sgml +++ b/zh/14/ref/update.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation UPDATE 7 - SQL - Language Statements + SQL - 语言语句 @@ -313,12 +313,12 @@ UPDATE count 在被移动的行上并发执行UPDATE或 - DELETE时,有可能收到序列化失败错误。假设会话 1 - 正在更新某个分区键,与此同时,一个对该行可见的并发会话 2 对该行 + DELETE时,有可能收到串行化失败错误。假设会话 1 + 正在对某个分区键执行UPDATE,与此同时,一个能够看到该行的并发会话 2 对该行 执行UPDATEDELETE操作。在 这种情况下,会话 2 的UPDATE或 - DELETE将检测到行移动,并引发序列化失败错误 - (其 SQLSTATE 代码始终为'40001')。如果发生 + DELETE将检测到行移动,并引发串行化失败错误 + (其 SQLSTATE 代码始终为'40001')。如果发生 这种情况,应用程序可能需要重试事务。在表未分区或没有发生行移动 的通常情况下,会话 2 会识别出新更新的那一行,并在这个新行版本上执行 UPDATE/DELETE。 diff --git a/zh/14/ref/vacuum.sgml b/zh/14/ref/vacuum.sgml index 47e8673b..a9c54be9 100644 --- a/zh/14/ref/vacuum.sgml +++ b/zh/14/ref/vacuum.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation VACUUM 7 - SQL - Language Statements + SQL - 语言语句 @@ -22,6 +22,7 @@ PostgreSQL documentation VACUUM [ ( option [, ...] ) ] [ table_and_columns [, ...] ] +VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ ANALYZE ] [ table_and_columns [, ...] ] 其中option可以是下列之一: @@ -38,7 +39,7 @@ VACUUM [ ( option [, ...] ) ] [ 其中table_and_columns是: - [ ONLY ] table_name [ * ] [ ( column_name [, ...] ) ] + table_name [ ( column_name [, ...] ) ] @@ -71,11 +72,13 @@ VACUUM [ ( option [, ...] ) ] [ 并行清理。 - 如需禁用该功能,可以使用PARALLEL选项并将并行工作者数指定为零。 + 如需禁用该功能,可以使用PARALLEL选项并将并行工作进程数指定为零。 VACUUM FULL会把表的全部内容重写到一个没有额外空闲空间的新磁盘文件中, 从而让未使用的空间能够返还给操作系统。这种形式要慢得多,并且在处理每个表时都需要 ACCESS EXCLUSIVE锁。 + + 当选项列表用圆括号括起来时,选项可以按任意顺序书写。如果不加圆括号,则必须严格按照上面所示的顺序指定选项。带圆括号的语法是在PostgreSQL 9.0 中加入的;不带圆括号的语法已被弃用。 @@ -109,9 +112,7 @@ VACUUM [ ( option [, ...] ) ] [ VERBOSE - - 为每个表以INFO级别输出详细的清理活动报告。 - + 为每个表输出详细的清理活动报告。 @@ -195,14 +196,7 @@ VACUUM [ ( option [, ...] ) ] [ TRUNCATE - - 指定VACUUM应尝试截去表末尾的空页,使这些被截断页面占用的磁盘空间 - 能够返还给操作系统。通常这是期望的行为,也是默认行为,除非 - 被设为 false,或者待清理表的 - vacuum_truncate选项被设为 false。将此选项设为 false 有助于避免 - 截断操作所需的表级ACCESS EXCLUSIVE锁。使用FULL选项时, - 此选项会被忽略。 - + 指定VACUUM应尝试截去表末尾的空页,使这些被截断页面占用的磁盘空间能够返还给操作系统。通常这是期望的行为,也是默认行为,除非待清理表的vacuum_truncate选项被设为 false。将此选项设为 false 有助于避免截断操作所需的表级ACCESS EXCLUSIVE锁。使用FULL选项时,此选项会被忽略。 @@ -247,27 +241,12 @@ VACUUM [ ( option [, ...] ) ] [ - - size - - - 指定以千字节为单位的内存大小。也可以把大小写成一个字符串,即数值后跟下列任一种内存单位: - B(字节)、kB(千字节)、 - MB(兆字节)、GB(吉字节)或 - TB(太字节)。 - - - + table_name - - 要清理的特定表或物化视图的名称(可选地带模式限定)。 - 如果在表名前指定ONLY,则只清理该表。 - 如果未指定ONLY,则还会清理该表及其所有继承子表或分区(如果有)。 - 也可以在表名后显式指定*,以明确表示要清理继承子表(或分区)。 - + 要清理的特定表或物化视图的名称(可选地带模式限定)。如果指定的表是分区表,则清理它的所有叶子分区。 @@ -302,11 +281,6 @@ VACUUM [ ( option [, ...] ) ] [ VACUUM 会跳过调用用户无权清理的任何表。 - - 当VACUUM运行时,会被临时改为 - pg_catalog, pg_temp。 - - VACUUM不能在一个事务块内被执行。 @@ -317,10 +291,7 @@ VACUUM [ ( option [, ...] ) ] [ - - 我们建议定期对所有数据库执行清理,以移除死行。PostgreSQL提供了一个autovacuum机制, - 可以自动执行常规清理维护。有关自动与手动清理的更多信息,参见。 - + 我们建议对活跃的生产数据库频繁执行清理(至少每晚一次),以移除死行。在添加或删除大量行之后,对受影响的表执行VACUUM ANALYZE命令可能是个好主意。这会用所有近期变更的结果更新系统目录,使PostgreSQL查询规划器在规划查询时能够做出更好的选择。 选项不建议在日常场景中使用,但在某些特殊情况下可能很有用。 @@ -336,10 +307,11 @@ VACUUM [ ( option [, ...] ) ] [ VACUUM会显著增加 I/O 流量,这可能导致其他活动会话性能变差。 - 因此,有时建议使用基于代价的清理延迟特性。对于并行清理,每个工作者的睡眠时长 - 都与该工作者完成的工作量成比例。详见。 + 因此,有时建议使用基于代价的清理延迟特性。对于并行清理,每个工作进程的睡眠时长 + 都与该工作进程完成的工作量成比例。详见 + PostgreSQL提供了一个自动清理(autovacuum)机制,可以自动执行常规清理维护。有关自动与手动清理的更多信息,参见 每个运行不带FULL选项的VACUUM的后端,都会在 pg_stat_progress_vacuum视图中报告其进度。 @@ -353,7 +325,7 @@ VACUUM [ ( option [, ...] ) ] [ 示例 - 清理单个表onek,对其执行优化器分析,并打印详细的清理活动报告: + 清理单个表onek,对其进行分析以供优化器使用,并打印详细的清理活动报告: VACUUM (VERBOSE, ANALYZE) onek; @@ -366,14 +338,6 @@ VACUUM (VERBOSE, ANALYZE) onek; 在SQL标准中没有VACUUM语句。 - - - 下列语法在PostgreSQL 9.0版本之前使用,并且目前仍受支持: - -VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ ANALYZE ] [ table_and_columns [, ...] ] - - 请注意,在这种语法中,选项必须严格按所示顺序指定。 - diff --git a/zh/14/ref/vacuumdb.sgml b/zh/14/ref/vacuumdb.sgml index 49666392..3f58dd18 100644 --- a/zh/14/ref/vacuumdb.sgml +++ b/zh/14/ref/vacuumdb.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation vacuumdb 1 - Application + 应用程序 @@ -36,61 +36,17 @@ PostgreSQL documentation - - - dbname - - - - + dbname vacuumdb connection-option option - - - - - - - - schema - - - - - - dbname - - - - - - - - vacuumdb - connection-option - option - - - - - - - - schema - - - - - - dbname - - - - + + + + @@ -148,6 +104,9 @@ PostgreSQL documentation 禁止基于可见性映射内容跳过页面。 + + 此选项仅适用于运行PostgreSQL 9.6 及更高版本的服务器。 + @@ -176,7 +135,7 @@ PostgreSQL documentation - 积极地冻结元组。 + 激进地冻结元组。 @@ -187,6 +146,9 @@ PostgreSQL documentation 始终删除指向死元组的索引条目。 + + 此选项仅适用于运行PostgreSQL 12 及更高版本的服务器。 + @@ -214,16 +176,19 @@ PostgreSQL documentation - 仅对 multixact ID 年龄至少为 mxid_age - 的表执行清理或分析命令。此设置可用于优先处理表,以防止 multixact ID 回卷 + 仅对 多事务 ID 年龄至少为 mxid_age + 的表执行清理或分析命令。此设置可用于优先处理表,以防止 多事务 ID 回卷 (见 )。 - 就此选项而言,一个关系的 multixact ID 年龄,是其主关系及其关联的 + 就此选项而言,一个关系的 多事务 ID 年龄,是其主关系及其关联的 TOAST 表(如果存在)年龄中的较大者。由于 vacuumdb 发出的命令在必要时也会处理该关系的 TOAST 表,因此无需单独考虑它。 + + 此选项仅适用于运行PostgreSQL 9.6 及更高版本的服务器。 + @@ -240,53 +205,17 @@ PostgreSQL documentation vacuumdb 发出的命令在必要时也会处理该关系的 TOAST 表,因此无需单独考虑它。 + + 此选项仅适用于运行PostgreSQL 9.6 及更高版本的服务器。 + - - - - - 仅分析那些在列、索引表达式或扩展统计信息对象上缺少统计信息的关系。与 - 一起使用时,此选项可防止 - vacuumdb 临时用按较低统计目标生成的统计信息替换现有统计信息, - 从而避免查询优化器短暂地作出更差的选择。 - - - 此选项只能与 配合使用。 - - - 注意, 要求拥有 - SELECT 权限,以访问 - pg_statistic - 和 - pg_statistic_ext_data, - 而这些权限默认只授予超级用户。 - - - - - - - - - 仅清理或分析 schema 中的所有表。 - 可以通过多次指定 来清理多个模式。 - - - - - - - - - 不清理或分析 schema 中的任何表。 - 可以通过多次指定 来排除多个模式。 - - - + + + @@ -294,17 +223,13 @@ PostgreSQL documentation 不删除指向死元组的索引条目。 + + 此选项仅适用于运行PostgreSQL 12 及更高版本的服务器。 + - - - - - 跳过主关系。 - - - + @@ -312,6 +237,9 @@ PostgreSQL documentation 如果有,跳过与待清理表关联的 TOAST 表。 + + 此选项仅适用于运行PostgreSQL 14 及更高版本的服务器。 + @@ -321,6 +249,9 @@ PostgreSQL documentation 不截断表末尾的空页。 + + 此选项仅适用于运行PostgreSQL 12 及更高版本的服务器。 + @@ -332,6 +263,9 @@ PostgreSQL documentation 指定并行清理的并行工作进程数量。这样可以让清理利用多个 CPU 处理索引。 参见 + + 此选项仅适用于运行PostgreSQL 13 及更高版本的服务器。 + @@ -351,6 +285,9 @@ PostgreSQL documentation 跳过那些无法立即加锁并进行处理的关系。 + + 此选项仅适用于运行PostgreSQL 12 及更高版本的服务器。 + @@ -414,19 +351,12 @@ PostgreSQL documentation - - 类似 ,仅计算供优化器使用的统计信息(不执行清理)。 - 该选项会运行三个阶段的分析;第一阶段使用尽可能低的统计目标 - (见 ),以便更快地生成可用统计信息, - 随后的阶段再构建完整统计信息。 - + 仅计算供优化器使用的统计信息(不执行清理),类似。使用不同的配置设置运行多个(目前为三个)分析阶段,以便更快地生成可用统计信息。 - 此选项仅在分析当前没有统计信息,或现有统计信息完全错误的数据库时才有用,例如数据库是 - 从恢复出的转储中重新填充,或是通过 pg_upgrade 新建得到的。 - 注意,在已有统计信息的数据库上使用此选项,可能会因为早期阶段采用较低统计目标, - 导致查询优化器的选择暂时变差。 - + 此选项适合分析刚通过恢复转储或pg_upgrade填充的数据库。 + 它会尽快尝试生成一些统计信息,让数据库能够使用,然后在后续阶段生成完整统计信息。 + @@ -568,6 +498,12 @@ PostgreSQL documentation + + 注解 + + vacuumdb可能需要多次连接到PostgreSQL服务器,每次都要询问密码。在这种情况下,使用~/.pgpass文件会比较方便。更多信息见 + + 示例 @@ -592,11 +528,7 @@ PostgreSQL documentation $ vacuumdb --analyze --verbose --table='foo(bar)' xyzzy - - 清理名为 xyzzy 的数据库中 foobar 模式内的所有表: - -$ vacuumdb --schema='foo' --schema='bar' xyzzy - + diff --git a/zh/14/ref/values.sgml b/zh/14/ref/values.sgml index e5b00372..8c6d7597 100644 --- a/zh/14/ref/values.sgml +++ b/zh/14/ref/values.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation VALUES 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/14/reference.sgml b/zh/14/reference.sgml index 8f57f865..f62a9188 100644 --- a/zh/14/reference.sgml +++ b/zh/14/reference.sgml @@ -272,6 +272,7 @@ &pgupgrade; &pgwaldump; &postgres; + &postmaster; diff --git a/zh/14/release-14.sgml b/zh/14/release-14.sgml index 016b136b..6737a778 100644 --- a/zh/14/release-14.sgml +++ b/zh/14/release-14.sgml @@ -1550,14 +1550,14 @@ Branch: REL_14_STABLE [15fd7a3e2] 2026-07-28 10:56:39 +0200 --> - 在清理 GIN 索引 posting-tree 期间响应查询取消并遵守清理延迟 + 在清理 GIN 索引倒排树期间响应查询取消并遵守清理延迟 (Paul Kim、Alexander Korotkov) § - 常见值的 posting tree 可能很大,因此遗漏这项检查可能导致清理运行 + 常见值的倒排树可能很大,因此遗漏这项检查可能导致清理运行 很长时间后才注意到中断。 @@ -2971,7 +2971,7 @@ Branch: REL_15_STABLE [bab4f7fa5] 2026-05-05 10:32:42 +0900 Branch: REL_14_STABLE [172034f6e] 2026-05-05 10:34:07 +0900 --> - 在假定可排序类型上的等值条件意味着唯一性之前,检查是否存在非确定性排序规则 + 在假定支持排序规则的类型上的等值条件意味着唯一性之前,检查是否存在非确定性排序规则 (Richard Guo) § § @@ -7538,7 +7538,7 @@ Branch: REL_14_STABLE [5144e1f8f] 2025-03-11 12:50:35 +0100 Branch: REL_13_STABLE [f5b4a0b49] 2025-03-11 12:50:35 +0100 --> - 检测 BRIN 索引操作符类中缺失的支持过程,并报告错误而不是崩溃 + 检测 BRIN 索引操作符类中缺失的支持函数,并报告错误而不是崩溃 (Álvaro Herrera) § @@ -8598,7 +8598,7 @@ Branch: REL_14_STABLE [d9d5e1b48] 2024-12-07 14:28:16 -0500 Branch: REL_13_STABLE [531cbd8b7] 2024-12-07 14:28:16 -0500 --> - 修复操作符族成员操作符或支持过程可能成为悬空引用的情况 + 修复操作符族成员操作符或支持函数可能成为悬空引用的情况 (Tom Lane) § § @@ -11267,17 +11267,17 @@ Branch: REL_13_STABLE [e9c8747ee] 2024-06-27 21:08:55 +0300 Branch: REL_12_STABLE [5dea6628b] 2024-06-27 21:09:15 +0300 --> - 修复启动热备服务器时对已准备事务的子事务的处理 + 修复启动热备服务器时对预备事务的子事务的处理 (Heikki Linnakangas) § 当备库的重放从关闭检查点 WAL 记录开始时, - 主库上已准备但尚未提交的事务会被正确理解为仍在进行中。 - 但已准备事务的子事务(由保存点或 + 主库上已预备但尚未提交的事务会被正确理解为仍在进行中。 + 但预备事务的子事务(由保存点或 PL/pgSQL 异常块创建)没有被考虑在内, - 会被视为已中止。如果该已准备事务后来被提交,这会导致不一致。 + 会被视为已中止。如果该预备事务后来被提交,这会导致不一致。 @@ -15504,8 +15504,8 @@ Branch: REL_11_STABLE [0048c3b51] 2023-07-04 09:27:00 +1200 - 使用位图堆扫描、使用 GIN 索引以及检查初始为空的 B-树 索引时可能会遗漏冲突。 - 所有这些情况都可能因不当允许冲突事务提交而导致可序列化失败。 + 使用位图堆扫描、使用 GIN 索引以及检查初始为空的 B-树索引时可能会遗漏冲突。 + 所有这些情况都可能因不当允许相互冲突的事务提交而破坏可串行性。 @@ -24214,7 +24214,7 @@ Branch: REL_14_STABLE [6cac34339] 2021-10-27 13:09:01 -0700 Branch: REL_13_STABLE [d5a2ffbce] 2021-10-27 13:09:00 -0700 --> - 增加更多围绕 B-树 posting list 分裂的防御性检查(Peter Geoghegan) + 增加更多围绕 B-树倒排列表分裂的防御性检查(Peter Geoghegan) § § diff --git a/zh/14/runtime.sgml b/zh/14/runtime.sgml index b170f555..3ff8078f 100644 --- a/zh/14/runtime.sgml +++ b/zh/14/runtime.sgml @@ -1,7 +1,6 @@ - 服务器设置和操作 @@ -13,11 +12,10 @@ - <productname>PostgreSQL</productname>用户账户 - postgres user + postgres 用户 @@ -34,7 +32,6 @@ - 创建一个数据库集簇 @@ -47,7 +44,7 @@ - 在做任何事情之前,必须先在磁盘上初始化一个数据库存储区域。我们把它称为数据库集簇。(SQL 标准使用术语 catalog cluster。)数据库集簇是由一个正在运行的数据库服务器实例管理的一组数据库。初始化之后,数据库集簇中会包含一个名为postgres的数据库,作为供工具、用户和第三方应用使用的默认数据库。数据库服务器本身并不要求该postgres数据库存在,但许多外部工具程序都假定它存在。初始化期间,集簇中还会创建另一个数据库,名为template1。顾名思义,它会作为后续新建数据库的模板;不应将它用于实际工作。(关于在集簇中创建新数据库的信息,见。) + 在做任何事情之前,必须先在磁盘上初始化一个数据库存储区域。我们把它称为数据库集簇。(SQL 标准使用术语目录集簇(catalog cluster)。)数据库集簇是由一个正在运行的数据库服务器实例管理的一组数据库。初始化之后,数据库集簇中会包含一个名为postgres的数据库,作为供工具、用户和第三方应用使用的默认数据库。数据库服务器本身并不要求该postgres数据库存在,但许多外部工具程序都假定它存在。初始化期间,集簇中还会创建另一个数据库,名为template1。顾名思义,它会作为后续新建数据库的模板;不应将它用于实际工作。(关于在集簇中创建新数据库的信息,见。) @@ -67,7 +64,6 @@ - 除了使用 选项,也可以设置环境变量 PGDATAPGDATA @@ -112,9 +108,7 @@ postgres$ initdb -D /usr/local/pgsql/data 另外,指定,以避免使用默认的trust认证方式;或者在运行initdb之后、首次启动服务器之前修改生成的pg_hba.conf文件。(其他合理方法包括使用peer认证,或使用文件系统权限限制连接。更多信息见。) - - initdb还会为数据库集簇初始化默认区域设置locale。通常,它只是采用环境中的区域设置,并将其应用到新初始化的数据库。你也可以为数据库指定不同的区域设置;更多信息见。该数据库集簇内部使用的默认排序顺序由initdb设定。虽然你可以创建采用不同排序顺序的新数据库,但initdb创建的模板数据库所使用的排序顺序,若不删除并重建它们就无法更改。使用非CPOSIX区域设置还会带来性能影响,因此第一次就做出正确选择很重要。 - + initdb 还会初始化数据库集簇的默认区域设置区域设置。通常,它会直接采用环境中的区域设置,并将其应用于初始化的数据库。可以为数据库指定不同的区域设置;更多信息见 。特定数据库集簇中使用的默认排序顺序由 initdb 设置,虽然你可以使用不同的排序顺序创建新数据库,但 initdb 创建的模板数据库所使用的顺序,只有删除并重建这些数据库才能更改。使用 CPOSIX 以外的区域设置还会影响性能。因此,一开始就作出正确选择很重要。 initdb还会为数据库集簇设置默认字符集编码。通常应选择与区域设置相匹配的字符集编码。详见。 @@ -139,7 +133,6 @@ postgres$ initdb -D /usr/local/pgsql/data - 文件系统 @@ -147,7 +140,6 @@ postgres$ initdb -D /usr/local/pgsql/data - NFS @@ -162,9 +154,7 @@ postgres$ initdb -D /usr/local/pgsql/data 对于在PostgreSQL中使用NFS,唯一硬性要求是文件系统必须使用hard选项挂载。使用hard选项时,如果出现网络问题,进程可能会无限期地挂起,因此这种配置需要配套谨慎的监控措施。soft选项会在网络问题出现时中断系统调用,但PostgreSQL不会重试以这种方式被中断的系统调用,因此任何此类中断都会导致报告 I/O 错误。 - - 没有必要使用sync挂载选项。async选项的行为已经足够,因为PostgreSQL会在适当的时候发出fsync调用来刷新写缓存。(这和它在本地文件系统上的工作方式类似。)但是,强烈建议在支持该选项的NFS服务器端系统上使用sync导出选项(主要是 Linux)。否则,NFS 客户端上的fsync或等效操作实际上并不能保证数据到达服务器上的持久存储,这可能导致类似于将参数设为关闭时那样的损坏。这些挂载和导出选项的默认值在不同厂商和版本间并不相同,因此无论如何都建议检查它们,并且最好显式指定,以避免歧义。 - + 没有必要使用 sync 挂载选项。async 选项的行为已经足够,因为 PostgreSQL 会在适当的时候发出 fsync 调用将写缓存刷盘。(这和它在本地文件系统上的工作方式类似。)但是,强烈建议在支持该选项的 NFS 服务器端系统上使用 sync 导出选项(主要是 Linux)。否则,NFS 客户端上的 fsync 或等效操作实际上并不能保证数据到达服务器上的持久存储,这可能导致类似于将参数 设为关闭时那样的损坏。这些挂载和导出选项的默认值在不同厂商和版本间并不相同,因此无论如何都建议检查它们,并且最好显式指定,以避免歧义。 在某些情况下,可以通过 NFS 或更底层的协议(例如 iSCSI)访问外部存储产品。在后一种情况下,存储会表现为块设备,可以在其上创建任意可用的文件系统。这种方式或许能让 DBA 不必应对 NFS 的某些特性,但当然,管理远程存储的复杂性会转移到其他层面。 @@ -175,7 +165,6 @@ postgres$ initdb -D /usr/local/pgsql/data - 启动数据库服务器 @@ -215,7 +204,7 @@ pg_ctl start -l logfile - 通常,你会希望在计算机启动时就启动数据库服务器。booting启动服务器时自动启动脚本依赖于操作系统。PostgreSQLcontrib/start-scripts 目录中附带了一些示例脚本。安装这些脚本需要 root 权限。 + 通常,你会希望在计算机启动时就启动数据库服务器。引导期间启动服务器自动启动脚本依赖于操作系统。PostgreSQLcontrib/start-scripts 目录中附带了一些示例脚本。安装这些脚本需要 root 权限。 @@ -232,14 +221,14 @@ su postgres -c 'pg_ctl start -D /usr/local/pgsql/data -l serverlog' 对于FreeBSD,请查看PostgreSQL源码发布包中的contrib/start-scripts/freebsd文件。 - FreeBSDstart script + FreeBSD启动脚本 OpenBSD上,把以下内容加入/etc/rc.local: - OpenBSDstart script + OpenBSD启动脚本 if [ -x /usr/local/pgsql/bin/pg_ctl -a -x /usr/local/pgsql/bin/postgres ]; then su -l postgres -c '/usr/local/pgsql/bin/pg_ctl start -s -l /var/postgresql/log -D /usr/local/pgsql/data' @@ -252,7 +241,7 @@ fi Linux系统上,可以把 - Linuxstart script + Linux启动脚本 /usr/local/pgsql/bin/pg_ctl start -l logfile -D /usr/local/pgsql/data @@ -291,14 +280,14 @@ WantedBy=multi-user.target NetBSD上,可根据偏好使用FreeBSDLinux的启动脚本。 - NetBSDstart script + NetBSD启动脚本 Solaris上,创建一个名为/etc/init.d/postgresql的文件,其中包含以下内容: - Solarisstart script + Solaris启动脚本 su - postgres -c "/usr/local/pgsql/bin/pg_ctl start -l logfile -D /usr/local/pgsql/data" @@ -360,7 +349,6 @@ DETAIL: Failed system call was semget(5440126, 17, 03600). - 客户端连接问题 @@ -372,7 +360,7 @@ DETAIL: Failed system call was semget(5440126, 17, 03600). psql: error: connection to server at "server.joe.com" (123.123.123.123), port 5432 failed: Connection refused Is the server running on that host and accepting TCP/IP connections? - 这是一个典型的我找不到可通信的服务器错误。上面这种情况发生在尝试使用 TCP/IP 通信时。一个常见错误是忘记配置,从而导致服务器不接受远程 TCP 连接。 + 这是一个典型的我找不到可通信的服务器错误。上面这种情况发生在尝试使用 TCP/IP 通信时。一个常见错误是忘记配置服务器以允许 TCP/IP 连接。 @@ -391,15 +379,13 @@ psql: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: No such - 管理内核资源 - PostgreSQL有时会耗尽操作系统的各种资源限制,尤其是在同一系统上运行多个服务器副本,或在非常大型的安装环境中时更是如此。本节解释PostgreSQL使用的内核资源,以及你可以采取哪些步骤来解决与内核资源消耗相关的问题。 + PostgreSQL有时会达到操作系统的各种资源上限,尤其是在同一系统上运行多个服务器实例,或在非常大型的安装环境中时更是如此。本节解释PostgreSQL使用的内核资源,以及你可以采取哪些步骤来解决与内核资源消耗相关的问题。 - 共享内存和信号量 @@ -419,11 +405,10 @@ psql: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: No such - System V IPC 功能通常受系统范围的分配限制约束。当PostgreSQL超出这些限制之一时,服务器会拒绝启动,并留下带有指导性的错误消息,说明问题所在以及应如何处理(另见)。相关内核参数在不同系统上的命名基本一致,给出了概览;不过,设置它们的方法却各不相同。下面给出一些平台上的建议。 + System V IPC 功能通常受系统范围的分配限制约束。当PostgreSQL超出这些限制之一时,服务器会拒绝启动,并应留下带有指导性的错误消息,说明问题所在以及应如何处理(另见)。相关内核参数在不同系统上的命名基本一致,给出了概览;不过,设置它们的方法却各不相同。下面给出一些平台上的建议。 - <systemitem class="osname">System V</systemitem> <acronym>IPC</acronym>参数 @@ -431,7 +416,6 @@ psql: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: No such - 名称 描述 @@ -440,11 +424,10 @@ psql: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: No such - SHMMAX 共享内存段的最大尺寸(字节) - 至少 1kB,但是默认值通常要高一些 + 至少 1kB,但是默认值通常高得多 @@ -475,13 +458,13 @@ psql: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: No such SEMMNI 信号量标识符(即,集合)的最大数目 - 至少 ceil(num_os_semaphores / 16),并为其他应用保留空间 + 至少 ceil((max_connections + autovacuum_max_workers + max_wal_senders + max_worker_processes + 6) / 16),并为其他应用保留空间 SEMMNS 系统范围内的最大信号量数目 - ceil(num_os_semaphores / 16) * 17,并为其他应用保留空间 + ceil((max_connections + autovacuum_max_workers + max_wal_senders + max_worker_processes + 6) / 16) * 17,并为其他应用保留空间 @@ -507,8 +490,8 @@ psql: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: No such
- PostgreSQL要求少量字节的 System V 共享内存(在 64 位平台上通常是 48 字节)用于每一个服务器拷贝。在大多数现代操作系统上,这个量很容易得到。 - 但是,如果你运行了很多个服务器副本,或者显式配置服务器以使用大量 System V 共享内存(参见 ), + PostgreSQL要求少量字节的 System V 共享内存(在 64 位平台上通常是 48 字节)用于每一个服务器实例。在大多数现代操作系统上,这个量很容易得到。 + 但是,如果你运行了很多个服务器实例,或者显式配置服务器以使用大量 System V 共享内存(参见 ), 可能需要增加SHMALL(系统范围内 System V 共享内存的总量)。注意在很多系统上SHMALL是以页面而不是字节来度量。 @@ -516,30 +499,36 @@ psql: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: No such 不太可能出问题的是共享内存段的最小尺寸(SHMMIN),对PostgreSQL来说应该最多大约是 32 字节(通常只是1)。而系统范围(SHMMNI)或每个进程(SHMSEG)的最大共享内存段数目不太可能会导致问题,除非你的系统把它们设成零。 - - 当使用 System V 信号量时,PostgreSQL会为每个允许连接()、每个允许自动清理工作进程()、每个允许 WAL 发送进程()、每个允许后台进程()等分配一个信号量,按 16 个一组。运行期计算参数会报告所需信号量数;可在启动服务器前用如下命令查看: - -$ postgres -D $PGDATA -C num_os_semaphores - - - - - 每组 16 个信号量还包含第 17 个信号量,用于存放magic number,以检测与其他应用信号量集合的冲突。系统最大信号量数由 SEMMNS 设定,因此至少应为 num_os_semaphores 加上每组 16 个所需信号量的一个附加量(见中的公式)。SEMMNI决定系统中同一时刻可存在的信号量集合数上限,因此至少应为 ceil(num_os_semaphores / 16)。降低允许连接数是对通常带有误导措辞设备上没有剩余空间(来自semget)这类失败的临时缓解手段。 - + 使用 System V 信号量时,PostgreSQL 为每个允许的连接()、自动清理工作进程()、WAL 发送进程()和后台进程()各使用一个信号量,每 16 个组成一组。每组还包含第 17 个信号量,其中存放一个魔数,用来检测与其他应用程序使用的信号量集的冲突。系统中的信号量最大数量由 SEMMNS 设置,因此它必须至少等于 max_connectionsautovacuum_max_workersmax_wal_sendersmax_worker_processes 之和,再为每 16 个允许的连接和工作进程额外增加一个信号量(参见 中的公式)。参数 SEMMNI 限制系统中同时存在的信号量集的数量。因此,此参数必须至少为 ceil((max_connections + autovacuum_max_workers + max_wal_senders + max_worker_processes + 6) / 16)。降低允许的连接数,可以临时规避 semget 函数的失败;此类失败通常会报告令人困惑的 No space left on device 在某些情况下,可能还需要增大SEMMAP,使其至少与SEMMNS处于同一数量级。如果系统提供这个参数(很多系统没有),它定义的是信号量资源映射的大小;映射中每个连续的可用信号量块都需要占用一项。每当一个信号量集合被释放时,它要么会并入与该释放块相邻的现有项,要么会登记为一个新的映射项。如果映射已满,被释放的信号量就会丢失(直到重启)。因此,随着时间推移,信号量空间碎片化可能会导致可用信号量少于应有数量。 - 与semaphore undo有关的其他各种设置,如SEMMNUSEMUME,不会影响PostgreSQL。 + 与信号量撤销有关的其他各种设置,如SEMMNUSEMUME,不会影响PostgreSQL - 当使用 POSIX 信号量时,所需数量与 System V 相同,即每个允许连接()、每个允许自动清理工作进程()、每个允许 WAL 发送进程()、每个允许后台进程()等各需一个。在优先使用该实现的平台上,POSIX 信号量数量没有特定内核上限。 + 当使用 POSIX 信号量时,所需数量与 System V 相同,即每个允许连接()、每个允许自动清理工作进程()、每个允许 WAL 发送进程()、每个允许后台进程()各需一个。在优先使用该实现的平台上,POSIX 信号量数量没有特定内核上限。 + + + AIX + AIXIPC 配置 + + + + 对于 SHMMAX 之类的参数,通常不需要任何特殊配置,因为看起来系统已经配置为允许将所有内存都用作共享内存。这类配置也常用于其他数据库,例如 DB/2。 + + + 不过,可能需要修改 /etc/security/limits 中的全局 ulimit 信息,因为文件大小(fsize)和文件数量(nofiles)的默认硬限制可能过低。 + + + + FreeBSD @@ -572,15 +561,11 @@ $ postgres -D $PGDATA -C num_os_semaphores - NetBSD NetBSDIPC 配置 - - - 默认共享内存设置通常就足够了,除非你已将 shared_memory_type 设置为 sysv。不过,你需要增大 kern.ipc.semmnikern.ipc.semmns,因为 NetBSD 对这两项的默认值小得实际上无法使用。 - + 默认共享内存设置通常就足够了,除非你已将 shared_memory_type 设置为 sysv。通常需要增大 kern.ipc.semmnikern.ipc.semmns,因为 NetBSD 对这两项的默认设置小得不便使用。 可以使用 sysctl 调整 IPC 参数,例如: @@ -597,15 +582,11 @@ $ postgres -D $PGDATA -C num_os_semaphores - OpenBSD OpenBSDIPC 配置 - - - 默认共享内存设置通常就足够了,除非你已将 shared_memory_type 设置为 sysv。不过,你需要增大 kern.seminfo.semmnikern.seminfo.semmns,因为 OpenBSD 对这两项的默认值小得实际上无法使用。 - + 默认共享内存设置通常已经足够,除非你将 shared_memory_type 设为 sysv。通常需要增大 kern.seminfo.semmnikern.seminfo.semmns,因为 OpenBSD 对这两项的默认设置小得令人担忧。 可以使用 sysctl 调整 IPC 参数,例如: @@ -618,6 +599,17 @@ $ postgres -D $PGDATA -C num_os_semaphores + + HP-UX + HP-UXIPC 配置 + + + 默认设置通常足以满足普通安装的需求。 + 可以在 System Administration ManagerSAM)的 Kernel ConfigurationConfigurable Parameters 中设置 IPC 参数。完成后选择 Create A New Kernel + + + + Linux @@ -630,7 +622,7 @@ $ postgres -D $PGDATA -C num_os_semaphores - 共享内存大小设置可以通过sysctl界面更改。例如,允许 16 GB: + 共享内存大小设置可以通过sysctl接口更改。例如,允许 16 GB: $ sysctl -w kernel.shmmax=17179869184 $ sysctl -w kernel.shmall=4194304 @@ -641,17 +633,15 @@ $ postgres -D $PGDATA -C num_os_semaphores - + macOS macOSIPC 配置 - 默认共享内存和信号量设置通常就足够了,除非你已将 shared_memory_type 设置为 sysv - 在 macOS 中配置共享内存的推荐方法是创建一个名为/etc/sysctl.conf的文件,其中包含这样的变量赋值: @@ -668,9 +658,7 @@ kern.sysv.shmall=1024 SHMMAX 只能设置为 4096 的倍数。 - - 在这个平台上,SHMALL以 4kB 的页面度量。 - + 在这个平台上,SHMALL 以 4 kB 的页为单位。 SHMMNI 之外,其他设置都可以使用 sysctl 动态更改。不过,最好还是通过/etc/sysctl.conf设置你希望使用的值,这样重启后仍能保留。 @@ -683,9 +671,8 @@ kern.sysv.shmall=1024 Solaris illumos - - 默认的共享内存和信号量设置对于大多数 PostgreSQL 应用通常已经足够。Solaris 现在将SHMMAX的默认值设为系统 RAM 的四分之一。要进一步调整这一设置,可使用与postgres用户关联的项目设置。例如,以root运行下列命令: + 默认的共享内存和信号量设置对于大多数 PostgreSQL 应用通常已经足够。Solaris 将SHMMAX的默认值设为系统 RAM 的四分之一。要进一步调整这一设置,可使用与postgres用户关联的项目设置。例如,以root运行下列命令: projadd -c "PostgreSQL DB User" -K "project.max-shm-memory=(privileged,8GB,deny)" -U postgres -G postgres user.postgres @@ -715,7 +702,6 @@ project.max-msg-ids=(priv,4096,deny) - systemd RemoveIPC @@ -723,15 +709,15 @@ project.max-msg-ids=(priv,4096,deny) RemoveIPC - + 如果使用systemd,必须注意不要让操作系统过早移除 IPC 资源(包括共享内存)。这在从源码安装 PostgreSQL 时尤其值得关注。使用发行版软件包的用户较不容易受到影响,因为此时postgres用户通常会被创建为系统用户。 - + logind.conf 中的 RemoveIPC 设置控制当用户完全注销时是否移除 IPC 对象。系统用户不受此限制。原版 systemd 默认开启该设置,但某些操作系统发行版默认将其关闭。 - + 当此设置开启时,一个常见现象是,用于并行查询执行的共享内存对象会在看似随机的时间被删除,导致在尝试打开或删除它们时出现错误和警告,例如 WARNING: could not remove shared memory segment "/PostgreSQL.1450751626": No such file or directory @@ -739,19 +725,19 @@ WARNING: could not remove shared memory segment "/PostgreSQL.1450751626": No su 不同类型的 IPC 对象(共享内存与信号量、System V 与 POSIX)在 systemd 中的处理略有不同,因此你可能会发现某些 IPC 资源不会像其他资源那样被删除。但依赖这些细微差别并不可取。 - - 用户注销可能会作为维护作业的一部分发生,也可能在管理员以postgres用户或类似名称登录时手工触发,因此通常很难彻底防止。 + + 用户注销可能会作为维护作业的一部分发生,也可能在管理员以postgres用户登录或执行类似操作时手工触发,因此通常很难彻底防止。 - + 什么算作系统用户,是在编译 systemd 时依据 /etc/login.defs 中的 SYS_UID_MAX 设置确定的。 - + 打包和部署脚本应当谨慎地使用useradd -radduser --system或其等价方式,把postgres用户创建为系统用户。 - + 或者,如果该用户账户创建得不正确,或无法更改,建议在/etc/systemd/logind.conf或其他适当的配置文件中设置 RemoveIPC=no @@ -759,7 +745,6 @@ RemoveIPC=no - 上述两件事至少要确保做到其中之一,否则 PostgreSQL 服务器会变得非常不可靠。 @@ -767,10 +752,9 @@ RemoveIPC=no - 资源限制 - + 类 Unix 操作系统会施加多种资源限制,这些限制可能干扰 PostgreSQL 服务器的运行。其中尤其重要的是:每个用户可用的进程数限制、每个进程可打开文件数限制,以及每个进程可用内存量限制。每一种限制都有限制和限制。实际生效的是软限制,但用户可以自行把它调高到不超过硬限制;硬限制则只能由 root 用户修改。系统调用setrlimit负责设置这些参数。shell 的内置命令ulimit(Bourne shell)或limitcsh)可用于在命令行控制资源限制。在 BSD 派生系统上,/etc/login.conf文件控制登录时设置的各种资源限制。详细信息请参阅操作系统文档。相关参数有maxprocopenfilesdatasize。例如: default:\ @@ -783,7 +767,7 @@ default:\ (-cur表示软限制;把它改为-max则表示设置硬限制。) - + 内核还可能对某些资源施加系统范围的限制。 @@ -799,29 +783,28 @@ default:\ - + PostgreSQL服务器为每个连接使用一个进程,因此你至少应提供与允许连接数相同数量的进程,再加上系统其他部分所需的进程数。通常这不是问题,但如果你在一台机器上运行多个服务器,资源可能就会变得紧张。 - + 打开文件数的出厂默认限制通常被设为对共享环境友好的值,也就是允许许多用户在一台机器上共存,而不会占用不成比例的系统资源。如果你在一台机器上运行很多服务器,这也许正合适;但在专用服务器上,你可能会希望提高这个限制。 - + 另一方面,有些系统允许单个进程打开非常多的文件;如果不止少数几个进程都这么做,就很容易超过系统范围的限制。如果你遇到这种情况,又不想修改系统范围的限制,可以设置PostgreSQL配置参数来限制其打开文件的消耗。 - - 另一个在支持大量客户端连接时可能需要关注的内核限制,是套接字连接队列的最大长度。如果在很短时间内到达的连接请求超过了这个数量,那么其中一些请求可能会在PostgreSQL服务器来得及处理之前就被拒绝,于是客户端会收到不太有帮助的连接失败错误,例如Resource temporarily unavailableConnection refused。在许多平台上,默认队列长度限制是 128。要提高它,请通过sysctl调整相应的内核参数,然后重新启动PostgreSQL服务器。该参数在不同系统上的名称不同:在 Linux 上是net.core.somaxconn,在较新的 FreeBSD 上是kern.ipc.soacceptqueue,在 macOS 和其他 BSD 变体上是kern.ipc.somaxconn。 + + 另一个在支持大量客户端连接时可能需要关注的内核限制,是套接字连接队列的最大长度。如果在很短时间内到达的连接请求超过了这个数量,那么其中一些请求可能会在postmaster来得及处理之前就被拒绝,于是客户端会收到不太有帮助的连接失败错误,例如Resource temporarily unavailableConnection refused。在许多平台上,默认队列长度限制是 128。要提高它,请通过sysctl调整相应的内核参数,然后重新启动postmaster。该参数在不同系统上的名称不同:在 Linux 上是net.core.somaxconn,在较新的 FreeBSD 上是kern.ipc.soacceptqueue,在 macOS 和其他 BSD 变体上是kern.ipc.somaxconn - Linux 内存过量分配 - memory overcommit + 内存过量分配 @@ -829,14 +812,14 @@ default:\ - overcommit + 过量分配 - + Linux 上默认的虚拟内存行为对PostgreSQL并非最佳。由于内核实现内存过量分配的方式,如果 PostgreSQL 或其他进程的内存需求导致系统耗尽虚拟内存,内核可能会终止 PostgreSQL 的 postmaster(主管服务器进程)。 - + 如果发生这种情况,你会看到类似下面的内核消息(至于应到哪里查看此类消息,请参阅你的系统文档和配置): Out of Memory: Killed process 12345 (postgres). @@ -844,15 +827,15 @@ Out of Memory: Killed process 12345 (postgres). 这表示 postgres 进程因内存压力而被终止。尽管现有数据库连接仍会继续正常运行,但新连接将不再被接受。要恢复服务,必须重启PostgreSQL - + 避免该问题的一种办法,是让PostgreSQL运行在一台你能确定不会被其他进程耗尽内存的机器上。如果内存紧张,增加操作系统交换空间也有助于避免这个问题,因为内存不足(OOM)杀手只有在物理内存和交换空间都耗尽时才会被触发。 - - 如果导致系统耗尽内存的正是PostgreSQL自身,那么你可以通过调整配置来避免该问题。在某些情况下,调低与内存相关的配置参数会有帮助,尤其是shared_bufferswork_memhash_mem_multiplier。在其他情况下,允许数据库服务器接受过多连接也可能导致这一问题。很多时候,更好的做法是减小max_connections,并转而使用外部连接池软件。 + + 如果导致系统耗尽内存的正是PostgreSQL自身,那么你可以通过调整配置来避免该问题。在某些情况下,调低与内存相关的配置参数会有帮助,尤其是shared_bufferswork_memhash_mem_multiplier。在其他情况下,允许数据库服务器接受过多连接也可能导致这一问题。很多时候,更好的做法可能是减小max_connections,并转而使用外部连接池软件。 - + 还可以修改内核行为,使其不再过量分配内存。尽管这种设置无法彻底阻止OOM 杀手被触发,但能显著降低其发生概率,从而得到更稳健的系统行为。这可以通过使用sysctl选择严格的过量分配模式来实现: sysctl -w vm.overcommit_memory=2 @@ -860,26 +843,33 @@ sysctl -w vm.overcommit_memory=2 或者在/etc/sysctl.conf中加入等效设置。你可能还希望修改相关设置vm.overcommit_ratio。详细信息请参阅内核文档中的文件。 - - 另一种方法可在修改或不修改 vm.overcommit_memory 的情况下使用:把 PostgreSQL 主进程的 OOM score adjustment 值设为 -1000,从而保证它不会成为 OOM 杀手的目标。最简单的做法是在 PostgreSQL 启动脚本中、调用 postgres 之前执行以下命令: + + 另一种方法可在修改或不修改 vm.overcommit_memory 的情况下使用: + 把 postmaster 进程专属的OOM 评分调整值设为 -1000, + 从而保证它不会成为 OOM 杀手的目标。最简单的做法是在 postmaster + 启动脚本中、调用 postmaster 之前执行: echo -1000 > /proc/self/oom_score_adj - 请注意,这个操作必须以 root 身份完成,否则不会生效。因此,最容易放置该操作的位置是由 root 拥有的启动脚本。如果这样做,你还应该在调用 postgres 之前,在启动脚本中设置这些环境变量: + 请注意,这个操作必须以 root 身份完成,否则不会生效;因此,由 root 拥有的启动脚本是最容易执行该操作的位置。 + 如果这样做,还应在调用 postmaster 之前,在启动脚本中设置以下环境变量: export PG_OOM_ADJUST_FILE=/proc/self/oom_score_adj export PG_OOM_ADJUST_VALUE=0 - 这些设置会使 postgres 子进程以默认值零的 OOM score adjustment 运行,因此 OOM 杀手在需要时仍可将它们作为目标。如果你希望子进程使用其他 OOM score adjustment 值,也可以为 PG_OOM_ADJUST_VALUE 指定其他数值(也可省略,此时默认为零)。如果不设置 PG_OOM_ADJUST_FILE,子进程就会和主进程使用相同的 OOM score adjustment,这并不明智,因为这样做的目的正是为了确保主进程拥有优先保护设置。 - + 这些设置会使 postmaster 子进程以常规的 OOM 评分调整值零运行,以便 OOM 杀手在需要时仍可将它们作为目标。 + 如果希望子进程以其他 OOM 评分调整值运行,也可以为 PG_OOM_ADJUST_VALUE 指定其他值。 + (也可以省略 PG_OOM_ADJUST_VALUE,此时默认为零。) + 如果不设置 PG_OOM_ADJUST_FILE,子进程就会和 postmaster 使用相同的 OOM 评分调整值, + 这并不明智,因为这样做的目的正是确保 postmaster 获得优先保护。 + - Linux 大页 - + 使用大页可以减少PostgreSQL这类会使用大块连续内存的软件所带来的开销,尤其是在取值较大时。要在PostgreSQL中使用这一特性,你需要一个启用了CONFIG_HUGETLBFS=yCONFIG_HUGETLB_PAGE=y的内核。你还需要把操作系统配置为提供足够多、且大小合适的大页。要估算所需的大页数量,可以先在不启用大页的情况下启动PostgreSQL,然后使用/proc/sys文件系统检查 postmaster 的匿名共享内存段大小,以及系统默认和支持的大页大小。操作可能如下: $ head -1 $PGDATA/postmaster.pid @@ -905,30 +895,31 @@ hugepages-1048576kB hugepages-2048kB 也可以在启动时通过内核参数(例如hugepagesz=2M hugepages=3170)提供这些设置。 - + 有时由于内存碎片,内核无法立即分配所需数量的大页,因此可能需要重复执行该命令,或者重启系统。(重启后,机器上的大部分内存应当都可立即转换为大页。)要检查某一给定大小的大页分配情况,请使用: $ cat /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages - - 你可能还需要授予数据库服务器的操作系统用户使用大页的权限,例如通过sysctl设置vm.hugetlb_shm_group,以及/或者授予其使用ulimit -l锁定内存的权限。 - + + 可能还需要通过 sysctl 设置 vm.hugetlb_shm_group, + 授予数据库服务器的操作系统用户使用大页的权限,以及/或者通过 ulimit -l 授予其锁定内存的权限。 + - + PostgreSQL对大页的默认行为是:只要可能就使用它们,采用系统默认的大页大小;如果失败,则回退到普通页面。要强制使用大页,可以在postgresql.conf中将设为on。请注意,在这种设置下,如果没有足够的大页可用,PostgreSQL将无法启动。 - + 关于Linux大页特性的详细说明,请参见 - + 关闭服务器 @@ -936,7 +927,7 @@ $ cat /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages - 有几种关闭数据库服务器的方法。在后台,它们都简化为向主管 postgres 进程发送信号。 + 有几种关闭数据库服务器的方法。这些方法在内部都是向主管 postgres 进程发送信号。 @@ -953,7 +944,7 @@ $ cat /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages 这是智能关闭模式。 收到SIGTERM后,服务器禁止新连接,但允许现有会话正常结束工作。 - 仅在所有会话终止后才会关闭。如果服务器在请求智能关闭时处于恢复状态, + 仅在所有会话终止后才会关闭。如果服务器处于在线备份模式,还会等待该模式结束。在线备份模式生效期间,仍允许新的超级用户连接(这一例外允许超级用户连接以结束在线备份模式),但不允许其他新连接。如果服务器在请求智能关闭时处于恢复状态, 则只有在所有常规会话终止后,恢复和流复制才会停止。 @@ -966,7 +957,7 @@ $ cat /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages快速关闭模式。 服务器禁止新连接并向所有现有服务器进程发送SIGTERM, 这将导致它们中止当前事务并迅速退出。然后等待所有服务器进程退出,最后关闭。 - + 如果服务器处于在线备份模式,该模式将被终止,导致备份不可用。 @@ -978,7 +969,7 @@ $ cat /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepagesSIGQUIT并等待它们终止。 如果有任何进程在 5 秒内未终止,它们将被发送SIGKILL。 一旦所有子进程退出,主管服务器进程将立即退出,而不进行正常的数据库关闭处理。 - 这会导致下次启动时通过回放 WAL 日志执行恢复。仅建议在紧急情况下使用。 + 这会导致下次启动时通过重放 WAL 日志执行恢复。仅建议在紧急情况下使用。 @@ -993,11 +984,7 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` - - - 最好不要使用SIGKILL关闭服务器。这样做将会阻止服务器释放共享内存和信号量。 - 此外,使用SIGKILL杀掉postgres进程时,postgres不会有机会将信号传播到它的子进程,所以可能也必须手工杀掉单个的子进程。 - + 最好不要使用 SIGKILL 关闭服务器。这样做会阻止服务器释放共享内存和信号量。此外,SIGKILL 会终止 postgres 进程,使其没有机会将信号转发给子进程,因此可能还需要手动逐个终止子进程。 @@ -1006,16 +993,15 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` - 升级 <productname>PostgreSQL</productname> 集簇 - upgrading + 升级 - version - compatibility + 版本 + 兼容性 @@ -1035,7 +1021,7 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` - 新的主版本通常还会引入一些用户可见的不兼容变化,因此应用程序可能也需要做出修改。所有用户可见的变化都列在发行说明()中;请特别留意标为Migration的小节。虽然你可以从一个主版本直接升级到另一个主版本,而不必逐个升级中间版本,但仍应阅读所有中间版本的主版本发行说明。 + 新的主版本通常还会引入一些用户可见的不兼容变化,因此应用程序可能也需要做出修改。所有用户可见的变化都列在发行说明()中;请特别留意标为迁移(Migration)的小节。虽然你可以从一个主版本直接升级到另一个主版本,而不必逐个升级中间版本,但仍应阅读所有中间版本的主版本发行说明。 @@ -1089,12 +1075,10 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` - 服务器端 C 语言 API - - 这涉及以后端函数 API 为代表的变更,该 API 使用 C 语言编写。这类变更会影响那些深入引用服务器内部后端函数的代码。 + 这涉及使用 C 语言编写的后端函数 API 的变更。这类变更会影响那些深入引用服务器内部后端函数的代码。 @@ -1102,32 +1086,28 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` - 通过<application>pg_dumpall</application>升级数据 - 一种升级方法是从某个主版本的PostgreSQL导出数据,再在另一个版本中恢复。要这样做,必须使用逻辑备份工具,例如pg_dumpall;文件系统级备份方法不起作用。(系统中有相应检查,会阻止你在不兼容版本的PostgreSQL上使用某个数据目录,因此即便误用错误版本的服务器去启动某个数据目录,通常也不会造成太大损害。) + 一种升级方法是从某个主版本的PostgreSQL转储数据,再在另一个版本中恢复。要这样做,必须使用逻辑备份工具,例如pg_dumpall;文件系统级备份方法不起作用。(系统中有相应检查,会阻止你在不兼容版本的PostgreSQL上使用某个数据目录,因此即便误用错误版本的服务器去启动某个数据目录,通常也不会造成太大损害。) - - 建议使用来自较新版本PostgreSQLpg_dumppg_dumpall程序,以利用这些程序可能包含的改进。当前版本的转储程序可以读取从 9.2 起任意服务器版本的数据。 - + 建议使用来自较新版本 PostgreSQLpg_dumppg_dumpall 程序,以利用这些程序可能包含的改进。当前版本的转储程序可以读取从 8.0 起任意服务器版本的数据。 - + 以下说明假定你现有的安装位于/usr/local/pgsql目录下,数据区域位于/usr/local/pgsql/data。请根据实际情况替换成你的路径。 - - 如果是在制作备份,请确认数据库此时没有正在进行更新。这不会影响备份的一致性,但那些变更当然不会包含在备份中。必要时,可修改/usr/local/pgsql/data/pg_hba.conf中的访问权限(或采用等效方法),禁止除你之外的其他人访问数据库。有关访问控制的更多信息见。 + 如果是在制作备份,请确认数据库此时没有正在进行更新。更新操作不会影响备份的完整性,但那些变更当然不会包含在备份中。必要时,可修改/usr/local/pgsql/data/pg_hba.conf(或等效文件)中的访问权限,禁止除你之外的其他人访问数据库。有关访问控制的更多信息见 pg_dumpall - use during upgrade + 在升级期间使用 要备份整个数据库安装,请输入: @@ -1142,13 +1122,12 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` - 关闭旧服务器: pg_ctl stop - 在那些会自动启动PostgreSQL的系统上,可能已经有某个启动脚本能完成同样的工作。例如,在Red Hat Linux系统上,也许下面这条命令就可以: + 在那些会在开机时自动启动PostgreSQL的系统上,可能已经有某个启动脚本能完成同样的工作。例如,在Red Hat Linux系统上,也许下面这条命令就可以: /etc/rc.d/init.d/postgresql stop @@ -1157,7 +1136,6 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` - 如果是从备份恢复,请重命名或删除旧的安装目录,前提是它不是按版本区分的目录。与其删除,不如重命名,这样如果你遇到问题需要回退,它仍然还在。请记住,该目录可能会占用相当可观的磁盘空间。要重命名该目录,可以使用类似下面的命令: @@ -1168,14 +1146,10 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` - - - 按照 安装新版本的 PostgreSQL。 - + 按照 安装新版本的 PostgreSQL - 如有需要,创建一个新的数据库集簇。请记住,执行这些命令时必须登录到专用数据库用户账户(如果你正在升级,就已经拥有这个账户)。 @@ -1185,14 +1159,12 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` - 恢复先前的pg_hba.conf,以及你对postgresql.conf所做的任何修改。 - 启动数据库服务器,同样要使用该专门的数据库用户账户: @@ -1202,13 +1174,9 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` - - - 最后,使用新的psql从备份恢复数据: - + 最后,使用以下命令从备份恢复数据: /usr/local/pgsql/bin/psql -d postgres -f outputfile - - 这里务必使用新的psql。 +这里应使用新版 psql @@ -1235,11 +1203,10 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 - 通过复制升级数据 - 也可以使用逻辑复制方法,创建一个运行较新版本PostgreSQL的备库。之所以可行,是因为逻辑复制支持不同主版本PostgreSQL之间进行复制。该备库可以与旧服务器部署在同一台机器上,也可以部署在不同机器上。一旦它与主库(运行旧版本PostgreSQL)同步,就可以切换主备角色,让备库提升为主库,并关闭旧的数据库实例。这种切换通常只会带来几秒钟的停机时间。 + 也可以使用逻辑复制方法,创建一个运行较新版本PostgreSQL的备库。之所以可行,是因为逻辑复制支持不同主版本PostgreSQL之间进行复制。该备库可以与旧服务器部署在同一台机器上,也可以部署在不同机器上。一旦它与主库(运行旧版本PostgreSQL)同步,就可以切换主备角色,让备库提升为主库,并关闭旧的数据库实例。这种切换使升级只需几秒钟的停机时间。 @@ -1249,7 +1216,6 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 - 防止服务器欺骗 @@ -1272,22 +1238,12 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 要防止 TCP 连接上的欺骗,要么使用 SSL 证书并确保客户端检查服务器证书,要么使用 GSSAPI 加密(如果它们分别用于不同连接,也可以两者都用)。 - - 要防止 SSL 欺骗,服务器必须配置为仅接受 hostssl 连接(),并且具备 SSL 密钥和证书文件()。TCP 客户端必须使用 sslmode=verify-caverify-full 连接,并安装适当的根证书文件()。另外,也可使用 SSL 实现定义的系统 CA 池(system CA pool),即设置 sslrootcert=system;出于安全考虑,此时会强制使用 sslmode=verify-full,因为获得由公共 CA 签发的证书通常并不困难。 - + 要通过 SSL 防止服务器欺骗,服务器必须配置为仅接受 hostssl 连接(),并且具备 SSL 密钥和证书文件()。TCP 客户端必须使用 sslmode=verify-caverify-full 连接,并安装适当的根证书文件()。 - - 在网络上使用 scram-sha-256 密码认证时,为防止服务器欺骗,应确保通过 SSL 连接服务器,并使用上一段描述的任一防欺骗方法。此外,libpq 中的 SCRAM 实现无法保护整个认证交换过程,但使用连接参数 channel_binding=require 可对服务器欺骗提供一定缓解。攻击者若用伪造服务器拦截 SCRAM 交换,可能通过离线分析推导出客户端哈希密码。 - - - - 要防止 GSSAPI 欺骗,必须将服务器配置为仅接受hostgssenc连接 () 并对它们使用gss认证。 - TCP 客户端则必须使用 gssencmode=require 发起连接。 - + 要通过 GSSAPI 防止服务器欺骗,服务器必须配置为仅接受 hostgssenc 连接(),并对这些连接使用 gss 认证。TCP 客户端必须使用 gssencmode=require 连接。 - 加密选项 @@ -1295,7 +1251,7 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 - PostgreSQL提供了多个层次的加密,并在防止数据因数据库服务器被盗、不可靠的管理员或不安全网络等原因而泄露方面提供了很高的灵活性。对于医疗记录、金融交易等敏感数据,加密也可能是合规要求的一部分。 + PostgreSQL提供了多个层次的加密,并在防止数据因数据库服务器被盗、不诚实的管理员或不安全网络等原因而泄露方面提供了很高的灵活性。为了保护医疗记录、金融交易等敏感数据,也可能需要使用加密。 @@ -1309,11 +1265,7 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 数据库用户密码以哈希形式存储(由 控制),因此管理员无法得知分配给用户的实际密码。如果客户端认证使用 SCRAM 或 MD5,明文密码甚至不会暂时出现在服务器端,因为客户端会在通过网络发送前完成加密。推荐使用 SCRAM,因为它是互联网标准,并且比 PostgreSQL 特有的 MD5 认证协议更安全。 - - - 对 MD5 加密密码的支持已弃用,并将在未来版本的 PostgreSQL 中移除。迁移到其他密码类型的细节见 。 - - + @@ -1399,28 +1351,20 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 - 使用 SSL 的安全 TCP/IP 连接 SSL - TLS PostgreSQL原生支持使用SSL连接来加密客户端与服务器之间的通信,以提高安全性。这要求客户端和服务器系统上都安装了OpenSSL,并且在构建PostgreSQL时启用了该支持(见)。 - - 术语SSLTLS经常被交替使用,用来表示基于TLS协议的安全加密连接。SSL协议是TLS协议的前身,尽管SSL协议本身已不再受支持,SSL一词仍常被用来泛指这类加密连接。在PostgreSQL中,SSLTLS也是这样互换使用的。 - - 基本设置 - - 如果构建时启用了SSL支持,那么只需在postgresql.conf中把参数设为onPostgreSQL服务器就可以启用基于TLS协议的加密连接支持。服务器会在同一个 TCP 端口上同时监听普通连接和SSL连接,并与每个连接进来的客户端协商是否使用SSL。默认情况下,这由客户端决定;关于如何把服务器配置为要求某些或全部连接必须使用SSL,请参阅。 - + 如果构建时启用了 SSL 支持,那么在 postgresql.conf 中将参数 设为 on,就可以在启动 PostgreSQL 服务器时启用 SSL。服务器会在同一个 TCP 端口上同时监听普通连接和 SSL 连接,并与每个连接进来的客户端协商是否使用 SSL。默认情况下,这由客户端决定;关于如何把服务器配置为要求某些或全部连接必须使用 SSL,请参阅 要以SSL模式启动服务器,必须存在包含服务器证书和私钥的文件。默认情况下,这些文件应分别命名为server.crtserver.key,并放在服务器的数据目录中;不过也可以通过配置参数指定其他名称和位置。 @@ -1435,7 +1379,7 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 - 如果私钥受密码保护,服务器会提示输入该密码,并在输入之前不会启动。默认情况下,使用密码会禁用无需重启服务器即可更改 SSL 配置的能力,不过参见。此外,在 Windows 上完全无法使用带密码保护的私钥。 + 如果私钥受口令保护,服务器会提示输入该口令,并在输入之前不会启动。默认情况下,使用口令会禁用无需重启服务器即可更改 SSL 配置的能力,不过参见。此外,在 Windows 上完全无法使用带口令保护的私钥。 @@ -1448,7 +1392,6 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 - OpenSSL 配置 @@ -1460,9 +1403,8 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 - - 使用NULL-SHANULL-MD5密码套件,可以在几乎没有加密开销的情况下完成认证。不过,中间人仍然能够读取并转发客户端与服务器之间的通信。此外,与认证的开销相比,加密开销本身通常很小。基于这些原因,不建议使用 NULL 密码套件。 + 使用NULL-SHANULL-MD5密码套件,可以在没有加密开销的情况下完成认证。不过,中间人仍然能够读取并转发客户端与服务器之间的通信。此外,与认证的开销相比,加密开销本身很小。基于这些原因,不建议使用 NULL 密码套件。 @@ -1672,7 +1614,6 @@ openssl x509 -req -in server.csr -text -days 365 \ - 通过 <application>SSH</application> 隧道建立安全 TCP/IP 连接 @@ -1695,9 +1636,7 @@ psql -h localhost -p 63333 postgres 对数据库服务器来说,它看到的是来自主机foo.com上用户joelocalhost绑定地址的连接,并将应用为该用户到该绑定地址所配置的认证方式。请注意,服务器不会认为这是 SSL 加密连接,因为实际上SSH服务器与PostgreSQL服务器之间并没有加密。不过这通常不会带来额外安全风险,因为两者位于同一台机器上。 - - 要让这条隧道建立成功,你必须能够像建立终端会话那样,通过sshjoe@foo.com身份连接。 - + 要让这条隧道建立成功,你必须有权通过 sshjoe@foo.com 身份连接,就像尝试使用 ssh 创建终端会话一样。 你也可以把端口转发设成这样: @@ -1716,7 +1655,6 @@ ssh -L 63333:db.foo.com:5432 joe@shell.foo.com - 还有一些其他应用也能提供安全隧道,其思路与刚才描述的 SSH 方法类似。 diff --git a/zh/14/sepgsql.sgml b/zh/14/sepgsql.sgml index 4a040c99..6106c44d 100644 --- a/zh/14/sepgsql.sgml +++ b/zh/14/sepgsql.sgml @@ -76,15 +76,7 @@ Policy from config file: targeted 它,之后才能安装本模块。 - - 要构建此模块,使用 make 和 autoconf 时请指定 ,使用 meson 时请指定 。 - - 还要确保构建时已经安装 libselinux-devel RPM。 - + 要构建此模块,请将选项 --with-selinux 加入 PostgreSQL 的 configure 命令中。还要确保构建时已经安装 libselinux-devel RPM。 要使用此模块,必须将 sepgsql 包含在 diff --git a/zh/14/spgist.sgml b/zh/14/spgist.sgml index e627b18e..c2fb8ad3 100644 --- a/zh/14/spgist.sgml +++ b/zh/14/spgist.sgml @@ -4,7 +4,7 @@ SP-GiST 索引 - index + 索引 SP-GiST @@ -12,7 +12,7 @@ 简介 - SP-GiST 是 space-partitioned GiST + SP-GiST 是空间分区 GiST 的缩写。SP-GiST 支持分区搜索树,这使得开发多种不同的 非平衡数据结构成为可能,例如四叉树、k-d 树以及基数树(trie)。这些结构 的共同特征是,它们会反复将搜索空间划分为不必等大的分区。与这种划分规则良 @@ -49,7 +49,7 @@ 内置操作符类 - 核心 PostgreSQL 发行版包含了 + PostgreSQL 核心发行版包含了 SP-GiST 操作符类,如 所示。 @@ -232,11 +232,11 @@ - SP-GiST 核心代码会处理空项。虽然 - SP-GiST 索引确实会为被索引列中的空值存储项,但这一 - 点对索引操作符类代码是隐藏的:不会有空的索引项或搜索条件传递给操作符类 - 方法。(这里假定 SP-GiST 操作符是严格的,因此对空 - 值不可能成功。)因此,这里不再进一步讨论空值。 + SP-GiST 核心代码负责处理值为 null 的索引项。虽然 + SP-GiST 索引会为被索引列中的 null 值存储索引项, + 但索引操作符类代码看不到这些项:值为 null 的索引项或搜索条件绝不会传给 + 操作符类方法。(这里假定 SP-GiST 操作符是严格的, + 因此对 null 值不可能返回真。)所以这里不再讨论 null 值。 @@ -286,8 +286,8 @@ typedef struct spgConfigOut Oid prefixType; /* 内部元组前缀的数据类型 */ Oid labelType; /* 内部元组结点标签的数据类型 */ Oid leafType; /* 叶子元组值的数据类型 */ - bool canReturnData; /* 操作符类能重构原始数据 */ - bool longValuesOK; /* 操作符类能处理值 > 1 页 */ + bool canReturnData; /* 操作符类能重建原始数据 */ + bool longValuesOK; /* 操作符类能处理大小 > 1 页的值 */ } spgConfigOut; @@ -314,7 +314,7 @@ typedef struct spgConfigOut 类型与操作符类的输入类型相同,这也是最常见的情况。)出于向后兼容的原 因,config 方法也可以将 leafType 设为其他值,并且该值将被使用; - 但这已被废弃,因为这样会导致目录中对索引内容的标识不正确。此外,也允 + 但这已被弃用,因为这样会导致目录中对索引内容的标识不正确。此外,也允 许不初始化 leafType(即保持为零);这会 被解释为使用从 opckeytype 派生的索引存 储类型。 @@ -354,7 +354,7 @@ typedef struct spgChooseIn int level; /* 当前层级(从零开始计) */ /* 来自当前内部元组的数据 */ - bool allTheSame; /* 元组被标记为 all-the-same? */ + bool allTheSame; /* 元组被标记为全部相同? */ bool hasPrefix; /* 元组有前缀? */ Datum prefixDatum; /* 如果有,前缀值 */ int nNodes; /* 内部元组中的结点数 */ @@ -594,14 +594,14 @@ typedef struct spgInnerConsistentIn int nkeys; /* scankeys 数组的长度 */ int norderbys; /* orderbys 数组的长度 */ - Datum reconstructedValue; /* 在父元组处重构的值 */ + Datum reconstructedValue; /* 在父元组处重建的值 */ void *traversalValue; /* 操作符类特定的遍历值 */ MemoryContext traversalMemoryContext; /* 将新的遍历值放在这里 */ int level; /* 当前层级(从零开始计) */ bool returnData; /* 必须返回原始数据? */ /* 来自当前内部元组的数据 */ - bool allTheSame; /* 元组被标记为 all-the-same? */ + bool allTheSame; /* 元组被标记为全部相同? */ bool hasPrefix; /* 元组有前缀? */ Datum prefixDatum; /* 如果有,前缀值 */ int nNodes; /* 内部元组中的结点数 */ @@ -613,7 +613,7 @@ typedef struct spgInnerConsistentOut int nNodes; /* 需要访问的子结点数 */ int *nodeNumbers; /* 它们在结点数组中的索引 */ int *levelAdds; /* 对每个结点层级增加这么多 */ - Datum *reconstructedValues; /* 关联的重构值 */ + Datum *reconstructedValues; /* 关联的重建值 */ void **traversalValues; /* 操作符类特定的遍历值 */ double **distances; /* 关联距离 */ } spgInnerConsistentOut; @@ -624,7 +624,7 @@ typedef struct spgInnerConsistentOut 用 AND 组合 — 只有满足全部条件的索引项才是我们关心的。(注 意, nkeys = 0 表示所有索引项都满足该查 - 询。)通常 consistent 函数只关心每个数组元素的 + 询。)通常一致性检查函数只关心每个数组元素的 sk_strategysk_argument 字段,它们分别给出可索引操 作符和比较值。特别地,无需检查 sk_flags @@ -641,9 +641,8 @@ typedef struct spgInnerConsistentOut 遍历值(见下文)的内存上下文。level 是 当前内部元组的层级,根层为零。如果本查询需要重建数据,则 returnDatatrue; - 只有在 config 函数声明了 - canReturnData 时才会如此。若当前内部元组 - 被标记为 all-the-same,则 + 只有在 config 函数将 canReturnData 设为真时才会如此。若当前内部元组 + 被标记为 全部相同,则 allTheSame 为真;在这种情况下,所有结点 都具有相同的标签(如果有),因此要么全部匹配该查询,要么全部不匹配 (参见 )。若当前内部元组包 @@ -663,8 +662,7 @@ typedef struct spgInnerConsistentOut 非必然如此,所以这里使用数组。)如果需要值重建,则将 reconstructedValues 设为一个数组,其中包 含为每个待访问子结点重建的值;否则,将 - reconstructedValues 保持为 NULL。重构 - 值假定具有 spgConfigOut.leafType + reconstructedValues 保持为 NULL。重建的值假定具有 spgConfigOut.leafType 类型。(不过,由于核心系统除了可能复制它们以外不会对其做任何处理,只 要它们具有与 leafType 相同的 typlentypbyval 属性就足 @@ -713,7 +711,7 @@ typedef struct spgLeafConsistentIn int nkeys; /* scankeys 数组的长度 */ int norderbys; /* orderbys 数组的长度 */ - Datum reconstructedValue; /* 在父元组处重构的值 */ + Datum reconstructedValue; /* 在父元组处重建的值 */ void *traversalValue; /* 操作符类特定的遍历值 */ int level; /* 当前层级(从零开始计) */ bool returnData; /* 必须返回原始数据? */ @@ -723,7 +721,7 @@ typedef struct spgLeafConsistentIn typedef struct spgLeafConsistentOut { - Datum leafValue; /* 重构出的原始数据(如果有) */ + Datum leafValue; /* 重建出的原始数据(如果有) */ bool recheck; /* 如果必须重新检查操作符则设为真 */ bool recheckDistances; /* 如果必须重新检查距离则设为真 */ double *distances; /* 关联距离 */ @@ -734,7 +732,7 @@ typedef struct spgLeafConsistentOut scankeys 数组描述索引搜索条件。这些条件 用 AND 组合在一起 — 只有满足全部条件的索引项才满足该查询。(注 意 nkeys = 0 表示所有索引项都满足该查 - 询。)通常 consistent 函数只关心每个数组元素的 + 询。)通常一致性检查函数只关心每个数组元素的 sk_strategysk_argument 字段,它们分别给出可索引操 作符和比较值。特别地,无需检查 sk_flags @@ -750,8 +748,7 @@ typedef struct spgLeafConsistentOut NULL。level 是当前叶子元组的层级,根层为 零。如果本查询需要重建数据,则 returnDatatrue; - 只有在 config 函数声明了 - canReturnData 时才会如此。 + 只有在 config 函数将 canReturnData 设为真时才会如此。 leafDatum 是当前叶子元组中存储的、类型为 spgConfigOut.leafType 的键值。 @@ -844,7 +841,7 @@ LANGUAGE C STRICT; - 如果被索引列属于可应用排序规则的数据类型,则索引排序规则会通过标准的 + 如果被索引列属于支持排序规则的数据类型,则索引排序规则会通过标准的 PG_GET_COLLATION() 机制传递给所有支持方法。 @@ -922,7 +919,7 @@ LANGUAGE C STRICT; - <quote>All-the-Same</quote> 内部元组 + <quote>全部相同</quote>的内部元组 picksplit 无法把提供的叶子值划分为至少两个结点 diff --git a/zh/14/spi.sgml b/zh/14/spi.sgml index 1892c2dd..9ecc4190 100644 --- a/zh/14/spi.sgml +++ b/zh/14/spi.sgml @@ -76,7 +76,7 @@ int SPI_connect_ext(int options) SPI_connect 会为某次 C 函数调用打开到 SPI 管理器 的连接。如果要通过 SPI 执行命令,就必须调用此函数。不过,有些 SPI - 实用函数可以在未连接的 C 函数中调用。 + 辅助函数可以在未连接的 C 函数中调用。 @@ -119,7 +119,7 @@ int SPI_connect_ext(int options) SPI_ERROR_CONNECT - 出错时 + 发生错误时 @@ -291,16 +291,16 @@ SPI_execute("INSERT INTO foo SELECT * FROM bar RETURNING *", false, 5); typedef struct SPITupleTable { - /* Public members */ - TupleDesc tupdesc; /* tuple descriptor */ - HeapTuple *vals; /* array of tuples */ - uint64 numvals; /* number of valid tuples */ - - /* Private members, not intended for external callers */ - uint64 alloced; /* allocated length of vals array */ - MemoryContext tuptabcxt; /* memory context of result table */ - slist_node next; /* link for internal bookkeeping */ - SubTransactionId subid; /* subxact in which tuptable was created */ + /* 公共成员 */ + TupleDesc tupdesc; /* 元组描述符 */ + HeapTuple *vals; /* 元组数组 */ + uint64 numvals; /* 有效元组数 */ + + /* 私有成员,不供外部调用者使用 */ + uint64 alloced; /* vals 数组的已分配长度 */ + MemoryContext tuptabcxt; /* 结果表的内存上下文 */ + slist_node next; /* 用于内部管理的链接 */ + SubTransactionId subid; /* 创建 tuptable 的子事务 */ } SPITupleTable; SPI 调用者可以使用 tupdesc、 @@ -453,7 +453,7 @@ typedef struct SPITupleTable - 发生错误时,则返回下列负值之一: + 出错时,返回以下负值之一: @@ -503,7 +503,7 @@ typedef struct SPITupleTable SPI_ERROR_UNCONNECTED - 从未连接的 C 函数中调用 + 如果从一个未连接的 C 函数中调用 @@ -516,9 +516,9 @@ typedef struct SPITupleTable 所有 SPI 查询执行函数都会设置 SPI_processed 和 - SPI_tuptable(只设置指针,而不会复制结构体内容)。如果 + SPI_tuptable(只设置指针,而不更改结构体内容)。如果 需要在后续调用之后继续访问 SPI_execute 或其他查询 - 执行函数的结果表,请把这两个全局变量保存到本地 C 函数变量中。 + 执行函数的结果表,请把这两个全局变量保存到 C 函数的局部变量中。 @@ -563,7 +563,7 @@ int SPI_exec(const char * command, long count< const char * command - 包含要执行命令的字符串 + 包含待执行命令的字符串 @@ -572,7 +572,7 @@ int SPI_exec(const char * command, long count< long count - 要返回的最大行数,或者用0表示没有限制 + 要返回的最大行数,或者用 0 表示不限制 @@ -803,7 +803,7 @@ int SPI_execute_with_args(const char *command, SPI_execute_plan 达到类似效果。不过,使用本函数 时,查询计划总会针对所提供的具体参数值进行定制。对于一次性查询执行,应 优先选择本函数。如果同一条命令要用许多不同参数重复执行,则两种方式孰快 - 取决于重新计划的代价与定制计划收益之间的权衡。 + 取决于重新规划的代价与定制计划收益之间的权衡。 @@ -858,9 +858,9 @@ int SPI_execute_with_args(const char *command, 如果 nullsNULL,则 - SPI_execute_with_args 会假定没有参数为 NULL。 - 否则,如果对应参数值非 NULL,则 nulls 数组中 - 的对应项应为 ' ';如果对应参数值为 NULL,则 + SPI_execute_with_args 会假定没有参数为空值。 + 否则,如果对应参数值非空值,则 nulls 数组中 + 的对应项应为 ' ';如果对应参数值为空值,则 对应项应为 'n'。(后一种情况下,对应 values 项中的实际值无关紧要。)注意, nulls 不是文本字符串,而只是一个数组,因此不 @@ -914,7 +914,7 @@ int SPI_execute_with_args(const char *command, SPI_prepare - 准备一个语句,但不执行它 + 准备一个语句,但暂不执行 @@ -993,8 +993,7 @@ SPIPlanPtr SPI_prepare(const char * command, int 返回值 - SPI_prepare 返回一个指向非空 SPIPlan - 的指针,它是表示预备语句的不透明结构体。发生错误时会返回 + SPI_prepare 返回一个非空指针,指向表示预备语句的不透明结构体 SPIPlan。发生错误时会返回 NULL,并将 SPI_result 设为 SPI_execute 所使用的那些错误码之一;但如果 commandNULL,或者 @@ -1013,17 +1012,16 @@ SPIPlanPtr SPI_prepare(const char * command, int SPI_execute_plan 在最初几次使用时会根据提供的参数 值生成定制计划。当同一个预备语句被使用足够多次之后, SPI_execute_plan 会构建一个通用计划;如果它的代价 - 没有比定制计划高出太多,就会开始改用通用计划,而不是每次都重新计划。如 + 没有比定制计划高出太多,就会开始改用通用计划,而不是每次都重新规划。如 果这种默认行为不合适,可以把 CURSOR_OPT_GENERIC_PLANCURSOR_OPT_CUSTOM_PLAN 标志传给 SPI_prepare_cursor,分别强制使用通用计划或定制计划。 - 尽管预备语句的主要目的在于避免重复进行解析分析和计划,但只要语句中使用 + 尽管预备语句的主要目的在于避免重复进行解析分析和规划,但只要语句中使用 的数据库对象自上次使用该预备语句以来发生了定义性(DDL)变更, - PostgreSQL 就会在再次使用前强制重新分析并重 - 新计划该语句。此外,如果 的值在两次 + PostgreSQL 就会在再次使用前强制重新分析并重新规划该语句。此外,如果 的值在两次 使用之间发生变化,该语句也会基于新的 search_path 重 新解析。(后一种行为是从 PostgreSQL 9.3 开 始引入的。)有关预备语句行为的更多信息,请参见 @@ -1083,7 +1081,7 @@ SPIPlanPtr SPI_prepare_cursor(const char * command, int < - 此函数现已废弃,推荐改用 SPI_prepare_extended。 + 此函数现已弃用,推荐改用 SPI_prepare_extended @@ -1113,7 +1111,7 @@ SPIPlanPtr SPI_prepare_cursor(const char * command, int < Oid * argtypes - 指向数组的指针,该数组包含参数数据类型的 + 一个数组指针,它指向的数组包含参数的数据类型的 OID @@ -1182,7 +1180,7 @@ SPIPlanPtr SPI_prepare_extended(const char * command, SPI_prepare_extended 为指定命令创建并返回一个预备语 句,但并不执行该命令。它相当于 SPI_prepare,并额外 - 允许调用者指定选项,以控制外部参数引用的解析,以及查询解析和计划的其他 + 允许调用者指定选项,以控制外部参数引用的解析,以及查询解析和规划的其他 方面。 @@ -1222,7 +1220,7 @@ SPIPlanPtr SPI_prepare_extended(const char * command, ParserSetupHook parserSetup - 语法分析器钩子设置函数 + 解析器钩子设置函数 @@ -1300,7 +1298,7 @@ SPIPlanPtr SPI_prepare_params(const char * command, - 此函数现已废弃,推荐改用 SPI_prepare_extended。 + 此函数现已弃用,推荐改用 SPI_prepare_extended @@ -1321,7 +1319,7 @@ SPIPlanPtr SPI_prepare_params(const char * command, ParserSetupHook parserSetup - 语法分析器钩子设置函数 + 解析器钩子设置函数 @@ -1536,8 +1534,8 @@ bool SPI_is_cursor_plan(SPIPlanPtr plan) 返回值 - 如果 plan 能产生游标,则返回 - true;如果不能,则返回 false,并将 + 返回 truefalse,表示 + plan 能否产生游标,同时将 SPI_result 设为零。如果无法确定答案(例如 planNULL 或无效,或者在 未连接到 SPI 时调用),则会将 SPI_result 设为合适 @@ -1609,15 +1607,14 @@ int SPI_execute_plan(SPIPlanPtr plan, Datum * - 如果nullsNULL, - 那么SPI_execute_plan会假设没有参数 - 为空值。否则,如果对应的参数值为非空, - nulls - 数组的每一个项都应该是' ';如果对应参数值为空, - nulls数组的项应为'n'(在后 - 面的情况中,对应的values项中的值没有 - 关系)。注意nulls不是一个文本字符串, - 它只是一个数组:它不需要一个'\0'终止符。 + 如果 nullsNULL,则 + SPI_execute_plan 会假定没有参数为空值。 + 否则,如果对应参数值非空值,则 nulls 数组中 + 的对应项应为 ' ';如果对应参数值为空值,则 + 对应项应为 'n'。(后一种情况下,对应 + values 项中的实际值无关紧要。)注意, + nulls 不是文本字符串,而只是一个数组,因此不 + 需要 '\0' 终止符。 @@ -1690,7 +1687,7 @@ int SPI_execute_plan(SPIPlanPtr plan, Datum * SPI_execute_plan_extended - 执行一个由SPI_prepare准备的语句 + 执行由 SPI_prepare 准备好的语句 @@ -1775,8 +1772,9 @@ int SPI_execute_plan_extended(SPIPlanPtr plan, bool allow_nonatomic - true 允许以非原子方式执行 CALL 与 DO 语句 - (但除非向 SPI_connect_ext 传入了 + true 允许以非原子方式执行 CALL + 和 DO 语句(但除非向 + SPI_connect_ext 传入了 SPI_OPT_NONATOMIC 标志,否则该字段会被忽略) @@ -1796,7 +1794,7 @@ int SPI_execute_plan_extended(SPIPlanPtr plan, uint64 tcount - 要返回的最大行数,或者用0表示没有限制 + 要返回的最大行数,或者用 0 表示不限制 @@ -1881,7 +1879,7 @@ int SPI_execute_plan_with_paramlist(SPIPlanPtr plan, - 此函数现已废弃,推荐改用 SPI_execute_plan_extended。 + 此函数现已弃用,推荐改用 SPI_execute_plan_extended @@ -1918,7 +1916,7 @@ int SPI_execute_plan_with_paramlist(SPIPlanPtr plan, long count - 要返回的最大行数,或者用0表示没有限制 + 要返回的最大行数,或者用 0 表示不限制 @@ -2002,15 +2000,14 @@ int SPI_execp(SPIPlanPtr plan, Datum * values< - 如果nullsNULL, - 那么SPI_execp会假设没有参数 - 为空值。否则,如果对应的参数值为非空, - nulls - 数组的每一个项都应该是' ';如果对应参数值为空, - nulls数组的项应为'n'(在后 - 面的情况中,对应的values项中的值没有 - 关系)。注意nulls不是一个文本字符串, - 它只是一个数组:它不需要一个'\0'终止符。 + 如果 nullsNULL,则 + SPI_execp 会假定没有参数为空值。 + 否则,如果对应参数值非空值,则 nulls 数组中 + 的对应项应为 ' ';如果对应参数值为空值,则 + 对应项应为 'n'。(后一种情况下,对应 + values 项中的实际值无关紧要。)注意, + nulls 不是文本字符串,而只是一个数组,因此不 + 需要 '\0' 终止符。 @@ -2019,7 +2016,7 @@ int SPI_execp(SPIPlanPtr plan, Datum * values< long count - 要返回的最大行数,或者用0表示没有限制 + 要返回的最大行数,或者用 0 表示不限制 @@ -2127,15 +2124,14 @@ Portal SPI_cursor_open(const char * name, SPIPlanPtr - 如果nullsNULL, - 那么SPI_cursor_open会假设没有参数 - 为空值。否则,如果对应的参数值为非空, - nulls - 数组的每一个项都应该是' ';如果对应参数值为空, - nulls数组的项应为'n'(在后 - 面的情况中,对应的values项中的值没有 - 关系)。注意nulls不是一个文本字符串, - 它只是一个数组:它不需要一个'\0'终止符。 + 如果 nullsNULL,则 + SPI_cursor_open 会假定没有参数为空值。 + 否则,如果对应参数值非空值,则 nulls 数组中 + 的对应项应为 ' ';如果对应参数值为空值,则 + 对应项应为 'n'。(后一种情况下,对应 + values 项中的实际值无关紧要。)注意, + nulls 不是文本字符串,而只是一个数组,因此不 + 需要 '\0' 终止符。 @@ -2196,11 +2192,10 @@ Portal SPI_cursor_open_with_args(const char *name, - 对于一次性的查询执行,这个函数应该比 - SPI_prepare_cursor加上其后的 - SPI_cursor_open更好。如果相同的命令 - 要被用很多不同的参数执行,哪种方法更快就要取决于重做计划的 - 代价与定制计划带来的好处之间谁更有利。 + 对于一次性查询执行,应优先使用此函数,而不是先调用 + SPI_prepare_cursor 再调用 + SPI_cursor_open。如果同一条命令要用许多不同参数执行, + 哪种方法更快取决于重新规划的代价与定制计划收益之间的权衡。 @@ -2209,7 +2204,7 @@ Portal SPI_cursor_open_with_args(const char *name, - 此函数现已废弃,推荐改用 SPI_cursor_parse_open, + 此函数现已弃用,推荐改用 SPI_cursor_parse_open, 它提供了等价的功能,并使用更现代的查询参数处理 API。 @@ -2249,8 +2244,8 @@ Portal SPI_cursor_open_with_args(const char *name, Oid * argtypes - 一个长度为nargs的数组, - 包含参数的数据类型的OID + 一个长度为 nargs 的数组,包含参数数据类型的 + OID @@ -2259,8 +2254,7 @@ Portal SPI_cursor_open_with_args(const char *name, Datum * values - 一个长度为nargs的数组, - 包含实际的参数值 + 一个长度为 nargs 的数组,包含实际参数值 @@ -2269,20 +2263,19 @@ Portal SPI_cursor_open_with_args(const char *name, const char * nulls - 一个长度为nargs的数组, - 描述哪些参数为空值 + 一个长度为 nargs 的数组,用于描述哪些参数为 + 空值 - 如果nullsNULL, - 那么SPI_cursor_open_with_args会假设没有参数 - 为空值。否则,如果对应的参数值为非空, - nulls - 数组的每一个项都应该是' ';如果对应参数值为空, - nulls数组的项应为'n'(在后 - 面的情况中,对应的values项中的值没有 - 关系)。注意nulls不是一个文本字符串, - 它只是一个数组:它不需要一个'\0'终止符。 + 如果 nullsNULL,则 + SPI_cursor_open_with_args 会假定没有参数为空值。 + 否则,如果对应参数值非空值,则 nulls 数组中 + 的对应项应为 ' ';如果对应参数值为空值,则 + 对应项应为 'n'。(后一种情况下,对应 + values 项中的实际值无关紧要。)注意, + nulls 不是文本字符串,而只是一个数组,因此不 + 需要 '\0' 终止符。 @@ -2419,7 +2412,7 @@ Portal SPI_cursor_open_with_paramlist(const char *name, SPI_cursor_parse_open - 使用查询字符串和参数设置游标 + 使用查询字符串和参数建立游标 @@ -2445,7 +2438,7 @@ Portal SPI_cursor_parse_open(const char *name, 对于一次性查询执行,推荐优先使用此函数,而不是 SPI_prepare_cursorSPI_cursor_open_with_paramlist 的组合。如果同一条命 - 令要用很多不同参数执行,两种方法孰快则取决于重新计划的代价与定制计划带 + 令要用很多不同参数执行,两种方法孰快则取决于重新规划的代价与定制计划带 来的收益之间的权衡。 @@ -2682,7 +2675,7 @@ void SPI_cursor_fetch(Portal portal, bool forw 如果该游标的计划不是用CURSOR_OPT_SCROLL - 选项创建的,向后获取会失败。 + 选项创建的,向后获取可能失败。 @@ -2756,7 +2749,7 @@ void SPI_cursor_move(Portal portal, bool forwa 如果该游标的计划不是用CURSOR_OPT_SCROLL - 选项创建的,向后移动会失败。 + 选项创建的,向后移动可能失败。 @@ -2852,8 +2845,7 @@ void SPI_scroll_cursor_fetch(Portal portal, FetchDirectio 如果该游标的计划不是用CURSOR_OPT_SCROLL - 选项创建的,除FETCH_FORWARD之外的方向值会 - 失败。 + 选项创建的,除FETCH_FORWARD之外的方向值可能失败。 @@ -2950,8 +2942,7 @@ void SPI_scroll_cursor_move(Portal portal, FetchDirection 如果该游标的计划不是用CURSOR_OPT_SCROLL - 选项创建的,除FETCH_FORWARD之外的方向值会 - 失败。 + 选项创建的,除FETCH_FORWARD之外的方向值可能失败。 @@ -3173,8 +3164,8 @@ SPIPlanPtr SPI_saveplan(SPIPlanPtr plan) SPI_register_relation - ephemeral named relation - registering with SPI + 临时命名关系 + 向 SPI 注册 @@ -3198,7 +3189,7 @@ int SPI_register_relation(EphemeralNamedRelation enr) SPI_register_relation 使一个带有相关信息的临时命名关 - 系对通过当前 SPI 连接计划和执行的查询可用。 + 系对通过当前 SPI 连接规划和执行的查询可用。 @@ -3236,7 +3227,7 @@ int SPI_register_relation(EphemeralNamedRelation enr) - 在出错时,会返回下列负值之一: + 出错时,返回以下负值之一: @@ -3278,8 +3269,8 @@ int SPI_register_relation(EphemeralNamedRelation enr) SPI_unregister_relation - ephemeral named relation - unregistering from SPI + 临时命名关系 + 从 SPI 注销 @@ -3326,7 +3317,7 @@ int SPI_unregister_relation(const char * name) 返回值 - 如果该命令的执行成功,则会返回下列(非负)值: + 如果该命令的执行成功,则将返回下列(非负)值: @@ -3341,7 +3332,7 @@ int SPI_unregister_relation(const char * name) - 出现错误时,会返回下列负值之一: + 出错时,返回以下负值之一: @@ -3381,13 +3372,13 @@ int SPI_unregister_relation(const char * name) SPI_register_trigger_data - ephemeral named relation - registering with SPI + 临时命名关系 + 向 SPI 注册 - transition tables - implementation in PLs + 过渡表 + 在 PL 中实现 @@ -3411,8 +3402,8 @@ int SPI_register_trigger_data(TriggerData *tdata) SPI_register_trigger_data 使触发器捕获的所有临时关系 - 都能在通过当前 SPI 连接计划和执行的查询中使用。目前,这指的是通过 - REFERENCING OLD/NEW TABLE AS ... 子句定义、并由 + 都能在通过当前 SPI 连接规划和执行的查询中使用。目前,这指的是由带有 + REFERENCING OLD/NEW TABLE AS ... 子句的 AFTER 触发器捕获的过渡表。PL 触发器处理函数应在建 立 SPI 连接后调用此函数。 @@ -3438,7 +3429,7 @@ int SPI_register_trigger_data(TriggerData *tdata) 返回值 - 如果命令的执行成功,则会返回下列(非负)值: + 如果该命令的执行成功,则将返回下列(非负)值: @@ -3453,7 +3444,7 @@ int SPI_register_trigger_data(TriggerData *tdata) - 出现错误时,会返回下列负值之一: + 出错时,返回以下负值之一: @@ -3710,7 +3701,7 @@ char * SPI_getvalue(HeapTuple row, TupleDesc r 返回值 - 列值;如果该列为 NULL、colnumber 超出范围 + 列值;如果该列为空值、colnumber 超出范围 (SPI_result 被设置为 SPI_ERROR_NOATTRIBUTE)或者没有输出函数 可用(SPI_result 被设置为 @@ -3802,8 +3793,8 @@ Datum SPI_getbinval(HeapTuple row, TupleDesc r 返回值 - 返回该列的二进制值。如果该列为 NULL,则 - isnull 指向的变量会被设为 true,否则设为 false。 + 返回该列的二进制值。如果该列为空值,则 + isnull 指向的变量会被设为真,否则设为假。 @@ -3839,7 +3830,7 @@ char * SPI_gettype(TupleDesc rowdesc, int coln SPI_gettype返回该指定列的数据类型名称 - 的拷贝(当你不再需要该拷贝后,可以使用pfree + 的副本(当你不再需要该副本后,可以使用pfree 释放它)。 @@ -3971,7 +3962,7 @@ char * SPI_getrelname(Relation rel) SPI_getrelname返回该指定关系的名称 - 的拷贝(当你不再需要该拷贝后,可以使用pfree + 的副本(当你不再需要该副本后,可以使用pfree 释放它)。 @@ -4064,7 +4055,7 @@ char * SPI_getnspname(Relation rel) SPI_result_code_string - 将结果代码表示为字符串 + 返回错误码的字符串表示 @@ -4078,7 +4069,7 @@ const char * SPI_result_code_string(int code); SPI_result_code_string 返回各种 SPI 函数返回的,或 - 存放在 SPI_result 中的结果代码的字符串表示。 + 存放在 SPI_result 中的结果码的字符串表示。 @@ -4090,7 +4081,7 @@ const char * SPI_result_code_string(int code); int code - 结果代码 + 结果码 @@ -4101,7 +4092,7 @@ const char * SPI_result_code_string(int code); 返回值 - 结果代码的字符串表示。 + 结果码的字符串表示。 @@ -4113,8 +4104,8 @@ const char * SPI_result_code_string(int code); - memory context - in SPI + 内存上下文 + 在 SPI 中 PostgreSQL内存上下文 中分配内存。内存上下文为管理那些在许多不同位置创建、且生命周期各不相同 @@ -4139,7 +4130,7 @@ const char * SPI_result_code_string(int code); 办法是用 SPI_palloc 为返回对象分配内存。 SPI_palloc上层执行器上下文中分配 内存,也就是调用 SPI_connect 时的当前内存上下文; - 这正是从 C 函数返回值最合适的上下文。本节介绍的其他几个实用函数同样会返 + 这正是从 C 函数返回值最合适的上下文。本节介绍的其他几个辅助函数同样会返 回在上层执行器上下文中创建的对象。 @@ -4147,7 +4138,7 @@ const char * SPI_result_code_string(int code); 调用 SPI_connect 时,会把该 C 函数的私有上下文 (由 SPI_connect 创建)设为当前上下文。所有通过 pallocrepalloc 或 SPI - 实用函数分配的内存(本节另有说明的除外)都位于这个上下文中。当 C 函数通 + 辅助函数分配的内存(本节另有说明的除外)都位于这个上下文中。当 C 函数通 过 SPI_finish 与 SPI 管理器断开连接时,当前上下文 会恢复为上层执行器上下文,而在该 C 函数内存上下文中分配的所有内存都会被 释放,之后就不能再使用。 @@ -4342,7 +4333,7 @@ void SPI_pfree(void * pointer) SPI_copytuple - 在上层执行器上下文中创建一行的拷贝 + 在上层执行器上下文中创建一行的副本 @@ -4375,7 +4366,7 @@ HeapTuple SPI_copytuple(HeapTuple row) HeapTuple row - 要拷贝的行 + 要复制的行 @@ -4386,7 +4377,7 @@ HeapTuple SPI_copytuple(HeapTuple row) 返回值 - 拷贝后的行;出错时返回 NULL + 复制后的行;出错时返回 NULL (错误指示见 SPI_result @@ -4442,7 +4433,7 @@ HeapTupleHeader SPI_returntuple(HeapTuple row, TupleDesc HeapTuple row - 要拷贝的行 + 要复制的行 @@ -4451,7 +4442,7 @@ HeapTupleHeader SPI_returntuple(HeapTuple row, TupleDesc TupleDesc rowdesc - 行描述符(若要获得最佳缓存效果,大多数情况下应每次都传入同一个描述符) + 行描述符(若要获得最佳缓存效果,每次都传入同一个描述符) @@ -4462,7 +4453,7 @@ HeapTupleHeader SPI_returntuple(HeapTuple row, TupleDesc 返回值 - 指向拷贝后行的 HeapTupleHeader;出错时返回 + 指向复制后行的 HeapTupleHeader;出错时返回 NULL(错误指示见 SPI_result @@ -4564,13 +4555,14 @@ HeapTuple SPI_modifytuple(Relation rel, HeapTuple - 如果nullsNULL,那么 - SPI_modifytuple假定没有新值为空值。否则, - 如果对应的新值为非空,nulls数组的每一项都应 - 该是' ',而如果对应的新值为空值则为'n'(在 - 后一种情况中,对应的values项中的新值无关紧 - 要)。注意nulls不是一个文本字符串,只是一个 - 数组:它不需要一个'\0'终止符。 + 如果 nullsNULL,则 + SPI_modifytuple 会假定没有新值为空值。 + 否则,如果对应新值非空值,则 nulls 数组中 + 的对应项应为 ' ';如果对应新值为空值,则 + 对应项应为 'n'。(后一种情况下,对应 + values 项中的实际值无关紧要。)注意, + nulls 不是文本字符串,而只是一个数组,因此不 + 需要 '\0' 终止符。 @@ -4649,7 +4641,7 @@ void SPI_freetuple(HeapTuple row) SPI_freetuple释放之前在上层执行器上下文中 - 分配的一个行。 + 分配的一行。 @@ -4947,7 +4939,7 @@ void SPI_start_transaction(void) - 数据改变的可见性 + 数据更改的可见性 下列规则决定了使用 SPI 的函数(以及其他任何 C 函数)中数据更改的可见 diff --git a/zh/14/stylesheet-speedup-common.xsl b/zh/14/stylesheet-speedup-common.xsl index e3fb582a..403f350c 100644 --- a/zh/14/stylesheet-speedup-common.xsl +++ b/zh/14/stylesheet-speedup-common.xsl @@ -95,6 +95,6 @@ -en +zh_cn diff --git a/zh/14/syntax.sgml b/zh/14/syntax.sgml index b60a341f..45befa44 100644 --- a/zh/14/syntax.sgml +++ b/zh/14/syntax.sgml @@ -21,7 +21,7 @@ 词法结构 - token + 词元 @@ -29,7 +29,7 @@ - 一个词元可以是关键词标识符带引号的标识符文字值(或常量),或者特殊字符符号。词元通常由空白(空格、制表符、换行)分隔,但如果不存在歧义,则不必如此(一般只有特殊字符与其他类型的词元相邻时才会这样)。 + 一个词元可以是关键词标识符带引号的标识符字面量(或常量),或者特殊字符符号。词元通常由空白(空格、制表符、换行)分隔,但如果不存在歧义,则不必如此(一般只有特殊字符与其他类型的词元相邻时才会这样)。 @@ -58,18 +58,18 @@ INSERT INTO MY_TABLE VALUES (3, 'hi there'); 标识符和关键词 - identifier - syntax of + 标识符 + 语法 - name - syntax of + 名称 + 语法 - key word - syntax of + 关键词 + 语法 @@ -83,7 +83,7 @@ INSERT INTO MY_TABLE VALUES (3, 'hi there'); - identifierlength + 标识符长度 系统对标识符最多只使用 NAMEDATALEN-1 个字节;在命令中可以写更长的名称,但它们会被截断。默认情况下, NAMEDATALEN 为 64,因此标识符的最大长度是 63 字节。如果这个限制有问题,可以通过修改 src/include/pg_config_manual.h 中的 NAMEDATALEN 常量来提高。 @@ -91,8 +91,8 @@ INSERT INTO MY_TABLE VALUES (3, 'hi there'); - case sensitivity - of SQL commands + 大小写敏感性 + SQL 命令 关键词和未加引号的标识符不区分大小写。因此: @@ -110,8 +110,8 @@ UPDATE my_table SET a = 5; - quotation marks - and identifiers + 引号 + 与标识符 还有第二类标识符:定界标识符带引号的标识符。它通过把任意字符序列括在双引号中形成(")。 定界标识符始终是标识符,绝不会是关键词。因此,"select" 可以用来引用名为 select 的列或表,而不加引号的 select 会被视为关键词,因此在期望表名或列名的位置使用时会导致解析错误。这个示例可以用带引号的标识符写成: @@ -133,7 +133,7 @@ UPDATE "my_table" SET "a" = 5; Unicode 转义 - in identifiers + 在标识符中 @@ -172,12 +172,11 @@ U&"d!0061t!+000061" UESCAPE '!' - 常量 - constant + 常量 @@ -188,19 +187,15 @@ U&"d!0061t!+000061" UESCAPE '!' 字符串常量 - character string - constant + 字符串 + 常量 - - - quotation marks + + 引号 转义 - SQL 中的字符串常量是由单引号括起的任意字符序列,例如 - 'This is a string'。要在字符串常量中包含单引号字符,请写两个相邻的单引号,例如 - 'Dianne''s horse'。注意,这与双引号字符("不同 - + SQL 中的字符串常量是由单引号(')括起的任意字符序列,例如 'This is a string'。要在字符串常量中包含单引号字符,请写两个相邻的单引号,例如 'Dianne''s horse'。注意,这不同于双引号字符(")。 两个只由空白及至少一个新行分隔的字符串常量会被连接在一起,并且将作为一个写在一起的字符串常量来对待。例如: @@ -304,7 +299,7 @@ SELECT 'foo' 'bar'; - 如果配置参数off,那么PostgreSQL对常规字符串常量和转义字符串常量中的反斜线转义都识别。不过,从PostgreSQL 9.1 开始,该参数的默认值为on,意味着只在转义字符串常量中识别反斜线转义。这种行为更兼容标准,但是可能打断依赖于历史行为(反斜线转义总是会被识别)的应用。作为一种变通,你可以设置该参数为off,但是最好迁移到符合新的行为。如果你需要使用一个反斜线转义来表示一个特殊字符,为该字符串常量写上一个E。 + 如果配置参数off,那么PostgreSQL对常规字符串常量和转义字符串常量中的反斜线转义都识别。不过,从PostgreSQL 9.1 开始,该参数的默认值为on,意味着只在转义字符串常量中识别反斜线转义。这种行为更兼容标准,但是可能使依赖历史行为(始终识别反斜线转义)的应用无法正常工作。作为一种变通,你可以设置该参数为off,但最好修改应用,不再使用反斜线转义。如果你需要使用一个反斜线转义来表示一个特殊字符,为该字符串常量写上一个E @@ -322,7 +317,7 @@ SELECT 'foo' 'bar'; Unicode 转义 - in string constants + 在字符串常量中 @@ -368,7 +363,7 @@ U&'d!0061t!+000061' UESCAPE '!' 美元引用的字符串常量 - dollar quoting + 美元引用 @@ -411,8 +406,8 @@ $function$ 位串常量 - bit string - constant + 位串 + 常量 @@ -432,8 +427,8 @@ $function$ 数字常量 - number - constant + 数字 + 常量 @@ -447,7 +442,7 @@ $function$ 其中 digits 是一个或多个十进制数字(0 到 9)。 若使用小数点,则小数点前后至少有一侧必须有数字。若使用指数标记 (e),其后至少必须有一位数字。常量中不能嵌入空格或 - 其他字符,但可按下文所述使用下划线进行视觉分组。请注意,前导正号或负号 + 其他字符。请注意,前导正号或负号 实际上不属于常量本身,而是作用于常量的操作符。 @@ -463,45 +458,6 @@ $function$ - - 此外,还支持以下形式的非十进制整型常量: - -0xhexdigits -0ooctdigits -0bbindigits - - 其中 hexdigits 为一个或多个十六进制数字 - (0-9、A-F),octdigits 为一个或多个八进制数字 - (0-7),bindigits 为一个或多个二进制数字 - (0 或 1)。十六进制数字与基数前缀均可使用大小写。请注意,只有整数 - 可以使用非十进制形式,带小数部分的数字不可以。 - - - - 下面是一些合法的非十进制整型常量示例: - -0b100101 -0B10011001 -0o273 -0O755 -0x42f -0XFFFF - - - - - 为了便于视觉分组,可在数字之间插入下划线。下划线不会影响常量的值。例如: - -1_500_000_000 -0b10001000_00000000 -0o_1_755 -0xFFFF_FFFF -1.618_034 - - 下划线不能出现在数字常量或数字分组的开头或结尾(即不能紧邻小数点或指数标记的 - 前后),也不允许连续出现多个下划线。 - - integer bigint @@ -510,12 +466,12 @@ $function$ - 为数字常量最初指定的数据类型,只是类型解析算法的起点。在大多数情况下,常量会根据上下文被自动强制转换成最合适的类型。必要时,你可以通过类型转换强制把一个数值解释为特定的数据类型。type cast + 为数字常量最初指定的数据类型,只是类型解析算法的起点。在大多数情况下,常量会根据上下文被自动强制转换成最合适的类型。必要时,你可以通过类型转换强制把一个数值解释为特定的数据类型。类型转换 例如,可以通过下面的写法强制把一个数值当作类型 realfloat4)处理: -REAL '1.23' -- string style -1.23::REAL -- PostgreSQL (historical) style +REAL '1.23' -- 字符串形式 +1.23::REAL -- PostgreSQL(历史)形式 这些实际上只是下面将要讨论的一般类型转换记法的特例。 @@ -526,8 +482,8 @@ REAL '1.23' -- string style 其他类型的常量 - data type - constant + 数据类型 + 常量 @@ -553,7 +509,7 @@ CAST ( 'string' AS type ) - 如中所述,::CAST() 以及函数调用语法也可以用来指定任意表达式的运行时类型转换。为避免语法歧义,type 'string' 语法只能用来指定简单字面常量的类型。该语法的另一个限制是不能用于数组类型;要指定数组常量的类型,请使用 ::CAST()。 + 如中所述,::CAST() 以及函数调用语法也可以用来指定任意表达式的运行时类型转换。为避免语法歧义,type 'string' 语法只能用来指定简单字面常量的类型。type 'string' 语法的另一个限制是不能用于数组类型;要指定数组常量的类型,请使用 ::CAST() @@ -566,8 +522,8 @@ CAST ( 'string' AS type ) 操作符 - operator - syntax + 操作符 + 语法 @@ -617,7 +573,7 @@ CAST ( 'string' AS type ) - 圆括号(())具有它们通常的含义,用来分组表达式并且强制优先。在某些情况中,圆括号被要求作为一个特定 SQL 命令的固定语法的一部分。 + 圆括号(())具有它们通常的含义,用来对表达式分组并确定运算优先级。在某些情况中,圆括号被要求作为一个特定 SQL 命令的固定语法的一部分。 @@ -635,7 +591,7 @@ CAST ( 'string' AS type ) - 分号(;)结束一个 SQL 命令。它不能出现在一个命令中间的任何位置,除了在一个字符串常量中或者一个被引用的标识符中。 + 分号(;)结束一个 SQL 命令。它不能出现在一个命令中间的任何位置,除了在一个字符串常量中或者一个带引号的标识符中。 @@ -647,7 +603,7 @@ CAST ( 'string' AS type ) - 星号(*)在某些上下文中用来表示表行或组合值的所有字段。当它被用作聚合函数的参数时,还有一种特殊含义,即该聚合不需要任何显式参数。 + 星号(*)在某些上下文中用来表示表行或复合值的所有字段。当它被用作聚合函数的参数时,还有一种特殊含义,即该聚合不需要任何显式参数。 @@ -665,22 +621,22 @@ CAST ( 'string' AS type ) 注释 - comment - in SQL + 注释 + 在 SQL 中 注释是一串以双连字符开始并延伸到行尾的字符,例如: --- This is a standard SQL comment +-- 这是一条标准 SQL 注释 另外,也可以使用 C 风格注释块: -/* multiline comment - * with nesting: /* nested block comment */ +/* 多行注释 + * 包含嵌套:/* 嵌套块注释 */ */ 这里该注释开始于/*并且延伸到匹配出现的*/。这些注释块可按照 SQL 标准中指定的方式嵌套,但和 C 中不同。这样我们可以注释掉一大段可能包含注释块的代码。 @@ -695,8 +651,8 @@ CAST ( 'string' AS type ) 操作符优先级 - operator - precedence + 操作符 + 优先级 @@ -740,7 +696,7 @@ CAST ( 'string' AS type ) + - - 一元加、一元减 + 一元正号、一元负号 @@ -752,19 +708,19 @@ CAST ( 'string' AS type ) AT - AT TIME ZONE, AT LOCAL + AT TIME ZONE ^ - 指数 + 求幂 * / % - 乘、除、模 + 乘、除、取模 @@ -776,7 +732,7 @@ CAST ( 'string' AS type ) (任意其他操作符) - 所有其他本地以及用户定义的操作符 + 所有其他内置以及用户定义的操作符 @@ -833,18 +789,7 @@ SELECT 3 OPERATOR(pg_catalog.+) 4; - - 版本 9.5 之前的PostgreSQL使用的操作符优先级 - 规则略有不同。特别是,<=>= - 和<>习惯于被当作普通操作符,IS - 测试习惯于具有较高的优先级。并且在一些认为NOT比 - BETWEEN优先级高的情况下,NOT BETWEEN - 和相关的结构的行为不一致。为了更好地兼容 SQL 标准并且减少对 - 逻辑上等价的结构不一致的处理,这些规则也得到了修改。在大部分情况下, - 这些变化不会导致行为上的变化,或者可能会产生no such operator - 错误,但可以通过增加圆括号解决。不过在一些极端情况中,查询可能在 - 没有被报告解析错误的情况下发生行为的改变。 - + PostgreSQL 9.5 之前的版本使用的操作符优先级规则略有不同。特别是,<=>=<> 过去被当作普通操作符;IS 测试过去具有较高的优先级;而 NOT BETWEEN 和相关结构的处理不一致,在某些情况下被认为具有 NOT 而不是 BETWEEN 的优先级。为了更好地符合 SQL 标准,并减少对逻辑等价结构的不一致处理造成的困惑,这些规则得到了修改。在大部分情况下,这些变化不会导致行为变化,或者可能会产生 no such operator 错误,但可以通过增加圆括号解决。不过在一些极端情况下,查询可能在没有报告任何解析错误的情况下改变行为。 @@ -1537,7 +1482,7 @@ SELECT * FROM tbl WHERE a COLLATE "C" > 'foo'; SELECT * FROM tbl WHERE (a > 'foo') COLLATE "C"; - 因为它尝试把一个排序规则应用到>操作符的结果,而它的数据类型是非可排序数据类型boolean。 + 因为它尝试把一个排序规则应用到>操作符的结果,而它的数据类型是不支持排序规则的数据类型boolean。 diff --git a/zh/14/textsearch.sgml b/zh/14/textsearch.sgml index a28d1544..51eea368 100644 --- a/zh/14/textsearch.sgml +++ b/zh/14/textsearch.sgml @@ -2099,7 +2099,7 @@ ALTER TEXT SEARCH CONFIGURATION russian 分类词典示例 - 考虑简单的天文词库 thesaurus_astro,其中包含一些天文单词组合: + 考虑简单的天文词库 thesaurus_astro,其中包含一些天文单词组合: supernovae stars : sn @@ -2534,7 +2534,7 @@ ts_debug( config re - 以下是一个简单的示例: + 以下是一个简单的示例: SELECT * FROM ts_debug('english', 'a fat cat sat on a mat - it ate a fat rats'); diff --git a/zh/14/trigger.sgml b/zh/14/trigger.sgml index 2866fff3..28e79389 100644 --- a/zh/14/trigger.sgml +++ b/zh/14/trigger.sgml @@ -4,7 +4,7 @@ 触发器 - trigger + 触发器 @@ -73,38 +73,15 @@ 如果触发器被定义为 约束触发器,则 AFTER 触发器的执行可被推迟到事务末尾,而不是语句末尾。 - 无论哪种情况,触发器都作为触发它的语句所属同一事务的一部分执行,因此只要语句或触发器任一方发生错误,二者的效果都会回滚。此外,触发器总是以将该触发事件排入队列的角色身份运行,除非触发器函数标记为 - SECURITY DEFINER,那样的话则以函数所有者身份运行。 - - - - 若 INSERT 包含 ON CONFLICT DO UPDATE - 子句,则被触发的行上可能先执行行级 - BEFORE INSERT 触发器,再执行 - BEFORE UPDATE 触发器。若触发器不是 - 幂等的,这种交互可能很复杂,因为 BEFORE - INSERT 触发器所做更改会被 - BEFORE UPDATE 触发器看到, - 包括对 EXCLUDED 列的更改。 - - - - 注意,当指定 ON CONFLICT DO UPDATE 时,语句级 - UPDATE 触发器会执行,不管 - UPDATE 是否实际影响了行(也不管是否走到了 - UPDATE 分支)。带有 - ON CONFLICT DO UPDATEINSERT - 会先执行语句级 BEFORE INSERT - 触发器,再执行语句级 BEFORE UPDATE - 触发器,然后执行语句级 AFTER UPDATE - 触发器,最后执行语句级 AFTER INSERT - 触发器。 + 无论哪种情况,触发器都作为触发它的语句所属同一事务的一部分执行,因此只要语句或触发器任一方发生错误,二者的效果都会回滚。 如果某条语句以继承层次或分区层次中的父表为目标,它不会导致受影响子表上的语句级触发器触发;只有父表上的语句级触发器会触发。不过,任何受影响子表上的行级触发器仍会触发。 + INSERT 包含 ON CONFLICT DO UPDATE 子句,则行级 BEFORE INSERT 触发器和行级 BEFORE UPDATE 触发器的效果可能都会体现在更新后行的最终状态中,前提是引用了 EXCLUDED 列。不过,即使没有引用 EXCLUDED 列,这两组行级 BEFORE 触发器也可能都会执行。如果同时存在会更改正在插入/更新的行的 BEFORE INSERTBEFORE UPDATE 行级触发器,就应考虑可能出现令人意外的结果(即使它们的修改大致等效,如果不具有幂等性,也可能出现问题)。注意,语句级 UPDATE 触发器会在指定 ON CONFLICT DO UPDATE 时执行,不管 UPDATE 是否实际影响了行(也不管是否走到了 UPDATE 分支)。INSERT 如果带有 ON CONFLICT DO UPDATE 子句,会先执行语句级 BEFORE INSERT 触发器,再执行语句级 BEFORE UPDATE 触发器,然后执行语句级 AFTER UPDATE 触发器,最后执行语句级 AFTER INSERT 触发器。 + 如果对分区表执行 UPDATE 导致某行移动到另一个分区,这将表现为从原始分区执行一次 DELETE,然后向新分区执行一次 INSERT。在这种情况下,原始分区上的所有行级 BEFORE UPDATE 触发器和所有行级 @@ -157,18 +134,18 @@ 生成列还有一些额外注意事项。 - generated column在触发器中 + 生成列在触发器中 存储型生成列会在 BEFORE 触发器之后、AFTER 触发器之前计算。因此,可以在 AFTER 触发器中检查生成值。在 BEFORE 触发器中,OLD 行如预期那样包含旧的 生成值,但 NEW 行尚未包含新的生成值,因此不应访问。对于 C 语言接口,此时该列内容未定义;更高层编程语言应阻止在 BEFORE 触发器中访问 NEW 行中的存储型 - 生成列。在 BEFORE 触发器中对生成列值所做的修改会被忽略并随后被覆盖。虚拟生成列在触发器触发时永远不会被计算。在 C 语言接口中,它们在触发器函数中的内容是未定义的;更高层编程语言应阻止在触发器中访问虚拟生成列。 + 生成列。在 BEFORE 触发器中对生成列值所做的修改会被忽略并随后被覆盖。 - 如果在同一关系上的同一事件为其定义了多个触发器,它们会按触发器名称的字母顺序触发。对于 BEFOREINSTEAD OF + 如果为同一关系上的同一事件定义了多个触发器,它们会按触发器名称的字母顺序触发。对于 BEFOREINSTEAD OF 触发器,每个触发器返回的、可能已经被修改过的行都会成为下一个触发器的输入。如果任何一个 BEFOREINSTEAD OF 触发器返回 NULL,则会放弃对该行执行该操作,并且后续触发器(针对该行)都不会再触发。 @@ -178,7 +155,7 @@ 条件,不过这个特性对它们用处不大。)在 BEFORE 触发器中, WHEN 条件就在函数即将执行或本会执行之前求值,因此使用 WHEN 与在触发器函数开头测试同样的条件并无实质差别。不过,在 - AFTER 触发器中,WHEN 条件会在行更改发生后立即求值,并决定是否要在语句末尾将一个事件排入队列以触发该触发器。因此,当 AFTER 触发器的 WHEN + AFTER 触发器中,WHEN 条件会在行更改发生后立即求值,并决定是否要将一个事件排入队列,以便在语句末尾触发该触发器。因此,当 AFTER 触发器的 WHEN 条件不返回真时,就不必排队该事件,也不必在语句末尾重新取出该行。如果触发器只需要针对少数几行触发,这会让修改大量行的语句显著加快。 INSTEAD OF 触发器不支持 WHEN 条件。 @@ -195,17 +172,10 @@ 如果触发器函数执行 SQL 命令,那么这些命令可能会再次触发触发器。这就是所谓的级联触发器。对级联层数没有直接限制。级联还有可能导致同一个触发器被递归调用;例如,一个 INSERT 触发器可能执行一条向同一个表再插入一行的命令,从而导致该 INSERT 触发器再次触发。因此,在这种场景下,避免无限递归是触发器编写者自己的责任。 - - 若外键约束指定了引用动作(即级联更新或级联删除),这些动作会通过在引用表上执行 - 普通 SQL UPDATEDELETE 命令完成。 - 特别地,引用表上存在的触发器会因这些更改而触发。若此类触发器修改或阻止了这些 - 命令之一的效果,最终可能破坏引用完整性。避免这种情况是触发器编写者的责任。 - - - trigger - arguments for trigger functions + 触发器 + 触发器函数的参数 在定义触发器时,可以为它指定参数。在触发器定义中包含参数,是为了让需求相似的不同触发器能够调用同一个函数。举例来说,可以有一个通用触发器函数,它接受两个列名作为参数,把当前用户写入其中一个列,把当前时间戳写入另一个列。只要编写得当,这个触发器函数就应独立于它所作用的具体表。因此,同一个函数可用于任何具有适当列的表上的 INSERT 事件,例如自动跟踪某个事务表中记录的创建。如果把它定义成 UPDATE 触发器,还可以用来跟踪最近更新事件。 @@ -288,13 +258,13 @@ 用 C 编写触发器函数 - trigger - in C + 触发器 + 在 C 中 - transition tables - referencing from C trigger + 过渡表 + 从 C 触发器中引用 @@ -306,7 +276,7 @@ - 当函数由触发器管理器调用时,不会向它传递任何普通参数,但会传递一个指向 TriggerData 结构体的 context 指针。C 函数可以通过执行下列宏来检查自己是否由触发器管理器调用: + 当函数由触发器管理器调用时,不会向它传递任何普通参数,但会传递一个指向 TriggerData 结构体的 上下文 指针。C 函数可以通过执行下列宏来检查自己是否由触发器管理器调用: CALLED_AS_TRIGGER(fcinfo) @@ -365,7 +335,7 @@ typedef struct TriggerData TRIGGER_FIRED_BEFORE(tg_event) - 如果触发器在操作之前触发,则返回 true。 + 如果触发器在操作之前触发,则返回真。 @@ -374,7 +344,7 @@ typedef struct TriggerData TRIGGER_FIRED_AFTER(tg_event) - 如果触发器在操作之后触发,则返回 true。 + 如果触发器在操作之后触发,则返回真。 @@ -383,7 +353,7 @@ typedef struct TriggerData TRIGGER_FIRED_INSTEAD(tg_event) - 如果触发器是取代该操作而触发,则返回 true。 + 如果触发器是取代该操作而触发,则返回真。 @@ -392,7 +362,7 @@ typedef struct TriggerData TRIGGER_FIRED_FOR_ROW(tg_event) - 如果触发器是因行级事件触发,则返回 true。 + 如果触发器是因行级事件触发,则返回真。 @@ -401,7 +371,7 @@ typedef struct TriggerData TRIGGER_FIRED_FOR_STATEMENT(tg_event) - 如果触发器是因语句级事件触发,则返回 true。 + 如果触发器是因语句级事件触发,则返回真。 @@ -410,7 +380,7 @@ typedef struct TriggerData TRIGGER_FIRED_BY_INSERT(tg_event) - 如果触发器是由 INSERT 命令触发,则返回 true。 + 如果触发器是由 INSERT 命令触发,则返回真。 @@ -419,7 +389,7 @@ typedef struct TriggerData TRIGGER_FIRED_BY_UPDATE(tg_event) - 如果触发器是由 UPDATE 命令触发,则返回 true。 + 如果触发器是由 UPDATE 命令触发,则返回真。 @@ -428,7 +398,7 @@ typedef struct TriggerData TRIGGER_FIRED_BY_DELETE(tg_event) - 如果触发器是由 DELETE 命令触发,则返回 true。 + 如果触发器是由 DELETE 命令触发,则返回真。 @@ -437,7 +407,7 @@ typedef struct TriggerData TRIGGER_FIRED_BY_TRUNCATE(tg_event) - 如果触发器是由 TRUNCATE 命令触发,则返回 true。 + 如果触发器是由 TRUNCATE 命令触发,则返回真。 @@ -596,16 +566,16 @@ typedef struct Trigger - 一个完整的触发器实例 + 一个完整的触发器示例 这里给出一个非常简单的、用 C 编写的触发器函数示例。(用过程语言编写的触发器示例可见各过程语言的文档。) - 如果某条命令试图向列 x 中插入空值,函数 - trigf 就会报告表 ttest - 中的行数,并跳过实际操作。(这样,这个触发器就起到了非空约束的作用,但不会中止事务。) + 函数 trigf 会报告表 ttest 中的行数, + 并在命令试图向列 x 中插入空值时跳过实际操作。 + (这样,这个触发器就起到了非空约束的作用,但不会中止事务。) @@ -664,7 +634,8 @@ trigf(PG_FUNCTION_ARGS) tupdesc = trigdata->tg_relation->rd_att; /* connect to SPI manager */ - SPI_connect(); + if ((ret = SPI_connect()) < 0) + elog(ERROR, "trigf (fired %s): SPI_connect returned %d", when, ret); /* get number of rows in table */ ret = SPI_exec("SELECT count(*) FROM ttest", 0); diff --git a/zh/14/typeconv.sgml b/zh/14/typeconv.sgml index 15e7c27c..984ee0cf 100644 --- a/zh/14/typeconv.sgml +++ b/zh/14/typeconv.sgml @@ -30,7 +30,7 @@ -PostgreSQL扫描器/解析器将词法元素分成五个基本类别:整数、非整数数字、字符串、标识符和关键字。大多数非数值类型的常量会先被归类为字符串。SQL语言定义允许用字符串指定类型名,而PostgreSQL可以利用这一机制让解析器从一开始就沿着正确的路径处理。例如,查询: +PostgreSQL扫描器/解析器将词法元素分成五个基本类别:整数、非整数数字、字符串、标识符和关键字。大多数非数值类型的常量会先被归类为字符串。SQL语言定义允许给字符串指定类型名,而PostgreSQL可以利用这一机制让解析器从一开始就沿着正确的路径处理。例如,查询: SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; @@ -41,7 +41,7 @@ SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; (1 row) -包含两个文字常量,它们的类型分别是textpoint。如果没有为某个字符串文字指定类型,那么它最初会被赋予占位类型unknown,并在后文所述的后续阶段解析。 +包含两个字面量,它们的类型分别是textpoint。如果没有为某个字符串字面量指定类型,那么它最初会被赋予占位类型unknown,并在后文所述的后续阶段解析。 @@ -166,11 +166,11 @@ SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; -检查是否存在一个恰好接受输入参数类型的操作符。如果存在(在被考虑的操作符集合中至多只有一个精确匹配),就使用它。若通过限定名调用(这种情况并不常见)某个允许不可信用户创建对象的模式中的操作符,而又缺少精确匹配,就会带来安全隐患 +检查是否存在一个恰好接受输入参数类型的操作符。如果存在(在被考虑的操作符集合中至多只有一个精确匹配),就使用它。若通过限定名调用(这种情况并不常见)某个允许不受信任的用户创建对象的模式中的操作符,而又缺少精确匹配,就会带来安全隐患 - 对于未带模式限定的名称,不会出现这种隐患,因为包含允许不可信用户创建对象的模式的搜索路径不是一种模式的安全使用方式。 + 对于未带模式限定的名称,不会出现这种隐患,因为包含允许不受信任的用户创建对象的模式的搜索路径不是一种模式的安全使用方式。 。在这种情况下,应通过对参数进行类型转换来强制获得精确匹配。 @@ -186,7 +186,7 @@ SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; -如果二元操作符调用的一个参数是unknown类型,而另一个是域类型,则接着检查是否存在两边都恰好接受该域基类型的操作符;如果有,就使用它。 +如果二元操作符调用的一个参数是unknown类型,而另一个是域类型,则接着检查是否存在两边都恰好接受该域基础类型的操作符;如果有,就使用它。 @@ -201,13 +201,13 @@ SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; -丢弃那些输入类型不匹配,且也无法通过隐式类型转换实现匹配的候选操作符。为此,假定unknown文字可以转换为任何类型。如果只剩一个候选操作符,就使用它;否则继续下一步。 +丢弃那些输入类型不匹配,且也无法通过隐式类型转换实现匹配的候选操作符。为此,假定unknown字面量可以转换为任何类型。如果只剩一个候选操作符,就使用它;否则继续下一步。 -如果任何输入参数是域类型,则在后续所有步骤中都把它当作该域的基类型。这样可以确保在解决操作符歧义时,域的行为与其基类型一致。 +如果任何输入参数是域类型,则在后续所有步骤中都把它当作该域的基础类型。这样可以确保在解决操作符歧义时,域的行为与其基础类型一致。 @@ -219,13 +219,13 @@ SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; -遍历所有候选操作符,保留那些在需要类型转换的最多位置上接受首选类型(属于输入数据类型的类型分类)的候选项。如果没有候选项接受首选类型,则保留全部候选项。如果只剩一个候选操作符,就使用它;否则继续下一步。 +遍历所有候选操作符,在需要类型转换的位置上,保留接受首选类型(属于输入数据类型的类型分类)的位置数最多的候选项。如果没有候选项接受首选类型,则保留全部候选项。如果只剩一个候选操作符,就使用它;否则继续下一步。 -如果有任何输入参数是unknown,就检查剩余候选操作符在这些参数位置上接受哪些类型分类。在每个位置上,如果有任何候选项接受string分类,就选择该分类。(这种偏向字符串的做法是合适的,因为unknown类型的文字看起来像字符串。)否则,如果所有剩余候选项都接受同一种类型分类,就选择该分类;否则失败,因为在缺少更多线索的情况下无法推断出正确选择。然后丢弃不接受所选类型分类的候选项。此外,如果有任何候选项接受该分类中的首选类型,就丢弃在该参数上接受非首选类型的候选项。如果没有候选项通过这些测试,则保留全部候选项。如果只剩一个候选操作符,就使用它;否则继续下一步。 +如果有任何输入参数是unknown,就检查剩余候选操作符在这些参数位置上接受哪些类型分类。在每个位置上,如果有任何候选项接受string分类,就选择该分类。(这种偏向字符串的做法是合适的,因为unknown类型的字面量看起来像字符串。)否则,如果所有剩余候选项都接受同一种类型分类,就选择该分类;否则失败,因为在缺少更多线索的情况下无法推断出正确选择。然后丢弃不接受所选类型分类的候选项。此外,如果有任何候选项接受该分类中的首选类型,就丢弃在该参数上接受非首选类型的候选项。如果没有候选项通过这些测试,则保留全部候选项。如果只剩一个候选操作符,就使用它;否则继续下一步。 @@ -273,7 +273,7 @@ SELECT |/ CAST(40 AS double precision) AS "square root of 40"; -一个只有一个未指定参数的例子: +一个参数未指定类型的例子: SELECT text 'abc' || 'def' AS "text and unknown"; @@ -301,7 +301,7 @@ SELECT 'abc' || 'def' AS "unspecified"; -这里对使用哪种类型没有初始提示,因为查询中没有指定任何类型。因此,解析器会查找所有候选操作符,并发现既有接受字符串分类输入的候选项,也有接受位串分类输入的候选项。由于在可用时优先选择字符串分类,所以会选中该分类,再使用字符串的首选类型text作为解析这些unknown类型文字的具体类型。 +这里对使用哪种类型没有初始提示,因为查询中没有指定任何类型。因此,解析器会查找所有候选操作符,并发现既有接受字符串分类输入的候选项,也有接受位串分类输入的候选项。由于在可用时优先选择字符串分类,所以会选中该分类,再使用字符串的首选类型text作为解析这些unknown类型字面量的具体类型。 @@ -318,7 +318,7 @@ SELECT @ '-4.5' AS "abs"; 4.5 (1 row) -这里,系统在应用所选操作符之前,已经把unknown类型文字隐式解析为float8。我们可以验证使用的确实是float8,而不是其他类型: +这里,系统在应用所选操作符之前,已经把unknown类型字面量隐式解析为float8。我们可以验证使用的确实是float8,而不是其他类型: SELECT @ '-4.5e500' AS "abs"; @@ -352,7 +352,7 @@ SELECT ~ CAST('20' AS int8) AS "negation"; 数组包含操作符类型解析 -下面是另一个解析一边已知、一边未知输入的操作符的例子: +下面是另一个解析带有一个已知类型输入和一个未知类型输入的操作符的例子: SELECT array[1,2] <@ '{1,2,3}' as "is subset"; @@ -361,7 +361,7 @@ SELECT array[1,2] <@ '{1,2,3}' as "is subset"; t (1 row) -PostgreSQL操作符目录中为中缀操作符<@定义了多个条目,但左侧能够接受整数数组的只有两种:数组包含(anyarray <@ anyarray)和范围包含(anyelement <@ anyrange)。由于这些多态伪类型(见)都不被视为首选类型,解析器无法据此消除歧义。不过,告诉它可以假定unknown类型文字与另一输入具有相同类型,也就是整数数组。这样两个操作符中只有一个能够匹配,因此会选择数组包含。(如果选中范围包含,就会报错,因为该字符串的格式并不是合法的范围文字。) +PostgreSQL操作符目录中为中缀操作符<@定义了多个条目,但左侧能够接受整数数组的只有两种:数组包含(anyarray <@ anyarray)和范围包含(anyelement <@ anyrange)。由于这些多态伪类型(见)都不被视为首选类型,解析器无法据此消除歧义。不过,要求它假定unknown类型字面量与另一输入具有相同类型,也就是整数数组。这样两个操作符中只有一个能够匹配,因此会选择数组包含。(如果选中范围包含,就会报错,因为该字符串的格式并不是合法的范围字面量。) @@ -370,7 +370,7 @@ SELECT array[1,2] <@ '{1,2,3}' as "is subset"; 域类型上的自定义操作符 -用户有时会尝试声明只适用于某个域类型的操作符。这是可行的,但远没有看上去那样有用,因为操作符解析规则被设计成优先选择作用于域基类型的操作符。考虑下面的例子: +用户有时会尝试声明只适用于某个域类型的操作符。这是可行的,但远没有看上去那样有用,因为操作符解析规则被设计成优先选择作用于域基础类型的操作符。考虑下面的例子: CREATE DOMAIN mytext AS text CHECK(...); CREATE FUNCTION mytext_eq_text (mytext, text) RETURNS boolean AS ...; @@ -379,11 +379,11 @@ CREATE TABLE mytable (val mytext); SELECT * FROM mytable WHERE val = 'foo'; -这个查询不会使用自定义操作符。解析器首先会检查是否存在mytext = mytext操作符(),但并不存在;然后它会考虑该域的基类型text,并检查是否存在text = text操作符(),而这是存在的;于是它会把unknown类型的文字解析为text,并使用text = text操作符。要让自定义操作符被使用,唯一的方法是显式地对该文字做类型转换: +这个查询不会使用自定义操作符。解析器首先会检查是否存在mytext = mytext操作符(),但并不存在;然后它会考虑该域的基础类型text,并检查是否存在text = text操作符(),而这是存在的;于是它会把unknown类型的字面量解析为text,并使用text = text操作符。要让自定义操作符被使用,唯一的方法是显式地对该字面量做类型转换: SELECT * FROM mytable WHERE val = text 'foo'; -这样就会根据精确匹配规则立即找到mytext = text操作符。如果解析过程进入最佳匹配规则,它们会主动排斥作用于域类型的操作符。如果不是这样,这类操作符会导致过多的操作符歧义失败,因为类型转换规则总是把域视为可以转换到其基类型或从其基类型转换而来,因此域操作符会在所有与基类型上同名操作符相同的场景中都被视为可用。 +这样就会根据精确匹配规则立即找到mytext = text操作符。如果解析过程进入最佳匹配规则,它们会主动排斥作用于域类型的操作符。如果不是这样,这类操作符会导致过多的操作符歧义失败,因为类型转换规则总是把域视为可以转换到其基础类型或从其基础类型转换而来,因此域操作符会在所有与基础类型上同名操作符相同的场景中都被视为可用。 @@ -422,27 +422,27 @@ SELECT * FROM mytable WHERE val = text 'foo'; -如果函数声明了一个VARIADIC数组参数,而调用时没有使用VARIADIC关键字,则把该函数视为其数组参数按需要被其元素类型的一个或多个出现所替换,以匹配该调用。扩展之后,该函数的有效参数类型可能与某个非VARIADIC函数完全相同。在这种情况下,使用搜索路径中较早出现的函数;如果两个函数位于同一模式,则优先选择非VARIADIC函数。 +如果函数声明了一个VARIADIC数组参数,而调用时没有使用VARIADIC关键字,则把数组参数视为一个或多个其元素类型的参数,个数按匹配该调用的需要确定。扩展之后,该函数的有效参数类型可能与某个非VARIADIC函数完全相同。在这种情况下,使用搜索路径中较早出现的函数;如果两个函数位于同一模式,则优先选择非VARIADIC函数。 -通过限定名调用某个允许不可信用户创建对象的模式中找到的可变参数函数时,会带来安全隐患 +通过限定名调用某个允许不受信任的用户创建对象的模式中找到的可变参数函数时,会带来安全隐患 - 对于未带模式限定的名称,不会出现这种隐患,因为包含允许不可信用户创建对象的模式的搜索路径不是一种模式的安全使用方式。 + 对于未带模式限定的名称,不会出现这种隐患,因为包含允许不受信任的用户创建对象的模式的搜索路径不是一种模式的安全使用方式。 - 。恶意用户可以借此劫持调用,并以你的身份执行任意 SQL 函数。改为使用带有VARIADIC关键字的调用可以绕过这一隐患。对于填充VARIADIC "any"参数的调用,往往没有包含VARIADIC关键字的等价写法。要安全地发出这类调用,该函数所在模式必须只允许可信用户创建对象。 + 。恶意用户可以借此劫持调用,并以你的身份执行任意 SQL 函数。改为使用带有VARIADIC关键字的调用可以绕过这一隐患。对于填充VARIADIC "any"参数的调用,往往没有包含VARIADIC关键字的等价写法。要安全地发出这类调用,该函数所在模式必须只允许受信任的用户创建对象。 -带有参数默认值的函数,被认为可以匹配任何省略了零个或多个可默认参数位置的调用。如果不止一个这样的函数能匹配某个调用,则使用搜索路径中最早出现的那一个。如果同一模式中存在两个或更多这样的函数,并且它们在未使用默认值的参数位置上的参数类型相同(如果它们具有不同的可默认参数集合,这种情况是可能的),系统就无法判断该偏好哪一个;如果找不到更好的匹配,就会报有歧义的函数调用错误。 +带有参数默认值的函数,被认为可以匹配任何省略了零个或多个可使用默认值的参数位置的调用。如果不止一个这样的函数能匹配某个调用,则使用搜索路径中最早出现的那一个。如果同一模式中存在两个或更多这样的函数,并且它们在未使用默认值的参数位置上的参数类型相同(如果它们具有不同的带有默认值的参数集合,这种情况是可能的),系统就无法判断该偏好哪一个;如果找不到更好的匹配,就会报有歧义的函数调用错误。 -通过限定名调用某个允许不可信用户创建对象的模式中的任意函数时,会带来可用性隐患。恶意用户可以用现有函数的名字创建一个新函数,复制该函数的参数,并附加带有默认值的新参数。这样就会阻止对原始函数的新调用。为避免这种隐患,应把函数放在只允许可信用户创建对象的模式中。 +通过限定名调用某个允许不受信任的用户创建对象的模式中的任意函数时,会带来可用性隐患。恶意用户可以用现有函数的名字创建一个新函数,复制该函数的参数,并附加带有默认值的新参数。这样就会阻止对原始函数的新调用。为避免这种隐患,应把函数放在只允许受信任的用户创建对象的模式中。 @@ -451,14 +451,14 @@ SELECT * FROM mytable WHERE val = text 'foo'; -检查是否存在一个恰好接受输入参数类型的函数。如果存在(在被考虑的函数集合中至多只有一个精确匹配),就使用它。若通过限定名调用某个允许不可信用户创建对象的模式中的函数,而又缺少精确匹配,就会带来安全隐患。在这种情况下,应通过对参数进行类型转换来强制获得精确匹配。(涉及unknown的情况在这一步永远找不到匹配。) +检查是否存在一个恰好接受输入参数类型的函数。如果存在(在被考虑的函数集合中至多只有一个精确匹配),就使用它。若通过限定名调用某个允许不受信任的用户创建对象的模式中的函数,而又缺少精确匹配,就会带来安全隐患。在这种情况下,应通过对参数进行类型转换来强制获得精确匹配。(涉及unknown的情况在这一步永远找不到匹配。) -如果没有找到精确匹配,就检查该函数调用是否看起来像一种特殊的类型转换请求。这种情况发生在:函数调用只有一个参数,且函数名与某个数据类型的(内部)名称相同。此外,函数参数必须是unknown类型文字,或者是一种能够进行二进制强制转换到该命名数据类型的类型,或者是一种可以通过应用其 I/O 函数转换为该命名数据类型的类型(也就是说,该转换要么转到某种标准字符串类型,要么从某种标准字符串类型转来)。满足这些条件时,该函数调用会被当作一种CAST形式。 +如果没有找到精确匹配,就检查该函数调用是否看起来像一种特殊的类型转换请求。这种情况发生在:函数调用只有一个参数,且函数名与某个数据类型的(内部)名称相同。此外,函数参数必须是unknown类型字面量,或者是一种可以二进制强制转换为该命名数据类型的类型,或者是一种可以通过应用其 I/O 函数转换为该命名数据类型的类型(也就是说,该转换要么转到某种标准字符串类型,要么从某种标准字符串类型转来)。满足这些条件时,该函数调用会被当作一种CAST形式。 之所以有这一步,是为了在不存在实际类型转换函数的情况下仍支持函数风格的类型转换写法。如果存在类型转换函数,按惯例它会以其输出类型命名,因此无需为此设置特殊情况。更多说明见。 @@ -475,13 +475,13 @@ SELECT * FROM mytable WHERE val = text 'foo'; -丢弃那些输入类型不匹配,且也无法通过隐式类型转换实现匹配的候选函数。为此,假定unknown文字可以转换为任何类型。如果只剩一个候选函数,就使用它;否则继续下一步。 +丢弃那些输入类型不匹配,且也无法通过隐式类型转换实现匹配的候选函数。为此,假定unknown字面量可以转换为任何类型。如果只剩一个候选函数,就使用它;否则继续下一步。 -如果任何输入参数是域类型,则在后续所有步骤中都把它当作该域的基类型。这样可以确保在解决函数歧义时,域的行为与其基类型一致。 +如果任何输入参数是域类型,则在后续所有步骤中都把它当作该域的基础类型。这样可以确保在解决函数歧义时,域的行为与其基础类型一致。 @@ -493,13 +493,13 @@ SELECT * FROM mytable WHERE val = text 'foo'; -遍历所有候选函数,保留那些在需要类型转换的最多位置上接受首选类型(属于输入数据类型的类型分类)的候选项。如果没有候选项接受首选类型,则保留全部候选项。如果只剩一个候选函数,就使用它;否则继续下一步。 +遍历所有候选函数,在需要类型转换的位置上,保留接受首选类型(属于输入数据类型的类型分类)的位置数最多的候选项。如果没有候选项接受首选类型,则保留全部候选项。如果只剩一个候选函数,就使用它;否则继续下一步。 -如果有任何输入参数是unknown,就检查剩余候选函数在这些参数位置上接受哪些类型分类。在每个位置上,如果有任何候选项接受string分类,就选择该分类。(这种偏向字符串的做法是合适的,因为unknown类型的文字看起来像字符串。)否则,如果所有剩余候选项都接受同一种类型分类,就选择该分类;否则失败,因为在缺少更多线索的情况下无法推断出正确选择。然后丢弃不接受所选类型分类的候选项。此外,如果有任何候选项接受该分类中的首选类型,就丢弃在该参数上接受非首选类型的候选项。如果没有候选项通过这些测试,则保留全部候选项。如果只剩一个候选函数,就使用它;否则继续下一步。 +如果有任何输入参数是unknown,就检查剩余候选函数在这些参数位置上接受哪些类型分类。在每个位置上,如果有任何候选项接受string分类,就选择该分类。(这种偏向字符串的做法是合适的,因为unknown类型的字面量看起来像字符串。)否则,如果所有剩余候选项都接受同一种类型分类,就选择该分类;否则失败,因为在缺少更多线索的情况下无法推断出正确选择。然后丢弃不接受所选类型分类的候选项。此外,如果有任何候选项接受该分类中的首选类型,就丢弃在该参数上接受非首选类型的候选项。如果没有候选项通过这些测试,则保留全部候选项。如果只剩一个候选函数,就使用它;否则继续下一步。 @@ -680,7 +680,7 @@ SELECT substr(CAST (1234 AS text), 3); -否则,尝试把表达式转换为目标类型。如果这两种类型之间在pg_cast目录中登记了赋值类型转换(见),就可以这样做。另一种情况是,如果表达式是unknown类型文字,则会把文字字符串的内容送入目标类型的输入转换例程。 +否则,尝试把表达式转换为目标类型。如果这两种类型之间在pg_cast目录中登记了赋值类型转换(见),就可以这样做。另一种情况是,如果表达式是unknown类型字面量,则会把字符串字面量的内容送入目标类型的输入转换例程。 @@ -713,7 +713,7 @@ SELECT v, octet_length(v) FROM vv; -这里实际发生的是,两个unknown类型文字默认都被解析为text,从而使||操作符被解析为text的连接操作。然后,操作符得到的text结果被转换为bpcharblank-padded char,即character数据类型的内部名称),以匹配目标列类型。(由于从textbpchar的转换是二进制可强制转换的,这一步不会插入任何真实的函数调用。)最后,系统目录中找到尺寸调整函数bpchar(bpchar, integer, boolean),并把它应用到操作符结果以及存储列长度上。这个特定于类型的函数会执行所需的长度检查并补齐填充空格。 +这里实际发生的是,两个unknown类型字面量默认都被解析为text,从而使||操作符被解析为text的连接操作。然后,操作符得到的text结果被转换为bpchar用空格填充的字符,blank-padded char,即character数据类型的内部名称),以匹配目标列类型。(由于从textbpchar的转换是二进制可强制转换的,这一步不会插入任何真实的函数调用。)最后,系统从系统目录中找到尺寸调整函数bpchar(bpchar, integer, boolean),并把它应用到操作符结果以及存储列长度上。这个特定于类型的函数会执行所需的长度检查并补齐填充空格。 @@ -770,10 +770,10 @@ SQL 的UNION结构必须让可能不同的类型彼此匹配 -如果任何输入是域类型,则在后续所有步骤中都把它当作该域的基类型。 +如果任何输入是域类型,则在后续所有步骤中都把它当作该域的基础类型。 - 这在某种程度上类似于操作符和函数对域输入的处理方式;只要用户确保所有输入都隐式或显式地正好属于该域类型,这种行为就能让域类型在UNION或类似结构中得以保留。否则,就会使用该域的基类型。 + 这在某种程度上类似于操作符和函数对域输入的处理方式;只要用户确保所有输入都隐式或显式地正好属于该域类型,这种行为就能让域类型在UNION或类似结构中得以保留。否则,就会使用该域的基础类型。 @@ -832,7 +832,7 @@ SELECT text 'a' AS "text" UNION SELECT 'b'; b (2 rows) -这里,unknown类型文字'b'会被解析为text类型。 +这里,unknown类型字面量'b'会被解析为text类型。 @@ -850,7 +850,7 @@ SELECT 1.2 AS "numeric" UNION SELECT 1; 1.2 (2 rows) -文字常量1.2的类型是numeric,而integer1可以隐式转换为numeric,因此使用该类型。 +字面量1.2的类型是numeric,而integer1可以隐式转换为numeric,因此使用该类型。 @@ -905,17 +905,17 @@ ERROR: UNION types text and integer cannot be matched -前面各节给出的规则会为 SQL 查询中的所有表达式分配非unknown的数据类型,唯一的例外是作为SELECT命令简单输出列出现的未指定类型文字常量。例如,在 +前面各节给出的规则会为 SQL 查询中的所有表达式分配非unknown的数据类型,唯一的例外是作为SELECT命令简单输出列出现的未指定类型字面量。例如,在 SELECT 'Hello World'; -中,没有任何信息能够表明这个字符串文字应该视为哪种类型。在这种情况下,PostgreSQL会退回到把该文字解析为text类型。 +中,没有任何信息能够表明这个字符串字面量应该视为哪种类型。在这种情况下,PostgreSQL会退回到把该字面量解析为text类型。 -当SELECTUNION(或INTERSECTEXCEPT)结构的一端,或者出现在INSERT ... SELECT中时,这条规则不适用,因为前面各节给出的规则具有更高优先级。在前一种情况下,未指定类型文字的类型可以从UNION的另一侧取得;在后一种情况下,则从目标列取得。 +当SELECTUNION(或INTERSECTEXCEPT)结构的一端,或者出现在INSERT ... SELECT中时,这条规则不适用,因为前面各节给出的规则具有更高优先级。在前一种情况下,未指定类型字面量的类型可以从UNION的另一侧取得;在后一种情况下,则从目标列取得。 @@ -925,7 +925,7 @@ SELECT 'Hello World'; - 在PostgreSQL 10 之前,这条规则并不存在,SELECT输出列表中的未指定类型文字会被保留为unknown类型。这会带来各种不良后果,因此后来做了修改。 + 在PostgreSQL 10 之前,这条规则并不存在,SELECT输出列表中的未指定类型字面量会被保留为unknown类型。这会带来各种不良后果,因此后来做了修改。 diff --git a/zh/14/user-manag.sgml b/zh/14/user-manag.sgml index f5dcf621..b33e7ca2 100644 --- a/zh/14/user-manag.sgml +++ b/zh/14/user-manag.sgml @@ -64,19 +64,15 @@ dropuser name - 要确定现有角色的集合,可以查看pg_roles系统目录,例如: + 要确定现有角色的集合,请查看 pg_roles 系统目录,例如 SELECT rolname FROM pg_roles; - 或者只看那些能够登录的角色: - -SELECT rolname FROM pg_roles WHERE rolcanlogin; - - 程序的\du元命令也很适合列出现有角色。 + 使用 程序的 \du 元命令也可以列出现有角色。 - 为了完成数据库系统的初始引导,一个刚初始化的系统总会包含一个预定义的可登录角色。该角色总是一个超级用户,并且除非另行指定了不同名称,否则它的名称与用initdb初始化数据库集簇的操作系统用户相同。这个角色通常命名为postgres。要创建更多角色,必须先以这个初始角色建立连接。 + 为了完成数据库系统的初始引导,一个刚初始化的系统总会包含一个预定义角色。该角色总是一个超级用户,并且除非另行指定了不同名称,否则它的名称与用initdb初始化数据库集簇的操作系统用户相同。这个角色通常命名为postgres。要创建更多角色,必须先以这个初始角色建立连接。 @@ -208,11 +204,7 @@ ALTER ROLE myname SET enable_indexscan TO off; 这会保存该设置(但不会立即生效)。在该角色后续建立的连接中,它看起来就像在会话开始之前执行了SET enable_indexscan TO off一样。你仍然可以在会话期间更改该设置;它只会作为默认值。要移除角色特定默认设置,使用ALTER ROLE rolename RESET varname。注意,附加到没有LOGIN权限的角色上的角色特定默认值几乎没有用,因为它们永远不会生效。 - - 当非超级用户利用CREATEROLE权限创建角色时,所创建的角色会自动重新授予给创建用户,就像引导超级用户执行了命令GRANT created_user TO creating_user WITH ADMIN TRUE, SET FALSE, - INHERIT FALSE一样。由于CREATEROLE用户只有在对现有角色拥有ADMIN OPTION时,才能对该角色行使特殊权限,这项授权恰好足以让CREATEROLE用户管理自己创建的角色。不过,因为它是以INHERIT FALSE, SET - FALSE创建的,CREATEROLE用户不会继承所创建角色的权限,也不能通过SET ROLE访问该角色的权限。然而,由于任何对某角色拥有ADMIN OPTION的用户都可以把该角色的成员资格授予任何其他用户,CREATEROLE用户只需使用INHERIT和/或SET选项把该角色再次授予自己,就可以获得对所创建角色的访问能力。因此,默认不继承权限、也不默认授予SET ROLE,只是为了防止意外,而不是一种安全特性。还要注意,由于这项自动授权是由引导超级用户发出的,CREATEROLE用户自己不能撤销或更改它;不过,任何超级用户都可以撤销或修改它,并向其他CREATEROLE用户发出额外的此类授权。无论何时,对某角色拥有ADMIN OPTIONCREATEROLE用户都可以管理该角色。 - + @@ -244,25 +236,27 @@ REVOKE group_role FROM role1 - 组角色的成员可以通过两种方式使用该角色的权限。第一,获授成员资格且带有SET选项的成员角色可以通过SET ROLE临时成为该组角色。在这种状态下,数据库会话可以使用组角色的权限,而不是原始登录角色的权限,并且创建的任何数据库对象都被认为归组角色所有,而不是归登录角色所有。第二,获授成员资格且带有INHERIT选项的成员角色,会自动拥有其直接或间接所属角色的权限,不过一旦成员资格链上某一段缺少继承选项,这条链就会在那里终止。举例来说,假设我们执行了: + 组角色的成员可以通过两种方式使用该角色的权限。首先,组的每个成员都可以显式执行 + SET ROLE,以暂时成为该组角色。在这种状态下,数据库会话可以使用组角色的权限,而不是原始登录角色的权限;创建的任何数据库对象也被视为由组角色而非登录角色拥有。其次,具有 INHERIT 属性的成员角色可以自动使用其所属角色的权限,包括这些角色继承的所有权限。例如,假定我们已经执行了: -CREATE ROLE joe LOGIN; -CREATE ROLE admin; -CREATE ROLE wheel; -CREATE ROLE island; -GRANT admin TO joe WITH INHERIT TRUE; -GRANT wheel TO admin WITH INHERIT FALSE; -GRANT island TO joe WITH INHERIT TRUE, SET FALSE; +CREATE ROLE joe LOGIN INHERIT; +CREATE ROLE admin NOINHERIT; +CREATE ROLE wheel NOINHERIT; +GRANT admin TO joe; +GRANT wheel TO admin; - 以角色joe建立连接后,数据库会话立即可以使用直接授予joe的权限,以及授予adminisland的任何权限,因为joe继承了这些权限。然而,授予wheel的权限不可用,因为尽管joe间接是wheel的成员,但这层成员资格是经由使用WITH INHERIT FALSE授予的admin得来的。执行: + 以角色 joe 连接后,数据库会话立即可以使用直接授予 joe 的权限,以及授予 admin 的所有权限,因为 joe + 继承 admin 的权限。不过,授予 wheel 的权限不可用,因为即使 joe 间接属于 wheel,该成员资格也是通过 admin 获得的,而后者具有 NOINHERIT 属性。执行以下命令后: SET ROLE admin; - 之后,会话将只能使用授予admin的权限,而不能使用授予joeisland的权限。再执行: + 会话将只能使用授予 + admin 的权限,而不能使用授予 joe 的权限。执行以下命令后: SET ROLE wheel; - 之后,会话将只能使用授予wheel的权限,而不能使用授予joeadmin的权限。原始权限状态可通过以下任一方式恢复: + 会话将只能使用授予 + wheel 的权限,而不能使用授予 joeadmin 的权限。使用以下任一命令可以恢复原始的权限状态: SET ROLE joe; SET ROLE NONE; @@ -272,7 +266,7 @@ RESET ROLE; - SET ROLE命令总是允许切换到原始登录角色直接或间接所属的任何角色,只要存在一条成员资格授权链,并且链上的每一段都具有SET TRUE(默认值)。因此,在上例中,没有必要先成为admin再成为wheel。另一方面,根本不可能成为islandjoe只能通过继承来使用那些权限。 + SET ROLE命令总是允许切换到原始登录角色直接或间接所属的任何角色。因此,在上例中,没有必要先成为admin再成为wheel @@ -315,12 +309,12 @@ ALTER TABLE bobs_table OWNER TO alice; - 一旦有价值的对象都已转移给新拥有者,被删除角色所拥有的其余对象即可使用DROP OWNED命令删除。同样,由于该命令不能访问其他数据库中的对象,因此必须在包含该角色所拥有对象的每个数据库中运行它。另外,DROP + 一旦有价值的对象都已转移给新拥有者,待删除角色所拥有的其余对象即可使用DROP OWNED命令删除。同样,由于该命令不能访问其他数据库中的对象,因此必须在包含该角色所拥有对象的每个数据库中运行它。另外,DROP OWNED不会删除整个数据库或表空间,因此如果该角色拥有任何尚未转移给新拥有者的数据库或表空间,就必须手工删除它们。 - DROP OWNED还会负责移除授予目标角色、但不属于它自身对象的任何权限。由于REASSIGN OWNED不会处理这类对象,所以通常需要同时运行REASSIGN OWNEDDROP OWNED(按这个顺序!),才能完整移除待删除角色的依赖关系。 + DROP OWNED还会负责移除目标角色在其他角色所拥有的对象上获授的所有权限。由于REASSIGN OWNED不会处理这类对象,所以通常需要同时运行REASSIGN OWNEDDROP OWNED(按这个顺序!),才能完整移除待删除角色的依赖关系。 @@ -371,11 +365,11 @@ DROP ROLE doomed_role; pg_read_all_data - 读取所有数据(表、视图、序列),其效果就像对这些对象拥有SELECT权限并对所有模式拥有USAGE权限一样,即使未被显式授予也是如此。该角色没有设置角色属性BYPASSRLS。如果正在使用 RLS,管理员可能希望对被授予此角色的角色设置BYPASSRLS + 读取所有数据(表、视图、序列),其效果就像对这些对象拥有SELECT权限并对所有模式拥有 USAGE 权限一样,即使没有被显式授予。该角色没有设置角色属性BYPASSRLS。如果正在使用 RLS,管理员可能希望对被 GRANT 此角色的角色设置BYPASSRLS pg_write_all_data - 写入所有数据(表、视图、序列),其效果就像对这些对象拥有INSERTUPDATEDELETE权限并对所有模式拥有USAGE权限一样,即使未被显式授予也是如此。该角色没有设置角色属性BYPASSRLS。如果正在使用 RLS,管理员可能希望对被授予此角色的角色设置BYPASSRLS + 写入所有数据(表、视图、序列),其效果就像对这些对象拥有INSERTUPDATEDELETE权限并对所有模式拥有 USAGE 权限一样,即使没有被显式授予。该角色没有设置角色属性BYPASSRLS。如果正在使用 RLS,管理员可能希望对被 GRANT 此角色的角色设置BYPASSRLS pg_read_all_settings @@ -383,7 +377,7 @@ DROP ROLE doomed_role; pg_read_all_stats - 读取所有 pg_stat_* 视图,并使用各种与统计信息相关的扩展,即使是那些通常仅对超级用户可见的扩展。 + 读取所有 pg_stat_* 视图,并使用各种与统计信息相关的扩展,包括通常仅对超级用户可见的内容。 pg_stat_scan_tables @@ -403,15 +397,15 @@ DROP ROLE doomed_role; pg_read_server_files - 允许使用COPY和其他文件访问函数,从服务器上数据库可访问的任何位置读取文件。 + 允许使用COPY和其他文件访问函数,从服务器上数据库可访问的任何位置读取文件。 pg_write_server_files - 允许使用COPY和其他文件访问函数,向服务器上数据库可访问的任何位置写入文件。 + 允许使用COPY和其他文件访问函数,向服务器上数据库可访问的任何位置写入文件。 pg_execute_server_program - 允许使用COPY和其他允许执行服务器端程序的函数,以数据库运行所用用户的身份在数据库服务器上执行程序。 + 允许使用COPY和其他允许执行服务器端程序的函数,以数据库运行所用用户的身份在数据库服务器上执行程序。 @@ -430,15 +424,15 @@ DROP ROLE doomed_role; - pg_read_server_filespg_write_server_filespg_execute_server_program角色旨在让管理员能够创建受信任但非超级用户的角色,使其能够以数据库运行所用用户的身份访问文件并在数据库服务器上运行程序。由于这些角色能够访问服务器文件系统上的任意文件,它们在直接访问文件时会绕过所有数据库级权限检查,并且可被用来获得超级用户级别的访问能力,因此向用户授予这些角色时必须极其谨慎。 + pg_read_server_filespg_write_server_filespg_execute_server_program角色旨在让管理员能够使受信任但非超级用户的角色能够以数据库运行所用用户的身份访问文件并在数据库服务器上运行程序。由于这些角色能够访问服务器文件系统上的任意文件,它们在直接访问文件时会绕过所有数据库级权限检查,并且可被用来获得超级用户级别的访问能力,因此向用户授予这些角色时必须极其谨慎。 - 授予这些角色时应当谨慎,确保它们只在需要时使用,并理解这些角色会授予对特权信息的访问。 + 授予这些角色时应当谨慎,确保它们只在需要时使用,并理解这些角色会授予对需要特权才能访问的信息的访问。 - 管理员可以使用GRANT命令把这些角色授予用户,例如: + 管理员可以使用GRANT命令把这些角色的访问授予用户,例如: GRANT pg_signal_backend TO admin_user; @@ -451,7 +445,7 @@ GRANT pg_signal_backend TO admin_user; 函数安全性 - 函数、触发器和行级安全策略允许用户把代码插入后端服务器,而其他用户可能会无意中执行这些代码。因此,这些机制使用户能够相对容易地对其他用户实施特洛伊木马攻击。最强的保护方式是严格控制谁能定义对象。如果这不可行,则应编写只引用拥有者可信对象的查询,并从search_path中移除任何允许不受信任用户创建对象的模式。 + 函数、触发器和行级安全策略允许用户把代码插入后端服务器,而其他用户可能会无意中执行这些代码。因此,这些机制使用户能够相对容易地对其他用户实施特洛伊木马攻击。最强的保护方式是严格控制谁能定义对象。如果这不可行,则应编写只引用拥有者可信的对象的查询,并从search_path中移除 public 模式以及任何其他允许不受信任用户创建对象的模式。 diff --git a/zh/14/vacuumlo.sgml b/zh/14/vacuumlo.sgml index 9e80b19f..cc2c04f5 100644 --- a/zh/14/vacuumlo.sgml +++ b/zh/14/vacuumlo.sgml @@ -8,7 +8,7 @@ vacuumlo 1 - Application + 应用程序 diff --git a/zh/14/wal.sgml b/zh/14/wal.sgml index 8f8c09ae..7cffa05e 100644 --- a/zh/14/wal.sgml +++ b/zh/14/wal.sgml @@ -158,7 +158,8 @@ - 数据页默认带有校验和,而记录在 WAL 记录中的整页镜像始终受校验和保护。 + 数据页默认并不带校验和,不过,记录在 WAL 记录中的整页镜像始终受保护;有关启用数据校验和的细节,见 initdb @@ -198,14 +199,14 @@ - 默认情况下,数据页受校验和保护,但也可以选择为集簇禁用。启用后,每个数据页 + 默认情况下,数据页不受校验和保护,但可以选择为集簇启用。启用后,每个数据页 都包含一个校验和,在页面写入时更新,并在页面每次被读取时进行验证。只有数据 页受校验和保护;内部数据结构和临时文件不受保护。 可以在使用 initdb - 初始化集簇时禁用校验和。之后也可以作为离线操作启用或禁用。数据校验和是在整个 + 初始化集簇时启用校验和。之后也可以作为离线操作启用或禁用。数据校验和是在整个 集簇级别启用或禁用的,不能为单个数据库或表分别指定。 @@ -390,9 +391,9 @@ 检查点检查点 是事务序列中的一些点,在这些点上可以保证堆和索引数据文件已经用检查点之前写入 - 的全部信息进行了更新。执行检查点时,所有脏数据页都会刷写到磁盘,并向 WAL - 文件写入一条特殊的检查点记录。(更改记录此前已经刷入 WAL - 文件。)如果发生崩溃,崩溃恢复过程会查看最新的检查点记录,以确定应该从 WAL + 的全部信息进行了更新。执行检查点时,所有脏数据页都会刷盘,并向 WAL + 文件写入一条特殊的检查点记录。(更改记录此前已写入 WAL + 文件并刷盘。)如果发生崩溃,崩溃恢复过程会查看最新的检查点记录,以确定应该从 WAL 的哪个位置(称为重做记录)开始执行 REDO。该点之前对数据文件所做的任何更改 都保证已经在磁盘上。因此,检查点之后,位于包含重做记录的段之前的 WAL 段不再需要, 可以被回收或删除。(若正在执行 WAL 归档,则这些 WAL 段必 @@ -420,7 +421,7 @@ 减小 checkpoint_timeout 和/或 max_wal_size 会让检查点更频繁地发生。这样可以加快崩溃后 - 恢复,因为需要重做的工作更少。不过,这必须与更频繁刷写脏数据页所增加的成本 + 恢复,因为需要重做的工作更少。不过,这必须与更频繁地将脏数据页刷盘所增加的成本 权衡。如果设置了 (默认就是如此), 还要考虑另一个因素。为了保证数据页一致性,每个检查点之后对某个数据页的首次 修改,都会导致把整页内容写入日志。在这种情况下,更短的检查点间隔会增加输出到 @@ -447,7 +448,7 @@ I/O 速率,使检查点在给定比例的 checkpoint_timeout 秒数 经过时完成,或者在 max_wal_size 即将超出之前完成,以较早 者为准。使用默认值 0.9 时,可以预期 PostgreSQL - 会在下一次计划检查点开始前稍早完成每个检查点(大约在检查点间隔的 90% 时)。 + 会在下一次计划检查点开始前稍早完成每个检查点(耗时约为上一次检查点持续时间的 90%)。 这样能尽可能摊平 I/O,从而使检查点 I/O 负载在整个检查点间隔内保持稳定。这样 做的缺点是,延长检查点会影响恢复时间,因为需要保留更多 WAL 段以备恢复时 使用。关心恢复耗时的用户,可能希望减小 @@ -463,7 +464,7 @@ 在 Linux 和 POSIX 平台上, - 允许在检查点写出的操作系统页面达到可配置的字节数后,强制把它们刷到磁盘。 + 允许在检查点写出的操作系统页面达到可配置的字节数后,强制将它们刷盘。 否则,这些页面可能会停留在操作系统页缓存中,从而在检查点末尾发出 fsync 时引发停顿。这个设置通常有助于降低事务延迟,但也可能 对性能产生不利影响,尤其是在工作负载大于 @@ -499,13 +500,12 @@ 在归档恢复或备库模式下,服务器会周期性地执行 重启点重启点, - 其行为类似于正常运行时的检查点:服务器会强制把自身状态写盘,更新 + 其行为类似于正常运行时的检查点:服务器会强制将其所有状态刷盘,更新 pg_control 文件,以表明已经处理过的 WAL 数据无需再次 扫描,然后回收 pg_wal 目录中的旧 WAL 段文件。重启点的 - 执行频率不会高于主库上的检查点,因为重启点只能在检查点记录处执行。重启点既 - 可能由调度触发,也可能由外部请求触发。当到达某条检查点记录且距离上次重启点 - 至少已经过去 秒,或者 WAL 大小即将超过 - 时,就会触发重启点。不过,由于重启点的可执行时机受到 + 执行频率不会高于主库上的检查点,因为重启点只能在检查点记录处执行。当到达某条检查点记录且距离上次重启点 + 至少已经过去 checkpoint_timeout 秒,或者 WAL 大小即将超过 + max_wal_size 时,就会触发重启点。不过,由于重启点的可执行时机受到 限制,恢复期间经常会超出 max_wal_size,最多可能超出一个 检查点周期对应的 WAL 量。(无论如何,max_wal_size 从来 都不是硬上限,因此你始终应留出充足余量,以免耗尽磁盘空间。) @@ -523,7 +523,7 @@ 快。更糟的是,写 WAL 缓冲区还可能迫使系统创建新的 WAL 段, 这会花费更多时间。正常情况下,WAL 缓冲区应由 XLogFlush 请求负责写出并刷盘; - 该请求大多发生在事务提交时,以确保事务记录被刷入持久存储。在 WAL 输出量很高 + 该请求大多发生在事务提交时,以确保事务记录已刷盘至持久存储。在 WAL 输出量很高 的系统上,XLogFlush 请求可能不够频繁,无法避免 XLogInsertRecord 自己去执行写出。在这种系统上,应增加 WAL 缓冲区的数量,具体做法是修改参数 @@ -536,7 +536,7 @@ 参数 定义了组提交的领导者进程在 XLogFlush 内部获取锁之后会睡眠多少微秒,在此期间,组提 交的追随者会排队跟在领导者后面。这一延迟允许其他服务器进程把自己的提交记录添 - 加到 WAL 缓冲区中,以便它们都能由领导者最终执行的同步操作一并刷出。如果没有 + 加到 WAL 缓冲区中,以便它们都能由领导者最终执行的同步操作一并刷盘。如果没有 启用 ,或者当前处于活跃事务中的其他会话少于 个,就不会发生睡眠;这样可以避免在其他 会话不太可能很快提交时还去睡眠。请注意,在某些平台上,休眠请求的分辨率是 @@ -565,8 +565,7 @@ commit_delay 设为 0(默认值)时,仍然可能出现一种组 - 提交,但每个组只会包含那些恰好在前一次刷盘操作(若有)进行期间,到达“需要刷 - 出其提交记录”这一点的会话。客户端数量更高时,往往会出现一种 + 提交,但每个组只会包含那些恰好在前一次刷盘操作(若有)进行期间,到达“需要将其提交记录刷盘”这一点的会话。客户端数量更高时,往往会出现一种 gangway effect,以至于即使 commit_delay 为 0,组提交的效果也会变得很显著,因此显式设置 commit_delay 的帮助反而会变小。只有在以下两种条件同时 @@ -579,9 +578,9 @@ 参数 决定 PostgreSQL 将如何请求内核把 - WAL 更新强制刷到磁盘。就可靠性而言,所有选项应当都是相同 + WAL 更新强制刷盘。就可靠性而言,所有选项应当都是相同 的;例外是 fsync_writethrough,它有时能够在其他选项做不 - 到时强制刷新磁盘缓存。不过,具体哪个选项速度最快则高度依赖平台。可以使用 + 到时强制将磁盘缓存中的数据刷盘。不过,具体哪个选项速度最快则高度依赖平台。可以使用 程序测试不同选项的速度。请注意,如果 fsync 已被关闭,那么这个参数就没有意义。 diff --git a/zh/14/xaggr.sgml b/zh/14/xaggr.sgml index b46b119e..d7ef45aa 100644 --- a/zh/14/xaggr.sgml +++ b/zh/14/xaggr.sgml @@ -43,11 +43,11 @@ SELECT sum(a) FROM test_complex; - 如果没有非空输入值,上述sum定义将返回零(即初始状态值)。也许我们更希望在这种情况下返回空值 — SQL 标准要求sum这样做。实现这一点只需省略initcond短语,使初始状态值为空。通常这意味着sfunc需要检查输入的状态值是否为空。但对于sum以及maxmin这类其他简单聚合,只需把第一个非空输入值放入状态变量,然后从第二个非空输入值开始应用转移函数即可。如果初始状态值为空,并且转移函数被标记为strict(即不会对空输入调用),PostgreSQL会自动这样做。 + 如果没有非空输入值,上述sum定义将返回零(即初始状态值)。也许我们更希望在这种情况下返回空值 — SQL 标准要求sum这样做。实现这一点只需省略initcond短语,使初始状态值为空值。通常这意味着sfunc需要检查输入的状态值是否为空值。但对于sum以及maxmin这类其他简单聚合,只需把第一个非空输入值放入状态变量,然后从第二个非空输入值开始应用转移函数即可。如果初始状态值为空值,并且转移函数被标记为strict(即不会对空值输入调用),PostgreSQL会自动这样做。 - strict转移函数的另一项默认行为是,只要遇到空输入值,就会保留先前的状态值不变。因此,空值会被忽略。如果你需要对空输入采用其他行为,就不要把转移函数声明为 strict,而应在函数代码中自行检测空输入并完成所需处理。 + strict转移函数的另一项默认行为是,只要遇到空值输入,就会保留先前的状态值不变。因此,空值会被忽略。如果你需要对空值输入采用其他行为,就不要把转移函数声明为 strict,而应在函数代码中自行检测空值输入并完成所需处理。 @@ -72,7 +72,7 @@ CREATE AGGREGATE avg (float8) - SQL 中的聚合函数调用允许使用DISTINCTORDER BY选项,以控制哪些行会传递给聚合的转移函数,以及传递顺序。这些选项是在后台实现的,并不是聚合支持函数需要关心的事情。 + SQL 中的聚合函数调用允许使用DISTINCTORDER BY选项,以控制哪些行会传递给聚合的转移函数,以及传递顺序。这些选项由系统在内部实现,并不是聚合支持函数需要关心的事情。 @@ -292,7 +292,7 @@ SELECT percentile_disc(0.5) WITHIN GROUP (ORDER BY income) FROM households; - 与普通聚合不同,有序集聚合的输入行排序不是在幕后完成的,而是由聚合的支持函数负责。典型的实现方法是在聚合的状态值中保存一个tuplesort对象的引用,把输入行送入该对象,然后在最终函数中完成排序并读出数据。这样的设计使最终函数可以执行特殊操作,例如向待排序数据中注入额外的假想行。普通聚合通常可以使用由PL/pgSQL或其他 PL 语言编写的支持函数来实现,但有序集聚合通常必须用 C 编写,因为它们的状态值无法定义为任何 SQL 数据类型。(在上面的示例中,注意状态值被声明为internal类型,这很典型。)另外,由于最终函数执行了排序,之后就不可能再通过再次执行转移函数来继续加入输入行。这意味着最终函数不是READ_ONLY;在CREATE AGGREGATE中,必须将其声明为READ_WRITE,或者如果额外的最终函数调用能够利用已经排好序的状态,则声明为SHAREABLE。 + 与普通聚合不同,有序集聚合的输入行排序不是由系统在内部完成的,而是由聚合的支持函数负责。典型的实现方法是在聚合的状态值中保存一个tuplesort对象的引用,把输入行送入该对象,然后在最终函数中完成排序并读出数据。这样的设计使最终函数可以执行特殊操作,例如向待排序数据中注入额外的假想行。普通聚合通常可以使用由PL/pgSQL或其他 PL 语言编写的支持函数来实现,但有序集聚合通常必须用 C 编写,因为它们的状态值无法定义为任何 SQL 数据类型。(在上面的示例中,注意状态值被声明为internal类型,这很典型。)另外,由于最终函数执行了排序,之后就不可能再通过再次执行转移函数来继续加入输入行。这意味着最终函数不是READ_ONLY;在CREATE AGGREGATE中,必须将其声明为READ_WRITE,或者如果额外的最终函数调用能够利用已经排好序的状态,则声明为SHAREABLE @@ -366,7 +366,7 @@ if (AggCheckCallContext(fcinfo, NULL)) - AggCheckCallContext的第二个参数可用于取得保存聚合状态值的内存上下文。这对于希望把扩展对象(见)用作状态值的转移函数很有用。第一次调用时,转移函数应返回一个扩展对象,其内存上下文是聚合状态上下文的子上下文;之后的调用则持续返回同一个扩展对象。示例见array_append()。(array_append()并不是任何内置聚合的转移函数,但它的写法保证了在用作自定义聚合的转移函数时也能高效工作。) + AggCheckCallContext的第二个参数可用于取得保存聚合状态值的内存上下文。这对于希望把展开对象(见)用作状态值的转移函数很有用。第一次调用时,转移函数应返回一个展开对象,其内存上下文是聚合状态上下文的子上下文;之后的调用则持续返回同一个展开对象。示例见array_append()。(array_append()并不是任何内置聚合的转移函数,但它的写法保证了在用作自定义聚合的转移函数时也能高效工作。) diff --git a/zh/14/xfunc.sgml b/zh/14/xfunc.sgml index 225f1351..c88b6b73 100644 --- a/zh/14/xfunc.sgml +++ b/zh/14/xfunc.sgml @@ -4,8 +4,8 @@ 用户定义的函数 - function - user-defined + 函数 + 用户定义的 @@ -36,15 +36,15 @@ - 每一类函数可以采用基本类型、复合类型或者它们的组合作为参数。此外,每一类函数可以返回一个基本类型或一个复合类型。函数也能被定义成返回基本类型或复合类型值的集合。 + 每一类函数可以采用基础类型、复合类型或者它们的组合作为参数。此外,每一类函数可以返回一个基础类型或一个复合类型。函数也能被定义成返回基础类型或复合类型值的集合。 - 很多类函数可以接受或者返回特定的伪类型(例如,多态类型),但是可用的功能会变化。详情可以参考每一种函数的描述。 + 很多类函数可以接受或者返回特定的伪类型(例如,多态类型),但是可用的功能因函数类别而异。详情可以参考每一种函数的描述。 - 定义SQL函数最容易,因此我们将从讨论SQL函数开始。大部分SQL函数的概念也能用到其他类型的函数上。 + 定义SQL函数最容易,因此我们将从讨论它们开始。大部分SQL函数的概念也能用到其他类型的函数上。 @@ -57,8 +57,8 @@ 用户定义的过程 - procedure - user-defined + 过程 + 用户定义的 @@ -101,7 +101,7 @@ - 函数和过程一起构成了例程routine。 + 函数和过程统称为例程例程。 有ALTER ROUTINEDROP ROUTINE这样的命令可以操作函数和过程而不需要知道它们是哪一种。 不过,要注意没有CREATE ROUTINE命令。 @@ -113,7 +113,7 @@ 函数 用户定义的 - in SQL + 在 SQL 中 @@ -124,13 +124,7 @@ 或者,一个 SQL 函数可以通过指定函数的返回类型为SETOF sometype被声明为返回一个集合(也就是多个行),或者等效地声明它为RETURNS TABLE(columns)。在这种情况下,最后一个查询的结果的所有行会被返回。下文将给出进一步的细节。 - - SQL 函数的函数体必须是一个由分号分隔的 SQL 语句列表。最后一条语句后的分号是可选的。除非该函数被声明为返回 - void,否则最后一条语句必须是 SELECT, - 或者是带有 RETURNING 子句的 INSERT、 - UPDATEDELETE 或 - MERGE。 - + SQL 函数的函数体必须是一个由分号分隔的 SQL 语句列表。最后一条语句后的分号是可选的。除非该函数被声明为返回 void,否则最后一条语句必须是 SELECT,或者是 INSERTUPDATEDELETE 并带有 RETURNING 子句。 任意一组 SQL 语言命令都可以打包并定义成函数。除 @@ -139,7 +133,7 @@ DELETE ),以及其他 SQL 命令。(在 SQL 函数中不能使用事务控制命令,例如 COMMITSAVEPOINT,也不能使用某些 - 实用命令,例如 VACUUM。)不过,最后一条命令必须是 + 工具命令,例如 VACUUM。)不过,最后一条命令必须是 SELECT,或者带有 RETURNING 子句,并返回与函数声明返回类型相符的结果。或者,如果你想定义一个执行动作 但没有有用返回值的 SQL 函数,也可以把它定义为返回 void。 @@ -171,11 +165,23 @@ CREATE PROCEDURE clean_emp() AS ' CALL clean_emp(); - 在像这样的简单情况中,函数与过程返回void的差异主要是风格上面的。 + 在像这样的简单情况中,返回void的函数与过程之间的差异主要是风格上面的。 不过,过程还提供了函数所没有的额外能力,例如事务控制。 此外,过程是 SQL 标准的一部分,而返回void则是 PostgreSQL 扩展。 + + + 一个 SQL 函数的整个函数体在它的任何部分被执行前就已经被解析。 + 虽然 SQL 函数能包含修改系统目录的命令(例如CREATE TABLE), + 但在解析分析函数中后续命令时,这种命令的效果是不可见的。 + 因此,例如CREATE TABLE foo (...); INSERT INTO foo VALUES(...); + 如果被打包在一个单一的 SQL 函数中将不能按照预期工作, + 因为当INSERT命令被解析时foo还不存在。 + 在这类情况中建议使用PL/pgSQL代替 SQL 函数。 + + + CREATE FUNCTION 命令的语法要求把函数体写成一个字符串常量。对于字符串常量,通常使用美元引用最方便(见)。如果你选择使用常规的单引号字符串常量语法,那么必须在函数体中将单引号(')和反斜线(\)写成双份(假定使用转义字符串语法,见)。 @@ -226,10 +232,10 @@ INSERT INTO $1 VALUES (42); - 基本类型上的<acronym>SQL</acronym>函数 + 基础类型上的<acronym>SQL</acronym>函数 - 最简单的 SQL 函数没有参数,只是返回一个基本类型,例如 + 最简单的 SQL 函数没有参数,只是返回一个基础类型,例如 integer @@ -255,7 +261,7 @@ SELECT one(); - 定义接受基本类型参数的 SQL 函数也几乎同样容易: + 定义接受基础类型参数的 SQL 函数也几乎同样容易: CREATE FUNCTION add_em(x integer, y integer) RETURNS integer AS $$ @@ -338,24 +344,11 @@ $$ LANGUAGE SQL; - - 如果在SELECTRETURNING子句中, - SQL函数的最终返回值类型与函数声明的结果类型不完全匹配, - 如果可以使用隐式或赋值转换, - PostgreSQL将自动将该值转换为所需类型。 - 否则,你必须写出显式类型转换。 - 例如,假设我们希望前面的add_em函数返回float8类型。 - 只需编写 - - + 如果最后的 SELECTRETURNING 子句返回的类型,与该 SQL 函数声明的结果类型并不完全一致,PostgreSQL 会自动将值转换为所需类型,只要通过隐式转换或赋值转换可以做到。否则,就必须写出显式转换。例如,假设我们希望前面的 add_em 函数改为返回 float8。只需写成: CREATE FUNCTION add_em(integer, integer) RETURNS float8 AS $$ SELECT $1 + $2; $$ LANGUAGE SQL; - - - 因为integer的和可以隐式转换为float8。 - (有关转换的更多信息,请参见。) - +因为 integer 类型的和可以隐式转换为 float8。(有关类型转换的更多信息,请参阅 。) @@ -393,17 +386,17 @@ SELECT name, double_salary(emp.*) AS dream 注意这里用 $1.salary 语法来选取参数行值中的一个字段。 还要注意,调用时的 SELECT 命令使用 - table_name.* 将表的当前整行取作一个组合值。该表行也可以仅用表名来引用: + table_name.* 将表的当前整行取作一个复合值。该表行也可以仅用表名来引用: SELECT name, double_salary(emp) AS dream FROM emp WHERE emp.cubicle ~= point '(2,1)'; - 但这种用法已被废弃,因为它很容易让人混淆(关于表行组合值这两种记法的更多细节,见)。 + 但这种用法已被弃用,因为它很容易让人混淆(关于表行复合值这两种记法的更多细节,见)。 - 有时候即时构造一个组合参数会很方便。这可以用ROW构造器完成。 + 有时候即时构造一个复合参数值会很方便。这可以用ROW构造器完成。 例如,我们可以调整被传递给函数的数据: SELECT name, double_salary(ROW(name, salary*1.1, age, cubicle)) AS dream @@ -432,7 +425,7 @@ $$ LANGUAGE SQL; - 查询中的选择列表顺序必须与列在复合类型中出现的顺序完全相同。(正如我们上面所做的那样,命名列与系统无关。) + 查询中的选择列表顺序必须与列在复合类型中出现的顺序完全相同。(系统不考虑像上面这样指定的列名。) @@ -444,7 +437,7 @@ ERROR: return type mismatch in function declared to return emp DETAIL: Final statement returns text instead of point at column 4. - 与基本类型的情况一样,系统不会自动插入显式转换,只会插入隐式或赋值转换。 + 与基础类型的情况一样,系统不会自动插入显式转换,只会插入隐式或赋值转换。 @@ -461,7 +454,7 @@ $$ LANGUAGE SQL; 这里我们写了一个只返回单列、且该列具有正确复合类型的 SELECT。 在这种场景下,这样写并不见得更好,但在某些情况下会很方便 - — 例如,需要通过调用另一个返回目标组合值的函数来计算结果时。 + — 例如,需要通过调用另一个返回目标复合值的函数来计算结果时。 还有一种情况是,如果我们要编写的函数返回的是基于复合类型的域,而不是普通复合类型, 那么就必须写成返回单列的形式,因为没有办法让整行结果发生所需的强制转换。 @@ -526,7 +519,7 @@ SELECT name(new_emp()); - 另一种使用函数返回复合类型的方法是将结果传递给另一个接受正确行类型作为输入的函数: + 另一种使用函数返回复合类型的方法是将结果传递给另一个接受正确行类型作为输入的函数: CREATE FUNCTION getname(emp) RETURNS text AS $$ @@ -614,7 +607,7 @@ DROP FUNCTION sum_n_product (int, int); <acronym>SQL</acronym>有输出参数的过程 - procedures + 过程 输出参数 @@ -636,7 +629,7 @@ $$ LANGUAGE SQL; CALL tp1(17, 100.0, NULL); 如果你写的是其他内容,它必须是一个能够像输入参数那样被隐式强制转换成该参数声明类型的表达式。 - 注意,无论如何这样的表达式不会被评估。 + 不过要注意,这样的表达式不会被求值。 @@ -648,12 +641,12 @@ CALL tp1(17, 100.0, NULL); 带有可变数量参数的<acronym>SQL</acronym>函数 - function - variadic + 函数 + 可变参数 - variadic function + 可变参数函数 @@ -684,27 +677,27 @@ SELECT mleast(ARRAY[10, -1, 5, 4.4]); -- doesn't work - 有时候,能够把一个已经构造好的数组传给 variadic 函数会很有用,尤其是当一个 variadic 函数想把它的数组参数再传给另一个函数时。此外,在允许不受信任用户创建对象的模式中调用 variadic 函数时,这是唯一安全的方式,见。你可以在调用中指定VARIADIC来做到这一点: + 有时候,能够把一个已经构造好的数组传给可变参数函数会很有用,尤其是当一个可变参数函数想把它的数组参数再传给另一个函数时。此外,在允许不受信任用户创建对象的模式中调用可变参数函数时,这是唯一安全的方式,见。你可以在调用中指定VARIADIC来做到这一点: SELECT mleast(VARIADIC ARRAY[10, -1, 5, 4.4]); - 这样会阻止函数的 variadic 参数按其元素类型展开,从而让数组实参能够按常规方式匹配。VARIADIC 只能附加在函数调用的最后一个实参上。 + 这样会阻止函数的可变参数按其元素类型展开,从而让数组实参能够按常规方式匹配。VARIADIC 只能附加在函数调用的最后一个实参上。 - 在调用中指定VARIADIC也是向 variadic 函数传递空数组的唯一方式,例如: + 在调用中指定VARIADIC也是向可变参数函数传递空数组的唯一方式,例如: SELECT mleast(VARIADIC ARRAY[]::numeric[]); - 仅仅写成SELECT mleast()是行不通的,因为 variadic 参数必须匹配至少一个实参。(如果你希望允许这种调用,可以再定义一个同名且不带参数的函数mleast。) + 仅仅写成SELECT mleast()是行不通的,因为可变参数必须匹配至少一个实参。(如果你希望允许这种调用,可以再定义一个同名且不带参数的函数mleast。) - 从 variadic 参数派生出的数组元素参数会被视为没有自己的名字。这意味着除非你指定了 VARIADIC,否则不能使用命名参数来调用 variadic 函数()。例如,下面的调用是可行的: + 从可变参数派生出的数组元素参数会被视为没有自己的名字。这意味着除非你指定了 VARIADIC,否则不能使用命名参数来调用可变参数函数()。例如,下面的调用是可行的: SELECT mleast(VARIADIC arr => ARRAY[10, -1, 5, 4.4]); @@ -723,7 +716,7 @@ SELECT mleast(arr => ARRAY[10, -1, 5, 4.4]); 带有参数默认值的<acronym>SQL</acronym>函数 - function + 函数 参数的默认值 @@ -732,7 +725,7 @@ SELECT mleast(arr => ARRAY[10, -1, 5, 4.4]); 没有给出足够多的实参,就会插入默认值来弥补缺失的实参。由于参数只 能从实参列表的尾部开始被省略,在一个有默认值的参数之后的所有参数 都不得不也具有默认值(尽管使用命名参数记法可以允许放松这种限制, - 这种限制仍然会被强制以便位置参数记法能工作)。不管你是否使用它,这种能力都要求在某些用户不信任其他用户的数据中调用函数时做一些预防措施,见。 + 这种限制仍然会被强制以便位置参数记法能工作)。不管你是否使用它,这种能力都要求在某些用户不信任其他用户的数据库中调用函数时做一些预防措施,见 @@ -775,13 +768,13 @@ ERROR: function foo() does not exist 所有的 SQL 函数都可以被用在查询的FROM子句中,但是 - 对于返回复合类型的函数特别有用。如果函数被定义为返回一种基本类型, + 对于返回复合类型的函数特别有用。如果函数被定义为返回一种基础类型, 该表函数会产生一个单列表。如果该函数被定义为返回一种复合类型,该 表函数会为该复合类型的每一个属性产生一列。 - 以下是一个示例: + 以下是一个示例: CREATE TABLE foo (fooid int, foosubid int, fooname text); @@ -814,8 +807,8 @@ SELECT *, upper(fooname) FROM getfoo(1) AS t1; 返回集合的<acronym>SQL</acronym>函数 - function - with SETOF + 函数 + 使用 SETOF @@ -948,7 +941,7 @@ SELECT x, generate_series(1,5) AS g FROM tab; SELECT x, g FROM tab, LATERAL generate_series(1,5) AS g; - 这会是完全一样的,除了在这个特别的示例中,规划器会选择把g放在嵌套循环连接的外侧,因为gtab没有实际的横向依赖。那会导致一种不同的输出行顺序。选择列表中的集合返回函数总是会被计算,就好像它们在FROM子句剩余部分的嵌套循环连接的内侧一样,因此在考虑来自FROM子句的下一行之前,这些函数会运行到完成。 + 这会是完全一样的,除了在这个特别的示例中,规划器可以选择把g放在嵌套循环连接的外侧,因为gtab没有实际的横向依赖。那会导致一种不同的输出行顺序。选择列表中的集合返回函数总是会被计算,就好像它们在FROM子句剩余部分的嵌套循环连接的内侧一样,因此在考虑来自FROM子句的下一行之前,这些函数会运行到完成。 @@ -968,15 +961,11 @@ SELECT srf1(srf2(x), srf3(y)), srf4(srf5(z)) FROM tab; SELECT x, CASE WHEN x > 0 THEN generate_series(1, 5) ELSE 0 END FROM tab; - 看起来这个语句应该产生满足x > 0的输入行的五次重复,以及不满足的行的一次重复。但实际上,由于在CASE表达时被计算前,generate_series(1, 5)会被运行在一个隐式的LATERAL FROM项中,它会为每个输入行产生五次重复。为了减少混乱,这类情况会产生一个解析时错误。 + 看起来这个语句应该产生满足x > 0的输入行的五次重复,以及不满足的行的一次重复。但实际上,由于在CASE表达式被计算前,generate_series(1, 5)会被运行在一个隐式的LATERAL FROM项中,它会为每个输入行产生五次重复。为了减少混乱,这类情况会产生一个解析时错误。 - - 如果一个函数的最后一条命令是带有 RETURNING 子句的 - INSERTUPDATE、 - DELETEMERGE,那么即使该函数没有声明为 SETOF,或者调用它的查询并未取走全部结果行,该命令也总会执行到完成。RETURNING 子句产生的额外结果行会被静默丢弃,但相应的表修改仍然会发生,并且会在函数返回前全部完成。 - + 如果一个函数的最后一条命令是 INSERTUPDATEDELETE 并带有 RETURNING,那么即使该函数没有声明为 SETOF,或者调用它的查询并未取走全部结果行,该命令也总会执行到完成。RETURNING 子句产生的额外结果行会被静默丢弃,但相应的表修改仍然会发生,并且会在函数返回前全部完成。 @@ -984,11 +973,11 @@ SELECT x, CASE WHEN x > 0 THEN generate_series(1, 5) ELSE 0 END FROM tab; 在 PostgreSQL 10 之前,除非多个集合返回函数始终产生相同数量的行,否则把它们放在同一个选择列表中的行为并不合理。 否则,得到的输出行数会是这些集合返回函数各自产生行数的最小公倍数。 此外,嵌套的集合返回函数也不像上文所描述的那样工作;相反,一个集合返回函数至多只能有一个集合返回参数, - 并且每一层嵌套都会独立运行。再加上过去还允许条件执行(即在 CASE 等结构内部使用集合返回函数), + 并且每一组嵌套的集合返回函数都会独立运行。再加上过去还允许条件执行(即在 CASE 等结构内部使用集合返回函数), 事情就更加复杂了。 如果你要编写需要在旧版 PostgreSQL 上运行的查询,建议使用 LATERAL 语法, 因为这样在不同版本之间能够得到一致的结果。 - 如果你的查询依赖于集合返回函数的条件执行,可以把条件判断移动到自定义集合返回函数内部来修复。例如, + 如果你的查询依赖于集合返回函数的条件执行,或许可以把条件判断移动到自定义集合返回函数内部来修复。例如, SELECT x, CASE WHEN y > 0 THEN generate_series(1, z) ELSE 5 END FROM tab; @@ -1006,7 +995,7 @@ END$$ LANGUAGE plpgsql; SELECT x, case_generate_series(y > 0, 1, z, 5) FROM tab; - 这种写法在所有版本的 PostgreSQL 中都能正常工作。 + 这种写法在所有版本的 PostgreSQL 中的行为都相同。 @@ -1015,7 +1004,7 @@ SELECT x, case_generate_series(y > 0, 1, z, 5) FROM tab; 返回<literal>TABLE</literal>的<acronym>SQL</acronym>函数 - function + 函数 RETURNS TABLE @@ -1064,10 +1053,9 @@ SELECT make_array(1, 2) AS intarray, make_array('a'::text, 'b') AS textarray; 注意类型转换'a'::text的使用是为了指定该参数的类型 - 是text。如果该参数只是一个字符串这就是必须的,因为 + 是text。如果该参数只是一个字符串字面量,这就是必须的,因为 否则它会被当作unknown类型,并且 - unknown的数组也不是一种合法的类型。如果没有改类型 - 类型转换,将得到这样的错误: + unknown的数组也不是一种合法的类型。如果没有该类型转换,将得到这样的错误: ERROR: could not determine polymorphic type because input has type unknown @@ -1138,7 +1126,7 @@ SELECT * FROM dup(22); - 多态也可以用于 variadic 函数。例如: + 多态也可以用于可变参数函数。例如: CREATE FUNCTION anyleast (VARIADIC anyarray) RETURNS anyelement AS $$ SELECT min($1[i]) FROM generate_subscripts($1, 1) g(i); @@ -1173,14 +1161,14 @@ SELECT concat_values('|', 1, 4, 2); 带有排序规则的<acronym>SQL</acronym>函数 - collation - in SQL functions + 排序规则 + 在 SQL 函数中 - 当一个 SQL 函数有一个或多个可设定排序规则的数据类型参数时,会按 - 中的说明,为每次函数调用确定一个排序规则。 - 如果能够成功确定(也就是说,参数之间不存在隐式排序规则冲突),那么所有可设定排序规则的参数都会被视为隐式带有该排序规则。 + 当一个 SQL 函数有一个或多个支持排序规则的数据类型参数时,会按 + 中的说明,根据分配给实参的排序规则,为每次函数调用确定一个排序规则。 + 如果能够成功确定(也就是说,参数之间不存在隐式排序规则冲突),那么所有支持排序规则的参数都会被视为隐式带有该排序规则。 这会影响函数中对排序规则敏感的操作的行为。例如,使用上文的 anyleast 函数时, SELECT anyleast('abc'::text, 'ABC'); @@ -1200,7 +1188,7 @@ CREATE FUNCTION anyleast (VARIADIC anyarray) RETURNS anyelement AS $$ SELECT min($1[i] COLLATE "en_US") FROM generate_subscripts($1, 1) g(i); $$ LANGUAGE SQL; - 但请注意,如果把它用于不可设定排序规则的数据类型,就会抛出错误。 + 但请注意,如果把它用于不支持排序规则的数据类型,就会抛出错误。 @@ -1209,7 +1197,7 @@ $$ LANGUAGE SQL; - 这种可设定排序规则参数的行为,可以看作是仅适用于文本数据类型的一种受限多态形式。 + 这种支持排序规则的参数的行为,可以看作是仅适用于文本数据类型的一种受限多态形式。 @@ -1218,13 +1206,13 @@ $$ LANGUAGE SQL; 函数重载 - overloading - functions + 重载 + 函数 可以用同样的 SQL 名称定义多于一个函数,只要它们的参数不同即可。 - 换句话说,函数名可以被重载。不管你是否使用它,这种能力都要求在某些用户不信任其他用户的数据中调用函数时做一些预防措施,见。当一个查询 + 换句话说,函数名可以被重载。不管你是否使用它,这种能力都要求在某些用户不信任其他用户的数据库中调用函数时采取安全预防措施,见。当一个查询 被执行时,服务器将从数据类型和所提供的参数个数来决定要调用哪个 函数。重载也可用来模拟具有可变参数个数(最大个数有限)的函数。 @@ -1251,10 +1239,10 @@ CREATE FUNCTION test(smallint, double precision) RETURNS ... - 另一类可能的冲突发生在 variadic 函数和非 variadic 函数之间。例如,可以同时创建 + 另一类可能的冲突发生在可变参数函数和非可变参数函数之间。例如,可以同时创建 foo(numeric)foo(VARIADIC numeric[])。 这时,对于只提供一个 numeric 参数的调用(例如 foo(10.1)),就不清楚该匹配哪个函数。 - 规则是:优先使用在搜索路径中出现较早的那个函数;如果两者位于同一模式中,则优先使用非 variadic 函数。 + 规则是:优先使用在搜索路径中出现较早的那个函数;如果两者位于同一模式中,则优先使用非可变参数函数。 @@ -1281,8 +1269,8 @@ CREATE FUNCTION test(int, int) RETURNS int 函数易变性分类 - volatility - functions + 易变性 + 函数 VOLATILE @@ -1304,7 +1292,7 @@ CREATE FUNCTION test(int, int) RETURNS int 一个VOLATILE函数可以做任何事情,包括修改数据库。在 使用相同的参数连续调用时,它能返回不同的结果。优化器不会对这类函 - 数的行为做任何假定。对于在每一行都需要 volatile 函数值的查询,函数都会被重新求值。 + 数的行为做任何假定。使用易变函数的查询会在需要该函数值的每一行上重新对它求值。 @@ -1352,8 +1340,7 @@ CREATE FUNCTION test(int, int) RETURNS int 在考虑先规划然后立即执行的简单交互式查询时,在STABLEIMMUTABLE分类间的区别相对较小:一个函数是在规划时只 执行一次还是在查询执行开始期间只执行一次没有太大关系。但是如果计划 - 被保存下来然后在后面被重用,区别就大了。如果在不允许过早把一个函数 - 变成规划期间的一个常数时把它标记为IMMUTABLE,会导致 + 被保存下来然后在后面被重用,区别就大了。如果把一个实际上并非不可变的函数标记为IMMUTABLE,就可能在规划期间过早将它折叠成常量,导致 在后续重用该计划时继续使用陈旧的值。在使用预备语句,或使用会缓存执行计划的函数语言(如 PL/pgSQL)时,这会带来严重问题。 @@ -1421,7 +1408,7 @@ CREATE FUNCTION test(int, int) RETURNS int 内部函数 - functioninternal + 函数内部 内部函数由 C 编写并且已经被静态链接到PostgreSQL @@ -1459,9 +1446,9 @@ CREATE FUNCTION square_root(double precision) RETURNS double precision C 语言函数 - function - user-defined - in C + 函数 + 用户定义的 + 在 C 中 @@ -1485,17 +1472,17 @@ CREATE FUNCTION square_root(double precision) RETURNS double precision - 在一个会话中第一次调用一个特定可载入对象文件中的用户定义函数时, - 动态载入器会把那个对象文件载入到内存以便该函数被调用。因此用户 + 在一个会话中第一次调用一个特定可载入目标文件中的用户定义函数时, + 动态载入器会把那个目标文件载入到内存以便该函数被调用。因此用户 定义的 C 函数的CREATE FUNCTION必须 - 为该函数指定两块信息:可载入对象文件的名称,以及要在该对象文件中 + 为该函数指定两块信息:可载入目标文件的名称,以及要在该目标文件中 调用的特定函数的 C 名称(链接符号)。如果没有显式指定 C 名称,则 它被假定为和 SQL 函数名相同。 下面的算法被用来基于CREATE FUNCTION - 命令中给定的名称来定位共享对象文件: + 命令中给定的名称来定位共享目标文件: @@ -1554,66 +1541,48 @@ CREATE FUNCTION square_root(double precision) RETURNS double precision PostgreSQL不会自动编译 C 函数。在 - 从CREATE FUNCTION命令中引用对象文件 + 从CREATE FUNCTION命令中引用目标文件 之前,它必须先被编译好。更多信息请见 - magic block - - - PG_MODULE_MAGIC + 魔数块 - 为确保动态装载的对象文件不会被加载到不兼容的服务器中,PostgreSQL 会检查该文件是否包含内容正确的magic block。这样服务器就能检测出明显的不兼容情况,例如代码是针对另一个 PostgreSQL 主版本编译的。要加入 magic block,请在模块某一个(且只能一个)源文件中,在包含头文件 fmgr.h 之后写入: + 为确保动态装载的目标文件不会被加载到不兼容的服务器中,PostgreSQL 会检查该文件是否包含内容正确的魔数块。这样服务器就能检测出明显的不兼容情况,例如代码是针对另一个 PostgreSQL 主版本编译的。要加入魔数块,请在模块某一个(且只能一个)源文件中,在包含头文件 fmgr.h 之后写入: PG_MODULE_MAGIC; - -或者 - -PG_MODULE_MAGIC_EXT(parameters); - PG_MODULE_MAGIC_EXT 这种形式允许为模块指定附加信息;目前可以添加名称和/或版本字符串。(将来可能允许更多字段。)可以写成这样: - - -PG_MODULE_MAGIC_EXT( - .name = "my_module_name", - .version = "1.2.3" -); - - - 之后,名称和版本可以通过 pg_get_loaded_modules() 函数查看。版本字符串的具体含义不受 PostgreSQL 限制,但建议采用语义化版本规则。 - - - - 在第一次使用之后,动态载入对象文件会保留在内存中。在同一个会话中, + 在第一次使用之后,动态载入目标文件会保留在内存中。在同一个会话中, 后续对该文件中函数的调用只需付出一次很小的符号表查找开销。如果需要 - 强制重新载入一个对象文件(例如在重新编译之后),就需要开启一个新的会话。 + 强制重新载入一个目标文件(例如在重新编译之后),就需要开启一个新的会话。 _PG_init + + _PG_fini + 库初始化函数 + + 库终结函数 + - - 可选地,一个动态加载的文件可以包含一个初始化函数。如果文件包含一个名为 - _PG_init的函数,那个函数将在加载文件后立即被调用。 - 该函数不接收任何参数,应该返回void。目前没有办法卸载一个动态加载的文件。 - + 动态装载的文件可以选择包含初始化和终结函数。如果文件包含一个名为 _PG_init 的函数,该函数会在文件装载后立即被调用。该函数不接收参数,并且应返回 void。如果文件包含一个名为 _PG_fini 的函数,该函数会在文件卸载前立即被调用。同样,该函数不接收参数,并且应返回 void。注意,_PG_fini 只会在卸载文件时被调用,而不会在进程终止时被调用。(目前,卸载已被禁用,永远不会发生,但将来可能会改变。) - C 语言函数中的基本类型 + C 语言函数中的基础类型 数据类型 @@ -1622,16 +1591,16 @@ PG_MODULE_MAGIC_EXT( 要了解如何编写 C 语言函数,你需要了解 - PostgreSQL如何在内部表达基本数据类型 + PostgreSQL如何在内部表达基础类型 以及如何与函数传递它们。在内部, - PostgreSQL把基本类型视为一块内存数据块。 + PostgreSQL把基础类型视为一块内存数据块。 你为该类型定义的用户自定义函数,决定了 PostgreSQL 如何操作它。 也就是说,PostgreSQL 只负责把数据存到磁盘、再从磁盘取回, 而数据的输入、处理和输出则依赖你定义的这些函数。 - 基本类型可以有三种内部格式之一: + 基础类型可以有三种内部格式之一: @@ -1696,10 +1665,9 @@ typedef struct 最后,所有变长类型必须也以引用的方式传递。所有变长类型必须用一个 - 正好 4 字节的不透明长度域开始,该域会由SET_VARSIZE - 设置,绝不要直接设置该域!所有要被存储在该类型中的数据必须在内存 - 中接着该长度域的后面存储。长度域包含该结构体的总长度,也就是包括长 - 度域本身的尺寸。 + 正好 4 字节的不透明长度字段开始,该字段会由SET_VARSIZE + 设置,绝不要直接设置该字段!所有要被存储在该类型中的数据必须在内存 + 中接着该长度字段的后面存储。长度字段包含该结构体的总长度,也就是包括长度字段本身的尺寸。 @@ -1749,16 +1717,16 @@ memcpy(destination->data, buffer, 40); VARHDRSZsizeof(int32)一样, - 但是用宏VARHDRSZ来引用变长类型的载荷的 + 但是用宏VARHDRSZ来引用变长类型的额外开销的 尺寸被认为是比较好的风格。还有,必须 - 使用SET_VARSIZE宏来设置长度域,而不是用 + 使用SET_VARSIZE宏来设置长度字段,而不是用 简单的赋值来设置。 展示了 PostgreSQL 中许多内置 SQL 数据类型所对应的 C 类型。 - Defined In列给出了需要包含的头文件,以获取类型定义。 + 定义文件列给出了需要包含的头文件,以获取类型定义。 (实际的定义可能位于所列文件包含的其他文件中。建议用户坚持使用已定义的接口。) 请注意,在服务器代码的任何源文件中,都应该始终首先包含postgres.h, 因为它声明了很多你反正都会用到的内容,而且先包含其他头文件可能会带来可移植性问题。 @@ -1934,8 +1902,7 @@ memcpy(destination->data, buffer, 40); - 现在我们已经复习了基本类型所有可能的结构,现在可以展示一些 - 真实函数的示例了。 + 了解了基础类型所有可能的结构后,就可以看一些实际函数示例。 @@ -1943,7 +1910,7 @@ memcpy(destination->data, buffer, 40); 版本 1 的调用约定 - 版本-1 的调用规范依赖于宏来降低传参数和结果的复杂度。版本-1 函数的 + 版本-1 的调用约定依赖于宏来降低传参数和结果的复杂度。版本-1 函数的 C 声明总是: Datum funcname(PG_FUNCTION_ARGS) @@ -1955,35 +1922,11 @@ PG_FUNCTION_INFO_V1(funcname); 必须出现在同一个源文件中(按惯例会正好写在该函数本身之前)。 这种宏调用不是internal语言函数所需要的,因为 PostgreSQL会假定所有内部函数都使用 - 版本-1 规范。不过,对于动态载入函数是必需的。 - - - - 在版本-1 函数中,每一个实参都使用对应于该参数数据类型的PG_GETARG_xxx()宏取得。(在非严格的函数中,需要使用PG_ARGISNULL()对参数是否为空提前做检查;见下文。)结果要用对应于返回类型的PG_RETURN_xxx()宏返回。PG_GETARG_xxx()的参数是要取得的函数参数的编号,从零开始计。PG_RETURN_xxx()的参数是实际要返回的值。 - - - - 要调用另一个版本-1 函数,你可以使用 - DirectFunctionCalln(func, - arg1, ..., argn)。这在你想调用标准内部库中定义的函数时尤其有用,因为它提供了与其 SQL 签名相似的接口。 - - - - 这些便利函数以及类似函数都可以在 fmgr.h 中找到。 - DirectFunctionCalln 系列把 C 函数名作为其第一个参数。另有 - OidFunctionCalln 等一些变体,它们接收目标函数的 OID。所有这些函数都要求以 Datum 形式提供函数参数,返回值也同样是 Datum。注意,使用这些便利函数时,参数和结果都不能为 NULL。 - - - - 例如,要在 C 中调用 starts_with(text, text),你可以在系统目录中查到它的 C 实现是 - Datum text_starts_with(PG_FUNCTION_ARGS) - 函数。通常你会用 DirectFunctionCall2(text_starts_with, ...) 来调用它。不过,starts_with(text, - text) 需要排序规则信息,因此如果这样调用,会因无法确定字符串比较该使用哪一种排序规则而失败。你必须改用 DirectFunctionCall2Coll(text_starts_with, ...), - 并提供所需的排序规则,通常就是从 PG_GET_COLLATION() 传递进来,如下面的示例所示。 + 版本-1 调用约定。不过,对于动态载入函数是必需的。 - fmgr.h 还提供了便于在 C 类型和 Datum 之间转换的宏。例如,要把 Datum 转成 text*,可以使用 DatumGetTextPP(X)。虽然某些类型为反向转换提供了名为 TypeGetDatum(X) 之类的宏,但 text* 没有;对它而言,直接使用通用宏 PointerGetDatum(X) 即可。如果你的扩展定义了额外的类型,通常也很方便为这些类型定义类似的宏。 + 在版本-1 函数中,每一个实参都使用对应于该参数数据类型的PG_GETARG_xxx()宏取得。(在非严格的函数中,需要使用PG_ARGISNULL()对参数是否为空值提前做检查;见下文。)结果要用对应于返回类型的PG_RETURN_xxx()宏返回。PG_GETARG_xxx()的参数是要取得的函数参数的编号,从零开始计。PG_RETURN_xxx()的参数是实际要返回的值。 @@ -1995,7 +1938,6 @@ PG_FUNCTION_INFO_V1(funcname); #include #include "fmgr.h" #include "utils/geo_decls.h" -#include "varatt.h" PG_MODULE_MAGIC; @@ -2061,8 +2003,8 @@ copytext(PG_FUNCTION_ARGS) * VARDATA is a pointer to the data region of the new struct. The source * could be a short datum, so retrieve its data through VARDATA_ANY. */ - memcpy(VARDATA(new_t), /* destination */ - VARDATA_ANY(t), /* source */ + memcpy((void *) VARDATA(new_t), /* destination */ + (void *) VARDATA_ANY(t), /* source */ VARSIZE_ANY_EXHDR(t)); /* how many bytes */ PG_RETURN_TEXT_P(new_t); } @@ -2084,25 +2026,6 @@ concat_text(PG_FUNCTION_ARGS) memcpy(VARDATA(new_text) + arg1_size, VARDATA_ANY(arg2), arg2_size); PG_RETURN_TEXT_P(new_text); } - -/* A wrapper around starts_with(text, text) */ - -PG_FUNCTION_INFO_V1(t_starts_with); - -Datum -t_starts_with(PG_FUNCTION_ARGS) -{ - text *t1 = PG_GETARG_TEXT_PP(0); - text *t2 = PG_GETARG_TEXT_PP(1); - Oid collid = PG_GET_COLLATION(); - bool result; - - result = DatumGetBool(DirectFunctionCall2Coll(text_starts_with, - collid, - PointerGetDatum(t1), - PointerGetDatum(t2))); - PG_RETURN_BOOL(result); -} ]]> @@ -2131,10 +2054,6 @@ CREATE FUNCTION copytext(text) RETURNS text CREATE FUNCTION concat_text(text, text) RETURNS text AS 'DIRECTORY/funcs', 'concat_text' LANGUAGE C STRICT; - -CREATE FUNCTION t_starts_with(text, text) RETURNS boolean - AS 'DIRECTORY/funcs', 't_starts_with' - LANGUAGE C STRICT; @@ -2142,11 +2061,11 @@ CREATE FUNCTION t_starts_with(text, text) RETURNS boolean - 注意我们已经把函数指定为strict,这意味着如果有任何输入值为空,系统应该自动假定得到空结果。通过这种做法,我们避免在函数代码中检查空值输入。如果不这样做,我们必须使用PG_ARGISNULL()明确地检查空值输入。 + 注意我们已经把函数指定为strict,这意味着如果有任何输入值为空值,系统应该自动假定结果为空值。通过这种做法,我们避免在函数代码中检查空值输入。如果不这样做,我们必须使用PG_ARGISNULL()明确地检查空值输入。 - 宏PG_ARGISNULL(n)允许一个函数测试是否每一个输入为空(当然,只需要在没有声明为strict的函数中这样做)。和PG_GETARG_xxx()宏一样,输入参数也是从零开始计数。注意应该在验证了一个参数不是空之后才执行PG_GETARG_xxx()。要返回一个空结果,应执行PG_RETURN_NULL(),它对严格的以及非严格的函数都有用。 + 宏PG_ARGISNULL(n)允许一个函数测试是否每一个输入为空值(当然,只需要在没有声明为strict的函数中这样做)。和PG_GETARG_xxx()宏一样,输入参数也是从零开始计数。注意应该在验证了一个参数不是空值之后才执行PG_GETARG_xxx()。要返回空值结果,应执行PG_RETURN_NULL(),它对严格的以及非严格的函数都有用。 @@ -2154,11 +2073,11 @@ CREATE FUNCTION t_starts_with(text, text) RETURNS boolean - 在版本-1接口中提供的其他选项是PG_GETARG_xxx()宏的两个变种。其中的第一种是PG_GETARG_xxx_COPY(),它确保返回的指定参数的拷贝可以被安全地写入(通常的宏有时会返回一个指向表中物理存储的值,它不能被写入。使用PG_GETARG_xxx_COPY()宏可以保证得到一个可写的结果)。第二种变种PG_GETARG_xxx_SLICE()宏有三个参数。第一个是函数参数的编号(如上文)。第二个和第三个是要被返回的段的偏移量和长度。偏移量从零开始计算,而负值的长度则表示要求返回该值的剩余部分。当大型值的存储类型为external时,这些宏提供了访问这些大型值的更有效的方法(列的存储类型可以使用ALTER TABLE tablename ALTER COLUMN colname SET STORAGE storagetype来指定。storagetypeplainexternalextended或者main)。 + 在版本-1接口中提供的其他选项是PG_GETARG_xxx()宏的两个变种。其中的第一种是PG_GETARG_xxx_COPY(),它确保返回的指定参数的拷贝可以被安全地写入(通常的宏有时会返回一个指向表中物理存储值的指针,不能写入该值。使用PG_GETARG_xxx_COPY()宏可以保证得到一个可写的结果)。第二种变种PG_GETARG_xxx_SLICE()宏有三个参数。第一个是函数参数的编号(如上文)。第二个和第三个是要被返回的段的偏移量和长度。偏移量从零开始计算,而负值的长度则表示要求返回该值的剩余部分。当大型值的存储类型为external时,这些宏提供了访问这些大型值的部分内容的更有效方法(列的存储类型可以使用ALTER TABLE tablename ALTER COLUMN colname SET STORAGE storagetype来指定。storagetypeplainexternalextended或者main)。 - 最后,版本-1 的函数调用规范可以返回集合结果()、实现触发器函数()和过程语言调用处理器()。更多细节 + 最后,版本-1 的函数调用约定可以返回集合结果()、实现触发器函数()和过程语言调用处理器()。更多细节 可见源代码发布中的src/backend/utils/fmgr/README @@ -2169,10 +2088,10 @@ CREATE FUNCTION t_starts_with(text, text) RETURNS boolean 在开始更高级的话题之前,我们应该讨论一下用于 PostgreSQL C 语言函数的编码规则。 - 虽然可以把不是 C 编写的函数载入到 - PostgreSQL中,这通常是很困难的, + 虽然有可能把不是 C 编写的函数载入到 + PostgreSQL中,但即使能够做到,通常也很困难, 因为其他语言(例如 C++、FORTRAN 或者 Pascal)通常不会遵循和 C - 相同的调用规范。也就是说,其他语言不会以同样的方式在函数之间传递 + 相同的调用约定。也就是说,其他语言不会以同样的方式在函数之间传递 参数以及返回值。由于这个原因,我们会假定你的 C 语言函数确实是用 C 编写的。 @@ -2184,7 +2103,7 @@ CREATE FUNCTION t_starts_with(text, text) RETURNS boolean 使用 pg_config - --includedir-serverpg_configwith user-defined C functions + --includedir-serverpg_config用于用户定义的 C 函数 查出 PostgreSQL 服务器头文件在你的系统上(或你的用户将要运行的系统上)安装于何处。 @@ -2197,7 +2116,7 @@ CREATE FUNCTION t_starts_with(text, text) RETURNS boolean - 记得按照中的说明,为你的共享库定义一个magic block。 + 记得按照中的说明,为你的共享库定义一个魔数块 @@ -2223,7 +2142,7 @@ CREATE FUNCTION t_starts_with(text, text) RETURNS boolean - 对象文件中定义的符号名不能彼此冲突,也不能与 + 目标文件中定义的符号名不能彼此冲突,也不能与 PostgreSQL 服务器可执行文件中定义的符号冲突。如果你收到这类错误消息,就必须重命名相关函数或变量。 @@ -2233,99 +2152,15 @@ CREATE FUNCTION t_starts_with(text, text) RETURNS boolean &dfunc; - - 服务器 API 和 ABI 稳定性指南 - - - 本节向扩展和其他服务器插件的作者提供有关 - PostgreSQL 服务器 API 与 ABI 稳定性的指导。 - - - - 概述 - - - PostgreSQL 服务器为服务器插件提供了若干边界清晰的 API,例如函数管理器(fmgr,本章已介绍)、SPI)以及专门为扩展设计的各种钩子。这些接口都会被谨慎管理,以保持长期稳定性和兼容性。不过,服务器中的整套全局函数和变量实际上也构成了可公开使用的 API,而其中大部分在设计时并未把可扩展性和长期稳定性作为目标。 - - - - 因此,虽然使用这些接口是完全允许的,但越是偏离那些久经实践考验的路径,将来遇到 API 或 ABI 兼容性问题的可能性就越大。鼓励扩展作者反馈自己的需求,以便随着时间推移和新用法的出现,某些接口能够被视为更稳定,或者可以加入新的、设计更完善的接口。 - - - - - API 兼容性 - - API,即应用程序编程接口,是编译时使用的接口。 - - - - 主版本 - - 在 PostgreSQL 不同主版本之间,不承诺 API 兼容性。因此,扩展代码可能需要修改源代码才能同时支持多个主版本。这类差异通常可以通过预处理器条件来管理。那些使用了边界清晰接口之外能力的复杂扩展,通常每个服务器主版本都需要做少量这类修改。 - - - - - 小版本 - - PostgreSQL 会尽力避免在小版本发布中破坏服务器 API。一般来说,能针对某个小版本编译并正常工作的扩展代码,也应当能够针对同一主版本的其他任意小版本(无论过去还是将来)编译并正常工作。 - - - - 如果确实需要做出变更,也会在考虑扩展需求的前提下谨慎管理。这类变更会在发布说明()中进行说明。 - - - - - - ABI 兼容性 - - ABI,即应用程序二进制接口,是运行时使用的接口。 - - - - 主版本 - - 不同主版本的服务器在 ABI 上是有意不兼容的。因此,使用服务器 API 的扩展必须针对每一个主版本重新编译。包含 PG_MODULE_MAGIC(见)可以确保针对某个主版本编译的代码会被其他主版本拒绝。 - - - - - 小版本 - - PostgreSQL 会尽力避免在小版本发布中破坏服务器 ABI。一般来说,针对任意一个小版本编译的扩展,应当能与同一主版本过去或将来的其他任意小版本一起工作。 - - - - 如果确实需要变更,PostgreSQL 会尽量选择侵入性最小的方式,例如把新字段塞进填充空间,或者附加到结构体末尾。这类修改通常不应影响扩展,除非扩展使用了非常不寻常的代码模式。 - - - - 然而,在极少数情况下,即使是这种非侵入式变更也可能不现实甚至不可能做到。发生这种情况时,也会在考虑扩展需求的前提下谨慎管理该变更。这类变更同样会记录在发布说明()中。 - - - - 但请注意,服务器中有很多部分并不是作为公开可消费的 API 来设计和维护的(而且在大多数情况下,其真实边界也并不清晰)。如果这些部分出现紧急需求,对它们的修改自然会比对那些边界清楚且广泛使用的接口做修改时,更少考虑扩展代码的兼容性。 - - - - 此外,在缺乏自动化检测这类变化的机制时,这并不能构成严格保证;不过从历史上看,这种破坏性变化极为罕见。 - - - - - - 复合类型参数 复合类型没有像 C 结构体那样的固定布局。复合类型的实例可能包含 - 空值域。此外,继承层次中的复合类型可能具有和同一继承层次中 - 其他成员不同的域。因此, + 空值字段。此外,继承层次中的复合类型可能具有和同一继承层次中 + 其他成员不同的字段。因此, PostgreSQL提供了函数接口 - 来访问 C 的复合类型的域。 + 以便从 C 访问复合类型的字段。 @@ -2337,7 +2172,7 @@ SELECT name, c_overpaid(emp, 1500) AS overpaid WHERE name = 'Bill' OR name = 'Sam'; - 如果使用版本-1的调用规范,我们可以定义 + 如果使用版本-1的调用约定,我们可以定义 c_overpaid为: GetAttributeByName 是 - PostgreSQL 的一个系统函数,用于从指定行中取出属性。它有三个参数:传入函数的 HeapTupleHeader 类型参数、所需属性的名称,以及一个用于指示该属性是否为 null 的返回参数。GetAttributeByName 返回一个 Datum 值,你可以用适当的 DatumGetXXX() 函数把它转换为正确的数据类型。注意,如果 null 标志被设置,那么返回值本身没有意义;在尝试对结果做任何处理之前,务必先检查这个 null 标志。 + PostgreSQL 的一个系统函数,用于从指定行中取出属性。它有三个参数:传入函数的 HeapTupleHeader 类型参数、所需属性的名称,以及一个用于指示该属性是否为 null 的返回参数。GetAttributeByName 返回一个 Datum 值,你可以用适当的 DatumGetXXX() 宏把它转换为正确的数据类型。注意,如果 null 标志被设置,那么返回值本身没有意义;在尝试对结果做任何处理之前,务必先检查这个 null 标志。 也有GetAttributeByNum函数,它可以用目标属性 - 的属性号而不是属性名来选择目标属性。 + 的列号而不是属性名来选择目标属性。 @@ -2396,14 +2231,14 @@ CREATE FUNCTION c_overpaid(emp, integer) RETURNS boolean 要从 C 语言函数中返回一行或一个复合类型值,可以使用一套特殊的 API, - 它通过一组宏和函数隐藏了构造组合数据类型时的大部分复杂性。要使用这套 API,源文件中必须包含: + 它通过一组宏和函数隐藏了构造复合数据类型时的大部分复杂性。要使用这套 API,源文件中必须包含: #include "funcapi.h" - 构造组合数据值(下文简称元组)有两种方式: + 构造复合数据值(下文简称元组)有两种方式: 一种是从 Datum 值数组构造,另一种是从 C 字符串数组构造,这些字符串会传给该元组各列数据类型的输入转换函数。 无论采用哪种方式,首先都需要获取或构造描述该元组结构的 TupleDesc。 处理 Datum 时,需要把 TupleDesc 传给 BlessTupleDesc,然后为每一行调用 heap_form_tuple。 @@ -2412,13 +2247,13 @@ CREATE FUNCTION c_overpaid(emp, integer) RETURNS boolean - 有一些辅助函数可以用来设置所需的 TupleDesc。在大多数返回组合值的函数中,推荐的做法是调用: + 有一些辅助函数可以用来设置所需的 TupleDesc。在大多数返回复合值的函数中,推荐的做法是调用: TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc) - 传入与调用函数本身相同的 fcinfo 结构体(这当然要求使用版本 1 调用约定)。 + 传入调用函数本身收到的同一个 fcinfo 结构体(这当然要求使用版本 1 调用约定)。 resultTypeId 可以指定为 NULL,也可以指定为一个本地变量的地址,用于接收函数结果类型的 OID。 resultTupleDesc 应当是一个本地 TupleDesc 变量的地址。 检查返回结果是否为 TYPEFUNC_COMPOSITE;如果是,resultTupleDesc 就会被填入所需的 TupleDesc。 @@ -2437,7 +2272,7 @@ TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, get_call_result_type有一个兄弟 get_expr_result_type,它被用来解析被表示为一棵表达式 - 树的函数调用的输出类型。在尝试确定来自函数外部的结果类型时可以用它。 + 树的函数调用的输出类型。在尝试从函数自身外部确定结果类型时可以用它。 也有一个get_func_result_type,当只有函数的 OID 可用时 可以用它。不过这些函数无法处理被声明为返回record的 函数,并且get_func_result_type无法解析多态类型,因此你 @@ -2446,22 +2281,22 @@ TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, - 更早、现在已被废弃的获取TupleDesc的函数有: + 更早、现在已被弃用的获取TupleDesc的函数有: TupleDesc RelationNameGetTupleDesc(const char *relname) - 它可以为一个提到的关系的行类型得到TupleDesc, + 它可以为一个指定名称的关系的行类型得到TupleDesc, 还有: TupleDesc TypeGetTupleDesc(Oid typeoid, List *colaliases) 可以基于一个类型 OID 得到TupleDesc。这可以被用来 - 为一种基础或者复合类型获得TupleDesc。不过,对于 + 为一种基本或者复合类型获得TupleDesc。不过,对于 返回record的函数它不起作用,并且它无法解析多态类型。 - 一旦有了一个TupleDesc,如果计划处理 Datum可以调用: + 一旦有了一个TupleDesc,如果计划处理 Datum,可以调用: TupleDesc BlessTupleDesc(TupleDesc tupdesc) @@ -2471,7 +2306,7 @@ AttInMetadata *TupleDescGetAttInMetadata(TupleDesc tupdesc) 如果正在编写一个返回集合的函数,你可以把这些函数的结果保存在 FuncCallContext结构体中 — 分别使用 - tuple_desc或者attinmeta域。 + tuple_desc或者attinmeta字段。 @@ -2491,8 +2326,7 @@ HeapTuple BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values) values是一个 C 字符串数组,每一个元素是返回行 的一个属性。每一个 C 字符串应该是该属性数据类型的输入函数所期望 的格式。为了对一个属性返回空值,values数组中对 - 应的指针应该被设置为NULL。对于你返回的每一行都将 - 再次调用这个函数。 + 应的指针应该被设置为NULL。对于你返回的每一行都需要再次调用这个函数。 @@ -2527,13 +2361,13 @@ HeapTupleGetDatum(HeapTuple tuple) 使用 ValuePerCall 模式时,重要的是要记住查询不能保证运行完成; 也就是说,由于诸如LIMIT之类的选项, - 执行程序可能会在获取所有行之前停止调用 set-returning 函数。 + 执行器可能会在获取所有行之前停止调用集合返回函数。 这意味着在最后一次调用中执行清理活动是不安全的,因为这可能永远不会发生。 对于需要访问外部资源(例如文件描述符)的函数,建议使用 Materialize 模式。 - 本节的其余部分记录了一组使用 ValuePerCall 模式的 SRF 常用(尽管不是必须使用)的帮助程序宏。 + 本节的其余部分记录了一组使用 ValuePerCall 模式的 SRF 常用(尽管不是必须使用)的辅助宏。 有关 Materialize 模式的其他详细信息可以在src/backend/utils/fmgr/README中找到。 此外,PostgreSQL源代码分发中的contrib 模块包含许多使用 ValuePerCall 和 Materialize 模式的 SRF 示例。 @@ -2542,7 +2376,7 @@ HeapTupleGetDatum(HeapTuple tuple) 要使用此处描述的 ValuePerCall 支持宏,请包含funcapi.h。 这些宏与结构体FuncCallContext一起使用,该结构体包含需要跨调用保存的状态。 - 在调用 SRF 中,fcinfo->flinfo->fn_extra用于在调用之间保存 + 在使用这些宏的 SRF 中,fcinfo->flinfo->fn_extra用于在调用之间保存 指向FuncCallContext的指针。 宏在第一次使用时自动填充该字段,并期望在后续使用中找到相同的指针。 @@ -2575,7 +2409,7 @@ typedef struct FuncCallContext /* * 可选:指向包含属性类型输入元数据的结构的指针 * - * attinmeta 被用在返回元组(即组合数据类型)时,在返回基本数据类型 + * attinmeta 被用在返回元组(即复合数据类型)时,在返回基础类型 * 时不会使用。只有想用BuildTupleFromCStrings()创建返回元组时才需要它。 */ AttInMetadata *attinmeta; @@ -2592,7 +2426,7 @@ typedef struct FuncCallContext /* * 可选:指向包含元组描述的结构的指针 * - * tuple_desc 被用在返回元组(即组合数据类型)时,并且只有在用 + * tuple_desc 被用在返回元组(即复合数据类型)时,并且只有在用 * heap_form_tuple() 而不是 BuildTupleFromCStrings() 构建元组时才需要它。 * 注意这里存储的 TupleDesc 指针通常已经被先运行过 BlessTupleDesc()。 */ @@ -2696,7 +2530,7 @@ my_set_returning_function(PG_FUNCTION_ARGS) else { /* 这里已经完成了项的返回,所以只报告事实。 */ - /* (不要将清理代码放在这里的。) */ + /* (不要将清理代码放在这里。) */ SRF_RETURN_DONE(funcctx); } } @@ -2729,7 +2563,7 @@ retcomposite(PG_FUNCTION_ARGS) oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); /* 要返回的元组总数 */ - funcctx->max_calls = PG_GETARG_INT32(0); + funcctx->max_calls = PG_GETARG_UINT32(0); /* 为我们的结果类型构建一个元组描述符 */ if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) @@ -2776,7 +2610,7 @@ retcomposite(PG_FUNCTION_ARGS) /* 构建一个元组 */ tuple = BuildTupleFromCStrings(attinmeta, values); - /* 将元组转换为数据 */ + /* 将元组转换为 datum */ result = HeapTupleGetDatum(tuple); /* 清理(这实际上并不是必要的) */ @@ -2832,10 +2666,10 @@ CREATE OR REPLACE FUNCTION retcomposite(IN integer, IN integer, fcinfo->flinfo访问。参数argnum则是从零 开始计。get_call_result_type也可被用作 get_fn_expr_rettype的一种替代品。还有 - get_fn_expr_variadic,它可以被用来找出 variadic 参数 + get_fn_expr_variadic,它可以被用来找出可变参数 是否已经被合并到了一个数组中。这主要用于 VARIADIC "any"函数,因为对于接收普通数组类型的 - variadic 函数来说总是会发生这类合并。 + 可变参数函数来说总是会发生这类合并。 @@ -2903,7 +2737,7 @@ CREATE FUNCTION make_array(anyelement) RETURNS anyarray 它与 anyelement 类似,但不会要求不同的 "any" 参数必须是同一种类型,也不会帮助确定函数的结果类型。 C 语言函数还可以把最后一个参数声明为 VARIADIC "any"。 这可以匹配一个或多个任意类型的实参(不必是同一种类型)。 - 这些参数不会像普通 variadic 函数那样被收集成一个数组,而是会单独传给函数。 + 这些参数不会像普通可变参数函数那样被收集成一个数组,而是会单独传给函数。 使用这种特性时,必须结合 PG_NARGS() 宏以及前面介绍的方法来确定实参的个数和类型。 此外,这种函数的用户也可能希望在函数调用中使用 VARIADIC 关键字,以便让函数把数组元素当作独立参数处理。 如果希望支持这种行为,函数本身就必须在使用 get_fn_expr_variadic 检测到实参被标记为 VARIADIC 后自行实现它。 @@ -2911,324 +2745,32 @@ CREATE FUNCTION make_array(anyelement) RETURNS anyarray - 共享内存 - - - 启动时请求共享内存 - - - 插件可以在服务器启动时预留共享内存。要做到这一点,插件的共享库必须通过 - shared_preload_libraries - 预加载。该共享库还应当在其 _PG_init 函数中注册 - shmem_request_hook。这个 - shmem_request_hook 可以通过调用: - -void RequestAddinShmemSpace(Size size) - - 来预留共享内存。每个后端都应当通过调用: - -void *ShmemInitStruct(const char *name, Size size, bool *foundPtr) - - 来获取指向这块预留共享内存的指针。如果该函数把 - foundPtr 设为 false,调用者就应初始化这块预留共享内存的内容;如果 foundPtrtrue,说明该共享内存已经由其他后端初始化过,调用者无需再做初始化。 - + 共享内存与 LWLocks - - 为避免竞争条件,每个后端在初始化其共享内存分配时都应使用 LWLock - AddinShmemInitLock,如下所示: - + 附加模块可以在服务器启动时预留 LWLock 和一块共享内存。附加模块的共享库必须通过在以下参数中指定它来预装载:shared_preload_libraries。共享内存可以通过下面的调用来预留: +void RequestAddinShmemSpace(int size) +该调用应放在你的 _PG_init 函数中。 + LWLock 可以通过下面的调用来预留: +void RequestNamedLWLockTranche(const char *tranche_name, int num_lwlocks) +该调用应放在 _PG_init 中。这样可以确保一个包含 num_lwlocks 个 LWLock 的数组可通过以下名称访问:tranche_name。使用 GetNamedLWLockTranche 可以取得指向该数组的指针。 + 为避免可能的竞争条件,每个后端都应使用 LWLock AddinShmemInitLock 来连接和初始化分配给它的共享内存,如下所示: static mystruct *ptr = NULL; -bool found; + +if (!ptr) +{ + bool found; LWLockAcquire(AddinShmemInitLock, LW_EXCLUSIVE); ptr = ShmemInitStruct("my struct name", size, &found); if (!found) { - ... initialize contents of shared memory ... + initialize contents of shmem area; + acquire any requested LWLocks using: ptr->locks = GetNamedLWLockTranche("my tranche name"); } LWLockRelease(AddinShmemInitLock); - - shmem_startup_hook 为初始化代码提供了一个方便的位置,但并不强制要求所有这类代码都放在这个钩子中。在 Windows 上(以及任何定义了 EXEC_BACKEND 的平台上),每个后端都会在附加到共享内存后不久执行已注册的 shmem_startup_hook,因此插件在该钩子中仍应像上例那样获取 AddinShmemInitLock。在其他平台上,只有 postmaster 进程会执行 shmem_startup_hook,每个后端会自动继承这些共享内存指针。 - - - - shmem_request_hook 与 - shmem_startup_hook 的一个完整示例可见于 - PostgreSQL 源代码树中的 - contrib/pg_stat_statements/pg_stat_statements.c。 - - - - - 启动后请求共享内存 - - - 还有另一种更灵活的预留共享内存的方法,可以在服务器启动之后、并且无需借助 - shmem_request_hook 来完成。为此,每个需要使用该共享内存的后端都应通过调用以下函数来获取一个指针: - -void *GetNamedDSMSegment(const char *name, size_t size, - void (*init_callback) (void *ptr), - bool *found) - - 如果给定名称的动态共享内存段尚不存在,该函数会分配该段,并使用提供的 - init_callback 回调函数对其进行初始化。如果该段已经由另一个后端分配并初始化过,该函数就只会把现有的动态共享内存段附加到当前后端。 - - - - 与在服务器启动时预留的共享内存不同,使用 - GetNamedDSMSegment 预留共享内存时,不需要获取 - AddinShmemInitLock,也不需要采取其他措施来避免竞争条件。该函数会确保只有一个后端分配并初始化该内存段,而其他所有后端都会获得指向同一块已完全分配并初始化好的内存段的指针。 - - - - GetNamedDSMSegment 的完整使用示例可见于 - src/test/modules/test_dsm_registry/test_dsm_registry.c - ,位于 PostgreSQL 源代码树中。 - - - - - - LWLocks - - - 启动时请求 LWLocks - - - 插件可以在服务器启动时预留 LWLocks。与在服务器启动时预留共享内存一样,插件的共享库必须通过 - shared_preload_libraries - 预加载,并且共享库应在其 _PG_init 函数中注册 - shmem_request_hook。这个 - shmem_request_hook 可以通过调用以下函数来预留 LWLocks: - -void RequestNamedLWLockTranche(const char *tranche_name, int num_lwlocks) - - 这样可以确保在名为 tranche_name 的 tranche 下提供一组数量为 num_lwlocks 的 LWLocks。可以通过调用以下函数获得指向这组 LWLocks 的指针: - -LWLockPadded *GetNamedLWLockTranche(const char *tranche_name) - - - - - - 启动后请求 LWLocks - - - 还有另一种更灵活的获取 LWLocks 的方法,可以在服务器启动后进行,也无需借助 - shmem_request_hook。为此,首先通过调用下面的函数分配一个 - tranche_id: - -int LWLockNewTrancheId(void) - - 接下来,初始化每个 LWLock,并把新的 - tranche_id 作为参数传入: - -void LWLockInitialize(LWLock *lock, int tranche_id) - - 与共享内存类似,每个后端都应确保只有一个进程会分配新的 - tranche_id 并初始化每一个新的 LWLock。一种做法是仅在持有 - AddinShmemInitLock 独占锁的共享内存初始化代码中调用这些函数。如果使用 - GetNamedDSMSegment,那么在 - init_callback 回调函数中调用这些函数就足以避免竞争条件。 - - - - 最后,每个使用该 tranche_id 的后端都应通过调用以下函数把它与一个 tranche_name 关联起来: - -void LWLockRegisterTranche(int tranche_id, const char *tranche_name) - - - - - LWLockNewTrancheId、 - LWLockInitialize 和 - LWLockRegisterTranche 的完整使用示例可见于 - PostgreSQL 源代码树中的 - contrib/pg_prewarm/autoprewarm.c。 - - - - - - 自定义等待事件 - - - 插件可以通过调用以下函数,在等待事件类型 - Extension 下定义自定义等待事件: - -uint32 WaitEventExtensionNew(const char *wait_event_name) - - 该等待事件会关联到一个面向用户的自定义字符串。示例可见于 - src/test/modules/worker_spi,位于 PostgreSQL 源代码树中。 - - - 自定义等待事件可以在 - pg_stat_activity 中查看: - -=# SELECT wait_event_type, wait_event FROM pg_stat_activity - WHERE backend_type ~ 'worker_spi'; - wait_event_type | wait_event ------------------+--------------- - Extension | WorkerSpiMain -(1 row) - - - - - - 注入点 - - - 给定名称 name 的注入点可通过以下宏声明: - -INJECTION_POINT(name, arg); - - - 服务器代码中已经在若干关键位置声明了注入点。新增注入点后,需要重新编译代码,才能让该注入点出现在二进制文件中。用 C 语言编写的插件也可以使用同一个宏在自己的代码中声明注入点。注入点名称应使用小写字母,并用连字符分隔各个术语。arg 是运行时传给回调的可选参数值。 - - - - 执行注入点可能需要分配少量内存,而这可能失败。如果你需要在一个不允许动态分配的临界区中使用注入点,可以采用以下两步法: - -INJECTION_POINT_LOAD(name); -INJECTION_POINT_CACHED(name, arg); - - - 在进入临界区之前,调用 INJECTION_POINT_LOAD。它会检查共享内存状态,并在该注入点处于激活状态时把回调加载到后端私有内存中。在临界区内部,再用 - INJECTION_POINT_CACHED 来执行回调。 - - - - 插件可以通过调用以下函数,为一个已经声明好的注入点附加回调: - -extern void InjectionPointAttach(const char *name, - const char *library, - const char *function, - const void *private_data, - int private_data_size); - - - name 是注入点名称;执行过程中到达该注入点时,就会执行从 library 载入的 functionprivate_data 是一块大小为 private_data_size 的私有数据区域,会在执行时作为参数传给回调。 - - - - 下面是一个 - InjectionPointCallback 的示例: - -static void -custom_injection_callback(const char *name, - const void *private_data, - void *arg) -{ - uint32 wait_event_info = WaitEventInjectionPointNew(name); - - pgstat_report_wait_start(wait_event_info); - elog(NOTICE, "%s: executed custom callback", name); - pgstat_report_wait_end(); -} - - 这个回调会以 NOTICE 级别向服务器错误日志写入一条消息,但回调完全可以实现更复杂的逻辑。 - - - - 另一种定义“到达注入点时应执行什么动作”的方式,是把测试代码直接写在常规源代码旁边。如果该动作依赖于加载模块无法访问的局部变量,这会很有用。此时可以使用 - IS_INJECTION_POINT_ATTACHED 宏来检查某个注入点是否已附加,例如: - -#ifdef USE_INJECTION_POINTS -if (IS_INJECTION_POINT_ATTACHED("before-foobar")) -{ - /* change a local variable if injection point is attached */ - local_var = 123; - - /* also execute the callback */ - INJECTION_POINT_CACHED("before-foobar", NULL); -} -#endif - - 注意,附加到注入点上的回调不会由 IS_INJECTION_POINT_ATTACHED 宏执行。如果你想执行该回调,就必须像上面的示例那样另外调用 - INJECTION_POINT_CACHED。 - - - - 可选地,也可以通过调用以下函数来解除一个注入点: - -extern bool InjectionPointDetach(const char *name); - - 成功时返回 true,否则返回 false。 - - - - 一个附加到注入点的回调会在所有后端中生效,包括在调用 - InjectionPointAttach 之后才启动的后端。它会一直保持附加状态,直到服务器停止,或者通过 - InjectionPointDetach 将其解除。 - - - - 相关示例可见于 PostgreSQL 源代码树中的 - src/test/modules/injection_points。 - - - - 启用注入点需要在 configure 中指定 - ,或者在 - Meson 中指定 - 。 - - - - - 自定义累计统计 - - - 用 C 语言编写的插件可以使用在 - 累计统计系统 中注册的自定义累计统计类型。 - - - - 首先,定义一个 PgStat_KindInfo,其中包含与所注册自定义类型相关的全部信息。例如: - -static const PgStat_KindInfo custom_stats = { - .name = "custom_stats", - .fixed_amount = false, - .shared_size = sizeof(PgStatShared_Custom), - .shared_data_off = offsetof(PgStatShared_Custom, stats), - .shared_data_len = sizeof(((PgStatShared_Custom *) 0)->stats), - .pending_size = sizeof(PgStat_StatCustomEntry), } - - 然后,每个需要使用这种自定义类型的后端,都需要使用 - pgstat_register_kind 注册它,并指定一个用于存储该类统计条目的唯一 ID: - -extern PgStat_Kind pgstat_register_kind(PgStat_Kind kind, - const PgStat_KindInfo *kind_info); - - 在开发新扩展时,应将 - PGSTAT_KIND_EXPERIMENTAL 用作 - kind。当你准备把扩展发布给用户时,请在 - - Custom Cumulative Statistics 页面上预留一个 kind ID。 - - - - 关于 PgStat_KindInfo API 的细节,可见 - src/include/utils/pgstat_internal.h。 - - - - 已注册的统计类型会关联到一个名称以及一个在共享内存中供整个服务器共享的唯一 ID。每个使用自定义统计类型的后端都会维护一个本地缓存,用来保存各个自定义 PgStat_KindInfo 的信息。 - - - - 应将实现自定义累计统计类型的扩展模块加入 - ,以便在 - PostgreSQL 启动期间尽早载入。 - - - - 展示如何注册并使用自定义统计信息的示例可见于 - src/test/modules/injection_points @@ -3272,9 +2814,9 @@ extern PgStat_Kind pgstat_register_kind(PgStat_Kind kind, - 如果从 C++ 代码调用后端函数,确定 C++ 调用栈值包含传统 C 风格 + 如果从 C++ 代码调用后端函数,确定 C++ 调用栈只包含传统 C 风格 的数据结构(POD)。这是必要的,因为后端错误会 - 产生远距离的longjmp(),它无法正确的退回具有非 + 产生远距离的longjmp(),它无法正确地展开具有非 POD 对象的 C++ 调用栈。 @@ -3293,8 +2835,8 @@ extern PgStat_Kind pgstat_register_kind(PgStat_Kind kind, 函数优化信息 - optimization information - for functions + 优化信息 + 用于函数 @@ -3330,7 +2872,7 @@ supportfn(internal) returns internal - 对于返回 boolean 的目标函数,估计使用该函数的 WHERE 子句会筛选出多少行通常很有用。这可以通过实现 SupportRequestSelectivity 请求类型的支持函数来完成。 + 对于返回 boolean 的目标函数,估计使用该函数的 WHERE 子句筛选出的行所占的比例通常很有用。这可以通过实现 SupportRequestSelectivity 请求类型的支持函数来完成。 diff --git a/zh/14/xindex.sgml b/zh/14/xindex.sgml index 425c94d8..9bb5013f 100644 --- a/zh/14/xindex.sgml +++ b/zh/14/xindex.sgml @@ -4,8 +4,8 @@ 索引扩展接口 - index - for user-defined data type + 索引 + 用于用户定义的数据类型 @@ -19,15 +19,10 @@ 索引方法和操作符类 - - 操作符类与索引访问方法相关联,例如 - B-树 或 GIN。 - 自定义索引访问方法可通过 定义。 - 详见 。 - + pg_am 表为每个索引方法(内部称为访问方法)保存一行。对表进行常规访问的支持内置于 PostgreSQL 中,但所有索引方法都在 pg_am 中描述。可以编写必要的代码,然后在 pg_am 中创建一个条目,从而添加新的索引访问方法 — 但这超出了本章的范围(参见)。 - 索引方法的例程并不直接知道它将处理哪些数据类型。相反,一个操作符类operator class标识了索引方法在处理特定数据类型时需要使用的那组操作。之所以称为操作符类,是因为它指定的一项内容就是可与索引一起使用的 WHERE 子句操作符集合(也就是能被转换成索引扫描条件的操作符)。操作符类还可以指定索引方法内部操作所需的一些支持函数,但这些函数并不直接对应任何可与索引一起使用的 WHERE 子句操作符。 + 索引方法的例程并不直接知道它将处理哪些数据类型。相反,一个操作符类操作符类标识了索引方法在处理特定数据类型时需要使用的那组操作。之所以称为操作符类,是因为它指定的一项内容就是可与索引一起使用的 WHERE 子句操作符集合(也就是能被转换成索引扫描条件的操作符)。操作符类还可以指定索引方法内部操作所需的一些支持函数,但这些函数并不直接对应任何可与索引一起使用的 WHERE 子句操作符。 @@ -353,12 +348,6 @@ 5 - - - 返回可由 C 调用的 skip 支持函数地址(可选) - - 6 - @@ -385,7 +374,7 @@ - 给定一个 64 位 salt,计算一个键的 64 位哈希值;如果 salt 为 0,结果的低 32 位必须与函数 1 计算出的值一致(可选) + 给定一个 64 位盐值,计算一个键的 64 位哈希值;如果盐值为 0,结果的低 32 位必须与函数 1 计算出的值一致(可选) 2 @@ -400,7 +389,7 @@ - GiST 索引有十二个支持函数,其中七个是可选的,如所示。 + GiST 索引有十一个支持函数,其中六个是可选的,如所示。 (详见。) @@ -475,11 +464,7 @@ (可选) 11 - - translate_cmptype - 把比较类型转换为该操作符类使用的策略号(可选) - 12 - + @@ -558,7 +543,7 @@ compare - 比较两个键,并返回一个小于零、等于零或大于零的整数,以表示第一个键是小于、等于还是大于第二个键 + 比较两个键,并返回一个小于零、等于零或大于零的整数,用以表示第一个键是小于、等于还是大于第二个键 1 @@ -732,7 +717,7 @@ CREATE OPERATOR < ( restrict = scalarltsel, join = scalarltjoinsel ); - 指定正确的交换子和求反器操作符很重要,同样也要指定合适的限制选择度函数和连接选择度函数,否则优化器将无法有效地利用索引。 + 指定正确的交换子和求反器操作符很重要,同样也要指定合适的限制选择率函数和连接选择率函数,否则优化器将无法有效地利用索引。 @@ -811,7 +796,7 @@ CREATE OPERATOR CLASS complex_abs_ops - 为了满足这些需求,PostgreSQL使用操作符族operator family这一概念。一个操作符族包含一个或多个操作符类,还可以包含属于整个族、但不属于族中任何单一类的可索引操作符及其相应的支持函数。我们称这样的操作符和函数在该族中是松散的,而不是绑定在某个特定类中。通常,每个操作符类只包含单一数据类型的操作符,而跨数据类型操作符则作为操作符族中的松散成员存在。 + 为了满足这些需求,PostgreSQL使用操作符族操作符族这一概念。一个操作符族包含一个或多个操作符类,还可以包含属于整个族、但不属于族中任何单一类的可索引操作符及其相应的支持函数。我们称这样的操作符和函数在该族中是松散的,而不是绑定在某个特定类中。通常,每个操作符类只包含单一数据类型的操作符,而跨数据类型操作符则作为操作符族中的松散成员存在。 @@ -835,8 +820,7 @@ DEFAULT FOR TYPE int8 USING btree FAMILY integer_ops AS FUNCTION 1 btint8cmp(int8, int8) , FUNCTION 2 btint8sortsupport(internal) , FUNCTION 3 in_range(int8, int8, int8, boolean, boolean) , - FUNCTION 4 btequalimage(oid) , - FUNCTION 6 btint8skipsupport(internal) ; + FUNCTION 4 btequalimage(oid) ; CREATE OPERATOR CLASS int4_ops DEFAULT FOR TYPE int4 USING btree FAMILY integer_ops AS @@ -849,8 +833,7 @@ DEFAULT FOR TYPE int4 USING btree FAMILY integer_ops AS FUNCTION 1 btint4cmp(int4, int4) , FUNCTION 2 btint4sortsupport(internal) , FUNCTION 3 in_range(int4, int4, int4, boolean, boolean) , - FUNCTION 4 btequalimage(oid) , - FUNCTION 6 btint4skipsupport(internal) ; + FUNCTION 4 btequalimage(oid) ; CREATE OPERATOR CLASS int2_ops DEFAULT FOR TYPE int2 USING btree FAMILY integer_ops AS @@ -863,8 +846,7 @@ DEFAULT FOR TYPE int2 USING btree FAMILY integer_ops AS FUNCTION 1 btint2cmp(int2, int2) , FUNCTION 2 btint2sortsupport(internal) , FUNCTION 3 in_range(int2, int2, int2, boolean, boolean) , - FUNCTION 4 btequalimage(oid) , - FUNCTION 6 btint2skipsupport(internal) ; + FUNCTION 4 btequalimage(oid) ; ALTER OPERATOR FAMILY integer_ops USING btree ADD -- cross-type comparisons int8 vs int2 @@ -931,7 +913,7 @@ ALTER OPERATOR FAMILY integer_ops USING btree ADD - 要构建一个多数据类型的哈希操作符族,必须为该族支持的每一种数据类型创建相互兼容的哈希支持函数。这里的兼容性是指:对任意两个被该族中的等值操作符视为相等的值,这些函数都保证返回相同的哈希码,即使这两个值属于不同类型也是如此。当这些类型具有不同的物理表示时,这通常难以实现,但在某些情况下可以做到。此外,将该操作符族中一种数据类型的值通过隐式或二进制强制转换转换成该族中另一种数据类型时,不应改变所计算出的哈希值。注意,每种数据类型只有一个支持函数,而不是每个等值操作符一个。建议让操作符族保持完整,也就是说,对每一种数据类型组合都提供一个等值操作符。每个操作符类只应包含其数据类型对应的非跨数据类型等值操作符和支持函数。 + 要构建一个多数据类型的哈希操作符族,必须为该族支持的每一种数据类型创建相互兼容的哈希支持函数。这里的兼容性是指:对任意两个被该族中的等值操作符视为相等的值,这些函数都保证返回相同的哈希码,即使这两个值属于不同类型也是如此。当这些类型具有不同的物理表示时,这通常难以实现,但在某些情况下可以做到。此外,将该操作符族中一种数据类型的值通过隐式或二进制强制转换转为该族中另一种数据类型时,不得改变所计算出的哈希值。注意,每种数据类型只有一个支持函数,而不是每个等值操作符一个。建议让操作符族保持完整,也就是说,对每一种数据类型组合都提供一个等值操作符。每个操作符类只应包含其数据类型对应的非跨数据类型等值操作符和支持函数。 @@ -944,7 +926,7 @@ ALTER OPERATOR FAMILY integer_ops USING btree ADD - 在 PostgreSQL 8.3 之前,并没有操作符族这一概念,因此任何打算与索引一起使用的跨数据类型操作符都必须直接绑定到该索引的操作符类中。虽然这种做法仍然有效,但已经废弃,因为它会使索引的依赖关系过于宽泛,而且当两种数据类型都在同一操作符族中拥有操作符时,规划器能更有效地处理跨数据类型比较。 + 在 PostgreSQL 8.3 之前,并没有操作符族这一概念,因此任何打算与索引一起使用的跨数据类型操作符都必须直接绑定到该索引的操作符类中。虽然这种做法仍然有效,但已被弃用,因为它会使索引的依赖关系过于宽泛,而且当两种数据类型都在同一操作符族中拥有操作符时,规划器能更有效地处理跨数据类型比较。 @@ -953,7 +935,7 @@ ALTER OPERATOR FAMILY integer_ops USING btree ADD 系统对操作符类的依赖 - ordering operator + 排序操作符 @@ -961,7 +943,7 @@ ALTER OPERATOR FAMILY integer_ops USING btree ADD - 特别地,ORDER BYDISTINCT等 SQL 特性要求对值的比较和排序。为了在用户定义的数据类型上实现这些特性,PostgreSQL会为数据类型查找默认 B-树操作符类。这个操作符类的equals成员定义了用于GROUP BYDISTINCT的值的等值概念,而该操作符类施加的排序顺序定义了默认的ORDER BY顺序。 + 特别地,ORDER BYDISTINCT等 SQL 特性要求对值的比较和排序。为了在用户定义的数据类型上实现这些特性,PostgreSQL会为数据类型查找默认 B-树操作符类。这个操作符类的相等成员定义了用于GROUP BYDISTINCT的值的等值概念,而该操作符类施加的排序顺序定义了默认的ORDER BY顺序。 @@ -987,11 +969,11 @@ SELECT * FROM mytable ORDER BY somecol USING ~<~; - 用户定义类型的数组比较也依赖于该类型默认 B-树操作符类所定义的语义。如果没有默认 B-树操作符类,但有默认的哈希操作符类,则支持数组相等比较,但不支持顺序比较。 + 用户定义类型的数组比较也依赖于该类型默认 B-树操作符类所定义的语义。如果没有默认 B-树操作符类,但有默认的哈希操作符类,则支持数组相等比较,但不支持排序比较。 - 另一种需要更多数据类型相关知识的 SQL 特性,是窗口函数中的 RANGE offset PRECEDING/FOLLOWING 框架选项(见)。对于下面这样的查询 + 另一种需要更多数据类型相关知识的 SQL 特性,是窗口函数中的 RANGE offset PRECEDING/FOLLOWING 帧选项(见)。对于下面这样的查询 SELECT sum(x) OVER (ORDER BY x RANGE BETWEEN 5 PRECEDING AND 10 FOLLOWING) FROM mytable; @@ -1026,7 +1008,7 @@ SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10; - 搜索操作符必须返回布尔结果,而排序操作符通常返回其他类型的结果,例如表示距离的浮点数或数值。这种类型通常不同于被索引的数据类型。为了避免对不同数据类型行为作硬编码假设,在定义排序操作符时,必须指定一个 B-树操作符族,用来说明结果数据类型的排序顺序。正如上一节所述,B-树操作符族定义了 PostgreSQL 的顺序概念,因此这是一种自然的表示方式。由于点的 <-> 操作符返回 float8,因此可以在创建操作符类时这样指定它: + 搜索操作符必须返回布尔结果,而排序操作符通常返回其他类型的结果,例如用于表示距离的 float 或 numeric。这种类型通常不同于被索引的数据类型。为了避免对不同数据类型行为作硬编码假设,在定义排序操作符时,必须指定一个 B-树操作符族,用来说明结果数据类型的排序顺序。正如上一节所述,B-树操作符族定义了 PostgreSQL 的顺序概念,因此这是一种自然的表示方式。由于点的 <-> 操作符返回 float8,因此可以在创建操作符类时这样指定它: (point, point) FOR ORDER BY float_ops ]]> @@ -1039,7 +1021,7 @@ OPERATOR 15 <-> (point, point) FOR ORDER BY float_ops 操作符类的特殊特性 - 还有两个操作符类的特殊特性我们尚未讨论,主要是因为它们对最常用的索引方法并不太有用。 + 还有两个操作符类的特殊特性我们尚未讨论,主要是因为它们对最常用的索引方法没有用处。 @@ -1060,7 +1042,7 @@ CREATE OPERATOR CLASS polygon_ops STORAGE box; - 目前,只有 GiST、SP-GiST、GIN 和 BRIN 索引方法支持与列数据类型不同的 STORAGE 类型。GiST 的 compressdecompress 支持例程在使用 STORAGE 时必须处理数据类型转换。SP-GiST 同样需要 compress 支持函数在存储类型不同时完成转换;如果某个 SP-GiST 操作符类还支持取回数据,那么反向转换必须由 consistent 函数处理。在 GIN 中,STORAGE 类型标识key值的类型,它通常不同于被索引列的类型 — 例如,整数数组列上的某个操作符类,其键值可能只是整数。GIN 的 extractValueextractQuery 支持例程负责从被索引值中提取键。BRIN 与 GIN 类似:STORAGE 类型标识被存储的摘要值类型,而操作符类的支持过程负责正确解释这些摘要值。 + 目前,只有 GiST、SP-GiST、GIN 和 BRIN 索引方法支持与列数据类型不同的 STORAGE 类型。GiST 的 compressdecompress 支持例程在使用 STORAGE 时必须处理数据类型转换。SP-GiST 同样需要 compress 支持函数在存储类型不同时完成转换;如果某个 SP-GiST 操作符类还支持取回数据,那么反向转换必须由 consistent 函数处理。在 GIN 中,STORAGE 类型标识值的类型,它通常不同于被索引列的类型 — 例如,整数数组列上的某个操作符类,其键值可能只是整数。GIN 的 extractValueextractQuery 支持例程负责从被索引值中提取键。BRIN 与 GIN 类似:STORAGE 类型标识被存储的摘要值类型,而操作符类的支持函数负责正确解释这些摘要值。 diff --git a/zh/14/xml2.sgml b/zh/14/xml2.sgml index 1324ffd4..1da73e99 100644 --- a/zh/14/xml2.sgml +++ b/zh/14/xml2.sgml @@ -1,7 +1,7 @@ - xml2 — XPath 查询与 XSLT 功能 + xml2 xml2 @@ -90,7 +90,7 @@ 对文档执行该查询,并将结果包在 XML 标签中。如果结果包含多个值,输出将类似于: <toptag> -<itemtag>Value 1 which could be an XML fragment</itemtag> +<itemtag>Value 1(可以是 XML 片段)</itemtag> <itemtag>Value 2....</itemtag> </toptag> @@ -173,7 +173,7 @@ xpath_table(text key, text document, text relation, text xpaths, text criteria) key - key 字段的名称 — 这只是一个作为输出表第一列使用的字段,也就是说,它用于标识每个输出行来自哪条记录(关于多个值,见下文注释) + 字段的名称 — 这只是一个作为输出表第一列使用的字段,也就是说,它用于标识每个输出行来自哪条记录(关于多个值,见下文注释) @@ -238,7 +238,7 @@ xpath_table('article_id', 'date_entered > ''2003-01-01'' ') AS t(article_id integer, author text, page_count integer, title text); - AS 子句定义了输出表中各列的名称和类型。第一列是 key 字段,其余各列对应 XPath 查询。如果 XPath 查询多于结果列,多出的查询将被忽略。如果结果列多于 XPath 查询,多出的列将为 NULL。 + AS 子句定义了输出表中各列的名称和类型。第一列是 字段,其余各列对应 XPath 查询。如果 XPath 查询多于结果列,多出的查询将被忽略。如果结果列多于 XPath 查询,多出的列将为 NULL。 @@ -267,7 +267,7 @@ WHERE t.author_id = p.person_id; - 在某些情况下,用户会知道某个 XPath 查询只会返回单个结果(例如唯一文档标识符)— 如果它与返回多个结果的 XPath 查询一起使用,这个单值结果只会出现在结果的第一行。解决办法是把 key 字段作为与一个更简单的 XPath 查询结果进行连接的条件之一。例如: + 在某些情况下,用户会知道某个 XPath 查询只会返回单个结果(例如唯一文档标识符)— 如果它与返回多个结果的 XPath 查询一起使用,这个单值结果只会出现在结果的第一行。解决办法是把键字段作为与一个更简单的 XPath 查询结果进行连接的条件之一。例如: CREATE TABLE test ( diff --git a/zh/14/xoper.sgml b/zh/14/xoper.sgml index b9968985..6c439275 100644 --- a/zh/14/xoper.sgml +++ b/zh/14/xoper.sgml @@ -127,6 +127,17 @@ SELECT (a + b) AS c FROM test_complex; 设就认为这种转换有效;= 操作符的创建者必须通过为该操 作符标记交换子信息,明确声明这种转换是有效的。 + + 定义一个与自身可交换的操作符时,直接定义即可。但定义一对可交换操作符时,情况就稍微复杂一些:第一个要定义的操作符如何引用另一个尚未定义的操作符呢?这个问题有两种解决办法: + + 一种办法是在定义第一个操作符时省略 COMMUTATOR 子句,然后在第二个操作符的定义中提供该子句。由于 PostgreSQL 知道可交换操作符是成对出现的,因此它在看到第二个定义时,会自动回头补全第一个定义中缺少的 COMMUTATOR 子句。 + + + + 另一种更直接的办法是在两个定义中都包含 COMMUTATOR 子句。当 PostgreSQL 处理第一个定义并发现 COMMUTATOR 引用了一个不存在的操作符时,系统会在系统目录中为该操作符建立一个占位项。这个占位项只有操作符名称、左右操作数类型和结果类型包含有效数据,因为这就是 PostgreSQL 此时能够推断出的全部信息。第一个操作符的目录项将链接到这个占位项。之后,当你定义第二个操作符时,系统会用第二个定义中的附加信息更新该占位项。如果在占位操作符补全之前尝试使用它,就只会得到一条错误消息。 + + + @@ -158,16 +169,19 @@ SELECT (a + b) AS c FROM test_complex; x <> y。这种情况比你想象得更常见,因为 NOT 操作可能会作为其他重排的结果被插入进来。 + + 可以使用上面解释的定义交换子对的相同方法,来定义成对的求反器操作符。 + <literal>RESTRICT</literal> - 如果给出 RESTRICT 子句,它指定该操作符的限制选择度估 + 如果给出 RESTRICT 子句,它指定该操作符的限制选择率估 算函数。(注意,这里是函数名,而不是操作符名。) RESTRICT 子句只对返回 boolean 的二元操 - 作符有意义。限制选择度估算器的作用,是针对当前操作符和某个特定常量值, + 作符有意义。限制选择率估算器的作用,是针对当前操作符和某个特定常量值, 猜测一张表中有多少比例的行会满足如下形式的 WHERE 子句条件: @@ -179,9 +193,9 @@ column OP constant - 编写新的限制选择度估算函数远远超出了本章的范围,不过幸运的是,对于你自 + 编写新的限制选择率估算函数远远超出了本章的范围,不过幸运的是,对于你自 己的很多操作符,通常都可以直接使用系统提供的某个标准估算器。标准的限制 - 选择度估算器如下: + 选择率估算器如下: eqsel 用于 = neqsel 用于 <> @@ -193,7 +207,7 @@ column OP constant - 对于选择度非常高或非常低的操作符,即使它们实际上并不是真正的相等或不等 + 对于选择率非常高或非常低的操作符,即使它们实际上并不是真正的相等或不等 比较,你也常常可以勉强使用 eqselneqsel。例如,几何类型中的近似相等操作符就使用 eqsel,其依据是它们通常只会匹配表中很小一部分项。 @@ -212,7 +226,7 @@ column OP constant - 另一个有用的内置选择度估算函数是 matchingsel。只要 + 另一个有用的内置选择率估算函数是 matchingsel。只要 已为输入数据类型收集了标准的 MCV 和/或直方图统计信息,它几乎就适用于任 何二元操作符。它的默认估计值被设定为 eqsel 所用默认 估计值的两倍,因此最适合那些比相等比较稍微宽松一些的比较操作符。(或者 @@ -222,7 +236,7 @@ column OP constant src/backend/utils/adt/geo_selfuncs.c 中,还为几 - 何操作符提供了其他选择度估算函数:areasel、 + 何操作符提供了其他选择率估算函数:areaselpositionselcontsel。截至 目前,这些函数都还只是桩实现,但你也许仍会想使用它们(或者更好的是,改 进它们)。 @@ -233,9 +247,9 @@ column OP constant <literal>JOIN</literal> - 如果给出 JOIN 子句,它指定该操作符的连接选择度估算函 + 如果给出 JOIN 子句,它指定该操作符的连接选择率估算函 数。(注意,这里是函数名,而不是操作符名。)JOIN 子 - 句只对返回 boolean 的二元操作符有意义。连接选择度估算器的 + 句只对返回 boolean 的二元操作符有意义。连接选择率估算器的 作用,是针对当前操作符,猜测两张表中有多少比例的行对会满足如下形式的 WHERE 子句条件: @@ -246,7 +260,7 @@ table1.column1 OP table2.column2 - 与前面一样,本章不会尝试解释如何编写连接选择度估算函数,而只是建议你在 + 与前面一样,本章不会尝试解释如何编写连接选择率估算函数,而只是建议你在 适用时使用某个标准估算器: eqjoinsel 用于 = @@ -305,7 +319,7 @@ table1.column1 OP table2.column2 一个可参与哈希连接的操作符,必须拥有一个交换子(如果两侧操作数数据类型 - 相同,则可以是它自身;如果不同,则应是相关的相等操作符),并且该交换子 + 相同,则为它自身;如果不同,则应是相关的相等操作符),并且该交换子 也必须出现在同一个操作符族中。否则,在使用该操作符时可能会发生规划器错 误。另外,对于支持多种数据类型的哈希操作符族,最好(虽然并非严格必需) 为每一种数据类型组合都提供相等操作符;这样可以获得更好的优化效果。 @@ -342,7 +356,7 @@ table1.column1 OP table2.column2 - 归并连接的基本思想,是先把左表和右表分别排序,然后并行扫描它们。因此, + 归并连接的基本思想,是先把左表和右表分别排序,然后同步扫描它们。因此, 两种数据类型都必须能够被完全排序,而连接操作符必须只能在那对值位于排序 次序中同一位置时才成功。实际效果上,这意味着连接操作符 必须表现得像相等比较一样。不过,只要两种不同的数据类型在逻辑上兼容,也 @@ -362,7 +376,7 @@ table1.column1 OP table2.column2 一个可参与归并连接的操作符,必须拥有一个交换子(如果两侧操作数数据类型 - 相同,则可以是它自身;如果不同,则应是相关的相等操作符),并且该交换子 + 相同,则为它自身;如果不同,则应是相关的相等操作符),并且该交换子 也必须出现在同一个操作符族中。否则,在使用该操作符时可能会发生规划器错 误。另外,对于支持多种数据类型的 btree 操作符族,最 好(虽然并非严格必需)为每一种数据类型组合都提供相等操作符;这样可以获 diff --git a/zh/14/xplang.sgml b/zh/14/xplang.sgml index 9075d7b6..0590ea2d 100644 --- a/zh/14/xplang.sgml +++ b/zh/14/xplang.sgml @@ -183,7 +183,7 @@ CREATE TRUSTED LANGUAGE plperl 在默认的PostgreSQL安装中, PL/pgSQL语言的调用处理器会被构建并安装到 - library目录中;此外, + 目录中;此外, PL/pgSQL语言本身也安装在所有数据库中。如 果在构建时配置了Tcl支持,那么 PL/TclPL/TclU diff --git a/zh/14/xtypes.sgml b/zh/14/xtypes.sgml index 3d1b66d1..b66c4aa1 100644 --- a/zh/14/xtypes.sgml +++ b/zh/14/xtypes.sgml @@ -218,7 +218,7 @@ CREATE TYPE complex ( 如果数据类型的内部表示是可变长度的,则这种内部表示必须遵循可变长度数 据的标准布局:前四个字节必须是一个从不直接访问的char[4] 字段(惯例上命名为vl_len_)。必须使用 - SET_VARSIZE()宏在该字段中存储该值的总大小(包括 + SET_VARSIZE()宏在该字段中存储该 datum 的总大小(包括 长度字段本身),并使用VARSIZE()取回它。(这些宏 之所以存在,是因为长度字段可能会随平台不同而采用编码形式。) @@ -260,7 +260,7 @@ CREATE TYPE complex ( PG_DETOAST_DATUM_PACKED(通常通过定义 GETARG_DATATYPE_PP宏来隐藏),并使用 VARSIZE_ANY_EXHDRVARDATA_ANY - 宏访问一个可能采用打包形式的值。再次注意,即使数据类型定义指定了 + 宏访问一个可能采用打包形式的 datum。再次注意,即使数据类型定义指定了 对齐方式,这些宏返回的数据也不是对齐的。如果对齐很重要,就必须使用常 规的PG_DETOAST_DATUM接口。 @@ -271,8 +271,7 @@ CREATE TYPE complex ( 较旧的代码常把vl_len_声明为 int32字段,而不是char[4]字段。只要结构体定 义中还有其他至少按int32对齐的字段,这样做是可以的。但 - 在处理可能未对齐的值时使用这种结构体定义就很危险;编译器可能据此假定该 - 值实际上是对齐的,从而在对齐要求严格的体系结构上导致核心转储。 + 在处理可能未对齐的 datum 时使用这种结构体定义就很危险;编译器可能据此假定该 datum 实际上是对齐的,从而在对齐要求严格的体系结构上导致核心转储。 diff --git a/zh/15/acronyms.sgml b/zh/15/acronyms.sgml index bfb4ff2c..02e7566e 100644 --- a/zh/15/acronyms.sgml +++ b/zh/15/acronyms.sgml @@ -8,32 +8,7 @@ - - AIO - - - 异步I/O - - - - - ACL - - - 访问控制列表 - - - - - - AM - - - 访问方法 - - - ANSI @@ -347,14 +322,6 @@ - - I/O - - - 输入/输出 - - - ISO diff --git a/zh/15/adminpack.sgml b/zh/15/adminpack.sgml index e7fbd05a..bbe26268 100644 --- a/zh/15/adminpack.sgml +++ b/zh/15/adminpack.sgml @@ -94,14 +94,14 @@ pg_file_sync - pg_file_sync对由filename指定的文件或目录执行 fsync。失败时会抛出错误(例如,指定的文件不存在)。请注意,对此函数没有影响,因此即使刷新数据库文件失败,也不会引发 PANIC 级别的错误。 + pg_file_sync对由filename指定的文件或目录执行 fsync。失败时会抛出错误(例如,指定的文件不存在)。请注意,对此函数没有影响,因此即使数据库文件刷盘失败,也不会引发 PANIC 级别的错误。 pg_file_rename - pg_file_rename重命名文件。如果省略archivename或其值为 NULL,则它只是将oldname重命名为newname(后者必须尚不存在)。如果提供了archivename,它会先将newname重命名为archivename(后者必须尚不存在),然后再将oldname重命名为newname。如果第二个重命名步骤失败,它会在报告错误之前尝试将archivename再改回newname。成功时返回 true;如果源文件不存在或不可写,则返回 false;其他情况会抛出错误。 + pg_file_rename重命名文件。如果省略archivename或其值为空值,则它只是将oldname重命名为newname(后者必须尚不存在)。如果提供了archivename,它会先将newname重命名为archivename(后者必须尚不存在),然后再将oldname重命名为newname。如果第二个重命名步骤失败,它会在报告错误之前尝试将archivename再改回newname。成功时返回 true;如果源文件不存在或不可写,则返回 false;其他情况会抛出错误。 diff --git a/zh/15/amcheck.sgml b/zh/15/amcheck.sgml index 502f69b0..64313e5e 100644 --- a/zh/15/amcheck.sgml +++ b/zh/15/amcheck.sgml @@ -46,7 +46,7 @@ - bt_index_check(index regclass, heapallindexed boolean, checkunique boolean) returns void + bt_index_check(index regclass, heapallindexed boolean) returns void bt_index_check @@ -97,8 +97,6 @@ ORDER BY c.relpages DESC LIMIT 10; bt_index_check不会验证跨越父子关系的不变式, 但如果heapallindexedtrue, 它会验证所有堆元组在索引中都有对应的索引元组。 - 如果checkuniquetrue, - bt_index_check还会检查唯一索引中重复条目里可见的项不超过一个。 当在线生产环境中需要一种例行的、轻量级的损坏检查时, bt_index_check通常能在验证彻底程度与对应用性能、可用性的影响之间提供最佳权衡。 @@ -107,7 +105,7 @@ ORDER BY c.relpages DESC LIMIT 10; - bt_index_parent_check(index regclass, heapallindexed boolean, rootdescend boolean, checkunique boolean) returns void + bt_index_parent_check(index regclass, heapallindexed boolean, rootdescend boolean) returns void bt_index_parent_check @@ -118,8 +116,6 @@ ORDER BY c.relpages DESC LIMIT 10; bt_index_parent_check测试其目标 B-树索引是否满足多种不变式。 如果可选参数heapallindexedtrue, 该函数还会验证索引中是否包含所有本应出现的堆元组。 - 如果checkuniquetrue, - bt_index_parent_check还会检查唯一索引中重复条目里可见的项不超过一个。 如果可选参数rootdescendtrue, 则会对每个元组都从根页重新搜索一次,从而在叶子层重新定位这些元组。 bt_index_parent_check能够执行的检查, @@ -361,7 +357,7 @@ SET client_min_messages = DEBUG1; 这也包括因操作系统排序规则的比较规则发生变化而引起的问题。 - 像text这类可排序类型的数据值之间的比较必须是不可变的 + 像text这类支持排序规则的类型的 datum 之间的比较必须是不可变的 (正如用于 B-树索引扫描的所有比较都必须不可变一样), 这就意味着操作系统排序规则绝不能发生变化。 虽然这种情况比较少见,但操作系统排序规则的更新确实可能导致此类问题。 diff --git a/zh/15/backup-manifest.sgml b/zh/15/backup-manifest.sgml index dd6385a4..b5558f0a 100644 --- a/zh/15/backup-manifest.sgml +++ b/zh/15/backup-manifest.sgml @@ -34,20 +34,7 @@ PostgreSQL-Backup-Manifest-Version - 其对应的值是一个整数。从 PostgreSQL - 17 开始,该值为 2;在较早的版 - 本中,该值为 1。 - - - - - - System-Identifier - - - 执行该备份的 PostgreSQL 实例的数据库系统标识 - 符。只有当 PostgreSQL-Backup-Manifest-Version 为 - 2 时,才会出现该字段。 + 其对应的值始终为整数 1。 @@ -81,9 +68,9 @@ 该键总是出现在备份清单文件的最后一行。其对应的值是此前所有行的 - SHA-256 校验和。这里使用固定的校验和方法,是为了让客户端能够对清单进 - 行增量解析。尽管 SHA-256 校验和明显比 CRC-32C 校验和开销更高,但清单 - 通常足够小,因此这些额外计算一般并不重要。 + SHA256 校验和。这里使用固定的校验和方法,是为了让客户端能够对清单进 + 行增量解析。尽管 SHA256 校验和明显比 CRC32C 校验和开销更高,但清单通 + 常足够小,因此这些额外计算一般并不重要。 @@ -180,7 +167,7 @@ Start-LSN - 为了使用该备份,必须在指定时间线上从这个 LSN 开始回放。该 LSN 按 + 为了使用该备份,必须在指定时间线上从这个 LSN 开始重放。该 LSN 按 PostgreSQL 通常使用的格式存储;也就是说, 它是一个字符串,由两段十六进制字符串构成,每段长度在 1 到 8 之间,并 以斜杠分隔。 @@ -192,7 +179,7 @@ End-LSN - 使用该备份时,指定时间线上的回放可结束于此 LSN,而这也是允许的最早 + 使用该备份时,指定时间线上的重放可结束于此 LSN,而这也是允许的最早 LSN。其存储格式与 Start-LSN 相同。 diff --git a/zh/15/backup.sgml b/zh/15/backup.sgml index 6a52ed55..eade594b 100644 --- a/zh/15/backup.sgml +++ b/zh/15/backup.sgml @@ -3,7 +3,7 @@ 备份和恢复 - backup + 备份 与任何保存重要数据的系统一样,PostgreSQL数据库也应定期备份。虽然其过程基本简单,但清楚理解其底层技术和前提假设非常重要。 @@ -74,7 +74,7 @@ psql -X dbname < psql -X --set ON_ERROR_STOP=on dbname < dumpfile - 无论如何,你最终只会得到一个部分恢复的数据库。另一种做法是指定将整个转储作为单个事务恢复,这样恢复要么全部完成,要么全部回滚。可以通过把命令行选项传给psql来启用这种模式。使用这种模式时要注意,即便是一个很小的错误,也可能回滚一个已经运行了许多小时的恢复过程。不过,这仍可能比在部分恢复后手工清理一个复杂数据库更可取。 + 无论采用上述哪种方式,你最终只会得到一个部分恢复的数据库。另一种做法是指定将整个转储作为单个事务恢复,这样恢复要么全部完成,要么全部回滚。可以通过把命令行选项传给psql来启用这种模式。使用这种模式时要注意,即便是一个很小的错误,也可能回滚一个已经运行了许多小时的恢复过程。不过,这仍可能比在部分恢复后手工清理一个复杂数据库更可取。 @@ -194,7 +194,7 @@ pg_restore -d dbname - 对于非常大的数据库,你可能需要把split与前两种方法之一结合使用。 + 对于非常大的数据库,你可能需要把split与另外两种方法之一结合使用。 @@ -250,7 +250,7 @@ tar -cf backup.tar /usr/local/pgsql/data - 如果无法获得同时的快照,一种选择是将数据库服务器关闭足够长的时间,以建立所有冻结快照。另一种选择是执行持续归档基础备份(),因为这种备份不受备份期间文件系统变化的影响。这要求只在备份过程中启用持续归档;恢复则使用持续归档恢复()。 + 如果无法获得同时的快照,一种选择是将数据库服务器关闭足够长的时间,以建立所有冻结快照。另一种选择是执行持续归档基础备份(),因为这种备份不受备份期间文件系统变化的影响。这种方法只需在备份期间启用持续归档;恢复则使用持续归档恢复()。 @@ -310,7 +310,7 @@ tar -cf backup.tar /usr/local/pgsql/data - 和普通文件系统备份技术一样,这种方法只能支持整个数据库集簇的恢复,而不支持其中某个子集的恢复。此外,它需要大量归档存储:基础备份可能很庞大,繁忙系统也会产生大量必须归档的 WAL 流量。尽管如此,在很多需要高可靠性的场景中,它仍是首选的备份技术。 + 和普通文件系统备份技术一样,这种方法只能支持整个数据库集簇的恢复,而不支持其中某个子集的恢复。此外,它需要大量归档存储:基础备份可能很庞大,繁忙系统也会产生许多兆字节的、必须归档的 WAL 流量。尽管如此,在很多需要高可靠性的场景中,它仍是首选的备份技术。 @@ -329,7 +329,7 @@ tar -cf backup.tar /usr/local/pgsql/data - 要启用 WAL 归档,请将配置参数设置为replica或更高,将设置为on,并在配置参数中指定要使用的 shell 命令,或者在配置参数中指定要使用的库。实际上,这些设置通常都会放在postgresql.conf文件中。 + 要启用 WAL 归档,请将配置参数设置为replica或更高,将设置为on,并在配置参数中指定要使用的 shell 命令,或者在配置参数中指定要使用的库。在实际使用中,这些设置总是放在postgresql.conf文件中。 @@ -345,24 +345,24 @@ test ! -f /mnt/server/archivedir/00000001000000A900000065 && cp pg_wal/0 对每个新的待归档文件都会生成一条类似的命令。 - - 归档命令会以运行PostgreSQL服务器的同一操作系统用户身份执行。由于这一系列被归档的 WAL 文件实际上包含了数据库中的几乎全部内容,因此你应确保归档数据不会被他人窥探;例如,把它归档到一个不向组或所有用户开放读权限的目录中。 - + 归档命令将以运行 PostgreSQL 服务器的同一用户身份执行。由于归档的一系列 WAL 文件实际上包含数据库中的全部内容,应确保归档数据不会被他人窥视;例如,将其归档到不允许所属组或其他用户读取的目录。 + + 归档命令必须当且仅当成功时才返回退出状态零。收到零状态后,PostgreSQL 会认为该文件已成功归档,并将其删除或回收。非零状态则告诉 PostgreSQL 该文件尚未归档;它会定期重试,直到成功。 - 重要的是,归档命令只有在成功时才返回零退出状态。收到零结果后,PostgreSQL会认为该文件已经成功归档,并会将其删除或回收。相反,非零状态会告诉PostgreSQL该文件尚未归档;系统会周期性重试,直到成功为止。 + 另一种归档方式是把自定义归档模块用作archive_library。由于这类模块是用C编写的,创建自己的模块可能比编写 shell 命令需要更多工作。不过,归档模块可能比通过 shell 归档更高效,而且可以访问许多有用的服务器资源。有关归档模块的更多信息,见 - 另一种归档方式是把自定义归档模块用作archive_library。由于这类模块是用C编写的,创建自己的模块可能比编写 shell 命令需要更多工作。不过,归档模块可能比通过 shell 归档更高效,而且可以访问许多有用的服务器资源。有关归档模块的更多信息,见。 + 当归档命令被信号终止(用于服务器关闭流程的SIGTERM除外),或者因 shell 报错(例如命令未找到)而以大于 125 的状态退出,或者归档函数发出ERRORFATAL时,归档器进程会中止,并由 postmaster 重新启动。在这种情况下,失败不会记录到中。 - 当归档命令被信号终止(用于服务器关闭流程的SIGTERM除外),或者 shell 因退出状态大于 125 的错误(例如命令未找到)而失败,或者归档函数发出ERRORFATAL时,归档器进程会中止,并由 postmaster 重新启动。在这种情况下,失败不会记录到中。 + 归档命令和归档库通常都应设计为拒绝覆盖任何已存在的归档文件。这是一项重要的安全特性,可在管理员出错时保护归档的完整性(例如把两台不同服务器的输出发送到同一个归档目录)。 - 归档命令和归档库通常都应设计为拒绝覆盖任何已存在的归档文件。这是一项重要的安全特性,可在管理员出错时保护归档的完整性(例如把两台不同服务器的输出发送到同一个归档目录)。建议测试你打算使用的归档命令或归档库,以确保它确实不会覆盖已有文件,并且在这种情况下分别返回非零状态或 false。上面给出的 Unix 示例命令通过单独加入一个test步骤来保证这一点。在某些 Unix 平台上,cp提供了诸如之类的开关,也可以更简洁地实现同样目的,但在你确认它会返回正确的退出状态之前,不应依赖这些开关。(尤其是 GNU cp在使用且目标文件已存在时会返回状态零,这不是我们想要的行为。) + 建议测试所拟定的归档命令或归档库,确保它确实不会覆盖已有文件,并且在这种情况下分别返回非零状态或false。上面给出的 Unix 示例命令通过单独加入一个test步骤,确保这两点。在某些 Unix 平台上,cp提供了诸如之类的开关,也可以更简洁地实现同样目的,但在你确认它会返回正确的退出状态之前,不应依赖这些开关。(尤其是 GNU cp在使用且目标文件已存在时会返回状态零,这不是我们想要的行为。) @@ -382,7 +382,7 @@ test ! -f /mnt/server/archivedir/00000001000000A900000065 && cp pg_wal/0 - 归档命令或归档函数只会在完整的 WAL 段上被调用。因此,如果服务器产生的 WAL 流量很小(或者存在低谷期),事务完成到其被安全写入归档存储之间可能会有很长延迟。为了限制未归档数据可能有多旧,你可以设置,强制服务器至少隔这么长时间切换到一个新的 WAL 段文件。注意,由强制切换而提前归档的文件长度仍与装满的文件相同。因此,把archive_timeout设得很短并不明智,这会使归档存储膨胀。archive_timeout设为大约 1 分钟通常是合理的。 + 归档命令或归档函数只会针对已完成的 WAL 段调用。因此,如果服务器产生的 WAL 流量很小(或者存在低谷期),事务完成到其被安全写入归档存储之间可能会有很长延迟。为了限制未归档数据可能有多旧,你可以设置,使服务器强制切换到新 WAL 段文件的间隔不超过这个值。注意,由强制切换而提前归档的文件长度仍与装满的文件相同。因此,把archive_timeout设得很短并不明智,这会使归档存储膨胀。archive_timeout设为大约 1 分钟通常是合理的。 @@ -418,39 +418,9 @@ test ! -f /mnt/server/archivedir/00000001000000A900000065 && cp pg_wal/0 - - 进行增量备份 - - - 你可以使用,通过指定--incremental选项进行增量备份。作为--incremental的参数,必须提供来自同一服务器较早一次备份的备份清单。生成的备份中,非关系文件会被完整包含,而某些关系文件则可能被较小的增量文件取代,这些文件只包含自较早备份以来发生变化的块,以及重建该文件当前版本所需的足够元数据。 - - - - 为了找出需要备份哪些块,服务器使用 WAL 汇总,这些汇总存储在数据目录中的pg_wal/summaries目录内。如果所需的汇总文件不存在,尝试执行增量备份将会失败。该目录中存在的汇总必须覆盖从前一次备份起始 LSN 到当前备份起始 LSN 之间的所有 LSN。由于服务器是在确定当前备份起始 LSN 后才去查找 WAL 汇总,因此所需的汇总文件可能不会立刻出现在磁盘上,但服务器会等待缺失文件出现。这对于 WAL 汇总进程落后的情况也有帮助。然而,如果所需文件已经被移除,或者 WAL 汇总进程追赶得不够快,增量备份就会失败。 - - - - 恢复增量备份时,不仅需要增量备份本身,还必须具有所有更早的备份,以便提供增量备份中省略的那些块。请注意,当集簇的校验和状态发生变化时,使用pg_combinebackup会受到限制。 - - - - 请注意,使用完整备份的所有要求同样适用于增量备份。例如,你仍然需要在文件系统备份期间及之后生成的所有 WAL 段文件,以及任何相关的 WAL 历史文件。你仍然需要创建recovery.signal(或standby.signal),并按照所述执行恢复。恢复时需要更早的备份以及使用pg_combinebackup,是在这些要求之外额外增加的条件。请记住,PostgreSQL没有内置机制来判断哪些备份仍然需要作为恢复后续增量备份的基础。你必须自己跟踪完整备份与增量备份之间的关系,并确保在恢复后续增量备份可能还需要它们时,不要删除较早的备份。 - - - - 增量备份通常只对相对较大的数据库有意义,因为其中相当一部分数据不变,或者变化缓慢。对于小数据库,忽略增量备份的存在而直接进行完整备份会更简单,也更容易管理。对于所有数据都被频繁修改的大数据库,增量备份也不会比完整备份小多少。 - - - - 只有当恢复重放会从比它所依赖的前一次备份更晚的检查点开始时,增量备份才有可能进行。如果你在主库上进行增量备份,这个条件总能满足,因为每次备份都会触发新的检查点。在备库上,重放从最近的重启点开始。因此,如果自前一次备份以来活动很少,可能尚未创建新的重启点,备库上的增量备份就可能失败。 - - - 使用低级 API 进行基础备份 - - 除了使用进行完整或增量基础备份之外,你还可以使用低级 API 制作基础备份。这个过程比pg_basebackup方法多几个步骤,但相对简单。极其重要的是,这些步骤必须按顺序执行,并且在进行下一步之前必须确认当前步骤已经成功。 - + 使用低级 API 制作基础备份的过程,比 方法多几个步骤,但相对简单。务必按顺序执行这些步骤,并在继续下一步之前确认当前步骤成功。 多个备份可以并发运行(无论是通过该备份 API 启动的,还是通过启动的)。 @@ -565,12 +535,7 @@ SELECT * FROM pg_backup_stop(wait_for_archive => true); - 如果你正在恢复完整备份,可以把数据库文件直接恢复到目标目录中。务必确保它们以正确的所有者(数据库系统用户,而不是root!)和正确的权限恢复。如果使用了表空间,还应验证pg_tblspc/中的符号链接是否已正确恢复。 - - - - - 如果你正在恢复增量备份,则需要把该增量备份以及它直接或间接依赖的所有较早备份都恢复到执行恢复的那台机器上。这些备份必须放在单独的目录中,而不是你希望最终运行服务器的目标目录中。完成后,使用pg_combinebackup从完整备份和所有后续增量备份中提取数据,并向目标目录写出一份合成的完整备份。和上面一样,验证权限以及表空间链接是否正确。 + 从文件系统备份中恢复数据库文件。务必确保它们以正确的所有者(数据库系统用户,而不是root!)和正确的权限恢复。如果使用了表空间,还应验证pg_tblspc/中的符号链接是否已正确恢复。 @@ -601,20 +566,16 @@ SELECT * FROM pg_backup_stop(wait_for_archive => true); - - 这一切的关键在于设置一个恢复配置,描述你希望如何恢复,以及恢复应运行到什么位置。其中绝对必须指定的一项是restore_command,它告诉PostgreSQL如何检索已归档的 WAL 文件段。像archive_command一样,它也是一个 shell 命令字符串。它可以包含%f,会被替换为所需日志文件的名称;也可以包含%p,会被替换为复制该日志文件时要使用的路径名。(该路径名相对于当前工作目录,也就是集簇的数据目录。)如果需要在命令中嵌入实际的%字符,请写成%%。最简单而有用的命令类似如下: - + 整个过程的关键,是设置恢复配置,说明希望如何恢复,以及恢复到什么位置。必须指定的设置是 restore_command,它告诉 PostgreSQL 如何获取已归档的 WAL 段文件。与 archive_command 一样,它是一个 shell 命令字符串,可以包含 %f,该标记会被替换为所需日志文件的名称;还可以包含 %p,该标记会被替换为日志文件要复制到的路径名。(路径名相对于当前工作目录,即集簇的数据目录。)使用 %% 可以在命令中嵌入实际的 % 字符。最简单的可用命令类似于: restore_command = 'cp /mnt/server/archivedir/%f %p' - - 它会从目录/mnt/server/archivedir中复制先前归档的 WAL 段。当然,你也可以使用复杂得多的方案,甚至写一个 shell 脚本来要求操作员装载合适的磁带。 - +这会复制先前归档的 WAL 段,来源目录为 /mnt/server/archivedir。当然,也可以使用复杂得多的命令,甚至可以使用要求操作人员挂载相应磁带的 shell 脚本。 - 重要的是,该命令在失败时必须返回非零退出状态。系统调用该命令来请求归档中不存在的文件;遇到这种情况时,它就应返回非零值。这不是一种错误情况。例外是,如果该命令被信号终止(用于数据库服务器关闭的SIGTERM除外),或者因 shell 错误(如命令未找到)而失败,那么恢复将中止,服务器也不会启动。 + 重要的是,该命令在失败时必须返回非零退出状态。系统调用该命令来请求归档中不存在的文件;遇到这种情况时,它必须返回非零值。这不是一种错误情况。例外是,如果该命令被信号终止(用于数据库服务器关闭的SIGTERM除外),或者因 shell 错误(如命令未找到)而失败,那么恢复将中止,服务器也不会启动。 - 被请求的文件并不全都是 WAL 段文件;你还应预期会收到对带有.history后缀文件的请求。另外请注意,%p路径的基本文件名会与%f不同;不要指望它们可以互换使用。 + 被请求的文件并不全都是 WAL 段文件;你还应预期会收到对带有.history后缀文件的请求。另外请注意,%p路径的文件名部分会与%f不同;不要指望它们可以互换使用。 @@ -622,16 +583,16 @@ restore_command = 'cp /mnt/server/archivedir/%f %p' - 通常,恢复会处理完所有可用的 WAL 段,从而把数据库恢复到当前时间点(或者在可用 WAL 段所允许的情况下尽可能接近当前时间点)。因此,一次正常恢复通常会以一条file not found消息结束,具体错误文本取决于你选择的restore_command。在恢复开始时,你也可能看到一条针对类似00000001.history文件的错误消息。这同样是正常的,在简单恢复场景中并不表示有问题;相关讨论见。 + 通常,恢复会处理完所有可用的 WAL 段,从而把数据库恢复到当前时间点(或者在可用 WAL 段所允许的情况下尽可能接近当前时间点)。因此,一次正常恢复会以一条file not found消息结束,具体错误文本取决于你选择的restore_command。在恢复开始时,你也可能看到一条针对类似00000001.history文件的错误消息。这同样是正常的,在简单恢复场景中并不表示有问题;相关讨论见 - 如果你希望恢复到过去的某个时间点(例如恢复到那位初级 DBA 删掉你的主事务表之前),只需指定所需的停止点即可。这个停止点也称为恢复目标,可以通过日期/时间、命名恢复点或者某个特定事务 ID 完成时刻来指定。在目前的实现下,只有日期/时间和命名恢复点这两种方式真正比较实用,因为没有工具能够帮助你足够准确地识别应使用哪个事务 ID。 + 如果你希望恢复到过去的某个时间点(例如恢复到那位初级 DBA 删掉你的主事务表之前),只需指定所需的停止点即可。这个停止点也称为恢复目标,可以通过日期/时间、命名恢复点或者某个特定事务 ID 完成时刻来指定。在撰写本文时,只有日期/时间和命名恢复点这两种方式真正比较实用,因为没有工具能够帮助你足够准确地识别应使用哪个事务 ID。 - 停止点必须晚于基础备份的结束时间,也就是pg_backup_stop的结束时间。你不能用某次基础备份恢复到该备份仍在进行中的时间点。(若要恢复到这样的时间点,必须回到更早的一次基础备份,再从那里向前滚动。) + 停止点必须晚于基础备份的结束时间,也就是pg_backup_stop的结束时间。你不能用某次基础备份恢复到该备份仍在进行中的时间点。(若要恢复到这样的时间点,必须回到更早的一次基础备份,再从那里向前重放日志。) @@ -645,24 +606,18 @@ restore_command = 'cp /mnt/server/archivedir/%f %p' 时间线 - timelines + 时间线 - - 把数据库恢复到过去某个时间点的能力,会带来一些复杂性,颇有点像关于时间旅行和平行宇宙的科幻小说。例如,在数据库的原始历史中,假设你在星期二晚上 5:15 删掉了一张关键表,但直到星期三中午才意识到自己的错误。于是你拿出备份,把系统恢复到星期二晚上 5:14,并重新上线运行。在数据库宇宙的这条历史中,你从未删掉那张表。但如果你后来发现这并不是个好主意,并且想回到原始历史中的星期三上午某个时间点,就办不到了,因为在数据库重新上线运行期间,它可能已经覆盖了某些 WAL 段文件,而这些文件本来能把你带回到现在想回去的那个时刻。因此,为了避免这种情况,你需要把时间点恢复之后生成的那一串 WAL 记录,与数据库原始历史中生成的那些 WAL 记录区分开来。 - + 能够将数据库恢复到过去某个时间点,也会带来一些类似科幻故事中时间旅行和平行宇宙的复杂情况。例如,假设在数据库原来的历史中,你在周二下午 5:15 删除了一张重要的表,直到周三中午才发现错误。你从容地取出备份,将数据库恢复到周二下午 5:14,然后重新投入运行。在数据库宇宙的这段历史中,你从未删除过那张表。但假设你后来发现这样做不太合适,希望回到原来历史中的周三上午某个时刻。如果数据库恢复运行后覆盖了通往该时刻所需的某些 WAL 段文件,就无法回去了。因此,为了避免这种情况,需要区分时间点恢复后产生的一系列 WAL 记录与数据库原来历史中产生的记录。 - - 为了解决这个问题,PostgreSQL引入了时间线的概念。每当一次归档恢复完成时,系统都会创建一条新的时间线,用来标识此次恢复之后生成的 WAL 记录序列。时间线 ID 是 WAL 段文件名的一部分,因此新的时间线不会覆盖先前时间线产生的 WAL 数据。实际上,完全可以归档许多不同的时间线。虽然这看起来像是个没什么用的特性,但它往往能救命。设想这样一种情况:你不太确定应恢复到哪个时间点,因此不得不通过反复试验做几次时间点恢复,直到找到从旧历史分叉出去的最佳位置。如果没有时间线,这个过程很快就会变成一团无法管理的混乱。有了时间线,你可以恢复到任何先前状态,包括那些你早先已经放弃的时间线分支上的状态。 - + 为解决这一问题,PostgreSQL 引入了时间线的概念。每当归档恢复完成,系统都会创建一条新时间线,用于标识此次恢复之后产生的一系列 WAL 记录。时间线 ID 是 WAL 段文件名的一部分,因此新时间线不会覆盖旧时间线产生的 WAL 数据。实际上,可以归档许多不同的时间线。这个功能看似没什么用,却常常能救急。比如,你不能确定应该恢复到哪个时间点,需要反复尝试时间点恢复,直到找到脱离旧历史的最佳分支点。没有时间线,这个过程很快就会乱得无法管理。有了时间线,就可以恢复到任何先前的状态,包括早先已放弃的时间线分支中的状态。 每当创建一条新的时间线时,PostgreSQL都会创建一个时间线历史文件,记录它是从哪条时间线、在何时分叉出来的。当从包含多条时间线的归档中恢复时,这些历史文件对于系统选取正确的 WAL 段文件是必需的。因此,它们会像 WAL 段文件一样被归档到 WAL 归档区域。历史文件只是很小的文本文件,因此长期保存它们既便宜也合适(而段文件通常很大)。如果你愿意,还可以在历史文件中加入注释,记录创建这条时间线的方式和原因。当你因实验而积累出一批错综复杂的时间线时,这类注释会特别有价值。 - - 恢复的默认行为是恢复到归档中找到的最新时间线。如果你希望恢复到执行基础备份时的当前时间线,或者恢复到某个指定的子时间线(也就是说,你想回到某个本身就是在一次恢复尝试之后才产生的状态),就需要指定current,或者在中指定目标时间线 ID。你不能恢复到那些在基础备份之前就已经分叉出去的时间线。 - + 默认的恢复行为是恢复到归档中找到的最新时间线。如果希望恢复到制作基础备份时的当前时间线,或者某条特定的子时间线(即希望返回到一次恢复尝试之后产生的某个状态),需要在 中指定 current 或目标时间线 ID。不能恢复到在基础备份之前就已分支出去的时间线。 @@ -673,14 +628,14 @@ restore_command = 'cp /mnt/server/archivedir/%f %p' - 单机热备份 + 独立热备份 - 可以利用PostgreSQL的备份设施生成单机热备份。这些备份不能用于时间点恢复,但它们的制作和恢复通常都比pg_dump转储快得多。(它们也比pg_dump转储大得多,因此在某些情况下速度优势可能会被抵消。) + 可以利用PostgreSQL的备份设施生成独立热备份。这些备份不能用于时间点恢复,但它们的制作和恢复通常都比pg_dump转储快得多。(它们也比pg_dump转储大得多,因此在某些情况下速度优势可能会被抵消。) - 和基础备份一样,生成单机热备份最简单的方法是使用工具。如果在调用它时包含-X参数,使用该备份所需的全部预写式日志都会自动包含在备份中,恢复该备份时也不需要额外动作。 + 和基础备份一样,生成独立热备份最简单的方法是使用工具。如果在调用它时包含-X参数,使用该备份所需的全部预写式日志都会自动包含在备份中,恢复该备份时也不需要额外动作。 @@ -711,7 +666,7 @@ archive_command = 'local_backup_script.sh "%p" "%f"' - 脚本中可能需要解决的需求示例包括: + 可以在脚本中处理的需求示例包括: @@ -720,7 +675,7 @@ archive_command = 'local_backup_script.sh "%p" "%f"' - 把 WAL 文件成批处理,使其每三个小时传输一次,而不是每生成一个就传一次 + 把 WAL 文件成批处理,使其每三个小时传输一次,而不是每次只传输一个 @@ -759,14 +714,14 @@ archive_command = 'local_backup_script.sh "%p" "%f"' - CREATE TABLESPACE命令会以字面绝对路径写入 WAL,因此重放时会按相同的绝对路径创建表空间。如果日志在另一台机器上重放,这可能并不理想。即使日志在同一台机器上、但重放到新的数据目录中,也可能有危险:重放仍会覆盖原表空间的内容。为避免此类潜在陷阱,最佳做法是在创建或删除表空间后重新执行一次基础备份。 + CREATE TABLESPACE命令会以字面绝对路径写入 WAL,因此重放时会按相同的绝对路径创建表空间。如果 WAL 在另一台机器上重放,这可能并不理想。即使 WAL 在同一台机器上、但重放到新的数据目录中,也可能有危险:重放仍会覆盖原表空间的内容。为避免此类潜在陷阱,最佳做法是在创建或删除表空间后重新执行一次基础备份。 - 还应注意,默认的WAL格式相当臃肿,因为它包含许多磁盘页面快照。这些页面快照是为支持崩溃恢复而设计的,因为我们可能需要修复部分写入的磁盘页。根据你的系统硬件和软件情况,部分写入的风险可能小到可以忽略;在这种情况下,可以通过参数关闭页面快照,从而显著减少已归档日志的总量。(在这样做之前,请先阅读中的说明和警告。)关闭页面快照并不妨碍把日志用于 PITR 操作。未来一个可能的开发方向,是在full_page_writes开启的情况下,通过去除不必要的页面副本来压缩归档 WAL 数据。在此之前,管理员可以考虑尽可能增大检查点间隔相关参数,以减少 WAL 中包含的页面快照数量。 + 还应注意,默认的WAL格式相当臃肿,因为它包含许多磁盘页面快照。这些页面快照是为支持崩溃恢复而设计的,因为我们可能需要修复部分写入的磁盘页。根据你的系统硬件和软件情况,部分写入的风险可能小到可以忽略;在这种情况下,可以通过参数关闭页面快照,从而显著减少已归档 WAL 文件的总量。(在这样做之前,请先阅读中的说明和警告。)关闭页面快照并不妨碍把 WAL 用于 PITR 操作。未来一个可能的开发方向,是在full_page_writes开启的情况下,通过去除不必要的页面副本来压缩归档 WAL 数据。在此之前,管理员可以考虑尽可能增大检查点间隔相关参数,以减少 WAL 中包含的页面快照数量。 diff --git a/zh/15/bki.sgml b/zh/15/bki.sgml index c5ffc2b5..9eeea6db 100644 --- a/zh/15/bki.sgml +++ b/zh/15/bki.sgml @@ -74,9 +74,9 @@ descr => 'database\'s default template', datname => 'template1', encoding => 'ENCODING', datlocprovider => 'LOCALE_PROVIDER', datistemplate => 't', - datallowconn => 't', dathasloginevt => 'f', datconnlimit => '-1', datfrozenxid => '0', + datallowconn => 't', datconnlimit => '-1', datfrozenxid => '0', datminmxid => '1', dattablespace => 'pg_default', datcollate => 'LC_COLLATE', - datctype => 'LC_CTYPE', datlocale => 'DATLOCALE', datacl => '_null_' }, + datctype => 'LC_CTYPE', daticulocale => 'ICU_LOCALE', datacl => '_null_' }, ] ]]> diff --git a/zh/15/brin.sgml b/zh/15/brin.sgml index c4f55d51..626d0612 100644 --- a/zh/15/brin.sgml +++ b/zh/15/brin.sgml @@ -4,11 +4,11 @@ BRIN 索引 - index + 索引 BRIN - + 简介 @@ -25,8 +25,7 @@ - 如果索引中存储的摘要信息与查询条件相一致BRIN - 索引就可以通过常规位图索引扫描来满足查询,并返回每个范围内所有页上的全部元组。 + BRIN 索引可以通过常规位图索引扫描来满足查询;对于每个范围,如果索引中存储的摘要信息与查询条件相一致,就会返回该范围内所有页上的全部元组。 查询执行器负责重新检查这些元组,并丢弃不匹配查询条件的元组 — 换句话说,这些索引是有损的。 由于 BRIN 索引非常小,与顺序扫描相比,扫描索引只会带来很小的额外开销, 但可以避免扫描那些已知不包含匹配元组的大块表数据。 @@ -46,7 +45,7 @@ 但与此同时,存储的摘要数据也会更精确,并且在索引扫描期间可以跳过更多数据块。 - + 索引维护 @@ -68,9 +67,7 @@ - 最后,还可以使用下列函数(这些函数运行期间, - 会临时改为 - pg_catalog, pg_temp): + 最后,还可以使用下列函数: brin_summarize_new_values(regclass) @@ -85,7 +82,7 @@ 当启用自动摘要时,一旦检测到向下一个块范围第一页的第一项执行了插入, - 就会向 autovacuum 发送请求,要求对该块范围执行定向摘要。 + 就会向 autovacuum 发送请求,要求对前一个块范围执行定向摘要。 该请求会在同一数据库中的某个 autovacuum 工作进程下一次结束运行时得到处理。 如果请求队列已满,该请求就不会被记录,并会向服务器日志发送一条消息: @@ -101,10 +98,10 @@ LOG: request for BRIN range summarization for index "brin_wi_idx" page 128 was 详见 - + - + 内置操作符类 @@ -703,7 +700,7 @@ LOG: request for BRIN range summarization for index "brin_wi_idx" page 128 was - + 操作符类参数 @@ -759,11 +756,11 @@ LOG: request for BRIN range summarization for index "brin_wi_idx" page 128 was - - - + + + 可扩展性 @@ -790,13 +787,13 @@ LOG: request for BRIN range summarization for index "brin_wi_idx" page 128 was typedef struct BrinOpcInfo { - /* Number of columns stored in an index column of this opclass */ + /* 此操作符类在一个索引列中存储的列数 */ uint16 oi_nstored; - /* Opaque pointer for the opclass' private use */ + /* 供操作符类私有使用的不透明指针 */ void *oi_opaque; - /* Type cache entries of the stored columns */ + /* 所存储列的类型缓存条目 */ TypeCacheEntry *oi_typcache[FLEXIBLE_ARRAY_MEMBER]; } BrinOpcInfo; @@ -1012,62 +1009,62 @@ typedef struct BrinOpcInfo 操作符策略 1 - left-of 操作符 + 位于左侧的操作符 操作符策略 4 操作符策略 2 - does-not-extend-to-the-right-of 操作符 + 不延伸到右侧的操作符 操作符策略 5 操作符策略 3 - overlaps 操作符 + 重叠操作符 操作符策略 4 - does-not-extend-to-the-left-of 操作符 + 不延伸到左侧的操作符 操作符策略 1 操作符策略 5 - right-of 操作符 + 位于右侧的操作符 操作符策略 2 - 操作符策略 6, 18 - same-as-or-equal-to 操作符 + 操作符策略 6、18 + 相同或等于操作符 操作符策略 7 - 操作符策略 7, 16, 24, 25 - contains-or-equal-to 操作符 + 操作符策略 7、16、24、25 + 包含或等于操作符 - 操作符策略 8, 26, 27 - is-contained-by-or-equal-to 操作符 + 操作符策略 8、26、27 + 被包含或等于操作符 操作符策略 3 操作符策略 9 - does-not-extend-above 操作符 + 不延伸到上方的操作符 操作符策略 11 操作符策略 10 - is-below 操作符 + 位于下方的操作符 操作符策略 12 操作符策略 11 - is-above 操作符 + 位于上方的操作符 操作符策略 9 操作符策略 12 - does-not-extend-below 操作符 + 不延伸到下方的操作符 操作符策略 10 @@ -1113,12 +1110,12 @@ typedef struct BrinOpcInfo 要为仅实现等值操作符且支持哈希的数据类型编写操作符类,可以按 - 所示,将 bloom 支持过程与相应操作符一起使用。 - 所有操作符类成员(过程和操作符)都是必需的。 + 所示,将 bloom 支持函数与相应操作符一起使用。 + 所有操作符类成员(函数和操作符)都是必需的。 - bloom 操作符类的过程和支持编号 + bloom 操作符类的函数和支持编号 @@ -1128,28 +1125,28 @@ typedef struct BrinOpcInfo - 支持过程 1 + 支持函数 1 内部函数brin_bloom_opcinfo() - 支持过程 2 + 支持函数 2 内部函数brin_bloom_add_value() - 支持过程 3 + 支持函数 3 内部函数brin_bloom_consistent() - 支持过程 4 + 支持函数 4 内部函数brin_bloom_union() - 支持过程 5 + 支持函数 5 内部函数brin_bloom_options() - 支持过程 11 - 计算元素哈希值的函数 + 支持函数 11 + 计算元素 hash 值的函数 操作符策略 1 @@ -1160,20 +1157,20 @@ typedef struct BrinOpcInfo
- 支持过程编号 1 至 10 保留给 BRIN 内部函数,因此 SQL 层函数从编号 11 开始。 + 支持函数编号 1 至 10 保留给 BRIN 内部函数,因此 SQL 层函数从编号 11 开始。 支持函数 11 是构建索引所需的主要函数。 - 它应接受一个与操作符类数据类型相同的参数,并返回该值的哈希值。 + 它应接受一个与操作符类数据类型相同的参数,并返回该值的 hash 值。 minmax-multi 操作符类也面向实现全序集的数据类型,可以看作 minmax 操作符类的简单扩展。 minmax 操作符类把每个块范围中的值摘要为单个连续区间,而 minmax-multi 则允许将其摘要为多个较小区间,以改进对离群值的处理。 - 可以按 所示,将 minmax-multi 支持过程与相应操作符一起使用。 - 所有操作符类成员(过程和操作符)都是必需的。 + 可以按 所示,将 minmax-multi 支持函数与相应操作符一起使用。 + 所有操作符类成员(函数和操作符)都是必需的。 - minmax-multi 操作符类的过程和支持编号 + minmax-multi 操作符类的函数和支持编号 @@ -1183,27 +1180,27 @@ typedef struct BrinOpcInfo - 支持过程 1 + 支持函数 1 内部函数brin_minmax_multi_opcinfo() - 支持过程 2 + 支持函数 2 内部函数brin_minmax_multi_add_value() - 支持过程 3 + 支持函数 3 内部函数brin_minmax_multi_consistent() - 支持过程 4 + 支持函数 4 内部函数brin_minmax_multi_union() - 支持过程 5 + 支持函数 5 内部函数brin_minmax_multi_options() - 支持过程 11 + 支持函数 11 计算两个值之间距离(范围长度)的函数 @@ -1241,5 +1238,5 @@ typedef struct BrinOpcInfo minmax 的示例见 float4_minmax_ops,inclusion 的示例见 box_inclusion_ops。 - + diff --git a/zh/15/btree.sgml b/zh/15/btree.sgml index 9c505b78..946c009e 100644 --- a/zh/15/btree.sgml +++ b/zh/15/btree.sgml @@ -4,11 +4,11 @@ B-树索引 - index + 索引 B-树 - + 简介 @@ -18,16 +18,16 @@ - 由于每个 B-树 操作符类都会为其数据类型施加一种排序顺序,B-树 + 由于每个 B-树操作符类都会为其数据类型施加一种排序顺序,B-树 操作符类(更准确地说,是操作符族)已经成为 PostgreSQL 用来统一表示和理解排序语义的方式。因此,它们具备了一些超出单纯支持 - B-树 索引所需范围的特性,系统中某些与 btree AM + B-树索引所需范围的特性,系统中某些与 B-树 AM 相距甚远的部分也会利用它们。 - + - + B-树操作符类的行为 @@ -55,7 +55,7 @@ - = 操作符必须是一种等价关系;也就是说,对于该数据类型的所有非空值 + = 操作符必须是一种等价关系;也就是说,对于该数据类型的所有非 null 值 ABC: @@ -93,7 +93,7 @@ - < 操作符必须是一种强排序关系;也就是说,对于所有非空值 + < 操作符必须是一种强排序关系;也就是说,对于所有非 null 值 ABC: @@ -123,7 +123,7 @@ - 此外,该顺序还是全序的;也就是说,对于所有非空值 + 此外,该顺序还是全序的;也就是说,对于所有非 null 值 AB: @@ -171,24 +171,24 @@ 很容易理解为什么 B-树 索引要求这些定律在单一数据类型内部成立:没有这些定律,就不存在可用于排列键的顺序。此外,使用不同数据类型比较键的索引搜索,也要求跨两种数据类型的比较行为合理一致。把这些要求扩展到一个族内的三种或更多数据类型,虽然并非 B-树 索引机制本身的严格要求,但规划器会出于优化目的依赖它们。 - + - + B-树支持函数 - 如所示,btree 定义了一个必需和五个可选的支持函数。六个用户定义的方法如下: + 如所示,B-树定义了一个必需和四个可选的支持函数。五个用户定义的方法如下: order - 对于 B-树 操作符族为其提供比较操作符的每一种数据类型组合,都必须提供一个比较支持函数。该函数在 + 对于 B-树操作符族为其提供比较操作符的每一种数据类型组合,都必须提供一个比较支持函数。该函数在 pg_amproc 中注册,支持函数编号为 1,并且 amproclefttype/amprocrighttype 要等于该比较的左右数据类型(也就是与匹配操作符在 - pg_amop 中注册时相同的数据类型)。比较函数必须接受两个非空值 + pg_amop 中注册时相同的数据类型)。比较函数必须接受两个非 null 值 AB,并返回一个 int32 值,其值为 < 0、 @@ -197,12 +197,12 @@ < BA = BA - > B。不允许返回空值:该数据类型的所有值都必须可比较。示例见 + > B。不允许返回 null:该数据类型的所有值都必须可比较。示例见 src/backend/access/nbtree/nbtcompare.c - 如果参与比较的值属于可排序数据类型,则会通过标准的 + 如果参与比较的值属于支持排序规则的数据类型,则会通过标准的 PG_GET_COLLATION() 机制,把适当的排序规则 OID 传递给比较支持函数。 @@ -223,11 +223,11 @@ in_range - in_range support functions + in_range 支持函数 - support functions + 支持函数 in_range @@ -266,7 +266,7 @@ returns bool - in_range 函数的核心语义取决于这两个 Boolean + in_range 函数的核心语义取决于这两个布尔 标志参数。它应当先对 baseoffset 做加法或减法,再把 val 与结果比较,具体如下: @@ -383,7 +383,7 @@ returns bool - 如果被排序的类型(type1)属于可排序数据类型,则会通过标准的 + 如果被排序的类型(type1)属于支持排序规则的数据类型,则会通过标准的 PG_GET_COLLATION() 机制,把适当的排序规则 OID 传递给 in_range 函数。 @@ -408,12 +408,7 @@ returns bool equalimage(opcintype oid) returns bool - 返回值是关于某个操作符类及其排序规则的静态信息。返回 - true 表示:该操作符类的 - order 函数被保证只有在返回 - 0arguments are equal)时,其 - AB - 参数才是可以互换而不损失任何语义信息的。如果未注册 + 返回值是关于某个操作符类及其排序规则的静态信息。返回 true 表示可以保证:该操作符类的 order 函数只有在其 AB 参数也能够互换而不损失任何语义信息时,才会返回 0参数相等)。如果未注册 equalimage 函数,或其返回 false,就表示不能假定该条件成立。 @@ -421,7 +416,7 @@ equalimage(opcintype oid) returns bool opcintype 参数是该操作符类所索引数据类型的 pg_type.oid。这只是为了方便在不同操作符类之间复用同一个底层 equalimage 函数。如果 - opcintype 是可排序数据类型,则会通过标准的 + opcintype 是支持排序规则的数据类型,则会通过标准的 PG_GET_COLLATION() 机制,把适当的排序规则 OID 传递给 equalimage 函数。 @@ -453,7 +448,7 @@ equalimage(opcintype oid) returns bool 发行版中包含的操作符类遵循的惯例是:注册一个现成的通用 equalimage 函数。大多数操作符类注册 btequalimage(),这表示去重在无条件下都是安全的。像 - text 这样可排序数据类型的操作符类会注册 + text 这样支持排序规则的数据类型的操作符类会注册 btvarstrequalimage(),这表示在确定性排序规则下去重是安全的。第三方扩展的最佳实践则是注册它们自己的自定义函数,以保留控制权。 @@ -489,38 +484,18 @@ options(relopts local_relopts *) returns - - skipsupport - - - 可选地,B-树 操作符族可以提供skip 支持函数,注册为支持函数编号 - 6。这些函数为 B-树 - 代码提供了一种按键空间顺序遍历某个操作符类底层输入类型所能表示的全部可能值的方法。当核心代码应用跳过扫描优化时,就会用到它。相关 - API 定义在 src/include/utils/skipsupport.h - 中。 - - - 没有提供 skip 支持函数的操作符类,仍然可以使用跳过扫描。核心代码仍可采用其后备策略,尽管对于某些离散类型来说,这种策略可能并非最优。对于连续类型上的操作符类,提供 - skip 支持函数通常没有意义(甚至可能不可行)。 - - - 操作符族注册跨类型的 skipsupport - 函数并不合理,尝试这样做会导致错误。因为要确定下一个可被索引的值,必须通过递增一个从索引元组复制出来的值来完成。所生成的值都必须属于同一种底层数据类型(也就是被跳过的索引列的 opclass 输入类型)。 - - - - + - + 实现 本节介绍一些可能对高级用户有用的 B-树索引实现细节。若要查看更详细、更加侧重内部机制的 B-树实现说明,请参见源码发布包中的 src/backend/access/nbtree/README - + B-树结构 PostgreSQL 的 B-树 @@ -531,9 +506,9 @@ options(relopts local_relopts *) returns 当现有叶页无法容纳一个新传入的元组时,B-树索引就会增加新的叶页。一次页拆分操作会把原本属于溢出页的一部分项移动到新页中,从而为这些项腾出空间。页拆分还必须在父页中插入一个指向新页的下行链接,这又可能导致父页继续拆分。页拆分会以递归的方式向上级联。当根页最终也容纳不下新的下行链接时,就会发生一次根页拆分操作。它通过创建一个位于原始根页之上的新根页,为树结构增加一个新的层级。 - + - + 自底向上索引删除 B-树索引并不直接知道,在 MVCC @@ -547,7 +522,7 @@ options(relopts local_relopts *) returns B-树索引会通过执行自底向上索引删除轮次,增量地删除这类版本频繁更替产生的索引元组。每一轮删除都是因预期中的版本频繁更替页拆分而触发的。这只会发生在那些没有被 - UPDATE 语句逻辑修改的索引上,否则过时版本就会集中积累在某些特定页面中。通常可以避免页拆分,不过也可能出现某些实现层面的启发式规则甚至一个垃圾索引元组都识别不出来、删不掉的情况(这时就要靠页拆分或一次去重轮次来解决新元组放不进叶页的问题)。任何一次索引扫描在单个逻辑行上必须穿越的最坏版本数,是影响整个系统响应能力和吞吐量的重要因素。一次自底向上索引删除轮次会基于涉及逻辑行与版本的定性区别,针对单个叶页中疑似垃圾的元组。这与自动清理工作进程执行的自顶向下索引清理不同,后者是在超出某些定量的表级阈值时触发的(见)。 + UPDATE 语句逻辑修改的索引上;如果不执行这类删除,过时版本就会集中积累在某些特定页面中。通常可以避免页拆分,不过也可能出现某些实现层面的启发式规则甚至一个垃圾索引元组都识别不出来、删不掉的情况(这时就要靠页拆分或一次去重轮次来解决新元组放不进叶页的问题)。任何一次索引扫描在单个逻辑行上必须穿越的最坏版本数,是影响整个系统响应能力和吞吐量的重要因素。一次自底向上索引删除轮次会基于涉及逻辑行与版本的定性区别,针对单个叶页中疑似垃圾的元组。这与自动清理工作进程执行的自顶向下索引清理不同,后者是在超出某些定量的表级阈值时触发的(见)。 @@ -578,16 +553,16 @@ options(relopts local_relopts *) returns (当然,这绝不可能发生在生命周期跨越同一个 VACUUM 周期的两个逻辑行之间)。 - + - + 去重 重复项是这样一种叶页元组(即指向表中行的元组):其中所有被索引的键列值,都与同一索引中至少另一个叶页元组对应列的值相匹配。重复元组在实践中相当常见。当启用一种可选技术时,B-树索引可以为重复项采用一种特殊且节省空间的表示形式:去重 去重通过周期性地把一组组重复元组合并起来,为每一组形成一个 - posting list 元组。在这种表示中,列键值只出现一次,后面跟着一个排好序的 + 倒排列表 元组。在这种表示中,列键值只出现一次,后面跟着一个排好序的 TID 数组,指向表中的各行。这能显著减小那些每个值(或每一种不同列值组合)平均会出现多次的索引的存储大小。查询延迟可能显著降低,整体查询吞吐量也可能显著提升,例行索引清理的开销同样可能显著减少。 @@ -601,14 +576,14 @@ options(relopts local_relopts *) returns 去重过程是惰性发生的:当插入一个放不进现有叶页的新项时,只有在索引元组删除也无法为该新项释放足够空间的情况下,才会进行去重(通常只会短暂考虑删除,然后就跳过)。与 - GIN 的 posting list 元组不同,B-树的 posting list - 元组不需要在每次插入新的重复项时都扩展;它们只是叶页原始逻辑内容的一种替代物理表示。这种设计优先考虑混合读写工作负载下的一致性能。大多数客户端应用至少都能从去重中获得适度的性能收益。去重默认启用。 + GIN 的倒排列表元组不同,B-树的倒排列表 + 元组不需要在每次插入新的重复项时都扩展;它们只是叶页原始逻辑内容的一种替代物理表示。这种设计优先考虑混合读写工作负载下的稳定性能。大多数客户端应用至少都能从去重中获得适度的性能收益。去重默认启用。 CREATE INDEXREINDEX - 都会应用去重来创建 posting list - 元组,只是两者采用的策略略有不同。对于从表中取出的已排序输入中遇到的每一组普通重复元组,都会在被加入当前待写入叶页之前先合并成一个 - posting list 元组。每个 posting list 元组都会尽量容纳更多的 + 都会应用去重来创建倒排列表 + 元组,不过它们采用的策略与上述过程略有不同。对于从表中取出的已排序输入中遇到的每一组普通重复元组,都会在被加入当前待写入叶页之前先合并成一个 + 倒排列表元组。每个倒排列表元组都会尽量容纳更多的 TID。叶页按通常方式写出,不需要额外独立的去重过程。由于 CREATE INDEXREINDEX 都是一次性的批处理操作,这种策略非常适合它们。 @@ -617,14 +592,14 @@ options(relopts local_relopts *) returns 如果某个写密集型工作负载由于索引中的重复值很少甚至没有,而无法从去重中获益,那么它会承担很小且固定的性能损耗(除非显式禁用去重)。 deduplicate_items 存储参数可用于在单个索引内禁用去重。而只读工作负载绝不会因此遭受性能损失,因为读取 - posting list 元组至少与读取标准元组表示一样高效。禁用去重通常并没有帮助。 + 倒排列表元组至少与读取标准元组表示一样高效。禁用去重通常并没有帮助。 有时唯一索引(以及唯一约束)也可以使用去重。这允许叶页临时吸收因版本频繁更替产生的额外重复项。唯一索引中的去重能够增强自底向上索引删除,特别是在长事务持有阻塞垃圾回收的快照时。其目标是为自底向上索引删除策略再次发挥作用争取时间。把页拆分推迟到某个单独的长事务自然结束之后,可能使一次自底向上删除轮次在较早一次失败的地方获得成功。 - 系统会应用一种特殊的启发式规则,来判定唯一索引中是否应当执行一次去重轮次。它往往可以直接跳到拆分叶页,从而避免把周期浪费在无益的去重过程中而造成性能损耗。如果你担心去重的开销,可以考虑有选择地设置 + 系统会应用一种特殊的启发式规则,来判定唯一索引中是否应当执行一次去重轮次。它往往可以直接跳到拆分叶页,从而避免把处理器周期浪费在无益的去重过程中而造成性能损耗。如果你担心去重的开销,可以考虑有选择地设置 deduplicate_items = off。在唯一索引中保持去重启用,坏处很小。 @@ -648,7 +623,7 @@ options(relopts local_relopts *) returns numeric 不能使用去重。必须保留相等的 datum - 之间的小数位数。 + 之间的显示小数位数。 @@ -694,7 +669,7 @@ options(relopts local_relopts *) returns - + diff --git a/zh/15/catalogs.sgml b/zh/15/catalogs.sgml index 03db00cd..6a93f7bf 100644 --- a/zh/15/catalogs.sgml +++ b/zh/15/catalogs.sgml @@ -678,7 +678,7 @@ t = 表(包括物化视图), - i = 索引. + i = 索引。 @@ -931,7 +931,7 @@
- amproclefttypeamprocrighttype列的通常解释是它们标识了一个特定支持过程所支持的操作符的左右输入类型。对于某些访问方法它们和支持过程本身的输入数据类型相匹配,而对其他的则不会匹配。对于一个索引有一个默认支持过程的概念,这些支持过程的amproclefttypeamprocrighttype都等于索引操作符类的opcintype。 + amproclefttypeamprocrighttype列的通常解释是它们标识了一个特定支持函数所支持的操作符的左右输入类型。对于某些访问方法它们和支持函数本身的输入数据类型相匹配,而对其他的则不会匹配。对于一个索引有一个默认支持函数的概念,这些支持函数的amproclefttypeamprocrighttype都等于索引操作符类的opcintype
@@ -1068,6 +1068,20 @@ + + + attstattarget int4 + + + attstattarget 控制 + ANALYZE 为该列收集统计信息时的细节级别。 + 零值表示不应收集统计信息。 + 负值表示使用系统默认统计目标。 + 正值的确切含义依赖于数据类型。 + 对于标量数据类型,attstattarget 既是要收集的高频值目标个数,也是要创建的直方图桶目标个数。 + + + attlen int2 @@ -1088,21 +1102,30 @@ - atttypmod int4 + attndims int4 - atttypmod记录了在表创建时提供的类型相关数据(例如一个varchar列的最大长度)。 - 它会被传递给类型相关的输入函数和长度强制函数。对于那些不需要atttypmod的类型,这个值通常总是为-1。 + 如果该列是数组类型,则为维数;否则为 0。 + (目前并不会强制检查数组维数,因此任何非零值实际上都只意味着这是一个数组。) - attndims int2 + attcacheoff int4 - 如果该列是数组类型,则为维数;否则为 0。 - (目前并不会强制检查数组维数,因此任何非零值实际上都只意味着这是一个数组。) + 在存储中始终为 -1,但装入内存中的行描述符时,可能会更新为该属性在行内偏移量的缓存值 + + + + + + atttypmod int4 + + + atttypmod记录了在表创建时提供的类型相关数据(例如一个varchar列的最大长度)。 + 它会被传递给类型相关的输入函数和长度强制转换函数。对于那些不需要atttypmod的类型,这个值通常为 -1。 @@ -1151,7 +1174,7 @@ attnotnull bool - 此列具有一个非空约束(可能尚未验证) + 这代表一个非空约束 @@ -1170,8 +1193,7 @@ atthasmissing bool - 该列在行中完全缺失时会用到这个列的值,如果在行创建之后增加一个有非易失DEFAULT值的列,就会发生这种情况。 - 实际使用的值被存放在attmissingval列中。 + 此列有一个值,供该列在数据行中完全缺失时使用;在数据行创建之后添加带有非易失 DEFAULT 值的列时,就会出现这种情况。实际使用的值存储在 attmissingval 列中。 @@ -1191,8 +1213,7 @@ 如果是零字节(''),则不是生成列。 - 否则,s = 存储式(stored),v = 虚拟(virtual)。 - 存储式生成列会像普通列一样实际存储;虚拟生成列则在物理上存储为空值,实际值在运行时计算。 + 否则,s = 存储式。(将来可能会添加其他值。) @@ -1201,7 +1222,7 @@ attisdropped bool - 该列被删除且不再有效。一个删除的列仍然物理存在于表中,但是会被分析器忽略并因此无法通过SQL访问。 + 该列被删除且不再有效。一个删除的列仍然物理存在于表中,但是会被解析器忽略并因此无法通过SQL访问。 @@ -1216,7 +1237,7 @@ - attinhcount int2 + attinhcount int4 该列直接祖先的数量。祖先数量非零的列不能被删除,也不能被重命名。 @@ -1229,21 +1250,7 @@ (引用 pg_collation.oid - 该列被定义的排序规则,如果该列不是一个可排序数据类型则为0。 - - - - - - attstattarget int2 - - - attstattarget 控制 - ANALYZE 为该列收集统计信息时的细节级别。 - 零值表示不应收集统计信息。 - 空值表示使用系统默认统计目标。 - 正值的确切含义依赖于数据类型。 - 对于标量数据类型,attstattarget 既是要收集的高频值目标个数,也是要创建的直方图桶目标个数。 + 该列定义的排序规则;如果该列的数据类型不支持排序规则,则为零。 @@ -1252,7 +1259,7 @@ attacl aclitem[] - 列级访问权限, 如果此列上已有特别授予的权限 + 列级访问权限,如果此列上已有特别授予的权限 @@ -1280,7 +1287,7 @@ 这个列中是一个含有一个元素的数组,其中的值被用于该列在行中完全缺失时,如果在行创建之后增加一个有非易失DEFAULT值的列,就会发生这种情况。 - 只有当atthasmissing为真时才使用这个值。如果没有值则该列为空。 + 只有当atthasmissing为真时才使用这个值。如果没有值则该列为空值。 @@ -1288,9 +1295,7 @@ - 在一个被删除的列的pg_attribute的项中,atttypid被重置为0,但attlen以及其他从pg_type拷贝的域仍然有效。 - 这种安排用于处理一种情况,即被删除列的数据类型后来被删除,并且因此不再有相应的pg_type行。 - attlen和其他域可以被用来解释表的一行的内容。 + 在被删除列的 pg_attribute 条目中,atttypid 被重置为零,但 attlen 以及其他从 pg_type 复制的字段仍然有效。这种安排用于应对被删除列的数据类型后来也被删除、因而不再有相应 pg_type 行的情况。attlen 和其他字段可用于解释表中一行的内容。 @@ -1419,7 +1424,7 @@ rolconnlimit int4 - 对于可以登录的角色,本列设置该角色可以同时发起最大连接数。-1表示无限制。 + 对于可以登录的角色,本列设置该角色能够建立的最大并发连接数。-1 表示无限制。 @@ -1428,7 +1433,7 @@ rolpassword text - 加密后的密码;如果未设置则为空。其格式取决于所使用的加密方式。 + 加密后的密码;如果未设置则为空值。其格式取决于所使用的加密方式。 @@ -1437,7 +1442,7 @@ rolvaliduntil timestamptz - 密码过期时间(只用于密码鉴定),如果永不过期则为空 + 密码过期时间(仅用于密码认证);不设过期时间时为空值 @@ -1445,14 +1450,10 @@ - 对于一个MD5加密的密码,rolpassword列将由字符串md5后面跟上一个32字符的十六进制MD5哈希值构成。MD5哈希值将是该用户的密码串接上它们的用户名。例如,如果用户joe的密码是xyzzy,则PostgreSQL将存储xyzzyjoe的md5哈希。 + 对于一个MD5加密的密码,rolpassword列将由字符串md5后面跟上一个32字符的十六进制MD5哈希值构成。MD5 哈希值通过在用户密码后拼接用户名再计算得到。例如,如果用户joe的密码是xyzzy,则PostgreSQL将存储xyzzyjoe的md5哈希。 - - - 对 MD5 加密密码的支持已被弃用,并将在未来的 PostgreSQL 发布中移除。关于迁移到其他密码类型的详细信息,请参见。 - - + 如果密码是使用SCRAM-SHA-256加密的,则格式如下: @@ -1496,14 +1497,7 @@ SCRAM-SHA-256$<iteration count>:&l - - - oid oid - - - 行标识符 - - + @@ -1544,25 +1538,9 @@ SCRAM-SHA-256$<iteration count>:&l - - - inherit_option bool - - - 如果成员会自动继承被授予角色的权限,则为真 - - - - - set_option bool - - - 如果成员可以 - SET ROLE - 到被授予的角色,则为真 - - + + @@ -1582,7 +1560,7 @@ SCRAM-SHA-256$<iteration count>:&l - 需要注意的是,pg_cast并不表示系统知道如何执行的所有类型转换,它只包括那些不能从某些通用规则推导出的转换。例如,一个域及其基类型之间的转换并未显式地在pg_cast中展示。另一个重要的例外是自动的基于 I/O 的类型转换,它们通过数据类型自己的 I/O 函数来转换成(或者转换自)text或其他字符串类型,这些转换也没有显式地在pg_cast中表示。 + 需要注意的是,pg_cast并不表示系统知道如何执行的所有类型转换,它只包括那些不能从某些通用规则推导出的转换。例如,一个域及其基础类型之间的转换并未显式地在pg_cast中展示。另一个重要的例外是自动的基于 I/O 的类型转换,它们通过数据类型自己的 I/O 函数来转换成(或者转换自)text或其他字符串类型,这些转换也没有显式地在pg_cast中表示。 @@ -1687,7 +1665,7 @@ SCRAM-SHA-256$<iteration count>:&l - 目录pg_class描述了具有列或与表类似的其他对象。这包括索引(但请参见pg_index)、序列(但请参见pg_sequence)、视图、物化视图、复合类型和TOAST表;请参见relkind。 + 目录pg_class描述了表以及其他具有列或在其他方面与表类似的对象。这包括索引(但请参见pg_index)、序列(但请参见pg_sequence)、视图、物化视图、复合类型和TOAST表;请参见relkind。 在下面,当我们指的是所有这些类型的对象时,我们称之为关系(relations)。并非所有pg_class的列对所有关系类型都有意义。 @@ -1739,9 +1717,7 @@ SCRAM-SHA-256$<iteration count>:&l reltype oid (引用 pg_type.oid) - - 该关系可能对应的表行类型的数据类型 OID;对索引为 0,而序列和 TOAST 表没有pg_type项 - + 与此表的行类型对应的数据类型的 OID(如有);索引、序列和 TOAST 表没有pg_type项,此值为零 @@ -1769,9 +1745,7 @@ SCRAM-SHA-256$<iteration count>:&l relam oid (引用 pg_am.oid) - - 用于访问该表或索引的访问方法。如果该关系是序列或者没有磁盘文件,则此字段无意义;分区表除外,对于分区表,如果设置了该字段,则在创建命令未指定时,它优先于 default_table_access_method 来决定用于创建分区的访问方法。 - + 如果这是表或索引,则为使用的访问方法(堆、B-树、hash 等);否则为零(序列以及没有存储的关系,如视图,此值为零) @@ -1827,20 +1801,7 @@ SCRAM-SHA-256$<iteration count>:&l - - - relallfrozen int4 - - - 表的可见性映射中被标记为全冻结的页数。这只是一个用于触发自动清理的估计值。 - 它也可以与 relallvisible 一起,用于安排手工清理以及调优清理冻结行为。 - 它会被 - VACUUM、 - ANALYZE - 以及一些 DDL 命令(例如 CREATE INDEX)更新。 - - + @@ -1876,7 +1837,7 @@ SCRAM-SHA-256$<iteration count>:&l relpersistence char - p = 永久表/序列, u = 不记录 WAL 的表/序列, + p = 永久表/序列,u = 不记录 WAL 的表/序列, t = 临时表/序列 @@ -1971,7 +1932,7 @@ SCRAM-SHA-256$<iteration count>:&l relispopulated bool - 如果表已被填充则为真(对于所有关系该列都为真,但对于某些物化视图却不是) + 如果关系已被填充则为真(对于所有关系该列都为真,但对于某些物化视图却不是) @@ -2013,7 +1974,7 @@ SCRAM-SHA-256$<iteration count>:&l relfrozenxid xid - 在此之前的所有事务ID在表中已经被替换为一个永久的(冻结的) 事务ID。 + 在此之前的所有事务ID在表中已经被替换为一个永久的(冻结的)事务ID。 这用于跟踪表是否需要被清理,以便阻止事务ID回卷或者允许pg_xact被收缩。 如果该关系不是一个表则为0(InvalidTransactionId)。 @@ -2024,7 +1985,7 @@ SCRAM-SHA-256$<iteration count>:&l relminmxid xid - 在此之前的多事务ID在表中已经被替换为一个事务ID。这被用于跟踪表是否需要被清理,以阻止 + 在此之前的所有多事务ID在表中已经被替换为一个事务ID。这被用于跟踪表是否需要被清理,以阻止 多事务ID回卷或者允许pg_multixact被收缩。如果关系不是一个表则 为0(InvalidMultiXactId)。 @@ -2053,7 +2014,7 @@ SCRAM-SHA-256$<iteration count>:&l relpartbound pg_node_tree - 如果表示一个分区(见relispartition),则为分区边界的内部表示 + 如果表是一个分区(见relispartition),则为分区边界的内部表示 @@ -2061,9 +2022,9 @@ SCRAM-SHA-256$<iteration count>:&l
- pg_class中的一些逻辑标志被以一种懒惰的方式维护:在正确状态时它们被保证为真,但是当条件不再为真时它们并不会被立刻重置为假。 + pg_class中的一些布尔标志采用延迟维护:当条件成立时,保证它们为真;但当条件不再成立时,可能不会立即将它们重置为假。 例如,relhasindexCREATE INDEX设置,但它从不会被DROP INDEX清除。 - 作为替代,VACUUM会在找到无索引表后清除其relhasindex。 + 作为替代,VACUUM会在找到无索引表后清除其relhasindex。 这种安排避免了竞争条件并且提高了并发性。 @@ -2137,9 +2098,10 @@ SCRAM-SHA-256$<iteration count>:&l collprovider char - 排序规则提供者:d = 数据库默认值, - b = builtin,c = libc, - i = icu + 排序规则提供程序:d = 数据库默认值, +c = libc, + i = icu + @@ -2165,8 +2127,7 @@ SCRAM-SHA-256$<iteration count>:&l collcollate text - 此排序规则对象的 LC_COLLATE。如果提供者不是 libc,则 collcollate 为 - NULL,改用 colllocale。 + 此排序规则对象的 LC_COLLATE @@ -2175,38 +2136,27 @@ SCRAM-SHA-256$<iteration count>:&l collctype text - 此排序规则对象的 LC_CTYPE。如果提供者不是 libc,则 collctype 为 - NULL,改用 colllocale。 + 此排序规则对象的 LC_CTYPE - colllocale text + colliculocale text - 此排序规则对象的提供者区域设置名称。如果提供者是 libc, - 则 colllocaleNULL; - 改用 collcollate 和 - collctype。 + 此排序规则对象的 ICU 区域设置 ID - - - collicurules text - - - 此排序规则对象的 ICU 排序规则 - - + collversion text - 排序规则的提供者相关的版本。这是在排序规则创建时记录下来的,并且在使用排序规则时会被检查以检测可能导致数据损坏的排序规则定义的改变。 + 提供程序特有的排序规则版本。它会在创建排序规则时记录下来,并在使用时接受检查,以检测可能导致数据损坏的排序规则定义更改。 @@ -2232,8 +2182,9 @@ SCRAM-SHA-256$<iteration count>:&l - 目录pg_constraint存储表上的检查约束、非空约束、主键约束、唯一约束、外键约束和排他约束。 + 目录pg_constraint存储表上的检查约束、主键约束、唯一约束、外键约束和排他约束。 (列约束不会被特殊对待。每一个列约束都等价于某种表约束。) + 非空约束在pg_attribute目录中表示,而不是在这里。 @@ -2294,7 +2245,6 @@ SCRAM-SHA-256$<iteration count>:&l c = 检查约束, f = 外键约束, - n = 非空约束, p = 主键约束, u = 唯一约束, t = 约束触发器, @@ -2320,15 +2270,6 @@ SCRAM-SHA-256$<iteration count>:&l - - - conenforced bool - - - 该约束是否会被强制执行? - - - convalidated bool @@ -2439,7 +2380,7 @@ SCRAM-SHA-256$<iteration count>:&l - coninhcount int2 + coninhcount int4 该约束直接继承自多少个祖先。祖先数量非零的约束不能被删除,也不能被重命名。 @@ -2455,17 +2396,6 @@ SCRAM-SHA-256$<iteration count>:&l - - - conperiod bool - - - 如果该约束被定义为 WITHOUT OVERLAPS - (主键或唯一约束)或 PERIOD - (外键),则为真。 - - - conkey int2[] @@ -2533,10 +2463,7 @@ SCRAM-SHA-256$<iteration count>:&l conexclop oid[] (引用 pg_operator.oid - - 如果是排他约束或 WITHOUT OVERLAPS - 主键/唯一约束,则这里列出每列的排他操作符。 - + 如果是排他约束,则列出每列的排他操作符 @@ -2552,9 +2479,9 @@ SCRAM-SHA-256$<iteration count>:&l - 在一个排他约束的情况中, conkey只对约束元素是单一列引用时有用。 - 对于其他情况,conkey为0且必须查阅相关索引来发现被约束的表达式。 - (对于索引,conkey因此和pg_index.indkey具有相同的内容)。 + 对于排他约束,conkey仅对作为简单列引用的约束元素有用。 + 对于其他情况,conkey中会出现一个 0,必须查阅关联索引来确定被约束的表达式。 + (因此,conkey与该索引的 pg_index.indkey具有相同的内容。) @@ -2748,8 +2675,8 @@ SCRAM-SHA-256$<iteration count>:&l datlocprovider char - 此数据库的区域设置提供者:b = builtin, - c = libc,i = icu + 此数据库的区域设置提供程序:c = libc,i = icu + @@ -2771,17 +2698,7 @@ SCRAM-SHA-256$<iteration count>:&l - - - dathasloginevt bool - - - 如果此数据库定义了登录事件触发器,则为真。 - 使用这个标志是为了避免每个后端启动时都额外查看 - pg_event_trigger。 - 该标志仅供 PostgreSQL 内部使用,不应为了监控目的手工修改或读取。 - - + @@ -2845,31 +2762,21 @@ SCRAM-SHA-256$<iteration count>:&l - datlocale text + daticulocale text - 此数据库的提供者区域设置名称。如果提供者是 libc, - 则 datlocaleNULL; - 改用 datcollate 和 - datctype。 + 此数据库的 ICU 区域设置 ID - - - daticurules text - - - 本数据库的 ICU 排序规则 - - + datcollversion text - 该排序规则的提供者特定版本。它会在创建数据库时记录下来,并在使用时接受检查,以检测可能导致数据损坏的排序规则定义更改。 + 提供程序特有的排序规则版本。它会在创建数据库时记录下来,并在使用时接受检查,以检测可能导致数据损坏的排序规则定义更改。 @@ -3951,7 +3858,7 @@ SCRAM-SHA-256$<iteration count>:&l indisunique bool - 如为真, 这是唯一索引 + 如为真, 这是唯一索引 @@ -3960,8 +3867,8 @@ SCRAM-SHA-256$<iteration count>:&l indnullsnotdistinct bool - 该值只用于唯一索引。如果为 false,则该唯一索引会将 null 值视为非重复值(因此索引中可以包含多个 null 值,这是 PostgreSQL 的默认行为)。 - 如果为 true,则会将 null 值视为相等(因此索引中只能包含一个 null 值)。 + 该值只用于唯一索引。如果为 false,则该唯一索引会将 null 值视为彼此不同(因此索引的某一列中可以包含多个 null 值,这是 PostgreSQL 的默认行为)。 + 如果为 true,则会将 null 值视为相等(因此索引的某一列中只能包含一个 null 值)。 @@ -4069,7 +3976,7 @@ SCRAM-SHA-256$<iteration count>:&l (引用 pg_collation.oid - 对于索引键(indnkeyatts值)中的每一列,这包含要用于该索引的排序规则的OID,如果该列不是一种可排序数据类型则为零。 + 对于索引键(indnkeyatts值)中的每一列,这包含要用于该索引的排序规则的OID,如果该列的数据类型不支持排序规则则为零。 @@ -5141,7 +5048,7 @@ SCRAM-SHA-256$<iteration count>:&l (引用 pg_collation.oid - 对于分区键中的每一个列,这个域包含要用于分区的排序规则的OID,如果该列不是一种可排序数据类型则为零。 + 对于分区键中的每一个列,这个域包含要用于分区的排序规则的OID,如果该列的数据类型不支持排序规则则为零。 @@ -5730,16 +5637,7 @@ SCRAM-SHA-256$<iteration count>:&l - - - pubgencols char - - - 控制在没有发布列列表时如何处理生成列复制: - n = 不复制与该发布关联表中的生成列, - s = 复制与该发布关联表中的存储式生成列。 - - + @@ -5983,7 +5881,11 @@ SCRAM-SHA-256$<iteration count>:&l - rngsubopc (加上rngcollation,如果元素类型是可排序的)决定了被该范围类型所使用的排序顺序。rngcanonical用于离散类型的元素类型。rngsubdiff是可选的,但是提供它可以提高范围类型上的GiST索引性能。 + rngsubopc(如果元素类型支持排序规则,则还包括 + rngcollation)决定范围类型所用的排序顺序。 + rngcanonical用于元素类型为离散类型的情况。 + rngsubdiff是可选的,但应当提供它, + 以提高范围类型上的 GiST 索引性能。 @@ -6671,8 +6573,8 @@ SCRAM-SHA-256$<iteration count>:&l 通常,每个已分析的表列都有一个条目,其中stainherit = false。 - 如果表具有继承子项或分区,则还会创建第二个条目,其中stainherit = true。 - 此行表示继承树上列的统计信息,即您可以通过SELECT column FROM table*看到的数据的统计信息, + 如果表具有继承子表或分区,则还会创建第二个条目,其中stainherit = true。 + 此行表示继承树上列的统计信息,即你可以通过SELECT column FROM table*看到的数据的统计信息, 而stainherit = false行表示SELECT column FROM ONLY table的结果。 @@ -6681,7 +6583,7 @@ SCRAM-SHA-256$<iteration count>:&l - 因为不同类型的统计信息适用于不同类型的数据, pg_statistic 被设计成不太在意自己存储的是什么类型的统计。 只有极为常用的统计信息(比如NULL的含量)才在pg_statistic里给予专用的字段。 其它所有东西都存储在槽位中,而槽位是一组相关的列, 它们的内容用槽位中的一个列里的代码表示。 更详细的信息请参阅 src/include/catalog/pg_statistic.h。 + 由于不同种类的数据可能适合不同种类的统计信息,pg_statistic 在设计上尽量不对所存储的统计信息种类作出假定。只有极为通用的统计信息(例如空值情况)才在 pg_statistic 中有专用的列。其余统计信息都存储在槽位中。每个槽位都是一组相关的列,其内容由其中一列的代码编号来标识。更多信息见 src/include/catalog/pg_statistic.h @@ -6737,7 +6639,7 @@ SCRAM-SHA-256$<iteration count>:&l stanullfrac float4 - 列的项为空的比例 + 列中空值所占的比例 @@ -6755,8 +6657,8 @@ SCRAM-SHA-256$<iteration count>:&l stadistinct float4 - 列中非空唯一值的数目。一个大于零的值是唯一值的真正数目。 - 一个小于零的值是表中行数的乘数的负值;例如,对于一个 80% 的值为非空且每个非空值平均出现两次的列,可以表示为stadistinct = -0.4。一个0值表示唯一值的数目未知。 + 列中不同非空数据值的数量。一个大于零的值是不同值的真正数目。 + 一个小于零的值是表中行数的乘数的负值;例如,对于一个约 80% 的值为非空且每个非空值平均出现两次的列,可以表示为stadistinct = -0.4。一个0值表示不同值的数目未知。 @@ -6787,8 +6689,8 @@ SCRAM-SHA-256$<iteration count>:&l (引用 pg_collation.oid - 用于导出存储在第N槽位中的统计信息的排序规则。 - 例如,可应用排序规则列的直方图槽会显示定义数据排序顺序的排序规则。对于不可应用排序规则的数据,则为零。 + 用于生成存储在第N槽位中的统计信息的排序规则。 + 例如,支持排序规则的列的直方图槽会显示定义数据排序顺序的排序规则。对于不支持排序规则的数据,则为零。 @@ -6797,7 +6699,7 @@ SCRAM-SHA-256$<iteration count>:&l stanumbersN float4[] - 第N槽位的类型的数值类型统计, 如果该槽位不涉及数值类型则为NULL + 第N槽位中相应种类的数值统计信息;如果该槽位种类不涉及数值,则为 NULL @@ -6807,7 +6709,7 @@ SCRAM-SHA-256$<iteration count>:&l N槽位的类型的列值,如果该槽位类型不存储任何数据值则为 NULL。 - 每个数组的元素值实际上都是指定列的数据类型或者是一个相关类型(如数组元素类型), 因此,除了把这些列的类型定义成anyarray之外别无他法。 + 每个数组的元素值实际上都是指定列的数据类型或者是一个相关类型(如数组元素类型), 因此,无法把这些列的类型定义得比anyarray更具体。 @@ -6893,24 +6795,24 @@ SCRAM-SHA-256$<iteration count>:&l - stxkeys int2vector - (引用 pg_attribute.attnum) + stxstattarget int4 - 一个属性编号的数组,表示哪些表列被这个统计信息对象覆盖。例如值1 3表示第一个和第三个表列被覆盖 + stxstattarget 控制 + ANALYZE 为该统计信息对象收集统计信息时的细节级别。 + 零值表示不应收集统计信息。 + 负值表示使用被引用列的统计目标中的最大值(如果有设置),否则使用系统默认统计目标。 + 正值 stxstattarget 决定要收集的高频值目标个数。 - stxstattarget int2 + stxkeys int2vector + (引用 pg_attribute.attnum - stxstattarget 控制 - ANALYZE 为该统计信息对象收集统计信息时的细节级别。 - 零值表示不应收集统计信息。 - 空值表示使用被引用列的统计目标中的最大值(如果有设置),否则使用系统默认统计目标。 - 正值 stxstattarget 决定要收集的高频值目标个数。 + 一个属性编号的数组,表示哪些表列被这个统计信息对象覆盖。例如值1 3表示第一个和第三个表列被覆盖 @@ -6934,7 +6836,7 @@ SCRAM-SHA-256$<iteration count>:&l 统计信息对象属性中那些不是简单列引用的表达式树,以 nodeToString() 表示。 这是一个列表,每个表达式占一个元素。 - 如果所有统计信息对象属性都是简单引用,则为空。 + 如果所有统计信息对象属性都是简单引用,则为空值。 @@ -6943,8 +6845,8 @@ SCRAM-SHA-256$<iteration count>:&l - pg_statistic_ext条目在CREATE STATISTICS期间完全填充,但是随后不计算实际的统计值。 - 后来ANALYZE命令计算所需的值,并在pg_statistic_ext_data目录中填充条目。 + pg_statistic_ext条目在CREATE STATISTICS期间完全填充,但此时不会计算实际的统计值。 + 后续的ANALYZE命令计算所需的值,并在pg_statistic_ext_data目录中填充条目。 @@ -6961,14 +6863,7 @@ SCRAM-SHA-256$<iteration count>:&l - 通常,每个已分析的统计对象都有一个条目,其中stxdinherit = - false。如果表具有继承子项或分区,还会创建第二个条目,其中 - stxdinherit = true。此行表示继承树上的统计对象,即, - 您将看到的数据的统计信息 - SELECT * FROM table*, - 而stxdinherit = false行 - 表示 - SELECT * FROM ONLY table的结果。 + 通常,每个已分析的统计信息对象都有一个 stxdinherit = false 的条目。如果表有继承子表或分区,还会创建第二个 stxdinherit = true 的条目。后者表示该统计信息对象在整个继承树上的统计信息,即通过 SELECT * FROM table* 看到的数据的统计信息;而 stxdinherit = false 的行表示 SELECT * FROM ONLY table 的结果。 @@ -7038,7 +6933,7 @@ SCRAM-SHA-256$<iteration count>:&l stxdmcv pg_mcv_list - MCV(最频值)列表统计信息,序列化为pg_mcv_list类型 + MCV(高频值)列表统计信息,序列化为pg_mcv_list类型 @@ -7047,7 +6942,7 @@ SCRAM-SHA-256$<iteration count>:&l stxdexpr pg_statistic[] - 每个表达式的统计信息,序列化为pg_statistic类型的数组 + 每个表达式的统计信息,序列化为pg_statistic类型的数组。 @@ -7114,7 +7009,7 @@ SCRAM-SHA-256$<iteration count>:&l subskiplsn pg_lsn - 事务的完成LSN,其更改将被跳过,如果是有效LSN;否则0/0。 + 若为有效 LSN,则表示要跳过其更改的事务的完成 LSN;否则为 0/0 @@ -7157,13 +7052,10 @@ SCRAM-SHA-256$<iteration count>:&l - substream char + substream bool - 控制如何处理进行中事务的流式传输: - f = 不允许对进行中事务进行流式传输, - t = 将进行中事务的更改溢写到磁盘,并在事务在发布者端提交且被订阅者接收后立即应用, - p = 如果可用,则直接使用并行应用工作进程应用更改(如果没有工作进程,则与 t 相同) + 如果为真,订阅将允许进行中事务的流式传输 @@ -7188,33 +7080,6 @@ SCRAM-SHA-256$<iteration count>:&l - - - subpasswordrequired bool - - - 如果为真,则订阅必须指定用于认证的密码 - - - - - - subrunasowner bool - - - 如果为真,则订阅将按订阅所有者的权限运行 - - - - - - subfailover bool - - - 如果为真,则会启用上游数据库中的相关复制槽(即主复制槽和表同步复制槽),使其能够同步到备库 - - - subconninfo text @@ -7252,17 +7117,6 @@ SCRAM-SHA-256$<iteration count>:&l - - - suborigin text - - - 来源值必须是 none 或 - any 之一。默认值是 any。 - 如果为 none,订阅会请求发布者只发送没有来源的更改。 - 如果为 any,发布者会发送更改,而不管其来源如何。 - - @@ -7649,7 +7503,7 @@ SCRAM-SHA-256$<iteration count>:&l tgdeferrable bool - 如果约束触发器可推迟则为真 + 如果约束触发器可延迟则为真 @@ -7658,7 +7512,7 @@ SCRAM-SHA-256$<iteration count>:&l tginitdeferred bool - 如果约束触发器初始可推迟则为真 + 如果约束触发器初始处于延迟状态则为真 @@ -8194,7 +8048,7 @@ SCRAM-SHA-256$<iteration count>:&l 目录pg_type存储有关数据类型的信息。 - 基类型和枚举类型(标量类型)使用CREATE TYPE创建,而域使用CREATE DOMAIN创建。 + 基础类型和枚举类型(标量类型)使用CREATE TYPE创建,而域使用CREATE DOMAIN创建。 数据库中的每一个表都会有一个自动创建的复合类型,用于表示表的行结构。 也可以使用CREATE TYPE AS创建复合类型。 @@ -8280,7 +8134,7 @@ SCRAM-SHA-256$<iteration count>:&l typtype可以是: - b表示一个基类型, + b表示一个基础类型, c表示一个复合类型(例如一个表的行类型), d表示一个域, e表示一个枚举类型, @@ -8486,7 +8340,7 @@ SCRAM-SHA-256$<iteration count>:&l - e (外部的): 值可以存储在一个次要 TOAST 关系中 (如果有一个关系, 参见pg_class.reltoastrelid). + e (外部的): 值可以存储在一个次要 TOAST 关系中 (如果有一个关系, 参见pg_class.reltoastrelid). @@ -8529,7 +8383,7 @@ SCRAM-SHA-256$<iteration count>:&l typtypmod int4 - 域使用typtypmod来记录被应用于它们基类型的typmod(如果基类型不使用typmod,则为-1)。如果此类型不是一个域则为-1。 + 域使用typtypmod来记录被应用于它们基础类型的typmod(如果基础类型不使用typmod,则为-1)。如果此类型不是一个域则为-1。 @@ -8549,8 +8403,8 @@ SCRAM-SHA-256$<iteration count>:&l typcollation指定此类型的排序规则。如果类型不支持排序规则,此列为零。 - 支持排序规则的基类型在这里会有一个非零值,典型值为DEFAULT_COLLATION_OID。 - 基于可应用排序规则类型的域,如果为其指定了排序规则 OID,则它的排序规则 OID 可以不同于其基类型。 + 支持排序规则的基础类型在这里会有一个非零值,典型值为DEFAULT_COLLATION_OID。 + 基于支持排序规则的类型的域,如果为其指定了排序规则 OID,则它的排序规则 OID 可以不同于其基础类型的排序规则 OID。 diff --git a/zh/15/charset.sgml b/zh/15/charset.sgml index 089b63c5..b812249a 100644 --- a/zh/15/charset.sgml +++ b/zh/15/charset.sgml @@ -29,7 +29,7 @@ 区域设置支持 - locale + 区域设置 区域设置支持是指应用程序在字母表、排序、数字格式等 @@ -197,7 +197,7 @@ initdb --locale=sv_SE 以及 POSIX 风格正则表达式);区域设置既会影响大小写不敏感匹配,也会 影响字符类正则表达式中的字符分类 LIKE与区域设置 - regular expressions与区域设置 + 正则表达式与区域设置 @@ -289,12 +289,18 @@ initdb --locale=sv_SE 区域设置提供程序 - 区域设置提供程序指定由哪个库来定义排序规则和字符分类的区域设置行为。 + PostgreSQL支持多种区域设置提供程序, + 用于指定由哪个库提供区域设置数据。一种标准提供程序名是libc, + 它使用操作系统 C 库提供的区域设置;操作系统提供的大多数工具也使用这些区域设置。 + 另一种提供程序是icu,它使用外部 + ICUICU库。只有在构建 PostgreSQL 时 + 配置了 ICU 支持,才能使用 ICU 区域设置。 - 如上所述,用于选择区域设置的命令和工具都提供了选择区域设置提供程序的选 - 项。下面是一个使用 ICU 提供程序初始化数据库集簇的示例: + 如上所述,用于选择区域设置的命令和工具都提供了选择区域设置提供程序的选项。 + 前面的示例都使用默认的libc提供程序。下面是一个使用 ICU + 提供程序初始化数据库集簇的示例: initdb --locale-provider=icu --icu-locale=en @@ -305,211 +311,14 @@ initdb --locale-provider=icu --icu-locale=en - 无论使用哪种区域设置提供程序,操作系统仍会用于提供某些区域设置相关的行 - 为,例如消息(参见)。 + 选择哪种区域设置提供程序取决于具体需求。对于大多数基本用途,两种提供程序 + 都能给出足够好的结果。libc 提供程序的表现取决于操作系统提供的支持;不同 + 操作系统的支持程度有所不同。对于高级用途,ICU 提供了更多区域设置变体和 + 定制选项。 - - - 可用的区域设置提供程序如下: - - - - - builtin - - - builtin提供程序使用内置操作。此提供程序仅支持 - CC.UTF-8和 - PG_UNICODE_FAST区域设置。 - - - C区域设置的行为与 libc 提供程序中的 - C区域设置相同。使用该区域设置时,其行为可能取决于 - 数据库编码。 - - - C.UTF-8区域设置仅在数据库编码为 - UTF-8时可用,并且其行为基于 Unicode。排序规则仅使 - 用代码点值。正则表达式字符类基于“POSIX 兼容”语义,大小写映射使用 - “简单”变体。 - - - PG_UNICODE_FAST区域设置仅在数据库编码为 - UTF-8时可用,并且其行为基于 Unicode。排序规则仅使 - 用代码点值。正则表达式字符类基于“标准”语义,大小写映射使用“完整” - 变体。 - - - - - - icu - - - icu提供程序使用外部 - ICUICU库。 - PostgreSQL必须在构建时配置了 ICU 支持。 - - - ICU 提供与操作系统和数据库编码无关的排序与字符分类行为。如果你希望将 - 来迁移到其他平台而不改变结果,这通常更可取。LC_COLLATE - 和LC_CTYPE可以独立于 ICU 区域设置进行设置。 - - - - 对于 ICU 提供程序,结果可能取决于所使用的 ICU 库版本,因为该库会随 - 时间推移更新,以反映自然语言的变化。 - - - - - - - libc - - - libc提供程序使用操作系统的 C 库。排序与字符分类行 - 为由LC_COLLATELC_CTYPE设置控 - 制,因此它们不能独立设置。 - - - - 使用 libc 提供程序时,同一个区域设置名称在不同平台上可能表现不同。 - - - - -
- - ICU 区域设置 - - - ICU 区域设置名称 - - - ICU 格式的区域设置名称采用语言标签。 - - -CREATE COLLATION mycollation1 (provider = icu, locale = 'ja-JP'); -CREATE COLLATION mycollation2 (provider = icu, locale = 'fr'); - - - - - - 区域设置规范化和验证 - - - 在定义新的 ICU 排序规则对象,或者定义以 ICU 为提供程序的数据库时,给 - 定的区域设置名称如果还不是语言标签形式,就会被转换(“规范化”)成语言 - 标签。例如: - - -CREATE COLLATION mycollation3 (provider = icu, locale = 'en-US-u-kn-true'); -NOTICE: using standard form "en-US-u-kn" for locale "en-US-u-kn-true" -CREATE COLLATION mycollation4 (provider = icu, locale = 'de_DE.utf8'); -NOTICE: using standard form "de-DE" for locale "de_DE.utf8" - - - 如果看到这类通知,请确认providerlocale - 是否符合预期。为了在使用 ICU 提供程序时获得一致结果,应直接指定规范化 - 的语言标签,而不要依赖这种转换。 - - - - 没有语言名称的区域设置,或特殊语言名root,会被转换 - 成语言und(“未定义”)。 - - - - ICU 可以将大多数 libc 区域设置名称以及一些其他格式转换为语言标签,这有 - 助于更容易地迁移到 ICU。如果在 ICU 中使用 libc 风格的区域设置名称,其 - 行为可能与 libc 中并不完全一致。 - - - - 如果在解释区域设置名称时出现问题,或者该区域设置名称表示 ICU 无法识别 - 的语言或地区,你会看到如下警告: - - -CREATE COLLATION nonsense (provider = icu, locale = 'nonsense'); -WARNING: ICU locale "nonsense" has unknown language "nonsense" -HINT: To disable ICU locale validation, set parameter icu_validation_level to DISABLED. -CREATE COLLATION - - - 控制消息的报告方式。除非将其设为 - ERROR,否则排序规则仍会被创建,但其行为可能不是用户 - 所期望的。 - - - - - 语言标签 - - - 语言标签在 BCP 47 中定义,是一种用于标识语言、地区以及其他区域设置信息 - 的标准化标识符。 - - - - 基本语言标签就是 - language-region; - 甚至也可以只有language。 - language是语言代码(例如法语为 - fr),region是地区代码 - (例如加拿大为CA)。例如:ja-JP、 - defr-CA。 - - - - 语言标签中还可以包含排序设置,以自定义排序行为。ICU 允许非常广泛的定 - 制,例如对重音、大小写和标点的敏感性(或不敏感性)、文本中数字的处理 - 方式,以及许多其他选项,以满足不同用途。 - - - - 若要在语言标签中包含这些附加排序信息,请附加-u,表 - 示存在附加排序设置,后跟一个或多个 - -key-value - 对。key排序设置的键, - value则是该设置的有效值。对于布尔设置,可以 - 只写-key而省略对应的 - -value,这意味着其值为 - true。 - - - - 例如,语言标签en-US-u-kn-ks-level2表示美国区域的英 - 语区域设置,其中排序设置kntrue, - kslevel2。这些设置意味着该排 - 序规则不区分大小写,并把一串数字视为一个整体数字: - - -CREATE COLLATION mycollation5 (provider = icu, deterministic = false, locale = 'en-US-u-kn-ks-level2'); -SELECT 'aB' = 'Ab' COLLATE mycollation5 as result; - result --------- - t -(1 row) - -SELECT 'N-45' < 'N-123' COLLATE mycollation5 as result; - result --------- - t -(1 row) - - - - 有关详细信息以及在区域设置中使用带自定义排序信息的语言标签的更多示 - 例,请参见。 - - - 问题 @@ -565,10 +374,10 @@ SELECT 'N-45' < 'N-123' COLLATE mycollation5 as result; 概念 - 从概念上讲,每个可排序数据类型的表达式都有一个排序规则。(内置的可排序 - 数据类型包括textvarcharchar。 - 用户定义的基本类型也可以标记为可排序,当然,建立在可排序数据类型之上的 - 也是可排序的。) + 从概念上讲,每个支持排序规则的数据类型的表达式都有一个排序规则。 + (内置的支持排序规则的数据类型包括textvarcharchar。 + 用户定义的基础类型也可以标记为支持排序规则,当然,建立在支持排序规则的数据类型之上的 + 也支持排序规则。) 如果表达式是列引用,则该表达式的排序规则就是该列定义的排序规则。如果表 达式是常量,则其排序规则就是该常量数据类型的默认排序规则。更复杂表达式 的排序规则则按下文所述,从其输入表达式的排序规则推导出来。 @@ -593,7 +402,7 @@ SELECT 'N-45' < 'N-123' COLLATE mycollation5 as result; 对于函数或操作符调用,通过检查参数排序规则推导出的排序规则,会在运行时 - 用于执行指定操作。如果该函数或操作符调用的结果属于可排序数据类型,那么 + 用于执行指定操作。如果该函数或操作符调用的结果属于支持排序规则的数据类型,那么 在解析时它也会被用作该函数或操作符表达式的已定义排序规则,以便在外围表 达式需要知道其排序规则时使用。 @@ -675,7 +484,7 @@ SELECT a || b FROM test1; - 如果函数或操作符返回的是可排序数据类型,那么分配给该函数或操作符组合输 + 如果函数或操作符返回的是支持排序规则的数据类型,那么分配给该函数或操作符组合输 入表达式的排序规则,也被认为适用于其结果。因此,在 SELECT * FROM test1 ORDER BY a || 'foo'; @@ -721,8 +530,7 @@ SELECT * FROM test1 ORDER BY a || b COLLATE "fr_FR"; - 由icu提供的排序规则对象,对应于 ICU 库提供的具名整 - 理器。ICU 不支持将collatectype分开设 + 由icu提供的排序规则对象,对应于 ICU 库提供的具名排序器。ICU 不支持将collatectype分开设 置,因此二者总是相同的。此外,ICU 排序规则与编码无关,因此在一个数据库 中,某个给定名称的 ICU 排序规则始终只有一个。 @@ -730,101 +538,10 @@ SELECT * FROM test1 ORDER BY a || b COLLATE "fr_FR"; 标准排序规则 - - 在所有平台上,都支持以下排序规则: - - - - unicode - - - 此 SQL 标准排序规则使用 Unicode 排序算法和默认 Unicode 排序元素表进 - 行排序。它在所有编码中都可用。 - 使用此排序规则需要 ICU 支持,并且如果 - PostgreSQL使用不同版本的 ICU 构建,其 - 行为可能会发生变化。(此排序规则与 ICU 根区域设置具有相同的行为;参 - 见。) - - - - - - ucs_basic - - - 此 SQL 标准排序规则使用 Unicode 代码点值而不是自然语言顺序进行排 - 序,并且只有 ASCII 字母A到 - Z会被视为字母。其行为高效且在所 - 有版本中都稳定。仅适用于UTF8编码。(此排序规则 - 与UTF8编码下 libc 区域设置规范C - 的行为相同。) - - - - - - pg_unicode_fast - - - 此排序规则按 Unicode 代码点值而不是自然语言顺序进行排序。对于 - lowerinitcap和 - upper函数,它使用 Unicode 完整大小写映射。对 - 于模式匹配(包括正则表达式),它使用 Unicode 兼容属性 - 的标准变体。其行为在 - Postgres主版本内高效且稳定。仅适用于 - UTF8编码。 - - - - - - pg_c_utf8 - - - 此排序规则按 Unicode 代码点值而不是自然语言顺序进行排序。对于 - lowerinitcap和 - upper函数,它使用 Unicode 简单大小写映射。对 - 于模式匹配(包括正则表达式),它使用 Unicode 兼容属性 - 的 POSIX 兼容变体。其行为在 - PostgreSQL主版本内高效且稳定。此排序规 - 则仅适用于UTF8编码。 - - - - - - C(等同于POSIX - - - CPOSIX排序规则基于 - 传统 C行为。它们按字节值而不是自然语言顺序排序,并且 - 只有 ASCII 字母A到 - Z会被视为字母。对于给定的数据库 - 编码,其行为高效且在所有版本中都稳定,但在不同数据库编码之间可能会 - 有所不同。 - - - - - - default - - - default排序规则会选择数据库创建时指定的区域设 - 置。 - - - - - + 所有平台都提供名为 defaultCPOSIX 的排序规则。根据操作系统支持情况,还可能提供其他排序规则。default 排序规则选择创建数据库时指定的 LC_COLLATELC_CTYPE 值。CPOSIX 排序规则都采用传统 C行为,仅将 ASCII 字母 AZ 视为字母,并严格按字符编码的字节值排序。 - - 根据操作系统支持情况,还可能存在其他排序规则。这些附加排序规则的效率和 - 稳定性取决于排序规则提供程序、提供程序版本以及区域设置。 - - + 此外,编码 UTF8 还可以使用 SQL 标准排序规则名 ucs_basic。它等价于 C,按 Unicode 码点排序。 + 预定义排序规则 @@ -946,23 +663,23 @@ SELECT a COLLATE "C" < b COLLATE "POSIX" FROM test1; - 创建新的排序规则对象 + 创建新的排序规则对象 - + 如果标准和预定义排序规则不足以满足需求,用户可以使用 SQL 命令创建自己的排序规则对象。 - + 与所有预定义对象一样,标准和预定义排序规则都位于模式 pg_catalog中。用户定义的排序规则应当创建在用户模式 中。这也能确保它们被pg_dump保存。 - - libc 排序规则 + + libc 排序规则 - + 新的 libc 排序规则可以这样创建: CREATE COLLATION german (provider = libc, locale = 'de_DE'); @@ -971,7 +688,7 @@ CREATE COLLATION german (provider = libc, locale = 'de_DE'); 类 Unix 系统上,命令locale -a会给出一个列表。 - + 由于预定义的 libc 排序规则已经包含了数据库实例初始化时操作系统中定义 的所有排序规则,因此通常不需要手工创建新的排序规则。可能需要这样做的 原因包括希望采用不同的命名系统(这种情况下另见pg_import_system_collations())。 - + + + + ICU 排序规则 - - ICU 排序规则 + 除了 initdb 预装载的基本语言与国家组合外,ICU 还允许进一步定制排序规则。建议用户定义自己的排序规则对象,利用这些功能使排序行为满足自己的需求。关于 ICU 区域设置名称的信息,参见 。可接受的名称和属性集合取决于具体的 ICU 版本。 - - ICU 排序规则可以这样创建: - -CREATE COLLATION german (provider = icu, locale = 'de-DE'); - - ICU 区域设置使用 BCP 47 语言标签 - 指定,但也接受大多数 libc 风格的区域设置名称。如果可能,libc 风格的区 - 域设置名称会被转换为语言标签。 - + 以下是一些示例: + + CREATE COLLATION "de-u-co-phonebk-x-icu" (provider = icu, locale = 'de-u-co-phonebk'); + CREATE COLLATION "de-u-co-phonebk-x-icu" (provider = icu, locale = 'de@collation=phonebook'); + + 德语排序规则,电话簿排序类型 + 第一个示例使用 BCP 47 定义的语言标签来选择 ICU 区域设置。第二个示例使用传统的 ICU 专有区域设置语法。今后应优先采用第一种形式,但较旧的 ICU 版本不支持它。 + 注意,可以在 SQL 环境中为排序规则对象任意命名。本例遵循预定义排序规则所采用的命名风格,该风格也遵循 BCP 47,但用户定义的排序规则并不要求如此。 + + - - 新的 ICU 排序规则可以通过在语言标签中包含排序属性来广泛定制排序行为。 - 详细信息和示例见。 - - + + CREATE COLLATION "und-u-co-emoji-x-icu" (provider = icu, locale = 'und-u-co-emoji'); + CREATE COLLATION "und-u-co-emoji-x-icu" (provider = icu, locale = '@collation=emoji'); + + + 根排序规则,表情符号排序类型,依据 Unicode 技术标准 #51 + + 注意,传统的 ICU 区域设置命名系统使用空字符串来选择根区域设置。 + + + + + CREATE COLLATION latinlast (provider = icu, locale = 'en-u-kr-grek-latn'); + CREATE COLLATION latinlast (provider = icu, locale = 'en@colReorder=grek-latn'); + + + 将希腊字母排在拉丁字母之前。(默认情况下是拉丁字母排在希腊字母之前。) + + + + + + CREATE COLLATION upperfirst (provider = icu, locale = 'en-u-kf-upper'); + CREATE COLLATION upperfirst (provider = icu, locale = 'en@colCaseFirst=upper'); + + + 将大写字母排在小写字母之前。(默认情况下是小写字母在前。) + + + + + + CREATE COLLATION special (provider = icu, locale = 'en-u-kf-upper-kr-grek-latn'); + CREATE COLLATION special (provider = icu, locale = 'en@colCaseFirst=upper;colReorder=grek-latn'); + + + 结合了以上两个选项。 + + + + + + CREATE COLLATION numeric (provider = icu, locale = 'en-u-kn-true'); + CREATE COLLATION numeric (provider = icu, locale = 'en@colNumeric=yes'); + + 数值排序,按数值对数字序列排序,例如:A-21 < A-123(也称自然排序)。 + + + 参见Unicode 技术标准 #35BCP 47了解详情。可用排序类型列表(co子标签)可在以下位置找到:CLDR 仓库。 + + + 注意,虽然此系统允许创建忽略大小写忽略重音等排序规则(使用 ks 键),但要让这些排序规则真正不区分大小写或重音,还必须在 CREATE COLLATION 中将它们声明为非确定性排序规则;参见 。否则,按排序规则比较相等、但字节不相等的字符串,仍会按字节值排序。 + + + ICU 的设计允许接受几乎任何字符串作为区域设置名,并按照其文档描述的回退流程,匹配到它能够提供的最接近区域设置。因此,如果排序规则定义使用了当前 ICU 安装实际不支持的功能,不会得到直接反馈。所以建议创建应用层面的测试用例,以检查排序规则定义是否满足需求。 + + - + 复制排序规则 @@ -1050,7 +822,7 @@ CREATE COLLATION ignore_accents (provider = icu, locale = 'und-u-ks-level1-kc-tr 定性的。虽然非确定性排序规则提供了更正确的行为,尤其是 在考虑 Unicode 的全部能力及其众多特殊情况时,但它们也有一些缺点。首 先,使用它们会带来性能损失。特别要注意的是,B-树不能对使用非确定性排 - 序规则的索引使用去重。此外,某些操作(例如某些模式匹配操作)对非确定性 + 序规则的索引使用去重。此外,某些操作(例如模式匹配操作)对非确定性 排序规则来说是不可行的。因此,只有在确实需要时才应使用它们。 @@ -1065,492 +837,7 @@ CREATE COLLATION ignore_accents (provider = icu, locale = 'und-u-ks-level1-kc-tr - - ICU 自定义排序规则 - - ICU 允许通过把排序设置作为语言标签的一部分,定义新的排序规则,从而对排 - 序规则行为进行广泛控制。这些设置可以修改排序顺序,以适应各种需求。例如: - - --- ignore differences in accents and case -CREATE COLLATION ignore_accent_case (provider = icu, deterministic = false, locale = 'und-u-ks-level1'); -SELECT 'Å' = 'A' COLLATE ignore_accent_case; -- true -SELECT 'z' = 'Z' COLLATE ignore_accent_case; -- true - --- upper case letters sort before lower case. -CREATE COLLATION upper_first (provider = icu, locale = 'und-u-kf-upper'); -SELECT 'B' < 'b' COLLATE upper_first; -- true - --- treat digits numerically and ignore punctuation -CREATE COLLATION num_ignore_punct (provider = icu, deterministic = false, locale = 'und-u-ka-shifted-kn'); -SELECT 'id-45' < 'id-123' COLLATE num_ignore_punct; -- true -SELECT 'w;x*y-z' = 'wxyz' COLLATE num_ignore_punct; -- true - - - 许多可用选项会在中说明;更详尽的 - 细节则可参见。 - - - - ICU 比较级别 - - - ICU 中两个字符串的比较(排序)由一个多级过程决定,其中各种文本特征被 - 分组为级别。每个级别的处理由排序规则设置控制。级别 - 越高,对文本特征的区分就越细。 - - - - 显示了在给定级别判断相等性时,哪 - 些文本特征差异会被认为是重要的。Unicode 字符U+2063 - 是不可见分隔符,如表中所示,在低于identic的所有比 - 较级别都会被忽略。 - - - - ICU 排序规则级别 - - - - - - - - - - - - - 级别 - 描述 - 'f' = 'f' - 'ab' = U&'a\2063b' - 'x-y' = 'x_y' - 'g' = 'G' - 'n' = 'ñ' - 'y' = 'z' - - - - - - level1 - 基本字符 - true - true - true - true - true - false - - - level2 - 重音 - true - true - true - true - false - false - - - level3 - 大小写/变体 - true - true - true - false - false - false - - - level4 - 标点符号仅在 - ka-shifted时;见 - true - true - false - false - false - false - - - identic - 全部 - true - false - false - false - false - false - - - -
- - - 在每个级别上,即使关闭了完全规范化,也会执行基本规范化。例如, - 'á'既可能由代码点序列 - U&'\0061\0301'表示,也可能由单个代码点 - U&'\00E1'表示;即使在identic - 级别,这两种表示也会被视为相等。若要把代码点表示上的任何差异都视为不同, - 请使用将deterministic设为true创 - 建的排序规则。 - - - - 排序规则级别示例 - - -CREATE COLLATION level3 (provider = icu, deterministic = false, locale = 'und-u-ka-shifted-ks-level3'); -CREATE COLLATION level4 (provider = icu, deterministic = false, locale = 'und-u-ka-shifted-ks-level4'); -CREATE COLLATION identic (provider = icu, deterministic = false, locale = 'und-u-ka-shifted-ks-identic'); - --- invisible separator ignored at all levels except identic -SELECT 'ab' = U&'a\2063b' COLLATE level4; -- true -SELECT 'ab' = U&'a\2063b' COLLATE identic; -- false - --- punctuation ignored at level3 but not at level 4 -SELECT 'x-y' = 'x_y' COLLATE level3; -- true -SELECT 'x-y' = 'x_y' COLLATE level4; -- false - - - -
- - - ICU 区域设置的排序规则设置 - - - 显示了可用的排序规则设置,这 - 些设置可以作为语言标签的一部分,用来定制排序规则。 - - - - ICU 排序规则设置 - - - - - - - - - - - 默认 - 描述 - - - - - - co - emoji, phonebk, standard, ... - standard - - 排序规则类型。有关其他选项和详细信息,请参见。 - - - - - ka - noignore, shifted - noignore - - 如果设为shifted,某些字符(例如标点或空格)在比 - 较时会被忽略。要使其生效,键ks必须设为 - level3或更低。可通过设置键kv - 来控制忽略哪些字符类别。 - - - - - kb - true, false - false - - 对 2 级差异进行反向比较。例如,区域设置und-u-kb - 会把'àe'排在'aé'之前。 - - - - - kc - true, false - false - - - 将大小写分离成一个介于重音和其他 3 级特征之间的 - 2.5 级。 - - - 如果其值为trueks设为 - level1,则会忽略重音,但仍考虑大小写。 - - - - - - kf - - upper, lower, - false - - false - - 若设为upper,大写字母排在小写字母之前;若设为 - lower,小写字母排在大写字母之前;若设为 - false,排序顺序则取决于该区域设置的规则。 - - - - - kn - true, false - false - - 如果设为true,字符串中的数字会被视为单个数值, - 而不是一串数字。例如,'id-45'会排在 - 'id-123'之前。 - - - - - kk - true, false - false - - - 启用完全规范化;这可能影响性能。即使其值为 - false,也会执行基本规范化。对那些需要完全规范 - 化的语言来说,其区域设置通常会默认启用这一选项。 - - - 在某些情况下,完全规范化很重要,例如多个重音符应用于同一个字符 - 时。比如,代码点序列U&'\0065\0323\0302'和 - U&'\0065\0302\0323'都表示一个 - e,只不过其抑扬符和下点重音的应用顺序不同。启 - 用完全规范化后,这两个代码点序列会被视为相等;否则则不相等。 - - - - - - kr - - space, punct, - symbol, currency, - digit, script-id - - - - - 可设为一个或多个有效值,或者任何 BCP 47 - script-id,例如latn - (拉丁)或grek希腊)。 - 多个值之间用-分隔。 - - - 它会重新定义字符类别的排序顺序;列表中较早出现的字符类别,会排在 - 列表中较晚类别的前面。例如,值 - digit-currency-space(作为语言标签 - und-u-kr-digit-currency-space的一部分)会让 - 标点符号排在数字和空格之前。 - - - - - - ks - level1, level2, level3, level4, identic - level3 - - 用于确定相等性时的敏感度(或强度),其中 - level1对差异最不敏感,而 - identic对差异最敏感。详见。 - - - - - kv - - space, punct, - symbol, currency - - punct - - 在 3 级比较时会被忽略的字符类别。设为更靠后的值时也会包含更靠前的 - 值;例如symbol也会把punct - 和space包含在要忽略的字符中。要使其生效,键 - ka必须设为shifted,且键 - ks必须设为level3或更低。 - - - - -
- - - 默认值可能依赖于具体区域设置。上表并非意在穷举所有情况。有关其他选项和 - 详细信息,请参见。 - - - - - 对于许多排序规则设置,必须在创建排序规则时把 - 设为false,这些设 - 置才能产生预期效果(参见)。此外,某些设置只有在键 - ka设为shifted时才会生效(参见 - )。 - - -
- - - 排序规则设置示例 - - - - CREATE COLLATION "de-u-co-phonebk-x-icu" (provider = icu, locale = 'de-u-co-phonebk'); - - 德语排序规则,电话簿排序类型 - - - - - CREATE COLLATION "und-u-co-emoji-x-icu" (provider = icu, locale = 'und-u-co-emoji'); - - - 根排序规则,表情符号排序类型,依据 Unicode 技术标准 #51 - - - - - - CREATE COLLATION latinlast (provider = icu, locale = 'en-u-kr-grek-latn'); - - - 将希腊字母排在拉丁字母之前。(默认情况下是拉丁字母排在希腊字母之前。) - - - - - - CREATE COLLATION upperfirst (provider = icu, locale = 'en-u-kf-upper'); - - - 将大写字母排在小写字母之前。(默认情况下是小写字母在前。) - - - - - - CREATE COLLATION special (provider = icu, locale = 'en-u-kf-upper-kr-grek-latn'); - - - 结合了以上两个选项。 - - - - - - - - ICU 定制规则 - - - 如果上面列出的排序规则设置所提供的选项仍然不够用,可以用定制规则改变排 - 序元素的顺序,其语法详见。 - - - - 下面这个小例子基于根区域设置创建了一个带定制规则的排序规则: - - - - 按照这条规则,字母W会排在V之后,但被视 - 为类似重音那样的次要差异。某些语言的区域设置定义中就包含类似这样的规 - 则。(当然,如果某个区域设置定义本身已经包含了所需规则,就无需再次显式 - 指定。) - - - - 下面是一个更复杂的例子。以下语句设置了一个名为ebcdic - 的排序规则,其规则会按照 EBCDIC 编码的顺序对 US-ASCII 字符进行排序。 - - -' < '?' -< '`' < ':' < '#' < '@' < \' < '=' < '"' -<*a-r < '~' <*s-z < '^' < '[' < ']' -< '{' <*A-I < '}' <*J-R < '\' <*S-Z <*0-9 -$$);]]> - -SELECT c -FROM (VALUES ('a'), ('b'), ('A'), ('B'), ('1'), ('2'), ('!'), ('^')) AS x(c) -ORDER BY c COLLATE ebcdic; - c ---- - ! - a - b - ^ - A - B - 1 - 2 - - - - - - ICU 的外部参考 - - - 本节()只是对 ICU 行为和语言标 - 签的简要概述。有关技术细节、其他选项和新的行为,请参阅以下文档: - - - - - - Unicode 技术标准 #35 - - - - - BCP 47 - - - - - CLDR 存储库 - - - - - - - - - - - - - - -
diff --git a/zh/15/client-auth.sgml b/zh/15/client-auth.sgml index 07fcb80e..dcb9ec2c 100644 --- a/zh/15/client-auth.sgml +++ b/zh/15/client-auth.sgml @@ -62,14 +62,7 @@ 每条认证记录都指定一种连接类型、一个客户端 IP 地址范围(如果该连接类型需要)、一个数据库名、一个用户名,以及对匹配这些参数的连接要使用的认证方法。第一条同时匹配连接类型、客户端地址、请求数据库和用户名的记录会被用来执行认证。这里不存在 继续向后匹配后备 机制:如果选中某条记录而认证失败,就不会再考虑后续记录。如果没有任何记录匹配,则拒绝访问。 - - 一条记录可以是 include 指令,也可以是认证记录。include 指令用于指定可被包含的文件,这些文件中可以含有额外记录;这些记录会插入到 include 指令所在的位置。include 指令只有两个字段:includeinclude_if_existsinclude_dir 指令本身,以及要包含的文件或目录。文件或目录既可以是相对路径,也可以是绝对路径,并且都可以用双引号括起。对于 include_dir 形式,将包含所有文件名不以 . 开头且以 .conf 结尾的文件。include 目录中的多个文件会按照文件名顺序处理(依据 C locale 规则,即数字排在字母前,大写字母排在小写字母前)。 - - - - 一条记录可以有多种格式: - - + 记录可以采用以下几种格式: local database user auth-method auth-options host database user address auth-method auth-options hostssl database user address auth-method auth-options @@ -81,14 +74,7 @@ hostssl database userdatabase user IP-address IP-mask auth-method auth-options hostgssenc database user IP-address IP-mask auth-method auth-options hostnogssenc database user IP-address IP-mask auth-method auth-options -include file -include_if_exists file -include_dir directory - - - 字段的含义如下: - - +各字段的含义如下: local @@ -181,50 +167,14 @@ include_dir directory database - - - 指定此记录匹配的数据库名称。值all指定匹配所有数据库。 - 值sameuser指定如果请求的数据库与请求的用户具有相同的名称,则记录匹配。 - 值samerole指定请求的用户必须是与请求的数据库具有相同名称的角色的成员。 - (samegroupsamerole的一种过时但仍被接受的写法。) - 对于 samerole 而言,超级用户并不会仅因其超级用户身份就被视为某个角色的成员;只有当其显式地直接或间接属于该角色时,才会被视为成员。 - 值replication表示当请求的是物理复制连接时匹配,但不匹配逻辑复制连接。请注意,物理复制连接不指定任何特定数据库,而逻辑复制连接会指定数据库。 - 否则,这里可以是某个特定PostgreSQL数据库的名称,或者一个正则表达式。 - 多个数据库名和/或正则表达式可以用逗号分隔提供。 - - - - 如果数据库名以斜线(/)开头,则其余部分会被视为一个正则表达式。 - (关于 PostgreSQL 正则表达式语法的细节,见 。) - - - - 也可以通过在文件名前加上@来指定一个单独文件,该文件中包含数据库名和/或正则表达式。 - + 指定此记录匹配的数据库名称。all 表示匹配所有数据库。sameuser 表示请求的数据库与请求的用户同名时才匹配。samerole 要求请求的用户是与所请求数据库同名的角色的成员。(samegroupsamerole 已过时但仍被接受的写法。)对于 samerole,只有显式地直接或间接属于该角色,超级用户才被视为其成员,仅凭超级用户身份并不算。replication 表示请求物理复制连接时匹配此记录,但不匹配逻辑复制连接。注意,物理复制连接不指定任何特定数据库,而逻辑复制连接会指定数据库。其他值则表示某个特定的 PostgreSQL 数据库的名称。可以用逗号分隔多个数据库名称。也可以在文件名前加 @,指定一个单独存放数据库名称的文件。 user - - - 指定此记录匹配哪些数据库用户名。值all表示匹配所有用户。 - 否则,这里可以是某个特定数据库用户的名称、一个正则表达式(以斜线(/)开头时),或者一个以前缀 + 标识的组名。 - (请记住,在PostgreSQL中,用户和组之间并没有真正区别; - + 标记实际上表示匹配直接或间接属于该角色的任意角色,而没有 + 标记的名称只匹配该特定角色。) - 为此目的,只有在超级用户显式地直接或间接属于该角色时,才会被视为该角色的成员,而不会仅因其超级用户身份而被视为成员。 - 多个用户名和/或正则表达式可以用逗号分隔提供。 - - - - 如果用户名以斜线(/)开头,则其余部分会被视为一个正则表达式。 - (关于 PostgreSQL 正则表达式语法的细节,见 。) - - - - 也可以通过在文件名前加上@来指定一个单独文件,该文件中包含用户名和/或正则表达式。 - + 指定此记录匹配的数据库用户名。all 表示匹配所有用户。其他值可以是某个特定数据库用户的名称,也可以是前面带 + 的组名。(请记住,在 PostgreSQL 中,用户和组并无实质区别;+ 实际表示匹配直接或间接属于此角色的任何角色,而不带 + 的名称仅匹配该角色本身。)为此,只有显式地直接或间接属于该角色,超级用户才被视为其成员,仅凭超级用户身份并不算。可以用逗号分隔多个用户名。也可以在文件名前加 @,指定一个单独存放用户名的文件。 @@ -239,7 +189,7 @@ include_dir directory IP地址范围使用标准的数字表示法来指定起始地址,然后是斜杠(/)和一个CIDR掩码长度。 掩码长度表示客户端IP地址必须匹配的高位比特数。给定IP地址中右侧的比特应为零。 - IP地址、/和CIDR掩码长度之间不得有任何空格。 + IP地址、/和CIDR掩码长度之间不得有任何空白。 @@ -276,12 +226,12 @@ include_dir directory 以点(.)开头的主机名规范匹配实际主机名的后缀。 因此,.example.com将匹配foo.example.com - (但不仅仅是example.com)。 + (但不匹配单独的example.com)。 当在pg_hba.conf中指定主机名时,应确保名称解析相对快速。 - 最好设置一个本地名称解析缓存,如nscd。 + 设置一个本地名称解析缓存可能会有帮助,如nscd。 此外,还可能希望启用配置参数log_hostname,以便在日志中看到客户端的主机名而不是 IP 地址。 @@ -293,7 +243,7 @@ include_dir directory 用户有时会想知道为什么主机名以这种看似复杂的方式处理,包括两次名称解析,其中包括对客户端IP地址的反向查找。 - 如果客户端的反向DNS条目未设置或生成了一些不良的主机名,则使用该功能会变得复杂。 + 如果客户端的反向DNS条目未设置或返回了不符合预期的主机名,则使用该功能会变得复杂。 这主要是为了效率:这样,连接尝试最多需要两次解析器查找,一次反向查找和一次正向查找。 如果某个地址存在解析器问题,那就只会成为该客户端的问题。 一个假设的替代实现只进行正向查找的情况下,在每次连接尝试期间都必须解析pg_hba.conf中提到的每个主机名。 @@ -308,7 +258,7 @@ include_dir directory 请注意,这种行为与其他流行的基于主机名的访问控制实现一致,例如 - Apache HTTP服务器和TCP包装器。 + Apache HTTP 服务器和 TCP Wrappers。 @@ -320,7 +270,7 @@ include_dir directory - 这两个字段可以用作IP地址/掩码长度 + 这两个字段可以用作IP-address/mask-length 表示法的替代方案。而不是指定掩码长度,实际掩码在一个单独的列中指定。 例如,255.0.0.0表示IPv4的CIDR掩码长度为8, 而255.255.255.255表示CIDR掩码长度为32。 @@ -378,11 +328,7 @@ include_dir directory 执行 SCRAM-SHA-256 或 MD5 认证以校验用户密码。详见 - - - 对 MD5 加密密码的支持已被弃用,并将在未来版本的 PostgreSQL 中移除。关于迁移到其他密码类型的细节,请参阅 。 - - + @@ -499,14 +445,7 @@ include_dir directory - - oauth - - - 使用第三方 OAuth 2.0 身份提供方进行授权,并可选地完成认证。详细信息请参见 。 - - - + @@ -516,11 +455,7 @@ include_dir directory auth-options - - - 在auth-method字段之后,可以是形如name=value的字段, - 用于指定认证方法的选项。关于哪些选项适用于哪些认证方法的详细信息见下文。 - + auth-method 字段之后,可以有一个或多个形如 name=value 的字段,用于指定认证方法的选项。下文会详细说明各认证方法有哪些可用选项。 除了下面列出的特定于方法的选项外,还有一个方法无关的认证选项 clientcert, @@ -533,7 +468,7 @@ include_dir directory - 对于任何使用客户端证书认证的记录(即使用 cert 认证方法的记录,或使用 clientcert 选项的记录),都可以通过 clientname 选项指定要匹配客户端证书凭据中的哪一部分。此选项有两个可选值。如果指定 clientname=CN,这也是默认值,则用户名将与证书的 Common Name (CN) 匹配。如果改为指定 clientname=DN,则用户名将与证书的完整 Distinguished Name (DN) 匹配。此选项通常最好与用户名映射配合使用。比较时使用的是 RFC 2253 格式的 DN。要查看以这种格式表示的客户端证书 DN,请执行 + 对于任何使用客户端证书认证的记录(即使用 cert 认证方法的记录,或使用 clientcert 选项的记录),都可以通过 clientname 选项指定要匹配客户端证书凭据中的哪一部分。此选项有两个可选值。如果指定 clientname=CN,这也是默认值,则用户名将与证书的 Common Name (CN) 匹配。如果改为指定 clientname=DN,则用户名将与证书的完整 Distinguished Name (DN) 匹配。此选项可能更适合与用户名映射配合使用。比较时使用的是 RFC 2253 格式的 DN。要查看以这种格式表示的客户端证书 DN,请执行 openssl x509 -in myclient.crt -noout -subject -nameopt RFC2253 | sed "s/^subject=//" @@ -541,33 +476,6 @@ openssl x509 -in myclient.crt -noout -subject -nameopt RFC2253 | sed "s/^subject - - - include - - - 这一行会被给定文件的内容替换。 - - - - - - include_if_exists - - - 如果给定文件存在,这一行会被该文件的内容替换;否则会记录一条消息,说明该文件已被跳过。 - - - - - - include_dir - - - 这一行会被目录中找到的所有文件内容替换,前提是这些文件名不以 . 开头并且以 .conf 结尾;这些文件会按照文件名字典序处理(依据 C locale 规则,即数字排在字母前,大写字母排在小写字母前)。 - - - @@ -575,19 +483,17 @@ openssl x509 -in myclient.crt -noout -subject -nameopt RFC2253 | sed "s/^subject 由 @ 构造引用的文件会被读取为名称列表,其中的名称可以用空白或逗号分隔。注释仍然用 # 引入,与 pg_hba.conf 中相同,并且允许嵌套的 @ 构造。除非 @ 后面的文件名是绝对路径,否则它会被视为相对于引用它的文件所在目录。 - - 因为每一次连接尝试都会顺序地检查pg_hba.conf记录,所以这些记录的顺序是非常关键的。通常,靠前的记录有比较严的连接匹配参数和比较弱的认证方法,而靠后的记录有比较松的匹配参数和比较强的认证方法。 例如,我们希望对本地 TCP/IP 连接使用trust认证,而对远程 TCP/IP 连接要求密码。在这种情况下为来自于 127.0.0.1 的连接指定trust认证的记录将出现在为一个更宽范围的客户端 IP 地址指定密码认证的记录前面。 - + 由于每次连接尝试都会按顺序检查 pg_hba.conf 记录,因此记录的顺序很重要。通常,靠前的记录使用较严格的连接匹配条件和较弱的认证方法,靠后的记录使用较宽松的匹配条件和较强的认证方法。例如,可能希望对本地 TCP/IP 连接使用 trust 认证,而要求远程 TCP/IP 连接提供密码。此时,为来自 127.0.0.1 的连接指定 trust 认证的记录,应放在为更大范围的允许客户端 IP 地址指定密码认证的记录之前。 - 在启动以及主服务器进程收到SIGHUPSIGHUP信号时,pg_hba.conf文件会被读取。 - 如果你在活动的系统上编辑了该文件,你将需要通知 postmaster(使用pg_ctl reload,调用SQL函数pg_reload_conf(),或使用kill -HUP)使其重新读取该文件。 + 在启动时以及主服务器进程收到 SIGHUPSIGHUP 信号时,pg_hba.conf 文件会被读取。 + 如果你在运行中的系统上编辑了该文件,就需要通知 postmaster(使用 pg_ctl reload、调用 SQL 函数 pg_reload_conf(),或者使用 kill -HUP)重新读取该文件。 - 前面的说明在Microsoft Windows上不为真:在Windows上,pg_hba.conf文件中的任何更改会立即被应用到后续的新连接上。 + 前面的说明不适用于 Microsoft Windows:在Windows上,pg_hba.conf文件中的任何更改会立即被应用到后续的新连接上。 @@ -602,9 +508,7 @@ openssl x509 -in myclient.crt -noout -subject -nameopt RFC2253 | sed "s/^subject - - 中展示了pg_hba.conf项的一些示例。不同认证方法的详情请见下一节。 - + 展示了一些 pg_hba.conf 条目示例。有关不同认证方法的详细信息,参见下一节。 @@ -612,8 +516,8 @@ openssl x509 -in myclient.crt -noout -subject -nameopt RFC2253 | sed "s/^subject # 允许本地系统上的任何用户 -# 通过 Unix 域套接字以任意 -# 数据库用户名连接到任意数据库(本地连接的默认值)。 +# 通过 Unix 域套接字(本地连接的默认方式)以任意 +# 数据库用户名连接到任意数据库。 # # TYPE DATABASE USER ADDRESS METHOD local all all trust @@ -638,13 +542,6 @@ host all all ::1/128 trust # TYPE DATABASE USER ADDRESS METHOD host all all localhost trust -# 使用 DATABASE 正则表达式的相同规则,它允许连接到任何 -# 名称以 "db" 开头并以两到四位数字结尾的数据库 -# (例如 "db1234" 或 "db12")。 -# -# TYPE DATABASE USER ADDRESS METHOD -host "/^db\d{2,4}$" all localhost trust - # 允许来自任意具有 IP 地址192.168.93.x 的主机上任意 # 用户以 ident 为该连接所报告的相同用户名连接到 # 数据库 "postgres"(通常是操作系统用户名)。 @@ -658,7 +555,7 @@ host postgres all 192.168.93.0/24 ident # TYPE DATABASE USER ADDRESS METHOD host postgres all 192.168.12.10/32 scram-sha-256 -# 如果用户的密码被正确提供,允许 example.com 中主机上 +# 如果用户的密码被正确提供,允许 example.com 域中主机上 # 的任意用户连接到任意数据库。 # # 为大部分用户要求SCRAM认证,但是用户'mike'是个例外, @@ -669,7 +566,7 @@ host all mike .example.com md5 host all all .example.com scram-sha-256 # 如果没有前面的 "host" 行,这三行 -# 将拒绝所有来自 192.168.54.1的连接(因为那些项将首先被匹配), +# 将拒绝所有来自 192.168.54.1的连接(因为该条目将首先被匹配), # 但是允许来自互联网其他任何地方的 # GSSAPI 加密连接。零掩码表示不会考虑主机 IP 地址中的任何位, # 因此它会匹配任意主机。未加密的 GSSAPI 连接 @@ -684,28 +581,27 @@ host all all 192.168.12.10/32 gss # 允许来自 192.168.x.x 主机的用户连接到任意数据库,如果它们能够 # 通过 ident 检查。例如,假设 ident说用户是 "bryanh" 并且他要求以 # PostgreSQL 用户 "guest1" 连接,如果在 pg_ident.conf 有一个映射 -# "omicron" 的选项说 "bryanh" 被允许以 "guest1" 连接,则该连接将被允许。 +# "omicron" 的条目表明 "bryanh" 被允许以 "guest1" 连接,则该连接将被允许。 # # TYPE DATABASE USER ADDRESS METHOD host all all 192.168.0.0/16 ident map=omicron -# 如果这些是本地连接的唯一四行,它们将允许本地用户只连接到它们 -# 自己的数据库(与其数据库用户名同名的数据库),不过用户名以 -# "helpdesk" 结尾的用户、管理员以及角色 "support" 的成员除外 -# (它们可以连接到所有数据库)。文件 $PGDATA/admins 包含一个 -# 管理员名字的列表。在所有情况下都要求密码。 +# 如果这些是本地连接的唯一三行,它们将允许本地用户只连接到 +# 自己的数据库(与其数据库用户名同名的数据库),但管理员和 +# 角色 "support" 的成员除外,他们可以连接到所有数据库。 +# 文件 $PGDATA/admins 包含管理员名称列表。 +# 所有情况下都要求提供密码。 # # TYPE DATABASE USER ADDRESS METHOD -local sameuser all scram-sha-256 -local all /^.*helpdesk$ scram-sha-256 -local all @admins scram-sha-256 -local all +support scram-sha-256 +local sameuser all md5 +local all @admins md5 +local all +support md5 # 上面的最后两行可以被整合为一行: -local all @admins,+support scram-sha-256 +local all @admins,+support md5 # 数据库列也可以用列表和文件名: -local db1,db2,@demodbs all scram-sha-256 +local db1,db2,@demodbs all md5 @@ -722,44 +618,14 @@ local db1,db2,@demodbs all scram-sha-256 当使用 Ident 或 GSSAPI 之类的外部认证系统时,发起连接的操作系统用户名可能不同于要使用的数据库用户(角色)。在这种情况下,可以通过用户名映射把操作系统用户名映射为数据库用户。要使用用户名映射,需要在 pg_hba.conf 的选项字段中指定 map=map-name。此选项适用于所有会接收外部用户名的认证方法。由于不同连接可能需要不同映射,在 pg_hba.conf 中通过 map-name 参数指定要使用的映射,以表明每个连接应使用哪个映射。 - - 用户名映射定义在 ident 映射文件中,该文件默认名为 pg_ident.confpg_ident.conf,并存放在集簇的数据目录中。(当然,也可以把该映射文件放在别处;见配置参数 。) - ident 映射文件中的行通常有如下形式: - + 用户名映射在 ident 映射文件中定义。该文件默认名为 pg_ident.confpg_ident.conf,存储在集簇的数据目录中。(也可以将映射文件放在其他位置;参见 配置参数。)ident 映射文件中各行的基本格式如下: map-name system-username database-username -include file -include_if_exists file -include_dir directory - - 注释、空白以及续行的处理方式与 pg_hba.conf 完全相同。 - map-name 是一个任意名称,用于在 pg_hba.conf 中引用该映射。 - 其余两个字段分别指定一个操作系统用户名和一个与之匹配的数据库用户名。 - 同一个 map-name 可以重复使用,以便在同一映射中定义多条用户映射。 - - - - 与 pg_hba.conf 一样,此文件中的各行也可以是 include 指令,并遵循相同的规则。 - - - - 对于给定的一个操作系统用户可以对应多少个数据库用户,没有任何限制,反之亦然。因此,映射中的条目应理解为该操作系统用户被允许以该数据库用户身份连接,而不是意味着两者等价。只要存在任何一条映射项把外部认证系统获得的用户名与用户请求连接时使用的数据库用户名配对起来,该连接就会被允许。值 all 还可以用作 database-username,表示只要 system-username 匹配,该用户就被允许以任意现有数据库用户身份登录。若给 all 加上引号,则它会失去该特殊含义。 - - - - 如果 database-username 字段以 + 开头,则该操作系统用户可以以属于该角色的任意用户身份登录,这与 pg_hba.conf 中以 + 开头的用户名处理方式类似。因此,+ 标记表示匹配直接或间接属于该角色的任意角色,而没有 + 标记的名称只匹配该特定角色。对以 + 开头的用户名加上引号,会让 + 失去其特殊含义。 - - - - 如果 system-username 字段以斜线(/)开头,则该字段的其余部分会被视为一个正则表达式。(关于 PostgreSQL 正则表达式语法的细节,见 。)该正则表达式可以包含一个捕获组,也就是用圆括号括起来的子表达式;捕获到的系统用户名片段随后可以在 database-username 字段中通过 \1(反斜线一)引用。这使得在一行中映射多个用户名成为可能,特别适合简单的语法替换。例如,下面这些条目 - +注释、空白和续行的处理方式与 pg_hba.conf 相同。map-name 是任意名称,用于在 pg_hba.conf 中引用此映射。另两个字段指定操作系统用户名及与之匹配的数据库用户名。同一个 map-name 可以重复使用,以便在一项映射中指定多个用户对应关系。 + 一个操作系统用户可以对应多少个数据库用户,没有限制,反之亦然。因此,映射中的条目应理解为此操作系统用户可以作为此数据库用户连接,而不是说二者等同。只要存在一个映射条目,将从外部认证系统取得的用户名与用户请求连接时使用的数据库用户名配对,就会允许该连接。 + 如果 system-username 字段以斜杠(/)开头,该字段的其余部分就会被视为正则表达式。(参见 ,其中介绍了 PostgreSQL 的正则表达式语法。)正则表达式可以包含一个捕获,即用圆括号括起来的子表达式。系统用户名中与捕获匹配的部分,可以在 database-username 字段中使用 \1(反斜杠加数字一)来引用。这样就可以在一行中映射多个用户名,对简单的语法替换尤其有用。例如,以下条目 mymap /^(.*)@mydomain\.com$ \1 mymap /^(.*)@otherdomain\.com$ guest - - 会去掉系统用户名中以 @mydomain.com 结尾的域名部分,并允许任何系统名以 @otherdomain.com 结尾的用户以 guest 身份登录。对包含 \1database-username 加上引号,并不会\1 失去其特殊含义。 - - - - 如果 database-username 字段以斜线(/)开头,则该字段其余部分会被视为一个正则表达式。当 database-username 字段是正则表达式时,不能在其中使用 \1 来引用 system-username 字段中的捕获组。 +会去掉系统用户名中的域名部分(如果用户名以 @mydomain.com 结尾),并允许系统用户名以 @otherdomain.com 结尾的任何用户登录为 guest @@ -870,16 +736,12 @@ omicron bryanh guest1 BSD 认证,依赖于 BSD 认证框架(目前仅在 OpenBSD 上可用)。 - - - OAuth 授权/认证,依赖于外部 OAuth 2.0 身份提供方。 - - + - Peer 认证通常适用于本地连接,不过在某些情况下,信任认证也可能已经足够。 + 通常建议对本地连接使用 Peer 认证,不过在某些情况下,信任认证也可能已经足够。 密码认证是远程连接最容易采用的选择。 其余所有选项都需要某种外部安全基础设施(通常是认证服务器,或用于签发 SSL 证书的证书颁发机构),或者属于平台特定功能。 @@ -898,16 +760,14 @@ omicron bryanh guest1 - trust认证对于单用户工作站的本地连接是非常合适和方便的。通常它本身适用于一台多用户机器。不过,只要你利用文件系统权限限制了对服务器的 Unix 域套接字文件的访问,即使在多用户机器上,你也可以使用trust。 要做这些限制,你可以设置中描述的unix_socket_permissions配置参数(可能还有unix_socket_group)。 或者你可以设置unix_socket_directories配置参数来把 Unix 域套接字文件放在一个经过恰当限制的目录中。 + trust认证对于单用户工作站的本地连接是非常合适和方便的。通常它本身适用于一台多用户机器。不过,只要你利用文件系统权限限制了对服务器的 Unix 域套接字文件的访问,即使在多用户机器上,你也可能可以使用trust。 要做这些限制,你可以设置中描述的unix_socket_permissions配置参数(可能还有unix_socket_group)。 或者你可以设置unix_socket_directories配置参数来把 Unix 域套接字文件放在一个经过恰当限制的目录中。 设置文件系统权限只能有助于 Unix 套接字连接。本地 TCP/IP 连接不会被文件系统权限限制。因此,如果你想利用文件系统权限来控制本地安全,那么从pg_hba.conf中移除host ... 127.0.0.1 ...行,或者把它改为一个非trust认证方法。 - - 如果通过指定trustpg_hba.conf行让你信任每一个被允许连接到服务器的机器上的用户,trust认证只适合 TCP/IP 连接。为任何不是来自localhost(127.0.0.1)的 TCP/IP 连接使用trust很少是合理的。 - + 只有当你信任由 pg_hba.conf 中指定 trust 的行所允许连接的每台机器上的每个用户时,trust 认证才适合用于 TCP/IP 连接。对来自 localhost(127.0.0.1)以外的任何 TCP/IP 连接使用 trust,通常都不合理。 @@ -952,18 +812,14 @@ omicron bryanh guest1 md5 - - 方法md5使用一种自定义的安全性较低的挑战-响应机制。它能防止密码嗅探并且防止密码在服务器上以明文存储,但是无法保护攻击者想办法从服务器上窃取了密码哈希的情况。此外,现在认为MD5哈希算法对于确定攻击已经不再安全。 - + 方法md5使用一种自定义的、安全性较低的挑战-响应机制。它能防止密码嗅探,并避免在服务器上以明文存储密码;但如果攻击者设法从服务器上窃取了密码哈希,它就无法提供保护。此外,如今已不再认为 MD5 哈希算法能抵御有决心的攻击者。 + + md5方法不能与功能一起使用。 为了简化从md5方法到较新的SCRAM方法的转变,如果在pg_hba.conf中指定了md5但是用户在服务器上的密码是为SCRAM(见下文)加密的,则将自动选择基于SCRAM的认证。 - - - 对 MD5 加密密码的支持已被弃用,并将在未来版本的 PostgreSQL 中移除。关于迁移到其他密码类型的细节,请参阅下文。 - - + @@ -987,7 +843,7 @@ omicron bryanh guest1 - 要把现有安装从 md5 升级到 scram-sha-256,需要先确保所有正在使用的客户端库都足够新并支持 SCRAM,然后在 postgresql.conf 中设置 password_encryption = 'scram-sha-256',要求所有用户重新设置密码,并将 pg_hba.conf 中的认证方法说明改为 scram-sha-256。 + 要把现有安装从 md5 升级到 scram-sha-256,需要先确保所有正在使用的客户端库都足够新并支持 SCRAM,然后在 postgresql.conf 中设置 password_encryption = 'scram-sha-256',要求所有用户重新设置密码,并将 pg_hba.conf 中的认证方法设置改为 scram-sha-256 @@ -1141,7 +997,7 @@ omicron bryanh guest1 如果设为 1,则会在 include_realm 选项中使用域的 SAM 兼容名称(也称为 NetBIOS 名称)。这是默认值。如果设为 0,则会使用 Kerberos 用户主体名中的真实 realm 名称。 - 不要禁用这个选项,除非你的服务器运行在一个域账号(这包括一个域成员系统上的虚拟服务账号)下并且所有通过 SSPI 认证的所有客户端也在使用域账号,否则认证将会失败。 + 不要禁用这个选项,除非你的服务器运行在一个域账号(这包括一个域成员系统上的虚拟服务账号)下并且所有通过 SSPI 认证的客户端也在使用域账号,否则认证将会失败。 @@ -1206,7 +1062,7 @@ omicron bryanh guest1 map - 允许在系统用户和数据库用户名称之间进行映射。详细信息请参见。 + 允许在系统用户名和数据库用户名之间进行映射。详见 @@ -1229,7 +1085,7 @@ omicron bryanh guest1
RFC 1413 - 标识协议的本意不是作为一种认证或访问控制协议。 + 标识协议的本意不是作为一种授权或访问控制协议。
@@ -1258,7 +1114,7 @@ omicron bryanh guest1 map - 允许在系统用户和数据库用户名称之间进行映射。详细信息请参见。 + 允许在系统用户名和数据库用户名之间进行映射。详见 @@ -1288,7 +1144,7 @@ omicron bryanh guest1 - 第二种模式称为搜索+绑定模式,服务器首先使用由 ldapbinddnldapbindpasswd 指定的固定用户名和密码绑定到 LDAP 目录,并搜索试图登录数据库的用户。如果没有配置用户名和密码,则会尝试对目录进行匿名绑定。搜索会在 ldapbasedn 指定的子树上进行,并尝试对 ldapsearchattribute 指定的属性做精确匹配。一旦在搜索中找到了该用户,服务器就会作为该用户重新绑定到目录,并使用客户端指定的密码来验证登录是否正确。这种模式与 Apache mod_authnz_ldappam_ldap 等软件中的 LDAP 认证方案相同。这种方法使目录中用户对象的位置更具灵活性,但会对 LDAP 服务器额外发起两次请求。 + 第二种模式称为搜索+绑定模式,服务器首先使用由 ldapbinddnldapbindpasswd 指定的固定用户名和密码绑定到 LDAP 目录,并搜索试图登录数据库的用户。如果没有配置用户名和密码,则会尝试对目录进行匿名绑定。搜索会在 ldapbasedn 指定的子树上进行,并尝试对 ldapsearchattribute 指定的属性做精确匹配。一旦在搜索中找到了该用户,服务器会断开连接,再作为该用户重新绑定到目录,并使用客户端指定的密码来验证登录是否正确。这种模式与 Apache mod_authnz_ldappam_ldap 等软件中的 LDAP 认证方案相同。这种方法使目录中用户对象的位置更具灵活性,但会与 LDAP 服务器建立两个独立的连接。 @@ -1314,8 +1170,7 @@ omicron bryanh guest1 ldapscheme - 设置为ldaps以使用LDAPS。这是一种非标准的使用LDAP - 进行SSL加密的方式,受一些LDAP服务器实现支持。另请参阅ldaptls + 设置为ldaps以使用LDAPS。这是一种非标准的通过 SSL 使用 LDAP 的方式,受一些LDAP服务器实现支持。另请参阅ldaptls 选项作为替代。 @@ -1408,16 +1263,14 @@ omicron bryanh guest1 一个RFC 4516 - LDAP URL。这是以更紧凑和标准形式编写其他LDAP选项的替代方式。格式为 + LDAP URL。这是以更紧凑和标准形式编写部分其他 LDAP 选项的替代方式。格式为 ldap[s]://host[:port]/basedn[?[attribute][?[scope][?[filter]]]] scope必须是baseonesub中的一个,通常是最后一个。(默认为base,在此应用中通常无用。)attribute可以指定单个属性,此时将用作ldapsearchattribute的值。如果attribute为空,则filter可用作ldapsearchfilter的值。 - - URL方案ldaps选择了通过SSL进行LDAP连接的LDAPS方法,相当于使用ldapscheme=ldaps。要使用StartTLS操作进行加密LDAP连接,请使用正常的URL方案ldap并另外指定ldaptls选项。 - + URL 方案 ldaps 会选择 LDAPS 方法,通过 SSL 建立 LDAP 连接,等同于使用 ldapscheme=ldaps。要通过 StartTLS 操作使用加密的 LDAP 连接,请使用普通的 URL 方案 ldap,并在 ldapurl 之外指定 ldaptls 选项。 对于非匿名绑定,必须将ldapbinddnldapbindpasswd指定为单独的选项。 @@ -1432,7 +1285,7 @@ ldap[s]://host[:port]/ - 将简单绑定选项与搜索+绑定选项混用是错误的。若要在简单绑定模式下使用 ldapurl,该 URL 中不能包含 basedn 或查询元素。 + 将简单绑定模式的配置选项与搜索+绑定模式的配置选项混用是错误的。 @@ -1451,21 +1304,9 @@ host ... ldap ldapserver=ldap.example.net ldapprefix="cn=" ldapsuffix=", dc=exam 当请求以数据库用户 someuser 连接数据库服务器时,PostgreSQL 将尝试使用 DN cn=someuser, dc=example, dc=net 和客户端提供的密码绑定到 LDAP 服务器。如果该连接成功,数据库访问就会被授予。 - - 下面是另一种简单绑定配置,它使用 LDAPS 方案和自定义端口号,并以 URL 形式写出: - -host ... ldap ldapurl="ldaps://ldap.example.net:49151" ldapprefix="cn=" ldapsuffix=", dc=example, dc=net" - - 这种写法比单独指定 ldapserverldapschemeldapport 稍微更紧凑。 - - - - 下面是一个搜索+绑定配置示例: - + 下面是搜索加绑定配置的示例: host ... ldap ldapserver=ldap.example.net ldapbasedn="dc=example, dc=net" ldapsearchattribute=uid - - 当请求以数据库用户 someuser 连接数据库服务器时,PostgreSQL 将尝试对 LDAP 服务器进行匿名绑定(因为未指定 ldapbinddn),并在指定的基础 DN 下执行一次 (uid=someuser) 搜索。如果找到了对应条目,随后就会尝试使用该条目的信息以及客户端提供的密码进行绑定。如果第二次绑定成功,数据库访问就会被授予。 - +当请求以数据库用户 someuser 的身份连接数据库服务器时,PostgreSQL 会尝试匿名绑定到 LDAP 服务器(因为没有指定 ldapbinddn),并在指定的基础 DN 下搜索 (uid=someuser)。如果找到了条目,就会尝试使用找到的信息和客户端提供的密码进行绑定。如果第二次连接成功,就会授予数据库访问权限。 下面是以 URL 形式写出的同一个搜索+绑定配置: @@ -1679,172 +1520,7 @@ host ... radius radiusservers="server1,server2" radiussecrets="""secret one"","" - - OAuth 授权/认证 - - - OAuth 授权/认证 - - - - OAuth 2.0 是一个行业标准框架,定义见 - RFC 6749, - 它允许第三方应用获得对受保护资源的受限访问。 - - 在构建 PostgreSQL 时必须启用 OAuth 客户端支持; - 详见 。 - - - - 本文档在讨论 OAuth 生态系统时使用下列术语: - - - - - 资源所有者(或终端用户) - - - 拥有受保护资源并能够授予访问权限的用户或系统。当资源所有者是人时,本文档也使用终端用户一词。当你使用 psql 通过 OAuth 连接数据库时,你就是资源所有者/终端用户。 - - - - - - 客户端 - - - 使用访问令牌访问受保护资源的系统。使用 libpq 的应用(例如 psql)在连接 PostgreSQL 集簇时,就是 OAuth 客户端。 - - - - - - 资源服务器 - - - 托管受保护资源并供客户端访问的系统。被连接的 PostgreSQL 集簇就是资源服务器。 - - - - - - 提供方 - - - 为某个应用开发和/或管理 OAuth 授权服务器与客户端的组织、产品供应商或其他实体。不同提供方通常会为各自的 OAuth 系统选择不同的实现细节;一个提供方的客户端通常并不能保证可以访问另一提供方的服务器。 - - - 这里对“提供方”一词的使用并非标准术语,但在口语中似乎很常见。(不要将它与 OpenID 中相近的术语“Identity Provider”混淆。虽然 PostgreSQL 中的 OAuth 实现旨在与 OpenID Connect/OIDC 互操作并保持兼容,但它本身并不是 OIDC 客户端,也不要求必须使用 OIDC。) - - - - - - 授权服务器 - - - 在资源所有者完成认证并给出批准之后,接收客户端请求并向其发放访问令牌的系统。PostgreSQL 不提供授权服务器;这属于 OAuth 提供方的职责。 - - - - - - 签发者 - - - 授权服务器的一个标识符,以 https:// URL 形式出现,为 OAuth 客户端和应用提供一个可信的“命名空间”。签发者标识符使得单个授权服务器能够同时与彼此互不信任实体的客户端通信,只要这些实体维护各自独立的签发者即可。 - - - - - - - - - 对于小型部署来说,“提供方”、“授权服务器”和“签发者”之间可能并没有有意义的区别。然而在更复杂的部署中,它们之间可能是一个对多个(甚至多个对多个)的关系:某个提供方可能把多个签发者标识符租给不同租户,然后再提供多个授权服务器与其客户端交互,而这些授权服务器支持的特性集合也可能各不相同。 - - - - - - PostgreSQL 支持在 - RFC 6750 - 中定义的 Bearer 令牌,这是一类用于 OAuth 2.0 的访问令牌,其本体是一个不透明字符串。访问令牌的格式取决于具体实现,由各个授权服务器自行决定。 - - - OAuth 支持下列配置选项: - - - issuer - - - 一个 HTTPS URL,它要么是授权服务器发现文档所定义的精确 - 签发者标识符, - 要么是一个直接指向该发现文档的众所周知 URI。此参数为必需项。 - - - 当 OAuth 客户端连接到服务器时,会基于签发者标识符构造发现文档的 URL。默认情况下,该 URL 采用 OpenID Connect Discovery 的约定:会在签发者标识符末尾追加路径 /.well-known/openid-configuration。另一种情况是,如果 issuer 本身包含 /.well-known/ 路径段,那么该 URL 会原样提供给客户端。 - - - - libpq 中的 OAuth 客户端要求服务器的 issuer 设置必须与发现文档中提供的签发者标识符完全一致,而该标识符又必须与客户端的 设置完全一致。不允许大小写或格式上的任何差异。 - - - - - - - scope - - - 一个以空格分隔的 OAuth scope 列表,服务器需要借此既能授权客户端,又能认证用户。合适的取值由授权服务器以及所使用的 OAuth 验证模块决定。此参数为必需项。 - - - - - - validator - - - 用于验证 Bearer 令牌的库。如果指定,其名称必须与 oauth_validator_libraries 中列出的某个库完全匹配。除非 oauth_validator_libraries 中包含多个库,否则该参数是可选的;如果包含多个库,则该参数为必需项。 - - - - - - map - - - 允许在 OAuth 身份提供方用户名和数据库用户名之间建立映射。详见 。如果未指定映射,则与令牌关联的用户名(由 OAuth 验证器决定)必须与请求的角色名完全一致。此参数是可选的。 - - - - - - - delegate_ident_mapping - - - - 这是一个高级选项,不适合常规使用。 - - - 当设置为 1 时,会跳过基于 pg_ident.conf 的标准用户映射,而由 OAuth 验证器完全负责把终端用户身份映射到数据库角色。如果验证器授权该令牌,服务器就会信任该用户被允许以请求的角色进行连接,并且无论该用户自身的认证状态如何,连接都将继续进行。 - - - 此参数与 map 不兼容。 - - - - delegate_ident_mapping 为认证系统设计带来了额外灵活性,但也要求对 OAuth 验证器进行谨慎实现。验证器不仅必须执行标准检查,还必须判断所提供的令牌是否携带了足够的终端用户权限。请谨慎使用。 - - - - - - - @@ -1879,7 +1555,7 @@ FATAL: user "andym" does not exist FATAL: database "testdb" does not exist - 你试图连接的数据库不存在。注意,如果你没有指定数据库名,默认会使用数据库用户名作为数据库名。 + 你试图连接的数据库不存在。注意,如果你没有指定数据库名,默认会使用数据库用户名作为数据库名,但这不一定是所需的数据库名。 diff --git a/zh/15/config.sgml b/zh/15/config.sgml index 2523613c..76ae116d 100644 --- a/zh/15/config.sgml +++ b/zh/15/config.sgml @@ -15,7 +15,6 @@ - 设置参数 @@ -29,94 +28,87 @@ + - 布尔: - 值可以写为 - on、 - off、 - true、 - false、 - yes、 - no、 - 1、 + 布尔: + 值可以被写成 + on, + off, + true, + false, + yes, + no, + 1, 0 - (全部大小写不敏感)或上述任一值的无歧义前缀。 + (都是大小写不敏感的)或者这些值的任何无歧义前缀。 + - 字符串: - 通常将值放在单引号内,值中的单引号要写两次。 - 然而,如果值是简单的数字或标识符,通常可以省略引号。 - (在某些上下文中,匹配 SQL 关键字的值需要加引号。) + 字符串: + 通常值被包括在单引号内,值内部的任何单引号都需要被双写。不过,如果值是一个简单数字或者 + 标识符,引号通常可以被省略。 + (与 SQL 关键字匹配的值在某些上下文中需要加引号。) + - 数字(整数和浮点数): - 数字参数可以按通常的整数和浮点格式指定;如果参数类型是整数, - 小数值将四舍五入到最近的整数。整数参数还可以接受十六进制输入(以 - 0x 开头)和八进制输入(以 - 0 开头),但这些格式不能有小数部分。 - 不要使用千位分隔符。 - 除十六进制输入外,不需要引号。 + 数字(整数和浮点数): + 数字参数可以按惯常的整数和浮点格式指定;如果参数是整数类型,则小数值会被四舍五入到最接近的整数。 + 整数参数还接受十六进制输入(以0x开头)和八进制输入(以0开头),但这些格式不能带小数部分。 + 不要使用千位分隔符。除十六进制输入外,不要求使用引号。 + - 带单位的数字: - 某些数字参数有隐含的单位,因为它们描述的是内存或时间的量。 - 单位可以是字节、千字节、块(通常为 8 KB)、毫秒、秒或分钟。 - 这些设置的无装饰数值将使用该设置的默认单位,可以从 - pg_settings.unit - 中获知。为方便起见,可以在设置时显式指定单位,例如对时间值使用 - '120 ms',系统会自动将其转换为参数实际使用的单位。 - 注意,要使用此特性,值必须作为字符串(带引号)来写。 - 单位名称是大小写敏感的,数值和单位之间可以有空格。 + 带单位的数字: + 一些数字参数具有隐含单位,因为它们描述的是内存或时间量。单位可能是字节、千字节、块 + (通常为 8 千字节)、毫秒、秒或分钟。这类设置若给出不带单位的数字值,就会使用该设置的默认单位, + 可以通过 pg_settings.unit 了解该默认单位。为了方便, + 也可以显式指定单位,例如把时间值写成 '120 ms',系统会将其转换为该参数的实际单位。 + 注意,要使用这一特性,值必须写成字符串(带引号)。单位名称区分大小写,并且数字值与单位之间可以有空白。 - 有效的内存单位有 B(字节)、 - kB(千字节)、 - MB(兆字节)、GB - (吉字节)和 TB(太字节)。 - 内存单位的乘数是 1024,不是 1000。 + 可用的内存单位是 B(字节)、kB(千字节)、 + MB(兆字节)、GB(吉字节)和 + TB(太字节)。内存单位的乘数是 1024,而不是 1000。 - 有效的时间单位有 + 可用的时间单位是 us(微秒)、 ms(毫秒)、 s(秒)、min(分钟)、 - h(小时)和 d(天)。 + h(小时)和d(天)。 - 如果指定了带单位的小数值,如果存在更小的单位, - 将被四舍五入为下一个更小单位的倍数。 - 例如,30.1 GB 将被转换为 - 30822 MB 而不是 32319628902 B。 - 如果参数类型是整数,在任何单位转换后还会进行一次最终的整数舍入。 + 如果指定了带单位的小数值,并且存在更小一级的单位,则会将其四舍五入为该更小单位的整数倍。 + 例如,30.1 GB会被转换为30822 MB,而不是32319628902 B。 + 如果参数是整数类型,则在完成所有单位转换之后还会再做一次整数取整。 + - 枚举: - 枚举类型的参数和字符串参数的写法相同,但限制为一组预定义的值。 - 此类参数允许的值可以在 - pg_settings.enumvals - 中找到。枚举参数值是大小写不敏感的。 + 枚举: + 枚举类型的参数以与字符串参数相同的方式指定,但被限制到一组有限的值。 这样一个参数可用的值可以在pg_settings.enumvals + 中找到。枚举参数值是大小写无关的。 - + @@ -144,7530 +136,8853 @@ shared_buffers = 128MB 以这种方式设定的参数为集簇提供了默认值。除非这些设置被覆盖,活动会话看到的就是这些设置。 下面的小节描述了管理员或用户覆盖这些默认值的方法。 + + + + SIGHUP + + 主服务器进程每次收到SIGHUP信号(最简单的方法是从命令行运行pg_ctl reload或调用 SQL 函数pg_reload_conf()来发送这个信号)后都会重新读取这个配置 + 文件。主服务器进程还会把这个信号传播给所有正在运行的服务器进程,这样现有的会话也能采用新 + 值(要等待它们完成当前正在执行的客户端命令之后才会发生)。另外,你可以直接向一个单一服务 + 器进程发送该信号。有些参数只能在服务器启动时设置,在配置文件中对这些条目的修改将被忽略, + 直到下次服务器重启。配置文件中的非法参数设置也会在SIGHUP处理过程中被 + 忽略(但是会记录日志)。 + + + + 除了 postgresql.conf 之外,PostgreSQL + 数据目录还包含文件 + postgresql.auto.confpostgresql.auto.conf, + 它与 postgresql.conf 采用相同的格式,但设计为自动编辑而非手工编辑。 + 这个文件保存了通过ALTER SYSTEM命令提供的设置。 + 每当读取 postgresql.conf 时,也会读取该文件,并以同样的方式使其中设置生效。 + postgresql.auto.conf 中的设置会覆盖 postgresql.conf 中的设置。 + + + + 外部工具也可以修改 postgresql.auto.conf。 + 不建议在服务器运行时这样做, + 因为并发的 ALTER SYSTEM 命令可能会覆盖这些更改。 + 这类工具可能只是简单地在文件末尾追加新设置,也可能选择删除重复设置和/或注释 + (正如 ALTER SYSTEM 那样)。 + + + + 系统视图pg_file_settings + 可以有助于对配置文件中的更改进行提前测试,或者在SIGHUP + 信号没有达到预期效果时用来诊断问题。 + - + - + 通过SQL影响参数 - 查询规划 + + PostgreSQL提供了三个SQL命令来建立配置默认值。 + 已经提到过的ALTER SYSTEM命令提供了一种改变全局默认值的从SQL可 + 访问的方法;它在功效上等效于编辑postgresql.conf。此外,还有两个命令 + 可以针对每个数据库或者每个角色设置默认值: + - + + - 规划器方法配置 + + ALTER DATABASE命令允许针对各个数据库覆盖全局设置。 + + - - 这些配置参数提供了一种较为粗糙的方法,用于影响查询优化器所选择的查询计划。 - 如果优化器为某个特定查询选择的默认计划并不理想,一种临时解决方案是使用这些配置参数, - 强制优化器选择另一种计划。 - 改善优化器所选计划质量的更好办法包括调整规划器代价常数 - (见)、手工运行 - ANALYZE、增加 - 配置参数的值,以及使用 - ALTER TABLE SET STATISTICS 增加为特定列收集的统计信息量。 - + - - + + ALTER ROLE命令允许用针对特定用户设置的值来覆盖全局设置和数据库设置。 + + + - enable_async_append (boolean) + + 只有当开始一个新的数据库会话时,用ALTER DATABASE和 + ALTER ROLE设置的值才会被应用。它们会覆盖从配置文件或服务器命令行 + 获得的值,并且作为该会话后续的默认值。注意某些设置在服务器启动后不能被更改,并且因此 + 不能被这些命令(或者下文列举的命令)设置。 + + + + 一旦一个客户端连接到数据库,PostgreSQL会提供两个额外的SQL命令( + 以及等效的函数)用以影响会话本地的配置设置: + + + + + + + SHOW命令允许察看任何参数的当前值。对应的SQL函数是 + current_setting(setting_name text) (参见 )。 + + + + + + + 那些可以在会话本地设置的参数,允许通过SET命令修改当前会话的参数值;它对其他会话没有影响。 + 许多参数可以通过任何用户以这种方式设置,但有些只能由超级用户和被授予该参数上SET权限的用户设置。 + 相应的SQL函数是set_config(setting_name, new_value, is_local) + (参见)。 + + + + + + 此外,系统视图pg_settings可以被用来查看和改变 + 会话本地的值: + + + + + + + 查询这个视图与使用SHOW ALL相似,但是可以提供更多细节。它也更加灵活, + 因为可以为它指定过滤条件或者把它与其他关系进行连接。 + + + + + + + 在这个视图上使用UPDATE并且指定更新setting + 列,其效果等同于发出SET命令。例如,下面的命令 + +SET configuration_parameter TO DEFAULT; + + 等效于: + +UPDATE pg_settings SET setting = reset_val WHERE name = 'configuration_parameter'; + + + + + + + + + + 通过 Shell 影响参数 + + + 除了设置全局默认值或在数据库、角色级别覆盖默认值之外,你还可以通过 shell 工具把设置 + 传递给PostgreSQL。服务器和libpq + 客户端库都能通过 shell 接受参数值。 + + + + + + + 在服务器启动期间,可以通过命令行参数把参数设置传递给 + postgres命令。例如: + +postgres -c log_connections=yes -c log_destination='syslog' + + 这种方式提供的设置会覆盖通过postgresql.conf或者 + ALTER SYSTEM提供的设置,因此除了重启服务器之外无法从全局上改变它们。 + + + + + + + 当通过libpq启动一个客户端会话时,可以使用PGOPTIONS + 环境变量指定参数设置。这种方式建立的设置构成了会话生存期间的默认值,但是不会影响 + 其他的会话。由于历史原因,PGOPTIONS的格式和启动 + postgres命令时用到的相似,特别是标志必须被指定。 + 例如: + +env PGOPTIONS="-c geqo=off -c statement_timeout=5min" psql + + + + + 通过 shell 或者其他方式,其他客户端和库可能提供它们自己的机制,以便允许用户在不直接 + 使用SQL命令的前提下修改会话设置。 + + + + + + + + + 管理配置文件内容 + + + PostgreSQL提供了一些特性用于把复杂的 + postgresql.conf文件分解成子文件。在管理多个具有相关但不完全相同 + 配置的服务器时,这些特性特别有用。 + + + - enable_async_append 配置参数 + include + 配置文件中的 - - - - 允许或禁止查询规划器使用异步感知的 append 计划类型。默认值是 - on。 - - - + 除了单个参数设置之外,postgresql.conf 文件还可以包含 + include 指令,用来指定另一个要读取和处理的文件,就像把该文件插入到配置文件的这个位置一样。 + 这一特性允许把一个配置文件拆分成多个物理上独立的部分。include 指令的形式如下: + +include 'filename' + + 如果文件名不是绝对路径,则会被解释为相对于引用它的配置文件所在目录的路径。include 可以嵌套。 + - - enable_parallel_append (boolean) + - enable_parallel_append 配置参数 + include_if_exists + 配置文件中的 + + 还有一个 include_if_exists 指令,其行为与 include 相同, + 但在被引用文件不存在或无法读取时有所不同。普通的 include 会将其视为错误, + 而 include_if_exists 只会记录一条消息并继续处理引用它的配置文件。 + + + + + include_dir + 配置文件中的 + + postgresql.conf 文件也可以包含 include_dir 指令, + 用来指定一个应被包含的配置文件目录。其用法如下: + +include_dir 'directory' + + 非绝对目录名会被解释为相对于引用它的配置文件所在目录的路径。在指定目录中, + 只有名称以 .conf 结尾的非目录文件才会被包含。以 . + 开头的文件名也会被忽略,以避免在某些平台上误处理隐藏文件。包含目录中的多个文件会按文件名顺序处理 + (依据 C 区域规则排序,即数字在字母之前,大写字母在小写字母之前)。 + + + + 包含文件或目录可以用来在逻辑上分隔数据库配置的各个部分,而不是用一个很大的postgresql.conf文件。 + 考虑一个有两台数据库服务器的公司,每一个都有不同的内存量。 + 两者很可能会共享部分配置,例如日志设置。但是两者关于内存的参数将会不同。 + 并且还可能会有服务器相关的自定义。 + 一种管理这类情况的方法是将你的站点的自定义配置修改分成三个文件。 + 你可以把下面的内容加入到你的postgresql.conf文件末尾来包含它们: + +include 'shared.conf' +include 'memory.conf' +include 'server.conf' + + 所有的系统将会有相同的shared.conf。 + 每个有特定内存量的服务器可以共享相同的memory.conf。 + 你可能对所有 8GB 内存的服务器有一个,而对那些 16GB 内存的服务器有另一个。 + 并且最后server.conf可以装有真正服务器相关的配置信息。 + + + + 另一种做法是创建一个配置文件目录,并把这些信息放到其中的文件里。 + 例如,一个conf.d目录可以在postgresql.conf的末尾被引用: + +include_dir 'conf.d' + + 然后你可以这样命名conf.d目录中的文件: + +00shared.conf +01memory.conf +02server.conf + + 这种命名习惯建立了这些文件将被载入的清晰顺序。这是很重要的,因为在服务器读取配置 + 文件时,对于一个特定的参数只有最后碰到的一个设置才会被使用。在这个示例中, + conf.d/02server.conf设置的东西将会覆盖在 + conf.d/01memory.conf中相同参数的值。 + + + + 你还可以使用这种配置目录方法,在命名文件时更有描述性: + +00shared.conf +01memory-8GB.conf +02server-foo.conf + + 这种形式的安排为每个配置文件变体给定了一个唯一的名称。当多个服务器把它们的配置全部存储在一个位置(例如在一个版本控制仓库中)时,这可以帮助消除歧义(在版本控制下存储数据库配置文件是另一个值得考虑的好方法)。 + + + + + + + 文件位置 + + + 除了已经提到过的postgresql.conf文件之外,PostgreSQL还使用另外两个手工编辑的配置文件,它们控制客户端认证(其使用在中讨论)。默认情况下,所有三个配置文件都存放在数据库集簇的数据目录中。 本节描述的参数允许配置文件放在别的地方(这么做可以简化管理,特别是如果配置文件被独立放置,可以很容易保证它得到恰当的备份)。 + + + + + + data_directory (string) + + data_directory配置参数 + - 允许或禁止查询规划器使用并行感知的 append 计划类型。默认值是 - on。 + 指定用于数据存储的目录。这个参数只能在服务器启动时设置。 - - enable_self_join_elimination (boolean) - - enable_self_join_elimination配置参数 - - - - - 启用或禁用查询规划器的一项优化,该优化会分析查询树并将自连接替换为语义等价的单次扫描。 - 目前只考虑普通表。默认值为on。 - - - - - + - enable_seqscan (boolean) - - 顺序扫描 - + config_file (string) - enable_seqscan配置参数 + config_file配置参数 - 允许或禁止查询规划器使用顺序扫描计划类型。它不可能完全禁止顺序扫描,但是关闭这个变量将使得规划器尽可能优先使用其他方法。默认值是on。 + 指定主服务器配置文件(通常叫postgresql.conf)。这个参数只能在postgres命令行上设置。 - + - enable_sort (boolean) + hba_file (string) - enable_sort配置参数 + hba_file配置参数 - 允许或禁止查询规划器使用显式排序步骤。它不可能完全禁止显式排序,但是关闭这个变量将使得规划器尽可能优先使用其他方法。默认值是on。 + 指定基于主机认证配置文件(通常叫pg_hba.conf)。这个参数只能在服务器启动的时候设置。 - + - enable_tidscan (boolean) + ident_file (string) - enable_tidscan配置参数 + ident_file配置参数 - 允许或禁止查询规划器使用TID扫描计划类型。默认值是on。 + 指定用于用户名称映射的配置文件(通常叫pg_ident.conf)。这个参数只能在服务器启动的时候设置。另见 - + - enable_partition_pruning (boolean) - - enable_partition_pruning配置参数 - + external_pid_file (string) + + external_pid_file配置参数 + - 允许或者禁止查询规划器从查询计划中消除一个分区表的分区。这也控制着规划器产生允许执行器在查询执行期间移除(忽略)分区的查询计划的能力。默认值是on。详情请参考。 + 指定服务器应创建的额外进程 ID(PID)文件的名称,供服务器管理程序使用。这个参数只能在服务器启动的时候设置。 - - - - 规划器代价常量 + + 在默认安装中不会显式设置以上参数。相反,命令行参数或者环境变量PGDATA指定数据目录,并且上述配置文件都能在数据目录中找到。 + - - 这一节中描述的代价变量可以按照任意尺度衡量。我们只关心它们的相对值,将它们以相同的因子缩放不会影响规划器的选择。默认情况下,这些代价变量是基于顺序页面获取的代价的,即seq_page_cost被设置为1.0并且其他代价变量都参考它来设置。不过你可以使用你喜欢的不同尺度,例如在一个特定机器上的真实执行时间。 - + + 如果你想把配置文件放在别的地方而不是数据目录中,那么postgres 命令行选项或者环境变量PGDATA必须指向包含配置文件的目录,并且postgresql.conf中(或者命令行上)的data_directory参数必须设置为数据目录的实际位置。请注意,data_directory将覆盖PGDATA指定的数据目录位置,但是不覆盖配置文件的位置。 + - + + 如果你愿意,可以使用选项config_filehba_file和/或ident_file单独指定配置文件名称和位置。config_file只能在postgres命令行上指定,但是其他参数可以在主配置文件中设置。如果所有三个参数外加data_directory被显式地设置,则不必指定PGDATA。 + - - 不幸的是,没有一种良定义的方法来决定代价变量的理想值。它们最好被作为一个特定安装将接收到的查询的平均值来对待。这意味着基于少量的实验来改变它们是有风险的。 - - + + 在设置任何这些参数时,相对路径将被解释为相对于启动 postgres 时所在目录的路径。 + + - + + 连接和认证 - + + 连接设置 - seq_page_cost (floating point) + + + + listen_addresses (string) - seq_page_cost配置参数 + listen_addresses 配置参数 - 设置规划器对一系列顺序磁盘页面获取中的一次的代价估计。默认值是 1.0。通过把表和索引放在一个特殊的表空间(要设置该表空间的同名参数)中可以覆盖这个值(见)。 + 指定服务器用于监听来自客户端应用程序的连接的TCP/IP地址。 + 该值采用逗号分隔的主机名和/或数字IP地址的形式。特殊条目*对应于所有可用的IP接口。 + 条目0.0.0.0允许监听所有IPv4地址,::允许监听所有IPv6地址。 + 如果列表为空,则服务器不会在任何IP接口上监听,此时只能使用Unix域套接字进行连接。 + 如果列表不为空,则服务器将在至少一个TCP/IP地址上可以监听时启动。 + 对于任何无法打开的TCP/IP地址,将发出警告。 + 默认值为localhost,仅允许进行本地TCP/IP回环连接。 - - - + + 在客户端认证()允许对谁可以访问服务器进行细粒度控制的同时,listen_addresses 控制哪些接口接受连接尝试,这可以帮助防止在不安全的网络接口上重复恶意连接请求。此参数只能在服务器启动时设置。 + + + - random_page_cost (floating point) + + port (integer) - random_page_cost配置参数 + port 配置参数 + + 服务器监听的 TCP 端口,默认是 5432。请注意,服务器监听的所有 IP 地址都使用同一个端口号。 + 此参数只能在服务器启动时设置。 + + + + + max_connections (integer) + + max_connections 配置参数 + + + - 设置规划器对一次非顺序获取磁盘页面的代价估计。默认值是 4.0。通过把表和索引放在一个特殊的表空间(要设置该表空间的同名参数)中可以覆盖这个值(见)。 + 决定数据库服务器允许的最大并发连接数。默认值通常是 100 个连接,但如果内核设置不支持 + (在 initdb 期间确定),则可能更少。这个参数只能在服务器启动时设置。 - 减少这个值(相对于seq_page_cost)将导致系统更倾向于索引扫描;提高它将让索引扫描看起来相对更昂贵。你可以一起提高或降低两个值来改变磁盘 I/O 代价相对于 CPU 代价的重要性,后者由下列参数描述。 + 当运行一个备库时,你必须设置这个参数等于或大于主库上的参数。 + 否则,备库上将不允许查询。 + + + + + superuser_reserved_connections + (integer) + + superuser_reserved_connections 配置参数 + + + - 对持久存储的随机访问通常远不止比顺序访问贵四倍。不过,仍使用较低的默认值(4.0),因为假定对存储的大多数随机访问(例如索引读取)都将在缓存中命中。此外,网络附加存储的延迟往往会降低随机访问的相对额外开销。 + 决定为 PostgreSQL 超级用户连接保留多少个连接。 + 同时活跃的连接数最多始终只能达到 。 + 当活跃并发连接数至少达到 max_connections 减去 + superuser_reserved_connections 时,新连接将只接受超级用户, + 并且不再接受新的复制连接。 - 如果你认为缓存命中的频率低于默认值所反映的情况,并且网络延迟很低,则可以增大 - random_page_cost,以更好地反映随机存储读取的真实代价。相反,若某种存储的随机读取代价相对于顺序读取更高,例如机械磁盘,也可以用更高的 random_page_cost 值来更好地建模。对应地,如果你的数据很可能完全缓存在内存中,例如数据库小于服务器总内存,或者网络延迟较高,则降低 random_page_cost 可能更合适。 + 默认值是 3 个连接。该值必须小于 max_connections。 + 这个参数只能在服务器启动时设置。 - - - - - 尽管允许你将random_page_cost设置得小于seq_page_cost,但实际上这样没有意义。不过,如果数据库被整个缓存在 RAM 中,将它们设置为相等是合理的,因为在这种情况下,非顺序访问页面并不会产生额外代价。同样,在一个高度缓存化的数据库中,你应该相对于 CPU 参数降低这两个值,因为获取一个已经在 RAM 中的页面的代价要远小于通常情况下的代价。 - - - - - + - cpu_tuple_cost (floating point) + + unix_socket_directories (string) - cpu_tuple_cost配置参数 + unix_socket_directories 配置参数 - 设置规划器对一次查询中处理每一行的代价估计。默认值是 0.01。 + 指定服务器用于监听来自客户端应用的连接的 Unix 域套接字目录。通过列出用逗号分隔的多个目录可以建立多个套接字。 + 项之间的空白被忽略,如果你需要在名字中包括空白或逗号,在目录名周围放上双引号。 + 一个空值指定在任何 Unix 域套接字上都不监听,在这种情况中只能使用 TCP/IP 套接字来连接到服务器。 - - - + + 以 @ 开头的值表示应在抽象命名空间中创建 Unix 域套接字(目前仅在 Linux 上支持)。 + 在这种情况下,此值不指定一个目录,而是一个前缀,从中计算实际套接字名称的方式与文件系统命名空间相同。 + 虽然抽象套接字名称前缀可以自由选择(因为它不是文件系统位置),但惯例上仍然使用类似文件系统的值,例如 + @/tmp。 + - cpu_index_tuple_cost (floating point) + + 默认值通常是 /tmp,但可以在构建时更改。 + 在 Windows 上,默认值为空,这意味着默认不会创建 Unix 域套接字。这个参数只能在服务器启动时设置。 + + + + 除了套接字文件本身(名为.s.PGSQL.nnnn,其中nnnn是服务器的端口号),一个名为.s.PGSQL.nnnn.lock的普通文件会在每一个unix_socket_directories目录中被创建。 + 任何一个都不应该被手工移除。 + 对于抽象命名空间,没有锁文件被建立。 + + + + + + unix_socket_group (string) - cpu_index_tuple_cost配置参数 + unix_socket_group 配置参数 - 设置规划器对一次索引扫描中处理每一个索引项的代价估计。默认值是 0.005。 + 设置 Unix 域套接字的所属组(套接字的所属用户总是启动服务器的用户)。可以与选项unix_socket_permissions一起用于对 Unix域连接进行访问控制。默认是一个空字符串,表示服务器用户的默认组。这个参数只能在服务器启动时设置。 - - - + + Windows 上不支持这个参数。 + 所有设置会被忽略。 + 同样,抽象命名空间中的套接字没有文件属主,所以在这种情况下,这个设置也会被忽略。 + + + - cpu_operator_cost (floating point) + + unix_socket_permissions (integer) - cpu_operator_cost配置参数 + unix_socket_permissions 配置参数 - - 设置规划器对于一次查询中处理每个操作符或函数的代价估计。默认值是 0.0025。 + 设置 Unix 域套接字的访问权限。Unix 域套接字使用通常的 Unix 文件系统权限集。参数值应是以 chmodumask 系统调用所接受格式指定的数字权限模式。(要使用惯用的八进制格式,数字必须以 0(零)开头。) + + + 默认权限是 0777,表示任何人都可以连接。合理的其他取值包括 0770(仅属主和所属组,另见 unix_socket_group)和 0700(仅属主)。(注意,对 Unix 域套接字而言,只有写权限起作用,因此设置或撤销读权限和执行权限没有意义。) + + + 此访问控制机制独立于 中描述的机制。 + + + 此参数只能在服务器启动时设置。 + + + 此参数对完全忽略套接字权限的系统无效,尤其是 Solaris(截至 Solaris 10)。在这些系统上,可以将 unix_socket_directories 指向一个仅向目标用户授予搜索权限的目录,以达到类似效果。 + + + 抽象命名空间中的套接字没有文件权限,因此这种情况下也会忽略此设置。 - - - + - parallel_setup_cost (floating point) + + bonjour (boolean) - parallel_setup_cost 配置参数 + bonjour 配置参数 - - 设置规划器对启动并行工作者进程的代价估计。默认是 1000。 + 启用通过 Bonjour 通告服务器存在的功能。默认值为关闭。此参数只能在服务器启动时设置。 - - - + - parallel_tuple_cost (floating point) + + bonjour_name (string) - parallel_tuple_cost 配置参数 + bonjour_name 配置参数 + + 指定 Bonjour 服务名。空字符串 ''(默认值)表示使用计算机名。 + 如果编译时未启用 Bonjour 支持,则此参数会被忽略。此参数只能在服务器启动时设置。 + + + + + tcp_keepalives_idle (integer) + + tcp_keepalives_idle 配置参数 + + + - 设置规划器对于从一个并行工作者进程传递一个元组给另一个进程的代价估计。默认是 0.1。 + 指定在多久没有网络活动后,操作系统应向客户端发送 TCP keepalive 消息。 + 如果指定值时没有单位,则以秒为单位。值 0(默认值)表示选择操作系统默认值。 + 这个参数只有在支持 TCP_KEEPIDLE 或等效套接字选项的系统以及 Windows 上才可用; + 在其他系统上,它必须为零。在通过 Unix 域套接字连接的会话中,这个参数会被忽略,并始终读作零。 + + + 在 Windows 上,值 0 会将此参数设置为 2 小时,因为 Windows 不提供读取系统默认值的方法。 + + - - - + - min_parallel_table_scan_size (integer) + + tcp_keepalives_interval (integer) - min_parallel_table_scan_size配置参数 + tcp_keepalives_interval 配置参数 - - 为必须扫描的表数据量设置一个最小值,扫描的表数据量超过这一个值才会考虑使用并行扫描。 - 对于并行顺序扫描,被扫描的表数据量总是等于表的尺寸,但是在使用索引时,被扫描的表数据量通常会更小。 - 如果指定值时没有单位,则以块为单位,即BLCKSZ字节,通常为8kB。默认值是8兆字节(8MB)。 + 指定未被客户端确认收到的 TCP keepalive 消息在多久之后应被重传。 + 如果指定值时没有单位,则以秒为单位。值 0(默认值)表示选择操作系统默认值。 + 这个参数只有在支持 TCP_KEEPINTVL 或等效套接字选项的系统以及 Windows 上才可用; + 在其他系统上,它必须为零。在通过 Unix 域套接字连接的会话中,这个参数会被忽略,并始终读作零。 + + + 在 Windows 上,值 0 会将此参数设置为 1 秒,因为 Windows 不提供读取系统默认值的方法。 + + - - - + - min_parallel_index_scan_size (integer) + + tcp_keepalives_count (integer) - min_parallel_index_scan_size配置参数 + tcp_keepalives_count 配置参数 - - 为必须扫描的索引数据量设置一个最小值,扫描的索引数据量超过这一个值时才会考虑使用并行扫描。 - 注意并行索引扫描通常并不会触及整个索引,它是规划器认为该扫描会实际用到的相关页面的数量。 - 这个参数还用于决定特定的索引是否参与并行vacuum。参见。 - 如果指定值时没有单位,则以块为单位,即BLCKSZ字节,通常为8kB。默认值是512千字节(512kB)。 + 指定在服务器与客户端之间的连接被视为中断之前,可以丢失多少个 TCP keepalive 消息。 + 值 0(默认值)表示选择操作系统默认值。 + 这个参数只有在支持 TCP_KEEPCNT 或等效套接字选项的系统上才可用 + ;在其他系统上,它必须为零。在通过 Unix 域套接字连接的会话中, + 这个参数会被忽略,并始终读作零。 + + + Windows 不支持此参数,它必须为零。 + + - - - + - effective_cache_size (integer) + + tcp_user_timeout (integer) - effective_cache_size配置参数 + tcp_user_timeout 配置参数 - - 设置规划器对一个单一查询可用的有效磁盘缓冲区尺寸的假设。 - 这个参数会被考虑在使用一个索引的代价估计中,更高的数值会使得索引扫描更可能被使用,更低的数值会使得顺序扫描更可能被使用。 - 在设置这个参数时,你还应该考虑PostgreSQL的共享缓冲区以及将被用于PostgreSQL数据文件的内核磁盘缓冲区,尽管有些数据可能在两个地方都存在。 - 另外,还要考虑预计在不同表上的并发查询数目,因为它们必须共享可用的空间。 - 这个参数对PostgreSQL分配的共享内存尺寸没有影响,它也不会保留内核磁盘缓冲,它只用于估计的目的。系统也不会假设在查询之间数据会保留在磁盘缓冲中。 - 如果指定值时没有单位,则以块为单位,即BLCKSZ字节,通常为8kB。 - 默认值是 4吉字节(4GB)。(如果BLCKSZ不是8kB,默认值会按比例缩放它。) + 指定已发送的数据在 TCP 连接被强制关闭之前最多可以保持未确认状态多长时间。 + 如果指定值时没有单位,则以毫秒为单位。值 0(默认值)表示选择操作系统默认值。 + 这个参数只在支持 TCP_USER_TIMEOUT 的系统上受支持; + 在其他系统上,它必须为零。在通过 Unix 域套接字连接的会话中,此参数会被忽略,并始终读作零。 + + + Windows 不支持此参数,它必须为零。 + + - - - + - jit_above_cost (floating point) + + client_connection_check_interval (integer) - jit_above_cost配置参数 + client_connection_check_interval 配置参数 - - 设置激活JIT编译的查询代价,如果查询代价超过这个值就会激活JIT编译(如果启用了JIT,见)。执行JIT会消耗一些规划时间,但是能够加速查询执行。将这个值设置为-1会禁用JIT编译。默认值是100000。 + 设置查询执行期间可选的客户端连接检查的时间间隔,用于检查客户端是否仍然连接。检查通过轮询套接字执行;如果内核报告连接已经关闭,就可以更早中止长时间运行的查询。 + + + 此选项依赖 Linux、macOS、illumos 和 BSD 系列操作系统提供的内核事件,目前在其他系统上不可用。 + + + 如果指定值时没有单位,则以毫秒计。默认值为 0,表示禁用连接检查。如果不进行连接检查,服务器只有在下一次与套接字交互(等待、接收或发送数据)时,才会检测到连接丢失。 + + + 要让内核本身在包括网络故障在内的所有场景中,能够在确定的时间范围内可靠地检测到 TCP 连接丢失,可能还需要调整操作系统的 TCP keepalive 设置,或 PostgreSQL 设置。 - + - + + - jit_inline_above_cost (floating point) + + 认证 + + + + authentication_timeout (integer) + 超时客户端认证 + 客户端认证期间超时 - jit_inline_above_cost配置参数 + authentication_timeout 配置参数 + - 设置JIT编译尝试内联函数和操作符的查询代价阈值,如果查询代价超过这个值,JIT编译就会尝试内联。内联会增加规划时间,但是可以提高执行速度。将这个参数设置成小于jit_above_cost是没有意义的。将这个参数设置为-1会禁用内联。默认值是500000。 + 允许完成客户端认证的最长时间。如果一个客户端没有在这段时间里完成认证协议,服务器将关闭连接。 + 这样就避免了出问题的客户端无限制地占有一个连接。如果指定值时没有单位,则以秒为单位。 + 默认值是 1分钟(1m)。这个参数只能在服务器命令行上或者在postgresql.conf文件中设置。 - - - + - jit_optimize_above_cost (floating point) + + password_encryption (enum) - jit_optimize_above_cost配置参数 + password_encryption 配置参数 - 设置JIT编译应用优化的查询代价阈值,如果查询代价超过这个值,JIT编译就会应用开销较大的优化。这类优化会增加规划时间,但是更能够改进执行速度。将这个参数设置成小于jit_above_cost是没有意义的,并且将它设置成大于jit_inline_above_cost也未必有益。将这个参数设置为-1会禁用开销较大的优化。默认值是500000。 + 当在 中指定密码时, + 该参数决定用于加密密码的算法。可能的值有 scram-sha-256, + 即使用 SCRAM-SHA-256 加密密码,以及 md5,即将密码存储为 MD5 哈希。 + 默认值为 scram-sha-256 - - - - - - - - 遗传查询优化 - - - GEQO是一个使用探索式搜索来执行查询规划的算法。它可以降低负载查询的规划时间。 同时,GEQO的检索是随机的,因此它的规划可能会不可确定。 更多信息参阅Chapter 50。 - 遗传查询规划器(GEQO)是一种使用启发式搜索来进行查询规划的算法。它可以降低对于复杂查询(连接很多表的查询)的规划时间,但是代价是它产生的计划有时候要差于使用穷举搜索算法找到的计划。详见。 - - - - - + + 请注意,较旧的客户端可能缺少对 SCRAM 认证机制的支持,因此无法使用以 SCRAM-SHA-256 加密的密码。 + 详情参见 。 + + + - geqo (boolean) - - 遗传查询优化 - - - GEQO - 遗传查询优化 - + + krb_server_keyfile (string) - geqo配置参数 + krb_server_keyfile 配置参数 - 允许或禁止遗传查询优化。默认是启用。在生产环境中通常最好不要关闭它。geqo_threshold变量提供了对 GEQO 更细粒度的空值。 + 设置服务器的Kerberos密钥文件的位置。 + 默认为FILE:/usr/local/pgsql/etc/krb5.keytab(其中目录部分是在构建时由sysconfdir指定的;可用pg_config --sysconfdir来确定该目录)。 + 如果这个参数被设为空字符串,它将被忽略,并且系统依赖的默认值被应用。 + 这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 + 详情请参考 - - - + - geqo_threshold (integer) + + krb_caseins_users (boolean) - geqo_threshold配置参数 + krb_caseins_users 配置参数 - 只有当涉及的FROM项数量至少有这么多个的时候,才使用遗传查询优化(注意一个FULL OUTER JOIN只被计为一个FROM项)。默认值是 12。对于更简单的查询,通常会使用普通的穷举搜索规划器,但是对于有很多表的查询穷举搜索会花很长时间,通常比执行一个次优的计划带来的惩罚值还要长。因此,在查询尺寸上的一个阈值是管理 GEQO 使用的一种方便的方法。 + 设置是否应该以大小写不敏感的方式对待GSSAPI用户名。默认值是off(大小写敏感)。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 - - - + - geqo_effort (integer) + + db_user_namespace (boolean) - geqo_effort配置参数 + db_user_namespace 配置参数 + + 此参数启用各数据库独立的用户名。默认关闭。 + 此参数只能在postgresql.conf文件中或在服务器命令行上设置。 + - 控制 GEQO 里规划时间和查询规划的有效性之间的平衡。这个变量必须是 一个范围从 1 到 10 的整数。缺省值是 5 。大的数值增加花在进行查询 规划上面的时间,但是也很可能会提高选中更有效的查询规划的几率。 - 控制 GEQO 中规划时间和查询计划质量之间的折中。这个变量必须是位于 1 到 10 之间的一个整数。默认值是 5。更大的值会增加花在查询规划上的时间,但是同时也增加了选择一个高效查询计划的可能性。 + 如果启用此参数,你应以username@dbname的形式创建用户。 + 连接的客户端传入username时,会在用户名后附加@和数据库名, + 然后由服务器查找此数据库专属的用户名。请注意,在 SQL 环境中创建名称包含@的用户时,需要用引号括起用户名。 - geqo_effort实际并不直接做任何事情;它只是被用来计算其他影响 GEQO 行为的变量(如下所述)的默认值。如果你愿意,你可以手工设置其他参数。 + 启用此参数后,仍然可以创建普通的全局用户。只需在客户端指定用户名时附加@,例如joe@。 + 服务器查找用户名之前会去掉@。 + + + + db_user_namespace会使客户端和服务器的用户名表示形式不同。 + 认证检查始终使用服务器端的用户名,因此认证方法必须针对服务器端的用户名配置,而不是客户端的用户名。 + 由于md5在客户端和服务器上都使用用户名作为盐值,md5不能与db_user_namespace一起使用。 + + + + 此特性旨在作为找到完整解决方案之前的临时措施。届时将移除此选项。 + + + + - + + SSL - geqo_pool_size (integer) + + 关于 SSL 的设置,参见 。虽然对 SSL 协议的支持已被弃用,但由于历史原因,用于控制 TLS 协议传输加密的配置参数仍以 ssl 命名。在此语境中,SSLTLS 这两个术语可互换使用。 + + + + + ssl (boolean) - geqo_pool_size配置参数 + ssl 配置参数 - 控制 GEQO 使用的池尺寸,它就是遗传种群中的个体数目。它必须至少为 2,且有用的值通常在 100 到 1000 之间。如果它被设置为零(默认设置)则会基于geqo_effort和查询中表的数量选择一个合适的值。 + 启用SSL连接。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。默认值是off - - - + - geqo_generations (integer) + + ssl_ca_file (string) - geqo_generations配置参数 + ssl_ca_file 配置参数 - 控制 GEQO 使用的子代数目。子代的意思是算法的迭代次数。它必须至少 是 1 ,有用的值范围和池大小相同。如果设置为零(缺省),那么将基于 geqo_pool_size选取合适的值。 - 控制 GEQO 使用的代数,也是算法的迭代次数。它必须至少为 1,并且有用值的范围和池尺寸相同。如果它被设置为零(默认设置)则会基于geqo_pool_size选择一个合适的值。 + 指定包含 SSL 服务器证书颁发机构(CA)的文件名。相对路径是相对于数据目录的。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。默认值为空,表示没有载入CA文件,并且客户端证书验证没有被执行。 - - - + - geqo_selection_bias (floating point) + + ssl_cert_file (string) - geqo_selection_bias配置参数 + ssl_cert_file 配置参数 - 控制 GEQO 使用的选择偏好。选择偏好是种群中的选择压力。值可以是 1.5 到 2.0 之间,后者是默认值。 + 指定包含 SSL 服务器证书的文件名。相对路径是相对于数据目录的。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。默认值是server.crt - + - - - geqo_seed (floating point) + + ssl_crl_file (string) - geqo_seed配置参数 + ssl_crl_file 配置参数 - 控制 GEQO 使用的随机数生成器的初始值,随机数生成器用于在连接顺序搜索空间中选择随机路径。该值可以从 0 (默认值)到 1。变化该值会改变被探索的连接路径集合,并且可能导致找到一个更好或更差的路径。 - + 指定包含SSL客户端证书吊销列表(CRL)的文件名。 + 相对路径是相对于数据目录的。 + 此参数只能在postgresql.conf文件或服务器命令行中设置。 + 默认为空,表示不加载CRL文件(除非设置了)。 + - + - - - + + ssl_crl_dir (string) + + ssl_crl_dir 配置参数 + + + - 其他规划器选项 + + 指定包含SSL客户端证书吊销列表(CRL)的目录名称。相对路径是相对于数据目录的。 + 此参数只能在postgresql.conf文件或服务器命令行中设置。 + 默认为空,表示不使用CRL(除非设置了)。 + - + + 这个目录需要用OpenSSL 命令 openssl rehashc_rehash来准备。 + 详情参阅相应文档。 + - + + 当使用此设置时,在连接时会按需加载指定目录下的CRL。 + 新的CRL可以添加到该目录中,并可以立即使用。 + 这与不同,那个会导致文件中的CRL在服务器启动时或重新加载配置时加载。 + 两个设置可以一起使用。 + + + - default_statistics_target (integer) + + ssl_key_file (string) - default_statistics_target配置参数 + ssl_key_file 配置参数 - 为没有通过ALTER TABLE SET STATISTICS设置列相关目标的表列设置默认统计目标。更大的值增加了需要做ANALYZE的时间,但是可能会改善规划器的估计质量。默认值是 100。有关PostgreSQL查询规划器使用的统计信息的更多内容, 请参考。 + 指定包含 SSL 服务器私钥的文件名。相对路径是相对于数据目录。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。默认值是server.key - - - + - constraint_exclusion (enum) - - constraint exclusion - + + ssl_ciphers (string) - constraint_exclusion配置参数 + ssl_ciphers 配置参数 - 控制查询规划器对表约束的使用,以优化查询。 - constraint_exclusion的允许值是on(对所有表检查约束)、off(从不检查约束)和partition(只对继承的子表和UNION ALL子查询检查约束)。 - partition是默认设置。它通常与传统的继承树一起使用来提高性能。 - + 指定允许 SSL 连接使用的 SSL 密码套件列表。 + 该设置的语法及支持的值列表可参见 OpenSSL 包中的 + ciphers 手册页。 + 只有使用 TLS 1.2 及更低版本的连接会受到影响。目前还没有控制 + TLS 1.3 连接所用密码选择的设置。默认值是 + HIGH:MEDIUM:+3DES:!aNULL。除非你有特定的安全需求,否则这个默认值通常是合理的选择。 + - 当对一个特定表允许这个参数,规划器比较查询条件和表的CHECK约束,并且忽略那些条件违反约束的表扫描。例如: - - -CREATE TABLE parent(key integer, ...); -CREATE TABLE child1000(check (key between 1000 and 1999)) INHERITS(parent); -CREATE TABLE child2000(check (key between 2000 and 2999)) INHERITS(parent); -... -SELECT * FROM parent WHERE key = 2400; - - - 在启用约束排除时,这个SELECT将完全不会扫描child1000,从而提高性能。 + 这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 - 目前,约束排除只在通过继承树实现表分区的情况中被默认启用。为所有表启用它会增加额外的规划开销,特别是在简单查询上并且不会产生任何好处。 - 如果没有用传统继承树分区的表时,最好是完全关闭它。(注意分区表的等效特性是由单独的参数控制的,.) + 默认值的解释: + + + HIGH + + + 使用HIGH组中密码(例如 AES、Camellia、3DES)的密码套件。 + + + + + + MEDIUM + + + 使用MEDIUM组中密码(例如 RC4、SEED)的密码套件。 + + + + + + +3DES + + + OpenSSLHIGH的默认排序有问题, + 因为它将 3DES 排在 AES128 之前。这是不正确的,因为 3DES 的安全性低于 AES128, + 并且速度也慢得多。+3DES会把它重新排序到其他所有 + HIGHMEDIUM密码之后。 + + + + + + !aNULL + + + 禁用不进行认证的匿名密码套件。这类密码套件容易遭受MITM攻击,因此不应使用。 + + + + - 更多关于使用约束排除实现分区的信息请参阅。 + 可用的密码套件细节可能会随着OpenSSL 版本变化。 + 可使用命令 openssl ciphers -v 'HIGH:MEDIUM:+3DES:!aNULL'来查看当前安装的OpenSSL版本的实际细节。 + 注意这个列表是根据服务器密钥类型在运行时过滤过的。 - - - + - cursor_tuple_fraction (floating point) + + ssl_prefer_server_ciphers (boolean) - cursor_tuple_fraction配置参数 + ssl_prefer_server_ciphers 配置参数 - - 设置规划器对将被检索的一个游标的行的比例的估计。默认值是 0.1。更小的值使得规划器偏向为游标使用快速开始计划,它将很快地检索前几行但是可能需要很长时间来获取所有行。更大的值强调总的估计时间。最大设置为 1.0,游标将和普通查询完全一样地被规划,只考虑总估计时间并且不考虑前几行会被多快地返回。 + 指定是否使用服务器的 SSL 密码套件优先顺序,而非客户端的优先顺序。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。默认值为 on。 + + + PostgreSQL 9.4 之前的版本没有此设置,始终采用客户端的优先顺序。此设置主要用于与这些旧版本保持向后兼容。采用服务器的优先顺序通常更好,因为服务器更可能得到适当配置。 - - - + - from_collapse_limit (integer) + + ssl_ecdh_curve (string) - from_collapse_limit配置参数 + ssl_ecdh_curve 配置参数 - - 如果生成的FROM列表不超过这么多项,规划器将把子查询融合到上层查询。较小的值可以减少规划时间,但是可能 会生成较差的查询计划。默认值是 8。详见。 + 指定在 ECDH 密钥交换中使用的曲线名称。所有连接的客户端都必须支持该曲线。它不必与服务器椭圆曲线密钥使用的曲线相同。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。默认值为 prime256v1 - - 将这个值设置为或更大,可能触发使用 GEQO 规划器,从而产生非最优计划。见。 + OpenSSL 中最常见的曲线名称为:prime256v1(NIST P-256)、secp384r1(NIST P-384)、secp521r1(NIST P-521)。可以用 openssl ecparam -list_curves 命令显示可用曲线的完整列表,但其中并非所有曲线都能用于 TLS - - - jit (boolean) + + ssl_min_protocol_version (enum) - jit配置参数 + ssl_min_protocol_version 配置参数 - - 决定如果可用(见),PostgreSQL是否可以使用JIT编译。默认值是on。 + 设置要使用的最低 SSL/TLS 协议版本。当前有效值为:TLSv1TLSv1.1TLSv1.2TLSv1.3。较旧版本的 OpenSSL 库不支持所有值;如果选择了不支持的设置,就会报错。TLS 1.0 之前的协议版本,即 SSL 2 和 3,始终被禁用。 + + + 默认值为 TLSv1.2,符合本文撰写时的行业最佳实践。 + + + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 - - - + - join_collapse_limit (integer) + + ssl_max_protocol_version (enum) - join_collapse_limit配置参数 + ssl_max_protocol_version 配置参数 - - 如果得出的列表中不超过这么多项,那么规划器将把显式JOIN(除了FULL JOIN)结构重写到 FROM项列表中。较小的值可减少规划时间,但是可能会生成差些的查询计划。 + 设置要使用的最高 SSL/TLS 协议版本。有效值与 相同,此外还可设为空字符串,表示允许任意协议版本。默认允许任意版本。设置最高协议版本主要用于测试,或处理某些组件无法正常配合更新协议工作的问题。 - - 默认情况下,这个变量被设置成和from_collapse_limit相同, 这样适合大多数使用。把它设置为 1 可避免任何显式JOIN的重排序。因此查询中指定的显式连接顺序就是关系被连接的实际顺序。因为查询规划器并不是总能 选取最优的连接顺序,高级用户可以选择暂时把这个变量设置为 1,然后显式地指定他们想要的连接顺序。更多信息请见。 + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 + + + + ssl_dh_params_file (string) + + ssl_dh_params_file 配置参数 + + + - 将这个值设置为或更大,可能触发使用 GEQO 规划器,从而产生非最优计划。见。 + 指定包含 Diffie-Hellman 参数的文件名,这些参数用于所谓临时 DH 系列的 SSL 密码套件。默认值为空,此时使用编译时内置的默认 DH 参数。如果攻击者破解了众所周知的内置 DH 参数,使用自定义 DH 参数可以降低由此带来的风险。可以用命令 openssl dhparam -out dhparams.pem 2048 创建自己的 DH 参数文件。 + + + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 - - - + - plan_cache_mode (enum) + + ssl_passphrase_command (string) - plan_cache_mode 配置参数 + ssl_passphrase_command 配置参数 - - 准备语句(显式准备或隐式生成的,例如 PL/pgSQL)可以使用自定义或通用计划执行。 - 使用其特定的参数值集为每个执行重新生成自定义计划,而通用计划不依赖于参数值,并且可以在执行中重复使用。 - 因此,使用通用计划可以节省计划时间,但如果理想计划严重依赖参数值,则通用计划可能效率低下。 - 这些选项之间的选择通常是自动进行的,但可以通过plan_cache_mode覆盖它。 - 允许的值为 auto (默认的),force_custom_planforce_generic_plan。 - 这个设置是在执行缓存计划时考虑,而不是在准备计划时考虑。 - 更多信息请参阅 . + 设置获取用于解密私钥等 SSL 文件的口令时要调用的外部命令。默认值为空,表示使用内置的提示机制。 + + + 该命令必须将口令输出到标准输出,并以退出码 0 结束。参数值中的 %p 会被替换为提示字符串。(要表示字面值 %,应写成 %%。)提示字符串可能包含空白,因此务必正确加引号。如果输出末尾有一个换行符,会将其去掉。 + + + 该命令不一定要提示用户输入口令,也可以从文件读取口令、从钥匙链获取口令等。用户应自行确保所选机制足够安全。 + + + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 - - - + - recursive_worktable_factor (floating point) + + ssl_passphrase_command_supports_reload (boolean) - recursive_worktable_factor配置参数 + ssl_passphrase_command_supports_reload 配置参数 - - 设置规划器对递归查询 - 的工作表的平均大小的估计值,作为查询初始非递归项的估计大小的倍数。 - 这有助于规划器选择将工作表与查询的其他表连接的最合适方法。 - 默认值为10.0。当递归从一步到下一步的fan-out较低时,如最短路径查询中的示例,使用较小的值(如1.0)可能有所帮助。 - 图分析查询可能会从大于默认值的设置中受益。 + 此参数决定:配置重载期间,如果密钥文件需要口令,是否也调用 ssl_passphrase_command 设置的口令命令。如果此参数为 off(默认值),则重载时会忽略 ssl_passphrase_command,如果需要口令,就不会重载 SSL 配置。此设置适合需要通过 TTY 提示用户的命令,因为服务器运行期间可能无法使用 TTY。例如,如果从文件中获取口令,则适合将此参数设为 on。 - - - + + 在 Windows 上运行时,必须将此参数设为 on,因为该平台的进程模型不同,每个连接都会执行配置重载。 + + + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 + + + + - - - 错误报告和日志 - - - 服务器日志 - - - - - 在哪里做日志 + + 资源消耗 - - 日志写到哪里 - - - current_logfiles - 和日志_目的地配置参数 - - + + 内存 - + + + shared_buffers (integer) + + shared_buffers 配置参数 + + + + + 设置数据库服务器用于共享内存缓冲区的内存量。默认值通常为 128 兆字节(128MB),但如果内核设置不支持,则可能更小(在 initdb 期间确定)。此设置必须至少为 128 千字节。不过,要获得良好性能,通常需要远高于该最小值的设置。如果指定值时没有单位,则以块为单位,即 BLCKSZ 字节,通常为 8kB。(BLCKSZ 的非默认值会改变该最小值。)此参数只能在服务器启动时设置。 + + + 如果专用数据库服务器具有 1GB 或更多内存,shared_buffers 的合理初始值是系统内存的 25%。对于某些工作负载,将 shared_buffers 设得更大也有效,但由于 PostgreSQL 同时依赖操作系统缓存,将超过 40% 的内存分配给 shared_buffers 不太可能比更小的值效果更好。将 shared_buffers 设得更大时,通常还需要相应增加 max_wal_size,以便将大量新数据或已修改数据的写入过程分散到更长的时间内。 + + + 对于内存少于 1GB 的系统,适合使用更小的内存比例,以便为操作系统留出足够空间。 + + + - log_destination (string) + + huge_pages (enum) - log_destination配置参数 + huge_pages 配置参数 - PostgreSQL支持多种记录服务器消息的方法,包括 - stderrcsvlog, - jsonlog和 - syslog。在Windows上, - eventlog也受支持。将此参数设置为以逗号分隔的所需日志目的地列表。默认情况下仅记录到 - stderr。 - 此参数只能在postgresql.conf - 文件或服务器命令行中设置。 + 控制是否为主共享内存区域请求巨型页。有效值是try(默认)、on以及off。该参数只能在服务器启动时设置。如果huge_pages被设置为try,则服务器将尝试请求巨型页,但是如果失败会退回到默认的方式。如果为on,请求巨型页失败将使得服务器无法启动。如果为off,则不会请求巨型页。 - 如果csvlog被包括在log_destination中,日志项会以逗号分隔值CSV)格式被输出,这样可以很方便地把日志载入到程序中。详见。要产生 CSV 格式的日志输出,必须启用。 + 当前,只有Linux和Windows上支持这个设置。在其他系统上这个参数被设置为try时,它会被忽略。 + 在Linux中,它只在shared_memory_type设置为mmap(默认)的时候被支持。 - 如果jsonlog包含在log_destination中, - 日志条目将以JSON格式输出,这对将日志加载到程序中很方便。 - 有关详细信息,请参见。 - 必须启用才能生成JSON格式的日志输出。 + 巨型页的使用会导致更小的页表以及花费在内存管理上的 CPU 时间更少,从而提高性能。更多有关Linux上使用巨型页的细节请见 - 当包含stderrcsvlogjsonlog时, - 文件current_logfiles会被创建,记录日志收集器当前使用的日志文件位置和相关的日志目的地。 - 这提供了一种方便的方式来查找实例当前使用的日志。以下是该文件内容的示例: - -stderr log/postgresql.log -csvlog log/postgresql.csv -jsonlog log/postgresql.json - - - 当由于轮换而创建新的日志文件时,以及重新加载log_destination时,current_logfiles会被重新创建。 - 当log_destination中不包含stderrcsvlogjsonlog, - 以及日志收集器被禁用时,它会被移除。 + 巨型页在Windows上被称为大页面。 + 要使用大页面,需要为运行PostgreSQL的Windows用户账号分配在内存中锁定页面的用户权限。 + 可以使用Windows的组策略工具(gpedit.msc)来分配用户权限在内存中锁定页面。 + 为了在命令窗口以独立进程(而不是Windows服务)的方式启动数据库服务器,命令窗口必须以管理员身份运行或者禁用用户访问控制(UAC)。 + 当UAC被启用时,普通的命令窗口会在启动时收回用户权限在内存中锁定页面 - - - - 在大多数 Unix 系统上,你将需要修改系统的syslog守护进程的配置来使用log_destinationsyslog选项。PostgreSQL可以在syslog设备LOCAL0LOCAL7中记录(见),但是大部分平台上的默认syslog配置会丢弃所有这种消息。你将需要增加这样的内容: - -local0.* /var/log/postgresql - - 到syslog守护进程的配置文件来让它工作。 - - - - 在 Windows 上,当你使用log_destinationeventlog选项时,你应该在操作系统中注册一个事件源极其库,这样 Windows 事件查看器能够清楚地显示事件日志消息。详见。 - - + + 注意这种设置仅影响主共享内存区域。Linux、FreeBSD以及Illumos之类的操作系统也能为普通内存分配自动使用巨型页(也被称为超级页或者页面),而不需要来自PostgreSQL的显式请求。在Linux上,这被称为transparent huge pages透明巨型页(THP,透明巨型页)。已知这种特性对某些Linux版本上的某些用户会导致PostgreSQL的性能退化,因此当前并不鼓励使用它(与huge_pages的显式使用不同)。 + - - - + - logging_collector (boolean) + + huge_page_size (integer) - logging_collector配置参数 + huge_page_size 配置参数 - - 这个参数启用日志收集器,它是一个捕捉被发送到stderr的日志消息的后台进程,并且它会将这些消息重定向到日志文件中。这种方法比记录到syslog通常更有用,因为某些类型的消息不会在syslog输出中出现(一个常见的示例是动态链接器错误消息;另一个示例是由archive_command等脚本产生的错误消息)。这个参数只能在服务器启动时设置。 + 控制通过 启用巨型页时所使用的页大小。默认值为零(0)。设置为 0 时,使用系统默认的巨型页大小。此参数只能在服务器启动时设置。 + + 现代 64 位服务器体系结构上常见的页大小包括:2MB1GB(Intel 和 AMD),16MB16GB(IBM POWER),以及 64kB2MB32MB1GB(ARM)。关于使用和支持的更多信息,参见 。 + + + 目前只有 Linux 支持非默认设置。 + + + - - - - 也可以不使用日志收集器而把日志记录到stderr,日志消息将只会去到服务器的stderr被定向到的位置。不过,那种方法只适合于低日志量,因为它没有提供方法来轮转日志文件。还有,在某些不使用日志收集器的平台上可能会导致丢失或者混淆日志输出,因为多个进程并发写入同一个日志文件时会覆盖彼此的输出。 - - - - - - - 日志收集器被设计成从来不会丢失消息。这意味着在极高的负载下,如果服务器进程试图在收集器已经落后时发送更多的日志消息,那么它会被阻塞。相反,syslog倾向于在无法写入消息时丢掉消息,这意味着在这样的情况下它可能会无法记录某些消息,但是它不会阻塞系统的其他部分。 - - - - - - - - - log_directory (string) + + temp_buffers (integer) - log_directory配置参数 + temp_buffers 配置参数 - - 当logging_collector被启用时,这个参数决定日志文件将被在哪个目录下创建。它可以被指定为一个绝对路径,也可以被指定为一个相对于集簇数据目录的相对路径。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 - 默认是log。 + 设置每个数据库会话用于临时缓冲区的最大内存量。这些是会话本地的缓冲区,仅用于访问临时表。如果指定值时没有单位,则以块为单位,即 BLCKSZ 字节,通常为 8kB。默认值为 8 兆字节(8MB)。(如果 BLCKSZ 不是 8kB,则默认值按比例变化。)可以在单个会话内更改此设置,但必须在该会话首次使用临时表之前更改;此后尝试更改该值,对该会话不会产生影响。 + + + 会话会按需分配临时缓冲区,上限为 temp_buffers。对于实际不需要很多临时缓冲区的会话,将此参数设得较大时,开销仅为 temp_buffers 每增加一就多分配一个缓冲区描述符,约为 64 字节。不过,如果实际使用了某个缓冲区,还会为它额外消耗 8192 字节(一般而言为 BLCKSZ 字节)。 - - - + - log_filename (string) + + max_prepared_transactions (integer) - log_filename配置参数 + max_prepared_transactions 配置参数 - - 当logging_collector被启用时,这个参数设置被创建的日志文件的文件名。 - 该值被视为一种strftime模式,因此%转义可以被用来指定根据时间变化的文件名(注意如果有任何时区独立的%转义,计算将在由指定的时区中完成)。 - 被支持的%转义和开放组织的strftime说明中列举的类似。 - 注意系统的strftime不会被直接使用,因此平台相关(非标准)的扩展无法工作。 - 默认是postgresql-%Y-%m-%d_%H%M%S.log。 + 设置可同时处于预备状态的事务的最大数量(见 )。将此参数设为零(默认值)会禁用预备事务功能。此参数只能在服务器启动时设置。 - - 如果你不使用转义来指定一个文件名,你应该计划使用一个日志轮转工具来避免最终填满整个磁盘。在 8.4 发行之前,如果不存在%转义,PostgreSQL将追加新日志文件创建时间的纪元,但是现在已经不再这样做了。 + 如果不打算使用预备事务,应将此参数设为零,以防意外创建预备事务。如果使用预备事务,通常应将 max_prepared_transactions 设为不小于 的值,以便每个会话都能有一个待处理的预备事务。 - - 如果在log_destination中启用了 CSV 格式输出,.csv将会被追加到时间戳日志文件名中来创建 CSV 格式输出(如果log_filename.log结尾,该后缀会被替换)。 + 运行备库时,必须将此参数设为与主库相同或更大的值。否则,备库上将不允许执行查询。 + + + + work_mem (integer) + + work_mem 配置参数 + + + - 如果在log_destination中启用了JSON格式的输出, - 时间戳日志文件名将会在末尾添加.json, - 以创建JSON格式输出的文件名。 - (如果log_filename.log结尾, - 则会替换掉这个后缀。) + 设置查询操作(如排序或哈希表)在写入临时磁盘文件之前可使用的基础最大内存量。如果未指定单位,则以千字节为单位。默认值为 4 兆字节(4MB)。请注意,复杂查询可能同时执行多个排序和哈希操作,每个操作在开始向临时文件写入数据之前,通常都可以使用此值指定的内存量。此外,多个正在运行的会话也可能并发执行此类操作。因此,使用的总内存量可能是 work_mem 值的数倍;选择此值时必须考虑这一点。排序操作用于 ORDER BYDISTINCT 和归并连接。哈希表用于哈希连接、基于哈希的聚合、Memoize 节点以及基于哈希的 IN 子查询处理。 - - 这个参数只能在postgresql.conf文件中或通过服务器命令行进行设置。 + 与等效的排序操作相比,基于哈希的操作通常对可用内存更敏感。哈希表的内存上限由 work_mem 乘以 hash_mem_multiplier 计算得到。因此,基于哈希的操作可以使用超过通常的 work_mem 基础量的内存。 - - - + - log_file_mode (integer) + + hash_mem_multiplier (floating point) - log_file_mode配置参数 + hash_mem_multiplier 配置参数 - - 在 Unix 系统上,当logging_collector被启用时,这个参数设置日志文件的权限(在微软 Windows 上这个参数将被忽略)。这个参数值应当是一个数字形式的模式,它可以被chmodumask系统调用接受(要使用通常的十进制格式,该数字必须以一个0(零)开始)。 + 用于计算基于哈希的操作可以使用的最大内存量。最终上限由 work_mem 乘以 hash_mem_multiplier 确定。默认值为 2.0,使基于哈希的操作可以使用通常的 work_mem 基础量的两倍。 - - 默认的权限是0600,表示只有服务器拥有者才能读取或写入日志文件。其他常用的设置是0640,它允许拥有者的组成员读取文件。不过要注意你需要修改为将文件存储在集簇数据目录之外的某个位置,才能利用这个设置。在任何情况下,让日志文件变成任何人都可读是不明智的,因为日志文件中可能包含敏感数据。 + 如果查询操作经常溢写磁盘,可以考虑增加 hash_mem_multiplier,尤其是在单纯增加 work_mem 会导致内存压力的情况下(内存压力通常表现为间歇性的内存不足错误)。对于混合工作负载,默认值 2.0 通常有效。如果 work_mem 已增加到 40MB 或更高,则将该值进一步设为 2.0 - 8.0 或更高可能有效。 + + + + maintenance_work_mem (integer) + + maintenance_work_mem 配置参数 + + + - 这个参数只能在postgresql.conf文件中或通过服务器命令行进行设置。 + 指定维护操作(如 VACUUMCREATE INDEXALTER TABLE ADD FOREIGN KEY)可使用的最大内存量。如果未指定单位,则以千字节为单位。默认值为 64 兆字节(64MB)。由于一个数据库会话一次只能执行一个此类操作,而一个数据库系统通常也不会并发运行很多此类操作,因此可以安全地将该值设得远大于 work_mem。更大的设置可能改善清理和恢复数据库转储的性能。 + + + 注意,自动清理运行时,最多可能分配此内存量的 倍,因此不要将默认值设得过高。单独设置 可能有助于控制这一点。 + + + 注意,在收集死元组标识符时,VACUUM 最多只能使用 1GB 内存。 - - - + - log_rotation_age (integer) + + autovacuum_work_mem (integer) - log_rotation_age配置参数 + autovacuum_work_mem 配置参数 - - 当logging_collector被启用时,这个参数决定使用一个单个日志文件的最大时间量,之后将创立一个新的日志文件。 - 如果指定值时没有单位,则以分钟为单位。默认为24小时。 - 将这个参数设置为零将禁用基于时间的新日志文件创建。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 + 指定每个自动清理工作进程可使用的最大内存量。如果未指定单位,则以千字节为单位。默认值为 -1,表示改用 的值。该设置不影响其他上下文中运行的 VACUUM 的行为。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 + + + 在收集死元组标识符时,自动清理最多只能使用 1GB 内存,因此将 autovacuum_work_mem 设得更高,不会影响自动清理扫描表时能收集的死元组数量。 - - - + - log_rotation_size (integer) + + logical_decoding_work_mem (integer) - log_rotation_size配置参数 + logical_decoding_work_mem 配置参数 - - 当logging_collector被启用时,这个参数决定一个个体日志文件的最大尺寸。 - 当这些数据量被发送到一个日志文件后,将创建一个新的日志文件。 - 如果指定值的时候没有单位,则以千字节为单位。默认值是10兆字节。设置为零时将禁用基于大小创建新的日志文件。 - 这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 + 指定逻辑解码在将部分已解码的更改写入本地磁盘之前可使用的最大内存量。它限制了流式逻辑复制连接使用的内存量。默认值为 64 兆字节(64MB)。由于每个复制连接仅使用一个此大小的缓冲区,而一个数据库系统通常不会同时有很多此类连接(受 max_wal_senders 限制),因此可以安全地将该值设得远高于 work_mem,以减少写入磁盘的已解码更改数量。 - - - + - log_truncate_on_rotation (boolean) + + max_stack_depth (integer) - log_truncate_on_rotation配置参数 + max_stack_depth 配置参数 - 当logging_collector被启用时,这个参数将导致PostgreSQL截断(覆盖而不是追加)任何已有的同名日志文件。不过,截断只在一个新文件由于基于时间的轮转被打开时发生,在服务器启动或基于尺寸的轮转时不会发生。如果被关闭,在所有情况下以前存在的文件将被追加。例如,使用这个设置和一个类似postgresql-%H.loglog_filename将导致产生 24 个每小时的日志文件,并且循环地覆盖它们。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 + 指定服务器执行栈的最大安全深度。此参数的理想设置是由内核强制执行的实际栈大小限制 + (如由ulimit -s或本地等效设置),减去大约一兆字节的安全余量。 + 需要安全余量是因为服务器中并非每个例程都检查栈深度,而只在关键的潜在递归例程中检查。 + 如果未指定单位,则将其视为千字节。默认设置为两兆字节(2MB), + 这是保守且不太可能引起崩溃的小值。但是,这可能太小,无法执行复杂函数。 + 只有超级用户和具有适当SET权限的用户才能更改此设置。 - 示例:保留7天的日志,每天一个日志文件,命名为server_log.Monserver_log.Tue,等等,并自动用本周的日志覆盖上周的日志,将log_filename设置为server_log.%a,将log_truncate_on_rotation设置为on,将log_rotation_age设置为1440。 + 把max_stack_depth参数设置得高于实际的内核限制将意味着一个失控的递归函数可能会导致一个独立的后端进程崩溃。 在PostgreSQL能够检测内核限制的平台上, 服务器将不允许把这个参数设置为一个不安全的值。不过,并非所有平台都能提供该信息,所以我们还是建议你在选择值时要小心。 + + + + shared_memory_type (enum) + + shared_memory_type 配置参数 + + + - 示例:要保留 24 小时的日志,每个小时一个日志文件,但是在日志文件尺寸超过 1GB 时轮转。可以这样做:将log_filename设置为server_log.%H%M、 - 将log_truncate_on_rotation设置为on、 - 将log_rotation_age设置为60并且 - 将log_rotation_size设置为1000000。 - 在log_filename中包括%M允许发生任何尺寸驱动的轮转来选择一个不同于每个小时的初始文件名的新文件名。 + 指定服务器用于主共享内存区域的共享内存实现,该区域存放 PostgreSQL 的共享缓冲区及其他共享数据。可选值为 mmap(使用 mmap 分配的匿名共享内存)、sysv(通过 shmget 分配的 System V 共享内存)和 windows(Windows 共享内存)。并非所有平台都支持所有值;第一个受支持的选项是该平台的默认值。sysv 不是任何平台的默认选项,通常不建议使用,因为它一般需要更改内核的默认设置才能分配大量内存(见 )。此参数只能在服务器启动时设置。 - - - + - syslog_facility (enum) + + dynamic_shared_memory_type (enum) - syslog_facility配置参数 + dynamic_shared_memory_type 配置参数 - - 当启用了向syslog记录时,这个参数决定要使用的syslog设备。你可以在LOCAL0LOCAL1LOCAL2LOCAL3LOCAL4、 - LOCAL5LOCAL6LOCAL7中选择,默认值是LOCAL0。还请参阅系统的syslog守护进程的文档。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 + 指定服务器应使用的动态共享内存实现。可选值为 posix(使用 shm_open 分配的 POSIX 共享内存)、sysv(通过 shmget 分配的 System V 共享内存)、windows(Windows 共享内存)、mmap(使用存放在数据目录中的内存映射文件模拟共享内存)。并非所有平台都支持所有值;第一个受支持的选项通常是该平台的默认值。mmap 不是任何平台的默认选项,通常不建议使用,因为操作系统可能会反复将修改过的页面写回磁盘,增加系统 I/O 负载;不过,在调试、将 pg_dynshmem 目录存放在 RAM 磁盘上,或其他共享内存设施不可用时,它可能有用。此参数只能在服务器启动时设置。 - - - + - syslog_ident (string) + + min_dynamic_shared_memory (integer) - syslog_ident配置参数 + min_dynamic_shared_memory 配置参数 - - - - 当启用了向syslog记录时,这个参数决定用来标识syslog中的PostgreSQL消息的程序名。默认值是postgres。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 - - - - - - - syslog_sequence_numbers (boolean) - - syslog_sequence_numbers 配置参数 - - - - - - - 当日志被记录到syslog并且这个设置为 on (默认)时,每一个消息会被加上一个增长的序号作为前缀(例如[2])。这种行为避开了很多 syslog 实现默认采用的--- 上一个消息重复 N 次 ---形式。在现代 syslog 实现中,抑制重复消息是可以配置的(例如rsyslog中的$RepeatedMsgReduction),因此这个参数可能不是必需的。此外,如果你真的想抑制重复消息,你可以把这个参数设置为 off。 - - - - 这个参数只能在postgresql.conf文件或者服务器命令行上设置。 - + + + 指定服务器启动时为并行查询分配的内存量。当此内存区域不足或被并发查询耗尽时,新的并行查询会尝试使用 dynamic_shared_memory_type 配置的方法,临时向操作系统分配额外的共享内存;由于内存管理开销,这可能较慢。在支持 huge_pages 设置的操作系统上,启动时通过 min_dynamic_shared_memory 分配的内存会受到该设置的影响;在自动管理巨型页的操作系统上,这些内存也可能更容易受益于较大的页。默认值为 0(不分配)。此参数只能在服务器启动时设置。 + - + + + - + + 磁盘 - syslog_split_messages (boolean) + + + temp_file_limit (integer) - syslog_split_messages 配置参数 + temp_file_limit 配置参数 - - - 当启用把日志记录到syslog时,这个参数决定消息如何送达 syslog。当设置为 on(默认)时,消息会被分成行,并且长的行也会被划分以便能够放到 1024 字节中,这是传统 syslog 实现一种典型的尺寸限制。当设置为 off 时,PostgreSQL 服务器日志消息会被原样送达 syslog 服务,而处理可能的大体量消息的任务由 syslog 服务负责。 - - - 如果 syslog 最终被记录到一个文本文件中,那么两种设置的效果是一样的,但最好设置为 on,因为大部分 syslog 实现要么不能处理大型消息,要么需要做特殊的配置以处理大型消息。但是如果 syslog 最终写入到某种其他媒介,有必要让消息保持逻辑上的整体性(也更加有用)。 + 指定一个进程可用于临时文件的最大磁盘空间,例如排序和哈希临时文件,或保留游标的存储文件。尝试超过此限制的事务将被取消。如果未指定单位,则以千字节为单位。-1(默认值)表示没有限制。只有超级用户和具有适当 SET 权限的用户才能更改此设置。 - - 这个参数只能在postgresql.conf文件中或通过服务器命令行进行设置。 + 此设置限制单个 PostgreSQL 进程在任意时刻使用的所有临时文件的总空间。需要注意,显式临时表所用的磁盘空间计入该上限;计入的是查询执行过程中内部使用的临时文件。 - + + + - + + 内核资源使用 - event_source (string) + + + max_files_per_process (integer) - event_source配置参数 + max_files_per_process 配置参数 - - 当启用了向事件日志记录时,这个参数决定用来标识日志中PostgreSQL消息的程序名。默认值是PostgreSQL。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 + 设置每个服务器子进程允许同时打开的最大文件数量。默认值为一千个文件。如果内核强制实施了安全的每进程上限,就不必担心此设置。但在某些平台上(尤其是大多数 BSD 系统),内核允许单个进程打开的文件数量很大,如果很多进程都尝试打开这么多文件,就会远超系统实际能够支持的总量。如果遇到 Too many open files(打开的文件过多)错误,可尝试减小此设置。此参数只能在服务器启动时设置。 - + + + - - - - 什么时候记录日志 + + 基于代价的清理延迟 - + + 执行 命令期间,系统维护一个内部计数器,记录已执行的各种 I/O 操作的估算代价。 + 当累计代价达到上限(由 vacuum_cost_limit 指定)时,执行该操作的进程会休眠一小段时间,时长由 vacuum_cost_delay 指定。 + 随后重置计数器并继续执行。 + - + + 此功能让管理员能够降低这些命令对并发数据库活动的 I/O 影响。在许多情况下,VACUUMANALYZE 等维护命令是否快速完成并不重要, + 但避免它们显著干扰系统执行其他数据库操作的能力通常很重要。基于代价的清理延迟为管理员提供了实现这一点的方法。 + - log_min_messages (enum) - - log_min_messages配置参数 - - - + + 对于手动执行的 VACUUM 命令,此功能默认禁用。要启用它,将 vacuum_cost_delay 变量设为非零值。 + + + + vacuum_cost_delay (floating point) + + vacuum_cost_delay 配置参数 + + + - 控制将哪些消息级别写入服务器日志。 - 有效值为DEBUG5DEBUG4, - DEBUG3DEBUG2DEBUG1, - INFONOTICEWARNING, - ERRORLOGFATAL和 - PANIC。每个级别包括其后的所有级别。 - 级别越高,发送到日志的消息越少。默认值为WARNING。 - 请注意,在中,LOG的排名不同。 - 只有超级用户和具有适当SET权限的用户才能更改此设置。 + 超过代价上限后,进程将休眠的时长。如果未指定单位,则以毫秒为单位。默认值为 0,表示禁用基于代价的清理延迟功能。正值会启用基于代价的清理。 + + + 使用基于代价的清理时,vacuum_cost_delay 的合适值通常很小,可能不到 1 毫秒。虽然 vacuum_cost_delay 可以设为以毫秒为单位的小数值,但较旧的平台可能无法准确计量这种延迟。在这些平台上,若要让 VACUUM 的资源用量超过延迟设为 1ms 时的水平,需要调整其他清理代价参数。尽管如此,仍应将 vacuum_cost_delay 设为平台能够稳定计量的尽可能小的值;较大的延迟没有帮助。 - - - - - log_min_error_statement (enum) - - log_min_error_statement配置参数 - - - + + + vacuum_cost_page_hit (integer) + + vacuum_cost_page_hit 配置参数 + + + - 控制在服务器日志中记录哪些导致错误条件的SQL语句。当前的SQL语句将包含在任何指定 - severity - 或更高消息的日志条目中。 - 有效值为DEBUG5、 - DEBUG4DEBUG3、 - DEBUG2DEBUG1、 - INFONOTICE、 - WARNINGERROR、 - LOG、 - FATALPANIC。 - 默认值为ERROR,这意味着导致错误、日志消息、致命错误或紧急情况的语句将被记录。 - 要有效地关闭记录失败的语句, - 将此参数设置为PANIC。 - 只有超级用户和具有适当SET权限的用户才能更改此设置。 + 清理在共享缓冲区缓存中找到的缓冲区时所计入的估算代价。它表示锁定缓冲池、查找共享哈希表和扫描页内容的代价。默认值为 1。 - - - + - log_min_duration_statement (integer) - - log_min_duration_statement配置参数 - - + + vacuum_cost_page_miss (integer) + + vacuum_cost_page_miss 配置参数 + + + + 清理必须从磁盘读取的缓冲区时所计入的估算代价。它表示锁定缓冲池、查找共享哈希表、从磁盘读取所需数据块并扫描其内容所需的工作量。默认值为 2。 + + + - - 记录每个已完成语句的持续时间,如果语句运行时间至少达到指定时间。 - 例如,如果将其设置为250ms,那么所有运行时间为250ms或更长的SQL语句将被记录。 - 启用此参数可帮助跟踪应用程序中的未优化查询。 - 如果未指定单位,则将其视为毫秒。 - 将此值设置为零将打印所有语句持续时间。 - -1(默认值)禁用记录语句持续时间。 - 只有超级用户和具有适当SET权限的用户才能更改此设置。 - - - - 这会覆盖,意味着持续时间超过此设置的查询不进行抽样,并且始终被记录。 - + + vacuum_cost_page_dirty (integer) + + vacuum_cost_page_dirty 配置参数 + + + + + 清理操作修改原本干净的数据块时所计入的估算代价。它表示再次将脏块刷盘所需的额外 I/O。默认值为 20。 + + + - - 对于使用扩展查询协议的客户端,解析、绑定和执行步骤的持续时间将被独立记录。 - + + vacuum_cost_limit (integer) + + vacuum_cost_limit 配置参数 + + + + + 会使清理进程休眠的累计代价。默认值为 200。 + + + + - + + + 某些操作持有关键的锁,因此应尽快完成。这些操作期间不会发生基于代价的清理延迟,所以累计代价可能远超指定上限。 + 为避免此时出现无益的长时间延迟,实际延迟按 vacuum_cost_delay * accumulated_balance / vacuum_cost_limit 计算, + 但最大不超过 vacuum_cost_delay * 4。 + + + - - 当把这个选项和一起使用时,已经被log_statement记录的语句文本不会在持续时间日志消息中重复。如果你没有使用syslog,我们推荐你使用记录 PID 或会话 ID,这样你可以使用进程 ID 或会话 ID 把语句消息链接到后来的持续时间消息。 - - - - + + 后台写入器 - + + 有一个独立的服务器进程,称为后台写入器,负责写出(新的或修改过的)共享缓冲区。 + 当干净的共享缓冲区数量似乎不足时,后台写入器会将一些脏缓冲区写入文件系统,并将其标记为干净。 + 这可以降低处理用户查询的服务器进程找不到干净缓冲区、因而不得不自行写出脏缓冲区的可能性。 + 不过,后台写入器确实会使总体 I/O 负载有所增加:反复变脏的页面原本可能在每个检查点间隔中只写出一次, + 而后台写入器可能在同一间隔内随着它变脏而多次写出。本节参数可用于根据实际需求调整此行为。 + - log_min_duration_sample (integer) - - log_min_duration_sample 配置参数 - - + + + bgwriter_delay (integer) + + bgwriter_delay 配置参数 + + + + 指定后台写入器各轮活动之间的延迟。每一轮中,写入器会对一定数量的脏缓冲区发出写操作(由下面的参数控制),然后休眠 bgwriter_delay 指定的时长,再重复此过程。不过,当缓冲池中没有脏缓冲区时,它会进入更长的休眠,而不受 bgwriter_delay 限制。如果未指定单位,则以毫秒为单位。默认值为 200 毫秒(200ms)。注意,在许多系统上,休眠延迟的有效分辨率为 10 毫秒;将 bgwriter_delay 设为不是 10 的倍数的值,可能与将它设为下一个更大的 10 的倍数效果相同。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 + + + - - 允许对运行时间至少达到指定时间的已完成语句进行采样。这会产生与 - 相同类型的日志条目, - 但仅针对已执行语句的子集,采样率由控制。 - 例如,如果将其设置为100ms,那么运行时间达到100ms或更长的所有 - SQL语句都将被考虑进行采样。启用此参数在流量过高无法记录所有查询时很有帮助。 - 如果未指定单位,则将其视为毫秒。 - 将其设置为零会对所有语句持续时间进行采样。 - -1(默认值)禁用语句持续时间的采样。 - 只有超级用户和具有适当SET权限的用户才能更改此设置。 - - - - 此设置的优先级低于 log_min_duration_statement,意味着持续时间超过 log_min_duration_statement 的语句不被采样,并且始终被记录。 - - - - log_min_duration_statement的其他注释也适用于此设置。 - - - + + bgwriter_lru_maxpages (integer) + + bgwriter_lru_maxpages 配置参数 + + + + + 后台写入器每轮写出的缓冲区数量不会超过此值。设为零会禁用后台写入。(由另一个独立的专用辅助进程管理的检查点不受影响。)默认值为 100 个缓冲区。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 + + + - + + bgwriter_lru_multiplier (floating point) + + bgwriter_lru_multiplier 配置参数 + + + + + 每轮写出的脏缓冲区数量取决于最近几轮服务器进程所需的新缓冲区数量。将近期平均需求乘以 bgwriter_lru_multiplier,即可估算下一轮所需的缓冲区数量。写入器会写出脏缓冲区,直到可用的干净且可重用缓冲区达到这一数量。(不过,每轮写出的缓冲区数量不会超过 bgwriter_lru_maxpages。)因此,设为 1.0 表示采用恰好及时策略,写出的缓冲区数量恰好等于预测需求量。更大的值可为需求突增留出余量,而更小的值则有意将部分写操作留给服务器进程执行。默认值为 2.0。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 + + + - log_statement_sample_rate (floating point) - - log_statement_sample_rate 配置参数 - - + + bgwriter_flush_after (integer) + + bgwriter_flush_after 配置参数 + + + + 每当后台写入器写出的数据超过此数量时,就尝试强制操作系统将这些写操作发往底层存储。这样可以限制内核页缓存中的脏数据量,降低在检查点结束时调用 fsync,或操作系统在后台以较大批次写回数据时发生停顿的可能性。通常,这能大幅降低事务延迟,但在某些情况下性能可能下降,尤其是工作负载大于 而小于操作系统页缓存时。此设置在某些平台上可能没有效果。如果未指定单位,则以块为单位,即 BLCKSZ 字节,通常为 8kB。有效范围为 0(禁用强制写回)至 2MB。Linux 上的默认值为 512kB,其他平台为 0。(如果 BLCKSZ 不是 8kB,默认值和最大值将按比例变化。)此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 + + + + - - 确定持续时间超过的语句的比例将被记录。 - 采样是随机的,例如0.5表示统计上有一半的机会任何给定的语句将被记录。 - 默认值为1.0,表示记录所有采样的语句。 - 将此设置为零将禁用采样语句持续时间记录,与将log_min_duration_sample设置为-1相同。 - 只有超级用户和具有适当SET权限的用户才能更改此设置。 - - - + + 较小的 bgwriter_lru_maxpagesbgwriter_lru_multiplier 可以降低后台写入器造成的额外 I/O 负载, + 但也会增加服务器进程必须自行发出写操作的可能性,从而延迟交互式查询。 + + - + + 异步行为 - log_transaction_sample_rate (floating point) - - log_transaction_sample_rate 配置参数 - - + + + backend_flush_after (integer) + + backend_flush_after 配置参数 + + + + 每当单个后端写出的数据超过此数量时,就尝试强制操作系统将这些写操作发往底层存储。这样可以限制内核页缓存中的脏数据量,降低在检查点结束时调用 fsync,或操作系统在后台以较大批次写回数据时发生停顿的可能性。通常,这能大幅降低事务延迟,但在某些情况下性能可能下降,尤其是工作负载大于 而小于操作系统页缓存时。此设置在某些平台上可能没有效果。如果未指定单位,则以块为单位,即 BLCKSZ 字节,通常为 8kB。有效范围为 0(禁用强制写回)至 2MB。默认值为 0,即不强制写回。(如果 BLCKSZ 不是 8kB,最大值将按比例变化。) + + + - - 设置所有语句都被记录的事务的比例,除了其他原因记录的语句。它适用于每个新事务,无论其语句的持续时间如何。 - 采样是随机的,例如0.1表示任何给定事务被记录的统计概率是十分之一。 - log_transaction_sample_rate可以帮助构建事务样本。 - 默认值为0,表示不记录任何额外事务的语句。将其设置为1会记录所有事务的所有语句。 - 只有超级用户和具有适当SET权限的用户才能更改此设置。 - - - - - 就像所有的语句-日志选项一样,这个选项可能会增加大量开销。 - - - - + + effective_io_concurrency (integer) + + effective_io_concurrency 配置参数 + + + + + 设置 PostgreSQL 预期可以同时执行的并发磁盘 I/O 操作数量。提高此值会增加单个 PostgreSQL 会话尝试并行发起的 I/O 操作数量。允许的范围为 1 至 1000,或设为零以禁用异步 I/O 请求。目前,此设置仅影响位图堆扫描。 + + + 对于磁盘,可以将为数据库提供存储的 RAID 0 条带或 RAID 1 镜像中的独立磁盘数量作为合理初始值。(对于 RAID 5,不应计入校验盘。)不过,如果数据库经常忙于执行并发会话发出的多个查询,较小的值可能就足以使磁盘阵列保持繁忙。超过使磁盘保持繁忙所需的值只会增加 CPU 开销。SSD 和其他基于内存的存储通常可以处理大量并发请求,因此最佳值可能达到数百。 + + + 异步 I/O 依赖于有效的 posix_fadvise 函数,而某些操作系统缺少此函数。如果该函数不存在,将此参数设为任何非零值都会报错。在某些操作系统(如 Solaris)上,该函数虽然存在,却实际上不做任何事情。 + + + 支持此功能的系统上默认值为 1,其他系统为 0。对于位于特定表空间中的表,可以通过设置同名的表空间参数覆盖此值(见 )。 + + + - + + maintenance_io_concurrency (integer) + + maintenance_io_concurrency 配置参数 + + + + + 与 effective_io_concurrency 类似,但用于为多个客户端会话执行的维护工作。 + + + 支持此功能的系统上默认值为 10,其他系统为 0。对于位于特定表空间中的表,可以通过设置同名的表空间参数覆盖此值(见 )。 + + + - log_startup_progress_interval (integer) - - log_startup_progress_interval配置参数 - - + + max_worker_processes (integer) + + max_worker_processes 配置参数 + + + + 设置系统能够支持的后台进程的最大数量。此参数只能在服务器启动时设置。默认值为 8。 + + + 运行备库时,必须将此参数设为与主库相同或更大的值。否则,备库上将不允许执行查询。 + + + 更改此值时,也应考虑调整 、&zwsp;、&zwsp;。 + + + - - 设置启动进程在长时间运行的操作仍在进行时记录消息的时间间隔, - 以及该操作进一步进展消息之间的间隔时间。默认值为10秒。 - 设置为0会禁用该功能。如果未指定单位, - 则将其视为毫秒。此设置分别应用于每个操作。 - 此参数只能在postgresql.conf文件或服务器命令行中设置。 - + + max_parallel_workers_per_gather (integer) + + max_parallel_workers_per_gather 配置参数 + + + + + 设置单个 GatherGather Merge 节点能够启动的工作进程的最大数量。并行工作进程取自 建立的进程池,并受到 的限制。注意,运行时实际可用的工作进程可能不足请求的数量。此时,计划会使用少于预期的工作进程运行,效率可能较低。默认值为 2。设为 0 会禁用并行查询执行。 + + + 注意,并行查询消耗的资源可能远多于非并行查询,因为每个工作进程都是完全独立的进程,对系统的影响大致相当于额外增加一个用户会话。选择此设置的值,以及配置其他控制资源使用的设置(如 )时,都应考虑这一点。work_mem 等资源限制分别应用于每个工作进程,因此所有进程的总资源用量可能远高于单个进程通常的用量。例如,使用 4 个工作进程的并行查询,其 CPU 时间、内存、I/O 带宽等用量可能达到完全不使用工作进程的查询的 5 倍。 + + + 并行查询的更多信息参见 。 + + + - - 例如,如果同步数据目录需要25秒,然后重置不记录 WAL 的关系需要8秒,如果此设置的默认值为10秒, - 那么在数据目录同步进行了10秒后,将记录一条消息,再在进行了20秒后记录一条消息, - 但对于重置不记录 WAL 的关系不会记录任何消息。 - - - - - - - - 解释了PostgreSQL所使用的消息严重级别。如果日志输出被发送到syslog或 Windows 的eventlog,严重级别会按照表中所示进行转换。 - - - - - 消息严重级别 - - - - - - - - - 严重性 - 用法 - syslog - eventlog - - - - + + max_parallel_maintenance_workers (integer) + + max_parallel_maintenance_workers 配置参数 + + + + + 设置单个工具命令能够启动的并行工作进程的最大数量。目前,支持使用并行工作进程的工具命令包括:构建 B-树索引时的 CREATE INDEX,以及不带 FULL 选项的 VACUUM。并行工作进程取自 建立的进程池,并受到 的限制。注意,运行时实际可用的工作进程可能不足请求的数量。此时,工具操作会使用少于预期的工作进程运行。默认值为 2。设为 0 会禁止工具命令使用并行工作进程。 + + + 注意,并行工具命令的内存消耗不应明显高于等效的非并行操作。这与并行查询的策略不同,后者的资源限制通常分别应用于每个工作进程。并行工具命令将 maintenance_work_mem 视为整个工具命令的资源上限,而不论使用多少个并行工作进程。不过,并行工具命令仍可能消耗多得多的 CPU 资源和 I/O 带宽。 + + + - - DEBUG1 .. DEBUG5 - 为开发者提供连续的更详细的信息。 - DEBUG - INFORMATION - + + max_parallel_workers (integer) + + max_parallel_workers 配置参数 + + + + + 设置系统能够为并行操作提供的工作进程的最大数量。默认值为 8。增大或减小此值时,也应考虑调整 。此外,将此值设得大于 没有效果,因为并行工作进程取自该设置建立的工作进程池。 + + + - - INFO - 提供用户隐式要求的信息,例如来自VACUUM VERBOSE的输出。 - INFO - INFORMATION - - - NOTICE - 提供可能对用户有用的信息,例如长标识符截断提示。 - NOTICE - INFORMATION - - - WARNING - 提供可能出现的问题的警告,例如在一个事务块外COMMIT - NOTICE - WARNING - - - ERROR - 报告一个导致当前命令中断的错误。 - WARNING - ERROR - + + + parallel_leader_participation (boolean) + + parallel_leader_participation 配置参数 + + + + + 允许领导者进程执行 GatherGather Merge 节点下的查询计划,而不是等待工作进程。默认值为 on。将此值设置为 off,可以降低工作进程因领导者读取元组不够快而被阻塞的可能性,但在产生第一批元组之前,领导者进程必须等待工作进程启动。领导者对性能的帮助或妨碍程度取决于计划类型、工作进程数量和查询持续时间。 + + + - - LOG - 报告管理员可能感兴趣的信息,例如检查点活动。 - INFO - INFORMATION - + + old_snapshot_threshold (integer) + + old_snapshot_threshold 配置参数 + + + + + 设置查询快照在使用时不发生snapshot too old错误的最短可用时间。 + 已死亡超过该阈值的数据允许被清理掉。这有助于在快照长期保持使用时防止膨胀。 + 为了避免因清理本应对该快照可见的数据而得到错误结果,当快照年龄超过该阈值, + 并且该快照被用于读取某个自其建立以来已被修改过的页面时,就会报错。 + - - FATAL - 报告一个导致当前会话中断的错误。 - ERR - ERROR - + + 如果指定值时没有单位,则以分钟为单位。值为 -1 + (默认值)会禁用此特性,相当于把快照年龄上限设为无穷大。 + 该参数只能在服务器启动时设置。 + - - PANIC - 报告一个导致所有数据库会话中断的错误。 - CRIT - ERROR - - - -
+ + 对生产环境而言,有用的取值大概从几个小时到几天不等。较小的值 + (例如 01min)之所以被允许, + 只是因为它们有时可用于测试。虽然允许设置到 60d 这么高, + 但请注意,在许多工作负载中,严重膨胀或事务 ID 回卷可能会在更短时间内发生。 + -
- + + 启用此特性后,关系末尾释放出来的空间将不能返还给操作系统,因为那样可能会移除 + 检测snapshot too old条件所需的信息。分配给某个关系的全部空间都会一直 + 归属于该关系,只能在该关系内部重用,除非显式释放(例如使用 + VACUUM FULL)。 + - 记录什么到日志 + + 该设置并不尝试保证在任何特定情况下都一定会产生错误。实际上,如果仍能从 + 某个对象(例如已经物化结果集的游标)生成正确结果,那么即使被引用表中的底层行 + 已经被清理掉,也不会报错。有些表不能安全地提前清理,因此不会受此设置影响, + 例如系统目录。对这类表来说,此设置既不会减少膨胀,也不会在扫描时引入 + snapshot too old错误的可能性。 + + + + + +
- + + 预写式日志 - - 你选择记录的内容可能会影响安全性;请参见。 - - + + 参阅获取调节这些设置的额外信息。 + - + + 设置 - + + - application_name (string) + wal_level (enum) - application_name配置参数 + wal_level配置参数 - application_name可以是任意小于NAMEDATALEN个字符(标准编译中是 64 个字符)的字符串。这通常由一个应用通过到服务器的连接设置。该名称将被显示在pg_stat_activity视图中并被包括在 CSV 日志项中。它也会被通过包括在普通日志项中。只有可打印 ASCII 字符能被使用在application_name之中。其他字符将被替换为问号(?)。 + wal_level决定多少信息写入到 WAL 中。默认值是replica,它会写入足够的数据以支持WAL归档和复制,包括在备库上运行只读查询。minimal会去掉除从崩溃或者立即关机中进行恢复所需的信息之外的所有记录。最后,logical会增加支持逻辑解码所需的信息。每个层次包括所有更低层次记录的信息。这个参数只能在服务器启动时设置。 - - - - - - debug_print_parse (boolean) - - debug_print_parse配置参数 - - - debug_print_rewritten (boolean) - - debug_print_rewritten配置参数 - - + + minimal级别生成最少的WAL日志量。对于在当前事务中创建或重写的永久关系,不记录其行信息。 + 这可以使操作速度更快(参见)。触发此优化的操作包括: + + ALTER ... SET TABLESPACE + CLUSTER + CREATE TABLE + REFRESH MATERIALIZED VIEW + (不使用 + REINDEX + TRUNCATE + + 然而,minimal 级别的 WAL 不包含足够的信息用于时间点恢复,因此必须使用replica或更高级别来启用持续归档 + ()和流式二进制复制。 + 实际上,如果max_wal_senders不为零,服务器甚至不会以此模式启动。 + 请注意,将wal_level更改为minimal会使先前的基础备份无法用于时间点恢复和备库。 + - debug_print_plan (boolean) - - debug_print_plan配置参数 - - - + + 在logical级别上,记录与replica相同的信息,以及从WAL中提取逻辑变更集所需的信息。 + 使用logical级别会增加 WAL 的数量,特别是如果许多表被配置为REPLICA IDENTITY FULL, + 并且执行了许多UPDATEDELETE语句。 + - 这个参数启用发出各种调试输出。当设置时,会打印生成的解析树, 查询重写输出,或执行的每个查询的执行计划。这些信息是在LOG 信息级别发出,因此默认的,它们会出现在服务器日志中,但不会发送给客户端。 可以通过 client_min_messages和/或log_min_messages 来设置。这些参数缺省是off。 - 这些参数将会让多种调试输出被发出。当被设置时,它们为每一个被执行的查询打印结果分析树、查询重写器输出或执行计划。这些消息在LOG消息级别上被发出,因此默认情况下它们将出现在服务器日志中但不会被发送到客户端。你可以通过调整和/或来改变这种情况。这些参数默认是关闭的。 + 在 9.6 之前的版本中,这个参数也允许值archivehot_standby。现在仍然接受这些值,但是它们会被映射到replica - + - debug_pretty_print (boolean) + fsync (boolean) - debug_pretty_print配置参数 + fsync配置参数 - 当被设置时,debug_pretty_print会缩进由debug_print_parse、 - debug_print_rewritten或 - debug_print_plan产生的输出。这将导致比关闭参数时使用的紧凑模式可读性更强但是更长的输出。它默认是打开的。 + 如果打开这个参数,PostgreSQL服务器将尝试确保更新被物理地写入到磁盘,做法是发出fsync()系统调用或者使用多种等价的方法(见)。这保证了数据库集簇在一次操作系统或者硬件崩溃后能恢复到一个一致的状态。 - - - + + 虽然关闭fsync常常可以得到性能上的收益,但当发生断电或系统崩溃时可能造成不可恢复的数据损坏。因此,只有在能很容易地从外部数据中重建整个数据库时才建议关闭fsync。 + - log_autovacuum_min_duration (integer) - - log_autovacuum_min_duration - 配置参数 - - - + + 可以安全关闭fsync的情形包括:从备份文件初始装载一个新数据库集簇;用数据库集簇处理一批数据,处理后就丢弃并重建该数据库;或者使用经常重建且不用于故障切换的只读数据库克隆。仅有高质量硬件不足以成为关闭fsync的理由。 + - 每次由自动清理执行的操作都会被记录,如果运行时间至少达到指定时间。将此设置为零会记录所有自动清理操作。 - -1会禁用记录自动清理操作。如果未指定单位,则将其视为毫秒。 - 例如,如果将其设置为250ms,则所有运行时间为250ms或更长的自动清理和分析都将被记录。 - 此外,当此参数设置为任何值而不是-1时,如果由于冲突的锁定或同时删除的关系而跳过自动清理操作,则会记录消息。 - 默认值为10min。启用此参数可帮助跟踪自动清理活动。 - 此参数只能在postgresql.conf文件或服务器命令行中设置;但可以通过更改表存储参数来覆盖对单个表的设置。 + 为确保将fsync从关闭改为打开后能够可靠恢复,必须将内核中所有已修改的缓冲区强制写入持久存储。可以在集簇已关闭或fsync已开启时,通过运行initdb --sync-only、运行sync、卸载文件系统或重启服务器来完成。 + + + + 在很多情况下,为非关键事务关闭,可以获得关闭fsync所带来的大部分潜在性能收益,同时避免伴随的数据损坏风险。 + + + + fsync只能在postgresql.conf文件中或在服务器命令行上设置。如果你关闭这个参数,请也考虑关闭 - + - log_checkpoints (boolean) + synchronous_commit (enum) - log_checkpoints配置参数 + synchronous_commit配置参数 - 导致检查点和重启点在服务器日志中记录。日志消息中包括一些统计信息, - 包括写入的缓冲区数量和写入它们所花费的时间。此参数只能在 - postgresql.conf文件或服务器命令行中设置。默认值为开启。 + 指定数据库服务器向客户端返回成功指示之前,必须完成多少 WAL 处理。有效值为remote_applyon(默认值)、remote_writelocaloff - - - + + 如果synchronous_standby_names为空,只有onoff两种设置有意义;remote_applyremote_writelocal提供的本地同步级别都与on相同。所有非off模式在本地都会等待 WAL 刷写到磁盘。在off模式下则无需等待,因此,向客户端报告成功后,可能还要经过一段时间,才能保证事务不会因服务器崩溃而丢失。(最大延迟为的三倍。)与不同,将此参数设为off不会带来数据库不一致的风险:操作系统或数据库崩溃可能会使一些最近报告已提交的事务丢失,但数据库状态会与这些事务已正常中止时完全相同。因此,当性能比完全确保事务持久性更重要时,关闭synchronous_commit可以是一种有用的替代方案。更多讨论见。 + - log_connections (string) - - log_connections配置参数 - - - + + 如果非空,synchronous_commit还控制事务提交是否等待备库处理其 WAL 记录。 + - 控制是否记录服务器每次连接的各个阶段。默认值为空字符串 - '',表示禁用所有连接日志。下列选项既可以单独指定, - 也可以用逗号分隔的列表指定: + 设为remote_apply时,提交会等待当前同步备库回复,确认已收到并应用该事务的提交记录,使其对备库上的查询可见,并且已将其写入备库的持久存储。由于需要等待 WAL 重放,这会比之前的设置产生大得多的提交延迟。设为on时,提交会等待当前同步备库回复,确认已收到事务的提交记录,并已将其刷写到持久存储。这能保证事务不会丢失,除非主库和所有同步备库的数据库存储都损坏。设为remote_write时,提交会等待当前同步备库回复,确认已收到事务的提交记录,并已将其写入各自的文件系统。此设置能保证备库上的PostgreSQL实例崩溃时数据不丢失,但不能保证备库发生操作系统级别崩溃时数据不丢失,因为数据未必已写入备库的持久存储。设为local时,提交会等待本地刷盘,但不等待复制。使用同步复制时通常不希望采用这种设置,提供它是为了使选项完整。 - - 连接日志选项 - - - + + 此参数可以随时更改;每个事务的行为由提交时生效的设置决定。因此,让一些事务同步提交、另一些事务异步提交是可行且有用的。例如,当默认设置要求同步提交时,可以在一个包含多条语句的事务中执行SET LOCAL synchronous_commit TO OFF,使该事务异步提交。 + + + + 汇总了synchronous_commit各种设置具备的能力。 + + +
+ + synchronous_commit 模式 + + + + + + + - 名称 - 说明 + synchronous_commit 设置 + 本地提交持久性 + PG 崩溃后备库提交持久性 + OS 崩溃后备库提交持久性 + 备库查询一致性 + + - receipt - 记录收到连接。 + remote_apply + + + + + - authentication - 记录认证方法用于识别用户的原始身份。在大多数情况下,该身份字符串与PostgreSQL用户名一致,但某些第三方认证方法可能会在服务器存储之前修改原始用户标识符。无论此设置为何值,认证失败始终都会被记录。 + on + + + + + - authorization - 记录授权成功完成。此时连接已经建立,但后端尚未完全初始化。日志消息会包含授权后的用户名,以及数据库名和应用名(如果适用)。 + remote_write + + + + + - setup_durations - 记录从 postmaster 接受传入连接开始,到连接准备好执行第一条查询为止,建立连接并完成后端初始化所花费的时间。日志消息会包含三个时长:总设置时长、fork 新后端所花费的时间,以及用户认证所花费的时间。 + local + + + + + - all - 一个便捷别名,相当于指定所有选项。如果在其他选项列表中包含all,则会记录连接的所有方面。 + off + + + + +
- - 断开连接的日志由单独控制。 - +
+
- - 出于向后兼容性考虑,onoff、 - truefalseyes、 - no10仍然受支持。 - 正向值等价于指定receiptauthentication和 - authorization选项。 - + + + wal_sync_method (enum) + + wal_sync_method配置参数 + + + - 只有超级用户和具有适当SET权限的用户可以在会话开始时更改此参数, - 并且在会话内部完全不能更改。 + 用于将 WAL 更新强制写入磁盘的方法。如果fsync关闭,此设置就没有作用,因为 WAL 文件更新根本不会被强制写入磁盘。可选值为: - - + + - 某些客户端程序(例如psql)在要求密码时会尝试连接两次,因此重复的收到连接消息并不一定表示一个错误。 + open_datasync(用open()选项O_DSYNC写 WAL 文件) - + + + + + fdatasync(在每次提交时调用fdatasync()) + + + + + + fsync(在每次提交时调用fsync()) + + + + + + fsync_writethrough(在每次提交时调用fsync(),强制穿透任何磁盘写缓存) + + + + + + open_sync(用open()选项O_SYNC写 WAL 文件) + + + + + + open_* 选项还会使用O_DIRECT(如果可用)。 + 不是在所有平台上都能使用所有这些选择。 + 默认值是列表中第一个被平台支持的那个, 不过fdatasync是 Linux 和 FreeBSD 中的默认值。 + 默认值不一定最合适;可能需要更改此设置或系统配置的其他方面,以确保崩溃时的数据安全或达到最佳性能。 + 这些方面在中讨论。 + 这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 + - + - log_disconnections (boolean) + full_page_writes (boolean) - log_disconnections配置参数 + full_page_writes配置参数 - 导致会话终止被记录。日志输出提供类似于log_connections的信息,以及会话的持续时间。 - 只有超级用户和具有适当SET权限的用户可以在会话开始时更改此参数,而且在会话中根本无法更改。 - 默认值为off。 + 启用此参数时,PostgreSQL服务器会在检查点之后首次修改每个磁盘页面时,将该页面的全部内容写入 WAL。这样做是因为,操作系统崩溃时正在进行的页面写入可能只完成了一部分,导致磁盘页面混有新旧数据。通常存储在 WAL 中的行级变更数据不足以在崩溃恢复时完整还原这样的页面。保存整页镜像能保证正确恢复页面,但会增加必须写入 WAL 的数据量。(由于 WAL 重放总是从检查点开始,只需在检查点之后首次修改每个页面时这样做。因此,减少整页写入开销的一种方法是增大检查点间隔参数。) + + + + 关闭此参数可以加快正常操作,但系统故障后可能出现不可恢复的数据损坏或静默数据损坏。风险与关闭fsync类似,虽然较小,但也只有在该参数建议的相同情形下才应关闭此参数。 + + + + 关闭这个选项并不影响用于时间点恢复(PITR)的 WAL 归档使用(见)。 + + + + 这个参数只能在postgresql.conf文件中或在服务器命令行上设置。默认值是on - + - log_duration (boolean) + wal_log_hints (boolean) - log_duration配置参数 + wal_log_hints配置参数 - 记录每个已完成语句的持续时间。 - 默认值为off。 - 只有超级用户和具有适当SET权限的用户才能更改此设置。 + 当这个参数为on时,PostgreSQL服务器在检查点之后首次修改页面时把该磁盘页面的整个内容都写入 WAL,即使对所谓的提示位做非关键修改也会这样做。 - 对于使用扩展查询协议的客户端,解析、绑定和执行步骤的持续时间将被独立记录。 + 如果启用了数据校验和,提示位更新总是会被 WAL 记录并且这个设置会被忽略。你可以使用这个 + 设置测试如果你的数据库启用了数据校验和,会有多少额外的 WAL 记录发生。 - - - - 启用log_duration和设置为零之间的区别是,超过log_min_duration_statement强制查询的文本被记录,但这个选项不会。因此,如果log_durationon并且log_min_duration_statement为正值,所有持续时间都将被记录,但是只有超过阈值的语句才会被记录查询文本。这种行为有助于在高负载安装中收集统计信息。 - - + + 这个参数只能在服务器启动时设置。默认值是off。 + - + - log_error_verbosity (enum) + wal_compression (enum) - log_error_verbosity配置参数 + wal_compression配置参数 - 控制在服务器日志中记录的每条消息的详细程度。有效值为TERSE, - DEFAULTVERBOSE,每个值都会添加更多字段到显示的消息中。 - TERSE不包括DETAILHINT, - QUERYCONTEXT错误信息的记录。 - VERBOSE输出包括SQLSTATE错误代码 - (另请参见)以及生成错误的源代码文件名、函数名和行号。 + 此参数启用使用指定的压缩方法对WAL进行压缩。 + 启用后,PostgreSQL服务器会压缩写入 WAL 的整页镜像,例如 + 在启用时、基础备份期间等。 + 在WAL重放期间,将对压缩的页镜像进行解压缩。 + 支持的方法有pglz、 + lz4(如果PostgreSQL + 使用编译)和 + zstd(如果PostgreSQL + 使用编译)。 + 值 onpglz 的历史拼写。 + 默认值为off。 只有超级用户和具有适当SET权限的用户才能更改此设置。 + + + 启用压缩可以减少 WAL 数据量,而且不会增加不可恢复的数据损坏风险;代价是在记录 WAL 时压缩、重放 WAL 时解压会额外消耗一些 CPU。 + - + - log_hostname (boolean) + wal_init_zero (boolean) - log_hostname配置参数 + wal_init_zero 配置参数 - 默认情况下,连接日志消息只显示连接主机的 IP 地址。打开这个参数将导致也记录主机名。注意根据你的主机名解析设置,这可能会导致很微小的性能损失。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 + 如果设置为on(默认值),此选项会导致新的 WAL 文件被零填充。 + 在某些文件系统上,这可确保在我们需要写入 WAL 记录之前分配空间。 + 但是,写时复制(COW)文件系统可能不会从此技术中受益,因此可以选择跳过不必要的工作。 + 如果设置为off,则在创建文件时只写入最后一个字节,以便其具有预期大小。 - + - log_line_prefix (string) + wal_recycle (boolean) - log_line_prefix配置参数 + wal_recycle 配置参数 - 这是一个printf风格的字符串,它在每个日志行的开头输出。 - %字符开始转义序列,它将被按照下文描述的替换成状态信息。 - 未识别的转义被忽略。其他字符被直接复制到日志行。某些转义只被会话进程识别并且被主服务器进程等后台进程当作空。 - 通过指定一个在%之后和该选项之前的数字可以让状态信息左对齐或右对齐。 - 负值将导致在右边用空格填充状态信息已达到最小宽度,而正值则在左边填充。填充对于日志文件的人类可读性大有帮助。 + 如果设置为 on (默认值),此选项通过重命名来回收 WAL 文件,从而避免创建新文件。 + 在 COW 文件系统上,创建新文件可能更快,因此提供了禁用此行为的选项。 + + + + + + wal_buffers (integer) + + wal_buffers配置参数 + + + - 这个参数只能在postgresql.conf文件中或在服务器命令行上设置。默认值是'%m [%p] ',它记录时间戳和进程ID。 + 用于还未写入磁盘的 WAL 数据的共享内存量。默认值 -1 选择等于的 1/32 的尺寸(大约3%),但是不小于64kB也不大于 WAL 段的尺寸(通常为16MB)。如果自动的选择太大或太小可以手工设置该值,但是任何小于32kB的正值都将被当作32kB。 + 如果指定值时没有单位,则以WAL块作为单位,即为 XLOG_BLCKSZ 字节,通常为8kB。这个参数只能在服务器启动时设置。 - - - + + 在每次事务提交时,WAL 缓冲区的内容被写出到磁盘,因此极大的值不太可能带来显著收益。不过,把这个值设置为至少几个兆字节可以在一个繁忙的服务器(其中很多客户端会在同一时间提交)上提高写性能。由默认设置 -1 选择的自动调节将在大部分情况下得到合理的结果。 + - - 转义 - 效果 - 只限会话 - - - + + - - %a - 应用名 - - + - - %u - 用户名 - - + wal_writer_delay (integer) + + wal_writer_delay配置参数 + + + - - %d - 数据库名 - - + + 指定 WAL 写入器刷写 WAL 的频繁程度,以时间为单位。 + 在刷写WAL之后,写入器将根据wal_writer_delay所给出的时间长度进行睡眠,除非被一个异步提交的事务提前唤醒。 + 如果距上次刷盘的时间小于wal_writer_delay,并且自那以后产生的 WAL 数据量小于wal_writer_flush_after,则只将 WAL 写入操作系统,而不刷写到磁盘。 + 如果指定值时没有单位,则以毫秒作为单位。 + 默认值是 200 毫秒(200ms)。注意在很多系统上,有效的睡眠延迟粒度是 10 毫秒,把wal_writer_delay设置为一个不是 10 的倍数的值,其效果可能与将其设置为下一个更大的 10 的倍数相同。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 + + + - - %r - 远程主机名或 IP 地址,以及远程端口 - - + - - %h - 远程主机名或 IP 地址 - - + wal_writer_flush_after (integer) + + wal_writer_flush_after 配置参数 + + + - - %b - 后端类型 - - + + 指定 WAL 写入器刷写 WAL 的频繁程度,按数据量衡量。 + 如果距上次刷盘的时间小于wal_writer_delay,并且自那以后产生的 WAL 数据量小于wal_writer_flush_after,则只将 WAL 写入操作系统,而不刷写到磁盘。 + 如果wal_writer_flush_after被设置为0,则WAL数据总是会被立即刷写。 + 如果指定值时没有单位,则以WAL块作为单位,即为XLOG_BLCKSZ字节,通常为8kB。 + 默认是1MB。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 + + + - - %p - 进程 ID - - + - - %P - 并行组leader的进程ID,如果该进程是一个并行查询worker - no - + wal_skip_threshold (integer) + + wal_skip_threshold 配置参数 + + + - - %t - 无毫秒的时间戳 - - + + 当wal_levelminimal,且事务在创建或重写永久关系后提交时,此设置决定如何持久保存新数据。如果数据量小于此设置,就将其写入 WAL;否则,对受影响的文件执行 fsync。如果这类提交拖慢了并发事务,根据存储的特性,增大或减小此值可能有所帮助。未指定单位时以千字节为单位。默认值为两兆字节(2MB)。 + + + - - %m - 带毫秒的时间戳 - - + - - %n - 带毫秒的时间戳(作为 Unix 时代) - no - + commit_delay (integer) + + commit_delay配置参数 + + + - - %i - 命令标签:会话当前命令的类型 - - + + 设置commit_delay会在发起 WAL 刷盘之前添加时间延迟。 + 如果系统负载足够高,使得在给定时间间隔内有更多事务准备提交, + 这可以通过允许更多事务通过一次 WAL 刷盘来提高组提交吞吐量。 + 不过,每次 WAL 刷盘的延迟也会因此增加,最多增加commit_delay。 + 如果没有其他事务准备提交,等待就没有意义,因此仅当即将发起刷盘时至少还有 + commit_siblings个其他活动事务,才会等待。 + 此外,如果禁用了fsync,也不会等待。 + 如果未指定单位,则将其视为微秒。 + 默认commit_delay为零(无延迟)。 + 只有超级用户和具有适当SET权限的用户才能更改此设置。 + - - %e - SQLSTATE 错误代码 - - + + 在PostgreSQL的 9.3 发布之前,commit_delay的行为不同并且效果更差:它只影响提交,而不是所有 WAL 刷写,并且即使 WAL 刷盘更早完成,也会等待整个配置的延迟时间。从PostgreSQL 9.3 开始,第一个准备好刷写的进程会等待配置的间隔,而后续的进程只等到领先者完成刷写操作。 + + + - - %c - 会话 ID:见下文 - - + - - %l - 对每个会话或进程的日志行号,从 1 开始 - - + commit_siblings (integer) + + commit_siblings配置参数 + + + - - %s - 进程开始的时间戳 - - + + 执行commit_delay延迟前要求的并发活动事务的最小数目。大一些的值会导致在延迟间隔期间更可能有至少另外一个事务准备好提交。默认值是五个事务。 + + + +
+
+ + 检查点 - - %v - 虚拟事务 ID (backendID/localXID) - - - - - %x - 事务 ID (如果未分配则为 0) - - - - - %q - 不产生输出,但是告诉非会话进程在字符串的这一点停止;会话进程忽略 - - - - - %Q - 当前查询的查询标识符。 - 查询标识符默认是不计算的,所以这个部分将是零,除非 参数被激活或者配置了计算查询标识符的第三方模块 - yes - - - - %% - 纯文字 % - - - - - - - - 后端类型对应视图 pg_stat_activity中的backend_type列。 - 但是其他类型可能会出现在日志中而不显示在该视图中。 - - - - %c转义打印一个准唯一的会话标识符,它由两个 4 字节的十六进制数(不带先导零)组成,以点号分隔。 - 这些数字是进程启动时间和进程 ID,因此%c也可以被用作保存打印这些项的方式的空间。 - 例如,要从pg_stat_activity生成会话标识符,使用这个查询: - -SELECT to_hex(trunc(EXTRACT(EPOCH FROM backend_start))::integer) || '.' || - to_hex(pid) -FROM pg_stat_activity; - + + + checkpoint_timeout (integer) + + checkpoint_timeout配置参数 + + + + + 自动 WAL 检查点之间的最长时间。如果指定值时没有单位,则以秒为单位。 + 合理的范围在 30 秒到 1 天之间。默认是 5 分钟(5min)。增加这个参数的值可能会增加崩溃恢复所需的时间。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 + + + + + checkpoint_completion_target (floating point) + + checkpoint_completion_target配置参数 + + + + + 指定检查点完成所用时间的目标值,以检查点之间总时间的比例表示。 + 默认值为 0.9,这会把检查点工作分散到几乎整个可用间隔内,使 I/O 负载较为平稳, + 同时为检查点完成时的额外工作留出一些时间。不建议减小此参数,因为这样会让检查点更快完成, + 导致检查点期间的 I/O 速率更高,而在检查点完成后到下一个计划检查点开始前的一段时间内 I/O 较少。 + 此参数只能在postgresql.conf文件中或服务器命令行上设置。 - - - - - 如果你为log_line_prefix设置了非空值,你通常应该让它的最后一个字符为空格,这样用以提供和日志行的剩余部分的视觉区别。也可以使用标点符号。 - - - - - - - Syslog产生自己的时间戳和进程 ID 信息,因此如果你记录到syslog你可能不希望包括哪些转义。 - - - - - - - 在包括仅在会话(后端)上下文中可用的信息(如用户名或者数据库名)时,%q转义很有用。例如: - -log_line_prefix = '%m [%p] %q%u@%d/%a ' - - - - - - - - 对于输出的行,%Q 总是报告零标识符, - 因为log_statement在标识符能被计算之前生成输出,包括无效标识符不能计算的无效语句。 - - - - - log_lock_waits (boolean) + + checkpoint_flush_after (integer) - log_lock_waits配置参数 + checkpoint_flush_after配置参数 - - 控制当会话等待时间超过以获取锁时是否生成日志消息。 - 这对于确定锁等待是否导致性能不佳很有用。默认值为off。 - 只有超级用户和具有适当SET权限的用户才能更改此设置。 + 当执行检查点时写入的数据量超过此数量时,就尝试强制 OS 把这些写发送到底层存储。 + 这样做将会限制内核页面高速缓存中的脏数据数量,降低在检查点末尾发出fsync或者 OS 在后台大批量写回数据时被卡住的可能性。 + 这通常能显著降低事务延迟,但是也有一些情况(特别是负载超过但小于 OS 页面高速缓存)的性能会降低。 + 这种设置可能会在某些平台上没有效果。 + 如果指定值时没有单位,则以块为单位,即为BLCKSZ 字节,通常为8kB。 + 合法的范围在0(禁用强制写回)和2MB之间。Linux 上的默认值是256kB,其他平台上是0(如果BLCKSZ不是8kB,则默认值和最大值会按比例缩放到它)。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 - - - - + + - log_recovery_conflict_waits (boolean) + + checkpoint_warning (integer) - log_recovery_conflict_waits 配置参数 + checkpoint_warning配置参数 - - 控制启动进程等待时间超过针对恢复冲突的deadlock_timeout的时候是否产生日志消息。 - 这对于决定恢复冲突是否会阻止恢复应用WAL有所帮助。 + 如果由于填充WAL段文件导致的检查点之间的间隔低于这个参数表示的时间量,那么就向服务器日志写一个消息(它建议增加max_wal_size的值)。 + 如果指定值时没有单位,则以秒为单位。默认值是 30 秒(30s)。零则关闭警告。如果checkpoint_timeout低于checkpoint_warning,则不会有警告产生。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 + + + + max_wal_size (integer) + + max_wal_size配置参数 + + + - 默认为off。 - 这个参数只能在postgresql.conf文件中或服务器命令行中设置。 + 在自动检查点期间允许WAL增长的最大大小。这是一个软限制;在特殊情况下,如重负载、失败的archive_commandarchive_library,或高wal_keep_size设置下,WAL大小可能会超过max_wal_size。 + 如果未指定单位,则将其视为兆字节。默认值为1 GB。 + 增加此参数可能会增加崩溃恢复所需的时间。 + 此参数只能在postgresql.conf文件或服务器命令行中设置。 - - + + - - log_lock_failures (boolean) - - log_lock_failures配置参数 - - - - - 控制当获取锁失败时是否生成详细日志消息。这有助于分析锁失败的原因。 - 目前,仅支持由于SELECT NOWAIT导致的锁失败。 - 默认值为off。只有超级用户和具有适当SET权限的用户才能更改此设置。 - - - + + min_wal_size (integer) + + min_wal_size配置参数 + + + + + 只要 WAL 磁盘用量保持在这个设置之下,在检查点时旧的 WAL 文件总是 + 被回收以便未来使用,而不是直接被删除。这可以被用来确保有足够的 + WAL 空间被保留来应付 WAL 使用的高峰,例如运行大型的批处理任务。 + 如果指定值时没有单位,则以兆字节为单位。默认是 80 MB。这个参数只能在postgresql.conf + 或者服务器命令行中设置。 + + + - + + + + 归档 - log_parameter_max_length (integer) + + + archive_mode (enum) - log_parameter_max_length 配置参数 + archive_mode配置参数 - - 如果大于零,则记录在非错误语句日志消息中的每个绑定参数值都会被截断为指定的字节数。 - 零表示禁用非错误语句日志中绑定参数的记录。 - -1(默认值)允许完整记录绑定参数。 - 如果未指定单位,则默认为字节。 - 只有超级用户和具有适当SET权限的用户才能更改此设置。 + 当启用archive_mode时,完成的WAL段会通过设置 + 或 + 发送到归档存储。除了用于禁用归档的off外,还有两种模式:on和 + always。在正常操作期间,这两种模式之间没有区别,但当设置为always时, + WAL归档程序在归档恢复或备库模式下也会被启用。在always模式下,从归档中恢复的所有文件 + 或通过流复制传输的文件将被再次归档。详细信息请参见 + - - 此设置仅影响作为结果打印的日志消息,, 和相关的设置。 - 该设置的非零值会增加一些开销,特别是当参数以二进制形式发送时,因为需要转换为文本。 + archive_mode是一个独立的设置,不同于 + archive_command和 + archive_library,这样 + archive_command和 + archive_library可以在不离开 + 归档模式的情况下进行更改。 + 此参数只能在服务器启动时设置。 + 当wal_level设置为minimal时, + 无法启用archive_mode - - - log_parameter_max_length_on_error (integer) + + archive_command (string) - log_parameter_max_length_on_error 配置参数 + archive_command配置参数 - - 如果大于零,则错误消息中报告的每个绑定参数值都将裁剪为这么多字节。 - 零(默认值)禁止在错误消息中包含绑定参数。-1允许打印完整绑定参数。 - 如果指定此值时没有单位,则将其作为字节。 + 本地 shell 命令被执行来归档一个完成的 WAL 文件段。字符串中的任何%p被替换成要被归档的文件的路径名, 而%f只被文件名替换(路径名是相对于服务器的工作目录, 即集簇的数据目录)。如果要在命令里嵌入一个真正的%字符,可以使用%%。有一点很重要,该命令只在成功时返回一个零作为退出状态。更多信息请见 - - 该设置的非零值会增加开销,由于PostgreSQL需要在每条语句的开始处将参数值的文本表示存储在内存中,无论最终是否会发生错误。 - 当绑定参数以二进制形式发送时,开销比以文本形式发送时更大,因为前者需要数据转换,而后者只需要复制字符串。 + 这个参数只能在postgresql.conf文件或服务器命令行中设置。 + 除非在服务器启动时启用了archive_mode并且archive_library设置为空字符串,否则将被忽略。 + 如果archive_command是空字符串(默认值),而archive_mode已启用(并且archive_library设置为空字符串), + WAL归档将暂时被禁用,但服务器将继续积累WAL段文件,期望很快会提供命令。 + 将archive_command设置为一个什么都不做但返回true的命令,例如/bin/true(Windows上为REM), + 实际上禁用了归档,但也破坏了用于归档恢复所需的WAL文件链,因此只应在不寻常的情况下使用。 - - - log_statement (enum) + + archive_library (string) - log_statement配置参数 + archive_library配置参数 - - 控制哪些 SQL 语句被记录。有效值是 - none (off)、ddlmod和 - all(所有语句)。ddl记录所有数据定义语句,例如CREATEALTER和 - DROP语句。mod记录所有ddl语句,外加数据修改语句例如INSERT, - UPDATEDELETETRUNCATE, - 和COPY FROM。 - 如果PREPAREEXECUTE和 - EXPLAIN ANALYZE包含合适类型的命令,它们也会被记录。对于使用扩展查询协议的客户端,当收到一个执行消息时会产生日志并且会包括绑定参数的值(任何内嵌的单引号会被双写)。 + 用于归档已完成的WAL文件段的库。如果设置为空字符串(默认值),则通过shell进行归档,并使用。 + 否则,指定的共享库用于归档。当此参数更改时,postmaster会重新启动WAL归档进程。有关更多信息,请参见。 + + + 这个参数只能在postgresql.conf文件中或者服务器命令行中设置。 + + + + archive_timeout (integer) + + archive_timeout配置参数 + + + - 默认值为none。 - 只有超级用户和具有适当SET权限的用户才能更改此设置。 + 只针对已完成的 WAL 段调用。 + 因此,如果您的服务器生成的WAL流量较少(或者在这样做时有间歇期),在事务完成和安全记录到归档存储之间可能会有很长的延迟。 + 为了限制未归档数据的年龄,您可以将archive_timeout设置为强制服务器定期切换到新的WAL段文件。 + 当此参数大于零时,只要自上次段文件切换以来经过了这段时间,并且存在任何数据库活动,包括单个检查点(如果没有数据库活动,则跳过检查点),服务器将切换到新的段文件。 + 请注意,由于强制切换而提前关闭的归档文件仍然与完全填满的文件长度相同。因此,使用非常短的archive_timeout是不明智的,它会使您的归档存储膨胀。 + 通常,将archive_timeout设置为一分钟左右是合理的。如果您希望数据比这更快地从主库复制出来,您应该考虑使用流复制而不是归档。 + 如果未指定单位,则将此值视为秒。 + 此参数只能在postgresql.conf文件或服务器命令行中设置。 + + - + + - - 即使使用log_statement = all设置,包含简单语法错误的语句也不会被记录。这是因为只有在完成基本语法解析并确定了语句类型之后才会发出日志消息。在扩展查询协议的情况下,在执行阶段之前(即在解析分析或规划期间)出错的语句也不会被记录。将log_min_error_statement设置为ERROR(或更低)来记录这种语句。 - + - - 记录的语句可能会透露敏感数据,甚至包含明文密码。 - - - - + 恢复 - + + 配置 + 恢复 + general settings + - log_replication_commands (boolean) + + 本节描述了适用于一般恢复的设置,影响崩溃恢复、流复制和基于归档的复制。 + + + + + + recovery_prefetch (enum) - log_replication_commands 配置参数 + recovery_prefetch配置参数 - - 每个复制命令都会被记录在服务器日志中。 - 有关复制命令的更多信息,请参见。 - 默认值为off。 - 只有超级用户和具有适当SET权限的用户才能更改此设置。 + 是否在恢复期间尝试预取在WAL中引用但尚未在缓冲池中的块。有效值为 + offon和 + try(默认值)。设置 + try仅在操作系统提供 + posix_fadvise函数时才启用 + 预取,该函数目前用于实现预取。请注意,一些操作系统提供该 + 函数,但它不起作用。 + + + 预取即将需要的块可以减少某些工作负载下恢复期间的I/O等待时间。 + 另请参阅和 + 设置,限制预取活动。 - - - log_temp_files (integer) + + wal_decode_buffer_size (integer) - log_temp_files配置参数 + wal_decode_buffer_size配置参数 - - 控制临时文件名和大小的日志记录。 - 临时文件可以用于排序、哈希和临时查询结果。 - 如果通过此设置启用,每当删除临时文件时都会发出日志记录。 - 值为零时记录所有临时文件信息,而正值仅记录大小大于或等于指定数据量的文件。 - 如果未指定单位,则将其视为千字节。 - 默认设置为-1,禁用此类日志记录。 - 只有超级用户和具有适当SET权限的用户才能更改此设置。 + 服务器可以在WAL中查找预取块的最大提前量限制。如果未指定单位,则将其视为字节。 + 默认值为512kB。该参数只能在服务器启动时设置。 - + + - log_timezone (string) + + + 归档恢复 + + + 配置 + 恢复 + of a standby server + + + + 本节描述了仅在恢复期间适用的设置。如果您希望执行任何后续恢复,则必须重置它们。 + + + + 恢复 涵盖使用服务器作为备库或用于执行目标恢复。 + 通常情况,备库模式用于提供高可用性和/或读可扩展性,而目标恢复用于从数据丢失中恢复。 + + + + 若要在备库模式下启动服务器,在数据目录中建立名为standby.signalstandby.signal的文件。 + 服务器将会进入恢复状态并且在到达归档WAL末尾时不会停止恢复,但将保持尝试继续恢复,通过连接到primary_conninfo设置指定的发送服务器和/或用restore_command获取新的WAL分段。 + 对于这种模式,来自本节的参数和 是值得关注的。 + 中的参数也会被应用,但通常在这种模式下没用。 + + + + 要启动服务器为目标恢复模式,需在数据目录中建立名为recovery.signalrecovery.signal的文件。 + 如果同时创建了standby.signalrecovery.signal 文件,则优先使用备库模式。 + 目标恢复模式在归档的WAL全部回放或到达recovery_target时结束。 + 在这种模式下,将使用来自本节和 的参数。 + + + + + restore_command (string) - log_timezone配置参数 + restore_command配置参数 + + 用于获取 WAL 文件系列的一个已归档段的本地 shell 命令。这个参数是归档恢复所必需的,但是对于流复制是可选的。 + 在该字符串中的任何%f会被替换为从归档中获得的文件的名字,并且任何%p会被在服务器上的复制目标路径名替换(该路径名是相对于当前工作目录的,即集簇的数据目录)。 + 任何%r会被包含上一个可用重启点的文件的名字所替换。 + 在那些必须被保留用于使得一次恢复变成可重启的文件中,这个文件是其中最早的一个,因此这个信息可以被用来把归档截断为支持从当前恢复重启所需的最小值。 + %r通常只被温备配置(见)所使用。要嵌入一个真正的%字符,需要写成%%。 + - 设置在服务器日志中写入的时间戳的时区。和不同,这个值是集簇范围的,因此所有会话将报告一致的时间戳。内置默认值是GMT,但是通常会被在postgresql.conf中覆盖。initdb将安装一个对应于其系统环境的设置。详见。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 + 很重要的一点是,该命令只有在成功时才返回一个为零的退出状态。 + 该命令会被询问不存在于归档中的文件名,当这样被询问时它必须返回非零。示例: + +restore_command = 'cp /mnt/server/archivedir/%f "%p"' +restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows + + 一个例外是如果该命令被一个信号(不是SIGTERM,它是数据库服务器关闭的一部分)或者一个 shell 错误(例如命令未找到)终止,则恢复将会中止并且服务器将不会启动。 + + + + 这个参数只能在postgresql.conf文件中或者服务器命令行中设置。 - - - - - 使用 CSV 格式的日志输出 - - - 在log_destination列表中包括csvlog提供了一种便捷方式将日志文件导入到一个数据库表。这个选项发出逗号分隔值(CSV)格式的日志行,包括这些列: - 带毫秒的时间戳、 - 用户名、 - 数据库名、 - 进程 ID、 - 客户端主机:端口号、 - 会话 ID、 - 每个会话的行号、 - 命令标签、 - 会话开始时间、 - 虚拟事务 ID、 - 普通事务 ID、 - 错误严重性、 - SQLSTATE 代码、 - 错误消息、 - 错误消息详情、 - 提示、 - 导致错误的内部查询(如果有)、 - 错误位置所在的字符计数、 - 错误上下文、 - 导致错误的用户查询(如果有且被log_min_error_statement启用)、 - 错误位置所在的字符计数、 - 在 PostgreSQL 源代码中错误的位置(如果log_error_verbosity被设置为verbose)以及应用名,后端类型,并行组leader的进程ID和查询ID。 - 下面是一个定义用来存储 CSV 格式日志输出的样表: - - -CREATE TABLE postgres_log -( - log_time timestamp(3) with time zone, - user_name text, - database_name text, - process_id integer, - connection_from text, - session_id text, - session_line_num bigint, - command_tag text, - session_start_time timestamp with time zone, - virtual_transaction_id text, - transaction_id bigint, - error_severity text, - sql_state_code text, - message text, - detail text, - hint text, - internal_query text, - internal_query_pos integer, - context text, - query text, - query_pos integer, - location text, - application_name text, - backend_type text, - leader_pid integer, - query_id bigint, - PRIMARY KEY (session_id, session_line_num) -); - + + archive_cleanup_command (string) + + archive_cleanup_command配置参数 + + + + + 这个可选参数指定了一个 shell 命令,它将在每一个重启点被执行。 + archive_cleanup_command的目的是提供一种清除不再被备库需要的旧的已归档 WAL 文件的机制。 + 任何%r会被替换为包含最后一个可用重启点的文件的名称。 + 那是使一次恢复变成可重启的所必须被保留的最早的文件,并且因此比%r更早的所有文件可以被安全地移除。 + 这个信息可以被用来把归档截断为支持从当前恢复重启所需的最小值。 + 对于单一备库配置,模块常常被用在archive_cleanup_command中,例如: +archive_cleanup_command = 'pg_archivecleanup /mnt/server/archivedir %r' + 但是注意,如果多个备库正在从同一个归档目录中恢复,你将需要保证只有当所有服务器都不再需要这些 WAL 文件时才会删除它们。 + archive_cleanup_command通常被用于一种温备配置(见)中。 + 要在该命令中嵌入一个真正的%字符,需要写成%% - - 使用COPY FROM命令将一个日志文件导入到这个表中: - - -COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - - 也可以作为外部表访问该文件,使用提供的 模块。 + 如果该命令返回一个非零退出状态,则将会写出一个警告日志消息。 + 一个例外是如果该命令被一个信号或者一个 shell 错误(例如命令未找到)终止,则会抛出一个致命错误。 - - 你可以做一些事情来简化导入 CSV 日志文件: - - - - - 设置log_filenamelog_rotation_age为你的日志文件提供一种一致的、可预测的命名空间。这让你预测文件名会是怎样以及知道什么时候一个个体日志文件完成并且因此准备好被导入。 - - + 这个参数只能在postgresql.conf文件中或者服务器命令行中设置。 + + + - - - 将log_rotation_size设置为 0 来禁用基于尺寸的日志轮转,因为它使得日志文件名难以预测。 - - + + recovery_end_command (string) + + recovery_end_command配置参数 + + + + + 这个参数指定了一个将只在恢复末尾被执行一次的 shell 命令。这个参数是可选的。 + recovery_end_command的目的是为复制或恢复之后的清除提供一种机制。 + 与中相似,任何%r会被替换为包含最后一个可用重启点的文件的名称。 + + + 如果该命令返回一个非零退出状态,则一个警告日志消息将被写出并且不管怎样该数据库将继续启动。 + 一个例外是如果该命令被一个信号或者 shell 错误(例如命令未找到)中止,该数据库将不会继续启动。 + + + 这个参数只能在postgresql.conf文件中或者服务器命令行中设置。 + + + - - - 将log_truncate_on_rotation设置为on,这样在同一个文件中旧日志数据不会与新数据混杂。 - - +
- - - 上述表定义包括一个主键声明。这有助于避免意外地两次导入相同的信息。COPY命令一次提交所有它导入的数据,因此任何错误将导致整个导入失败。如果你导入一个部分完成的日志文件并且稍后当它完全完成后再次导入,主键违背将导致导入失败。请等到日志完成且被关闭之后再导入。这个过程也可以避免意外地导入部分完成的行,这种行也将导致COPY失败。 - - - - - - + - 使用JSON格式的日志输出 + - - 包括jsonloglog_destination列表中提供了一种方便的方式将日志文件导入到许多不同的程序中。此选项以JSON格式发出日志行。 - + 恢复目标 - 字段值为null的字符串字段将被排除在输出之外。 - 未来可能会添加其他字段。处理jsonlog输出的用户应忽略未知字段。 + 默认情况下,恢复将会一直恢复到 WAL 日志的末尾。下面的参数可以被用来指定一个更早的停止点。 + 在recovery_targetrecovery_target_lsnrecovery_target_namerecovery_target_timerecovery_target_xid中, + 最多只能使用一个,如果在配置文件中使用了多个,将会产生一个错误。这些参数只能在服务器启动时设置。 - - 每个日志行都被序列化为一个JSON对象,其中包含一组键和它们对应的值,如中所示。 - + + + recovery_target = 'immediate' + + recovery_target配置参数 + + + + + 这个参数指定恢复应该在达到一个一致状态后尽快结束,即尽早结束。在从一个在线备份中恢复时,这意味着备份结束的那个点。 + + + 在技术上,这是一个字符串参数,但是'immediate'是目前唯一允许的值。 + + + - + + recovery_target_name (string) + + recovery_target_name配置参数 + + + + + 这个参数指定(pg_create_restore_point()所创建)的已命名的恢复点,恢复将进行到该恢复点。 + + + - JSON日志条目的键和值 - - + + recovery_target_time (timestamp) + + recovery_target_time配置参数 + + + + + 此参数指定恢复要进行到的时间戳。精确的停止点还受到的影响。 + - - 键名 - 类型 - 描述 - - - + + 此参数的值是一个被timestamp with time zone数据类型接受的相同格式的时间戳,只不过你不能使用时区缩写(除非变量在配置文件中已提前设置)。 + 首选样式是使用 UTC 的数字偏移量,或者你可以写一个完整时区名称,例如 Europe/Helsinki 而不是 EEST。 + + + - - timestamp - string - 带毫秒的时间戳 - + + recovery_target_xid (string) + + recovery_target_xid配置参数 + + + + + 这个参数指定恢复要进行到的事务 ID。记住虽然事务 ID 是在事务开始时顺序分配的,但是事务可能以不同的数字顺序完成。 + 那些在指定事务之前(也可以包括该事务)提交的事务将被恢复。精确的停止点也受到的影响。 + + + - - user - string - 用户名 - + + recovery_target_lsn (pg_lsn) + + recovery_target_lsn配置参数 + + + + + 此参数指定恢复要进行到的预写日志位置的 LSN。精确的停止点也受 的影响。 + 使用系统数据类型pg_lsn解析此参数。 + + + + - - dbname - string - 数据库名称 - + + 下列选项进一步指定恢复目标,并且影响到达目标时会发生什么: + - - pid - number - 进程ID - + + + recovery_target_inclusive (boolean) + + recovery_target_inclusive配置参数 + + + + + 指定我们是否仅在指定的恢复目标之后停止(on),或者仅在恢复目标之前停止(off)。 + 适用于或者被指定的情况。 + 这个设置控制恢复是否包含 WAL 位置(LSN)、提交时间或事务 ID 分别恰好等于目标值的事务。默认值为on。 + + + - - remote_host - string - 客户端主机 - + - - remote_port - number - 客户端端口 - + recovery_target_timeline (string) + + recovery_target_timeline 配置参数 + + + - - session_id - string - 会话ID - + + 指定恢复到一个特定的时间线中。该值可以是数字时间线 ID 或特殊值。 + 值current沿着与执行基础备份时相同的时间线恢复。 + 值latest将恢复到归档中能找到的最新时间线,这在备库中很有用。 + latest是默认值。 + - - line_num - number - 每个会话的行号 - - - ps - string - 当前ps显示 - - - session_start - string - 会话开始时间 - + + 你通常只需要在复杂的再次恢复场景中设置此参数,也就是当你需要回到某个状态,而该状态本身又是在一次时间点恢复之后达到的。 + 相关讨论见。 + + + - - vxid - string - 虚拟事务ID - - - - txid - string - 常规事务 ID - + + recovery_target_action (enum) + + recovery_target_action配置参数 + + + + + 指定在达到恢复目标时服务器应该立刻采取的动作。默认动作是pause,这表示恢复将会被暂停。 + promote表示恢复处理将会结束并且服务器将开始接受连接。 + 最后,shutdown将在达到恢复目标之后停止服务器。 + + + 使用pause设置的目的是允许对数据库执行查询,以检查这个恢复目标是否为最合适的恢复位置。 + 暂停的状态可以使用pg_wal_replay_resume()(见)继续,这会让恢复终结。 + 如果这个恢复目标不是想要的停止点,那么关闭服务器,将恢复目标设置改为一个稍后的目标并且重启以继续恢复。 + + + 要让实例在想要的重放点那里准备好,shutdown设置可以派上用场。 + 该实例将仍能重放更多 WAL 记录(并且事实上,下次启动时必须重新回放自上一个检查点以来的 WAL 记录)。 + + + 注意由于在recovery_target_action被设置为shutdown时,recovery.signal将不会被移除, + 任何后续的启动都将会以立刻关闭为终结,除非该配置被改变或者recovery.signal文件被手工移除。 + + + 如果没有设置恢复目标,这个设置没有效果。 + 如果没有启用pause设置的动作将和shutdown一样。 + 如果在备库提升期间达到恢复目标,pause 的设置将与 promote的行为相同。 + + + 在任何情况下,如果已配置了恢复目标,但归档恢复在达到目标之前结束,则服务器将关闭,并出现致命错误。 + + + - - error_severity - string - 错误严重性 - + + - - state_code - string - SQLSTATE代码 - + - - message - string - 错误消息 - + + 复制 - - detail - string - 错误消息的详细信息 - + + 这些设置控制内置流复制特性(见)的行为。服务器将可以是主库或备库。主库能发送数据,而备库总是被复制数据的接收者。当使用级联复制(见)时,备库也可以是发送者,同时也是接收者。这些参数主要用于发送服务器和备库,尽管某些只在主库上有意义。如果有必要,设置可以在集簇中变化而不出问题。 + - - hint - string - 错误消息提示 - + + 发送服务器 - - internal_query - string - 导致错误的内部查询 - + + 这些参数适用于向一个或多个备库发送复制数据的服务器。主库总是发送服务器,因此这些参数通常需要在主库上设置。 + - - internal_position - number - 内部查询的游标索引 - + + - - context - string - 错误上下文 - + max_wal_senders (integer) + + max_wal_senders配置参数 + + + - - statement - string - 客户提供的查询字符串 - + + 指定来自备库或流式基础备份客户端的最大并发连接数(即同时运行的 WAL 发送进程的最大数量)。 + 默认值为 10。值 0 表示禁用复制。 + 流式客户端突然断开连接后,可能会留下一个孤立连接槽,直到超时才释放。 + 因此,此参数应设置得略高于预期的最大客户端数,使断开连接的客户端能够立即重新连接。 + 此参数只能在服务器启动时设置。此外,wal_level 必须设置为 + replica 或更高级别,才允许来自备库的连接。 + - - cursor_position - number - 查询字符串中的光标索引 - + + 运行备库时,必须将此参数设置为大于或等于主库上的值。否则,备库上将不允许查询。 + + + - - func_name - string - 错误位置函数名称 - + + max_replication_slots (integer) + + max_replication_slots配置参数 + + + + + 指定服务器可以支持的复制槽(见) + 最大数量。默认值为10。这个参数只能在服务器启动时设置。将它设置为一个比当前已有复制槽要少的值会阻碍服务器启动。此外,要允许使用复制槽, + wal_level必须被设置为replica或 + 更高。 + - - file_name - string - 错误位置的文件名 - + + 在订阅者端,指定可以同时跟踪多少个复制源(参见),从而限制可以在服务器上创建的逻辑复制订阅数。 + 如果将其设置为低于当前正在跟踪的复制源数量的值(该数量反映在 + pg_replication_origin_status 中, + 而不是 pg_replication_origin 中),服务器将无法启动。 + + + - - file_line_num - number - 错误位置的文件行号 - + + output_plugin_libraries (string) + + output_plugin_libraries配置参数 + + + + + 列出安装在 所指定位置中、同时也被信任可供复制客户端用作逻辑输出插件的库。 + 任何针对其他库的逻辑解码或 + 复制请求都将被拒绝。所有用户都受此限制。 + 默认值为 'pgoutput, test_decoding',它们是标准 + PostgreSQL 发行版中包含的两个逻辑输出插件。 + + + 其格式为以逗号分隔的库名称列表,每个名称的解释方式与 + LOAD命令相同 + (但逻辑解码客户端指定的插件名称必须与列表中的一个条目完全匹配, + 大小写或路径结构不得有变化)。条目之间的空白会被忽略;如果库名称中需要包含空白或逗号, + 请用双引号将其括起。 + + + 服务器管理员有责任确保,加载添加到此列表中的库时,不会无意中向非超级用户授予额外权限。 + + + + 从没有 output_plugin_libraries 参数的版本更新服务器时, + 以下查询可帮助构造所有持久逻辑复制槽所需的插件列表: + +SELECT DISTINCT plugin FROM pg_replication_slots WHERE plugin IS NOT NULL; + + 调整 output_plugin_libraries 之前,请仔细审查该列表以确保安全。 + + + 上述查询只能显示过去某个时刻已成功添加到复制槽的插件。 + 新近被拒绝的请求将以类似以下消息出现在日志中: + +ERROR: library "..." may not be used as an output plugin +DETAIL: The configuration parameter "output_plugin_libraries" (currently 'pgoutput, test_decoding') does not name this library as a trusted output plugin. +HINT: If it is safe for all REPLICATION users to use this library as an output plugin, add it to "output_plugin_libraries" and reload the server configuration. + + + + + - - application_name - string - 客户端应用程序名称 - + - - backend_type - string - 后端类型 - + wal_keep_size (integer) + + wal_keep_size 配置参数 + + + - - leader_pid - number - 活动并行工作者的领导者进程ID - + + 指定在 pg_wal 目录中保留的旧 WAL 文件的最小总量, + 以便备库需要时获取这些文件进行流复制。如果连接到发送服务器的备库落后超过 + wal_keep_size 兆字节,发送服务器可能会移除备库仍需要的 WAL 段, + 从而导致复制连接终止。下游连接最终也会因此失败。 + (不过,如果使用了 WAL 归档,备库可以通过从归档获取该段来恢复。) + - - query_id - number - 查询ID - - - -
-
+ + 此设置只规定 pg_wal 中保留的段的最小总量;系统可能需要为 WAL 归档 + 或从检查点恢复而保留更多段。如果 wal_keep_size 为零(默认值), + 系统不会为备库额外保留任何段,因此备库可用的旧 WAL 段数取决于前一个检查点的位置 + 和 WAL 归档的状态。如果指定值时没有单位,则按兆字节计算。 + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 + + + - + - 进程标题 + max_slot_wal_keep_size (integer) + + max_slot_wal_keep_size 配置参数 + + + - - 这些设置控制服务器进程的进程标题如何被修改。进程标题通常可以用ps或者 Windows 上的进程浏览器等程序来查看。详见。 - + + 指定检查点时复制槽允许在 + pg_wal 目录中保留的 WAL 文件最大总量。 + 如果 max_slot_wal_keep_size 为 -1(默认值),复制槽可以保留无限量的 WAL 文件。 + 否则,如果复制槽的 restart_lsn 落后当前 LSN 超过给定大小,使用该槽的备库可能会 + 因为所需 WAL 文件被移除而无法继续复制。可以在 + pg_replication_slots 中查看复制槽的 WAL 可用情况。 + 如果指定值时没有单位,则按兆字节计算。此参数只能在 + postgresql.conf 文件中或服务器命令行上设置。 + + + - - + - cluster_name (string) + wal_sender_timeout (integer) - cluster_name 配置参数 + wal_sender_timeout配置参数 - 为不同目的设置标识这个数据库集簇(实例)的名称。此集簇名称出现在该集簇中所有服务器进程的进程标题中。 - 此外,它还是备库连接的默认应用名称。(参见 .) + 终止非活动时间超过此值的复制连接。这有助于发送服务器检测备库崩溃或网络中断。 + 如果指定值时没有单位,则按毫秒计算。默认值为 60 秒。值零禁用超时机制。 - 这个名称可以是任何长度不超过NAMEDATALEN个字符(在标准编译中是 64字符)的任何字符串。只有可打印的 ASCII 字符能被用在cluster_name值中。其他字符将被替换为问号(?)。如果这个参数被设置为空字符串''(也是默认值),将不会显示名称。这个参数只能在服务器启动时设置。 + 对于跨多个地理位置分布的集簇,在各位置使用不同的值可以提高集簇管理的灵活性。 + 对于网络延迟较低的备库,较小的值有助于更快地检测故障; + 对于地处远端、网络延迟较高的备库,较大的值有助于更准确地判断其健康状况。 - + - update_process_title (boolean) + track_commit_timestamp (boolean) - update_process_title 配置参数 + track_commit_timestamp 配置参数 - 每次服务器接收到新的SQL命令时,都可以更新进程标题。 - 在大多数平台上,默认情况下此设置为on,但在Windows上默认为off, - 因为该平台更新进程标题的开销较大。 - 只有超级用户和具有适当SET权限的用户才能更改此设置。 + 记录事务的提交时间。该参数只能在服务器启动时设置。默认值是off - - - - - + + - 运行时统计数据 + + 主库 - + + 这些参数可以在向一个或多个备库发送复制数据的主库上设置。 + 除这些参数外,还必须在主库上适当设置 , + 也可以选择启用 WAL 归档(见 )。 + 这些参数在备库上的取值不影响备库运行,不过也可以预先设置,以备将来提升为主库。 + - 累积查询和索引统计 + + - - 这些参数控制服务器范围内的累积统计系统。 - 启用后,收集的数据可以通过pg_statpg_statio - 系列系统视图进行访问。有关更多信息,请参阅。 - - - - - - - track_activities (boolean) - - track_activities配置参数 - - - + synchronous_standby_names (string) + + synchronous_standby_names配置参数 + + + - 启用对每个会话当前执行命令的信息收集,包括其标识符和命令开始执行的时间。 - 此参数默认为开启状态。请注意,即使启用了此信息,只有超级用户、具有 - pg_read_all_stats角色权限的角色和拥有被报告会话的用户 - (包括属于他们具有权限的角色的会话)才能看到此信息,因此不应构成安全风险。 - 只有超级用户和具有适当SET权限的用户才能更改此设置。 + 如所述,这个参数指定一个支持同步复制的备库的列表。 + 将有一个或多个活动的同步备库,在这些备库确认收到它们的数据之后,等待提交的事务将被允许继续下去。 + 同步备库是那些名字出现在这个列表中,并且当前已连接并且正在实时流式传输数据(如pg_stat_replication视图中streaming的状态所示)的服务器。 + 指定多于一台同步备库可以得到非常高的可用性并且能防止数据丢失。 - - - - - - track_activity_query_size (integer) - - track_activity_query_size配置参数 - - - - 为每个活动会话指定存储当前执行命令的文本所保留的内存量,它们被用于pg_stat_activity.query域。 - 如果指定值时没有单位,则以字节为单位。默认值是 1024字节。这个参数只能在服务器启动时被设置。 + 用于这一目的的备库的名称是其application_name设置,它在备库的连接信息中设置。 + 对于物理复制备库,应在 primary_conninfo 设置中指定。 + 若已设置 ,则默认使用其值;否则默认值为 walreceiver。 + 对于逻辑复制,可以在订阅的连接信息中设置,默认值为订阅名称。 + 对于其他复制流消费者,请参考其文档。 - - - - - track_counts (boolean) - - track_counts配置参数 - - - + + 这个参数使用下面的语法之一来指定一个备库列表: + +[FIRST] num_sync ( standby_name [, ...] ) +ANY num_sync ( standby_name [, ...] ) +standby_name [, ...] + + 其中num_sync是事务需要等待其回复的同步备库的数量,standby_name是一个备库的名称。FIRST以及ANY指定从所列服务器中选取同步备库的方法。 + - 启用对数据库活动的统计信息收集。 - 此参数默认为开启,因为自动清理守护进程需要收集的信息。 - 只有超级用户和具有适当SET权限的用户才能更改此设置。 + 关键词FIRST加上num_sync指定一种基于优先级的同步复制,并且会让事务提交等待,直到它们的WAL记录被复制到基于优先级选择的num_sync台同步备库上为止。例如,设置FIRST 3 (s1, s2, s3, s4)将导致每次提交都等待来自三台较高优先级的备库的答复,这三台备库将从备库s1s2s3以及s4中选出。在该列表中出现较早的备库将被给予较高的优先级,并且将被考虑为同步备库。列表中出现的其他备库表示潜在的同步备库。如果当前的任何同步备库因为某种原因断开连接,它将立刻被下一个最高优先级的备库替代。关键词FIRST是可选的。 - - - - - track_cost_delay_timing (boolean) - - track_cost_delay_timing配置参数 - - - - - 启用基于成本的清理延迟计时(参见)。 - 默认情况下该参数关闭,因为它需要反复查询操作系统当前时间,在某些平台上可能带来显著开销。 - 你可以使用pg_test_timing来衡量系统上的计时开销。 - 基于成本的清理延迟计时信息会显示在pg_stat_progress_vacuum、 - pg_stat_progress_analyze中, - 也会显示在带有VERBOSE选项的VACUUMANALYZE输出中, - 并且当设置了时,autovacuum 还会为自动清理和自动分析记录这些信息。 - 只有超级用户和具有适当SET权限的用户才能更改此设置。 - - - - - - - track_io_timing (boolean) - - track_io_timing配置参数 - - - - 启用数据库I/O调用的计时。 默认情况下,此参数处于关闭状态,因为它将重复查询操作系统的当前时间,这可能会在某些平台上造成显著的开销。 您可以使用工具来测量系统上计时的开销。 - I/O计时信息显示在 - pg_stat_database中,在的输出中,当使用BUFFERS选项时,在的输出中,当使用VERBOSE选项时,由autovacuum执行自动清理和自动分析时,当设置了时,以及由。 - 只有超级用户和具有适当SET权限的用户才能更改此设置。 + 关键词ANY加上num_sync指定一种基于法定人数的同步复制,并且会让事务提交等待,直到它们的WAL记录被复制到所列出备库中的至少num_sync台上为止。例如,设置ANY 3 (s1, s2, s3, s4)将导致每次提交会在收到s1s2s3以及s4中任意三台备库的回答后立刻继续下去。 - - - - - - track_wal_io_timing (boolean) - - track_wal_io_timing 配置参数 - - - - 启用WAL I/O调用的定时。此参数默认关闭,因为它将重复查询操作系统的当前时间, - 这可能会在某些平台上造成显著的开销。 - 您可以使用pg_test_timing工具来 - 测量系统上定时的开销。 - I/O定时信息显示在 - pg_stat_wal中。 - 只有超级用户和具有适当SET权限的用户才能更改此设置。 + FIRSTANY是大小写不敏感的。如果这些关键词被用作备库的名字,其standby_name必须被放在双引号内。 - - - - - - track_functions (enum) - - track_functions配置参数 - - - - 启用函数调用次数和时间的跟踪。指定pl以仅跟踪过程语言函数, - all以同时跟踪SQL和C语言函数。默认值为none, - 即禁用函数统计跟踪。只有超级用户和具有适当SET权限的用户才能更改此设置。 + PostgreSQL版本 9.6 之前使用过第三种语法,目前也仍然支持。它和FIRSTnum_sync等于1的第一种语法相同。例如,FIRST 1 (s1, s2)s1, s2具有相同的含义:s1或者s2会被选中作为同步备库。 - - - - 简单到足以被内联到调用查询中的 SQL 语言函数不会被跟踪, 而不管这个设置。 - - - - - - - - stats_fetch_consistency (enum) - - stats_fetch_consistency配置参数 - - - + + 特殊项*匹配任意备库名称。 + - 确定在事务中多次访问累积统计信息时的行为。当设置为 - none时,每次访问都会重新从共享内存中获取计数器。 - 当设置为cache时,对对象的统计信息的第一次访问会将这些统计信息缓存, - 直到事务结束,除非调用pg_stat_clear_snapshot()。 - 当设置为snapshot时,第一次访问统计信息会缓存当前数据库中所有可访问的统计信息, - 直到事务结束,除非调用pg_stat_clear_snapshot()。 - 在事务中更改此参数会丢弃统计快照。默认值为cache。 + 没有机制强制备库名称的唯一性。在出现重复的情况下,匹配的备库之一将被认为是较高优先级,不过无法弄清到底是哪一个。 - none适用于监控系统。如果值只被访问一次,它是最有效的。 - cache确保重复访问产生相同的值,这对涉及自连接的查询很重要。 - snapshot在交互式检查统计信息时可能很有用,但开销较高, - 特别是存在许多数据库对象时。 + 每一个standby_name都应该具有合法 SQL 标识符的形式,除非它是*。如果必要你可以使用双引号。但是注意在比较standby_name和备库应用程序名称时是大小写不敏感的(不管有没有双引号)。 - - - - - - - - - 统计监控 - - - - - compute_query_id (enum) - - compute_query_id 配置参数 - - - - 启用查询标识符的内核计算。 - 查询标识符可以在 pg_stat_activity - 视图中显示,使用 EXPLAIN,或者如果通过 - 参数进行配置,则可以在日志中发出。 - 扩展还需要计算查询标识符。 - 请注意,如果内核查询标识符计算方法不可接受,也可以使用外部模块。 - 在这种情况下,必须始终禁用内核计算。 - 有效值为 off(始终禁用), - on(始终启用),auto, - 允许诸如 这样的模块 - 自动启用它,并且 regress 具有与 - auto 相同的效果,只是查询标识符不会显示在 - EXPLAIN 输出中,以便促进自动回归测试。 - 默认值为 auto。 + 如果这里没有指定同步备库名称,那么不启用同步复制并且事务提交将不会等待复制。这是默认的配置。即便当同步复制被启用时,个体事务也可以被配置为不等待复制,做法是将参数设置为localoff - - - 确认只有一个查询标识符被计算和显示,如果一个查询标识符已经被计算,扩展计算标识符将抛出一个错误。 - - + + 这个参数只能在postgresql.conf文件中或通过服务器命令行进行设置。 + - - - log_statement_stats (boolean) - - log_statement_stats配置参数 - - - - log_parser_stats (boolean) - - log_parser_stats配置参数 - - - - log_planner_stats (boolean) - - log_planner_stats配置参数 - - - log_executor_stats (boolean) + + vacuum_defer_cleanup_age (integer) - log_executor_stats配置参数 + vacuum_defer_cleanup_age 配置参数 - - 对于每个查询,将各自模块的性能统计输出到服务器日志中。这是一个简单的性能分析工具,类似于Unix getrusage()操作系统功能。 - log_statement_stats报告总语句统计,而其他选项报告每个模块的统计信息。 - log_statement_stats不能与任何单独模块选项一起启用。所有这些选项默认情况下都是禁用的。 - 只有超级用户和具有适当SET权限的用户才能更改这些设置。 + 指定VACUUMHOT更新延迟清理死行版本的事务数。默认值为零个事务, + 意味着可以尽快移除死行版本,也就是在它们不再对任何打开的事务可见时立即移除。 + 如所述,在为热备服务器提供支持的主库上,你可能希望将此参数设置为非零值。 + 这让备库上的查询有更多时间完成,而不会因过早清理行而发生冲突。 + 但是,由于此值以主库上发生的写事务数计量,很难预测会给备库查询带来多少额外的宽限时间。 + 此参数只能在postgresql.conf文件中或在服务器命令行上设置。 + + + 你也应考虑在备库上设置hot_standby_feedback,作为使用此参数的替代方案。 + + + 这不会阻止清理已经达到old_snapshot_threshold指定年龄的死行。 + + - - - - - - - - Vacuuming - - - 自动清理 - 配置参数 - + + 备库 - - 这些参数控制 vacuuming 的行为。有关 vacuum 的目的和职责的更多信息,请参阅。 + + 这些设置控制备库接收复制数据时的行为。 + 它们在主库的值是无关的。 - - 自动 Vacuuming - - - 这些设置控制autovacuum特性的行为。详情请参考 - 。注意很多这些设置可以被针对每个表 - 的设置所覆盖,参见。 - + - + + primary_conninfo (string) + + primary_conninfo 配置参数 + + + + + 指定备库用来连接发送服务器的连接字符串。这个字符串的格式在中描述。 + 如果在这个字符串中有任何选项未被指定,那么将检查相应的环境变量(见)。 + 如果环境变量也没有被设置,则使用默认值。 + + + 连接字符串应当指定发送服务器的主机名(或地址),以及端口号(如果它与备库的默认端口不同)。 + 还要指定发送服务器上具有适当权限的角色所对应的用户名(见)。 + 如果发送端要求密码认证,还需要提供密码。它既可以直接写在 primary_conninfo 字符串中, + 也可以写在备库上的独立 ~/.pgpass 文件中(数据库名使用 replication)。 + 不要在primary_conninfo字符串中指定数据库名。 + + + 这个参数只能在 postgresql.conf 文件或服务器命令行上设置。 + 如果在 WAL 接收进程运行时修改该参数,则会向该进程发送信号使其关闭,并期望它使用新设置重新启动 + (除非 primary_conninfo 是空字符串)。 + 如果服务器没有处于备库模式,则此设置无效。 + + + - + + primary_slot_name (string) + + primary_slot_name 配置参数 + + + + + 有选择地指定通过流复制连接到发送服务器时使用一个现有的复制槽来控制上游节点上的资源移除(见)。 + 这个参数只能在 postgresql.conf文件或服务器命令行上设置。 + 如果在 WAL 接收进程运行时更改此参数,则会向该进程发送关闭信号,并预期它使用新设置重新启动。 + 如果没有设置primary_conninfo或服务器没有处于备库模式,则此设置无效。 + + + - autovacuum (boolean) - - autovacuum配置参数 - - - - - 控制服务器是否运行自动清理启动器后台进程。默认为开启, - 不过要自动清理正常工作还需要启用。 - 该参数只能在postgresql.conf文件或服务器命令行中设置, - 不过,通过更改表存储参数可以为表禁用自动清理。 - - - 注意即使该参数被禁用,系统也会在需要防止事务ID回卷时发起清理进程。详情请见。 + + promote_trigger_file (string) + + promote_trigger_file 配置参数 + + + + + 指定一个触发文件,该文件的存在会结束备库上的恢复。即使未设置此值,你仍然可以使用pg_ctl promote或调用 + pg_promote()来提升备库。 + 这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 + + + + + + hot_standby (boolean) + + hot_standby 配置参数 + + + + + 指定在恢复期间,你是否能够连接并运行查询,如中所述。默认值是on。这个参数只能在服务器启动时设置。它只在归档恢复期间或备库模式下才有效。 - - + + - - autovacuum_worker_slots (integer) - - autovacuum_worker_slots配置参数 - - - - - 指定为 autovacuum 工作进程保留的后端槽位数。默认通常是 16 个槽位,但如果内核设置不支持(如 initdb 期间所判定),则可能少于此数。 - 该参数只能在服务器启动时设置。 - - - 更改该值时,也应考虑调整。 - - - + + max_standby_archive_delay (integer) + + max_standby_archive_delay 配置参数 + + + + + 当热备处于活动状态时,此参数确定备库在取消与即将应用的WAL条目冲突的备库查询之前应等待多长时间,如 + 中所述。 + max_standby_archive_delay在从WAL归档中读取WAL数据时适用(因此不是当前的)。 + 如果未指定单位,则将其视为毫秒。 + 默认值为30秒。 + 值为-1允许备库永远等待冲突查询完成。 + 此参数只能在postgresql.conf文件或服务器命令行中设置。 + + 注意,max_standby_archive_delay并不等同于查询在被取消前可以运行的最长时间;它表示应用任意一个 WAL 段的数据所允许的最长总时间。因此,如果某个查询先前在处理该 WAL 段时已造成显著延迟,后续冲突查询的宽限时间就会短得多。 + + - + + max_standby_streaming_delay (integer) + + max_standby_streaming_delay 配置参数 + + + + + 当热备处于活动状态时,此参数确定备库在取消与即将应用的WAL条目冲突的备库查询之前应等待多长时间,如中所述。 + max_standby_streaming_delay在通过流复制接收WAL数据时应用。 + 如果未指定单位,则将其视为毫秒。 + 默认值为30秒。 + 值为-1允许备库永远等待冲突查询完成。 + 此参数只能在postgresql.conf文件或服务器命令行中设置。 + + 注意,max_standby_streaming_delay并不等同于查询在被取消前可以运行的最长时间;它表示从主库接收到 WAL 数据后,允许用于应用这些数据的最长总时间。因此,如果某个查询已造成显著延迟,后续冲突查询的宽限时间就会短得多,直到备库再次赶上进度。 + + - autovacuum_max_workers (integer) - - autovacuum_max_workers配置参数 - - - + + wal_receiver_create_temp_slot (boolean) + + wal_receiver_create_temp_slot 配置参数 + + + + 指定在未使用配置要使用的永久复制槽时,WAL 接收进程是否应在远程实例上创建临时复制槽。默认值为 off。此参数只能在postgresql.conf文件中或服务器命令行上设置。如果在 WAL 接收进程运行时更改此参数,则会向该进程发送信号使其关闭,并预期它使用新设置重新启动。 + + - - 指定能同时运行的自动清理进程(除了自动清理启动器之外)的最大数量。默认值为3。该参数只能在服务器启动时设置。 - - - 请注意,如果该值被设置得高于,将不会产生任何效果,因为 autovacuum 工作进程是从该设置建立的槽位池中获取的。 - - - + + wal_receiver_status_interval (integer) + + wal_receiver_status_interval 配置参数 + + + + + 指定在备库上的 WAL 接收进程向主库或上游备库发送有关复制进度的信息的最小频度,它可以使用pg_stat_replication视图看到。 + 备库将报告最后写入的预写日志位置、最后刷盘的位置以及最后应用的位置。 + 这个参数的值是报告之间的最大时间量。 + 每次写入或刷盘位置改变时会发送状态更新,或者按这个参数的指定的频度发送,如果设置为非零值。 + 在其他情况下发送更新时忽略此参数;例如,当现有的WAL处理完成或当synchronous_commit设置为remote_apply时。 + 因此,应用位置可能比真实位置略微滞后。 + 如果指定值时没有单位,则以秒为单位。 + 默认值是 10 秒。 + 这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 + + + - + + hot_standby_feedback (boolean) + + hot_standby_feedback 配置参数 + + + + + 指定一个热备机是否将会向主库或上游备库发送有关于备库上当前正被执行的查询的反馈。这个参数可以被用来消除由清理记录引起的查询取消,但是可能导致在主库上用于某些负载的数据库膨胀。反馈消息的发送频度不会高于每个wal_receiver_status_interval周期发送一次。默认值是off。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 + + + 如果使用级联复制,反馈将被向上游传递直到它最后到达主库。备库在接收到反馈之后除了传递给上游不会做任何其他操作。 + + + 此设置不会覆盖主库上old_snapshot_threshold的行为。 + 如果备库上的快照超过了主库的快照年龄阈值,它可能失效,从而导致备库上的事务被取消。 + 这是因为old_snapshot_threshold旨在为死行版本导致表膨胀的持续时间设定一个绝对限制, + 而备库的配置不应允许违反这个限制。 + + + - autovacuum_naptime (integer) + + wal_receiver_timeout (integer) + + wal_receiver_timeout 配置参数 + + + + + 中止处于非活动状态超过这个时间量的复制连接。这对于正在接收的备库检测主库崩溃或网络断开有用。 + 如果指定值时没有单位,则以毫秒为单位。默认值是 60 秒。值为零会禁用超时机制。 + 这个参数只能在postgresql.conf文件中或者服务器命令行中设置。 + + + + + + wal_retrieve_retry_interval (integer) + + wal_retrieve_retry_interval 配置参数 + + + + + 指定当从任何来源(流复制、本地pg_wal或者 WAL 归档)都得不到 WAL 数据时,备库应该等待多久才去重新尝试获取 WAL 数据。 + 如果指定值时没有单位,则以毫秒为单位。默认值是 5 秒。 + 这个参数只能在postgresql.conf文件或者服务器命令行中设置。 + + + 该参数在需要控制恢复中的节点等待新 WAL 数据可用的时间时非常有用。 + 例如,在归档恢复中,可以通过减小该参数的值来让系统更快地检测到新的 WAL 日志文件。 + 在 WAL 活动较少的系统上,增大该参数可以减少访问 WAL 归档所需的请求次数; + 例如在云环境中,这样做会很有用,因为基础设施被访问的次数会被纳入计费或配额考虑。 + + + + + + recovery_min_apply_delay (integer) - autovacuum_naptime配置参数 + recovery_min_apply_delay 配置参数 + + 默认情况下,备库会尽快恢复来自发送服务器的 WAL 记录。保留一份延迟的数据副本可能很有用,因为它提供了纠正数据丢失错误的机会。此参数允许将恢复延迟指定的时间。例如,将此参数设置为 5min 时,只有当备库系统时间比主库报告的提交时间至少晚五分钟,备库才会重放各事务的提交。如果没有指定单位,则以毫秒计。默认值为零,不增加延迟。 + + + 服务器之间的复制延迟可能超过此参数的值,这种情况下不会增加延迟。注意,延迟根据主库写入的 WAL 时间戳与备库当前时间之差计算。网络延迟或级联复制配置导致的传输延迟,可能显著缩短实际等待时间。如果主库和备库的系统时钟不同步,恢复时可能比预期更早应用记录;但这通常不是主要问题,因为此参数的实用取值远大于服务器间常见的时间偏差。 + + + 延迟仅发生在事务提交的 WAL 记录上。其他记录会尽快重放;这不会造成问题,因为 MVCC 可见性规则确保在对应提交记录被应用之前,它们的效果不会可见。 + + + 恢复中的数据库达到一致状态后开始延迟,直到备库被提升或触发。此后,备库会结束恢复,不再等待。 + + + WAL 记录必须保留在备库上,直到可以应用它们。因此,更长的延迟会导致更多 WAL 文件积压,增加备库 pg_wal 目录所需的磁盘空间。 + + + 此参数旨在用于流复制部署;不过,只要指定了此参数,它就会在除崩溃恢复以外的所有情况下生效。使用此功能也会延迟 hot_standby_feedback,可能导致主库膨胀;同时使用两者时应谨慎。 + + + 当 synchronous_commit 设置为 remote_apply 时,同步复制会受到此设置影响;每个 COMMIT 都必须等待提交被应用。 + + + - 指定自动清理在任意给定数据库上运行的最小延迟。在每一轮中后台进程检查数据库并根据需要为数据库中的表发出VACUUMANALYZE命令。 - 如果指定值时没有单位,则以秒为单位。默认值为1分钟(1min)。该参数只能在postgresql.conf文件或在服务器命令行上设置。 + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 - - + + + + - - autovacuum_vacuum_max_threshold (integer) - - autovacuum_vacuum_max_threshold配置参数 - - - - - 指定在任意一个表上触发VACUUM所需更新或删除元组数的最大值,也就是对 - autovacuum_vacuum_threshold和 - autovacuum_vacuum_scale_factor计算结果所施加的上限。 - 默认值为 100,000,000 个元组。如果指定为-1,autovacuum 将不会对触发 - VACUUM所需的更新或删除元组数强制施加最大值。 - 该参数只能在postgresql.conf文件中或服务器命令行上设置;但可以通过更改表存储参数覆盖单个表的该设置。 - - - + + 订阅者 - + + 这些设置控制逻辑复制订阅者的行为。它们在发布者上的值与此无关。 + - autovacuum_vacuum_threshold (integer) + + 注意,配置参数wal_receiver_timeoutwal_receiver_status_interval以及wal_retrieve_retry_interval也影响逻辑复制工作进程。 + + + + + + max_logical_replication_workers (integer) + + max_logical_replication_workers 配置参数 + + + + + 指定逻辑复制工作进程的最大数量,其中包括应用工作进程和表同步工作进程。 + + + 逻辑复制工作进程来自max_worker_processes定义的进程池。 + + + 默认值是 4。此参数只能在服务器启动时设置。 + + + + + + max_sync_workers_per_subscription (integer) + + max_sync_workers_per_subscription 配置参数 + + + + + 每个订阅允许的最大同步工作进程数。该参数控制订阅初始化时或新增表时初始数据复制的并行度。 + + + 目前,每个表只能有一个同步工作进程。 + + + 同步工作进程来自max_logical_replication_workers定义的进程池。 + + + 默认值是 2。此参数只能在postgresql.conf文件中或服务器命令行上设置。 + + + + + + + + + + + 查询规划 + + + + 规划器方法配置 + + + 这些配置参数提供了一种较为粗糙的方法,用于影响查询优化器所选择的查询计划。 + 如果优化器为某个特定查询选择的默认计划并不理想,一种临时解决方案是使用这些配置参数, + 强制优化器选择另一种计划。 + 改善优化器所选计划质量的更好办法包括调整规划器代价常数 + (见)、手工运行 + ANALYZE、增加 + 配置参数的值,以及使用 + ALTER TABLE SET STATISTICS 增加为特定列收集的统计信息量。 + + + + + + enable_async_append (boolean) - autovacuum_vacuum_threshold - 配置参数 + enable_async_append 配置参数 - - 指定能在一个表上触发VACUUM的被更新或被删除元组的最小数量。默认值为50个元组。该参数只能在postgresql.conf文件或在服务器命令中设置。但是对个别表可以通过修改表存储参数来覆盖该设置。 + 允许或禁止查询规划器使用异步感知的 append 计划类型。默认值是 + on - - - autovacuum_vacuum_insert_threshold (integer) + + enable_bitmapscan (boolean) - autovacuum_vacuum_insert_threshold - 配置参数 + 位图扫描 + + + enable_bitmapscan 配置参数 - - 指定在任何一个表中触发 VACUUM所需要插入的元组数。默认值为 1000 个元组。 - 如果指定了 -1,则autovacuum不会根据插入数量在任何表上触发 VACUUM操作。 - 此参数只能在postgresql.conf文件或服务器命令行中设置;但可以通过更改表存储参数来覆盖单个表的设置。 + 启用或禁用查询规划器对位图扫描计划类型的使用。默认值为 on - - - autovacuum_analyze_threshold (integer) + + enable_gathermerge (boolean) - autovacuum_analyze_threshold - 配置参数 + enable_gathermerge 配置参数 - - 指定能在一个表上触发ANALYZE的被插入、被更新或被删除元组的最小数量。默认值为50个元组。该参数只能在postgresql.conf文件或在服务器命令中设置。但是对个别表可以通过修改表存储参数来覆盖该设置。 + 启用或禁用查询规划器对收集归并计划类型的使用。默认值为 on - - - autovacuum_vacuum_scale_factor (floating point) + + enable_hashagg (boolean) - autovacuum_vacuum_scale_factor - 配置参数 + enable_hashagg 配置参数 - - 指定一个表尺寸的分数,在决定是否触发VACUUM时将它加到autovacuum_vacuum_threshold上。默认值为0.2(表尺寸的20%)。该参数只能在postgresql.conf文件或在服务器命令中设置。但是对个别表可以通过修改表存储参数来覆盖该设置。 + 启用或禁用查询规划器对哈希聚合计划类型的使用。默认值为 on - - - autovacuum_vacuum_insert_scale_factor (floating point) + + enable_hashjoin (boolean) - autovacuum_vacuum_insert_scale_factor - 配置参数 + enable_hashjoin 配置参数 - - 指定一个要添加到autovacuum_vacuum_insert_threshold 中的表的大小的比例,在决定是否触发VACUUM时。 - 默认值为 0.2(表大小的 20%)。此参数只能在postgresql.conf文件或服务器命令行中设置;但可以通过更改表存储参数来覆盖单个表的设置。 + 启用或禁用查询规划器对哈希连接计划类型的使用。默认值为 on - - - autovacuum_analyze_scale_factor (floating point) + + enable_incremental_sort (boolean) - autovacuum_analyze_scale_factor - 配置参数 + enable_incremental_sort 配置参数 - - 指定一个表尺寸的分数,在决定是否触发ANALYZE时将它加到autovacuum_analyze_threshold上。默认值为0.1(表尺寸的10%)。该参数只能在postgresql.conf文件或在服务器命令中设置。但是对个别表可以通过修改表存储参数来覆盖该设置。 + 启用或禁用查询规划器对增量排序步骤的使用。默认值为 on - - - autovacuum_freeze_max_age (integer) + + enable_indexscan (boolean) - autovacuum_freeze_max_age - 配置参数 + 索引扫描 + + + enable_indexscan 配置参数 - - 指定在一个VACUUM操作被强制执行来防止表中事务ID回卷之前,一个表的pg_class.relfrozenxid域能保持的最大年龄(事务的)。注意即便自动清理被禁用,系统也将发起自动清理进程来阻止回卷。 + 启用或禁用查询规划器对索引扫描和仅索引扫描计划类型的使用。默认值为 on。另请参见 + + + + enable_indexonlyscan (boolean) + + enable_indexonlyscan 配置参数 + + + - 清理也允许从pg_xact子目录中移除旧文件,这也是为什么默认值被设置为较低的2亿事务。该参数只能在服务器启动时设置,但是对于个别表可以通过修改表存储参数来降低该设置。详见。 + 启用或禁用查询规划器对仅索引扫描计划类型的使用(参见 )。默认值为 on。还必须启用 ,查询规划器才会考虑仅索引扫描。 - - - autovacuum_multixact_freeze_max_age (integer) + + enable_material (boolean) - autovacuum_multixact_freeze_max_age - 配置参数 + enable_material 配置参数 - 指定在一个VACUUM操作被强制执行来防止表中多事务ID回卷之前,一个表的pg_class.relminmxid域能保持的最大年龄(多事务的)。注意即便自动清理被禁用,系统也将发起自动清理进程来阻止回卷。 + 允许或者禁止查询规划器使用物化。它不可能完全禁用物化,但是关闭这个变量将阻止规划器插入物化节点,除非为了保证正确性。默认值是on + + + + + enable_memoize (boolean) + + enable_memoize 配置参数 + + + - 清理多事务也允许从pg_multixact/memberspg_multixact/offsets子目录中移除旧文件,这也是为什么默认值被设置为较低的4亿个多事务。该参数只能在服务器启动时设置,但是对于个别表可以通过修改表存储参数来降低该设置。详见。 + 启用或禁用查询规划器对memoize计划的使用,以便缓存在嵌套循环连接中参数化扫描的结果。 + 在当前参数的结果已经在缓存中时,此计划类型允许跳过对底层计划的扫描。 + 当新条目需要更多空间时,不太常用的查询结果可能会从缓存中去除。 + 默认值是on - - - autovacuum_vacuum_cost_delay (floating point) + + enable_mergejoin (boolean) - autovacuum_vacuum_cost_delay - 配置参数 + enable_mergejoin 配置参数 - - 指定用于自动VACUUM操作中的代价延迟值。如果指定-1,则使用值。 - 如果指定值时没有单位,则以毫秒为单位。默认值为2毫秒。该参数只能在postgresql.conf文件或在服务器命令中设置。但是对个别表可以通过修改表存储参数来覆盖该设置。 + 启用或禁用查询规划器对归并连接计划类型的使用。默认值为 on - - - autovacuum_vacuum_cost_limit (integer) + + enable_nestloop (boolean) - autovacuum_vacuum_cost_limit - 配置参数 + enable_nestloop 配置参数 - 指定用于自动VACUUM操作中的代价限制值。如果指定-1(默认值),则使用值。注意该值被按比例地分配到运行中的自动清理工作者上(如果有多个),因此每一个工作者的限制值之和不会超过这个变量中的值。该参数只能在postgresql.conf文件或在服务器命令中设置。但是对个别表可以通过修改表存储参数来覆盖该设置。 + 允许或禁止查询规划器使用嵌套循环连接计划。它不可能完全禁止嵌套循环连接,但是关闭这个变量将使得规划器尽可能优先使用其他方法。默认值是on - - - - - 默认行为 - - - - vacuum_truncate (boolean) + + enable_parallel_append (boolean) - vacuum_truncate配置参数 + enable_parallel_append 配置参数 - 启用或禁用 vacuum 尝试截断表末尾的空页。默认值为true。 - 如果为true,则VACUUM和 autovacuum 会执行截断,并将这些页面占用的磁盘空间返还给操作系统。 - 请注意,截断需要获取表上的ACCESS EXCLUSIVE锁。 - 如果在VACUUM中指定了TRUNCATE参数,它将覆盖该参数的值。 - 也可以通过修改表存储参数来为单个表覆盖此设置。 + 允许或禁止查询规划器使用并行感知的 append 计划类型。默认值是 + on - - - - 冻结 (Freezing) - - 这些设置控制旧行版本的冻结。更多信息请参阅。 - - - - vacuum_freeze_table_age (integer) - - vacuum_freeze_table_age配置参数 - + + enable_parallel_hash (boolean) + + enable_parallel_hash 配置参数 + - 当表的pg_class.relfrozenxid字段达到该设置指定的年龄时,VACUUM会执行激进扫描。激进扫描与常规VACUUM不同,它会访问每一个可能包含未冻结 XID 或 MXID 的页面,而不仅仅是那些可能包含死元组的页面。默认值是 1.5 亿个事务。尽管用户可以将该值设置为 0 到 20 亿之间的任意值,VACUUM会悄悄将有效值调整为的 95%,从而在触发防回卷 autovacuum 之前仍有机会执行一次常规手工VACUUM。更多信息请参见。 + 启用或禁用查询规划器对使用并行哈希的哈希连接计划类型的使用。如果没有同时启用哈希连接计划,此参数不起作用。默认值为 on - - vacuum_freeze_min_age (integer) - - vacuum_freeze_min_age配置参数 - + + + enable_partition_pruning (boolean) + + enable_partition_pruning配置参数 + + - 指定VACUUM在扫描表时用来决定是否冻结行版本的切断年龄(以事务计)。默认值是 5000 万个事务。尽管用户可以将该值设置为 0 到 10 亿之间的任意值,VACUUM会悄悄将有效值调整为的一半,这样强制 autovacuum 之间就不会间隔过短。更多信息请参见。 + 允许或者禁止查询规划器从查询计划中消除一个分区表的分区。这也控制着规划器产生允许执行器在查询执行期间移除(忽略)分区的查询计划的能力。默认值是on。详情请参考 - - vacuum_failsafe_age (integer) + + enable_partitionwise_join (boolean) - vacuum_failsafe_age配置参数 + enable_partitionwise_join 配置参数 - 指定表的pg_class.relfrozenxid字段在VACUUM采取特别措施以避免系统范围事务 ID 回卷失败之前所允许达到的最大年龄(以事务计)。这是VACUUM的最后防线。失效保护通常会在防止事务 ID 回卷的 autovacuum 已经运行了一段时间后触发,但也有可能在任何VACUUM期间触发。 - - - 当失效保护被触发时,将不再应用任何有效的基于成本的延迟,并且会跳过进一步的非关键维护任务(例如索引 vacuum)。 - - - 默认值为 16 亿个事务。尽管用户可以将该值设置为 0 到 21 亿之间的任意值,VACUUM会悄悄将有效值调整为不低于的 105%。 + 启用或禁用查询规划器对分区连接的使用,使分区表之间的连接可以通过连接相匹配的分区来完成。分区连接目前仅适用于连接条件包含所有分区键的情况;这些分区键必须具有相同的数据类型,并且子分区集合必须一一匹配。启用此设置后,最终计划中内存用量受 work_mem 限制的节点数量可能随所扫描分区的数量线性增加。这可能大幅增加查询执行期间的总内存消耗。查询规划在内存和 CPU 方面的开销也会显著增加。默认值为 off - - vacuum_multixact_freeze_table_age (integer) + + enable_partitionwise_aggregate (boolean) - vacuum_multixact_freeze_table_age配置参数 + enable_partitionwise_aggregate 配置参数 - 当表的pg_class.relminmxid字段达到该设置指定的年龄时,VACUUM会执行激进扫描。激进扫描与常规VACUUM不同,它会访问每一个可能包含未冻结 XID 或 MXID 的页面,而不是只扫描那些可能包含死元组的页面。默认值是 1.5 亿个 multixact。尽管用户可以将该值设置为 0 到 20 亿之间的任意值,VACUUM会悄悄将有效值调整为的 95%,从而在触发防回卷 autovacuum 之前仍有机会执行一次常规手工VACUUM。更多信息请参见。 + 启用或禁用查询规划器对分区分组或聚合的使用,使分区表上的分组或聚合可以在各个分区上分别执行。如果 GROUP BY 子句不包含分区键,则只能在各分区上执行部分聚合,随后还必须进行最终处理。启用此设置后,最终计划中内存用量受 work_mem 限制的节点数量可能随所扫描分区的数量线性增加。这可能大幅增加查询执行期间的总内存消耗。查询规划在内存和 CPU 方面的开销也会显著增加。默认值为 off - - vacuum_multixact_freeze_min_age (integer) + + + enable_seqscan (boolean) - vacuum_multixact_freeze_min_age配置参数 + 顺序扫描 + + + enable_seqscan配置参数 + - 指定VACUUM在扫描表时用来决定是否将 multixact ID 替换为较新的事务 ID 或 multixact ID 的切断年龄(以 multixact 计)。默认值是 5000 万个 multixact。尽管用户可以将该值设置为 0 到 10 亿之间的任意值,VACUUM会悄悄将有效值调整为的一半,这样强制 autovacuum 之间就不会间隔过短。更多信息请参见。 + 允许或禁止查询规划器使用顺序扫描计划类型。它不可能完全禁止顺序扫描,但是关闭这个变量将使得规划器尽可能优先使用其他方法。默认值是on - - vacuum_multixact_failsafe_age (integer) + + + enable_sort (boolean) - vacuum_multixact_failsafe_age配置参数 + enable_sort配置参数 + - 指定表的pg_class.relminmxid字段在VACUUM采取特别措施以避免系统范围 multixact ID 回卷失败之前所允许达到的最大年龄(以 multixact 计)。这是VACUUM的最后防线。失效保护通常会在防止事务 ID 回卷的 autovacuum 已经运行了一段时间后触发,但也有可能在任何VACUUM期间触发。 - - - 当失效保护被触发时,将不再应用任何有效的基于成本的延迟,并且会跳过进一步的非关键维护任务(例如索引 vacuum)。 - - - 默认值为 16 亿个 multixact。尽管用户可以将该值设置为 0 到 21 亿之间的任意值,VACUUM会悄悄将有效值调整为不低于的 105%。 + 允许或禁止查询规划器使用显式排序步骤。它不可能完全禁止显式排序,但是关闭这个变量将使得规划器尽可能优先使用其他方法。默认值是on - - vacuum_max_eager_freeze_failure_rate (floating point) + + + enable_tidscan (boolean) - vacuum_max_eager_freeze_failure_rate配置参数 + enable_tidscan配置参数 + - 指定VACUUM在积极扫描模式下可以扫描但未能在可见性映射中设置为 all-frozen 的页面数量占整个关系总页面数的比例,超过该比例后就会禁用积极扫描。值0表示完全禁用积极扫描。默认值为0.03(3%)。 - - - 请注意,当积极扫描启用时,只有冻结失败才会计入上限,成功的冻结不会计入。成功冻结的页面在内部会被限制为关系中所有 all-visible 但未 all-frozen 页面数的 20%。对成功冻结页面设置上限有助于将成本分摊到多次常规 vacuum 中,并限制在下次积极 vacuum 之前页面再次被修改时积极冻结可能带来的浪费。 - - - 这个参数只能在postgresql.conf文件中或服务器命令行上设置; - 但也可以通过修改 - 对应的表存储参数 - 为单个表覆盖该设置。关于调整清理冻结行为的更多信息,见 - 。 + 允许或禁止查询规划器使用TID扫描计划类型。默认值是on - - - - + + + - 客户端连接默认值 + 规划器代价常量 - + + 这一节中描述的代价变量可以按照任意尺度衡量。我们只关心它们的相对值,将它们以相同的因子缩放不会影响规划器的选择。默认情况下,这些代价变量是基于顺序页面获取的代价的,即seq_page_cost被设置为1.0并且其他代价变量都参考它来设置。不过你可以使用你喜欢的不同尺度,例如在一个特定机器上的真实执行时间。 + + + + + + 不幸的是,没有一种良定义的方法来决定代价变量的理想值。它们最好被作为一个特定安装将接收到的查询的平均值来对待。这意味着基于少量的实验来改变它们是有风险的。 + + - 语句行为 - + - client_min_messages (enum) + seq_page_cost (floating point) - client_min_messages配置参数 + seq_page_cost配置参数 - 控制被发送给客户端的消息级别。有效值是DEBUG5、 - DEBUG4DEBUG3DEBUG2、 - DEBUG1LOGNOTICE、 - WARNINGERROR。 - 每个级别都包括其后的所有级别。级别越靠后,被发送的消息越少。默认值是NOTICE。 - 注意LOG在这里有与中不同的排名。 - - - - INFO 级别的消息总是被发送到客户端。 + 设置规划器对一系列顺序磁盘页面获取中的一次的代价估计。默认值是 1.0。通过把表和索引放在一个特殊的表空间(要设置该表空间的同名参数)中可以覆盖这个值(见)。 - + - search_path (string) + random_page_cost (floating point) - search_path配置参数 + random_page_cost配置参数 - pathfor schemas - 这个变量指定当一个对象(表、数据类型、函数等)被用一个无模式限定的简单名称引用时,用于进行搜索该对象的模式顺序。当在不同模式中有同名对象时,将使用第一个在搜索路径中被找到的对象。一个不属于搜索路径中任何一个模式的对象只能通过用限定名(带点号)指定包含它的模式来引用。 - - - - search_path的值必需是一个逗号分隔的模式名列表。任何不是一个已有模式的名称,或者是一个用户不具有USAGE权限的模式,将被安静地忽略。 - - - - 如果列表项之一是特殊名$user,则具有SESSION_USER返回的名字的模式将取代它(如果有这样一个模式并且该用户有该模式的USAGE权限;如果没有,$user会被忽略)。 - - - - 系统目录模式pg_catalog总是被搜索,不管它是否在搜索路径中被提及。如果它在路径中被提及,那么它将被按照路径指定的顺序搜索。如果pg_catalog不在路径中,则它将在任何路径项之前被搜索。 - - - - - - 同样,如果存在,当前会话的临时表模式pg_temp_nnn总是被搜索。 - 可以通过使用别名pg_temppg_temp在路径中显式列出它。 - 如果它没有列在路径中,则首先搜索它(甚至在pg_catalog之前)。 - 然而,临时模式仅用于搜索关系(表、视图、序列等)和数据类型名称。 - 它永远不会用于搜索函数或操作符名称。 + 设置规划器对一次非顺序获取磁盘页面的代价估计。默认值是 4.0。通过把表和索引放在一个特殊的表空间(要设置该表空间的同名参数)中可以覆盖这个值(见)。 - 当对象创建时没有指定一个特定目标模式,它们将被放置在search_path中第一个合法模式中。如果搜索路径为空将报告一个错误。 + 减少这个值(相对于seq_page_cost)将导致系统更倾向于索引扫描;提高它将让索引扫描看起来相对更昂贵。你可以一起提高或降低两个值来改变磁盘 I/O 代价相对于 CPU 代价的重要性,后者由下列参数描述。 - 这个参数的缺省值是"$user", public。这种设置支持一个数据库(其中没有用户拥有私有模式,并且所有人共享使用public)、每个用户私有模式及其组合的共享使用。其它效果可以通过全局或者针对每个用户修改默认搜索路径设置获得。 + 对持久存储的随机访问通常远不止比顺序访问贵四倍。不过,仍使用较低的默认值(4.0),因为假定对存储的大多数随机访问(例如索引读取)都将在缓存中命中。此外,网络附加存储的延迟往往会降低随机访问的相对额外开销。 - 更多有关方案处理的信息,请参考。特别地,只有当数据库只有一个用户或者有少数的相互信任的用户时,默认配置是合适的。 + 如果你认为缓存命中的频率低于默认值所反映的情况,并且网络延迟很低,则可以增大 + random_page_cost,以更好地反映随机存储读取的真实代价。相反,若某种存储的随机读取代价相对于顺序读取更高,例如机械磁盘,也可以用更高的 random_page_cost 值来更好地建模。对应地,如果你的数据很可能完全缓存在内存中,例如数据库小于服务器总内存,或者网络延迟较高,则降低 random_page_cost 可能更合适。 - - 搜索路径的当前有效值可以通过SQL函数current_schemas检查(见)。它和检查search_path的值不太一样,因为current_schemas显示出现在search_path中的项如何被解析。 - + + + 尽管允许你将random_page_cost设置得小于seq_page_cost,但实际上这样没有意义。不过,如果数据库被整个缓存在 RAM 中,将它们设置为相等是合理的,因为在这种情况下,非顺序访问页面并不会产生额外代价。同样,在一个高度缓存化的数据库中,你应该相对于 CPU 参数降低这两个值,因为获取一个已经在 RAM 中的页面的代价要远小于通常情况下的代价。 + + - + - row_security (boolean) + cpu_tuple_cost (floating point) - row_security 配置参数 + cpu_tuple_cost配置参数 - 这个变量控制是否以抛出一个错误来代替应用一条行安全性策略。在设置为on时,策略正常应用。在设置为off时,只要有至少一条策略被应用则查询就会失败。默认为on。受限的行可见性会导致不正确的结果时,可将其改成off。例如,pg_dump默认会做这种更改。这个变量对能绕过每一条行安全性策略的角色(即超级用户和具有BYPASSRLS)属性的角色没有效果。 - - - - 更多关于行安全性策略的信息请见。 + 设置规划器对一次查询中处理每一行的代价估计。默认值是 0.01。 - + - default_table_access_method (string) + cpu_index_tuple_cost (floating point) - default_table_access_method 配置参数 + cpu_index_tuple_cost配置参数 - 这个参数指定了在创建表或物化视图时使用的默认表访问方法,如果CREATE命令没有明确指定访问方法, - 或者当使用SELECT ... INTO时,不允许指定表访问方法。默认值是heap。 + 设置规划器对一次索引扫描中处理每一个索引项的代价估计。默认值是 0.005。 - + - default_tablespace (string) + cpu_operator_cost (floating point) - default_tablespace配置参数 + cpu_operator_cost配置参数 - tablespacedefault - 这个变量指定当一个CREATE命令没有显式指定一个表空间时,创建对象(表和索引)的默认表空间。 + 设置规划器对于一次查询中处理每个操作符或函数的代价估计。默认值是 0.0025。 + + - - 该值要么是一个表空间的名字,要么是一个指定使用当前数据库默认表空间的空字符串。如果该值和任何现有表空间的名字都不匹配,PostgreSQL将自动使用当前数据库的默认表空间。如果指定了一个非默认的表空间,用户必须对它有CREATE权限,否则创建企图将失败。 - + - - 这个变量不被用于临时表,对临时表会使用。 - + parallel_setup_cost (floating point) + + parallel_setup_cost 配置参数 + + + - 当创建数据库时也会使用这个变量。默认情况下,一个新数据库会从它的模板数据库继承其表空间设置。 + 设置规划器对启动并行工作者进程的代价估计。默认是 1000。 + + - - 当一个分区表建立时如果这个参数被设置为空字符串以外的值,分区表的表空间将被设置为该值,将被用做未来建立分区的默认表空间, - 即使default_tablespace已经改变。 - + + + parallel_tuple_cost (floating point) + + parallel_tuple_cost 配置参数 + + + - 有关表空间的更多的信息,请见。 + 设置规划器对于从一个并行工作者进程传递一个元组给另一个进程的代价估计。默认是 0.1。 - + - default_toast_compression (enum) + min_parallel_table_scan_size (integer) - default_toast_compression 配置参数 + min_parallel_table_scan_size配置参数 - 这个变量设置可压缩列的值所使用的默认TOAST压缩方法。 - (可以在CREATE TABLEALTER TABLE中为单独的列设置 - COMPRESSION列选项,从而覆盖该默认值。) - 支持的压缩方法有pglz,以及 - (如果PostgreSQL编译时启用了) - lz4。默认值为pglz。 + 为必须扫描的表数据量设置一个最小值,扫描的表数据量超过这一个值才会考虑使用并行扫描。 + 对于并行顺序扫描,被扫描的表数据量总是等于表的尺寸,但是在使用索引时,被扫描的表数据量通常会更小。 + 如果指定值时没有单位,则以块为单位,即BLCKSZ字节,通常为8kB。默认值是8兆字节(8MB)。 - + - temp_tablespaces (string) + min_parallel_index_scan_size (integer) - temp_tablespaces配置参数 + min_parallel_index_scan_size配置参数 - 表空间临时 - 这个变量指定当一个CREATE命令没有显式指定一个表空间时,创建临时对象(临时表和临时表上的索引)的默认表空间。用于排序大型数据集的临时文件也被创建在这些表空间中。 - - - - 该值是一个表空间名字的列表。当列表中有多于一个名称时,每次一个临时对象被创建时PostgreSQL随机选择列表中的一个成员。例外是在一个事务中,连续创建的临时对象被放置在里表中的连续表空间中。如果列表被选中元素是一个空字符串,PostgreSQL将自动使用当前数据库的默认表空间。 + 为必须扫描的索引数据量设置一个最小值,扫描的索引数据量超过这一个值时才会考虑使用并行扫描。 + 注意并行索引扫描通常并不会触及整个索引,它是规划器认为该扫描会实际用到的相关页面的数量。 + 这个参数还用于决定特定的索引是否参与并行vacuum。参见。 + 如果指定值时没有单位,则以块为单位,即BLCKSZ字节,通常为8kB。默认值是512千字节(512kB)。 + + - - 当temp_tablespaces被交互式地设置时,指定一个不存在的表空间是一种错误,类似于为用户指定一个不具有CREATE权限的表空间。不过,当使用一个之前设置的值时,不存在的表空间会被忽略,就像用户缺少CREATE权限的表空间一样。特殊地,使用一个在postgresql.conf中设置的值时,这条规则起效。 - + - - 默认值是一个空字符串,它使得所有临时对象被创建在当前数据库的默认表空间中。 - + effective_cache_size (integer) + + effective_cache_size配置参数 + + + - 参阅。 + 设置规划器对一个单一查询可用的有效磁盘缓冲区尺寸的假设。 + 这个参数会被考虑在使用一个索引的代价估计中,更高的数值会使得索引扫描更可能被使用,更低的数值会使得顺序扫描更可能被使用。 + 在设置这个参数时,你还应该考虑PostgreSQL的共享缓冲区以及将被用于PostgreSQL数据文件的内核磁盘缓冲区,尽管有些数据可能在两个地方都存在。 + 另外,还要考虑预计在不同表上的并发查询数目,因为它们必须共享可用的空间。 + 这个参数对PostgreSQL分配的共享内存尺寸没有影响,它也不会保留内核磁盘缓冲,它只用于估计的目的。系统也不会假设在查询之间数据会保留在磁盘缓冲中。 + 如果指定值时没有单位,则以块为单位,即BLCKSZ字节,通常为8kB。 + 默认值是 4吉字节(4GB)。(如果BLCKSZ不是8kB,默认值会按比例缩放它。) - + - check_function_bodies (boolean) + jit_above_cost (floating point) - check_function_bodies配置参数 + jit_above_cost配置参数 - 这个参数通常为打开。 - 当设置为off时,它禁用期间对例程体字符串的验证。 - 禁用验证避免了验证处理的副作用,特别避免了如向前引用导致的伪肯定。 - 在代表其他用户载入函数之前设置这个参数为offpg_dump会自动这样做。 + 设置激活JIT编译的查询代价,如果查询代价超过这个值就会激活JIT编译(如果启用了JIT,见)。执行JIT会消耗一些规划时间,但是能够加速查询执行。将这个值设置为-1会禁用JIT编译。默认值是100000 - + - default_transaction_isolation (enum) - - transaction isolation level - 设置默认值 - + jit_inline_above_cost (floating point) - default_transaction_isolation配置参数 + jit_inline_above_cost配置参数 - 每个 SQL 事务都有一个隔离级别,可以是读未提交读已提交可重复读或者可串行化。这个参数控制每个新事务的默认隔离级别。默认是读已提交。 - - - - 更多信息请参阅。 + 设置JIT编译尝试内联函数和操作符的查询代价阈值,如果查询代价超过这个值,JIT编译就会尝试内联。内联会增加规划时间,但是可以提高执行速度。将这个参数设置成小于jit_above_cost是没有意义的。将这个参数设置为-1会禁用内联。默认值是500000 - + - default_transaction_read_only (boolean) - - read-only transaction - 设置默认值 - + jit_optimize_above_cost (floating point) - default_transaction_read_only配置参数 + jit_optimize_above_cost配置参数 - 一个只读的 SQL 事务不能修改非临时表。这个参数控制每个新事务的默认只读状态 。默认是off(读/写)。 - - - - 更多信息请参考。 + 设置JIT编译应用优化的查询代价阈值,如果查询代价超过这个值,JIT编译就会应用开销较大的优化。这类优化会增加规划时间,但是更能够改进执行速度。将这个参数设置成小于jit_above_cost是没有意义的,并且将它设置成大于jit_inline_above_cost也未必有益。将这个参数设置为-1会禁用开销较大的优化。默认值是500000 - + - default_transaction_deferrable (boolean) + + + + 遗传查询优化 + + + GEQO是一个使用探索式搜索来执行查询规划的算法。它可以降低负载查询的规划时间。 同时,GEQO的检索是随机的,因此它的规划可能会不可确定。 更多信息参阅Chapter 50。 + 遗传查询规划器(GEQO)是一种使用启发式搜索来进行查询规划的算法。它可以降低对于复杂查询(连接很多表的查询)的规划时间,但是代价是它产生的计划有时候要差于使用穷举搜索算法找到的计划。详见。 + + + + + + + geqo (boolean) - deferrable transaction - 设置默认值 + 遗传查询优化 - default_transaction_deferrable配置参数 + GEQO + 遗传查询优化 + + + geqo配置参数 - 当运行在可串行化隔离级别时,一个可延迟只读 SQL 事务可以在它被允许继续之前延迟一段时间。但是,一旦它开始执行就不会产生任何用来保证可串行化性的负荷;因此串行化代码将没有任何理由因为并发更新而强制它中断,使得这个选项适合于长时间运行的只读事务。 - - - - 这个参数控制每个新事务的默认可延迟状态。目前它对读写事务或者那些操作在低于可串行化隔离级别上的事务无效。默认值是off。 - - - - 更多信息请参考。 + 允许或禁止遗传查询优化。默认是启用。在生产环境中通常最好不要关闭它。geqo_threshold变量提供了对 GEQO 更细粒度的空值。 - + - transaction_isolation (enum) - - transaction isolation level - + geqo_threshold (integer) - transaction_isolation配置参数 + geqo_threshold配置参数 - 此参数反映当前事务的隔离级别。在每个事务开始时,它被设置为 - 的当前值。 - 任何后续更改它的尝试都相当于命令。 + 只有当涉及的FROM项数量至少有这么多个的时候,才使用遗传查询优化(注意一个FULL OUTER JOIN只被计为一个FROM项)。默认值是 12。对于更简单的查询,通常会使用普通的穷举搜索规划器,但是对于有很多表的查询穷举搜索会花很长时间,通常比执行一个次优的计划带来的惩罚值还要长。因此,在查询尺寸上的一个阈值是管理 GEQO 使用的一种方便的方法。 - + - transaction_read_only (boolean) - - read-only transaction - + geqo_effort (integer) - transaction_read_only 配置参数 + geqo_effort配置参数 - 此参数反映当前事务的只读状态。 - 在每个事务的开始,它被设置为的当前值。 - 任何后续尝试更改它的都等同于命令。 + 控制 GEQO 里规划时间和查询规划的有效性之间的平衡。这个变量必须是 一个范围从 1 到 10 的整数。缺省值是 5 。大的数值增加花在进行查询 规划上面的时间,但是也很可能会提高选中更有效的查询规划的几率。 + 控制 GEQO 中规划时间和查询计划质量之间的折中。这个变量必须是位于 1 到 10 之间的一个整数。默认值是 5。更大的值会增加花在查询规划上的时间,但是同时也增加了选择一个高效查询计划的可能性。 + + + + geqo_effort实际并不直接做任何事情;它只是被用来计算其他影响 GEQO 行为的变量(如下所述)的默认值。如果你愿意,你可以手工设置其他参数。 - + - transaction_deferrable (boolean) - - deferrable transaction - + geqo_pool_size (integer) - transaction_deferrable 配置参数 + geqo_pool_size配置参数 - 此参数反映当前事务的可延迟性状态。 - 在每个事务的开始,它被设置为的当前值。 - 任何后续尝试更改它的都等同于命令。 + 控制 GEQO 使用的池尺寸,它就是遗传种群中的个体数目。它必须至少为 2,且有用的值通常在 100 到 1000 之间。如果它被设置为零(默认设置)则会基于geqo_effort和查询中表的数量选择一个合适的值。 - + - session_replication_role (enum) + geqo_generations (integer) - session_replication_role配置参数 + geqo_generations配置参数 - 控制当前会话中复制相关触发器和规则的触发。 - 可能的值是origin(默认值), - replicalocal。 - 设置此参数会导致丢弃先前缓存的任何查询计划。 - 只有超级用户和具有适当SET权限的用户才能更改此设置。 + 控制 GEQO 使用的子代数目。子代的意思是算法的迭代次数。它必须至少 是 1 ,有用的值范围和池大小相同。如果设置为零(缺省),那么将基于 geqo_pool_size选取合适的值。 + 控制 GEQO 使用的代数,也是算法的迭代次数。它必须至少为 1,并且有用值的范围和池尺寸相同。如果它被设置为零(默认设置)则会基于geqo_pool_size选择一个合适的值。 + + - - 这个设置的预期用途是由逻辑复制系统在应用所复制的更改时将它设置为replica。 - 其效果将是触发器和规则(没有对其默认配置做修改)在复制机上将不会被触发。 - 更多信息请参考ALTER TABLE的子句ENABLE TRIGGER以及ENABLE RULE。 - + - - PostgreSQL在内部会把设置originlocal同样对待。第三方复制系统可能会把这两个值用于其内部目的,例如把local用来标出一个不应复制其更改的会话。 - + geqo_selection_bias (floating point) + + geqo_selection_bias配置参数 + + + - 因为外键被实现为触发器,将这个参数设置为replica还会禁用所有的外键检查,如果使用不当可能会让数据处于一种不一致的状态。 + 控制 GEQO 使用的选择偏好。选择偏好是种群中的选择压力。值可以是 1.5 到 2.0 之间,后者是默认值。 - + - statement_timeout (integer) + geqo_seed (floating point) - statement_timeout配置参数 + geqo_seed配置参数 - 中止任何使用了超过指定时间量的语句。 - 如果log_min_error_statement被设置为ERROR或更低,语句如果超时也会被记录。 - 如果指定值时没有单位,则以毫秒为单位。一个零值(默认)将禁用超时。 - - - - 超时从命令到达服务器的时间开始计算,一直到它被服务器完成为止。 - 如果单个简单查询消息中出现多个 SQL 语句,超时将分别应用于每个语句。(PostgreSQL 13 之前的版本通常将超时应用于整个查询字符串。 - 在扩展查询协议中,当任何与查询相关的消息(解析、绑定、执行、描述)到达时,超时就开始运行,并且可以通过执行完成或同步消息来取消超时。 + 控制 GEQO 使用的随机数生成器的初始值,随机数生成器用于在连接顺序搜索空间中选择随机路径。该值可以从 0 (默认值)到 1。变化该值会改变被探索的连接路径集合,并且可能导致找到一个更好或更差的路径。 + + - - 我们不推荐在postgresql.conf中设置statement_timeout,因为它会影响所有会话。 - - - + + + - - transaction_timeout (integer) - - transaction_timeout配置参数 - - - - - 终止任何在一个事务中运行时间超过指定时长的会话。该限制既适用于显式事务(以BEGIN开始),也适用于与单条语句对应的隐式事务。 - 如果指定值时没有单位,则以毫秒为单位。零值(默认值)将禁用该超时。 - - - 如果transaction_timeout短于或等于idle_in_transaction_session_timeoutstatement_timeout,则较长的超时将被忽略。 - - - 不建议在postgresql.conf中设置transaction_timeout,因为它会影响所有会话。 - - - - 预备事务不受该超时影响。 - - - - + 其他规划器选项 - + - lock_timeout (integer) + + + default_statistics_target (integer) - lock_timeout配置参数 + default_statistics_target配置参数 - 如果任何语句在试图获取表、索引、行或其他数据库对象上的锁时等到超过指定的时间量,该语句将被中止。 - 该时间限制独立地应用于每一次锁获取尝试。该限制会应用到显式锁定请求(如LOCK TABLE或不带NOWAITSELECT FOR UPDATE)和隐式获得的锁。 - 如果指定值时没有单位,则以毫秒为单位。一个零值(默认)将禁用超时。 - - - - 与statement_timeout不同,这个超时只在等待锁时发生。注意如果statement_timeout为非零,设置lock_timeout为相同或更大的值没有意义,因为事务超时将总是第一个被触发。 - 如果log_min_error_statement 被设置为ERROR 或更低,超时的语句将被记录。 - - - - 我们不推荐在postgresql.conf中设置lock_timeout,因为它会影响所有会话。 + 为没有通过ALTER TABLE SET STATISTICS设置列相关目标的表列设置默认统计目标。更大的值增加了需要做ANALYZE的时间,但是可能会改善规划器的估计质量。默认值是 100。有关PostgreSQL查询规划器使用的统计信息的更多内容, 请参考 - + - idle_in_transaction_session_timeout (integer) + constraint_exclusion (enum) - idle_in_transaction_session_timeout 配置参数 + 约束排除 + + + constraint_exclusion配置参数 - 终止任何已经闲置(这是指,等待客户端查询)超过这个参数所指定时间量的打开事务的会话。 - 如果这个值指定时没有单位,它被设为毫秒。 - 零值(默认)禁用超时。 - + 控制查询规划器对表约束的使用,以优化查询。 + constraint_exclusion的允许值是on(对所有表检查约束)、off(从不检查约束)和partition(只对继承的子表和UNION ALL子查询检查约束)。 + partition是默认设置。它通常与传统的继承树一起使用来提高性能。 + - 此选项可以用于确保空闲会话不会在不合理的时间内持有锁。 - 即使没有持有重要的锁的时候,打开的事务也会防止清理最近死亡的可能只对这个事务可见的元组;所以长时间保持空闲会导致表膨胀。 - 详见。 - - - - - + 当对一个特定表允许这个参数,规划器比较查询条件和表的CHECK约束,并且忽略那些条件违反约束的表扫描。例如: - idle_session_timeout (integer) - - idle_session_timeout 配置参数 - - - + +CREATE TABLE parent(key integer, ...); +CREATE TABLE child1000(check (key between 1000 and 1999)) INHERITS(parent); +CREATE TABLE child2000(check (key between 2000 and 2999)) INHERITS(parent); +... +SELECT * FROM parent WHERE key = 2400; + - - 终止任何空闲的会话(也就是,等待客户端查询),但不在打开的事务中,且超过指定的时间量。 - 如果指定值时不带单位,其单位采用毫秒。 - 零值时(默认)禁用超时。 + 在启用约束排除时,这个SELECT将完全不会扫描child1000,从而提高性能。 - 不像打开事务的情况,没有事务的空闲会话不会给服务器带来很大的开销,因此启用此超时的需要比idle_in_transaction_session_timeout更少。 + 目前,约束排除只在通过继承树实现表分区的情况中被默认启用。为所有表启用它会增加额外的规划开销,特别是在简单查询上并且不会产生任何好处。 + 如果没有用传统继承树分区的表时,最好是完全关闭它。(注意分区表的等效特性是由单独的参数控制的,.) - 注意不要对通过连接池软件或其他中间件建立的连接强制执行此超时,因为这样的层可能不会很好地响应意外的连接关闭。 - 只对交互会话启用此超时可能是帮助的,也许只对特定用户应用它。 + 更多关于使用约束排除实现分区的信息请参阅 - + - bytea_output (enum) + cursor_tuple_fraction (floating point) - bytea_output配置参数 + cursor_tuple_fraction配置参数 - 设置bytea类型值的输出格式。有效值是hex(默认)和 escape(传统的 PostgreSQL 格式)。详见。不管这个设置的值如何,bytea类型总是接受这两种格式的输入。 + 设置规划器对将被检索的一个游标的行的比例的估计。默认值是 0.1。更小的值使得规划器偏向为游标使用快速开始计划,它将很快地检索前几行但是可能需要很长时间来获取所有行。更大的值强调总的估计时间。最大设置为 1.0,游标将和普通查询完全一样地被规划,只考虑总估计时间并且不考虑前几行会被多快地返回。 - + - xmlbinary (enum) + from_collapse_limit (integer) - xmlbinary配置参数 + from_collapse_limit配置参数 - 设置二进制值如何被编码为 XML。例如,这适用于通过xmlelement函数或xmlforest函数将bytea值转换到 XML 值。可能的值有base64hex,它们都是用 XML 模式标准定义的。默认值是base64。更多关于 XML 相关函数的信息可参阅。 + 如果生成的FROM列表不超过这么多项,规划器将把子查询融合到上层查询。较小的值可以减少规划时间,但是可能 会生成较差的查询计划。默认值是 8。详见 - 这里的实际选择都是根据爱好做出的,只受客户端应用中可能存在的限制的约束。两种方法都支持所有可能的值,尽管十六进制编码将比 base64 编码更大。 + 将这个值设置为或更大,可能触发使用 GEQO 规划器,从而产生非最优计划。见 - + - xmloption (enum) - - xmloption配置参数 - - - SET XML OPTION - + jit (boolean) - XML option + jit配置参数 - 当在XML和字符串值之间进行转换时,无论设置DOCUMENT或 CONTENT都是隐式的。可参阅Section 8.13。 有效值是DOCUMENT和CONTENT。 缺省值是CONTENT。当在 XML 和字符串值之间进行转换时,设置DOCUMENTCONTENT都是隐式的。详见。有效值是DOCUMENTCONTENT。默认值是CONTENT。 - - - - 根据 SQL 标准,设置这个选项的命令是: - -SET XML OPTION { DOCUMENT | CONTENT }; - - 这种语法在 PostgreSQL 也可用。 + 决定如果可用(见),PostgreSQL是否可以使用JIT编译。默认值是on - + - gin_pending_list_limit (integer) + join_collapse_limit (integer) - gin_pending_list_limit - 配置参数 + join_collapse_limit配置参数 - 设置fastupdate被启用时可以使用的 GIN索引的待处理列表的最大尺寸。 - 如果该列表增长到超过这个最大尺寸,会通过批量将其中的项移入索引的主 GIN 数据结构来清理列表。 - 如果指定值时没有单位,则以千字节为单位。默认值是四兆字节(4MB)。 - 可以通过更改索引的存储参数来为个别 GIN 索引覆盖这个设置。更多信息请见。 + 如果得出的列表中不超过这么多项,那么规划器将把显式JOIN(除了FULL JOIN)结构重写到 FROM项列表中。较小的值可减少规划时间,但是可能会生成差些的查询计划。 - - - - - - - - 区域和格式化 - - - - - DateStyle (string) - - DateStyle配置参数 - - - + + 默认情况下,这个变量被设置成和from_collapse_limit相同, 这样适合大多数使用。把它设置为 1 可避免任何显式JOIN的重排序。因此查询中指定的显式连接顺序就是关系被连接的实际顺序。因为查询规划器并不是总能 选取最优的连接顺序,高级用户可以选择暂时把这个变量设置为 1,然后显式地指定他们想要的连接顺序。更多信息请见。 + - 设置日期和时间值的显示格式,以及解释有歧义的日期输入值的规则。由于历史原因, 这个变量包含两个独立的部分:输出格式声明(ISOPostgresSQLGerman)、 输入/输出的年/月/日顺序(DMYMDYYMD)。这些可以被独立设置或者一起设置。关键字EuroEuropeanDMY的同义词;关键字USNonEuroNonEuropeanMDY的同义词。详见。内置默认值是ISO, MDY,但是initdb将用对应于选中的lc_time区域行为的设置初始化配置文件。 + 将这个值设置为或更大,可能触发使用 GEQO 规划器,从而产生非最优计划。见 - + - IntervalStyle (enum) + plan_cache_mode (enum) - IntervalStyle配置参数 + plan_cache_mode 配置参数 - 设置间隔值的显示格式。值sql_standard将产生匹配 SQL 标准间隔文本的输出。当参数被设置为ISO时,值postgres(默认)将产生匹配PostgreSQL发行 8.4 之前的输出。当DateStyle参数被设置为非ISO输出时,值postgres_verbose会产生匹配PostgreSQL发行 8.4 之前的输出。值iso_8601会产生匹配在 ISO 8601 的 4.4.3.2 节中定义的带标志符格式的时间间隔的输出。 - - - - IntervalStyle参数也可以影响对有歧义的间隔输入的解释。详见。 + 准备语句(显式准备或隐式生成的,例如 PL/pgSQL)可以使用自定义或通用计划执行。 + 使用其特定的参数值集为每个执行重新生成自定义计划,而通用计划不依赖于参数值,并且可以在执行中重复使用。 + 因此,使用通用计划可以节省计划时间,但如果理想计划严重依赖参数值,则通用计划可能效率低下。 + 这些选项之间的选择通常是自动进行的,但可以通过plan_cache_mode覆盖它。 + 允许的值为 auto (默认的),force_custom_planforce_generic_plan。 + 这个设置是在执行缓存计划时考虑,而不是在准备计划时考虑。 + 更多信息请参阅 . - + - TimeZone (string) + recursive_worktable_factor (floating point) - TimeZone配置参数 + recursive_worktable_factor配置参数 - time zone - 设置用于显示和解释时间戳的时区。内置默认值是GMT,但是它通常会在postgresql.conf中被覆盖;initdb将安装一个对应于其系统环境的设置。详见。 + 设置规划器对递归查询 + 的工作表的平均大小的估计值,作为查询初始非递归项的估计大小的倍数。 + 这有助于规划器选择将工作表与查询的其他表连接的最合适方法。 + 默认值为10.0。当递归从一步到下一步的fan-out较低时,如最短路径查询中的示例,使用较小的值(如1.0)可能有所帮助。 + 图分析查询可能会从大于默认值的设置中受益。 - - + + + + + - + - timezone_abbreviations (string) - - timezone_abbreviations配置参数 - - time zone names - - + 错误报告和日志 - - 设置服务器接受的日期时间输入中使用的时区缩写集合。默认值为'Default', 这个集合在全世界大多数地方都能工作。也还有'Australia''India',以及可能为一种特定安装定义的其他集合。详见。 - - - + + 服务器日志 + - + - extra_float_digits (integer) - - significant digits - - - floating-point - display - + 在哪里做日志 + + + 日志写到哪里 + + + + current_logfiles + 和日志_目的地配置参数 + + + + + + + log_destination (string) - extra_float_digits配置参数 + log_destination配置参数 - 这个参数调整用于文本输出浮点值的位数,包括float4float8以及几何数据类型。 + PostgreSQL支持多种记录服务器消息的方法,包括 + stderrcsvlog, + jsonlog和 + syslog。在Windows上, + eventlog也受支持。将此参数设置为以逗号分隔的所需日志目的地列表。默认情况下仅记录到 + stderr。 + 此参数只能在postgresql.conf + 文件或服务器命令行中设置。 - 如果值为1(默认值)或更高,浮点值被输出为最短-精度格式;参见。 - 实际生成的位数只取决于输出的值,而不取决于此参数的值。 - float8 值最多需要 17 位数字,float4值最多需要9位数字。 - 这种格式既快速又精确,在正确读取时精确地保留了原始的二进制浮点值。为了历史兼容性,允许的值最大为3。 + 如果csvlog被包括在log_destination中,日志项会以逗号分隔值CSV)格式被输出,这样可以很方便地把日志载入到程序中。详见。要产生 CSV 格式的日志输出,必须启用 - 如果值为零或负,则输出四舍五入为给定的十进制精度。 - 使用的精度是根据此参数的值减小的类型((FLT_DIGDBL_DIG,视情况而定)的标准位数。 - (例如,指定 -1 将导致float4 值输出四舍五入为 5 位有效数字,而float8值四舍五入为 14 位。) - 此格式较慢,不会保留二进制浮点值的所有位,但可能令人更易于阅读。 + 如果jsonlog包含在log_destination中, + 日志条目将以JSON格式输出,这对将日志加载到程序中很方便。 + 有关详细信息,请参见。 + 必须启用才能生成JSON格式的日志输出。 + + + + 当包含stderrcsvlogjsonlog时, + 文件current_logfiles会被创建,记录日志收集器当前使用的日志文件位置和相关的日志目的地。 + 这提供了一种方便的方式来查找实例当前使用的日志。以下是该文件内容的示例: + +stderr log/postgresql.log +csvlog log/postgresql.csv +jsonlog log/postgresql.json + + + 当由于轮换而创建新的日志文件时,以及重新加载log_destination时,current_logfiles会被重新创建。 + 当log_destination中不包含stderrcsvlogjsonlog, + 以及日志收集器被禁用时,它会被移除。 + - 此参数的含义,以及其默认值,在 PostgreSQL 12 中发生了变化; - 参见 以便进一步讨论。 + 在大多数 Unix 系统上,你将需要修改系统的syslog守护进程的配置来使用log_destinationsyslog选项。PostgreSQL可以在syslog设备LOCAL0LOCAL7中记录(见),但是大部分平台上的默认syslog配置会丢弃所有这种消息。你将需要增加这样的内容: + +local0.* /var/log/postgresql + + 到syslog守护进程的配置文件来让它工作。 + + + + 在 Windows 上,当你使用log_destinationeventlog选项时,你应该在操作系统中注册一个事件源极其库,这样 Windows 事件查看器能够清楚地显示事件日志消息。详见 - + - client_encoding (string) + logging_collector (boolean) - client_encoding配置参数 + logging_collector配置参数 - character set - 设置客户端编码(字符集)。默认使用数据库编码。PostgreSQL服务器所支持的字符集在中描述。 + 这个参数启用日志收集器,它是一个捕捉被发送到stderr的日志消息的后台进程,并且它会将这些消息重定向到日志文件中。这种方法比记录到syslog通常更有用,因为某些类型的消息不会在syslog输出中出现(一个常见的示例是动态链接器错误消息;另一个示例是由archive_command等脚本产生的错误消息)。这个参数只能在服务器启动时设置。 - - - + - lc_messages (string) - - lc_messages配置参数 - - - + + 也可以不使用日志收集器而把日志记录到stderr,日志消息将只会去到服务器的stderr被定向到的位置。不过,那种方法只适合于低日志量,因为它没有提供方法来轮转日志文件。还有,在某些不使用日志收集器的平台上可能会导致丢失或者混淆日志输出,因为多个进程并发写入同一个日志文件时会覆盖彼此的输出。 + + - - 设置消息显示的语言。可接受的值是系统相关的;详见。如果这个变量被设置为空字符串(默认),那么该值将以一种系统相关的方式从服务器的执行环境中继承。 - + - - 在一些系统上,这个区域分类并不存在。仍然可以设置这个变量,只是不会有任何效果。同样,所期望语言的翻译消息也可能不存在。在这种情况下,你将仍然继续看到英文消息。 - + + 日志收集器被设计成从来不会丢失消息。这意味着在极高的负载下,如果服务器进程试图在收集器已经落后时发送更多的日志消息,那么它会被阻塞。相反,syslog倾向于在无法写入消息时丢掉消息,这意味着在这样的情况下它可能会无法记录某些消息,但是它不会阻塞系统的其他部分。 + + - - 只有超级用户和具有适当SET权限的用户才能更改此设置。 - - + - lc_monetary (string) + log_directory (string) - lc_monetary配置参数 + log_directory配置参数 - 设置用于格式化货币量的区域,例如用to_char函数族。可接受的值是系统相关的;详见。如果这个变量被设置为空字符串(默认),那么该值将以一种系统相关的方式从服务器的执行环境中继承。 + 当logging_collector被启用时,这个参数决定日志文件将被在哪个目录下创建。它可以被指定为一个绝对路径,也可以被指定为一个相对于集簇数据目录的相对路径。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 + 默认是log - + - lc_numeric (string) + log_filename (string) - lc_numeric配置参数 + log_filename配置参数 - 设置用于格式化数字的区域,例如用to_char函数族。可接受的值是系统相关的;详见。如果这个变量被设置为空字符串(默认),那么该值将以一种系统相关的方式从服务器的执行环境中继承。 + 当logging_collector被启用时,这个参数设置被创建的日志文件的文件名。 + 该值被视为一种strftime模式,因此%转义可以被用来指定根据时间变化的文件名(注意如果有任何时区独立的%转义,计算将在由指定的时区中完成)。 + 被支持的%转义和开放组织的strftime说明中列举的类似。 + 注意系统的strftime不会被直接使用,因此平台相关(非标准)的扩展无法工作。 + 默认是postgresql-%Y-%m-%d_%H%M%S.log。 + + + + 如果你不使用转义来指定一个文件名,你应该计划使用一个日志轮转工具来避免最终填满整个磁盘。在 8.4 发行之前,如果不存在%转义,PostgreSQL将追加新日志文件创建时间的纪元,但是现在已经不再这样做了。 + + + + 如果在log_destination中启用了 CSV 格式输出,.csv将会被追加到时间戳日志文件名中来创建 CSV 格式输出(如果log_filename.log结尾,该后缀会被替换)。 + + + + 如果在log_destination中启用了JSON格式的输出, + 时间戳日志文件名将会在末尾添加.json, + 以创建JSON格式输出的文件名。 + (如果log_filename.log结尾, + 则会替换掉这个后缀。) + + + + 这个参数只能在postgresql.conf文件中或通过服务器命令行进行设置。 - + - lc_time (string) + log_file_mode (integer) - lc_time配置参数 + log_file_mode配置参数 - 设置用于格式化日期和时间的区域,例如用to_char函数族。可接受的值是系统相关的;详见。如果这个变量被设置为空字符串(默认),那么该值将以一种系统相关的方式从服务器的执行环境中继承。 + 在 Unix 系统上,当logging_collector被启用时,这个参数设置日志文件的权限(在微软 Windows 上这个参数将被忽略)。这个参数值应当是一个数字形式的模式,它可以被chmodumask系统调用接受(要使用通常的十进制格式,该数字必须以一个0(零)开始)。 - - - - icu_validation_level (enum) - - icu_validation_level配置参数 - - - - - 控制在遇到 ICU 区域设置验证问题时使用何种消息严重级别报告该问题。 - 有效值包括DISABLEDDEBUG5DEBUG4DEBUG3DEBUG2DEBUG1INFONOTICEWARNINGERRORLOG。 - - - 如果设置为DISABLED,则不会报告任何验证问题;否则,将以给定的消息级别报告问题。默认值为WARNING。 - - - + + 默认的权限是0600,表示只有服务器拥有者才能读取或写入日志文件。其他常用的设置是0640,它允许拥有者的组成员读取文件。不过要注意你需要修改为将文件存储在集簇数据目录之外的某个位置,才能利用这个设置。在任何情况下,让日志文件变成任何人都可读是不明智的,因为日志文件中可能包含敏感数据。 + - + + 这个参数只能在postgresql.conf文件中或通过服务器命令行进行设置。 + + + - default_text_search_config (string) + + + log_rotation_age (integer) - default_text_search_config配置参数 + log_rotation_age配置参数 - 选择被那些没有显式参数指定配置的文本搜索函数变体使用的文本搜索配置。详见。内置默认值是pg_catalog.simple,但是如果能够标识一个匹配区域的配置,initdb将用对应于选中的lc_ctype区域的设置初始化配置文件。 + 当logging_collector被启用时,这个参数决定使用一个单个日志文件的最大时间量,之后将创立一个新的日志文件。 + 如果指定值时没有单位,则以分钟为单位。默认为24小时。 + 将这个参数设置为零将禁用基于时间的新日志文件创建。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 - - - - - - - 共享库预载入 - - - 为了载入附加的功能或者达到提高性能的目的,可用多个设置来预先载入共享库到服务器中。 - 例如'$libdir/mylib'设置可能会导致mylib.so(或者某些平台上的mylib.sl)从安装的标准库目录被预装载。这些设置之间的区别在于生效的时间以及改变它们所需的权限。 - - - - 可以用这个方法预装载PostgreSQL的过程语言库,通常是使用'$libdir/plXXX'语法,其中的XXXpgsqlperltclpython。 - - - - 只有特别为与PostgreSQL一起使用设计的共享库才能以这种方式载入。每一个PostgreSQL支持 - 的库都有一个魔法块,它会被检查以保证兼容性。由于这个原因,非PostgreSQL无法 - 以这种方式被载入。你可能可以使用操作系统的工具(如LD_PRELOAD)载入它。 - - - - 总之,请参考特定模块的文档来用推荐的方法载入它。 - - - - + - local_preload_libraries (string) - - local_preload_libraries配置参数 - + log_rotation_size (integer) - $libdir/plugins + log_rotation_size配置参数 - 这个变量指定一个或者多个要在连接开始时预载入的共享库。 - 它包含一个由逗号分隔的库名列表,其中每个名称都会按LOAD命令的方式解析。 - 项之间的空格会被忽略,如果需要在库名中包含空格或者逗号,请把库名放在双引号内。 - 这个参数值只在连接开始时生效。后续的更改不会有任何效果。 - 如果一个指定的库没有找到,连接尝试将会失败。 - - - - 任何用户都能设置这个选项。正因为如此,能被这样载入的库被严格限制为出现于安装的标准库 - 目录中plugins子目录下的共享库(保证只有安全的库被安装到 - 这里是数据库管理员的责任)。local_preload_libraries中的项可以显式 - 指定这个目录,例如$libdir/plugins/mylib,或者只是指定库的 - 名称 — mylib 和 - $libdir/plugins/mylib的效果是相同的。 - - - - 这个特性的目的是允许非特权用户在特定的会话中载入正在调试的或者性能度量库, - 而无需一个显式的LOAD命令。为了这个目的,通常通过使用客 - 户端的PGOPTIONS环境变量或者 - ALTER ROLE SET来设置这个参数。 - - - - 不过,除非一个模块被特别设计成由非超级用户以这种方式使用,通常不推荐使用这个设置。应该看看 - 。 + 当logging_collector被启用时,这个参数决定一个个体日志文件的最大尺寸。 + 当这些数据量被发送到一个日志文件后,将创建一个新的日志文件。 + 如果指定值的时候没有单位,则以千字节为单位。默认值是10兆字节。设置为零时将禁用基于大小创建新的日志文件。 + 这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 - + - session_preload_libraries (string) + log_truncate_on_rotation (boolean) - session_preload_libraries配置参数 + log_truncate_on_rotation配置参数 - 这个变量指定在连接开始时要预加载的一个或多个共享库。 - 它包含一个逗号分隔的库名称列表,其中每个名称的解释方式与LOAD命令相同。 - 条目之间的空格会被忽略;如果需要在名称中包含空格或逗号,请用双引号括起库名称。 - 参数值仅在连接开始时生效。后续更改不会生效。如果指定的库未找到,连接尝试将失败。 - 只有超级用户和具有适当SET权限的用户才能更改此设置。 + 当logging_collector被启用时,这个参数将导致PostgreSQL截断(覆盖而不是追加)任何已有的同名日志文件。不过,截断只在一个新文件由于基于时间的轮转被打开时发生,在服务器启动或基于尺寸的轮转时不会发生。如果被关闭,在所有情况下以前存在的文件将被追加。例如,使用这个设置和一个类似postgresql-%H.loglog_filename将导致产生 24 个每小时的日志文件,并且循环地覆盖它们。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 - 这个特性的意图是允许在特定会话中载入调试用的或者测量性能的库,而不需要显式的给出一个 - LOAD命令。例如,通过用ALTER ROLE SET设置这个参数可以 - 为一个给定用户名下的所有会话启用。还有,无需重启 - 服务器就能更改这个参数(但是只有新会话启动时才会生效),这样可以以这种方式更容易地增 - 加新模块,即便它们会应用到所有会话。 + 示例:保留7天的日志,每天一个日志文件,命名为server_log.Monserver_log.Tue,等等,并自动用本周的日志覆盖上周的日志,将log_filename设置为server_log.%a,将log_truncate_on_rotation设置为on,将log_rotation_age设置为1440 - 和不同,相对于在库被第一次使用 - 时载入它,在会话开始时载入库并没有什么性能优势。不过,当使用连接池时这样做还是有一些 - 优势。 + 示例:要保留 24 小时的日志,每个小时一个日志文件,但是在日志文件尺寸超过 1GB 时轮转。可以这样做:将log_filename设置为server_log.%H%M、 + 将log_truncate_on_rotation设置为on、 + 将log_rotation_age设置为60并且 + 将log_rotation_size设置为1000000。 + 在log_filename中包括%M允许发生任何尺寸驱动的轮转来选择一个不同于每个小时的初始文件名的新文件名。 - + - shared_preload_libraries (string) + syslog_facility (enum) - shared_preload_libraries配置参数 + syslog_facility配置参数 - 这个变量指定一个或者多个要在服务器启动时预载入的共享库。 - 它包含一个由逗号分隔的库名列表,其中每个名称都会按LOAD命令的方式解析。 - 项之间的空格会被忽略,如果需要在库名中包含空格或者逗号,请把库名放在双引号内。 - 这个参数只能在服务器启动时设置。 - 如果指定的库没有找到,服务器将无法启动。 - - - - 有些库需要执行只能在postmaster启动时发生的特定操作,例如分配共享内存、保留轻量级锁 - 或者启动后台工作者。这些库必须通过这个参数在服务器启动时载入。每个库的详情请见文档。 - - - - 其他库也能被预载入。通过预载入一个共享库,当该库被第一次使用时就可以避免库的启动时间。 - 不过,启动每个新服务器进程的时间可能会略有增加,即使该进程从不使用该库。因此,推荐只 - 把这个参数用于那些要在大多数会话中使用的库上。还有,改变这个参数要求重启服务器,因此 - 对于短期的调试任务来说这不是好的选择,应该转用 - 。 - - - - - - 在 Windows 主机上,在服务器启动时预载入一个库并不会减少启动每个新服务器进程所需的 - 时间;每一个服务器进程将会重新载入预载入的库。不过,对于那些要在postmaster启动时 - 执行操作的库来说,Windows 主机上的 - shared_preload_libraries任然有用。 + 当启用了向syslog记录时,这个参数决定要使用的syslog设备。你可以在LOCAL0LOCAL1LOCAL2LOCAL3LOCAL4、 + LOCAL5LOCAL6LOCAL7中选择,默认值是LOCAL0。还请参阅系统的syslog守护进程的文档。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 - - + - jit_provider (string) - - jit_provider配置参数 - + syslog_ident (string) + + syslog_ident配置参数 + - + - - 这个变量是要被使用的JIT提供者库的名称(见)。默认是llvmjit。这个参数只能在服务器启动时设置。 - + + 当启用了向syslog记录时,这个参数决定用来标识syslog中的PostgreSQL消息的程序名。默认值是postgres。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 + + + - - 如果这个变量被设置为一个不存在的库,JIT将不可用,但是也不会发生错误。这种特性允许在主PostgreSQL包之外单独安装JIT支持。 - - - + - - + syslog_sequence_numbers (boolean) + + syslog_sequence_numbers 配置参数 + + - + - 其他默认值 + + 当日志被记录到syslog并且这个设置为 on (默认)时,每一个消息会被加上一个增长的序号作为前缀(例如[2])。这种行为避开了很多 syslog 实现默认采用的--- 上一个消息重复 N 次 ---形式。在现代 syslog 实现中,抑制重复消息是可以配置的(例如rsyslog中的$RepeatedMsgReduction),因此这个参数可能不是必需的。此外,如果你真的想抑制重复消息,你可以把这个参数设置为 off。 + - + + 这个参数只能在postgresql.conf文件或者服务器命令行上设置。 + + + - + - dynamic_library_path (string) + syslog_split_messages (boolean) - dynamic_library_path配置参数 + syslog_split_messages 配置参数 - 动态装载 - 如果需要打开一个可以动态装载的模块并且在CREATE FUNCTIONLOAD命令中指定的文件名没有目录部分(即名字中不包含斜线),那么系统将搜索这个路径以查找所需的文件。 - - - - dynamic_library_path的值必须是一个冒号分隔(或者在 Windows 上以分号分隔)的绝对目录路径的列表。如果一个列表元素以特殊字符串开始,$libdir会被替换为PostgreSQL包中已编译好的库目录。这里是PostgreSQL发布提供的模块被安装的位置(使用pg_config --pkglibdir来找到这个目录的名字)。例如: - -dynamic_library_path = '/usr/local/lib/postgresql:/home/my_project/lib:$libdir' - - 或者在 Windows 环境中: - -dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' - + 当启用把日志记录到syslog时,这个参数决定消息如何送达 syslog。当设置为 on(默认)时,消息会被分成行,并且长的行也会被划分以便能够放到 1024 字节中,这是传统 syslog 实现一种典型的尺寸限制。当设置为 off 时,PostgreSQL 服务器日志消息会被原样送达 syslog 服务,而处理可能的大体量消息的任务由 syslog 服务负责。 - 这个参数的默认值是'$libdir'。如果该值被设置为一个空字符串,则关闭自动路径搜索。 + 如果 syslog 最终被记录到一个文本文件中,那么两种设置的效果是一样的,但最好设置为 on,因为大部分 syslog 实现要么不能处理大型消息,要么需要做特殊的配置以处理大型消息。但是如果 syslog 最终写入到某种其他媒介,有必要让消息保持逻辑上的整体性(也更加有用)。 - 这个参数可以由超级用户和具有适当SET权限的用户在运行时更改, - 但以这种方式进行的设置只会持续到客户端连接结束,因此这种方法应该保留用于开发目的。 - 推荐设置此参数的方法是在postgresql.conf配置文件中。 + 这个参数只能在postgresql.conf文件中或通过服务器命令行进行设置。 - - - - - extension_control_path (string) - - extension_control_path配置参数 - - - - - 搜索扩展的路径,特别是扩展控制文件(name.control)。其余扩展脚本和辅助控制文件会从找到主控制文件的同一目录中加载。 - - - extension_control_path 的值必须是绝对目录路径列表,各路径以冒号分隔 - (在 Windows 上使用分号)。如果某个列表元素以特殊字符串 $system 开头, - 则 $system 会被替换为编译时确定的 PostgreSQL 扩展目录, - 也就是标准版 PostgreSQL 所提供扩展的安装位置。 - (可使用 pg_config --sharedir 查找该目录名称。)例如: - -extension_control_path = '/usr/local/share/postgresql:/home/my_project/share:$system' - - 或者在 Windows 环境中: - -extension_control_path = 'C:\tools\postgresql;H:\my_project\share;$system' - - 请注意,指定的每个路径元素都应当包含一个 extension 子目录,其中放置 - .control.sql 文件;系统会自动为每个路径元素追加 - extension 后缀。 - - - 该参数的默认值是 '$system'。如果将其设置为空字符串,也会视为默认的 - '$system'。 - - - 如果配置路径中的多个目录中存在同名扩展,则只会使用路径中最先找到的那个。 - - - 该参数可以由超级用户和具有适当SET权限的用户在运行时更改,但这种方式下的设置只会持续到客户端连接结束,因此这种方法应保留用于开发目的。 - 推荐在postgresql.conf中设置该参数。 - - - 请注意,如果你设置该参数以便从非标准位置加载扩展,那么通常还需要把设置为相应的位置。 - - - + + - + - gin_fuzzy_search_limit (integer) + event_source (string) - gin_fuzzy_search_limit配置参数 + event_source配置参数 - GIN 索引返回的集合尺寸的软上限。详见。 + 当启用了向事件日志记录时,这个参数决定用来标识日志中PostgreSQL消息的程序名。默认值是PostgreSQL。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 - + - - - + - 锁管理 + 什么时候记录日志 - + - deadlock_timeout (integer) - - deadlock - 期间超时 - - - timeout - deadlock - + log_min_messages (enum) - deadlock_timeout配置参数 + log_min_messages配置参数 - 这是在锁上等待的时间,然后再检查是否存在死锁条件。检查死锁相对昂贵,因此服务器不会每次等待锁时都运行它。 - 我们乐观地假设在生产应用程序中死锁并不常见,所以在检查死锁之前只是等待一段时间。 - 增加此值会减少在不必要的死锁检查中浪费的时间,但会减慢实际死锁错误的报告速度。 - 如果未指定单位,则将其视为毫秒。 - 默认值为一秒(1s),这可能是您在实践中想要的最小值。 - 在负载较重的服务器上,您可能希望提高它。 - 理想情况下,设置应超过您的典型事务时间,以提高在等待者决定检查死锁之前释放锁的几率。 + 控制将哪些消息级别写入服务器日志。 + 有效值为DEBUG5DEBUG4, + DEBUG3DEBUG2DEBUG1, + INFONOTICEWARNING, + ERRORLOGFATAL和 + PANIC。每个级别包括其后的所有级别。 + 级别越高,发送到日志的消息越少。默认值为WARNING。 + 请注意,在中,LOG的排名不同。 只有超级用户和具有适当SET权限的用户才能更改此设置。 - - - 当被设置时,这个参数还可以决定发出关于锁等待的日志之前等待的时间量。如果你想调查锁延迟,你可能希望设置一个比正常的deadlock_timeout小的值。 - - + - max_locks_per_transaction (integer) + log_min_error_statement (enum) - max_locks_per_transaction配置参数 + log_min_error_statement配置参数 - 共享锁表跟踪在max_locks_per_transaction * ( + ) 个对象(如表)上的锁。因此,在任何一个时刻,只有不超过这么多个可区分对象能够被锁住。这个参数控制为每个事务分配的对象锁的平均数量。个体事务可以锁住更多对象,数量可以和锁表中能容纳的所有事务的锁一样多。这是能被锁住的行数,那个值是没有限制的。默认值 64 已经被历史证明是足够的,但是如果你有需要在一个事务中使用很多不同表的查询(例如查询一个有很多子表的父表),你可能需要提高这个值。这个参数只能在服务器启动时设置。 - - - - 当运行一个备库时,你必须设置这个参数等于或大于主库上的参数。 - 否则,备库上可能无法允许查询。 + 控制在服务器日志中记录哪些导致错误条件的SQL语句。当前的SQL语句将包含在任何指定 + severity + 或更高消息的日志条目中。 + 有效值为DEBUG5、 + DEBUG4DEBUG3、 + DEBUG2DEBUG1、 + INFONOTICE、 + WARNINGERROR、 + LOG、 + FATALPANIC。 + 默认值为ERROR,这意味着导致错误、日志消息、致命错误或紧急情况的语句将被记录。 + 要有效地关闭记录失败的语句, + 将此参数设置为PANIC。 + 只有超级用户和具有适当SET权限的用户才能更改此设置。 - + - max_pred_locks_per_transaction (integer) + log_min_duration_statement (integer) - max_pred_locks_per_transaction配置参数 + log_min_duration_statement配置参数 - + - - 共享谓词锁表跟踪在max_pred_locks_per_transaction * ( + ) 个对象(如表)上的锁。因此,在任何一个时刻,只有不超过这么多个可区分对象能够被锁住。这个参数控制为每个事务分配的对象锁的平均数量。个体事务可以锁住更多对象,数量可以和锁表中能容纳的所有事务的锁一样多。这是能被锁住的行数,那个值是没有限制的。默认值 64 已经在测试中被证明通常是足够的,但是如果你有需要在一个可串行化事务中使用很多不同表的查询(例如查询一个有很多子表的父表),你可能需要提高这个值。这个参数只能在服务器启动时设置。 - - - + + 记录每个已完成语句的持续时间,如果语句运行时间至少达到指定时间。 + 例如,如果将其设置为250ms,那么所有运行时间为250ms或更长的SQL语句将被记录。 + 启用此参数可帮助跟踪应用程序中的未优化查询。 + 如果未指定单位,则将其视为毫秒。 + 将此值设置为零将打印所有语句持续时间。 + -1(默认值)禁用记录语句持续时间。 + 只有超级用户和具有适当SET权限的用户才能更改此设置。 + - + + 这会覆盖,意味着持续时间超过此设置的查询不进行抽样,并且始终被记录。 + - max_pred_locks_per_relation (integer) - - max_pred_locks_per_relation配置参数 - - - + + 对于使用扩展查询协议的客户端,解析、绑定和执行步骤的持续时间将被独立记录。 + - - 这个参数控制在谓词锁被提升为覆盖整个关系之前,该谓词锁能够在单个关系上锁住多少页面或元组。大于等于零的值表示一种绝对限制,而负值表示用除以这个设置的绝对值。默认值为-2,它将保持以往版本的PostgreSQL中的行为。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 - - - + - + + 当把这个选项和一起使用时,已经被log_statement记录的语句文本不会在持续时间日志消息中重复。如果你没有使用syslog,我们推荐你使用记录 PID 或会话 ID,这样你可以使用进程 ID 或会话 ID 把语句消息链接到后来的持续时间消息。 + + + + - max_pred_locks_per_page (integer) + + + log_min_duration_sample (integer) - max_pred_locks_per_page配置参数 + log_min_duration_sample 配置参数 - + - - 这个参数控制在谓词锁被提升为覆盖整个页面之前,该谓词锁能在单一页面上锁住多少行。默认值是2。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 - - - - - - + + 允许对运行时间至少达到指定时间的已完成语句进行采样。这会产生与 + 相同类型的日志条目, + 但仅针对已执行语句的子集,采样率由控制。 + 例如,如果将其设置为100ms,那么运行时间达到100ms或更长的所有 + SQL语句都将被考虑进行采样。启用此参数在流量过高无法记录所有查询时很有帮助。 + 如果未指定单位,则将其视为毫秒。 + 将其设置为零会对所有语句持续时间进行采样。 + -1(默认值)禁用语句持续时间的采样。 + 只有超级用户和具有适当SET权限的用户才能更改此设置。 + - + + 此设置的优先级低于 log_min_duration_statement,意味着持续时间超过 log_min_duration_statement 的语句不被采样,并且始终被记录。 + - 版本和平台兼容性 + + log_min_duration_statement的其他注释也适用于此设置。 + + + - + - 以前的 PostgreSQL 版本 + log_statement_sample_rate (floating point) + + log_statement_sample_rate 配置参数 + + + - + + 确定持续时间超过的语句的比例将被记录。 + 采样是随机的,例如0.5表示统计上有一半的机会任何给定的语句将被记录。 + 默认值为1.0,表示记录所有采样的语句。 + 将此设置为零将禁用采样语句持续时间记录,与将log_min_duration_sample设置为-1相同。 + 只有超级用户和具有适当SET权限的用户才能更改此设置。 + + + - + - array_nulls (boolean) + log_transaction_sample_rate (floating point) - array_nulls配置参数 + log_transaction_sample_rate 配置参数 - + - - 这个参数控制数组输入解析器是否把未用引号的NULL识别为一个空数组元素。默认为on,允许输入包含空值的数组值。但是PostgreSQL 8.2 之前的版本不支持数组中的空值,并且因此将把NULL当作指定一个值为字符串NULL的正常数组元素。对于那些要求旧行为的应用的向后兼容性,这个变量可以被设置为off。 - + + 设置所有语句都被记录的事务的比例,除了其他原因记录的语句。它适用于每个新事务,无论其语句的持续时间如何。 + 采样是随机的,例如0.1表示任何给定事务被记录的统计概率是十分之一。 + log_transaction_sample_rate可以帮助构建事务样本。 + 默认值为0,表示不记录任何额外事务的语句。将其设置为1会记录所有事务的所有语句。 + 只有超级用户和具有适当SET权限的用户才能更改此设置。 + + - - 注意即使这个变量为off也能够创建包含空值的数组值。 - - + + 就像所有的语句-日志选项一样,这个选项可能会增加大量开销。 + + + - + - backslash_quote (enum) - stringsbackslash quotes + log_startup_progress_interval (integer) - backslash_quote配置参数 + log_startup_progress_interval配置参数 - + - - 这个参数控制字符串文本中的单引号是否能够用\'来表示。首选的 SQL 标准的方法是将其双写(''),但是PostgreSQL在历史上也接受\'。不过使用\'容易导致安全风险,因为在某些客户端字符集编码中,有多字节字符的最后一个字节在数值上等价于 ASCII 的\'。如果客户端代码没有做到正确转义,那么将会导致 SQL 注入攻击。如果服务器拒绝看起来带有被反斜线转义的单引号的查询,那么就可以避免这种风险。backslash_quote的可用值是on(总是允许\')、off(总是拒绝)以及safe_encoding(只有客户端编码不允许在多字节字符中存在 ASCII \时允许)。safe_encoding是默认设置。 - + + 设置启动进程在长时间运行的操作仍在进行时记录消息的时间间隔, + 以及该操作进一步进展消息之间的间隔时间。默认值为10秒。 + 设置为0会禁用该功能。如果未指定单位, + 则将其视为毫秒。此设置分别应用于每个操作。 + 此参数只能在postgresql.conf文件或服务器命令行中设置。 + - - 注意在符合标准的字符串文本中,\就表示\。这个参数只影响不符合标准的文本的处理,包括转义字符串语法(E'...')。 - - + + 例如,如果同步数据目录需要25秒,然后重置不记录 WAL 的关系需要8秒,如果此设置的默认值为10秒, + 那么在数据目录同步进行了10秒后,将记录一条消息,再在进行了20秒后记录一条消息, + 但对于重置不记录 WAL 的关系不会记录任何消息。 + + - + - escape_string_warning (boolean) - strings转义警告 + + 解释了PostgreSQL所使用的消息严重级别。如果日志输出被发送到syslog或 Windows 的eventlog,严重级别会按照表中所示进行转换。 + + + + + 消息严重级别 + + + + + + + + + 严重性 + 用法 + syslog + eventlog + + + + + + + DEBUG1 .. DEBUG5 + 为开发者提供连续的更详细的信息。 + DEBUG + INFORMATION + + + + INFO + 提供用户隐式要求的信息,例如来自VACUUM VERBOSE的输出。 + INFO + INFORMATION + + + + NOTICE + 提供可能对用户有用的信息,例如长标识符截断提示。 + NOTICE + INFORMATION + + + + WARNING + 提供可能出现的问题的警告,例如在一个事务块外COMMIT + NOTICE + WARNING + + + + ERROR + 报告一个导致当前命令中断的错误。 + WARNING + ERROR + + + + LOG + 报告管理员可能感兴趣的信息,例如检查点活动。 + INFO + INFORMATION + + + + FATAL + 报告一个导致当前会话中断的错误。 + ERR + ERROR + + + + PANIC + 报告一个导致所有数据库会话中断的错误。 + CRIT + ERROR + + + +
+ +
+ + + 记录什么到日志 + + + + + 你选择记录的内容可能会影响安全性;请参见。 + + + + + + + + application_name (string) - escape_string_warning配置参数 + application_name配置参数 - 打开时,如果在普通字符串文本中('...'语法)出现了 一个反斜线(\)并且standard_conforming_strings为关闭,那么就会发出一个警告。默认值是on。 - - - - 希望使用反斜线作为转义符的应用应该被修改来使用转义字符串语法(E'...'),因为在 SQL 标准中普通字符串的默认行为是将反斜线视作一个普通字符。这个变量可以被启用来帮助定位需要被更改的代码。 + application_name可以是任意小于NAMEDATALEN个字符(标准编译中是 64 个字符)的字符串。应用通常在连接服务器时设置此值。该名称将被显示在pg_stat_activity视图中并被包括在 CSV 日志项中。它也会被通过包括在普通日志项中。只有可打印 ASCII 字符能被使用在application_name之中。其他字符将被替换为问号(?)。 - + - lo_compat_privileges (boolean) + debug_print_parse (boolean) - lo_compat_privileges配置参数 + debug_print_parse配置参数 - - - 在PostgreSQL 9.0之前的版本中,大对象没有访问权限,因此始终可以被所有用户读取和写入。 - 将此变量设置为on会禁用新的权限检查,以保持与之前版本的兼容性。默认值为off。 - 只有超级用户和具有适当SET权限的用户才能更改此设置。 - + debug_print_rewritten (boolean) + + debug_print_rewritten配置参数 + + + + debug_print_plan (boolean) + + debug_print_plan配置参数 + + + - 设置这个参数不会禁用所有与大对象相关的安全检查 — 除了那些在PostgreSQL 9.0中已经修改了的默认行为。 + 这个参数启用发出各种调试输出。当设置时,会打印生成的解析树, 查询重写输出,或执行的每个查询的执行计划。这些信息是在LOG 信息级别发出,因此默认的,它们会出现在服务器日志中,但不会发送给客户端。 可以通过 client_min_messages和/或log_min_messages 来设置。这些参数缺省是off。 + 这些参数将会让多种调试输出被发出。当被设置时,它们为每一个被执行的查询打印结果分析树、查询重写器输出或执行计划。这些消息在LOG消息级别上被发出,因此默认情况下它们将出现在服务器日志中但不会被发送到客户端。你可以通过调整和/或来改变这种情况。这些参数默认是关闭的。 - + - quote_all_identifiers (boolean) + debug_pretty_print (boolean) - quote_all_identifiers配置参数 + debug_pretty_print配置参数 - 当数据库产生 SQL 时,强制所有标识符被引号包围,即使它们(当前)不是关键字。这将影响EXPLAIN的输出以及pg_get_viewdef等函数的结果。另请参阅选项。 + 当被设置时,debug_pretty_print会缩进由debug_print_parse、 + debug_print_rewritten或 + debug_print_plan产生的输出。这将导致比关闭参数时使用的紧凑模式可读性更强但是更长的输出。它默认是打开的。 - + - standard_conforming_strings (boolean) - stringsstandard conforming + log_autovacuum_min_duration (integer) - standard_conforming_strings配置参数 + log_autovacuum_min_duration + 配置参数 - 控制普通字符串文本('...')是否按照 SQL 标准把反斜线当普通文本。从PostgreSQL 9.1 开始,默认值为on(之前的发行中默认值为off)。应用可以检查这个参数来判断字符串文本如何被处理。这个参数的存在也可以被当做转义字符串语法(E'...')被支持的标志。如果一个应用希望反斜线被当做转义字符,应该使用转义字符串语法()。 + 每次由自动清理执行的操作都会被记录,如果运行时间至少达到指定时间。将此设置为零会记录所有自动清理操作。 + -1会禁用记录自动清理操作。如果未指定单位,则将其视为毫秒。 + 例如,如果将其设置为250ms,则所有运行时间为250ms或更长的自动清理和分析都将被记录。 + 此外,当此参数设置为任何值而不是-1时,如果由于冲突的锁定或同时删除的关系而跳过自动清理操作,则会记录消息。 + 默认值为10min。启用此参数可帮助跟踪自动清理活动。 + 此参数只能在postgresql.conf文件或服务器命令行中设置;但可以通过更改表存储参数来覆盖对单个表的设置。 - + - synchronize_seqscans (boolean) + log_checkpoints (boolean) - synchronize_seqscans配置参数 + log_checkpoints配置参数 - 它允许对大型表的顺序扫描与其他扫描同步,因此并发扫描可以在几乎相同的时刻读取相同的块,这样可以分担 I/O 负载。当启用这个参数时,一个扫描可能会从表的中间开始并且之后绕回到开头以覆盖所有的行,这样可以与已在进行中的扫描活动同步。对于没有ORDER BY子句的查询来,这样的扫描会在返回行的顺序中造成不可预料的改变。将这个参数设置为off以保证 8.3 之前的行为(顺序扫描总是从表的起始处开始)。默认值是on。 + 导致检查点和重启点在服务器日志中记录。日志消息中包括一些统计信息, + 包括写入的缓冲区数量和写入它们所花费的时间。此参数只能在 + postgresql.conf文件或服务器命令行中设置。默认值为开启。 - - - - - - 平台和客户端兼容性 - - - - - transform_null_equals (boolean) - IS NULL + + log_connections (boolean) - transform_null_equals配置参数 + log_connections 配置参数 - - 当打开时,形为expr = NULL(或NULL = expr)的表达式将被当做expr IS NULL, 也就是说,如果expr得出空值值则返回真,否则返回假。正确的 SQL 标准兼容的expr = NULL行为总是返回空(未知)。因此这个参数默认为off。 + 记录每次尝试连接服务器的操作,以及客户端认证(如有必要)和授权的成功完成。 + 只有超级用户和具有适当 SET 权限的用户可以在会话开始时更改此参数,在会话期间则完全不能更改。 + 默认值为 off - - 不过,在Microsoft Access里的过滤表单生成的查询似乎使用expr = NULL来测试空值,因此,如果你使用这个接口访问数据库,你可能想把这个选项打开。因为expr = NULL形式的表达式总是返回空值(使用 SQL 标准解释)。它们不是非常有用并且在普通应用中也不常见,在应用中也不常见,因此这个选项实际上没有什么危害。但是新用户常常对涉及 空值的表达式的语义上感到困惑,因此这个选项默认为关闭。 - + + + 某些客户端程序(例如 psql)在判断是否需要密码时会尝试连接两次, + 因此重复的收到连接消息并不一定表示有问题。 + + + + - - 请注意这个选项只影响= NULL形式,而不影响其它比较操作符或者其它与一些涉及等值操作符的表达式在计算上等效的其他表达式(例如IN)。因此,这个选项不是劣质程序的一般修复。 - + - - 相关信息请见。 + log_disconnections (boolean) + + log_disconnections配置参数 + + + + + + 导致会话终止被记录。日志输出提供类似于log_connections的信息,以及会话的持续时间。 + 只有超级用户和具有适当SET权限的用户可以在会话开始时更改此参数,而且在会话中根本无法更改。 + 默认值为off - - allow_alter_system (boolean) + + + log_duration (boolean) - allow_alter_system配置参数 + log_duration配置参数 - - 当allow_alter_system被设置为off时,执行ALTER SYSTEM命令会返回错误。 - 这个参数只能在postgresql.conf文件或服务器命令行中设置。默认值为on。 - - 请注意,这个设置不应被视为一种安全特性。它只会禁用ALTER SYSTEM命令, - 不会阻止超级用户使用其他 SQL 命令修改配置。超级用户有很多办法在操作系统层面执行 shell 命令, - 因而无论此设置为何值,都可以修改postgresql.auto.conf。 + 记录每个已完成语句的持续时间。 + 默认值为off。 + 只有超级用户和具有适当SET权限的用户才能更改此设置。 - 关闭这个设置主要适用于由外部工具管理PostgreSQL配置的环境。 - 在这样的环境中,出于好意的超级用户可能会误用ALTER SYSTEM - 来修改配置,而不是通过外部工具进行管理。这可能导致意外行为,例如外部工具稍后更新配置时覆盖这些更改。 - 将此参数设置为off有助于避免这类错误。 + 对于使用扩展查询协议的客户端,解析、绑定和执行步骤的持续时间将被独立记录。 - - 这个参数只控制ALTER SYSTEM的使用。即使allow_alter_system - 被设置为off,存储在postgresql.auto.conf中的设置仍然会生效。 - + + + + 启用log_duration和设置为零之间的区别是,超过log_min_duration_statement强制查询的文本被记录,但这个选项不会。因此,如果log_durationon并且log_min_duration_statement为正值,所有持续时间都将被记录,但是只有超过阈值的语句才会被记录查询文本。这种行为有助于在高负载安装中收集统计信息。 + + - - - - - - - 错误处理 - - - - + - exit_on_error (boolean) + log_error_verbosity (enum) - exit_on_error配置参数 + log_error_verbosity配置参数 - 如果为开(on),任何错误将中止当前会话。默认情况下,这个值被设置为关(off),这样只有 FATAL 错误(致命)将中止会话。 + 控制在服务器日志中记录的每条消息的详细程度。有效值为TERSE, + DEFAULTVERBOSE,每个值都会添加更多字段到显示的消息中。 + TERSE不包括DETAILHINT, + QUERYCONTEXT错误信息的记录。 + VERBOSE输出包括SQLSTATE错误代码 + (另请参见)以及生成错误的源代码文件名、函数名和行号。 + 只有超级用户和具有适当SET权限的用户才能更改此设置。 - + - restart_after_crash (boolean) + log_hostname (boolean) - restart_after_crash配置参数 + log_hostname配置参数 - 当被设置为开(on),PostgreSQL将在一次后端崩溃后自动重新初始化。 - 让这个值设置为开(on)通常是将数据库可用性最大化的最佳方法。但是在某些环境中,例如PostgreSQL被集群软件调用时,禁用重启可能很有用,这样集群软件可以得到控制并且采取它认为适当的行动。 - - - - 这个参数只能在postgresql.conf文件中或通过服务器命令行进行设置。 + 默认情况下,连接日志消息只显示连接主机的 IP 地址。打开这个参数将导致也记录主机名。注意根据你的主机名解析设置,这可能会导致很微小的性能损失。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 - + - data_sync_retry (boolean) + log_line_prefix (string) - data_sync_retry配置参数 + log_line_prefix配置参数 - 如果设置为关(off),PostgreSQL在将修改的数据文件刷新到文件系统失败时,将引发PANIC级错误。 - 这样会导致数据库服务器崩溃。这个参数只能在服务器启动时被设置。 - - - - 在某些操作系统上,回写失败后,内核页面缓存中的数据状态未知。 在某些情况下,它可能已被完全遗忘,因此重试不安全;第二次尝试可能报告为成功,而事实上数据已丢失。在此类情形下,避免数据丢失的唯一方法是在报告任何故障后从WAL中恢复,最好是在调查了故障的根本原因并更换了任何有故障的硬件之后。 + 这是一个printf风格的字符串,它在每个日志行的开头输出。 + %字符开始转义序列,它将被按照下文描述的替换成状态信息。 + 未识别的转义被忽略。其他字符被直接复制到日志行。某些转义只被会话进程识别并且被主服务器进程等后台进程当作空。 + 通过指定一个在%之后和该选项之前的数字可以让状态信息左对齐或右对齐。 + 负值将导致在右边用空格填充状态信息已达到最小宽度,而正值则在左边填充。填充对于日志文件的人类可读性大有帮助。 - 如果设置为开(on),PostgreSQL将报告错误,但会继续运行,以便可以在以后的检查点中重试数据刷新操作。 - 仅在调查操作系统假如回写失败时对缓冲数据的处理方式的情况下,才将其设置为开(on)。 + 这个参数只能在postgresql.conf文件中或在服务器命令行上设置。默认值是'%m [%p] ',它记录时间戳和进程ID。 - - - + + + - recovery_init_sync_method (enum) - - recovery_init_sync_method 配置参数 - - - + + 转义 + 效果 + 只限会话 + + + - - 当设置为fsync,也就是默认值,PostgreSQL将在崩溃恢复开始之前递归地打开并同步数据目录中的所有文件。 - 对文件的搜索将遵循WAL目录和每个配置表空间的符号链接(而不是任何其它符号链接)。 - 这是为了确保在重现更改之前,所有WAL和数据文件都持久地存储在硬盘上。 - 这适用于在启动没有完全关闭的数据库集簇时,包括由pg_basebackup创建的副本。 - + + %a + 应用名 + + - - 在Linux上,可以用syncfs代替,请求操作系统来同步包含数据目录的整个文件系统,WAL文件和每个表空间(但不是通过符号链接可访问到的任何其他文件系统)。 - 这可能比fsync设置快得多,因为它不需要逐个打开每个文件。 - 另一方面,如果一个文件系统是被其他需要修改大量文件的应用程序共享的,它可能会慢一些,因为这些文件也将写入硬盘。 - 此外,在5.8之前的Linux版本中,向磁盘写入数据时遇到的I/O错误可能不会报告给PostgreSQL,相关的错误消息可能只出现在内核日志中。 - + + %u + 用户名 + + - - 这个参数只能在postgresql.conf文件中或者服务器命令行中设置。 - - - + + %d + 数据库名 + + - + + %r + 远程主机名或 IP 地址,以及远程端口 + + - + + %h + 远程主机名或 IP 地址 + + - + + %b + 后端类型 + + - 预置选项 + + %p + 进程 ID + + - - 下列参数是只读的。 - 同样,它们被排除在postgresql.conf文件示例之外。 - 这些选项报告特定应用可能感兴趣的多种PostgreSQL行为,特别是管理前端相关的行为。 - 所有这些都是在PostgreSQL被编译或者它被安装时决定的。 - + + %P + 并行组leader的进程ID,如果该进程是一个并行查询worker + no + - + + %t + 无毫秒的时间戳 + + - + + %m + 带毫秒的时间戳 + + - block_size (integer) - - block_size配置参数 - - - + + %n + 带毫秒的时间戳(作为 Unix 时代) + no + - - 报告一个磁盘块的大小。它由编译服务器时BLCKSZ的值确定。默认值是 8192 字节。有些配置变量的含义(例如)会被block_size影响。详见。 - - - + + %i + 命令标签:会话当前命令的类型 + + - + + %e + SQLSTATE 错误代码 + + - data_checksums (boolean) - - data_checksums配置参数 - - - + + %c + 会话 ID:见下文 + + + + + %l + 对每个会话或进程的日志行号,从 1 开始 + + + + + %s + 进程开始的时间戳 + + + + + %v + 虚拟事务 ID (backendID/localXID) + + + + + %x + 事务 ID (如果未分配则为 0) + + + + + %q + 不产生输出,但是告诉非会话进程在字符串的这一点停止;会话进程忽略 + + + + + %Q + 当前查询的查询标识符。 + 查询标识符默认是不计算的,所以这个部分将是零,除非 参数被激活或者配置了计算查询标识符的第三方模块 + yes + + + + %% + 字面字符 % + + + + + + + + 后端类型对应视图 pg_stat_activity中的backend_type列。 + 但是其他类型可能会出现在日志中而不显示在该视图中。 + + + + %c转义打印一个准唯一的会话标识符,它由两个 4 字节的十六进制数(不带先导零)组成,以点号分隔。 + 这些数字是进程启动时间和进程 ID,因此%c也可以被用作保存打印这些项的方式的空间。 + 例如,要从pg_stat_activity生成会话标识符,使用这个查询: + +SELECT to_hex(trunc(EXTRACT(EPOCH FROM backend_start))::integer) || '.' || + to_hex(pid) +FROM pg_stat_activity; + - - 报告对这个集簇是否启用了数据校验码。详见 + + + + + 如果你为log_line_prefix设置了非空值,你通常应该让它的最后一个字符为空格,这样用以提供和日志行的剩余部分的视觉区别。也可以使用标点符号。 + + + + + + + Syslog产生自己的时间戳和进程 ID 信息,因此如果你记录到syslog你可能不希望包括那些转义。 + + + + + + + 在包括仅在会话(后端)上下文中可用的信息(如用户名或者数据库名)时,%q转义很有用。例如: + +log_line_prefix = '%m [%p] %q%u@%d/%a ' + + + + + + + + 对于输出的行,%Q 总是报告零标识符, + 因为log_statement在标识符能被计算之前生成输出,包括无效标识符不能计算的无效语句。 + + - + - data_directory_mode (integer) + log_lock_waits (boolean) - data_directory_mode配置参数 + log_lock_waits配置参数 - 在Unix系统上,这个参数报告启动时的数据目录(由定义)的权限。 - (在Microsoft Windows上这个参数将总是显示0700。) - 更多信息请参考。 + 控制当会话等待时间超过以获取锁时是否生成日志消息。 + 这对于确定锁等待是否导致性能不佳很有用。默认值为off。 + 只有超级用户和具有适当SET权限的用户才能更改此设置。 - - + + - + - debug_assertions (boolean) + log_recovery_conflict_waits (boolean) - debug_assertions 配置参数 + log_recovery_conflict_waits 配置参数 - 报告PostgreSQL是否在构建时启用了断言。 - 如果在构建PostgreSQL时定义了宏 - USE_ASSERT_CHECKING(例如通过 - configure选项), - 则会报告已启用。默认情况下,PostgreSQL是在未启用断言的情况下构建的。 + 控制启动进程等待时间超过针对恢复冲突的deadlock_timeout的时候是否产生日志消息。 + 这对于决定恢复冲突是否会阻止恢复应用WAL有所帮助。 - - - - huge_pages_status (enum) - - huge_pages_status配置参数 - - - - 报告当前实例中大页的状态:onoff 或 - unknown(当通过postgres -C查看时)。 - 这个参数有助于确定在huge_pages=try时分配大页是否成功。 - 更多信息参见。 + 默认为off。 + 这个参数只能在postgresql.conf文件中或服务器命令行中设置。 - - + + - - integer_datetimes (boolean) + + + + log_parameter_max_length (integer) - integer_datetimes配置参数 + log_parameter_max_length 配置参数 - 报告PostgreSQL是否在编译时打开了 64 位整数日期和时间。从PostgreSQL 10起,这个值总是on。 + 如果大于零,则记录在非错误语句日志消息中的每个绑定参数值都会被截断为指定的字节数。 + 零表示禁用非错误语句日志中绑定参数的记录。 + -1(默认值)允许完整记录绑定参数。 + 如果未指定单位,则默认为字节。 + 只有超级用户和具有适当SET权限的用户才能更改此设置。 + + + + 此设置仅影响作为结果打印的日志消息,, 和相关的设置。 + 该设置的非零值会增加一些开销,特别是当参数以二进制形式发送时,因为需要转换为文本。 - + - in_hot_standby (boolean) + log_parameter_max_length_on_error (integer) - in_hot_standby 配置参数 + log_parameter_max_length_on_error 配置参数 - 报告服务器当前是否处于热备模式。 - 当这个是on的时候,所有的事务强制为只读。 - 在会话中,这个只能在服务器提升为主库的时候变更。 - 更多信息参见 + 如果大于零,则错误消息中报告的每个绑定参数值都将裁剪为这么多字节。 + 零(默认值)禁止在错误消息中包含绑定参数。-1允许打印完整绑定参数。 + 如果指定此值时没有单位,则将其作为字节。 - - - - - max_function_args (integer) - - max_function_args配置参数 - - - - 报告函数参数的最大数量。它由编译服务器时的FUNC_MAX_ARGS值决定的。默认值是 100 个参数。 + 该设置的非零值会增加开销,由于PostgreSQL需要在每条语句的开始处将参数值的文本表示存储在内存中,无论最终是否会发生错误。 + 当绑定参数以二进制形式发送时,开销比以文本形式发送时更大,因为前者需要数据转换,而后者只需要复制字符串。 - + - max_identifier_length (integer) + log_statement (enum) - max_identifier_length配置参数 + log_statement配置参数 - 报告标识符的最大长度。它由编译服务器时的NAMEDATALEN值减一决定。NAMEDATALEN的默认值是 64 ;因此max_identifier_length的默认值是 63,但是在使用多字节编码时可以少于 63 个字符。 + 控制哪些 SQL 语句被记录。有效值是 + none (off)、ddlmod和 + all(所有语句)。ddl记录所有数据定义语句,例如CREATEALTER和 + DROP语句。mod记录所有ddl语句,外加数据修改语句例如INSERT, + UPDATEDELETETRUNCATE, + 和COPY FROM。 + 如果PREPAREEXECUTE和 + EXPLAIN ANALYZE包含合适类型的命令,它们也会被记录。对于使用扩展查询协议的客户端,当收到一个执行消息时会产生日志并且会包括绑定参数的值(任何内嵌的单引号会被双写)。 + + + + 默认值为none。 + 只有超级用户和具有适当SET权限的用户才能更改此设置。 + + + + + 即使使用log_statement = all设置,包含简单语法错误的语句也不会被记录。这是因为只有在完成基本语法解析并确定了语句类型之后才会发出日志消息。在扩展查询协议的情况下,在执行阶段之前(即在解析分析或规划期间)出错的语句也不会被记录。将log_min_error_statement设置为ERROR(或更低)来记录这种语句。 + + + + 记录的语句可能会透露敏感数据,甚至包含明文密码。 + + - + - max_index_keys (integer) + log_replication_commands (boolean) - max_index_keys配置参数 + log_replication_commands 配置参数 - 报告索引键的最大数目。它由编译服务器时的INDEX_MAX_KEYS值决定。默认值是 32 个键。 + 每个复制命令都会被记录在服务器日志中。 + 有关复制命令的更多信息,请参见。 + 默认值为off。 + 只有超级用户和具有适当SET权限的用户才能更改此设置。 - + - - num_os_semaphores (integer) + + + log_temp_files (integer) - num_os_semaphores配置参数 + log_temp_files配置参数 + - 根据配置的最大连接数()、允许的自动清理工作进程数()、 - 允许的 WAL 发送进程数()、允许的后台进程数()等, - 报告服务器所需的信号量数量。 + 控制临时文件名和大小的日志记录。 + 临时文件可以用于排序、哈希和临时查询结果。 + 如果通过此设置启用,每当删除临时文件时都会发出日志记录。 + 值为零时记录所有临时文件信息,而正值仅记录大小大于或等于指定数据量的文件。 + 如果未指定单位,则将其视为千字节。 + 默认设置为-1,禁用此类日志记录。 + 只有超级用户和具有适当SET权限的用户才能更改此设置。 - + - segment_size (integer) + log_timezone (string) - segment_size配置参数 + log_timezone配置参数 - 报告一个文件段中可以存储的块(页)的数量。由编译服务器时的RELSEG_SIZE值决定。一个段文件的最大尺寸(以字节计)等于segment_size乘以block_size,默认是 1GB。 + 设置在服务器日志中写入的时间戳的时区。和不同,这个值是集簇范围的,因此所有会话将报告一致的时间戳。内置默认值是GMT,但是通常会被在postgresql.conf中覆盖。initdb将安装一个对应于其系统环境的设置。详见。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 - - - server_encoding (string) - - server_encoding配置参数 - - character set - - - - - 报告数据库的编码(字符集)。这是在数据库被创建时决定的。通常,客户端只需要关心的值。 - - - - - + + + - server_version (string) - - server_version配置参数 - - - + 使用 CSV 格式的日志输出 - 报告服务器版本数值。它是由编译服务器时的PG_VERSION值决定的。 - - - - - - - server_version_num (integer) - - server_version_num配置参数 - - - + 在log_destination列表中包括csvlog提供了一种便捷方式将日志文件导入到一个数据库表。这个选项发出逗号分隔值(CSV)格式的日志行,包括这些列: + 带毫秒的时间戳、 + 用户名、 + 数据库名、 + 进程 ID、 + 客户端主机:端口号、 + 会话 ID、 + 每个会话的行号、 + 命令标签、 + 会话开始时间、 + 虚拟事务 ID、 + 普通事务 ID、 + 错误严重性、 + SQLSTATE 代码、 + 错误消息、 + 错误消息详情、 + 提示、 + 导致错误的内部查询(如果有)、 + 错误位置所在的字符计数、 + 错误上下文、 + 导致错误的用户查询(如果有且被log_min_error_statement启用)、 + 错误位置所在的字符计数、 + 在 PostgreSQL 源代码中错误的位置(如果log_error_verbosity被设置为verbose)以及应用名,后端类型,并行组leader的进程ID和查询ID。 + 下面是一个定义用来存储 CSV 格式日志输出的样表: - - 报告服务器版本数值的整数值。它是由编译服务器时的PG_VERSION_NUM值决定的。 + +CREATE TABLE postgres_log +( + log_time timestamp(3) with time zone, + user_name text, + database_name text, + process_id integer, + connection_from text, + session_id text, + session_line_num bigint, + command_tag text, + session_start_time timestamp with time zone, + virtual_transaction_id text, + transaction_id bigint, + error_severity text, + sql_state_code text, + message text, + detail text, + hint text, + internal_query text, + internal_query_pos integer, + context text, + query text, + query_pos integer, + location text, + application_name text, + backend_type text, + leader_pid integer, + query_id bigint, + PRIMARY KEY (session_id, session_line_num) +); + - - - - - - shared_memory_size (integer) - - shared_memory_size配置参数 - - - - 报告主共享内存区域的大小,四舍五入到最接近的兆字节。 - - - - - - - - shared_memory_size_in_huge_pages (integer) - - shared_memory_size_in_huge_pages配置参数 - - - + 使用COPY FROM命令将一个日志文件导入到这个表中: - - 报告基于指定的所需的主共享内存区域的大页数。 - 如果不支持大页,这将是-1。 + +COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; + + 也可以作为外部表访问该文件,使用提供的 模块。 - 这个设置仅在Linux上受支持。在其他平台上,它始终设置为-1。 - 有关在Linux上使用大页的更多详细信息,请参见。 - - - + 你可以做一些事情来简化导入 CSV 日志文件: - + + + + 设置log_filenamelog_rotation_age为你的日志文件提供一种一致的、可预测的命名空间。这让你预测文件名会是怎样以及知道什么时候一个个体日志文件完成并且因此准备好被导入。 + + - ssl_library (string) - - ssl_library 配置参数 - - - + + + 将log_rotation_size设置为 0 来禁用基于尺寸的日志轮转,因为它使得日志文件名难以预测。 + + - - 报告此PostgreSQL服务器已构建的 SSL 库的名称(即使此实例当前未配置或使用 SSL), - 例如OpenSSL,或一个空字符串(如果没有)。 - - - + + + 将log_truncate_on_rotation设置为on,这样在同一个文件中旧日志数据不会与新数据混杂。 + + - + + + 上述表定义包括一个主键声明。这有助于避免意外地两次导入相同的信息。COPY命令一次提交所有它导入的数据,因此任何错误将导致整个导入失败。如果你导入一个部分完成的日志文件并且稍后当它完全完成后再次导入,主键违背将导致导入失败。请等到日志完成且被关闭之后再导入。这个过程也可以避免意外地导入部分完成的行,这种行也将导致COPY失败。 + + + + + + - wal_block_size (integer) - - wal_block_size配置参数 - - - + 使用JSON格式的日志输出 - - 报告一个 WAL 磁盘块的尺寸。由编译服务器时的XLOG_BLCKSZ值决定。默认是 8192 字节。 - - - + + 包括jsonloglog_destination列表中提供了一种方便的方式将日志文件导入到许多不同的程序中。此选项以JSON格式发出日志行。 + - + + 字段值为null的字符串字段将被排除在输出之外。 + 未来可能会添加其他字段。处理jsonlog输出的用户应忽略未知字段。 + - wal_segment_size (integer) - - wal_segment_size配置参数 - - - + + 每个日志行都被序列化为一个JSON对象,其中包含一组键和它们对应的值,如中所示。 + - - 报告 WAL 段文件的大小。默认是 16MB。详见。 - - - + - - + JSON日志条目的键和值 + + - + + 键名 + 类型 + 描述 + + + - 自定义选项 + + timestamp + string + 带毫秒的时间戳 + - - 这个特性被设计用来由附加模块向PostgreSQL添加通常不为系统知道的参数(例如过程语言)。这允许使用标准方法配置扩展模块。 - + + user + string + 用户名 + - - 自定义选项有两部分名称:一个扩展名,然后是一个句点,再然后是正确的参数名,就像 SQL 中的合格名称。一个示例是plpgsql.variable_conflict。 - + + dbname + string + 数据库名称 + - - 因为自定义选项可能需要在尚未加载相关扩展模块的进程中设置, - PostgreSQL将接受任何两部分参数名称的设置。 - 这些变量被视为占位符,在定义它们的模块加载之前没有任何功能。 - 当加载扩展模块时,它将添加其变量定义并根据这些定义转换任何占位符值。 - 如果存在以其扩展名开头的任何未识别的占位符,将发出警告并删除这些占位符。 - - + + pid + number + 进程ID + - + + remote_host + string + 客户端主机 + - 开发者选项 + + remote_port + number + 客户端端口 + + + + session_id + string + 会话ID + + + + line_num + number + 每个会话的行号 + + + + ps + string + 当前ps显示 + + + + session_start + string + 会话开始时间 + + + + vxid + string + 虚拟事务ID + + + + txid + string + 常规事务 ID + + + + error_severity + string + 错误严重性 + + + + state_code + string + SQLSTATE代码 + + + + message + string + 错误消息 + + + + detail + string + 错误消息的详细信息 + + + + hint + string + 错误消息提示 + + + + internal_query + string + 导致错误的内部查询 + + + + internal_position + number + 内部查询的游标索引 + + + + context + string + 错误上下文 + + + + statement + string + 客户提供的查询字符串 + + + + cursor_position + number + 查询字符串中的光标索引 + + + + func_name + string + 错误位置函数名称 + + + + file_name + string + 错误位置的文件名 + + + + file_line_num + number + 错误位置的文件行号 + + + + application_name + string + 客户端应用程序名称 + + + + backend_type + string + 后端类型 + + + + leader_pid + number + 活动并行工作者的领导者进程ID + + + + query_id + number + 查询ID + + + +
+
+ + + + 进程标题 - 下面的参数目的是用在开发测试上, 并且永远不能用于生产数据库。 - 但是,它们中的一些能够用于帮助恢复严重损坏的数据库。 - 同样,它们被从示例postgresql.conf文件中排除。 - 请注意许多这些参数要求特殊的源代码编译标志才能工作。 + 这些设置控制服务器进程的进程标题如何被修改。进程标题通常可以用ps或者 Windows 上的进程浏览器等程序来查看。详见 - + - allow_in_place_tablespaces (boolean) + cluster_name (string) - allow_in_place_tablespaces配置参数 + cluster_name 配置参数 - 允许将表空间创建为pg_tblspc内的目录,当CREATE TABLESPACE命令提供空位置字符串时。 - 这旨在允许测试主库和备库在同一台机器上运行的复制场景。这样的目录可能会混淆备份工具,因为这些工具期望在该位置只找到符号链接。 - 只有超级用户和具有适当SET权限的用户才能更改此设置。 + 设置一个用于各种目的、标识此数据库集簇(实例)的名称。集簇名称会出现在此集簇所有服务器进程的进程标题中。 + 此外,它还是备库连接的默认应用名称(参见)。 + + + + 这个名称可以是任何长度少于NAMEDATALEN个字符(在标准编译中是 64字符)的任何字符串。只有可打印的 ASCII 字符能被用在cluster_name值中。其他字符将被替换为问号(?)。如果这个参数被设置为空字符串''(也是默认值),将不会显示名称。这个参数只能在服务器启动时设置。 - + - allow_system_table_mods (boolean) + update_process_title (boolean) - allow_system_table_mods配置参数 + update_process_title 配置参数 - 允许修改系统表的结构以及对系统表进行某些其他风险操作。即使对于超级用户,这也通常是不允许的。 - 不明智地使用此设置可能导致无法检索的数据丢失或严重损坏数据库系统。 + 每次服务器接收到新的SQL命令时,都可以更新进程标题。 + 在大多数平台上,默认情况下此设置为on,但在Windows上默认为off, + 因为该平台更新进程标题的开销较大。 只有超级用户和具有适当SET权限的用户才能更改此设置。 - + + + +
- + - backtrace_functions (string) + 运行时统计数据 + + + + 累积查询和索引统计 + + + 这些参数控制服务器范围内的累积统计系统。 + 启用后,收集的数据可以通过pg_statpg_statio + 系列系统视图进行访问。有关更多信息,请参阅。 + + + + + + + track_activities (boolean) - backtrace_functions 配置参数 + track_activities配置参数 - 这个参数包含一个以逗号分隔的C函数名称列表。 - 如果出现错误,并且发生错误的内部C函数的名称与列表中的值相匹配,那么将向服务器日志中写入一个回溯跟踪信息和错误消息。 - 这可以用来调试源代码的特定区域。 - - - - 回溯支持并非在所有平台上都可以使用,并且回溯的质量取决于编译选项。 - - - + 启用对每个会话当前执行命令的信息收集,包括其标识符和命令开始执行的时间。 + 此参数默认为开启状态。请注意,即使启用了此信息,只有超级用户、具有 + pg_read_all_stats角色权限的角色和拥有被报告会话的用户 + (包括属于他们具有权限的角色的会话)才能看到此信息,因此不应构成安全风险。 只有超级用户和具有适当SET权限的用户才能更改此设置。 - - debug_copy_parse_plan_trees (boolean) + + + track_activity_query_size (integer) - debug_copy_parse_plan_trees配置参数 + track_activity_query_size配置参数 - - 启用该选项会强制所有解析树和计划树都经过copyObject()处理, - 以便更容易发现copyObject()中的错误和遗漏。默认值为关闭。 - - 只有在编译时定义了DEBUG_NODE_TESTS_ENABLED时,这个参数才可用; - 使用configure选项时会自动定义该宏。 + 为每个活动会话指定存储当前执行命令的文本所保留的内存量,它们被用于pg_stat_activity.query域。 + 如果指定值时没有单位,则以字节为单位。默认值是 1024字节。这个参数只能在服务器启动时被设置。 - + - debug_discard_caches (integer) + track_counts (boolean) - debug_discard_caches 配置参数 + track_counts配置参数 - 当设置为1时,每个系统目录缓存条目在第一个可能的机会时失效,不管任何使之无效的事情是否真的发生。 - 作为结果,系统目录的缓存被有效地禁用,因此服务器将运行得非常缓慢。 - 较高的值递归地运行缓存失效,这样会更慢,而且只用于测试缓存逻辑自身。 - 默认值0选择正常的目录缓存行为。 + 启用对数据库活动的统计信息收集。 + 此参数默认为开启,因为自动清理守护进程需要收集的信息。 + 只有超级用户和具有适当SET权限的用户才能更改此设置。 + + - - 当试图触发涉及并发目录更改的难以复现的错误时,此参数非常有用,但除此之外它不太被需要。 - 详情请参见源码文件inval.cpg_config_manual.h。 - - - 只有在编译时定义了DISCARD_CACHES_ENABLED时,这个参数才受支持; - 使用configure选项时会自动定义该宏。 - 在生产构建中,它的值始终为0,尝试将其设置为其他值会引发错误。 - - - - - debug_io_direct (string) + + track_io_timing (boolean) - debug_io_direct配置参数 + track_io_timing 配置参数 - 要求内核使用O_DIRECT(大多数类 Unix 系统)、F_NOCACHE(macOS) - 或FILE_FLAG_NO_BUFFERING(Windows),尽量减小关系数据和 WAL 文件缓存的影响。 + 启用数据库 I/O 调用的计时。此参数默认关闭,因为计时需要反复向操作系统查询 + 当前时间,在某些平台上可能会产生显著开销。可以使用 工具 + 测量本系统上的计时开销。I/O 计时信息会显示在 + pg_stat_database 中、 + 使用 BUFFERS 选项的 输出中、 + 使用 VERBOSE 选项的 输出中, + autovacuum 也会在执行自动清理和自动分析时输出这些信息 + (需设置 ), + 同样提供这些信息。只有超级用户和具有适当 + SET 权限的用户可以更改此设置。 + + - - 可以将其设置为空字符串(默认值)以禁用直接 I/O,也可以设置为应使用直接 I/O 的操作列表, - 各项之间用逗号分隔。有效选项包括data(主数据文件)、 - wal(WAL 文件)和wal_init(WAL 文件初始分配时)。 - 这个参数只能在服务器启动时设置。 - + - - 某些操作系统和文件系统不支持直接 I/O,因此非默认设置可能会在启动时被拒绝或导致错误。 - + track_wal_io_timing (boolean) + + track_wal_io_timing 配置参数 + + + - 目前该特性会降低性能,仅用于开发人员测试。 - + 启用 WAL I/O 调用的计时。此参数默认关闭,因为它会反复向操作系统查询当前时间,可能在某些平台上产生显著开销。可以使用 pg_test_timing 工具测量系统上的计时开销。I/O 计时信息显示在 pg_stat_wal 中。只有超级用户和具有适当 SET 权限的用户才能更改此设置。 + - + - debug_parallel_query (enum) + track_functions (enum) - debug_parallel_query 配置参数 + track_functions配置参数 - 允许出于测试目的使用并行查询,即使预计不会带来性能收益也是如此。 - debug_parallel_query的允许值为off(仅在预期会提高性能时使用并行模式), - on(对所有被认为安全的查询强制使用并行查询), - 以及regress(类似于on,但有下文所述的额外行为变化)。 + 启用函数调用次数和时间的跟踪。指定pl以仅跟踪过程语言函数, + all以同时跟踪SQL和C语言函数。默认值为none, + 即禁用函数统计跟踪。只有超级用户和具有适当SET权限的用户才能更改此设置。 - - 更具体地说,将该值设置为on会在任何看起来安全的查询计划顶部添加一个 - Gather节点,以便查询在并行工作进程中运行。即使并行工作进程不可用或 - 无法使用,启动子事务等在并行查询上下文中被禁止的操作也将被禁止,除非规划器认为这样会导致查询失败。 - 如果设置此选项时出现故障或意外结果,则可能需要将查询使用的一些函数标记为 - PARALLEL UNSAFE(或可能是PARALLEL RESTRICTED)。 - + - - 将该值设置为regress会产生与设置为on相同的所有效果, - 并额外启用一些行为,以便自动回归测试。通常,来自并行工作进程的消息会包含一行上下文说明, - 但regress会抑制这一行,因此输出与非并行执行时相同。 - 此外,由该设置添加到计划中的Gather节点会在EXPLAIN输出中被隐藏, - 以便输出与此设置为off时得到的结果一致。 - + + 简单到足以被内联到调用查询中的 SQL 语言函数不会被跟踪, 而不管这个设置。 + + - - debug_raw_expression_coverage_test (boolean) + + + stats_fetch_consistency (enum) - debug_raw_expression_coverage_test配置参数 + stats_fetch_consistency配置参数 - - 启用该选项会强制所有 DML 语句的原始解析树都经过raw_expression_tree_walker()扫描, - 以便更容易发现该函数中的错误和遗漏。默认值为关闭。 - - 只有在编译时定义了DEBUG_NODE_TESTS_ENABLED时,这个参数才可用; - 使用configure选项时会自动定义该宏。 + 确定在事务中多次访问累积统计信息时的行为。当设置为 + none时,每次访问都会重新从共享内存中获取计数器。 + 当设置为cache时,对对象的统计信息的第一次访问会将这些统计信息缓存, + 直到事务结束,除非调用pg_stat_clear_snapshot()。 + 当设置为snapshot时,第一次访问统计信息会缓存当前数据库中所有可访问的统计信息, + 直到事务结束,除非调用pg_stat_clear_snapshot()。 + 在事务中更改此参数会丢弃统计快照。默认值为cache + + + + none适用于监控系统。如果值只被访问一次,它是最有效的。 + cache确保重复访问产生相同的值,这对涉及自连接的查询很重要。 + snapshot在交互式检查统计信息时可能很有用,但开销较高, + 特别是存在许多数据库对象时。 + + - - debug_write_read_parse_plan_trees (boolean) + + + + + + 统计监控 + + + + + compute_query_id (enum) - debug_write_read_parse_plan_trees配置参数 + compute_query_id 配置参数 - - 启用该选项会强制所有解析树和计划树都经过outfuncs.c/readfuncs.c处理, - 以便更容易发现这些模块中的错误和遗漏。默认值为关闭。 - - 只有在编译时定义了DEBUG_NODE_TESTS_ENABLED时,这个参数才可用; - 使用configure选项时会自动定义该宏。 + 启用查询标识符的内核计算。 + 查询标识符可以在 pg_stat_activity + 视图中显示,使用 EXPLAIN,或者如果通过 + 参数进行配置,则可以在日志中发出。 + 扩展还需要计算查询标识符。 + 请注意,如果内核查询标识符计算方法不可接受,也可以使用外部模块。 + 在这种情况下,必须始终禁用内核计算。 + 有效值为 off(始终禁用), + on(始终启用),auto, + 允许诸如 这样的模块 + 自动启用它,并且 regress 具有与 + auto 相同的效果,只是查询标识符不会显示在 + EXPLAIN 输出中,以便促进自动回归测试。 + 默认值为 auto + + + + 为确保只有一个查询标识符被计算和显示,计算查询标识符的扩展在查询标识符已被计算时应当抛出一个错误。 + + - + - ignore_system_indexes (boolean) + log_statement_stats (boolean) - ignore_system_indexes配置参数 + log_statement_stats配置参数 + + + + log_parser_stats (boolean) + + log_parser_stats配置参数 + + + + log_planner_stats (boolean) + + log_planner_stats配置参数 + + + + log_executor_stats (boolean) + + log_executor_stats配置参数 - 读取系统表时忽略系统索引(但是修改系统表时依然同时更新索引)。这在从被破坏的系统索引中恢复数据的时有用。这个参数在会话开始之后不能被更改。 + 对于每个查询,将各自模块的性能统计输出到服务器日志中。这是一个简单的性能分析工具,类似于Unix getrusage()操作系统功能。 + log_statement_stats报告总语句统计,而其他选项报告每个模块的统计信息。 + log_statement_stats不能与任何单独模块选项一起启用。所有这些选项默认情况下都是禁用的。 + 只有超级用户和具有适当SET权限的用户才能更改这些设置。 - + - post_auth_delay (integer) + + + + + 自动清理 + + + 自动清理 + 配置参数 + + + + 这些设置控制autovacuum特性的行为。详情请参考 + 。注意很多这些设置可以被针对每个表 + 的设置所覆盖,参见。 + + + + + + + autovacuum (boolean) - post_auth_delay配置参数 + autovacuum配置参数 - 执行认证过程后启动新服务器进程时延迟的时间量。这是为了给开发者们一个机会在一个服务器进程上附加一个调试器。 - 如果指定值时没有单位,则以秒为单位。0值(默认值)禁用延迟。这个参数在会话开始之后不能被更改。 + 控制服务器是否运行自动清理启动器后台进程。默认为开启, + 不过要自动清理正常工作还需要启用。 + 该参数只能在postgresql.conf文件或服务器命令行中设置, + 不过,通过更改表存储参数可以为表禁用自动清理。 - - - + + 注意即使该参数被禁用,系统也会在需要防止事务ID回卷时发起自动清理进程。详情请见。 + + + - pre_auth_delay (integer) + + + + + autovacuum_max_workers (integer) - pre_auth_delay配置参数 + autovacuum_max_workers配置参数 - - 在新服务器进程分叉后,在进行认证过程之前,延迟的时间量。这是为了给开发者们一个机会在一个服务器进程上附加一个调试器来跟踪认证过程中的不当行为。 - 如果指定值时没有单位,则以秒为单位。0值(默认值)禁用延迟。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 - - - + + 指定能同时运行的自动清理进程(除了自动清理启动器之外)的最大数量。默认值为3。该参数只能在服务器启动时设置。 + - + + - trace_notify (boolean) + + + autovacuum_naptime (integer) - trace_notify配置参数 + autovacuum_naptime配置参数 - 为LISTENNOTIFY命令生成大量调试输出。必须是DEBUG1或者更低才能把这种输出分别发送到客户端或者服务器日志。 + 指定自动清理在任意给定数据库上各次运行之间的最小间隔。在每一轮中后台进程检查数据库并根据需要为数据库中的表发出VACUUMANALYZE命令。 + 如果指定值时没有单位,则以秒为单位。默认值为1分钟(1min)。该参数只能在postgresql.conf文件或在服务器命令行上设置。 - - - + + - trace_sort (boolean) + + + + + autovacuum_vacuum_threshold (integer) - trace_sort配置参数 + autovacuum_vacuum_threshold + 配置参数 - 如果打开,发出在排序操作中的资源使用的相关信息。只有在编译PostgreSQL时定义了TRACE_SORT宏, 这个参数才可用(不过,当前在默认情况下就定义了TRACE_SORT)。 + 指定能在一个表上触发VACUUM的被更新或被删除元组的最小数量。默认值为50个元组。该参数只能在postgresql.conf文件或在服务器命令中设置。但是对个别表可以通过修改表存储参数来覆盖该设置。 - + - trace_locks (boolean) + autovacuum_vacuum_insert_threshold (integer) - trace_locks配置参数 + autovacuum_vacuum_insert_threshold + 配置参数 - 如果开启,发出锁使用情况的信息。被转储信息中包括锁操作的类型、锁的类型和 被锁或被解锁对象的唯一标识符。同样包括的还有已经授予这个对象的锁类型的位掩码和 等待这个对象的锁类型的位掩码。对每一种锁类型,已授权锁和等待锁的计数也会被一起转储。一个日志文件输出的示例如下: - -LOG: LockAcquire: new: lock(0xb7acd844) id(24688,24696,0,0,0,1) - grantMask(0) req(0,0,0,0,0,0,0)=0 grant(0,0,0,0,0,0,0)=0 - wait(0) type(AccessShareLock) -LOG: GrantLock: lock(0xb7acd844) id(24688,24696,0,0,0,1) - grantMask(2) req(1,0,0,0,0,0,0)=1 grant(1,0,0,0,0,0,0)=1 - wait(0) type(AccessShareLock) -LOG: UnGrantLock: updated: lock(0xb7acd844) id(24688,24696,0,0,0,1) - grantMask(0) req(0,0,0,0,0,0,0)=0 grant(0,0,0,0,0,0,0)=0 - wait(0) type(AccessShareLock) -LOG: CleanUpLock: deleting: lock(0xb7acd844) id(24688,24696,0,0,0,1) - grantMask(0) req(0,0,0,0,0,0,0)=0 grant(0,0,0,0,0,0,0)=0 - wait(0) type(INVALID) - - 被转储结构体的详细信息可以在src/include/storage/lock.h中找到。 - - - - 只有在编译PostgreSQL时定义了LOCK_DEBUG宏, 这个参数才可用。 + 指定在任何一个表中触发 VACUUM所需要插入的元组数。默认值为 1000 个元组。 + 如果指定了 -1,则autovacuum不会根据插入数量在任何表上触发 VACUUM操作。 + 此参数只能在postgresql.conf文件或服务器命令行中设置;但可以通过更改表存储参数来覆盖单个表的设置。 - + - trace_lwlocks (boolean) + autovacuum_analyze_threshold (integer) - trace_lwlocks配置参数 + autovacuum_analyze_threshold + 配置参数 - 如果开启,发出轻量级锁的使用信息。轻量级锁主要是为了提供对共享内存数据结构的互斥访问。 - - - - 只有在编译PostgreSQL时定义了LOCK_DEBUG宏, 这个参数才可用。 + 指定能在一个表上触发ANALYZE的被插入、被更新或被删除元组的最小数量。默认值为50个元组。该参数只能在postgresql.conf文件或在服务器命令中设置。但是对个别表可以通过修改表存储参数来覆盖该设置。 - + - trace_userlocks (boolean) + autovacuum_vacuum_scale_factor (floating point) - trace_userlocks配置参数 + autovacuum_vacuum_scale_factor + 配置参数 - 如果开启,发出关于用户锁使用的信息。与trace_locks的输出一样,但只用于咨询锁。 - - - - 只有在编译PostgreSQL时定义了LOCK_DEBUG宏, 这个参数才可用。 + 指定一个表尺寸的分数,在决定是否触发VACUUM时将它加到autovacuum_vacuum_threshold上。默认值为0.2(表尺寸的20%)。该参数只能在postgresql.conf文件或在服务器命令中设置。但是对个别表可以通过修改表存储参数来覆盖该设置。 - + - trace_lock_oidmin (integer) + autovacuum_vacuum_insert_scale_factor (floating point) - trace_lock_oidmin配置参数 + autovacuum_vacuum_insert_scale_factor + 配置参数 - 如果设置,不会跟踪小于这个 OID 的锁(用于避免在系统表上的输出)。 - - - - 只有在编译PostgreSQL时定义了LOCK_DEBUG宏, 这个参数才可用。 + 指定一个要添加到autovacuum_vacuum_insert_threshold 中的表的大小的比例,在决定是否触发VACUUM时。 + 默认值为 0.2(表大小的 20%)。此参数只能在postgresql.conf文件或服务器命令行中设置;但可以通过更改表存储参数来覆盖单个表的设置。 - + - trace_lock_table (integer) + autovacuum_analyze_scale_factor (floating point) - trace_lock_table配置参数 + autovacuum_analyze_scale_factor + 配置参数 - 无条件地跟踪此表(OID)上的锁。 - - - - 只有在编译PostgreSQL时定义了LOCK_DEBUG宏, 这个参数才可用。 + 指定一个表尺寸的分数,在决定是否触发ANALYZE时将它加到autovacuum_analyze_threshold上。默认值为0.1(表尺寸的10%)。该参数只能在postgresql.conf文件或在服务器命令中设置。但是对个别表可以通过修改表存储参数来覆盖该设置。 - + - debug_deadlocks (boolean) + autovacuum_freeze_max_age (integer) - debug_deadlocks配置参数 + autovacuum_freeze_max_age + 配置参数 - 如果设置,当死锁超时发生时,转储所有当前锁的信息。 + 指定在一个VACUUM操作被强制执行来防止表中事务ID回卷之前,一个表的pg_class.relfrozenxid域能保持的最大年龄(事务的)。注意即便自动清理被禁用,系统也将发起自动清理进程来阻止回卷。 - 只有在编译PostgreSQL时定义了LOCK_DEBUG宏, 这个参数才可用。 + 清理也允许从pg_xact子目录中移除旧文件,这也是为什么默认值被设置为较低的2亿事务。该参数只能在服务器启动时设置,但是对于个别表可以通过修改表存储参数来降低该设置。详见 - + - log_btree_build_stats (boolean) + autovacuum_multixact_freeze_max_age (integer) - log_btree_build_stats配置参数 + autovacuum_multixact_freeze_max_age + 配置参数 - 如果设置,会记录 B-树操作上的系统资源使用情况统计(内存和 CPU)。 + 指定在一个VACUUM操作被强制执行来防止表中多事务ID回卷之前,一个表的pg_class.relminmxid域能保持的最大年龄(多事务的)。注意即便自动清理被禁用,系统也将发起自动清理进程来阻止回卷。 - 只有在编译PostgreSQL时定义了BTREE_BUILD_STATS宏, 这个参数才可用。 + 清理多事务也允许从pg_multixact/memberspg_multixact/offsets子目录中移除旧文件,这也是为什么默认值被设置为较低的4亿个多事务。该参数只能在服务器启动时设置,但是对于个别表可以通过修改表存储参数来降低该设置。详见 - + - wal_consistency_checking (string) + autovacuum_vacuum_cost_delay (floating point) - wal_consistency_checking配置参数 + autovacuum_vacuum_cost_delay + 配置参数 - 这个参数被设计用来检查WAL重做例程中的缺陷。当这个参数被启用时,被修改的任何缓冲区的整页镜像及其WAL记录都被加入到记录中。如果该记录后来被重放,系统将首先应用每个记录然后测试该记录修改的缓冲区是否符合存储的镜像。在某些情况下(例如提示位),小的变动是可以接受的,并且会被忽略。任何预期之外的差别都将导致致命错误,最后中止恢复。 - - - - 默认值为空字符串,表示禁用该功能。可以设置为all以检查所有记录, - 或者设置为逗号分隔的资源管理器列表,以仅检查来自这些资源管理器的记录。目前支持的资源管理器有 - heapheap2btreehash、 - gingistsequencespgist、 - bringeneric。扩展可以定义额外的资源管理器。只有超级用户和具有 - 适当SET权限的用户才能更改此设置。 + 指定用于自动VACUUM操作中的代价延迟值。如果指定-1,则使用值。 + 如果指定值时没有单位,则以毫秒为单位。默认值为2毫秒。该参数只能在postgresql.conf文件或在服务器命令中设置。但是对个别表可以通过修改表存储参数来覆盖该设置。 - + - wal_debug (boolean) + autovacuum_vacuum_cost_limit (integer) - wal_debug配置参数 + autovacuum_vacuum_cost_limit + 配置参数 - 如果被打开,WAL 相关的调试输出将被发出。只有在编译PostgreSQL时定义了WAL_DEBUG宏的情况下,这个参数才可用。 + 指定用于自动VACUUM操作中的代价限制值。如果指定-1(默认值),则使用值。注意该值被按比例地分配到运行中的自动清理工作进程上(如果有多个),因此每一个工作进程的限制值之和不会超过这个变量中的值。该参数只能在postgresql.conf文件或在服务器命令中设置。但是对个别表可以通过修改表存储参数来覆盖该设置。 - + + - ignore_checksum_failure (boolean) + + + 客户端连接默认值 + + + + 语句行为 + + + + + client_min_messages (enum) - ignore_checksum_failure配置参数 + client_min_messages配置参数 - 只有当被启用时才有效。 + 控制被发送给客户端的消息级别。有效值是DEBUG5、 + DEBUG4DEBUG3DEBUG2、 + DEBUG1LOGNOTICE、 + WARNINGERROR。 + 每个级别都包括其后的所有级别。级别越靠后,被发送的消息越少。默认值是NOTICE。 + 注意LOG在这里有与中不同的排名。 - 在读取过程中检测到校验和失败通常会导致PostgreSQL报告错误,中止当前事务。 - 将ignore_checksum_failure设置为on会导致系统忽略失败(但仍然报告警告),并继续处理。 - 这种行为可能导致崩溃,传播或隐藏损坏,或其他严重问题。然而,它可能允许您跳过错误, - 并检索可能仍然存在于表中的未损坏的元组,如果块头仍然正常。如果头部损坏,即使启用此选项也会报告错误。 - 默认设置为off。 - 只有超级用户和具有适当SET权限的用户才能更改此设置。 + INFO 级别的消息总是被发送到客户端。 - + - zero_damaged_pages (boolean) + search_path (string) - zero_damaged_pages配置参数 + search_path配置参数 + 路径用于模式 - 检测到损坏的页面头通常会导致PostgreSQL报告错误,中止当前事务。 - 将zero_damaged_pages设置为on会导致系统报告警告,将内存中的损坏页面清零,并继续处理。 - 这种行为会破坏数据,即损坏页面上的所有行。但是,它确实允许您跳过错误,并从表中可能存在的未损坏页面中检索行。 - 如果由于硬件或软件错误而发生损坏,这对于恢复数据很有用。通常在放弃从表的损坏页面恢复数据的希望之前,不应将其设置为on。 - 清零的页面不会强制写入磁盘,因此建议在再次关闭此参数之前重新创建表或索引。默认设置为off。 - 只有超级用户和具有适当SET权限的用户才能更改此设置。 + 这个变量指定当一个对象(表、数据类型、函数等)被用一个无模式限定的简单名称引用时,用于进行搜索该对象的模式顺序。当在不同模式中有同名对象时,将使用第一个在搜索路径中被找到的对象。一个不属于搜索路径中任何一个模式的对象只能通过用限定名(带点号)指定包含它的模式来引用。 - - - + + search_path的值必需是一个逗号分隔的模式名列表。任何不是一个已有模式的名称,或者是一个用户不具有USAGE权限的模式,将被安静地忽略。 + - ignore_invalid_pages (boolean) - - ignore_invalid_pages 配置参数 - - - + + 如果列表项之一是特殊名$user,则具有SESSION_USER返回的名字的模式将取代它(如果有这样一个模式并且该用户有该模式的USAGE权限;如果没有,$user会被忽略)。 + - 如果设置为 off(默认值),则在恢复期间检测到引用无效页面的 WAL 记录会导致 PostgreSQL 引发 PANIC 级别错误,中止恢复。 - 将ignore_invalid_pages设置为on会导致系统忽略 WAL 记录中的无效页面引用(但仍报告警告),并继续恢复。 - 此行为可能会导致崩溃、数据丢失、传播或隐藏腐败,或其他严重问题。 - 但是,它可能允许你通过 PANIC 级错误,完成恢复,并启动服务器。 - 参数只能在服务器启动时设置。它仅在恢复期间或备库模式下生效。 + 系统目录模式pg_catalog总是被搜索,不管它是否在搜索路径中被提及。如果它在路径中被提及,那么它将被按照路径指定的顺序搜索。如果pg_catalog不在路径中,则它将在任何路径项之前被搜索。 - - - + - jit_debugging_support (boolean) - - jit_debugging_support配置参数 - - - + + 同样,如果存在,当前会话的临时表模式pg_temp_nnn总是被搜索。 + 可以通过使用别名pg_temppg_temp在路径中显式列出它。 + 如果它没有列在路径中,则首先搜索它(甚至在pg_catalog之前)。 + 然而,临时模式仅用于搜索关系(表、视图、序列等)和数据类型名称。 + 它永远不会用于搜索函数或操作符名称。 + - 如果LLVM有所需要的功能,用GDB注册所生成的函数。这会让调试更加容易。默认设置是off。只有超级用户和具有适当SET权限的用户可以在会话开始时更改这个参数,并且在会话内完全不能更改它。 + 当对象创建时没有指定一个特定目标模式,它们将被放置在search_path中第一个合法模式中。如果搜索路径为空将报告一个错误。 - - - + + 这个参数的缺省值是"$user", public。这种设置支持一个数据库(其中没有用户拥有私有模式,并且所有人共享使用public)、每个用户私有模式及其组合的共享使用。其它效果可以通过全局或者针对每个用户修改默认搜索路径设置获得。 + - jit_dump_bitcode (boolean) - - jit_dump_bitcode配置参数 - - - + + 更多有关方案处理的信息,请参考。特别地,只有当数据库只有一个用户或者有少数的相互信任的用户时,默认配置是合适的。 + - 将生成的LLVM IR写入文件系统,位于内。 - 这仅对于在JIT实现内部工作时有用。默认设置为off。 - 只有超级用户和具有适当SET权限的用户才能更改此设置。 + 搜索路径的当前有效值可以通过SQL函数current_schemas检查(见)。它和检查search_path的值不太一样,因为current_schemas显示出现在search_path中的项如何被解析。 + - + - jit_expressions (boolean) + row_security (boolean) - jit_expressions配置参数 + row_security 配置参数 - 当JIT编译被激活时(见),确定表达式是否用JIT编译。默认值是on。 + 这个变量控制是否以抛出一个错误来代替应用一条行安全性策略。在设置为on时,策略正常应用。在设置为off时,只要有至少一条策略被应用则查询就会失败。默认为on。受限的行可见性会导致不正确的结果时,可将其改成off。例如,pg_dump默认会做这种更改。这个变量对能绕过每一条行安全性策略的角色(即超级用户和具有BYPASSRLS)属性的角色没有效果。 - - - - - - jit_profiling_support (boolean) - - jit_profiling_support配置参数 - - - - 如果LLVM有所需的功能,发出需要的数据以允许perf对JIT生成的函数画像。 - 这会写出文件到~/.debug/jit/中,如果需要,由用户负责对其执行清除。 - 默认设置是off。 - 只有超级用户和具有适当SET权限的用户可以在会话开始时更改这个参数,并且在会话内完全不能更改它。 + 更多关于行安全性策略的信息请见 - + - jit_tuple_deforming (boolean) + default_table_access_method (string) - jit_tuple_deforming配置参数 + default_table_access_method 配置参数 - 当JIT编译被激活时(见),确定元组拆解是否被JIT编译。默认值是on。 + 这个参数指定了在创建表或物化视图时使用的默认表访问方法,如果CREATE命令没有明确指定访问方法, + 或者当使用SELECT ... INTO时,不允许指定表访问方法。默认值是heap - + - remove_temp_files_after_crash (boolean) + default_tablespace (string) - remove_temp_files_after_crash 配置参数 + default_tablespace配置参数 + 表空间默认 - - 当设置为on时,这是默认值,PostgreSQL将在后端崩溃后自动删除临时文件。 - 如果禁用,文件将被保留,并且也许可用于调试,例如。 - 重复的崩溃可能会导致无用文件的积累。 - 该参数只能在postgresql.conf文件中或服务器命令行中设置。 + + 这个变量指定当一个CREATE命令没有显式指定一个表空间时,创建对象(表和索引)的默认表空间。 - - - - send_abort_for_crash (boolean) - - send_abort_for_crash配置参数 - - - - 默认情况下,后端崩溃后,主进程会向其余子进程发送SIGQUIT信号使其停止, - 这样它们可以较为平稳地退出。当该选项设置为on时,则改为发送SIGABRT。 - 这通常会让每个这类子进程生成一个 core dump 文件。这有助于在崩溃后调查其他进程的状态。 - 但在反复崩溃时,它也可能消耗大量磁盘空间,因此不要在未严密监控的系统上启用它。 - 请注意,系统并不支持自动清理这些 core 文件。这个参数只能在postgresql.conf文件中或服务器命令行中设置。 + 该值要么是一个表空间的名字,要么是一个指定使用当前数据库默认表空间的空字符串。如果该值和任何现有表空间的名字都不匹配,PostgreSQL将自动使用当前数据库的默认表空间。如果指定了一个非默认的表空间,用户必须对它有CREATE权限,否则创建企图将失败。 - - - - send_abort_for_kill (boolean) - - send_abort_for_kill配置参数 - - - - 默认情况下,在尝试用SIGQUIT停止子进程之后,主进程会等待五秒, - 然后发送SIGKILL强制立即终止。当该选项设置为on时, - 则会发送SIGABRT而不是SIGKILL。 - 这通常会让每个这类子进程生成一个 core dump 文件。这有助于调查那些卡住的子进程状态。 - 但在反复崩溃时,它也可能消耗大量磁盘空间,因此不要在未严密监控的系统上启用它。 - 请注意,系统并不支持自动清理这些 core 文件。这个参数只能在postgresql.conf文件中或服务器命令行中设置。 + 这个变量不被用于临时表,对临时表会使用 - - - - debug_logical_replication_streaming (enum) - - debug_logical_replication_streaming配置参数 - - - - 允许值为bufferedimmediate。默认值为buffered。 - 这个参数旨在用于测试逻辑解码以及大型事务的复制。 - debug_logical_replication_streaming对发布端和订阅端的影响不同。 + 当创建数据库时也会使用这个变量。默认情况下,一个新数据库会从它的模板数据库继承其表空间设置。 - 在发布端,debug_logical_replication_streaming允许在逻辑解码中立即流式传输或序列化更改。 - 当设置为immediate时,如果 - streaming选项在 - CREATE SUBSCRIPTION中已启用, - 则每条更改都会被流式传输;否则会序列化每条更改。设置为buffered时, - 会在达到logical_decoding_work_mem后再流式传输或序列化更改。 + 当一个分区表建立时如果这个参数被设置为空字符串以外的值,分区表的表空间将被设置为该值,将被用做未来建立分区的默认表空间, + 即使default_tablespace已经改变。 - 在订阅端,如果streaming选项被设置为parallel, - 则debug_logical_replication_streaming可用于控制主应用工作进程是将更改发送到共享内存队列, - 还是将所有更改序列化到文件。设置为buffered时,主进程通过共享内存队列将更改发送给并行应用工作进程。 - 设置为immediate时,主进程会将所有更改序列化到文件,并通知并行应用工作进程在事务结束时读取并应用这些更改。 + 有关表空间的更多的信息,请见 - - - - - 文件位置 + - - 除了前面已经提到的 postgresql.confPostgreSQL - 还会使用另外两个手工编辑的配置文件来控制客户端认证(相关用法见 )。 - 默认情况下,这三个配置文件都存放在数据库集簇的数据目录中。本节所述参数允许把这些配置文件放到别处。 - 这样做有时更便于管理,尤其是当配置文件单独存放时,往往更容易保证它们得到正确备份。 - + default_toast_compression (enum) + + default_toast_compression 配置参数 + + + - - - data_directory - - - 指定用于数据存储的目录。此参数只能在服务器启动时设置。 - - - + + 这个变量设置可压缩列的值所使用的默认TOAST压缩方法。 + (可以在CREATE TABLEALTER TABLE中为单独的列设置 + COMPRESSION列选项,从而覆盖该默认值。) + 支持的压缩方法有pglz,以及 + (如果PostgreSQL编译时启用了) + lz4。默认值为pglz。 + + + - - config_file - - - 指定主服务器配置文件,通常称为 postgresql.conf。 - 此参数只能在 postgres 命令行上设置。 - - - + - - hba_file - - - 指定基于主机的认证配置文件,通常称为 pg_hba.conf。 - 此参数只能在服务器启动时设置。 - - - + temp_tablespaces (string) + + temp_tablespaces配置参数 + + 表空间临时 + + - - ident_file - - - 指定用户名映射配置文件,通常称为 pg_ident.conf。 - 此参数只能在服务器启动时设置。另请参见 。 - - - + + 这个变量指定当一个CREATE命令没有显式指定一个表空间时,创建临时对象(临时表和临时表上的索引)的默认表空间。用于排序大型数据集的临时文件也被创建在这些表空间中。 + - - external_pid_file - - - 指定服务器应创建的额外进程 ID(PID)文件的名称,供服务器管理程序使用。 - 此参数只能在服务器启动时设置。 - - - - + + 该值是一个表空间名字的列表。当列表中有多于一个名称时,每次一个临时对象被创建时PostgreSQL随机选择列表中的一个成员。例外是在一个事务中,连续创建的临时对象被放置在里表中的连续表空间中。如果列表被选中元素是一个空字符串,PostgreSQL将自动使用当前数据库的默认表空间。 + - - 在默认安装中,上述参数都不会被显式设置。数据目录由命令行选项 - 或环境变量 PGDATA 指定,而各个配置文件都位于数据目录中。 - + + 当temp_tablespaces被交互式地设置时,指定一个不存在的表空间是一种错误,类似于为用户指定一个不具有CREATE权限的表空间。不过,当使用一个之前设置的值时,不存在的表空间会被忽略,就像用户缺少CREATE权限的表空间一样。特殊地,使用一个在postgresql.conf中设置的值时,这条规则起效。 + - - 如果你希望把配置文件放在数据目录之外,那么 postgres - 命令行选项或 PGDATA 环境变量必须指向包含这些配置文件的目录,而 - postgresql.conf 中(或命令行上)的 data_directory - 参数必须指出数据目录的实际位置。请注意,data_directory 会覆盖 - PGDATA 对数据目录位置的指定,但不会覆盖配置文件的位置。 - + + 默认值是一个空字符串,它使得所有临时对象被创建在当前数据库的默认表空间中。 + - - 如果愿意,你也可以使用 config_filehba_file - 和/或 ident_file 分别指定各个配置文件的名称和位置。 - config_file 只能在 postgres 命令行上指定,而其他参数可以写在主配置文件里。 - 如果这三个参数以及 data_directory 都显式设置了,那么就不必再指定 PGDATA。 - + + 参阅。 + + + - - 设置这些参数时,相对路径会按 postgres 的启动目录来解释。 - - + - - 连接和认证 + check_function_bodies (boolean) + + check_function_bodies配置参数 + + + - - 连接设置 + + 这个参数通常为打开。 + 当设置为off时,它禁用期间对例程体字符串的验证。 + 禁用验证避免了验证处理的副作用,特别避免了如向前引用导致的伪肯定。 + 在代表其他用户载入函数之前设置这个参数为offpg_dump会自动这样做。 + + + - - - listen_addresses - - - 指定服务器监听客户端连接时使用的 TCP/IP 地址。值采用逗号分隔的主机名和/或数值 IP 地址列表。 - 特殊项 * 表示所有可用的 IP 接口。0.0.0.0 表示监听全部 IPv4 地址, - :: 表示监听全部 IPv6 地址。如果列表为空,服务器将完全不监听任何 IP 接口, - 此时只能通过 Unix 域套接字连接。如果列表不为空,只要至少有一个 TCP/IP 地址可监听,服务器就会启动。 - 任何无法打开的 TCP/IP 地址都会给出警告。默认值是 localhost, - 只允许本地 TCP/IP 回环连接。 - + - - 客户端认证()控制谁可以访问服务器,而 - listen_addresses 控制哪些接口接受连接尝试,这有助于减少在不安全网络接口上的恶意重复连接请求。 - 此参数只能在服务器启动时设置。 - - - + default_transaction_isolation (enum) + + 事务隔离级别 + 设置默认值 + + + default_transaction_isolation配置参数 + + + - - port - - - 服务器监听的 TCP 端口,默认是 5432。请注意,服务器监听的所有 IP 地址都使用同一个端口号。 - 此参数只能在服务器启动时设置。 - - - + + 每个 SQL 事务都有一个隔离级别,可以是读未提交读已提交可重复读或者可串行化。这个参数控制每个新事务的默认隔离级别。默认是读已提交。 + - - max_connections - - - 决定数据库服务器允许的最大并发连接数。默认值通常是 100 个连接,但如果内核设置不支持这一点, - 该值可能会更小(由 initdb 期间的检测决定)。此参数只能在服务器启动时设置。 - + + 更多信息请参阅。 + + + - - 当运行备库时,这个参数必须设置为与主库相同或更高的值,否则备库上将不允许查询。 - - - + - - superuser_reserved_connections - - - 决定为 PostgreSQL 超级用户保留多少个连接槽位。 - 同时活跃的连接数最多只能达到 。 - 当活跃连接数达到 max_connections 减去 superuser_reserved_connections 时, - 新连接只接受超级用户,且不会再接受新的复制连接。 - + default_transaction_read_only (boolean) + + 只读事务 + 设置默认值 + + + default_transaction_read_only配置参数 + + + - - 默认值是 3 个连接。该值必须小于 max_connections。此参数只能在服务器启动时设置。 - - - + + 一个只读的 SQL 事务不能修改非临时表。这个参数控制每个新事务的默认只读状态 。默认是off(读/写)。 + - - unix_socket_directories - - - 指定服务器监听客户端连接时使用的 Unix 域套接字目录。通过以逗号分隔的多个目录,可以创建多个套接字。 - 各项之间的空白会被忽略;如果目录名中需要包含空白或逗号,请用双引号括起来。 - 空值表示不监听任何 Unix 域套接字,此时只能使用 TCP/IP 套接字连接服务器。 - + + 更多信息请参考。 + + + - - 以 @ 开头的值表示应在抽象命名空间中创建 Unix 域套接字(目前仅 Linux 支持)。 - 此时该值并不是一个目录,而是用于计算实际套接字名的前缀,方式与文件系统命名空间相同。 - 虽然抽象套接字名前缀可以自由选择,但通常仍使用类似文件系统的值,例如 @/tmp。 - + - - 默认值通常是 /tmp,但可在编译时改变。在 Windows 上,默认值为空, - 这表示默认不会创建 Unix 域套接字。此参数只能在服务器启动时设置。 - + default_transaction_deferrable (boolean) + + 可延迟事务 + 设置默认值 + + + default_transaction_deferrable配置参数 + + + - - 除了套接字文件本身(命名为 .s.PGSQL.nnnn, - 其中 nnnn 是服务器端口号)之外,每个 unix_socket_directories - 目录中还会创建一个名为 .s.PGSQL.nnnn.lock 的普通文件。 - 这两个文件都不应手工删除。抽象命名空间中的套接字不会创建锁文件。 - - - + + 当运行在可串行化隔离级别时,一个可延迟只读 SQL 事务可以在它被允许继续之前延迟一段时间。但是,一旦它开始执行就不会产生任何用来保证可串行化性的负荷;因此串行化代码将没有任何理由因为并发更新而强制它中断,使得这个选项适合于长时间运行的只读事务。 + - - unix_socket_group - - - 设置 Unix 域套接字所属的组。套接字的属主始终是启动服务器的用户。与 - unix_socket_permissions 配合使用时,它可以作为 Unix 域连接的额外访问控制机制。 - 默认值是空字符串,表示使用服务器用户的默认组。此参数只能在服务器启动时设置。 - + + 这个参数控制每个新事务的默认可延迟状态。目前它对读写事务或者那些操作在低于可串行化隔离级别上的事务无效。默认值是off。 + - - Windows 不支持此参数,任何设置都会被忽略。抽象命名空间中的套接字没有文件属主,因此这种情况下该设置也会被忽略。 - - - + + 更多信息请参考。 + + + - - unix_socket_permissions - - - 设置 Unix 域套接字的访问权限。Unix 域套接字使用标准 Unix 文件系统权限。参数值应使用 - chmodumask 接受的八进制形式表示;如果使用自定义八进制格式,数字必须以 0 开头。 - + - - 默认权限是 0777,表示任何人都可以连接。常见的合理取值是 0770 - (只有属主和同组用户可访问,见 unix_socket_group)以及 0700 - (只有属主可访问)。请注意,对 Unix 域套接字来说,只有写权限真正重要,因此没有读取和执行权限的区别。 - + transaction_isolation (enum) + + 事务隔离级别 + + + transaction_isolation配置参数 + + + - - 此访问控制机制与 中的用户认证无关。 - + + 此参数反映当前事务的隔离级别。在每个事务开始时,它被设置为 + 的当前值。 + 任何后续更改它的尝试都相当于命令。 + + + - - 此参数只能在服务器启动时设置。 - + - - 对完全忽略套接字权限的系统,此参数没有效果,尤其是 Solaris 10 及以上版本。在这些系统上, - 可以把 unix_socket_directories 指向一个只允许特定用户搜索的目录,以获得类似效果。 - + transaction_read_only (boolean) + + 只读事务 + + + transaction_read_only 配置参数 + + + - - 抽象命名空间中的套接字没有文件权限,因此这种情况下该设置也会被忽略。 - - - + + 此参数反映当前事务的只读状态。 + 在每个事务的开始,它被设置为的当前值。 + 任何后续尝试更改它的都等同于命令。 + + + - - bonjour - - - 通过 Bonjour 广播服务器存在。默认值为关闭。此参数只能在服务器启动时设置。 - - - + - - bonjour_name - - - 指定 Bonjour 服务名。空字符串 ''(默认值)表示使用计算机名。 - 如果编译时未启用 Bonjour 支持,则此参数会被忽略。此参数只能在服务器启动时设置。 - - - + transaction_deferrable (boolean) + + 可延迟事务 + + + transaction_deferrable 配置参数 + + + - - tcp_keepalives_idle - - - 指定在网络活动停止多久之后,操作系统应向客户端发送 TCP keepalive 消息。 - 如果指定值没有单位,则按秒计算。值 0(默认值)表示使用操作系统默认值。 - 在 Windows 上,设为 0 会把该参数设为 2 小时,因为 Windows 无法读取系统默认值。 - 该参数仅在支持 TCP_KEEPIDLE 或等效套接字选项的系统以及 Windows 上可用;其他系统必须为零。 - 通过 Unix 域套接字连接时,此参数会被忽略,并始终视为零。 - - - - - - tcp_keepalives_interval - - - 指定未被客户端确认的 TCP keepalive 消息在多久之后应当重传。 - 如果指定值没有单位,则按秒计算。值 0(默认值)表示使用操作系统默认值。 - 在 Windows 上,设为 0 会把该参数设为 1 秒,因为 Windows 无法读取系统默认值。 - 该参数仅在支持 TCP_KEEPINTVL 或等效套接字选项的系统以及 Windows 上可用;其他系统必须为零。 - 通过 Unix 域套接字连接时,此参数会被忽略,并始终视为零。 - - - + + 此参数反映当前事务的可延迟性状态。 + 在每个事务的开始,它被设置为的当前值。 + 任何后续尝试更改它的都等同于命令。 + + + - - tcp_keepalives_count - - - 指定在连接被判定为断开之前,允许重试的 keepalive 消息次数。默认值和系统默认值取决于平台。 - 通过 Unix 域套接字连接时,此参数会被忽略,并始终视为零。 - - - + - - tcp_user_timeout - - - 指定在发送了未确认的数据后,TCP 连接允许保持未完成状态的最长时间。 - 如果指定值没有单位,则按毫秒计算。值 0 表示使用操作系统默认值。 - 该参数仅在支持 TCP_USER_TIMEOUT 套接字选项的系统上可用;通过 Unix 域套接字连接时会被忽略。 - - - + session_replication_role (enum) + + session_replication_role配置参数 + + + - - client_connection_check_interval - - - 指定服务器检查客户端连接是否仍然存活的时间间隔。 - 如果客户端连接已经断开,服务器会尽快终止后端进程并清理资源。 - 如果指定值没有单位,则按秒计算。默认值为 0,表示不做额外检查。 - - - - + + 控制当前会话中复制相关触发器和规则的触发。 + 可能的值是origin(默认值), + replicalocal。 + 设置此参数会导致丢弃先前缓存的任何查询计划。 + 只有超级用户和具有适当SET权限的用户才能更改此设置。 + - - 下列参数控制客户端认证方式以及与 SSL 连接相关的行为。 - + + 这个设置的预期用途是由逻辑复制系统在应用所复制的更改时将它设置为replica。 + 其效果将是触发器和规则(没有对其默认配置做修改)在复制机上将不会被触发。 + 更多信息请参考ALTER TABLE的子句ENABLE TRIGGER以及ENABLE RULE。 + - - - authentication_timeout - - - 指定等待客户端完成认证的最长时间。超时后,服务器会断开连接。 - 如果指定值没有单位,则按秒计算。默认值为 1 分钟。此参数只能在服务器启动时设置。 - - - + + PostgreSQL在内部会把设置originlocal同样对待。第三方复制系统可能会把这两个值用于其内部目的,例如把local用来标出一个不应复制其更改的会话。 + - - password_encryption - - - 指定用来加密新密码的算法。可用值取决于编译时支持的算法;默认值应当与当前版本的安全默认值一致。 - 该参数只影响新写入的密码,不会重新加密已有密码。 - - - + + 因为外键被实现为触发器,将这个参数设置为replica还会禁用所有的外键检查,如果使用不当可能会让数据处于一种不一致的状态。 + + + - - krb_server_keyfile - - - 指定 Kerberos 服务器密钥文件的位置。此参数只能在服务器启动时设置。 - - - + - - krb_caseins_users - - - 指定 Kerberos 用户名是否按大小写不敏感方式处理。默认值为关闭。 - - - + statement_timeout (integer) + + statement_timeout配置参数 + + + - - db_user_namespace - - - 开启后,用户名会带有数据库名前缀,从而允许不同数据库中的同名用户共存。默认值为关闭。 - - - + + 中止任何使用了超过指定时间量的语句。 + 如果log_min_error_statement被设置为ERROR或更低,语句如果超时也会被记录。 + 如果指定值时没有单位,则以毫秒为单位。一个零值(默认)将禁用超时。 + - - ssl - - - 是否启用 SSL 连接。默认值为关闭。此参数只能在服务器启动时设置。 - - - + + 超时从命令到达服务器的时间开始计算,一直到它被服务器完成为止。 + 如果单个简单查询消息中出现多个 SQL 语句,超时将分别应用于每个语句。(PostgreSQL 13 之前的版本通常将超时应用于整个查询字符串。 + 在扩展查询协议中,当任何与查询相关的消息(解析、绑定、执行、描述)到达时,超时就开始运行,并且可以通过执行完成或同步消息来取消超时。 + - - ssl_ca_file - - - 指定用于验证客户端证书的 CA 文件。默认值为空。此参数只能在服务器启动时设置。 - - - + + 我们不推荐在postgresql.conf中设置statement_timeout,因为它会影响所有会话。 + + + - - ssl_cert_file - - - 指定服务器证书文件。默认值为 server.crt。此参数只能在服务器启动时设置。 - - - - - ssl_crl_file - - - 指定用于验证证书吊销状态的 CRL 文件。默认值为空。此参数只能在服务器启动时设置。 - - - - - ssl_crl_dir - - - 指定用于验证证书吊销状态的 CRL 目录。默认值为空。此参数只能在服务器启动时设置。 - - - + - - ssl_key_file - - - 指定服务器私钥文件。默认值为 server.key。此参数只能在服务器启动时设置。 - - - + lock_timeout (integer) + + lock_timeout配置参数 + + + - - ssl_ciphers - - - 指定 SSL 连接允许使用的密码套件列表。默认值由编译时和运行时环境决定。此参数只能在服务器启动时设置。 - - - + + 如果任何语句在试图获取表、索引、行或其他数据库对象上的锁时等到超过指定的时间量,该语句将被中止。 + 该时间限制独立地应用于每一次锁获取尝试。该限制会应用到显式锁定请求(如LOCK TABLE或不带NOWAITSELECT FOR UPDATE)和隐式获得的锁。 + 如果指定值时没有单位,则以毫秒为单位。一个零值(默认)将禁用超时。 + - - ssl_prefer_server_ciphers - - - 是否优先使用服务器端的密码套件顺序。默认值为关闭。此参数只能在服务器启动时设置。 - - - + + 与statement_timeout不同,这个超时只在等待锁时发生。注意如果statement_timeout为非零,设置lock_timeout为相同或更大的值没有意义,因为事务超时将总是第一个被触发。 + 如果log_min_error_statement 被设置为ERROR 或更低,超时的语句将被记录。 + - - ssl_ecdh_curve - - - 指定用于 ECDH 密钥交换的椭圆曲线名称。默认值取决于编译时使用的 SSL 库。此参数只能在服务器启动时设置。 - - - + + 我们不推荐在postgresql.conf中设置lock_timeout,因为它会影响所有会话。 + + + - - ssl_min_protocol_version - - - 指定允许的最低 SSL/TLS 协议版本。默认值由运行时库决定。此参数只能在服务器启动时设置。 - - - + - - ssl_max_protocol_version - - - 指定允许的最高 SSL/TLS 协议版本。默认值由运行时库决定。此参数只能在服务器启动时设置。 - - - + idle_in_transaction_session_timeout (integer) + + idle_in_transaction_session_timeout 配置参数 + + + - - ssl_dh_params_file - - - 指定 Diffie-Hellman 参数文件。默认值为空。此参数只能在服务器启动时设置。 - - - + + 终止任何已经闲置(这是指,等待客户端查询)超过这个参数所指定时间量的打开事务的会话。 + 如果这个值指定时没有单位,它被设为毫秒。 + 零值(默认)禁用超时。 + - - ssl_passphrase_command - - - 指定用于获取私钥口令的命令。默认值为空。此参数只能在服务器启动时设置。 - - - + + 此选项可以用于确保空闲会话不会在不合理的时间内持有锁。 + 即使没有持有重要的锁的时候,打开的事务也会防止清理最近死亡的可能只对这个事务可见的元组;所以长时间保持空闲会导致表膨胀。 + 详见。 + + + - - ssl_passphrase_command_supports_reload - - - 指定 ssl_passphrase_command 是否支持在重新加载配置时再次调用。默认值为关闭。 - - - - - - + - - 资源消耗 + idle_session_timeout (integer) + + idle_session_timeout 配置参数 + + + - - 本节描述影响内存、磁盘和后台作业资源使用的参数。 - + + 终止任何空闲的会话(也就是,等待客户端查询),但不在打开的事务中,且超过指定的时间量。 + 如果指定值时不带单位,其单位采用毫秒。 + 零值时(默认)禁用超时。 + - - 内存 + + 不像打开事务的情况,没有事务的空闲会话不会给服务器带来很大的开销,因此启用此超时的需要比idle_in_transaction_session_timeout更少。 + - - - shared_buffers - - - 指定服务器应为共享缓冲区分配多少内存。默认值通常是系统可接受的合理初始值,但在大多数安装中都可以根据工作负载调高。 - 如果指定值没有单位,则按块计算。此参数只能在服务器启动时设置。 - - - + + 注意不要对通过连接池软件或其他中间件建立的连接强制执行此超时,因为这样的层可能不会很好地响应意外的连接关闭。 + 只对交互会话启用此超时可能是帮助的,也许只对特定用户应用它。 + + + + + + vacuum_freeze_table_age (integer) + + vacuum_freeze_table_age配置参数 + + + + + 当表的pg_class.relfrozenxid字段达到该设置指定的年龄时,VACUUM会执行激进扫描。激进扫描与常规VACUUM不同,它会访问每一个可能包含未冻结 XID 或 MXID 的页面,而不仅仅是那些可能包含死元组的页面。默认值是 1.5 亿个事务。尽管用户可以将该值设置为 0 到 20 亿之间的任意值,VACUUM会悄悄将有效值限制为不超过的 95%,从而在触发防回卷 autovacuum 之前仍有机会执行一次常规手工VACUUM。更多信息请参见。 + + + + + + vacuum_freeze_min_age (integer) + + vacuum_freeze_min_age配置参数 + + + + + 指定VACUUM在扫描表时用来决定是否冻结行版本的切断年龄(以事务计)。默认值是 5000 万个事务。尽管用户可以将该值设置为 0 到 10 亿之间的任意值,VACUUM会悄悄将有效值限制为不超过的一半,这样强制 autovacuum 之间就不会间隔过短。更多信息请参见。 + + + + + + vacuum_failsafe_age (integer) + + vacuum_failsafe_age配置参数 + + + + + 指定表的pg_class.relfrozenxid字段在VACUUM采取特别措施以避免系统范围事务 ID 回卷失败之前所允许达到的最大年龄(以事务计)。这是VACUUM的最后防线。失效保护通常会在防止事务 ID 回卷的 autovacuum 已经运行了一段时间后触发,但也有可能在任何VACUUM期间触发。 + + + 当失效保护被触发时,将不再应用任何有效的基于代价的延迟,并且会跳过进一步的非关键维护任务(例如索引清理)。 + + + 默认值为 16 亿个事务。尽管用户可以将该值设置为 0 到 21 亿之间的任意值,VACUUM会悄悄将有效值调整为不低于的 105%。 + + + + + + vacuum_multixact_freeze_table_age (integer) + + vacuum_multixact_freeze_table_age配置参数 + + + + + 当表的pg_class.relminmxid字段达到该设置指定的年龄时,VACUUM会执行激进扫描。激进扫描与常规VACUUM不同,它会访问每一个可能包含未冻结 XID 或 MXID 的页面,而不是只扫描那些可能包含死元组的页面。默认值是 1.5 亿个多事务。尽管用户可以将该值设置为 0 到 20 亿之间的任意值,VACUUM会悄悄将有效值限制为不超过的 95%,从而在触发防回卷 autovacuum 之前仍有机会执行一次常规手工VACUUM。更多信息请参见。 + + + + + + vacuum_multixact_freeze_min_age (integer) + + vacuum_multixact_freeze_min_age配置参数 + + + + + 指定VACUUM在扫描表时用来决定是否将多事务 ID 替换为较新的事务 ID 或多事务 ID 的切断年龄(以多事务计)。默认值是 500 万个多事务。尽管用户可以将该值设置为 0 到 10 亿之间的任意值,VACUUM会悄悄将有效值限制为不超过的一半,这样强制 autovacuum 之间就不会间隔过短。更多信息请参见。 + + + + + + vacuum_multixact_failsafe_age (integer) + + vacuum_multixact_failsafe_age 配置参数 + + + + + 指定表的 pg_class.relminmxid 字段在 VACUUM 采取特别措施避免系统范围的多事务 ID 回卷故障之前,所能达到的最大年龄(以多事务计)。这是 VACUUM 的最后手段。失效保护通常会在防止事务 ID 回卷的自动清理已经运行一段时间后触发,但也可能在任何 VACUUM 期间触发。 + + + 触发失效保护后,任何正在生效的基于代价的延迟都将不再应用,后续非必要的维护任务(例如索引清理)也会被跳过。 + + + 默认值为 16 亿个多事务。虽然用户可以将此值设置为 0 到 21 亿之间的任意值,VACUUM 仍会将实际生效值自动调整为不低于 的 105%。 + + + + + + + bytea_output (enum) + + bytea_output配置参数 + + + + + + 设置bytea类型值的输出格式。有效值是hex(默认)和 escape(传统的 PostgreSQL 格式)。详见。不管这个设置的值如何,bytea类型总是接受这两种格式的输入。 + + + + + + + xmlbinary (enum) + + xmlbinary配置参数 + + + + + + 设置二进制值如何被编码为 XML。例如,这适用于通过xmlelement函数或xmlforest函数将bytea值转换到 XML 值。可能的值有base64hex,它们都是用 XML 模式标准定义的。默认值是base64。更多关于 XML 相关函数的信息可参阅。 + + + + 这里的实际选择都是根据爱好做出的,只受客户端应用中可能存在的限制的约束。两种方法都支持所有可能的值,尽管十六进制编码将比 base64 编码更大。 + + + + + + + xmloption (enum) + + xmloption配置参数 + + + SET XML OPTION + + + XML 选项 + + + + + + 当在XML和字符串值之间进行转换时,无论设置DOCUMENT或 CONTENT都是隐式的。可参阅Section 8.13。 有效值是DOCUMENT和CONTENT。 缺省值是CONTENT。当在 XML 和字符串值之间进行转换时,设置DOCUMENTCONTENT都是隐式的。详见。有效值是DOCUMENTCONTENT。默认值是CONTENT。 + + + + 根据 SQL 标准,设置这个选项的命令是: + +SET XML OPTION { DOCUMENT | CONTENT }; + + 这种语法在 PostgreSQL 也可用。 + + + + + + + gin_pending_list_limit (integer) + + gin_pending_list_limit + 配置参数 + + + + + + 设置fastupdate被启用时可以使用的 GIN索引的待处理列表的最大尺寸。 + 如果该列表增长到超过这个最大尺寸,会通过批量将其中的项移入索引的主 GIN 数据结构来清理列表。 + 如果指定值时没有单位,则以千字节为单位。默认值是四兆字节(4MB)。 + 可以通过更改索引的存储参数来为个别 GIN 索引覆盖这个设置。更多信息请见。 + + + + + + restrict_nonsystem_relation_kind (string) + + restrict_nonsystem_relation_kind配置参数 + + + + + 设置禁止访问非系统关系的关系类型。该值采用关系类型的逗号分隔列表形式。 + 目前支持的关系类型是viewforeign-table。 + + + + + + + + + 区域和格式化 + + + + + + DateStyle (string) + + DateStyle配置参数 + + + + + + 设置日期和时间值的显示格式,以及解释有歧义的日期输入值的规则。由于历史原因, 这个变量包含两个独立的部分:输出格式声明(ISOPostgresSQLGerman)、 输入/输出的年/月/日顺序(DMYMDYYMD)。这些可以被独立设置或者一起设置。关键字EuroEuropeanDMY的同义词;关键字USNonEuroNonEuropeanMDY的同义词。详见。内置默认值是ISO, MDY,但是initdb将用对应于选中的lc_time区域行为的设置初始化配置文件。 + + + + + + + IntervalStyle (enum) + + IntervalStyle配置参数 + + + + + + 设置间隔值的显示格式。值sql_standard将产生匹配 SQL 标准间隔文本的输出。当参数被设置为ISO时,值postgres(默认)将产生匹配PostgreSQL发行 8.4 之前的输出。当DateStyle参数被设置为非ISO输出时,值postgres_verbose会产生匹配PostgreSQL发行 8.4 之前的输出。值iso_8601会产生匹配在 ISO 8601 的 4.4.3.2 节中定义的带标志符格式的时间间隔的输出。 + + + + IntervalStyle参数也可以影响对有歧义的间隔输入的解释。详见。 + + + + + + + TimeZone (string) + + TimeZone配置参数 + + 时区 + + + + + 设置用于显示和解释时间戳的时区。内置默认值是GMT,但是它通常会在postgresql.conf中被覆盖;initdb将安装一个对应于其系统环境的设置。详见。 + + + + + + + timezone_abbreviations (string) + + timezone_abbreviations配置参数 + + 时区名称 + + + + + 设置服务器接受的日期时间输入中使用的时区缩写集合。默认值为'Default', 这个集合在全世界大多数地方都能工作。也还有'Australia''India',以及可能为一种特定安装定义的其他集合。详见。 + + + + + + + extra_float_digits (integer) + + 有效数字 + + + 浮点数 + 显示 + + + extra_float_digits配置参数 + + + + + + 这个参数调整用于文本输出浮点值的位数,包括float4float8以及几何数据类型。 + + + + 如果值为1(默认值)或更高,浮点值被输出为最短-精度格式;参见。 + 实际生成的位数只取决于输出的值,而不取决于此参数的值。 + float8 值最多需要 17 位数字,float4值最多需要9位数字。 + 这种格式既快速又精确,在正确读取时精确地保留了原始的二进制浮点值。为了历史兼容性,允许的值最大为3。 + + + + 如果值为零或负,则输出四舍五入为给定的十进制精度。 + 使用的精度是根据此参数的值减小的类型((FLT_DIGDBL_DIG,视情况而定)的标准位数。 + (例如,指定 -1 将导致float4 值输出四舍五入为 5 位有效数字,而float8值四舍五入为 14 位。) + 此格式较慢,不会保留二进制浮点值的所有位,但可能令人更易于阅读。 + + + + + 此参数的含义,以及其默认值,在 PostgreSQL 12 中发生了变化; + 参见 以便进一步讨论。 + + + + + + + + client_encoding (string) + + client_encoding配置参数 + + 字符集 + + + + + 设置客户端编码(字符集)。默认使用数据库编码。PostgreSQL服务器所支持的字符集在中描述。 + + + + + + + lc_messages (string) + + lc_messages配置参数 + + + + + + 设置消息显示的语言。可接受的值是系统相关的;详见。如果这个变量被设置为空字符串(默认),那么该值将以一种系统相关的方式从服务器的执行环境中继承。 + + + + 在一些系统上,这个区域分类并不存在。仍然可以设置这个变量,只是不会有任何效果。同样,所期望语言的翻译消息也可能不存在。在这种情况下,你将仍然继续看到英文消息。 + + + + 只有超级用户和具有适当SET权限的用户才能更改此设置。 + + + + + + + lc_monetary (string) + + lc_monetary配置参数 + + + + + + 设置用于格式化货币量的区域,例如用to_char函数族。可接受的值是系统相关的;详见。如果这个变量被设置为空字符串(默认),那么该值将以一种系统相关的方式从服务器的执行环境中继承。 + + + + + + + lc_numeric (string) + + lc_numeric配置参数 + + + + + + 设置用于格式化数字的区域,例如用to_char函数族。可接受的值是系统相关的;详见。如果这个变量被设置为空字符串(默认),那么该值将以一种系统相关的方式从服务器的执行环境中继承。 + + + + + + + lc_time (string) + + lc_time配置参数 + + + + + + 设置用于格式化日期和时间的区域,例如用to_char函数族。可接受的值是系统相关的;详见。如果这个变量被设置为空字符串(默认),那么该值将以一种系统相关的方式从服务器的执行环境中继承。 + + + + + + + + + default_text_search_config (string) + + default_text_search_config配置参数 + + + + + + 选择被那些没有显式参数指定配置的文本搜索函数变体使用的文本搜索配置。详见。内置默认值是pg_catalog.simple,但是如果能够标识一个匹配区域的配置,initdb将用对应于选中的lc_ctype区域的设置初始化配置文件。 + + + + + + + + + + + 共享库预载入 - - huge_pages - - 控制是否允许主共享内存区域使用大页。可用值通常为 onofftry。 - 此参数只能在服务器启动时设置。 + 为了载入附加的功能或者达到提高性能的目的,可用多个设置来预先载入共享库到服务器中。 + 例如'$libdir/mylib'设置可能会导致mylib.so(或者某些平台上的mylib.sl)从安装的标准库目录被预装载。这些设置之间的区别在于生效的时间以及改变它们所需的权限。 - - - - huge_page_size - - - 指定大页大小。此参数主要用于调试和平台相关配置,通常只有在系统提供多种大页大小时才有意义。 - 此参数只能在服务器启动时设置。 - - - + + 可以用这个方法预装载PostgreSQL的过程语言库,通常是使用'$libdir/plXXX'语法,其中的XXXpgsqlperltclpython。 + + + + 只有特别为与PostgreSQL一起使用设计的共享库才能以这种方式载入。每一个PostgreSQL支持 + 的库都有一个魔法块,它会被检查以保证兼容性。由于这个原因,非PostgreSQL无法 + 以这种方式被载入。你可能可以使用操作系统的工具(如LD_PRELOAD)载入它。 + + + + 总之,请参考特定模块的文档来用推荐的方法载入它。 + + + + + + local_preload_libraries (string) + + local_preload_libraries配置参数 + + + $libdir/plugins + + + + + + 这个变量指定一个或者多个要在连接开始时预载入的共享库。 + 它包含一个由逗号分隔的库名列表,其中每个名称都会按LOAD命令的方式解析。 + 项之间的空格会被忽略,如果需要在库名中包含空格或者逗号,请把库名放在双引号内。 + 这个参数值只在连接开始时生效。后续的更改不会有任何效果。 + 如果一个指定的库没有找到,连接尝试将会失败。 + + + + 任何用户都能设置这个选项。正因为如此,能被这样载入的库被严格限制为出现于安装的标准库 + 目录中plugins子目录下的共享库(保证只有安全的库被安装到 + 这里是数据库管理员的责任)。local_preload_libraries中的项可以显式 + 指定这个目录,例如$libdir/plugins/mylib,或者只是指定库的 + 名称 — mylib 和 + $libdir/plugins/mylib的效果是相同的。 + + + + 这个特性的目的是允许非特权用户在特定的会话中载入正在调试的或者性能度量库, + 而无需一个显式的LOAD命令。为了这个目的,通常通过使用客 + 户端的PGOPTIONS环境变量或者 + ALTER ROLE SET来设置这个参数。 + + + + 不过,除非一个模块被特别设计成由非超级用户以这种方式使用,通常不推荐使用这个设置。应该看看 + 。 + + + + + + + session_preload_libraries (string) + + session_preload_libraries配置参数 + + + + + + 这个变量指定在连接开始时要预加载的一个或多个共享库。 + 它包含一个逗号分隔的库名称列表,其中每个名称的解释方式与LOAD命令相同。 + 条目之间的空格会被忽略;如果需要在名称中包含空格或逗号,请用双引号括起库名称。 + 参数值仅在连接开始时生效。后续更改不会生效。如果指定的库未找到,连接尝试将失败。 + 只有超级用户和具有适当SET权限的用户才能更改此设置。 + + + + 这个特性的意图是允许在特定会话中载入调试用的或者测量性能的库,而不需要显式的给出一个 + LOAD命令。例如,通过用ALTER ROLE SET设置这个参数可以 + 为一个给定用户名下的所有会话启用。还有,无需重启 + 服务器就能更改这个参数(但是只有新会话启动时才会生效),这样可以以这种方式更容易地增 + 加新模块,即便它们会应用到所有会话。 + + + + 和不同,相对于在库被第一次使用 + 时载入它,在会话开始时载入库并没有什么性能优势。不过,当使用连接池时这样做还是有一些 + 优势。 + + + + + + + shared_preload_libraries (string) + + shared_preload_libraries配置参数 + + + + + + 这个变量指定一个或者多个要在服务器启动时预载入的共享库。 + 它包含一个由逗号分隔的库名列表,其中每个名称都会按LOAD命令的方式解析。 + 项之间的空格会被忽略,如果需要在库名中包含空格或者逗号,请把库名放在双引号内。 + 这个参数只能在服务器启动时设置。 + 如果指定的库没有找到,服务器将无法启动。 + + + + 有些库需要执行只能在postmaster启动时发生的特定操作,例如分配共享内存、保留轻量级锁 + 或者启动后台工作者。这些库必须通过这个参数在服务器启动时载入。每个库的详情请见文档。 + + + + 其他库也能被预载入。通过预载入一个共享库,当该库被第一次使用时就可以避免库的启动时间。 + 不过,启动每个新服务器进程的时间可能会略有增加,即使该进程从不使用该库。因此,推荐只 + 把这个参数用于那些要在大多数会话中使用的库上。还有,改变这个参数要求重启服务器,因此 + 对于短期的调试任务来说这不是好的选择,应该转用 + 。 + + + + + + 在 Windows 主机上,在服务器启动时预载入一个库并不会减少启动每个新服务器进程所需的 + 时间;每一个服务器进程将会重新载入预载入的库。不过,对于那些要在postmaster启动时 + 执行操作的库来说,Windows 主机上的 + shared_preload_libraries任然有用。 + + + + + + + + jit_provider (string) + + jit_provider配置参数 + + + + + + 这个变量是要被使用的JIT提供者库的名称(见)。默认是llvmjit。这个参数只能在服务器启动时设置。 + + + + 如果这个变量被设置为一个不存在的库,JIT将不可用,但是也不会发生错误。这种特性允许在主PostgreSQL包之外单独安装JIT支持。 + + + + + + + + + + 其他默认值 + + + + + + dynamic_library_path (string) + + dynamic_library_path配置参数 + + 动态装载 + + + + + 如果需要打开一个可以动态装载的模块并且在CREATE FUNCTIONLOAD命令中指定的文件名没有目录部分(即名字中不包含斜线),那么系统将搜索这个路径以查找所需的文件。 + + + + dynamic_library_path的值必须是一个冒号分隔(或者在 Windows 上以分号分隔)的绝对目录路径的列表。如果一个列表元素以特殊字符串开始,$libdir会被替换为PostgreSQL包中已编译好的库目录。这里是PostgreSQL发布提供的模块被安装的位置(使用pg_config --pkglibdir来找到这个目录的名字)。例如: + +dynamic_library_path = '/usr/local/lib/postgresql:/home/my_project/lib:$libdir' + + 或者在 Windows 环境中: + +dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' + + + + + 这个参数的默认值是'$libdir'。如果该值被设置为一个空字符串,则关闭自动路径搜索。 + + + + 这个参数可以由超级用户和具有适当SET权限的用户在运行时更改, + 但以这种方式进行的设置只会持续到客户端连接结束,因此这种方法应该保留用于开发目的。 + 推荐设置此参数的方法是在postgresql.conf配置文件中。 + + + + + + + + + gin_fuzzy_search_limit (integer) + + gin_fuzzy_search_limit配置参数 + + + + + + GIN 索引返回的集合尺寸的软上限。详见。 + + + + + + + + + + + 锁管理 + + + + + + deadlock_timeout (integer) + + 死锁 + 期间超时 + + + 超时 + 死锁 + + + deadlock_timeout配置参数 + + + + + + 这是在锁上等待的时间,然后再检查是否存在死锁条件。检查死锁相对昂贵,因此服务器不会每次等待锁时都运行它。 + 我们乐观地假设在生产应用程序中死锁并不常见,所以在检查死锁之前只是等待一段时间。 + 增加此值会减少在不必要的死锁检查中浪费的时间,但会减慢实际死锁错误的报告速度。 + 如果未指定单位,则将其视为毫秒。 + 默认值为一秒(1s),这可能是您在实践中想要的最小值。 + 在负载较重的服务器上,您可能希望提高它。 + 理想情况下,设置应超过您的典型事务时间,以提高在等待者决定检查死锁之前释放锁的几率。 + 只有超级用户和具有适当SET权限的用户才能更改此设置。 + + + + 当被设置时,这个参数还可以决定发出关于锁等待的日志之前等待的时间量。如果你想调查锁延迟,你可能希望设置一个比正常的deadlock_timeout小的值。 + + + + + + + max_locks_per_transaction (integer) + + max_locks_per_transaction配置参数 + + + + + + 共享锁表跟踪在max_locks_per_transaction * ( + ) 个对象(如表)上的锁。因此,在任何一个时刻,只有不超过这么多个可区分对象能够被锁住。这个参数控制为每个事务分配的对象锁的平均数量。只要所有事务的锁都能放入锁表中,单个事务就可以锁住更多对象。这是能被锁住的行数,那个值是没有限制的。默认值 64 已经被历史证明是足够的,但是如果你有需要在一个事务中使用很多不同表的查询(例如查询一个有很多子表的父表),你可能需要提高这个值。这个参数只能在服务器启动时设置。 + + + + 运行备库时,必须将此参数设置为大于或等于主库上的值。否则,备库上将不允许查询。 + + + + + + + max_pred_locks_per_transaction (integer) + + max_pred_locks_per_transaction配置参数 + + + + + + 共享谓词锁表跟踪在max_pred_locks_per_transaction * ( + ) 个对象(如表)上的锁。因此,在任何一个时刻,只有不超过这么多个可区分对象能够被锁住。这个参数控制为每个事务分配的对象锁的平均数量。只要所有事务的锁都能放入锁表中,单个事务就可以锁住更多对象。这是能被锁住的行数,那个值是没有限制的。默认值 64 已经在测试中被证明通常是足够的,但是如果你有会在单个可串行化事务中访问许多不同表的客户端,则可能需要提高这个值。这个参数只能在服务器启动时设置。 + + + + + + + max_pred_locks_per_relation (integer) + + max_pred_locks_per_relation配置参数 + + + + + + 这个参数控制在谓词锁被提升为覆盖整个关系之前,该谓词锁能够在单个关系上锁住多少页面或元组。大于等于零的值表示一种绝对限制,而负值表示用除以这个设置的绝对值。默认值为-2,它将保持以往版本的PostgreSQL中的行为。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 + + + + + + + max_pred_locks_per_page (integer) + + max_pred_locks_per_page配置参数 + + + + + + 这个参数控制在谓词锁被提升为覆盖整个页面之前,该谓词锁能在单一页面上锁住多少行。默认值是2。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 + + + + + + + + + + 版本和平台兼容性 + + + + 以前的 PostgreSQL 版本 + + + + + + array_nulls (boolean) + + array_nulls配置参数 + + + + + + 这个参数控制数组输入解析器是否把未用引号的NULL识别为一个空数组元素。默认为on,允许输入包含空值的数组值。但是PostgreSQL 8.2 之前的版本不支持数组中的空值,并且因此将把NULL当作指定一个值为字符串NULL的正常数组元素。对于那些要求旧行为的应用的向后兼容性,这个变量可以被设置为off。 + + + + 注意即使这个变量为off也能够创建包含空值的数组值。 + + + + + + + backslash_quote (enum) + 字符串反斜线引号 + + backslash_quote配置参数 + + + + + + 这个参数控制字符串文本中的单引号是否能够用\'来表示。首选的 SQL 标准的方法是将其双写(''),但是PostgreSQL在历史上也接受\'。不过使用\'容易导致安全风险,因为在某些客户端字符集编码中,有多字节字符的最后一个字节在数值上等价于 ASCII 的\'。如果客户端代码没有做到正确转义,那么将会导致 SQL 注入攻击。如果服务器拒绝看起来带有被反斜线转义的单引号的查询,那么就可以避免这种风险。backslash_quote的可用值是on(总是允许\')、off(总是拒绝)以及safe_encoding(只有客户端编码不允许在多字节字符中存在 ASCII \时允许)。safe_encoding是默认设置。 + + + + 注意在符合标准的字符串文本中,\就表示\。这个参数只影响不符合标准的文本的处理,包括转义字符串语法(E'...')。 + + + + + + + escape_string_warning (boolean) + 字符串转义警告 + + escape_string_warning配置参数 + + + + + + 打开时,如果在普通字符串文本中('...'语法)出现了 一个反斜线(\)并且standard_conforming_strings为关闭,那么就会发出一个警告。默认值是on。 + + + + 希望使用反斜线作为转义符的应用应该被修改来使用转义字符串语法(E'...'),因为在 SQL 标准中普通字符串的默认行为是将反斜线视作一个普通字符。这个变量可以被启用来帮助定位需要被更改的代码。 + + + + + + + lo_compat_privileges (boolean) + + lo_compat_privileges配置参数 + + + + + + 在PostgreSQL 9.0之前的版本中,大对象没有访问权限,因此始终可以被所有用户读取和写入。 + 将此变量设置为on会禁用新的权限检查,以保持与之前版本的兼容性。默认值为off。 + 只有超级用户和具有适当SET权限的用户才能更改此设置。 + + + + 设置这个参数不会禁用所有与大对象相关的安全检查 — 除了那些在PostgreSQL 9.0中已经修改了的默认行为。 + + + + + + + quote_all_identifiers (boolean) + + quote_all_identifiers配置参数 + + + + + + 当数据库产生 SQL 时,强制所有标识符被引号包围,即使它们(当前)不是关键字。这将影响EXPLAIN的输出以及pg_get_viewdef等函数的结果。另请参阅选项。 + + + + + + + standard_conforming_strings (boolean) + 字符串标准符合 + + standard_conforming_strings配置参数 + + + + + + 控制普通字符串文本('...')是否按照 SQL 标准把反斜线当普通文本。从PostgreSQL 9.1 开始,默认值为on(之前的发行中默认值为off)。应用可以检查这个参数来判断字符串文本如何被处理。这个参数的存在也可以被当做转义字符串语法(E'...')被支持的标志。如果一个应用希望反斜线被当做转义字符,应该使用转义字符串语法()。 + + + + + + + synchronize_seqscans (boolean) + + synchronize_seqscans配置参数 + + + + + + 它允许对大型表的顺序扫描与其他扫描同步,因此并发扫描可以在几乎相同的时刻读取相同的块,这样可以分担 I/O 负载。当启用这个参数时,一个扫描可能会从表的中间开始并且之后绕回到开头以覆盖所有的行,这样可以与已在进行中的扫描活动同步。对于没有ORDER BY子句的查询来,这样的扫描会在返回行的顺序中造成不可预料的改变。将这个参数设置为off以保证 8.3 之前的行为(顺序扫描总是从表的起始处开始)。默认值是on。 + + + + + + + + + + 平台和客户端兼容性 + + + + + transform_null_equals (boolean) + IS NULL + + transform_null_equals配置参数 + + + + + + 当打开时,形为expr = NULL(或NULL = expr)的表达式将被当做expr IS NULL, 也就是说,如果expr得出空值值则返回真,否则返回假。正确的 SQL 标准兼容的expr = NULL行为总是返回空(未知)。因此这个参数默认为off。 + + + + 不过,在Microsoft Access里的过滤表单生成的查询似乎使用expr = NULL来测试空值,因此,如果你使用这个接口访问数据库,你可能想把这个选项打开。因为expr = NULL形式的表达式总是返回空值(使用 SQL 标准解释)。它们不是非常有用并且在普通应用中也不常见,在应用中也不常见,因此这个选项实际上没有什么危害。但是新用户常常对涉及 空值的表达式的语义上感到困惑,因此这个选项默认为关闭。 + + + + 请注意这个选项只影响= NULL形式,而不影响其它比较操作符或者其它与一些涉及等值操作符的表达式在计算上等效的其他表达式(例如IN)。因此,这个选项不是劣质程序的一般修复。 + + + + 相关信息请见。 + + + + + + + + + + + + + 错误处理 + + + + + + exit_on_error (boolean) + + exit_on_error配置参数 + + + + + + 如果为开(on),任何错误将中止当前会话。默认情况下,这个值被设置为关(off),这样只有 FATAL 错误(致命)将中止会话。 + + + + + + + restart_after_crash (boolean) + + restart_after_crash配置参数 + + + + + + 当被设置为开(on),PostgreSQL将在一次后端崩溃后自动重新初始化。 + 让这个值设置为开(on)通常是将数据库可用性最大化的最佳方法。但是在某些环境中,例如PostgreSQL被集群软件调用时,禁用重启可能很有用,这样集群软件可以得到控制并且采取它认为适当的行动。 + + + + 这个参数只能在postgresql.conf文件中或通过服务器命令行进行设置。 + + + + + + + data_sync_retry (boolean) + + data_sync_retry配置参数 + + + + + + 如果设置为关(off),PostgreSQL在将修改的数据文件刷新到文件系统失败时,将引发PANIC级错误。 + 这样会导致数据库服务器崩溃。这个参数只能在服务器启动时被设置。 + + + + 在某些操作系统上,回写失败后,内核页面缓存中的数据状态未知。 在某些情况下,它可能已被完全遗忘,因此重试不安全;第二次尝试可能报告为成功,而事实上数据已丢失。在此类情形下,避免数据丢失的唯一方法是在报告任何故障后从WAL中恢复,最好是在调查了故障的根本原因并更换了任何有故障的硬件之后。 + + + + 如果设置为开(on),PostgreSQL将报告错误,但会继续运行,以便可以在以后的检查点中重试数据刷新操作。 + 仅在调查操作系统假如回写失败时对缓冲数据的处理方式的情况下,才将其设置为开(on)。 + + + + + + + recovery_init_sync_method (enum) + + recovery_init_sync_method 配置参数 + + + + + + 当设置为fsync,也就是默认值,PostgreSQL将在崩溃恢复开始之前递归地打开并同步数据目录中的所有文件。 + 对文件的搜索将遵循WAL目录和每个配置表空间的符号链接(而不是任何其它符号链接)。 + 这是为了确保在重现更改之前,所有WAL和数据文件都持久地存储在硬盘上。 + 这适用于在启动没有完全关闭的数据库集簇时,包括由pg_basebackup创建的副本。 + + + + 在Linux上,可以用syncfs代替,请求操作系统来同步包含数据目录的整个文件系统,WAL文件和每个表空间(但不是通过符号链接可访问到的任何其他文件系统)。 + 这可能比fsync设置快得多,因为它不需要逐个打开每个文件。 + 另一方面,如果一个文件系统是被其他需要修改大量文件的应用程序共享的,它可能会慢一些,因为这些文件也将写入硬盘。 + 此外,在5.8之前的Linux版本中,向磁盘写入数据时遇到的I/O错误可能不会报告给PostgreSQL,相关的错误消息可能只出现在内核日志中。 + + + + 这个参数只能在postgresql.conf文件中或者服务器命令行中设置。 + + + + + + + + + + + 预置选项 + + + 下列参数是只读的。 + 同样,它们被排除在postgresql.conf文件示例之外。 + 这些选项报告特定应用可能感兴趣的多种PostgreSQL行为,特别是管理前端相关的行为。 + 所有这些都是在PostgreSQL被编译或者它被安装时决定的。 + + + + + - - temp_buffers - - - 指定每个会话可用于临时表的缓冲区数量。初次访问临时表时才会分配这些缓冲区,因此把这个值设得太大通常问题不大, - 但如果经常创建和使用临时表,合适的值会影响性能。默认值通常为 8MB。此参数只能在会话开始时设置。 - - - + block_size (integer) + + block_size配置参数 + + + - - max_prepared_transactions - - - 指定允许的最大预备事务数。此值至少应与 max_connections 一样大,以便每个会话都能使用预备事务。 - 此参数只能在服务器启动时设置。 - - - + + 报告一个磁盘块的大小。它由编译服务器时BLCKSZ的值确定。默认值是 8192 字节。有些配置变量的含义(例如)会被block_size影响。详见。 + + + + + + + data_checksums (boolean) + + data_checksums配置参数 + + + + + + 报告对这个集簇是否启用了数据校验码。详见。 + + + + + + + data_directory_mode (integer) + + data_directory_mode配置参数 + + + + + + 在Unix系统上,这个参数报告启动时的数据目录(由定义)的权限。 + (在Microsoft Windows上这个参数将总是显示0700。) + 更多信息请参考。 + + + + + + + debug_assertions (boolean) + + debug_assertions 配置参数 + + + + + + 报告PostgreSQL是否在构建时启用了断言。 + 如果在构建PostgreSQL时定义了宏 + USE_ASSERT_CHECKING(例如通过 + configure选项), + 则会报告已启用。默认情况下,PostgreSQL是在未启用断言的情况下构建的。 + + + + + + + + + integer_datetimes (boolean) + + integer_datetimes配置参数 + + + + + + 报告PostgreSQL是否在编译时打开了 64 位整数日期和时间。从PostgreSQL 10起,这个值总是on。 + + + + + + + in_hot_standby (boolean) + + in_hot_standby 配置参数 + + + + + + 报告服务器当前是否处于热备模式。 + 当这个是on的时候,所有的事务强制为只读。 + 在会话中,这个只能在服务器提升为主库的时候变更。 + 更多信息参见 + + + + + lc_collate (string) + + lc_collate 配置参数 + + + + + 报告对文本数据进行排序所使用的区域设置。更多信息参见。 + 此值在创建数据库时确定。 + + + + + + lc_ctype (string) + + lc_ctype 配置参数 + + + + + 报告决定字符分类的区域设置。更多信息参见。 + 此值在创建数据库时确定。通常它与lc_collate相同,但特殊应用可能将它设置为不同的值。 + + + + + + + max_function_args (integer) + + max_function_args配置参数 + + + + + + 报告函数参数的最大数量。它由编译服务器时的FUNC_MAX_ARGS值决定的。默认值是 100 个参数。 + + + + + + + max_identifier_length (integer) + + max_identifier_length配置参数 + + + + + + 报告标识符的最大长度。它由编译服务器时的NAMEDATALEN值减一决定。NAMEDATALEN的默认值是 64 ;因此max_identifier_length的默认值是 63,但是在使用多字节编码时可以少于 63 个字符。 + + + + + + + max_index_keys (integer) + + max_index_keys配置参数 + + + + + + 报告索引键的最大数目。它由编译服务器时的INDEX_MAX_KEYS值决定。默认值是 32 个键。 + + + + + + + + + segment_size (integer) + + segment_size配置参数 + + + + + + 报告一个文件段中可以存储的块(页)的数量。由编译服务器时的RELSEG_SIZE值决定。一个段文件的最大尺寸(以字节计)等于segment_size乘以block_size,默认是 1GB。 + + + + + + + server_encoding (string) + + server_encoding配置参数 + + 字符集 + + + + + 报告数据库的编码(字符集)。这是在数据库被创建时决定的。通常,客户端只需要关心的值。 + + + + + + + server_version (string) + + server_version配置参数 + + + + + + 报告服务器版本数值。它是由编译服务器时的PG_VERSION值决定的。 + + + + + + + server_version_num (integer) + + server_version_num配置参数 + + + + + + 报告服务器版本数值的整数值。它是由编译服务器时的PG_VERSION_NUM值决定的。 + + + + + + + shared_memory_size (integer) + + shared_memory_size配置参数 + + + + + + 报告主共享内存区域的大小,四舍五入到最接近的兆字节。 + + + - - work_mem - - - 指定排序、哈希和其他算子在写入临时文件之前可使用的最大内存量。 - 默认值为 4MB。该值会影响单个操作,而不是整个会话,因此并发查询可能会消耗远高于此值的总内存。 - - - + - - hash_mem_multiplier - - - 指定哈希算子可使用的内存倍率,即在 work_mem 的基础上允许扩展多少倍。 - 默认值为 2.0。增大该值会提高哈希类操作的内存上限,但也会增加内存消耗。 - - - + + shared_memory_size_in_huge_pages (integer) + + shared_memory_size_in_huge_pages配置参数 + + + - - maintenance_work_mem - - - 指定维护操作可使用的最大内存量,例如 VACUUMCREATE INDEX - 以及 ALTER TABLE ADD FOREIGN KEY。默认值通常是 64MB。 - 相比 work_mem,该值通常可以设得更高,因为单个会话一次只执行一个维护操作。 - + + 报告基于指定的所需的主共享内存区域的大页数。 + 如果不支持大页,这将是-1。 + - - 注意,在自动清理运行时,最多可能分配相当于此值乘以 - 的内存,因此不要把默认值设得过高。单独设置 有助于控制这一点。 - - - + + 这个设置仅在Linux上受支持。在其他平台上,它始终设置为-1。 + 有关在Linux上使用大页的更多详细信息,请参见。 + + + - - autovacuum_work_mem - - - 指定每个自动清理工作进程可使用的最大内存量。默认值为 -1,表示改用 - 的值。该设置只影响自动清理上下文中的 VACUUM。 - 此参数只能在 postgresql.conf 中或服务器命令行上设置。 - - - + - - logical_decoding_work_mem - - - 指定逻辑解码在把已解码的更改写入本地磁盘之前可使用的最大内存量。 - 默认值为 64MB。由于每个复制连接只使用一个这样的缓冲区,而集簇通常不会同时拥有很多这类连接, - 因此把该值设得明显高于 work_mem 是安全的。 - - - + ssl_library (string) + + ssl_library 配置参数 + + + - - max_stack_depth - - - 指定服务器执行栈的安全最大深度。理想值应当是内核强制的栈大小限制减去约 1MB 的安全边界。 - 默认值为 2MB。只有超级用户和具有适当 SET 权限的用户才能更改此设置。 - + + 报告此PostgreSQL服务器已构建的 SSL 库的名称(即使此实例当前未配置或使用 SSL), + 例如OpenSSL,或一个空字符串(如果没有)。 + + + - - 如果把此值设得高于实际内核限制,失控的递归函数可能导致单独的后端进程崩溃。 - 在能够检测内核限制的平台上,服务器不会允许不安全的设置;不过并非所有平台都能提供这类信息。 - - - + - - shared_memory_type - - - 指定主共享内存区域使用的共享内存实现,包括共享缓冲区和其他共享数据。 - 可选值通常有 mmapsysvwindows。 - 并非所有平台都支持所有值,第一个受支持的选项通常就是该平台的默认值。 - - - + wal_block_size (integer) + + wal_block_size配置参数 + + + - - dynamic_shared_memory_type - - - 指定服务器应使用的动态共享内存实现。可选值通常有 posixsysv、 - windowsmmap。并非所有平台都支持所有值。 - 通常不建议使用 mmap,因为它可能增加系统 I/O 负载;但在调试或其他共享内存设施不可用时可能有用。 - 此参数只能在服务器启动时设置。 - - - + + 报告一个 WAL 磁盘块的尺寸。由编译服务器时的XLOG_BLCKSZ值决定。默认是 8192 字节。 + + + - - min_dynamic_shared_memory - - - 指定服务器启动时预留给并行查询使用的动态共享内存最小量。 - 当该区域不足时,新的并行查询可以临时向操作系统申请额外共享内存,但代价更高。 - 默认值为 0。此参数只能在服务器启动时设置。 - - - - - + - - 磁盘 + wal_segment_size (integer) + + wal_segment_size配置参数 + + + - - - temp_file_limit - - - 指定单个进程可用于临时文件以及保留游标相关存储文件的最大磁盘空间。 - 超过此限制的事务会被取消。默认值为 -1,表示不限制。此参数可在会话中设置。 - - - - - + + 报告 WAL 段文件的大小。默认是 16MB。详见。 + + + - - 内核资源 + + - - - max_files_per_process - - - 指定服务器进程可同时打开的最大文件数。默认值通常足以满足大多数安装。 - 此参数只能在服务器启动时设置。 - - - - - + - - 基于成本的清理延迟 + 自定义选项 - - 这一组参数控制 VACUUM 的成本计量和暂停行为。 - + + 这个特性被设计用来由附加模块向PostgreSQL添加通常不为系统知道的参数(例如过程语言)。这允许使用标准方法配置扩展模块。 + - - - vacuum_cost_delay - - - 指定 VACUUM 在达到成本上限后暂停的时间。默认值为 0,表示不做成本延迟。 - 如果指定值没有单位,则按毫秒计算。 - - - + + 自定义选项有两部分名称:一个扩展名,然后是一个句点,再然后是正确的参数名,就像 SQL 中的合格名称。一个示例是plpgsql.variable_conflict。 + - - vacuum_cost_page_hit - - - 指定在缓冲区中命中的页面所对应的成本。默认值为 1。 - - - + + 因为自定义选项可能需要在尚未加载相关扩展模块的进程中设置, + PostgreSQL将接受任何两部分参数名称的设置。 + 这些变量被视为占位符,在定义它们的模块加载之前没有任何功能。 + 当加载扩展模块时,它将添加其变量定义并根据这些定义转换任何占位符值。 + 如果存在以其扩展名开头的任何未识别的占位符,将发出警告并删除这些占位符。 + + - - vacuum_cost_page_miss - - - 指定未命中缓冲区、需要从磁盘读取的页面所对应的成本。默认值为 2。 - - - + - - vacuum_cost_page_dirty - - - 指定把页面标记为脏页所对应的成本。默认值为 20。 - - - + 开发者选项 - - vacuum_cost_limit - - - 指定 VACUUM 在暂停前允许累积的成本上限。默认值为 200。 - 如果此参数设为负值,则会使用 的相应值。 - - - - - + + 下面的参数目的是用在开发测试上, 并且永远不能用于生产数据库。 + 但是,它们中的一些能够用于帮助恢复严重损坏的数据库。 + 同样,它们被从示例postgresql.conf文件中排除。 + 请注意许多这些参数要求特殊的源代码编译标志才能工作。 + - - 后台写入器 + + - - - bgwriter_delay - - - 指定后台写入器轮询与刷写脏页的频率。默认值为 200ms。此参数只能在服务器启动时设置。 - - - + allow_in_place_tablespaces (boolean) + + allow_in_place_tablespaces配置参数 + + + - - bgwriter_lru_maxpages - - - 指定后台写入器每轮最多可写出的脏页数。默认值为 100。此参数可随时设置。 - - - + + 允许将表空间创建为pg_tblspc内的目录,当CREATE TABLESPACE命令提供空位置字符串时。 + 这旨在允许测试主库和备库在同一台机器上运行的复制场景。这样的目录可能会混淆备份工具,因为这些工具期望在该位置只找到符号链接。 + 只有超级用户和具有适当SET权限的用户才能更改此设置。 + + + - - bgwriter_lru_multiplier - - - 指定后台写入器根据后台命中率计算刷写额度时所使用的乘数。默认值为 2.0。 - - - + - - bgwriter_flush_after - - - 指定后台写入器在刷写多少 WAL 或数据页之后主动把脏页刷新到磁盘。该参数有助于平滑 I/O 峰值。 - 默认值为 512kB。 - - - - - + allow_system_table_mods (boolean) + + allow_system_table_mods配置参数 + + + - - 异步行为 + + 允许修改系统表的结构以及对系统表进行某些其他风险操作。即使对于超级用户,这也通常是不允许的。 + 不明智地使用此设置可能导致无法检索的数据丢失或严重损坏数据库系统。 + 只有超级用户和具有适当SET权限的用户才能更改此设置。 + + + + + - - - backend_flush_after - - - 指定单个后台进程在写入多少数据后主动调用刷写。默认值为 0,表示不主动刷写。 - 这有助于减少长时间运行的写入操作对系统缓存造成的压力。 - - - + backtrace_functions (string) + + backtrace_functions 配置参数 + + + - - effective_io_concurrency - - - 指定磁盘子系统并发预读的有效度量。较高的值可使索引扫描和某些顺序扫描受益, - 但只有当底层存储确实能从并发预读中获益时才应调高。默认值因平台而异。 - - - + + 这个参数包含一个以逗号分隔的C函数名称列表。 + 如果出现错误,并且发生错误的内部C函数的名称与列表中的值相匹配,那么将向服务器日志中写入一个回溯跟踪信息和错误消息。 + 这可以用来调试源代码的特定区域。 + - - maintenance_io_concurrency - - - 指定维护操作可并发预读的 I/O 数量。较高的值可能加快 VACUUM 和索引维护, - 但也可能增加 I/O 压力。默认值通常为 10。 - - - + + 回溯支持并非在所有平台上都可以使用,并且回溯的质量取决于编译选项。 + - - max_worker_processes - - - 指定服务器可启动的后台工作进程总数。此上限同时影响并行查询、逻辑复制等功能。 - 它必须不小于 - 和 的需要。此参数只能在服务器启动时设置。 - - - + + 只有超级用户和具有适当SET权限的用户才能更改此设置。 + + + - - max_parallel_workers_per_gather - - - 指定单个 Gather 节点最多可使用的并行工作进程数。即使请求的数量更高,也会受 - 限制。 - 默认值通常为 2。 - - - - - max_parallel_maintenance_workers - - - 指定并行维护操作最多可使用的并行工作进程数,例如并行索引构建。该值受 - 约束。 - 默认值通常为 2。 - - - - - max_parallel_workers - - - 指定整个集簇允许的并行工作进程总数。默认值通常为 8。此值不得小于 - 的要求。 - 如果它小于 ,后者就不会起作用。 - - - + - - parallel_leader_participation - - - 指定并行查询的 leader 进程是否也参与执行。默认值为 on。 - 关闭它会让 leader 只负责调度而不参与实际执行。 - - - + debug_discard_caches (integer) + + debug_discard_caches 配置参数 + + + - - old_snapshot_threshold - - - 指定快照被视为过旧之前允许经过的时间。开启后,服务器会在快照过旧时拒绝继续使用它,以减少长时间查询对空间回收的阻塞。 - 默认值为 -1,表示禁用此功能。此参数只能在服务器启动时设置。 - - - - - - + + 当设置为1时,每个系统目录缓存条目在第一个可能的机会时失效,不管任何使之无效的事情是否真的发生。 + 作为结果,系统目录的缓存被有效地禁用,因此服务器将运行得非常缓慢。 + 较高的值递归地运行缓存失效,这样会更慢,而且只用于测试缓存逻辑自身。 + 默认值0选择正常的目录缓存行为。 + - - 预写式日志 + + 当试图触发涉及并发目录更改的难以复现的错误时,此参数非常有用,但除此之外它不太被需要。 + 详情请参见源码文件inval.cpg_config_manual.h。 + - - 本节描述控制 WAL 生成、刷写、检查点以及恢复行为的参数。 - + + 只有在编译时定义了DISCARD_CACHES_ENABLED时,这个参数才受支持; + 使用configure选项时会自动定义该宏。 + 在生产构建中,它的值始终为0,尝试将其设置为其他值会引发错误。 + + + - - WAL 设置 - - - wal_level - - - 指定 WAL 记录的详细程度。较高的级别会记录更多信息,以支持复制和归档恢复。 - 默认值通常是 replica。此参数只能在服务器启动时设置。 - - - - - fsync - - - 指定服务器是否在把 WAL 和数据文件写入磁盘后强制同步。默认值为 on。 - 关闭它会显著加快写入,但会带来数据损坏风险。此参数只能在服务器启动时设置。 - - - - - synchronous_commit - - - 指定事务提交时要等待到什么程度才算完成。默认值通常是 on, - 也可以设为 remote_writeremote_applylocaloff。 - 更弱的设置可以降低延迟,但也会增加在崩溃时丢失已提交事务的风险。 - - - - - full_page_writes - - - 控制在检查点之后页面第一次被修改时,是否把整个页面内容写入 WAL。 - 默认值为 on。关闭它可以减少 WAL 量,但会增加崩溃后出现不可恢复数据损坏的风险。 - - - - - wal_log_hints - - - 指定在检查点之后页面第一次被修改时,是否即使只是提示位变化也写入整页镜像到 WAL。 - 如果启用了数据校验和,这一行为总会发生,此设置会被忽略。此参数只能在服务器启动时设置。 - - - - - wal_compression - - - 指定是否以及使用何种压缩方式压缩写入 WAL 的整页镜像。可用值通常包括 pglz、 - lz4(如果编译时启用)和 zstd(如果编译时启用)。 - 值 onpglz 的历史拼写。 - 启用后可减少 WAL 体积,但会增加 CPU 开销。 - - - - - wal_init_zero - - - 指定新建 WAL 文件时是否先用零填充。默认值为 on,这样可以确保文件空间在需要写入 WAL 记录前就已分配。 - 关闭它可以跳过这一步。此参数只能在服务器启动时设置。 - - - - - wal_recycle - - - 指定是否通过重命名回收旧 WAL 文件而不是创建新文件。默认值为 on。 - 在某些 Copy-On-Write 文件系统上,关闭该选项可能更快。 - - - + + force_parallel_mode (enum) + + force_parallel_mode 配置参数 + + + + + 允许为测试目的使用并行查询,即使预期不会带来性能收益。 + force_parallel_mode允许的值包括 + off(仅在预期能提高性能时使用并行模式)、 + on(对所有被认为可以安全并行的查询强制使用并行查询),以及 + regress(类似于on,但还有下文说明的额外行为变化)。 + - - wal_sync_method - - - 指定将 WAL 强制刷写到磁盘时使用的方法。若 fsync 关闭,则此设置无关紧要。 - 可选值包括 open_datasyncfdatasyncfsync、 - fsync_writethroughopen_sync。并非所有平台都支持所有值, - 默认值通常是平台支持的第一个选项。 - - - + + 更具体地说,将此值设置为on会在任何看起来可以安全并行的查询计划顶部添加一个Gather节点, + 让查询在并行工作进程中运行。即使没有可用的并行工作进程或无法使用并行工作进程, + 在并行查询上下文中不允许的操作(例如启动子事务)也会被禁止,除非规划器认为这会使查询失败。 + 如果设置此选项后出现失败或意外结果,查询使用的某些函数可能需要被标记为PARALLEL UNSAFE + (也可能是PARALLEL RESTRICTED)。 + - - wal_buffers - - - 指定尚未写入磁盘的 WAL 数据可占用多少共享内存。默认值 -1 会自动选择合适大小, - 约为 shared_buffers 的 1/32,但不少于 64kB。此参数只能在服务器启动时设置。 - - - + + 将此值设置为regress具有设置为on的所有效果,另外还有一些旨在方便自动回归测试的效果。 + 通常,来自并行工作进程的消息会包含一行说明这一点的上下文信息,但regress设置会抑制此行,使输出与非并行执行时相同。 + 此外,此设置添加到计划中的Gather节点会在EXPLAIN输出中隐藏, + 使输出与此设置为off时的输出一致。 + + + - - wal_writer_delay - - - 指定 WAL 写入进程刷写 WAL 的间隔。默认值为 200ms。若指定值没有单位,则按毫秒计算。 - 此参数只能在 postgresql.conf 中或服务器命令行上设置。 - - - + - - wal_writer_flush_after - - - 指定 WAL 写入进程在写出多少 WAL 后主动调用刷盘。默认值通常为 1MB。 - 该参数有助于平滑磁盘 I/O,但如果设置过大,可能会增加崩溃时恢复的工作量。 - - - + ignore_system_indexes (boolean) + + ignore_system_indexes配置参数 + + + - - wal_skip_threshold - - - 指定在某些情况下可以跳过回放旧 WAL 的阈值。该参数用于减少检查点和恢复过程中的无效工作。 - 默认值为 2MB。 - - - + + 读取系统表时忽略系统索引(但是修改系统表时依然同时更新索引)。这在从被破坏的系统索引中恢复数据的时有用。这个参数在会话开始之后不能被更改。 + + + - - commit_delay - - - 指定在刷写 WAL 之前,提交进程可额外等待的时间。默认值为 0。它主要用于较少连接并且提交冲突较多的场景。 - 只有具有相应权限的用户才能更改此设置。 - - - + - - commit_siblings - - - 指定当系统中至少有多少个并发事务时,commit_delay 才会生效。 - 默认值为 5。该参数只能与 commit_delay 配合使用。 - - - - - + post_auth_delay (integer) + + post_auth_delay配置参数 + + + - - 检查点和归档 + + 执行认证过程后启动新服务器进程时延迟的时间量。这是为了给开发者们一个机会在一个服务器进程上附加一个调试器。 + 如果指定值时没有单位,则以秒为单位。0值(默认值)禁用延迟。这个参数在会话开始之后不能被更改。 + + + - - - checkpoint_timeout - - - 指定两个检查点之间的最长时间。默认值为 5 分钟。若指定值没有单位,则按秒计算。 - 更长的间隔可以减少检查点开销,但会增加崩溃恢复需要回放的 WAL 量。 - - - + - - checkpoint_completion_target - - - 指定检查点写入在整个检查点间隔中的目标完成比例。默认值为 0.9。 - 较高的值会让检查点 I/O 更均匀,但也可能延长检查点完成时间。 - - - + pre_auth_delay (integer) + + pre_auth_delay配置参数 + + + - - checkpoint_flush_after - - - 指定检查点在写出多少数据后主动刷盘。默认值通常为 256kB。 - 这样可以减少一次性积压的大量 I/O。 - - - + + 在新服务器进程分叉后,在进行认证过程之前,延迟的时间量。这是为了给开发者们一个机会在一个服务器进程上附加一个调试器来跟踪认证过程中的不当行为。 + 如果指定值时没有单位,则以秒为单位。0值(默认值)禁用延迟。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 + + + - - checkpoint_warning - - - 如果检查点过于频繁,则发出警告。默认值为 30 秒。若指定值没有单位,则按秒计算。 - 这有助于发现 max_wal_size 或检查点配置过小的问题。 - - - + - - max_wal_size - - - 指定触发检查点前允许 WAL 增长到的目标上限。默认值通常为 1GB。 - 更大的值会减少检查点频率,但会增加崩溃恢复时间。 - - - + trace_notify (boolean) + + trace_notify配置参数 + + + - - min_wal_size - - - 指定在检查点后系统应尽量保留的 WAL 最小量。默认值通常为 80MB。 - 较大的值会减少 WAL 段文件被频繁创建和删除的开销。 - - - + + 为LISTENNOTIFY命令生成大量调试输出。必须是DEBUG1或者更低才能把这种输出分别发送到客户端或者服务器日志。 + + + + + trace_recovery_messages (enum) + + trace_recovery_messages 配置参数 + + + + + 启用原本不会记录的恢复相关调试输出。此参数允许用户覆盖的常规设置,但仅针对特定消息。 + 它旨在用于调试热备。有效值为DEBUG5DEBUG4、 + DEBUG3DEBUG2DEBUG1LOG。 + 默认值LOG完全不影响是否记录消息的决定。其他值会让该优先级或更高优先级的恢复相关调试消息 + 按LOG优先级记录;对于log_min_messages的常见设置,这会无条件地将它们发送到服务器日志。 + 此参数只能在postgresql.conf文件中或在服务器命令行上设置。 + + + - - archive_mode - - - 指定是否把生成的 WAL 段归档。除 off 外,通常还可设为 onalways。 - 只有在配置了 archive_commandarchive_library 时才真正有意义。 - 此参数只能在服务器启动时设置。 - - - + - - archive_command - - - 指定把完成写入的 WAL 段复制到归档位置时执行的 shell 命令。 - 只有该命令返回零退出状态,服务器才认为归档成功。此参数只能在 postgresql.conf - 中或服务器命令行上设置。 - - - + trace_sort (boolean) + + trace_sort配置参数 + + + - - archive_library - - - 指定执行 WAL 归档时要调用的共享库模块。它可以代替 archive_command 使用。 - 此参数只能在服务器启动时设置。 - - - + + 如果打开,发出在排序操作中的资源使用的相关信息。只有在编译PostgreSQL时定义了TRACE_SORT宏, 这个参数才可用(不过,当前在默认情况下就定义了TRACE_SORT)。 + + + - - archive_timeout - - - 指定即使 WAL 段尚未写满,也最多等待多久就强制切换并归档。默认值为 0,表示只在段写满时切换。 - 如果指定值没有单位,则按秒计算。 - - - + - - recovery_prefetch - - - 控制恢复过程中是否预取即将需要的块。预取可以减少某些工作负载下的 I/O 等待时间。 - 此参数可与 配合使用。 - - - + trace_locks (boolean) + + trace_locks配置参数 + + + - - wal_decode_buffer_size - - - 指定在 WAL 中查找预取块时允许向前看的最大距离。默认值为 512kB。 - 此参数只能在服务器启动时设置。 - - - - - + + 如果开启,发出锁使用情况的信息。被转储信息中包括锁操作的类型、锁的类型和 被锁或被解锁对象的唯一标识符。同样包括的还有已经授予这个对象的锁类型的位掩码和 等待这个对象的锁类型的位掩码。对每一种锁类型,已授权锁和等待锁的计数也会被一起转储。一个日志文件输出的示例如下: + +LOG: LockAcquire: new: lock(0xb7acd844) id(24688,24696,0,0,0,1) + grantMask(0) req(0,0,0,0,0,0,0)=0 grant(0,0,0,0,0,0,0)=0 + wait(0) type(AccessShareLock) +LOG: GrantLock: lock(0xb7acd844) id(24688,24696,0,0,0,1) + grantMask(2) req(1,0,0,0,0,0,0)=1 grant(1,0,0,0,0,0,0)=1 + wait(0) type(AccessShareLock) +LOG: UnGrantLock: updated: lock(0xb7acd844) id(24688,24696,0,0,0,1) + grantMask(0) req(0,0,0,0,0,0,0)=0 grant(0,0,0,0,0,0,0)=0 + wait(0) type(AccessShareLock) +LOG: CleanUpLock: deleting: lock(0xb7acd844) id(24688,24696,0,0,0,1) + grantMask(0) req(0,0,0,0,0,0,0)=0 grant(0,0,0,0,0,0,0)=0 + wait(0) type(INVALID) + + 被转储结构体的详细信息可以在src/include/storage/lock.h中找到。 + - - 归档恢复 + + 只有在编译PostgreSQL时定义了LOCK_DEBUG宏, 这个参数才可用。 + + + - - 本节所述设置只在恢复期间生效。如果需要后续恢复,必须重新配置它们。 - + - - 恢复既包括把服务器作为备库运行,也包括执行定点恢复。 - 一般来说,备库模式用于高可用和读扩展,定点恢复则用于从数据丢失中恢复。 - + trace_lwlocks (boolean) + + trace_lwlocks配置参数 + + + - - 要以备库模式启动服务器,请在数据目录中创建名为 standby.signal 的文件。 - 服务器会进入恢复状态,并在到达归档 WAL 末尾后继续尝试恢复,通过 primary_conninfo - 指定的发送服务器和/或通过 restore_command 获取新的 WAL 段。 - 在这种模式下,本节参数以及 中的参数都可能生效, - 但后者通常无须特别设置。 - + + 如果开启,发出轻量级锁的使用信息。轻量级锁主要是为了提供对共享内存数据结构的互斥访问。 + - - 要以定点恢复模式启动服务器,请在数据目录中创建名为 recovery.signal 的文件。 - 如果同时创建了 standby.signalrecovery.signal, - 则优先使用备库模式。定点恢复会在归档 WAL 全部回放完成,或者到达 recovery_target 时结束。 - + + 只有在编译PostgreSQL时定义了LOCK_DEBUG宏, 这个参数才可用。 + + + - - - restore_command - - - 指定用于从归档中提取 WAL 文件段的本地 shell 命令。该参数是归档恢复所必需的,但对流复制是可选的。 - 命令中的 %f 会被替换为归档文件名,%p 会被替换为服务器上的目标路径名, - %r 会被替换为包含上一个可用重启点的文件名。要表示真正的百分号,请写成 %%。 - + - - 该命令只有在成功时才应返回零退出状态。命令会被用于查询归档中可能不存在的文件,因此在找不到文件时必须返回非零。 - 如果命令因信号或 shell 错误而终止,恢复会中止并且服务器不会启动。 - + trace_userlocks (boolean) + + trace_userlocks配置参数 + + + - - 此参数只能在 postgresql.conf 中或通过服务器命令行设置。 - - - + + 如果开启,发出关于用户锁使用的信息。与trace_locks的输出一样,但只用于咨询锁。 + - - archive_cleanup_command - - - 指定在每个重启点执行的可选 shell 命令,用于清理不再需要的已归档 WAL 文件。 - 命令中的 %r 会被替换为包含最后一个可用重启点的文件名。 - 这个文件以及它之前的文件都可以安全删除。 - + + 只有在编译PostgreSQL时定义了LOCK_DEBUG宏, 这个参数才可用。 + + + - - 对单一备库配置,常会把 pg_archivecleanup 用在此参数中。 - 如果多个备库共享同一个归档目录,则必须保证只有当所有服务器都不再需要某个 WAL 文件时才删除它。 - 要在命令中嵌入真正的百分号,请写成 %%。 - + - - 如果命令返回非零退出状态,会写出警告日志;如果命令因信号或 shell 错误中止,则会报致命错误。 - 此参数只能在 postgresql.conf 中或通过服务器命令行设置。 - - - + trace_lock_oidmin (integer) + + trace_lock_oidmin配置参数 + + + - - recovery_end_command - - - 指定一个只会在恢复结束时执行一次的 shell 命令。它通常用于在复制或恢复完成后执行清理。 - 与 archive_cleanup_command 类似,命令中的 %r 会被替换为包含最后一个可用重启点的文件名。 - + + 如果设置,不会跟踪小于这个 OID 的锁(用于避免在系统表上的输出)。 + - - 如果命令返回非零退出状态,会写出警告日志,数据库仍会继续启动;如果命令因信号或 shell 错误中止, - 则数据库不会继续启动。此参数只能在 postgresql.conf 中或通过服务器命令行设置。 - - - - - + + 只有在编译PostgreSQL时定义了LOCK_DEBUG宏, 这个参数才可用。 + + + - - 恢复目标 + - - 默认情况下,恢复会一直执行到 WAL 日志末尾。下面这些参数可以指定更早的停止点。 - recovery_targetrecovery_target_lsnrecovery_target_name、 - recovery_target_timerecovery_target_xid 中最多只能选择一个, - 否则会报错。此参数只能在服务器启动时设置。 - + trace_lock_table (integer) + + trace_lock_table配置参数 + + + - - - recovery_target - - - 指定恢复应在达到一致状态后尽快结束,也就是尽早结束。对于从在线备份恢复,这意味着停在备份结束的位置。 - 在技术上这是一个字符串参数,但目前唯一允许的值是 immediate。 - - - + + 无条件地跟踪此表(OID)上的锁。 + - - recovery_target_name - - - 指定由 pg_create_restore_point() 创建的命名恢复点,恢复将停在该恢复点。 - - - + + 只有在编译PostgreSQL时定义了LOCK_DEBUG宏, 这个参数才可用。 + + + - - recovery_target_time - - - 指定恢复应停在的时间戳。精确停止点还受 影响。 - 该值应使用 timestamp with time zone 接受的相同格式,但不能使用时区缩写, - 除非已经在配置文件中设置了 。推荐使用 UTC 数值偏移或完整时区名。 - - - + - - recovery_target_xid - - - 指定恢复应停在的事务 ID。事务 ID 在事务开始时按顺序分配,但完成顺序可能不同。 - 目标事务之前(以及可能包括该事务)的提交都会被恢复。精确停止点还受 - 影响。 - - - + debug_deadlocks (boolean) + + debug_deadlocks配置参数 + + + - - recovery_target_lsn - - - 指定恢复应继续到的 WAL LSN。精确停止点也受 影响。 - 该参数使用系统数据类型 pg_lsn 解析。 - - - + + 如果设置,当死锁超时发生时,转储所有当前锁的信息。 + - - recovery_target_inclusive - - - 指定是停在恢复目标之后(on),还是停在恢复目标之前(off)。 - 适用于 - 或 被指定的情况。默认值为 on。 - - - + + 只有在编译PostgreSQL时定义了LOCK_DEBUG宏, 这个参数才可用。 + + + - - recovery_target_timeline - - - 指定恢复到某个特定时间线。可取数值时间线 ID,或特殊值 currentlatest。 - current 会沿着生成基础备份时的时间线恢复,latest - 会恢复到归档中能找到的最新时间线。默认值为 latest。 - + - - 如果要以十六进制指定时间线 ID,例如从 WAL 文件名或历史文件中提取,请前置 0x。 - 例如,文件名 00000011000000A10000004F 的时间线 ID 是 0x11, - 即十进制 17。 - + log_btree_build_stats (boolean) + + log_btree_build_stats配置参数 + + + - - 一般只在更复杂的再次恢复场景中需要设置此参数,也就是你需要回到一个状态,而那个状态本身又是一次时间点恢复的结果。 - 相关讨论见 。 - - - + + 如果设置,会记录 B-树操作上的系统资源使用情况统计(内存和 CPU)。 + - - recovery_target_action - - - 指定到达恢复目标后服务器应立即采取的动作。默认值是 pause,表示暂停恢复。 - promote 表示结束恢复并开始接受连接,shutdown - 则表示到达目标后直接停止服务器。 - + + 只有在编译PostgreSQL时定义了BTREE_BUILD_STATS宏, 这个参数才可用。 + + + - - pause 的用途是:如果目标位置正是你希望查询的恢复位置,就允许数据库在该点上继续提供只读查询。 - 暂停状态可通过 pg_wal_replay_resume() 继续。如果目标点不是最终想要的位置, - 则可以关闭服务器、修改恢复目标并重启继续恢复。 - + - - shutdown 在希望实例停留在某个特定重放点时很有用。之后它仍然可以继续重放更多 WAL 记录。 - 由于在设置为 shutdown 时不会移除 recovery.signal, - 后续启动仍会在到达该目标后关闭,除非更改配置或手工删除该文件。 - + wal_consistency_checking (string) + + wal_consistency_checking配置参数 + + + - - 如果没有设置恢复目标,此参数无效。若未启用 , - pause 的效果等同于 shutdown。如果在升级过程中达到恢复目标, - pause 的效果与 promote 相同。 - + + 这个参数被设计用来检查WAL重做例程中的缺陷。当这个参数被启用时,被修改的任何缓冲区的整页镜像及其WAL记录都被加入到记录中。如果该记录后来被重放,系统将首先应用每个记录然后测试该记录修改的缓冲区是否符合存储的镜像。在某些情况下(例如提示位),小的变动是可以接受的,并且会被忽略。任何预期之外的差别都将导致致命错误,最后中止恢复。 + - - 如果已经配置了恢复目标,但在到达目标前归档恢复结束,服务器将以致命错误关闭。 - - - - - - + + 默认值为空字符串,表示禁用该功能。可以设置为all以检查所有记录, + 或者设置为逗号分隔的资源管理器列表,以仅检查来自这些资源管理器的记录。目前支持的资源管理器有 + heapheap2btreehash、 + gingistsequencespgist、 + bringeneric。扩展可以定义额外的资源管理器。只有超级用户和具有 + 适当SET权限的用户才能更改此设置。 + + + - - 复制 + - - 这些设置控制内置流复制功能的行为。主库负责发送数据,备库负责接收数据。 - 在级联复制中,备库也可以同时充当发送者。这里列出的参数主要用于发送服务器和备库, - 但有些参数只对主库有意义。 - + wal_debug (boolean) + + wal_debug配置参数 + + + - - 发送服务器 + + 如果被打开,WAL 相关的调试输出将被发出。只有在编译PostgreSQL时定义了WAL_DEBUG宏的情况下,这个参数才可用。 + + + - - 这些参数适用于向一个或多个备库发送复制数据的服务器。主库总是发送服务器,因此这些参数通常需要在主库上设置。 - + - - - max_wal_senders - - - 指定可以同时连接到该服务器以接收复制数据或流式基础备份的最大客户端数,也就是 WAL 发送进程的最大数量。 - 默认值通常为 10。值 0 表示禁用复制。此参数只能在服务器启动时设置。 - - - + ignore_checksum_failure (boolean) + + ignore_checksum_failure配置参数 + + + - - max_replication_slots - - - 指定服务器支持的复制槽最大数量。默认值为 10。此参数只能在服务器启动时设置。 - 如果将其设得小于当前已有复制槽数量,服务器将无法启动。 - - - + + 只有当被启用时才有效。 + - - output_plugin_libraries (string) - - output_plugin_libraries配置参数 - - - - - 列出安装在 所指定位置中、同时也被信任可供复制客户端用作逻辑输出插件的库。 - 任何针对其他库的逻辑解码或 - 复制请求都将被拒绝。所有用户都受此限制。 - 默认值为 'pgoutput, test_decoding',它们是标准 - PostgreSQL 发行版中包含的两个逻辑输出插件。 - - - 其格式为以逗号分隔的库名称列表,每个名称的解释方式与 - LOAD命令相同 - (但逻辑解码客户端指定的插件名称必须与列表中的一个条目完全匹配, - 大小写或路径结构不得有变化)。条目之间的空白会被忽略;如果库名称中需要包含空白或逗号, - 请用双引号将其括起。 - - - 服务器管理员有责任确保,加载添加到此列表中的库时,不会无意中向非超级用户授予额外权限。 - - - - 从没有 output_plugin_libraries 参数的版本更新服务器时, - 以下查询可帮助构造所有持久逻辑复制槽所需的插件列表: - -SELECT DISTINCT plugin FROM pg_replication_slots WHERE plugin IS NOT NULL; - - 调整 output_plugin_libraries 之前,请仔细审查该列表以确保安全。 - - - 上述查询只能显示过去某个时刻已成功添加到复制槽的插件。 - 新近被拒绝的请求将以类似以下消息出现在日志中: - -ERROR: library "..." may not be used as an output plugin -DETAIL: The configuration parameter "output_plugin_libraries" (currently 'pgoutput, test_decoding') does not name this library as a trusted output plugin. -HINT: If it is safe for all REPLICATION users to use this library as an output plugin, add it to "output_plugin_libraries" and reload the server configuration. - - - - - + + 在读取过程中检测到校验和失败通常会导致PostgreSQL报告错误,中止当前事务。 + 将ignore_checksum_failure设置为on会导致系统忽略失败(但仍然报告警告),并继续处理。 + 这种行为可能导致崩溃,传播或隐藏损坏,或其他严重问题。然而,它可能允许您跳过错误, + 并检索可能仍然存在于表中的未损坏的元组,如果块头仍然正常。如果头部损坏,即使启用此选项也会报告错误。 + 默认设置为off。 + 只有超级用户和具有适当SET权限的用户才能更改此设置。 + + + - - wal_keep_size - - - 指定 pg_wal 目录中应至少保留多少旧 WAL 文件段,以便落后的备库仍能通过流复制获取它们。 - 如果备库落后超过该值,发送服务器可能会删除备库仍然需要的 WAL 段,复制连接就会中断。 - 如果指定值没有单位,则按兆字节计算。 - - - + - - max_slot_wal_keep_size - - - 指定复制槽允许在 pg_wal 中保留的 WAL 文件最大总量。 - 若某个复制槽的 restart_lsn 落后当前 LSN 太多,使用该槽的备库可能因为缺少所需 WAL 而无法继续复制。 - 如果未指定单位,则按兆字节计算。默认值为 -1,表示不限制。 - - - + zero_damaged_pages (boolean) + + zero_damaged_pages配置参数 + + + - - wal_sender_timeout - - - 指定 WAL 发送进程在没有收到对端反馈时允许保持空闲的最长时间。 - 默认值为 60 秒。若指定值没有单位,则按毫秒计算。 - - - + + 检测到损坏的页面头通常会导致PostgreSQL报告错误,中止当前事务。 + 将zero_damaged_pages设置为on会导致系统报告警告,将内存中的损坏页面清零,并继续处理。 + 这种行为会破坏数据,即损坏页面上的所有行。但是,它确实允许您跳过错误,并从表中可能存在的未损坏页面中检索行。 + 如果由于硬件或软件错误而发生损坏,这对于恢复数据很有用。通常在放弃从表的损坏页面恢复数据的希望之前,不应将其设置为on。 + 清零的页面不会强制写入磁盘,因此建议在再次关闭此参数之前重新创建表或索引。默认设置为off。 + 只有超级用户和具有适当SET权限的用户才能更改此设置。 + + + - - track_commit_timestamp - - - 指定是否跟踪事务提交时间戳。启用后可以查询提交时间,但会增加少量开销。 - 默认值为关闭。 - - - - - + - - 主库设置 + ignore_invalid_pages (boolean) + + ignore_invalid_pages 配置参数 + + + - - 这些参数主要用于主库上的同步复制行为。备库上的值对主库行为没有影响。 - + + 如果设置为 off(默认值),则在恢复期间检测到引用无效页面的 WAL 记录会导致 PostgreSQL 引发 PANIC 级别错误,中止恢复。 + 将ignore_invalid_pages设置为on会导致系统忽略 WAL 记录中的无效页面引用(但仍报告警告),并继续恢复。 + 此行为可能会导致崩溃、数据丢失、传播或隐藏腐败,或其他严重问题。 + 但是,它可能允许你通过 PANIC 级错误,完成恢复,并启动服务器。 + 参数只能在服务器启动时设置。它仅在恢复期间或备库模式下生效。 + + + - - - synchronous_standby_names - - - 指定同步备库名称列表。事务提交时会等待这些备库确认接收 WAL。默认值为空,表示不启用同步复制。 - 语法可以指定优先级模式或基于仲裁的模式;如果未指定同步备库名称,提交不会等待复制。 - 此参数只能在 postgresql.conf 中或服务器命令行上设置。 - - - + - - vacuum_defer_cleanup_age - - - 指定 VACUUM 和 HOT 更新在清理死行版本之前要推迟多少个事务。 - 默认值为 0,表示一旦死行版本不再对任何未提交事务可见,就尽快删除。 - 在支持热备的主库上,适当增大此值有助于减少备库查询因早期清理而被取消的概率。 - 此参数只能在 postgresql.conf 中或服务器命令行上设置。 - + jit_debugging_support (boolean) + + jit_debugging_support配置参数 + + + - - 也可以考虑在备库上设置 hot_standby_feedback,作为使用此参数的替代方案。 - + + 如果LLVM有所需要的功能,用GDB注册所生成的函数。这会让调试更加容易。默认设置是off。只有超级用户和具有适当SET权限的用户可以在会话开始时更改这个参数,并且在会话内完全不能更改它。 + + + - - 该设置不会阻止已经达到 old_snapshot_threshold 年龄的死行清理。 - - - - - + - - 备库设置 + jit_dump_bitcode (boolean) + + jit_dump_bitcode配置参数 + + + - - 这些设置控制接收复制数据的备库服务器的行为。它们在主库上的值无关紧要。 - + + 将生成的LLVM IR写入文件系统,位于内。 + 这仅对于在JIT实现内部工作时有用。默认设置为off。 + 只有超级用户和具有适当SET权限的用户才能更改此设置。 + + + - + - - primary_conninfo (string) - - primary_conninfo 配置参数 - - - - - 指定备库服务器用来连接发送服务器的连接字符串。此字符串的格式见 - 。如果该字符串中未指定任何选项,则会检查相应的环境变量 - (见 )。如果环境变量也没有设置,则使用默认值。 - - - 连接字符串应指定发送服务器的主机名(或地址),如果端口号不同于备库的默认端口,也应一并指定。 - 还应指定一个在发送服务器上拥有适当权限的角色名(见 - )。如果发送方要求密码认证,也需要提供密码。 - 密码既可以写在 primary_conninfo 字符串中,也可以放在备库服务器上的单独 - ~/.pgpass 文件中(请使用 replication 作为数据库名)。 - 不要在 primary_conninfo 字符串中指定数据库名。 - - - 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 - 如果在 WAL 接收进程运行时更改了该参数,该进程会被信号通知关闭,并预期用新设置重新启动 - (除非 primary_conninfo 为空字符串)。如果服务器不处于备库模式,这一设置无效。 - - - + jit_expressions (boolean) + + jit_expressions配置参数 + + + - - primary_slot_name (string) - - primary_slot_name 配置参数 - - - - - 可选地指定一个现有复制槽,在通过流复制连接到发送服务器时使用,以控制上游节点上的资源移除 - (见 )。 - 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 - 如果在 WAL 接收进程运行时更改了该参数,该进程会被信号通知关闭,并预期用新设置重新启动。 - 如果未设置 primary_conninfo,或者服务器不处于备库模式,这一设置无效。 - - - + + 当JIT编译被激活时(见),确定表达式是否用JIT编译。默认值是on。 + + + - - promote_trigger_file (string) - - promote_trigger_file 配置参数 - - - - - 指定一个触发文件,只要该文件存在,就会结束备库中的恢复。 - 即使未设置该值,仍然可以通过 pg_ctl promote 或调用 - pg_promote() 来提升备库。 - 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 - - - + - - hot_standby (boolean) - - hot_standby 配置参数 - - - - - 指定是否允许在恢复期间连接并运行查询,详见 。 - 默认值是 on。此参数只能在服务器启动时设置。 - 它只在归档恢复或备库模式下生效。 - - - + jit_profiling_support (boolean) + + jit_profiling_support配置参数 + + + - - max_standby_archive_delay (integer) - - max_standby_archive_delay 配置参数 - - - - - 当热备处于活动状态时,此参数决定备库在取消与即将应用的 WAL 记录冲突的备库查询之前应等待多久, - 详见 。 - max_standby_archive_delay 适用于从 WAL 归档读取 WAL 数据的情况 - (因此不是当前 WAL)。 - 如果该值未指定单位,则按毫秒计算。默认值是 30 秒。 - 值为 -1 时,备库会无限期等待冲突查询完成。 - 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 - - - 注意,max_standby_archive_delay 并不等同于查询在被取消前可以运行的最长时间; - 它实际上是应用某个 WAL 段数据所允许的最大总时间。因此,如果某个查询已经在该 WAL 段前部造成了显著延迟, - 后续发生冲突的查询就会得到少得多的宽限时间。 - - - + + 如果LLVM有所需的功能,发出需要的数据以允许perf对JIT生成的函数画像。 + 这会写出文件到~/.debug/jit/中,如果需要,由用户负责对其执行清除。 + 默认设置是off。 + 只有超级用户和具有适当SET权限的用户可以在会话开始时更改这个参数,并且在会话内完全不能更改它。 + + + - - max_standby_streaming_delay (integer) - - max_standby_streaming_delay 配置参数 - - - - - 当热备处于活动状态时,此参数决定备库在取消与即将应用的 WAL 记录冲突的备库查询之前应等待多久, - 详见 。 - max_standby_streaming_delay 适用于通过流复制接收 WAL 数据的情况。 - 如果该值未指定单位,则按毫秒计算。默认值是 30 秒。 - 值为 -1 时,备库会无限期等待冲突查询完成。 - 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 - - - 注意,max_standby_streaming_delay 并不等同于查询在被取消前可以运行的最长时间; - 它实际上是从主服务器接收到 WAL 数据后,允许用于应用这些数据的最大总时间。因此,如果某个查询已经造成了显著延迟, - 后续发生冲突的查询在备库追上进度之前会获得少得多的宽限时间。 - - - + - - wal_receiver_create_temp_slot (boolean) - - wal_receiver_create_temp_slot 配置参数 - - - - - 指定在未配置可用的永久复制槽时,WAL 接收进程是否应在远端实例上创建一个临时复制槽 - (使用 )。 - 默认值是 off。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 - 如果在 WAL 接收进程运行时更改了该参数,该进程会被信号通知关闭,并预期用新设置重新启动。 - - - + jit_tuple_deforming (boolean) + + jit_tuple_deforming配置参数 + + + - - wal_receiver_status_interval (integer) - - wal_receiver_status_interval 配置参数 - - - - - 指定备库上的 WAL 接收进程向主服务器或上游备库发送复制进度信息的最低频率, - 可通过 pg_stat_replication 视图查看。 - 备库会报告它已经写入的最后一个预写式日志位置、已经刷盘的最后一个位置,以及已经应用的最后一个位置。 - 此参数的值表示两次报告之间允许的最长时间。每当写入或刷盘位置变化时,系统都会发送更新; - 如果该参数的值非零,则也会按该参数指定的频率发送更新。 - 还有一些情况会在忽略该参数的情况下发送更新,例如现有 WAL 的处理完成时,或者 - synchronous_commit 设置为 remote_apply 时。 - 因此,应用位置可能会比真实位置略微滞后。 - 如果该值未指定单位,则按秒计算。默认值是 10 秒。此参数只能在 - postgresql.conf 文件中或服务器命令行上设置。 - - - + + 当JIT编译被激活时(见),确定元组拆解是否被JIT编译。默认值是on。 + + + - - hot_standby_feedback (boolean) - - hot_standby_feedback 配置参数 - - - - - 指定热备是否会向主服务器或上游备库发送关于当前在备库上执行的查询的反馈。 - 该参数可用于消除由清理记录引起的查询取消,但对于某些工作负载,也可能导致主服务器上的数据库膨胀。 - 反馈消息发送的频率不会高于 wal_receiver_status_interval 所允许的频率。 - 默认值是 off。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 - - - 如果使用级联复制,反馈会向上游传递,直到最终到达主服务器。备库接收到的反馈除继续向上游转发之外, - 不会有其他用途。 - - - 该设置不会覆盖主服务器上 old_snapshot_threshold 的行为; - 如果备库上的快照超过了主服务器的年龄阈值,就可能变为无效,从而导致备库上的事务被取消。 - 这是因为 old_snapshot_threshold 的设计目标是对死行可能造成膨胀的时间提供一个绝对上限, - 而备库的配置会以其他方式破坏这一限制。 - - - + - - wal_receiver_timeout (integer) - - wal_receiver_timeout 配置参数 - - - - - 终止超过此时间仍处于空闲状态的复制连接。这对接收端备库检测主节点崩溃或网络中断很有用。 - 如果该值未指定单位,则按毫秒计算。默认值是 60 秒。 - 值为零会禁用超时机制。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 - - - + remove_temp_files_after_crash (boolean) + + remove_temp_files_after_crash 配置参数 + + + - - wal_retrieve_retry_interval (integer) - - wal_retrieve_retry_interval 配置参数 - - - - - 指定当所有来源(流复制、本地 pg_wal 或 WAL 归档)都无法提供 WAL 数据时, - 备库在再次尝试检索 WAL 数据之前应等待多长时间。 - 如果该值未指定单位,则按毫秒计算。默认值是 5 秒。 - 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 - - 该参数在需要控制恢复中的节点等待新 WAL 数据可用的时间时非常有用。 - 例如,在归档恢复中,可以通过减小该参数的值来让系统更快地检测到新的 WAL 日志文件。 - 在 WAL 活动较少的系统上,增大该参数可以减少访问 WAL 归档所需的请求次数; - 例如在云环境中,这样做会很有用,因为基础设施被访问的次数会被纳入计费或配额考虑。 - - - - - - + 当设置为on时,这是默认值,PostgreSQL将在后端崩溃后自动删除临时文件。 + 如果禁用,文件将被保留,并且也许可用于调试,例如。 + 重复的崩溃可能会导致无用文件的积累。 + 该参数只能在postgresql.conf文件中或服务器命令行中设置。 + + + - - 订阅端 - - 这些设置控制逻辑复制订阅端的行为。它们在发布端上的值无关紧要。 - - - 请注意,wal_receiver_timeoutwal_receiver_status_interval - 和 wal_retrieve_retry_interval 配置参数也会影响逻辑复制工作进程。 - - - - max_logical_replication_workers (integer) - - max_logical_replication_workers 配置参数 - - - - - 指定逻辑复制工作进程的最大数量,其中包括应用工作进程和表同步工作进程。 - - - 逻辑复制工作进程来自 max_worker_processes 定义的进程池。 - - - 默认值是 4。此参数只能在服务器启动时设置。 - - - - - max_sync_workers_per_subscription (integer) - - max_sync_workers_per_subscription 配置参数 - - - - - 每个订阅允许的最大同步工作进程数。该参数控制订阅初始化时或新增表时初始数据复制的并行度。 - - - 目前,每个表只能有一个同步工作进程。 - - - 同步工作进程来自 max_logical_replication_workers 定义的进程池。 - - - 默认值是 2。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 - - - - - - + + diff --git a/zh/15/contrib.sgml b/zh/15/contrib.sgml index 4c28f673..dbbab08e 100644 --- a/zh/15/contrib.sgml +++ b/zh/15/contrib.sgml @@ -109,6 +109,7 @@ CREATE EXTENSION extension_name; 详情见各组件文档。 +&adminpack; &amcheck; &auth-delay; &auto-explain; @@ -131,6 +132,7 @@ CREATE EXTENSION extension_name; &isn; &lo; <ree; + &oldsnapshot; &pageinspect; &passwordcheck; &pgbuffercache; diff --git a/zh/15/custom-rmgr.sgml b/zh/15/custom-rmgr.sgml index e06782a6..87bf3093 100644 --- a/zh/15/custom-rmgr.sgml +++ b/zh/15/custom-rmgr.sgml @@ -10,6 +10,7 @@ 一个扩展,尤其是表访问方法或 索引访问方法,可能需要使用 WAL 来进行恢复、 复制和/或逻辑解码。 + 相比通用 WAL(不支持逻辑解码),自定义资源管理器更加灵活,但扩展实现起来也更复杂。 要创建新的自定义 WAL 资源管理器,首先定义一个 diff --git a/zh/15/datatype.sgml b/zh/15/datatype.sgml index 6064a2f5..3f085e36 100644 --- a/zh/15/datatype.sgml +++ b/zh/15/datatype.sgml @@ -354,19 +354,19 @@ smallint 2字节 小范围整数 - -32768 to +32767 + -32768 到 +32767 integer 4字节 整数的典型选择 - -2147483648 to +2147483647 + -2147483648 到 +2147483647 bigint 8字节 大范围整数 - -9223372036854775808 to +9223372036854775807 + -9223372036854775808 到 +9223372036854775807 @@ -866,9 +866,8 @@ FROM generate_series(-3.5, 3.5, 1) as x; - 本节描述的是 PostgreSQL 特有的创建 - 自动递增列的方法。另一种方法是使用 SQL 标准的标识列特性, - 参见 。 + 本节介绍 PostgreSQL 特有的自动递增列创建方法。 + 另一种方法是使用 SQL 标准的标识列特性,参见 @@ -947,7 +946,7 @@ ALTER SEQUENCE tablename_money 类型以固定的小数精度存储货币金额; 参见 。小数精度由数据库的 设置决定。表中显示的范围假定 - 有两位小数。输入支持多种格式,包括整数和浮点文字,以及典型的 + 有两位小数。输入支持多种格式,包括整数字面量和浮点数字面量,以及典型的 货币格式,例如 '$1,000.00'。输出通常也采用 后一种形式,但会受到区域设置影响。 @@ -1355,7 +1354,7 @@ SELECT '\xDEADBEEF'::bytea; - <type>bytea</type>文字转义字节 + <type>bytea</type>字面量中需要转义的字节 @@ -2620,7 +2619,7 @@ SELECT '2 years 15 months 100 weeks 99 hours 123456789 milliseconds'::interval; 3 years 3 mons 700 days 133:17:36.789 - 这里,周被理解为 7 days,而较小和较大的时间单位 + 这里,周按7 天计算并单独保留,而较小和较大的时间单位 则被合并并规范化了。 @@ -4048,17 +4047,16 @@ a0ee-bc99-9c0b-4ef8-bb6d-6bb9-bd38-0a11 xml 数据类型可用于存储 XML 数据。与把 XML 数据存储在 - text 字段中相比,它的优势在于会检查输入值是否格式 - 良好,并且提供了可执行类型安全操作的支持函数;见 - 。使用该数据类型要求安装时启用 + text 字段中相比,它的优势在于会检查输入值的良构性,并且提供了可执行类型安全操作的支持函数;见 + 。使用该数据类型要求构建时使用 configure --with-libxml - xml 类型既可以存储符合 XML 标准定义的格式良好的 + xml 类型既可以存储 XML 标准所定义的良构 文档,也可以存储 内容 片段;后者是参照 XQuery 和 XPath 数据模型中更宽松的 - document node + 文档节点 概念来定义的。粗略地说,这意味着内容片段可以拥有多个顶层元素或字符 节点。表达式 xmlvalue IS DOCUMENT @@ -4227,7 +4225,7 @@ SET xmloption TO { DOCUMENT | CONTENT }; - 是一种用户定义的数据类型,它基于另一种底层类型。根据需要,它可以有约束来限制其有效值为底层类型所允许值的一个子集。如果没有约束,它的行为就和底层类型一样 — 例如,任何适用于底层类型的操作符或函数都对该域类型有效。底层类型可以是任何内置或者用户定义的基础类型、枚举类型、数组类型、复合类型、范围类型或者另一个域。 + 是一种用户定义的数据类型,它基于另一种底层类型。根据需要,它可以有约束来限制其有效值为底层类型所允许值的一个子集。除此之外,它的行为与底层类型相同 — 例如,任何适用于底层类型的操作符或函数都对该域类型有效。底层类型可以是任何内置或者用户定义的基础类型、枚举类型、数组类型、复合类型、范围类型或者另一个域。 diff --git a/zh/15/dblink.sgml b/zh/15/dblink.sgml index ac0888f4..78d18236 100644 --- a/zh/15/dblink.sgml +++ b/zh/15/dblink.sgml @@ -11,39 +11,6 @@ dblink 是一个支持在数据库会话内连接到其他 PostgreSQL 数据库的模块。 - - dblink 可以在 Extension 等待事件类型下报告以下等待事件。 - - - - - DblinkConnect - - - 等待与远程服务器建立连接。 - - - - - - DblinkGetConnect - - - 当在已打开连接列表中找不到该连接时,等待建立与远程服务器的连接。 - - - - - - DblinkGetResult - - - 等待接收来自远程服务器的查询结果。 - - - - - 另请参见 ,它使用更现代且更符合标准的基础设施提供了基本相同的功能。 @@ -65,8 +32,8 @@ -dblink_connect(text connstr) 返回 text -dblink_connect(text connname, text connstr) 返回 text +dblink_connect(text connstr) returns text +dblink_connect(text connname, text connstr) returns text @@ -128,22 +95,13 @@ dblink_connect(text connname, text connstr) 返回 text 注解 - 如果不可信用户能够访问一个尚未采用模式的安全使用方式的数据库,则应在每个会话开始时从 + 如果不受信任的用户能够访问一个尚未采用模式的安全使用方式的数据库,则应在每个会话开始时从 search_path 中移除公共可写模式。例如,可以把 options=-csearch_path= 加到 connstr 中。这个注意事项并非 dblink 所特有;它适用于每一种执行任意 SQL 命令的接口。 - - 外部数据包装器 dblink_fdw 还有一个额外的布尔选项 - use_scram_passthrough,用于控制 - dblink 是否在连接远程数据库时使用 SCRAM 透传认证。 - 使用 SCRAM 透传认证时,dblink 会使用 SCRAM 哈希后的凭据,而不是明文用户密码来连接远程服务器。 - 这样可以避免在 PostgreSQL 系统目录中存储明文用户密码。关于更多细节和限制,请参见 - postgres_fdw 中对应的 - use_scram_passthrough - 选项文档。 - + 只有超级用户才能使用 dblink_connect 创建不使用密码认证的连接。 @@ -173,10 +131,9 @@ SELECT dblink_connect('myconn', 'dbname=postgres options=-csearch_path='); OK (1 row) --- FOREIGN DATA WRAPPER functionality --- Note: local connections that don't use SCRAM pass-through require password --- authentication for this to work properly. Otherwise, you will receive --- the following error from dblink_connect(): +-- FOREIGN DATA WRAPPER 功能 +-- 注意:要使本例正常工作,本地连接必须要求密码认证。 +-- 否则,dblink_connect() 将报告以下错误: -- ERROR: password is required -- DETAIL: Non-superuser cannot connect if the server does not request a password. -- HINT: Target server's authentication method must be changed. @@ -239,8 +196,8 @@ DROP SERVER fdtest; -dblink_connect_u(text connstr) 返回 text -dblink_connect_u(text connname, text connstr) 返回 text +dblink_connect_u(text connstr) returns text +dblink_connect_u(text connname, text connstr) returns text @@ -260,7 +217,7 @@ dblink_connect_u(text connname, text connstr) 返回 text 因此,dblink_connect_u() 在初始安装时会撤销 PUBLIC 的全部权限,从而除了超级用户之外无法调用它。 在某些情况下,可能适合向被认为可信的特定用户授予 - EXECUTE 权限,但必须谨慎操作。还建议服务器用户的任何 + dblink_connect_u()EXECUTE 权限,但必须谨慎操作。还建议服务器用户的任何 ~/.pgpass 文件不要包含指定通配主机名的记录。 @@ -287,8 +244,8 @@ dblink_connect_u(text connname, text connstr) 返回 text -dblink_disconnect() 返回 text -dblink_disconnect(text connname) 返回 text +dblink_disconnect() returns text +dblink_disconnect(text connname) returns text @@ -360,9 +317,9 @@ SELECT dblink_disconnect('myconn'); -dblink(text connname, text sql [, bool fail_on_error]) 返回 setof record -dblink(text connstr, text sql [, bool fail_on_error]) 返回 setof record -dblink(text sql [, bool fail_on_error]) 返回 setof record +dblink(text connname, text sql [, bool fail_on_error]) returns setof record +dblink(text connstr, text sql [, bool fail_on_error]) returns setof record +dblink(text sql [, bool fail_on_error]) returns setof record @@ -439,7 +396,7 @@ SELECT * WHERE proname LIKE 'bytea%'; - FROM 子句中的 alias 部分必须指定该函数将返回的列名和类型。(在别名中指定列名实际上是标准 SQL 语法,但指定列类型则是 + FROM 子句中的 别名 部分必须指定该函数将返回的列名和类型。(在别名中指定列名实际上是标准 SQL 语法,但指定列类型则是 PostgreSQL 的扩展。)这样系统才能在尝试执行该函数之前,就知道 * 应展开成什么,以及 WHERE 子句中的 proname 指的是什么。运行时,如果远程数据库返回的实际查询结果与 @@ -559,9 +516,9 @@ SELECT * FROM dblink('myconn', 'select proname, prosrc from pg_proc') -dblink_exec(text connname, text sql [, bool fail_on_error]) 返回 text -dblink_exec(text connstr, text sql [, bool fail_on_error]) 返回 text -dblink_exec(text sql [, bool fail_on_error]) 返回 text +dblink_exec(text connname, text sql [, bool fail_on_error]) returns text +dblink_exec(text connstr, text sql [, bool fail_on_error]) returns text +dblink_exec(text sql [, bool fail_on_error]) returns text @@ -686,8 +643,8 @@ DETAIL: ERROR: null value in column "relnamespace" violates not-null constrain -dblink_open(text cursorname, text sql [, bool fail_on_error]) 返回 text -dblink_open(text connname, text cursorname, text sql [, bool fail_on_error]) 返回 text +dblink_open(text cursorname, text sql [, bool fail_on_error]) returns text +dblink_open(text connname, text cursorname, text sql [, bool fail_on_error]) returns text @@ -800,8 +757,8 @@ SELECT dblink_open('foo', 'select proname, prosrc from pg_proc'); -dblink_fetch(text cursorname, int howmany [, bool fail_on_error]) 返回 setof record -dblink_fetch(text connname, text cursorname, int howmany [, bool fail_on_error]) 返回 setof record +dblink_fetch(text cursorname, int howmany [, bool fail_on_error]) returns setof record +dblink_fetch(text connname, text cursorname, int howmany [, bool fail_on_error]) returns setof record @@ -943,8 +900,8 @@ SELECT * FROM dblink_fetch('foo', 5) AS (funcname name, source text); -dblink_close(text cursorname [, bool fail_on_error]) 返回 text -dblink_close(text connname, text cursorname [, bool fail_on_error]) 返回 text +dblink_close(text cursorname [, bool fail_on_error]) returns text +dblink_close(text connname, text cursorname [, bool fail_on_error]) returns text @@ -1049,7 +1006,7 @@ SELECT dblink_close('foo'); -dblink_get_connections() 返回 text[] +dblink_get_connections() returns text[] @@ -1065,7 +1022,7 @@ dblink_get_connections() 返回 text[] 返回值 - 返回一个包含连接名称的 text 数组;如果没有,则返回 NULL。 + 返回包含连接名称的文本数组;如果没有连接,则返回 NULL。 @@ -1094,7 +1051,7 @@ SELECT dblink_get_connections(); -dblink_error_message(text connname) 返回 text +dblink_error_message(text connname) returns text @@ -1165,7 +1122,7 @@ SELECT dblink_error_message('dtest1'); -dblink_send_query(text connname, text sql) 返回 int +dblink_send_query(text connname, text sql) returns int @@ -1240,7 +1197,7 @@ SELECT dblink_send_query('dtest1', 'SELECT * FROM foo WHERE f1 < 3'); -dblink_is_busy(text connname) 返回 int +dblink_is_busy(text connname) returns int @@ -1302,8 +1259,8 @@ SELECT dblink_is_busy('dtest1'); -dblink_get_notify() 返回 setof (notify_name text, be_pid int, extra text) -dblink_get_notify(text connname) 返回 setof (notify_name text, be_pid int, extra text) +dblink_get_notify() returns setof (notify_name text, be_pid int, extra text) +dblink_get_notify(text connname) returns setof (notify_name text, be_pid int, extra text) @@ -1382,7 +1339,7 @@ SELECT * FROM dblink_get_notify(); -dblink_get_result(text connname [, bool fail_on_error]) 返回 setof record +dblink_get_result(text connname [, bool fail_on_error]) returns setof record @@ -1528,7 +1485,7 @@ contrib_regression=# SELECT * FROM dblink_get_result('dtest1') AS t1(f1 int, f2 -dblink_cancel_query(text connname) 返回 text +dblink_cancel_query(text connname) returns text @@ -1591,7 +1548,7 @@ SELECT dblink_cancel_query('dtest1'); -dblink_get_pkey(text relname) 返回 setof dblink_pkey_results +dblink_get_pkey(text relname) returns setof dblink_pkey_results @@ -1680,7 +1637,7 @@ dblink_build_sql_insert(text relname, int2vector primary_key_attnums, integer num_primary_key_atts, text[] src_pk_att_vals_array, - text[] tgt_pk_att_vals_array) 返回 text + text[] tgt_pk_att_vals_array) returns text @@ -1749,7 +1706,7 @@ dblink_build_sql_insert(text relname, 返回值 - 以 text 形式返回所请求的 SQL 语句。 + 以文本形式返回所请求的 SQL 语句。 @@ -1796,7 +1753,7 @@ SELECT dblink_build_sql_insert('foo', '1 2', 2, '{"1", "a"}', '{"1", "b''a"}'); dblink_build_sql_delete(text relname, int2vector primary_key_attnums, integer num_primary_key_atts, - text[] tgt_pk_att_vals_array) 返回 text + text[] tgt_pk_att_vals_array) returns text @@ -1856,7 +1813,7 @@ dblink_build_sql_delete(text relname, 返回值 - 以 text 形式返回所请求的 SQL 语句。 + 以文本形式返回所请求的 SQL 语句。 @@ -1904,7 +1861,7 @@ dblink_build_sql_update(text relname, int2vector primary_key_attnums, integer num_primary_key_atts, text[] src_pk_att_vals_array, - text[] tgt_pk_att_vals_array) 返回 text + text[] tgt_pk_att_vals_array) returns text @@ -1974,7 +1931,7 @@ dblink_build_sql_update(text relname, 返回值 - 以 text 形式返回所请求的 SQL 语句。 + 以文本形式返回所请求的 SQL 语句。 diff --git a/zh/15/ddl.sgml b/zh/15/ddl.sgml index ab711228..54b2333d 100644 --- a/zh/15/ddl.sgml +++ b/zh/15/ddl.sgml @@ -232,19 +232,17 @@ INSERT INTO people (id, name, address) VALUES (DEFAULT, 'C' 生成列是一种特殊列,其值总是根据其他列计算得出。因此,对列而言,它就像视图对表一样。生成列有两种:存储型和虚拟型。存储型生成列在写入时(插入或更新时)计算,并像普通列一样占用存储空间。虚拟生成列不占用存储空间,而是在读取时计算。因此,虚拟生成列类似于视图,存储型生成列类似于物化视图(只是它总会自动更新)。 + PostgreSQL 目前只实现了存储型生成列。 - - 要创建生成列,可在CREATE TABLE中使用GENERATED ALWAYS AS子句,例如: - + 要创建生成列,可使用GENERATED ALWAYS + AS子句,在CREATE TABLE中,例如: CREATE TABLE people ( ..., height_cm numeric, - height_in numeric GENERATED ALWAYS AS (height_cm / 2.54) + height_in numeric GENERATED ALWAYS AS (height_cm / 2.54) STORED ); - - 生成列默认是虚拟型。使用关键字VIRTUALSTORED可以显式指定类型。更多细节见。 - +必须指定关键字STORED来选择存储型生成列。参见了解更多细节。 生成列不能直接写入。在INSERTUPDATE命令中,不能为生成列指定值,但可以指定关键字DEFAULT。 @@ -273,11 +271,7 @@ CREATE TABLE people ( 生成表达式不能引用系统列,tableoid 除外。 - - - 虚拟生成列不能使用用户定义类型,并且其生成表达式不得引用用户定义函数或类型,也就是说,它只能使用内置函数或类型。该限制也包括间接使用的情况,例如操作符或类型转换背后的函数或类型。(这一限制不适用于存储型生成列。) - - + 生成列不能具有列默认值或标识定义。 @@ -294,36 +288,16 @@ CREATE TABLE people ( - 对于继承和分区: + 对于继承: - - 如果父列是生成列,其子列也必须是同种类(存储型或虚拟型)的生成列;不过,子列可以使用不同的生成表达式。 - - - - 对于存储型生成列,在插入或更新一行时,实际应用的是该行所在物理表关联的生成表达式。(这与列默认值不同:默认值使用的是查询中所指名表关联的默认值。)对于虚拟生成列,在读取表时,应用的是查询中所指名表的生成表达式。 - + 如果父列是生成列,则子列也必须是使用相同表达式的生成列。在子列的定义中,应省略GENERATED子句,因为它会从父列复制。 - - 如果父列不是生成列,其子列也不能是生成列。 - + 在多重继承的情况下,如果某个父列是生成列,则所有父列都必须是生成列,并且使用相同的表达式。 - - 对于继承表,如果在CREATE TABLE ... INHERITS中编写子列定义时未写任何GENERATED子句,则会自动从父列复制该GENERATED子句。ALTER TABLE ... INHERIT要求父列和子列在是否为生成列这一点上已经匹配,但不要求它们的生成表达式相同。 - - - - - 类似地,对于分区表,如果在CREATE TABLE ... PARTITION OF中编写子列定义时未写任何GENERATED子句,则会自动从父列复制该子句。ALTER TABLE ... ATTACH PARTITION要求父列和子列在生成状态上已经匹配,但不要求它们的生成表达式相同。 - - - - - 在多重继承的情况下,如果某个父列是生成列,则所有父列都必须是生成列。如果它们的生成表达式并不完全相同,则必须为子列显式指定所需的表达式。 - + 如果父列不是生成列,则子列可以定义为生成列,也可以不是生成列。 @@ -338,24 +312,16 @@ CREATE TABLE people ( 生成列与其底层基础列分别维护访问权限。因此,可以安排成某个角色能够读取生成列,但不能读取底层基础列。 - - 对于虚拟生成列,只有在生成表达式只使用防泄漏函数时,这种安排才完全安全(见),但系统不会强制检查这一点。 - - - - - 生成表达式中所用函数的权限,会在表达式实际执行时分别在写入或读取时检查,就像生成表达式是由使用生成列的查询直接调用的一样。生成列的用户必须拥有调用生成表达式中所有函数的权限。生成表达式中的函数是以执行查询的用户的权限还是函数所有者的权限来执行,取决于这些函数被定义为SECURITY INVOKER还是SECURITY DEFINER。 - + + 从概念上说,生成列会在BEFORE触发器运行之后更新。因此,BEFORE触发器中对基础列所做的修改会反映到生成列中。反过来,在BEFORE触发器中访问生成列是不允许的。 - - 生成列可以根据CREATE PUBLICATION参数publish_generated_columns,或者通过把它们包含在CREATE PUBLICATION命令的列列表中,在逻辑复制期间被复制。目前这只支持存储型生成列。详情见。 - + 逻辑复制会跳过生成列,并且不能在CREATE PUBLICATION的列列表中指定生成列。 @@ -1418,7 +1384,7 @@ ALTER TABLE products RENAME TO items; DELETETRUNCATEREFERENCESTRIGGERCREATECONNECTTEMPORARYEXECUTEUSAGE、 - SETALTER SYSTEM以及MAINTAIN。 + SETALTER SYSTEM。 适用于特定对象的权限取决于对象的类型(表、函数等)。 有关这些权限含义的更多详细信息如下所示。 后续的各节和各章还将展示这些权限是如何使用的。 @@ -1434,7 +1400,7 @@ ALTER TABLE products RENAME TO items; ALTER TABLE table_name OWNER TO new_owner; - 超级用户总是可以做到这点,普通角色只有在同时是对象的当前所有者(或者继承拥有角色的权限)并且能够对新的拥有角色执行SET ROLE时,才能做同样的事。旧所有者的所有对象权限会随所有权一起转移给新所有者。 + 超级用户总是可以做到这点,普通角色只有在同时是对象的当前所有者(或拥有者角色的成员)并且是新拥有者角色的成员时,才能做同样的事。旧所有者的所有对象权限会随所有权一起转移给新所有者。 @@ -1667,16 +1633,6 @@ REVOKE ALL ON accounts FROM PUBLIC; - - MAINTAIN - - - 允许在关系上执行VACUUMANALYZE、 - CLUSTERREFRESH MATERIALIZED VIEW、 - REINDEXLOCK TABLE,以及数据库对象统计信息操作函数(见)。 - - - 其他命令所需的权限列在各自命令的参考页面上。 @@ -1819,11 +1775,6 @@ REVOKE ALL ON accounts FROM PUBLIC; A PARAMETER - - MAINTAIN - m - TABLE -
@@ -1921,7 +1872,7 @@ REVOKE ALL ON accounts FROM PUBLIC; TABLE(以及类似表的对象) - arwdDxtm + arwdDxt \dp @@ -3436,7 +3387,16 @@ ALTER INDEX measurement_city_id_logdate_key - 创建表,所有的表都将从它继承。这个表将不包含数据。不要在这个表上定义任何检查约束,除非想让它们应用到所有的子表上。同样,在这个表上定义索引或者唯一约束也没有意义。对于我们的示例来说,根表是最初定义的measurement表。 + 创建表,所有的表都将从它继承。这个表将不包含数据。不要在这个表上定义任何检查约束,除非想让它们应用到所有的子表上。同样,在这个表上定义索引或者唯一约束也没有意义。对于我们的示例来说,根表是最初定义的measurement表: + + +CREATE TABLE measurement ( + city_id int not null, + logdate date not null, + peaktemp int, + unitsales int +); + @@ -4045,7 +4005,7 @@ DROP TABLE products CASCADE; - 对于一个将其主体定义为字符串文字的用户定义函数或过程,PostgreSQL会跟踪与函数的外部可见属性相关的依赖关系,例如其参数和结果类型,但不会跟踪只有通过检查函数主体才能知道的依赖关系。例如,考虑以下情况: + 对于一个将其主体定义为字符串字面量的用户定义函数或过程,PostgreSQL会跟踪与函数的外部可见属性相关的依赖关系,例如其参数和结果类型,但不会跟踪只有通过检查函数主体才能知道的依赖关系。例如,考虑以下情况: CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', diff --git a/zh/15/dfunc.sgml b/zh/15/dfunc.sgml index 52d5aa54..fd697438 100644 --- a/zh/15/dfunc.sgml +++ b/zh/15/dfunc.sgml @@ -47,7 +47,7 @@ FreeBSD - FreeBSDshared library + FreeBSD共享库 @@ -65,7 +65,7 @@ gcc -shared -o foo.so foo.o HP-UX - HP-UXshared library + HP-UX共享库 @@ -92,7 +92,7 @@ ld -b -o foo.sl foo.o Linux - Linuxshared library + Linux共享库 @@ -109,7 +109,7 @@ cc -shared -o foo.so foo.o macOS - macOSshared library + macOS共享库 @@ -125,7 +125,7 @@ cc -bundle -flat_namespace -undefined suppress -o foo.so foo.o NetBSD - NetBSDshared library + NetBSD共享库 @@ -143,7 +143,7 @@ gcc -shared -o foo.so foo.o OpenBSD - OpenBSDshared library + OpenBSD共享库 @@ -160,7 +160,7 @@ ld -Bshareable -o foo.so foo.o Solaris - Solarisshared library + Solaris共享库 diff --git a/zh/15/diskusage.sgml b/zh/15/diskusage.sgml index cfcd855d..be6f91e6 100644 --- a/zh/15/diskusage.sgml +++ b/zh/15/diskusage.sgml @@ -15,15 +15,15 @@ - 每个表都有一个主堆磁盘文件,其中存储了大部分数据。如果该表有任何值可能较宽的列,还可能会有一个与该表关联的TOAST文件,用于存储宽到无法方便地放入主表中的值(见)。如果存在,还会在TOAST表上有一个有效索引。也可能会有与基表关联的索引。每个表和索引都存储在单独的磁盘文件中 — 如果文件会超过 1 GB,则可能分成多个文件。这些文件的命名约定见。 - + 每个表都有一个主堆磁盘文件,大部分数据都存储在那里。如果表中有任何列可能包含较宽的值,还可能有一个与该表关联的 TOAST 文件,用于存储那些不适合放在主表中的过宽值(参见)。如果该 TOAST 表存在,则它会有一个有效索引。基础表本身也可能带有索引。每个表和索引都存储在单独的磁盘文件中;如果某个文件会超过 1 GB,则可能拆分为多个文件。关于这些文件的命名规则,请参见。 + - 可以通过三种方式监控磁盘空间:使用中列出的 SQL 函数,使用模块,或者手工检查系统目录。SQL 函数最容易使用,通常也是推荐的方法。本节其余部分展示如何通过检查系统目录来完成此事。 - + 你可以通过三种方式监控磁盘空间:使用中列出的 SQL 函数、使用模块,或者手工检查系统目录。SQL 函数最容易使用,通常也是推荐的方法。本节余下内容展示如何通过检查系统目录来完成这项工作。 + - 在最近做过 vacuum 或 analyze 的数据库上使用psql时,可以发出查询以查看任意表的磁盘使用情况: + 在最近进行过清理或分析 的数据库上使用 psql,你可以发出查询来查看任意表的磁盘使用情况: SELECT pg_relation_filepath(oid), relpages FROM pg_class WHERE relname = 'customer'; @@ -32,11 +32,11 @@ SELECT pg_relation_filepath(oid), relpages FROM pg_class WHERE relname = 'custom base/16384/16806 | 60 (1 row) - 每个页通常为 8 KB。(请记住,relpages只会由VACUUMANALYZE以及少数 DDL 命令(如CREATE INDEX)更新。)如果你想直接检查该表的磁盘文件,文件路径名就很有用。 - + 每一页通常是 8 KB。(请记住,relpages 只会由 VACUUMANALYZE 以及少数 DDL 命令如 CREATE INDEX 更新。)如果你想直接检查该表的磁盘文件,那么文件路径名会很有用。 + - 要显示TOAST表使用的空间,可使用如下查询: + 要显示 TOAST 表使用的空间,可以使用如下查询: SELECT relname, relpages FROM pg_class, @@ -54,10 +54,10 @@ ORDER BY relname; pg_toast_16806 | 0 pg_toast_16806_index | 1 - + - 也可以很容易地显示索引大小: + 也可以很容易地显示索引所占空间: SELECT c2.relname, c2.relpages FROM pg_class c, pg_class c2, pg_index i @@ -70,10 +70,10 @@ ORDER BY c2.relname; -------------------+---------- customer_id_index | 26 - + - 利用这些信息,可以很容易找出最大的表和索引: + 利用这些信息,你可以很容易地找出最大的表和索引: SELECT relname, relpages FROM pg_class @@ -84,28 +84,28 @@ ORDER BY relpages DESC; bigtable | 3290 customer | 3144 - +
磁盘已满故障 - 数据库管理员最重要的磁盘监控任务,是确保磁盘不会被写满。数据盘被写满不会导致数据损坏,但可能使有用的活动无法继续进行。如果存放 WAL 文件的磁盘逐渐被写满,数据库服务器可能会进入 panic 状态并随后关闭。 - + 数据库管理员最重要的磁盘监控任务,是确保磁盘不会被写满。数据磁盘写满不会导致数据损坏,但可能会阻止有用的活动继续进行。如果保存 WAL 文件的磁盘被写满,则数据库服务器可能会 panic 并随后关闭。 + - 如果无法通过删除其他内容来释放磁盘上的额外空间,可以利用表空间将部分数据库文件移到其他文件系统上。有关更多信息,请参见。 - + 如果你无法通过删除其他文件来释放更多磁盘空间,那么可以利用表空间把部分数据库文件移动到其他文件系统上。详见。 + - 有些文件系统在接近写满时性能很差,因此不要等到磁盘完全写满才采取措施。 - + 有些文件系统在接近写满时性能会明显变差,因此不要等到磁盘完全写满才采取措施。 + - 如果系统支持按用户设置磁盘配额,那么数据库自然会受限于运行服务器的那个用户所被施加的配额。超出配额与磁盘空间完全耗尽会产生同样的不良影响。 - + 如果你的系统支持按用户设置磁盘配额,那么数据库自然也会受到运行服务器的那个用户所拥有配额的限制。超出配额会带来与磁盘空间完全耗尽相同的不良影响。 + diff --git a/zh/15/docguide.sgml b/zh/15/docguide.sgml index 2b146772..75dff471 100644 --- a/zh/15/docguide.sgml +++ b/zh/15/docguide.sgml @@ -231,16 +231,11 @@ checking for dbtoepub... dbtoepub - - 如果你更愿意使用 Meson 构建PostgreSQL,则请按说明运行 - meson setup(见), - 然后参见。 - - 使用 Make 构建文档 + 构建文档 一切设置妥当后,切换到doc/src/sgml目录,并运行后续各小节中介绍的某个命令来构建文档。 @@ -306,7 +301,7 @@ checking for dbtoepub... dbtoepub - 对于 U.S. letter 格式: + 对于美国信纸格式: doc/src/sgml$ make postgres-US.pdf @@ -320,7 +315,7 @@ checking for dbtoepub... dbtoepub 因此,在某些系统上,构建会因内存相关错误而失败。这通常可以通过在配置文件 ~/.foprc中配置 Java 堆设置来解决,例如: -# FOP binary distribution +# FOP 二进制发行版 FOP_OPTS='-Xmx1500m' # Debian JAVA_ARGS='-Xmx1500m' @@ -331,17 +326,24 @@ ADDITIONAL_FLAGS='-Xmx1500m' 对于内存很少(小于 1 GB)的系统,构建要么会因交换而非常缓慢,要么根本无法工作。 + - 在默认配置下,FOP会为每一页输出一条INFO消息。 - 日志级别可通过~/.foprc修改: - -LOGCHOICE=-Dorg.apache.commons.logging.Log=&zwsp;org.apache.commons.logging.impl.SimpleLog -LOGLEVEL=-Dorg.apache.commons.logging.simplelog.defaultlog=WARN - + 也可以手工使用其他 XSL-FO 处理器,但自动化构建过程只支持 FOP。 + + + + 纯文本文件 - 也可以手工使用其他 XSL-FO 处理器,但自动化构建过程只支持 FOP。 + 安装说明也以纯文本形式分发,以便在没有更好的阅读工具时使用。 + INSTALL文件对应,并针对不同语境作了少量调整。 + 要重新生成该文件,请切换到doc/src/sgml目录,然后输入make INSTALL。 + 构建文本输出还需要Pandoc 1.13 或更新版本作为额外的构建工具。 + + + + 过去,发行说明和回归测试说明也曾以纯文本形式分发,但现已停止这种做法。 diff --git a/zh/15/ecpg.sgml b/zh/15/ecpg.sgml index 31dd8d27..7d9fcc54 100644 --- a/zh/15/ecpg.sgml +++ b/zh/15/ecpg.sgml @@ -1139,7 +1139,7 @@ oid=313780, datname=testdb, size=8183012 - 结构体主变量将列尽数吸收成结构体的域。额外的列可以被分配给其他主变量。例如,上面的程序也可以使用结构体外部的size变量重新构造: + 结构体主变量吸收的列数与结构体的字段数相同。额外的列可以被分配给其他主变量。例如,上面的程序也可以使用结构体外部的size变量改写: EXEC SQL BEGIN DECLARE SECTION; typedef struct @@ -1440,7 +1440,7 @@ while (1) 用户定义的基础类型 - ECPG 并不直接支持新的用户定义的基本类型。你可以使用外部字符串表示以及类型char[]VARCHAR[]的主变量,并且这种方案事实上对很多类型都是合适和足够的。 + ECPG 并不直接支持新的用户定义的基础类型。你可以使用外部字符串表示以及类型char[]VARCHAR[]的主变量,并且这种方案事实上对很多类型都是合适和足够的。 @@ -3980,7 +3980,6 @@ datdba = 10 (type: 1) encoding = 0 (type: 5) datistemplate = t (type: 1) datallowconn = t (type: 1) -dathasloginevt = f (type: 1) datconnlimit = -1 (type: 5) datfrozenxid = 379 (type: 1) dattablespace = 1663 (type: 1) @@ -4005,7 +4004,6 @@ datdba = 10 (type: 1) encoding = 0 (type: 5) datistemplate = f (type: 1) datallowconn = t (type: 1) -dathasloginevt = f (type: 1) datconnlimit = -1 (type: 5) datfrozenxid = 379 (type: 1) dattablespace = 1663 (type: 1) @@ -4743,7 +4741,7 @@ EXEC SQL INCLUDE "filename"; 当前目录 /usr/local/include - PostgreSQL 的包括目录,在编译时定义(例如/usr/local/pgsql/include + PostgreSQL 的头文件目录,在编译时定义(例如/usr/local/pgsql/include /usr/include @@ -4870,7 +4868,7 @@ EXEC SQL UPDATE Tbl SET col = MYNUMBER; - 此示例将完全编译三个SET TIMEZONE命令之一: + 此示例将完全编译三个SET TIMEZONE命令之一: EXEC SQL ifdef TZVAR; EXEC SQL SET TIMEZONE TO TZVAR; @@ -5498,7 +5496,7 @@ DATABASE connection_target 使用 user_name/passworduser_name IDENTIFIED BY password或者 - user_name USING password之一,这个参数也能指定用户名和密码. + user_name USING password之一,这个参数也能指定用户名和密码。 @@ -6078,9 +6076,7 @@ EXECUTE IMMEDIATE string - 如果你使用文字字符串,请注意任何你可能希望在SQL语句中包括的双引号必须写为八进制转义(\042) ,而不是通常的C惯语\"。 - 这是因为字符串在EXEC SQL段里面,所以ECPG 语法分析器根据SQL规则而不是C规则来解析它。 - 任何内嵌的反斜杠后续将按照C规格处理;但是\"会造成直接语法错误,因为它被视为文字的终结。 + 如果使用字符串字面量,请注意,要在 SQL 语句中包含的双引号必须写为八进制转义(\042),而不是通常的 C 写法\"。这是因为字符串位于EXEC SQL段中,ECPG 词法分析器会按照 SQL 规则而非 C 规则解析它。内嵌的反斜杠随后会按照 C 规则处理;但\"会被视为字面量的结束,因此会立即引起语法错误。 @@ -6413,9 +6409,7 @@ PREPARE prepared_name FROM - 如果你使用文字字符串,请注意任何你可能希望在SQL语句中包括的双引号必须写为八进制转义(\042) ,而不是通常的C惯语\"。 - 这是因为字符串在EXEC SQL段里面,所以ECPG 语法分析器根据SQL规则而不是C规则来解析它。 - 任何内嵌的反斜杠后续将按照C规格处理;但是\"会造成直接语法错误,因为它被视为文字的终结。 + 如果使用字符串字面量,请注意,要在 SQL 语句中包含的双引号必须写为八进制转义(\042),而不是通常的 C 写法\"。这是因为字符串位于EXEC SQL段中,ECPG 词法分析器会按照 SQL 规则而非 C 规则解析它。内嵌的反斜杠随后会按照 C 规则处理;但\"会被视为字面量的结束,因此会立即引起语法错误。 @@ -7672,19 +7666,19 @@ int rjulmdy(date d, short mdy[3]); rdefmtdate - 使用格式掩码将字符字符串转换为日期类型的值。 + 使用格式掩码将字符串转换为日期类型的值。 int rdefmtdate(date *d, char *fmt, char *str); 该函数接收一个指向应该保存操作结果的日期值的指针(d), 用于解析日期的格式掩码(fmt)和包含日期文本表示的C char*字符串 (str)。文本表示应与格式掩码匹配。但是,你不需要将字符串 - 与格式掩码进行一一映射。该函数仅分析顺序顺序,并查找表示年份位置的文字 + 与格式掩码进行一一映射。该函数只分析先后顺序,并查找表示年份位置的字面文本 yyyyyy,表示月份位置的mm 和表示日期位置的dd - 该函数返回以下值: + 该函数返回以下值: diff --git a/zh/15/event-trigger.sgml b/zh/15/event-trigger.sgml index d461e798..3a360626 100644 --- a/zh/15/event-trigger.sgml +++ b/zh/15/event-trigger.sgml @@ -20,11 +20,11 @@ - 事件触发器行为概览 + 事件触发器行为概述 只要与事件触发器关联的事件在其定义所在数据库中发生,事件触发器就会被触发。 - 目前支持的事件有 + 目前仅支持以下事件: ddl_command_startddl_command_endtable_rewrite @@ -32,97 +32,49 @@ 未来版本可能会增加对更多事件的支持。 - - ddl_command_start - - - ddl_command_start 事件发生在 DDL 命令即将执行之前。 - 此处的 DDL 命令包括: - - CREATE - ALTER - DROP - COMMENT - GRANT - IMPORT FOREIGN SCHEMA - REINDEX - REFRESH MATERIALIZED VIEW - REVOKE - SECURITY LABEL - + + ddl_command_start 事件发生在 + CREATEALTERDROP、 + SECURITY LABEL、 + COMMENTGRANTREVOKE + 命令即将执行之前。在事件触发器触发之前,不会检查受影响对象究竟存在还是不存在。 + 但有一个例外:对于以共享对象 — 数据库、角色和表空间 — + 为目标的 DDL 命令或者针对事件触发器本身的命令,不会发生该事件。事件触发器机制 + 不支持这些对象类型。 ddl_command_start 也会在 SELECT INTO 命令即将执行之前发生,因为它等价于 CREATE TABLE AS - - 但有一个例外:对于以共享对象为目标的 DDL 命令,不会发生该事件: - - 数据库 - 角色(角色定义和角色成员关系) - 表空间 - 参数权限 - ALTER SYSTEM - - 针对事件触发器本身的命令也不会引发该事件。 - - - - 在事件触发器触发之前,不会检查受影响对象究竟存在还是不存在。 - - - - - ddl_command_end - - - ddl_command_end 事件发生在与 - ddl_command_start 相同的一组命令执行之后。 + + ddl_command_end 事件发生在上述同一组命令执行之后。 要获取这些 DDL 操作的更多细节,可在 ddl_command_end 事件触发器代码中使用集合返回函数 pg_event_trigger_ddl_commands()(见 )。注意,触发器是在这些动作已发生 之后(但在事务提交之前)触发的,因此读取系统目录时,看到的已是变更后的状态。 - - - - sql_drop - + 对于任何删除数据库对象的操作,sql_drop 事件都发生在 - ddl_command_end 事件触发器之前。请注意,除了显而易见的 - DROP 命令外,某些 ALTER 命令也会触发 - sql_drop 事件。 - - - - 要列出已删除的对象,可在 sql_drop 事件触发器代码中使用 + ddl_command_end 事件触发器之前。要列出已删除的对象,可在 + sql_drop 事件触发器代码中使用 集合返回函数 pg_event_trigger_dropped_objects()(见 )。注意,触发器是在这些对象已经从 系统目录中删除之后执行的,因此已无法再查找它们。 - - - table_rewrite - - + table_rewrite 事件发生在表即将因 ALTER TABLEALTER TYPE 命令中的某些 操作而被重写之前。虽然还有其他控制语句也可以重写表,例如 CLUSTERVACUUM,但它们不会触发 table_rewrite 事件。要找出被重写表的 OID,请使用函数 - pg_event_trigger_table_rewrite_oid();要找出重写的一个或多个 - 原因, - 可使用函数 pg_event_trigger_table_rewrite_reason()(见 )。 + pg_event_trigger_table_rewrite_oid()(见 + )。要找出重写的一个或多个原因, + 可使用函数 pg_event_trigger_table_rewrite_reason() - - - 已中止事务中的事件触发器 - - + 事件触发器(与其他函数一样)不能在已中止的事务中执行。因此,如果 DDL 命令因 错误而失败,任何关联的 ddl_command_end 触发器都不会执行。 反之,如果 ddl_command_start 触发器因错误而失败,后续事 @@ -130,12 +82,13 @@ ddl_command_end 触发器因错误而失败,DDL 语句的效果将被回 滚,就像包含该语句的事务在任何其他情况下中止时那样。 - - - - 创建事件触发器 + 有关事件触发器机制所支持命令的完整列表,参见 + 。 + + + 事件触发器通过命令 创建。 为了创建事件触发器,必须先创建一个返回类型为 event_trigger 的特殊函数。 @@ -152,7 +105,927 @@ ddl_command_start 触发器就可以只针对用户希望拦截的特定命 令触发。这类触发器的一个常见用途是限制用户可执行的 DDL 操作范围。 - + + + + 事件触发器触发矩阵 + + + 列出了事件触发器所支持的 + 所有命令。 + + + + 按命令标签分类的事件触发器支持 + + + + + + + + + + 命令标签 + ddl_&zwsp;command_&zwsp;start + ddl_&zwsp;command_&zwsp;end + sql_&zwsp;drop + table_&zwsp;rewrite + 备注 + + + + + ALTER AGGREGATE + X + X + - + - + + + + ALTER COLLATION + X + X + - + - + + + + ALTER CONVERSION + X + X + - + - + + + + ALTER DOMAIN + X + X + - + - + + + + ALTER DEFAULT PRIVILEGES + X + X + - + - + + + + ALTER EXTENSION + X + X + - + - + + + + ALTER FOREIGN DATA WRAPPER + X + X + - + - + + + + ALTER FOREIGN TABLE + X + X + X + - + + + + ALTER FUNCTION + X + X + - + - + + + + ALTER LANGUAGE + X + X + - + - + + + + ALTER LARGE OBJECT + X + X + - + - + + + + ALTER MATERIALIZED VIEW + X + X + - + X + + + + ALTER OPERATOR + X + X + - + - + + + + ALTER OPERATOR CLASS + X + X + - + - + + + + ALTER OPERATOR FAMILY + X + X + - + - + + + + ALTER POLICY + X + X + - + - + + + + ALTER PROCEDURE + X + X + - + - + + + + ALTER PUBLICATION + X + X + - + - + + + + ALTER ROUTINE + X + X + - + - + + + + ALTER SCHEMA + X + X + - + - + + + + ALTER SEQUENCE + X + X + - + - + + + + ALTER SERVER + X + X + - + - + + + + ALTER STATISTICS + X + X + - + - + + + + ALTER SUBSCRIPTION + X + X + - + - + + + + ALTER TABLE + X + X + X + X + + + + ALTER TEXT SEARCH CONFIGURATION + X + X + - + - + + + + ALTER TEXT SEARCH DICTIONARY + X + X + - + - + + + + ALTER TEXT SEARCH PARSER + X + X + - + - + + + + ALTER TEXT SEARCH TEMPLATE + X + X + - + - + + + + ALTER TRIGGER + X + X + - + - + + + + ALTER TYPE + X + X + - + X + + + + ALTER USER MAPPING + X + X + - + - + + + + ALTER VIEW + X + X + - + - + + + + COMMENT + X + X + - + - + 仅限本地对象 + + + CREATE ACCESS METHOD + X + X + - + - + + + + CREATE AGGREGATE + X + X + - + - + + + + CREATE CAST + X + X + - + - + + + + CREATE COLLATION + X + X + - + - + + + + CREATE CONVERSION + X + X + - + - + + + + CREATE DOMAIN + X + X + - + - + + + + CREATE EXTENSION + X + X + - + - + + + + CREATE FOREIGN DATA WRAPPER + X + X + - + - + + + + CREATE FOREIGN TABLE + X + X + - + - + + + + CREATE FUNCTION + X + X + - + - + + + + CREATE INDEX + X + X + - + - + + + + CREATE LANGUAGE + X + X + - + - + + + + CREATE MATERIALIZED VIEW + X + X + - + - + + + + CREATE OPERATOR + X + X + - + - + + + + CREATE OPERATOR CLASS + X + X + - + - + + + + CREATE OPERATOR FAMILY + X + X + - + - + + + + CREATE POLICY + X + X + - + - + + + + CREATE PROCEDURE + X + X + - + - + + + + CREATE PUBLICATION + X + X + - + - + + + + CREATE RULE + X + X + - + - + + + + CREATE SCHEMA + X + X + - + - + + + + CREATE SEQUENCE + X + X + - + - + + + + CREATE SERVER + X + X + - + - + + + + CREATE STATISTICS + X + X + - + - + + + + CREATE SUBSCRIPTION + X + X + - + - + + + + CREATE TABLE + X + X + - + - + + + + CREATE TABLE AS + X + X + - + - + + + + CREATE TEXT SEARCH CONFIGURATION + X + X + - + - + + + + CREATE TEXT SEARCH DICTIONARY + X + X + - + - + + + + CREATE TEXT SEARCH PARSER + X + X + - + - + + + + CREATE TEXT SEARCH TEMPLATE + X + X + - + - + + + + CREATE TRIGGER + X + X + - + - + + + + CREATE TYPE + X + X + - + - + + + + CREATE USER MAPPING + X + X + - + - + + + + CREATE VIEW + X + X + - + - + + + + DROP ACCESS METHOD + X + X + X + - + + + + DROP AGGREGATE + X + X + X + - + + + + DROP CAST + X + X + X + - + + + + DROP COLLATION + X + X + X + - + + + + DROP CONVERSION + X + X + X + - + + + + DROP DOMAIN + X + X + X + - + + + + DROP EXTENSION + X + X + X + - + + + + DROP FOREIGN DATA WRAPPER + X + X + X + - + + + + DROP FOREIGN TABLE + X + X + X + - + + + + DROP FUNCTION + X + X + X + - + + + + DROP INDEX + X + X + X + - + + + + DROP LANGUAGE + X + X + X + - + + + + DROP MATERIALIZED VIEW + X + X + X + - + + + + DROP OPERATOR + X + X + X + - + + + + DROP OPERATOR CLASS + X + X + X + - + + + + DROP OPERATOR FAMILY + X + X + X + - + + + + DROP OWNED + X + X + X + - + + + + DROP POLICY + X + X + X + - + + + + DROP PROCEDURE + X + X + X + - + + + + DROP PUBLICATION + X + X + X + - + + + + DROP ROUTINE + X + X + X + - + + + + DROP RULE + X + X + X + - + + + + DROP SCHEMA + X + X + X + - + + + + DROP SEQUENCE + X + X + X + - + + + + DROP SERVER + X + X + X + - + + + + DROP STATISTICS + X + X + X + - + + + + DROP SUBSCRIPTION + X + X + X + - + + + + DROP TABLE + X + X + X + - + + + + DROP TEXT SEARCH CONFIGURATION + X + X + X + - + + + + DROP TEXT SEARCH DICTIONARY + X + X + X + - + + + + DROP TEXT SEARCH PARSER + X + X + X + - + + + + DROP TEXT SEARCH TEMPLATE + X + X + X + - + + + + DROP TRIGGER + X + X + X + - + + + + DROP TYPE + X + X + X + - + + + + DROP USER MAPPING + X + X + X + - + + + + DROP VIEW + X + X + X + - + + + + GRANT + X + X + - + - + 仅限本地对象 + + + IMPORT FOREIGN SCHEMA + X + X + - + - + + + + REFRESH MATERIALIZED VIEW + X + X + - + - + + + + REVOKE + X + X + - + - + 仅限本地对象 + + + SECURITY LABEL + X + X + - + - + 仅限本地对象 + + + SELECT INTO + X + X + - + - + + + + +
@@ -186,7 +1059,7 @@ CALLED_AS_EVENT_TRIGGER(fcinfo) ((fcinfo)->context != NULL && IsA((fcinfo)->context, EventTriggerData)) - 如果该宏返回 true,那么就可以安全地将 fcinfo->context + 如果该宏返回真,那么就可以安全地将 fcinfo->context 转换为 EventTriggerData * 类型,并使用它所指向的 EventTriggerData 结构体。该函数 不得修改 EventTriggerData @@ -222,11 +1095,10 @@ typedef struct EventTriggerData event - + 描述调用该函数对应的事件,可为 "ddl_command_start"、 - "ddl_command_end"、 - "sql_drop"、 + "ddl_command_end""sql_drop""table_rewrite" 之一。 关于这些事件的含义,参见 @@ -258,7 +1130,7 @@ typedef struct EventTriggerData 事件触发器函数必须返回一个 NULL 指针 (不是 SQL 空值,也就是不要将 - isNull 设为 true)。 + isNull 设为真)。 @@ -277,13 +1149,10 @@ typedef struct EventTriggerData 中提到的例外)。
- - 以下是该触发器函数的源代码: -下面是触发器函数的源代码: -
+ diff --git a/zh/15/extend.sgml b/zh/15/extend.sgml index df81cf7c..05d6a6e6 100644 --- a/zh/15/extend.sgml +++ b/zh/15/extend.sgml @@ -59,7 +59,7 @@ 类型、函数、访问方法等的信息。这些表可以由用户修改,而 PostgreSQL 又是基于这些表来运行的,这意味着 PostgreSQL 可以由用户扩展。相比之下,传统数据库 - 系统通常只能通过修改源代码中的硬编码过程,或加载由 + 系统只能通过修改源代码中的硬编码过程,或加载由 DBMS 供应商专门编写的模块来扩展。 @@ -92,7 +92,7 @@ 数据类型 - 组合 + 复合 @@ -517,7 +517,7 @@ RETURNS anycompatible AS ... 哪些 SQL 对象种类可以成为扩展成员,见 ALTER EXTENSION 的说明。特别是,数据库集簇范围内的对象,如数据库、角色和表空间,不能 - 成为扩展成员,因为扩展只在单个数据库内可见。(尽管扩展脚本并不禁止创 + 成为扩展成员,因为扩展只在单个数据库内可见。(尽管并不禁止扩展脚本创 建这类对象,但如果这样做,它们不会作为扩展的一部分受到跟踪。)还要注意, 虽然表可以成为扩展成员,但其附属对象(如索引)并不直接被视为扩展成员。 另一个重要点是,模式可以属于扩展,但反过来不成立:扩展本身只有一个非 @@ -552,10 +552,7 @@ RETURNS anycompatible AS ... 件指定不同的目录。 - - 扩展控制文件的其他查找位置可通过参数 - 配置。 - + 扩展控制文件的格式与 postgresql.conf 文件相同, @@ -575,8 +572,8 @@ RETURNS anycompatible AS ... 包含扩展 SQL 脚本文件的目录。除非给出的是绝对路 - 径,否则该名称相对于找到控制文件的目录。默认情况下,会在找到控制 - 文件的同一目录中查找脚本文件。 + 径,否则该名称相对于安装的 SHAREDIR 目录。默认行为 + 等价于指定 directory = 'extension' @@ -621,8 +618,8 @@ RETURNS anycompatible AS ... 该参数的值会替换脚本文件中每次出现的 MODULE_PATHNAME。如果未设置该参数,则不会进行替 - 换。通常会把它设置为简单的 - shared_library_name, + 换。通常会把它设置为 + $libdir/shared_library_name, 然后在 C 语言函数的 CREATE FUNCTION 命令中使用 MODULE_PATHNAME,这样脚本文件就无需把共享库的名 字硬编码进去。 @@ -658,21 +655,7 @@ RETURNS anycompatible AS ... trusted (boolean) - - 如果该参数被设为 true(默认并非如此),则允许某些 - 非超级用户安装 superuser 设为 - true 的扩展。具体来说,任何在当前数据库上具有 - CREATE 权限的用户都被允许安装。当执行 - CREATE EXTENSION 的用户不是超级用户,但因该参数 - 而被允许安装时,安装或更新脚本会以引导超级用户的身份运行,而不是以 - 调用用户的身份运行。如果 superuser 为 - false,这个参数就没有意义。一般来说,对于可能让 - 用户访问原本只有超级用户才能使用的能力(如文件系统访问)的扩展,不 - 应把它设为 true。此外,把一个扩展标记为 - trusted,还需要付出大量额外努力来确保安装和更 - 新脚本写得足够安全;见 - 。 - + 如果将此参数设为 true(不是默认值),则允许某些非超级用户安装 superuser 设为 true 的扩展。具体而言,当前数据库上具有 CREATE 权限的任何人都可以安装。当执行 CREATE EXTENSION 的用户不是超级用户,但凭借此参数获准安装时,安装或更新脚本会以引导超级用户的身份运行,而不是调用用户的身份。如果 superuserfalse,则此参数不起作用。通常,对于可能允许访问原本仅限超级用户使用的能力(例如文件系统访问)的扩展,不应将此参数设为真。此外,将扩展标记为受信任的,需要投入大量额外工作来安全地编写其安装和更新脚本;参见 @@ -733,8 +716,8 @@ RETURNS anycompatible AS ... 如果扩展脚本中包含字符串 @extowner@,该字符串会被 替换为调用 CREATE EXTENSION 或 - ALTER EXTENSION 的用户名称(会作适当引用)。通常, - 这个特性被标记为 trusted 的扩展用来把选定对象的 + ALTER EXTENSION 的用户名称(会适当加上引号)。通常, + 这个特性被标记为受信任的扩展用来把选定对象的 所有权赋给调用用户, 而不是赋给引导超级用户。(不过这样做时应当谨慎。例如,把一个 C 语言 函数的所有权赋给非超级用户,会为该用户创建一条权限提升路径。) @@ -942,7 +925,7 @@ SELECT pg_catalog.pg_extension_config_dump('my_config', 'WHERE NOT standard_entr 在有合适更新脚本可用的前提下, - ALTER EXTENSION UPDATE 命令可以把已安装的扩展更新 + ALTER EXTENSION UPDATE 命令会把已安装的扩展更新 到指定的新版本。更新脚本运行在 CREATE EXTENSION 为安装脚本提供的同一环境中:尤其 是,search_path 的设置方式完全相同,而且脚本创建的 @@ -968,7 +951,7 @@ SELECT pg_catalog.pg_extension_config_dump('my_config', 'WHERE NOT standard_entr 例如,它并不知道 1.1 是否跟在 1.0 之后。它只是匹配可用的版本名,并选择需要应用 更新脚本最少的那条路径。(实际上,版本名可以是任何不包含 - --,且不以前导或尾随 - 结尾的字 + --,且不以 - 开头或结尾的字 符串。) @@ -1041,19 +1024,9 @@ SELECT * FROM pg_extension_update_paths('extension_name - - 将 superuser 属性设为 true 的 - 扩展,还必须考虑其安装脚本和更新脚本中操作所带来的安全风险。恶意用户并不难创建出特洛伊木 - 马对象,从而在后续粗心编写的扩展脚本执行时造成破坏,并借此获得超级用 - 户权限。 - + superuser 属性设为真的扩展,还必须考虑其安装和更新脚本所执行操作的安全风险。恶意用户可以创建木马对象,破坏以后对编写不慎的扩展脚本的执行,从而获得超级用户权限;这并非特别困难。 - - 如果一个扩展被标记为 trusted,那么安装用户可以自己 - 选择安装模式,而该用户可能会有意使用不安全的模式,希望借此获得超级用 - 户权限。因此,从安全角度看,trusted 扩展暴露程度 - 极高,必须仔细审查其所有脚本命令,确保不存在任何可被利用之处。 - + 如果扩展被标记为 trusted,那么安装用户可以选择其安装模式,而该用户可能故意使用不安全的模式,试图获得超级用户权限。因此,从安全角度看,受信任的扩展面临的风险极高,必须仔细检查其全部脚本命令,确保无法被攻破。 关于如何安全地编写函数,建议见下面的 @@ -1101,7 +1074,7 @@ SELECT * FROM pg_extension_update_paths('extension_namemyschema.myfunc(bigint),那么像 myschema.myfunc(42) 这样的调用,就可能被恶意函数 myschema.myfunc(integer) 截获。要注意函数和操作符 - 参数的数据类型必须与声明的实参类型精确匹配,必要时请使用显式类型转 + 所传参数的数据类型必须与声明的参数类型精确匹配,必要时请使用显式类型转 换。 @@ -1138,12 +1111,12 @@ SELECT * FROM pg_extension_update_paths('extension_name - 跨扩展引用很难做到完全安全,部分原因是无法确定另一个扩展位于哪个模式 - 中。如果两个扩展安装在同一模式中,风险会降低,因为此时敌意对象无法在 - 安装时的 search_path 中排列到被引用扩展的前面。然 - 而,目前没有机制可以强制要求这一点。就目前而言,最佳做法是不要把一个 - 依赖另一个扩展的扩展标记为受信任的,除非那个被依赖的扩展总是安装在 - pg_catalog 中。 + 跨扩展引用要做到完全安全是极其困难的,部分原因是无法确定另一个扩展 + 位于哪个模式中。如果两个扩展都安装在同一个模式中,风险就会降低, + 因为这样恶意对象就无法在安装时的 search_path 中 + 被放到被引用扩展之前。但目前还没有机制来强制要求这一点。就目前而言, + 最佳实践是:如果一个扩展依赖于另一个扩展,就不要将它标记为受信任的, + 除非那个被依赖的扩展始终安装在 pg_catalog 中。 @@ -1152,7 +1125,7 @@ SELECT * FROM pg_extension_update_paths('extension_name扩展示例 - 下面给出一个纯 SQL 扩展的完整示例:一个双元素组合 + 下面给出一个纯 SQL 扩展的完整示例:一个双元素复合 类型,它可以在两个槽位中存储任意类型的值,这两个槽位名为 kv。非文本值会自动强制转换为文本后 再存储。 @@ -1233,7 +1206,7 @@ include $(PGXS) 如果你打算分发自己的 PostgreSQL 扩展模块, - 那么为它们搭建一个可移植的构建系统会相当困难。因此, + 那么为它们搭建一个可移植的构建系统可能相当困难。因此, PostgreSQL 安装提供了一套称为 PGXS 的扩展构建基础设施,使简单的扩展模块可以针对 已安装好的服务器直接构建。PGXS 主要面向包含 C 代码 @@ -1284,7 +1257,7 @@ include $(PGXS) MODULE_big - 要从多个源文件构建的共享库(在 OBJS 中列出对象 + 要从多个源文件构建的共享库(在 OBJS 中列出目标 文件) @@ -1294,7 +1267,7 @@ include $(PGXS) PROGRAM - 要构建的可执行程序(在 OBJS 中列出对象文件) + 要构建的可执行程序(在 OBJS 中列出目标文件) @@ -1589,33 +1562,7 @@ include $(PGXS) make 命令行上设置都可以。 - - 你还可以在执行 make install 时,通过设置 - make 变量 prefix 来选择一个独立 - 的目录前缀,以安装扩展文件,例如: - -make install prefix=/usr/local/postgresql - - 这样会把扩展控制文件和 SQL 文件安装到 - /usr/local/postgresql/share,把共享模块安装到 - /usr/local/postgresql/lib。如果该前缀不包含 - postgrespgsql 字符串,例如: - -make install prefix=/usr/local/extras - - 那么 postgresql 会被附加到目录名中,从而把控制文件 - 和 SQL 文件安装到 - /usr/local/extras/share/postgresql/extension, - 把共享模块安装到 - /usr/local/extras/lib/postgresql。无论哪种情况, - 你都需要设置 和 - ,以便 - PostgreSQL 服务器能找到这些文件: - -extension_control_path = '/usr/local/extras/share/postgresql:$system' -dynamic_library_path = '/usr/local/extras/lib/postgresql:$libdir' - - + 如果你想保持构建目录与源代码目录分离,也可以在扩展源代码树之外的目录 @@ -1649,7 +1596,7 @@ make VPATH=/path/to/extension/source/tree install 正在运行的 PostgreSQL 服务器。列在 REGRESS 中的脚本文件必须位于扩展目录下名为 sql/ 的子目录中。这些文件必须具有 - .sql 扩展名,而该扩展名不应出现在 makefile 的 + .sql 扩展名,而该扩展名不能出现在 makefile 的 REGRESS 列表中。对于每个测试,还应在名为 expected/ 的子目录中有一个包含期望输出的文件,其主 干名相同,扩展名为 .out。 @@ -1668,7 +1615,7 @@ make VPATH=/path/to/extension/source/tree install 必须有一个正在运行的 PostgreSQL 服务器。列 在 ISOLATION 中的脚本文件必须位于扩展目录下名为 specs/ 的子目录中。这些文件必须具有 - .spec 扩展名,而该扩展名不应出现在 makefile 的 + .spec 扩展名,而该扩展名不能出现在 makefile 的 ISOLATION 列表中。对于每个测试,还应在名为 expected/ 的子目录中有一个包含期望输出的文件,其主 干名相同,扩展名为 .out。 diff --git a/zh/15/fdwhandler.sgml b/zh/15/fdwhandler.sgml index 2272d9af..fca1062a 100644 --- a/zh/15/fdwhandler.sgml +++ b/zh/15/fdwhandler.sgml @@ -747,7 +747,7 @@ RecheckForeignScan(ForeignScanState *node, - <command>EXPLAIN</command>的FDW例程 + <command>EXPLAIN</command> 的 FDW 例程 @@ -797,7 +797,7 @@ ExplainDirectModify(ForeignScanState *node, - <command>ANALYZE</command>的FDW例程 + <command>ANALYZE</command> 的 FDW 例程 diff --git a/zh/15/features.sgml b/zh/15/features.sgml index 7dd14ac4..eea44acd 100644 --- a/zh/15/features.sgml +++ b/zh/15/features.sgml @@ -406,7 +406,7 @@ SELECT XMLQUERY('$a is $b' PASSING BY VALUE x AS a, < DOCUMENTCONTENT形式的值。 一个 XQuery/XPath 表达式的上下文项必须是单个 XML 节点或原子值, 但 XPath 1.0 又进一步限制它只能是 XML 节点,并且没有允许CONTENT的节点类型。 - 归根结底,格式良好的DOCUMENT是 + 归根结底,良构的DOCUMENTPostgreSQL能够作为 XPath 上下文项提供的唯一 XML 值形式。 diff --git a/zh/15/func.sgml b/zh/15/func.sgml index 49d5679f..d89c54bd 100644 --- a/zh/15/func.sgml +++ b/zh/15/func.sgml @@ -39,20 +39,17 @@ repeat('Pg', 4) PgPgPgPg 逻辑操作符 - operator - logical + 操作符 + 逻辑 - Boolean - operators - operators, logical + 布尔 + 操作符 + 操作符,逻辑 - - 常用的逻辑操作符有: - - + 可以使用以下常见逻辑操作符: AND(操作符) @@ -65,15 +62,15 @@ repeat('Pg', 4) PgPgPgPg - conjunction + 合取 - disjunction + 析取 - negation + 否定 @@ -82,9 +79,7 @@ repeat('Pg', 4) PgPgPgPg NOT boolean boolean - SQL使用三值的逻辑系统,包括真、假和nullnull表示未知。观察下面的真值表: - - + SQL使用由真、假和null构成的三值逻辑系统,其中null表示未知。请看下面的真值表: @@ -181,8 +176,8 @@ repeat('Pg', 4) PgPgPgPg 比较函数和操作符 - comparison - operators + 比较 + 操作符 @@ -265,14 +260,14 @@ repeat('Pg', 4) PgPgPgPg - <> 表示 not equal 的标准的SQL符号。 - != 是一个别名, 在解析的早期阶段被转换为 <> 。 - 因此, 它不可能实现 !=<> 操作符以做不同的事情。 + <>不等于 的标准 SQL 符号。 + != 是一个别名,在解析的早期阶段就会被转换为 <>。 + 因此,不可能让 !=<> 操作符执行不同的操作。 - 这些比较操作符适用于所有具有自然排序的内置数据类型,包括数字、字符串和日期/时间类型。 + 这些比较操作符适用于所有具有自然排序的内置数据类型,包括数值、字符串和日期/时间类型。 此外,如果其组成数据类型具有可比性,则也可以比较数组、复合类型和范围。 @@ -318,7 +313,7 @@ repeat('Pg', 4) PgPgPgPg boolean - 之间(包括范围端点)。 + 位于两者之间(包括范围端点)。 2 BETWEEN 1 AND 3 @@ -378,7 +373,7 @@ repeat('Pg', 4) PgPgPgPg boolean - 不相等, 将空(null)视为可比值。 + 不相等,将 null 视为可比值。 1 IS DISTINCT FROM NULL @@ -396,7 +391,7 @@ repeat('Pg', 4) PgPgPgPg boolean - 相等, 将空(null)视为可比值。 + 相等,将 null 视为可比值。 1 IS NOT DISTINCT FROM NULL @@ -414,7 +409,7 @@ repeat('Pg', 4) PgPgPgPg boolean - 测试值是否为空。 + 测试值是否为 null。 1.5 IS NULL @@ -428,7 +423,7 @@ repeat('Pg', 4) PgPgPgPg boolean - 测试值是否不为空。 + 测试值是否不为 null。 'null' IS NOT NULL @@ -442,7 +437,7 @@ repeat('Pg', 4) PgPgPgPg boolean - 测试值是否为空(非标准语法)。 + 测试值是否为 null(非标准语法)。 @@ -452,7 +447,7 @@ repeat('Pg', 4) PgPgPgPg boolean - 测试值是否不为空(非标准语法)。 + 测试值是否不为 null(非标准语法)。 @@ -573,30 +568,22 @@ repeat('Pg', 4) PgPgPgPg BETWEEN SYMMETRIC - - BETWEEN谓词可以简化范围测试: - + BETWEEN谓词可以简化范围测试: a BETWEEN x AND y - - 等效于 - +等价于 a >= x AND a <= y - - 注意BETWEEN认为终点值是包含在范围内的。 - BETWEEN SYMMETRIC 就像BETWEEN,除了没有要求AND的左边的参数小于或等于右边的参数。 - 如果不是的话,这两个参数将自动交换,因此总是隐含一个非空范围。 - +注意,BETWEEN将两个端点值都视为包含在范围内。BETWEEN SYMMETRIC类似于BETWEEN,但不要求AND左侧的参数小于或等于右侧的参数。如果不是这样,这两个参数会自动交换,以确保表示的范围始终非空。 - BETWEEN的各种变量都是以普通比较操作符的方式实现的,因此适用于任何可以比较的数据类型。 + BETWEEN的各种变体都是以普通比较操作符的方式实现的,因此适用于任何可以比较的数据类型。 - 在BETWEEN语法中使用AND会与使用AND作为逻辑操作符产生歧义。 - 为了解决这个问题,只允许有限的一组表达类型作为BETWEEN子句的第二个参数。 - 如果您需要在BETWEEN中写一个更复杂的子表达式,在子表达式两边写上圆括号。 + 在BETWEEN语法中使用AND,会与将AND用作逻辑操作符产生歧义。 + 为了解决这个问题,只允许有限的一组表达式类型作为BETWEEN子句的第二个参数。 + 如果你需要在BETWEEN中写一个更复杂的子表达式,请在该子表达式两边加上圆括号。 @@ -607,12 +594,12 @@ repeat('Pg', 4) PgPgPgPg IS NOT DISTINCT FROM - 当有一个输入为空时,普通的比较操作符会得到空(表示未知),而不是真或假。例如,7 = NULL得到空,7 <> NULL也一样。如果这种行为不合适,可以使用IS NOT DISTINCT FROM谓词: + 当任一输入为 null 时,普通的比较操作符会得到 null(表示未知),而不是真或假。例如,7 = NULL得到 null,7 <> NULL也一样。如果这种行为不合适,可以使用IS NOT DISTINCT FROM谓词: a IS DISTINCT FROM b a IS NOT DISTINCT FROM b - 对于非空输入,IS DISTINCT FROM<>操作符一样。不过,如果两个输入都为空,它会返回假。而如果只有一个输入为空,它会返回真。类似地,IS NOT DISTINCT FROM对于非空输入的行为与=相同,但是当两个输入都为空时它返回真,并且当只有一个输入为空时返回假。因此,这些谓词实际上把空值当作一种普通数据值,而不是未知。 + 对于非 null 输入,IS DISTINCT FROM<>操作符一样。不过,如果两个输入都为 null,它会返回假。而如果只有一个输入为 null,它会返回真。类似地,IS NOT DISTINCT FROM对于非 null 输入的行为与=相同,但是当两个输入都为 null 时它返回真,并且当只有一个输入为 null 时返回假。因此,这些谓词实际上把 null 当作一种普通数据值,而不是未知 @@ -628,17 +615,17 @@ repeat('Pg', 4) PgPgPgPg NOTNULL - 要检查一个值是否为空,使用下面的谓词: + 要检查一个值是否为 null,使用下面的谓词: expression IS NULL expression IS NOT NULL - 或者等效,但并不标准的谓词: + 或者等效但非标准的谓词: expression ISNULL expression NOTNULL - null valuecomparing + 空值比较 @@ -648,24 +635,12 @@ repeat('Pg', 4) PgPgPgPg - 有些应用可能要求表达式expression = NULLexpression得出空值时返回真。我们强烈建议这样的应用修改成遵循 SQL 标准。但是,如果这样修改不可能完成,那么我们可以使用配置变量。如果打开它,PostgreSQL将把x = NULL子句转换成x IS NULL。 + 有些应用可能期望表达式expression = NULLexpression求值为 null 时返回真。我们强烈建议此类应用修改为遵循 SQL 标准。但是,如果无法这样修改,那么可以使用配置变量。如果将其打开,PostgreSQL会把x = NULL子句转换成x IS NULL - 如果expression是行值,那么当行表达式本身为 null 或其所有字段都为 null 时,IS NULL 为真;而当行表达式本身非 null 且其所有字段都非 null 时,IS NOT NULL 为真。由于这种行为,IS NULLIS NOT NULL并不总是对行值表达式返回相反的结果;特别是,一个同时包含 null 和非 null 字段的行值表达式会对这两种测试都返回假。例如: - - -SELECT ROW(1,2.5,'this is a test') = ROW(1, 3, 'not the same'); - -SELECT ROW(table.*) IS NULL FROM table; -- detect all-null rows - -SELECT ROW(table.*) IS NOT NULL FROM table; -- detect all-non-null rows - -SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in rows - - - 在某些情况下,写成row IS DISTINCT FROM NULL或者row IS NOT DISTINCT FROM NULL可能更合适,因为它们只会检查整个行值是否为 null,而不会再对行字段做额外测试。 + 如果expression是行值,那么当行表达式本身为 null 或其所有字段都为 null 时,IS NULL 为真;而当行表达式本身非 null 且其所有字段都非 null 时,IS NOT NULL 为真。由于这种行为,IS NULLIS NOT NULL并不总是对行值表达式返回相反的结果;特别是,一个同时包含 null 和非 null 字段的行值表达式会对这两种测试都返回假。在某些情况下,写成row IS DISTINCT FROM NULL或者row IS NOT DISTINCT FROM NULL可能更合适,因为它们只会检查整个行值是否为 null,而不会再对行字段做额外测试。 @@ -696,7 +671,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in boolean_expression IS UNKNOWN boolean_expression IS NOT UNKNOWN - 这些谓词将总是返回真或假,从来不返回空值,即使操作数是空也如此。空值输入被当做逻辑值未知。 请注意实际上IS UNKNOWNIS NOT UNKNOWN分别与IS NULLIS NOT NULL相同, 只是输入表达式必须是布尔类型。 + 这些谓词总是返回真或假,从不返回空值,即使操作数为 null 也是如此。null 输入被当作逻辑值未知。请注意,IS UNKNOWNIS NOT UNKNOWN实际上分别等同于IS NULLIS NOT NULL,只是输入表达式必须是布尔类型。 @@ -733,7 +708,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in integer - 返回非空参数的数量。 + 返回非 null 参数的数量。 num_nonnulls(1, NULL, 2) @@ -750,7 +725,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in integer - 返回空参数的数量。 + 返回 null 参数的数量。 num_nulls(1, NULL, 2) @@ -768,12 +743,12 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in 数学函数和操作符 - PostgreSQL为很多类型提供了数学操作符。对于那些没有标准数学表达的类型(如日期/时间类型),我们将在后续小节中描述实际的行为。 + PostgreSQL为很多类型提供了数学操作符。对于那些没有标准数学惯例的类型(如日期/时间类型),我们将在后续小节中描述实际的行为。 - 显示了可用于标准数字类型的数学操作符。 - 除非另有说明, 显示为可接受 numeric_type 的操作符对所有的 smallintintegerbigintnumericrealdouble precision类型都可用。 + 显示了可用于标准数值类型的数学操作符。 + 除非另有说明, 显示为可接受 numeric_type 的操作符对所有的 smallintintegerbigintnumericrealdouble precision类型都可用。 显示为可接受 integral_type 的操作符对 smallintintegerbigint类型是可用的。 除了特别说明之处,操作符的每种形式都返回与其参数相同的数据类型。 涉及多个参数数据类型的调用, 例如 integer + numeric,可通过使用这些列表中稍后出现的类型来解析。 @@ -821,7 +796,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in numeric_type - 一元加(无操作) + 一元正号(不执行操作) + 3.5 @@ -849,7 +824,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in numeric_type - 否定 + 取负 - (-4) @@ -877,7 +852,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in numeric_type - 除(对于整型,除法将结果截断为零) + 除法(对于整数类型,除法将结果向零截断) 5.0 / 2 @@ -917,14 +892,14 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in double precision - 指数 + 求幂 2 ^ 3 8 - 不像典型的数学实践,多次使用 ^ 将会默认从左到右关联: + 与通常的数学惯例不同,多次使用^时默认从左到右结合: 2 ^ 3 ^ 3 @@ -984,7 +959,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in integral_type - 按位与(AND) + 按位与 91 & 15 @@ -998,7 +973,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in integral_type - 按位或(OR) + 按位或 32 | 3 @@ -1012,7 +987,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in integral_type - 按位异或(exclusive OR) + 按位异或 17 # 5 @@ -1026,7 +1001,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in integral_type - 按位求反(NOT) + 按位非 ~1 @@ -1069,9 +1044,9 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in 显示了可用的数学函数。 许多这样的函数以多种具有不同的参数类型的形式提供。 - 除非注明,任何给定形式的函数都返回与其参数相同的数据类型;跨类型情况的解决方法与上述对操作符的解释相同。 - 使用double precision数据的函数大多是在主机系统的C库上实现的; - 因此,边界情况下的准确性和行为会因主机系统的区别而不同。 + 除非注明,任何给定形式的函数都返回与其参数相同的数据类型;跨类型情况的解决方法与上述对操作符的解释相同。 + 使用double precision数据的函数大多是在主机系统的C库上实现的; + 因此,精度和边界情况下的行为可能因主机系统而异。 @@ -1202,7 +1177,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in numeric - y/x 的整数商(截断为零位) + y/x 的整数商(向零截断) div(9, 4) @@ -1223,7 +1198,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in double precision - 指数 (e 的给定次方) + 指数函数(e的给定次幂) exp(1.0) @@ -1273,26 +1248,6 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in - - - - gamma - - gamma ( double precision ) - double precision - - - 伽马函数 - - - gamma(0.5) - 1.772453850905516 - - - gamma(6) - 120 - - @@ -1328,22 +1283,6 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in - - - - lgamma - - lgamma ( double precision ) - double precision - - - 伽马函数绝对值的自然对数 - - - lgamma(1000) - 5905.220423209181 - - @@ -1432,7 +1371,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in integer - 精确表示所提供值所需的最小刻度(小数位数) + 精确表示给定值所需的最少小数位数 min_scale(8.4100) @@ -1529,7 +1468,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in double precision - 四舍五入到最近的整数。 + 舍入到最接近的整数。 对于numeric,遇到恰好位于中点的情况时按远离零的方向舍入。 对于double precision,中点取舍规则取决于平台,但舍入到最接近的偶数是最常见的规则。 @@ -1566,7 +1505,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in integer - 参数的刻度(小数点后的位数) + 参数的小数位数(小数部分的十进制位数) scale(8.4100) @@ -1625,7 +1564,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in numeric - 通过删除尾数部分的零来降低值的刻度(小数位数) + 通过移除尾随零来减少值的小数位数 trim_scale(8.4100) @@ -1646,7 +1585,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in double precision - 截断整数 (向零靠近) + 向零截断为整数 trunc(42.8) @@ -1664,7 +1603,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in numeric - 截断 vs 位小数位置的数字 + 将v截断到s位小数 trunc(42.4382, 2) @@ -2090,7 +2029,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in - 另一种使用以角度度量的角的方法是使用早前展示的单位转换函数radians()degrees()。不过,使用基于角度的三角函数更好,因为这类方法能避免sind(30)等特殊情况下的舍入偏差。 + 另一种使用以角度度量的角的方法是使用早前展示的单位转换函数radians()degrees()。不过,使用基于角度的三角函数更好,因为这类方法能避免sind(30)等特殊情况下的舍入误差。 @@ -2163,7 +2102,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in double precision - 双曲切线 + 双曲正切 tanh(1) @@ -2214,7 +2153,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in double precision - 反双曲切线 + 反双曲正切 atanh(0.5) @@ -2236,7 +2175,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in 这里的字符串包括charactercharacter varyingtext类型的值。 除非另有说明,这些函数和操作符都声明为接受并返回text类型。 它们也可互换地接受character varying参数。 - 在应用函数或操作符之前,character类型的值会先转换为text,因此会去除其尾随空格。 + 在应用函数或操作符之前,character类型的值会先转换为text,因此会去除 character 值的尾随空格。 @@ -2247,7 +2186,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in 字符串串接操作符(||)将接受非字符串输入,只要至少一个输入是一种字符串类型,如所示。 - 对于其他情况,向text插入一个显式强制,可用于接受非字符串输入。 + 对于其他情况,可以添加到text的显式强制转换,以接受非字符串输入。 @@ -2275,14 +2214,14 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in - character string - concatenation + 字符串 + 串接 text || text text - 连接两个字符串。 + 串接两个字符串。 'Post' || 'greSQL' @@ -2300,8 +2239,8 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 将非字符串输入转换为文本,然后将两个字符串串联在一起。 - (非字符串输入不能为数组类型,因为这将在||操作符的数组中造成歧义。如果你想连接一个数组的文本相等的,请显式地将其转换为text 。) + 将非字符串输入转换为文本,然后将两个字符串串接起来。 + (非字符串输入不能是数组类型,因为那样会与数组的||操作符产生歧义。如果要串接数组的文本表示,请显式地将其转换为text。) 'Value: ' || 42 @@ -2312,17 +2251,17 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in - normalized + 规范化 - Unicode normalization + Unicode 规范化 text IS NOT form NORMALIZED boolean - 检查字符串是否在指定的 Unicode 规范化表单中。 - 可选的form关键词指定表单:NFC (默认的), NFD, NFKC, 或 NFKD。 + 检查字符串是否处于指定的 Unicode 规范化形式中。 + 可选的form关键字指定形式:NFC(默认)、NFDNFKCNFKD。 只有在服务器编码为UTF8时,才能使用此表达式。 请注意,使用这个表达式检查规范化通常比规范化可能已经规范化的字符串要快。 @@ -2355,13 +2294,13 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in char_length - character string - length + 字符串 + 长度 - length + 长度 字符串 - character string, length + 字符串,长度 char_length ( text ) integer @@ -2391,7 +2330,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 根据数据库的语言环境规则,将字符串转换为全部小写。 + 根据数据库的区域设置规则,将字符串转换为全部小写。 lower('TOM') @@ -2405,16 +2344,14 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in normalize - Unicode normalization + Unicode 规范化 normalize ( text , form ) text - 将字符串转换为指定的Unicode规范化形式。 - 可选的form关键字指定了如下形式:NFC (the default),NFDNFKC,或NFKD。 - 该函数只能在服务器编码为UTF8时使用。 + 将字符串转换为指定的 Unicode 规范化形式。可选的 form 关键字指定如下形式:NFC(默认值)、NFDNFKCNFKD。该函数只能在服务器编码为 UTF8 时使用。 normalize(U&'\0061\0308bc', NFC) @@ -2465,8 +2402,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 替换stringstart字符开始的子串,并用newsubstring扩展到count字符。 - 如果省略了count,则默认为newsubstring的长度。 + 用newsubstring替换string中从第start个字符开始、长度为count个字符的子字符串。如果省略count,则默认为newsubstring的长度。 overlay('Txxxxas' placing 'hom' from 2 for 4) @@ -2483,7 +2419,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in integer - 返回string中指定的substring的第一个起始索引,如果不存在则返回零,。 + 返回substringstring中首次出现的位置;如果不存在则返回零。 position('om' in 'Thomas') @@ -2500,9 +2436,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 如果已指定,提取stringstart字符开始的子串, - 并且在count字符后停止。如果已指定的话。 - 提供至少一个startcount中的至少一个。 + 提取string的子字符串:若指定了起始位置,则从第start个字符开始;若指定了长度,则在提取count个字符后停止。startcount至少需要指定一个。 substring('Thomas' from 2 for 3) @@ -2524,7 +2458,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 提取匹配POSIX正则表达式的第一个子字符串; 参见 。 + 提取匹配 POSIX 正则表达式的第一个子字符串;参见 substring('Thomas' from '...$') @@ -2542,8 +2476,8 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 提取匹配 SQL 正则表达式的第一个字串;参见 。 - 第一种形式自从SQL:2003被指定,第二种形式仅在SQL:1999中,并应认为是废弃的。 + 提取匹配 SQL 正则表达式的第一个子字符串;参见 。 + 第一种形式自 SQL:2003 起由标准规定;第二种形式只出现在 SQL:1999 中,应视为已过时。 substring('Thomas' similar '%#"o_a#"_' escape '#') @@ -2595,7 +2529,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 根据数据库的定位规则,将字符串转换为所有大写。 + 根据数据库的区域设置规则,将字符串转换为全部大写。 upper('tom') @@ -2662,7 +2596,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in integer - 返回参数的第一个字符的数字代码。在UTF8编码中,返回该字符的Unicode代码点。 + 返回参数的第一个字符的数字代码。在UTF8编码中,返回该字符的Unicode 码点。 在其他多字节编码中,该参数必须是一个ASCII字符。 @@ -2671,6 +2605,8 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in + + @@ -2681,7 +2617,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 从string的开头或结尾删除最长的只包含characters(默认是一个空格)的字符串 + 从string的开头和结尾移除仅由characters中字符(默认为空格)组成的最长字符串。 btrim('xyxtrimyyx', 'xyz') @@ -2698,7 +2634,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 返回给定代码的字符。在UTF8编码中该参数被视作一个Unicode代码点。 + 返回给定代码的字符。在UTF8编码中该参数被视作一个Unicode 码点。 在其他多字节编码中该参数必须指定一个ASCII字符。 chr(0) 字符不被允许,因为文本数据类型不能存储这种字符。 @@ -2718,7 +2654,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 连接所有参数的文本表示。空参数被忽略。 + 串接所有参数的文本表示。NULL 参数被忽略。 concat('abcde', 2, NULL, 22) @@ -2737,7 +2673,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 用分隔符连接除第一个参数外的所有参数。第一个参数用作分隔符字符串,不应为NULL。其他NULL参数将被忽略。 + 用分隔符串接除第一个参数外的所有参数。第一个参数用作分隔符字符串,不应为NULL。其他NULL参数将被忽略。 concat_ws(',', 'abcde', 2, NULL, 22) @@ -2791,7 +2727,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 以字符串返回第一个 n 字符,或在 n 为负时, 返回最后 |n| 个字符之外的全部字符。 + 返回字符串最左侧的 n 个字符;如果 n 为负,则返回除最后 |n| 个字符之外的全部字符。 left('abcde', 2) @@ -2816,6 +2752,8 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in + + @@ -2827,8 +2765,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 将string扩展为长度length,通过前置字符fill(默认空格)。 - 如果string已经超过length那么它将被截断(在右侧)。 + 在string前面添加字符fill(默认为空格),将其填充到长度length。如果string已经长于length,则从右侧截断。 lpad('hi', 5, 'xy') @@ -2836,6 +2773,8 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in + + @@ -2846,7 +2785,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 从string开始删除包含characters(默认空格)中仅包含字符的最长字符串。 + 从string的开头移除仅由characters中字符(默认为空格)组成的最长字符串。 ltrim('zzzytest', 'xyz') @@ -2881,10 +2820,10 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text[] - 将qualified_identifier拆分为一个标识符数组,删除单个标识符的任何引用。 + 将qualified_identifier拆分为一个标识符数组,去除各个标识符的引号。 默认情况下,最后一个标识符之后的额外字符被视为错误;但是,如果第二个参数为false,则忽略这些额外的字符。 (这种行为对于解析类似函数的对象的名称有作用。) - 请注意,此函数不会截断超长标识符。如果你想截断,你可以把结果给到name[]。 + 请注意,此函数不会截断超长标识符。如果你想截断,你可以将结果转换为name[] parse_ident('"SomeSchema".someTable') @@ -2918,9 +2857,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 返回适合引用的给定字符串,作为SQL语句字符串中的标识符。 - 只有在必要的情况下才添加引号(例如,如果字符串包含非标识符字符或将被大小写折叠)。 - 嵌入的引号被适当地加双引号。参见。 + 为给定字符串添加适当的引号并返回,使其可用作SQL语句字符串中的标识符。仅在必要时(即字符串包含不能用于标识符的字符,或会发生大小写折叠时)添加引号。内嵌的引号会被适当地双写。另见 quote_ident('Foo bar') @@ -2937,9 +2874,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 返回在SQL语句字符串中适当引用的给定字符串,用作字符串文字使用。 - 嵌入式单引号和反斜线适当的翻倍(转双引号或双斜线)。 - 请注意,quote_literal在参数为 null 时返回 null;如果这个参数可能为空,quote_nullable通常更合适。另请参阅。 + 为给定字符串添加适当的引号并返回,使其可用作SQL语句字符串中的字符串字面量。内嵌的单引号和反斜杠会被适当地双写。注意,quote_literal在输入为 null 时返回 null;如果参数可能为 null,quote_nullable通常更合适。另见 quote_literal(E'O\'Reilly') @@ -2953,8 +2888,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 将给定的值转换为文本,然后将其作为字面量引用。 - 内嵌的单引号和反斜杠被适当地翻倍。 + 将给定值转换为文本,然后作为字面量加引号。内嵌的单引号和反斜杠会被适当地双写。 quote_literal(42.5) @@ -2971,8 +2905,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 返回在SQL语句字符串中适当引用的给定字符串文字;或者,如果参数为null,则返回NULL。 - 内嵌的单引号和反斜杠被适当地翻倍。参见。 + 为给定字符串添加适当的引号并返回,使其可用作SQL语句字符串中的字符串字面量;如果参数为 null,则返回NULL。内嵌的单引号和反斜杠会被适当地双写。另见 quote_nullable(NULL) @@ -2986,8 +2919,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 将给定值转换为文本,然后将其作为字面量引用;或者,如果参数为null,则返回NULL。 - 内嵌的单引号和反斜杠被适当地翻倍。 + 将给定值转换为文本,然后作为字面量加引号;如果参数为 null,则返回NULL。内嵌的单引号和反斜杠会被适当地双写。 quote_nullable(42.5) @@ -3028,7 +2960,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in integer - 返回string中第N个匹配项的POSIX正则表达式pattern出现的位置,如果没有这样的匹配项,则返回零;参见。 + 返回 POSIX 正则表达式patternstring中第N次匹配的位置;如果没有这样的匹配,则返回零。参见 regexp_instr('ABCDEF', 'c(.)(..)', 1, 1, 0, 'i') @@ -3067,7 +2999,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text[] - 返回第一个匹配的POSIX正则表达式patternstring中的子字符串;参见。 + 返回 POSIX 正则表达式patternstring的第一次匹配中的子字符串;参见 regexp_match('foobarbequebaz', '(bar)(beque)') @@ -3084,8 +3016,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in setof text[] - 返回第一个匹配的 POSIX 正则表达式patternstring中的子字符串,或者如果使用了g标志,则返回所有匹配的子字符串; - 参见。 + 返回 POSIX 正则表达式patternstring的第一次匹配中的子字符串;如果使用g标志,则返回所有匹配中的子字符串。参见 regexp_matches('foobarbequebaz', 'ba.', 'g') @@ -3125,7 +3056,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 替换字符串中第N个与 POSIX 正则表达式pattern匹配的子字符串,如果N为零,则替换所有匹配项;参见。 + 替换第N个与 POSIX 正则表达式pattern匹配的子字符串;如果N为零,则替换所有这样的匹配。参见 regexp_replace('Thomas', '.', 'X', 3, 2) @@ -3184,8 +3115,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 返回string中与第N个出现的POSIX正则表达式pattern匹配的子字符串, - 如果没有这样的匹配,则返回NULL;参见。 + 返回string中 POSIX 正则表达式pattern的第N次匹配对应的子字符串;如果没有这样的匹配,则返回NULL。参见 regexp_substr('ABCDEF', 'c(.)(..)', 1, 1, 'i') @@ -3225,7 +3155,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 将string 中当前的子串from替换为子串to。 + 将string中所有出现的子字符串from替换为子字符串to replace('abcdefabcdef', 'cd', 'XX') @@ -3260,7 +3190,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 返回字符串中的最后n个字符,或者在n>为负时,返回除了前面的|n|字符之外的所有字符。 + 返回字符串中的最后n个字符;如果n为负数,则返回除前 |n| 个字符之外的全部字符。 right('abcde', 2) @@ -3268,6 +3198,8 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in + + @@ -3279,8 +3211,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 扩展 string 到长度 length,通过追加fill 字符(默认为空格). - 如果string 已经比 length 长,则截断它。 + 在string后面追加字符fill(默认为空格),将其填充到长度length。如果string已经长于length,则截断它。 rpad('hi', 5, 'xy') @@ -3288,6 +3219,8 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in + + @@ -3298,7 +3231,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 从string末尾删除包含characters(默认为空格)中仅包含字符的最长字符串。 + 从string的结尾移除仅由characters中字符(默认为空格)组成的最长字符串。 rtrim('testxxzx', 'xyz') @@ -3317,7 +3250,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 在delimiter出现时拆分string,并且返回第n个字段(从一计数),或者当n为负数时,返回|n|'th-from-last 字段。 + 在出现delimiter时拆分string,并返回第n个字段(从一开始计数);如果n为负数,则返回倒数第 |n| 个字段。 split_part('abc~@~def~@~ghi', '~@~', 2) @@ -3401,8 +3334,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in integer - 返回在string中指定的substring的第一个起始索引,如果不存在则为零。 - (与(substringstring中的)位置相同,但是请注意反转的参数顺序) + 返回substringstring中首次出现的位置;如果不存在则返回零。(与position(substring in string)相同,但请注意参数顺序相反。) strpos('high', 'ig') @@ -3419,8 +3351,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 提取stringstart字符开始的子字符串,并扩展count字符,如果指定了的话。 - (与 子字符串(stringstart 开始计数 count)相同。) + 提取string中从第start个字符开始的子字符串;若指定了长度,则提取count个字符。(与substring(string from start for count)相同。) substr('alphabet', 3) @@ -3451,10 +3382,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 将string从另一个编码中转换为ASCII,该编码可按名称或编号标识。 - 如果encoding被省略,则假定数据库编码(这在实践中是唯一有用的案例)。转换主要包括降音。 - 转换仅支持来自 LATIN1LATIN2LATIN9、 和 WIN1250 的编码. - (其他请参见 模块, 更灵活的解决方案。) + 将string从其他编码转换为ASCII,源编码可以用名称或编号指定。如果省略encoding,则使用数据库编码(实际上,这也是唯一有用的情况)。转换主要是去除重音符号。只支持从LATIN1LATIN2LATIN9WIN1250编码转换。(另一种更灵活的解决方案参见模块。) to_ascii('Karél') @@ -3495,7 +3423,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in string中与from集合中匹配的每个字符替换为to集合中相应的字符。 - 如果from长于tofrom中出现的额外字符被删除。 + 如果from长于to,输入中出现的from中的额外字符会被删除。 translate('12345', '143', 'ax') @@ -3512,18 +3440,18 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 计算参数中的转义Unicode字符。 + 解析参数中转义的 Unicode 字符。 Unicode字符可以被指定为\XXXX (4个十六进制数字),\+XXXXXX(6个十六进制数字),\uXXXX(4个十六进制数字),或\UXXXXXXXX (8个十六进制数字)。 要指定反斜杠,请写入两个反斜杠。 - 所有其他字符都是按字面意义的。 + 所有其他字符均按字面解释。 - 如果服务器编码不是UTF-8,由这些转义序列之一标识的Unicode编码点将被转换为实际的服务器编码;如果不可能,则会报告错误。 + 如果服务器编码不是 UTF-8,由这些转义序列之一标识的 Unicode 码点将被转换为实际的服务器编码;如果无法转换,则会报告错误。 - 这个函数提供了一个(非标准的)替代到Unicode转义的字符串常量(参见)。 + 此函数提供了带 Unicode 转义的字符串常量的另一种(非标准)写法(参见)。 @@ -3541,12 +3469,12 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in
- concatconcat_wsformat函数是可变的,因此可以把要串接或格式化的值作为一个标记了VARIADIC关键字的数组进行传递(见)。 - 数组的元素被当作函数的独立普通参数一样处理。如果可变数组参数为 NULL,concatconcat_ws返回 NULL,但format把 NULL 当作一个零元素数组。 + concatconcat_wsformat是可变参数函数,因此可以把要串接或格式化的值作为一个标记了VARIADIC关键字的数组进行传递(见)。 + 数组的元素被当作函数的独立普通参数一样处理。如果可变参数数组为 NULL,concatconcat_ws返回 NULL,但format把 NULL 当作一个零元素数组。 - 还可以参阅中的string_agg,以及中的字符串和bytea类型之间转换的功能。 + 还可以参阅中的聚合函数string_agg,以及中的字符串和bytea类型之间转换的函数。 @@ -3564,22 +3492,22 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in format(formatstr text [, formatarg "any" [, ...] ]) - formatstr是一个格式字符串,它指定了结果应该如何被格式化。格式字符串中的文本被直接复制到结果中,除了使用格式说明符的地方。格式说明符在字符串中扮演着占位符的角色,它定义后续的函数参数如何被格式化及插入到结果中。每一个formatarg参数会被根据其数据类型的常规输出规则转换为文本,并接着根据格式说明符被格式化和插入到结果字符串中。 + formatstr是指定结果格式的字符串。格式字符串中的文本会直接复制到结果中,但格式说明符所在的位置除外。格式说明符充当字符串中的占位符,定义如何格式化后续函数参数并将其插入结果。每个formatarg参数都按照其数据类型通常的输出规则转换为文本,再根据格式说明符进行格式化并插入结果字符串。
- 格式说明符由一个%字符开始并且有这样的形式 + 格式说明符以%字符开头,格式如下: %[position][flags][width]type - 其中的各组件域是: + 其中各组成字段为: position(可选) - 一个形式为n$的字符串,其中n是要打印的参数的索引。索引 1 表示formatstr之后的第一个参数。如果position被忽略,默认会使用序列中的下一个参数。 + 一个形式为n$的字符串,其中n是要打印的参数的索引。索引 1 表示formatstr之后的第一个参数。如果position被省略,默认会使用序列中的下一个参数。 @@ -3587,9 +3515,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in flags(可选) - - 控制格式说明符的输出如何被格式化的附加选项。当前唯一支持的标志是一个负号(-),它将导致格式说明符的输出会被左对齐(left-justified)。除非width域也被指定,否者这个域不会产生任何效果。 - + 用于控制格式说明符输出格式的附加选项。目前唯一支持的标志是减号(-),它使格式说明符的输出左对齐。只有同时指定了width字段时,它才有效。 @@ -3601,8 +3527,8 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in - 如果宽度来自于一个函数参数,则参数在被格式说明符的值使用之前就被消耗掉了。如果宽度参数是负值,结果会在长度为abs(width)的域中被左对齐(如果-标志被指定)。 - + 如果宽度来自一个函数参数,会先使用该宽度参数,再使用作为格式说明符值的参数。如果宽度参数为负数,结果会在长度为abs(width)的字段中左对齐(如同指定了-标志)。 +
@@ -3619,12 +3545,12 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in - I将参数值视作 SQL 标识符,并在必要时用双写引号包围它。如果参数为空,将会是一个错误(等效于quote_ident)。 + I将参数值视作 SQL 标识符,并在必要时用双引号包围它。如果参数为 null,则会报错(等效于quote_ident)。 - L将参数值引用为 SQL 文字。一个空值将被显示为不带引号的字符串NULL(等效于quote_nullable)。 + L将参数值作为 SQL 字面量加引号。null 值显示为不带引号的字符串NULL(等效于quote_nullable)。 @@ -3635,13 +3561,10 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in
- 除了以上所述的格式说明符之外,要输出一个文字形式的%字符,可以使用特殊序列%%。 + 除了以上所述的格式说明符之外,要输出一个字面形式的%字符,可以使用特殊序列%% - - 下面有一些基本的格式转换的示例: - - + 下面是一些基本格式转换的示例: SELECT format('Hello %s', 'World'); 结果:Hello World @@ -3652,14 +3575,11 @@ SELECT format('INSERT INTO %I VALUES(%L)', 'Foo bar', E'O\'Reilly'); 结果:INSERT INTO "Foo bar" VALUES('O''Reilly') SELECT format('INSERT INTO %I VALUES(%L)', 'locations', 'C:\Program Files'); -结果:INSERT INTO locations VALUES(E'C:\\Program Files') +结果:INSERT INTO locations VALUES('C:\Program Files') - - 下面是使用width域和-标志的示例: - - + 下面是使用width字段和-标志的示例: SELECT format('|%10s|', 'foo'); 结果:| foo| @@ -3680,10 +3600,7 @@ SELECT format('|%-*s|', -10, 'foo'); - - 这些示例展示了position域的示例: - - + 这些示例展示了如何使用position字段: SELECT format('Testing %3$s, %2$s, %1$s', 'one', 'two', 'three'); 结果:Testing three, two, one @@ -3695,10 +3612,8 @@ SELECT format('|%1$*2$s|', 'foo', 10, 'bar'); - - 不同于标准的 C 函数sprintfPostgreSQLformat函数允许将带有或者不带有position域的格式说明符被混在同一个格式字符串中。一个不带有position域的格式说明符总是使用最后一个被消耗的参数的下一个参数。另外,format函数不要求所有函数参数都被用在格式字符串中。例如: - - + 不同于标准 C 函数sprintf, + PostgreSQLformat函数允许在同一个格式字符串中,混合使用带有或不带有position字段的格式说明符。不带position字段的格式说明符,总是使用最后一个已使用参数之后的下一个参数。此外,format函数不要求格式字符串使用全部函数参数。例如: SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); 结果:Testing three, two, three @@ -3716,17 +3631,17 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); 二进制串函数和操作符 - binary data - functions + 二进制数据 + 函数 - 本节描述那些检查和操作二进制字符串的函数和操作符,这是类型bytea的值。 + 本节描述用于检查和操作二进制字符串(即bytea类型的值)的函数和操作符。 其中许多函数在用途和语法上都与上一节中描述的文本字符串函数等效。 - SQL定义了一些使用关键字而不是逗号来分割参数的串函数。详情请见PostgreSQL也提供了这些函数使用常规函数调用语法的版本(参阅)。 + SQL定义了一些使用关键字而不是逗号来分隔参数的字符串函数。详情请见PostgreSQL也提供了这些函数使用常规函数调用语法的版本(参阅)。 @@ -3753,14 +3668,14 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); - binary string - concatenation + 二进制串 + 串接 bytea || bytea bytea - 连接两个二进制字符串。 + 串接两个二进制字符串。 '\x123456'::bytea || '\x789a00bcde'::bytea @@ -3811,8 +3726,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bytea - 将bytes的子字符串替换为newsubstring,该子字符串从start字节开始,并以count字节扩展。 - 如果忽略了count,则默认为newsubstring的长度。 + 用newsubstring替换bytes中从第start个字节开始、长度为count个字节的子字符串。如果省略count,则默认为newsubstring的长度。 overlay('\x1234567890'::bytea placing '\002\003'::bytea from 2 for 3) @@ -3829,7 +3743,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); integer - 返回bytes中指定的substring的第一个起始索引,如果不存在,则为零。 + 返回substringbytes中首次出现的位置;如果不存在则返回零。 position('\x5678'::bytea in '\x1234567890'::bytea) @@ -3846,8 +3760,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bytea - 提取bytesstart字节开始的子字符串,如果指定了,并且在count字节之后停止,如果指定了的话。 - 至少提供startcount中的一个。 + 提取bytes的子字符串:若指定了起始位置,则从第start个字节开始;若指定了长度,则在提取count个字节后停止。startcount至少需要指定一个。 substring('\x1234567890'::bytea from 3 for 2) @@ -3866,7 +3779,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bytea - 删除bytesremoved中只包含字节的最长字符串,从bytes的开始、结束,或两端(BOTH 为默认的)。 + 从bytes的开头、结尾或两端(默认为BOTH)移除仅由bytesremoved中字节组成的最长字符串。 trim('\x9012'::bytea from '\x1234567890'::bytea) @@ -3882,7 +3795,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bytea - 这是trim()的非标准语法。 + 这是一个非标准的trim()语法。 trim(both from '\x1234567890'::bytea, '\x9012'::bytea) @@ -3894,7 +3807,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three');
- 还有一些二进制串处理函数可以使用,在列出。 其中有一些是在内部使用,用于实现列出的 SQL 标准串函数。 + 还有一些二进制串处理函数可以使用,在列出。 其中有一些是在内部使用,用于实现列出的 SQL 标准串函数。 @@ -3931,7 +3844,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bigint - 返回二进制字符串中设置的位数(也被认为popcount)。 + 返回二进制字符串中被置位的位数(也称为popcount)。 bit_count('\x1234567890'::bytea) @@ -3939,6 +3852,8 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); + + @@ -3949,7 +3864,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bytea - 从bytes的开始和结束处删除只包含bytesremoved中出现的字节的最长字符串 + 从bytes的开头和结尾移除仅由bytesremoved中字节组成的最长字符串。 btrim('\x1234567890'::bytea, '\x9012'::bytea) @@ -3967,7 +3882,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); integer - 从二进制字符串中提取 n'th 位。 + 从二进制字符串中提取 编号为 n 的 位。 get_bit('\x1234567890'::bytea, 30) @@ -3985,7 +3900,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); integer - 从二进制字符串中提取 n'th 字节。 + 从二进制字符串中提取 编号为 n 的 字节。 get_byte('\x1234567890'::bytea, 4) @@ -3999,13 +3914,13 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); length - binary string - length + 二进制串 + 长度 - length - 二进制字符串 - binary strings, length + 长度 + 二进制串 + 二进制串,长度 length ( bytea ) integer @@ -4034,6 +3949,8 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); + + @@ -4044,8 +3961,8 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bytea - 从bytes开头移除出现在bytesremoved中的只包含字节的最长字符串。 - + 从bytes的开头移除仅由bytesremoved中字节组成的最长字符串。 + ltrim('\x1234567890'::bytea, '\x9012'::bytea) \x34567890 @@ -4069,6 +3986,8 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); + + @@ -4079,8 +3998,8 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bytea - 从bytes结尾移除出现在bytesremoved中的只包含字节的最长字符串。 - + 从bytes的结尾移除仅由bytesremoved中字节组成的最长字符串。 + rtrim('\x1234567890'::bytea, '\x9012'::bytea) \x12345678 @@ -4098,7 +4017,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bytea - 设置二进制字符串中的n'th位为newvalue。 + 设置二进制字符串中的编号为 n 的位为newvalue set_bit('\x1234567890'::bytea, 30, 0) @@ -4117,7 +4036,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bytea - 设置二进制字符串中的 n'th 字节到 newvalue。 + 设置二进制字符串中的 编号为 n 的 字节到 newvalue set_byte('\x1234567890'::bytea, 4, 64) @@ -4172,7 +4091,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); sha384('abc'::bytea) - \xcb00753f45a35e8bb5a03d699ac65007&zwsp;272c32ab0ed1631a8b605a43ff5bed&zwsp;8086072ba1e7cc2358baeca134c825a7 + \xcb00753f45a35e8bb5a03d699ac65007&zwsp;272c32ab0eded1631a8b605a43ff5bed&zwsp;8086072ba1e7cc2358baeca134c825a7 @@ -4189,7 +4108,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); sha512('abc'::bytea) - \xddaf35a193617abacc417349ae204131&zwsp;12e6fa4e89a97ea20a9ee64b55d39a&zwsp;2192992a274fc1a836ba3c23a3feebbd&zwsp;454d4423643ce80e2a9ac94fa54ca49f + \xddaf35a193617abacc417349ae204131&zwsp;12e6fa4e89a97ea20a9eeee64b55d39a&zwsp;2192992a274fc1a836ba3c23a3feebbd&zwsp;454d4423643ce80e2a9ac94fa54ca49f @@ -4202,8 +4121,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bytea - 从start字节开始提取bytes的子字符串,并扩展为count字节,如果这是指定的。 - (与 substring(bytesstartcount) 相同.) + 提取bytes中从第start个字节开始的子字符串;若指定了长度,则提取count个字节。(与substring(bytes from start for count)相同。) substr('\x1234567890'::bytea, 3, 2) @@ -4215,7 +4133,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three');
- 函数get_byteset_byte把一个二进制串中的一个字节计数为字节 0。 + 函数get_byteset_byte把二进制串中的第一个字节编号为字节 0。 函数get_bitset_bit在每一个字节中从右边起计数位; 例如位 0 是第一个字节的最低有效位,而位 15 是第二个字节的最高有效位。 @@ -4223,16 +4141,16 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); 由于历史原因,函数md5返回的是一个十六进制编码的text值,而SHA-2函数返回类型bytea。 可以使用函数encodedecode在两者之间转换。 - 例如encode(sha256('abc'),'hex')可以得到一个十六进制编码的文本表示,或者decode(md5('abc'), 'hex')得到一个bytea 值。 + 例如encode(sha256('abc'), 'hex')可以得到一个十六进制编码的文本表示,或者decode(md5('abc'), 'hex')得到一个bytea 值。 - character string + 字符串 转换为二进制字符串 - binary string + 二进制串 转换为字符串 用于在不同字符集(编码)之间转换字符串的函数,以及用于以文本形式表示任意二进制数据的函数,在中显示。 @@ -4241,7 +4159,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); - 文本/字符串转换函数 + 文本/二进制串转换函数 @@ -4349,7 +4267,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bytea - 从文本表示中解码二进制数据;支持的format值与encode相同。 + 从文本表示中解码二进制数据;支持的format值与encode相同。 decode('MTIzAAE=', 'base64') @@ -4373,9 +4291,9 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); base64格式是RFC 2045第6.8节中描述的。根据RFC,编码行在76个字符处换行。 - 然而,与MIME CRLF换行符不同,结尾只使用换行符。 + 然而,与MIME CRLF换行符不同,行尾只使用一个换行符。 decode函数会忽略回车、换行、空格和制表符。 - 否则,当decode提供无效的base64数据时,包括尾部填充不正确时,会引发错误。 + 否则,当向decode传入无效的 base64 数据时,包括尾部填充不正确时,会引发错误。 @@ -4387,8 +4305,8 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); - escape格式将零字节和高位设置的字节转换为八进制转义序列 - (\nnn),并将反斜杠加倍。 + escape格式将零字节和最高位被置位的字节转换为八进制转义序列 + (\nnn),并将反斜杠双写。 其他字节值会直接表示。如果反斜杠后面不是第二个反斜杠或三个八进制数字,则decode函数会引发错误; 它会接受其他字节值不变。 @@ -4403,10 +4321,10 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); hex格式将每4位数据表示为一个十六进制数字,0f, - 先写入每个字节的高阶数字。 encode函数以小写输出a-f十六进制数字。 + 先写入每个字节的高位数字。 encode函数以小写输出a-f十六进制数字。 因为数据的最小单位是8位,所以encode总是返回偶数个字符。 decode函数接受a-f字符的大小写。 - 当decode提供无效的十六进制数据时,包括提供奇数个字符时,会引发错误。 + 当向decode传入无效的十六进制数据时,包括提供奇数个字符时,会引发错误。 @@ -4423,14 +4341,14 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); 位串函数和操作符 - bit strings - functions + 位串 + 函数 本节描述用于检查和操作位串的函数和操作符,也就是操作类型为bitbit varying的值的函数和操作符。 - (虽然这些表中只提到了bit类型,但bit varying类型的值可以互换使用。) - 位字符串支持中显示的常用比较操作符,就像中显示的操作符。 + (虽然这些表中只提到了bit类型,但bit varying类型的值可以互换使用。) + 位串支持中显示的常用比较操作符,以及中显示的操作符。
@@ -4460,7 +4378,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bit - 连接 + 串接 B'10001' || B'011' @@ -4516,7 +4434,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bit - 按位求反 + 按位非 ~ B'10001' @@ -4556,12 +4474,12 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three');
- 一些可用于二进制字符串的函数也可用于位字符串,如中所示。 + 一些可用于二进制字符串的函数也可用于位串,如中所示。 - 位字符串函数 + 位串函数 @@ -4589,7 +4507,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bigint - 返回位字符串中设置的位数(也被视为popcount)。 + 返回位串中被置位的位数(也称为popcount)。 bit_count(B'10111') @@ -4606,7 +4524,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); integer - 返回位字符串中的位数。 + 返回位串中的位数。 bit_length(B'10111') @@ -4620,14 +4538,14 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); length - bit string - length + 位串 + 长度 length ( bit ) integer - 返回位字符串中的位数。 + 返回位串中的位数。 length(B'10111') @@ -4644,7 +4562,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); integer - 返回位字符串中的字节数。 + 返回位串中的字节数。 octet_length(B'1011111011') @@ -4661,8 +4579,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bit - 替换从start位开始的bits的子字符串,并将newsubstring扩展count位。 - 如果count被省略,默认为newsubstring的长度。 + 用newsubstring替换bits中从第start位开始、长度为count位的子串。如果省略count,则默认为newsubstring的长度。 overlay(B'01010101010101010' placing B'11111' from 2 for 3) @@ -4679,7 +4596,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); integer - 按返回指定substring的第一个起始索引,以bits为单位,如果不存在则返回0。 + 返回substringbits中首次出现的位置;如果不存在则返回零。 position(B'010' in B'000001101011') @@ -4696,8 +4613,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bit - 如果指定了起始位,则提取从start位开始的bits的子字符串,如果指定了计数位,则在count位之后停止。 - startcount至少提供一个。 + 提取bits的子串:若指定了起始位置,则从第start位开始;若指定了长度,则在提取count位后停止。startcount至少需要指定一个。 substring(B'110010111111' from 3 for 2) @@ -4715,7 +4631,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); integer - 从位字符串中提取第n位;第一个(最左)位为第0位。 + 从位串中提取编号为n的位;第一位(最左侧的位)编号为位 0。 get_bit(B'101010101010101010', 6) @@ -4734,7 +4650,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bit - 将位字符串中的第n位设置为newvalue;第一个(最左)位是第0位。 + 将位串中编号为n的位设置为newvalue;第一位(最左侧的位)编号为位 0。 set_bit(B'101010101010101010', 6, 0) @@ -4745,18 +4661,12 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three');
- - 另外,我们可以在整数和bit之间来回转换。 - 将一个整数转换为bit(n)会复制最右边的n位。 - 将一个整数转换为比整数本身更宽的位字符串宽度将在左边进行符号扩展。一些示例: - + 此外,还可以在整数值与bit类型之间进行类型转换。将整数转换为bit(n)会复制最右侧的n位。将整数转换为宽度超过该整数自身位宽的位串时,会在左侧进行符号扩展。下面是一些示例: 44::bit(10) 0000101100 44::bit(3) 100 cast(-44 as bit(12)) 111111010100 '1110'::bit(4)::integer 14 - - 请注意,如果只是转换为bit,意思是转换成bit(1),因此只会转换整数的最低有效位。 - +注意,仅转换为bit意味着转换为bit(1),因此只会得到该整数的最低有效位。 @@ -4764,11 +4674,11 @@ cast(-44 as bit(12)) 111111010100 模式匹配 - pattern matching + 模式匹配 - PostgreSQL提供了三种独立的实现模式匹配的方法:SQL LIKE操作符、更近一些的SIMILAR TO操作符(SQL:1999 里添加进来的)和POSIX-风格的正则表达式。除了这些基本的这个串匹配这个模式吗?操作符外,还有一些函数可用于提取或替换匹配子串并在匹配位置分离一个串。 + PostgreSQL提供了三种独立的模式匹配方法:传统的SQL LIKE操作符、较新的SIMILAR TO操作符(在 SQL:1999 中加入),以及POSIX风格的正则表达式。除了用于判断这个字符串是否匹配这个模式?的基本操作符外,还提供了提取或替换匹配子字符串、在匹配位置分割字符串的函数。 @@ -4781,25 +4691,20 @@ cast(-44 as bit(12)) 111111010100 - 虽然大部分的正则表达式搜索都能被很快地执行,但是正则表达式仍可能被 - 人为地弄成需要任意长的时间和任意量的内存进行处理。要当心从不怀好意 - 的来源接受正则表达式搜索模式。如果必须这样做,建议加上语句超时限制。 + 虽然大多数正则表达式搜索都能很快完成,但特意构造的正则表达式可能需要任意长的处理时间和任意多的内存。接受来自恶意来源的正则表达式搜索模式时应当谨慎。如果必须这样做,建议设置语句超时。 - 使用SIMILAR TO模式的搜索具有同样的安全性危险, - 因为SIMILAR TO提供了很多和 - POSIX-风格正则表达式相同的能力。 + 使用SIMILAR TO模式进行搜索具有同样的安全风险,因为SIMILAR TO提供了许多与POSIX风格正则表达式相同的能力。 - LIKE搜索比其他两种选项简单得多,因此在使用 - 不怀好意的模式来源时要更安全些。 + LIKE搜索比另外两种方法简单得多,因此,当模式可能来自恶意来源时,使用它更安全。 - SIMILAR TOPOSIX-风格正则表达式不支持非确定性排序规则。如果需要的话,可以使用LIKE或在表达式中应用不同的排序规则来绕过这个限制。 + 这三种模式匹配操作符都不支持非确定性排序规则。如有需要,可以对表达式应用不同的排序规则来绕过这一限制。 @@ -4819,7 +4724,11 @@ cast(-44 as bit(12)) 111111010100
- 如果pattern不包含百分号或者下划线,那么该模式只代表它本身的串;这时候LIKE的行为就象等号操作符。在pattern里的下划线 (_)代表(匹配)任何单个字符; 而一个百分号(%)匹配任何零或更多个字符的序列。 + 如果pattern不包含百分号或下划线,那么该模式只表示它 + 本身的字符串;在这种情况下,LIKE的行为就像等号操作符。 + pattern中的下划线(_)代表 + (匹配)任意单个字符;百分号(%)匹配任意由零个或多个 + 字符组成的序列。 @@ -4833,23 +4742,26 @@ cast(-44 as bit(12)) 111111010100 - LIKE模式匹配总是覆盖整个串。因此,要匹配在串内任何位置的序列,该模式必须以百分号开头和结尾。 + LIKE模式匹配总是覆盖整个字符串。因此,如果想要匹配字符串内 + 任意位置上的一个序列,该模式就必须以百分号开头并以百分号结尾。 - 要匹配文本的下划线或者百分号,而不是匹配其它字符, 在pattern里相应的字符必须 前导转义字符。缺省的转义字符是反斜线,但是你可以用ESCAPE子句指定一个不同的转义字符。 要匹配转义字符本身,写两个转义字符。 + 要匹配字面量下划线或百分号而不是把它们当作通配符, + pattern中相应的字符前面必须带有转义字符。 + 默认的转义字符是反斜线,但也可以使用ESCAPE子句选择其他 + 转义字符。要匹配转义字符本身,请写两个转义字符。 - 如果你关掉了,你在文串常量中写的任何反斜线都需要被双写。详见。 + 如果你关掉了,你在字符串常量中写的任何反斜线都需要被双写。详见 - 请注意反斜线在串文本里已经有特殊含义了,所以如果你写一个 包含反斜线的模式常量,那你就要在 SQL 语句里写两个反斜线。 因此,写一个匹配单个反斜线的模式实际上要在语句里写四个反斜线。 你可以通过用 ESCAPE 选择一个不同的转义字符 来避免这样;这样反斜线就不再是 LIKE 的特殊字符了。 但仍然是字符文本分析器的特殊字符,所以你还是需要两个反斜线。) - 我们也可以通过写ESCAPE ''的方式不选择转义字符,这样可以有效地禁用转义机制,但是没有办法关闭下划线和百分号在模式中的特殊含义。 + 也可以通过写 ESCAPE '' 来选择不使用转义字符。这会禁用转义机制,从而无法关闭模式中下划线和百分号的特殊含义。 @@ -4858,7 +4770,7 @@ cast(-44 as bit(12)) 111111010100 - 关键字ILIKE可以用于替换LIKE,它令该匹配根据活动区域成为大小写无关。(但这不支持非确定性排序规则。)这个不属于SQL标准而是一个PostgreSQL扩展。 + 可以用关键字 ILIKE 代替 LIKE,使匹配根据当前区域设置忽略大小写。这不属于 SQL 标准,而是 PostgreSQL 的扩展。 @@ -4869,14 +4781,11 @@ cast(-44 as bit(12)) 111111010100 - 短语LIKEILIKENOT LIKE,和 NOT ILIKEPostgreSQL语法中通常被视为操作符; - 例如,它们可以用于expression operator的任何(subquery)构造,尽管这里不能包含ESCAPE子句。 - 在某些晦涩难懂的情况下,可能需要用底层操作符名称替代。 + 在 PostgreSQL 语法中,LIKEILIKENOT LIKENOT ILIKE 通常被当作操作符;例如,它们可以用于 expression operator ANY (subquery) 构造,但其中不能包含 ESCAPE 子句。在某些不常见的情况下,可能需要改用底层操作符名称。 - 另请参阅以^@开头的操作符和相应的starts_with()函数, - 在需要简单匹配字符串开头的情况下非常有用。 + 另请参见用于匹配字符串开头的操作符 ^@ 和相应的 starts_with() 函数,它们适用于只需匹配字符串开头的情况。 @@ -4885,8 +4794,8 @@ cast(-44 as bit(12)) 111111010100 <function>SIMILAR TO</function>正则表达式 - regular expression - + 正则表达式 + @@ -4903,13 +4812,11 @@ cast(-44 as bit(12)) 111111010100 - SIMILAR TO操作符根据自己的模式是否匹配给定串而返回真或者假。 - 它和LIKE非常类似,只不过它使用 SQL 标准定义的正则表达式理解模式。 - SQL 正则表达式是在LIKE标记和普通的(POSIX)正则表达式标记的奇怪的杂交。 + SIMILAR TO操作符根据其模式是否匹配给定字符串返回真或假。它与LIKE非常相似,但使用 SQL 标准定义的正则表达式来解释模式。SQL 正则表达式是LIKE表示法与普通(POSIX)正则表达式表示法的一种奇特结合。 - 类似LIKESIMILAR TO操作符只有在它的模式匹配整个串的时候才能成功;这一点和普通的 正则表达式的行为不同,在普通的正则表达式里,模式匹配串的任意部分。 和LIKE类似的地方还有,SIMILAR TO使用_%作为分别代表任意单个字符和任意串的通配符(这些可以比得上 POSIX 正则表达式里的..*)。 + 与LIKE类似,SIMILAR TO操作符只有在其模式匹配整个字符串时才算成功;这一点不同于普通正则表达式,后者可以匹配字符串的任意部分。与LIKE相同,SIMILAR TO也使用_%作为通配符,分别匹配任意单个字符和任意字符串(分别类似于 POSIX 正则表达式中的..*)。 @@ -4977,8 +4884,7 @@ cast(-44 as bit(12)) 111111010100 - 另一个非标准扩展是,在转义字符后面跟着一个字母或数字提供了对为POSIX正则表达式定义的转义序列的访问;参见下面的 - ,和 。 + 另一个非标准扩展是在转义字符后跟一个字母或数字,以使用 POSIX 正则表达式定义的转义序列;参见下文的 @@ -4994,19 +4900,19 @@ cast(-44 as bit(12)) 111111010100 - 带有三个参数的substring函数可以提取匹配SQL正则表达式模式的子字符串。 该函数可以按照标准SQL99语法编写。 + 带有三个参数的substring函数可以提取匹配 SQL 正则表达式模式的子字符串。该函数可以按照标准 SQL 语法书写: substring(string similar pattern escape escape-character) - 或使用现在废除的 SQL:1999 语法: + 也可以使用现已过时的 SQL:1999 语法: substring(string from pattern for escape-character) - 或作为一个普通的三参数函数: + 或写成普通的三参数函数: substring(string, pattern, escape-character) - 与SIMILAR TO一样,指定的模式必须与整个数据字符串匹配,否则函数失败并返回空值。 为了表示匹配的数据子字符串的模式中,模式中应该包含两个转义字符的出现,并在后面加上一个双引号(")。 匹配成功后,将返回与这些分隔符之间的模式部分匹配的文本。 + 与SIMILAR TO一样,指定的模式必须匹配整个数据字符串,否则函数失败并返回空值。为了指明要提取的子字符串所对应的模式部分,模式中应包含两个分隔符,每个分隔符都由转义字符后跟双引号(")组成。匹配成功时,返回与这两个分隔符之间的模式部分匹配的文本。 @@ -5014,7 +4920,7 @@ substring(string, pattern, - 作为对SQL标准的扩展,PostgreSQL只允许有一个转义双引号分隔符,在这种情况下,第三个正则表达式被视为空;或者没有分隔符,在这种情况下,第一个和第三个正则表达式被视为空。 + 作为对SQL标准的扩展,PostgreSQL允许仅有一个转义双引号分隔符,在这种情况下,第三个正则表达式被视为空;或者没有分隔符,在这种情况下,第一个和第三个正则表达式被视为空。 @@ -5031,8 +4937,8 @@ substring('foobar' similar '#"o_b#"%' escape '#') NULLPOSIX正则表达式 - regular expression - pattern matching + 正则表达式 + 模式匹配 @@ -5107,7 +5013,7 @@ substring('foobar' similar '#"o_b#"%' escape '#') NULLboolean - 字符串匹配正则表达式,大小写敏感 + 字符串匹配正则表达式,区分大小写 'thomas' ~ 't.*ma' @@ -5121,7 +5027,7 @@ substring('foobar' similar '#"o_b#"%' escape '#') NULLboolean - 字符串匹配正则表达式,大小写不敏感 + 字符串匹配正则表达式,不区分大小写 'thomas' ~* 'T.*ma' @@ -5135,7 +5041,7 @@ substring('foobar' similar '#"o_b#"%' escape '#') NULLboolean - 字符串不匹配正则表达式,大小写敏感 + 字符串不匹配正则表达式,区分大小写 'thomas' !~ 't.*max' @@ -5149,7 +5055,7 @@ substring('foobar' similar '#"o_b#"%' escape '#') NULLboolean - 字符串不匹配正则表达式,大小写不敏感 + 字符串不匹配正则表达式,不区分大小写 'thomas' !~* 'T.*ma' @@ -5161,11 +5067,11 @@ substring('foobar' similar '#"o_b#"%' escape '#') NULL - POSIX正则表达式提供了比LIKESIMILAR TO操作符更强大的含义。许多 Unix 工具,例如egrepsedawk使用一种与我们这里描述的类似的模式匹配语言。 + POSIX正则表达式提供了比LIKESIMILAR TO操作符更强大的模式匹配方式。许多 Unix 工具,例如egrepsedawk,都使用与这里描述的模式匹配语言相似的语言。 - 正则表达式是一个字符序列,它是定义一个串集合 (一个正则集)的缩写。 如果一个串是正则表达式描述的正则集中的一员时, 我们就说这个串匹配该正则表达式。 和LIKE一样,模式字符准确地匹配串字符, 除非在正则表达式语言里有特殊字符 — 不过正则表达式用的 特殊字符和LIKE用的不同。 和LIKE模式不一样的是,正则表达式允许匹配串里的任何位置,除非该正则表达式显式地挂接在串的开头或者结尾。 + 正则表达式是一个字符序列,是定义一组字符串(一个正则集)的简写。如果字符串属于正则表达式描述的正则集,就称该字符串匹配此正则表达式。与LIKE一样,模式中的字符精确匹配字符串中的字符,除非该模式字符在正则表达式语言中有特殊含义 — 但正则表达式使用的特殊字符与LIKE不同。与LIKE模式不同,正则表达式可以匹配字符串中的任意位置,除非显式将其锚定到字符串开头或末尾。 @@ -5186,8 +5092,8 @@ substring('foobar' similar '#"o_b#"%' escape '#') NULL 带两个参数的substring函数,即substring(string from pattern),提供了抽取一个匹配 POSIX 正则表达式模式的子串的方法。 - 如果没有匹配它返回空值,否则就是匹配模式的文本中的第一部分。 - 但是如果该模式包含任何圆括号,那么将返回匹配第一对子表达式(对应第一个左圆括号的) 的文本。 + 如果没有匹配它返回空值,否则返回文本中首次匹配模式的那部分内容。 + 但是如果该模式包含任何圆括号,那么将返回匹配第一个圆括号子表达式(左圆括号最先出现的那个)的文本。 如果你想在表达式里使用圆括号而又不想导致这个例外,那么你可以在整个表达式外边放上一对圆括号。 如果你需要在想抽取的子表达式前有圆括号,参阅后文描述的非捕获性圆括号。 @@ -5216,7 +5122,7 @@ substring('foobar' from 'o(.)b') o - 一些示例: + 一些示例: regexp_count('ABCABCAXYaxy', 'A.') 3 regexp_count('ABCABCAXYaxy', 'A.', 1, 'i') 4 @@ -5224,26 +5130,26 @@ regexp_count('ABCABCAXYaxy', 'A.', 1, 'i') 4 - regexp_instr函数返回字符串中第N个匹配项的起始或结束位置,如果没有这样的匹配项则返回零。 + regexp_instr函数返回 POSIX 正则表达式模式在字符串中第N个匹配项的起始或结束位置,如果没有这样的匹配项则返回零。 它的语法为regexp_instr(string, pattern , start , N , endoption , flags , subexpr - ). + )。 在string中搜索pattern,通常从字符串的开头开始,但如果提供了start参数,则从该字符索引开始。 如果指定了N,则定位模式的第N个匹配项,否则定位第一个匹配项。 如果省略了endoption参数或将其指定为0,则函数返回匹配项的第一个字符的位置。否则,endoption 必须为1,函数返回匹配项后面字符的位置。 flags参数是一个可选的文本字符串,包含零个或多个单字母标志,可以改变函数的行为。支持的标志在中描述。 - 对于包含括号子表达式的模式,subexpr是一个整数,表示感兴趣的子表达式:结果标识与该子表达式匹配的子字符串的位置。 - 子表达式按其前导括号的顺序编号。 - 当省略或将subexpr指定为零时,结果标识整个匹配的位置,而不考虑括号子表达式。 + 对于包含圆括号子表达式的模式,subexpr是一个整数,表示感兴趣的子表达式:结果标识与该子表达式匹配的子字符串的位置。 + 子表达式按其左圆括号的顺序编号。 + 当省略或将subexpr指定为零时,结果标识整个匹配的位置,而不考虑圆括号子表达式。 - 一些示例: + 一些示例: regexp_instr('number of your street, town zip, FR', '[^,]+', 1, 2) 23 @@ -5265,7 +5171,7 @@ regexp_instr('ABCDEFGHI', '(c..)(...)', 1, 1, 0, 'i', 2) - 一些示例: + 一些示例: regexp_like('Hello World', 'world') false regexp_like('Hello World', 'world', 'i') true @@ -5273,18 +5179,18 @@ regexp_like('Hello World', 'world', 'i') true - regexp_match函数返回一个文本数组,其中包含与POSIX正则表达式模式对字符串的第一个匹配的子字符串。它的语法为 + regexp_match函数返回一个文本数组,包含字符串首次匹配 POSIX 正则表达式模式时匹配的子字符串。它的语法为 regexp_match(string, pattern , flags )。 如果没有匹配,结果为NULL。 - 如果找到匹配,并且pattern不包含括号子表达式,则结果是包含与整个模式匹配的子字符串的单元素文本数组。 - 如果找到匹配,并且pattern包含括号子表达式,则结果是一个文本数组,其中n的元素是匹配 - pattern的第n个括号子表达式的子字符串(不包括非捕获括号;详情见下文)。 + 如果找到匹配,并且pattern不包含圆括号子表达式,则结果是包含与整个模式匹配的子字符串的单元素文本数组。 + 如果找到匹配,并且pattern包含圆括号子表达式,则结果是一个文本数组,其中第n个元素是匹配 + pattern的第n个圆括号子表达式的子字符串(不包括非捕获括号;详情见下文)。 flags参数是一个可选的文本字符串,其中包含零个或多个单个字母标志,用于更改函数的行为。支持的标志在中描述。 - 一些示例: + 一些示例: SELECT regexp_match('foobarbequebaz', 'bar.*que'); regexp_match @@ -5303,10 +5209,10 @@ SELECT regexp_match('foobarbequebaz', '(bar)(beque)'); - 在通常情况下,当您只想要整个匹配的子字符串或NULL表示没有匹配时, + 在通常情况下,当你只想要整个匹配的子字符串或NULL表示没有匹配时, 最好的解决方案是使用regexp_substr()。 然而,在PostgreSQL版本15及以上版本中才存在 - regexp_substr()。在旧版本中工作时,您可以提取 + regexp_substr()。在旧版本中工作时,你可以提取 regexp_match()结果的第一个元素,例如: SELECT (regexp_match('foobarbequebaz', 'bar.*que'))[1]; @@ -5349,44 +5255,25 @@ SELECT regexp_matches('foobarbequebazilbarfbonk', '(b[^b]+)(b[^b]+)', 'g'); - 在大部分情况下,regexp_matches()应该与g标志一起使用,因为如果只是想要第一个匹配,使用regexp_match()会更加简单高效。不过,regexp_match()仅存在于PostgreSQL版本10以及更高的版本中。当在较老的版本中使用时,一种常用的技巧是把regexp_matches()调用放在子选择中,例如: + 在大部分情况下,regexp_matches()应该与g标志一起使用,因为如果只是想要第一个匹配,使用regexp_match()会更加简单高效。不过,regexp_match()仅存在于PostgreSQL版本10以及更高的版本中。当在较老的版本中使用时,一种常用的技巧是把regexp_matches()调用放在子查询中,例如: SELECT col1, (SELECT regexp_matches(col2, '(bar)(beque)')) FROM tab; - 如果有一个匹配,则这个语句会产生一个文本数组,否则返回NULL,这和regexp_match()的做法一样。如果没有子选择,这个查询对于没有匹配的表行根本不会产生输出,显然那不是想要的行为。 + 如果有一个匹配,则这个语句会产生一个文本数组,否则返回NULL,这和regexp_match()的做法一样。如果没有子查询,这个查询对于没有匹配的表行根本不会产生输出,这通常不是预期行为。 - regexp_replace函数提供了对匹配POSIX正则表达式模式的子字符串进行替换的功能。 - 它的语法为 - regexp_replace(source, + regexp_replace函数将匹配 POSIX 正则表达式模式的子字符串替换为新文本。它的语法为 regexp_replace(source, pattern, replacement , start , N - , flags ). - (注意,除非指定了start,否则无法指定N, - 但flags可以在任何情况下给出。) - 如果pattern没有匹配到source字符串, - 则返回未更改的source字符串。如果有匹配,则返回带有 - replacement字符串替换匹配子字符串的source字符串。 - replacement字符串可以包含\n, - 其中n为1至9,表示应插入与模式的第n个括号子表达式匹配的源子字符串, - 也可以包含\&表示应插入与整个模式匹配的子字符串。 - 如果需要在替换文本中放置一个字面上的反斜杠,则写\\。 - 在string中搜索pattern, - 通常从字符串的开头开始,但如果提供了start参数,则从该字符索引开始。 - 默认情况下,只替换模式的第一个匹配项。 - 如果指定了N且大于零,则替换模式的第N个匹配项。 - 如果给出了g标志,或者指定了N且为零,则在或之后的所有匹配项 - 位置都将被替换。 (当指定了N时,g标志将被忽略。) - flags参数是一个可选的文本字符串,包含零个或多个单字母标志,用于更改函数的行为。 - 支持的标志(尽管不包括g)在中描述。 + , flags )。(注意,只有指定了start,才能指定N,但flags在任何情况下都可以给出。)如果没有匹配pattern的内容,则原样返回源字符串source。如果有匹配,则返回将匹配的子字符串替换为replacement后的sourcereplacement字符串可以包含\n,其中n为 1 至 9,表示插入与模式中第n个圆括号子表达式匹配的源子字符串;也可以包含\&,表示插入与整个模式匹配的子字符串。要在替换文本中放入字面的反斜线,应写成\\。在string中搜索pattern时,通常从字符串开头开始;如果提供了start参数,则从该字符索引开始。默认只替换模式的第一个匹配项。如果指定了N且其值大于零,则替换模式的第N个匹配项。如果给出g标志,或指定了N且其值为零,则替换start位置及其后的所有匹配项。(指定N时,g标志会被忽略。)flags参数是可选的文本字符串,可包含零个或多个单字母标志,用于改变函数行为。支持的标志(不包括g)在中介绍。 - 一些示例: + 一些示例: regexp_replace('foobarbaz', 'b..', 'X') fooXbaz @@ -5402,7 +5289,7 @@ regexp_replace('A PostgreSQL function', 'a|e|i|o|u', 'X', 1, 3, 'i') - regexp_split_to_table把一个 POSIX 正则表达式模式当作一个定界符来分离一个串。它的语法形式是regexp_split_to_table(string, pattern , flags )。如果没有与pattern的匹配,该函数返回string。如果有至少有一个匹配,对每一个匹配它都返回从上一个匹配的末尾(或者串的开头)到这次匹配开头之间的文本。当没有更多匹配时,它返回从上一次匹配的末尾到串末尾之间的文本。flags参数是一个可选的文本串,它包含零个或更多单字母标志,这些标识可以改变该函数的行为。regexp_split_to_table能支持的标志在中描述。 + regexp_split_to_table把一个 POSIX 正则表达式模式当作一个定界符来分割字符串。它的语法形式是regexp_split_to_table(string, pattern , flags )。如果没有与pattern的匹配,该函数返回string。如果至少有一个匹配,对每一个匹配它都返回从上一个匹配的末尾(或者串的开头)到这次匹配开头之间的文本。当没有更多匹配时,它返回从上一次匹配的末尾到串末尾之间的文本。flags参数是一个可选的文本串,它包含零个或更多单字母标志,这些标志可以改变该函数的行为。regexp_split_to_table能支持的标志在中描述。 @@ -5410,7 +5297,7 @@ regexp_replace('A PostgreSQL function', 'a|e|i|o|u', 'X', 1, 3, 'i') - 一些示例: + 一些示例: SELECT foo FROM regexp_split_to_table('the quick brown fox jumps over the lazy dog', '\s+') AS foo; foo @@ -5456,9 +5343,9 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; - 正如最后一个示例所示,regexp分割函数会忽略出现在字符串开头或结尾 - 或紧跟在前一个匹配项之后的零长度匹配。这与其他regexp函数实现的 - 严格的regexp匹配定义相矛盾,但在实践中通常是最方便的行为。 + 正如最后一个示例所示,正则表达式分割函数会忽略出现在字符串开头或结尾 + 或紧跟在前一个匹配项之后的零长度匹配。这与其他正则表达式函数实现的 + 严格的正则表达式匹配定义相矛盾,但在实践中通常是最方便的行为。 其他软件系统如Perl使用类似的定义。 @@ -5471,23 +5358,23 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; , N , flags , subexpr - )。 + )。 patternstring中进行搜索, 通常从字符串的开头开始,但如果提供了start参数,则从该字符索引开始。 如果指定了N,则返回模式的第N次匹配, 否则返回第一次匹配。参数flags是一个可选文本字符串, 包含零个或多个单字母标志,可以改变函数的行为。支持的标志在中描述。 - 对于包含括号子表达式的模式,subexpr是一个整数, + 对于包含圆括号子表达式的模式,subexpr是一个整数, 表示感兴趣的子表达式:结果是与该子表达式匹配的子字符串。 - 子表达式按其前导括号的顺序编号。 - 当省略或为零时,subexpr的结果是整个匹配,而不考虑括号子表达式。 + 子表达式按其左圆括号的顺序编号。 + 当subexpr省略或为零时,结果是整个匹配,而不考虑圆括号子表达式。 - 一些示例: + 一些示例: regexp_substr('number of your street, town zip, FR', '[^,]+', 1, 2) - 城镇 邮编 + town zip regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) FGH @@ -5524,7 +5411,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 一个量化原子是一个原子, 后面可能跟着一个量词。没有量词的时候,它匹配一个原子, 有量词的时候,它可以匹配若干个原子。一个原子可以是在里面显示的任何可能。 可能的量词和它们的含义在里显示。 + 一个量化原子是一个原子,后面可以跟一个量词。没有量词时,匹配一次原子所匹配的内容;有量词时,按量词指定的次数匹配原子所匹配的内容。原子可以是列出的任何一种形式。可用量词及其含义见 @@ -5548,12 +5435,12 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) (re) - (其中re是任何正则表达式) 匹配一个对re的匹配,匹配将为可能的报告被记下 + (其中re是任意正则表达式)匹配re所匹配的内容,并记录该匹配,以备输出结果 (?:re) - 同上,但是匹配不会为了报告而被记下 (一个非捕获圆括号集) (只对 ARE) + 同上,但不记录匹配结果(非捕获圆括号;仅适用于 ARE) @@ -5568,17 +5455,17 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) \k - (其中k是一个非字母数字字符) 匹配一个被当作普通字符看待的特定字符, 例如,\\匹配一个反斜线字符 + (其中k既不是字母也不是数字)把该字符视为普通字符并匹配它,例如,\\匹配反斜线字符 \c - 其中c是一个字母数字 (可能跟着其它字符),它是一个转义, 参阅(仅对 ARE; 在 ERE 和 BRE 中,它匹配c + 其中c是字母或数字(后面可能还有其他字符),这是一个转义,参见(仅适用于 ARE;在 ERE 和 BRE 中,它匹配c { - 如果后面跟着一个字符,而不是数字, 那么就匹配左花括弧{;如果跟着一个数字, 那么它是range的开始(见下文) + 如果后面跟着非数字字符,则匹配左花括号{;如果后面跟着数字,则是bound的开头(见下文) @@ -5596,7 +5483,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 如果你关掉了,你在文串常量中写的任何反斜线都需要被双写。详见。 + 如果你关掉了,你在字符串常量中写的任何反斜线都需要被双写。详见 @@ -5685,7 +5572,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 非贪婪的量词(只在 ARE 中可用)匹配对应的正常 (贪婪)模式,区别是它寻找最少的匹配,而不是最多的匹配。详见。 + 非贪婪量词(仅适用于 ARE)与对应的普通(贪婪)量词匹配相同的可能内容,但优先选择最少的匹配次数,而不是最多的匹配次数。详见 @@ -5712,39 +5599,39 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) ^ - 串开头的匹配 + 在字符串开头匹配 $ - 串末尾的匹配 + 在字符串末尾匹配 (?=re) - 在某个位置上,如果从该位置开始的子串能够匹配re,则匹配正向先行断言(仅对 ARE) + 正向先行断言在这样的位置匹配:存在从该位置开始且匹配re的子字符串(仅适用于 ARE) (?!re) - 在某个位置上,如果从该位置开始的子串不能匹配re,则匹配负向先行断言(仅对 ARE) + 负向先行断言在这样的位置匹配:不存在任何从该位置开始且匹配re的子字符串(仅适用于 ARE) (?<=re) - 在某个位置上,如果以该位置结束的某个子串能够匹配re,则匹配正向后行断言(仅对 ARE) + 正向后行断言在这样的位置匹配:存在以该位置结束且匹配re的子字符串(仅适用于 ARE) (?<!re) - 在某个位置上,如果以该位置结束的任何子串都不能匹配re,则匹配负向后行断言(仅对 ARE) + 负向后行断言在这样的位置匹配:不存在任何以该位置结束且匹配re的子字符串(仅适用于 ARE) - Lookahead 和 lookbehind 约束不能包含反向引用 (参阅),并且其中的所有圆括号 都被认为是非捕获的。 + 先行和后行约束不能包含反向引用(参见),其中的所有圆括号都视为非捕获圆括号。 @@ -5753,11 +5640,11 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) 方括号表达式 - 方括号表达式是一个包围在[]中的字符列表。它通常匹配列表中的任意单个字符(但见下文)。 如果列表以^开头,它匹配任意单个在该列表参与部分中的字符。如果该列表中两个字符用-隔开, 那它就是那两个字符(包括在内)之间的所有字符范围的缩写,例如,在ASCII[0-9]匹配任何十进制数字。两个范围共享一个端点是非法的,例如,a-c-e。范围与字符集关系密切, 可移植的程序应该避免依靠它们。 + 方括号表达式是用[]括起来的字符列表。通常,它匹配列表中的任意单个字符(但请参见下文)。如果列表以^开头,则匹配任意在列表剩余部分中的单个字符。如果列表中的两个字符用-分隔,则表示排序序列中这两个字符之间的完整字符范围(包含两个端点);例如,ASCII中的[0-9]匹配任意十进制数字。两个范围共享一个端点是不合法的,例如a-c-e。范围高度依赖排序序列,因此可移植程序应避免依赖它们。 - 想在列表中包含文本],可以让它做列表的首字符(如果使用了^,需要放在其后)。 想在列表中包含文本-,可以让它做列表的首字符或者尾字符,或者一个范围的第二个端点。 想在列表中把文本-当做范围的起点, 把它用[..]包围起来,这样它就成为一个排序元素(见下文)。 除了这些字符本身、一些用[的组合(见下段)以及转义(只在 ARE 中有效)以外,所有其它特殊字符 在方括号表达式里都失去它们的特殊含义。特别是,在 ERE 和 BRE 规则下\不是特殊的, 但在 ARE 里,它是特殊的(引入一个转义)。 + 想在列表中包含字面字符],可以让它做列表的首字符(如果使用了^,需要放在其后)。 想在列表中包含字面字符-,可以让它做列表的首字符或者尾字符,或者一个范围的第二个端点。 想在列表中把字面字符-当做范围的起点, 把它用[..]包围起来,这样它就成为一个排序元素(见下文)。 除了这些字符本身、一些用[的组合(见下段)以及转义(只在 ARE 中有效)以外,所有其它特殊字符 在方括号表达式里都失去它们的特殊含义。特别是,在 ERE 和 BRE 规则下\不是特殊的, 但在 ARE 里,它是特殊的(引入一个转义)。 @@ -5772,30 +5659,11 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 在方括号表达式里,包围在[==]里的排序元素是一个等价类, 代表等效于那一个的所有排序元素的字符序列,包括它本身(如果没有其它等效排序元素,那么就好象封装定界符是[..])。例如,如果o^是一个等价类的成员,那么[[=o=]][[=^=]][o^]都是同义的。一个等价类不能是一个范围的端点。 + 在方括号表达式里,包围在[==]里的排序元素是一个等价类, 代表等效于那一个的所有排序元素的字符序列,包括它本身(如果没有其它等效排序元素,那么就好像封装定界符是[..])。例如,如果o^是一个等价类的成员,那么[[=o=]][[=^=]][o^]都是同义的。一个等价类不能是一个范围的端点。 - 在方括号表达式里,在[::]里面封装的字符类的名字代表属于该类的所有字符的列表。 - 字符类不能作为范围的端点使用。 - POSIX标准定义了这些字符类的名称: - alnum (字符和数字), - alpha (字符), - blank (空格和制表符tab), - cntrl (控制符), - digit (数位数), - graph (空格除外可打印字符), - lower (小写字母), - print (包含空格可打印字符), - punct (标点符号), - space (空白), - upper (大写字母), - 和 xdigit (十六进制数). - 对于7位ASCII字符集中的字符来说,这些标准字符类的行为在不同平台上一般是一致的。 - 一个给定的非 ASCII 字符是否被认为属于这些类别中的一个,取决于正则表达式函数或操作符所使用的排序规则(见),或者在默认情况下取决于数据库的LC_CTYPE locale 设置(见)。 - 非ASCII字符的分类在不同的平台上会有不同的分类,即使是在类似命名的locale中也是如此。 - (但C locale从不认为任何非ASCII字符属于上述任何一类)。 - 除了这些标准字符类之外,PostgreSQL定义了word字符类,等同于alnum加上下划线(_), 以及ascii字符类,它完全包含7位ASCII字符集。 + 在方括号表达式中,用[::]括起来的字符类名称表示属于该类的所有字符。字符类不能作为范围的端点。POSIX标准定义了以下字符类名称:alnum(字母和数字)、alpha(字母)、blank(空格和制表符)、cntrl(控制字符)、digit(数字)、graph(空格以外的可打印字符)、lower(小写字母)、print(包括空格的可打印字符)、punct(标点符号)、space(任意空白字符)、upper(大写字母)和xdigit(十六进制数字)。对于 7 位 ASCII 字符集中的字符,这些标准字符类在各平台上的行为通常一致。给定的非 ASCII 字符是否属于其中某个类,取决于正则表达式函数或操作符使用的排序规则(参见),默认则取决于数据库的LC_CTYPE区域设置(参见)。即使区域设置名称相似,非 ASCII 字符的分类也可能因平台而异。(但C区域设置不会将任何非 ASCII 字符归入这些类。)除了这些标准字符类,PostgreSQL还定义了word字符类,即alnum加上下划线(_),以及恰好包含 7 位 ASCII 字符集的ascii字符类。 @@ -5812,11 +5680,11 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) 正则表达式转义 - 转义是以\开头,后面跟着一个字母数字字符的特殊序列。 转义有好几种变体:字符输入转义、字符类简写转义、约束转义以及反向引用。在 ARE 里, 如果一个\后面跟着一个字母数字,但是并未组成一个合法的转义, 那么它是非法的。在 ERE 中没有转义:在方括号表达式之外,一个后面跟着字母数字字符的\只是表示该字符是一个普通的字符,而且在一个方括号表达式里,\是一个普通的字符(后者实际上在 ERE 和 ARE 不兼容)。 + 转义是以\开头,后面跟着一个字母或数字字符的特殊序列。 转义有好几种变体:字符输入转义、字符类简写转义、约束转义以及反向引用。在 ARE 里, 如果一个\后面跟着一个字母或数字,但是并未组成一个合法的转义, 那么它是非法的。在 ERE 中没有转义:在方括号表达式之外,一个后面跟着字母或数字字符的\只是表示该字符是一个普通的字符,而且在一个方括号表达式里,\是一个普通的字符(后者是 ERE 与 ARE 之间唯一的实际不兼容之处)。 - 字符输入转义用于便于我们在 RE 中声明那些不可打印的或其他习惯的字符。它们显示在中。 + 字符输入转义便于在 RE 中指定不可打印或其他不便输入的字符,见 @@ -5824,13 +5692,13 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 约束转义是一个约束,如果满足特定的条件,它匹配该空串。它们显示在中。 + 约束转义是以转义形式书写的约束,在满足特定条件时匹配空字符串,见 - 反向引用\n)匹配数字\n指定的被前面的圆括号子表达式匹配的同一个串 (参阅)。 + 反向引用\n)匹配前面编号为n的圆括号子表达式所匹配的同一字符串 (参阅)。 例如, ([bc])\1匹配bb或者cc, 但是不匹配bc或者cb。 - RE 中子表达式必须完全在反向引用前面。子表达式以它们的先导圆括号的顺序编号。 + RE 中子表达式必须完全在反向引用前面。子表达式以它们的左圆括号的顺序编号。 非捕获圆括号并不定义子表达式。 反向引用仅考虑被引用的子表达式匹配的字符串字符,而不考虑其中包含的任何约束。 例如,(^\d)\1 将匹配 22。 @@ -5873,7 +5741,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) \e - 排序序列名为ESC的字符,如果无法做到该字符为八进制值 033 + 排序序列名称为ESC的字符;若不存在这样的字符,则使用八进制值为033的字符 @@ -5883,7 +5751,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) \n - 新行,和 C 中一样 + 换行符,与 C 中相同 @@ -6007,7 +5875,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 类-缩写转义也适用于括号表达式,尽管上面显示的定义在该上下文中在语法上并不完全有效。 + 字符类简写转义也适用于括号表达式,尽管上面显示的定义在该上下文中在语法上并不完全有效。 例如,[a-c\d] 等同于 [a-c[:digit:]] @@ -6048,7 +5916,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) \Y - 只在一个词的不是开头或末尾的点上匹配 + 只在不属于单词开头或末尾的位置匹配 @@ -6060,7 +5928,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 一个词被定义成在上面[[:<:]][[:>:]]中的声明。在方括号表达式里,约束转义是非法的。 + 单词的定义与上文[[:<:]][[:>:]]的说明相同。方括号表达式中不允许使用约束转义。 @@ -6080,12 +5948,12 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) \m - (其中m是一个非零位)一个到第m个子表达式的反向引用 + (其中m是一个非零数字)一个到第m个子表达式的反向引用 \mnn - (其中m是一个非零位,并且nn是一些更多的位,并且十六进制值mnn不超过目前能看到的封闭捕获圆括号的数目)一个到第mnn个子表达式的反向引用 + (其中m是一个非零数字,并且nn是后续的若干数字,并且十进制值mnn不大于此前已出现的捕获右圆括号数)一个到第mnn个子表达式的反向引用 @@ -6094,7 +5962,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 在八进制字符输入转义和反向引用之间有一个历史继承的歧义存在,这个歧义是 通过下面的启发式规则解决的,像上面描述地那样。前导零总是表示这是一个八进制转义。 而单个非零数字,如果没有跟着任何其它位,那么总是被认为反向引用。 一个多位的非零开头的序列也被认为是反向引用,只要它出现在合适的子表达式后面 (也就是说,在反向引用的合法范围中的数),否则就被认为是一个八进制。 + 八进制字符输入转义与反向引用之间存在固有歧义,按上文提到的启发式规则解决:前导零始终表示八进制转义。单个非零数字,如果后面没有其他数字,始终视为反向引用。不以零开头的多位数字序列,如果前面已有相应的子表达式(即该数字在反向引用的合法范围内),则视为反向引用,否则视为八进制转义。 @@ -6108,11 +5976,11 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 如果一个 RE 以***:开头,那么剩下的 RE 都被当作 ARE(这在PostgreSQL中通常是无效的,因为 RE 被假定为 ARE,但是如果 ERE 或 BRE 模式通过flags参数被指定为一个正则表达式函数时,它确实能产生效果)。如果一个 RE 以***=开头, 那么剩下的 RE 被当作一个文本串,所有的字符都被认为是一个普通字符。 + RE 可以以两种特殊的引导前缀之一开头。如果 RE 以***:开头,余下部分就被视为 ARE。(这在PostgreSQL中通常没有影响,因为 RE 默认被视为 ARE;但如果通过正则表达式函数的flags参数指定了 ERE 或 BRE 模式,它就会产生影响。)如果 RE 以***=开头,余下部分就作为按字面解释的字符串处理,所有字符都视为普通字符。 - 一个 ARE 可以以嵌入选项开头:一个序列(?xyz)(这里的xyz是一个或多个字母字符)声明影响剩余 RE 的选项。 这些选项覆盖任何前面判断的选项 — 特别地,它们可以覆盖一个正则表达式操作符隐含的大小写敏感的行为,或者覆盖flags参数中的正则表达式函数。可用的选项字母在中显示。注意这些同样的选项字母也被用在正则表达式函数的flags参数中。 + 一个 ARE 可以以嵌入选项开头:一个序列(?xyz)(这里的xyz是一个或多个字母字符)声明影响剩余 RE 的选项。 这些选项覆盖任何先前确定的选项 — 特别地,它们可以覆盖一个正则表达式操作符隐含的大小写敏感的行为,或者覆盖正则表达式函数的flags参数所指定的选项。可用的选项字母在中显示。注意这些同样的选项字母也被用在正则表达式函数的flags参数中。
@@ -6157,32 +6025,32 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) n - 新行敏感的匹配(见 + 换行敏感的匹配(见 p - 部分新行敏感的匹配(见 + 部分换行敏感的匹配(见 q - RE的剩余部分是一个文字(quoted)串,全部是普通字符 + RE 的剩余部分按字面(加引号)解释,所有字符都视为普通字符 s - 非新行敏感的匹配(默认) + 非换行敏感的匹配(默认) t - 紧语法(默认,见下文) + 紧凑语法(默认;见下文) w - 逆部分新行敏感(怪异)的匹配(见 + 逆部分换行敏感(怪异)的匹配(见 @@ -6194,16 +6062,16 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2)
- 嵌入选项在)终止序列时发生作用。它们只在 ARE 的开始处起作用 (在任何可能存在的***:控制器后面)。 + 嵌入选项从结束该序列的)处开始生效。它们只能出现在 ARE 的开头(如果存在***:引导前缀,则位于该前缀之后)。 - 除了通常的()RE 语法(这种情况下所有字符都有效), 还有一种扩展语法,可以通过声明嵌入的x选项获得。在扩展语法里,RE 中的空白字符被忽略,就像那些在#和其后的新行(或 RE 的末尾)之间的字符一样。这样就允许我们给一个复杂的 RE 分段和注释。不过这个基本规则有三种例外: + 除了通常的紧凑 RE 语法(其中所有字符都有意义)之外,还有一种扩展语法,可以通过指定嵌入的x选项来使用。在扩展语法中,RE 中的空白字符会被忽略,同样被忽略的还有#与其后的换行符(或 RE 末尾)之间的所有字符。这使得复杂的 RE 可以分段并添加注释。此基本规则有三个例外: - 空白字符或前置了\#将被保留 + 空白字符或 # 的前面若有 \,该字符就会被保留。 @@ -6218,14 +6086,14 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 为了这个目的,空白是空格、制表符、新行以及任何属于 whitespace 字符类的字符。 + 在这里,空白字符包括空格、制表符、换行符,以及属于space字符类的任何字符。 - 最后,在 ARE 里,方括号表达式外面,序列(?#ttt)(其中ttt是任意不包含一个))的文本)是一个注释, 它被完全忽略。同样,这样的东西是不允许出现在多字符符号的字符中间的,例如 (?:。这种注释更像是一种历史产物而不是一种有用的设施,并且它们的使用已经被废弃;请使用扩展语法来替代。 + 最后,在 ARE 里,方括号表达式外面,序列(?#ttt)(其中ttt是任意不包含一个)的文本)是一个注释, 它被完全忽略。同样,这样的东西是不允许出现在多字符符号的字符中间的,例如 (?:。这种注释更像是一种历史产物而不是一种有用的设施,并且它们的使用已经被废弃;请使用扩展语法来替代。
- 如果声明了一个初始的***=控制器,那么所有这些元语法扩展都不能使用,因为这样表示把用户输入当作一个文字串而不是 RE 对待。 + 如果指定了开头的***=引导前缀,那么这些元语法扩展都不能使用,因为这表示把用户输入作为按字面解释的字符串,而非 RE 处理。 @@ -6242,7 +6110,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 大多数原子以及所有约束,都没有贪婪属性(因为它们毕竟无法匹配个数变化的文本)。 + 大多数原子以及所有约束,都没有贪婪属性(因为它们毕竟无法匹配长度不定的文本)。 @@ -6294,7 +6162,7 @@ SELECT SUBSTRING('XY1234Z', 'Y*?([0-9]{1,3})');
- 简而言之,如果一个 RE 同时包含贪婪和非贪婪的子表达式,那么总的匹配长度要么是尽可能长,要么是尽可能短,这取决于给整个 RE 赋予的属性。给子表达式赋予的属性只影响在这个匹配里,各个子表达式之间相互允许吃掉的多少。 + 简而言之,如果一个 RE 同时包含贪婪和非贪婪的子表达式,那么总的匹配长度要么是尽可能长,要么是尽可能短,这取决于给整个 RE 赋予的属性。给子表达式赋予的属性只影响在这个匹配里,各个子表达式相对于其他子表达式能吃掉多少内容。 @@ -6328,23 +6196,23 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 如果声明了大小写无关的匹配,那么效果就好像所有大小写区别在字母表中消失了。如果在多个情况中一个字母以一个普通字符的形式出现在方括号表达式外面,那么它实际上被转换成 一个包含大小写的方括号表达式,也就是说,x 变成 [xX]。 如果它出现在一个方括号表达式里面,那么它的所有大小写的同族都被加入 方括号表达式中,也就是说,x变成[xX]。当它出现在一个方括号表达式内时,它的所有大小写副本都被加入到方括号表达式中,例如, [x]会变成[xX],而[^x]会变成[^xX]。 + 如果指定不区分大小写的匹配,其效果近似于字母表中的所有大小写差别都消失了。当存在大小写形式的字母作为普通字符出现在方括号表达式之外时,实际上会转换为包含其大小写形式的方括号表达式,例如x变成[xX]。当它出现在方括号表达式内部时,其所有大小写形式都会加入该表达式,例如[x]变成[xX][^x]变成[^xX] 如果指定了换行敏感的匹配,.和使用^的方括号表达式 将永远不会匹配换行字符(这样,匹配就不会跨越行,除非 RE 显式地包含了换行)并且^$除了分别匹配串开头和结尾之外,还将分别匹配换行后面和前面的空串。 但是 ARE 转义\A\Z仍然匹配串的开头和结尾。 - 此外,字符类缩写符\D\W将匹配换行,而无论这种模式如何。 + 此外,字符类简写\D\W将匹配换行,而无论这种模式如何。 (在PostgreSQL 14之前,它们在换行敏感模式下不匹配换行。 写入[^[:digit:]][^[:word:]]以获取旧的行为。) - 如果指定了部分新行敏感的匹配,那么它影响.和方括号表达式, 这个时候和新行敏感的匹配一样,但是不影响^$。 + 如果指定了部分换行敏感的匹配,那么它影响.和方括号表达式, 这个时候和换行敏感的匹配一样,但是不影响^$ - 如果指定了逆新行敏感匹配,那么它影响^$,其作用和在新行敏感的匹配里一样,但是不影响.和方括号表达式。这个并不是很有用,只是为了满足对称性而提供的。 + 如果指定了逆部分换行敏感匹配,那么它影响^$,其作用和在换行敏感的匹配里一样,但是不影响.和方括号表达式。这个并不是很有用,只是为了满足对称性而提供的。 @@ -6357,11 +6225,11 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}');
- ARE 实际上和 POSIX ERE 不兼容的唯一的特性是在方括号表达式里\并不失去它特殊的含义。所有其它 ARE 特性都使用在 POSIX ERE 里面是非法或者是未定义、未声明效果的语法;指示器的***就是在 POSIX 的 BRE 和 ERE 之外的语法。 + ARE 与 POSIX ERE 实际不兼容的唯一特性是:\在方括号表达式中不会失去特殊含义。其他所有 ARE 特性所使用的语法,在 POSIX ERE 中都是非法的,或其效果未定义或未指定;引导前缀的***语法同样不属于 POSIX 的 BRE 或 ERE 语法。 - 许多 ARE 扩展都是从 Perl 那里借来的(但是有些被做了修改来清理它们),以及一些 Perl 里没有出现的扩展。要注意的不兼容性包括\b\B、对结尾的新行缺乏特别的处理、对那些被新行敏感匹配的东西附加的补齐方括号表达式、在 lookahead/lookbehind 约束里对圆括号和反向引用的限制以及最长/最短 匹配(而不是第一匹配)的语义。 + 许多 ARE 扩展借鉴自 Perl,但其中一些经过了整理和修改,也未实现少数 Perl 扩展。需要注意的不兼容之处包括\b\B、不对末尾换行符作特殊处理、取反的方括号表达式也受换行敏感匹配影响、先行和后行约束中对圆括号及反向引用的限制,以及采用最长或最短匹配而非首次匹配的语义。 @@ -6370,7 +6238,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 基本正则表达式 - BREs 在几个方面和 ERE 不太一样。在 BRE 中,|+?都是普通字符并且没有与它们功能等价的东西。范围的定界符是\{\}, 因为 {}本身是普通字符。嵌套的子表达式的圆括号是\(\),因为()自身是普通字符。除非在 RE 开头或者是圆括号子表达式开头,^都是一个普通字符。 除非在 RE 结尾或者是圆括号子表达式的结尾,$是一个普通字符。如果*出现在 RE 开头或者是圆括号封装的子表达式开头 (前面可能有^),那么它是个普通字符。最后,可以用单数字的反向引用,\<\>分别是[[:<:]][[:>:]]的同义词;在 BRE 中没有其它可用的转义。 + BRE 在几个方面和 ERE 不太一样。在 BRE 中,|+?都是普通字符并且没有与它们功能等价的东西。范围的定界符是\{\},而{}本身是普通字符。嵌套的子表达式的圆括号是\(\),而()自身是普通字符。除非在 RE 开头或者是圆括号子表达式开头,^都是一个普通字符。 除非在 RE 结尾或者是圆括号子表达式的结尾,$是一个普通字符。如果*出现在 RE 开头或者是圆括号封装的子表达式开头 (前面可能有^),那么它是个普通字符。最后,可以用单数字的反向引用,\<\>分别是[[:<:]][[:>:]]的同义词;在 BRE 中没有其它可用的转义。 @@ -6483,16 +6351,13 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 使用\p{UnicodeProperty}或其反义\P{UnicodeProperty}来定义XQuery字符类元素是不被支持的。 + 使用\p{UnicodeProperty}或其取反形式\P{UnicodeProperty}来定义XQuery字符类元素是不被支持的。 - POSIX解释字符类,如\w - (参见) - 根据当前区域设置(你可以通过将COLLATE子句附加到操作符或函数上来控制)。 - XQuery通过参考Unicode字符属性来指定这些类别,因此只有遵循Unicode规则的区域设置才能获得等效行为。 + POSIX 根据当前区域设置解释\w等字符类(参见);你可以通过为操作符或函数附加COLLATE子句来控制该区域设置。XQuery 根据 Unicode 字符属性定义这些类,因此只有使用遵循 Unicode 规则的区域设置时,才能得到等效行为。 @@ -6505,10 +6370,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 在描述的字符输入转义中 - 中, - XQuery仅支持\n\r, - 和\t。 + 在描述的字符输入转义中,XQuery 仅支持 \n\r\t @@ -6520,7 +6382,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - XQuery没有前瞻或后顾约束,也没有在中描述的任何约束转义。 + XQuery没有先行或后行约束,也没有在中描述的任何约束转义。 @@ -6540,7 +6402,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); XQuery的s(允许点匹配换行符) 和m(允许^ - 和$匹配换行符)标志提供 + 和$在换行处匹配)标志提供 与POSIX的npw标志相同的行为,但它们 匹配POSIX的sm标志的行为。 @@ -6571,11 +6433,11 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 数据类型格式化函数 - formatting + 格式化 - PostgreSQL格式化函数提供一套强大的工具用于把各种数据类型 (日期/时间、整数、浮点、数字) 转换成格式化的字符串以及反过来从格式化的字符串转换成 指定的数据类型。列出了这些函数。这些函数都遵循一个公共的调用规范: 第一个参数是待格式化的值,而第二个是一个定义输出或输入格式的模板。 + PostgreSQL格式化函数提供一套强大的工具用于把各种数据类型 (日期/时间、整数、浮点数、数值) 转换成格式化的字符串以及反过来从格式化的字符串转换成 指定的数据类型。列出了这些函数。这些函数都遵循一个公共的调用规范: 第一个参数是待格式化的值,而第二个是一个定义输出或输入格式的模板。 @@ -6626,7 +6488,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); text - 根据给定的格式将间隔转换为字符串。 + 根据给定的格式将时间间隔转换为字符串。 to_char(interval '15h 2m 12s', 'HH24:MI:SS') @@ -6682,7 +6544,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); numeric - 根据给定的格式将字符串转换为数字。 + 根据给定的格式将字符串转换为数值。 to_number('12,454.8-', '99G999D9S') @@ -6723,7 +6585,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 展示了可以用于格式化日期和时间值的模版。 + 展示了可以用于格式化日期和时间值的模板模式。
@@ -6806,24 +6668,24 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); SSSS, SSSSS - 午夜后的秒 (0–86399) + 自午夜起的秒数 (0–86399) AM, am, - PM or pm - 正午指示器(不带句号) + PMpm + 上午/下午标记(不带句点) A.M., a.m., - P.M. or p.m. - 正午指示器(带句号) + P.M.p.m. + 上午/下午标记(带句点) Y,YYY - 带逗号的年(4 位或者更多位) with comma + 带逗号的年(4 位或者更多位) @@ -6880,17 +6742,17 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); MONTH - 全大写形式的月名(空格补齐到 9 字符) + 大写的月份全称(空格补齐到 9 字符) Month - 全首字母大写形式的月名(空格补齐到 9 字符) + 首字母大写的月份全称(空格补齐到 9 字符) month - 全小写形式的月名(空格补齐到 9 字符) + 小写的月份全称(空格补齐到 9 字符) @@ -6915,72 +6777,72 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); DAY - 全大写形式的日名(空格补齐到 9 字符) + 大写的星期全称(空格补齐到 9 字符) Day - 全首字母大写形式的日名(空格补齐到 9 字符) + 首字母大写的星期全称(空格补齐到 9 字符) day - 全小写形式的日名(空格补齐到 9 字符) + 小写的星期全称(空格补齐到 9 字符) DY - 简写的大写形式的日名(英语 3 字符,本地化长度可变) + 大写的星期简称(英语 3 字符,本地化长度可变) Dy - 简写的首字母大写形式的日名(英语 3 字符,本地化长度可变) + 首字母大写的星期简称(英语 3 字符,本地化长度可变) dy - 简写的小写形式的日名(英语 3 字符,本地化长度可变) + 小写的星期简称(英语 3 字符,本地化长度可变) DDD - 一年中的日(001–366) + 年内日序数(001–366) IDDD - ISO 8601 周编号方式的年中的日 (001–371; 年的第 1 日时第一个 ISO 周的周一) + ISO 8601 周编号方式的年中的日 (001–371; 年的第 1 日是第一个 ISO 周的周一) DD - 月中的日 (01–31) + 月内日序数 (01–31) D - 周中的日,周日 (1) 到周六 (7) + 星期几,周日 (1) 到周六 (7) ID - 周中的 ISO 8601 日,周一 (1) 到周日 (7) + ISO 8601 星期几,周一 (1) 到周日 (7) W - 月中的周 (1–5) (第一周从该月的第一天开始) + 月内周序数 (1–5) (第一周从该月的第一天开始) WW - 年中的周数 (1–53) (第一周从该年的第一天开始) + 年中的周编号 (1–53) (第一周从该年的第一天开始) IW - ISO 8601 周编号方式的年中的周数 (01–53; 新的一年的第一个周四在第一周) + ISO 8601 周编号方式的年中的周编号 (01–53; 新的一年的第一个周四在第一周) @@ -7030,24 +6892,24 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); OF - 从UTC开始的时区偏移(仅在to_char中支持) + 相对于 UTC 的时区偏移(仅在to_char中支持)
- 修饰语可以被应用于模板模式来修改它们的行为。例如,FMMonth就是带着FM修饰语的Month模式。展示了可用于日期/时间格式化的修饰语模式。 + 修饰符可以被应用于模板模式来修改它们的行为。例如,FMMonth就是带着FM修饰符的Month模式。展示了可用于日期/时间格式化的修饰符模式。 - 用于日期/时间格式化的模板模式修饰语 + 用于日期/时间格式化的模板模式修饰符 - 修饰语 + 修饰符 描述 示例 @@ -7055,37 +6917,37 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - FM prefix + FM 前缀 填充模式(抑制前导零和填充的空格) FMMonth - TH suffix + TH 后缀 大写形式的序数后缀 - DDTH, e.g., 12TH + DDTH,例如, 12TH - th suffix + th 后缀 小写形式的序数后缀 - DDth, e.g., 12th + DDth,例如, 12th - FX prefix - 固定的格式化全局选项(见使用须知) + FX 前缀 + 固定格式全局选项(见使用须知) FX Month DD Day - TM prefix - 翻译模式(基于使用本地化的日和月名) + TM 前缀 + 翻译模式(基于使用本地化的星期名和月份名) TMMonth - SP suffix + SP 后缀 拼写模式(未实现) DDSP @@ -7102,8 +6964,8 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); FM抑制了在模式输出中添加前导零和尾随空格的行为,这些前导零和尾随空格 本来会被添加以使输出成为固定宽度。在PostgreSQL中, - FM仅修改下一个规范,而在Oracle中FM影响所有后续 - 规范,并且重复的FM修饰符切换填充模式的开启和关闭。 + FM仅修改下一个格式说明,而在Oracle中FM影响所有后续 + 格式说明,并且重复的FM修饰符切换填充模式的开启和关闭。 @@ -7161,10 +7023,10 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 一个TZH模板模式可以匹配有符号数。 - 没有FX选项,减号可能会有歧义,并且可能被解释为分隔符。 - 此歧义解决如下:如果模板字符串中TZH之前的分隔符数量少于输入字符串中减号之前的分隔符数量, - 则减号被解释为TZH的一部分。 - 否则,减号被视为值之间的分隔符。 + 没有FX选项,负号可能会有歧义,并且可能被解释为分隔符。 + 此歧义解决如下:如果模板字符串中TZH之前的分隔符数量少于输入字符串中负号之前的分隔符数量, + 则负号被解释为TZH的一部分。 + 否则,负号被视为值之间的分隔符。 例如,to_timestamp('2000 -10', 'YYYY TZH')匹配 -10TZH,但 to_timestamp('2000 -10', 'YYYY  TZH') @@ -7175,12 +7037,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 普通文本允许在to_char模板中,并且将被直接输出。您可以将子字符串放在双引号中, - 以强制将其解释为文字文本,即使它包含模板模式。例如,在'"Hello Year "YYYY'中, - YYYY将被年份数据替换,但Year中的单个Y不会被替换。 - 在to_dateto_numberto_timestamp中, - 文本和双引号字符串会导致跳过字符串中包含的字符数;例如"XX"跳过两个输入字符 - (无论它们是否为XX)。 + 普通文本可以出现在to_char模板中,并会按字面输出。可以用双引号括起子串,使其即使包含模式关键字也强制按字面文本解释。例如,在'"Hello Year "YYYY'中,YYYY会被年份数据替换,但Year中单独的Y不会被替换。在to_dateto_numberto_timestamp中,字面文本和双引号字符串会跳过与该字符串所含字符数相同数量的输入字符;例如,"XX"跳过两个输入字符(无论它们是否为XX)。 @@ -7199,7 +7056,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 如果您想在输出中使用双引号,必须在其前面加上反斜杠,例如'\"YYYY Month\"' - 反斜杠在双引号之外不起特殊作用。在双引号字符串内部,反斜杠会使下一个字符被直接解释,无论是什么(但除非下一个字符是双引号或另一个反斜杠,否则没有特殊效果)。 + 反斜杠在双引号之外不起特殊作用。在双引号字符串内部,反斜杠会使下一个字符被按字面解释,无论是什么(但除非下一个字符是双引号或另一个反斜杠,否则没有特殊效果)。 @@ -7262,14 +7119,14 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 年份、周数和星期几:例如to_date('2006-42-4', 'IYYY-IW-ID') + 年份、周编号和星期几:例如to_date('2006-42-4', 'IYYY-IW-ID') 返回日期2006-10-19。 如果省略星期几,则假定为1(星期一)。 - 年份和年内天数:例如to_date('2006-291', 'IYYY-IDDD')也返回2006-10-19。 + 年份和年内日序数:例如to_date('2006-291', 'IYYY-IDDD')也返回2006-10-19 @@ -7277,14 +7134,14 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 尝试使用ISO 8601周编号字段和公历日期字段的混合输入日期是荒谬的,并将导致错误。 - 在ISO 8601周编号年的背景下,月份日期的概念没有意义。 + 在ISO 8601周编号年的背景下,月份月内日序数的概念没有意义。 在公历年的背景下,ISO周没有意义。 - 当to_date拒绝混合使用公历和ISO周编号日期字段时, - to_char不会,因为输出格式规范如YYYY-MM-DD (IYYY-IDDD)可能很有用。 + 虽然to_date会拒绝混合使用公历和ISO周编号日期字段, + 但to_char不会,因为输出格式规范如YYYY-MM-DD (IYYY-IDDD)可能很有用。 但要避免编写类似IYYY-MM-DD的内容;那会在年初附近产生令人惊讶的结果。 (有关更多信息,请参见。) @@ -7303,7 +7160,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 这是一个更复杂的示例: to_timestamp('15:12:02.020.001230', 'HH24:MI:SS.MS.US') - 是15小时,12分钟和2秒 + 20毫秒 + 1230微秒 = 2.021230秒。 + 为15小时12分钟,秒数为2秒 + 20毫秒 + 1230微秒 = 2.021230秒。 @@ -7311,7 +7168,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); to_char(..., 'ID')的星期几编号与extract(isodow from ...)函数匹配, - 但to_char(..., 'D')的不匹配extract(dow from ...)的星期编号。 + 但to_char(..., 'D')的不匹配extract(dow from ...)的星期几编号。 @@ -7328,12 +7185,12 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 展示了可以用于格式化数字值的模版模式。 + 展示了可以用于格式化数值的模板模式。
- 用于数字格式化的模板模式 + 用于数值格式化的模板模式 @@ -7346,21 +7203,21 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 9 - 数位(如果无意义可以被删除) + 数位(非有效位可以被省略) 0 - 数位(即便没有意义也不会被删除) + 数位(即便是非有效位也不会被省略) - . (period) + .(句点) 小数点 - , (comma) + ,(逗号) 分组(千)分隔符 @@ -7371,22 +7228,22 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); S - 带符号的数字(使用区域) + 紧贴数值的正负号(使用区域设置) L - 货币符号(使用区域) + 货币符号(使用区域设置) D - 小数点(使用区域) + 小数点(使用区域设置) G - 分组分隔符(使用区域) + 分组分隔符(使用区域设置) @@ -7410,7 +7267,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - TH or th + THth 序数后缀 @@ -7428,7 +7285,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}');
- 数字格式化的使用注意事项: + 数值格式化的使用注意事项: @@ -7444,14 +7301,14 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 如果格式提供的小数位数少于被格式化的数字,则to_char()将会将数字四舍五入到指定的小数位数。 + 如果格式指定的小数位数少于被格式化数值的小数位数,to_char()会将该数值舍入到指定的小数位数。 - 模式字符SLDG表示当前区域设置定义的符号、货币符号、小数点和千位分隔符字符 + 模式字符SLDG表示当前区域设置定义的正负号、货币符号、小数点和千位分隔符字符 (参见)。模式字符句点和逗号表示这些确切字符,具有小数点和千位分隔符的含义,不受区域设置影响。 @@ -7460,15 +7317,14 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 如果在to_char()的模式中没有明确指定符号,将为符号保留一列,并将其锚定到(出现在)数字的左侧。 - 如果S出现在一些9的左侧,它也将锚定到数字。 + 如果to_char()的模式中没有明确指定正负号的位置,就会为正负号保留一列,并使其紧贴数值(紧靠数值左侧)。如果S紧邻若干个9的左侧,它同样会紧贴数值。 - 使用SGPLMI格式化的符号不与数字绑定; + 使用SGPLMI格式化的正负号不紧贴数值; 例如,to_char(-12, 'MI9999')会产生'-  12', 但to_char(-12, 'S9999')会产生'  -12'。 (Oracle实现不允许在9之前使用MI,而是要求9MI之前。) @@ -7495,7 +7351,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); to_number函数中,如果使用非数据模板模式,如LTH, - 则会跳过相应数量的输入字符,无论它们是否与模板模式匹配,除非它们是数据字符(即数字、符号、小数点或逗号)。 + 则会跳过相应数量的输入字符,无论它们是否与模板模式匹配,除非它们是数据字符(即数字、正负号、小数点或逗号)。 例如,TH会跳过两个非数据字符。 @@ -7506,7 +7362,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); Vto_char一起, 将输入值乘以10^n, 其中n是跟在V后面的数字位数。 - Vto_number一起以类似的方式除法。 + Vto_number一起以类似的方式进行除法。 to_charto_number不支持与小数点结合使用的V (例如,不允许使用99.9V99)。 @@ -7522,17 +7378,17 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}');
- 某些修饰语可以被应用到任何模板来改变其行为。例如,FM99.99是带有FM修饰语的99.99模式。中展示了用于数字格式化模式修饰语。 + 某些修饰符可以被应用到任何模板来改变其行为。例如,FM99.99是带有FM修饰符的99.99模式。中展示了用于数值格式化的模式修饰符。 - 用于数字格式化的模板模式修饰语 + 用于数值格式化的模板模式修饰符 - 修饰语 + 修饰符 描述 示例 @@ -7540,19 +7396,19 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - FM prefix - 填充模式(抑制拖尾零和填充的空白) + FM 前缀 + 填充模式(抑制尾随零和填充的空白) FM99.99 - TH suffix + TH 后缀 大写序数后缀 999TH - th suffix + th 后缀 小写序数后缀 999th @@ -7736,10 +7592,10 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 时间/日期函数和操作符 + 日期/时间函数和操作符 - 展示了可用于处理日期/时间值的函数,其细节在随后的小节中描述。演示了基本算术操作符 (+*等)的行为。 而与格式化相关的函数,可以参考。你应该很熟悉中的日期/时间数据类型的背景知识。 + 展示了可用于处理日期/时间值的函数,其细节在随后的小节中描述。演示了基本算术操作符 (+*等)的行为。 而与格式化相关的函数,可以参考。你应当熟悉中的日期/时间数据类型的背景知识。 @@ -7825,7 +7681,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); interval - 添加时间间隔 + 将两个时间间隔相加 interval '1 day' + interval '1 hour' @@ -7867,7 +7723,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); interval - 取否一个时间间隔 + 对时间间隔取负 - interval '23 hours' @@ -7881,7 +7737,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); integer - 减去日期,生成经过的天数 + 将两个日期相减,得到相隔的天数 date '2001-10-01' - date '2001-09-28' @@ -7923,7 +7779,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); interval - 减去时间 + 将两个时间相减 time '05:00' - time '03:00' @@ -7965,7 +7821,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); interval - 减去时间间隔 + 将两个时间间隔相减 interval '1 day' - interval '1 hour' @@ -7979,12 +7835,12 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); interval - 减去时间戳(将24小时间隔转换为天数,类似于justify_hours() - 时间戳 '2001-09-29 03:00' - 时间戳 '2001-07-27 12:00' - 63 天 15:00:00 + timestamp '2001-09-29 03:00' - timestamp '2001-07-27 12:00' + 63 days 15:00:00 @@ -7994,7 +7850,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); interval - 将时间间隔乘以数量 + 将时间间隔乘以一个标量 interval '1 second' * 900 @@ -8016,7 +7872,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); interval - 用时间间隔除以数量 + 将时间间隔除以一个标量 interval '1 hour' / 1.5 @@ -8057,7 +7913,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); interval - 减去参数,生成一个使用年和月,而不是只用日的符号化的结果 + 将两个参数相减,生成一个使用年和月,而不是只用日的符号化的结果 age(timestamp '2001-04-10', timestamp '1957-06-13') @@ -8071,7 +7927,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); interval - 从 current_date 减去参数(在午夜) + 从current_date(午夜时刻)减去参数 age(timestamp '1957-06-13') @@ -8122,7 +7978,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); time with time zone - 一天中的当前时间;参见 + 一天中的当前时刻;参见 current_time @@ -8136,7 +7992,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); time with time zone - 一天中的当前时间;有限精度;参见 + 一天中的当前时刻,精度受限;参见 current_time(2) @@ -8153,7 +8009,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); timestamp with time zone - 当前日期和时间 (当前事务的开始);参见 + 当前日期和时间(当前事务开始时);参见 current_timestamp @@ -8167,7 +8023,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); timestamp with time zone - 当前日期和时间 (当前事务的开始);有限精度;参见 + 当前日期和时间(当前事务开始时),精度受限;参见 current_timestamp(0) @@ -8198,7 +8054,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); double precision - 获取时间戳字段 (等同于 extract);参见 + 获取时间戳子字段 (等同于 extract);参见 date_part('hour', timestamp '2001-02-16 20:38:40') @@ -8305,7 +8161,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); boolean - 测试有限日期(不是+/-无限) + 测试日期是否有限(不是正负无穷) isfinite(date '2001-02-16') @@ -8319,7 +8175,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); boolean - 测试有限时间戳(不是+/-无限) + 测试时间戳是否有限(不是正负无穷) isfinite(timestamp 'infinity') @@ -8386,7 +8242,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); interval - 使用 justify_daysjustify_hours调整时间间隔; 通过额外的符号调整 + 使用 justify_daysjustify_hours调整时间间隔,并额外调整符号 justify_interval(interval '1 mon -1 hour') @@ -8403,7 +8259,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); time - 一天中当前时间;参见 + 一天中的当前时刻;参见 localtime @@ -8417,7 +8273,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); time - 一天中的当前时间,有限精度;参见 + 一天中的当前时刻,精度受限;参见 localtime(0) @@ -8434,7 +8290,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); timestamp - 当前日期和时间(当前事务的开始);参见 + 当前日期和时间(当前事务开始时);参见 localtimestamp @@ -8448,7 +8304,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); timestamp - 当前日期和时间(当前事务的开始);有限精度;参见 + 当前日期和时间(当前事务开始时),精度受限;参见 localtimestamp(2) @@ -8576,7 +8432,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); timestamp with time zone - 当前日期和时间(当前事务的开始);参见 + 当前日期和时间(当前事务开始时);参见 now() @@ -8593,7 +8449,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); timestamp with time zone - 当前日期和时间(当前语句的开始);参见 + 当前日期和时间(当前语句开始时);参见 statement_timestamp() @@ -8628,7 +8484,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); timestamp with time zone - 当前日期和时间(当前事务的开始);参见 + 当前日期和时间(当前事务开始时);参见 transaction_timestamp() @@ -8645,7 +8501,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); timestamp with time zone - 将Unix纪元转换为带时区的时间戳(从1970-01-01 00:00:00+00开始的秒) + 将 Unix 纪元时间(自 1970-01-01 00:00:00+00 起的秒数)转换为带时区的时间戳 to_timestamp(1284352323) @@ -8665,7 +8521,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); (start1, end1) OVERLAPS (start2, end2) (start1, length1) OVERLAPS (start2, length2) - 这个表达式在两个时间域(用它们的端点定义)重叠的时候得到真,当它们不重叠时得到假。端点可以用一对日期、时间或者时间戳来指定;或者是用一个后面跟着一个间隔的日期、时间或时间戳来指定。当一对值被提供时,起点或终点都可以被写在前面,OVERLAPS会自动地把较早的值作为起点。每一个时间段被认为是表示半开的间隔start <= time < end,除非startend相等,这种情况下它表示单个时间实例。例如这表示两个只有一个共同端点的时间段不重叠。 + 这个表达式在两个时间段(用它们的端点定义)重叠的时候得到真,当它们不重叠时得到假。端点可以用一对日期、时间或者时间戳来指定;或者是用一个后面跟着一个间隔的日期、时间或时间戳来指定。当一对值被提供时,起点或终点都可以被写在前面,OVERLAPS会自动地把较早的值作为起点。每一个时间段被认为是表示半开区间start <= time < end,除非startend相等,这种情况下它表示单个时刻。例如这表示两个只有一个共同端点的时间段不重叠。 @@ -8684,16 +8540,13 @@ SELECT (DATE '2001-10-30', DATE '2001-10-30') OVERLAPS - 当把一个interval值添加到timestamp with time zone上(或从中减去)时,天这一部分会按照指定的天数增减该timestamp with time zone的日期,同时保持一天中的时间不变。 - 对于跨越夏令时变更的情况(当会话时区被设置为能够识别 DST 的时区时),这意味着interval '1 day'并不一定等于interval '24 hours'。 - 例如,当会话的时区设置为America/Denver时: + 当把一个interval值加到某个时间戳上(或从该时间戳中减去一个interval值)时,如果该时间戳为timestamp with time zone类型,天数部分会相应增加或减少timestamp with time zone的日期,变化天数为所指定的天数,而一天中的时刻保持不变。当跨越夏令时变化时(会话时区设为识别夏令时的时区),这意味着interval '1 day'不一定等于interval '24 hours'。例如,当会话时区设置为America/Denver SELECT timestamp with time zone '2005-04-02 12:00:00-07' + interval '1 day'; 结果:2005-04-03 12:00:00-06 SELECT timestamp with time zone '2005-04-02 12:00:00-07' + interval '24 hours'; 结果:2005-04-03 13:00:00-06 - - 发生这种情况是因为在America/Denver时区,夏令时在2005-04-03 02:00:00发生切换,导致跳过了一个小时。 +出现这种情况,是因为夏令时变化跳过了一个小时;变化发生的时间为2005-04-03 02:00:00,所在时区为America/Denver @@ -8701,15 +8554,9 @@ SELECT timestamp with time zone '2005-04-02 12:00:00-07' + interval '24 hours'; - 日期和时间戳的减法也可能会很复杂。执行减法的一种概念上很简单的方法是,使用 - EXTRACT(EPOCH FROM ...)把每个值都转换成秒数,然后执行减法, - 这样会得到两个值之间的数。这种方法将会适应每个月中天数、 - 时区改变和夏令时调整。使用-操作符的日期或时间 - 戳减法会返回值之间的天数(24小时)以及时/分/秒,也会做同样的调整。 - age函数会返回年、月、日以及时/分/秒,执行按域的减法,然后对 - 负值域进行调整。下面的查询展示了这些方法的不同。示例中的结果由 - timezone = 'US/Eastern'产生,这使得两个使用的日期之间存在着夏令 - 时的变化: + 日期和时间戳的减法也可能很复杂。一种概念上简单的方法是,先用EXTRACT(EPOCH FROM ...)将各值转换为秒数,然后将结果相减;这样得到的是两个值之间的数。这种方法会针对每个月的天数、时区变化和夏令时变化进行调整。 + 用-操作符将日期或时间戳值相减,会返回两个值之间的天数(每一天为 24 小时)和时/分/秒,也会作相同的调整。age函数返回年、月、日和时/分/秒,它会逐字段相减,然后调整负值字段。 + 以下查询显示了这些方法的差异。示例结果在timezone = 'US/Eastern'设置下产生;所用的两个日期之间发生了夏令时切换: @@ -8761,7 +8608,7 @@ EXTRACT(field FROM source) - 这个世纪;对于interval值,年份字段除以100 + 世纪;对于interval值,年份字段除以100 @@ -8784,7 +8631,7 @@ SELECT EXTRACT(CENTURY FROM INTERVAL '2001 years'); - 月份的日期(1–31);对于interval值,表示天数 + 一个月中的第几天(1–31);对于interval值,表示天数 @@ -8837,7 +8684,7 @@ SELECT EXTRACT(DOW FROM TIMESTAMP '2001-02-16 20:38:40'); - 一年中的日子(1-365/366) + 一年中的第几天(1–365/366) @@ -8852,7 +8699,7 @@ SELECT EXTRACT(DOY FROM TIMESTAMP '2001-02-16 20:38:40'); - 对于timestamp with time zone值,自1970-01-01 00:00:00 UTC以来的秒数(负值表示该时间戳之前的时间); + 对于timestamp with time zone值,自1970-01-01 00:00:00 UTC以来的秒数(早于该时刻的时间戳对应负值); 对于datetimestamp值,自1970-01-01 00:00:00以来的名义秒数,不考虑时区或夏令时规则; 对于interval值,间隔中的总秒数 @@ -8876,8 +8723,8 @@ SELECT to_timestamp(982384720.12); - 注意,将to_timestamp应用于从datetimestamp值中提取的时代可能会产生误导性的结果: - 结果将有效地假定原始值是以UTC时间给出的,这可能并非事实。 + 注意,将to_timestamp应用于从datetimestamp值中提取的 epoch 值可能会产生误导性的结果: + 结果实际上会假定原始值是以UTC时间给出的,这可能并非事实。 @@ -8933,8 +8780,7 @@ SELECT EXTRACT(ISOYEAR FROM DATE '2006-01-02'); - 每个ISO 8601周编号年从包含1月4日的星期一开始,因此在一月初或十二月底,ISO年可能与格里高利年不同。 - 有关更多信息,请参见week字段。 + 每个 ISO 8601 周编号年都从包含 1 月 4 日的那一周的星期一开始,因此在 1 月初或 12 月末,ISO 年可能与格里高利年不同。更多信息请参见 week 字段。 @@ -8977,7 +8823,7 @@ SELECT EXTRACT(MICROSECONDS FROM TIME '17:12:28.5'); - 千年; 对于interval值,年份字段除以1000 + 千年; 对于interval值,年份字段除以1000 @@ -8988,7 +8834,7 @@ SELECT EXTRACT(MILLENNIUM FROM INTERVAL '2001 years'); - 20世纪的年份在第二个千年。第三个千年从2001年1月1日开始。 + 1900 年代的年份属于第二个千年。第三个千年始于 2001 年 1 月 1 日。 @@ -8998,7 +8844,7 @@ SELECT EXTRACT(MILLENNIUM FROM INTERVAL '2001 years'); - 第二个字段,包括小数部分,乘以1000。请注意,这包括完整的秒数。 + 秒字段,包括小数部分,乘以1000。请注意,这包括完整的秒数。 @@ -9028,7 +8874,7 @@ SELECT EXTRACT(MINUTE FROM TIMESTAMP '2001-02-16 20:38:40'); - 月份在一年中的编号(1-12);对于interval值,月份模12的余数(0-11) + 月份在一年中的编号(1–12);对于interval值,月份模12的余数(0–11) @@ -9047,7 +8893,7 @@ SELECT EXTRACT(MONTH FROM INTERVAL '2 years 13 months'); - 日期所在的年份季度(1-4) + 日期所在的年份季度(1–4) @@ -9089,7 +8935,7 @@ SELECT EXTRACT(SECOND FROM TIME '17:12:28.5'); - 时间区偏移的小时组件 + 时区偏移的小时部分 @@ -9099,7 +8945,7 @@ SELECT EXTRACT(SECOND FROM TIME '17:12:28.5'); - 时间区偏移的分钟组件 + 时区偏移的分钟部分 @@ -9109,16 +8955,11 @@ SELECT EXTRACT(SECOND FROM TIME '17:12:28.5'); - 一年中ISO 8601周编号周的数量。根据定义,ISO周从周一开始, - 一年的第一周包含该年的1月4日。换句话说,一年的第一个星期四在该年的第1周。 + 一年中按ISO 8601 周编号体系计算的周序号。根据定义,ISO 周从周一开始,一年的第一周包含该年的 1 月 4 日。换句话说,一年的第一个星期四在该年的第 1 周。 - 在ISO周编号系统中,早年1月的日期可能属于前一年的第52周或第53周,而 - 晚年12月的日期可能属于下一年的第一周。例如,2005-01-01 - 属于2004年的第53周,2006-01-01 属于2005年的第52周, - 而2012-12-31 属于2013年的第一周。建议同时使用 - isoyear 字段和week以获得一致的结果。 + 在 ISO 周编号体系中,1 月初的日期可能属于前一年的第 52 周或第 53 周,而 12 月末的日期可能属于下一年的第一周。例如,2005-01-01属于 2004 年的第 53 周,2006-01-01属于 2005 年的第 52 周,而2012-12-31属于 2013 年的第一周。建议将isoyear字段与week一起使用,以获得一致的结果。 @@ -9133,7 +8974,7 @@ SELECT EXTRACT(WEEK FROM TIMESTAMP '2001-02-16 20:38:40'); - 年份字段。请记住,没有0 AD,所以要小心地从AD年中减去BC年。 + 年份字段。请记住,没有0 AD,所以把BC年份从AD年份中减去时需要小心。 @@ -9160,7 +9001,7 @@ SELECT EXTRACT(MINUTES FROM INTERVAL '80 minutes'); - 当输入值为 +/-Infinity 时,extract对于单调增的域(epochjulianyearisoyeardecadecentury以及millennium)返回 +/-Infinity。对于其他域返回 NULL。PostgreSQL 9.6 之前的版本对所有输入无穷的情况都返回零。 + 当输入值为 +/-Infinity 时,extract对于单调递增的字段(epochjulianyearisoyeardecadecentury以及millennium)返回 +/-Infinity。对于其他字段返回 NULL。PostgreSQL 9.6 之前的版本对所有输入无穷的情况都返回零。 @@ -9169,15 +9010,12 @@ SELECT EXTRACT(MINUTES FROM INTERVAL '80 minutes'); - 在传统的Ingres上建模的date_part函数等价于SQL标准函数extract: + date_part函数仿照传统的Ingres实现,后者对应SQL标准的extract函数: date_part('field', source) - 请注意这里的field参数必须是一个串值,而不是一个名字。 - 有效的date_part域名 和extract相同。 - 由于历史原因,date_part函数返回double precision类型的值。 - 这可能导致在某些使用中损失精度。 - 建议使用extract替代。 + 注意,此处的field参数必须是字符串值,而不能是名称。date_part的有效字段名与extract相同。 + 由于历史原因,date_part函数返回double precision类型的值,可能在某些用途中损失精度。建议改用extract @@ -9204,11 +9042,12 @@ SELECT date_part('hour', INTERVAL '4 hours 3 minutes'); date_trunc(field, source [, time_zone ]) - source是类型timestampinterval的值表达式(类型datetime的值都分别被自动转换成timestamp, timestamp with time zone,或者interval)。field选择对输入值选用什么样的精度进行截断。返回的值是timestamp, timestamp with time zone,类型或者所有小于选定的 精度的域都设置为零(或者一,对于日期和月份)的interval。 + sourcetimestamptimestamp with time zoneinterval类型的值表达式。(datetime类型的值会分别自动转换为timestampinterval。) + field选择输入值的截断精度。返回值同样为timestamptimestamp with time zoneinterval类型,其中低于所选精度的所有字段都设为零(日和月则设为一)。 - field的有效值是∶ + field的有效值是: microseconds milliseconds @@ -9227,7 +9066,7 @@ date_trunc(field, source [ - 当输入值的类型为timestamp with time zone时。截断是针对特定时区进行的。 例如,截断为day,产生的值是 是该区域的午夜。 默认情况下,截断是在以下方面进行的 到当前的设置,但在当前的 可以提供可选的time_zone参数。以指定不同的时区。 可以指定时区名称 中描述的任何一种方式。 + 当输入值为timestamp with time zone类型时,截断会以特定时区为准;例如,截断到day会得到该时区的午夜。默认情况下,截断以当前的设置为准,但可以通过可选的time_zone参数指定其他时区。时区名称可以用中描述的任意方式指定。 @@ -9269,11 +9108,11 @@ date_bin(stride, source, < sourcetimestamptimestamp with time zone类型的值表达式。 (类型date的值会自动转换为timestamp。) strideinterval类型的值表达式。 - 返回值同样是timestamptimestamp with time zone类型,并且它标记着放置source的bin的开始。 + 返回值同样是timestamptimestamp with time zone类型,并且它表示source所在分箱的起点。 - 示例: + 示例: SELECT date_bin('15 minutes', TIMESTAMP '2020-02-11 15:44:17', TIMESTAMP '2001-01-01'); 结果: 2020-02-11 15:30:00 @@ -9292,28 +9131,24 @@ SELECT date_bin('15 minutes', TIMESTAMP '2020-02-11 15:44:17', TIMESTAMP '2001-0 - <literal>AT TIME ZONE</literal> 和 <literal>AT LOCAL</literal> + <literal>AT TIME ZONE</literal> - time zone - conversion + 时区 + 转换 AT TIME ZONE - - AT LOCAL - - - AT TIME ZONE 操作符可在带时区和不带时区的时间戳之间进行转换,也可将 time with time zone 值转换到不同的时区。 展示了它的各种变体。 + AT TIME ZONE 操作符可将不带时区的时间戳转换为时区的时间戳或反向转换,也可将 time with time zone 值转换到不同的时区。 展示了它的各种变体。
- <literal>AT TIME ZONE</literal> 和 <literal>AT LOCAL</literal> 变体 + <literal>AT TIME ZONE</literal> 变体 @@ -9346,20 +9181,6 @@ SELECT date_bin('15 minutes', TIMESTAMP '2020-02-11 15:44:17', TIMESTAMP '2001-0 - - - timestamp without time zone AT LOCAL - timestamp with time zone - - - 将给定的不带时区时间戳转换为带时区时间戳,所用时区为会话的 TimeZone 值。 - - - timestamp '2001-02-16 20:38:40' at local - 2001-02-17 03:38:40+00 - - - timestamp with time zone AT TIME ZONE zone @@ -9374,20 +9195,6 @@ SELECT date_bin('15 minutes', TIMESTAMP '2020-02-11 15:44:17', TIMESTAMP '2001-0 - - - timestamp with time zone AT LOCAL - timestamp without time zone - - - 将给定的带时区时间戳转换为无时区时间戳,所用时区为会话的 TimeZone 值。 - - - timestamp with time zone '2001-02-16 20:38:40-05' at local - 2001-02-16 18:38:40 - - - time with time zone AT TIME ZONE zone @@ -9402,22 +9209,6 @@ SELECT date_bin('15 minutes', TIMESTAMP '2020-02-11 15:44:17', TIMESTAMP '2001-0 - - - time with time zone AT LOCAL - time with time zone - - - 将给定的带时区时间转换到新的时区,所用时区为会话的 TimeZone 值。由于没有提供日期,这会使用会话 TimeZone 当前生效的 UTC 偏移量。 - - - 假定会话的 TimeZone 设为 UTC: - - - time with time zone '05:34:17-05' at local - 10:34:17+00 - -
@@ -9428,12 +9219,7 @@ SELECT date_bin('15 minutes', TIMESTAMP '2020-02-11 15:44:17', TIMESTAMP '2001-0 使用间隔值只对与 UTC 存在固定偏移量的时区有意义,因此在实践中并不常见。
- - 语法 AT LOCAL 可以作为 AT TIME ZONE local 的简写,其中 local 是会话的 TimeZone 值。 - - - - 示例(假设当前的设置为America/Los_Angeles): + 示例(假设当前设置为America/Los_Angeles): SELECT TIMESTAMP '2001-02-16 20:38:40' AT TIME ZONE 'America/Denver'; 结果:2001-02-16 19:38:40-08 @@ -9441,36 +9227,10 @@ SELECT TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40-05' AT TIME ZONE 'America/D 结果:2001-02-16 18:38:40 SELECT TIMESTAMP '2001-02-16 20:38:40' AT TIME ZONE 'Asia/Tokyo' AT TIME ZONE 'America/Chicago'; 结果:2001-02-16 05:38:40 -SELECT TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40-05' AT LOCAL; -结果:2001-02-16 17:38:40 -SELECT TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40-05' AT TIME ZONE '+05'; -结果:2001-02-17 06:38:40 -SELECT TIME WITH TIME ZONE '20:38:40-05' AT LOCAL; -结果:17:38:40-08 - - 第一个示例为缺少时区的值添加时区,并使用当前的 TimeZone 设置显示该值。 - 第二个示例将带时区的时间戳值转换到指定时区,并返回无时区的值。 - 这允许存储和显示与当前 TimeZone 设置不同的值。第三个示例将东京时间转换为芝加哥时间。第四个示例展示了 AT LOCAL 的用法。第五个示例使用数值型 UTC 偏移量作为时区。最后一个示例展示了 time with time zone 值转换为会话本地时区的结果。 - - - - 函数timezone(zone, timestamp)等效于 SQL 兼容的结构timestamp AT TIME ZONE zone。 - +
第一个示例为不带时区的值添加时区,并使用当前TimeZone设置显示该值。第二个示例将带时区的时间戳值移到指定时区,并返回不带时区的值。这样就可以存储和显示与当前TimeZone设置不同的值。第三个示例将东京时间转换为芝加哥时间。
- 结构 timestamp AT LOCAL 等效于 timestamp AT TIME ZONE local。 - - - - 函数timezone(zone, timestamp with time zone)等效于 SQL 兼容的结构timestamp with time zone AT TIME ZONE zone。 - - - - 结构 timestamp with time zone AT LOCAL 等效于 timestamp with time zone AT TIME ZONE local。 - - - - 函数timezone(zone, time with time zone)等效于 SQL 兼容的结构time with time zone AT TIME ZONE zone。结构 time with time zone AT LOCAL 等效于 time with time zone AT TIME ZONE local。 + 函数timezone(zone, timestamp)等效于符合 SQL 标准的结构timestamp AT TIME ZONE zone @@ -9479,13 +9239,13 @@ SELECT TIME WITH TIME ZONE '20:38:40-05' AT LOCAL; 当前日期/时间 - date - current + 日期 + 当前 - time - current + 时间 + 当前 @@ -9504,15 +9264,15 @@ LOCALTIMESTAMP(precision) - CURRENT_TIMECURRENT_TIMESTAMP传递带有时区的值;LOCALTIMELOCALTIMESTAMP传递的值不带时区。 + CURRENT_TIMECURRENT_TIMESTAMP返回带时区的值;LOCALTIMELOCALTIMESTAMP返回不带时区的值。 - CURRENT_TIMECURRENT_TIMESTAMPLOCALTIMELOCALTIMESTAMP可以有选择地接受一个精度参数,该精度会使结果的秒字段圆整到指定的小数位数。如果没有精度参数,结果将给出可用的全部精度。 + CURRENT_TIMECURRENT_TIMESTAMPLOCALTIMELOCALTIMESTAMP可以有选择地接受一个精度参数,该精度会使结果的秒字段舍入到指定的小数位数。如果没有精度参数,结果将给出可用的全部精度。 - 一些示例: + 一些示例: SELECT CURRENT_TIME; 结果: 14:39:53.662522-05 @@ -9534,7 +9294,7 @@ SELECT LOCALTIMESTAMP; - 许多其它数据库系统可能会更频繁地推进这些值。 + 其他数据库系统可能会更频繁地推进这些值。 @@ -9551,11 +9311,11 @@ now() - transaction_timestamp()等价于CURRENT_TIMESTAMP,但是其命名清楚地反映了它的返回值。statement_timestamp()返回当前语句的开始时刻(更准确的说是收到 客户端最后一条命令的时间)。statement_timestamp()transaction_timestamp()在一个事务的第一条命令期间返回值相同,但是在随后的命令中却不一定相同。 clock_timestamp()返回真正的当前时间,因此它的值甚至在同一条 SQL 命令中都会变化。timeofday()是一个有历史原因的PostgreSQL函数。和clock_timestamp()相似,timeofday()也返回真实的当前时间,但是它的结果是一个格式化的text串,而不是timestamp with time zone值。now()PostgreSQL的一个传统,等效于transaction_timestamp()。 + transaction_timestamp()等价于CURRENT_TIMESTAMP,但是其命名清楚地反映了它的返回值。statement_timestamp()返回当前语句的开始时刻(更准确地说,是接收到客户端最近一条命令消息的时间)。statement_timestamp()transaction_timestamp()在一个事务的第一条语句期间返回值相同,但是在随后的语句中却不一定相同。 clock_timestamp()返回真正的当前时间,因此它的值甚至在同一条 SQL 语句中都会变化。timeofday()是一个有历史原因的PostgreSQL函数。和clock_timestamp()相似,它也返回真实的当前时间,但是它的结果是一个格式化的text串,而不是timestamp with time zone值。now()PostgreSQL中与transaction_timestamp()等价的传统函数。 - 所有日期/时间类型还接受特殊的文字值now,用于指定当前的日期和时间(重申,被解释为当前事务的开始时刻)。 因此,下面三个都返回相同的结果: + 所有日期/时间数据类型也都接受特殊字面值now来指定当前日期和时间(同样解释为事务开始时间)。因此,下面三种写法都返回相同的结果: SELECT CURRENT_TIMESTAMP; SELECT now(); @@ -9567,7 +9327,7 @@ SELECT TIMESTAMP 'now'; -- 但请参阅下面的提示 当指定以后要计算的值时,不要使用第三种形式,例如在表列的DEFAULT子句中。 - 系统将在分析这个常量的时候把now转换为一个timestamp, 这样需要默认值时就会得到创建表的时间!而前两种形式要到实际使用缺省值的时候才被计算, 因为它们是函数调用。因此它们可以给出每次插入行的时刻。 + 系统将在分析这个常量的时候把now转换为一个timestamp, 这样需要默认值时就会得到创建表的时间!而前两种形式要到实际使用默认值的时候才被计算, 因为它们是函数调用。因此它们可以给出每次插入行的时刻。 (参见 。)
@@ -9590,24 +9350,24 @@ SELECT TIMESTAMP 'now'; -- 但请参阅下面的提示 - sleep + 休眠 - delay + 延迟 - 下面的这些函数可以用于让服务器进程延时执行: + 以下函数可用于延迟服务器进程的执行: pg_sleep ( double precision ) pg_sleep_for ( interval ) pg_sleep_until ( timestamp with time zone ) - pg_sleep使当前会话的进程休眠,直到过去给定的秒数。可以指定几分之一秒的延迟。 - pg_sleep_for是一个方便的函数,允许将睡眠时间指定为时间间隔。 - pg_sleep_until是一个方便的函数,用于需要特定的唤醒时间。例如: + pg_sleep使当前会话的进程休眠,直到经过指定的秒数。可以指定带小数部分的秒数作为延迟时间。 + pg_sleep_for是一个便捷函数,允许以interval指定休眠时间。 + pg_sleep_until是在需要指定唤醒时间时使用的便捷函数。例如: SELECT pg_sleep(1.5); @@ -9642,7 +9402,7 @@ SELECT pg_sleep_until('tomorrow 03:00'); 枚举支持函数 - 对于枚举类型(在中描述), 有一些函数允许更清洁的编码,而不需要为一个枚举类型硬写特定的值。它们被列在中。本例假定一个枚举类型被创建为: + 对于枚举类型(见),有些函数可以避免硬编码枚举类型中的特定值,使程序更简洁。这些函数列在中。以下示例假定枚举类型按如下方式创建: CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple'); @@ -9728,8 +9488,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple anyarray - 以一个数组返回在给定两个枚举值之间的范围。值必须来自相同的枚举类型。 - 如果第一个参数为空,其结果将从枚举类型的第一个值开始。如果第二参数为空,其结果将以枚举类型的最后一个值结束。 + 以有序数组返回两个给定枚举值之间的范围。两个值必须来自同一枚举类型。如果第一个参数为 null,结果从该枚举类型的第一个值开始;如果第二个参数为 null,结果以该枚举类型的最后一个值结束。 enum_range('orange'::rainbow, 'green'::rainbow) @@ -9749,8 +9508,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple - 请注意,除了双参数形式的enum_range外, 这些函数忽略传递给它们的具体值,它们只关心声明的数据类型。 - 空值或类型的一个特定值可以通过,并得到相同的结果。这些函数更多地被用于一个表列或函数参数,而不是一个硬写的类型名,如示例中所使用。 + 请注意,除了enum_range的双参数形式外,这些函数都忽略传入的具体值,只关心其声明的数据类型。传入 null 或该类型的某个具体值,结果都相同。通常会将这些函数用于表列或函数参数,而不是像示例那样使用硬编码的类型名。 @@ -9761,7 +9519,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple 几何类型pointboxlseglinepath、 - polygoncircle有一大堆本地支持函数和操作符,如中所示。 + polygoncircle有大量内置支持函数和操作符,如中所示。 @@ -9806,7 +9564,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple path - 连接两个打开的路径(如果其中一个路径是关闭的,则返回NULL)。 + 连接两个开放路径(如果任一路径是封闭的,则返回NULL)。 path '[(0,0),(1,1)]' + path '[(2,2),(3,3),(4,4)]' @@ -9835,12 +9593,12 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple geometric_type - 将第一个参数的每个点乘上第二个point(将点视为由实部和虚部表示的复数,并执行标准的复数乘法)。 + 将第一个参数的每个点乘上第二个point(将点视为由实部和虚部表示的复数,并执行标准的复数乘法)。 如果将第二个point解释为向量,这等价于将对象的大小和到原点的距离按向量的长度缩放,并以向量与x轴的夹角绕原点逆时针旋转。 - 适用于point, box,Rotating 用这些操作符“旋转”一个盒子,只会移动它的角点:这个盒子仍然被认为有平行于轴的边。 - 因此,盒子的大小并没有像真正的旋转那样得到保留。 - path, circle.。 + 适用于pointbox用这些操作符旋转一个矩形框,只会移动它的角点:这个矩形框仍然被认为有平行于轴的边。 + 因此,矩形框的大小并没有像真正的旋转那样得到保留。 + pathcircle path '((0,0),(1,0),(1,1))' * point '(3.0,0)' @@ -9859,7 +9617,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple 将第一个参数的每个点除以第二个point(将点视为由实部和虚部表示的复数,并执行标准的复数除法)。 - 如果将第二个point解释为向量,这等价于将物体的大小和到原点的距离按向量的长度向下缩放,并以向量与x轴的夹角围绕原点顺时针旋转。 + 如果将第二个point解释为向量,这等价于将对象的大小和到原点的距离按向量长度的倒数缩放,并以向量与x轴的夹角围绕原点顺时针旋转。 适用于 point, box, path,circle @@ -9936,7 +9694,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple box - 计算两个方框的交集,如果没有则为NULL。 + 计算两个矩形框的交集,如果没有则为NULL。 box '(2,2),(-1,-1)' # box '(1,1),(-2,-2)' @@ -9950,7 +9708,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple point - 计算第一个对象上距离第二个对象最近的点。 + 计算第二个对象上距离第一个对象最近的点。 可用于以下类型的配对: (point, box), (point, lseg), @@ -9972,7 +9730,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple 计算对象之间的距离。 - 对于所有七种几何类型,所有point与另一种几何类型的组合, + 适用于所有七种几何类型,所有point与另一种几何类型的组合, 以及以下这些额外的类型对: (box, lseg), (lseg, line), @@ -10012,7 +9770,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 第一个对象包含在第二个对象之中还是在第二个对象之上? 适用于这些类型对: + 第一个对象是否位于第二个对象内部或其上? 适用于这些类型对: (point, box), (point, lseg), (point, line), @@ -10112,7 +9870,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 第一个对象是否确定位于第二个对象下面? + 第一个对象是否严格位于第二个对象下面? 适用于 point, box, polygon, circle @@ -10127,7 +9885,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 第一个对象是否确定位于第二个对象上面? + 第一个对象是否严格位于第二个对象上面? 适用于 point, box, polygon, circle. @@ -10200,7 +9958,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 这些对象是否相交? 适用于这些类型对: + 这些对象是否相交? 适用于这些类型对: (box, box), (lseg, box), (lseg, lseg), @@ -10225,7 +9983,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 线是水平的? + 线是否水平? ?- lseg '[(-1,0),(1,0)]' @@ -10257,7 +10015,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 线是纵向的? + 线是否竖直? ?| lseg '[(-1,0),(1,0)]' @@ -10289,7 +10047,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 线是垂直的? + 两条线是否互相垂直? lseg '[(0,0),(0,1)]' ?-| lseg '[(0,0),(1,0)]' @@ -10307,7 +10065,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 线是平行的? + 两条线是否平行? lseg '[(-1,0),(1,0)]' ?|| lseg '[(-1,2),(1,2)]' @@ -10336,16 +10094,16 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple - 请注意same as操作符(~=),表示pointboxpolygoncircle类型的一般相等概念。 - 这些类型中的某些还有一个=操作符,但是=只比较相同的面积。 - 其它的标量比较操作符 (<=等等),在这些类型可用的地方,同样比较区域。 + 注意,相同操作符~=表示pointboxpolygoncircle类型通常意义上的相等。 + 某些几何类型还有=操作符,但=仅比较面积是否相等。 + 对于提供其他标量比较操作符(<=等)的类型,这些操作符同样比较面积。 - 在PostgreSQL14之前, 该点严格低于/高于比较操作符 point <<| pointpoint |>> point 分别被称为 <^>^。 + 在PostgreSQL14之前, 用于判断点是否严格位于另一点下方/上方的比较操作符 point <<| pointpoint |>> point 分别被称为 <^>^。 这些名字仍然可以使用,但是已被弃用并且最终将被移除。 @@ -10642,7 +10400,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple box - 计算内接于圆的方框。 + 计算内接于圆的矩形框。 box(circle '<(0,0),2>') @@ -10701,7 +10459,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple box - 计算两个方框的边界框。 + 计算两个矩形框的边界框。 bound_box(box '(1,1),(0,0)', box '(4,4),(3,3)') @@ -10718,7 +10476,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple circle - 计算包围方框的最小圆。 + 计算包围矩形框的最小圆。 circle(box '(1,1),(0,0)') @@ -10811,7 +10569,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple path - 将多边形转换为具有点的相同列表的封闭路径。 + 将多边形转换为具有相同点列表的封闭路径。 path(polygon '((0,0),(1,1),(2,0))') @@ -10919,7 +10677,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple polygon(circle '<(0,0),2>') - (-2,0,)&zwsp; (-1.73205080758774,0.9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999998999998989898989676868686887898999999999998989898989898999978987878787808070876888788989898989898989898989898989898989898989898968686868688768686887878989896868686889899999999999990000890000899900000000890000890000890000000000000000 + ((-2,0),&zwsp;(-1.7320508075688774,0.9999999999999999),&zwsp;(-1.0000000000000002,1.7320508075688772),&zwsp;(-1.2246063538223773e-16,2),&zwsp;(0.9999999999999996,1.7320508075688774),&zwsp;(1.732050807568877,1.0000000000000007),&zwsp;(2,2.4492127076447545e-16),&zwsp;(1.7320508075688776,-0.9999999999999994),&zwsp;(1.0000000000000009,-1.7320508075688767),&zwsp;(3.673819061467132e-16,-2),&zwsp;(-0.9999999999999987,-1.732050807568878),&zwsp;(-1.7320508075688767,-1.0000000000000009)) @@ -10933,7 +10691,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple polygon(4, circle '<(3,0),1>') - ((2,0,)&zwsp; (3,1,)&zwsp; (4,1.2246063538223773e-16), &zwsp; (3,-1)). + ((2,0),&zwsp;(3,1),&zwsp;(4,1.2246063538223773e-16),&zwsp;(3,-1)) @@ -10943,7 +10701,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple polygon - 将封闭路径转换为具有点的相同列表的多边形。 + 将封闭路径转换为具有相同点列表的多边形。 polygon(path '((0,0),(1,1),(2,0))') @@ -10956,7 +10714,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple
- 我们可以把一个point的两个组成数字当作具有索引 0 和 1 的数组访问。例如,如果t.p是一个point列,那么SELECT p[0] FROM t检索 X 坐标而 UPDATE t SET p[1] = ...改变 Y 坐标。同样,box或者lseg类型的值可以当作两个point值的数组值看待。 + 可以把一个point当作下标为 0 和 1 的数组,访问它的两个数值分量。例如,如果t.p是一个point列,那么SELECT p[0] FROM t检索 X 坐标而 UPDATE t SET p[1] = ...改变 Y 坐标。同样,box或者lseg类型的值可以当作两个point值组成的数组看待。 @@ -10972,8 +10730,8 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple 任何cidr 值都可以隐式地转换到inet;因此,下面在inet上操作的操作符和函数也可以在cidr值上工作。 - (对于inetcidr有单独的函数,这是因为这两种情况的行为应该是不同的。) - 此外,它允许将inet值转换为cidr。 + (如果inetcidr各有单独的函数,是因为这两种情况下的行为应当不同。) + 此外,也允许将inet值转换为cidr。 当这样做的时候,子网掩码右边的任何位都被静默地置零,以创建一个有效的cidr值。 @@ -11004,8 +10762,8 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean
- 子网是否严格包含在子网中?这个操作符和后续的四个操作符测试子网包含情况。 - 它们只考虑两个地址的网络部分(忽略网络掩码右侧的任何位),并确定一个网络与另一个网络相同或者是相同的子网。 + 子网是否严格包含在另一个子网中?这个操作符和后续四个操作符测试子网包含关系。 + 它们只考虑两个地址的网络部分(忽略网络掩码右侧的所有位),并判断一个网络是否与另一个网络相同,或是另一个网络的子网。 inet '192.168.1.5' << inet '192.168.1/24' @@ -11027,7 +10785,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 子网是否包含或等于子网? + 子网是否被包含于或等于子网? inet '192.168.1/24' <<= inet '192.168.1/24' @@ -11087,7 +10845,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple inet - 计算位 NOT. + 计算按位非。 ~ inet '192.168.1.6' @@ -11101,7 +10859,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple inet - 计算位 AND. + 计算按位与。 inet '192.168.1.6' & inet '0.0.0.255' @@ -11115,7 +10873,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple inet - 计算位 OR. + 计算按位或。 inet '192.168.1.6' | inet '0.0.0.255' @@ -11216,9 +10974,8 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple text - 创建缩写的文本显示格式。 - (结果与inet输出函数产生的结果相同;只有在与显式转换为text的结果相比时它才算是缩写形式, - 由于历史原因,它永远不会抑制子网掩码部分。) + 创建文本形式的缩写显示格式。 + (结果与inet输出函数产生的结果相同;只有与显式类型转换为text的结果相比时,才称为缩写形式。由于历史原因,后一种转换从不省略网络掩码部分。) abbrev(inet '10.1.0.0/32') @@ -11232,7 +10989,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple text - 创建缩写的文本显示格式。(缩写包括在子网掩码的右侧删除所有零字节;更多的示例请见 。) + 创建文本形式的缩写显示格式。(缩写形式会省略网络掩码右侧值为零的字节;更多示例见。) abbrev(cidr '10.1.0.0/16') @@ -11351,7 +11108,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple integer - 以比特位返回子网掩码长度。 + 返回子网掩码长度,以位为单位。 masklen(inet '192.168.1.5/24') @@ -11453,7 +11210,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple MAC地址类型, macaddrmacaddr8,支持中所示的常用比较操作符以及中所示的特殊函数。 - 此外,它们支持位元逻辑操作符~, &| (NOT, AND 和 OR),就像上面对IP地址所示的那样。 + 此外,它们支持按位逻辑操作符~&|(非、与和或),就像上面对IP地址所示的那样。 @@ -11517,7 +11274,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple macaddr8 - 将地址的第7位设置为1,创建所谓的modified EUI-64,用于包含在IPv6地址中。 + 将地址的第 7 位设置为 1,生成所谓的修订 EUI-64 格式,以便用于 IPv6 地址。 macaddr8_set7bit(macaddr8 '00:34:56:ab:cd:ef') @@ -11535,7 +11292,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple 文本搜索函数和操作符 - 全文搜索 + 全文检索 函数和操作符 @@ -11548,7 +11305,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple 以及 - 总结了为全文搜索提供的函数和操作符。PostgreSQL的文本搜索功能的详细解释可参考。 + 总结了为全文检索提供的函数和操作符。PostgreSQL的文本搜索功能的详细解释可参考
@@ -11628,11 +11385,11 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsvector - 连接两个tsvector。如果两个输入都包含词素位置,则相应地调整第二个输入的位置。 + 连接两个tsvector。如果两个输入都包含词位位置,则相应地调整第二个输入的位置。 'a:1 b:2'::tsvector || 'c:1 d:2 b:3'::tsvector - 'a':1'b':2,5'c':3'd':4 + 'a':1 'b':2,5 'c':3 'd':4 @@ -11670,7 +11427,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsquery - 否定tsquery,生成一个与输入查询不匹配的匹配文档的查询。 + 对tsquery取反,生成匹配那些不满足输入查询的文档的查询。 !! 'cat'::tsquery @@ -11684,7 +11441,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsquery - 构造一个短语查询,如果两个输入查询在连续的词素上匹配,该查询将进行匹配。 + 构造一个短语查询;当两个输入查询分别匹配相邻的词位时,该查询匹配。 to_tsquery('fat') <-> to_tsquery('rat') @@ -11698,7 +11455,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 第一个tsquery包含了第二个吗?(这只考虑出现在一个查询中的所有词素是否出现在另一个查询中,忽略了组合操作符。) + 第一个tsquery包含了第二个吗?(这只考虑出现在一个查询中的所有词位是否出现在另一个查询中,忽略了组合操作符。) 'cat'::tsquery @> 'cat & rat'::tsquery @@ -11712,7 +11469,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 第一个tsquery包含在第二个中吗?(这只考虑出现在一个查询中的所有词素是否出现在另一个查询中,而忽略了组合操作符。) + 第一个tsquery包含在第二个中吗?(这只考虑出现在一个查询中的所有词位是否出现在另一个查询中,而忽略了组合操作符。) 'cat'::tsquery <@ 'cat & rat'::tsquery @@ -11729,7 +11486,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple 除了这些专用操作符之外, 中所示的常用比较操作符也适用于tsvectortsquery类型。 - 它们对于文本搜索不是很有用,但是允许使用。例如,建在这些类型列上的唯一索引。 + 这些操作符对文本搜索用处不大,但可以用于其他用途,例如在这些类型的列上建立唯一索引。
@@ -11763,7 +11520,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple 将文本字符串数组转换为tsvector。 - 给定的字符串被直接用作词元,不经过进一步处理。数组元素不得为空字符串 + 给定的字符串被直接用作词位,不经过进一步处理。数组元素不得为空字符串 或NULL @@ -11834,8 +11591,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsquery - 将文本转换为tsquery,根据指定的或默认配置对单词进行标准化。 - 字符串中的任何标点符号都会被忽略(它不决定查询操作符)。结果查询匹配文本中包含所有非停止词的文档。 + 将文本转换为tsquery,根据指定的或默认配置对单词进行正规化。字符串中的任何标点符号都会被忽略(它们不决定查询操作符)。生成的查询匹配包含文本中所有非停用词的文档。 plainto_tsquery('english', 'The Fat Rats') @@ -11854,8 +11610,8 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsquery - 将文本转换为tsquery,根据指定的或默认配置对单词进行标准化。 - 字符串中的任何标点符号都会被忽略(它不决定查询操作符)。结果查询匹配包含文本中所有非停止词的短语。 + 将文本转换为tsquery,根据指定的或默认配置对单词进行正规化。 + 字符串中的任何标点符号都会被忽略(它不决定查询操作符)。结果查询匹配包含文本中所有非停用词的短语。 phraseto_tsquery('english', 'The Fat Rats') @@ -11878,8 +11634,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsquery - 将文本转换为tsquery,根据指定的或默认配置对单词进行标准化。引用的单词序列被转换为短语测试。 - or一词被理解为产生OR操作符,而破折号产生NOT操作符;其他标点符号被忽略。这类似于一些常见的网络搜索工具的行为。 + 将文本转换为tsquery,根据指定的或默认配置对单词进行正规化。带引号的单词序列被转换为短语测试。or一词产生 OR 操作符,短横线产生 NOT 操作符;其他标点符号会被忽略。这类似于一些常见网络搜索工具的行为。 websearch_to_tsquery('english', '"fat rat" or cat dog') @@ -11925,14 +11680,13 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple setweight - 为特定词元设置权重 + 为特定词位设置权重 setweight ( vector tsvector, weight "char", lexemes text[] ) tsvector - 为vector中列出的lexemes赋予指定的weight。 - lexemes中的字符串被视为词元,不经过进一步处理。不匹配vector中任何词元的字符串将被忽略。 + 为vector中列在lexemes内的元素赋予指定的weightlexemes中的字符串按原样用作词位,不经过进一步处理。不匹配vector中任何词位的字符串将被忽略。 setweight('fat:2,4 cat:3 rat:5,6B'::tsvector, 'A', '{cat,rat}') @@ -11968,7 +11722,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsquery - 将文本转换为tsquery,根据指定的或默认配置对单词进行标准化。单词必须由有效的tsquery操作符组合。 + 将文本转换为tsquery,根据指定的或默认配置对单词进行正规化。单词必须由有效的tsquery操作符组合。 to_tsquery('english', 'The & Fat & Rats') @@ -11987,7 +11741,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsvector - 将文本转换为tsvector,根据指定的或默认配置对单词进行标准化。结果中包含位置信息。 + 将文本转换为tsvector,根据指定的或默认配置对单词进行正规化。结果中包含位置信息。 to_tsvector('english', 'The Fat Rats') @@ -12009,9 +11763,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsvector - 将JSON文档中的每个字符串值转换为tsvector,根据指定的或默认配置对单词进行标准化。 - 然后将结果按文档顺序连接起来以产生输出。位置信息就像在每对字符串值之间存在一个停止词一样生成。 - (注意,当输入为jsonb时,JSON对象的字段的document order取决于实现;请观察这些示例中的差异。) + 将 JSON 文档中的每个字符串值转换为tsvector,根据指定的或默认配置对单词进行正规化。然后将结果按文档顺序连接起来以产生输出。生成位置信息时,视为每对字符串值之间存在一个停用词。(注意,当输入为jsonb时,JSON 对象字段的文档顺序取决于具体实现;请注意这些示例中的差异。) to_tsvector('english', '{"aa": "The Fat Rats", "b": "dog"}'::json) @@ -12045,15 +11797,15 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsvector - 选择filter请求的JSON文档中的每个项,并将每个项转换为tsvector,根据指定的或默认配置对单词进行标准化。 - 然后将结果按文档顺序连接起来以产生输出。位置信息就像在每对选定的项目之间存在一个停止词一样生成。 - (注意,当输入为jsonb时,JSON对象字段的document order取决于实现。) - filter必须是一个jsonb数组,其中包含0个或多个关键字: + 选择filter请求的JSON文档中的每个项,并将每个项转换为tsvector,根据指定的或默认配置对单词进行正规化。 + 然后将结果按文档顺序连接起来以产生输出。位置信息就像在每对选定的项目之间存在一个停用词一样生成。 + (注意,当输入为jsonb时,JSON对象字段的文档顺序取决于实现。) + filter必须是一个jsonb数组,其中包含0个或多个关键字: "string"(包括所有字符串值), "numeric"(包括所有数值), "boolean"(包括所有布尔值), "key"(包括所有键),或 - "all"(包括以上所有关键字)。 + "all"(包括以上所有内容)。 作为一种特殊情况,该filter也可以是这些关键字之一的简单JSON值。 @@ -12075,8 +11827,8 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsvector - 从vector中删除给定的lexeme的任何出现。 - lexeme字符串被视为原样的词元,不经过进一步处理。 + 从vector中删除给定的lexeme的所有出现。 + lexeme字符串被视为原样的词位,不经过进一步处理。 ts_delete('fat:2,4 cat:3 rat:5A'::tsvector, 'fat') @@ -12090,9 +11842,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsvector - 从vector中删除lexemes中的任何出现。 - lexemes中的字符串被视为词元,不经过进一步处理。 - 不匹配vector中任何词元的字符串将被忽略。 + 从vector中删除lexemes所列词位的所有出现。lexemes中的字符串按原样用作词位,不经过进一步处理。不匹配vector中任何词位的字符串将被忽略。 ts_delete('fat:2,4 cat:3 rat:5A'::tsvector, ARRAY['fat','rat']) @@ -12130,9 +11880,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple text - 以缩写形式显示documentquery的匹配项,该匹配项必须是原始文本,而不是tsvector。 - 在匹配查询之前,文档中的单词将根据指定的或默认的配置进行规范化。 - 中讨论了该函数的使用,还描述了可用的options。 + 以缩略形式显示querydocument中的匹配项;后者必须是原始文本,不能是tsvector。在匹配查询之前,文档中的单词将根据指定的或默认配置进行正规化。中讨论了该函数的使用,还描述了可用的options ts_headline('The fat cat ate the rat.', 'cat') @@ -12158,8 +11906,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple text - 以缩写形式显示匹配JSONdocument中字符串值中的query。 - 更多细节请参阅 。 + 以缩略形式显示query在 JSON document字符串值中的匹配项。更多细节请参见 ts_headline('{"cat":"raining cats and dogs"}'::jsonb, 'cat') @@ -12237,8 +11984,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsquery - 根据目标替换部分query,并替换通过执行SELECT命令获得的查询。 - 详情参见。 + 根据执行SELECT命令得到的目标和替换项,替换query中的相应部分。详情参见 SELECT ts_rewrite('a & b'::tsquery, 'SELECT t,s FROM aliases') @@ -12269,7 +12015,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsquery - 构造一个短语查询,用于搜索query1query2的匹配项,这些匹配项恰好出现在distance词位之间。 + 构造一个短语查询,用于搜索query1query2的匹配项,其匹配位置恰好相距distance个词位。 tsquery_phrase(to_tsquery('fat'), to_tsquery('cat'), 10) @@ -12298,7 +12044,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple unnest - for tsvector + 用于 tsvector unnest ( tsvector ) setof record @@ -12328,7 +12074,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple - 所有接受一个可选的regconfig参数的文本搜索函数在该参数被忽略时,使用由指定的配置。 + 所有接受一个可选的regconfig参数的文本搜索函数在省略该参数时,会使用由指定的配置。 @@ -12375,7 +12121,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple lexemes text[] ) - 根据指定的或默认的文本搜索配置从document中提取和标准化标记,并返回关于每个标记是如何处理的信息。 + 根据指定的或默认的文本搜索配置从document中提取和正规化词元,并返回关于每个词元是如何处理的信息。 详情参见 @@ -12393,8 +12139,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple text[] - 如果字典知道输入标记,则返回替换词位数组;如果字典知道标记,但它是停止词,则返回空数组;如果它不是已知词,则返回NULL。 - 详情参见。 + 如果词典识别输入词元,则返回由替换词位组成的数组;如果词典识别该词元,但它是停用词,则返回空数组;如果词典无法识别该词元,则返回NULL。详情参见 ts_lexize('english_stem', 'stars') @@ -12414,7 +12159,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple token text ) - 使用命名的解析器从document中提取标记。详情参见。 + 使用指定名称的解析器从document中提取词元。详情参见 ts_parse('default', 'foo - bar') @@ -12431,7 +12176,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple token text ) - 使用 OID 指定的解析器从document中提取标记。 + 使用 OID 指定的解析器从document中提取词元。 详情参见 @@ -12452,7 +12197,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple description text ) - 返回一个表,该表描述命名解析器可以识别的每种类型的标记。详情参见。 + 返回一个表,该表描述指定名称的解析器可以识别的每种类型的词元。详情参见 ts_token_type('default') @@ -12469,7 +12214,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple description text ) - 返回一个表,该表描述 OID 指定的解析器可以识别的每种标记类型。详情参见。 + 返回一个表,该表描述 OID 指定的解析器可以识别的每种词元类型。详情参见 ts_token_type(3722) @@ -12490,7 +12235,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple nentry integer ) - 执行sqlquery,该查询必须返回单个tsvector列,并返回数据中每个不同词元的统计信息。 + 执行sqlquery,该查询必须返回单个tsvector列,并返回数据中每个不同词位的统计信息。 详情参见 @@ -12517,19 +12262,16 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple - PostgreSQL包含一个用于生成UUID的函数: + PostgreSQL包含一个生成 UUID 的函数: gen_random_uuid () uuid - 这个函数返回一个版本4(随机)UUID。这是最常用的UUID类型,适合大多数应用。 - + 该函数返回版本 4(随机)UUID。这是最常用的 UUID 类型,适用于大多数应用。 - - 模块提供了额外的函数,实现了其他用于生成UUID的标准算法。 - + 模块还提供了额外的函数,用于实现其他标准 UUID 生成算法。 - PostgreSQL也为UUID提供了中展示的常用比较操作符。 + PostgreSQL也为 UUID 提供了中展示的常用比较操作符。 @@ -12967,7 +12709,7 @@ SELECT xmlexists('//town[text() = ''Toronto'']' PASSING BY VALUE 'T - 示例: + 示例: - 示例: + 示例: test', ARRAY[ARRAY['my', 'http://example.com']]); @@ -13084,7 +12826,7 @@ SELECT xpath('//mydefns:b/text()', 'test - 示例: + 示例: test', ARRAY[ARRAY['my', 'http://example.com']]); @@ -13136,8 +12878,8 @@ SELECT xpath_exists('/my:a/text()', 'test - document_expression提供了上下文。row_expression的项。 - 它必须是一个格式良好的XML文档;不接受片段/森林。BY REFBY VALUE子句 如上文所讨论的那样,被接受但被忽略了,正如在中所讨论的。 + document_expressionrow_expression提供上下文项。 + 它必须是一个良构的 XML 文档;不接受内容片段或森林。BY REFBY VALUE子句会被接受,但会被忽略,如中所述。 @@ -13186,7 +12928,7 @@ SELECT xpath_exists('/my:a/text()', 'test - 一个XML元素的字符串值是字符串值的协整,按文档的顺序。该元素中包含的所有文本节点及其子节点。字符串 元素的值是一个没有下级文本节点的元素的值是一个 空字符串(不是NULL)。任何xsi:nil属性都会被忽略。请注意,两个非文本之间的text()节点只用空格,而两个非文本 元素,并且保留了text()上的前导白格。节点不被扁平化。XPath 1.0中的string函数可以参考XPath 1.0中的 定义其他XML节点类型和非XML值的字符串值的规则。 + 一个 XML 元素的字符串值,是该元素及其所有后代中包含的文本节点按文档顺序拼接而成的字符串。没有后代文本节点的元素,其字符串值为空字符串(不是 NULL)。所有 xsi:nil 属性都会被忽略。注意,两个非文本元素之间仅含空白的 text() 节点会被保留,text() 节点的前导空白也不会被折叠。其他 XML 节点类型及非 XML 值的字符串值定义规则,可参考 XPath 1.0 的 string 函数。 @@ -13206,7 +12948,7 @@ SELECT xpath_exists('/my:a/text()', 'test - 示例: + 示例: - 下面的示例展示了多个text()节点的连接,列名作为XPath过滤器的使用,以及对空格、XML注释和处理指令的处理: + 下面的示例展示了多个text()节点的连接,列名作为XPath过滤器的使用,以及对空格、XML注释和处理指令的处理: - 本节描述: + 本节描述: @@ -13542,14 +13284,16 @@ table2-mapping - SQL/JSON路径语言 + SQL/JSON 路径语言 - 要了解有关SQL/JSON标准的更多信息,请参阅。有关PostgreSQL中支持的JSON类型的详细信息,见 。 + 要了解有关 SQL/JSON 标准的更多信息,请参阅。有关 + PostgreSQL 中支持的 JSON 类型的详细信息,见 + @@ -13704,14 +13448,13 @@ table2-mapping - 如果JSON输入没有匹配请求的正确结构,字段/元素/路径提取操作符返回NULL,而不是失败;例如,如果不存在这样的键或数组元素。 + 如果 JSON 输入没有匹配请求的正确结构,字段/元素/路径提取操作符会返回 NULL,而不是失败;例如,如果不存在这样的键或数组元素。 - 还有一些操作符仅适用于jsonb,如表所示。 - 第描述了如何使用这些操作符来有效地搜索索引的jsonb数据。 - + 还有一些操作符仅适用于jsonb,如所示。介绍了如何使用这些操作符有效地搜索已建立索引的jsonb数据。 +
@@ -13786,7 +13529,7 @@ table2-mapping boolean - 文本数组中的字符串是否作为顶级键或数组元素存在? + 文本数组中的任一字符串是否作为顶级键或数组元素存在? '{"a":1, "b":2, "c":3}'::jsonb ?| array['b', 'd'] @@ -13818,7 +13561,7 @@ table2-mapping 连接两个数组将生成一个包含每个输入的所有元素的数组。 连接两个对象将生成一个包含它们键的并集的对象,当存在重复的键时取第二个对象的值。 所有其他情况都通过将非数组输入转换为单元素数组来处理,然后按照两个数组的方式进行处理。 - 不递归操作:只有顶级数组或对象结构被合并。 + 不递归操作:只有顶级数组或对象结构会被合并。 '["a", "b"]'::jsonb || '["a", "d"]'::jsonb @@ -13837,7 +13580,7 @@ table2-mapping [{"a": "b"}, 42] - 要将一个数组作为单个条目附加到另一个数组中,请将其包装在另一个数组附加层中,例如: + 要将一个数组作为单个元素追加到另一个数组中,请先在它外面再包装一层数组,例如: '[1, 2]'::jsonb || jsonb_build_array('[3, 4]'::jsonb) @@ -13939,9 +13682,7 @@ table2-mapping - jsonpath操作符@?@@抑制以下错误:缺少对象字段或数组元素,意外的JSON项目类型,日期时间和数字错误。 - 还可以告诉以下描述的与jsonpath相关的函数来抑制这些类型的错误。 - 在搜索不同结构的JSON文档集合时,此行为可能会有所帮助。 + jsonpath操作符@?@@会抑制以下错误:缺少对象字段或数组元素、JSON 项类型不符合预期,以及日期时间和数值错误。下文介绍的jsonpath相关函数也可以设置为抑制这些类型的错误。在搜索结构各异的 JSON 文档集合时,这一行为可能很有用。 @@ -13986,14 +13727,14 @@ table2-mapping jsonb - 将任何SQL值转换为jsonjsonb。数组和组合递归地转换为数组和对象(多维数组在JSON中变成数组的数组)。 - 否则,如果存在从SQL数据类型到json的类型转换,则类型转换函数将用于执行转换; + 将任何SQL值转换为jsonjsonb。数组和复合值递归地转换为数组和对象(多维数组在JSON中变成数组的数组)。 + 否则,如果存在从SQL数据类型到json的类型转换,则类型转换函数将用于执行转换; - 例如,扩展有一个从hstorejson的转换,这样通过json创建函数转换的hstore值将被表示为json对象,而不是原始字符串值 + 例如,扩展有一个从hstorejson的类型转换,因此通过 JSON 创建函数转换的hstore值将表示为 JSON 对象,而不是基本的字符串值。 - 否则,将生成一个标量json值。对于除数字、布尔值或空值之外的任何标量,将使用文本表示,并根据需要进行转义,使其成为有效的JSON字符串值。 + 否则,将生成一个标量 JSON 值。对于除数字、布尔值或空值之外的任何标量,将使用文本表示,并根据需要进行转义,使其成为有效的JSON字符串值。 to_json('Fred said "Hi."'::text) @@ -14001,7 +13742,7 @@ table2-mapping to_jsonb(row(42, 'Fred said "Hi."'::text)) - {"f1":42,"f2":"Fred said \"Hi.\""} + {"f1": 42, "f2": "Fred said \"Hi.\""} @@ -14031,7 +13772,7 @@ table2-mapping json - 将SQL组合值转换为JSON对象。该行为与to_json相同,只是如果可选boolean参数为真,换行符将在顶级元素之间添加。 + 将SQL 复合值转换为JSON对象。该行为与to_json相同,只是如果可选boolean参数为真,换行符将在顶级元素之间添加。 row_to_json(row(1,'foo')) @@ -14080,7 +13821,7 @@ table2-mapping 根据可变参数列表构建一个JSON对象。按照惯例,参数列表由交替的键和值组成。 - 关键参数强制转换为文本;值参数按照to_jsonto_jsonb进行转换。 + 键参数会被强制转换为文本;值参数则按照to_jsonto_jsonb进行转换。 json_build_object('foo', 1, 2, row(3,'bar')) @@ -14104,8 +13845,7 @@ table2-mapping jsonb - 从文本数组构建JSON对象。该数组必须有两个维度,一个维度的成员数为偶数,在这种情况下,它们被视为交替的键/值对; - 另一个维度的成员数为二维,每个内部数组恰好有两个元素,它们被视为键/值对。所有值都转换为JSON字符串。 + 从文本数组构造 JSON 对象。该数组必须是一维且包含偶数个成员,此时将成员按交替的键/值对处理;或者是二维数组,且每个内部数组恰好有两个元素,将这两个元素作为一个键/值对。所有值都转换为 JSON 字符串。 json_object('{a, 1, b, "def", c, 3.5}') @@ -14126,7 +13866,7 @@ table2-mapping jsonb - 这种形式的json_object从单独的文本数组中成对地获取键和值。否则,它与单参数形式相同。 + 这种形式的json_object从单独的文本数组中成对地获取键和值。除此之外,它与单参数形式相同。 json_object('{a,b}', '{1,2}') @@ -14413,48 +14153,48 @@ table2-mapping anyelement - 将顶级 JSON 对象展开为具有 base 参数复合类型的行。JSON 对象将被扫描,查找名称与输出行类型列名匹配的字段,并将其值插入到输出行的对应列中。 - (不对应任何输出列名的字段将被忽略。)在典型用法中,base 的值仅为 NULL,这意味着任何不匹配对象字段的输出列都会被填充为 null。 - 但是,如果base不为NULL,那么它包含的值将用于不匹配的列。 + 将顶级 JSON 对象展开为一个行,其复合类型与base参数相同。系统会扫描该 JSON 对象,查找名称与输出行类型列名匹配的字段,并将其值插入输出中的对应列。 + (不对应任何输出列名的字段会被忽略。)在典型用法中,base的值就是NULL,这意味着凡是不匹配对象字段的输出列都会被填充为空值。 + 但是,如果base不是NULL,那么其中包含的值将用于那些不匹配的列。 - 要将JSON值转换为输出列的SQL类型,需要按次序应用以下规则: + 要将 JSON 值转换为输出列的 SQL 类型,需要依次应用以下规则: - 在所有情况下,JSON空值都会转换为SQL空值。 + 在所有情况下,JSON 空值都会转换为 SQL 空值。 - 如果输出列的类型是jsonjsonb,则会精确地重制JSON值。 + 如果输出列的类型是jsonjsonb,则 JSON 值会被原样保留。 - 如果输出列是复合(行)类型,且JSON值是JSON对象,则该对象的字段将转换为输出行类型的列,通过这些规则的递归应用程序。 + 如果输出列是复合(行)类型,且 JSON 值是 JSON 对象,则该对象的字段会通过递归应用这些规则,被转换为输出行类型的各列。 - 同样,如果输出列是数组类型,而JSON值是JSON数组,则通过这些规则的递归应用程序将JSON数组的元素转换为输出数组的元素。 + 同样,如果输出列是数组类型,而 JSON 值是 JSON 数组,则会通过递归应用这些规则,把 JSON 数组的元素转换为输出数组的元素。 - 否则,如果JSON值是字符串,则将字符串的内容提供给输入转换函数,用以确定列的数据类型。 + 否则,如果 JSON 值是字符串,则会把该字符串的内容送入该列数据类型的输入转换函数。 - 否则,JSON值的普通文本表示将被提供给输入转换函数,以确定列的数据类型。 + 否则,JSON 值的普通文本表示会被送入该列数据类型的输入转换函数。 - 虽然下面的示例使用一个常量JSON值,典型的用法是在查询的FROM子句中从另一个表侧面地引用jsonjsonb列。 - 在FROM子句中编写json_populate_record是一种很好的实践,因为提取的所有列都可以使用,而不需要重复的函数调用。 + 虽然下面的示例使用的是常量 JSON 值,但典型用法是在查询的FROM子句中,以横向方式引用另一个表中的jsonjsonb列。 + 把json_populate_record写在FROM子句中是一种良好实践,因为这样抽取出的所有列都可以直接使用,而不需要重复调用函数。 create type subrowtype as (d int, e text); @@ -14488,8 +14228,7 @@ table2-mapping setof anyelement - 将对象的顶级 JSON 数组展开为一组具有 base 参数复合类型的行。 - 对于json[b]_populate_record,将如上所述处理JSON数组的每个元素。 + 将由对象组成的顶级 JSON 数组展开为一组行,其复合类型与base参数相同。JSON 数组中的每个元素都按照上文对json[b]_populate_record的说明进行处理。 create type twoints as (a int, b int); @@ -14558,8 +14297,8 @@ table2-mapping 将顶级JSON对象数组展开为一组由AS子句定义的复合类型的行。 - (与所有返回record的函数一样,调用查询必须使用AS子句显式定义记录的结构。) - 对于json[b]_populate_record,将如上所述处理JSON数组的每个元素。 + (与所有返回record的函数一样,调用查询必须使用AS子句显式定义记录的结构。) + JSON 数组中的每个元素都按照上文对json[b]_populate_record的说明进行处理。 select * from json_to_recordset('[{"a":1,"b":"foo"}, {"a":"2","c":"bar"}]') as x(a int, b text) @@ -14585,7 +14324,7 @@ table2-mapping 返回target,将path指定的项替换为new_value, 如果create_if_missing为真(此为默认值)并且path指定的项不存在,则添加new_value。 路径中的所有前面步骤都必须存在,否则将不加改变地返回target。 - 与面向路径操作符一样,负整数出现在JSON数组末尾的path计数中。 + 与面向路径的操作符一样,path中的负整数从 JSON 数组末尾计数。 如果最后一个路径步骤是超出范围的数组索引,并且create_if_missing为真,那么如果索引为负,新值将添加到数组的开头,如果索引为正,则添加到数组的结尾。 @@ -14632,8 +14371,8 @@ table2-mapping 如果path指派的项是一个数组元素,如果 insert_after为假(此为默认值),则new_value将被插入到该项之前,如果 insert_after为真则在该项之后。 如果由path指派的项是一个对象字段,则只在对象不包含该键时才插入 new_value。 路径中的所有前面步骤都必须存在,否则将不加改变地返回target。 - 与面向路径操作符一样,负整数出现在JSON数组末尾的 path计数中。 - 如果最后一个路径步骤是超出范围的数组下标,则如果下标为负,则将新值添加到数组的开头;如果下标为正,则将新值添加到数组的结尾。 + 与面向路径的操作符一样,path中的负整数从 JSON 数组末尾计数。 + 如果最后一个路径步骤是超出范围的数组下标,那么当下标为负时,新值会被添加到数组开头;当下标为正时,新值会被添加到数组末尾。 jsonb_insert('{"a": [0,1,2]}', '{a, 1}', '"new_value"') @@ -14650,26 +14389,20 @@ table2-mapping json_strip_nulls - json_strip_nulls ( target json ,strip_in_arrays boolean ) + json_strip_nulls ( json ) json jsonb_strip_nulls - jsonb_strip_nulls ( target jsonb ,strip_in_arrays boolean ) + jsonb_strip_nulls ( jsonb ) jsonb - - 递归地删除给定 JSON 值中所有值为 null 的对象字段。如果 strip_in_arrays 为 true(默认值为 false),那么数组中的 null 元素也会被删除;否则不会删除。裸露的 null 值永远不会被删除。 - + 递归删除给定 JSON 值中所有值为 null 的对象字段。不是对象字段的 null 值保持不变。 json_strip_nulls('[{"f1":1, "f2":null}, 2, null, 3]') [{"f1":1},2,null,3] - - - jsonb_strip_nulls('[1,2,null,3,4]', true) - [1,2,3,4] @@ -14682,7 +14415,7 @@ table2-mapping boolean - 检查JSON路径是否返回指定JSON值的任何项。如果指定了vars参数,则它必须是一个JSON对象,并且它的字段提供要替换到jsonpath表达式中的名称值。 + 检查JSON路径是否返回指定JSON值的任何项。如果指定了vars参数,则它必须是一个JSON对象,并且它的字段提供要替换到jsonpath表达式中的具名值。 如果指定了silent参数并为true,函数会抑制与@?@@操作符相同的错误。 @@ -14824,7 +14557,7 @@ table2-mapping text - 将给定的JSON值转换为精美打印的,缩进的文本。 + 将给定的 JSON 值转换为经过美化并带有缩进的文本。 jsonb_pretty('[{"f1":1,"f2":null}, 2]') @@ -14857,8 +14590,8 @@ table2-mapping text - 以文本字符串形式返回顶级JSON值的类型。可能的类型有object, array,string, number,boolean, 和 null。 - (null的结果不应该与SQL NULL 混淆;参见示例。) + 以文本字符串形式返回顶级JSON值的类型。可能的类型有objectarraystringnumberbooleannull。 + (null 的结果不应与 SQL NULL 混淆;参见示例。) json_typeof('-123.4') @@ -14903,13 +14636,11 @@ table2-mapping - 要引用正在查询的JSON值(context item项),在路径表达式中使用$变量。 - 它后面可以跟着一个或多个accessor operators,这些操作符在JSON结构中逐级向下检索上下文项的子项。 - 后面的每个操作符处理前一个求值步骤的结果。 - + 要引用正在查询的 JSON 值(上下文项),请在路径表达式中使用$变量。它后面可以跟一个或多个访问操作符,沿 JSON 结构逐层向下获取上下文项的子项。每个后续操作符都处理上一步求值的结果。 + - 例如,假设你有一些你想要解析的来自GPS跟踪器的JSON数据,例如: + 例如,假设你有一些你想要解析的来自GPS跟踪器的JSON数据,例如: { "track": { @@ -14930,50 +14661,38 @@ table2-mapping - - 为了检索可用的轨迹段,你需要使用.key访问操作符来向下浏览周边的JSON对象: - + 要获取可用的轨迹片段,需要使用.key访问操作符,逐层访问外围的 JSON 对象: $.track.segments - 要检索数组的内容,通常使用[*]操作符。例如,下面的路径将返回所有可用轨道段的位置坐标: + 要检索数组的内容,通常使用[*]操作符。例如,下面的路径将返回所有可用轨迹段的位置坐标: $.track.segments[*].location - - 要只返回第一个段的坐标,可以在[]访问操作符中指定相应的下标。重新调用相对于0的JSON数组索引: - + 要仅返回第一个片段的坐标,可以在[]访问操作符中指定相应下标。注意,JSON 数组下标从 0 开始: $.track.segments[0].location - - 每个路径求值步骤的结果可以由中列出的一个或多个jsonpath操作符和方法来处理。 - 每个方法名之前必须有一个点。例如,你可以得到一个数组的大小: - + 每一步路径求值的结果都可以使用一个或多个jsonpath操作符和方法处理,它们列于。每个方法名之前都必须有一个点。例如,可以获取数组的大小: $.track.segments.size() - - 在路径表达式中使用jsonpath操作符和方法的更多示例见下面。 +有关在路径表达式中使用jsonpath操作符和方法的更多示例,见下文 - - 在定义路径时,还可以使用一个或多个与SQL中的WHERE子句类似的filter expressions。 - 过滤器表达式以问号开头,并在圆括号中提供条件: - - + 定义路径时,还可以使用一个或多个过滤表达式,其作用类似于 SQL 中的WHERE子句。过滤表达式以问号开头,并在圆括号中提供条件: ? (condition) - 过滤表达式必须在它们应该应用的路径求值步骤之后写入。该步骤的结果将被筛选,以只包括满足所提供条件的那些项。 + 过滤表达式必须在它们应该应用的路径求值步骤之后指定。该步骤的结果会经过过滤,只保留满足给定条件的项。 SQL/JSON定义了三值逻辑,因此条件可以是 true, false,或 unknownunknown值发挥与SQL NULL相同的角色,可以使用is unknown谓词进行测试。 - 进一步的路径求值步骤只使用筛选器表达式返回true的那些项。 + 进一步的路径求值步骤只使用过滤表达式返回true的那些项。 @@ -14981,113 +14700,105 @@ $.track.segments.size() 在一个过滤表达式中,@变量表示被过滤的值(也就是说,前面路径步骤的一个结果)。你可以在 @后面写访问操作符来检索组件项。 - - 例如,假设你想要检索所有高于130的心率值。你可以使用下面的表达式来实现这一点: - + 例如,假设你想检索所有高于 130 的心率值。可以用下面的表达式实现: $.track.segments[*].HR ? (@ > 130) - - 为了获得具有这些值的片段的开始时间,必须在返回开始时间之前过滤掉不相关的片段,所以过滤表达式应用于上一步,条件中使用的路径不同: - + 为了获得具有这些值的轨迹段的开始时间,必须先过滤掉不相关的轨迹段,再返回开始时间。因此,过滤表达式应用于上一步,条件中使用的路径也不同: $.track.segments[*] ? (@.HR > 130)."start time" - - 如果需要,可以按顺序使用几个过滤器表达式。例如,下面的表达式选择所有包含有相关坐标和高心率值的位置的段的开始时间: - + 如有需要,可以依次使用多个过滤表达式。例如,下面的表达式选择位置坐标符合要求且心率较高的所有轨迹段的开始时间: $.track.segments[*] ? (@.location[1] < 13.4) ? (@.HR > 130)."start time" - - 也允许在不同嵌套层级中使用过滤器表达式。下面的示例首先根据位置筛选所有的片段,然后返回这些片段的高心率值,如果适用的话: - + 也可以在不同嵌套层级使用过滤表达式。下面的示例先按位置筛选所有轨迹段,再返回这些轨迹段中的高心率值(如果存在): $.track.segments[*] ? (@.location[1] < 13.4).HR ? (@ > 130) - - 你也可以在彼此之间嵌套过滤器表达式: - + 还可以将过滤表达式相互嵌套: $.track ? (exists(@.segments[*] ? (@.HR > 130))).segments.size() +如果轨迹包含任何具有高心率值的轨迹段,该表达式返回轨迹的大小,否则返回空序列。 + + + + PostgreSQL 对 SQL/JSON 路径语言的实现与 SQL/JSON 标准有以下偏差: + + + + + 路径表达式可以是布尔谓词,尽管 SQL/JSON 标准只允许在过滤器中使用谓词。 + 这对于实现 @@ 操作符是必要的。例如, + 下面的 jsonpath 表达式在 PostgreSQL 中是有效的: + +$.track.segments[*].HR < 70 - 如果包含任何具有高心率值的片段,则该表达式返回曲目的大小,否则返回空序列。 - + + + + + 对于 like_regex 过滤器中使用的正则表达式模式,其解释方式存在一些细微差异,详见。 + + + - + 严格模式与宽松模式 当查询JSON数据时,路径表达式可能与实际的JSON数据结构不匹配。 - 试图访问不存在的对象成员或数组元素会导致结构错误。SQL/JSON路径表达式有两种处理结构错误的模式: + 试图访问不存在的对象成员或数组元素会导致结构错误。SQL/JSON路径表达式有两种处理结构错误的模式: - 不严格的(lax)(默认)—路径引擎隐式地将查询的数据适配到指定的路径。任何剩余的结构错误都将被抑制并转换为空SQL/JSON序列。 + 宽松模式(lax,默认)—路径引擎隐式地将查询的数据适配到指定的路径。任何剩余的结构错误都将被抑制并转换为空SQL/JSON序列。 - - 严格的(strict) —如果发生了结构错误,则会引发错误。 - + 严格模式(strict)— 如果发生结构错误,就会引发错误。 - 如果JSON数据不符合期望的模式,不严格的(lax)模式有助于匹配JSON文档结构和路径表达式。 - 如果操作不匹配特定操作的要求,可以自动将其包装为SQL/JSON数组,也可以在执行该操作之前将其元素转换为SQL/JSON序列来解包装。 - 此外,比较操作符会自动以lax模式打开它们的操作数,因此你可以开包即用的就能比较SQL/JSON数组。 - 大小为1的数组被认为等于它的唯一元素。只有在以下情况下才不会自动展开: + 如果 JSON 数据不符合预期模式,宽松模式有助于使 JSON 文档结构与路径表达式相匹配。如果操作数不满足某个操作的要求,可以在执行该操作之前自动将其包装为 SQL/JSON 数组,或通过将其元素转换为 SQL/JSON 序列来解包。此外,在宽松模式下,比较操作符会自动解包其操作数,因此可以直接比较 SQL/JSON 数组。大小为 1 的数组被视为等于其唯一元素。以下情况不会自动解包: - 路径表达式包含type()size()方法,它们分别返回数组中的元素类型和数量。 + 路径表达式包含type()size()方法,它们分别返回类型和数组中的元素数量。 - 查询的JSON数据包含嵌套的数组。在本例中,只有最外层的数组被打开,而所有内部数组保持不变。 - 因此,隐式展开在每个路径求值步骤中只能向下进行一级。 + 查询的JSON数据包含嵌套的数组。在本例中,只有最外层的数组被解包,而所有内部数组保持不变。 + 因此,隐式解包在每个路径求值步骤中只能向下进行一级。 - - 例如,当查询上面列出的GPS数据时,当使用不严格的(lax)模式时,你可以从它存储了一组片段的事实中抽象出来: - + 例如,查询上面列出的 GPS 数据时,使用宽松模式可以不必关心它将轨迹段存储为数组这一细节: lax $.track.segments.location - - 在严格的(strict)模式中,指定的路径必须与查询的JSON文档的结构完全匹配才能返回SQL/JSON项,因此使用该路径表达式会导致错误。 - 要得到与不严格的(lax)模式相同的结果,你必须显式地打开segments数组: - + 在严格模式下,指定路径必须与所查询 JSON 文档的结构完全匹配,才能返回 SQL/JSON 项,因此使用此路径表达式会导致错误。要得到与宽松模式相同的结果,必须显式解包segments数组: strict $.track.segments[*].location - - .**访问器在使用lax模式时可能导致令人惊讶的结果。 - 例如,下面的查询选择每个HR值两次: - + .**访问器在宽松模式下可能产生出人意料的结果。例如,下面的查询会选出每个HR值两次: lax $.**.HR - - 发生这个,是因为.**访问器会全部选择segments数组和它的每个元素。 - 而当使用lax模式时,.HR访问器会自动打开数组。 - 为了避免意外的结果,我们建议仅在严格模式下使用.**访问器。 - 下面的查询选择每个HR值仅一次: - +这是因为.**访问器既选择segments数组,又选择其每个元素,而.HR访问器在宽松模式下会自动解包数组。为避免意外结果,建议将.**访问器仅用于严格模式。下面的查询只选出每个HR值一次: strict $.**.HR @@ -15099,7 +14810,7 @@ strict $.**.HR SQL/JSON 路径操作符和方法 - 显示了jsonpath中可用的操作符和方法。 + 显示了jsonpath中可用的操作符和方法。 请注意,虽然一元操作符和方法可以应用于由前一个路径步骤产生的多个值,二元操作符(加法等)只能应用于单个值。 @@ -15172,7 +14883,7 @@ strict $.**.HR number - 否定;与减法不同,它可以迭代多个值 + 取负;与减法不同,可以遍历多个值。 jsonb_path_query_array('{"x": [2,3,4]}', '- $.x') @@ -15214,7 +14925,7 @@ strict $.**.HR number - 模数 (余数) + 取模(余数) jsonb_path_query('[32]', '$[0] % 10') @@ -15310,7 +15021,7 @@ strict $.**.HR string . datetime() datetime_type - (see note) + (见注) 从字符串转换过来的日期/时间值 @@ -15325,7 +15036,7 @@ strict $.**.HR string . datetime(template) datetime_type - (see note) + (见注) 使用指定的to_timestamp模板从字符串转换过来的日期/时间值 @@ -15362,7 +15073,7 @@ strict $.**.HR datetime()方法依次尝试将其输入字符串与date, timetz, time,timestamptz, 和 timestamp的ISO格式进行匹配。 - 它在第一个匹配格式时停止,并发出相应的数据类型。 + 它在第一个匹配格式时停止,并返回相应数据类型的值。 @@ -15370,26 +15081,26 @@ strict $.**.HR - datetime()datetime(template)方法使用与to_timestamp SQL函数相同的解析规则(see ),但有三个例外。 + datetime()datetime(template)方法使用与to_timestamp SQL函数相同的解析规则(参见),但有三个例外。 首先,这些方法不允许不匹配的模板模式。 - 其次,模板字符串中只允许以下分隔符:减号、句点、solidus(斜杠)、逗号、撇号、分号、冒号和空格。 + 其次,模板字符串中只允许以下分隔符:减号、句点、斜杠、逗号、撇号、分号、冒号和空格。 第三,模板字符串中的分隔符必须与输入字符串完全匹配。 - 如果需要比较不同的日期/时间类型,则应用隐式转换。 + 如果需要比较不同的日期/时间类型,则应用隐式类型转换。 date值可以转换为timestamptimestamptz, timestamp可以转换为timestamptz, time可以转换为timetz。 但是,除了第一个转换外,其他所有转换都依赖于当前设置,因此只能在时区感知的jsonpath函数中执行。 - 显示了适用的过滤器表达式元素。 + 显示了可用的过滤表达式元素。
- <type>jsonpath</type> 过滤器表达式元素 + <type>jsonpath</type> 过滤表达式元素 @@ -15538,7 +15249,7 @@ strict $.**.HR value - JSON常数null(注意,与SQL不同,与null比较可以正常工作) + JSON 常量null(注意,与SQL不同,与null比较可以正常工作) jsonb_path_query('[{"name": "Mary", "job": null}, {"name": "Michael", "job": "driver"}]', '$[*] ? (@.job == null) .name') @@ -15608,7 +15319,7 @@ strict $.**.HR boolean - 测试第一个操作数是否与第二个操作数给出的正则表达式匹配,可选使用由一串flag字符描述的修改(参见)。 + 测试第一个操作数是否与第二个操作数给出的正则表达式匹配;可以用一串flag标志字符调整匹配行为(参见)。 jsonb_path_query_array('["abc", "abd", "aBdC", "abdacb", "babc"]', '$[*] ? (@ like_regex "^ab.*c")') @@ -15664,31 +15375,28 @@ strict $.**.HR LIKE_REGEX - in SQL/JSON + 用于 SQL/JSON - - SQL/JSON路径表达式允许通过like_regex过滤器将文本匹配为正则表达式。 - 例如,下面的SQL/JSON路径查询将不区分大小写地匹配以英语元音开头的数组中的所有字符串: - + SQL/JSON 路径表达式允许使用like_regex过滤器,将文本与正则表达式进行匹配。例如,以下 SQL/JSON 路径查询会以不区分大小写的方式,匹配数组中所有以英语元音字母开头的字符串: $[*] ? (@ like_regex "^[aeiou]" flag "i") - 可选的flag字符串可以包括一个或多个字符i用于不区分大小写的匹配,m允许^$在换行时匹配,s允许.匹配换行符,q引用整个模式(将行为简化为一个简单的子字符串匹配)。 + 可选的flag字符串可以包括一个或多个字符i用于不区分大小写的匹配,m允许^$在换行时匹配,s允许.匹配换行符,q将整个模式按字面量处理(将行为简化为一个简单的子字符串匹配)。 SQL/JSON标准借用了来自LIKE_REGEX操作符的正则表达式定义,其使用了XQuery标准。 PostgreSQL目前不支持LIKE_REGEX操作符。因此,like_regex过滤器是使用中描述的POSIX正则表达式引擎来实现的。 - 这导致了与标准SQL/JSON行为的各种细微差异,这在中进行了分类。 - 但是请注意,这里描述的标志字母不兼容并不适用于SQL/JSON,因为它将XQuery标志字母翻译为符合POSIX引擎的预期。 + 这导致了与标准SQL/JSON行为的各种细微差异,这些差异列在中。 + 但是请注意,这里描述的标志字母不兼容并不适用于SQL/JSON,因为 SQL/JSON 会将 XQuery 标志字母转换为 POSIX 引擎所预期的形式。 - 请记住,like_regex的模式参数是一个JSON路径字符串文字,根据给出的规则编写。 - 这特别意味着在正则表达式中要使用的任何反斜杠都必须加倍。例如,匹配只包含数字的根文档的字符串值: + 请记住,like_regex的模式参数是一个JSON 路径字符串字面量,根据给出的规则编写。 + 这特别意味着在正则表达式中要使用的任何反斜杠都必须加倍。例如,匹配根文档中仅包含数字的字符串值: $.* ? (@ like_regex "^\\d+$") @@ -15703,11 +15411,11 @@ $.* ? (@ like_regex "^\\d+$") 序列操作函数 - sequence + 序列 - 本节描述对序列对象进行操作的函数,也称为序列生成器或简称序列。 + 本节描述用于操作序列对象(也称为序列生成器,或简称序列)的函数。 序列对象是使用创建的特殊单行表。 序列对象通常用于为表中的行生成惟一标识符。在中列出的序列函数,提供了简单的、多用户安全方法,用于从序列对象中获取连续的序列值。 @@ -15739,12 +15447,12 @@ $.* ? (@ like_regex "^\\d+$") bigint - 将序列对象推进到下一个值并返回该值。这是自动完成的:即使多个会话并发地执行nextval,每个会话也会安全地接收到不同的序列值。 - 如果序列对象是用默认形参创建的,则连续的nextval调用将返回以1开始的连续值。 + 将序列对象推进到下一个值并返回该值。这个操作是原子的:即使多个会话并发地执行nextval,每个会话也会安全地接收到不同的序列值。 + 如果序列对象是用默认参数创建的,则连续的nextval调用将返回以1开始的连续值。 其他行为可以通过在命令中使用适当的参数获得。 - 这个函数需要USAGEUPDATE权限在序列上。 + 这个函数需要序列上的USAGEUPDATE权限。 @@ -15757,16 +15465,16 @@ $.* ? (@ like_regex "^\\d+$") bigint - 设置序列对象的当前值,以及可选的它的is_called标志。 + 设置序列对象的当前值,并可选地设置其is_called标志。 双参数形式将序列的last_value字段设置为指定的值,并将其is_called字段设置为true,意味着下一个nextval将在返回值之前推进序列。 currval将报告的值也设置为指定的值。在三参数形式中,is_called可以设置为truefalsetrue与双参数形式具有相同的效果。 - 如果设置为false,下一个nextval将返回指定的值,序列推进从下面的nextval开始。 - 而且,currval报告的值在这种情况下不会改变。例如, + 如果设置为false,下一个nextval将返回指定的值,序列推进从再下一次调用nextval开始。 + 而且,currval报告的值在这种情况下不会改变。例如: -SELECT setval('myseq', 42); Next nextval will return 43 +SELECT setval('myseq', 42); 下一次 nextval 将返回 43 SELECT setval('myseq', 42, true); 同上 -SELECT setval('myseq', 42, false); Next nextval will return 42 +SELECT setval('myseq', 42, false); 下一次 nextval 将返回 42 setval返回的结果就是它的第二个参数的值。 @@ -15784,8 +15492,7 @@ SELECT setval('myseq', 42, false); Next nextvalbigint - 返回nextval在当前会话中为该序列最近获取的值。(如果在这个会话中没有为这个序列调用nextval会报告错误。) - 因为它返回的是一个会话本地值,所以它给出了一个可预测的答案,即自当前会话以来,其他会话是否执行了nextval。 + 返回当前会话中最近一次针对该序列调用nextval所获得的值。(如果当前会话从未针对该序列调用过nextval,则会报错。)由于返回的是会话局部值,无论其他会话是否在当前会话调用之后执行过nextval,结果都是可预测的。 这个函数需要序列上的USAGESELECT权限。 @@ -15837,9 +15544,7 @@ SELECT setval('myseq', 42, false); Next nextval - 序列函数所要操作的序列由regclass参数指定,该参数只是pg_class系统目录中序列的OID。 - 你不必手工查找OID,不过,因为regclass数据类型的输入转换器将为您完成这项工作。 - 详见 + 序列函数所要操作的序列由regclass参数指定,该参数就是序列在pg_class系统目录中的 OID。不过,不必手动查找 OID,因为regclass数据类型的输入转换器会完成这项工作。详见 @@ -15886,7 +15591,7 @@ CASE WHEN condition THEN result - CASE子句可以用于任何表达式可以出现的地方。每一个condition是一个返回boolean结果的表达式。如果结果为真,那么CASE表达式的结果就是符合条件的result,并且剩下的CASE表达式不会被处理。如果条件的结果不为真,那么以相同方式搜寻任何随后的WHEN子句。如果没有WHEN condition为真,那么CASE表达式的值就是在ELSE子句里的result。如果省略了ELSE子句而且没有条件为真,结果为空。 + CASE子句可以用于任何表达式可以出现的地方。每一个condition是一个返回boolean结果的表达式。如果结果为真,那么CASE表达式的结果就是紧随该条件后的result,并且剩下的CASE表达式不会被处理。如果条件的结果不为真,那么以相同方式搜寻任何随后的WHEN子句。如果没有WHEN condition为真,那么CASE表达式的值就是在ELSE子句里的result。如果省略了ELSE子句而且没有条件为真,结果为 null。 @@ -15930,7 +15635,7 @@ CASE expression END - 第一个expression会被计算,然后与所有在WHEN子句中的每一个value对比,直到找到一个相等的。如果没有找到匹配的,则返回在ELSE子句中的result(或者控制)。 这类似于 C 里的switch语句。 + 第一个expression会被计算,然后与所有在WHEN子句中的每一个value对比,直到找到一个相等的。如果没有找到匹配的,则返回在ELSE子句中的result(或者 null 值)。 这类似于 C 里的switch语句。 @@ -15961,11 +15666,7 @@ SELECT ... WHERE CASE WHEN x <> 0 THEN y/x > 1.5 ELSE false END; - 如中所述,在有几种情况中一个表达式的子表达式 - 会被计算多次,因此CASE只计算必要的表达式这 - 一原则并非不可打破。例如一个常量子表达式1/0通常将会在规划时导致一次 - 除零错误,即便它位于一个执行时永远也不会进入的CASE分支时也是 - 如此。 + 如所述,在多种情况下,表达式中的子表达式会在不同阶段求值,因此CASE只计算必要的子表达式这一原则并非绝对成立。例如,常量子表达式1/0通常会在规划时导致除零错误,即便它位于一个运行时永远不会进入的CASE分支中也是如此。 @@ -15990,19 +15691,19 @@ SELECT ... WHERE CASE WHEN x <> 0 THEN y/x > 1.5 ELSE false END; - COALESCE函数返回它的第一个非空参数的值。当且仅当所有参数都为空时才会返回空。它常用于在为显示目的检索数据时用缺省值替换空值。例如: + COALESCE函数返回参数中第一个不为 null 的值。只有所有参数都为 null 时,才返回 null。它常用于在检索数据以供显示时,用默认值替换 null 值。例如: SELECT COALESCE(description, short_description, '(none)') ... - 如果description不为空,这将会返回它的值,否则如果short_description非空则返回short_description的值,如果前两个都为空则返回(none)。 + 此表达式返回description,前提是它不为 null,否则返回short_description,前提是它不为 null,否则返回(none) - 所有参数都必须转换为一个公共数据类型,它将是结果的类型 (详情参见 )。 + 所有参数都必须能转换为同一个数据类型,它将是结果的类型(详情参见)。 - 和CASE表达式一样,COALESCE将不会 计算无助于判断结果的参数;也就是说,在第一个非空参数右边的参数不会被计算。这个 SQL 标准函数提供了类似于NVLIFNULL的能力,它们被用在某些其他数据库系统中。 + 和CASE表达式一样,COALESCE只计算确定结果所需的参数;也就是说,在第一个不为 null 的参数右边的参数不会被计算。这个 SQL 标准函数提供了类似于NVLIFNULL的能力,它们被用在某些其他数据库系统中。 @@ -16018,12 +15719,12 @@ SELECT COALESCE(description, short_description, '(none)') ... - 当value1value2相等时,NULLIF返回一个空值。 + 当value1value2相等时,NULLIF返回 null。 否则它返回value1。 这些可以用于执行前文给出的COALESCE示例的逆操作: SELECT NULLIF(value, '(none)') ... - 在这个示例中,如果value(none),将返回空值,否则返回value的值。 + 在这个示例中,如果value(none),将返回 null,否则返回value的值。 @@ -16058,11 +15759,11 @@ SELECT NULLIF(value, '(none)') ... - GREATESTLEAST函数从一个任意的数字表达式列表里选取最大或者最小的数值。 这些表达式必须都可以转换成一个普通的数据类型,它将会是结果类型 (参阅获取细节)。列表中的 NULL 数值将被忽略。只有所有表达式的结果都是 NULL 的时候,结果才会是 NULL。 + GREATESTLEAST函数从由任意数量的表达式组成的列表中选取最大值或最小值。这些表达式都必须能转换为同一个数据类型,该类型将作为结果类型(详情参见)。列表中的 NULL 值会被忽略。只有所有表达式的求值结果都为 NULL 时,结果才为 NULL。 - 请注意GREATESTLEAST都不是 SQL 标准,但却是很常见的扩展。某些其他数据库让它们在任何参数为 NULL 时返回 NULL,而不是在所有参数都为 NULL 时才返回 NULL。 + 请注意GREATESTLEAST都未包含在 SQL 标准中,但却是很常见的扩展。某些其他数据库让它们在任何参数为 NULL 时返回 NULL,而不是在所有参数都为 NULL 时才返回 NULL。 @@ -16074,9 +15775,9 @@ SELECT NULLIF(value, '(none)') ... 显示了可以用于数组类型的专用的操作符。 除此之外,中所示的常用比较操作符也适用于数组。 - 比较操作符逐个元素的比较数组内容,使用默认的元素数据类型的B-树比较函数,并根据第一个差值进行排序。 + 比较操作符逐个元素比较数组内容,使用元素数据类型的默认 B-树比较函数,并根据第一个差异进行排序。 多维数组的元素按照行序进行访问(最后的下标变化最快)。 - 如果两个数组的内容相同但维数不等,那么维度信息中的第一个不同将决定排序顺序。 + 如果两个数组的内容相同但维度信息不同,那么维度信息中的第一个不同将决定排序顺序。
@@ -16107,7 +15808,7 @@ SELECT NULLIF(value, '(none)') ... 第一个数组是否包含第二个数组,也就是说,出现在第二个数组中的每个元素是否等于第一个数组中的某个元素? - (重复值不需要特殊处理,因此ARRAY[1]ARRAY[1,1]被认为包含对方。) + (重复元素不作特殊处理,因此ARRAY[1]ARRAY[1,1]被认为包含对方。) ARRAY[1,4,3] @> ARRAY[3,1,3] @@ -16149,8 +15850,7 @@ SELECT NULLIF(value, '(none)') ... anycompatiblearray - 连接两个数组。连接空(null)或空数组是一个无操作(no-op);否则,数组必须具有相同的维度数(如第一个示例所示),或者维度数相差一个(如第二个示例所示)。 - 如果数组不是完全相同的元素类型,它们将被强制转换成一个共同的类型(参见)。 + 连接两个数组。连接 null 或空数组不会产生任何效果;否则,数组必须具有相同的维数(如第一个示例所示),或维数相差一维(如第二个示例所示)。如果数组的元素类型不同,则会将它们强制转换为同一个类型(参见)。 ARRAY[1,2,3] || ARRAY[4,5,6,7] @@ -16182,7 +15882,7 @@ SELECT NULLIF(value, '(none)') ... anycompatiblearray - 将元素连接到数组的末尾(数组必须为空或一维的[one-dimensional])。 + 将元素连接到数组的末尾(数组必须为空或一维)。 ARRAY[4,5,6] || 7 @@ -16194,7 +15894,7 @@ SELECT NULLIF(value, '(none)') ...
- 参阅获取有关数组操作符行为的更多细节。有关哪些操作符支持被索引的操作,请参阅。 + 参阅获取有关数组操作符行为的更多细节。有关哪些操作符支持索引操作,请参阅 @@ -16283,8 +15983,7 @@ SELECT NULLIF(value, '(none)') ... anyarray - 返回一个包含给定值的拷贝的数组,其维数与第二个参数指定的长度相同。 - 可选的第三个参数提供每个维度的下界值(默认为全部为 1)。 + 返回用给定值的副本填充的数组,各维的长度由第二个参数指定。可选的第三个参数提供各维的下界值(默认均为1)。 array_fill(11, ARRAY[2,3]) @@ -16365,7 +16064,7 @@ SELECT NULLIF(value, '(none)') ... integer - 返回阵列中第二个参数中第一次发生的下标,如果它不存在,则返回NULL。 + 返回第二个参数在数组中首次出现的下标;若不存在,则返回NULL。 如果给出了第三个参数,则搜索从该下标开始。数组必须是一维的。比较是使用IS NOT DISTINCT FROM语义进行的,所以可以搜索NULL @@ -16383,9 +16082,9 @@ SELECT NULLIF(value, '(none)') ... integer[] - 返回作为第一个参数的数组中第二个参数所有出现的下标的数组。 + 返回第二个参数在第一个参数所给数组中所有出现位置的下标数组。 数组必须是一维的。使用IS NOT DISTINCT FROM语义完成比较,所以可以搜索NULL。 - 只有当数组为NULL时才返回NULL;如果在数组中没有找到该值,则返回空数组。 + 只有当数组为NULL时才返回NULL;如果在数组中没有找到该值,则返回空数组。 array_positions(ARRAY['A','A','B','A'], 'A') @@ -16506,7 +16205,7 @@ SELECT NULLIF(value, '(none)') ... anyarray - 通过删除最后的n元素来裁剪数组。 + 通过删除最后的n个元素来裁剪数组。 如果数组是多维的,则只裁剪第一个维度。 @@ -16555,7 +16254,7 @@ SELECT NULLIF(value, '(none)') ... 将多个数组(可能是不同的数据类型)展开到一组行中。 如果数组的长度不完全相同,那么较短的数组将用NULL填充。 - 这种形式只在查询的FROM子句中允许;参见。 + 这种形式只允许出现在查询的 FROM 子句中;参见 select * from unnest(ARRAY[1,2], ARRAY['foo','bar','baz']) as x(a,b) @@ -16706,7 +16405,7 @@ SELECT NULLIF(value, '(none)') ... boolean - 第一个范围是否严格符合第二个(范围)? + 第一个范围是否严格地在第二个(范围)的右边? int8range(50,60) >> int8range(20,30) @@ -16790,7 +16489,7 @@ SELECT NULLIF(value, '(none)') ... anyrange - 计算范围的差异。第二个范围必须不能包含在第一个(范围)中,以使差异不是一个单一的范围。 + 计算范围的差集。第二个范围不能被包含在第一个范围中而导致差集无法表示为单个范围。 int8range(5,15) - int8range(10,20) @@ -16884,7 +16583,7 @@ SELECT NULLIF(value, '(none)') ... boolean - 第一个多范围是否被第二个所包括? + 第一个多范围是否被第二个所包含? '{[2,4)}'::int4multirange <@ '{[1,7)}'::int4multirange @@ -16898,7 +16597,7 @@ SELECT NULLIF(value, '(none)') ... boolean - 多范围是否被范围所包括。 + 多范围是否被范围所包含? '{[2,4)}'::int4multirange <@ int4range(1,7) @@ -16912,7 +16611,7 @@ SELECT NULLIF(value, '(none)') ... boolean - 范围是否被多范围所包括? + 范围是否被多范围所包含? int4range(2,4) <@ '{[1,7)}'::int4multirange @@ -17010,7 +16709,7 @@ SELECT NULLIF(value, '(none)') ... boolean - 范围是否完全的在多范围左边? + 范围是否完全在多范围左边? int8range(1,10) << '{[100,110)}'::int8multirange @@ -17052,7 +16751,7 @@ SELECT NULLIF(value, '(none)') ... boolean - 范围是否完全在多范围右边。 + 范围是否完全在多范围右边? int8range(50,60) >> '{[20,30)}'::int8multirange @@ -17220,7 +16919,7 @@ SELECT NULLIF(value, '(none)') ... anymultirange - 计算多范围的差异。 + 计算多范围的差集。 '{[5,20)}'::int8multirange - '{[10,15)}'::int8multirange @@ -17232,21 +16931,21 @@ SELECT NULLIF(value, '(none)') ... - 当涉及一个空范围或多范围时,左部/右部/相邻操作符总是返回假;即一个空范围被认为不在任何其他范围前面或者后面。 + 涉及空范围或空多范围时,左侧、右侧和相邻操作符总是返回假;也就是说,空范围不被视为位于任何其他范围之前或之后。 - 在其他地方,空范围和多范围被视为添加标识:与空值的任何交集都是它自己。 - 任何减去空值的都是它自己。 - 空的多范围与空的范围具有完全相同的点。 + 在其他运算中,空范围和空多范围被视为加法单位元:任何值与空值求并集,结果仍是该值本身。 + 任何值减去空值,结果也仍是该值本身。 + 空多范围与空范围具有完全相同的点。 每个范围都包含空范围。 每个多范围包含任意多个空范围。 - 范围交集和差异操作符将失败,如果结果范围需要包含两个不相交的子范围,因为这样的范围无法表示。 - 还有用于求交集和差集的单独操作符,它们接受多范围参数并返回多范围,即使参数彼此不相交也不会失败。 - 因此,如果需要对可能不相交的范围进行交集或差异操作,你可以通过首先将范围转换为多范围来避免错误。 + 如果结果范围需要包含两个不相交的子范围,范围并集和差集操作符会失败,因为这样的范围无法表示。 + 另有接受多范围参数并返回多范围的并集和差集操作符,即使参数彼此不相交,也不会失败。 + 因此,如果需要对可能不相交的范围求并集或差集,可以先将范围转换为多范围来避免错误。 @@ -17301,7 +17000,7 @@ SELECT NULLIF(value, '(none)') ... anyelement - 提取范围的上限(如果范围为空或上限为无限,则为NULL)。 + 提取范围的上界(如果范围为空或上界为无限,则为NULL)。 upper(numrange(1.1,2.2)) @@ -17443,7 +17142,7 @@ SELECT NULLIF(value, '(none)') ... anyelement - 提取多范围的下界 (NULL 如果多范围为空或下界为无穷的)。 + 提取多范围的下界(如果多范围为空或下界为无穷,则返回NULL)。 lower('{[1.1,2.2)}'::nummultirange) @@ -17460,7 +17159,7 @@ SELECT NULLIF(value, '(none)') ... anyelement - 提取多范围的上界 (NULL 如果多范围为空或上界为无穷的)。 + 提取多范围的上界(如果多范围为空或上界为无穷,则返回NULL)。 upper('{[1.1,2.2)}'::nummultirange) @@ -17494,7 +17193,7 @@ SELECT NULLIF(value, '(none)') ... boolean - 多范围的下界是否包括? + 多范围的下界是否包含在内? lower_inc('{[1.1,2.2)}'::nummultirange) @@ -17511,7 +17210,7 @@ SELECT NULLIF(value, '(none)') ... boolean - 多范围的上界是否包括? + 多范围的上界是否包含在内? upper_inc('{[1.1,2.2)}'::nummultirange) @@ -17573,7 +17272,7 @@ SELECT NULLIF(value, '(none)') ... - multirange (function) + multirange(函数) multirange ( anyrange ) anymultirange @@ -17591,14 +17290,14 @@ SELECT NULLIF(value, '(none)') ... unnest - for multirange + 用于多范围 unnest ( anymultirange ) setof anyrange - 扩展多范围为一组范围。 - 范围按存储顺序读出(升序)。 + 将多范围展开为一组范围。 + 范围按存储顺序(升序)读出。 unnest('{[1,2), [3,4)}'::int4multirange) @@ -17614,7 +17313,7 @@ SELECT NULLIF(value, '(none)') ... - lower_incupper_inclower_inf、 和 upper_inf 函数对空范围(empty range)或多范围都返回假(false)。 + lower_incupper_inclower_infupper_inf 函数对空范围或空多范围都返回假。 @@ -17628,11 +17327,11 @@ SELECT NULLIF(value, '(none)') ... - 聚合函数从一个输入值的集合计算出一个单一值。 - 内置的通用聚合函数在中列出,而统计性聚合是在中列出。 + 聚合函数从一个输入值的集合计算出一个单一结果。 + 内置的通用聚合函数在中列出,而统计聚合函数在中列出。 内置的组内有序集聚合函数在中列出,而内置的组内假想集聚合在中列出。 与聚合函数紧密相关的分组操作在中列出。 - 中会解释针对聚合函数的特殊语法考虑。额外的介绍信息请参考。 + 中会解释针对聚合函数的特殊语法注意事项。更多入门信息请参考 @@ -17671,7 +17370,7 @@ SELECT NULLIF(value, '(none)') ... 将所有输入值,包括空值,收集到一个数组中。 - No + @@ -17680,15 +17379,15 @@ SELECT NULLIF(value, '(none)') ... anyarray - 将所有输入数组连接到一个更高维度的数组中。(输入必须都具有相同的维度,并且不能为空的(empty)或空值(null)。) + 将所有输入数组连接成维数增加一维的数组。(所有输入的维数必须相同,且不能是空数组或空值(NULL)。) - No + - average + 平均值 avg @@ -17723,7 +17422,7 @@ SELECT NULLIF(value, '(none)') ... 计算所有非空输入值的平均值(算术平均值)。 - Yes + @@ -17747,9 +17446,9 @@ SELECT NULLIF(value, '(none)') ... bit - 计算所有非空输入值的逐位AND。 + 计算所有非空输入值的按位与。 - Yes + @@ -17773,9 +17472,9 @@ SELECT NULLIF(value, '(none)') ... bit - 计算所有非空输入值的逐位OR。 + 计算所有非空输入值的按位或。 - Yes + @@ -17802,7 +17501,7 @@ SELECT NULLIF(value, '(none)') ... 计算所有非空输入值的按位异或。 可用作一组无序的值集合的校验和。
- Yes + @@ -17816,7 +17515,7 @@ SELECT NULLIF(value, '(none)') ... 如果全部非空输入值都为真则返回真,否则返回假。 - Yes + @@ -17830,7 +17529,7 @@ SELECT NULLIF(value, '(none)') ... 如果任何非空输入值为真则返回真,否则返回假。 - Yes + @@ -17844,7 +17543,7 @@ SELECT NULLIF(value, '(none)') ... 计算输入行的数量。 - Yes + @@ -17855,7 +17554,7 @@ SELECT NULLIF(value, '(none)') ... 计算输入值不为空的输入行的数量。 - Yes + @@ -17867,9 +17566,9 @@ SELECT NULLIF(value, '(none)') ... boolean
- 这是对应bool_and的SQL标准的等效物。 + 这是标准 SQL 中与bool_and等价的函数。 - Yes + @@ -17890,7 +17589,7 @@ SELECT NULLIF(value, '(none)') ... 收集所有输入值,包括空值,到一个JSON数组。根据to_jsonto_jsonb将值转换为JSON。 - No + @@ -17913,10 +17612,10 @@ SELECT NULLIF(value, '(none)') ... jsonb - 将所有键/值对收集到一个JSON对象中。关键参数强制转换为文本;值参数按照to_jsonto_jsonb进行转换。 + 将所有键/值对收集到一个JSON对象中。键参数强制转换为文本;值参数按照to_jsonto_jsonb进行转换。 值可以为空,但键不能(为空)。 - No + @@ -17924,8 +17623,8 @@ SELECT NULLIF(value, '(none)') ... 最大值 - max ( see text ) - same as input type + max ( 见说明 ) + 与输入类型相同 计算非空输入值的最大值。适用于任何数字、字符串、日期/时间或枚举类型, @@ -17942,8 +17641,8 @@ SELECT NULLIF(value, '(none)') ... 最小值 - min ( see text ) - same as input type + min ( 见说明 ) + 与输入类型相同 计算非空输入值的最小值。适用于任何数字、字符串、日期/时间或枚举类型, @@ -17972,7 +17671,7 @@ SELECT NULLIF(value, '(none)') ... 计算非空输入值的并集。 - No + @@ -17992,7 +17691,7 @@ SELECT NULLIF(value, '(none)') ... 计算非空输入值的交集。 - No + @@ -18010,9 +17709,9 @@ SELECT NULLIF(value, '(none)') ... bytea - 将非 null 输入值连接成一个字符串。第一个值之后的每个值前面都会放置相应的delimiter(如果它不为 null)。 + 将非 NULL 输入值连接成一个字符串。在第一个值之后,每个值前面都会放置相应的delimiter(如果它不为 NULL)。 - No + @@ -18054,7 +17753,7 @@ SELECT NULLIF(value, '(none)') ... 计算非空输入值的总和。 - Yes + @@ -18066,31 +17765,24 @@ SELECT NULLIF(value, '(none)') ... xml - 连接非空的XML输入值(参见)。 + 连接非空的 XML 输入值(参见)。 - No + - 应该注意的是,除了count之外,这些函数在没有选择行时返回空值。 - 特别地,行数的sum返回空(null),而不是预期的零,array_agg在没有输入行时返回空(null)而不是空数组。 - coalesce函数可以在必要时用零或空数组代替空(null)。 + 需要注意,除了count之外,这些函数在没有选中任何行时都会返回空值。特别地,sum在没有输入行时返回空值,而不是预期中的零;array_agg在没有输入行时返回空值,而不是空数组。必要时,可以用coalesce函数把空值替换成零或空数组。 - 聚合函数 array_agg,json_agg, jsonb_agg,json_object_agg, jsonb_object_agg, - string_agg,和 xmlagg,以及类似的用户定义的聚合函数,根据输入值的顺序产生富有意义的不同的结果值。 - 默认情况下,这种排序是不指定的,但可以通过在聚合调用中写入ORDER BY子句来控制,如所示。 - 或者,从排序的子查询提供输入值通常也可以。例如: - + 聚合函数array_aggjson_aggjsonb_aggjson_object_aggjsonb_object_aggstring_aggxmlagg,以及类似的用户定义聚合函数,其结果值会随输入值的顺序发生实质性变化。默认情况下,输入顺序未指定,但可以在聚合调用中写入ORDER BY子句来控制,如所示。也可以用已排序的子查询提供输入值,这通常也能奏效。例如: - - 注意,如果外部查询级别包含其他处理,例如关联,则此方法可能会失败,因为这可能导致子查询的输出在计算聚合之前重新排序。 + 需要注意,如果外层查询包含连接等额外处理,这种方法可能失效,因为子查询的输出可能在计算聚合之前被重新排序。 @@ -18104,31 +17796,24 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; - 布尔聚合 bool_andbool_or 对应于标准SQL聚合 everyanysome. - PostgreSQL 支持 every, 但不支持 anysome, 因为标准语法中存在模糊性: - + 布尔聚合bool_andbool_or对应于标准 SQL 聚合everyanysome。 + PostgreSQL支持every,但不支持anysome,因为标准语法中存在歧义: SELECT b1 = ANY((SELECT b2 FROM t2 ...)) FROM t1 ...; - - 这里ANY可以被认为是引入子查询,或者是聚合函数,如果子查询返回一行布尔值。因此,不能为这些聚合提供标准名称。 +此处的ANY既可以被视为引入一个子查询,也可以在该子查询返回一行布尔值时被视为聚合函数。因此,不能将标准名称用于这些聚合。 - 习惯使用其他SQL数据库管理系统的用户可能会对count聚合应用于整个表时的性能感到失望。一个类似下面的查询: - + 习惯于其他 SQL 数据库管理系统的用户,可能会对count聚合用于整个表时的性能感到失望。如下查询: SELECT count(*) FROM sometable; - - 将需要与表大小成比例的工作:PostgreSQL将需要扫描整个表或包含表中所有行的索引。 +所需的工作量与表大小成正比:PostgreSQL需要扫描整个表,或者完整扫描一个包含表中所有行的索引。 - 显示了统计分析中常用的聚合函数。 - (这些被分离出来仅仅是为了避免使更常用的聚合列表混乱。) - 显示为接受numeric_type的函数可用于所有类型smallint, integer,bigint, numeric, real, 和 double precision。 - 在描述中提及N时,它意味着所有输入表达式都非空的输入行数。在所有情况下,如果计算没有意义,则返回null,例如当N为0时。 + 列出了统计分析中常用的聚合函数。(将它们单独列出,只是为了避免更常用的聚合函数列表过于杂乱。)标为接受numeric_type的函数适用于smallintintegerbigintnumericrealdouble precision这些类型。描述中提到的N表示所有输入表达式都非空的输入行数。无论哪种情况,如果计算没有意义,例如N为 0,就返回 null。 @@ -18163,7 +17848,7 @@ SELECT count(*) FROM sometable; - correlation + 相关性 corr @@ -18174,14 +17859,14 @@ SELECT count(*) FROM sometable; 计算相关系数。 - Yes + - covariance - population + 协方差 + 总体 covar_pop @@ -18192,14 +17877,14 @@ SELECT count(*) FROM sometable; 计算总体协方差。 - Yes + - covariance - sample + 协方差 + 样本 covar_samp @@ -18210,7 +17895,7 @@ SELECT count(*) FROM sometable; 计算样本协方差。 - Yes + @@ -18222,9 +17907,9 @@ SELECT count(*) FROM sometable; double precision - 计算自变量的平均值,sum(X)/N. + 计算自变量的平均值,即sum(X)/N - Yes + @@ -18236,9 +17921,9 @@ SELECT count(*) FROM sometable; double precision - 计算因变量的平均值,sum(Y)/N. + 计算因变量的平均值,即sum(Y)/N - Yes + @@ -18252,13 +17937,13 @@ SELECT count(*) FROM sometable; 计算两个输入都非空的行数。 - Yes + - regression intercept + 回归截距 regr_intercept @@ -18267,9 +17952,9 @@ SELECT count(*) FROM sometable; double precision - 计算由(XY)对决定的最小二乘拟合的线性方程的Y-截距。 + 计算由(XY)数值对确定的最小二乘拟合线性方程的 y 轴截距。 - Yes + @@ -18283,13 +17968,13 @@ SELECT count(*) FROM sometable; 计算相关系数的平方。 - Yes + - regression slope + 回归斜率 regr_slope @@ -18298,9 +17983,9 @@ SELECT count(*) FROM sometable; double precision - 计算由(X, Y)对决定的最小二乘拟合的线性方程的斜率。 + 计算由(XY)数值对确定的最小二乘拟合线性方程的斜率。 - Yes + @@ -18312,10 +17997,9 @@ SELECT count(*) FROM sometable; double precision - 计算自变量的平方和 - sum(X^2) - sum(X)^2/N. + 计算自变量的平方和,即sum(X^2) - sum(X)^2/N - Yes + @@ -18327,10 +18011,9 @@ SELECT count(*) FROM sometable; double precision - 计算独立变量乘以因变量的sum of products, - sum(X*Y) - sum(X) * sum(Y)/N. + 计算自变量与因变量的乘积和,即sum(X*Y) - sum(X) * sum(Y)/N - Yes + @@ -18342,69 +18025,62 @@ SELECT count(*) FROM sometable; double precision - 计算因变量的平方和, - sum(Y^2) - sum(Y)^2/N. + 计算因变量的平方和,即sum(Y^2) - sum(Y)^2/N - Yes + - standard deviation + 标准差 stddev stddev ( numeric_type ) - double precision - for real or double precision, - otherwise numeric + 对于realdouble precision输入,返回double precision;否则返回numeric - 这是stddev_samp的一个历史别称。 + 这是stddev_samp的一个历史别名。 - Yes + - standard deviation - population + 标准差 + 总体 stddev_pop stddev_pop ( numeric_type ) - double precision - for real or double precision, - otherwise numeric + 对于realdouble precision输入,返回double precision;否则返回numeric 计算输入值的总体标准差。 - Yes + - standard deviation - sample + 标准差 + 样本 stddev_samp stddev_samp ( numeric_type ) - double precision - for real or double precision, - otherwise numeric + 对于realdouble precision输入,返回double precision;否则返回numeric 计算输入值的样本标准差。 - Yes + @@ -18413,54 +18089,48 @@ SELECT count(*) FROM sometable; variance variance ( numeric_type ) - double precision - for real or double precision, - otherwise numeric + 对于realdouble precision输入,返回double precision;否则返回numeric - 这是 var_samp 的一个历史别称。 + 这是 var_samp 的一个历史别名。 - Yes + - variance - population + 方差 + 总体 var_pop var_pop ( numeric_type ) - double precision - for real or double precision, - otherwise numeric + 对于realdouble precision输入,返回double precision;否则返回numeric - 计算输入值的总体方差(总体标准差的平方)。 + 计算输入值的总体方差(总体标准差的平方)。 - Yes + - variance - sample + 方差 + 样本 var_samp var_samp ( numeric_type ) - double precision - for real or double precision, - otherwise numeric + 对于realdouble precision输入,返回double precision;否则返回numeric - 计算输入值的样本方差(样本标准差的平方)。 + 计算输入值的样本方差(样本标准差的平方)。 - Yes + @@ -18471,11 +18141,11 @@ SELECT count(*) FROM sometable; 这些函数有时被称为逆分布函数。 它们的聚合输入通过ORDER BY引入,还可以接受未聚合的直接参数,但后者只计算一次。 所有这些函数在其聚合输入中都忽略空(null)值。 - 对于使用fraction参数的函数,分数值必须在 0 到 1 之间;否则会报错。但是,null 的 fraction 值只会产生一个 null 结果。 + 对于使用fraction参数的函数,比例值必须在 0 到 1 之间;否则会报错。但是,null 的 fraction 值只会产生一个 null 结果。 - ordered-set aggregate + 有序集聚合 内置 @@ -18507,16 +18177,16 @@ SELECT count(*) FROM sometable; - mode - statistical + 众数 + 统计 mode () WITHIN GROUP ( ORDER BY anyelement ) anyelement - 计算mode,即聚合参数最频繁的值(如果有多个相同频繁的值,第一个可以任意选择)。聚合参数必须是可排序类型。 + 计算众数,即聚合参数中出现次数最多的值(若多个值的出现次数相同且最多,则任意选择其中第一个)。聚合参数必须是可排序类型。 - No + @@ -18534,9 +18204,9 @@ SELECT count(*) FROM sometable; 计算连续百分位点,该值对应于聚合参数值有序集合中的指定fraction。 - 如果需要,这将在相邻的输入项之间插入。 + 必要时会在相邻输入项之间进行插值。 - No + @@ -18551,7 +18221,7 @@ SELECT count(*) FROM sometable; 计算多个连续百分位点。结果是一个与fractions参数具有相同维度的数组,其中每个非 null 元素都被替换为对应百分位点的值(必要时会进行插值)。 - No + @@ -18567,7 +18237,7 @@ SELECT count(*) FROM sometable; 计算离散百分位数,即聚合参数值的有序集合中的第一个值,该值在排序中的位置等于或超过指定的fraction。 聚合参数必须是可排序类型。 - No + @@ -18580,14 +18250,14 @@ SELECT count(*) FROM sometable; 结果是一个与fractions参数具有相同维数的数组,每个非空元素都被对应于该百分位数的输入值替换。 聚合参数必须是可排序类型。 - No + - hypothetical-set aggregate + 假想集聚合 内置 @@ -18623,52 +18293,52 @@ SELECT count(*) FROM sometable; rank - hypothetical + 假设行 rank ( args ) WITHIN GROUP ( ORDER BY sorted_args ) bigint - 计算假设行的排名,包括间隔,就是说在它的同等行组中第一行的行号。 + 计算假设行的排名,允许空缺;即该行所属同等行组中第一行的行号。 - No + dense_rank - hypothetical + 假设行 dense_rank ( args ) WITHIN GROUP ( ORDER BY sorted_args ) bigint - 计算假设行的排名,没有间隔;这个功能有效地计数同等行组。 + 计算假设行的排名,没有空缺;此函数实际上对同等行组进行计数。 - No + percent_rank - hypothetical + 假设行 percent_rank ( args ) WITHIN GROUP ( ORDER BY sorted_args ) double precision - 计算假设行的相关排行,也就是(rank - 1) / (total rows - 1)。取值范围为 0 到 1(含)。 + 计算假设行的相对排名,即(rank - 1)/(总行数 - 1)。取值范围为 0 到 1(含)。 - No + cume_dist - hypothetical + 假设行 cume_dist ( args ) WITHIN GROUP ( ORDER BY sorted_args ) double precision @@ -18676,7 +18346,7 @@ SELECT count(*) FROM sometable; 计算累积分布,也就是(位于假设行之前或与假设行同等的行数)/(总行数)。取值范围为 1/N 到 1。 - No + @@ -18709,8 +18379,7 @@ SELECT count(*) FROM sometable; integer - 返回一个位掩码以指示哪个GROUP BY表达式没有包含在当前分组集中。 - 比特位被分配给最右边的参数对应于最低有效位;如果对应的表达式包含在生成当前结果行的分组集的分组条件中,则每个位为0,如果不包含则为1。 + 返回一个位掩码,指示哪些GROUP BY表达式未包含在当前分组集中。分配比特位时,最右侧参数对应最低有效位;如果相应表达式包含在生成当前结果行的分组集的分组条件中,该位为 0,否则为 1。 @@ -18718,9 +18387,7 @@ SELECT count(*) FROM sometable; - 所示的分组操作与分组集(参见)共同使用,以区分结果行。 - GROUPING函数的参数实际上并不求值,但它们必须与相关查询级别的GROUP BY子句中给出的表达式完全匹配。例如: - + 在中列出的分组操作与分组集配合使用(参见),以区分结果行。传给GROUPING函数的参数不会实际求值,但它们必须与相关查询层级的GROUP BY子句中的表达式完全匹配。例如: => SELECT * FROM items_sold; make | model | sales -------+-------+------- @@ -18741,9 +18408,7 @@ SELECT count(*) FROM sometable; Bar | | 1 | 20 | | 3 | 50 (7 rows) - - 在这里,前四行中的grouping0表明这些已经正常分组,在两个分组列上。 - 值1表示model没有在倒数两行中分组,值3表示无论是make还是model都没有在最后一行中分组(因此,这是所有输入行的聚合)。 +这里,前四行的grouping值为0,表明这些行按两个分组列正常分组。值1表明model未用于倒数第二、第三行的分组,值3则表明最后一行既未按make分组,也未按model分组(因此该行聚合了全部输入行)。 @@ -18767,7 +18432,7 @@ SELECT count(*) FROM sometable; - 除了这些函数之外,任何内置的或用户定义的普通聚合(例如非有序集或假想集聚合)都可以作为窗口函数使用;关于内置聚合的列表,参见。 + 除了这些函数之外,任何内置的或用户定义的普通聚合(即不属于有序集或假想集聚合)都可以作为窗口函数使用;关于内置聚合的列表,参见。 聚合函数只有在调用后带有OVER子句时才作为窗口函数;否则,它们就是普通聚合,并为整个结果集返回一行。 @@ -18798,7 +18463,7 @@ SELECT count(*) FROM sometable; bigint - 返回其分区内的当前行数,从1开始计数。 + 返回当前行在其分区内的编号,从 1 开始计数。 @@ -18811,7 +18476,7 @@ SELECT count(*) FROM sometable; bigint - 返回当前行的排名,包含间隔;即同等行组中第一行的row_number。 + 返回当前行的排名,允许空缺;即同等行组中第一行的row_number @@ -18824,7 +18489,7 @@ SELECT count(*) FROM sometable; bigint - 返回当前行的排名,不包括间隔;这个功能有效地计数同等行组。 + 返回当前行的排名,没有空缺;此函数实际上对同等行组进行计数。 @@ -18863,7 +18528,7 @@ SELECT count(*) FROM sometable; integer - 返回一个从1到参数值的整数,并将分区划分为尽可能相等的值。 + 返回从 1 到参数值的整数,将分区尽可能均等地划分。 @@ -18878,9 +18543,7 @@ SELECT count(*) FROM sometable; anycompatible - 返回分区中在当前行之前offset行的value;如果没有这样的行,则返回default(必须与value相兼容的类型)。 - offsetdefault都是针对当前行求值的。 - 如果省略,offset默认为1,defaultNULL。 + 返回在分区内当前行之前offset行处计算的value;如果没有这样的行,则返回default(其类型必须与value兼容)。offsetdefault都针对当前行求值。如果省略,offset默认为 1,default默认为NULL @@ -18895,10 +18558,7 @@ SELECT count(*) FROM sometable; anycompatible - 返回分区中在当前行之后offset行的value; - 如果没有这样的行,则返回default(必须与value兼容的类型)。 - offsetdefault都是针对当前行求值的。 - 如果省略,offset默认为1,defaultNULL。 + 返回在分区内当前行之后offset行处计算的value;如果没有这样的行,则返回default(其类型必须与value兼容)。offsetdefault都针对当前行求值。如果省略,offset默认为 1,default默认为NULL @@ -18953,14 +18613,14 @@ SELECT count(*) FROM sometable; 注意first_valuelast_valuenth_value只考虑窗口帧内的行,它默认情况下包含从分区的开始行直到当前行的最后一个同等行。 这对last_value可能不会给出有用的结果,有时对nth_value也一样。 - 你可以通过向OVER子句增加一个合适的帧声明(RANGEGROUPS)来重定义帧。 + 你可以通过向OVER子句增加一个合适的帧声明(RANGEROWSGROUPS)来重定义帧。 关于帧声明的更多信息请参考 当一个聚合函数被用作窗口函数时,它将在当前行的窗口帧内的行上聚合。 - 一个使用ORDER BY和默认窗口帧定义的聚合产生一种运行时求和类型的行为,这可能是或者不是想要的结果。 - 为了获取在整个分区上的聚合,忽略ORDER BY或者使用ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING。 + 一个使用ORDER BY和默认窗口帧定义的聚合产生一种累计求和类型的行为,这可能是或者不是想要的结果。 + 为了获取在整个分区上的聚合,省略ORDER BY或者使用ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING。 其它窗口帧声明可以用来获得其它的效果。 @@ -18969,7 +18629,7 @@ SELECT count(*) FROM sometable; SQL 标准为leadlagfirst_valuelast_valuenth_value定义了一个RESPECT NULLSIGNORE NULLS选项。 这在PostgreSQL中没有实现:行为总是与标准的默认相同,即RESPECT NULLS。 - 同样,标准中用于nth_valueFROM FIRSTFROM LAST选项没有实现: 只有支持默认的FROM FIRST行为(你可以通过反转ORDER BY的排序达到FROM LAST的结果)。 + 同样,标准中用于nth_valueFROM FIRSTFROM LAST选项没有实现: 只支持默认的FROM FIRST行为(你可以通过反转ORDER BY的排序达到FROM LAST的结果)。 @@ -19005,11 +18665,11 @@ SELECT count(*) FROM sometable; - subquery + 子查询 - 本节描述PostgreSQL中可用的SQL兼容的子查询表达式。所有本节中成文的表达式都返回布尔值(真/假)结果。 + 本节描述PostgreSQL中可用的SQL兼容的子查询表达式。本节介绍的所有表达式形式都返回布尔值(真/假)结果。 @@ -19024,7 +18684,7 @@ EXISTS (subquery) - 子查询可以引用来自周围的查询的变量,这些变量在该子查询的任何一次计算中都起常量的作用。 + 子查询可以引用外层查询的变量,这些变量在该子查询的任何一次计算中都起常量的作用。 @@ -19036,7 +18696,7 @@ EXISTS (subquery) - 下面这个简单的示例类似在col2上的一次内联接,但是它为每个 tab1的行生成最多一个输出,即使存在多个匹配tab2的行也如此∶ + 下面这个简单的示例类似在col2上的一次内连接,但是它为每个 tab1的行最多生成一行输出,即使存在多个匹配tab2的行也如此: SELECT col1 FROM tab1 @@ -19053,15 +18713,15 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 右手边是一个圆括弧括起来的子查询, 它必须正好只返回一个列。左手边表达式将被计算并与子查询结果逐行进行比较。 如果找到任何等于子查询行的情况,那么IN的结果就是。 如果没有找到相等行,那么结果是(包括子查询没有返回任何行的情况)。 + 右手边是一个圆括号括起来的子查询,它必须恰好返回一列。左手边表达式会被求值,并与子查询结果逐行比较。如果找到任意相等的子查询行,那么IN的结果就是。如果没有找到相等行,那么结果就是(包括子查询不返回任何行的情况)。 - 请注意如果左手边表达式得到空值,或者没有相等的右手边值, 并且至少有一个右手边行得到空值,那么IN结构的结果将是空值,而不是假。这个行为是遵照 SQL 处理空值的一般规则的。 + 请注意,如果左侧表达式得到空值,或者右侧没有相等的值且至少有一行得到空值,则IN结构的结果将是空值,而不是假。这符合 SQL 对空值布尔组合的一般规则。 - 和EXISTS一样,假设子查询将被完成运行完全是不明智的。 + 和EXISTS一样,假定子查询一定会完整运行并不明智。 @@ -19069,7 +18729,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 这种形式的IN的左手边是一个行构造器, 如中所述。 右手边是一个圆括弧子查询,它必须返回和左手边返回的行中表达式所构成的完全一样多的列。 左手边表达式将被计算并与子查询结果逐行进行比较。如果找到任意相等的子查询行,则IN的结果为。如果没有找到相等行, 那么结果为(包括子查询不返回行的情况)。 + 这种形式的IN左手边是一个行构造器,如中所述。右手边是一个圆括号括起来的子查询,它必须返回与左手边行中表达式数量完全相同的列数。左手边表达式会被求值,并与子查询结果逐行比较。如果找到任意相等的子查询行,则IN的结果为。如果没有找到相等行,那么结果为(包括子查询不返回任何行的情况)。 @@ -19085,15 +18745,15 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 右手边是一个用圆括弧包围的子查询,它必须返回正好一个列。左手边表达式将被计算并与子查询结果逐行进行比较。 如果只找到不相等的子查询行(包括子查询不返回行的情况),那么NOT IN的结果是。 如果找到任何相等行,则结果为。 + 右手边是一个圆括号括起来的子查询,它必须恰好返回一列。左手边表达式会被求值,并与子查询结果逐行比较。如果只找到不相等的子查询行(包括子查询不返回任何行的情况),那么NOT IN的结果是。如果找到任何相等行,则结果为 - 请注意如果左手边表达式得到空值,或者没有相等的右手边值, 并且至少有一个右手边行得到空值,那么NOT IN结构的结果将是空值,而不是真。这个行为是遵照 SQL 处理空值的一般规则的。 + 请注意,如果左侧表达式得到空值,或者右侧没有相等的值且至少有一行得到空值,则NOT IN结构的结果将是空值,而不是真。这符合 SQL 对空值布尔组合的一般规则。 - 和EXISTS一样,假设子查询将被完成运行完全是不明智的。 + 和EXISTS一样,假定子查询一定会完整运行并不明智。 @@ -19101,7 +18761,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 这种形式的NOT IN的左手边是一个行构造器, 如中所述。 右手边是一个圆括弧子查询,它必须返回和左手边返回的行中表达式所构成的完全一样多的列。 左手边表达式将被计算并与子查询结果逐行进行比较。如果找到不等于子查询行的行,则NOT IN的结果为。如果找到相等行, 那么结果为(包括子查询不返回行的情况)。 + 这种形式的NOT IN左侧是一个行构造器,如中所述。右侧是一个用圆括号括起来的子查询,必须返回与左侧行中表达式数量完全相同的列数。对左侧表达式求值后,将其按行与子查询结果的每一行比较。如果只找到不相等的子查询行(包括子查询不返回任何行的情况),则NOT IN的结果为。如果找到任何相等行,则结果为 @@ -19119,7 +18779,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 这种形式的右侧是一个用括号括起来的子查询,它必须恰好返回一列。左侧表达式会被求值,并使用给定的 operator 与子查询结果的每一行进行比较。如果得到任何真值结果,那么ANY的结果就是。如果没有找到真值结果,那么结果是(包括子查询没有返回任何行的情况)。 + 这种形式的右侧是一个用括号括起来的子查询,它必须恰好返回一列。左侧表达式会被求值,并使用给定的 operator 与子查询结果的每一行进行比较。该操作符必须产生布尔结果。如果得到任何真值结果,那么ANY的结果就是。如果没有找到真值结果,那么结果是(包括子查询没有返回任何行的情况)。 @@ -19127,11 +18787,11 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 请注意如果没有任何成功并且至少有一个右手边行为该操作符结果生成空值, 那么ANY结构的结果将是空值,而不是假。 这个行为是遵照 SQL 处理空值布尔组合的一般规则制定的。 + 请注意,如果没有任何比较返回真,并且至少有一个右侧行的操作符结果为空值,则ANY结构的结果将是空值,而不是假。这符合 SQL 对空值布尔组合的一般规则。 - 和EXISTS一样,假设子查询将被完成运行完全是不明智的。 + 和EXISTS一样,假定子查询一定会完整运行并不明智。 @@ -19140,7 +18800,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 这种形式的左侧是一个行构造器,如所述。右侧是一个用括号括起来的子查询,它必须返回与左侧行中表达式数量完全相同的列数。左侧表达式会被求值,并使用给定的operator与子查询结果的每一行逐行比较。如果比较对任何子查询行返回真,则ANY的结果为。如果比较对每一个子查询行都返回假,则结果为(包括子查询不返回行的情况)。如果比较对任何行都不返回真,并且至少有一次比较返回 NULL,则结果为 NULL。 + 这种形式的ANY左侧是一个行构造器,如所述。右侧是一个用括号括起来的子查询,它必须返回与左侧行中表达式数量完全相同的列数。左侧表达式会被求值,并使用给定的operator与子查询结果的每一行逐行比较。如果比较对任何子查询行返回真,则ANY的结果为。如果比较对每一个子查询行都返回假,则结果为(包括子查询不返回行的情况)。如果比较对任何行都不返回真,并且至少有一次比较返回 NULL,则结果为 NULL。 @@ -19156,7 +18816,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 这种形式的 ALL 右侧是一个用括号括起来的子查询,它必须只返回一列。左侧表达式会被求值,并使用给定的 operator 与子查询结果的每一行进行比较。该操作符必须产生布尔结果。如果所有行都得到真(包括子查询没有返回任何行的情况),ALL 的结果就是。如果发现任何假值结果,结果就是。如果比较对任何行都不返回假,并且至少有一次比较返回 NULL,则结果为 NULL。 + 右侧是一个用圆括号括起来的子查询,必须恰好返回一列。左侧表达式会被求值,并使用给定的operator与子查询结果的每一行进行比较。该操作符必须产生布尔结果。如果所有行都得到真(包括子查询不返回任何行的情况),则ALL的结果为。如果得到任何假值结果,则结果为。如果与任何子查询行的比较都不返回假,并且至少有一次比较返回 NULL,则结果为 NULL。 @@ -19164,7 +18824,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 和EXISTS一样,假设子查询将被完成运行完全是不明智的。 + 和EXISTS一样,假定子查询一定会完整运行并不明智。 @@ -19194,7 +18854,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 左手边是一个行构造器,如所述。 右手边是一个圆括弧括起来的子查询,该查询必须返回和左手边行中表达式数目完全一样的列。 另外,该子查询不能返回超过一行的数量(如果它返回零行,那么结果就是空值)。 左手边被计算并逐行与右手边的子查询结果行比较。 + 左侧是一个行构造器,如所述。右侧是一个用圆括号括起来的子查询,必须返回与左侧行中表达式数量完全相同的列数。此外,该子查询不能返回超过一行;如果它返回零行,则结果为空值。对左侧求值后,将所得的行与子查询返回的唯一一行进行比较。 @@ -19233,12 +18893,12 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 逐行比较 + 行比较 比较 - 逐行 + 复合类型 @@ -19255,7 +18915,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 本节描述几个特殊的结构,用于在值的组之间进行多重比较。这些形式语法上和前面一节的子查询形式相关,但是不涉及子查询。 这种形式涉及的数组子表达式是PostgreSQL的扩展; 其它的是SQL兼容的。所有本节记录的表达式形式都返回布尔(Boolean)结果(真/假)。 + 本节描述几个特殊的结构,用于在值的组之间进行多重比较。这些形式语法上和前面一节的子查询形式相关,但是不涉及子查询。 涉及数组子表达式的形式是PostgreSQL的扩展; 其余形式是SQL兼容的。本节介绍的所有表达式形式都返回布尔(Boolean)结果(真/假)。 @@ -19266,14 +18926,12 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 右侧是一个用括号括起来的表达式列表。如果左侧表达式的结果等于右侧任何一个表达式的结果,则结果为true。 - 这是一个简写表示法,如下所示: - + 右侧是一个用圆括号括起来的表达式列表。如果左侧表达式的结果等于右侧任一表达式的结果,则结果为。这等价于以下写法: expression = value1 -或 +OR expression = value2 -或 +OR ... @@ -19291,9 +18949,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 右侧是一个用括号括起来的表达式列表。如果左侧表达式的结果与所有右侧表达式都不相等,则结果为true。 - 这是一个简写表示法,用于 - + 右侧是一个用圆括号括起来的表达式列表。如果左侧表达式的结果与右侧所有表达式的结果都不相等,则结果为。这等价于以下写法: expression <> value1 AND @@ -19317,7 +18973,7 @@ AND - <literal>ANY</literal>/<literal>SOME</literal> (array) + <literal>ANY</literal>/<literal>SOME</literal>(数组) expression operator ANY (array expression) @@ -19339,7 +18995,7 @@ AND - <literal>ALL</literal> (array) + <literal>ALL</literal>(数组) expression operator ALL (array expression) @@ -19363,20 +19019,7 @@ AND - 每一边都是一个行构造器, - 如在中描述的那样。 - 这两个行构造器必须具有相同数量的字段。 - 给定的operator应用于每一对 - 对应的字段。(由于字段可能是不同类型的,这意味着每对可能选择不同的具体操作符。) - 所有选定的操作符必须是某个B-树操作符类的成员,或者是B-树操作符类的=成员的否定形式, - 这意味着只有当operator是 - =、 - <>、 - <、 - <=、 - >或 - >=时才可能进行行构造器比较, - 或者具有类似于这些操作符的语义。 + 两侧都是行构造器,如所述。两个行构造器必须具有相同数量的字段。给定的operator应用于每一对对应字段。(由于字段可能具有不同的类型,因此可能为各对字段选择不同的具体操作符。)所选操作符必须是某个 B-树操作符类的成员,或者是 B-树操作符类中=成员的否定操作符。这意味着只有当operator=<><<=>>=,或具有与这些操作符类似的语义时,才可以进行行构造器比较。 @@ -19421,21 +19064,21 @@ AND - SQL 规范要求在结果依赖于比较两个 NULL 值或者一个 NULL 与一个非 NULL 时逐行比较返回 NULL。 + SQL 规范要求在结果依赖于比较两个 NULL 值或者一个 NULL 与一个非 NULL 时行比较返回 NULL。 PostgreSQL只有在比较两个行构造器(如)的结果或者比较一个行构造器与一个子查询的输出时才这样做(如中所述)。 - 在其他比较两个复合类型值的环境中,两个 NULL 域值被认为相等,并且一个 NULL 被认为大于一个非 NULL。 + 在其他比较两个复合类型值的环境中,两个 NULL 字段值被认为相等,并且一个 NULL 被认为大于一个非 NULL。 为了得到复合类型的一致的排序和索引行为,这样做是必要的。 - 每一边都会被计算并且它们会被逐行比较。当operator是 + 对两侧分别求值后,按行进行比较。当operator=<><<=>或者 - >=时或者具有与这些类似的语义时,允许复合类型的比较(更准确地说,如果一个操作符是一个 B-树操作符类的成员,或者是一个 B-树操作符类的=成员的否定词,它就可以是一个行比较操作符)。 - 上述操作符的行为与用于行构造器(见)的IS [ NOT ] DISTINCT FROM相同。 + >=时或者具有与这些类似的语义时,允许复合类型的比较(更准确地说,如果一个操作符是一个 B-树操作符类的成员,或者是一个 B-树操作符类的=成员的否定操作符,它就可以是一个行比较操作符)。 + 上述操作符的默认行为与用于行构造器(见)的IS [ NOT ] DISTINCT FROM相同。 @@ -19446,9 +19089,9 @@ AND *<=*>以及 *>=。 - 这些操作符比较两行的内部二进制表达。即使两行用相等操作符的比较为真,两行也可能具有不同的二进制表达。 - 行在这些比较操作符之下的排序是决定性的,其他倒没什么意义。 - 这些操作符在内部被用于物化视图并且可能对其他如复制和B-树复制(参见 )之类的特殊功能有用,但是它们并不打算用在书写查询这类普通用途中。 + 这些操作符比较两行的内部二进制表示。即使两行用相等操作符的比较为真,两行也可能具有不同的二进制表示。 + 使用这些比较操作符得到的行排序是确定的,但除此之外没有其他意义。 + 这些操作符在内部被用于物化视图并且可能对其他如复制和 B-树去重(参见 )之类的特殊功能有用,但是它们并不打算用在书写查询这类普通用途中。 @@ -19463,13 +19106,13 @@ AND - 本节描述那些可能返回多于一行的函数。目前这个类中被使用最广泛的是级数生成函数, 如所述。其他更特殊的集合返回函数在本手册的其他地方描述。 - 组合多集合返回函数的方法可见。 + 本节描述那些可能返回多于一行的函数。目前这个类中被使用最广泛的是序列生成函数, 如所述。其他更特殊的集合返回函数在本手册的其他地方描述。 + 组合多个集合返回函数的方法可见 - 级数生成函数 + 序列生成函数 @@ -19524,9 +19167,7 @@ AND
- 当step为正时,如果start大于stop则返回零行。 - 相反,当step为负时,如果start小于stop则返回零行。 - 如果任何输入为NULL也会返回零行。step为零是一个错误。下面是一些示例: + 当step为正数时,如果start大于stop,则返回零行。反之,当step为负数时,如果start小于stop,则返回零行。如果任一输入为NULL,也返回零行。如果step为零,则会报错。下面是一些示例: SELECT * FROM generate_series(2,4); generate_series @@ -19557,7 +19198,7 @@ SELECT generate_series(1.1, 4, 1.3); 3.7 (3 rows) --- this example relies on the date-plus-integer operator: +-- 此示例使用日期加整数的操作符: SELECT current_date + s.a AS dates FROM generate_series(0,14,7) AS s(a); dates ------------ @@ -19610,7 +19251,7 @@ SELECT * FROM generate_series('2008-03-01 00:00'::timestamp, setof integer - 生成一个包含给定数组第dim维度的有效下标的序列。 + 生成一个包含给定数组第dim维的有效下标的序列。 @@ -19620,7 +19261,7 @@ SELECT * FROM generate_series('2008-03-01 00:00'::timestamp, setof integer
- 生成一个包含给定数组第dim维度的有效下标的序列。当reverse为真时,以相反的顺序返回序列。 + 生成一个包含给定数组第dim维的有效下标的序列。当reverse为真时,以相反的顺序返回序列。 @@ -19629,9 +19270,9 @@ SELECT * FROM generate_series('2008-03-01 00:00'::timestamp, generate_subscripts是一个快捷函数,它为给定数组的指定维度生成一组合法的下标。 - 对于不具有请求维度的数组返回零行,对于任何输入为NULL数组也返回零行。下面是一些示例: + 如果数组不具有所请求的维度,或者任一输入为NULL,则返回零行。下面是一些示例: --- basic usage: +-- 基本用法: SELECT generate_subscripts('{NULL,1,NULL,2}'::int[], 1) AS s; s --- @@ -19641,8 +19282,8 @@ SELECT generate_subscripts('{NULL,1,NULL,2}'::int[], 1) AS s; 4 (4 rows) --- presenting an array, the subscript and the subscripted --- value requires a subquery: +-- 展示数组、下标和下标对应的值 +-- 需要使用子查询: SELECT * FROM arrays; a -------------------- @@ -19661,7 +19302,7 @@ FROM (SELECT generate_subscripts(a, 1) AS s, a FROM arrays) foo; {100,200,300} | 3 | 300 (5 rows) --- unnest a 2D array: +-- 展开二维数组: CREATE OR REPLACE FUNCTION unnest2(anyarray) RETURNS SETOF anyelement AS $$ select $1[i][j] @@ -19681,15 +19322,13 @@ SELECT * FROM unnest2(ARRAY[[1,2],[3,4]]); - ordinality + 序号 - 当FROM子句中的函数以WITH ORDINALITY作为后缀时,将在函数的输出列上附加一个bigint列,该列从1开始,函数输出的每一行加1。 - 这在 unnest()等集合返回函数的情况下最有用。 - + 当FROM子句中的函数后面加上WITH ORDINALITY时,一个bigint列会追加到函数的输出列中,其值从 1 开始,对函数输出的每一行递增 1。这种方式对集合返回函数尤其有用,例如unnest() --- set returning function WITH ORDINALITY: +-- 集合返回函数与 WITH ORDINALITY: SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); ls | n -----------------+---- @@ -19723,7 +19362,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); 系统信息函数和操作符 - 展示了多个可以抽取会话和系统信息的函数。 + 列出了多个用于提取会话和系统信息的函数。 @@ -19764,7 +19403,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); name - 返回当前数据库的名称。(在SQL标准中数据库被称为catalogs,因此current_catalog是该标准的拼写方式。) + 返回当前数据库的名称。(SQL 标准将数据库称为目录(catalogs),因此current_catalog是标准中的写法。) @@ -19777,7 +19416,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); text - 返回当前所执行查询的文本,由客户端提交的(可能包含一个以上的语句)。 + 返回客户端提交的当前正在执行的查询文本(可能包含多条语句)。 @@ -19800,8 +19439,8 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); current_schema - schema - current + 模式 + 当前 current_schema name @@ -19822,16 +19461,14 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); current_schemas - search path - current + 搜索路径 + 当前 current_schemas ( include_implicit boolean ) name[]
- 返回当前在有效搜索路径中的所有模式的名称的数组,以优先级顺序。 - (当前 设置中与已存在的、可搜索模式不相符的项将被省略。) - 如果布尔参数为true,则类似pg_catalog的隐式搜索的系统模式将包含在结果中。 + 返回当前有效搜索路径中所有模式名称的数组,按优先级排序。(当前设置中不对应于已存在且可搜索的模式的项会被省略。)如果布尔参数为true,结果还会包含pg_catalog等隐式搜索的系统模式。 @@ -19841,8 +19478,8 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); current_user - user - current + 用户 + 当前 current_user name @@ -19861,7 +19498,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); inet
- 返回当前客户端的IP地址,如果当前连接是通过Unix-域套接字则返回NULL + 返回当前客户端的 IP 地址;如果当前连接通过 Unix 域套接字建立,则返回NULL @@ -19874,7 +19511,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); integer
- 返回当前客户端的IP端口号,如果当前连接是通过Unix-域套接字则返回NULL。 + 返回当前客户端的IP端口号,如果当前连接是通过Unix 域套接字则返回NULL @@ -19887,7 +19524,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); inet
- 返回服务器接受当前连接的IP地址,如果当前连接是通过Unix-域套接字则返回NULL。 + 返回服务器接受当前连接的IP地址,如果当前连接是通过Unix 域套接字则返回NULL @@ -19900,7 +19537,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); integer
- 返回服务器接受当前连接的IP端口号,如果当前连接是通过Unix-域套接字则返回NULL。 + 返回服务器接受当前连接的IP端口号,如果当前连接是通过Unix 域套接字则返回NULL @@ -19926,12 +19563,10 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); integer[] - 返回阻止服务器进程的会话的进程ID数组,该进程ID与指定的进程ID一起获取锁定,如果没有这样的服务器进程或者没有被阻塞,则返回一个空数组。 + 返回一个数组,包含阻止指定进程 ID 对应的服务器进程获取锁的会话进程 ID;如果不存在这样的服务器进程,或该进程未被阻塞,则返回空数组。 - 如果一个服务器进程持有一个与被阻塞进程的锁请求冲突的锁(硬阻塞),或者正在等待一个与被阻塞进程的锁请求冲突并且在等待队列中位于其前面的锁(软阻塞),那么这个服务器进程就会阻塞另一个服务器进程。 - 当使用并行查询时结果总是列出客户端可见的进程ID(即pg_backend_pid的结果),即使实际的锁是由子工作进程持有或等待的。 - 因此,结果中可能存在重复的pid。还要注意当准备好的事务持有冲突锁时,它将用零进程ID表示。 + 一个服务器进程会在以下情况下阻塞另一个进程:它持有与被阻塞进程请求的锁冲突的锁(硬阻塞);或者它正在等待一个会与被阻塞进程请求的锁冲突的锁,并且在等待队列中位于被阻塞进程之前(软阻塞)。使用并行查询时,即使实际持锁或等待锁的是子工作进程,结果也始终列出客户端可见的进程 ID(即pg_backend_pid的结果)。因此,结果中可能出现重复的 PID。另外,如果持有冲突锁的是一个预备事务,结果中会用进程 ID 0 表示它。 频繁调用这个函数可能会对数据库性能产生一些影响,因为它需要在短时间内独占访问锁管理器的共享状态。 @@ -19947,8 +19582,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); timestamp with time zone - 返回服务器配置文件最后加载的时间。如果当前会话当时是活跃的,那么这将是会话本身重新读取配置文件的时间(因此在不同的会话中读取会稍有不同)。 - 否则,就是postmaster进程重新读取配置文件的时间。 + 返回服务器配置文件最近一次加载的时间。如果当时当前会话已经存在,则返回该会话自身重新读取配置文件的时间(因此不同会话中的返回时间会略有不同)。否则,返回 postmaster 进程重新读取配置文件的时间。 @@ -19958,16 +19592,16 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); pg_current_logfile - Logging - pg_current_logfile函数 + 日志记录 + pg_current_logfile 函数 current_logfiles - 和pg_current_logfile函数 + 和pg_current_logfile 函数 - Logging - current_logfiles文件和pg_current_logfile函数 + 日志记录 + current_logfiles 文件和pg_current_logfile 函数 pg_current_logfile ( text ) text @@ -19982,9 +19616,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); 如果请求的日志格式未在中配置,则结果为NULL。 结果反映current_logfiles文件的内容。 - - 默认情况下,此函数仅限于超级用户以及具有pg_monitor角色权限的角色,但可以向其他用户授予 EXECUTE 权限以运行该函数。 - + @@ -20026,18 +19658,6 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); - - - - pg_numa_available - - pg_numa_available () - boolean - - - 如果服务器在编译时启用了 NUMA 支持,则返回真。 - - @@ -20061,7 +19681,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); double precision - 返回当前被等待处理的通知所占用的异步通知队列最大尺寸的分数(0–1)。更多信息请参见。 + 返回待处理通知当前占用的空间占异步通知队列最大容量的比例(0–1)。更多信息请参见 @@ -20087,11 +19707,11 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); integer[] - 返回一个进程ID数组,该进程ID是阻塞服务器进程获取安全快照的会话的进程ID数组,如果没有这样的服务器进程或者没有阻塞,则返回一个空数组。 + 返回一个数组,包含阻止指定进程 ID 对应的服务器进程获取安全快照的会话进程 ID;如果不存在这样的服务器进程,或该进程未被阻塞,则返回空数组。 运行SERIALIZABLE事务的会话会阻止SERIALIZABLE READ ONLY DEFERRABLE事务获取快照,直到后者确定可以安全地避免获取谓词锁。 - 关于可串行化和可延迟事务的更多信息,请参见。 + 关于可序列化和可延迟事务的更多信息,请参见 频繁调用这个函数可能会对数据库性能产生一些影响,因为它需要在短时间内访问谓词锁管理器的共享状态。 @@ -20107,7 +19727,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); integer - 返回当前嵌套层次的PostgreSQL触发器(如果没有调用则为 0,直接或间接,从一个触发器内部开始)。 + 返回PostgreSQL触发器的当前嵌套层级(如果不是从触发器内部直接或间接调用,则为 0)。 @@ -20120,7 +19740,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); name - 返回会话用户名. + 返回会话用户名。 @@ -20137,7 +19757,8 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); - + + version @@ -20146,9 +19767,12 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); text - 返回描述PostgreSQL服务器的版本的字符串。 - 你还可以从 中获得此信息,或者对于机器可读的版本,使用。 - 软件开发人员可以使用server_version_num(从8.2起可用)或,而不是解析文本版本。 + 返回描述PostgreSQL + 服务器版本的字符串。你还可以从 + 获得此信息,或者对于机器可读的 + 版本,使用。软件 + 开发人员应该使用server_version_num(自 8.2 起可用) + 或,而不是解析文本版本。 @@ -20158,32 +19782,21 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); - current_catalogcurrent_rolecurrent_schemacurrent_usersession_useruserSQL里有特殊的语法地位: 它们被调用时结尾不要跟着圆括号。 - 在 PostgreSQL 中,圆括号可以有选择性地被用于current_schema,但是不能和其他的一起用。 + current_catalogcurrent_rolecurrent_schemacurrent_usersession_useruserSQL中具有特殊语法:调用时不得在后面加圆括号。在 PostgreSQL 中,current_schema可以选择加圆括号,其他函数则不可以。 - session_user通常是发起当前数据库连接的用户,不过超级用户可以用修改这个设置。 - current_user是用于权限检查的用户标识。通常, 它总是等于会话用户,但是可以被改变。 - 它也会在函数执行的过程中随着属性SECURITY DEFINER的改变而改变。 - 在 Unix 的说法里,那么会话用户是真实用户,而当前用户是有效用户。 - current_role以及usercurrent_user的同义词(SQL标准在current_rolecurrent_user之间做了区分,但PostgreSQL不区分,因为它把用户和角色统一成了一种实体)。 + session_user通常是发起当前数据库连接的用户,但超级用户可以用修改此设置。current_user是用于权限检查的用户标识,通常等于会话用户,但可以用更改。在执行具有SECURITY DEFINER属性的函数期间,它也会改变。用 Unix 的术语来说,会话用户是真实用户,当前用户是有效用户current_roleusercurrent_user的同义词。(SQL 标准区分current_rolecurrent_user,但PostgreSQL不区分,因为它将用户和角色统一为同一种实体。) - privilege - querying + 权限 + 查询 - 列出那些允许编程查询对象访问权限的函数。参阅获取更多有关权限的信息。 - 在这些函数中,可以通过名称或OID (pg_authid.oid)指定被查询权限的用户,或者如果名称被指定为public,则检查PUBLIC伪角色的权限。 - 同样,user参数可以完全省略,在这种情况下,假设为current_user。被查询的对象也可以通过名称或OID来指定。 - 通过名称指定时,可以包含相关的模式名称。感兴趣的访问权限由一个文本字符串指定,它必须计算为对象类型的一个适当的权限关键字(例如,SELECT)。 - 还可以将 WITH GRANT OPTION添加到权限类型中,以测试该权限是否由授予选项持有。 - 同样,可以用逗号分隔列出多个权限类型,在这种情况下,如果所列出的权限中有任何一个被持有,结果将为真。 - (权限字符串的大小写不重要,权限名之间允许有额外的空格,但在权限名中不允许。)一些示例: + 列出了允许以编程方式查询对象访问权限的函数。(关于权限的更多信息,请参见。)在这些函数中,可以通过名称或 OID(pg_authid.oid)指定要查询权限的用户;如果名称为public,则检查 PUBLIC 伪角色的权限。也可以完全省略user参数,此时使用current_user。要查询的对象也可以通过名称或 OID 指定。通过名称指定时,如适用,可以包含模式名。所需访问权限由文本字符串指定,其值必须为适用于该对象类型的权限关键字之一(例如SELECT)。还可以在权限类型后附加WITH GRANT OPTION,以检查是否拥有该权限及其授予选项。也可以用逗号分隔列出多个权限类型;只要拥有列出的任一权限,结果就为真。(权限字符串不区分大小写,权限名之间允许有额外的空白,但权限名内部不允许。)例如: SELECT has_table_privilege('myschema.mytable', 'select'); SELECT has_table_privilege('joe', 'mytable', 'INSERT, SELECT WITH GRANT OPTION'); @@ -20220,9 +19833,7 @@ SELECT has_table_privilege('joe', 'mytable', 'INSERT, SELECT WITH GRANT OPTION') boolean - 用户是否对表的任何列有权限? - 如果对整个表持有权限,或者对至少一个列有列级的权限授予,则会成功。 - 允许的权限类型为SELECT, INSERT,UPDATE, 和 REFERENCES + 用户是否对表的至少一列具有权限?如果拥有整个表的权限,或至少一列获得了该权限的列级授权,则返回真。允许的权限类型为SELECTINSERTUPDATEREFERENCES @@ -20273,7 +19884,7 @@ SELECT has_table_privilege('joe', 'mytable', 'INSERT, SELECT WITH GRANT OPTION') boolean - 用户是否拥有外部数据包装的权限?唯一允许的权限类型是USAGE。 + 用户是否具有外部数据包装器权限?唯一允许的权限类型为USAGE @@ -20315,21 +19926,6 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); - - - - has_largeobject_privilege - - has_largeobject_privilege ( - user name or oid, - largeobject oid, - privilege text ) - boolean - - - 用户是否拥有大对象的权限?可用的权限类型是 SELECTUPDATE。 - - @@ -20377,7 +19973,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); boolean - 用户是否有顺序权限?允许的权限类型有USAGE, SELECT, 和UPDATE。 + 用户是否具有序列权限?允许的权限类型为USAGESELECTUPDATE @@ -20409,7 +20005,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); boolean - 用户对表有权限吗?允许的权限类型有SELECTINSERTUPDATEDELETETRUNCATEREFERENCESTRIGGERMAINTAIN。 + 用户是否具有表权限?允许的权限类型为SELECTINSERTUPDATEDELETETRUNCATEREFERENCESTRIGGER @@ -20457,13 +20053,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); privilege text ) boolean - - 用户对角色有权限吗?允许的权限类型有MEMBERUSAGESET。 - MEMBER表示对该角色的直接或间接成员资格,而不考虑由此授予的具体权限。 - USAGE表示该角色的权限是否无需执行SET ROLE即可立即使用,而SET表示是否可以使用SET ROLE命令切换到该角色。 - 任一权限类型后面都可以附加WITH ADMIN OPTIONWITH GRANT OPTION,用于测试是否持有 ADMIN 权限(这六种写法测试的都是同一件事)。 - 此函数不允许特殊情况下将user设置为public,因为PUBLIC伪角色永远不能成为真实角色的成员。 - + 用户是否具有角色权限?允许的权限类型为 MEMBERUSAGEMEMBER 表示该角色的直接或间接成员资格(即执行 SET ROLE 的权限),而 USAGE 表示无需执行 SET ROLE 就能立即使用该角色的权限。任一权限类型后面都可以附加 WITH ADMIN OPTIONWITH GRANT OPTION,以测试是否持有 ADMIN 权限(这四种写法测试的都是同一件事)。此函数不允许将 user 设置为 public 这一特殊情况,因为 PUBLIC 伪角色永远不能成为实际角色的成员。 @@ -20476,7 +20066,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); boolean - 在当前用户和当前环境的上下文之中,指定表的行级安全是活动的吗? + 在当前用户和当前环境的上下文中,指定表的行级安全性是否生效? @@ -20484,8 +20074,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); - 显示了aclitem类型的可用操作符,它是访问权限的目录表示。 - 有关如何读取访问权限值的信息,请参阅 。 + 列出了aclitem类型可用的操作符;该类型是访问权限在系统目录中的表示形式。有关如何解读访问权限值的信息,请参见 @@ -20518,8 +20107,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); boolean - aclitem相等吗?(注意,aclitem类型缺少比较操作符的通常集合;它只有相等。 - 反而言之,aclitem数组只能进行相等比较。) + 两个aclitem是否相等?(注意,aclitem类型没有通常的整套比较操作符,而只支持相等比较。因此,aclitem数组也只能进行相等比较。) 'calvin=r*w/hobbes'::aclitem = 'calvin=r*w*/hobbes'::aclitem @@ -20536,7 +20124,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); boolean - 数组是否包含指定的权限?(如果有一个数组条目与aclitem的被授权人和授予人相匹配,并且至少具有权限的指定集,则此选项为真。) + 数组是否包含指定的权限?(如果数组中存在一个条目,其被授权者和授权者与该aclitem相同,且至少包含指定的全部权限,则返回真。) '{calvin=r*w/hobbes,hobbes=r*w*/postgres}'::aclitem[] @> 'calvin=r*/hobbes'::aclitem @@ -20548,7 +20136,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute');
- 显示了一些额外的函数来管理aclitem类型。 + 列出了一些用于管理aclitem类型的其他函数。 @@ -20580,23 +20168,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); aclitem[] - 构造一个aclitem数组,保存属于具有OID ownerId的角色的对象类型type的默认访问权限。 - 这表示当对象的ACL条目为空时将假定的访问权限。(默认访问权限在中描述。) - type参数必须是以下之一: - 'c'表示COLUMN, - 'r'表示TABLE和类似表的对象, - 's'表示SEQUENCE, - 'd'表示DATABASE, - 'f'表示FUNCTIONPROCEDURE, - 'l'表示LANGUAGE, - 'L'表示LARGE OBJECT, - 'n'表示SCHEMA, - 'p'表示PARAMETER, - 't'表示TABLESPACE, - 'F'表示FOREIGN DATA WRAPPER, - 'S'表示FOREIGN SERVER, - 或 - 'T'表示TYPEDOMAIN。 + 构造一个aclitem数组,保存类型为type、属于 OID 为ownerId的角色的对象的默认访问权限。当对象的ACL条目为空值时,会采用这些访问权限。(默认访问权限见。)type参数必须为以下值之一:'c' 表示COLUMN,'r' 表示TABLE和类似表的对象,'s' 表示SEQUENCE,'d' 表示DATABASE,'f' 表示FUNCTIONPROCEDURE,'l' 表示LANGUAGE,'L' 表示LARGE OBJECT,'n' 表示SCHEMA,'p' 表示PARAMETER,'t' 表示TABLESPACE,'F' 表示FOREIGN DATA WRAPPER,'S' 表示FOREIGN SERVER,'T' 表示TYPEDOMAIN @@ -20613,9 +20185,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); is_grantableboolean ) - 以行集的形式返回aclitem数组。如果受让人是伪角色PUBLIC,则在grantee列中用0表示。 - 每个被授予的权限都表示为SELECT, INSERT等。 - 注意,每个权限被分割成单独的一行,因此在privilege_type列中只出现一个关键字。 + 以行集的形式返回aclitem数组。如果被授权者是伪角色 PUBLIC,则在grantee列中用零表示。每项授予的权限表示为SELECTINSERT等。注意,每项权限都会拆成单独的一行,因此privilege_type列中只会出现一个关键字。 @@ -20640,14 +20210,9 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute');
- 展示了决定是否一个特定对象在当前模式搜索路径中可见的函数。 - 例如,如果一个表所在的模式在当前搜索路径中并且在它之前没有出现过相同的名字,这个表就被说是可见的。 - 这等价于在语句中表可以被用名称引用但不加显式的模式限定。因此,要列出所有可见表的名字: - + 列出了判断某个特定对象是否可见的函数,其判断依据是当前模式搜索路径。例如,如果表所在的模式位于搜索路径中,并且在搜索路径的更前面没有同名表,就称该表可见。这等价于说,可以只通过表名引用该表,而不必显式地用模式限定。因此,要列出所有可见表的名称: SELECT relname FROM pg_class WHERE pg_table_is_visible(oid); - - 对于函数和操作符,如果路径前面没有相同名称和参数数据类型的对象,那么搜索路径中的对象就是可见的。 - 对于操作符类和操作符族,要考虑名称和关联的索引访问方法。 +对于函数和操作符,只要搜索路径中更靠前的位置没有对象具有与被检查对象相同的名称和参数数据类型,就称被检查对象可见。对于操作符类和操作符族,会同时考虑名称及关联的索引访问方法。 @@ -20786,7 +20351,7 @@ SELECT relname FROM pg_class WHERE pg_table_is_visible(oid); boolean - 文本搜索配置在搜索路径可见吗? + 全文检索配置是否在搜索路径中可见? @@ -20799,7 +20364,7 @@ SELECT relname FROM pg_class WHERE pg_table_is_visible(oid); boolean - 文本搜索字典在搜索路径可见吗? + 全文检索词典是否在搜索路径中可见? @@ -20812,7 +20377,7 @@ SELECT relname FROM pg_class WHERE pg_table_is_visible(oid); boolean - 文本搜索解析器在搜索路径中可见吗? + 全文检索解析器是否在搜索路径中可见? @@ -20825,7 +20390,7 @@ SELECT relname FROM pg_class WHERE pg_table_is_visible(oid); boolean - 文本搜索模板在搜索路径可见吗? + 全文检索模板是否在搜索路径中可见? @@ -20846,11 +20411,10 @@ SELECT relname FROM pg_class WHERE pg_table_is_visible(oid); - 所有这些函数都要求用对象 OID 来标识将被检查的对象。如果你想用名称来测试一个对象,使用 OID 别名类型(regclassregtyperegprocedureregoperatorregconfigregdictionary)将会很方便。例如: - + 所有这些函数都需要用对象 OID 标识要检查的对象。如果想按名称测试对象,使用 OID 别名类型会很方便(regclassregtype, + regprocedureregoperatorregconfig,或regdictionary),例如: SELECT pg_type_is_visible('myschema.widget'::regtype); - - 注意以这种方式测试一个非模式限定的类型名没什么意义 — 如果该名称完全能被识别,它必须是可见的。 +注意,用这种方式测试不带模式限定的类型名并没有太大意义:只要该名称能够被识别,它就必然可见。 @@ -20934,7 +20498,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); 返回一组记录,描述存在于PostgreSQL系统目录中的外键关系。 fktable 列包含引用目录的名称,fkcols列包含引用列的名称。 类似地,pktable列包含被引用目录的名称,而pkcols列包含被引用列的名称。 - 如果is_array为真,则最后一个引用列是一个数组,其每个元素都应该与引用目录中的某个条目匹配。 + 如果is_array为真,则最后一个引用列是一个数组,其每个元素都应该与被引用目录中的某个条目匹配。 如果is_opt为真,则允许引用列包含零而不是有效引用。 @@ -20948,7 +20512,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 重构为了约束的创建命令。(这是一个反编译的重构,而不是命令的原始文本。) + 重建约束的创建命令。(这是反编译重建的结果,并非命令的原始文本。) @@ -20961,8 +20525,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 反编译存储在系统目录中的表达式的内部形式,例如列的默认值。 - 如果表达式可能包含变量,则指定它们所指向的关系的OID作为第二个参数;如果没有预期的变量,传递0就可以了。 + 反编译存储在系统目录中的表达式的内部形式,例如列的默认值。如果表达式可能包含 Var 节点,请将它们所引用的关系的 OID 指定为第二个参数;如果预计不含 Var 节点,传入零即可。 @@ -20975,8 +20538,8 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 重构为了函数或过程的创建命令。(这是一个反编译的重构,而不是命令的原始文本。) - 结果是一个完整的CREATE OR REPLACE FUNCTIONCREATE OR REPLACE PROCEDURE语句。 + 重建函数或过程的创建命令。(这是反编译重建的结果,并非命令的原始文本。) + 结果是一条完整的CREATE OR REPLACE FUNCTIONCREATE OR REPLACE PROCEDURE语句。 @@ -20989,7 +20552,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 重新构造函数或过程的参数列表,以其在 CREATE FUNCTION里面需要出现的形式(包括默认值)。 + 重建函数或过程的参数列表,采用其在CREATE FUNCTION中应有的形式(包括默认值)。 @@ -21002,7 +20565,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 重新构造标识函数或过程所需的参数列表,以其应出现在ALTER FUNCTION等命令中的形式。这个表单省略默认值。 + 重建标识函数或过程所需的参数列表,采用其在ALTER FUNCTION等命令中应有的形式。这种形式省略默认值。 @@ -21015,7 +20578,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 重构函数的RETURNS子句,以其需要出现在CREATE FUNCTION中的形式。对于过程,返回NULL。 + 重建函数的RETURNS子句,采用其在CREATE FUNCTION中应有的形式。对于过程,返回NULL @@ -21028,7 +20591,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 重构针对索引的创建命令。(这是一个反编译的重构,而不是命令的原始文本。)如果提供了column而且不为零,则只重构该列的定义。 + 重建索引的创建命令。(这是反编译重建的结果,并非命令的原始文本。)如果提供了column而且不为零,则只重建该列的定义。 @@ -21046,11 +20609,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); baredesc text ) - 返回一组描述服务器识别的SQL关键字的记录。word列包含关键字。 - catcode列包含一个类别代码:U表示无保留关键字,C表示可以是列名的关键字,T表示可以是类型或函数名的关键字,或者R表示完全保留关键字。 - 如果关键字可以在SELECT列表中用作bare列标签,则barelabel列包含true,或者false,如果它只能在AS之后使用。 - catdesc列包含可能本地化字符串,描述关键字的类别。 - baredesc列包含可能本地化的字符串,描述关键字的列标签状态。 + 返回描述服务器所识别 SQL 关键字的一组记录。word列包含关键字。catcode列包含类别代码:U表示非保留关键字,C表示可用作列名的关键字,T表示可用作类型名或函数名的关键字,R表示完全保留的关键字。如果关键字可以在SELECT列表中用作列标签,barelabel列为true;如果只能在AS之后使用,则为falsecatdesc列包含描述关键字类别的字符串,该字符串可能已被本地化。baredesc列包含描述关键字列标签状态的字符串,该字符串可能已被本地化。 @@ -21062,8 +20621,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 重构分区约束的定义。 - (这是反编译得到的重构结果,而不是命令的原始文本。) + 重建分区约束的定义。(这是反编译重建的结果,并非命令的原始文本。) @@ -21076,7 +20634,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 重构针对规则的创建命令。(这是一个反编译的重构,而不是命令的原始文本。) + 重建规则的创建命令。(这是反编译重建的结果,并非命令的原始文本。) @@ -21091,15 +20649,15 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); 返回与列相关联的序列名称,如果没有序列与该列相关联则返回NULL。 如果列是标识列,则关联序列是在内部为该列创建的序列。 - 对于使用一种串行类型(serial, smallserial, bigserial)创建的列,它是为该串行列定义创建的序列。 + 对于使用一种 serial 类型(serial, smallserial, bigserial)创建的列,它是为该 serial 列定义创建的序列。 在后一种情况下,可以使用ALTER SEQUENCE OWNED BY修改或删除关联。 - (这个函数可能应该被称为pg_get_owned_sequence;它的当前名称反映了它在历史上曾与串行类型的列一起使用。) + (这个函数可能应该被称为pg_get_owned_sequence;它的当前名称反映了它在历史上曾与 serial 类型的列一起使用。) 第一个参数是具有可选模式的表名,第二个参数是列名。 由于第一个参数可能包含模式名和表名,因此按照通常的SQL规则解析它,这意味着默认情况下它是小写的。 第二个参数只是一个列名,按照字面来处理,因此保留了它的大小写。结果经过了适当的格式化,可以传递给序列函数(参见)。 - 典型的用法是读取序列的当前值以获取标识或串行列,示例如下: + 典型用法是读取标识列或 serial 列所用序列的当前值,例如: SELECT currval(pg_get_serial_sequence('sometable', 'id')); @@ -21115,7 +20673,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); text - 重构针对扩展统计对象的创建命令。(这是一个反编译的重构,而不是命令的原始文本。) + 重建扩展统计对象的创建命令。(这是反编译重建的结果,并非命令的原始文本。) @@ -21128,7 +20686,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); text - 重构针对触发器的创建命令。(这是一个反编译的重构,而不是命令的原始文本。) + 重建触发器的创建命令。(这是反编译重建的结果,并非命令的原始文本。) @@ -21154,7 +20712,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); text - 重构针对视图或物化视图的SELECT命令。(这是一个反编译的重构,而不是命令的原始文本。) + 重建定义视图或物化视图的SELECT命令。(这是反编译重建的结果,并非命令的原始文本。) @@ -21164,8 +20722,8 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); text - 重构针对视图或物化视图的底层SELECT命令。(这是一个反编译的重构,而不是命令的原始文本。) - 在这种形式的函数中,总是启用美观打印,并对长行进行换行,以尽量使它们小于指定的列数。 + 重建定义视图或物化视图的SELECT命令。(这是反编译重建的结果,并非命令的原始文本。) + 这种形式始终启用美化输出,并将长行折行,尽量使每行长度小于指定列数。 @@ -21175,7 +20733,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); text - 根据视图的文本名称而不是它的OID,重构针对视图或物化视图的底层SELECT命令。(这是弃用;请使用OID变体。) + 根据视图的文本名称而不是其 OID,重建定义视图或物化视图的SELECT命令。(此形式已弃用;请使用 OID 变体。) @@ -21188,7 +20746,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); boolean - 测试一个索引列是否具有命名属性。列出了常用索引列属性。 + 测试一个索引列是否具有指定名称的属性。列出了常用索引列属性。 (注意,扩展访问方法可以为其索引定义额外的属性名。) 如果属性名未知或不适用于特定对象,或者OID或列号不能识别有效的对象,则返回NULL @@ -21203,7 +20761,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); boolean - 测试一个索引是否具有命名属性。列出了常用的索引属性。 + 测试一个索引是否具有指定名称的属性。列出了常用的索引属性。 (注意,扩展访问方法可以为其索引定义额外的属性名。) 如果属性名未知或不适用于特定对象,或者OID不能识别有效的对象,则返回NULL @@ -21218,7 +20776,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); boolean - 测试索引访问方法是否具有命名属性。访问方法属性如所示。 + 测试索引访问方法是否具有指定名称的属性。访问方法属性如所示。 如果属性名未知或不适用于特定对象,或者OID不能识别有效的对象,则返回NULL @@ -21247,9 +20805,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); text[] - 返回与给定GUC相关联的标志数组,如果不存在则返回NULL。 - 如果GUC存在但没有要显示的标志,则结果为空数组。 - 仅公开列出在中最有用的标志。 + 返回与给定 GUC 关联的标志数组;如果该 GUC 不存在,则返回NULL。如果 GUC 存在但没有要显示的标志,则结果为空数组。此函数仅公开中列出的最有用的标志。 @@ -21262,9 +20818,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); setof oid - 返回具有存储在指定表空间中的对象的数据库的OIDs集。 - 如果这个函数返回了任何行,那么表空间就不是空的,且不能被删除。 - 要识别填充表空间的特定对象,需要连接到由pg_tablespace_databases标识的数据库,并查询它们的pg_class目录。 + 返回在指定表空间中存储了对象的数据库 OID 集合。如果此函数返回任何行,则说明该表空间不为空,不能删除。要查看存放在该表空间中的具体对象,需要连接到pg_tablespace_databases标识的数据库,并查询它们的pg_class系统目录。 @@ -21290,12 +20844,10 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); regtype - 返回传递值给它的数据类型的OID。这对于故障排除或动态构造SQL查询很有帮助。 - 函数声明为返回regtype,它是一个OID别名类型(see ); - 这意味着,为了比较,它与OID相同,但显示为类型名。 + 返回所传入值的数据类型的 OID。这有助于排查问题或动态构造 SQL 查询。函数声明的返回类型是regtype,它是一种 OID 别名类型(参见);这意味着它在比较时与 OID 相同,但显示为类型名。 - 例如: + 例如: SELECT pg_typeof(33); pg_typeof @@ -21319,11 +20871,12 @@ SELECT typlen FROM pg_type WHERE oid = pg_typeof(33); text - 返回传递值给它的排序规则的名称。如果需要,该值会被引号括起来,并使用模式限定。 - 如果没有为参数表达式派生排序规则,则返回NULL。如果参数不是可排序数据类型,则会引发错误。 + 返回传入值的排序规则名称。必要时会为返回的名称加上引号和模式限定。 + 如果无法为参数表达式推导出排序规则,则返回NULL。 + 如果参数不属于支持排序规则的数据类型,则报错。 - 例如: + 例如: SELECT collation for (description) FROM pg_description LIMIT 1; pg_collation_for @@ -21348,7 +20901,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); 将文本关系名转换为它的OID。通过将字符串类型转换为regclass可以得到类似的结果(参见); - 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与类型转换不同的是,它不接受数字OID作为输入。 @@ -21361,8 +20914,8 @@ SELECT collation for ('foo' COLLATE "de_DE"); regcollation - 将文本排序规则名称转换为它的OID。通过将字符串类型转换为regcollation(参见)可以得到类似的结果; - 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 将文本排序规则名称转换为它的OID。通过将字符串类型转换为regcollation(参见)可以得到类似的结果; + 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与类型转换不同的是,它不接受数字OID作为输入。 @@ -21375,8 +20928,8 @@ SELECT collation for ('foo' COLLATE "de_DE"); regnamespace - 将文本模式名转换为它的OID。通过将字符串转换为regnamespace类型(参见)可以得到类似的结果; - 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 将文本模式名转换为它的OID。通过将字符串转换为regnamespace类型(参见)可以得到类似的结果; + 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与类型转换不同的是,它不接受数字OID作为输入。 @@ -21389,8 +20942,8 @@ SELECT collation for ('foo' COLLATE "de_DE"); regoper - 将文本操作符名称转换为它的OID。通过将字符串类型转换为regoper(参见)可以得到类似的结果; - 但是,如果找不到名称或名称有多义性,该函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 将文本操作符名称转换为它的OID。通过将字符串类型转换为regoper(参见)可以得到类似的结果; + 但是,如果找不到名称或名称有歧义,该函数将返回NULL而不会抛出错误。与类型转换不同的是,它不接受数字OID作为输入。 @@ -21403,8 +20956,8 @@ SELECT collation for ('foo' COLLATE "de_DE"); regoperator - 将文本操作符名称(带有参数类型)转换为其OID。通过将字符串转换为regoperator类型(参见节)可以得到类似的结果; - 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 将文本操作符名称(带有参数类型)转换为其OID。通过将字符串转换为regoperator类型(参见节)可以得到类似的结果; + 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与类型转换不同的是,它不接受数字OID作为输入。 @@ -21417,8 +20970,8 @@ SELECT collation for ('foo' COLLATE "de_DE"); regproc - 将文本函数或过程名转换为其OID。通过将字符串转换为regproc类型(参见)可以得到类似的结果; - 但是,如果找不到名称或名称有多义性,该函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 将文本函数或过程名转换为其OID。通过将字符串转换为regproc类型(参见)可以得到类似的结果; + 但是,如果找不到名称或名称有歧义,该函数将返回NULL而不会抛出错误。与类型转换不同的是,它不接受数字OID作为输入。 @@ -21432,7 +20985,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); 将文本函数或过程名(带有参数类型)转换为其OID。通过将字符串类型转换为regprocedure可以得到类似的结果(参见); - 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与类型转换不同的是,它不接受数字OID作为输入。 @@ -21446,7 +20999,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); 将文本角色名转换为它的OID。通过将字符串类型转换为regrole可以得到类似的结果(参见); - 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与类型转换不同的是,它不接受数字OID作为输入。 @@ -21459,8 +21012,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); regtype - 将文本类型名转换为它的OID。通过将字符串类型转换为regtype可以得到类似的结果(参见); - 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 将文本形式的类型名转换为其 OID。将字符串转换为 regtype 类型也能得到类似的结果(参见 );不过,如果找不到该名称,此函数会返回 NULL,而不会报错。与类型转换不同的是,此函数不接受数值 OID 作为输入。 @@ -21468,10 +21020,10 @@ SELECT collation for ('foo' COLLATE "de_DE"); - 大多数重构(反编译)数据库对象的函数都有一个可选的 pretty标志,如果为true,结果将被pretty-printed。 - 美观打印会抑制不必要的圆括号,并为易读性增加空格。 - 美观打印的格式可读性更好,但是默认格式更有可能被PostgreSQL的未来版本以同样的方式解释; - 因此,避免为转储目的使用美观打印的输出。为pretty参数传递false会产生与省略参数相同的结果。 + 大多数重建(反编译)数据库对象的函数都有一个可选的pretty标志;若为true,则对结果进行美化输出。 + 美化输出会省略不必要的圆括号,并增加空白以提高可读性。 + 美化后的格式更易读,但默认格式更有可能被PostgreSQL的未来版本以同样的方式解释,因此用于转储时应避免美化输出。 + 为pretty参数传入false与省略该参数的结果相同。 @@ -21516,19 +21068,20 @@ SELECT collation for ('foo' COLLATE "de_DE"); distance_orderable - 列能否通过一个distance操作符(例如ORDER BY col <-> constant)有序地扫描? + + 能否按距离操作符的结果有序地扫描该列,例如ORDER BY col <-> constant returnable - 列值是否可以通过一次只用索引扫描返回? + 列值是否可以通过一次仅索引扫描返回? search_array - 列是否天然支持col = ANY(array)搜索? + 列是否原生支持col = ANY(array)搜索? @@ -21543,7 +21096,7 @@ SELECT collation for ('foo' COLLATE "de_DE");
- 索引性质 + 索引属性 @@ -21580,7 +21133,7 @@ SELECT collation for ('foo' COLLATE "de_DE");
- 索引访问方法性质 + 索引访问方法属性 @@ -21633,12 +21186,12 @@ SELECT collation for ('foo' COLLATE "de_DE"); EXPLAIN - 带有此标志的参数包含在EXPLAIN (SETTINGS)命令中。 + 带有此标志的参数会在EXPLAIN (SETTINGS)命令的输出中显示。 NO_SHOW_ALL - 具有此标志的参数将被排除在SHOW ALL命令之外。 + 带有此标志的参数不会在SHOW ALL命令的输出中显示。 @@ -21662,13 +21215,12 @@ SELECT collation for ('foo' COLLATE "de_DE");
- 列出了与数据库对象 - 标识和定位有关的函数。 + 列出了与数据库对象标识和寻址有关的函数。 - 对象信息和定位函数 + 对象信息和寻址函数 @@ -21693,9 +21245,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); text - 返回由目录OID、对象OID和子对象ID(例如表中的列号)标识的数据库对象的文本描述;当引用整个对象时,子对象ID为0)。 - 这个描述是人类可读的,并且可以根据服务器配置进行翻译。这对于决定pg_depend目录中引用的对象的标识特别有用。 - 此函数对于未定义的对象返回NULL值 + 返回数据库对象的文本描述,对象由系统目录 OID、对象 OID 和子对象 ID 指定(例如表中的列号;引用整个对象时,子对象 ID 为零)。该描述供人阅读,并可能根据服务器配置被翻译。这对于确定pg_depend系统目录中所引用对象的标识尤其有用。对于未定义的对象,此函数返回NULL @@ -21712,13 +21262,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); identitytext ) - 返回包含足够信息的行以唯一标识由目录OID、对象OID和子对象ID指定的数据库对象。 - 这些信息是为了机器可读的,永远不会被翻译。 - type标识数据库对象的类型; - schema是对象所属的模式名,NULL表示不属于模式的对象类型; - name是对象的名称,如果有必要,用引号括起来,如果名称(随着模式名称,如果相关)足以唯一地标识对象,否则为NULL; - identity是完整的对象标识,其精确格式依赖于对象类型,格式中的每个名称都是模式限定的,并在必要时用引号括起来。 - 未定义的对象由NULL值标识。 + 返回一行,其中包含足以唯一标识数据库对象的信息,该对象由系统目录 OID、对象 OID 和子对象 ID 指定。这些信息供机器读取,永远不会被翻译。type标识数据库对象的类型;schema是对象所属的模式名,对于不属于模式的对象类型则为NULL;如果对象名(以及适用时的模式名)足以唯一标识该对象,name就是对象名,并在必要时加引号,否则为NULLidentity是完整的对象标识,其具体格式取决于对象类型,格式中的每个名称都会根据需要加上模式限定和引号。未定义的对象以NULL值标识。 @@ -21734,10 +21278,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); object_argstext[] ) - 返回包含足够信息的行以唯一标识由目录OID、对象OID和子对象ID指定的数据库对象。 - 返回的信息独立于当前服务器,也就是说,它可以用于标识另一个服务器中具有相同名称的对象。 - type标识数据库对象的类型;object_namesobject_args是文本数组,它们一起构成对对象的引用。 - 这三个值可以传递给pg_get_object_address以获得对象的内部地址。 + 返回一行,其中包含足以唯一标识数据库对象的信息,该对象由系统目录 OID、对象 OID 和子对象 ID 指定。返回的信息与当前服务器无关,也就是说,它也能用于标识另一台服务器上名称相同的对象。type标识数据库对象的类型;object_namesobject_args是文本数组,共同构成对该对象的引用。将这三个值传给pg_get_object_address可以获得对象的内部地址。 @@ -21753,12 +21294,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); objsubidinteger ) - 返回包含足够信息的行以唯一标识由类型代码、对象名称和参数数组指定的数据库对象。 - 返回的值将在系统目录中使用,例如pg_depend; - 它们可以传递给其他系统函数,比如 pg_describe_objectpg_identify_object。 - classid是包含该对象的系统目录的OID;objid是对象本身的OID, objsubid是子对象的ID,如果没有则为零。 - 这个函数是pg_identify_object_as_address的反向函数。 - 未定义的对象以NULL值标识。 + 返回一行,其中包含足以唯一标识数据库对象的信息,该对象由类型代码、对象名称数组和参数数组指定。返回的值就是pg_depend等系统目录中使用的值;它们可以传给pg_describe_objectpg_identify_object等其他系统函数。classid是包含该对象的系统目录的 OID;objid是对象自身的 OID;objsubid是子对象 ID,没有子对象时为零。此函数执行pg_identify_object_as_address的逆操作。未定义的对象以NULL值标识。 @@ -21771,7 +21307,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); - 中展示的函数抽取注释,注释是由命令在以前存储的。如果对指定参数找不到注释,则返回空值。 + 中的函数用于提取此前通过命令存储的注释。如果找不到与指定参数对应的注释,则返回空值。
@@ -21801,7 +21337,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); text - 返回表列的注释,该注释由该表的OID和列号指定。(obj_description不能用于表的列,因为列没有自己的oid。) + 返回表列的注释,列由所属表的 OID 和列号指定。(obj_description不能用于表列,因为列没有自身的 OID。) @@ -21814,8 +21350,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); text - 返回OID指定的数据库对象的注释和包含该对象的系统目录的名称。 - 例如,obj_description(123456, 'pg_class')将检索OID为123456的表的注释。 + 返回数据库对象的注释,对象由其 OID 和所在系统目录的名称指定。例如,obj_description(123456, 'pg_class')会获取 OID 为 123456 的表的注释。 @@ -21825,8 +21360,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); text - 返回仅由其OID指定的数据库对象的注释。 - 这个已被弃用(deprecated)因为无法保证oid在不同的系统目录中是唯一的;因此,可能会返回错误的注释。 + 返回仅由其 OID 指定的数据库对象的注释。此形式已弃用,因为无法保证 OID 在不同系统目录之间唯一,因而可能返回错误的注释。 @@ -21839,9 +21373,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); text - 返回共享数据库对象的注释,该对象由其OID和包含的系统编目的名称指定。 - 这与obj_description类似,只是它用于检索共享对象(也就是数据库、角色和表空间)上的注释。 - 有些系统编目对每个集簇中的所有数据库都是全局的,其中对象的描述也全局存储。 + 返回共享数据库对象的注释,对象由其 OID 和所在系统目录的名称指定。此函数与obj_description类似,但用于获取共享对象(即数据库、角色和表空间)的注释。有些系统目录由数据库集簇中的所有数据库全局共享,其中对象的描述也全局存储。 @@ -21871,6 +21403,32 @@ SELECT collation for ('foo' COLLATE "de_DE"); + + + + age + + age ( xid ) + integer + + + 返回给定事务 ID 与当前事务计数器之间的事务数。 + + + + + + + mxid_age + + mxid_age ( xid ) + integer + + + 返回给定多事务 ID 与当前多事务计数器之间的多事务 ID 数。 + + + @@ -21880,7 +21438,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); xid8 - 返回当前事务的ID。如果当前事务还没有一个ID(因为它还没有执行任何数据库更新),它将分配一个新的事务。 + 返回当前事务的ID。如果当前事务还没有一个ID(因为它还没有执行任何数据库更新),它将分配一个新的事务 ID。 @@ -21907,10 +21465,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); text - 报告最近的事务的提交状态。如果事务为最近的,系统会保留事务的提交状态,则结果是 in progresscommittedaborted。 - 如果该事务的时间足够久,并且系统中没有对该事务的引用,而且提交状态信息已经被丢弃,则结果为NULL。 - 应用可以使用此函数,例如,确定在进行COMMIT时,应用程序和数据库服务器断开连接后,它们的事务是已提交还是中止。 - 注意,准备好的事务报告为in progress的事务;如果应用需要确定一个事务ID是否属于一个准备好的事务,则必须检查pg_prepared_xacts。 + 报告近期事务的提交状态。只要事务足够新,系统仍保留其提交状态,结果就为in progresscommittedaborted。如果事务已足够旧,系统中不再有对它的引用,且提交状态信息已被丢弃,则返回NULL。例如,在COMMIT进行过程中应用与数据库服务器断开连接时,应用可以用此函数判断事务是提交了还是中止了。注意,预备事务被报告为in progress;如果需要确定某个事务 ID 是否为预备事务,应用必须检查pg_prepared_xacts @@ -21923,7 +21478,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); pg_snapshot - 返回当前snapshot,显示哪些事务 ID正在进行中的数据结构。 + 返回当前快照,即显示哪些事务 ID 正在进行中的数据结构。 @@ -21975,8 +21530,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); boolean - 根据此快照,给定的事务ID是否可见(visible)(也就是说,它是否在快照拍摄之前完成)? - 注意,这个函数不会给出子事务ID的正确答案。 + 根据此快照,给定的事务 ID 是否可见(即该事务是否在生成快照之前完成)?注意,此函数无法为子事务 ID 给出正确结果。 @@ -22000,7 +21554,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); 内部事务 ID 类型xid是 32 位宽,每 40 亿个事务就会回卷一次(wrap around)。 - 但是,中所示的函数使用的是 64 位类型xid8,它在一次安装的生命周期内不会回卷,必要时可以通过强制转换将其转换为xid。 + 但是,中所示的函数除 agemxid_agepg_get_multixact_members 外,使用的是 64 位类型xid8,它在一次安装的生命周期内不会回卷,必要时可以通过类型转换将其转换为xid。 数据类型pg_snapshot存储特定时刻事务ID可见性的信息。 其组成如所描述。pg_snapshot的文本表示形式是xmin:xmax:xip_list。 例如10:20:10,14,15表示xmin=10, xmax=20, xip_list=10, 14, 15。 @@ -22023,21 +21577,22 @@ SELECT collation for ('foo' COLLATE "de_DE"); xmin - 仍然处于活动状态的最低事务ID。所有小于xmin的事务 ID要么提交且可见,要么回滚并死亡。 + 仍然处于活动状态的最小事务 ID。所有小于xmin的事务 ID 要么已经提交且可见,要么已经回滚而失效。 xmax - 比最高完成的事务ID还高出一个值。所有大于或等于xmax的事务 ID到快照时还没有完成,因此不可见。 + 已完成事务中的最大事务 ID 加一。所有大于或等于xmax的事务 ID 在生成快照时尚未完成,因此不可见。 xip_list - 快照时正在进行的事务。一个事务ID为xmin <= X < xmax且不在快照时已经完成的列表中,因此根据其提交状态,该事务ID要么是可见的,要么是死的。此列表不包括子事务的事务 ID。 + 生成快照时正在进行的事务。满足xmin <= X < + xmax且不在此列表中的事务 ID 在生成快照时已经完成,因此根据其提交状态,要么可见,要么失效。此列表不包含子事务的事务 ID。 @@ -22222,7 +21777,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); roidentoid) - 返回事务的提交时间戳和复制起源。 + 返回事务的提交时间戳和复制源。 @@ -22238,7 +21793,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); roidentoid ) - 返回最近提交的事务的事务ID、提交时间戳和复制源头。 + 返回最近提交事务的事务 ID、提交时间戳和复制源。 @@ -22246,9 +21801,7 @@ SELECT collation for ('foo' COLLATE "de_DE");
- 中所展示的函数能打印initdb期间初始化的信息,例如目录版本。 - 它们也能显示有关预写式日志和检查点处理的信息。这些信息是集簇范围内的,不与任何特定的一个数据库相关。 - 这些函数提供大致相同的信息,对于同一种来源,就像应用。 + 中的函数显示在initdb期间初始化的信息,例如系统目录版本。它们也显示有关预写式日志和检查点处理的信息。这些信息适用于整个数据库集簇,而非某个特定数据库。这些函数与应用程序从相同来源提供大部分相同的信息。 @@ -22278,7 +21831,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); record - 返回有关当前检查点状态的信息, 如 所展示。 + 返回有关当前检查点状态的信息, 如 所展示。 @@ -22317,7 +21870,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); record - 返回有关恢复状态的信息,如 所展示。 + 返回有关恢复状态的信息,如 所展示。 @@ -22609,9 +22162,9 @@ SELECT collation for ('foo' COLLATE "de_DE"); - configuration - of the server - functions + 配置 + 服务器 + 函数 @@ -22648,7 +22201,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); text - 返回设置的setting_name的当前值。 + 返回设置setting_name的当前值。 如果没有这样的设置,current_setting将抛出一个错误,除非missing_ok被提供并且为true(在此情况下返回NULL)。 这个函数对应于SQL命令 @@ -22670,9 +22223,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); text - 将参数setting_name设置为new_value,并返回该值。 - 如果is_localtrue,新值将仅在当前事务期间应用。 - 如果您希望新值应用于当前会话的其余部分,请使用false代替。这个函数对应于SQL命令。 + 将参数setting_name设置为new_value,并返回该值。如果is_localtrue,新值仅在当前事务期间生效。如果希望新值在当前会话的剩余时间内生效,则使用false。此函数对应 SQL 命令 set_config('log_statement_stats', 'off', false) @@ -22695,7 +22246,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); - 在中展示的函数向其它服务器进程发送控制信号。默认情况下这些函数只能被超级用户使用,但是如果需要,可以利用GRANT把访问权限授予给其他用户。 + 在中展示的函数向其它服务器进程发送控制信号。默认情况下这些函数只能被超级用户使用,但是如果需要,可以利用GRANT把访问权限授予给其他用户(注明的例外除外)。 @@ -22743,11 +22294,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); boolean - 请求记录具有指定进程ID的后端的内存上下文。此函数可以将请求发送到后端和辅助进程,但不包括记录器。这些内存上下文将以 - LOG消息级别记录。它们将根据设置的日志配置出现在服务器日志中 - (有关更多信息,请参见), - 但无论如何都不会发送给客户端 - ()。 + 请求记录具有指定进程 ID 的后端进程的内存上下文。此函数可以向除日志记录进程以外的后端进程和辅助进程发送请求。这些内存上下文将以LOG消息级别记录,并根据日志配置出现在服务器日志中(详见);无论如何设置,都不会发送给客户端。 @@ -22796,7 +22343,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); 终止具有指定进程ID的后端进程的会话。如果调用角色是正在终止的后端的角色的成员,或者调用角色具有pg_signal_backend的权限,则也允许执行此操作,但只有超级用户才能终止超级用户后端。 - 如果未指定或超时timeout为零,则此函数无论进程是否实际终止,都将返回true,仅表示信号发送成功。如果指定了timeout(以毫秒为单位)且大于零,则函数将等待直到进程实际终止或直到给定时间已过。如果进程被终止,函数将返回true。在超时时,会发出警告并返回false。 + 如果未指定timeout或其值为零,则此函数无论进程是否实际终止,都将返回true,仅表示信号发送成功。如果指定了timeout(以毫秒为单位)且大于零,则函数将等待直到进程实际终止或直到给定时间已过。如果进程被终止,函数将返回true。在超时时,会发出警告并返回false @@ -22845,7 +22392,7 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 备份控制函数 - backup + 备份 @@ -22885,13 +22432,9 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 pg_lsn - 在预写式日志中创建一个命名标记记录,稍后可以将其用作恢复目标,并返回相应的预写日志位置。 - 然后可以将给定的名称与 一起使用,以指定进行恢复的点。 - 要避免创建多个名称相同的恢复点,因为恢复将在第一个名称与恢复目标匹配的恢复点停止。 + 在预写式日志中创建一条命名标记记录,供以后用作恢复目标,并返回相应的预写式日志位置。随后可以在中使用给定名称,指定恢复到哪一点。应避免创建多个同名恢复点,因为恢复会在第一个名称匹配恢复目标的恢复点停止。 - - 默认情况下,该函数仅限超级用户使用,但可以授权给其他用户执行该函数。 - + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -22903,7 +22446,7 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 pg_lsn - 返回当前预写式日志刷新位置(参见下面的说明)。 + 返回当前预写式日志刷盘位置(参见下文说明)。 @@ -22916,7 +22459,7 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 pg_lsn - 返回当前预式日志插入位置(参见下面的说明)。 + 返回当前预写式日志插入位置(参见下文说明)。 @@ -22929,7 +22472,7 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 pg_lsn - 返回当前预写式日志写位置(参见下面的说明)。 + 返回当前预写式日志写入位置(参见下文说明)。 @@ -22945,15 +22488,9 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 pg_lsn - 准备服务器开始在线备份。唯一必需的参数是备份的任意用户定义标签。 - (通常这将是备份转储文件存储的名称。) - 如果将可选的第二个参数指定为true, - 它将尽快执行pg_backup_start。这将强制立即进行检查点, - 这将导致I/O操作的激增,从而减慢任何同时执行的查询。 + 准备服务器开始在线备份。唯一必需的参数是用户任意指定的备份标签。(通常是备份转储文件将要保存的名称。)如果可选的第二个参数为true,则尽快执行pg_backup_start。这会强制立即执行检查点,使 I/O 操作量陡增,并降低并发执行的查询的速度。 - - 默认情况下,此函数仅限于超级用户,但可以授予其他用户执行权限以运行该函数。 - + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -22970,31 +22507,18 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 spcmapfile text ) - 完成在线备份。函数的结果中返回备份标签文件和表空间映射文件的期望内容,并必须写入备份区域的文件中。 - 这些文件不得写入实时数据目录(这样做将导致PostgreSQL在崩溃时无法重新启动)。 + 结束在线备份。备份标签文件和表空间映射文件所需的内容作为函数结果的一部分返回,必须将其写入备份区域中的文件。切勿将这些文件写入正在使用的数据目录(否则发生崩溃后 PostgreSQL 将无法重新启动)。 - 有一个类型为boolean的可选参数。 - 如果为false,则在备份完成后立即返回,而无需等待WAL进行归档。 - 此行为仅适用于独立监视WAL归档的备份软件。否则,可能会缺少使备份一致所需的WAL,使备份无效。 - 默认情况下或当此参数为true时,pg_backup_stop将在启用归档时等待WAL进行归档。 - (在备库上,这意味着仅当archive_mode = always时才会等待。 - 如果主库上的写入活动较低,则可能有必要在主库上运行pg_switch_wal以触发立即段切换。) + 有一个boolean类型的可选参数。如果为 false,该函数会在备份完成后立即返回,不等待 WAL 归档。这种行为只适用于自行监控 WAL 归档的备份软件;否则,可能缺少使备份保持一致所需的 WAL,导致备份无法使用。默认情况下或该参数为 true 时,若已启用归档,pg_backup_stop会等待 WAL 归档。(在备库上,这意味着只有archive_mode = always时才会等待。如果主库的写入活动很少,可以在主库上运行pg_switch_wal,触发立即切换日志段。) - 在主库上执行时,此函数还会在预写式日志归档区域中创建一个备份历史文件。 - 历史文件包括给定给pg_backup_start的标签、备份的起始和结束预写式日志位置,以及备份的起始和结束时间。 - 在记录结束位置后,当前的预写式日志插入点会自动前进到下一个预写式日志文件,以便立即归档结束的预写式日志文件以完成备份。 + 在主库上执行时,该函数还会在预写式日志归档区域创建备份历史文件。历史文件包括传给pg_backup_start的标签、备份的起止预写式日志位置以及备份的起止时间。记录结束位置后,当前预写式日志插入点会自动推进到下一个预写式日志文件,使包含结束位置的预写式日志文件可以立即归档,从而完成备份。 - 函数的结果是一个记录。 - lsn列保存备份的结束预写式日志位置(可以忽略)。 - 第二列返回备份标签文件的内容,第三列返回表空间映射文件的内容。 - 这些必须作为备份的一部分存储,并作为恢复过程的一部分。 + 该函数的结果是一条记录。lsn列保存备份结束时的预写式日志位置(同样可以忽略)。第二列返回备份标签文件的内容,第三列返回表空间映射文件的内容。这些内容必须作为备份的一部分保存,恢复时需要用到它们。 - - 默认情况下,此函数仅限于超级用户,但可以授予其他用户EXECUTE权限来运行该函数。 - + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -23006,13 +22530,9 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 pg_lsn - 强制服务器切换到一个新的预写式日志文件,这允许对当前文件进行归档(假设你正在使用连续归档)。 - 其结果是在刚刚完成的预写式日志文件中结束预写式日志位置加1。 - 如果自从上次预写式日志切换以来没有提前写日志活动,pg_switch_wal将不做任何操作,并返回当前正在使用的提前写日志文件的起始位置。 + 强制服务器切换到新的预写式日志文件,使当前文件可以归档(假设正在使用连续归档)。返回值是刚完成的预写式日志文件中的结束预写式日志位置加 1。如果自上次切换预写式日志以来没有发生任何预写式日志活动,pg_switch_wal不执行任何操作,并返回当前使用的预写式日志文件的起始位置。 - - 默认情况下该函数仅限超级用户使用,但可以授权其他用户执行该函数。 - + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -23024,7 +22544,7 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 text - 将预写式日志位置转换为保持该位置的WAL文件的名称。 + 将预写式日志位置转换为包含该位置的 WAL 文件的名称。 @@ -23052,35 +22572,22 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 numeric - 计算两个预写式日志位置之间的字节(lsn1 - lsn2)差异。 - 这可以与pg_stat_replication中所示的一些函数一起使用,以获得复制延迟。 + 计算两个预写式日志位置之间的字节差(lsn1 - lsn2)。可以将它与pg_stat_replication中的某些函数配合使用,以获取复制延迟。
- - pg_current_wal_lsn 显示当前预写式日志写位置,与上述函数所用的格式相同。 - 类似地,pg_current_wal_insert_lsn显示当前预写式日志插入位置,pg_current_wal_flush_lsn显示当前预写式日志刷新位置。 - 插入位置是预写式日志在任何时刻的逻辑(logical) 结束,而写位置是已经从服务器内部缓冲区实际写入的内容的结束,而刷新位置是已知的要写入持久化存储的最后一个位置。 - 写位置是可以从服务器外部检查的最后位置,如果你对归档部分完成的预写式日志文件感兴趣,那么它通常就是你想要的位置。 - 插入和刷新位置主要用于服务器调试目的。这些都是只读操作,不需要超级用户权限。 - + pg_current_wal_lsn 显示当前预写式日志写入位置,格式与上述函数相同。类似地,pg_current_wal_insert_lsn 显示当前预写式日志插入位置,pg_current_wal_flush_lsn 显示当前预写式日志刷盘位置。插入位置是预写式日志在任意时刻的逻辑末尾;写入位置是实际从服务器内部缓冲区写出的内容的末尾;刷盘位置则是已知已经写入持久存储的最后位置。写入位置是能从服务器外部检查到的内容的末尾,如果要归档尚未写满的预写式日志文件,通常需要这个位置。插入位置和刷盘位置主要用于服务器调试。这些都是只读操作,不需要超级用户权限。 - - 您可以使用pg_walfile_name_offsetpg_lsn值中提取相应的预写式日志文件名和字节偏移量。例如: - + 可以使用pg_walfile_name_offset从一个pg_lsn值中提取相应的预写式日志文件名和字节偏移量。例如: postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); file_name | file_offset --------------------------+------------- 00000001000000000000000D | 4039624 (1 row) - - 类似地,pg_walfile_name仅提取预写式日志文件名。 - 当给定的预写式日志位置恰好位于预写式日志文件边界时,这两个函数都会返回前一个预写式日志文件的名称。 - 这通常是管理预写式日志归档行为的期望行为,因为前一个文件是当前需要归档的最后一个文件。 - +类似地,pg_walfile_name仅提取预写式日志文件名。当指定的预写式日志位置恰好位于预写式日志文件边界时,这两个函数都返回前一个预写式日志文件的名称。这通常正是管理预写式日志归档时所需的行为,因为前一个文件是当前需要归档的最后一个文件。
@@ -23133,9 +22640,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); pg_lsn - 返回已接收并通过流复制同步到磁盘的最后一个预写式日志位置。 - 当流复制正在进行时这将单调地增加。如果恢复已经完成,那么在恢复期间,接收到的最后一条WAL记录的位置将保持静态,并同步到磁盘。 - 如果流复制已禁用,或者尚未启动,函数将返回NULL。 + 返回流复制最近接收并同步到磁盘的预写式日志位置。在流复制进行期间,该值单调增加。如果恢复已完成,该值将保持为恢复期间最后接收并同步到磁盘的 WAL 记录的位置。如果禁用了流复制,或者流复制尚未开始,此函数返回 NULL @@ -23148,8 +22653,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); pg_lsn - 返回恢复期间重新播放的最后一个预写式日志位置。如果恢复仍在进行中这将会单调地增加。 - 如果恢复已经完成,那么恢复期间应用的最后WAL记录的位置将保持静态。当服务器正常启动且没有恢复时,函数返回NULL。 + 返回恢复期间最近重放的预写式日志位置。如果恢复仍在进行,该值单调增加。如果恢复已完成,该值将保持为该次恢复期间最后应用的 WAL 记录的位置。如果服务器未经恢复而正常启动,此函数返回 NULL @@ -23162,10 +22666,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); timestamp with time zone - 返回恢复期间重放的最后一个事务的时间戳。这是在主库上为该事务生成提交或中止 WAL记录的时间。 - 如果在恢复期间没有重放任何事务,该函数将返回NULL。否则,如果恢复仍在进行中,这将单调地增加。 - 如果恢复已经完成,那么在恢复期间应用最后一个事务时,这将会保持静态。 - 当服务器正常启动且没有恢复时,函数返回NULL。 + 返回恢复期间最近重放事务的时间戳,即该事务的提交或中止 WAL 记录在主库上生成的时间。如果恢复期间尚未重放任何事务,此函数返回 NULL。否则,如果恢复仍在进行,该值单调增加。如果恢复已完成,该值将保持为该次恢复期间最后应用的事务的时间戳。如果服务器未经恢复而正常启动,此函数返回 NULL @@ -23189,7 +22690,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); - 控制恢复进度的功能如 所示。这些函数只能在恢复过程中执行。 + 列出的函数用于控制恢复进度。这些函数只能在恢复期间执行。 @@ -23219,7 +22720,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); boolean - 如果请求了恢复暂停了则返回真。 + 如果已请求暂停恢复,则返回真。 @@ -23233,7 +22734,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); 返回恢复暂停状态。 - 如果没有请求pause,返回值是not paused,如果请求暂停但恢复还没有暂停,返回值是pause requested,如果恢复实际已经暂停,返回值是paused。 + 如果没有请求暂停,返回值是not paused,如果请求暂停但恢复还没有暂停,返回值是pause requested,如果恢复实际已经暂停,返回值是paused @@ -23247,11 +22748,11 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); 将备库提升为主库状态。 - 当wait设置为true(默认值)时,函数将等待直到升级完成或wait_seconds秒数已过,如果升级成功则返回true,否则返回false。 - 如果wait设置为false,则该函数在向postmaster发送SIGUSR1信号以触发升级后立即返回true。 + 当wait设置为true(默认值)时,函数将等待直到提升完成或wait_seconds秒数已过,如果提升成功则返回true,否则返回false。 + 如果wait设置为false,则该函数在向postmaster发送SIGUSR1信号以触发提升后立即返回true - 默认情况下这个函数仅限超级用户使用,但可以授权给其他用户执行该函数。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -23272,7 +22773,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); 如果热备是激活的,所有新查询将看到相同的一致的数据库快照,并且在恢复继续之前不会生成进一步的查询冲突。 - 默认情况下该函数仅限超级用户使用,但可以授权其他用户执行该函数。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -23288,7 +22789,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); 如果暂停了,则重新启动恢复。 - 默认情况下该函数仅限超级用户使用,但可以授权其他用户执行该函数。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -23296,8 +22797,8 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn);
- pg_wal_replay_pausepg_wal_replay_resume不能在提升(promotion)进行时执行。 - 如果在恢复暂停时触发了提升(promotion),则暂停状态结束,升级继续进行。 + pg_wal_replay_pausepg_wal_replay_resume不能在提升进行时执行。 + 如果在恢复暂停时触发了提升,则暂停状态结束,提升继续进行。 @@ -23316,7 +22817,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); - 为了解决这个问题,PostgreSQL允许一个事务导出它正在使用的快照。只要导出的事务仍然保持打开,其他事务可以导入它的快照,并且因此可以保证它们可以看到和第一个事务看到的完全一样的数据库视图。但是注意这些事务中的任何一个对数据库所作的更改对其他事务仍然保持不可见,和未提交事务所作的修改一样。因此这些事务是针对以前存在的数据同步,而对由它们自己所作的更改则采取正常的动作。 + 为了解决这个问题,PostgreSQL允许一个事务导出它正在使用的快照。只要导出快照的事务仍然保持打开,其他事务可以导入它的快照,并且因此可以保证它们可以看到和第一个事务看到的完全一样的数据库视图。但是注意这些事务中的任何一个对数据库所作的更改对其他事务仍然保持不可见,和未提交事务所作的修改一样。因此这些事务是针对以前存在的数据同步,而对由它们自己所作的更改则采取正常的动作。 @@ -23356,7 +22857,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); 如果需要的话,一个事务可以导出多个快照。 请注意,这样做仅在READ COMMITTED事务中有用,因为在REPEATABLE READ和更高的隔离级别中,事务在它们的生命周期中使用相同的快照。 - 一旦事务导出了快照,它就不能用 进行准备。 + 一旦事务导出了快照,它就不能用 进行预备。 @@ -23372,7 +22873,6 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); 中展示的函数用于控制以及与复制特性交互。 有关底层特性的信息请见以及。 - 复制原点函数的使用仅限于超级用户。 默认只允许超级用户使用复制源的函数,但可以通过GRANT命令允许其他用户使用。 复制槽的函数只限于超级用户和拥有REPLICATION权限的用户。 @@ -23418,12 +22918,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); lsn pg_lsn ) - 创建一个新的名为slot_name的物理复制槽。 - 第二个参数是可选的,当它为true时,立即为这个物理槽指定要被保留的LSN。 - 否则该LSN会被保留在来自一个流复制客户端的第一个连接上。 - 来自一个物理槽的更改只能通过流复制协议进行流式传输 — 见。 - 当可选的第三参数temporary被设置为真时,指定那个槽不会被持久地存储在磁盘上并且仅对当前会话的使用有意义。 - 临时槽也会在发生任何错误时被释放。这个函数对应于复制协议命令CREATE_REPLICATION_SLOT ... PHYSICAL。 + 创建名为 slot_name 的新物理复制槽。可选的第二个参数为 true 时,指定立即为此复制槽保留 LSN;否则在流复制客户端首次连接时保留 LSN。从物理槽流式传输更改只能使用流复制协议 — 参见。可选的第三个参数 temporary 为真时,指定该槽不永久存储到磁盘,且仅供当前会话使用。发生任何错误时,临时槽也会被释放。此函数对应复制协议命令 CREATE_REPLICATION_SLOT ... PHYSICAL @@ -23436,9 +22931,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); void - 丢弃名为slot_name的物理或逻辑复制槽。 - 和复制协议命令DROP_REPLICATION_SLOT相同。对于逻辑槽, - 在连接到在其中创建该槽的同一个数据库时,必须调用这个函数。 + 删除名为slot_name的物理或逻辑复制槽。与复制协议命令DROP_REPLICATION_SLOT相同。 @@ -23447,13 +22940,13 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); pg_create_logical_replication_slot - pg_create_logical_replication_slot ( slot_name name, plugin name , temporary boolean, twophase boolean, failover boolean ) + pg_create_logical_replication_slot ( slot_name name, plugin name , temporary boolean, twophase boolean ) record ( slot_name name, lsn pg_lsn ) - 创建一个名为slot_name的新逻辑(解码)复制插槽,使用输出插件plugin。可选的第三个参数temporary,当设置为true时,指定插槽不应永久存储到磁盘,仅供当前会话使用。临时插槽也会在任何错误发生时释放。可选的第四个参数twophase,当设置为true时,指定为此插槽启用已准备事务的解码。可选的第五个参数failover,当设置为true时,指定启用此插槽同步到备库,以便在故障切换后可以恢复逻辑复制。调用此函数的效果与复制协议命令CREATE_REPLICATION_SLOT ... LOGICAL相同。 + 创建一个名为slot_name的新逻辑(解码)复制槽,使用输出插件plugin。可选的第三个参数temporary,当设置为真时,指定槽不应永久存储到磁盘,仅供当前会话使用。临时槽也会在任何错误发生时释放。可选的第四个参数twophase,当设置为真时,指定为此槽启用预备事务的解码。调用此函数的效果与复制协议命令CREATE_REPLICATION_SLOT ... LOGICAL相同。 @@ -23469,7 +22962,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); 将一个名为src_slot_name的现有物理复制槽复制到一个名为dst_slot_name的物理复制槽。 - 被复制的物理槽开始从与源槽相同的LSN开始保留WAL。temporary是可选的。 + 复制后的物理槽从与源槽相同的LSN开始保留WAL。temporary是可选的。 如果省略了temporary,则使用与源槽相同的值。 @@ -23485,7 +22978,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); lsn pg_lsn ) - 复制一个名为src_slot_name的现有逻辑复制槽到一个名为dst_slot_name的逻辑复制槽,选择性的改变输出插件和持久性。 + 复制一个名为src_slot_name的现有逻辑复制槽到一个名为dst_slot_name的逻辑复制槽,可选地更改输出插件和持久性。 被复制的逻辑槽从与源逻辑槽相同的LSN开始。temporaryplugin都是可选的。 如果它们被省略了,使用与源逻辑槽相同的值。 @@ -23503,11 +22996,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); data text ) - 返回槽slot_name中的改变,从最后一次使用更改的点开始。 - 如果upto_lsnupto_nchanges为 NULL,逻辑解码将一直继续到 WAL 的末尾。 - 如果upto_lsn为非 NULL,解码将只包括那些在指定 LSN 之前提交的事务。 - 如果upto_nchanges为非 NULL,解码将在其产生的行数超过指定值后停止。 - 不过要注意,被返回的实际行数可能更大,因为对这个限制的检查只会在增加了解码每个新的提交事务产生的行之后进行。 + 返回槽 slot_name 中自上次消费更改的位置起的更改。如果 upto_lsnupto_nchanges 都为 NULL,逻辑解码会持续到 WAL 末尾。如果 upto_lsn 非 NULL,解码仅包含在指定 LSN 之前提交的事务。如果 upto_nchanges 非 NULL,解码产生的行数超过指定值时就会停止。不过,实际返回行数可能更大,因为只有在添加完对每个新事务提交进行解码所产生的行后,才会检查此限制。 @@ -23572,9 +23061,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); end_lsn pg_lsn ) - 将复制槽的当前确认的位置提前到名为slot_name的复制槽的当前确认位置。 - 该槽不会向后移动,也不会移动到当前插入位置之外。返回该槽的名称和它被推进到的真实位置。 - 如果有任何进展,则在下一个检查点中写出更新后的槽位置信息。所以如果发生崩溃,该槽位可能会返回到之前的位置。 + 推进名为 slot_name 的复制槽当前已确认的位置。该槽不会后退,也不会越过当前插入位置。返回槽名及其实际推进到的位置。如果发生了推进,更新后的槽位置信息会在下一个检查点写出。因此,发生崩溃时,槽可能回到更早的位置。 @@ -23626,8 +23113,8 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); void - 将当前会话标记为从给定的原点回放,从而允许跟踪回放进度。 - 只能在当前没有选择原点时使用。使用pg_replication_origin_session_reset 命令来撤销。 + 将当前会话标记为从给定的复制源重放,从而允许跟踪重放进度。 + 只能在当前没有选择复制源时使用。使用pg_replication_origin_session_reset来撤销。 @@ -23666,7 +23153,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); pg_lsn - 返回当前会话中选择的复制源的重放位置。参数flush决定对应的本地事务是否被确保已经刷入磁盘。 + 返回当前会话中选择的复制源的重放位置。参数flush决定是否保证对应的本地事务已刷盘。 @@ -23720,7 +23207,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); pg_lsn - 返回给定复制元的重放位置。参数flush决定对应的本地事务是否被确保已经刷入磁盘。 + 返回给定复制源的重放位置。参数flush决定是否保证对应的本地事务已刷盘。 @@ -23737,37 +23224,10 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); pg_lsn - 发出逻辑解码消息。这可以用于通过WAL将通用消息传递给逻辑解码插件。 - transactional参数指定消息是否应该是当前事务的一部分, - 还是应该立即写入并在逻辑解码器读取记录时立即解码。 - prefix参数是一个文本前缀,逻辑解码插件可以使用它轻松识别对它们有趣的消息。 - content参数是消息的内容,可以以文本或二进制形式给出。 + 发出逻辑解码消息。这可用于通过 WAL 向逻辑解码插件传递通用消息。transactional 参数指定消息是作为当前事务的一部分,还是立即写入并在逻辑解码器读到该记录时立即解码。prefix 参数是一个文本前缀,便于逻辑解码插件识别其关注的消息。content 参数是消息内容,可以文本或二进制形式给出。 - - - - pg_sync_replication_slots - - pg_sync_replication_slots () - void - - - 将逻辑故障切换复制槽从主库同步到备库。此函数只能在备库上执行。 - 临时同步的槽(如果有)不能用于逻辑解码,必须在提升后删除。 - 详见。 - 请注意,此函数主要用于测试和调试目的,应谨慎使用。 - 此外,如果sync_replication_slots已启用且 slotsync 工作进程已在运行以执行槽同步,则无法执行此函数。 - - - - - 如果在执行该函数后,备库上禁用了hot_standby_feedback,或者在primary_slot_name中配置的物理槽被移除,那么同步槽所需的行可能会被主库上的VACUUM进程移除,导致同步的槽变为无效。 - - - - @@ -23870,13 +23330,13 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); bigint - 计算指定关系的一个fork所使用的磁盘空间。 - (注意在大多数情况下,使用更高级的函数 pg_total_relation_sizepg_table_size更方便,它们将所有分叉(forks)的大小相加。) - 使用一个参数,这将返回关系的主数据分叉的大小。第二个参数可以用来指定要检查哪个分叉: + 计算指定关系的一个分支所使用的磁盘空间。 + (注意在大多数情况下,使用更高级的函数 pg_total_relation_sizepg_table_size更方便,它们将所有分支的大小相加。) + 使用一个参数,这将返回关系的主数据分支的大小。第二个参数可以用来指定要检查哪个分支: - main返回关系的主数据分叉的大小。 + main返回关系的主数据分支的大小。 @@ -23891,7 +23351,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); - init 返回初始化分叉的大小,如果有的话,与关系相关。 + init 返回与该关系关联的初始化分支(如有)的大小。 @@ -23907,7 +23367,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); bigint - 将人可阅读的格式的大小(由pg_size_pretty返回)转换为字节。 + 将人类可读格式的大小(由pg_size_pretty返回)转换为字节。 @@ -23938,7 +23398,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); bigint - 计算指定表所使用的磁盘空间,不包括索引(但包括它的TOAST表,如果有的话,空闲空间映射,以及可见性映射)。 + 计算指定表所使用的磁盘空间,不包括索引(但包括其 TOAST 表(如有)、空闲空间映射和可见性映射)。 @@ -23972,7 +23432,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); 计算指定表所使用的总磁盘空间,包括所有索引和TOAST数据。 - 结果等价pg_table_size + pg_indexes_size。 + 结果等价于pg_table_size + pg_indexes_size @@ -23980,11 +23440,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); - 上述操作表和索引的函数接受一个regclass参数,它是该表或索引在pg_class系统目录中的 OID。 - 你不必手工去查找该 OID,因为regclass数据类型的输入转换器会为你代劳。 - 只写包围在单引号内的表名,这样它看起来像一个文字常量。 - 为了与普通SQL名称的处理相兼容,该字符串将被转换为小写形式,除非其中在表名周围包含双引号。 - 详见。 + 上述操作表和索引的函数接受一个regclass参数,即该表或索引在pg_class系统目录中的 OID。不必手工查找该 OID,因为regclass数据类型的输入转换器会代为查找。详见 @@ -24018,7 +23474,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); oid - 返回当前分配给指定关系的filenode数字。文件节点是用于该关系的文件名称的基本组件(更多信息请参阅 )。 + 返回当前分配给指定关系的文件结点编号。文件结点是用于该关系的文件名称的基本组件(更多信息请参阅 )。 对于大多数关系,其结果与pg_class.relfilenode相同,但对于某些系统目录,relfilenode为0,并且必须使用这个函数来获得正确的值。 如果传递的是一个没有存储的关系,例如一个视图,那么函数将返回NULL。 @@ -24033,7 +23489,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); text - 返回关系的完整文件路径名称(相对于数据库集簇的数据目录,即关系的PGDATA)。 + 返回关系的完整文件路径名称(相对于数据库集簇的数据目录,即PGDATA)。 @@ -24046,8 +23502,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); regclass - 返回一个给定表空间OID和存储它的文件节点的关系的OID。这本质上是pg_relation_filepath的反向映射。 - 对于数据库默认表空间中的关系,表空间可以指定为0。如果当前数据库中没有与给定值相关联的关系,则返回 NULL。 + 根据关系所在表空间的 OID 和文件结点返回该关系的 OID。这本质上是pg_relation_filepath的反向映射。对于数据库默认表空间中的关系,表空间可以指定为 0。如果当前数据库中没有与给定值关联的关系,或者该关系是临时关系,则返回NULL @@ -24114,181 +23569,20 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); integer - 基于在操作系统中找到的所有区域环境(locales),加入排序规则到系统目录pg_collation中。 - 这是 initdb 会用到的,更多细节请参考。 - 如果后来在操作系统上安装了额外的区域环境,可以再次运行这个函数加入新区域环境的排序规则。 - 匹配pg_collation中现有条目的区域环境将被跳过(但是这个函数不会移除以在操作系统中不再存在的区域环境为基础的排序规则对象)。 - schema参数通常是pg_catalog,但这并非强制要求,排序规则也可以安装到其他模式中。 - 该函数返回其创建的新排序规则对象的数量。 - 此函数仅限超级用户使用。 + 根据操作系统中找到的所有区域设置,向系统目录pg_collation添加排序规则。 + initdb使用的就是此函数;更多信息见。 + 如果以后在操作系统中安装了其他区域设置,可以再次运行此函数,为新区域设置添加排序规则。 + 与pg_collation中现有条目匹配的区域设置会被跳过。 + (但此函数不会删除基于操作系统中已不存在的区域设置的排序规则对象。) + schema参数通常为pg_catalog,但并非必须如此;也可以将排序规则安装到其他模式中。 + 函数返回新建的排序规则对象数量。此函数仅限超级用户使用。 - - 列出用于操纵统计信息的函数。 - 这些函数不能在恢复期间执行。 - - - 由这些统计信息操纵函数所做的更改可能会被autovacuum(或手动 - VACUUMANALYZE)覆盖,应视为临时性的。 - - - - - - 数据库对象统计信息操纵函数 - - - - - 函数 - - - 描述 - - - - - - - - - pg_restore_relation_stats - - pg_restore_relation_stats ( - VARIADIC kwargs "any" ) - boolean - - - 更新表级统计信息。通常这些统计信息由自动收集或作为的一部分更新,因此不必调用此函数。但它在恢复后很有用,可以在尚未运行ANALYZE时帮助优化器选择更好的计划。 - - - 被跟踪的统计信息可能因版本而异,所以参数以argnameargvalue对的形式传递: - -SELECT pg_restore_relation_stats( - 'arg1name', 'arg1value'::arg1type, - 'arg2name', 'arg2value'::arg2type, - 'arg3name', 'arg3value'::arg3type); - - - - 例如,要设置表mytablerelpagesreltuples值: - -SELECT pg_restore_relation_stats( - 'schemaname', 'myschema', - 'relname', 'mytable', - 'relpages', 173::integer, - 'reltuples', 10000::real); - - - - 参数schemanamerelname是必需的,用于指定表。其他参数是与pg_class中某些列对应的统计信息的名称和值。当前支持的关系统计信息包括:integer类型的relpagesreal类型的reltuplesinteger类型的relallvisible以及integer类型的relallfrozen。 - - - 此外,此函数还接受integer类型的参数名version,指定统计信息来源的服务器版本。这有助于从旧版本的PostgreSQL移植统计信息。 - - - 次要错误会以WARNING报告并被忽略,其余统计信息仍将被恢复。如果所有指定的统计信息都成功恢复,则返回true,否则返回false。 - - - 调用者必须对该表拥有MAINTAIN权限或者是数据库的所有者。 - - - - - - - - - pg_clear_relation_stats - - pg_clear_relation_stats ( schemaname text, relname text ) - void - - - 清除给定关系的表级统计信息,就像该表是新创建的一样。 - - - 调用者必须对该表拥有MAINTAIN权限或者是数据库的所有者。 - - - - - - - - pg_restore_attribute_stats - - pg_restore_attribute_stats ( - VARIADIC kwargs "any" ) - boolean - - - 创建或更新列级统计信息。通常这些统计信息由自动收集或作为的一部分更新,因此不必调用此函数。但它在恢复后很有用,可以在尚未运行ANALYZE时帮助优化器选择更好的计划。 - - - 被跟踪的统计信息可能因版本而异,所以参数以argnameargvalue对的形式传递: - -SELECT pg_restore_attribute_stats( - 'arg1name', 'arg1value'::arg1type, - 'arg2name', 'arg2value'::arg2type, - 'arg3name', 'arg3value'::arg3type); - - - - 例如,要设置表mytable的属性col1avg_widthnull_frac值: - -SELECT pg_restore_attribute_stats( - 'schemaname', 'myschema', - 'relname', 'mytable', - 'attname', 'col1', - 'inherited', false, - 'avg_width', 125::integer, - 'null_frac', 0.5::real); - - - - 必需的参数包括:text类型的schemanamerelname,用于指定表;text类型的attnamesmallint类型的attnum,用于指定列;以及inherited,指定统计信息是否包含来自子表的值。其他参数是与pg_stats中的列对应的统计信息的名称和值。 - - - 此外,此函数还接受integer类型的参数名version,指定统计信息来源的服务器版本。这有助于从旧版本的PostgreSQL移植统计信息。 - - - 次要错误会以WARNING报告并被忽略,其余统计信息仍将被恢复。如果所有指定的统计信息都成功恢复,则返回true,否则返回false。 - - - 调用者必须对该表拥有MAINTAIN权限或者是数据库的所有者。 - - - - - - - - pg_clear_attribute_stats - - pg_clear_attribute_stats ( - schemaname text, - relname text, - attname text, - inherited boolean ) - void - - - 清除给定关系和属性的列级统计信息,就像该表是新创建的一样。 - - - 调用者必须对该表拥有MAINTAIN权限或者是数据库的所有者。 - - - - - -
列出提供有关分区表结构信息的函数。 @@ -24362,7 +23656,7 @@ SELECT pg_restore_attribute_stats( - 例如,要检查分区表measurement中包含的数据的总大小,可以使用以下查询: + 例如,要检查分区表measurement中包含的数据的总大小,可以使用以下查询: SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size FROM pg_partition_tree('measurement'); @@ -24377,7 +23671,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size 显示了索引维护任务可以使用的函数。 - (注意,这些维护任务通常由自动清理(autovacuum)自动完成;只有在特殊情况下才需要使用这些函数。) + (注意,这些维护任务通常由 autovacuum 自动完成;只有在特殊情况下才需要使用这些函数。) 这些函数在恢复过程中无法执行。这些函数的使用局限于超级用户和给定索引的所有者。 @@ -24408,7 +23702,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size integer - 扫描指定的BRIN索引以查找基表中当前尚未生成索引摘要的页面范围; + 扫描指定的BRIN索引以查找基表中当前尚未生成索引摘要的页面范围; 对于任何这样的范围,它都通过扫描这些表页来创建一个新的摘要索引元组。 返回插入到索引中的新页面范围摘要的数量。 @@ -24424,7 +23718,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size 对覆盖给定块的页面范围执行摘要(如果尚未摘要)。 - 这类似于brin_summarize_new_values,只是它只处理覆盖给定表块数的页范围。 + 这类似于brin_summarize_new_values,区别在于它只处理包含给定表块编号的页面范围。 @@ -24450,9 +23744,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size bigint - 清理指定GIN索引的pending列表,通过移除里面的条目,以大批的方式,到主要的GIN数据结构。 - 返回从挂起列表中删除的页数。如果参数是使用禁用fastupdate选项构建的GIN索引,则不会发生清理,结果为零,因为索引没有挂起的列表。 - 关于挂起列表和fastupdate选项的详细信息,请参见。 + 将指定 GIN 索引的待处理列表中的条目批量移入主 GIN 数据结构,从而清理该列表。返回从待处理列表中移除的页数。如果参数是禁用fastupdate选项构建的 GIN 索引,则不会进行清理,结果为零,因为该索引没有待处理列表。有关待处理列表和fastupdate选项的详细信息,参见 @@ -24467,21 +23759,16 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size 中展示的函数提供了对数据库服务器所在机器上的文件的本地访问。 - 只能访问数据库集簇目录以及log_directory中的文件,除非用户是超级用户或者被授予了角色pg_read_server_files。 + 只能访问数据库集簇目录以及log_directory中的文件,除非用户是超级用户或者被授予了角色pg_read_server_files。 使用相对路径访问集簇目录里面的文件,以及匹配 log_directory配置设置的路径访问日志文件。 - 注意在pg_read_file()或者相关函数上,向用户授予EXECUTE权限, - 以允许他们有能力读取服务器上该数据库服务器进程能读取的任何文件;这些函数会绕过所有的数据库内权限检查。 - 这意味着,例如,具有这种访问的用户能够读取pg_authid表中存储着认证信息的内容,也能读取数据库中的任何表数据。 - 因此,授予对这些函数的访问应该要很仔细地考虑。 + 注意,向用户授予pg_read_file()或相关函数的 EXECUTE 权限,会使其能够读取服务器上数据库服务器进程能读取的任何文件;这些函数会绕过数据库内部的所有权限检查。例如,具有这种访问权限的用户能够读取存储认证信息的pg_authid表的内容,以及数据库中的任何表数据。因此,授予这些函数的访问权限时应仔细考虑。 - 这些函数中的一些函数有可选的missing_ok参数,可以指定当文件或目录不存在时的行为。 - 如果为true,函数返回NULL或着空结果集,根据适合情况。 - 如果为false,会产生一个错误。默认为false。 + 这些函数中的一些函数接受可选的missing_ok参数,用于指定文件或目录不存在时的行为。如果为true,函数会视情况返回NULL或空结果集。如果为false,则会报错。默认为false @@ -24511,12 +23798,12 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size setof text - 返回指定目录中所有文件(和目录以及其他指定文件)的名称。 - include_dot_dirs参数标示在结果集中是否包括...;默认为不包括它们。 - 要包括它们在missing_oktrue时能够有用,以从不存在的目录中辨别一个空目录。 + 返回指定目录中所有文件的名称(包括目录及其他特殊文件)。 + include_dot_dirs参数指示结果集中是否包含...;默认不包含它们。 + 在missing_oktrue时,包含它们有助于区分不存在的目录和空目录。 - 这个函数默认限制为超级用户,但是其他用户可以被授予EXECUTE以运行此函数。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -24535,7 +23822,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size 返回服务器日志目录中每个普通文件的名称、大小和最后修改时间(mtime)。以点开头的文件名、目录和其他特殊文件将被排除。 - 默认情况下,此函数仅限于超级用户和具有pg_monitor角色权限的角色,但其他用户可以被授予EXECUTE权限来运行该函数。 + 默认情况下,此函数仅限超级用户和具有pg_monitor角色权限的角色使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -24555,8 +23842,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size 以点开头的文件名、目录和其他特殊文件将被排除。 - 默认情况下,此函数仅限于超级用户和具有pg_monitor角色权限的角色, - 但其他用户可以被授予EXECUTE权限来运行该函数。 + 默认情况下,此函数仅限超级用户和具有pg_monitor角色权限的角色使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -24576,7 +23862,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size 以点开头的文件名、目录和其他特殊文件将被排除。 - 默认情况下,此函数仅限于超级用户和pg_monitor角色的成员,但其他用户可以被授予EXECUTE权限来运行该函数。 + 默认情况下,此函数仅限超级用户和pg_monitor角色的成员使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -24596,7 +23882,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size 以点开头的文件名、目录和其他特殊文件将被排除。 - 默认情况下,此函数仅限于超级用户和pg_monitor角色的成员,但其他用户可以被授予EXECUTE权限来运行该函数。 + 默认情况下,此函数仅限超级用户和pg_monitor角色的成员使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -24616,7 +23902,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size 其中slot_name是作为函数输入提供的复制槽的名称。以点开头的文件名、目录和其他特殊文件将被排除。 - 默认情况下,此函数仅限于超级用户和pg_monitor角色的成员,但其他用户可以被授予EXECUTE权限来运行该函数。 + 默认情况下,此函数仅限超级用户和pg_monitor角色的成员使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -24632,11 +23918,11 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size modificationtimestamp with time zone ) - 返回服务器的WAL归档状态目录(pg_wal/archive_status)中的每个普通文件的名称、大小、和最后修改时间(mtime)。 - 文件名以一个点(dot)开始,目录和其他指定的文件不包括。 + 返回服务器 WAL 归档状态目录(pg_wal/archive_status)中每个普通文件的名称、大小和最后修改时间(mtime)。 + 以点号开头的文件名、目录以及其他特殊文件都不会包含在结果中。 - 这个函数默认限制在超级用户和pg_monitor角色的成员,但是其他用户可以被授予EXECUTE以运行此函数。 + 默认情况下,此函数仅限超级用户和pg_monitor角色的成员使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -24653,12 +23939,12 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size modificationtimestamp with time zone ) - 返回针对指定tablespace的临时文件目录中的每个普通文件的名称、大小、和最后修改时间(mtime)。 - 如果tablespace没有提供,pg_default 表空间为被检验的。 - 文件名以一个点(dot)开始,目录和其他指定的文件不包括。 + 返回针对指定tablespace的临时文件目录中每个普通文件的名称、大小和最后修改时间(mtime)。 + 如果未提供tablespace,则检查pg_default表空间。 + 以点号开头的文件名、目录以及其他特殊文件都不会包含在结果中。 - 这个函数默认限制在超级用户和pg_monitor角色的成员,但是其他用户可以被授予EXECUTE以运行此函数。 + 默认情况下,此函数仅限超级用户和pg_monitor角色的成员使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -24671,12 +23957,12 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size text - 返回一个文本文件的全部或部分,开始于给定的字节offset,在最大的length字节返回(如果文件的结尾先达到了则减少)。 - 如果offset为负,他于文件的结尾有关。如果offsetlength 被省略,整个文件被返回。 - 从文件中读的字节在服务器的编码中解释为字符串;如果它们在哪些编码中不是有效的则抛出错误。 + 返回一个文本文件的全部或部分,从给定的字节offset开始,最多返回length字节(如果先到达文件末尾,则返回更少)。 + 如果offset为负,则它相对于文件末尾计算。如果省略offsetlength,则返回整个文件。 + 从文件中读取的字节会按数据库编码解释为字符串;如果它们在该编码下无效,则会抛出错误。 - 这个函数默认限制在超级用户,但是其他用户可以被授予EXECUTE以运行此函数。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -24689,14 +23975,14 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size bytea - 返回文件的全部或部分。这个函数与pg_read_file 是完全相同的,除了它可以读任意的二进制数据,返回结果为bytea而不是text; - 因此,没有编码检查会被执行。 + 返回文件的全部或部分。该函数与pg_read_file完全相同,只是它可以读取任意二进制数据,并返回bytea而不是text; + 因此不会执行编码检查。 - 这个函数默认限制在超级用户,但是其他用户可以被授予EXECUTE以运行此函数。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 - 与 convert_from函数组合,这个函数能被用于以指定的编码读文本文件并转换到数据库的编码: + 与convert_from函数配合使用时,该函数可用于按指定编码读取文本文件,并将其转换为数据库编码: SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); @@ -24718,10 +24004,10 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); isdir boolean ) - 返回一个记录,包含文件的大小、最后访问时间戳、最后修改时间戳,最后文件状态变更时间戳(仅在UNIX平台)、文件建立时间戳(仅Windows),和一个标志旗如果它是一个目录。 + 返回一个记录,包含文件大小、最后访问时间戳、最后修改时间戳、最后文件状态变更时间戳(仅限 Unix 平台)、文件创建时间戳(仅限 Windows)以及一个指示其是否为目录的标志。 - 这个函数默认限制在超级用户,但是其他用户可以被授予EXECUTE以运行此函数。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -24741,11 +24027,11 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); - 所有这些函数都打算用于锁定应用程序定义的资源,可以通过一个64位键值或两个32位键值来标识(注意这两个键空间不能重叠)。 - 如果另一个会话已经在相同的资源标识符上持有一个冲突的锁,函数将等待直到资源变成可用,或者返回一个false结果,合适于函数的。 - 锁可以是共享或排他的:共享锁不会与同一资源上的其他共享锁发生冲突,只会与排他锁发生冲突。 - 锁可以在会话级(这样它们被保持直到释放或会话结束)或在事务级(这样它们被保持直到当前事务结束;没有手动释放的供应)。 - 多个会话级锁请求堆栈,因此如果同一个资源标识符被锁定三次,那么必须有三个解锁请求来释放资源,在会话结束之前。 + 这些函数用于锁定应用程序定义的资源;资源可用一个 64 位键值或两个 32 位键值标识(这两个键空间互不重叠)。 + 如果另一个会话已对同一资源标识符持有冲突锁,函数会根据自身的行为等待资源可用,或返回false。 + 锁可以是共享的或排他的:共享锁不会与同一资源上的其他共享锁冲突,只会与排他锁冲突。 + 锁可以在会话级获取(一直保持到释放或会话结束),也可以在事务级获取(一直保持到当前事务结束,不能手动释放)。 + 多次会话级锁请求会累加,因此,如果同一资源标识符被锁定三次,就必须请求解锁三次,才能在会话结束前释放该资源。
@@ -24896,8 +24182,8 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); boolean - 获取一个排他的会话级咨询锁,如果适用。 - 这将立即获得锁并返回true,或者如果不能立即获取锁则立即返回 false而无需等待。 + 尝试获取一个排他的会话级咨询锁。 + 如果能立即获取到锁,就返回true;否则立即返回false,而不等待。 @@ -24914,8 +24200,8 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); boolean - 获取一个共享的会话级咨询锁,如果适用。 - 这将立即获得锁并返回true,或者如果不能立即获取锁则立即返回 false而无需等待。 + 尝试获取一个共享的会话级咨询锁。 + 如果能立即获取到锁,就返回true;否则立即返回false,而不等待。 @@ -24932,8 +24218,8 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); boolean - 获取一个排他的事务级咨询锁,如果适用。 - 这将立即获得锁并返回true,或者如果不能立即获取锁则立即返回 false而无需等待。 + 尝试获取一个排他的事务级咨询锁。 + 如果能立即获取到锁,就返回true;否则立即返回false,而不等待。 @@ -24950,8 +24236,8 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); boolean - 获取一个共享的事务级咨询锁,如果适用。 - 这将立即获得锁并返回true,或者如果不能立即获取锁则立即返回 false而无需等待。 + 尝试获取一个共享的事务级咨询锁。 + 如果能立即获取到锁,就返回true;否则立即返回false,而不等待。 @@ -25006,7 +24292,7 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); trigger - 阻止不做事的更新操作。详见下文。 + 抑制不改变数据的更新操作。详见下文。 CREATE TRIGGER ... suppress_redundant_updates_trigger() @@ -25022,8 +24308,7 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); trigger - 自动从相关的纯文本文档列更新tsvector列。 - 要使用的文本搜索配置是以名称指定为触发器参数。详情请参见。 + 根据关联的纯文本文档列自动更新tsvector列。所用的全文检索配置以名称形式指定为触发器参数。详见 CREATE TRIGGER ... tsvector_update_trigger(tsvcol, 'pg_catalog.swedish', title, body) @@ -25039,8 +24324,7 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); trigger - 自动从相关的纯文本文档列更新tsvector列。 - 要使用的文本搜索配置取自表的regconfig列。详情请参见。 + 根据关联的纯文本文档列自动更新tsvector列。所用的全文检索配置取自表的regconfig列。详见 CREATE TRIGGER ... tsvector_update_trigger_column(tsvcol, tsconfigcol, title, body) @@ -25057,23 +24341,15 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); - 理想的情况下,你应该避免运行实际上并没有改变记录中数据的更新。 - 冗余更新会花费大量不必要的时间,尤其是如果有大量索引要改变, 并将最终不得不清理被死亡行占用的空间。 - 但是,在客户端代码中检测这种情况并不总是容易的,甚至不可能做到。 而写表达式来检测它们容易产生错误。 - 作为替代,使用suppress_redundant_updates_trigger可以跳过不改变数据的更新。 但是,你需要小心使用它。 - 触发器需要很短但不能忽略的时间来处理每条记录,所以如果受更新影响的大多数记录确实变化了,此触发器的使用将使更新比平均水平运行得更慢。 + 理想情况下,应避免执行实际上不会改变记录中数据的更新。冗余更新会耗费大量不必要的时间,尤其是在需要修改许多索引时;它们还会使死行占用空间,最终需要通过清理回收。但是,在客户端代码中检测这种情况并不总是容易,甚至可能无法做到,而编写用于检测的表达式也容易出错。另一种办法是使用suppress_redundant_updates_trigger,跳过不改变数据的更新。但使用时应当谨慎。此触发器处理每条记录的耗时虽小,却不可忽略,因此如果更新涉及的大多数记录确实会改变,使用此触发器反而会增加更新的平均耗时。 - suppress_redundant_updates_trigger函数可以像这样添加到表中: - + 该suppress_redundant_updates_trigger函数可以按如下方式添加到表中: CREATE TRIGGER z_min_update BEFORE UPDATE ON tablename FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); - - 在大多数情况下,你需要为每一行最后触发这个触发器,这样它就不会覆盖可能希望更改该行的其他触发器。 - 请记住,触发器是按照名称顺序触发的,你将为此选择一个触发器名称,该名称位于表中可能存在的任何其他触发器的名称之后。 - (因此在示例中使用了z前缀。) +大多数情况下,需要让该触发器对每一行最后触发,以免覆盖其他可能修改该行的触发器的效果。由于触发器按名称顺序触发,应选择一个排序位于表上其他所有触发器名称之后的名称。(这就是示例中使用z前缀的原因。) @@ -25082,7 +24358,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); 事件触发器函数 - PostgreSQL提供了这些助手函数来从事件触发器检索信息。 + PostgreSQL提供了这些辅助函数来从事件触发器检索信息。 @@ -25104,7 +24380,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); 当在一个ddl_command_end事件触发器的函数中调用时,pg_event_trigger_ddl_commands返回被每一个用户动作执行的DDL命令的列表。 如果在其他任何环境中调用这个函数,会发生错误。 - pg_event_trigger_ddl_commands为每一个被执行的基本命令返回一行,某些只有一个单一 SQL 句子的命令可能会返回多于一行。 + pg_event_trigger_ddl_commands为每一个被执行的基本命令返回一行,某些由单条 SQL 语句构成的命令可能会返回多于一行。 这个函数返回下面的列: @@ -25121,7 +24397,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); classid oid - 对象所属的目录的 OID + 对象所属系统目录的 OID objid @@ -25131,7 +24407,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); objsubid integer - 对象的子-id(例如列的属性号) + 子对象 ID(例如列的属性编号) command_tag @@ -25147,16 +24423,14 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); schema_name text - 该对象所属的模式的名称(如果有),如果没有则为NULL。 - 没有引号。 + 对象所属模式的名称(若有);否则为NULL。不加引号。 object_identity text - 对象标识的文本表现形式,用模式限定。如果必要,出现在 - 该标识中的每一个标识符都会被引用。 + 对象标识的文本表示形式,带模式限定。标识中包含的每个标识符在必要时都会加引号。 @@ -25168,8 +24442,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); command pg_ddl_command - 以内部格式表达的该命令的一个完整表现形式。这不能被直接输出, - 但是可以把它传递给其他函数来得到有关于该命令不同部分的信息。 + 命令的完整内部表示,不能直接输出,但可以将其传给其他函数以获取关于该命令的不同信息。 @@ -25191,8 +24464,8 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); - pg_event_trigger_dropped_objects返回被调用sql_drop事件的命令删除的所有对象的列表。 - 如果调用在任何其他上下文中,会引发一个错误。这个函数返回以下列: + 在命令的sql_drop事件中调用pg_event_trigger_dropped_objects时,它返回该命令删除的所有对象的列表。 + 如果调用在任何其他上下文中,会引发一个错误。这个函数返回以下列: @@ -25208,7 +24481,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); classid oid - 对象所属的目录的 OID + 对象原先所属系统目录的 OID objid @@ -25218,7 +24491,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); objsubid integer - 子对象ID(如列的属性号) + 子对象 ID(例如列的属性编号) original @@ -25229,7 +24502,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); normal boolean - 指示在依赖图中有一个普通依赖关系指向该对象的标志 + 如果依赖图中存在指向该对象的普通依赖关系,则为真。 @@ -25248,29 +24521,28 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); schema_name text - 对象所属模式的名称(如果存在);否则为NULL。不应用引用。 + 对象原先所属模式的名称(若有);否则为NULL。不加引号。 object_name text - 如果模式和名称的组合能被用于对象的一个唯一标识符,则是对象的名称;否则是NULL。不应用引用,并且名称不是模式限定的。 + 如果模式和名称的组合可用作该对象的唯一标识符,则为对象名称;否则为NULL。不加引号,并且该名称永远不带模式限定。 object_identity text - 对象身份的文本表现,模式限定的。每一个以及所有身份中出现的标识符在必要时加引号。 + 对象标识的文本表示形式,带模式限定。标识中包含的每个标识符在必要时都会加引号。 address_names text[] - 一个数组,它可以和object_typeaddress_args, - 一起通过pg_get_object_address函数在一台包含有同类相同名称对象的远程服务器上重建该对象地址。 + 一个数组,可与object_typeaddress_args一起,通过pg_get_object_address函数在包含同类同名对象的远程服务器上重建该对象地址。 @@ -25369,7 +24641,7 @@ CREATE EVENT TRIGGER test_event_trigger_for_drops
- 这些函数可以在事件触发器中使用,就像这样: + 这些函数可以在事件触发器中使用,就像这样: CREATE FUNCTION test_event_trigger_table_rewrite_oid() RETURNS event_trigger @@ -25395,12 +24667,12 @@ CREATE EVENT TRIGGER test_table_rewrite_oid 统计信息函数 - function - statistics + 函数 + 统计信息 - PostgreSQL提供了一个函数来检查使用CREATE STATISTICS命令定义的复杂统计。 + PostgreSQL提供了一个函数来检查使用CREATE STATISTICS命令定义的复杂统计信息。 @@ -25416,7 +24688,7 @@ CREATE EVENT TRIGGER test_table_rewrite_oid - pg_mcv_list_items返回一组记录,描述存储在多列MCV列表中的所有项目。它返回以下列: + pg_mcv_list_items返回一组记录,描述存储在多列MCV列表中的所有项目。它返回以下列: @@ -25452,7 +24724,7 @@ CREATE EVENT TRIGGER test_table_rewrite_oid base_frequency double precision - MCV项目的基本频率 + MCV项目的基础频率 @@ -25460,7 +24732,7 @@ CREATE EVENT TRIGGER test_table_rewrite_oid - pg_mcv_list_items函数可以这样使用: + pg_mcv_list_items函数可以这样使用: SELECT m.* FROM pg_statistic_ext join pg_statistic_ext_data on (oid = stxoid), diff --git a/zh/15/generic-wal.sgml b/zh/15/generic-wal.sgml index 448939ae..5edefc7c 100644 --- a/zh/15/generic-wal.sgml +++ b/zh/15/generic-wal.sgml @@ -4,7 +4,12 @@ 通用 WAL 记录 - 虽然所有内置的、会生成 WAL 记录的模块都有各自的 WAL 记录类型,但也有一种通用 WAL 记录类型,可以用通用方式描述对页面的更改。 + 虽然所有内置的、会生成 WAL 记录的模块都有各自的 WAL 记录类型,但也有一种通用 WAL 记录类型,可以用通用方式描述对页面的更改。这对于提供自定义访问方法的扩展很有用。 + + + + 与自定义 WAL 资源管理器相比,通用 WAL 对扩展而言实现更简单, + 而且应用这些记录时不需要加载扩展库。 diff --git a/zh/15/gin.sgml b/zh/15/gin.sgml index ce1e6aae..ae7bfcfe 100644 --- a/zh/15/gin.sgml +++ b/zh/15/gin.sgml @@ -8,7 +8,7 @@ GIN - + 简介 @@ -47,13 +47,13 @@ Teodor Sigaev 和 Oleg Bartunov 维护。关于 GIN 的更多信息, 可在他们的 网站 上找到。 - + - + 内置操作符类 - PostgreSQL 核心发布包含 + PostgreSQL 核心发行版包含 所示的 GIN 操作符类。 (在 中描述的一些可选模块还提供额外的 GIN 操作符类。) @@ -111,9 +111,12 @@ @@ (jsonb,jsonpath) - tsvector_ops + tsvector_ops @@ (tsvector,tsquery) + + @@@ (tsvector,tsquery) + @@ -124,9 +127,9 @@ 详见 - + - + 可扩展性 @@ -152,7 +155,7 @@ 给定一个要建立索引的项,返回一个用 palloc 分配的键数组。返回键的数量必须存入 *nkeys。如果任一键可以为 null,还要另外 palloc 一个包含 *nkeysbool 字段的数组,将其地址存入 - *nullFlags,并按需设置这些空值标志。如果所有键都非空, + *nullFlags,并按需设置这些空值标志。如果所有键都不是 null, *nullFlags 可以保持为 NULL(其初始值)。 如果该项不包含任何键,则返回值可以为 NULL @@ -172,7 +175,7 @@ query 的数据类型,以及应采用何种方法提取键值。返回键的数量必须存入 *nkeys。如果任一键可以为 null,还要另外 palloc 一个包含 *nkeysbool 字段的数组,将其地址存入 - *nullFlags,并按需设置这些空值标志。如果所有键都非空, + *nullFlags,并按需设置这些空值标志。如果所有键都不是 null, *nullFlags 可以保持为 NULL(其初始值)。 如果 query 不包含任何键,则返回值可以为 NULL @@ -185,7 +188,7 @@ 被设置为 GIN_SEARCH_MODE_INCLUDE_EMPTY,则除至少包含一个匹配键的项之外, 完全不含任何键的项也会被视为候选匹配。(例如,该模式对于实现是子集操作符很有用。) 若 *searchMode 被设置为 GIN_SEARCH_MODE_ALL, - 则索引中所有非空项都会被视为候选匹配,无论它们是否匹配任一返回键。 + 则索引中所有非 null 项都会被视为候选匹配,无论它们是否匹配任一返回键。 (该模式比前两种选择慢得多,因为它基本上需要扫描整个索引;但为了正确处理某些边界情况, 可能有此必要。在大多数情况下都需要此模式的操作符,大概并不适合作为 GIN 操作符类的候选。)用于设置该模式的符号定义在 @@ -218,7 +221,7 @@ 操作符类还必须提供一个函数,用于检查被索引项是否匹配查询。它有两种形式:布尔型 consistent 函数,以及三值型 triConsistent 函数。 triConsistent 覆盖了两者的功能,因此仅提供 triConsistent - 就已经足够。不过,如果布尔变体的计算明显更便宜,那么同时提供两者会更有利。 + 就已经足够。不过,如果布尔变体的计算代价明显更低,那么同时提供两者可能更有利。 若只提供布尔变体,则一些依赖于在取回所有键之前先排除索引项的优化将被禁用。 @@ -233,10 +236,10 @@ 该函数无法直接访问被索引项的值,因为 GIN 并不显式存储项。 它所能利用的是这样一种信息:从查询中提取出的哪些键值出现在给定的被索引项中。 check 数组长度为 nkeys,这与先前针对该 - query 数据由 extractQuery 返回的键数量相同。 + query datum 由 extractQuery 返回的键数量相同。 如果被索引项包含相应查询键,则 check 数组中的对应元素为 true; 也就是说,如果 check[i] == true,则 extractQuery - 结果数组中的第 i 个键存在于该被索引项中。传入原始 query 数据值, + 结果数组中的第 i 个键存在于该被索引项中。传入原始 query datum, 是为了让 consistent 方法在需要时可以查看它;同样也会传入先前由 extractQuery 返回的 queryKeys[]nullFlags[] 数组。extra_data 则是 @@ -274,7 +277,7 @@ 而 GIN_MAYBE 表示该键是否存在尚不确定。存在 GIN_MAYBE 值时,只有当无论索引项是否包含对应查询键,该项都确定匹配时,函数才应返回 GIN_TRUE。同样,只有当无论是否包含 GIN_MAYBE 键, - 该项都确定不匹配时,函数才必须返回 GIN_FALSE。如果结果依赖于 + 该项都确定不匹配时,函数才能返回 GIN_FALSE。如果结果依赖于 GIN_MAYBE 条目,也就是说,无法根据已知的查询键确认或否定匹配, 则函数必须返回 GIN_MAYBE。 @@ -306,7 +309,7 @@ 或者,如果操作符类没有提供 compare 方法,GIN 将查找该索引键数据类型的默认 B-树操作符类,并使用其比较函数。建议在仅面向单一数据类型的 - GIN 操作符类中显式指定比较函数,因为查找 B-树操作符类会消耗少量周期。 + GIN 操作符类中显式指定比较函数,因为查找 B-树操作符类会消耗少量处理器周期。 不过,多态 GIN 操作符类(例如 array_ops)通常无法指定单一比较函数。 @@ -367,15 +370,15 @@ 尽管依据具体操作符,实际类型可能是别的类型。 - + - + 实现 在内部,一个 GIN 索引包含一个基于键构建的 B-树索引,其中每个键都是一个或多个被索引项中的某个元素 - (例如数组成员),而叶子页中的每个元组要么包含一个指向堆指针 B-树的指针(posting tree), - 要么在列表足够小、能够连同键值一起放入单个索引元组时,直接包含一个简单的堆指针列表(posting list)。 + (例如数组成员),而叶子页中的每个元组要么包含一个指向堆指针 B-树的指针(倒排树), + 要么在列表足够小、能够连同键值一起放入单个索引元组时,直接包含一个简单的堆指针列表(倒排列表)。 展示了 GIN 索引的这些组成部分。 @@ -399,7 +402,7 @@ - + GIN 快速更新技术 @@ -422,13 +425,13 @@ - 如果一致的响应时间比更新速度更重要,可以通过关闭 GIN 索引的 + 如果稳定的响应时间比更新速度更重要,可以通过关闭 GIN 索引的 fastupdate 存储参数来禁用待处理列表机制。详见 - + - + 部分匹配算法 @@ -442,11 +445,11 @@ 对于虽然不匹配但仍处在待搜索范围内的索引键,返回小于零; 如果索引键已经超出了可能匹配的范围,则返回大于零。 - - - + + + GIN 提示和技巧 @@ -461,7 +464,7 @@ 当为 GIN 启用 fastupdate 时 (详见 ),这种代价会比未启用时小一些。 - 但对于非常大的更新,最好仍然是删除并重建索引。 + 但对于非常大的更新,删除并重建索引仍然可能是最佳选择。 @@ -520,24 +523,24 @@ - + - + 限制 GIN 假定可索引操作符是严格的。这意味着,当项值为 null 时, 根本不会对其调用 extractValue(而是自动创建一个占位符索引项); 当查询值为 null 时,也不会调用 extractQuery(而是认为该查询不可满足)。 - 不过要注意,非空组合项或查询值内部包含的 null 键值仍然受支持。 + 不过要注意,非 null 的组合项或查询值内部包含的 null 键值仍然受支持。 - + - + 示例 - PostgreSQL 核心发布包含前面在 + PostgreSQL 核心发行版包含前面在 中展示过的 GIN 操作符类。 下列 contrib 模块也包含 GIN 操作符类: @@ -571,6 +574,6 @@ - + diff --git a/zh/15/gist.sgml b/zh/15/gist.sgml index 7dc4c28c..21a5960f 100644 --- a/zh/15/gist.sgml +++ b/zh/15/gist.sgml @@ -4,11 +4,11 @@ GiST 索引 - index + 索引 GiST - + 简介 @@ -30,9 +30,9 @@ 网站上还有更多信息。 - + - + 内置操作符类 @@ -201,9 +201,9 @@ CREATE INDEX ON my_table USING GIST (my_inet_column inet_ops); - + - + 可扩展性 @@ -211,7 +211,7 @@ CREATE INDEX ON my_table USING GIST (my_inet_column inet_ops); - 这种可扩展性不应与其他标准搜索树在可处理数据方面的可扩展性相混淆。例如,PostgreSQL支持可扩展的 B-树和哈希索引。这意味着你可以用PostgreSQL在任意数据类型上构建 B-树或哈希索引。但 B-树只支持范围谓词(<=>),而哈希索引只支持等值查询。 + 这种可扩展性不应与其他标准搜索树在可处理数据方面的可扩展性相混淆。例如,PostgreSQL支持可扩展的 B-树和 hash 索引。这意味着你可以用PostgreSQL在任意数据类型上构建 B-树或 hash 索引。但 B-树只支持范围谓词(<=>),而 hash 索引只支持等值查询。 @@ -223,7 +223,7 @@ CREATE INDEX ON my_table USING GIST (my_inet_column inet_ops); - 一个GiST索引操作符类必须提供五个方法,另外还有七个可选方法。通过正确实现sameconsistentunion方法可以保证索引的正确性,而索引的效率(大小与速度)则取决于penaltypicksplit方法。两个可选方法是compressdecompress,它们允许索引的内部树数据使用与其所索引数据不同的类型。叶子必须是被索引数据类型,而其他树节点可以是任意 C 结构体(但这里仍必须遵守PostgreSQL的数据类型规则,关于变长数据可参见varlena)。如果树的内部数据类型在 SQL 层存在,可以使用CREATE OPERATOR CLASS命令的STORAGE选项。可选的第八个方法是distance,若操作符类希望支持有序扫描(最近邻搜索),则需要它。可选的第九个方法fetch在操作符类希望支持仅索引扫描时需要,除非省略了compress方法。可选的第十个方法options在操作符类具有用户指定参数时需要。可选的第十一个方法sortsupport用于加速构建GiST索引。可选的第十二个方法translate_cmptype用于把比较类型(来自src/include/access/cmptype.h)转换为该操作符类使用的策略号。这样核心代码就可以为时态约束索引查找操作符。 + 一个GiST索引操作符类必须提供五个方法,另外还有六个可选方法。通过正确实现sameconsistentunion方法可以保证索引的正确性,而索引的效率(大小与速度)则取决于penaltypicksplit方法。两个可选方法是compressdecompress,它们允许索引的内部树数据使用与其所索引数据不同的类型。叶子必须是被索引数据类型,而其他树节点可以是任意 C 结构体(但这里仍必须遵守PostgreSQL的数据类型规则,关于变长数据可参见varlena)。如果树的内部数据类型在 SQL 层存在,可以使用CREATE OPERATOR CLASS命令的STORAGE选项。可选的第八个方法是distance,若操作符类希望支持有序扫描(最近邻搜索),则需要它。可选的第九个方法fetch在操作符类希望支持仅索引扫描时需要,除非省略了compress方法。可选的第十个方法options在操作符类具有用户指定参数时需要。可选的第十一个方法sortsupport用于加速构建GiST索引。 @@ -262,15 +262,14 @@ my_consistent(PG_FUNCTION_ARGS) bool retval; /* - * determine return value as a function of strategy, key and query. + * 根据 strategy、key 和 query 确定返回值。 * - * Use GIST_LEAF(entry) to know where you're called in the index tree, - * which comes handy when supporting the = operator for example (you could - * check for non empty union() in non-leaf nodes and equality in leaf - * nodes). + * 使用 GIST_LEAF(entry) 判断当前调用位于索引树的哪个位置。 + * 例如,支持 = 操作符时这很有用(可以在非叶节点检查 + * union() 是否非空,在叶节点检查是否相等)。 */ - *recheck = true; /* or false if check is exact */ + *recheck = true; /* 如果检查是精确的,则为 false */ PG_RETURN_BOOL(retval); } @@ -386,10 +385,10 @@ my_compress(PG_FUNCTION_ARGS) if (entry->leafkey) { - /* replace entry->key with a compressed version */ + /* 将 entry->key 替换为压缩后的形式 */ compressed_data_type *compressed_data = palloc(sizeof(compressed_data_type)); - /* fill *compressed_data from entry->key ... */ + /* 根据 entry->key 填充 *compressed_data ... */ retval = palloc(sizeof(GISTENTRY)); gistentryinit(*retval, PointerGetDatum(compressed_data), @@ -397,7 +396,7 @@ my_compress(PG_FUNCTION_ARGS) } else { - /* typically we needn't do anything with non-leaf entries */ + /* 通常无需对非叶项做任何处理 */ retval = entry; } @@ -460,7 +459,7 @@ my_decompress(PG_FUNCTION_ARGS) CREATE OR REPLACE FUNCTION my_penalty(internal, internal, internal) RETURNS internal AS 'MODULE_PATHNAME' -LANGUAGE C STRICT; -- in some cases penalty functions need not be strict +LANGUAGE C STRICT; -- 某些情况下 penalty 函数不必是严格函数 而 C 模块中的对应代码则可以遵循如下框架: @@ -482,7 +481,7 @@ my_penalty(PG_FUNCTION_ARGS) } - 出于历史原因,penalty函数并不是直接返回一个float结果;相反,它必须把该值存储到第三个参数指示的位置。返回值本身会被忽略,不过通常会返回该参数的地址。 + 出于历史原因,penalty函数并不是直接返回一个float结果;相反,它必须把该值存储到第三个参数指示的位置。返回值本身会被忽略,不过通常会返回该参数所指向的地址。 @@ -543,7 +542,7 @@ my_picksplit(PG_FUNCTION_ARGS) unionL = NULL; unionR = NULL; - /* Initialize the raw entry vector. */ + /* 初始化原始项向量。 */ raw_entryvec = (GISTENTRY **) malloc(entryvec->n * sizeof(void *)); for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) raw_entryvec[i] = &(entryvec->vector[i]); @@ -556,9 +555,9 @@ my_picksplit(PG_FUNCTION_ARGS) Assert(tmp_union != NULL); /* - * Choose where to put the index entries and update unionL and unionR - * accordingly. Append the entries to either v->spl_left or - * v->spl_right, and care about the counters. + * 选择索引项的存放位置,并相应更新 unionL 和 unionR。 + * 将项追加到 v->spl_left 或 v->spl_right, + * 同时更新计数器。 */ if (my_choice_is_left(unionL, curl, unionR, curr)) @@ -575,7 +574,7 @@ my_picksplit(PG_FUNCTION_ARGS) else { /* - * Same on the right + * 对右侧执行相同操作 */ } } @@ -629,7 +628,7 @@ my_same(PG_FUNCTION_ARGS) } - 出于历史原因,same函数并不是直接返回一个布尔结果;相反,它必须把该标志存储到第三个参数指示的位置。返回值本身会被忽略,不过通常会返回该参数的地址。 + 出于历史原因,same函数并不是直接返回一个布尔结果;相反,它必须把该标志存储到第三个参数指示的位置。返回值本身会被忽略,不过通常会返回该参数所指向的地址。 @@ -668,7 +667,7 @@ my_distance(PG_FUNCTION_ARGS) double retval; /* - * determine return value as a function of strategy, key and query. + * 根据 strategy、key 和 query 确定返回值。 */ PG_RETURN_FLOAT8(retval); @@ -679,11 +678,11 @@ my_distance(PG_FUNCTION_ARGS) - 在确定距离时允许有一定近似,只要结果永不大于该项的实际距离即可。因此,例如在几何应用中,到外包盒的距离通常就足够了。对于内部树节点,返回的距离不能大于其任一子节点的距离。如果返回的距离不精确,函数必须将*recheck设为 true。(对内部树节点则不必这样做;对它们总是假定计算结果不精确。)在这种情况下,执行器会在从堆中取出元组后计算准确距离,并在必要时重新排序这些元组。 + 在确定距离时允许有一定近似,只要结果永不大于该项的实际距离即可。因此,例如在几何应用中,到包围盒的距离通常就足够了。对于内部树节点,返回的距离不能大于其任一子节点的距离。如果返回的距离不精确,函数必须将*recheck设为 true。(对内部树节点则不必这样做;对它们总是假定计算结果不精确。)在这种情况下,执行器会在从堆中取出元组后计算准确距离,并在必要时重新排序这些元组。 - 如果距离函数对任何叶节点都返回*recheck = true,原始排序操作符的返回类型必须是float8float4,且距离函数的结果值必须能与原始排序操作符的结果进行比较,因为执行器会同时使用距离函数结果和重新计算得到的排序操作符结果进行排序。否则,距离函数的结果值可以是任意有限的float8值,只要这些结果值的相对顺序与排序操作符返回的顺序一致即可。(无穷大和负无穷在内部用于处理空值等情况,因此不建议distance函数返回这些值。) + 如果距离函数对任意一个叶节点返回*recheck = true,原始排序操作符的返回类型必须是float8float4,且距离函数的结果值必须能与原始排序操作符的结果进行比较,因为执行器会同时使用距离函数结果和重新计算得到的排序操作符结果进行排序。否则,距离函数的结果值可以是任意有限的float8值,只要这些结果值的相对顺序与排序操作符返回的顺序一致即可。(无穷大和负无穷在内部用于处理空值等情况,因此不建议distance函数返回这些值。) @@ -727,10 +726,10 @@ my_fetch(PG_FUNCTION_ARGS) fetched_data = palloc(sizeof(fetched_data_type)); /* - * Convert 'fetched_data' into the a Datum of the original datatype. + * 将 'fetched_data' 转换为原始数据类型的 Datum。 */ - /* fill *retval from fetched_data. */ + /* 根据 fetched_data 填充 *retval。 */ gistentryinit(*retval, PointerGetDatum(converted_datum), entry->rel, entry->page, entry->offset, FALSE); @@ -781,26 +780,26 @@ typedef enum MyEnumType typedef struct { - int32 vl_len_; /* varlena header (do not touch directly!) */ - int int_param; /* integer parameter */ - double real_param; /* real parameter */ - MyEnumType enum_param; /* enum parameter */ - int str_param; /* string parameter */ + int32 vl_len_; /* varlena 首部(不要直接操作!) */ + int int_param; /* 整数参数 */ + double real_param; /* 实数参数 */ + MyEnumType enum_param; /* 枚举参数 */ + int str_param; /* 字符串参数 */ } MyOptionsStruct; -/* String representation of enum values */ +/* 枚举值的字符串表示 */ static relopt_enum_elt_def myEnumValues[] = { {"on", MY_ENUM_ON}, {"off", MY_ENUM_OFF}, {"auto", MY_ENUM_AUTO}, - {(const char *) NULL} /* list terminator */ + {(const char *) NULL} /* 列表终止项 */ }; static char *str_param_default = "default"; /* - * Sample validator: checks that string is not longer than 8 bytes. + * 验证器示例:检查字符串长度不超过 8 字节。 */ static void validate_my_string_relopt(const char *value) @@ -812,7 +811,7 @@ validate_my_string_relopt(const char *value) } /* - * Sample filler: switches characters to lower case. + * 填充函数示例:将字符转换为小写。 */ static Size fill_my_string_relopt(const char *value, void *ptr) @@ -821,7 +820,7 @@ fill_my_string_relopt(const char *value, void *ptr) int len = strlen(tmp); if (ptr) - strcpy(ptr, tmp); + strcpy((char *) ptr, tmp); pfree(tmp); return len + 1; @@ -865,10 +864,9 @@ my_compress(PG_FUNCTION_ARGS) char *str_param = str_param_default; /* - * Normally, when opclass contains 'options' method, then options are always - * passed to support functions. However, if you add 'options' method to - * existing opclass, previously defined indexes have no options, so the - * check is required. + * 通常,操作符类包含 'options' 方法时,总会把选项传给支持函数。 + * 但是,如果把 'options' 方法添加到已有操作符类中, + * 先前定义的索引没有选项,因此需要进行检查。 */ if (PG_HAS_OPCLASS_OPTIONS()) { @@ -880,7 +878,7 @@ my_compress(PG_FUNCTION_ARGS) str_param = GET_STRING_RELOPTION(options, str_param); } - /* the rest implementation of support function */ + /* 支持函数的其余实现 */ } @@ -924,7 +922,7 @@ PG_FUNCTION_INFO_V1(my_sortsupport); static int my_fastcmp(Datum x, Datum y, SortSupport ssup) { - /* establish order between x and y by computing some sorting value z */ + /* 通过计算某个排序值 z 来确定 x 和 y 的顺序 */ int z1 = ComputeSpatialCode(x); int z2 = ComputeSpatialCode(y); @@ -944,85 +942,22 @@ my_sortsupport(PG_FUNCTION_ARGS) - - - translate_cmptype - - - 给定一个来自src/include/access/cmptype.hCompareType值,返回该操作符类用于匹配功能的策略号。如果该操作符类没有匹配策略,函数应返回InvalidStrategy。 - - - - 这用于时态索引约束(即PRIMARY - KEYUNIQUE)。如果该操作符类提供此函数,并且它会为COMPARE_EQ返回结果,那么它就可以用于索引约束中非WITHOUT OVERLAPS的部分。 - - - - 这个支持函数对应于索引访问方法回调函数amtranslatecmptype(见)。GiST 索引的amtranslatecmptype回调函数只是调用相应操作符族的translate_cmptype支持函数,因为 GiST 索引访问方法本身并没有固定的策略号。 - - - - 该函数的SQL声明必须如下所示: - - -CREATE OR REPLACE FUNCTION my_translate_cmptype(integer) -RETURNS smallint -AS 'MODULE_PATHNAME' -LANGUAGE C STRICT; - - - 而操作符族注册必须如下所示: - -ALTER OPERATOR FAMILY my_opfamily USING gist ADD - FUNCTION 12 ("any", "any") my_translate_cmptype(int); - - - - - 而 C 模块中的对应代码则可以遵循如下框架: - - -PG_FUNCTION_INFO_V1(my_translate_cmptype); - -Datum -my_translate_cmptype(PG_FUNCTION_ARGS) -{ - CompareType cmptype = PG_GETARG_INT32(0); - StrategyNumber ret = InvalidStrategy; - - switch (cmptype) - { - case COMPARE_EQ: - ret = BTEqualStrategyNumber; - } - - PG_RETURN_UINT16(ret); -} - - - - - PostgreSQL提供了一个翻译函数:gist_translate_cmptype_common,用于使用RT*StrategyNumber常量的操作符类。btree_gist扩展又定义了第二个翻译函数gist_translate_cmptype_btree,用于使用BT*StrategyNumber常量的操作符类。 - - - 所有 GiST 支持方法通常都在短生命周期的内存上下文中被调用;也就是说,每处理完一个元组,CurrentMemoryContext都会被重置。因此通常无需过分担心释放所有通过 palloc 分配的内容。不过,在某些情况下,让支持方法在重复调用之间缓存数据是有用的。要做到这一点,可将寿命更长的数据分配在fcinfo->flinfo->fn_mcxt中,并在fcinfo->flinfo->fn_extra中保存指向它的指针。这类数据会在一次索引操作期间存活(例如一次 GiST 索引扫描、索引构建或索引元组插入)。在替换fn_extra值时要注意 pfree 旧值,否则泄漏会在整个操作期间不断累积。 - + - + 实现 - + GiST 索引构建方法 - 构建 GiST 索引最简单的方法就是把所有项逐个插入。这对于大型索引往往很慢,因为如果索引元组分散在整个索引中,而索引又大到无法放入缓存,就需要大量随机 I/O。PostgreSQL支持两种用于 GiST 索引初始构建的替代方法:sortedbuffered模式。 + 构建 GiST 索引最简单的方法就是把所有项逐个插入。这对于大型索引往往很慢,因为如果索引元组分散在整个索引中,而索引又大到无法放入缓存,就需要大量随机 I/O。PostgreSQL支持两种用于 GiST 索引初始构建的替代方法:排序缓冲模式。 @@ -1041,10 +976,10 @@ my_translate_cmptype(PG_FUNCTION_ARGS) 如果不能排序,那么默认情况下,当索引大小达到时,GiST 索引构建会切换到缓冲方法。也可以通过 CREATE INDEX 命令的buffering参数手工强制启用或禁止缓冲。默认行为在大多数情况下都不错,但如果输入数据是有序的,关闭缓冲模式可能会略微加快构建速度。 - + - + 示例 @@ -1068,7 +1003,7 @@ my_translate_cmptype(PG_FUNCTION_ARGS) hstore - 用于存储 (key, value) 对的模块 + 用于存储(键,值)对的模块 @@ -1102,6 +1037,6 @@ my_translate_cmptype(PG_FUNCTION_ARGS) - + diff --git a/zh/15/glossary.sgml b/zh/15/glossary.sgml index 0046fa75..4f986c38 100644 --- a/zh/15/glossary.sgml +++ b/zh/15/glossary.sgml @@ -36,19 +36,6 @@ - - 访问方法 - - - PostgreSQL 用来访问表和索引中数据的接口。 - 这种抽象允许增加对新型数据存储的支持。 - - - 更多信息见 。 - - - - 分析函数 @@ -73,29 +60,6 @@ - - 异步 I/O - AIO - - 异步 I/O - - - - 异步 I/OAIO)描述的是以 - 非阻塞方式(异步地)执行 I/O,这与同步 - I/O 形成对比;后者会在整个 - I/O 持续期间阻塞。 - - - 使用 AIO 时,启动一次 I/O 操作 - 与等待其结果是分离的,这允许并发发起多个 I/O 操作, - 也允许在 I/O 的同时并发执行 - CPU 密集型操作。这种更高并发性的代价是复杂性增加。 - - - - - 原子 @@ -174,7 +138,6 @@ WAL 归档器WAL 接收进程 (但不包括 WAL 发送进程)、 - WAL 汇总器 以及 WAL 写入器 @@ -250,51 +213,6 @@ - - 引导超级用户 - - - 在一个 数据库集簇 中 - 被初始化的第一个 用户。 - - - 该用户拥有每个数据库中的所有系统目录表。所有已授予权限最终都源自该角色。 - 由于这些原因,此角色不能被删除。 - - - 该角色也充当普通的 - 数据库超级用户, - 并且它的超级用户状态不能被移除。 - - - - - - 缓冲区访问策略 - - - 某些操作会访问大量 - 。 - 缓冲区访问策略有助于防止这些操作从 - 共享缓冲区中逐出过多页面。 - - - 缓冲区访问策略会建立对有限数量 - 共享缓冲区的引用, - 并循环重用它们。当操作需要一个新页面时,会从策略环中的缓冲区里选择一个 - 牺牲缓冲区,这可能要求刷出该页的脏数据,也可能还要把尚未刷新的 - WAL 刷写到持久存储。 - - - 缓冲区访问策略用于多种操作,例如对大表的顺序扫描、 - VACUUMCOPY、 - CREATE TABLE AS SELECTALTER TABLE、 - CREATE DATABASECREATE INDEX - 和 CLUSTER。 - - - - 类型转换 @@ -382,7 +300,7 @@ 客户端(进程) - 任何进程,可能是远程的,通过连接到某个 + 任何进程,可能是远程的,通过连接到某个 实例来建立 会话, 以与一个数据库交互。 @@ -390,22 +308,6 @@ - - 集簇所有者 - - - 拥有数据目录, - 且 postgres 进程在其身份下运行的操作系统用户。 - 在创建新的 - 数据库集簇之前, - 必须先存在这个用户。 - - - 在存在 root 用户的操作系统上,不允许该用户成为集簇所有者。 - - - - @@ -529,12 +431,6 @@ 集簇一词有时也用来指实例。 (不要把这个术语与 SQL 命令 CLUSTER 混淆。) - - 另见 集簇所有者, - 即集簇的操作系统所有者,以及 - 引导超级用户, - 即集簇的 PostgreSQL 所有者。 - @@ -543,19 +439,6 @@ - - 数据库超级用户 - - - 具有 超级用户状态的角色 - (见 )。 - - - 通常简称为 超级用户。 - - - - 数据目录 @@ -830,7 +713,7 @@ 一台通过网络与其他计算机通信的计算机。这个术语有时被用作 服务器的同义词。 - 它也用来指客户端进程运行所在的计算机。 + 它也用来指客户端进程运行所在的计算机。 @@ -850,41 +733,6 @@ - - 增量备份 - - - 一种特殊的 基础备份, - 对于某些文件,它可能只包含自前一次备份以来被修改过的页面, - 而不是每个文件的完整内容。和基础备份一样,它由 - 工具生成。 - - - 恢复增量备份时要使用 pg_combinebackup 工具, - 它会把增量备份与基础备份合并。随后,恢复过程可以利用 - WAL 把 - 数据库集簇 - 带到一致状态。 - - - 更多信息见 。 - - - - - - 输入/输出 - I/O - - - 输入/输出(I/O)描述程序与外围设备之间的通信。 - 在数据库系统语境中,I/O 通常但不限于 - 指与存储设备或网络的交互。 - - - - - 插入 @@ -914,7 +762,7 @@ 实例处理 DBMS 的所有关键特性: 对文件和共享内存的读写访问、保证 ACID 属性、 - 与客户端进程的连接、 + 与客户端进程连接、 权限验证、崩溃恢复、复制等。 @@ -1009,14 +857,7 @@ - - 逻辑复制集簇 - - - 一组发布者实例和订阅者实例,其中发布者实例把变更复制到订阅者实例。 - - - + 日志记录 @@ -1027,28 +868,6 @@ - - 日志序列号 - LSN - - - 在 WAL 中的字节偏移量, - 会随着每条新的 - WAL 记录 - 单调递增。 - - - 更多信息见 pg_lsn - 和 。 - - - - - - LSN - - - 主库(Master) @@ -1164,7 +983,7 @@ - 当它用于指代查询中的 + 当它用于指代查询中的 窗口函数时, 分区是一种用户定义的准则,用来标识 查询结果集中哪些相邻的 @@ -1341,19 +1160,6 @@ - - 重启点 - - - 在副本服务器上执行的 - 检查点的一种变体。 - - - 更多信息见 。 - - - - 结果集 @@ -1642,17 +1448,6 @@ - - 超级用户 - - - 在本文档中,它是 - 数据库超级用户 - 的同义词。 - - - - 系统目录 @@ -2042,19 +1837,7 @@ - - WAL 汇总器 - - - 一种 辅助进程, - 用于为增量备份 - 汇总 WAL 数据。 - - - 更多信息见 WAL 汇总相关配置说明。 - - - + WAL 写入器 diff --git a/zh/15/hash.sgml b/zh/15/hash.sgml index 078e8dd8..81f5f878 100644 --- a/zh/15/hash.sgml +++ b/zh/15/hash.sgml @@ -1,72 +1,72 @@ -哈希索引 +Hash 索引 索引 - 哈希 + Hash - + 概述 PostgreSQL - 提供了持久化的磁盘哈希索引实现,并且完全支持崩溃恢复。任何数据类型都可以使用哈希索引,包括那些没有明确定义线性顺序的数据类型。哈希索引只存储被索引数据的哈希值,因此对被索引数据列的大小没有限制。 + 提供了持久化的磁盘 hash 索引实现,并且完全支持崩溃恢复。任何数据类型都可以使用 hash 索引,包括那些没有明确定义线性顺序的数据类型。Hash 索引只存储被索引数据的 hash 值,因此对被索引数据列的大小没有限制。 - 哈希索引仅支持单列索引,也不支持唯一性检查。 + Hash 索引仅支持单列索引,也不支持唯一性检查。 - 哈希索引仅支持=操作符,因此指定范围操作的 WHERE 子句无法利用哈希索引。 + Hash 索引仅支持=操作符,因此指定范围操作的 WHERE 子句无法利用 hash 索引。 - 每个哈希索引元组只存储 4 字节的哈希值,而不存储实际的列值。因此,在为 UUID、URL 等较长的数据项建立索引时,哈希索引可能比 B-树小得多。由于没有列值,所有哈希索引扫描也都是有损的。哈希索引可以参与位图索引扫描和反向扫描。 + 每个 hash 索引元组只存储 4 字节的 hash 值,而不存储实际的列值。因此,在为 UUID、URL 等较长的数据项建立索引时,hash 索引可能比 B-树小得多。由于没有列值,所有 hash 索引扫描也都是有损的。Hash 索引可以参与位图索引扫描和反向扫描。 - 哈希索引最适合于在较大表上执行等值扫描、且以 SELECT 和 UPDATE 为主的工作负载。在 B-树索引中,搜索必须沿树向下直到找到叶页。在拥有数百万行的表中,这种向下遍历会增加访问数据的时间。在哈希索引中,与叶页对应的页称为桶页。相比之下,哈希索引允许直接访问桶页,因此可能减少大表中的索引访问时间。这种“逻辑 I/O”的减少,在索引/数据大于 shared_buffers/RAM 时会更加明显。 + Hash 索引最适合于在较大表上执行等值扫描、且以 SELECT 和 UPDATE 为主的工作负载。在 B-树索引中,搜索必须沿树向下直到找到叶页。在拥有数百万行的表中,这种向下遍历会增加访问数据的时间。在 hash 索引中,与叶页对应的页称为桶页。相比之下,hash 索引允许直接访问桶页,因此可能减少大表中的索引访问时间。这种“逻辑 I/O”的减少,在索引/数据大于 shared_buffers/RAM 时会更加明显。 - 哈希索引在设计上能够应对哈希值分布不均的情况。如果哈希值分布均匀,那么直接访问桶页的效果很好。当插入导致桶页填满时,额外的溢出页就会链接到该特定桶页上,从而在局部扩展用于存放匹配该哈希值的索引元组的空间。查询期间扫描某个哈希桶时,需要遍历其全部溢出页。因此,对于某些数据,不平衡的哈希索引在所需块访问次数方面实际上可能比 B-树更差。 + Hash 索引在设计上能够应对 hash 值分布不均的情况。如果 hash 值分布均匀,那么直接访问桶页的效果很好。当插入导致桶页填满时,额外的溢出页就会链接到该特定桶页上,从而在局部扩展用于存放匹配该 hash 值的索引元组的空间。查询期间扫描某个 hash 桶时,需要遍历其全部溢出页。因此,对于某些数据,不平衡的 hash 索引在所需块访问次数方面实际上可能比 B-树更差。 - 由于会出现这些溢出情况,可以说哈希索引最适合用于唯一值、近乎唯一值,或者每个哈希桶中行数较少的数据。 + 由于会出现这些溢出情况,可以说 hash 索引最适合用于唯一值、近乎唯一值,或者每个 hash 桶中行数较少的数据。 避免问题的一种可能办法,是使用部分索引条件把高度非唯一的值排除在索引之外,但这在很多情况下可能并不适用。 - 与 B-树一样,哈希索引也会执行简单的索引元组删除。这是一种延迟维护操作,用于删除那些已知可以安全删除的索引元组(即其项标识符的 LP_DEAD 位已经被设置的那些元组)。如果插入操作发现页上没有可用空间,我们会尝试通过移除死索引元组来避免创建新的溢出页。如果该页当时已被钉住,就无法执行移除。死索引指针也会在 VACUUM 期间被删除。 + 与 B-树一样,hash 索引也会执行简单的索引元组删除。这是一种延迟维护操作,用于删除那些已知可以安全删除的索引元组(即其项标识符的 LP_DEAD 位已经被设置的那些元组)。如果插入操作发现页上没有可用空间,我们会尝试通过移除死索引元组来避免创建新的溢出页。如果该页当时已被钉住,就无法执行移除。死索引指针也会在 VACUUM 期间被删除。 - 如果可能,VACUUM 还会尝试将索引元组压缩到尽可能少的溢出页上,以最小化溢出链。 + 如果可能,VACUUM 还会尝试将索引元组集中存放在尽可能少的溢出页上,以最小化溢出链。 如果某个溢出页变为空页,该溢出页就可以被回收并在其他桶中重用,不过我们从不将它们返还给操作系统。 - 目前除了使用 REINDEX 重建哈希索引之外,还没有缩小哈希索引的方法。 + 目前除了使用 REINDEX 重建 hash 索引之外,还没有缩小 hash 索引的方法。 同样也没有减少桶数量的方法。 - 随着被索引行数的增长,哈希索引可能会扩展桶页数量。哈希键到桶号的映射经过选择,使得索引能够增量扩展。当需要向索引中添加一个新桶时,恰好只需要“拆分”一个现有桶,并根据更新后的键到桶号映射,将其中一部分元组转移到新桶。 + 随着被索引行数的增长,Hash 索引可能会扩展桶页数量。hash 键到桶号的映射经过选择,使得索引能够增量扩展。当需要向索引中添加一个新桶时,恰好只需要“拆分”一个现有桶,并根据更新后的键到桶号映射,将其中一部分元组转移到新桶。 - 这种扩展是在前台进行的,因此可能会增加用户插入操作的执行时间。因此,哈希索引可能不适合行数快速增长的表。 + 这种扩展是在前台进行的,因此可能会增加用户插入操作的执行时间。因此,hash 索引可能不适合行数快速增长的表。 - + - + 实现 - 哈希索引中有四种页:元页(第零页),其中包含静态分配的控制信息;主桶页;溢出页;以及位图页,后者用于跟踪已被释放且可供重用的溢出页。在寻址时,位图页被视为溢出页的一个子集。 + hash 索引中有四种页:元页(第零页),其中包含静态分配的控制信息;主桶页;溢出页;以及位图页,后者用于跟踪已被释放且可供重用的溢出页。在寻址时,位图页被视为溢出页的一个子集。 @@ -74,17 +74,17 @@ - 主桶页和溢出页是独立分配的,因为任何一个给定索引相对于其桶数,可能需要更多或更少的溢出页。哈希代码使用了一组颇有意思的寻址规则,以支持可变数量的溢出页,同时又不必在主桶页创建后再移动它们。 + 主桶页和溢出页是独立分配的,因为任何一个给定索引相对于其桶数,可能需要更多或更少的溢出页。hash 实现代码使用了一组颇有意思的寻址规则,以支持可变数量的溢出页,同时又不必在主桶页创建后再移动它们。 - 被索引表中的每一行,都由哈希索引中的单个索引元组表示。哈希索引元组存储在桶页中,如果存在溢出页,也会存储在溢出页中。为了加快搜索速度,我们将任一索引页中的索引项按哈希码排序,从而可以在索引页内使用二分查找。但请注意,并不假定同一桶中不同索引页之间的哈希码具有任何相对顺序。 + 被索引表中的每一行,都由 hash 索引中的单个索引元组表示。Hash 索引元组存储在桶页中,如果存在溢出页,也会存储在溢出页中。为了加快搜索速度,我们将任一索引页中的索引项按 hash 码排序,从而可以在索引页内使用二分查找。但请注意,并不假定同一桶中不同索引页之间的 hash 码具有任何相对顺序。 - 用于扩展哈希索引的桶拆分算法过于复杂,这里不再展开说明;但在src/backend/access/hash/README中有更详细的描述。该拆分算法具备崩溃安全性,如果未能成功完成,可以重新启动。 + 用于扩展 hash 索引的桶拆分算法过于复杂,这里不再展开说明;但在src/backend/access/hash/README中有更详细的描述。该拆分算法具备崩溃安全性,如果未能成功完成,可以重新启动。 - + diff --git a/zh/15/high-availability.sgml b/zh/15/high-availability.sgml index a2610b38..d6b1a1ab 100644 --- a/zh/15/high-availability.sgml +++ b/zh/15/high-availability.sgml @@ -19,7 +19,7 @@ - 某些方案通过只允许一台服务器修改数据来处理同步。能够修改数据的服务器称为读/写、主库(master)主库(primary)服务器。跟踪主库变更的服务器称为备库。只能在被提升为主库之后才能连接的备库称为温备,而能够接受连接并提供只读查询的备库称为热备。 + 某些方案通过只允许一台服务器修改数据来处理同步。能够修改数据的服务器称为读/写、主库(master)主库(primary)服务器。跟踪主库变更的服务器称为备库(standby)备库(secondary)。只能在被提升为主库之后才能连接的备库称为温备,而能够接受连接并提供只读查询的备库称为热备 @@ -102,7 +102,7 @@ protocol to make nodes agree on a serializable transactional order. - 基于触发器的主库-备库复制 + 基于触发器的主备复制 @@ -238,7 +238,7 @@ protocol to make nodes agree on a serializable transactional order. - 主库无额外负载 + 主库无额外开销 @@ -354,7 +354,7 @@ protocol to make nodes agree on a serializable transactional order. - 连续归档可用于创建一种高可用性(HA)集簇配置,其中有一个或多个备库随时准备在主库失效时接管操作。这种能力通常称为温备日志传送。 + 持续归档可用于创建一种高可用性(HA)集簇配置,其中有一个或多个备库随时准备在主库失效时接管操作。这种能力通常称为温备日志传送 @@ -428,9 +428,7 @@ protocol to make nodes agree on a serializable transactional order. 启动时,备库首先通过调用 restore_command 恢复归档位置中所有可用的 WAL。一旦到达其中可用 WAL 的末尾,并且 restore_command 失败,它就会尝试恢复 pg_wal 目录中可用的任何 WAL。如果这也失败,并且已经配置了流复制,备库就会尝试连接到主库,并从归档或 pg_wal 中找到的最后一条有效记录开始流式接收 WAL。如果这仍然失败,或者没有配置流复制,或者连接后来断开,备库就会返回第 1 步,再次尝试从归档恢复文件。这样在归档、pg_wal 以及流复制之间循环重试,直到服务器停止或被提升。 - - 当执行 pg_ctl promote、调用 pg_promote() 或发现触发文件(promote_trigger_file)时,将退出备库模式,服务器切换到正常运行。在故障切换之前,会先恢复归档中或 pg_wal 中立即可用的所有 WAL,但不会尝试连接主库。 - + 运行 pg_ctl promote、调用 pg_promote(),或发现触发文件(promote_trigger_file)时,服务器会退出备库模式,切换到正常运行。在故障切换前,会恢复归档或 pg_wal 中能立即获取的所有 WAL,但不会尝试连接主库。 @@ -528,7 +526,7 @@ archive_cleanup_command = 'pg_archivecleanup /path/to/archive %r' 认证 - 正确设置复制访问权限非常重要,因为从 WAL 流中很容易提取出需要权限才能访问的信息,因此必须确保只有受信任的用户才能读取它。备库必须以具有 REPLICATION 权限的账户或超级用户身份向主库认证。建议专门创建一个具有 REPLICATIONLOGIN 权限的用户账户用于复制。虽然 REPLICATION 权限的权限很高,但它并不允许用户修改主系统上的任何数据,而 SUPERUSER 权限则允许。 + 正确设置复制访问权限非常重要,因为从 WAL 流中很容易提取出需要权限才能访问的信息,因此必须确保只有受信任的用户才能读取它。备库必须以具有 REPLICATION 权限的账户或超级用户身份向主库认证。建议专门创建一个具有 REPLICATIONLOGIN 权限的用户账户用于复制。虽然 REPLICATION 权限很高,但它并不允许用户修改主系统上的任何数据,而 SUPERUSER 权限则允许。 @@ -539,7 +537,7 @@ archive_cleanup_command = 'pg_archivecleanup /path/to/archive %r' # as a replication standby if the user's password is correctly supplied. # # TYPE DATABASE USER ADDRESS METHOD -host replication foo 192.168.1.100/32 scram-sha-256 +host replication foo 192.168.1.100/32 md5 @@ -559,7 +557,7 @@ primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass' 流复制的一个重要健康指标,是主库上已经生成但尚未在备库上应用的 WAL 记录量。你可以通过比较主库上的当前 WAL 写入位置和备库收到的最后一个 WAL 位置来计算这种滞后。这些位置分别可以用主库上的 pg_current_wal_lsn 和备库上的 pg_last_wal_receive_lsn 取得(详见 )。备库上的最后一个 WAL 接收位置也会显示在 WAL 接收进程的进程状态中,即通过 ps 命令显示的状态(详见 )。 - 你可以通过 pg_stat_replication 视图取得 WAL 发送进程列表。pg_current_wal_lsn 与该视图的 sent_lsn 字段之间存在较大差异,可能表示主库负载很重;而 sent_lsn 与备库上的 pg_last_wal_receive_lsn 之间存在较大差异,则可能表示网络延迟,或者备库负载很重。 + 你可以通过 pg_stat_replication 视图取得 WAL 发送进程列表。pg_current_wal_lsn 与该视图的 sent_lsn 字段之间存在较大差异,可能表示主库负载很重;而 sent_lsn 与备库上的 pg_last_wal_receive_lsn 之间存在差异,则可能表示网络延迟,或者备库负载很重。 在热备上,WAL 接收进程的状态可以通过 @@ -575,22 +573,10 @@ primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass' 流复制 - 复制槽提供了一种自动化方法,以确保主库在所有备库都收到 WAL 段之前不会删除它们,并且即使备库处于断开状态,主库也不会删除可能导致恢复冲突的行。 - - - 如果不使用复制槽,也可以通过阻止旧的 WAL 段被移除,或者通过把这些段保存到归档中。这些方法的一个缺点是,它们通常会保留多于实际所需数量的 WAL 段,而复制槽只会保留已知确实需要的段数。 - - - 类似地, - 和 虽然能防止相关的行被清理,但前者在备库未连接的那段时间内不能提供保护,而后者通常需要设置一个较高的值才能提供足够的保护。复制槽克服了这些缺点。 + 复制槽提供了一种自动化方法,以确保主库在所有备库都收到 WAL 段之前不会删除它们,并且即使备库处于断开状态,主库也不会删除那些一旦删除就可能导致恢复冲突的行。 - - - - 注意,复制槽可能会导致服务器保留过多的 WAL 段,以至于占满分配给pg_wal的空间。可以使用来限制复制槽保留的 WAL 文件大小。 - - - + 除了使用复制槽,也可以通过 防止旧 WAL 段被删除,或者使用 将这些段保存在归档中。不过,这些方法通常会保留多于实际所需的 WAL 段,而复制槽只保留已知必需的段数。另一方面,复制槽保留的 WAL 段也可能过多,填满分配给 pg_wal 的空间; 可以限制复制槽保留的 WAL 文件大小。 + 类似地, 可以保护相关行,避免它们被清理删除,但前者在备库未连接期间无法提供保护,后者则通常需要设为较大的值才能提供充分保护。复制槽克服了这些缺点。 查询和管理复制槽 @@ -605,7 +591,7 @@ primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass' 复制槽可以通过流复制协议(见)或者 SQL 函数(见)创建和删除。 - + 配置示例 你可以像下面这样创建一个复制槽: @@ -686,7 +672,7 @@ primary_slot_name = 'node_a_slot' - 只读事务和事务回滚不需要等待备库的回应。子事务提交也不需要等待备库响应,只有顶层提交才需要等待。数据装载或索引构建等长时间运行的动作,不会一直等到最终提交消息。所有两阶段提交操作都需要等待提交,包括 prepare 和 commit。 + 只读事务和事务回滚不需要等待备库的回应。子事务提交也不需要等待备库响应,只有顶层提交才需要等待。数据装载或索引构建等长时间运行的动作,直到最终提交时才会等待。所有两阶段提交操作都需要等待提交,包括准备和提交两个阶段。 @@ -701,7 +687,7 @@ primary_slot_name = 'node_a_slot' - 当提交记录已经在主库上写入磁盘之后,WAL 记录就会被发送到备库。每当新的一批 WAL 数据被写入磁盘时,备库就会发送回复消息,除非备库上的wal_receiver_status_interval被设置为零。如果synchronous_commit被设置为remote_apply,那么备库会在提交记录被重放时发送回复消息,从而使该事务变得可见。如果根据主库上的synchronous_standby_names设置,该备库被选为同步备库,那么它发出的回复会与其他同步备库的回复一起,用于决定何时释放那些正在等待确认提交记录已被收到的事务。这些参数允许管理员指定哪些备库应作为同步备库。注意,同步复制的配置主要在主库上进行。被命名的备库必须直接连接到主库;主库并不知道使用级联复制的下游备库。 + 当提交记录已经在主库上写入磁盘之后,WAL 记录就会被发送到备库。每当新的一批 WAL 数据被写入磁盘时,备库就会发送回复消息,除非备库上的wal_receiver_status_interval被设置为零。如果synchronous_commit被设置为remote_apply,那么备库会在提交记录被重放、该事务变得可见时发送回复消息。如果根据主库上的synchronous_standby_names设置,该备库被选为同步备库,那么它发出的回复会与其他同步备库的回复一起,用于决定何时释放那些正在等待确认提交记录已被收到的事务。这些参数允许管理员指定哪些备库应作为同步备库。注意,同步复制的配置主要在主库上进行。被命名的备库必须直接连接到主库;主库并不知道使用级联复制的下游备库。 @@ -713,7 +699,7 @@ primary_slot_name = 'node_a_slot' - 如果请求快速关闭,用户将停止等待。不过,与使用异步复制时一样,在所有尚未解决的 WAL 记录传输到当前已连接的备库之前,服务器不会完全关闭。 + 如果请求快速关闭,用户将停止等待。不过,与使用异步复制时一样,在所有尚未传送的 WAL 记录传输到当前已连接的备库之前,服务器不会完全关闭。 @@ -735,14 +721,14 @@ synchronous_standby_names = 'FIRST 2 (s1, s2, s3)' 在这个例子中,如果四台备库s1s2s3s4都在运行,则s1s2会被选为同步备库,因为它们的名字在备库名称列表中出现得更早。s3是潜在的同步备库,当s1s2中的任意一台失效时,它就会接替其角色。由于s4的名称不在列表中,因此它是异步备库。 - ANY方法指定基于法定人数的同步复制,使事务提交等待,直到它们的 WAL 记录被复制到列表中所要求数量的同步备库中的至少这么多台。 + ANY方法指定基于法定人数的同步复制,使事务提交等待,直到它们的 WAL 记录被复制到列表中至少所要求数量的同步备库。 基于法定人数的多同步备库的synchronous_standby_names示例如下: synchronous_standby_names = 'ANY 2 (s1, s2, s3)' - 在这个例子中,如果四台备库s1s2s3s4都在运行,事务提交将等待来自s1s2s3中的任意两台备库的回复。由于s4的名字不在列表中,因此它是异步备库。 + 在这个例子中,如果四台备库s1s2s3s4都在运行,事务提交将等待来自s1s2s3中的至少任意两台备库的回复。由于s4的名字不在列表中,因此它是异步备库。 备库的同步状态可以通过pg_stat_replication视图查看。 @@ -765,7 +751,7 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' - 通过在应用级别(在主库上)指定同步复制选项,我们可以只对最重要的变更提供同步复制,而不会拖慢整体工作负载。应用级别选项是让高性能应用获得同步复制收益的一种重要而实用的工具。 + 通过在应用级别(在主库上)指定同步复制选项,我们可以只对最重要的变更提供同步复制,而不会拖慢大部分工作负载。应用级别选项是让高性能应用获得同步复制收益的一种重要而实用的工具。 @@ -798,7 +784,7 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' - 如果主库在提交正等待确认时重启,这些等待中的事务会在主库恢复后被标记为已完全提交。无法确定在主库崩溃时,所有备库是否已经收到全部尚未处理的 WAL 数据。因此,某些事务可能不会在备库上显示为已提交,即使它们在主库上显示为已提交。我们所提供的保证是:只有在确认 WAL 数据已经被所有同步备库安全接收之后,应用才会收到事务成功提交的显式确认。 + 如果主库在提交正等待确认时重启,这些等待中的事务会在主库恢复后被标记为已完全提交。无法确定在主库崩溃时,所有备库是否已经收到全部待传送的 WAL 数据。因此,某些事务可能不会在备库上显示为已提交,即使它们在主库上显示为已提交。我们所提供的保证是:只有在确认 WAL 数据已经被所有同步备库安全接收之后,应用才会收到事务成功提交的显式确认。 @@ -809,9 +795,7 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' 如果主库与剩余的备库隔离开了,你应当故障切换到那些剩余备库中最佳的候选者。 - - 如果你需要在事务正在等待时重新创建一台备库,请确保pg_backup_start()pg_backup_stop()是在一个把synchronous_commit设置为off的会话中运行的,否则这些请求将永远等待备库出现。 - + 如果需要在事务等待期间重新创建备库,请确保在 synchronous_commit = off 的会话中运行 pg_backup_start() 和 pg_backup_stop() 命令,否则这些请求会一直等待备库出现。 @@ -832,47 +816,41 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' 如果archive_mode被设置为on,那么归档器在恢复期间或备库模式下不会启用。如果备库被提升,它会在提升后开始归档,但不会归档任何不是由它自己生成的 WAL 或时间线历史文件。要在归档中获得完整的一系列 WAL 文件,就必须确保所有 WAL 在到达备库之前已经被归档。对于基于文件的日志传送,这天然成立,因为备库只能恢复归档中找到的文件;但在启用流复制时则不是这样。当服务器不处于恢复模式时,onalways模式之间没有区别。 - + - - 故障切换 + + 故障切换 - + 如果主库失效,备库就应该开始执行故障切换过程。 - + 如果备库失效,则不需要发生故障切换。如果备库能够重新启动,即使是在稍后某个时间点,恢复过程也可以立即重新开始,从而利用可重启恢复的优势。如果备库无法重新启动,则应创建一个全新的备库实例。 - + 如果主库失效,而备库成为新的主库,那么旧主库之后如果重新启动,你必须有一种机制通知它,它已经不再是主库。这有时被称为STONITH(Shoot The Other Node In The Head),它对于避免两个系统都认为自己是主库的情况至关重要,因为那种情况会导致混乱,并最终造成数据丢失。 - + 许多故障切换系统只使用两个系统,即主库和备库,并通过某种心跳机制连接它们,以持续验证两者之间的连通性以及主库的可用性。也可以使用第三个系统(称为见证服务器)来防止某些不恰当的故障切换,但除非设置得足够谨慎并经过严格测试,否则额外增加的复杂性可能并不值得。 - + PostgreSQL并不提供用于识别主库故障并通知备库的系统软件。现在已经存在许多这样的工具,并且它们通常能很好地与成功故障切换所需的操作系统设施整合在一起,例如 IP 地址迁移。 - - 一旦故障切换到备库,系统中就只剩下一台服务器在运行。这被称为退化状态。原来的备库现在成为主库,而原来的主库已经停机,并且可能持续停机。要恢复到正常运行状态,就必须重新创建一台备库:要么在原主库恢复后在其上重建,要么在第三台可能是全新的服务器上重建。在大型集簇上,可以使用工具来加快这一过程。一旦完成,就可以认为主库和备库已经交换了角色。有些人会选择使用第三台服务器,在新的备库重建完成之前为新的主库提供备份,但显然这会让系统配置和操作流程更加复杂。 + + 一旦故障切换到备库,系统中就只剩下一台服务器在运行。这被称为退化状态。原来的备库现在成为主库,而原来的主库已经停机,并且可能持续停机。要恢复到正常运行状态,就必须重新创建一台备库:要么在原主库恢复后在其上重建,要么在第三台可能是全新的服务器上重建。在大型集簇上,可以使用工具来加快这一过程。一旦完成,就可以认为主库和备库已经交换了角色。有些人会选择使用第三台服务器,在新的备库重建完成之前为新的主库提供后备支持,但显然这会让系统配置和操作流程更加复杂。 - + 因此,从主库切换到备库可以很快,但重新准备故障切换集簇仍然需要时间。定期在主库与备库之间进行切换是有益的,因为它允许每个系统定期停机维护。这也相当于对故障切换机制进行测试,以确保真正需要它时它能够正常工作。建议编写书面的管理操作规程。 - - 如果你选择了逻辑复制槽同步(见),那么在切换到备库之前,建议检查备库上已同步的逻辑槽是否已经为故障切换做好准备。这可以通过执行中描述的步骤来完成。 - - - - 要触发日志传送备库的故障切换,请运行pg_ctl promote或调用pg_promote()。如果你设置的是仅用于从主库卸载只读查询的报表服务器,而不是用于高可用目的,那么就不需要执行提升。 - - + 要触发日志传送备库的故障切换,可以运行 pg_ctl promote、调用 pg_promote(),或按照 promote_trigger_file 指定的文件名和路径创建触发文件。如果计划通过运行 pg_ctl promote 或调用 pg_promote() 进行故障切换,就不需要设置 promote_trigger_file。如果所配置的报表服务器只是用来分担主库的只读查询,而不用于高可用,则不需要提升它。 + 热备 @@ -893,7 +871,7 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' 用户概览 - 当备库上的参数被设置为真时,一旦恢复把系统带到一致状态并为热备做好准备,它就会开始接受连接。所有这类连接都严格是只读的,甚至不能写入临时表。 + 当备库上的参数被设置为真时,一旦恢复把系统带到一致状态,它就会开始接受连接。所有这类连接都严格是只读的,甚至不能写入临时表。 @@ -921,7 +899,7 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' - 事务管理命令: + 事务管理命令: @@ -935,7 +913,7 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' - EXCEPTION块或其他内部子事务 + EXCEPTION块和其他内部子事务 @@ -975,7 +953,7 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' 数据操纵语言(DML):INSERTUPDATEDELETEMERGECOPY FROM、 - TRUNCATE。请注意,恢复期间不存在任何允许执行触发器的动作。这个限制甚至适用于临时表,因为不分配事务 ID 就无法读取或写入表行,而这在热备环境中目前是不可能的。 + TRUNCATE。请注意,恢复期间不存在任何允许执行触发器的动作。这个限制甚至适用于临时表,因为不分配事务 ID 就无法读取或写入表行,而目前热备环境中无法分配事务 ID。 @@ -1010,13 +988,13 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' - BEGIN READ WRITE, + BEGIN READ WRITESTART TRANSACTION READ WRITE - SET TRANSACTION READ WRITE, + SET TRANSACTION READ WRITESET SESSION CHARACTERISTICS AS TRANSACTION READ WRITE @@ -1032,7 +1010,7 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' 两阶段提交命令:PREPARE TRANSACTIONCOMMIT PREPAREDROLLBACK PREPARED, - 因为即使是只读事务,在 prepare 阶段(两阶段提交的第一阶段)也需要写入 WAL。 + 因为即使是只读事务,在准备阶段(两阶段提交的第一阶段)也需要写入 WAL。 @@ -1118,25 +1096,20 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' - 一旦max_standby_archive_delaymax_standby_streaming_delay指定的延迟被超越,冲突查询将被取消。这通常仅导致一个取消错误,尽管在重放一个DROP DATABASE的情况下整个冲突会话都将被中断。另外,如果冲突发生在一个被空闲事务持有的锁上,该冲突会话会被中断(这种行为可能在未来被改变)。 + 一旦max_standby_archive_delaymax_standby_streaming_delay指定的延迟被超越,冲突查询将被取消。这通常仅导致一个取消错误,尽管在重放一个DROP DATABASE的情况下整个冲突会话都将被终止。另外,如果冲突发生在一个被空闲事务持有的锁上,该冲突会话会被终止(这种行为可能在未来被改变)。 - - 被取消的查询可能会立即被重试(当然是在开始一个新的事务后)。因为查询取消依赖于 WAL 记录被重放的本质,如果一个被取消的查询被再次执行,它可能会很好地成功完成。 - + 被取消的查询可以立即重试(当然,要先开始一个新事务)。由于查询取消取决于正在重放的 WAL 记录的性质,被取消的查询再次执行时完全可能成功。 - 记住延迟参数是从 WAL 数据被备库收到后流逝的时间。因此,留给备库上任何一个查询的宽限期从不会超过延迟参数,并且如果备库已经由于等待之前的查询完成而落后或者因为过重的更新负载而无法跟上主库,宽限期可能会更少。 + 请记住,延迟参数要与备库收到 WAL 数据之后经过的时间进行比较。因此,留给备库上任何一个查询的宽限期从不会超过延迟参数,并且如果备库已经由于等待之前的查询完成而落后或者因为过重的更新负载而无法跟上主库,宽限期可能会更少。 - 备库查询与 WAL 重放发生冲突的最常见原因是过早清理。正常情况下,当没有事务需要看到旧行版本时,PostgreSQL允许清理这些旧行版本,以保证按照 MVCC 规则得到正确的数据可见性。不过,这条规则只能应用于在主库上执行的事务。因此,主库上的清理有可能移除某个备库事务仍然可见的行版本。 + 备库查询与 WAL 重放发生冲突的最常见原因是过早清理。正常情况下,当不再有事务需要看到旧行版本来保证符合 MVCC 规则的数据可见性时,PostgreSQL允许清理这些旧行版本。不过,这条规则只能应用于在主库上执行的事务。因此,主库上的清理有可能移除某个备库事务仍然可见的行版本。 - - 行版本清理并不是与备库查询发生冲突的唯一潜在原因。所有仅索引扫描(包括在备库上运行的那些)都必须使用一个MVCC快照,它与可见性映射一致。因此,每当VACUUM在可见性映射中把某个页面标记为全可见,而该页面中包含一行或多行对所有备库查询都不可见的数据时,就必须产生冲突。所以,即使针对一个没有更新或删除任何需要清理行的表执行VACUUM,也可能导致冲突。 - + 有经验的用户应注意,行版本清理和行版本冻结都有可能与备库查询冲突。手动运行 VACUUM FREEZE 很可能导致冲突,即使表中没有更新过或删除过的行也是如此。 用户应当清楚,主库上经常并且大量更新的表,会很快导致备库上的长时间运行查询被取消。在这种情况下,把max_standby_archive_delaymax_standby_streaming_delay设置为有限值,可以视作类似于设置statement_timeout。 @@ -1146,6 +1119,8 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' 如果备库查询被取消的次数多得令人无法接受,也存在补救办法。第一种选择是设置hot_standby_feedback参数,它会阻止VACUUM移除最近死亡的行,因此不会发生清理冲突。如果这样做,你应当注意这会延迟主库上死行的清理,从而可能导致不希望出现的表膨胀。不过,清理情况不会比直接在主库上运行这些备库查询更糟,而且你仍然可以获得把执行卸载到备库上的好处。如果备库经常连接又断开,你可能还需要进行一些调整,以应对无法提供hot_standby_feedback反馈的那段时间。例如,可以考虑增大max_standby_archive_delay,使查询在断开期间不会因为 WAL 归档文件中的冲突而被迅速取消。你也应考虑增大max_standby_streaming_delay,以避免重新连接后由于新到达的流式 WAL 条目而被快速取消。 + 另一种选择是增大主库上的 ,使死行不会像通常那样很快被清理。这样,无需将 max_standby_streaming_delay 设得很大,就能让备库查询在被取消前有更多执行时间。不过,这种方法难以保证具体的执行时间窗口,因为 vacuum_defer_cleanup_age 是按主库上执行的事务数来衡量的。 + 查询取消的数量及其原因可以通过备库上的pg_stat_database_conflicts系统视图查看。pg_stat_database系统视图也包含汇总信息。 @@ -1170,7 +1145,7 @@ LOG: consistent recovery state reached LOG: database system is ready to accept read-only connections - 一致性信息在主库上每个检查点时记录一次。在主库的wal_level未设置为replicalogical期间所写入的 WAL 被读取时,无法启用热备。即使已经达到一致状态,如果同时满足下列两个条件,恢复快照也可能还没有准备好用于热备,从而推迟接受只读连接。要启用热备,就需要在主库上结束那些包含超过 64 个子事务的长生命周期写事务。 + 一致性信息在主库上每个检查点时记录一次。在主库的wal_level未设置为replicalogical期间所写入的 WAL 被读取时,无法启用热备。如果同时存在以下两种情况,达到一致状态也可能会被推迟: @@ -1238,7 +1213,7 @@ HINT: You can then restart the server after making the necessary configuration - 主库上写出的事务状态 "hint bits" 不会被 WAL 记录,因此备库上的数据很可能会再次写出这些提示位。这样一来,即使所有用户都是只读的,备库仍然会执行磁盘写操作;不过数据值本身并不会发生变化。用户仍然会写出大型排序临时文件,并重新生成 relcache 信息文件,因此在热备模式下,数据库没有任何部分是真正只读的。还要注意,使用dblink模块写入远程数据库,以及借助 PL 函数执行其他数据库外部操作,依然是可能的,即使该事务在本地是只读的。 + 主库上写出的事务状态“提示位” 不会被 WAL 记录,因此备库上的数据很可能会再次写出这些提示位。这样一来,即使所有用户都是只读的,备库仍然会执行磁盘写操作;不过数据值本身并不会发生变化。用户仍然会写出大型排序临时文件,并重新生成 relcache 信息文件,因此在热备模式下,数据库没有任何部分是真正只读的。还要注意,使用dblink模块写入远程数据库,以及借助 PL 函数执行其他数据库外部操作,依然是可能的,即使该事务在本地是只读的。 @@ -1247,7 +1222,7 @@ HINT: You can then restart the server after making the necessary configuration - 数据定义语言:例如 CREATE INDEX + 数据定义语言(DDL):例如 CREATE INDEX @@ -1322,7 +1297,7 @@ HINT: You can then restart the server after making the necessary configuration - 累积统计系统在恢复期间是活动的。所有扫描、读取、块访问、索引使用等,都会在备库上照常记录。不过,WAL 重放不会增加关系和数据库级别的特定计数器。也就是说,重放不会增加pg_stat_all_tables中的列(例如n_tup_ins),启动进程执行的读写也不会被记录到pg_statio_视图中,相关的pg_stat_database列也不会增加。 + 累积统计系统在恢复期间是活动的。所有扫描、读取、块访问、索引使用等,都会在备库上照常记录。不过,WAL 重放不会增加关系和数据库级别的特定计数器。也就是说,重放不会增加pg_stat_all_tables中的列(例如n_tup_ins),启动进程执行的读写也不会被记录到pg_statio视图中,相关的pg_stat_database列也不会增加。 @@ -1341,13 +1316,9 @@ HINT: You can then restart the server after making the necessary configuration 多个参数已经在中提到过。 - - 在主库上,可以使用参数。如果设置在主库上,则不会生效。 - + 在主库上,可以使用 参数。 在主库上设置时没有效果。 - - 在备库上,可以使用这几个参数。 - + 在备库上,可以使用 参数。只要服务器仍处于备库模式, 就没有效果,不过备库成为主库后,它就会起作用。 diff --git a/zh/15/history.sgml b/zh/15/history.sgml index 0fc63086..0834f9b4 100644 --- a/zh/15/history.sgml +++ b/zh/15/history.sgml @@ -168,8 +168,7 @@ - 关于此后每个 PostgreSQL 发布版本发生了哪些变化的详情,可在 - https://www.postgresql.org/docs/release/ 查阅。 + 自那以后 PostgreSQL 发生了哪些变化,可见 diff --git a/zh/15/images/fixup-svg.xsl b/zh/15/images/fixup-svg.xsl index d6c46b36..cf7169bb 100644 --- a/zh/15/images/fixup-svg.xsl +++ b/zh/15/images/fixup-svg.xsl @@ -32,6 +32,11 @@ Fix stroke="transparent" attribute, which is invalid SVG. none + + + 'Alibaba PuHuiTi 3.0',serif + + diff --git a/zh/15/images/gin.gv b/zh/15/images/gin.gv index 097e9102..b8e26542 100644 --- a/zh/15/images/gin.gv +++ b/zh/15/images/gin.gv @@ -1,11 +1,12 @@ digraph "gin" { layout=dot; - node [label="", shape=box, style=filled, fillcolor=gray, width=1.4]; + fontname="Alibaba PuHuiTi 3.0"; + node [fontname="Alibaba PuHuiTi 3.0", label="", shape=box, style=filled, fillcolor=gray, width=1.4]; - m1 [label="meta page"]; + m1 [label="元页"]; subgraph cluster01 { - label="entry tree"; + label="键项树"; subgraph egroup1 { rank=same; e1; @@ -27,13 +28,13 @@ digraph "gin" { e4 -> e8; e4 -> e9; - e6 [fillcolor=green, label="posting list"]; - e8 [fillcolor=green, label="posting list"]; - e9 [fillcolor=green, label="posting list"]; + e6 [fillcolor=green, label="倒排列表"]; + e8 [fillcolor=green, label="倒排列表"]; + e9 [fillcolor=green, label="倒排列表"]; } subgraph cluster02 { - label="posting tree"; + label="倒排树"; subgraph pgroup1 { rank=same; p1; @@ -45,22 +46,22 @@ digraph "gin" { p1 -> p2; p1 -> p3; - p2 [fillcolor=green, label="heap ptr"]; - p3 [fillcolor=green, label="heap ptr"]; + p2 [fillcolor=green, label="堆指针"]; + p3 [fillcolor=green, label="堆指针"]; } subgraph cluster03 { - label="posting tree"; + label="倒排树"; subgraph pgroup3 { rank=same; p4; } - p4 [fillcolor=green, label="heap ptr"]; + p4 [fillcolor=green, label="堆指针"]; } subgraph cluster04 { - label="posting tree"; + label="倒排树"; subgraph pgroup4 { rank=same; p5; @@ -72,12 +73,12 @@ digraph "gin" { p5 -> p6; p5 -> p7; - p6 [fillcolor=green, label="heap ptr"]; - p7 [fillcolor=green, label="heap ptr"]; + p6 [fillcolor=green, label="堆指针"]; + p7 [fillcolor=green, label="堆指针"]; } subgraph cluster05 { - label="pending list"; + label="待处理列表"; node [style=filled, fillcolor=red]; n1 -> n2 -> n3 -> n4; } diff --git a/zh/15/images/gin.svg b/zh/15/images/gin.svg index 04fe85ba..79cf14a9 100644 --- a/zh/15/images/gin.svg +++ b/zh/15/images/gin.svg @@ -9,33 +9,33 @@ cluster01 -entry tree +键项树 cluster02 -posting tree +倒排树 cluster03 -posting tree +倒排树 cluster04 -posting tree +倒排树 cluster05 -pending list +待处理列表 m1 -meta page +元页 @@ -113,7 +113,7 @@ e6 -posting list +倒排列表 @@ -142,7 +142,7 @@ e8 -posting list +倒排列表 @@ -154,7 +154,7 @@ e9 -posting list +倒排列表 @@ -195,7 +195,7 @@ p4 -heap ptr +堆指针 @@ -224,7 +224,7 @@ p2 -heap ptr +堆指针 @@ -236,7 +236,7 @@ p3 -heap ptr +堆指针 @@ -254,7 +254,7 @@ p6 -heap ptr +堆指针 @@ -266,7 +266,7 @@ p7 -heap ptr +堆指针 diff --git a/zh/15/indexam.sgml b/zh/15/indexam.sgml index 56d22822..a5e23ac6 100644 --- a/zh/15/indexam.sgml +++ b/zh/15/indexam.sgml @@ -21,7 +21,7 @@ - 索引本质上是从一些数据键值到行版本(元组)在索引父表中的元组标识符TID)的映射。一个 TID 由块号以及该块中的项号组成(见 元组标识符(TIDs)的映射。一个 TID 由块号以及该块中的项号组成(见 )。这些信息足以从表中取出某个特定的行版本。索引并不直接知道在 MVCC 之下同一逻辑行可能会存在多个现存版本;对索引来说,每个元组都是一个独立对象,需要它自己的索引条目。因此,对一行的更新总会为该行创建全新的索引条目,即使键值并未改变也是如此。(HOT 元组是这一说法的例外;但索引同样不直接处理它们。)当死元组自身被回收时(通过清理),它们对应的索引条目也会被回收。 @@ -44,86 +44,72 @@ typedef struct IndexAmRoutine NodeTag type; /* - * Total number of strategies (operators) by which we can traverse/search - * this AM. Zero if AM does not have a fixed set of strategy assignments. + * 可用于遍历或搜索此 AM 的策略(操作符)总数。 + * 如果 AM 没有固定的一组策略分配,则为零。 */ uint16 amstrategies; - /* total number of support functions that this AM uses */ + /* 此 AM 使用的支持函数总数 */ uint16 amsupport; - /* opclass options support function number or 0 */ + /* 操作符类选项支持函数编号,或为 0 */ uint16 amoptsprocnum; - /* does AM support ORDER BY indexed column's value? */ + /* AM 是否支持按被索引列的值进行 ORDER BY? */ bool amcanorder; - /* does AM support ORDER BY result of an operator on indexed column? */ + /* AM 是否支持按被索引列上操作符的结果进行 ORDER BY? */ bool amcanorderbyop; - /* does AM support hashing using API consistent with the hash AM? */ - bool amcanhash; - /* do operators within an opfamily have consistent equality semantics? */ - bool amconsistentequality; - /* do operators within an opfamily have consistent ordering semantics? */ - bool amconsistentordering; - /* does AM support backward scanning? */ + /* AM 是否支持反向扫描? */ bool amcanbackward; - /* does AM support UNIQUE indexes? */ + /* AM 是否支持 UNIQUE 索引? */ bool amcanunique; - /* does AM support multi-column indexes? */ + /* AM 是否支持多列索引? */ bool amcanmulticol; - /* does AM require scans to have a constraint on the first index column? */ + /* AM 是否要求扫描必须约束第一个索引列? */ bool amoptionalkey; - /* does AM handle ScalarArrayOpExpr quals? */ + /* AM 是否处理 ScalarArrayOpExpr 限定条件? */ bool amsearcharray; - /* does AM handle IS NULL/IS NOT NULL quals? */ + /* AM 是否处理 IS NULL/IS NOT NULL 限定条件? */ bool amsearchnulls; - /* can index storage data type differ from column data type? */ + /* 索引存储数据类型是否可以不同于列数据类型? */ bool amstorage; - /* can an index of this type be clustered on? */ + /* 是否可以按此类型的索引进行聚簇? */ bool amclusterable; - /* does AM handle predicate locks? */ + /* AM 是否处理谓词锁? */ bool ampredlocks; - /* does AM support parallel scan? */ + /* AM 是否支持并行扫描? */ bool amcanparallel; - /* does AM support parallel build? */ - bool amcanbuildparallel; - /* does AM support columns included with clause INCLUDE? */ + /* AM 是否支持由 INCLUDE 子句包含的列? */ bool amcaninclude; - /* does AM use maintenance_work_mem? */ + /* AM 是否使用 maintenance_work_mem? */ bool amusemaintenanceworkmem; - /* OR of parallel vacuum flags */ + /* 并行清理标志的 OR 组合 */ uint8 amparallelvacuumoptions; - /* type of data stored in index, or InvalidOid if variable */ + /* 索引中存储的数据类型;如果可变,则为 InvalidOid */ Oid amkeytype; - /* interface functions */ + /* 接口函数 */ ambuild_function ambuild; ambuildempty_function ambuildempty; aminsert_function aminsert; - aminsertcleanup_function aminsertcleanup; /* can be NULL */ ambulkdelete_function ambulkdelete; amvacuumcleanup_function amvacuumcleanup; - amcanreturn_function amcanreturn; /* can be NULL */ + amcanreturn_function amcanreturn; /* 可以为 NULL */ amcostestimate_function amcostestimate; - amgettreeheight_function amgettreeheight; /* can be NULL */ amoptions_function amoptions; - amproperty_function amproperty; /* can be NULL */ - ambuildphasename_function ambuildphasename; /* can be NULL */ + amproperty_function amproperty; /* 可以为 NULL */ + ambuildphasename_function ambuildphasename; /* 可以为 NULL */ amvalidate_function amvalidate; - amadjustmembers_function amadjustmembers; /* can be NULL */ + amadjustmembers_function amadjustmembers; /* 可以为 NULL */ ambeginscan_function ambeginscan; amrescan_function amrescan; - amgettuple_function amgettuple; /* can be NULL */ - amgetbitmap_function amgetbitmap; /* can be NULL */ + amgettuple_function amgettuple; /* 可以为 NULL */ + amgetbitmap_function amgetbitmap; /* 可以为 NULL */ amendscan_function amendscan; - ammarkpos_function ammarkpos; /* can be NULL */ - amrestrpos_function amrestrpos; /* can be NULL */ + ammarkpos_function ammarkpos; /* 可以为 NULL */ + amrestrpos_function amrestrpos; /* 可以为 NULL */ - /* interface functions to support parallel index scans */ - amestimateparallelscan_function amestimateparallelscan; /* can be NULL */ - aminitparallelscan_function aminitparallelscan; /* can be NULL */ - amparallelrescan_function amparallelrescan; /* can be NULL */ - - /* interface functions to support planning */ - amtranslate_strategy_function amtranslatestrategy; /* can be NULL */ - amtranslate_cmptype_function amtranslatecmptype; /* can be NULL */ + /* 支持并行索引扫描的接口函数 */ + amestimateparallelscan_function amestimateparallelscan; /* 可以为 NULL */ + aminitparallelscan_function aminitparallelscan; /* 可以为 NULL */ + amparallelrescan_function amparallelrescan; /* 可以为 NULL */ } IndexAmRoutine; @@ -137,7 +123,7 @@ typedef struct IndexAmRoutine - IndexAmRoutine 的某些标志字段还有一些不那么直观的含义。amcanunique 的要求见 amcanmulticol 标志表明该访问方法支持多键列索引,而 amoptionalkey 表明它允许在第一索引列上没有给出可索引限制子句时进行扫描。当 amcanmulticol 为假时,amoptionalkey 实质上表示该访问方法是否支持没有任何限制子句的全索引扫描。支持多个索引列的访问方法必须支持在第一列之后省略任意一个或全部列限制条件的扫描;但它们可以要求第一索引列必须出现某种限制条件,这通过把 amoptionalkey 设为假来表示。索引 AM 可能把 amoptionalkey 设为假的一个原因,是它不索引 NULL 值。由于大多数可索引操作符都是严格的(strict),因此对 NULL 输入不可能返回 true,所以乍看之下不存储 NULL 值的索引条目似乎很有吸引力:无论如何,这些条目似乎都不可能被索引扫描返回。然而,当某个索引扫描对给定索引列没有限制子句时,这个论证就不成立了。实践中这意味着,若索引把 amoptionalkey 设为真,就必须索引 NULL 值,因为规划器可能决定在完全没有扫描键的情况下使用这种索引。与此相关的另一个限制是,支持多个索引列的索引访问方法必须支持对第一列之后各列中的 NULL 值建立索引,因为规划器会假定该索引可用于不限制这些列的查询。例如,考虑一个在 (a,b) 上的索引以及查询 WHERE a = 4。系统会假定该索引可用于扫描满足 a = 4 的行;如果索引省略了 b 为 NULL 的行,这个假定就是错误的。不过,省略第一索引列为 NULL 的行是可以的。对 NULL 值建立索引的索引访问方法还可以设置 amsearchnulls,表示它支持把 IS NULLIS NOT NULL 子句作为搜索条件。 + IndexAmRoutine 的某些标志字段还有一些不那么直观的含义。amcanunique 的要求见 amcanmulticol 标志表明该访问方法支持多键列索引,而 amoptionalkey 表明它允许在第一索引列上没有给出可索引限制子句时进行扫描。当 amcanmulticol 为假时,amoptionalkey 实质上表示该访问方法是否支持没有任何限制子句的全索引扫描。支持多个索引列的访问方法必须支持在第一列之后省略任意一个或全部列限制条件的扫描;但它们可以要求第一索引列必须出现某种限制条件,这通过把 amoptionalkey 设为假来表示。索引 AM 可能把 amoptionalkey 设为假的一个原因,是它不索引 NULL 值。由于大多数可索引操作符都是严格的(strict),因此对 NULL 输入不可能返回 true,所以乍看之下不存储 NULL 值的索引条目似乎很有吸引力:无论如何,这些条目似乎都不可能被索引扫描返回。然而,当某个索引扫描对给定索引列没有限制子句时,这个论证就不成立了。实践中这意味着,若索引把 amoptionalkey 设为真,就必须索引 NULL 值,因为规划器可能决定在完全没有扫描键的情况下使用这种索引。与此相关的另一个限制是,支持多个索引列的索引访问方法必须支持对第一列之后各列中的 NULL 值建立索引,因为规划器会假定该索引可用于不限制这些列的查询。例如,考虑一个在 (a,b) 上的索引以及查询 WHERE a = 4。系统会假定该索引可用于扫描满足 a = 4 的行;如果索引省略了 b 为 NULL 的行,这个假定就是错误的。不过,省略第一索引列为 NULL 的行是可以的。对 NULL 值建立索引的索引访问方法还可以设置 amsearchnulls,表示它支持把 IS NULLIS NOT NULL 子句作为搜索条件。 @@ -159,9 +145,7 @@ IndexBuildResult * ambuild (Relation heapRelation, Relation indexRelation, IndexInfo *indexInfo); - - 构建一个新索引。索引关系已经在物理上创建,但还是空的。它必须填入访问方法所需的任何固定数据,以及表中所有现有元组对应的条目。通常,ambuild 函数会调用 table_index_build_scan() 来扫描表中已有的元组,并计算需要插入索引的键值。该函数必须返回一个通过 palloc 分配的结构体,其中包含有关新索引的统计信息。amcanbuildparallel 标志指示该访问方法是否支持并行索引构建。设为 true 时,系统会尝试为构建分配并行工作进程。只支持非并行索引构建的访问方法应把该标志保留为 false。 - +构建新索引。索引关系已在物理上创建,但内容为空。必须填入访问方法所需的固定数据,以及表中所有已有元组对应的条目。通常,ambuild函数会调用table_index_build_scan()扫描表中现有的元组,并计算需要插入索引的键。函数必须返回一个通过 palloc 分配的结构体,其中包含新索引的统计信息。 @@ -199,16 +183,7 @@ aminsert (Relation indexRelation, - 如果索引 AM 希望在一条 SQL 语句中的连续索引插入之间缓存数据,它可以在 indexInfo->ii_Context 中分配空间,并把数据指针存入 indexInfo->ii_AmCache(该指针初始为 NULL)。如果在索引插入后需要释放内存之外的资源,可以提供 aminsertcleanup,它会在内存释放之前被调用。 - - - - -void -aminsertcleanup (Relation indexRelation, - IndexInfo *indexInfo); - - 清理由 indexInfo->ii_AmCache 在连续插入之间维护的状态。如果这些数据需要额外的清理步骤(例如释放已钉住的缓冲区),而仅释放内存还不够,那么这个函数就很有用。 + 如果索引 AM 希望在一条 SQL 语句中的连续索引插入之间缓存数据,它可以在 indexInfo->ii_Context 中分配空间,并把数据指针存入 indexInfo->ii_AmCache(该指针初始为 NULL)。 @@ -219,7 +194,7 @@ ambulkdelete (IndexVacuumInfo *info, IndexBulkDeleteCallback callback, void *callback_state); - 从索引中删除元组。这是一个批量删除操作,通常应通过扫描整个索引并检查每个条目是否应被删除来实现。必须调用传入的 callback 函数,其调用形式为 callback(TID, callback_state) returns bool,以确定由其引用 TID 标识的某个索引条目是否应删除。该函数必须返回 NULL,或者返回一个通过 palloc 分配的结构体,其中包含此次删除操作影响的统计信息。如果不需要向 amvacuumcleanup 传递信息,返回 NULL 也是可以的。 + 从索引中删除元组。这是一个批量删除操作,旨在通过扫描整个索引并检查每个条目是否应被删除来实现。必须调用传入的 callback 函数,其调用形式为 callback(TID, callback_state) returns bool,以确定由其引用 TID 标识的某个索引条目是否应删除。该函数必须返回 NULL,或者返回一个通过 palloc 分配的结构体,其中包含此次删除操作影响的统计信息。如果不需要向 amvacuumcleanup 传递信息,返回 NULL 也是可以的。 @@ -244,8 +219,7 @@ amvacuumcleanup (IndexVacuumInfo *info, bool amcanreturn (Relation indexRelation, int attno); - 检查索引是否能够在给定列上支持 仅索引扫描,做法是返回该列原始的被索引值。属性编号从 1 开始,也就是说第一列的 attno 为 1。若支持则返回真,否则返回假。如果支持包含列,这个函数应始终对包含列返回真,因为不能取回的包含列几乎没有意义。如果访问方法根本不支持仅索引扫描,那么它的 IndexAmRoutine 结构体中的 amcanreturn 字段可以设为 NULL。 + 检查索引能否通过返回给定列原始的被索引值,在该列上支持 仅索引扫描。属性编号从 1 开始,也就是说第一列的 attno 为 1。若支持则返回真,否则返回假。如果支持包含列,这个函数应始终对包含列返回真,因为不能取回的包含列几乎没有意义。如果访问方法根本不支持仅索引扫描,那么它的 IndexAmRoutine 结构体中的 amcanreturn 字段可以设为 NULL。 @@ -260,15 +234,7 @@ amcostestimate (PlannerInfo *root, double *indexCorrelation, double *indexPages); - 估计一次索引扫描的开销。该函数将在后面的 中详细讨论。 - - - - -int -amgettreeheight (Relation rel); - - 计算树形索引的高度。这一信息会通过 path->indexinfo->tree_height 提供给 amcostestimate 函数,可用于支持开销估计。其结果不会在其他地方使用,因此这个函数实际上也可以用来计算索引上任何一种适合装入整数、且开销估计函数可能想知道的数据。如果计算代价较高,把结果缓存到 RelationData.rd_amcache 中可能会有用。 + 估计一次索引扫描的代价。该函数将在后面的 中详细讨论。 @@ -277,7 +243,7 @@ bytea * amoptions (ArrayType *reloptions, bool validate); - 解析并验证索引的 reloptions 数组。只有当该索引存在非空的 reloptions 数组时才会调用此函数。reloptions 是一个 text 数组,其中的条目形如 name=value。该函数应构造一个 bytea 值,并将其复制到索引 relcache 条目的 rd_options 字段中。这个 bytea 值中的数据内容由访问方法自行定义;大多数标准访问方法使用结构体 StdRdOptions。当 validate 为真时,若存在未识别选项或无效取值,函数应报告合适的错误消息;当 validate 为假时,无效条目应被静默忽略。(当装载已存储在 pg_catalog 中的选项时,validate 为假;此时只有在访问方法改变了选项规则时才可能发现无效条目,而忽略过时条目是合适的。)如果希望采用默认行为,返回 NULL 也是可以的。 + 解析并验证索引的 reloptions 数组。只有当该索引存在非 NULL 的 reloptions 数组时才会调用此函数。reloptions 是一个 text 数组,其中的条目形如 name=value。该函数应构造一个 bytea 值,并将其复制到索引 relcache 条目的 rd_options 字段中。这个 bytea 值中的数据内容由访问方法自行定义;大多数标准访问方法使用结构体 StdRdOptions。当 validate 为真时,若存在未识别选项或无效取值,函数应报告合适的错误消息;当 validate 为假时,无效条目应被静默忽略。(当装载已存储在 pg_catalog 中的选项时,validate 为假;此时只有在访问方法改变了选项规则时才可能发现无效条目,而忽略过时条目是合适的。)如果希望采用默认行为,返回 NULL 也是可以的。 @@ -291,7 +257,7 @@ amproperty (Oid index_oid, int attno, - 支持排序操作符的访问方法应当实现 AMPROP_DISTANCE_ORDERABLE 属性测试,因为核心代码不知道如何完成该测试,只会返回 NULL。若实现成本低于打开索引并调用 amcanreturn(这正是核心代码的默认行为),那么实现 AMPROP_RETURNABLE 测试也可能是有利的。对于其他所有标准属性,默认行为应当已经足够。 + 支持排序操作符的访问方法应当实现 AMPROP_DISTANCE_ORDERABLE 属性测试,因为核心代码不知道如何完成该测试,只会返回 NULL。若完成该测试的代价低于打开索引并调用 amcanreturn(这正是核心代码的默认行为),那么实现 AMPROP_RETURNABLE 测试也可能是有利的。对于其他所有标准属性,默认行为应当已经足够。 @@ -353,11 +319,11 @@ bool amgettuple (IndexScanDesc scan, ScanDirection direction); - 在给定扫描中取出下一个元组,并按给定方向移动(在索引中向前或向后)。若成功取得元组则返回真;若不再有匹配元组则返回假。在返回真时,元组的 TID 会存入 scan 结构体中。请注意,成功仅表示索引中存在一个匹配扫描键的条目,并不表示该元组一定仍然存在于堆中,或者一定能通过调用者的快照测试。成功时,amgettuple 还必须把 scan->xs_recheck 设为真或假。假表示可以确定该索引条目匹配扫描键;真表示这一点并不确定,因此在取到堆元组后必须根据扫描键所代表的条件重新检查它。这一机制支持有损索引操作符。请注意,重检只会扩展到扫描条件;部分索引谓词(如果有)永远不会由 amgettuple 的调用者重新检查。 + 在给定扫描中取出下一个元组,并按给定方向移动(在索引中向前或向后)。若成功取得元组则返回真;若不再有匹配元组则返回假。在返回真时,元组的 TID 会存入 scan 结构体中。请注意,成功仅表示索引中存在一个匹配扫描键的条目,并不表示该元组一定仍然存在于堆中,或者一定能通过调用者的快照测试。成功时,amgettuple 还必须把 scan->xs_recheck 设为真或假。假表示可以确定该索引条目匹配扫描键;真表示这一点并不确定,因此在取到堆元组后必须根据扫描键所代表的条件重新检查它。这一机制支持有损索引操作符。请注意,重检只针对扫描条件;部分索引谓词(如果有)永远不会由 amgettuple 的调用者重新检查。 - 如果索引支持 仅索引扫描(即其任一列上 amcanreturn 返回真),那么成功时 AM 还必须检查 scan->xs_want_itup;若其为真,就必须返回该索引条目的原始被索引数据。对于 amcanreturn 返回假的列,可以把其值作为 NULL 返回。数据可以通过以下两种形式之一返回:一种是把 IndexTuple 指针存入 scan->xs_itup,其元组描述符为 scan->xs_itupdesc;另一种是把 HeapTuple 指针存入 scan->xs_hitup,其元组描述符为 scan->xs_hitupdesc。(当重建出的数据可能装不进 IndexTuple 时,应使用后一种格式。)无论采用哪种形式,指针所引用数据的管理责任都在访问方法一侧。对这份数据的有效性必须至少保持到该扫描下一次调用 amgettupleamrescanamendscan 为止。 + 如果索引支持 仅索引扫描(即其至少一列上 amcanreturn 返回真),那么成功时 AM 还必须检查 scan->xs_want_itup;若其为真,就必须返回该索引条目的原始被索引数据。对于 amcanreturn 返回假的列,可以把其值作为 NULL 返回。数据可以通过以下两种形式之一返回:一种是把 IndexTuple 指针存入 scan->xs_itup,其元组描述符为 scan->xs_itupdesc;另一种是把 HeapTuple 指针存入 scan->xs_hitup,其元组描述符为 scan->xs_hitupdesc。(当重建出的数据可能装不进 IndexTuple 时,应使用后一种格式。)无论采用哪种形式,指针所引用数据的管理责任都在访问方法一侧。这份数据必须至少保持有效,直到该扫描下一次调用 amgettupleamrescanamendscan @@ -370,7 +336,7 @@ int64 amgetbitmap (IndexScanDesc scan, TIDBitmap *tbm); - 取出给定扫描中的所有元组,并将其加入调用者提供的 TIDBitmap 中(也就是把这组元组 ID 与位图中已有的集合做 OR)。返回值是取得的元组数量(这可能只是近似计数,例如某些 AM 不会检测重复项)。在把元组 ID 插入位图时,amgetbitmap 可以指出某些具体的元组 ID 需要重新检查扫描条件。这类似于 amgettuplexs_recheck 输出参数。注意:在当前实现中,对这一特性的支持与位图自身的有损存储支持混在一起,因此调用者会对可重检元组同时重新检查扫描条件和部分索引谓词(如果有)。不过,这并不一定永远如此。amgetbitmapamgettuple 不能在同一次索引扫描中同时使用;使用 amgetbitmap 时还有其他限制,详见 。 + 取出给定扫描中的所有元组,并将其加入调用者提供的 TIDBitmap 中(也就是把这组元组 ID 与位图中已有的集合做 OR)。返回值是取得的元组数量(这可能只是近似计数,例如某些 AM 不会检测重复项)。在把元组 ID 插入位图时,amgetbitmap 可以指出某些具体的元组 ID 需要重新检查扫描条件。这类似于 amgettuplexs_recheck 输出参数。注意:在当前实现中,对这一特性的支持与位图自身的有损存储支持混在一起,因此调用者会对需要重检的元组同时重新检查扫描条件和部分索引谓词(如果有)。不过,这并不一定永远如此。amgetbitmapamgettuple 不能在同一次索引扫描中同时使用;使用 amgetbitmap 时还有其他限制,详见 @@ -382,7 +348,7 @@ amgetbitmap (IndexScanDesc scan, void amendscan (IndexScanDesc scan); - 结束一次扫描并释放资源。scan 结构体本身不应被释放,但访问方法内部获取的任何锁或 pin,以及由 ambeginscan 和其他扫描相关函数分配的其他内存,都必须被释放。 + 结束一次扫描并释放资源。scan 结构体本身不应被释放,但必须释放访问方法内部获取的所有锁、解除所有钉住状态,并释放由 ambeginscan 和其他扫描相关函数分配的其他内存。 @@ -416,15 +382,8 @@ amrestrpos (IndexScanDesc scan); Size -amestimateparallelscan (Relation indexRelation, - int nkeys, - int norderbys); - - 估计并返回执行并行扫描时该访问方法所需动态共享内存的字节数。(这个数字是额外需求,并不替代 ParallelIndexScanDescData 中 AM 无关数据所需的空间。) - - - - nkeysnorderbys 参数表示扫描中将使用的限定条件和排序操作符数量;同样的数值也会传给 amrescan。请注意,此时还没有提供扫描键的实际值。 +amestimateparallelscan (void); +估算并返回访问方法执行并行扫描所需的动态共享内存字节数。(此数值是额外需要的空间,不包括以下结构体中与访问方法无关的数据所需的空间:ParallelIndexScanDescData。) @@ -451,17 +410,6 @@ amparallelrescan (IndexScanDesc scan); 如果实现了此函数,当并行索引扫描必须重新开始时就会调用它。它应重置由 aminitparallelscan 建立的任何共享状态,以便扫描从头开始重新执行。 - - -CompareType -amtranslatestrategy (StrategyNumber strategy, Oid opfamily, Oid opcintype); - -StrategyNumber -amtranslatecmptype (CompareType cmptype, Oid opfamily, Oid opcintype); - - 如果实现了这些函数,规划器和执行器就会调用它们,在固定的 CompareType 值与访问方法所使用的特定策略编号之间进行转换。提供了与内置 btree 或 hash 访问方法相似功能的访问方法可以实现这些函数;通过实现这些转换,系统就能理解该访问方法操作的语义,并在多个地方把它们当作 btree 或 hash 索引的替代。如果该访问方法的功能与这些内置访问方法并不相似,就不需要实现这些函数。若不实现,访问方法会在某些规划器和执行器决策中被忽略,但除此之外仍然完全可用。 - - @@ -517,7 +465,7 @@ amtranslatecmptype (CompareType cmptype, Oid opfamily, Oid opcintype); - 除了使用 amgettuple 外,索引扫描也可以使用 amgetbitmap,在一次调用中取出所有元组。与 amgettuple 相比,这通常明显更高效,因为它可以避免访问方法内部的反复加锁和解锁。原则上,amgetbitmap 应具有与重复调用 amgettuple 相同的效果,但为了简化实现,我们施加了若干限制。首先,amgetbitmap 一次性返回全部元组,因此不支持标记或恢复扫描位置。其次,元组是通过一个位图返回的,没有特定顺序,这也是为什么 amgetbitmap 不带 direction 参数的原因。(这种扫描也永远不会提供排序操作符。)此外,使用 amgetbitmap 时也没有仅索引扫描的支持,因为没有办法返回索引元组的内容。最后,amgetbitmap 不保证对返回的元组做任何锁定,其影响见 。 + 除了使用 amgettuple 外,索引扫描也可以使用 amgetbitmap,在一次调用中取出所有元组。与 amgettuple 相比,这可能明显更高效,因为它可以避免访问方法内部的反复加锁和解锁。原则上,amgetbitmap 应具有与重复调用 amgettuple 相同的效果,但为了简化实现,我们施加了若干限制。首先,amgetbitmap 一次性返回全部元组,因此不支持标记或恢复扫描位置。其次,元组是通过一个位图返回的,没有特定顺序,这也是为什么 amgetbitmap 不带 direction 参数的原因。(这种扫描也永远不会提供排序操作符。)此外,使用 amgetbitmap 时也没有仅索引扫描的支持,因为没有办法返回索引元组的内容。最后,amgetbitmap 不保证对返回的元组做任何锁定,其影响见 @@ -534,7 +482,7 @@ amtranslatecmptype (CompareType cmptype, Oid opfamily, Oid opcintype); - 构建一种支持并发更新的索引类型,通常需要对所需行为进行大量而细致的分析。对于 B-树和哈希索引类型,可以阅读 src/backend/access/nbtree/READMEsrc/backend/access/hash/README 中涉及的设计决策。 + 构建一种支持并发更新的索引类型,通常需要对所需行为进行大量而细致的分析。对于 B-树和 hash 索引类型,可以阅读 src/backend/access/nbtree/READMEsrc/backend/access/hash/README 中涉及的设计决策。 @@ -553,12 +501,12 @@ amtranslatecmptype (CompareType cmptype, Oid opfamily, Oid opcintype); - 索引扫描必须在保存 amgettuple 最近一次返回条目的索引页面上维护一个 pin,而 ambulkdelete 不能从被其他后端钉住的页面中删除条目。下面会解释为什么需要这条规则。 + 索引扫描必须在保存 amgettuple 最近一次返回条目的索引页面上保持钉住状态,而 ambulkdelete 不能从被其他后端钉住的页面中删除条目。下面会解释为什么需要这条规则。 - 如果没有第三条规则,索引读取者就有可能在某个索引条目被 VACUUM 删除之前先看到它,然后在对应的堆条目已被 VACUUM 删除之后才到达那里。如果读取者到达时,该项号仍未被重新使用,就不会造成严重问题,因为空项槽位会被 heap_fetch() 忽略。但如果第三个后端已经把这个项槽位重新用作别的东西呢?在使用 MVCC 兼容快照时不会有问题,因为该槽位的新占用者一定太新,无法通过快照测试。然而,对于非 MVCC 兼容的快照(例如 SnapshotAny),就可能错误地接受并返回一行实际上并不匹配扫描键的数据。我们可以要求在所有情况下都对堆行重新检查扫描键,以防范这种情形,但那样代价太高。于是,我们改为把索引页面上的 pin 作为一种代理,表示读取者可能仍处于从索引条目前往匹配堆条目的飞行中。让 ambulkdelete 在这种 pin 上阻塞,能够保证 VACUUM 不会在读取者处理完之前删除对应的堆条目。这种方案运行时开销很小,只有在真正发生冲突的少数情况下才会增加阻塞开销。 + 如果没有第三条规则,索引读取者就有可能在某个索引条目被 VACUUM 删除之前先看到它,然后在对应的堆条目已被 VACUUM 删除之后才到达那里。如果读取者到达时,该项号仍未被重新使用,就不会造成严重问题,因为空项槽位会被 heap_fetch() 忽略。但如果第三个后端已经把这个项槽位重新用作别的东西呢?在使用 MVCC 兼容快照时不会有问题,因为该槽位的新占用者一定太新,无法通过快照测试。然而,对于非 MVCC 兼容的快照(例如 SnapshotAny),就可能错误地接受并返回一行实际上并不匹配扫描键的数据。我们可以要求在所有情况下都对堆行重新检查扫描键,以防范这种情形,但那样代价太高。于是,我们改为把索引页面的钉住状态作为一种代理,表示读取者从索引条目到匹配堆条目的访问过程可能仍在进行中。让 ambulkdelete 因这种钉住状态而阻塞,能够保证 VACUUM 不会在读取者处理完之前删除对应的堆条目。这种方案运行时开销很小,只有在真正发生冲突的少数情况下才会增加阻塞开销。 @@ -566,7 +514,7 @@ amtranslatecmptype (CompareType cmptype, Oid opfamily, Oid opcintype); - 在 amgetbitmap 索引扫描中,访问方法不会在任何返回的元组上保留索引 pin。因此,只有把这种扫描与 MVCC 兼容的快照一起使用才是安全的。 + 在 amgetbitmap 索引扫描中,访问方法不会为任何返回的元组保持索引页面的钉住状态。因此,只有把这种扫描与 MVCC 兼容的快照一起使用才是安全的。 @@ -605,7 +553,7 @@ amtranslatecmptype (CompareType cmptype, Oid opfamily, Oid opcintype); - 此外,在按照上述规则报告唯一性违背之前,访问方法必须立即重新检查正在插入那一行的存活性。如果它已经是提交后死亡的状态,就不应报告违背。(这种情况不会出现在插入由当前事务刚创建的行这一普通场景中,但在 CREATE UNIQUE INDEX CONCURRENTLY 期间却可能发生。) + 此外,就在按照上述规则报告唯一性违背之前,访问方法必须重新检查正在插入那一行的存活性。如果它已经是提交后死亡的状态,就不应报告违背。(这种情况不会出现在插入由当前事务刚创建的行这一普通场景中,但在 CREATE UNIQUE INDEX CONCURRENTLY 期间却可能发生。) @@ -613,7 +561,7 @@ amtranslatecmptype (CompareType cmptype, Oid opfamily, Oid opcintype); - 如果唯一约束是可延迟的,情况会更复杂:我们需要能够为新行插入一个索引条目,但把任何唯一性违背错误延迟到语句结束时甚至更晚才报告。为了避免对索引进行不必要的重复搜索,索引访问方法应在初始插入期间执行一次初步唯一性检查。如果这表明确实不存在冲突的存活元组,那么事情就结束了。否则,我们会安排在真正强制约束时再做一次重检。若在重检时,插入的元组与另外某个具有相同键值的元组都仍然存活,就必须报告错误。(注意,就此用途而言,存活实际上是指索引条目 HOT 链中的任一元组是存活的。)为实现这一点,传给 aminsert 函数的 checkUnique 参数会取以下值之一: + 如果唯一约束是可延迟的,情况会更复杂:我们需要能够为新行插入一个索引条目,但把任何唯一性违背错误延迟到语句结束时甚至更晚才报告。为了避免对索引进行不必要的重复搜索,索引访问方法应在初始插入期间执行一次初步唯一性检查。如果这表明确实不存在冲突的存活元组,那么事情就结束了。否则,我们会安排在真正强制约束时再做一次重检。若在重检时,插入的元组与另外某个具有相同键值的元组都仍然存活,就必须报告错误。(注意,就此用途而言,存活实际上是指索引条目 HOT 链中至少有一个元组是存活的。)为实现这一点,传给 aminsert 函数的 checkUnique 参数会取以下值之一: @@ -650,10 +598,10 @@ amtranslatecmptype (CompareType cmptype, Oid opfamily, Oid opcintype); - 索引开销估计函数 + 索引代价估算函数 - amcostestimate 函数会收到描述某种可能索引扫描方式的信息,其中包括已经确定可用于该索引的 WHERE 子句和 ORDER BY 子句列表。它必须返回访问该索引的开销估计,以及 WHERE 子句的选择率(也就是在索引扫描期间将从父表中检索出的行所占比例)。对于简单情况,开销估计器几乎所有工作都可以通过调用优化器中的标准例程来完成;之所以提供 amcostestimate 函数,是为了让索引访问方法能够提供与索引类型有关的专门知识,以便在可能时改进标准估计。 + amcostestimate 函数会收到描述某种可能索引扫描方式的信息,其中包括已经确定可用于该索引的 WHERE 子句和 ORDER BY 子句列表。它必须返回访问该索引的代价估算,以及 WHERE 子句选择率的估计值(也就是在索引扫描期间将从父表中检索出的行所占比例)。对于简单情况,代价估算器几乎所有工作都可以通过调用优化器中的标准例程来完成;之所以提供 amcostestimate 函数,是为了让索引访问方法能够提供与索引类型有关的专门知识,以便在可能时改进标准估计。 @@ -687,7 +635,7 @@ amcostestimate (PlannerInfo *root, path - 当前正在考虑的索引访问路径。除开销和选择率字段外,其余字段都有效。 + 当前正在考虑的索引访问路径。除代价和选择率字段外,其余字段都有效。 @@ -696,7 +644,7 @@ amcostestimate (PlannerInfo *root, loop_count - 在开销估计中应计入的索引扫描重复次数。当考虑在嵌套循环连接内部使用参数化扫描时,这个参数通常会大于 1。请注意,开销估计仍应只针对一次扫描;更大的 loop_count 只表示可以适当考虑多次扫描之间的一些缓存效应。 + 在代价估算中应计入的索引扫描重复次数。当考虑在嵌套循环连接内部使用参数化扫描时,这个参数通常会大于 1。请注意,代价估算仍应只针对一次扫描;更大的 loop_count 只表示可以适当考虑多次扫描之间的一些缓存效应。 @@ -711,7 +659,7 @@ amcostestimate (PlannerInfo *root, *indexStartupCost - 设为索引启动处理的开销。 + 设为索引启动处理的代价。 @@ -720,7 +668,7 @@ amcostestimate (PlannerInfo *root, *indexTotalCost - 设为索引处理的总开销。 + 设为索引处理的总代价。 @@ -755,19 +703,19 @@ amcostestimate (PlannerInfo *root, - 请注意,开销估计函数必须用 C 编写,而不能用 SQL 或任何可用的过程语言,因为它们必须访问规划器/优化器的内部数据结构。 + 请注意,代价估算函数必须用 C 编写,而不能用 SQL 或任何可用的过程语言,因为它们必须访问规划器/优化器的内部数据结构。 - 索引访问开销应使用 src/backend/optimizer/path/costsize.c 所采用的参数来计算:顺序磁盘块读取的开销为 seq_page_cost,非顺序读取的开销为 random_page_cost,处理一条索引行的开销通常应取为 cpu_index_tuple_cost。此外,在索引处理期间调用的任何比较操作符(特别是对 indexquals 本身的求值)都应计入适当倍数的 cpu_operator_cost。 + 索引访问代价应使用 src/backend/optimizer/path/costsize.c 所采用的参数来计算:顺序磁盘块读取的代价为 seq_page_cost,非顺序读取的代价为 random_page_cost,处理一条索引行的代价通常应取为 cpu_index_tuple_cost。此外,在索引处理期间调用的任何比较操作符(特别是对 indexquals 本身的求值)都应计入适当倍数的 cpu_operator_cost - 访问开销应包括与扫描索引本身有关的全部磁盘和 CPU 开销,但包括取出或处理由索引标识出的父表行的开销。 + 访问代价应包括与扫描索引本身有关的全部磁盘和 CPU 代价,但包括取出或处理由索引标识出的父表行的代价。 - 启动开销是整个扫描总开销中必须在开始取第一行之前先付出的那一部分。对大多数索引来说,这可以视为零;但启动开销较高的索引类型可能希望把它设为非零。 + 启动代价是整个扫描总代价中必须在开始取第一行之前先付出的那一部分。对大多数索引来说,这可以视为零;但启动代价较高的索引类型可能希望把它设为非零。 @@ -775,7 +723,7 @@ amcostestimate (PlannerInfo *root, - indexCorrelation 应设为索引顺序与表顺序之间的相关性(范围从 -1.0 到 1.0)。该值用于调整从父表取行开销的估计。 + indexCorrelation 应设为索引顺序与表顺序之间的相关性(范围从 -1.0 到 1.0)。该值用于调整从父表取行代价的估计。 @@ -787,9 +735,9 @@ amcostestimate (PlannerInfo *root, - 开销估计 + 代价估算 - 一个典型的开销估计器会按如下步骤进行: + 一个典型的代价估算器会按如下步骤进行: @@ -818,14 +766,14 @@ amcostestimate (PlannerInfo *root, - 计算索引访问开销。一个通用估计器可能会这样做: + 计算索引访问代价。一个通用估计器可能会这样做: /* - * Our generic assumption is that the index pages will be read - * sequentially, so they cost seq_page_cost each, not random_page_cost. - * Also, we charge for evaluation of the indexquals at each index row. - * All the costs are assumed to be paid incrementally during the scan. + * 通用假设是索引页面将按顺序读取, + * 因此每页代价为 seq_page_cost,而非 random_page_cost。 + * 此外,还要计入在每个索引行上对 indexquals 求值的代价。 + * 假定所有代价都在扫描过程中逐步付出。 */ cost_qual_eval(&index_qual_cost, path->indexquals, root); *indexStartupCost = index_qual_cost.startup; @@ -845,7 +793,7 @@ cost_qual_eval(&index_qual_cost, path->indexquals, root); - 开销估计器函数的示例可在 src/backend/utils/adt/selfuncs.c 中找到。 + 代价估算器函数的示例可在 src/backend/utils/adt/selfuncs.c 中找到。 diff --git a/zh/15/indices.sgml b/zh/15/indices.sgml index 45e27eef..d2578d63 100644 --- a/zh/15/indices.sgml +++ b/zh/15/indices.sgml @@ -31,7 +31,7 @@ SELECT content FROM test1 WHERE id = constant; - 大多数非小说类书籍也采用了类似的方法:读者经常查找的术语和概念会被收集到书末按字母顺序排列的索引中。感兴趣的读者可以相对快速地浏览索引并翻到相应页面,而不必通读整本书才能找到自己感兴趣的内容。正如作者需要预判读者可能查找哪些条目一样,数据库程序员也需要预见哪些索引会有用。 + 大多数非虚构类书籍也采用了类似的方法:读者经常查找的术语和概念会被收集到书末按字母顺序排列的索引中。感兴趣的读者可以相对快速地浏览索引并翻到相应页面,而不必通读整本书才能找到自己感兴趣的内容。正如作者需要预判读者可能查找哪些条目一样,数据库程序员也需要预见哪些索引会有用。 @@ -71,7 +71,7 @@ CREATE INDEX test1_id_index ON test1 (id); comparison-value operator indexed-column - 那么如果原始operator有一个可交换操作符,并且该操作符属于该索引的操作符类,就可以把它翻转成可索引的形式。 + 那么如果原始operator有一个交换子操作符,并且该操作符属于该索引的操作符类,就可以把它翻转成可索引的形式。 @@ -100,12 +100,12 @@ CREATE INDEX name ON table B-树 - index + 索引 B-树 B-树 - index + 索引 @@ -133,12 +133,12 @@ CREATE INDEX name ON table Hash - index + 索引 hash hash - index + 索引 @@ -154,12 +154,12 @@ CREATE INDEX name ON table GiST - index + 索引 GiST GiST - index + 索引 @@ -186,12 +186,12 @@ SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10; SP-GiST - index + 索引 SP-GiST SP-GiST - index + 索引 @@ -213,12 +213,12 @@ SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10; GIN - index + 索引 GIN GIN - index + 索引 @@ -240,12 +240,12 @@ SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10; BRIN - index + 索引 BRIN BRIN - index + 索引 @@ -265,8 +265,8 @@ SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10; 多列索引 - index - multicolumn + 索引 + 多列 @@ -292,28 +292,18 @@ CREATE INDEX test2_mm_idx ON test2 (major, minor); 当前,只有 B-树、GiST、GIN 和 BRIN 索引类型支持多键列索引。能否有多个键列,与索引中能否添加INCLUDE列无关。索引最多可以有 32 列,包括INCLUDE列。(这个限制在构建PostgreSQL时可以修改;参见文件pg_config_manual.h。) - - 多列 B-树索引可以用于涉及索引任意列子集的查询条件,但当对前导(最左)列存在约束时,索引效率最高。精确的规则是:对前导列的等值约束,再加上第一个没有等值约束列上的任意不等约束,总会被用来限制被扫描的索引范围。这些列右侧列上的约束会在索引中进行检查,因此总能减少访问表本体的次数,但不一定会减少必须扫描的索引范围。如果 B-树索引扫描能够有效应用跳过扫描优化,那么它在通过反复的索引搜索遍历索引时,会利用每一列约束。这可能减少需要读取的索引部分,即便一个或多个列(位于查询谓词中最低有效索引列之前)缺少常规的等值约束。跳过扫描的工作方式是内部生成一个动态的等值约束,使其匹配索引列中的每个可能值(不过这只适用于某个列缺少来自查询谓词的等值约束,且生成的约束能够与查询谓词中较后列的约束联合使用时)。 - - - - 例如,给定一个(x, y)上的索引和查询条件WHERE y = 7700,B-树索引扫描可能能够应用跳过扫描优化。这通常发生在查询规划器预计:针对每个可能的N反复执行WHERE x = N AND y = 7700搜索(或者针对索引中实际存储的每个x值),在当前表上可用索引的前提下,这是最快的方法。一般来说,只有当不同的x值很少,以致规划器预计扫描能跳过索引的大部分内容时,才会采用这种方法(因为大多数叶子页都不可能包含相关元组)。如果不同的x值很多,那么就必须扫描整个索引,因此在大多数情况下,规划器会更倾向于顺序扫描表而不是使用该索引。 - - - - 在至少具有一部分来自查询谓词的有用约束的 B-树扫描中,跳过扫描优化也可以被选择性地应用。例如,给定一个(a, b, c)上的索引和查询条件WHERE a = 5 AND b >= 42 AND c < 77,该索引可能必须从第一个a = 5 且b = 42 的条目扫描,一直到最后一个a = 5 的条目。c >= 77 的索引项永远不需要在表层面进行过滤,但是否值得在索引内部跳过它们,则未必。发生跳过时,扫描会启动一次新的索引搜索,把自身从当前a = 5 且b = N 分组的末尾重新定位(也就是索引中第一个a = 5 AND b = N AND c >= 77元组出现的位置),移动到下一个这类分组的起始位置(也就是索引中第一个a = 5 AND b = N + 1元组出现的位置)。 - + 多列 B-树索引可以用于涉及索引任意列子集的查询条件,但当对前导(最左)列存在约束时,索引效率最高。精确的规则是:对前导列的等值约束,再加上第一个没有等值约束的列上的任何不等约束,会被用来限制索引扫描的范围。这些列右侧列上的约束会在索引中进行检查,因此可以减少访问表本体的次数,但不会缩小必须扫描的索引范围。例如,给定一个 (a, b, c) 上的索引和查询条件 WHERE a = 5 AND b >= 42 AND c < 77,索引必须从第一个 a = 5 且 b = 42 的条目扫描到最后一个 a = 5 的条目。c >= 77 的索引项会被排除,但仍然必须扫描这些项。原则上,这个索引也可以用于只对 b 和/或 c 有约束、而对 a 没有约束的查询,但必须扫描整个索引,因此在大多数情况下,规划器会倾向于顺序扫描表,而不是使用该索引。 多列 GiST 索引可以用于涉及索引任意列子集的查询条件。附加列上的条件会限制索引返回的项,但决定索引需要扫描多少内容的,最重要的仍是第一列上的条件。如果第一列只有很少几个非重复值,即使其他列有很多非重复值,GiST 索引也会相对低效。 - 多列 GIN 索引可以用于涉及索引任意列子集的查询条件。与 B-树或 GiST 不同,无论查询条件使用的是哪一列索引列,GIN 的索引搜索效果都一样。 + 多列 GIN 索引可以用于涉及索引任意列子集的查询条件。与 B-树或 GiST 不同,无论查询条件使用的是哪些索引列,GIN 的索引搜索效果都一样。 - 多列 BRIN 索引可以用于涉及索引任意列子集的查询条件。和 GIN 一样、不同于 B-树或 GiST,无论查询条件使用的是哪一列索引列,索引搜索效果都一样。在单个表上使用多个 BRIN 索引,而不是使用一个多列 BRIN 索引的唯一理由,是需要不同的pages_per_range存储参数。 + 多列 BRIN 索引可以用于涉及索引任意列子集的查询条件。和 GIN 一样、不同于 B-树或 GiST,无论查询条件使用的是哪些索引列,索引搜索效果都一样。在单个表上使用多个 BRIN 索引,而不是使用一个多列 BRIN 索引的唯一理由,是需要不同的pages_per_range存储参数。 @@ -330,8 +320,8 @@ CREATE INDEX test2_mm_idx ON test2 (major, minor); 索引和<literal>ORDER BY</literal> - index - and ORDER BY + 索引 + ORDER BY @@ -339,7 +329,7 @@ CREATE INDEX test2_mm_idx ON test2 (major, minor); - 规划器在满足ORDER BY要求时,会考虑两种方案:扫描一个与该要求匹配的可用索引,或者按物理顺序扫描表再显式排序。对于需要扫描表中很大一部分内容的查询,显式排序通常会比使用索引更快,因为它遵循顺序访问模式,需要的磁盘 I/O 更少。只有在只需取出少量行时,索引才更有价值。一个重要的特例是ORDER BYLIMIT n组合使用:显式排序必须处理所有数据才能找出最前面的n行,而如果有一个与ORDER BY匹配的索引,就可以直接取回前n行,而完全不必扫描剩余数据。 + 规划器在满足ORDER BY要求时,会考虑两种方案:扫描一个与该要求匹配的可用索引,或者按物理顺序扫描表再显式排序。对于需要扫描表中很大一部分内容的查询,显式排序通常会比使用索引更快,因为它遵循顺序访问模式,需要的磁盘 I/O 更少。只需取出少量行时,索引更有价值。一个重要的特例是ORDER BYLIMIT n组合使用:显式排序必须处理所有数据才能找出最前面的n行,而如果有一个与ORDER BY匹配的索引,就可以直接取回前n行,而完全不必扫描剩余数据。 @@ -369,12 +359,12 @@ CREATE INDEX test3_desc_index ON test3 (id DESC NULLS LAST); 组合多个索引 - index - combining multiple indexes + 索引 + 组合多个索引 - bitmap scan + 位图扫描 @@ -391,7 +381,7 @@ CREATE INDEX test3_desc_index ON test3 (id DESC NULLS LAST); - 除了最简单的应用之外,通常会有多种可能有用的索引组合,数据库开发者必须权衡决定提供哪些索引。有时多列索引最好,但有时创建独立索引并依赖索引组合功能会更合适。例如,如果你的工作负载包含一组查询:有时只涉及列x,有时只涉及列y,有时同时涉及两列,那么你可以选择分别在xy上创建两个独立索引,并依赖索引组合来处理同时使用两列的查询。你也可以创建一个(x, y)上的多列索引。对于同时涉及两列的查询,这个索引通常会比索引组合更高效,但正如中所讨论的,它对于只涉及y的查询就没那么有用了。具体能有多大用处,取决于 B-树索引跳过扫描优化的效果;如果x的非重复值不超过几百个,跳过扫描会让针对特定y值的搜索仍然具有相当不错的效率。再加上一个(x, y)上的多列索引和一个单独的y索引,也可能工作得相当好。对于只涉及x的查询,多列索引也可以使用,但它会比单独的x索引更大,因此更慢。最后一种选择是同时创建这三个索引,但这大概只有在该表被搜索的频率远高于被更新的频率,并且三类查询都很常见时才合理。如果其中一种查询远没有另外两种常见,那么你大概只需创建最适合常见查询类型的两个索引即可。 + 除了最简单的应用之外,通常会有多种可能有用的索引组合,数据库开发者必须权衡决定提供哪些索引。有时多列索引最好,但有时创建独立索引并依赖索引组合功能会更合适。例如,如果你的工作负载包含一组查询:有时只涉及列x,有时只涉及列y,有时同时涉及两列,那么你可以选择分别在xy上创建两个独立索引,并依赖索引组合来处理同时使用两列的查询。你也可以创建一个(x, y)上的多列索引。对于同时涉及两列的查询,这个索引通常会比索引组合更高效,但正如中所讨论的,它对于只涉及y的查询几乎没有用处,因此不应只创建这一个索引。将这个多列索引与一个单独的y索引组合起来,能够取得相当好的效果。对于只涉及x的查询,多列索引也可以使用,但它会比单独的x索引更大,因此更慢。最后一种选择是同时创建这三个索引,但这大概只有在该表被搜索的频率远高于被更新的频率,并且三类查询都很常见时才合理。如果其中一种查询远没有另外两种常见,那么你大概只需创建最适合常见查询类型的两个索引即可。 @@ -401,8 +391,8 @@ CREATE INDEX test3_desc_index ON test3 (id DESC NULLS LAST); 唯一索引 - index - unique + 索引 + 唯一 @@ -433,8 +423,8 @@ CREATE UNIQUE INDEX name ON table表达式索引 - index - on expressions + 索引 + 基于表达式 @@ -481,8 +471,8 @@ CREATE INDEX people_names ON people ((first_name || ' ' || last_name)); 部分索引 - index - partial + 索引 + 部分 @@ -490,7 +480,7 @@ CREATE INDEX people_names ON people ((first_name || ' ' || last_name)); - 使用部分索引的一个主要原因是避免索引常见值。由于搜索常见值的查询(即占全部表行百分之几以上的值)反正也不会使用索引,因此完全没有必要把这些行保留在索引里。这会减小索引尺寸,从而加快那些确实会使用该索引的查询。它也会加快很多表更新操作,因为索引并不需要在所有情况下都更新。展示了这种思路的一种可能应用。 + 使用部分索引的一个主要原因是避免索引常见值。由于搜索常见值(即占全部表行百分之几以上的值)的查询反正也不会使用索引,因此完全没有必要把这些行保留在索引里。这会减小索引尺寸,从而加快那些确实会使用该索引的查询。它也会加快很多表更新操作,因为索引并不需要在所有情况下都更新。展示了这种思路的一种可能应用。 @@ -578,7 +568,7 @@ SELECT * FROM orders WHERE order_nr = 3501; - 也说明了:索引列和谓词中使用的列不必一致。PostgreSQL支持带任意谓词的部分索引,只要其中只涉及正在建立索引的那张表的列。不过要记住,谓词必须与那些希望从该索引受益的查询中使用的条件相匹配。更准确地说,只有当系统能够识别出查询的WHERE条件在数学上蕴含该索引的谓词时,部分索引才能用于该查询。PostgreSQL并没有一个复杂的定理证明器,来识别那些写法不同但数学上等价的表达式。(不仅构建这样一个通用定理证明器极其困难,而且它很可能也会慢到失去实际用途。)系统可以识别简单的不等式蕴含,例如x < 1蕴含x < 2;否则,谓词条件必须与查询WHERE条件的某一部分完全匹配,否则索引不会被识别为可用。匹配发生在查询规划阶段,而不是运行时。因此,参数化查询子句无法与部分索引配合工作。例如,一个带参数的预备查询可能写成x < ?,而对于参数的所有可能取值,它都不可能蕴含x < 2。 + 也说明了:索引列和谓词中使用的列不必一致。PostgreSQL支持带任意谓词的部分索引,只要其中只涉及正在建立索引的那张表的列。不过要记住,谓词必须与那些希望从该索引受益的查询中使用的条件相匹配。更准确地说,只有当系统能够识别出查询的WHERE条件在数学上蕴含该索引的谓词时,部分索引才能用于该查询。PostgreSQL并没有一个复杂的定理证明器,来识别那些写法不同但数学上等价的表达式。(不仅构建这样一个通用定理证明器极其困难,而且它很可能也会慢到失去实际用途。)系统可以识别简单的不等式蕴含,例如x < 1蕴含x < 2;否则,谓词条件必须与查询WHERE条件的某一部分完全匹配,否则索引不会被识别为可用。匹配发生在查询规划阶段,而不是运行时。因此,参数化查询子句无法与部分索引配合工作。例如,一个带参数的预备查询可能写成x < ?,而它无法保证在参数的所有可能取值下都蕴含x < 2 @@ -590,7 +580,7 @@ SELECT * FROM orders WHERE order_nr = 3501; 建立一个部分唯一索引 - 假设我们有一张描述测试结果的表。我们希望确保对于给定的subjecttarget组合,只有一条成功记录,但可以有任意多条失败记录。实现方法之一如下: + 假设我们有一张描述测试结果的表。我们希望确保对于给定的测试对象和目标组合,只有一条成功记录,但可以有任意多条失败记录。实现方法之一如下: CREATE TABLE tests ( subject text, @@ -686,7 +676,7 @@ CREATE INDEX mytable_cat_data ON mytable (category, data); - 查询只能引用存储在索引中的列。例如,给定一个表,它有列xyz,而索引建立在xy上,那么下面这些查询可以使用仅索引扫描: + 查询只能引用存储在索引中的列。例如,假设某个表的xy列上有一个索引,且该表还有一列z,那么下面这些查询可以使用仅索引扫描: SELECT x, y FROM tab WHERE x = 'key'; SELECT x FROM tab WHERE x = 'key' AND y < 42; @@ -713,7 +703,7 @@ SELECT x FROM tab WHERE x = 'key' AND z < 42; INCLUDE - in index definitions + 在索引定义中 为了有效利用仅索引扫描特性,你可以选择创建一个覆盖索引,也就是专门设计来包含某一类高频查询所需列的索引。由于查询通常需要取回的列不止是用于搜索的那些列,PostgreSQL允许你创建一种索引,其中某些列只是负载,而不是搜索键的一部分。这是通过添加一个INCLUDE子句列出这些额外列来实现的。例如,如果你经常运行如下查询: @@ -735,7 +725,7 @@ CREATE UNIQUE INDEX tab_x_y ON tab(x) INCLUDE (y); - 向索引中添加非键负载列时,明智的做法是保持保守,尤其是宽列。如果某个索引元组超过该索引类型允许的最大尺寸,数据插入就会失败。无论如何,非键列都会复制索引对应表中的数据并让索引膨胀,因此可能拖慢搜索。另外请记住,除非表变化足够缓慢,以至于仅索引扫描很可能无需访问堆,否则把负载列包含在索引中并没有太大意义。如果反正必须访问堆元组,那么顺便从那里取出该列的值也不会增加额外成本。其他限制包括:当前不支持把表达式作为包含列;并且当前只有 B-树、GiST 和 SP-GiST 索引支持包含列。 + 向索引中添加非键负载列时,明智的做法是保持保守,尤其是宽列。如果某个索引元组超过该索引类型允许的最大尺寸,数据插入就会失败。无论如何,非键列都会复制索引对应表中的数据并让索引膨胀,因此可能拖慢搜索。另外请记住,除非表变化足够缓慢,以至于仅索引扫描很可能无需访问堆,否则把负载列包含在索引中并没有太大意义。如果反正必须访问堆元组,那么顺便从那里取出该列的值也不会增加额外代价。其他限制包括:当前不支持把表达式作为包含列;并且当前只有 B-树、GiST 和 SP-GiST 索引支持包含列。 @@ -781,11 +771,11 @@ SELECT target FROM tests WHERE subject = 'some-subject' AND success; 操作符类和操作符族 - operator class + 操作符类 - operator family + 操作符族 @@ -903,8 +893,8 @@ CREATE INDEX test1c_content_y_index ON test1c (content COLLATE "y"); 检查索引使用情况 - index - examining usage + 索引 + 检查使用情况 diff --git a/zh/15/information_schema.sgml b/zh/15/information_schema.sgml index ca654d01..bece56cc 100644 --- a/zh/15/information_schema.sgml +++ b/zh/15/information_schema.sgml @@ -388,7 +388,7 @@ collation_catalog sql_identifier - 包含此属性排序规则的数据库名(总是当前数据库),如果默认或者该属性的数据类型不可排序则为空 + 包含该属性排序规则的数据库名称(总是当前数据库);如果使用默认排序规则,或该属性的数据类型不支持排序规则,则为 null。 @@ -397,7 +397,7 @@ collation_schema sql_identifier - 包含此属性排序规则的模式名,如果默认或者该属性的数据类型不可排序则为空 + 包含该属性排序规则的模式名称;如果使用默认排序规则,或该属性的数据类型不支持排序规则,则为 null。 @@ -406,7 +406,7 @@ collation_name sql_identifier - 该属性排序规则的名称,如果默认或者该属性的数据类型不可排序则为空 + 该属性排序规则的名称;如果使用默认排序规则,或该属性的数据类型不支持排序规则,则为 null。 @@ -1626,7 +1626,7 @@ collation_catalog sql_identifier - 包含此属性排序规则的数据库名(总是当前数据库),如果默认或者该属性的数据类型不可排序则为空 + 包含该列排序规则的数据库名称(总是当前数据库);如果使用默认排序规则,或该列的数据类型不支持排序规则,则为 null。 @@ -1635,7 +1635,7 @@ collation_schema sql_identifier - 该列的包含排序规则的模式名,如果默认或者该列的数据类型不可排序则为空 + 包含该列排序规则的模式名称;如果使用默认排序规则,或该列的数据类型不支持排序规则,则为 null。 @@ -1644,7 +1644,7 @@ collation_name sql_identifier - 该列的排序规则的名称,如果默认或者该列的数据类型不可排序则为空 + 该列排序规则的名称;如果使用默认排序规则,或该列的数据类型不支持排序规则,则为 null。 @@ -2385,7 +2385,7 @@ collation_catalog sql_identifier - 包含此域排序规则的数据库名(总是当前数据库),如果默认或者该域的数据类型不可排序则为空 + 包含该域排序规则的数据库名称(总是当前数据库);如果使用默认排序规则,或该域的数据类型不支持排序规则,则为 null。 @@ -2394,7 +2394,7 @@ collation_schema sql_identifier - 包含此域排序规则的模式名,如果默认或者该域的数据类型不可排序则为空 + 包含该域排序规则的模式名称;如果使用默认排序规则,或该域的数据类型不支持排序规则,则为 null。 @@ -2403,7 +2403,7 @@ collation_name sql_identifier - 该域排序规则的名称,如果默认或者该域的数据类型不可排序则为空 + 该域排序规则的名称;如果使用默认排序规则,或该域的数据类型不支持排序规则,则为 null。 @@ -2558,7 +2558,7 @@ <literal>element_types</literal> - 视图element_types包含数组元素的数据类型描述符。当一个表列、复合类型属性、域、函数参数或函数返回值被定义为一种数组类型,相应的信息模式视图只在列data_type中包含ARRAY。要获得该数组元素类型的信息,你可以连接该相应的视图和这个视图。例如,要显示一个表的列及其数据类型和数组元素类型,你可以: + 视图element_types包含数组元素的数据类型描述符。当一个表列、复合类型属性、域、函数参数或函数返回值被定义为一种数组类型时,相应的信息模式视图只在列data_type中包含ARRAY。要获得该数组元素类型的信息,你可以连接该相应的视图和这个视图。例如,要显示一个表的列及其数据类型和数组元素类型(如果适用),你可以: SELECT c.column_name, c.data_type, e.data_type AS element_type FROM information_schema.columns c LEFT JOIN information_schema.element_types e @@ -2689,7 +2689,7 @@ ORDER BY c.ordinal_position; collation_catalog sql_identifier - 包含元素类型排序规则的数据库名称(总是当前数据库), 如果默认或该元素的数据类型是不可排序的则为空 + 包含该元素类型排序规则的数据库名称(总是当前数据库);如果使用默认排序规则,或该元素类型不支持排序规则,则为 null。 @@ -2698,7 +2698,7 @@ ORDER BY c.ordinal_position; collation_schema sql_identifier - 包含元素类型排序规则的模式名称, 如果默认或该元素的数据类型是不可排序的则为空 + 包含该元素类型排序规则的模式名称;如果使用默认排序规则,或该元素类型不支持排序规则,则为 null。 @@ -2707,7 +2707,7 @@ ORDER BY c.ordinal_position; collation_name sql_identifier - 元素类型的排序规则名, 如果默认或该元素的数据类型是不可排序的则为空 + 该元素类型排序规则的名称;如果使用默认排序规则,或该元素类型不支持排序规则,则为 null。 @@ -2765,6 +2765,15 @@ ORDER BY c.ordinal_position; + + + domain_default character_data + + + 尚未实现 + + + udt_catalog sql_identifier @@ -6291,7 +6300,7 @@ ORDER BY c.ordinal_position; enforced yes_or_no - 如果该约束被强制执行,则为YES,否则为NO + 适用于PostgreSQL尚不提供的功能(当前总是YES @@ -7145,7 +7154,7 @@ ORDER BY c.ordinal_position; - SQL 了解两种用户定义类型:结构类型(在PostgreSQL中也称为复合类型)以及 distinct type(PostgreSQL 尚未实现)。为兼顾将来,请使用列user_defined_type_category来区分它们。其他用户定义类型,如基类型和枚举(两者都是PostgreSQL的扩展),不会在这里显示。域的相关信息见。 + SQL 中有两种用户定义类型:结构类型(在PostgreSQL中也称为复合类型)以及独立类型(distinct type,PostgreSQL 尚未实现)。为兼顾将来,请使用列user_defined_type_category来区分它们。其他用户定义类型,如基础类型和枚举(两者都是PostgreSQL的扩展),不会在这里显示。域的相关信息见 @@ -7877,7 +7886,7 @@ ORDER BY c.ordinal_position; check_optioncharacter_data - CASCADEDLOCAL 如果视图上有CHECK OPTION 定义,如果没有则为NONE。 + CASCADEDLOCAL 如果视图上有CHECK OPTION 定义,如果没有则为NONE diff --git a/zh/15/install-windows.sgml b/zh/15/install-windows.sgml index 895533ad..da1f72d1 100644 --- a/zh/15/install-windows.sgml +++ b/zh/15/install-windows.sgml @@ -4,8 +4,8 @@ 在 <productname>Windows</productname> 上从源代码安装 - installation - on Windows + 安装 + 在 Windows 上 @@ -116,8 +116,7 @@ $ENV{MSBFLAGS}="/m"; - Bison and - Flex + BisonFlex 从 Git 构建需要BisonFlex,但从发布文件构建则不需要。只有 Bison 1.875 或 2.2 及以上版本可以工作。Flex必须为 2.5.31 或更高版本。 @@ -162,8 +161,7 @@ $ENV{MSBFLAGS}="/m"; - libxml2 and - libxslt + libxml2libxslt XML 支持需要它们。二进制文件可从下载,源代码可从获取。请注意,libxml2 需要 iconv,而它可从相同的下载位置获得。 @@ -321,9 +319,7 @@ $ENV{CONFIG}="Debug"; IPC::Run - - 截至本文写作时,IPC::Run既未包含在 ActiveState Perl 安装中,也未包含在 ActiveState Perl Package Manager(PPM)库中。要安装它,请从 CPAN 下载IPC-Run-<version>.tar.gz源代码归档文件,即,并解压。编辑buildenv.pl文件,并增加一个 PERL5LIB 变量,使其指向解压后目录中的lib子目录。例如: - + 撰写本文时,IPC::Run 既未包含在 ActiveState Perl 安装中,也未包含在 ActiveState Perl 软件包管理器(PPM)的库中。要安装它,请下载以下文件:IPC-Run-<version>.tar.gz,这是 CPAN 提供的源码归档,地址为 ,然后将其解压。编辑 buildenv.pl 文件,并添加 PERL5LIB 变量,使其指向解压后归档中的 lib 子目录。例如: $ENV{PERL5LIB}=$ENV{PERL5LIB} . ';c:\IPC-Run-0.94\lib'; @@ -346,19 +342,19 @@ $ENV{PROVE_TESTS}='t/020*.pl t/010*.pl' - 某些 TAP 测试依赖一组外部命令,这些命令会选择性触发与其相关的测试。每个这样的变量都可以在buildenv.pl中设置或取消设置: + 部分 TAP 测试依赖一些外部命令,相关测试会根据这些命令是否可用而选择性触发。以下各变量都可以在 buildenv.pl 中设置或取消设置: GZIP_PROGRAM - 指向gzip命令的路径。默认值为gzip,即在PATH中找到的该命令。 + 指向gzip命令的路径。默认值为gzip,它会在配置好的PATH中搜索该名称的命令。 LZ4 - 指向lz4命令的路径。默认值为lz4,即在PATH中找到的该命令。 + 指向lz4命令的路径。默认值为lz4,它会在配置好的PATH中搜索该名称的命令。 @@ -366,14 +362,14 @@ $ENV{PROVE_TESTS}='t/020*.pl t/010*.pl' TAR - 指向tar命令的路径。默认值为tar,即在PATH中找到的该命令。 + 指向tar命令的路径。默认值为tar,它会在配置好的PATH中搜索该名称的命令。 ZSTD - 指向zstd命令的路径。默认值为zstd,即在PATH中找到的该命令。 + 指向zstd命令的路径。默认值为zstd,它会在配置好的PATH中搜索该名称的命令。 diff --git a/zh/15/installation.sgml b/zh/15/installation.sgml index 076b930b..ffaf3d01 100644 --- a/zh/15/installation.sgml +++ b/zh/15/installation.sgml @@ -1,12 +1,21 @@ + 从源代码安装 - installation + 安装 + 本章介绍如何使用源代码发布包安装 PostgreSQL。如果你安装的是预打包的发行版, @@ -14,6 +23,32 @@ + 如果你要为 Microsoft Windows 构建 PostgreSQL,并打算使用 MinGW 或 Cygwin,请阅读本章;但如果打算使用 Microsoft 的 Visual C++,请改为参见 + + + 简要说明 + + + + +./configure +make +su +make install +adduser postgres +mkdir -p /usr/local/pgsql/data +chown postgres /usr/local/pgsql/data +su - postgres +/usr/local/pgsql/bin/initdb -D /usr/local/pgsql/data +/usr/local/pgsql/bin/pg_ctl -D /usr/local/pgsql/data -l logfile start +/usr/local/pgsql/bin/createdb test +/usr/local/pgsql/bin/psql test + + 详细说明见本的其余部分。 + + + + 需求 @@ -46,26 +81,6 @@ - - - - Meson - - - 另一种方式是使用 Meson - 构建 PostgreSQL。这是在 Windows 上通过 - Visual Studio 构建 - PostgreSQL 的唯一方法。对于其他平台, - 使用 Meson 目前仍属于实验性功能。如果你选择使用 - Meson,则不需要 GNU - make,但下面列出的其他要求仍然适用。 - - - - Meson 的最低要求版本是 0.54。 - - - 你需要一个 ISO/ANSI C 编译器 @@ -83,40 +98,6 @@ - - - - flex - - - lex - - - bison - - - yacc - - - 需要 FlexBison。 - 不能使用其他 lex 和 - yacc 程序。 - Bison 至少需要 2.3 版本。 - - - - - - - perl - - - 在构建过程中以及运行某些测试套件时,需要 Perl - 5.14 或更高版本。(这一要求与构建 PL/Perl - 的要求是分开的;见下文。) - - - @@ -157,34 +138,6 @@ 对压缩归档的支持。 - - - - 默认使用 ICU 库。如果你不想使用它,则必须给 - configure 指定 - 选项。使用这个选项将禁用 ICU 排序规则特性的支持(见 - )。 - - - ICU 支持要求安装 ICU4C 软件包。 - 当前 ICU4C 的最低要求版本是 4.2。 - - - - 默认情况下,将使用 - pkg-configpkg-config - 查找所需的编译选项。这适用于 ICU4C 4.6 及更高版本。 - 对于较旧版本,或者如果 pkg-config 不可用, - 可以把 ICU_CFLAGSICU_LIBS - 变量传给 configure,例如: - -./configure ... ICU_CFLAGS='-I/some/where/include' ICU_LIBS='-L/some/where/lib -licui18n -licuuc -licudata' - - (如果 ICU4C 位于编译器的默认搜索路径中, - 你仍然需要指定非空字符串,以避免使用 pkg-config, - 例如 ICU_CFLAGS=' '。) - - @@ -198,7 +151,7 @@ 要构建服务器端编程语言 PL/Perl, 你需要一个完整的 Perl 安装, 包括 libperl 库和头文件。 - 最低要求版本是 Perl 5.14。 + 最低要求版本是 Perl 5.8.3。 由于 PL/Perl 是一个共享库,在大多数平台上, libperllibperl 也必须是共享库。这在较新的 @@ -224,8 +177,8 @@ 要构建 PL/Python 服务器端编程语言, 你需要带有头文件以及 sysconfig 模块的 - Python 安装。最低支持版本是 - Python 3.6.8。 + Python 安装。最低要求版本是 + Python 3.2。 @@ -273,29 +226,12 @@ 如果你希望支持加密的客户端连接,就需要 OpenSSL。 在没有 /dev/urandom 的平台上(Windows 除外), 生成随机数也需要 OpenSSL。 - 最低要求版本是 1.1.1。 - - - 此外,也支持通过 OpenSSL 兼容层使用 - LibreSSL。最低要求版本是 3.4 - (来自 OpenBSD 7.0)。 - - - - - - 如果你希望支持使用这些服务进行认证,则需要 - MIT Kerberos(用于 GSSAPI)、 - OpenLDAP 和/或 PAM。 + 最低要求版本是 1.0.1。 - - 你需要 Curl 来构建一个可选模块, - 该模块为客户端应用实现了 - OAuth 设备授权流程。 - + 如果你希望支持使用相应服务进行认证,就需要 KerberosOpenLDAP 和/或 PAM @@ -323,12 +259,34 @@ + 如果你从 Git 树构建,而不是使用已发布的源码包,或者你要进行服务器开发,还需要以下软件包: + + + flex + + lex + + bison + + yacc + 从 Git 检出构建,或者修改了扫描器和解析器的实际定义文件时,需要 FlexBison。如果需要它们,请确保使用 Flex 2.5.31 或更高版本,以及 Bison 1.875 或更高版本。不能使用其他 lexyacc 程序。 + + + + perl + 从 Git 检出构建,或者修改了使用 Perl 脚本的任何构建步骤的输入文件时,需要 Perl 5.8.3 或更高版本。在 Windows 上构建时,无论如何都需要 Perl。运行某些测试套件也需要 Perl + + + + 如果你需要获取 GNU 软件包,可以从本地的 GNU 镜像站点获取(站点列表见 ),或者直接从 获取。 + + 还要检查磁盘空间是否充足。编译期间,源码树需要约 350 MB,安装目录需要约 60 MB。空数据库集簇约占 40 MB;数据库所需空间大约是存储相同数据的纯文本文件的五倍。如果要运行回归测试,还会临时额外需要最多 300 MB。使用 df 命令检查可用磁盘空间。 @@ -358,34 +316,10 @@ - - 使用 Autoconf 和 Make 进行构建和安装 - - - 简短版本 - - - -./configure -make -su -make install -adduser postgres -mkdir -p /usr/local/pgsql/data -chown postgres /usr/local/pgsql/data -su - postgres -/usr/local/pgsql/bin/initdb -D /usr/local/pgsql/data -/usr/local/pgsql/bin/pg_ctl -D /usr/local/pgsql/data -l logfile start -/usr/local/pgsql/bin/createdb test -/usr/local/pgsql/bin/psql test - - 较长版本见本其余部分。 - - - - - + 安装过程 + + @@ -601,13 +535,12 @@ build-postgresql: make distclean 是一个好主意。否则,你对配置选项所做的更改 可能不会传播到所有需要它们的地方。 - <filename>configure</filename> 选项 - 配置选项 + configure 选项 @@ -854,22 +787,24 @@ build-postgresql: + + + + 构建时支持 ICUICU 库,以使用 ICU 排序规则功能(见 。这要求已安装 ICU4C 软件包。当前 ICU4C 的最低要求版本是 4.2。 + + 默认情况下,pkg-configpkg-config 用于查找所需的编译选项。此方式支持 ICU4C 4.6 及更高版本。对于更早的版本,或者当 pkg-config 不可用时,可以将变量 ICU_CFLAGSICU_LIBS 指定给 configure,如下例所示: +./configure ... --with-icu ICU_CFLAGS='-I/some/where/include' ICU_LIBS='-L/some/where/lib -licui18n -licuuc -licudata' +(如果 ICU4C 位于编译器的默认搜索路径中,仍需要指定非空字符串,以避免使用 pkg-config,例如 ICU_CFLAGS=' '。) + + + + + 构建时支持基于 LLVMJIT 编译(见 。这要求已安装 LLVM 库。当前 LLVM 的最低要求版本是 3.9。 - 构建时支持基于 LLVM 的 - JIT 编译(见 )。 - 这要求已安装 LLVM 库。 - 当前 LLVM 的最低要求版本是 14。 - - - llvm-configllvm-config - 将用于查找所需的编译选项。系统会在你的 PATH 中搜索 - llvm-config。如果这样找不到你想要的程序,请使用 - LLVM_CONFIG 指定正确的 llvm-config - 路径。例如: - + llvm-configllvm-config 用于查找所需的编译选项。首先查找 llvm-config,然后查找 llvm-config-$major-$minor(遍历所有受支持版本),搜索位置为 PATH。如果这样无法找到所需程序,请使用 LLVM_CONFIG 指定正确程序的路径,即 llvm-config。例如: ./configure ... --with-llvm LLVM_CONFIG='/path/to/llvm/bin/llvm-config' @@ -911,10 +846,8 @@ build-postgresql: 构建时支持 SSL(加密)连接。 - 唯一支持的 LIBRARY, - 它同时适用于 OpenSSL 和 - LibreSSL。这要求安装 - OpenSSL 软件包。 + 唯一支持的 LIBRARY。 + 这要求安装 OpenSSL 软件包。 configure 会检查所需的头文件和库, 以确认你的 OpenSSL 安装足够后才继续。 @@ -934,8 +867,8 @@ build-postgresql: - 构建时支持 GSSAPI 认证。要使用 GSSAPI,必须安装 MIT Kerberos。 - 在很多系统上,GSSAPI 系统(MIT Kerberos 安装的一部分)并不位于默认搜索的路径 + 构建时支持 GSSAPI 认证。 + 在很多系统上,GSSAPI 系统(通常是 Kerberos 安装的一部分)并不位于默认搜索的路径 中(例如 /usr/include/usr/lib), 因此除了这个选项之外,你还必须使用 configure @@ -989,7 +922,7 @@ build-postgresql: 构建时支持 systemdsystemd 服务通知。如果服务器是在 systemd 下启动, - 这会改进集成;否则没有影响。更多信息见 。 + 这会改进集成;否则没有影响。更多信息见 要使用此选项,需要安装 libsystemd 及其相关头文件。 @@ -1031,7 +964,7 @@ build-postgresql: ,使用 OSSP UUID library + url="http://www.ossp.org/pkg/lib/uuid/">OSSP UUID 库 @@ -1047,45 +980,6 @@ build-postgresql: - - - - - 构建时支持 libcurl,用于 OAuth 2.0 客户端流程。 - 此特性要求 libcurl 7.61.0 或更高版本。 - 使用该选项构建时,会检查所需的头文件和库,以确认你的 - curl 安装足够后才继续。 - - - - - - - - - 构建时支持 libnuma,用于基础 NUMA 支持。 - 仅在实现了 libnuma 库的平台上受支持。 - - - - - - - - - 构建时支持 liburing,以启用异步 I/O 的 io_uring 支持。 - - - 为了检测所需的编译器和链接器选项,PostgreSQL 会查询 - pkg-config。 - - - 如果 liburing 安装在不常见的位置,你可以设置与 - pkg-config 相关的环境变量(见其文档)。 - - - - @@ -1094,13 +988,7 @@ build-postgresql: 这一特性要求 libxml2 2.6.23 或更高版本。 - - 为了检测所需的编译器和链接器选项,如果系统已安装 - pkg-config 且知道 libxml2,PostgreSQL - 会查询 pkg-config。否则,如果找得到由 libxml2 - 安装的 xml2-config 程序,就会使用它。 - 优先使用 pkg-config,因为它能更好地处理多架构安装。 - + 为检测所需的编译器和链接器选项,PostgreSQL 会查询 pkg-config,前提是已安装该程序且其中有 libxml2 的信息。否则,如果找到 libxml2 安装的 xml2-config 程序,就会使用它。优先使用 pkg-config,因为它能更好地处理多架构安装。 如果 libxml2 安装在不常见的位置,你可以设置与 @@ -1128,21 +1016,12 @@ build-postgresql: - - - - - 构建时支持 SElinux,以启用 扩展。 - - - - - 反功能 + 禁用特性 本节描述的选项允许禁用某些默认会构建的 @@ -1152,18 +1031,6 @@ build-postgresql: - - - - - 构建时不支持 - ICUICU - 库,从而禁用 ICU 排序规则特性(见 )。 - - - - @@ -1201,6 +1068,27 @@ build-postgresql: + + + + 即使 PostgreSQL 不支持该平台的 CPU 自旋锁,也允许构建成功。缺少自旋锁支持会导致性能极差;因此,仅应在构建中止并告知平台缺少自旋锁支持时使用此选项。如果在你的平台上构建 PostgreSQL 必须使用此选项,请向 PostgreSQL 开发者报告该问题。 + + + + + + + 禁用 CPU 原子操作。在不支持此类操作的平台上,此选项不产生影响。在支持的平台上,它会导致性能下降。此选项仅用于调试或性能比较。 + + + + + + + 禁用客户端库的线程安全性。这会使 libpqECPG 程序中的并发线程无法安全地控制各自私有的连接句柄。仅在缺乏完善线程支持的平台上使用此选项。 + + + @@ -1287,8 +1175,7 @@ build-postgresql: - 不在 PostgreSQL 的可执行文件中标记, - 使其在运行时到安装的库目录中搜索共享库(见 )。 + 不在 PostgreSQL 的可执行文件中添加指示其到安装的库目录中搜索共享库的标记(见 )。 在大多数平台上,这种标记使用库目录的绝对路径,因此如果你之后移动安装位置, 它就没有帮助了。不过这样一来,你就需要通过其他方式让可执行文件找到共享库。 通常这要求配置操作系统的动态链接器搜索该库目录;更多细节见 @@ -1305,7 +1192,7 @@ build-postgresql: 杂项 - 调整默认端口号 相当常见, + 使用 调整默认端口号相当常见, 尤其是在测试性构建中。本节中的其他选项只推荐给高级用户。 @@ -1340,10 +1227,10 @@ build-postgresql: - 设置 segment size,单位为 GB。 + 设置 段大小,单位为 GB。 大表会被分成多个操作系统文件,每个文件的大小等于段大小。 这可以避免很多平台上的文件大小限制问题。默认段大小 1GB 在所有支持的平台上 - 都是安全的。如果你的操作系统支持 largefile + 都是安全的。如果你的操作系统支持 大文件 (如今大多数都支持),你可以使用更大的段大小。 这有助于减少处理超大表时消耗的文件描述符数量。 但请注意不要选择超出你的平台和打算使用的文件系统所支持的值。 @@ -1359,7 +1246,7 @@ build-postgresql: - 设置 block size,单位为 KB。 + 设置 块大小,单位为 KB。 这是表内部存储和 I/O 的单位。默认值 8KB 适合大多数场景, 但在特殊情况下,其他取值也可能有用。 该值必须是 1 到 32(KB)之间的 2 的幂。 @@ -1373,7 +1260,7 @@ build-postgresql: - 设置 WAL block size,单位为 KB。 + 设置 WAL 块大小,单位为 KB。 这是 WAL 日志内部存储和 I/O 的单位。默认值 8KB 适合大多数场景, 但在特殊情况下,其他取值也可能有用。 该值必须是 1 到 64(KB)之间的 2 的幂。 @@ -1423,11 +1310,11 @@ build-postgresql: - 在服务器中启用 assertion 检查,用于测试许多 - 不应该发生的条件。这对代码开发非常有价值,但这些测试会显著拖慢 + 在服务器中启用 断言 检查,用于测试许多 + 不可能发生的条件。这对代码开发非常有价值,但这些测试可能会显著拖慢 服务器速度。此外,启用这些测试并不一定会增强服务器稳定性! 断言检查并未按严重程度分类,因此即使某个 bug 相对无害,只要触发了断言失败, - 仍可能导致服务器重启。该选项不建议用于生产环境,但如果你在做开发工作 + 仍会导致服务器重启。该选项不建议用于生产环境,但如果你在做开发工作 或运行测试版,就应当启用它。 @@ -1438,7 +1325,7 @@ build-postgresql: 启用使用 Perl TAP 工具的测试。这要求安装 Perl 以及 Perl 模块 - IPC::Run。更多信息见 。 + IPC::Run更多信息见 @@ -1461,7 +1348,7 @@ build-postgresql: 如果使用 GCC,所有程序和库都会带代码覆盖率测试插桩进行编译。 运行时,它们会在构建目录中生成包含代码覆盖率指标的文件。 - 更多信息见 。 + 更多信息见 该选项只适用于 GCC,并且仅在开发工作中使用。 @@ -1472,7 +1359,7 @@ build-postgresql: 如果使用 GCC,所有程序和库都会被编译成可进行性能分析的形式。 - 后端退出时,会创建一个子目录,其中包含带有 profile 数据的 + 后端退出时,会创建一个子目录,其中包含带有性能分析数据的 gmon.out 文件。 该选项只适用于 GCC,并且仅在开发工作中使用。 @@ -1487,7 +1374,7 @@ build-postgresql: DTracePostgreSQL 编译为支持动态跟踪工具 DTrace。 - 更多信息见 。 + 更多信息见 @@ -1512,32 +1399,6 @@ build-postgresql: - - - - - - 将 PostgreSQL 编译为支持服务器中的注入点。 - 注入点允许在预定义的代码路径中,从服务器内部运行用户定义的代码。 - 这有助于以受控方式测试并研究并发场景。该选项默认关闭。 - 更多细节见 。 - 该选项仅供开发人员测试使用。 - - - - - - - - - 以块数指定关系段大小。如果同时指定了 - 和这个选项,则以后者为准。 - - 该选项仅供开发人员测试与段相关的代码。 - - - - @@ -1548,7 +1409,7 @@ build-postgresql: <filename>configure</filename> 环境变量 - configure environment variables + configure 环境变量 @@ -1615,7 +1476,7 @@ build-postgresql: 在使用 --with-llvm 编译时, - 用于处理源代码以内联的 clang 程序路径 + 用于处理源代码以进行内联的 clang 程序路径 @@ -1773,21 +1634,9 @@ build-postgresql: - - 有时,在事后把额外的编译器标志加入到 - configure 选定的那组选项中会很有用。 - 一个重要例子是,gcc - 不能包含在传给 configureCFLAGS 中, - 因为这会破坏 configure 的很多内置测试。 - 要添加这类标志,请在运行 make 时把它们放入环境变量 - COPTCOPT 的内容会被附加到 - configure 设置好的 CFLAGS、 - CXXFLAGSLDFLAGS 上。例如,你可以这样做: - + 有时,事后补充编译器标志会很有用;原有标志由 configure 选定。一个重要的例子是 gcc 选项不能包含在以下变量中:CFLAGS(该变量会传给 configure),因为它会破坏 configure 的许多内置测试。要添加此类标志,请将其放入 COPT 环境变量,再运行 makeCOPT 的内容会被加入以下两组选项:CFLAGSLDFLAGS;这两组选项原本由以下程序设置:configure。例如,你可以执行: make COPT='-Werror' - - 或者: - +或者: export COPT='-Werror' make @@ -1815,1197 +1664,52 @@ build-postgresql: - - 使用 Meson 构建和安装 - - - 简短版本 - - - -meson setup build --prefix=/usr/local/pgsql -cd build -ninja -su -ninja install -adduser postgres -mkdir -p /usr/local/pgsql/data -chown postgres /usr/local/pgsql/data -su - postgres -/usr/local/pgsql/bin/initdb -D /usr/local/pgsql/data -/usr/local/pgsql/bin/pg_ctl -D /usr/local/pgsql/data -l logfile start -/usr/local/pgsql/bin/createdb test -/usr/local/pgsql/bin/psql test - - 较长版本见本其余部分。 - - - - - 安装过程 + + 安装后设置 - + + 共享库 - - 配置 + + 共享库 + - 安装过程的第一步,是针对你的系统配置构建树,并选择你需要的选项。 - 要创建并配置构建目录,可以从 meson setup 命令开始: - -meson setup build - - setup 命令接受 builddirsrcdir - 两个参数。如果未给出 srcdir,Meson 会根据当前目录以及 - meson.build 的位置推导出 srcdir。 - builddir 是必需的。 + 在某些使用共享库的系统上,你需要告诉系统如何找到新安装的共享库。 + 需要这样做的系统包括 + FreeBSD、 + HP-UX、 + Linux、 + NetBSD、 + OpenBSD 和 + Solaris - 运行 meson setup 会加载构建配置文件并设置构建目录。 - 此外,你也可以向 Meson 传递多个构建选项。后续章节会介绍一些常用选项。例如: - - -# configure with a different installation prefix -meson setup build --prefix=/home/user/pg-install - -# configure to generate a debug build -meson setup build --buildtype=debug - -# configure to build with OpenSSL support -meson setup build -Dssl=openssl - + 设置共享库搜索路径的方法因平台而异,但最常见的方法是按如下方式设置环境变量 + LD_LIBRARY_PATH。对于 Bourne shell + (shkshbash、 + zsh): + +LD_LIBRARY_PATH=/usr/local/pgsql/lib +export LD_LIBRARY_PATH + + 或者对于 cshtcsh: + +setenv LD_LIBRARY_PATH /usr/local/pgsql/lib + + 请把这里的 /usr/local/pgsql/lib 替换为你在 + 中通过 + 设置的值。你应该把这些命令放入 shell 启动文件,例如 + /etc/profile~/.bash_profile。 + 关于这种方法的注意事项,有一些不错的资料可参见 + - 设置构建目录是一次性步骤。如果要在新的构建前重新配置,只需使用 - meson configure 命令: - -meson configure -Dcassert=true - - meson configure 的常用命令行选项见 - 。 - - - - - 构建 - - - 默认情况下,Meson 使用 - Ninja 作为构建工具。 - 要使用 Meson 从源代码构建 PostgreSQL, - 只需在构建目录中运行 ninja 命令: - -ninja - - Ninja 会自动检测你的计算机 CPU 数量,并据此并行执行。 - 你也可以用命令行参数 -j 覆盖并行进程数。 - - - - 需要注意的是,在最初的配置步骤之后,ninja 就是你编译时 - 唯一需要输入的命令。不管你如何修改源码树(只要不是把它移动到全新的位置), - Meson 都会检测变化并相应重新生成自己。如果你有多个构建目录,这一点尤其方便。 - 通常其中一个用于开发(调试构建),而另一些只在偶尔需要时使用 - (比如 静态分析构建)。任何配置都只需切换到对应目录, - 然后运行 Ninja 即可完成构建。 - - - - 如果你希望使用 ninja 之外的后端进行构建,可以在配置时使用 - 选项进行选择,然后通过 - meson compile 来构建。要进一步了解这些后端, - 以及你可以传给 ninja 的其他参数,可参考 - - Meson 文档。 - - - - - 回归测试 - - - 回归测试 - - - - 如果你希望在安装之前测试新构建的服务器,可以在此时运行回归测试。 - 回归测试是一套测试,用来验证 PostgreSQL - 是否按开发者预期的方式在你的机器上运行。输入: - -meson test - - (这不能以 root 身份运行;请使用非特权用户。) - 关于如何解释测试结果的详细信息,见 。 - 在以后的任何时候,你都可以再次执行同样的命令来重复此测试。 - - - - 如果要针对正在运行的 postgres 实例运行 pg_regress 和 - pg_isolation_regress 测试,请向 meson test - 传入参数 --setup running。 - - - - - 安装文件 - - - - 如果你是在升级已有系统,请务必阅读 - ,其中包含关于升级集簇的说明。 - - - - - PostgreSQL 构建完成后,只需运行 ninja install 命令即可安装: - -ninja install - - - - - 这会把文件安装到 中指定的目录。 - 请确保你有权限写入该区域。你可能需要以 root 身份执行这一步。 - 另一种做法是预先创建目标目录,并安排授予适当权限。 - 标准安装会提供客户端应用开发以及服务器端程序开发所需的全部头文件, - 例如用 C 编写的自定义函数或数据类型。 - - - - 在大多数情况下,ninja install 都能正常工作; - 但如果你希望使用更多选项(例如 以抑制额外输出), - 也可以改用 meson install。关于 - meson install - 及其选项的更多信息,请参见 Meson 文档。 - - - - - - 卸载: - - 要撤销安装,可以使用 ninja uninstall 命令。 - - - - - 清理: - - 安装完成后,可以通过 ninja clean 命令从源码树中删除 - 已构建文件,以释放磁盘空间。 - - - - - - <literal>meson setup</literal> 选项 - - - 下面解释 meson setup 的命令行选项。 - 这个列表并不完整(可使用 meson configure --help - 获取完整列表)。此处未涉及的选项主要用于高级用例,并记录在标准 - Meson - 文档中。这些参数也可用于 meson setup。 - - - - 安装位置 - - - 这些选项控制 ninja install(或 - meson install)将文件安装到哪里。 - 选项(示例见 ) - 对大多数情况来说已经足够。如果你有特殊需求,可以使用本节中描述的其他选项 - 定制安装子目录。但请注意,更改不同子目录之间的相对位置可能会使安装变得 - 不可重定位,也就是安装后无法再移动。(man 和 - doc 的位置不受这一限制影响。) - 对于可重定位安装,你可能希望使用稍后介绍的 - -Drpath=false 选项。 - - - - - - - - 把所有文件安装到目录 PREFIX 下, - 而不是安装到 /usr/local/pgsql - (类 Unix 系统)或 - 当前驱动器盘符:/usr/local/pgsql - (Windows)下。实际文件会安装到各个子目录中;不会有任何文件直接安装到 - PREFIX 目录中。 - - - - - - - - - 指定可执行程序的目录。默认是 - PREFIX/bin。 - - - - - - - - - 设置各种配置文件的目录,默认是 - PREFIX/etc。 - - - - - - - - - 设置安装库和动态可加载模块的位置。默认是 - PREFIX/lib。 - - - - - - - - - 设置安装 C 和 C++ 头文件的目录。默认是 - PREFIX/include。 - - - - - - - - - 设置已安装程序使用的只读数据文件目录。默认是 - PREFIX/share。 - 注意,这与数据库文件实际存放的位置无关。 - - - - - - - - - 设置安装区域设置数据的目录,尤其是消息翻译目录文件。 - 默认是 DATADIR/locale。 - - - - - - - - - PostgreSQL 附带的手册页将安装到这个目录下 - 各自对应的 manx - 子目录中。默认是 DATADIR/man。 - - - - - - - - - 为了能把 PostgreSQL 安装到共享安装位置 - (例如 /usr/local/include),同时又不干扰系统其他部分的 - 名字空间,我们做了特别处理。首先,除非完整展开后的目录名已经包含字符串 - postgres 或 - pgsql,否则会自动把字符串 - /postgresql 追加到 - datadirsysconfdir 和 - docdir 上。例如,如果你选择 - /usr/local 作为前缀,那么文档会安装到 - /usr/local/doc/postgresql;但如果前缀是 - /opt/postgres,那么它会安装到 - /opt/postgres/doc。客户端接口的公共 C 头文件 - 会安装到 includedir 中,并且不会污染名字空间。 - 内部头文件和服务器头文件则会安装到 includedir - 下的私有目录中。关于如何访问这些头文件,请参见各接口自己的文档。 - 最后,如果有需要,也会在 libdir 下创建私有子目录, - 用于存放动态可加载模块。 - - - - - - <productname>PostgreSQL</productname> 特性 - - - 本节描述的选项用于启用各种可选的 - PostgreSQL 特性。 - 其中大多数需要额外的软件,如 - 所述;如果找到了所需软件,这些特性会自动启用。 - 你可以通过手工把这些特性设为 enabled(要求必须构建) - 或 disabled(不构建),来改变这种行为。 - - - - 要指定 PostgreSQL 特有的选项,选项名必须以 -D 为前缀。 - - - - - - - - 启用或禁用本地语言支持(NLS),也就是以非英语语言显示 - 程序消息的能力。默认值是 auto;如果找到了 - Gettext API 的实现,就会自动启用。 - - - - - - - - - 构建 PL/Perl 服务器端语言。 - 默认值是 auto。 - - - - - - - - - 构建 PL/Python 服务器端语言。 - 默认值是 auto。 - - - - - - - - - 构建 PL/Tcl 服务器端语言。 - 默认值是 auto。 - - - - - - - - - 指定构建 PL/Tcl 时要使用的 Tcl 版本。 - - - - - - - - - 构建时支持 - ICUICU - 库,从而启用 ICU 排序规则特性(见 )。默认值是 auto,并且要求安装 - ICU4C 软件包。当前 - ICU4C 的最低要求版本是 4.2。 - - - - - - - - - 构建时支持基于 LLVM 的 - JIT 编译(见 )。 - 这要求已安装 LLVM 库。 - 当前 LLVM 的最低要求版本是 14。 - 默认禁用。 - - - - llvm-configllvm-config - 将用于查找所需的编译选项。系统会先在你的 PATH 中搜索 - llvm-config,然后再搜索各个受支持版本对应的 - llvm-config-$version。如果这样找不到你想要的程序, - 请使用 LLVM_CONFIG 指定正确的 - llvm-config 路径。 - - - - - - - - - 构建时支持 LZ4 压缩。 - 默认值是 auto。 - - - - - - - - - 构建时支持 Zstandard 压缩。 - 默认值是 auto。 - - - - - - - - OpenSSL - SSL - - - - - 构建时支持 SSL(加密)连接。 - 唯一受支持的 LIBRARY。 - 这要求安装 OpenSSL 软件包。 - 使用该选项构建时,会检查所需的头文件和库,以确认你的 - OpenSSL 安装足够后才继续。 - 该选项的默认值是 auto。 - - - - - - - - - 构建时支持 GSSAPI 认证。要使用 GSSAPI,必须安装 MIT Kerberos。 - 在很多系统上,GSSAPI 系统(MIT Kerberos 安装的一部分)并不位于默认搜索的路径 - 中(例如 /usr/include/usr/lib)。 - 在这种情况下,PostgreSQL 会查询 pkg-config - 来检测所需的编译器和链接器选项。默认值是 auto。 - meson configure 会检查所需的头文件和库, - 以确认你的 GSSAPI 安装足够后才继续。 - - - - - - - - - 构建时支持 - LDAPLDAP - 认证和连接参数查找(更多信息见 - 和 - )。在 Unix 上,这要求安装 - OpenLDAP 软件包。在 Windows 上,使用默认的 - WinLDAP 库。默认值是 auto。 - meson configure 会检查所需的头文件和库, - 以确认你的 OpenLDAP 安装足够后才继续。 - - - - - - - - - 构建时支持 - PAMPAM - (可插拔认证模块)。默认值是 auto。 - - - - - - - - - 构建时支持 BSD 认证。(BSD 认证框架目前仅在 OpenBSD 上可用。) - 默认值是 auto。 - - - - - - - - - 构建时支持 - systemdsystemd - 服务通知。如果服务器是在 systemd 下启动, - 这会改进集成;否则没有影响。更多信息见 - 。默认值是 auto。 - 要使用此选项,需要安装 libsystemd - 及其相关头文件。 - - - - - - - - - 构建时支持 Bonjour 自动服务发现。默认值是 auto,并要求你的操作系统支持 - Bonjour。在 macOS 上推荐启用。 - - - - - - - - - 构建 模块 - (它提供生成 UUID 的函数),并使用指定的 UUID 库。 - UUID - LIBRARY 必须是以下之一: - - - - - ,不构建 uuid 模块。这是默认值。 - - - - - ,使用 FreeBSD 以及其他某些 BSD 衍生系统中的 UUID 函数 - - - - - ,使用 e2fsprogs 项目创建的 UUID 库; - 该库存在于大多数 Linux 系统和 macOS 中,也可用于其他平台 - - - - - ,使用 OSSP UUID library - - - - - - - - - - - 构建时支持 libcurl,用于 OAuth 2.0 客户端流程。 - 此特性要求 libcurl 7.61.0 或更高版本。 - 使用该选项构建时,会检查所需的头文件和库,以确认你的 - Curl 安装足够后才继续。 - 该选项的默认值是 auto。 - - - - - - - - - 构建时支持 liburing,以启用异步 I/O 的 io_uring 支持。 - 默认值是 auto。 - - - - 如果 liburing 安装在不常见的位置,你可以设置与 - pkg-config 相关的环境变量(见其文档)。 - - - - - - - - - 构建时支持 libnuma,用于基础 NUMA 支持。 - 仅在实现了 libnuma 库的平台上受支持。 - 该选项的默认值是 auto。 - - - - - - - - - 构建时支持 libxml2,以启用 SQL/XML 支持。 - 默认值是 auto。该特性要求 libxml2 2.6.23 或更高版本。 - - - - 如果 libxml2 安装在不常见的位置,你可以设置与 - pkg-config 相关的环境变量(见其文档)。 - - - - - - - - - 构建时支持 libxslt,以启用 - - 模块对 XML 执行 XSL 转换。 - 同时还必须指定 。 - 默认值是 auto。 - - - - - - - - - 构建时支持 SElinux,以启用 扩展。 - 默认值是 auto。 - - - - - - - - - 反功能 - - - - - - - 允许使用 Readline 库(以及 - libedit)。该选项默认值为 auto, - 会为 psql 启用命令行编辑和历史记录, - 强烈推荐保留。 - - - - - - - - - 将此值设为 true 时,会优先使用 BSD 许可的 - libedit 库,而不是 GPL 许可的 - Readline。只有在两个库都已安装时, - 该选项才有意义;默认值是 false,也就是使用 - Readline。 - - - - - - - - - - zlib - - 启用 Zlib 库的使用。 - 该选项默认值为 auto,会为 pg_dump、 - pg_restore 和 - pg_basebackup 启用压缩归档支持,推荐保留。 - - - - - - - - - 构建过程细节 - - - - - - - 设置这个选项,可以覆盖所有 auto 特性的取值 - (也就是那些在找到所需软件时会自动启用的特性)。 - 当你想一次性禁用或启用所有 optional 特性, - 而不必逐个手工设置时,这会很有用。 - 该参数的默认值是 auto。 - - - - - - - - - Meson 默认使用的后端是 ninja,这对大多数用例已经足够。 - 不过,如果你希望与 Visual Studio 完全集成,可以把 - BACKEND 设为 vs。 - - - - - - - - - 这个选项可用于向 C 编译器传递额外选项。 - - - - - - - - - 这个选项可用于向 C 链接器传递额外选项。 - - - - - - - - - DIRECTORIES 是一个以逗号分隔的目录列表, - 这些目录会被加入编译器搜索头文件的路径中。 - 如果你把可选软件包(如 GNU Readline) - 安装在非标准位置,就必须使用此选项,并且通常还要使用对应的 - 选项。 - - - - 例如: - -Dextra_include_dirs=/opt/gnu/include,/usr/sup/include。 - - - - - - - - - DIRECTORIES 是一个以逗号分隔的目录列表, - 用于搜索库文件。如果你把软件包安装在非标准位置, - 很可能需要使用这个选项(以及对应的 - )。 - - - 例如:-Dextra_lib_dirs=/opt/gnu/lib,/usr/sup/lib。 - - - - - - - - 时区数据 - - - - - PostgreSQL 自带了日期和时间操作所需的时区数据库。 - 这个时区数据库实际上与很多操作系统(如 FreeBSD、Linux 和 Solaris) - 提供的 IANA 时区数据库兼容,因此再次安装它是多余的。使用此选项时, - 将使用位于 DIRECTORY 的系统提供时区数据库, - 而不是 PostgreSQL 源码发布中自带的那一份。 - DIRECTORY 必须是绝对路径。 - 在某些操作系统上,/usr/share/zoneinfo - 是一个可能的目录。请注意,安装过程不会检测时区数据是否不匹配或有误。 - 如果你使用该选项,建议运行回归测试,以验证你指定的时区数据能够与 - PostgreSQL 正常配合工作。 - - - 交叉编译 - - - 这个选项主要面向那些非常了解其目标操作系统的二进制包发布者。 - 使用该选项的主要优点是,当本地众多夏令时规则中的任何一条发生变化时, - PostgreSQL 软件包都无需升级。另一个优点是,如果安装时不需要构建 - 时区数据库文件,那么 PostgreSQL 的交叉编译也会更直接。 - - - - - - - - - 将 STRING 追加到 PostgreSQL 版本号后面。 - 例如,你可以用它给从未发布的 Git 快照构建出来的 - 二进制文件、或包含自定义补丁的二进制文件,添加额外版本字符串作为标记, - 例如 git describe 标识符或发行包版本号。 - - - - - - - - - 该选项默认值是 true。如果设为 false,则不会在 - PostgreSQL 的可执行文件中标记, - 使其在运行时到安装的库目录中搜索共享库(见 )。 - 在大多数平台上,这种标记使用库目录的绝对路径,因此如果你之后移动安装位置, - 它就没有帮助了。不过这样一来,你就需要通过其他方式让可执行文件找到共享库。 - 通常这要求配置操作系统的动态链接器搜索该库目录;更多细节见 - 。 - - - - - - - - - 如果构建 PostgreSQL(无论是否启用可选标志)所需的某个程序位于非标准路径, - 你可以手工把它指定给 meson configure。 - 支持这样指定的程序完整列表,可通过运行 - meson configure 查看。例如: -meson configure -DBISON=PATH_TO_BISON - - - - - - - - 文档 - - - 关于构建文档所需的工具,见 。 - - - - - - - - - 启用构建 HTMLman - 格式的文档。默认值是 auto。 - - - - - - - - - 启用构建 PDF 格式的文档。默认值是 auto。 - - - - - - - - - 控制使用哪种 CSS 样式表。默认值是 - simple。如果设为 website, - HTML 文档将引用 - postgresql.org - 的样式表。 - - - - - - - - - 杂项 - - - - - - - 将 NUMBER 设为服务器和客户端的默认端口号。 - 默认值是 5432。端口号以后始终都可以修改,但如果在这里指定, - 那么服务器和客户端都会编译进同一个默认值,这可能很方便。 - 通常选择非默认值的唯一合理原因,是你打算在同一台机器上运行多个 - PostgreSQL 服务器。 - - - - - - - - - GSSAPI 所使用的 Kerberos 服务主体的默认名称。 - 默认是 postgres。通常没有理由修改它, - 除非你是在为 Windows 环境构建,在那种情况下它必须被设为大写的 - POSTGRES。 - - - - - - - - - 设置 segment size,单位为 GB。 - 大表会被分成多个操作系统文件,每个文件的大小等于段大小。 - 这可以避免很多平台上的文件大小限制问题。默认段大小 1GB 在所有支持的平台上 - 都是安全的。如果你的操作系统支持 largefile - (如今大多数都支持),你可以使用更大的段大小。 - 这有助于减少处理超大表时消耗的文件描述符数量。 - 但请注意不要选择超出你的平台和打算使用的文件系统所支持的值。 - 你可能想用到的其他工具,例如 tar, - 也可能对可用文件大小施加限制。推荐(但不是绝对要求)把这个值设为 2 的幂。 - - - - - - - - - 设置 block size,单位为 KB。 - 这是表内部存储和 I/O 的单位。默认值 8KB 适合大多数场景, - 但在特殊情况下,其他取值也可能有用。 - 该值必须是 1 到 32(KB)之间的 2 的幂。 - - - - - - - - - 设置 WAL block size,单位为 KB。 - 这是 WAL 日志内部存储和 I/O 的单位。默认值 8KB 适合大多数场景, - 但在特殊情况下,其他取值也可能有用。 - 该值必须是 1 到 64(KB)之间的 2 的幂。 - - - - - - - - 开发人员选项 - - - 本节中的大多数选项只对开发或调试 - PostgreSQL 有意义。 - 除 外,不建议在生产构建中使用它们; - 不过,如果你不幸遇到 bug,该选项有助于获得更详细的 bug 报告。 - 在支持 DTrace 的平台上, - 也可能适合在生产环境中使用。 - - - - 如果构建的安装将用于开发服务器内部代码,建议至少使用 - 。 - - - - - - - - 这个选项可用于指定要使用的构建类型;默认值是 - 。如果你希望对调试符号和优化级别 - 进行比该选项更细粒度的控制,可以参考 - 标志。 - - - - 常用的构建类型包括:、 - 和 - 。关于它们的更多信息,可参见 - Meson - 文档。 - - - - - - - - - 将所有程序和库编译为带调试符号的版本。这意味着你可以在调试器中运行程序, - 以分析问题。这会显著增大安装后的可执行文件大小,而且在非 GCC 编译器上, - 通常还会禁用编译器优化,从而导致变慢。不过,保留这些符号对于处理可能出现的 - 各种问题极其有帮助。目前,只有在你使用 GCC 的情况下,才建议在生产安装中使用 - 该选项。但如果你在做开发工作或运行测试版,就应始终启用它。 - - - - - - =LEVEL - - - 指定优化级别。 可以设为 - {0,g,1,2,3,s} 中任意一个。 - - - - - - - - - 设置该选项后,编译器会把警告当作错误处理。 - 这对代码开发很有用。 - - - - - - - - - 在服务器中启用 assertion 检查,用于测试许多 - 不应该发生的条件。这对代码开发非常有价值,但这些测试会显著拖慢 - 服务器速度。此外,启用这些测试并不一定会增强服务器稳定性! - 断言检查并未按严重程度分类,因此即使某个 bug 相对无害,只要触发了断言失败, - 仍可能导致服务器重启。该选项不建议用于生产环境,但如果你在做开发工作 - 或运行测试版,就应当启用它。 - - - - - - - - - 启用使用 Perl TAP 工具的测试。默认值是 auto,并要求安装 Perl 以及 - Perl 模块 IPC::Run。更多信息见 - 。 - - - - - - - - - 启用额外测试套件;这些测试默认不会运行,因为它们不适合在多用户系统上运行、 - 需要特殊软件,或者资源消耗较大。该参数是以空白分隔的测试名称列表。 - 详见 。如果在运行测试时设置了 - PG_TEST_EXTRA 环境变量,那么它会覆盖这个构建时选项。 - - - - - - - - - 如果使用 GCC,所有程序和库都会带代码覆盖率测试插桩进行编译。 - 运行时,它们会在构建目录中生成包含代码覆盖率指标的文件。 - 更多信息见 。 - 该选项只适用于 GCC,并且仅在开发工作中使用。 - - - - - - - - - - DTrace - - 启用该选项会将 PostgreSQL 编译为支持动态跟踪工具 - DTrace。更多信息见 。 - - - - 如果要指向 dtrace 程序,可以设置 - 选项。这通常是必要的,因为 - dtrace 往往安装在 /usr/sbin 下, - 而该目录可能不在你的 PATH 中。 - - - - - - - - - 将 PostgreSQL 编译为支持服务器中的注入点。 - 注入点允许在预定义的代码路径中,从服务器内部运行用户定义的代码。 - 这有助于以受控方式测试并研究并发场景。该选项默认关闭。 - 更多细节见 。 - 该选项仅供开发人员测试使用。 - - - - - - - - - 以块数指定关系段大小。如果同时指定了 - 和这个选项,则以后者为准。 - - 该选项仅供开发人员测试与段相关的代码。 - - - - - - - - - - - - 安装后设置 - - - 共享库 - - - 共享库 - - - - 在某些使用共享库的系统上,你需要告诉系统如何找到新安装的共享库。 - 需要这样做的系统包括 - FreeBSD、 - Linux、 - NetBSD、 - OpenBSD 和 - Solaris。 - - - - 设置共享库搜索路径的方法因平台而异,但最常见的方法是按如下方式设置环境变量 - LD_LIBRARY_PATH。对于 Bourne shell - (shkshbash、 - zsh): - -LD_LIBRARY_PATH=/usr/local/pgsql/lib -export LD_LIBRARY_PATH - - 或者对于 cshtcsh: - -setenv LD_LIBRARY_PATH /usr/local/pgsql/lib - - 请把这里的 /usr/local/pgsql/lib 替换为你在 - 中通过 - 设置的值。你应该把这些命令放入 shell 启动文件,例如 - /etc/profile~/.bash_profile。 - 关于这种方法的注意事项,有一些不错的资料可参见 - 。 - - - - 在某些系统上,更好的做法可能是在构建 - 之前 设置环境变量 LD_RUN_PATH。 + 在某些系统上,更好的做法可能是在构建 + 之前 设置环境变量 LD_RUN_PATH @@ -3113,21 +1817,9 @@ export MANPATH 成员机器,以便持续确保兼容性。 - - 一般来说,可以预期 PostgreSQL 能在以下 CPU - 架构上工作:x86、PowerPC、S/390、SPARC、ARM、MIPS 和 RISC-V, - 以及在适用情况下的大端、小端、32 位和 64 位变体。 - + 一般来说,可以预期 PostgreSQL 能在以下 CPU 架构上工作:x86、x86_64、IA64、PowerPC、PowerPC 64、S/390、S/390x、Sparc、Sparc 64、ARM、MIPS、MIPSEL 和 PA-RISC。代码中包含对 M68K、M32R 和 VAX 的支持,但尚不清楚这些架构近期是否经过测试。对于不受支持的 CPU 类型,通常可以通过配置 来构建,但性能会很差。 - - 可以预期 PostgreSQL 能在这些操作系统的当前版本上工作: - Linux、Windows、FreeBSD、OpenBSD、NetBSD、DragonFlyBSD、macOS、Solaris - 和 illumos。其他类 Unix 系统也可能可用,但目前未在测试。 - 大多数情况下,某个操作系统所支持的全部 CPU 架构也都可以工作。 - 尤其是在使用较旧系统时,请查看下面的 - , - 看看是否有针对你的操作系统的特别说明。 - + 可以预期 PostgreSQL 能在以下操作系统上工作:Linux(所有较新的发行版)、Windows(XP 及更高版本)、FreeBSD、OpenBSD、NetBSD、macOS、AIX、HP/UX 和 Solaris。其他类 Unix 系统也可能可用,但目前未在测试。大多数情况下,某个操作系统所支持的全部 CPU 架构也都可以工作。尤其是在使用较旧系统时,请查看下面的 ,看看是否有针对你的操作系统的特别说明。 如果你在某个平台上遇到安装问题,而根据近期构建农场的结果该平台是受支持的, @@ -3135,14 +1827,6 @@ export MANPATH 如果你有兴趣把 PostgreSQL 移植到一个新平台, 那么 pgsql-hackers@lists.postgresql.org 是合适的讨论地点。 - - - 历史版本的 PostgreSQL 或 POSTGRES 也曾运行在 - Alpha、Itanium、M32R、M68K、M88K、NS32K、PA-RISC、SuperH 和 VAX 等 - CPU 架构上,以及 4.3BSD、AIX、BEOS、BSD/OS、DG/UX、Dynix、HP-UX、IRIX、 - NeXTSTEP、QNX、SCO、SINIX、Sprite、SunOS、Tru64 UNIX 和 ULTRIX 等 - 操作系统上。 - @@ -3158,6 +1842,47 @@ export MANPATH 这里未列出的平台,目前没有已知的平台特定安装问题。 + + AIX + + + AIX + 在其上安装 + + + + 你可以使用 GCC,或者 IBM 的原生编译器 xlc, + 在 AIX 上构建 PostgreSQL。 + + + AIX 7.1 之前的版本已不再由 PostgreSQL 社区测试或支持。 + + + 内存管理 + + + AIX 的内存管理方式有些特殊。服务器可能有数 GB 乃至更多的空闲 RAM,但运行应用程序时仍会出现内存不足或地址空间错误。例如,加载扩展可能因不寻常的错误而失败。以下是以 PostgreSQL 安装所有者身份运行的例子: +=# CREATE EXTENSION plperl; +ERROR: could not load library "/opt/dbs/pgsql/lib/plperl.so": A memory address is not in the address space for the process. +以 PostgreSQL 安装所属组中非所有者的成员身份运行: +=# CREATE EXTENSION plperl; +ERROR: could not load library "/opt/dbs/pgsql/lib/plperl.so": Bad address +另一个例子是 PostgreSQL 服务器日志中的内存不足错误,此时每次接近或超过 256 MB 的内存分配都会失败。 + + 这些问题的总体原因是服务器进程使用的默认位数和内存模型。默认情况下,在 AIX 上构建的所有二进制文件都是 32 位的。这与硬件类型或所用内核无关。这些 32 位进程的内存上限为 4 GB,按几种模型之一以 256 MB 的段布局。默认情况下,堆与栈共享一个段,因此堆可用空间不足 256 MB。 + + 对于上面的 plperl 示例,请检查你的 umask 和 PostgreSQL 安装中二进制文件的权限。该示例涉及的二进制文件是 32 位的,安装时使用模式 750 而非 755。由于权限以这种方式设置,只有所有者或所属组的成员可以加载该库。因为它不是所有用户可读,加载器会将该对象放入进程的堆中,而不是通常应放置的共享库段。 + + 这个问题的理想解决办法是使用 64 位构建的 PostgreSQL,但这并非总是可行,因为采用 32 位处理器的系统可以构建 64 位二进制文件,却无法运行它们。 + + 如果需要 32 位二进制文件,请在启动 PostgreSQL 服务器之前,将 LDR_CNTRL 设为 MAXDATA=0xn0000000,其中 1 <= n <= 8,并尝试不同的值及 postgresql.conf 设置,找到能令人满意地工作的配置。这样使用 LDR_CNTRL 会告知 AIX,为服务器的堆预留 MAXDATA 字节,按 256 MB 的段分配。找到可用配置后,可以使用 ldedit 修改二进制文件,使其默认使用所需的堆大小。也可以重新构建 PostgreSQL,传入 configure LDFLAGS="-Wl,-bmaxdata:0xn0000000" 来达到相同效果。 + + 对于 64 位构建,将 OBJECT_MODE 设为 64,并向 configure 传入 CC="gcc -maix64"LDFLAGS="-Wl,-bbigtoc"。(xlc 的选项可能不同。)如果未导出 OBJECT_MODE,构建可能因链接器错误而失败。设置 OBJECT_MODE 后,它会告知 AIX 的 arasld 等构建工具默认处理哪种对象。 + + 默认情况下,可能发生分页空间过量分配。虽然我们尚未见过这种情况,但当内存耗尽且访问了过量分配的空间时,AIX 会终止进程。我们遇到过最接近的情况是,系统认为没有足够内存容纳另一个进程,导致 fork 失败。与 AIX 的许多其他部分一样,如果这成为问题,可以在系统或进程级别配置分页空间分配方式和内存不足时终止进程的行为。 + + + Cygwin @@ -3166,10 +1891,7 @@ export MANPATH 在其上安装 - - 可以使用 Cygwin 这个 Windows 上的类 Linux 环境来构建 PostgreSQL, - 但这种方式不如原生 Windows 构建,且如今已不再推荐在 Cygwin 下运行服务器。 - + 可以使用 Cygwin 这个 Windows 上的类 Linux 环境来构建 PostgreSQL,但这种方式不如原生 Windows 构建(见 ,且如今已不再推荐在 Cygwin 下运行服务器。 从源代码构建时,请按照 Unix 风格的安装过程(也就是 @@ -3185,17 +1907,11 @@ export MANPATH - - 不支持 adduser 命令;请使用 Windows 中相应的 - 用户管理应用。除此之外,跳过这一步即可。 - + 不支持 adduser 命令;请使用 Windows NT、2000 或 XP 中相应的用户管理应用。如果不是这些系统,则跳过此步骤。 - - 不支持 su 命令;请在 Windows 上使用 ssh 来模拟 su。 - 除此之外,跳过这一步即可。 - + 不支持 su 命令;请在 Windows NT、2000 或 XP 上使用 ssh 模拟 su。如果不是这些系统,则跳过此步骤。 @@ -3225,16 +1941,11 @@ export MANPATH - - 并行回归测试(make check)可能会因为 - listen() backlog 队列溢出而产生伪造的回归测试失败, - 进而导致连接拒绝错误或挂起。你可以像下面这样使用 make 变量 - MAX_CONNECTIONS 来限制连接数: + 并行回归测试(make check)可能因 listen() 的待处理连接队列溢出而误报回归测试失败;队列溢出会导致连接被拒绝的错误或挂起。可以使用 make 变量 MAX_CONNECTIONS 限制连接数,方法如下: make MAX_CONNECTIONS=5 check - (在某些系统上,同时连接数大致最多可达到 10 个。) - +(在某些系统上,并发连接数最高可达约 10 个。) @@ -3307,7 +2018,7 @@ xcrun --show-sdk-path macOS 的 - System Integrity Protection(SIP)特性会破坏 + 系统完整性保护(SIP)特性会破坏 make check,因为它会阻止把所需的 DYLD_LIBRARY_PATH 设置传递给被测试的可执行文件。 你可以通过在 make check 之前先执行 @@ -3317,21 +2028,23 @@ xcrun --show-sdk-path - MinGW + MinGW/原生 Windows MinGW 在其上安装 - - 可以使用 MinGW 这个 Windows 上的类 Unix 构建环境来构建 Windows 版 - PostgreSQL。推荐为此使用 MSYS2 环境,并安装所需的前置软件包。 - + Windows 版 PostgreSQL 可以使用 MinGW(用于 Microsoft 操作系统的类 Unix 构建环境)构建,也可以使用 Microsoft 的 Visual C++ 编译器套件构建。MinGW 构建过程使用本章介绍的常规构建系统;Visual C++ 构建方式完全不同,详见 + + 原生 Windows 移植版本要求 32 位或 64 位的 Windows 2000 或更高版本。更早的操作系统没有足够的基础设施(但可以在其上使用 Cygwin)。可以从 下载 MinGW 这一类 Unix 构建工具,以及 MSYS 这一运行 configure 等 shell 脚本所需的 Unix 工具集。运行生成的二进制文件不需要它们;只有创建二进制文件时才需要。 + + 要使用 MinGW 构建 64 位二进制文件,请从 安装 64 位工具集,将其 bin 目录放入 PATH,并使用 --host=x86_64-w64-mingw32 选项运行 configure - - 收集崩溃转储 + 安装好所有组件后,建议在 CMD.EXE 下运行 psql,因为 MSYS 控制台存在缓冲问题。 + + + 在 Windows 上收集崩溃转储 如果 PostgreSQL 在 Windows 上崩溃,它能够生成 @@ -3373,7 +2086,7 @@ xcrun --show-sdk-path 你可以从 下载 Sun Studio。许多 GNU 工具已经集成到 Solaris 10 中, - 或者包含在 Solaris companion CD 中。如果你需要适用于较旧 Solaris 版本的 + 或者包含在 Solaris 配套光盘中。如果你需要适用于较旧 Solaris 版本的 软件包,可以到 查找这些工具。 如果你更想要源码,请看 。 @@ -3381,10 +2094,10 @@ xcrun --show-sdk-path - configure 抱怨测试程序失败 + configure 报告测试程序失败 - 如果 configure 抱怨某个测试程序失败, + 如果 configure 报告某个测试程序失败, 这多半是因为运行时链接器找不到某些库,通常是 libz、libreadline, 或其他非标准库如 libssl。要把它指向正确位置,请在 configure 命令行中设置环境变量 LDFLAGS, @@ -3439,248 +2152,6 @@ make: *** [postgres] Error 1 - - - Visual Studio - - - Visual Studio - 在其上安装 - - - - 建议大多数用户直接下载 Windows 的二进制发行版,它以图形化安装程序的形式发布在 - PostgreSQL 网站上: - 。 - 从源代码构建只适合开发 PostgreSQL - 或扩展的人。 - - - - Windows 上配合 Visual Studio 的 PostgreSQL 可以使用 Meson 构建, - 如 所述。 - 原生 Windows 移植要求 Windows 10 或更高版本的 32 位或 64 位系统。 - - - - 原生构建的 psql 不支持命令行编辑。 - Cygwin 构建支持命令行编辑,因此如果需要在 - Windows 上交互式使用 psql, - 应使用 Cygwin 构建。 - - - - PostgreSQL 可以使用 Microsoft 的 Visual C++ 编译器套件构建。 - 这些编译器可以来自 Visual Studio、 - Visual Studio Express,或某些版本的 - Microsoft Windows SDK。 - 如果你还没有搭建好 Visual Studio 环境, - 最简单的办法是使用 Visual Studio 2022 中的编译器, - 或者 Windows SDK 10 中的编译器; - 它们都可以从 Microsoft 免费下载。 - - - - Microsoft 编译器套件既可以进行 32 位构建,也可以进行 64 位构建。 - 32 位 PostgreSQL 可使用 Visual Studio 2015 到 - Visual Studio 2022 构建,也可使用独立发布的 - Windows SDK 10 及更高版本。64 位 PostgreSQL 构建则支持 - Microsoft Windows SDK 10 及更高版本, - 或 Visual Studio 2015 及更高版本。 - - - - - 如果你的构建环境没有附带受支持版本的 - Microsoft Windows SDK,建议升级到最新版本 - (当前是 10 版),可从 - 下载。 - - - - 你必须始终安装 SDK 中的 - Windows Headers and Libraries 部分。 - 如果你安装的 Windows SDK 包含 - Visual C++ Compilers,那么即使没有 - Visual Studio 也可以完成构建。 - 请注意,自 8.0a 版本起,Windows SDK 已不再附带完整的命令行构建环境。 - - - - 需求 - - 在 Windows 上构建 PostgreSQL 还需要下列附加产品。 - - - - Strawberry Perl - - 运行构建生成脚本需要 Strawberry Perl。MinGW Perl 或 Cygwin Perl 都不行。 - 它还必须位于 PATH 中。二进制文件可从 - 下载。 - - - - - Bison 和 - Flex - - - BisonFlex - 的二进制文件可以从 下载。 - - - - - - - - 下列附加产品虽然不是开始构建所必需的,但要构建完整软件包则需要它们。 - - - - Magicsplat Tcl - - 构建 PL/Tcl 所需。 - 二进制文件可从 - 下载。 - - - - - Diff - - 运行回归测试需要 Diff,可从 - 下载。 - - - - - Gettext - - 构建 NLS 支持需要 Gettext,可从 - 下载。 - 请注意,二进制文件、依赖项和开发文件都需要。 - - - - - MIT Kerberos - - GSSAPI 认证支持所需。MIT Kerberos 可从 - 下载。 - - - - - libxml2 和 - libxslt - - XML 支持所需。二进制文件可从 - 下载, - 源代码可从 下载。 - 请注意,libxml2 需要 iconv,而它也可在同一下载位置获得。 - - - - - LZ4 - - 支持 LZ4 压缩所需。 - 二进制文件和源代码可从 - 下载。 - - - - - Zstandard - - 支持 Zstandard 压缩所需。 - 二进制文件和源代码可从 - 下载。 - - - - - OpenSSL - - SSL 支持所需。二进制文件可从 - 下载, - 源代码可从 下载。 - - - - - ossp-uuid - - UUID-OSSP 支持(仅限 contrib)所需。源代码可从 - 下载。 - - - - - Python - - 构建 PL/Python 所需。 - 二进制文件可从 下载。 - - - - - zlib - - pg_dumppg_restore - 的压缩支持所需。二进制文件可从 下载。 - - - - - - - - - 64 位 Windows 的特别注意事项 - - PostgreSQL 在 64 位 Windows 上只能构建为 x64 架构。 - - - 不支持在同一个构建树中混用 32 位和 64 位版本。 - 构建系统会自动检测自己当前运行在 32 位还是 64 位环境中,并据此构建 PostgreSQL。 - 因此,在开始构建前,启动正确的命令提示符非常重要。 - - - 如果要使用服务器端第三方库,例如 Python 或 - OpenSSL,那么该库也必须 - 是 64 位的。64 位服务器不支持加载 32 位库。PostgreSQL 支持的若干第三方库 - 可能只提供 32 位版本,在这种情况下,它们无法与 64 位 PostgreSQL 一起使用。 - - - - - 收集崩溃转储 - - - 如果 PostgreSQL 在 Windows 上崩溃,它能够生成 - minidumps,可用于追踪崩溃原因, - 类似于 Unix 上的核心转储。这些转储可以使用 - Windows Debugger Tools 或 - Visual Studio 读取。 - 要在 Windows 上启用转储生成,请在集簇数据目录中创建一个名为 - crashdumps 的子目录。随后,转储会以唯一名称写入该目录, - 该名称基于崩溃进程的标识符以及崩溃发生时的当前时间。 - - - diff --git a/zh/15/isn.sgml b/zh/15/isn.sgml index 93e9db55..f470f6b1 100644 --- a/zh/15/isn.sgml +++ b/zh/15/isn.sgml @@ -215,69 +215,53 @@ - make_valid - make_valid ( isn ) - isn + isn_weak + isn_weak ( boolean ) + boolean - 清除该值上的“校验位无效”标记。 + 设置弱输入模式,并返回新的设置值。 - is_valid - is_valid ( isn ) + isn_weak () boolean - 检查该值是否带有“校验位无效”标记。 + 返回弱模式的当前状态。 - isn_weak - isn_weak ( boolean ) - boolean + make_valid + make_valid ( isn ) + isn - 设置弱输入模式,并返回新的设置值。保留此函数是为了向后兼容。推荐通过isn.weak配置参数来设置弱模式。 + 将无效编号变为有效(清除无效标记)。 - isn_weak () + is_valid + is_valid ( isn ) boolean - 返回弱模式的当前状态。保留此函数是为了向后兼容。推荐通过isn.weak配置参数来检查弱模式。 + 检查是否存在无效标记。
- - - 配置参数 - - - - - isn.weak (boolean) - - isn.weak 配置参数 - - - - - isn.weak启用弱输入模式,使得即使 ISN 输入值的校验位有误也会被接受。默认值为false,此时会拒绝无效校验位。 - - - - + + 模式用于允许向表中插入无效数据。这里的“无效”指的是校验位错误,而不是缺少数字。 + 为什么会需要使用弱模式呢?例如,手头可能有一大批 ISBN 编号,数量多到难免会有一些编号因为某些奇怪的原因而带有错误的校验位(也许这些编号是从印刷清单扫描得到的,而 OCR 把数字识别错了;也许这些编号是人工录入的……谁知道呢)。总之,可能想把这些混乱情况清理干净,但同时仍希望先把所有编号都装入数据库,并借助外部工具在数据库中定位无效编号,以便核对信息并更容易完成校验;例如,可能会想把表中所有无效编号都查询出来。 @@ -288,7 +272,7 @@ - 即使未启用弱模式,也可以通过在编号末尾附加!字符来强制插入被标记为无效的编号。 + 即使未启用弱模式,也可以通过在编号末尾附加 ! 字符来强制插入无效编号。 @@ -325,11 +309,11 @@ SELECT issn('3251231?'); SELECT ismn('979047213542?'); --Using the weak mode: -SET isn.weak TO true; +SELECT isn_weak(true); INSERT INTO test VALUES('978-0-11-000533-4'); INSERT INTO test VALUES('9780141219307'); INSERT INTO test VALUES('2-205-00876-X'); -SET isn.weak TO false; +SELECT isn_weak(false); SELECT id FROM test WHERE NOT is_valid(id); UPDATE test SET id = make_valid(id) WHERE id = '2-205-00876-X!'; @@ -355,7 +339,7 @@ SELECT isbn13(id) FROM test; 用于进行连字符分隔的前缀还整理自: - + diff --git a/zh/15/libpq.sgml b/zh/15/libpq.sgml index 9db5f849..345c915f 100644 --- a/zh/15/libpq.sgml +++ b/zh/15/libpq.sgml @@ -41,7 +41,7 @@ - 如果不可信用户能够访问一个没有采用模式的安全使用方式的数据库,那么每个会话开始时都应从search_path中移除公开可写的模式。可以把参数关键词options设置为-csearch_path=。也可以在连接后发出PQexec(conn, "SELECT pg_catalog.set_config('search_path', '', false)")。这种考虑并非专门针对libpq;它适用于每一种可执行任意 SQL 命令的接口。 + 如果不受信任的用户能够访问一个没有采用模式的安全使用方式的数据库,那么每个会话开始时都应从search_path中移除公开可写的模式。可以把参数关键词options设置为-csearch_path=。也可以在连接后发出PQexec(conn, "SELECT pg_catalog.set_config('search_path', '', false)")。这种考虑并非专门针对libpq;它适用于每一种可执行任意 SQL 命令的接口。 @@ -214,7 +214,7 @@ PostgresPollingStatusType PQconnectPoll(PGconn *conn); - hostaddrhost参数必须被合适地使用,以防止做DNS查询。详见中这些参数的文档。 + 必须正确使用 hostaddr 参数,以避免执行 DNS 查询。详细信息请参见中该参数的说明。 @@ -779,7 +779,7 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname 参数关键词 - 目前被识别的参数关键字包括: + 目前被识别的参数关键字包括: @@ -919,93 +919,7 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname - - require_auth - - - 指定客户端要求服务器采用的认证方法。如果服务器没有使用所要求的方法来认证客户端,或者服务器没有完整完成认证握手,则连接将失败。也可以提供一个以逗号分隔的方法列表,此时服务器必须准确使用其中一种方法,连接才会成功。默认情况下接受任意认证方法,并且服务器也可以完全跳过认证。 - - - 可以在方法名前加上!前缀以表示否定,此时服务器不得尝试所列方法;除此之外,任何其他方法都可接受,并且服务器也可以完全不认证客户端。如果提供的是逗号分隔列表,服务器不得尝试其中任何一个被否定的方法。否定形式和非否定形式不能在同一设置中混用。 - - - 最后还有一种特殊情况:none方法要求服务器不使用认证质询。(它也可以被否定,用来要求必须进行某种认证。) - - - 可指定的方法如下: - - - - password - - - 服务器必须请求明文密码认证。 - - - - - - md5 - - - 服务器必须请求 MD5 哈希密码认证。 - - - - 对 MD5 加密密码的支持已被废弃,并将在未来的PostgreSQL版本中移除。关于迁移到其他密码类型的细节,请参见。 - - - - - - - gss - - - 服务器必须通过GSSAPI请求 Kerberos 握手,或者建立一个经过GSS加密的通道(另见)。 - - - - - - sspi - - - 服务器必须请求 Windows SSPI 认证。 - - - - - - scram-sha-256 - - - 服务器必须与客户端成功完成一次 SCRAM-SHA-256 认证交换。 - - - - - - oauth - - - 服务器必须向客户端请求 OAuth Bearer 令牌。 - - - - - none - - - 服务器不得提示客户端执行认证交换。(这并不禁止通过 TLS 进行客户端证书认证,也不禁止通过其加密传输进行 GSS 认证。) - - - - - - - channel_binding @@ -1354,34 +1268,7 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname - - sslnegotiation - - - 如果使用 SSL,此选项控制如何与服务器协商 SSL 加密。在默认的postgres模式下,客户端会先询问服务器是否支持 SSL;在direct模式下,客户端会在建立 TCP/IP 连接后直接开始标准 SSL 握手。传统的PostgreSQL协议协商能兼容更多不同的服务器配置;如果已知服务器支持直接SSL连接,则后一种方式可以减少一次往返,从而降低连接延迟,也允许使用与协议无关的 SSL 网络工具。直接 SSL 选项是在PostgreSQL 17 中引入的。 - - - - - postgres - - - 执行PostgreSQL协议协商。如果未提供该选项,这是默认值。 - - - - - direct - - - 在建立 TCP/IP 连接后直接开始 SSL 握手。仅当sslmode=require或更高时才允许使用该模式,因为更弱的设置可能在服务器不支持直接 SSL 握手时导致意外回退到明文认证。 - - - - - - sslcompression @@ -1429,19 +1316,7 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname - - sslkeylogfile - - - 这个参数指定libpq记录此 SSL 上下文所用密钥的位置。这对于调试PostgreSQL协议交互,或者借助Wireshark之类的网络检查工具分析客户端连接很有用。如果未建立 SSL 连接,或者使用的是LibreSSL(其不支持密钥记录),则会忽略此参数。密钥将按NSS格式记录。 - - - 密钥记录会在 keylog 文件中暴露潜在敏感信息。应当像处理文件一样谨慎处理 keylog 文件。 - - - - - + sslpassword @@ -1468,49 +1343,7 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname - - sslcertmode - - - 此选项决定是否可以向服务器发送客户端证书,以及服务器是否必须请求客户端证书。共有三种模式: - - - - disable - - - 即使客户端有可用证书(默认位置或通过提供),也绝不发送客户端证书。 - - - - - - allow(默认) - - - 如果服务器请求证书且客户端有证书可发,则可以发送证书。 - - - - - - require - - - 服务器必须请求证书。如果客户端没有发送证书而服务器仍成功认证了客户端,则连接将失败。 - - - - - - - - sslcertmode=require不会增加额外的安全性,因为无法保证服务器一定正确验证了证书;PostgreSQL服务器通常无论是否验证,都会向客户端请求 TLS 证书。该选项在排查更复杂的 TLS 配置时可能有用。 - - - - sslrootcert @@ -1617,47 +1450,9 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname - - min_protocol_version - - - 这个参数指定该连接允许的最低协议版本。默认情况下,允许使用 - libpq所支持的任何 - PostgreSQL协议版本, - 目前即3.0。如果服务器至少不支持这一协议版本, - 则连接将被关闭。 - - - 当前支持的值是3.03.2 - 和latestlatest等价于 - 正在使用的libpq版本所支持的最新协议版本, - 目前即3.2。 - - - - - max_protocol_version - - - 这个参数指定要向服务器请求的协议版本。默认会使用 - PostgreSQL协议的3.0版本; - 但如果连接字符串指定了依赖更高协议版本的特性,则会使用 - libpq支持的最新版本。如果服务器不支持客户端请求的协议版本, - 连接会自动降级为服务器支持的较低次版本协议。连接尝试完成后, - 你可以使用PQfullProtocolVersion()来确定 - 最终协商得到的确切协议版本。 - - - 当前支持的值是3.03.2 - 和latestlatest等价于 - 正在使用的libpq版本所支持的最新协议版本, - 目前即3.2。 - - - krbsrvname @@ -1690,32 +1485,11 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname - - gssdelegation - - - 将 GSS 凭证转发(委派)给服务器。默认值为0,表示不向服务器转发凭证。将其设置为1时,会在可能的情况下转发凭证。 - - - - - scram_client_key - - - 以 Base64 编码的 SCRAM client key。外部数据包装器或类似中间件可以利用它启用透传式 SCRAM 认证。一个实现示例见。普通用户或客户端应用不应直接指定它。 - - - - - scram_server_key - - - 以 Base64 编码的 SCRAM server key。外部数据包装器或类似中间件可以利用它启用透传式 SCRAM 认证。一个实现示例见。普通用户或客户端应用不应直接指定它。 - - - + + + service @@ -1797,98 +1571,15 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname - - load_balance_hosts - - - 控制客户端尝试连接可用主机和地址的顺序。一旦某次连接尝试成功,就不会再尝试其他主机和地址。该参数通常与多个主机名或返回多个 IP 地址的 DNS 记录一起使用。它还可以与组合使用,例如只在备库之间进行负载均衡。连接一旦成功建立,随后在返回的连接上发出的所有查询都会发送到同一台服务器。目前有两种模式: - - - - disable(默认) - - - 不在主机之间执行负载均衡。主机会按提供的顺序进行尝试,地址会按从 DNS 或 hosts 文件获得的顺序进行尝试。 - - - - - - random - - - 按随机顺序尝试主机和地址。这个值主要适用于同时打开多个连接的场景,甚至这些连接来自不同机器。这样就可以把连接负载分散到多个PostgreSQL服务器上。 - - - 虽然随机负载均衡由于其随机性几乎不会得到完全均匀的分布,但统计上会相当接近。这里有一个重要点:该算法使用两级随机选择。首先,主机会按随机顺序解析。其次,在解析下一个主机之前,会按随机顺序尝试当前主机解析得到的全部地址。在某些情况下,这种行为会显著偏斜各节点获得的连接数量,例如某些主机解析出的地址比其他主机更多时。但这种偏斜也可以被有意利用,例如通过在主机字符串中多次提供某台更大服务器的主机名,来增加它获得的连接数量。 - - - 使用这个值时,建议同时为配置一个合理的值。这样,如果某个参与负载均衡的节点没有响应,就会继续尝试新的节点。 - - - - - - - - - oauth_issuer - - - 如果服务器为该连接请求 OAuth 令牌,要联系的受信任签发者的 HTTPS URL。所有 OAuth 连接都必须设置此参数;它应当与服务器 HBA 配置中的issuer设置完全一致。 - - - 作为标准认证握手的一部分,libpq会向服务器请求一个发现文档,也就是一个提供一组 OAuth 配置参数的 URL。服务器必须提供一个可由oauth_issuer的各组成部分直接构造出来的 URL,并且该值必须与发现文档自身声明的签发者标识符完全一致,否则连接会失败。这是为了防止 OAuth 客户端遭受一类 - “混淆攻击(mix-up attacks)”。 - - - 你也可以显式把oauth_issuer设置为 OAuth 发现所使用的/.well-known/ URI。在这种情况下,如果服务器要求使用不同的 URL,连接就会失败;不过,自定义 OAuth 流程也许能够通过使用先前缓存的令牌来加速标准握手。(此时也建议设置,因为客户端将没有机会向服务器询问正确的 scope 设置,而令牌的默认 scope 可能不足以完成连接。)libpq当前支持以下 well-known 端点: - - /.well-known/openid-configuration - /.well-known/oauth-authorization-server - - - - - 在 OAuth 连接握手期间,签发者拥有极高的权限。经验法则是:如果你不会信任某个 URL 的运营者来处理你对服务器的访问,或者不会信任其直接冒充你,那么这个 URL 就不应被信任为oauth_issuer。 - - - - - - oauth_client_id - - - 由授权服务器发放的 OAuth 2.0 客户端标识符。如果PostgreSQL服务器为该连接请求 OAuth 令牌,并且没有安装自定义 OAuth 钩子来提供该令牌,那么就必须设置此参数;否则连接会失败。 - - - - - oauth_client_secret - - - 与 OAuth 授权服务器通信时要使用的客户端密码(如果有)。该参数是否必需由 OAuth 提供者决定;“public” 客户端通常不使用 secret,而 “confidential” 客户端通常会使用。 - - - - - oauth_scope - - - 发送给授权服务器的访问请求 scope,以 OAuth scope 标识符的空格分隔列表指定(该列表可以为空)。该参数是可选的,面向高级用法。 - - - 通常客户端会从PostgreSQL服务器获得合适的 scope 设置。如果使用这个参数,服务器请求的 scope 列表会被忽略。这可以防止不那么受信任的服务器向最终用户请求不恰当的访问 scope。不过,如果客户端的 scope 设置不包含服务器所要求的 scope,服务器很可能会拒绝已经签发的令牌,连接也会失败。 - - - 空 scope 列表的含义取决于提供者。OAuth 授权服务器可以选择签发带有“默认 scope”的令牌,不管那具体是什么;也可以完全拒绝该令牌请求。 - - - + + + + + @@ -1955,7 +1646,7 @@ char *PQpass(const PGconn *conn); 将返回连接参数中指定的密码,如果连接参数中没有密码并且能从密码文件中得到密码,则它将返回得到的密码。 - 在后一种情况中,如果连接参数中指定了多个主机,在连接被建立之前都不能依赖的结果。连接的状态可以用函数检查。 + 在后一种情况中,如果连接参数中指定了多个主机,在连接被建立之前都不能依赖的结果。连接的状态可以用函数检查。 @@ -2109,46 +1800,28 @@ PGTransactionStatusType PQtransactionStatus(const PGconn *conn); - 查找服务器的一个当前参数设置。 + 查找服务器某个参数的当前设置。 const char *PQparameterStatus(const PGconn *conn, const char *paramName); - 某一参数值会被服务器在连接开始或值改变时自动报告。可以被用来询问这些设置。它为已知的参数返回当前值,为未知的参数返回NULL。 + 服务器会在连接启动时,以及某些参数值发生变化时,自动报告这些参数值。可用于查询这些设置。如果已知该参数,则返回其当前值;如果未知,则返回NULL - 自当前发布开始会被报告的参数包括 - server_version、 - server_encoding、 - client_encoding、 - application_name、 - default_transaction_read_only, - in_hot_standby, - is_superuser、 - session_authorization、 - DateStyle、 - IntervalStyle、 - TimeZone、 - integer_datetimes以及 - standard_conforming_strings。 - (server_encodingTimeZone以及integer_datetimes在 8.0 以前的发布中不被报告; - standard_conforming_strings在 8.1 以前的发布中不被报告; - IntervalStyle在 8.4 以前的发布中不被报告; - application_name在 9.0 以前的发布中不被报告; - default_transaction_read_onlyin_hot_standby 在14以前的发布中不被报告) - 注意 server_version、 - server_encoding以及 - integer_datetimes在启动之后无法改变。 + 当前版本报告的参数包括: + server_versionserver_encodingclient_encodingapplication_namedefault_transaction_read_onlyin_hot_standbyis_superusersession_authorizationDateStyleIntervalStyleTimeZoneinteger_datetimesstandard_conforming_strings。 + (8.0 之前的版本不报告 server_encodingTimeZoneinteger_datetimes;8.1 之前的版本不报告 standard_conforming_strings;8.4 之前的版本不报告 IntervalStyle;9.0 之前的版本不报告 application_name;14 之前的版本不报告 default_transaction_read_onlyin_hot_standby。) + 注意,server_versionserver_encodinginteger_datetimes 在启动后不能改变。 - 如果没有为standard_conforming_strings报告值,应用能假设它是off,也就是说反斜线会被视为字符串中的转义。还有,这个参数的存在可以被作为转义字符串语法(E'...')被接受的指示。 + 如果服务器未报告standard_conforming_strings的值,应用程序可以假定其为off,即反斜杠在字符串字面量中被视为转义字符。此外,服务器报告此参数也表明它接受转义字符串语法(E'...')。 - 尽管被返回的指针被声明成const,它事实上指向与PGconn结构体相关的可变存储。假定该指针在存储之间保持有效是不明智的。 + 返回的指针虽然被声明为const,但实际上指向与PGconn结构体关联的可变存储。不能假定该指针在执行其他查询后仍然有效。 @@ -2569,7 +2242,7 @@ PGresult *PQexecParams(PGconn *conn, paramTypes[] - 通过 OID 指定要赋予给参数符号的数据类型。如果paramTypesNULL或者该数组中任何特定元素为零,服务器会用对待未知类型文字串的方式为参数符号推测一种数据类型。 + 通过 OID 指定要赋予给参数符号的数据类型。如果paramTypesNULL或者该数组中任何特定元素为零,服务器会用对待未指定类型的字符串字面量的方式为参数符号推测一种数据类型。 @@ -2663,10 +2336,10 @@ PGresult *PQprepare(PGconn *conn, 该函数从query串创建一个名为stmtName的预备语句,该串必须包含一个单一 SQL 命令。 stmtName可以是""来创建一个未命名语句,在这种情况下任何已存在未命名语句将被自动替换。 - 如果语句名称已经在当前会话中被定义,则是一种错误。如果使用了任何参数,它们在查询中以$1$2等引用。 + 否则,如果语句名称已经在当前会话中被定义,则是一种错误。如果使用了任何参数,它们在查询中以$1$2等引用。 nParams是参数的个数,其类型在数组paramTypes[]中被预先指定(当nParams为零时,该数组指针可以是NULL)。 paramTypes[]通过 OID 指定要赋予给参数符号的数据类型。 - 如果paramTypesNULL或者该数组中任何特定元素为零,服务器会用对待未知类型文字串的方式为参数符号推测一种数据类型。 + 如果paramTypesNULL或者该数组中任何特定元素为零,服务器会用对待未指定类型的字符串字面量的方式为参数符号推测一种数据类型。 还有,查询能够使用编号高于nParams的参数符号,它们的数据类型也会被自动推测(找出推测出的数据类型的方法见)。 @@ -2774,47 +2447,9 @@ PGresult *PQdescribePortal(PGconn *conn, const char *portalName); - - PQclosePreparedPQclosePrepared - - - 提交一个请求以关闭指定的预备语句,并等待完成。 - -PGresult *PQclosePrepared(PGconn *conn, const char *stmtName); - - - - - 允许应用程序关闭先前准备好的预备语句。关闭语句会释放它在服务器上的全部相关资源,并允许重复使用其名称。 - - - - stmtName可以是""NULL来引用未命名语句。如果不存在该名称的语句也没有关系;在这种情况下,该操作不会执行任何操作。成功时,会返回一个状态为PGRES_COMMAND_OKPGresult。 - - - - - - PQclosePortalPQclosePortal - - - - 提交一个请求以关闭指定的 portal,并等待完成。 - -PGresult *PQclosePortal(PGconn *conn, const char *portalName); - - - - 允许应用程序关闭先前创建的 portal。关闭 portal 会释放它在服务器上的全部相关资源,并允许重复使用其名称。(libpq不直接提供对 portal 的访问,但你可以使用这个函数来关闭通过DECLARE CURSOR SQL 命令创建的游标。) - - - portalName可以是""NULL来引用未命名的 portal。如果不存在该名称的 portal 也没有关系;在这种情况下,该操作不会执行任何操作。成功时,会返回一个状态为PGRES_COMMAND_OKPGresult。 - - -
@@ -3076,7 +2711,7 @@ char *PQresultErrorField(const PGresult *res, int fieldcode); PG_DIAG_MESSAGE_DETAIL - 细节:一个可选的次级错误消息,它携带了关于问题的等多细节。可能有多行。 + 细节:一个可选的次级错误消息,它携带了关于问题的更多细节。可能有多行。 @@ -3094,7 +2729,7 @@ char *PQresultErrorField(const PGresult *res, int fieldcode); PG_DIAG_STATEMENT_POSITION - 包含一个十进制整数的字符串,它表示一个错误游标位置,该位置是原始语句字符串的索引。第一个字符的索引是 1,位置以字符计算而不是以及字节计算。 + 包含一个十进制整数的字符串,它表示一个错误游标位置,该位置是原始语句字符串的索引。第一个字符的索引是 1,位置以字符计算而不是以字节计算。 @@ -3888,8 +3523,8 @@ unsigned char *PQescapeByteaConn(PGconn *conn,
- 当某些字节值被用作一个SQL语句中的bytea文字的一部分时,它们必须被转义。 - 转义使用十六进制编码或反斜线转义的字节。详见。 + 当某些字节值被用作一个SQL语句中的bytea字面量的一部分时,它们必须被转义。 + 使用十六进制编码或反斜杠转义来转义这些字节。详见 @@ -3939,7 +3574,8 @@ unsigned char *PQescapeBytea(const unsigned char *from, - 将二进制数据的一个字符串表示转换成二进制数据 — 它是的逆向函数。当检索文本格式的bytea数据时,需要这个函数,但检索二进制个事时则不需要它。 + 将二进制数据的字符串表示转换为二进制数据,这是的逆操作。 + 以文本格式取得bytea数据时需要此操作;以二进制格式取得时则不需要。 unsigned char *PQunescapeBytea(const unsigned char *from, size_t *to_length); @@ -3947,14 +3583,15 @@ unsigned char *PQunescapeBytea(const unsigned char *from, size_t *to_length); - from参数指向一个字符串,例如被应用到一个bytea列上所返回的。 - 把这个串表示转换成它的二进制表示。 - 它返回一个指向用malloc()分配的缓冲区的指针,在错误时返回NULL,并且把缓冲区的尺寸放在to_length中。 - 当结果不再需要时,它必须使用释放。 + from参数指向一个字符串,例如对bytea列调用时返回的字符串。 + 将这个字符串表示转换为二进制表示。 + 它返回指向通过malloc()分配的缓冲区的指针,出错时返回NULL,并将缓冲区大小存入to_length。 + 不再需要结果时,必须使用释放它。 - 这种转换并不完全是PQescapeBytea的逆函数,因为当从PQgetvalue接收到字符串时,我们并不能期待它被转义。特别地这意味着不需要考虑字符串引用,并且因此也不需要一个参数。 + 此转换并不完全是的逆操作,因为从收到的字符串并非经过转义的形式。 + 具体而言,这意味着无需考虑字符串引号,因此也不需要PGconn参数。 @@ -4003,26 +3640,13 @@ unsigned char *PQunescapeBytea(const unsigned char *from, size_t *to_length); - - 不喜欢这些限制的应用程序可以使用构建自的底层函数: - 。 - 还有 - , - , - , - , - , - 以及 - , - 它们可以与配合使用,分别复制 - , - , - , - , - , - 和 - - 的功能。 + 如果应用程序不希望受到这些限制,可以改用构成的底层函数:。此外,还有, + , + , + ,以及,它们可以与配合使用,分别实现以下函数的功能:, + , + , + ,以及 @@ -4160,35 +3784,9 @@ int PQsendDescribePortal(PGconn *conn, const char *portalName); - - PQsendClosePreparedPQsendClosePrepared - - - - 提交一个关闭指定预备语句的请求,而不等待完成。 - -int PQsendClosePrepared(PGconn *conn, const char *stmtName); - - - 这是的异步版本:如果成功分派请求则返回 1,否则返回 0。调用成功后,使用获取结果。其参数处理方式与相同。 - - - - - PQsendClosePortalPQsendClosePortal - - - 提交一个关闭指定 portal 的请求,而不等待完成。 - -int PQsendClosePortal(PGconn *conn, const char *portalName); - - 这是的异步版本:如果成功分派请求则返回 1,否则返回 0。调用成功后,使用获取结果。其参数处理方式与相同。 - - - @@ -4473,68 +4071,46 @@ int PQflush(PGconn *conn); - 发出查询 - 进入管道模式后,应用程序使用或其姊妹函数来分派请求。 - 这些请求在客户端排队,直到刷新到服务器端;当使用建立管道中的同步点时,或者调用时,会发生这种情况。 - 函数在管道模式下也可以工作。 - 结果处理如下所述。 + 进入管道模式后,应用程序使用 或其处理预备查询的对应函数 发送请求。这些请求在客户端排队,直到发送到服务器;使用 在管道中建立同步点,或调用 时会发送它们。函数 、&zwsp; 也可用于管道模式。结果处理方式见下文。 - 服务器执行语句,并返回结果,按客户端发送它们的顺序。 - 服务器将立即开始执行管道中的命令,不等待管道的结束。 - 注意,结果被缓冲在服务器端;当使用PQpipelineSync建立同步点时,或者PQsendFlushRequest被调用时,服务器会刷新该缓冲区。 - 如果任何语句遇到错误,服务器将中止当前事务,并且不执行队列中的任何后续命令,直到下一个同步点;对于每一个这样的命令都会产生一个PGRES_PIPELINE_ABORTED结果。 - (即使管道中的命令将回滚事务,依然如此。) - 查询处理在同步点之后恢复。 + 服务器按客户端发送的顺序执行语句并返回结果。服务器会立即开始执行管道中的命令,无需等待管道结束。结果会缓存在服务器端;使用 PQpipelineSync 建立同步点,或调用 PQsendFlushRequest 时,服务器会发送该缓冲区中的数据。如果任何语句发生错误,服务器会中止当前事务,并停止执行队列中的后续命令,直到下一个同步点;每条被跳过的命令都会产生一个 PGRES_PIPELINE_ABORTED 结果。(即使管道中的命令会回滚事务,也仍然如此。)到达同步点后,查询处理恢复。 - 一个操作依赖于前一个操作的结果是没问题的; - 例如,一个查询可以定义一个同一管道中的下一个查询将用到的表。 - 类似地,应用可以创建一个命名的预备语句,并在同一管道中与后续语句一起执行它。 + 一个操作可以依赖先前操作的结果;例如,一个查询可以定义一张表,供同一管道中的下一个查询使用。类似地,应用程序可以创建命名的预备语句,并通过同一管道中后续的语句执行它。 - 处理结果 - 为了在管道中处理一个查询的结果,应用重复调用PQgetResult并处理每个结果,直到PQgetResult返回空。 - 可以再次使用PQgetResult检索管道中下一个查询的结果,并且循环重复 - 应用像通常一样处理单个语句结果。 - 当管道中所有查询的结果都返回时,PQgetResult返回一个结果,其包含状态值PGRES_PIPELINE_SYNC。 + 要处理管道中一个查询的结果,应用程序应重复调用 PQgetResult 并处理每个结果,直到 PQgetResult 返回空指针。然后再次调用 PQgetResult 获取管道中下一个查询的结果,重复这一过程。应用程序按通常方式处理各条语句的结果。当管道中所有查询的结果都已返回时,PQgetResult 会返回一个包含状态值 PGRES_PIPELINE_SYNC 的结果。 - 客户端可以选择延迟结果处理,直到完整的管道被发送,或者与管道中发送的更多的查询交错在一起;参见。 + 客户端可以等到整条管道发送完毕后再处理结果,也可以在继续发送管道中的查询时交错处理结果;参见 - 要进入单行模式,在使用PQgetResult检索结果之前调用PQsetSingleRowMode。 - 此模式选择仅对当前处理的查询有效。 - 有关使用PQsetSingleRowMode的更多信息,请参阅。 + 要进入单行模式,应在使用 PQgetResult 获取结果之前调用 PQsetSingleRowMode。该模式选择仅对当前正在处理的查询有效。关于 PQsetSingleRowMode 的更多信息,参见 - PQgetResult行为与普通异步处理相同,除了它可能包含新的PGresult类型PGRES_PIPELINE_SYNCPGRES_PIPELINE_ABORTED。 - 对于每个在管道中相应的点的PQpipelineSyncPGRES_PIPELINE_SYNC确定报告一次。 - PGRES_PIPELINE_ABORTED在第一个错误和所有后续结果的正常查询结果中发出,直到下一个PGRES_PIPELINE_SYNC;参见。 + PQgetResult 的行为与普通异步处理相同,只是返回结果可能具有新的 PGresult 类型 PGRES_PIPELINE_SYNCPGRES_PIPELINE_ABORTED。对于每次 PQpipelineSync 调用,都会在管道中的对应位置恰好报告一次 PGRES_PIPELINE_SYNC。对于第一个错误及其后的所有结果,会用 PGRES_PIPELINE_ABORTED 代替正常查询结果,直到下一个 PGRES_PIPELINE_SYNC;参见 - PQisBusyPQconsumeInput、等正常操作,在处理管道结果时。 - 特别是,在管道中间调用PQisBusy 时,如果到目前为止发出的所有查询的结果都已被消耗,则返回0。 + PQisBusyPQconsumeInput 等函数在处理管道结果时照常工作。特别地,在管道处理过程中调用 PQisBusy 时,如果到目前为止已发出查询的所有结果均已被消费,则返回 0。 - libpq不向应用提供有关当前正在处理的查询的任何信息(除了PQgetResult返回空,以表示我们开始返回下一个查询的结果)。 - 应用必须保持跟踪它发送查询的顺序,以将它们与相应的结果相关联。 - 应用通常会为此使用状态机或FIFO队列。 + libpq 不向应用程序提供当前正在处理哪个查询的信息(除了 PQgetResult 返回空指针,表示开始返回下一个查询的结果)。应用程序必须跟踪查询的发送顺序,以便将查询与对应结果关联起来。应用程序通常会使用状态机或 FIFO 队列实现这一点。 @@ -4581,7 +4157,7 @@ int PQflush(PGconn *conn); 客户端应用通常应该维护一个尚未分派的工作队列和一个已分派但尚未处理结果的工作队列。 当套接字是可写时,它将可以分派更多的工作。 当套接字是可读时,它将读取结果并处理它们,将它们匹配到相应结果队列中的下一个条目。 - 基于可用内存,来自套接字的结果将被经常读取:这里不需要等到管道结束才读取结果。 + 基于可用内存,来自套接字的结果将被经常读取:这里不需要等到管道结束才读取结果。 管道将范围涵盖到工作的逻辑单元,通常(但不是必然)每个管道一个事务。 在管道之间,不需要退出管道模式再重新进入管道模式,也不需要等待一个管道结束后再发送下一个。 @@ -4612,7 +4188,7 @@ PGpipelineStatus PQpipelineStatus(const PGconn *conn); - PQpipelineStatus 可以返回下列值中的一个: + PQpipelineStatus 可以返回下列值中的一个: @@ -4720,22 +4296,7 @@ int PQpipelineSync(PGconn *conn); - - PQsendPipelineSyncPQsendPipelineSync - - - - 通过发送sync message但不刷新发送缓冲区,来标记管道中的一个同步点。它可作为隐式事务的分界符和错误恢复点;参见。 - -int PQsendPipelineSync(PGconn *conn); - - - - 成功时返回 1。如果连接不处于管道模式,或者发送sync message失败,则返回 0。请注意,该消息本身不会自动刷新到服务器;必要时请使用PQflush。 - - - @@ -4756,8 +4317,8 @@ int PQsendFlushRequest(PGconn *conn); - 当PQpipelineSync被调用的结果,或者在非管道模式下的任何请求时,服务器自动刷新它的输出缓冲区;这个函数用于使得服务器在不建立同步点的情况下以管道模式刷新其输出缓冲区。 - 请注意,请求不是自身能自动刷新到服务器;如果需要时使用PQflush。 + 当PQpipelineSync被调用的结果,或者在非管道模式下的任何请求时,服务器自动刷新它的输出缓冲区;这个函数用于使得服务器在不建立同步点的情况下以管道模式刷新其输出缓冲区。 + 请注意,请求不是自身能自动刷新到服务器;如果需要时使用PQflush @@ -4777,7 +4338,7 @@ int PQsendFlushRequest(PGconn *conn); 当服务器比较远,即网络延迟(ping time)高的时候,管道模式最有用,以及在许多小操作正在快速连续执行的时候。 当每个查询的执行时间是客户端/服务器往返时间的许多倍时,使用管道命令的优势通常会更少。 - 不用管道模式,在往返时间为300毫秒的服务器上运行一个100条语句的操作,仅网络延迟就需要30秒;使用管道,等待来自服务器的结果可能只消耗仅仅0.3秒。 + 不用管道模式,在往返时间为300毫秒的服务器上运行一个100条语句的操作,仅网络延迟就需要30秒;使用管道,等待来自服务器的结果可能只消耗仅仅0.3秒。 @@ -4788,7 +4349,7 @@ int PQsendFlushRequest(PGconn *conn); 当来自一个操作的信息需要客户端产生下一个操作时,管道模式是没有用的。 在这种情况下,客户机将不得不引入一个同步点,并等待完整的客户端/服务器往返以获取它需要的结果。 但是,通常可以调整客户端设计以交换服务器端所需的信息。 - 读-修改-写循环是非常好的选择;例如: + 读-修改-写循环是非常好的选择;例如: BEGIN; SELECT x FROM mytable WHERE id = 42 FOR UPDATE; @@ -4797,7 +4358,7 @@ SELECT x FROM mytable WHERE id = 42 FOR UPDATE; UPDATE mytable SET x = 3 WHERE id = 42; COMMIT; - 可以更有效地开展以下工作: + 可以更有效地开展以下工作: UPDATE mytable SET x = x + 1 WHERE id = 42; @@ -4810,29 +4371,18 @@ UPDATE mytable SET x = x + 1 WHERE id = 42; - 分块检索查询结果 - - - libpq - single-row mode - + 逐行检索查询结果 libpq - chunked mode + 单行模式 - - 通常,libpq会收集一条 SQL 命令的完整结果,并将其作为单个PGresult返回给应用程序。对于返回大量行的命令,这可能并不适用。对于这类情况,应用程序可以将用于单行模式分块模式。在这些模式下,结果行会在从服务器收到时立即返回给应用程序;单行模式每次返回一行,分块模式则每次返回一组行。 - + 通常,libpq 会收集一条 SQL 命令的完整结果,并将其作为单个 PGresult 返回给应用程序。对于返回大量行的命令,这种方式可能不可行。在这种情况下,应用程序可以在单行模式下使用 。此模式在从服务器收到结果行时,每次将一行返回给应用程序。 - - 要进入这些模式之一,请在成功调用(或其兄弟函数)后立即调用。这种模式选择只对当前正在执行的查询生效。然后按所述,反复调用直到其返回空指针。如果查询返回了任何行,这些行会作为一个或多个PGresult对象返回。它们看起来与普通查询结果相同,只是状态码在单行模式下为PGRES_SINGLE_TUPLE,在分块模式下为PGRES_TUPLES_CHUNK,而不是PGRES_TUPLES_OK。每个PGRES_SINGLE_TUPLE对象恰好包含一行结果,而PGRES_TUPLES_CHUNK对象至少包含一行、至多包含指定的每块行数。最后一行之后,或者如果查询返回零行,则会返回一个状态为PGRES_TUPLES_OK且不含行的对象,表示不会再有更多行到达。(但请注意,仍然必须继续调用直到其返回空指针。)所有这些PGresult对象都会包含与普通查询结果相同的行描述数据(列名、类型等)。每个对象在使用完之后都应像往常一样通过释放。 - + 要进入单行模式,请在成功调用 (或其同类函数)后,立即调用 。此模式选择仅对当前正在执行的查询生效。然后按照 所述,反复调用 ,直到返回空指针。如果查询返回了行,每一行都作为独立的 PGresult 对象返回。这些对象看起来与普通查询结果相同,只是状态码为 PGRES_SINGLE_TUPLE,而不是 PGRES_TUPLES_OK。最后一行之后,或者查询返回零行时立即返回一个不含行、状态为 PGRES_TUPLES_OK 的对象,表示不会再有更多行到达。(但注意,仍然必须继续调用 ,直到返回空指针。)所有这些 PGresult 对象都包含与该查询普通 PGresult 对象相同的行描述数据(列名、类型等)。每个对象都应像往常一样使用 释放。 - - 在使用管道模式时,必须在用PQgetResult提取该查询结果之前,为管道中的每个查询分别激活单行模式或分块模式。更多信息见。 - + 在使用管道模式时,必须在用 PQgetResult 获取某个查询的结果之前,为管道中的该查询激活单行模式。更多信息见 @@ -4853,31 +4403,11 @@ int PQsetSingleRowMode(PGconn *conn); - - - PQsetChunkedRowsModePQsetChunkedRowsMode - - - - 为当前正在执行的查询选择分块模式。 - - -int PQsetChunkedRowsMode(PGconn *conn, int chunkSize); - - - - - 该函数与类似,不同之处在于它指定每个PGresult最多返回chunkSize行,而不一定只返回一行。此函数也只能在调用或其某个兄弟函数之后立即调用,并且必须在该连接上执行任何其他操作之前调用,例如。如果调用时机正确,该函数会为当前查询激活分块模式并返回 1;否则模式保持不变并返回 0。无论如何,当前查询结束后都会恢复为普通模式。 - - - - - 在处理一个查询的过程中,服务器可能先返回一些行,然后遇到错误并中止该查询。通常,libpq会丢弃这些行,只报告错误。但在单行模式或分块模式下,部分行可能已经返回给应用程序。因此,应用程序可能会先看到一些PGRES_SINGLE_TUPLEPGRES_TUPLES_CHUNKPGresult对象,然后再看到一个PGRES_FATAL_ERROR对象。为了获得正确的事务语义,如果查询最终失败,应用程序必须能丢弃或撤销之前对这些已处理行所做的操作。 - + 处理查询时,服务器可能先返回一些行,然后遇到错误,导致查询中止。通常,libpq 会丢弃这些行,只报告错误。但在单行模式下,这些行已经返回给了应用程序。因此,应用程序会先看到一些 PGRES_SINGLE_TUPLE PGresult 对象,随后看到一个 PGRES_FATAL_ERROR 对象。为了保证正确的事务行为,如果查询最终失败,应用程序必须能够丢弃或撤销此前对这些行所做的全部操作。 @@ -4886,287 +4416,16 @@ int PQsetChunkedRowsMode(PGconn *conn, int chunkSize); 取消进行中的查询 - canceling SQL queries - - - query cancellation + 取消 + SQL 命令 - - 发送取消请求的函数 - - - PQcancelCreatePQcancelCreate - - - - 准备用于发送取消请求的连接。 - -PGcancelConn *PQcancelCreate(PGconn *conn); - - - - - 创建一个PGcancelConnPGcancelConn对象,但不会立即通过这条连接发送取消请求。可以使用以阻塞方式发送取消请求,或者使用以非阻塞方式发送。返回值可以传给,以检查该PGcancelConn对象是否成功创建。PGcancelConn是不透明结构,不应由应用程序直接访问。它可用于以线程安全的方式取消原始连接上正在执行的查询。 - - - - 在为取消请求建立连接时,会重用原始客户端连接的许多连接参数。特别是,如果原始连接要求对连接进行加密和/或验证目标主机(通过sslmodegssencmode),则取消请求连接也会使用同样的要求。不过,仅在客户端认证期间或认证后才会用到的连接选项会被忽略,因为取消请求不需要认证,并且提交取消请求后该连接就会立即关闭。 - - - - 请注意,当PQcancelCreate返回非空指针时,你必须在使用完毕后调用,以释放该结构及其关联内存块。即使取消请求失败或被放弃,也必须这样做。 - - - - - - PQcancelBlockingPQcancelBlocking - - - - 以阻塞方式请求服务器放弃处理当前命令。 - -int PQcancelBlocking(PGcancelConn *cancelConn); - - - - - 请求通过给定的PGcancelConn发送,该对象必须由创建。成功分派取消请求时返回 1,否则返回 0。若失败,可通过获取错误信息。 - - - - 取消请求成功分派并不保证一定会产生效果。如果取消成功,被取消的命令会提前终止并返回一个错误结果;如果取消失败(例如服务器已经处理完该命令),则不会有任何可见结果。 - - - - - - PQcancelStartPQcancelStart - PQcancelPollPQcancelPoll - - - - 以非阻塞方式请求服务器放弃处理当前命令。 - -int PQcancelStart(PGcancelConn *cancelConn); - -PostgresPollingStatusType PQcancelPoll(PGcancelConn *cancelConn); - - - - - 请求通过给定的PGcancelConn发送,该对象必须由创建。能够启动取消请求时返回 1,否则返回 0。若失败,可通过获取错误信息。 - - - - 如果PQcancelStart成功,下一阶段就是轮询libpq,使其继续推进取消连接序列。使用获取底层套接字描述符。(注意:不要假定该套接字在多次调用PQcancelPoll之间保持不变。)循环规则如下:如果PQcancelPoll(cancelConn)上一次返回PGRES_POLLING_READING,就等待该套接字准备好可读(由select()poll()或类似系统函数指示),然后再次调用PQcancelPoll(cancelConn)。反之,如果其上一次返回PGRES_POLLING_WRITING,就等待套接字准备好可写,然后再次调用。第一次迭代时,也就是尚未调用过PQcancelPoll(cancelConn)时,按其上次返回PGRES_POLLING_WRITING来处理。持续这一循环,直到PQcancelPoll(cancelConn)返回PGRES_POLLING_FAILED,表示连接过程失败,或者返回PGRES_POLLING_OK,表示取消请求已成功分派。 - - - - 取消请求成功分派并不保证一定会产生效果。如果取消成功,被取消的命令会提前终止并返回一个错误结果;如果取消失败(例如服务器已经处理完该命令),则不会有任何可见结果。 - - - - 在连接期间的任意时刻,都可以通过调用检查取消连接的状态。如果返回CONNECTION_BAD,则取消过程失败;如果返回CONNECTION_OK,则取消请求已成功分派。这两种状态同样可以从前面描述的PQcancelPoll返回值中检测到。其他状态也可能仅在异步取消过程中出现,它们表示连接过程的当前阶段,并可能有助于向用户提供反馈。这些状态如下: - - - - CONNECTION_ALLOCATED - - - 等待调用以真正打开套接字。这是刚调用之后的连接状态。此时尚未开始与服务器建立连接。要真正开始发送取消请求,请使用。 - - - - - - CONNECTION_STARTED - - - 等待连接建立。 - - - - - - CONNECTION_MADE - - - 连接正常,等待发送。 - - - - - - CONNECTION_AWAITING_RESPONSE - - - 等待服务器响应。 - - - - - - CONNECTION_SSL_STARTUP - - - 协商 SSL 加密。 - - - - - - CONNECTION_GSS_STARTUP - - - 协商 GSS 加密。 - - - - - - 请注意,尽管这些常量会继续保留(为了保持兼容性),应用程序也绝不应依赖它们按某个特定顺序出现,甚至不应依赖它们一定会出现,或者依赖状态值始终属于这些已记录的取值之一。应用程序可以这样写: - -switch(PQcancelStatus(conn)) -{ - case CONNECTION_STARTED: - feedback = "Connecting..."; - break; - - case CONNECTION_MADE: - feedback = "Connected to server..."; - break; -. -. -. - default: - feedback = "Connecting..."; -} - - - - - 在使用PQcancelPoll时,连接参数connect_timeout会被忽略;是否已经过去过长时间应由应用程序自行判断。除此之外,PQcancelStart后接PQcancelPoll循环,等效于。 - - - - - - PQcancelStatusPQcancelStatus - - - - 返回取消连接的状态。 - -ConnStatusType PQcancelStatus(const PGcancelConn *cancelConn); - - - - - 该状态可以是多种取值之一。不过,在异步取消过程之外只能看到三种:CONNECTION_ALLOCATEDCONNECTION_OKCONNECTION_BAD。使用成功创建的PGcancelConn初始状态为CONNECTION_ALLOCATED。成功分派取消请求后状态为CONNECTION_OK;取消失败则表现为CONNECTION_BAD。处于 OK 状态时,会一直保持到调用。 - - - - 其他可能返回的状态代码,请参见条目。 - - - - 取消请求成功分派并不保证一定会产生效果。如果取消成功,被取消的命令会提前终止并返回一个错误结果;如果取消失败(例如服务器已经处理完该命令),则不会有任何可见结果。 - - - - - - PQcancelSocketPQcancelSocket - - - - 获取到服务器的取消连接套接字的文件描述符编号。 - -int PQcancelSocket(const PGcancelConn *cancelConn); - - - - - 有效描述符将大于等于 0;结果为 -1 表示当前没有打开到服务器的连接。对该PGcancelConn调用本节中的任意函数(PQcancelSocket自身除外)都可能改变这一状态。 - - - - - - - PQcancelErrorMessagePQcancelErrorMessage - error messagein PGcancelConn - - - - - 返回最近一次针对取消连接执行操作时生成的错误消息。 - -char *PQcancelErrorMessage(const PGcancelConn *cancelconn); - - - - - 几乎所有接受PGcancelConn参数的libpq函数在失败时都会为设置消息。按照libpq的约定,非空的结果可能包含多行,并带有结尾换行符。调用者不应直接释放该结果;当关联的PGcancelConn句柄传给时,它会被释放。也不应假定该结果字符串在多次对PGcancelConn结构执行操作之间保持不变。 - - - - - - PQcancelFinishPQcancelFinish - - - 关闭取消连接(如果它尚未完成发送取消请求),同时释放PGcancelConn对象使用的内存。 - -void PQcancelFinish(PGcancelConn *cancelConn); - - - - - 请注意,即使取消尝试失败(由指示),应用程序也应调用来释放PGcancelConn对象使用的内存。在调用后,不得再次使用该PGcancelConn指针。 - - - - - - PQcancelResetPQcancelReset - - - 重置PGcancelConn,以便将其重新用于新的取消连接。 - -void PQcancelReset(PGcancelConn *cancelConn); - - - - - 如果PGcancelConn当前正用于发送取消请求,则会关闭该连接。随后它会将PGcancelConn对象重新准备好,使其能够用于发送新的取消请求。 - - - - 这使得可以为一个PGconn创建一个PGcancelConn,并在原始PGconn的整个生命周期中重复使用它。 - - - - - - - - 发送取消请求的过时函数 - - - 这些函数代表较旧的取消请求发送方式。虽然它们仍然可以工作,但由于即使原始连接通过sslmodegssencmode要求加密,它们发送取消请求时也不会以加密方式进行,因此已被废弃。因此,强烈不建议在新代码中继续使用这些旧方法,已有代码也建议迁移到新的函数。 - - - + 客户端应用程序可以使用本节介绍的函数,请求取消服务器仍在处理的命令。 PQgetCancelPQgetCancel - - 创建一个数据结构,其中包含使用取消命令所需的信息。 - + 创建一个数据结构,其中包含取消通过特定数据库连接发出的命令所需的信息。 PGcancel *PQgetCancel(PGconn *conn); @@ -5238,7 +4497,7 @@ int PQrequestCancel(PGconn *conn); - +
@@ -5296,7 +4555,7 @@ typedef struct
- 要传递NULL参数到函数,将参数结构体的len字段设置为-1;isintu 字段就不相关了。 + 要传递NULL参数到函数,将参数结构体的len字段设置为-1isintu 字段就不相关了。 @@ -5553,7 +4812,7 @@ int PQgetCopyData(PGconn *conn, 当async为真时(非零),将不会阻塞等待输入; 如果COPY仍在处理过程中并且没有可用的完整行,那么它将返回零 (在这种情况下等待读准备好,然后在再次调用之前,调用)。 - 当async为假(零)时,PQgetCopyData将阻塞,直到数据可用或者操作完成。 + 当async为假(零)时,将阻塞,直到数据可用或者操作完成。 @@ -5853,7 +5112,7 @@ void PQtrace(PGconn *conn, FILE *stream); - 每行包括:一个可选的时间戳,一个方向指示器(F表示从客户端到服务器的消息或B表示从服务器到客户端的消息),消息长度、消息类型、和消息内容。 + 每行包括:一个可选的时间戳,一个方向指示器(F表示从客户端到服务器的消息或B表示从服务器到客户端的消息),消息长度、消息类型、和消息内容。 非消息内容字段(时间戳、方向、长度和消息类型)由一个制表符分隔。 消息内容用空格分隔。 协议字符串用双引号括起来,而用作数据值的字符串用单引号括起来。 @@ -5994,27 +5253,7 @@ char *PQencryptPasswordConn(PGconn *conn, const char *passwd, const char *user, - - PQchangePasswordPQchangePassword - - - 修改一个PostgreSQL密码。 - -PGresult *PQchangePassword(PGconn *conn, const char *user, const char *passwd); - - 此函数使用PQencryptPasswordConn构造并执行ALTER USER ... PASSWORD '...'命令,从而更改该用户的密码。它存在的原因与PQencryptPasswordConn相同,但更方便,因为它会替你同时构造并执行命令。传给的算法参数是NULL,因此会按照服务器的设置进行加密。 - - - - userpasswd参数分别是目标用户的 SQL 名称以及新的明文密码。 - - - - 返回一个表示ALTER USER命令结果的PGresult指针;如果例程在发出任何命令前就失败,则返回空指针。应调用检查返回值中是否有错误(包括空指针的情况,此时它会返回PGRES_FATAL_ERROR)。可使用获取更多错误信息。 - - - @@ -6027,7 +5266,7 @@ PGresult *PQchangePassword(PGconn *conn, const char *user, const char *passwd); char *PQencryptPassword(const char *passwd, const char *user); - 的一个较老的已经被废弃的版本。其差别是不要求一个连接对象,并且总是用md5作为加密算法。 + 的旧版本,现已弃用。其差别是不需要连接对象,并且总是用md5作为加密算法。 @@ -6047,11 +5286,12 @@ PGresult *PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status); 这是libpq内部用于分配并初始化一个空PGresult对象的函数。 - 如果不能分配内存,那么这个函数返回NULL。 - 它也是可以对外使用的,因为一些应用认为它可以用于产生结果对象(特别是带有错误状态的对象)本身。 - 如果conn非空,并且status表示一个错误,那么指定连接的当前错误消息会被复制到PGresult中。 - 如果conn非空,那么连接中的任何已注册事件过程也会被复制到PGresult中(它们不会获得PGEVT_RESULTCREATE调用,但会看到)。 - 注意在该对象上最终应该调用,正如对libpq本身返回的PGresult对象所作的那样。 + 如果无法分配内存,此函数返回NULL。 + 将它导出供外部调用,是因为一些应用需要自行生成结果对象,特别是带有错误状态的对象。 + 如果conn非空,并且status表示错误,指定连接的当前错误消息会被复制到PGresult中。 + 此外,如果conn非空,连接中注册的所有事件过程也会被复制到PGresult中。 + (这些过程不会收到PGEVT_RESULTCREATE调用,但可参见。) + 注意,最终应对该对象调用,就像处理libpq自身返回的PGresult一样。 @@ -6411,8 +5651,8 @@ typedef struct - 结果创建事件是响应任何生成结果的查询执行函数而触发的,包括 - 。此事件只会在结果成功创建后触发。 + 任何生成结果的查询执行函数都会触发结果创建事件,其中包括。 + 只有成功创建结果后才会触发该事件。 typedef struct @@ -6422,11 +5662,9 @@ typedef struct } PGEventResultCreate; - 当接收到PGEVT_RESULTCREATE事件时, - 应将evtInfo指针转换为 - PGEventResultCreate *。 - conn是用于生成结果的连接。 - 这是初始化需要与结果关联的任何instanceData的理想位置。 + 收到PGEVT_RESULTCREATE事件时,应将evtInfo指针转换为PGEventResultCreate *。 + 其中,conn是用于生成结果的连接。 + 这是初始化需要与结果关联的instanceData的理想位置。 如果事件过程失败(返回零),那么该事件过程将在结果的剩余生命周期内被忽略; 也就是说,它将不会接收到针对此结果或从中复制的结果的 PGEVT_RESULTCOPYPGEVT_RESULTDESTROY事件。 @@ -7195,20 +6433,15 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough) - 用户的主目录中的文件.pgpass可以包含密码, - 如果连接需要密码(且未指定其他密码)。在Microsoft Windows中, - 该文件的名称为%APPDATA%\postgresql\pgpass.conf - (其中%APPDATA%指用户配置文件中的应用数据子目录)。 - 或者,可以使用连接参数 - 或环境变量PGPASSFILE指定要使用的密码文件。 - + 用户主目录中的.pgpass文件可保存密码,供连接需要密码且尚未通过其他方式指定密码时使用。在 Microsoft Windows 上,文件名为%APPDATA%\postgresql\pgpass.conf(其中%APPDATA%指用户配置文件中的应用数据子目录)。也可以通过连接参数或环境变量PGPASSFILE指定要使用的密码文件。 + 这个文件应该包含下列格式的行: hostname:port:database:username:password - (你可以向该文件增加一个提醒:把上面的行复制到该文件并且在前面加上#)。前四个域的每一个都可以是文字值或者匹配任何东西的*。第一个匹配当前连接参数的行中的密码域将被使用(因此,在使用通配符时把更特殊的项放在前面)。如果一个条目需要包含:或者\,用\对该字符转义。如果指定了host连接参数,主机名字段会被匹配到host,否则如果指定了hostaddr参数则匹配到hostaddr,如果两者都没有给出,则会搜索主机名localhost。当连接是一个Unix域套接字连接并且host参数匹配libpq的默认套接字目录路径时,也会搜索主机名localhost。在一台备库上,值为replication的数据库字段匹配连接到主库的流复制连接。否则数据库字段的用途有限,因为用户对同一个集簇中的所有数据库都有相同的密码。 + (你可以向该文件增加一个提醒:把上面的行复制到该文件并且在前面加上#)。前四个字段的每一个都可以是字面值或者匹配任何东西的*。第一个匹配当前连接参数的行中的密码字段将被使用(因此,在使用通配符时把更特殊的项放在前面)。如果一个条目需要包含:或者\,用\对该字符转义。如果指定了host连接参数,主机名字段会被匹配到host,否则如果指定了hostaddr参数则匹配到hostaddr,如果两者都没有给出,则会搜索主机名localhost。当连接是一个Unix域套接字连接并且host参数匹配libpq的默认套接字目录路径时,也会搜索主机名localhost。在一台备库上,值为replication的数据库字段匹配连接到主库的流复制连接。否则数据库字段的用途有限,因为用户对同一个集簇中的所有数据库都有相同的密码。 @@ -7645,7 +6878,7 @@ ldap://ldap.acme.com/cn=dbserver,cn=hosts?pgconnectinfo?base?(objectclass=*) 构建时带有SSL支持,您应该调用告诉libpq libssl和/或libcrypto库已被您的应用程序初始化,以便 libpq不会再初始化这些库。 - 但是,当使用OpenSSL版本1.1.0或更高版本时,重复初始化不再成问题。 + 但是,当使用OpenSSL版本1.1.0或更高版本时,无需这样做,因为重复初始化不再成问题。 @@ -7669,7 +6902,7 @@ void PQinitOpenSSL(int do_ssl, int do_crypto); - 如果你的应用使用并且初始化OpenSSL或者它的底层libcrypto库,你必须在第一次打开数据库连接前以合适的非零参数调用这个函数。 + 如果你的应用使用并且初始化OpenSSL或者它的底层libcrypto库,你必须在第一次打开数据库连接前调用这个函数,并把相应参数设为零。 同时要确保在打开一个数据库连接前已经完成了初始化。 @@ -7702,240 +6935,17 @@ void PQinitSSL(int do_ssl); - - OAuth 支持 - - - libpq通过一个可选模块实现了对 OAuth v2 Device Authorization 客户端流程的支持,该流程记录在 - RFC 8628中。关于如何启用内置的 Device Authorization 流程,请参见安装文档。 - - - 当启用支持并安装该可选模块后,如果服务器在认证期间请求 Bearer 令牌,libpq默认会使用内置流程。即使运行客户端应用的系统没有可用的 Web 浏览器,例如通过SSH运行客户端时,也可以使用这一流程。 - - - 内置流程默认会打印一个需要访问的 URL 以及一个要在该处输入的用户代码: - -$ psql 'dbname=postgres oauth_issuer=https://example.com oauth_client_id=...' -Visit https://example.com/device and enter the code: ABCD-EFGH - - (这一提示可以被定制。)然后,用户将在其 OAuth 提供者处登录,提供者会询问是否允许 libpq 和服务器代表其执行操作。在继续之前,始终应当仔细检查显示的 URL 和权限,确认它们符合预期。不要向不受信任的第三方授予权限。 - - - 客户端应用可以实现自己的流程,以定制交互方式以及与应用程序的集成。关于如何向libpq添加自定义流程的更多信息,请参见。 - - - 要使某个 OAuth 客户端流程可用,连接字符串至少必须包含。(这些设置由你所在组织的 OAuth 提供者决定。)此外,内置流程还要求 OAuth 授权服务器发布一个设备授权端点。 - - - - - 当前 Windows 上尚不支持内置的 Device Authorization 流程。不过,仍然可以实现自定义客户端流程。 - - - - - Authdata 钩子 - - - 客户端可以通过下面的钩子 API 修改或替换 OAuth 流程的行为: - - - - PQsetAuthDataHookPQsetAuthDataHook - - - - 设置PGauthDataHook,以覆盖libpq对其 OAuth 客户端流程一个或多个方面的处理。 - -void PQsetAuthDataHook(PQauthDataHook_type hook); - - 如果hookNULL,则会重新安装默认处理器。否则,应用程序需要传入一个回调函数指针,其签名如下: - -int hook_fn(PGauthData type, PGconn *conn, void *data); - - 当应用程序需要执行某个动作时,libpq会调用该回调。type描述所提出的请求,conn是正在认证的连接句柄,而data指向该请求特有的元数据。这个指针所指内容由type决定;支持的列表见。 - - - 钩子可以串联起来,以支持协作式和/或回退式行为。一般来说,钩子实现应检查传入的type(以及可能的请求元数据和/或当前conn的设置),以决定是否处理某一项 authdata。如果不处理,则应把请求委托给链中的前一个钩子(可通过PQgetAuthDataHook获取)。 - - - 返回一个大于零的整数表示成功。返回负整数表示发生错误并放弃此次连接尝试。(值零保留给默认实现。) - - - - - - PQgetAuthDataHookPQgetAuthDataHook - - - - 获取当前的PGauthDataHook值。 - -PQauthDataHook_type PQgetAuthDataHook(void); - - 在初始化阶段(即首次调用PQsetAuthDataHook之前),该函数会返回PQdefaultAuthDataHook。 - - - - - - - - 钩子类型 - - 下面定义了这些PGauthData类型及其对应的data结构: - - - - - PQAUTHDATA_PROMPT_OAUTH_DEVICE - PQAUTHDATA_PROMPT_OAUTH_DEVICE - - - - 在内置的设备授权客户端流程期间,替换默认的用户提示。data指向一个PGpromptOAuthDevice实例: - -typedef struct _PGpromptOAuthDevice -{ - const char *verification_uri; /* verification URI to visit */ - const char *user_code; /* user code to enter */ - const char *verification_uri_complete; /* optional combination of URI and - * code, or NULL */ - int expires_in; /* seconds until user code expires */ -} PGpromptOAuthDevice; - - - - 可被包含在libpq中的 OAuth Device Authorization 流程要求最终用户使用浏览器访问一个 URL,然后输入一个代码,以允许libpq代表其连接到服务器。默认提示只是把verification_uriuser_code打印到标准错误。替换实现可以按任意偏好的方式展示这些信息,例如使用 GUI。 - - - 该回调只会在内置设备授权流程中被调用。如果应用程序安装了自定义 OAuth 流程,或者libpq构建时未启用内置流程支持,则不会使用这种 authdata 类型。 - - - 如果提供了非空的verification_uri_complete,则可以选择把它用于非文本形式的验证(例如显示二维码)。在这种情况下,仍应向最终用户显示 URL 和用户代码,因为该代码需要由提供者手工确认,而 URL 也使得用户在无法使用非文本方式时仍可继续。更多信息见 - RFC 8628 第 3.3.1 节。 - - - - - - - PQAUTHDATA_OAUTH_BEARER_TOKEN - PQAUTHDATA_OAUTH_BEARER_TOKEN - - - - 添加一个自定义流程实现;如果内置流程已安装,则用它替换内置流程。该钩子应当要么直接返回一个适用于当前 user/issuer/scope 组合的 Bearer 令牌(如果能在不阻塞的情况下获得),要么设置一个异步回调来获取令牌。 - - - data指向一个PGoauthBearerRequest实例,应该由实现填充: - -typedef struct PGoauthBearerRequest -{ - /* Hook inputs (constant across all calls) */ - const char *openid_configuration; /* OIDC discovery URL */ - const char *scope; /* required scope(s), or NULL */ - /* Hook outputs */ - - /* - * Callback implementing a custom asynchronous OAuth flow. The signature is - * platform-dependent: PQ_SOCKTYPE is SOCKET on Windows, and int everywhere - * else. - */ - PostgresPollingStatusType (*async) (PGconn *conn, - struct PGoauthBearerRequest *request, - PQ_SOCKTYPE *altsock); - - /* Callback to clean up custom allocations. */ - void (*cleanup) (PGconn *conn, struct PGoauthBearerRequest *request); - - char *token; /* acquired Bearer token */ - void *user; /* hook-defined allocated data */ -} PGoauthBearerRequest; - - - - libpq会向该钩子提供两项信息:openid_configuration包含描述授权服务器所支持流程的 OAuth 发现文档 URL,而scope包含访问服务器所需的 OAuth scope 列表(以空格分隔,可以为空)。两者中的任意一个或两个都可能为NULL,表示无法发现该信息。(在这种情况下,实现可以通过其他预先配置的知识来确定要求,或者选择失败。) - - - 该钩子的最终输出是token,它必须指向一个可在该连接上使用的有效 Bearer 令牌。(该令牌应由所指定的发行者签发,并持有所请求的 scope,否则连接会被服务器的验证器模块拒绝。)分配得到的令牌字符串必须在libpq完成连接之前始终有效;该钩子应设置cleanup回调,以便在libpq不再需要该令牌时调用。 - - - 如果某个实现无法在首次调用钩子时立即产生token,则应设置async回调,以处理与授权服务器之间的非阻塞通信。 - - - 在PQAUTHDATA_OAUTH_BEARER_TOKEN钩子回调中执行阻塞操作,会干扰诸如PQconnectPoll之类的非阻塞连接 API,并阻止并发连接继续推进。那些只使用同步连接原语(例如PQconnectdb)的应用程序,可以在钩子中同步获取令牌,而不是实现async回调,但这样它们必然一次只能处理一个连接。 - - - 从钩子返回后,将立即调用该回调以启动流程。当回调在不阻塞的情况下无法继续推进时,它应在设置*altsock后返回PGRES_POLLING_READINGPGRES_POLLING_WRITING,其中*altsock是当可以再次取得进展时会被标记为可读/可写的文件描述符。(然后,这个描述符会通过PQsocket()提供给顶层轮询循环。)当流程完成时,在设置好token之后返回PGRES_POLLING_OK;如果失败,则返回PGRES_POLLING_FAILED。 - - - 实现可能希望在多次调用asynccleanup回调之间保存额外的数据用于记账。为此提供了user指针;libpq不会触碰其内容,应用程序可以按自己的需要使用它。(记得在令牌清理时释放相关分配。) - - - - - - - - - - 调试与开发者设置 - - - 通过设置环境变量PGOAUTHDEBUG=UNSAFE,可以启用一种危险的调试模式。该功能仅用于便于本地开发和测试。它会做一些你绝不会希望生产系统去做的事情: - - - - - 允许在与 OAuth 提供者交互期间使用未加密的 HTTP - - - - - 允许使用环境变量PGOAUTHCAFILE完全替换系统受信任的 CA 列表 - - - - - 在 OAuth 流程期间把 HTTP 流量(其中包含多个关键机密)打印到标准错误 - - - - - 允许使用零秒重试间隔,这可能导致客户端忙等并无谓地消耗 CPU - - - - - - - 不要把 OAuth 流量的输出分享给第三方。它包含可被用来攻击你的客户端和服务器的机密。 - - - - 在线程化程序中的行为 - threads - with libpq + 线程 + 用于 libpq - - 从版本 17 起,libpq始终是可重入且线程安全的。不过仍有一条限制:不得有两个线程同时操作同一个PGconn对象。特别是,不能从不同线程通过同一个连接对象并发发出命令。(如果需要并发运行命令,请使用多个连接。) - - - - PGresult对象在创建后通常是只读的,因此可以在线程之间自由传递。不过,如果你使用中描述的任何会修改PGresult的函数,则需要自行避免对同一个PGresult执行并发操作。 - - - - 在较早版本中,libpq能否提供线程支持取决于编译选项。下面这个函数允许查询libpq的线程安全状态: - + libpq 默认是可重入且线程安全的。编译应用程序代码时,可能需要使用特殊的编译器命令行选项。有关如何构建支持线程的应用程序,请参阅系统文档,或查看 src/Makefile.global 中的 PTHREAD_CFLAGSPTHREAD_LIBS。以下函数可用于查询 libpq 的线程安全状态: @@ -7950,22 +6960,22 @@ int PQisthreadsafe(); - 如果libpq是线程安全的则返回 1,否则返回 0。在版本 17 及以上始终返回 1。 + 如果libpq是线程安全的则返回 1,否则返回 0。 - - 已废弃的函数不是线程安全的,不应在多线程程序中使用。可以用替代;可以用替代。 - + 线程使用的一项限制是:两个线程不能同时操作同一个 PGconn 对象。尤其不能通过同一个连接对象从不同线程并发发出命令。(如果需要并发执行命令,请使用多个连接。) - 如果你在应用程序中使用 Kerberos(除了libpq内部之外),则需要在 Kerberos 调用周围加锁,因为 Kerberos 函数不是线程安全的。可参考libpq源代码中的PQregisterThreadLock函数,它提供了一种在libpq与应用程序之间协作加锁的方法。 + PGresult对象在创建后通常是只读的,因此可以在线程之间自由传递。不过,如果你使用中描述的任何会修改PGresult的函数,则需要自行避免对同一个PGresult执行并发操作。 + 已弃用的 函数不是线程安全的,不应在多线程程序中使用。可以用 替代 ,用 替代 + - 同样地,如果你在应用程序中使用Curl,并且在启动新线程之前还没有先对 libcurl 进行全局初始化,那么你也需要通过PQregisterThreadLock协作地为任何可能初始化 libcurl 的代码加锁。对于支持线程安全初始化的较新版本Curl,这一限制已被解除;这类构建可以通过其版本元数据中声明的threadsafe特性识别出来。 + 如果你在应用程序中使用 Kerberos(除了libpq内部之外),则需要在 Kerberos 调用周围加锁,因为 Kerberos 函数不是线程安全的。可参考libpq源代码中的PQregisterThreadLock函数,它提供了一种在libpq与应用程序之间协作加锁的方法。 diff --git a/zh/15/logical-replication.sgml b/zh/15/logical-replication.sgml index 4b5b448d..f0891caf 100644 --- a/zh/15/logical-replication.sgml +++ b/zh/15/logical-replication.sgml @@ -93,6 +93,10 @@ )。 + + 已发布的表必须配置了复制标识,才能复制UPDATEDELETE操作,以便在订阅端能够识别要更新或删除的对应行。默认情况下,使用主键(如果有的话)。也可以将另一个唯一索引(有一些额外要求)设置为复制标识。如果表没有任何合适的键,则可以将其复制标识设置为full,这意味着整行都成为键。但这样做效率很低,只应在无其他方案时作为后备使用。如果在发布端设置了full以外的复制标识,则订阅端也必须设置包含相同或更少列的复制标识。关于如何设置复制标识的详细信息,见。如果一个没有复制标识的表被添加到了可复制UPDATEDELETE操作的发布中,后续的UPDATEDELETE操作将在发布端产生错误。无论复制标识如何,INSERT操作都可以正常进行。 + + 每个发布都可以有多个订阅者。 @@ -110,48 +114,6 @@ 都是事务性的,因此事务提交后,表会在正确的快照点开始或停止复制。 - - 复制标识 - - - 已发布的表若要复制 UPDATE 和 - DELETE 操作,必须配置 - 复制标识,以便在订阅端识别应更新或删除的行。 - - - - 默认情况下,如果存在主键,则主键就是复制标识。也可以将另一个唯一索引 - (满足某些附加要求)设置为复制标识。如果表没有合适的键,可将复制标识设为 - FULL,表示整行作为键。指定复制标识 - FULL 时,订阅端在查找行时可以使用索引。 - 候选索引必须是 btree 或 hash、非部分索引,且最左索引字段必须是引用已发布表 - 列的列(而非表达式)。这些非唯一索引属性的限制,遵循了主键的一部分限制规则。 - 如果没有合适索引,订阅端查找会非常低效,因此复制标识 - FULL 仅应在没有其他方案时作为后备选项。 - - - - 如果发布端设置的是非 FULL 的复制标识,则订阅端也必须设置 - 由相同或更少列组成的复制标识。 - - - - 对于复制标识定义为 NOTHING、无主键时的 - DEFAULT,或使用已删除索引的 USING INDEX - 的表,如果将其包含在复制 UPDATE 或 - DELETE 的发布中,则不支持这些操作。尝试执行时会在发布端报错。 - - - - 无论复制标识如何,INSERT 操作都可以继续执行。 - - - - 关于如何设置复制标识,见 - ALTER TABLE...REPLICA IDENTITY。 - - - @@ -214,13 +176,7 @@ - 表列也按名称匹配。订阅端表的列顺序无需与发布端一致。只要数据的文本表示可转换 - 为目标类型,列数据类型也无需一致。例如,可从 integer 列复制到 - bigint 列。目标表还可包含发布表未提供的额外列,这些列会填充为目标 - 表定义中的默认值。不过,二进制格式逻辑复制限制更严格。详见 - CREATE SUBSCRIPTION 的 - binary - 选项。 + 表的列也按名称匹配。订阅端表中列的顺序无需与发布端匹配。列的数据类型也无需匹配,只要数据的文本表示可以转换为目标类型即可。例如,可以从integer类型的列复制到bigint类型的列。目标表也可以有已发布表未提供的额外列。这些额外列将用目标表定义中指定的默认值填充。 @@ -230,7 +186,7 @@ 如前所述,每个(活动)订阅都从远端(发布侧)的一个复制槽接收变更。 - 额外的表同步槽通常是临时的,由系统内部创建用于执行初始表同步,在不再需要时 + 额外的表同步槽通常只会短暂存在,由系统内部创建用于执行初始表同步,在不再需要时 自动删除。这些表同步槽的名称是自动生成的: pg_%u_sync_%u_%llu (参数分别为:订阅 oid、 @@ -238,9 +194,9 @@ 通常,远端复制槽会在使用 - CREATE SUBSCRIPTION + CREATE SUBSCRIPTION 创建订阅时自动创建,并在使用 - DROP SUBSCRIPTION + DROP SUBSCRIPTION 删除订阅时自动删除。但在某些场景下,分别操作订阅与底层复制槽会更有用或更必要。 常见场景如下: @@ -265,7 +221,7 @@ 删除订阅时希望保留复制槽。这在将订阅者数据库迁移到其他主机并从那里激活时 很有用。此时应在尝试删除订阅前,使用 - ALTER SUBSCRIPTION + ALTER SUBSCRIPTION 将槽与订阅解除关联。 @@ -285,65 +241,81 @@ - 示例:建立逻辑复制 + 示例 在发布端创建一些测试表。 -/* pub # */ CREATE TABLE t1(a int, b text, PRIMARY KEY(a)); -/* pub # */ CREATE TABLE t2(c int, d text, PRIMARY KEY(c)); -/* pub # */ CREATE TABLE t3(e int, f text, PRIMARY KEY(e)); +test_pub=# CREATE TABLE t1(a int, b text, PRIMARY KEY(a)); +CREATE TABLE +test_pub=# CREATE TABLE t2(c int, d text, PRIMARY KEY(c)); +CREATE TABLE +test_pub=# CREATE TABLE t3(e int, f text, PRIMARY KEY(e)); +CREATE TABLE 在订阅端创建同样的表。 -/* sub # */ CREATE TABLE t1(a int, b text, PRIMARY KEY(a)); -/* sub # */ CREATE TABLE t2(c int, d text, PRIMARY KEY(c)); -/* sub # */ CREATE TABLE t3(e int, f text, PRIMARY KEY(e)); +test_sub=# CREATE TABLE t1(a int, b text, PRIMARY KEY(a)); +CREATE TABLE +test_sub=# CREATE TABLE t2(c int, d text, PRIMARY KEY(c)); +CREATE TABLE +test_sub=# CREATE TABLE t3(e int, f text, PRIMARY KEY(e)); +CREATE TABLE 在发布端向表中插入数据。 -/* pub # */ INSERT INTO t1 VALUES (1, 'one'), (2, 'two'), (3, 'three'); -/* pub # */ INSERT INTO t2 VALUES (1, 'A'), (2, 'B'), (3, 'C'); -/* pub # */ INSERT INTO t3 VALUES (1, 'i'), (2, 'ii'), (3, 'iii'); +test_pub=# INSERT INTO t1 VALUES (1, 'one'), (2, 'two'), (3, 'three'); +INSERT 0 3 +test_pub=# INSERT INTO t2 VALUES (1, 'A'), (2, 'B'), (3, 'C'); +INSERT 0 3 +test_pub=# INSERT INTO t3 VALUES (1, 'i'), (2, 'ii'), (3, 'iii'); +INSERT 0 3 为这些表创建发布。发布 pub2pub3a 禁用了部分 - publish + publish 操作。发布 pub3b 使用了行过滤器(见 )。 - 5); -]]> + +test_pub=# CREATE PUBLICATION pub1 FOR TABLE t1; +CREATE PUBLICATION +test_pub=# CREATE PUBLICATION pub2 FOR TABLE t2 WITH (publish = 'truncate'); +CREATE PUBLICATION +test_pub=# CREATE PUBLICATION pub3a FOR TABLE t3 WITH (publish = 'truncate'); +CREATE PUBLICATION +test_pub=# CREATE PUBLICATION pub3b FOR TABLE t3 WHERE (e > 5); +CREATE PUBLICATION + 为这些发布创建订阅。订阅 sub3 同时订阅 pub3apub3b。默认情况下所有订阅都会复制 初始数据。 -/* sub # */ CREATE SUBSCRIPTION sub1 -/* sub - */ CONNECTION 'host=localhost dbname=test_pub application_name=sub1' -/* sub - */ PUBLICATION pub1; -/* sub # */ CREATE SUBSCRIPTION sub2 -/* sub - */ CONNECTION 'host=localhost dbname=test_pub application_name=sub2' -/* sub - */ PUBLICATION pub2; -/* sub # */ CREATE SUBSCRIPTION sub3 -/* sub - */ CONNECTION 'host=localhost dbname=test_pub application_name=sub3' -/* sub - */ PUBLICATION pub3a, pub3b; +test_sub=# CREATE SUBSCRIPTION sub1 +test_sub-# CONNECTION 'host=localhost dbname=test_pub application_name=sub1' +test_sub-# PUBLICATION pub1; +CREATE SUBSCRIPTION +test_sub=# CREATE SUBSCRIPTION sub2 +test_sub-# CONNECTION 'host=localhost dbname=test_pub application_name=sub2' +test_sub-# PUBLICATION pub2; +CREATE SUBSCRIPTION +test_sub=# CREATE SUBSCRIPTION sub3 +test_sub-# CONNECTION 'host=localhost dbname=test_pub application_name=sub3' +test_sub-# PUBLICATION pub3a, pub3b; +CREATE SUBSCRIPTION 注意,无论发布的 publish 操作如何,初始表数据都会被复制。 -/* sub # */ SELECT * FROM t1; +test_sub=# SELECT * FROM t1; a | b ---+------- 1 | one @@ -351,7 +323,7 @@ 3 | three (3 rows) -/* sub # */ SELECT * FROM t2; +test_sub=# SELECT * FROM t2; c | d ---+--- 1 | A @@ -365,7 +337,7 @@ pub3a 没有行过滤器,所以复制后的表 t3 会包含所有行,即使它们不匹配发布 pub3b 的行过滤器。 -/* sub # */ SELECT * FROM t3; +test_sub=# SELECT * FROM t3; e | f ---+----- 1 | i @@ -377,15 +349,18 @@ 在发布端向表继续插入数据。 -/* pub # */ INSERT INTO t1 VALUES (4, 'four'), (5, 'five'), (6, 'six'); -/* pub # */ INSERT INTO t2 VALUES (4, 'D'), (5, 'E'), (6, 'F'); -/* pub # */ INSERT INTO t3 VALUES (4, 'iv'), (5, 'v'), (6, 'vi'); +test_pub=# INSERT INTO t1 VALUES (4, 'four'), (5, 'five'), (6, 'six'); +INSERT 0 3 +test_pub=# INSERT INTO t2 VALUES (4, 'D'), (5, 'E'), (6, 'F'); +INSERT 0 3 +test_pub=# INSERT INTO t3 VALUES (4, 'iv'), (5, 'v'), (6, 'vi'); +INSERT 0 3 现在发布端数据如下: -/* pub # */ SELECT * FROM t1; +test_pub=# SELECT * FROM t1; a | b ---+------- 1 | one @@ -396,7 +371,7 @@ 6 | six (6 rows) -/* pub # */ SELECT * FROM t2; +test_pub=# SELECT * FROM t2; c | d ---+--- 1 | A @@ -407,7 +382,7 @@ 6 | F (6 rows) -/* pub # */ SELECT * FROM t3; +test_pub=# SELECT * FROM t3; e | f ---+----- 1 | i @@ -422,10 +397,10 @@ 注意在常规复制阶段会使用相应的 publish 操作。 这意味着发布 pub2pub3a 不会复制 - INSERT。另外,发布 pub3b 只会复制与其 + INSERT。另外,发布 pub3b 只会复制与 pub3b 的 行过滤器匹配的数据。现在订阅端数据如下: -/* sub # */ SELECT * FROM t1; +test_sub=# SELECT * FROM t1; a | b ---+------- 1 | one @@ -436,7 +411,7 @@ 6 | six (6 rows) -/* sub # */ SELECT * FROM t2; +test_sub=# SELECT * FROM t2; c | d ---+--- 1 | A @@ -444,7 +419,7 @@ 3 | C (3 rows) -/* sub # */ SELECT * FROM t3; +test_sub=# SELECT * FROM t3; e | f ---+----- 1 | i @@ -455,259 +430,11 @@ - - 示例:延迟创建复制槽 - - 在某些场景(例如 - )中,如果远端复制槽未自动创建, - 用户必须在订阅激活前手工创建。下面示例展示了创建槽并激活订阅的步骤。 - 这些示例指定了标准逻辑解码输出插件 pgoutput,这是内置逻辑复制 - 使用的插件。 - - - 首先,创建示例所需的发布。 - -/* pub # */ CREATE PUBLICATION pub1 FOR ALL TABLES; - - - 示例 1:订阅指定 connect = false - - - - - - 创建订阅。 - -/* sub # */ CREATE SUBSCRIPTION sub1 -/* sub - */ CONNECTION 'host=localhost dbname=test_pub' -/* sub - */ PUBLICATION pub1 -/* sub - */ WITH (connect=false); -WARNING: subscription was created, but is not connected -HINT: To initiate replication, you must manually create the replication slot, enable the subscription, and refresh the subscription. - - - - - 在发布端手工创建槽。由于 CREATE SUBSCRIPTION 时未指定名称, - 要创建的槽名与订阅名相同,例如 "sub1"。 - -/* pub # */ SELECT * FROM pg_create_logical_replication_slot('sub1', 'pgoutput'); - slot_name | lsn ------------+----------- - sub1 | 0/19404D0 -(1 row) - - - - - 在订阅端完成订阅激活。之后 pub1 的表将开始复制。 - -/* sub # */ ALTER SUBSCRIPTION sub1 ENABLE; -/* sub # */ ALTER SUBSCRIPTION sub1 REFRESH PUBLICATION; - - - - - - - 示例 2:订阅指定 connect = false,并同时指定 - slot_name - 选项。 - - - - 创建订阅。 - -/* sub # */ CREATE SUBSCRIPTION sub1 -/* sub - */ CONNECTION 'host=localhost dbname=test_pub' -/* sub - */ PUBLICATION pub1 -/* sub - */ WITH (connect=false, slot_name='myslot'); -WARNING: subscription was created, but is not connected -HINT: To initiate replication, you must manually create the replication slot, enable the subscription, and refresh the subscription. - - - - - 在发布端使用与 CREATE SUBSCRIPTION 指定一致的名称手工创建槽, - 例如 "myslot"。 - -/* pub # */ SELECT * FROM pg_create_logical_replication_slot('myslot', 'pgoutput'); - slot_name | lsn ------------+----------- - myslot | 0/19059A0 -(1 row) - - - - - 在订阅端,剩余激活步骤与前例相同。 - -/* sub # */ ALTER SUBSCRIPTION sub1 ENABLE; -/* sub # */ ALTER SUBSCRIPTION sub1 REFRESH PUBLICATION; - - - - - - - 示例 3:订阅指定 slot_name = NONE - - - - 创建订阅。设置 slot_name = NONE 时,还需要设置 - enabled = falsecreate_slot = false。 - -/* sub # */ CREATE SUBSCRIPTION sub1 -/* sub - */ CONNECTION 'host=localhost dbname=test_pub' -/* sub - */ PUBLICATION pub1 -/* sub - */ WITH (slot_name=NONE, enabled=false, create_slot=false); - - - - - 在发布端使用任意名称手工创建槽,例如 "myslot"。 - -/* pub # */ SELECT * FROM pg_create_logical_replication_slot('myslot', 'pgoutput'); - slot_name | lsn ------------+----------- - myslot | 0/1905930 -(1 row) - - - - - 在订阅端,将订阅关联到刚创建的槽名。 - -/* sub # */ ALTER SUBSCRIPTION sub1 SET (slot_name='myslot'); - - - - - 剩余的订阅激活步骤与前例相同。 - -/* sub # */ ALTER SUBSCRIPTION sub1 ENABLE; -/* sub # */ ALTER SUBSCRIPTION sub1 REFRESH PUBLICATION; - - - - - - - 逻辑复制故障切换 - - - 为了让订阅节点在发布节点宕机后仍能继续从发布端复制数据,发布节点必须有对应的 - 物理备库。创建订阅时指定 failover = true,即可将主库上与 - 订阅对应的逻辑槽同步到备库。详情见 - 。 - 启用 - failover - 参数可确保备库提升后这些订阅无缝切换,并继续订阅新主库上的发布。 - - - - 由于槽同步逻辑是异步复制,在发生故障切换前,必须确认复制槽已经同步到备库。 - 为确保故障切换成功,备库必须领先于订阅端。可通过配置 - synchronized_standby_slots 实现。 - - - - 要确认某个订阅对应的备库确实已做好故障切换准备,请按下列步骤验证该订阅需要的 - 所有逻辑复制槽都已同步到备库: - - - - - 在订阅节点上,使用以下 SQL 识别应同步到计划提升的备库的复制槽。 - 该查询返回启用故障切换的订阅对应的复制槽。 - -/* sub # */ SELECT - array_agg(quote_literal(s.subslotname)) AS slots - FROM pg_subscription s - WHERE s.subfailover AND - s.subslotname IS NOT NULL; - slots -------- - {'sub1','sub2','sub3'} -(1 row) - - - - - 在订阅节点上,使用以下 SQL 识别应同步到计划提升备库的表同步槽。 - 此查询需要在每个包含启用故障切换订阅的数据库中执行。 - 注意只有在表复制完成时,表同步槽才应同步到备库(见 - )。 - 在其他场景下无需确保表同步槽已同步,因为这些情况下它们会在新主库上被删除或重建。 - -/* sub # */ SELECT - array_agg(quote_literal(slot_name)) AS slots - FROM - ( - SELECT CONCAT('pg_', srsubid, '_sync_', srrelid, '_', ctl.system_identifier) AS slot_name - FROM pg_control_system() ctl, pg_subscription_rel r, pg_subscription s - WHERE r.srsubstate = 'f' AND s.oid = r.srsubid AND s.subfailover - ); - slots -------- - {'pg_16394_sync_16385_7394666715149055164'} -(1 row) - - - - - 检查上面识别出的逻辑复制槽是否存在于备库上,并且已准备好故障切换。 - -/* standby # */ SELECT slot_name, (synced AND NOT temporary AND invalidation_reason IS NULL) AS failover_ready - FROM pg_replication_slots - WHERE slot_name IN - ('sub1','sub2','sub3', 'pg_16394_sync_16385_7394666715149055164'); - slot_name | failover_ready ---------------------------------------------+---------------- - sub1 | t - sub2 | t - sub3 | t - pg_16394_sync_16385_7394666715149055164 | t -(4 rows) - - - - - - 如果所有槽都存在于备库,且上述 SQL 查询结果 - (failover_ready)为 true,则现有订阅可以继续订阅新主库上的发布。 - - - - 上述步骤中的前两步针对的是 PostgreSQL 订阅端。 - 建议在每次故障切换后,都在将由目标备库服务的各个订阅节点上执行这两步,以获得完整的复制槽 - 列表,然后在第 3 步中统一验证故障切换就绪状态。 - 非 PostgreSQL 订阅端则可使用其自身方法识别各自订阅使用的复制槽。 - - - - 在某些场景(如计划内故障切换)中,需要确认所有订阅端(无论是否为 - PostgreSQL)在切换到某个备库后都能继续复制。 - 这种情况下,可用下列 SQL(而不是执行前两步)识别主库上需要同步到目标备库并准备 - 提升的复制槽。该查询返回所有启用故障切换订阅对应的复制槽。 - - - - -/* primary # */ SELECT array_agg(quote_literal(r.slot_name)) AS slots - FROM pg_replication_slots r - WHERE r.failover AND NOT r.temporary; - slots -------- - {'sub1','sub2','sub3', 'pg_16394_sync_16385_7394666715149055164'} -(1 row) - - 行过滤器 @@ -726,7 +453,7 @@ HINT: To initiate replication, you must manually create the replication slot, e 行过滤器会在发布更改之前应用。如果行过滤器求值为falseNULL, 则该行不会被复制。WHERE子句表达式会使用复制连接所用的同一角色来求值(即在 - CONNECTION + CONNECTION 子句中指定的角色)。行过滤器对TRUNCATE命令没有影响。 @@ -815,7 +542,7 @@ HINT: To initiate replication, you must manually create the replication slot, e 分区表 - 如果发布包含分区表,则发布参数publish_via_partition_root确定使用哪个行过滤器。 + 如果发布包含分区表,则发布参数publish_via_partition_root确定使用哪个行过滤器。 如果publish_via_partition_roottrue,则使用根分区表的行过滤器。 否则,如果publish_via_partition_rootfalse(默认值),则使用各个分区的行过滤器。 @@ -840,7 +567,7 @@ HINT: To initiate replication, you must manually create the replication slot, e - 由于初始数据同步在复制现有表数据时不会考虑publish参数, + 由于初始数据同步在复制现有表数据时不会考虑publish参数, 因此有些使用 DML 时本不会复制的行,也可能在此阶段被复制。参见 ,并查看 中的示例。 @@ -862,7 +589,7 @@ HINT: To initiate replication, you must manually create the replication slot, e 组合多个行过滤器 - 如果某个订阅包含多个发布,而其中同一张表针对相同的publish操作使用了不同的行过滤器, + 如果某个订阅包含多个发布,而其中同一张表针对相同的publish操作使用了不同的行过滤器, 那么这些表达式会按 OR 组合,因此满足任意一个表达式的行都会被复制。这意味着,如果出现以下任一情况,那么同一张表上的其他所有行过滤器都会变得多余: @@ -872,12 +599,12 @@ HINT: To initiate replication, you must manually create the replication slot, e - 其中某个发布是使用FOR ALL TABLES创建的。该子句不允许行过滤器。 + 其中某个发布是使用FOR ALL TABLES创建的。该子句不允许行过滤器。 - 其中某个发布是使用FOR TABLES IN SCHEMA创建的,并且该表属于所引用的模式。该子句不允许行过滤器。 + 其中某个发布是使用FOR TABLES IN SCHEMA创建的,并且该表属于所引用的模式。该子句不允许行过滤器。 @@ -892,54 +619,60 @@ HINT: To initiate replication, you must manually create the replication slot, e 创建一些表,供下面的示例使用。 -/* pub # */ CREATE TABLE t1(a int, b int, c text, PRIMARY KEY(a,c)); -/* pub # */ CREATE TABLE t2(d int, e int, f int, PRIMARY KEY(d)); -/* pub # */ CREATE TABLE t3(g int, h int, i int, PRIMARY KEY(g)); +test_pub=# CREATE TABLE t1(a int, b int, c text, PRIMARY KEY(a,c)); +CREATE TABLE +test_pub=# CREATE TABLE t2(d int, e int, f int, PRIMARY KEY(d)); +CREATE TABLE +test_pub=# CREATE TABLE t3(g int, h int, i int, PRIMARY KEY(g)); +CREATE TABLE 创建一些发布。发布p1包含一个表(t1),该表带有行过滤器。 发布p2包含两个表,其中t1没有行过滤器,而t2带有行过滤器。 发布p3包含两个表,并且这两个表都带有行过滤器。 - 5 AND c = 'NSW'); -/* pub # */ CREATE PUBLICATION p2 FOR TABLE t1, t2 WHERE (e = 99); -/* pub # */ CREATE PUBLICATION p3 FOR TABLE t2 WHERE (d = 10), t3 WHERE (g = 10); -]]> + +test_pub=# CREATE PUBLICATION p1 FOR TABLE t1 WHERE (a > 5 AND c = 'NSW'); +CREATE PUBLICATION +test_pub=# CREATE PUBLICATION p2 FOR TABLE t1, t2 WHERE (e = 99); +CREATE PUBLICATION +test_pub=# CREATE PUBLICATION p3 FOR TABLE t2 WHERE (d = 10), t3 WHERE (g = 10); +CREATE PUBLICATION + psql可用于显示每个发布的行过滤表达式(如果已定义)。 - +test_pub=# \dRp+ + Publication p1 + Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root +----------+------------+---------+---------+---------+-----------+---------- + postgres | f | t | t | t | t | f Tables: "public.t1" WHERE ((a > 5) AND (c = 'NSW'::text)) - Publication p2 - Owner | All tables | Inserts | Updates | Deletes | Truncates | Generated columns | Via root -----------+------------+---------+---------+---------+-----------+-------------------+---------- - postgres | f | t | t | t | t | none | f + Publication p2 + Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root +----------+------------+---------+---------+---------+-----------+---------- + postgres | f | t | t | t | t | f Tables: "public.t1" "public.t2" WHERE (e = 99) - Publication p3 - Owner | All tables | Inserts | Updates | Deletes | Truncates | Generated columns | Via root -----------+------------+---------+---------+---------+-----------+-------------------+---------- - postgres | f | t | t | t | t | none | f + Publication p3 + Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root +----------+------------+---------+---------+---------+-----------+---------- + postgres | f | t | t | t | t | f Tables: "public.t2" WHERE (d = 10) "public.t3" WHERE (g = 10) -]]> + psql可用于显示每个表的行过滤表达式(如果已定义)。可以看到,表t1属于两个发布,但只有在p1中带有行过滤器; 表t2也属于两个发布,并且在这两个发布中具有不同的行过滤器。 - +test_pub=# \d t1 Table "public.t1" Column | Type | Collation | Nullable | Default --------+---------+-----------+----------+--------- @@ -952,7 +685,7 @@ Publications: "p1" WHERE ((a > 5) AND (c = 'NSW'::text)) "p2" -/* pub # */ \d t2 +test_pub=# \d t2 Table "public.t2" Column | Type | Collation | Nullable | Default --------+---------+-----------+----------+--------- @@ -965,7 +698,7 @@ Publications: "p2" WHERE (e = 99) "p3" WHERE (d = 10) -/* pub # */ \d t3 +test_pub=# \d t3 Table "public.t3" Column | Type | Collation | Nullable | Default --------+---------+-----------+----------+--------- @@ -976,31 +709,41 @@ Indexes: "t3_pkey" PRIMARY KEY, btree (g) Publications: "p3" WHERE (g = 10) -]]> + 在订阅端节点上,创建一个与发布端定义相同的表t1, 然后创建订阅s1来订阅发布p1 -/* sub # */ CREATE TABLE t1(a int, b int, c text, PRIMARY KEY(a,c)); -/* sub # */ CREATE SUBSCRIPTION s1 -/* sub - */ CONNECTION 'host=localhost dbname=test_pub application_name=s1' -/* sub - */ PUBLICATION p1; +test_sub=# CREATE TABLE t1(a int, b int, c text, PRIMARY KEY(a,c)); +CREATE TABLE +test_sub=# CREATE SUBSCRIPTION s1 +test_sub-# CONNECTION 'host=localhost dbname=test_pub application_name=s1' +test_sub-# PUBLICATION p1; +CREATE SUBSCRIPTION 插入一些行。只有满足发布p1t1 WHERE子句的那些行会被复制。 -/* pub # */ INSERT INTO t1 VALUES (2, 102, 'NSW'); -/* pub # */ INSERT INTO t1 VALUES (3, 103, 'QLD'); -/* pub # */ INSERT INTO t1 VALUES (4, 104, 'VIC'); -/* pub # */ INSERT INTO t1 VALUES (5, 105, 'ACT'); -/* pub # */ INSERT INTO t1 VALUES (6, 106, 'NSW'); -/* pub # */ INSERT INTO t1 VALUES (7, 107, 'NT'); -/* pub # */ INSERT INTO t1 VALUES (8, 108, 'QLD'); -/* pub # */ INSERT INTO t1 VALUES (9, 109, 'NSW'); - -/* pub # */ SELECT * FROM t1; +test_pub=# INSERT INTO t1 VALUES (2, 102, 'NSW'); +INSERT 0 1 +test_pub=# INSERT INTO t1 VALUES (3, 103, 'QLD'); +INSERT 0 1 +test_pub=# INSERT INTO t1 VALUES (4, 104, 'VIC'); +INSERT 0 1 +test_pub=# INSERT INTO t1 VALUES (5, 105, 'ACT'); +INSERT 0 1 +test_pub=# INSERT INTO t1 VALUES (6, 106, 'NSW'); +INSERT 0 1 +test_pub=# INSERT INTO t1 VALUES (7, 107, 'NT'); +INSERT 0 1 +test_pub=# INSERT INTO t1 VALUES (8, 108, 'QLD'); +INSERT 0 1 +test_pub=# INSERT INTO t1 VALUES (9, 109, 'NSW'); +INSERT 0 1 + +test_pub=# SELECT * FROM t1; a | b | c ---+-----+----- 2 | 102 | NSW @@ -1014,7 +757,7 @@ Publications: (8 rows) -/* sub # */ SELECT * FROM t1; +test_sub=# SELECT * FROM t1; a | b | c ---+-----+----- 6 | 106 | NSW @@ -1025,9 +768,10 @@ Publications: 更新一些数据,此时旧行和新行的值都满足发布p1t1 WHERE子句。该UPDATE会像平常一样复制该更改。 -/* pub # */ UPDATE t1 SET b = 999 WHERE a = 6; +test_pub=# UPDATE t1 SET b = 999 WHERE a = 6; +UPDATE 1 -/* pub # */ SELECT * FROM t1; +test_pub=# SELECT * FROM t1; a | b | c ---+-----+----- 2 | 102 | NSW @@ -1041,7 +785,7 @@ Publications: (8 rows) -/* sub # */ SELECT * FROM t1; +test_sub=# SELECT * FROM t1; a | b | c ---+-----+----- 9 | 109 | NSW @@ -1053,9 +797,10 @@ Publications: 更新一些数据,此时旧行的值不满足发布p1t1 WHERE子句,而新行的值满足该子句。 UPDATE会被转换为INSERT,并且该更改会被复制。可以在订阅端看到新行。 -/* pub # */ UPDATE t1 SET a = 555 WHERE a = 2; +test_pub=# UPDATE t1 SET a = 555 WHERE a = 2; +UPDATE 1 -/* pub # */ SELECT * FROM t1; +test_pub=# SELECT * FROM t1; a | b | c -----+-----+----- 3 | 103 | QLD @@ -1069,7 +814,7 @@ Publications: (8 rows) -/* sub # */ SELECT * FROM t1; +test_sub=# SELECT * FROM t1; a | b | c -----+-----+----- 9 | 109 | NSW @@ -1082,9 +827,10 @@ Publications: 更新一些数据,此时旧行的值满足发布p1t1 WHERE子句,而新行的值不再满足该子句。 UPDATE会被转换为DELETE,并且该更改会被复制。可以看到该行已从订阅端移除。 -/* pub # */ UPDATE t1 SET c = 'VIC' WHERE a = 9; +test_pub=# UPDATE t1 SET c = 'VIC' WHERE a = 9; +UPDATE 1 -/* pub # */ SELECT * FROM t1; +test_pub=# SELECT * FROM t1; a | b | c -----+-----+----- 3 | 103 | QLD @@ -1098,7 +844,7 @@ Publications: (8 rows) -/* sub # */ SELECT * FROM t1; +test_sub=# SELECT * FROM t1; a | b | c -----+-----+----- 6 | 999 | NSW @@ -1107,42 +853,50 @@ Publications: - 下面的示例展示了发布参数publish_via_partition_root + 下面的示例展示了发布参数publish_via_partition_root 在分区表场景下如何决定使用父表还是子表的行过滤器。 在发布端创建一个分区表。 -/* pub # */ CREATE TABLE parent(a int PRIMARY KEY) PARTITION BY RANGE(a); -/* pub # */ CREATE TABLE child PARTITION OF parent DEFAULT; +test_pub=# CREATE TABLE parent(a int PRIMARY KEY) PARTITION BY RANGE(a); +CREATE TABLE +test_pub=# CREATE TABLE child PARTITION OF parent DEFAULT; +CREATE TABLE 在订阅端创建相同的表。 -/* sub # */ CREATE TABLE parent(a int PRIMARY KEY) PARTITION BY RANGE(a); -/* sub # */ CREATE TABLE child PARTITION OF parent DEFAULT; +test_sub=# CREATE TABLE parent(a int PRIMARY KEY) PARTITION BY RANGE(a); +CREATE TABLE +test_sub=# CREATE TABLE child PARTITION OF parent DEFAULT; +CREATE TABLE 创建一个发布p4,然后订阅它。发布参数publish_via_partition_root设置为 true。 分区表(parent)和分区(child)上都定义了行过滤器。 -= 5) -/* pub - */ WITH (publish_via_partition_root=true); -]]> -/* sub # */ CREATE SUBSCRIPTION s4 -/* sub - */ CONNECTION 'host=localhost dbname=test_pub application_name=s4' -/* sub - */ PUBLICATION p4; +test_pub=# CREATE PUBLICATION p4 FOR TABLE parent WHERE (a < 5), child WHERE (a >= 5) +test_pub-# WITH (publish_via_partition_root=true); +CREATE PUBLICATION + + +test_sub=# CREATE SUBSCRIPTION s4 +test_sub-# CONNECTION 'host=localhost dbname=test_pub application_name=s4' +test_sub-# PUBLICATION p4; +CREATE SUBSCRIPTION 直接向parentchild表插入一些值。它们会使用parent的行过滤器进行复制(因为publish_via_partition_root为 true)。 -/* pub # */ INSERT INTO parent VALUES (2), (4), (6); -/* pub # */ INSERT INTO child VALUES (3), (5), (7); +test_pub=# INSERT INTO parent VALUES (2), (4), (6); +INSERT 0 3 +test_pub=# INSERT INTO child VALUES (3), (5), (7); +INSERT 0 3 -/* pub # */ SELECT * FROM parent ORDER BY a; +test_pub=# SELECT * FROM parent ORDER BY a; a --- 2 @@ -1154,7 +908,7 @@ Publications: (6 rows) -/* sub # */ SELECT * FROM parent ORDER BY a; +test_sub=# SELECT * FROM parent ORDER BY a; a --- 2 @@ -1166,23 +920,29 @@ Publications: 重复相同的测试,但将publish_via_partition_root设为不同的值。 这里发布参数publish_via_partition_root设置为 false,并且在分区(child)上定义了行过滤器。 -= 5) -/* pub - */ WITH (publish_via_partition_root=false); -]]> -/* sub # */ ALTER SUBSCRIPTION s4 REFRESH PUBLICATION; +test_pub=# DROP PUBLICATION p4; +DROP PUBLICATION +test_pub=# CREATE PUBLICATION p4 FOR TABLE parent, child WHERE (a >= 5) +test_pub-# WITH (publish_via_partition_root=false); +CREATE PUBLICATION + + +test_sub=# ALTER SUBSCRIPTION s4 REFRESH PUBLICATION; +ALTER SUBSCRIPTION 像前面一样在发布端执行插入。它们会使用child的行过滤器进行复制(因为publish_via_partition_root为 false)。 -/* pub # */ TRUNCATE parent; -/* pub # */ INSERT INTO parent VALUES (2), (4), (6); -/* pub # */ INSERT INTO child VALUES (3), (5), (7); +test_pub=# TRUNCATE parent; +TRUNCATE TABLE +test_pub=# INSERT INTO parent VALUES (2), (4), (6); +INSERT 0 3 +test_pub=# INSERT INTO child VALUES (3), (5), (7); +INSERT 0 3 -/* pub # */ SELECT * FROM parent ORDER BY a; +test_pub=# SELECT * FROM parent ORDER BY a; a --- 2 @@ -1194,7 +954,7 @@ Publications: (6 rows) -/* sub # */ SELECT * FROM child ORDER BY a; +test_sub=# SELECT * FROM child ORDER BY a; a --- 5 @@ -1229,21 +989,16 @@ Publications: 列列表只能包含简单的列引用。列表中列的顺序不会被保留。 - - 生成列也可以在列列表中指定。这样就可以不受发布参数 - - publish_generated_columns 的限制而发布生成列。详见 - 。 - + 当发布还发布 - FOR TABLES IN SCHEMA + FOR TABLES IN SCHEMA 时,不支持指定列列表。 - 对于分区表,发布参数publish_via_partition_root + 对于分区表,发布参数publish_via_partition_root 决定使用哪个列列表。如果publish_via_partition_roottrue,则使用根分区表的列列表。 否则,如果publish_via_partition_rootfalse(默认值),则使用各个分区的列列表。 @@ -1261,8 +1016,6 @@ Publications: 在初始数据同步期间,只会复制已发布的列。然而,如果订阅端使用的是 15 之 前的版本,那么在初始数据同步期间会复制表中的所有列,而忽略任何列列表。 - 如果订阅端使用的是 18 之前的版本,那么即使发布端定义了生成列,初始表同 - 步也不会复制生成列。 @@ -1281,7 +1034,7 @@ Publications: 如果某个订阅受到了这个问题的影响,那么恢复复制的唯一方法是调整发布端的某个列列表,使它们全部一致; - 然后要么重新创建该订阅,要么使用ALTER SUBSCRIPTION ... DROP PUBLICATION + 然后要么重新创建该订阅,要么使用ALTER SUBSCRIPTION ... DROP PUBLICATION 删除一个有问题的发布,再把它重新加回来。 @@ -1293,23 +1046,25 @@ Publications: 创建一个表t1,供下面的示例使用。 -/* pub # */ CREATE TABLE t1(id int, a text, b text, c text, d text, e text, PRIMARY KEY(id)); +test_pub=# CREATE TABLE t1(id int, a text, b text, c text, d text, e text, PRIMARY KEY(id)); +CREATE TABLE 创建一个发布p1。为表t1定义一个列列表,以减少将被复制的列数。请注意,列列表中列名的顺序并不重要。 -/* pub # */ CREATE PUBLICATION p1 FOR TABLE t1 (id, b, a, d); +test_pub=# CREATE PUBLICATION p1 FOR TABLE t1 (id, b, a, d); +CREATE PUBLICATION psql可用于显示每个发布的列列表(如果已定义)。 -/* pub # */ \dRp+ - Publication p1 - Owner | All tables | Inserts | Updates | Deletes | Truncates | Generated columns | Via root -----------+------------+---------+---------+---------+-----------+-------------------+---------- - postgres | f | t | t | t | t | none | f +test_pub=# \dRp+ + Publication p1 + Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root +----------+------------+---------+---------+---------+-----------+---------- + postgres | f | t | t | t | t | f Tables: "public.t1" (id, a, b, d) @@ -1317,7 +1072,7 @@ Tables: psql可用于显示每个表的列列表(如果已定义)。 -/* pub # */ \d t1 +test_pub=# \d t1 Table "public.t1" Column | Type | Collation | Nullable | Default --------+---------+-----------+----------+--------- @@ -1336,19 +1091,24 @@ Publications: 在订阅端节点上,创建一个名为t1的表,它现在只需要发布端表t1中的部分列,然后创建订阅s1来订阅发布p1 -/* sub # */ CREATE TABLE t1(id int, b text, a text, d text, PRIMARY KEY(id)); -/* sub # */ CREATE SUBSCRIPTION s1 -/* sub - */ CONNECTION 'host=localhost dbname=test_pub application_name=s1' -/* sub - */ PUBLICATION p1; +test_sub=# CREATE TABLE t1(id int, b text, a text, d text, PRIMARY KEY(id)); +CREATE TABLE +test_sub=# CREATE SUBSCRIPTION s1 +test_sub-# CONNECTION 'host=localhost dbname=test_pub application_name=s1' +test_sub-# PUBLICATION p1; +CREATE SUBSCRIPTION 在发布端节点上,向表t1插入一些行。 -/* pub # */ INSERT INTO t1 VALUES(1, 'a-1', 'b-1', 'c-1', 'd-1', 'e-1'); -/* pub # */ INSERT INTO t1 VALUES(2, 'a-2', 'b-2', 'c-2', 'd-2', 'e-2'); -/* pub # */ INSERT INTO t1 VALUES(3, 'a-3', 'b-3', 'c-3', 'd-3', 'e-3'); -/* pub # */ SELECT * FROM t1 ORDER BY id; +test_pub=# INSERT INTO t1 VALUES(1, 'a-1', 'b-1', 'c-1', 'd-1', 'e-1'); +INSERT 0 1 +test_pub=# INSERT INTO t1 VALUES(2, 'a-2', 'b-2', 'c-2', 'd-2', 'e-2'); +INSERT 0 1 +test_pub=# INSERT INTO t1 VALUES(3, 'a-3', 'b-3', 'c-3', 'd-3', 'e-3'); +INSERT 0 1 +test_pub=# SELECT * FROM t1 ORDER BY id; id | a | b | c | d | e ----+-----+-----+-----+-----+----- 1 | a-1 | b-1 | c-1 | d-1 | e-1 @@ -1360,7 +1120,7 @@ Publications: 只有发布p1的列列表中包含的数据会被复制。 -/* sub # */ SELECT * FROM t1 ORDER BY id; +test_sub=# SELECT * FROM t1 ORDER BY id; id | b | a | d ----+-----+-----+----- 1 | b-1 | a-1 | d-1 @@ -1373,370 +1133,13 @@ Publications: - - 生成列复制 - - - 通常,订阅端的表会与发布端表定义相同,因此如果发布端表包含 - GENERATED 列, - 订阅端表也会有对应的生成列。在这种情况下,始终使用订阅端表生成列的值。 - - - - 例如,下面可以看到订阅端表的生成列值来自订阅端列自身的计算: - -/* pub # */ CREATE TABLE tab_gen_to_gen (a int, b int GENERATED ALWAYS AS (a + 1) STORED); -/* pub # */ INSERT INTO tab_gen_to_gen VALUES (1),(2),(3); -/* pub # */ CREATE PUBLICATION pub1 FOR TABLE tab_gen_to_gen; -/* pub # */ SELECT * FROM tab_gen_to_gen; - a | b ----+--- - 1 | 2 - 2 | 3 - 3 | 4 -(3 rows) - -/* sub # */ CREATE TABLE tab_gen_to_gen (a int, b int GENERATED ALWAYS AS (a * 100) STORED); -/* sub # */ CREATE SUBSCRIPTION sub1 CONNECTION 'dbname=test_pub' PUBLICATION pub1; -/* sub # */ SELECT * from tab_gen_to_gen; - a | b ----+---- - 1 | 100 - 2 | 200 - 3 | 300 -(3 rows) - - - - - 实际上,在 18.0 之前的版本中,逻辑复制根本不会发布 - GENERATED 列。 - - - - 但在某些场景中,将生成列复制到普通列是有意义的。 - - - 当通过输出插件将数据复制到非 PostgreSQL 数据库时,此特性可能很有用, - 尤其是目标数据库不支持生成列时。 - - - - - - 默认不会发布生成列,但用户可以选择像普通列一样发布存储生成列。 - - - - 有两种方式: - - - - 将 PUBLICATION 参数 - - publish_generated_columns - 设置为 stored。 - 这样 PostgreSQL 逻辑复制会发布该发布中各表当前及未来的存储生成列。 - - - - - - 指定表的 列列表, - 显式指定要发布哪些存储生成列。 - - - - - 在确定发布哪些表列时,列列表优先级更高,会覆盖 - publish_generated_columns 参数的效果。 - - - - - - - - 下表汇总了逻辑复制涉及生成列时的行为,分别展示未启用和启用发布生成列时的结果。 - - - - 复制结果汇总 - - - - 发布生成列? - 发布端表列 - 订阅端表列 - 结果 - - - - - - - GENERATED - GENERATED - 发布端该列不复制。使用订阅端表生成列的值。 - - - - - GENERATED - 普通列 - 发布端该列不复制。使用订阅端普通列默认值。 - - - - - GENERATED - --missing-- - 发布端该列不复制。不会发生任何操作。 - - - - - GENERATED - GENERATED - 错误。不支持。 - - - - - GENERATED - 普通列 - 发布端该列值会复制到订阅端表列。 - - - - - GENERATED - --missing-- - 错误。该列会被报告为订阅端表缺失。 - - - -
- - - - 目前不支持一个订阅包含多个发布,且同一张表在这些发布中使用不同列列表。 - 见 。 - - - - 如果同一订阅中一个发布对该表发布生成列,而另一个发布不发布生成列, - 也会出现同样的问题。 - - - - - - 如果订阅端版本早于 18,即使发布端定义了生成列,初始表同步也不会复制生成列。 - - -
冲突 - 逻辑复制的行为在一点上类似于普通 DML 操作:即使订阅节点上的数据已在本地被修改, - 传入的变更仍会更新它。如果传入数据违反了任何约束,复制就会停止,这种情况称为 - 冲突。在复制 UPDATE 或 - DELETE 操作时,找不到目标数据也被视为 - 冲突,但不会报错,这类操作会被直接跳过。 - - - - 在以下 冲突 场景中,会记录附加日志,并收集冲突统计信息 - (显示在 - pg_stat_subscription_stats - 视图中): - - - insert_exists - - - 插入某行时违反了一个 NOT DEFERRABLE 唯一约束。 - 请注意,若要在日志中记录冲突键的来源和提交时间戳详情,订阅端应启用 - track_commit_timestamp。 - 这种情况下,系统会持续报错,直到手工解决该冲突。 - - - - - update_origin_differs - - - 更新一行,而该行此前已被另一来源修改。请注意,只有在订阅端启用了 - track_commit_timestamp - 时才能检测到这种冲突。目前,无论本地行的来源是什么,更新都会照常应用。 - - - - - update_exists - - - 某行更新后的值违反了一个 NOT DEFERRABLE 唯一约束。 - 请注意,若要在日志中记录冲突键的来源和提交时间戳详情,订阅端应启用 - track_commit_timestamp。 - 这种情况下,系统会持续报错,直到手工解决该冲突。另请注意,在更新分区表时, - 如果更新后的行值满足了另一个分区的约束,导致该行被插入到新分区中,而新行又 - 违反了一个 NOT DEFERRABLE 唯一约束,则可能出现 - insert_exists 冲突。 - - - - - update_missing - - - 要更新的行未找到。在这种情况下,该更新会被直接跳过。 - - - - - delete_origin_differs - - - 删除一行,而该行此前已被另一来源修改。请注意,只有在订阅端启用了 - track_commit_timestamp - 时才能检测到这种冲突。目前,无论本地行的来源是什么,删除都会照常应用。 - - - - - delete_missing - - - 要删除的行未找到。在这种情况下,该删除会被直接跳过。 - - - - - multiple_unique_conflicts - - - 插入或更新某行时违反了多个 NOT DEFERRABLE 唯一约束。 - 请注意,若要在日志中记录冲突键的来源和提交时间戳详情,请确保订阅端启用了 - track_commit_timestamp。 - 这种情况下,系统会持续报错,直到手工解决该冲突。 - - - - - 请注意,还存在其他冲突场景,例如排他约束违规。目前,我们不会在日志中为它们 - 提供额外细节。 - - - - 逻辑复制冲突的日志格式如下: - -LOG: conflict detected on relation "schemaname.tablename": conflict=conflict_type -DETAIL: detailed_explanation. -{detail_values [; ... ]}. - -其中 detail_values 可以是以下之一: - - Key (column_name , ...)=(column_value , ...) - existing local row (column_name , ...)=(column_value , ...) - remote row (column_name , ...)=(column_value , ...) - replica identity {(column_name , ...)=(column_value , ...) | full (column_name , ...)=(column_value , ...)} - - - 日志会提供以下信息: - - - LOG - - - - - schemaname.tablename - 标识发生冲突的本地关系。 - - - - - conflict_type 是发生的冲突类型 - (例如 insert_existsupdate_exists)。 - - - - - - - - DETAIL - - - - - detailed_explanation 包括 - 修改现有本地行的事务的来源、事务 ID 以及提交时间戳(如果可用)。 - - - - - Key 部分包含本地行的键值;该本地行在 - insert_existsupdate_exists 或 - multiple_unique_conflicts 冲突中违反了唯一约束。 - - - - - existing local row 部分包含本地行;当 - update_origin_differs 或 - delete_origin_differs 冲突中,本地行的来源与远端行不同, - 或者在 insert_existsupdate_exists - 或 multiple_unique_conflicts 冲突中,该键值与远端行冲突时, - 会记录这部分内容。 - - - - - remote row 部分包含导致冲突的远端插入或更新操作中的新行。 - 注意,对于更新操作,如果某个列值未变化且已被 TOAST 化,则新行中的该列值 - 会为 null。 - - - - - replica identity 部分包含用于查找要更新或删除的现有本地行的 - 复制标识键值。如果本地关系被标记为 - REPLICA IDENTITY FULL, - 这里也可能包含整行值。 - - - - - column_name 是列名。对于 - existing local rowremote row 以及 - replica identity full 这几种情况,只有当用户没有权限访问该表 - 的全部列时,才会记录列名。如果记录了列名,它们的顺序与对应列值的顺序一致。 - - - - - column_value 是列值。较大的列值 - 会被截断到 64 字节。 - - - - - 请注意,在 multiple_unique_conflicts 冲突场景中, - 会生成多条 detailed_explanation - 和 detail_values 行, - 每条都描述一个不同唯一约束对应的冲突信息。 - - - - - - + 逻辑复制的行为类似于普通的 DML 操作,即使数据在订阅端本地已被更改,仍会更新数据。如果传入的数据违反了任何约束,复制将停止。这称为冲突。当复制UPDATEDELETE操作时,缺失的数据不会产生冲突,这类操作只会被简单跳过。 @@ -1750,54 +1153,37 @@ DETAIL: detailed_explanation. - 会产生错误的冲突会使复制停止;这类冲突必须由用户手工解决。有关冲突的详细信息 - 可以在订阅端的服务器日志中找到。 + 冲突将产生一个错误并停止复制;它必须由用户手动解决。冲突的详细信息可在订阅端的服务器日志中找到。 解决方法可以是修改订阅端上的数据或权限,使其不再与传入变更冲突;也可以跳过与 - 现有数据冲突的事务。当冲突导致错误时,复制不会继续,逻辑复制工作者会向订阅端 + 现有数据冲突的事务。当冲突导致错误时,复制不会继续,逻辑复制工作进程会向订阅端 的服务器日志输出如下消息: -ERROR: conflict detected on relation "public.test": conflict=insert_exists -DETAIL: Key already exists in unique index "t_pkey", which was modified locally in transaction 740 at 2024-06-26 10:47:04.727375+08. -Key (c)=(1); existing local row (1, 'local'); remote row (1, 'remote'). +ERROR: duplicate key value violates unique constraint "test_pkey" +DETAIL: Key (c)=(1) already exists. CONTEXT: processing remote data for replication origin "pg_16395" during "INSERT" for replication target relation "public.test" in transaction 725 finished at 0/14C0378 可以从服务器日志中找到包含违规变更的事务的 LSN 以及复制源名称 (在上述示例中分别是 LSN 0/14C0378 和复制源 pg_16395)。 可以使用 - ALTER SUBSCRIPTION ... SKIP - 并提供 finish LSN(即 LSN 0/14C0378)来跳过产生冲突的事务。这个 finish LSN - 可以是该事务在发布端提交或准备完成时的 LSN。或者,也可以调用 + ALTER SUBSCRIPTION ... SKIP + 并提供 完成 LSN(即 LSN 0/14C0378)来跳过产生冲突的事务。这个 完成 LSN + 可以是该事务在发布端提交或预备时的 LSN。或者,也可以调用 pg_replication_origin_advance() 函数来跳过该事务。 在使用此函数之前,需要暂时禁用订阅,可以使用 - - ALTER SUBSCRIPTION ... DISABLE,或者让订阅使用 - disable_on_error + + ALTER SUBSCRIPTION ... DISABLE,或者让订阅使用 + disable_on_error 选项。然后,可以使用 pg_replication_origin_advance() 函数, 传入 node_name(即 pg_16395) - 以及 finish LSN 的下一个 LSN(即 0/14C0379)。当前各复制源的位置可以在 + 以及 完成 LSN 的下一个 LSN(即 0/14C0379)。当前各复制源的位置可以在 pg_replication_origin_status 系统视图中查看。 请注意,跳过整个事务也会跳过那些本来可能不违反任何约束的变更,这很容易导致 - 订阅端不一致。关于冲突行的其他细节,例如其来源和提交时间戳,也可以在日志的 - DETAIL 行中看到。但请注意,这些信息只有在订阅端启用了 - track_commit_timestamp - 时才可用。用户可以利用这些信息来决定是保留本地更改,还是采用远端变更。例如, - 上述日志中的 DETAIL 行表明现有行是在本地被修改的。用户 - 可以手工让远端变更胜出。 - - - - 当 - streaming - 模式为 parallel 时,失败事务的 finish LSN 可能不会被记录。 - 这种情况下,可能需要把 streaming 模式改为 on 或 - off,并再次触发相同的冲突,以便将失败事务的 finish LSN - 写入服务器日志。关于 finish LSN 的用法,请参见 - ALTER SUBSCRIPTION ... SKIP。 + 订阅端不一致。 @@ -1814,9 +1200,9 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER 数据库模式和 DDL 命令不会被复制。初始模式可以手工使用 pg_dump --schema-only 复制。之后的模式更改需要手工保持同步。 (不过请注意,两端的模式其实不需要绝对一致。)当活动数据库中的模式定义发生变化时, - 逻辑复制仍然具有一定鲁棒性:如果发布端修改了模式,而复制数据开始到达订阅端时 + 逻辑复制仍然能够稳健运行:如果发布端修改了模式,而复制数据开始到达订阅端时 与表模式不匹配,复制就会报错,直到模式被更新。在很多情况下,可以通过先在订阅端 - 应用增量式的模式变更来避免间歇性错误。 + 应用仅添加内容的模式变更来避免间歇性错误。 @@ -1857,26 +1243,11 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER - 在分区表之间复制时,默认情况下,实际复制来源是发布端的叶子分区,因此发布端上的 - 这些分区也必须在订阅端作为有效的目标表存在。(它们既可以本身也是叶子分区, - 也可以进一步再分区,甚至可以是独立表。)发布还可以指定,复制变更时改用分区根表 - 的标识和模式,而不是使用实际产生变更的各个叶子分区的标识和模式(见 - CREATE PUBLICATION 的 - publish_via_partition_root - 参数)。 + 在分区表之间进行复制时,实际的复制默认源自发布端的叶分区,因此发布端的分区在订阅端也必须作为有效的目标表存在。(它们可以本身是叶分区,也可以进一步子分区,甚至可以是独立的表。)发布也可以指定使用分区根表的标识和模式来复制变更,而不使用变更实际发生的各个叶分区的标识和模式(见CREATE PUBLICATION)。 - - - 对已发布表使用 - REPLICA IDENTITY FULL - 时,需要注意:如果表中包含某些数据类型的属性(例如 point 或 box),而这些类型 - 没有 B-tree 或 Hash 的默认操作符类,那么 UPDATE 和 - DELETE 操作就无法在订阅端应用。不过,可以通过确保该表具有 - 主键或已定义复制标识来规避这一限制。 - - + @@ -1884,57 +1255,33 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER 架构 - 逻辑复制采用了与物理流复制类似的架构(见 - )。它由 walsender - 和 apply 进程实现。walsender 进程会对 WAL - 执行逻辑解码(见 ),并装载标准逻辑解码输出插件 - (pgoutput)。该插件会把从 WAL 中读取到的变更转换为逻辑复制协议 - (见 ),并按照发布规范过滤数据。 - 然后,数据会通过流复制协议持续传输给应用工作进程,由它把数据映射到本地表, - 并在收到时按正确的事务顺序应用各项变更。 + 逻辑复制首先复制发布端数据库中数据的快照。完成后,发布端的变更会随着发生实时发送给订阅端。订阅端按照发布端提交的顺序应用数据,因此对于单个订阅中的发布,可以保证事务一致性。 - 订阅端数据库上的应用进程始终在 - session_replication_role - 设置为 replica 的情况下运行。这意味着默认情况下,触发器和规则 - 不会在订阅端触发。用户可以选择使用 - ALTER TABLE 命令以及 - ENABLE TRIGGERENABLE RULE 子句, - 在表上启用触发器和规则。 + 逻辑复制采用类似于物理流复制的架构(见)。它由walsenderapply进程实现。walsender 进程启动 WAL 的逻辑解码(见),并加载标准逻辑解码输出插件(pgoutput)。该插件将从 WAL 读取的变更转换为逻辑复制协议(见),并根据发布规范过滤数据。然后使用流复制协议将数据持续传输给 应用工作进程,该工作进程将数据映射到本地表,并按正确的事务顺序逐一应用每个变更。 - 逻辑复制应用进程目前只会触发行触发器,不会触发语句触发器。不过,初始表同步的 - 实现方式类似于 COPY 命令,因此会为 - INSERT 同时触发行触发器和语句触发器。 + 订阅端数据库上的 应用进程总是在session_replication_role设置为replica的情况下运行。这意味着默认情况下,触发器和规则不会在订阅端触发。用户可以选择使用ALTER TABLE命令和ENABLE TRIGGERENABLE RULE子句在表上启用触发器和规则。 + + + + 逻辑复制的应用进程目前只触发行触发器,不触发语句触发器。但初始表同步的实现方式类似于COPY命令,因此会触发INSERT的行触发器和语句触发器。 初始快照 - 对现有订阅表中的初始数据,会取快照并由一种特殊应用进程的并行实例来复制。 - 这些特殊的应用进程是为每张待同步表启动的专用表同步工作者。每个表同步进程 - 都会创建自己的复制槽,并复制现有数据。复制一完成,该表内容就会对其他后端可见。 - 现有数据复制完成后,工作者会进入同步模式,通过标准逻辑复制流式发送在初始数据 - 复制期间发生的任何变更,使该表与主应用进程达到同步状态。在这一同步阶段, - 变更会按照它们在发布端发生的顺序被应用和提交。同步完成后,该表的复制控制权 - 会交还给主应用进程,之后复制将照常继续。 + 已订阅表中的初始数据由一种特殊的应用进程的并行实例建立快照并复制。该进程将创建自己的复制槽并复制现有数据。一旦复制完成,表的内容就对其他后端可见了。现有数据复制完成后,工作进程进入同步模式,通过使用标准逻辑复制流式传输初始数据复制期间发生的所有变更,确保该表与主应用进程同步。在此同步阶段,变更会按照在发布端发生的顺序被应用和提交。同步完成后,该表的复制控制权交还给主应用进程,此后复制照常继续。 - + 发布的 - publish + publish 参数只影响哪些 DML 操作会被复制。初始数据同步在复制现有表数据时不会考虑该参数。 - - - 如果表同步工作者在复制期间失败,应用工作者会检测到这一失败,并重新启动表同步 - 工作者以继续同步过程。这种行为确保了瞬时错误不会永久破坏复制配置。另见 - wal_retrieve_retry_interval。 - - @@ -1951,22 +1298,20 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER 与订阅相关的监控信息可在 pg_stat_subscription - 中查看。这个视图为每个订阅工作者包含一行。一个订阅根据其状态,可能有零个或多个 - 活跃的订阅工作者。 + 中查看。这个视图为每个订阅工作进程包含一行。一个订阅根据其状态,可能有零个或多个 + 活跃的订阅工作进程。 - 通常,一个已启用的订阅会有一个应用进程在运行。被禁用的订阅或已崩溃的订阅在这个 - 视图中将没有任何行。如果某张表的初始数据同步正在进行,则还会有针对这些正在同步 - 的表的额外工作者。并且,如果使用 - streaming - 并以并行方式应用事务,则还可能出现额外的并行应用工作进程。 + 正常情况下,已启用的订阅会有一个应用进程在运行。被禁用或已崩溃的订阅在此视图中将有零行。如果任何表的初始数据同步正在进行中,将有额外的工作进程用于正在同步的表。 安全性 + 能够修改订阅端表模式的用户,可以以修改这些表的订阅的所有者角色身份执行任意代码。此类表的所有权和TRIGGER权限应只授予受信任的角色。此外,如果不受信任的用户可以创建表,则应只使用显式列出表的发布。也就是说,只有当超级用户信任发布端或订阅端上每一个获准创建非临时表的用户时,才能创建FOR ALL TABLESFOR TABLES IN SCHEMA的订阅。 + 用于复制连接的角色必须具有 REPLICATION 属性 (或为超级用户)。如果该角色既没有 SUPERUSER,也没有 @@ -2000,834 +1345,42 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER 用户也必须是超级用户。 - - 目前发布没有权限控制。任何订阅(只要能够连接)都可以访问任何发布。因此, - 如果你打算向某些订阅者隐藏部分信息,例如通过行过滤器、列列表,或者通过不把整张表 - 加入发布来实现,需要注意:同一数据库中的其他发布仍可能暴露这些信息。未来版本的 - PostgreSQL 可能会增加发布权限,以支持更细粒度的 - 访问控制。 - - - 要创建订阅,用户必须具有 pg_create_subscription 角色的权限, - 并且对该数据库具有 CREATE 权限。 - - - 订阅应用进程在会话级别会以订阅所有者的权限运行。不过,在对某个具体表执行 - insert、update、delete 或 truncate 操作时,它会切换角色到该表所有者,并以 - 表所有者的权限执行该操作。这意味着,订阅所有者必须能够对每个复制表的所有者执行 - SET ROLE。 - + 要创建订阅,用户必须是超级用户。 + + 订阅应用进程将以订阅所有者的权限在本地数据库中运行。 + - - 如果订阅配置了 run_as_owner = true,则不会发生用户切换。 - 取而代之的是,所有操作都将以订阅所有者的权限执行。在这种情况下,订阅所有者只需 - 具备对目标表执行 SELECTINSERT、 - UPDATEDELETE 的权限,而不需要 - 具备对表所有者执行 SET ROLE 的权限。不过,这也意味着, - 任何拥有正在接收复制数据的表的用户,都可以以订阅所有者的权限执行任意代码。 - 例如,他们只需在自己拥有的某张表上附加一个触发器即可。由于通常并不希望允许一个 - 角色自由取得另一个角色的权限,因此除非数据库内部的用户安全完全不重要,否则应避免 - 使用该选项。 - 在发布端,权限只在复制连接开始时检查一次,在读取每条变更记录时不会重新检查。 - 在订阅端,订阅所有者的权限会在每个事务应用时重新检查。如果某个工作者正在应用 + 在订阅端,订阅所有者的权限会在每个事务应用时重新检查。如果某个工作进程正在应用 事务时,订阅的所有权被并发事务更改,那么当前事务的应用仍会继续使用旧所有者的 权限。 - 配置参数 + 配置设置 - 逻辑复制需要设置若干配置选项。这些选项只在复制的一侧生效。 + 逻辑复制需要设置几个配置选项。 - - 发布端 - - - wal_level - 必须设置为 logical。 - - - - max_replication_slots - 必须至少设置为预期连接的订阅数量,再加上用于表同步的预留量。 - - - - 逻辑复制槽还会受到 - idle_replication_slot_timeout - 的影响。 - - - - max_wal_senders - 应至少设置为 max_replication_slots,再加上同时连接的 - 物理副本数量。 - - - - 逻辑复制 walsender 还会受到 - wal_sender_timeout - 的影响。 - - - - - - 订阅端 - - - max_active_replication_origins - 必须至少设置为将添加到订阅端的订阅数量,再加上用于表同步的预留量。 - - - - max_logical_replication_workers - 必须至少设置为订阅数量(用于主应用工作进程),再加上用于表同步工作进程 - 和并行应用工作进程的预留量。 - - - - 可能还需要调整 - max_worker_processes - 以容纳复制工作进程,至少应为 - (max_logical_replication_workers - + 1)。注意,一些扩展和并行查询也会占用 - max_worker_processes 的工作进程槽位。 - - - - max_sync_workers_per_subscription - 控制订阅初始化或新增表时初始数据复制的并行度。 - - - - max_parallel_apply_workers_per_subscription - 控制订阅参数 streaming = parallel 时,进行中事务流式复制的并行度。 - - - - 逻辑复制工作进程还会受到 - wal_receiver_timeout、 - wal_receiver_status_interval - 和 - wal_retrieve_retry_interval - 的影响。 - - - - - - - 升级 - - 仅当旧逻辑复制集群的所有成员都为 17.0 或更高版本时,才支持迁移 - 逻辑复制集群。 + 在发布端,wal_level必须设置为logicalmax_replication_slots必须至少设置为预期连接的订阅数,加上为表同步预留的一些余量。而max_wal_senders应至少设置为max_replication_slots加上同时连接的物理副本数。 - - 为发布端升级做准备 - - - pg_upgrade 会尝试迁移逻辑槽。 - 这有助于避免在新发布端手工定义相同的逻辑槽。 - 仅当旧集簇版本为 17.0 或更高时才支持逻辑槽迁移。 - 17.0 之前集簇中的逻辑槽会被静默忽略。 - - - - 在开始升级发布端集簇前,请通过执行 - ALTER SUBSCRIPTION ... DISABLE - 临时禁用订阅。升级完成后再重新启用订阅。 - - - - pg_upgrade 升级逻辑槽有若干前置条件。 - 若不满足,将报错。 - - - - - - 新集簇必须将 - wal_level - 设为 logical。 - - - - - 新集簇中 - max_replication_slots - 的配置值必须大于等于旧集簇中的槽数量。 - - - - - 旧集簇槽引用的输出插件必须安装在新 PostgreSQL 可执行文件目录中。 - - - - - 旧集簇必须已将所有事务和逻辑解码消息复制到订阅端。 - - - - - 旧集簇中的所有槽都必须可用,即不存在 - pg_replication_slots.conflicting - 不为 true 的槽。 - - - - - 新集簇中不能存在永久逻辑槽,即不能有 - pg_replication_slots.temporary - 为 false 的槽。 - - - - - - - 为订阅端升级做准备 - - - 在新订阅端完成 - 订阅端配置。 - pg_upgrade 会尝试迁移订阅依赖,包括 - pg_subscription_rel - 系统目录中的订阅表信息,以及订阅的复制源。 - 这样新订阅端上的逻辑复制可以从旧订阅端停止的位置继续。 - 仅当旧集簇版本为 17.0 或更高时才支持订阅依赖迁移。 - 17.0 之前集簇中的订阅依赖会被静默忽略。 - - - - pg_upgrade 升级订阅也有若干前置条件。 - 若不满足,将报错。 - - - - - - 旧订阅端中所有订阅表应处于 i(initialize) - 或 r(ready)状态。 - 可通过检查 - pg_subscription_rel.srsubstate - 验证。 - - - - - 旧集簇中每个订阅对应的复制源条目都必须存在。 - 可通过检查 - pg_subscription 与 - pg_replication_origin - 系统表确认。 - - - - - 新集簇中的 - max_active_replication_origins - 配置值必须大于等于旧集簇中的订阅数量。 - - - - - - - 升级逻辑复制集群 - - - 在升级订阅端时,发布端仍可执行写操作。这些变更会在订阅端升级完成后继续复制。 - - - - - 逻辑复制的限制同样适用于逻辑复制集群升级。详见 - 。 - - - 发布端升级的前置条件同样适用于逻辑复制集群升级。详见 - 。 - - - 订阅端升级的前置条件同样适用于逻辑复制集群升级。详见 - 。 - - - - - - 升级逻辑复制集群需要在多个节点执行多个步骤。由于并非所有操作都是事务性的, - 建议按 所述先做好备份。 - - - - - 下列逻辑复制集群的升级步骤详见后文: - - - - 按照 - 的步骤升级双节点逻辑复制集群。 - - - - - 按照 - 的步骤升级级联逻辑复制集群。 - - - - - 按照 - 的步骤升级双节点环形逻辑复制集群。 - - - - - - - 升级双节点逻辑复制集群的步骤 - - 假设发布端位于 node1,订阅端位于 node2。 - 订阅端 node2 上有订阅 - sub1_node1_node2,用于订阅来自 node1 的变更。 - - - - - - 在 node2 上,使用 - ALTER SUBSCRIPTION ... DISABLE - 禁用所有订阅来自 node1 变更的订阅,例如: - -/* node2 # */ ALTER SUBSCRIPTION sub1_node1_node2 DISABLE; - - - - - - 停止 node1 上的发布端服务器,例如: - -pg_ctl -D /opt/PostgreSQL/data1 stop - - - - - - - 使用目标新版本初始化 data1_upgraded 实例。 - - - - - - 将发布端 node1 升级到目标新版本,例如: - -pg_upgrade - --old-datadir "/opt/PostgreSQL/postgres/17/data1" - --new-datadir "/opt/PostgreSQL/postgres/18/data1_upgraded" - --old-bindir "/opt/PostgreSQL/postgres/17/bin" - --new-bindir "/opt/PostgreSQL/postgres/18/bin" - - - - - - - 启动升级后的 node1 发布端服务器,例如: - -pg_ctl -D /opt/PostgreSQL/data1_upgraded start -l logfile - - - - - - - 停止 node2 上的订阅端服务器,例如: - -pg_ctl -D /opt/PostgreSQL/data2 stop - - - - - - - 使用目标新版本初始化 data2_upgraded 实例。 - - - - - - 将订阅端 node2 升级到目标新版本,例如: - -pg_upgrade - --old-datadir "/opt/PostgreSQL/postgres/17/data2" - --new-datadir "/opt/PostgreSQL/postgres/18/data2_upgraded" - --old-bindir "/opt/PostgreSQL/postgres/17/bin" - --new-bindir "/opt/PostgreSQL/postgres/18/bin" - - - - - - - 启动升级后的 node2 订阅端服务器,例如: - -pg_ctl -D /opt/PostgreSQL/data2_upgraded start -l logfile - - - - - - - 在 node2 上,创建从 - 到当前期间, - 升级后的发布端 node1 新建的表,例如: - -/* node2 # */ CREATE TABLE distributors (did integer PRIMARY KEY, name varchar(40)); - - - - - - - 在 node2 上,使用 - ALTER SUBSCRIPTION ... ENABLE - 启用所有订阅来自 node1 变更的订阅,例如: - -/* node2 # */ ALTER SUBSCRIPTION sub1_node1_node2 ENABLE; - - - - - - - 在 node2 上使用 - ALTER SUBSCRIPTION ... REFRESH PUBLICATION - 刷新订阅发布,例如: - -/* node2 # */ ALTER SUBSCRIPTION sub1_node1_node2 REFRESH PUBLICATION; - - - - - - - - 上述步骤中先升级发布端,再升级订阅端。也可以采用类似步骤先升级订阅端, - 再升级发布端。 - - - - - - 升级级联逻辑复制集群的步骤 - - 假设有级联逻辑复制拓扑 - node1->node2->node3。 - 其中 node2 订阅 node1 的变更, - node3 订阅 node2 的变更。 - node2 上有订阅 sub1_node1_node2, - node3 上有订阅 sub1_node2_node3。 - - - - - - 在 node2 上,使用 - ALTER SUBSCRIPTION ... DISABLE - 禁用所有订阅 node1 变更的订阅,例如: - -/* node2 # */ ALTER SUBSCRIPTION sub1_node1_node2 DISABLE; - - - - - - - 停止 node1 上的服务器,例如: - -pg_ctl -D /opt/PostgreSQL/data1 stop - - - - - - - 使用目标新版本初始化 data1_upgraded 实例。 - - - - - - 将 node1 服务器升级到目标新版本,例如: - -pg_upgrade - --old-datadir "/opt/PostgreSQL/postgres/17/data1" - --new-datadir "/opt/PostgreSQL/postgres/18/data1_upgraded" - --old-bindir "/opt/PostgreSQL/postgres/17/bin" - --new-bindir "/opt/PostgreSQL/postgres/18/bin" - - - - - - - 启动升级后的 node1 服务器,例如: - -pg_ctl -D /opt/PostgreSQL/data1_upgraded start -l logfile - - - - - - - 在 node3 上,使用 - ALTER SUBSCRIPTION ... DISABLE - 禁用所有订阅 node2 变更的订阅,例如: - -/* node3 # */ ALTER SUBSCRIPTION sub1_node2_node3 DISABLE; - - - - - - - 停止 node2 上的服务器,例如: - -pg_ctl -D /opt/PostgreSQL/data2 stop - - - - - - - 使用目标新版本初始化 data2_upgraded 实例。 - - - - - - 将 node2 服务器升级到目标新版本,例如: - -pg_upgrade - --old-datadir "/opt/PostgreSQL/postgres/17/data2" - --new-datadir "/opt/PostgreSQL/postgres/18/data2_upgraded" - --old-bindir "/opt/PostgreSQL/postgres/17/bin" - --new-bindir "/opt/PostgreSQL/postgres/18/bin" - - - - - - - 启动升级后的 node2 服务器,例如: - -pg_ctl -D /opt/PostgreSQL/data2_upgraded start -l logfile - - - - - - - 在 node2 上,创建从 - 到当前期间, - 升级后的发布端 node1 新建的表,例如: - -/* node2 # */ CREATE TABLE distributors (did integer PRIMARY KEY, name varchar(40)); - - - - - - - 在 node2 上,使用 - ALTER SUBSCRIPTION ... ENABLE - 启用所有订阅 node1 变更的订阅,例如: - -/* node2 # */ ALTER SUBSCRIPTION sub1_node1_node2 ENABLE; - - - - - - - 在 node2 上使用 - ALTER SUBSCRIPTION ... REFRESH PUBLICATION - 刷新订阅发布,例如: - -/* node2 # */ ALTER SUBSCRIPTION sub1_node1_node2 REFRESH PUBLICATION; - - - - - - - 停止 node3 上的服务器,例如: - -pg_ctl -D /opt/PostgreSQL/data3 stop - - - - - - - 使用目标新版本初始化 data3_upgraded 实例。 - - - - - - 将 node3 服务器升级到目标新版本,例如: - -pg_upgrade - --old-datadir "/opt/PostgreSQL/postgres/17/data3" - --new-datadir "/opt/PostgreSQL/postgres/18/data3_upgraded" - --old-bindir "/opt/PostgreSQL/postgres/17/bin" - --new-bindir "/opt/PostgreSQL/postgres/18/bin" - - - - - - - 启动升级后的 node3 服务器,例如: - -pg_ctl -D /opt/PostgreSQL/data3_upgraded start -l logfile - - - - - - - 在 node3 上,创建从 - 到当前期间, - 升级后的 node2 新建的表,例如: - -/* node3 # */ CREATE TABLE distributors (did integer PRIMARY KEY, name varchar(40)); - - - - - - - 在 node3 上,使用 - ALTER SUBSCRIPTION ... ENABLE - 启用所有订阅 node2 变更的订阅,例如: - -/* node3 # */ ALTER SUBSCRIPTION sub1_node2_node3 ENABLE; - - - - - - - 在 node3 上使用 - ALTER SUBSCRIPTION ... REFRESH PUBLICATION - 刷新订阅发布,例如: - -/* node3 # */ ALTER SUBSCRIPTION sub1_node2_node3 REFRESH PUBLICATION; - - - - - - - - 升级双节点环形逻辑复制集群的步骤 - - 假设有环形逻辑复制拓扑 - node1->node2 以及 - node2->node1。 - 其中 node2 订阅 node1 的变更, - node1 订阅 node2 的变更。 - node1 上有订阅 sub1_node2_node1, - node2 上有订阅 sub1_node1_node2。 - - - - - - 在 node2 上,使用 - ALTER SUBSCRIPTION ... DISABLE - 禁用所有订阅 node1 变更的订阅,例如: - -/* node2 # */ ALTER SUBSCRIPTION sub1_node1_node2 DISABLE; - - - - - - - 停止 node1 上的服务器,例如: - -pg_ctl -D /opt/PostgreSQL/data1 stop - - - - - - - 使用目标新版本初始化 data1_upgraded 实例。 - - - - - - 将 node1 服务器升级到目标新版本,例如: - -pg_upgrade - --old-datadir "/opt/PostgreSQL/postgres/17/data1" - --new-datadir "/opt/PostgreSQL/postgres/18/data1_upgraded" - --old-bindir "/opt/PostgreSQL/postgres/17/bin" - --new-bindir "/opt/PostgreSQL/postgres/18/bin" - - - - - - - 启动升级后的 node1 服务器,例如: - -pg_ctl -D /opt/PostgreSQL/data1_upgraded start -l logfile - - - - - - - 在 node2 上,使用 - ALTER SUBSCRIPTION ... ENABLE - 启用所有订阅 node1 变更的订阅,例如: - -/* node2 # */ ALTER SUBSCRIPTION sub1_node1_node2 ENABLE; - - - - - - - 在 node1 上,创建从 - 到当前期间, - node2 新建的表,例如: - -/* node1 # */ CREATE TABLE distributors (did integer PRIMARY KEY, name varchar(40)); - - - - - - - 在 node1 上使用 - ALTER SUBSCRIPTION ... REFRESH PUBLICATION - 刷新订阅发布,从 node2 复制初始表数据,例如: - -/* node1 # */ ALTER SUBSCRIPTION sub1_node2_node1 REFRESH PUBLICATION; - - - - - - - 在 node1 上,使用 - ALTER SUBSCRIPTION ... DISABLE - 禁用所有订阅 node2 变更的订阅,例如: - -/* node1 # */ ALTER SUBSCRIPTION sub1_node2_node1 DISABLE; - - - - - - - 停止 node2 上的服务器,例如: - -pg_ctl -D /opt/PostgreSQL/data2 stop - - - - - - - 使用目标新版本初始化 data2_upgraded 实例。 - - - - - - 将 node2 服务器升级到目标新版本,例如: - -pg_upgrade - --old-datadir "/opt/PostgreSQL/postgres/17/data2" - --new-datadir "/opt/PostgreSQL/postgres/18/data2_upgraded" - --old-bindir "/opt/PostgreSQL/postgres/17/bin" - --new-bindir "/opt/PostgreSQL/postgres/18/bin" - - - - - - - 启动升级后的 node2 服务器,例如: - -pg_ctl -D /opt/PostgreSQL/data2_upgraded start -l logfile - - - - - - - 在 node1 上,使用 - ALTER SUBSCRIPTION ... ENABLE - 启用所有订阅 node2 变更的订阅,例如: - -/* node1 # */ ALTER SUBSCRIPTION sub1_node2_node1 ENABLE; - - - - - - - 在 node2 上,创建从 - 到当前期间, - 升级后的 node1 新建的表,例如: - -/* node2 # */ CREATE TABLE distributors (did integer PRIMARY KEY, name varchar(40)); - - - - - - - 在 node2 上使用 - ALTER SUBSCRIPTION ... REFRESH PUBLICATION - 刷新订阅发布,从 node1 复制初始表数据,例如: - -/* node2 # */ ALTER SUBSCRIPTION sub1_node1_node2 REFRESH PUBLICATION; - - - - - - - + + 订阅端也必须设置max_replication_slots。它应至少设置为将要添加到订阅端的订阅数,加上为表同步预留的一些余量。max_logical_replication_workers必须至少设置为订阅数,加上为表同步预留的余量。此外,max_worker_processes可能需要调整以容纳复制工作进程,至少为(max_logical_replication_workers + 1)。注意一些扩展和并行查询也会占用max_worker_processes中的工作进程槽。 + + 快速设置 @@ -2844,7 +1397,7 @@ wal_level = logical 需要调整 pg_hba.conf 以允许复制 (这里的值取决于实际网络配置以及要用于连接的用户): -host all repuser 0.0.0.0/0 scram-sha-256 +host all repuser 0.0.0.0/0 md5 diff --git a/zh/15/logicaldecoding.sgml b/zh/15/logicaldecoding.sgml index 82a151c0..8ee14c4b 100644 --- a/zh/15/logicaldecoding.sgml +++ b/zh/15/logicaldecoding.sgml @@ -291,28 +291,6 @@ postgres=# select * from pg_logical_slot_get_changes('regression_slot', NULL, NU 在任意给定时刻,只允许一个接收端从某个槽中消费更改。 - - 逻辑复制槽也可以在热备上创建。为了防止 VACUUM 从系 - 统目录中移除所需的行,应当在备库上设置 hot_standby_feedback。 - 即便如此,如果任何所需行仍被移除,槽也会失效。强烈建议在主库和备库之间 - 使用物理复制槽。否则,hot_standby_feedback 虽然也能 - 工作,但只在连接存活期间有效(例如节点重启就会打断它)。随后主库可能会删 - 除备库上逻辑解码所需的系统目录行(因为它并不知道备库上的 - catalog_xmin)。如果主库上的 wal_level - 降低到小于 logical,备库上现有的逻辑槽也会失效。这会 - 在备库检测到 WAL 流中的该变化后立刻发生。这意味着,对于落后的 WAL 发送 - 器(如果有),直到主库上 wal_level 参数变更为止的一些 - WAL 记录将不会被解码。 - - - - 创建逻辑槽需要有关当前所有正在运行事务的信息。在主库上,这些信息可以直接 - 获得;但在备库上,这些信息必须从主库获取。因此,创建槽可能需要等待主库上 - 发生某些活动。如果主库空闲,在备库上创建逻辑槽可能会花费可察觉的时间。 - 通过在主库上调用 pg_log_standby_snapshot 函数可以加 - 快这一过程。 - - 复制槽可跨崩溃持久存在,而且不了解其消费者的状态。即使没有连接使用它们, @@ -326,97 +304,7 @@ postgres=# select * from pg_logical_slot_get_changes('regression_slot', NULL, NU - - 复制槽同步 - - 主库上的逻辑复制槽可以通过 - failover 参数同步到热备,该参数用于 - - pg_create_logical_replication_slot;或者在创建槽 - 时执行带有 - - failover 选项的 - CREATE SUBSCRIPTION,也可以把主库上的逻辑复制槽同步 - 到热备。另外,还必须在备库上启用 - sync_replication_slots。在备库上启用 - sync_replication_slots 后,故障切换槽就可以由 - slotsync 工作进程定期同步。要让同步生效,主库和备库之间必须使 - 用物理复制槽(也就是说,备库上应当配置 - primary_slot_name), - 并且备库上必须启用 - hot_standby_feedback。 - 还必须指定有效的 dbname,并将其放在 - primary_conninfo - 中。强烈建议在主库的 - synchronized_standby_slots - 列表中写入上述物理复制槽的名称,以防止订阅者消费更改的速度快于热备的接 - 收进度。 - 即使配置正确,由于需要等待 - synchronized_standby_slots - 中列出的槽,向逻辑订阅者发送更改时仍然会有一定延迟。使用 - synchronized_standby_slots 时,主库在与 - synchronized_standby_slots 中指定的物理复制槽相关联 - 的备库确认已接收到截至主库最新刷写位置的 WAL 之前,不会完全关闭。 - - - - - 虽然启用 sync_replication_slots 允许对故障切换槽进行自 - 动、周期性的同步,但也可以在备库上使用 - - pg_sync_replication_slots 函数手工同步。然 - 而,该函数主要用于测试和调试,应当谨慎使用。与自动同步不同,它不包含循 - 环重试,因此更容易发生同步失败,尤其是在初始同步场景中:槽所需的 WAL - 文件或系统目录行可能已经被删除,或者在备库上处于可能被删除的风险之中。相 - 比之下,通过 sync_replication_slots 实现的自动同步 - 会持续更新槽,从而实现无缝故障切换并支持高可用。因此,这是推荐的槽同步 - 方法。 - - - - - 当按建议完成配置,并且初始同步已经通过自动方式或通过 - pg_sync_replication_slots 手工执行后,备库只有在 - 满足以下条件时才能将同步后的槽持久化:主库上的逻辑复制槽必须保留那些在 - 备库上仍可用的 WAL 和系统目录行。这样可以保证数据完整性,并允许在提升 - 后顺畅继续逻辑复制。如果备库上所需的 WAL 或系统目录行已经被清除,则该槽不 - 会被持久化,以避免数据丢失。此时,可能会出现如下日志消息: - -LOG: could not synchronize replication slot "failover_slot" -DETAIL: Synchronization could lead to data loss, because the remote slot needs WAL at LSN 0/3003F28 and catalog xmin 754, but the standby has LSN 0/3003F28 and catalog xmin 756. - - 如果某个消费者正在积极使用该逻辑复制槽,则无需人工干预;槽会自动前进, - 并在下一个周期恢复同步。不过,如果没有配置消费者,则建议在主库上使用 - - pg_logical_slot_get_changes 或 - - pg_logical_slot_get_binary_changes 手工推进该 - 槽,以便同步继续进行。 - - - - 故障切换后能否继续逻辑复制,取决于故障发生时备库上的同步槽在 - pg_replication_slots.synced - 列中的值。只有在故障切换前其值已经在备库上变为 true 的持久槽,才能在故 - 障切换后继续用于逻辑复制。临时同步槽不能用于逻辑解码,因此这些槽的逻辑 - 复制无法恢复。例如,如果某个同步槽由于订阅被禁用而无法在备库上变为持久 - 槽,那么即使之后启用了订阅,故障切换后也无法恢复该订阅。 - - - 要在故障切换后从已同步的逻辑槽恢复逻辑复制,必须修改订阅的 'conninfo',使 - 其指向新的主库。这可以使用 - ALTER SUBSCRIPTION ... CONNECTION - 完成。建议先禁用订阅,再提升备库,并在修改连接字符串之后重新启用订阅。 - - - - 在提升过程中,旧主库有可能重新上线;如果订阅未被禁用,那么即使完成提 - 升,逻辑订阅者仍可能继续从旧主库接收数据,直到连接字符串被修改为止。这 - 可能导致数据不一致问题,使逻辑订阅者无法继续从新的主库复制。 - - - 输出插件 diff --git a/zh/15/maintenance.sgml b/zh/15/maintenance.sgml index 2f6af878..2c9c547e 100644 --- a/zh/15/maintenance.sgml +++ b/zh/15/maintenance.sgml @@ -378,32 +378,24 @@ 不一定会冻结表中的每一个旧行版本。在这种情况下,VACUUM 最终需要执行一次 激进扫描,它会冻结所有符合条件且尚未冻结的 XID 和 MXID 值, 包括那些来自全部可见(all-visible)但未全部冻结(all-frozen)页面的值。 - - - - 如果一个表正在积累全部可见但尚未全部冻结的页面,普通清理可能会选择扫描这些本可跳过的页面, - 以尝试冻结它们。这样可以减少下一次激进扫描必须扫描的页面数。这类页面称为 - 积极扫描页。通过增大 ,可以调整积极扫描, - 使其尝试冻结更多全部可见页面。即使积极扫描已将全部可见但未全部冻结页面的数量降到最低, - 大多数表仍然需要周期性地进行激进扫描。不过,任何成功被积极冻结的页面在激进扫描时都可以跳过, - 因此积极冻结可以尽量减小激进扫描的开销。 - - - + 在实际使用中,大多数表需要周期性地进行激进扫描。 - 控制何时对表执行激进扫描。如果距离上一次这类扫描以来经过的事务数大于 + 控制VACUUM何时对表执行激进扫描:如果距离上一次这类扫描以来经过的事务数大于 vacuum_freeze_table_age 减去 vacuum_freeze_min_age,就会扫描所有全部可见但未全部冻结的页面。 把 vacuum_freeze_table_age 设为 0 会强制 VACUUM 始终采用其激进策略。 + + + + 一个表在不被清理的情况下所能维持的最长时间,是最后一次激进扫描时的 vacuum_freeze_min_age 值从 20 亿事务中扣除后的结果。 如果超过这个时间仍不清理,就可能导致数据丢失。为了确保不会发生这种情况, - 任何可能包含未冻结行且其 XID 早于配置参数 所指定年龄的表,都会触发自动清理。 (即使自动清理已被禁用,也会如此。) @@ -491,12 +483,10 @@ SELECT datname, age(datfrozenxid) FROM pg_database; - 虽然 VACUUM 主要扫描自上次清理以来被修改过的页面, - 但它也可能为了冻结它们而积极扫描某些全部可见但未全部冻结的页面; - 不过,只有当表中每一个可能包含未冻结 XID 的页面都被扫描时, + VACUUM 通常只扫描自上次清理以来被修改过的页面,但只有 + 当表中每一个可能包含未冻结 XID 的页面都被扫描时, relfrozenxid 才会被推进。当 - relfrozenxid 比 - vacuum_freeze_table_age 旧、使用了 VACUUM 的 + relfrozenxid的年龄超过vacuum_freeze_table_age个事务、使用了 VACUUMFREEZE 选项,或者所有尚未全部冻结的页面碰巧都需要清理以移除死行版本时, 就会发生这种情况。当 VACUUM 扫描了表中每个尚未全部冻结的页面时, 它应把 age(relfrozenxid) 设为略高于所用 @@ -515,7 +505,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; WARNING: database "mydb" must be vacuumed within 39985967 transactions -HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. +HINT: To avoid a database shutdown, execute a database-wide VACUUM in that database. (如提示所建议,手工执行 VACUUM 应能解决问题;但要注意, @@ -524,13 +514,13 @@ HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that 如果忽略这些警告,一旦距离回卷只剩不到三百万个事务,系统就会拒绝分配新的 XID: -ERROR: database is not accepting commands that assign new XIDs to avoid wraparound data loss in database "mydb" -HINT: Execute a database-wide VACUUM in that database. +ERROR: database is not accepting commands to avoid wraparound data loss in database "mydb" +HINT: Stop the postmaster and vacuum that database in single-user mode. 在这种状态下,已经在进行中的事务可以继续,但只能启动只读事务。 修改数据库记录或截断关系的操作都会失败。VACUUM 命令仍然可以正常执行。 - 请注意,与早期版本中有时给出的建议相反,为了恢复正常运行, + 与提示内容相反,为了恢复正常运行, 不需要也不希望停止 postmaster 或进入单用户模式。相反,请按以下步骤操作: @@ -595,22 +585,22 @@ HINT: Execute a database-wide VACUUM in that database. 多事务(multitransaction,MultiXact) ID 用于支持多个事务对行加锁。由于元组头中用于存储锁信息的空间有限, 当有多个事务同时锁定一行时,这些信息会被编码为一个多事务 ID, - 简称 multixact ID。某个特定 multixact ID 包含哪些事务 ID 的信息, + 简称 multixact ID。某个特定 多事务 ID 包含哪些事务 ID 的信息, 会单独存放在 pg_multixact 子目录中,而元组头的 - xmax 字段中只出现 multixact ID。和事务 ID 一样, - multixact ID 也是以 32 位计数器及其对应存储实现的,因此同样需要仔细处理老化管理、 - 存储清理和回卷问题。还有一个单独的存储区域保存每个 multixact 的成员列表, + xmax 字段中只出现 多事务 ID。和事务 ID 一样, + 多事务 ID 也是以 32 位计数器及其对应存储实现的,因此同样需要仔细处理老化管理、 + 存储清理和回卷问题。还有一个单独的存储区域保存每个 多事务 的成员列表, 它也使用 32 位计数器,因此同样必须被管理。 中介绍的系统函数 pg_get_multixact_members() - 可用于检查与某个 multixact ID 关联的事务 ID。 + 可用于检查与某个 多事务 ID 关联的事务 ID。 每当 VACUUM 扫描表的任何部分时,它都会把遇到的、早于 - 的任何 multixact ID 替换为另一个值,该值可能是零值、单个事务 ID,或者更新的 multixact ID。 + 的任何 多事务 ID 替换为另一个值,该值可能是零值、单个事务 ID,或者更新的 多事务 ID。 对于每个表,pg_class.relminmxid - 保存该表任何元组中仍可能出现的最老 multixact ID。如果这个值早于 + 保存该表任何元组中仍可能出现的最老 多事务 ID。如果这个值早于 ,就会强制执行一次激进扫描。 正如上一节所述,激进扫描意味着只有那些已知为全部冻结的页面才会被跳过。 可以对 pg_class.relminmxid @@ -620,14 +610,14 @@ HINT: Execute a database-wide VACUUM in that database. 无论出于何种原因而发生,激进的 VACUUM保证 能够推进表的 relminmxid。最终,随着所有数据库中的所有表都被扫描, - 并推进其最老的 multixact 值,较老 multixact 的磁盘存储就可以被移除。 + 并推进其最老的 多事务 值,较老 多事务 的磁盘存储就可以被移除。 - 作为一项安全措施,对于 multixact 年龄大于 的任何表,都会进行一次激进扫描。 - 此外,如果 multixact 成员占用的存储超过大约 10GB,则会更频繁地对所有表进行激进扫描, - 从 multixact 年龄最老的表开始。即便自动清理名义上被禁用,这两类激进扫描也都会发生。 + 此外,如果 多事务 成员占用的存储超过大约 10GB,则会更频繁地对所有表进行激进扫描, + 从 多事务 年龄最老的表开始。即便自动清理名义上被禁用,这两类激进扫描也都会发生。 成员存储区域在到达回卷之前最多可增长到大约 20GB。 @@ -644,11 +634,11 @@ HINT: Execute a database-wide VACUUM in that database. - 如果没有可能出现在 multixact 中,那么正在运行的事务和预备事务都可以忽略。 + 如果没有可能出现在 多事务 中,那么正在运行的事务和预备事务都可以忽略。 - 与事务 ID 回卷不同,复制槽不会直接阻止 multixact 清理。 - 因此,删除陈旧的复制槽通常与解决 multixact ID 回卷问题无关。 + 与事务 ID 回卷不同,复制槽不会直接阻止 多事务 清理。 + 因此,删除陈旧的复制槽通常与解决 多事务 ID 回卷问题无关。 MXID 信息不会直接出现在诸如 pg_stat_activity 这样的系统视图中; @@ -703,50 +693,15 @@ HINT: Execute a database-wide VACUUM in that database. 的限制。 - - 对于 relfrozenxid 值早于 - 个事务的表,总是会执行清理 - (这也适用于那些通过存储参数修改了冻结最大年龄的表,见下文)。 - 否则,如果自上次 VACUUM 以来已经失效的元组数超过了 - 清理阈值,就会对该表执行清理。清理阈值定义如下: - -vacuum threshold = Minimum(vacuum max threshold, vacuum base threshold + vacuum scale factor * number of tuples) - - 其中,vacuum max threshold 是 - , - vacuum base threshold 是 - , - vacuum scale factor 是 - , - 而元组数是 - pg_class.reltuples。 + 凡是 relfrozenxid 值的年龄超过 个事务的表,始终都会被清理(这也适用于通过存储参数修改了最大冻结年龄的表,见下文)。否则,如果自上次 VACUUM 以来失效的元组数超过清理阈值,就会清理该表。清理阈值定义为: +vacuum threshold = vacuum base threshold + vacuum scale factor * number of tuples +其中,清理基础阈值为 ,清理比例因子为 ,元组数为 pg_class.reltuples - - 如果自上次清理以来插入的元组数超过了定义的插入阈值,也会对该表执行清理,该阈值定义如下: - -vacuum insert threshold = vacuum base insert threshold + vacuum insert scale factor * number of tuples * percent of table not frozen - - 其中,vacuum insert base threshold 是 - , - vacuum insert scale factor 是 - , - 元组数是 - pg_class.reltuples, - 而表中未冻结部分的百分比是 - 1 - pg_class.relallfrozen / pg_class.relpages。 - 这样的清理可能使表的一部分被标记为全部可见, - 并且也允许元组被冻结,从而减少后续清理所需的工作。对于只接收 - INSERT 操作、但没有或几乎没有 UPDATE / - DELETE 操作的表,降低该表的 - 可能是有益的, - 因为这会让元组在更早的清理中被冻结。过时元组数和插入元组数取自累积统计系统; - 这是一个由每次 UPDATEDELETE 和 - INSERT 操作更新的最终一致计数。如果该表的 - relfrozenxid 值早于 - vacuum_freeze_table_age 个事务,就会执行一次激进扫描, - 以冻结旧元组并推进 relfrozenxid。 - + 如果自上次清理以来插入的元组数超过了定义的插入阈值,也会清理该表。插入阈值定义为: +vacuum insert threshold = vacuum base insert threshold + vacuum insert scale factor * number of tuples +其中,清理插入基础阈值为 ,清理插入比例因子为 。这种清理可以将表的部分区域标记为全部可见,并允许冻结元组,从而减少后续清理所需的工作。对于有 INSERT 操作,但没有或几乎没有 UPDATE/DELETE 操作的表,降低表的 可能有益,因为这可能让元组在更早的清理中被冻结。失效元组数和插入元组数来自累积统计系统;这些计数只是近似值,由每次 UPDATE, + DELETEINSERT 操作更新。(之所以只是近似值,是因为高负载下可能丢失部分信息。)如果表的 relfrozenxid 值的年龄超过 vacuum_freeze_table_age 个事务,就会执行激进清理,冻结旧元组并推进 relfrozenxid;否则,只扫描自上次清理以来被修改过的页面。 对于分析操作,也使用了一个类似的条件:其阈值定义如下: @@ -944,7 +899,7 @@ pg_ctl start | rotatelogs /var/log/pgsql_log 86400 不过,在很多系统上,syslog 并不十分可靠, 尤其是在日志消息很大时;它可能恰恰在你最需要消息的时候截断或丢弃它们。 此外,在 Linux 上, - syslog 会把每条消息都刷新到磁盘,导致性能较差。 + syslog 会把每条消息都刷盘,导致性能较差。 (你可以在 syslog 配置文件的文件名开头使用一个 - 来禁用同步。) diff --git a/zh/15/monitoring.sgml b/zh/15/monitoring.sgml index 4eded6fa..a39037a5 100644 --- a/zh/15/monitoring.sgml +++ b/zh/15/monitoring.sgml @@ -87,15 +87,15 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - 累计统计系统 + 累积统计系统 - statistics + 统计信息 PostgreSQL累积统计系统支持收集和报告有关服务器活动的信息。 - 目前,对表和索引的访问以磁盘块和单个行的术语进行计数。每个表中的总行数, + 目前,对表和索引的访问分别以磁盘块和单行计数。每个表中的总行数, 以及每个表的清理和分析操作的信息也被计数。如果启用,对用户定义函数的调用 和每个函数中花费的总时间也会被计数。 @@ -107,7 +107,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - 统计收集配置 + 统计信息收集配置 由于收集统计信息会增加查询执行的开销,因此可以配置系统是否收集信息。这由通常在postgresql.conf中设置的配置参数控制(有关设置配置参数的详细信息,请参阅)。 @@ -117,9 +117,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 参数启用对任意服务器进程当前执行命令的监控。 - - 参数启用对基于代价的清理延迟的监控。 - + 参数控制是否收集关于表和索引访问的累积统计信息。 @@ -130,12 +128,10 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - 参数启用对块读取、写入、扩展和 fsync 时间的监控。 + 参数启用对块读取和写入时间的监控。 - - 参数启用对 WAL 读取、写入和 fsync 时间的监控。 - + 参数启用对 WAL 写入时间的监控。 通常,这些参数会设置在postgresql.conf中,以便它们适用于所有服务器进程,但也可以在单个会话中使用命令打开或关闭它们。(为防止普通用户隐藏其活动不被管理员发现,只有超级用户才能使用SET更改这些参数。) @@ -160,11 +156,11 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - 另一个重要的观点是,当服务器进程被要求显示任何累积的统计信息时,在默认配置中,访问的值会被缓存直到当前事务结束。因此,只要您继续当前事务,统计信息将显示静态信息。类似地,当在事务中首次请求任何当前会话的查询信息时,会收集关于所有会话当前查询的信息,并且相同的信息将在整个事务中显示。这是一个特性,而不是一个错误,因为它允许您在统计信息上执行多个查询并将结果相关联,而不必担心数字在您眼前发生变化。 + 另一个重要的观点是,当服务器进程被要求显示任何累积的统计信息时,在默认配置中,访问的值会被缓存直到当前事务结束。因此,只要你继续当前事务,统计信息将显示静态信息。类似地,当在事务中首次请求这类当前查询信息时,会收集关于所有会话当前查询的信息,并且相同的信息将在整个事务中显示。这是一个特性,而不是一个错误,因为它允许你在统计信息上执行多个查询并将结果相关联,而不必担心数字在你眼前发生变化。 - 在交互式分析统计信息或使用昂贵的查询时,访问各个统计信息之间的时间差可能导致缓存统计信息中出现显著的偏差。为了最小化偏差,可以将stats_fetch_consistency设置为snapshot,但这会增加用于缓存不需要的统计数据的内存使用量。相反,如果已知统计信息只被访问一次,那么缓存访问的统计信息是不必要的,可以通过将stats_fetch_consistency设置为none来避免。 + 在交互式分析统计信息或使用开销较大的查询时,访问各个统计信息之间的时间差可能导致缓存统计信息中出现显著的偏差。为了最小化偏差,可以将stats_fetch_consistency设置为snapshot,但这会增加用于缓存不需要的统计数据的内存使用量。相反,如果已知统计信息只被访问一次,那么缓存访问的统计信息是不必要的,可以通过将stats_fetch_consistency设置为none来避免。 - 您可以调用pg_stat_clear_snapshot()来丢弃当前事务的统计快照或缓存的值(如果有)。下一次使用统计信息时(在快照模式下),将会创建一个新的快照,或者(在缓存模式下)将访问的统计信息缓存起来。 + 你可以调用pg_stat_clear_snapshot()来丢弃当前事务的统计快照或缓存的值(如果有)。下一次使用统计信息时(在快照模式下),将会创建一个新的快照,或者(在缓存模式下)将访问的统计信息缓存起来。 @@ -176,11 +172,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 相反,它们在事务期间持续更新。 - - 动态统计视图中显示的一些信息在中受到安全限制。 - 普通用户只能查看关于他们自己会话的所有信息(属于他们是成员的角色的会话)。在关于其他会话的行中,许多列将为空。 - 但是,请注意,所有用户都可以看到会话的存在以及其一般属性,如会话用户和数据库。超级用户和具有内置角色pg_read_all_stats权限的角色(另请参阅)可以查看所有会话的所有信息。 - + 所列动态统计视图中的一些信息受到安全限制。普通用户只能查看其自身会话的全部信息(包括属于其所加入角色的会话)。对于其他会话的行,许多列将为空值。不过,会话的存在及其一般属性(例如会话用户和数据库)对所有用户都可见。超级用户和具有内置角色pg_read_all_stats权限的角色(另请参阅)可以查看所有会话的全部信息。 @@ -215,7 +207,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser pg_stat_wal_receiverpg_stat_wal_receiver - 只有一行,显示有关 WAL 接收进程从其连接服务器接收到的统计信息。有关详细信息,请参阅pg_stat_wal_receiver。 + 只有一行,显示 WAL 接收进程从其所连接服务器接收数据的统计信息。有关详细信息,请参阅pg_stat_wal_receiver @@ -305,36 +297,30 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - + pg_stat_bgwriterpg_stat_bgwriter 只有一行,显示有关后台写入器活动的信息。有关详细信息,请参阅pg_stat_bgwriter - - pg_stat_checkpointerpg_stat_checkpointer - 只有一行,显示有关检查点进程活动的信息。有关详细信息,请参阅pg_stat_checkpointer。 - - - - + pg_stat_walpg_stat_wal 只有一行,显示有关 WAL 活动的统计信息。有关详细信息,请参阅pg_stat_wal - + pg_stat_databasepg_stat_database 每个数据库一行,显示数据库范围的统计信息。有关详细信息,请参阅pg_stat_database - + pg_stat_database_conflictspg_stat_database_conflicts 每个数据库一行,显示数据库范围内因备库上的恢复冲突而导致查询被取消的统计信息。有关详细信息,请参阅pg_stat_database_conflicts - + pg_stat_all_tablespg_stat_all_tables 当前数据库中每个表一行,显示有关访问指定表的统计信息。详见 @@ -342,114 +328,114 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - + pg_stat_sys_tablespg_stat_sys_tables pg_stat_all_tables一样,但只显示系统表。 - + pg_stat_user_tablespg_stat_user_tables pg_stat_all_tables一样,但只显示用户表。 - + pg_stat_xact_all_tablespg_stat_xact_all_tables - pg_stat_all_tables相似,但计数动作只在当前事务内发生(还没有被包括在pg_stat_all_tables和相关视图中)。用于生存和死亡行数量的列以及清理和分析动作在此视图中不出现。 + pg_stat_all_tables 相似,但只统计当前事务中截至目前执行的操作(这些操作尚计入 pg_stat_all_tables 及相关视图)。此视图不包含存活行和死行数量以及清理、分析操作的列。 - + pg_stat_xact_sys_tablespg_stat_xact_sys_tables pg_stat_xact_all_tables一样,但只显示系统表。 - + pg_stat_xact_user_tablespg_stat_xact_user_tables pg_stat_xact_all_tables一样,但只显示用户表。 - + pg_stat_all_indexespg_stat_all_indexes 当前数据库中的每个索引一行,显示有关访问该特定索引的统计信息。有关详细信息,请参阅pg_stat_all_indexes - + pg_stat_sys_indexespg_stat_sys_indexes pg_stat_all_indexes一样,但只显示系统表上的索引。 - + pg_stat_user_indexespg_stat_user_indexes pg_stat_all_indexes一样,但只显示用户表上的索引。 - + pg_statio_all_tablespg_statio_all_tables 当前数据库中的每个表一行,显示有关访问该特定表的 I/O 统计信息。有关详细信息,请参阅pg_statio_all_tables - + pg_statio_sys_tablespg_statio_sys_tables pg_statio_all_tables一样,但只显示系统表。 - + pg_statio_user_tablespg_statio_user_tables pg_statio_all_tables一样,但只显示用户表。 - + pg_statio_all_indexespg_statio_all_indexes 当前数据库中的每个索引一行,显示有关访问该特定索引的 I/O 统计信息。有关详细信息,请参阅pg_statio_all_indexes - + pg_statio_sys_indexespg_statio_sys_indexes pg_statio_all_indexes一样,但只显示系统表上的索引。 - + pg_statio_user_indexespg_statio_user_indexes pg_statio_all_indexes一样,但只显示用户表上的索引。 - + pg_statio_all_sequencespg_statio_all_sequences 当前数据库中的每个序列一行,显示有关访问该特定序列的 I/O 统计信息。有关详细信息,请参阅pg_statio_all_sequences - + pg_statio_sys_sequencespg_statio_sys_sequences pg_statio_all_sequences一样,但只显示系统序列(目前没有定义系统序列,因此这个视图总是为空)。 - + pg_statio_user_sequencespg_statio_user_sequences pg_statio_all_sequences一样,但只显示用户序列。 - + pg_stat_user_functionspg_stat_user_functions 每个被跟踪的函数一行,显示有关该函数执行的统计信息。有关详细信息,请参阅pg_stat_user_functions - + pg_stat_xact_user_functionspg_stat_xact_user_functions pg_stat_user_functions相似,但是只统计在当前事务期间的调用(还没有被包括在pg_stat_user_functions中)。 - + pg_stat_slrupg_stat_slru 每个 SLRU 一行,显示操作统计信息。有关详细信息,请参阅pg_stat_slru - + pg_stat_replication_slotspg_stat_replication_slots 每个复制槽一行,显示有关复制槽使用情况的统计信息。有关详细信息,请参阅pg_stat_replication_slots - + pg_stat_subscription_statspg_stat_subscription_stats - 每个订阅一行,显示有关错误和冲突的统计信息。有关详细信息,请参阅pg_stat_subscription_stats + 每个订阅一行,显示有关错误的统计信息。有关详细信息,请参阅pg_stat_subscription_stats @@ -563,7 +549,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser client_addr inet - 连接到这个后端的客户端的 IP 地址。如果这个字段为空,它表示客户端通过服务器机器上的一个 Unix 套接字连接或者这是一个内部进程,如自动清理。 + 连接到这个后端的客户端的 IP 地址。如果这个字段为空值,它表示客户端通过服务器机器上的一个 Unix 套接字连接或者这是一个内部进程,如自动清理。 @@ -582,7 +568,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser client_port integer - 客户端用于与此后端通信的TCP端口号,如果使用Unix套接字,则为-1。如果该字段为空,它表示这是一个内部服务器进程。 + 客户端用于与此后端通信的TCP端口号,如果使用Unix套接字,则为-1。如果该字段为空值,它表示这是一个内部服务器进程。 @@ -600,8 +586,8 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser xact_start timestamp with time zone - 这个进程的当前事务被启动的时间,如果没有活动事务则为空。 - 如果当前查询是它的第一个事务,这一列等于query_start列。 + 这个进程的当前事务被启动的时间,如果没有活动事务则为空值。 + 如果当前查询是其事务中的第一个查询,这一列等于query_start列。 @@ -628,7 +614,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser wait_event_type text - 后端正在等待的事件类型(如果有);否则为NULL。请参阅。 + 后端正在等待的事件类型(如果有);否则为空值。请参阅 @@ -637,7 +623,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser wait_event text - 如果此后端当前正在等待,则返回等待事件名称,否则为NULL。请参阅。 + 如果此后端当前正在等待,则返回等待事件名称,否则为空值。请参阅 @@ -645,44 +631,24 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser state text - - 这个后端的当前总体状态。可能的值为: - + 该后端当前的总体状态。可能的值为: - - starting: 后端正处于初始启动阶段。客户端认证在此阶段执行。 - - - - - active: 后端正在执行一个查询。 - + active:后端正在执行一个查询。 - - idle: 后端正在等待一个新的客户端命令。 - + idle:后端正在等待新的客户端命令。 - - idle in transaction: 后端在一个事务中,但是当前没有正在执行一个查询。 - + idle in transaction:后端处于事务中,但当前没有执行查询。 - - idle in transaction (aborted): 这个状态与 - idle in transaction相似,除了在该事务中的一个语句导致了一个错误。 - + idle in transaction (aborted):该状态与idle in transaction类似,但事务中的某个语句导致了错误。 - - fastpath function call: 后端正在执行一个 fast-path 函数。 - + fastpath function call:后端正在执行一个快速路径函数。 - - disabled: 如果在这个后端中被禁用,则报告这个状态。 - + disabled:如果在此后端中禁用了,就会报告此状态。 @@ -702,7 +668,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser backend_xmin xid - 当前后端的xmin范围。 + 当前后端的xmin视界。 @@ -714,7 +680,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 这个后端的最近查询的标识符。 如果stateactive,这个字段显示当前正在执行的查询的标识符。 在所有其他状态,它显示执行的最后一个查询的标识符。 - 默认不计算查询标识符,因此该字段将为空,除非启用参数或配置了计算查询标识符的第三方模块。 + 默认不计算查询标识符,因此该字段将为空值,除非启用参数或配置了计算查询标识符的第三方模块。 @@ -732,19 +698,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser backend_type text - - 当前后端的类型。可能的类型为 - autovacuum launcher, autovacuum worker, - logical replication launcher, - logical replication worker, - parallel worker, background writer, - client backend, checkpointer, - archiver, standalone backend, - startup, walreceiver, - walsender, walwriter 以及 - walsummarizer。 - 此外,由扩展注册的后台工作进程还可能有额外的类型。 - + 当前后端的类型。可能的类型为autovacuum launcherautovacuum workerlogical replication launcherlogical replication workerparallel workerbackground writerclient backendcheckpointerarchiverstartupwalreceiverwalsenderwalwriter。此外,由扩展注册的后台工作进程还可能有额外的类型。 @@ -753,7 +707,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - wait_eventstate列彼此独立。如果某个后端处于active状态,它既可能正在等待某个事件,也可能没有等待。如果状态为activewait_event非空,就意味着某个查询正在执行,但在系统中的某处被阻塞了。为将报告开销保持在较低水平,系统不会尝试为某个后端同步活动数据的不同方面。因此,视图各列之间可能暂时存在不一致。 + wait_eventstate列彼此独立。如果某个后端处于active状态,它可能在等待(waiting)某个事件,也可能没有等待。如果状态为activewait_event非空,就意味着某个查询正在执行,但在系统中的某处被阻塞了。 @@ -780,10 +734,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser BufferPin - 服务器进程正在等待对数据缓冲的独占访问。 - 如果另一个进程持有一个打开的游标,该游标最后一次从相关缓冲区读取数据,则缓冲区销等待可能是漫长的。 - 参见。 - + 服务器进程正在等待独占访问一个数据缓冲区。如果另一个进程持有尚未关闭的游标,且该游标最近读取的数据来自此缓冲区,缓冲区钉住等待就可能持续较长时间。参见 @@ -799,14 +750,11 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - - InjectionPoint - 服务器进程正在等待某个注入点在测试中达到预定义结果。更多细节请参见。该类型没有预定义的等待点。 - + IO - 服务器进程正在等待一个I/O操作完成。wait_event将识别特定的等待点;参见。 + 服务器进程正在等待一个 I/O 操作完成。wait_event将识别特定的等待点;参见 @@ -818,17 +766,14 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser Lock - 服务器进程正在等待一个重量级锁。重量级锁,也称为锁管理器锁或简单锁,主要保护表等SQL可见对象。 + 服务器进程正在等待一个重量级锁。重量级锁,也称为锁管理器锁或简称为锁,主要保护表等SQL可见对象。 然而,它们也用于确保某些内部操作的互斥,例如关系扩展。wait_event将识别等待的锁的类型;参见 LWLock - 服务器进程正在等待一个轻量级锁。大多数这样的锁保护共享内存中的特定数据结构。 - wait_event将包含标识轻量级锁用途的名称。 - (有些锁有特定的名称;其他锁是一组锁的一部分,每个锁具有类似的目的。)参见。 - + 服务器进程正在等待一个轻量级锁。大多数这样的锁保护共享内存中的某个特定数据结构。wait_event将包含标识该轻量级锁用途的名称。(有些锁具有专门的名称,另一些锁属于一组用途相似的锁。)参见 @@ -861,12 +806,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser AutoVacuumMain - 在自动清理启动过程的主循环中等待。 + 在自动清理启动进程的主循环中等待。 BgWriterHibernate - 在后台写入器中等待,休眠状态。 + 在后台写入器进程中休眠等待。 @@ -891,7 +836,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser RecoveryWalStream - 流恢复期间,在启动进程主循环等待WAL到达。 + 在流恢复期间,在启动进程的主循环中等待 WAL 到达。 @@ -901,7 +846,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser WalReceiverMain - 在WAL 接收进程的主循环中等待。 + 在 WAL 接收进程的主循环中等待。 @@ -911,7 +856,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser WalWriterMain - 在WAL写入进程的主循环中等待。 + 在 WAL 写入进程的主循环中等待。 @@ -933,7 +878,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser BufferPin - 等待获得缓冲区上的独占销。 + 等待获得缓冲区上的独占钉住。 @@ -970,12 +915,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser LibPQWalReceiverConnect - 在WAL 接收进程等待与远程服务器建立连接。 + 在 WAL 接收进程中等待与远程服务器建立连接。 LibPQWalReceiverReceive - 在WAL 接收进程中等待从远程服务器接收数据。 + 在 WAL 接收进程中等待从远程服务器接收数据。 @@ -985,7 +930,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser WalSenderWaitForWAL - 在 WAL 发送进程中等待 WAL 被刷新。 + 在 WAL 发送进程中等待 WAL 刷盘。 @@ -1039,7 +984,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser BaseBackupSync - 等待由基础备份写入的数据达到持久存储。 + 等待基础备份写入的数据同步到持久存储。 @@ -1069,12 +1014,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser ControlFileSync - 等待pg_control文件到达持久存储。 + 等待 pg_control 文件同步到持久存储。 ControlFileSyncUpdate - 等待更新pg_control文件以达到持久存储。 + 等待对 pg_control 文件的更新同步到持久存储。 @@ -1084,7 +1029,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser ControlFileWriteUpdate - 等待写入更新pg_control文件。 + 等待写入以更新 pg_control 文件。 @@ -1094,12 +1039,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser CopyFileWrite - 在文件拷贝操作期间等待写入。 + 在文件复制操作期间等待写入。 DSMFillZeroWrite - 等待用零填充动态共享内存备份(backing)文件。 + 等待用零填充动态共享内存的后备文件。 @@ -1109,12 +1054,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser DataFileFlush - 等待关系数据文件达到持久存储。 + 等待关系数据文件同步到持久存储。 DataFileImmediateSync - 等待关系数据文件到持久存储的立即同步。 + 等待关系数据文件立即同步到持久存储。 @@ -1129,7 +1074,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser DataFileSync - 等待对关系数据文件的更改达到持久存储。 + 等待对关系数据文件的更改同步到持久存储。 @@ -1149,7 +1094,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser LockFileAddToDataDirSync - 等待数据到达持久存储,同时向数据目录锁文件添加一行。 + 在向数据目录锁文件中添加一行时,等待数据同步到持久存储。 @@ -1164,7 +1109,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser LockFileCreateSync - 在创建数据目录锁文件时等待数据到达持久存储。 + 在创建数据目录锁文件时,等待数据同步到持久存储。 @@ -1179,12 +1124,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser LogicalRewriteCheckpointSync - 等待逻辑重写映射到在检查点到达持久存储。 + 在检查点期间等待逻辑重写映射同步到持久存储。 LogicalRewriteMappingSync - 在逻辑重写期间等待映射数据到达持久存储 + 在逻辑重写期间等待映射数据同步到持久存储。 @@ -1194,12 +1139,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser LogicalRewriteSync - 等待逻辑重写映射到达持久存储。 + 等待逻辑重写映射同步到持久存储。 LogicalRewriteTruncate - 等待在逻辑重写期间截断映射数据。 + 在逻辑重写期间等待截断映射数据。 @@ -1214,7 +1159,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser RelationMapSync - 等待关系映射文件到达持久存储。 + 等待关系映射文件同步到持久存储。 @@ -1224,17 +1169,17 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser ReorderBufferRead - 在重新排序缓冲区管理期间等待读取。 + 在重排序缓冲区管理期间等待读取。 ReorderBufferWrite - 在重新排序缓冲区管理期间等待写操作。 + 在重排序缓冲区管理期间等待写入。 ReorderLogicalMappingRead - 在重新排序缓冲区管理期间等待读取逻辑映射。 + 在重排序缓冲区管理期间等待读取逻辑映射。 @@ -1244,12 +1189,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser ReplicationSlotRestoreSync - 等待复制槽控制文件到达持久存储,同时将其恢复到内存中。 + 在将复制槽控制文件恢复到内存期间,等待该文件同步到持久存储。 ReplicationSlotSync - 等待复制槽控制文件到达持久存储。 + 等待复制槽控制文件同步到持久存储。 @@ -1259,7 +1204,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser SLRUFlushSync - 在检查点或数据库关闭期间等待SLRU数据到达持久存储。 + 在检查点或数据库关闭期间,等待 SLRU 数据同步到持久存储。 @@ -1269,7 +1214,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser SLRUSync - 在写页面后等待SLRU数据到达持久存储。 + 在页面写入后等待 SLRU 数据同步到持久存储。 @@ -1279,22 +1224,22 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser SnapbuildRead - 等待读取序列化的历史目录快照。 + 等待读取序列化的历史系统目录快照。 SnapbuildSync - 等待序列化历史目录快照到达持久存储。 + 等待序列化的历史系统目录快照同步到持久存储。 SnapbuildWrite - 等待串行历史目录快照的写入。 + 等待写入序列化的历史系统目录快照。 TimelineHistoryFileSync - 等待通过流复制接收的时间线历史文件到达持久存储。 + 等待通过流复制接收的时间线历史文件同步到持久存储。 @@ -1309,7 +1254,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser TimelineHistorySync - 等待新创建的时间线历史文件到达持久存储。 + 等待新创建的时间线历史文件同步到持久存储。 @@ -1324,7 +1269,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser TwophaseFileSync - 等待两阶段状态文件到达持久存储。 + 等待两阶段状态文件同步到持久存储。 @@ -1334,7 +1279,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser VersionFileSync - 等待版本文件达到持久存储,同时创建数据库。 + 在创建数据库时,等待版本文件同步到持久存储。 @@ -1344,7 +1289,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser WALBootstrapSync - 在引导过程中等待WAL达到持久存储。 + 在引导过程中等待 WAL 同步到持久存储。 @@ -1359,7 +1304,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser WALCopySync - 等待通过复制一个已有WAL段到持久存储来创建一个新的WAL段。 + 等待通过复制现有 WAL 段创建的新 WAL 段同步到持久存储。 @@ -1369,7 +1314,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser WALInitSync - 等待一个新初始化的WAL文件到持久存储。 + 等待新初始化的 WAL 文件同步到持久存储。 @@ -1384,22 +1329,22 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser WALSenderTimelineHistoryRead - 在walsender时间线命令期间等待从时间线历史文件读取。 + 在 WAL 发送进程执行时间线命令期间,等待从时间线历史文件读取。 WALSync - 等待WAL文件到达持久存储。 + 等待 WAL 文件同步到持久存储。 WALSyncMethodAssign - 等待数据到达持久存储,同时分配一个新的WAL同步方法。 + 在设置新的 WAL 同步方法时,等待数据同步到持久存储。 WALWrite - 等待写入WAL文件。 + 等待写入 WAL 文件。 @@ -1456,12 +1401,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser BtreePage - 正等待继续并行B-树扫描所需的页号变得可用。 + 等待继续并行 B-树扫描所需的页号变得可用。 BufferIO - 等待缓冲I/O结束。 + 等待缓冲区 I/O 完成。 @@ -1476,82 +1421,82 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser ExecuteGather - 在执行Gather 计划节点时,等待子进程的活动。 + 在执行 Gather 计划节点时,等待子进程的活动。 HashBatchAllocate - 等待一个选定的并行哈希参与者分配哈希表。 + 等待选出的 Parallel Hash 参与者分配哈希表。 HashBatchElect - 等待选择一个并行哈希参与者来分配哈希表。 + 等待选出负责分配哈希表的 Parallel Hash 参与者。 HashBatchLoad - 等待其他并行哈希参与者完成哈希表的加载。 + 等待其他 Parallel Hash 参与者完成哈希表的加载。 HashBuildAllocate - 等待一个选定的并行哈希参与者分配初始哈希表。 + 等待选出的 Parallel Hash 参与者分配初始哈希表。 HashBuildElect - 等待选择一个并行哈希参与者来分配初始哈希表。 + 等待选出负责分配初始哈希表的 Parallel Hash 参与者。 HashBuildHashInner - 等待其他并行哈希参与者完成内部关系的散列。 + 等待其他 Parallel Hash 参与者完成对内层关系的哈希处理。 HashBuildHashOuter - 等待其他Parallel 哈希参与者完成对外部关系的分区。 + 等待其他 Parallel Hash 参与者完成对外层关系的分区。 HashGrowBatchesAllocate - 等待选定的并行哈希参与者分配更多批处理。 + 等待选出的 Parallel Hash 参与者分配更多批次。 HashGrowBatchesDecide - 等待选择一个并行哈希参与者来决定未来的批处理增长。 + 等待选出负责决定后续批次增长的 Parallel Hash 参与者。 HashGrowBatchesElect - 等待选择一个Parallel 哈希参与者来分配更多批处理。 + 等待选出负责分配更多批次的 Parallel Hash 参与者。 HashGrowBatchesFinish - 等待当选的平行散列参与者决定未来的批量增长。 + 等待选出的 Parallel Hash 参与者决定后续的批次增长。 HashGrowBatchesRepartition - 等待一个选定的并行哈希参与者决定未来的批处理增长。 + 等待其他 Parallel Hash 参与者完成重新分区。 HashGrowBucketsAllocate - 等待选定的并行哈希参与者完成更多bucket的分配。 + 等待选出的 Parallel Hash 参与者完成更多桶的分配。 HashGrowBucketsElect - 等待选择一个并行哈希参与者来分配更多的buckets。 + 等待选出负责分配更多桶的 Parallel Hash 参与者。 HashGrowBucketsReinsert - 等待其他Parallel 哈希参与者完成将元组插入到新buckets中。 + 等待其他 Parallel Hash 参与者完成向新桶插入元组。 @@ -1586,22 +1531,22 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser ParallelBitmapScan - 等待并行位图扫描被初始化。 + 等待并行位图扫描完成初始化。 ParallelCreateIndexScan - 等待并行CREATE INDEX 工作进程完成堆扫描。 + 等待并行 CREATE INDEX 工作进程完成堆扫描。 ParallelFinish - 等待并行工作人员完成计算。 + 等待并行工作进程完成计算。 ProcArrayGroupUpdate - 等待组领导在并行操作结束时清除事务ID。 + 等待组领导者在事务结束时清除事务 ID。 @@ -1616,12 +1561,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser RecoveryConflictSnapshot - 等待vacuum清理的恢复冲突解决。 + 等待解决清理操作引发的恢复冲突。 RecoveryConflictTablespace - 等待恢复冲突解决删除表空间。 + 等待解决删除表空间引发的恢复冲突。 @@ -1656,7 +1601,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser SyncRep - 在同步复制期间等待远程服务器的确认。 + 在同步复制期间等待来自远程服务器的确认。 @@ -1671,7 +1616,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser XactGroupUpdate - 等待分组组长在并行操作结束时更新事务状态。 + 等待组领导者在事务结束时更新事务状态。 @@ -1693,7 +1638,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser advisory - 等待获得一个建议用户锁。 + 等待获取用户咨询锁。 @@ -1703,8 +1648,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser frozenid - 等待升级 pg_database.datfrozenxid - 和 pg_database.datminmxid. + 等待更新 pg_database.datfrozenxidpg_database.datminmxid @@ -1719,12 +1663,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser relation - 等待获得一个关系的锁。 + 等待获取关系上的锁。 spectoken - 等待获取推测的插入锁。 + 等待获取推测插入锁。 @@ -1766,7 +1710,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser AddinShmemInit - 等待管理共享内存中的扩展空间分配。 + 等待管理扩展在共享内存中的空间分配。 @@ -1781,7 +1725,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser AutovacuumSchedule - 等待确保选择为自动清理的表仍然需要清理。 + 等待确认选中进行自动清理的表是否仍需清理。 @@ -1811,7 +1755,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser CommitTs - 等待读取或更新事务提交时间戳的最后一个值集。 + 等待读取或更新最近设置的事务提交时间戳值。 @@ -1841,42 +1785,42 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser LockManager - 等待读取或更新关于heavyweight锁。 + 等待读取或更新有关重量级锁的信息。 LogicalRepWorker - 等待读取或更新逻辑复制工作器的状态。 + 等待读取或更新逻辑复制工作进程的状态。 MultiXactGen - 等待读取或更新共享的multixact状态。 + 等待读取或更新共享的多事务状态。 MultiXactMemberBuffer - 在multixact成员SLRU缓冲区上等待I/O。 + 等待多事务成员 SLRU 缓冲区上的 I/O。 MultiXactMemberSLRU - 等待访问multixact成员SLRU缓存。 + 等待访问多事务成员 SLRU 缓存。 MultiXactOffsetBuffer - 在multixact 偏移 SLRU缓冲区上等待I/O。 + 等待多事务偏移量 SLRU 缓冲区上的 I/O。 MultiXactOffsetSLRU - 等待访问multixact 偏移 SLRU缓存。 + 等待访问多事务偏移量 SLRU 缓存。 MultiXactTruncation - 等待读取或截断multixact信息。 + 等待读取或截断多事务信息。 @@ -1891,7 +1835,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser NotifyQueueTail - 等待NOTIFY消息存储上的更新限制。 + 等待更新 NOTIFY 消息存储的限制。 @@ -1911,12 +1855,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser ParallelAppend - 在并行附加计划执行期间等待选择下一个子计划。 + 在 Parallel Append 计划执行期间等待选择下一个子计划。 ParallelHashJoin - 在并行哈希连接计划执行期间等待同步工作器。 + 在 Parallel Hash Join 计划执行期间等待同步工作进程。 @@ -1931,12 +1875,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser PerSessionRecordType - 等待访问有关复合类型的并行查询信息。 + 等待访问并行查询中有关复合类型的信息。 PerSessionRecordTypmod - 等待访问有关标识匿名记录类型的类型修饰符的并行查询信息。 + 等待访问并行查询中用于标识匿名记录类型的类型修饰符信息。 @@ -1951,7 +1895,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser ProcArray - 等待访问每个进程共享的数据结构(通常情况,是获取快照或报告会话的事务ID)。 + 等待访问各进程的共享数据结构(通常是为了获取快照或报告会话的事务 ID)。 @@ -2006,17 +1950,17 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser PgStatsDSA - 等待统计动态共享内存分配器访问 + 等待访问统计信息的动态共享内存分配器。 PgStatsHash - 等待统计共享内存哈希表访问 + 等待访问统计信息的共享内存哈希表。 PgStatsData - 等待共享内存统计数据访问 + 等待访问共享内存中的统计数据。 @@ -2046,12 +1990,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser SInvalRead - 等待从共享目录失效队列中检索消息。 + 等待从共享系统目录失效队列中取出消息。 SInvalWrite - 等待向共享编目失效队列添加消息。 + 等待向共享系统目录失效队列添加消息。 @@ -2081,7 +2025,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser TwoPhaseState - 等待读取或更新已准备事务的状态。 + 等待读取或更新预备事务的状态。 @@ -2101,7 +2045,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser WrapLimitsVacuum - 等待更新事务 ID和multixact消费的限制。 + 等待更新事务 ID 和多事务消耗量的限制。 @@ -2130,8 +2074,8 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - 扩展可以将ExtensionInjectionPointLWLock 类型添加到所示的列表中。 - 在某些情况下,扩展分配的 LWLock 名称无法在所有服务器进程中使用;因此,LWLock 等待事件可能只会被报告为extension,而不是扩展分配的名称。 + 扩展可以将LWLock 类型添加到所示的列表中。 + 在某些情况下,扩展分配的名称无法在所有服务器进程中使用;因此,LWLock 等待事件可能只会被报告为extension,而不是扩展分配的名称。 @@ -2151,12 +2095,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser BaseBackupThrottle - 当有限流活动时在基础备份期间等待。 + 在基础备份期间因限流而等待。 CheckpointWriteDelay - 在执行检查点时写入之间的等待时间。 + 在执行检查点时,在各次写入之间等待。 @@ -2176,12 +2120,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser RegisterSyncRequest - 在发送同步请求到检查点程序时等待,因为请求队列已满。 + 向检查点进程发送同步请求时,因请求队列已满而等待。 VacuumDelay - 在一个基于代价的清理延迟点。 + 在基于代价的清理延迟点等待。 @@ -2193,7 +2137,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser
- 这里是一个查看等待事件的示例: + 以下示例展示如何查看等待事件: SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event is NOT NULL; @@ -2204,17 +2148,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i (2 rows) - -SELECT a.pid, a.wait_event, w.description - FROM pg_stat_activity a JOIN - pg_wait_events w ON (a.wait_event_type = w.type AND - a.wait_event = w.name) - WHERE a.wait_event is NOT NULL and a.state = 'active'; --[ RECORD 1 ]------------------------------------------------------&zwsp;------------ -pid | 686674 -wait_event | WALInitSync -description | Waiting for a newly initialized WAL file to reach durable storage - +
@@ -2291,7 +2225,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage
连接到这个 WAL 发送进程的客户端的 IP 地址。 - 如果这个域为空,它表示该客户端通过服务器机器上的一个Unix 套接字连接。 + 如果这个字段为空值,它表示该客户端通过服务器机器上的一个Unix 套接字连接。 @@ -2342,27 +2276,27 @@ description | Waiting for a newly initialized WAL file to reach durable storage - startup: 此 WAL 发送进程正在启动。 + startup: 此 WAL 发送进程正在启动。 - catchup: 与此 WAL 发送进程连接的备库正在赶上主库。 + catchup: 与此 WAL 发送进程连接的备库正在赶上主库。 - streaming: 在其连接的备库赶上主库之后,此 WAL 发送进程正在流式传输更改。 + streaming: 在其连接的备库赶上主库之后,此 WAL 发送进程正在流式传输更改。 - backup: 此 WAL 发送进程正在发送一个备份。 + backup: 此 WAL 发送进程正在发送一个备份。 - stopping: 此 WAL 发送进程正在停止。 + stopping: 此 WAL 发送进程正在停止。 @@ -2409,30 +2343,21 @@ description | Waiting for a newly initialized WAL file to reach durable storage write_lag interval - - 从本地刷写最近的 WAL,到收到该备库已写入该 WAL(但尚未刷盘或应用)的通知之间经过的时间。 - 如果该服务器被配置为同步备库,可用此值衡量在提交时 synchronous_commit 级别 remote_write 所导致的延迟。 - + 从在本地将最近的 WAL 刷盘,到收到该备库已写入该 WAL(但尚未刷盘或应用)的通知之间经过的时间。如果该服务器被配置为同步备库,可用此值衡量在提交时synchronous_commit级别remote_write所导致的延迟。 flush_lag interval - - 从本地刷写最近的 WAL,到收到该备库已写入并刷写该 WAL(但尚未应用)的通知之间经过的时间。 - 如果该服务器被配置为同步备库,可用此值衡量在提交时 synchronous_commit 级别 on 所导致的延迟。 - + 从在本地将最近的 WAL 刷盘,到收到该备库已写入该 WAL 并将其刷盘(但尚未应用)的通知之间经过的时间。如果该服务器被配置为同步备库,可用此值衡量在提交时synchronous_commit级别on所导致的延迟。 replay_lag interval - - 从本地刷写最近的 WAL,到收到该备库已写入、刷写并应用该 WAL 的通知之间经过的时间。 - 如果该服务器被配置为同步备库,可用此值衡量在提交时 synchronous_commit 级别 remote_apply 所导致的延迟。 - + 从在本地将最近的 WAL 刷盘,到收到该备库已写入该 WAL、将其刷盘并应用的通知之间经过的时间。如果该服务器被配置为同步备库,可用此值衡量在提交时synchronous_commit级别remote_apply所导致的延迟。 @@ -2454,22 +2379,22 @@ description | Waiting for a newly initialized WAL file to reach durable storage - async: 该备库是异步的。 + async: 该备库是异步的。 - potential: 该备库当前是异步的,但在当前同步备库失效时可能变为同步的。 + potential: 该备库当前是异步的,但在当前某个同步备库失效时可能变为同步的。 - sync: 该备库是同步的。 + sync: 该备库是同步的。 - quorum: 该备库被作为法定人数同步复制候选备库。 + quorum: 该备库被作为法定人数同步复制候选备库。 @@ -2478,7 +2403,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - reply_time 带时区的时间戳 + reply_time timestamp with time zone 从备库收到的最后一条回复消息的发送时间 @@ -2489,17 +2414,17 @@ description | Waiting for a newly initialized WAL file to reach durable storage - pg_stat_replication视图中报告的滞后时间,是最近的 WAL 被写入、刷写和重放,以及发送端获知这些操作完成所花费时间的度量。如果远程服务器被配置为同步备库,这些时间表示各个同步提交级别带来或可能带来的提交延迟。对于异步备库,replay_lag列是最近事务对查询变得可见所需延迟时间的近似值。如果备库已经完全追上发送服务器且没有新的 WAL 活动,系统会在短时间内继续显示最近测得的滞后时间,随后显示为 NULL。 + pg_stat_replication视图中报告的滞后时间,是最近的 WAL 被写入、刷盘和重放,以及发送端获知这些操作完成所花费时间的度量。如果远程服务器被配置为同步备库,这些时间表示各个同步提交级别带来或可能带来的提交延迟。对于异步备库,replay_lag列是最近事务对查询变得可见所需延迟时间的近似值。如果备库已经完全追上发送服务器且没有新的 WAL 活动,系统会在短时间内继续显示最近测得的滞后时间,随后显示为 空值。 - 对于物理复制,滞后时间会自动测量。逻辑解码插件可以选择发出跟踪消息;如果没有这样做,跟踪机制会将滞后显示为 NULL。 + 对于物理复制,滞后时间会自动测量。逻辑解码插件可以选择发出跟踪消息;如果没有这样做,跟踪机制会将滞后显示为 空值。 - 报告出的滞后时间并不是根据当前重放速率预测该备库还需多久才能追上发送服务器。在持续生成新 WAL 时,那样的系统可能会显示相近的时间;但当发送端空闲时,就会显示不同的值。特别是当备库已经完全追上时,pg_stat_replication显示的是写入、刷写和重放最近报告的 WAL 位置所花费的时间,而不是某些用户可能预期的零。这样做符合为最近写事务测量同步提交和事务可见性延迟的目的。为减少用户因预期另一种滞后模型而产生的混淆,在一个已完全重放且处于空闲状态的系统上,lag 列会在较短时间后恢复为 NULL。监控系统应自行决定将这种情况表示为缺失数据、零,还是继续显示最近一次已知值。 + 报告出的滞后时间并不是根据当前重放速率预测该备库还需多久才能追上发送服务器。在持续生成新 WAL 时,那样的系统可能会显示相近的时间;但当发送端空闲时,就会显示不同的值。特别是当备库已经完全追上时,pg_stat_replication显示的是写入、刷盘和重放最近报告的 WAL 位置所花费的时间,而不是某些用户可能预期的零。这样做符合为最近写事务测量同步提交和事务可见性延迟的目的。为减少用户因预期另一种滞后模型而产生的混淆,在一个已完全重放且处于空闲状态的系统上,滞后列会在较短时间后恢复为 空值。监控系统应自行决定将这种情况表示为缺失数据、零,还是继续显示最近一次已知值。 @@ -2538,19 +2463,14 @@ description | Waiting for a newly initialized WAL file to reach durable storage slot_name text - - 唯一的,复制槽的集簇范围标识符 - + 复制槽在整个集簇范围内的唯一标识符 spill_txns bigint - - 当逻辑解码在解码来自WAL的更改时所使用的内存超过logical_decoding_work_mem,溢出到磁盘的事务数。 - 顶级事务和子事务的计数器都是递增的。 - + 当逻辑解码从 WAL 解码更改时所使用的内存超过logical_decoding_work_mem后,溢出到磁盘的事务数。顶层事务和子事务都会使此计数器递增。 @@ -2558,7 +2478,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage spill_count bigint
- 在为该槽位解码来自WAL的更改时,事务溢出到磁盘的次数。 + 在为该槽解码来自WAL的更改时,事务溢出到磁盘的次数。 此计数器在每次事务被溢出时递增,并且同一事务可能被溢出多次。 @@ -2567,20 +2487,14 @@ description | Waiting for a newly initialized WAL file to reach durable storage spill_bytes bigint - - 在对来自WAL的更改执行解码时,已解码的事务数据溢出到磁盘的数量。 - 这个和其他溢出计数器可用于测量逻辑解码期间发生的I/O,并且允许调优logical_decoding_work_mem。 - + 为此槽从 WAL 解码更改时,溢出到磁盘的已解码事务数据量。此计数器及其他溢出计数器可用于衡量逻辑解码期间发生的 I/O,并用于调优logical_decoding_work_mem stream_txns bigint - - 在逻辑解码在解码来自该槽位的WAL更改的时候,所使用的内存超过logical_decoding_work_mem之后,流式传输到解码输出插件的正在进行的事务数。 - 流式传输仅对顶级事务有效(子事务不能独立进行流式传输),因此子事务的计数器不会增加。 - + 当逻辑解码为此槽从 WAL 解码更改时所使用的内存超过logical_decoding_work_mem后,流式传输到解码输出插件的进行中事务数。流式传输仅适用于顶层事务(子事务不能单独进行流式传输),因此子事务不会使此计数器递增。 @@ -2588,7 +2502,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage stream_countbigint - 在为该槽位解码来自WAL的更改时,将正在进行的事务流式传输到解码输出插件的次数。 + 在为该槽解码来自WAL的更改时,将进行中事务流式传输到解码输出插件的次数。 此计数器在每次事务流式传输时递增,并且同一事务可能被流式传输多次。 @@ -2598,8 +2512,8 @@ description | Waiting for a newly initialized WAL file to reach durable storage stream_bytesbigint - 在为该槽位解码来自WAL的更改时,为将正在进行的事务流式传输到解码输出插件而解码的事务数据的数量。 - 这个和针对此槽位的其他流式传输计数器可用于调优logical_decoding_work_mem。 + 在为该槽解码来自WAL的更改时,为将进行中事务流式传输到解码输出插件而解码的事务数据量。 + 这个和针对此槽的其他流式传输计数器可用于调优logical_decoding_work_mem @@ -2610,7 +2524,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage 针对此槽的,发送到解码输出插件的已解码事务数。 - 这只计算顶级事务,对子事务不会增加。 + 这只计算顶层事务,对子事务不会增加。 注意,这包括流式传输和/或溢出的事务。 @@ -2620,7 +2534,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage total_bytesbigint - 在对此槽位的WAL进行解码时,为将事务发送到解码输出插件而解码的事务数据量。 + 在为此槽从 WAL 解码更改时,为将事务发送到解码输出插件而解码的事务数据量。 注意这包括流式传输和/或溢出的数据。 @@ -2630,9 +2544,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage stats_reset timestamp with time zone - - 这些统计最后重置的时间 - + 这些统计信息上次被重置的时间 @@ -2647,9 +2559,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage pg_stat_wal_receiver - - pg_stat_wal_receiver事务只包含一行,它显示了从 WAL 接收进程所连接的服务器得到的有关该接收进程的统计信息。 - + pg_stat_wal_receiver视图只包含一行,显示 WAL 接收进程从其所连接服务器接收数据的统计信息。 @@ -2674,7 +2584,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage pidinteger - WAL 接收进程的进程ID + WAL 接收进程的进程 ID @@ -2683,7 +2593,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage statustext - WAL接收进程的活动状态 + WAL 接收进程的活动状态 @@ -2692,7 +2602,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage receive_start_lsnpg_lsn - WAL 接收进程启动时使用的第一个写前日志位置 + WAL 接收进程启动时使用的第一个预写式日志位置 @@ -2701,7 +2611,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage receive_start_tliinteger - WAL 接收进程启动时使用的第一个时间线数字 + WAL 接收进程启动时使用的第一个时间线编号 @@ -2710,7 +2620,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage written_lsnpg_lsn - 已经接收并写入磁盘的最后一个预写式日志位置,但没有刷入。这不能用于数据完整性检查。 + 已经接收并写入磁盘的最后一个预写式日志位置,但尚未刷盘。此字段不应用于数据完整性检查。 @@ -2719,7 +2629,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage flushed_lsnpg_lsn - 已经接收并刷入到磁盘的最后一个预写式日志位置,该字段的初始值是启动WAL 接收进程时使用的第一个日志位置 + 已经接收并刷入到磁盘的最后一个预写式日志位置,该字段的初始值是启动 WAL 接收进程时使用的第一个日志位置 @@ -2728,7 +2638,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage received_tliinteger - 接收并刷入到磁盘的最后一个预写式日志位置的时间线数字,该字段的初始值为启动WAL 接收进程时使用的第一个日志位置的时间线数字 + 接收并刷入到磁盘的最后一个预写式日志位置的时间线编号,该字段的初始值为启动 WAL 接收进程时使用的第一个日志位置的时间线编号 @@ -2773,7 +2683,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage slot_nametext - 这个WAL 接收进程使用的复制槽的名称 + 这个 WAL 接收进程使用的复制槽的名称 @@ -2782,8 +2692,8 @@ description | Waiting for a newly initialized WAL file to reach durable storage sender_hosttext - 这个WAL 接收进程连接到的PostgreSQL实例的主机。 - 这可以是主机名、IP地址,或者目录路径,如果连接是通过Unix套接字进行的。(路径的情况可以区分,因为它总是以/开头的绝对路径。) + 这个 WAL 接收进程连接到的PostgreSQL实例的主机。 + 这可以是主机名、IP地址,或者目录路径,如果连接是通过Unix套接字进行的。(路径的情况可以区分,因为它总是以/开头的绝对路径。) @@ -2792,7 +2702,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage sender_portinteger - 这个WAL 接收进程连接的PostgreSQL实例的端口号。 + 这个 WAL 接收进程连接的PostgreSQL实例的端口号。 @@ -2801,7 +2711,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage conninfotext - 这个WAL 接收进程使用的连接字符串,对安全敏感的字段进行了模糊处理。 + 这个 WAL 接收进程使用的连接字符串,对安全敏感的字段进行了模糊处理。 @@ -2847,9 +2757,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage stats_reset timestamp with time zone - - 这些统计数据上次重置的时间 - + 这些统计信息上次被重置的时间 @@ -2924,9 +2832,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage wal_distance int - - 预取器向前查看多少字节 - + 预取器向前查看的字节数 @@ -2935,9 +2841,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage block_distance int - - 预取器正在查看多少个块之前 - + 预取器向前查看的块数 @@ -2946,9 +2850,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage io_depth int - - 已启动但尚未完成的预取数量 - + 已启动但尚未确认完成的预取数量 @@ -2991,7 +2893,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + subname name @@ -3000,16 +2902,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - - - worker_type text - - - 订阅工作进程的类型。可能的类型有 applyparallel applytable synchronization。 - - - - + pid integer @@ -3018,25 +2911,25 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + relid oid - 该工作进程正在同步的关系的 OID;主应用工作进程则为 NULL + 该工作进程正在同步的关系的 OID;主应用工作进程则为 空值 - + received_lsn pg_lsn - 接收到的最后一个预写式日志位置,该字段的初始值为0 + 接收到的最后一个预写式日志位置,该字段的初始值为 0 - + last_msg_send_time timestamp with time zone @@ -3045,7 +2938,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + last_msg_receipt_time timestamp with time zone @@ -3054,7 +2947,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + latest_end_lsn pg_lsn @@ -3063,14 +2956,15 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + latest_end_time timestamp with time zone - 向 WAL 发送进程报告最后一个预写式日志位置的时间 + 向源 WAL 发送进程报告最后一个预写式日志位置的时间 +
@@ -3142,76 +3036,25 @@ description | Waiting for a newly initialized WAL file to reach durable storage - - - confl_insert_exists bigint - - - 在应用更改期间,行插入违反 NOT DEFERRABLE 唯一约束的次数。有关该冲突的详细信息,请参阅。 - - - - - confl_update_origin_differs bigint - - - 在应用更改期间,更新被应用到先前已被另一个源修改过的行上的次数。有关该冲突的详细信息,请参阅。 - - - - - confl_update_exists bigint - - - 在应用更改期间,更新后的行值违反 NOT DEFERRABLE 唯一约束的次数。有关该冲突的详细信息,请参阅。 - - - - - confl_update_missing bigint - - - 在应用更改期间,待更新的元组未找到的次数。有关该冲突的详细信息,请参阅。 - - - - - confl_delete_origin_differs bigint - - - 在应用更改期间,删除操作被应用到先前已被另一个源修改过的行上的次数。有关该冲突的详细信息,请参阅。 - - - - - confl_delete_missing bigint - - - 在应用更改期间,待删除的元组未找到的次数。有关该冲突的详细信息,请参阅。 - - - - - confl_multiple_unique_conflicts bigint - - - 在应用更改期间,行插入或更新后的行值违反多个 NOT DEFERRABLE 唯一约束的次数。有关该冲突的详细信息,请参阅。 - - + + + + + + + stats_reset timestamp with time zone - - 这些统计数据最后一次重置的时间 - + 这些统计信息上次被重置的时间 @@ -3272,7 +3115,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage version text - 使用SSL的版本,如果此连接上没有使用SSL则为NULL + 使用SSL的版本,如果此连接上没有使用SSL则为空值 @@ -3281,7 +3124,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage cipher text - 正在使用的SSL密码的名称,如果此连接上没有使用SSL则为NULL + 正在使用的SSL 密码套件的名称,如果此连接上没有使用SSL则为空值 @@ -3290,7 +3133,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage bits integer - 使用的加密算法中的位数,如果此连接上没有使用SSL则为NULL + 使用的加密算法中的位数,如果此连接上没有使用SSL则为空值 @@ -3299,8 +3142,8 @@ description | Waiting for a newly initialized WAL file to reach durable storage client_dn text - 区别名称(DN,Distinguished Name)字段与使用的客户端证书,如果没有提供客户端证书或在此连接上没有使用SSL,则为NULL。 - 如果DN字段长于NAMEDATALEN(标准构建中为64个字符),则该字段将被截断。 + 所用客户端证书中的区别名称(DN,Distinguished Name)字段,如果没有提供客户端证书或在此连接上没有使用SSL,则为空值。 + 如果DN字段长于NAMEDATALEN(标准构建中为64个字符),则该字段将被截断。 @@ -3309,8 +3152,8 @@ description | Waiting for a newly initialized WAL file to reach durable storage client_serial numeric - 客户端证书的序列号,如果没有提供客户端证书或在此连接上没有使用SSL,则为NULL。 - 证书序列号和证书颁发者的组合唯一标识一个证书(除非颁发者错误地重用序列号)。 + 客户端证书的序列号,如果没有提供客户端证书或在此连接上没有使用SSL,则为空值。 + 证书序列号和证书颁发者的组合唯一标识一个证书(除非颁发者错误地重用序列号)。 @@ -3319,7 +3162,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage issuer_dn text - 客户端证书颁发者的区别名称(DN,Distinguished Name),如果没有提供客户端证书或在此连接上没有使用SSL,则为NULL。该字段像client_dn一样被截断。 + 客户端证书颁发者的区别名称(DN,Distinguished Name),如果没有提供客户端证书或在此连接上没有使用SSL,则为空值。该字段像client_dn一样被截断。 @@ -3337,7 +3180,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage pg_stat_gssapi视图将包含每一个后端一个行,显示该连接上的GSSAPI使用情况。 - 它可以加入到pg_stat_activitypg_stat_replication上的pid列,获取更多关于连接的详细信息。 + 可以通过pid列将它与pg_stat_activitypg_stat_replication连接,获取更多关于连接的详细信息。 @@ -3381,8 +3224,8 @@ description | Waiting for a newly initialized WAL file to reach durable storage principaltext - 用于验证此连接的主体,如果未使用GSSAPI对此连接进行认证,则为NULL。 - 如果主体长度超过NAMEDATALEN(标准构建中为64个字符),则该字段被截断。 + 用于认证此连接的主体,如果未使用GSSAPI对此连接进行认证,则为空值。 + 如果主体长度超过NAMEDATALEN(标准构建中为64个字符),则该字段被截断。 @@ -3487,9 +3330,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage stats_reset timestamp with time zone - - 这些统计数据最后一次重置的时间 - + 这些统计信息上次被重置的时间 @@ -3511,7 +3352,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - pg_stat_bgwriter 视图始终只有一行,包含有关集簇后台写入器的数据。 + pg_stat_bgwriter 视图始终只有一行,包含整个集簇的全局数据。
@@ -3531,158 +3372,77 @@ description | Waiting for a newly initialized WAL file to reach durable storage - buffers_clean bigint - - - 后台写入器写入的缓冲区数量 - - - - - - maxwritten_clean bigint - - - 后台写入器因写入了过多缓冲区而停止清理扫描的次数 - - - - - - buffers_alloc bigint - - - 分配的缓冲区数量 - - - - - - stats_reset timestamp with time zone - - - 这些统计信息上次被重置的时间 - - - - -
- - - - - <structname>pg_stat_checkpointer</structname> - - - pg_stat_checkpointer - - - - pg_stat_checkpointer 视图始终只有一行,包含有关集簇检查点进程的数据。 - - - - <structname>pg_stat_checkpointer</structname> 视图 - - - - - 列类型 - - - 描述 - - - - - - - - num_timed bigint + checkpoints_timed bigint - - 因超时而安排的检查点数量 - + 已执行的计划检查点数 - num_requested bigint + checkpoints_req bigint - - 被请求执行的检查点数量 - + 已执行的请求检查点数 - num_done bigint + checkpoint_write_time double precision - - 已执行的检查点数量 - + 检查点处理中将文件写入磁盘部分所花费的总时间,单位为毫秒 - restartpoints_timed bigint + checkpoint_sync_time double precision - - 因超时或上次尝试执行失败后而安排的重启点数量 - + 检查点处理中将文件同步到磁盘部分所花费的总时间,单位为毫秒 - restartpoints_req bigint + buffers_checkpoint bigint - - 被请求执行的重启点数量 - + 检查点期间写入的缓冲区数 - restartpoints_done bigint + buffers_clean bigint - 已执行的重启点数量 + 后台写入器写入的缓冲区数量 - write_time double precision + maxwritten_clean bigint - 处理检查点和重启点时,将文件写入磁盘阶段所花费的总时间,以毫秒计 + 后台写入器因写入了过多缓冲区而停止清理扫描的次数 - sync_time double precision + buffers_backend bigint - - 处理检查点和重启点时,将文件同步到磁盘阶段所花费的总时间,以毫秒计 - + 后端直接写入的缓冲区数 - buffers_written bigint + buffers_backend_fsync bigint - - 在检查点和重启点期间写入的共享缓冲区数量 - + 后端必须自行执行fsync调用的次数(通常即使后端自行写入,也由后台写入器处理这些调用) - slru_written bigint + buffers_alloc bigint - 在检查点和重启点期间写入的 SLRU 缓冲区数量 + 分配的缓冲区数量 @@ -3690,20 +3450,16 @@ description | Waiting for a newly initialized WAL file to reach durable storage stats_reset timestamp with time zone - - 这些统计信息上次被重置的时间 - + 这些统计信息上次被重置的时间
- - 如果服务器自上次检查点以来一直处于空闲状态,则检查点可能会被跳过。num_timednum_requested 统计的是已完成和已跳过的检查点,而 num_done 只跟踪实际完成的检查点。类似地,如果最后一个重放的检查点记录已经是最后一个重启点,则重启点也可能被跳过。restartpoints_timedrestartpoints_req 统计的是已完成和已跳过的重启点,而 restartpoints_done 只跟踪实际完成的重启点。 - -
+ + <structname>pg_stat_wal</structname> @@ -3756,7 +3512,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage wal_bytes numeric - 生成的WAL总数,以字节计 + 生成的 WAL 总量,以字节计 @@ -3765,7 +3521,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage wal_buffers_full bigint - 因为缓冲区已满,WAL数据被写入磁盘的次数 + 因为 WAL 缓冲区已满,WAL 数据被写入磁盘的次数 @@ -3784,7 +3540,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage wal_sync bigint - 通过issue_xlog_fsync 请求将WAL文件同步到磁盘的次数(如果onfdatasync, fsyncfsync_writethrough,否则为零)。 + 通过issue_xlog_fsync 请求将WAL文件同步到磁盘的次数(如果onfdatasyncfsyncfsync_writethrough,否则为零)。 有关内部WAL函数issue_xlog_fsync的更多信息,参见 @@ -3794,7 +3550,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage wal_write_time double precision - 通过XLogWrite请求将WAL缓冲区写入磁盘所消耗的总时间,以毫秒计(如果是启用的,否则为零)。 + 通过XLogWrite请求将WAL缓冲区写入磁盘所消耗的总时间,以毫秒计(如果是启用的,否则为零)。 这包括当wal_sync_methodopen_datasyncopen_sync时的同步时间。 @@ -3804,7 +3560,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage wal_sync_time double precision - 通过issue_xlog_fsync请求将WAL文件同步到磁盘所消耗的总时间,以毫秒计(如果 track_wal_io_timing 被启用,fsync is on, 和 wal_sync_methodfdatasync, fsyncfsync_writethrough, 否则为零). + 通过 issue_xlog_fsync 请求将 WAL 文件同步到磁盘所花费的总时间,以毫秒计(如果启用了 track_wal_io_timingfsyncon,且 wal_sync_methodfdatasyncfsyncfsync_writethrough,否则为零)。 @@ -3812,9 +3568,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage stats_reset timestamp with time zone - - 这些统计数据最后一次重置的时间 - + 这些统计信息上次被重置的时间 @@ -3860,7 +3614,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + datname name @@ -3869,17 +3623,17 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + numbackends integer 当前连接到此数据库的后端数,对于共享对象则为NULL。 - 这是该视图中唯一返回反映当前状态的值的列;所有其他列返回自上次重置以来累积的值。 + 这是该视图中唯一返回反映当前状态的值的列;所有其他列返回自上次重置以来累积的值。 - + xact_commit bigint @@ -3888,7 +3642,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + xact_rollback bigint @@ -3897,7 +3651,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + blks_read bigint @@ -3906,7 +3660,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + blks_hit bigint @@ -3915,7 +3669,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + tup_returned bigint @@ -3924,7 +3678,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + tup_fetched bigint @@ -3933,7 +3687,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + tup_inserted bigint @@ -3942,7 +3696,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + tup_updated bigint @@ -3951,7 +3705,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + tup_deleted bigint @@ -3960,7 +3714,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + conflicts bigint @@ -3969,7 +3723,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + temp_files bigint @@ -3978,7 +3732,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + temp_bytes bigint @@ -3987,7 +3741,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + deadlocks bigint @@ -3996,7 +3750,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + checksum_failures bigint @@ -4005,7 +3759,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + checksum_last_failure timestamp with time zone @@ -4014,7 +3768,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + blk_read_time double precision @@ -4023,7 +3777,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + blk_write_time double precision @@ -4032,25 +3786,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - - - parallel_workers_to_launch bigint - - - 计划由该数据库上的查询启动的并行工作进程数 - - - - - - parallel_workers_launched bigint - - - 由该数据库上的查询启动的并行工作进程数 - - - - + session_time double precision @@ -4059,7 +3795,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + active_time double precision @@ -4068,7 +3804,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + idle_in_transaction_time double precision @@ -4077,7 +3813,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + sessions bigint @@ -4086,7 +3822,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + sessions_abandoned bigint @@ -4095,7 +3831,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + sessions_fatal bigint @@ -4104,7 +3840,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + sessions_killed bigint @@ -4113,7 +3849,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + stats_reset timestamp with time zone @@ -4121,6 +3857,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage 这些统计数据最后一次重置的时间 + @@ -4207,7 +3944,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage confl_bufferpin bigint - 此数据库中由于固定缓冲区而被取消的查询数 + 此数据库中由于缓冲区被钉住而被取消的查询数 @@ -4220,14 +3957,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - - - confl_active_logicalslot bigint - - - 此数据库中因旧快照或主库上的 太低而被取消的逻辑槽使用次数 - - + @@ -4300,21 +4030,14 @@ description | Waiting for a newly initialized WAL file to reach durable storage - - - last_seq_scan timestamp with time zone - - - 此表上最后一次顺序扫描的时间,基于最近的事务停止时间 - - + seq_tup_read bigint - 连续扫描获取的实时行数 + 顺序扫描获取的存活行数 @@ -4327,21 +4050,14 @@ description | Waiting for a newly initialized WAL file to reach durable storage - - - last_idx_scan timestamp with time zone - - - 此表上最后一次索引扫描的时间,基于最近的事务停止时间 - - + idx_tup_fetch bigint - 索引扫描获取的实时行数 + 索引扫描获取的存活行数 @@ -4377,18 +4093,11 @@ description | Waiting for a newly initialized WAL file to reach durable storage n_tup_hot_upd bigint - HOT更新的行数(即,不需要单独的索引更新) + HOT 更新的行数(即不需要单独更新索引) - - - n_tup_newpage_upd bigint - - - 更新的行数,其中后继版本转到新的堆页,留下一个原始版本,其t_ctid字段指向不同的堆页。这些始终是非 HOT 更新。 - - + @@ -4431,7 +4140,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage last_vacuum timestamp with time zone - 最后一次手动清理这个表(不包括VACUUM FULL) + 最后一次手动清理这个表的时间(不包括VACUUM FULL @@ -4449,7 +4158,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage last_analyze timestamp with time zone - 上一次手动分析这个表 + 上一次手动分析这个表的时间 @@ -4458,7 +4167,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage last_autoanalyze timestamp with time zone - 自动清理守护进程最后一次分析这个表 + 自动清理守护进程最后一次分析这个表的时间 @@ -4467,7 +4176,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage vacuum_count bigint - 这个表被手动清理的次数(VACUUM FULL不计数) + 这个表被手动清理的次数(VACUUM FULL不计数) @@ -4498,41 +4207,13 @@ description | Waiting for a newly initialized WAL file to reach durable storage - - - total_vacuum_time double precision - - - 手动 VACUUM 此表所花费的总时间,以毫秒计(不包括 VACUUM FULL)。(这包括由于基于成本的延迟而睡眠的时间。) - - - - - total_autovacuum_time double precision - - - 自动清理守护进程对该表执行 VACUUM 所花费的总时间,以毫秒计。(这包括由于基于成本的延迟而睡眠的时间。) - - - - - total_analyze_time double precision - - - 手动分析该表所花费的总时间,以毫秒计。(这包括由于基于成本的延迟而睡眠的时间。) - - - - - total_autoanalyze_time double precision - - - 自动清理守护进程分析该表所花费的总时间,以毫秒计。(这包括由于基于成本的延迟而睡眠的时间。) - - + + + + @@ -4622,14 +4303,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - - - last_idx_scan timestamp with time zone - - - 此索引上最后一次扫描的时间,基于最近的事务停止时间 - - + @@ -4645,7 +4319,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage idx_tup_fetch bigint - 使用此索引进行简单索引扫描获取的活动表行数 + 使用此索引进行简单索引扫描获取的存活表行数 @@ -4653,13 +4327,13 @@ description | Waiting for a newly initialized WAL file to reach durable storage - 索引可以被简单索引扫描、位图索引扫描以及优化器使用。在一次位图扫描中,多个索引的输出可以被通过 AND 或 OR 规则组合,因此当使用一次位图扫描时难以将取得的个体堆行与特定的索引关联起来。因此,一次位图扫描会增加它使用的索引的pg_stat_all_indexes.idx_tup_read计数,并且为每个表增加pg_stat_all_tables.idx_tup_fetch计数,但是它不影响pg_stat_all_indexes.idx_tup_fetch。如果所提供的常量值不在优化器统计信息记录的范围之内,优化器也会访问索引来检查,因为优化器统计信息可能已经“不新鲜”了。 + 索引可以被简单索引扫描、位图索引扫描以及优化器使用。在一次位图扫描中,多个索引的输出可以被通过 AND 或 OR 规则组合,因此当使用一次位图扫描时难以将取得的个体堆行与特定的索引关联起来。因此,一次位图扫描会增加它使用的索引的pg_stat_all_indexes.idx_tup_read计数,并且为该表增加pg_stat_all_tables.idx_tup_fetch计数,但是它不影响pg_stat_all_indexes.idx_tup_fetch。如果所提供的常量值不在优化器统计信息记录的范围之内,优化器也会访问索引来检查,因为优化器统计信息可能已经过时。 - 即使不用位图扫描,idx_tup_readidx_tup_fetch计数也可能不同,因为idx_tup_read统计从该索引取得的索引项而idx_tup_fetch统计从表取得的活着的行。如果使用该索引取得了任何死亡行或还未提交的行,或者如果通过一次只用索引扫描的方式避免了任何堆获取,后者将较小。 + 即使不用位图扫描,idx_tup_readidx_tup_fetch计数也可能不同,因为idx_tup_read统计从该索引取得的索引项而idx_tup_fetch统计从表取得的存活行。如果使用该索引取得了任何死亡行或还未提交的行,或者如果通过一次仅索引扫描的方式避免了任何堆获取,后者将较小。 @@ -4762,7 +4436,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage toast_blks_read bigint - 从这个表的TOAST表中读取的磁盘块的数量(如果有的话) + 从这个表的TOAST表中读取的磁盘块的数量(如果有的话) @@ -4771,7 +4445,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage toast_blks_hit bigint - 这个表的TOAST表中的缓冲区命中数(如果有的话) + 这个表的TOAST表中的缓冲区命中数(如果有的话) @@ -4780,7 +4454,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage tidx_blks_read bigint - 从这个表的TOAST表索引中读取的磁盘块的数量(如果有的话) + 从这个表的TOAST表索引中读取的磁盘块的数量(如果有的话) @@ -4789,7 +4463,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage tidx_blks_hit bigint - 这个表的TOAST表索引中的缓冲区命中数(如果有的话) + 这个表的TOAST表索引中的缓冲区命中数(如果有的话) @@ -5076,7 +4750,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - PostgreSQL通过SLRU(simple least-recently-used,简单的最近-最少-使用)缓存访问某些磁盘上的信息。 + PostgreSQL通过SLRU(simple least-recently-used,简单最近最少使用)缓存访问某些磁盘上的信息。 pg_stat_slru视图将为每个被跟踪的SLRU缓存包含一行,显示关于访问缓存页面的统计信息。 @@ -5121,7 +4795,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage blks_hit bigint - 已经在SLRU中的磁盘块被发现的次数,因此不需要读取(这只包括SLRU中的命中,而不是操作系统的文件系统缓存) + 已经在SLRU中的磁盘块被发现的次数,因此不需要读取(这只包括SLRU中的命中,而不是操作系统的文件系统缓存) @@ -5157,7 +4831,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage flushes bigint - 此SLRU的脏数据刷新数 + 此SLRU的脏数据刷盘次数 @@ -5166,7 +4840,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage truncates bigint - 这个SLRU的截断数 + 这个SLRU的截断次数 @@ -5174,9 +4848,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage stats_reset timestamp with time zone - - 这些统计数据最后一次重置的时间 - + 这些统计信息上次被重置的时间 @@ -5196,7 +4868,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - 与累积统计系统相关的其他功能在中列出。 + 与累积统计系统相关的其他函数在中列出。 @@ -5242,21 +4914,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - - - - pg_stat_get_backend_wal - - pg_stat_get_backend_wal ( integer ) - record - - - 返回指定进程 ID 的后端的 WAL 统计信息。输出字段与 pg_stat_wal 视图中的字段完全相同。 - - - 该函数不会返回检查点进程、后台写入器、启动进程和 自动清理启动器的 WAL 统计信息。 - - + @@ -5267,7 +4925,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage timestamp with time zone - 返回当前统计快照的时间戳,如果没有统计快照则返回NULL。如果在事务中第一次访问累积统计信息时将快照设置为stats_fetch_consistencysnapshot。 + 返回当前统计快照的时间戳;如果尚未获取统计快照,则返回 NULL。如果 stats_fetch_consistency 设置为 snapshot,则会在事务中第一次访问累积统计信息时获取快照。 @@ -5323,9 +4981,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage 将当前数据库的所有统计计数器重置为零。 - - 默认情况下该函数仅限于超级用户,但是其他用户可以被授予EXECUTE来运行此函数。 - + 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 @@ -5337,32 +4993,12 @@ description | Waiting for a newly initialized WAL file to reach durable storage void - 根据参数将一些集簇范围的统计计数器重置为零。参数可以是bgwriter, - 用于重置在pg_stat_bgwriter视图中显示的所有计数器, - archiver,用于重置在pg_stat_archiver视图中显示的所有计数器, - wal,用于重置在pg_stat_wal视图中显示的所有计数器, - 或recovery_prefetch,用于重置在pg_stat_recovery_prefetch视图中显示的所有计数器。 + 根据参数将一些集簇范围的统计计数器重置为零。参数可以为 bgwriter,用于重置 pg_stat_bgwriter 视图中显示的所有计数器;archiver,用于重置 pg_stat_archiver 视图中显示的所有计数器;wal,用于重置 pg_stat_wal 视图中显示的所有计数器;或 recovery_prefetch,用于重置 pg_stat_recovery_prefetch 视图中显示的所有计数器。 - - 默认情况下,此函数仅限超级用户使用,但可以授予其他用户EXECUTE权限来运行该函数。 - + 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 - - - - pg_stat_reset_backend_stats - - pg_stat_reset_backend_stats ( integer ) - void - - - 将指定进程 ID 的单个后端进程的统计信息重置为零。 - - - 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 - - + @@ -5373,11 +5009,9 @@ description | Waiting for a newly initialized WAL file to reach durable storage void - 重置当前数据库中的单个表或索引的统计信息,或者在集簇中跨所有数据库共享的统计信息为零。 + 将单个表或索引的统计信息重置为零;该对象可以位于当前数据库中,也可以由集簇中的所有数据库共享。 - - 默认情况下,此函数仅限超级用户使用,但可以授予其他用户EXECUTE权限来运行该函数。 - + 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 @@ -5391,9 +5025,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage 将当前数据库中单个函数的统计信息重置为零。 - - 默认情况下该函数仅限于超级用户,但是其他用户可以被授予EXECUTE来运行此函数。 - + 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 @@ -5405,15 +5037,9 @@ description | Waiting for a newly initialized WAL file to reach durable storage void - 将单个SLRU缓存或集簇中所有SLRU的统计信息重置为零。 - 如果该参数为NULL,则所有SLRU缓存的pg_stat_slru视图中显示的计数器将被重置。 - 参数可以是CommitTsMultiXactMemberMultiXactOffsetNotify、 - SerialSubtrans、 或Xact中的一个,以便只重置该条目的计数器。 - 如果参数是other(或实际上,任何无法识别的名称),那么所有其他SLRU缓存的计数器,如扩展定义的缓存,将被重置。 + 将单个 SLRU 缓存或集簇中所有 SLRU 的统计信息重置为零。如果参数为空值,则重置 pg_stat_slru 视图中所有 SLRU 缓存的全部计数器。参数可以为 CommitTs、&zwsp;MultiXactMember、&zwsp;MultiXactOffset、&zwsp;Notify、&zwsp;Serial、&zwsp;SubtransXact 中的一个,以便只重置对应条目的计数器。如果参数为 other(实际上,任何无法识别的名称都可以),则重置其他所有 SLRU 缓存的计数器,例如扩展定义的缓存。 - - 默认情况下该函数仅限于超级用户,但是其他用户可以被授予EXECUTE来运行此函数。 - + 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 @@ -5428,9 +5054,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage 重置由参数定义的复制槽的统计信息。 如果参数为NULL,则重置所有复制槽的统计信息。 - - 该函数默认仅限于超级用户,但可以授予其他用户EXECUTE权限来运行该函数。 - + 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 @@ -5445,9 +5069,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage 重置pg_stat_subscription_stats视图中显示的单个订阅的统计信息为零。 如果参数是NULL,则重置所有订阅的统计信息。 - - 默认情况下,此函数仅限超级用户使用,但其他用户可以被授予EXECUTE权限来运行该函数。 - + 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 @@ -5527,7 +5149,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, pg_stat_get_backend_activity_startpg_stat_get_backend_activity_start ( integer ) - 有时区的时间戳 + timestamp with time zone 返回后端最近一次查询开始的时间。 @@ -5592,25 +5214,12 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, pg_stat_get_backend_start pg_stat_get_backend_start ( integer ) - 有时区的时间戳 + timestamp with time zone - - 返回该进程开始的时间。 - + 返回该进程开始的时间。 - - - - pg_stat_get_backend_subxact - - pg_stat_get_backend_subxact ( integer ) - record - - - 返回指定 ID 的后端进程的子事务信息记录。返回的字段包括 subxact_count(该后端进程子事务缓存中的子事务数量)以及 subxact_overflow(指示该后端进程的子事务缓存是否已溢出)。 - - + @@ -5634,7 +5243,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, text - 如果后端当前正在等待,则返回等待事件类型名称,否则返回NULL。 + 如果后端当前正在等待,则返回等待事件类型名称,否则返回空值。 请参阅 @@ -5648,7 +5257,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, text - 如果后端当前正在等待,则返回等待事件名称,否则为NULL。 + 如果后端当前正在等待,则返回等待事件名称,否则为空值。 请参阅 @@ -5659,7 +5268,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, pg_stat_get_backend_xact_startpg_stat_get_backend_xact_start ( integer ) - 有时区的时间戳 + timestamp with time zone 返回后端当前事务开始的时间。 @@ -5677,23 +5286,23 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, 查看锁 - lock - monitoring + + 监控 - 监控数据库活动的另外一个有用的工具是pg_locks系统表。这样就允许数据库管理员查看在锁管理器里面未解决的锁的信息。例如,这个功能可以被用于: + 监控数据库活动的另外一个有用的工具是pg_locks系统表。这样就允许数据库管理员查看锁管理器中当前存在的锁的信息。例如,这个功能可以被用于: - 查看当前所有未解决的锁、在一个特定数据库中的关系上所有的锁、在一个特定关系上所有的锁,或者由一个特定PostgreSQL会话持有的所有的锁。 + 查看当前存在的所有锁、在一个特定数据库中的关系上所有的锁、在一个特定关系上所有的锁,或者由一个特定PostgreSQL会话持有的所有的锁。 - 判断当前数据库中带有最多未授予锁的关系(它很可能是数据库客户端的竞争源)。 + 判断当前数据库中带有最多未授予锁的关系(它可能是数据库客户端之间的竞争来源)。 @@ -5855,14 +5464,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - - - delay_time double precision - - - 因基于成本的延迟而睡眠的总时间(参见),以毫秒计(如果启用了 ,否则为零)。 - - +
@@ -5892,14 +5494,14 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, acquiring sample rows - 该命令当前正在扫描relid给出的表以获得样例行。 + 该命令当前正在扫描relid给出的表以获得样本行。 acquiring inherited sample rows - 该命令当前正在扫描子表以获得样例行。列child_tables_total,child_tables_done, + 该命令当前正在扫描子表以获得样本行。列child_tables_totalchild_tables_done、 和current_child_table_relid包含此阶段的进度信息。 @@ -5907,14 +5509,14 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, computing statistics - 该命令从表扫描期间获得的样例行计算统计信息。 + 该命令从表扫描期间获得的样本行计算统计信息。 computing extended statistics - 该命令从表扫描期间获得的样例行计算扩展统计信息。 + 该命令从表扫描期间获得的样本行计算扩展统计信息。 @@ -5930,10 +5532,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - - 注意当在分区表上运行ANALYZE时,它的所有分区也会被递归分析。 - 在这种情况下,首先报告父表的ANALYZE进度,收集它的继承统计信息,然后是每个分区的(继承统计信息)。 - + 请注意,当在分区表上运行ANALYZE时,其所有分区也会被递归分析。在这种情况下,会先报告父表的ANALYZE进度,并收集其继承统计信息,随后再报告每个分区的进度。
@@ -6018,8 +5617,8 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, command text - 在运行的命令: CREATE INDEX,CREATE INDEX CONCURRENTLY, - REINDEX, 或 REINDEX CONCURRENTLY. + 在运行的命令: CREATE INDEXCREATE INDEX CONCURRENTLY、 + REINDEXREINDEX CONCURRENTLY @@ -6036,27 +5635,21 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, lockers_total bigint - - 在适用的情况下,需要等待的储物柜总数 - + 在适用的情况下,需要等待的持锁进程总数。 lockers_done bigint - - 已经等待的储物柜数量。 - + 已完成等待的持锁进程数量。 current_locker_pid bigint - - 目前正在等待的储物柜的进程ID。 - + 当前正在等待的持锁进程的进程 ID。 @@ -6064,7 +5657,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, blocks_total bigint - 本阶段要处理的区块总数。 + 本阶段要处理的块总数。 @@ -6073,7 +5666,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, blocks_done bigint - 当前阶段已经处理的区块数量。 + 当前阶段已经处理的块数量。 @@ -6120,7 +5713,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - CREATE INDEX 的阶段 + CREATE INDEX 阶段 @@ -6134,70 +5727,70 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - 初始化 + initializing CREATE INDEXREINDEX正在准备创建索引。 这个阶段预计会非常短暂。 - 构建前等待读写器 + waiting for writers before build - CREATE INDEX CONCURRENTLYREINDEX CONCURRENTLY正在等待有可能看到表的写锁的事务完成。 当不在并发模式时,这个阶段会被跳过。lockers_totallockers_donecurrent_locker_pid 列包含了这个阶段的进度信息。 + CREATE INDEX CONCURRENTLYREINDEX CONCURRENTLY正在等待持有写锁且可能看到该表的事务结束。 当不在并发模式时,这个阶段会被跳过。lockers_totallockers_donecurrent_locker_pid 列包含了这个阶段的进度信息。 - 新建索引 + building index - 索引是由访问方法专用代码建立的。 在这一阶段,支持进度报告的访问方法填写自己的进度数据,子阶段在这一栏中表示。 通常情况下,blocks_totalblocks_done将包含进度数据,也可能包含tuples_totaltuples_done。 + 索引是由访问方法专用代码建立的。 在这一阶段,支持进度报告的访问方法填写自己的进度数据,子阶段在这一栏中表示。 通常情况下,blocks_totalblocks_done将包含进度数据,tuples_totaltuples_done也可能包含进度数据。 - 在验证前等待读写器 + waiting for writers before validation - CREATE INDEX CONCURRENTLYREINDEX CONCURRENTLY正在等待有可能写入表的事务完成写锁的事务。当不在并发模式时,这个阶段会被跳过。lockers_totallockers_donecurrent_locker_pid 列包含了这个阶段的进度信息。 + CREATE INDEX CONCURRENTLYREINDEX CONCURRENTLY正在等待持有写锁且可能写入该表的事务结束。当不在并发模式时,这个阶段会被跳过。lockers_totallockers_donecurrent_locker_pid 列包含了这个阶段的进度信息。 - 索引验证:扫描索引 + index validation: scanning index CREATE INDEX CONCURRENTLY正在扫描索引,搜索需要验证的元组。如果不是并发模式,则会跳过此阶段。列 blocks_total(设为索引总大小)和 blocks_done 包含该阶段的进度信息。 - 索引验证:排序元组 + index validation: sorting tuples CREATE INDEX CONCURRENTLY正在对索引扫描阶段的输出进行排序。 - 索引验证:扫描表 + index validation: scanning table CREATE INDEX CONCURRENTLY正在扫描表,以验证前两个阶段收集的索引元组。如果不是并发模式,则会跳过此阶段。blocks_total 列(设为表总大小)和 blocks_done 列包含该阶段的进度信息。 - 等待旧照 + waiting for old snapshots CREATE INDEX CONCURRENTLYREINDEX CONCURRENTLY正在等待可能看到表的事务释放快照。 当不处于并发模式时,这个阶段会被跳过。 lockers_totallockers_donecurrent_locker_pid 列包含了这个阶段的进度信息。 - 标记 dead之前等待readers + waiting for readers before marking dead REINDEX CONCURRENTLY等待表上有读锁的事务完成后,再将旧索引标记为死索引。当不在并发模式时,这个阶段被跳过。lockers_totallockers_donecurrent_locker_pid 列包含了这个阶段的进度信息。 - 在 dropping之前等待readers + waiting for readers before dropping REINDEX CONCURRENTLY等待表上有读锁的事务完成后,再丢弃旧索引。当不在并发模式时,这个阶段被跳过。列 lockers_totallockers_donecurrent_locker_pid包含了这个阶段的进度信息。 @@ -6270,7 +5863,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, relid oid - 被vacuum的表的OID。 + 正在清理的表的OID。 @@ -6279,7 +5872,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, phasetext - vacuum的当前处理阶段。参见 。 + 清理的当前处理阶段。参见 @@ -6288,7 +5881,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, heap_blks_totalbigint - 该表中堆块的总数。这个数字在扫描开始时报告,之后增加的块将不会(并且不需要)被这个VACUUM访问。 + 该表中堆块的总数。这个数字以扫描开始时的数量为准,之后增加的块将不会(并且不需要)被这个VACUUM访问。 @@ -6297,9 +5890,9 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, heap_blks_scannedbigint - 被扫描的堆块数量。由于visibility map被用来优化扫描,一些块将被跳过而不做检查, + 被扫描的堆块数量。由于可见性映射被用来优化扫描,一些块将被跳过而不做检查, 被跳过的块会被包括在这个总数中,因此当清理完成时这个数字最终将会等于heap_blks_total。 - 仅当处于扫描堆阶段时这个计数器才会前进。 + 仅当处于scanning heap阶段时这个计数器才会前进。 @@ -6308,7 +5901,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, heap_blks_vacuumedbigint - 被清理的堆块数量。除非表没有索引,这个计数器仅在处于清理堆阶段时才会前进。 + 被清理的堆块数量。除非表没有索引,这个计数器仅在处于vacuuming heap阶段时才会前进。 不包含死亡元组的块会被跳过,因此这个计数器可能有时会向前跳跃一个比较大的增量。 @@ -6324,64 +5917,40 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - max_dead_tuple_bytes bigint + max_dead_tuples bigint - 在需要执行索引清理周期之前可存储的死亡元组数据量,取决于。 + 在需要执行索引清理周期之前可存储的死亡元组数量,取决于 - dead_tuple_bytes bigint + num_dead_tuples bigint - 自上一个索引清理周期以来收集到的死亡元组数据量。 + 自上一个索引清理周期以来收集到的死亡元组数量。 - - - num_dead_item_ids bigint - - - 自上一个索引清理周期以来收集到的死项标识符数量。 - - - - - indexes_total bigint - - - 将要执行 vacuum 或清理的索引总数。该数字会在 vacuuming indexescleaning up indexes 阶段开始时报告。 - - - - - indexes_processed bigint - - - 已处理的索引数量。该计数器只会在 vacuuming indexescleaning up indexes 阶段推进。 - - - - - delay_time double precision - - - 因基于成本的延迟而睡眠的总时间(参见),以毫秒计(如果启用了 ,否则为零)。这包括任何相关并行工作进程的睡眠时间;不过,并行工作进程最多每秒才会上报一次自己的睡眠时间,因此该值可能略有滞后。 - - + + + + + + + +
- VACUUM的阶段 + VACUUM 阶段 @@ -6396,51 +5965,47 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - 初始化 + initializing VACUUM正在准备开始扫描堆。这个阶段应该很简短。 - 扫描堆 + scanning heap - VACUUM正在扫描堆。如果需要,它将会对每个页面进行修建以及碎片整理,并且可能会执行冻结动作。heap_blks_scanned列可以用来监控扫描的进度。 + VACUUM正在扫描堆。如果需要,它将会对每个页面进行剪枝以及碎片整理,并且可能会执行冻结动作。heap_blks_scanned列可以用来监控扫描的进度。 - 清理索引 - - VACUUM当前正在清理索引。 - 如果一个表拥有索引,那么每次清理时这个阶段会在堆扫描完成后至少发生一次。 - 如果不足以存放找到的死亡元组(或者, 在autovacuum情况下,如果设置了) ,则每次清理时会多次清理索引。 - + vacuuming indexes + VACUUM当前正在清理索引。如果表有索引,每次清理都会在堆扫描完成后至少执行一次此阶段。如果(或者,对于自动清理,已设置的)不足以存储找到的死亡元组数量,则每次清理可能多次执行此阶段。 - 清理堆 + vacuuming heap - VACUUM当前正在清理堆。清理堆与扫描堆不是同一个概念,清理堆发生在每一次清理索引的实例之后。如果heap_blks_scanned小于heap_blks_total,系统将在这个阶段完成之后回去扫描堆;否则,系统将在这个阶段完成后开始清理索引。 + VACUUM当前正在清理堆。清理堆与扫描堆不是同一个概念,清理堆发生在每次索引清理之后。如果heap_blks_scanned小于heap_blks_total,系统将在这个阶段完成之后回去扫描堆;否则,系统将在这个阶段完成后开始索引收尾清理。 - 清除索引 + cleaning up indexes - VACUUM当前正在清除索引。这个阶段发生在堆被完全扫描并且对堆和索引的所有清理都已经完成以后。 + VACUUM当前正在进行索引收尾清理。这个阶段发生在堆被完全扫描并且对堆和索引的所有清理都已经完成以后。 - 截断堆 + truncating heap - VACUUM正在截断堆,以便把关系尾部的空页面返还给操作系统。这个阶段发生在清除完索引之后。 + VACUUM正在截断堆,以便把关系尾部的空页面返还给操作系统。这个阶段发生在索引收尾清理完成之后。 - 执行最终清理 + performing final cleanup VACUUM正在执行最终清理。在此阶段,VACUUM将清理空闲空间映射, 更新pg_class中的统计信息,并向累积统计系统报告统计信息。当此阶段完成时, @@ -6462,7 +6027,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - 每当CLUSTERVACUUM FULL运行时,pg_stat_progress_cluster视图将包含当前正在运行的每一个后台的记录。下面的表格描述了将被报告的信息,并提供了关于如何解释这些信息的信息。 + 每当CLUSTERVACUUM FULL运行时,pg_stat_progress_cluster视图将为每个当前正在运行这两种命令之一的后端包含一行。下面的表格描述了将被报告的信息,并提供了关于如何解释这些信息的信息。
@@ -6515,7 +6080,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, relidoid - 被集群的表的OID。 + 正在聚簇的表的OID。 @@ -6562,8 +6127,8 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, heap_tuples_writtenbigint - 写入的堆元组的数量。这个计数器只有在阶段为seq scanning heap,index scanning heap - 或 writing new heap时才会前进。 + 写入的堆元组的数量。这个计数器只有在阶段为seq scanning heapindex scanning heap + 或 writing new heap时才会递增。 @@ -6572,7 +6137,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, heap_blks_totalbigint - 表中的堆块总数。 这个数字是在seq scanning heap的开始时报告的。 + 表中的堆块总数。 这个数字以seq scanning heap开始时的数量为准。 @@ -6590,7 +6155,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, index_rebuild_countbigint - 已重建的索引数。该计数器仅在重建索引阶段时才会递增。 + 已重建的索引数。该计数器仅在rebuilding index阶段时才会递增。 @@ -6614,56 +6179,56 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - 初始化 + initializing - 该命令准备开始扫描堆栈。 这个阶段预计会非常短暂。 - + 命令正在准备开始扫描堆。这个阶段预计会非常短暂。 + - seq扫描堆 + seq scanning heap 该命令目前采用顺序扫描的方式对表进行扫描。 - 索引扫描堆 + index scanning heap CLUSTER目前正在使用索引扫描表。 - 元组排序 + sorting tuples CLUSTER目前正在对元组进行排序。 - 新写入堆 + writing new heap - CLUSTER目前正在编写新的堆。 + CLUSTER目前正在写入新的堆。 - 交换关系文件 + swapping relation files 目前,该命令正在将新建立的文件调换到位。 - 重建索引 + rebuilding index 该命令目前正在重建一个索引。 - 清理 + performing final cleanup 该命令正在执行最后的清理工作。 当此阶段完成后,CLUSTERVACUUM FULL将结束。 @@ -6731,7 +6296,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, 将被流式传输的数据总量。该值在streaming database files阶段开始时进行估算并报告。 注意,这只是一个近似值,因为数据库可能会在streaming database files阶段期间发生变化,而 WAL 日志也可能在稍后的备份阶段被包含进来。 一旦流式传输的数据量超过了估计的总大小,该值始终与backup_streamed相同。 - 如果在pg_basebackup中禁用估算(也就是说,指定了--no-estimate-size选项),这为NULL。 + 如果在pg_basebackup中禁用估算(也就是说,指定了--no-estimate-size选项),这为NULL @@ -6788,7 +6353,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - 等待检查点完成 + waiting for checkpoint to finish WAL 发送进程当前正在执行pg_backup_start以准备进行基础备份,并等待备份起始检查点完成。 @@ -6809,7 +6374,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - 等待wal归档完成 + waiting for wal archiving to finish WAL发送进程当前正在执行pg_backup_stop以完成备份, 并等待基础备份所需的所有 WAL 文件成功归档。 @@ -6904,7 +6469,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, command text - 正在运行的命令: COPY FROM, 或 COPY TO。 + 正在运行的命令: COPY FROMCOPY TO @@ -6912,9 +6477,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, type text - - 数据被读取或写入的io类型:FILE, PROGRAM, PIPE (对于COPY FROM STDINCOPY TO STDOUT),或 CALLBACK(例如在逻辑复制中初始表同步期间使用)。 - + 读取或写入数据的 I/O 类型:FILEPROGRAMPIPE(用于COPY FROM STDINCOPY TO STDOUT),或CALLBACK(例如在逻辑复制的初始表同步期间使用)。 @@ -6954,14 +6517,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - - - tuples_skipped bigint - - - 因包含格式错误的数据而被跳过的元组数。只有当 ON_ERROR 选项指定的值不是 stop 时,此计数器才会递增。 - - +
@@ -6992,10 +6548,10 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - 动态追踪的编译 + 为动态追踪编译 - 默认情况下,探针是不可用的,因此你将需要显式地告诉配置脚本让探针在PostgreSQL中可用。要包括 DTrace 支持,在配置时指定。更多信息请见。 + 默认情况下,探针是不可用的,因此你将需要显式地告诉配置脚本让探针在PostgreSQL中可用。要包括 DTrace 支持,在配置时指定。更多信息请见 @@ -7004,7 +6560,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, 内置探针 - 如所示,源代码中提供了一些标准探针。显式了在探针中使用的类型。当然,可以增加更多探针来增强PostgreSQL的可观测性。 + 如所示,源代码中提供了一些标准探针。显示了在探针中使用的类型。当然,可以增加更多探针来增强PostgreSQL的可观测性。 @@ -7040,13 +6596,13 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, transaction-abort (LocalTransactionId) - 当一个事务失败完成时触发的探针。arg0 是事务 ID。 + 当一个事务失败结束时触发的探针。arg0 是事务 ID。 query-start (const char *) - 当一个查询的处理被开始时触发的探针。arg0 是查询字符串。 + 当一个查询的处理开始时触发的探针。arg0 是查询字符串。 @@ -7058,7 +6614,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, query-parse-start (const char *) - 当一个查询的解析被开始时触发的探针。arg0 是查询字符串。 + 当一个查询的解析开始时触发的探针。arg0 是查询字符串。 @@ -7070,7 +6626,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, query-rewrite-start (const char *) - 当一个查询的重写被开始时触发的探针。arg0 是查询字符串。 + 当一个查询的重写开始时触发的探针。arg0 是查询字符串。 @@ -7082,7 +6638,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, query-plan-start () - 当一个查询的规划被开始时触发的探针。 + 当一个查询的规划开始时触发的探针。 @@ -7094,7 +6650,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, query-execute-start () - 当一个查询的执行被开始时触发的探针。 + 当一个查询的执行开始时触发的探针。 @@ -7112,19 +6668,19 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, checkpoint-start (int) - 当一个检查点被开始时触发的探针。arg0 传递位标志来区分不同的检查点类型,例如关闭(shutdown)、立即(immediate)或强制(force)。 + 当一个检查点开始时触发的探针。arg0 传递位标志来区分不同的检查点类型,例如关闭(shutdown)、立即(immediate)或强制(force)。 checkpoint-done (int, int, int, int, int) - 当一个检查点完成时触发的探针(检查点处理过程中序列中列出的下一个触发的探针)。arg0 是要写的缓冲区数量。arg1 是缓冲区的总数。arg2、arg3 和 arg4 分别包含了增加、删除和循环回收的 WAL 文件的数量。 + 当一个检查点完成时触发的探针(下面列出的探针会在检查点处理过程中依次触发)。arg0 是已写入的缓冲区数量。arg1 是缓冲区的总数。arg2、arg3 和 arg4 分别包含了增加、删除和循环回收的 WAL 文件的数量。 clog-checkpoint-start (bool) - 当一个检查点的 CLOG 部分被开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 + 当一个检查点的 CLOG 部分开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 @@ -7136,7 +6692,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, subtrans-checkpoint-start (bool) - 当一个检查点的 SUBTRANS 部分被开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 + 当一个检查点的 SUBTRANS 部分开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 @@ -7148,7 +6704,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, multixact-checkpoint-start (bool) - 当一个检查点的 MultiXact 部分被开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 + 当一个检查点的 MultiXact 部分开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 @@ -7160,7 +6716,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, buffer-checkpoint-start (int) - 当一个检查点的写缓冲区部分被开始时触发的探针。arg0 传递位标志来区分不同的检查点类型,例如关闭(shutdown)、立即(immediate)或强制(force)。 + 当一个检查点的写缓冲区部分开始时触发的探针。arg0 传递位标志来区分不同的检查点类型,例如关闭(shutdown)、立即(immediate)或强制(force)。 @@ -7196,7 +6752,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, twophase-checkpoint-start () - 当一个检查点的两阶段部分被开始时触发的探针。 + 当一个检查点的两阶段部分开始时触发的探针。 @@ -7208,19 +6764,19 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, buffer-read-start (ForkNumber, BlockNumber, Oid, Oid, Oid, int, bool) - 当一次缓冲区读被开始时触发的探针。arg0 和 arg1 包含该页的分叉号和块号(如果这是一次关系扩展请求,arg1 为 -1)。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是 InvalidBackendId(-1)。arg6 为真表示一次关系扩展请求,为假表示正常读。 + 当一次缓冲区读开始时触发的探针。arg0 和 arg1 包含该页的分支号和块号(如果这是一次关系扩展请求,arg1 为 -1)。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是 InvalidBackendId(-1)。arg6 为真表示一次关系扩展请求,为假表示正常读。 buffer-read-done (ForkNumber, BlockNumber, Oid, Oid, Oid, int, bool, bool) - 当一次缓冲区读完成时触发的探针。arg0 和 arg1 包含该页的分叉号和块号(如果这是一次关系扩展请求,arg1 现在包含新增加块的块号)。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是 InvalidBackendId(-1)。arg6 为真表示一次关系扩展请求,为假表示正常读。arg7 为真表示在池中找到该缓冲区,为假表示没有找到。 + 当一次缓冲区读完成时触发的探针。arg0 和 arg1 包含该页的分支号和块号(如果这是一次关系扩展请求,arg1 现在包含新增加块的块号)。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是 InvalidBackendId(-1)。arg6 为真表示一次关系扩展请求,为假表示正常读。arg7 为真表示在池中找到该缓冲区,为假表示没有找到。 buffer-flush-start (ForkNumber, BlockNumber, Oid, Oid, Oid) - 在发出对一个共享缓冲区的任意写请求之前触发的探针。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。 + 在发出对一个共享缓冲区的任意写请求之前触发的探针。arg0 和 arg1 包含该页的分支号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。 @@ -7232,7 +6788,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, buffer-write-dirty-start (ForkNumber, BlockNumber, Oid, Oid, Oid) - 当一个服务器进程开始写一个脏缓冲区时触发的探针(如果这经常发生,表示太小,或需要调整后台写入器的控制参数)。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。 + 当一个服务器进程开始写一个脏缓冲区时触发的探针(如果这经常发生,表示太小,或需要调整后台写入器的控制参数)。arg0 和 arg1 包含该页的分支号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。 @@ -7250,13 +6806,13 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, wal-buffer-write-dirty-done () - 当一次脏 WAL 缓冲区完成时触发的探针。 + 当一次脏 WAL 缓冲区写入完成时触发的探针。 wal-insert (unsigned char, unsigned char) - 当一个 WAL 记录被插入时触发的探针。arg0 是该记录的资源管理者(rmid)。arg1 包含 info 标志。 + 当一个 WAL 记录被插入时触发的探针。arg0 是该记录的资源管理器(rmid)。arg1 包含 info 标志。 @@ -7268,31 +6824,31 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, smgr-md-read-start (ForkNumber, BlockNumber, Oid, Oid, Oid, int) - 当开始从一个关系读取一块时触发的探针。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。 + 当开始从一个关系读取一块时触发的探针。arg0 和 arg1 包含该页的分支号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。 smgr-md-read-done (ForkNumber, BlockNumber, Oid, Oid, Oid, int, int, int) - 当一次块读取完成时触发的探针。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。arg6 是实际读取的字节数,而 arg7 是请求读取的字节数(如果两者不同就意味着麻烦)。 + 当一次块读取完成时触发的探针。arg0 和 arg1 包含该页的分支号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。arg6 是实际读取的字节数,而 arg7 是请求读取的字节数(如果两者不同就意味着麻烦)。 smgr-md-write-start (ForkNumber, BlockNumber, Oid, Oid, Oid, int) - 当开始向一个关系中写入一个块时触发的探针。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。 + 当开始向一个关系中写入一个块时触发的探针。arg0 和 arg1 包含该页的分支号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。 smgr-md-write-done (ForkNumber, BlockNumber, Oid, Oid, Oid, int, int, int) - 当一个块写操作完成时触发的探针。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3和arg4 包含表空间、数据库和关系 OID来标识该关系。对于一个本地缓冲区,arg5 是创建临时关系的后端 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。arg6 是实际写的字节数,而 arg7 是要求写的字节数(如果这两者不同,则意味着麻烦)。 + 当一个块写操作完成时触发的探针。arg0 和 arg1 包含该页的分支号和块号。arg2、arg3和arg4 包含表空间、数据库和关系 OID来标识该关系。对于一个本地缓冲区,arg5 是创建临时关系的后端 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。arg6 是实际写的字节数,而 arg7 是要求写的字节数(如果这两者不同,则意味着麻烦)。 sort-start (int, bool, int, int, bool, int) - 当一次排序操作开始时触发的探针。arg0 指示是堆排序、索引排序或数据排序。arg1 为真表示强制唯一值。arg2 是键列数。arg3 是允许使用的工作内存大小(以千字节计)。如果要求随机访问排序结果,则 arg4 为真。arg5 为 0 时表示串行,为 1 时表示并行工作进程,为 2 时表示并行领导者。 + 当一次排序操作开始时触发的探针。arg0 指示是堆排序、索引排序或 datum 排序。arg1 为真表示强制唯一值。arg2 是键列数。arg3 是允许使用的工作内存大小(以千字节计)。如果要求随机访问排序结果,则 arg4 为真。arg5 为 0 时表示串行,为 1 时表示并行工作进程,为 2 时表示并行领导者。 @@ -7306,7 +6862,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, (char *, LWLockMode) 当成功获得一个 LWLock 时触发的探针。 arg0 是该 LWLock 所在的切片(Tranche)。 - arg1 所请求的锁模式,是排他或共享。 + arg1 是所请求的锁模式,是排他或共享。 @@ -7321,34 +6877,34 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, (char *, LWLockMode) 当一个 LWLock不是当即可用并且一个服务器进程因此开始等待该锁变为可用时触发的探针。 arg0 是该 LWLock 所在的切片(Tranche)。 - arg1 请求的锁模式,是排他或共享。 + arg1 是所请求的锁模式,是排他或共享。 lwlock-wait-done (char *, LWLockMode) 当一个进程从对一个 LWLock 的等待中被释放时(它实际还没有得到该锁)时触发的探针。arg0 是该 LWLock 所在的切片(Tranche)。 - arg1 所请求的锁模式,是排他或共享。 + arg1 是所请求的锁模式,是排他或共享。 lwlock-condacquire (char *, LWLockMode) 当调用者指定无需等待而成功获得一个 LWLock 时触发的探针。arg0 是该 LWLock 所在的切片(Tranche)。 - arg1 所请求的锁模式,是排他或共享。 + arg1 是所请求的锁模式,是排他或共享。 lwlock-condacquire-fail (char *, LWLockMode) 当调用者指定无需等待而没有成功获得一个 LWLock 时触发的探针。arg0 是该 LWLock 所在的切片(Tranche)。 - arg1 所请求的锁模式,是排他或共享。 + arg1 是所请求的锁模式,是排他或共享。 lock-wait-start (unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, LOCKMODE) - 当一个重量级锁(lmgr锁)的请求由于锁不可用开始等待时触发的探针。arg0 到 arg3 是标识被锁定对象的标签域。arg4 指示被锁对象的类型。arg5 表示被请求的锁类型。 + 当一个重量级锁(lmgr锁)的请求由于锁不可用开始等待时触发的探针。arg0 到 arg3 是标识被锁定对象的标签字段。arg4 指示被锁对象的类型。arg5 表示被请求的锁类型。 @@ -7369,7 +6925,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid,
- 定义用在探针参数中的类型 + 探针参数中使用的已定义类型 @@ -7463,7 +7019,7 @@ Total time (ns) 2312105013 - 你应该记住,DTrace 脚本需要细心地编写和调试,否则被收集的追踪信息可能会毫无意义。在大部分发现问题的情况中,它就是发生问题的部件,而不是底层系统。当讨论使用动态追踪发现的信息时,一定要附上使用的脚本以便其也被检查和讨论。 + 你应该记住,DTrace 脚本需要细心地编写和调试,否则被收集的追踪信息可能会毫无意义。在大多数发现问题的情况下,出错的是插桩,而不是底层系统。当讨论使用动态追踪发现的信息时,一定要附上使用的脚本以便其也被检查和讨论。 @@ -7479,7 +7035,7 @@ Total time (ns) 2312105013 - 决定探针名称以及探针可用的数据 + 决定探针名称以及要通过探针提供的数据 @@ -7493,7 +7049,7 @@ Total time (ns) 2312105013 - 如果pg_trace.h还不存在于包含该探针点的模块中,包括它,并且在源代码中期望的位置插入TRACE_POSTGRESQL探针宏 + 如果pg_trace.h尚未被包含该探针点的模块引用,则将它包含进来,并且在源代码中期望的位置插入TRACE_POSTGRESQL探针宏 @@ -7529,14 +7085,14 @@ Total time (ns) 2312105013 probe transaction__start(LocalTransactionId); - 注意探针名字中双下划线的使用。在一个使用探针的 DTrace 脚本中,双下划线需要被替换为一个连字符,因此 ,对用户而言transaction-start是文档名。 + 注意探针名字中双下划线的使用。在一个使用探针的 DTrace 脚本中,双下划线需要被替换为一个连字符,因此,文档中应向用户说明的名称是transaction-start - 在编译时,transaction__start被转换成一个宏调用TRACE_POSTGRESQL_TRANSACTION_START(注意这里是单下划线),可以通过包括头文件pg_trace.h获得。将宏调用加入到源代码中的合适位置。在这种情况下,看起来类似: + 在编译时,transaction__start被转换成一个名为TRACE_POSTGRESQL_TRANSACTION_START的宏(注意这里是单下划线),可以通过包含头文件pg_trace.h获得。将宏调用加入到源代码中的合适位置。在这种情况下,看起来类似: TRACE_POSTGRESQL_TRANSACTION_START(vxid.localTransactionId); @@ -7573,7 +7129,7 @@ TRACE_POSTGRESQL_TRANSACTION_START(vxid.localTransactionId); - 在大多数平台上,如果用编译了PostgreSQL,无论何时当控制经过一个追踪宏时,都会评估该宏的参数,即使没有进行追踪也会这样做。通常不需要担心你是否只在报告一些局部变量的值。但是要注意不要将开销大的函数调用放入参数中。如果你需要这样做,考虑通过检查追踪是否真的被启用来保护该宏: + 在大多数平台上,如果用编译了PostgreSQL,无论何时当控制经过一个追踪宏时,都会对该宏的参数求值,即使没有进行追踪也会这样做。如果只是报告少数局部变量的值,通常无需担心这一点。但是要注意不要将开销大的函数调用放入参数中。如果你需要这样做,考虑通过检查追踪是否真的被启用来保护该宏: if (TRACE_POSTGRESQL_TRANSACTION_START_ENABLED()) @@ -7591,114 +7147,6 @@ if (TRACE_POSTGRESQL_TRANSACTION_START_ENABLED()) - - 监控磁盘使用情况 - - - 本节讨论如何监控 PostgreSQL 数据库系统的磁盘使用情况。 - - - - 确定磁盘使用情况 - - - disk usage - - - - 每个表都有一个主堆磁盘文件,大部分数据都存储在那里。如果表中有任何列可能包含较宽的值,还可能有一个与该表关联的 TOAST 文件,用于存储那些不适合放在主表中的过宽值(参见)。如果该 TOAST 表存在,则它会有一个有效索引。基础表本身也可能带有索引。每个表和索引都存储在单独的磁盘文件中;如果某个文件会超过 1 GB,则可能拆分为多个文件。关于这些文件的命名规则,请参见。 - - - - 你可以通过三种方式监控磁盘空间:使用中列出的 SQL 函数、使用模块,或者手工检查系统目录。SQL 函数最容易使用,通常也是推荐的方法。本节余下内容展示如何通过检查系统目录来完成这项工作。 - - - - 在最近执行过 VACUUMANALYZE 的数据库上使用 psql,你可以发出查询来查看任意表的磁盘使用情况: - -SELECT pg_relation_filepath(oid), relpages FROM pg_class WHERE relname = 'customer'; - - pg_relation_filepath | relpages -----------------------+---------- - base/16384/16806 | 60 -(1 row) - - 每一页通常是 8 KB。(请记住,relpages 只会由 VACUUMANALYZE 以及少数 DDL 命令如 CREATE INDEX 更新。)如果你想直接检查该表的磁盘文件,那么文件路径名会很有用。 - - - 要显示 TOAST 表使用的空间,可以使用如下查询: - -SELECT relname, relpages -FROM pg_class, - (SELECT reltoastrelid - FROM pg_class - WHERE relname = 'customer') AS ss -WHERE oid = ss.reltoastrelid OR - oid = (SELECT indexrelid - FROM pg_index - WHERE indrelid = ss.reltoastrelid) -ORDER BY relname; - - relname | relpages -----------------------+---------- - pg_toast_16806 | 0 - pg_toast_16806_index | 1 - - - - - 也可以很容易地显示索引所占空间: - -SELECT c2.relname, c2.relpages -FROM pg_class c, pg_class c2, pg_index i -WHERE c.relname = 'customer' AND - c.oid = i.indrelid AND - c2.oid = i.indexrelid -ORDER BY c2.relname; - - relname | relpages --------------------+---------- - customer_id_index | 26 - - - - - 利用这些信息,你可以很容易地找出最大的表和索引: - -SELECT relname, relpages -FROM pg_class -ORDER BY relpages DESC; - - relname | relpages -----------------------+---------- - bigtable | 3290 - customer | 3144 - - - - - - 磁盘已满故障 - - - 数据库管理员最重要的磁盘监控任务,是确保磁盘不会被写满。数据磁盘写满不会导致数据损坏,但可能会阻止有用的活动继续进行。如果保存 WAL 文件的磁盘被写满,则数据库服务器可能会 panic 并随后关闭。 - - - - 如果你无法通过删除其他文件来释放更多磁盘空间,那么可以利用表空间把部分数据库文件移动到其他文件系统上。详见。 - - - - - 有些文件系统在接近写满时性能会明显变差,因此不要等到磁盘完全写满才采取措施。 - - - - - 如果你的系统支持按用户设置磁盘配额,那么数据库自然也会受到运行服务器的那个用户所拥有配额的限制。超出配额会带来与磁盘空间完全耗尽相同的不良影响。 - - - diff --git a/zh/15/mvcc.sgml b/zh/15/mvcc.sgml index 5dde519d..2bef66f2 100644 --- a/zh/15/mvcc.sgml +++ b/zh/15/mvcc.sgml @@ -306,11 +306,7 @@ 不过,由于 MERGE 可以指定多个动作并且这些动作可以带条件, 因此会从第一个动作开始,在该行的已更新版本上重新评估各动作的条件, 即使最初匹配的动作在动作列表中出现得更靠后。 - 另一方面,如果该行被并发更新以致连接条件不再成立,那么 MERGE - 接下来会评估命令的 NOT MATCHED BY SOURCE 和 - NOT MATCHED [BY TARGET] 动作,并分别执行每一类中第一个成功的动作。 - 如果该行被并发删除,那么 MERGE 会评估命令的 - NOT MATCHED [BY TARGET] 动作,并执行第一个成功的动作。 + 另一方面,如果该行被并发更新或删除,导致连接条件不成立,那么 MERGE 接下来会评估条件的 NOT MATCHED 动作,并执行第一个成功的动作。 如果 MERGE 尝试执行 INSERT,且存在唯一索引并且并发插入了重复行, 则会引发唯一性违例错误;MERGE 不会通过重新开始评估 MATCHED 条件来尝试避免此类错误。 @@ -319,7 +315,7 @@ 由于上述规则,更新命令可能看到一个不一致的快照:它能够看到并发更新命令在它试图更新的同一行上的效果, 却看不到这些命令对数据库中其他行的影响。这种行为使得读已提交模式不适合涉及复杂搜索条件的命令; - 不过,对于较简单的场景它恰到好处。例如,考虑将 100 美元从一个账户转到另一个账户: + 不过,对于较简单的场景它恰到好处。例如,考虑以如下事务更新银行余额: BEGIN; @@ -328,13 +324,13 @@ UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 7534; COMMIT; - 如果另一个事务并发地尝试更改账户 7534 的余额,我们显然希望第二条语句从该账户行的已更新版本开始。 + 如果两个这样的事务并发地尝试更改账户 12345 的余额,我们显然希望第二个事务从该账户行的已更新版本开始。 因为每个命令只影响一个预先确定的行,让它看到该行的已更新版本不会造成任何麻烦的不一致。 在读已提交模式下,更复杂的用法可能产生不理想的结果。例如,考虑一个 - DELETE 命令,它所处理的数据会被另一个命令同时加入和移出其筛选条件。 + DELETE 命令,另一个命令正在修改数据,使某些行开始满足其筛选条件、另一些行不再满足。 假设 website 是一个有两行的表,其中 website.hits 分别等于 910: @@ -342,7 +338,7 @@ COMMIT; BEGIN; UPDATE website SET hits = hits + 1; --- run from another session: DELETE FROM website WHERE hits = 10; +-- 从另一个会话运行: DELETE FROM website WHERE hits = 10; COMMIT; @@ -428,9 +424,7 @@ ERROR: could not serialize access due to concurrent update 可重复读模式提供了严格的保证,即每个事务都看到数据库的一个完全稳定的视图。 不过,这个视图并不一定总能与同一级别并发事务的某种串行(一次一个)执行保持一致。 - 例如,即使该级别上的只读事务可能看到一条控制记录被更新,表明某个批处理已经完成, - 但它并不一定能看到作为该批处理逻辑组成部分的某条明细记录, - 因为它读到的是控制记录的较早版本。如果不仔细使用显式锁来阻塞冲突事务, + 例如,即使是该级别的只读事务,也可能看到一条表明某批次已完成的控制记录,却看不到逻辑上属于该批次的某条明细记录,因为创建该明细记录的事务读取了控制记录的较早版本。如果不仔细使用显式锁来阻塞冲突事务, 试图依靠运行在这一隔离级别的事务来强制业务规则,往往无法正确工作。 @@ -438,7 +432,7 @@ ERROR: could not serialize access due to concurrent update 可重复读隔离级别是通过一种技术实现的,这种技术在学术数据库文献中以及某些其他数据库产品中被称为 快照隔离。与使用会降低并发性的传统加锁技术的系统相比, 其行为和性能可能会表现出差异。有些其他系统甚至把可重复读和快照隔离作为两个行为不同的独立隔离级别提供。 - 用来区分这两种技术的允许现象,直到 SQL 标准制定之后才被数据库研究人员正式定义,因此超出了本手册的范围。 + 用来区分这两种技术的允许现象,直到 SQL 标准制定之后才被数据库研究人员正式定义,并且超出了本手册的范围。 完整讨论请参阅 @@ -480,48 +474,30 @@ ERROR: could not serialize access due to concurrent update 一旦检测到可能导致串行化异常的条件,就会触发串行化失败 - - 例如,考虑一张表 mytab,其初始内容为: - + 例如,考虑表mytab,它最初包含以下内容: class | value -------+------- 1 | 10 1 | 20 2 | 100 2 | 200 - - 假设可串行化事务 A 计算: - +假设可串行化事务 A 执行以下计算: SELECT SUM(value) FROM mytab WHERE class = 1; - - 然后将结果(30)作为一条新行的 value 插入,并把 - class 设为 2。与此同时,可串行化事务 B 计算: - +然后将结果(30)作为新行的value插入,且该行满足class = 2。与此同时,可串行化事务 B 执行以下计算: SELECT SUM(value) FROM mytab WHERE class = 2; - - 并得到结果 300,再把它插入为一条新行,其 - class1。然后两个事务都尝试提交。 - 如果任一事务是在可重复读隔离级别下运行,则二者都可以提交; - 但由于不存在与该结果一致的串行执行顺序,使用可串行化事务时将允许其中一个事务提交, - 并按如下消息回滚另一个事务: - - +得到结果 300,并将它插入一个新行,该行满足class = 1。然后两个事务都尝试提交。如果任一事务运行在可重复读隔离级别,两个事务都可以提交;但由于不存在与该结果一致的串行执行顺序,使用可串行化事务时,只会允许一个事务提交,另一个则会被回滚,并收到以下消息: ERROR: could not serialize access due to read/write dependencies among transactions - - - 这是因为,如果 A 先于 B 执行,B 算出的和将是 330 而不是 300; - 反过来,另一种顺序也会使 A 算出不同的和。 - +这是因为,如果 A 在 B 之前执行,B 算出的总和应该是 330,而不是 300;同样,按另一种顺序执行,A 算出的总和也会不同。 当依赖可串行化事务来防止异常时,重要的是:从永久用户表读取的任何数据,在读取它的事务成功提交之前, - 都不应视为有效。即使对于只读事务也是如此;唯一的例外是可推迟只读事务中读取的数据, + 都不应视为有效。即使对于只读事务也是如此;唯一的例外是可延迟只读事务中读取的数据, 它一经读出就可视为有效,因为这种事务会等到能够获取一个保证不存在此类问题的快照后才开始读取数据。 在所有其他情况下,应用不能依赖后来被中止事务中读到的结果;相反,应重试事务直到成功。 - 为了保证真正的可串行化,PostgreSQL 使用了谓词锁, + 为了保证真正的可串行性,PostgreSQL 使用了谓词锁, 也就是说,系统会保留一些锁,以便判断某个写操作如果先发生,是否会影响并发事务先前读取的结果。 在 PostgreSQL 中,这些锁不会造成任何阻塞,因此会参与形成死锁。 它们用于识别并标记并发可串行化事务之间的依赖关系,而这些依赖在某些组合下可能导致串行化异常。 @@ -543,7 +519,7 @@ ERROR: could not serialize access due to read/write dependencies among transact - 持续使用可串行化事务可以简化开发。任何一组成功提交的并发可串行化事务,都保证与把它们一次一个运行的效果相同;这意味着,如果你能够证明某个事务在单独运行时会做正确的事,那么即使不了解其他事务会做什么,也可以相信它在任何可串行化事务的混合执行中也会做正确的事,否则它就不会成功提交。重要的是,采用这种技术的环境应当有一套通用机制来处理串行化失败(其 SQLSTATE 值总是 40001),因为很难准确预测究竟哪些事务会对读/写依赖关系有贡献,并因此需要被回滚来防止串行化异常。监视读/写依赖关系会带来开销,被串行化失败中止的事务重新启动也会带来开销;但在把这些开销与显式锁以及 SELECT FOR UPDATESELECT FOR SHARE 所涉及的成本和阻塞进行权衡之后,可串行化事务在某些环境中仍然是性能最佳的选择。 + 统一采用可串行化事务可以简化开发。任何一组成功提交的并发可串行化事务,都保证与把它们一次一个运行的效果相同;这意味着,如果你能够证明某个事务在单独运行时会做正确的事,那么即使不了解其他事务会做什么,也可以相信它在任何可串行化事务的混合执行中也会做正确的事,否则它就不会成功提交。重要的是,采用这种技术的环境应当有一套通用机制来处理串行化失败(其 SQLSTATE 值总是 40001),因为很难准确预测究竟哪些事务会对读/写依赖关系有贡献,并因此需要被回滚来防止串行化异常。监视读/写依赖关系会带来开销,被串行化失败中止的事务重新启动也会带来开销;但在把这些开销与显式锁以及 SELECT FOR UPDATESELECT FOR SHARE 所涉及的成本和阻塞进行权衡之后,可串行化事务在某些环境中仍然是性能最佳的选择。 @@ -587,7 +563,7 @@ ERROR: could not serialize access due to read/write dependencies among transact - 当系统因谓词锁表内存不足而被迫把多个页级谓词锁合并为单个关系级谓词锁时,串行化失败的比例可能会上升。你可以通过增加 来避免这种情况。 + 当系统因谓词锁表内存不足而被迫把多个页级谓词锁合并为单个关系级谓词锁时,串行化失败的比例可能会上升。你可以通过增加 和/或 来避免这种情况。 @@ -715,7 +691,7 @@ ERROR: could not serialize access due to read/write dependencies among transact CREATE STATISTICSCOMMENT ONREINDEX CONCURRENTLY, 以及某些 ALTER INDEX - 和 ALTER TABLE 变体会获取这种锁 + 和 ALTER TABLE 变体获取这种锁 (有关详细信息,请参阅这些命令的文档)。 @@ -980,7 +956,7 @@ ERROR: could not serialize access due to read/write dependencies among transact - 行为与 FOR SHARE 类似,不过锁更弱:SELECT FOR UPDATE 会被阻塞,但 SELECT FOR NO KEY UPDATE 不会。键共享锁会阻塞其他事务执行会修改键值的 DELETEUPDATE,但不会阻塞其他 UPDATE,也不会阻止 SELECT FOR NO KEY UPDATESELECT FOR SHARESELECT FOR KEY SHARE。 + 行为与 FOR SHARE 类似,不过锁更弱:SELECT FOR UPDATE 会被阻塞,但 SELECT FOR NO KEY UPDATE 不会。键共享锁会阻塞其他事务执行 DELETE 或任何会修改键值的 UPDATE,但不会阻塞其他 UPDATE,也不会阻止 SELECT FOR NO KEY UPDATESELECT FOR SHARESELECT FOR KEY SHARE @@ -1138,12 +1114,12 @@ UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 22222; 在某些使用咨询锁的方法中,特别是涉及显式排序和 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(id) FROM foo WHERE id = 12345; -- 可以 +SELECT pg_advisory_lock(id) FROM foo WHERE id > 12345 LIMIT 100; -- 危险! SELECT pg_advisory_lock(q.id) FROM ( SELECT id FROM foo WHERE id > 12345 LIMIT 100 -) q; -- ok +) q; -- 可以 在上面的查询中,第二种形式是危险的,因为不能保证在执行加锁函数之前先应用 LIMIT。 这可能导致获取了一些应用并未预期的锁,因此应用也不会去释放它们(直到会话结束)。 @@ -1161,12 +1137,12 @@ SELECT pg_advisory_lock(q.id) FROM 应用级别的数据一致性检查 - 在读已提交事务下,想要通过业务规则强制数据一致性非常困难,因为数据视图会随每条语句而变化, + 用读已提交事务强制执行有关数据完整性的业务规则非常困难,因为数据视图会随每条语句而变化, 而且一旦发生写冲突,即使是单条语句也未必局限于该语句自己的快照。 - 虽然可重复读事务在整个执行期间都具有稳定的数据视图,但在使用 MVCC 快照进行数据一致性检查时,还存在一个微妙问题,即所谓的读/写冲突。如果一个事务写入数据,而并发事务试图读取相同的数据(无论是在写入之前还是之后),它都看不到另一个事务的工作。于是,读取者看起来就像是先执行的一方,而不管究竟是谁先启动,也不管谁先提交。如果事情只停留在这一步,就没有问题;但如果读取者还写入了数据,而这些数据又被另一个并发事务读取,那么现在就会有一个事务看起来像是在前面提到的任一事务之前执行。如果看起来最后执行的事务实际上最先提交,就很容易在事务执行顺序图中形成一个环。一旦出现这样的环,不借助额外机制,一致性检查就无法正确工作。 + 虽然可重复读事务在整个执行期间都具有稳定的数据视图,但在使用 MVCC 快照进行数据一致性检查时,还存在一个微妙问题,即所谓的读/写冲突。如果一个事务写入数据,而并发事务试图读取相同的数据(无论是在写入之前还是之后),它都看不到另一个事务的工作。于是,读取者看起来就像是先执行的一方,而不管究竟是谁先启动,也不管谁先提交。如果事情只停留在这一步,就没有问题;但如果读取者还写入了数据,而这些数据又被另一个并发事务读取,那么现在就会有一个事务看起来像是在前面提到的任一事务之前执行。如果看起来最后执行的事务实际上最先提交,就很容易在事务执行顺序图中形成一个环。一旦出现这样的环,不借助额外机制,完整性检查就无法正确工作。 @@ -1183,7 +1159,7 @@ SELECT pg_advisory_lock(q.id) FROM - 使用这种技术时,如果应用软件通过某个框架运行,并由该框架自动重试因串行化错误而回滚的事务,就可以避免给应用程序员带来不必要的负担。把 default_transaction_isolation 设置为 serializable 可能是个好主意。通过在触发器中检查事务隔离级别来采取某些措施,以确保不会因为疏忽或为了绕过完整性检查而使用其他事务隔离级别,也是明智的。 + 使用这种技术时,如果应用软件通过某个框架运行,并由该框架自动重试因串行化失败而回滚的事务,就可以避免给应用程序员带来不必要的负担。把 default_transaction_isolation 设置为 serializable 可能是个好主意。通过在触发器中检查事务隔离级别来采取某些措施,以确保不会因为疏忽或为了绕过完整性检查而使用其他事务隔离级别,也是明智的。 @@ -1199,7 +1175,7 @@ SELECT pg_advisory_lock(q.id) FROM - 使用显式锁定强制一致性 + 使用显式阻塞锁强制一致性 当存在非可串行化写入时,要确保某一行当前仍然有效,并保护它不受并发更新影响, @@ -1222,7 +1198,7 @@ SELECT pg_advisory_lock(q.id) FROM 在非可串行化的 MVCC 环境下,全局有效性检查需要额外考虑。 - 例如,一个银行应用可能希望检查一个表中的所有收入总和等于另一个表中的所有支出总和, + 例如,一个银行应用可能希望检查一个表中的贷方金额总和等于另一个表中的借方金额总和, 而这两个表都在被活跃更新。在读已提交模式下,比较两个连续的 SELECT sum(...) 命令的结果并不可靠,因为第二个查询很可能会包含第一个查询没有统计到的事务提交结果。 在单个可重复读事务中完成这两次求和,只能准确反映在该可重复读事务开始之前已提交事务的效果 @@ -1290,7 +1266,7 @@ SELECT pg_advisory_lock(q.id) FROM 重试事务并不保证重试后的事务一定能够完成;可能需要多次重试。 在争用非常激烈的情况下,完成一个事务可能需要尝试很多次。 - 如果涉及相互冲突的已准备事务,那么在已准备事务提交或回滚之前,可能根本无法取得进展。 + 如果涉及相互冲突的预备事务,那么在预备事务提交或回滚之前,可能根本无法取得进展。 @@ -1332,7 +1308,7 @@ SELECT pg_advisory_lock(q.id) FROM - 读写访问使用短期的页级共享/排他锁。每个索引行在被取出或插入之后,锁都会立即释放。这些索引类型在不存在死锁条件的前提下提供了最高的并发性。 + 读写访问使用短期的页级共享/排他锁。每个索引行在被取出或插入之后,锁都会立即释放。这些索引类型提供最高的并发性,并且不会产生死锁。 @@ -1354,7 +1330,7 @@ SELECT pg_advisory_lock(q.id) FROM - 读写访问使用短期的页级共享/排他锁。每个索引行在被取出或插入之后,锁都会立即释放。但要注意,插入一个 GIN 索引值通常会导致每行产生多个索引键插入,因此 GIN 可能为了插入单个值而做大量工作。 + 读写访问使用短期的页级共享/排他锁。每个索引行在被取出或插入之后,锁都会立即释放。但要注意,插入一个使用 GIN 索引的值通常会导致每行产生多个索引键插入,因此 GIN 可能为了插入单个值而做大量工作。 diff --git a/zh/15/nls.sgml b/zh/15/nls.sgml index 42f4fd1f..09678cb2 100644 --- a/zh/15/nls.sgml +++ b/zh/15/nls.sgml @@ -299,9 +299,7 @@ fprintf(stderr, gettext("panic level %d\n"), lvl); AVAIL_LANGUAGES - - 已提供翻译的列表 — 起初为空。 - + 已提供的翻译列表 — 最初为空。 diff --git a/zh/15/oid2name.sgml b/zh/15/oid2name.sgml index 4b80f64a..40bb461a 100644 --- a/zh/15/oid2name.sgml +++ b/zh/15/oid2name.sgml @@ -8,7 +8,7 @@ oid2name 1 - Application + 应用程序 diff --git a/zh/15/pageinspect.sgml b/zh/15/pageinspect.sgml index 0e9e3ea4..fdee989f 100644 --- a/zh/15/pageinspect.sgml +++ b/zh/15/pageinspect.sgml @@ -370,19 +370,19 @@ test=# SELECT itemoffset, ctid, itemlen, nulls, vars, data, dead, htid, tids[0:2 13 | (16,8292) | 616 | f | f | 2f 00 00 00 00 00 00 00 | f | (4,17) | {"(4,17)","(4,21)"} (13 rows) - 这是一个 B-树叶页。所有指向表的元组恰好都是 posting list 元组(它们总共存储了 100 个 6 字节的 TID)。此外,在itemoffset 编号 1 处还有一个high key元组。这个示例中,ctid用于存储每个元组的编码信息,不过叶页元组通常会直接在ctid字段中存储一个堆 TID。tids是作为 posting list 存储的 TID 列表。 + 这是一个 B-树叶页。所有指向表的元组恰好都是倒排列表元组(每个都存储了 100 个 6 字节的 TID)。此外,在itemoffset 编号 1 处还有一个高键元组。这个示例中,ctid用于存储每个元组的编码信息,不过叶页元组通常会直接在ctid字段中存储一个堆 TID。tids是作为倒排列表存储的 TID 列表。 在内部页(此处未显示)中,ctid的块号部分是一个downlink(下行链接),也就是该索引中另一页的块号。ctid的偏移部分(第二个数字)存储着关于该元组的编码信息,例如实际存在的列数(后缀截断可能移除了不需要的后缀列)。被截断的列被视为具有负无穷值。 - htid显示该元组的堆 TID,而不考虑底层元组表示形式。这个值可能与ctid相同,也可能是从 posting list 元组以及内部页元组所使用的替代表示中解码出来的。内部页中的元组通常会把实现层面的堆 TID 列截断掉,这会表现为htid值为 NULL。 + htid显示该元组的堆 TID,而不考虑底层元组表示形式。这个值可能与ctid相同,也可能是从倒排列表元组以及内部页元组所使用的替代表示中解码出来的。内部页中的元组通常会把实现层面的堆 TID 列截断掉,这会表现为htid值为 NULL。 - 请注意,任何非最右页(即btpo_next字段值非零的页面)的第一项都是该页的high key,这意味着它的data充当该页上所有项的上界,而它的ctid字段并不指向另一个块。另外,在内部页上,第一个真正的数据项(第一个不是high key的项)一定会把所有列都截断掉,因此其data字段中没有实际值。不过,这样的项在其ctid字段中确实有一个有效的下行链接。 + 请注意,任何非最右页(即btpo_next字段值非零的页面)的第一项都是该页的高键,这意味着它的data充当该页上所有项的上界,而它的ctid字段并不指向另一个块。另外,在内部页上,第一个真正的数据项(第一个不是高键的项)一定会把所有列都截断掉,因此其data字段中没有实际值。不过,这样的项在其ctid字段中确实有一个有效的下行链接。 - 关于 B-树索引结构的更多细节,参见。关于去重和 posting list 的更多细节,参见。关于去重和倒排列表的更多细节,参见 diff --git a/zh/15/parallel.sgml b/zh/15/parallel.sgml index b77a88aa..e3832749 100644 --- a/zh/15/parallel.sgml +++ b/zh/15/parallel.sgml @@ -286,9 +286,11 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%'; - - 引用相关 SubPlan 的计划节点。 - + 附带 InitPlan 的计划节点。 + + + + 引用相关 SubPlan 的计划节点。 @@ -300,7 +302,7 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%'; - 如果函数或聚合会写数据库、修改事务状态(而不是通过子事务进行错误恢复)、访问序列,或者对设置做持久更改,那么它们必须标记为 PARALLEL UNSAFE。类似地,如果函数访问临时表、客户端连接状态、游标、预备语句,或者系统无法在工作进程之间同步的各种后端本地状态,那么它必须标记为 PARALLEL RESTRICTED。例如,setseedrandom 就因为最后一个原因而属于并行受限。 + 如果函数或聚合会写入数据库、访问序列、修改事务状态(即使只是临时修改,例如 PL/pgSQL 函数建立 EXCEPTION 块来捕获错误),或者对设置作出持久更改,那么它们必须标记为 PARALLEL UNSAFE。类似地,如果函数访问临时表、客户端连接状态、游标、预备语句,或者系统无法在工作进程之间同步的各种后端本地状态,那么它必须标记为 PARALLEL RESTRICTED。例如,setseedrandom 就因为最后一个原因而属于并行受限。 diff --git a/zh/15/pgcrypto.sgml b/zh/15/pgcrypto.sgml index 035f67b0..3eb60cf1 100644 --- a/zh/15/pgcrypto.sgml +++ b/zh/15/pgcrypto.sgml @@ -179,29 +179,6 @@ hmac(data bytea, key bytea, type text) returns bytea 13 原始 UNIX crypt - - sha256crypt - 无限制 - - 最多 32 - 80 - 改编自公开可用的参考实现 - 使用 SHA-256 和 SHA-512 的 Unix crypt - - - - - sha512crypt - 无限制 - - 最多 32 - 123 - 改编自公开可用的参考实现 - 使用 SHA-256 和 SHA-512 的 Unix crypt - - - -
@@ -254,17 +231,14 @@ gen_salt(type text [, iter_count integer ]) returns text - type参数指定哈希算法。 - 接受的类型有:desxdesmd5、 - bfsha256cryptsha512crypt。 - 最后两种即 sha256cryptsha512crypt, - 是现代的、基于 SHA-2 的密码哈希。 + type参数指定 hash 算法。 + 接受的类型有:desxdesmd5bf iter_count参数允许用户为支持该参数的算法指定迭代次数。 - 次数越高,密码哈希所需时间越长,从而破解它所需时间也越长。 - 不过,如果次数过高,计算一个哈希可能需要数年时间 — 这显然不切实际。 + 次数越高,对密码进行 hash 所需的时间越长,从而破解它所需时间也越长。 + 不过,如果次数过高,计算一个 hash 可能需要数年时间 — 这显然不切实际。 若省略iter_count参数,则使用默认迭代次数。 允许的iter_count值取决于算法,如所示。 @@ -293,12 +267,6 @@ gen_salt(type text [, iter_count integer ]) returns text 4 31 - - sha256crypt, sha512crypt - 5000 - 1000 - 999999999 - @@ -308,34 +276,27 @@ gen_salt(type text [, iter_count integer ]) returns text - 为了选择合适的迭代次数,可以考虑原始 DES crypt 在当时硬件上的设计速度是每秒 4 次哈希。 - 低于每秒 4 次哈希可能会影响可用性,而高于每秒 100 次哈希则很可能过快。 + 为了选择合适的迭代次数,可以考虑原始 DES crypt 在当时硬件上的设计速度是每秒 4 次 hash。 + 低于每秒 4 次 hash 可能会影响可用性,而高于每秒 100 次 hash 则很可能过快。 - 概述了不同哈希算法之间的相对速度差异。 + 概述了不同 hash 算法之间的相对速度差异。 该表展示了在 8 字符密码上尝试所有字符组合所需的时间,假定密码只包含小写字母, 或者包含大小写字母和数字。在crypt-bf条目中, 斜杠后的数字是gen_saltiter_count参数值。 - - 对sha256cryptsha512crypt而言, - 默认的iter_count5000 对现代硬件来说被认为过低, - 但可以调高以生成更强的密码哈希。除此之外, - sha256cryptsha512crypt都被认为是安全的。 - - - 哈希算法速度 + Hash 算法速度 算法 - 每秒哈希次数 + 每秒 hash 次数 针对[a-z] 针对[A-Za-z0-9] - 相对于md5 哈希的耗时倍数 + 相对于md5 hash的耗时倍数 @@ -417,7 +378,7 @@ gen_salt(type text [, iter_count integer ]) returns text - md5 哈希的数字来自 mdcrack 1.2。 + md5 hash的数字来自 mdcrack 1.2。 diff --git a/zh/15/pgwalinspect.sgml b/zh/15/pgwalinspect.sgml index 5fade953..967ac64d 100644 --- a/zh/15/pgwalinspect.sgml +++ b/zh/15/pgwalinspect.sgml @@ -1,7 +1,7 @@ - pg_walinspect — WAL 的底层检查 + pg_walinspect pg_walinspect @@ -19,28 +19,15 @@ 该模块的所有函数都基于服务器当前时间线 ID 提供 WAL 信息。 + + 本模块的所有函数都会尝试查找位于给定in_lsnstart_lsn处或其后的第一条有效 WAL 记录;若找不到这样的记录,则会报错。同样,end_lsn也必须可用;如果它位于一条记录的中间,则整条记录都必须可用。 + + - pg_walinspect函数通常使用一个 LSN 参数, - 用来指定某条已知且感兴趣的 WAL 记录起始位置。 - 不过,某些函数(例如 - pg_logical_emit_message) - 返回的是刚插入那条记录之后的 LSN。 - + 某些函数(例如pg_logical_emit_message)返回刚插入的记录之后的 LSN。因此,如果将该 LSN 作为in_lsnstart_lsn传给这些函数之一,返回的将是下一条记录。 + - - - 所有显示某个 LSN 范围内记录信息的 - pg_walinspect函数, - 也接受大于服务器当前 LSN 的end_lsn参数。 - 使用一个来自未来end_lsn不会引发错误。 - - - 便捷做法是将FFFFFFFF/FFFFFFFF - (最大合法pg_lsn值)作为end_lsn参数。 - 这等价于传入与服务器当前 LSN 相同的end_lsn。 - - 默认情况下,这些函数仅允许超级用户和 pg_read_server_files角色成员使用。 @@ -58,28 +45,23 @@ - 获取位于in_lsn处或其后的某条 WAL 记录的信息。 - 例如: + 获取给定 LSN 处的 WAL 记录信息。如果给定 LSN 不在 WAL 记录的起始位置,则返回下一条可用的有效 WAL 记录的信息;若找不到这样的记录,则会报错。例如,该函数的用法如下: -postgres=# SELECT * FROM pg_get_wal_record_info('0/E419E28'); --[ RECORD 1 ]----+------------------------------------------------- -start_lsn | 0/E419E28 -end_lsn | 0/E419E68 -prev_lsn | 0/E419D78 +postgres=# SELECT * FROM pg_get_wal_record_info('0/1E826E98'); +-[ RECORD 1 ]----+---------------------------------------------------- +start_lsn | 0/1E826F20 +end_lsn | 0/1E826F60 +prev_lsn | 0/1E826C80 xid | 0 resource_manager | Heap2 -record_type | VACUUM +record_type | PRUNE record_length | 58 -main_data_length | 2 +main_data_length | 8 fpi_length | 0 -description | nunused: 5, unused: [1, 2, 3, 4, 5] -block_ref | blkref #0: rel 1663/16385/1249 fork main blk 364 +description | snapshotConflictHorizon 33748 nredirected 0 ndead 2 +block_ref | blkref #0: rel 1663/5/60221 fork main blk 2 - - - 如果in_lsn不是某条 WAL 记录的起始位置, - 则改为显示下一条有效 WAL 记录的信息。 - 若不存在下一条有效 WAL 记录,则函数报错。 + @@ -94,9 +76,7 @@ block_ref | blkref #0: rel 1663/16385/1249 fork main blk 364 - 获取start_lsnend_lsn - 之间所有有效 WAL 记录的信息。 - 每条 WAL 记录返回一行。例如: + 获取start_lsnend_lsn之间所有有效 WAL 记录的信息。每条 WAL 记录返回一行。如果start_lsnend_lsn尚不可用,则函数会报错。例如: postgres=# SELECT * FROM pg_get_wal_records_info('0/1E913618', '0/1E913740') LIMIT 1; -[ RECORD 1 ]----+-------------------------------------------------------------- @@ -112,98 +92,22 @@ fpi_length | 0 description | nextXid 33775 latestCompletedXid 33774 oldestRunningXid 33775 block_ref | - - - 若start_lsn不可用,函数会报错。 + - + - pg_get_wal_block_info(start_lsn pg_lsn, end_lsn pg_lsn, show_data boolean DEFAULT true) returns setof record + + pg_get_wal_records_info_till_end_of_wal(start_lsn pg_lsn) + returns setof record + - 获取start_lsnend_lsn - 范围内所有有效 WAL 记录中每个块引用的信息,仅返回包含一个或多个块引用的记录。 - 每条 WAL 记录中的每个块引用返回一行。 - 例如: - -postgres=# SELECT * FROM pg_get_wal_block_info('0/1230278', '0/12302B8'); --[ RECORD 1 ]-----+----------------------------------- -start_lsn | 0/1230278 -end_lsn | 0/12302B8 -prev_lsn | 0/122FD40 -block_id | 0 -reltablespace | 1663 -reldatabase | 1 -relfilenode | 2658 -relforknumber | 0 -relblocknumber | 11 -xid | 341 -resource_manager | Btree -record_type | INSERT_LEAF -record_length | 64 -main_data_length | 2 -block_data_length | 16 -block_fpi_length | 0 -block_fpi_info | -description | off: 46 -block_data | \x00002a00070010402630000070696400 -block_fpi_data | - - - - 上例中的 WAL 记录只包含一个块引用, - 但许多 WAL 记录会包含多个块引用。 - pg_get_wal_block_info输出的每一行, - 其start_lsnblock_id - 值的组合都保证唯一。 - - - 这里展示的大部分信息与使用相同参数时 - pg_get_wal_records_info的输出一致。 - 不过,pg_get_wal_block_info会把每条 WAL 记录中的信息拆解为展开形式: - 对每个块引用输出一行,因此某些细节是在块引用级别而不是整条记录级别进行跟踪。 - 这种结构适合配合跟踪单个块随时间变化的查询使用。 - 需要注意,不含块引用的记录(如COMMIT WAL 记录) - 不会返回任何行,因此pg_get_wal_block_info - 实际返回的行数可能少于 - pg_get_wal_records_info。 - - - reltablespace、 - reldatabase和 - relfilenode字段分别引用 - pg_tablespace.oid、 - pg_database.oid - 以及 - pg_class.relfilenode。 - relforknumber字段表示该块引用在关系中的分支编号; - 详见common/relpath.h。 - - - - pg_filenode_relation函数(见 - ) - 可帮助确定在最初执行时被修改的是哪个关系。 - - - - 客户端可以避免物化块数据所带来的开销, - 这可能使函数执行显著加快。 - 当show_datafalse时, - 会省略block_data和 - block_fpi_data值 - (也就是说,返回的所有行中block_data和 - block_fpi_data这两个OUT - 参数均为NULL)。 - 显然,这项优化只适用于查询确实不需要块数据的场景。 - - - 若start_lsn不可用,函数会报错。 + 此函数与pg_get_wal_records_info()相同,但获取的是从start_lsn到 WAL 末尾之间所有有效 WAL 记录的信息。 @@ -218,12 +122,7 @@ block_fpi_data | - 获取start_lsn与 - end_lsn之间所有有效 WAL 记录的统计信息。 - 默认按每种resource_manager类型返回一行。 - 当per_record设为true时, - 则按每种record_type返回一行。 - 例如: + 获取start_lsnend_lsn之间所有有效 WAL 记录的统计信息。默认按每种resource_manager类型返回一行。当per_record设为true时,则按每种record_type返回一行。如果start_lsnend_lsn尚不可用,则函数会报错。例如: postgres=# SELECT * FROM pg_get_wal_stats('0/1E847D00', '0/1E84F500') WHERE count > 0 AND @@ -240,9 +139,22 @@ fpi_size_percentage | 0 combined_size | 875 combined_size_percentage | 2.8634072910530795 + + + + + + + + pg_get_wal_stats_till_end_of_wal(start_lsn pg_lsn, per_record boolean DEFAULT false) + returns setof record + + + + - 若start_lsn不可用,函数会报错。 + 此函数与pg_get_wal_stats()相同,但获取的是从start_lsn到 WAL 末尾之间所有有效 WAL 记录的统计信息。 diff --git a/zh/15/plhandler.sgml b/zh/15/plhandler.sgml index 38562e46..4048d572 100644 --- a/zh/15/plhandler.sgml +++ b/zh/15/plhandler.sgml @@ -17,11 +17,11 @@ - 调用处理器与其他函数一样被调用:它会接收一个指向 FunctionCallInfoBaseData struct 的指针,其中包含参数值以及被调用函数的相关信息;同时它还应返回一个 Datum 结果(如果希望返回 SQL 空值结果,还可以设置 isnull 字段,也就是 FunctionCallInfoBaseData 结构体中的该字段)。调用处理器与普通被调函数之间的区别在于,flinfo->fn_oid 字段在 FunctionCallInfoBaseData 结构体中保存的是实际要调用函数的 OID,而不是调用处理器本身的 OID。调用处理器必须使用这个字段来判定要执行哪个函数。另外,传入的参数列表是按照目标函数而不是调用处理器的声明来设置的。 + 调用处理器与其他函数一样被调用:它会接收一个指向 FunctionCallInfoBaseData struct 的指针,其中包含参数值以及被调用函数的相关信息;同时它还应返回一个 Datum 结果(如果希望返回 SQL 空值结果,还需要设置 isnull 字段,也就是 FunctionCallInfoBaseData 结构体中的该字段)。调用处理器与普通被调函数之间的区别在于,flinfo->fn_oid 字段在 FunctionCallInfoBaseData 结构体中保存的是实际要调用函数的 OID,而不是调用处理器本身的 OID。调用处理器必须使用这个字段来判定要执行哪个函数。另外,传入的参数列表是按照目标函数而不是调用处理器的声明来设置的。 - 调用处理器必须从系统目录 pg_proc 中取出该函数的条目,并分析被调用函数的参数类型和返回类型。该函数的 AS 子句可在其 CREATE FUNCTION 命令对应的 prosrc 列里找到,也就是 pg_proc 行中的该列。这里通常是一段过程语言源文本,但理论上也可以是其他内容,例如某个文件的路径名,或者任何能详细告诉调用处理器该做什么的信息。 + 调用处理器必须从系统目录 pg_proc 中取出该函数的条目,并分析被调用函数的参数类型和返回类型。该函数的 CREATE FUNCTION 命令中的 AS 子句内容,保存在 pg_proc 对应行的 prosrc 列中。这里通常是一段过程语言源文本,但理论上也可以是其他内容,例如某个文件的路径名,或者任何能详细告诉调用处理器该做什么的信息。 @@ -46,7 +46,7 @@ 验证器函数通常应遵循 参数:如果它被关闭,就应跳过任何开销高昂或依赖上下文的检查。如果该语言允许在编译时执行代码,验证器还必须抑制会诱发此类执行的检查。特别是,pg_dump 会关闭这个参数,这样它就可以装载过程语言函数,而不必担心函数体对其他数据库对象的副作用或依赖关系。(正因为有这一要求,调用处理器不应假设验证器已经完整检查了函数。提供验证器的目的,并不是让调用处理器省略检查,而是在 CREATE FUNCTION 命令中存在明显错误时立即通知用户。)虽然究竟检查哪些内容主要由验证器函数自行决定,但要注意,核心 CREATE FUNCTION 代码只会执行附加到函数上的 SET 子句,前提是 check_function_bodies 打开。因此,当 check_function_bodies 关闭时,那些结果可能受 GUC 参数影响的检查肯定都应跳过,以避免在恢复转储时出现虚假的失败。 + linkend="guc-check-function-bodies"/> 参数:如果它被关闭,就应跳过任何开销高昂或依赖上下文的检查。如果该语言允许在编译时执行代码,验证器还必须抑制会诱发此类执行的检查。特别是,pg_dump 会关闭这个参数,这样它就可以装载过程语言函数,而不必担心副作用或函数体对其他数据库对象的依赖关系。(正因为有这一要求,调用处理器不应假设验证器已经完整检查了函数。提供验证器的目的,并不是让调用处理器省略检查,而是在 CREATE FUNCTION 命令中存在明显错误时立即通知用户。)虽然究竟检查哪些内容主要由验证器函数自行决定,但要注意,只有在 check_function_bodies 打开时,核心 CREATE FUNCTION 代码才会执行函数附带的 SET 子句。因此,当 check_function_bodies 关闭时,那些结果可能受 GUC 参数影响的检查肯定都应跳过,以避免在恢复转储时出现虚假的失败。 diff --git a/zh/15/plperl.sgml b/zh/15/plperl.sgml index 7fc5b272..a7da7851 100644 --- a/zh/15/plperl.sgml +++ b/zh/15/plperl.sgml @@ -13,7 +13,7 @@ - PL/Perl 是一种可载入的过程语言,它允许使用 + PL/Perl 是一种可加载的过程语言,它允许使用 Perl 编程语言编写 PostgreSQL 函数和过程。 @@ -32,8 +32,7 @@ - 如果把该语言安装到 template1 中,之后创建的所有 - 数据库都会自动安装该语言。 + 如果把某种语言安装到template1中,之后创建的所有数据库都会自动安装该语言。 @@ -57,9 +56,9 @@ CREATE FUNCTION funcname (argument-types) RETURNS return-type --- function attributes can go here +-- 函数属性可以写在这里 AS $$ - # PL/Perl function body goes here + # PL/Perl 函数体写在这里 $$ LANGUAGE plperl; @@ -78,7 +77,7 @@ $$ LANGUAGE plperl; DO $$ - # PL/Perl code + # PL/Perl 代码 $$ LANGUAGE plperl; @@ -136,15 +135,14 @@ $$ LANGUAGE plperl; 如果一个 SQL 空值空值in PL/Perl被传给一个函数,在 - Perl 中该参数值将呈现为undefined。上述函数定义对于 - 空输入的行为并不理想(实际上,它会把它们当作零)。我们可以在函数 + sortas="PL/Perl">在 PL/Perl 中被传给一个函数,在 + Perl 中该参数值将呈现为未定义。上述函数定义对于 + 空值输入的行为并不理想(实际上,它会把它们当作零)。我们可以在函数 定义中添加 STRICT,让 PostgreSQL 采取更合理的做法:如果传入空值, - 函数将根本不会被调用,而是自动返回空结果。另一种方式是在函数体中 + 函数将根本不会被调用,而是自动返回空值结果。另一种方式是在函数体中 检查未定义输入。例如,假设我们希望在 - perl_max 的两个参数中一个为空、另一个非空时, - 返回非空参数而不是空值: + perl_max 的两个参数中一个为空值、另一个非空值时,返回非空值参数而不是空值: CREATE FUNCTION perl_max (integer, integer) RETURNS integer AS $$ @@ -186,7 +184,7 @@ $$ LANGUAGE plperl; bool_plperl 扩展提供了合适的转换。要使用它, 请先安装该扩展: -CREATE EXTENSION bool_plperl; -- or bool_plperlu for PL/PerlU +CREATE EXTENSION bool_plperl; -- 对于 PL/PerlU,则使用 bool_plperlu 然后对接收或返回 bool 的 PL/Perl 函数使用 TRANSFORM 函数属性,例如: @@ -199,7 +197,7 @@ AS $$ $$ LANGUAGE plperl; 应用该转换后,Perl 会将 bool 参数视为 - 1 或空值,从而能正确表示真或假。如果函数结果类型为 + 1 或空字符串,从而能正确表示真或假。如果函数结果类型为 bool,则其真或假取决于 Perl 是否会将返回值求值为真。 对函数内部执行的 SPI 查询,其布尔查询参数和结果也会进行类似的转换 ()。 @@ -232,12 +230,12 @@ CREATE OR REPLACE FUNCTION concat_array_elements(text[]) RETURNS TEXT AS $$ my $result = ""; return undef if (!defined $arg); - # as an array reference + # 作为数组引用 for (@$arg) { $result .= $_; } - # also works as a string + # 也可以作为字符串使用 $result .= $arg; return $result; @@ -248,7 +246,8 @@ SELECT concat_array_elements(ARRAY['PL','/','Perl']); - 多维数组会以所有 Perl 程序员都熟悉的方式,表示为对低维数组引用的引用。 + 多维数组按 Perl 程序员熟悉的方式表示为指向较低维数组的引用, + 而这些数组的元素又是引用。 @@ -357,11 +356,11 @@ SELECT * FROM perl_set(); 如果希望在代码中使用 strict 编译指示,可以有几种 选择。对于临时的全局用法,可以 SET - plperl.use_strict 为 true。这会影响后续编译的 + plperl.use_strict 为真。这会影响后续编译的 PL/Perl 函数,但不会影响当前会话中已经编译的 函数。对于永久的全局用法,可以在 postgresql.conf 文件中将 - plperl.use_strict 设为 true。 + plperl.use_strict 设为真。 @@ -417,7 +416,7 @@ use strict; spi_exec_query(query [, limit]) spi_exec_query - in PL/Perl + 在 PL/Perl 中 @@ -503,7 +502,7 @@ SELECT * FROM test_munge(); spi_query(command) spi_query - in PL/Perl + 在 PL/Perl 中 @@ -511,7 +510,7 @@ SELECT * FROM test_munge(); spi_fetchrow(cursor) spi_fetchrow - in PL/Perl + 在 PL/Perl 中 @@ -519,7 +518,7 @@ SELECT * FROM test_munge(); spi_cursor_close(cursor) spi_cursor_close - in PL/Perl + 在 PL/Perl 中 @@ -539,7 +538,7 @@ CREATE OR REPLACE FUNCTION lotsa_md5 (INTEGER) RETURNS SETOF foo_type AS $$ my $file = '/usr/share/dict/words'; my $t = localtime; elog(NOTICE, "opening file $file at $t" ); - open my $fh, '<', $file # ooh, it's a file access! + open my $fh, '<', $file # 注意,这里访问了文件! or elog(ERROR, "cannot open $file for reading: $!"); my @words = <$fh>; close $fh; @@ -579,7 +578,7 @@ SELECT * from lotsa_md5(500); spi_prepare(command, argument types) spi_prepare - in PL/Perl + 在 PL/Perl 中 @@ -587,7 +586,7 @@ SELECT * from lotsa_md5(500); spi_query_prepared(plan, arguments) spi_query_prepared - in PL/Perl + 在 PL/Perl 中 @@ -595,7 +594,7 @@ SELECT * from lotsa_md5(500); spi_exec_prepared(plan [, attributes], arguments) spi_exec_prepared - in PL/Perl + 在 PL/Perl 中 @@ -603,7 +602,7 @@ SELECT * from lotsa_md5(500); spi_freeplan(plan) spi_freeplan - in PL/Perl + 在 PL/Perl 中 @@ -612,7 +611,7 @@ SELECT * from lotsa_md5(500); spi_preparespi_query_preparedspi_exec_preparedspi_freeplan - 提供相同的功能,但用于预处理查询。spi_prepare + 提供相同的功能,但用于预备查询。spi_prepare 接受一个带编号参数占位符($1、$2 等)的查询字符串,以及参数类型的 字符串列表: @@ -631,7 +630,7 @@ $plan = spi_prepare('SELECT * FROM test WHERE id > $1 AND name = $2', - 预处理查询的优点在于,一个准备好的计划可以用于多次查询执行。当计划 + 预备查询的优点在于,一个准备好的计划可以用于多次查询执行。当计划 不再需要时,可以用 spi_freeplan 将其释放: CREATE OR REPLACE FUNCTION init() RETURNS VOID AS $$ @@ -708,7 +707,7 @@ SELECT release_hosts_query(); spi_commit() spi_commit - in PL/Perl + 在 PL/Perl 中 @@ -716,7 +715,7 @@ SELECT release_hosts_query(); spi_rollback() spi_rollback - in PL/Perl + 在 PL/Perl 中 @@ -756,7 +755,7 @@ CALL transaction_test1(); - PL/Perl 中的工具函数 + PL/Perl 中的辅助函数 @@ -765,7 +764,7 @@ CALL transaction_test1(); elog(level, msg) elog - in PL/Perl + 在 PL/Perl 中 @@ -791,7 +790,7 @@ CALL transaction_test1(); quote_literal(string) quote_literal - in PL/Perl + 在 PL/Perl 中 @@ -812,7 +811,7 @@ CALL transaction_test1(); quote_nullable(string) quote_nullable - in PL/Perl + 在 PL/Perl 中 @@ -831,7 +830,7 @@ CALL transaction_test1(); quote_ident(string) quote_ident - in PL/Perl + 在 PL/Perl 中 @@ -850,7 +849,7 @@ CALL transaction_test1(); decode_bytea(string) decode_bytea - in PL/Perl + 在 PL/Perl 中 @@ -868,7 +867,7 @@ CALL transaction_test1(); encode_bytea(string) encode_bytea - in PL/Perl + 在 PL/Perl 中 @@ -885,7 +884,7 @@ CALL transaction_test1(); encode_array_literal(array) encode_array_literal - in PL/Perl + 在 PL/Perl 中 @@ -908,7 +907,7 @@ CALL transaction_test1(); encode_typed_literal(value, typename) encode_typed_literal - in PL/Perl + 在 PL/Perl 中 @@ -926,7 +925,7 @@ CALL transaction_test1(); encode_array_constructor(array) encode_array_constructor - in PL/Perl + 在 PL/Perl 中 @@ -947,7 +946,7 @@ CALL transaction_test1(); looks_like_number(string) looks_like_number - in PL/Perl + 在 PL/Perl 中 @@ -967,7 +966,7 @@ CALL transaction_test1(); is_array_ref(argument) is_array_ref - in PL/Perl + 在 PL/Perl 中 @@ -1025,9 +1024,9 @@ CREATE OR REPLACE FUNCTION myfuncs() RETURNS void AS $$ }; $$ LANGUAGE plperl; -SELECT myfuncs(); /* initializes the function */ +SELECT myfuncs(); /* 初始化函数 */ -/* Set up a function that uses the quote function */ +/* 创建一个使用加引号函数的函数 */ CREATE OR REPLACE FUNCTION use_quote(TEXT) RETURNS text AS $$ my $text_to_quote = shift; @@ -1042,11 +1041,9 @@ $$ LANGUAGE plperl; - 出于安全原因,PL/Perl 会为某个 SQL 角色调用的函数在该角色专用的独立 - Perl 解释器中执行。这可以防止一个用户意外或恶意地干扰另一个用户的 + 出于安全原因,PL/Perl 会在每个 SQL 角色各自独立的 Perl 解释器中执行该角色调用的函数。这可以防止一个用户意外或恶意地干扰另一个用户的 PL/Perl 函数行为。每个这样的解释器都有自己的 - %_SHARED 变量值和其他全局状态。因此,只有在两个 - PL/Perl 函数都由同一 SQL 角色执行时,它们才会共享 + %_SHARED 变量值和其他全局状态。因此,当且仅当两个 PL/Perl 函数都由同一 SQL 角色执行时,它们才会共享 %_SHARED 的值。在某些应用中,一个会话可能会在多个 SQL 角色下执行代码(通过 SECURITY DEFINER 函数、 使用 SET ROLE 等),这时可能需要显式采取措施, @@ -1059,29 +1056,29 @@ $$ LANGUAGE plperl; - 可信与不可信的 PL/Perl + 受信任与不受信任的 PL/Perl - trusted + 受信任的 PL/Perl 通常,PL/Perl 会被安装为一种名为 plperl 的 - 可信编程语言。在这种设置下,为了保持安全性,某些 Perl + 受信任的编程语言。在这种设置下,为了保持安全性,某些 Perl 操作会被禁用。一般来说,受限制的是那些与环境交互的操作,包括文件句柄 操作、requireuse (针对外部模块)。它无法像 C 函数那样访问数据库服务器进程的内部, - 也无法以服务器进程的权限获取操作系统级访问。因此,可以允许任何无权限 + 也无法以服务器进程的权限获取操作系统级访问。因此,可以允许任何无特权 的数据库用户使用这种语言。 - 可信 PL/Perl 依赖 Perl 的 Opcode 模块来维持安全性。 + 受信任的 PL/Perl 依赖 Perl 的 Opcode 模块来维持安全性。 Perl 的 文档 - 指出,该模块对于可信 PL/Perl 这一使用场景并不有效。若你的安全需求 + 指出,该模块对于受信任的 PL/Perl 这一使用场景并不有效。若你的安全需求 不能接受该警告中的不确定性,请考虑执行 REVOKE USAGE ON LANGUAGE plperl FROM PUBLIC @@ -1105,16 +1102,16 @@ $$ LANGUAGE plperl; 有时需要编写不受这些限制的 Perl 函数。例如,可能需要一个能发送邮件的 Perl 函数。为处理这类情况,也可以把 PL/Perl 安装成一种 - 不可信语言(通常称为 + 不受信任的语言(通常称为 PL/PerlUPL/PerlU)。 在这种情况下,完整的 Perl 语言都可用。安装该语言时,使用语言名 - plperlu 就会选择不可信的 PL/Perl 变体。 + plperlu 就会选择不受信任的 PL/Perl 变体。 PL/PerlU 函数的编写者必须注意,函数不能被 用于任何非预期用途,因为它能够执行以数据库管理员身份登录的用户所能 - 做的任何事情。请注意,数据库系统只允许数据库超级用户用不可信语言创建 + 做的任何事情。请注意,数据库系统只允许数据库超级用户用不受信任的语言创建 函数。 @@ -1249,7 +1246,7 @@ $$ LANGUAGE plperl; $_TD->{relname} - 触发该触发器的表名。该字段已废弃,并且可能会在未来版本中移除。 + 触发该触发器的表名。该字段已弃用,并且可能会在未来版本中移除。 请改用 $_TD->{table_name}。 @@ -1328,12 +1325,12 @@ CREATE TABLE test ( CREATE OR REPLACE FUNCTION valid_id() RETURNS trigger AS $$ if (($_TD->{new}{i} >= 100) || ($_TD->{new}{i} <= 0)) { - return "SKIP"; # skip INSERT/UPDATE command + return "SKIP"; # 跳过 INSERT/UPDATE 命令 } elsif ($_TD->{new}{v} ne "immortal") { $_TD->{new}{v} .= "(modified by trigger)"; - return "MODIFY"; # modify row and execute INSERT/UPDATE command + return "MODIFY"; # 修改行并执行 INSERT/UPDATE 命令 } else { - return; # execute INSERT/UPDATE command + return; # 执行 INSERT/UPDATE 命令 } $$ LANGUAGE plperl; @@ -1490,7 +1487,7 @@ DO 'elog(WARNING, join ", ", sort keys %INC)' LANGUAGE plperl; 也会发生。这是在 plperl.on_init 完成的任何初始化 之后进行的。执行这段代码时 SPI 函数不可用。 plperl.on_plperl_init 中的 Perl 代码是在对解释器 - 进行锁定之后执行的,因此只能执行可信操作。 + 进行锁定之后执行的,因此只能执行受信任的操作。 diff --git a/zh/15/plpgsql.sgml b/zh/15/plpgsql.sgml index 73d6dfb2..23c6e2f5 100644 --- a/zh/15/plpgsql.sgml +++ b/zh/15/plpgsql.sgml @@ -144,7 +144,7 @@ CREATE FUNCTION somefunc(integer, text) RETURNS integer AS 'function body text' LANGUAGE plpgsql; - 就 CREATE FUNCTION 而言,函数体目前只是一个字符串字面量。编写函数体时,通常最好使用美元引用(见 ),而不是普通的单引号语法。如果不使用美元引用,函数体中的任何单引号或反斜线都必须通过双写进行转义。本章几乎所有示例的函数体都使用了美元引用。 + 就 CREATE FUNCTION 而言,函数体只是一个字符串字面量。编写函数体时,通常最好使用美元引用(见 ),而不是普通的单引号语法。如果不使用美元引用,函数体中的任何单引号或反斜线都必须通过双写进行转义。本章几乎所有示例的函数体都使用了美元引用。 @@ -340,7 +340,7 @@ $$ LANGUAGE plpgsql; - 当 PL/pgSQL 函数声明了输出参数时,输出参数也会像普通输入参数一样获得 $n 名称和可选别名。输出参数本质上是一个初始值为 NULL 的变量,应在函数执行期间给它赋值。该参数的最终值就是返回值。例如,sales-tax 的示例也可以这样写: + 当 PL/pgSQL 函数声明了输出参数时,输出参数也会像普通输入参数一样获得 $n 名称和可选别名。输出参数本质上是一个初始值为 NULL 的变量,应在函数执行期间给它赋值。该参数的最终值就是返回值。例如,销售税的示例也可以这样写: CREATE FUNCTION sales_tax(subtotal real, OUT tax real) AS $$ @@ -465,7 +465,7 @@ $$ LANGUAGE plpgsql; SELECT add_three_values(1, 2, 4.7); - 可以正常工作,并会自动把整数输入提升为 numeric。如果使用 anyelement,则必须手工把这三个输入转换成同一类型。 + 可以正常工作,并会自动把整数输入提升为 numeric。如果使用 anyelement,则必须手工把这三个输入转换成同一类型。 @@ -499,26 +499,15 @@ DECLARE 复制类型 -name table.column%TYPE -name variable%TYPE +variable%TYPE - %TYPE 提供表列或先前已声明的 PL/pgSQL 变量的数据类型。你可以用它来声明用于保存数据库值的变量。例如,假设 users 表中有一个名为 user_id 的列。要声明一个与 users.user_id 具有相同数据类型的变量,可以这样写: - + %TYPE提供变量或表列的数据类型。可以用它声明将保存数据库值的变量。例如,假设有一个名为user_id的列,位于users表中。要声明一个数据类型与users.user_id相同的变量,可以写: user_id users.user_id%TYPE; - - 也可以在 %TYPE 后写数组修饰,从而创建保存被引用类型数组的变量: - -user_ids users.user_id%TYPE[]; -user_ids users.user_id%TYPE ARRAY[4]; -- 等价于上面一行 - - 与声明数组表列时一样,写多个方括号还是写具体数组维度都无关紧要:PostgreSQL 会把同一元素类型的所有数组都视为同一种类型,而不考虑维度数。(见 。) - - 使用 %TYPE 的好处是,你不必知道所引用结构的实际数据类型;更重要的是,如果被引用项的数据类型将来发生变化(例如把 user_id 的类型从 integer 改成 real),你可能就不需要修改函数定义。 @@ -546,10 +535,6 @@ user_ids users.user_id%TYPE ARRAY[4]; -- 等价于上面一行 行变量既可以通过 table_name%ROWTYPE 记法声明为与现有表或视图的行具有相同类型,也可以通过给出某个复合类型的名称来声明。(由于每个表都有一个同名的关联复合类型,所以在 PostgreSQL 中实际上写不写 %ROWTYPE 并无区别;不过带 %ROWTYPE 的形式可移植性更好。) - - 与 %TYPE 一样,%ROWTYPE 后也可以跟数组修饰,用于声明保存被引用复合类型数组的变量。 - - 函数参数也可以是复合类型(完整的表行)。在这种情况下,相应的标识符 $n 就是一个行变量,并且可以从中选取字段,例如 $1.user_id @@ -594,12 +579,12 @@ SELECT merge_fields(t.*) FROM table1 t WHERE ... ; <application>PL/pgSQL</application>变量的排序规则 - collation - in PL/pgSQL + 排序规则 + 在 PL/pgSQL 中 - 当 PL/pgSQL 函数具有一个或多个可排序数据类型参数时,每次函数调用都会根据分配给实际参数的排序规则确定出一个排序规则,如 所述。如果该排序规则能成功确定出来(即参数之间的隐式排序规则没有冲突),那么所有可排序参数都会被视为隐式带有该排序规则。这会影响函数中那些受排序规则影响的操作。例如,考虑 + 当 PL/pgSQL 函数具有一个或多个支持排序规则的数据类型参数时,每次函数调用都会根据分配给实际参数的排序规则确定出一个排序规则,如 所述。如果该排序规则能成功确定出来(即参数之间的隐式排序规则没有冲突),那么所有支持排序规则的参数都会被视为隐式带有该排序规则。这会影响函数中那些受排序规则影响的操作。例如,考虑 CREATE FUNCTION less_than(a text, b text) RETURNS boolean AS $$ @@ -616,7 +601,7 @@ SELECT less_than(text_field_1, text_field_2 COLLATE "C") FROM table1; - 此外,确定出的排序规则也会被视为任何可排序数据类型局部变量的排序规则。因此,即使把这个函数写成下面这样,其行为也不会有任何不同: + 此外,确定出的排序规则也会被视为任何支持排序规则的数据类型局部变量的排序规则。因此,即使把这个函数写成下面这样,其行为也不会有任何不同: CREATE FUNCTION less_than(a text, b text) RETURNS boolean AS $$ @@ -631,11 +616,11 @@ $$ LANGUAGE plpgsql; - 如果函数没有可排序数据类型的参数,或者无法为它们确定共同排序规则,那么参数和局部变量将使用其数据类型的默认排序规则(通常是数据库默认排序规则,但对于域类型变量也可能不同)。 + 如果函数没有支持排序规则的数据类型的参数,或者无法为它们确定共同排序规则,那么参数和局部变量将使用其数据类型的默认排序规则(通常是数据库默认排序规则,但对于域类型变量也可能不同)。 - 通过在可排序数据类型局部变量的声明中加入 COLLATE 选项,可以为其指定不同的排序规则,例如 + 通过在支持排序规则的数据类型局部变量的声明中加入 COLLATE 选项,可以为其指定不同的排序规则,例如 DECLARE @@ -666,7 +651,7 @@ $$ LANGUAGE plpgsql; 表达式 - PL/pgSQL语句中使用的所有表达式都会由服务器的主SQL执行器处理。例如,当你写下这样一条PL/pgSQL语句时: + PL/pgSQL 语句中使用的所有表达式都会由服务器的主 SQL 执行器处理。例如,当写下这样一条 PL/pgSQL 语句时: IF expression THEN ... @@ -674,7 +659,7 @@ IF expression THEN ... SELECT expression - 来计算该表达式。如中详细讨论的那样,在构造该SELECT命令时,PL/pgSQL变量名的每一次出现都会被替换成查询参数。这使得该SELECT的查询计划只需准备一次,然后就能在后续以不同变量值求值时重用。因此,表达式第一次被使用时,实际发生的事情本质上相当于执行了一条PREPARE命令。例如,如果已经声明了两个整数变量xy,并写下 + 来计算该表达式。如 中详细讨论的那样,在构造该 SELECT 命令时,PL/pgSQL 变量名的每一次出现都会被替换成查询参数。这使得该 SELECT 的查询计划只需准备一次,然后就能在后续以不同变量值求值时重用。因此,表达式第一次被使用时,实际发生的事情本质上相当于执行了一条 PREPARE 命令。例如,如果已经声明了两个整数变量 xy,并写下 IF x < y THEN ... @@ -682,7 +667,7 @@ IF x < y THEN ... PREPARE statement_name(integer, integer) AS SELECT $1 < $2; - 然后,在每次执行IF语句时,这条预备语句都会以当前PL/pgSQL变量值作为参数值被EXECUTE。通常这些细节对PL/pgSQL用户并不重要,但在诊断问题时了解它们会很有帮助。更多信息见。 + 然后,在每次执行 IF 语句时,这条预备语句都会以当前 PL/pgSQL 变量值作为参数值由 EXECUTE 执行。通常这些细节对 PL/pgSQL 用户并不重要,但在诊断问题时了解它们会很有帮助。更多信息见 @@ -699,7 +684,7 @@ PREPARE statement_name(integer, integer) AS SELECT $1 基本语句 - 在这一节和接下来的小节中,我们会描述PL/pgSQL能明确理解的所有语句类型。任何不被识别为这些语句类型之一的被假定为是一个 SQL 命令,并且会被发送给主数据库引擎执行,具体如中所述。 + 在这一节和接下来的小节中,我们会描述 PL/pgSQL 能明确理解的所有语句类型。任何不被识别为这些语句类型之一的语句都被视为 SQL 命令,并会被发送给主数据库引擎执行,具体如 中所述。 @@ -715,8 +700,7 @@ PREPARE statement_name(integer, integer) AS SELECT $1 SELECT命令被发送到主数据库引擎的方式计算。 该表达式必须得到一个单一值(如果该变量是一个行或记录变量, 它可能是一个行值)。该目标变量可以是一个简单变量( - 可以选择用一个块名限定)、一个行或记录变量的域或是一个简单 - 变量或域的数组的元素或者数组的切片。 + 可以选择用一个块名限定)、行或记录目标的字段,或者数组目标的元素或切片。 等号(=)可以被用来代替 PL/SQL-兼容的 := @@ -757,8 +741,8 @@ complex_array[n].realpart = 12.3; - 如果命令返回行(例如 SELECT,或者带 RETURNINGINSERT/UPDATE/DELETE/MERGE),有两种方式处理。 - 当命令最多返回一行,或者你只关心第一行的输出时,像往常一样编写命令,但要添加一个INTO子句来捕获输出,如中所述。为了处理所有的输出行,把命令写成FOR循环的数据源,如 中所述。 + 如果命令返回行(例如 SELECT,或者带 RETURNINGINSERT/UPDATE/DELETE),有两种方式处理。 + 当命令最多返回一行,或者只关心第一行的输出时,可照常编写该命令,但要添加一个 INTO 子句来捕获输出,如 中所述。要处理所有输出行,可将该命令写成 FOR 循环的数据源,如 中所述。 @@ -766,29 +750,29 @@ complex_array[n].realpart = 12.3; - PL/pgSQL变量值可以自动插入到可优化的SQL命令中,这些命令包括SELECTINSERTUPDATEDELETEMERGE以及某些包含其中之一的实用程序命令,比如EXPLAINCREATE TABLE ... AS SELECT。在这些命令中,命令文本中出现的任何PL/pgSQL变量名都会被查询参数替换,然后变量的当前值会在运行时作为参数值提供。这与前面描述的表达式处理完全相同;详情请参见。 + PL/pgSQL 变量值可以自动插入可优化的 SQL 命令中,这些命令包括 SELECTINSERTUPDATEDELETEMERGE 以及某些包含其中之一的工具命令,比如 EXPLAINCREATE TABLE ... AS SELECT。在这些命令中,命令文本中出现的任何 PL/pgSQL 变量名都会被查询参数替换,然后变量的当前值会在运行时作为参数值提供。这与前面描述的表达式处理完全相同;详情请参见 - 当以这种方式执行一个可优化的 SQL 命令时,如中讨论的,PL/pgSQL会为该命令缓存并重用执行计划。 + 当以这种方式执行一个可优化的 SQL 命令时,如中讨论的,PL/pgSQL可能会为该命令缓存并重用执行计划。 - 不可优化的SQL命令(也称为实用命令)不能够接受查询参数。 所以自动替换PL/pgSQL的变量在这类命令中不起作用。 要在从PL/pgSQL执行的实用程序命令中包含非常量文本,你必须将实用程序命令构建为一个字符串,然后EXECUTE它,如中所讨论的。 + 不可优化的 SQL 命令(也称为工具命令)不能接受查询参数。因此,自动替换 PL/pgSQL 变量在这类命令中不起作用。要在从 PL/pgSQL 执行的工具命令中包含非常量文本,必须将工具命令构建为一个字符串,然后用 EXECUTE 执行它,如 中所讨论的。 - EXECUTE也必须使用,如果你想以某种其他方式修改命令,而不是提供数据值,例如改变表名。 + 如果想通过其他方式修改命令,而不只是提供数据值,例如改变表名,也必须使用 EXECUTE - 有时候计算一个表达式或SELECT查询但抛弃其结果是有用的,例如调用一个有副作用但是没有有用的结果值的函数。在PL/pgSQL中要这样做,可使用PERFORM语句: + 有时需要计算一个表达式或 SELECT 查询但丢弃其结果,例如调用一个有副作用但没有有用结果值的函数。要在 PL/pgSQL 中这样做,可使用 PERFORM 语句: PERFORM query; - 这会执行query并且丢弃掉结果。以写一个SQL SELECT命令相同的方式写该query,并且将初始的关键词SELECT替换为PERFORM。对于WITH查询,使用PERFORM并且接着把该查询放在圆括号中(在这种情况中,该查询只能返回一行)。PL/pgSQL变量将被替换到该查询中,正如上面描述的查询,并且计划被以相同的方式被缓存。还有,如果该查询产生至少一行,特殊变量FOUND会被设置为真,而如果它不产生行则设置为假(见)。 + 这会执行 query 并丢弃结果。query 的写法与 SQL SELECT 命令相同,只需把开头的关键词 SELECT 替换为 PERFORM。对于 WITH 查询,使用 PERFORM 并将该查询放在圆括号中(在这种情况下,该查询只能返回一行)。PL/pgSQL 变量会像上文所述那样替换到查询中,计划也会以相同方式缓存。此外,如果该查询产生至少一行,特殊变量 FOUND 会被设置为真;如果不产生行,则设置为假(见 )。 @@ -812,12 +796,12 @@ PERFORM create_mv('cs_session_page_requests_mv', my_query); SELECT INTO - in PL/pgSQL + 在 PL/pgSQL 中 RETURNING INTO - in PL/pgSQL + 在 PL/pgSQL 中 @@ -828,10 +812,9 @@ SELECT select_expressions INTO STRICTexpressions INTO STRICT target; UPDATE ... RETURNING expressions INTO STRICT target; DELETE ... RETURNING expressions INTO STRICT target; -MERGE ... RETURNING expressions INTO STRICT target; - 其中target可以是记录变量、行变量,或者由简单变量和记录/行字段组成的逗号分隔列表。PL/pgSQL变量会像前文所述那样替换进命令的其余部分(也就是除了INTO子句之外的所有部分),并且计划也会以同样的方式缓存。这适用于SELECT、带有RETURNINGINSERT/UPDATE/DELETE/MERGE,以及某些返回行集的工具命令,例如EXPLAIN。除了INTO子句之外,该 SQL 命令的写法与在PL/pgSQL之外完全相同。 + 其中target可以是记录变量、行变量,或者由简单变量和记录/行字段组成的逗号分隔列表。PL/pgSQL变量会像前文所述那样替换进命令的其余部分(也就是除了INTO子句之外的所有部分),并且计划也会以同样的方式缓存。这适用于SELECT、带有RETURNINGINSERT/UPDATE/DELETE,以及某些返回行集的工具命令,例如EXPLAIN。除了INTO子句之外,该 SQL 命令的写法与在PL/pgSQL之外完全相同。 @@ -842,7 +825,7 @@ MERGE ... RETURNING expressions INTO STRICT - 如果一个行变量或一个变量列表被用作目标,该命令的结果列必须完全匹配该结果的结构,包括数量和数据类型,否则会发生一个运行时错误。当一个记录变量是目标时,它会自动地把自身配置成命令的结果列组成的行类型。 + 如果一个行变量或一个变量列表被用作目标,该命令的结果列必须完全匹配该目标的结构,包括数量和数据类型,否则会发生一个运行时错误。当一个记录变量是目标时,它会自动地把自身配置成命令的结果列组成的行类型。 @@ -850,7 +833,7 @@ MERGE ... RETURNING expressions INTO STRICT - 如果STRICT没有在INTO子句中被指定,那么target将被设置为该命令返回的第一个行,或者在该命令不返回行时设置为空(注意除非使用了ORDER BY,否则第一行的界定并不清楚)。第一行之后的任何结果行都会被抛弃。你可以检查特殊的FOUND变量(见)来确定是否返回了一行: + 如果STRICT没有在INTO子句中被指定,那么target将被设置为该命令返回的第一个行,或者在该命令不返回行时设置为空值(注意除非使用了ORDER BY,否则第一行的界定并不清楚)。第一行之后的任何结果行都会被抛弃。你可以检查特殊的FOUND变量(见)来确定是否返回了一行: SELECT * INTO myrec FROM emp WHERE empname = myname; @@ -875,11 +858,11 @@ END; - 对于带有RETURNINGINSERT/UPDATE/DELETE/MERGE,即使没有指定STRICTPL/pgSQL也会针对多于一个返回行的情况报告一个错误。这是因为没有类似于ORDER BY的选项可以用来决定应该返回哪个被影响的行。 + 对于带有RETURNINGINSERT/UPDATE/DELETE,即使没有指定STRICTPL/pgSQL也会针对多于一个返回行的情况报告一个错误。这是因为没有类似于ORDER BY的选项可以用来决定应该返回哪个被影响的行。 - 如果为函数启用了print_strict_params,那么当由于不满足STRICT要求而抛出错误时,错误消息的DETAIL部分将包含传给该命令的参数信息。你可以通过设置plpgsql.print_strict_params来修改所有函数的print_strict_params设置,不过只有此后重新编译的函数才会受影响。也可以通过编译器选项按函数启用它,例如: + 如果为函数启用了print_strict_params,那么当由于不满足STRICT要求而抛出错误时,错误消息的DETAIL部分将包含传给该命令的参数信息。你可以通过设置plpgsql.print_strict_params来修改所有函数的print_strict_params设置,不过该设置只会影响此后编译的函数。也可以通过编译器选项按函数启用它,例如: CREATE FUNCTION get_userid(username text) RETURNS int AS $$ @@ -915,33 +898,31 @@ CONTEXT: PL/pgSQL function get_userid(text) line 6 at SQL statement 执行动态命令 - 很多时候你将想要在PL/pgSQL函数中产生动态命令,也就是每次执行中会涉及到不同表或不同数据类型的命令。PL/pgSQL通常对于命令所做的缓存计划尝试(如中讨论)在这种情境下无法工作。要处理这一类问题,需要提供EXECUTE语句: + 很多时候你将想要在PL/pgSQL函数中产生动态命令,也就是每次执行中会涉及到不同表或不同数据类型的命令。PL/pgSQL通常对于命令所做的缓存计划尝试(如中讨论)在这种情境下无法工作。要处理这一类问题,提供了EXECUTE语句: EXECUTE command-string INTO STRICT target USING expression , ... ; - 其中command-string是一个能得到一个包含要被执行命令字符串(类型text)的表达式。可选的target是一个记录变量、一个行变量或者一个逗号分隔的简单变量以及记录/行域的列表,该命令的结果将存储在其中。可选的USING表达式提供要被插入到该命令中的值。 + 其中command-string是一个能得到一个包含要被执行命令字符串(类型text)的表达式。可选的target是一个记录变量、一个行变量或者一个逗号分隔的简单变量以及记录/行字段的列表,该命令的结果将存储在其中。可选的USING表达式提供要被插入到该命令中的值。 在计算得到的命令字符串中,不会做PL/pgSQL变量的替换。任何所需的变量值必须在命令字符串被构造时被插入其中,或者你可以使用下面描述的参数。 - - 还有,对于通过EXECUTE执行的命令不会有计划被缓存。该命令反而在每次运行时都会被做计划。因此,该命令字符串可以在执行不同表和列上动作的函数中被动态创建。 - + 此外,通过 EXECUTE 执行的命令不会缓存计划,而是在每次运行该语句时重新规划。因此,可以在函数中动态构造命令字符串,对不同的表和列执行操作。 - INTO子句指定一个返回行的 SQL 命令的结果应该被赋值到哪里。如果提供了一个行或变量列表,它必须完全匹配查询命令结果的结构(当一个记录变量被提供时,它会自动把它自己配置为匹配结果结构)。如果返回多个行,只有第一个行会被赋值给INTO变量。如果没有返回行,NULL 会被赋值给INTO变量。如果没有指定INTO变量,该查询结果会被抛弃。 + INTO子句指定一个返回行的 SQL 命令的结果应该被赋值到哪里。如果提供了一个行变量或变量列表,它必须完全匹配查询命令结果的结构(当一个记录变量被提供时,它会自动把它自己配置为匹配结果结构)。如果返回多个行,只有第一个行会被赋值给INTO变量。如果没有返回行,NULL 会被赋值给INTO变量。如果没有指定INTO子句,该查询结果会被抛弃。 - 如果给出了STRICT选项,除非该查询刚好产生一行,否则将会报告一个错误。 + 如果给出了STRICT选项,除非该命令刚好产生一行,否则将会报告一个错误。 - 命令字符串可以使用参数值,它们在命令中用$1$2等引用。这些符号引用在USING子句中提供的值。这种方法常常更适合于把数据值作为文本插入到命令字符串中:它避免了将该值转换为文本以及转换回来的运行时负荷,并且它更不容易被 SQL 注入攻击,因为不需要引用或转义。一个示例是: + 命令字符串可以使用参数值,它们在命令中用$1$2等引用。这些符号引用在USING子句中提供的值。这种方法通常比把数据值作为文本插入命令字符串更可取:它避免了将该值转换为文本以及转换回来的运行时负荷,并且它更不容易被 SQL 注入攻击,因为不需要引用或转义。一个示例是: EXECUTE 'SELECT count(*) FROM mytable WHERE inserted_by = $1 AND inserted <= $2' INTO c @@ -959,25 +940,25 @@ EXECUTE 'SELECT count(*) FROM ' USING checked_user, checked_date; 一种更干净的方法是使用format()的 - %I规范,插入自带引号的表名或者列名: + %I 格式说明符,插入表名或列名并自动为其加上引号: EXECUTE format('SELECT count(*) FROM %I ' 'WHERE inserted_by = $1 AND inserted <= $2', tabname) INTO c USING checked_user, checked_date; - (此示例依赖于隐式连接由换行符分隔的字符串文字的 SQL 规则) + (此示例依赖于隐式连接由换行符分隔的字符串字面量的 SQL 规则) 参数符号的另一个限制是它们仅适用于可优化的SQL命令 (SELECT, INSERT, UPDATE, DELETE, MERGE以及包含其中一个的某些命令)。 - 在其他语句类型(通称为实用程序语句)中,即使它们只是数据值,您也必须以文本方式插入值。 + 在其他语句类型(通称为工具语句)中,即使它们只是数据值,你也必须以文本方式插入值。 - 在上面第一个示例中,带有一个简单的常量命令字符串和一些USING参数的EXECUTE命令在功能上等效于直接用PL/pgSQL写的命令,并且允许自动发生PL/pgSQL变量替换。重要的不同之处在于,EXECUTE会在每一次执行时根据当前的参数值重新计划该命令,而PL/pgSQL则是创建一个通用计划并且将其缓存以便重用。在最佳计划强依赖于参数值的情况中,使用EXECUTE来明确地保证不会选择一个通用计划是很有帮助的。 + 在上面第一个示例中,带有一个简单的常量命令字符串和一些USING参数的EXECUTE命令在功能上等效于直接用PL/pgSQL写的命令,并且允许自动发生PL/pgSQL变量替换。重要的不同之处在于,EXECUTE会在每一次执行时根据当前的参数值重新计划该命令,而PL/pgSQL则可能创建一个通用计划并且将其缓存以便重用。在最佳计划强依赖于参数值的情况中,使用EXECUTE来明确地保证不会选择一个通用计划是很有帮助的。 @@ -985,10 +966,7 @@ EXECUTE format('SELECT count(*) FROM %I ' - - - PL/pgSQL中的EXECUTE语句与EXECUTE PostgreSQL服务器支持的 SQL 语句无关。服务器的EXECUTE语句不能直接在PL/pgSQL函数中使用(并且也没有必要)。 - + PL/pgSQLEXECUTE 语句与 PostgreSQL 服务器支持的 SQL EXECUTE 语句无关。服务器的 EXECUTE 语句不能直接用于 PL/pgSQL 函数中(也没有这个必要)。 @@ -1052,19 +1030,19 @@ EXECUTE 'UPDATE tbl SET ' || ' WHERE key = ' || quote_nullable(keyvalue); - 如果正在处理的参数值可能为空,那么通常应该用quote_nullable来代替quote_literal。 + 如果正在处理的参数值可能为空值,那么通常应该用quote_nullable来代替quote_literal - 通常,必须小心地确保查询中的空值不会递送意料之外的结果。例如如果keyvalue为空,下面的WHERE子句 + 通常,必须小心地确保查询中的空值不会产生意料之外的结果。例如如果keyvalue为空值,下面的WHERE子句 'WHERE key = ' || quote_nullable(keyvalue) - 永远不会成功,因为在=操作符中使用空操作数得到的结果总是为空。如果想让空和一个普通键值一样工作,你应该将上面的命令重写成 + 永远不会成功,因为在=操作符中使用空值操作数得到的结果总是空值。如果想让空值像普通键值一样工作,你应该将上面的命令重写成 'WHERE key IS NOT DISTINCT FROM ' || quote_nullable(keyvalue) - (目前,IS NOT DISTINCT FROM的处理效率不如=,因此只有在非常必要时才这样做。关于空和IS DISTINCT的详细信息请见)。 + (目前,IS NOT DISTINCT FROM的处理效率不如=,因此只有在非常必要时才这样做。关于空值和IS DISTINCT的详细信息请见)。 @@ -1077,7 +1055,7 @@ EXECUTE 'UPDATE tbl SET ' || '$$ WHERE key = ' || quote_literal(keyvalue); - 因为如果newvalue的内容碰巧含有$$,那么这段代码就会出问题。同样的缺点可能适用于你选择的任何其他美元符号引用定界符。因此,要想安全地引用事先不知道的文本,必须恰当地使用quote_literalquote_nullablequote_ident。 + 因为如果newvalue的内容碰巧含有$$,那么这段代码就会出问题。同样的问题也适用于你选择的任何其他美元符号引用定界符。因此,要想安全地引用事先不知道的文本,必须恰当地使用quote_literalquote_nullablequote_ident @@ -1116,7 +1094,7 @@ EXECUTE format('UPDATE tbl SET %I = $1 WHERE key = $2', colname) GET CURRENT DIAGNOSTICS variable { = | := } item , ... ; - 这条命令允许检索系统状态指示符。CURRENT是一个噪声词(另见中的GET STACKED DIAGNOSTICS)。每个item是一个关键字, 它标识一个要被赋予给指定变量的状态值(变量应具有正确的数据类型来接收状态值)。中展示了当前可用的状态项。冒号等号(:=)可以被用来取代 SQL 标准的=符号。例如: + 这条命令允许检索系统状态指示符。CURRENT是一个噪声词(另见中的GET STACKED DIAGNOSTICS)。每个item是一个关键字, 它标识一个要被赋予给指定variable的状态值(变量应具有正确的数据类型来接收状态值)。中展示了当前可用的状态项。冒号等号(:=)可以被用来取代 SQL 标准的=符号。例如: GET DIAGNOSTICS integer_var = ROW_COUNT; @@ -1150,24 +1128,19 @@ GET DIAGNOSTICS integer_var = ROW_COUNT; text 描述当前调用栈的文本行(见 - - PG_ROUTINE_OID - oid - 当前函数的 OID -
第二种确定命令效果的方法是检查名为FOUND的特殊变量,类型为boolean。 - 在每次PL/pgSQL函数调用中,FOUND都是以 false 开头。 + 在每次PL/pgSQL函数调用中,FOUND的初始值都是 false。 它由以下类型的语句设置: - SELECT INTO语句在分配行时将FOUND设置为true, + SELECT INTO语句在为目标赋上一行值时将FOUND设置为true, 如果没有返回行则设置为false。 @@ -1199,7 +1172,7 @@ GET DIAGNOSTICS integer_var = ROW_COUNT; FORFOREACH语句在迭代一次或多次时将 FOUND设置为true,否则设置为false。 - 当循环退出时,FOUND被设置为这种方式; + 当循环退出时,FOUND会按上述方式设置; 在循环执行过程中,FOUND不会被循环语句修改, 尽管它可能会被循环体内的其他语句执行修改。 @@ -1295,7 +1268,7 @@ RETURN expression; - 如果函数返回的是标量类型,表达式结果会自动转换为函数的返回类型。但如果要返回一个组合(行)值,你必须写出一个恰好生成所需列集合的表达式。这可能需要显式类型转换。 + 如果函数返回的是标量类型,表达式结果会按照赋值部分的说明自动转换为函数的返回类型。但如果要返回一个复合(行)值,你必须写出一个恰好生成所需列集合的表达式。这可能需要显式类型转换。 @@ -1307,7 +1280,7 @@ RETURN expression; - 一个函数的返回值不能是未定义。如果控制到达了函数最顶层的块而没有碰到一个RETURN语句,那么会发生一个运行时错误。不过,这个限制不适用于带输出参数的函数以及返回void的函数。在这些情况中,如果顶层的块结束,将自动执行一个RETURN语句。 + 一个函数的返回值不能是未定义。如果控制到达了函数最顶层块的末尾而没有碰到一个RETURN语句,那么会发生一个运行时错误。不过,这个限制不适用于带输出参数的函数以及返回void的函数。在这些情况中,如果顶层的块结束,将自动执行一个RETURN语句。 @@ -1331,12 +1304,12 @@ RETURN (1, 2, 'three'::text); -- 必须把列类型转换成正确的类型 RETURN NEXT - in PL/pgSQL + 在 PL/pgSQL 中 RETURN QUERY - in PL/pgSQL + 在 PL/pgSQL 中 @@ -1346,7 +1319,7 @@ RETURN QUERY EXECUTE command-string < - 当 PL/pgSQL 函数被声明为返回 SETOF sometype 时,返回过程会略有不同。在这种情况下,要返回的各个项通过一系列 RETURN NEXTRETURN QUERY 命令指定,最后再用一个不带参数的 RETURN 命令表明函数已经执行完毕。RETURN NEXT 可用于标量和组合数据类型;对于组合结果类型,会返回完整的结果RETURN QUERY 会把查询执行结果追加到函数的结果集中。在同一个集合返回函数中,RETURN NEXTRETURN QUERY 可以自由混用,此时它们的结果会被串接起来。 + 当 PL/pgSQL 函数被声明为返回 SETOF sometype 时,返回过程会略有不同。在这种情况下,要返回的各个项通过一系列 RETURN NEXTRETURN QUERY 命令指定,最后再用一个不带参数的 RETURN 命令表明函数已经执行完毕。RETURN NEXT 可用于标量和复合数据类型;对于复合结果类型,会返回完整的结果RETURN QUERY 会把查询执行结果追加到函数的结果集中。在同一个集合返回函数中,RETURN NEXTRETURN QUERY 可以自由混用,此时它们的结果会被串接起来。 @@ -1511,7 +1484,7 @@ END IF; - IF-THEN语句是IF的最简单形式。 如果条件为真,在THENEND IF之间的语句将被执行。否则,将忽略它们。 + IF-THEN语句是IF的最简单形式。 如果条件为真,在THENEND IF之间的语句将被执行。否则,将忽略它们。 @@ -1594,7 +1567,7 @@ ELSIF number > 0 THEN ELSIF number < 0 THEN result := 'negative'; ELSE - -- 嗯,唯一的其他可能性是数字为空 + -- 嗯,唯一的其他可能性是 number 为 null result := 'NULL'; END IF; @@ -1690,9 +1663,7 @@ END CASE; - - 这种形式的CASEIF-THEN-ELSIF完全等价,唯一的区别是:如果省略了ELSE子句,CASE会报错,而不是简单地什么也不做。 - + 这种形式的CASEIF-THEN-ELSIF完全等价,唯一的区别是:如果执行到被省略的ELSE子句,就会报错,而不是简单地什么也不做。 @@ -1702,12 +1673,12 @@ END CASE; 简单循环 - loop + 循环 在 PL/pgSQL 中 - 使用LOOPEXITCONTINUEWHILEFORFOREACH语句,你可以安排PL/pgSQL重复一系列命令。 + 使用LOOPEXITCONTINUEWHILEFORFOREACH语句,你可以安排PL/pgSQL函数重复一系列命令。 @@ -1862,22 +1833,22 @@ END LOOP label ; - 这种形式的FOR会创建一个在一个整数范围上迭代的循环。变量name会自动定义为类型integer并且只在循环内存在(任何该变量名的现有定义在此循环内都将被忽略)。给出范围上下界的两个表达式在进入循环的时候计算一次。如果没有指定BY子句,迭代步长为 1,否则步长是BY中指定的值,该值也只在循环进入时计算一次。如果指定了REVERSE,那么在每次迭代后步长值会被减除而不是增加。 + 这种形式的FOR会创建一个在一个整数范围上迭代的循环。变量name会自动定义为类型integer并且只在循环内存在(任何该变量名的现有定义在此循环内都将被忽略)。给出范围上下界的两个表达式在进入循环的时候计算一次。如果没有指定BY子句,迭代步长为 1,否则步长是BY中指定的值,该值也只在循环进入时计算一次。如果指定了REVERSE,那么在每次迭代后会减去步长,而不是加上步长。 整数FOR循环的一些示例: FOR i IN 1..10 LOOP - -- 我在循环中将取值 1,2,3,4,5,6,7,8,9,10 + -- i 在循环中将取值 1,2,3,4,5,6,7,8,9,10 END LOOP; FOR i IN REVERSE 10..1 LOOP - -- 我在循环中将取值 10,9,8,7,6,5,4,3,2,1 + -- i 在循环中将取值 10,9,8,7,6,5,4,3,2,1 END LOOP; FOR i IN REVERSE 10..1 BY 2 LOOP - -- 我在循环中将取值 10,8,6,4,2 + -- i 在循环中将取值 10,8,6,4,2 END LOOP; @@ -1941,7 +1912,7 @@ $$ LANGUAGE plpgsql; - 在这类 FOR 语句中使用的 query,可以是任何向调用者返回行的 SQL 命令:最常见的是 SELECT,但也可以是带 RETURNING 子句的 INSERTUPDATEDELETEMERGE。某些实用程序命令,如 EXPLAIN,也可以用于此处。 + 在这类 FOR 语句中使用的 query,可以是任何向调用者返回行的 SQL 命令:最常见的是 SELECT,但也可以是带 RETURNING 子句的 INSERTUPDATEDELETE。某些工具命令,如 EXPLAIN,也可以用于此处。 @@ -1956,7 +1927,7 @@ FOR target IN EXECUTE text_expressionstatements END LOOP label ; - 这个示例类似前面的形式,只不过源查询被指定为一个字符串表达式,在每次进入FOR循环时都会计算它并且重新计划。这允许程序员在一个预先计划好了的命令的速度和一个动态命令的灵活性之间进行选择,就像一个纯EXECUTE语句那样。在使用EXECUTE时,可以通过USING将参数值插入到动态命令中。 + 这个示例类似前面的形式,只不过源查询被指定为一个字符串表达式,在每次进入FOR循环时都会计算它并且重新计划。这允许程序员在一个预先计划好了的命令的速度和一个动态命令的灵活性之间进行选择,就像一个纯EXECUTE语句那样。与EXECUTE一样,可以通过USING将参数值插入到动态命令中。 @@ -1969,7 +1940,7 @@ END LOOP label ; 遍历数组 - FOREACH循环很像FOR循环,但它不是遍历 SQL 查询返回的行,而是遍历数组值的元素。(一般来说,FOREACH用于遍历组合值表达式的组成部分;未来还可能加入遍历数组以外其他组合值的变体。)用于遍历数组的FOREACH语句如下: + FOREACH循环很像FOR循环,但它不是遍历 SQL 查询返回的行,而是遍历数组值的元素。(一般来说,FOREACH用于遍历复合值表达式的组成部分;未来还可能加入遍历数组以外其他复合值的变体。)用于遍历数组的FOREACH语句如下: <<label>> @@ -1997,7 +1968,7 @@ END; $$ LANGUAGE plpgsql; - 元素会按存储顺序访问,而不管数组有多少维。尽管target通常只是单个变量,但在遍历组合值(记录)数组时,它也可以是一个变量列表。在这种情况下,每个数组元素都会按组合值的连续列给这些变量赋值。 + 元素会按存储顺序访问,而不管数组有多少维。尽管target通常只是单个变量,但在遍历复合值(记录)数组时,它也可以是一个变量列表。在这种情况下,每个数组元素都会按复合值的连续列给这些变量赋值。 @@ -2030,8 +2001,8 @@ NOTICE: row = {10,11,12} 捕获错误 - exceptions - in PL/pgSQL + 异常 + 在 PL/pgSQL 中 @@ -2054,7 +2025,7 @@ END; - 如果没有发生错误,这种形式的块只是简单地执行所有statements, 并且接着控制转到END之后的下一个语句。但是如果在statements内发生了一个错误,则会放弃对statements的进一步处理,然后控制会转到EXCEPTION列表。系统会在列表中寻找匹配所发生错误的第一个condition。如果找到一个匹配,则执行对应的handler_statements,并且接着把控制转到END之后的下一个语句。如果没有找到匹配,该错误就会传播出去,就好像根本没有EXCEPTION一样:错误可以被一个带有EXCEPTION的闭合块捕捉,如果没有EXCEPTION则中止该函数的处理。 + 如果没有发生错误,这种形式的块只是简单地执行所有statements, 并且接着控制转到END之后的下一个语句。但是如果在statements内发生了一个错误,则会放弃对statements的进一步处理,然后控制会转到EXCEPTION列表。系统会在列表中寻找匹配所发生错误的第一个condition。如果找到一个匹配,则执行对应的handler_statements,并且接着把控制转到END之后的下一个语句。如果没有找到匹配,该错误就会传播出去,就好像根本没有EXCEPTION一样:错误可以被一个带有EXCEPTION的外围块捕捉,如果没有这样的块则中止该函数的处理。 @@ -2091,7 +2062,7 @@ END; - 进入和退出一个包含EXCEPTION子句的块要比不包含EXCEPTION的块开销大的多。因此,只在必要的时候使用EXCEPTION。 + 进入和退出一个包含EXCEPTION子句的块要比不包含该子句的块开销大得多。因此,只在必要的时候使用EXCEPTION @@ -2118,9 +2089,9 @@ BEGIN IF found THEN RETURN; END IF; - -- 不在这里,那么尝试插入该键 + -- 该键不存在,因此尝试插入 -- 如果其他某人并发地插入同一个键, - -- 我们可能得到一个唯一键失败 + -- 就可能发生违反唯一约束的错误 BEGIN INSERT INTO db(a,b) VALUES (key, data); RETURN; @@ -2159,7 +2130,7 @@ SELECT merge_db(1, 'dennis'); GET STACKED DIAGNOSTICS variable { = | := } item , ... ; - 每个item是一个关键词,它标识一个被赋予给指定变量(应该具有接收该值的正确数据类型)的状态值。中显示了当前可用的状态项。 + 每个item是一个关键词,它标识一个被赋予给指定variable(应该具有接收该值的正确数据类型)的状态值。中显示了当前可用的状态项。 @@ -2271,7 +2242,7 @@ END; 获得执行位置信息 - GET DIAGNOSTICS(之前在中描述)命令检索有关当前执行状态的信息(反之上文讨论的GET STACKED DIAGNOSTICS命令会把有关执行状态的信息报告成一个以前的错误)。它的PG_CONTEXT状态项可用于标识当前执行位置。状态项PG_CONTEXT将返回一个文本字符串,其中有描述该调用栈的多行文本。第一行会指向当前函数以及当前正在执行GET DIAGNOSTICS的命令。第二行及其后的行表示调用栈中更上层的调用函数。例如: + GET DIAGNOSTICS(之前在中描述)命令检索有关当前执行状态的信息(反之上文讨论的GET STACKED DIAGNOSTICS命令报告先前发生错误时的执行状态信息)。它的PG_CONTEXT状态项可用于标识当前执行位置。状态项PG_CONTEXT将返回一个文本字符串,其中包含一行或多行描述该调用栈的文本。第一行会指向当前函数以及当前正在执行的GET DIAGNOSTICS命令。第二行及其后的行表示调用栈中更上层的调用函数。例如: CREATE OR REPLACE FUNCTION outer_func() RETURNS integer AS $$ @@ -2315,7 +2286,7 @@ CONTEXT: PL/pgSQL function outer_func() line 3 at RETURN 游标 - cursor + 游标 在 PL/pgSQL 中 @@ -2347,7 +2318,7 @@ DECLARE - 当游标查询使用 FOR UPDATE/SHARE 时,不能使用 SCROLL 选项。此外,对于涉及易失函数的查询,最好使用 NO SCROLLSCROLL 的实现假定重新读取查询输出会得到一致的结果,而易失函数并不满足这一假设。 + 当游标查询使用 FOR UPDATE/SHARE 时,不能使用 SCROLL 选项。此外,对于涉及易失函数的查询,最好使用 NO SCROLLSCROLL 的实现假定重新读取查询输出会得到一致的结果,而易失函数可能无法满足这一假设。 @@ -2356,25 +2327,16 @@ DECLARE 打开游标 - 在能够使用游标检索行之前,必须先将其打开(这等效于 SQL 命令DECLARE CURSOR)。PL/pgSQL有三种形式的OPEN命令,其中两种用于未绑定游标变量,另一种用于已绑定游标变量。 + 在能够使用游标检索行之前,必须先将其打开(这等效于 SQL 命令DECLARE CURSOR)。PL/pgSQL有三种形式的OPEN命令,其中两种用于未绑定游标变量,另一种用于已绑定游标变量。 - 可以通过中描述的FOR语句在不显式打开游标的情况下使用已绑定的游标变量。FOR 循环会打开该游标,并在循环完成时再次关闭它。 + 可以通过中描述的FOR语句在不显式打开游标的情况下使用已绑定的游标变量。 - - portal - 在 PL/pgSQL 中 - - - - 打开游标会创建一个称为 portal 的服务器内部数据结构,它保存游标查询的执行状态。portal 具有一个名称,在其存在期间该名称在会话内必须唯一。默认情况下,PL/pgSQL 会为其创建的每个 portal 分配唯一名称。不过,如果你给游标变量赋一个非空字符串值,该字符串会被用作 portal 名称。这个特性可用于中描述的用法。 - - <command>OPEN FOR</command> <replaceable>query</replaceable> @@ -2422,7 +2384,7 @@ OPEN curs1 FOR EXECUTE format('SELECT * FROM %I WHERE col1 = $1',tabname) USING 打开已绑定游标 -OPEN bound_cursorvar ( argument_name { := | => } argument_value , ... ) ; +OPEN bound_cursorvar ( argument_name := argument_value , ... ) ; @@ -2434,7 +2396,7 @@ OPEN bound_cursorvar ( - 使用位置命名记号可以传递参数值。在位置记号中,所有参数都必须按照顺序指定。在命名记号中,每一个参数的名字使用:==>与参数表达式分隔。类似于中描述的调用函数,也允许混合位置和命名记号。 + 使用位置命名记号可以传递参数值。在位置记号中,所有参数都必须按照顺序指定。在命名记号中,每一个参数的名字使用:=与参数表达式分隔。类似于中描述的调用函数,也允许混合位置和命名记号。 @@ -2443,7 +2405,6 @@ OPEN bound_cursorvar ( @@ -2498,7 +2459,7 @@ FETCH direction { FROM | IN } RELATIVE countFORWARD或者 BACKWARD。 - 省略direction和指定NEXT是一样的。在使用count的形式中,count可以是任意的整数值表达式(与SQL命令FETCH不一样,FETCH仅允许整数常量)。除非游标被使用SCROLL选项声明或打开,否则要求反向移动的direction值很可能会失败。 + 省略direction和指定NEXT是一样的。在使用count的形式中,count可以是任意的整数值表达式(与SQL命令FETCH不一样,后者仅允许整数常量)。除非游标被使用SCROLL选项声明或打开,否则要求反向移动的direction值很可能会失败。 @@ -2592,7 +2553,7 @@ CLOSE curs1; - 在 PostgreSQL 16 之前,已绑定游标变量会被初始化为其自身名称,而不是保持为空,因此默认情况下底层 portal 名称与游标变量名相同。之所以改动,是因为该行为在不同函数里同名游标之间带来了过高的名称冲突风险。 + 已绑定游标变量会被初始化为表示其名称的字符串值,因此除非程序员在打开游标之前通过赋值覆盖它,否则 portal 名称与游标变量名相同。而未绑定游标变量在初始时默认为空值,因此除非被覆盖,否则它会得到一个自动生成的唯一名称。 @@ -2679,7 +2640,7 @@ COMMIT; <<label>> -FOR recordvar IN bound_cursorvar ( argument_name { := | => } argument_value , ... ) LOOP +FOR recordvar IN bound_cursorvar ( argument_name := argument_value , ... ) LOOP statements END LOOP label ; @@ -2726,7 +2687,7 @@ CALL transaction_test1(); 连锁的事务 - 在 PL/pgSQL + 在 PL/pgSQL 中 @@ -2738,13 +2699,7 @@ CALL transaction_test1(); 只有在从顶层调用的CALLDO中才能进行事务控制,在没有任何其他中间命令的嵌套CALLDO调用中也能进行事务控制。例如,如果调用栈是CALL proc1()CALL proc2()CALL proc3(),那么第二个和第三个过程可以执行事务控制动作。但是如果调用栈是CALL proc1()SELECT func2()CALL proc3(),则最后一个过程不能做事务控制,因为中间有SELECT - - PL/pgSQL 不支持保存点(SAVEPOINT/ROLLBACK TO SAVEPOINT/RELEASE SAVEPOINT)。保存点的典型用法可以用带异常处理器的代码块替代(见)。在内部,实现为带异常处理器的代码块会形成一个子事务,这意味着在这类代码块内部不能结束事务。 - - - - 对于游标循环,还有一些特殊注意事项。请看下面这个示例: - + 游标循环需要特别考虑。来看这个例子: CREATE PROCEDURE transaction_test2() LANGUAGE plpgsql AS $$ @@ -2759,13 +2714,13 @@ END; $$; CALL transaction_test2(); - - 通常,游标会在事务提交时自动关闭。但是,作为这类循环一部分创建的游标,会在第一次 COMMITROLLBACK 时自动转换为可保持游标。这意味着该游标会在第一次 COMMITROLLBACK 时被完整求值,而不是逐行求值。循环结束后,该游标仍会被自动移除,因此这一点对用户通常不可见。但必须注意,游标查询获取的任何表锁或行锁,在第一次 COMMITROLLBACK 之后都不再保持。 - +通常,游标会在事务提交时自动关闭。但是,在这样的循环中创建的游标,会自动转换为可保持游标,转换发生于第一次COMMITROLLBACK。这意味着,游标将在第一次执行以下命令时被完整求值:COMMITROLLBACK,而不是逐行求值。循环结束后游标仍然会被自动移除,因此这些行为对用户大多是不可见的。 由非只读命令(例如 UPDATE ... RETURNING)驱动的游标循环中,不允许使用事务命令。 + + 不能在带有异常处理器的块中结束事务。 @@ -2786,28 +2741,17 @@ CALL transaction_test2(); 在 PL/pgSQL 中 - - 使用RAISE语句报告消息以及抛出错误。 - - -RAISE level 'format' , expression , ... USING option { = | := } expression , ... ; -RAISE level condition_name USING option { = | := } expression , ... ; -RAISE level SQLSTATE 'sqlstate' USING option { = | := } expression , ... ; -RAISE level USING option { = | := } expression , ... ; + 使用RAISE语句报告消息和抛出错误。 +RAISE level 'format' , expression , ... USING option = expression , ... ; +RAISE level condition_name USING option = expression , ... ; +RAISE level SQLSTATE 'sqlstate' USING option = expression , ... ; +RAISE level USING option = expression , ... ; RAISE ; - - - level选项指定了错误的严重性。允许的级别有DEBUGLOGINFONOTICE, WARNING以及EXCEPTION,默认级别是EXCEPTIONEXCEPTION会抛出一个错误(通常会中止当前事务)。其他级别仅仅是产生不同优先级的消息。不管一个特定优先级的消息是被报告给客户端、还是写到服务器日志、亦或是二者同时都做,这都由配置变量控制。详见。 - +其中,level选项指定错误的严重程度。允许的级别为DEBUG, + LOGINFO, + NOTICEWARNING以及EXCEPTION,其中EXCEPTION是默认值。EXCEPTION会抛出错误(通常会中止当前事务);其他级别只会生成不同优先级的消息。特定优先级的消息是报告给客户端、写入服务器日志,还是两者都做,由配置变量控制。更多信息见中的说明。 - - 在第一种语法变体中,在level之后(如果有),写一个format字符串 - (必须是一个简单的字符串文字,而不是一个表达式)。格式字符串指定要报告的错误消息文本。 - 格式字符串后跟要插入到消息中的可选参数表达式。 - 在格式字符串中,%将被下一个可选参数的值的字符串表示替换。写 - %%以发出一个字面上的%。 - 参数的数量必须与格式字符串中的%占位符的数量匹配,否则在函数编译期间会引发错误。 - + level(如果有)之后,可以指定一个format字符串(必须是简单的字符串字面量,不能是表达式)。格式字符串指定要报告的错误消息文本。格式字符串之后可以跟上可选的参数表达式,其值将被插入消息中。在格式字符串内,%会被替换为下一个可选参数值的字符串表示。写成%%可以输出一个字面的%。参数个数必须与格式字符串中%占位符的个数匹配,否则会在函数编译期间报错。 在这个示例中,v_job_id的值将替换字符串中的%: @@ -2816,36 +2760,21 @@ RAISE NOTICE 'Calling cs_create_job(%)', v_job_id; - - 在第二和第三种语法变体中,condition_name 和 - sqlstate 分别指定错误条件名称或五字符 SQLSTATE 代码。 - 有效的错误条件名称和预定义 SQLSTATE 代码见 。 - - - - 下面是 condition_name 和 - sqlstate 的用法示例: - -RAISE division_by_zero; -RAISE WARNING SQLSTATE '22012'; - - - - - 在任意一种语法变体中,都可以通过写一个后面跟着option = expression项的USING,为错误报告附加额外信息。每一个expression可以是任意字符串值的表达式。允许的option关键词是: - - + 可以为错误报告附加额外信息,方法是写出USING,后面跟上option = expression项目。每个expression都可以是任意字符串值表达式。允许的option关键字为: MESSAGE - 设置错误消息文本。该选项不能用于第一种语法变体,因为消息文本已经给出。 + 设置错误消息文本。该选项不能用于在USING之前包含格式字符串的RAISE形式。 DETAIL - 提供一个错误的细节消息。 + 提供错误的详细信息。 @@ -2859,7 +2788,7 @@ RAISE WARNING SQLSTATE '22012'; ERRCODE - 指定要报告的错误代码(SQLSTATE),可以用中所示的条件名,或者直接作为一个五字符 SQLSTATE 代码。该选项不能用于第二和第三种语法变体,因为错误代码已经给出。 + 指定要报告的错误代码(SQLSTATE),可以用中所示的条件名,或者直接作为一个五字符 SQLSTATE 代码。 @@ -2876,9 +2805,7 @@ RAISE WARNING SQLSTATE '22012'; - - 这个示例将用给定的错误消息和提示中止事务: - + 这个例子会中止事务,并给出指定的错误消息和提示: RAISE EXCEPTION 'Nonexistent ID --> %', user_id USING HINT = 'Please check your user ID'; @@ -2893,14 +2820,19 @@ RAISE 'Duplicate user ID: %', user_id USING ERRCODE = '23505'; - 另一种得到前面示例相同结果的方式是: + 还有第二种RAISE语法,其中主参数是要报告的条件名或 SQLSTATE,例如: + +RAISE division_by_zero; +RAISE SQLSTATE '22012'; + + 在这种语法中,USING可以用来提供自定义的错误消息、细节或提示。另一种达到前面示例同样效果的方式是: RAISE unique_violation USING MESSAGE = 'Duplicate user ID: ' || user_id; - 如第四种语法变体所示,也可以写成RAISE USINGRAISE level USING,并把其余内容都放在USING列表里。 + 还有另一种变体是写RAISE USINGRAISE level USING,并把其余内容都放在USING列表里。 @@ -2923,7 +2855,7 @@ RAISE unique_violation USING MESSAGE = 'Duplicate user ID: ' || user_id; - 当用 SQLSTATE 代码指定错误代码时,你并不受限于预定义错误代码,而是可以选择任何由五位数字和/或大写 ASCII 字母构成的错误代码,唯一不能使用的是 00000。我们建议尽量避免抛出以三个零结尾的错误代码,因为这些是类别代码,只能用于捕获整个类别。 + 当用 SQLSTATE 代码指定错误代码时,你并不受限于预定义错误代码,而是可以选择任何由五位数字和/或大写 ASCII 字母构成的错误代码,唯一不能使用的是 00000。我们建议尽量避免抛出以三个零结尾的错误代码,因为这些是类别代码,只能通过捕获整个类别来捕获这类错误。 @@ -2935,12 +2867,12 @@ RAISE unique_violation USING MESSAGE = 'Duplicate user ID: ' || user_id; ASSERT - in PL/pgSQL + 在 PL/pgSQL 中 - assertions - in PL/pgSQL + 断言 + 在 PL/pgSQL 中 @@ -2957,15 +2889,14 @@ ASSERT condition , condition是一个布尔 表达式,它被期望总是计算为真。如果确实如此, - ASSERT语句不会再做什么。但如果结果是假 - 或者空,那么将发生一个ASSERT_FAILURE异常(如果在计算 + ASSERT语句不会再做什么。但如果结果是假或者空值,那么将发生一个ASSERT_FAILURE异常(如果在计算 condition时发生错误, 它会被报告为一个普通错误)。 如果提供了可选的message, - 它是一个结果(如果非空)被用来替换默认错误消息文本 + 它是一个结果(如果不为 NULL)被用来替换默认错误消息文本 assertion failed的表达式(如果 condition失败)。 message表达式在 @@ -2998,7 +2929,7 @@ ASSERT condition , - PL/pgSQL可以被用来在数据更改或者数据库事件上定义触发器函数。触发器函数用CREATE FUNCTION命令创建,它被声明为一个没有参数并且返回类型为trigger(对于数据更改触发器)或者event_trigger(对于数据库事件触发器)的函数。名为PG_something的特殊局部变量将被自动创建用以描述触发该调用的条件。 + PL/pgSQL可以被用来在数据更改或者数据库事件上定义触发器函数。触发器函数用CREATE FUNCTION命令创建,它被声明为一个没有参数并且返回类型为trigger(对于数据更改触发器)或者event_trigger(对于数据库事件触发器)的函数。名为TG_something的特殊局部变量将被自动创建用以描述触发该调用的条件。 @@ -3009,115 +2940,104 @@ ASSERT condition , 数据更改触发器被声明为一个没有参数并且返回类型为trigger的函数。注意,如下所述,即便该函数准备接收一些在CREATE TRIGGER中指定的参数 — 这类参数通过TG_ARGV传递,也必须把它声明为没有参数。 - - 当一个PL/pgSQL函数当做触发器调用时,在顶层块会自动创建一些特殊变量。它们是: - - + 当一个PL/pgSQL函数作为触发器被调用时,会在顶层块中自动创建一些特殊变量。它们是: - NEW record + NEW - - 行级触发器中用于 INSERT/UPDATE 操作的新数据行。在语句级触发器和 DELETE 操作中,该变量为 null。 - + 数据类型为RECORD;该变量保存行级触发器中用于INSERT/UPDATE操作的新数据行。在语句级触发器和DELETE操作中,该变量为 null。 - OLD record + OLD - - 行级触发器中用于 UPDATE/DELETE 操作的旧数据行。在语句级触发器和 INSERT 操作中,该变量为 null。 - + 数据类型为RECORD;该变量保存行级触发器中用于UPDATE/DELETE操作的旧数据行。在语句级触发器和INSERT操作中,该变量为 null。 - TG_NAME name + TG_NAME - 被触发的触发器名称。 + 数据类型为 name;包含实际触发的触发器名称的变量。 - TG_WHEN text + TG_WHEN - 根据触发器定义,其值为 BEFOREAFTERINSTEAD OF。 + 数据类型为 text;根据触发器定义,其值为字符串 BEFOREAFTERINSTEAD OF - TG_LEVEL text + TG_LEVEL - 根据触发器定义,其值为 ROWSTATEMENT。 + 数据类型为 text;根据触发器定义,其值为字符串 ROWSTATEMENT - TG_OP text + TG_OP - 触发器对应的操作:INSERTUPDATEDELETETRUNCATE。 + 数据类型为 text;表示触发器对应操作的字符串:INSERTUPDATEDELETETRUNCATE - TG_RELID oid(引用 pg_class.oid + TG_RELID - - 导致触发器调用的表的对象 ID。 - + 数据类型为oid;导致触发器调用的表的对象 ID。 - TG_RELNAME name + TG_RELNAME - 导致触发器调用的表名。该变量已弃用,未来版本可能移除;请改用 TG_TABLE_NAME。 + 数据类型为 name;导致触发器调用的表名。该变量已弃用,未来版本可能移除;请改用 TG_TABLE_NAME - TG_TABLE_NAME name + TG_TABLE_NAME - 导致触发器调用的表名。 + 数据类型为 name;导致触发器调用的表名。 - TG_TABLE_SCHEMA name + TG_TABLE_SCHEMA - 导致触发器调用的表所在模式名。 + 数据类型为 name;导致触发器调用的表所在模式名。 - TG_NARGS integer + TG_NARGS - CREATE TRIGGER 语句中传给触发器函数的参数个数。 + 数据类型为 integerCREATE TRIGGER 语句中传给触发器函数的参数个数。 - TG_ARGV text[] + TG_ARGV[] - - 来自 CREATE TRIGGER 语句的参数。索引从 0 开始;非法索引(小于 0 或大于等于 tg_nargs)返回 null。 - + 数据类型为text数组;来自CREATE TRIGGER语句的参数。索引从 0 开始;非法索引(小于 0 或大于等于tg_nargs)返回 null。 @@ -3132,11 +3052,11 @@ ASSERT condition , - INSTEAD OF触发器(总是行级触发器,并且可能只被用于视图)能够返回空来表示它们没有执行任何更新,并且对该行剩余的操作可以被跳过(即后续的触发器不会被引发,并且该行不会被计入外围INSERT/UPDATE/DELETE的行影响状态中)。否则一个非空值应该被返回用以表示该触发器执行了所请求的操作。对于INSERTUPDATE操作,返回值应该是NEW,触发器函数可能对它进行了修改来支持INSERT RETURNINGUPDATE RETURNING(这也将影响被传递给任何后续触发器的行值,或者被传递给带有ON CONFLICT DO UPDATEINSERT语句中一个特殊的EXCLUDED别名引用)。对于DELETE操作,返回值应该是OLD。 + INSTEAD OF触发器(总是行级触发器,并且只能用于视图)能够返回 null 来表示它们没有执行任何更新,并且对该行剩余的操作应被跳过(即后续的触发器不会被引发,并且该行不会被计入外围INSERT/UPDATE/DELETE的行影响状态中)。否则应该返回一个非 null 值用以表示该触发器执行了所请求的操作。对于INSERTUPDATE操作,返回值应该是NEW,触发器函数可能对它进行了修改来支持INSERT RETURNINGUPDATE RETURNING(这也将影响被传递给任何后续触发器的行值,或者被传递给带有ON CONFLICT DO UPDATEINSERT语句中一个特殊的EXCLUDED别名引用)。对于DELETE操作,返回值应该是OLD - 一个AFTER行级触发器或一个BEFOREAFTER语句级触发器的返回值总是会被忽略,它可能也是空。不过,任何这些类型的触发器可能仍会通过抛出一个错误来中止整个操作。 + 一个AFTER行级触发器或一个BEFOREAFTER语句级触发器的返回值总是会被忽略,因此也可以返回 null。不过,任何这些类型的触发器可能仍会通过抛出一个错误来中止整个操作。 @@ -3310,11 +3230,10 @@ INSTEAD OF INSERT OR UPDATE OR DELETE ON emp_view - - 一个 <application>PL/pgSQL</application> 用于维护汇总表的触发器函数 + 一个用于维护汇总表的 <application>PL/pgSQL</application> 触发器函数 - 这里详述的模式有一部分是基于 Ralph Kimball 所作的数据仓工具包中的Grocery Store示例。 + 这里详述的模式有一部分是基于 Ralph Kimball 所作的数据仓库工具包中的Grocery Store示例。 @@ -3457,7 +3376,7 @@ SELECT * FROM sales_summary_bytime; 使用过渡表审计 - 这个示例产生和相同的结果,但并未使用一个为每一行都触发的触发器,而是在把相关信息收集到一个过渡表中之后用了一个只为每个语句引发一次的触发器。当调用语句修改了很多行时,这种方法明显比行触发器方法快。注意我们必须为每一种事件建立一个单独的触发器声明,因为每种情况的REFERENCING子句必须不同。但是这并不能阻止我们使用单一的触发器函数(实际上,使用三个单独的函数会更好,因为可以避免在TG_OP上的运行时测试)。 + 这个示例产生和相同的结果,但并未使用一个为每一行都触发的触发器,而是在把相关信息收集到一个过渡表中之后用了一个只为每个语句引发一次的触发器。当调用语句修改了很多行时,这种方法可能显著快于行触发器方法。注意我们必须为每一种事件建立一个单独的触发器声明,因为每种情况的REFERENCING子句必须不同。但是这并不能阻止我们使用单一的触发器函数(实际上,使用三个单独的函数可能会更好,因为可以避免在TG_OP上的运行时测试)。 @@ -3519,24 +3438,21 @@ CREATE TRIGGER emp_audit_del PL/pgSQL可以被用来定义事件触发器。PostgreSQL要求一个可以作为事件触发器调用的函数必须被声明为没有参数并且返回类型为event_trigger - - 当一个PL/pgSQL函数被作为一个事件触发器调用,在顶层块中会自动创建一些特殊变量。它们是: - - + 当一个PL/pgSQL函数作为事件触发器被调用时,会在顶层块中自动创建一些特殊变量。它们是: - TG_EVENT text + TG_EVENT - 触发器被触发时对应的事件。 + 数据类型为 text;表示触发器被触发时对应事件的字符串。 - TG_TAG text + TG_TAG - 触发该触发器的命令标签。 + 数据类型为 text;包含触发该触发器的命令标签的变量。 @@ -3573,9 +3489,7 @@ CREATE EVENT TRIGGER snitch ON ddl_command_start EXECUTE FUNCTION snitch(); <application>PL/pgSQL</application> 内部机制 - - 这一节讨论了一些PL/pgSQL用户应该知道的一些重要的实现细节。 - + 本节讨论一些实现细节,了解这些细节对 PL/pgSQL 用户通常很重要。 @@ -3653,7 +3567,7 @@ CREATE FUNCTION stamp_user(id int, comment text) RETURNS void AS $$ END; $$ LANGUAGE plpgsql; - 在UPDATE命令中,curtimecomment以及id将引用该函数的变量和参数,不管users有没有这些名称的列。注意,我们不得不在WHERE子句中对users.id的引用加以限定,以便让它引用表列。但是我们不需要在UPDATE列表中把对comment的引用限定为一个目标,因为语法上那必须是users的一列。我们可以用下面的方式写一个相同的不依赖于variable_conflict设置的函数: + 在UPDATE命令中,curtimecomment以及id将引用该函数的变量和参数,不管users有没有这些名称的列。注意,我们不得不在WHERE子句中对users.id的引用加以限定,以便让它引用表列。但是我们不需要对UPDATE列表中作为目标的comment引用加以限定,因为语法上那必须是users的一列。我们可以用下面的方式写一个相同的不依赖于variable_conflict设置的函数: CREATE FUNCTION stamp_user(id int, comment text) RETURNS void AS $$ <<fn>> @@ -3672,7 +3586,7 @@ $$ LANGUAGE plpgsql; - 目前,变量替换只在 SELECTINSERTUPDATEDELETEMERGE 以及包含其中之一的命令中生效(例如 EXPLAINCREATE TABLE ... AS SELECT),因为主 SQL 引擎只允许在这些命令中使用查询参数。若要在其他语句类型(统称为实用语句)中使用非常量名称或值,就必须把该实用语句构造为字符串,再用 EXECUTE 执行。 + 目前,变量替换只在 SELECTINSERTUPDATEDELETEMERGE 以及包含其中之一的命令中生效(例如 EXPLAINCREATE TABLE ... AS SELECT),因为主 SQL 引擎只允许在这些命令中使用查询参数。若要在其他语句类型(统称为工具语句)中使用非常量名称或值,就必须把该工具语句构造为字符串,再用 EXECUTE 执行。 @@ -3694,7 +3608,7 @@ $$ LANGUAGE plpgsql; - PL/pgSQL(更准确地说,是 SPI 管理器)还会尝试缓存与某个预备语句相关的执行计划。如果没有使用缓存计划,那么每次执行该语句时都会生成新的执行计划,而当前参数值(也就是 PL/pgSQL 变量值)可用于优化所选计划。如果该语句没有参数,或者会被执行很多次,SPI 管理器就会考虑创建一个不依赖具体参数值的通用计划,并将其缓存起来供重复使用。通常只有在执行计划对其中引用的 PL/pgSQL 变量值不太敏感时,才会这样做。如果执行计划对参数值非常敏感,那么每次重新生成计划总体上反而更划算。关于预备语句的行为,详见 。 + PL/pgSQL(更准确地说,是 SPI 管理器)还可以尝试缓存与某个预备语句相关的执行计划。如果没有使用缓存计划,那么每次执行该语句时都会生成新的执行计划,而当前参数值(也就是 PL/pgSQL 变量值)可用于优化所选计划。如果该语句没有参数,或者会被执行很多次,SPI 管理器就会考虑创建一个不依赖具体参数值的通用计划,并将其缓存起来供重复使用。通常只有在执行计划对其中引用的 PL/pgSQL 变量值不太敏感时,才会这样做。如果执行计划对参数值非常敏感,那么每次重新生成计划总体上反而更划算。关于预备语句的行为,详见 @@ -3743,7 +3657,7 @@ $$ LANGUAGE plpgsql; - 在logfunc2中,PostgreSQL的主解析器不知道应该把'now'解释成什么类型,因此返回一个text类型的数据值,其中包含字符串now。在确定对本地变量curtime的赋值时,PL/pgSQL解释器通过调用用于该转换的textouttimestamp_in函数,把这个字符串转换为timestamp类型。因此,计算得到的时间戳会按程序员预期在每次执行时更新。虽然这恰好能得到预期结果,但效率并不高,因此使用now()函数仍然是更好的主意。 + 在logfunc2中,PostgreSQL的主解析器不知道应该把'now'解释成什么类型,因此返回一个text类型的数据值,其中包含字符串now。在随后给局部变量curtime赋值时,PL/pgSQL解释器通过调用用于该转换的textouttimestamp_in函数,把这个字符串转换为timestamp类型。因此,计算得到的时间戳会按程序员预期在每次执行时更新。虽然这恰好能得到预期结果,但效率并不高,因此使用now()函数仍然是更好的主意。 @@ -3772,7 +3686,7 @@ $$ LANGUAGE plpgsql; - 另一种开发PL/pgSQL的好方法,是使用有助于过程语言开发的 GUI 数据库访问工具。这类工具的一个例子是pgAdmin,当然也有其他工具。它们通常提供一些方便的特性,例如转义单引号,以及让重新创建和调试函数变得更容易。 + 另一种使用PL/pgSQL进行开发的好方法,是使用有助于过程语言开发的 GUI 数据库访问工具。这类工具的一个例子是pgAdmin,当然也有其他工具。它们通常提供一些方便的特性,例如转义单引号,以及让重新创建和调试函数变得更容易。 @@ -3780,7 +3694,7 @@ $$ LANGUAGE plpgsql; 引号的处理 - 一个PL/pgSQL函数的代码在一个CREATE FUNCTION中被指定为一个字符串。如果你用通常的方式把该字符串写在单引号中间,那么该函数体中的任何单引号都必须被双写;同样任何反斜线也必须被双写(假定使用了转义字符串语法)。双写引号最多有点冗长,并且在更复杂的情况中代码会变得完全无法理解,因为你很容易发现你需要半打或者更多相邻的引号。我们推荐你转而把函数体写成一个美元引用的字符串(见)。在美元引用方法中,你从不需要双写任何引号。但是要注意为你需要的每一层嵌套选择一个不同的美元引用定界符。例如,你可能把CREATE FUNCTION命令写成: + 一个PL/pgSQL函数的代码在一个CREATE FUNCTION中被指定为一个字符串字面量。如果你用通常的方式把该字符串写在单引号中间,那么该函数体中的任何单引号都必须被双写;同样任何反斜线也必须被双写(假定使用了转义字符串语法)。双写引号本身就很繁琐,并且在更复杂的情况中代码会变得完全无法理解,因为你很容易发现你需要半打或者更多相邻的引号。我们推荐你转而把函数体写成一个美元引用的字符串(见)。在美元引用方法中,你从不需要双写任何引号。但是要注意为你需要的每一层嵌套选择一个不同的美元引用定界符。例如,你可能把CREATE FUNCTION命令写成: CREATE OR REPLACE FUNCTION testfunc(integer) RETURNS integer AS $PROC$ .... @@ -3817,7 +3731,7 @@ CREATE FUNCTION foo() RETURNS integer AS ' - 用于函数体内的字符串,例如: + 用于函数体内的字符串字面量,例如: a_output := ''Blah''; SELECT * FROM users WHERE f_name=''foobar''; @@ -3827,7 +3741,7 @@ SELECT * FROM users WHERE f_name=''foobar''; a_output := 'Blah'; SELECT * FROM users WHERE f_name='foobar'; - 这恰好就是PL/pgSQL在两种情况中会看到的。 + 这恰好就是PL/pgSQL解析器在两种情况中会看到的。 @@ -3850,7 +3764,7 @@ a_output := a_output || '' AND name LIKE ''''foobar'''' AND xyz'' a_output := a_output || $$ AND name LIKE 'foobar' AND xyz$$ - 要小心在这周围的任何美元引用定界符不只是$$。 + 要小心在这周围的任何美元引用定界符都不能是$$ @@ -3883,7 +3797,7 @@ a_output := a_output || $$ AND name LIKE 'foobar'$$ - 当你想在一个字符串常量(占 8 个引号)中有两个单引号时并且这会挨着该字符串常量的末尾(另外 2 个)。如果你正在写一个产生其他函数的函数(如中),你将很可能只需要这种。例如: + 当字符串常量中需要两个单引号(这需要 8 个引号),而且它们紧邻该字符串常量的末尾(还需 2 个引号)时。通常只有在编写生成其他函数的函数时(如所示),才会需要这种写法。例如: a_output := a_output || '' if v_'' || referrer_keys.kind || '' like '''''''''' @@ -3925,9 +3839,7 @@ a_output := a_output || $$ if v_$$ || referrer_keys.kind || $$ like '$$ 因此建议你在一个单独的开发环境中进行测试。 - - 根据需要设置 plpgsql.extra_warningsplpgsql.extra_errors,适当情况下,在开发和/或测试环境中可以设置为 "all"。 - + 建议在开发和/或测试环境中,根据需要将 plpgsql.extra_warningsplpgsql.extra_errors 设置为 "all" 这些额外的检查通过配置变量plpgsql.extra_warnings来启用警告, @@ -3947,10 +3859,10 @@ a_output := a_output || $$ if v_$$ || referrer_keys.kind || $$ like '$$ strict_multi_assignment - 一些PL/pgSQL命令允许一次为多个变量赋值, + 一些PL/PgSQL命令允许一次为多个变量赋值, 例如SELECT INTO。通常,目标变量的数量和源变量的数量应该匹配, - 尽管PL/pgSQL会对缺失的值使用NULL, - 并且额外的变量会被忽略。启用此检查将导致PL/pgSQL + 尽管PL/PgSQL会对缺失的值使用NULL, + 并且额外的变量会被忽略。启用此检查将导致PL/PgSQL 在目标变量的数量和源变量的数量不同时抛出WARNINGERROR @@ -3960,7 +3872,7 @@ a_output := a_output || $$ if v_$$ || referrer_keys.kind || $$ like '$$ too_many_rows - 启用此检查将导致PL/pgSQL检查给定查询在使用INTO子句时是否返回多行。 + 启用此检查将导致PL/PgSQL检查给定查询在使用INTO子句时是否返回多行。 由于INTO语句只会使用一行,当查询返回多行时通常是低效和/或不确定性的,因此很可能是错误的。 @@ -4041,18 +3953,16 @@ HINT: Make sure the query returns the exact list of columns. - PL/pgSQL与 PL/SQL 在许多方面都非常类似。它是一种块结构的、命令式的语言并且所有变量必须先被声明。赋值、循环和条件则很类似。在从PL/SQLPL/pgSQL移植时必须记住一些事情: - - + PL/pgSQL在许多方面都与 PL/SQL 类似。它是一种具有块结构的命令式语言,所有变量都必须声明。赋值、循环和条件语句也都很相似。在从PL/SQL移植到PL/pgSQL时,应当记住以下主要差异: - 如果一个 SQL 命令中使用的名字可能是一个表的列名或者是对一个函数中变量的引用,那么PL/SQL会将它当作一个列名。默认情况下, PL/pgSQL会抛出名称模糊的错误, 你可以指定plpgsql.variable_conflict=use_column来改变这一行为以匹配PL/SQL。如中所述。通常最好是首先避免这种歧义,但如果不得不移植依赖于该行为的大量代码,那么设置variable_conflict将是最好的方案。 + 如果一个 SQL 命令中使用的名字可能是一个表的列名或者是对一个函数中变量的引用,那么PL/SQL会将它当作一个列名。默认情况下, PL/pgSQL会抛出名称有歧义的错误, 你可以指定plpgsql.variable_conflict=use_column来改变这一行为以匹配PL/SQL。如中所述。通常最好是首先避免这种歧义,但如果不得不移植依赖于该行为的大量代码,那么设置variable_conflict可能是最好的方案。 - 在PostgreSQL中,函数体必须写成字符串文本。因此你需要使用美元符引用或者转义函数体中的单引号(见)。 + 在PostgreSQL中,函数体必须写成字符串字面量。因此你需要使用美元符引用或者转义函数体中的单引号(见)。 @@ -4142,13 +4052,13 @@ show errors; - 在PostgreSQL中,函数体被认为是一个字符串,所以你需要使用引号或者美元符号包围它。这代替了Oracle 方法中的用于终止的/。 + 在PostgreSQL中,函数体被认为是一个字符串字面量,所以你需要使用引号或者美元引用定界符包围它。这代替了Oracle 方法中的用于终止的/ - 在PostgreSQL中没有show errors命令, 并且也不需要这个命令,因为错误是自动报告的。 + 在PostgreSQL中没有show errors命令, 并且也不需要这个命令,因为错误是自动报告的。 @@ -4180,9 +4090,7 @@ $$ LANGUAGE plpgsql; 从<application>PL/SQL</application>移植一个创建另一个函数的函数到<application>PL/pgSQL</application> - - 下面的过程从一个SELECT语句抓取行,并且为了效率而构建一个带有IF语句中结果的大型函数。 - + 下面的过程从 SELECT 语句读取行,并将结果写入 IF 语句,从而构造一个大型函数,以提高效率。 这是 Oracle 版本: @@ -4213,8 +4121,7 @@ show errors; - - 这里是PostgreSQL的版本: + 下面是这个函数的最终移植结果,目标数据库为PostgreSQL CREATE OR REPLACE PROCEDURE cs_update_referrer_type_proc() AS $func$ DECLARE @@ -4247,9 +4154,7 @@ BEGIN EXECUTE func_cmd; END; $func$ LANGUAGE plpgsql; - - 请注意,这里先单独构造了函数体,再通过 quote_literal 传入,以便把其中的引号正确双写。之所以需要这种技术,是因为我们无法安全地使用美元引用来定义新函数:我们并不确切知道会从 referrer_key.key_string 字段插入什么字符串。(这里假定 referrer_key.kind 始终可信地只会是 hostdomainurl,但 referrer_key.key_string 可能是任意内容,尤其可能包含美元符号。)实际上,这个函数比 Oracle 原版还有改进,因为当 referrer_key.key_stringreferrer_key.referrer_type 中包含引号时,它也不会生成无效代码。 - +注意,这里单独构造函数体,然后将其传给quote_literal,使其中的每个引号都变成两个。这种技术是必需的,因为不能安全地使用美元引用来定义新函数:我们无法确定会插入什么字符串,其来源是referrer_key.key_string字段。(这里假定referrer_key.kind可信,其值总是hostdomainurl,但是referrer_key.key_string可能是任何内容,尤其可能包含美元符号。)这个函数实际上改进了 Oracle 原版:当referrer_key.key_stringreferrer_key.referrer_type中包含引号时,它也不会生成有问题的代码。 @@ -4269,7 +4174,7 @@ $func$ LANGUAGE plpgsql; CREATE OR REPLACE PROCEDURE cs_parse_url( v_url IN VARCHAR2, - v_host OUT VARCHAR2, -- 这将被传回去 + v_host OUT VARCHAR2, -- 这个值将被返回 v_path OUT VARCHAR2, -- 这个也是 v_query OUT VARCHAR2) -- 还有这个 IS @@ -4312,9 +4217,9 @@ show errors; CREATE OR REPLACE FUNCTION cs_parse_url( v_url IN VARCHAR, - v_host OUT VARCHAR, -- 这将被传递回去 + v_host OUT VARCHAR, -- 这个值将被返回 v_path OUT VARCHAR, -- 这个也是 - v_query OUT VARCHAR) -- 以及这个 + v_query OUT VARCHAR) -- 还有这个 AS $$ DECLARE a_pos1 INTEGER; @@ -4357,7 +4262,7 @@ SELECT * FROM cs_parse_url('http://foobar.com/query.cgi?baz'); - 展示了如何移植一个使用了多种 Oracle 特性的过程。 + 展示了如何移植一个使用了多种 Oracle 专属特性的过程。 @@ -4397,7 +4302,7 @@ show errors - 这是我们如何将这个过程移植到PL/pgSQL: + 下面展示了如何将这个过程移植到PL/pgSQL CREATE OR REPLACE PROCEDURE cs_create_job(v_job_id integer) AS $$ @@ -4472,7 +4377,7 @@ EXCEPTION END; - 如果你正在移植一个以这种方式使用SAVEPOINTROLLBACK TO的 Oracle 过程,工作会比较简单:只要忽略SAVEPOINTROLLBACK TO即可。如果你的 Oracle 过程以不同方式使用SAVEPOINTROLLBACK TO,那就需要认真思考了。 + 如果你正在移植一个以这种方式使用SAVEPOINTROLLBACK TO的 Oracle 过程,工作会比较简单:只要省略SAVEPOINTROLLBACK TO即可。如果你的 Oracle 过程以不同方式使用SAVEPOINTROLLBACK TO,那就需要认真思考了。 @@ -4489,11 +4394,11 @@ END; 优化 <application>PL/pgSQL</application> 函数 - PostgreSQL提供了两种函数创建修饰符来优化执行:volatility(对于给定的相同参数,函数是否总是返回相同的结果)以及strictness (如果任何参数为空,函数是否返回空)。详见参考页。 + PostgreSQL提供了两种函数创建修饰符来优化执行:volatility(对于给定的相同参数,函数是否总是返回相同的结果)以及strictness (如果任何参数为空值,函数是否返回空值)。详见参考页。 - 在利用这些优化属性时,你的CREATE FUNCTION语句应该看起来像这样: + 在利用这些优化属性时,你的CREATE FUNCTION语句可能像这样: CREATE FUNCTION foo(...) RETURNS integer AS $$ diff --git a/zh/15/plpython.sgml b/zh/15/plpython.sgml index 085e65e9..bb019320 100644 --- a/zh/15/plpython.sgml +++ b/zh/15/plpython.sgml @@ -45,7 +45,7 @@ CREATE FUNCTION funcname (argument-list) RETURNS return-type AS $$ - # PL/Python function body + # PL/Python 函数体 $$ LANGUAGE plpython3u; @@ -85,7 +85,7 @@ def __plpython_procedure_pymax_23456(): CREATE FUNCTION pystrip(x text) RETURNS text AS $$ - x = x.strip() # error + x = x.strip() # 错误 return x $$ LANGUAGE plpython3u; @@ -95,7 +95,7 @@ CREATE FUNCTION pystrip(x text) RETURNS text AS $$ global x - x = x.strip() # ok now + x = x.strip() # 现在可以正常工作 return x $$ LANGUAGE plpython3u; @@ -216,7 +216,7 @@ $$ LANGUAGE plpython3u; 如果把 SQL 空值空值在 PL/Python 中传给函数,参数值在 Python 中会显示为None。例如,中展示的pymax定义在处理空输入时就会返回错误结果。我们可以在函数定义中添加STRICT,让PostgreSQL做出更合理的处理:如果传入空值,函数根本不会被调用,而是自动返回空结果。另一种办法是在函数体中检查空输入: + sortas="PL/Python">在 PL/Python 中传给函数,参数值在 Python 中会显示为None。例如,中展示的pymax定义在处理空值输入时就会返回错误结果。我们可以在函数定义中添加STRICT,让PostgreSQL做出更合理的处理:如果传入空值,函数根本不会被调用,而是自动返回空值结果。另一种办法是在函数体中检查空值输入: CREATE FUNCTION pymax (a integer, b integer) @@ -329,21 +329,21 @@ CREATE TYPE named_value AS ( ); - 组合结果可以按以下形式返回: + 复合结果可以按以下形式返回: 序列类型(元组或列表,但不能是集合,因为集合不可通过索引访问) - 返回的序列对象必须包含与组合结果类型字段数相同的项。索引为 0 的项会赋给复合类型的第一个字段,索引为 1 的项赋给第二个字段,依此类推。例如: + 返回的序列对象必须包含与复合结果类型字段数相同的项。索引为 0 的项会赋给复合类型的第一个字段,索引为 1 的项赋给第二个字段,依此类推。例如: CREATE FUNCTION make_pair (name text, value integer) RETURNS named_value AS $$ return ( name, value ) - # or alternatively, as list: return [ name, value ] + # 也可以使用列表: return [ name, value ] $$ LANGUAGE plpython3u; @@ -391,7 +391,7 @@ AS $$ self.value = v return named_value(name, value) - # or simply + # 或者简写为 class nv: pass nv.name = name nv.value = value @@ -452,8 +452,8 @@ CREATE TYPE greeting AS ( CREATE FUNCTION greet (how text) RETURNS SETOF greeting AS $$ - # return tuple containing lists as composite types - # all other combinations work also + # 返回包含列表的元组,以列表表示复合类型 + # 其他组合方式也都可用 return ( [ how, "World" ], [ how, "PostgreSQL" ], [ how, "PL/Python" ] ) $$ LANGUAGE plpython3u; @@ -511,7 +511,7 @@ $$ LANGUAGE plpython3u; - 也支持带OUT参数的返回集函数(使用RETURNS SETOF record)。例如: + 也支持带OUT参数的集合返回函数(使用RETURNS SETOF record)。例如: CREATE FUNCTION multiout_simple_setof(n integer, OUT integer, OUT integer) RETURNS SETOF record AS $$ return [(1, 2)] * n @@ -546,7 +546,7 @@ SELECT * FROM multiout_simple_setof(3); DO $$ - # PL/Python code + # PL/Python 代码 $$ LANGUAGE plpython3u; @@ -795,7 +795,7 @@ CREATE FUNCTION usesavedplan() RETURNS trigger AS $$ else: plan = plpy.prepare("SELECT 1") SD["plan"] = plan - # rest of function + # 函数的其余部分 $$ LANGUAGE plpython3u; @@ -812,11 +812,11 @@ $$ LANGUAGE plpython3u; - 游标对象提供fetch方法,它接受一个整数参数并返回结果对象。每次调用fetch,返回对象都会包含下一批行,数量不会超过该参数值。一旦所有行都已取完,fetch就会开始返回空结果对象。游标对象还提供迭代器接口,每次产生一行,直到所有行为止。以这种方式获取的数据不会作为结果对象返回,而是以字典形式返回,每个字典对应一行结果。 + 游标对象提供fetch方法,它接受一个整数参数并返回结果对象。每次调用fetch,返回对象都会包含下一批行,数量不会超过该参数值。一旦所有行都已取完,fetch就会开始返回空结果对象。游标对象还提供迭代器接口,每次产生一行,直到取完所有行。以这种方式获取的数据不会作为结果对象返回,而是以字典形式返回,每个字典对应一行结果。 - 下面示例展示了如何处理大表中的数据: + 下面示例展示了处理大表中数据的两种方式: CREATE FUNCTION count_odd_iterator() RETURNS integer AS $$ odd = 0 @@ -842,7 +842,7 @@ $$ LANGUAGE plpython3u; CREATE FUNCTION count_odd_prepared() RETURNS integer AS $$ odd = 0 plan = plpy.prepare("select num from largetable where num % $1 <> 0", ["integer"]) -rows = list(plpy.cursor(plan, [2])) # or: = list(plan.cursor([2])) +rows = list(plpy.cursor(plan, [2])) # 或者:= list(plan.cursor([2])) return len(rows) $$ LANGUAGE plpython3u; @@ -995,7 +995,7 @@ CALL transaction_test1(); - 实用函数 + 辅助函数 plpy模块还提供以下函数: @@ -1049,7 +1049,7 @@ PL/Python function "raise_custom_exception" - 另一组实用函数是plpy.quote_literal(string)plpy.quote_nullable(string)以及plpy.quote_ident(string)。它们等价于中描述的内置引用函数。在构造临时查询时,这些函数很有用。中动态 SQL 的一个 PL/Python 等价写法如下: + 另一组辅助函数是plpy.quote_literal(string)plpy.quote_nullable(string)以及plpy.quote_ident(string)。它们等价于中描述的内置加引号函数。在构造临时查询时,这些函数很有用。中动态 SQL 的一个 PL/Python 等价写法如下: plpy.execute("UPDATE tbl SET %s = %s WHERE key = %s" % ( plpy.quote_ident(colname), diff --git a/zh/15/pltcl.sgml b/zh/15/pltcl.sgml index d4e0e94c..19d660db 100644 --- a/zh/15/pltcl.sgml +++ b/zh/15/pltcl.sgml @@ -13,7 +13,7 @@ - PL/Tcl 是一种适用于 PostgreSQL 数据库系统的可载入的过程语言,它允许使用 Tcl 语言 来编写 PostgreSQL 函数和过程。 + PL/Tcl 是一种适用于 PostgreSQL 数据库系统的可加载的过程语言,它允许使用 Tcl 语言 来编写 PostgreSQL 函数和过程。 @@ -54,7 +54,7 @@ CREATE FUNCTION funcname (argument-types) RETURNS return-type AS $$ - # PL/Tcl function body + # PL/Tcl 函数体 $$ LANGUAGE pltcl; @@ -75,11 +75,11 @@ CREATE FUNCTION tcl_max(integer, integer) RETURNS integer AS $$ $$ LANGUAGE pltcl STRICT; - 注意STRICT子句,它让我们不必考虑空输入值:如果传入的是空值,函数根本不会被调用,而是会自动返回空结果。 + 注意STRICT子句,它让我们不必考虑空值输入:如果传入的是空值,函数根本不会被调用,而是会自动返回空值结果。 - 在非严格函数中,如果某个参数的实际值为空,对应的$n变量会被设置为空串。要检测某个特定参数是否为空,可使用函数argisnull。例如,假设我们希望在tcl_max的两个参数中一个为空、一个非空时返回非空参数,而不是返回空值: + 在非严格函数中,如果某个参数的实际值为空值,对应的$n变量会被设置为空串。要检测某个特定参数是否为空值,可使用函数argisnull。例如,假设我们希望在tcl_max的两个参数中一个为空值、一个非空值时返回非空值参数,而不是返回空值: CREATE FUNCTION tcl_max(integer, integer) RETURNS integer AS $$ @@ -99,7 +99,7 @@ $$ LANGUAGE pltcl; - 复合类型参数会作为 Tcl 数组传递给函数。数组元素名就是该复合类型的属性名。如果传入行中的某个属性为 NULL,它就不会出现在数组中。下面是一个示例: + 复合类型参数会作为 Tcl 数组传递给函数。数组元素名就是该复合类型的属性名。如果传入行中的某个属性为空值,它就不会出现在数组中。下面是一个示例: CREATE TABLE employee ( @@ -185,7 +185,7 @@ $$ LANGUAGE pltcl; PL/Tcl 中的数据值 - 提供给 PL/Tcl 函数代码的参数值,只是将输入参数转换成文本形式(就像用SELECT语句将它们显示出来一样)。反过来,returnreturn_next命令会接受任何字符串,只要它是该函数声明结果类型或组合结果类型中指定列的可接受输入格式。 + 提供给 PL/Tcl 函数代码的参数值,只是将输入参数转换成文本形式(就像用SELECT语句将它们显示出来一样)。反过来,returnreturn_next命令会接受任何字符串,只要它是该函数声明结果类型或复合结果类型中指定列的可接受输入格式。 @@ -195,8 +195,8 @@ $$ LANGUAGE pltcl; PL/Tcl 中的全局数据 - global data - in PL/Tcl + 全局数据 + 在 PL/Tcl 中 @@ -234,7 +234,7 @@ $$ LANGUAGE pltcl; - 执行以字符串形式给出的 SQL 命令。命令出错时会引发错误。否则,spi_exec的返回值是该命令处理的行数(选出、插入、更新或删除的行),如果命令是实用程序语句则返回零。此外,如果命令是SELECT语句,则所选列的值会按下文所述放入 Tcl 变量中。 + 执行以字符串形式给出的 SQL 命令。命令出错时会引发错误。否则,spi_exec的返回值是该命令处理的行数(选出、插入、更新或删除的行),如果命令是工具语句则返回零。此外,如果命令是SELECT语句,则所选列的值会按下文所述放入 Tcl 变量中。 @@ -275,7 +275,7 @@ spi_exec -array C "SELECT * FROM pg_class" { - 如果查询结果中的某一列为空,则对应的目标变量会被unset,而不是被设值。 + 如果查询结果中的某一列为空值,则对应的目标变量会被unset,而不是被设值。 @@ -287,7 +287,7 @@ spi_exec -array C "SELECT * FROM pg_class" { 准备并保存一个查询计划以供后续执行。保存的计划会在当前会话的整个生命周期内保留。 准备查询 - 在PL/Tcl中 + 在 PL/Tcl 中 @@ -317,7 +317,7 @@ spi_exec -array C "SELECT * FROM pg_class" { 可选的-nulls值是由空格和'n'字符组成的字符串,用来告诉spi_execp哪些参数是空值。 - 如果给出,它的长度必须与value-list完全相同。如果未给出,则所有参数值都视为非空。 + 如果给出,它的长度必须与value-list完全相同。如果未给出,则所有参数值都视为非空值。 @@ -331,7 +331,7 @@ spi_exec -array C "SELECT * FROM pg_class" { CREATE FUNCTION t1_count(integer, integer) RETURNS integer AS $$ if {![ info exists GD(plan) ]} { - # prepare the saved plan on the first call + # 在首次调用时准备并保存计划 set GD(plan) [ spi_prepare \ "SELECT count(*) AS cnt FROM t1 WHERE num >= \$1 AND num <= \$2" \ [ list int4 int4 ] ] @@ -367,7 +367,7 @@ $$ LANGUAGE pltcl; 将给定字符串中的所有单引号和反斜杠字符都加倍。 - 这可用于安全地引用那些要插入到传给spi_execspi_prepare的 SQL 命令中的字符串。 + 这可用于安全地为那些要插入到传给spi_execspi_prepare的 SQL 命令中的字符串加引号。 例如,考虑如下 SQL 命令字符串: @@ -393,7 +393,7 @@ SELECT 'doesn''t' AS ret "SELECT '[ quote $val ]' AS ret" - spi_execp的一个优点是,你不必像这样对参数值做引用,因为这些参数永远不会作为 SQL 命令字符串的一部分被解析。 + spi_execp的一个优点是,你不必像这样给参数值加引号,因为这些参数永远不会作为 SQL 命令字符串的一部分被解析。 @@ -404,7 +404,7 @@ SELECT 'doesn''t' AS ret elog level msg elog - 在PL/Tcl中 + 在 PL/Tcl 中 @@ -436,8 +436,8 @@ SELECT 'doesn''t' AS ret PL/Tcl 中的触发器函数 - trigger - in PL/Tcl + 触发器 + 在 PL/Tcl 中 @@ -525,7 +525,7 @@ SELECT 'doesn''t' AS ret $NEW - 对于INSERTUPDATE动作,这是一个包含新表行值的关联数组;对于DELETE则为空。该数组以列名为索引。值为 NULL 的列不会出现在数组中。对于语句级触发器,不会设置这个变量。 + 对于INSERTUPDATE动作,这是一个包含新表行值的关联数组;对于DELETE则为空。该数组以列名为索引。值为空值的列不会出现在数组中。对于语句级触发器,不会设置这个变量。 @@ -534,7 +534,7 @@ SELECT 'doesn''t' AS ret $OLD - 对于UPDATEDELETE动作,这是一个包含旧表行值的关联数组;对于INSERT则为空。该数组以列名为索引。值为 NULL 的列不会出现在数组中。对于语句级触发器,不会设置这个变量。 + 对于UPDATEDELETE动作,这是一个包含旧表行值的关联数组;对于INSERT则为空。该数组以列名为索引。值为空值的列不会出现在数组中。对于语句级触发器,不会设置这个变量。 @@ -598,8 +598,8 @@ CREATE TRIGGER trig_mytab_modcount BEFORE INSERT OR UPDATE ON mytab PL/Tcl 中的事件触发器函数 - event trigger - in PL/Tcl + 事件触发器 + 在 PL/Tcl 中 @@ -615,7 +615,7 @@ CREATE TRIGGER trig_mytab_modcount BEFORE INSERT OR UPDATE ON mytab $TG_event - 触发器因其而被触发的事件名称。 + 该触发器所针对的事件名称。 @@ -624,7 +624,7 @@ CREATE TRIGGER trig_mytab_modcount BEFORE INSERT OR UPDATE ON mytab $TG_tag - 触发器因其而被触发的命令标签。 + 该触发器所针对的命令标签。 @@ -632,7 +632,7 @@ CREATE TRIGGER trig_mytab_modcount BEFORE INSERT OR UPDATE ON mytab - 事件触发器函数的返回值会被忽略。 + 触发器函数的返回值会被忽略。 @@ -653,8 +653,8 @@ CREATE EVENT TRIGGER tcl_a_snitch ON ddl_command_start EXECUTE FUNCTION tclsnitc PL/Tcl 中的错误处理 - exceptions - in PL/Tcl + 异常 + 在 PL/Tcl 中 @@ -682,9 +682,9 @@ if {[catch { spi_exec $sql_command }]} { if {[lindex $::errorCode 0] == "POSTGRES"} { array set errorArray $::errorCode if {$errorArray(condition) == "undefined_table"} { - # deal with missing table + # 处理表不存在的情况 } else { - # deal with some other type of SQL error + # 处理其他类型的 SQL 错误 } } } @@ -698,8 +698,8 @@ if {[catch { spi_exec $sql_command }]} { PL/Tcl 中的显式子事务 - subtransactions - in PL/Tcl + 子事务 + 在 PL/Tcl 中 @@ -797,7 +797,7 @@ CALL transaction_test1(); pltcl.start_proc (string) - pltcl.start_proc configuration parameter + pltcl.start_proc 配置参数 @@ -825,7 +825,7 @@ CALL transaction_test1(); pltclu.start_proc (string) - pltclu.start_proc configuration parameter + pltclu.start_proc 配置参数 @@ -844,11 +844,7 @@ CALL transaction_test1(); Tcl 过程名 - 在PostgreSQL中,如果函数位于不同模式中,或者参数个数或参数类型不同,就可以复用同一个函数名。不过,Tcl 要求所有过程名都必须不同。PL/Tcl 处理这一问题的方式是:在内部 Tcl 过程名中包含参数类型名,并在必要时把函数对象 ID(OID)追加到内部 Tcl 过程名后面,以确保它与同一 Tcl 解释器中所有先前已装载的函数名都不同。因此,名称相同但参数类型不同的PostgreSQL函数,也会对应不同的 Tcl 过程。这通常不是 PL/Tcl 程序员需要关心的事情,但在调试时可能会看见。 - - - - 因此,再加上其他一些原因,一个 PL/Tcl 函数不能在 Tcl 内部直接调用另一个 PL/Tcl 函数。如果确实需要这样做,就必须通过 SQL 并使用spi_exec或相关命令来实现。 + 在PostgreSQL中,只要参数个数或参数类型不同,就可以复用同一个函数名。不过,Tcl 要求所有过程名都必须不同。PL/Tcl 处理这一问题的方式是:在内部 Tcl 过程名中包含系统表 pg_proc 中的函数对象 ID 作为其名称的一部分。因此,名称相同但参数类型不同的PostgreSQL函数,也会对应不同的 Tcl 过程。这通常不是 PL/Tcl 程序员需要关心的事情,但在调试时可能会看见。 diff --git a/zh/15/postgres-fdw.sgml b/zh/15/postgres-fdw.sgml index a1a33724..f6a2c39e 100644 --- a/zh/15/postgres-fdw.sgml +++ b/zh/15/postgres-fdw.sgml @@ -1,8 +1,7 @@ - postgres_fdw — - 访问存储在外部 <productname>PostgreSQL</productname> 服务器中的数据 + postgres_fdw postgres_fdw @@ -38,7 +37,7 @@ - 对于每个需要被允许访问各外部服务器的数据库用户,使用 + 对于每个需要获准访问各个外部服务器的数据库用户,使用 创建用户映射。将要使用的 远程用户名和密码指定为用户映射的 userpassword 选项。 @@ -56,7 +55,7 @@ - 现在,只需从外部表执行 SELECT,即可访问其底层远程表中 + 现在,只需对外部表执行 SELECT,即可访问其底层远程表中 存储的数据。也可以使用 INSERTUPDATEDELETECOPYTRUNCATE 修改远程表。 @@ -120,8 +119,7 @@ application_name 可以出现在连接选项和 - 中的任一处,或同时出现在 - 二者中。 + 中的任一处,或同时出现在二者中。 如果两者都存在,postgres_fdw.application_name 会覆盖连接设置。与 libpq 不同, postgres_fdw 允许 application_name @@ -149,11 +147,7 @@ 只有超级用户才能创建或修改带有 sslcertsslkey 设置的用户映射。 - - 非超级用户可以通过密码认证或使用 GSSAPI 委派凭据连接到外部服务器, - 因此在需要密码认证的场景中,应为属于非超级用户的用户映射指定 - password 选项。 - + 只有超级用户才能不使用密码认证连接到外部服务器,因此应始终为属于非超级用户的用户映射指定 password 选项。 超级用户可以通过设置用户映射选项 password_required 'false' 按用户映射单独覆盖此检查, @@ -172,7 +166,7 @@ OPTIONS (ADD password_required 'false'); password_required=false。还要记住,被映射用户可能 使用 postgres 服务器所运行的系统用户 unix 主目录中的任何客户端证书、 .pgpass.pg_service.conf - 等文件。(有关如何查找主目录的细节,见 。) + 等文件。 他们还可以利用通过 peerident 等认证方式授予的任何信任关系。 @@ -250,7 +244,7 @@ OPTIONS (ADD password_required 'false'); - fdw_startup_cost (floating point) + fdw_startup_cost (浮点数) 该选项可为外部服务器指定,是一个浮点值,会被加到该服务器上任何 @@ -261,13 +255,13 @@ OPTIONS (ADD password_required 'false'); - fdw_tuple_cost (floating point) + fdw_tuple_cost (浮点数) 该选项可为外部服务器指定,是一个浮点值,用作该服务器上外部表扫描的 每个元组的额外代价。它表示服务器之间数据传输的额外开销。可以增大或 减小该数值,以反映到远程服务器更高或更低的网络延迟。默认值为 - 0.2。 + 0.01 @@ -288,36 +282,6 @@ OPTIONS (ADD password_required 'false'); 但如果远程表经常更新,本地统计信息很快就会过时。 - - 以下选项控制这种 ANALYZE 操作的行为: - - - - - - analyze_sampling (string) - - - 该选项可为外部表或外部服务器指定,用于决定在外部表上执行 - ANALYZE 时,是在远程端对数据采样,还是读取并传输 - 所有数据后在本地采样。支持的取值为 off、 - randomsystem、 - bernoulliauto。 - off 禁用远程采样,因此所有数据都会被传输并在本地 - 采样。random 使用 random() - 函数选择返回的行,从而在远程端执行采样,而 system 和 - bernoulli 则依赖同名的内置 - TABLESAMPLE 方法。random 适用于 - 所有远程服务器版本,而 TABLESAMPLE 仅从 9.5 起 - 受支持。auto(默认值)会自动选择推荐的采样方法; - 当前意味着根据远程服务器版本选择 bernoulli 或 - random。 - - - - - - @@ -339,7 +303,7 @@ OPTIONS (ADD password_required 'false'); 该选项是一个以逗号分隔的 PostgreSQL 扩展 名称列表,这些扩展必须在本地和远程服务器上都已安装且版本兼容。 - 属于列出扩展且为 immutable 的函数和操作符,将被视为可下推到远程服务器 + 属于列出扩展且不可变的函数和操作符,将被视为可下推到远程服务器 执行。该选项只能为外部服务器指定,不能按表指定。 @@ -380,12 +344,6 @@ OPTIONS (ADD password_required 'false'); 会被调整,以避免报错。 - - 该选项也适用于向外部表执行 COPY。在这种情况下, - postgres_fdw 实际一次复制的行数会以与插入场景 - 类似的方式确定,但由于 COPY 命令的实现限制, - 最多只能为 1000 行。 - @@ -442,10 +400,10 @@ OPTIONS (ADD password_required 'false'); 如“事务管理”一节所述,在 postgres_fdw 中, 事务是通过创建对应的远程事务来管理的,子事务则通过创建对应的远程 子事务来管理。当当前本地事务涉及多个远程事务时,默认情况下, - postgres_fdw 会在本地事务提交或中止时串行提交 - 或中止这些远程事务。当当前本地子事务涉及多个远程子事务时,默认情况下, - postgres_fdw 也会在本地子事务提交或中止时串行 - 提交或中止这些远程子事务。使用以下选项可以改善性能: + postgres_fdw 会在本地事务提交时串行提交这些远程事务。 + 当当前本地子事务涉及多个远程子事务时,默认情况下, + postgres_fdw 也会在本地子事务提交时串行 + 提交这些远程子事务。使用以下选项可以改善性能: @@ -459,33 +417,21 @@ OPTIONS (ADD password_required 'false'); 此设置也适用于远程子事务和本地子事务。该选项只能为外部服务器指定, 不能按表指定。默认值为 false - - - - parallel_abort (boolean) - - 该选项控制在本地事务中止时,postgres_fdw - 是否并行中止该本地事务中在某个外部服务器上打开的远程事务。 - 此设置也适用于远程子事务和本地子事务。该选项只能为外部服务器指定, - 不能按表指定。默认值为 false。 + 如果启用了此选项的多个外部服务器参与同一个本地事务,那么在本地事务 + 提交时,这些外部服务器上的多个远程事务会跨服务器并行提交。 + + + + 启用此选项后,若某个外部服务器涉及很多远程事务,则在本地事务提交时, + 该外部服务器上的性能可能会受到负面影响。 - - 如果启用了这些选项的多个外部服务器参与同一个本地事务,那么在本地事务 - 提交或中止时,这些外部服务器上的多个远程事务会跨服务器并行提交或中止。 - - - - 启用这些选项后,若某个外部服务器涉及很多远程事务,则在本地事务提交 - 或中止时,该外部服务器上的性能可能会受到负面影响。 - - @@ -573,8 +519,7 @@ OPTIONS (ADD password_required 'false'); COLLATE 选项。默认值为 true。 如果远程服务器的排序规则名称集合与本地服务器不同,则可能需要关闭此 选项;如果远程服务器运行在不同操作系统上,这种情况尤其可能发生。 - 不过,如果这样做,导入表列的排序规则极有可能与底层数据不匹配, - 从而导致查询行为异常。 + 不过,如果这样做,导入表列的排序规则就存在与底层数据不匹配的严重风险,从而导致查询行为异常。 @@ -661,68 +606,6 @@ OPTIONS (ADD password_required 'false'); - - - use_scram_passthrough (boolean) - - - 该选项控制 postgres_fdw 在连接到外部服务器时 - 是否使用 SCRAM 透传认证。使用 SCRAM 透传认证时, - postgres_fdw 使用 SCRAM 哈希后的凭据,而不是 - 明文用户密码连接远程服务器。这样可以避免在 PostgreSQL 系统目录中 - 存储明文用户密码。 - - - - 要使用 SCRAM 透传认证: - - - - 远程服务器必须请求 scram-sha-256 认证方法; - 否则连接将失败。 - - - - - - 远程服务器可以是任何支持 SCRAM 的 PostgreSQL 版本。 - 对 use_scram_passthrough 的支持只要求客户端 - 一侧(FDW 侧)具备。 - - - - - - 用户映射密码不会被使用。 - - - - - - 运行 postgres_fdw 的服务器与远程服务器, - 必须针对用于在 postgres_fdw 上认证到外部 - 服务器的该用户,拥有完全相同的 SCRAM secret(加密密码) - (盐值和迭代次数都必须相同,而不仅仅是密码相同)。 - - - - 因而,如果要建立到多个主机的 FDW 连接,例如用于分区外部表或分片, - 则所有主机都必须为相关用户保存完全相同的 SCRAM secret。 - - - - - - 发起对外 FDW 连接的 PostgreSQL 实例中,当前会话的传入客户端连接 - 也必须使用 SCRAM 认证。(因此称为透传:SCRAM - 必须在进入和离开时都被使用。)这是 SCRAM 协议的技术要求。 - - - - - - - @@ -731,111 +614,22 @@ OPTIONS (ADD password_required 'false'); 函数 - - postgres_fdw_get_connections( - IN check_conn boolean DEFAULT false, OUT server_name text, - OUT user_name text, OUT valid boolean, OUT used_in_xact boolean, - OUT closed boolean, OUT remote_backend_pid int4) - returns setof record - - - 此函数返回 postgres_fdw 从本地会话到外部服务器所建立的所有打开连接的 - 信息。如果没有打开的连接,则不返回任何记录。 - - - 如果将 check_conn 设置为 true, - 该函数会检查每个连接的状态,并在 closed 列中显示 - 结果。该特性当前仅在支持对 poll 系统调用的非标准 - POLLRDHUP 扩展的系统上可用,包括 Linux。 - 这对于检查事务中使用的所有连接是否仍然打开很有帮助。如果任一连接已经 - 关闭,该事务将无法成功提交,因此在检测到关闭连接后,最好尽快回滚, - 而不是继续执行到末尾。如果函数报告的某个连接同时满足 - used_in_xactclosed 都为 - true,用户即可立即回滚事务。 - - - 此函数的用法示例: + + postgres_fdw_get_connections(OUT server_name text, OUT valid boolean) returns setof record + + + 此函数返回postgres_fdw从本地会话向外部服务器建立的所有打开连接的外部服务器名称。它还返回每个连接是否有效。如果外部服务器连接在当前本地事务中被使用,但其外部服务器或用户映射被更改或删除,则返回false(注意,如果服务器被删除,无效连接的服务器名称将为NULL),然后这样的无效连接将在该事务结束时被关闭。否则返回true。如果没有打开的连接,则不返回任何记录。 + 该函数的用法示例: -postgres=# SELECT * FROM postgres_fdw_get_connections(true); - server_name | user_name | valid | used_in_xact | closed | remote_backend_pid --------------+-----------+-------+--------------+----------------------------- - loopback1 | postgres | t | t | f | 1353340 - loopback2 | public | t | t | f | 1353120 - loopback3 | | f | t | f | 1353156 +postgres=# SELECT * FROM postgres_fdw_get_connections() ORDER BY 1; + server_name | valid +-------------+------- + loopback1 | t + loopback2 | f - 输出列见 。 - - -
- <function>postgres_fdw_get_connections</function> 输出列 - - - - - 类型 - 描述 - - - - - - server_name - text - - 此连接的外部服务器名称。如果服务器已被删除但连接仍保持打开 - (即被标记为无效),则该值为 NULL。 - - - - user_name - text - - 映射到此连接所属外部服务器的本地用户名称;如果使用的是 public - 映射,则为 public。 - 如果用户映射已被删除但连接仍保持打开(即被标记为无效),则该值为 - NULL。 - - - - valid - boolean - - 如果此连接无效,则为假;无效意味着它在当前事务中被使用,但其外部 - 服务器或用户映射已被更改或删除。无效连接将在事务结束时关闭。 - 否则返回真。 - - - - used_in_xact - boolean - - 如果此连接在当前事务中被使用,则为真。 - - - - closed - boolean - - 如果此连接已关闭,则为真,否则为假。如果 - check_conn 被设置为 false, - 或当前平台不提供连接状态检查,则返回 NULL。 - - - - remote_backend_pid - int4 - - 外部服务器上处理此连接的远程后端进程 ID。如果远程后端已终止且 - 连接已关闭(closedtrue), - 此处仍会显示该已终止后端的进程 ID。 - - - - -
- - - +
+ + postgres_fdw_disconnect(server_name text) returns boolean @@ -930,8 +724,7 @@ postgres=# SELECT postgres_fdw_disconnect_all();
- 请注意,postgres_fdw 当前不支持将远程事务预备为 - 两阶段提交。 + 请注意,postgres_fdw 当前不支持为两阶段提交预备远程事务。 @@ -942,9 +735,9 @@ postgres=# SELECT postgres_fdw_disconnect_all(); postgres_fdw 会尽力优化远程查询,以减少从外部 服务器传输的数据量。这是通过将查询的 WHERE 子句发送到 远程服务器执行,以及不获取当前查询不需要的表列来实现的。为降低查询被 - 错误执行的风险,除非 WHERE 子句仅使用内置数据类型、 - 操作符和函数,或属于外部服务器 extensions 选项列出的 - 扩展,否则不会将其发送到远程服务器。这类子句中的操作符和函数还必须是 + 错误执行的风险,只有当 WHERE 子句使用的所有数据类型、 + 操作符和函数都是内置的,或属于外部服务器 extensions + 选项列出的扩展时,才会将该子句发送到远程服务器。这类子句中的操作符和函数还必须是 IMMUTABLE。对于 UPDATEDELETE 查询,postgres_fdw 会在 查询中不存在无法发送到远程服务器的 WHERE 子句、没有 @@ -1029,8 +822,6 @@ postgres=# SELECT postgres_fdw_disconnect_all(); postgres_fdw 可用于最早追溯到 PostgreSQL 8.3 的远程服务器。只读能力可追溯到 8.1。 -
- 不过有一个限制是,postgres_fdw 通常假定: 如果外部表的 WHERE 子句中出现不可变的内置函数和 操作符,那么把它们发送到远程服务器执行是安全的。因此,某个在远程服务器 @@ -1040,51 +831,9 @@ postgres=# SELECT postgres_fdw_disconnect_all(); OFFSET 0 的子 SELECT 中,作为优化 栅栏,并将有问题的函数或操作符放到子 SELECT 之外。 - - 另一个限制是,在外部表上执行 INSERT 语句并带有 - ON CONFLICT DO NOTHING 子句时,远程服务器必须运行 - PostgreSQL 9.5 或更高版本,因为更早版本 - 不支持此特性。 - - - 等待事件 - - postgres_fdw 可以在等待事件类型 - Extension 下报告以下等待事件: - - - - - PostgresFdwCleanupResult - - - 等待远程服务器上的事务中止。 - - - - - - PostgresFdwConnect - - - 等待与远程服务器建立连接。 - - - - - - PostgresFdwGetResult - - - 等待接收来自远程服务器的查询结果。 - - - - - 配置参数 @@ -1094,7 +843,7 @@ postgres=# SELECT postgres_fdw_disconnect_all(); postgres_fdw.application_name (string) - postgres_fdw.application_name configuration parameter + postgres_fdw.application_name 配置参数 @@ -1105,13 +854,7 @@ postgres=# SELECT postgres_fdw_disconnect_all(); 修改此参数不会影响任何现有连接,除非这些连接重新建立。 - postgres_fdw.application_name 可以是任意长度的任意 - 字符串,甚至可以包含非 ASCII 字符。不过,当它被传递并作为外部服务器中 - 的 application_name 使用时,请注意它会被截断到少于 - NAMEDATALEN 个字符。所有不可打印 ASCII 字符都会被 - 替换为C 风格的十六进制逃逸。 - 有关细节见 。 + postgres_fdw.application_name 可以是任意长度的任意字符串,甚至可以包含非 ASCII 字符。不过,当它被传递并作为外部服务器中的 application_name 使用时,请注意它会被截断到少于 NAMEDATALEN 个字符,且除可打印 ASCII 字符以外的所有字符都会被替换为问号(?)。有关细节见 @@ -1162,7 +905,7 @@ postgres=# SELECT postgres_fdw_disconnect_all(); %% - 字面值 % + 字面字符 % diff --git a/zh/15/postgres.sgml b/zh/15/postgres.sgml index 0e167400..15cc69d9 100644 --- a/zh/15/postgres.sgml +++ b/zh/15/postgres.sgml @@ -114,6 +114,7 @@ &installbin; &installation; + &installw; &runtime; &config; &client-auth; @@ -124,6 +125,7 @@ &backup; &high-availability; &monitoring; + &diskusage; &wal; &logical-replication; &jit; diff --git a/zh/15/protocol.sgml b/zh/15/protocol.sgml index 08dea480..4fc039e7 100644 --- a/zh/15/protocol.sgml +++ b/zh/15/protocol.sgml @@ -226,11 +226,16 @@ 前端现在必须发送一个 PasswordMessage,其中包含密码;该密码先与用户名一起经过 MD5 加密,再使用 AuthenticationMD5Password 消息中指定的 4 字节随机盐重新加密。如果密码正确,服务器响应 AuthenticationOk;否则响应 ErrorResponse。实际的 PasswordMessage 可以用 SQL 计算:concat('md5', md5(concat(md5(concat(password, username)), random-salt)))。(请记住 md5() 函数返回的是十六进制字符串。) - - - 对 MD5 加密密码的支持已弃用,并将在未来版本 PostgreSQL 中移除。关于迁移到其他密码类型,请参阅 。 - - + + + + + + AuthenticationSCMCredential + + + 此响应仅适用于支持 SCM 凭据消息的平台上的本地 Unix 域连接。前端必须发出一条 SCM 凭据消息,然后发送一个单字节数据。(该数据字节的内容无关紧要;它仅用于确保服务器等待足够长的时间来接收凭据消息。)如果凭据可接受,服务器响应 AuthenticationOk;否则响应 ErrorResponse。(该消息类型仅由 9.1 之前的服务器发出。它最终可能会从协议规范中移除。) + @@ -832,28 +837,10 @@ SELCT 1/0; - 目前,系统会为以下参数发送 ParameterStatus: - - application_name - client_encoding - DateStyle - default_transaction_read_only - in_hot_standby - integer_datetimes - IntervalStyle - is_superuser - scram_iterations - search_path - server_encoding - server_version - session_authorization - standard_conforming_strings - TimeZone - - (default_transaction_read_onlyin_hot_standby 在 14 之前不报告; - scram_iterations 在 16 之前不报告; - search_path 在 18 之前不报告。) - 注意 server_versionserver_encodinginteger_datetimes 是启动后不可更改的伪参数。未来该集合可能变化,甚至可能变为可配置。因此,前端应忽略其不理解或不关心的 ParameterStatus。 + 目前,会为一组固定的参数生成 ParameterStatus,参数如下: + server_versionserver_encodingclient_encodingapplication_namedefault_transaction_read_onlyin_hot_standbyis_superusersession_authorizationDateStyleIntervalStyleTimeZoneinteger_datetimesstandard_conforming_strings。 + (8.0 之前的版本不报告 server_encodingTimeZoneinteger_datetimes;8.1 之前的版本不报告 standard_conforming_strings;8.4 之前的版本不报告 IntervalStyle;9.0 之前的版本不报告 application_name;14 之前的版本不报告 default_transaction_read_onlyin_hot_standby。) + 注意,server_versionserver_encodinginteger_datetimes 是启动后不能改变的伪参数。这组参数将来可能变化,甚至可能变为可配置。因此,前端应直接忽略其不理解或不关心的参数的 ParameterStatus。 @@ -1368,7 +1355,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" CREATE_REPLICATION_SLOT slot_name [ TEMPORARY ] { PHYSICAL | LOGICAL output_plugin } [ ( option [, ...] ) ] - 创建复制槽 + CREATE_REPLICATION_SLOT @@ -1425,14 +1412,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - - FAILOVER [ boolean ] - - - 若为 true,则该复制槽会同步到备库,从而在故障切换后恢复逻辑复制。默认值为 false。 - - - + RESERVE_WAL [ boolean ] @@ -1450,13 +1430,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" SNAPSHOT { 'export' | 'use' | 'nothing' } - - 决定在逻辑复制槽初始化期间如何处理所创建的快照。'export' - 这是默认选项,将导出快照供其他会话使用。此选项不能在事务内使用。 - 'use'将为执行命令的当前事务使用快照。此选项必须在事务中使用, - 并且CREATE_REPLICATION_SLOT必须是在该事务中运行的第一个命令。 - 最后,'nothing'将像往常一样仅用于逻辑解码使用快照,但不会执行其他操作。 - + 决定如何处理初始化逻辑复制槽时创建的快照。默认选项 'export' 会导出快照供其他会话使用,此选项不能在事务内使用。'use' 会将快照用于执行该命令的当前事务;此选项必须在事务内使用,且 CREATE_REPLICATION_SLOT 必须是该事务中执行的第一条命令。最后,'nothing' 只会像平常一样将快照用于逻辑解码,不会对其执行其他操作。 @@ -1487,7 +1461,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" snapshot_name (text) - 该命令导出的快照标识符。该快照在此连接上执行下一条命令之前,或复制连接关闭之前有效。如果所创建的是物理复制槽,则为 null。 + 该命令导出的快照标识符。该快照在此连接上执行下一条命令之前,或复制连接关闭之前有效。如果所创建的是物理复制槽,则为空值。 @@ -1496,7 +1470,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" output_plugin (text) - 新建复制槽所使用的输出插件名称。如果所创建的是物理复制槽,则为 null。 + 新建复制槽所使用的输出插件名称。如果所创建的是物理复制槽,则为空值。 @@ -2029,28 +2003,16 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - - - UPLOAD_MANIFEST - UPLOAD_MANIFEST - - - - 上传备份清单(backup manifest),为执行增量备份做准备。 - - - - + BASE_BACKUP [ ( option [, ...] ) ] BASE_BACKUP - - 指示服务器开始流式传输基本备份。 + 指示服务器开始流式传输基础备份。 在备份开始之前,系统将自动进入备份模式,并在备份完成后退出备份模式。 接受以下选项: @@ -2058,10 +2020,9 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" LABEL 'label' - 设置备份的标签。如果未指定,则将使用base backup作为备份标签。 - 标签的引用规则与打开的标准SQL字符串相同。 + 标签的引号使用规则与打开的标准SQL字符串相同。 @@ -2099,13 +2060,12 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" PROGRESS [ boolean ] - - 如果设置为true,则请求生成进度报告所需的信息。这将在每个表空间的头部发送一个近似大小, + 如果设置为true,则请求生成进度报告所需的信息。这将在每个表空间的首部发送一个近似大小, 可用于计算流式传输的进度。这是通过在传输开始之前先枚举所有文件大小来计算的, 可能会对性能产生负面影响。特别是,在流式传输数据之前可能需要更长的时间。 由于备份期间数据库文件可能会发生变化,因此大小仅为近似值, - 在近似值和实际文件发送之间可能会增长或缩小。默认值为false。 + 在估算与实际发送文件之间的这段时间里可能会增长或缩小。默认值为false。 @@ -2113,9 +2073,8 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" CHECKPOINT { 'fast' | 'spread' } - - 设置在基本备份开始时执行的检查点类型。默认值为spread。 + 设置在基础备份开始时执行的检查点类型。默认值为spread @@ -2123,19 +2082,15 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" WAL [ boolean ] - - - 如果设置为true,则在备份中包含必要的WAL段。这将包括在开始和停止备份之间的所有文件在基本目录tar文件的pg_wal目录中。默认值为false。 - + 如果设置为 true,则在备份中包含必要的 WAL 段。这会把开始备份到停止备份之间的所有文件放入基础目录 tar 文件内的pg_wal目录中。默认值为 false。 WAIT [ boolean ] - - 如果设置为 true,备份会等待直到最后一个所需 WAL 段已归档;若未启用 WAL 归档则发出警告。 + 如果设置为 true,备份会等待直到最后一个所需 WAL 段已归档;若未启用日志归档则发出警告。 如果设置为 false,备份既不等待也不警告,而由客户端负责确保所需 WAL 可用。 默认值为true。 @@ -2156,12 +2111,11 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" COMPRESSION_DETAIL detail - 指定所选压缩方法的详细信息。这应该只与COMPRESSION选项一起使用。 如果该值是一个整数,则指定压缩级别。否则,它应该是一个逗号分隔的项目列表, 每个项目的形式为keywordkeyword=value。 - 目前,支持的关键字是levellongworkers。 + 目前,支持的关键字是levelworkers @@ -2176,10 +2130,6 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" (默认为ZSTD_CLEVEL_DEFAULT3)。 - - long 关键字用于启用长距离匹配模式,可提高压缩比,但会增加内存使用。长距离模式仅支持 zstd。 - - workers关键字设置应该用于并行压缩的线程数。并行压缩仅支持zstd @@ -2212,9 +2162,8 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" VERIFY_CHECKSUMS [ boolean ] - - 如果为true,则在进行基本备份时验证校验和(如果已启用)。如果为false,则跳过此步骤。默认值为true。 + 如果为true,则在进行基础备份时验证校验和(如果已启用)。如果为false,则跳过此步骤。默认值为true。 @@ -2222,14 +2171,13 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" MANIFEST manifest_option - 当指定此选项的值为yesforce-encode时, 将创建一个备份清单并随备份一起发送。该清单是备份中每个文件的列表, 除了可能包含的任何WAL文件。它还存储每个文件的大小、最后修改时间, 以及可选的校验和。 值为force-encode会强制对所有文件名进行十六进制编码; - 否则,仅对文件名为非UTF8八位序列的文件执行此类型的编码。 + 否则,仅对文件名为非 UTF8 字节序列的文件执行此类型的编码。 force-encode主要用于测试目的,以确保读取备份清单的客户端 能够处理这种情况。为了与之前的版本兼容,默认值为MANIFEST 'no' @@ -2249,15 +2197,6 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - - - INCREMENTAL - - - 请求执行增量备份。使用该选项执行基础备份前,必须先执行 UPLOAD_MANIFEST 命令。 - - - @@ -2271,14 +2210,14 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" 第二个普通结果集中的每个表空间都有一行。 - 这一行中的字段是: + 这一行中的字段是: spcoid (oid) - 表空间的OID,如果是基本目录则为null。 + 表空间的OID,如果是基础目录则为null。 @@ -2287,7 +2226,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" spclocation (text) - 表空间目录的完整路径,如果是基本目录则为null。 + 表空间目录的完整路径,如果是基础目录则为null。 @@ -2310,8 +2249,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - - new archive (B) + 新归档 (B) @@ -2327,7 +2265,6 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - String @@ -2338,22 +2275,17 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - String - - - - 对于主数据目录,使用空字符串。对于其他表空间,使用从创建此归档的目录的完整路径。 - - + + 对于主数据目录,使用空字符串。对于其他表空间,使用创建此归档所用目录的完整路径。 + - - manifest (B) + 清单 (B) @@ -2401,8 +2333,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - - progress report (B) + 进度报告 (B) @@ -2460,13 +2391,11 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - - 不记录 WAL 的关系(Unlogged表),除了需要在恢复时重新创建(空的)不记录 WAL 的关系的init fork。 - + 不记录 WAL 的关系,但不包括恢复时重新创建(空的)不记录 WAL 的关系所需的初始化分支。 - pg_wal,包括子目录。如果备份包含WAL文件,则将包含pg_wal的合成版本,但它只包含备份工作所需的文件,而不包含其余内容。 + pg_wal,包括子目录。如果备份包含WAL文件,则将包含pg_wal的合成版本,但它只包含使备份可用所需的文件,而不包含其余内容。 @@ -2479,7 +2408,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 除了常规文件和目录之外的文件,如符号链接(除了上述列出的目录之外的符号链接)以及特殊设备和操作系统文件,将被跳过。(pg_tblspc中的符号链接将被保留。) + 除了普通文件和目录之外的文件,如符号链接(除了上述列出的目录之外的符号链接)以及特殊设备和操作系统文件,将被跳过。(pg_tblspc中的符号链接将被保留。) @@ -2512,7 +2441,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 逻辑复制参数 + 逻辑流复制参数 使用 START_REPLICATION 命令时,pgoutput 接受以下选项: @@ -2524,17 +2453,15 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 协议版本。目前支持的版本有 1234。必须指定一个有效版本。 - - - 版本2仅支持服务器版本14及以上,并允许流式传输大型进行中的事务。 + 协议版本。目前支持的版本有 123。必须指定一个有效版本。 - 版本3仅支持服务器版本15及以上,并允许流式传输两阶段提交。 + 版本 2 仅在服务器版本 14 及以上受支持,允许流式传输正在进行的大型事务。 - 版本4仅支持服务器版本 16 及以上,并允许对大型进行中事务的流进行并行应用。 + 版本 3 仅在服务器版本 15 及以上受支持,允许流式传输两阶段提交。 + @@ -2544,8 +2471,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 用于订阅(接收更改)的发布名称的逗号分隔列表。各个发布名称按标准对象名处理,可按需加引号。 - 至少需要一个发布名称。 + 要订阅(接收变更)的发布名称列表,以逗号分隔。各个发布名称按标准对象名处理,可按需加引号。至少需要一个发布名称。 @@ -2556,7 +2482,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 使用二进制传输模式的布尔选项。二进制模式比文本模式更快,但略微不够稳健。 + 使用二进制传输模式的布尔选项。二进制模式比文本模式更快,但稳健性略差。 @@ -2567,7 +2493,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 一个布尔选项,用于启用发送由 pg_logical_emit_message 写入的消息。 + 布尔选项,用于启用发送由 pg_logical_emit_message 写入的消息。 @@ -2578,7 +2504,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 启用进行中事务流式传输的选项。可选值为 off(默认)、onparallelparallel 会在部分消息中附带用于并行化的额外信息。设置为 on 需要最低协议版本 2;设置为 parallel 需要最低协议版本 4。 + 一个布尔选项,启用进行中事务的流式传输。需要最低协议版本 2 才能启用。 @@ -2594,22 +2520,12 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - - - origin - - - - 按来源发送变更的选项。可选值为 none(仅发送无来源信息的变更)或 any(无论来源均发送)。该选项可用于避免复制节点之间形成循环(同一数据无限复制)。 - - - + - - 在上述命令中,若参数类型为 boolean,可省略 value 部分;省略等同于指定 TRUE。 - + + @@ -2921,7 +2837,41 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - + + AuthenticationSCMCredential (B) + + + + Byte1('R') + + + 标识消息为认证请求。 + + + + + + Int32(8) + + + 消息内容的长度(以字节为单位),包括其自身。 + + + + + + Int32(6) + + + 指定需要 SCM 凭据消息。 + + + + + + + + AuthenticationGSS (B) @@ -3456,58 +3406,45 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - CancelRequest (F) - - Int32 + Int32(16) - - 消息内容的长度(以字节为单位),包括其自身。 + 消息内容的长度,以字节为单位,包括此长度字段本身。 - Int32(80877102) - - 取消请求代码。该值被选择为在最高的16位中包含1234,在最低的16位中包含5678。 - (为避免混淆,此代码不得与任何协议版本号相同。) + 取消请求代码。此值的最高 16 位为 1234,最低 16 位为 5678。(为避免混淆,此代码不能与任何协议版本号相同。) - Int32 - - 目标后端的进程ID。 + 目标后端的进程 ID。 - Int32 - - 目标后端的 secret key。该字段长度由消息总长度决定并延伸至消息末尾,最大长度为 256 字节。 + 目标后端的密钥。 - - 在协议 3.2 之前,secret key 固定为 4 字节。 - @@ -5587,7 +5524,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 严重性: 字段内容为ERROR, FATAL, 或 + 严重性: 字段内容为ERROR, FATAL, 或 PANIC (在错误消息中), 或 WARNING, NOTICE, DEBUG, INFO, 或 LOG (在通知消息中), @@ -5601,7 +5538,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 严重性:字段内容为ERRORFATAL或 + 严重性:字段内容为ERRORFATALPANIC(在错误消息中),或WARNINGNOTICEDEBUGINFOLOG(在通知消息中)。 这与S字段相同,只是内容不会被本地化。仅在由PostgreSQL版本9.6 @@ -5625,7 +5562,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 消息: 主要的人类可读错误消息。 + 消息: 主要的人类可读错误消息。 这应该准确但简洁(通常一行)。 总是存在。 @@ -5647,7 +5584,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 提示: 关于问题应该怎么做的一个可选建议。 + 提示: 关于问题应该怎么做的一个可选建议。 这意在与细节不同,它提供建议(可能不合适)而不是硬性事实。 可能会跨越多行。 @@ -5681,7 +5618,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 内部查询: 一个失败的内部生成命令的文本。 + 内部查询: 一个失败的内部生成命令的文本。 例如,这可能是由PL/pgSQL函数发出的SQL查询。 @@ -5714,7 +5651,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 表名: 如果错误与特定表相关联,则为表的名称。(有关表模式名称的名称,请参考模式名称字段。) + 表名: 如果错误与特定表相关联,则为表的名称。(有关表模式名称的名称,请参考模式名称字段。) @@ -5724,7 +5661,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 列名: 如果错误与特定表列相关联,则为列的名称。(请参考模式和表名字段以识别表。) + 列名: 如果错误与特定表列相关联,则为列的名称。(请参考模式和表名字段以识别表。) @@ -5734,7 +5671,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 数据类型名称: 如果错误与特定数据类型相关联,则为数据类型的名称。 + 数据类型名称: 如果错误与特定数据类型相关联,则为数据类型的名称。 (有关数据类型模式的名称,请参阅模式名称字段。) @@ -5745,7 +5682,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 约束名称: 如果错误与特定约束相关联,则为约束的名称。请参考上面列出的字段,了解相关表或域。 + 约束名称: 如果错误与特定约束相关联,则为约束的名称。请参考上面列出的字段,了解相关表或域。 (为此,即使索引不是使用约束语法创建的,也将其视为约束。) @@ -5756,7 +5693,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 文件: 报告错误的源代码位置的文件名。 + 文件: 报告错误的源代码位置的文件名。 @@ -5894,7 +5831,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 标志; 逻辑解码消息是非事务性的时为0,是事务性的时为1。 + 标志; 逻辑解码消息是非事务性的时为0,是事务性的时为1。 @@ -5968,7 +5905,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 标志; 目前未使用。 + 标志; 目前未使用。 @@ -6666,7 +6603,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 标志; 目前未使用。 + 标志; 目前未使用。 @@ -6850,7 +6787,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 标志; 目前未使用。 + 标志; 目前未使用。 @@ -6935,7 +6872,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 标志; 目前未使用。 + 标志; 目前未使用。 @@ -7020,7 +6957,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 标志; 目前未使用。 + 标志; 目前未使用。 @@ -7116,7 +7053,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 标志; 目前未使用。 + 标志; 目前未使用。 @@ -7276,76 +7213,36 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 自协议2.0以来的变化总结 + 自协议 2.0 以来的变更总结 - 本节为那些试图将现有客户端库更新到协议3.0的开发人员提供了一个快速变更清单。 + 本节提供一份简要的变更清单,供准备将现有客户端库更新到协议 3.0 的开发者参考。 - - 初始启动数据包使用灵活的字符串列表格式,而不是固定格式。请注意,现在可以直接在启动数据包中指定运行时参数的会话默认值。 - (实际上,以前可以使用options字段来做到这一点,但考虑到options的有限宽度以及缺乏引用值中空格的任何方法,这并不是一种非常安全的技术。) - + 初始启动包采用灵活的字符串列表格式,取代了固定格式。注意,运行时参数的会话默认值现在可以直接在启动包中指定。(实际上,以前也能通过 options 字段实现,但由于 options 的宽度有限,且无法用引号保护值中的空白字符,这种方法并不稳妥。) - - 所有消息现在都在消息类型字节后面立即跟着长度计数(除了启动数据包,它们没有类型字节)。另外请注意,PasswordMessage现在有一个类型字节。 - + 现在,所有消息都在消息类型字节之后紧跟一个长度计数(启动包除外,它没有类型字节)。另请注意,PasswordMessage 现在也有类型字节。 - - ErrorResponse和NoticeResponse('E'和'N') - 消息现在包含多个字段,客户端代码可以从中组装出所需级别的错误消息。请注意, - 单个字段通常不会以换行符结尾,而在旧协议中发送的单个字符串总是以换行符结尾。 - + ErrorResponse 和 NoticeResponse('E' 和 'N')消息现在包含多个字段,客户端代码可以利用这些字段组合出所需详细程度的错误消息。注意,各字段通常不会以换行符结束,而旧协议发送的单个字符串总是以换行符结束。 - - ReadyForQuery('Z')消息包括事务状态指示器。 - + ReadyForQuery('Z')消息包含一个事务状态指示器。 - - 二进制行和数据行消息类型之间的区别已经消失;单个数据行消息类型用于以所有格式返回数据。 - 请注意,DataRow的布局已更改,以使其更容易解析。 - 此外,二进制值的表示已更改:它不再直接与服务器的内部表示形式绑定。 - + BinaryRow 与 DataRow 消息类型不再有区别;单一的 DataRow 消息类型用于返回所有格式的数据。注意,DataRow 的布局已经改变,使其更容易解析。另外,二进制值的表示方式也已改变,不再直接取决于服务器内部的表示方式。 - - 有一个新的扩展查询子协议,它增加了前端消息类型Parse、Bind、Execute、Describe、Close、Flush和Sync, - 以及后端消息类型ParseComplete、BindComplete、PortalSuspended、ParameterDescription、NoData和CloseComplete。 - 现有客户端不必关心这个子协议,但利用它可能会提高性能或功能。 - + 新增了扩展查询子协议,其中增加了前端消息类型 Parse、Bind、Execute、Describe、Close、Flush 和 Sync,以及后端消息类型 ParseComplete、BindComplete、PortalSuspended、ParameterDescription、NoData 和 CloseComplete。现有客户端不必关注这个子协议,但使用它可能有助于改善性能或功能。 - - COPY数据现在封装到CopyData和CopyDone消息中。在COPY期间有一种明确定义的错误恢复方式。 - 特殊的\.最后一行不再需要,并且在COPY OUT期间不发送。 - (在文本模式的COPY IN期间仍然被识别为终止符,但在CSV模式中不会被识别。文本模式中的这种行为已弃用,并且最终可能会被移除。)支持二进制COPY。 - CopyInResponse和CopyOutResponse消息包括指示列数和每列格式的字段。 - + COPY 数据现在封装在 CopyData 和 CopyDone 消息中。COPY 期间的错误恢复已有明确定义的方法。不再需要特殊的最后一行 \.COPY OUT 期间也不再发送它。(在 COPY IN 期间仍会将它识别为终止符,但这种用法已弃用,最终将被移除。)现已支持二进制 COPY。CopyInResponse 和 CopyOutResponse 消息包含了表示列数及各列格式的字段。 - - FunctionCall和FunctionCallResponse消息的布局已更改。 - FunctionCall现在可以支持将NULL参数传递给函数。它还可以处理以文本或二进制格式传递参数和检索结果。 - 不再需要考虑FunctionCall可能存在安全漏洞,因为它不提供对内部服务器数据表示的直接访问。 - + FunctionCall 和 FunctionCallResponse 消息的布局已经改变。FunctionCall 现在支持向函数传递 NULL 参数,也可以使用文本或二进制格式传递参数和取得结果。由于它不再提供对服务器内部数据表示的直接访问,因此也不再有理由将 FunctionCall 视为潜在的安全漏洞。 - - 后端在连接启动期间向客户端库发送ParameterStatus('S')消息,以传达其认为对客户端库有趣的所有参数。 - 随后,每当这些参数中任何一个的活动值发生变化时,都会发送ParameterStatus消息。 - + 在连接启动期间,后端会为其认为客户端库关注的所有参数发送 ParameterStatus('S')消息。之后,只要这些参数中任何一个的当前值发生变化,就会发送一条 ParameterStatus 消息。 - - RowDescription('T')消息携带了描述行的每列的新表OID和列号字段。它还显示了每列的格式代码。 - + RowDescription('T')消息针对所描述行中的每一列,增加了表 OID 和列编号字段,并显示各列的格式代码。 - - CursorResponse('P')消息不再由后端生成。 - + 后端不再生成 CursorResponse('P')消息。 - - NotificationResponse('A')消息有一个额外的字符串字段,可以携带一个有效负载字符串, - 从NOTIFY事件发送者传递过来。 - + NotificationResponse('A')消息增加了一个字符串字段,可以携带 NOTIFY 事件发送者传来的载荷字符串。 - - EmptyQueryResponse('I')消息曾包含一个空字符串参数;现已移除。 - + EmptyQueryResponse('I')消息以前包含一个空字符串参数,现在已将其移除。 diff --git a/zh/15/queries.sgml b/zh/15/queries.sgml index 1bedf7ee..897f82e0 100644 --- a/zh/15/queries.sgml +++ b/zh/15/queries.sgml @@ -509,7 +509,7 @@ FROM (VALUES ('anne', 'smith'), ('bob', 'jones'), ('joe', 'blow')) - 表函数是那些生成行集合的函数,这些行可以由基本数据类型(标量类型)组成,也可以由复合数据类型(表行)组成。它们在查询的FROM子句中用法类似于表、视图或子查询。表函数返回的列可以像表、视图或子查询的列一样,出现在SELECTJOINWHERE子句中。 + 表函数是那些生成行集合的函数,这些行可以由基础类型(标量类型)组成,也可以由复合数据类型(表行)组成。它们在查询的FROM子句中用法类似于表、视图或子查询。表函数返回的列可以像表、视图或子查询的列一样,出现在SELECTJOINWHERE子句中。 @@ -547,7 +547,7 @@ UNNEST( array_expression , ... - 如果没有提供列的别名,那么对于一个返回基数据类型的函数,列名也与该函数 + 如果没有提供列的别名,那么对于一个返回基础类型的函数,列名也与该函数 名相同。对于一个返回复合类型的函数,结果列会从该类型的属性得到名称。 diff --git a/zh/15/rangetypes.sgml b/zh/15/rangetypes.sgml index f60e0af7..68409fa3 100644 --- a/zh/15/rangetypes.sgml +++ b/zh/15/rangetypes.sgml @@ -209,7 +209,7 @@ SELECT '{[3,7), [8,9)}'::int4multirange; 构造范围和多范围 - 每种范围类型都有一个与范围类型同名的构造函数。使用构造函数通常比书写范围文字常量更方便,因为这样无需对界限值进行额外引用。构造函数接受两个或三个参数。两个参数的形式构造标准形式的范围(下界包含,上界排除),而三个参数的形式则按第三个参数指定的界限形式构造范围。第三个参数必须是下列字符串之一: + 每种范围类型都有一个与范围类型同名的构造函数。使用构造函数通常比书写范围字面量更方便,因为这样无需为界限值额外加引号。构造函数接受两个或三个参数。两个参数的形式构造标准形式的范围(下界包含,上界排除),而三个参数的形式则按第三个参数指定的界限形式构造范围。第三个参数必须是下列字符串之一: ()(][)或者 diff --git a/zh/15/ref/abort.sgml b/zh/15/ref/abort.sgml index 95835c70..caed1f42 100644 --- a/zh/15/ref/abort.sgml +++ b/zh/15/ref/abort.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ABORT 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/allfiles.sgml b/zh/15/ref/allfiles.sgml index 883cd94a..88a37081 100644 --- a/zh/15/ref/allfiles.sgml +++ b/zh/15/ref/allfiles.sgml @@ -202,10 +202,8 @@ PostgreSQL documentation - - @@ -220,8 +218,8 @@ PostgreSQL documentation - + diff --git a/zh/15/ref/alter_aggregate.sgml b/zh/15/ref/alter_aggregate.sgml index 6e6d9e05..c021ff23 100644 --- a/zh/15/ref/alter_aggregate.sgml +++ b/zh/15/ref/alter_aggregate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER AGGREGATE 7 - SQL - Language Statements + SQL - 语言语句 @@ -41,13 +41,7 @@ ALTER AGGREGATE name ( aggregate_signatu ALTER AGGREGATE更改聚合函数的定义。 - - 要使用ALTER AGGREGATE,你必须拥有该聚合函数。 - 要更改聚合函数的模式,你还必须在新模式上具有 - CREATE权限。要更改拥有者,你必须能够对新的拥有角色执行 - SET ROLE,并且该角色必须在该聚合函数所在模式上具有 - CREATE权限。(这些限制确保更改拥有者不会做出任何你无法通过删除并重新创建该聚合函数来完成的事情。不过,超级用户无论如何都可以更改任何聚合函数的所有权。) - + 要使用ALTER AGGREGATE,必须拥有该聚合函数。要更改聚合函数的模式,还必须在新模式上拥有CREATE权限。要更改所有者,还必须是新所有者角色的直接或间接成员,并且该角色必须在聚合函数所在模式上拥有CREATE权限。(这些限制确保更改所有者不会执行任何无法通过删除并重新创建聚合函数完成的操作。不过,超级用户无论如何都可以更改任何聚合函数的所有权。) diff --git a/zh/15/ref/alter_collation.sgml b/zh/15/ref/alter_collation.sgml index 85fd5517..5768077b 100644 --- a/zh/15/ref/alter_collation.sgml +++ b/zh/15/ref/alter_collation.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER COLLATION 7 - SQL - Language Statements + SQL - 语言语句 @@ -36,14 +36,7 @@ ALTER COLLATION name SET SCHEMA new_sche ALTER COLLATION更改排序规则的定义。 - - 要使用ALTER COLLATION,你必须拥有该排序规则。 - 要更改拥有者,你必须能够对新的拥有角色执行SET ROLE, - 并且该角色必须在该排序规则所在模式上具有CREATE权限。 - (这些限制确保更改拥有者不会做出任何你无法通过删除并重新创建该排序 - 规则来完成的事情。不过,超级用户无论如何都可以更改任何排序规则的所 - 有权。) - + 要使用ALTER COLLATION,必须拥有该排序规则。要更改所有者,还必须是新所有者角色的直接或间接成员,并且该角色必须在排序规则所在模式上拥有CREATE权限。(这些限制确保更改所有者不会执行任何无法通过删除并重新创建排序规则完成的操作。不过,超级用户无论如何都可以更改任何排序规则的所有权。) @@ -102,7 +95,7 @@ ALTER COLLATION name SET SCHEMA new_sche 注解 - 创建排序规则对象时,该排序规则的提供者特定版本会记录在系统目录中。 + 创建排序规则对象时,会在系统目录中记录由提供程序确定的排序规则版本。 使用该排序规则时,会将当前版本与记录的版本进行比较;如果二者不匹 配,就会发出警告,例如: diff --git a/zh/15/ref/alter_conversion.sgml b/zh/15/ref/alter_conversion.sgml index d6c8e82c..979ef1e2 100644 --- a/zh/15/ref/alter_conversion.sgml +++ b/zh/15/ref/alter_conversion.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER CONVERSION 7 - SQL - Language Statements + SQL - 语言语句 @@ -34,13 +34,7 @@ ALTER CONVERSION name SET SCHEMA new_sch ALTER CONVERSION更改一个转换的定义。 - - 要使用ALTER CONVERSION,你必须拥有该转换。 - 要更改拥有者,你必须能够对新的拥有者角色执行SET ROLE, - 并且该角色必须在转换所在模式上具有CREATE权限。 - (这些限制确保更改拥有者不会做出任何你无法通过删除并重新创建该转换 - 来完成的事情。不过,超级用户仍然可以更改任何转换的所有权。) - + 要使用ALTER CONVERSION,必须拥有该转换。要更改所有者,还必须是新所有者角色的直接或间接成员,并且该角色必须在转换所在模式上拥有CREATE权限。(这些限制确保更改所有者不会执行任何无法通过删除并重新创建转换完成的操作。不过,超级用户无论如何都可以更改任何转换的所有权。) diff --git a/zh/15/ref/alter_database.sgml b/zh/15/ref/alter_database.sgml index 8ce5bc57..06098f3e 100644 --- a/zh/15/ref/alter_database.sgml +++ b/zh/15/ref/alter_database.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER DATABASE 7 - SQL - Language Statements + SQL - 语言语句 @@ -59,14 +59,10 @@ ALTER DATABASE name RESET ALL 第二种形式更改数据库的名称。只有数据库拥有者或者超级用户可以重命名数据库;非超级用户拥有者还必须具有CREATEDB权限。当前连接的数据库不能被重命名(如果需要这样做,请连接到另一个数据库)。 - - 第三种形式更改数据库的拥有者。要修改拥有者,你必须能够对新拥有者角色执行 - SET ROLE,并且还必须具有CREATEDB权限。 - (注意,超级用户会自动拥有这些权限。) - + 第三种形式更改数据库的所有者。要更改所有者,必须拥有该数据库,并且还必须是新所有者角色的直接或间接成员,并且必须拥有CREATEDB权限。(请注意,超级用户会自动拥有所有这些权限。) - 第四种形式更改数据库的默认表空间。只有数据库拥有者或者超级用户可以这样做;你还必须对新表空间具有创建权限。该命令会将数据库旧默认表空间中的所有表和索引在物理上移动到新表空间中。对于该数据库而言,新默认表空间必须为空,并且不能有人连接到该数据库。位于非默认表空间中的表和索引不受影响。复制文件到新表空间所使用的方法会受该命令内部使用的方法影响。 + 第四种形式更改数据库的默认表空间。只有数据库拥有者或者超级用户可以这样做;你还必须对新表空间具有创建权限。该命令会将数据库旧默认表空间中的所有表和索引在物理上移动到新表空间中。对于该数据库而言,新默认表空间必须为空,并且不能有人连接到该数据库。位于非默认表空间中的表和索引不受影响。 @@ -90,9 +86,7 @@ ALTER DATABASE name RESET ALL allowconn - - 如果为假,则没有人能连接到这个数据库。 - + 如果为 false,则任何人都不能连接到该数据库。 @@ -109,7 +103,7 @@ ALTER DATABASE name RESET ALL istemplate - 如果为真,则任何具有CREATEDB权限的用户都可以从这个数据库克隆。如果为假,则只有超级用户或者该数据库的拥有者可以克隆它。 + 如果为 true,则任何具有 CREATEDB 权限的用户都可以克隆该数据库;如果为 false,则只有超级用户或该数据库的拥有者可以克隆它。 diff --git a/zh/15/ref/alter_default_privileges.sgml b/zh/15/ref/alter_default_privileges.sgml index 2fca3f17..644de19c 100644 --- a/zh/15/ref/alter_default_privileges.sgml +++ b/zh/15/ref/alter_default_privileges.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER DEFAULT PRIVILEGES 7 - SQL - Language Statements + SQL - 语言语句 @@ -121,7 +121,7 @@ REVOKE [ GRANT OPTION FOR ] - 当前,只有模式、表(包括视图和外部表)、序列、函数、类型(包括域)以及大对象的权限可以修改。 + 当前,只有模式、表(包括视图和外部表)、序列、函数、类型(包括域)的权限可以修改。 对于此命令,函数包括聚合函数和过程。此命令中的FUNCTIONSROUTINES等价。(今后更推荐使用ROUTINES, 因为这是同时指代函数和过程的标准术语。在较早的PostgreSQL版本中, @@ -156,8 +156,8 @@ REVOKE [ GRANT OPTION FOR ] 一个现有模式的名称。如果指定,将修改以后在该模式中创建的对象的默认权限。 如果省略IN SCHEMA,则修改全局默认权限。 - 在为模式和大对象设置权限时,不允许使用IN SCHEMA, - 因为模式不能嵌套,而大对象不属于任何模式。 + 在为模式设置权限时,不允许使用IN SCHEMA, + 因为模式不能嵌套。 diff --git a/zh/15/ref/alter_domain.sgml b/zh/15/ref/alter_domain.sgml index a0fe964c..6d5c8f70 100644 --- a/zh/15/ref/alter_domain.sgml +++ b/zh/15/ref/alter_domain.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER DOMAIN 7 - SQL - Language Statements + SQL - 语言语句 @@ -148,13 +148,7 @@ ALTER DOMAIN name - - 要使用ALTER DOMAIN,你必须拥有该域。要更改域的模式, - 你还必须在新模式上具有CREATE权限。要更改拥有者,你必须能够对 - 新的拥有角色执行SET ROLE,并且该角色必须在该域所在的模式上具有 - CREATE权限。(这些限制确保更改拥有者不会做出任何你不能通过 - 删除并重新创建该域来完成的事情。不过,超级用户无论如何都可以更改任何域的所有权。) - + 要使用ALTER DOMAIN,必须拥有该域。要更改域的模式,还必须在新模式上拥有CREATE权限。要更改所有者,还必须是新所有者角色的直接或间接成员,并且该角色必须在域所在模式上拥有CREATE权限。(这些限制确保更改所有者不会执行任何无法通过删除并重新创建域完成的操作。不过,超级用户无论如何都可以更改任何域的所有权。) diff --git a/zh/15/ref/alter_event_trigger.sgml b/zh/15/ref/alter_event_trigger.sgml index 326f30e1..b9407346 100644 --- a/zh/15/ref/alter_event_trigger.sgml +++ b/zh/15/ref/alter_event_trigger.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER EVENT TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -58,7 +58,7 @@ ALTER EVENT TRIGGER name RENAME TO new_owner - 该事件触发器的新拥有者的用户名。 + 该事件触发器的新所有者的用户名。 @@ -94,7 +94,7 @@ ALTER EVENT TRIGGER name RENAME TO - 另见 + 参见 diff --git a/zh/15/ref/alter_extension.sgml b/zh/15/ref/alter_extension.sgml index 9471390f..3ceae003 100644 --- a/zh/15/ref/alter_extension.sgml +++ b/zh/15/ref/alter_extension.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER EXTENSION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/alter_foreign_data_wrapper.sgml b/zh/15/ref/alter_foreign_data_wrapper.sgml index 06bdb8be..52dbfc7e 100644 --- a/zh/15/ref/alter_foreign_data_wrapper.sgml +++ b/zh/15/ref/alter_foreign_data_wrapper.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER FOREIGN DATA WRAPPER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/alter_foreign_table.sgml b/zh/15/ref/alter_foreign_table.sgml index 14958ed9..a8e47a75 100644 --- a/zh/15/ref/alter_foreign_table.sgml +++ b/zh/15/ref/alter_foreign_table.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER FOREIGN TABLE 7 - SQL - Language Statements + SQL - 语言语句 @@ -286,15 +286,7 @@ ALTER FOREIGN TABLE [ IF EXISTS ] name - - 你必须拥有该表才能使用ALTER FOREIGN TABLE。 - 要更改外部表的模式,你还必须在新模式上具有CREATE权限。 - 要更改拥有者,你必须能够对新的拥有角色执行SET ROLE, - 并且该角色必须在该表所在模式上具有CREATE权限。 - (这些限制确保更改拥有者不会做出任何你无法通过删除并重新创建该表来完成的事情。 - 不过,超级用户仍然可以更改任何表的所有权。) - 要添加列或更改列类型,你还必须在该数据类型上具有USAGE权限。 - + 要使用ALTER FOREIGN TABLE,必须拥有该表。要更改外部表的模式,还必须在新模式上拥有CREATE权限。要更改所有者,还必须是新所有者角色的直接或间接成员,并且该角色必须在表所在模式上拥有CREATE权限。(这些限制确保更改所有者不会执行任何无法通过删除并重新创建该表完成的操作。不过,超级用户无论如何都可以更改任何表的所有权。)要添加列或更改列类型,还必须在数据类型上拥有USAGE权限。 diff --git a/zh/15/ref/alter_function.sgml b/zh/15/ref/alter_function.sgml index 5de95078..c23e0831 100644 --- a/zh/15/ref/alter_function.sgml +++ b/zh/15/ref/alter_function.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation ALTER FUNCTION 7 - SQL - Language Statements + SQL - 语言语句 @@ -59,14 +59,7 @@ ALTER FUNCTION name [ ( [ [ group_name RENAME TO 组的角色授予或撤销成员资格, 因此更推荐使用GRANTREVOKE。 - 请注意,GRANTREVOKE还提供了此命令没有的附加选项, - 例如可以授予和撤销ADMIN OPTION,以及指定授权者(grantor)。 diff --git a/zh/15/ref/alter_index.sgml b/zh/15/ref/alter_index.sgml index 06134114..978d61e1 100644 --- a/zh/15/ref/alter_index.sgml +++ b/zh/15/ref/alter_index.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER INDEX 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/alter_language.sgml b/zh/15/ref/alter_language.sgml index 7af98f20..000fe499 100644 --- a/zh/15/ref/alter_language.sgml +++ b/zh/15/ref/alter_language.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER LANGUAGE 7 - SQL - Language Statements + SQL - 语言语句 @@ -31,8 +31,8 @@ ALTER [ PROCEDURAL ] LANGUAGE name OWNER TO { ALTER LANGUAGE更改一种过程语言的定义。 - 目前唯一的功能是重命名该语言或为其指定新的拥有者。 - 要使用ALTER LANGUAGE,你必须是超级用户或者该语言的拥有者。 + 目前唯一的功能是重命名该语言或为其指定新的所有者。 + 要使用ALTER LANGUAGE,你必须是超级用户或者该语言的所有者。 @@ -62,7 +62,7 @@ ALTER [ PROCEDURAL ] LANGUAGE name OWNER TO { new_owner - 该语言的新拥有者 + 该语言的新所有者 diff --git a/zh/15/ref/alter_large_object.sgml b/zh/15/ref/alter_large_object.sgml index ad3f61f7..6805cd38 100644 --- a/zh/15/ref/alter_large_object.sgml +++ b/zh/15/ref/alter_large_object.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER LARGE OBJECT 7 - SQL - Language Statements + SQL - 语言语句 @@ -32,12 +32,7 @@ ALTER LARGE OBJECT large_object_oid ALTER LARGE OBJECT更改一个大对象的定义。 - - 要使用ALTER LARGE OBJECT,你必须是该大对象的拥有者。 - 要修改其拥有者,你还必须能够对新的拥有者角色执行SET ROLE。 - (不过,超级用户无论如何都可以修改任何大对象。) - 当前唯一提供的功能是指定新的拥有者,因此这两项限制始终都适用。 - + 要使用ALTER LARGE OBJECT,必须拥有该大对象。要更改所有者,还必须是新所有者角色的直接或间接成员。(不过,超级用户无论如何都可以更改任何大对象。)目前唯一的功能是指定新的所有者,因此两项限制始终适用。 diff --git a/zh/15/ref/alter_materialized_view.sgml b/zh/15/ref/alter_materialized_view.sgml index 71ac3ade..6d22460b 100644 --- a/zh/15/ref/alter_materialized_view.sgml +++ b/zh/15/ref/alter_materialized_view.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER MATERIALIZED VIEW 7 - SQL - Language Statements + SQL - 语言语句 @@ -59,14 +59,7 @@ ALTER MATERIALIZED VIEW ALL IN TABLESPACE name - - 要使用ALTER MATERIALIZED VIEW,你必须拥有该物化视图。 - 要更改一个物化视图的模式,你还必须具有新模式上的CREATE权限。 - 要更改拥有者,你必须能够对新拥有角色执行SET ROLE, - 并且该角色必须具有该物化视图所在模式上的CREATE权限。 - (这些限制确保,更改拥有者不会做到你无法通过删除并重新创建该物化视图来完成的事情。 - 不过,超级用户无论如何都可以更改任何视图的所有权。) - + 要使用ALTER MATERIALIZED VIEW,必须拥有该物化视图。要更改物化视图的模式,还必须在新模式上拥有CREATE权限。要更改所有者,还必须是新所有者角色的直接或间接成员,并且该角色必须在物化视图所在模式上拥有CREATE权限。(这些限制确保更改所有者不会执行任何无法通过删除并重新创建物化视图完成的操作。不过,超级用户无论如何都可以更改任何视图的所有权。) 可用于ALTER MATERIALIZED VIEW的语句形式和动作是 diff --git a/zh/15/ref/alter_opclass.sgml b/zh/15/ref/alter_opclass.sgml index b1872b37..e6ab8643 100644 --- a/zh/15/ref/alter_opclass.sgml +++ b/zh/15/ref/alter_opclass.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER OPERATOR CLASS 7 - SQL - Language Statements + SQL - 语言语句 @@ -39,13 +39,7 @@ ALTER OPERATOR CLASS name USING res_proc | NONE } | JOIN = { join_proc | NONE } - | COMMUTATOR = com_op - | NEGATOR = neg_op - | HASHES - | MERGES - } [, ... ] ) + } [, ... ] ) @@ -45,13 +41,7 @@ ALTER OPERATOR name ( { left_typeALTER OPERATOR更改一个操作符的定义。 - - 要使用ALTER OPERATOR,你必须拥有该操作符。 - 要修改拥有者,你必须能够对新拥有角色执行SET ROLE, - 并且该角色必须在该操作符所在模式上具有CREATE权限。 - (这些限制确保更改拥有者不会让你做到那些不能通过删除并重建该操作符来做到的事情。 - 不过,超级用户始终可以更改任何操作符的所有权。) - + 要使用ALTER OPERATOR,必须拥有该操作符。要更改所有者,还必须是新所有者角色的直接或间接成员,并且该角色必须在操作符所在模式上拥有CREATE权限。(这些限制确保更改所有者不会执行任何无法通过删除并重新创建操作符完成的操作。不过,超级用户无论如何都可以更改任何操作符的所有权。) @@ -122,63 +112,19 @@ ALTER OPERATOR name ( { left_type - - com_op - - - 该操作符的交换子。只有当该操作符当前没有交换子时,才能修改此项。 - - - - - neg_op - - - 该操作符的求反器。只有当该操作符当前没有求反器时,才能修改此项。 - - - - - HASHES - - - 表示该操作符可以支持哈希连接。该属性只能启用,不能禁用。 - - - - - MERGES - - - 表示该操作符可以支持归并连接。该属性只能启用,不能禁用。 - - - - - - - 注解 - - 更多信息请参见和 - 。 - - - 由于交换子总是成对出现、彼此互为交换子, - ALTER OPERATOR SET COMMUTATOR也会把 - com_op的交换子设置为目标操作符。 - 同样,ALTER OPERATOR SET NEGATOR也会把 - neg_op的求反器设置为目标操作符。 - 因此,你不仅必须拥有目标操作符,也必须拥有其交换子或求反器操作符。 - + + + + 示例 @@ -193,16 +139,11 @@ ALTER OPERATOR @@ (text, text) OWNER TO joe; 更改类型int[]上的自定义操作符a && b的 限制和连接选择度估算函数: -ALTER OPERATOR && (int[], int[]) SET (RESTRICT = _int_contsel, JOIN = _int_contjoinsel); +ALTER OPERATOR && (_int4, _int4) SET (RESTRICT = _int_contsel, JOIN = _int_contjoinsel); - - 将&&操作符标记为其自身的交换子: - -ALTER OPERATOR && (int[], int[]) SET (COMMUTATOR = &&); - - + diff --git a/zh/15/ref/alter_opfamily.sgml b/zh/15/ref/alter_opfamily.sgml index a0b755c2..45e5007b 100644 --- a/zh/15/ref/alter_opfamily.sgml +++ b/zh/15/ref/alter_opfamily.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER OPERATOR FAMILY 7 - SQL - Language Statements + SQL - 语言语句 @@ -247,6 +247,9 @@ ALTER OPERATOR FAMILY name USING ALTER PROCEDURE更改过程的定义。 - - 要使用ALTER PROCEDURE,你必须拥有该过程。要更改 - 过程的模式,你还必须在新模式上具有CREATE权限。 - 要更改拥有者,你必须能够对新的拥有角色执行SET ROLE, - 并且该角色必须在过程所在模式上具有CREATE权限。 - (这些限制确保更改拥有者不会做出任何你无法通过删除并重新创建该过程 - 来完成的事情。不过,超级用户仍然可以更改任何过程的所有权)。 - + 要使用ALTER PROCEDURE,必须拥有该过程。要更改过程的模式,还必须在新模式上拥有CREATE权限。要更改所有者,还必须是新所有者角色的直接或间接成员,并且该角色必须在过程所在模式上拥有CREATE权限。(这些限制确保更改所有者不会执行任何无法通过删除并重新创建过程完成的操作。不过,超级用户无论如何都可以更改任何过程的所有权。) diff --git a/zh/15/ref/alter_publication.sgml b/zh/15/ref/alter_publication.sgml index 12bfeb8e..02f3f3e6 100644 --- a/zh/15/ref/alter_publication.sgml +++ b/zh/15/ref/alter_publication.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER PUBLICATION 7 - SQL - Language Statements + SQL - 语言语句 @@ -57,10 +57,10 @@ ALTER PUBLICATION name RENAME TO ADD和DROP子句则会向发 布中添加或移除一个或多个表或模式。请注意,向已经被订阅的发布中添加 表或模式后,需要在订阅端执行 - ALTER SUBSCRIPTION ... REFRESH PUBLICATION + ALTER SUBSCRIPTION ... REFRESH PUBLICATION 操作后才会生效。还要注意,DROP TABLES IN SCHEMA 不会移除那些通过 - FOR TABLE/ADD TABLE + FOR TABLE/ADD TABLE 指定的模式中的表。 @@ -74,16 +74,14 @@ ALTER PUBLICATION name RENAME TO - 要使用ALTER PUBLICATION,你必须拥有该发布。 - 向发布中添加表还要求拥有该表。对发布执行 + 要使用ALTER PUBLICATION,必须拥有该发布。 + 向发布添加表还要求拥有该表。对发布执行 ADD TABLES IN SCHEMASET TABLES IN SCHEMA要求调用用户为超级用户。 - 要更改所有者,你必须能够对新的拥有角色执行SET ROLE, - 并且该角色必须在数据库上具有CREATE权限。此外, - FOR ALL TABLES - 或FOR TABLES IN SCHEMA - 发布的新所有者也必须是超级用户。不过,超级用户可以不受这些限制而更 - 改发布的所有权。 + 要更改所有者,还必须是新所有者角色的直接或间接成员。 + 新所有者必须在数据库上拥有CREATE权限。此外, + FOR ALL TABLESFOR TABLES IN SCHEMA + 发布的新所有者必须是超级用户。不过,超级用户可以不受这些限制而更改发布的所有权。 @@ -148,20 +146,7 @@ ALTER PUBLICATION name RENAME TO 设置的 发布参数。详见该命令的说明。 - - - 更改 publish_via_partition_root 参数可能导致订 - 阅端发生数据丢失或重复,因为它会改变已发布表的标识和模式。请注 - 意,只有当根分区表被指定为复制目标时,才会发生此问题。 - - - 可通过以下方式避免此问题:在执行 - ALTER PUBLICATION ... SET之后、执行 - ALTER SUBSCRIPTION ... REFRESH PUBLICATION - 之前,不修改分区叶子表;并且刷新时仅使用 - copy_data = off选项。 - - + diff --git a/zh/15/ref/alter_role.sgml b/zh/15/ref/alter_role.sgml index 6c719424..5be2fab2 100644 --- a/zh/15/ref/alter_role.sgml +++ b/zh/15/ref/alter_role.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation ALTER ROLE 7 - SQL - Language Statements + SQL - 语言语句 @@ -69,23 +69,14 @@ ALTER ROLE { role_specification | A (涵盖了所有可能的属性,但没有用于添加或移除成员资格的选项;为此请使用 GRANTREVOKE。) - 命令中未提及的属性保持原有设置不变。数据库超级用户可以更改任何角色的这些设置,但不能更改 - 引导超级用户的 - SUPERUSER属性。拥有CREATEROLE权限的非超级用户角色也可以更改其中的大多数属性, - 但只能更改其已被授予ADMIN OPTION的、非超级用户且非复制角色的这些属性。 - 非超级用户不能更改SUPERUSER属性;只有其自身也拥有相应属性时,才能更改 - CREATEDBREPLICATIONBYPASSRLS属性。 - 普通角色只能更改自己的密码。 + 命令中未提及的属性保持原有设置不变。数据库超级用户可以为任何角色更改 + 这些设置。拥有CREATEROLE权限的角色可以更改除 + SUPERUSERREPLICATION和 + BYPASSRLS之外的任何这些设置,但只能针对非超级用户 + 且非复制角色。普通角色只能更改自己的密码。 - - 第二种形式更改角色的名称。数据库超级用户可以重命名任何角色。具有 - CREATEROLE权限的角色可以重命名其已被授予 - ADMIN OPTION的非超级用户角色。当前会话用户不能被重命名。 - (如果需要这样做,请以其他用户连接。) - 由于MD5加密的密码使用角色名作为密码学盐值,如果该密码采用 - MD5加密,重命名角色会清除其密码。 - + 第二种形式更改角色的名称。数据库超级用户可以重命名任何角色。拥有CREATEROLE权限的角色可以重命名非超级用户角色。当前会话用户不能被重命名。(如果需要这样做,请以其他用户连接。)由于MD5加密的密码使用角色名作为密码学盐,重命名角色会清除其密码(如果密码使用MD5加密)。 其余形式更改角色针对配置变量的会话默认值,可以针对所有数据库,也可以在指定 @@ -105,12 +96,7 @@ ALTER ROLE { role_specification | A 或特定角色的设置会覆盖针对所有角色的设置。 - - 超级用户可以更改任何角色的会话默认值。具有CREATEROLE权限的角色 - 可以更改其已被授予ADMIN OPTION的非超级用户角色的默认值。 - 普通角色只能为自己设置默认值。某些配置变量不能以这种方式设置,或者只有由超级用户 - 发出该命令时才能设置。只有超级用户才能更改所有数据库中所有角色的设置。 - + 超级用户可以更改任何人的会话默认值。拥有CREATEROLE权限的角色可以更改非超级用户角色的默认值。普通角色只能为自己设置默认值。某些配置变量不能以这种方式设置,或者只能由超级用户执行命令来设置。只有超级用户可以更改所有数据库中所有角色的设置。 diff --git a/zh/15/ref/alter_routine.sgml b/zh/15/ref/alter_routine.sgml index 4fc3e18d..79191e1e 100644 --- a/zh/15/ref/alter_routine.sgml +++ b/zh/15/ref/alter_routine.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER ROUTINE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/alter_rule.sgml b/zh/15/ref/alter_rule.sgml index 9449d787..9397274c 100644 --- a/zh/15/ref/alter_rule.sgml +++ b/zh/15/ref/alter_rule.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER RULE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/alter_schema.sgml b/zh/15/ref/alter_schema.sgml index 2baf518d..c711f199 100644 --- a/zh/15/ref/alter_schema.sgml +++ b/zh/15/ref/alter_schema.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER SCHEMA 7 - SQL - Language Statements + SQL - 语言语句 @@ -33,13 +33,7 @@ ALTER SCHEMA name OWNER TO { new_ownerALTER SCHEMA更改一个模式的定义。 - - 要使用ALTER SCHEMA,你必须拥有该模式。 - 要重命名一个模式,你还必须具有该数据库的CREATE权限。 - 要更改拥有者,你必须能够对新的拥有者角色执行SET ROLE, - 并且该角色还必须具有该数据库的CREATE权限。 - (注意,超级用户会自动拥有所有这些权限。) - + 要使用ALTER SCHEMA,必须拥有该模式。要重命名模式,还必须在数据库上拥有CREATE权限。要更改所有者,还必须是新所有者角色的直接或间接成员,并且必须在数据库上拥有CREATE权限。(请注意,超级用户会自动拥有所有这些权限。) diff --git a/zh/15/ref/alter_sequence.sgml b/zh/15/ref/alter_sequence.sgml index 05ba4edf..dcd8f8cc 100644 --- a/zh/15/ref/alter_sequence.sgml +++ b/zh/15/ref/alter_sequence.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER SEQUENCE 7 - SQL - Language Statements + SQL - 语言语句 @@ -47,13 +47,7 @@ ALTER SEQUENCE [ IF EXISTS ] name S ALTER SEQUENCE命令中未明确设置的参数,会保留其原有设置。 - - 要使用ALTER SEQUENCE,你必须拥有该序列。要更改序列所在的模式, - 你还必须在新模式上具有CREATE权限。要更改拥有者,你必须能够对新的拥有角色执行 - SET ROLE,并且该角色必须在该序列所在模式上具有CREATE权限。 - (这些限制确保更改拥有者不会做出任何你不能通过删除并重建该序列来完成的事情。 - 不过,超级用户无论如何都可以更改任何序列的所有权。) - + 要使用ALTER SEQUENCE,必须拥有该序列。要更改序列的模式,还必须在新模式上拥有CREATE权限。要更改所有者,还必须是新所有者角色的直接或间接成员,并且该角色必须在序列所在模式上拥有CREATE权限。(这些限制确保更改所有者不会执行任何无法通过删除并重新创建序列完成的操作。不过,超级用户无论如何都可以更改任何序列的所有权。) diff --git a/zh/15/ref/alter_server.sgml b/zh/15/ref/alter_server.sgml index 5d870833..c500ff22 100644 --- a/zh/15/ref/alter_server.sgml +++ b/zh/15/ref/alter_server.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER SERVER 7 - SQL - Language Statements + SQL - 语言语句 @@ -37,12 +37,7 @@ ALTER SERVER name RENAME TO - - 要更改服务器,你必须是该服务器的拥有者。此外,要更改拥有者,你必须 - 能够对新的拥有角色执行SET ROLE,并且必须在该服 - 务器的外部数据包装器上具有USAGE权限。(注意, - 超级用户会自动满足所有这些条件。) - + 要更改服务器,必须是服务器的所有者。此外,要更改所有者,还必须拥有该服务器,是新所有者角色的直接或间接成员,并且必须在服务器的外部数据包装器上拥有USAGE权限。(请注意,超级用户会自动满足所有这些条件。) diff --git a/zh/15/ref/alter_statistics.sgml b/zh/15/ref/alter_statistics.sgml index 315ff6b7..f98f20b2 100644 --- a/zh/15/ref/alter_statistics.sgml +++ b/zh/15/ref/alter_statistics.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER STATISTICS 7 - SQL - Language Statements + SQL - 语言语句 @@ -38,14 +38,7 @@ ALTER STATISTICS name SET STATISTIC 凡未在ALTER STATISTICS命令中明确设置的参数,都会保留其原有设置。 - - 要使用ALTER STATISTICS,你必须拥有该统计对象。 - 要更改统计对象的模式,你还必须在新模式上具有CREATE权限。 - 要更改所有者,你必须能够对新的拥有角色执行SET ROLE, - 并且该角色必须在统计对象所在的模式上具有CREATE权限。 - (这些限制确保更改所有者不会做出任何你无法通过删除并重新创建该统计对象来完成的事情。 - 不过,超级用户无论如何都可以更改任何统计对象的所有权。) - + 要使用ALTER STATISTICS,必须拥有该统计对象。要更改统计对象的模式,还必须在新模式上拥有CREATE权限。要更改所有者,还必须是新所有者角色的直接或间接成员,并且该角色必须在统计对象所在模式上拥有CREATE权限。(这些限制确保更改所有者不会执行任何无法通过删除并重新创建统计对象完成的操作。不过,超级用户无论如何都可以更改任何统计对象的所有权。) diff --git a/zh/15/ref/alter_subscription.sgml b/zh/15/ref/alter_subscription.sgml index 280136f0..d7bcd7fe 100644 --- a/zh/15/ref/alter_subscription.sgml +++ b/zh/15/ref/alter_subscription.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER SUBSCRIPTION 7 - SQL - Language Statements + SQL - 语言语句 @@ -43,13 +43,7 @@ ALTER SUBSCRIPTION name RENAME TO < 中指定的订阅属性。 - - 要使用ALTER SUBSCRIPTION,你必须拥有该订阅。 - 要重命名订阅或更改其所有者,你必须在数据库上具有 - CREATE权限。此外,要更改所有者,你必须能够对新的拥有角色执行 - SET ROLE。如果该订阅具有 - password_required=false,则只有超级用户可以修改它。 - + 要使用ALTER SUBSCRIPTION,必须拥有该订阅。要更改所有者,还必须是新所有者角色的直接或间接成员。新所有者必须是超级用户。(目前,所有订阅所有者都必须是超级用户,因此实际上会绕过所有者检查。但将来可能会改变。) 刷新发布时,会移除不再属于该发布的关系;如果存在表同步槽,也会一并删除。 @@ -59,27 +53,9 @@ ALTER SUBSCRIPTION name RENAME TO < 将该槽与订阅解除关联并删除该订阅。 - - 命令ALTER SUBSCRIPTION ... REFRESH PUBLICATION、 - 带有refresh = true选项的 - ALTER SUBSCRIPTION ... {SET|ADD|DROP} PUBLICATION ...、 - ALTER SUBSCRIPTION ... SET (failover = true|false)以及 - ALTER SUBSCRIPTION ... SET (two_phase = false) - 不能在事务块内执行。 - + 命令ALTER SUBSCRIPTION ... REFRESH PUBLICATION以及带有refresh选项为trueALTER SUBSCRIPTION ... {SET|ADD|DROP} PUBLICATION ...不能在事务块内执行。这些命令在订阅启用了two_phase两阶段提交时也不能执行,除非copy_datafalse。要了解实际的两阶段状态,可参见pg_subscriptionsubtwophasestate列。 + - - 命令ALTER SUBSCRIPTION ... REFRESH PUBLICATION以及 - 带有refresh = true选项的 - ALTER SUBSCRIPTION ... {SET|ADD|DROP} PUBLICATION ..., - 在订阅启用了 - two_phase - 参数时也不能执行,除非 - copy_data - 为false。要了解实际的两阶段状态,可参见 - pg_subscription - 的subtwophasestate列。 - @@ -146,7 +122,7 @@ ALTER SUBSCRIPTION name RENAME TO < 从发布者获取缺失的表信息。这将开始复制自 - CREATE SUBSCRIPTION + CREATE SUBSCRIPTION 或上次执行REFRESH PUBLICATION以来添加到已订阅发布中的表。 @@ -158,26 +134,16 @@ ALTER SUBSCRIPTION name RENAME TO < copy_data (boolean) - + 指定在复制开始时,是否复制所订阅发布中预先存在的数据。 默认值为true - + + 以前已订阅的表不会再次复制,即使某个表的行过滤器 WHERE子句此后已被修改。 - - 关于copy_data = true如何与 - origin - 参数相互作用的细节,请参见。 - - - 关于以二进制格式复制预先存在的数据的细节,请参见 - CREATE SUBSCRIPTION的 - binary - 参数。 - - + @@ -204,62 +170,7 @@ ALTER SUBSCRIPTION name RENAME TO < SET ( subscription_parameter [= value] [, ... ] ) - - 该子句修改最初由设置的参数。 - 详情请参见该命令。可更改的参数有 - slot_name、 - synchronous_commit、 - binary、 - streaming、 - disable_on_error、 - password_required、 - run_as_owner、 - origin、 - failover - 以及 - two_phase。 - 只有超级用户才能设置password_required = false。 - - - - 更改 - slot_name - 时,所指定槽的failovertwo_phase属性值, - 可能与订阅中相应的 - failover - 和 - two_phase - 参数不同。创建该槽时,应确保槽的failover和 - two_phase属性与订阅中对应的参数一致。否则, - 发布者上的该槽的行为可能与这些订阅选项所表明的不同:例如,即使订阅的 - failover - 选项已禁用,发布者上的该槽仍可能被同步到备库;或者即使订阅的 - failover - 选项已启用,该槽也可能不会被同步到备库。 - - - - 只有在订阅被禁用时,才能更改 - failover - 和 - two_phase - 参数。 - - - - 当将 - two_phase - 从true改为false时,如果发现逻辑复制工作进程 - 在two_phase参数仍为true时执行的任何预备事务, - 后端进程会报告错误。你可以在发布者节点上处理这些预备事务,或者在订阅者上手工回滚 - 它们,然后再次尝试。与特定订阅对应、由逻辑复制工作进程预备的事务具有如下模式: - pg_gid_%u_%u - (参数:订阅oid,远端事务标识xid)。 - 要手工处理这类事务,需要回滚名称中包含相应订阅 ID 的所有预备事务。应用可以检查 - pg_prepared_xacts - 来找出所需的预备事务。在two_phase选项从true - 改为false之后,这些事务在提交时会由发布者再次复制。 - + 该子句修改最初由设置的参数。详情请参见该命令。可更改的参数有slot_namesynchronous_commitbinarystreamingdisable_on_error @@ -269,12 +180,11 @@ ALTER SUBSCRIPTION name RENAME TO < 跳过应用远端事务的所有更改。如果传入数据违反任何约束,逻辑复制会停止,直到问题解决。 通过使用ALTER SUBSCRIPTION ... SKIP命令,逻辑复制工作进程会跳过 - 该事务中的所有数据修改操作。若订阅者上启用了 - two_phase, - 则此选项对因在订阅者上启用该参数而已经预备的事务没有作用。逻辑复制工作进程成功跳过该事务或完成一个事务后, + 该事务中的所有数据修改操作。此选项对因在订阅者上启用 two_phase 而已经预备的事务没有作用。逻辑复制工作进程成功跳过该事务或完成一个事务后, LSN(存储在pg_subscription.subskiplsn中) 会被清除。有关逻辑复制冲突的详细信息,请参见 。 + 使用此命令需要超级用户权限。 @@ -315,11 +225,7 @@ ALTER SUBSCRIPTION name RENAME TO < - - 当指定boolean类型的参数时,可以省略 - = value - 部分,这等价于指定TRUE。 - + diff --git a/zh/15/ref/alter_system.sgml b/zh/15/ref/alter_system.sgml index 22c645e6..e843c7b6 100644 --- a/zh/15/ref/alter_system.sgml +++ b/zh/15/ref/alter_system.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER SYSTEM 7 - SQL - Language Statements + SQL - 语言语句 @@ -85,8 +85,7 @@ ALTER SYSTEM RESET ALL - 对于某些接受列表的参数,带引号的值会生成带双引号的输出,以保留空 - 格和逗号;对于另一些参数,则必须在单引号字符串内部使用双引号才能 + 对于某些接受列表的参数,带引号的值会生成带双引号的输出,以保留空白和逗号;对于另一些参数,则必须在单引号字符串内部使用双引号才能 达到这种效果。 @@ -97,22 +96,13 @@ ALTER SYSTEM RESET ALL 注解 - - 不能用这个命令来设置、 - ,以及不允许出现在 - postgresql.conf中的参数(例如 - 预置选项)。 - + 此命令不能用于设置,也不能用于设置postgresql.conf中不允许的参数(例如预设选项)。 关于设置这些参数的其他方法,见 - - 可以通过把设置为 - off来禁用ALTER SYSTEM,但这 - 并不是一种安全机制(该参数的文档中对此有详细说明)。 - + diff --git a/zh/15/ref/alter_table.sgml b/zh/15/ref/alter_table.sgml index 4798657b..d00286a1 100644 --- a/zh/15/ref/alter_table.sgml +++ b/zh/15/ref/alter_table.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TABLE 7 - SQL - Language Statements + SQL - 语言语句 @@ -742,9 +742,7 @@ WITH ( MODULUS numeric_literal, REM 所有作用于单个表的ALTER TABLE形式,除RENAMESET SCHEMAATTACH PARTITIONDETACH PARTITION外,都可以组合成一个多项修改列表,一并执行。例如,可以在一条命令中添加多个列并且/或者修改多个列的类型。对于大型表,这一点尤其有用,因为这样只需对表执行一次遍历。 - - 要使用ALTER TABLE,你必须拥有该表。要更改表的模式或表空间,你还必须在新模式或新表空间上拥有CREATE权限。要把一个表作为父表的新子表加入,你还必须拥有该父表。此外,要把一个表附加为另一个表的新分区,你必须拥有被附加的表。要更改所有者,你必须能够对新的拥有角色执行SET ROLE,并且该角色必须在该表所在模式上具有CREATE权限。(这些限制确保更改所有者不会做出任何你不能通过删除并重建该表来完成的事情。不过,超级用户无论如何都可以更改任何表的所有权。)要添加列、修改列类型或使用OF子句,你还必须在相应数据类型上具有USAGE权限。 - + 要使用ALTER TABLE,必须拥有该表。要更改表的模式或表空间,还必须在新模式或表空间上拥有CREATE权限。要将表作为父表的新子表添加,还必须拥有父表。要将表作为表的新分区附加,还必须拥有要附加的表。要更改所有者,还必须是新所有者角色的直接或间接成员,并且该角色必须在表所在模式上拥有CREATE权限。(这些限制确保更改所有者不会执行任何无法通过删除并重新创建表完成的操作。不过,超级用户无论如何都可以更改任何表的所有权。)要添加列、更改列类型或使用OF子句,还必须在数据类型上拥有USAGE权限。 @@ -1011,7 +1009,7 @@ WITH ( MODULUS numeric_literal, REM - 若要强制立即回收已删除列所占的空间,可以执行任何一种会导致整表重写的ALTER TABLE形式。这样会重新构造每一行,并用空值替换被删除的列。 + 若要强制立即回收已删除列所占的空间,可以执行任何一种会导致整表重写的ALTER TABLE形式。这样会重建每一行,并用空值替换被删除的列。 diff --git a/zh/15/ref/alter_tablespace.sgml b/zh/15/ref/alter_tablespace.sgml index f0297481..8fd7b94c 100644 --- a/zh/15/ref/alter_tablespace.sgml +++ b/zh/15/ref/alter_tablespace.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TABLESPACE 7 - SQL - Language Statements + SQL - 语言语句 @@ -35,10 +35,7 @@ ALTER TABLESPACE name RESET ( diff --git a/zh/15/ref/alter_tsconfig.sgml b/zh/15/ref/alter_tsconfig.sgml index 7ae05dd5..891dce66 100644 --- a/zh/15/ref/alter_tsconfig.sgml +++ b/zh/15/ref/alter_tsconfig.sgml @@ -13,7 +13,7 @@ PostgreSQL documentation ALTER TEXT SEARCH CONFIGURATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/alter_tsdictionary.sgml b/zh/15/ref/alter_tsdictionary.sgml index 9679697e..163d788b 100644 --- a/zh/15/ref/alter_tsdictionary.sgml +++ b/zh/15/ref/alter_tsdictionary.sgml @@ -13,7 +13,7 @@ PostgreSQL documentation ALTER TEXT SEARCH DICTIONARY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/alter_tsparser.sgml b/zh/15/ref/alter_tsparser.sgml index 525064c9..0844cb0a 100644 --- a/zh/15/ref/alter_tsparser.sgml +++ b/zh/15/ref/alter_tsparser.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TEXT SEARCH PARSER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/alter_tstemplate.sgml b/zh/15/ref/alter_tstemplate.sgml index fa4157f9..a3eec599 100644 --- a/zh/15/ref/alter_tstemplate.sgml +++ b/zh/15/ref/alter_tstemplate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TEXT SEARCH TEMPLATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/alter_type.sgml b/zh/15/ref/alter_type.sgml index 58063799..6599b699 100644 --- a/zh/15/ref/alter_type.sgml +++ b/zh/15/ref/alter_type.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation ALTER TYPE 7 - SQL - Language Statements + SQL - 语言语句 @@ -229,16 +229,7 @@ ALTER TYPE name SET ( - - 要使用 ALTER TYPE,你必须拥有该类型。 - 要更改类型所在的模式,你还必须在新模式上拥有 CREATE 权限。 - 要更改拥有者,你必须能够对新的拥有角色执行 SET ROLE, - 并且该角色必须在该类型所在的模式上拥有 CREATE 权限。 - (这些限制确保,更改拥有者不会做出任何你不能通过删除并重新创建该类型来完成的事情。 - 不过,超级用户仍然可以更改任何类型的所有权。) - 要添加属性或更改属性的数据类型,你还必须对该属性的数据类型拥有 - USAGE 权限。 - + 要使用ALTER TYPE,必须拥有该类型。要更改类型的模式,还必须在新模式上拥有CREATE权限。要更改所有者,还必须是新所有者角色的直接或间接成员,并且该角色必须在类型所在模式上拥有CREATE权限。(这些限制确保更改所有者不会执行任何无法通过删除并重新创建类型完成的操作。不过,超级用户无论如何都可以更改任何类型的所有权。)要添加属性或更改属性类型,还必须在该属性的数据类型上拥有USAGE权限。 diff --git a/zh/15/ref/alter_user.sgml b/zh/15/ref/alter_user.sgml index 362b5518..5a4f5dd4 100644 --- a/zh/15/ref/alter_user.sgml +++ b/zh/15/ref/alter_user.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER USER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/alter_user_mapping.sgml b/zh/15/ref/alter_user_mapping.sgml index 6bbeffc6..b1fc6606 100644 --- a/zh/15/ref/alter_user_mapping.sgml +++ b/zh/15/ref/alter_user_mapping.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER USER MAPPING 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/alter_view.sgml b/zh/15/ref/alter_view.sgml index 020f864b..a67abd6f 100644 --- a/zh/15/ref/alter_view.sgml +++ b/zh/15/ref/alter_view.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER VIEW 7 - SQL - Language Statements + SQL - 语言语句 @@ -41,15 +41,7 @@ ALTER VIEW [ IF EXISTS ] name RESET CREATE OR REPLACE VIEW。) - - 要使用 ALTER VIEW,你必须是该视图的拥有者。 - 要更改视图的模式,你还必须拥有新模式上的 CREATE - 权限。要更改拥有者,你必须能够对新的拥有角色执行 - SET ROLE,并且该角色必须拥有该视图所在模式上的 - CREATE 权限。(这些限制确保,更改拥有者不会做出任何 - 你不能通过删除并重新创建该视图来完成的事情。不过,超级用户无论如何都可以 - 更改任何视图的所有权。) - + 要使用ALTER VIEW,必须拥有该视图。要更改视图的模式,还必须在新模式上拥有CREATE权限。要更改所有者,还必须是新所有者角色的直接或间接成员,并且该角色必须在视图所在模式上拥有CREATE权限。(这些限制确保更改所有者不会执行任何无法通过删除并重新创建视图完成的操作。不过,超级用户无论如何都可以更改任何视图的所有权。) diff --git a/zh/15/ref/analyze.sgml b/zh/15/ref/analyze.sgml index e3a712af..1d417e5c 100644 --- a/zh/15/ref/analyze.sgml +++ b/zh/15/ref/analyze.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ANALYZE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/begin.sgml b/zh/15/ref/begin.sgml index 2343e66c..fc8fb312 100644 --- a/zh/15/ref/begin.sgml +++ b/zh/15/ref/begin.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation BEGIN 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/call.sgml b/zh/15/ref/call.sgml index 4a12245b..7dca6405 100644 --- a/zh/15/ref/call.sgml +++ b/zh/15/ref/call.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CALL 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/checkpoint.sgml b/zh/15/ref/checkpoint.sgml index a7e8a4b2..5e95964c 100644 --- a/zh/15/ref/checkpoint.sgml +++ b/zh/15/ref/checkpoint.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CHECKPOINT 7 - SQL - Language Statements + SQL - 语言语句 @@ -48,8 +48,9 @@ CHECKPOINT - 只有超级用户,或者具有 pg_checkpoint 角色权限的用户, - 才能调用CHECKPOINT。 + 只有超级用户,或者具有 + pg_checkpoint + 角色权限的用户,才能调用CHECKPOINT diff --git a/zh/15/ref/close.sgml b/zh/15/ref/close.sgml index 53c793c4..788e2c9a 100644 --- a/zh/15/ref/close.sgml +++ b/zh/15/ref/close.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation CLOSE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/cluster.sgml b/zh/15/ref/cluster.sgml index f22017f1..fb0c44b0 100644 --- a/zh/15/ref/cluster.sgml +++ b/zh/15/ref/cluster.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CLUSTER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/clusterdb.sgml b/zh/15/ref/clusterdb.sgml index fd83c9ba..ada12058 100644 --- a/zh/15/ref/clusterdb.sgml +++ b/zh/15/ref/clusterdb.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation clusterdb 1 - Application + 应用程序 diff --git a/zh/15/ref/comment.sgml b/zh/15/ref/comment.sgml index baa2f239..5148556c 100644 --- a/zh/15/ref/comment.sgml +++ b/zh/15/ref/comment.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation COMMENT 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/commit.sgml b/zh/15/ref/commit.sgml index 046c6d84..596d1550 100644 --- a/zh/15/ref/commit.sgml +++ b/zh/15/ref/commit.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation COMMIT 7 - SQL - Language Statements + SQL - 语言语句 @@ -39,7 +39,7 @@ COMMIT [ WORK | TRANSACTION ] [ AND [ NO ] CHAIN ] 参数 - chained transactions + 链式事务 diff --git a/zh/15/ref/commit_prepared.sgml b/zh/15/ref/commit_prepared.sgml index dcdba873..734b2833 100644 --- a/zh/15/ref/commit_prepared.sgml +++ b/zh/15/ref/commit_prepared.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation COMMIT PREPARED 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/copy.sgml b/zh/15/ref/copy.sgml index aef76bdf..92dd546b 100644 --- a/zh/15/ref/copy.sgml +++ b/zh/15/ref/copy.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation COPY 7 - SQL - Language Statements + SQL - 语言语句 @@ -497,15 +497,10 @@ COPY count 注解 - - COPY TO可用于普通表和已填充的物化视图。例如, - COPY table TO - 复制的行与 - SELECT * FROM ONLY table - 相同。但它不直接支持其他关系类型,如分区表、继承子表或视图。 - 要复制这类关系的全部行,请使用 - COPY (SELECT * FROM table) TO。 - + COPY TO 只能用于普通表,不能用于视图,且不会复制子表或子分区中的行。例如,COPY table TO 复制的行与 SELECT * FROM ONLY table 相同。语法 COPY (SELECT * FROM table) TO ... 可用于导出继承层次结构、分区表或视图中的所有行。 COPY FROM可用于普通表、外部表、分区表,以及具有 diff --git a/zh/15/ref/create_access_method.sgml b/zh/15/ref/create_access_method.sgml index d4cb6d2c..7f2d9d8e 100644 --- a/zh/15/ref/create_access_method.sgml +++ b/zh/15/ref/create_access_method.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE ACCESS METHOD 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/create_aggregate.sgml b/zh/15/ref/create_aggregate.sgml index 3b890824..252f9fab 100644 --- a/zh/15/ref/create_aggregate.sgml +++ b/zh/15/ref/create_aggregate.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation CREATE AGGREGATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/create_cast.sgml b/zh/15/ref/create_cast.sgml index 1e2c9275..94e78f9e 100644 --- a/zh/15/ref/create_cast.sgml +++ b/zh/15/ref/create_cast.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation CREATE CAST 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/create_collation.sgml b/zh/15/ref/create_collation.sgml index 6bb3f7ab..a232fef9 100644 --- a/zh/15/ref/create_collation.sgml +++ b/zh/15/ref/create_collation.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE COLLATION 7 - SQL - Language Statements + SQL - 语言语句 @@ -27,7 +27,6 @@ CREATE COLLATION [ IF NOT EXISTS ] name ( [ LC_CTYPE = lc_ctype, ] [ PROVIDER = provider, ] [ DETERMINISTIC = boolean, ] - [ RULES = rules, ] [ VERSION = version ] ) CREATE COLLATION [ IF NOT EXISTS ] name FROM existing_collation @@ -81,24 +80,7 @@ CREATE COLLATION [ IF NOT EXISTS ] name FROM locale - - 该排序规则的区域设置名称。详见。 - - - 如果providerlibc, - 这相当于同时设置LC_COLLATE和 - LC_CTYPE。如果指定了 - locale,则不能再指定这两个参数中的任何 - 一个。 - - - 如果providerbuiltin, - 则必须指定locale,且其值只能是 - CC.UTF-8或 - PG_UNICODE_FAST。 - + 这是同时设置 LC_COLLATELC_CTYPE 的快捷方式。如果指定了此选项,则不能指定这两个参数中的任何一个。 @@ -106,11 +88,7 @@ CREATE COLLATION [ IF NOT EXISTS ] name FROM lc_collate - - 如果providerlibc, - 则对LC_COLLATE区域类别使用指定的操作系统区域设 - 置。 - + LC_COLLATE 区域类别使用指定的操作系统区域设置。 @@ -118,10 +96,7 @@ CREATE COLLATION [ IF NOT EXISTS ] name FROM lc_ctype - - 如果providerlibc, - 则对LC_CTYPE区域类别使用指定的操作系统区域设置。 - + LC_CTYPE 区域类别使用指定的操作系统区域设置。 @@ -129,14 +104,7 @@ CREATE COLLATION [ IF NOT EXISTS ] name FROM provider - - 指定与该排序规则关联的区域设置服务所使用的提供者。可能的值是 - builtin、 - icuICU - (如果服务器在构建时启用了 ICU 支持)或libc。 - 默认值是libc。详见。 - + 指定用于与此排序规则关联的区域设置服务的提供程序。可能的值为: icuICU libclibc 是默认值。可用选项取决于操作系统和构建选项。 @@ -154,22 +122,12 @@ CREATE COLLATION [ IF NOT EXISTS ] name FROM - 非确定性排序规则仅受 ICU 提供者支持。 + 非确定性排序规则仅受 ICU 提供程序支持。 - - rules - - - 指定额外的定制规则,以自定义该排序规则的行为。这仅受 ICU 支持。 - 详见 - 。 - - - version @@ -238,20 +196,13 @@ CREATE COLLATION french (locale = 'fr_FR.utf8'); - 使用 ICU 提供者并采用德语电话簿排序顺序创建一种排序规则: + 使用 ICU 提供程序并采用德语电话簿排序顺序创建一种排序规则: CREATE COLLATION german_phonebook (provider = icu, locale = 'de-u-co-phonebk'); - - 使用 ICU 提供者、基于 ICU 根区域设置并带有自定义规则创建一种排序规 - 则: - - - - 关于规则语法的更多细节和示例,见。 - + 通过复制现有排序规则来创建一种排序规则: diff --git a/zh/15/ref/create_conversion.sgml b/zh/15/ref/create_conversion.sgml index da83218a..3fcb4447 100644 --- a/zh/15/ref/create_conversion.sgml +++ b/zh/15/ref/create_conversion.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE CONVERSION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/create_database.sgml b/zh/15/ref/create_database.sgml index 36df86cd..2e4d3380 100644 --- a/zh/15/ref/create_database.sgml +++ b/zh/15/ref/create_database.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE DATABASE 7 - SQL - Language Statements + SQL - 语言语句 @@ -29,9 +29,7 @@ CREATE DATABASE name [ LOCALE [=] locale ] [ LC_COLLATE [=] lc_collate ] [ LC_CTYPE [=] lc_ctype ] - [ BUILTIN_LOCALE [=] builtin_locale ] [ ICU_LOCALE [=] icu_locale ] - [ ICU_RULES [=] icu_rules ] [ LOCALE_PROVIDER [=] locale_provider ] [ COLLATION_VERSION = collation_version ] [ TABLESPACE [=] tablespace_name ] @@ -80,11 +78,7 @@ CREATE DATABASE name user_name - - 将成为新数据库拥有者的用户角色名,或者指定 DEFAULT - 以使用默认值(即执行该命令的用户)。要创建由其他角色拥有的数据库, - 你必须能够对该角色执行 SET ROLE。 - + 新数据库所有者的角色名称,或使用 DEFAULT 以使用默认值(即执行命令的用户)。要创建由其他角色拥有的数据库,你必须是该角色的直接或间接成员,或为超级用户。 @@ -115,35 +109,13 @@ CREATE DATABASE name 创建新数据库时使用的策略。如果使用 WAL_LOG 策略,数据库将按块复制,并且每个块都会分别写入预写式日志。当模板数据库较小时,这是最高效的策略,因此也是默认策略。较早的 FILE_COPY 策略也可用。该策略会为目标数据库使用的每个表空间向预写式日志写入一条较小的记录,每条记录都表示在文件系统层面把整个目录复制到一个新位置。虽然这样能大幅减少预写式日志量,特别是在模板数据库很大时更是如此,但它也会迫使系统在创建新数据库之前和之后各执行一次检查点。在某些情况下,这可能会对整体系统性能产生明显的负面影响。 - FILE_COPY 策略受 file_copy_method 设置影响。 locale - - 设置新数据库中的默认排序规则和字符分类。排序规则会影响应用于字符串的排序顺序, - 例如带有 ORDER BY 的查询,以及文本列索引中使用的顺序。字符分类会影响字符的类别划分,例如小写、大写和数字。它还会设置操作系统环境中相应的 - LC_COLLATELC_CTYPE。 - 默认值与模板数据库中的设置相同。详见 - 和 - 。 - - - 也可以通过分别设置 、 - 、 - 或 - 来覆盖它。 - - - 如果 是 - builtin,则必须指定 - locale 或 - builtin_locale,并将其设为 - CC.UTF-8 或 - PG_UNICODE_FAST之一。 - + 这是同时设置 LC_COLLATELC_CTYPE 的快捷方式。 其他区域设置参数 、 @@ -158,87 +130,35 @@ CREATE DATABASE name lc_collate - - 在数据库服务器的操作系统环境中设置 LC_COLLATE。 - 默认值为 的设置(如果已指定), - 否则与模板数据库中的设置相同。其他限制见下文。 - - - 如果 是 - libc,它还会设置新数据库中使用的默认排序规则, - 从而覆盖 的设置。 - + 新数据库中使用的排序规则(LC_COLLATE)。这会影响字符串的排序顺序,例如在带有 ORDER BY 的查询中,以及文本列索引中使用的顺序。默认值是使用模板数据库的排序规则。请参见下文的其他限制。 lc_ctype - - 在数据库服务器的操作系统环境中设置 LC_CTYPE。 - 默认值为 的设置(如果已指定), - 否则与模板数据库中的设置相同。其他限制见下文。 - - - 如果 是 - libc,它还会设置新数据库中使用的默认字符分类, - 从而覆盖 的设置。 - + 新数据库中使用的字符分类(LC_CTYPE)。这会影响字符的分类,例如小写、大写和数字。默认值是使用模板数据库的字符分类。请参见下文的其他限制。 - - builtin_locale - - - 指定用于数据库默认排序规则和字符分类的 builtin 提供程序区域设置, - 从而覆盖 的设置。 - 区域设置提供程序 - 必须是 builtin。默认值为 - 的设置(如果已指定),否则与模板数据库中的设置相同。 - - - builtin 提供程序可用的区域设置有 - CC.UTF-8 和 - PG_UNICODE_FAST。 - - - + icu_locale - 指定 ICU 区域设置(见 ), - 用于数据库默认排序规则和字符分类,从而覆盖 - 的设置。 - 区域设置提供程序 - 必须是 ICU。默认值为 的设置 - (如果已指定),否则与模板数据库中的设置相同。 + 如果使用 ICU 区域设置提供程序,则指定 ICU 区域设置 ID。 - - icu_rules - - - 指定附加的排序规则,用以定制该数据库默认排序规则的行为。该选项仅支持 - ICU。详见 。 - - - + locale_provider - 指定该数据库默认排序规则使用的提供程序。可能的值为 builtin、 - icuICU - (如果服务器构建时启用了 ICU 支持)或 libc。 - 默认情况下,该值与 - 的区域设置提供程序相同。详见 - 。 + 指定该数据库默认排序规则使用的提供程序。可能的值为:icuICUlibc。默认值为libc。可用选项取决于操作系统和构建选项。 @@ -358,7 +278,7 @@ CREATE DATABASE nameLC_CTYPE)兼容。如果区域设置为 C (或等价的 POSIX),则允许所有编码;但对于其他区域设置,只有一种编码能够正常工作。(不过,在 Windows 上,UTF-8 编码可与任何区域设置一起使用。) CREATE DATABASE 允许超级用户不考虑区域设置而指定 - SQL_ASCII 编码,但这种选择已被废弃;如果数据库中存储了与该区域设置不兼容编码的数据,字符串函数的行为可能会出错。 + SQL_ASCII 编码,但这种选择已弃用;如果数据库中存储了与该区域设置不兼容编码的数据,字符串函数的行为可能会出错。 @@ -408,7 +328,7 @@ CREATE DATABASE music TEMPLATE template0; 在这个示例中,如果指定的区域设置与 template1 中的不同, - 则必须使用 TEMPLATE template0 子句。(如果并不不同, + 则必须使用 TEMPLATE template0 子句。(如果相同, 那么显式指定区域设置就是多余的。) diff --git a/zh/15/ref/create_domain.sgml b/zh/15/ref/create_domain.sgml index 905dd30d..420bbf83 100644 --- a/zh/15/ref/create_domain.sgml +++ b/zh/15/ref/create_domain.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE DOMAIN 7 - SQL - Language Statements + SQL - 语言语句 @@ -86,7 +86,7 @@ CREATE DOMAIN name [ AS ] 该域的可选排序规则。如果未指定排序规则,则该域的排序规则行为与其 底层数据类型相同。如果指定了COLLATE,则底层 - 类型必须是一种可排序数据类型。 + 类型必须是一种支持排序规则的数据类型。 diff --git a/zh/15/ref/create_event_trigger.sgml b/zh/15/ref/create_event_trigger.sgml index 95987ce3..f1be5a62 100644 --- a/zh/15/ref/create_event_trigger.sgml +++ b/zh/15/ref/create_event_trigger.sgml @@ -13,7 +13,7 @@ PostgreSQL documentation CREATE EVENT TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -44,7 +44,7 @@ CREATE EVENT TRIGGER name CREATE EVENT TRIGGER创建一个新的事件触发器。 每当指定的事件发生,并且与该触发器关联的WHEN条件(如果有)得到 满足时,就会执行该触发器函数。有关事件触发器的一般性介绍,见 - 。创建事件触发器的用户将成为其拥有者。 + 。创建事件触发器的用户将成为其所有者。 @@ -83,8 +83,7 @@ CREATE EVENT TRIGGER name - 用于过滤事件的变量名称。这使得可以将触发器限定为只在支持该变量的部 - 分情形下触发。当前唯一支持的 + 用于过滤事件的变量名称。这样可以将触发器限定为只在原本支持的部分情形下触发。当前唯一支持的 filter_variableTAG @@ -140,6 +139,8 @@ CREATE EVENT TRIGGER name 只有超级用户能创建事件触发器。 + 事件触发器在单用户模式下被禁用(参见 )。如果错误的事件触发器导致数据库严重失效,以至于无法删除触发器,可以重启到单用户模式,然后就能执行删除操作。 + @@ -183,7 +184,7 @@ CREATE EVENT TRIGGER abort_ddl ON ddl_command_start - 另见 + 参见 diff --git a/zh/15/ref/create_extension.sgml b/zh/15/ref/create_extension.sgml index 1503df25..7acc3a5e 100644 --- a/zh/15/ref/create_extension.sgml +++ b/zh/15/ref/create_extension.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE EXTENSION 7 - SQL - Language Statements + SQL - 语言语句 @@ -82,10 +82,9 @@ CREATE EXTENSION [ IF NOT EXISTS ] extension_name 要安装的扩展名称。PostgreSQL将根据 - 文件 extension_name.control - 中的详细信息创建该扩展;该文件通过服务器的扩展控制路径找到 - (由 设置)。 + SHAREDIR/extension/extension_name.control + 文件中的详细信息创建该扩展。 @@ -167,7 +166,7 @@ CREATE EXTENSION [ IF NOT EXISTS ] extension_name 会在之后执行编写粗心的扩展脚本时实施攻击,使该用户获得超级用户权限。 不过,只有当特洛伊木马对象在脚本执行期间位于 search_path 中时,它们才会构成危险;这意味着它们 - 位于扩展的安装目标模式中,或位于它所依赖的某个扩展所属的模式中。 + 位于扩展的安装目标模式中,或位于它所依赖的某个扩展的目标模式中。 因此,处理那些脚本尚未经过仔细审查的扩展时,一个经验法则是: 只把它们安装到从未向任何不受信任用户授予、而且今后也不会授予 CREATE 权限的模式中。它们所依赖的任何扩展也应如此。 diff --git a/zh/15/ref/create_foreign_data_wrapper.sgml b/zh/15/ref/create_foreign_data_wrapper.sgml index bfa097ef..0611709d 100644 --- a/zh/15/ref/create_foreign_data_wrapper.sgml +++ b/zh/15/ref/create_foreign_data_wrapper.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE FOREIGN DATA WRAPPER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/create_foreign_table.sgml b/zh/15/ref/create_foreign_table.sgml index 787d3748..5e7768bf 100644 --- a/zh/15/ref/create_foreign_table.sgml +++ b/zh/15/ref/create_foreign_table.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE FOREIGN TABLE 7 - SQL - Language Statements + SQL - 语言语句 @@ -143,9 +143,7 @@ WITH ( MODULUS numeric_literal, REM COLLATE collation - - COLLATE子句为该列(必须是一种可排序数据类型)指定一个排序规则。如果未指定,则使用该列数据类型的默认排序规则。 - + COLLATE子句为列指定排序规则(该列必须属于支持排序规则的数据类型)。如果未指定,则使用列数据类型的默认排序规则。 diff --git a/zh/15/ref/create_function.sgml b/zh/15/ref/create_function.sgml index b6447707..5b894c32 100644 --- a/zh/15/ref/create_function.sgml +++ b/zh/15/ref/create_function.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation CREATE FUNCTION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/create_group.sgml b/zh/15/ref/create_group.sgml index 06195a91..9a6538ed 100644 --- a/zh/15/ref/create_group.sgml +++ b/zh/15/ref/create_group.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE GROUP 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/create_index.sgml b/zh/15/ref/create_index.sgml index 1c525288..cab7ed99 100644 --- a/zh/15/ref/create_index.sgml +++ b/zh/15/ref/create_index.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation CREATE INDEX 7 - SQL - Language Statements + SQL - 语言语句 @@ -57,7 +57,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] PostgreSQL提供了索引方法 - B-树、哈希、GiST、SP-GiST、GIN 以及 BRIN。用户也可以定义自己的索引 + B-树、hash、GiST、SP-GiST、GIN 以及 BRIN。用户也可以定义自己的索引 方法,但这相当复杂。 @@ -123,7 +123,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] 对于临时表,CREATE INDEX始终是非并发的, - 因为没有其他会话可以访问它们,而且非并发创建索引的成本更低。 + 因为没有其他会话可以访问它们,而且非并发创建索引的代价更低。 @@ -373,10 +373,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] 可选的WITH子句为索引指定存储参数。每一种 索引方法都有其各自允许的存储参数集合。 - - - - B-树、哈希、GiST 和 SP-GiST 索引方法都接受以下参数: + B-树、hash、GiST 和 SP-GiST 索引方法都接受以下参数: @@ -390,7 +387,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - 控制索引方法尝试将索引页填充到多满。对于 B-树,在初始构建索引时, + 索引的填充因子是一个百分比,用于确定索引方法尝试将索引页填充到多满。对于 B-树,在初始构建索引时, 以及在右侧扩展索引(加入新的最大键值)时,叶子页都会填充到这一 百分比。如果页面随后变成全满,就会发生分裂,从而导致磁盘上的 索引结构碎片化。B-树默认使用 90 的填充因子,但也可以选择 10 到 @@ -471,7 +468,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - 控制是否使用中描述的缓冲构建技术 + 确定是否使用中描述的缓冲构建技术 来构建索引。设置为OFF时禁用缓冲构建,设置为 ON时启用,设置为AUTO时初始为 禁用,但一旦索引大小达到, @@ -484,7 +481,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - GIN 索引接受以下参数: + GIN 索引接受不同的参数: @@ -498,8 +495,8 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - 控制中描述的快速更新技术的使用。 - ON 启用快速更新,OFF 禁用快速更新。 + 此设置控制中描述的快速更新技术的使用。 + 这是一个布尔参数:ON 启用快速更新,OFF 禁用快速更新。 默认值为ON @@ -528,7 +525,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - 为该索引覆盖的全局设置。 + 自定义参数。 该值以千字节为单位。 @@ -536,7 +533,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - BRIN 索引接受以下参数: + BRIN 索引接受不同的参数: @@ -566,7 +563,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - 定义当在下一页范围检测到插入时,是否为前一页范围排队执行一次提要操作 + 定义当在下一页范围检测到插入时,是否为前一页范围排队执行一次范围摘要操作 (详见)。 默认值为off @@ -580,8 +577,8 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] 并发构建索引 - index - building concurrently + 索引 + 并发构建 @@ -733,11 +730,6 @@ Indexes: 生成这些索引的统计信息。 - - 在 CREATE INDEX 执行期间, - 会被临时设置为 pg_catalog, pg_temp。 - - 对于大多数索引方法,索引的创建速度取决于 的设置。较大的值将会减少 @@ -748,7 +740,7 @@ Indexes: PostgreSQL可以在构建索引时利用多个 CPU, 以便更快处理表中的行。这项特性被称为并行索引构建。 - 对于支持并行构建索引的索引方法(当前为 B-树、GIN 和 BRIN), + 对于支持并行构建索引的索引方法(当前只有 B-树), maintenance_work_mem指定每次索引构建操作整体最多 可使用的内存量,而不管启动了多少工作者进程。通常,代价模型会自动决 定是否需要请求工作者进程,以及请求多少个。 diff --git a/zh/15/ref/create_language.sgml b/zh/15/ref/create_language.sgml index fca9e159..5d737764 100644 --- a/zh/15/ref/create_language.sgml +++ b/zh/15/ref/create_language.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE LANGUAGE 7 - SQL - Language Statements + SQL - 语言语句 @@ -96,7 +96,7 @@ CREATE [ OR REPLACE ] [ TRUSTED ] [ PROCEDURAL ] LANGUAGE name [ DEFAUL 会妨碍优化器识别该查询匹配一个索引。 + + 在PostgreSQL 8.4 之前,OPERATOR子句可以包含RECHECK选项。现在不再支持该选项,因为索引操作符是否有损会在运行时动态确定。这样可以高效处理操作符可能有损也可能无损的情况。 + diff --git a/zh/15/ref/create_operator.sgml b/zh/15/ref/create_operator.sgml index faae3140..9ea345ed 100644 --- a/zh/15/ref/create_operator.sgml +++ b/zh/15/ref/create_operator.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE OPERATOR 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/create_opfamily.sgml b/zh/15/ref/create_opfamily.sgml index 1577f0c1..9d31bb01 100644 --- a/zh/15/ref/create_opfamily.sgml +++ b/zh/15/ref/create_opfamily.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE OPERATOR FAMILY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/create_policy.sgml b/zh/15/ref/create_policy.sgml index 9a5fc65e..d3c49bc8 100644 --- a/zh/15/ref/create_policy.sgml +++ b/zh/15/ref/create_policy.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE POLICY 7 - SQL - Language Statements + SQL - 语言语句 @@ -515,9 +515,7 @@ CREATE POLICY name ON MERGE ... THEN INSERT - - 检查新行  - + 检查新行 diff --git a/zh/15/ref/create_procedure.sgml b/zh/15/ref/create_procedure.sgml index eaa88de6..fe20673f 100644 --- a/zh/15/ref/create_procedure.sgml +++ b/zh/15/ref/create_procedure.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation CREATE PROCEDURE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/create_publication.sgml b/zh/15/ref/create_publication.sgml index 7f80bf1a..e4c38095 100644 --- a/zh/15/ref/create_publication.sgml +++ b/zh/15/ref/create_publication.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE PUBLICATION 7 - SQL - Language Statements + SQL - 语言语句 @@ -85,12 +85,9 @@ CREATE PUBLICATION name - 指定列列表时,只复制其中列出的列。列列表也可以包含存储生成列。 - 如果省略列列表,则该发布默认复制所有非生成列(包括今后新增的列)。 - 如果将publish_generated_columns设为 - stored,也可以复制存储生成列。指定列列表对 - TRUNCATE命令没有影响。有关列列表的详细信息, - 请参见。 + 指定列列表时,只复制其中列出的列。如果省略列列表,则该发布会复制该表的所有列, + 包括今后新增的列。指定列列表对TRUNCATE命令没有影响。 + 有关列列表的详细信息,请参见 @@ -167,36 +164,7 @@ CREATE PUBLICATION name - - publish_generated_columns (enum) - - - 指定是否复制与该发布关联的表中存在的生成列。可选值为 - nonestored。 - - - - 默认值为none,表示不会复制与该发布关联的表中的生成列。 - - - 如果设为stored,则会复制与该发布关联的表中的存储生成列。 - - - - - 如果订阅端版本早于 18,那么即使发布端的 - publish_generated_columns参数为 - stored,初始表同步时也不会复制生成列。 - - - - - 有关生成列逻辑复制的更多细节,请参见 - 。 - - - publish_via_partition_root (boolean) @@ -209,12 +177,7 @@ CREATE PUBLICATION name 非分区表,或者复制到分区结构与发布端不同的分区表。 - - 订阅可能会组合多个发布。如果任一已订阅发布以 - publish_via_partition_root = true发布某个分区表, - 那么该分区表(或其分区)上的更改将使用该分区表本身的标识和模式来发布, - 而不是使用各个分区的标识和模式。 - + 该参数还会影响为分区选择行过滤器和列列表的方式;详见下文。 @@ -231,11 +194,7 @@ CREATE PUBLICATION name - - 指定boolean类型的参数时, - 可以省略= value - 部分,这等价于指定TRUE。 - + @@ -282,12 +241,7 @@ CREATE PUBLICATION name 操作符、类型和排序规则、系统列引用,或非不可变内置函数。 - - 属于REPLICA IDENTITY的生成列必须被显式发布, - 即要么将其列入列列表,要么启用publish_generated_columns - 选项,这样UPDATEDELETE - 操作才能被发布。 - + 如果指定了FOR TABLES IN SCHEMA,并且该表属于所引用的模式, diff --git a/zh/15/ref/create_role.sgml b/zh/15/ref/create_role.sgml index 337ac043..62d380b3 100644 --- a/zh/15/ref/create_role.sgml +++ b/zh/15/ref/create_role.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE ROLE 7 - SQL - Language Statements + SQL - 语言语句 @@ -36,8 +36,10 @@ CREATE ROLE name [ [ WITH ] password' | PASSWORD NULL | VALID UNTIL 'timestamp' | IN ROLE role_name [, ...] + | IN GROUP role_name [, ...] | ROLE role_name [, ...] | ADMIN role_name [, ...] + | USER role_name [, ...] | SYSID uid @@ -64,13 +66,7 @@ in sync when changing the above synopsis! 注意,角色是在数据库集簇级别定义的,因此在该集簇中的所有数据库里都有效。 - - 在创建角色时,可以立即将新建角色加入现有角色,也可以将现有角色加入新建角色。 - 关于初始角色成员资格会启用哪些选项,其规则见下文 - IN ROLEROLEADMIN - 子句的说明。命令在创建成员资格时提供了更细粒度 - 的选项控制,也可以在新角色创建后修改这些选项。 - + @@ -103,13 +99,7 @@ in sync when changing the above synopsis! CREATEDB NOCREATEDB - - 这些子句定义角色创建数据库的能力。如果指定CREATEDB, - 正在定义的角色将被允许创建新数据库。指定NOCREATEDB - 则会禁止该角色创建数据库。若未指定,默认值是 - NOCREATEDB。只有超级用户角色或拥有 - CREATEDB属性的角色才能指定CREATEDB。 - + 这些子句定义角色创建数据库的能力。如果指定CREATEDB,则允许正在定义的角色创建新数据库。指定NOCREATEDB会禁止角色创建数据库。如果未指定,默认值为NOCREATEDB @@ -119,7 +109,7 @@ in sync when changing the above synopsis! 这些子句决定某个角色是否被允许创建、更改、删除其他角色,为其添加注释, - 以及更改其安全标签。关于该权限赋予的具体能力,参见 + 更改其安全标签,以及授予或撤销其中的成员资格。关于该权限赋予的具体能力,参见 。若未指定,默认值是 NOCREATEROLE @@ -130,19 +120,7 @@ in sync when changing the above synopsis! INHERIT NOINHERIT - - 这会影响该角色在本命令以及后续命令中被加入为其他角色成员时,其成员资格 - 的继承状态。具体来说,它控制通过本命令中的IN ROLE - 子句添加的成员资格的继承状态,以及通过后续命令中的ROLE - 子句添加的成员资格的继承状态。使用GRANT命令把该角色 - 添加为成员时,它也会被用作默认继承状态。若未指定,默认值是 - INHERIT。 - - - - 在PostgreSQL 16 之前的版本中,继承是一个 - 角色级属性,用于控制该角色在运行时的所有成员资格检查。 - + 这些子句决定角色是否继承其所属角色的权限。具有INHERIT属性的角色可以自动使用直接或间接所属的所有角色获得的任何数据库权限。没有INHERIT时,成为另一个角色的成员只授予对该角色执行SET ROLE的能力;另一个角色的权限只有在执行该操作后才可用。如果未指定,默认值为INHERIT @@ -150,15 +128,7 @@ in sync when changing the above synopsis! LOGIN NOLOGIN - - 这些子句决定一个角色是否允许登录,也就是说,该角色能否在客户端连接时 - 被用作初始会话授权标识符。具有LOGIN属性的角色可以视为 - 用户。没有这个属性的角色对于管理数据库权限很有用,但并不是通常意义上的 - 用户。若未指定,默认值是NOLOGIN;但当 - CREATE ROLE以其另一种拼写 - CREATE USER - 调用时,默认值是LOGIN。 - + 这些子句决定是否允许角色登录;也就是说,在客户端连接期间,是否可以将该角色作为初始会话授权名称。具有LOGIN属性的角色可以视为用户。没有该属性的角色可用于管理数据库权限,但通常意义上不属于用户。如果未指定,默认值为NOLOGIN,但通过其另一种拼写CREATE USER调用CREATE ROLE时除外。 @@ -166,14 +136,7 @@ in sync when changing the above synopsis! REPLICATION NOREPLICATION - - 这些子句决定一个角色是否为复制角色。角色必须拥有该属性(或本身是超级用户), - 才能以复制模式(物理复制或逻辑复制)连接到服务器,也才能创建或删除复制槽。 - 具有REPLICATION属性的角色权限非常高,因此应只用于 - 实际承担复制任务的角色。若未指定,默认值是 - NOREPLICATION。只有超级用户角色或拥有 - REPLICATION属性的角色才能指定REPLICATION。 - + 这些子句决定角色是否为复制角色。角色必须具有此属性(或是超级用户),才能以复制模式(物理复制或逻辑复制)连接到服务器,以及创建或删除复制槽。具有REPLICATION属性的角色权限非常高,因此该属性只应赋予实际用于复制的角色。如果未指定,默认值为NOREPLICATION。要创建具有REPLICATION属性的新角色,必须是超级用户。 @@ -181,11 +144,7 @@ in sync when changing the above synopsis! BYPASSRLS NOBYPASSRLS - - 这些子句决定一个角色是否绕过所有行级安全(RLS)策略。默认值是 - NOBYPASSRLS。只有超级用户角色或拥有 - BYPASSRLS属性的角色才能指定BYPASSRLS。 - + 这些子句决定角色是否绕过每个行级安全(RLS)策略。NOBYPASSRLS是默认值。要创建具有BYPASSRLS属性的新角色,必须是超级用户。 注意,pg_dump 默认会把row_security设置为 @@ -233,13 +192,7 @@ in sync when changing the above synopsis! 的值是什么,它都会按原样存储(因为系统无法解密指定的已加密密码字符串, 再将其改用其他格式加密)。这样便可在转储/恢复期间重新装载已加密的密码。 - - - 对 MD5 加密密码的支持已被弃用,并将在未来的 - PostgreSQL版本中移除。关于迁移到其他密码类型 - 的细节,参见。 - - + @@ -257,9 +210,15 @@ in sync when changing the above synopsis! IN ROLE role_name - IN ROLE子句会使新角色自动成为指定现有角色的成员。 - 新建的成员资格将启用SET选项,并禁用ADMIN选项。 - 除非指定了NOINHERIT选项,否则还会启用INHERIT选项。 + IN ROLE子句列出一个或多个现有角色,新角色会立即被添加为这些角色的新成员。(注意,没有选项能将新角色添加为管理员;请另行使用GRANT命令执行此操作。) + + + + + + IN GROUP role_name + + IN GROUPIN ROLE的过时拼写。 @@ -268,11 +227,7 @@ in sync when changing the above synopsis! ROLE role_name - ROLE子句会使一个或多个指定的现有角色自动成为新角色 - 的成员,并启用SET选项。这实际上会使新角色成为一个 - 。在该子句中命名且具有角色级INHERIT - 属性的角色,其新建成员资格将启用INHERIT选项。新建 - 成员资格的ADMIN选项将被禁用。 + ROLE子句列出一个或多个现有角色,它们会被自动添加为新角色的成员。(这实际上使新角色成为一个。) @@ -281,9 +236,17 @@ in sync when changing the above synopsis! ADMIN role_name - ADMIN子句与ROLE效果相同,但被命名的 - 角色会作为新角色的成员加入,并启用ADMIN选项,从而使 - 它们有权将新角色的成员资格授予其他角色。 + ADMIN子句与ROLE类似,但所列角色会以WITH ADMIN + OPTION加入新角色,从而有权向其他人授予此角色的成员资格。 + + + + + + USER role_name + + + USER子句是ROLE子句的过时拼写。 @@ -321,18 +284,10 @@ in sync when changing the above synopsis! - 这里定义的角色属性都是不可继承的。也就是说,成为一个例如具有 - CREATEDB属性的角色成员,并不会让该成员在其成员资格授予 - 带有INHERIT选项的情况下也能创建新数据库。当然,如果该成员资格 - 带有SET选项,成员角色仍然可以 - SET ROLE切换到具有 - CREATEDB属性的角色,然后再创建新数据库。 + INHERIT属性控制可授予权限的继承(即数据库对象的访问权限和角色成员资格)。它不适用于通过CREATE ROLEALTER ROLE设置的特殊角色属性。例如,成为具有CREATEDB权限的角色的成员,并不会立即获得创建数据库的能力,即使设置了INHERIT也是如此;必须先通过SET ROLE成为该角色,才能创建数据库。 - - 通过IN ROLEROLEADMIN - 子句创建的成员资格,其授权者就是执行此命令的角色。 - + 之所以默认采用INHERIT属性,是出于向后兼容的考虑:在 @@ -340,6 +295,10 @@ in sync when changing the above synopsis! 全部权限。不过,NOINHERIT更接近 SQL 标准规定的语义。 + + 请谨慎对待CREATEROLE权限。对于具有CREATEROLE的角色的权限,没有继承的概念。这意味着,即使某个角色不具有某项权限,只要允许它创建其他角色,它就可以轻易创建权限与自身不同的另一个角色(但不能创建具有超级用户权限的角色)。例如,如果角色user具有CREATEROLE权限而没有CREATEDB权限,它仍然可以创建具有CREATEDB权限的新角色。因此,应将具有CREATEROLE权限的角色视为近乎超级用户的角色。 + + PostgreSQL包含一个程序,其功能与CREATE ROLE相同 @@ -415,25 +374,13 @@ CREATE ROLE name [ WITH ADMIN - 若要最接近 SQL 标准规定的行为,可以将 SQL 标准中的用户创建为带有 - NOINHERIT选项的PostgreSQL - 角色,而将 SQL 标准中的角色创建为带有INHERIT选项的 - PostgreSQL角色。 + 将用户赋予 NOINHERIT 属性,而将角色赋予 + INHERIT 属性,最接近 SQL 标准规定的行为。 - - USER子句的行为与ROLE相同,但已经被弃用: - -USER role_name [, ...] - - - - IN GROUP子句的行为与IN ROLE相同,但已经被弃用: - -IN GROUP role_name [, ...] - - + + diff --git a/zh/15/ref/create_rule.sgml b/zh/15/ref/create_rule.sgml index 6d1486c9..e8b37c6d 100644 --- a/zh/15/ref/create_rule.sgml +++ b/zh/15/ref/create_rule.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE RULE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/create_schema.sgml b/zh/15/ref/create_schema.sgml index 74944401..8b36ce72 100644 --- a/zh/15/ref/create_schema.sgml +++ b/zh/15/ref/create_schema.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE SCHEMA 7 - SQL - Language Statements + SQL - 语言语句 @@ -77,9 +77,7 @@ CREATE SCHEMA IF NOT EXISTS AUTHORIZATION role_sp user_name - 将拥有新模式的用户的角色名。如果省略,则默认为执行该命令的用户。要创建 - 由另一个角色拥有的模式,你必须能够对该角色执行 - SET ROLE。 + 将拥有新模式的用户的角色名。如果省略,则默认为执行该命令的用户。要创建由另一个角色拥有的模式,你必须是该角色的直接或间接成员,或者是超级用户。 diff --git a/zh/15/ref/create_sequence.sgml b/zh/15/ref/create_sequence.sgml index ffbf9797..c786a61f 100644 --- a/zh/15/ref/create_sequence.sgml +++ b/zh/15/ref/create_sequence.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation CREATE SEQUENCE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/create_server.sgml b/zh/15/ref/create_server.sgml index 586067b0..0cb4f9ed 100644 --- a/zh/15/ref/create_server.sgml +++ b/zh/15/ref/create_server.sgml @@ -13,7 +13,7 @@ PostgreSQL documentation CREATE SERVER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/create_statistics.sgml b/zh/15/ref/create_statistics.sgml index ecafe6c6..f007156a 100644 --- a/zh/15/ref/create_statistics.sgml +++ b/zh/15/ref/create_statistics.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE STATISTICS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/create_subscription.sgml b/zh/15/ref/create_subscription.sgml index 9311f13b..58cc8e28 100644 --- a/zh/15/ref/create_subscription.sgml +++ b/zh/15/ref/create_subscription.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE SUBSCRIPTION 7 - SQL - Language Statements + SQL - 语言语句 @@ -33,7 +33,7 @@ CREATE SUBSCRIPTION subscription_name CREATE SUBSCRIPTION添加一个新的逻辑复制订阅。 - 创建订阅的用户将成为该订阅的所有者。订阅名称必须与当前数据库中 + 订阅名称必须与当前数据库中 任何现有订阅的名称不同。 @@ -47,10 +47,7 @@ CREATE SUBSCRIPTION subscription_name - - 要能够创建订阅,必须具有pg_create_subscription角色的权限, - 以及当前数据库上的CREATE权限。 - + 关于订阅以及整个逻辑复制的更多信息,请参见 @@ -118,12 +115,7 @@ CREATE SUBSCRIPTION subscription_nametrue。) - - 由于该选项为false时不会建立连接,因此不会订阅任何表。 - 要启动复制,你必须手工创建复制槽、在需要时启用故障切换、启用订阅, - 并刷新订阅。示例见 - 。 - + 由于该选项为false时不会建立连接,因此不会订阅任何表,所以即使之后启用了订阅,也不会复制任何内容。随后需要执行ALTER SUBSCRIPTION ... REFRESH PUBLICATION,才能订阅这些表。 @@ -133,12 +125,7 @@ CREATE SUBSCRIPTION subscription_name 指定该命令是否应在发布者上创建复制槽。默认值为 true。 - - - 如果设为false,则必须以其他方式自行创建 - 发布者上的复制槽。示例见 - 。 - + 如果设为false,则必须以其他方式自行创建发布者上的复制槽。 @@ -159,25 +146,7 @@ CREATE SUBSCRIPTION subscription_name - - 将slot_name设为NONE表示该订阅 - 不关联任何复制槽。这类订阅还必须同时将enabled - 和create_slot设为false。 - 当你打算稍后手工创建复制槽时,可使用此设置。示例见 - 。 - - - - 将slot_name设为有效名称且 - create_slot设为false时, - 所指定复制槽的failover属性值可能与订阅中对应的 - failover参数不同。应始终确保该槽的 - failover属性与订阅中的对应参数一致,反之亦然。 - 否则,发布者上的该槽的行为可能与这些订阅选项所表明的不同:例如, - 即使订阅的failover选项已禁用,发布者上的该槽仍可能 - 被同步到备库;或者即使订阅的failover选项已启用, - 该槽也可能不会被同步到备库。 - + slot_name设为NONE表示该订阅不关联任何复制槽。当打算稍后手工创建复制槽时,可使用此设置。这类订阅还必须同时将enabledcreate_slot设为false @@ -193,16 +162,8 @@ CREATE SUBSCRIPTION subscription_name 指定订阅是否请求发布者以二进制格式(而不是文本格式)发送数据。 - 默认值为false。任何初始表同步复制 - (见copy_data)也使用相同格式。二进制格式可能 - 比文本格式更快,但在不同机器架构和 - PostgreSQL版本之间的可移植性较差。 - 二进制格式对数据类型非常敏感;例如,虽然在文本格式下可以正常工作, - 但它不允许从smallint列复制到integer列。 - 即使启用了此选项,也只有具有二进制发送和接收函数的数据类型才会以 - 二进制方式传输。注意,初始同步要求所有数据类型都具有二进制发送和 - 接收函数,否则同步将失败(关于发送/接收函数的更多信息,请参见 - )。 + 默认值为false。即使启用了此选项,也只有具有 + 二进制发送和接收函数的数据类型才会以二进制方式传输。 @@ -210,13 +171,6 @@ CREATE SUBSCRIPTION subscription_namebinary选项。 - - - 如果发布者使用的是 16 之前版本的 - PostgreSQL,那么即使 - binary = true,任何初始表同步也都会使用 - 文本格式。 - @@ -227,45 +181,20 @@ CREATE SUBSCRIPTION subscription_nametrue。 + 如果这些发布包含WHERE子句,将会影响被复制的数据。 详情请参见 - - 关于copy_data = true如何与 - origin参数相互作用的细节,请参见 - 。 - - streaming (enum) + streaming (boolean) - 指定是否为该订阅启用进行中事务的流式传输。默认值为 - parallel,表示如果有可用的并行应用工作进程, - 接收到的更改会直接通过其中之一应用。如果没有空闲的并行应用工作进程 - 可以处理流式事务,那么这些更改会写入临时文件,并在事务提交后再应用。 - 注意,如果并行应用工作进程中发生错误,远端事务的 finish LSN - 可能不会记录到服务器日志中。 - - - - - 当发布者与订阅者的模式不同时,存在发生死锁的风险,尽管这种情况 - 很少见。应用工作进程会自动重试这些事务。 - - - - - 如果设为on,接收到的更改会写入临时文件,然后仅在 - 事务在发布者上提交且被订阅者接收之后才应用。 - - - - 如果设为off,所有事务都会先在发布者上完全解码, - 然后才整体发送给订阅者。 + 指定是否为该订阅启用进行中事务的流式传输。默认情况下,所有事务 + 都会先在发布者上被完全解码,然后才整体发送给订阅者。 @@ -333,69 +262,20 @@ CREATE SUBSCRIPTION subscription_name - - password_required (boolean) - - - 如果设为true,则由于该订阅而建立的到发布者的连接 - 必须使用密码认证,并且密码必须作为连接字符串的一部分指定。如果该订阅 - 由超级用户拥有,则此设置会被忽略。默认值为true。 - 只有超级用户才能将该值设为false。 - - - - - run_as_owner (boolean) - - - 如果为true,所有复制操作都以订阅所有者的身份执行。 - 如果为false,复制工作进程会在每张表上以该表所有者 - 的身份执行操作。后一种配置通常安全得多;详情请参见 - 。 - 默认值为false。 - - - - - origin (string) - - - 指定订阅是请求发布者仅发送没有复制源的更改,还是无论复制源如何都发送更改。 - 将origin设为none表示订阅会请求 - 发布者仅发送没有复制源的更改。将origin设为 - any表示发布者无论复制源如何都发送更改。默认值为 - any。 - - - 关于copy_data = true如何与 - origin参数相互作用的细节,请参见 - 。 - - - - - failover (boolean) - - - 指定与该订阅关联的复制槽是否启用同步到备库,以便在故障切换后 - 能够从新的主库继续逻辑复制。默认值为false。 - - - + + + + - - 指定boolean类型的参数时, - = value - 部分可以省略,这等价于指定TRUE。 - + @@ -416,10 +296,9 @@ CREATE SUBSCRIPTION subscription_nameCREATE SUBSCRIPTION 调用将挂起。要实现这种用法,应分别创建复制槽(使用函数 - pg_create_logical_replication_slot并指定插件名 + pg_create_logical_replication_slot 并指定插件名 pgoutput),然后使用参数 - create_slot = false创建订阅。示例见 - 。 + create_slot = false 创建订阅。 这是一个实现限制,未来版本中可能会解除。 @@ -432,15 +311,15 @@ CREATE SUBSCRIPTION subscription_nameWHERE子句,如果其中某个发布没有 WHERE子句(针对相应的发布操作),或者该发布被声明为 - FOR ALL TABLES + FOR ALL TABLES 或 - FOR TABLES IN SCHEMA, + FOR TABLES IN SCHEMA, 则无论其他表达式如何定义,该行都会被发布。如果订阅者使用的是 15 之前 版本的PostgreSQL,那么在初始数据同步阶段 会忽略所有行过滤。在这种情况下,用户可能需要考虑删除那些初始复制过来、 但与后续过滤不兼容的数据。由于初始数据同步在复制现有表数据时不会考虑 发布的 - publish + publish 参数,因此有些使用 DML 时本不会复制的行,也可能在此阶段被复制。示例见 。 @@ -455,31 +334,9 @@ CREATE SUBSCRIPTION subscription_name - - 当使用copy_data = true和 - origin = NONE这一订阅参数组合时,初始同步的表数据会 - 直接从发布者复制过来,因此无法得知这些数据的真实来源。如果发布者本身 - 也有订阅,那么复制过来的表数据可能来自更上游。系统会检测到这种情况, - 并向用户记录一条WARNING,但这条警告只表明可能存在问题;用户仍需 - 自行进行必要检查,以确认复制过来的数据来源是否确实符合预期。 - - - 若要找出哪些表可能包含非本地来源的数据(由于在发布者上创建了其他订阅), - 可以尝试执行以下 SQL 查询: - -# substitute <pub-names> below with your publication name(s) to be queried -SELECT DISTINCT PT.schemaname, PT.tablename -FROM pg_publication_tables PT - JOIN pg_class C ON (C.relname = PT.tablename) - JOIN pg_namespace N ON (N.nspname = PT.schemaname), - pg_subscription_rel PS -WHERE C.relnamespace = N.oid AND - (PS.srrelid = C.oid OR - C.oid IN (SELECT relid FROM pg_partition_ancestors(PS.srrelid) UNION - SELECT relid FROM pg_partition_tree(PS.srrelid))) AND - PT.pubname IN (<pub-names>); - + + diff --git a/zh/15/ref/create_table.sgml b/zh/15/ref/create_table.sgml index 01eced4e..52b86af2 100644 --- a/zh/15/ref/create_table.sgml +++ b/zh/15/ref/create_table.sgml @@ -4,7 +4,6 @@ PostgreSQL documentation --> - CREATE TABLE @@ -12,7 +11,7 @@ PostgreSQL documentation CREATE TABLE 7 - SQL - Language Statements + SQL - 语言语句 @@ -23,7 +22,7 @@ PostgreSQL documentation CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXISTS ] table_name ( [ - { column_name data_type [ STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN | DEFAULT } ] [ COMPRESSION compression_method ] [ COLLATE collation ] [ column_constraint [ ... ] ] + { column_name data_type [ COMPRESSION compression_method ] [ COLLATE collation ] [ column_constraint [ ... ] ] | table_constraint | LIKE source_table [ like_option ... ] } [, ... ] @@ -59,56 +58,55 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI [ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ] [ TABLESPACE tablespace_name ] -where column_constraint is: +其中column_constraint为: [ CONSTRAINT constraint_name ] -{ NOT NULL [ NO INHERIT ] | +{ NOT NULL | NULL | CHECK ( expression ) [ NO INHERIT ] | DEFAULT default_expr | - GENERATED ALWAYS AS ( generation_expr ) [ STORED | VIRTUAL ] | + GENERATED ALWAYS AS ( generation_expr ) STORED | GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( sequence_options ) ] | UNIQUE [ NULLS [ NOT ] DISTINCT ] index_parameters | PRIMARY KEY index_parameters | REFERENCES reftable [ ( refcolumn ) ] [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE referential_action ] [ ON UPDATE referential_action ] } -[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ] [ ENFORCED | NOT ENFORCED ] +[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ] -and table_constraint is: +table_constraint为: [ CONSTRAINT constraint_name ] { CHECK ( expression ) [ NO INHERIT ] | - NOT NULL column_name [ NO INHERIT ] | - UNIQUE [ NULLS [ NOT ] DISTINCT ] ( column_name [, ... ] [, column_name WITHOUT OVERLAPS ] ) index_parameters | - PRIMARY KEY ( column_name [, ... ] [, column_name WITHOUT OVERLAPS ] ) index_parameters | + UNIQUE [ NULLS [ NOT ] DISTINCT ] ( column_name [, ... ] ) index_parameters | + PRIMARY KEY ( column_name [, ... ] ) index_parameters | EXCLUDE [ USING index_method ] ( exclude_element WITH operator [, ... ] ) index_parameters [ WHERE ( predicate ) ] | - FOREIGN KEY ( column_name [, ... ] [, PERIOD column_name ] ) REFERENCES reftable [ ( refcolumn [, ... ] [, PERIOD refcolumn ] ) ] + FOREIGN KEY ( column_name [, ... ] ) REFERENCES reftable [ ( refcolumn [, ... ] ) ] [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE referential_action ] [ ON UPDATE referential_action ] } -[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ] [ ENFORCED | NOT ENFORCED ] +[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ] -and like_option is: +like_option为: { INCLUDING | EXCLUDING } { COMMENTS | COMPRESSION | CONSTRAINTS | DEFAULTS | GENERATED | IDENTITY | INDEXES | STATISTICS | STORAGE | ALL } -and partition_bound_spec is: +partition_bound_spec为: IN ( partition_bound_expr [, ...] ) | FROM ( { partition_bound_expr | MINVALUE | MAXVALUE } [, ...] ) TO ( { partition_bound_expr | MINVALUE | MAXVALUE } [, ...] ) | WITH ( MODULUS numeric_literal, REMAINDER numeric_literal ) -index_parameters in UNIQUE, PRIMARY KEY, and EXCLUDE constraints are: +UNIQUEPRIMARY KEYEXCLUDE约束中的index_parameters为: [ INCLUDE ( column_name [, ... ] ) ] [ WITH ( storage_parameter [= value] [, ... ] ) ] [ USING INDEX TABLESPACE tablespace_name ] -exclude_element in an EXCLUDE constraint is: +EXCLUDE约束中的exclude_element为: { column_name | ( expression ) } [ COLLATE collation ] [ opclass [ ( opclass_parameter = value [, ... ] ) ] ] [ ASC | DESC ] [ NULLS { FIRST | LAST } ] -referential_action in a FOREIGN KEY/REFERENCES constraint is: +FOREIGN KEY/REFERENCES 约束中的 referential_action 为: { NO ACTION | RESTRICT | CASCADE | SET NULL [ ( column_name [, ... ] ) ] | SET DEFAULT [ ( column_name [, ... ] ) ] } @@ -148,16 +146,13 @@ WITH ( MODULUS numeric_literal, REM - 参数 - - TEMPORARY or TEMP + TEMPORARYTEMP - 如果指定该选项,表将创建为临时表。 临时表会在会话结束时自动删除,或者也可在当前事务结束时删除(见下文 ON COMMIT)。 @@ -170,7 +165,7 @@ WITH ( MODULUS numeric_literal, REM - 可以在 TEMPORARYTEMP 前写 GLOBALLOCAL。这在当前的 PostgreSQL 中没有区别,而且已废弃;见下文 。 + 可以在 TEMPORARYTEMP 前写 GLOBALLOCAL。这在当前的 PostgreSQL 中没有区别,而且已弃用;见下文 @@ -178,7 +173,6 @@ WITH ( MODULUS numeric_literal, REM UNLOGGED - 如果指定该选项,表将创建为不记录 WAL 的表。写入不记录 WAL 的表的数据不会写入预写式日志(见 ),因此它们比普通表快得多。不过,它们不具备崩溃安全性:在崩溃或非正常关闭后,不记录 WAL 的表会被自动截断。不记录 WAL 的表的内容也不会复制到备库。在不记录 WAL 的表上创建的任何索引也都会自动成为不记录 WAL 的。 @@ -186,10 +180,6 @@ WITH ( MODULUS numeric_literal, REM 如果指定该选项,与不记录 WAL 的表一起创建的任何序列(用于标识列或 serial 列)也会创建为不记录 WAL 的。 - - - 这种形式不支持分区表。 - @@ -216,14 +206,9 @@ WITH ( MODULUS numeric_literal, REM OF type_name + 创建一个类型化表,其结构取自指定的复合类型(名称可以带模式限定)。类型化表与其类型绑定;例如,如果删除该类型(使用DROP TYPE ... CASCADE),该表也会被删除。 - - 创建一个类型化表,其结构取自指定的独立复合类型(即通过 创建的类型),同时该表自身也会生成一个新的复合类型。该表会依赖于所引用的类型,这意味着对该类型执行级联的 ALTER 或 DROP 操作会传播到该表。 - - - - 类型化表的列名和数据类型始终与其派生类型相同,因此不能再指定额外的列。但 CREATE TABLE 命令仍可为该表添加默认值和约束,并指定存储参数。 - + 创建类型化表时,列的数据类型由底层复合类型决定,不由CREATE TABLE命令指定。不过,CREATE TABLE命令可以为表添加默认值和约束,并指定存储参数。 @@ -252,26 +237,7 @@ WITH ( MODULUS numeric_literal, REM COLLATE collation - - - COLLATE 子句为该列(必须是一种可排序数据类型)赋予一个排序规则。 - 如果没有指定,将使用该列数据类型的默认排序规则。 - - - - - - - STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN | DEFAULT } - - TOAST - per-column storage settings - - - - - 该形式设置列的存储模式,用于控制该列是以内联形式存储还是存入二级 TOAST 表,以及数据是否压缩。PLAIN 必须用于诸如 integer 的定长值,表示内联且不压缩。MAIN 用于内联且可压缩的数据。EXTERNAL 用于外部且不压缩的数据,EXTENDED 用于外部且压缩的数据。写成 DEFAULT 则将存储模式设置为该列数据类型的默认模式。对大多数支持非 PLAIN 存储的数据类型,默认是 EXTENDED。使用 EXTERNAL 可提高超大 textbytea 值上的子串操作速度,但代价是占用更多存储空间。详见 。 - + COLLATE子句为列指定排序规则(该列必须属于支持排序规则的数据类型)。如果未指定,则使用列数据类型的默认排序规则。 @@ -335,7 +301,6 @@ WITH ( MODULUS numeric_literal, REM PARTITION BY { RANGE | LIST | HASH } ( { column_name | ( expression ) } [ opclass ] [, ...] ) - 可选的 PARTITION BY 子句指定表的分区策略。 这样创建的表称为分区表。 @@ -356,6 +321,8 @@ WITH ( MODULUS numeric_literal, REM 如果没有现有分区与新行中的值匹配,就会报错。 + 分区表不支持EXCLUDE约束;不过,可以在各个分区上定义这些约束。 + 有关表分区的更多讨论,请参阅 @@ -366,7 +333,6 @@ WITH ( MODULUS numeric_literal, REM PARTITION OF parent_table { FOR VALUES partition_bound_spec | DEFAULT } - 将该表创建为指定父表的分区。 可以使用 FOR VALUES 将其创建为特定值的分区,也可以使用 DEFAULT 创建为默认分区。 @@ -424,13 +390,13 @@ WITH ( MODULUS numeric_literal, REM 还要注意,某些元素类型(如 timestamp)具有 - "infinity" 的概念,那只是另一种可存储的值。这不同于 + “无穷大” 的概念,那只是另一种可存储的值。这不同于 MINVALUEMAXVALUE,后两者并非可存储 的实际值,而只是表示值无界的方式。MAXVALUE 可以视为大于任何 - 其他值,包括 "infinity";MINVALUE 可以视为小于任何 - 其他值,包括 "minus infinity"。因此,范围 + 其他值,包括 “无穷大”;MINVALUE 可以视为小于任何 + 其他值,包括 “负无穷大”。因此,范围 FROM ('infinity') TO (MAXVALUE) 并不是空范围;它只允许存储 - 一个值 — "infinity"。 + 一个值 — “无穷大”。 @@ -488,19 +454,15 @@ WITH ( MODULUS numeric_literal, REM LIKE source_table [ like_option ... ] - LIKE 子句指定一个表,新表会自动从中复制所有列名、数据类型及其非空约束。 - INHERITS 不同,新表和原表在创建完成后就完全脱钩了。对原表的修改不会应用到新表,也不可能在扫描原表时包含新表的数据。 - 同样与 INHERITS 不同,由 LIKE 复制的列和约束不会与同名的列和约束合并。如果同一名称被显式指定,或在另一个 LIKE 子句中指定,则会报错。 - 可选的 like_option 子句指定还要复制原表的哪些附加属性。 指定 INCLUDING 表示复制该属性,指定 EXCLUDING 表示省略该属性。默认是 EXCLUDING。 @@ -548,7 +510,7 @@ WITH ( MODULUS numeric_literal, REM INCLUDING GENERATED - 会复制被复制列定义中的生成表达式以及 STORED/VIRTUAL 的选择。默认情况下,新列将是常规基表列。 + 会复制被复制列定义中的生成表达式。默认情况下,新列将是普通基础列。 @@ -621,16 +583,11 @@ WITH ( MODULUS numeric_literal, REM - NOT NULL [ NO INHERIT ] + NOT NULL - 该列不允许包含空值。 - - - 标记为 NO INHERIT 的约束不会传播到子表。 - @@ -651,7 +608,6 @@ WITH ( MODULUS numeric_literal, REM CHECK ( expression ) [ NO INHERIT ] - CHECK 子句指定一个产生布尔结果的表达式。要使插入或更新成功,新行或更新后的行必须满足该表达式。计算结果为 TRUE 或 UNKNOWN 的表达式视为成功。如果插入或更新操作中的任何一行得到 FALSE 结果,就会抛出错误异常,并且插入或更新不会修改数据库。作为列约束指定的检查约束只应引用该列的值,而出现在表约束中的表达式可以引用多个列。 @@ -661,7 +617,7 @@ WITH ( MODULUS numeric_literal, REM - 一个被标记为NO INHERIT的约束将不会传播到子表。 + 标记为 NO INHERIT 的约束不会传播到子表。 @@ -687,25 +643,17 @@ WITH ( MODULUS numeric_literal, REM - - GENERATED ALWAYS AS ( generation_expr ) [ STORED | VIRTUAL ]generated column + GENERATED ALWAYS AS ( generation_expr ) STORED生成列 - 此子句将列创建为生成列。列不可写入,读取时会返回指定表达式的结果。 - - 指定 VIRTUAL 时,列会在读取时计算且不占用存储;指定 STORED 时,列会在写入时计算并存储在磁盘上。默认是 VIRTUAL。 - + 必须使用关键字STORED,表示该列将在写入时计算并存储在磁盘上。 生成表达式可以引用表中的其他列,但不能引用其他生成的列。使用的任何函数和操作符都必须是不可变的。不允许引用其他表。 - - - 虚拟生成列不能使用用户定义类型,且其生成表达式不得引用用户定义函数或类型,也就是只能使用内置函数或类型。此限制也包含间接使用(例如操作符或类型转换背后的函数或类型)。该限制不适用于存储型生成列。 - @@ -746,38 +694,17 @@ WITH ( MODULUS numeric_literal, REM - UNIQUE [ NULLS [ NOT ] DISTINCT ](列约束) - - - UNIQUE [ NULLS [ NOT ] DISTINCT ] ( column_name [, ... ] [, column_name WITHOUT OVERLAPS ] ) - INCLUDE ( column_name [, ...]) (表约束) - + UNIQUE [ NULLS [ NOT ] DISTINCT ] ( column_name [, ... ] ) + INCLUDE ( column_name [, ...]) (表约束) - UNIQUE 约束指定表中一列或多列组成的一组只能包含唯一值。 表级唯一约束的行为与列级唯一约束相同,只是它还能跨越多列。因此,该约束 要求任意两行在这些列中至少有一列不同。 - - 如果为最后一列指定了 WITHOUT OVERLAPS 选项,则该列检查的 - 是是否重叠,而不是是否相等。在这种情况下,只要重复值在 - WITHOUT OVERLAPS 列上不发生重叠,约束中的其他列就允许重 - 复。(如果该列是日期或时间戳范围,这有时被称为时态键;但 - PostgreSQL 允许在任意基础类型上定义范围。) - 实际上,这种约束是通过 EXCLUDE 约束而不是 - UNIQUE 约束来强制的。例如, - UNIQUE (id, valid_at WITHOUT OVERLAPS) 的行为类似于 - EXCLUDE USING GIST (id WITH =, valid_at WITH &&)。 - WITHOUT OVERLAPS 列必须是范围类型或多范围类型,且不允许 - 为空范围或空多范围。该约束中不带 WITHOUT OVERLAPS 的列可以 - 是任何可在 GiST 索引中按相等性比较的类型。默认仅支持范围类型,但可通过安装 - 扩展来使用其他类型(这也是该特性的预期用法)。 - - 就唯一约束而言,空值不被视为相等,除非指定了 NULLS NOT DISTINCT。 @@ -787,20 +714,17 @@ WITH ( MODULUS numeric_literal, REM 每个唯一约束都应引用一组列,这组列应不同于该表上任何其他唯一约束或 主键约束所引用的列集合。(否则,冗余的唯一约束将被丢弃。) + 在为多级分区层次结构建立唯一约束时,目标分区表分区键中的所有列,以及 其所有后代分区表分区键中的所有列,都必须包含在约束定义中。 - - 添加唯一约束会自动在约束所用的列或列组上创建唯一 B-树索引;但如果该约束 - 包含 WITHOUT OVERLAPS 子句,则会使用 GiST 索引。所创建 - 的索引与该唯一约束同名。 - + 添加唯一约束会自动在约束所用的列或列组上创建唯一 B-树索引。 可选的 INCLUDE 子句会向该索引添加一个或多个仅作为 - payload 的列:对这些列不强制唯一性,而且该索引也不能据此 + 载荷 的列:对这些列不强制唯一性,而且该索引也不能据此 进行搜索。不过,它们可以通过仅索引扫描取回。注意,尽管约束不在包含列上 强制执行,它仍然依赖于这些列。因此,对这类列执行某些操作(例如 DROP COLUMN)可能导致约束和索引被级联删除。 @@ -809,13 +733,10 @@ WITH ( MODULUS numeric_literal, REM - PRIMARY KEY(列约束) - - PRIMARY KEY ( column_name [, ... ] [, column_name WITHOUT OVERLAPS ] ) - INCLUDE ( column_name [, ...]) (表约束) + PRIMARY KEY ( column_name [, ... ] ) + INCLUDE ( column_name [, ...]) (表约束) - PRIMARY KEY 约束指定表的一列或多列只能包含唯一 (不重复)且非空的值。无论作为列约束还是表约束,一个表都只能指定一个 @@ -841,13 +762,11 @@ WITH ( MODULUS numeric_literal, REM 添加 PRIMARY KEY 约束会自动在约束所用的列或列组上创建 - 唯一 B-树索引;如果指定了 WITHOUT OVERLAPS,则会创建 - GiST 索引。 - + 唯一 B-树索引。 可选的 INCLUDE 子句会向该索引添加一个或多个仅作为 - payload 的列:对这些列不强制唯一性,而且该索引也不能据此 + 载荷 的列:对这些列不强制唯一性,而且该索引也不能据此 进行搜索。不过,它们可以通过仅索引扫描取回。注意,尽管约束不在包含列上 强制执行,它仍然依赖于这些列。因此,对这类列执行某些操作(例如 DROP COLUMN)可能导致约束和索引被级联删除。 @@ -858,7 +777,6 @@ WITH ( MODULUS numeric_literal, REM EXCLUDE [ USING index_method ] ( exclude_element WITH operator [, ... ] ) index_parameters [ WHERE ( predicate ) ] - EXCLUDE 子句定义一个排他约束。它保证如果任意两行在 指定列或表达式上使用指定操作符进行比较,这些比较不会全部返回 @@ -871,7 +789,7 @@ WITH ( MODULUS numeric_literal, REM - 排他约束通过一个与约束同名的索引来实现,因此每个指定操作符都必须与 + 排他约束通过索引来实现,因此每个指定操作符都必须与 索引访问方法 index_method 的适当操作符类关联 (见 )。每个 exclude_element 都定义了索引的一 @@ -883,7 +801,7 @@ WITH ( MODULUS numeric_literal, REM 访问方法必须支持 amgettuple(见 );目前这意味着不能使用 GIN。 虽然允许,但在排他约束上使用 B-树或 hash 索引意义不大,因为它们做不到 - 比普通唯一约束更好的事情。因此,实践中访问方法几乎总会是 + 比普通唯一约束更好的事情。因此,实践中访问方法总是 GiSTSP-GiST @@ -892,67 +810,21 @@ WITH ( MODULUS numeric_literal, REM 子集上指定排他约束;在内部,这会创建一个部分索引。注意, predicate 周围的圆括号是必需的。 - - 在为多级分区层次结构建立排他约束时,目标分区表分区键中的所有列,以及其 - 所有后代分区表分区键中的所有列,都必须包含在约束定义中。此外,这些列必 - 须使用等值操作符进行比较。这些限制保证潜在冲突的行会落在同一分区中。约 - 束也可以引用不属于任何分区键的其他列,这些列可以使用任何合适的操作符来 - 比较。 - - REFERENCES reftable [ ( refcolumn ) ] [ MATCH matchtype ] [ ON DELETE referential_action ] [ ON UPDATE referential_action ](列约束) - FOREIGN KEY ( column_name [, ... ] [, PERIOD column_name ] ) - REFERENCES reftable [ ( refcolumn [, ... ] [, PERIOD refcolumn ] ) ] - [ MATCH matchtype ] - [ ON DELETE referential_action ] - [ ON UPDATE referential_action ] + FOREIGN KEY ( column_name [, ... ] ) + REFERENCES reftable [ ( refcolumn [, ... ] ) ] + [ MATCH matchtype ] + [ ON DELETE referential_action ] + [ ON UPDATE referential_action ] (表约束) - - - 这些子句指定外键约束,要求新表的一列或多列组成的一组只能包含与被引用 - 表某一行的被引用列中值相匹配的值。若省略 - refcolumn 列表,则使用 - reftable 的主键。否则, - refcolumn 列表必须引用某个不可延 - 迟的唯一约束或主键约束的列,或者引用某个非部分唯一索引的列。 - - - - 如果最后一列标记为 PERIOD,则会按特殊方式处理。非 - PERIOD 列按相等性比较(并且至少需要一列),而 - PERIOD 列则不会。取而代之的是,只有当被引用表中基于键的 - 非 PERIOD 部分相匹配的记录,其合并后的 - PERIOD 值能够完整覆盖引用记录的 - PERIOD 值时,约束才算满足。换言之,该引用在其整个持续区 - 间内都必须有对应的被引用对象。该列必须是范围类型或多范围类型。此外,被 - 引用表必须具有用 WITHOUT OVERLAPS 声明的主键或唯一约 - 束。最后,如果外键包含 PERIOD - column_name 说明,则对应的 - refcolumn(如果存在)也必须标记 - 为 PERIOD。如果省略 - refcolumn 子句,从而选择 - reftable 的主键约束,则该主键的最后一列必须标记为 - WITHOUT OVERLAPS。 - - - - 对于每一对引用列和被引用列,如果它们属于可排序数据类型,则两者的排序规 - 则要么都必须是确定性的,要么必须完全相同。这样可以确保两列对“相等”具 - 有一致的定义。 - - - 用户必须对被引用表拥有 REFERENCES 权限(对整张表,或对 - 特定的被引用列)。添加外键约束需要在被引用表上获取 - SHARE ROW EXCLUSIVE 锁。注意,不能在临时表和永久表之间 - 定义外键约束。 - + 这些子句指定外键约束,要求新表中由一个或多个列组成的列组只能包含与被引用表中某一行的被引用列中的值相匹配的值。如果省略refcolumn列表,则使用reftable的主键。否则,refcolumn列表必须引用不可延迟的唯一约束或主键约束的列,或者是非部分唯一索引的列。用户必须拥有被引用表的REFERENCES权限(可以针对整个表,也可以针对具体的被引用列)。添加外键约束需要在被引用表上获取SHARE ROW EXCLUSIVE锁。请注意,不能在临时表和永久表之间定义外键约束。 插入到引用列中的值会按照给定的匹配类型,与被引用表及其被引用列中的值进 @@ -966,39 +838,18 @@ WITH ( MODULUS numeric_literal, REM NOT NULL 约束,以防止出现这些情况。) - - 此外,当被引用列中的数据发生变化时,会对本表列中的数据执行某些操作。 - ON DELETE 子句指定当被引用表中的被引用行被删除时要执行 - 的操作。同样,ON UPDATE 子句指定当被引用表中的被引用列 - 被更新为新值时要执行的操作。如果更新了行,但被引用列实际上并未改变,则 - 不执行任何操作。引用动作作为数据更改命令的一部分执行,即使该约束是延迟 - 的也一样。每个子句可用的操作如下: - - + 此外,当被引用列中的数据发生变化时,会对本表列中的数据执行某些操作。ON DELETE子句指定删除被引用表中的被引用行时要执行的操作。同样,ON UPDATE子句指定将被引用表中的被引用列更新为新值时要执行的操作。如果行被更新,但被引用列实际上没有变化,则不执行任何操作。除NO ACTION检查以外的引用操作都不能延迟,即使该约束声明为可延迟也是如此。每个子句可以指定以下操作: NO ACTION - - 如果删除或更新会导致外键约束违规,则产生错误。如果约束被延迟,且到 - 约束检查时仍然存在任何引用行,就会产生此错误。 - 这是默认操作。 - + 产生错误,指出删除或更新会违反外键约束。如果该约束被延迟,则会在约束检查时仍存在引用行的情况下产生这个错误。这是默认操作。 RESTRICT - - 如果待删除或更新的行在引用表中有匹配行,则产生错误。即使操作完成后 - 的状态并不违反外键约束,也会阻止该操作。特别地,它会阻止将被引用行 - 更新为“值不同但比较相等”的情况。(但不会阻止把列更新为相同值的 - 无操作更新。) - - - - 对于时态外键,该选项不受支持。 - + 产生错误,指出删除或更新会违反外键约束。这与NO ACTION相同,但检查不能延迟。 @@ -1008,10 +859,6 @@ WITH ( MODULUS numeric_literal, REM 分别删除任何引用已删除行的行,或将引用列的值更新为被引用列的新值。 - - - 对于时态外键,该选项不受支持。 - @@ -1022,10 +869,6 @@ WITH ( MODULUS numeric_literal, REM 将全部引用列,或指定的引用列子集,设置为空值。只有 ON DELETE 动作才能指定列子集。 - - - 对于时态外键,该选项不受支持。 - @@ -1037,19 +880,12 @@ WITH ( MODULUS numeric_literal, REM ON DELETE 动作才能指定列子集。(如果默认值不是空 值,则被引用表中必须有一行与这些默认值匹配,否则该操作会失败。) - - - 对于时态外键,该选项不受支持。 - - - 如果被引用列经常发生变化,那么最好在引用列上添加一个索引,以便更高效地 - 执行与该外键约束相关的引用动作。 - + 如果被引用列经常变化,可以考虑在引用列上添加索引,使与外键约束关联的引用操作能够更高效地执行。 @@ -1088,38 +924,15 @@ WITH ( MODULUS numeric_literal, REM - - ENFORCED - NOT ENFORCED - - - 当约束为 ENFORCED 时,数据库系统会在适当时机检查该约束(按需要在每条语句后或事务结束时),这是默认行为。若约束为 NOT ENFORCED,数据库系统将不再检查该约束,改由应用代码保证约束成立。对于不影响结果正确性的优化决策,数据库系统仍可能假定数据满足该约束。 - - - - NOT ENFORCED 约束可作为文档用途,适用于运行时检查约束代价过高的场景。 - - - - 当前该能力仅支持外键约束与 CHECK 约束。 - - - - USING method - 该可选子句指定存储新表内容所用的表访问方法;该方法必须是类型为 TABLE 的访问方法。详见 。如果未 指定此选项,则会为新表选择默认表访问方法。详见 - - - 创建分区时,若其分区表已设置表访问方法,则该分区会使用分区表的访问方法。 - @@ -1221,11 +1034,10 @@ WITH ( MODULUS numeric_literal, REM - 存储参数 - storage parameters + 存储参数 @@ -1244,10 +1056,9 @@ WITH ( MODULUS numeric_literal, REM - fillfactor (integer) - fillfactor storage parameter + fillfactor 存储参数 @@ -1266,18 +1077,16 @@ WITH ( MODULUS numeric_literal, REM - toast_tuple_target (integer) - toast_tuple_target storage parameter + toast_tuple_target 存储参数 - toast_tuple_target 指定在尝试压缩和/或将长列值移入 TOAST 表之前所需的最小元组长度,同时也是一旦开始 TOAST 化后试图将长度 - 缩减到的目标长度。这会影响标记为 External(用于移动)、Main(用于压缩) + 缩减到其以下的目标长度。这会影响标记为 External(用于移动)、Main(用于压缩) 或 Extended(用于两者)的列,并且只适用于新元组。对现有行没有影响。默认 情况下,该参数被设置为至少允许每个块容纳 4 个元组,在默认块大小下即为 2040 字节。有效值介于 128 字节与(块大小减去页头)之间,默认上限为 @@ -1289,16 +1098,14 @@ WITH ( MODULUS numeric_literal, REM - parallel_workers (integer) - parallel_workers storage parameter + parallel_workers 存储参数 - - 该参数设置在对该表执行并行扫描时可用于辅助扫描的工作进程数量。若未设置, + 该参数设置在对该表执行并行扫描时用于辅助扫描的工作进程数量。若未设置, 系统会根据关系大小决定一个值。规划器或使用并行扫描的实用命令实际选择的 工作进程数量可能更少,例如可能受 设置所限。 @@ -1307,10 +1114,9 @@ WITH ( MODULUS numeric_literal, REM - autovacuum_enabled, toast.autovacuum_enabled (boolean) - autovacuum_enabled storage parameter + autovacuum_enabled 存储参数 @@ -1330,10 +1136,9 @@ WITH ( MODULUS numeric_literal, REM - vacuum_index_cleanup, toast.vacuum_index_cleanup (enum) - vacuum_index_cleanup storage parameter + vacuum_index_cleanup 存储参数 @@ -1353,29 +1158,28 @@ WITH ( MODULUS numeric_literal, REM - vacuum_truncate, toast.vacuum_truncate (boolean) - vacuum_truncate - storage parameter + vacuum_truncate 存储参数 - - 参数的每表取值。若 - VACUUM 指定了 - TRUNCATE 参数,将覆盖此选项的值。 + 允许或禁止清理尝试截去该表末尾的空页。默认值为 + true。若为 true, + VACUUM 和自动清理都会执行截断,并将被截断页面占用的磁盘空间返还给操作系统。注意,截断操作需要对表持有 + ACCESS EXCLUSIVE 锁。若在 + VACUUM 中指定了 + TRUNCATE 参数,则会覆盖此选项的值。 - autovacuum_vacuum_threshold, toast.autovacuum_vacuum_threshold (integer) autovacuum_vacuum_threshold - storage parameter + 存储参数 @@ -1384,28 +1188,13 @@ WITH ( MODULUS numeric_literal, REM 参数的每表取值。 - - - - autovacuum_vacuum_max_threshold, toast.autovacuum_vacuum_max_threshold (integer) - - autovacuum_vacuum_max_threshold - storage parameter - - - - - 参数的每表取值。 - - - + - autovacuum_vacuum_scale_factor, toast.autovacuum_vacuum_scale_factor (floating point) autovacuum_vacuum_scale_factor - storage parameter + 存储参数 @@ -1417,11 +1206,10 @@ WITH ( MODULUS numeric_literal, REM - autovacuum_vacuum_insert_threshold, toast.autovacuum_vacuum_insert_threshold (integer) autovacuum_vacuum_insert_threshold - storage parameter + 存储参数 @@ -1434,11 +1222,10 @@ WITH ( MODULUS numeric_literal, REM - autovacuum_vacuum_insert_scale_factor, toast.autovacuum_vacuum_insert_scale_factor (floating point) autovacuum_vacuum_insert_scale_factor - storage parameter + 存储参数 @@ -1450,11 +1237,10 @@ WITH ( MODULUS numeric_literal, REM - autovacuum_analyze_threshold (integer) autovacuum_analyze_threshold - storage parameter + 存储参数 @@ -1466,11 +1252,10 @@ WITH ( MODULUS numeric_literal, REM - autovacuum_analyze_scale_factor (floating point) autovacuum_analyze_scale_factor - storage parameter + 存储参数 @@ -1482,11 +1267,10 @@ WITH ( MODULUS numeric_literal, REM - autovacuum_vacuum_cost_delay, toast.autovacuum_vacuum_cost_delay (floating point) autovacuum_vacuum_cost_delay - storage parameter + 存储参数 @@ -1498,11 +1282,10 @@ WITH ( MODULUS numeric_literal, REM - autovacuum_vacuum_cost_limit, toast.autovacuum_vacuum_cost_limit (integer) autovacuum_vacuum_cost_limit - storage parameter + 存储参数 @@ -1514,10 +1297,9 @@ WITH ( MODULUS numeric_literal, REM - autovacuum_freeze_min_age, toast.autovacuum_freeze_min_age (integer) - autovacuum_freeze_min_age storage parameter + autovacuum_freeze_min_age 存储参数 @@ -1531,11 +1313,10 @@ WITH ( MODULUS numeric_literal, REM - autovacuum_freeze_max_age, toast.autovacuum_freeze_max_age (integer) autovacuum_freeze_max_age - storage parameter + 存储参数 @@ -1549,10 +1330,9 @@ WITH ( MODULUS numeric_literal, REM - autovacuum_freeze_table_age, toast.autovacuum_freeze_table_age (integer) - autovacuum_freeze_table_age storage parameter + autovacuum_freeze_table_age 存储参数 @@ -1564,10 +1344,9 @@ WITH ( MODULUS numeric_literal, REM - autovacuum_multixact_freeze_min_age, toast.autovacuum_multixact_freeze_min_age (integer) - autovacuum_multixact_freeze_min_age storage parameter + autovacuum_multixact_freeze_min_age 存储参数 @@ -1582,11 +1361,10 @@ WITH ( MODULUS numeric_literal, REM - autovacuum_multixact_freeze_max_age, toast.autovacuum_multixact_freeze_max_age (integer) autovacuum_multixact_freeze_max_age - storage parameter + 存储参数 @@ -1601,10 +1379,9 @@ WITH ( MODULUS numeric_literal, REM - autovacuum_multixact_freeze_table_age, toast.autovacuum_multixact_freeze_table_age (integer) - autovacuum_multixact_freeze_table_age storage parameter + autovacuum_multixact_freeze_table_age 存储参数 @@ -1616,11 +1393,10 @@ WITH ( MODULUS numeric_literal, REM - log_autovacuum_min_duration, toast.log_autovacuum_min_duration (integer) log_autovacuum_min_duration - storage parameter + 存储参数 @@ -1629,27 +1405,12 @@ WITH ( MODULUS numeric_literal, REM 参数的每表取值。 - - - - vacuum_max_eager_freeze_failure_rate, toast.vacuum_max_eager_freeze_failure_rate (floating point) - - vacuum_max_eager_freeze_failure_rate - storage parameter - - - - - 参数的每表取值。 - - - user_catalog_table (boolean) - user_catalog_table storage parameter + user_catalog_table 存储参数 @@ -1667,11 +1428,9 @@ WITH ( MODULUS numeric_literal, REM - 注解 - - PostgreSQL为每一个唯一约束和主键约束创建一个索引来强制唯一性。因此,没有必要显式地为主键列创建一个索引(详见)。 + PostgreSQL为每一个唯一约束和主键约束自动创建一个索引来强制唯一性。因此,没有必要显式地为主键列创建一个索引(详见)。 @@ -1684,6 +1443,7 @@ WITH ( MODULUS numeric_literal, REM + 示例 @@ -1993,7 +1753,6 @@ CREATE TABLE cities_partdef - 兼容性 @@ -2096,19 +1855,17 @@ CREATE TABLE cities_partdef - <literal>NULL</literal> <quote>约束</quote> NULL 约束(实际上并不是约束)是 - PostgreSQL 对 SQL 标准的扩展;它也被其他一些数 - 据库系统采纳,以便兼容(以及与对称的 NOT NULL 约束保持一 - 致)。由于它本来就是任意列的默认值,所以它的存在只是噪声。 + PostgreSQL 对 SQL 标准的扩展;提供它是为了 + 与其他一些数据库系统兼容(以及与 NOT NULL 约束保持 + 对称)。由于它本来就是任意列的默认情况,所以它的存在只是噪声。 - 约束命名 @@ -2120,6 +1877,7 @@ CREATE TABLE cities_partdef 名,而索引名称在同一模式内的所有关系之间必须唯一。 + 目前,PostgreSQL根本不会为NOT NULL约束记录名称,因此它们不受唯一性限制。这种情况可能会在未来版本中改变。 @@ -2132,38 +1890,33 @@ CREATE TABLE cities_partdef - - 零列表 + 零列的表 PostgreSQL 允许创建没有列的表(例如 CREATE TABLE foo();)。这是对 SQL 标准的扩展,标准不允许 - 零列表。零列表本身并不十分有用,但若禁止它们,就会让 + 零列的表。零列的表本身并不十分有用,但若禁止它们,就会让 ALTER TABLE DROP COLUMN 出现奇怪的特殊情况,因此忽略这 一规范限制看起来更整洁。 - 多个标识列 PostgreSQL 允许一个表拥有多个标识列。 该标准指定一个表最多只能有一个标识列。 - 这主要是为了给模式更改或迁移提供更大的灵活性。 + 放宽这一限制主要是为了给模式更改或迁移提供更大的灵活性。 请注意,INSERT 命令仅支持一个适用于整个语句的覆盖子 句,因此对行为不同的多个标识列支持并不好。 - 生成列 - - STOREDVIRTUAL 选项都不是标准的一部分,但其他 SQL 实现也会使用。SQL 标准并不规定生成列的存储方式。 - + STORED选项不是标准的一部分,但其他 SQL 实现也使用它。SQL 标准没有规定生成列的存储方式。 @@ -2200,12 +1953,10 @@ CREATE TABLE cities_partdef - 类型化表 - 类型化表实现了 SQL 标准的一个子集。按照标准,类型化表除了具有与底层组合 - 类型相对应的列之外,还应有一个额外的自引用列。 + 类型化表实现了 SQL 标准的一个子集。按照标准,类型化表除了具有与底层复合类型相对应的列之外,还应有一个额外的自引用列PostgreSQL 不显式支持自引用列。 @@ -2232,6 +1983,7 @@ CREATE TABLE cities_partdef + 另见 diff --git a/zh/15/ref/create_table_as.sgml b/zh/15/ref/create_table_as.sgml index 7d80a1f0..03a60483 100644 --- a/zh/15/ref/create_table_as.sgml +++ b/zh/15/ref/create_table_as.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation CREATE TABLE AS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/create_tablespace.sgml b/zh/15/ref/create_tablespace.sgml index 32b0dbb1..88106ccd 100644 --- a/zh/15/ref/create_tablespace.sgml +++ b/zh/15/ref/create_tablespace.sgml @@ -13,7 +13,7 @@ PostgreSQL documentation CREATE TABLESPACE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/create_transform.sgml b/zh/15/ref/create_transform.sgml index 247e6a0f..ecea2c1e 100644 --- a/zh/15/ref/create_transform.sgml +++ b/zh/15/ref/create_transform.sgml @@ -13,7 +13,7 @@ PostgreSQL documentation CREATE TRANSFORM 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/create_trigger.sgml b/zh/15/ref/create_trigger.sgml index 236c79c4..4146e2ba 100644 --- a/zh/15/ref/create_trigger.sgml +++ b/zh/15/ref/create_trigger.sgml @@ -11,13 +11,13 @@ PostgreSQL documentation 过渡表 - ephemeral named relation + 临时命名关系 CREATE TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -70,7 +70,7 @@ CREATE [ OR REPLACE ] [ CONSTRAINT ] TRIGGER name UPDATEDELETE之前); 也可以在该操作完成之后引发(即在检查约束以及完成 INSERTUPDATE或 - DELETE之后);或者改为执行该操作 + DELETE之后);或者取代该操作执行 (用于视图上的插入、更新或删除)。如果触发器在事件之前引发,或者改为取代该事件执行, 则它可以跳过对当前行的操作,或者修改待插入的行 (仅适用于INSERTUPDATE操作)。 @@ -126,7 +126,7 @@ CREATE [ OR REPLACE ] [ CONSTRAINT ] TRIGGER name TRUNCATE - 表和外部表 + @@ -139,7 +139,7 @@ CREATE [ OR REPLACE ] [ CONSTRAINT ] TRIGGER name TRUNCATE - 表和外部表 + @@ -178,7 +178,7 @@ CREATE [ OR REPLACE ] [ CONSTRAINT ] TRIGGER name 调整其引发时机。约束触发器必须是普通表(不是外部表)上的 AFTER ROW 触发器。它们既可以在导致触发事件的语句结束时引发, 也可以在包含它的事务结束时引发;后一种情况称为延迟。 - 也可以使用SET CONSTRAINTS强制挂起的延迟触发立即引发。 + 也可以使用SET CONSTRAINTS强制尚待执行的延迟触发器立即引发。 约束触发器应当在其所实现的约束遭到违反时抛出异常。 @@ -394,7 +394,7 @@ UPDATE OF column_name1 [, column_name2CREATE TRIGGER的语法中,关键字 FUNCTIONPROCEDURE 是等价的, 但无论如何,被引用的对象都必须是函数而不是过程。 - 这里使用 PROCEDURE 关键字只是出于历史原因,并且已被废弃。 + 这里使用 PROCEDURE 关键字只是出于历史原因,并且已被弃用。 diff --git a/zh/15/ref/create_tsconfig.sgml b/zh/15/ref/create_tsconfig.sgml index 52c43127..52970b36 100644 --- a/zh/15/ref/create_tsconfig.sgml +++ b/zh/15/ref/create_tsconfig.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TEXT SEARCH CONFIGURATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/create_tsdictionary.sgml b/zh/15/ref/create_tsdictionary.sgml index 7a06b430..c45a7240 100644 --- a/zh/15/ref/create_tsdictionary.sgml +++ b/zh/15/ref/create_tsdictionary.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TEXT SEARCH DICTIONARY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/create_tsparser.sgml b/zh/15/ref/create_tsparser.sgml index d0c11ba5..358152ce 100644 --- a/zh/15/ref/create_tsparser.sgml +++ b/zh/15/ref/create_tsparser.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TEXT SEARCH PARSER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/create_tstemplate.sgml b/zh/15/ref/create_tstemplate.sgml index 947b18b9..702233e4 100644 --- a/zh/15/ref/create_tstemplate.sgml +++ b/zh/15/ref/create_tstemplate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TEXT SEARCH TEMPLATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/create_type.sgml b/zh/15/ref/create_type.sgml index 45a4d93a..2e1ba18d 100644 --- a/zh/15/ref/create_type.sgml +++ b/zh/15/ref/create_type.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation CREATE TYPE 7 - SQL - Language Statements + SQL - 语言语句 @@ -96,7 +96,7 @@ CREATE TYPE name 复合类型 - 第一种形式的CREATE TYPE创建复合类型。组合 + 第一种形式的CREATE TYPE创建复合类型。复合 类型由属性名和数据类型列表指定。如果某个属性的数据类型支持排序规 则,还可以指定该属性的排序规则。复合类型本质上与表的行类型相同, 但如果目的只是定义一种类型,使用CREATE TYPE @@ -322,7 +322,7 @@ CREATE TYPE name 数才知道,但仍有若干内部表示属性必须向 PostgreSQL声明。其中最重要的是 internallength。 - 基础数据类型可以是定长的,此时internallength为正整数;也可 以是变长的,此时将internallength设为 @@ -427,7 +427,7 @@ CREATE TYPE name collatable为真,则 该类型的列定义和表达式可以通过COLLATE子句携 带排序规则信息。是否实际使用这些排序规则信息取决于操作该类型的函 - 数实现;仅仅把类型标记为 collatable 并不会自动实现这一点。 + 数实现;仅仅把类型标记为支持排序规则并不会自动实现这一点。 @@ -829,15 +829,6 @@ CREATE TYPE name 以这种方式创建 shell 类型。 - - 在PostgreSQL 16 及更高版本中,基础类 - 型的输入函数最好使用新的 - errsave()/ereturn()机 - 制返回错误,而不是像早期版本那样抛出 - ereport()异常。更多信息见 - src/backend/utils/fmgr/README。 - - @@ -876,7 +867,7 @@ CREATE TYPE float8_range AS RANGE (subtype = float8, subtype_diff = float8mi); - 这个示例创建基础数据类型box,然后在表定义中使用它: + 这个示例创建基础类型box,然后在表定义中使用它: CREATE TYPE box; diff --git a/zh/15/ref/create_user.sgml b/zh/15/ref/create_user.sgml index 218c51eb..9548a147 100644 --- a/zh/15/ref/create_user.sgml +++ b/zh/15/ref/create_user.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE USER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/create_user_mapping.sgml b/zh/15/ref/create_user_mapping.sgml index fe556318..1abe6abd 100644 --- a/zh/15/ref/create_user_mapping.sgml +++ b/zh/15/ref/create_user_mapping.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE USER MAPPING 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/create_view.sgml b/zh/15/ref/create_view.sgml index 80c6d1ab..292b1a4b 100644 --- a/zh/15/ref/create_view.sgml +++ b/zh/15/ref/create_view.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation CREATE VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/createdb.sgml b/zh/15/ref/createdb.sgml index 554d7377..15331c50 100644 --- a/zh/15/ref/createdb.sgml +++ b/zh/15/ref/createdb.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation createdb 1 - Application + 应用程序 @@ -114,12 +114,7 @@ PostgreSQL documentation - - - 指定该数据库要使用的区域设置。这等同于为、 - 指定相同的值。 - 某些区域设置仅对 ICU 有效,必须通过设置。 - + 指定此数据库要使用的区域设置。这相当于同时指定 @@ -143,15 +138,7 @@ PostgreSQL documentation - - - - - 当使用 builtin 提供程序时,指定区域设置名称。区域设置支持的说明见 - 。 - - - + @@ -163,17 +150,10 @@ PostgreSQL documentation - - - - - 指定附加的排序规则,用以定制该数据库默认排序规则的行为。该选项仅支持 ICU。 - - - + - + @@ -194,6 +174,7 @@ PostgreSQL documentation + diff --git a/zh/15/ref/createuser.sgml b/zh/15/ref/createuser.sgml index f698459d..9c8b0f3a 100644 --- a/zh/15/ref/createuser.sgml +++ b/zh/15/ref/createuser.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation createuser 1 - Application + 应用程序 @@ -70,16 +70,7 @@ PostgreSQL documentation - - - - - - 指定一个现有角色,使其自动作为带有 ADMIN OPTION 的成员加入新角色,从而有权将新角色的成员资格授予其他角色。 - 可以通过写多个开关来指定多个现有角色。 - - - + @@ -138,14 +129,10 @@ PostgreSQL documentation - - (已废弃) + - - 指定新角色应自动成为指定现有角色的成员。 - 可以通过写多个开关来指定多个现有角色。 - + 指定此角色应立即作为新成员加入的现有角色。可以使用多个开关,指定此角色要加入的多个角色。 @@ -210,16 +197,7 @@ PostgreSQL documentation - - - - - - 指定一个现有角色,使其自动作为成员加入新角色。 - 可以通过写多个开关来指定多个现有角色。 - - - + @@ -239,7 +217,7 @@ PostgreSQL documentation - 允许新用户创建、更改、删除其他角色,对其添加注释,以及更改其安全标签;也就是说, + 允许新用户创建、更改、删除其他角色,对其添加注释,更改其安全标签,以及授予或撤销其他角色的成员资格;也就是说, 该用户将具有CREATEROLE权限。 关于该权限赋予哪些能力的更多细节,见 @@ -279,16 +257,7 @@ PostgreSQL documentation - - - - - - 设置一个日期和时间,在此之后该角色的密码将不再有效。 - 默认不设置密码过期日期。 - - - + @@ -301,23 +270,9 @@ PostgreSQL documentation - - - - - 新用户将绕过每一条行级安全(RLS)策略。 - - - - - - - - 新用户将不会绕过行级安全(RLS)策略。这是默认设置。 - - - + + @@ -336,7 +291,7 @@ PostgreSQL documentation 新用户将不具有REPLICATION权限,关于该权限的更完整说明见。这是默认设置。 + linkend="sql-createrole"/>。 @@ -502,7 +457,7 @@ PostgreSQL documentation $ createuser -P -s -e joe Enter password for new role: xyzzy Enter it again: xyzzy -CREATE ROLE joe PASSWORD 'SCRAM-SHA-256$4096:44560wPMLfjqiAzyPDZ/eQ==$4CA054rZlSFEq8Z3FEhToBTa2X6KnWFxFkPwIbKoDe0=:L/nbSZRCjp6RhOhKK56GoR1zibCCSePKshCJ9lnl3yw=' SUPERUSER CREATEDB CREATEROLE INHERIT LOGIN NOREPLICATION NOBYPASSRLS; +CREATE ROLE joe PASSWORD 'SCRAM-SHA-256$4096:44560wPMLfjqiAzyPDZ/eQ==$4CA054rZlSFEq8Z3FEhToBTa2X6KnWFxFkPwIbKoDe0=:L/nbSZRCjp6RhOhKK56GoR1zibCCSePKshCJ9lnl3yw=' SUPERUSER CREATEDB CREATEROLE INHERIT LOGIN; 在上面的示例中,输入新密码时实际上不会回显它,但为清楚起见,这里展示了输入的内容。 可以看到,该密码在发送给客户端之前就已经被加密了。 diff --git a/zh/15/ref/deallocate.sgml b/zh/15/ref/deallocate.sgml index 27b9da86..6dea341e 100644 --- a/zh/15/ref/deallocate.sgml +++ b/zh/15/ref/deallocate.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation DEALLOCATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/declare.sgml b/zh/15/ref/declare.sgml index ed389e4d..9276a0e3 100644 --- a/zh/15/ref/declare.sgml +++ b/zh/15/ref/declare.sgml @@ -22,7 +22,7 @@ PostgreSQL documentation DECLARE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/delete.sgml b/zh/15/ref/delete.sgml index 4a79783c..653e86a2 100644 --- a/zh/15/ref/delete.sgml +++ b/zh/15/ref/delete.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DELETE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/discard.sgml b/zh/15/ref/discard.sgml index 29d4ea8d..f6572252 100644 --- a/zh/15/ref/discard.sgml +++ b/zh/15/ref/discard.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DISCARD 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/do.sgml b/zh/15/ref/do.sgml index 2ea6566a..cdbf189e 100644 --- a/zh/15/ref/do.sgml +++ b/zh/15/ref/do.sgml @@ -15,7 +15,7 @@ PostgreSQL documentation DO 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/drop_access_method.sgml b/zh/15/ref/drop_access_method.sgml index 407ec4cd..646100e1 100644 --- a/zh/15/ref/drop_access_method.sgml +++ b/zh/15/ref/drop_access_method.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP ACCESS METHOD 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/drop_aggregate.sgml b/zh/15/ref/drop_aggregate.sgml index 1c8a1122..9fd7ea4b 100644 --- a/zh/15/ref/drop_aggregate.sgml +++ b/zh/15/ref/drop_aggregate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP AGGREGATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/drop_cast.sgml b/zh/15/ref/drop_cast.sgml index 73860e3c..5e330ae0 100644 --- a/zh/15/ref/drop_cast.sgml +++ b/zh/15/ref/drop_cast.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP CAST 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/drop_collation.sgml b/zh/15/ref/drop_collation.sgml index b90849fc..b10b3206 100644 --- a/zh/15/ref/drop_collation.sgml +++ b/zh/15/ref/drop_collation.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP COLLATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/drop_conversion.sgml b/zh/15/ref/drop_conversion.sgml index b63d1291..35009708 100644 --- a/zh/15/ref/drop_conversion.sgml +++ b/zh/15/ref/drop_conversion.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP CONVERSION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/drop_database.sgml b/zh/15/ref/drop_database.sgml index 9bbd949f..10817b69 100644 --- a/zh/15/ref/drop_database.sgml +++ b/zh/15/ref/drop_database.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP DATABASE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/drop_domain.sgml b/zh/15/ref/drop_domain.sgml index d43f95c6..b292b189 100644 --- a/zh/15/ref/drop_domain.sgml +++ b/zh/15/ref/drop_domain.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP DOMAIN 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/drop_event_trigger.sgml b/zh/15/ref/drop_event_trigger.sgml index 80020f78..f4f0053f 100644 --- a/zh/15/ref/drop_event_trigger.sgml +++ b/zh/15/ref/drop_event_trigger.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP EVENT TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -30,7 +30,7 @@ DROP EVENT TRIGGER [ IF EXISTS ] name DROP EVENT TRIGGER移除一个现有的事件触发器。 - 要执行此命令,当前用户必须是该事件触发器的拥有者。 + 要执行此命令,当前用户必须是该事件触发器的所有者。 @@ -99,7 +99,7 @@ DROP EVENT TRIGGER snitch; - 另见 + 参见 diff --git a/zh/15/ref/drop_extension.sgml b/zh/15/ref/drop_extension.sgml index 5eb04c04..ccccb0b1 100644 --- a/zh/15/ref/drop_extension.sgml +++ b/zh/15/ref/drop_extension.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP EXTENSION 7 - SQL - Language Statements + SQL - 语言语句 @@ -59,8 +59,8 @@ DROP EXTENSION [ IF EXISTS ] name [ name - 已安装扩展的名称。 - + 一个已安装扩展的名称。 + @@ -95,7 +95,7 @@ DROP EXTENSION [ IF EXISTS ] name [ DROP EXTENSION hstore; - 如果数据库中正在使用hstore的任何对象, + 如果数据库中使用了hstore的任何对象, 例如某些表具有hstore类型的列,则该命令会失败。 加上CASCADE选项可以强制一并移除这些依赖对象。 diff --git a/zh/15/ref/drop_foreign_data_wrapper.sgml b/zh/15/ref/drop_foreign_data_wrapper.sgml index 9902c875..6f781f31 100644 --- a/zh/15/ref/drop_foreign_data_wrapper.sgml +++ b/zh/15/ref/drop_foreign_data_wrapper.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP FOREIGN DATA WRAPPER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/drop_foreign_table.sgml b/zh/15/ref/drop_foreign_table.sgml index 0b4d0bbd..c420e4ba 100644 --- a/zh/15/ref/drop_foreign_table.sgml +++ b/zh/15/ref/drop_foreign_table.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP FOREIGN TABLE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/drop_function.sgml b/zh/15/ref/drop_function.sgml index 32e1de58..f80cc1d8 100644 --- a/zh/15/ref/drop_function.sgml +++ b/zh/15/ref/drop_function.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP FUNCTION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/drop_group.sgml b/zh/15/ref/drop_group.sgml index f43389ca..4ee8fc55 100644 --- a/zh/15/ref/drop_group.sgml +++ b/zh/15/ref/drop_group.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP GROUP 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/drop_index.sgml b/zh/15/ref/drop_index.sgml index b65b810b..d7f892d9 100644 --- a/zh/15/ref/drop_index.sgml +++ b/zh/15/ref/drop_index.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP INDEX 7 - SQL - Language Statements + SQL - 语言语句 @@ -57,7 +57,7 @@ DROP INDEX [ CONCURRENTLY ] [ IF EXISTS ] name 对于临时表,DROP INDEX始终是非并发的, - 因为没有其他会话可以访问它们,而且非并发删除索引的成本更低。 + 因为没有其他会话可以访问它们,而且非并发删除索引的代价更低。 @@ -66,7 +66,7 @@ DROP INDEX [ CONCURRENTLY ] [ IF EXISTS ] nameIF EXISTS - 如果该索引不存在,则不要抛出错误。这种情况下会发出一个提示。 + 如果该索引不存在,则不要抛出错误。这种情况下会发出一条提示。 diff --git a/zh/15/ref/drop_language.sgml b/zh/15/ref/drop_language.sgml index 9696f612..8fb4de3f 100644 --- a/zh/15/ref/drop_language.sgml +++ b/zh/15/ref/drop_language.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP LANGUAGE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/drop_materialized_view.sgml b/zh/15/ref/drop_materialized_view.sgml index f3682552..71ad4326 100644 --- a/zh/15/ref/drop_materialized_view.sgml +++ b/zh/15/ref/drop_materialized_view.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP MATERIALIZED VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/drop_opclass.sgml b/zh/15/ref/drop_opclass.sgml index c3dd2e74..9d67dc64 100644 --- a/zh/15/ref/drop_opclass.sgml +++ b/zh/15/ref/drop_opclass.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP OPERATOR CLASS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/drop_operator.sgml b/zh/15/ref/drop_operator.sgml index 3cfb069c..19e93d4e 100644 --- a/zh/15/ref/drop_operator.sgml +++ b/zh/15/ref/drop_operator.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP OPERATOR 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/drop_opfamily.sgml b/zh/15/ref/drop_opfamily.sgml index 8e7097f9..06223045 100644 --- a/zh/15/ref/drop_opfamily.sgml +++ b/zh/15/ref/drop_opfamily.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP OPERATOR FAMILY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/drop_owned.sgml b/zh/15/ref/drop_owned.sgml index 2bc659bf..3ec24e66 100644 --- a/zh/15/ref/drop_owned.sgml +++ b/zh/15/ref/drop_owned.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP OWNED 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/drop_policy.sgml b/zh/15/ref/drop_policy.sgml index ee64ffa0..a939a688 100644 --- a/zh/15/ref/drop_policy.sgml +++ b/zh/15/ref/drop_policy.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP POLICY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/drop_procedure.sgml b/zh/15/ref/drop_procedure.sgml index 178e6684..19708931 100644 --- a/zh/15/ref/drop_procedure.sgml +++ b/zh/15/ref/drop_procedure.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP PROCEDURE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/drop_publication.sgml b/zh/15/ref/drop_publication.sgml index 6bc4bf59..048c1756 100644 --- a/zh/15/ref/drop_publication.sgml +++ b/zh/15/ref/drop_publication.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP PUBLICATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/drop_role.sgml b/zh/15/ref/drop_role.sgml index 6f3dd022..9fbfa99e 100644 --- a/zh/15/ref/drop_role.sgml +++ b/zh/15/ref/drop_role.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP ROLE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/drop_routine.sgml b/zh/15/ref/drop_routine.sgml index 4f2be77f..db15d5d2 100644 --- a/zh/15/ref/drop_routine.sgml +++ b/zh/15/ref/drop_routine.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP ROUTINE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/drop_rule.sgml b/zh/15/ref/drop_rule.sgml index ddb561f4..2968d946 100644 --- a/zh/15/ref/drop_rule.sgml +++ b/zh/15/ref/drop_rule.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP RULE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/drop_schema.sgml b/zh/15/ref/drop_schema.sgml index 9f622df3..94843c9a 100644 --- a/zh/15/ref/drop_schema.sgml +++ b/zh/15/ref/drop_schema.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP SCHEMA 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/drop_sequence.sgml b/zh/15/ref/drop_sequence.sgml index 4ba78640..586d3038 100644 --- a/zh/15/ref/drop_sequence.sgml +++ b/zh/15/ref/drop_sequence.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP SEQUENCE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/drop_server.sgml b/zh/15/ref/drop_server.sgml index 0864a4c2..8bdacdc8 100644 --- a/zh/15/ref/drop_server.sgml +++ b/zh/15/ref/drop_server.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP SERVER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/drop_statistics.sgml b/zh/15/ref/drop_statistics.sgml index 3120dc06..4773bfa8 100644 --- a/zh/15/ref/drop_statistics.sgml +++ b/zh/15/ref/drop_statistics.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP STATISTICS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/drop_subscription.sgml b/zh/15/ref/drop_subscription.sgml index 67421595..01a6c5f0 100644 --- a/zh/15/ref/drop_subscription.sgml +++ b/zh/15/ref/drop_subscription.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP SUBSCRIPTION 7 - SQL - Language Statements + SQL - 语言语句 @@ -32,14 +32,12 @@ DROP SUBSCRIPTION [ IF EXISTS ] nameDROP SUBSCRIPTION从数据库集簇中移除一个订阅。 - - 要执行此命令,用户必须是该订阅的拥有者。 - + 只有超级用户才能删除订阅。 如果该订阅与复制槽相关联,则不能在事务块内执行 DROP SUBSCRIPTION。 - (可以使用ALTER SUBSCRIPTION + (可以使用ALTER SUBSCRIPTION 来取消设置该槽。) @@ -90,11 +88,9 @@ DROP SUBSCRIPTION [ IF EXISTS ] nameDROP SUBSCRIPTION命令都会失败。 要在这种情况下继续,首先执行 - - ALTER SUBSCRIPTION ... DISABLE + ALTER SUBSCRIPTION ... DISABLE 禁用订阅,然后执行 - - ALTER SUBSCRIPTION ... SET (slot_name = NONE) + ALTER SUBSCRIPTION ... SET (slot_name = NONE) 将其与复制槽解除关联。此后,DROP SUBSCRIPTION将不会尝试删除订阅自身的复制槽。 如果还有某些表同步尚未完成,它仍可能连接到发布者,以删除由系统内部创建的表同步槽; 如果发布者不可达,则必须手工删除这些槽(以及仍然存在的主复制槽)。否则,这些槽会继续保留 WAL, diff --git a/zh/15/ref/drop_table.sgml b/zh/15/ref/drop_table.sgml index a2634c54..bdfbabf4 100644 --- a/zh/15/ref/drop_table.sgml +++ b/zh/15/ref/drop_table.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TABLE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/drop_tablespace.sgml b/zh/15/ref/drop_tablespace.sgml index c8b09e59..a31fd70f 100644 --- a/zh/15/ref/drop_tablespace.sgml +++ b/zh/15/ref/drop_tablespace.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TABLESPACE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/drop_transform.sgml b/zh/15/ref/drop_transform.sgml index be84b60c..09a3c9c7 100644 --- a/zh/15/ref/drop_transform.sgml +++ b/zh/15/ref/drop_transform.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TRANSFORM 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/drop_trigger.sgml b/zh/15/ref/drop_trigger.sgml index 1f85cf41..160a5ebd 100644 --- a/zh/15/ref/drop_trigger.sgml +++ b/zh/15/ref/drop_trigger.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -30,7 +30,7 @@ DROP TRIGGER [ IF EXISTS ] name ON DROP TRIGGER移除一个现有触发器的定义。 - 要执行此命令,当前用户必须是定义该触发器的表的拥有者。 + 要执行此命令,当前用户必须是定义该触发器的表的所有者。 @@ -109,7 +109,7 @@ DROP TRIGGER if_dist_exists ON films; - 另见 + 参见 diff --git a/zh/15/ref/drop_tsconfig.sgml b/zh/15/ref/drop_tsconfig.sgml index 2a7cdc52..ea139802 100644 --- a/zh/15/ref/drop_tsconfig.sgml +++ b/zh/15/ref/drop_tsconfig.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TEXT SEARCH CONFIGURATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/drop_tsdictionary.sgml b/zh/15/ref/drop_tsdictionary.sgml index 1eb24189..316c5d00 100644 --- a/zh/15/ref/drop_tsdictionary.sgml +++ b/zh/15/ref/drop_tsdictionary.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TEXT SEARCH DICTIONARY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/drop_tsparser.sgml b/zh/15/ref/drop_tsparser.sgml index 0cfa7acd..a65f47be 100644 --- a/zh/15/ref/drop_tsparser.sgml +++ b/zh/15/ref/drop_tsparser.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TEXT SEARCH PARSER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/drop_tstemplate.sgml b/zh/15/ref/drop_tstemplate.sgml index 282231c5..fa1faab0 100644 --- a/zh/15/ref/drop_tstemplate.sgml +++ b/zh/15/ref/drop_tstemplate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TEXT SEARCH TEMPLATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/drop_type.sgml b/zh/15/ref/drop_type.sgml index dab5bfa0..2f139da5 100644 --- a/zh/15/ref/drop_type.sgml +++ b/zh/15/ref/drop_type.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TYPE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/drop_user.sgml b/zh/15/ref/drop_user.sgml index 00d1d5f4..2e61d6ef 100644 --- a/zh/15/ref/drop_user.sgml +++ b/zh/15/ref/drop_user.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP USER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/drop_user_mapping.sgml b/zh/15/ref/drop_user_mapping.sgml index 2a79a65b..d23b0a16 100644 --- a/zh/15/ref/drop_user_mapping.sgml +++ b/zh/15/ref/drop_user_mapping.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP USER MAPPING 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/drop_view.sgml b/zh/15/ref/drop_view.sgml index 4feb47e5..8f995245 100644 --- a/zh/15/ref/drop_view.sgml +++ b/zh/15/ref/drop_view.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/dropdb.sgml b/zh/15/ref/dropdb.sgml index 70ad776f..10f79ed2 100644 --- a/zh/15/ref/dropdb.sgml +++ b/zh/15/ref/dropdb.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation dropdb 1 - Application + 应用程序 diff --git a/zh/15/ref/dropuser.sgml b/zh/15/ref/dropuser.sgml index 55aa53fa..3cdd48c0 100644 --- a/zh/15/ref/dropuser.sgml +++ b/zh/15/ref/dropuser.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation dropuser 1 - Application + 应用程序 diff --git a/zh/15/ref/ecpg-ref.sgml b/zh/15/ref/ecpg-ref.sgml index 002b8ef1..506be589 100644 --- a/zh/15/ref/ecpg-ref.sgml +++ b/zh/15/ref/ecpg-ref.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ecpg 1 - Application + 应用程序 diff --git a/zh/15/ref/end.sgml b/zh/15/ref/end.sgml index d042a740..10947ab0 100644 --- a/zh/15/ref/end.sgml +++ b/zh/15/ref/end.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation END 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/execute.sgml b/zh/15/ref/execute.sgml index 2aed0669..5e7274ff 100644 --- a/zh/15/ref/execute.sgml +++ b/zh/15/ref/execute.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation EXECUTE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/explain.sgml b/zh/15/ref/explain.sgml index 5d6ad75a..bb06dcca 100644 --- a/zh/15/ref/explain.sgml +++ b/zh/15/ref/explain.sgml @@ -21,7 +21,7 @@ PostgreSQL documentation EXPLAIN 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/fetch.sgml b/zh/15/ref/fetch.sgml index 71c12406..9ab88c49 100644 --- a/zh/15/ref/fetch.sgml +++ b/zh/15/ref/fetch.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation FETCH 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/grant.sgml b/zh/15/ref/grant.sgml index 90d2b6aa..170f6226 100644 --- a/zh/15/ref/grant.sgml +++ b/zh/15/ref/grant.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation GRANT 7 - SQL - Language Statements + SQL - 语言语句 @@ -22,7 +22,7 @@ PostgreSQL documentation -GRANT { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER | MAINTAIN } +GRANT { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER } [, ...] | ALL [ PRIVILEGES ] } ON { [ TABLE ] table_name [, ...] | ALL TABLES IN SCHEMA schema_name [, ...] } @@ -99,10 +99,10 @@ GRANT { USAGE | ALL [ PRIVILEGES ] } [ GRANTED BY role_specification ] GRANT role_name [, ...] TO role_specification [, ...] - [ WITH { ADMIN | INHERIT | SET } { OPTION | TRUE | FALSE } ] + [ WITH ADMIN OPTION ] [ GRANTED BY role_specification ] -where role_specification can be: +其中role_specification可以是: [ GROUP ] role_name | PUBLIC @@ -167,7 +167,6 @@ GRANT role_name [, ...] TO USAGE SET ALTER SYSTEM - MAINTAIN 具体的权限类型见 。 @@ -207,39 +206,23 @@ GRANT role_name [, ...] TO - 角色上的 GRANT - 这种 GRANT 命令变体把一个角色的成员资格授予一个或多个其他角色,并修改成员资格选项 SETINHERITADMIN;详见 。角色成员资格之所以重要,是因为它可能使成员能够访问授予给该角色的权限,也可能使其能够对该角色本身作出更改。不过,实际赋予的权限取决于该授权所关联的选项。要修改现有成员资格的这些选项,只需再次指定该成员资格并给出更新后的选项值即可。 - - - - 下面描述的每个选项都可以设为 TRUEFALSE。关键字 OPTION 可作为 TRUE 的同义词,因此 WITH ADMIN OPTION 等同于 WITH ADMIN TRUE。修改现有成员资格时,省略某个选项表示保留其当前值。 - - - - ADMIN 选项允许成员随后将该角色的成员资格授予其他人,也允许撤销该角色中的成员资格。没有该选项时,普通用户不能这样做。角色不被视为在其自身上持有 WITH ADMIN OPTION。数据库超级用户可以向任何人授予或撤销任何角色的成员资格。该选项默认为 FALSE。 - - - - INHERIT 选项控制新成员资格的继承状态;有关继承的细节见 。如果设为 TRUE,会使新成员从被授予的角色继承权限;如果设为 FALSE,新成员就不会继承。创建新的角色成员资格时,如果未指定该选项,则默认采用新成员的继承属性。 - - - - 如果 SET 选项设为 TRUE,成员就可以使用SET ROLE 命令切换到被授予的角色。如果一个角色是另一个角色的间接成员,那么只有在整条授权链上的每一次授权都带有 SET TRUE 时,它才能使用 SET ROLE 切换到该角色。该选项默认为 TRUE。 + 这种GRANT命令变体把一个角色的成员资格授予一个或多个其他角色。角色成员资格之所以重要,是因为它会把授予该角色的权限传递给其每个成员。 - 若要创建由其他角色拥有的对象,或把现有对象的所有权赋给其他角色,必须具备切换为该角色的能力,即能够对该角色执行 SET ROLE;否则,诸如 ALTER ... OWNER TOCREATE DATABASE ... OWNER 之类的命令都会失败。不过,一个继承了某角色权限但不能对其执行 SET ROLE 的用户,仍可能通过操纵该角色拥有的现有对象而获得对该角色的完全访问能力(例如,可以把现有函数重定义为特洛伊木马)。因此,如果某个角色的权限应当可继承,但不应通过 SET ROLE 访问,那么它就不应拥有任何 SQL 对象。 + 如果指定了WITH ADMIN OPTION,成员就可以将该角色的成员资格继续授予其他人,也可以撤销该角色的成员资格。没有管理选项时,普通用户不能这样做。一个角色不被认为在其自身上持有WITH ADMIN + OPTION。数据库超级用户可以向任何人授予或撤销任何角色的成员资格。具有CREATEROLE权限的角色可以授予或撤销任何非超级用户角色的成员资格。 - 如果指定了 GRANTED BY,该授权会被记录为由指定角色执行。只有在用户拥有该角色权限时,才能把授权记为来自另一个角色。除非该角色是引导超级用户,否则被记录为授权者的角色必须对目标角色持有 ADMIN OPTION。当授权被记录为由引导超级用户以外的某个授权者发出时,该授权依赖于授权者继续持有该角色上的 ADMIN OPTION;因此,如果 ADMIN OPTION 被撤销,依赖的授权也必须一并撤销。 + 如果指定了GRANTED BY,该授权会记录为由指定角色执行。只有数据库超级用户可以使用此选项,除非指定的是执行命令的同一角色。 - 与权限的情况不同,角色成员资格不能授予给 PUBLIC。还要注意,这种形式的命令不允许在 role_specification 中使用噪声词 GROUP。 + 与权限不同,角色成员资格不能授予PUBLIC。还要注意,这种形式的命令不允许把无实际作用的GROUP一词用于role_specification中。 @@ -269,7 +252,7 @@ GRANT role_name [, ...] TO - 如果超级用户选择执行 GRANTREVOKE 命令,该命令会像由受影响对象的拥有者发出一样执行。特别是,通过这种命令授予的权限看起来会像是由对象拥有者授予的。(对于角色成员资格,则看起来像是由引导超级用户授予的。) + 如果超级用户选择执行 GRANTREVOKE 命令,该命令会像由受影响对象的拥有者发出一样执行。特别是,通过这种命令授予的权限看起来会像是由对象拥有者授予的。(对于角色成员资格,则看起来像是由被授予成员资格的角色本身授予的。) diff --git a/zh/15/ref/import_foreign_schema.sgml b/zh/15/ref/import_foreign_schema.sgml index 6e912201..1957d60a 100644 --- a/zh/15/ref/import_foreign_schema.sgml +++ b/zh/15/ref/import_foreign_schema.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation IMPORT FOREIGN SCHEMA 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/initdb.sgml b/zh/15/ref/initdb.sgml index 28ee2e7d..16df267e 100644 --- a/zh/15/ref/initdb.sgml +++ b/zh/15/ref/initdb.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation initdb 1 - Application + 应用程序 @@ -76,26 +76,25 @@ PostgreSQL documentation initdb会初始化数据库集簇的默认区域设置和字符集编码。这些设置也可以在 创建每个数据库时分别设置。initdb为模板数据库确定这些设置,它们将 - 作为所有其他数据库的默认值。 + 作为所有其他数据库的默认值。默认情况下,initdb使用 + libc区域设置提供程序,从环境中获取区域设置,并根据区域设置确定编码。 + 除非有特殊要求,这样几乎总能满足需要。 - - 默认情况下,initdb使用libc区域设置提供程序 - (见)。libc区域设置提供程序会 - 从环境中获取区域设置,并根据区域设置确定编码。 - + 要为集簇选择不同的区域设置,请使用。此外还有单独的 - 选项(见下文),用于为各个 + 选项(见下文),用于为各个 区域设置类别设置值。请注意,不同区域设置类别之间若设置不一致,可能产生不合理的结果,因此应谨慎使用。 - 另一种方式是指定--locale-provider=icu,让initdb - 使用 ICU 库提供区域设置服务。服务器必须在构建时启用 ICU 支持。要选择具体要应用的 ICU - 区域设置 ID,请使用。请注意,出于实现原因以及对旧代码的支持, - 在使用 ICU 区域设置提供程序时,initdb仍会选择并初始化 libc 区域设置。 + 也可以使用 ICU 库提供区域设置服务(同样,这只会设置后续创建的数据库的默认值)。 + 要选择此方式,请指定--locale-provider=icu。要选择具体要应用的 + ICU 区域设置 ID,请使用。请注意,出于实现原因以及 + 对旧代码的支持,在使用 ICU 区域设置提供程序时,initdb + 仍会选择并初始化 libc 区域设置。 @@ -178,16 +177,7 @@ PostgreSQL documentation - 选择模板数据库的编码。这也将成为以后创建的任何数据库的默认编码,除非在创建时覆盖它。 - PostgreSQL服务器支持的字符集见 - 。 - - - 默认情况下,模板数据库的编码从区域设置派生。如果指定了 - (或者等价地,区域设置为 - CPOSIX),那么 ICU 提供程序的默认值为 - UTF8,而 libc 提供程序的默认值为 - SQL_ASCII。 + 选择模板数据库的编码。这也将成为以后创建的任何数据库的默认编码,除非在创建时覆盖它。如果使用 libc 区域设置提供程序,默认值由区域设置推导而来;如果使用 ICU 区域设置提供程序,默认值为UTF8PostgreSQL服务器支持的字符集见 @@ -208,20 +198,12 @@ PostgreSQL documentation - 当使用 ICU 提供程序时,指定 ICU 区域设置 ID。区域设置支持见 - 。 + 如果使用 ICU 区域设置提供程序,则指定 ICU 区域设置 ID。 - - - - - 指定附加的排序规则,以定制默认排序规则的行为。该选项仅支持 ICU。 - - - + @@ -250,12 +232,6 @@ PostgreSQL documentation initdb运行时所在的环境。区域设置支持见 - - 如果builtin, - 则必须指定, - 并将其设置为CC.UTF-8或 - PG_UNICODE_FAST。 - @@ -283,23 +259,15 @@ PostgreSQL documentation - - - - - 当使用 builtin 提供程序时,指定区域设置名称。区域设置支持见 - 。 - - - + - + 该选项设置新集簇中创建的数据库所使用的区域设置提供程序。后续创建新数据库时, 可以在CREATE DATABASE命令中覆盖它。默认值为 - libc(见)。 + libc @@ -338,7 +306,7 @@ PostgreSQL documentation - 设置引导超级用户的用户名。 + 选择数据库超级用户的用户名。 默认值是运行initdb的操作系统用户名。 diff --git a/zh/15/ref/insert.sgml b/zh/15/ref/insert.sgml index e3cc2c2e..025d9d82 100644 --- a/zh/15/ref/insert.sgml +++ b/zh/15/ref/insert.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation INSERT 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/listen.sgml b/zh/15/ref/listen.sgml index 8c31cae2..7451cf82 100644 --- a/zh/15/ref/listen.sgml +++ b/zh/15/ref/listen.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation LISTEN 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/load.sgml b/zh/15/ref/load.sgml index bb0adb7c..89bdb114 100644 --- a/zh/15/ref/load.sgml +++ b/zh/15/ref/load.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation LOAD 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/lock.sgml b/zh/15/ref/lock.sgml index bc45eec4..09bc18f9 100644 --- a/zh/15/ref/lock.sgml +++ b/zh/15/ref/lock.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation LOCK 7 - SQL - Language Statements + SQL - 语言语句 @@ -55,7 +55,7 @@ LOCK [ TABLE ] [ ONLY ] name [ * ] 因为SHARE锁模式与写入者获取的ROW EXCLUSIVE锁冲突, 而LOCK TABLE name IN SHARE MODE - 语句会一直等待,直到任何并发持有ROW EXCLUSIVE模式锁的事务提交或回滚。 + 语句会一直等待,直到所有并发持有ROW EXCLUSIVE模式锁的事务提交或回滚。 因此,一旦获得该锁,就不存在尚未提交的写入;而且在释放该锁之前,也不会有新的写入开始。 @@ -136,13 +136,8 @@ LOCK [ TABLE ] [ ONLY ] name [ * ] 注解 - 要锁定一个表,用户必须拥有与所指定lockmode对应的权限。 - 如果用户在该表上拥有MAINTAINUPDATE、 - DELETETRUNCATE权限,则允许使用任意 - lockmode。 - 如果用户在该表上拥有INSERT权限,则允许使用ROW EXCLUSIVE MODE - (或冲突更少的锁模式,见)。 - 如果用户在该表上拥有SELECT权限,则允许使用ACCESS SHARE MODE。 + LOCK TABLE ... IN ACCESS SHARE MODE要求对目标表具有SELECT权限。LOCK TABLE ... IN ROW EXCLUSIVE + MODE要求对目标表具有INSERTUPDATEDELETETRUNCATE权限。所有其他形式的LOCK都要求具有表级UPDATEDELETETRUNCATE权限。 @@ -166,9 +161,7 @@ LOCK [ TABLE ] [ ONLY ] name [ * ] 这些模式名称通常应理解为:用户打算在被锁定的表中获取行级锁。 此外,ROW EXCLUSIVE模式本身也是一种可共享的表锁。 请记住,就LOCK TABLE而言,所有锁模式的语义完全相同, - 差别只在于哪些模式彼此冲突。关于如何获取真正的行级锁,请参阅 - 文档中的和 - 。 + 差别只在于哪些模式彼此冲突。关于如何获取真正的行级锁,请参阅 (后者位于文档中)。 diff --git a/zh/15/ref/merge.sgml b/zh/15/ref/merge.sgml index aaca5a26..bdf97cf1 100644 --- a/zh/15/ref/merge.sgml +++ b/zh/15/ref/merge.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation MERGE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/move.sgml b/zh/15/ref/move.sgml index e90c1b88..961359c8 100644 --- a/zh/15/ref/move.sgml +++ b/zh/15/ref/move.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation MOVE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/notify.sgml b/zh/15/ref/notify.sgml index 43dadec4..a2df6be2 100644 --- a/zh/15/ref/notify.sgml +++ b/zh/15/ref/notify.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation NOTIFY 7 - SQL - Language Statements + SQL - 语言语句 @@ -88,7 +88,7 @@ NOTIFY channel [ , 注解 - 系统中有一个队列,用来保存那些已经发送但尚未被所有监听会话处理的通知。如果这个队列被塞满,那么调用NOTIFY的事务会在提交时失败。该队列非常大(标准安装中为 8GB),几乎足以满足所有用例。不过,如果某个会话执行了LISTEN后又长时间停留在一个事务里,就无法进行清理。一旦队列占用超过一半,你就会在日志文件中看到警告,指出究竟是哪个会话阻碍了清理。在这种情况下,应确保该会话结束其当前事务,以便清理能够继续进行。 + 系统中有一个队列,用来保存那些已经发送但尚未被所有监听会话处理的通知。如果这个队列被塞满,那么调用NOTIFY的事务会在提交时失败。该队列非常大(标准安装中为 8GB),几乎足以满足所有用例。不过,如果某个会话执行了LISTEN后又长时间停留在一个事务里,就无法进行清理。一旦队列占用达到一半,你就会在日志文件中看到警告,指出究竟是哪个会话阻碍了清理。在这种情况下,应确保该会话结束其当前事务,以便清理能够继续进行。 函数pg_notification_queue_usage返回当前被待处理通知占用的队列比例。详见。 @@ -143,7 +143,6 @@ Asynchronous notification "foo" with payload "payload" received from server proc - max_notify_queue_pages diff --git a/zh/15/ref/pg_amcheck.sgml b/zh/15/ref/pg_amcheck.sgml index 855c42dd..a0f5e30f 100644 --- a/zh/15/ref/pg_amcheck.sgml +++ b/zh/15/ref/pg_amcheck.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_amcheck 1 - Application + 应用程序 @@ -284,14 +284,7 @@ PostgreSQL documentation 下列命令行选项控制 B-树索引的检查: - - - - - 对于检查的每个带唯一约束的索引,使用选项,验证重复条目中在索引里可见的项不超过一个。 - - - + @@ -488,17 +481,7 @@ PostgreSQL documentation - - 环境 - - 与大多数其他PostgreSQL工具一样,pg_amcheck也使用libpq支持的环境变量(见)。 - - - - 环境变量PG_COLOR指定是否在诊断消息中使用颜色。可能的值为alwaysautonever。 - - 注意 diff --git a/zh/15/ref/pg_basebackup.sgml b/zh/15/ref/pg_basebackup.sgml index 42ccf23b..2cd8a3d4 100644 --- a/zh/15/ref/pg_basebackup.sgml +++ b/zh/15/ref/pg_basebackup.sgml @@ -4,7 +4,6 @@ PostgreSQL documentation --> - pg_basebackup @@ -12,7 +11,7 @@ PostgreSQL documentation pg_basebackup 1 - Application + 应用程序 @@ -28,19 +27,13 @@ PostgreSQL documentation - 描述 - pg_basebackup用于获取正在运行的PostgreSQL数据库集簇的基础备份。备份过程不会影响数据库的其他客户端,并且该备份既可用于时间点恢复(见),也可用作日志传送或流复制备库的起点(见)。 - pg_basebackup既可以执行完整基础备份,也可以执行增量基础备份。执行完整备份时,它会精确复制数据库集簇的文件。执行增量备份时,原本会包含在完整备份中的某些文件,可能会被这些文件的增量版本替代,其中仅包含自参考备份以来被修改过的块。增量备份不能直接使用;必须先使用pg_combinebackup将其与它所依赖的先前备份合并。关于增量备份的更多信息,见;关于从备份恢复的步骤,见。 - - - - 在任何模式下,pg_basebackup都会确保服务器自动进入和退出备份模式。备份始终针对整个数据库集簇;不可能只备份单个数据库或数据库对象。对于选择性备份,必须使用诸如之类的其他工具。 + pg_basebackup会精确复制数据库集簇的文件,同时确保服务器自动进入和退出备份模式。备份始终针对整个数据库集簇;不可能只备份单个数据库或数据库对象。对于选择性备份,必须使用诸如之类的其他工具。 @@ -80,7 +73,7 @@ PostgreSQL documentation - 备份所需的所有 WAL 记录都必须包含足够的全页写入, + 备份所需的所有 WAL 记录都必须包含足够的整页写入, 因此必须在主库上启用full_page_writes @@ -93,7 +86,6 @@ PostgreSQL documentation - 选项 @@ -160,16 +152,6 @@ PostgreSQL documentation - - - - - - 执行增量备份。必须提供参考备份的备份清单;该文件将被上传到服务器,随后服务器会返回所请求的增量备份。 - - - - @@ -179,10 +161,7 @@ PostgreSQL documentation 创建standby.signal standby.signalpg_basebackup --write-recovery-conf文件,并将连接设置追加到目标目录中的postgresql.auto.conf文件中(如果使用 tar 格式,则追加到基础归档文件内)。这样可以更方便地利用备份结果搭建备库。 - - - postgresql.auto.conf文件将记录连接设置,以及(如果指定)pg_basebackup正在使用的复制槽,以便后续的流复制和逻辑复制槽同步使用相同的设置。只有当 dbname 在连接字符串或环境变量中被显式指定时,才会记录 dbname。 - + postgresql.auto.conf文件会记录pg_basebackup所用的连接设置,以及复制槽(如果指定了),以便流复制以后使用相同的设置。 @@ -207,7 +186,6 @@ PostgreSQL documentation - 在备份期间,将目录olddir中的表空间重定位到newdir。要使此选项生效,olddir必须与源服务器上定义的该表空间路径完全一致。(但如果源服务器上在olddir中没有表空间,也不算错误。)与此同时,newdir是接收主机文件系统中的一个目录。与主目标目录一样,newdir不必事先存在,但如果存在则必须为空。olddirnewdir都必须是绝对路径。如果任一路径中需要包含等号(=),请在其前面加上反斜杠。可以多次指定此选项,以处理多个表空间。 @@ -217,7 +195,7 @@ PostgreSQL documentation - 目前,此选项仅适用于 plain 输出格式;如果选择了 tar 格式,则会被忽略。 + 目前,此选项仅适用于 普通文件 输出格式;如果选择了 tar 格式,则会被忽略。 @@ -225,9 +203,8 @@ PostgreSQL documentation - - 设置写入 WAL(预写式日志)文件的目录。默认情况下,WAL 文件会放在目标目录的pg_wal子目录中,但此选项可用于将其放在其他位置。waldir必须是绝对路径。与主目标目录一样,waldir不必事先存在,但如果存在则必须为空。只有当备份采用 plain 格式时,才能指定此选项。 + 设置写入 WAL(预写式日志)文件的目录。默认情况下,WAL 文件会放在目标目录的pg_wal子目录中,但此选项可用于将其放在其他位置。waldir必须是绝对路径。与主目标目录一样,waldir不必事先存在,但如果存在则必须为空。只有当备份采用 普通文件 格式时,才能指定此选项。 @@ -305,23 +282,23 @@ PostgreSQL documentation - 请求对备份进行压缩。如果包含clientserver,则指定压缩执行的位置。在服务器端压缩会减少传输带宽占用,但会增加服务器 CPU 消耗。默认值是client,但使用--target时除外;此时备份不会发送到客户端,因此只有服务器端压缩才有意义。使用默认的-Xstream时,服务器端压缩不会应用于 WAL。若要压缩 WAL,请使用客户端压缩,或者指定-Xfetch - - 压缩方法可以设置为gziplz4zstdnone(不压缩),也可以直接指定一个整数(0 表示不压缩,大于 0 表示gzip)。还可以选择性地指定压缩细节字符串。如果细节字符串是整数,则表示压缩级别;否则,它应为逗号分隔的项目列表,每项的形式为keywordkeyword=value。目前支持的关键字有levellongworkers。当压缩方法以纯整数形式指定时,不能再使用细节字符串。 - - + 压缩方法可以设置为gziplz4、 + zstd或表示不压缩的none。 + 还可以选择性地指定压缩细节字符串。如果细节字符串是整数,则表示压缩级别; + 否则,它应为逗号分隔的项目列表,每项的形式为keyword + 或keyword=value。目前支持的关键字有level + 和workers。 + 如果未指定压缩级别,则使用默认压缩级别。如果只指定了级别而未指定算法,那么级别大于 0 时使用gzip压缩,级别为 0 时则不压缩。 - - 当 tar 格式配合gziplz4zstd使用时,所有 tar 文件名都会分别自动加上.gz.lz4.zst后缀。使用 plain 格式时,不能指定客户端压缩,但仍可以请求服务器端压缩。这样做时,服务器会先压缩备份再传输,而客户端会对其进行解压并提取。 + 当 tar 格式配合gziplz4zstd使用时,所有 tar 文件名都会分别自动加上.gz.lz4.zst后缀。使用 普通文件 格式时,不能指定客户端压缩,但仍可以请求服务器端压缩。这样做时,服务器会先压缩备份再传输,而客户端会对其进行解压并提取。 - 当此选项与-Xstream组合使用时,如果选择了客户端 gzip 压缩,则pg_wal.tar会使用gzip压缩;但如果选择了其他压缩算法,或者选择了服务器端压缩,则不会被压缩。 @@ -329,7 +306,6 @@ PostgreSQL documentation - 以下命令行选项控制备份的生成和程序的调用: @@ -372,13 +348,12 @@ PostgreSQL documentation - 默认情况下,当pg_basebackup因错误中止时,它会删除在发现自己无法完成任务之前可能已创建的所有目录(例如目标目录和预写式日志目录)。此选项会禁止这种清理,因此对调试很有帮助。 - 请注意,无论如何表空间目录都不会被清理。 + 请注意,无论是否使用此选项,表空间目录都不会被清理。 @@ -424,36 +399,18 @@ PostgreSQL documentation - - 此选项只能与-X stream一起使用。它会使 WAL 流式传输使用指定的复制槽。如果此基础备份打算用作使用复制槽的流复制备库,那么该备库应使用与相同的复制槽名称。这样可以确保主库在基础备份结束与新备库开始流复制之间的这段时间内,不会移除任何必需的 WAL 数据。 + 此选项只能与-X stream一起使用。它会使 WAL 流式传输使用指定的复制槽。如果此基础备份打算用作使用复制槽的流复制备库,那么该备库应将同一个复制槽名称用作的值。这样可以确保主库在基础备份结束与新备库开始流复制之间的这段时间内,不会移除任何必需的 WAL 数据。 - 指定的复制槽必须已经存在,除非还同时使用了 - 如果未指定此选项,并且服务器支持临时复制槽(10 及以上版本),则会自动使用临时复制槽进行 WAL 流式传输。 - - - - - 设置为fsync(默认)时,pg_basebackup会递归打开并同步备份目录中的所有文件。使用 plain 格式时,查找文件会跟随 WAL 目录和各已配置表空间的符号链接。 - - - 在 Linux 上,也可以使用syncfs,让操作系统同步包含备份目录的整个文件系统。使用 plain 格式时,pg_basebackup还会同步包含 WAL 文件和各表空间的文件系统。关于使用syncfs时需要注意的限制,见。 - - - 使用时,此选项无效。 - - - - @@ -468,19 +425,15 @@ PostgreSQL documentation - 指定应用到备份清单中每个文件的校验和算法。目前可用的算法有NONECRC32CSHA224SHA256SHA384SHA512。默认值为CRC32C - 如果选择NONE,备份清单将不包含任何校验和。否则,它将包含使用指定算法为备份中每个文件计算的校验和。此外,清单始终会包含其自身内容的SHA256校验和。SHA算法明显比CRC32C更耗费 CPU,因此选择其中一种可能会增加完成备份所需的时间。 - - 对于希望验证备份未被篡改的用户,使用 SHA 哈希函数可以为每个文件提供具有密码学安全性的摘要;而 CRC-32C 算法提供的校验和计算速度要快得多,虽然它很适合发现由于意外改动造成的错误,但并不能抵御恶意修改。请注意,要想对能够访问备份的攻击者形成防护,备份清单就需要安全地保存在其他地方,或者以其他方式确认自备份完成后未被修改。 + 对于希望验证备份未被篡改的用户,使用 SHA hash 函数可以为每个文件提供具有密码学安全性的摘要;而 CRC32C 算法提供的校验和计算速度要快得多,虽然它很适合发现由于意外改动造成的错误,但并不能抵御恶意修改。请注意,要想对能够访问备份的攻击者形成防护,备份清单就需要安全地保存在其他地方,或者以其他方式确认自备份完成后未被修改。 - 可以使用根据备份清单检查备份的完整性。 @@ -570,9 +523,7 @@ PostgreSQL documentation 连接字符串的形式指定用于连接服务器的参数;这些参数会覆盖任何相互冲突的命令行选项。 - - 出于与其他客户端应用保持一致的考虑,此选项名为--dbname;但由于pg_basebackup并不连接到集簇中的某个特定数据库,连接字符串中包含的数据库名会被服务器忽略。不过,以这种方式提供的数据库名会覆盖默认数据库名(replication),从而用于在~/.pgpass中查找复制连接的密码。类似地,连接PostgreSQL时使用的中间件或代理,也可能出于连接路由等目的使用该名称。该数据库名也可供逻辑复制槽同步使用。 - + 出于与其他客户端应用保持一致的考虑,此选项名为--dbname;但由于pg_basebackup并不连接到集簇中的某个特定数据库,连接字符串中的任何数据库名都会被忽略。 @@ -685,8 +636,7 @@ PostgreSQL documentation - - 注意 + 注解 在备份开始时,需要在源服务器上执行一次检查点。这可能需要一些时间(尤其是在未使用--checkpoint=fast选项时);在此期间,pg_basebackup看起来会处于空闲状态。 @@ -697,16 +647,14 @@ PostgreSQL documentation - 在 plain 格式中,除非使用了--tablespace-mapping选项,否则表空间会备份到其在源服务器上的相同路径。如果不使用此选项,那么当表空间正在使用时,就无法在与服务器相同的主机上执行 plain 格式的基础备份,因为备份将不得不写入与原始表空间相同的目录位置。 + 在 普通文件 格式中,除非使用了--tablespace-mapping选项,否则表空间会备份到其在源服务器上的相同路径。如果不使用此选项,那么当表空间正在使用时,就无法在与服务器相同的主机上执行 普通文件 格式的基础备份,因为备份将不得不写入与原始表空间相同的目录位置。 使用 tar 格式时,用户有责任在启动使用这些数据的 PostgreSQL 服务器之前解压每一个 tar 文件。如果存在额外表空间,则这些表空间对应的 tar 文件必须解压到正确的位置。在这种情况下,服务器会根据包含在base.tar文件中的tablespace_map文件内容,为这些表空间创建符号链接。 - - pg_basebackup可以与相同主版本或更低主版本的服务器配合工作,最低支持到 9.1。不过,WAL 流式传输模式(-X stream)仅适用于 9.3 及以上版本服务器,tar 格式(--format=tar)仅适用于 9.5 及以上版本服务器,而增量备份(--incremental)仅适用于 17 及以上版本服务器。 - + pg_basebackup可以与相同主版本或更低主版本的服务器配合工作,最低支持到 9.1。不过,WAL 流式传输模式(-X stream)仅适用于 9.3 及以上版本服务器,tar 格式(--format=tar)仅适用于 9.5 及以上版本服务器。 如果源集簇启用了数据文件的组权限,pg_basebackup会保留这些组权限。 @@ -756,8 +704,7 @@ PostgreSQL documentation - - 参见 + 另见 diff --git a/zh/15/ref/pg_checksums.sgml b/zh/15/ref/pg_checksums.sgml index bba74354..a22b9125 100644 --- a/zh/15/ref/pg_checksums.sgml +++ b/zh/15/ref/pg_checksums.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_checksums 1 - Application + 应用程序 @@ -33,7 +33,7 @@ PostgreSQL documentation - + 描述 pg_checksums用于在PostgreSQL数据库集簇中检查、启用或禁用数据校验和。运行pg_checksums之前,必须先将服务器干净关闭。验证校验和时,如果没有校验和错误,则退出状态为零;如果检测到至少一个校验和失败,则退出状态为非零。启用或禁用校验和时,如果操作失败,则退出状态为非零。 diff --git a/zh/15/ref/pg_combinebackup.sgml b/zh/15/ref/pg_combinebackup.sgml deleted file mode 100644 index 5ae1aa14..00000000 --- a/zh/15/ref/pg_combinebackup.sgml +++ /dev/null @@ -1,325 +0,0 @@ - - - - - pg_combinebackup - - - - pg_combinebackup - 1 - Application - - - - pg_combinebackup - 从增量备份及其所依赖的备份重建完整备份 - - - - - pg_combinebackup - option - backup_directory - - - - - 描述 - - pg_combinebackup用于从 - 增量备份及其所依赖的 - 更早备份中重建一个合成的完整备份。 - - - - 请在命令行上按照从旧到新的顺序指定所有必需的备份。 - 也就是说,第一个备份目录应当是完整备份的路径, - 最后一个应当是您希望恢复的最终增量备份的路径。 - 重建后的备份将写入由选项指定的输出目录。 - - - - pg_combinebackup会尝试验证您指定的这些备份 - 是否构成一条合法的备份链,并且能否据此重建出正确的完整备份。 - 但它并不是为帮助您跟踪哪些备份依赖于哪些其他备份而设计的。 - 如果您删除了增量备份所依赖的一个或多个先前备份, - 就无法恢复该增量备份。 - 此外,pg_combinebackup只会尝试验证这些备份 - 相互之间的关系是否正确,而不会验证每个单独备份本身是否完好; - 如需完成该项验证,请使用 - 。 - - - - 由于pg_combinebackup的输出是一个合成完整备份, - 因此它可以作为将来调用pg_combinebackup时的输入。 - 在这种情况下,可以在命令行上指定这个合成完整备份, - 以代替原先用于重建它的那条备份链。 - - - - - 选项 - - - - - - - - - 在stderr上输出大量调试日志。 - - - - - - - - - - 在合成备份中使用硬链接,而不是复制文件。 - 这样重建合成备份可能更快(因为无需复制文件), - 并且占用更少磁盘空间;但在使用输出目录时必须格外小心, - 因为对该目录的任何修改(例如启动服务器)也可能影响输入目录。 - 同样,对输入目录的更改(例如在完整备份上启动服务器) - 也可能影响输出目录。 - 因此,此选项最适合输入目录只是副本、并且会在 - pg_combinebackup完成后被删除的场景。 - - - - 要求输入备份和输出目录位于同一文件系统中。 - - - - 如果备份清单不可用,或者其中不包含正确类型的校验和, - 仍会创建硬链接,但也会按块读取文件以计算校验和。 - - - - - - - - - - /会让 - pg_combinebackup确定将要执行哪些操作, - 而不实际创建目标目录或任何输出文件。 - 该选项与组合时尤其有用。 - - - - - - - - - - 默认情况下,pg_combinebackup会等待所有文件都被安全写入磁盘。 - 此选项会使pg_combinebackup不经等待就直接返回,因此速度更快, - 但这意味着如果随后操作系统崩溃,输出备份可能会损坏。 - 通常,此选项适合测试,但不应用于创建生产环境安装。 - - - - - - - - - - 指定合成完整备份写入的输出目录。 - 当前该参数是必需的。 - - - - - - - - - - 在重建备份期间,将目录olddir中的表空间重定位到 - newdir。 - olddir是命令行指定的最终备份中该表空间的绝对路径, - newdir是重建备份中要使用的绝对路径。 - 若路径中需要包含等号(=),请在其前加反斜杠。 - 可多次指定此选项以映射多个表空间。 - - - - - - - - - 使用高效的文件克隆(某些系统将其称为reflink), - 代替向新数据目录复制文件,这样可能实现几乎瞬时的数据文件复制。 - - - - 如果备份清单不可用,或者其中不包含正确类型的校验和, - 仍会使用文件克隆来复制文件,但也会按块读取该文件以计算校验和。 - - - - 文件克隆仅在某些操作系统和文件系统上受支持。 - 如果选择了该选项,但系统并不支持, - pg_combinebackup运行时将报错。 - 目前,它在 Linux(内核 4.5 及以上)上的 Btrfs 和 XFS - (在创建时启用了 reflink 支持的文件系统)以及 macOS 上的 APFS - 上受支持。 - - - - - - - - - 执行常规文件复制。这是默认行为。 - (另见 - 和/。) - - - - - - - - - 使用copy_file_range系统调用进行高效复制。 - 在某些文件系统上,这会得到与类似的结果, - 即共享物理磁盘块;而在其他文件系统上,它仍可能复制数据块, - 但会通过优化后的路径进行。目前支持 Linux 和 FreeBSD。 - - - - 如果备份清单不可用,或者其中不包含正确类型的校验和, - 仍会使用copy_file_range复制文件, - 但也会按块读取该文件以计算校验和。 - - - - - - - - - 与一样, - pg_combinebackup会在输出目录中写入备份清单。 - 此选项指定对清单中每个文件使用的校验和算法。 - 当前可用算法为NONECRC32C、 - SHA224SHA256、 - SHA384SHA512。 - 默认值为CRC32C。 - - - - - - - - - 禁用备份清单的生成。 - 若未指定该选项,则会将重建备份的清单写入输出目录。 - - - - - - - - - 当设置为fsync(这是默认值)时, - pg_combinebackup会递归打开并同步备份目录中的所有文件。 - 使用 plain 格式时,搜索文件时会跟随 WAL 目录和每个已配置表空间的符号链接。 - - - 在 Linux 上,也可以改用syncfs, - 让操作系统同步包含备份目录的整个文件系统。 - 使用 plain 格式时,pg_combinebackup - 还会同步包含 WAL 文件和各表空间的文件系统。 - 关于使用syncfs时需要注意的事项,请参见 - 。 - - - 当使用时,此选项无效。 - - - - - - - - - - 打印pg_combinebackup版本并退出。 - - - - - - - - - - 显示pg_combinebackup命令行参数帮助并退出。 - - - - - - - - - - - 限制 - - - pg_combinebackup在写入输出目录时不会重新计算页面校验和。 - 因此,如果用于重建的某些备份是在禁用校验和时创建的, - 而最终备份是在启用校验和时创建的, - 则生成的目录中可能包含校验和无效的页面。 - - - - 为避免这个问题,建议在使用 - 更改集簇的校验和状态之后重新创建一次新的完整备份。 - 否则,您也可以对由pg_combinebackup生成的目录 - 先禁用校验和,然后再按需重新启用,以修正这个问题。 - - - - - 环境 - - - 与多数PostgreSQL工具一样, - 本工具使用libpq支持的环境变量 - (参见)。 - - - - 环境变量PG_COLOR指定诊断消息是否使用颜色。 - 可选值为alwaysauto和 - never。 - - - - - 另见 - - - - - - - diff --git a/zh/15/ref/pg_config-ref.sgml b/zh/15/ref/pg_config-ref.sgml index 565638d9..b157f24c 100644 --- a/zh/15/ref/pg_config-ref.sgml +++ b/zh/15/ref/pg_config-ref.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation pg_config 1 - Application + 应用程序 diff --git a/zh/15/ref/pg_controldata.sgml b/zh/15/ref/pg_controldata.sgml index 818db6cc..5435edfa 100644 --- a/zh/15/ref/pg_controldata.sgml +++ b/zh/15/ref/pg_controldata.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_controldata 1 - Application + 应用程序 diff --git a/zh/15/ref/pg_createsubscriber.sgml b/zh/15/ref/pg_createsubscriber.sgml deleted file mode 100644 index 653d5ada..00000000 --- a/zh/15/ref/pg_createsubscriber.sgml +++ /dev/null @@ -1,552 +0,0 @@ - - - - - pg_createsubscriber - - - - pg_createsubscriber - 1 - Application - - - - pg_createsubscriber - 将物理副本转换为新的逻辑副本 - - - - - pg_createsubscriber - option - - - - - - dbname - - - - - datadir - - - - - connstr - - - - - - 描述 - - - pg_createsubscriber从物理备库创建新的逻辑副本。 - 指定数据库中的所有表都会包含在逻辑复制配置中。 - 每个数据库都会创建一对发布和订阅对象。 - 该工具必须在目标服务器上运行。 - - - - 成功运行后,目标服务器的状态类似于一个全新的逻辑复制配置。 - 逻辑复制配置与pg_createsubscriber之间的主要区别在于 - 数据同步的完成方式。pg_createsubscriber - 不会复制初始表数据。它只执行同步阶段,以确保每个表都达到同步状态。 - - - - pg_createsubscriber主要面向大型数据库系统, - 因为在逻辑复制配置中,大部分时间都花在复制初始数据上。 - 此外,在数据同步上花费较长时间的一个副作用通常是,会有大量在初始数据复制期间产生的更改需要应用, - 这会进一步延后逻辑副本可用的时间。对于较小的数据库,建议建立带初始数据同步的逻辑复制。 - 详见CREATE SUBSCRIPTION的 - - copy_data选项。 - - - - - - 选项 - - - pg_createsubscriber接受以下命令行参数: - - - - - - - - 在目标服务器上的每个数据库中创建一个订阅。 - 模板数据库以及不允许连接的数据库除外。 - 为发现所有数据库的列表,工具会使用 - 连接字符串中指定的数据库名连接到源服务器;如果未指定,则使用 - postgres数据库;如果该数据库不存在,则使用 - template1。 - 指定此选项时,会使用自动生成的订阅、发布和复制槽名称。 - 此选项不能与、 - 一起使用。 - - - - - - - - - - 要在其中创建订阅的数据库名称。通过多次指定 - 可以选择多个数据库。此选项不能与一起使用。 - 如果未提供选项,数据库名将从 - 选项中获取。如果在选项或 - 选项中都未指定数据库名,且又未指定选项, - 则会报告错误。 - - - - - - - - - - 包含物理副本中的集簇目录的目标目录。 - - - - - - - - - - 执行除实际修改目标目录之外的所有步骤。 - - - - - - - - - - 目标服务器监听连接的端口号。 - 默认为让目标服务器在 50432 端口上运行,以避免意外的客户端连接。 - - - - - - - - - - 到发布者的连接字符串。详情见。 - - - - - - - - - - 目标服务器上 postmaster 套接字所使用的目录。 - 默认值为当前目录。 - - - - - - - - - - 等待恢复结束的最大秒数。设为 0 表示禁用。 - 默认值为 0。 - - - - - - - - - - 为订阅启用 - two_phase - 两阶段提交。当指定多个数据库时,此选项会统一应用于在这些数据库上创建的所有订阅。 - 默认值为false。 - - - - - - - - - - 连接目标服务器所使用的用户名。 - 默认是当前操作系统用户名。 - - - - - - - - - - 启用详细模式。这将使 - pg_createsubscriber向标准错误输出进度消息 - 以及每个步骤的详细信息。重复指定该选项会让更多调试级消息出现在标准错误中。 - - - - - - - - - 从目标服务器上的指定数据库中删除指定类型的所有对象。 - - - - - - publications: - 为该订阅者建立的FOR ALL TABLES发布总是会被删除; - 指定此对象类型还会删除从源服务器复制过来的其他所有发布。 - - - - - - 被选中要删除的对象都会逐个记录到日志中,包括在 - 期间也是如此。没有机会干预或停止这些对象的删除,因此可以考虑使用 - pg_dump先对它们进行备份。 - - - - - - - - - 为目标数据目录使用指定的主配置文件。 - pg_createsubscriber在内部使用 - pg_ctl命令来启动和停止目标服务器。 - 如果实际的postgresql.conf配置文件存放在数据目录之外, - 此选项允许你显式指定它。 - - - - - - - - - 用于建立逻辑复制的发布名称。通过多次指定 - 可以指定多个发布。发布名称的数量必须与指定的数据库数量一致, - 否则会报告错误。多个发布名称开关的顺序必须与数据库开关的顺序一致。 - 如果未指定此选项,则会为发布分配一个生成的名称。此选项不能与 - 一起使用。 - - - - - - - - - 用于建立逻辑复制的复制槽名称。通过多次指定 - 可以指定多个复制槽。复制槽名称的数量必须与指定的数据库数量一致, - 否则会报告错误。多个复制槽名称开关的顺序必须与数据库开关的顺序一致。 - 如果未指定此选项,则使用订阅名称作为复制槽名称。此选项不能与 - 一起使用。 - - - - - - - - - 用于建立逻辑复制的订阅名称。通过多次指定 - 可以指定多个订阅。订阅名称的数量必须与指定的数据库数量一致, - 否则会报告错误。多个订阅名称开关的顺序必须与数据库开关的顺序一致。 - 如果未指定此选项,则会为订阅分配一个生成的名称。此选项不能与 - 一起使用。 - - - - - - - - - - 打印pg_createsubscriber版本并退出。 - - - - - - - - - - 显示pg_createsubscriber命令行参数的帮助并退出。 - - - - - - - - - 注意 - - - 前置条件 - - - 要让pg_createsubscriber将目标服务器转换为逻辑副本, - 需要满足一些前提条件。如果不满足这些条件,就会报告错误。 - 源服务器和目标服务器的主版本必须与 - pg_createsubscriber相同。 - 给定的目标数据目录必须与源数据目录具有相同的系统标识符。 - 为目标数据目录指定的数据库用户必须具备创建订阅以及使用pg_replication_origin_advance() - 的权限。 - - - - 目标服务器必须作为物理备库使用。 - 目标服务器必须将max_active_replication_origins配置为大于等于指定数据库数量的值。 - 目标服务器必须将配置为大于指定数据库数量的值。 - 目标服务器必须接受本地连接。如果计划使用 - 开关,还需要适当地设置。 - - - - 源服务器必须接受来自目标服务器的连接。源服务器不能处于恢复中。 - 源服务器必须将设置为logical。 - 源服务器必须将配置为 - 大于等于指定数据库数量加现有复制槽数量的值。源服务器必须将配置为大于等于指定数据库数量与现有 WAL 发送器 - 进程数量之和的值。 - - - - - 警告 - - - 若pg_createsubscriber在目标服务器被提升后失败, - 数据目录很可能已处于不可恢复状态。此时建议重新创建新的备库。 - - - - 在转换过程中,pg_createsubscriber通常会使用不同的连接设置 - 来启动目标服务器。因此,对目标服务器的连接应该会失败。 - - - - 由于逻辑复制不复制 DDL 命令, - 运行pg_createsubscriber期间应避免执行会更改数据库模式的 DDL 命令。 - 若目标服务器已转换为逻辑副本,相关 DDL 可能不会被复制,从而引发错误。 - - - - 若pg_createsubscriber处理过程中失败, - 会删除在源服务器上创建的对象(发布、复制槽)。 - 如果目标服务器无法连接到源服务器,删除可能失败。 - 在这种情况下,警告消息会提示遗留的对象。 - 如果目标服务器正在运行,它会被停止。 - - - - 若复制使用了, - 在逻辑复制配置完成后会从源服务器移除该复制槽。 - - - - 如果目标服务器是同步副本, - 运行pg_createsubscriber期间, - 主库上的事务提交可能会在等待复制时阻塞。 - - - - 除非指定, - pg_createsubscriber会在禁用两阶段提交的情况下建立逻辑复制。 - 这意味着任何预备事务都会在COMMIT PREPARED时被复制, - 而不会事先进行预备。配置完成后,你可以手动删除并重新创建订阅, - 并启用two_phase - 选项。 - - - - pg_createsubscriber会使用pg_resetwal - 修改系统标识符。 - 这样可以避免目标服务器可能使用源服务器的 WAL 文件。 - 如果目标服务器还有备库,复制将会中断,应创建一个新的备库。 - - - - 若缺少必需 WAL 文件,复制可能失败。 - 为避免该问题,源服务器应将 - 设置为-1, - 以确保必需 WAL 文件不会被提前移除。 - - - - - 工作原理 - - - 基本思路是从源服务器获得复制起点,并从该位置开始建立逻辑复制: - - - - - - 使用指定命令行选项启动目标服务器。 - 若目标服务器已在运行,pg_createsubscriber会报错终止。 - - - - - - 检查目标服务器是否可以转换,同时也会对源服务器进行一些检查。 - 若任一前置条件不满足,pg_createsubscriber会报错终止。 - - - - - - 在源服务器上为每个指定的数据库创建一个发布和一个复制槽。 - 每个发布都以FOR ALL - TABLES创建。 - 若未指定,发布名称模式为 - pg_createsubscriber_%u_%x - (参数:数据库oid、随机int)。 - 若未指定,复制槽的名称模式如下: - pg_createsubscriber_%u_%x - (参数:数据库oid、随机int)。 - 这些复制槽将在后续步骤中被订阅使用。最后一个复制槽的 LSN 会在 - 参数中用作停止点,也会被订阅用作复制起点。 - 这样可以保证不会丢失任何事务。 - - - - - - 将恢复参数写入目标数据目录并重启目标服务器。 - 它指定了恢复将推进到的预写式日志位置的 LSN()。 - 它还将promote指定为服务器在达到恢复目标后应执行的动作。 - 为了避免恢复过程中出现意外行为,还会添加其他恢复参数,例如在达到一致状态后就结束恢复 - (实际上 WAL 应继续应用到复制起始位置)以及因多个恢复目标而导致失败。 - 当服务器退出备库模式并接受读写事务时,该步骤结束。 - 如果设置了选项,而恢复在给定秒数内没有结束, - pg_createsubscriber就会终止。 - - - - - - 在目标服务器上为每个指定数据库创建订阅。 - 若未指定,名称模式为 - pg_createsubscriber_%u_%x - (参数:数据库oid、随机int)。 - 该订阅不会复制源服务器上的现有数据,也不会创建复制槽, - 而是使用前一步中创建的复制槽。订阅会被创建,但尚不启用, - 因为必须在启动复制之前先将复制进度设置到复制起点。 - - - - - - 删除在目标服务器上被复制过来的发布(这些发布是在复制起点前创建的), - 它们在订阅者上没有用途。 - - - - - - 将每个订阅的复制进度设置为复制起点。 - 当目标服务器开始恢复过程时,它会追赶到复制起点。 - 这正是每个订阅要用作初始复制位置的 LSN。 - 由于订阅已经创建,因此可以取得复制源名称。 - 使用复制源名称和复制起点调用 - pg_replication_origin_advance() - 以设置初始复制位置。 - - - - - - 在目标服务器上启用每个指定数据库的订阅。 - 订阅将从复制起点开始应用事务。 - - - - - - 若备库使用了, - 该复制槽之后不再有用,故将其删除。 - - - - - - 若备库包含故障切换复制槽, - 它们后续无法继续同步,故将其删除。 - - - - - - 更新目标服务器上的系统标识符。会运行 - 来修改系统标识符。由于pg_resetwal的要求,目标服务器会被停止。 - - - - - - - - 示例 - - - 要从位于foo的物理副本为数据库 - hrfinance创建逻辑副本: - -$ pg_createsubscriber -D /usr/local/pgsql/data -P "host=foo" -d hr -d finance - - - - - - 另见 - - - - - - diff --git a/zh/15/ref/pg_ctl-ref.sgml b/zh/15/ref/pg_ctl-ref.sgml index 6085da56..801cbc55 100644 --- a/zh/15/ref/pg_ctl-ref.sgml +++ b/zh/15/ref/pg_ctl-ref.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation pg_ctl 1 - Application + 应用程序 diff --git a/zh/15/ref/pg_dump.sgml b/zh/15/ref/pg_dump.sgml index 5bf6314d..7b0da2b2 100644 --- a/zh/15/ref/pg_dump.sgml +++ b/zh/15/ref/pg_dump.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_dump 1 - Application + 应用程序 @@ -1529,7 +1529,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; 完整表复制之前,可能也适合先截断目标表。如果用户打算在刷新期间复制初始 数据,则必须以 two_phase = false 创建该槽。初始同步 之后,订阅者会自动启用 - two_phase + two_phase 选项,前提是该订阅最初是以 two_phase = true 选项创建的。 diff --git a/zh/15/ref/pg_dumpall.sgml b/zh/15/ref/pg_dumpall.sgml index bdec2662..c10a1658 100644 --- a/zh/15/ref/pg_dumpall.sgml +++ b/zh/15/ref/pg_dumpall.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_dumpall 1 - Application + 应用程序 diff --git a/zh/15/ref/pg_isready.sgml b/zh/15/ref/pg_isready.sgml index 2e93dde1..a09f7745 100644 --- a/zh/15/ref/pg_isready.sgml +++ b/zh/15/ref/pg_isready.sgml @@ -13,7 +13,7 @@ PostgreSQL documentation pg_isready 1 - Application + 应用程序 diff --git a/zh/15/ref/pg_receivewal.sgml b/zh/15/ref/pg_receivewal.sgml index 3c9e580a..bf520c28 100644 --- a/zh/15/ref/pg_receivewal.sgml +++ b/zh/15/ref/pg_receivewal.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation pg_receivewal 1 - Application + 应用程序 diff --git a/zh/15/ref/pg_recvlogical.sgml b/zh/15/ref/pg_recvlogical.sgml index 993fc2a9..c92bbed9 100644 --- a/zh/15/ref/pg_recvlogical.sgml +++ b/zh/15/ref/pg_recvlogical.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation pg_recvlogical 1 - Application + 应用程序 @@ -44,11 +44,7 @@ PostgreSQL documentation pg_recvlogical没有与逻辑解码 SQL 接口中 peek 和 get 模式等价的功能。它会在接收数据期间惰性地为这些数据发送回放确认,并在正常退出时发送确认。若要在不消费数据的情况下检查某个槽上的待处理数据,请使用pg_logical_slot_peek_changes - - 在没有致命错误的情况下,pg_recvlogical会一直运行,直到收到 - SIGINTControlC) - 或 SIGTERM 信号。 - + pg_recvlogical 收到 SIGHUP 信号时, @@ -75,13 +71,7 @@ PostgreSQL documentation 创建一个名称由指定的新逻辑复制槽。 - - 此操作必须指定 。 - - - - 可与 一起指定 选项。 - + 可与一起指定,以启用对预备事务的解码。 @@ -91,9 +81,6 @@ PostgreSQL documentation 删除由指定名称的复制槽,然后退出。 - - 此操作必须指定 。 - @@ -105,10 +92,6 @@ PostgreSQL documentation 如果服务端的更改流因服务器关闭或断开连接而结束,则除非指定了,否则会循环重试。 - - 此操作必须指定 。 - - 流格式由创建该槽时指定的输出插件决定。 @@ -134,7 +117,6 @@ PostgreSQL documentation - 模式下,当接收达到指定的 LSN 时,自动停止复制,并以正常退出状态 0 退出。 如果在非模式下指定,则会报错。 @@ -151,26 +133,15 @@ PostgreSQL documentation - - - - - 启用后会将该槽同步到备库。此选项只能与 一起指定。 - - - + - 将接收到并解码后的事务数据写入该文件。指定-表示写入stdout - - 此参数对于 操作是必需的。 - @@ -178,10 +149,9 @@ PostgreSQL documentation - 指定pg_recvlogical应当以多高的频率发起fsync()调用, - 以确保输出文件被安全地刷入磁盘。 + 以确保输出文件安全刷盘。 @@ -200,7 +170,6 @@ PostgreSQL documentation - 模式下,从给定的 LSN 开始复制。关于其影响的详细信息,请参见 中的说明。 @@ -212,7 +181,6 @@ PostgreSQL documentation - 当指定且指定名称的槽已存在时,不报错。 @@ -223,7 +191,6 @@ PostgreSQL documentation - 当与服务器的连接丢失时,不要循环重试,直接退出。 @@ -234,7 +201,6 @@ PostgreSQL documentation - 将选项name传递给输出插件;如果指定了value, 则将其用作该选项的值。可用选项及其效果取决于所使用的输出插件。 @@ -246,7 +212,6 @@ PostgreSQL documentation - 创建该槽时,使用指定的逻辑解码输出插件。参见。 如果该槽已经存在,则此选项不起作用。 @@ -258,7 +223,6 @@ PostgreSQL documentation - 该选项与中同名选项的效果相同。参见该处说明。 @@ -269,27 +233,19 @@ PostgreSQL documentation - 模式下,使用名为slot_name的现有逻辑复制槽。 在模式下,以此名称创建该槽。 在模式下,删除此名称的槽。 - - 此参数对于任何一种操作都是必需的。 - - - (已废弃) + - - - 启用对预备事务的解码。此选项只能与一起指定。 - + 启用对预备事务的解码。此选项只能与一起指定。 @@ -297,7 +253,6 @@ PostgreSQL documentation - 启用详细模式。 @@ -314,14 +269,7 @@ PostgreSQL documentation - - 要连接到的数据库。其具体含义请参见各操作的说明。 - dbname可以是一个连接字符串。 - 如果是这种情况,连接字符串参数将覆盖任何冲突的命令行选项。 - - - 此参数在 操作中是必需的。 - + 要连接的数据库。有关其具体含义,请参阅各操作的说明。dbname可以是一个连接字符串。如果如此,连接字符串参数会覆盖任何与之冲突的命令行选项。默认值为用户名。 @@ -329,7 +277,7 @@ PostgreSQL documentation - + 指定服务器运行所在机器的主机名。如果该值以斜杠开头, 则它会被用作 Unix 域套接字的目录。默认值取自 PGHOST环境变量(如果已设置), @@ -342,7 +290,7 @@ PostgreSQL documentation - + 指定服务器监听连接所用的 TCP 端口,或本地 Unix 域套接字文件扩展名。 默认值取自PGPORT环境变量(如果已设置), 否则使用编译时的默认值。 @@ -354,7 +302,7 @@ PostgreSQL documentation - + 用于连接的用户名。默认为当前操作系统用户名。 @@ -364,7 +312,7 @@ PostgreSQL documentation - + 绝不提示输入密码。如果服务器要求密码认证,而密码又无法通过 .pgpass文件等其他方式获得, 则连接尝试将失败。此选项适用于批处理作业和脚本, @@ -377,7 +325,7 @@ PostgreSQL documentation - + 强制pg_recvlogical在连接数据库之前提示输入密码。 @@ -411,7 +359,7 @@ PostgreSQL documentation - + 显示pg_recvlogical命令行参数的帮助并退出。 @@ -420,14 +368,7 @@ PostgreSQL documentation - - 退出状态 - - 当收到 SIGINTSIGTERM 信号终止时, - pg_recvlogical会以状态 0 退出。(这是其正常结束方式,因此不视为错误。) - 遇到致命错误或其他信号时,退出状态为非零。 - - + diff --git a/zh/15/ref/pg_resetwal.sgml b/zh/15/ref/pg_resetwal.sgml index 9deadc8c..7dee0bce 100644 --- a/zh/15/ref/pg_resetwal.sgml +++ b/zh/15/ref/pg_resetwal.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_resetwal 1 - Application + 应用程序 diff --git a/zh/15/ref/pg_restore.sgml b/zh/15/ref/pg_restore.sgml index 7ae86b39..8cd4af1a 100644 --- a/zh/15/ref/pg_restore.sgml +++ b/zh/15/ref/pg_restore.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_restore 1 - Application + 应用程序 diff --git a/zh/15/ref/pg_rewind.sgml b/zh/15/ref/pg_rewind.sgml index 16ffc2e9..93617f49 100644 --- a/zh/15/ref/pg_rewind.sgml +++ b/zh/15/ref/pg_rewind.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation pg_rewind 1 - Application + 应用程序 diff --git a/zh/15/ref/pg_verifybackup.sgml b/zh/15/ref/pg_verifybackup.sgml index a2afbec0..6cbb79a6 100644 --- a/zh/15/ref/pg_verifybackup.sgml +++ b/zh/15/ref/pg_verifybackup.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_verifybackup 1 - Application + 应用程序 @@ -28,32 +28,16 @@ PostgreSQL documentation 描述 - - pg_verifybackup用于依据服务器在备份时生成的 - backup_manifest,检查使用 - pg_basebackup获取的数据库集簇备份的完整性。备份 - 既可以采用“plain”格式,也可以采用“tar”格式;其中也包括使用 - pg_basebackup支持的任意算法压缩的 tar 格 - 式备份。不过,目前仅支持对 plain 格式备份执行WAL - 验证。因此,如果备份采用 tar 格式存储,应使用 - -n, --no-parse-wal选项。 - + pg_verifybackup用于检查通过pg_basebackup获取的数据库集簇备份的完整性,检查依据是服务器在备份时生成的backup_manifest。备份必须以“普通文件”格式存储;“tar”格式的备份可以在解包后检查。 需要注意,pg_verifybackup执行的验证并未、也 不可能涵盖运行中的服务器在尝试使用该备份时会执行的每一项检查。即使使 - 用了此工具,你仍应进行测试恢复,并确认生成的数据库按预期工作且包含正 - 确的数据。不过,pg_verifybackup能够检测出 + 用了此工具,你仍应进行测试恢复,并确认生成的数据库按预期工作且看起来包含正确的数据。不过,pg_verifybackup能够检测出 许多因存储问题或用户错误而常见的问题。 - - 备份验证分为四个阶段。首先,pg_verifybackup读取 - backup_manifest文件。如果该文件不存在、无法读取、 - 格式不正确、其系统标识符与备份目录中的pg_control - 不匹配,或者未能通过其自身内部校验和的验证, - pg_verifybackup就会以致命错误终止。 - + 备份验证分为四个阶段。首先,pg_verifybackup读取backup_manifest文件。如果该文件不存在、无法读取、格式不正确,或者未能通过其自身内部校验和的验证,pg_verifybackup就会以致命错误终止。 其次,pg_verifybackup将尝试验证当前存储在磁盘上 @@ -118,41 +102,6 @@ PostgreSQL documentation - - - - - - 指定备份格式。format可以是下列值之一: - - - - p - plain - - - 备份由普通文件组成,其布局与源服务器的数据目录和表空间相同。 - - - - - - t - tar - - - 备份由 tar 文件组成,这些文件可以经过压缩。有效的备份包括名为 - base.tar的主数据目录、名为 - pg_wal.tar的 WAL 文件,以及每个表空间 - 对应的单独 tar 文件,这些文件以该表空间的 OID 命名。如果备份 - 被压缩,则会在每个文件名末尾追加相应的压缩扩展名。 - - - - - - - @@ -188,19 +137,6 @@ PostgreSQL documentation - - - - - - 启用进度报告。启用此选项后,在验证校验和时会输出进度报告。 - - - 此选项不能与一起使用。 - - - - @@ -237,9 +173,9 @@ PostgreSQL documentation - 还提供下列其他选项: + 其他选项也可用: - + @@ -270,7 +206,7 @@ PostgreSQL documentation 示例 - 要在mydbserver上创建服务器的基础备份,并验证该备 + 要为位于mydbserver的服务器创建基础备份,并验证该备 份的完整性: $ pg_basebackup -h mydbserver -D /usr/local/pgsql/data @@ -279,7 +215,7 @@ PostgreSQL documentation - 要在mydbserver上创建服务器的基础备份,将备份清单 + 要为位于mydbserver的服务器创建基础备份,将备份清单 移到备份目录之外的位置,然后验证该备份: $ pg_basebackup -h mydbserver -D /usr/local/pgsql/backup1234 diff --git a/zh/15/ref/pg_waldump.sgml b/zh/15/ref/pg_waldump.sgml index a4433e63..baa4bb42 100644 --- a/zh/15/ref/pg_waldump.sgml +++ b/zh/15/ref/pg_waldump.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_waldump 1 - Application + 应用程序 diff --git a/zh/15/ref/pg_walsummary.sgml b/zh/15/ref/pg_walsummary.sgml deleted file mode 100644 index 2e8ee5fd..00000000 --- a/zh/15/ref/pg_walsummary.sgml +++ /dev/null @@ -1,124 +0,0 @@ - - - - - pg_walsummary - - - - pg_walsummary - 1 - Application - - - - pg_walsummary - 打印 WAL 汇总文件的内容 - - - - - pg_walsummary - option - file - - - - - 描述 - - pg_walsummary用于打印 WAL 汇总文件的内容。 - 这些二进制文件位于数据目录下的pg_wal/summaries子目录中, - 可使用本工具将其转换为文本。 - 通常并无此必要,因为 WAL 汇总文件主要是为了支持 - 增量备份而存在的, - 但在调试时可能会很有用。 - - - - WAL 汇总文件按表空间 OID、关系 OID 以及关系分支(fork)建立索引。 - 对于每个关系分支,它都存储该文件所汇总范围内被 WAL 修改的块列表。 - 它还可以存储一个limit block: - 如果该关系分支在相关 WAL 范围内被创建或截断,则其值为 0; - 否则,其值为该关系分支被截断后的最短长度。 - 如果该关系分支在相关 WAL 范围内未被创建、删除或截断, - 则 limit block 未定义,或者为无穷大,本工具不会打印它。 - - - - - 选项 - - - - - - - - - 默认情况下,pg_walsummary会为每个由一个或多个连续已修改块构成的范围输出一行。 - 这样可以使输出简洁得多,因为如果某个关系中从 0 到 999 的所有块都被修改了, - 则只会输出一行,而不是 1000 行单独的输出。 - 该选项要求为每个已修改块分别输出一行。 - - - - - - - - - - 除错误之外不打印任何输出。 - 当只想知道某个 WAL 汇总文件能否被成功解析,而并不关心其内容时,这会很有用。 - - - - - - - - - - 显示版本信息,然后退出。 - - - - - - - - - - 显示pg_walsummary命令行参数的帮助并退出。 - - - - - - - - - - - 环境 - - - 环境变量PG_COLOR用于指定是否在诊断消息中使用颜色。 - 可能的值为alwaysauto和 - never。 - - - - - 另见 - - - - - - - diff --git a/zh/15/ref/pgarchivecleanup.sgml b/zh/15/ref/pgarchivecleanup.sgml index 5c2c0a53..fd4da23e 100644 --- a/zh/15/ref/pgarchivecleanup.sgml +++ b/zh/15/ref/pgarchivecleanup.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_archivecleanup 1 - Application + 应用程序 diff --git a/zh/15/ref/pgbench.sgml b/zh/15/ref/pgbench.sgml index a0e6ceab..f699e735 100644 --- a/zh/15/ref/pgbench.sgml +++ b/zh/15/ref/pgbench.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation pgbench 1 - Application + 应用程序 @@ -1685,7 +1685,7 @@ SELECT 4 AS four \; SELECT 5 AS five \aset greatest ( number , ... ) - double 如果任何参数是双精度的,否则 integer + 若任一参数为 double,则为 double,否则为 integer 选择参数中的最大值。 @@ -1755,7 +1755,7 @@ SELECT 4 AS four \; SELECT 5 AS five \aset least ( number , ... ) - double 如果任何参数是双精度的,否则 integer + 若任一参数为 double,则为 double,否则为 integer 选择参数中的最小值。 @@ -2602,7 +2602,7 @@ PGOPTIONS='-c default_table_access_method=wuzza' 安全性 - 如果不可信用户能够访问尚未采用模式的安全使用方式的数据库,就不要在该数据库中运行pgbenchpgbench使用非限定名称,并且不会更改搜索路径。 + 如果不受信任的用户能够访问尚未采用模式的安全使用方式的数据库,就不要在该数据库中运行pgbenchpgbench使用非限定名称,并且不会更改搜索路径。 diff --git a/zh/15/ref/pgtestfsync.sgml b/zh/15/ref/pgtestfsync.sgml index 86e69b30..6055bccf 100644 --- a/zh/15/ref/pgtestfsync.sgml +++ b/zh/15/ref/pgtestfsync.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_test_fsync 1 - Application + 应用程序 diff --git a/zh/15/ref/pgtesttiming.sgml b/zh/15/ref/pgtesttiming.sgml index f652980f..dc7208fc 100644 --- a/zh/15/ref/pgtesttiming.sgml +++ b/zh/15/ref/pgtesttiming.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_test_timing 1 - Application + 应用程序 diff --git a/zh/15/ref/pgupgrade.sgml b/zh/15/ref/pgupgrade.sgml index 33017708..0172cd36 100644 --- a/zh/15/ref/pgupgrade.sgml +++ b/zh/15/ref/pgupgrade.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_upgrade 1 - Application + 应用程序 @@ -40,8 +40,8 @@ PostgreSQL documentation pg_upgrade(以前称为 pg_migrator)允许将存储在 PostgreSQL 数据文件中的数据升级到更新的 PostgreSQL主版本,而无需执行主版本升级通常所需的数据转储/恢复, - 例如从 12.14 升级到 13.10,或从 14.9 升级到 15.5。它不用于次版本升级, - 例如从 12.7 升级到 12.8 或从 14.1 升级到 14.5。 + 例如从 9.5.8 升级到 9.6.4,或从 10.7 升级到 11.2。次版本升级不需要使用它, + 例如从 9.6.2 升级到 9.6.3 或从 10.1 升级到 10.2。 @@ -58,10 +58,7 @@ PostgreSQL documentation 二进制兼容,这一点很重要,但 pg_upgrade 无法检查。 - - pg_upgrade 支持从 9.2.X 及更高版本升级到当前 - PostgreSQL主版本,包括快照版和 beta 版。 - + pg_upgrade 支持从 9.2.X 及更高版本升级到当前PostgreSQL主版本,包括快照版和 beta 版。 @@ -112,7 +109,7 @@ PostgreSQL documentation - 要使用的并发连接和进程/线程数 + 要使用的并发进程或线程数 @@ -206,118 +203,17 @@ PostgreSQL documentation - - - - - 将文件复制到新集簇。这是默认行为。(另见 - 、 - 。) - - - - - - - - 使用 copy_file_range 系统调用进行高效复制。在某些文件系统上, - 这会产生与 类似的结果,即共享物理磁盘块;在另一些文件系统上, - 它仍然会复制块,但会通过优化路径完成。目前,它在 Linux 和 FreeBSD 上受支持。 - - - - - - - - 不要把旧集簇中的统计信息恢复到新集簇中。 - - - - - option - - - 手工设置新集簇默认的 char 有符号性。可选值为 - signedunsigned。 - - - 在 C 语言中,char 类型在未显式指定时的默认有符号性因平台而异。 - 例如,在 x86 CPU 上 char 默认是 signed char, - 而在 ARM CPU 上默认是 unsigned char。 - - - 从 PostgreSQL 18 开始,数据库集簇会维护自身默认的 - char 有符号性设置,可用于确保在默认 char 有符号性不同的平台之间保持一致行为。 - 默认情况下,pg_upgrade 在从现有集簇升级时会保留该有符号性设置。 - 然而,从 PostgreSQL 17 或更早版本升级时, - pg_upgrade 会采用其构建所在平台的 char 有符号性。 - - - 该选项允许你显式设置新集簇默认的 char 有符号性,以覆盖任何继承值。 - 该选项主要适用于以下两种场景: - - - - 如果你计划在升级后迁移到不同平台,则不应使用该选项。在这种情况下,默认行为才是正确的。 - 应当先在原平台上不带此选项完成升级,然后再迁移集簇。这是推荐且最安全的方法。 - - - - - 如果你已经将集簇迁移到了默认 char 有符号性不同的平台上 - (例如从基于 x86 的系统迁移到基于 ARM 的系统),则应使用该选项来指定与原平台 - 默认 char 有符号性相匹配的值。此外,从迁移数据文件到运行 - pg_upgrade 之间,切勿修改任何数据文件。 - pg_upgrade 应当是新平台上首次启动该集簇的操作。 - - - - - - - - - - - 将数据目录从旧集簇移动到新集簇,然后用为新集簇生成的系统目录文件替换原有目录文件。 - 该模式的性能可能优于 、 - ,尤其是在关系很多的集簇上。 - - - 但是,这种模式会在旧集簇中产生大量垃圾文件,如果使用 - ,可能会延长文件同步步骤。因此, - 建议在 模式下使用 。 - - - 此外,一旦文件传输步骤开始,旧集簇就会被破坏性修改,因此不再能安全启动。 - 详见 。 - - - - - method - - - 设置为 fsync(默认)时,pg_upgrade 会递归打开并同步 - 升级后集簇数据目录中的所有文件。查找文件时会跟随 WAL 目录和各个已配置表空间的符号链接。 - - - 在 Linux 上,也可以使用 syncfs,让操作系统同步包含升级后集簇数据目录、 - 其 WAL 文件以及各个表空间的整个文件系统。见 - 了解使用 syncfs - 时需要注意的事项。 - - - 当使用 时,此选项无效。 - - - + + + + + + @@ -338,11 +234,7 @@ PostgreSQL documentation - - 这里不介绍升级 - 逻辑复制集簇 - 的步骤;详见 。 - + @@ -441,18 +333,11 @@ make prefix=/usr/local/pgsql.new install 停止两个服务器 - - 确保两个数据库服务器都已停止,在 Unix 上例如: - - -pg_ctl -D /opt/PostgreSQL/12 stop + 确保两个数据库服务器都已停止。例如,在 Unix 上使用: +pg_ctl -D /opt/PostgreSQL/9.6 stop pg_ctl -D /opt/PostgreSQL/&majorversion; stop - - - 或者在 Windows 上使用合适的服务名: - - -NET STOP postgresql-12 +或者在 Windows 上使用正确的服务名: +NET STOP postgresql-9.6 NET STOP postgresql-&majorversion; @@ -481,7 +366,7 @@ NET STOP postgresql-&majorversion; 始终运行新服务器的 pg_upgrade 二进制,而不是旧服务器的。 pg_upgrade 需要指定新旧集簇的数据目录和可执行文件 (bin)目录。你还可以指定用户和端口值,以及是否希望将数据文件 - 链接、克隆或交换,而不是采用默认的复制行为。 + 链接或克隆,而不是采用默认的复制行为。 @@ -489,37 +374,21 @@ NET STOP postgresql-&majorversion; 新集簇,就无法再访问旧集簇。链接模式还要求新旧集簇的数据目录位于同一文件系统中。 (表空间和 pg_wal 可以位于不同文件系统中。)克隆模式具有相同的 速度和磁盘空间优势,但在启动新集簇后不会使旧集簇不可用。克隆模式同样要求新旧数据目录 - 位于同一文件系统中。该模式只在某些操作系统和文件系统上可用。如果关系很多,交换模式 - 可能最快,但一旦文件传输步骤开始,你将无法再访问旧集簇。交换模式也要求新旧集簇的数据 - 目录位于同一文件系统中。 - - - - 将 设置为 2 或更高可以让 pg_upgrade 并行处理多个数据库和表空间。 - 一个不错的起始值是机器上的 CPU 核心数。对于多数据库、多表空间的服务器,此选项可以显著 - 减少升级时间。 + 位于同一文件系统中。该模式只在某些操作系统和文件系统上可用。 - - 对于 Windows 用户,必须登录到管理员账户,然后以带引号的目录运行 - pg_upgrade,例如: + 选项允许使用多个 CPU 核心复制/链接文件,并行转储和恢复数据库模式;一个不错的起始值是 CPU 核心数与表空间数量中的较大值。对于运行在多处理器机器上的多数据库服务器,此选项可以显著减少升级时间。 - + Windows 用户必须先登录管理员帐号,然后以 postgres 用户身份启动 shell,并设置正确的路径: +RUNAS /USER:postgres "CMD.EXE" +SET PATH=%PATH%;C:\Program Files\PostgreSQL\&majorversion;\bin; +然后运行 pg_upgrade,并用引号括起目录,例如: pg_upgrade.exe - --old-datadir "C:/Program Files/PostgreSQL/12/data" + --old-datadir "C:/Program Files/PostgreSQL/9.6/data" --new-datadir "C:/Program Files/PostgreSQL/&majorversion;/data" - --old-bindir "C:/Program Files/PostgreSQL/12/bin" + --old-bindir "C:/Program Files/PostgreSQL/9.6/bin" --new-bindir "C:/Program Files/PostgreSQL/&majorversion;/bin" - - - 启动后,pg_upgrade 会验证两个集簇是否兼容,然后执行升级。 - 即使旧服务器仍在运行,也可以使用 pg_upgrade --check 仅执行检查。 - pg_upgrade --check 还会概述升级后需要手工进行的调整。如果你打算 - 使用链接、克隆、copy-file-range 或交换模式,则应将 、 - 或 - 一起使用,以启用对应模式的专用检查。 - pg_upgrade 需要对当前目录具有写权限。 - +启动后,pg_upgrade会验证两个集簇是否兼容,然后执行升级。你可以使用 pg_upgrade --check 仅执行检查,即使旧服务器仍在运行。pg_upgrade --check还会概述升级后需要手工进行的调整。如果你打算使用链接或克隆模式,则应将选项 一起使用,以启用对应模式的专用检查。pg_upgrade需要对当前目录具有写权限。 显然,在升级期间不应有人访问这些集簇。pg_upgrade @@ -600,30 +469,12 @@ pg_upgrade.exe 运行 <application>rsync</application> - - 在使用链接模式时,可以通过 rsync 快速升级备库。 - 为此,在主库上选择一个位于新旧数据库集簇目录之上的目录,并在 - 主库上针对每个备库运行: - - + 在使用链接模式时,可以通过 rsync 快速升级备库。为此,在主库上选择一个位于新旧数据库集簇目录之上的目录,并在主库上针对每个备库运行: rsync --archive --delete --hard-links --size-only --no-inc-recursive old_cluster new_cluster remote_dir - - - 其中, 是相对于 - 主库当前目录的路径, 则是备库上位于新旧集簇目录 - 上层的目录。主库和备库在指定目录下的目录结构必须一致。 - 关于如何指定远程目录的细节,请参阅 rsync 手册页,例如: - - -rsync --archive --delete --hard-links --size-only --no-inc-recursive /opt/PostgreSQL/12 \ - /opt/PostgreSQL/&majorversion; standby.example.com:/opt/PostgreSQL - - - 你可以使用 rsync 选项来验证 - 命令将执行什么操作。尽管至少要在主库上为一个备库运行 - rsync,但只要某个已升级的备库尚未启动,也可以在该备库上 - 运行 rsync 来升级其他备库。 - +其中, 是相对于主库当前目录的路径,则是备库上位于新旧集簇目录上层的目录。主库和备库在指定目录下的目录结构必须一致。请参阅 rsync 手册页,了解如何指定远程目录,例如: +rsync --archive --delete --hard-links --size-only --no-inc-recursive /opt/PostgreSQL/9.5 \ + /opt/PostgreSQL/9.6 standby.example.com:/opt/PostgreSQL +你可以使用 rsync 选项来验证命令将执行什么操作。尽管至少要在主库上为一个备库运行 rsync,但也可以运行 rsync 来升级其他备库,运行位置是某个已升级且尚未启动的备库。 其原理是记录主库上新旧集簇文件之间由 pg_upgrade @@ -633,31 +484,16 @@ rsync --archive --delete --hard-links --size-only --no-inc-recursive /opt/Postgr 临时表和不记录 WAL 的表相关的文件,因为这些文件通常不存在于备库上。 - - 如果你有表空间,则需要对每个表空间目录运行类似的 - rsync 命令,例如: - - -rsync --archive --delete --hard-links --size-only --no-inc-recursive /vol1/pg_tblsp/PG_12_201909212 \ - /vol1/pg_tblsp/PG_&majorversion;_202307071 standby.example.com:/vol1/pg_tblsp - - - 如果你把 pg_wal 迁移到了数据目录之外,也必须对这些目录运行 - rsync。 - + 如果你有表空间,则需要对每个表空间目录运行类似的 rsync 命令,例如: +rsync --archive --delete --hard-links --size-only --no-inc-recursive /vol1/pg_tblsp/PG_9.5_201510051 \ + /vol1/pg_tblsp/PG_9.6_201608131 standby.example.com:/vol1/pg_tblsp +如果你把 pg_wal 迁移到了数据目录之外,也必须对这些目录运行 rsync 配置流复制和日志传送备库 - - 为服务器配置日志传送。(由于备库仍与主库保持同步,因此无需运行 - pg_backup_start()pg_backup_stop(), - 也无需进行文件系统备份。)如果旧主库早于 17.0,则主库上的任何槽都不会复制到新备库, - 因此旧备库上的所有槽都必须手工重建。如果旧主库为 17.0 或更高版本, - 则只有主库上的逻辑槽会复制到新备库,而旧备库上的其他槽不会复制, - 因此也必须手工重建。 - + 为服务器配置日志传送。(由于备库仍与主库保持同步,因此无需运行pg_backup_start()pg_backup_stop(),也无需进行文件系统备份。)复制槽不会被复制,必须重建。 @@ -708,28 +544,13 @@ psql --username=postgres --file=script.sql postgres 统计信息 - - 除非指定 pg_upgrade 会将大多数 - 优化器统计信息从旧集簇传输到新集簇。但这不会传输所有统计信息,例如通过 - 显式创建的统计信息、扩展添加的自定义统计信息, - 或由累积统计系统收集的统计信息。 - - - 由于并非所有统计信息都会由 pg_upgrade 传输,升级结束时你会被要求 - 运行命令来重新生成这些信息。你可能需要设置连接参数以匹配新集簇。 - - - 首先,使用 - vacuumdb --all --analyze-in-stages --missing-stats-only - 为尚无统计信息的关系快速生成最基本的优化器统计信息。然后,使用 - vacuumdb --all --analyze-only 以确保所有关系都拥有最新的累积统计信息, - 用于触发 vacuum 和 analyze。对于这两个命令,使用 都可以加快速度。 - 如果 vacuum_cost_delay 被设置为非零值,可以通过 - PGOPTIONS 覆盖它来加快统计信息生成,例如 PGOPTIONS='-c - vacuum_cost_delay=0' vacuumdb ...。 - + + + + + 由于优化器统计信息不会由pg_upgrade传输,升级结束时你会被要求运行命令来重新生成这些信息。你可能需要设置连接参数以匹配新集簇。 @@ -756,10 +577,7 @@ psql --username=postgres --file=script.sql postgres - - 如果既没有使用 ,也没有使用 , - 旧集簇不会被修改;可以重新启动。 - + 如果选项没有被使用,旧集簇就未被修改,可以重新启动。 @@ -794,130 +612,14 @@ psql --username=postgres --file=script.sql postgres - - - 如果使用了 选项,旧集簇可能已经被破坏性修改: - - - - - 如果 pg_upgrade 在报告旧集簇不再能安全启动之前中止, - 则旧集簇没有被修改;可以重新启动。 - - - - - 如果 pg_upgrade 已报告旧集簇不再能安全启动, - 则旧集簇已经被破坏性修改。在这种情况下,旧集簇必须从备份恢复。 - - - - - - - 环境 - - - 一些环境变量可以为命令行选项提供默认值: - - - - PGBINOLD - - - - 旧 PostgreSQL 可执行文件目录;选项 - /。 - - - - - - PGBINNEW - - - - 新 PostgreSQL 可执行文件目录;选项 - /。 - - - - - - PGDATAOLD - - - - 旧数据库集簇配置目录;选项 - /。 - - - - - - PGDATANEW - - - 新数据库集簇配置目录;选项 - /。 - - - - - - PGPORTOLD - - - - 旧集簇端口号;选项 - /。 - - - - - - PGPORTNEW - - - - 新集簇端口号;选项 - /。 - - - - - - PGSOCKETDIR - - - - 升级期间用于 postmaster 套接字的目录;选项 - /。 - - - - - - PGUSER - - - - 集簇安装用户名称;选项 - /。 - - - - - - 注解 diff --git a/zh/15/ref/postgres-ref.sgml b/zh/15/ref/postgres-ref.sgml index b62740d6..4d876ebb 100644 --- a/zh/15/ref/postgres-ref.sgml +++ b/zh/15/ref/postgres-ref.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation postgres 1 - Application + 应用程序 @@ -340,6 +340,13 @@ PostgreSQL documentation + + + + 此选项用于调试导致服务器进程异常终止的问题。在这种情况下,通常的策略是通知所有其他服务器进程必须终止,然后重新初始化共享内存和信号量。这是因为出错的服务器进程可能在终止前破坏了某些共享状态。此选项指定postgres不重新初始化共享数据结构。经验丰富的系统程序员随后可以使用调试器检查共享内存和信号量的状态。 + + + @@ -373,12 +380,7 @@ PostgreSQL documentation - - 该选项用于调试导致服务器 - 进程异常终止的问题。在这种情况下,通常的策略是通过向所有其他服务器进程发送SIGQUIT - 信号,通知它们必须终止。使用此选项时,则会改为发送SIGABRT, - 从而生成核心转储文件。 - + 此选项用于调试导致服务器进程异常终止的问题。在这种情况下,通常的策略是通知所有其他服务器进程必须终止,然后重新初始化共享内存和信号量。这是因为出错的服务器进程可能在终止前破坏了某些共享状态。此选项指定postgres通过发送SIGSTOP信号暂停所有其他服务器进程,但不使它们终止。这允许系统程序员手工收集所有服务器进程的核心转储。 @@ -532,7 +534,7 @@ PostgreSQL documentation - 表明另一台服务器已经在运行的失败消息 + 表明另一个服务器已经在运行的失败消息 应仔细检查,例如可根据你的系统使用下面的命令: $ ps ax | grep postgres @@ -721,7 +723,7 @@ PostgreSQL documentation - 参见 + 另见 , diff --git a/zh/15/ref/postmaster.sgml b/zh/15/ref/postmaster.sgml new file mode 100644 index 00000000..9e210cc1 --- /dev/null +++ b/zh/15/ref/postmaster.sgml @@ -0,0 +1,42 @@ + + + + + postmaster + + + + postmaster + 1 + 应用程序 + + + + postmaster + PostgreSQL数据库服务器 + + + + + postmaster + option + + + + + 描述 + + postmasterpostgres的一个已弃用别名。 + + + + 另见 + + + + + + diff --git a/zh/15/ref/prepare.sgml b/zh/15/ref/prepare.sgml index 6c456821..92ac658a 100644 --- a/zh/15/ref/prepare.sgml +++ b/zh/15/ref/prepare.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation PREPARE 7 - SQL - Language Statements + SQL - 语言语句 @@ -119,7 +119,7 @@ PREPARE name [ ( - 默认情况下,也就是当 设置为 + 默认情况下,也就是当 设置为 auto 时,服务器会自动为带参数的预备语句选择使用通 用计划还是自定义计划。当前规则是:前五次执行使用自定义计划,并计算这些 计划的平均估计代价;然后创建一个通用计划,并将其估计代价与自定义计划的 diff --git a/zh/15/ref/prepare_transaction.sgml b/zh/15/ref/prepare_transaction.sgml index 10d018b0..75776dab 100644 --- a/zh/15/ref/prepare_transaction.sgml +++ b/zh/15/ref/prepare_transaction.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation PREPARE TRANSACTION 7 - SQL - Language Statements + SQL - 语言语句 @@ -72,7 +72,7 @@ PREPARE TRANSACTION transaction_id - 当前不允许将执行过以下任一操作的事务置为预备状态:涉及临时表或会话临时命名空间的操作、创建任何WITH HOLD游标,或执行过LISTENUNLISTENNOTIFY。这些特性与当前会话绑定得过于紧密,因此在要进入预备状态的事务中没有意义。 + 当前不允许对执行过以下任一操作的事务执行PREPARE:涉及临时表或会话临时命名空间的操作、创建任何WITH HOLD游标,或执行过LISTENUNLISTENNOTIFY。这些特性与当前会话绑定得过于紧密,因此在要进入预备状态的事务中没有意义。 diff --git a/zh/15/ref/psql-ref.sgml b/zh/15/ref/psql-ref.sgml index f7651da7..18d7884c 100644 --- a/zh/15/ref/psql-ref.sgml +++ b/zh/15/ref/psql-ref.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation psql 1 - Application + 应用程序 @@ -534,7 +534,7 @@ testdb=> - 如果不可信用户能够访问尚未采用模式的安全使用方式的数据库,请在会话开始时从search_path中移除所有公众可写的 schema。可以在连接字符串中加入options=-csearch_path=,或者在执行其他 SQL 命令之前发出SELECT pg_catalog.set_config('search_path', '', false)。这种考虑并非psql特有;它适用于任何执行任意 SQL 命令的接口。 + 如果不受信任的用户能够访问尚未采用模式的安全使用方式的数据库,请在会话开始时从search_path中移除所有公众可写的模式。可以在连接字符串中加入options=-csearch_path=,或者在执行其他 SQL 命令之前发出SELECT pg_catalog.set_config('search_path', '', false)。这种考虑并非psql特有;它适用于任何执行任意 SQL 命令的接口。 @@ -582,12 +582,9 @@ testdb=> 很多元命令作用在当前查询缓冲区上。这就是一个缓冲区而已,它保存任何已经被键入但是还没有发送到服务器执行的SQL命令文本。这将包括之前输入的行以及在该元命令同一行上出现在前面的任何文本。 - - 许多元命令还允许在命令名后追加 x 作为选项。这会使结果以扩展模式显示,就像使用了 \x\pset expanded 一样。 - - 定义了以下元命令: + 定义了以下元命令: @@ -599,56 +596,7 @@ testdb=> - - \bind [ parameter ] ... - - - - 为下一次查询执行设置查询参数,并将指定参数传给任意参数占位符($1 等)。 - - - - 示例: - -INSERT INTO tbl1 VALUES ($1, $2) \bind 'first value' 'second value' \g - - - - - 这对除 \g 之外的查询执行命令也有效,例如 \gx 和 - \gset。 - - - - 此命令会使用扩展查询协议(参见),不同于psql通常使用的简单查询协议。因此,可以用它在psql中测试扩展查询协议。(即使查询没有参数,而且此命令指定了零个参数,也会使用扩展查询协议。)此命令只影响下一条被执行的查询;之后的所有查询默认仍会使用简单查询协议。 - - - - - \bind_named statement_name [ parameter ] ... - - - - \bind_named 等同于 \bind,不同之处在于它把现有预备语句的名称作为第一个参数。空字符串表示未命名的预备语句。 - - - - 示例: - -INSERT INTO tbls1 VALUES ($1, $2) \parse stmt1 -\bind_named stmt1 'first value' 'second value' \g - - - - - 此命令会使用扩展查询协议(参见 - ),不同于psql通常使用的简单查询协议。因此,可以用它在psql中测试扩展查询协议。 - - - - \c\connect [ -reuse-previous=on|off ] [ dbname [ username ] [ host ] [ port ] | conninfo ] @@ -686,7 +634,7 @@ INSERT INTO tbls1 VALUES ($1, $2) \parse stmt1 - 示例: + 示例: => \c mydb myuser host.dom 6432 @@ -726,28 +674,6 @@ INSERT INTO tbls1 VALUES ($1, $2) \parse stmt1 - - \close_prepared prepared_statement_name - - - - 关闭指定的预备语句。空字符串表示未命名的预备语句。如果不存在该名称的预备语句,则该操作不执行任何操作。 - - - - 示例: - -SELECT $1 \parse stmt1 -\close_prepared stmt1 - - - - - 此命令会使用扩展查询协议,不同于psql通常使用的简单查询协议。因此,可以用它在psql中测试扩展查询协议。 - - - - \conninfo @@ -881,7 +807,7 @@ SELECT $1 \parse stmt1 - \d[Sx+] [ pattern ] + \d[S+] [ pattern ] @@ -914,66 +840,62 @@ SELECT $1 \parse stmt1 它等同于\dtvmsE,它将显示所有可见的表、视图、物化视图、序列和外部表的列表。 这纯粹是一种便利措施。 - - 与许多其他命令一样,如果在命令名后追加 x,结果会以扩展模式显示。但请注意,这只适用于不带 pattern 参数的 \d;并且 x 修饰符不能直接紧跟在 \d 后面(因为 \dx 是另一个命令)。x 只能出现在 S+ 修饰符之后。例如,\d+x 等同于 \dtvmsE+x,并以扩展模式显示所有关系的列表。 - - \da[Sx] [ pattern ] + \da[S] [ pattern ] 列出聚合函数,以及它们的返回类型和所作用的数据类型。如果指定了 pattern,则只显示名称与模式匹配的聚合。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。如果在命令名后追加 x,结果会以扩展模式显示。 - + class="parameter">pattern,则只显示名称与模式匹配的聚合。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。 - \dA[x+] [ pattern ] + \dA[+] [ pattern ] 列出访问方法。如果指定了 pattern,则只显示名称与模式匹配的访问方法。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则每个访问方法都会连同其关联的处理器函数和描述一起列出。 + class="parameter">pattern,则只显示名称与模式匹配的访问方法。如果在命令名后追加 +,则每个访问方法都会连同其关联的处理器函数和描述一起列出。 - \dAc[x+] + \dAc[+] [access-method-pattern [input-type-pattern]] - 列出操作符类(参见 )。如果指定了 access-method-pattern,则只列出与名称匹配该模式的访问方法关联的操作符类。如果指定了 input-type-pattern,则只列出与名称匹配该模式的输入类型关联的操作符类。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则每个操作符类都会连同其关联的操作符族和所有者一起列出。 + 列出操作符类(参见 )。如果指定了 access-method-pattern,则只列出与名称匹配该模式的访问方法关联的操作符类。如果指定了 input-type-pattern,则只列出与名称匹配该模式的输入类型关联的操作符类。如果在命令名后追加 +,则每个操作符类都会连同其关联的操作符族和所有者一起列出。 - \dAf[x+] + \dAf[+] [access-method-pattern [input-type-pattern]] - 列出操作符族(参见 )。如果指定了 access-method-pattern,则只列出与名称匹配该模式的访问方法关联的操作符族。如果指定了 input-type-pattern,则只列出与名称匹配该模式的输入类型关联的操作符族。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则每个操作符族都会连同其所有者一起列出。 + 列出操作符族(参见 )。如果指定了 access-method-pattern,则只列出与名称匹配该模式的访问方法关联的操作符族。如果指定了 input-type-pattern,则只列出与名称匹配该模式的输入类型关联的操作符族。如果在命令名后追加 +,则每个操作符族都会连同其所有者一起列出。 - \dAo[x+] + \dAo[+] [access-method-pattern [operator-family-pattern]] @@ -981,69 +903,69 @@ SELECT $1 \parse stmt1 - 列出与操作符族关联的操作符(参见 )。如果指定了 access-method-pattern,则只列出与名称匹配该模式的访问方法所关联的操作符族成员。如果指定了 operator-family-pattern,则只列出名称与该模式匹配的操作符族成员。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则每个操作符都会连同其排序操作符族(如果它是排序操作符)以及其底层函数是否防漏一起列出。 + 列出与操作符族关联的操作符(参见 )。如果指定了 access-method-pattern,则只列出与名称匹配该模式的访问方法所关联的操作符族成员。如果指定了 operator-family-pattern,则只列出名称与该模式匹配的操作符族成员。如果在命令名后追加 +,则每个操作符都会连同其排序操作符族(如果它是排序操作符)以及其底层函数是否防漏一起列出。 - \dAp[x+] + \dAp[+] [access-method-pattern [operator-family-pattern]] - 列出与操作符族关联的支持函数(参见 )。如果指定了 access-method-pattern,则只列出与名称匹配该模式的访问方法所关联的操作符族函数。如果指定了 operator-family-pattern,则只列出名称与该模式匹配的操作符族函数。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,函数会以详细形式显示,并带有其实际参数列表。 + 列出与操作符族关联的支持函数(参见 )。如果指定了 access-method-pattern,则只列出与名称匹配该模式的访问方法所关联的操作符族函数。如果指定了 operator-family-pattern,则只列出名称与该模式匹配的操作符族函数。如果在命令名后追加 +,函数会以详细形式显示,并带有其实际参数列表。 - \db[x+] [ pattern ] + \db[+] [ pattern ] 列出表空间。如果指定了 pattern,则只显示名称与模式匹配的表空间。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则每个表空间都会连同其关联选项、磁盘大小、权限和描述一起列出。 + class="parameter">pattern,则只显示名称与模式匹配的表空间。如果在命令名后追加 +,则每个表空间都会连同其关联选项、磁盘大小、权限和描述一起列出。 - \dc[Sx+] [ pattern ] + \dc[S+] [ pattern ] - 列出字符集编码之间的转换。如果指定了 pattern,则只列出名称与模式匹配的转换。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则每个对象都会连同其相关描述一起列出。 + 列出字符集编码之间的转换。如果指定了 pattern,则只列出名称与模式匹配的转换。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。如果在命令名后追加 +,则每个对象都会连同其相关描述一起列出。 - \dconfig[x+] [ pattern ] + \dconfig[+] [ pattern ] - 列出服务器配置参数及其值。如果指定了 pattern,则只列出名称与模式匹配的参数。不带 pattern 时,只列出被设置为非默认值的参数。(使用 \dconfig * 可查看所有参数。)如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则每个参数都会连同其数据类型、该参数可设置的上下文以及访问权限(如果已授予非默认访问权限)一起列出。 + 列出服务器配置参数及其值。如果指定了 pattern,则只列出名称与模式匹配的参数。不带 pattern 时,只列出被设置为非默认值的参数。(使用 \dconfig * 可查看所有参数。)如果在命令名后追加 +,则每个参数都会连同其数据类型、该参数可设置的上下文以及访问权限(如果已授予非默认访问权限)一起列出。 - \dC[x+] [ pattern ] + \dC[+] [ pattern ] - 列出类型转换。如果指定了 pattern,则只列出其源类型或目标类型与模式匹配的类型转换。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则会显示每个类型转换的附加信息,包括其底层函数是否防漏,以及该类型转换的描述。 + 列出类型转换。如果指定了 pattern,则只列出其源类型或目标类型与模式匹配的类型转换。如果在命令名后追加 +,则会显示每个类型转换的附加信息,包括其底层函数是否防漏,以及该类型转换的描述。 - \dd[Sx] [ pattern ] + \dd[S] [ pattern ] 显示constraintoperator class、 @@ -1052,8 +974,7 @@ SELECT $1 \parse stmt1 \dd 显示与 - pattern 匹配的对象描述;如果没有给出参数,则显示相应类型的可见对象的描述。但无论哪种情况,只列出那些已有描述的对象。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。如果在命令名后追加 x,结果会以扩展模式显示。 - + pattern 匹配的对象描述;如果没有给出参数,则显示相应类型的可见对象的描述。但无论哪种情况,只列出那些已有描述的对象。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。 可以使用 COMMENT SQL 命令创建对象的描述。 @@ -1063,22 +984,21 @@ SELECT $1 \parse stmt1 - \dD[Sx+] [ pattern ] + \dD[S+] [ pattern ] 列出域。如果指定了 pattern,则只显示名称与模式匹配的域。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则每个对象都会连同其相关权限和描述一起列出。 + class="parameter">pattern,则只显示名称与模式匹配的域。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。如果在命令名后追加 +,则每个对象都会连同其相关权限和描述一起列出。 - \ddp[x] [ pattern ] + \ddp[ pattern ] - 列出默认访问权限设置。对于每个默认权限设置已偏离内置默认值的角色(以及适用时的模式),都会显示一条记录。如果指定了 pattern,则只列出角色名或模式名与模式匹配的记录。如果在命令名后追加 x,结果会以扩展模式显示。 - + 列出默认访问权限设置。对于每个默认权限设置已偏离内置默认值的角色(以及适用时的模式),都会显示一条记录。如果指定了 pattern,则只列出角色名或模式名与模式匹配的记录。 ALTER DEFAULT @@ -1089,51 +1009,51 @@ SELECT $1 \parse stmt1 - \dE[Sx+] [ pattern ] - \di[Sx+] [ pattern ] - \dm[Sx+] [ pattern ] - \ds[Sx+] [ pattern ] - \dt[Sx+] [ pattern ] - \dv[Sx+] [ pattern ] + \dE[S+] [ pattern ] + \di[S+] [ pattern ] + \dm[S+] [ pattern ] + \ds[S+] [ pattern ] + \dt[S+] [ pattern ] + \dv[S+] [ pattern ] 在这组命令中,字母 Eimstv - 分别表示外部表、索引、物化视图、序列、表和视图。你可以按任意顺序指定其中任意一个或多个字母,以获取这些类型对象的列表。例如,\dti 会列出表和索引。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则每个对象都会连同其持久性状态(永久、临时或不记录 WAL)、磁盘上的物理大小以及相关描述(如果有)一起列出。如果指定了 pattern,则只列出名称与模式匹配的对象。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。 + 分别表示外部表、索引、物化视图、序列、表和视图。你可以按任意顺序指定其中任意一个或多个字母,以获取这些类型对象的列表。例如,\dti 会列出表和索引。如果在命令名后追加 +,则每个对象都会连同其持久性状态(永久、临时或不记录 WAL)、磁盘上的物理大小以及相关描述(如果有)一起列出。如果指定了 pattern,则只列出名称与模式匹配的对象。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。 - \des[x+] [ pattern ] + \des[+] [ pattern ] 列出外部服务器(助记符:external - servers)。如果指定了 pattern,则只列出名称与模式匹配的服务器。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则会显示每个服务器的完整描述,包括服务器的访问权限、类型、版本、选项和描述。 + servers)。如果指定了 pattern,则只列出名称与模式匹配的服务器。如果在命令名后追加 +,则会显示每个服务器的完整描述,包括服务器的访问权限、类型、版本、选项和描述。 - \det[x+] [ pattern ] + \det[+] [ pattern ] - 列出外部表(助记符:external tables)。如果指定了 pattern,则只列出表名或模式名与模式匹配的条目。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则还会显示通用选项以及外部表描述。 + 列出外部表(助记符:external tables)。如果指定了 pattern,则只列出表名或模式名与模式匹配的条目。如果在命令名后追加 +,则还会显示通用选项以及外部表描述。 - \deu[x+] [ pattern ] + \deu[+] [ pattern ] 列出用户映射(助记符:external - users)。如果指定了 pattern,则只列出用户名与模式匹配的映射。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则会显示每个映射的附加信息。 + users)。如果指定了 pattern,则只列出用户名与模式匹配的映射。如果在命令名后追加 +,则会显示每个映射的附加信息。 @@ -1146,136 +1066,135 @@ SELECT $1 \parse stmt1 - \dew[x+] [ pattern ] + \dew[+] [ pattern ] 列出外部数据包装器(助记符:external - wrappers)。如果指定了 pattern,则只列出名称与模式匹配的外部数据包装器。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则还会显示外部数据包装器的访问权限、选项和描述。 + wrappers)。如果指定了 pattern,则只列出名称与模式匹配的外部数据包装器。如果在命令名后追加 +,则还会显示外部数据包装器的访问权限、选项和描述。 - \df[anptwSx+] [ pattern [ arg_pattern ... ] ] + \df[anptwS+] [ pattern [ arg_pattern ... ] ] 列出函数,以及它们的结果数据类型、参数数据类型和函数类型,函数类型分为 agg(聚合)、normalproceduretriggerwindow。要只显示特定类型的函数,请在命令后添加相应的字母 anptw。如果指定了 pattern,则只显示名称与模式匹配的函数。任何附加参数都是类型名模式,分别与函数第一、第二等参数的类型名匹配。(匹配到的函数可以比你指定的参数更多;若要防止这种情况,可将破折号 - 写成最后一个 arg_pattern。)默认情况下,只显示用户创建的对象;提供模式或 S - 修饰符可包括系统对象。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则会显示每个函数的附加信息,包括易变性、并行安全性、所有者、安全分类、是否防漏、访问权限、语言、内部名称(仅适用于 C 和 internal 函数)以及描述。特定函数的源代码可通过 \sf 查看。 + 修饰符可包括系统对象。如果在命令名后追加 +,则会显示每个函数的附加信息,包括易变性、并行安全性、所有者、安全分类、是否防漏、访问权限、语言、内部名称(仅适用于 C 和 internal 函数)以及描述。特定函数的源代码可通过 \sf 查看。 - \dF[x+] [ pattern ] + \dF[+] [ pattern ] - 列出文本搜索配置。如果指定了 pattern,则只显示名称与模式匹配的配置。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则会显示每个配置的完整描述,包括底层文本搜索解析器以及每种记号类型对应的词典列表。 + 列出文本搜索配置。如果指定了 pattern,则只显示名称与模式匹配的配置。如果在命令名后追加 +,则会显示每个配置的完整描述,包括底层文本搜索解析器以及每种记号类型对应的词典列表。 - \dFd[x+] [ pattern ] + \dFd[+] [ pattern ] - 列出文本搜索词典。如果指定了 pattern,则只显示名称与模式匹配的词典。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则会显示每个所选词典的附加信息,包括底层文本搜索模板和选项值。 + 列出文本搜索词典。如果指定了 pattern,则只显示名称与模式匹配的词典。如果在命令名后追加 +,则会显示每个所选词典的附加信息,包括底层文本搜索模板和选项值。 - \dFp[x+] [ pattern ] + \dFp[+] [ pattern ] - 列出文本搜索解析器。如果指定了 pattern,则只显示名称与模式匹配的解析器。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则会显示每个解析器的完整描述,包括底层函数和已识别的记号类型列表。 + 列出文本搜索解析器。如果指定了 pattern,则只显示名称与模式匹配的解析器。如果在命令名后追加 +,则会显示每个解析器的完整描述,包括底层函数和已识别的记号类型列表。 - \dFt[x+] [ pattern ] + \dFt[+] [ pattern ] - 列出文本搜索模板。如果指定了 pattern,则只显示名称与模式匹配的模板。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则会显示每个模板的附加信息,包括底层函数名。 + 列出文本搜索模板。如果指定了 pattern,则只显示名称与模式匹配的模板。如果在命令名后追加 +,则会显示每个模板的附加信息,包括底层函数名。 - \dg[Sx+] [ pattern ] + \dg[S+] [ pattern ] 列出数据库角色。(由于 usersgroups 的概念已经统一为 roles,此命令现在等同于 \du。)默认情况下,只显示用户创建的角色;提供 - S 修饰符可包括系统角色。如果指定了 pattern,则只列出名称与模式匹配的角色。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则会显示每个角色的附加信息;目前这会增加每个角色的注释。 + S 修饰符可包括系统角色。如果指定了 pattern,则只列出名称与模式匹配的角色。如果在命令名后追加 +,则会显示每个角色的附加信息;目前这会增加每个角色的注释。 - \dl[x+] + \dl[+] - 这是 \lo_list 的别名,后者会显示大对象列表。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则会列出每个大对象的相关权限(如果有)。 + 这是 \lo_list 的别名,后者会显示大对象列表。如果在命令名后追加 +,则会列出每个大对象的相关权限(如果有)。 - \dL[Sx+] [ pattern ] + \dL[S+] [ pattern ] 列出过程语言。如果指定了 pattern,则只列出名称与模式匹配的语言。默认情况下,只显示用户创建的语言;提供 S 修饰符可包括系统对象。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则每种语言都会连同其调用处理器、验证器、访问权限以及它是否为系统对象一起列出。 + class="parameter">pattern,则只列出名称与模式匹配的语言。默认情况下,只显示用户创建的语言;提供 S 修饰符可包括系统对象。如果在命令名后追加 +,则每种语言都会连同其调用处理器、验证器、访问权限以及它是否为系统对象一起列出。 - \dn[Sx+] [ pattern ] + \dn[S+] [ pattern ] 列出模式(命名空间)。如果指定了 pattern,则只列出名称与模式匹配的模式。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则每个对象都会连同其相关权限和描述(如果有)一起列出。 + class="parameter">pattern
,则只列出名称与模式匹配的模式。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。如果在命令名后追加 +,则每个对象都会连同其相关权限和描述(如果有)一起列出。 - \do[Sx+] [ pattern [ arg_pattern [ arg_pattern ] ] ] + \do[S+] [ pattern [ arg_pattern [ arg_pattern ] ] ] - 列出操作符及其操作数类型和结果类型。如果指定了 pattern,则只列出名称与模式匹配的操作符。如果指定了一个 arg_pattern,则只列出其右参数类型名称与该模式匹配的前缀操作符。如果指定了两个 arg_pattern,则只列出参数类型名称与这些模式匹配的二元操作符。(对于一元操作符未使用的参数,也可以写成 -。)默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则会显示每个操作符的附加信息,包括底层函数名以及它是否防漏。 + 列出操作符及其操作数类型和结果类型。如果指定了 pattern,则只列出名称与模式匹配的操作符。如果指定了一个 arg_pattern,则只列出其右参数类型名称与该模式匹配的前缀操作符。如果指定了两个 arg_pattern,则只列出参数类型名称与这些模式匹配的二元操作符。(对于一元操作符未使用的参数,也可以写成 -。)默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。如果在命令名后追加 +,则会显示每个操作符的附加信息,包括底层函数名以及它是否防漏。 - \dO[Sx+] [ pattern ] + \dO[S+] [ pattern ] - 列出排序规则。如果指定了 pattern,则只列出名称与模式匹配的排序规则。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则每个排序规则都会连同其相关描述(如果有)一起列出。请注意,只会显示与当前数据库编码兼容的排序规则,因此在同一安装中的不同数据库里结果可能不同。 + 列出排序规则。如果指定了 pattern,则只列出名称与模式匹配的排序规则。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。如果在命令名后追加 +,则每个排序规则都会连同其相关描述(如果有)一起列出。请注意,只会显示与当前数据库编码兼容的排序规则,因此在同一安装中的不同数据库里结果可能不同。 - \dp[Sx] [ pattern ] + \dp [ pattern ] - 列出表、视图和序列及其相关访问权限。如果指定了 pattern,则只列出名称与模式匹配的表、视图和序列。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。如果在命令名后追加 x,结果会以扩展模式显示。 - + 列出表、视图和序列及其相关访问权限。如果指定了 pattern,则只列出名称与模式匹配的表、视图和序列。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。 GRANT和 @@ -1288,7 +1207,7 @@ SELECT $1 \parse stmt1 - \dP[itnx+] [ pattern ] + \dP[itn+] [ pattern ] 列出分区关系。 @@ -1305,20 +1224,19 @@ SELECT $1 \parse stmt1 - 如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则还会显示每个关系分区大小的总和以及关系描述。如果 n+ 组合使用,则会显示两个大小:一个包括直接附加的叶分区的总大小,另一个显示包括间接附加子分区在内的所有分区总大小。 +如果在命令名后追加 +,则还会显示每个关系分区大小的总和以及关系描述。如果 n+ 组合使用,则会显示两个大小:一个包括直接附加的叶分区的总大小,另一个显示包括间接附加子分区在内的所有分区总大小。 - \drds[x] [ role-pattern [ database-pattern ] ] + \drds[ role-pattern [ database-pattern ] ] 列出已定义的配置设置。这些设置可以是特定于角色、特定于数据库,或者两者兼有。role-patterndatabase-pattern 分别用于选择要列出的特定角色和数据库。如果省略,或者指定了 - *,则会列出所有设置,包括那些未指定角色或数据库的设置。如果在命令名后追加 x,结果会以扩展模式显示。 - + *,则会列出所有设置,包括那些未指定角色或数据库的设置。 ALTER ROLE和 @@ -1329,75 +1247,60 @@ SELECT $1 \parse stmt1 - - \drg[Sx] [ pattern ] - - - 列出每个被授予角色成员身份的信息,包括被授予的选项(ADMIN、 - INHERIT 和/或 SET)以及授予者。关于角色成员身份,参见 GRANT - 命令。 - - - 默认情况下,只显示授予用户创建角色的成员身份;提供 - S 修饰符可包括系统角色。如果指定了 pattern,则只列出名称与模式匹配的角色。如果在命令名后追加 x,结果会以扩展模式显示。 - - - - \dRp[x+] [ pattern ] + \dRp[+] [ pattern ] - 列出逻辑复制发布。如果指定了 pattern,则只列出名称与模式匹配的发布。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则还会显示与每个发布关联的表和模式。 + 列出逻辑复制发布。如果指定了 pattern,则只列出名称与模式匹配的发布。如果在命令名后追加 +,则还会显示与每个发布关联的表和模式。 - \dRs[x+] [ pattern ] + \dRs[+] [ pattern ] - 列出逻辑复制订阅。如果指定了 pattern,则只列出名称与模式匹配的订阅。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则会显示订阅的其他属性。 + 列出逻辑复制订阅。如果指定了 pattern,则只列出名称与模式匹配的订阅。如果在命令名后追加 +,则会显示订阅的其他属性。 - \dT[Sx+] [ pattern ] + \dT[S+] [ pattern ] - 列出数据类型。如果指定了 pattern,则只列出名称与模式匹配的类型。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则每个类型都会连同其内部名称和大小一起列出;对于 enum 类型,还会显示其允许值以及相关权限。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。 + 列出数据类型。如果指定了 pattern,则只列出名称与模式匹配的类型。如果在命令名后追加 +,则每个类型都会连同其内部名称和大小一起列出;对于 enum 类型,还会显示其允许值以及相关权限。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。 - \du[Sx+] [ pattern ] + \du[S+] [ pattern ] 列出数据库角色。(由于 usersgroups 的概念已经统一为 roles,此命令现在等同于 \dg。)默认情况下,只显示用户创建的角色;提供 - S 修饰符可包括系统角色。如果指定了 pattern,则只列出名称与模式匹配的角色。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则会显示每个角色的附加信息;目前这会增加每个角色的注释。 + S 修饰符可包括系统角色。如果指定了 pattern,则只列出名称与模式匹配的角色。如果在命令名后追加 +,则会显示每个角色的附加信息;目前这会增加每个角色的注释。 - \dx[x+] [ pattern ] + \dx[+] [ pattern ] - 列出已安装的扩展。如果指定了 pattern,则只列出名称与模式匹配的扩展。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则会列出属于每个匹配扩展的全部对象。 + 列出已安装的扩展。如果指定了 pattern,则只列出名称与模式匹配的扩展。如果在命令名后追加 +,则会列出属于每个匹配扩展的全部对象。 - \dX[x] [ pattern ] + \dX[ pattern ] - 列出扩展统计信息。如果指定了 pattern,则只列出名称与模式匹配的扩展统计信息。如果在命令名后追加 x,结果会以扩展模式显示。 - + 列出扩展统计信息。如果指定了 pattern,则只列出名称与模式匹配的扩展统计信息。 每种扩展统计信息的状态显示在以其统计类型命名的列中(例如 Ndistinct)。 @@ -1408,10 +1311,10 @@ SELECT $1 \parse stmt1 - \dy[x+] [ pattern ] + \dy[+] [ pattern ] - 列出事件触发器。如果指定了 pattern,则只列出名称与模式匹配的事件触发器。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则每个对象都会连同其相关描述一起列出。 + 列出事件触发器。如果指定了 pattern,则只列出名称与模式匹配的事件触发器。如果在命令名后追加 +,则每个对象都会连同其相关描述一起列出。 @@ -1658,11 +1561,7 @@ CREATE INDEX - 生成的查询按照返回的行的顺序执行,并在每行内从左到右执行,如果有多个列。NULL字段将被忽略。生成的查询文字 - 直接发送到服务器进行处理,因此它们不能是psql元命令,也不能包含psql - 变量引用。如果任何单个查询失败,剩余查询的执行将继续,除非设置了ON_ERROR_STOP。每个查询的执行 - 都受ECHO处理的影响。(通常在使用\gexec时,将ECHO设置为 - allqueries是明智的。)查询记录、单步模式、计时和其他查询执行功能也适用于每个生成的查询。 + 生成的查询按照返回行的顺序执行;如果有多列,则在每行内从左到右执行。NULL 字段会被忽略。生成的查询按原样发送到服务器进行处理,因此不能是psql元命令,也不能包含psql变量引用。如果某个查询失败,仍会继续执行其余查询,除非设置了ON_ERROR_STOP。每个查询的执行都受ECHO处理的影响。(通常,在使用\gexec时,适宜将ECHO设为allqueries。)查询日志、单步模式、计时及其他查询执行功能也适用于每个生成的查询。 如果当前查询缓冲区为空,则重新执行最近发送的查询。 @@ -1868,10 +1767,10 @@ SELECT - \l[x+] or \list[x+] [ pattern ] + \l[+] or \list[+] [ pattern ] - 列出服务器中的数据库,并显示其名称、所有者、字符集编码和访问权限。如果指定了 pattern,则只列出名称与模式匹配的数据库。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则还会显示数据库大小、默认表空间和描述。当前用户对其拥有 CONNECT 权限的数据库可以显示大小信息;如果当前用户是超级用户或具有 pg_read_all_stats 角色的权限,也可以显示大小信息。 + 列出服务器中的数据库,并显示其名称、所有者、字符集编码和访问权限。如果指定了 pattern,则只列出名称与模式匹配的数据库。如果在命令名后追加 +,则还会显示数据库大小、默认表空间和描述。当前用户对其拥有 CONNECT 权限的数据库可以显示大小信息;如果当前用户是超级用户或具有 pg_read_all_stats 角色的权限,也可以显示大小信息。 @@ -1902,7 +1801,7 @@ SELECT - 将文件存储到一个PostgreSQL大对象中。可选地,它将给定的注释与对象关联起来。例如: + 将文件存储到一个PostgreSQL大对象中。可选地,它将给定的注释与对象关联起来。例如: foo=> \lo_import '/home/peter/pictures/photo.xcf' 'a picture of me' lo_import 152801 @@ -1917,11 +1816,11 @@ lo_import 152801 - \lo_list[x+] + \lo_list[+] 显示当前存储在数据库中的全部 PostgreSQL - 大对象列表,以及为它们提供的任何注释。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则会列出每个大对象的相关权限(如果有)。 + 大对象列表,以及为它们提供的任何注释。如果在命令名后追加 +,则会列出每个大对象的相关权限(如果有)。 @@ -1981,28 +1880,6 @@ lo_import 152801 - - \parse statement_name - - - 基于目标预备语句对象的名称,从当前查询缓冲区创建一个预备语句。空字符串表示未命名的预备语句。 - - - - 示例: - -SELECT $1 \parse stmt1 - - - - - 此命令会使用扩展查询协议,不同于psql通常使用的简单查询协议。该命令会发出一条 - - 消息,因此可用于在psql中测试扩展查询协议。此命令只影响下一条被执行的查询;之后的所有查询默认仍会使用简单查询协议。 - - - - \password [ username ] @@ -2048,7 +1925,7 @@ SELECT $1 \parse stmt1 - 可调整打印选项有: + 可调整打印选项有: border @@ -2148,7 +2025,7 @@ SELECT $1 \parse stmt1 允许使用唯一缩写。 - aligned格式是标准的、人类可读的、格式良好的文本输出;这是默认设置。 + aligned格式是标准的、适合人阅读且排版整齐的文本输出;这是默认格式。 unaligned格式将一行中的所有列写在一行上,由当前活动的字段分隔符分隔。这对于创建可能被其他程序读取的输出很有用,例如,制表符分隔或逗号分隔格式。然而,如果字段分隔符字符出现在列的值中,则不会被特殊处理;因此,CSV格式可能更适合这些目的。 @@ -2565,61 +2442,6 @@ testdb=> \setenv LESS -imx4F - - \startpipeline - \sendpipeline - \syncpipeline - \endpipeline - \flushrequest - \flush - \getresults [ number_results ] - - - - 这组命令实现 SQL 语句的管道化。一个管道必须以 \startpipeline 开始,并以 \endpipeline 结束。其间可以出现任意数量的 \syncpipeline 命令,它会发送一条同步消息,但不会结束当前管道,并会刷新发送缓冲区。在管道模式下,语句会被发送到服务器,而不等待前面语句的结果。更多细节见 。 - - - - 管道进行期间执行的所有查询都使用扩展查询协议。以分号结束的查询会被追加到管道中。元命令 \bind、 - \bind_named\close_prepared 和 - \parse 可以在进行中的管道里使用。管道进行期间,\sendpipeline 会将当前查询缓冲区追加到管道中。其他元命令,如 - \g\gx 或 - \gdesc,则不允许在管道模式中使用。 - - - - \flushrequest 会向管道追加一条 flush 命令,使得可以在不发送 sync 或结束管道的情况下通过 - \getresults 读取结果。\getresults 会自动将尚未发送的数据推送到服务器。\flush 可用于手动推送未发送的数据。 - - - - \getresults 接受一个可选的 - number_results 参数。如果提供,则只读取前 - number_results 个待处理结果。若省略该参数或其值为 0,则读取所有待处理结果。 - - - - 当管道模式处于活动状态时,可使用一个专用的提示符变量来报告管道状态。详见 。 - - - - COPY 在管道模式中不支持。 - - - - 示例: - -\startpipeline -SELECT * FROM pg_class; -SELECT 1 \bind \sendpipeline -\flushrequest -\getresults -\endpipeline - - - - - @@ -2718,12 +2540,10 @@ SELECT 1 \bind \sendpipeline - \watch [ i[nterval]=seconds ] [ c[ount]=times ] [ m[in_rows]=rows ] [ seconds ] + \watch [ seconds ] - 重复执行当前查询缓冲区(如同 \g 一样),直到被中断、查询失败、达到执行次数上限(如果给定)或查询返回的行数低于最小要求。两次执行之间等待指定的秒数(默认 2 秒)。默认等待时间可通过变量 - 修改。为保持向后兼容, - seconds 可以带或不带 interval= 前缀。每次查询结果都会带有一个头部,其中包含 \pset title + 重复执行当前查询缓冲区(如同 \g 一样),直到被中断或查询失败。两次执行之间等待指定的秒数(默认 2 秒)。每次查询结果都会带有一个头部,其中包含 \pset title 字符串(如果有)、查询开始时的时间以及延迟间隔。 @@ -2744,11 +2564,10 @@ SELECT 1 \bind \sendpipeline - \z[Sx] [ pattern ] + \z [ pattern ] - 列出表、视图和序列及其相关访问权限。如果指定了 pattern,则只列出名称与模式匹配的表、视图和序列。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。如果在命令名后追加 x,结果会以扩展模式显示。 - + 列出表、视图和序列及其相关访问权限。如果指定了 pattern,则只列出名称与模式匹配的表、视图和序列。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。 这是\dp的别名(显示权限)。 @@ -3126,34 +2945,8 @@ bar - - PIPELINE_COMMAND_COUNT - - - 正在运行的管道中排队的命令数 。 - - - - - PIPELINE_RESULT_COUNT - - - 正在进行的管道中,有多少条命令后面跟着 \flushrequest 或 - \syncpipeline,从而强制服务器发送结果。这些结果可以通过 - \getresults 取回。 - - - - - PIPELINE_SYNC_COUNT - - - 正在运行的管道中排队的同步消息数量 。 - - - PORT @@ -3203,38 +2996,8 @@ bar - - SERVICE - - - 服务名称(如果适用)。 - - - - - SHELL_ERROR - - - 如果最后一个 shell 命令失败,则为 true;如果成功,则为 false。这适用于通过 \!、 - \g\o\w - 和 \copy 元命令调用的 shell 命令,也适用于反引号(`)展开。请注意,对于 \o,该变量会在下一个 \o 命令关闭输出管道时更新。 - 另见 SHELL_EXIT_CODE。 - - - - - SHELL_EXIT_CODE - - - 最后一个 shell 命令返回的退出状态。0–127 表示程序退出码,128–255 表示因信号而终止,-1 表示未能启动程序或未能取得其退出状态。这适用于通过 \!、 - \g\o\w - 和 \copy 元命令调用的 shell 命令,也适用于反引号(`)展开。请注意,对于 \o,该变量会在下一个 \o 命令关闭输出管道时更新。 - 另见 SHELL_ERROR。 - - - SHOW_ALL_RESULTS @@ -3312,14 +3075,6 @@ bar - - WATCH_INTERVAL - - - 此变量设置\watch在两次执行查询之间等待的默认间隔,单位为秒。默认值为 2 秒。若在命令中指定了间隔,则会覆盖此变量。 - - - @@ -3329,7 +3084,7 @@ bar <acronym>SQL</acronym> 中插入变量 - psql变量的一个关键特性是可以把它们替换(插入)到常规SQL语句中,也可以把它们作为元命令的参数。此外,psql还提供了功能来确保被用作 SQL 文字和标识符的变量值会被正确地引用。插入一个值而不需要加引用的语法是在变量名前面加上一个冒号(:)。例如, + psql变量的一个关键特性是可以把它们替换(插入)到常规SQL语句中,也可以把它们作为元命令的参数。此外,psql还提供了功能来确保被用作 SQL 字面量和标识符的变量值会被正确地加引号。插入一个值而不加引号的语法是在变量名前面加上一个冒号(:)。例如, testdb=> \set foo 'my_table' testdb=> SELECT * FROM :foo; @@ -3416,10 +3171,6 @@ testdb=> INSERT INTO my_table VALUES (:'content'); - - %s - 服务名称。 - %/ @@ -3450,16 +3201,6 @@ testdb=> INSERT INTO my_table VALUES (:'content'); - - %P - - - 管道状态:不在管道中时为 off, - 在进行中的管道中时为 on, - 在已中止的管道中时为 abort。 - - - %R @@ -3989,28 +3730,6 @@ testdb=> \df int*pl * bigint - - 这里,+ 选项用于显示其中一个函数的附加信息,而 x 用于以扩展模式显示结果: - -testdb=> \df+x int*pl integer bigint -List of functions --[ RECORD 1 ]-------+----------------------------- -Schema | pg_catalog -Name | int48pl -Result data type | bigint -Argument data types | integer, bigint -Type | func -Volatility | immutable -Parallel | safe -Owner | postgres -Security | invoker -Leakproof? | no -Access privileges | -Language | internal -Internal name | int48pl -Description | implementation of + operator - - 在适合的情况下,可以使用 \crosstabview 命令将查询结果显示为交叉表: diff --git a/zh/15/ref/reassign_owned.sgml b/zh/15/ref/reassign_owned.sgml index 824834b8..ba7d9f7b 100644 --- a/zh/15/ref/reassign_owned.sgml +++ b/zh/15/ref/reassign_owned.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation REASSIGN OWNED 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/refresh_materialized_view.sgml b/zh/15/ref/refresh_materialized_view.sgml index 2ccb7ac0..7d0fed7a 100644 --- a/zh/15/ref/refresh_materialized_view.sgml +++ b/zh/15/ref/refresh_materialized_view.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation REFRESH MATERIALIZED VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/reindex.sgml b/zh/15/ref/reindex.sgml index 43065194..a254b41b 100644 --- a/zh/15/ref/reindex.sgml +++ b/zh/15/ref/reindex.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation REINDEX 7 - SQL - Language Statements + SQL - 语言语句 @@ -23,8 +23,7 @@ PostgreSQL documentation -REINDEX [ ( option [, ...] ) ] { INDEX | TABLE | SCHEMA } [ CONCURRENTLY ] name -REINDEX [ ( option [, ...] ) ] { DATABASE | SYSTEM } [ CONCURRENTLY ] [ name ] +REINDEX [ ( option [, ...] ) ] { INDEX | TABLE | SCHEMA | DATABASE | SYSTEM } [ CONCURRENTLY ] name 其中 option 可以是以下之一: @@ -125,8 +124,8 @@ REINDEX [ ( option [, ...] ) ] { DA - 重新创建当前数据库中除系统目录外的所有索引。 - 系统目录上的索引不会被处理。这种形式的REINDEX不能 + 重新创建当前数据库中的所有索引。 + 共享系统目录上的索引也会被处理。这种形式的REINDEX不能 在事务块内执行。 @@ -151,8 +150,7 @@ REINDEX [ ( option [, ...] ) ] { DA 要重新索引的特定索引、表或数据库的名称。索引名和表名可以带模式限 定。目前,REINDEX DATABASE和 - REINDEX SYSTEM只能对当前数据库重新索引。它们的参 - 数是可选的,但如果给出,就必须与当前数据库名匹配。 + REINDEX SYSTEM只能对当前数据库重新索引,所以其参数必须与当前数据库名匹配。 @@ -188,10 +186,7 @@ REINDEX [ ( option [, ...] ) ] { DA VERBOSE - - - 在每个索引被重建时,以 INFO 级别打印进度报告。 - + 在每个索引被重建时打印进度报告。 @@ -276,23 +271,13 @@ REINDEX [ ( option [, ...] ) ] { DA - 在REINDEX运行期间,会临时改为pg_catalog, - pg_temp。 - - - - 对单个索引或表重新索引,需要是该索引或该表的拥有者。对模式或数据库重 - 新索引,则需要是该模式或数据库的拥有者。要特别注意的是,这意味着非超 - 级用户也可能重建其他用户所拥有表的索引。 - - - - 不过,作为一个特殊例外,当非超级用户执行 - REINDEX DATABASEREINDEX SCHEMA - 或 REINDEX SYSTEM 时,会跳过共享系统目录上的索 - 引,除非该用户拥有相应目录对象(通常并不是这种情况)。当然,超级用户 - 始终可以重新索引任何对象。 + 对单个索引或表重新索引,要求用户是该索引或表的拥有者。对模式或数据库 + 重新索引,则要求用户是该模式或数据库的拥有者。特别要注意,这意味着 + 非超级用户也可能重建其他用户拥有的表的索引。不过,作为一个特殊例外, + 当非超级用户执行REINDEX DATABASE、 + REINDEX SCHEMAREINDEX SYSTEM + 时,除非该用户拥有共享系统目录(而这通常并非如此),否则会跳过共享 + 系统目录上的索引。当然,超级用户始终可以重新索引任何对象。 @@ -305,7 +290,7 @@ REINDEX [ ( option [, ...] ) ] { DA 当对分区索引或分区表执行带TABLESPACE子句的 REINDEX时,只有叶分区的表空间引用会被更新。由于 - 分区索引本身不会更新,建议另外对相应的分区表单独执行 + 分区索引本身不会更新,建议另外对这些分区索引单独执行 ALTER TABLE ONLY,以便后续附加的任何新分区都继承 新表空间。如果命令失败,可能不会把所有索引都移动到新表空间。重新运行 该命令将重建所有叶分区,并把先前未处理的索引移动到新表空间。 @@ -323,8 +308,8 @@ REINDEX [ ( option [, ...] ) ] { DA 并发重建索引 - index - rebuilding concurrently + 索引 + 并发重建 diff --git a/zh/15/ref/reindexdb.sgml b/zh/15/ref/reindexdb.sgml index 20dc32bf..c9d7bfeb 100644 --- a/zh/15/ref/reindexdb.sgml +++ b/zh/15/ref/reindexdb.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation reindexdb 1 - Application + 应用程序 @@ -55,22 +55,30 @@ PostgreSQL documentation - - - - - - - - + dbname + - - - dbname - - - - + + reindexdb + connection-option + option + + + + + + + + + reindexdb + connection-option + option + + + + + + dbname @@ -162,9 +170,7 @@ PostgreSQL documentation reindexdb将打开njobs个到数据库的连接,因此请确保设置足够高,能容纳所有连接。 - - 注意,该选项与选项不兼容。 - + 注意,该选项与 选项不兼容。 @@ -373,6 +379,12 @@ PostgreSQL documentation + + 注解 + + reindexdb 可能需要多次连接到 PostgreSQL 服务器,每次都要求输入密码。在这种情况下,使用 ~/.pgpass 文件会很方便。更多信息见 + + 示例 diff --git a/zh/15/ref/release_savepoint.sgml b/zh/15/ref/release_savepoint.sgml index 59f96e68..30956601 100644 --- a/zh/15/ref/release_savepoint.sgml +++ b/zh/15/ref/release_savepoint.sgml @@ -10,18 +10,18 @@ PostgreSQL documentation 保存点 - releasing + 释放 RELEASE SAVEPOINT 7 - SQL - Language Statements + SQL - 语言语句 RELEASE SAVEPOINT - 释放一个先前定义的保存点 + 销毁一个先前定义的保存点 @@ -33,11 +33,11 @@ RELEASE [ SAVEPOINT ] savepoint_name 描述 - - RELEASE SAVEPOINT释放指定名称的保存点,以及在该保存点之后创建且仍处于活动状态的所有保存点,并释放它们占用的资源。 - 自该保存点创建以来所做、且之前尚未被回滚的所有更改,都会并入在创建该保存点时处于活动状态的事务或保存点中。 - 在RELEASE SAVEPOINT之后所做的更改,也将成为该活动事务或保存点的一部分。 - + RELEASE SAVEPOINT 销毁先前在当前事务中定义的保存点。 + + 销毁保存点后,就不能再将它用作回滚点,但除此之外没有其他用户可见的行为。它不会撤销保存点建立之后执行的命令的效果。(要这样做,请参见 。)在不再需要保存点时将其销毁,可以让系统在事务结束之前回收一些资源。 + + RELEASE SAVEPOINT 还会销毁在指定保存点建立之后建立的所有保存点。 @@ -48,7 +48,7 @@ RELEASE [ SAVEPOINT ] savepoint_name savepoint_name - 要释放的保存点名称。 + 要销毁的保存点名称。 @@ -62,9 +62,7 @@ RELEASE [ SAVEPOINT ] savepoint_name 指定一个此前未定义的保存点名称是一种错误。 - - 当事务处于已中止状态时,不能释放保存点;要这样做,请使用。 - + 当事务处于已中止状态时,不能释放保存点。 如果有多个保存点使用相同名称,则只会释放最近定义且尚未释放的那个。 @@ -77,7 +75,7 @@ RELEASE [ SAVEPOINT ] savepoint_name 示例 - 建立并随后释放一个保存点: + 要建立保存点,并在稍后销毁它: BEGIN; INSERT INTO table1 VALUES (3); @@ -86,32 +84,7 @@ BEGIN; RELEASE SAVEPOINT my_savepoint; COMMIT; - 上面的事务将插入 3 和 4。 - - - - 一个包含多个嵌套子事务的更复杂示例: - -BEGIN; - INSERT INTO table1 VALUES (1); - SAVEPOINT sp1; - INSERT INTO table1 VALUES (2); - SAVEPOINT sp2; - INSERT INTO table1 VALUES (3); - RELEASE SAVEPOINT sp2; - INSERT INTO table1 VALUES (4))); -- generates an error - - 在这个例子中,应用程序请求释放保存点sp2,值 3 是在其中插入的。 - 这样会把该插入操作的事务上下文改为sp1。 - 当试图插入值 4 的语句产生错误时,2 和 4 的插入都会丢失,因为它们位于同一个随后被回滚的保存点中, - 而值 3 现在也位于同一事务上下文中,因此同样会丢失。 - 由于此后所有其他命令都会被忽略,应用程序现在只能在以下两个命令中选择一个: - -ROLLBACK; -ROLLBACK TO SAVEPOINT sp1; - - 选择ROLLBACK将中止所有内容,包括值 1; - 而ROLLBACK TO SAVEPOINT sp1会保留值 1,并允许事务继续。 + 上述事务将同时插入 3 和 4。 diff --git a/zh/15/ref/reset.sgml b/zh/15/ref/reset.sgml index e8aeae8c..5e249ff9 100644 --- a/zh/15/ref/reset.sgml +++ b/zh/15/ref/reset.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation RESET 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/revoke.sgml b/zh/15/ref/revoke.sgml index 8d7945a5..79a8e0ec 100644 --- a/zh/15/ref/revoke.sgml +++ b/zh/15/ref/revoke.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation REVOKE 7 - SQL - Language Statements + SQL - 语言语句 @@ -23,7 +23,7 @@ PostgreSQL documentation REVOKE [ GRANT OPTION FOR ] - { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER | MAINTAIN } + { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER } [, ...] | ALL [ PRIVILEGES ] } ON { [ TABLE ] table_name [, ...] | ALL TABLES IN SCHEMA schema_name [, ...] } @@ -126,12 +126,12 @@ REVOKE [ GRANT OPTION FOR ] [ GRANTED BY role_specification ] [ CASCADE | RESTRICT ] -REVOKE [ { ADMIN | INHERIT | SET } OPTION FOR ] +REVOKE [ ADMIN OPTION FOR ] role_name [, ...] FROM role_specification [, ...] [ GRANTED BY role_specification ] [ CASCADE | RESTRICT ] -where role_specification can be: +其中role_specification可以是: [ GROUP ] role_name | PUBLIC @@ -186,21 +186,9 @@ REVOKE [ { ADMIN | INHERIT | SET } OPTION FOR ] 权限不会产生任何效果。 - - 在撤销角色成员资格时,GRANT OPTION 改称为 - ADMIN OPTION,但行为类似。请注意,在 - PostgreSQL 16 之前的版本中,系统不会跟踪 - 角色成员资格授权所产生的依赖权限,因此 CASCADE 对 - 角色成员资格没有效果。现在情况已不再如此。另请注意,这种形式的命令不允许在 - role_specification - 中使用噪声词 GROUP。 - + 在撤销角色成员资格时,GRANT OPTION 改称为 ADMIN OPTION,但行为类似。这种形式的命令还允许使用 GRANTED BY 选项,但目前会忽略该选项(只检查所指定角色是否存在)。另请注意,这种形式的命令不允许把噪声词 GROUP 写在 role_specification 中。 + - - 正如可以从现有角色成员资格授权中移除 ADMIN OPTION 一样, - 也可以撤销 INHERIT OPTIONSET OPTION。 - 这等价于将相应选项的值设为 FALSE。 - @@ -228,9 +216,7 @@ REVOKE [ { ADMIN | INHERIT | SET } OPTION FOR ] 如果超级用户选择执行 GRANTREVOKE - 命令,则该命令会像由受影响对象的拥有者发出那样执行。(由于角色没有 - 拥有者,在 GRANT 角色成员资格时,该命令会像由引导 - 超级用户发出那样执行。)由于所有权限最终都来自对象拥有者 + 命令,则该命令会像由受影响对象的拥有者发出那样执行。由于所有权限最终都来自对象拥有者 (可能经由授予选项链间接传递),超级用户可以撤销所有权限,但如上所述, 这可能需要使用 CASCADE diff --git a/zh/15/ref/rollback.sgml b/zh/15/ref/rollback.sgml index d1c8fdd2..17b9c070 100644 --- a/zh/15/ref/rollback.sgml +++ b/zh/15/ref/rollback.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ROLLBACK 7 - SQL - Language Statements + SQL - 语言语句 @@ -37,7 +37,7 @@ ROLLBACK [ WORK | TRANSACTION ] [ AND [ NO ] CHAIN ] 参数 - chained transactions + 链式事务 @@ -55,7 +55,7 @@ ROLLBACK [ WORK | TRANSACTION ] [ AND [ NO ] CHAIN ] AND CHAIN - 如果指定了AND CHAIN,则会立即启动一个新的(未中止的)事务, + 如果指定了AND CHAIN,则会立即启动一个新事务, 其事务特征与刚刚结束的事务相同(参见)。 否则,不会启动任何新事务。 diff --git a/zh/15/ref/rollback_prepared.sgml b/zh/15/ref/rollback_prepared.sgml index 7ffe1af8..7438d9cc 100644 --- a/zh/15/ref/rollback_prepared.sgml +++ b/zh/15/ref/rollback_prepared.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ROLLBACK PREPARED 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/rollback_to.sgml b/zh/15/ref/rollback_to.sgml index 843a612e..e3f305b7 100644 --- a/zh/15/ref/rollback_to.sgml +++ b/zh/15/ref/rollback_to.sgml @@ -10,13 +10,13 @@ PostgreSQL documentation 保存点 - rolling back + 回滚 ROLLBACK TO SAVEPOINT 7 - SQL - Language Statements + SQL - 语言语句 @@ -34,8 +34,7 @@ ROLLBACK [ WORK | TRANSACTION ] TO [ SAVEPOINT ] savepoint_name描述 - 回滚该保存点建立后执行的所有命令,然后在同一事务层级启动一个新的 - 子事务。该保存点仍然有效,如有需要,之后还可以再次回滚到它。 + 回滚该保存点建立后执行的所有命令。该保存点仍然有效,如有需要,之后还可以再次回滚到它。 @@ -73,8 +72,8 @@ ROLLBACK [ WORK | TRANSACTION ] TO [ SAVEPOINT ] savepoint_name 就保存点而言,游标带有一些非事务性的行为。凡是在某个保存点内打开的游标, 在回滚该保存点时都会被关闭。如果先前打开的游标在某个随后又被回滚的保存点内受到了 - FETCHMOVE命令的影响,那么该游标会保留在这些命令使其指向的位置上 - (也就是说,由FETCHMOVE引起的游标移动不会被回滚)。 + FETCHMOVE命令的影响,那么该游标会保留在FETCH使其指向的位置上 + (也就是说,由FETCH引起的游标移动不会被回滚)。 关闭游标同样不会因回滚而撤销。不过,如果游标查询导致了其他副作用(例如该查询调用的 易变函数带来的副作用),且这些副作用发生在后来被回滚的保存点期间,那么它们 被回滚。如果某个游标的执行导致事务中止,该游标会进入不可执行状态, diff --git a/zh/15/ref/savepoint.sgml b/zh/15/ref/savepoint.sgml index fdca4151..5f9bea25 100644 --- a/zh/15/ref/savepoint.sgml +++ b/zh/15/ref/savepoint.sgml @@ -10,13 +10,13 @@ PostgreSQL documentation 保存点 - defining + 定义 SAVEPOINT 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/security_label.sgml b/zh/15/ref/security_label.sgml index fc969a4a..9c2b13d0 100644 --- a/zh/15/ref/security_label.sgml +++ b/zh/15/ref/security_label.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SECURITY LABEL 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/select.sgml b/zh/15/ref/select.sgml index 1b47aa6d..19abe844 100644 --- a/zh/15/ref/select.sgml +++ b/zh/15/ref/select.sgml @@ -21,7 +21,7 @@ PostgreSQL documentation SELECT 7 - SQL - Language Statements + SQL - 语言语句 @@ -1485,7 +1485,7 @@ SELECT * FROM (SELECT * FROM mytable FOR UPDATE) ss ORDER BY column1; REPEATABLE READSERIALIZABLE事务隔离级别下, - 这将导致序列化失败(带有SQLSTATE'40001'), + 这将导致串行化失败(SQLSTATE'40001'), 因此在这些隔离级别下不可能接收到无序的行。 diff --git a/zh/15/ref/select_into.sgml b/zh/15/ref/select_into.sgml index a05e57e8..12a48774 100644 --- a/zh/15/ref/select_into.sgml +++ b/zh/15/ref/select_into.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SELECT INTO 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/set.sgml b/zh/15/ref/set.sgml index ab67075e..9702d560 100644 --- a/zh/15/ref/set.sgml +++ b/zh/15/ref/set.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SET 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/set_constraints.sgml b/zh/15/ref/set_constraints.sgml index 53d0c7a0..e5588db7 100644 --- a/zh/15/ref/set_constraints.sgml +++ b/zh/15/ref/set_constraints.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SET CONSTRAINTS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/set_role.sgml b/zh/15/ref/set_role.sgml index ed65dec8..f9139dbc 100644 --- a/zh/15/ref/set_role.sgml +++ b/zh/15/ref/set_role.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SET ROLE 7 - SQL - Language Statements + SQL - 语言语句 @@ -30,23 +30,9 @@ RESET ROLE 描述 - - 这个命令将当前 SQL 会话的当前用户标识符设置为 - role_name。 - 角色名既可以写成标识符,也可以写成字符串字面量。 - 执行SET ROLE之后,对 SQL 命令的权限检查会按照 - 最初登录的就是该角色那样进行。注意, - SET ROLE和 - SET SESSION AUTHORIZATION是例外:对这两个命令的权限检查, - 分别仍然使用当前会话用户和初始会话用户(即已认证用户)。 - + 该命令把当前 SQL 会话的当前用户标识符设置为 role_name。角色名可以写成标识符或字符串字面量。在 SET ROLE 之后,SQL 命令的权限检查会视同指定角色是最初登录的角色。 - - 当前会话用户必须对指定的 - role_name拥有SET选项, - 这可以是直接拥有,也可以通过带有SET选项的成员关系链间接拥有。 - (如果会话用户是超级用户,则可以选择任意角色。) - + 当前会话用户必须是指定的 role_name 角色的成员。(如果会话用户是超级用户,则可以选择任意角色。) SESSIONLOCAL修饰符的作用与常规的 @@ -68,18 +54,9 @@ RESET ROLE 注解 - - 使用这个命令,既可以增加权限,也可以限制自己的权限。 - 如果会话用户角色获得的是WITH INHERIT TRUE的成员关系, - 它会自动拥有每个此类角色的全部权限。在这种情况下, - SET ROLE实际上会去掉除目标角色直接拥有或继承而来的权限之外的所有权限。 - 另一方面,如果会话用户角色获得的是WITH INHERIT FALSE的成员关系, - 默认就不能使用被授予角色的权限。但是,如果该角色是以 - WITH SET TRUE授予的,则会话用户可以使用 - SET ROLE放弃直接分配给自己的权限,转而获得该角色可用的权限。 - 如果该角色是以WITH INHERIT FALSE, SET FALSE授予的, - 那么无论是否使用SET ROLE,该角色的权限都无法行使。 - + 使用这个命令,既可以增加权限,也可以限制自己的权限。如果会话用户角色具有 INHERIT 属性,它会自动拥有每个可通过 SET ROLE 切换到的角色的全部权限;在这种情况下,SET ROLE 实际上会去掉直接分配给会话用户及其所属其他角色的全部权限,只保留指定角色可用的权限。另一方面,如果会话用户角色具有 NOINHERIT 属性,SET ROLE 会放弃直接分配给会话用户的权限,转而获得指定角色可用的权限。 + + 特别是,当超级用户选择通过 SET ROLE 切换到非超级用户角色时,会失去其超级用户权限。 SET ROLE的效果与 diff --git a/zh/15/ref/set_session_auth.sgml b/zh/15/ref/set_session_auth.sgml index e520dd49..9ec07ce6 100644 --- a/zh/15/ref/set_session_auth.sgml +++ b/zh/15/ref/set_session_auth.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SET SESSION AUTHORIZATION 7 - SQL - Language Statements + SQL - 语言语句 @@ -46,7 +46,7 @@ RESET SESSION AUTHORIZATION - 只有当初始会话用户(即已认证用户)具有超级用户权限时, + 只有当初始会话用户(即已认证用户)最初具有超级用户权限时, 才能更改会话用户标识符。否则,只有当该命令指定的是已认证用户名时, 才会被接受。 diff --git a/zh/15/ref/set_transaction.sgml b/zh/15/ref/set_transaction.sgml index ca7f3e50..8b3470a9 100644 --- a/zh/15/ref/set_transaction.sgml +++ b/zh/15/ref/set_transaction.sgml @@ -26,7 +26,7 @@ PostgreSQL documentation SET TRANSACTION 7 - SQL - Language Statements + SQL - 语言语句 @@ -66,7 +66,7 @@ SET SESSION CHARACTERISTICS AS TRANSACTION transa - 一个事务的隔离级别决定当其他事务并行运行时该事务能看见什么数据: + 一个事务的隔离级别决定当其他事务并发运行时该事务能看见什么数据: @@ -137,7 +137,7 @@ SET SESSION CHARACTERISTICS AS TRANSACTION transa 事务属性才会生效。当为一个事务同时选择这三个属性时,该事务在 首次获取其快照时可能会阻塞;在此之后,它便可以运行,而无需承担普通 SERIALIZABLE事务的常规开销,也不会有促成 - 序列化失败或因序列化失败而被取消的风险。这种模式非常适合长时间运行的 + 串行化失败或因串行化失败而被取消的风险。这种模式非常适合长时间运行的 报表或备份。 diff --git a/zh/15/ref/show.sgml b/zh/15/ref/show.sgml index 3b4be6bd..b27c2145 100644 --- a/zh/15/ref/show.sgml +++ b/zh/15/ref/show.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SHOW 7 - SQL - Language Statements + SQL - 语言语句 @@ -73,6 +73,20 @@ SHOW ALL + + LC_COLLATE + + 显示数据库用于排序规则(文本排序)的区域设置。目前,该参数可以显示但不能设置,因为该设置在数据库创建时就已确定。 + + + + + LC_CTYPE + + 显示数据库用于字符分类的区域设置。目前,该参数可以显示但不能设置,因为该设置在数据库创建时就已确定。 + + + IS_SUPERUSER diff --git a/zh/15/ref/start_transaction.sgml b/zh/15/ref/start_transaction.sgml index 57a74b2f..5026fa70 100644 --- a/zh/15/ref/start_transaction.sgml +++ b/zh/15/ref/start_transaction.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation START TRANSACTION 7 - SQL - Language Statements + SQL - 语言语句 @@ -64,15 +64,16 @@ START TRANSACTION [ transaction_mode - DEFERRABLE 这一 - transaction_mode 是 - PostgreSQL语言扩展。 + DEFERRABLE + transaction_mode + 是PostgreSQL的一种语言扩展。 SQL 标准要求在连续的transaction_modes之间有逗号, - 但出于历史原因PostgreSQL允许省略逗号。 + 但出于历史原因, + PostgreSQL允许省略逗号。 diff --git a/zh/15/ref/truncate.sgml b/zh/15/ref/truncate.sgml index aa2ce51c..ff1e0bc9 100644 --- a/zh/15/ref/truncate.sgml +++ b/zh/15/ref/truncate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation TRUNCATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/unlisten.sgml b/zh/15/ref/unlisten.sgml index 5e73e99e..6b52f1af 100644 --- a/zh/15/ref/unlisten.sgml +++ b/zh/15/ref/unlisten.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation UNLISTEN 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/ref/update.sgml b/zh/15/ref/update.sgml index a3c965df..4ace7c49 100644 --- a/zh/15/ref/update.sgml +++ b/zh/15/ref/update.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation UPDATE 7 - SQL - Language Statements + SQL - 语言语句 @@ -313,12 +313,12 @@ UPDATE count 在被移动的行上并发执行UPDATE或 - DELETE时,有可能收到序列化失败错误。假设会话 1 - 正在更新某个分区键,与此同时,一个对该行可见的并发会话 2 对该行 + DELETE时,有可能收到串行化失败错误。假设会话 1 + 正在对某个分区键执行UPDATE,与此同时,一个能够看到该行的并发会话 2 对该行 执行UPDATEDELETE操作。在 这种情况下,会话 2 的UPDATE或 - DELETE将检测到行移动,并引发序列化失败错误 - (其 SQLSTATE 代码始终为'40001')。如果发生 + DELETE将检测到行移动,并引发串行化失败错误 + (其 SQLSTATE 代码始终为'40001')。如果发生 这种情况,应用程序可能需要重试事务。在表未分区或没有发生行移动 的通常情况下,会话 2 会识别出新更新的那一行,并在这个新行版本上执行 UPDATE/DELETE。 diff --git a/zh/15/ref/vacuum.sgml b/zh/15/ref/vacuum.sgml index abe9d66a..a72d9246 100644 --- a/zh/15/ref/vacuum.sgml +++ b/zh/15/ref/vacuum.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation VACUUM 7 - SQL - Language Statements + SQL - 语言语句 @@ -22,6 +22,7 @@ PostgreSQL documentation VACUUM [ ( option [, ...] ) ] [ table_and_columns [, ...] ] +VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ ANALYZE ] [ table_and_columns [, ...] ] 其中option可以是下列之一: @@ -32,16 +33,13 @@ VACUUM [ ( option [, ...] ) ] [ boolean
] SKIP_LOCKED [ boolean ] INDEX_CLEANUP { AUTO | ON | OFF } - PROCESS_MAIN [ boolean ] PROCESS_TOAST [ boolean ] TRUNCATE [ boolean ] PARALLEL integer - SKIP_DATABASE_STATS [ boolean ] - ONLY_DATABASE_STATS [ boolean ] 其中table_and_columns是: - [ ONLY ] table_name [ * ] [ ( column_name [, ...] ) ] + table_name [ ( column_name [, ...] ) ] @@ -74,11 +72,13 @@ VACUUM [ ( option [, ...] ) ] [ 并行清理。 - 如需禁用该功能,可以使用PARALLEL选项并将并行工作者数指定为零。 + 如需禁用该功能,可以使用PARALLEL选项并将并行工作进程数指定为零。 VACUUM FULL会把表的全部内容重写到一个没有额外空闲空间的新磁盘文件中, 从而让未使用的空间能够返还给操作系统。这种形式要慢得多,并且在处理每个表时都需要 ACCESS EXCLUSIVE锁。 + + 当选项列表用圆括号括起来时,选项可以按任意顺序书写。如果不加圆括号,则必须严格按照上面所示的顺序指定选项。带圆括号的语法是在PostgreSQL 9.0 中加入的;不带圆括号的语法已被弃用。 @@ -112,9 +112,7 @@ VACUUM [ ( option [, ...] ) ] [ VERBOSE - - 为每个表以INFO级别输出详细的清理活动报告。 - + 为每个表输出详细的清理活动报告。 @@ -184,15 +182,7 @@ VACUUM [ ( option [, ...] ) ] [ - - PROCESS_MAIN - - - 指定VACUUM应尝试处理主关系。这通常是期望的行为,也是默认行为。 - 当只需要清理某个关系对应的TOAST表时,将此选项设为 false 可能会有用。 - - - + PROCESS_TOAST @@ -208,14 +198,7 @@ VACUUM [ ( option [, ...] ) ] [ TRUNCATE - - 指定VACUUM应尝试截去表末尾的空页,使这些被截断页面占用的磁盘空间 - 能够返还给操作系统。通常这是期望的行为,也是默认行为,除非 - 被设为 false,或者待清理表的 - vacuum_truncate选项被设为 false。将此选项设为 false 有助于避免 - 截断操作所需的表级ACCESS EXCLUSIVE锁。使用FULL选项时, - 此选项会被忽略。 - + 指定VACUUM应尝试截去表末尾的空页,使这些被截断页面占用的磁盘空间能够返还给操作系统。通常这是期望的行为,也是默认行为,除非待清理表的vacuum_truncate选项被设为 false。将此选项设为 false 有助于避免截断操作所需的表级ACCESS EXCLUSIVE锁。使用FULL选项时,此选项会被忽略。 @@ -237,31 +220,9 @@ VACUUM [ ( option [, ...] ) ] [ - - SKIP_DATABASE_STATS - - - 指定VACUUM应跳过更新数据库范围内关于最老未冻结 XID 的统计信息。 - 通常,VACUUM会在命令结束时更新这些统计信息。不过,在拥有大量表的数据库中, - 这可能需要一段时间,而且只有当包含最老未冻结 XID 的表也在本次清理范围内时,这么做才有意义。 - 此外,如果多个VACUUM命令并行发出,那么同一时间只能有一个命令更新数据库范围统计信息。 - 因此,如果应用程序打算连续发出一系列VACUUM命令,那么除了最后一条命令之外, - 其余命令都可以设置此选项;或者在所有命令上都设置它,然后再单独执行 - VACUUM (ONLY_DATABASE_STATS)。 - - - - - ONLY_DATABASE_STATS - - - 指定VACUUM除了更新数据库范围内关于最老未冻结 XID 的统计信息外,不执行任何其他操作。 - 指定该选项时,table_and_columns列表必须为空, - 并且除了VERBOSE之外不能启用其他任何选项。 - - - + + boolean @@ -286,27 +247,12 @@ VACUUM [ ( option [, ...] ) ] [ - - size - - - 指定以千字节为单位的内存大小。也可以把大小写成一个字符串,即数值后跟下列任一种内存单位: - B(字节)、kB(千字节)、 - MB(兆字节)、GB(吉字节)或 - TB(太字节)。 - - - + table_name - - 要清理的特定表或物化视图的名称(可选地带模式限定)。 - 如果在表名前指定ONLY,则只清理该表。 - 如果未指定ONLY,则还会清理该表及其所有继承子表或分区(如果有)。 - 也可以在表名后显式指定*,以明确表示要清理继承子表(或分区)。 - + 要清理的特定表或物化视图的名称(可选地带模式限定)。如果指定的表是分区表,则清理它的所有叶子分区。 @@ -334,14 +280,11 @@ VACUUM [ ( option [, ...] ) ] [ 注解 - 要清理一个表,通常必须拥有该表上的MAINTAIN权限。 + 要清理一个表,通常调用者必须是该表的拥有者或超级用户。 不过,数据库拥有者可以清理其数据库中的所有表,但共享系统目录除外。 - VACUUM会跳过调用用户无权清理的任何表。 - - - - 当VACUUM运行时,会被临时改为 - pg_catalog, pg_temp。 + (对共享系统目录的这一限制意味着,真正意义上的全数据库 + VACUUM 只能由超级用户执行。) + VACUUM 会跳过调用用户无权清理的任何表。 @@ -355,7 +298,7 @@ VACUUM [ ( option [, ...] ) ] [ - 我们建议定期对所有数据库执行清理,以移除死行。PostgreSQL提供了一个autovacuum机制, + 我们建议定期对所有数据库执行清理,以移除死行。PostgreSQL提供了一个自动清理(autovacuum)机制, 可以自动执行常规清理维护。有关自动与手动清理的更多信息,参见 @@ -373,8 +316,8 @@ VACUUM [ ( option [, ...] ) ] [ VACUUM会显著增加 I/O 流量,这可能导致其他活动会话性能变差。 - 因此,有时建议使用基于代价的清理延迟特性。对于并行清理,每个工作者的睡眠时长 - 都与该工作者完成的工作量成比例。详见。 + 因此,有时建议使用基于代价的清理延迟特性。对于并行清理,每个工作进程的睡眠时长 + 都与该工作进程完成的工作量成比例。详见 @@ -390,7 +333,7 @@ VACUUM [ ( option [, ...] ) ] [ 示例 - 清理单个表onek,对其执行优化器分析,并打印详细的清理活动报告: + 清理单个表onek,对其进行分析以供优化器使用,并打印详细的清理活动报告: VACUUM (VERBOSE, ANALYZE) onek; @@ -403,14 +346,6 @@ VACUUM (VERBOSE, ANALYZE) onek; 在SQL标准中没有VACUUM语句。 - - - 下列语法在PostgreSQL 9.0版本之前使用,并且目前仍受支持: - -VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ ANALYZE ] [ table_and_columns [, ...] ] - - 请注意,在这种语法中,选项必须严格按所示顺序指定。 - diff --git a/zh/15/ref/vacuumdb.sgml b/zh/15/ref/vacuumdb.sgml index 4396e2e0..d50842a4 100644 --- a/zh/15/ref/vacuumdb.sgml +++ b/zh/15/ref/vacuumdb.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation vacuumdb 1 - Application + 应用程序 @@ -36,61 +36,17 @@ PostgreSQL documentation - - - dbname - - - - - - - - vacuumdb - connection-option - option - - - - - - - - schema - - - - - - dbname - - - - + dbname vacuumdb connection-option option - - - - - - - - schema - - - - - - dbname - - - - + + + + @@ -128,16 +84,7 @@ PostgreSQL documentation - - - - - 指定给定一次 缓冲区访问策略(Buffer Access Strategy) - 环形缓冲区大小,供 vacuumdb 调用使用。这个大小用于计算将作为该策略一部分被重用的共享缓冲区数量。参见 - 。 - - - + @@ -159,6 +106,9 @@ PostgreSQL documentation 禁止基于可见性映射内容跳过页面。 + + 此选项仅适用于运行PostgreSQL 9.6 及更高版本的服务器。 + @@ -187,7 +137,7 @@ PostgreSQL documentation - 积极地冻结元组。 + 激进地冻结元组。 @@ -198,6 +148,9 @@ PostgreSQL documentation 始终删除指向死元组的索引条目。 + + 此选项仅适用于运行PostgreSQL 12 及更高版本的服务器。 + @@ -225,16 +178,19 @@ PostgreSQL documentation - 仅对 multixact ID 年龄至少为 mxid_age - 的表执行清理或分析命令。此设置可用于优先处理表,以防止 multixact ID 回卷 + 仅对 多事务 ID 年龄至少为 mxid_age + 的表执行清理或分析命令。此设置可用于优先处理表,以防止 多事务 ID 回卷 (见 )。 - 就此选项而言,一个关系的 multixact ID 年龄,是其主关系及其关联的 + 就此选项而言,一个关系的 多事务 ID 年龄,是其主关系及其关联的 TOAST 表(如果存在)年龄中的较大者。由于 vacuumdb 发出的命令在必要时也会处理该关系的 TOAST 表,因此无需单独考虑它。 + + 此选项仅适用于运行PostgreSQL 9.6 及更高版本的服务器。 + @@ -251,53 +207,17 @@ PostgreSQL documentation vacuumdb 发出的命令在必要时也会处理该关系的 TOAST 表,因此无需单独考虑它。 + + 此选项仅适用于运行PostgreSQL 9.6 及更高版本的服务器。 + - - - - - 仅分析那些在列、索引表达式或扩展统计信息对象上缺少统计信息的关系。与 - 一起使用时,此选项可防止 - vacuumdb 临时用按较低统计目标生成的统计信息替换现有统计信息, - 从而避免查询优化器短暂地作出更差的选择。 - - - 此选项只能与 配合使用。 - - - 注意, 要求拥有 - SELECT 权限,以访问 - pg_statistic - 和 - pg_statistic_ext_data, - 而这些权限默认只授予超级用户。 - - - - - - - - - 仅清理或分析 schema 中的所有表。 - 可以通过多次指定 来清理多个模式。 - - - - - - - - - 不清理或分析 schema 中的任何表。 - 可以通过多次指定 来排除多个模式。 - - - + + + @@ -305,17 +225,13 @@ PostgreSQL documentation 不删除指向死元组的索引条目。 + + 此选项仅适用于运行PostgreSQL 12 及更高版本的服务器。 + - - - - - 跳过主关系。 - - - + @@ -323,6 +239,9 @@ PostgreSQL documentation 如果有,跳过与待清理表关联的 TOAST 表。 + + 此选项仅适用于运行PostgreSQL 14 及更高版本的服务器。 + @@ -332,6 +251,9 @@ PostgreSQL documentation 不截断表末尾的空页。 + + 此选项仅适用于运行PostgreSQL 12 及更高版本的服务器。 + @@ -343,6 +265,9 @@ PostgreSQL documentation 指定并行清理的并行工作进程数量。这样可以让清理利用多个 CPU 处理索引。 参见 。 + + 此选项仅适用于运行PostgreSQL 13 及更高版本的服务器。 + @@ -362,6 +287,9 @@ PostgreSQL documentation 跳过那些无法立即加锁并进行处理的关系。 + + 此选项仅适用于运行PostgreSQL 12 及更高版本的服务器。 + @@ -579,6 +507,12 @@ PostgreSQL documentation + + 注解 + + vacuumdb可能需要多次连接到PostgreSQL服务器,每次都要询问密码。在这种情况下,使用~/.pgpass文件会比较方便。更多信息见 + + 示例 @@ -603,11 +537,7 @@ PostgreSQL documentation $ vacuumdb --analyze --verbose --table='foo(bar)' xyzzy - - 清理名为 xyzzy 的数据库中 foobar 模式内的所有表: - -$ vacuumdb --schema='foo' --schema='bar' xyzzy - + diff --git a/zh/15/ref/values.sgml b/zh/15/ref/values.sgml index e5b00372..8c6d7597 100644 --- a/zh/15/ref/values.sgml +++ b/zh/15/ref/values.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation VALUES 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/15/reference.sgml b/zh/15/reference.sgml index 0968de0c..af75c5c2 100644 --- a/zh/15/reference.sgml +++ b/zh/15/reference.sgml @@ -273,6 +273,7 @@ &pgupgrade; &pgwaldump; &postgres; + &postmaster; diff --git a/zh/15/regress.sgml b/zh/15/regress.sgml index 39fc858e..1db2c61f 100644 --- a/zh/15/regress.sgml +++ b/zh/15/regress.sgml @@ -385,34 +385,11 @@ make check LANG=C ENCODING=EUC_JP 自定义服务器设置 - 运行测试套件时,有几种方式可以使用自定义服务器设置。这对于启用额外日志、 - 调整资源限制,或启用额外的运行时检查(例如 - )可能很有用。但请注意, - 并非所有测试都能在任意设置下都顺利通过。 - - - - 在测试准备过程中,内部运行的各个initdb命令可以通过 - 环境变量PG_TEST_INITDB_EXTRA_OPTS传入附加选项。例如, - 要在启用校验和并使用自定义 WAL 段大小和work_mem - 设置的情况下运行测试,可使用: + 运行回归测试套件时使用的自定义服务器设置可以通过 + PGOPTIONS环境变量来设置(适用于允许这样设置的参数): -make check PG_TEST_INITDB_EXTRA_OPTS='-k --wal-segsize=4 -c work_mem=50MB' +make check PGOPTIONS="-c force_parallel_mode=regress -c work_mem=50MB" - - - - 对于核心回归测试套件以及其他由pg_regress驱动的测试, - 自定义运行时服务器设置还可以通过PGOPTIONS环境变量 - 来设置(适用于允许这样设置的参数),例如: - -make check PGOPTIONS="-c debug_parallel_query=regress -c work_mem=50MB" - - (这利用了 libpq 提供的功能;详情见。) - - - 在针对临时安装运行时,也可以通过提供预先写好的 postgresql.conf来设置自定义参数: @@ -422,6 +399,10 @@ make check EXTRA_REGRESS_OPTS="--temp-config=test_postgresql.conf" + + 这对于启用额外日志、调整资源限制,或启用额外的运行时检查(例如 + )可能很有用。 + diff --git a/zh/15/release-15.sgml b/zh/15/release-15.sgml index f694055f..e96f60da 100644 --- a/zh/15/release-15.sgml +++ b/zh/15/release-15.sgml @@ -1570,14 +1570,14 @@ Branch: REL_14_STABLE [15fd7a3e2] 2026-07-28 10:56:39 +0200 --> - 在清理 GIN 索引 posting-tree 期间响应查询取消并遵守清理延迟 + 在清理 GIN 索引倒排树期间响应查询取消并遵守清理延迟 (Paul Kim、Alexander Korotkov) § - 常见值的 posting tree 可能很大,因此遗漏这项检查可能导致清理运行 + 常见值的倒排树可能很大,因此遗漏这项检查可能导致清理运行 很长时间后才注意到中断。 @@ -3144,7 +3144,7 @@ Branch: REL_15_STABLE [bab4f7fa5] 2026-05-05 10:32:42 +0900 Branch: REL_14_STABLE [172034f6e] 2026-05-05 10:34:07 +0900 --> - 在假定可排序类型上的等值条件意味着唯一性之前,检查是否存在非确定性排序规则 + 在假定支持排序规则的类型上的等值条件意味着唯一性之前,检查是否存在非确定性排序规则 (Richard Guo) § § @@ -8196,7 +8196,7 @@ Branch: REL_14_STABLE [5144e1f8f] 2025-03-11 12:50:35 +0100 Branch: REL_13_STABLE [f5b4a0b49] 2025-03-11 12:50:35 +0100 --> - 检测 BRIN 索引操作符类中缺失的支持过程,并报告错误而不是崩溃 + 检测 BRIN 索引操作符类中缺失的支持函数,并报告错误而不是崩溃 (Álvaro Herrera) § @@ -9265,7 +9265,7 @@ Branch: REL_14_STABLE [d9d5e1b48] 2024-12-07 14:28:16 -0500 Branch: REL_13_STABLE [531cbd8b7] 2024-12-07 14:28:16 -0500 --> - 修复操作符族成员操作符或支持过程可能成为悬空引用的情况 + 修复操作符族成员操作符或支持函数可能成为悬空引用的情况 (Tom Lane) § § @@ -11477,16 +11477,16 @@ Branch: REL_13_STABLE [e9c8747ee] 2024-06-27 21:08:55 +0300 Branch: REL_12_STABLE [5dea6628b] 2024-06-27 21:09:15 +0300 --> - 修复启动热备服务器时对已准备事务的子事务的处理 + 修复启动热备服务器时对预备事务的子事务的处理 (Heikki Linnakangas) § - 当备库的重放从关闭检查点 WAL 记录开始时,在主库上已准备但尚未提交的事务 - 会被正确理解为仍在进行中。但已准备事务的子事务(由保存点或 + 当备库的重放从关闭检查点 WAL 记录开始时,在主库上已预备但尚未提交的事务 + 会被正确理解为仍在进行中。但预备事务的子事务(由保存点或 PL/pgSQL 异常块创建)没有被考虑在内, - 会被视为已中止。如果该已准备事务随后被提交,就会导致不一致。 + 会被视为已中止。如果该预备事务随后被提交,就会导致不一致。 @@ -16346,8 +16346,8 @@ Branch: REL_11_STABLE [0048c3b51] 2023-07-04 09:27:00 +1200 - 使用位图堆扫描、使用 GIN 索引以及检查初始为空的 B-树 索引时可能会遗漏冲突。 - 所有这些情况都可能因不当允许冲突事务提交而导致可序列化失败。 + 使用位图堆扫描、使用 GIN 索引以及检查初始为空的 B-树索引时可能会遗漏冲突。 + 所有这些情况都可能因不当允许相互冲突的事务提交而破坏可串行性。 diff --git a/zh/15/runtime.sgml b/zh/15/runtime.sgml index 43aae078..a8f00a15 100644 --- a/zh/15/runtime.sgml +++ b/zh/15/runtime.sgml @@ -1,7 +1,6 @@ - 服务器设置和操作 @@ -34,7 +33,6 @@ - 创建一个数据库集簇 @@ -47,7 +45,7 @@ - 在做任何事情之前,必须先在磁盘上初始化一个数据库存储区域。我们把它称为数据库集簇。(SQL 标准使用术语 catalog cluster。)数据库集簇是由一个正在运行的数据库服务器实例管理的一组数据库。初始化之后,数据库集簇中会包含一个名为postgres的数据库,作为供工具、用户和第三方应用使用的默认数据库。数据库服务器本身并不要求该postgres数据库存在,但许多外部工具程序都假定它存在。初始化期间,集簇中还会创建另外两个数据库,名为template1template0。顾名思义,它们会作为后续新建数据库的模板;不应将它们用于实际工作。(关于在集簇中创建新数据库的信息,见。) + 在做任何事情之前,必须先在磁盘上初始化一个数据库存储区域。我们把它称为数据库集簇。(SQL 标准使用术语目录集簇(catalog cluster)。)数据库集簇是由一个正在运行的数据库服务器实例管理的一组数据库。初始化之后,数据库集簇中会包含一个名为postgres的数据库,作为供工具、用户和第三方应用使用的默认数据库。数据库服务器本身并不要求该postgres数据库存在,但许多外部工具程序都假定它存在。初始化期间,集簇中还会创建另外两个数据库,名为template1template0。顾名思义,它们会作为后续新建数据库的模板;不应将它们用于实际工作。(关于在集簇中创建新数据库的信息,见。) @@ -67,7 +65,6 @@ - 除了使用 选项,也可以设置环境变量 PGDATAPGDATA @@ -112,9 +109,7 @@ postgres$ initdb -D /usr/local/pgsql/data 另外,指定,以避免使用默认的trust认证方式;或者在运行initdb之后、首次启动服务器之前修改生成的pg_hba.conf文件。(其他合理方法包括使用peer认证,或使用文件系统权限限制连接。更多信息见。) - - initdb还会为数据库集簇初始化默认区域设置locale。通常,它只是采用环境中的区域设置,并将其应用到新初始化的数据库。你也可以为数据库指定不同的区域设置;更多信息见。该数据库集簇内部使用的默认排序顺序由initdb设定。虽然你可以创建采用不同排序顺序的新数据库,但initdb创建的模板数据库所使用的排序顺序,若不删除并重建它们就无法更改。使用非CPOSIX区域设置还会带来性能影响,因此第一次就做出正确选择很重要。 - + initdb 还会初始化数据库集簇的默认区域设置区域设置。通常,它会直接采用环境中的区域设置,并将其应用于初始化的数据库。可以为数据库指定不同的区域设置;更多信息见 。特定数据库集簇中使用的默认排序顺序由 initdb 设置,虽然你可以使用不同的排序顺序创建新数据库,但 initdb 创建的模板数据库所使用的顺序,只有删除并重建这些数据库才能更改。使用 CPOSIX 以外的区域设置还会影响性能。因此,一开始就作出正确选择很重要。 initdb还会为数据库集簇设置默认字符集编码。通常应选择与区域设置相匹配的字符集编码。详见。 @@ -139,7 +134,6 @@ postgres$ initdb -D /usr/local/pgsql/data - 文件系统 @@ -147,7 +141,6 @@ postgres$ initdb -D /usr/local/pgsql/data - NFS @@ -162,9 +155,7 @@ postgres$ initdb -D /usr/local/pgsql/data 对于在PostgreSQL中使用NFS,唯一硬性要求是文件系统必须使用hard选项挂载。使用hard选项时,如果出现网络问题,进程可能会无限期地挂起,因此这种配置需要配套谨慎的监控措施。soft选项会在网络问题出现时中断系统调用,但PostgreSQL不会重试以这种方式被中断的系统调用,因此任何此类中断都会导致报告 I/O 错误。 - - 没有必要使用sync挂载选项。async选项的行为已经足够,因为PostgreSQL会在适当的时候发出fsync调用来刷新写缓存。(这和它在本地文件系统上的工作方式类似。)但是,强烈建议在支持该选项的NFS服务器端系统上使用sync导出选项(主要是 Linux)。否则,NFS 客户端上的fsync或等效操作实际上并不能保证数据到达服务器上的持久存储,这可能导致类似于将参数设为关闭时那样的损坏。这些挂载和导出选项的默认值在不同厂商和版本间并不相同,因此无论如何都建议检查它们,并且最好显式指定,以避免歧义。 - + 没有必要使用 sync 挂载选项。async 选项的行为已经足够,因为 PostgreSQL 会在适当的时候发出 fsync 调用将写缓存刷盘。(这和它在本地文件系统上的工作方式类似。)但是,强烈建议在支持该选项的 NFS 服务器端系统上使用 sync 导出选项(主要是 Linux)。否则,NFS 客户端上的 fsync 或等效操作实际上并不能保证数据到达服务器上的持久存储,这可能导致类似于将参数 设为关闭时那样的损坏。这些挂载和导出选项的默认值在不同厂商和版本间并不相同,因此无论如何都建议检查它们,并且最好显式指定,以避免歧义。 在某些情况下,可以通过 NFS 或更底层的协议(例如 iSCSI)访问外部存储产品。在后一种情况下,存储会表现为块设备,可以在其上创建任意可用的文件系统。这种方式或许能让 DBA 不必应对 NFS 的某些特性,但当然,管理远程存储的复杂性会转移到其他层面。 @@ -175,7 +166,6 @@ postgres$ initdb -D /usr/local/pgsql/data - 启动数据库服务器 @@ -215,7 +205,7 @@ pg_ctl start -l logfile - 通常,你会希望在计算机启动时就启动数据库服务器。与系统引导时启动服务器相关的系统引导启动服务器时自动启动脚本依赖于操作系统。PostgreSQLcontrib/start-scripts 目录中附带了一些示例脚本。安装这些脚本需要 root 权限。 + 通常,你会希望在计算机启动时就启动数据库服务器。引导期间启动服务器自动启动脚本依赖于操作系统。PostgreSQLcontrib/start-scripts 目录中附带了一些示例脚本。安装这些脚本需要 root 权限。 @@ -360,7 +350,6 @@ DETAIL: Failed system call was semget(5440126, 17, 03600). - 客户端连接问题 @@ -372,7 +361,7 @@ DETAIL: Failed system call was semget(5440126, 17, 03600). psql: error: connection to server at "server.joe.com" (123.123.123.123), port 5432 failed: Connection refused Is the server running on that host and accepting TCP/IP connections? - 这是一个典型的我找不到可通信的服务器错误。上面这种情况发生在尝试使用 TCP/IP 通信时。一个常见错误是忘记配置,从而导致服务器不接受远程 TCP 连接。 + 这是一个典型的我找不到可通信的服务器错误。上面这种情况发生在尝试使用 TCP/IP 通信时。一个常见错误是忘记配置服务器以允许 TCP/IP 连接。 @@ -391,15 +380,13 @@ psql: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: No such - 管理内核资源 - PostgreSQL有时会耗尽操作系统的各种资源限制,尤其是在同一系统上运行多个服务器副本,或在非常大型的安装环境中时更是如此。本节解释PostgreSQL使用的内核资源,以及你可以采取哪些步骤来解决与内核资源消耗相关的问题。 + PostgreSQL有时会达到操作系统的各种资源上限,尤其是在同一系统上运行多个服务器实例,或在非常大型的安装环境中时更是如此。本节解释PostgreSQL使用的内核资源,以及你可以采取哪些步骤来解决与内核资源消耗相关的问题。 - 共享内存和信号量 @@ -419,11 +406,10 @@ psql: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: No such - System V IPC 功能通常受系统范围的分配限制约束。当PostgreSQL超出这些限制之一时,服务器会拒绝启动,并留下带有指导性的错误消息,说明问题所在以及应如何处理(另见)。相关内核参数在不同系统上的命名基本一致,给出了概览;不过,设置它们的方法却各不相同。下面给出一些平台上的建议。 + System V IPC 功能通常受系统范围的分配限制约束。当PostgreSQL超出这些限制之一时,服务器会拒绝启动,并应留下带有指导性的错误消息,说明问题所在以及应如何处理(另见)。相关内核参数在不同系统上的命名基本一致,给出了概览;不过,设置它们的方法却各不相同。下面给出一些平台上的建议。 - <systemitem class="osname">System V</systemitem> <acronym>IPC</acronym>参数 @@ -431,7 +417,6 @@ psql: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: No such - 名称 描述 @@ -440,11 +425,10 @@ psql: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: No such - SHMMAX 共享内存段的最大尺寸(字节) - 至少 1kB,但是默认值通常要高一些 + 至少 1kB,但是默认值通常高得多 @@ -475,13 +459,13 @@ psql: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: No such SEMMNI 信号量标识符(即,集合)的最大数目 - 至少 ceil(num_os_semaphores / 16),并为其他应用保留空间 + 至少 ceil((max_connections + autovacuum_max_workers + max_wal_senders + max_worker_processes + 6) / 16),并为其他应用保留空间 SEMMNS 系统范围内的最大信号量数目 - ceil(num_os_semaphores / 16) * 17,并为其他应用保留空间 + ceil((max_connections + autovacuum_max_workers + max_wal_senders + max_worker_processes + 6) / 16) * 17,并为其他应用保留空间 @@ -507,8 +491,8 @@ psql: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: No such
- PostgreSQL要求少量字节的 System V 共享内存(在 64 位平台上通常是 48 字节)用于每一个服务器拷贝。在大多数现代操作系统上,这个量很容易得到。 - 但是,如果你运行了很多个服务器副本,或者显式配置服务器以使用大量 System V 共享内存(参见 ), + PostgreSQL要求少量字节的 System V 共享内存(在 64 位平台上通常是 48 字节)用于每一个服务器实例。在大多数现代操作系统上,这个量很容易得到。 + 但是,如果你运行了很多个服务器实例,或者显式配置服务器以使用大量 System V 共享内存(参见 ), 可能需要增加SHMALL(系统范围内 System V 共享内存的总量)。注意在很多系统上SHMALL是以页面而不是字节来度量。 @@ -516,30 +500,36 @@ psql: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: No such 不太可能出问题的是共享内存段的最小尺寸(SHMMIN),对PostgreSQL来说应该最多大约是 32 字节(通常只是1)。而系统范围(SHMMNI)或每个进程(SHMSEG)的最大共享内存段数目不太可能会导致问题,除非你的系统把它们设成零。 - - 当使用 System V 信号量时,PostgreSQL会为每个允许连接()、每个允许自动清理工作进程()、每个允许 WAL 发送进程()、每个允许后台进程()等分配一个信号量,按 16 个一组。运行期计算参数会报告所需信号量数;可在启动服务器前用如下命令查看: - -$ postgres -D $PGDATA -C num_os_semaphores - - - - - 每组 16 个信号量还包含第 17 个信号量,用于存放magic number,以检测与其他应用信号量集合的冲突。系统最大信号量数由 SEMMNS 设定,因此至少应为 num_os_semaphores 加上每组 16 个所需信号量的一个附加量(见中的公式)。SEMMNI决定系统中同一时刻可存在的信号量集合数上限,因此至少应为 ceil(num_os_semaphores / 16)。降低允许连接数是对通常带有误导措辞设备上没有剩余空间(来自semget)这类失败的临时缓解手段。 - + 使用 System V 信号量时,PostgreSQL 为每个允许的连接()、自动清理工作进程()、WAL 发送进程()和后台进程()各使用一个信号量,每 16 个组成一组。每组还包含第 17 个信号量,其中存放一个魔数,用来检测与其他应用程序使用的信号量集的冲突。系统中的信号量最大数量由 SEMMNS 设置,因此它必须至少等于 max_connectionsautovacuum_max_workersmax_wal_sendersmax_worker_processes 之和,再为每 16 个允许的连接和工作进程额外增加一个信号量(参见 中的公式)。参数 SEMMNI 限制系统中同时存在的信号量集的数量。因此,此参数必须至少为 ceil((max_connections + autovacuum_max_workers + max_wal_senders + max_worker_processes + 6) / 16)。降低允许的连接数,可以临时规避 semget 函数的失败;此类失败通常会报告令人困惑的 No space left on device 在某些情况下,可能还需要增大SEMMAP,使其至少与SEMMNS处于同一数量级。如果系统提供这个参数(很多系统没有),它定义的是信号量资源映射的大小;映射中每个连续的可用信号量块都需要占用一项。每当一个信号量集合被释放时,它要么会并入与该释放块相邻的现有项,要么会登记为一个新的映射项。如果映射已满,被释放的信号量就会丢失(直到重启)。因此,随着时间推移,信号量空间碎片化可能会导致可用信号量少于应有数量。 - 与semaphore undo有关的其他各种设置,如SEMMNUSEMUME,不会影响PostgreSQL。 + 与信号量撤销有关的其他各种设置,如SEMMNUSEMUME,不会影响PostgreSQL - 当使用 POSIX 信号量时,所需数量与 System V 相同,即每个允许连接()、每个允许自动清理工作进程()、每个允许 WAL 发送进程()、每个允许后台进程()等各需一个。在优先使用该实现的平台上,POSIX 信号量数量没有特定内核上限。 + 当使用 POSIX 信号量时,所需数量与 System V 相同,即每个允许连接()、每个允许自动清理工作进程()、每个允许 WAL 发送进程()、每个允许后台进程()各需一个。在优先使用该实现的平台上,POSIX 信号量数量没有特定内核上限。 + + + AIX + AIXIPC 配置 + + + + 对于 SHMMAX 之类的参数,通常不需要任何特殊配置,因为看起来系统已经配置为允许将所有内存都用作共享内存。这类配置也常用于其他数据库,例如 DB/2。 + + + 不过,可能需要修改 /etc/security/limits 中的全局 ulimit 信息,因为文件大小(fsize)和文件数量(nofiles)的默认硬限制可能过低。 + + + + FreeBSD @@ -572,33 +562,11 @@ $ postgres -D $PGDATA -C num_os_semaphores - HP-UX - HP-UXIPC 配置 - - - - 对于正常安装,默认设置通常就足够了。 - - - 可以在系统管理器SAM)的 - 内核配置可配置参数下设置 - IPC 参数。完成后请选择 - 创建新内核。 - - - - - - - NetBSD NetBSDIPC 配置 - - - 默认共享内存设置通常就足够了,除非你已将 shared_memory_type 设置为 sysv。不过,你需要增大 kern.ipc.semmnikern.ipc.semmns,因为 NetBSD 对这两项的默认值小得实际上无法使用。 - + 默认共享内存设置通常就足够了,除非你已将 shared_memory_type 设置为 sysv。通常需要增大 kern.ipc.semmnikern.ipc.semmns,因为 NetBSD 对这两项的默认设置小得不便使用。 可以使用 sysctl 调整 IPC 参数,例如: @@ -615,15 +583,11 @@ $ postgres -D $PGDATA -C num_os_semaphores - OpenBSD OpenBSDIPC 配置 - - - 默认共享内存设置通常就足够了,除非你已将 shared_memory_type 设置为 sysv。不过,你需要增大 kern.seminfo.semmnikern.seminfo.semmns,因为 OpenBSD 对这两项的默认值小得实际上无法使用。 - + 默认共享内存设置通常已经足够,除非你将 shared_memory_type 设为 sysv。通常需要增大 kern.seminfo.semmnikern.seminfo.semmns,因为 OpenBSD 对这两项的默认设置小得令人担忧。 可以使用 sysctl 调整 IPC 参数,例如: @@ -636,6 +600,17 @@ $ postgres -D $PGDATA -C num_os_semaphores + + HP-UX + HP-UXIPC 配置 + + + 默认设置通常足以满足普通安装的需求。 + 可以在 System Administration ManagerSAM)的 Kernel ConfigurationConfigurable Parameters 中设置 IPC 参数。完成后选择 Create A New Kernel + + + + Linux @@ -648,7 +623,7 @@ $ postgres -D $PGDATA -C num_os_semaphores - 共享内存大小设置可以通过sysctl界面更改。例如,允许 16 GB: + 共享内存大小设置可以通过sysctl接口更改。例如,允许 16 GB: $ sysctl -w kernel.shmmax=17179869184 $ sysctl -w kernel.shmall=4194304 @@ -659,17 +634,15 @@ $ postgres -D $PGDATA -C num_os_semaphores - + macOS macOSIPC 配置 - 默认共享内存和信号量设置通常就足够了,除非你已将 shared_memory_type 设置为 sysv - 在 macOS 中配置共享内存的推荐方法是创建一个名为/etc/sysctl.conf的文件,其中包含这样的变量赋值: @@ -686,9 +659,7 @@ kern.sysv.shmall=1024 SHMMAX 只能设置为 4096 的倍数。 - - 在这个平台上,SHMALL以 4kB 的页面度量。 - + 在这个平台上,SHMALL 以 4 kB 的页为单位。 SHMMNI 之外,其他设置都可以使用 sysctl 动态更改。不过,最好还是通过/etc/sysctl.conf设置你希望使用的值,这样重启后仍能保留。 @@ -701,9 +672,8 @@ kern.sysv.shmall=1024 Solaris illumos - - 默认的共享内存和信号量设置对于大多数 PostgreSQL 应用通常已经足够。Solaris 现在将SHMMAX的默认值设为系统 RAM 的四分之一。要进一步调整这一设置,可使用与postgres用户关联的项目设置。例如,以root运行下列命令: + 默认的共享内存和信号量设置对于大多数 PostgreSQL 应用通常已经足够。Solaris 将SHMMAX的默认值设为系统 RAM 的四分之一。要进一步调整这一设置,可使用与postgres用户关联的项目设置。例如,以root运行下列命令: projadd -c "PostgreSQL DB User" -K "project.max-shm-memory=(privileged,8GB,deny)" -U postgres -G postgres user.postgres @@ -733,7 +703,6 @@ project.max-msg-ids=(priv,4096,deny)
- systemd RemoveIPC @@ -741,15 +710,15 @@ project.max-msg-ids=(priv,4096,deny) RemoveIPC - + 如果使用systemd,必须注意不要让操作系统过早移除 IPC 资源(包括共享内存)。这在从源码安装 PostgreSQL 时尤其值得关注。使用发行版软件包的用户较不容易受到影响,因为此时postgres用户通常会被创建为系统用户。 - + logind.conf 中的 RemoveIPC 设置控制当用户完全注销时是否移除 IPC 对象。系统用户不受此限制。原版 systemd 默认开启该设置,但某些操作系统发行版默认将其关闭。 - + 当此设置开启时,一个常见现象是,用于并行查询执行的共享内存对象会在看似随机的时间被删除,导致在尝试打开或删除它们时出现错误和警告,例如 WARNING: could not remove shared memory segment "/PostgreSQL.1450751626": No such file or directory @@ -757,19 +726,19 @@ WARNING: could not remove shared memory segment "/PostgreSQL.1450751626": No su 不同类型的 IPC 对象(共享内存与信号量、System V 与 POSIX)在 systemd 中的处理略有不同,因此你可能会发现某些 IPC 资源不会像其他资源那样被删除。但依赖这些细微差别并不可取。 - - 用户注销可能会作为维护作业的一部分发生,也可能在管理员以postgres用户或类似名称登录时手工触发,因此通常很难彻底防止。 + + 用户注销可能会作为维护作业的一部分发生,也可能在管理员以postgres用户登录或执行类似操作时手工触发,因此通常很难彻底防止。 - + 什么算作系统用户,是在编译 systemd 时依据 /etc/login.defs 中的 SYS_UID_MAX 设置确定的。 - + 打包和部署脚本应当谨慎地使用useradd -radduser --system或其等价方式,把postgres用户创建为系统用户。 - + 或者,如果该用户账户创建得不正确,或无法更改,建议在/etc/systemd/logind.conf或其他适当的配置文件中设置 RemoveIPC=no @@ -777,7 +746,6 @@ RemoveIPC=no - 上述两件事至少要确保做到其中之一,否则 PostgreSQL 服务器会变得非常不可靠。 @@ -785,10 +753,9 @@ RemoveIPC=no - 资源限制 - + 类 Unix 操作系统会施加多种资源限制,这些限制可能干扰 PostgreSQL 服务器的运行。其中尤其重要的是:每个用户可用的进程数限制、每个进程可打开文件数限制,以及每个进程可用内存量限制。每一种限制都有限制和限制。实际生效的是软限制,但用户可以自行把它调高到不超过硬限制;硬限制则只能由 root 用户修改。系统调用setrlimit负责设置这些参数。shell 的内置命令ulimit(Bourne shell)或limitcsh)可用于在命令行控制资源限制。在 BSD 派生系统上,/etc/login.conf文件控制登录时设置的各种资源限制。详细信息请参阅操作系统文档。相关参数有maxprocopenfilesdatasize。例如: default:\ @@ -801,7 +768,7 @@ default:\ (-cur表示软限制;把它改为-max则表示设置硬限制。) - + 内核还可能对某些资源施加系统范围的限制。 @@ -817,29 +784,28 @@ default:\ - + PostgreSQL服务器为每个连接使用一个进程,因此你至少应提供与允许连接数相同数量的进程,再加上系统其他部分所需的进程数。通常这不是问题,但如果你在一台机器上运行多个服务器,资源可能就会变得紧张。 - + 打开文件数的出厂默认限制通常被设为对共享环境友好的值,也就是允许许多用户在一台机器上共存,而不会占用不成比例的系统资源。如果你在一台机器上运行很多服务器,这也许正合适;但在专用服务器上,你可能会希望提高这个限制。 - + 另一方面,有些系统允许单个进程打开非常多的文件;如果不止少数几个进程都这么做,就很容易超过系统范围的限制。如果你遇到这种情况,又不想修改系统范围的限制,可以设置PostgreSQL配置参数来限制其打开文件的消耗。 - - 另一个在支持大量客户端连接时可能需要关注的内核限制,是套接字连接队列的最大长度。如果在很短时间内到达的连接请求超过了这个数量,那么其中一些请求可能会在PostgreSQL服务器来得及处理之前就被拒绝,于是客户端会收到不太有帮助的连接失败错误,例如Resource temporarily unavailableConnection refused。在许多平台上,默认队列长度限制是 128。要提高它,请通过sysctl调整相应的内核参数,然后重新启动PostgreSQL服务器。该参数在不同系统上的名称不同:在 Linux 上是net.core.somaxconn,在较新的 FreeBSD 上是kern.ipc.soacceptqueue,在 macOS 和其他 BSD 变体上是kern.ipc.somaxconn。 + + 另一个在支持大量客户端连接时可能需要关注的内核限制,是套接字连接队列的最大长度。如果在很短时间内到达的连接请求超过了这个数量,那么其中一些请求可能会在postmaster来得及处理之前就被拒绝,于是客户端会收到不太有帮助的连接失败错误,例如Resource temporarily unavailableConnection refused。在许多平台上,默认队列长度限制是 128。要提高它,请通过sysctl调整相应的内核参数,然后重新启动postmaster。该参数在不同系统上的名称不同:在 Linux 上是net.core.somaxconn,在较新的 FreeBSD 上是kern.ipc.soacceptqueue,在 macOS 和其他 BSD 变体上是kern.ipc.somaxconn - Linux 内存过量分配 - memory overcommit + 内存过量分配 @@ -847,14 +813,14 @@ default:\ - overcommit + 过量分配 - + Linux 上默认的虚拟内存行为对PostgreSQL并非最佳。由于内核实现内存过量分配的方式,如果 PostgreSQL 或其他进程的内存需求导致系统耗尽虚拟内存,内核可能会终止 PostgreSQL 的 postmaster(主管服务器进程)。 - + 如果发生这种情况,你会看到类似下面的内核消息(至于应到哪里查看此类消息,请参阅你的系统文档和配置): Out of Memory: Killed process 12345 (postgres). @@ -862,15 +828,15 @@ Out of Memory: Killed process 12345 (postgres). 这表示 postgres 进程因内存压力而被终止。尽管现有数据库连接仍会继续正常运行,但新连接将不再被接受。要恢复服务,必须重启PostgreSQL - + 避免该问题的一种办法,是让PostgreSQL运行在一台你能确定不会被其他进程耗尽内存的机器上。如果内存紧张,增加操作系统交换空间也有助于避免这个问题,因为内存不足(OOM)杀手只有在物理内存和交换空间都耗尽时才会被触发。 - - 如果导致系统耗尽内存的正是PostgreSQL自身,那么你可以通过调整配置来避免该问题。在某些情况下,调低与内存相关的配置参数会有帮助,尤其是shared_bufferswork_memhash_mem_multiplier。在其他情况下,允许数据库服务器接受过多连接也可能导致这一问题。很多时候,更好的做法是减小max_connections,并转而使用外部连接池软件。 + + 如果导致系统耗尽内存的正是PostgreSQL自身,那么你可以通过调整配置来避免该问题。在某些情况下,调低与内存相关的配置参数会有帮助,尤其是shared_bufferswork_memhash_mem_multiplier。在其他情况下,允许数据库服务器接受过多连接也可能导致这一问题。很多时候,更好的做法可能是减小max_connections,并转而使用外部连接池软件。 - + 还可以修改内核行为,使其不再过量分配内存。尽管这种设置无法彻底阻止OOM 杀手被触发,但能显著降低其发生概率,从而得到更稳健的系统行为。这可以通过使用sysctl选择严格的过量分配模式来实现: sysctl -w vm.overcommit_memory=2 @@ -878,26 +844,33 @@ sysctl -w vm.overcommit_memory=2 或者在/etc/sysctl.conf中加入等效设置。你可能还希望修改相关设置vm.overcommit_ratio。详细信息请参阅内核文档中的文件。 - - 另一种方法可在修改或不修改 vm.overcommit_memory 的情况下使用:把 PostgreSQL 主进程的 OOM score adjustment 值设为 -1000,从而保证它不会成为 OOM 杀手的目标。最简单的做法是在 PostgreSQL 启动脚本中、调用 postgres 之前执行以下命令: + + 另一种方法可在修改或不修改 vm.overcommit_memory 的情况下使用: + 把 postmaster 进程专属的OOM 评分调整值设为 -1000, + 从而保证它不会成为 OOM 杀手的目标。最简单的做法是在 postmaster + 启动脚本中、调用 postmaster 之前执行: echo -1000 > /proc/self/oom_score_adj - 请注意,这个操作必须以 root 身份完成,否则不会生效。因此,最容易放置该操作的位置是由 root 拥有的启动脚本。如果这样做,你还应该在调用 postgres 之前,在启动脚本中设置这些环境变量: + 请注意,这个操作必须以 root 身份完成,否则不会生效;因此,由 root 拥有的启动脚本是最容易执行该操作的位置。 + 如果这样做,还应在调用 postmaster 之前,在启动脚本中设置以下环境变量: export PG_OOM_ADJUST_FILE=/proc/self/oom_score_adj export PG_OOM_ADJUST_VALUE=0 - 这些设置会使 postgres 子进程以默认值零的 OOM score adjustment 运行,因此 OOM 杀手在需要时仍可将它们作为目标。如果你希望子进程使用其他 OOM score adjustment 值,也可以为 PG_OOM_ADJUST_VALUE 指定其他数值(也可省略,此时默认为零)。如果不设置 PG_OOM_ADJUST_FILE,子进程就会和主进程使用相同的 OOM score adjustment,这并不明智,因为这样做的目的正是为了确保主进程拥有优先保护设置。 - + 这些设置会使 postmaster 子进程以常规的 OOM 评分调整值零运行,以便 OOM 杀手在需要时仍可将它们作为目标。 + 如果希望子进程以其他 OOM 评分调整值运行,也可以为 PG_OOM_ADJUST_VALUE 指定其他值。 + (也可以省略 PG_OOM_ADJUST_VALUE,此时默认为零。) + 如果不设置 PG_OOM_ADJUST_FILE,子进程就会和 postmaster 使用相同的 OOM 评分调整值, + 这并不明智,因为这样做的目的正是确保 postmaster 获得优先保护。 + - Linux 大页 - + 使用大页可以减少PostgreSQL这类会使用大块连续内存的软件所带来的开销,尤其是在取值较大时。要在PostgreSQL中使用这一特性,你需要一个启用了CONFIG_HUGETLBFS=yCONFIG_HUGETLB_PAGE=y的内核。你还需要把操作系统配置为提供足够多、且大小合适的大页。运行时计算参数会报告所需的大页数量。可以在启动服务器前用如下postgres命令查看: $ postgres -D $PGDATA -C shared_memory_size_in_huge_pages @@ -921,30 +894,31 @@ hugepages-1048576kB hugepages-2048kB 也可以在启动时通过内核参数(例如hugepagesz=2M hugepages=3170)提供这些设置。 - + 有时由于内存碎片,内核无法立即分配所需数量的大页,因此可能需要重复执行该命令,或者重启系统。(重启后,机器上的大部分内存应当都可立即转换为大页。)要检查某一给定大小的大页分配情况,请使用: $ cat /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages - - 你可能还需要授予数据库服务器的操作系统用户使用大页的权限,例如通过sysctl设置vm.hugetlb_shm_group,以及/或者授予其使用ulimit -l锁定内存的权限。 - + + 可能还需要通过 sysctl 设置 vm.hugetlb_shm_group, + 授予数据库服务器的操作系统用户使用大页的权限,以及/或者通过 ulimit -l 授予其锁定内存的权限。 + - + PostgreSQL对大页的默认行为是:只要可能就使用它们,采用系统默认的大页大小;如果失败,则回退到普通页面。要强制使用大页,可以在postgresql.conf中将设为on。请注意,在这种设置下,如果没有足够的大页可用,PostgreSQL将无法启动。 - + 关于Linux大页特性的详细说明,请参见 - + 关闭服务器 @@ -952,7 +926,7 @@ $ cat /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages - 有几种关闭数据库服务器的方法。在后台,它们都简化为向主管 postgres 进程发送信号。 + 有几种关闭数据库服务器的方法。这些方法在内部都是向主管 postgres 进程发送信号。 @@ -994,7 +968,7 @@ $ cat /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepagesSIGQUIT并等待它们终止。 如果有任何进程在 5 秒内未终止,它们将被发送SIGKILL。 一旦所有子进程退出,主管服务器进程将立即退出,而不进行正常的数据库关闭处理。 - 这会导致下次启动时通过回放 WAL 日志执行恢复。仅建议在紧急情况下使用。 + 这会导致下次启动时通过重放 WAL 日志执行恢复。仅建议在紧急情况下使用。 @@ -1009,11 +983,7 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` - - - 最好不要使用SIGKILL关闭服务器。这样做将会阻止服务器释放共享内存和信号量。 - 此外,使用SIGKILL杀掉postgres进程时,postgres不会有机会将信号传播到它的子进程,所以可能也必须手工杀掉单个的子进程。 - + 最好不要使用 SIGKILL 关闭服务器。这样做会阻止服务器释放共享内存和信号量。此外,SIGKILL 会终止 postgres 进程,使其没有机会将信号转发给子进程,因此可能还需要手动逐个终止子进程。 @@ -1022,16 +992,15 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` - 升级 <productname>PostgreSQL</productname> 集簇 - upgrading + 升级 - version - compatibility + 版本 + 兼容性 @@ -1051,7 +1020,7 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` - 新的主版本通常还会引入一些用户可见的不兼容变化,因此应用程序可能也需要做出修改。所有用户可见的变化都列在发行说明()中;请特别留意标为Migration的小节。虽然你可以从一个主版本直接升级到另一个主版本,而不必逐个升级中间版本,但仍应阅读所有中间版本的主版本发行说明。 + 新的主版本通常还会引入一些用户可见的不兼容变化,因此应用程序可能也需要做出修改。所有用户可见的变化都列在发行说明()中;请特别留意标为迁移(Migration)的小节。虽然你可以从一个主版本直接升级到另一个主版本,而不必逐个升级中间版本,但仍应阅读所有中间版本的主版本发行说明。 @@ -1105,12 +1074,10 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` - 服务器端 C 语言 API - - 这涉及以后端函数 API 为代表的变更,该 API 使用 C 语言编写。这类变更会影响那些深入引用服务器内部后端函数的代码。 + 这涉及使用 C 语言编写的后端函数 API 的变更。这类变更会影响那些深入引用服务器内部后端函数的代码。 @@ -1118,32 +1085,30 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` - 通过<application>pg_dumpall</application>升级数据 - 一种升级方法是从某个主版本的PostgreSQL导出数据,再在另一个版本中恢复。要这样做,必须使用逻辑备份工具,例如pg_dumpall;文件系统级备份方法不起作用。(系统中有相应检查,会阻止你在不兼容版本的PostgreSQL上使用某个数据目录,因此即便误用错误版本的服务器去启动某个数据目录,通常也不会造成太大损害。) + 一种升级方法是从某个主版本的PostgreSQL转储数据,再在另一个版本中恢复。要这样做,必须使用逻辑备份工具,例如pg_dumpall;文件系统级备份方法不起作用。(系统中有相应检查,会阻止你在不兼容版本的PostgreSQL上使用某个数据目录,因此即便误用错误版本的服务器去启动某个数据目录,通常也不会造成太大损害。) - + 建议使用来自较新版本PostgreSQLpg_dumppg_dumpall程序,以利用这些程序可能包含的改进。当前版本的转储程序可以读取从 9.2 起任意服务器版本的数据。 - + 以下说明假定你现有的安装位于/usr/local/pgsql目录下,数据区域位于/usr/local/pgsql/data。请根据实际情况替换成你的路径。 - - 如果是在制作备份,请确认数据库此时没有正在进行更新。这不会影响备份的一致性,但那些变更当然不会包含在备份中。必要时,可修改/usr/local/pgsql/data/pg_hba.conf中的访问权限(或采用等效方法),禁止除你之外的其他人访问数据库。有关访问控制的更多信息见。 + 如果是在制作备份,请确认数据库此时没有正在进行更新。更新操作不会影响备份的完整性,但那些变更当然不会包含在备份中。必要时,可修改/usr/local/pgsql/data/pg_hba.conf(或等效文件)中的访问权限,禁止除你之外的其他人访问数据库。有关访问控制的更多信息见 pg_dumpall - use during upgrade + 在升级期间使用 要备份整个数据库安装,请输入: @@ -1158,13 +1123,12 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` - 关闭旧服务器: pg_ctl stop - 在那些会自动启动PostgreSQL的系统上,可能已经有某个启动脚本能完成同样的工作。例如,在Red Hat Linux系统上,也许下面这条命令就可以: + 在那些会在开机时自动启动PostgreSQL的系统上,可能已经有某个启动脚本能完成同样的工作。例如,在Red Hat Linux系统上,也许下面这条命令就可以: /etc/rc.d/init.d/postgresql stop @@ -1173,7 +1137,6 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` - 如果是从备份恢复,请重命名或删除旧的安装目录,前提是它不是按版本区分的目录。与其删除,不如重命名,这样如果你遇到问题需要回退,它仍然还在。请记住,该目录可能会占用相当可观的磁盘空间。要重命名该目录,可以使用类似下面的命令: @@ -1184,14 +1147,10 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` - - - 按照 安装新版本的 PostgreSQL。 - + 按照 安装新版本的 PostgreSQL - 如有需要,创建一个新的数据库集簇。请记住,执行这些命令时必须登录到专用数据库用户账户(如果你正在升级,就已经拥有这个账户)。 @@ -1201,14 +1160,12 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` - 恢复先前的pg_hba.conf,以及你对postgresql.conf所做的任何修改。 - 启动数据库服务器,同样要使用该专门的数据库用户账户: @@ -1218,13 +1175,9 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` - - - 最后,使用新的psql从备份恢复数据: - + 最后,使用以下命令从备份恢复数据: /usr/local/pgsql/bin/psql -d postgres -f outputfile - - 这里务必使用新的psql。 +这里应使用新版 psql @@ -1251,11 +1204,10 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 - 通过复制升级数据 - 也可以使用逻辑复制方法,创建一个运行较新版本PostgreSQL的备库。之所以可行,是因为逻辑复制支持不同主版本PostgreSQL之间进行复制。该备库可以与旧服务器部署在同一台机器上,也可以部署在不同机器上。一旦它与主库(运行旧版本PostgreSQL)同步,就可以切换主备角色,让备库提升为主库,并关闭旧的数据库实例。这种切换通常只会带来几秒钟的停机时间。 + 也可以使用逻辑复制方法,创建一个运行较新版本PostgreSQL的备库。之所以可行,是因为逻辑复制支持不同主版本PostgreSQL之间进行复制。该备库可以与旧服务器部署在同一台机器上,也可以部署在不同机器上。一旦它与主库(运行旧版本PostgreSQL)同步,就可以切换主备角色,让备库提升为主库,并关闭旧的数据库实例。这种切换使升级只需几秒钟的停机时间。 @@ -1265,7 +1217,6 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 - 防止服务器欺骗 @@ -1288,22 +1239,12 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 要防止 TCP 连接上的欺骗,要么使用 SSL 证书并确保客户端检查服务器证书,要么使用 GSSAPI 加密(如果它们分别用于不同连接,也可以两者都用)。 - - 要防止 SSL 欺骗,服务器必须配置为仅接受 hostssl 连接(),并且具备 SSL 密钥和证书文件()。TCP 客户端必须使用 sslmode=verify-caverify-full 连接,并安装适当的根证书文件()。另外,也可使用 SSL 实现定义的系统 CA 池(system CA pool),即设置 sslrootcert=system;出于安全考虑,此时会强制使用 sslmode=verify-full,因为获得由公共 CA 签发的证书通常并不困难。 - + 要通过 SSL 防止服务器欺骗,服务器必须配置为仅接受 hostssl 连接(),并且具备 SSL 密钥和证书文件()。TCP 客户端必须使用 sslmode=verify-caverify-full 连接,并安装适当的根证书文件()。 - - 在网络上使用 scram-sha-256 密码认证时,为防止服务器欺骗,应确保通过 SSL 连接服务器,并使用上一段描述的任一防欺骗方法。此外,libpq 中的 SCRAM 实现无法保护整个认证交换过程,但使用连接参数 channel_binding=require 可对服务器欺骗提供一定缓解。攻击者若用伪造服务器拦截 SCRAM 交换,可能通过离线分析推导出客户端哈希密码。 - - - - 要防止 GSSAPI 欺骗,必须将服务器配置为仅接受hostgssenc连接 () 并对它们使用gss认证。 - TCP 客户端则必须使用 gssencmode=require 发起连接。 - + 要通过 GSSAPI 防止服务器欺骗,服务器必须配置为仅接受 hostgssenc 连接(),并对这些连接使用 gss 认证。TCP 客户端必须使用 gssencmode=require 连接。 - 加密选项 @@ -1311,7 +1252,7 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 - PostgreSQL提供了多个层次的加密,并在防止数据因数据库服务器被盗、不可靠的管理员或不安全网络等原因而泄露方面提供了很高的灵活性。对于医疗记录、金融交易等敏感数据,加密也可能是合规要求的一部分。 + PostgreSQL提供了多个层次的加密,并在防止数据因数据库服务器被盗、不诚实的管理员或不安全网络等原因而泄露方面提供了很高的灵活性。为了保护医疗记录、金融交易等敏感数据,也可能需要使用加密。 @@ -1325,11 +1266,7 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 数据库用户密码以哈希形式存储(由 控制),因此管理员无法得知分配给用户的实际密码。如果客户端认证使用 SCRAM 或 MD5,明文密码甚至不会暂时出现在服务器端,因为客户端会在通过网络发送前完成加密。推荐使用 SCRAM,因为它是互联网标准,并且比 PostgreSQL 特有的 MD5 认证协议更安全。 - - - 对 MD5 加密密码的支持已弃用,并将在未来版本的 PostgreSQL 中移除。迁移到其他密码类型的细节见 。 - - + @@ -1415,7 +1352,6 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 - 使用 SSL 的安全 TCP/IP 连接 @@ -1431,7 +1367,6 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 术语SSLTLS经常被交替使用,用来表示基于TLS协议的安全加密连接。SSL协议是TLS协议的前身,尽管SSL协议本身已不再受支持,SSL一词仍常被用来泛指这类加密连接。在PostgreSQL中,SSLTLS也是这样互换使用的。 - 基本设置 @@ -1451,7 +1386,7 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 - 如果私钥受密码保护,服务器会提示输入该密码,并在输入之前不会启动。默认情况下,使用密码会禁用无需重启服务器即可更改 SSL 配置的能力,不过参见。此外,在 Windows 上完全无法使用带密码保护的私钥。 + 如果私钥受口令保护,服务器会提示输入该口令,并在输入之前不会启动。默认情况下,使用口令会禁用无需重启服务器即可更改 SSL 配置的能力,不过参见。此外,在 Windows 上完全无法使用带口令保护的私钥。 @@ -1464,7 +1399,6 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 - OpenSSL 配置 @@ -1476,9 +1410,8 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 - - 使用NULL-SHANULL-MD5密码套件,可以在几乎没有加密开销的情况下完成认证。不过,中间人仍然能够读取并转发客户端与服务器之间的通信。此外,与认证的开销相比,加密开销本身通常很小。基于这些原因,不建议使用 NULL 密码套件。 + 使用NULL-SHANULL-MD5密码套件,可以在没有加密开销的情况下完成认证。不过,中间人仍然能够读取并转发客户端与服务器之间的通信。此外,与认证的开销相比,加密开销本身很小。基于这些原因,不建议使用 NULL 密码套件。 @@ -1688,7 +1621,6 @@ openssl x509 -req -in server.csr -text -days 365 \ - 通过 <application>SSH</application> 隧道建立安全 TCP/IP 连接 @@ -1711,9 +1643,7 @@ psql -h localhost -p 63333 postgres 对数据库服务器来说,它看到的是来自主机foo.com上用户joelocalhost绑定地址的连接,并将应用为该用户到该绑定地址所配置的认证方式。请注意,服务器不会认为这是 SSL 加密连接,因为实际上SSH服务器与PostgreSQL服务器之间并没有加密。不过这通常不会带来额外安全风险,因为两者位于同一台机器上。 - - 要让这条隧道建立成功,你必须能够像建立终端会话那样,通过sshjoe@foo.com身份连接。 - + 要让这条隧道建立成功,你必须有权通过 sshjoe@foo.com 身份连接,就像尝试使用 ssh 创建终端会话一样。 你也可以把端口转发设成这样: @@ -1732,7 +1662,6 @@ ssh -L 63333:db.foo.com:5432 joe@shell.foo.com - 还有一些其他应用也能提供安全隧道,其思路与刚才描述的 SSH 方法类似。 diff --git a/zh/15/sepgsql.sgml b/zh/15/sepgsql.sgml index a8e6d416..78cc0db5 100644 --- a/zh/15/sepgsql.sgml +++ b/zh/15/sepgsql.sgml @@ -75,15 +75,7 @@ Policy from config file: targeted 它,之后才能安装本模块。 - - 要构建此模块,使用 make 和 autoconf 时请指定 ,使用 meson 时请指定 。 - - 还要确保构建时已经安装 libselinux-devel RPM。 - + 要构建此模块,请将选项 --with-selinux 加入 PostgreSQL 的 configure 命令中。还要确保构建时已经安装 libselinux-devel RPM。 要使用此模块,必须将 sepgsql 包含在 diff --git a/zh/15/sourcerepo.sgml b/zh/15/sourcerepo.sgml index 8b27c3b1..997ce588 100644 --- a/zh/15/sourcerepo.sgml +++ b/zh/15/sourcerepo.sgml @@ -13,9 +13,10 @@ - 请注意,从源代码仓库构建PostgreSQL需要使用相当新版本的bisonflexPerl。这些工具不需要 - 用于从发行版 tarball 构建,因为这些工具用于构建的文件已经包含在 tarball 中。其他工具 - 要求与中所示相同。 + 请注意,从源代码仓库构建PostgreSQL需要版本相当新的 + bisonflexPerl。 + 从发行版 tarball 构建则不需要这些工具,因为这些工具生成的文件已经包含在 tarball 中。 + 其他工具要求与中的说明相同。 diff --git a/zh/15/spgist.sgml b/zh/15/spgist.sgml index c1d2626e..809ed209 100644 --- a/zh/15/spgist.sgml +++ b/zh/15/spgist.sgml @@ -4,11 +4,11 @@ SP-GiST 索引 - index + 索引 SP-GiST - + 简介 @@ -43,13 +43,13 @@ 上还有更多信息。 - + - + 内置操作符类 - 核心 PostgreSQL 发行版包含了 + PostgreSQL 核心发行版包含了 SP-GiST 操作符类,如 所示。 @@ -183,9 +183,9 @@ (k-NN)搜索。 - + - + 可扩展性 @@ -232,11 +232,11 @@ - SP-GiST 核心代码会处理空项。虽然 - SP-GiST 索引确实会为被索引列中的空值存储项,但这一 - 点对索引操作符类代码是隐藏的:不会有空的索引项或搜索条件传递给操作符类 - 方法。(这里假定 SP-GiST 操作符是严格的,因此对空 - 值不可能成功。)因此,这里不再进一步讨论空值。 + SP-GiST 核心代码负责处理值为 null 的索引项。虽然 + SP-GiST 索引会为被索引列中的 null 值存储索引项, + 但索引操作符类代码看不到这些项:值为 null 的索引项或搜索条件绝不会传给 + 操作符类方法。(这里假定 SP-GiST 操作符是严格的, + 因此对 null 值不可能返回真。)所以这里不再讨论 null 值。 @@ -286,8 +286,8 @@ typedef struct spgConfigOut Oid prefixType; /* 内部元组前缀的数据类型 */ Oid labelType; /* 内部元组结点标签的数据类型 */ Oid leafType; /* 叶子元组值的数据类型 */ - bool canReturnData; /* 操作符类能重构原始数据 */ - bool longValuesOK; /* 操作符类能处理值 > 1 页 */ + bool canReturnData; /* 操作符类能重建原始数据 */ + bool longValuesOK; /* 操作符类能处理大小 > 1 页的值 */ } spgConfigOut; @@ -314,7 +314,7 @@ typedef struct spgConfigOut 类型与操作符类的输入类型相同,这也是最常见的情况。)出于向后兼容的原 因,config 方法也可以将 leafType 设为其他值,并且该值将被使用; - 但这已被废弃,因为这样会导致目录中对索引内容的标识不正确。此外,也允 + 但这已被弃用,因为这样会导致目录中对索引内容的标识不正确。此外,也允 许不初始化 leafType(即保持为零);这会 被解释为使用从 opckeytype 派生的索引存 储类型。 @@ -354,7 +354,7 @@ typedef struct spgChooseIn int level; /* 当前层级(从零开始计) */ /* 来自当前内部元组的数据 */ - bool allTheSame; /* 元组被标记为 all-the-same? */ + bool allTheSame; /* 元组被标记为全部相同? */ bool hasPrefix; /* 元组有前缀? */ Datum prefixDatum; /* 如果有,前缀值 */ int nNodes; /* 内部元组中的结点数 */ @@ -594,14 +594,14 @@ typedef struct spgInnerConsistentIn int nkeys; /* scankeys 数组的长度 */ int norderbys; /* orderbys 数组的长度 */ - Datum reconstructedValue; /* 在父元组处重构的值 */ + Datum reconstructedValue; /* 在父元组处重建的值 */ void *traversalValue; /* 操作符类特定的遍历值 */ MemoryContext traversalMemoryContext; /* 将新的遍历值放在这里 */ int level; /* 当前层级(从零开始计) */ bool returnData; /* 必须返回原始数据? */ /* 来自当前内部元组的数据 */ - bool allTheSame; /* 元组被标记为 all-the-same? */ + bool allTheSame; /* 元组被标记为全部相同? */ bool hasPrefix; /* 元组有前缀? */ Datum prefixDatum; /* 如果有,前缀值 */ int nNodes; /* 内部元组中的结点数 */ @@ -613,7 +613,7 @@ typedef struct spgInnerConsistentOut int nNodes; /* 需要访问的子结点数 */ int *nodeNumbers; /* 它们在结点数组中的索引 */ int *levelAdds; /* 对每个结点层级增加这么多 */ - Datum *reconstructedValues; /* 关联的重构值 */ + Datum *reconstructedValues; /* 关联的重建值 */ void **traversalValues; /* 操作符类特定的遍历值 */ double **distances; /* 关联距离 */ } spgInnerConsistentOut; @@ -624,7 +624,7 @@ typedef struct spgInnerConsistentOut 用 AND 组合 — 只有满足全部条件的索引项才是我们关心的。(注 意, nkeys = 0 表示所有索引项都满足该查 - 询。)通常 consistent 函数只关心每个数组元素的 + 询。)通常一致性检查函数只关心每个数组元素的 sk_strategysk_argument 字段,它们分别给出可索引操 作符和比较值。特别地,无需检查 sk_flags @@ -641,9 +641,8 @@ typedef struct spgInnerConsistentOut 遍历值(见下文)的内存上下文。level 是 当前内部元组的层级,根层为零。如果本查询需要重建数据,则 returnDatatrue; - 只有在 config 函数声明了 - canReturnData 时才会如此。若当前内部元组 - 被标记为 all-the-same,则 + 只有在 config 函数将 canReturnData 设为真时才会如此。若当前内部元组 + 被标记为 全部相同,则 allTheSame 为真;在这种情况下,所有结点 都具有相同的标签(如果有),因此要么全部匹配该查询,要么全部不匹配 (参见 )。若当前内部元组包 @@ -663,8 +662,7 @@ typedef struct spgInnerConsistentOut 非必然如此,所以这里使用数组。)如果需要值重建,则将 reconstructedValues 设为一个数组,其中包 含为每个待访问子结点重建的值;否则,将 - reconstructedValues 保持为 NULL。重构 - 值假定具有 spgConfigOut.leafType + reconstructedValues 保持为 NULL。重建的值假定具有 spgConfigOut.leafType 类型。(不过,由于核心系统除了可能复制它们以外不会对其做任何处理,只 要它们具有与 leafType 相同的 typlentypbyval 属性就足 @@ -713,7 +711,7 @@ typedef struct spgLeafConsistentIn int nkeys; /* scankeys 数组的长度 */ int norderbys; /* orderbys 数组的长度 */ - Datum reconstructedValue; /* 在父元组处重构的值 */ + Datum reconstructedValue; /* 在父元组处重建的值 */ void *traversalValue; /* 操作符类特定的遍历值 */ int level; /* 当前层级(从零开始计) */ bool returnData; /* 必须返回原始数据? */ @@ -723,7 +721,7 @@ typedef struct spgLeafConsistentIn typedef struct spgLeafConsistentOut { - Datum leafValue; /* 重构出的原始数据(如果有) */ + Datum leafValue; /* 重建出的原始数据(如果有) */ bool recheck; /* 如果必须重新检查操作符则设为真 */ bool recheckDistances; /* 如果必须重新检查距离则设为真 */ double *distances; /* 关联距离 */ @@ -734,7 +732,7 @@ typedef struct spgLeafConsistentOut scankeys 数组描述索引搜索条件。这些条件 用 AND 组合在一起 — 只有满足全部条件的索引项才满足该查询。(注 意 nkeys = 0 表示所有索引项都满足该查 - 询。)通常 consistent 函数只关心每个数组元素的 + 询。)通常一致性检查函数只关心每个数组元素的 sk_strategysk_argument 字段,它们分别给出可索引操 作符和比较值。特别地,无需检查 sk_flags @@ -750,8 +748,7 @@ typedef struct spgLeafConsistentOut NULL。level 是当前叶子元组的层级,根层为 零。如果本查询需要重建数据,则 returnDatatrue; - 只有在 config 函数声明了 - canReturnData 时才会如此。 + 只有在 config 函数将 canReturnData 设为真时才会如此。 leafDatum 是当前叶子元组中存储的、类型为 spgConfigOut.leafType 的键值。 @@ -844,13 +841,13 @@ LANGUAGE C STRICT; - 如果被索引列属于可应用排序规则的数据类型,则索引排序规则会通过标准的 + 如果被索引列属于支持排序规则的数据类型,则索引排序规则会通过标准的 PG_GET_COLLATION() 机制传递给所有支持方法。 - + - + 实现 @@ -858,7 +855,7 @@ LANGUAGE C STRICT; 现者有用的技巧。 - + SP-GiST 限制 @@ -895,9 +892,9 @@ LANGUAGE C STRICT; 用 choose 方法之后叶子 datum 仍没有变小, SP-GiST 核心就会报错。 - + - + 无结点标签的 SP-GiST @@ -919,10 +916,10 @@ LANGUAGE C STRICT; spgAddNode 是错误的,因为在这种情况下结点集合应被 视为固定不变。 - + - - <quote>All-the-Same</quote> 内部元组 + + <quote>全部相同</quote>的内部元组 picksplit 无法把提供的叶子值划分为至少两个结点 @@ -954,11 +951,11 @@ LANGUAGE C STRICT; 况代码,取决于 inner_consistent 函数平常对这些结 点含义做了多大程度的假定。 - - - + + + 示例 @@ -969,6 +966,6 @@ LANGUAGE C STRICT; src/backend/utils/adt/ - + diff --git a/zh/15/spi.sgml b/zh/15/spi.sgml index b4b8b0e2..4bf4e18a 100644 --- a/zh/15/spi.sgml +++ b/zh/15/spi.sgml @@ -76,7 +76,7 @@ int SPI_connect_ext(int options) SPI_connect 会为某次 C 函数调用打开到 SPI 管理器 的连接。如果要通过 SPI 执行命令,就必须调用此函数。不过,有些 SPI - 实用函数可以在未连接的 C 函数中调用。 + 辅助函数可以在未连接的 C 函数中调用。 @@ -114,15 +114,16 @@ int SPI_connect_ext(int options) - - - 这些函数返回 int 而不是 void 属于历史遗留设 - 计。所有失败情况都通过 ereport 或 - elog 报告。(在 - PostgreSQL v10 之前,部分但并非全部失败会以 - SPI_ERROR_CONNECT 作为结果值报告。) - + + SPI_ERROR_CONNECT + + + 发生错误时 + + + + @@ -276,8 +277,7 @@ SPI_execute("INSERT INTO foo SELECT * FROM bar RETURNING *", false, 5); SPI_OK_SELECTSPI_OK_INSERT_RETURNINGSPI_OK_DELETE_RETURNING、 - SPI_OK_UPDATE_RETURNING 或 - SPI_OK_MERGE_RETURNING,则可以通过全局指针 + SPI_OK_UPDATE_RETURNING,则可以通过全局指针 SPITupleTable *SPI_tuptable 访问结果行。有些工具命令 (如 EXPLAIN)也会返回结果行集,此时 SPI_tuptable 同样会保存结果。另一些工具命令 @@ -291,16 +291,16 @@ SPI_execute("INSERT INTO foo SELECT * FROM bar RETURNING *", false, 5); typedef struct SPITupleTable { - /* Public members */ - TupleDesc tupdesc; /* tuple descriptor */ - HeapTuple *vals; /* array of tuples */ - uint64 numvals; /* number of valid tuples */ - - /* Private members, not intended for external callers */ - uint64 alloced; /* allocated length of vals array */ - MemoryContext tuptabcxt; /* memory context of result table */ - slist_node next; /* link for internal bookkeeping */ - SubTransactionId subid; /* subxact in which tuptable was created */ + /* 公共成员 */ + TupleDesc tupdesc; /* 元组描述符 */ + HeapTuple *vals; /* 元组数组 */ + uint64 numvals; /* 有效元组数 */ + + /* 私有成员,不供外部调用者使用 */ + uint64 alloced; /* vals 数组的已分配长度 */ + MemoryContext tuptabcxt; /* 结果表的内存上下文 */ + slist_node next; /* 用于内部管理的链接 */ + SubTransactionId subid; /* 创建 tuptable 的子事务 */ } SPITupleTable; SPI 调用者可以使用 tupdesc、 @@ -439,15 +439,6 @@ typedef struct SPITupleTable - - SPI_OK_MERGE_RETURNING - - - 执行了 MERGE RETURNING - - - - SPI_OK_UTILITY @@ -471,7 +462,7 @@ typedef struct SPITupleTable - 发生错误时,则返回下列负值之一: + 出错时,返回以下负值之一: @@ -521,7 +512,7 @@ typedef struct SPITupleTable SPI_ERROR_UNCONNECTED - 从未连接的 C 函数中调用 + 如果从一个未连接的 C 函数中调用 @@ -534,9 +525,9 @@ typedef struct SPITupleTable 所有 SPI 查询执行函数都会设置 SPI_processed 和 - SPI_tuptable(只设置指针,而不会复制结构体内容)。如果 + SPI_tuptable(只设置指针,而不更改结构体内容)。如果 需要在后续调用之后继续访问 SPI_execute 或其他查询 - 执行函数的结果表,请把这两个全局变量保存到本地 C 函数变量中。 + 执行函数的结果表,请把这两个全局变量保存到 C 函数的局部变量中。 @@ -581,7 +572,7 @@ int SPI_exec(const char * command, long count< const char * command - 包含要执行命令的字符串 + 包含待执行命令的字符串 @@ -590,7 +581,7 @@ int SPI_exec(const char * command, long count< long count - 要返回的最大行数,或者用0表示没有限制 + 要返回的最大行数,或者用 0 表示不限制 @@ -821,7 +812,7 @@ int SPI_execute_with_args(const char *command, SPI_execute_plan 达到类似效果。不过,使用本函数 时,查询计划总会针对所提供的具体参数值进行定制。对于一次性查询执行,应 优先选择本函数。如果同一条命令要用许多不同参数重复执行,则两种方式孰快 - 取决于重新计划的代价与定制计划收益之间的权衡。 + 取决于重新规划的代价与定制计划收益之间的权衡。 @@ -876,9 +867,9 @@ int SPI_execute_with_args(const char *command, 如果 nullsNULL,则 - SPI_execute_with_args 会假定没有参数为 NULL。 - 否则,如果对应参数值非 NULL,则 nulls 数组中 - 的对应项应为 ' ';如果对应参数值为 NULL,则 + SPI_execute_with_args 会假定没有参数为空值。 + 否则,如果对应参数值非空值,则 nulls 数组中 + 的对应项应为 ' ';如果对应参数值为空值,则 对应项应为 'n'。(后一种情况下,对应 values 项中的实际值无关紧要。)注意, nulls 不是文本字符串,而只是一个数组,因此不 @@ -932,7 +923,7 @@ int SPI_execute_with_args(const char *command, SPI_prepare - 准备一个语句,但不执行它 + 准备一个语句,但暂不执行 @@ -1011,8 +1002,7 @@ SPIPlanPtr SPI_prepare(const char * command, int 返回值 - SPI_prepare 返回一个指向非空 SPIPlan - 的指针,它是表示预备语句的不透明结构体。发生错误时会返回 + SPI_prepare 返回一个非空指针,指向表示预备语句的不透明结构体 SPIPlan。发生错误时会返回 NULL,并将 SPI_result 设为 SPI_execute 所使用的那些错误码之一;但如果 commandNULL,或者 @@ -1031,17 +1021,16 @@ SPIPlanPtr SPI_prepare(const char * command, int SPI_execute_plan 在最初几次使用时会根据提供的参数 值生成定制计划。当同一个预备语句被使用足够多次之后, SPI_execute_plan 会构建一个通用计划;如果它的代价 - 没有比定制计划高出太多,就会开始改用通用计划,而不是每次都重新计划。如 + 没有比定制计划高出太多,就会开始改用通用计划,而不是每次都重新规划。如 果这种默认行为不合适,可以把 CURSOR_OPT_GENERIC_PLANCURSOR_OPT_CUSTOM_PLAN 标志传给 SPI_prepare_cursor,分别强制使用通用计划或定制计划。 - 尽管预备语句的主要目的在于避免重复进行解析分析和计划,但只要语句中使用 + 尽管预备语句的主要目的在于避免重复进行解析分析和规划,但只要语句中使用 的数据库对象自上次使用该预备语句以来发生了定义性(DDL)变更, - PostgreSQL 就会在再次使用前强制重新分析并重 - 新计划该语句。此外,如果 的值在两次 + PostgreSQL 就会在再次使用前强制重新分析并重新规划该语句。此外,如果 的值在两次 使用之间发生变化,该语句也会基于新的 search_path 重 新解析。(后一种行为是从 PostgreSQL 9.3 开 始引入的。)有关预备语句行为的更多信息,请参见 @@ -1101,7 +1090,7 @@ SPIPlanPtr SPI_prepare_cursor(const char * command, int < - 此函数现已废弃,推荐改用 SPI_prepare_extended。 + 此函数现已弃用,推荐改用 SPI_prepare_extended @@ -1131,7 +1120,7 @@ SPIPlanPtr SPI_prepare_cursor(const char * command, int < Oid * argtypes - 指向数组的指针,该数组包含参数数据类型的 + 一个数组指针,它指向的数组包含参数的数据类型的 OID @@ -1200,7 +1189,7 @@ SPIPlanPtr SPI_prepare_extended(const char * command, SPI_prepare_extended 为指定命令创建并返回一个预备语 句,但并不执行该命令。它相当于 SPI_prepare,并额外 - 允许调用者指定选项,以控制外部参数引用的解析,以及查询解析和计划的其他 + 允许调用者指定选项,以控制外部参数引用的解析,以及查询解析和规划的其他 方面。 @@ -1240,7 +1229,7 @@ SPIPlanPtr SPI_prepare_extended(const char * command, ParserSetupHook parserSetup - 语法分析器钩子设置函数 + 解析器钩子设置函数 @@ -1318,7 +1307,7 @@ SPIPlanPtr SPI_prepare_params(const char * command, - 此函数现已废弃,推荐改用 SPI_prepare_extended。 + 此函数现已弃用,推荐改用 SPI_prepare_extended @@ -1339,7 +1328,7 @@ SPIPlanPtr SPI_prepare_params(const char * command, ParserSetupHook parserSetup - 语法分析器钩子设置函数 + 解析器钩子设置函数 @@ -1554,8 +1543,8 @@ bool SPI_is_cursor_plan(SPIPlanPtr plan) 返回值 - 如果 plan 能产生游标,则返回 - true;如果不能,则返回 false,并将 + 返回 truefalse,表示 + plan 能否产生游标,同时将 SPI_result 设为零。如果无法确定答案(例如 planNULL 或无效,或者在 未连接到 SPI 时调用),则会将 SPI_result 设为合适 @@ -1627,15 +1616,14 @@ int SPI_execute_plan(SPIPlanPtr plan, Datum * - 如果nullsNULL, - 那么SPI_execute_plan会假设没有参数 - 为空值。否则,如果对应的参数值为非空, - nulls - 数组的每一个项都应该是' ';如果对应参数值为空, - nulls数组的项应为'n'(在后 - 面的情况中,对应的values项中的值没有 - 关系)。注意nulls不是一个文本字符串, - 它只是一个数组:它不需要一个'\0'终止符。 + 如果 nullsNULL,则 + SPI_execute_plan 会假定没有参数为空值。 + 否则,如果对应参数值非空值,则 nulls 数组中 + 的对应项应为 ' ';如果对应参数值为空值,则 + 对应项应为 'n'。(后一种情况下,对应 + values 项中的实际值无关紧要。)注意, + nulls 不是文本字符串,而只是一个数组,因此不 + 需要 '\0' 终止符。 @@ -1708,7 +1696,7 @@ int SPI_execute_plan(SPIPlanPtr plan, Datum * SPI_execute_plan_extended - 执行一个由SPI_prepare准备的语句 + 执行由 SPI_prepare 准备好的语句 @@ -1793,8 +1781,9 @@ int SPI_execute_plan_extended(SPIPlanPtr plan, bool allow_nonatomic - true 允许以非原子方式执行 CALL 与 DO 语句 - (但除非向 SPI_connect_ext 传入了 + true 允许以非原子方式执行 CALL + 和 DO 语句(但除非向 + SPI_connect_ext 传入了 SPI_OPT_NONATOMIC 标志,否则该字段会被忽略) @@ -1814,7 +1803,7 @@ int SPI_execute_plan_extended(SPIPlanPtr plan, uint64 tcount - 要返回的最大行数,或者用0表示没有限制 + 要返回的最大行数,或者用 0 表示不限制 @@ -1899,7 +1888,7 @@ int SPI_execute_plan_with_paramlist(SPIPlanPtr plan, - 此函数现已废弃,推荐改用 SPI_execute_plan_extended。 + 此函数现已弃用,推荐改用 SPI_execute_plan_extended @@ -1936,7 +1925,7 @@ int SPI_execute_plan_with_paramlist(SPIPlanPtr plan, long count - 要返回的最大行数,或者用0表示没有限制 + 要返回的最大行数,或者用 0 表示不限制 @@ -2020,15 +2009,14 @@ int SPI_execp(SPIPlanPtr plan, Datum * values< - 如果nullsNULL, - 那么SPI_execp会假设没有参数 - 为空值。否则,如果对应的参数值为非空, - nulls - 数组的每一个项都应该是' ';如果对应参数值为空, - nulls数组的项应为'n'(在后 - 面的情况中,对应的values项中的值没有 - 关系)。注意nulls不是一个文本字符串, - 它只是一个数组:它不需要一个'\0'终止符。 + 如果 nullsNULL,则 + SPI_execp 会假定没有参数为空值。 + 否则,如果对应参数值非空值,则 nulls 数组中 + 的对应项应为 ' ';如果对应参数值为空值,则 + 对应项应为 'n'。(后一种情况下,对应 + values 项中的实际值无关紧要。)注意, + nulls 不是文本字符串,而只是一个数组,因此不 + 需要 '\0' 终止符。 @@ -2037,7 +2025,7 @@ int SPI_execp(SPIPlanPtr plan, Datum * values< long count - 要返回的最大行数,或者用0表示没有限制 + 要返回的最大行数,或者用 0 表示不限制 @@ -2145,15 +2133,14 @@ Portal SPI_cursor_open(const char * name, SPIPlanPtr - 如果nullsNULL, - 那么SPI_cursor_open会假设没有参数 - 为空值。否则,如果对应的参数值为非空, - nulls - 数组的每一个项都应该是' ';如果对应参数值为空, - nulls数组的项应为'n'(在后 - 面的情况中,对应的values项中的值没有 - 关系)。注意nulls不是一个文本字符串, - 它只是一个数组:它不需要一个'\0'终止符。 + 如果 nullsNULL,则 + SPI_cursor_open 会假定没有参数为空值。 + 否则,如果对应参数值非空值,则 nulls 数组中 + 的对应项应为 ' ';如果对应参数值为空值,则 + 对应项应为 'n'。(后一种情况下,对应 + values 项中的实际值无关紧要。)注意, + nulls 不是文本字符串,而只是一个数组,因此不 + 需要 '\0' 终止符。 @@ -2214,11 +2201,10 @@ Portal SPI_cursor_open_with_args(const char *name, - 对于一次性的查询执行,这个函数应该比 - SPI_prepare_cursor加上其后的 - SPI_cursor_open更好。如果相同的命令 - 要被用很多不同的参数执行,哪种方法更快就要取决于重做计划的 - 代价与定制计划带来的好处之间谁更有利。 + 对于一次性查询执行,应优先使用此函数,而不是先调用 + SPI_prepare_cursor 再调用 + SPI_cursor_open。如果同一条命令要用许多不同参数执行, + 哪种方法更快取决于重新规划的代价与定制计划收益之间的权衡。 @@ -2227,7 +2213,7 @@ Portal SPI_cursor_open_with_args(const char *name, - 此函数现已废弃,推荐改用 SPI_cursor_parse_open, + 此函数现已弃用,推荐改用 SPI_cursor_parse_open, 它提供了等价的功能,并使用更现代的查询参数处理 API。 @@ -2267,8 +2253,8 @@ Portal SPI_cursor_open_with_args(const char *name, Oid * argtypes - 一个长度为nargs的数组, - 包含参数的数据类型的OID + 一个长度为 nargs 的数组,包含参数数据类型的 + OID @@ -2277,8 +2263,7 @@ Portal SPI_cursor_open_with_args(const char *name, Datum * values - 一个长度为nargs的数组, - 包含实际的参数值 + 一个长度为 nargs 的数组,包含实际参数值 @@ -2287,20 +2272,19 @@ Portal SPI_cursor_open_with_args(const char *name, const char * nulls - 一个长度为nargs的数组, - 描述哪些参数为空值 + 一个长度为 nargs 的数组,用于描述哪些参数为 + 空值 - 如果nullsNULL, - 那么SPI_cursor_open_with_args会假设没有参数 - 为空值。否则,如果对应的参数值为非空, - nulls - 数组的每一个项都应该是' ';如果对应参数值为空, - nulls数组的项应为'n'(在后 - 面的情况中,对应的values项中的值没有 - 关系)。注意nulls不是一个文本字符串, - 它只是一个数组:它不需要一个'\0'终止符。 + 如果 nullsNULL,则 + SPI_cursor_open_with_args 会假定没有参数为空值。 + 否则,如果对应参数值非空值,则 nulls 数组中 + 的对应项应为 ' ';如果对应参数值为空值,则 + 对应项应为 'n'。(后一种情况下,对应 + values 项中的实际值无关紧要。)注意, + nulls 不是文本字符串,而只是一个数组,因此不 + 需要 '\0' 终止符。 @@ -2437,7 +2421,7 @@ Portal SPI_cursor_open_with_paramlist(const char *name, SPI_cursor_parse_open - 使用查询字符串和参数设置游标 + 使用查询字符串和参数建立游标 @@ -2463,7 +2447,7 @@ Portal SPI_cursor_parse_open(const char *name, 对于一次性查询执行,推荐优先使用此函数,而不是 SPI_prepare_cursorSPI_cursor_open_with_paramlist 的组合。如果同一条命 - 令要用很多不同参数执行,两种方法孰快则取决于重新计划的代价与定制计划带 + 令要用很多不同参数执行,两种方法孰快则取决于重新规划的代价与定制计划带 来的收益之间的权衡。 @@ -2700,7 +2684,7 @@ void SPI_cursor_fetch(Portal portal, bool forw 如果该游标的计划不是用CURSOR_OPT_SCROLL - 选项创建的,向后获取会失败。 + 选项创建的,向后获取可能失败。 @@ -2774,7 +2758,7 @@ void SPI_cursor_move(Portal portal, bool forwa 如果该游标的计划不是用CURSOR_OPT_SCROLL - 选项创建的,向后移动会失败。 + 选项创建的,向后移动可能失败。 @@ -2870,8 +2854,7 @@ void SPI_scroll_cursor_fetch(Portal portal, FetchDirectio 如果该游标的计划不是用CURSOR_OPT_SCROLL - 选项创建的,除FETCH_FORWARD之外的方向值会 - 失败。 + 选项创建的,除FETCH_FORWARD之外的方向值可能失败。 @@ -2968,8 +2951,7 @@ void SPI_scroll_cursor_move(Portal portal, FetchDirection 如果该游标的计划不是用CURSOR_OPT_SCROLL - 选项创建的,除FETCH_FORWARD之外的方向值会 - 失败。 + 选项创建的,除FETCH_FORWARD之外的方向值可能失败。 @@ -3191,8 +3173,8 @@ SPIPlanPtr SPI_saveplan(SPIPlanPtr plan) SPI_register_relation - ephemeral named relation - registering with SPI + 临时命名关系 + 向 SPI 注册 @@ -3216,7 +3198,7 @@ int SPI_register_relation(EphemeralNamedRelation enr) SPI_register_relation 使一个带有相关信息的临时命名关 - 系对通过当前 SPI 连接计划和执行的查询可用。 + 系对通过当前 SPI 连接规划和执行的查询可用。 @@ -3254,7 +3236,7 @@ int SPI_register_relation(EphemeralNamedRelation enr) - 在出错时,会返回下列负值之一: + 出错时,返回以下负值之一: @@ -3296,8 +3278,8 @@ int SPI_register_relation(EphemeralNamedRelation enr) SPI_unregister_relation - ephemeral named relation - unregistering from SPI + 临时命名关系 + 从 SPI 注销 @@ -3344,7 +3326,7 @@ int SPI_unregister_relation(const char * name) 返回值 - 如果该命令的执行成功,则会返回下列(非负)值: + 如果该命令的执行成功,则将返回下列(非负)值: @@ -3359,7 +3341,7 @@ int SPI_unregister_relation(const char * name) - 出现错误时,会返回下列负值之一: + 出错时,返回以下负值之一: @@ -3399,13 +3381,13 @@ int SPI_unregister_relation(const char * name) SPI_register_trigger_data - ephemeral named relation - registering with SPI + 临时命名关系 + 向 SPI 注册 - transition tables - implementation in PLs + 过渡表 + 在 PL 中实现 @@ -3429,8 +3411,8 @@ int SPI_register_trigger_data(TriggerData *tdata) SPI_register_trigger_data 使触发器捕获的所有临时关系 - 都能在通过当前 SPI 连接计划和执行的查询中使用。目前,这指的是通过 - REFERENCING OLD/NEW TABLE AS ... 子句定义、并由 + 都能在通过当前 SPI 连接规划和执行的查询中使用。目前,这指的是由带有 + REFERENCING OLD/NEW TABLE AS ... 子句的 AFTER 触发器捕获的过渡表。PL 触发器处理函数应在建 立 SPI 连接后调用此函数。 @@ -3456,7 +3438,7 @@ int SPI_register_trigger_data(TriggerData *tdata) 返回值 - 如果命令的执行成功,则会返回下列(非负)值: + 如果该命令的执行成功,则将返回下列(非负)值: @@ -3471,7 +3453,7 @@ int SPI_register_trigger_data(TriggerData *tdata) - 出现错误时,会返回下列负值之一: + 出错时,返回以下负值之一: @@ -3728,7 +3710,7 @@ char * SPI_getvalue(HeapTuple row, TupleDesc r 返回值 - 列值;如果该列为 NULL、colnumber 超出范围 + 列值;如果该列为空值、colnumber 超出范围 (SPI_result 被设置为 SPI_ERROR_NOATTRIBUTE)或者没有输出函数 可用(SPI_result 被设置为 @@ -3820,8 +3802,8 @@ Datum SPI_getbinval(HeapTuple row, TupleDesc r 返回值 - 返回该列的二进制值。如果该列为 NULL,则 - isnull 指向的变量会被设为 true,否则设为 false。 + 返回该列的二进制值。如果该列为空值,则 + isnull 指向的变量会被设为真,否则设为假。 @@ -3857,7 +3839,7 @@ char * SPI_gettype(TupleDesc rowdesc, int coln SPI_gettype返回该指定列的数据类型名称 - 的拷贝(当你不再需要该拷贝后,可以使用pfree + 的副本(当你不再需要该副本后,可以使用pfree 释放它)。 @@ -3989,7 +3971,7 @@ char * SPI_getrelname(Relation rel) SPI_getrelname返回该指定关系的名称 - 的拷贝(当你不再需要该拷贝后,可以使用pfree + 的副本(当你不再需要该副本后,可以使用pfree 释放它)。 @@ -4082,7 +4064,7 @@ char * SPI_getnspname(Relation rel) SPI_result_code_string - 将结果代码表示为字符串 + 返回错误码的字符串表示 @@ -4096,7 +4078,7 @@ const char * SPI_result_code_string(int code); SPI_result_code_string 返回各种 SPI 函数返回的,或 - 存放在 SPI_result 中的结果代码的字符串表示。 + 存放在 SPI_result 中的结果码的字符串表示。 @@ -4108,7 +4090,7 @@ const char * SPI_result_code_string(int code); int code - 结果代码 + 结果码 @@ -4119,7 +4101,7 @@ const char * SPI_result_code_string(int code); 返回值 - 结果代码的字符串表示。 + 结果码的字符串表示。 @@ -4131,8 +4113,8 @@ const char * SPI_result_code_string(int code); - memory context - in SPI + 内存上下文 + 在 SPI 中 PostgreSQL内存上下文 中分配内存。内存上下文为管理那些在许多不同位置创建、且生命周期各不相同 @@ -4157,7 +4139,7 @@ const char * SPI_result_code_string(int code); 办法是用 SPI_palloc 为返回对象分配内存。 SPI_palloc上层执行器上下文中分配 内存,也就是调用 SPI_connect 时的当前内存上下文; - 这正是从 C 函数返回值最合适的上下文。本节介绍的其他几个实用函数同样会返 + 这正是从 C 函数返回值最合适的上下文。本节介绍的其他几个辅助函数同样会返 回在上层执行器上下文中创建的对象。 @@ -4165,7 +4147,7 @@ const char * SPI_result_code_string(int code); 调用 SPI_connect 时,会把该 C 函数的私有上下文 (由 SPI_connect 创建)设为当前上下文。所有通过 pallocrepalloc 或 SPI - 实用函数分配的内存(本节另有说明的除外)都位于这个上下文中。当 C 函数通 + 辅助函数分配的内存(本节另有说明的除外)都位于这个上下文中。当 C 函数通 过 SPI_finish 与 SPI 管理器断开连接时,当前上下文 会恢复为上层执行器上下文,而在该 C 函数内存上下文中分配的所有内存都会被 释放,之后就不能再使用。 @@ -4360,7 +4342,7 @@ void SPI_pfree(void * pointer) SPI_copytuple - 在上层执行器上下文中创建一行的拷贝 + 在上层执行器上下文中创建一行的副本 @@ -4393,7 +4375,7 @@ HeapTuple SPI_copytuple(HeapTuple row) HeapTuple row - 要拷贝的行 + 要复制的行 @@ -4404,7 +4386,7 @@ HeapTuple SPI_copytuple(HeapTuple row) 返回值 - 拷贝后的行;出错时返回 NULL + 复制后的行;出错时返回 NULL (错误指示见 SPI_result @@ -4460,7 +4442,7 @@ HeapTupleHeader SPI_returntuple(HeapTuple row, TupleDesc HeapTuple row - 要拷贝的行 + 要复制的行 @@ -4469,7 +4451,7 @@ HeapTupleHeader SPI_returntuple(HeapTuple row, TupleDesc TupleDesc rowdesc - 行描述符(若要获得最佳缓存效果,大多数情况下应每次都传入同一个描述符) + 行描述符(若要获得最佳缓存效果,每次都传入同一个描述符) @@ -4480,7 +4462,7 @@ HeapTupleHeader SPI_returntuple(HeapTuple row, TupleDesc 返回值 - 指向拷贝后行的 HeapTupleHeader;出错时返回 + 指向复制后行的 HeapTupleHeader;出错时返回 NULL(错误指示见 SPI_result @@ -4582,13 +4564,14 @@ HeapTuple SPI_modifytuple(Relation rel, HeapTuple - 如果nullsNULL,那么 - SPI_modifytuple假定没有新值为空值。否则, - 如果对应的新值为非空,nulls数组的每一项都应 - 该是' ',而如果对应的新值为空值则为'n'(在 - 后一种情况中,对应的values项中的新值无关紧 - 要)。注意nulls不是一个文本字符串,只是一个 - 数组:它不需要一个'\0'终止符。 + 如果 nullsNULL,则 + SPI_modifytuple 会假定没有新值为空值。 + 否则,如果对应新值非空值,则 nulls 数组中 + 的对应项应为 ' ';如果对应新值为空值,则 + 对应项应为 'n'。(后一种情况下,对应 + values 项中的实际值无关紧要。)注意, + nulls 不是文本字符串,而只是一个数组,因此不 + 需要 '\0' 终止符。 @@ -4667,7 +4650,7 @@ void SPI_freetuple(HeapTuple row) SPI_freetuple释放之前在上层执行器上下文中 - 分配的一个行。 + 分配的一行。 @@ -4965,7 +4948,7 @@ void SPI_start_transaction(void) - 数据改变的可见性 + 数据更改的可见性 下列规则决定了使用 SPI 的函数(以及其他任何 C 函数)中数据更改的可见 diff --git a/zh/15/stylesheet-speedup-common.xsl b/zh/15/stylesheet-speedup-common.xsl index e3fb582a..403f350c 100644 --- a/zh/15/stylesheet-speedup-common.xsl +++ b/zh/15/stylesheet-speedup-common.xsl @@ -95,6 +95,6 @@ -en +zh_cn diff --git a/zh/15/syntax.sgml b/zh/15/syntax.sgml index f7d97ee9..ad7402a1 100644 --- a/zh/15/syntax.sgml +++ b/zh/15/syntax.sgml @@ -21,7 +21,7 @@ 词法结构 - token + 词元 @@ -29,7 +29,7 @@ - 一个词元可以是关键词标识符带引号的标识符文字值(或常量),或者特殊字符符号。词元通常由空白(空格、制表符、换行)分隔,但如果不存在歧义,则不必如此(一般只有特殊字符与其他类型的词元相邻时才会这样)。 + 一个词元可以是关键词标识符带引号的标识符字面量(或常量),或者特殊字符符号。词元通常由空白(空格、制表符、换行)分隔,但如果不存在歧义,则不必如此(一般只有特殊字符与其他类型的词元相邻时才会这样)。 @@ -58,18 +58,18 @@ INSERT INTO MY_TABLE VALUES (3, 'hi there'); 标识符和关键词 - identifier - syntax of + 标识符 + 语法 - name - syntax of + 名称 + 语法 - key word - syntax of + 关键词 + 语法 @@ -83,7 +83,7 @@ INSERT INTO MY_TABLE VALUES (3, 'hi there'); - identifierlength + 标识符长度 系统对标识符最多只使用 NAMEDATALEN-1 个字节;在命令中可以写更长的名称,但它们会被截断。默认情况下, NAMEDATALEN 为 64,因此标识符的最大长度是 63 字节。如果这个限制有问题,可以通过修改 src/include/pg_config_manual.h 中的 NAMEDATALEN 常量来提高。 @@ -91,8 +91,8 @@ INSERT INTO MY_TABLE VALUES (3, 'hi there'); - case sensitivity - of SQL commands + 大小写敏感性 + SQL 命令 关键词和未加引号的标识符不区分大小写。因此: @@ -110,8 +110,8 @@ UPDATE my_table SET a = 5; - quotation marks - and identifiers + 引号 + 与标识符 还有第二类标识符:定界标识符带引号的标识符。它通过把任意字符序列括在双引号中形成(")。 定界标识符始终是标识符,绝不会是关键词。因此,"select" 可以用来引用名为 select 的列或表,而不加引号的 select 会被视为关键词,因此在期望表名或列名的位置使用时会导致解析错误。这个示例可以用带引号的标识符写成: @@ -133,7 +133,7 @@ UPDATE "my_table" SET "a" = 5; Unicode 转义 - in identifiers + 在标识符中 @@ -177,7 +177,7 @@ U&"d!0061t!+000061" UESCAPE '!' 常量 - constant + 常量 @@ -188,19 +188,15 @@ U&"d!0061t!+000061" UESCAPE '!' 字符串常量 - character string - constant + 字符串 + 常量 - - - quotation marks + + 引号 转义 - SQL 中的字符串常量是由单引号括起的任意字符序列,例如 - 'This is a string'。要在字符串常量中包含单引号字符,请写两个相邻的单引号,例如 - 'Dianne''s horse'。注意,这与双引号字符("不同 - + SQL 中的字符串常量是由单引号(')括起的任意字符序列,例如 'This is a string'。要在字符串常量中包含单引号字符,请写两个相邻的单引号,例如 'Dianne''s horse'。注意,这不同于双引号字符(")。 两个只由空白及至少一个新行分隔的字符串常量会被连接在一起,并且将作为一个写在一起的字符串常量来对待。例如: @@ -304,7 +300,7 @@ SELECT 'foo' 'bar'; - 如果配置参数off,那么PostgreSQL对常规字符串常量和转义字符串常量中的反斜线转义都识别。不过,从PostgreSQL 9.1 开始,该参数的默认值为on,意味着只在转义字符串常量中识别反斜线转义。这种行为更兼容标准,但是可能打断依赖于历史行为(反斜线转义总是会被识别)的应用。作为一种变通,你可以设置该参数为off,但是最好迁移到符合新的行为。如果你需要使用一个反斜线转义来表示一个特殊字符,为该字符串常量写上一个E。 + 如果配置参数off,那么PostgreSQL对常规字符串常量和转义字符串常量中的反斜线转义都识别。不过,从PostgreSQL 9.1 开始,该参数的默认值为on,意味着只在转义字符串常量中识别反斜线转义。这种行为更兼容标准,但是可能使依赖历史行为(始终识别反斜线转义)的应用无法正常工作。作为一种变通,你可以设置该参数为off,但最好修改应用,不再使用反斜线转义。如果你需要使用一个反斜线转义来表示一个特殊字符,为该字符串常量写上一个E @@ -322,7 +318,7 @@ SELECT 'foo' 'bar'; Unicode 转义 - in string constants + 在字符串常量中 @@ -368,7 +364,7 @@ U&'d!0061t!+000061' UESCAPE '!' 美元引用的字符串常量 - dollar quoting + 美元引用 @@ -411,8 +407,8 @@ $function$ 位串常量 - bit string - constant + 位串 + 常量 @@ -432,8 +428,8 @@ $function$ 数字常量 - number - constant + 数字 + 常量 @@ -471,12 +467,12 @@ $function$ - 为数字常量最初指定的数据类型,只是类型解析算法的起点。在大多数情况下,常量会根据上下文被自动强制转换成最合适的类型。必要时,你可以通过类型转换强制把一个数值解释为特定的数据类型。type cast + 为数字常量最初指定的数据类型,只是类型解析算法的起点。在大多数情况下,常量会根据上下文被自动强制转换成最合适的类型。必要时,你可以通过类型转换强制把一个数值解释为特定的数据类型。类型转换 例如,可以通过下面的写法强制把一个数值当作类型 realfloat4)处理: -REAL '1.23' -- string style -1.23::REAL -- PostgreSQL (historical) style +REAL '1.23' -- 字符串形式 +1.23::REAL -- PostgreSQL(历史)形式 这些实际上只是下面将要讨论的一般类型转换记法的特例。 @@ -487,8 +483,8 @@ REAL '1.23' -- string style 其他类型的常量 - data type - constant + 数据类型 + 常量 @@ -514,7 +510,7 @@ CAST ( 'string' AS type ) - 如中所述,::CAST() 以及函数调用语法也可以用来指定任意表达式的运行时类型转换。为避免语法歧义,type 'string' 语法只能用来指定简单字面常量的类型。该语法的另一个限制是不能用于数组类型;要指定数组常量的类型,请使用 ::CAST()。 + 如中所述,::CAST() 以及函数调用语法也可以用来指定任意表达式的运行时类型转换。为避免语法歧义,type 'string' 语法只能用来指定简单字面常量的类型。type 'string' 语法的另一个限制是不能用于数组类型;要指定数组常量的类型,请使用 ::CAST() @@ -527,8 +523,8 @@ CAST ( 'string' AS type ) 操作符 - operator - syntax + 操作符 + 语法 @@ -578,7 +574,7 @@ CAST ( 'string' AS type ) - 圆括号(())具有它们通常的含义,用来分组表达式并且强制优先。在某些情况中,圆括号被要求作为一个特定 SQL 命令的固定语法的一部分。 + 圆括号(())具有它们通常的含义,用来对表达式分组并确定运算优先级。在某些情况中,圆括号被要求作为一个特定 SQL 命令的固定语法的一部分。 @@ -596,7 +592,7 @@ CAST ( 'string' AS type ) - 分号(;)结束一个 SQL 命令。它不能出现在一个命令中间的任何位置,除了在一个字符串常量中或者一个被引用的标识符中。 + 分号(;)结束一个 SQL 命令。它不能出现在一个命令中间的任何位置,除了在一个字符串常量中或者一个带引号的标识符中。 @@ -608,7 +604,7 @@ CAST ( 'string' AS type ) - 星号(*)在某些上下文中用来表示表行或组合值的所有字段。当它被用作聚合函数的参数时,还有一种特殊含义,即该聚合不需要任何显式参数。 + 星号(*)在某些上下文中用来表示表行或复合值的所有字段。当它被用作聚合函数的参数时,还有一种特殊含义,即该聚合不需要任何显式参数。 @@ -626,22 +622,22 @@ CAST ( 'string' AS type ) 注释 - comment - in SQL + 注释 + 在 SQL 中 注释是一串以双连字符开始并延伸到行尾的字符,例如: --- This is a standard SQL comment +-- 这是一条标准 SQL 注释 另外,也可以使用 C 风格注释块: -/* multiline comment - * with nesting: /* nested block comment */ +/* 多行注释 + * 包含嵌套:/* 嵌套块注释 */ */ 这里该注释开始于/*并且延伸到匹配出现的*/。这些注释块可按照 SQL 标准中指定的方式嵌套,但和 C 中不同。这样我们可以注释掉一大段可能包含注释块的代码。 @@ -656,8 +652,8 @@ CAST ( 'string' AS type ) 操作符优先级 - operator - precedence + 操作符 + 优先级 @@ -701,7 +697,7 @@ CAST ( 'string' AS type ) + - - 一元加、一元减 + 一元正号、一元负号 @@ -713,19 +709,19 @@ CAST ( 'string' AS type ) AT - AT TIME ZONE, AT LOCAL + AT TIME ZONE ^ - 指数 + 求幂 * / % - 乘、除、模 + 乘、除、取模 @@ -737,7 +733,7 @@ CAST ( 'string' AS type ) (任意其他操作符) - 所有其他本地以及用户定义的操作符 + 所有其他内置以及用户定义的操作符 @@ -794,18 +790,7 @@ SELECT 3 OPERATOR(pg_catalog.+) 4; - - 版本 9.5 之前的PostgreSQL使用的操作符优先级 - 规则略有不同。特别是,<=>= - 和<>习惯于被当作普通操作符,IS - 测试习惯于具有较高的优先级。并且在一些认为NOT比 - BETWEEN优先级高的情况下,NOT BETWEEN - 和相关的结构的行为不一致。为了更好地兼容 SQL 标准并且减少对 - 逻辑上等价的结构不一致的处理,这些规则也得到了修改。在大部分情况下, - 这些变化不会导致行为上的变化,或者可能会产生no such operator - 错误,但可以通过增加圆括号解决。不过在一些极端情况中,查询可能在 - 没有被报告解析错误的情况下发生行为的改变。 - + PostgreSQL 9.5 之前的版本使用的操作符优先级规则略有不同。特别是,<=>=<> 过去被当作普通操作符;IS 测试过去具有较高的优先级;而 NOT BETWEEN 和相关结构的处理不一致,在某些情况下被认为具有 NOT 而不是 BETWEEN 的优先级。为了更好地符合 SQL 标准,并减少对逻辑等价结构的不一致处理造成的困惑,这些规则得到了修改。在大部分情况下,这些变化不会导致行为变化,或者可能会产生 no such operator 错误,但可以通过增加圆括号解决。不过在一些极端情况下,查询可能在没有报告任何解析错误的情况下改变行为。 @@ -1498,7 +1483,7 @@ SELECT * FROM tbl WHERE a COLLATE "C" > 'foo'; SELECT * FROM tbl WHERE (a > 'foo') COLLATE "C"; - 因为它尝试把一个排序规则应用到>操作符的结果,而它的数据类型是非可排序数据类型boolean。 + 因为它尝试把一个排序规则应用到>操作符的结果,而它的数据类型是不支持排序规则的数据类型boolean diff --git a/zh/15/system-views.sgml b/zh/15/system-views.sgml index 0f14651f..c66e4a19 100644 --- a/zh/15/system-views.sgml +++ b/zh/15/system-views.sgml @@ -45,11 +45,6 @@ - - pg_aios - 正在使用的异步 I/O 句柄 - - pg_available_extensions 可用的扩展 @@ -175,11 +170,6 @@ 共享内存分配 - - pg_shmem_allocations_numa - 共享内存分配的 NUMA 节点映射 - - pg_stats 规划器统计信息 @@ -225,293 +215,12 @@ 视图 - - pg_wait_events - 等待事件 - - - - - - - - - <structname>pg_aios</structname> - - - pg_aios - - - - pg_aios 视图列出当前正在使用的全部 - 句柄。I/O 句柄用于引用正在准备、执行或处于完成过程中的 - I/O 操作。pg_aios 为每个 I/O 句柄提供一行。 - - - - 该视图主要对 PostgreSQL 开发者有用, - 但在调优 PostgreSQL 时也可能有帮助。 - - - - <structname>pg_aios</structname> 列 - - - - - 列类型 - - - 描述 - - - - - - - - pid int4 - - - 发起该 I/O 的服务器进程 ID。 - - - - - - io_id int4 - - - I/O 句柄的标识符。I/O 完成后(或者在 I/O 启动前释放句柄时),句柄会被复用。每次复用时, - - pg_aios.io_generation - - 都会递增。 - - - - - - io_generation int8 - - - I/O 句柄的代次。 - - - - - - state text - - - I/O 句柄的状态: - - - - HANDED_OUT,已被代码引用但尚未使用 - - - - - DEFINED,执行所需的信息已知 - - - - - STAGED,已就绪,可执行 - - - - - SUBMITTED,已提交执行 - - - - - COMPLETED_IO,已完成,但结果尚未处理 - - - - - COMPLETED_SHARED,共享完成处理已完成 - - - - - COMPLETED_LOCAL,后端本地完成处理已完成 - - - - - - - - - operation text - - - 使用 I/O 句柄执行的操作: - - - - invalid,尚未知晓 - - - - - readv,向量化读取 - - - - - writev,向量化写入 - - - - - - - - - off int8 - - - I/O 操作的偏移量。 - - - - - - length int8 - - - I/O 操作的长度。 - - - - - - target text - - - I/O 的目标对象类型: - - - - smgr,关系上的 I/O - - - - - - - - - handle_data_len int2 - - - 与 I/O 操作关联的数据长度。对于指向或来自 - 的 I/O,该值表示 I/O 正在操作的缓冲区个数。 - - - - - - raw_result int4 - - - I/O 操作的底层结果;如果操作尚未完成,则为 NULL。 - - - - - - result text - - - I/O 操作的高级结果: - - - - UNKNOWN 表示操作结果尚未知晓。 - - - - - OK 表示 I/O 已成功完成。 - - - - - PARTIAL 表示 I/O 完成时没有出错,但未处理全部数据。通常调用方需要在单独的 I/O 中重试并完成剩余工作。 - - - - - WARNING 表示 I/O 完成时没有出错,但执行 I/O 时触发了警告。例如,在启用 时遇到损坏的缓冲区。 - - - - - ERROR 表示 I/O 因错误而失败。 - - - - - - - - - target_desc text - - - I/O 操作目标的描述。 - - - - - - f_sync bool - - - 标记该 I/O 是否同步执行。 - - - - - - f_localmem bool - - - 标记该 I/O 是否引用进程本地内存。 - - - - - - f_buffered bool - - - 标记该 I/O 是否为缓冲 I/O。 - - -
- - - pg_aios 视图是只读的。 - - - - 默认情况下,pg_aios视图只能由超级用户或具有 - pg_read_all_stats 角色权限的角色读取。 -
+ <structname>pg_available_extensions</structname> @@ -749,10 +458,10 @@ - type text + parent text - 内存上下文类型 + 此内存上下文的父上下文名称 @@ -761,18 +470,7 @@ level int4
- 该上下文在内存上下文层次中的层级,从 1 开始计数。上下文的层级也表示该上下文在 - path 列中的位置。 - - - - - - path int4[] - - - 由瞬态数字标识符组成的数组,用于描述内存上下文层次。第一个元素对应 - TopMemoryContext,后续元素包含中间父上下文,最后一个元素包含当前上下文的标识符。 + 与上下文树中 TopMemoryContext 的距离 @@ -827,24 +525,6 @@ 默认情况下,pg_backend_memory_contexts视图只能被超级用户或具有pg_read_all_stats角色权限的角色读取。 - - - 由于内存上下文会在查询运行期间创建和销毁,因此存储在 path 列中的标识符,在同一查询中多次调用该视图时可能不稳定。下面的示例展示了该列的一种有效用法,并计算 - CacheMemoryContext 及其全部子上下文所使用的总字节数: - - -WITH memory_contexts AS ( - SELECT * FROM pg_backend_memory_contexts -) -SELECT sum(c1.total_bytes) -FROM memory_contexts c1, memory_contexts c2 -WHERE c2.name = 'CacheMemoryContext' -AND c1.path[c2.level] = c2.path[c2.level]; - - - 这里使用了通用表表达式,以确保对视图进行两次求值时, - path 列中的上下文 ID 能够对应一致。 - @@ -1245,7 +925,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; line_number int4 - 此规则在pg_hba.conf中的行号 + 该规则在 pg_hba.conf 中的行号 @@ -1281,7 +961,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; address text - 主机名或IP地址,或者allsamehostsamenet之一,对于本地连接为空 + 主机名或IP地址,或者allsamehostsamenet之一,对于本地连接为 NULL @@ -1290,7 +970,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; netmask text - IP地址掩码,如果不适用则为空 + IP地址掩码,如果不适用则为 NULL @@ -1370,31 +1050,12 @@ AND c1.path[c2.level] = c2.path[c2.level]; - - - map_number int4 - - - 如果该映射有效,则为其编号,按优先级顺序排列;否则为 - NULL - - - - - - file_name text - - - 包含该映射的文件名 - - - line_number int4 - 该映射在 file_name 中的行号 + 该映射在 pg_ident.conf 中的行号 @@ -1508,7 +1169,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; (参考 pg_tablespace.spcname) - 包含索引的表空间名(如果是数据库的默认值则为空) + 包含索引的表空间名(如果是数据库的默认值则为 NULL) @@ -1517,7 +1178,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; indexdef text - 索引定义(重构出的 命令) + 索引定义(重建出的 命令) @@ -1551,8 +1212,8 @@ AND c1.path[c2.level] = c2.path[c2.level]; 以及一般的数据库对象(由类OID和对象OID标识, 与pg_descriptionpg_depend中的方式相同)。 - 此外,扩展关系的权限被表示为一个单独的可锁定对象,以及更新 - pg_database.datfrozenxid 的更新权限。 + 此外,扩展关系的权利被表示为单独的可锁定对象,更新 + pg_database.datfrozenxid的权利也是如此。 此外,还可以对具有用户定义含义的数字施加咨询锁。 @@ -1587,8 +1248,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; spectoken, object, userlock, - advisory 或 - applytransaction。 + advisory。 (另请参见。) @@ -1599,7 +1259,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; (参考 pg_database.oid) - 锁目标存在的数据库的OID,如果目标是一个共享对象则为0,如果目标是一个事务ID则为空 + 锁目标存在的数据库的OID,如果目标是一个共享对象则为0,如果目标是一个事务ID则为 NULL @@ -1609,7 +1269,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; (参考 pg_class.oid) - 作为锁目标的关系的OID,如果目标不是一个关系或者只是关系的一部分则此列为空 + 作为锁目标的关系的OID,如果目标既不是关系,也不是关系的一部分则此列为 NULL @@ -1618,7 +1278,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; page int4 - 作为锁目标的页在关系中的页号,如果目标不是一个关系页或元组则此列为空 + 作为锁目标的页在关系中的页号,如果目标不是一个关系页或元组则此列为 NULL @@ -1627,7 +1287,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; tuple int2 - 作为锁目标的元组在页中的元组号,如果目标不是一个元组则此列为空 + 作为锁目标的元组在页中的元组号,如果目标不是一个元组则此列为 NULL @@ -1636,7 +1296,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; virtualxid text - 锁定目标事务的虚拟 ID,如果目标不是虚拟事务 ID,则为空 + 锁定目标事务的虚拟 ID,如果目标不是虚拟事务 ID,则为 NULL @@ -1645,7 +1305,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; transactionid xid - 锁定目标事务的标识,如果目标不是事务 ID,则为空 + 锁定目标事务的标识,如果目标不是事务 ID,则为 NULL @@ -1655,7 +1315,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; (参考 pg_class.oid) - 包含锁目标的系统目录的OID,如果目标不是一个普通数据库对象则此列为空 + 包含锁目标的系统目录的OID,如果目标不是一个普通数据库对象则此列为 NULL @@ -1665,7 +1325,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; (参考任意 OID 列) - 锁目标在它的系统目录中的OID,如果目标不是一个普通数据库对象则为空 + 锁目标在它的系统目录中的OID,如果目标不是一个普通数据库对象则为 NULL @@ -1674,7 +1334,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; objsubid int2 - 锁的目标列号(classidobjid指表本身),如果目标是某种其他普通数据库对象则此列为0,如果目标不是一个普通数据库对象则此列为空 + 锁的目标列号(classidobjid指表本身),如果目标是某种其他普通数据库对象则此列为0,如果目标不是一个普通数据库对象则此列为 NULL @@ -1692,7 +1352,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; pid int4 - 保持这个锁或者正在等待这个锁的服务器进程的PID,如果此锁被一个预备事务所持有则此列为空 + 保持这个锁或者正在等待这个锁的服务器进程的PID,如果此锁被一个预备事务所持有则此列为 NULL @@ -1728,8 +1388,8 @@ AND c1.path[c2.level] = c2.path[c2.level]; waitstart timestamptz - 服务器进程开始等待该锁的时间;如果锁已被授予则为空。 - 注意,在开始等待之后,即使grantedfalse,该值在极短时间内也可能仍为空。 + 服务器进程开始等待该锁的时间;如果锁已被授予则为 NULL。 + 注意,在开始等待之后,即使grantedfalse,该值在极短时间内也可能仍为 NULL。 @@ -1754,27 +1414,16 @@ AND c1.path[c2.level] = c2.path[c2.level]; 如果一个进程正在等待行级锁,它通常会出现在视图中,等待当前持有该行锁的永久事务ID。 - - 推测插入锁由事务 ID 和推测插入令牌组成。推测插入令牌显示在 - objid 列中。 - - 咨询锁可以在由单个 bigint 值或两个整数值组成的键上获取。 - 一个bigint键在classid列中显示其高阶半部分, - 在objid列中显示其低阶半部分,并且objsubid等于1。 + 一个bigint键在classid列中显示其高位半部分, + 在objid列中显示其低位半部分,并且objsubid等于1。 可以使用表达式(classid::bigint << 32) | objid::bigint重新组装原始bigint值。 整数键在classid列中显示第一个键,在objid列中显示第二个键, 并且 objsubid 等于 2。键的实际含义由用户自行决定。咨询锁在每个数据库内都是本地的, 因此 database 列对于咨询锁是有意义的。 - - 应用事务锁用于在并行模式下应用逻辑复制中的事务。远程事务 ID 显示在 - transactionid 列中。objsubid - 显示锁子类型:用于同步一组变更的锁其值为 0;用于等待事务完成以确保提交顺序的锁其值为 1。 - - pg_locks提供了集簇中所有锁的全局视图,不仅包括与当前数据库相关的锁。 虽然它的relation列可以与pg_class.oid 连接来识别被锁定的关系,但这仅对当前数据库中的关系有效(即 database 列为当前数据库的 OID 或零的那些关系)。 @@ -1811,15 +1460,15 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx pg_locks视图显示来自常规锁管理器和谓词锁管理器的数据,这两个是独立的系统; - 此外,常规锁管理器将其锁分为常规锁和fast-path锁。 + 此外,常规锁管理器将其锁分为常规锁和快速路径锁。 不能保证这些数据完全一致。 当查询该视图时, - fast-path 锁的数据(具有fastpath = true) + 快速路径锁的数据(具有fastpath = true) 从每个后端逐个收集,而不会冻结整个锁管理器的状态,因此在收集信息时可能会发生锁的获取或释放。 但请注意,这些锁已知不会与当前放置的任何其他锁发生冲突。 - 在查询所有后端的 fast-path 锁后,剩余的常规锁管理器将作为一个单元被锁定,并且所有剩余锁的一致快照将作为一个原子操作收集。 + 在查询所有后端的快速路径锁后,剩余的常规锁管理器将作为一个单元被锁定,并且所有剩余锁的一致快照将作为一个原子操作收集。 解锁常规锁管理器后,谓词锁管理器类似地被锁定,并且所有谓词锁将作为一个原子操作收集。 - 因此,除了 fast-path 锁外,每个锁管理器将提供一致的结果集,但由于我们不同时锁定两个锁管理器,因此在询问常规锁管理器后和在询问谓词锁管理器前,可能会发生锁的获取或释放。 + 因此,除了快速路径锁外,每个锁管理器将提供一致的结果集,但由于我们不同时锁定两个锁管理器,因此在询问常规锁管理器后和在询问谓词锁管理器前,可能会发生锁的获取或释放。 @@ -1895,7 +1544,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx (参考 pg_tablespace.spcname) - 包含物化视图的表空间名(如使用数据库默认表空间则为空) + 包含物化视图的表空间名(如使用数据库默认表空间则为 NULL) @@ -1922,7 +1571,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx definition text - 物化视图的定义(一个重构的查询) + 物化视图的定义(一个重建的查询) @@ -2240,8 +1889,8 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx 视图pg_publication_tables提供发布与其所包含表之间映射关系的信息。与底层目录 pg_publication_rel不同,该视图会展开定义为 - FOR ALL TABLES - 和 FOR TABLES IN SCHEMA 的发布, + FOR ALL TABLES + 和 FOR TABLES IN SCHEMA 的发布, 因此对于这类发布,每个符合条件的表都会有一行。 @@ -2473,7 +2122,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx active bool - 如果该槽当前正被用于流送则为真 + 如果该槽当前正在使用中则为真 @@ -2482,7 +2131,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx active_pid int4 - 为该槽流送数据的会话的进程 ID。NULL 表示不活动。 + 如果该槽当前正在使用中,则为使用该槽的会话的进程 ID;不活动时为 NULL @@ -2518,7 +2167,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx confirmed_flush_lsn pg_lsn - 逻辑槽消费者已确认接收到数据的地址(LSN)。在此 LSN 之前提交的事务所对应的数据将不再可用。物理槽为 NULL。 + 逻辑槽消费者已确认接收的数据所到达的地址(LSN)。早于此地址的数据将不再可用。物理槽为 NULL @@ -2537,15 +2186,16 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - unreserved 表示该槽已不再保留所需的 WAL 文件,其中一部分将在下一个检查点被移除。这通常发生在 被设置为非负值时。该状态可以返回为 reservedextended。 + unreserved 表示该槽已不再保留所需的 WAL 文件,其中一部分将在下一个检查点被移除。该状态可以返回为 reservedextended - lost 表示该槽已经不可用。 + lost 表示某些必需的 WAL 文件已被移除,该槽已经不可用。 + 后两种状态仅在 为非负值时出现。 @@ -2567,82 +2217,6 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - - - two_phase_at pg_lsn - - - 自哪个地址(LSN)起启用预备事务解码。对于 two_phase 为假的逻辑槽,以及物理槽,该值为 NULL。 - - - - - - inactive_since timestamptz - - - 槽变为不活动的时间。如果该槽当前正在被流送,则为 NULL。如果该槽变为无效,该值将不再更新。对于从主库同步而来的备库逻辑槽(其 synced 字段为 true),inactive_since 表示槽同步(参见 )最近一次停止的时间。如果该槽始终保持同步,则为 NULL。这有助于跟踪备库上的槽同步何时被中断。 - - - - - - conflicting bool - - - 如果该逻辑槽与恢复发生冲突(因此现已失效)则为真。当该列为真时,请检查 invalidation_reason 列以了解冲突原因。物理槽始终为 NULL。 - - - - - - invalidation_reason text - - - 该槽失效的原因。逻辑槽和物理槽都可能设置该值。若该槽未失效,则为 NULL。可能值为: - - - - wal_removed 表示所需的 WAL 已被移除。 - - - - - rows_removed 表示所需的行已被移除。该值只会设置在逻辑槽上。 - - - - - wal_level_insufficient 表示主库没有足够的 来执行逻辑解码。该值只会设置在逻辑槽上。 - - - - - idle_timeout 表示该槽保持不活动的时间已超过配置的 idle_replication_slot_timeout 时长。 - - - - - - - - - failover bool - - - 如果这是一个允许同步到备库的逻辑槽则为真,这样逻辑复制就可以在故障切换后从新的主库恢复。物理槽始终为假。 - - - - - - synced bool - - - 如果这是一个从主库同步而来的逻辑槽则为真。在热备上,synced 列为真的槽既不能用于逻辑解码,也不能手工删除。该列在主库上的值没有意义;主库上该列默认对所有槽都为假,但也可能(如果是由已提升的备库遗留)为真。 - - - @@ -2657,7 +2231,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx 视图pg_roles提供数据库角色的信息。它本质上是 - pg_authid 的公开可读视图,并将密码字段清空。 + pg_authid 的公开可读视图,并隐藏密码字段。 @@ -2743,7 +2317,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx rolconnlimitint4 - 对于可以登录的角色,本列设置该角色可以同时发起最大连接数。-1表示无限制。 + 对于可以登录的角色,本列设置该角色能够建立的最大并发连接数。-1 表示无限制。 @@ -2761,7 +2335,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx rolvaliduntiltimestamptz - 密码过期时间(只用于密码认证),如果永不过期则为空 + 密码过期时间(仅用于密码认证);不设过期时间时为 NULL @@ -2859,7 +2433,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx definitiontext - 规则定义(创建命令的重构) + 规则定义(重建的创建命令) @@ -2945,7 +2519,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx (参考 pg_namespace.oid) - 如果适用,为此对象的命名空间 OID;否则为空。 + 如果适用,为此对象的命名空间 OID;否则为 NULL。 @@ -3252,7 +2826,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx min_valtext - 参数的最小允许值(对非数值参数为空) + 参数的最小允许值(对非数值参数为 NULL) @@ -3261,7 +2835,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx max_valtext - 参数的最大允许值(对非数值参数为空) + 参数的最大允许值(对非数值参数为 NULL) @@ -3270,7 +2844,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx enumvalstext[] - 枚举参数的允许值(对非枚举参数为空) + 枚举参数的允许值(对非枚举参数为 NULL) @@ -3458,7 +3032,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx 这个名称源于该表不应向公众开放读取,因为它包含密码。 pg_user - 是 pg_shadow 的公开可读视图,并将密码字段清空。 + 是 pg_shadow 的公开可读视图,并隐藏密码字段。
@@ -3647,79 +3221,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - - <structname>pg_shmem_allocations_numa</structname> - - - pg_shmem_allocations_numa - - - - pg_shmem_allocations_numa 显示服务器主共享内存段中的共享内存分配如何分布在各个 NUMA 节点上。这既包括 PostgreSQL 自身分配的内存,也包括扩展使用 所述机制分配的内存。只要共享内存段分布在多个 NUMA 节点上,该视图就会为每个共享内存段输出多行。监控系统不应查询此视图,因为它非常慢,而且如果共享内存此前尚未分配,还可能最终触发共享内存分配。目前该视图的限制是不会显示匿名共享内存分配。 - - - - 请注意,此视图不包括使用动态共享内存基础设施分配的内存。 - - - - - 在确定 NUMA 节点时,该视图会触碰共享内存段的所有内存页。这会强制分配共享内存(如果此前尚未分配),并且这些内存可能会被分配到单个 NUMA 节点上(取决于系统配置)。 - - - -
- <structname>pg_shmem_allocations_numa</structname> 列 - - - - - 列类型 - - - 描述 - - - - - - - - name text - - - 共享内存分配的名称 - - - - - - numa_node int4 - - - NUMA 节点 ID - - - - - - size int8 - - - 该分配在此特定 NUMA 内存节点上的大小,按字节计 - - - - - -
- - - 默认情况下,pg_shmem_allocations_numa视图只能由超级用户或具有 - pg_read_all_stats 角色权限的角色读取。 - -
- + <structname>pg_stats</structname> @@ -3797,7 +3299,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx null_frac float4 - 列项中为空的比例 + 列项中为 NULL 的比例 @@ -3825,7 +3327,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx most_common_vals anyarray - 列中高频值的一个列表(如果没有任何一个值看起来比其他值更常用,此列为空) + 列中高频值的一个列表(如果没有任何一个值看起来比其他值更常用,此列为 NULL) @@ -3834,7 +3336,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx most_common_freqs float4[] - 高频值的频率列表,即每一个高频值的出现次数除以总行数(如果most_common_vals为空,则此列为空) + 高频值的频率列表,即每一个高频值的出现次数除以总行数(如果most_common_vals为 NULL,则此列为 NULL) @@ -3843,7 +3345,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx histogram_bounds anyarray - 将列值划分成大小接近的组的值列表。如果存在most_common_vals,其中的值会被直方图计算所忽略(如果列类型没有一个<操作符或者most_common_vals等于整个值集合,则此列为空) + 将列值划分成大小接近的组的值列表。如果存在most_common_vals,其中的值会被直方图计算所忽略(如果列类型没有一个<操作符或者most_common_vals等于整个值集合,则此列为 NULL) @@ -3852,7 +3354,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx correlation float4 - 物理行顺序和列值逻辑顺序之间的统计关联。其范围从-1到+1。当值接近-1或+1时,在列上的一个索引扫描被认为比值接近0时的代价更低,因为这种情况减少了对磁盘的随机访问(如果列数据类型不具有一个<操作符,则此列为空) + 物理行顺序和列值逻辑顺序之间的统计关联。其范围从-1到+1。当值接近-1或+1时,在列上的一个索引扫描被认为比值接近0时的代价更低,因为这种情况减少了对磁盘的随机访问(如果列数据类型不具有一个<操作符,则此列为 NULL) @@ -3861,7 +3363,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx most_common_elems anyarray - 在列值中,最经常出现的非空元素列表(对标量类型为空) + 在列值中,最经常出现的非空元素列表(对标量类型为 NULL) @@ -3871,7 +3373,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx 最常用元素值的频度列表,即含有至少一个给定值实例的行的分数。 - 在每个元素的频度之后有二至三个附加值,它们是每个元素频度的最小和最大值,以及可选的空元素的频度(如果most_common_elems为空,则此列为空) + 在每个元素的频度之后有二至三个附加值,它们是每个元素频度的最小和最大值,以及可选的空元素的频度(如果most_common_elems为 NULL,则此列为 NULL) @@ -3880,42 +3382,10 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx elem_count_histogram float4[] - 在列值中可区分非空元素值计数的一个直方图,后面跟随可区分非空元素的平均数(对于标量类型为空) - - - - - - range_length_histogram anyarray - - - 范围类型列中非空且非 NULL 的范围值长度直方图。(对非范围类型为空。) - - - 该直方图使用范围函数 subtype_diff 计算,而不考虑范围边界是否包含端点。 - - - - - - range_empty_frac float4 - - - 列项中值为空范围的比例。(对非范围类型为空。) + 在列值中可区分非空元素值计数的一个直方图,后面跟随可区分非空元素的平均数(对于标量类型为 NULL) - - - range_bounds_histogram anyarray - - - 非空且非 NULL 的范围值下界和上界的直方图。(对非范围类型为空。) - - - 这两个直方图表示为单个数组列,其中下半部分表示下界的直方图,上半部分表示上界的直方图。 - - @@ -4079,7 +3549,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx most_common_vals text[] - 列中值的最常见组合的列表(如果没有组合看上去比其它的更常见,则为空。) + 列中值的最常见组合的列表(如果没有组合看上去比其它的更常见,则为 NULL。) @@ -4088,7 +3558,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx most_common_val_nulls bool[] - 值最常见组合的NULL标志的列表(当most_common_vals是空值时,为空。) + 值最常见组合的NULL标志的列表(当most_common_vals为 NULL 时,为 NULL。) @@ -4097,7 +3567,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx most_common_freqs float8[] - 最常见组合的频率的列表,即每个出现的数量除以行的总数(当most_common_vals是空值时,为空) + 最常见组合的频率的列表,即每个出现的数量除以行的总数(当most_common_vals为 NULL 时,为 NULL) @@ -4106,7 +3576,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx most_common_base_freqs float8[] - 最常见组合的基本频率的列表,即每个值频率的乘积。(当most_common_vals是空值时,为空。) + 最常见组合的基本频率的列表,即每个值频率的乘积。(当most_common_vals为 NULL 时,为 NULL。) @@ -4231,7 +3701,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx null_frac float4 - 表达式条目为空的比例 + 表达式条目为 NULL 的比例 @@ -4259,7 +3729,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx most_common_vals anyarray - 表达式中高频值的列表(如果没有值看起来比任何其他值更常见则为空) + 表达式中高频值的列表(如果没有值看起来比任何其他值更常见则为 NULL) @@ -4268,7 +3738,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx most_common_freqs float4[] - 高频值的频率列表,即每一个高频值的出现次数除以总行数(如果most_common_vals为空,则此列为空) + 高频值的频率列表,即每一个高频值的出现次数除以总行数(如果most_common_vals为 NULL,则此列为 NULL) @@ -4277,7 +3747,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx histogram_bounds anyarray - 将表达式的值划分成大小接近的组的值列表。如果存在most_common_vals,其中的值会被直方图计算所忽略(如果表达式的数据类型没有一个<操作符或者most_common_vals等于整个值集合,则此列为空) + 将表达式的值划分成大小接近的组的值列表。如果存在most_common_vals,其中的值会被直方图计算所忽略(如果表达式的数据类型没有一个<操作符或者most_common_vals等于整个值集合,则此列为 NULL) @@ -4286,7 +3756,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx correlation float4 - 物理行顺序和表达式值逻辑顺序之间的统计关联。其范围从-1到+1。当值接近-1或+1时,在表达式上的一个索引扫描被认为比值接近0时的代价更低,因为这种情况减少了对磁盘的随机访问(如果表达式的数据类型不具有一个<操作符,则此列为空) + 物理行顺序和表达式值逻辑顺序之间的统计关联。其范围从-1到+1。当值接近-1或+1时,在表达式上的一个索引扫描被认为比值接近0时的代价更低,因为这种情况减少了对磁盘的随机访问(如果表达式的数据类型不具有一个<操作符,则此列为 NULL) @@ -4295,7 +3765,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx most_common_elems anyarray - 与表达式的值一起最常出现的非空元素值的列表。(标量类型时为空) + 与表达式的值一起最常出现的非空元素值的列表。(标量类型时为 NULL) @@ -4305,7 +3775,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx 最常用元素值的频度列表,即含有至少一个给定值实例的行的分数。 - 在每个元素的频度之后有二至三个附加值,它们是每个元素频度的最小和最大值,以及可选的空元素的频度(如果most_common_elems为空,则此列为空) + 在每个元素的频度之后有二至三个附加值,它们是每个元素频度的最小和最大值,以及可选的空元素的频度(如果most_common_elems为 NULL,则此列为 NULL) @@ -4314,7 +3784,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx elem_count_histogram float4[] - 表达式值的不同非空元素值的计数的直方图,后面跟着不同非空元素的平均数量。(标量类型时为空) + 表达式值的不同非空元素值的计数的直方图,后面跟着不同非空元素的平均数量。(标量类型时为 NULL) @@ -4391,7 +3861,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx (参考 pg_tablespace.spcname) - 包含该表的表空间名称(如果使用数据库的默认表空间,此列为空) + 包含该表的表空间名称(如果使用数据库的默认表空间,此列为 NULL) @@ -4588,7 +4058,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx 视图pg_user提供数据库用户的信息。它本质上是 - pg_shadow 的公开可读视图,并将密码字段清空。 + pg_shadow 的公开可读视图,并隐藏密码字段。 @@ -4866,7 +4336,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx definitiontext - 视图定义(一个重构的查询) + 视图定义(一个重建的查询) @@ -4875,61 +4345,5 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - - <structname>pg_wait_events</structname> - - - pg_wait_events - - - - 视图pg_wait_events提供等待事件的相关描述。 - - -
- <structname>pg_wait_events</structname> 列 - - - - - 列类型 - - - 描述 - - - - - - - - type text - - - 等待事件类型 - - - - - - name text - - - 等待事件名称 - - - - - - description text - - - 等待事件描述 - - - - -
-
- + diff --git a/zh/15/textsearch.sgml b/zh/15/textsearch.sgml index 0b95c3fe..f08b7bc3 100644 --- a/zh/15/textsearch.sgml +++ b/zh/15/textsearch.sgml @@ -2097,7 +2097,7 @@ ALTER TEXT SEARCH CONFIGURATION russian 分类词典示例 - 考虑简单的天文词库 thesaurus_astro,其中包含一些天文单词组合: + 考虑简单的天文词库 thesaurus_astro,其中包含一些天文单词组合: supernovae stars : sn @@ -2532,7 +2532,7 @@ ts_debug( config re - 以下是一个简单的示例: + 以下是一个简单的示例: SELECT * FROM ts_debug('english', 'a fat cat sat on a mat - it ate a fat rats'); diff --git a/zh/15/trigger.sgml b/zh/15/trigger.sgml index d830948f..c6361528 100644 --- a/zh/15/trigger.sgml +++ b/zh/15/trigger.sgml @@ -4,7 +4,7 @@ 触发器 - trigger + 触发器 @@ -73,38 +73,15 @@ 如果触发器被定义为 约束触发器,则 AFTER 触发器的执行可被推迟到事务末尾,而不是语句末尾。 - 无论哪种情况,触发器都作为触发它的语句所属同一事务的一部分执行,因此只要语句或触发器任一方发生错误,二者的效果都会回滚。此外,触发器总是以将该触发事件排入队列的角色身份运行,除非触发器函数标记为 - SECURITY DEFINER,那样的话则以函数所有者身份运行。 - - - - 若 INSERT 包含 ON CONFLICT DO UPDATE - 子句,则被触发的行上可能先执行行级 - BEFORE INSERT 触发器,再执行 - BEFORE UPDATE 触发器。若触发器不是 - 幂等的,这种交互可能很复杂,因为 BEFORE - INSERT 触发器所做更改会被 - BEFORE UPDATE 触发器看到, - 包括对 EXCLUDED 列的更改。 - - - - 注意,当指定 ON CONFLICT DO UPDATE 时,语句级 - UPDATE 触发器会执行,不管 - UPDATE 是否实际影响了行(也不管是否走到了 - UPDATE 分支)。带有 - ON CONFLICT DO UPDATEINSERT - 会先执行语句级 BEFORE INSERT - 触发器,再执行语句级 BEFORE UPDATE - 触发器,然后执行语句级 AFTER UPDATE - 触发器,最后执行语句级 AFTER INSERT - 触发器。 + 无论哪种情况,触发器都作为触发它的语句所属同一事务的一部分执行,因此只要语句或触发器任一方发生错误,二者的效果都会回滚。 如果某条语句以继承层次或分区层次中的父表为目标,它不会导致受影响子表上的语句级触发器触发;只有父表上的语句级触发器会触发。不过,任何受影响子表上的行级触发器仍会触发。 + INSERT 包含 ON CONFLICT DO UPDATE 子句,则行级 BEFORE INSERT 触发器和行级 BEFORE UPDATE 触发器的效果可能都会体现在更新后行的最终状态中,前提是引用了 EXCLUDED 列。不过,即使没有引用 EXCLUDED 列,这两组行级 BEFORE 触发器也可能都会执行。如果同时存在会更改正在插入/更新的行的 BEFORE INSERTBEFORE UPDATE 行级触发器,就应考虑可能出现令人意外的结果(即使它们的修改大致等效,如果不具有幂等性,也可能出现问题)。注意,语句级 UPDATE 触发器会在指定 ON CONFLICT DO UPDATE 时执行,不管 UPDATE 是否实际影响了行(也不管是否走到了 UPDATE 分支)。INSERT 如果带有 ON CONFLICT DO UPDATE 子句,会先执行语句级 BEFORE INSERT 触发器,再执行语句级 BEFORE UPDATE 触发器,然后执行语句级 AFTER UPDATE 触发器,最后执行语句级 AFTER INSERT 触发器。 + 如果对分区表执行 UPDATE 导致某行移动到另一个分区,这将表现为从原始分区执行一次 DELETE,然后向新分区执行一次 INSERT。在这种情况下,原始分区上的所有行级 BEFORE UPDATE 触发器和所有行级 @@ -125,7 +102,7 @@ - 在执行 MERGE 命令时,对于该命令动作中指定的事件,无论该动作最终是否实际执行,语句级 + 在执行 MERGE 命令时,对于 MERGE 命令的动作中指定的事件,无论该动作最终是否实际执行,语句级 BEFOREAFTER 触发器都会触发。这与更新零行的 UPDATE 语句相同:尽管没有行被更新,语句级触发器仍会触发。只有在某行确实被更新、插入或删除时,行级触发器才会触发。因此,完全可能出现这样的情况:某类动作的语句级触发器已经触发,而同类动作的行级触发器却一个也没有触发。 @@ -169,19 +146,18 @@ 生成列还有一些额外注意事项。 - generated columnin - triggers + 生成列在触发器中 存储型生成列会在 BEFORE 触发器之后、AFTER 触发器之前计算。因此,可以在 AFTER 触发器中检查生成值。在 BEFORE 触发器中,OLD 行如预期那样包含旧的 生成值,但 NEW 行尚未包含新的生成值,因此不应访问。对于 C 语言接口,此时该列内容未定义;更高层编程语言应阻止在 BEFORE 触发器中访问 NEW 行中的存储型 - 生成列。在 BEFORE 触发器中对生成列值所做的修改会被忽略并随后被覆盖。虚拟生成列在触发器触发时永远不会被计算。在 C 语言接口中,它们在触发器函数中的内容是未定义的;更高层编程语言应阻止在触发器中访问虚拟生成列。 + 生成列。在 BEFORE 触发器中对生成列值所做的修改会被忽略并随后被覆盖。 - 如果在同一关系上的同一事件为其定义了多个触发器,它们会按触发器名称的字母顺序触发。对于 BEFOREINSTEAD OF + 如果为同一关系上的同一事件定义了多个触发器,它们会按触发器名称的字母顺序触发。对于 BEFOREINSTEAD OF 触发器,每个触发器返回的、可能已经被修改过的行都会成为下一个触发器的输入。如果任何一个 BEFOREINSTEAD OF 触发器返回 NULL,则会放弃对该行执行该操作,并且后续触发器(针对该行)都不会再触发。 @@ -191,7 +167,7 @@ 条件,不过这个特性对它们用处不大。)在 BEFORE 触发器中, WHEN 条件就在函数即将执行或本会执行之前求值,因此使用 WHEN 与在触发器函数开头测试同样的条件并无实质差别。不过,在 - AFTER 触发器中,WHEN 条件会在行更改发生后立即求值,并决定是否要在语句末尾将一个事件排入队列以触发该触发器。因此,当 AFTER 触发器的 WHEN + AFTER 触发器中,WHEN 条件会在行更改发生后立即求值,并决定是否要将一个事件排入队列,以便在语句末尾触发该触发器。因此,当 AFTER 触发器的 WHEN 条件不返回真时,就不必排队该事件,也不必在语句末尾重新取出该行。如果触发器只需要针对少数几行触发,这会让修改大量行的语句显著加快。 INSTEAD OF 触发器不支持 WHEN 条件。 @@ -208,17 +184,10 @@ 如果触发器函数执行 SQL 命令,那么这些命令可能会再次触发触发器。这就是所谓的级联触发器。对级联层数没有直接限制。级联还有可能导致同一个触发器被递归调用;例如,一个 INSERT 触发器可能执行一条向同一个表再插入一行的命令,从而导致该 INSERT 触发器再次触发。因此,在这种场景下,避免无限递归是触发器编写者自己的责任。 - - 若外键约束指定了引用动作(即级联更新或级联删除),这些动作会通过在引用表上执行 - 普通 SQL UPDATEDELETE 命令完成。 - 特别地,引用表上存在的触发器会因这些更改而触发。若此类触发器修改或阻止了这些 - 命令之一的效果,最终可能破坏引用完整性。避免这种情况是触发器编写者的责任。 - - - trigger - arguments for trigger functions + 触发器 + 触发器函数的参数 在定义触发器时,可以为它指定参数。在触发器定义中包含参数,是为了让需求相似的不同触发器能够调用同一个函数。举例来说,可以有一个通用触发器函数,它接受两个列名作为参数,把当前用户写入其中一个列,把当前时间戳写入另一个列。只要编写得当,这个触发器函数就应独立于它所作用的具体表。因此,同一个函数可用于任何具有适当列的表上的 INSERT 事件,例如自动跟踪某个事务表中记录的创建。如果把它定义成 UPDATE 触发器,还可以用来跟踪最近更新事件。 @@ -301,13 +270,13 @@ 用 C 编写触发器函数 - trigger - in C + 触发器 + 在 C 中 - transition tables - referencing from C trigger + 过渡表 + 从 C 触发器中引用 @@ -319,7 +288,7 @@ - 当函数由触发器管理器调用时,不会向它传递任何普通参数,但会传递一个指向 TriggerData 结构体的 context 指针。C 函数可以通过执行下列宏来检查自己是否由触发器管理器调用: + 当函数由触发器管理器调用时,不会向它传递任何普通参数,但会传递一个指向 TriggerData 结构体的 上下文 指针。C 函数可以通过执行下列宏来检查自己是否由触发器管理器调用: CALLED_AS_TRIGGER(fcinfo) @@ -378,7 +347,7 @@ typedef struct TriggerData TRIGGER_FIRED_BEFORE(tg_event) - 如果触发器在操作之前触发,则返回 true。 + 如果触发器在操作之前触发,则返回真。 @@ -387,7 +356,7 @@ typedef struct TriggerData TRIGGER_FIRED_AFTER(tg_event) - 如果触发器在操作之后触发,则返回 true。 + 如果触发器在操作之后触发,则返回真。 @@ -396,7 +365,7 @@ typedef struct TriggerData TRIGGER_FIRED_INSTEAD(tg_event) - 如果触发器是取代该操作而触发,则返回 true。 + 如果触发器是取代该操作而触发,则返回真。 @@ -405,7 +374,7 @@ typedef struct TriggerData TRIGGER_FIRED_FOR_ROW(tg_event) - 如果触发器是因行级事件触发,则返回 true。 + 如果触发器是因行级事件触发,则返回真。 @@ -414,7 +383,7 @@ typedef struct TriggerData TRIGGER_FIRED_FOR_STATEMENT(tg_event) - 如果触发器是因语句级事件触发,则返回 true。 + 如果触发器是因语句级事件触发,则返回真。 @@ -423,7 +392,7 @@ typedef struct TriggerData TRIGGER_FIRED_BY_INSERT(tg_event) - 如果触发器是由 INSERT 命令触发,则返回 true。 + 如果触发器是由 INSERT 命令触发,则返回真。 @@ -432,7 +401,7 @@ typedef struct TriggerData TRIGGER_FIRED_BY_UPDATE(tg_event) - 如果触发器是由 UPDATE 命令触发,则返回 true。 + 如果触发器是由 UPDATE 命令触发,则返回真。 @@ -441,7 +410,7 @@ typedef struct TriggerData TRIGGER_FIRED_BY_DELETE(tg_event) - 如果触发器是由 DELETE 命令触发,则返回 true。 + 如果触发器是由 DELETE 命令触发,则返回真。 @@ -450,7 +419,7 @@ typedef struct TriggerData TRIGGER_FIRED_BY_TRUNCATE(tg_event) - 如果触发器是由 TRUNCATE 命令触发,则返回 true。 + 如果触发器是由 TRUNCATE 命令触发,则返回真。 @@ -609,16 +578,16 @@ typedef struct Trigger - 一个完整的触发器实例 + 一个完整的触发器示例 这里给出一个非常简单的、用 C 编写的触发器函数示例。(用过程语言编写的触发器示例可见各过程语言的文档。) - 如果某条命令试图向列 x 中插入空值,函数 - trigf 就会报告表 ttest - 中的行数,并跳过实际操作。(这样,这个触发器就起到了非空约束的作用,但不会中止事务。) + 函数 trigf 会报告表 ttest 中的行数, + 并在命令试图向列 x 中插入空值时跳过实际操作。 + (这样,这个触发器就起到了非空约束的作用,但不会中止事务。) @@ -677,7 +646,8 @@ trigf(PG_FUNCTION_ARGS) tupdesc = trigdata->tg_relation->rd_att; /* connect to SPI manager */ - SPI_connect(); + if ((ret = SPI_connect()) < 0) + elog(ERROR, "trigf (fired %s): SPI_connect returned %d", when, ret); /* get number of rows in table */ ret = SPI_exec("SELECT count(*) FROM ttest", 0); diff --git a/zh/15/typeconv.sgml b/zh/15/typeconv.sgml index 15e7c27c..984ee0cf 100644 --- a/zh/15/typeconv.sgml +++ b/zh/15/typeconv.sgml @@ -30,7 +30,7 @@ -PostgreSQL扫描器/解析器将词法元素分成五个基本类别:整数、非整数数字、字符串、标识符和关键字。大多数非数值类型的常量会先被归类为字符串。SQL语言定义允许用字符串指定类型名,而PostgreSQL可以利用这一机制让解析器从一开始就沿着正确的路径处理。例如,查询: +PostgreSQL扫描器/解析器将词法元素分成五个基本类别:整数、非整数数字、字符串、标识符和关键字。大多数非数值类型的常量会先被归类为字符串。SQL语言定义允许给字符串指定类型名,而PostgreSQL可以利用这一机制让解析器从一开始就沿着正确的路径处理。例如,查询: SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; @@ -41,7 +41,7 @@ SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; (1 row) -包含两个文字常量,它们的类型分别是textpoint。如果没有为某个字符串文字指定类型,那么它最初会被赋予占位类型unknown,并在后文所述的后续阶段解析。 +包含两个字面量,它们的类型分别是textpoint。如果没有为某个字符串字面量指定类型,那么它最初会被赋予占位类型unknown,并在后文所述的后续阶段解析。 @@ -166,11 +166,11 @@ SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; -检查是否存在一个恰好接受输入参数类型的操作符。如果存在(在被考虑的操作符集合中至多只有一个精确匹配),就使用它。若通过限定名调用(这种情况并不常见)某个允许不可信用户创建对象的模式中的操作符,而又缺少精确匹配,就会带来安全隐患 +检查是否存在一个恰好接受输入参数类型的操作符。如果存在(在被考虑的操作符集合中至多只有一个精确匹配),就使用它。若通过限定名调用(这种情况并不常见)某个允许不受信任的用户创建对象的模式中的操作符,而又缺少精确匹配,就会带来安全隐患 - 对于未带模式限定的名称,不会出现这种隐患,因为包含允许不可信用户创建对象的模式的搜索路径不是一种模式的安全使用方式。 + 对于未带模式限定的名称,不会出现这种隐患,因为包含允许不受信任的用户创建对象的模式的搜索路径不是一种模式的安全使用方式。 。在这种情况下,应通过对参数进行类型转换来强制获得精确匹配。 @@ -186,7 +186,7 @@ SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; -如果二元操作符调用的一个参数是unknown类型,而另一个是域类型,则接着检查是否存在两边都恰好接受该域基类型的操作符;如果有,就使用它。 +如果二元操作符调用的一个参数是unknown类型,而另一个是域类型,则接着检查是否存在两边都恰好接受该域基础类型的操作符;如果有,就使用它。 @@ -201,13 +201,13 @@ SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; -丢弃那些输入类型不匹配,且也无法通过隐式类型转换实现匹配的候选操作符。为此,假定unknown文字可以转换为任何类型。如果只剩一个候选操作符,就使用它;否则继续下一步。 +丢弃那些输入类型不匹配,且也无法通过隐式类型转换实现匹配的候选操作符。为此,假定unknown字面量可以转换为任何类型。如果只剩一个候选操作符,就使用它;否则继续下一步。 -如果任何输入参数是域类型,则在后续所有步骤中都把它当作该域的基类型。这样可以确保在解决操作符歧义时,域的行为与其基类型一致。 +如果任何输入参数是域类型,则在后续所有步骤中都把它当作该域的基础类型。这样可以确保在解决操作符歧义时,域的行为与其基础类型一致。 @@ -219,13 +219,13 @@ SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; -遍历所有候选操作符,保留那些在需要类型转换的最多位置上接受首选类型(属于输入数据类型的类型分类)的候选项。如果没有候选项接受首选类型,则保留全部候选项。如果只剩一个候选操作符,就使用它;否则继续下一步。 +遍历所有候选操作符,在需要类型转换的位置上,保留接受首选类型(属于输入数据类型的类型分类)的位置数最多的候选项。如果没有候选项接受首选类型,则保留全部候选项。如果只剩一个候选操作符,就使用它;否则继续下一步。 -如果有任何输入参数是unknown,就检查剩余候选操作符在这些参数位置上接受哪些类型分类。在每个位置上,如果有任何候选项接受string分类,就选择该分类。(这种偏向字符串的做法是合适的,因为unknown类型的文字看起来像字符串。)否则,如果所有剩余候选项都接受同一种类型分类,就选择该分类;否则失败,因为在缺少更多线索的情况下无法推断出正确选择。然后丢弃不接受所选类型分类的候选项。此外,如果有任何候选项接受该分类中的首选类型,就丢弃在该参数上接受非首选类型的候选项。如果没有候选项通过这些测试,则保留全部候选项。如果只剩一个候选操作符,就使用它;否则继续下一步。 +如果有任何输入参数是unknown,就检查剩余候选操作符在这些参数位置上接受哪些类型分类。在每个位置上,如果有任何候选项接受string分类,就选择该分类。(这种偏向字符串的做法是合适的,因为unknown类型的字面量看起来像字符串。)否则,如果所有剩余候选项都接受同一种类型分类,就选择该分类;否则失败,因为在缺少更多线索的情况下无法推断出正确选择。然后丢弃不接受所选类型分类的候选项。此外,如果有任何候选项接受该分类中的首选类型,就丢弃在该参数上接受非首选类型的候选项。如果没有候选项通过这些测试,则保留全部候选项。如果只剩一个候选操作符,就使用它;否则继续下一步。 @@ -273,7 +273,7 @@ SELECT |/ CAST(40 AS double precision) AS "square root of 40"; -一个只有一个未指定参数的例子: +一个参数未指定类型的例子: SELECT text 'abc' || 'def' AS "text and unknown"; @@ -301,7 +301,7 @@ SELECT 'abc' || 'def' AS "unspecified"; -这里对使用哪种类型没有初始提示,因为查询中没有指定任何类型。因此,解析器会查找所有候选操作符,并发现既有接受字符串分类输入的候选项,也有接受位串分类输入的候选项。由于在可用时优先选择字符串分类,所以会选中该分类,再使用字符串的首选类型text作为解析这些unknown类型文字的具体类型。 +这里对使用哪种类型没有初始提示,因为查询中没有指定任何类型。因此,解析器会查找所有候选操作符,并发现既有接受字符串分类输入的候选项,也有接受位串分类输入的候选项。由于在可用时优先选择字符串分类,所以会选中该分类,再使用字符串的首选类型text作为解析这些unknown类型字面量的具体类型。 @@ -318,7 +318,7 @@ SELECT @ '-4.5' AS "abs"; 4.5 (1 row) -这里,系统在应用所选操作符之前,已经把unknown类型文字隐式解析为float8。我们可以验证使用的确实是float8,而不是其他类型: +这里,系统在应用所选操作符之前,已经把unknown类型字面量隐式解析为float8。我们可以验证使用的确实是float8,而不是其他类型: SELECT @ '-4.5e500' AS "abs"; @@ -352,7 +352,7 @@ SELECT ~ CAST('20' AS int8) AS "negation"; 数组包含操作符类型解析 -下面是另一个解析一边已知、一边未知输入的操作符的例子: +下面是另一个解析带有一个已知类型输入和一个未知类型输入的操作符的例子: SELECT array[1,2] <@ '{1,2,3}' as "is subset"; @@ -361,7 +361,7 @@ SELECT array[1,2] <@ '{1,2,3}' as "is subset"; t (1 row) -PostgreSQL操作符目录中为中缀操作符<@定义了多个条目,但左侧能够接受整数数组的只有两种:数组包含(anyarray <@ anyarray)和范围包含(anyelement <@ anyrange)。由于这些多态伪类型(见)都不被视为首选类型,解析器无法据此消除歧义。不过,告诉它可以假定unknown类型文字与另一输入具有相同类型,也就是整数数组。这样两个操作符中只有一个能够匹配,因此会选择数组包含。(如果选中范围包含,就会报错,因为该字符串的格式并不是合法的范围文字。) +PostgreSQL操作符目录中为中缀操作符<@定义了多个条目,但左侧能够接受整数数组的只有两种:数组包含(anyarray <@ anyarray)和范围包含(anyelement <@ anyrange)。由于这些多态伪类型(见)都不被视为首选类型,解析器无法据此消除歧义。不过,要求它假定unknown类型字面量与另一输入具有相同类型,也就是整数数组。这样两个操作符中只有一个能够匹配,因此会选择数组包含。(如果选中范围包含,就会报错,因为该字符串的格式并不是合法的范围字面量。) @@ -370,7 +370,7 @@ SELECT array[1,2] <@ '{1,2,3}' as "is subset"; 域类型上的自定义操作符 -用户有时会尝试声明只适用于某个域类型的操作符。这是可行的,但远没有看上去那样有用,因为操作符解析规则被设计成优先选择作用于域基类型的操作符。考虑下面的例子: +用户有时会尝试声明只适用于某个域类型的操作符。这是可行的,但远没有看上去那样有用,因为操作符解析规则被设计成优先选择作用于域基础类型的操作符。考虑下面的例子: CREATE DOMAIN mytext AS text CHECK(...); CREATE FUNCTION mytext_eq_text (mytext, text) RETURNS boolean AS ...; @@ -379,11 +379,11 @@ CREATE TABLE mytable (val mytext); SELECT * FROM mytable WHERE val = 'foo'; -这个查询不会使用自定义操作符。解析器首先会检查是否存在mytext = mytext操作符(),但并不存在;然后它会考虑该域的基类型text,并检查是否存在text = text操作符(),而这是存在的;于是它会把unknown类型的文字解析为text,并使用text = text操作符。要让自定义操作符被使用,唯一的方法是显式地对该文字做类型转换: +这个查询不会使用自定义操作符。解析器首先会检查是否存在mytext = mytext操作符(),但并不存在;然后它会考虑该域的基础类型text,并检查是否存在text = text操作符(),而这是存在的;于是它会把unknown类型的字面量解析为text,并使用text = text操作符。要让自定义操作符被使用,唯一的方法是显式地对该字面量做类型转换: SELECT * FROM mytable WHERE val = text 'foo'; -这样就会根据精确匹配规则立即找到mytext = text操作符。如果解析过程进入最佳匹配规则,它们会主动排斥作用于域类型的操作符。如果不是这样,这类操作符会导致过多的操作符歧义失败,因为类型转换规则总是把域视为可以转换到其基类型或从其基类型转换而来,因此域操作符会在所有与基类型上同名操作符相同的场景中都被视为可用。 +这样就会根据精确匹配规则立即找到mytext = text操作符。如果解析过程进入最佳匹配规则,它们会主动排斥作用于域类型的操作符。如果不是这样,这类操作符会导致过多的操作符歧义失败,因为类型转换规则总是把域视为可以转换到其基础类型或从其基础类型转换而来,因此域操作符会在所有与基础类型上同名操作符相同的场景中都被视为可用。 @@ -422,27 +422,27 @@ SELECT * FROM mytable WHERE val = text 'foo'; -如果函数声明了一个VARIADIC数组参数,而调用时没有使用VARIADIC关键字,则把该函数视为其数组参数按需要被其元素类型的一个或多个出现所替换,以匹配该调用。扩展之后,该函数的有效参数类型可能与某个非VARIADIC函数完全相同。在这种情况下,使用搜索路径中较早出现的函数;如果两个函数位于同一模式,则优先选择非VARIADIC函数。 +如果函数声明了一个VARIADIC数组参数,而调用时没有使用VARIADIC关键字,则把数组参数视为一个或多个其元素类型的参数,个数按匹配该调用的需要确定。扩展之后,该函数的有效参数类型可能与某个非VARIADIC函数完全相同。在这种情况下,使用搜索路径中较早出现的函数;如果两个函数位于同一模式,则优先选择非VARIADIC函数。 -通过限定名调用某个允许不可信用户创建对象的模式中找到的可变参数函数时,会带来安全隐患 +通过限定名调用某个允许不受信任的用户创建对象的模式中找到的可变参数函数时,会带来安全隐患 - 对于未带模式限定的名称,不会出现这种隐患,因为包含允许不可信用户创建对象的模式的搜索路径不是一种模式的安全使用方式。 + 对于未带模式限定的名称,不会出现这种隐患,因为包含允许不受信任的用户创建对象的模式的搜索路径不是一种模式的安全使用方式。 - 。恶意用户可以借此劫持调用,并以你的身份执行任意 SQL 函数。改为使用带有VARIADIC关键字的调用可以绕过这一隐患。对于填充VARIADIC "any"参数的调用,往往没有包含VARIADIC关键字的等价写法。要安全地发出这类调用,该函数所在模式必须只允许可信用户创建对象。 + 。恶意用户可以借此劫持调用,并以你的身份执行任意 SQL 函数。改为使用带有VARIADIC关键字的调用可以绕过这一隐患。对于填充VARIADIC "any"参数的调用,往往没有包含VARIADIC关键字的等价写法。要安全地发出这类调用,该函数所在模式必须只允许受信任的用户创建对象。 -带有参数默认值的函数,被认为可以匹配任何省略了零个或多个可默认参数位置的调用。如果不止一个这样的函数能匹配某个调用,则使用搜索路径中最早出现的那一个。如果同一模式中存在两个或更多这样的函数,并且它们在未使用默认值的参数位置上的参数类型相同(如果它们具有不同的可默认参数集合,这种情况是可能的),系统就无法判断该偏好哪一个;如果找不到更好的匹配,就会报有歧义的函数调用错误。 +带有参数默认值的函数,被认为可以匹配任何省略了零个或多个可使用默认值的参数位置的调用。如果不止一个这样的函数能匹配某个调用,则使用搜索路径中最早出现的那一个。如果同一模式中存在两个或更多这样的函数,并且它们在未使用默认值的参数位置上的参数类型相同(如果它们具有不同的带有默认值的参数集合,这种情况是可能的),系统就无法判断该偏好哪一个;如果找不到更好的匹配,就会报有歧义的函数调用错误。 -通过限定名调用某个允许不可信用户创建对象的模式中的任意函数时,会带来可用性隐患。恶意用户可以用现有函数的名字创建一个新函数,复制该函数的参数,并附加带有默认值的新参数。这样就会阻止对原始函数的新调用。为避免这种隐患,应把函数放在只允许可信用户创建对象的模式中。 +通过限定名调用某个允许不受信任的用户创建对象的模式中的任意函数时,会带来可用性隐患。恶意用户可以用现有函数的名字创建一个新函数,复制该函数的参数,并附加带有默认值的新参数。这样就会阻止对原始函数的新调用。为避免这种隐患,应把函数放在只允许受信任的用户创建对象的模式中。 @@ -451,14 +451,14 @@ SELECT * FROM mytable WHERE val = text 'foo'; -检查是否存在一个恰好接受输入参数类型的函数。如果存在(在被考虑的函数集合中至多只有一个精确匹配),就使用它。若通过限定名调用某个允许不可信用户创建对象的模式中的函数,而又缺少精确匹配,就会带来安全隐患。在这种情况下,应通过对参数进行类型转换来强制获得精确匹配。(涉及unknown的情况在这一步永远找不到匹配。) +检查是否存在一个恰好接受输入参数类型的函数。如果存在(在被考虑的函数集合中至多只有一个精确匹配),就使用它。若通过限定名调用某个允许不受信任的用户创建对象的模式中的函数,而又缺少精确匹配,就会带来安全隐患。在这种情况下,应通过对参数进行类型转换来强制获得精确匹配。(涉及unknown的情况在这一步永远找不到匹配。) -如果没有找到精确匹配,就检查该函数调用是否看起来像一种特殊的类型转换请求。这种情况发生在:函数调用只有一个参数,且函数名与某个数据类型的(内部)名称相同。此外,函数参数必须是unknown类型文字,或者是一种能够进行二进制强制转换到该命名数据类型的类型,或者是一种可以通过应用其 I/O 函数转换为该命名数据类型的类型(也就是说,该转换要么转到某种标准字符串类型,要么从某种标准字符串类型转来)。满足这些条件时,该函数调用会被当作一种CAST形式。 +如果没有找到精确匹配,就检查该函数调用是否看起来像一种特殊的类型转换请求。这种情况发生在:函数调用只有一个参数,且函数名与某个数据类型的(内部)名称相同。此外,函数参数必须是unknown类型字面量,或者是一种可以二进制强制转换为该命名数据类型的类型,或者是一种可以通过应用其 I/O 函数转换为该命名数据类型的类型(也就是说,该转换要么转到某种标准字符串类型,要么从某种标准字符串类型转来)。满足这些条件时,该函数调用会被当作一种CAST形式。 之所以有这一步,是为了在不存在实际类型转换函数的情况下仍支持函数风格的类型转换写法。如果存在类型转换函数,按惯例它会以其输出类型命名,因此无需为此设置特殊情况。更多说明见。 @@ -475,13 +475,13 @@ SELECT * FROM mytable WHERE val = text 'foo'; -丢弃那些输入类型不匹配,且也无法通过隐式类型转换实现匹配的候选函数。为此,假定unknown文字可以转换为任何类型。如果只剩一个候选函数,就使用它;否则继续下一步。 +丢弃那些输入类型不匹配,且也无法通过隐式类型转换实现匹配的候选函数。为此,假定unknown字面量可以转换为任何类型。如果只剩一个候选函数,就使用它;否则继续下一步。 -如果任何输入参数是域类型,则在后续所有步骤中都把它当作该域的基类型。这样可以确保在解决函数歧义时,域的行为与其基类型一致。 +如果任何输入参数是域类型,则在后续所有步骤中都把它当作该域的基础类型。这样可以确保在解决函数歧义时,域的行为与其基础类型一致。 @@ -493,13 +493,13 @@ SELECT * FROM mytable WHERE val = text 'foo'; -遍历所有候选函数,保留那些在需要类型转换的最多位置上接受首选类型(属于输入数据类型的类型分类)的候选项。如果没有候选项接受首选类型,则保留全部候选项。如果只剩一个候选函数,就使用它;否则继续下一步。 +遍历所有候选函数,在需要类型转换的位置上,保留接受首选类型(属于输入数据类型的类型分类)的位置数最多的候选项。如果没有候选项接受首选类型,则保留全部候选项。如果只剩一个候选函数,就使用它;否则继续下一步。 -如果有任何输入参数是unknown,就检查剩余候选函数在这些参数位置上接受哪些类型分类。在每个位置上,如果有任何候选项接受string分类,就选择该分类。(这种偏向字符串的做法是合适的,因为unknown类型的文字看起来像字符串。)否则,如果所有剩余候选项都接受同一种类型分类,就选择该分类;否则失败,因为在缺少更多线索的情况下无法推断出正确选择。然后丢弃不接受所选类型分类的候选项。此外,如果有任何候选项接受该分类中的首选类型,就丢弃在该参数上接受非首选类型的候选项。如果没有候选项通过这些测试,则保留全部候选项。如果只剩一个候选函数,就使用它;否则继续下一步。 +如果有任何输入参数是unknown,就检查剩余候选函数在这些参数位置上接受哪些类型分类。在每个位置上,如果有任何候选项接受string分类,就选择该分类。(这种偏向字符串的做法是合适的,因为unknown类型的字面量看起来像字符串。)否则,如果所有剩余候选项都接受同一种类型分类,就选择该分类;否则失败,因为在缺少更多线索的情况下无法推断出正确选择。然后丢弃不接受所选类型分类的候选项。此外,如果有任何候选项接受该分类中的首选类型,就丢弃在该参数上接受非首选类型的候选项。如果没有候选项通过这些测试,则保留全部候选项。如果只剩一个候选函数,就使用它;否则继续下一步。 @@ -680,7 +680,7 @@ SELECT substr(CAST (1234 AS text), 3); -否则,尝试把表达式转换为目标类型。如果这两种类型之间在pg_cast目录中登记了赋值类型转换(见),就可以这样做。另一种情况是,如果表达式是unknown类型文字,则会把文字字符串的内容送入目标类型的输入转换例程。 +否则,尝试把表达式转换为目标类型。如果这两种类型之间在pg_cast目录中登记了赋值类型转换(见),就可以这样做。另一种情况是,如果表达式是unknown类型字面量,则会把字符串字面量的内容送入目标类型的输入转换例程。 @@ -713,7 +713,7 @@ SELECT v, octet_length(v) FROM vv; -这里实际发生的是,两个unknown类型文字默认都被解析为text,从而使||操作符被解析为text的连接操作。然后,操作符得到的text结果被转换为bpcharblank-padded char,即character数据类型的内部名称),以匹配目标列类型。(由于从textbpchar的转换是二进制可强制转换的,这一步不会插入任何真实的函数调用。)最后,系统目录中找到尺寸调整函数bpchar(bpchar, integer, boolean),并把它应用到操作符结果以及存储列长度上。这个特定于类型的函数会执行所需的长度检查并补齐填充空格。 +这里实际发生的是,两个unknown类型字面量默认都被解析为text,从而使||操作符被解析为text的连接操作。然后,操作符得到的text结果被转换为bpchar用空格填充的字符,blank-padded char,即character数据类型的内部名称),以匹配目标列类型。(由于从textbpchar的转换是二进制可强制转换的,这一步不会插入任何真实的函数调用。)最后,系统从系统目录中找到尺寸调整函数bpchar(bpchar, integer, boolean),并把它应用到操作符结果以及存储列长度上。这个特定于类型的函数会执行所需的长度检查并补齐填充空格。 @@ -770,10 +770,10 @@ SQL 的UNION结构必须让可能不同的类型彼此匹配 -如果任何输入是域类型,则在后续所有步骤中都把它当作该域的基类型。 +如果任何输入是域类型,则在后续所有步骤中都把它当作该域的基础类型。 - 这在某种程度上类似于操作符和函数对域输入的处理方式;只要用户确保所有输入都隐式或显式地正好属于该域类型,这种行为就能让域类型在UNION或类似结构中得以保留。否则,就会使用该域的基类型。 + 这在某种程度上类似于操作符和函数对域输入的处理方式;只要用户确保所有输入都隐式或显式地正好属于该域类型,这种行为就能让域类型在UNION或类似结构中得以保留。否则,就会使用该域的基础类型。 @@ -832,7 +832,7 @@ SELECT text 'a' AS "text" UNION SELECT 'b'; b (2 rows) -这里,unknown类型文字'b'会被解析为text类型。 +这里,unknown类型字面量'b'会被解析为text类型。 @@ -850,7 +850,7 @@ SELECT 1.2 AS "numeric" UNION SELECT 1; 1.2 (2 rows) -文字常量1.2的类型是numeric,而integer1可以隐式转换为numeric,因此使用该类型。 +字面量1.2的类型是numeric,而integer1可以隐式转换为numeric,因此使用该类型。 @@ -905,17 +905,17 @@ ERROR: UNION types text and integer cannot be matched -前面各节给出的规则会为 SQL 查询中的所有表达式分配非unknown的数据类型,唯一的例外是作为SELECT命令简单输出列出现的未指定类型文字常量。例如,在 +前面各节给出的规则会为 SQL 查询中的所有表达式分配非unknown的数据类型,唯一的例外是作为SELECT命令简单输出列出现的未指定类型字面量。例如,在 SELECT 'Hello World'; -中,没有任何信息能够表明这个字符串文字应该视为哪种类型。在这种情况下,PostgreSQL会退回到把该文字解析为text类型。 +中,没有任何信息能够表明这个字符串字面量应该视为哪种类型。在这种情况下,PostgreSQL会退回到把该字面量解析为text类型。 -当SELECTUNION(或INTERSECTEXCEPT)结构的一端,或者出现在INSERT ... SELECT中时,这条规则不适用,因为前面各节给出的规则具有更高优先级。在前一种情况下,未指定类型文字的类型可以从UNION的另一侧取得;在后一种情况下,则从目标列取得。 +当SELECTUNION(或INTERSECTEXCEPT)结构的一端,或者出现在INSERT ... SELECT中时,这条规则不适用,因为前面各节给出的规则具有更高优先级。在前一种情况下,未指定类型字面量的类型可以从UNION的另一侧取得;在后一种情况下,则从目标列取得。 @@ -925,7 +925,7 @@ SELECT 'Hello World'; - 在PostgreSQL 10 之前,这条规则并不存在,SELECT输出列表中的未指定类型文字会被保留为unknown类型。这会带来各种不良后果,因此后来做了修改。 + 在PostgreSQL 10 之前,这条规则并不存在,SELECT输出列表中的未指定类型字面量会被保留为unknown类型。这会带来各种不良后果,因此后来做了修改。 diff --git a/zh/15/user-manag.sgml b/zh/15/user-manag.sgml index 561d4fe7..6c5ecd75 100644 --- a/zh/15/user-manag.sgml +++ b/zh/15/user-manag.sgml @@ -64,19 +64,15 @@ dropuser name - 要确定现有角色的集合,可以查看pg_roles系统目录,例如: + 要确定现有角色的集合,请查看 pg_roles 系统目录,例如 SELECT rolname FROM pg_roles; - 或者只看那些能够登录的角色: - -SELECT rolname FROM pg_roles WHERE rolcanlogin; - - 程序的\du元命令也很适合列出现有角色。 + 使用 程序的 \du 元命令也可以列出现有角色。 - 为了完成数据库系统的初始引导,一个刚初始化的系统总会包含一个预定义的可登录角色。该角色总是一个超级用户,并且除非另行指定了不同名称,否则它的名称与用initdb初始化数据库集簇的操作系统用户相同。这个角色通常命名为postgres。要创建更多角色,必须先以这个初始角色建立连接。 + 为了完成数据库系统的初始引导,一个刚初始化的系统总会包含一个预定义角色。该角色总是一个超级用户,并且除非另行指定了不同名称,否则它的名称与用initdb初始化数据库集簇的操作系统用户相同。这个角色通常命名为postgres。要创建更多角色,必须先以这个初始角色建立连接。 @@ -135,11 +131,14 @@ CREATE USER name; 角色必须被明确授予创建更多角色的权限(超级用户除外,因为后者会绕过所有权限检查)。要创建这样的角色,使用CREATE ROLE name CREATEROLE。 - 具有CREATEROLE权限的角色,可以更改和删除那些以带ADMIN选项的形式授予给该CREATEROLE用户的角色。非超级用户的CREATEROLE用户在创建新角色时会自动得到这种授权,因此默认情况下,CREATEROLE用户可以更改和删除自己创建的角色。更改角色包括使用ALTER ROLE能进行的大多数修改,例如更改密码。它还包括使用COMMENTSECURITY LABEL命令对角色进行的修改。 + 具有CREATEROLE权限的角色,也可以更改和删除其他角色,并且可以授予或撤销其中的成员资格。更改角色包括使用ALTER ROLE能进行的大多数修改,例如更改密码。它还包括使用COMMENTSECURITY LABEL命令对角色进行的修改。 然而,CREATEROLE并不赋予创建SUPERUSER角色的能力,也不赋予对已经存在的SUPERUSER角色的任何控制权。此外,CREATEROLE也不赋予创建REPLICATION用户的能力,也不能授予或撤销REPLICATION权限,也不能修改这类用户的角色属性。不过,它允许在REPLICATION角色上使用ALTER ROLE ... SETALTER ROLE ... RENAME,以及使用COMMENT ON ROLESECURITY LABEL ON ROLEDROP ROLE。最后,CREATEROLE也不赋予授予或撤销BYPASSRLS权限的能力。 + + 由于CREATEROLE权限允许用户即使对某些角色(尚)没有任何访问权,也能授予或撤销其中的成员资格,因此CREATEROLE用户可以获得系统中每个预定义角色的能力,包括pg_execute_server_programpg_write_server_files这类高权限角色。 + @@ -168,7 +167,7 @@ CREATE USER name; 默认情况下,角色会继承其所属角色的权限。不过,要创建一个默认不继承权限的角色,使用CREATE ROLE name - NOINHERIT。另外,也可以在单个授权时使用WITH INHERIT TRUEWITH INHERIT FALSE来覆盖继承行为。 + NOINHERIT。 @@ -205,11 +204,7 @@ ALTER ROLE myname SET enable_indexscan TO off; 这会保存该设置(但不会立即生效)。在该角色后续建立的连接中,它看起来就像在会话开始之前执行了SET enable_indexscan TO off一样。你仍然可以在会话期间更改该设置;它只会作为默认值。要移除角色特定默认设置,使用ALTER ROLE rolename RESET varname。注意,附加到没有LOGIN权限的角色上的角色特定默认值几乎没有用,因为它们永远不会生效。 - - 当非超级用户利用CREATEROLE权限创建角色时,所创建的角色会自动重新授予给创建用户,就像引导超级用户执行了命令GRANT created_user TO creating_user WITH ADMIN TRUE, SET FALSE, - INHERIT FALSE一样。由于CREATEROLE用户只有在对现有角色拥有ADMIN OPTION时,才能对该角色行使特殊权限,这项授权恰好足以让CREATEROLE用户管理自己创建的角色。不过,因为它是以INHERIT FALSE, SET - FALSE创建的,CREATEROLE用户不会继承所创建角色的权限,也不能通过SET ROLE访问该角色的权限。然而,由于任何对某角色拥有ADMIN OPTION的用户都可以把该角色的成员资格授予任何其他用户,CREATEROLE用户只需使用INHERIT和/或SET选项把该角色再次授予自己,就可以获得对所创建角色的访问能力。因此,默认不继承权限、也不默认授予SET ROLE,只是为了防止意外,而不是一种安全特性。还要注意,由于这项自动授权是由引导超级用户发出的,CREATEROLE用户自己不能撤销或更改它;不过,任何超级用户都可以撤销或修改它,并向其他CREATEROLE用户发出额外的此类授权。无论何时,对某角色拥有ADMIN OPTIONCREATEROLE用户都可以管理该角色。 - + @@ -241,25 +236,27 @@ REVOKE group_role FROM role1 - 组角色的成员可以通过两种方式使用该角色的权限。第一,获授成员资格且带有SET选项的成员角色可以通过SET ROLE临时成为该组角色。在这种状态下,数据库会话可以使用组角色的权限,而不是原始登录角色的权限,并且创建的任何数据库对象都被认为归组角色所有,而不是归登录角色所有。第二,获授成员资格且带有INHERIT选项的成员角色,会自动拥有其直接或间接所属角色的权限,不过一旦成员资格链上某一段缺少继承选项,这条链就会在那里终止。举例来说,假设我们执行了: + 组角色的成员可以通过两种方式使用该角色的权限。首先,组的每个成员都可以显式执行 + SET ROLE,以暂时成为该组角色。在这种状态下,数据库会话可以使用组角色的权限,而不是原始登录角色的权限;创建的任何数据库对象也被视为由组角色而非登录角色拥有。其次,具有 INHERIT 属性的成员角色可以自动使用其所属角色的权限,包括这些角色继承的所有权限。例如,假定我们已经执行了: -CREATE ROLE joe LOGIN; -CREATE ROLE admin; -CREATE ROLE wheel; -CREATE ROLE island; -GRANT admin TO joe WITH INHERIT TRUE; -GRANT wheel TO admin WITH INHERIT FALSE; -GRANT island TO joe WITH INHERIT TRUE, SET FALSE; +CREATE ROLE joe LOGIN INHERIT; +CREATE ROLE admin NOINHERIT; +CREATE ROLE wheel NOINHERIT; +GRANT admin TO joe; +GRANT wheel TO admin; - 以角色joe建立连接后,数据库会话立即可以使用直接授予joe的权限,以及授予adminisland的任何权限,因为joe继承了这些权限。然而,授予wheel的权限不可用,因为尽管joe间接是wheel的成员,但这层成员资格是经由使用WITH INHERIT FALSE授予的admin得来的。执行: + 以角色 joe 连接后,数据库会话立即可以使用直接授予 joe 的权限,以及授予 admin 的所有权限,因为 joe + 继承 admin 的权限。不过,授予 wheel 的权限不可用,因为即使 joe 间接属于 wheel,该成员资格也是通过 admin 获得的,而后者具有 NOINHERIT 属性。执行以下命令后: SET ROLE admin; - 之后,会话将只能使用授予admin的权限,而不能使用授予joeisland的权限。再执行: + 会话将只能使用授予 + admin 的权限,而不能使用授予 joe 的权限。执行以下命令后: SET ROLE wheel; - 之后,会话将只能使用授予wheel的权限,而不能使用授予joeadmin的权限。原始权限状态可通过以下任一方式恢复: + 会话将只能使用授予 + wheel 的权限,而不能使用授予 joeadmin 的权限。使用以下任一命令可以恢复原始的权限状态: SET ROLE joe; SET ROLE NONE; @@ -269,7 +266,7 @@ RESET ROLE; - SET ROLE命令总是允许切换到原始登录角色直接或间接所属的任何角色,只要存在一条成员资格授权链,并且链上的每一段都具有SET TRUE(默认值)。因此,在上例中,没有必要先成为admin再成为wheel。另一方面,根本不可能成为islandjoe只能通过继承来使用那些权限。 + SET ROLE命令总是允许切换到原始登录角色直接或间接所属的任何角色。因此,在上例中,没有必要先成为admin再成为wheel @@ -312,12 +309,12 @@ ALTER TABLE bobs_table OWNER TO alice; - 一旦有价值的对象都已转移给新拥有者,被删除角色所拥有的其余对象即可使用DROP OWNED命令删除。同样,由于该命令不能访问其他数据库中的对象,因此必须在包含该角色所拥有对象的每个数据库中运行它。另外,DROP + 一旦有价值的对象都已转移给新拥有者,待删除角色所拥有的其余对象即可使用DROP OWNED命令删除。同样,由于该命令不能访问其他数据库中的对象,因此必须在包含该角色所拥有对象的每个数据库中运行它。另外,DROP OWNED不会删除整个数据库或表空间,因此如果该角色拥有任何尚未转移给新拥有者的数据库或表空间,就必须手工删除它们。 - DROP OWNED还会负责移除授予目标角色、但不属于它自身对象的任何权限。由于REASSIGN OWNED不会处理这类对象,所以通常需要同时运行REASSIGN OWNEDDROP OWNED(按这个顺序!),才能完整移除待删除角色的依赖关系。 + DROP OWNED还会负责移除目标角色在其他角色所拥有的对象上获授的所有权限。由于REASSIGN OWNED不会处理这类对象,所以通常需要同时运行REASSIGN OWNEDDROP OWNED(按这个顺序!),才能完整移除待删除角色的依赖关系。 @@ -347,12 +344,11 @@ DROP ROLE doomed_role; - PostgreSQL提供了一组预定义角色,这些角色提供对某些常见的、需要特权的能力和信息的访问。管理员(包括具有 - CREATEROLE权限的角色)可以把这些角色GRANT给其环境中的用户和/或其他角色,从而让这些用户获得所指定的能力和信息。 + PostgreSQL提供了一组预定义角色,它们提供对某些常见且需要权限的能力和信息的访问。管理员(包括具有CREATEROLE权限的角色)可以把这些角色GRANT给其环境中的用户和/或其他角色,从而让这些用户获得所指定的能力和信息。 - 预定义角色见。请注意,随着将来增加更多能力,各个角色的具体权限可能会发生变化。管理员应关注发行说明中的变更。 + 预定义角色在中描述。请注意,随着将来增加更多能力,各个角色的具体权限可能会发生变化。管理员应关注发行说明中的变更。 @@ -369,11 +365,11 @@ DROP ROLE doomed_role; pg_read_all_data - 读取所有数据(表、视图、序列),其效果就像对这些对象拥有 SELECT 权限、并对所有模式拥有 USAGE 权限,即使并未显式授予这些权限。该角色没有设置 BYPASSRLS 角色属性。如果正在使用 RLS,管理员可能希望对被授予此角色的角色设置 BYPASSRLS + 读取所有数据(表、视图、序列),其效果就像对这些对象拥有SELECT权限并对所有模式拥有 USAGE 权限一样,即使没有被显式授予。该角色没有设置角色属性BYPASSRLS。如果正在使用 RLS,管理员可能希望对被 GRANT 此角色的角色设置BYPASSRLS pg_write_all_data - 写入所有数据(表、视图、序列),其效果就像对这些对象拥有 INSERTUPDATEDELETE 权限、并对所有模式拥有 USAGE 权限,即使并未显式授予这些权限。该角色没有设置 BYPASSRLS 角色属性。如果正在使用 RLS,管理员可能希望对被授予此角色的角色设置 BYPASSRLS + 写入所有数据(表、视图、序列),其效果就像对这些对象拥有INSERTUPDATEDELETE权限并对所有模式拥有 USAGE 权限一样,即使没有被显式授予。该角色没有设置角色属性BYPASSRLS。如果正在使用 RLS,管理员可能希望对被 GRANT 此角色的角色设置BYPASSRLS pg_read_all_settings @@ -381,19 +377,19 @@ DROP ROLE doomed_role; pg_read_all_stats - 读取所有 pg_stat_* 视图,并使用各种与统计信息相关的扩展,即使是那些通常仅对超级用户可见的扩展。 + 读取所有 pg_stat_* 视图,并使用各种与统计信息相关的扩展,包括通常仅对超级用户可见的内容。 pg_stat_scan_tables - 执行可能会对表持有 ACCESS SHARE 锁、并且可能持续较长时间的监控函数。 + 执行可能在表上持有ACCESS SHARE锁并且持续较长时间的监控函数。 pg_monitor - 读取或执行各种监控视图和函数。该角色是 pg_read_all_settingspg_read_all_statspg_stat_scan_tables 的成员。 + 读取或执行各种监控视图和函数。该角色是pg_read_all_settingspg_read_all_statspg_stat_scan_tables的成员。 pg_database_owner - 无。成员资格隐式地由当前数据库拥有者组成。 + 无。其成员隐式地由当前数据库拥有者组成。 pg_signal_backend @@ -401,46 +397,46 @@ DROP ROLE doomed_role; pg_read_server_files - 允许使用 COPY 和其他文件访问函数,从服务器上数据库可访问的任何位置读取文件。 + 允许使用COPY和其他文件访问函数,从服务器上数据库可访问的任何位置读取文件。 pg_write_server_files - 允许使用 COPY 和其他文件访问函数,向服务器上数据库可访问的任何位置写入文件。 + 允许使用COPY和其他文件访问函数,向服务器上数据库可访问的任何位置写入文件。 pg_execute_server_program - 允许使用 COPY 和其他允许执行服务器端程序的函数,以数据库运行所用用户的身份在数据库服务器上执行程序。 + 允许使用COPY和其他允许执行服务器端程序的函数,以数据库运行所用用户的身份在数据库服务器上执行程序。 pg_checkpoint - 允许执行 CHECKPOINT 命令。 + 允许执行CHECKPOINT命令。
- pg_monitorpg_read_all_settingspg_read_all_statspg_stat_scan_tables 这几个角色旨在让管理员更容易为监控数据库服务器配置一个角色。它们授予一组常见权限,使该角色能够读取各种有用的配置设置、统计信息以及其他通常仅限超级用户查看的系统信息。 + pg_monitorpg_read_all_settingspg_read_all_statspg_stat_scan_tables角色旨在让管理员能够方便地为监控数据库服务器配置一个角色。它们授予一组常见权限,使该角色能够读取各种有用的配置设置、统计信息以及其他通常仅限超级用户查看的系统信息。 - pg_database_owner 角色有一个隐式的、依赖于具体场景的成员,也就是当前数据库的拥有者。和任何角色一样,它可以拥有对象,也可以接收访问权限授予。因此,一旦 pg_database_owner 在某个模板数据库中拥有权限,由该模板实例化出的每个数据库的拥有者都会行使这些权限。pg_database_owner 不能成为任何角色的成员,也不能拥有非隐式成员。最初,这个角色拥有 public 模式,因此每个数据库拥有者都管理该模式在本数据库中的使用。 + pg_database_owner角色有一个隐式的、取决于具体情况的成员,即当前数据库的拥有者。像任何角色一样,它可以拥有对象或获得访问权限授权。因此,一旦pg_database_owner在模板数据库中拥有权限,由该模板实例化的每个数据库的拥有者都将行使这些权限。pg_database_owner不能成为任何角色的成员,也不能拥有非隐式成员。最初,这个角色拥有public模式,因此每个数据库拥有者都管理该模式在本数据库中的使用。 - pg_signal_backend 角色旨在允许管理员启用受信任但非超级用户的角色,以便向其他后端发送信号。当前,这个角色允许发送用于取消其他后端查询或终止其会话的信号。不过,被授予此角色的用户不能向超级用户拥有的后端发送信号。见 。 + pg_signal_backend角色旨在让管理员能够允许受信任但非超级用户的角色向其他后端发送信号。目前这个角色允许发送信号来取消另一个后端上的查询或终止其会话。不过,被授予此角色的用户不能向由超级用户拥有的后端发送信号。见 - pg_read_server_filespg_write_server_filespg_execute_server_program 角色旨在允许管理员使用受信任但非超级用户的角色,使其能够以数据库运行所用的操作系统用户身份访问文件并在数据库服务器上运行程序。由于这些角色能够访问服务器文件系统上的任意文件,因此在直接访问文件时会绕过所有数据库级权限检查,而且它们可能被用来获取超级用户级别的访问权限,所以向用户授予这些角色时必须非常谨慎。 + pg_read_server_filespg_write_server_filespg_execute_server_program角色旨在让管理员能够使受信任但非超级用户的角色能够以数据库运行所用用户的身份访问文件并在数据库服务器上运行程序。由于这些角色能够访问服务器文件系统上的任意文件,它们在直接访问文件时会绕过所有数据库级权限检查,并且可被用来获得超级用户级别的访问能力,因此向用户授予这些角色时必须极其谨慎。 - 授予这些角色时应当谨慎,确保它们只在需要的地方使用,并且明确理解这些角色会授予对特权信息的访问。 + 授予这些角色时应当谨慎,确保它们只在需要时使用,并理解这些角色会授予对需要特权才能访问的信息的访问。 - 管理员可以使用 GRANT 命令把这些角色授予用户,例如: + 管理员可以使用GRANT命令把这些角色的访问授予用户,例如: GRANT pg_signal_backend TO admin_user; @@ -453,7 +449,7 @@ GRANT pg_signal_backend TO admin_user; 函数安全性 - 函数、触发器和行级安全策略允许用户把代码插入后端服务器,而其他用户可能会无意中执行这些代码。因此,这些机制使用户能够相对容易地对其他用户实施特洛伊木马攻击。最强的保护方式是严格控制谁能定义对象。如果这不可行,则应编写只引用拥有者可信对象的查询,并从search_path中移除任何允许不受信任用户创建对象的模式。 + 函数、触发器和行级安全策略允许用户把代码插入后端服务器,而其他用户可能会无意中执行这些代码。因此,这些机制使用户能够相对容易地对其他用户实施特洛伊木马攻击。最强的保护方式是严格控制谁能定义对象。如果这不可行,则应编写只引用拥有者可信的对象的查询,并从search_path中移除任何允许不受信任用户创建对象的模式。 diff --git a/zh/15/vacuumlo.sgml b/zh/15/vacuumlo.sgml index 9e80b19f..cc2c04f5 100644 --- a/zh/15/vacuumlo.sgml +++ b/zh/15/vacuumlo.sgml @@ -8,7 +8,7 @@ vacuumlo 1 - Application + 应用程序 diff --git a/zh/15/wal.sgml b/zh/15/wal.sgml index 6ca8e63c..416d9b8c 100644 --- a/zh/15/wal.sgml +++ b/zh/15/wal.sgml @@ -157,7 +157,8 @@ - 数据页默认带有校验和,而记录在 WAL 记录中的整页镜像始终受校验和保护。 + 数据页默认并不带校验和,不过,记录在 WAL 记录中的整页镜像始终受保护;有关启用数据校验和的细节,见 initdb @@ -197,14 +198,14 @@ - 默认情况下,数据页受校验和保护,但也可以选择为集簇禁用。启用后,每个数据页 + 默认情况下,数据页不受校验和保护,但可以选择为集簇启用。启用后,每个数据页 都包含一个校验和,在页面写入时更新,并在页面每次被读取时进行验证。只有数据 页受校验和保护;内部数据结构和临时文件不受保护。 可以在使用 initdb - 初始化集簇时禁用校验和。之后也可以作为离线操作启用或禁用。数据校验和是在整个 + 初始化集簇时启用校验和。之后也可以作为离线操作启用或禁用。数据校验和是在整个 集簇级别启用或禁用的,不能为单个数据库或表分别指定。 @@ -389,9 +390,9 @@ 检查点检查点 是事务序列中的一些点,在这些点上可以保证堆和索引数据文件已经用检查点之前写入 - 的全部信息进行了更新。执行检查点时,所有脏数据页都会刷写到磁盘,并向 WAL - 文件写入一条特殊的检查点记录。(更改记录此前已经刷入 WAL - 文件。)如果发生崩溃,崩溃恢复过程会查看最新的检查点记录,以确定应该从 WAL + 的全部信息进行了更新。执行检查点时,所有脏数据页都会刷盘,并向 WAL + 文件写入一条特殊的检查点记录。(更改记录此前已写入 WAL + 文件并刷盘。)如果发生崩溃,崩溃恢复过程会查看最新的检查点记录,以确定应该从 WAL 的哪个位置(称为重做记录)开始执行 REDO。该点之前对数据文件所做的任何更改 都保证已经在磁盘上。因此,检查点之后,位于包含重做记录的段之前的 WAL 段不再需要, 可以被回收或删除。(若正在执行 WAL 归档,则这些 WAL 段必 @@ -419,7 +420,7 @@ 减小 checkpoint_timeout 和/或 max_wal_size 会让检查点更频繁地发生。这样可以加快崩溃后 - 恢复,因为需要重做的工作更少。不过,这必须与更频繁刷写脏数据页所增加的成本 + 恢复,因为需要重做的工作更少。不过,这必须与更频繁地将脏数据页刷盘所增加的成本 权衡。如果设置了 (默认就是如此), 还要考虑另一个因素。为了保证数据页一致性,每个检查点之后对某个数据页的首次 修改,都会导致把整页内容写入日志。在这种情况下,更短的检查点间隔会增加输出到 @@ -446,7 +447,7 @@ I/O 速率,使检查点在给定比例的 checkpoint_timeout 秒数 经过时完成,或者在 max_wal_size 即将超出之前完成,以较早 者为准。使用默认值 0.9 时,可以预期 PostgreSQL - 会在下一次计划检查点开始前稍早完成每个检查点(大约在检查点间隔的 90% 时)。 + 会在下一次计划检查点开始前稍早完成每个检查点(耗时约为上一次检查点持续时间的 90%)。 这样能尽可能摊平 I/O,从而使检查点 I/O 负载在整个检查点间隔内保持稳定。这样 做的缺点是,延长检查点会影响恢复时间,因为需要保留更多 WAL 段以备恢复时 使用。关心恢复耗时的用户,可能希望减小 @@ -462,7 +463,7 @@ 在 Linux 和 POSIX 平台上, - 允许在检查点写出的操作系统页面达到可配置的字节数后,强制把它们刷到磁盘。 + 允许在检查点写出的操作系统页面达到可配置的字节数后,强制将它们刷盘。 否则,这些页面可能会停留在操作系统页缓存中,从而在检查点末尾发出 fsync 时引发停顿。这个设置通常有助于降低事务延迟,但也可能 对性能产生不利影响,尤其是在工作负载大于 @@ -492,44 +493,24 @@ 或 archive_library 反复失败,那么旧 WAL 文件就会在 pg_wal 中不断累积,直到问题解决。使用复制槽的备库 如果速度很慢或者已经失败,也会产生同样的效果(见 - )。同样地,如果启用了 - WAL 汇总,那么旧段 - 会一直保留到完成汇总为止。 + )。 在归档恢复或备库模式下,服务器会周期性地执行 重启点重启点, - 其行为类似于正常运行时的检查点:服务器会强制把自身状态写盘,更新 - pg_control 文件,以表明已经处理过的 WAL 数据无需再次 - 扫描,然后回收 pg_wal 目录中的旧 WAL 段文件。重启点的 - 执行频率不会高于主库上的检查点,因为重启点只能在检查点记录处执行。重启点既 - 可能由调度触发,也可能由外部请求触发。 - restartpoints_timed 计数器在 pg_stat_checkpointer - 视图中统计前者,而 restartpoints_req 统计后者。按调度触发的 - 重启点,是在到达某条检查点记录时,如果距上一次已执行的重启点至少已经过去 - 秒,或者上一次尝试执行重启点失败时 - 触发。后一种情况下,下一次重启点会安排在 15 秒后。按请求触发的重启点,其原 - 因与检查点类似,但主要是在 WAL 大小即将超过 - 时触发。不过,由于重启点的可执行时机受到 - 限制,恢复期间经常会超出 max_wal_size,最多可能超出一个 - 检查点周期对应的 WAL 量。(无论如何,max_wal_size 从来 - 都不是硬上限,因此你始终应留出充足余量,以免耗尽磁盘空间。) - restartpoints_done 计数器则在 pg_stat_checkpointer - 视图中统计真正执行了的重启点数量。 - - - - 在某些情况下,例如发生大规模 INSERT 时,主库上的 WAL 大小 - 会快速增长,此时备库端的 restartpoints_req 计数器 - 可能会出现突增。这是因为,虽然由于 WAL 消耗增加而提出了创建新重启点的请求, - 但自上一次重启点以来可安全使用的检查点记录尚未在备库端重放,所以这些请求无法 - 执行。这种行为是正常的,不会导致系统资源消耗增加。在与重启点相关的计数器中, - 只有 restartpoints_done 才表明确实消耗了明显的 - 系统资源。 - + 其行为类似于正常运行时的检查点:服务器会强制将其所有状态刷盘,更新 + pg_control 文件,以表明已经处理过的 WAL 数据无需再次 + 扫描,然后回收 pg_wal 目录中的旧 WAL 段文件。重启点的 + 执行频率不会高于主库上的检查点,因为重启点只能在检查点记录处执行。当到达某条检查点记录且距离上次重启点 + 至少已经过去 checkpoint_timeout 秒,或者 WAL 大小即将超过 + max_wal_size 时,就会触发重启点。不过,由于重启点的可执行时机受到 + 限制,恢复期间经常会超出 max_wal_size,最多可能超出一个 + 检查点周期对应的 WAL 量。(无论如何,max_wal_size 从来 + 都不是硬上限,因此你始终应留出充足余量,以免耗尽磁盘空间。) + + + 有两个常用的内部 WAL 函数: @@ -543,7 +524,7 @@ 快。更糟的是,写 WAL 缓冲区还可能迫使系统创建新的 WAL 段, 这会花费更多时间。正常情况下,WAL 缓冲区应由 XLogFlush 请求负责写出并刷盘; - 该请求大多发生在事务提交时,以确保事务记录被刷入持久存储。在 WAL 输出量很高 + 该请求大多发生在事务提交时,以确保事务记录已刷盘至持久存储。在 WAL 输出量很高 的系统上,XLogFlush 请求可能不够频繁,无法避免 XLogInsertRecord 自己去执行写出。在这种系统上,应增加 WAL 缓冲区的数量,具体做法是修改参数 @@ -556,7 +537,7 @@ 参数 定义了组提交的领导者进程在 XLogFlush 内部获取锁之后会睡眠多少微秒,在此期间,组提 交的追随者会排队跟在领导者后面。这一延迟允许其他服务器进程把自己的提交记录添 - 加到 WAL 缓冲区中,以便它们都能由领导者最终执行的同步操作一并刷出。如果没有 + 加到 WAL 缓冲区中,以便它们都能由领导者最终执行的同步操作一并刷盘。如果没有 启用 ,或者当前处于活跃事务中的其他会话少于 个,就不会发生睡眠;这样可以避免在其他 会话不太可能很快提交时还去睡眠。请注意,在某些平台上,休眠请求的分辨率是 @@ -585,8 +566,7 @@ commit_delay 设为 0(默认值)时,仍然可能出现一种组 - 提交,但每个组只会包含那些恰好在前一次刷盘操作(若有)进行期间,到达“需要刷 - 出其提交记录”这一点的会话。客户端数量更高时,往往会出现一种 + 提交,但每个组只会包含那些恰好在前一次刷盘操作(若有)进行期间,到达“需要将其提交记录刷盘”这一点的会话。客户端数量更高时,往往会出现一种 gangway effect,以至于即使 commit_delay 为 0,组提交的效果也会变得很显著,因此显式设置 commit_delay 的帮助反而会变小。只有在以下两种条件同时 @@ -599,9 +579,9 @@ 参数 决定 PostgreSQL 将如何请求内核把 - WAL 更新强制刷到磁盘。就可靠性而言,所有选项应当都是相同 + WAL 更新强制刷盘。就可靠性而言,所有选项应当都是相同 的;例外是 fsync_writethrough,它有时能够在其他选项做不 - 到时强制刷新磁盘缓存。不过,具体哪个选项速度最快则高度依赖平台。可以使用 + 到时强制将磁盘缓存中的数据刷盘。不过,具体哪个选项速度最快则高度依赖平台。可以使用 程序测试不同选项的速度。请注意,如果 fsync 已被关闭,那么这个参数就没有意义。 @@ -615,14 +595,13 @@ - 有两个内部函数负责把 WAL 数据写入磁盘: - XLogWriteissue_xlog_fsync。 - 启用 后, - XLogWrite 写 WAL 数据以及 - issue_xlog_fsync 将 WAL 数据同步到磁盘所花费的总时间, - 会分别统计为 write_timefsync_time, - 记录在 pg_stat_io 视图中 - objectwal 的项下。 + 有两个内部函数负责把 WAL 数据写入磁盘: + XLogWriteissue_xlog_fsync。 + 启用 后, + XLogWrite 写 WAL 数据以及 + issue_xlog_fsync 将 WAL 数据同步到磁盘所花费的总时间, + 会分别统计为 wal_write_timewal_sync_time, + 并分别记录在 中。 XLogWrite 通常由 XLogInsertRecord (当 WAL 缓冲区没有空间容纳新记录时)、XLogFlush 以及 WAL 写入器调用,用于把 WAL 缓冲区写到磁盘并调用 @@ -634,15 +613,14 @@ issue_xlog_fsync 什么也不做。如果 wal_sync_methodfdatasyncfsyncfsync_writethrough, - 那么写操作会把 WAL 缓冲区移入内核缓存,而 - issue_xlog_fsync 会把它们同步到磁盘。无论 - track_wal_io_timing 是否开启, - XLogWrite 写 WAL 数据的次数和 - issue_xlog_fsync 同步 WAL 数据到磁盘的次数,也会分别统计 - 为 writesfsyncs,记录在 - pg_stat_ioobject 为 - wal 的项下。 - + 那么写操作会把 WAL 缓冲区移入内核缓存,而 + issue_xlog_fsync 会把它们同步到磁盘。无论 + track_wal_io_timing 是否开启, + XLogWrite 写 WAL 数据的次数和 + issue_xlog_fsync 同步 WAL 数据到磁盘的次数,也会分别统计 + 为 wal_writewal_sync,分别记录在 + pg_stat_wal 中。 + 参数 可用于在恢复期间降低 I/O 等待 @@ -650,7 +628,7 @@ PostgreSQL 缓冲池中的磁盘块发起读取。 分别限制预取的并发度和距离。 - 默认值是 try,这会在支持发出预读建议的系统上启用该特性。 + 默认值是 try,这会在posix_fadvise 可用的系统上启用该特性。
diff --git a/zh/15/xaggr.sgml b/zh/15/xaggr.sgml index b46b119e..d7ef45aa 100644 --- a/zh/15/xaggr.sgml +++ b/zh/15/xaggr.sgml @@ -43,11 +43,11 @@ SELECT sum(a) FROM test_complex; - 如果没有非空输入值,上述sum定义将返回零(即初始状态值)。也许我们更希望在这种情况下返回空值 — SQL 标准要求sum这样做。实现这一点只需省略initcond短语,使初始状态值为空。通常这意味着sfunc需要检查输入的状态值是否为空。但对于sum以及maxmin这类其他简单聚合,只需把第一个非空输入值放入状态变量,然后从第二个非空输入值开始应用转移函数即可。如果初始状态值为空,并且转移函数被标记为strict(即不会对空输入调用),PostgreSQL会自动这样做。 + 如果没有非空输入值,上述sum定义将返回零(即初始状态值)。也许我们更希望在这种情况下返回空值 — SQL 标准要求sum这样做。实现这一点只需省略initcond短语,使初始状态值为空值。通常这意味着sfunc需要检查输入的状态值是否为空值。但对于sum以及maxmin这类其他简单聚合,只需把第一个非空输入值放入状态变量,然后从第二个非空输入值开始应用转移函数即可。如果初始状态值为空值,并且转移函数被标记为strict(即不会对空值输入调用),PostgreSQL会自动这样做。 - strict转移函数的另一项默认行为是,只要遇到空输入值,就会保留先前的状态值不变。因此,空值会被忽略。如果你需要对空输入采用其他行为,就不要把转移函数声明为 strict,而应在函数代码中自行检测空输入并完成所需处理。 + strict转移函数的另一项默认行为是,只要遇到空值输入,就会保留先前的状态值不变。因此,空值会被忽略。如果你需要对空值输入采用其他行为,就不要把转移函数声明为 strict,而应在函数代码中自行检测空值输入并完成所需处理。 @@ -72,7 +72,7 @@ CREATE AGGREGATE avg (float8) - SQL 中的聚合函数调用允许使用DISTINCTORDER BY选项,以控制哪些行会传递给聚合的转移函数,以及传递顺序。这些选项是在后台实现的,并不是聚合支持函数需要关心的事情。 + SQL 中的聚合函数调用允许使用DISTINCTORDER BY选项,以控制哪些行会传递给聚合的转移函数,以及传递顺序。这些选项由系统在内部实现,并不是聚合支持函数需要关心的事情。 @@ -292,7 +292,7 @@ SELECT percentile_disc(0.5) WITHIN GROUP (ORDER BY income) FROM households; - 与普通聚合不同,有序集聚合的输入行排序不是在幕后完成的,而是由聚合的支持函数负责。典型的实现方法是在聚合的状态值中保存一个tuplesort对象的引用,把输入行送入该对象,然后在最终函数中完成排序并读出数据。这样的设计使最终函数可以执行特殊操作,例如向待排序数据中注入额外的假想行。普通聚合通常可以使用由PL/pgSQL或其他 PL 语言编写的支持函数来实现,但有序集聚合通常必须用 C 编写,因为它们的状态值无法定义为任何 SQL 数据类型。(在上面的示例中,注意状态值被声明为internal类型,这很典型。)另外,由于最终函数执行了排序,之后就不可能再通过再次执行转移函数来继续加入输入行。这意味着最终函数不是READ_ONLY;在CREATE AGGREGATE中,必须将其声明为READ_WRITE,或者如果额外的最终函数调用能够利用已经排好序的状态,则声明为SHAREABLE。 + 与普通聚合不同,有序集聚合的输入行排序不是由系统在内部完成的,而是由聚合的支持函数负责。典型的实现方法是在聚合的状态值中保存一个tuplesort对象的引用,把输入行送入该对象,然后在最终函数中完成排序并读出数据。这样的设计使最终函数可以执行特殊操作,例如向待排序数据中注入额外的假想行。普通聚合通常可以使用由PL/pgSQL或其他 PL 语言编写的支持函数来实现,但有序集聚合通常必须用 C 编写,因为它们的状态值无法定义为任何 SQL 数据类型。(在上面的示例中,注意状态值被声明为internal类型,这很典型。)另外,由于最终函数执行了排序,之后就不可能再通过再次执行转移函数来继续加入输入行。这意味着最终函数不是READ_ONLY;在CREATE AGGREGATE中,必须将其声明为READ_WRITE,或者如果额外的最终函数调用能够利用已经排好序的状态,则声明为SHAREABLE @@ -366,7 +366,7 @@ if (AggCheckCallContext(fcinfo, NULL)) - AggCheckCallContext的第二个参数可用于取得保存聚合状态值的内存上下文。这对于希望把扩展对象(见)用作状态值的转移函数很有用。第一次调用时,转移函数应返回一个扩展对象,其内存上下文是聚合状态上下文的子上下文;之后的调用则持续返回同一个扩展对象。示例见array_append()。(array_append()并不是任何内置聚合的转移函数,但它的写法保证了在用作自定义聚合的转移函数时也能高效工作。) + AggCheckCallContext的第二个参数可用于取得保存聚合状态值的内存上下文。这对于希望把展开对象(见)用作状态值的转移函数很有用。第一次调用时,转移函数应返回一个展开对象,其内存上下文是聚合状态上下文的子上下文;之后的调用则持续返回同一个展开对象。示例见array_append()。(array_append()并不是任何内置聚合的转移函数,但它的写法保证了在用作自定义聚合的转移函数时也能高效工作。) diff --git a/zh/15/xfunc.sgml b/zh/15/xfunc.sgml index f197856f..7750e57c 100644 --- a/zh/15/xfunc.sgml +++ b/zh/15/xfunc.sgml @@ -4,8 +4,8 @@ 用户定义的函数 - function - user-defined + 函数 + 用户定义的 @@ -36,15 +36,15 @@ - 每一类函数可以采用基本类型、复合类型或者它们的组合作为参数。此外,每一类函数可以返回一个基本类型或一个复合类型。函数也能被定义成返回基本类型或复合类型值的集合。 + 每一类函数可以采用基础类型、复合类型或者它们的组合作为参数。此外,每一类函数可以返回一个基础类型或一个复合类型。函数也能被定义成返回基础类型或复合类型值的集合。 - 很多类函数可以接受或者返回特定的伪类型(例如,多态类型),但是可用的功能会变化。详情可以参考每一种函数的描述。 + 很多类函数可以接受或者返回特定的伪类型(例如,多态类型),但是可用的功能因函数类别而异。详情可以参考每一种函数的描述。 - 定义SQL函数最容易,因此我们将从讨论SQL函数开始。大部分SQL函数的概念也能用到其他类型的函数上。 + 定义SQL函数最容易,因此我们将从讨论它们开始。大部分SQL函数的概念也能用到其他类型的函数上。 @@ -57,8 +57,8 @@ 用户定义的过程 - procedure - user-defined + 过程 + 用户定义的 @@ -101,7 +101,7 @@ - 函数和过程一起构成了例程routine。 + 函数和过程统称为例程例程。 有ALTER ROUTINEDROP ROUTINE这样的命令可以操作函数和过程而不需要知道它们是哪一种。 不过,要注意没有CREATE ROUTINE命令。 @@ -113,7 +113,7 @@ 函数 用户定义的 - in SQL + 在 SQL 中 @@ -124,13 +124,7 @@ 或者,一个 SQL 函数可以通过指定函数的返回类型为SETOF sometype被声明为返回一个集合(也就是多个行),或者等效地声明它为RETURNS TABLE(columns)。在这种情况下,最后一个查询的结果的所有行会被返回。下文将给出进一步的细节。 - - SQL 函数的函数体必须是一个由分号分隔的 SQL 语句列表。最后一条语句后的分号是可选的。除非该函数被声明为返回 - void,否则最后一条语句必须是 SELECT, - 或者是带有 RETURNING 子句的 INSERT、 - UPDATEDELETE 或 - MERGE。 - + SQL 函数的函数体必须是一个由分号分隔的 SQL 语句列表。最后一条语句后的分号是可选的。除非该函数被声明为返回 void,否则最后一条语句必须是 SELECT,或者是 INSERTUPDATEDELETE 并带有 RETURNING 子句。 任意一组 SQL 语言命令都可以打包并定义成函数。除 @@ -139,7 +133,7 @@ DELETEMERGE),以及其他 SQL 命令。(在 SQL 函数中不能使用事务控制命令,例如 COMMITSAVEPOINT,也不能使用某些 - 实用命令,例如 VACUUM。)不过,最后一条命令必须是 + 工具命令,例如 VACUUM。)不过,最后一条命令必须是 SELECT,或者带有 RETURNING 子句,并返回与函数声明返回类型相符的结果。或者,如果你想定义一个执行动作 但没有有用返回值的 SQL 函数,也可以把它定义为返回 void。 @@ -171,11 +165,23 @@ CREATE PROCEDURE clean_emp() AS ' CALL clean_emp(); - 在像这样的简单情况中,函数与过程返回void的差异主要是风格上面的。 + 在像这样的简单情况中,返回void的函数与过程之间的差异主要是风格上面的。 不过,过程还提供了函数所没有的额外能力,例如事务控制。 此外,过程是 SQL 标准的一部分,而返回void则是 PostgreSQL 扩展。 + + + 一个 SQL 函数的整个函数体在它的任何部分被执行前就已经被解析。 + 虽然 SQL 函数能包含修改系统目录的命令(例如CREATE TABLE), + 但在解析分析函数中后续命令时,这种命令的效果是不可见的。 + 因此,例如CREATE TABLE foo (...); INSERT INTO foo VALUES(...); + 如果被打包在一个单一的 SQL 函数中将不能按照预期工作, + 因为当INSERT命令被解析时foo还不存在。 + 在这类情况中建议使用PL/pgSQL代替 SQL 函数。 + + + CREATE FUNCTION 命令的语法要求把函数体写成一个字符串常量。对于字符串常量,通常使用美元引用最方便(见)。如果你选择使用常规的单引号字符串常量语法,那么必须在函数体中将单引号(')和反斜线(\)写成双份(假定使用转义字符串语法,见)。 @@ -226,10 +232,10 @@ INSERT INTO $1 VALUES (42); - 基本类型上的<acronym>SQL</acronym>函数 + 基础类型上的<acronym>SQL</acronym>函数 - 最简单的 SQL 函数没有参数,只是返回一个基本类型,例如 + 最简单的 SQL 函数没有参数,只是返回一个基础类型,例如 integer @@ -255,7 +261,7 @@ SELECT one(); - 定义接受基本类型参数的 SQL 函数也几乎同样容易: + 定义接受基础类型参数的 SQL 函数也几乎同样容易: CREATE FUNCTION add_em(x integer, y integer) RETURNS integer AS $$ @@ -393,17 +399,17 @@ SELECT name, double_salary(emp.*) AS dream 注意这里用 $1.salary 语法来选取参数行值中的一个字段。 还要注意,调用时的 SELECT 命令使用 - table_name.* 将表的当前整行取作一个组合值。该表行也可以仅用表名来引用: + table_name.* 将表的当前整行取作一个复合值。该表行也可以仅用表名来引用: SELECT name, double_salary(emp) AS dream FROM emp WHERE emp.cubicle ~= point '(2,1)'; - 但这种用法已被废弃,因为它很容易让人混淆(关于表行组合值这两种记法的更多细节,见)。 + 但这种用法已被弃用,因为它很容易让人混淆(关于表行复合值这两种记法的更多细节,见)。 - 有时候即时构造一个组合参数会很方便。这可以用ROW构造器完成。 + 有时候即时构造一个复合参数值会很方便。这可以用ROW构造器完成。 例如,我们可以调整被传递给函数的数据: SELECT name, double_salary(ROW(name, salary*1.1, age, cubicle)) AS dream @@ -432,7 +438,7 @@ $$ LANGUAGE SQL; - 查询中的选择列表顺序必须与列在复合类型中出现的顺序完全相同。(正如我们上面所做的那样,命名列与系统无关。) + 查询中的选择列表顺序必须与列在复合类型中出现的顺序完全相同。(系统不考虑像上面这样指定的列名。) @@ -444,7 +450,7 @@ ERROR: return type mismatch in function declared to return emp DETAIL: Final statement returns text instead of point at column 4. - 与基本类型的情况一样,系统不会自动插入显式转换,只会插入隐式或赋值转换。 + 与基础类型的情况一样,系统不会自动插入显式转换,只会插入隐式或赋值转换。 @@ -461,7 +467,7 @@ $$ LANGUAGE SQL; 这里我们写了一个只返回单列、且该列具有正确复合类型的 SELECT。 在这种场景下,这样写并不见得更好,但在某些情况下会很方便 - — 例如,需要通过调用另一个返回目标组合值的函数来计算结果时。 + — 例如,需要通过调用另一个返回目标复合值的函数来计算结果时。 还有一种情况是,如果我们要编写的函数返回的是基于复合类型的域,而不是普通复合类型, 那么就必须写成返回单列的形式,因为没有办法让整行结果发生所需的强制转换。 @@ -526,7 +532,7 @@ SELECT name(new_emp()); - 另一种使用函数返回复合类型的方法是将结果传递给另一个接受正确行类型作为输入的函数: + 另一种使用函数返回复合类型的方法是将结果传递给另一个接受正确行类型作为输入的函数: CREATE FUNCTION getname(emp) RETURNS text AS $$ @@ -614,7 +620,7 @@ DROP FUNCTION sum_n_product (int, int); <acronym>SQL</acronym>有输出参数的过程 - procedures + 过程 输出参数 @@ -636,7 +642,7 @@ $$ LANGUAGE SQL; CALL tp1(17, 100.0, NULL); 如果你写的是其他内容,它必须是一个能够像输入参数那样被隐式强制转换成该参数声明类型的表达式。 - 注意,无论如何这样的表达式不会被评估。 + 不过要注意,这样的表达式不会被求值。 @@ -648,12 +654,12 @@ CALL tp1(17, 100.0, NULL); 带有可变数量参数的<acronym>SQL</acronym>函数 - function - variadic + 函数 + 可变参数 - variadic function + 可变参数函数 @@ -684,27 +690,27 @@ SELECT mleast(ARRAY[10, -1, 5, 4.4]); -- doesn't work - 有时候,能够把一个已经构造好的数组传给 variadic 函数会很有用,尤其是当一个 variadic 函数想把它的数组参数再传给另一个函数时。此外,在允许不受信任用户创建对象的模式中调用 variadic 函数时,这是唯一安全的方式,见。你可以在调用中指定VARIADIC来做到这一点: + 有时候,能够把一个已经构造好的数组传给可变参数函数会很有用,尤其是当一个可变参数函数想把它的数组参数再传给另一个函数时。此外,在允许不受信任用户创建对象的模式中调用可变参数函数时,这是唯一安全的方式,见。你可以在调用中指定VARIADIC来做到这一点: SELECT mleast(VARIADIC ARRAY[10, -1, 5, 4.4]); - 这样会阻止函数的 variadic 参数按其元素类型展开,从而让数组实参能够按常规方式匹配。VARIADIC 只能附加在函数调用的最后一个实参上。 + 这样会阻止函数的可变参数按其元素类型展开,从而让数组实参能够按常规方式匹配。VARIADIC 只能附加在函数调用的最后一个实参上。 - 在调用中指定VARIADIC也是向 variadic 函数传递空数组的唯一方式,例如: + 在调用中指定VARIADIC也是向可变参数函数传递空数组的唯一方式,例如: SELECT mleast(VARIADIC ARRAY[]::numeric[]); - 仅仅写成SELECT mleast()是行不通的,因为 variadic 参数必须匹配至少一个实参。(如果你希望允许这种调用,可以再定义一个同名且不带参数的函数mleast。) + 仅仅写成SELECT mleast()是行不通的,因为可变参数必须匹配至少一个实参。(如果你希望允许这种调用,可以再定义一个同名且不带参数的函数mleast。) - 从 variadic 参数派生出的数组元素参数会被视为没有自己的名字。这意味着除非你指定了 VARIADIC,否则不能使用命名参数来调用 variadic 函数()。例如,下面的调用是可行的: + 从可变参数派生出的数组元素参数会被视为没有自己的名字。这意味着除非你指定了 VARIADIC,否则不能使用命名参数来调用可变参数函数()。例如,下面的调用是可行的: SELECT mleast(VARIADIC arr => ARRAY[10, -1, 5, 4.4]); @@ -723,7 +729,7 @@ SELECT mleast(arr => ARRAY[10, -1, 5, 4.4]); 带有参数默认值的<acronym>SQL</acronym>函数 - function + 函数 参数的默认值 @@ -732,7 +738,7 @@ SELECT mleast(arr => ARRAY[10, -1, 5, 4.4]); 没有给出足够多的实参,就会插入默认值来弥补缺失的实参。由于参数只 能从实参列表的尾部开始被省略,在一个有默认值的参数之后的所有参数 都不得不也具有默认值(尽管使用命名参数记法可以允许放松这种限制, - 这种限制仍然会被强制以便位置参数记法能工作)。不管你是否使用它,这种能力都要求在某些用户不信任其他用户的数据中调用函数时做一些预防措施,见。 + 这种限制仍然会被强制以便位置参数记法能工作)。不管你是否使用它,这种能力都要求在某些用户不信任其他用户的数据库中调用函数时做一些预防措施,见 @@ -775,13 +781,13 @@ ERROR: function foo() does not exist 所有的 SQL 函数都可以被用在查询的FROM子句中,但是 - 对于返回复合类型的函数特别有用。如果函数被定义为返回一种基本类型, + 对于返回复合类型的函数特别有用。如果函数被定义为返回一种基础类型, 该表函数会产生一个单列表。如果该函数被定义为返回一种复合类型,该 表函数会为该复合类型的每一个属性产生一列。 - 以下是一个示例: + 以下是一个示例: CREATE TABLE foo (fooid int, foosubid int, fooname text); @@ -814,8 +820,8 @@ SELECT *, upper(fooname) FROM getfoo(1) AS t1; 返回集合的<acronym>SQL</acronym>函数 - function - with SETOF + 函数 + 使用 SETOF @@ -948,7 +954,7 @@ SELECT x, generate_series(1,5) AS g FROM tab; SELECT x, g FROM tab, LATERAL generate_series(1,5) AS g; - 这会是完全一样的,除了在这个特别的示例中,规划器会选择把g放在嵌套循环连接的外侧,因为gtab没有实际的横向依赖。那会导致一种不同的输出行顺序。选择列表中的集合返回函数总是会被计算,就好像它们在FROM子句剩余部分的嵌套循环连接的内侧一样,因此在考虑来自FROM子句的下一行之前,这些函数会运行到完成。 + 这会是完全一样的,除了在这个特别的示例中,规划器可以选择把g放在嵌套循环连接的外侧,因为gtab没有实际的横向依赖。那会导致一种不同的输出行顺序。选择列表中的集合返回函数总是会被计算,就好像它们在FROM子句剩余部分的嵌套循环连接的内侧一样,因此在考虑来自FROM子句的下一行之前,这些函数会运行到完成。 @@ -968,15 +974,11 @@ SELECT srf1(srf2(x), srf3(y)), srf4(srf5(z)) FROM tab; SELECT x, CASE WHEN x > 0 THEN generate_series(1, 5) ELSE 0 END FROM tab; - 看起来这个语句应该产生满足x > 0的输入行的五次重复,以及不满足的行的一次重复。但实际上,由于在CASE表达时被计算前,generate_series(1, 5)会被运行在一个隐式的LATERAL FROM项中,它会为每个输入行产生五次重复。为了减少混乱,这类情况会产生一个解析时错误。 + 看起来这个语句应该产生满足x > 0的输入行的五次重复,以及不满足的行的一次重复。但实际上,由于在CASE表达式被计算前,generate_series(1, 5)会被运行在一个隐式的LATERAL FROM项中,它会为每个输入行产生五次重复。为了减少混乱,这类情况会产生一个解析时错误。 - - 如果一个函数的最后一条命令是带有 RETURNING 子句的 - INSERTUPDATE、 - DELETEMERGE,那么即使该函数没有声明为 SETOF,或者调用它的查询并未取走全部结果行,该命令也总会执行到完成。RETURNING 子句产生的额外结果行会被静默丢弃,但相应的表修改仍然会发生,并且会在函数返回前全部完成。 - + 如果一个函数的最后一条命令是 INSERTUPDATEDELETE 并带有 RETURNING,那么即使该函数没有声明为 SETOF,或者调用它的查询并未取走全部结果行,该命令也总会执行到完成。RETURNING 子句产生的额外结果行会被静默丢弃,但相应的表修改仍然会发生,并且会在函数返回前全部完成。 @@ -984,11 +986,11 @@ SELECT x, CASE WHEN x > 0 THEN generate_series(1, 5) ELSE 0 END FROM tab; 在 PostgreSQL 10 之前,除非多个集合返回函数始终产生相同数量的行,否则把它们放在同一个选择列表中的行为并不合理。 否则,得到的输出行数会是这些集合返回函数各自产生行数的最小公倍数。 此外,嵌套的集合返回函数也不像上文所描述的那样工作;相反,一个集合返回函数至多只能有一个集合返回参数, - 并且每一层嵌套都会独立运行。再加上过去还允许条件执行(即在 CASE 等结构内部使用集合返回函数), + 并且每一组嵌套的集合返回函数都会独立运行。再加上过去还允许条件执行(即在 CASE 等结构内部使用集合返回函数), 事情就更加复杂了。 如果你要编写需要在旧版 PostgreSQL 上运行的查询,建议使用 LATERAL 语法, 因为这样在不同版本之间能够得到一致的结果。 - 如果你的查询依赖于集合返回函数的条件执行,可以把条件判断移动到自定义集合返回函数内部来修复。例如, + 如果你的查询依赖于集合返回函数的条件执行,或许可以把条件判断移动到自定义集合返回函数内部来修复。例如, SELECT x, CASE WHEN y > 0 THEN generate_series(1, z) ELSE 5 END FROM tab; @@ -1006,7 +1008,7 @@ END$$ LANGUAGE plpgsql; SELECT x, case_generate_series(y > 0, 1, z, 5) FROM tab; - 这种写法在所有版本的 PostgreSQL 中都能正常工作。 + 这种写法在所有版本的 PostgreSQL 中的行为都相同。 @@ -1015,7 +1017,7 @@ SELECT x, case_generate_series(y > 0, 1, z, 5) FROM tab; 返回<literal>TABLE</literal>的<acronym>SQL</acronym>函数 - function + 函数 RETURNS TABLE @@ -1064,10 +1066,9 @@ SELECT make_array(1, 2) AS intarray, make_array('a'::text, 'b') AS textarray; 注意类型转换'a'::text的使用是为了指定该参数的类型 - 是text。如果该参数只是一个字符串这就是必须的,因为 + 是text。如果该参数只是一个字符串字面量,这就是必须的,因为 否则它会被当作unknown类型,并且 - unknown的数组也不是一种合法的类型。如果没有改类型 - 类型转换,将得到这样的错误: + unknown的数组也不是一种合法的类型。如果没有该类型转换,将得到这样的错误: ERROR: could not determine polymorphic type because input has type unknown @@ -1138,7 +1139,7 @@ SELECT * FROM dup(22); - 多态也可以用于 variadic 函数。例如: + 多态也可以用于可变参数函数。例如: CREATE FUNCTION anyleast (VARIADIC anyarray) RETURNS anyelement AS $$ SELECT min($1[i]) FROM generate_subscripts($1, 1) g(i); @@ -1173,14 +1174,14 @@ SELECT concat_values('|', 1, 4, 2); 带有排序规则的<acronym>SQL</acronym>函数 - collation - in SQL functions + 排序规则 + 在 SQL 函数中 - 当一个 SQL 函数有一个或多个可设定排序规则的数据类型参数时,会按 - 中的说明,为每次函数调用确定一个排序规则。 - 如果能够成功确定(也就是说,参数之间不存在隐式排序规则冲突),那么所有可设定排序规则的参数都会被视为隐式带有该排序规则。 + 当一个 SQL 函数有一个或多个支持排序规则的数据类型参数时,会按 + 中的说明,根据分配给实参的排序规则,为每次函数调用确定一个排序规则。 + 如果能够成功确定(也就是说,参数之间不存在隐式排序规则冲突),那么所有支持排序规则的参数都会被视为隐式带有该排序规则。 这会影响函数中对排序规则敏感的操作的行为。例如,使用上文的 anyleast 函数时, SELECT anyleast('abc'::text, 'ABC'); @@ -1200,7 +1201,7 @@ CREATE FUNCTION anyleast (VARIADIC anyarray) RETURNS anyelement AS $$ SELECT min($1[i] COLLATE "en_US") FROM generate_subscripts($1, 1) g(i); $$ LANGUAGE SQL; - 但请注意,如果把它用于不可设定排序规则的数据类型,就会抛出错误。 + 但请注意,如果把它用于不支持排序规则的数据类型,就会抛出错误。 @@ -1209,7 +1210,7 @@ $$ LANGUAGE SQL; - 这种可设定排序规则参数的行为,可以看作是仅适用于文本数据类型的一种受限多态形式。 + 这种支持排序规则的参数的行为,可以看作是仅适用于文本数据类型的一种受限多态形式。 @@ -1218,13 +1219,13 @@ $$ LANGUAGE SQL; 函数重载 - overloading - functions + 重载 + 函数 可以用同样的 SQL 名称定义多于一个函数,只要它们的参数不同即可。 - 换句话说,函数名可以被重载。不管你是否使用它,这种能力都要求在某些用户不信任其他用户的数据中调用函数时做一些预防措施,见。当一个查询 + 换句话说,函数名可以被重载。不管你是否使用它,这种能力都要求在某些用户不信任其他用户的数据库中调用函数时采取安全预防措施,见。当一个查询 被执行时,服务器将从数据类型和所提供的参数个数来决定要调用哪个 函数。重载也可用来模拟具有可变参数个数(最大个数有限)的函数。 @@ -1251,10 +1252,10 @@ CREATE FUNCTION test(smallint, double precision) RETURNS ... - 另一类可能的冲突发生在 variadic 函数和非 variadic 函数之间。例如,可以同时创建 + 另一类可能的冲突发生在可变参数函数和非可变参数函数之间。例如,可以同时创建 foo(numeric)foo(VARIADIC numeric[])。 这时,对于只提供一个 numeric 参数的调用(例如 foo(10.1)),就不清楚该匹配哪个函数。 - 规则是:优先使用在搜索路径中出现较早的那个函数;如果两者位于同一模式中,则优先使用非 variadic 函数。 + 规则是:优先使用在搜索路径中出现较早的那个函数;如果两者位于同一模式中,则优先使用非可变参数函数。 @@ -1281,8 +1282,8 @@ CREATE FUNCTION test(int, int) RETURNS int 函数易变性分类 - volatility - functions + 易变性 + 函数 VOLATILE @@ -1304,7 +1305,7 @@ CREATE FUNCTION test(int, int) RETURNS int 一个VOLATILE函数可以做任何事情,包括修改数据库。在 使用相同的参数连续调用时,它能返回不同的结果。优化器不会对这类函 - 数的行为做任何假定。对于在每一行都需要 volatile 函数值的查询,函数都会被重新求值。 + 数的行为做任何假定。使用易变函数的查询会在需要该函数值的每一行上重新对它求值。 @@ -1352,8 +1353,7 @@ CREATE FUNCTION test(int, int) RETURNS int 在考虑先规划然后立即执行的简单交互式查询时,在STABLEIMMUTABLE分类间的区别相对较小:一个函数是在规划时只 执行一次还是在查询执行开始期间只执行一次没有太大关系。但是如果计划 - 被保存下来然后在后面被重用,区别就大了。如果在不允许过早把一个函数 - 变成规划期间的一个常数时把它标记为IMMUTABLE,会导致 + 被保存下来然后在后面被重用,区别就大了。如果把一个实际上并非不可变的函数标记为IMMUTABLE,就可能在规划期间过早将它折叠成常量,导致 在后续重用该计划时继续使用陈旧的值。在使用预备语句,或使用会缓存执行计划的函数语言(如 PL/pgSQL)时,这会带来严重问题。 @@ -1421,7 +1421,7 @@ CREATE FUNCTION test(int, int) RETURNS int 内部函数 - functioninternal + 函数内部 内部函数由 C 编写并且已经被静态链接到PostgreSQL @@ -1459,9 +1459,9 @@ CREATE FUNCTION square_root(double precision) RETURNS double precision C 语言函数 - function - user-defined - in C + 函数 + 用户定义的 + 在 C 中 @@ -1485,17 +1485,17 @@ CREATE FUNCTION square_root(double precision) RETURNS double precision - 在一个会话中第一次调用一个特定可载入对象文件中的用户定义函数时, - 动态载入器会把那个对象文件载入到内存以便该函数被调用。因此用户 + 在一个会话中第一次调用一个特定可载入目标文件中的用户定义函数时, + 动态载入器会把那个目标文件载入到内存以便该函数被调用。因此用户 定义的 C 函数的CREATE FUNCTION必须 - 为该函数指定两块信息:可载入对象文件的名称,以及要在该对象文件中 + 为该函数指定两块信息:可载入目标文件的名称,以及要在该目标文件中 调用的特定函数的 C 名称(链接符号)。如果没有显式指定 C 名称,则 它被假定为和 SQL 函数名相同。 下面的算法被用来基于CREATE FUNCTION - 命令中给定的名称来定位共享对象文件: + 命令中给定的名称来定位共享目标文件: @@ -1554,47 +1554,27 @@ CREATE FUNCTION square_root(double precision) RETURNS double precision PostgreSQL不会自动编译 C 函数。在 - 从CREATE FUNCTION命令中引用对象文件 + 从CREATE FUNCTION命令中引用目标文件 之前,它必须先被编译好。更多信息请见 - magic block - - - PG_MODULE_MAGIC + 魔数块 - 为确保动态装载的对象文件不会被加载到不兼容的服务器中,PostgreSQL 会检查该文件是否包含内容正确的magic block。这样服务器就能检测出明显的不兼容情况,例如代码是针对另一个 PostgreSQL 主版本编译的。要加入 magic block,请在模块某一个(且只能一个)源文件中,在包含头文件 fmgr.h 之后写入: + 为确保动态装载的目标文件不会被加载到不兼容的服务器中,PostgreSQL 会检查该文件是否包含内容正确的魔数块。这样服务器就能检测出明显的不兼容情况,例如代码是针对另一个 PostgreSQL 主版本编译的。要加入魔数块,请在模块某一个(且只能一个)源文件中,在包含头文件 fmgr.h 之后写入: PG_MODULE_MAGIC; - -或者 - -PG_MODULE_MAGIC_EXT(parameters); - PG_MODULE_MAGIC_EXT 这种形式允许为模块指定附加信息;目前可以添加名称和/或版本字符串。(将来可能允许更多字段。)可以写成这样: - - -PG_MODULE_MAGIC_EXT( - .name = "my_module_name", - .version = "1.2.3" -); - - - 之后,名称和版本可以通过 pg_get_loaded_modules() 函数查看。版本字符串的具体含义不受 PostgreSQL 限制,但建议采用语义化版本规则。 - - - - 在第一次使用之后,动态载入对象文件会保留在内存中。在同一个会话中, + 在第一次使用之后,动态载入目标文件会保留在内存中。在同一个会话中, 后续对该文件中函数的调用只需付出一次很小的符号表查找开销。如果需要 - 强制重新载入一个对象文件(例如在重新编译之后),就需要开启一个新的会话。 + 强制重新载入一个目标文件(例如在重新编译之后),就需要开启一个新的会话。 @@ -1613,7 +1593,7 @@ PG_MODULE_MAGIC_EXT( - C 语言函数中的基本类型 + C 语言函数中的基础类型 数据类型 @@ -1622,16 +1602,16 @@ PG_MODULE_MAGIC_EXT( 要了解如何编写 C 语言函数,你需要了解 - PostgreSQL如何在内部表达基本数据类型 + PostgreSQL如何在内部表达基础类型 以及如何与函数传递它们。在内部, - PostgreSQL把基本类型视为一块内存数据块。 + PostgreSQL把基础类型视为一块内存数据块。 你为该类型定义的用户自定义函数,决定了 PostgreSQL 如何操作它。 也就是说,PostgreSQL 只负责把数据存到磁盘、再从磁盘取回, 而数据的输入、处理和输出则依赖你定义的这些函数。 - 基本类型可以有三种内部格式之一: + 基础类型可以有三种内部格式之一: @@ -1696,10 +1676,9 @@ typedef struct 最后,所有变长类型必须也以引用的方式传递。所有变长类型必须用一个 - 正好 4 字节的不透明长度域开始,该域会由SET_VARSIZE - 设置,绝不要直接设置该域!所有要被存储在该类型中的数据必须在内存 - 中接着该长度域的后面存储。长度域包含该结构体的总长度,也就是包括长 - 度域本身的尺寸。 + 正好 4 字节的不透明长度字段开始,该字段会由SET_VARSIZE + 设置,绝不要直接设置该字段!所有要被存储在该类型中的数据必须在内存 + 中接着该长度字段的后面存储。长度字段包含该结构体的总长度,也就是包括长度字段本身的尺寸。 @@ -1749,16 +1728,16 @@ memcpy(destination->data, buffer, 40); VARHDRSZsizeof(int32)一样, - 但是用宏VARHDRSZ来引用变长类型的载荷的 + 但是用宏VARHDRSZ来引用变长类型的额外开销的 尺寸被认为是比较好的风格。还有,必须 - 使用SET_VARSIZE宏来设置长度域,而不是用 + 使用SET_VARSIZE宏来设置长度字段,而不是用 简单的赋值来设置。 展示了 PostgreSQL 中许多内置 SQL 数据类型所对应的 C 类型。 - Defined In列给出了需要包含的头文件,以获取类型定义。 + 定义文件列给出了需要包含的头文件,以获取类型定义。 (实际的定义可能位于所列文件包含的其他文件中。建议用户坚持使用已定义的接口。) 请注意,在服务器代码的任何源文件中,都应该始终首先包含postgres.h, 因为它声明了很多你反正都会用到的内容,而且先包含其他头文件可能会带来可移植性问题。 @@ -1934,8 +1913,7 @@ memcpy(destination->data, buffer, 40); - 现在我们已经复习了基本类型所有可能的结构,现在可以展示一些 - 真实函数的示例了。 + 了解了基础类型所有可能的结构后,就可以看一些实际函数示例。 @@ -1943,7 +1921,7 @@ memcpy(destination->data, buffer, 40); 版本 1 的调用约定 - 版本-1 的调用规范依赖于宏来降低传参数和结果的复杂度。版本-1 函数的 + 版本-1 的调用约定依赖于宏来降低传参数和结果的复杂度。版本-1 函数的 C 声明总是: Datum funcname(PG_FUNCTION_ARGS) @@ -1955,35 +1933,11 @@ PG_FUNCTION_INFO_V1(funcname); 必须出现在同一个源文件中(按惯例会正好写在该函数本身之前)。 这种宏调用不是internal语言函数所需要的,因为 PostgreSQL会假定所有内部函数都使用 - 版本-1 规范。不过,对于动态载入函数是必需的。 - - - - 在版本-1 函数中,每一个实参都使用对应于该参数数据类型的PG_GETARG_xxx()宏取得。(在非严格的函数中,需要使用PG_ARGISNULL()对参数是否为空提前做检查;见下文。)结果要用对应于返回类型的PG_RETURN_xxx()宏返回。PG_GETARG_xxx()的参数是要取得的函数参数的编号,从零开始计。PG_RETURN_xxx()的参数是实际要返回的值。 - - - - 要调用另一个版本-1 函数,你可以使用 - DirectFunctionCalln(func, - arg1, ..., argn)。这在你想调用标准内部库中定义的函数时尤其有用,因为它提供了与其 SQL 签名相似的接口。 + 版本-1 调用约定。不过,对于动态载入函数是必需的。 - 这些便利函数以及类似函数都可以在 fmgr.h 中找到。 - DirectFunctionCalln 系列把 C 函数名作为其第一个参数。另有 - OidFunctionCalln 等一些变体,它们接收目标函数的 OID。所有这些函数都要求以 Datum 形式提供函数参数,返回值也同样是 Datum。注意,使用这些便利函数时,参数和结果都不能为 NULL。 - - - - 例如,要在 C 中调用 starts_with(text, text),你可以在系统目录中查到它的 C 实现是 - Datum text_starts_with(PG_FUNCTION_ARGS) - 函数。通常你会用 DirectFunctionCall2(text_starts_with, ...) 来调用它。不过,starts_with(text, - text) 需要排序规则信息,因此如果这样调用,会因无法确定字符串比较该使用哪一种排序规则而失败。你必须改用 DirectFunctionCall2Coll(text_starts_with, ...), - 并提供所需的排序规则,通常就是从 PG_GET_COLLATION() 传递进来,如下面的示例所示。 - - - - fmgr.h 还提供了便于在 C 类型和 Datum 之间转换的宏。例如,要把 Datum 转成 text*,可以使用 DatumGetTextPP(X)。虽然某些类型为反向转换提供了名为 TypeGetDatum(X) 之类的宏,但 text* 没有;对它而言,直接使用通用宏 PointerGetDatum(X) 即可。如果你的扩展定义了额外的类型,通常也很方便为这些类型定义类似的宏。 + 在版本-1 函数中,每一个实参都使用对应于该参数数据类型的PG_GETARG_xxx()宏取得。(在非严格的函数中,需要使用PG_ARGISNULL()对参数是否为空值提前做检查;见下文。)结果要用对应于返回类型的PG_RETURN_xxx()宏返回。PG_GETARG_xxx()的参数是要取得的函数参数的编号,从零开始计。PG_RETURN_xxx()的参数是实际要返回的值。 @@ -1995,7 +1949,6 @@ PG_FUNCTION_INFO_V1(funcname); #include #include "fmgr.h" #include "utils/geo_decls.h" -#include "varatt.h" PG_MODULE_MAGIC; @@ -2061,8 +2014,8 @@ copytext(PG_FUNCTION_ARGS) * VARDATA is a pointer to the data region of the new struct. The source * could be a short datum, so retrieve its data through VARDATA_ANY. */ - memcpy(VARDATA(new_t), /* destination */ - VARDATA_ANY(t), /* source */ + memcpy((void *) VARDATA(new_t), /* destination */ + (void *) VARDATA_ANY(t), /* source */ VARSIZE_ANY_EXHDR(t)); /* how many bytes */ PG_RETURN_TEXT_P(new_t); } @@ -2084,25 +2037,6 @@ concat_text(PG_FUNCTION_ARGS) memcpy(VARDATA(new_text) + arg1_size, VARDATA_ANY(arg2), arg2_size); PG_RETURN_TEXT_P(new_text); } - -/* A wrapper around starts_with(text, text) */ - -PG_FUNCTION_INFO_V1(t_starts_with); - -Datum -t_starts_with(PG_FUNCTION_ARGS) -{ - text *t1 = PG_GETARG_TEXT_PP(0); - text *t2 = PG_GETARG_TEXT_PP(1); - Oid collid = PG_GET_COLLATION(); - bool result; - - result = DatumGetBool(DirectFunctionCall2Coll(text_starts_with, - collid, - PointerGetDatum(t1), - PointerGetDatum(t2))); - PG_RETURN_BOOL(result); -} ]]> @@ -2131,10 +2065,6 @@ CREATE FUNCTION copytext(text) RETURNS text CREATE FUNCTION concat_text(text, text) RETURNS text AS 'DIRECTORY/funcs', 'concat_text' LANGUAGE C STRICT; - -CREATE FUNCTION t_starts_with(text, text) RETURNS boolean - AS 'DIRECTORY/funcs', 't_starts_with' - LANGUAGE C STRICT; @@ -2142,11 +2072,11 @@ CREATE FUNCTION t_starts_with(text, text) RETURNS boolean - 注意我们已经把函数指定为strict,这意味着如果有任何输入值为空,系统应该自动假定得到空结果。通过这种做法,我们避免在函数代码中检查空值输入。如果不这样做,我们必须使用PG_ARGISNULL()明确地检查空值输入。 + 注意我们已经把函数指定为strict,这意味着如果有任何输入值为空值,系统应该自动假定结果为空值。通过这种做法,我们避免在函数代码中检查空值输入。如果不这样做,我们必须使用PG_ARGISNULL()明确地检查空值输入。 - 宏PG_ARGISNULL(n)允许一个函数测试是否每一个输入为空(当然,只需要在没有声明为strict的函数中这样做)。和PG_GETARG_xxx()宏一样,输入参数也是从零开始计数。注意应该在验证了一个参数不是空之后才执行PG_GETARG_xxx()。要返回一个空结果,应执行PG_RETURN_NULL(),它对严格的以及非严格的函数都有用。 + 宏PG_ARGISNULL(n)允许一个函数测试是否每一个输入为空值(当然,只需要在没有声明为strict的函数中这样做)。和PG_GETARG_xxx()宏一样,输入参数也是从零开始计数。注意应该在验证了一个参数不是空值之后才执行PG_GETARG_xxx()。要返回空值结果,应执行PG_RETURN_NULL(),它对严格的以及非严格的函数都有用。 @@ -2154,11 +2084,11 @@ CREATE FUNCTION t_starts_with(text, text) RETURNS boolean - 在版本-1接口中提供的其他选项是PG_GETARG_xxx()宏的两个变种。其中的第一种是PG_GETARG_xxx_COPY(),它确保返回的指定参数的拷贝可以被安全地写入(通常的宏有时会返回一个指向表中物理存储的值,它不能被写入。使用PG_GETARG_xxx_COPY()宏可以保证得到一个可写的结果)。第二种变种PG_GETARG_xxx_SLICE()宏有三个参数。第一个是函数参数的编号(如上文)。第二个和第三个是要被返回的段的偏移量和长度。偏移量从零开始计算,而负值的长度则表示要求返回该值的剩余部分。当大型值的存储类型为external时,这些宏提供了访问这些大型值的更有效的方法(列的存储类型可以使用ALTER TABLE tablename ALTER COLUMN colname SET STORAGE storagetype来指定。storagetypeplainexternalextended或者main)。 + 在版本-1接口中提供的其他选项是PG_GETARG_xxx()宏的两个变种。其中的第一种是PG_GETARG_xxx_COPY(),它确保返回的指定参数的拷贝可以被安全地写入(通常的宏有时会返回一个指向表中物理存储值的指针,不能写入该值。使用PG_GETARG_xxx_COPY()宏可以保证得到一个可写的结果)。第二种变种PG_GETARG_xxx_SLICE()宏有三个参数。第一个是函数参数的编号(如上文)。第二个和第三个是要被返回的段的偏移量和长度。偏移量从零开始计算,而负值的长度则表示要求返回该值的剩余部分。当大型值的存储类型为external时,这些宏提供了访问这些大型值的部分内容的更有效方法(列的存储类型可以使用ALTER TABLE tablename ALTER COLUMN colname SET STORAGE storagetype来指定。storagetypeplainexternalextended或者main)。 - 最后,版本-1 的函数调用规范可以返回集合结果()、实现触发器函数()和过程语言调用处理器()。更多细节 + 最后,版本-1 的函数调用约定可以返回集合结果()、实现触发器函数()和过程语言调用处理器()。更多细节 可见源代码发布中的src/backend/utils/fmgr/README @@ -2169,10 +2099,10 @@ CREATE FUNCTION t_starts_with(text, text) RETURNS boolean 在开始更高级的话题之前,我们应该讨论一下用于 PostgreSQL C 语言函数的编码规则。 - 虽然可以把不是 C 编写的函数载入到 - PostgreSQL中,这通常是很困难的, + 虽然有可能把不是 C 编写的函数载入到 + PostgreSQL中,但即使能够做到,通常也很困难, 因为其他语言(例如 C++、FORTRAN 或者 Pascal)通常不会遵循和 C - 相同的调用规范。也就是说,其他语言不会以同样的方式在函数之间传递 + 相同的调用约定。也就是说,其他语言不会以同样的方式在函数之间传递 参数以及返回值。由于这个原因,我们会假定你的 C 语言函数确实是用 C 编写的。 @@ -2184,7 +2114,7 @@ CREATE FUNCTION t_starts_with(text, text) RETURNS boolean 使用 pg_config - --includedir-serverpg_configwith user-defined C functions + --includedir-serverpg_config用于用户定义的 C 函数 查出 PostgreSQL 服务器头文件在你的系统上(或你的用户将要运行的系统上)安装于何处。 @@ -2197,7 +2127,7 @@ CREATE FUNCTION t_starts_with(text, text) RETURNS boolean - 记得按照中的说明,为你的共享库定义一个magic block。 + 记得按照中的说明,为你的共享库定义一个魔数块 @@ -2223,7 +2153,7 @@ CREATE FUNCTION t_starts_with(text, text) RETURNS boolean - 对象文件中定义的符号名不能彼此冲突,也不能与 + 目标文件中定义的符号名不能彼此冲突,也不能与 PostgreSQL 服务器可执行文件中定义的符号冲突。如果你收到这类错误消息,就必须重命名相关函数或变量。 @@ -2233,99 +2163,15 @@ CREATE FUNCTION t_starts_with(text, text) RETURNS boolean &dfunc; - - 服务器 API 和 ABI 稳定性指南 - - - 本节向扩展和其他服务器插件的作者提供有关 - PostgreSQL 服务器 API 与 ABI 稳定性的指导。 - - - - 概述 - - - PostgreSQL 服务器为服务器插件提供了若干边界清晰的 API,例如函数管理器(fmgr,本章已介绍)、SPI)以及专门为扩展设计的各种钩子。这些接口都会被谨慎管理,以保持长期稳定性和兼容性。不过,服务器中的整套全局函数和变量实际上也构成了可公开使用的 API,而其中大部分在设计时并未把可扩展性和长期稳定性作为目标。 - - - - 因此,虽然使用这些接口是完全允许的,但越是偏离那些久经实践考验的路径,将来遇到 API 或 ABI 兼容性问题的可能性就越大。鼓励扩展作者反馈自己的需求,以便随着时间推移和新用法的出现,某些接口能够被视为更稳定,或者可以加入新的、设计更完善的接口。 - - - - - API 兼容性 - - API,即应用程序编程接口,是编译时使用的接口。 - - - - 主版本 - - 在 PostgreSQL 不同主版本之间,不承诺 API 兼容性。因此,扩展代码可能需要修改源代码才能同时支持多个主版本。这类差异通常可以通过预处理器条件(例如 #if PG_VERSION_NUM >= 160000)来管理。那些使用了边界清晰接口之外能力的复杂扩展,通常每个服务器主版本都需要做少量这类修改。 - - - - - 小版本 - - PostgreSQL 会尽力避免在小版本发布中破坏服务器 API。一般来说,能针对某个小版本编译并正常工作的扩展代码,也应当能够针对同一主版本的其他任意小版本(无论过去还是将来)编译并正常工作。 - - - - 如果确实需要做出变更,也会在考虑扩展需求的前提下谨慎管理。这类变更会在发布说明()中进行说明。 - - - - - - ABI 兼容性 - - ABI,即应用程序二进制接口,是运行时使用的接口。 - - - - 主版本 - - 不同主版本的服务器在 ABI 上是有意不兼容的。因此,使用服务器 API 的扩展必须针对每一个主版本重新编译。包含 PG_MODULE_MAGIC(见)可以确保针对某个主版本编译的代码会被其他主版本拒绝。 - - - - - 小版本 - - PostgreSQL 会尽力避免在小版本发布中破坏服务器 ABI。一般来说,针对任意一个小版本编译的扩展,应当能与同一主版本过去或将来的其他任意小版本一起工作。 - - - - 如果确实需要变更,PostgreSQL 会尽量选择侵入性最小的方式,例如把新字段塞进填充空间,或者附加到结构体末尾。这类修改通常不应影响扩展,除非扩展使用了非常不寻常的代码模式。 - - - - 然而,在极少数情况下,即使是这种非侵入式变更也可能不现实甚至不可能做到。发生这种情况时,也会在考虑扩展需求的前提下谨慎管理该变更。这类变更同样会记录在发布说明()中。 - - - - 但请注意,服务器中有很多部分并不是作为公开可消费的 API 来设计和维护的(而且在大多数情况下,其真实边界也并不清晰)。如果这些部分出现紧急需求,对它们的修改自然会比对那些边界清楚且广泛使用的接口做修改时,更少考虑扩展代码的兼容性。 - - - - 此外,在缺乏自动化检测这类变化的机制时,这并不能构成严格保证;不过从历史上看,这种破坏性变化极为罕见。 - - - - - - 复合类型参数 复合类型没有像 C 结构体那样的固定布局。复合类型的实例可能包含 - 空值域。此外,继承层次中的复合类型可能具有和同一继承层次中 - 其他成员不同的域。因此, + 空值字段。此外,继承层次中的复合类型可能具有和同一继承层次中 + 其他成员不同的字段。因此, PostgreSQL提供了函数接口 - 来访问 C 的复合类型的域。 + 以便从 C 访问复合类型的字段。 @@ -2337,7 +2183,7 @@ SELECT name, c_overpaid(emp, 1500) AS overpaid WHERE name = 'Bill' OR name = 'Sam'; - 如果使用版本-1的调用规范,我们可以定义 + 如果使用版本-1的调用约定,我们可以定义 c_overpaid为: GetAttributeByName 是 - PostgreSQL 的一个系统函数,用于从指定行中取出属性。它有三个参数:传入函数的 HeapTupleHeader 类型参数、所需属性的名称,以及一个用于指示该属性是否为 null 的返回参数。GetAttributeByName 返回一个 Datum 值,你可以用适当的 DatumGetXXX() 函数把它转换为正确的数据类型。注意,如果 null 标志被设置,那么返回值本身没有意义;在尝试对结果做任何处理之前,务必先检查这个 null 标志。 + PostgreSQL 的一个系统函数,用于从指定行中取出属性。它有三个参数:传入函数的 HeapTupleHeader 类型参数、所需属性的名称,以及一个用于指示该属性是否为 null 的返回参数。GetAttributeByName 返回一个 Datum 值,你可以用适当的 DatumGetXXX() 宏把它转换为正确的数据类型。注意,如果 null 标志被设置,那么返回值本身没有意义;在尝试对结果做任何处理之前,务必先检查这个 null 标志。 也有GetAttributeByNum函数,它可以用目标属性 - 的属性号而不是属性名来选择目标属性。 + 的列号而不是属性名来选择目标属性。 @@ -2396,14 +2242,14 @@ CREATE FUNCTION c_overpaid(emp, integer) RETURNS boolean 要从 C 语言函数中返回一行或一个复合类型值,可以使用一套特殊的 API, - 它通过一组宏和函数隐藏了构造组合数据类型时的大部分复杂性。要使用这套 API,源文件中必须包含: + 它通过一组宏和函数隐藏了构造复合数据类型时的大部分复杂性。要使用这套 API,源文件中必须包含: #include "funcapi.h" - 构造组合数据值(下文简称元组)有两种方式: + 构造复合数据值(下文简称元组)有两种方式: 一种是从 Datum 值数组构造,另一种是从 C 字符串数组构造,这些字符串会传给该元组各列数据类型的输入转换函数。 无论采用哪种方式,首先都需要获取或构造描述该元组结构的 TupleDesc。 处理 Datum 时,需要把 TupleDesc 传给 BlessTupleDesc,然后为每一行调用 heap_form_tuple。 @@ -2412,13 +2258,13 @@ CREATE FUNCTION c_overpaid(emp, integer) RETURNS boolean - 有一些辅助函数可以用来设置所需的 TupleDesc。在大多数返回组合值的函数中,推荐的做法是调用: + 有一些辅助函数可以用来设置所需的 TupleDesc。在大多数返回复合值的函数中,推荐的做法是调用: TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc) - 传入与调用函数本身相同的 fcinfo 结构体(这当然要求使用版本 1 调用约定)。 + 传入调用函数本身收到的同一个 fcinfo 结构体(这当然要求使用版本 1 调用约定)。 resultTypeId 可以指定为 NULL,也可以指定为一个本地变量的地址,用于接收函数结果类型的 OID。 resultTupleDesc 应当是一个本地 TupleDesc 变量的地址。 检查返回结果是否为 TYPEFUNC_COMPOSITE;如果是,resultTupleDesc 就会被填入所需的 TupleDesc。 @@ -2437,7 +2283,7 @@ TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, get_call_result_type有一个兄弟 get_expr_result_type,它被用来解析被表示为一棵表达式 - 树的函数调用的输出类型。在尝试确定来自函数外部的结果类型时可以用它。 + 树的函数调用的输出类型。在尝试从函数自身外部确定结果类型时可以用它。 也有一个get_func_result_type,当只有函数的 OID 可用时 可以用它。不过这些函数无法处理被声明为返回record的 函数,并且get_func_result_type无法解析多态类型,因此你 @@ -2446,22 +2292,22 @@ TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, - 更早、现在已被废弃的获取TupleDesc的函数有: + 更早、现在已被弃用的获取TupleDesc的函数有: TupleDesc RelationNameGetTupleDesc(const char *relname) - 它可以为一个提到的关系的行类型得到TupleDesc, + 它可以为一个指定名称的关系的行类型得到TupleDesc, 还有: TupleDesc TypeGetTupleDesc(Oid typeoid, List *colaliases) 可以基于一个类型 OID 得到TupleDesc。这可以被用来 - 为一种基础或者复合类型获得TupleDesc。不过,对于 + 为一种基本或者复合类型获得TupleDesc。不过,对于 返回record的函数它不起作用,并且它无法解析多态类型。 - 一旦有了一个TupleDesc,如果计划处理 Datum可以调用: + 一旦有了一个TupleDesc,如果计划处理 Datum,可以调用: TupleDesc BlessTupleDesc(TupleDesc tupdesc) @@ -2471,7 +2317,7 @@ AttInMetadata *TupleDescGetAttInMetadata(TupleDesc tupdesc) 如果正在编写一个返回集合的函数,你可以把这些函数的结果保存在 FuncCallContext结构体中 — 分别使用 - tuple_desc或者attinmeta域。 + tuple_desc或者attinmeta字段。 @@ -2491,8 +2337,7 @@ HeapTuple BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values) values是一个 C 字符串数组,每一个元素是返回行 的一个属性。每一个 C 字符串应该是该属性数据类型的输入函数所期望 的格式。为了对一个属性返回空值,values数组中对 - 应的指针应该被设置为NULL。对于你返回的每一行都将 - 再次调用这个函数。 + 应的指针应该被设置为NULL。对于你返回的每一行都需要再次调用这个函数。 @@ -2527,13 +2372,13 @@ HeapTupleGetDatum(HeapTuple tuple) 使用 ValuePerCall 模式时,重要的是要记住查询不能保证运行完成; 也就是说,由于诸如LIMIT之类的选项, - 执行程序可能会在获取所有行之前停止调用 set-returning 函数。 + 执行器可能会在获取所有行之前停止调用集合返回函数。 这意味着在最后一次调用中执行清理活动是不安全的,因为这可能永远不会发生。 对于需要访问外部资源(例如文件描述符)的函数,建议使用 Materialize 模式。 - 本节的其余部分记录了一组使用 ValuePerCall 模式的 SRF 常用(尽管不是必须使用)的帮助程序宏。 + 本节的其余部分记录了一组使用 ValuePerCall 模式的 SRF 常用(尽管不是必须使用)的辅助宏。 有关 Materialize 模式的其他详细信息可以在src/backend/utils/fmgr/README中找到。 此外,PostgreSQL源代码分发中的contrib 模块包含许多使用 ValuePerCall 和 Materialize 模式的 SRF 示例。 @@ -2542,7 +2387,7 @@ HeapTupleGetDatum(HeapTuple tuple) 要使用此处描述的 ValuePerCall 支持宏,请包含funcapi.h。 这些宏与结构体FuncCallContext一起使用,该结构体包含需要跨调用保存的状态。 - 在调用 SRF 中,fcinfo->flinfo->fn_extra用于在调用之间保存 + 在使用这些宏的 SRF 中,fcinfo->flinfo->fn_extra用于在调用之间保存 指向FuncCallContext的指针。 宏在第一次使用时自动填充该字段,并期望在后续使用中找到相同的指针。 @@ -2575,7 +2420,7 @@ typedef struct FuncCallContext /* * 可选:指向包含属性类型输入元数据的结构的指针 * - * attinmeta 被用在返回元组(即组合数据类型)时,在返回基本数据类型 + * attinmeta 被用在返回元组(即复合数据类型)时,在返回基础类型 * 时不会使用。只有想用BuildTupleFromCStrings()创建返回元组时才需要它。 */ AttInMetadata *attinmeta; @@ -2592,7 +2437,7 @@ typedef struct FuncCallContext /* * 可选:指向包含元组描述的结构的指针 * - * tuple_desc 被用在返回元组(即组合数据类型)时,并且只有在用 + * tuple_desc 被用在返回元组(即复合数据类型)时,并且只有在用 * heap_form_tuple() 而不是 BuildTupleFromCStrings() 构建元组时才需要它。 * 注意这里存储的 TupleDesc 指针通常已经被先运行过 BlessTupleDesc()。 */ @@ -2696,7 +2541,7 @@ my_set_returning_function(PG_FUNCTION_ARGS) else { /* 这里已经完成了项的返回,所以只报告事实。 */ - /* (不要将清理代码放在这里的。) */ + /* (不要将清理代码放在这里。) */ SRF_RETURN_DONE(funcctx); } } @@ -2776,7 +2621,7 @@ retcomposite(PG_FUNCTION_ARGS) /* 构建一个元组 */ tuple = BuildTupleFromCStrings(attinmeta, values); - /* 将元组转换为数据 */ + /* 将元组转换为 datum */ result = HeapTupleGetDatum(tuple); /* 清理(这实际上并不是必要的) */ @@ -2832,10 +2677,10 @@ CREATE OR REPLACE FUNCTION retcomposite(IN integer, IN integer, fcinfo->flinfo访问。参数argnum则是从零 开始计。get_call_result_type也可被用作 get_fn_expr_rettype的一种替代品。还有 - get_fn_expr_variadic,它可以被用来找出 variadic 参数 + get_fn_expr_variadic,它可以被用来找出可变参数 是否已经被合并到了一个数组中。这主要用于 VARIADIC "any"函数,因为对于接收普通数组类型的 - variadic 函数来说总是会发生这类合并。 + 可变参数函数来说总是会发生这类合并。 @@ -2903,7 +2748,7 @@ CREATE FUNCTION make_array(anyelement) RETURNS anyarray 它与 anyelement 类似,但不会要求不同的 "any" 参数必须是同一种类型,也不会帮助确定函数的结果类型。 C 语言函数还可以把最后一个参数声明为 VARIADIC "any"。 这可以匹配一个或多个任意类型的实参(不必是同一种类型)。 - 这些参数不会像普通 variadic 函数那样被收集成一个数组,而是会单独传给函数。 + 这些参数不会像普通可变参数函数那样被收集成一个数组,而是会单独传给函数。 使用这种特性时,必须结合 PG_NARGS() 宏以及前面介绍的方法来确定实参的个数和类型。 此外,这种函数的用户也可能希望在函数调用中使用 VARIADIC 关键字,以便让函数把数组元素当作独立参数处理。 如果希望支持这种行为,函数本身就必须在使用 get_fn_expr_variadic 检测到实参被标记为 VARIADIC 后自行实现它。 @@ -2911,324 +2756,52 @@ CREATE FUNCTION make_array(anyelement) RETURNS anyarray - 共享内存 - - - 启动时请求共享内存 + 共享内存与 LWLocks - - 插件可以在服务器启动时预留共享内存。要做到这一点,插件的共享库必须通过 + + 插件可以在服务器启动时预留 LWLock 和一块共享内存。插件的共享库必须通过在 shared_preload_libraries - 预加载。该共享库还应当在其 _PG_init 函数中注册 - shmem_request_hook。这个 - shmem_request_hook 可以通过调用: + 中指定它来预加载。共享库应在其 _PG_init 函数中注册 + shmem_request_hook。这个 shmem_request_hook + 可以预留 LWLock 或共享内存。要预留共享内存,应从你的 + shmem_request_hook 中调用: -void RequestAddinShmemSpace(Size size) +void RequestAddinShmemSpace(int size) - 来预留共享内存。每个后端都应当通过调用: + + + 要预留 LWLock,应从你的 shmem_request_hook 中调用: -void *ShmemInitStruct(const char *name, Size size, bool *foundPtr) +void RequestNamedLWLockTranche(const char *tranche_name, int num_lwlocks) - 来获取指向这块预留共享内存的指针。如果该函数把 - foundPtr 设为 false,调用者就应初始化这块预留共享内存的内容;如果 foundPtrtrue,说明该共享内存已经由其他后端初始化过,调用者无需再做初始化。 + 这样会确保有一个包含 num_lwlocks 个 LWLock 的数组, + 可以通过名称 tranche_name 访问。 + 使用 GetNamedLWLockTranche 可以取得指向该数组的指针。 - 为避免竞争条件,每个后端在初始化其共享内存分配时都应使用 LWLock - AddinShmemInitLock,如下所示: - + shmem_request_hook 的示例可见于 + PostgreSQL 源代码树中的 + contrib/pg_stat_statements/pg_stat_statements.c。 + + 为避免可能的竞争条件,每个后端都应使用 LWLock AddinShmemInitLock 来连接和初始化分配给它的共享内存,如下所示: static mystruct *ptr = NULL; -bool found; + +if (!ptr) +{ + bool found; LWLockAcquire(AddinShmemInitLock, LW_EXCLUSIVE); ptr = ShmemInitStruct("my struct name", size, &found); if (!found) { - ... initialize contents of shared memory ... + initialize contents of shmem area; + acquire any requested LWLocks using: ptr->locks = GetNamedLWLockTranche("my tranche name"); } LWLockRelease(AddinShmemInitLock); - - shmem_startup_hook 为初始化代码提供了一个方便的位置,但并不强制要求所有这类代码都放在这个钩子中。在 Windows 上(以及任何定义了 EXEC_BACKEND 的平台上),每个后端都会在附加到共享内存后不久执行已注册的 shmem_startup_hook,因此插件在该钩子中仍应像上例那样获取 AddinShmemInitLock。在其他平台上,只有 postmaster 进程会执行 shmem_startup_hook,每个后端会自动继承这些共享内存指针。 - - - - shmem_request_hook 与 - shmem_startup_hook 的一个完整示例可见于 - PostgreSQL 源代码树中的 - contrib/pg_stat_statements/pg_stat_statements.c。 - - - - - 启动后请求共享内存 - - - 还有另一种更灵活的预留共享内存的方法,可以在服务器启动之后、并且无需借助 - shmem_request_hook 来完成。为此,每个需要使用该共享内存的后端都应通过调用以下函数来获取一个指针: - -void *GetNamedDSMSegment(const char *name, size_t size, - void (*init_callback) (void *ptr), - bool *found) - - 如果给定名称的动态共享内存段尚不存在,该函数会分配该段,并使用提供的 - init_callback 回调函数对其进行初始化。如果该段已经由另一个后端分配并初始化过,该函数就只会把现有的动态共享内存段附加到当前后端。 - - - - 与在服务器启动时预留的共享内存不同,使用 - GetNamedDSMSegment 预留共享内存时,不需要获取 - AddinShmemInitLock,也不需要采取其他措施来避免竞争条件。该函数会确保只有一个后端分配并初始化该内存段,而其他所有后端都会获得指向同一块已完全分配并初始化好的内存段的指针。 - - - - GetNamedDSMSegment 的完整使用示例可见于 - src/test/modules/test_dsm_registry/test_dsm_registry.c - ,位于 PostgreSQL 源代码树中。 - - - - - - LWLocks - - - 启动时请求 LWLocks - - - 插件可以在服务器启动时预留 LWLocks。与在服务器启动时预留共享内存一样,插件的共享库必须通过 - shared_preload_libraries - 预加载,并且共享库应在其 _PG_init 函数中注册 - shmem_request_hook。这个 - shmem_request_hook 可以通过调用以下函数来预留 LWLocks: - -void RequestNamedLWLockTranche(const char *tranche_name, int num_lwlocks) - - 这样可以确保在名为 tranche_name 的 tranche 下提供一组数量为 num_lwlocks 的 LWLocks。可以通过调用以下函数获得指向这组 LWLocks 的指针: - -LWLockPadded *GetNamedLWLockTranche(const char *tranche_name) - - - - - - 启动后请求 LWLocks - - - 还有另一种更灵活的获取 LWLocks 的方法,可以在服务器启动后进行,也无需借助 - shmem_request_hook。为此,首先通过调用下面的函数分配一个 - tranche_id: - -int LWLockNewTrancheId(void) - - 接下来,初始化每个 LWLock,并把新的 - tranche_id 作为参数传入: - -void LWLockInitialize(LWLock *lock, int tranche_id) - - 与共享内存类似,每个后端都应确保只有一个进程会分配新的 - tranche_id 并初始化每一个新的 LWLock。一种做法是仅在持有 - AddinShmemInitLock 独占锁的共享内存初始化代码中调用这些函数。如果使用 - GetNamedDSMSegment,那么在 - init_callback 回调函数中调用这些函数就足以避免竞争条件。 - - - - 最后,每个使用该 tranche_id 的后端都应通过调用以下函数把它与一个 tranche_name 关联起来: - -void LWLockRegisterTranche(int tranche_id, const char *tranche_name) - - - - - LWLockNewTrancheId、 - LWLockInitialize 和 - LWLockRegisterTranche 的完整使用示例可见于 - PostgreSQL 源代码树中的 - contrib/pg_prewarm/autoprewarm.c。 - - - - - - 自定义等待事件 - - - 插件可以通过调用以下函数,在等待事件类型 - Extension 下定义自定义等待事件: - -uint32 WaitEventExtensionNew(const char *wait_event_name) - - 该等待事件会关联到一个面向用户的自定义字符串。示例可见于 - src/test/modules/worker_spi,位于 PostgreSQL 源代码树中。 - - - 自定义等待事件可以在 - pg_stat_activity 中查看: - -=# SELECT wait_event_type, wait_event FROM pg_stat_activity - WHERE backend_type ~ 'worker_spi'; - wait_event_type | wait_event ------------------+--------------- - Extension | WorkerSpiMain -(1 row) - - - - - - 注入点 - - - 给定名称 name 的注入点可通过以下宏声明: - -INJECTION_POINT(name, arg); - - - 服务器代码中已经在若干关键位置声明了注入点。新增注入点后,需要重新编译代码,才能让该注入点出现在二进制文件中。用 C 语言编写的插件也可以使用同一个宏在自己的代码中声明注入点。注入点名称应使用小写字母,并用连字符分隔各个术语。arg 是运行时传给回调的可选参数值。 - - - - 执行注入点可能需要分配少量内存,而这可能失败。如果你需要在一个不允许动态分配的临界区中使用注入点,可以采用以下两步法: - -INJECTION_POINT_LOAD(name); -INJECTION_POINT_CACHED(name, arg); - - - 在进入临界区之前,调用 INJECTION_POINT_LOAD。它会检查共享内存状态,并在该注入点处于激活状态时把回调加载到后端私有内存中。在临界区内部,再用 - INJECTION_POINT_CACHED 来执行回调。 - - - - 插件可以通过调用以下函数,为一个已经声明好的注入点附加回调: - -extern void InjectionPointAttach(const char *name, - const char *library, - const char *function, - const void *private_data, - int private_data_size); - - - name 是注入点名称;执行过程中到达该注入点时,就会执行从 library 载入的 functionprivate_data 是一块大小为 private_data_size 的私有数据区域,会在执行时作为参数传给回调。 - - - - 下面是一个 - InjectionPointCallback 的示例: - -static void -custom_injection_callback(const char *name, - const void *private_data, - void *arg) -{ - uint32 wait_event_info = WaitEventInjectionPointNew(name); - - pgstat_report_wait_start(wait_event_info); - elog(NOTICE, "%s: executed custom callback", name); - pgstat_report_wait_end(); -} - - 这个回调会以 NOTICE 级别向服务器错误日志写入一条消息,但回调完全可以实现更复杂的逻辑。 - - - - 另一种定义“到达注入点时应执行什么动作”的方式,是把测试代码直接写在常规源代码旁边。如果该动作依赖于加载模块无法访问的局部变量,这会很有用。此时可以使用 - IS_INJECTION_POINT_ATTACHED 宏来检查某个注入点是否已附加,例如: - -#ifdef USE_INJECTION_POINTS -if (IS_INJECTION_POINT_ATTACHED("before-foobar")) -{ - /* change a local variable if injection point is attached */ - local_var = 123; - - /* also execute the callback */ - INJECTION_POINT_CACHED("before-foobar", NULL); -} -#endif - - 注意,附加到注入点上的回调不会由 IS_INJECTION_POINT_ATTACHED 宏执行。如果你想执行该回调,就必须像上面的示例那样另外调用 - INJECTION_POINT_CACHED。 - - - - 可选地,也可以通过调用以下函数来解除一个注入点: - -extern bool InjectionPointDetach(const char *name); - - 成功时返回 true,否则返回 false。 - - - - 一个附加到注入点的回调会在所有后端中生效,包括在调用 - InjectionPointAttach 之后才启动的后端。它会一直保持附加状态,直到服务器停止,或者通过 - InjectionPointDetach 将其解除。 - - - - 相关示例可见于 PostgreSQL 源代码树中的 - src/test/modules/injection_points。 - - - - 启用注入点需要在 configure 中指定 - ,或者在 - Meson 中指定 - 。 - - - - - 自定义累计统计 - - - 用 C 语言编写的插件可以使用在 - 累计统计系统 中注册的自定义累计统计类型。 - - - - 首先,定义一个 PgStat_KindInfo,其中包含与所注册自定义类型相关的全部信息。例如: - -static const PgStat_KindInfo custom_stats = { - .name = "custom_stats", - .fixed_amount = false, - .shared_size = sizeof(PgStatShared_Custom), - .shared_data_off = offsetof(PgStatShared_Custom, stats), - .shared_data_len = sizeof(((PgStatShared_Custom *) 0)->stats), - .pending_size = sizeof(PgStat_StatCustomEntry), } - - 然后,每个需要使用这种自定义类型的后端,都需要使用 - pgstat_register_kind 注册它,并指定一个用于存储该类统计条目的唯一 ID: - -extern PgStat_Kind pgstat_register_kind(PgStat_Kind kind, - const PgStat_KindInfo *kind_info); - - 在开发新扩展时,应将 - PGSTAT_KIND_EXPERIMENTAL 用作 - kind。当你准备把扩展发布给用户时,请在 - - Custom Cumulative Statistics 页面上预留一个 kind ID。 - - - - 关于 PgStat_KindInfo API 的细节,可见 - src/include/utils/pgstat_internal.h。 - - - - 已注册的统计类型会关联到一个名称以及一个在共享内存中供整个服务器共享的唯一 ID。每个使用自定义统计类型的后端都会维护一个本地缓存,用来保存各个自定义 PgStat_KindInfo 的信息。 - - - - 应将实现自定义累计统计类型的扩展模块加入 - ,以便在 - PostgreSQL 启动期间尽早载入。 - - - - 展示如何注册并使用自定义统计信息的示例可见于 - src/test/modules/injection_points @@ -3272,9 +2845,9 @@ extern PgStat_Kind pgstat_register_kind(PgStat_Kind kind, - 如果从 C++ 代码调用后端函数,确定 C++ 调用栈值包含传统 C 风格 + 如果从 C++ 代码调用后端函数,确定 C++ 调用栈只包含传统 C 风格 的数据结构(POD)。这是必要的,因为后端错误会 - 产生远距离的longjmp(),它无法正确的退回具有非 + 产生远距离的longjmp(),它无法正确地展开具有非 POD 对象的 C++ 调用栈。 @@ -3293,8 +2866,8 @@ extern PgStat_Kind pgstat_register_kind(PgStat_Kind kind, 函数优化信息 - optimization information - for functions + 优化信息 + 用于函数 @@ -3330,7 +2903,7 @@ supportfn(internal) returns internal - 对于返回 boolean 的目标函数,估计使用该函数的 WHERE 子句会筛选出多少行通常很有用。这可以通过实现 SupportRequestSelectivity 请求类型的支持函数来完成。 + 对于返回 boolean 的目标函数,估计使用该函数的 WHERE 子句筛选出的行所占的比例通常很有用。这可以通过实现 SupportRequestSelectivity 请求类型的支持函数来完成。 diff --git a/zh/15/xindex.sgml b/zh/15/xindex.sgml index 425c94d8..9bb5013f 100644 --- a/zh/15/xindex.sgml +++ b/zh/15/xindex.sgml @@ -4,8 +4,8 @@ 索引扩展接口 - index - for user-defined data type + 索引 + 用于用户定义的数据类型 @@ -19,15 +19,10 @@ 索引方法和操作符类 - - 操作符类与索引访问方法相关联,例如 - B-树 或 GIN。 - 自定义索引访问方法可通过 定义。 - 详见 。 - + pg_am 表为每个索引方法(内部称为访问方法)保存一行。对表进行常规访问的支持内置于 PostgreSQL 中,但所有索引方法都在 pg_am 中描述。可以编写必要的代码,然后在 pg_am 中创建一个条目,从而添加新的索引访问方法 — 但这超出了本章的范围(参见)。 - 索引方法的例程并不直接知道它将处理哪些数据类型。相反,一个操作符类operator class标识了索引方法在处理特定数据类型时需要使用的那组操作。之所以称为操作符类,是因为它指定的一项内容就是可与索引一起使用的 WHERE 子句操作符集合(也就是能被转换成索引扫描条件的操作符)。操作符类还可以指定索引方法内部操作所需的一些支持函数,但这些函数并不直接对应任何可与索引一起使用的 WHERE 子句操作符。 + 索引方法的例程并不直接知道它将处理哪些数据类型。相反,一个操作符类操作符类标识了索引方法在处理特定数据类型时需要使用的那组操作。之所以称为操作符类,是因为它指定的一项内容就是可与索引一起使用的 WHERE 子句操作符集合(也就是能被转换成索引扫描条件的操作符)。操作符类还可以指定索引方法内部操作所需的一些支持函数,但这些函数并不直接对应任何可与索引一起使用的 WHERE 子句操作符。 @@ -353,12 +348,6 @@ 5 - - - 返回可由 C 调用的 skip 支持函数地址(可选) - - 6 - @@ -385,7 +374,7 @@ - 给定一个 64 位 salt,计算一个键的 64 位哈希值;如果 salt 为 0,结果的低 32 位必须与函数 1 计算出的值一致(可选) + 给定一个 64 位盐值,计算一个键的 64 位哈希值;如果盐值为 0,结果的低 32 位必须与函数 1 计算出的值一致(可选) 2 @@ -400,7 +389,7 @@ - GiST 索引有十二个支持函数,其中七个是可选的,如所示。 + GiST 索引有十一个支持函数,其中六个是可选的,如所示。 (详见。) @@ -475,11 +464,7 @@ (可选) 11 - - translate_cmptype - 把比较类型转换为该操作符类使用的策略号(可选) - 12 - + @@ -558,7 +543,7 @@ compare - 比较两个键,并返回一个小于零、等于零或大于零的整数,以表示第一个键是小于、等于还是大于第二个键 + 比较两个键,并返回一个小于零、等于零或大于零的整数,用以表示第一个键是小于、等于还是大于第二个键 1 @@ -732,7 +717,7 @@ CREATE OPERATOR < ( restrict = scalarltsel, join = scalarltjoinsel ); - 指定正确的交换子和求反器操作符很重要,同样也要指定合适的限制选择度函数和连接选择度函数,否则优化器将无法有效地利用索引。 + 指定正确的交换子和求反器操作符很重要,同样也要指定合适的限制选择率函数和连接选择率函数,否则优化器将无法有效地利用索引。 @@ -811,7 +796,7 @@ CREATE OPERATOR CLASS complex_abs_ops - 为了满足这些需求,PostgreSQL使用操作符族operator family这一概念。一个操作符族包含一个或多个操作符类,还可以包含属于整个族、但不属于族中任何单一类的可索引操作符及其相应的支持函数。我们称这样的操作符和函数在该族中是松散的,而不是绑定在某个特定类中。通常,每个操作符类只包含单一数据类型的操作符,而跨数据类型操作符则作为操作符族中的松散成员存在。 + 为了满足这些需求,PostgreSQL使用操作符族操作符族这一概念。一个操作符族包含一个或多个操作符类,还可以包含属于整个族、但不属于族中任何单一类的可索引操作符及其相应的支持函数。我们称这样的操作符和函数在该族中是松散的,而不是绑定在某个特定类中。通常,每个操作符类只包含单一数据类型的操作符,而跨数据类型操作符则作为操作符族中的松散成员存在。 @@ -835,8 +820,7 @@ DEFAULT FOR TYPE int8 USING btree FAMILY integer_ops AS FUNCTION 1 btint8cmp(int8, int8) , FUNCTION 2 btint8sortsupport(internal) , FUNCTION 3 in_range(int8, int8, int8, boolean, boolean) , - FUNCTION 4 btequalimage(oid) , - FUNCTION 6 btint8skipsupport(internal) ; + FUNCTION 4 btequalimage(oid) ; CREATE OPERATOR CLASS int4_ops DEFAULT FOR TYPE int4 USING btree FAMILY integer_ops AS @@ -849,8 +833,7 @@ DEFAULT FOR TYPE int4 USING btree FAMILY integer_ops AS FUNCTION 1 btint4cmp(int4, int4) , FUNCTION 2 btint4sortsupport(internal) , FUNCTION 3 in_range(int4, int4, int4, boolean, boolean) , - FUNCTION 4 btequalimage(oid) , - FUNCTION 6 btint4skipsupport(internal) ; + FUNCTION 4 btequalimage(oid) ; CREATE OPERATOR CLASS int2_ops DEFAULT FOR TYPE int2 USING btree FAMILY integer_ops AS @@ -863,8 +846,7 @@ DEFAULT FOR TYPE int2 USING btree FAMILY integer_ops AS FUNCTION 1 btint2cmp(int2, int2) , FUNCTION 2 btint2sortsupport(internal) , FUNCTION 3 in_range(int2, int2, int2, boolean, boolean) , - FUNCTION 4 btequalimage(oid) , - FUNCTION 6 btint2skipsupport(internal) ; + FUNCTION 4 btequalimage(oid) ; ALTER OPERATOR FAMILY integer_ops USING btree ADD -- cross-type comparisons int8 vs int2 @@ -931,7 +913,7 @@ ALTER OPERATOR FAMILY integer_ops USING btree ADD - 要构建一个多数据类型的哈希操作符族,必须为该族支持的每一种数据类型创建相互兼容的哈希支持函数。这里的兼容性是指:对任意两个被该族中的等值操作符视为相等的值,这些函数都保证返回相同的哈希码,即使这两个值属于不同类型也是如此。当这些类型具有不同的物理表示时,这通常难以实现,但在某些情况下可以做到。此外,将该操作符族中一种数据类型的值通过隐式或二进制强制转换转换成该族中另一种数据类型时,不应改变所计算出的哈希值。注意,每种数据类型只有一个支持函数,而不是每个等值操作符一个。建议让操作符族保持完整,也就是说,对每一种数据类型组合都提供一个等值操作符。每个操作符类只应包含其数据类型对应的非跨数据类型等值操作符和支持函数。 + 要构建一个多数据类型的哈希操作符族,必须为该族支持的每一种数据类型创建相互兼容的哈希支持函数。这里的兼容性是指:对任意两个被该族中的等值操作符视为相等的值,这些函数都保证返回相同的哈希码,即使这两个值属于不同类型也是如此。当这些类型具有不同的物理表示时,这通常难以实现,但在某些情况下可以做到。此外,将该操作符族中一种数据类型的值通过隐式或二进制强制转换转为该族中另一种数据类型时,不得改变所计算出的哈希值。注意,每种数据类型只有一个支持函数,而不是每个等值操作符一个。建议让操作符族保持完整,也就是说,对每一种数据类型组合都提供一个等值操作符。每个操作符类只应包含其数据类型对应的非跨数据类型等值操作符和支持函数。 @@ -944,7 +926,7 @@ ALTER OPERATOR FAMILY integer_ops USING btree ADD - 在 PostgreSQL 8.3 之前,并没有操作符族这一概念,因此任何打算与索引一起使用的跨数据类型操作符都必须直接绑定到该索引的操作符类中。虽然这种做法仍然有效,但已经废弃,因为它会使索引的依赖关系过于宽泛,而且当两种数据类型都在同一操作符族中拥有操作符时,规划器能更有效地处理跨数据类型比较。 + 在 PostgreSQL 8.3 之前,并没有操作符族这一概念,因此任何打算与索引一起使用的跨数据类型操作符都必须直接绑定到该索引的操作符类中。虽然这种做法仍然有效,但已被弃用,因为它会使索引的依赖关系过于宽泛,而且当两种数据类型都在同一操作符族中拥有操作符时,规划器能更有效地处理跨数据类型比较。 @@ -953,7 +935,7 @@ ALTER OPERATOR FAMILY integer_ops USING btree ADD 系统对操作符类的依赖 - ordering operator + 排序操作符 @@ -961,7 +943,7 @@ ALTER OPERATOR FAMILY integer_ops USING btree ADD - 特别地,ORDER BYDISTINCT等 SQL 特性要求对值的比较和排序。为了在用户定义的数据类型上实现这些特性,PostgreSQL会为数据类型查找默认 B-树操作符类。这个操作符类的equals成员定义了用于GROUP BYDISTINCT的值的等值概念,而该操作符类施加的排序顺序定义了默认的ORDER BY顺序。 + 特别地,ORDER BYDISTINCT等 SQL 特性要求对值的比较和排序。为了在用户定义的数据类型上实现这些特性,PostgreSQL会为数据类型查找默认 B-树操作符类。这个操作符类的相等成员定义了用于GROUP BYDISTINCT的值的等值概念,而该操作符类施加的排序顺序定义了默认的ORDER BY顺序。 @@ -987,11 +969,11 @@ SELECT * FROM mytable ORDER BY somecol USING ~<~; - 用户定义类型的数组比较也依赖于该类型默认 B-树操作符类所定义的语义。如果没有默认 B-树操作符类,但有默认的哈希操作符类,则支持数组相等比较,但不支持顺序比较。 + 用户定义类型的数组比较也依赖于该类型默认 B-树操作符类所定义的语义。如果没有默认 B-树操作符类,但有默认的哈希操作符类,则支持数组相等比较,但不支持排序比较。 - 另一种需要更多数据类型相关知识的 SQL 特性,是窗口函数中的 RANGE offset PRECEDING/FOLLOWING 框架选项(见)。对于下面这样的查询 + 另一种需要更多数据类型相关知识的 SQL 特性,是窗口函数中的 RANGE offset PRECEDING/FOLLOWING 帧选项(见)。对于下面这样的查询 SELECT sum(x) OVER (ORDER BY x RANGE BETWEEN 5 PRECEDING AND 10 FOLLOWING) FROM mytable; @@ -1026,7 +1008,7 @@ SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10; - 搜索操作符必须返回布尔结果,而排序操作符通常返回其他类型的结果,例如表示距离的浮点数或数值。这种类型通常不同于被索引的数据类型。为了避免对不同数据类型行为作硬编码假设,在定义排序操作符时,必须指定一个 B-树操作符族,用来说明结果数据类型的排序顺序。正如上一节所述,B-树操作符族定义了 PostgreSQL 的顺序概念,因此这是一种自然的表示方式。由于点的 <-> 操作符返回 float8,因此可以在创建操作符类时这样指定它: + 搜索操作符必须返回布尔结果,而排序操作符通常返回其他类型的结果,例如用于表示距离的 float 或 numeric。这种类型通常不同于被索引的数据类型。为了避免对不同数据类型行为作硬编码假设,在定义排序操作符时,必须指定一个 B-树操作符族,用来说明结果数据类型的排序顺序。正如上一节所述,B-树操作符族定义了 PostgreSQL 的顺序概念,因此这是一种自然的表示方式。由于点的 <-> 操作符返回 float8,因此可以在创建操作符类时这样指定它: (point, point) FOR ORDER BY float_ops ]]> @@ -1039,7 +1021,7 @@ OPERATOR 15 <-> (point, point) FOR ORDER BY float_ops 操作符类的特殊特性 - 还有两个操作符类的特殊特性我们尚未讨论,主要是因为它们对最常用的索引方法并不太有用。 + 还有两个操作符类的特殊特性我们尚未讨论,主要是因为它们对最常用的索引方法没有用处。 @@ -1060,7 +1042,7 @@ CREATE OPERATOR CLASS polygon_ops STORAGE box; - 目前,只有 GiST、SP-GiST、GIN 和 BRIN 索引方法支持与列数据类型不同的 STORAGE 类型。GiST 的 compressdecompress 支持例程在使用 STORAGE 时必须处理数据类型转换。SP-GiST 同样需要 compress 支持函数在存储类型不同时完成转换;如果某个 SP-GiST 操作符类还支持取回数据,那么反向转换必须由 consistent 函数处理。在 GIN 中,STORAGE 类型标识key值的类型,它通常不同于被索引列的类型 — 例如,整数数组列上的某个操作符类,其键值可能只是整数。GIN 的 extractValueextractQuery 支持例程负责从被索引值中提取键。BRIN 与 GIN 类似:STORAGE 类型标识被存储的摘要值类型,而操作符类的支持过程负责正确解释这些摘要值。 + 目前,只有 GiST、SP-GiST、GIN 和 BRIN 索引方法支持与列数据类型不同的 STORAGE 类型。GiST 的 compressdecompress 支持例程在使用 STORAGE 时必须处理数据类型转换。SP-GiST 同样需要 compress 支持函数在存储类型不同时完成转换;如果某个 SP-GiST 操作符类还支持取回数据,那么反向转换必须由 consistent 函数处理。在 GIN 中,STORAGE 类型标识值的类型,它通常不同于被索引列的类型 — 例如,整数数组列上的某个操作符类,其键值可能只是整数。GIN 的 extractValueextractQuery 支持例程负责从被索引值中提取键。BRIN 与 GIN 类似:STORAGE 类型标识被存储的摘要值类型,而操作符类的支持函数负责正确解释这些摘要值。 diff --git a/zh/15/xml2.sgml b/zh/15/xml2.sgml index 731918bc..fd03c7fb 100644 --- a/zh/15/xml2.sgml +++ b/zh/15/xml2.sgml @@ -90,7 +90,7 @@ 对文档执行该查询,并将结果包在 XML 标签中。如果结果包含多个值,输出将类似于: <toptag> -<itemtag>Value 1 which could be an XML fragment</itemtag> +<itemtag>Value 1(可以是 XML 片段)</itemtag> <itemtag>Value 2....</itemtag> </toptag> @@ -173,7 +173,7 @@ xpath_table(text key, text document, text relation, text xpaths, text criteria) key - key 字段的名称 — 这只是一个作为输出表第一列使用的字段,也就是说,它用于标识每个输出行来自哪条记录(关于多个值,见下文注释) + 字段的名称 — 这只是一个作为输出表第一列使用的字段,也就是说,它用于标识每个输出行来自哪条记录(关于多个值,见下文注释) @@ -238,7 +238,7 @@ xpath_table('article_id', 'date_entered > ''2003-01-01'' ') AS t(article_id integer, author text, page_count integer, title text); - AS 子句定义了输出表中各列的名称和类型。第一列是 key 字段,其余各列对应 XPath 查询。如果 XPath 查询多于结果列,多出的查询将被忽略。如果结果列多于 XPath 查询,多出的列将为 NULL。 + AS 子句定义了输出表中各列的名称和类型。第一列是 字段,其余各列对应 XPath 查询。如果 XPath 查询多于结果列,多出的查询将被忽略。如果结果列多于 XPath 查询,多出的列将为 NULL。 @@ -267,7 +267,7 @@ WHERE t.author_id = p.person_id; - 在某些情况下,用户会知道某个 XPath 查询只会返回单个结果(例如唯一文档标识符)— 如果它与返回多个结果的 XPath 查询一起使用,这个单值结果只会出现在结果的第一行。解决办法是把 key 字段作为与一个更简单的 XPath 查询结果进行连接的条件之一。例如: + 在某些情况下,用户会知道某个 XPath 查询只会返回单个结果(例如唯一文档标识符)— 如果它与返回多个结果的 XPath 查询一起使用,这个单值结果只会出现在结果的第一行。解决办法是把键字段作为与一个更简单的 XPath 查询结果进行连接的条件之一。例如: CREATE TABLE test ( diff --git a/zh/15/xoper.sgml b/zh/15/xoper.sgml index b2ecb081..2fe0d38c 100644 --- a/zh/15/xoper.sgml +++ b/zh/15/xoper.sgml @@ -127,6 +127,17 @@ SELECT (a + b) AS c FROM test_complex; 设就认为这种转换有效;= 操作符的创建者必须通过为该操 作符标记交换子信息,明确声明这种转换是有效的。 + + 定义一个与自身可交换的操作符时,直接定义即可。但定义一对可交换操作符时,情况就稍微复杂一些:第一个要定义的操作符如何引用另一个尚未定义的操作符呢?这个问题有两种解决办法: + + 一种办法是在定义第一个操作符时省略 COMMUTATOR 子句,然后在第二个操作符的定义中提供该子句。由于 PostgreSQL 知道可交换操作符是成对出现的,因此它在看到第二个定义时,会自动回头补全第一个定义中缺少的 COMMUTATOR 子句。 + + + + 另一种更直接的办法是在两个定义中都包含 COMMUTATOR 子句。当 PostgreSQL 处理第一个定义并发现 COMMUTATOR 引用了一个不存在的操作符时,系统会在系统目录中为该操作符建立一个占位项。这个占位项只有操作符名称、左右操作数类型和结果类型包含有效数据,因为这就是 PostgreSQL 此时能够推断出的全部信息。第一个操作符的目录项将链接到这个占位项。之后,当你定义第二个操作符时,系统会用第二个定义中的附加信息更新该占位项。如果在占位操作符补全之前尝试使用它,就只会得到一条错误消息。 + + + @@ -158,16 +169,19 @@ SELECT (a + b) AS c FROM test_complex; x <> y。这种情况比你想象得更常见,因为 NOT 操作可能会作为其他重排的结果被插入进来。 + + 可以使用上面解释的定义交换子对的相同方法,来定义成对的求反器操作符。 + <literal>RESTRICT</literal> - 如果给出 RESTRICT 子句,它指定该操作符的限制选择度估 + 如果给出 RESTRICT 子句,它指定该操作符的限制选择率估 算函数。(注意,这里是函数名,而不是操作符名。) RESTRICT 子句只对返回 boolean 的二元操 - 作符有意义。限制选择度估算器的作用,是针对当前操作符和某个特定常量值, + 作符有意义。限制选择率估算器的作用,是针对当前操作符和某个特定常量值, 猜测一张表中有多少比例的行会满足如下形式的 WHERE 子句条件: @@ -179,9 +193,9 @@ column OP constant - 编写新的限制选择度估算函数远远超出了本章的范围,不过幸运的是,对于你自 + 编写新的限制选择率估算函数远远超出了本章的范围,不过幸运的是,对于你自 己的很多操作符,通常都可以直接使用系统提供的某个标准估算器。标准的限制 - 选择度估算器如下: + 选择率估算器如下: eqsel 用于 = neqsel 用于 <> @@ -193,7 +207,7 @@ column OP constant - 对于选择度非常高或非常低的操作符,即使它们实际上并不是真正的相等或不等 + 对于选择率非常高或非常低的操作符,即使它们实际上并不是真正的相等或不等 比较,你也常常可以勉强使用 eqselneqsel。例如,几何类型中的近似相等操作符就使用 eqsel,其依据是它们通常只会匹配表中很小一部分项。 @@ -212,7 +226,7 @@ column OP constant - 另一个有用的内置选择度估算函数是 matchingsel。只要 + 另一个有用的内置选择率估算函数是 matchingsel。只要 已为输入数据类型收集了标准的 MCV 和/或直方图统计信息,它几乎就适用于任 何二元操作符。它的默认估计值被设定为 eqsel 所用默认 估计值的两倍,因此最适合那些比相等比较稍微宽松一些的比较操作符。(或者 @@ -222,7 +236,7 @@ column OP constant src/backend/utils/adt/geo_selfuncs.c 中,还为几 - 何操作符提供了其他选择度估算函数:areasel、 + 何操作符提供了其他选择率估算函数:areaselpositionselcontsel。截至 目前,这些函数都还只是桩实现,但你也许仍会想使用它们(或者更好的是,改 进它们)。 @@ -233,9 +247,9 @@ column OP constant <literal>JOIN</literal> - 如果给出 JOIN 子句,它指定该操作符的连接选择度估算函 + 如果给出 JOIN 子句,它指定该操作符的连接选择率估算函 数。(注意,这里是函数名,而不是操作符名。)JOIN 子 - 句只对返回 boolean 的二元操作符有意义。连接选择度估算器的 + 句只对返回 boolean 的二元操作符有意义。连接选择率估算器的 作用,是针对当前操作符,猜测两张表中有多少比例的行对会满足如下形式的 WHERE 子句条件: @@ -246,7 +260,7 @@ table1.column1 OP table2.column2 - 与前面一样,本章不会尝试解释如何编写连接选择度估算函数,而只是建议你在 + 与前面一样,本章不会尝试解释如何编写连接选择率估算函数,而只是建议你在 适用时使用某个标准估算器: eqjoinsel 用于 = @@ -305,7 +319,7 @@ table1.column1 OP table2.column2 一个可参与哈希连接的操作符,必须拥有一个交换子(如果两侧操作数数据类型 - 相同,则可以是它自身;如果不同,则应是相关的相等操作符),并且该交换子 + 相同,则为它自身;如果不同,则应是相关的相等操作符),并且该交换子 也必须出现在同一个操作符族中。否则,在使用该操作符时可能会发生规划器错 误。另外,对于支持多种数据类型的哈希操作符族,最好(虽然并非严格必需) 为每一种数据类型组合都提供相等操作符;这样可以获得更好的优化效果。 @@ -342,7 +356,7 @@ table1.column1 OP table2.column2 - 归并连接的基本思想,是先把左表和右表分别排序,然后并行扫描它们。因此, + 归并连接的基本思想,是先把左表和右表分别排序,然后同步扫描它们。因此, 两种数据类型都必须能够被完全排序,而连接操作符必须只能在那对值位于排序 次序中同一位置时才成功。实际效果上,这意味着连接操作符 必须表现得像相等比较一样。不过,只要两种不同的数据类型在逻辑上兼容,也 @@ -362,7 +376,7 @@ table1.column1 OP table2.column2 一个可参与归并连接的操作符,必须拥有一个交换子(如果两侧操作数数据类型 - 相同,则可以是它自身;如果不同,则应是相关的相等操作符),并且该交换子 + 相同,则为它自身;如果不同,则应是相关的相等操作符),并且该交换子 也必须出现在同一个操作符族中。否则,在使用该操作符时可能会发生规划器错 误。另外,对于支持多种数据类型的 btree 操作符族,最 好(虽然并非严格必需)为每一种数据类型组合都提供相等操作符;这样可以获 diff --git a/zh/15/xplang.sgml b/zh/15/xplang.sgml index 9075d7b6..0590ea2d 100644 --- a/zh/15/xplang.sgml +++ b/zh/15/xplang.sgml @@ -183,7 +183,7 @@ CREATE TRUSTED LANGUAGE plperl 在默认的PostgreSQL安装中, PL/pgSQL语言的调用处理器会被构建并安装到 - library目录中;此外, + 目录中;此外, PL/pgSQL语言本身也安装在所有数据库中。如 果在构建时配置了Tcl支持,那么 PL/TclPL/TclU diff --git a/zh/15/xtypes.sgml b/zh/15/xtypes.sgml index 3d1b66d1..b66c4aa1 100644 --- a/zh/15/xtypes.sgml +++ b/zh/15/xtypes.sgml @@ -218,7 +218,7 @@ CREATE TYPE complex ( 如果数据类型的内部表示是可变长度的,则这种内部表示必须遵循可变长度数 据的标准布局:前四个字节必须是一个从不直接访问的char[4] 字段(惯例上命名为vl_len_)。必须使用 - SET_VARSIZE()宏在该字段中存储该值的总大小(包括 + SET_VARSIZE()宏在该字段中存储该 datum 的总大小(包括 长度字段本身),并使用VARSIZE()取回它。(这些宏 之所以存在,是因为长度字段可能会随平台不同而采用编码形式。) @@ -260,7 +260,7 @@ CREATE TYPE complex ( PG_DETOAST_DATUM_PACKED(通常通过定义 GETARG_DATATYPE_PP宏来隐藏),并使用 VARSIZE_ANY_EXHDRVARDATA_ANY - 宏访问一个可能采用打包形式的值。再次注意,即使数据类型定义指定了 + 宏访问一个可能采用打包形式的 datum。再次注意,即使数据类型定义指定了 对齐方式,这些宏返回的数据也不是对齐的。如果对齐很重要,就必须使用常 规的PG_DETOAST_DATUM接口。 @@ -271,8 +271,7 @@ CREATE TYPE complex ( 较旧的代码常把vl_len_声明为 int32字段,而不是char[4]字段。只要结构体定 义中还有其他至少按int32对齐的字段,这样做是可以的。但 - 在处理可能未对齐的值时使用这种结构体定义就很危险;编译器可能据此假定该 - 值实际上是对齐的,从而在对齐要求严格的体系结构上导致核心转储。 + 在处理可能未对齐的 datum 时使用这种结构体定义就很危险;编译器可能据此假定该 datum 实际上是对齐的,从而在对齐要求严格的体系结构上导致核心转储。 diff --git a/zh/16/acronyms.sgml b/zh/16/acronyms.sgml index fb7d6cc6..7ba9f3e3 100644 --- a/zh/16/acronyms.sgml +++ b/zh/16/acronyms.sgml @@ -8,32 +8,7 @@ - - AIO - - - 异步I/O - - - - - ACL - - - 访问控制列表 - - - - - - AM - - - 访问方法 - - - ANSI @@ -347,14 +322,6 @@ - - I/O - - - 输入/输出 - - - ISO diff --git a/zh/16/adminpack.sgml b/zh/16/adminpack.sgml index 860def7c..44887a7a 100644 --- a/zh/16/adminpack.sgml +++ b/zh/16/adminpack.sgml @@ -94,14 +94,14 @@ pg_file_sync - pg_file_sync对由filename指定的文件或目录执行 fsync。失败时会抛出错误(例如,指定的文件不存在)。请注意,对此函数没有影响,因此即使刷新数据库文件失败,也不会引发 PANIC 级别的错误。 + pg_file_sync对由filename指定的文件或目录执行 fsync。失败时会抛出错误(例如,指定的文件不存在)。请注意,对此函数没有影响,因此即使数据库文件刷盘失败,也不会引发 PANIC 级别的错误。 pg_file_rename - pg_file_rename重命名文件。如果省略archivename或其值为 NULL,则它只是将oldname重命名为newname(后者必须尚不存在)。如果提供了archivename,它会先将newname重命名为archivename(后者必须尚不存在),然后再将oldname重命名为newname。如果第二个重命名步骤失败,它会在报告错误之前尝试将archivename再改回newname。成功时返回 true;如果源文件不存在或不可写,则返回 false;其他情况会抛出错误。 + pg_file_rename重命名文件。如果省略archivename或其值为空值,则它只是将oldname重命名为newname(后者必须尚不存在)。如果提供了archivename,它会先将newname重命名为archivename(后者必须尚不存在),然后再将oldname重命名为newname。如果第二个重命名步骤失败,它会在报告错误之前尝试将archivename再改回newname。成功时返回 true;如果源文件不存在或不可写,则返回 false;其他情况会抛出错误。 diff --git a/zh/16/amcheck.sgml b/zh/16/amcheck.sgml index 259e1b8a..f1e1eac9 100644 --- a/zh/16/amcheck.sgml +++ b/zh/16/amcheck.sgml @@ -337,7 +337,7 @@ SET client_min_messages = DEBUG1; 这也包括因操作系统排序规则的比较规则发生变化而引起的问题。 - 像text这类可排序类型的数据值之间的比较必须是不可变的 + 像text这类支持排序规则的类型的 datum 之间的比较必须是不可变的 (正如用于 B-树索引扫描的所有比较都必须不可变一样), 这就意味着操作系统排序规则绝不能发生变化。 虽然这种情况比较少见,但操作系统排序规则的更新确实可能导致此类问题。 diff --git a/zh/16/backup-manifest.sgml b/zh/16/backup-manifest.sgml index 5d61e7ff..b5558f0a 100644 --- a/zh/16/backup-manifest.sgml +++ b/zh/16/backup-manifest.sgml @@ -4,7 +4,7 @@ 备份清单格式 - Backup Manifest + 备份清单 @@ -34,20 +34,7 @@ PostgreSQL-Backup-Manifest-Version - 其对应的值是一个整数。从 PostgreSQL - 17 开始,该值为 2;在较早的版 - 本中,该值为 1。 - - - - - - System-Identifier - - - 执行该备份的 PostgreSQL 实例的数据库系统标识 - 符。只有当 PostgreSQL-Backup-Manifest-Version 为 - 2 时,才会出现该字段。 + 其对应的值始终为整数 1。 @@ -81,9 +68,9 @@ 该键总是出现在备份清单文件的最后一行。其对应的值是此前所有行的 - SHA-256 校验和。这里使用固定的校验和方法,是为了让客户端能够对清单进 - 行增量解析。尽管 SHA-256 校验和明显比 CRC-32C 校验和开销更高,但清单 - 通常足够小,因此这些额外计算一般并不重要。 + SHA256 校验和。这里使用固定的校验和方法,是为了让客户端能够对清单进 + 行增量解析。尽管 SHA256 校验和明显比 CRC32C 校验和开销更高,但清单通 + 常足够小,因此这些额外计算一般并不重要。 @@ -180,7 +167,7 @@ Start-LSN - 为了使用该备份,必须在指定时间线上从这个 LSN 开始回放。该 LSN 按 + 为了使用该备份,必须在指定时间线上从这个 LSN 开始重放。该 LSN 按 PostgreSQL 通常使用的格式存储;也就是说, 它是一个字符串,由两段十六进制字符串构成,每段长度在 1 到 8 之间,并 以斜杠分隔。 @@ -192,7 +179,7 @@ End-LSN - 使用该备份时,指定时间线上的回放可结束于此 LSN,而这也是允许的最早 + 使用该备份时,指定时间线上的重放可结束于此 LSN,而这也是允许的最早 LSN。其存储格式与 Start-LSN 相同。 diff --git a/zh/16/backup.sgml b/zh/16/backup.sgml index a549c4fb..92126884 100644 --- a/zh/16/backup.sgml +++ b/zh/16/backup.sgml @@ -3,7 +3,7 @@ 备份和恢复 - backup + 备份 与任何保存重要数据的系统一样,PostgreSQL数据库也应定期备份。虽然其过程基本简单,但清楚理解其底层技术和前提假设非常重要。 @@ -74,7 +74,7 @@ psql -X dbname < psql -X --set ON_ERROR_STOP=on dbname < dumpfile - 无论如何,你最终只会得到一个部分恢复的数据库。另一种做法是指定将整个转储作为单个事务恢复,这样恢复要么全部完成,要么全部回滚。可以通过把命令行选项传给psql来启用这种模式。使用这种模式时要注意,即便是一个很小的错误,也可能回滚一个已经运行了许多小时的恢复过程。不过,这仍可能比在部分恢复后手工清理一个复杂数据库更可取。 + 无论采用上述哪种方式,你最终只会得到一个部分恢复的数据库。另一种做法是指定将整个转储作为单个事务恢复,这样恢复要么全部完成,要么全部回滚。可以通过把命令行选项传给psql来启用这种模式。使用这种模式时要注意,即便是一个很小的错误,也可能回滚一个已经运行了许多小时的恢复过程。不过,这仍可能比在部分恢复后手工清理一个复杂数据库更可取。 @@ -194,7 +194,7 @@ pg_restore -d dbname - 对于非常大的数据库,你可能需要把split与前两种方法之一结合使用。 + 对于非常大的数据库,你可能需要把split与另外两种方法之一结合使用。 @@ -250,7 +250,7 @@ tar -cf backup.tar /usr/local/pgsql/data - 如果无法获得同时的快照,一种选择是将数据库服务器关闭足够长的时间,以建立所有冻结快照。另一种选择是执行持续归档基础备份(),因为这种备份不受备份期间文件系统变化的影响。这要求只在备份过程中启用持续归档;恢复则使用持续归档恢复()。 + 如果无法获得同时的快照,一种选择是将数据库服务器关闭足够长的时间,以建立所有冻结快照。另一种选择是执行持续归档基础备份(),因为这种备份不受备份期间文件系统变化的影响。这种方法只需在备份期间启用持续归档;恢复则使用持续归档恢复()。 @@ -266,11 +266,11 @@ tar -cf backup.tar /usr/local/pgsql/data 持续归档和时间点恢复(PITR) - continuous archiving + 持续归档 - point-in-time recovery + 时间点恢复 @@ -310,7 +310,7 @@ tar -cf backup.tar /usr/local/pgsql/data - 和普通文件系统备份技术一样,这种方法只能支持整个数据库集簇的恢复,而不支持其中某个子集的恢复。此外,它需要大量归档存储:基础备份可能很庞大,繁忙系统也会产生大量必须归档的 WAL 流量。尽管如此,在很多需要高可靠性的场景中,它仍是首选的备份技术。 + 和普通文件系统备份技术一样,这种方法只能支持整个数据库集簇的恢复,而不支持其中某个子集的恢复。此外,它需要大量归档存储:基础备份可能很庞大,繁忙系统也会产生许多兆字节的、必须归档的 WAL 流量。尽管如此,在很多需要高可靠性的场景中,它仍是首选的备份技术。 @@ -329,7 +329,7 @@ tar -cf backup.tar /usr/local/pgsql/data - 要启用 WAL 归档,请将配置参数设置为replica或更高,将设置为on,并在配置参数中指定要使用的 shell 命令,或者在配置参数中指定要使用的库。实际上,这些设置通常都会放在postgresql.conf文件中。 + 要启用 WAL 归档,请将配置参数设置为replica或更高,将设置为on,并在配置参数中指定要使用的 shell 命令,或者在配置参数中指定要使用的库。在实际使用中,这些设置总是放在postgresql.conf文件中。 @@ -345,20 +345,16 @@ test ! -f /mnt/server/archivedir/00000001000000A900000065 && cp pg_wal/0 对每个新的待归档文件都会生成一条类似的命令。 - - 归档命令会以运行PostgreSQL服务器的同一操作系统用户身份执行。由于这一系列被归档的 WAL 文件实际上包含了数据库中的几乎全部内容,因此你应确保归档数据不会被他人窥探;例如,把它归档到一个不向组或所有用户开放读权限的目录中。 - + 归档命令将以运行 PostgreSQL 服务器的同一用户身份执行。由于归档的一系列 WAL 文件实际上包含数据库中的全部内容,应确保归档数据不会被他人窥视;例如,将其归档到不允许所属组或其他用户读取的目录。 - - 重要的是,归档命令只有在成功时才返回零退出状态。收到零结果后,PostgreSQL会认为该文件已经成功归档,并会将其删除或回收。相反,非零状态会告诉PostgreSQL该文件尚未归档;系统会周期性重试,直到成功为止。 - + 归档命令必须当且仅当成功时才返回退出状态零。收到零状态后,PostgreSQL 会认为该文件已成功归档,并将其删除或回收。非零状态则告诉 PostgreSQL 该文件尚未归档;它会定期重试,直到成功。 另一种归档方式是把自定义归档模块用作archive_library。由于这类模块是用C编写的,创建自己的模块可能比编写 shell 命令需要更多工作。不过,归档模块可能比通过 shell 归档更高效,而且可以访问许多有用的服务器资源。有关归档模块的更多信息,见 - 当归档命令被信号终止(用于服务器关闭流程的SIGTERM除外),或者 shell 因退出状态大于 125 的错误(例如命令未找到)而失败,或者归档函数发出ERRORFATAL时,归档器进程会中止,并由 postmaster 重新启动。在这种情况下,失败不会记录到中。 + 当归档命令被信号终止(用于服务器关闭流程的SIGTERM除外),或者因 shell 报错(例如命令未找到)而以大于 125 的状态退出,或者归档函数发出ERRORFATAL时,归档器进程会中止,并由 postmaster 重新启动。在这种情况下,失败不会记录到中。 @@ -366,7 +362,7 @@ test ! -f /mnt/server/archivedir/00000001000000A900000065 && cp pg_wal/0 - 在少数情况下,PostgreSQL可能会尝试重新归档一个此前已经归档过的 WAL 文件。例如,如果系统在服务器把归档成功持久记录下来之前崩溃,服务器在重启后会再次尝试归档该文件(前提是归档仍然启用)。当归档命令或归档库遇到一个已存在的文件时,如果该文件与待归档 WAL 文件内容完全相同,且先前归档的文件已经完全持久化到存储,则前者应分别返回零状态或true。如果已存在文件的内容与正在归档的 WAL 文件不同,则归档命令或归档库必须分别返回非零状态或false。 + 在少数情况下,PostgreSQL可能会尝试重新归档一个此前已经归档过的 WAL 文件。例如,如果系统在服务器把归档成功持久记录下来之前崩溃,服务器在重启后会再次尝试归档该文件(前提是归档仍然启用)。当归档命令或归档库遇到一个已存在的文件时,如果该文件与待归档 WAL 文件内容完全相同,且先前归档的文件已经完全持久化到存储,则归档命令或归档库应分别返回零状态或true。如果已存在文件的内容与正在归档的 WAL 文件不同,则归档命令或归档库必须分别返回非零状态或false @@ -390,7 +386,7 @@ test ! -f /mnt/server/archivedir/00000001000000A900000065 && cp pg_wal/0 - 归档命令或归档函数只会在完整的 WAL 段上被调用。因此,如果服务器产生的 WAL 流量很小(或者存在低谷期),事务完成到其被安全写入归档存储之间可能会有很长延迟。为了限制未归档数据可能有多旧,你可以设置,强制服务器至少隔这么长时间切换到一个新的 WAL 段文件。注意,由强制切换而提前归档的文件长度仍与装满的文件相同。因此,把archive_timeout设得很短并不明智,这会使归档存储膨胀。archive_timeout设为大约 1 分钟通常是合理的。 + 归档命令或归档函数只会针对已完成的 WAL 段调用。因此,如果服务器产生的 WAL 流量很小(或者存在低谷期),事务完成到其被安全写入归档存储之间可能会有很长延迟。为了限制未归档数据可能有多旧,你可以设置,使服务器强制切换到新 WAL 段文件的间隔不超过这个值。注意,由强制切换而提前归档的文件长度仍与装满的文件相同。因此,把archive_timeout设得很短并不明智,这会使归档存储膨胀。archive_timeout设为大约 1 分钟通常是合理的。 @@ -426,39 +422,9 @@ test ! -f /mnt/server/archivedir/00000001000000A900000065 && cp pg_wal/0 - - 进行增量备份 - - - 你可以使用,通过指定--incremental选项进行增量备份。作为--incremental的参数,必须提供来自同一服务器较早一次备份的备份清单。生成的备份中,非关系文件会被完整包含,而某些关系文件则可能被较小的增量文件取代,这些文件只包含自较早备份以来发生变化的块,以及重建该文件当前版本所需的足够元数据。 - - - - 为了找出需要备份哪些块,服务器使用 WAL 汇总,这些汇总存储在数据目录中的pg_wal/summaries目录内。如果所需的汇总文件不存在,尝试执行增量备份将会失败。该目录中存在的汇总必须覆盖从前一次备份起始 LSN 到当前备份起始 LSN 之间的所有 LSN。由于服务器是在确定当前备份起始 LSN 后才去查找 WAL 汇总,因此所需的汇总文件可能不会立刻出现在磁盘上,但服务器会等待缺失文件出现。这对于 WAL 汇总进程落后的情况也有帮助。然而,如果所需文件已经被移除,或者 WAL 汇总进程追赶得不够快,增量备份就会失败。 - - - - 恢复增量备份时,不仅需要增量备份本身,还必须具有所有更早的备份,以便提供增量备份中省略的那些块。关于这项要求的更多信息见。请注意,当集簇的校验和状态发生变化时,使用pg_combinebackup会受到限制;参见pg_combinebackup limitations。 - - - - 请注意,使用完整备份的所有要求同样适用于增量备份。例如,你仍然需要在文件系统备份期间及之后生成的所有 WAL 段文件,以及任何相关的 WAL 历史文件。你仍然需要创建recovery.signal(或standby.signal),并按照所述执行恢复。恢复时需要更早的备份以及使用pg_combinebackup,是在这些要求之外额外增加的条件。请记住,PostgreSQL没有内置机制来判断哪些备份仍然需要作为恢复后续增量备份的基础。你必须自己跟踪完整备份与增量备份之间的关系,并确保在恢复后续增量备份可能还需要它们时,不要删除较早的备份。 - - - - 增量备份通常只对相对较大的数据库有意义,因为其中相当一部分数据不变,或者变化缓慢。对于小数据库,忽略增量备份的存在而直接进行完整备份会更简单,也更容易管理。对于所有数据都被频繁修改的大数据库,增量备份也不会比完整备份小多少。 - - - - 只有当恢复重放会从比它所依赖的前一次备份更晚的检查点开始时,增量备份才有可能进行。如果你在主库上进行增量备份,这个条件总能满足,因为每次备份都会触发新的检查点。在备库上,重放从最近的重启点开始。因此,如果自前一次备份以来活动很少,可能尚未创建新的重启点,备库上的增量备份就可能失败。 - - - 使用低级 API 进行基础备份 - - 除了使用进行完整或增量基础备份之外,你还可以使用低级 API 制作基础备份。这个过程比pg_basebackup方法多几个步骤,但相对简单。极其重要的是,这些步骤必须按顺序执行,并且在进行下一步之前必须确认当前步骤已经成功。 - + 使用低级 API 制作基础备份的过程,比 方法多几个步骤,但相对简单。务必按顺序执行这些步骤,并在继续下一步之前确认当前步骤成功。 多个备份可以并发运行(无论是通过该备份 API 启动的,还是通过启动的)。 @@ -573,12 +539,7 @@ SELECT * FROM pg_backup_stop(wait_for_archive => true); - 如果你正在恢复完整备份,可以把数据库文件直接恢复到目标目录中。务必确保它们以正确的所有者(数据库系统用户,而不是root!)和正确的权限恢复。如果使用了表空间,还应验证pg_tblspc/中的符号链接是否已正确恢复。 - - - - - 如果你正在恢复增量备份,则需要把该增量备份以及它直接或间接依赖的所有较早备份都恢复到执行恢复的那台机器上。这些备份必须放在单独的目录中,而不是你希望最终运行服务器的目标目录中。完成后,使用从完整备份和所有后续增量备份中提取数据,并向目标目录写出一份合成的完整备份。和上面一样,验证权限以及表空间链接是否正确。 + 从文件系统备份中恢复数据库文件。务必确保它们以正确的所有者(数据库系统用户,而不是root!)和正确的权限恢复。如果使用了表空间,还应验证pg_tblspc/中的符号链接是否已正确恢复。 @@ -610,7 +571,7 @@ SELECT * FROM pg_backup_stop(wait_for_archive => true); - 这一切的关键在于设置一个恢复配置,描述你希望如何恢复,以及恢复应运行到什么位置。其中绝对必须指定的一项是restore_command,它告诉PostgreSQL如何检索已归档的 WAL 文件段。像archive_command一样,它也是一个 shell 命令字符串。它可以包含%f,会被替换为所需 WAL 文件的名称;也可以包含%p,会被替换为复制该 WAL 文件时要使用的路径名。(该路径名相对于当前工作目录,也就是集簇的数据目录。)如果需要在命令中嵌入实际的%字符,请写成%%。最简单而有用的命令类似如下: + 这一切的关键在于设置一个恢复配置,描述你希望如何恢复,以及恢复应运行到什么位置。其中绝对必须指定的一项是restore_command,它告诉PostgreSQL如何检索已归档的 WAL 段文件。像archive_command一样,它也是一个 shell 命令字符串。它可以包含%f,会被替换为所需 WAL 文件的名称;也可以包含%p,会被替换为复制该 WAL 文件时要使用的路径名。(该路径名相对于当前工作目录,也就是集簇的数据目录。)如果需要在命令中嵌入实际的%字符,请写成%%。最简单而有用的命令类似如下: restore_command = 'cp /mnt/server/archivedir/%f %p' @@ -618,11 +579,11 @@ restore_command = 'cp /mnt/server/archivedir/%f %p' - 重要的是,该命令在失败时必须返回非零退出状态。系统调用该命令来请求归档中不存在的文件;遇到这种情况时,它就应返回非零值。这不是一种错误情况。例外是,如果该命令被信号终止(用于数据库服务器关闭的SIGTERM除外),或者因 shell 错误(如命令未找到)而失败,那么恢复将中止,服务器也不会启动。 + 重要的是,该命令在失败时必须返回非零退出状态。系统调用该命令来请求归档中不存在的文件;遇到这种情况时,它必须返回非零值。这不是一种错误情况。例外是,如果该命令被信号终止(用于数据库服务器关闭的SIGTERM除外),或者因 shell 错误(如命令未找到)而失败,那么恢复将中止,服务器也不会启动。 - 被请求的文件并不全都是 WAL 段文件;你还应预期会收到对带有.history后缀文件的请求。另外请注意,%p路径的基本文件名会与%f不同;不要指望它们可以互换使用。 + 被请求的文件并不全都是 WAL 段文件;你还应预期会收到对带有.history后缀文件的请求。另外请注意,%p路径的文件名部分会与%f不同;不要指望它们可以互换使用。 @@ -630,16 +591,16 @@ restore_command = 'cp /mnt/server/archivedir/%f %p' - 通常,恢复会处理完所有可用的 WAL 段,从而把数据库恢复到当前时间点(或者在可用 WAL 段所允许的情况下尽可能接近当前时间点)。因此,一次正常恢复通常会以一条file not found消息结束,具体错误文本取决于你选择的restore_command。在恢复开始时,你也可能看到一条针对类似00000001.history文件的错误消息。这同样是正常的,在简单恢复场景中并不表示有问题;相关讨论见。 + 通常,恢复会处理完所有可用的 WAL 段,从而把数据库恢复到当前时间点(或者在可用 WAL 段所允许的情况下尽可能接近当前时间点)。因此,一次正常恢复会以一条file not found消息结束,具体错误文本取决于你选择的restore_command。在恢复开始时,你也可能看到一条针对类似00000001.history文件的错误消息。这同样是正常的,在简单恢复场景中并不表示有问题;相关讨论见 - 如果你希望恢复到过去的某个时间点(例如恢复到那位初级 DBA 删掉你的主事务表之前),只需指定所需的停止点即可。这个停止点也称为恢复目标,可以通过日期/时间、命名恢复点或者某个特定事务 ID 完成时刻来指定。在目前的实现下,只有日期/时间和命名恢复点这两种方式真正比较实用,因为没有工具能够帮助你足够准确地识别应使用哪个事务 ID。 + 如果你希望恢复到过去的某个时间点(例如恢复到那位初级 DBA 删掉你的主事务表之前),只需指定所需的停止点即可。这个停止点也称为恢复目标,可以通过日期/时间、命名恢复点或者某个特定事务 ID 完成时刻来指定。在撰写本文时,只有日期/时间和命名恢复点这两种方式真正比较实用,因为没有工具能够帮助你足够准确地识别应使用哪个事务 ID。 - 停止点必须晚于基础备份的结束时间,也就是pg_backup_stop的结束时间。你不能用某次基础备份恢复到该备份仍在进行中的时间点。(若要恢复到这样的时间点,必须回到更早的一次基础备份,再从那里向前滚动。) + 停止点必须晚于基础备份的结束时间,也就是pg_backup_stop的结束时间。你不能用某次基础备份恢复到该备份仍在进行中的时间点。(若要恢复到这样的时间点,必须回到更早的一次基础备份,再从那里向前重放日志。) @@ -653,12 +614,10 @@ restore_command = 'cp /mnt/server/archivedir/%f %p' 时间线 - timelines + 时间线 - - 把数据库恢复到过去某个时间点的能力,会带来一些复杂性,颇有点像关于时间旅行和平行宇宙的科幻小说。例如,在数据库的原始历史中,假设你在星期二晚上 5:15 删掉了一张关键表,但直到星期三中午才意识到自己的错误。于是你拿出备份,把系统恢复到星期二晚上 5:14,并重新上线运行。在数据库宇宙的这条历史中,你从未删掉那张表。但如果你后来发现这并不是个好主意,并且想回到原始历史中的星期三上午某个时间点,就办不到了,因为在数据库重新上线运行期间,它可能已经覆盖了某些 WAL 段文件,而这些文件本来能把你带回到现在想回去的那个时刻。因此,为了避免这种情况,你需要把时间点恢复之后生成的那一串 WAL 记录,与数据库原始历史中生成的那些 WAL 记录区分开来。 - + 能够将数据库恢复到过去某个时间点,也会带来一些类似科幻故事中时间旅行和平行宇宙的复杂情况。例如,假设在数据库原来的历史中,你在周二下午 5:15 删除了一张重要的表,直到周三中午才发现错误。你从容地取出备份,将数据库恢复到周二下午 5:14,然后重新投入运行。在数据库宇宙的这段历史中,你从未删除过那张表。但假设你后来发现这样做不太合适,希望回到原来历史中的周三上午某个时刻。如果数据库恢复运行后覆盖了通往该时刻所需的某些 WAL 段文件,就无法回去了。因此,为了避免这种情况,需要区分时间点恢复后产生的一系列 WAL 记录与数据库原来历史中产生的记录。 为了解决这个问题,PostgreSQL引入了时间线的概念。每当一次归档恢复完成时,系统都会创建一条新的时间线,用来标识此次恢复之后生成的 WAL 记录序列。时间线 ID 是 WAL 段文件名的一部分,因此新的时间线不会覆盖先前时间线产生的 WAL 数据。例如,在 WAL 文件名0000000100001234000055CD中,开头的00000001就是十六进制表示的时间线 ID。(注意,在服务器日志消息等其他场合,时间线 ID 通常以十进制打印。) @@ -672,9 +631,7 @@ restore_command = 'cp /mnt/server/archivedir/%f %p' 每当创建一条新的时间线时,PostgreSQL都会创建一个时间线历史文件,记录它是从哪条时间线、在何时分叉出来的。当从包含多条时间线的归档中恢复时,这些历史文件对于系统选取正确的 WAL 段文件是必需的。因此,它们会像 WAL 段文件一样被归档到 WAL 归档区域。历史文件只是很小的文本文件,因此长期保存它们既便宜也合适(而段文件通常很大)。如果你愿意,还可以在历史文件中加入注释,记录创建这条时间线的方式和原因。当你因实验而积累出一批错综复杂的时间线时,这类注释会特别有价值。 - - 恢复的默认行为是恢复到归档中找到的最新时间线。如果你希望恢复到执行基础备份时的当前时间线,或者恢复到某个指定的子时间线(也就是说,你想回到某个本身就是在一次恢复尝试之后才产生的状态),就需要指定current,或者在中指定目标时间线 ID。你不能恢复到那些在基础备份之前就已经分叉出去的时间线。 - + 默认的恢复行为是恢复到归档中找到的最新时间线。如果希望恢复到制作基础备份时的当前时间线,或者某条特定的子时间线(即希望返回到一次恢复尝试之后产生的某个状态),需要在 中指定 current 或目标时间线 ID。不能恢复到在基础备份之前就已分支出去的时间线。 @@ -685,14 +642,14 @@ restore_command = 'cp /mnt/server/archivedir/%f %p' - 单机热备份 + 独立热备份 - 可以利用PostgreSQL的备份设施生成单机热备份。这些备份不能用于时间点恢复,但它们的制作和恢复通常都比pg_dump转储快得多。(它们也比pg_dump转储大得多,因此在某些情况下速度优势可能会被抵消。) + 可以利用PostgreSQL的备份设施生成独立热备份。这些备份不能用于时间点恢复,但它们的制作和恢复通常都比pg_dump转储快得多。(它们也比pg_dump转储大得多,因此在某些情况下速度优势可能会被抵消。) - 和基础备份一样,生成单机热备份最简单的方法是使用工具。如果在调用它时包含-X参数,使用该备份所需的全部预写式日志都会自动包含在备份中,恢复该备份时也不需要额外动作。 + 和基础备份一样,生成独立热备份最简单的方法是使用工具。如果在调用它时包含-X参数,使用该备份所需的全部预写式日志都会自动包含在备份中,恢复该备份时也不需要额外动作。 @@ -723,7 +680,7 @@ archive_command = 'local_backup_script.sh "%p" "%f"' - 脚本中可能需要解决的需求示例包括: + 可以在脚本中处理的需求示例包括: @@ -732,7 +689,7 @@ archive_command = 'local_backup_script.sh "%p" "%f"' - 把 WAL 文件成批处理,使其每三个小时传输一次,而不是每生成一个就传一次 + 把 WAL 文件成批处理,使其每三个小时传输一次,而不是每次只传输一个 diff --git a/zh/16/bki.sgml b/zh/16/bki.sgml index f2992540..ef615e42 100644 --- a/zh/16/bki.sgml +++ b/zh/16/bki.sgml @@ -74,9 +74,9 @@ descr => 'database\'s default template', datname => 'template1', encoding => 'ENCODING', datlocprovider => 'LOCALE_PROVIDER', datistemplate => 't', - datallowconn => 't', dathasloginevt => 'f', datconnlimit => '-1', datfrozenxid => '0', + datallowconn => 't', datconnlimit => '-1', datfrozenxid => '0', datminmxid => '1', dattablespace => 'pg_default', datcollate => 'LC_COLLATE', - datctype => 'LC_CTYPE', datlocale => 'DATLOCALE', datacl => '_null_' }, + datctype => 'LC_CTYPE', daticulocale => 'ICU_LOCALE', datacl => '_null_' }, ] ]]> diff --git a/zh/16/brin.sgml b/zh/16/brin.sgml index ec648028..626d0612 100644 --- a/zh/16/brin.sgml +++ b/zh/16/brin.sgml @@ -8,7 +8,7 @@ BRIN - + 简介 @@ -25,8 +25,7 @@ - 如果索引中存储的摘要信息与查询条件相一致BRIN - 索引就可以通过常规位图索引扫描来满足查询,并返回每个范围内所有页上的全部元组。 + BRIN 索引可以通过常规位图索引扫描来满足查询;对于每个范围,如果索引中存储的摘要信息与查询条件相一致,就会返回该范围内所有页上的全部元组。 查询执行器负责重新检查这些元组,并丢弃不匹配查询条件的元组 — 换句话说,这些索引是有损的。 由于 BRIN 索引非常小,与顺序扫描相比,扫描索引只会带来很小的额外开销, 但可以避免扫描那些已知不包含匹配元组的大块表数据。 @@ -46,7 +45,7 @@ 但与此同时,存储的摘要数据也会更精确,并且在索引扫描期间可以跳过更多数据块。 - + 索引维护 @@ -83,7 +82,7 @@ 当启用自动摘要时,一旦检测到向下一个块范围第一页的第一项执行了插入, - 就会向 autovacuum 发送请求,要求对该块范围执行定向摘要。 + 就会向 autovacuum 发送请求,要求对前一个块范围执行定向摘要。 该请求会在同一数据库中的某个 autovacuum 工作进程下一次结束运行时得到处理。 如果请求队列已满,该请求就不会被记录,并会向服务器日志发送一条消息: @@ -99,10 +98,10 @@ LOG: request for BRIN range summarization for index "brin_wi_idx" page 128 was 详见 - + - + 内置操作符类 @@ -701,7 +700,7 @@ LOG: request for BRIN range summarization for index "brin_wi_idx" page 128 was - + 操作符类参数 @@ -757,11 +756,11 @@ LOG: request for BRIN range summarization for index "brin_wi_idx" page 128 was - - - + + + 可扩展性 @@ -788,13 +787,13 @@ LOG: request for BRIN range summarization for index "brin_wi_idx" page 128 was typedef struct BrinOpcInfo { - /* Number of columns stored in an index column of this opclass */ + /* 此操作符类在一个索引列中存储的列数 */ uint16 oi_nstored; - /* Opaque pointer for the opclass' private use */ + /* 供操作符类私有使用的不透明指针 */ void *oi_opaque; - /* Type cache entries of the stored columns */ + /* 所存储列的类型缓存条目 */ TypeCacheEntry *oi_typcache[FLEXIBLE_ARRAY_MEMBER]; } BrinOpcInfo; @@ -1010,62 +1009,62 @@ typedef struct BrinOpcInfo 操作符策略 1 - left-of 操作符 + 位于左侧的操作符 操作符策略 4 操作符策略 2 - does-not-extend-to-the-right-of 操作符 + 不延伸到右侧的操作符 操作符策略 5 操作符策略 3 - overlaps 操作符 + 重叠操作符 操作符策略 4 - does-not-extend-to-the-left-of 操作符 + 不延伸到左侧的操作符 操作符策略 1 操作符策略 5 - right-of 操作符 + 位于右侧的操作符 操作符策略 2 - 操作符策略 6, 18 - same-as-or-equal-to 操作符 + 操作符策略 6、18 + 相同或等于操作符 操作符策略 7 - 操作符策略 7, 16, 24, 25 - contains-or-equal-to 操作符 + 操作符策略 7、16、24、25 + 包含或等于操作符 - 操作符策略 8, 26, 27 - is-contained-by-or-equal-to 操作符 + 操作符策略 8、26、27 + 被包含或等于操作符 操作符策略 3 操作符策略 9 - does-not-extend-above 操作符 + 不延伸到上方的操作符 操作符策略 11 操作符策略 10 - is-below 操作符 + 位于下方的操作符 操作符策略 12 操作符策略 11 - is-above 操作符 + 位于上方的操作符 操作符策略 9 操作符策略 12 - does-not-extend-below 操作符 + 不延伸到下方的操作符 操作符策略 10 @@ -1111,12 +1110,12 @@ typedef struct BrinOpcInfo 要为仅实现等值操作符且支持哈希的数据类型编写操作符类,可以按 - 所示,将 bloom 支持过程与相应操作符一起使用。 - 所有操作符类成员(过程和操作符)都是必需的。 + 所示,将 bloom 支持函数与相应操作符一起使用。 + 所有操作符类成员(函数和操作符)都是必需的。 - bloom 操作符类的过程和支持编号 + bloom 操作符类的函数和支持编号 @@ -1126,28 +1125,28 @@ typedef struct BrinOpcInfo - 支持过程 1 + 支持函数 1 内部函数brin_bloom_opcinfo() - 支持过程 2 + 支持函数 2 内部函数brin_bloom_add_value() - 支持过程 3 + 支持函数 3 内部函数brin_bloom_consistent() - 支持过程 4 + 支持函数 4 内部函数brin_bloom_union() - 支持过程 5 + 支持函数 5 内部函数brin_bloom_options() - 支持过程 11 - 计算元素哈希值的函数 + 支持函数 11 + 计算元素 hash 值的函数 操作符策略 1 @@ -1158,20 +1157,20 @@ typedef struct BrinOpcInfo
- 支持过程编号 1 至 10 保留给 BRIN 内部函数,因此 SQL 层函数从编号 11 开始。 + 支持函数编号 1 至 10 保留给 BRIN 内部函数,因此 SQL 层函数从编号 11 开始。 支持函数 11 是构建索引所需的主要函数。 - 它应接受一个与操作符类数据类型相同的参数,并返回该值的哈希值。 + 它应接受一个与操作符类数据类型相同的参数,并返回该值的 hash 值。 minmax-multi 操作符类也面向实现全序集的数据类型,可以看作 minmax 操作符类的简单扩展。 minmax 操作符类把每个块范围中的值摘要为单个连续区间,而 minmax-multi 则允许将其摘要为多个较小区间,以改进对离群值的处理。 - 可以按 所示,将 minmax-multi 支持过程与相应操作符一起使用。 - 所有操作符类成员(过程和操作符)都是必需的。 + 可以按 所示,将 minmax-multi 支持函数与相应操作符一起使用。 + 所有操作符类成员(函数和操作符)都是必需的。 - minmax-multi 操作符类的过程和支持编号 + minmax-multi 操作符类的函数和支持编号 @@ -1181,27 +1180,27 @@ typedef struct BrinOpcInfo - 支持过程 1 + 支持函数 1 内部函数brin_minmax_multi_opcinfo() - 支持过程 2 + 支持函数 2 内部函数brin_minmax_multi_add_value() - 支持过程 3 + 支持函数 3 内部函数brin_minmax_multi_consistent() - 支持过程 4 + 支持函数 4 内部函数brin_minmax_multi_union() - 支持过程 5 + 支持函数 5 内部函数brin_minmax_multi_options() - 支持过程 11 + 支持函数 11 计算两个值之间距离(范围长度)的函数 @@ -1239,5 +1238,5 @@ typedef struct BrinOpcInfo minmax 的示例见 float4_minmax_ops,inclusion 的示例见 box_inclusion_ops。 - + diff --git a/zh/16/btree.sgml b/zh/16/btree.sgml index a94ed527..0b334872 100644 --- a/zh/16/btree.sgml +++ b/zh/16/btree.sgml @@ -8,7 +8,7 @@ B-树 - + 简介 @@ -18,16 +18,16 @@ - 由于每个 B-树 操作符类都会为其数据类型施加一种排序顺序,B-树 + 由于每个 B-树操作符类都会为其数据类型施加一种排序顺序,B-树 操作符类(更准确地说,是操作符族)已经成为 PostgreSQL 用来统一表示和理解排序语义的方式。因此,它们具备了一些超出单纯支持 - B-树 索引所需范围的特性,系统中某些与 btree AM + B-树索引所需范围的特性,系统中某些与 B-树 AM 相距甚远的部分也会利用它们。 - + - + B-树操作符类的行为 @@ -55,7 +55,7 @@ - = 操作符必须是一种等价关系;也就是说,对于该数据类型的所有非空值 + = 操作符必须是一种等价关系;也就是说,对于该数据类型的所有非 null 值 ABC: @@ -93,7 +93,7 @@ - < 操作符必须是一种强排序关系;也就是说,对于所有非空值 + < 操作符必须是一种强排序关系;也就是说,对于所有非 null 值 ABC: @@ -123,7 +123,7 @@ - 此外,该顺序还是全序的;也就是说,对于所有非空值 + 此外,该顺序还是全序的;也就是说,对于所有非 null 值 AB: @@ -171,24 +171,24 @@ 很容易理解为什么 B-树 索引要求这些定律在单一数据类型内部成立:没有这些定律,就不存在可用于排列键的顺序。此外,使用不同数据类型比较键的索引搜索,也要求跨两种数据类型的比较行为合理一致。把这些要求扩展到一个族内的三种或更多数据类型,虽然并非 B-树 索引机制本身的严格要求,但规划器会出于优化目的依赖它们。 - + - + B-树支持函数 - 如所示,btree 定义了一个必需和五个可选的支持函数。六个用户定义的方法如下: + 如所示,B-树定义了一个必需和四个可选的支持函数。五个用户定义的方法如下: order - 对于 B-树 操作符族为其提供比较操作符的每一种数据类型组合,都必须提供一个比较支持函数。该函数在 + 对于 B-树操作符族为其提供比较操作符的每一种数据类型组合,都必须提供一个比较支持函数。该函数在 pg_amproc 中注册,支持函数编号为 1,并且 amproclefttype/amprocrighttype 要等于该比较的左右数据类型(也就是与匹配操作符在 - pg_amop 中注册时相同的数据类型)。比较函数必须接受两个非空值 + pg_amop 中注册时相同的数据类型)。比较函数必须接受两个非 null 值 AB,并返回一个 int32 值,其值为 < 0、 @@ -197,12 +197,12 @@ < BA = BA - > B。不允许返回空值:该数据类型的所有值都必须可比较。示例见 + > B。不允许返回 null:该数据类型的所有值都必须可比较。示例见 src/backend/access/nbtree/nbtcompare.c - 如果参与比较的值属于可排序数据类型,则会通过标准的 + 如果参与比较的值属于支持排序规则的数据类型,则会通过标准的 PG_GET_COLLATION() 机制,把适当的排序规则 OID 传递给比较支持函数。 @@ -266,7 +266,7 @@ returns bool - in_range 函数的核心语义取决于这两个 Boolean + in_range 函数的核心语义取决于这两个布尔 标志参数。它应当先对 baseoffset 做加法或减法,再把 val 与结果比较,具体如下: @@ -383,7 +383,7 @@ returns bool - 如果被排序的类型(type1)属于可排序数据类型,则会通过标准的 + 如果被排序的类型(type1)属于支持排序规则的数据类型,则会通过标准的 PG_GET_COLLATION() 机制,把适当的排序规则 OID 传递给 in_range 函数。 @@ -408,12 +408,7 @@ returns bool equalimage(opcintype oid) returns bool - 返回值是关于某个操作符类及其排序规则的静态信息。返回 - true 表示:该操作符类的 - order 函数被保证只有在返回 - 0arguments are equal)时,其 - AB - 参数才是可以互换而不损失任何语义信息的。如果未注册 + 返回值是关于某个操作符类及其排序规则的静态信息。返回 true 表示可以保证:该操作符类的 order 函数只有在其 AB 参数也能够互换而不损失任何语义信息时,才会返回 0参数相等)。如果未注册 equalimage 函数,或其返回 false,就表示不能假定该条件成立。 @@ -421,7 +416,7 @@ equalimage(opcintype oid) returns bool opcintype 参数是该操作符类所索引数据类型的 pg_type.oid。这只是为了方便在不同操作符类之间复用同一个底层 equalimage 函数。如果 - opcintype 是可排序数据类型,则会通过标准的 + opcintype 是支持排序规则的数据类型,则会通过标准的 PG_GET_COLLATION() 机制,把适当的排序规则 OID 传递给 equalimage 函数。 @@ -453,7 +448,7 @@ equalimage(opcintype oid) returns bool 发行版中包含的操作符类遵循的惯例是:注册一个现成的通用 equalimage 函数。大多数操作符类注册 btequalimage(),这表示去重在无条件下都是安全的。像 - text 这样可排序数据类型的操作符类会注册 + text 这样支持排序规则的数据类型的操作符类会注册 btvarstrequalimage(),这表示在确定性排序规则下去重是安全的。第三方扩展的最佳实践则是注册它们自己的自定义函数,以保留控制权。 @@ -489,38 +484,18 @@ options(relopts local_relopts *) returns - - skipsupport - - - 可选地,B-树 操作符族可以提供skip 支持函数,注册为支持函数编号 - 6。这些函数为 B-树 - 代码提供了一种按键空间顺序遍历某个操作符类底层输入类型所能表示的全部可能值的方法。当核心代码应用跳过扫描优化时,就会用到它。相关 - API 定义在 src/include/utils/skipsupport.h - 中。 - - - 没有提供 skip 支持函数的操作符类,仍然可以使用跳过扫描。核心代码仍可采用其后备策略,尽管对于某些离散类型来说,这种策略可能并非最优。对于连续类型上的操作符类,提供 - skip 支持函数通常没有意义(甚至可能不可行)。 - - - 操作符族注册跨类型的 skipsupport - 函数并不合理,尝试这样做会导致错误。因为要确定下一个可被索引的值,必须通过递增一个从索引元组复制出来的值来完成。所生成的值都必须属于同一种底层数据类型(也就是被跳过的索引列的 opclass 输入类型)。 - - - - + - + 实现 本节介绍一些可能对高级用户有用的 B-树索引实现细节。若要查看更详细、更加侧重内部机制的 B-树实现说明,请参见源码发布包中的 src/backend/access/nbtree/README - + B-树结构 PostgreSQL 的 B-树 @@ -531,9 +506,9 @@ options(relopts local_relopts *) returns 当现有叶页无法容纳一个新传入的元组时,B-树索引就会增加新的叶页。一次页拆分操作会把原本属于溢出页的一部分项移动到新页中,从而为这些项腾出空间。页拆分还必须在父页中插入一个指向新页的下行链接,这又可能导致父页继续拆分。页拆分会以递归的方式向上级联。当根页最终也容纳不下新的下行链接时,就会发生一次根页拆分操作。它通过创建一个位于原始根页之上的新根页,为树结构增加一个新的层级。 - + - + 自底向上索引删除 B-树索引并不直接知道,在 MVCC @@ -547,7 +522,7 @@ options(relopts local_relopts *) returns B-树索引会通过执行自底向上索引删除轮次,增量地删除这类版本频繁更替产生的索引元组。每一轮删除都是因预期中的版本频繁更替页拆分而触发的。这只会发生在那些没有被 - UPDATE 语句逻辑修改的索引上,否则过时版本就会集中积累在某些特定页面中。通常可以避免页拆分,不过也可能出现某些实现层面的启发式规则甚至一个垃圾索引元组都识别不出来、删不掉的情况(这时就要靠页拆分或一次去重轮次来解决新元组放不进叶页的问题)。任何一次索引扫描在单个逻辑行上必须穿越的最坏版本数,是影响整个系统响应能力和吞吐量的重要因素。一次自底向上索引删除轮次会基于涉及逻辑行与版本的定性区别,针对单个叶页中疑似垃圾的元组。这与自动清理工作进程执行的自顶向下索引清理不同,后者是在超出某些定量的表级阈值时触发的(见)。 + UPDATE 语句逻辑修改的索引上;如果不执行这类删除,过时版本就会集中积累在某些特定页面中。通常可以避免页拆分,不过也可能出现某些实现层面的启发式规则甚至一个垃圾索引元组都识别不出来、删不掉的情况(这时就要靠页拆分或一次去重轮次来解决新元组放不进叶页的问题)。任何一次索引扫描在单个逻辑行上必须穿越的最坏版本数,是影响整个系统响应能力和吞吐量的重要因素。一次自底向上索引删除轮次会基于涉及逻辑行与版本的定性区别,针对单个叶页中疑似垃圾的元组。这与自动清理工作进程执行的自顶向下索引清理不同,后者是在超出某些定量的表级阈值时触发的(见)。 @@ -578,16 +553,16 @@ options(relopts local_relopts *) returns (当然,这绝不可能发生在生命周期跨越同一个 VACUUM 周期的两个逻辑行之间)。 - + - + 去重 重复项是这样一种叶页元组(即指向表中行的元组):其中所有被索引的键列值,都与同一索引中至少另一个叶页元组对应列的值相匹配。重复元组在实践中相当常见。当启用一种可选技术时,B-树索引可以为重复项采用一种特殊且节省空间的表示形式:去重 去重通过周期性地把一组组重复元组合并起来,为每一组形成一个 - posting list 元组。在这种表示中,列键值只出现一次,后面跟着一个排好序的 + 倒排列表 元组。在这种表示中,列键值只出现一次,后面跟着一个排好序的 TID 数组,指向表中的各行。这能显著减小那些每个值(或每一种不同列值组合)平均会出现多次的索引的存储大小。查询延迟可能显著降低,整体查询吞吐量也可能显著提升,例行索引清理的开销同样可能显著减少。 @@ -601,14 +576,14 @@ options(relopts local_relopts *) returns 去重过程是惰性发生的:当插入一个放不进现有叶页的新项时,只有在索引元组删除也无法为该新项释放足够空间的情况下,才会进行去重(通常只会短暂考虑删除,然后就跳过)。与 - GIN 的 posting list 元组不同,B-树的 posting list - 元组不需要在每次插入新的重复项时都扩展;它们只是叶页原始逻辑内容的一种替代物理表示。这种设计优先考虑混合读写工作负载下的一致性能。大多数客户端应用至少都能从去重中获得适度的性能收益。去重默认启用。 + GIN 的倒排列表元组不同,B-树的倒排列表 + 元组不需要在每次插入新的重复项时都扩展;它们只是叶页原始逻辑内容的一种替代物理表示。这种设计优先考虑混合读写工作负载下的稳定性能。大多数客户端应用至少都能从去重中获得适度的性能收益。去重默认启用。 CREATE INDEXREINDEX - 都会应用去重来创建 posting list - 元组,只是两者采用的策略略有不同。对于从表中取出的已排序输入中遇到的每一组普通重复元组,都会在被加入当前待写入叶页之前先合并成一个 - posting list 元组。每个 posting list 元组都会尽量容纳更多的 + 都会应用去重来创建倒排列表 + 元组,不过它们采用的策略与上述过程略有不同。对于从表中取出的已排序输入中遇到的每一组普通重复元组,都会在被加入当前待写入叶页之前先合并成一个 + 倒排列表元组。每个倒排列表元组都会尽量容纳更多的 TID。叶页按通常方式写出,不需要额外独立的去重过程。由于 CREATE INDEXREINDEX 都是一次性的批处理操作,这种策略非常适合它们。 @@ -617,14 +592,14 @@ options(relopts local_relopts *) returns 如果某个写密集型工作负载由于索引中的重复值很少甚至没有,而无法从去重中获益,那么它会承担很小且固定的性能损耗(除非显式禁用去重)。 deduplicate_items 存储参数可用于在单个索引内禁用去重。而只读工作负载绝不会因此遭受性能损失,因为读取 - posting list 元组至少与读取标准元组表示一样高效。禁用去重通常并没有帮助。 + 倒排列表元组至少与读取标准元组表示一样高效。禁用去重通常并没有帮助。 有时唯一索引(以及唯一约束)也可以使用去重。这允许叶页临时吸收因版本频繁更替产生的额外重复项。唯一索引中的去重能够增强自底向上索引删除,特别是在长事务持有阻塞垃圾回收的快照时。其目标是为自底向上索引删除策略再次发挥作用争取时间。把页拆分推迟到某个单独的长事务自然结束之后,可能使一次自底向上删除轮次在较早一次失败的地方获得成功。 - 系统会应用一种特殊的启发式规则,来判定唯一索引中是否应当执行一次去重轮次。它往往可以直接跳到拆分叶页,从而避免把周期浪费在无益的去重过程中而造成性能损耗。如果你担心去重的开销,可以考虑有选择地设置 + 系统会应用一种特殊的启发式规则,来判定唯一索引中是否应当执行一次去重轮次。它往往可以直接跳到拆分叶页,从而避免把处理器周期浪费在无益的去重过程中而造成性能损耗。如果你担心去重的开销,可以考虑有选择地设置 deduplicate_items = off。在唯一索引中保持去重启用,坏处很小。 @@ -648,7 +623,7 @@ options(relopts local_relopts *) returns numeric 不能使用去重。必须保留相等的 datum - 之间的小数位数。 + 之间的显示小数位数。 @@ -694,7 +669,7 @@ options(relopts local_relopts *) returns - + diff --git a/zh/16/catalogs.sgml b/zh/16/catalogs.sgml index 19348d48..df29145e 100644 --- a/zh/16/catalogs.sgml +++ b/zh/16/catalogs.sgml @@ -678,7 +678,7 @@ t = 表(包括物化视图), - i = 索引. + i = 索引。 @@ -931,7 +931,7 @@
- amproclefttypeamprocrighttype列的通常解释是它们标识了一个特定支持过程所支持的操作符的左右输入类型。对于某些访问方法它们和支持过程本身的输入数据类型相匹配,而对其他的则不会匹配。对于一个索引有一个默认支持过程的概念,这些支持过程的amproclefttypeamprocrighttype都等于索引操作符类的opcintype。 + amproclefttypeamprocrighttype列的通常解释是它们标识了一个特定支持函数所支持的操作符的左右输入类型。对于某些访问方法它们和支持函数本身的输入数据类型相匹配,而对其他的则不会匹配。对于一个索引有一个默认支持函数的概念,这些支持函数的amproclefttypeamprocrighttype都等于索引操作符类的opcintype
@@ -1086,13 +1086,22 @@
+ + + attcacheoff int4 + + + 在存储中始终为 -1,但装入内存中的行描述符时,可能会更新为该属性在行内偏移量的缓存值 + + + atttypmod int4 atttypmod记录了在表创建时提供的类型相关数据(例如一个varchar列的最大长度)。 - 它会被传递给类型相关的输入函数和长度强制函数。对于那些不需要atttypmod的类型,这个值通常总是为-1。 + 它会被传递给类型相关的输入函数和长度强制转换函数。对于那些不需要atttypmod的类型,这个值通常为 -1。 @@ -1151,7 +1160,7 @@ attnotnull bool
- 此列具有一个非空约束(可能尚未验证) + 这代表一个非空约束 @@ -1170,8 +1179,7 @@ atthasmissing bool
- 该列在行中完全缺失时会用到这个列的值,如果在行创建之后增加一个有非易失DEFAULT值的列,就会发生这种情况。 - 实际使用的值被存放在attmissingval列中。 + 此列有一个值,供该列在数据行中完全缺失时使用;在数据行创建之后添加带有非易失 DEFAULT 值的列时,就会出现这种情况。实际使用的值存储在 attmissingval 列中。 @@ -1191,8 +1199,7 @@
如果是零字节(''),则不是生成列。 - 否则,s = 存储式(stored),v = 虚拟(virtual)。 - 存储式生成列会像普通列一样实际存储;虚拟生成列则在物理上存储为空值,实际值在运行时计算。 + 否则,s = 存储式。(将来可能会添加其他值。) @@ -1201,7 +1208,7 @@ attisdropped bool - 该列被删除且不再有效。一个删除的列仍然物理存在于表中,但是会被分析器忽略并因此无法通过SQL访问。 + 该列被删除且不再有效。一个删除的列仍然物理存在于表中,但是会被解析器忽略并因此无法通过SQL访问。 @@ -1225,25 +1232,25 @@ - attcollation oid - (引用 pg_collation.oid) + attstattarget int2 - 该列被定义的排序规则,如果该列不是一个可排序数据类型则为0。 + attstattarget 控制 + ANALYZE 为该列收集统计信息时的细节级别。 + 零值表示不应收集统计信息。 + 负值表示使用系统默认统计目标。 + 正值的确切含义依赖于数据类型。 + 对于标量数据类型,attstattarget 既是要收集的高频值目标个数,也是要创建的直方图桶目标个数。 - attstattarget int2 + attcollation oid + (引用 pg_collation.oid - attstattarget 控制 - ANALYZE 为该列收集统计信息时的细节级别。 - 零值表示不应收集统计信息。 - 空值表示使用系统默认统计目标。 - 正值的确切含义依赖于数据类型。 - 对于标量数据类型,attstattarget 既是要收集的高频值目标个数,也是要创建的直方图桶目标个数。 + 该列定义的排序规则;如果该列的数据类型不支持排序规则,则为零。 @@ -1252,7 +1259,7 @@ attacl aclitem[] - 列级访问权限, 如果此列上已有特别授予的权限 + 列级访问权限,如果此列上已有特别授予的权限 @@ -1280,7 +1287,7 @@ 这个列中是一个含有一个元素的数组,其中的值被用于该列在行中完全缺失时,如果在行创建之后增加一个有非易失DEFAULT值的列,就会发生这种情况。 - 只有当atthasmissing为真时才使用这个值。如果没有值则该列为空。 + 只有当atthasmissing为真时才使用这个值。如果没有值则该列为空值。 @@ -1288,9 +1295,7 @@ - 在一个被删除的列的pg_attribute的项中,atttypid被重置为0,但attlen以及其他从pg_type拷贝的域仍然有效。 - 这种安排用于处理一种情况,即被删除列的数据类型后来被删除,并且因此不再有相应的pg_type行。 - attlen和其他域可以被用来解释表的一行的内容。 + 在被删除列的 pg_attribute 条目中,atttypid 被重置为零,但 attlen 以及其他从 pg_type 复制的字段仍然有效。这种安排用于应对被删除列的数据类型后来也被删除、因而不再有相应 pg_type 行的情况。attlen 和其他字段可用于解释表中一行的内容。 @@ -1419,7 +1424,7 @@ rolconnlimit int4 - 对于可以登录的角色,本列设置该角色可以同时发起最大连接数。-1表示无限制。 + 对于可以登录的角色,本列设置该角色能够建立的最大并发连接数。-1 表示无限制。 @@ -1428,7 +1433,7 @@ rolpassword text - 加密后的密码;如果未设置则为空。其格式取决于所使用的加密方式。 + 加密后的密码;如果未设置则为空值。其格式取决于所使用的加密方式。 @@ -1437,7 +1442,7 @@ rolvaliduntil timestamptz - 密码过期时间(只用于密码鉴定),如果永不过期则为空 + 密码过期时间(仅用于密码认证);不设过期时间时为空值 @@ -1445,14 +1450,10 @@ - 对于一个MD5加密的密码,rolpassword列将由字符串md5后面跟上一个32字符的十六进制MD5哈希值构成。MD5哈希值将是该用户的密码串接上它们的用户名。例如,如果用户joe的密码是xyzzy,则PostgreSQL将存储xyzzyjoe的md5哈希。 + 对于一个MD5加密的密码,rolpassword列将由字符串md5后面跟上一个32字符的十六进制MD5哈希值构成。MD5 哈希值通过在用户密码后拼接用户名再计算得到。例如,如果用户joe的密码是xyzzy,则PostgreSQL将存储xyzzyjoe的md5哈希。 - - - 对 MD5 加密密码的支持已被弃用,并将在未来的 PostgreSQL 发布中移除。关于迁移到其他密码类型的详细信息,请参见。 - - + 如果密码是使用SCRAM-SHA-256加密的,则格式如下: @@ -1582,7 +1583,7 @@ SCRAM-SHA-256$<iteration count>:&l - 需要注意的是,pg_cast并不表示系统知道如何执行的所有类型转换,它只包括那些不能从某些通用规则推导出的转换。例如,一个域及其基类型之间的转换并未显式地在pg_cast中展示。另一个重要的例外是自动的基于 I/O 的类型转换,它们通过数据类型自己的 I/O 函数来转换成(或者转换自)text或其他字符串类型,这些转换也没有显式地在pg_cast中表示。 + 需要注意的是,pg_cast并不表示系统知道如何执行的所有类型转换,它只包括那些不能从某些通用规则推导出的转换。例如,一个域及其基础类型之间的转换并未显式地在pg_cast中展示。另一个重要的例外是自动的基于 I/O 的类型转换,它们通过数据类型自己的 I/O 函数来转换成(或者转换自)text或其他字符串类型,这些转换也没有显式地在pg_cast中表示。 @@ -1687,7 +1688,7 @@ SCRAM-SHA-256$<iteration count>:&l - 目录pg_class描述了具有列或与表类似的其他对象。这包括索引(但请参见pg_index)、序列(但请参见pg_sequence)、视图、物化视图、复合类型和TOAST表;请参见relkind。 + 目录pg_class描述了表以及其他具有列或在其他方面与表类似的对象。这包括索引(但请参见pg_index)、序列(但请参见pg_sequence)、视图、物化视图、复合类型和TOAST表;请参见relkind。 在下面,当我们指的是所有这些类型的对象时,我们称之为关系(relations)。并非所有pg_class的列对所有关系类型都有意义。 @@ -1739,9 +1740,7 @@ SCRAM-SHA-256$<iteration count>:&l reltype oid (引用 pg_type.oid) - - 该关系可能对应的表行类型的数据类型 OID;对索引为 0,而序列和 TOAST 表没有pg_type项 - + 与此表的行类型对应的数据类型的 OID(如有);索引、序列和 TOAST 表没有pg_type项,此值为零 @@ -1769,9 +1768,7 @@ SCRAM-SHA-256$<iteration count>:&l relam oid (引用 pg_am.oid) - - 用于访问该表或索引的访问方法。如果该关系是序列或者没有磁盘文件,则此字段无意义;分区表除外,对于分区表,如果设置了该字段,则在创建命令未指定时,它优先于 default_table_access_method 来决定用于创建分区的访问方法。 - + 如果这是表或索引,则为使用的访问方法(堆、B-树、hash 等);否则为零(序列以及没有存储的关系,如视图,此值为零) @@ -1827,19 +1824,7 @@ SCRAM-SHA-256$<iteration count>:&l - - - relallfrozen int4 - - - 表的可见性映射中被标记为全冻结的页数。这只是一个用于触发自动清理的估计值。 - 它也可以与 relallvisible 一起,用于安排手工清理以及调优清理冻结行为。 - 它会被 - VACUUM、 - ANALYZE - 以及一些 DDL 命令(例如 CREATE INDEX)更新。 - - + @@ -1875,7 +1860,7 @@ SCRAM-SHA-256$<iteration count>:&l relpersistence char - p = 永久表/序列, u = 不记录 WAL 的表/序列, + p = 永久表/序列,u = 不记录 WAL 的表/序列, t = 临时表/序列 @@ -1970,7 +1955,7 @@ SCRAM-SHA-256$<iteration count>:&l relispopulated bool - 如果表已被填充则为真(对于所有关系该列都为真,但对于某些物化视图却不是) + 如果关系已被填充则为真(对于所有关系该列都为真,但对于某些物化视图却不是) @@ -2012,7 +1997,7 @@ SCRAM-SHA-256$<iteration count>:&l relfrozenxid xid - 在此之前的所有事务ID在表中已经被替换为一个永久的(冻结的) 事务ID。 + 在此之前的所有事务ID在表中已经被替换为一个永久的(冻结的)事务ID。 这用于跟踪表是否需要被清理,以便阻止事务ID回卷或者允许pg_xact被收缩。 如果该关系不是一个表则为0(InvalidTransactionId)。 @@ -2023,7 +2008,7 @@ SCRAM-SHA-256$<iteration count>:&l relminmxid xid - 在此之前的多事务ID在表中已经被替换为一个事务ID。这被用于跟踪表是否需要被清理,以阻止 + 在此之前的所有多事务ID在表中已经被替换为一个事务ID。这被用于跟踪表是否需要被清理,以阻止 多事务ID回卷或者允许pg_multixact被收缩。如果关系不是一个表则 为0(InvalidMultiXactId)。 @@ -2052,7 +2037,7 @@ SCRAM-SHA-256$<iteration count>:&l relpartbound pg_node_tree - 如果表示一个分区(见relispartition),则为分区边界的内部表示 + 如果表是一个分区(见relispartition),则为分区边界的内部表示 @@ -2060,9 +2045,9 @@ SCRAM-SHA-256$<iteration count>:&l
- pg_class中的一些逻辑标志被以一种懒惰的方式维护:在正确状态时它们被保证为真,但是当条件不再为真时它们并不会被立刻重置为假。 + pg_class中的一些布尔标志采用延迟维护:当条件成立时,保证它们为真;但当条件不再成立时,可能不会立即将它们重置为假。 例如,relhasindexCREATE INDEX设置,但它从不会被DROP INDEX清除。 - 作为替代,VACUUM会在找到无索引表后清除其relhasindex。 + 作为替代,VACUUM会在找到无索引表后清除其relhasindex。 这种安排避免了竞争条件并且提高了并发性。 @@ -2136,9 +2121,10 @@ SCRAM-SHA-256$<iteration count>:&l collprovider char - 排序规则提供者:d = 数据库默认值, - b = builtin,c = libc, - i = icu + 排序规则提供程序:d = 数据库默认值, +c = libc, + i = icu + @@ -2164,8 +2150,7 @@ SCRAM-SHA-256$<iteration count>:&l collcollate text - 此排序规则对象的 LC_COLLATE。如果提供者不是 libc,则 collcollate 为 - NULL,改用 colllocale。 + 此排序规则对象的 LC_COLLATE @@ -2174,20 +2159,16 @@ SCRAM-SHA-256$<iteration count>:&l collctype text - 此排序规则对象的 LC_CTYPE。如果提供者不是 libc,则 collctype 为 - NULL,改用 colllocale。 + 此排序规则对象的 LC_CTYPE - colllocale text + colliculocale text - 此排序规则对象的提供者区域设置名称。如果提供者是 libc, - 则 colllocaleNULL; - 改用 collcollate 和 - collctype。 + 此排序规则对象的 ICU 区域设置 ID @@ -2205,7 +2186,7 @@ SCRAM-SHA-256$<iteration count>:&l collversion text - 排序规则的提供者相关的版本。这是在排序规则创建时记录下来的,并且在使用排序规则时会被检查以检测可能导致数据损坏的排序规则定义的改变。 + 提供程序特有的排序规则版本。它会在创建排序规则时记录下来,并在使用时接受检查,以检测可能导致数据损坏的排序规则定义更改。 @@ -2231,8 +2212,9 @@ SCRAM-SHA-256$<iteration count>:&l - 目录pg_constraint存储表上的检查约束、非空约束、主键约束、唯一约束、外键约束和排他约束。 + 目录pg_constraint存储表上的检查约束、主键约束、唯一约束、外键约束和排他约束。 (列约束不会被特殊对待。每一个列约束都等价于某种表约束。) + 非空约束在pg_attribute目录中表示,而不是在这里。 @@ -2293,7 +2275,6 @@ SCRAM-SHA-256$<iteration count>:&l c = 检查约束, f = 外键约束, - n = 非空约束, p = 主键约束, u = 唯一约束, t = 约束触发器, @@ -2319,15 +2300,6 @@ SCRAM-SHA-256$<iteration count>:&l - - - conenforced bool - - - 该约束是否会被强制执行? - - - convalidated bool @@ -2454,17 +2426,6 @@ SCRAM-SHA-256$<iteration count>:&l - - - conperiod bool - - - 如果该约束被定义为 WITHOUT OVERLAPS - (主键或唯一约束)或 PERIOD - (外键),则为真。 - - - conkey int2[] @@ -2532,10 +2493,7 @@ SCRAM-SHA-256$<iteration count>:&l conexclop oid[] (引用 pg_operator.oid - - 如果是排他约束或 WITHOUT OVERLAPS - 主键/唯一约束,则这里列出每列的排他操作符。 - + 如果是排他约束,则列出每列的排他操作符 @@ -2551,9 +2509,9 @@ SCRAM-SHA-256$<iteration count>:&l - 在一个排他约束的情况中, conkey只对约束元素是单一列引用时有用。 - 对于其他情况,conkey为0且必须查阅相关索引来发现被约束的表达式。 - (对于索引,conkey因此和pg_index.indkey具有相同的内容)。 + 对于排他约束,conkey仅对作为简单列引用的约束元素有用。 + 对于其他情况,conkey中会出现一个 0,必须查阅关联索引来确定被约束的表达式。 + (因此,conkey与该索引的 pg_index.indkey具有相同的内容。) @@ -2747,8 +2705,8 @@ SCRAM-SHA-256$<iteration count>:&l datlocprovider char - 此数据库的区域设置提供者:b = builtin, - c = libc,i = icu + 此数据库的区域设置提供程序:c = libc,i = icu + @@ -2770,17 +2728,7 @@ SCRAM-SHA-256$<iteration count>:&l - - - dathasloginevt bool - - - 如果此数据库定义了登录事件触发器,则为真。 - 使用这个标志是为了避免每个后端启动时都额外查看 - pg_event_trigger。 - 该标志仅供 PostgreSQL 内部使用,不应为了监控目的手工修改或读取。 - - + @@ -2844,13 +2792,10 @@ SCRAM-SHA-256$<iteration count>:&l - datlocale text + daticulocale text - 此数据库的提供者区域设置名称。如果提供者是 libc, - 则 datlocaleNULL; - 改用 datcollate 和 - datctype。 + 此数据库的 ICU 区域设置 ID @@ -2868,7 +2813,7 @@ SCRAM-SHA-256$<iteration count>:&l datcollversion text - 该排序规则的提供者特定版本。它会在创建数据库时记录下来,并在使用时接受检查,以检测可能导致数据损坏的排序规则定义更改。 + 提供程序特有的排序规则版本。它会在创建数据库时记录下来,并在使用时接受检查,以检测可能导致数据损坏的排序规则定义更改。 @@ -3950,7 +3895,7 @@ SCRAM-SHA-256$<iteration count>:&l indisunique bool - 如为真, 这是唯一索引 + 如为真, 这是唯一索引 @@ -3959,8 +3904,8 @@ SCRAM-SHA-256$<iteration count>:&l indnullsnotdistinct bool - 该值只用于唯一索引。如果为 false,则该唯一索引会将 null 值视为非重复值(因此索引中可以包含多个 null 值,这是 PostgreSQL 的默认行为)。 - 如果为 true,则会将 null 值视为相等(因此索引中只能包含一个 null 值)。 + 该值只用于唯一索引。如果为 false,则该唯一索引会将 null 值视为彼此不同(因此索引的某一列中可以包含多个 null 值,这是 PostgreSQL 的默认行为)。 + 如果为 true,则会将 null 值视为相等(因此索引的某一列中只能包含一个 null 值)。 @@ -4068,7 +4013,7 @@ SCRAM-SHA-256$<iteration count>:&l (引用 pg_collation.oid - 对于索引键(indnkeyatts值)中的每一列,这包含要用于该索引的排序规则的OID,如果该列不是一种可排序数据类型则为零。 + 对于索引键(indnkeyatts值)中的每一列,这包含要用于该索引的排序规则的OID,如果该列的数据类型不支持排序规则则为零。 @@ -5140,7 +5085,7 @@ SCRAM-SHA-256$<iteration count>:&l (引用 pg_collation.oid - 对于分区键中的每一个列,这个域包含要用于分区的排序规则的OID,如果该列不是一种可排序数据类型则为零。 + 对于分区键中的每一个列,这个域包含要用于分区的排序规则的OID,如果该列的数据类型不支持排序规则则为零。 @@ -5729,16 +5674,7 @@ SCRAM-SHA-256$<iteration count>:&l - - - pubgencols char - - - 控制在没有发布列列表时如何处理生成列复制: - n = 不复制与该发布关联表中的生成列, - s = 复制与该发布关联表中的存储式生成列。 - - + @@ -5982,7 +5918,11 @@ SCRAM-SHA-256$<iteration count>:&l - rngsubopc (加上rngcollation,如果元素类型是可排序的)决定了被该范围类型所使用的排序顺序。rngcanonical用于离散类型的元素类型。rngsubdiff是可选的,但是提供它可以提高范围类型上的GiST索引性能。 + rngsubopc(如果元素类型支持排序规则,则还包括 + rngcollation)决定范围类型所用的排序顺序。 + rngcanonical用于元素类型为离散类型的情况。 + rngsubdiff是可选的,但应当提供它, + 以提高范围类型上的 GiST 索引性能。 @@ -6670,8 +6610,8 @@ SCRAM-SHA-256$<iteration count>:&l 通常,每个已分析的表列都有一个条目,其中stainherit = false。 - 如果表具有继承子项或分区,则还会创建第二个条目,其中stainherit = true。 - 此行表示继承树上列的统计信息,即您可以通过SELECT column FROM table*看到的数据的统计信息, + 如果表具有继承子表或分区,则还会创建第二个条目,其中stainherit = true。 + 此行表示继承树上列的统计信息,即你可以通过SELECT column FROM table*看到的数据的统计信息, 而stainherit = false行表示SELECT column FROM ONLY table的结果。 @@ -6680,7 +6620,7 @@ SCRAM-SHA-256$<iteration count>:&l - 因为不同类型的统计信息适用于不同类型的数据, pg_statistic 被设计成不太在意自己存储的是什么类型的统计。 只有极为常用的统计信息(比如NULL的含量)才在pg_statistic里给予专用的字段。 其它所有东西都存储在槽位中,而槽位是一组相关的列, 它们的内容用槽位中的一个列里的代码表示。 更详细的信息请参阅 src/include/catalog/pg_statistic.h。 + 由于不同种类的数据可能适合不同种类的统计信息,pg_statistic 在设计上尽量不对所存储的统计信息种类作出假定。只有极为通用的统计信息(例如空值情况)才在 pg_statistic 中有专用的列。其余统计信息都存储在槽位中。每个槽位都是一组相关的列,其内容由其中一列的代码编号来标识。更多信息见 src/include/catalog/pg_statistic.h @@ -6736,7 +6676,7 @@ SCRAM-SHA-256$<iteration count>:&l stanullfrac float4 - 列的项为空的比例 + 列中空值所占的比例 @@ -6754,8 +6694,8 @@ SCRAM-SHA-256$<iteration count>:&l stadistinct float4 - 列中非空唯一值的数目。一个大于零的值是唯一值的真正数目。 - 一个小于零的值是表中行数的乘数的负值;例如,对于一个 80% 的值为非空且每个非空值平均出现两次的列,可以表示为stadistinct = -0.4。一个0值表示唯一值的数目未知。 + 列中不同非空数据值的数量。一个大于零的值是不同值的真正数目。 + 一个小于零的值是表中行数的乘数的负值;例如,对于一个约 80% 的值为非空且每个非空值平均出现两次的列,可以表示为stadistinct = -0.4。一个0值表示不同值的数目未知。 @@ -6786,8 +6726,8 @@ SCRAM-SHA-256$<iteration count>:&l (引用 pg_collation.oid - 用于导出存储在第N槽位中的统计信息的排序规则。 - 例如,可应用排序规则列的直方图槽会显示定义数据排序顺序的排序规则。对于不可应用排序规则的数据,则为零。 + 用于生成存储在第N槽位中的统计信息的排序规则。 + 例如,支持排序规则的列的直方图槽会显示定义数据排序顺序的排序规则。对于不支持排序规则的数据,则为零。 @@ -6796,7 +6736,7 @@ SCRAM-SHA-256$<iteration count>:&l stanumbersN float4[] - 第N槽位的类型的数值类型统计, 如果该槽位不涉及数值类型则为NULL + 第N槽位中相应种类的数值统计信息;如果该槽位种类不涉及数值,则为 NULL @@ -6806,7 +6746,7 @@ SCRAM-SHA-256$<iteration count>:&l N槽位的类型的列值,如果该槽位类型不存储任何数据值则为 NULL。 - 每个数组的元素值实际上都是指定列的数据类型或者是一个相关类型(如数组元素类型), 因此,除了把这些列的类型定义成anyarray之外别无他法。 + 每个数组的元素值实际上都是指定列的数据类型或者是一个相关类型(如数组元素类型), 因此,无法把这些列的类型定义得比anyarray更具体。 @@ -6892,24 +6832,24 @@ SCRAM-SHA-256$<iteration count>:&l - stxkeys int2vector - (引用 pg_attribute.attnum) + stxstattarget int4 - 一个属性编号的数组,表示哪些表列被这个统计信息对象覆盖。例如值1 3表示第一个和第三个表列被覆盖 + stxstattarget 控制 + ANALYZE 为该统计信息对象收集统计信息时的细节级别。 + 零值表示不应收集统计信息。 + 负值表示使用被引用列的统计目标中的最大值(如果有设置),否则使用系统默认统计目标。 + 正值 stxstattarget 决定要收集的高频值目标个数。 - stxstattarget int2 + stxkeys int2vector + (引用 pg_attribute.attnum - stxstattarget 控制 - ANALYZE 为该统计信息对象收集统计信息时的细节级别。 - 零值表示不应收集统计信息。 - 空值表示使用被引用列的统计目标中的最大值(如果有设置),否则使用系统默认统计目标。 - 正值 stxstattarget 决定要收集的高频值目标个数。 + 一个属性编号的数组,表示哪些表列被这个统计信息对象覆盖。例如值1 3表示第一个和第三个表列被覆盖 @@ -6933,7 +6873,7 @@ SCRAM-SHA-256$<iteration count>:&l 统计信息对象属性中那些不是简单列引用的表达式树,以 nodeToString() 表示。 这是一个列表,每个表达式占一个元素。 - 如果所有统计信息对象属性都是简单引用,则为空。 + 如果所有统计信息对象属性都是简单引用,则为空值。 @@ -6942,8 +6882,8 @@ SCRAM-SHA-256$<iteration count>:&l - pg_statistic_ext条目在CREATE STATISTICS期间完全填充,但是随后不计算实际的统计值。 - 后来ANALYZE命令计算所需的值,并在pg_statistic_ext_data目录中填充条目。 + pg_statistic_ext条目在CREATE STATISTICS期间完全填充,但此时不会计算实际的统计值。 + 后续的ANALYZE命令计算所需的值,并在pg_statistic_ext_data目录中填充条目。 @@ -6960,14 +6900,7 @@ SCRAM-SHA-256$<iteration count>:&l - 通常,每个已分析的统计对象都有一个条目,其中stxdinherit = - false。如果表具有继承子项或分区,还会创建第二个条目,其中 - stxdinherit = true。此行表示继承树上的统计对象,即, - 您将看到的数据的统计信息 - SELECT * FROM table*, - 而stxdinherit = false行 - 表示 - SELECT * FROM ONLY table的结果。 + 通常,每个已分析的统计信息对象都有一个 stxdinherit = false 的条目。如果表有继承子表或分区,还会创建第二个 stxdinherit = true 的条目。后者表示该统计信息对象在整个继承树上的统计信息,即通过 SELECT * FROM table* 看到的数据的统计信息;而 stxdinherit = false 的行表示 SELECT * FROM ONLY table 的结果。 @@ -7037,7 +6970,7 @@ SCRAM-SHA-256$<iteration count>:&l stxdmcv pg_mcv_list - MCV(最频值)列表统计信息,序列化为pg_mcv_list类型 + MCV(高频值)列表统计信息,序列化为pg_mcv_list类型 @@ -7046,7 +6979,7 @@ SCRAM-SHA-256$<iteration count>:&l stxdexpr pg_statistic[] - 每个表达式的统计信息,序列化为pg_statistic类型的数组 + 每个表达式的统计信息,序列化为pg_statistic类型的数组。 @@ -7113,7 +7046,7 @@ SCRAM-SHA-256$<iteration count>:&l subskiplsn pg_lsn - 事务的完成LSN,其更改将被跳过,如果是有效LSN;否则0/0。 + 若为有效 LSN,则表示要跳过其更改的事务的完成 LSN;否则为 0/0 @@ -7161,7 +7094,7 @@ SCRAM-SHA-256$<iteration count>:&l 控制如何处理进行中事务的流式传输: f = 不允许对进行中事务进行流式传输, - t = 将进行中事务的更改溢写到磁盘,并在事务在发布者端提交且被订阅者接收后立即应用, + t = 将进行中事务的更改溢写到磁盘,并在事务在发布者端提交且被订阅者接收后一次性应用, p = 如果可用,则直接使用并行应用工作进程应用更改(如果没有工作进程,则与 t 相同) @@ -7205,15 +7138,6 @@ SCRAM-SHA-256$<iteration count>:&l - - - subfailover bool - - - 如果为真,则会启用上游数据库中的相关复制槽(即主复制槽和表同步复制槽),使其能够同步到备库 - - - subconninfo text @@ -7648,7 +7572,7 @@ SCRAM-SHA-256$<iteration count>:&l tgdeferrable bool - 如果约束触发器可推迟则为真 + 如果约束触发器可延迟则为真 @@ -7657,7 +7581,7 @@ SCRAM-SHA-256$<iteration count>:&l tginitdeferred bool - 如果约束触发器初始可推迟则为真 + 如果约束触发器初始处于延迟状态则为真 @@ -8193,7 +8117,7 @@ SCRAM-SHA-256$<iteration count>:&l 目录pg_type存储有关数据类型的信息。 - 基类型和枚举类型(标量类型)使用CREATE TYPE创建,而域使用CREATE DOMAIN创建。 + 基础类型和枚举类型(标量类型)使用CREATE TYPE创建,而域使用CREATE DOMAIN创建。 数据库中的每一个表都会有一个自动创建的复合类型,用于表示表的行结构。 也可以使用CREATE TYPE AS创建复合类型。 @@ -8279,7 +8203,7 @@ SCRAM-SHA-256$<iteration count>:&l typtype可以是: - b表示一个基类型, + b表示一个基础类型, c表示一个复合类型(例如一个表的行类型), d表示一个域, e表示一个枚举类型, @@ -8485,7 +8409,7 @@ SCRAM-SHA-256$<iteration count>:&l - e (外部的): 值可以存储在一个次要 TOAST 关系中 (如果有一个关系, 参见pg_class.reltoastrelid). + e (外部的): 值可以存储在一个次要 TOAST 关系中 (如果有一个关系, 参见pg_class.reltoastrelid). @@ -8528,7 +8452,7 @@ SCRAM-SHA-256$<iteration count>:&l typtypmod int4 - 域使用typtypmod来记录被应用于它们基类型的typmod(如果基类型不使用typmod,则为-1)。如果此类型不是一个域则为-1。 + 域使用typtypmod来记录被应用于它们基础类型的typmod(如果基础类型不使用typmod,则为-1)。如果此类型不是一个域则为-1。 @@ -8548,8 +8472,8 @@ SCRAM-SHA-256$<iteration count>:&l typcollation指定此类型的排序规则。如果类型不支持排序规则,此列为零。 - 支持排序规则的基类型在这里会有一个非零值,典型值为DEFAULT_COLLATION_OID。 - 基于可应用排序规则类型的域,如果为其指定了排序规则 OID,则它的排序规则 OID 可以不同于其基类型。 + 支持排序规则的基础类型在这里会有一个非零值,典型值为DEFAULT_COLLATION_OID。 + 基于支持排序规则的类型的域,如果为其指定了排序规则 OID,则它的排序规则 OID 可以不同于其基础类型的排序规则 OID。 diff --git a/zh/16/charset.sgml b/zh/16/charset.sgml index 089b63c5..8ce905d0 100644 --- a/zh/16/charset.sgml +++ b/zh/16/charset.sgml @@ -29,7 +29,7 @@ 区域设置支持 - locale + 区域设置 区域设置支持是指应用程序在字母表、排序、数字格式等 @@ -197,7 +197,7 @@ initdb --locale=sv_SE 以及 POSIX 风格正则表达式);区域设置既会影响大小写不敏感匹配,也会 影响字符类正则表达式中的字符分类 LIKE与区域设置 - regular expressions与区域设置 + 正则表达式与区域设置 @@ -289,12 +289,18 @@ initdb --locale=sv_SE 区域设置提供程序 - 区域设置提供程序指定由哪个库来定义排序规则和字符分类的区域设置行为。 + PostgreSQL支持多种区域设置提供程序, + 用于指定由哪个库提供区域设置数据。一种标准提供程序名是libc, + 它使用操作系统 C 库提供的区域设置;操作系统提供的大多数工具也使用这些区域设置。 + 另一种提供程序是icu,它使用外部 + ICUICU库。只有在构建 PostgreSQL 时 + 配置了 ICU 支持,才能使用 ICU 区域设置。 - 如上所述,用于选择区域设置的命令和工具都提供了选择区域设置提供程序的选 - 项。下面是一个使用 ICU 提供程序初始化数据库集簇的示例: + 如上所述,用于选择区域设置的命令和工具都提供了选择区域设置提供程序的选项。 + 前面的示例都使用默认的libc提供程序。下面是一个使用 ICU + 提供程序初始化数据库集簇的示例: initdb --locale-provider=icu --icu-locale=en @@ -305,81 +311,11 @@ initdb --locale-provider=icu --icu-locale=en - 无论使用哪种区域设置提供程序,操作系统仍会用于提供某些区域设置相关的行 - 为,例如消息(参见)。 + 选择哪种区域设置提供程序取决于具体需求。对于大多数基本用途,两种提供程序 + 都能给出足够好的结果。libc 提供程序的表现取决于操作系统提供的支持;不同 + 操作系统的支持程度有所不同。对于高级用途,ICU 提供了更多区域设置变体和 + 定制选项。 - - - 可用的区域设置提供程序如下: - - - - - builtin - - - builtin提供程序使用内置操作。此提供程序仅支持 - CC.UTF-8和 - PG_UNICODE_FAST区域设置。 - - - C区域设置的行为与 libc 提供程序中的 - C区域设置相同。使用该区域设置时,其行为可能取决于 - 数据库编码。 - - - C.UTF-8区域设置仅在数据库编码为 - UTF-8时可用,并且其行为基于 Unicode。排序规则仅使 - 用代码点值。正则表达式字符类基于“POSIX 兼容”语义,大小写映射使用 - “简单”变体。 - - - PG_UNICODE_FAST区域设置仅在数据库编码为 - UTF-8时可用,并且其行为基于 Unicode。排序规则仅使 - 用代码点值。正则表达式字符类基于“标准”语义,大小写映射使用“完整” - 变体。 - - - - - - icu - - - icu提供程序使用外部 - ICUICU库。 - PostgreSQL必须在构建时配置了 ICU 支持。 - - - ICU 提供与操作系统和数据库编码无关的排序与字符分类行为。如果你希望将 - 来迁移到其他平台而不改变结果,这通常更可取。LC_COLLATE - 和LC_CTYPE可以独立于 ICU 区域设置进行设置。 - - - - 对于 ICU 提供程序,结果可能取决于所使用的 ICU 库版本,因为该库会随 - 时间推移更新,以反映自然语言的变化。 - - - - - - - libc - - - libc提供程序使用操作系统的 C 库。排序与字符分类行 - 为由LC_COLLATELC_CTYPE设置控 - 制,因此它们不能独立设置。 - - - - 使用 libc 提供程序时,同一个区域设置名称在不同平台上可能表现不同。 - - - - - @@ -565,10 +501,10 @@ SELECT 'N-45' < 'N-123' COLLATE mycollation5 as result; 概念 - 从概念上讲,每个可排序数据类型的表达式都有一个排序规则。(内置的可排序 - 数据类型包括textvarcharchar。 - 用户定义的基本类型也可以标记为可排序,当然,建立在可排序数据类型之上的 - 也是可排序的。) + 从概念上讲,每个支持排序规则的数据类型的表达式都有一个排序规则。 + (内置的支持排序规则的数据类型包括textvarcharchar。 + 用户定义的基础类型也可以标记为支持排序规则,当然,建立在支持排序规则的数据类型之上的 + 也支持排序规则。) 如果表达式是列引用,则该表达式的排序规则就是该列定义的排序规则。如果表 达式是常量,则其排序规则就是该常量数据类型的默认排序规则。更复杂表达式 的排序规则则按下文所述,从其输入表达式的排序规则推导出来。 @@ -593,7 +529,7 @@ SELECT 'N-45' < 'N-123' COLLATE mycollation5 as result; 对于函数或操作符调用,通过检查参数排序规则推导出的排序规则,会在运行时 - 用于执行指定操作。如果该函数或操作符调用的结果属于可排序数据类型,那么 + 用于执行指定操作。如果该函数或操作符调用的结果属于支持排序规则的数据类型,那么 在解析时它也会被用作该函数或操作符表达式的已定义排序规则,以便在外围表 达式需要知道其排序规则时使用。 @@ -675,7 +611,7 @@ SELECT a || b FROM test1; - 如果函数或操作符返回的是可排序数据类型,那么分配给该函数或操作符组合输 + 如果函数或操作符返回的是支持排序规则的数据类型,那么分配给该函数或操作符组合输 入表达式的排序规则,也被认为适用于其结果。因此,在 SELECT * FROM test1 ORDER BY a || 'foo'; @@ -721,8 +657,7 @@ SELECT * FROM test1 ORDER BY a || b COLLATE "fr_FR"; - 由icu提供的排序规则对象,对应于 ICU 库提供的具名整 - 理器。ICU 不支持将collatectype分开设 + 由icu提供的排序规则对象,对应于 ICU 库提供的具名排序器。ICU 不支持将collatectype分开设 置,因此二者总是相同的。此外,ICU 排序规则与编码无关,因此在一个数据库 中,某个给定名称的 ICU 排序规则始终只有一个。 @@ -730,101 +665,42 @@ SELECT * FROM test1 ORDER BY a || b COLLATE "fr_FR"; 标准排序规则 - - 在所有平台上,都支持以下排序规则: - - - - unicode - - - 此 SQL 标准排序规则使用 Unicode 排序算法和默认 Unicode 排序元素表进 - 行排序。它在所有编码中都可用。 - 使用此排序规则需要 ICU 支持,并且如果 - PostgreSQL使用不同版本的 ICU 构建,其 - 行为可能会发生变化。(此排序规则与 ICU 根区域设置具有相同的行为;参 - 见。) - - - - - - ucs_basic - - - 此 SQL 标准排序规则使用 Unicode 代码点值而不是自然语言顺序进行排 - 序,并且只有 ASCII 字母A到 - Z会被视为字母。其行为高效且在所 - 有版本中都稳定。仅适用于UTF8编码。(此排序规则 - 与UTF8编码下 libc 区域设置规范C - 的行为相同。) - - - - - - pg_unicode_fast - - - 此排序规则按 Unicode 代码点值而不是自然语言顺序进行排序。对于 - lowerinitcap和 - upper函数,它使用 Unicode 完整大小写映射。对 - 于模式匹配(包括正则表达式),它使用 Unicode 兼容属性 - 的标准变体。其行为在 - Postgres主版本内高效且稳定。仅适用于 - UTF8编码。 - - - - - - pg_c_utf8 - - - 此排序规则按 Unicode 代码点值而不是自然语言顺序进行排序。对于 - lowerinitcap和 - upper函数,它使用 Unicode 简单大小写映射。对 - 于模式匹配(包括正则表达式),它使用 Unicode 兼容属性 - 的 POSIX 兼容变体。其行为在 - PostgreSQL主版本内高效且稳定。此排序规 - 则仅适用于UTF8编码。 - - - - - - C(等同于POSIX - - - CPOSIX排序规则基于 - 传统 C行为。它们按字节值而不是自然语言顺序排序,并且 - 只有 ASCII 字母A到 - Z会被视为字母。对于给定的数据库 - 编码,其行为高效且在所有版本中都稳定,但在不同数据库编码之间可能会 - 有所不同。 - - - - - - default - - - default排序规则会选择数据库创建时指定的区域设 - 置。 - - - - - + 所有平台都提供名为 defaultCPOSIX 的排序规则。根据操作系统支持情况,还可能提供其他排序规则。default 排序规则选择创建数据库时指定的 LC_COLLATELC_CTYPE 值。CPOSIX 排序规则都采用传统 C行为,仅将 ASCII 字母 AZ 视为字母,并严格按字符编码的字节值排序。 + - 根据操作系统支持情况,还可能存在其他排序规则。这些附加排序规则的效率和 - 稳定性取决于排序规则提供程序、提供程序版本以及区域设置。 + CPOSIX区域设置的行为可能因数据库编码而异。 - + + + + 此外,还可以使用两个 SQL 标准排序规则名: + + + + unicode + + + 此排序规则使用 Unicode 排序算法和默认 Unicode 排序元素表进行排序。 + 它在所有编码中都可用。使用此排序规则需要 ICU 支持。 + (此排序规则与 ICU 根区域设置具有相同的行为;参见 + 。) + + + + + ucs_basic + + + 此排序规则按 Unicode 代码点排序。仅适用于UTF8编码。 + (此排序规则与UTF8编码下 libc 区域设置规范 + C的行为相同。) + + + + + + 预定义排序规则 @@ -1050,7 +926,7 @@ CREATE COLLATION ignore_accents (provider = icu, locale = 'und-u-ks-level1-kc-tr 定性的。虽然非确定性排序规则提供了更正确的行为,尤其是 在考虑 Unicode 的全部能力及其众多特殊情况时,但它们也有一些缺点。首 先,使用它们会带来性能损失。特别要注意的是,B-树不能对使用非确定性排 - 序规则的索引使用去重。此外,某些操作(例如某些模式匹配操作)对非确定性 + 序规则的索引使用去重。此外,某些操作(例如模式匹配操作)对非确定性 排序规则来说是不可行的。因此,只有在确实需要时才应使用它们。 diff --git a/zh/16/client-auth.sgml b/zh/16/client-auth.sgml index 09abaafd..6b148092 100644 --- a/zh/16/client-auth.sgml +++ b/zh/16/client-auth.sgml @@ -67,7 +67,7 @@ - 一条记录可以有多种格式: + 一条记录可以有多种格式: local database user auth-method auth-options @@ -239,7 +239,7 @@ include_dir directory IP地址范围使用标准的数字表示法来指定起始地址,然后是斜杠(/)和一个CIDR掩码长度。 掩码长度表示客户端IP地址必须匹配的高位比特数。给定IP地址中右侧的比特应为零。 - IP地址、/和CIDR掩码长度之间不得有任何空格。 + IP地址、/和CIDR掩码长度之间不得有任何空白。 @@ -253,8 +253,7 @@ include_dir directory 以IPv4格式给出的条目将仅匹配IPv4连接,以IPv6格式给出的条目将仅匹配IPv6连接, - 即使所代表的地址在IPv4-in-IPv6范围内。请注意,如果系统的C库不支持IPv6地址, - 以IPv6格式给出的条目将被拒绝。 + 即使所代表的地址在IPv4-in-IPv6范围内。 @@ -276,12 +275,12 @@ include_dir directory 以点(.)开头的主机名规范匹配实际主机名的后缀。 因此,.example.com将匹配foo.example.com - (但不仅仅是example.com)。 + (但不匹配单独的example.com)。 当在pg_hba.conf中指定主机名时,应确保名称解析相对快速。 - 最好设置一个本地名称解析缓存,如nscd。 + 设置一个本地名称解析缓存可能会有帮助,如nscd。 此外,还可能希望启用配置参数log_hostname,以便在日志中看到客户端的主机名而不是 IP 地址。 @@ -293,7 +292,7 @@ include_dir directory 用户有时会想知道为什么主机名以这种看似复杂的方式处理,包括两次名称解析,其中包括对客户端IP地址的反向查找。 - 如果客户端的反向DNS条目未设置或生成了一些不良的主机名,则使用该功能会变得复杂。 + 如果客户端的反向DNS条目未设置或返回了不符合预期的主机名,则使用该功能会变得复杂。 这主要是为了效率:这样,连接尝试最多需要两次解析器查找,一次反向查找和一次正向查找。 如果某个地址存在解析器问题,那就只会成为该客户端的问题。 一个假设的替代实现只进行正向查找的情况下,在每次连接尝试期间都必须解析pg_hba.conf中提到的每个主机名。 @@ -308,7 +307,7 @@ include_dir directory 请注意,这种行为与其他流行的基于主机名的访问控制实现一致,例如 - Apache HTTP服务器和TCP包装器。 + Apache HTTP 服务器和 TCP Wrappers。 @@ -320,7 +319,7 @@ include_dir directory - 这两个字段可以用作IP地址/掩码长度 + 这两个字段可以用作IP-address/mask-length 表示法的替代方案。而不是指定掩码长度,实际掩码在一个单独的列中指定。 例如,255.0.0.0表示IPv4的CIDR掩码长度为8, 而255.255.255.255表示CIDR掩码长度为32。 @@ -378,11 +377,7 @@ include_dir directory 执行 SCRAM-SHA-256 或 MD5 认证以校验用户密码。详见 - - - 对 MD5 加密密码的支持已被弃用,并将在未来版本的 PostgreSQL 中移除。关于迁移到其他密码类型的细节,请参阅 。 - - + @@ -499,14 +494,7 @@ include_dir directory - - oauth - - - 使用第三方 OAuth 2.0 身份提供方进行授权,并可选地完成认证。详细信息请参见 。 - - - + @@ -516,11 +504,7 @@ include_dir directory auth-options - - - 在auth-method字段之后,可以是形如name=value的字段, - 用于指定认证方法的选项。关于哪些选项适用于哪些认证方法的详细信息见下文。 - + auth-method 字段之后,可以有一个或多个形如 name=value 的字段,用于指定认证方法的选项。下文会详细说明各认证方法有哪些可用选项。 除了下面列出的特定于方法的选项外,还有一个方法无关的认证选项 clientcert, @@ -533,7 +517,7 @@ include_dir directory - 对于任何使用客户端证书认证的记录(即使用 cert 认证方法的记录,或使用 clientcert 选项的记录),都可以通过 clientname 选项指定要匹配客户端证书凭据中的哪一部分。此选项有两个可选值。如果指定 clientname=CN,这也是默认值,则用户名将与证书的 Common Name (CN) 匹配。如果改为指定 clientname=DN,则用户名将与证书的完整 Distinguished Name (DN) 匹配。此选项通常最好与用户名映射配合使用。比较时使用的是 RFC 2253 格式的 DN。要查看以这种格式表示的客户端证书 DN,请执行 + 对于任何使用客户端证书认证的记录(即使用 cert 认证方法的记录,或使用 clientcert 选项的记录),都可以通过 clientname 选项指定要匹配客户端证书凭据中的哪一部分。此选项有两个可选值。如果指定 clientname=CN,这也是默认值,则用户名将与证书的 Common Name (CN) 匹配。如果改为指定 clientname=DN,则用户名将与证书的完整 Distinguished Name (DN) 匹配。此选项可能更适合与用户名映射配合使用。比较时使用的是 RFC 2253 格式的 DN。要查看以这种格式表示的客户端证书 DN,请执行 openssl x509 -in myclient.crt -noout -subject -nameopt RFC2253 | sed "s/^subject=//" @@ -575,19 +559,17 @@ openssl x509 -in myclient.crt -noout -subject -nameopt RFC2253 | sed "s/^subject 由 @ 构造引用的文件会被读取为名称列表,其中的名称可以用空白或逗号分隔。注释仍然用 # 引入,与 pg_hba.conf 中相同,并且允许嵌套的 @ 构造。除非 @ 后面的文件名是绝对路径,否则它会被视为相对于引用它的文件所在目录。 - - 因为每一次连接尝试都会顺序地检查pg_hba.conf记录,所以这些记录的顺序是非常关键的。通常,靠前的记录有比较严的连接匹配参数和比较弱的认证方法,而靠后的记录有比较松的匹配参数和比较强的认证方法。 例如,我们希望对本地 TCP/IP 连接使用trust认证,而对远程 TCP/IP 连接要求密码。在这种情况下为来自于 127.0.0.1 的连接指定trust认证的记录将出现在为一个更宽范围的客户端 IP 地址指定密码认证的记录前面。 - + 由于每次连接尝试都会按顺序检查 pg_hba.conf 记录,因此记录的顺序很重要。通常,靠前的记录使用较严格的连接匹配条件和较弱的认证方法,靠后的记录使用较宽松的匹配条件和较强的认证方法。例如,可能希望对本地 TCP/IP 连接使用 trust 认证,而要求远程 TCP/IP 连接提供密码。此时,为来自 127.0.0.1 的连接指定 trust 认证的记录,应放在为更大范围的允许客户端 IP 地址指定密码认证的记录之前。 - 在启动以及主服务器进程收到SIGHUPSIGHUP信号时,pg_hba.conf文件会被读取。 - 如果你在活动的系统上编辑了该文件,你将需要通知 postmaster(使用pg_ctl reload,调用SQL函数pg_reload_conf(),或使用kill -HUP)使其重新读取该文件。 + 在启动时以及主服务器进程收到 SIGHUPSIGHUP 信号时,pg_hba.conf 文件会被读取。 + 如果你在运行中的系统上编辑了该文件,就需要通知 postmaster(使用 pg_ctl reload、调用 SQL 函数 pg_reload_conf(),或者使用 kill -HUP)重新读取该文件。 - 前面的说明在Microsoft Windows上不为真:在Windows上,pg_hba.conf文件中的任何更改会立即被应用到后续的新连接上。 + 前面的说明不适用于 Microsoft Windows:在Windows上,pg_hba.conf文件中的任何更改会立即被应用到后续的新连接上。 @@ -602,9 +584,7 @@ openssl x509 -in myclient.crt -noout -subject -nameopt RFC2253 | sed "s/^subject - - 中展示了pg_hba.conf项的一些示例。不同认证方法的详情请见下一节。 - + 展示了一些 pg_hba.conf 条目示例。有关不同认证方法的详细信息,参见下一节。 @@ -612,8 +592,8 @@ openssl x509 -in myclient.crt -noout -subject -nameopt RFC2253 | sed "s/^subject # 允许本地系统上的任何用户 -# 通过 Unix 域套接字以任意 -# 数据库用户名连接到任意数据库(本地连接的默认值)。 +# 通过 Unix 域套接字(本地连接的默认方式)以任意 +# 数据库用户名连接到任意数据库。 # # TYPE DATABASE USER ADDRESS METHOD local all all trust @@ -658,7 +638,7 @@ host postgres all 192.168.93.0/24 ident # TYPE DATABASE USER ADDRESS METHOD host postgres all 192.168.12.10/32 scram-sha-256 -# 如果用户的密码被正确提供,允许 example.com 中主机上 +# 如果用户的密码被正确提供,允许 example.com 域中主机上 # 的任意用户连接到任意数据库。 # # 为大部分用户要求SCRAM认证,但是用户'mike'是个例外, @@ -669,7 +649,7 @@ host all mike .example.com md5 host all all .example.com scram-sha-256 # 如果没有前面的 "host" 行,这三行 -# 将拒绝所有来自 192.168.54.1的连接(因为那些项将首先被匹配), +# 将拒绝所有来自 192.168.54.1的连接(因为该条目将首先被匹配), # 但是允许来自互联网其他任何地方的 # GSSAPI 加密连接。零掩码表示不会考虑主机 IP 地址中的任何位, # 因此它会匹配任意主机。未加密的 GSSAPI 连接 @@ -684,7 +664,7 @@ host all all 192.168.12.10/32 gss # 允许来自 192.168.x.x 主机的用户连接到任意数据库,如果它们能够 # 通过 ident 检查。例如,假设 ident说用户是 "bryanh" 并且他要求以 # PostgreSQL 用户 "guest1" 连接,如果在 pg_ident.conf 有一个映射 -# "omicron" 的选项说 "bryanh" 被允许以 "guest1" 连接,则该连接将被允许。 +# "omicron" 的条目表明 "bryanh" 被允许以 "guest1" 连接,则该连接将被允许。 # # TYPE DATABASE USER ADDRESS METHOD host all all 192.168.0.0/16 ident map=omicron @@ -696,16 +676,16 @@ host all all 192.168.0.0/16 ident map=omicro # 管理员名字的列表。在所有情况下都要求密码。 # # TYPE DATABASE USER ADDRESS METHOD -local sameuser all scram-sha-256 -local all /^.*helpdesk$ scram-sha-256 -local all @admins scram-sha-256 -local all +support scram-sha-256 +local sameuser all md5 +local all /^.*helpdesk$ md5 +local all @admins md5 +local all +support md5 # 上面的最后两行可以被整合为一行: -local all @admins,+support scram-sha-256 +local all @admins,+support md5 # 数据库列也可以用列表和文件名: -local db1,db2,@demodbs all scram-sha-256 +local db1,db2,@demodbs all md5 @@ -870,16 +850,12 @@ omicron bryanh guest1 BSD 认证,依赖于 BSD 认证框架(目前仅在 OpenBSD 上可用)。 - - - OAuth 授权/认证,依赖于外部 OAuth 2.0 身份提供方。 - - + - Peer 认证通常适用于本地连接,不过在某些情况下,信任认证也可能已经足够。 + 通常建议对本地连接使用 Peer 认证,不过在某些情况下,信任认证也可能已经足够。 密码认证是远程连接最容易采用的选择。 其余所有选项都需要某种外部安全基础设施(通常是认证服务器,或用于签发 SSL 证书的证书颁发机构),或者属于平台特定功能。 @@ -898,16 +874,14 @@ omicron bryanh guest1 - trust认证对于单用户工作站的本地连接是非常合适和方便的。通常它本身适用于一台多用户机器。不过,只要你利用文件系统权限限制了对服务器的 Unix 域套接字文件的访问,即使在多用户机器上,你也可以使用trust。 要做这些限制,你可以设置中描述的unix_socket_permissions配置参数(可能还有unix_socket_group)。 或者你可以设置unix_socket_directories配置参数来把 Unix 域套接字文件放在一个经过恰当限制的目录中。 + trust认证对于单用户工作站的本地连接是非常合适和方便的。通常它本身适用于一台多用户机器。不过,只要你利用文件系统权限限制了对服务器的 Unix 域套接字文件的访问,即使在多用户机器上,你也可能可以使用trust。 要做这些限制,你可以设置中描述的unix_socket_permissions配置参数(可能还有unix_socket_group)。 或者你可以设置unix_socket_directories配置参数来把 Unix 域套接字文件放在一个经过恰当限制的目录中。 设置文件系统权限只能有助于 Unix 套接字连接。本地 TCP/IP 连接不会被文件系统权限限制。因此,如果你想利用文件系统权限来控制本地安全,那么从pg_hba.conf中移除host ... 127.0.0.1 ...行,或者把它改为一个非trust认证方法。 - - 如果通过指定trustpg_hba.conf行让你信任每一个被允许连接到服务器的机器上的用户,trust认证只适合 TCP/IP 连接。为任何不是来自localhost(127.0.0.1)的 TCP/IP 连接使用trust很少是合理的。 - + 只有当你信任由 pg_hba.conf 中指定 trust 的行所允许连接的每台机器上的每个用户时,trust 认证才适合用于 TCP/IP 连接。对来自 localhost(127.0.0.1)以外的任何 TCP/IP 连接使用 trust,通常都不合理。 @@ -952,18 +926,14 @@ omicron bryanh guest1 md5 - - 方法md5使用一种自定义的安全性较低的挑战-响应机制。它能防止密码嗅探并且防止密码在服务器上以明文存储,但是无法保护攻击者想办法从服务器上窃取了密码哈希的情况。此外,现在认为MD5哈希算法对于确定攻击已经不再安全。 - + 方法md5使用一种自定义的、安全性较低的挑战-响应机制。它能防止密码嗅探,并避免在服务器上以明文存储密码;但如果攻击者设法从服务器上窃取了密码哈希,它就无法提供保护。此外,如今已不再认为 MD5 哈希算法能抵御有决心的攻击者。 + + md5方法不能与功能一起使用。 为了简化从md5方法到较新的SCRAM方法的转变,如果在pg_hba.conf中指定了md5但是用户在服务器上的密码是为SCRAM(见下文)加密的,则将自动选择基于SCRAM的认证。 - - - 对 MD5 加密密码的支持已被弃用,并将在未来版本的 PostgreSQL 中移除。关于迁移到其他密码类型的细节,请参阅下文。 - - + @@ -987,7 +957,7 @@ omicron bryanh guest1 - 要把现有安装从 md5 升级到 scram-sha-256,需要先确保所有正在使用的客户端库都足够新并支持 SCRAM,然后在 postgresql.conf 中设置 password_encryption = 'scram-sha-256',要求所有用户重新设置密码,并将 pg_hba.conf 中的认证方法说明改为 scram-sha-256。 + 要把现有安装从 md5 升级到 scram-sha-256,需要先确保所有正在使用的客户端库都足够新并支持 SCRAM,然后在 postgresql.conf 中设置 password_encryption = 'scram-sha-256',要求所有用户重新设置密码,并将 pg_hba.conf 中的认证方法设置改为 scram-sha-256 @@ -1051,7 +1021,7 @@ omicron bryanh guest1 keytab 文件用 Kerberos 软件生成;详见 Kerberos 文档。 - 下面展示了用 MIT 兼容的 Kerberos 5 实现的kadmin来做这个的示例: + 下面的示例展示了如何使用 MIT Kerberos 的 kadmin 工具生成该文件: kadmin% addprinc -randkey postgres/server.my.domain.org kadmin% ktadd -k krb5.keytab postgres/server.my.domain.org @@ -1129,7 +1099,9 @@ omicron bryanh guest1 include_realm - 如果设为 0,则在通过用户名映射()之前,会先从已认证用户的主体名中去掉 realm 名称。不建议这样做;它主要是为了向后兼容而保留的,因为在多 realm 环境中这并不安全,除非同时使用了 krb_realm。建议将 include_realm 保持为默认值(1),并在 pg_ident.conf 中提供显式映射,把主体名转换成 PostgreSQL 用户名。 + 如果设为 0,则在通过用户名映射()之前,会先从已认证用户的主体名中去掉 realm 名称。 + 不建议这样做;它主要是为了向后兼容而保留的,因为在多 realm 环境中这并不安全,除非同时使用了 krb_realm。 + 建议将 include_realm 保持为默认值(1),并在 pg_ident.conf 中提供显式映射,把主体名转换成 PostgreSQL 用户名。 @@ -1141,7 +1113,7 @@ omicron bryanh guest1 如果设为 1,则会在 include_realm 选项中使用域的 SAM 兼容名称(也称为 NetBIOS 名称)。这是默认值。如果设为 0,则会使用 Kerberos 用户主体名中的真实 realm 名称。 - 不要禁用这个选项,除非你的服务器运行在一个域账号(这包括一个域成员系统上的虚拟服务账号)下并且所有通过 SSPI 认证的所有客户端也在使用域账号,否则认证将会失败。 + 不要禁用这个选项,除非你的服务器运行在一个域账号(这包括一个域成员系统上的虚拟服务账号)下并且所有通过 SSPI 认证的客户端也在使用域账号,否则认证将会失败。 @@ -1206,7 +1178,7 @@ omicron bryanh guest1 map - 允许在系统用户和数据库用户名称之间进行映射。详细信息请参见。 + 允许在系统用户名和数据库用户名之间进行映射。详见 @@ -1229,7 +1201,7 @@ omicron bryanh guest1
RFC 1413 - 标识协议的本意不是作为一种认证或访问控制协议。 + 标识协议的本意不是作为一种授权或访问控制协议。
@@ -1258,7 +1230,7 @@ omicron bryanh guest1 map - 允许在系统用户和数据库用户名称之间进行映射。详细信息请参见。 + 允许在系统用户名和数据库用户名之间进行映射。详见 @@ -1288,7 +1260,7 @@ omicron bryanh guest1 - 第二种模式称为搜索+绑定模式,服务器首先使用由 ldapbinddnldapbindpasswd 指定的固定用户名和密码绑定到 LDAP 目录,并搜索试图登录数据库的用户。如果没有配置用户名和密码,则会尝试对目录进行匿名绑定。搜索会在 ldapbasedn 指定的子树上进行,并尝试对 ldapsearchattribute 指定的属性做精确匹配。一旦在搜索中找到了该用户,服务器就会作为该用户重新绑定到目录,并使用客户端指定的密码来验证登录是否正确。这种模式与 Apache mod_authnz_ldappam_ldap 等软件中的 LDAP 认证方案相同。这种方法使目录中用户对象的位置更具灵活性,但会对 LDAP 服务器额外发起两次请求。 + 第二种模式称为搜索+绑定模式,服务器首先使用由 ldapbinddnldapbindpasswd 指定的固定用户名和密码绑定到 LDAP 目录,并搜索试图登录数据库的用户。如果没有配置用户名和密码,则会尝试对目录进行匿名绑定。搜索会在 ldapbasedn 指定的子树上进行,并尝试对 ldapsearchattribute 指定的属性做精确匹配。一旦在搜索中找到了该用户,服务器会断开连接,再作为该用户重新绑定到目录,并使用客户端指定的密码来验证登录是否正确。这种模式与 Apache mod_authnz_ldappam_ldap 等软件中的 LDAP 认证方案相同。这种方法使目录中用户对象的位置更具灵活性,但会与 LDAP 服务器建立两个独立的连接。 @@ -1314,8 +1286,7 @@ omicron bryanh guest1 ldapscheme - 设置为ldaps以使用LDAPS。这是一种非标准的使用LDAP - 进行SSL加密的方式,受一些LDAP服务器实现支持。另请参阅ldaptls + 设置为ldaps以使用LDAPS。这是一种非标准的通过 SSL 使用 LDAP 的方式,受一些LDAP服务器实现支持。另请参阅ldaptls 选项作为替代。 @@ -1408,16 +1379,14 @@ omicron bryanh guest1 一个RFC 4516 - LDAP URL。这是以更紧凑和标准形式编写其他LDAP选项的替代方式。格式为 + LDAP URL。这是以更紧凑和标准形式编写部分其他 LDAP 选项的替代方式。格式为 ldap[s]://host[:port]/basedn[?[attribute][?[scope][?[filter]]]] scope必须是baseonesub中的一个,通常是最后一个。(默认为base,在此应用中通常无用。)attribute可以指定单个属性,此时将用作ldapsearchattribute的值。如果attribute为空,则filter可用作ldapsearchfilter的值。 - - URL方案ldaps选择了通过SSL进行LDAP连接的LDAPS方法,相当于使用ldapscheme=ldaps。要使用StartTLS操作进行加密LDAP连接,请使用正常的URL方案ldap并另外指定ldaptls选项。 - + URL 方案 ldaps 会选择 LDAPS 方法,通过 SSL 建立 LDAP 连接,等同于使用 ldapscheme=ldaps。要通过 StartTLS 操作使用加密的 LDAP 连接,请使用普通的 URL 方案 ldap,并在 ldapurl 之外指定 ldaptls 选项。 对于非匿名绑定,必须将ldapbinddnldapbindpasswd指定为单独的选项。 @@ -1432,7 +1401,7 @@ ldap[s]://host[:port]/ - 将简单绑定选项与搜索+绑定选项混用是错误的。若要在简单绑定模式下使用 ldapurl,该 URL 中不能包含 basedn 或查询元素。 + 将简单绑定模式的配置选项与搜索+绑定模式的配置选项混用是错误的。 @@ -1451,21 +1420,9 @@ host ... ldap ldapserver=ldap.example.net ldapprefix="cn=" ldapsuffix=", dc=exam 当请求以数据库用户 someuser 连接数据库服务器时,PostgreSQL 将尝试使用 DN cn=someuser, dc=example, dc=net 和客户端提供的密码绑定到 LDAP 服务器。如果该连接成功,数据库访问就会被授予。 - - 下面是另一种简单绑定配置,它使用 LDAPS 方案和自定义端口号,并以 URL 形式写出: - -host ... ldap ldapurl="ldaps://ldap.example.net:49151" ldapprefix="cn=" ldapsuffix=", dc=example, dc=net" - - 这种写法比单独指定 ldapserverldapschemeldapport 稍微更紧凑。 - - - - 下面是一个搜索+绑定配置示例: - + 下面是搜索加绑定配置的示例: host ... ldap ldapserver=ldap.example.net ldapbasedn="dc=example, dc=net" ldapsearchattribute=uid - - 当请求以数据库用户 someuser 连接数据库服务器时,PostgreSQL 将尝试对 LDAP 服务器进行匿名绑定(因为未指定 ldapbinddn),并在指定的基础 DN 下执行一次 (uid=someuser) 搜索。如果找到了对应条目,随后就会尝试使用该条目的信息以及客户端提供的密码进行绑定。如果第二次绑定成功,数据库访问就会被授予。 - +当请求以数据库用户 someuser 的身份连接数据库服务器时,PostgreSQL 会尝试匿名绑定到 LDAP 服务器(因为没有指定 ldapbinddn),并在指定的基础 DN 下搜索 (uid=someuser)。如果找到了条目,就会尝试使用找到的信息和客户端提供的密码进行绑定。如果第二次连接成功,就会授予数据库访问权限。 下面是以 URL 形式写出的同一个搜索+绑定配置: @@ -1679,172 +1636,7 @@ host ... radius radiusservers="server1,server2" radiussecrets="""secret one"","" - - OAuth 授权/认证 - - - OAuth 授权/认证 - - - - OAuth 2.0 是一个行业标准框架,定义见 - RFC 6749, - 它允许第三方应用获得对受保护资源的受限访问。 - - 在构建 PostgreSQL 时必须启用 OAuth 客户端支持; - 详见 。 - - - - 本文档在讨论 OAuth 生态系统时使用下列术语: - - - - - 资源所有者(或终端用户) - - - 拥有受保护资源并能够授予访问权限的用户或系统。当资源所有者是人时,本文档也使用终端用户一词。当你使用 psql 通过 OAuth 连接数据库时,你就是资源所有者/终端用户。 - - - - - - 客户端 - - - 使用访问令牌访问受保护资源的系统。使用 libpq 的应用(例如 psql)在连接 PostgreSQL 集簇时,就是 OAuth 客户端。 - - - - - - 资源服务器 - - - 托管受保护资源并供客户端访问的系统。被连接的 PostgreSQL 集簇就是资源服务器。 - - - - - - 提供方 - - - 为某个应用开发和/或管理 OAuth 授权服务器与客户端的组织、产品供应商或其他实体。不同提供方通常会为各自的 OAuth 系统选择不同的实现细节;一个提供方的客户端通常并不能保证可以访问另一提供方的服务器。 - - - 这里对“提供方”一词的使用并非标准术语,但在口语中似乎很常见。(不要将它与 OpenID 中相近的术语“Identity Provider”混淆。虽然 PostgreSQL 中的 OAuth 实现旨在与 OpenID Connect/OIDC 互操作并保持兼容,但它本身并不是 OIDC 客户端,也不要求必须使用 OIDC。) - - - - - - 授权服务器 - - - 在资源所有者完成认证并给出批准之后,接收客户端请求并向其发放访问令牌的系统。PostgreSQL 不提供授权服务器;这属于 OAuth 提供方的职责。 - - - - - - 签发者 - - - 授权服务器的一个标识符,以 https:// URL 形式出现,为 OAuth 客户端和应用提供一个可信的“命名空间”。签发者标识符使得单个授权服务器能够同时与彼此互不信任实体的客户端通信,只要这些实体维护各自独立的签发者即可。 - - - - - - - - - 对于小型部署来说,“提供方”、“授权服务器”和“签发者”之间可能并没有有意义的区别。然而在更复杂的部署中,它们之间可能是一个对多个(甚至多个对多个)的关系:某个提供方可能把多个签发者标识符租给不同租户,然后再提供多个授权服务器与其客户端交互,而这些授权服务器支持的特性集合也可能各不相同。 - - - - - - PostgreSQL 支持在 - RFC 6750 - 中定义的 Bearer 令牌,这是一类用于 OAuth 2.0 的访问令牌,其本体是一个不透明字符串。访问令牌的格式取决于具体实现,由各个授权服务器自行决定。 - - - OAuth 支持下列配置选项: - - - issuer - - - 一个 HTTPS URL,它要么是授权服务器发现文档所定义的精确 - 签发者标识符, - 要么是一个直接指向该发现文档的众所周知 URI。此参数为必需项。 - - - 当 OAuth 客户端连接到服务器时,会基于签发者标识符构造发现文档的 URL。默认情况下,该 URL 采用 OpenID Connect Discovery 的约定:会在签发者标识符末尾追加路径 /.well-known/openid-configuration。另一种情况是,如果 issuer 本身包含 /.well-known/ 路径段,那么该 URL 会原样提供给客户端。 - - - - libpq 中的 OAuth 客户端要求服务器的 issuer 设置必须与发现文档中提供的签发者标识符完全一致,而该标识符又必须与客户端的 设置完全一致。不允许大小写或格式上的任何差异。 - - - - - - - scope - - - 一个以空格分隔的 OAuth scope 列表,服务器需要借此既能授权客户端,又能认证用户。合适的取值由授权服务器以及所使用的 OAuth 验证模块决定。此参数为必需项。 - - - - - - validator - - - 用于验证 Bearer 令牌的库。如果指定,其名称必须与服务器允许的某个验证库完全匹配。除非 oauth_validator_libraries 中包含多个库,否则该参数是可选的;如果包含多个库,则该参数为必需项。 - - - - - - map - - - 允许在 OAuth 身份提供方用户名和数据库用户名之间建立映射。详见 。如果未指定映射,则与令牌关联的用户名(由 OAuth 验证器决定)必须与请求的角色名完全一致。此参数是可选的。 - - - - - - - delegate_ident_mapping - - - - 这是一个高级选项,不适合常规使用。 - - - 当设置为 1 时,会跳过基于 pg_ident.conf 的标准用户映射,而由 OAuth 验证器完全负责把终端用户身份映射到数据库角色。如果验证器授权该令牌,服务器就会信任该用户被允许以请求的角色进行连接,并且无论该用户自身的认证状态如何,连接都将继续进行。 - - - 此参数与 map 不兼容。 - - - - delegate_ident_mapping 为认证系统设计带来了额外灵活性,但也要求对 OAuth 验证器进行谨慎实现。验证器不仅必须执行标准检查,还必须判断所提供的令牌是否携带了足够的终端用户权限。请谨慎使用。 - - - - - - - diff --git a/zh/16/config.sgml b/zh/16/config.sgml index cdf0325c..2c14776e 100644 --- a/zh/16/config.sgml +++ b/zh/16/config.sgml @@ -51,7 +51,7 @@ 字符串: 通常值被包括在单引号内,值内部的任何单引号都需要被双写。不过,如果值是一个简单数字或者 标识符,引号通常可以被省略。 - (与 SQL 关键字匹配的值需要在某些上下文中引用。) + (与 SQL 关键字匹配的值在某些上下文中需要加引号。) @@ -70,7 +70,7 @@ 带单位的数字: 一些数字参数具有隐含单位,因为它们描述的是内存或时间量。单位可能是字节、千字节、块 - (通常为 8 千字节)、毫秒、秒或分钟。这类设置若给出不带修饰的数字值,就会使用该设置的默认单位, + (通常为 8 千字节)、毫秒、秒或分钟。这类设置若给出不带单位的数字值,就会使用该设置的默认单位, 可以通过 pg_settings.unit 了解该默认单位。为了方便, 也可以显式指定单位,例如把时间值写成 '120 ms',系统会将其转换为该参数的实际单位。 注意,要使用这一特性,值必须写成字符串(带引号)。单位名称区分大小写,并且数字值与单位之间可以有空白。 @@ -122,7 +122,7 @@ 它通常位于数据目录中。在数据库集簇目录初始化时,会安装该文件的一个默认副本。其内容示例如下: # This is a comment -log_connections = all +log_connections = yes log_destination = 'syslog' search_path = '"$user", public' shared_buffers = 128MB @@ -161,7 +161,8 @@ shared_buffers = 128MB - 外部工具也可以修改 postgresql.auto.conf。不过,不建议在服务器运行时这样做, + 外部工具也可以修改 postgresql.auto.conf。 + 不建议在服务器运行时这样做, 因为并发的 ALTER SYSTEM 命令可能会覆盖这些更改。 这类工具可能只是简单地在文件末尾追加新设置,也可能选择删除重复设置和/或注释 (正如 ALTER SYSTEM 那样)。 @@ -189,14 +190,14 @@ shared_buffers = 128MB - ALTER DATABASE命令允许针对一个数据库覆盖其全局设置。 + ALTER DATABASE命令允许针对各个数据库覆盖全局设置。 - ALTER ROLE命令允许用用户指定的值来覆盖全局设置和数据库设置。 + ALTER ROLE命令允许用针对特定用户设置的值来覆盖全局设置和数据库设置。 @@ -271,7 +272,7 @@ UPDATE pg_settings SET setting = reset_val WHERE name = 'configuration_parameter 通过 Shell 影响参数 - 除了在数据库或者角色层面上设置全局默认值或者进行覆盖,你还可以通过 shell 工具把设置 + 除了设置全局默认值或在数据库、角色级别覆盖默认值之外,你还可以通过 shell 工具把设置 传递给PostgreSQL。服务器和libpq 客户端库都能通过 shell 接受参数值。 @@ -283,7 +284,7 @@ UPDATE pg_settings SET setting = reset_val WHERE name = 'configuration_parameter 在服务器启动期间,可以通过命令行参数把参数设置传递给 postgres命令。例如: -postgres -c log_connections=all --log-destination='syslog' +postgres -c log_connections=yes -c log_destination='syslog' 这种方式提供的设置会覆盖通过postgresql.conf或者 ALTER SYSTEM提供的设置,因此除了重启服务器之外无法从全局上改变它们。 @@ -299,7 +300,7 @@ postgres -c log_connections=all --log-destination='syslog' postgres命令时用到的相似,特别是标志必须被指定。 例如: -env PGOPTIONS="-c geqo=off --statement-timeout=5min" psql +env PGOPTIONS="-c geqo=off -c statement_timeout=5min" psql @@ -343,7 +344,7 @@ include 'filename' 还有一个 include_if_exists 指令,其行为与 include 相同, 但在被引用文件不存在或无法读取时有所不同。普通的 include 会将其视为错误, - 而 include_if_exists 只会记录一条消息并继续处理引用配置文件。 + 而 include_if_exists 只会记录一条消息并继续处理引用它的配置文件。 @@ -354,21 +355,21 @@ include 'filename' postgresql.conf 文件也可以包含 include_dir 指令, 用来指定一个应被包含的配置文件目录。其用法如下: - include_dir 'directory' - - 非绝对目录名会被解释为相对于引用配置文件所在目录的路径。在指定目录中, +include_dir 'directory' + + 非绝对目录名会被解释为相对于引用它的配置文件所在目录的路径。在指定目录中, 只有名称以 .conf 结尾的非目录文件才会被包含。以 . 开头的文件名也会被忽略,以避免在某些平台上误处理隐藏文件。包含目录中的多个文件会按文件名顺序处理 (依据 C 区域规则排序,即数字在字母之前,大写字母在小写字母之前)。 - 包括文件或目录可以被用来在逻辑上分隔数据库配置的各个部分,而不是用一个很大的postgresql.conf文件。 + 包含文件或目录可以用来在逻辑上分隔数据库配置的各个部分,而不是用一个很大的postgresql.conf文件。 考虑一个有两台数据库服务器的公司,每一个都有不同的内存量。 - 很可能配置的元素都会被共享,例如用于日志的参数。但是两者关于内存的参数将会不同。 + 两者很可能会共享部分配置,例如日志设置。但是两者关于内存的参数将会不同。 并且还可能会有服务器相关的自定义。 一种管理这类情况的方法是将你的站点的自定义配置修改分成三个文件。 - 你可以把下面的内容加入到你的postgresql.conf文件末尾来包括它们: + 你可以把下面的内容加入到你的postgresql.conf文件末尾来包含它们: include 'shared.conf' include 'memory.conf' @@ -429,7 +430,7 @@ include_dir 'conf.d' - 指定用于数据存储的目录。这个选项只能在服务器启动时设置。 + 指定用于数据存储的目录。这个参数只能在服务器启动时设置。 @@ -489,7 +490,7 @@ include_dir 'conf.d' - 指定可被服务器创建的用于管理程序的额外进程 ID(PID)文件。这个参数只能在服务器启动的时候设置。 + 指定服务器应创建的额外进程 ID(PID)文件的名称,供服务器管理程序使用。这个参数只能在服务器启动的时候设置。 @@ -500,15 +501,15 @@ include_dir 'conf.d' - 如果你想把配置文件放在别的地方而不是数据目录中,那么postgres 命令行选项或者环境变量PGDATA必须指向包含配置文件的目录,并且postgresql.conf中(或者命令行上)的data_directory参数必须显示数据目录实际存放的地方。请注意,data_directory将覆盖PGDATA指定的数据目录位置,但是不覆盖配置文件的位置。 + 如果你想把配置文件放在别的地方而不是数据目录中,那么postgres 命令行选项或者环境变量PGDATA必须指向包含配置文件的目录,并且postgresql.conf中(或者命令行上)的data_directory参数必须设置为数据目录的实际位置。请注意,data_directory将覆盖PGDATA指定的数据目录位置,但是不覆盖配置文件的位置。 - 如果你愿意,可以使用选项config_filehba_file和/或ident_file单独指定配置文件名称和位置。config_file只能在postgres命令行上指定,但是其他文件可以在主配置文件中设置。如果所有三个参数外加data_directory被显式地设置,则不必指定PGDATA。 + 如果你愿意,可以使用选项config_filehba_file和/或ident_file单独指定配置文件名称和位置。config_file只能在postgres命令行上指定,但是其他参数可以在主配置文件中设置。如果所有三个参数外加data_directory被显式地设置,则不必指定PGDATA - 在设置任何这些参数时,相对路径将被解释为相对于postgres启动路径的路径。 + 在设置任何这些参数时,相对路径将被解释为相对于启动 postgres 时所在目录的路径。 @@ -532,7 +533,7 @@ include_dir 'conf.d' - 指定服务器用于监听来自客户端应用程序的连接的TCP/IP地址(指服务器网卡IP地址)。 + 指定服务器用于监听来自客户端应用程序的连接的TCP/IP地址。 该值采用逗号分隔的主机名和/或数字IP地址的形式。特殊条目*对应于所有可用的IP接口。 条目0.0.0.0允许监听所有IPv4地址,::允许监听所有IPv6地址。 如果列表为空,则服务器不会在任何IP接口上监听,此时只能使用Unix域套接字进行连接。 @@ -555,11 +556,11 @@ include_dir 'conf.d' - - - 服务器监听的 TCP 端口;默认是 5432 。请注意服务器会同一个端口号监听所有的 IP 地址。这个参数只能在服务器启动时设置。 - - + + 服务器监听的 TCP 端口,默认是 5432。请注意,服务器监听的所有 IP 地址都使用同一个端口号。 + 此参数只能在服务器启动时设置。 + + @@ -570,22 +571,16 @@ include_dir 'conf.d' - 决定数据库服务器允许的最大并发连接数。默认值通常是 100 个连接,但如果内核设置不支持 (在 initdb 期间确定),则可能更少。这个参数只能在服务器启动时设置。 - - PostgreSQL 会直接根据 max_connections 的值来确定某些资源的规模。 - 增大该值会导致这些资源(包括共享内存)的分配随之增加。 - - 当运行一个备库时,你必须设置这个参数等于或大于主库上的参数。 - 否则,备库上可能无法允许查询。 + 否则,备库上将不允许查询。 - + @@ -596,20 +591,10 @@ include_dir 'conf.d' - 确定为拥有 - pg_use_reserved_connections - 角色的连接保留多少个连接。当空闲连接槽的数量大于 - , - 但小于或等于superuser_reserved_connections与 - reserved_connections之和时,新连接将只接受超级用户以及拥有 - pg_use_reserved_connections权限的角色。如果可用连接槽的数量等于或少于 - superuser_reserved_connections,则新连接只接受超级用户。 + 确定为具有 pg_use_reserved_connections(见) 角色权限的角色保留多少个连接。当空闲连接槽的数量大于 ,但小于或等于 superuser_reserved_connectionsreserved_connections 之和时,新连接将只接受超级用户以及具有 pg_use_reserved_connections 角色权限的角色。如果可用连接槽的数量小于或等于 superuser_reserved_connections,则新连接只接受超级用户。 - 默认值为零连接。该值必须小于 - max_connections减去 - superuser_reserved_connections。 - 此参数只能在服务器启动时设置。 + 默认值为零个连接。该值必须小于 max_connections 减去 superuser_reserved_connections。此参数只能在服务器启动时设置。 @@ -627,7 +612,7 @@ include_dir 'conf.d' 决定为 PostgreSQL 超级用户连接保留多少个连接。 - 同时活跃的连接数最多始终只能达到 。当活跃并发连接数达到 + 同时活跃的连接数最多始终只能达到 。当活跃并发连接数至少达到 max_connections 减去 superuser_reserved_connections 时, 新连接将只接受超级用户。由该参数保留的连接槽是在 保留的连接槽耗尽之后,用于紧急情况的最后储备。 @@ -705,31 +690,23 @@ include_dir 'conf.d' - - 设置 Unix 域套接字的访问权限。Unix 域套接字使用普通的 Unix 文件系统权限集。这个参数值应该是数字的形式,也就是系统调用chmodumask接受的 形式(如果使用自定义的八进制格式,数字必须以一个0(零)开头)。 + 设置 Unix 域套接字的访问权限。Unix 域套接字使用通常的 Unix 文件系统权限集。参数值应是以 chmodumask 系统调用所接受格式指定的数字权限模式。(要使用惯用的八进制格式,数字必须以 0(零)开头。) - - 默认的权限是0777,意思是任何人都可以连接。合理的候选是0770(只有用户和同组的人可以访问, 又见unix_socket_group)和0700(只有用户自己可以访问)(请注意,对于 Unix 域套接字,只有写权限有麻烦,因此没有对读取和执行权限的设置和收回)。 + 默认权限是 0777,表示任何人都可以连接。合理的其他取值包括 0770(仅属主和所属组,另见 unix_socket_group)和 0700(仅属主)。(注意,对 Unix 域套接字而言,只有写权限起作用,因此设置或撤销读权限和执行权限没有意义。) - - 这个访问控制机制与中的用户认证没有关系。 + 此访问控制机制独立于 中描述的机制。 - - 这个参数只能在服务器启动时设置。 + 此参数只能在服务器启动时设置。 - - 这个参数与完全忽略套接字权限的系统无关,尤其是自版本10以上的Solaris。 - 在那些系统上,可以通过把unix_socket_directories指向一个把搜索权限 - 限制给指定用户的目录来实现相似的效果。 + 此参数对完全忽略套接字权限的系统无效,尤其是 Solaris(截至 Solaris 10)。在这些系统上,可以将 unix_socket_directories 指向一个仅向目标用户授予搜索权限的目录,以达到类似效果。 - - 抽象命名空间中的套接字没有文件权限,所以这种情况下这个设置也会被忽略。 + 抽象命名空间中的套接字没有文件权限,因此这种情况下也会忽略此设置。 @@ -742,10 +719,8 @@ include_dir 'conf.d' - - 通过Bonjour广告服务器的存在。默认值是关闭。 - 这个参数只能在服务器启动时设置。 + 启用通过 Bonjour 通告服务器存在的功能。默认值为关闭。此参数只能在服务器启动时设置。 @@ -758,11 +733,11 @@ include_dir 'conf.d' - - - 指定Bonjour服务名称。空字符串''(默认值)表示使用计算机名。 如果编译时没有打开Bonjour支持那么将忽略这个参数。这个参数只能在服务器启动时设置。 - - + + 指定 Bonjour 服务名。空字符串 ''(默认值)表示使用计算机名。 + 如果编译时未启用 Bonjour 支持,则此参数会被忽略。此参数只能在服务器启动时设置。 + + @@ -855,60 +830,21 @@ include_dir 'conf.d' - - 在运行查询时,设置检查客户端是否保持连接的可选检查的时间间隔。 - 这个检查通过轮询套接字来执行,并且在内核报告该连接关闭时,允许长时间运行的查询可以尽快中止。 + 设置查询执行期间可选的客户端连接检查的时间间隔,用于检查客户端是否仍然连接。检查通过轮询套接字执行;如果内核报告连接已经关闭,就可以更早中止长时间运行的查询。 - - 这个选项依赖于Linux、macOS、illumos和BSD家族操作系统暴露的内核事件, - 目前在其他系统上不可用。 + 此选项依赖 Linux、macOS、illumos 和 BSD 系列操作系统提供的内核事件,目前在其他系统上不可用。 - - 如果指定的值没有单位,则以毫秒为单位。 - 默认值为0,代表禁用连接检查。 - 没有连接检查,服务器将只在与套接字的下一次交互时检测连接的丢失,当它等待、接收或发送数据时。 + 如果指定值时没有单位,则以毫秒计。默认值为 0,表示禁用连接检查。如果不进行连接检查,服务器只有在下一次与套接字交互(等待、接收或发送数据)时,才会检测到连接丢失。 - - 为了让内核本身能够在包括网络故障在内的所有场景中,在已知的时间范围内可靠地检测丢失的TCP连接,它可能还需要调整操作系统的TCP保持连接设置, - 或者PostgreSQL, 设置。 + 要让内核本身在包括网络故障在内的所有场景中,能够在确定的时间范围内可靠地检测到 TCP 连接丢失,可能还需要调整操作系统的 TCP keepalive 设置,或 PostgreSQL 设置。 - - file_extend_method (enum) - - file_extend_method配置参数 - - - - - 指定在诸如COPY这类批量操作期间扩展数据文件时所使用的方法。 - 默认会根据操作系统选择第一个可用选项: - - - - posix_fallocate(Unix)使用标准 POSIX 接口分配磁盘空间,但某些系统缺少该接口。 - 如果接口存在但底层文件系统不支持,本选项会静默回退到write_zeros。 - 已知当前版本的 BTRFS 在使用该选项时会禁用压缩。 - 在提供该函数的系统上,这是默认值。 - - - - - write_zeros通过写出零字节块来扩展文件。 - 在不提供posix_fallocate函数的系统上,这是默认值。 - - - - 当数据文件扩展的块数不超过 8 个时,总是使用write_zeros方法。 - - - @@ -958,12 +894,6 @@ include_dir 'conf.d' 请注意,较旧的客户端可能缺少对 SCRAM 认证机制的支持,因此无法使用以 SCRAM-SHA-256 加密的密码。 详情参见 - - - 对 MD5 加密密码的支持已被弃用,并将在未来的 PostgreSQL 版本中移除。 - 关于迁移到其他密码类型的细节,请参见 。 - - @@ -1003,7 +933,7 @@ include_dir 'conf.d' 设置服务器的Kerberos密钥文件的位置。 - 默认为FILE:/usr/local/pgsql/etc/krb5.keytab(其中目录部分是在构建时由sysconfdir指定的;用pg_config --sysconfdir来决定)。 + 默认为FILE:/usr/local/pgsql/etc/krb5.keytab(其中目录部分是在构建时由sysconfdir指定的;可用pg_config --sysconfdir来确定该目录)。 如果这个参数被设为空字符串,它将被忽略,并且系统依赖的默认值被应用。 这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 详情请参考。 @@ -1034,26 +964,55 @@ include_dir 'conf.d' - 设置是否应接受来自客户端的 GSSAPI 代理。默认值为off, - 这表示不会接受客户端的凭据。将其改为on会使服务器接受 - 客户端代理给它的凭据。此参数只能在postgresql.conf文件 - 或服务器命令行中设置。 + 设置是否接受客户端的 GSSAPI 委派。默认值为 off,表示不会接受客户端的凭证。将其改为 on 会使服务器接受客户端委派给它的凭证。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 - + + db_user_namespace (boolean) + + db_user_namespace 配置参数 + + + + + 此参数启用各数据库独立的用户名。默认关闭。 + 此参数只能在postgresql.conf文件中或在服务器命令行上设置。 + + + + 如果启用此参数,你应以username@dbname的形式创建用户。 + 连接的客户端传入username时,会在用户名后附加@和数据库名, + 然后由服务器查找此数据库专属的用户名。请注意,在 SQL 环境中创建名称包含@的用户时,需要用引号括起用户名。 + + + + 启用此参数后,仍然可以创建普通的全局用户。只需在客户端指定用户名时附加@,例如joe@。 + 服务器查找用户名之前会去掉@。 + + + + db_user_namespace会使客户端和服务器的用户名表示形式不同。 + 认证检查始终使用服务器端的用户名,因此认证方法必须针对服务器端的用户名配置,而不是客户端的用户名。 + 由于md5在客户端和服务器上都使用用户名作为盐值,md5不能与db_user_namespace一起使用。 + + + + + 此特性旨在作为找到完整解决方案之前的临时措施。届时将移除此选项。 + + + + + - SSL - 查看以获取有关设置SSL的更多信息。 - 用TLS协议控制传输加密的配置参数被命名为ssl,出于历史原因, - 尽管对SSL协议的支持已被弃用。 - 在这种情况下,SSLTLS可互换使用。 + 关于 SSL 的设置,参见 。虽然对 SSL 协议的支持已被弃用,但由于历史原因,用于控制 TLS 协议传输加密的配置参数仍以 ssl 命名。在此语境中,SSLTLS 这两个术语可互换使用。 @@ -1137,13 +1096,13 @@ include_dir 'conf.d' 这个目录需要用OpenSSL 命令 openssl rehashc_rehash来准备。 - 详情参阅相应文档 + 详情参阅相应文档。 - 当使用此设置时,在连接时会按需加载指定目录下的CRLs。 - 新的CRLs可以添加到该目录中,并可以立即使用。 - 这与不同,那个会导致文件中的CRL在服务器启动时间或重新加载配置时加载。 + 当使用此设置时,在连接时会按需加载指定目录下的CRL。 + 新的CRL可以添加到该目录中,并可以立即使用。 + 这与不同,那个会导致文件中的CRL在服务器启动时或重新加载配置时加载。 两个设置可以一起使用。 @@ -1174,10 +1133,12 @@ include_dir 'conf.d' - 指定允许用于 TLS 1.2 及更低版本连接的 SSL 密码套件列表。 + 指定允许 SSL 连接使用的 SSL 密码套件列表。 该设置的语法及支持的值列表可参见 OpenSSL 包中的 ciphers 手册页。 - 默认值是HIGH:MEDIUM:+3DES:!aNULL。除非你有特定的安全需求,否则这个默认值通常是合理的选择。 + 只有使用 TLS 1.2 及更低版本的连接会受到影响。目前还没有控制 + TLS 1.3 连接所用密码选择的设置。默认值是 + HIGH:MEDIUM:+3DES:!aNULL。除非你有特定的安全需求,否则这个默认值通常是合理的选择。 @@ -1229,7 +1190,7 @@ include_dir 'conf.d' - 可用的密码组细节可能会随着OpenSSL 版本变化。 + 可用的密码套件细节可能会随着OpenSSL 版本变化。 可使用命令 openssl ciphers -v 'HIGH:MEDIUM:+3DES:!aNULL'来查看当前安装的OpenSSL版本的实际细节。 注意这个列表是根据服务器密钥类型在运行时过滤过的。 @@ -1244,15 +1205,27 @@ include_dir 'conf.d' - - 指定是否使用服务器的 SSL 密码首选项,而不是用客户端的。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 - 默认值是 on。 + 指定是否使用服务器的 SSL 密码套件优先顺序,而非客户端的优先顺序。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。默认值为 on + + PostgreSQL 9.4 之前的版本没有此设置,始终采用客户端的优先顺序。此设置主要用于与这些旧版本保持向后兼容。采用服务器的优先顺序通常更好,因为服务器更可能得到适当配置。 + + + + + ssl_ecdh_curve (string) + + ssl_ecdh_curve 配置参数 + + + + + 指定在 ECDH 密钥交换中使用的曲线名称。所有连接的客户端都必须支持该曲线。它不必与服务器椭圆曲线密钥使用的曲线相同。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。默认值为 prime256v1。 + - 老的PostgreSQL版本没有这个设置并且总是使用客户端的首选项。这个设置主要用于与那些版本 - 的向后兼容性。使用服务器的首选项通常会更好,因为服务器更可能会被合适地配置。 + OpenSSL 中最常见的曲线名称为:prime256v1(NIST P-256)、secp384r1(NIST P-384)、secp521r1(NIST P-521)。可以用 openssl ecparam -list_curves 命令显示可用曲线的完整列表,但其中并非所有曲线都能用于 TLS @@ -1265,19 +1238,14 @@ include_dir 'conf.d' - - 设置要使用的最小SSL/TLS协议版本。当前的可用版本包括: TLSv1, TLSv1.1, TLSv1.2, TLSv1.3. - 旧版本的 OpenSSL 库不支持所有值;如果选择了不支持的设置将会引发错误。 - TLS 1.0之前的协议版本,也就是SSL 版本 2 and 3,总是禁用的。 + 设置要使用的最低 SSL/TLS 协议版本。当前有效值为:TLSv1TLSv1.1TLSv1.2TLSv1.3。较旧版本的 OpenSSL 库不支持所有值;如果选择了不支持的设置,就会报错。TLS 1.0 之前的协议版本,即 SSL 2 和 3,始终被禁用。 - - 默认为TLSv1.2, 在本文撰写时的行业最佳实践。 + 默认值为 TLSv1.2,符合本文撰写时的行业最佳实践。 - - 这个参数只能在postgresql.conf文件中或通过服务器命令行进行设置。 + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 @@ -1290,15 +1258,11 @@ include_dir 'conf.d' - - 设定要使用的最大SSL/TLS协议版本。 - 有效的版本为 , 添加一个空字符串,允许任何协议版本。 - 默认为允许任何版本。设置最大协议版本主要用于测试,或者某个组件在与较新的协议配合工作时出现了问题。 + 设置要使用的最高 SSL/TLS 协议版本。有效值与 相同,此外还可设为空字符串,表示允许任意协议版本。默认允许任意版本。设置最高协议版本主要用于测试,或处理某些组件无法正常配合更新协议工作的问题。 - - 这个参数只能在postgresql.conf文件中或通过服务器命令行进行设置。 + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 @@ -1311,13 +1275,11 @@ include_dir 'conf.d' - - 指定含有用于SSL密码的所谓临时DH家族的Diffie-Hellman参数的文件名。默认值为空,这种情况下将使用内置的默认DH参数。使用自定义的DH参数可以降低攻击者破解众所周知的内置DH参数的风险。可以用命令openssl dhparam -out dhparams.pem 2048创建自己的DH参数文件。 + 指定包含 Diffie-Hellman 参数的文件名,这些参数用于所谓临时 DH 系列的 SSL 密码套件。默认值为空,此时使用编译时内置的默认 DH 参数。如果攻击者破解了众所周知的内置 DH 参数,使用自定义 DH 参数可以降低由此带来的风险。可以用命令 openssl dhparam -out dhparams.pem 2048 创建自己的 DH 参数文件。 - - 这个参数只能在postgresql.conf文件中或通过服务器命令行进行设置。 + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 @@ -1330,21 +1292,17 @@ include_dir 'conf.d' - - 设置当需要一个密码(例如一个私钥)来解密SSL文件时会调用的一个外部命令。默认情况下,这个参数为空,表示使用内置的提示机制。 + 设置获取用于解密私钥等 SSL 文件的口令时要调用的外部命令。默认值为空,表示使用内置的提示机制。 - - 该命令必须将密码打印到标准输出并且以代码0退出。在该参数值中,%p被替换为一个提示字符串(要得到文字%,应该写成%%)。注意该提示字符串将可能含有空格,因此要确保加上适当的引号。如果输出的末尾有单一的新行,它会被剥离掉。 + 该命令必须将口令输出到标准输出,并以退出码 0 结束。参数值中的 %p 会被替换为提示字符串。(要表示字面值 %,应写成 %%。)提示字符串可能包含空白,因此务必正确加引号。如果输出末尾有一个换行符,会将其去掉。 - - 该命令实际上并不一定要提示用户输入一个密码。它可以从文件中读取密码、从钥匙链得到密码等等。确保选中的机制足够安全是用户的责任。 + 该命令不一定要提示用户输入口令,也可以从文件读取口令、从钥匙链获取口令等。用户应自行确保所选机制足够安全。 - - 这个参数只能在postgresql.conf文件中或通过服务器命令行进行设置。 + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 @@ -1357,20 +1315,14 @@ include_dir 'conf.d' - - 这个参数决定在配置重载期间如果一个密钥文件需要密码时,是否也调用ssl_passphrase_command设置的密码命令。 - 如果这个参数为off(默认),那么在重载期间将忽略ssl_passphrase_command,如果在此期间需要密码则SSL配置将不会被重载。 - 对于要求一个TTY(当服务器正在运行时可能是不可用的)来进行提示的命令,这种设置是合适的。 - 例如,如果密码是从一个文件中得到的,将这个参数设置为on可能是合适的。 + 此参数决定:配置重载期间,如果密钥文件需要口令,是否也调用 ssl_passphrase_command 设置的口令命令。如果此参数为 off(默认值),则重载时会忽略 ssl_passphrase_command,如果需要口令,就不会重载 SSL 配置。此设置适合需要通过 TTY 提示用户的命令,因为服务器运行期间可能无法使用 TTY。例如,如果从文件中获取口令,则适合将此参数设为 on。 - 在Windows上运行时,必须将该参数设为on, - 因为该平台采用不同的进程模型,所有连接都会触发配置重载。 + 在 Windows 上运行时,必须将此参数设为 on,因为该平台的进程模型不同,每个连接都会执行配置重载。 - - 这个参数只能在postgresql.conf文件中或通过服务器命令行进行设置。 + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 @@ -1395,22 +1347,15 @@ include_dir 'conf.d' - - 设置数据库服务器将使用的共享内存缓冲区量。默认通常是 128 兆字节(128MB),但是如果你的内核设置不支持(在initdb时决定),那么可以会更少。 - 这个设置必须至少为 128 千字节。不过为了更好的性能,通常会使用明显高于最小值的设置。 - 如果指定值时没有单位,则以块为单位,即BLCKSZ字节,通常为8kB.(BLCKSZ 的非默认值改变最小值。) - 此参数只能在服务器启动时设置。 + 设置数据库服务器用于共享内存缓冲区的内存量。默认值通常为 128 兆字节(128MB),但如果内核设置不支持,则可能更小(在 initdb 期间确定)。此设置必须至少为 128 千字节。不过,要获得良好性能,通常需要远高于该最小值的设置。如果指定值时没有单位,则以块为单位,即 BLCKSZ 字节,通常为 8kB。(BLCKSZ 的非默认值会改变该最小值。)此参数只能在服务器启动时设置。 - - 如果有一个专用的 1GB 或更多内存的数据库服务器,一个合理的shared_buffers开始值是系统内存的 25%。即使更大的shared_buffers有效,也会造成一些工作负载, 但因为PostgreSQL同样依赖操作系统的高速缓冲区,将shared_buffers设置为超过 40% 的RAM不太可能比一个小点值工作得更好。为了能把对写大量新的或改变的数据的处理分布在一个较长的时间段内,shared_buffers更大的设置通常要求对max_wal_size也做相应增加。 + 如果专用数据库服务器具有 1GB 或更多内存,shared_buffers 的合理初始值是系统内存的 25%。对于某些工作负载,将 shared_buffers 设得更大也有效,但由于 PostgreSQL 同时依赖操作系统缓存,将超过 40% 的内存分配给 shared_buffers 不太可能比更小的值效果更好。将 shared_buffers 设得更大时,通常还需要相应增加 max_wal_size,以便将大量新数据或已修改数据的写入过程分散到更长的时间内。 - - 如果系统内存小于 1GB,一个较小的 RAM 百分数是合适的,这样可以为操作系统留下足够的空间。 + 对于内存少于 1GB 的系统,适合使用更小的内存比例,以便为操作系统留出足够空间。 - @@ -1433,19 +1378,19 @@ include_dir 'conf.d' - 巨型页面的使用会导致更小的页面表以及花费在内存管理上的 CPU 时间更少,从而提高性能。更多有关Linux上使用巨型页面的细节请见。 + 巨型页的使用会导致更小的页表以及花费在内存管理上的 CPU 时间更少,从而提高性能。更多有关Linux上使用巨型页的细节请见 巨型页在Windows上被称为大页面。 要使用大页面,需要为运行PostgreSQL的Windows用户账号分配在内存中锁定页面的用户权限。 可以使用Windows的组策略工具(gpedit.msc)来分配用户权限在内存中锁定页面。 - 为了在命令窗口以单进程(而不是Windows服务)的方式启动数据库服务器,命令窗口必须以管理员身份运行或者禁用用户访问控制(UAC)。 + 为了在命令窗口以独立进程(而不是Windows服务)的方式启动数据库服务器,命令窗口必须以管理员身份运行或者禁用用户访问控制(UAC)。 当UAC被启用时,普通的命令窗口会在启动时收回用户权限在内存中锁定页面 - 注意这种设置仅影响主共享内存区域。Linux、FreeBSD以及Illumos之类的操作系统也能为普通内存分配自动使用巨型页(也被称为超级页或者页面),而不需要来自PostgreSQL的显式请求。在Linux上,这被称为transparent huge pagestransparent huge pages(THP,透明巨型页)。已知这种特性对某些Linux版本上的某些用户会导致PostgreSQL的性能退化,因此当前并不鼓励使用它(与huge_pages的显式使用不同)。 + 注意这种设置仅影响主共享内存区域。Linux、FreeBSD以及Illumos之类的操作系统也能为普通内存分配自动使用巨型页(也被称为超级页或者页面),而不需要来自PostgreSQL的显式请求。在Linux上,这被称为transparent huge pages透明巨型页(THP,透明巨型页)。已知这种特性对某些Linux版本上的某些用户会导致PostgreSQL的性能退化,因此当前并不鼓励使用它(与huge_pages的显式使用不同)。 @@ -1458,24 +1403,14 @@ include_dir 'conf.d' - - 控制巨型页的大小,当他们通过时。 - 默认为零 (0)。 - 当设置为0时,将使用系统默认的巨型页大小。 - 这个参数只能在服务器启动时设置。 + 控制通过 启用巨型页时所使用的页大小。默认值为零(0)。设置为 0 时,使用系统默认的巨型页大小。此参数只能在服务器启动时设置。 - - 一些现代64位服务器体系结构上常用的有效页尺寸包括: - 2MB1GB (Intel and AMD), - 16MB16GB (IBM POWER), - 还有 64kB, 2MB,32MB1GB (ARM). - 关于使用和支持的更多信息,参见。 + 现代 64 位服务器体系结构上常见的页大小包括:2MB1GB(Intel 和 AMD),16MB16GB(IBM POWER),以及 64kB2MB32MB1GB(ARM)。关于使用和支持的更多信息,参见 - - 非默认设置当前仅在Linux上支持。 + 目前只有 Linux 支持非默认设置。 @@ -1488,16 +1423,11 @@ include_dir 'conf.d' - - 为每个数据库会话设置用于临时缓冲区的最大内存.这些是仅用于访问临时表的会话本地缓冲。 - 如果指定值时没有单位,则以块为单位,即BLCKSZ字节,通常为8kB。 - 默认为8兆字节 (8MB)。(如果BLCKSZ不是8kB,则默认值按比例缩放。) - 这个设置可以在独立的会话内部被改变,但是只有在会话第一次使用临时表之前才能改变; 在会话中随后企图改变该值是无效的。 + 设置每个数据库会话用于临时缓冲区的最大内存量。这些是会话本地的缓冲区,仅用于访问临时表。如果指定值时没有单位,则以块为单位,即 BLCKSZ 字节,通常为 8kB。默认值为 8 兆字节(8MB)。(如果 BLCKSZ 不是 8kB,则默认值按比例变化。)可以在单个会话内更改此设置,但必须在该会话首次使用临时表之前更改;此后尝试更改该值,对该会话不会产生影响。 - - 一个会话将按照temp_buffers给出的限制根据需要分配临时缓冲区。如果在一个并不需要大量临时缓冲区的会话里设置一个大的数值, 其开销只是一个缓冲区描述符,或者说temp_buffers每增加一则增加大概 64 字节。不过,如果一个缓冲区被实际使用,那么它就会额外消耗 8192 字节(或者BLCKSZ字节)。 + 会话会按需分配临时缓冲区,上限为 temp_buffers。对于实际不需要很多临时缓冲区的会话,将此参数设得较大时,开销仅为 temp_buffers 每增加一就多分配一个缓冲区描述符,约为 64 字节。不过,如果实际使用了某个缓冲区,还会为它额外消耗 8192 字节(一般而言为 BLCKSZ 字节)。 @@ -1510,18 +1440,14 @@ include_dir 'conf.d' - - 设置可以同时处于prepared状态的事务的最大数目(见)。把这个参数设置 为零(这是默认设置)将禁用预备事务特性。这个参数只能在服务器启动时设置。 + 设置可同时处于预备状态的事务的最大数量(见 )。将此参数设为零(默认值)会禁用预备事务功能。此参数只能在服务器启动时设置。 - - 如果你不打算使用预备事务,可以把这个参数设置为零来防止意外创建预备事务。如果你正在使用预备事务,你将希望把max_prepared_transactions至少设置为一样大,因此每一个会话可以有一个预备事务待处理。 + 如果不打算使用预备事务,应将此参数设为零,以防意外创建预备事务。如果使用预备事务,通常应将 max_prepared_transactions 设为不小于 的值,以便每个会话都能有一个待处理的预备事务。 - - 当运行一个备库时,你必须设置这个参数等于或大于主库上的参数。 - 否则,备库上可能无法允许查询。 + 运行备库时,必须将此参数设为与主库相同或更大的值。否则,备库上将不允许执行查询。 @@ -1534,24 +1460,11 @@ include_dir 'conf.d' - - 设置查询操作(如排序或哈希表)在写入临时磁盘文件之前可使用的基本最大内存量。 - 如果未指定单位,则将其视为千字节。默认值为四兆字节(4MB)。 - 请注意,复杂查询可能同时执行多个排序和哈希操作, - 每个操作通常允许在开始将数据写入临时文件之前使用此值指定的内存量。 - 此外,可能有多个正在运行的会话同时执行此类操作。 - 因此,使用的总内存量可能是work_mem值的多倍; - 在选择值时必须牢记这一事实。排序操作用于ORDER BYDISTINCT和合并连接。 - 哈希表用于哈希连接、基于哈希的聚合、记忆节点和IN子查询的基于哈希的处理。 + 设置查询操作(如排序或哈希表)在写入临时磁盘文件之前可使用的基础最大内存量。如果未指定单位,则以千字节为单位。默认值为 4 兆字节(4MB)。请注意,复杂查询可能同时执行多个排序和哈希操作,每个操作在开始向临时文件写入数据之前,通常都可以使用此值指定的内存量。此外,多个正在运行的会话也可能并发执行此类操作。因此,使用的总内存量可能是 work_mem 值的数倍;选择此值时必须考虑这一点。排序操作用于 ORDER BYDISTINCT 和归并连接。哈希表用于哈希连接、基于哈希的聚合、Memoize 节点以及基于哈希的 IN 子查询处理。 - - 基于哈希的操作通常比等效的基于排序的操作更加敏感于内存可用性。 - 哈希表的内存限制是通过将work_mem乘以 - hash_mem_multiplier来计算的。这使得 - 基于哈希的操作可以使用超过通常的work_mem基本 - 量的内存。 + 与等效的排序操作相比,基于哈希的操作通常对可用内存更敏感。哈希表的内存上限由 work_mem 乘以 hash_mem_multiplier 计算得到。因此,基于哈希的操作可以使用超过通常的 work_mem 基础量的内存。 @@ -1564,17 +1477,11 @@ include_dir 'conf.d' - - 用于计算哈希操作可以使用的最大内存量。最终限制由将work_mem乘以hash_mem_multiplier确定。 - 默认值为2.0,这使得基于哈希的操作使用通常work_mem基础量的两倍。 + 用于计算基于哈希的操作可以使用的最大内存量。最终上限由 work_mem 乘以 hash_mem_multiplier 确定。默认值为 2.0,使基于哈希的操作可以使用通常的 work_mem 基础量的两倍。 - - 考虑在查询操作频繁溢出的环境中增加hash_mem_multiplier, - 特别是当简单增加work_mem导致内存压力时(内存压力通常表现为间歇性的内存不足错误)。 - 默认设置为2.0通常在混合工作负载中有效。在已将work_mem增加到40MB或更高的环境中, - 可以考虑将设置调高至2.0-8.0或更高。 + 如果查询操作经常溢写磁盘,可以考虑增加 hash_mem_multiplier,尤其是在单纯增加 work_mem 会导致内存压力的情况下(内存压力通常表现为间歇性的内存不足错误)。对于混合工作负载,默认值 2.0 通常有效。如果 work_mem 已增加到 40MB 或更高,则将该值进一步设为 2.0 - 8.0 或更高可能有效。 @@ -1587,19 +1494,14 @@ include_dir 'conf.d' - - 指定维护操作(如 VACUUMCREATE INDEX 和 - ALTER TABLE ADD FOREIGN KEY)可使用的最大内存量。 - 如果指定值时未带单位,则按千字节解释。默认值为 64 兆字节(64MB)。 - 由于数据库会话一次只能执行一个这样的操作,而一个安装通常也不会有很多此类操作并发运行, - 因此把该值设置得明显大于 work_mem 通常是安全的。更大的设置可能改善清理和恢复数据库转储的性能。 + 指定维护操作(如 VACUUMCREATE INDEXALTER TABLE ADD FOREIGN KEY)可使用的最大内存量。如果未指定单位,则以千字节为单位。默认值为 64 兆字节(64MB)。由于一个数据库会话一次只能执行一个此类操作,而一个数据库系统通常也不会并发运行很多此类操作,因此可以安全地将该值设得远大于 work_mem。更大的设置可能改善清理和恢复数据库转储的性能。 + + + 注意,自动清理运行时,最多可能分配此内存量的 倍,因此不要将默认值设得过高。单独设置 可能有助于控制这一点。 - - 注意当自动清理运行时,可能会分配最多达这个内存的倍,因此要小心不要把该默认值设置得太高。 - 通过独立地设置可能会对控制这种情况 - 有所帮助。 + 注意,在收集死元组标识符时,VACUUM 最多只能使用 1GB 内存。 @@ -1612,15 +1514,13 @@ include_dir 'conf.d' - - 指定每个自动清理工作者进程能使用的最大内存量。 - 如果指定值时没有单位,则以千字节为单位。 - 其默认值为 -1,表示转而使用 的值。 - 当运行在其他上下文环境中时,这个设置对VACUUM的行为没有影响。 - 这个参数只能在postgresql.conf中或者服务器命令行上设置。 + 指定每个自动清理工作进程可使用的最大内存量。如果未指定单位,则以千字节为单位。默认值为 -1,表示改用 的值。该设置不影响其他上下文中运行的 VACUUM 的行为。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 - + + 在收集死元组标识符时,自动清理最多只能使用 1GB 内存,因此将 autovacuum_work_mem 设得更高,不会影响自动清理扫描表时能收集的死元组数量。 + + @@ -1631,13 +1531,7 @@ include_dir 'conf.d' - VACUUMANALYZE命令使用的缓冲区访问策略大小。 - 设置为0将允许操作使用任意数量的shared_buffers。 - 否则,有效范围是 128KB 到 16GB。如果指定的大小超过shared_buffers的 1/8, - 将被静默限制到该值。默认值为 2MB。如果未指定单位,则视为千字节。 - 此参数可随时设置,并且可通过为 - 传递选项来覆盖。较高的设置可以让 - VACUUMANALYZE运行得更快,但设置过大可能会将过多有用页面从共享缓冲区逐出。 + 指定 VACUUMANALYZE 命令使用的缓冲区访问策略的大小。设为 0 时,允许操作使用任意数量的 shared_buffers 缓冲区。否则,有效大小范围为 128 kB16 GB。如果指定的大小超过 shared_buffers 大小的 1/8,则会在不提示的情况下限制为该值。默认值为 256 kB。如果未指定单位,则以千字节为单位。此参数可以随时设置。在执行 时,可以通过 选项覆盖此设置。较大的设置可能使 VACUUMANALYZE 运行得更快,但设置过大可能会将过多其他有用页面逐出共享缓冲区。 @@ -1650,13 +1544,10 @@ include_dir 'conf.d' - - 指定逻辑解码要使用的最大内存量,在将某些解码的更改写入本地磁盘之前。 - 这将限制逻辑流复制连接使用的内存量。它默认为 64 兆字节(64MB)。 - 由于每个复制连接仅使用此大小的单个缓冲区,并且安装通常不会同时具有多个此类连接(受 max_wal_senders 的限制),因此将此值设置得明显高于 work_mem是安全的,从而减少写入磁盘的解码更改数量。 + 指定逻辑解码在将部分已解码的更改写入本地磁盘之前可使用的最大内存量。它限制了流式逻辑复制连接使用的内存量。默认值为 64 兆字节(64MB)。由于每个复制连接仅使用一个此大小的缓冲区,而一个数据库系统通常不会同时有很多此类连接(受 max_wal_senders 限制),因此可以安全地将该值设得远高于 work_mem,以减少写入磁盘的已解码更改数量。 - + @@ -1670,8 +1561,8 @@ include_dir 'conf.d' 指定服务器执行栈的最大安全深度。此参数的理想设置是由内核强制执行的实际栈大小限制 - (如由ulimit -s或本地等效设置),减去大约一兆字节的安全边界。 - 需要安全边界是因为服务器中并非每个例程都检查栈深度,而只在关键的潜在递归例程中检查。 + (如由ulimit -s或本地等效设置),减去大约一兆字节的安全余量。 + 需要安全余量是因为服务器中并非每个例程都检查栈深度,而只在关键的潜在递归例程中检查。 如果未指定单位,则将其视为千字节。默认设置为两兆字节(2MB), 这是保守且不太可能引起崩溃的小值。但是,这可能太小,无法执行复杂函数。 只有超级用户和具有适当SET权限的用户才能更改此设置。 @@ -1691,12 +1582,8 @@ include_dir 'conf.d' - - 指定服务器应用于主共享内存区域的共享内存实现,包括 PostgreSQL 的共享缓冲区和其他共享数据。 - 可能的值为 mmap (对使用 mmap 分配的匿名共享内存),sysv (通过 shmget 分配的系统V 共享内存),和windows (Windows共享内存)。 - 并非在所有平台上都支持全部值;第一个被支持的选项是该平台的默认选项。 - sysv 选项不是任何平台的默认选项,通常不建议使用,因为它通常需要非默认的内核设置来允许大量的地址分配(参见 )。 + 指定服务器用于主共享内存区域的共享内存实现,该区域存放 PostgreSQL 的共享缓冲区及其他共享数据。可选值为 mmap(使用 mmap 分配的匿名共享内存)、sysv(通过 shmget 分配的 System V 共享内存)和 windows(Windows 共享内存)。并非所有平台都支持所有值;第一个受支持的选项是该平台的默认值。sysv 不是任何平台的默认选项,通常不建议使用,因为它一般需要更改内核的默认设置才能分配大量内存(见 )。此参数只能在服务器启动时设置。 @@ -1709,16 +1596,8 @@ include_dir 'conf.d' - - 指定服务器应该使用的动态共享内存实现。可能的值包括posix(使用shm_open分配的POSIX共享内存), - sysv(通过shmget分配的System V共享内存), - windows(用于Windows共享内存), - 和mmap(使用存储在数据目录中的内存映射文件模拟共享内存)。 - 并非所有平台都支持所有值;通常第一个支持的选项是该平台的默认值。 - 通常不建议使用mmap选项,因为操作系统可能会反复将修改的页面写回磁盘,增加系统I/O负载; - 但在调试时,当pg_dynshmem目录存储在RAM磁盘上,或者其他共享内存设施不可用时,可能会有用。 - 该参数只能在服务器启动时设置。 + 指定服务器应使用的动态共享内存实现。可选值为 posix(使用 shm_open 分配的 POSIX 共享内存)、sysv(通过 shmget 分配的 System V 共享内存)、windows(Windows 共享内存)、mmap(使用存放在数据目录中的内存映射文件模拟共享内存)。并非所有平台都支持所有值;第一个受支持的选项通常是该平台的默认值。mmap 不是任何平台的默认选项,通常不建议使用,因为操作系统可能会反复将修改过的页面写回磁盘,增加系统 I/O 负载;不过,在调试、将 pg_dynshmem 目录存放在 RAM 磁盘上,或其他共享内存设施不可用时,它可能有用。此参数只能在服务器启动时设置。 @@ -1731,13 +1610,8 @@ include_dir 'conf.d' - - 指定在服务器启动时将要分配给并行查询使用的内存容量。 - 当此内存区域不够用或被并发查询耗尽时,新的并行查询尝试使用dynamic_shared_memory_type配置的方法从操作系统临时分配额外的共享内存,由于内存管理开销该方法可能慢一些。 - 在启动时由min_dynamic_shared_memory分配的内存受到操作系统上所支持的huge_pages设置的影响,并且在自动管理的操作系统上更可能从较大的页面中受益。 - 默认值是0(无)。 - 该参数只能在服务器启动时设置。 + 指定服务器启动时为并行查询分配的内存量。当此内存区域不足或被并发查询耗尽时,新的并行查询会尝试使用 dynamic_shared_memory_type 配置的方法,临时向操作系统分配额外的共享内存;由于内存管理开销,这可能较慢。在支持 huge_pages 设置的操作系统上,启动时通过 min_dynamic_shared_memory 分配的内存会受到该设置的影响;在自动管理巨型页的操作系统上,这些内存也可能更容易受益于较大的页。默认值为 0(不分配)。此参数只能在服务器启动时设置。 @@ -1758,17 +1632,42 @@ include_dir 'conf.d' - - 指定进程可以用于临时文件(如排序和哈希临时文件)或保留游标的存储文件的最大磁盘空间。 - 尝试超过此限制的事务将被取消。 - 如果未指定单位,则将其视为千字节。 - -1(默认值)表示没有限制。 - 只有超级用户和具有适当SET权限的用户才能更改此设置。 + 指定一个进程可用于临时文件的最大磁盘空间,例如排序和哈希临时文件,或保留游标的存储文件。尝试超过此限制的事务将被取消。如果未指定单位,则以千字节为单位。-1(默认值)表示没有限制。只有超级用户和具有适当 SET 权限的用户才能更改此设置。 + + 此设置限制单个 PostgreSQL 进程在任意时刻使用的所有临时文件的总空间。需要注意,显式临时表所用的磁盘空间计入该上限;计入的是查询执行过程中内部使用的临时文件。 + + + + + file_extend_method (enum) + + file_extend_method配置参数 + + + - 这个设置约束着一个给定PostgreSQL进程在任何瞬间所使用的所有临时文件的总空间。应该注意的是,与在查询执行中在幕后使用的临时文件相反,显式临时表所用的磁盘空间被这个设置所限制。 + 指定在诸如COPY这类批量操作期间扩展数据文件时所使用的方法。 + 默认会根据操作系统选择第一个可用选项: + + + + posix_fallocate(Unix)使用标准 POSIX 接口分配磁盘空间,但某些系统缺少该接口。 + 如果接口存在但底层文件系统不支持,本选项会静默回退到write_zeros。 + 已知当前版本的 BTRFS 在使用该选项时会禁用压缩。 + 在提供该函数的系统上,这是默认值。 + + + + + write_zeros通过写入全零数据块来扩展文件。 + 在不提供posix_fallocate函数的系统上,这是默认值。 + + + + 当数据文件扩展的块数不超过 8 个时,总是使用write_zeros方法。 @@ -1789,35 +1688,31 @@ include_dir 'conf.d' - - 设置每个服务器子进程允许同时打开的最大文件数。默认值是一千个文件。 - - - 如果内核强制实施了安全的每进程上限,你通常不必担心这个设置。但在某些平台上 - (尤其是大多数 BSD 系统),如果许多进程都尝试打开大量文件,内核可能允许单个进程打开的文件数 - 远超系统在整体上真正能够支持的数量。如果你看到打开的文件过多之类的失败, - 可以尝试减小这个设置。这个参数只能在服务器启动时设置。 + 设置每个服务器子进程允许同时打开的最大文件数量。默认值为一千个文件。如果内核强制实施了安全的每进程上限,就不必担心此设置。但在某些平台上(尤其是大多数 BSD 系统),内核允许单个进程打开的文件数量很大,如果很多进程都尝试打开这么多文件,就会远超系统实际能够支持的总量。如果遇到 Too many open files(打开的文件过多)错误,可尝试减小此设置。此参数只能在服务器启动时设置。 - + 基于代价的清理延迟 - 在命令的执行过程中,系统维持着一个内部计数器来跟踪各种被执行的I/O操作的估算开销。当累计的代价达到一个限制(由vacuum_cost_limit指定),执行这些操作的进程将按照vacuum_cost_delay所指定的休眠一小段时间。然后它将重置计数器并继续执行。 + 执行 命令期间,系统维护一个内部计数器,记录已执行的各种 I/O 操作的估算代价。 + 当累计代价达到上限(由 vacuum_cost_limit 指定)时,执行该操作的进程会休眠一小段时间,时长由 vacuum_cost_delay 指定。 + 随后重置计数器并继续执行。 - 这个特性的出发点是允许管理员降低这些命令对并发的数据库活动产生的I/O影响。在很多情况下,VACUUMANALYZE等维护命令能否快速完成并不重要,而非常重要的是这些命令不会对系统执行其他数据库操作的能力产生显著的影响。基于代价的清理延迟提供了一种方式让管理员能够保证这一点。 + 此功能让管理员能够降低这些命令对并发数据库活动的 I/O 影响。在许多情况下,VACUUMANALYZE 等维护命令是否快速完成并不重要, + 但避免它们显著干扰系统执行其他数据库操作的能力通常很重要。基于代价的清理延迟为管理员提供了实现这一点的方法。 - 对于手动发出的VACUUM命令,该特性默认被禁用。要启用它,只要把vacuum_cost_delay变量设为一个非零值。 + 对于手动执行的 VACUUM 命令,此功能默认禁用。要启用它,将 vacuum_cost_delay 变量设为非零值。 @@ -1829,19 +1724,13 @@ include_dir 'conf.d' - - - 当超出开销限制时进程将要休眠的时间量。如果指定值时没有单位,则以毫秒为单位。 - 其默认值为0,这将禁用基于代价的清理延迟特性。正值将启用基于代价的清理。 - - - - 在使用基于代价的清理时,vacuum_cost_delay的合适值通常很小,也许是小于1毫秒。 - 虽然vacuum_cost_delay可以被设置为毫秒级别的值,但是在较老的平台上可能无法准确地测量这种延迟。 - 在这样的平台上,增加 VACUUM的节流资源消耗在1ms以上,需要改变其他的清理开销参数。 - 尽管如此,你应该保持 vacuum_cost_delay 在平台能持续测量的情况下尽可能小;大延迟没有帮助。 - - + + 超过代价上限后,进程将休眠的时长。如果未指定单位,则以毫秒为单位。默认值为 0,表示禁用基于代价的清理延迟功能。正值会启用基于代价的清理。 + + + 使用基于代价的清理时,vacuum_cost_delay 的合适值通常很小,可能不到 1 毫秒。虽然 vacuum_cost_delay 可以设为以毫秒为单位的小数值,但较旧的平台可能无法准确计量这种延迟。在这些平台上,若要让 VACUUM 的资源用量超过延迟设为 1ms 时的水平,需要调整其他清理代价参数。尽管如此,仍应将 vacuum_cost_delay 设为平台能够稳定计量的尽可能小的值;较大的延迟没有帮助。 + + @@ -1852,11 +1741,10 @@ include_dir 'conf.d' - - - 清理一个在共享缓存中找到的缓冲区的估计代价。它表示锁住缓冲池、查找共享哈希表和扫描页内容的代价。默认值为1。 - - + + 清理在共享缓冲区缓存中找到的缓冲区时所计入的估算代价。它表示锁定缓冲池、查找共享哈希表和扫描页内容的代价。默认值为 1。 + + @@ -1867,13 +1755,10 @@ include_dir 'conf.d' - - - 清理一个必须从磁盘上读取的缓冲区的代价。 - 它表示锁住缓冲池、查找共享哈希表、从磁盘读取需要的块以及扫描其内容的代价。 - 默认值为2。 - - + + 清理必须从磁盘读取的缓冲区时所计入的估算代价。它表示锁定缓冲池、查找共享哈希表、从磁盘读取所需数据块并扫描其内容所需的工作量。默认值为 2。 + + @@ -1884,11 +1769,10 @@ include_dir 'conf.d' - - - 当清理修改一个之前干净的块时需要花费的估计代价。它表示再次把脏块刷出到磁盘所需要的额外I/O。默认值为20。 - - + + 清理操作修改原本干净的数据块时所计入的估算代价。它表示再次将脏块刷盘所需的额外 I/O。默认值为 20。 + + @@ -1899,33 +1783,31 @@ include_dir 'conf.d' - - - 将导致清理进程休眠的累计代价。默认值为200。 - - + + 会使清理进程休眠的累计代价。默认值为 200。 + + - - 有些操作会保持关键性的锁,这样可以尽快完成。基于代价的清理延迟在这类操作期间不会发生。因此有可能代价会累计至大大超过指定的限制。为了防止在这种情况下的无意义的长时间延迟,实际延迟的计算方式是vacuum_cost_delay * - accumulated_balance / - vacuum_cost_limit,且最大值是vacuum_cost_delay * 4。 + 某些操作持有关键的锁,因此应尽快完成。这些操作期间不会发生基于代价的清理延迟,所以累计代价可能远超指定上限。 + 为避免此时出现无益的长时间延迟,实际延迟按 vacuum_cost_delay * accumulated_balance / vacuum_cost_limit 计算, + 但最大不超过 vacuum_cost_delay * 4。 - 后台写入器 - 有一个独立的服务器进程,叫做后台写入器,它的功能就是发出写(新的或修改过的)共享缓冲区的命令。 - 当干净的共享缓存数量出现不足时,后台写入器写入一些脏缓存到文件系统,并标记为干净。 - 不过,后台写入器确实会增加 I/O 的总负荷,因为虽然在每个检查点间隔中一个重复弄脏的页面可能只会写出一次,但在同一个间隔中后台写入器可能会把它写出好几次。 - 在这一小节讨论的参数可以被用于调节本地需求的行为。 + 有一个独立的服务器进程,称为后台写入器,负责写出(新的或修改过的)共享缓冲区。 + 当干净的共享缓冲区数量似乎不足时,后台写入器会将一些脏缓冲区写入文件系统,并将其标记为干净。 + 这可以降低处理用户查询的服务器进程找不到干净缓冲区、因而不得不自行写出脏缓冲区的可能性。 + 不过,后台写入器确实会使总体 I/O 负载有所增加:反复变脏的页面原本可能在每个检查点间隔中只写出一次, + 而后台写入器可能在同一间隔内随着它变脏而多次写出。本节参数可用于根据实际需求调整此行为。 @@ -1937,13 +1819,10 @@ include_dir 'conf.d' - - - 指定后台写入器活动轮次之间的延迟。在每个轮次中,写入器都会为一定数量的脏缓冲区发出写操作(可以用下面的参数控制)。 - 然后它就休眠 bgwriter_delay的时长, 然后重复动作。当缓冲池中没有脏缓冲区时,不管 bgwriter_delay,它都会进入更长的休眠。如果指定值时没有单位,则以毫秒为单位。默认值是 200 毫秒(200ms)。 - 注意在许多系统上,休眠延迟的有效解析度是 10 毫秒;因此,为bgwriter_delay设置一个 不是 10 的倍数的值与把它设置为下一个更高的 10 的倍数是一样的效果。这个选项只能在服务器命令行上或者在postgresql.conf文件中设置。 - - + + 指定后台写入器各轮活动之间的延迟。每一轮中,写入器会对一定数量的脏缓冲区发出写操作(由下面的参数控制),然后休眠 bgwriter_delay 指定的时长,再重复此过程。不过,当缓冲池中没有脏缓冲区时,它会进入更长的休眠,而不受 bgwriter_delay 限制。如果未指定单位,则以毫秒为单位。默认值为 200 毫秒(200ms)。注意,在许多系统上,休眠延迟的有效分辨率为 10 毫秒;将 bgwriter_delay 设为不是 10 的倍数的值,可能与将它设为下一个更大的 10 的倍数效果相同。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 + + @@ -1954,11 +1833,10 @@ include_dir 'conf.d' - - - 在每个轮次中,不超过这么多个缓冲区将被后台写入器写出。把这个参数设置为零可禁用后台写出(注意被一个独立、专用辅助进程管理的检查点不受影响)。默认值是 100 个缓冲区。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 - - + + 后台写入器每轮写出的缓冲区数量不会超过此值。设为零会禁用后台写入。(由另一个独立的专用辅助进程管理的检查点不受影响。)默认值为 100 个缓冲区。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 + + @@ -1969,11 +1847,10 @@ include_dir 'conf.d' - - - 每一轮次要写的脏缓冲区的数目基于最近几个轮次中服务器进程需要的新缓冲区的数目。 最近所需的平均值乘以bgwriter_lru_multiplier可以估算下一轮次中将会需要的缓冲区数目。脏缓冲区将被写出直到有很多干净可重用的缓冲区(然而,每一轮次中写出的缓冲区数不超过bgwriter_lru_maxpages)。 因此,设置为 1.0 表示一种刚刚好的策略,这种策略会写出正好符合预测值的数目的缓冲区。 更大大的值可以为需求高峰提供某种缓冲,而更小的值则需要服务进程来处理一些写出操作。默认值是 2.0。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 - - + + 每轮写出的脏缓冲区数量取决于最近几轮服务器进程所需的新缓冲区数量。将近期平均需求乘以 bgwriter_lru_multiplier,即可估算下一轮所需的缓冲区数量。写入器会写出脏缓冲区,直到可用的干净且可重用缓冲区达到这一数量。(不过,每轮写出的缓冲区数量不会超过 bgwriter_lru_maxpages。)因此,设为 1.0 表示采用恰好及时策略,写出的缓冲区数量恰好等于预测需求量。更大的值可为需求突增留出余量,而更小的值则有意将部分写操作留给服务器进程执行。默认值为 2.0。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 + + @@ -1984,24 +1861,21 @@ include_dir 'conf.d' - - - 只要后台写入的数据超过这个数量,尝试强制 OS 把这些写发送到底层存储上。这样做将限制内核页缓存中脏数据的量,降低了在检查点末尾发出一个 fsync 时或者 OS 在后台大批量写回数据时卡住的可能性。 - 那常常会导致大幅度压缩的事务延迟,但是也有一些情况(特别是负载超过但小于 OS 页面高速缓存)的性能会降低。这种设置可能会在某些平台上没有效果。 - 如果指定值时没有单位,则以块为单位,即为BLCKSZ 字节,通常为8kB.合法的范围在0(禁用受控写回)和2MB之间。Linux 上的默认值是512kB,其他平台上是0(如果BLCKSZ不是8kB,则默认值和最大值会按比例缩放至这个值)。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 - - + + 每当后台写入器写出的数据超过此数量时,就尝试强制操作系统将这些写操作发往底层存储。这样可以限制内核页缓存中的脏数据量,降低在检查点结束时调用 fsync,或操作系统在后台以较大批次写回数据时发生停顿的可能性。通常,这能大幅降低事务延迟,但在某些情况下性能可能下降,尤其是工作负载大于 而小于操作系统页缓存时。此设置在某些平台上可能没有效果。如果未指定单位,则以块为单位,即 BLCKSZ 字节,通常为 8kB。有效范围为 0(禁用强制写回)至 2MB。Linux 上的默认值为 512kB,其他平台为 0。(如果 BLCKSZ 不是 8kB,默认值和最大值将按比例变化。)此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 + + - 较小的bgwriter_lru_maxpagesbgwriter_lru_multiplier可以降低由后台写入器造成的额外 I/O 开销。但更可能的是,服务器进程将必须自己发出写入操作,这会延迟交互式查询。 + 较小的 bgwriter_lru_maxpagesbgwriter_lru_multiplier 可以降低后台写入器造成的额外 I/O 负载, + 但也会增加服务器进程必须自行发出写操作的可能性,从而延迟交互式查询。 - - 异步行为 + 异步行为<anchor id="runtime-config-resource-worker-processes" xreflabel="工作进程"/> @@ -2012,19 +1886,10 @@ include_dir 'conf.d' - - - 当单个后端写入的数据量超过这个数量时,尝试强制操作系统把这些写入发送到底层存储。 - 这样做将限制内核页缓存中的脏数据量,降低在检查点结束时发出 fsync - 或者操作系统在后台成批写回数据时发生停顿的可能性。通常这会显著降低事务延迟, - 但在某些场景下,尤其是工作负载大于 , - 但小于操作系统页缓存时,性能可能会下降。该设置在某些平台上可能无效。 - 如果未指定单位,则按块计,即 BLCKSZ 字节,通常为 8kB。 - 有效范围是从 0(禁用强制回写)到 2MB。 - 默认值为 0,也就是不强制回写。(如果 BLCKSZ - 不是 8kB,则最大值按比例缩放。) - - + + 每当单个后端写出的数据超过此数量时,就尝试强制操作系统将这些写操作发往底层存储。这样可以限制内核页缓存中的脏数据量,降低在检查点结束时调用 fsync,或操作系统在后台以较大批次写回数据时发生停顿的可能性。通常,这能大幅降低事务延迟,但在某些情况下性能可能下降,尤其是工作负载大于 而小于操作系统页缓存时。此设置在某些平台上可能没有效果。如果未指定单位,则以块为单位,即 BLCKSZ 字节,通常为 8kB。有效范围为 0(禁用强制写回)至 2MB。默认值为 0,即不强制写回。(如果 BLCKSZ 不是 8kB,最大值将按比例变化。) + + @@ -2035,59 +1900,38 @@ include_dir 'conf.d' - - - 设置 PostgreSQL 预期能够同时执行的磁盘 I/O 操作数量。 - 增大该值会增加单个 PostgreSQL 会话尝试并行发起的 I/O 操作数。 - 允许范围为 1 到 1000,或者 0 表示禁用异步 I/O 请求。目前这个设置只影响位图堆扫描。 - - - - 对磁盘阵列来说,一个合适的起点通常是组成 RAID 0 条带或 RAID 1 镜像的磁盘数量。 - (对于 RAID 5,不应计入奇偶校验盘。)不过,如果数据库经常被多个并发会话同时访问, - 较小的值也可能足以让磁盘阵列保持忙碌。高于所需值只会带来额外的 CPU 开销。 - SSD 和其他基于内存的存储通常可以处理很多并发请求,因此最佳值可能高达数百。 - - - - 异步 I/O 依赖于有效的 posix_fadvise 函数,而某些操作系统并不提供它。 - 如果该函数不存在,那么把此参数设为非零值会导致错误。在某些操作系统上(例如 Solaris), - 虽然函数存在,但实际上并不做任何事情。 - - - - 支持该特性的系统上默认值为 1,否则为 0。这个值可以通过在某个表空间中设置同名表空间参数来覆盖 - (见 )。 - - + + 设置 PostgreSQL 预期可以同时执行的并发磁盘 I/O 操作数量。提高此值会增加单个 PostgreSQL 会话尝试并行发起的 I/O 操作数量。允许的范围为 1 至 1000,或设为零以禁用异步 I/O 请求。目前,此设置仅影响位图堆扫描。 + + + 对于磁盘,可以将为数据库提供存储的 RAID 0 条带或 RAID 1 镜像中的独立磁盘数量作为合理初始值。(对于 RAID 5,不应计入校验盘。)不过,如果数据库经常忙于执行并发会话发出的多个查询,较小的值可能就足以使磁盘阵列保持繁忙。超过使磁盘保持繁忙所需的值只会增加 CPU 开销。SSD 和其他基于内存的存储通常可以处理大量并发请求,因此最佳值可能达到数百。 + + + 异步 I/O 依赖于有效的 posix_fadvise 函数,而某些操作系统缺少此函数。如果该函数不存在,将此参数设为任何非零值都会报错。在某些操作系统(如 Solaris)上,该函数虽然存在,却实际上不做任何事情。 + + + 支持此功能的系统上默认值为 1,其他系统为 0。对于位于特定表空间中的表,可以通过设置同名的表空间参数覆盖此值(见 )。 + + - - - maintenance_io_concurrency (integer) - - maintenance_io_concurrency配置参数 - - - - - - 与 effective_io_concurrency 类似,但用于许多客户端会话共同执行的维护工作。 - - - - 支持该特性的系统上默认值为 10,否则为 0。这个值可以通过在某个表空间中设置同名表空间参数来覆盖 - (见 )。 - - - - - + - - 工作进程 + maintenance_io_concurrency (integer) + + maintenance_io_concurrency配置参数 + + + + + 与 effective_io_concurrency 类似,但用于为多个客户端会话执行的维护工作。 + + + 支持此功能的系统上默认值为 10,其他系统为 0。对于位于特定表空间中的表,可以通过设置同名的表空间参数覆盖此值(见 )。 + + + - max_worker_processes (integer) @@ -2096,22 +1940,16 @@ include_dir 'conf.d' - - - 设置系统能够支持的后台进程的最大数量。这个参数只能在服务器启动时设置。默认值为 8。 - - - - 在运行一个备库时,你必须把这个参数设置为等于或者高于主库上的值。 - 否则,备库上可能不会允许查询。 - - - - 在更改这个值时,考虑也对、 - 以及 - 进行调整。 - - + + 设置系统能够支持的后台进程的最大数量。此参数只能在服务器启动时设置。默认值为 8。 + + + 运行备库时,必须将此参数设为与主库相同或更大的值。否则,备库上将不允许执行查询。 + + + 更改此值时,也应考虑调整 、&zwsp;、&zwsp;。 + + @@ -2122,19 +1960,16 @@ include_dir 'conf.d' - - - 设置单个Gather或者Gather Merge节点能够开始的工作者的最大数量。并行工作者会从建立的进程池中取得,数量由限制。注意所要求的工作者数量在运行时可能实际无法被满足。如果这种事情发生,该计划将会以比预期更少的工作者运行,这可能会不太高效。默认值是2。把这个值设置为0将会禁用并行查询执行。 - - - - 注意并行查询可能消耗比非并行查询更多的资源,因为每一个工作者进程是一个完全独立的进程,它对系统产生的影响大致和一个额外的用户会话相同。在为这个设置选择值时,以及配置其他控制资源利用的设置(例如)时,应该把这个因素考虑在内。work_mem之类的资源限制会被独立地应用于每一个工作者,这意味着所有进程的总资源利用可能会比单个进程时高得多。例如,一个使用 4 个工作者的并行查询使用的 CPU 时间、内存、I/O 带宽可能是不使用工作者时的 5 倍之多。 - - - - 并行查询的更多信息请见。 - - + + 设置单个 GatherGather Merge 节点能够启动的工作进程的最大数量。并行工作进程取自 建立的进程池,并受到 的限制。注意,运行时实际可用的工作进程可能不足请求的数量。此时,计划会使用少于预期的工作进程运行,效率可能较低。默认值为 2。设为 0 会禁用并行查询执行。 + + + 注意,并行查询消耗的资源可能远多于非并行查询,因为每个工作进程都是完全独立的进程,对系统的影响大致相当于额外增加一个用户会话。选择此设置的值,以及配置其他控制资源使用的设置(如 )时,都应考虑这一点。work_mem 等资源限制分别应用于每个工作进程,因此所有进程的总资源用量可能远高于单个进程通常的用量。例如,使用 4 个工作进程的并行查询,其 CPU 时间、内存、I/O 带宽等用量可能达到完全不使用工作进程的查询的 5 倍。 + + + 并行查询的更多信息参见 。 + + @@ -2145,18 +1980,13 @@ include_dir 'conf.d' - - - 设置单一工具性命令能够启动的并行工作者的最大数目。 - 当前,支持使用并行工作者的工具性命令是CREATE INDEX,并且只有在构建B-树索引时才能并行,并且 VACUUM 没有 FULL选项。 - 并行工作者从由创建的进程池中取出,数量由控制。 - 注意实际在运行时所请求数量的工作者可能不可用。如果发生这种情况,工具性操作将使用比预期数量少的工作者运行。默认值为2。将这个值设置为0可以禁用工具性命令对并行工作者的使用。 - - - - 注意并行工具性命令不应该消耗比同等数量非并行操作更多的内存。这种策略与并行查询不同,并行查询的资源限制通常是应用在每个工作者进程上。并行工具性命令把资源限制maintenance_work_mem当作对整个工具性命令的限制,而不管其中用到了多少个并行工作者进程。不过,并行工具性命令实际上可能仍会消耗更多的CPU资源和I/O带宽。 - - + + 设置单个工具命令能够启动的并行工作进程的最大数量。目前,支持使用并行工作进程的工具命令包括:构建 B-树索引时的 CREATE INDEX,以及不带 FULL 选项的 VACUUM。并行工作进程取自 建立的进程池,并受到 的限制。注意,运行时实际可用的工作进程可能不足请求的数量。此时,工具操作会使用少于预期的工作进程运行。默认值为 2。设为 0 会禁止工具命令使用并行工作进程。 + + + 注意,并行工具命令的内存消耗不应明显高于等效的非并行操作。这与并行查询的策略不同,后者的资源限制通常分别应用于每个工作进程。并行工具命令将 maintenance_work_mem 视为整个工具命令的资源上限,而不论使用多少个并行工作进程。不过,并行工具命令仍可能消耗多得多的 CPU 资源和 I/O 带宽。 + + @@ -2167,17 +1997,74 @@ include_dir 'conf.d' + + 设置系统能够为并行操作提供的工作进程的最大数量。默认值为 8。增大或减小此值时,也应考虑调整 。此外,将此值设得大于 没有效果,因为并行工作进程取自该设置建立的工作进程池。 + + + + + + + parallel_leader_participation (boolean) + + parallel_leader_participation 配置参数 + + + + + 允许领导者进程执行 GatherGather Merge 节点下的查询计划,而不是等待工作进程。默认值为 on。将此值设置为 off,可以降低工作进程因领导者读取元组不够快而被阻塞的可能性,但在产生第一批元组之前,领导者进程必须等待工作进程启动。领导者对性能的帮助或妨碍程度取决于计划类型、工作进程数量和查询持续时间。 + + + - - 设置系统为并行操作所支持的工作者的最大数量。默认值为8。 - 在增加或者减小这个值时,也要考虑对以及进行调整。 - 此外,要注意将这个值设置得大于将不会产生效果,因为并行工作者进程都是从所建立的工作者进程池中取出来的。 - - + + old_snapshot_threshold (integer) + + old_snapshot_threshold 配置参数 + + + + + 设置查询快照在使用时不发生snapshot too old错误的最短可用时间。 + 已死亡超过该阈值的数据允许被清理掉。这有助于在快照长期保持使用时防止膨胀。 + 为了避免因清理本应对该快照可见的数据而得到错误结果,当快照年龄超过该阈值, + 并且该快照被用于读取某个自其建立以来已被修改过的页面时,就会报错。 + + + + 如果指定值时没有单位,则以分钟为单位。值为 -1 + (默认值)会禁用此特性,相当于把快照年龄上限设为无穷大。 + 该参数只能在服务器启动时设置。 + + + + 对生产环境而言,有用的取值大概从几个小时到几天不等。较小的值 + (例如 01min)之所以被允许, + 只是因为它们有时可用于测试。虽然允许设置到 60d 这么高, + 但请注意,在许多工作负载中,严重膨胀或事务 ID 回卷可能会在更短时间内发生。 + + + + 启用此特性后,关系末尾释放出来的空间将不能返还给操作系统,因为那样可能会移除 + 检测snapshot too old条件所需的信息。分配给某个关系的全部空间都会一直 + 归属于该关系,只能在该关系内部重用,除非显式释放(例如使用 + VACUUM FULL)。 + + + + 该设置并不尝试保证在任何特定情况下都一定会产生错误。实际上,如果仍能从 + 某个对象(例如已经物化结果集的游标)生成正确结果,那么即使被引用表中的底层行 + 已经被清理掉,也不会报错。有些表不能安全地提前清理,因此不会受此设置影响, + 例如系统目录。对这类表来说,此设置既不会减少膨胀,也不会在扫描时引入 + snapshot too old错误的可能性。 + + + + @@ -2207,7 +2094,7 @@ include_dir 'conf.d' - minimal级别生成最少的WAL日志量。它不记录在创建或重写事务中对永久关系的行信息。 + minimal级别生成最少的WAL日志量。对于在当前事务中创建或重写的永久关系,不记录其行信息。 这可以使操作速度更快(参见)。触发此优化的操作包括: ALTER ... SET TABLESPACE @@ -2218,15 +2105,15 @@ include_dir 'conf.d' REINDEX TRUNCATE - 然而,最小的WAL不包含足够的信息用于时点恢复,因此必须使用replica或更高级别来启用持续归档 + 然而,minimal 级别的 WAL 不包含足够的信息用于时间点恢复,因此必须使用replica或更高级别来启用持续归档 ()和流式二进制复制。 实际上,如果max_wal_senders不为零,服务器甚至不会以此模式启动。 - 请注意,将wal_level更改为minimal会使先前的基本备份无法用于时点恢复和备库。 + 请注意,将wal_level更改为minimal会使先前的基础备份无法用于时间点恢复和备库。 logical级别上,记录与replica相同的信息,以及从WAL中提取逻辑变更集所需的信息。 - 使用logical级别会增加WAL的容量,特别是如果许多表被配置为REPLICA IDENTITY FULL, + 使用logical级别会增加 WAL 的数量,特别是如果许多表被配置为REPLICA IDENTITY FULL, 并且执行了许多UPDATEDELETE语句。 @@ -2254,16 +2141,15 @@ include_dir 'conf.d' - 能安全关闭fsync的环境的示例包括从一个备份文件中初始加载一个新数据库集簇、使用一个数据库集簇来在数据库被删掉并重建之后处理一批数据,或者一个被经常重建并却不用于失效备援的只读数据库克隆。单独的高质量硬件不足以成为关闭fsync的理由。 + 可以安全关闭fsync的情形包括:从备份文件初始装载一个新数据库集簇;用数据库集簇处理一批数据,处理后就丢弃并重建该数据库;或者使用经常重建且不用于故障切换的只读数据库克隆。仅有高质量硬件不足以成为关闭fsync的理由。 - 当把fsync从关闭改成打开时,为了可靠的恢复,需要强制在内核中的所有被修改的缓冲区进入持久化存储。这可以在多个时机来完成: - 在集簇被关闭时或在fsync因为运行initdb --sync-only而打开时、运行sync时、卸载文件系统时或者重启服务器时。 + 为确保将fsync从关闭改为打开后能够可靠恢复,必须将内核中所有已修改的缓冲区强制写入持久存储。可以在集簇已关闭或fsync已开启时,通过运行initdb --sync-only、运行sync、卸载文件系统或重启服务器来完成。 - 在很多情况下,为不重要的事务关闭可以提供很多关闭fsync的潜在性能收益,并不会有的同时, 关闭fsync可以提供很多潜在的性能优势,而不会有伴随着的数据损坏风险。 + 在很多情况下,为非关键事务关闭,可以获得关闭fsync所带来的大部分潜在性能收益,同时避免伴随的数据损坏风险。 @@ -2282,44 +2168,32 @@ include_dir 'conf.d' - 指定数据库服务器返回success指示给客户端之前,必须要完成多少WAL处理。 - 合法的值为remote_apply, on(默认值), remote_write,local, 和 off。 + 指定数据库服务器向客户端返回成功指示之前,必须完成多少 WAL 处理。有效值为remote_applyon(默认值)、remote_writelocaloff - 如果synchronous_standby_names为空,则唯一有意义的设置为onoff ; - remote_applyremote_writelocal都提供与on相同的本地同步级别。 - 所有非off模式的本地行为都是等待WAL的本地刷新到磁盘。 - 在 off模式,无需等待,因此在向客户端报告成功和以后保证事务安全防止服务器崩溃之间可能会出现延迟。 - 当设置为off时,在向客户端报告成功和真正保证事务不会被服务器崩溃威胁之间会有延迟(最大的延迟是的三倍)。 - 不同于,将这个参数设置为off不会产生数据库不一致性的风险:一个操作系统或数据库崩溃可能会造成一些最近据说已提交的事务丢失,但数据库状态是一致的,就像这些事务已经被干净地中止。 - 因此,当性能比完全确保事务的持久性更重要时,关闭synchronous_commit可以作为一个有效的代替手段。更多讨论见。 + 如果synchronous_standby_names为空,只有onoff两种设置有意义;remote_applyremote_writelocal提供的本地同步级别都与on相同。所有非off模式在本地都会等待 WAL 刷写到磁盘。在off模式下则无需等待,因此,向客户端报告成功后,可能还要经过一段时间,才能保证事务不会因服务器崩溃而丢失。(最大延迟为的三倍。)与不同,将此参数设为off不会带来数据库不一致的风险:操作系统或数据库崩溃可能会使一些最近报告已提交的事务丢失,但数据库状态会与这些事务已正常中止时完全相同。因此,当性能比完全确保事务持久性更重要时,关闭synchronous_commit可以是一种有用的替代方案。更多讨论见 - 如果为非空,synchronous_commit也控制是否事务提交将等待它们的 WAL 记录在备库上被处理。 + 如果非空,synchronous_commit还控制事务提交是否等待备库处理其 WAL 记录。 - 当设置为 remote_apply 时,提交将等待,直到来自当前同步备库的答复显示他们已收到事务的提交记录并应用了它,以便它变得对备库上的查询可见,并写入备库上的持久存储。 - 这将导致比以前的设置更大的提交延迟,因为它等待 WAL 重放(replay)。 - 当设置为on时,提交将等待,直到来自于当前同步的备库的回复显示它们已经收到了事务的提交记录并将其刷入了磁盘。 - 这保证事务将不会被丢失,除非主库和所有同步备库都遭受到了数据库存储损坏的问题。 - 当这个参数被设置为remote_write时,提交将等待,直到来自当前的同步备库的回复指示它们已经收到了该事务的提交记录并且已经把该记录写到它们的文件系统,这种设置保证数据得以保存,在PostgreSQL的备库实例崩溃时,但是不能保证备库遭受操作系统级别崩溃时数据能被保持,因为数据不一定必须要在备库上达到持久存储。 - 设置local会导致提交等待本地刷写到磁盘,而不是复制。在使用同步复制时这通常是不可取的,但是为了完整性提供了这个选项。 + 设为remote_apply时,提交会等待当前同步备库回复,确认已收到并应用该事务的提交记录,使其对备库上的查询可见,并且已将其写入备库的持久存储。由于需要等待 WAL 重放,这会比之前的设置产生大得多的提交延迟。设为on时,提交会等待当前同步备库回复,确认已收到事务的提交记录,并已将其刷写到持久存储。这能保证事务不会丢失,除非主库和所有同步备库的数据库存储都损坏。设为remote_write时,提交会等待当前同步备库回复,确认已收到事务的提交记录,并已将其写入各自的文件系统。此设置能保证备库上的PostgreSQL实例崩溃时数据不丢失,但不能保证备库发生操作系统级别崩溃时数据不丢失,因为数据未必已写入备库的持久存储。设为local时,提交会等待本地刷盘,但不等待复制。使用同步复制时通常不希望采用这种设置,提供它是为了使选项完整。 - 这个参数可以随时被修改;任何一个事务的行为由其提交时生效的设置决定。因此,可以同步提交一些事务,同时异步提交其他事务。例如,当默认是相反时,实现一个单一多语句事务的异步提交,在事务中发出SET LOCAL synchronous_commit TO OFF。 + 此参数可以随时更改;每个事务的行为由提交时生效的设置决定。因此,让一些事务同步提交、另一些事务异步提交是可行且有用的。例如,当默认设置要求同步提交时,可以在一个包含多条语句的事务中执行SET LOCAL synchronous_commit TO OFF,使该事务异步提交。 - 概括了 synchronous_commit 设置的能力. + 汇总了synchronous_commit各种设置具备的能力。 - synchronous_commit Modes + synchronous_commit 模式 @@ -2329,10 +2203,10 @@ include_dir 'conf.d' - synchronous_commit setting - local durable commit - PG 崩溃备库持久提交 - OS 崩溃备库持久提交 + synchronous_commit 设置 + 本地提交持久性 + PG 崩溃后备库提交持久性 + OS 崩溃后备库提交持久性 备库查询一致性 @@ -2396,7 +2270,7 @@ include_dir 'conf.d' - 用来向强制 WAL 更新到磁盘的方法。如果fsync是关闭的,那么这个设置就不相关,因为 WAL 文件更新将根本不会被强制。可能的值是: + 用于将 WAL 更新强制写入磁盘的方法。如果fsync关闭,此设置就没有作用,因为 WAL 文件更新根本不会被强制写入磁盘。可选值为: @@ -2420,7 +2294,7 @@ include_dir 'conf.d' - fsync_writethrough(在每次提交时调用fsync(),强制任何磁盘写高速缓存的直通写) + fsync_writethrough(在每次提交时调用fsync(),强制穿透任何磁盘写缓存) @@ -2432,10 +2306,9 @@ include_dir 'conf.d' - open_* 选项也可以使用O_DIRECT(如果可用)。 不是在所有平台上都能使用所有这些选择。 - 默认值是列表中第一个被平台支持的那个, 不过fdatasync是 Linux和FreeBSD中的默认值。 - 默认值不一定是最理想的;有可能需要修改这个设置或系统配置的其他方面来创建一个崩溃-安全的配置,或达到最佳性能。 + 默认值是列表中第一个被平台支持的那个, 不过fdatasync是 Linux 和 FreeBSD 中的默认值。 + 默认值不一定最合适;可能需要更改此设置或系统配置的其他方面,以确保崩溃时的数据安全或达到最佳性能。 这些方面在中讨论。 这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 @@ -2452,11 +2325,11 @@ include_dir 'conf.d' - 当这个参数为打开时,PostgreSQL服务器在一个检查点之后的页面的第一次修改期间将每个页面的全部内容写到 WAL 中。这么做是因为在操作系统崩溃期间正在处理的一次页写入可能只有部分完成,从而导致在一个磁盘页面中混合有新旧数据。在崩溃后的恢复期间,通常存储在 WAL 中的行级改变数据不足以完全恢复这样一个页面。存储整页镜像可以保证页面被正确存储,但代价是增加了必须被写入 WAL 的数据量(因为 WAL 重放总是从一个检查点开始,所以在检查点后每个页面的第一次改变时这样做就够了。因此,一种减小全页面写开销的方法是增加检查点间隔参数值)。 + 启用此参数时,PostgreSQL服务器会在检查点之后首次修改每个磁盘页面时,将该页面的全部内容写入 WAL。这样做是因为,操作系统崩溃时正在进行的页面写入可能只完成了一部分,导致磁盘页面混有新旧数据。通常存储在 WAL 中的行级变更数据不足以在崩溃恢复时完整还原这样的页面。保存整页镜像能保证正确恢复页面,但会增加必须写入 WAL 的数据量。(由于 WAL 重放总是从检查点开始,只需在检查点之后首次修改每个页面时这样做。因此,减少整页写入开销的一种方法是增大检查点间隔参数。) - 把这个参数关闭会加快正常操作,但是在系统失败后可能导致不可恢复的数据损坏,或者静默的数据损坏。其风险类似于关闭fsync, 但是风险较小。并且只有在可关闭fsync的情况下才应该关闭它。 + 关闭此参数可以加快正常操作,但系统故障后可能出现不可恢复的数据损坏或静默数据损坏。风险与关闭fsync类似,虽然较小,但也只有在该参数建议的相同情形下才应关闭此参数。 @@ -2479,7 +2352,7 @@ include_dir 'conf.d' - 当这个参数为on时,PostgreSQL服务器一个检查点之后页面被第一次修改期间把该磁盘页面的整个内容都写入 WAL,即使对所谓的提示位做非关键修改也会这样做。 + 当这个参数为on时,PostgreSQL服务器在检查点之后首次修改页面时把该磁盘页面的整个内容都写入 WAL,即使对所谓的提示位做非关键修改也会这样做。 @@ -2504,9 +2377,8 @@ include_dir 'conf.d' 此参数启用使用指定的压缩方法对WAL进行压缩。 - 启用后,PostgreSQL服务器在 - 打开时或在基本备份期间, - 压缩写入WAL的整页镜像。 + 启用后,PostgreSQL服务器会压缩写入 WAL 的整页镜像,例如 + 在启用时、基础备份期间等。 在WAL重放期间,将对压缩的页镜像进行解压缩。 支持的方法有pglzlz4(如果PostgreSQL @@ -2519,8 +2391,7 @@ include_dir 'conf.d' - 启用压缩可以减少WAL卷的大小,而不会增加不可恢复的数据损坏的风险, - 但会增加在WAL记录期间进行压缩时的额外CPU消耗,以及在WAL重放期间进行解压缩时的成本。 + 启用压缩可以减少 WAL 数据量,而且不会增加不可恢复的数据损坏风险;代价是在记录 WAL 时压缩、重放 WAL 时解压会额外消耗一些 CPU。 @@ -2535,10 +2406,10 @@ include_dir 'conf.d' - 如果设置为on(默认值),此选项会导致新的 WAL 文件被零填充。 - 在某些文件系统上,这可确保在我们需要写入 WAL 记录之前分配空间。 - 但是,Copy-On-Write(COW)文件系统可能不会从此技术中受益,因此可以选择跳过不必要的工作。 - 如果设置为off,则在创建文件时仅写入最终字节,以便其具有预期大小。 + 如果设置为on(默认值),此选项会导致新的 WAL 文件被零填充。 + 在某些文件系统上,这可确保在我们需要写入 WAL 记录之前分配空间。 + 但是,写时复制(COW)文件系统可能不会从此技术中受益,因此可以选择跳过不必要的工作。 + 如果设置为off,则在创建文件时只写入最后一个字节,以便其具有预期大小。 @@ -2553,8 +2424,8 @@ include_dir 'conf.d' - 如果设置为 on (默认值),此选项通过重命名来回收 WAL 文件,从而避免创建新文件。 - 在 COW 文件系统上,创建新文件系统可能更快,因此提供了禁用此行为的选项。 + 如果设置为 on (默认值),此选项通过重命名来回收 WAL 文件,从而避免创建新文件。 + 在 COW 文件系统上,创建新文件可能更快,因此提供了禁用此行为的选项。 @@ -2569,12 +2440,12 @@ include_dir 'conf.d' - 用于还未写入磁盘的 WAL 数据的共享内存量。默认值 -1 选择等于的 1/32 的尺寸(大约3%),但是不小于64kB也不大于 WAL 段的尺寸(通常为16MB)。如果自动的选择太大或太小可以手工设置该值,但是任何小于32kB的正值都将被当作32kB。 + 用于还未写入磁盘的 WAL 数据的共享内存量。默认值 -1 选择等于的 1/32 的尺寸(大约3%),但是不小于64kB也不大于 WAL 段的尺寸(通常为16MB)。如果自动的选择太大或太小可以手工设置该值,但是任何小于32kB的正值都将被当作32kB。 如果指定值时没有单位,则以WAL块作为单位,即为 XLOG_BLCKSZ 字节,通常为8kB。这个参数只能在服务器启动时设置。 - 在每次事务提交时,WAL 缓冲区的内容被写出到磁盘,因此极大的值不可能提供显著的收益。不过,把这个值设置为几个兆字节可以在一个繁忙的服务器(其中很多客户端会在同一时间提交)上提高写性能。由默认设置 -1 选择的自动调节将在大部分情况下得到合理的结果。 + 在每次事务提交时,WAL 缓冲区的内容被写出到磁盘,因此极大的值不太可能带来显著收益。不过,把这个值设置为至少几个兆字节可以在一个繁忙的服务器(其中很多客户端会在同一时间提交)上提高写性能。由默认设置 -1 选择的自动调节将在大部分情况下得到合理的结果。 @@ -2592,9 +2463,9 @@ include_dir 'conf.d' 指定 WAL 写入器刷写 WAL 的频繁程度,以时间为单位。 在刷写WAL之后,写入器将根据wal_writer_delay所给出的时间长度进行睡眠,除非被一个异步提交的事务提前唤醒。 - 如果最近的刷写发生在 wal_writer_delay 之前,并且小于 wal_writer_flush_after WAL的值产生之后,那么WAL只会被写入操作系统,而不会被刷写到磁盘。 + 如果距上次刷盘的时间小于wal_writer_delay,并且自那以后产生的 WAL 数据量小于wal_writer_flush_after,则只将 WAL 写入操作系统,而不刷写到磁盘。 如果指定值时没有单位,则以毫秒作为单位。 - 默认值是 200 毫秒(200ms)。注意在很多系统上,有效的睡眠延迟粒度是 10 毫秒,把wal_writer_delay设置为一个不是 10 的倍数的值,其效果和把它设置为大于该值的下一个 10 的倍数产生的效果相同。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 + 默认值是 200 毫秒(200ms)。注意在很多系统上,有效的睡眠延迟粒度是 10 毫秒,把wal_writer_delay设置为一个不是 10 的倍数的值,其效果可能与将其设置为下一个更大的 10 的倍数相同。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 @@ -2609,8 +2480,8 @@ include_dir 'conf.d' - 指定 WAL 写入器刷写 WAL 的频繁程度,以卷为单位。 - 如果最近的刷写发生在 wal_writer_delay 之前,并且小于 wal_writer_flush_after WAL的值产生之后,那么WAL只会被写入操作系统,而不会被刷写到磁盘。 + 指定 WAL 写入器刷写 WAL 的频繁程度,按数据量衡量。 + 如果距上次刷盘的时间小于wal_writer_delay,并且自那以后产生的 WAL 数据量小于wal_writer_flush_after,则只将 WAL 写入操作系统,而不刷写到磁盘。 如果wal_writer_flush_after被设置为0,则WAL数据总是会被立即刷写。 如果指定值时没有单位,则以WAL块作为单位,即为XLOG_BLCKSZ字节,通常为8kB。 默认是1MB。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 @@ -2628,10 +2499,7 @@ include_dir 'conf.d' - 当wal_levelminimal,并且在创建或重写永久关系之后提交事务时,此设置将确定如何保留新数据。 - 如果数据小于此设置,将其写入 WAL 日志;否则,使用受影响文件的 fsync。 - 根据存储的属性,如果此类提交减慢了并发事务,提高或降低此值可能会有所帮助。 - 如果指定此值时没有单位,则视为千字节。默认为两兆字节(2MB)。 + 当wal_levelminimal,且事务在创建或重写永久关系后提交时,此设置决定如何持久保存新数据。如果数据量小于此设置,就将其写入 WAL;否则,对受影响的文件执行 fsync。如果这类提交拖慢了并发事务,根据存储的特性,增大或减小此值可能有所帮助。未指定单位时以千字节为单位。默认值为两兆字节(2MB)。 @@ -2646,20 +2514,20 @@ include_dir 'conf.d' - 设置commit_delay会在执行WAL刷新之前添加时间延迟。 + 设置commit_delay会在发起 WAL 刷盘之前添加时间延迟。 如果系统负载足够高,使得在给定时间间隔内有更多事务准备提交, - 这可以通过允许更多事务通过单个WAL刷新来提高组提交吞吐量。 - 然而,这也会增加延迟,最多为每个WAL刷新的commit_delay。 - 因为如果没有其他事务准备提交,延迟就是浪费的,所以只有在至少有 - commit_siblings其他事务活动时才会执行延迟, - 当要启动刷新时,如果fsync被禁用,则不会执行延迟。 + 这可以通过允许更多事务通过一次 WAL 刷盘来提高组提交吞吐量。 + 不过,每次 WAL 刷盘的延迟也会因此增加,最多增加commit_delay。 + 如果没有其他事务准备提交,等待就没有意义,因此仅当即将发起刷盘时至少还有 + commit_siblings个其他活动事务,才会等待。 + 此外,如果禁用了fsync,也不会等待。 如果未指定单位,则将其视为微秒。 默认commit_delay为零(无延迟)。 只有超级用户和具有适当SET权限的用户才能更改此设置。 - 在PostgreSQL的 9.3 发布之前,commit_delay的行为不同并且效果更差:它只影响提交,而不是所有 WAL 刷写,并且即使在 WAL 刷写马上就要完成时也会等待一整个配置的延迟。从PostgreSQL 9.3 中开始,第一个准备好刷写的进程会等待配置的间隔,而后续的进程只等到领先者完成刷写操作。 + 在PostgreSQL的 9.3 发布之前,commit_delay的行为不同并且效果更差:它只影响提交,而不是所有 WAL 刷写,并且即使 WAL 刷盘更早完成,也会等待整个配置的延迟时间。从PostgreSQL 9.3 开始,第一个准备好刷写的进程会等待配置的间隔,而后续的进程只等到领先者完成刷写操作。 @@ -2674,7 +2542,7 @@ include_dir 'conf.d' - 在执行commit_delay延迟时,要求的并发活动事务的最小数目。大一些的值会导致在延迟间隔期间更可能有至少另外一个事务准备好提交。默认值是五个事务。 + 执行commit_delay延迟前要求的并发活动事务的最小数目。大一些的值会导致在延迟间隔期间更可能有至少另外一个事务准备好提交。默认值是五个事务。 @@ -2697,7 +2565,7 @@ include_dir 'conf.d' 自动 WAL 检查点之间的最长时间。如果指定值时没有单位,则以秒为单位。 - 合理的范围在 30 秒到 1 天之间。默认是 5 分钟(5min)。增加这个参数的值会增加崩溃恢复所需的时间。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 + 合理的范围在 30 秒到 1 天之间。默认是 5 分钟(5min)。增加这个参数的值可能会增加崩溃恢复所需的时间。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 @@ -2712,11 +2580,11 @@ include_dir 'conf.d' - 指定检查点完成的目标,作为检查点之间总时间的一部分。 - 默认是 0.9,这将把检查点分布在几乎所有可用的时间间隔上,提供公平一致的I/O负载,同时也为检查点完成开销留下了一些时间。 - 减少此参数是不被推荐的,因为这会导致检查点完成得更快。 - 这个造成处于在检查点和下一个计划检查点之间较少IO之后的检查点会有更高的IO比例。 - 这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 + 指定检查点完成所用时间的目标值,以检查点之间总时间的比例表示。 + 默认值为 0.9,这会把检查点工作分散到几乎整个可用间隔内,使 I/O 负载较为平稳, + 同时为检查点完成时的额外工作留出一些时间。不建议减小此参数,因为这样会让检查点更快完成, + 导致检查点期间的 I/O 速率更高,而在检查点完成后到下一个计划检查点开始前的一段时间内 I/O 较少。 + 此参数只能在postgresql.conf文件中或服务器命令行上设置。 @@ -2733,7 +2601,7 @@ include_dir 'conf.d' 当执行检查点时写入的数据量超过此数量时,就尝试强制 OS 把这些写发送到底层存储。 这样做将会限制内核页面高速缓存中的脏数据数量,降低在检查点末尾发出fsync或者 OS 在后台大批量写回数据时被卡住的可能性。 - 那常常会导致大幅度压缩的事务延迟,但是也有一些情况(特别是负载超过但小于 OS 页面高速缓存)的性能会降低。 + 这通常能显著降低事务延迟,但是也有一些情况(特别是负载超过但小于 OS 页面高速缓存)的性能会降低。 这种设置可能会在某些平台上没有效果。 如果指定值时没有单位,则以块为单位,即为BLCKSZ 字节,通常为8kB。 合法的范围在0(禁用强制写回)和2MB之间。Linux 上的默认值是256kB,其他平台上是0(如果BLCKSZ不是8kB,则默认值和最大值会按比例缩放到它)。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 @@ -2813,10 +2681,9 @@ include_dir 'conf.d' 当启用archive_mode时,完成的WAL段会通过设置 或 - 发送到归档存储。除了off, - 要禁用,有两种模式:on和 + 发送到归档存储。除了用于禁用归档的off外,还有两种模式:onalways。在正常操作期间,这两种模式之间没有区别,但当设置为always时, - WAL归档程序在归档恢复或待机模式下也会被启用。在always模式下,从归档中恢复的所有文件 + WAL归档程序在归档恢复或备库模式下也会被启用。在always模式下,从归档中恢复的所有文件 或通过流复制传输的文件将被再次归档。详细信息请参见 @@ -2851,6 +2718,7 @@ include_dir 'conf.d' 这个参数只能在postgresql.conf文件或服务器命令行中设置。 除非在服务器启动时启用了archive_mode并且archive_library设置为空字符串,否则将被忽略。 + 如果archive_commandarchive_library都被设置,则会报错。 如果archive_command是空字符串(默认值),而archive_mode已启用(并且archive_library设置为空字符串), WAL归档将暂时被禁用,但服务器将继续积累WAL段文件,期望很快会提供命令。 将archive_command设置为一个什么都不做但返回true的命令,例如/bin/true(Windows上为REM), @@ -2870,6 +2738,7 @@ include_dir 'conf.d' 用于归档已完成的WAL文件段的库。如果设置为空字符串(默认值),则通过shell进行归档,并使用。 + 如果archive_commandarchive_library都被设置,则会报错。 否则,指定的共享库用于归档。当此参数更改时,postmaster会重新启动WAL归档进程。有关更多信息,请参见 @@ -2889,7 +2758,7 @@ include_dir 'conf.d' - 仅在完成的WAL段中调用。 + 只针对已完成的 WAL 段调用。 因此,如果您的服务器生成的WAL流量较少(或者在这样做时有间歇期),在事务完成和安全记录到归档存储之间可能会有很长的延迟。 为了限制未归档数据的年龄,您可以将archive_timeout设置为强制服务器定期切换到新的WAL段文件。 当此参数大于零时,只要自上次段文件切换以来经过了这段时间,并且存在任何数据库活动,包括单个检查点(如果没有数据库活动,则跳过检查点),服务器将切换到新的段文件。 @@ -2970,8 +2839,8 @@ include_dir 'conf.d' 归档恢复 - configuration - of recovery + 配置 + 恢复 一个备库 @@ -2980,7 +2849,7 @@ include_dir 'conf.d' - Recovery 涵盖使用服务器作为备库或用于执行目标恢复。 + 恢复 涵盖使用服务器作为备库或用于执行目标恢复。 通常情况,备库模式用于提供高可用性和/或读可扩展性,而目标恢复用于从数据丢失中恢复。 @@ -3049,7 +2918,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows 这个信息可以被用来把归档截断为支持从当前恢复重启所需的最小值。 对于单一备库配置,模块常常被用在archive_cleanup_command中,例如: archive_cleanup_command = 'pg_archivecleanup /mnt/server/archivedir %r' - 但是注意,如果多个备库正在从同一个归档目录中恢复,你将需要保证只有当任意服务器都不再需要 WAL 文件时才会删除它们。 + 但是注意,如果多个备库正在从同一个归档目录中恢复,你将需要保证只有当所有服务器都不再需要这些 WAL 文件时才会删除它们。 archive_cleanup_command通常被用于一种温备配置(见)中。 要在该命令中嵌入一个真正的%字符,需要写成%% @@ -3102,7 +2971,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows 默认情况下,恢复将会一直恢复到 WAL 日志的末尾。下面的参数可以被用来指定一个更早的停止点。 在recovery_targetrecovery_target_lsnrecovery_target_namerecovery_target_timerecovery_target_xid中, - 最多只能使用一个,如果在配置文件中使用了多个,将会产生一个错误。这个参数只能在服务器启动时设置。 + 最多只能使用一个,如果在配置文件中使用了多个,将会产生一个错误。这些参数只能在服务器启动时设置。 @@ -3135,7 +3004,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows - 这个参数指定(pg_create_restore_point()所创建)的已命名的恢复点,恢复将进入该恢复点。 + 这个参数指定(pg_create_restore_point()所创建)的已命名的恢复点,恢复将进行到该恢复点。 @@ -3150,7 +3019,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows - 此参数指定恢复将执行的时间戳。精确的停止点还受到得影响。 + 此参数指定恢复要进行到的时间戳。精确的停止点还受到的影响。 @@ -3170,7 +3039,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows - 这个参数指定恢复将进入的事务 ID。记住虽然事务 ID 是在事务开始时顺序分配的,但是事务可能以不同的数字顺序完成。 + 这个参数指定恢复要进行到的事务 ID。记住虽然事务 ID 是在事务开始时顺序分配的,但是事务可能以不同的数字顺序完成。 那些在指定事务之前(也可以包括该事务)提交的事务将被恢复。精确的停止点也受到的影响。 @@ -3186,7 +3055,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows - 此参数指定恢复将继续进行的预写日志位置的LSN。精确的停靠点也受 的影响。 + 此参数指定恢复要进行到的预写日志位置的 LSN。精确的停止点也受 的影响。 使用系统数据类型pg_lsn解析此参数。 @@ -3211,7 +3080,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows 指定我们是否仅在指定的恢复目标之后停止(on),或者仅在恢复目标之前停止(off)。 适用于或者被指定的情况。 - 这个设置分别控制事务是否有准确的目标WAL位置(LSN)、提交时间或事务ID将被包括在该恢复中。默认值为on。 + 这个设置控制恢复是否包含 WAL 位置(LSN)、提交时间或事务 ID 分别恰好等于目标值的事务。默认值为on @@ -3228,7 +3097,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows 指定恢复到一个特定的时间线中。该值可以是数字时间线 ID 或特殊值。 - 值current沿着与执行基本备份时相同的时间线恢复。 + 值current沿着与执行基础备份时相同的时间线恢复。 值latest将恢复到归档中能找到的最新时间线,这在备库中很有用。 latest是默认值。 @@ -3264,14 +3133,14 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows - 使用pause设置的目的是:如果这个恢复目标就是恢复最想要的位置,就允许对数据库执行查询。 + 使用pause设置的目的是允许对数据库执行查询,以检查这个恢复目标是否为最合适的恢复位置。 暂停的状态可以使用pg_wal_replay_resume()(见)继续,这会让恢复终结。 如果这个恢复目标不是想要的停止点,那么关闭服务器,将恢复目标设置改为一个稍后的目标并且重启以继续恢复。 要让实例在想要的重放点那里准备好,shutdown设置可以派上用场。 - 该实例将仍能重放更多 WAL 记录(并且事实上将不得不重放从下一次它被启动后最后一个检查点以来的 WAL 记录)。 + 该实例将仍能重放更多 WAL 记录(并且事实上,下次启动时必须重新回放自上一个检查点以来的 WAL 记录)。 @@ -3282,7 +3151,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows 如果没有设置恢复目标,这个设置没有效果。 如果没有启用pause设置的动作将和shutdown一样。 - 如果在升级期间达到恢复目标,pause 的设置将与 promote的行为相同。 + 如果在备库提升期间达到恢复目标,pause 的设置将与 promote的行为相同。 @@ -3301,7 +3170,15 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows 复制 - 这些设置控制内置流复制特性(见)的行为。服务器将可以是主库或备库。主库能发送数据,而备库总是被复制数据的接收者。当使用级联复制(见)时,备库也可以是发送者,同时也是接收者。这些参数主要用于发送服务器和备库,尽管某些只在主库上有意义。如果有必要,设置可以在集簇中变化而不出问题。 + 这些设置控制内置流复制特性(见)和内置逻辑复制特性(见)的行为。 + + + + 对于流复制,服务器将可以是主库或备库。主库能发送数据,而备库总是被复制数据的接收者。当使用级联复制(见)时,备库也可以是发送者,同时也是接收者。这些参数主要用于发送服务器和备库,尽管某些只在主库上有意义。如果有必要,设置可以在集簇中变化而不出问题。 + + + + 对于逻辑复制发布者(执行CREATE PUBLICATION的服务器)向订阅者(执行CREATE SUBSCRIPTION的服务器)复制数据。服务器也可以同时是发布者和订阅者。注意,下文各节将发布者称为“发送者”。有关逻辑复制配置设置的更多详细信息,请参见 @@ -3323,16 +3200,17 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows - 指定来自备库或流式基础备份客户端的并发连接的最大数量(即同时运行 WAL 发送进程的最大数)。 - 默认值是10。值0意味着禁用复制。 - 突然的流式传输客户端断开连接可能留下一个孤立连接槽(知道达到超时),因此这个参数应该设置得略高于最大客户端连接数,这样断开连接的客户端可以立刻重新连接。 - 这个参数只能在服务器启动时被设置。此外,wal_level必须设置为replica或更高级别以允许来自备库的连接。 + 指定来自备库或流式基础备份客户端的最大并发连接数(即同时运行的 WAL 发送进程的最大数量)。 + 默认值为 10。值 0 表示禁用复制。 + 流式客户端突然断开连接后,可能会留下一个孤立连接槽,直到超时才释放。 + 因此,此参数应设置得略高于预期的最大客户端数,使断开连接的客户端能够立即重新连接。 + 此参数只能在服务器启动时设置。此外,wal_level 必须设置为 + replica 或更高级别,才允许来自备库的连接。 - 在运行一个备库时,你必须把这个参数设置为等于或者高于主库上的值。 - 否则,备库上可能不会允许查询。 - + 运行备库时,必须将此参数设置为大于或等于主库上的值。否则,备库上将不允许查询。 + @@ -3341,6 +3219,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows max_replication_slots (integer) max_replication_slots配置参数 + 在发送服务器上 @@ -3352,6 +3231,9 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows 更高。 + + 请注意,此参数也适用于订阅者端,但含义不同。 + @@ -3411,16 +3293,19 @@ HINT: If it is safe for all REPLICATION users to use this library as an output - 指定在备库需要为流复制获取日志段文件的情况下,pg_wal目录下所能保留的过去日志文件段的最小尺寸。 - 如果一个连接到发送服务器的备库落后了超过wal_keep_size兆字节,发送服务器可以移除一个备库仍然需要的 WAL 段,在这种情况下复制连接将被中断。 - 最终结果是下行连接也将最终失败(不过,如果在使用 WAL 归档,备库可以通过从归档获取段来恢复)。 + 指定在 pg_wal 目录中保留的旧 WAL 文件的最小总量, + 以便备库需要时获取这些文件进行流复制。如果连接到发送服务器的备库落后超过 + wal_keep_size 兆字节,发送服务器可能会移除备库仍需要的 WAL 段, + 从而导致复制连接终止。下游连接最终也会因此失败。 + (不过,如果使用了 WAL 归档,备库可以通过从归档获取该段来恢复。) - 只设置pg_wal中保留的文件段的最小尺寸;系统可能需要为 WAL 归档或从一个检查点恢复保留更多段。 - 如果wal_keep_size为零(默认值), 更多的空间来 存放WAL归档或从一个检查点恢复。 - 如果wal_keep_segments是零(缺省), 系统不会为备库目的保留任何多余的段,因此备库可用的旧 WAL 段的数量是一个上个检查点位置和 WAL 归档状态的函数。 - 如果此值被指定时没有单位,则视为兆字节。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 + 此设置只规定 pg_wal 中保留的段的最小总量;系统可能需要为 WAL 归档 + 或从检查点恢复而保留更多段。如果 wal_keep_size 为零(默认值), + 系统不会为备库额外保留任何段,因此备库可用的旧 WAL 段数取决于前一个检查点的位置 + 和 WAL 归档的状态。如果指定值时没有单位,则按兆字节计算。 + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 @@ -3434,41 +3319,20 @@ HINT: If it is safe for all REPLICATION users to use this library as an output - - 指定在检查点时,replication slots(复制槽)允许在pg_wal目录中保留的WAL文件的最大大小。 - 如果max_slot_wal_keep_size为-1(默认值),复制槽可以保留无限量的WAL文件。否则,如果复制槽的restart_lsn落后于当前LSN超过给定大小, - 使用该槽的备机可能由于所需的WAL文件被删除而无法继续复制。您可以在pg_replication_slots中查看复制槽的WAL可用性。 - 如果未指定单位,则此值将被视为兆字节。此参数只能在postgresql.conf文件或服务器命令行中设置。 - - - - - - idle_replication_slot_timeout (integer) - - idle_replication_slot_timeout配置参数 - - - - - 使保持空闲状态(未被复制连接使用)超过此持续时间的复制槽失效。 - 如果指定值时没有单位,则以秒为单位。零值(默认值)将禁用空闲超时失效机制。 - 该参数只能在postgresql.conf文件中或服务器命令行上设置。 - - - 由于空闲超时导致的槽失效会在检查点期间发生。由于检查点每隔 - checkpoint_timeout触发一次,因此从 - idle_replication_slot_timeout超时到下一个检查点使槽失效之间可能会有一些延迟。 - 若要避免这种延迟,用户可以强制执行检查点,以便及时使不活动的槽失效。槽的不活动时间根据其 - pg_replication_slots.inactive_since值计算。 - - - 请注意,空闲超时失效机制不适用于不保留 WAL 的槽,也不适用于正在从主库同步的备库上的槽 - (即pg_replication_slots.synced - 值为true的备库槽)。已同步的槽总是被视为空闲,因为它们不会执行逻辑解码来生成变更。 - - - + + 指定检查点时复制槽允许在 + pg_wal 目录中保留的 WAL 文件最大总量。 + 如果 max_slot_wal_keep_size 为 -1(默认值),复制槽可以保留无限量的 WAL 文件。 + 否则,如果复制槽的 restart_lsn 落后当前 LSN 超过给定大小,使用该槽的备库可能会 + 因为所需 WAL 文件被移除而无法继续复制。可以在 + pg_replication_slots 中查看复制槽的 WAL 可用情况。 + 如果指定值时没有单位,则按兆字节计算。此参数只能在 + postgresql.conf 文件中或服务器命令行上设置。 + + + + + @@ -3480,14 +3344,14 @@ HINT: If it is safe for all REPLICATION users to use this library as an output - 中断那些停止活动超过这个时间量的复制连接。这对发送服务器检测一个费用服务器崩溃或网络中断有用。 - 如果指定值时没有单位,则以毫秒为单位。默认值是 60 秒。值0将禁用超时机制。 + 终止非活动时间超过此值的复制连接。这有助于发送服务器检测备库崩溃或网络中断。 + 如果指定值时没有单位,则按毫秒计算。默认值为 60 秒。值零禁用超时机制。 - 对于跨越多个地理位置分布的集簇,每个位置使用不同的值可以为集簇管理带来更大的灵活性。 - 对于具有低延迟网络连接的备库,较小的值有助于更快的故障检测; - 对于位于远端位置的具有高延迟网络连接的备库,较大的值有助于更好地判断备库的健康状况。 + 对于跨多个地理位置分布的集簇,在各位置使用不同的值可以提高集簇管理的灵活性。 + 对于网络延迟较低的备库,较小的值有助于更快地检测故障; + 对于地处远端、网络延迟较高的备库,较大的值有助于更准确地判断其健康状况。 @@ -3515,7 +3379,10 @@ HINT: If it is safe for all REPLICATION users to use this library as an output 主库 - 这些参数可以在发送复制数据给一个或多个备库的主库上设置。注意除了这些参数之外,在主库上必须设置合适的,并且也启用可选的 WAL 归档(见)。这些参数值与备库无关,尽管你可能希望为了准备好一个备库转变成主库来设置这些参数。 + 这些参数可以在向一个或多个备库发送复制数据的主库上设置。 + 除这些参数外,还必须在主库上适当设置 , + 也可以选择启用 WAL 归档(见 )。 + 这些参数在备库上的取值不影响备库运行,不过也可以预先设置,以备将来提升为主库。 @@ -3531,15 +3398,17 @@ HINT: If it is safe for all REPLICATION users to use this library as an output 所述,这个参数指定一个支持同步复制的备库的列表。 - 可能会有一个或者多个活动的同步备库,在这些备库确认收到它们的数据之后,等待提交的事务将被允许继续下去。 - 同步备库是那些名字出现在这个列表前面,并且当前已连接并且正在实时流式传输数据(如pg_stat_replication视图中streaming的状态所示)的服务器。 + 将有一个或多个活动的同步备库,在这些备库确认收到它们的数据之后,等待提交的事务将被允许继续下去。 + 同步备库是那些名字出现在这个列表中,并且当前已连接并且正在实时流式传输数据(如pg_stat_replication视图中streaming的状态所示)的服务器。 指定多于一台同步备库可以得到非常高的可用性并且能防止数据丢失。 用于这一目的的备库的名称是其application_name设置,它在备库的连接信息中设置。 - 在物理复制备库的情况下,这应该被设置在primary_conninfo设置中,如果设置了,默认是的设置,否则为 walreceiver。 - 对于逻辑复制,可以在订阅的连接信息中设置。对于其他复制流消费者,请参考其文档。 + 对于物理复制备库,应在 primary_conninfo 设置中指定。 + 若已设置 ,则默认使用其值;否则默认值为 walreceiver。 + 对于逻辑复制,可以在订阅的连接信息中设置,默认值为订阅名称。 + 对于其他复制流消费者,请参考其文档。 @@ -3553,11 +3422,11 @@ ANY num_sync ( num_sync指定一种基于优先的同步复制,并且会让事务提交等待,直到它们的WAL记录被复制到基于优先级选择的num_sync台同步备库上为止。例如,设置FIRST 3 (s1, s2, s3, s4)将导致每次提交都等待来自三台较高优先级的备库的答复,这三台备库将从备库s1s2s3以及s4中选出。在该列表中出现较早的备库将被给予较高的优先级,并且将被考虑为同步备库。列表中出现的其他备库表示潜在的同步备库。如果当前的任何同步备库因为某种原因断开连接,它将立刻被下一个最高优先级的备库替代。关键词FIRST是可选的。 + 关键词FIRST加上num_sync指定一种基于优先级的同步复制,并且会让事务提交等待,直到它们的WAL记录被复制到基于优先级选择的num_sync台同步备库上为止。例如,设置FIRST 3 (s1, s2, s3, s4)将导致每次提交都等待来自三台较高优先级的备库的答复,这三台备库将从备库s1s2s3以及s4中选出。在该列表中出现较早的备库将被给予较高的优先级,并且将被考虑为同步备库。列表中出现的其他备库表示潜在的同步备库。如果当前的任何同步备库因为某种原因断开连接,它将立刻被下一个最高优先级的备库替代。关键词FIRST是可选的。 - 关键词ANY加上num_sync指定一种基于规定数量的同步复制,并且会让事务提交等待,直到它们的WAL记录被复制到所列出备库中的至少num_sync台上为止。例如,设置ANY 3 (s1, s2, s3, s4)将导致每次提交会在收到s1s2s3以及s4中任意三台备库的回答后立刻继续下去。 + 关键词ANY加上num_sync指定一种基于法定人数的同步复制,并且会让事务提交等待,直到它们的WAL记录被复制到所列出备库中的至少num_sync台上为止。例如,设置ANY 3 (s1, s2, s3, s4)将导致每次提交会在收到s1s2s3以及s4中任意三台备库的回答后立刻继续下去。 @@ -3583,7 +3452,7 @@ ANY num_sync ( 参数设置为localoff。 + 如果这里没有指定同步备库名称,那么不启用同步复制并且事务提交将不会等待复制。这是默认的配置。即便当同步复制被启用时,个体事务也可以被配置为不等待复制,做法是将参数设置为localoff @@ -3614,25 +3483,18 @@ ANY num_sync ( 中描述。 如果在这个字符串中有任何选项未被指定,那么将检查相应的环境变量(见)。 如果环境变量也没有被设置,则使用默认值。 - - 连接字符串应当指定发送服务器的主机名(或地址),以及端口号(如果它与备库的默认端口不同)。 - 还要指定发送服务器上具有适当权限的角色所对应的用户名(见)。 - 如果发送端要求密码认证,还需要提供密码。它既可以直接写在 primary_conninfo 字符串中, - 也可以写在备库上的独立 ~/.pgpass 文件中(数据库名使用 replication)。 - - - - 对于复制槽同步,还必须在 primary_conninfo 字符串中指定有效的 dbname。 - 该设置只用于槽同步,对流复制会被忽略。 - - + 连接字符串应当指定发送服务器的主机名(或地址),以及端口号(如果它与备库的默认端口不同)。 + 还要指定发送服务器上具有适当权限的角色所对应的用户名(见)。 + 如果发送端要求密码认证,还需要提供密码。它既可以直接写在 primary_conninfo 字符串中, + 也可以写在备库上的独立 ~/.pgpass 文件中(数据库名使用 replication)。 + 不要在primary_conninfo字符串中指定数据库名。 + 这个参数只能在 postgresql.conf 文件或服务器命令行上设置。 如果在 WAL 接收进程运行时修改该参数,则会向该进程发送信号使其关闭,并期望它使用新设置重新启动 @@ -3653,7 +3515,7 @@ ANY num_sync ( )。 这个参数只能在 postgresql.conf文件或服务器命令行上设置。 - 如果在 WAL 接收进程运行时更改此参数,则该进程将发出关机信号,并预期使用新设置重新启动(除非primary_conninfo为空字符串)。 + 如果在 WAL 接收进程运行时更改此参数,则会向该进程发送关闭信号,并预期它使用新设置重新启动。 如果没有设置primary_conninfo或服务器没有处于备库模式,则此设置无效。 @@ -3692,9 +3554,7 @@ ANY num_sync ( num_sync ( num_sync ( )。 - 默认为"关闭"。 此参数只能在postgresql.conf文件或服务器命令行中设置。 - 如果在 WAL 接收进程运行时更改此参数,则该进程将发出关机的信号,并预期使用新设置重新启动。 - + 指定在未使用配置要使用的永久复制槽时,WAL 接收进程是否应在远程实例上创建临时复制槽。默认值为 off。此参数只能在postgresql.conf文件中或服务器命令行上设置。如果在 WAL 接收进程运行时更改此参数,则会向该进程发送信号使其关闭,并预期它使用新设置重新启动。 @@ -3750,9 +3604,9 @@ ANY num_sync ( pg_stat_replication视图看到。 - 备库将报告它已经写入的上一个预写式日志位置、它已经刷到磁盘的上一个位置以及它已经应用的最后一个位置。 + 备库将报告最后写入的预写日志位置、最后刷盘的位置以及最后应用的位置。 这个参数的值是报告之间的最大时间量。 - 每次写入或刷出位置改变时会发送状态更新,或者按这个参数的指定的频度发送,如果设置为非零值。 + 每次写入或刷盘位置改变时会发送状态更新,或者按这个参数的指定的频度发送,如果设置为非零值。 在其他情况下发送更新时忽略此参数;例如,当现有的WAL处理完成或当synchronous_commit设置为remote_apply时。 因此,应用位置可能比真实位置略微滞后。 如果指定值时没有单位,则以秒为单位。 @@ -3772,16 +3626,18 @@ ANY num_sync ( num_sync ( num_sync ( + + + + + recovery_min_apply_delay (integer) recovery_min_apply_delay 配置参数 - - 默认情况下,备库会尽快恢复来自于发送服务器的 WAL 记录。有一份数据的延时拷贝是有用的,它能提供机会纠正数据丢失错误。 - 这个参数允许你将恢复延迟一段指定的时间量。 - 例如,如果你设置这个参数为5min,对于一个事务提交,只有当备库上的系统时钟超过主库报告的提交时间至少 5分钟时,备库才会重放该事务。 - 如果指定值时没有单位,则以毫秒为单位。默认为0,不增加延迟。 + 默认情况下,备库会尽快恢复来自发送服务器的 WAL 记录。保留一份延迟的数据副本可能很有用,因为它提供了纠正数据丢失错误的机会。此参数允许将恢复延迟指定的时间。例如,将此参数设置为 5min 时,只有当备库系统时间比主库报告的提交时间至少晚五分钟,备库才会重放各事务的提交。如果没有指定单位,则以毫秒计。默认值为零,不增加延迟。 - - 有可能服务器之间的复制延迟会超过这个参数的值,在这种情况下则不会增加延迟。 - 注意延迟是根据主库上写 WAL 的时间戳以及备库上的当前时间来计算。 - 由于网络延迟或者级联复制配置导致的传输延迟可能会显著地减少实际等待时间。 - 如果主库和备库上的系统时钟不同步,这会导致恢复比预期的更早应用记录。 - 但这不是一个主要问题,因为这个参数有用的设置比服务器之间的典型事件偏差要大得多。 + 服务器之间的复制延迟可能超过此参数的值,这种情况下不会增加延迟。注意,延迟根据主库写入的 WAL 时间戳与备库当前时间之差计算。网络延迟或级联复制配置导致的传输延迟,可能显著缩短实际等待时间。如果主库和备库的系统时钟不同步,恢复时可能比预期更早应用记录;但这通常不是主要问题,因为此参数的实用取值远大于服务器间常见的时间偏差。 - - 只有在事务提交的 WAL 记录上才会发生延迟。其他记录还是会被尽可能快地重放,这不会成为问题,因为 MVCC 可见性规则确保了在对应的提交记录被应用之前它们的效果不会被看到。 + 延迟仅发生在事务提交的 WAL 记录上。其他记录会尽快重放;这不会造成问题,因为 MVCC 可见性规则确保在对应提交记录被应用之前,它们的效果不会可见。 - - 一旦恢复中的数据库已经达到一致状态,延迟就会产生,直到备库被提升或者触发。在那之后,备库将会结束恢复并且不再等待。 + 恢复中的数据库达到一致状态后开始延迟,直到备库被提升或触发。此后,备库会结束恢复,不再等待。 - - WAL记录必须保留在备库上,直到准备好应用。因此,较长的延迟将导致WAL文件的积累增加,增加备库的pg_wal目录的磁盘空间需求。 + WAL 记录必须保留在备库上,直到可以应用它们。因此,更长的延迟会导致更多 WAL 文件积压,增加备库 pg_wal 目录所需的磁盘空间。 - - 这个参数的目的是和流复制部署一起使用,但是,如果指定了该参数,除了崩溃恢复之外所有的情况下都会遵守它。 - 使用这个特性也会让hot_standby_feedback被延迟,这可能导致主库的膨胀,两者一起使用时要小心。 - + 此参数旨在用于流复制部署;不过,只要指定了此参数,它就会在除崩溃恢复以外的所有情况下生效。使用此功能也会延迟 hot_standby_feedback,可能导致主库膨胀;同时使用两者时应谨慎。 - 当synchronous_commit被设置为remote_apply时,同步复制会受到这个设置的影响,每一个COMMIT都需要等待被应用。 + 当 synchronous_commit 设置为 remote_apply 时,同步复制会受到此设置影响;每个 COMMIT 都必须等待提交被应用。 - - - - 这个参数只能在postgresql.conf文件中或通过服务器命令行进行设置。 - - - - - - createrole_self_grant (string) - - createrole_self_grant配置参数 - - - - - 如果一个拥有CREATEROLE但不拥有SUPERUSER权限的用户创建了角色,并且此选项被设置为非空值,则新创建的角色将以指定选项授予创建者。 - 该值必须是setinherit或它们的逗号分隔列表。默认值为空字符串,这会禁用此功能。 - - - 此选项的目的是允许非超级用户的CREATEROLE用户自动继承或自动获得对新创建角色执行SET ROLE的能力。 - 由于CREATEROLE用户始终会隐式获得其所创建角色的ADMIN OPTION,因此该用户总是可以通过执行GRANT语句达到相同效果,但自动授予在可用性上更方便。 - 超级用户会自动继承每个角色的权限,并且始终可以切换到任何角色;此设置可用于为CREATEROLE用户提供类似行为。 - - - - - - event_triggers (boolean) - - event_triggers配置参数 - - - - - 允许临时禁用事件触发器的执行,以便对有故障的事件触发器进行故障排查和修复。 - 将其设置为false会禁用所有事件触发器;设置为true则允许所有事件触发器触发,这也是默认值。 - 只有超级用户和具有适当SET权限的用户才能更改此设置。 - - - - - - restrict_nonsystem_relation_kind (string) - - restrict_nonsystem_relation_kind配置参数 - - - - - 设置禁止访问非系统关系的关系类型。该值采用关系类型的逗号分隔列表形式。 - 目前支持的关系类型是viewforeign-table。 - - - - + + + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 + + + + @@ -3937,11 +3731,7 @@ ANY num_sync ( @@ -3949,7 +3739,7 @@ ANY num_sync ( max_replication_slots (integer) - max_replication_slots configuration parameter + max_replication_slots配置参数 in a subscriber @@ -3975,16 +3765,15 @@ ANY num_sync ( num_sync ( num_sync ( num_sync ( + + enable_bitmapscan (boolean) - 位图扫描 + 位图扫描 - enable_bitmapscan配置参数 + enable_bitmapscan 配置参数 - - 允许或禁止查询规划器使用位图扫描计划类型。默认值是on。 + 启用或禁用查询规划器对位图扫描计划类型的使用。默认值为 on - - + + - + + enable_gathermerge (boolean) - enable_gathermerge配置参数 + enable_gathermerge 配置参数 - - 启用或者禁用查询规划器对收集归并计划类型的使用。默认值是on。 + 启用或禁用查询规划器对收集归并计划类型的使用。默认值为 on - - + + + - + enable_hashagg (boolean) - enable_hashagg配置参数 + enable_hashagg 配置参数 - - 允许或禁用查询规划器使用哈希聚合计划类型。默认值是on。 + 启用或禁用查询规划器对哈希聚合计划类型的使用。默认值为 on - + + enable_hashjoin (boolean) - enable_hashjoin配置参数 + enable_hashjoin 配置参数 - - 允许或禁止查询规划器使用哈希连接计划类型。默认值是on。 + 启用或禁用查询规划器对哈希连接计划类型的使用。默认值为 on - + + enable_incremental_sort (boolean) enable_incremental_sort 配置参数 - - 启用或禁用查询规划器对增量排序步骤的使用。默认为on。 + 启用或禁用查询规划器对增量排序步骤的使用。默认值为 on - + + + + enable_indexscan (boolean) - 索引扫描 + 索引扫描 - enable_indexscan配置参数 + enable_indexscan 配置参数 - - 允许或禁止查询规划器使用索引扫描计划类型。默认值是on。 + 启用或禁用查询规划器对索引扫描和仅索引扫描计划类型的使用。默认值为 on。另请参见 - enable_indexonlyscan (boolean) - enable_indexonlyscan配置参数 + enable_indexonlyscan 配置参数 - - 允许或禁止查询规划器使用只用索引扫描计划类型(见)。默认值是on。 + 启用或禁用查询规划器对仅索引扫描计划类型的使用(参见 )。默认值为 on。还必须启用 ,查询规划器才会考虑仅索引扫描。 - + + enable_material (boolean) - enable_material配置参数 + enable_material 配置参数 @@ -4204,8 +3993,9 @@ ANY num_sync ( + + enable_memoize (boolean) enable_memoize 配置参数 @@ -4222,26 +4012,27 @@ ANY num_sync ( + + enable_mergejoin (boolean) - enable_mergejoin配置参数 + enable_mergejoin 配置参数 - - 允许或禁止查询规划器使用归并连接计划类型。默认值是on。 + 启用或禁用查询规划器对归并连接计划类型的使用。默认值为 on - + + enable_nestloop (boolean) - enable_nestloop配置参数 + enable_nestloop 配置参数 @@ -4267,17 +4058,17 @@ ANY num_sync ( + + enable_parallel_hash (boolean) - enable_parallel_hash配置参数 + enable_parallel_hash 配置参数 - - 允许或禁止查询规划器对并行哈希使用哈希连接计划类型。如果哈希连接计划也没有启用,这个参数没有效果。默认值是on。 + 启用或禁用查询规划器对使用并行哈希的哈希连接计划类型的使用。如果没有同时启用哈希连接计划,此参数不起作用。默认值为 on @@ -4297,41 +4088,37 @@ ANY num_sync ( + + + + enable_partitionwise_join (boolean) - enable_partitionwise_join配置参数 + enable_partitionwise_join 配置参数 - - 允许或者禁止查询规划器使用面向分区的连接,这使得分区表之间的连接以连接匹配的分区的方式来执行。 - 面向分区的连接当前只适用于连接条件包括所有分区键的情况,连接条件必须是相同的数据类型并且子分区集合要1对1匹配。 - 由于面向分区的连接规划在规划期间会使用可观的CPU时间和内存,所以默认值为off。 + 启用或禁用查询规划器对分区连接的使用,使分区表之间的连接可以通过连接相匹配的分区来完成。分区连接目前仅适用于连接条件包含所有分区键的情况;这些分区键必须具有相同的数据类型,并且子分区集合必须一一匹配。启用此设置后,最终计划中内存用量受 work_mem 限制的节点数量可能随所扫描分区的数量线性增加。这可能大幅增加查询执行期间的总内存消耗。查询规划在内存和 CPU 方面的开销也会显著增加。默认值为 off - enable_partitionwise_aggregate (boolean) - enable_partitionwise_aggregate配置参数 + enable_partitionwise_aggregate 配置参数 - - 启用或禁用查询规划器使用分区分组或聚合的功能,该功能允许在分区表上分别对每个分区执行分组或聚合操作。 - 如果GROUP BY子句不包括分区键,那么只能在每个分区的基础上执行部分聚合,并且必须在稍后进行最终化处理。 - 由于分区分组或聚合在规划期间可能会使用更多的CPU时间和内存,因此默认情况下为off。 + 启用或禁用查询规划器对分区分组或聚合的使用,使分区表上的分组或聚合可以在各个分区上分别执行。如果 GROUP BY 子句不包含分区键,则只能在各分区上执行部分聚合,随后还必须进行最终处理。启用此设置后,最终计划中内存用量受 work_mem 限制的节点数量可能随所扫描分区的数量线性增加。这可能大幅增加查询执行期间的总内存消耗。查询规划在内存和 CPU 方面的开销也会显著增加。默认值为 off - - + + - + enable_presorted_aggregate (boolean) enable_presorted_aggregate配置参数 @@ -4800,7 +4587,7 @@ ANY num_sync ( 包括在普通日志项中。只有可打印 ASCII 字符能被使用在application_name之中。其他字符将被替换为问号(?)。 + application_name可以是任意小于NAMEDATALEN个字符(标准编译中是 64 个字符)的字符串。应用通常在连接服务器时设置此值。该名称将被显示在pg_stat_activity视图中并被包括在 CSV 日志项中。它也会被通过包括在普通日志项中。只有可打印 ASCII 字符能被使用在application_name之中。其他字符将被替换为C 风格的十六进制转义序列。 @@ -5692,77 +5479,22 @@ local0.* /var/log/postgresql - - log_connections (string) + log_connections (boolean) - log_connections配置参数 + log_connections 配置参数 - - - 控制是否记录服务器每次连接的各个阶段。默认值为空字符串 - '',表示禁用所有连接日志。下列选项既可以单独指定, - 也可以用逗号分隔的列表指定: - - -
- 连接日志选项 - - - - - - 名称 - 说明 - - - - - receipt - 记录收到连接。 - - - authentication - 记录认证方法用于识别用户的原始身份。在大多数情况下,该身份字符串与PostgreSQL用户名一致,但某些第三方认证方法可能会在服务器存储之前修改原始用户标识符。无论此设置为何值,认证失败始终都会被记录。 - - - authorization - 记录授权成功完成。此时连接已经建立,但后端尚未完全初始化。日志消息会包含授权后的用户名,以及数据库名和应用名(如果适用)。 - - - setup_durations - 记录从 postmaster 接受传入连接开始,到连接准备好执行第一条查询为止,建立连接并完成后端初始化所花费的时间。日志消息会包含三个时长:总设置时长、fork 新后端所花费的时间,以及用户认证所花费的时间。 - - - all - 一个便捷别名,相当于指定所有选项。如果在其他选项列表中包含all,则会记录连接的所有方面。 - - - -
- - - 断开连接的日志由单独控制。 - - - - 出于向后兼容性考虑,onoff、 - truefalseyes、 - no10仍然受支持。 - 正向值等价于指定receiptauthentication和 - authorization选项。 - - - 只有超级用户和具有适当SET权限的用户可以在会话开始时更改此参数, - 并且在会话内部完全不能更改。 + 记录每次尝试连接服务器的操作,以及客户端认证(如有必要)和授权的成功完成。 + 只有超级用户和具有适当 SET 权限的用户可以在会话开始时更改此参数,在会话期间则完全不能更改。 + 默认值为 off - - 某些客户端程序(例如psql)在要求密码时会尝试连接两次,因此重复的收到连接消息并不一定表示一个错误。 + 某些客户端程序(例如 psql)在判断是否需要密码时会尝试连接两次, + 因此重复的收到连接消息并不一定表示有问题。
@@ -5980,13 +5712,13 @@ local0.* /var/log/postgresql %v - 虚拟事务 ID (backendID/localXID) + 虚拟事务 ID (backendID/localXID);参见 %x - 事务 ID (如果未分配则为 0) + 事务 ID (如果未分配则为 0);参见 @@ -6005,7 +5737,7 @@ local0.* /var/log/postgresql %% - 纯文字 % + 字面字符 % @@ -6039,7 +5771,7 @@ FROM pg_stat_activity; - Syslog产生自己的时间戳和进程 ID 信息,因此如果你记录到syslog你可能不希望包括哪些转义。 + Syslog产生自己的时间戳和进程 ID 信息,因此如果你记录到syslog你可能不希望包括那些转义。 @@ -6573,12 +6305,12 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 为不同目的设置标识这个数据库集簇(实例)的名称。此集簇名称出现在该集簇中所有服务器进程的进程标题中。 - 此外,它还是备库连接的默认应用名称。(参见 .) + 设置一个用于各种目的、标识此数据库集簇(实例)的名称。集簇名称会出现在此集簇所有服务器进程的进程标题中。 + 此外,它还是备库连接的默认应用名称(参见)。 - 这个名称可以是任何长度不超过NAMEDATALEN个字符(在标准编译中是 64字符)的任何字符串。只有可打印的 ASCII 字符能被用在cluster_name值中。其他字符将被替换为问号(?)。如果这个参数被设置为空字符串''(也是默认值),将不会显示名称。这个参数只能在服务器启动时设置。 + 这个名称可以是任何长度少于NAMEDATALEN个字符(在标准编译中是 64字符)的任何字符串。只有可打印的 ASCII 字符能被用在cluster_name值中。其他字符将被替换为C 风格的十六进制转义序列。如果这个参数被设置为空字符串''(也是默认值),将不会显示名称。这个参数只能在服务器启动时设置。 @@ -6673,19 +6405,24 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - track_io_timing (boolean) - track_io_timing配置参数 + track_io_timing 配置参数 - - 启用数据库I/O调用的计时。 默认情况下,此参数处于关闭状态,因为它将重复查询操作系统的当前时间,这可能会在某些平台上造成显著的开销。 您可以使用工具来测量系统上计时的开销。 - I/O计时信息显示在 - pg_stat_database中,在的输出中,当使用BUFFERS选项时,在的输出中,当使用VERBOSE选项时,由autovacuum执行自动清理和自动分析时,当设置了时,以及由。 - 只有超级用户和具有适当SET权限的用户才能更改此设置。 + 启用数据库 I/O 调用的计时。此参数默认关闭,因为计时需要反复向操作系统查询 + 当前时间,在某些平台上可能会产生显著开销。可以使用 工具 + 测量本系统上的计时开销。I/O 计时信息会显示在 + pg_stat_database 中、 + pg_stat_io 中、 + 使用 BUFFERS 选项的 输出中、 + 使用 VERBOSE 选项的 输出中, + autovacuum 也会在执行自动清理和自动分析时输出这些信息 + (需设置 ), + 同样提供这些信息。只有超级用户和具有适当 + SET 权限的用户可以更改此设置。 @@ -6700,14 +6437,8 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 启用WAL I/O调用的定时。此参数默认关闭,因为它将重复查询操作系统的当前时间, - 这可能会在某些平台上造成显著的开销。 - 您可以使用pg_test_timing工具来 - 测量系统上定时的开销。 - I/O定时信息显示在 - pg_stat_wal中。 - 只有超级用户和具有适当SET权限的用户才能更改此设置。 - + 启用 WAL I/O 调用的计时。此参数默认关闭,因为它会反复向操作系统查询当前时间,可能在某些平台上产生显著开销。可以使用 pg_test_timing 工具测量系统上的计时开销。I/O 计时信息显示在 pg_stat_wal 中。只有超级用户和具有适当 SET 权限的用户才能更改此设置。 +
@@ -6802,7 +6533,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 确认只有一个查询标识符被计算和显示,如果一个查询标识符已经被计算,扩展计算标识符将抛出一个错误。 + 为确保只有一个查询标识符被计算和显示,计算查询标识符的扩展在查询标识符已被计算时应当抛出一个错误。 @@ -6869,7 +6600,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; autovacuum (boolean) - autovacuum configuration parameter + autovacuum配置参数 @@ -6889,7 +6620,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; autovacuum_max_workers (integer) - autovacuum_max_workers configuration parameter + autovacuum_max_workers配置参数 @@ -6903,12 +6634,12 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; autovacuum_naptime (integer) - autovacuum_naptime configuration parameter + autovacuum_naptime配置参数 - 指定自动清理在任意给定数据库上运行之间的最小延迟。每一轮中,守护进程会检查数据库, + 指定自动清理在任意给定数据库上各次运行之间的最小间隔。每一轮中,守护进程会检查数据库, 并根据需要为其中的表发出 VACUUMANALYZE 命令。 如果未指定单位,则按秒计。默认值为 1 分钟(1min)。 该参数只能在 postgresql.conf 文件或服务器命令行中设置。 @@ -6920,7 +6651,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; autovacuum_vacuum_threshold (integer) autovacuum_vacuum_threshold - configuration parameter + 配置参数 @@ -6936,7 +6667,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; autovacuum_vacuum_insert_threshold (integer) autovacuum_vacuum_insert_threshold - configuration parameter + 配置参数 @@ -6954,7 +6685,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; autovacuum_analyze_threshold (integer) autovacuum_analyze_threshold - configuration parameter + 配置参数 @@ -6970,7 +6701,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; autovacuum_vacuum_scale_factor (floating point) autovacuum_vacuum_scale_factor - configuration parameter + 配置参数 @@ -6987,7 +6718,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; autovacuum_vacuum_insert_scale_factor (floating point) autovacuum_vacuum_insert_scale_factor - configuration parameter + 配置参数 @@ -7004,7 +6735,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; autovacuum_analyze_scale_factor (floating point) autovacuum_analyze_scale_factor - configuration parameter + 配置参数 @@ -7021,7 +6752,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; autovacuum_freeze_max_age (integer) autovacuum_freeze_max_age - configuration parameter + 配置参数 @@ -7043,7 +6774,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; autovacuum_multixact_freeze_max_age (integer) autovacuum_multixact_freeze_max_age - configuration parameter + 配置参数 @@ -7066,7 +6797,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; autovacuum_vacuum_cost_delay (floating point) autovacuum_vacuum_cost_delay - configuration parameter + 配置参数 @@ -7083,7 +6814,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; autovacuum_vacuum_cost_limit (integer) autovacuum_vacuum_cost_limit - configuration parameter + 配置参数 @@ -7099,112 +6830,9 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - - 默认行为 - - - - vacuum_truncate (boolean) - - vacuum_truncate配置参数 - - - - - 启用或禁用 vacuum 尝试截断表末尾的空页。默认值为true。 - 如果为true,则VACUUM和 autovacuum 会执行截断,并将这些页面占用的磁盘空间返还给操作系统。 - 请注意,截断需要获取表上的ACCESS EXCLUSIVE锁。 - 如果在VACUUM中指定了TRUNCATE参数,它将覆盖该参数的值。 - 也可以通过修改表存储参数来为单个表覆盖此设置。 - - - - - - - - 冻结 (Freezing) - - 这些设置控制旧行版本的冻结。更多信息请参阅。 - - - - - vacuum_freeze_table_age (integer) - - vacuum_freeze_table_age配置参数 - - - - - 当表的pg_class.relfrozenxid字段达到该设置指定的年龄时,VACUUM会执行激进扫描。激进扫描与常规VACUUM不同,它会访问每一个可能包含未冻结 XID 或 MXID 的页面,而不仅仅是那些可能包含死元组的页面。默认值是 1.5 亿个事务。尽管用户可以将该值设置为 0 到 20 亿之间的任意值,VACUUM会悄悄将有效值调整为的 95%,从而在触发防回卷 autovacuum 之前仍有机会执行一次常规手工VACUUM。更多信息请参见。 - - - - - - vacuum_freeze_min_age (integer) - - vacuum_freeze_min_age配置参数 - - - - - 指定VACUUM在扫描表时用来决定是否冻结行版本的切断年龄(以事务计)。默认值是 5000 万个事务。尽管用户可以将该值设置为 0 到 10 亿之间的任意值,VACUUM会悄悄将有效值调整为的一半,这样强制 autovacuum 之间就不会间隔过短。更多信息请参见。 - - - - - - vacuum_failsafe_age (integer) - - vacuum_failsafe_age配置参数 - - - - - 指定表的pg_class.relfrozenxid字段在VACUUM采取特别措施以避免系统范围事务 ID 回卷失败之前所允许达到的最大年龄(以事务计)。这是VACUUM的最后防线。失效保护通常会在防止事务 ID 回卷的 autovacuum 已经运行了一段时间后触发,但也有可能在任何VACUUM期间触发。 - - - 当失效保护被触发时,将不再应用任何有效的基于成本的延迟,并且会跳过进一步的非关键维护任务(例如索引 vacuum),而且任何正在使用的 - 缓冲区访问策略 - 都会被禁用,使 VACUUM 可以自由使用全部 - 共享缓冲区。 - - - 默认值为 16 亿个事务。尽管用户可以将该值设置为 0 到 21 亿之间的任意值,VACUUM会悄悄将有效值调整为不低于的 105%。 - - - - - vacuum_multixact_freeze_table_age (integer) - - vacuum_multixact_freeze_table_age配置参数 - - - - - 当表的pg_class.relminmxid字段达到该设置指定的年龄时,VACUUM会执行激进扫描。激进扫描与常规VACUUM不同,它会访问每一个可能包含未冻结 XID 或 MXID 的页面,而不是只扫描那些可能包含死元组的页面。默认值是 1.5 亿个 multixact。尽管用户可以将该值设置为 0 到 20 亿之间的任意值,VACUUM会悄悄将有效值调整为的 95%,从而在触发防回卷 autovacuum 之前仍有机会执行一次常规手工VACUUM。更多信息请参见。 - - - - - vacuum_multixact_freeze_min_age (integer) - - vacuum_multixact_freeze_min_age配置参数 - - - - - 指定VACUUM在扫描表时用来决定是否将 multixact ID 替换为较新的事务 ID 或 multixact ID 的切断年龄(以 multixact 计)。默认值是 5000 万个 multixact。尽管用户可以将该值设置为 0 到 10 亿之间的任意值,VACUUM会悄悄将有效值调整为的一半,这样强制 autovacuum 之间就不会间隔过短。更多信息请参见。 - - - - -
@@ -7247,7 +6875,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; search_path配置参数 - pathfor schemas + 路径用于模式 @@ -7340,7 +6968,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; default_tablespace配置参数 - tablespacedefault + 表空间默认 @@ -7445,7 +7073,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; default_transaction_isolation (enum) - transaction isolation level + 事务隔离级别 设置默认值 @@ -7468,7 +7096,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; default_transaction_read_only (boolean) - read-only transaction + 只读事务 设置默认值 @@ -7491,7 +7119,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; default_transaction_deferrable (boolean) - deferrable transaction + 可延迟事务 设置默认值 @@ -7518,7 +7146,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; transaction_isolation (enum) - transaction isolation level + 事务隔离级别 transaction_isolation配置参数 @@ -7538,7 +7166,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; transaction_read_only (boolean) - read-only transaction + 只读事务 transaction_read_only 配置参数 @@ -7558,7 +7186,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; transaction_deferrable (boolean) - deferrable transaction + 可延迟事务 transaction_deferrable 配置参数 @@ -7677,7 +7305,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; 此选项可以用于确保空闲会话不会在不合理的时间内持有锁。 - 即使没有持有重要的锁的时候,打开的事务也会防止清理最近死亡的可能只对这个事务可见的元组;所以长时间保持空闲会导致表膨胀。 + 即使没有持有重要的锁的时候,打开的事务也会防止清理最近死亡的可能只对这个事务可见的元组;所以长时间保持空闲会导致表膨胀。 详见 @@ -7709,7 +7337,100 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - + + vacuum_freeze_table_age (integer) + + vacuum_freeze_table_age配置参数 + + + + + 当表的pg_class.relfrozenxid字段达到该设置指定的年龄时,VACUUM会执行激进扫描。激进扫描与常规VACUUM不同,它会访问每一个可能包含未冻结 XID 或 MXID 的页面,而不仅仅是那些可能包含死元组的页面。默认值是 1.5 亿个事务。尽管用户可以将该值设置为 0 到 20 亿之间的任意值,VACUUM会悄悄将有效值限制为不超过的 95%,从而在触发防回卷 autovacuum 之前仍有机会执行一次常规手工VACUUM。更多信息请参见。 + + + + + + vacuum_freeze_min_age (integer) + + vacuum_freeze_min_age配置参数 + + + + + 指定VACUUM用来决定是否触发对含有较旧 XID 的页面进行冻结的截止年龄(以事务计)。默认值是 5000 万个事务。尽管用户可以将该值设置为 0 到 10 亿之间的任意值,VACUUM会悄悄将有效值限制为不超过的一半,这样强制 autovacuum 之间就不会间隔过短。更多信息请参见。 + + + + + + vacuum_failsafe_age (integer) + + vacuum_failsafe_age配置参数 + + + + + 指定表的pg_class.relfrozenxid字段在VACUUM采取特别措施以避免系统范围事务 ID 回卷失败之前所允许达到的最大年龄(以事务计)。这是VACUUM的最后防线。失效保护通常会在防止事务 ID 回卷的 autovacuum 已经运行了一段时间后触发,但也有可能在任何VACUUM期间触发。 + + + 当失效保护被触发时,将不再应用任何有效的基于代价的延迟,并且会跳过进一步的非关键维护任务(例如索引清理),而且任何正在使用的 + 缓冲区访问策略 + 都会被禁用,使 VACUUM 可以自由使用全部 + 共享缓冲区。 + + + 默认值为 16 亿个事务。尽管用户可以将该值设置为 0 到 21 亿之间的任意值,VACUUM会悄悄将有效值调整为不低于的 105%。 + + + + + + vacuum_multixact_freeze_table_age (integer) + + vacuum_multixact_freeze_table_age配置参数 + + + + + 当表的pg_class.relminmxid字段达到该设置指定的年龄时,VACUUM会执行激进扫描。激进扫描与常规VACUUM不同,它会访问每一个可能包含未冻结 XID 或 MXID 的页面,而不是只扫描那些可能包含死元组的页面。默认值是 1.5 亿个多事务。尽管用户可以将该值设置为 0 到 20 亿之间的任意值,VACUUM会悄悄将有效值限制为不超过的 95%,从而在触发防回卷 autovacuum 之前仍有机会执行一次常规手工VACUUM。更多信息请参见。 + + + + + + vacuum_multixact_freeze_min_age (integer) + + vacuum_multixact_freeze_min_age配置参数 + + + + + 指定VACUUM用来决定是否触发对含有较旧多事务 ID 的页面进行冻结的截止年龄(以多事务计)。默认值是 500 万个多事务。尽管用户可以将该值设置为 0 到 10 亿之间的任意值,VACUUM会悄悄将有效值限制为不超过的一半,这样强制 autovacuum 之间就不会间隔过短。更多信息请参见。 + + + + + + vacuum_multixact_failsafe_age (integer) + + vacuum_multixact_failsafe_age 配置参数 + + + + + 指定表的 pg_class.relminmxid 字段在 VACUUM 采取特别措施避免系统范围的多事务 ID 回卷故障之前,所能达到的最大年龄(以多事务计)。这是 VACUUM 的最后手段。失效保护通常会在防止事务 ID 回卷的自动清理已经运行一段时间后触发,但也可能在任何 VACUUM 期间触发。 + + + 触发失效保护后,任何正在生效的基于代价的延迟都将不再应用,后续非必要的维护任务(例如索引清理)也会被跳过。 + + + 默认值为 16 亿个多事务。虽然用户可以将此值设置为 0 到 21 亿之间的任意值,VACUUM 仍会将实际生效值自动调整为不低于 的 105%。 + + + + + bytea_output (enum) @@ -7753,7 +7474,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; SET XML OPTION - XML option + XML 选项 @@ -7791,6 +7512,39 @@ SET XML OPTION { DOCUMENT | CONTENT }; + + createrole_self_grant (string) + + createrole_self_grant配置参数 + + + + + 如果一个拥有CREATEROLE但不拥有SUPERUSER权限的用户创建了角色,并且此选项被设置为非空值,则新创建的角色将以指定选项授予创建者。 + 该值必须是setinherit或它们的逗号分隔列表。默认值为空字符串,这会禁用此功能。 + + + 此选项的目的是允许非超级用户的CREATEROLE用户自动继承或自动获得对新创建角色执行SET ROLE的能力。 + 由于CREATEROLE用户始终会隐式获得其所创建角色的ADMIN OPTION,因此该用户总是可以通过执行GRANT语句达到相同效果,但自动授予在可用性上更方便。 + 超级用户会自动继承每个角色的权限,并且始终可以切换到任何角色;此设置可让CREATEROLE用户对其创建的用户获得类似的行为。 + + + + + + restrict_nonsystem_relation_kind (string) + + restrict_nonsystem_relation_kind配置参数 + + + + + 设置禁止访问非系统关系的关系类型。该值采用关系类型的逗号分隔列表形式。 + 目前支持的关系类型是viewforeign-table。 + + + + @@ -7839,7 +7593,7 @@ SET XML OPTION { DOCUMENT | CONTENT }; TimeZone配置参数 - time zone + 时区 @@ -7855,7 +7609,7 @@ SET XML OPTION { DOCUMENT | CONTENT }; timezone_abbreviations配置参数 - time zone names + 时区名称 @@ -7869,11 +7623,11 @@ SET XML OPTION { DOCUMENT | CONTENT }; extra_float_digits (integer) - significant digits + 有效数字 - floating-point - display + 浮点数 + 显示 extra_float_digits配置参数 @@ -7901,7 +7655,7 @@ SET XML OPTION { DOCUMENT | CONTENT }; - 此参数的含义,以及其默认值,在 PostgreSQL 12 中发生了变化; + 此参数的含义,以及其默认值,在 PostgreSQL 12 中发生了变化; 参见 以便进一步讨论。 @@ -7914,7 +7668,7 @@ SET XML OPTION { DOCUMENT | CONTENT }; client_encoding配置参数 - character set + 字符集 @@ -8264,12 +8018,12 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' deadlock_timeout (integer) - deadlock + 死锁 期间超时 - timeout - deadlock + 超时 + 死锁 deadlock_timeout配置参数 @@ -8304,14 +8058,11 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' - 共享锁表跟踪在max_locks_per_transaction * ( + ) 个对象(如表)上的锁。因此,在任何一个时刻,只有不超过这么多个可区分对象能够被锁住。这个参数控制为每个事务分配的对象锁的平均数量。个体事务可以锁住更多对象,数量可以和锁表中能容纳的所有事务的锁一样多。这是能被锁住的行数,那个值是没有限制的。默认值 64 已经被历史证明是足够的,但是如果你有需要在一个事务中使用很多不同表的查询(例如查询一个有很多子表的父表),你可能需要提高这个值。这个参数只能在服务器启动时设置。 + 共享锁表为每个服务器进程或预备事务预留可容纳max_locks_per_transaction 个对象(例如表)的空间;因此,在任何时刻可被锁住的不同对象数都不能超过总容量。这个参数限制每个事务使用的对象锁的平均数量;只要所有事务的锁能放入锁表中,单个事务就可以锁住更多对象。这是能被锁住的行数,那个值是没有限制的。默认值 64 已经被历史证明是足够的,但是如果你有需要在一个事务中使用很多不同表的查询(例如查询一个有很多子表的父表),你可能需要提高这个值。这个参数只能在服务器启动时设置。 - 当运行一个备库时,你必须设置这个参数等于或大于主库上的参数。 - 否则,备库上可能无法允许查询。 + 运行备库时,必须将此参数设置为大于或等于主库上的值。否则,备库上将不允许查询。 @@ -8326,9 +8077,7 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' - 共享谓词锁表跟踪在max_pred_locks_per_transaction * ( + ) 个对象(如表)上的锁。因此,在任何一个时刻,只有不超过这么多个可区分对象能够被锁住。这个参数控制为每个事务分配的对象锁的平均数量。个体事务可以锁住更多对象,数量可以和锁表中能容纳的所有事务的锁一样多。这是能被锁住的行数,那个值是没有限制的。默认值 64 已经在测试中被证明通常是足够的,但是如果你有需要在一个可串行化事务中使用很多不同表的查询(例如查询一个有很多子表的父表),你可能需要提高这个值。这个参数只能在服务器启动时设置。 + 共享谓词锁表为每个服务器进程或预备事务预留可容纳max_pred_locks_per_transaction 个对象(例如表)的空间;因此,在任何时刻可被锁住的不同对象数都不能超过总容量。这个参数限制每个事务使用的对象锁的平均数量;只要所有事务的锁能放入锁表中,单个事务就可以锁住更多对象。这是能被锁住的行数,那个值是没有限制的。默认值 64 已经被历史证明是足够的,但是如果你有会在单个可串行化事务中访问许多不同表的客户端,则可能需要提高这个值。这个参数只能在服务器启动时设置。 @@ -8398,7 +8147,7 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' backslash_quote (enum) - stringsbackslash quotes + 字符串反斜线引号 backslash_quote配置参数 @@ -8418,7 +8167,7 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' escape_string_warning (boolean) - strings转义警告 + 字符串转义警告 escape_string_warning配置参数 @@ -8474,7 +8223,7 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' standard_conforming_strings (boolean) - stringsstandard conforming + 字符串标准符合 standard_conforming_strings配置参数 @@ -8818,7 +8567,7 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' server_encoding配置参数 - character set + 字符集 @@ -9189,6 +8938,24 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' + + trace_recovery_messages (enum) + + trace_recovery_messages 配置参数 + + + + + 启用原本不会记录的恢复相关调试输出。此参数允许用户覆盖的常规设置,但仅针对特定消息。 + 它旨在用于调试热备。有效值为DEBUG5DEBUG4、 + DEBUG3DEBUG2DEBUG1LOG。 + 默认值LOG完全不影响是否记录消息的决定。其他值会让该优先级或更高优先级的恢复相关调试消息 + 按LOG优先级记录;对于log_min_messages的常见设置,这会无条件地将它们发送到服务器日志。 + 此参数只能在postgresql.conf文件中或在服务器命令行上设置。 + + + + trace_sort (boolean) @@ -9610,7 +9377,7 @@ LOG: CleanUpLock: deleting: lock(0xb7acd844) id(24688,24696,0,0,0,1) - 在订阅端,如果streaming选项被设置为parallel, + 在订阅端,如果streaming选项被设置为parallel, 则debug_logical_replication_streaming可用于控制主应用工作进程是将更改发送到共享内存队列, 还是将所有更改序列化到文件。设置为buffered时,主进程通过共享内存队列将更改发送给并行应用工作进程。 设置为immediate时,主进程会将所有更改序列化到文件,并通知并行应用工作进程在事务结束时读取并应用这些更改。 diff --git a/zh/16/contrib.sgml b/zh/16/contrib.sgml index da735d6f..f902a3c1 100644 --- a/zh/16/contrib.sgml +++ b/zh/16/contrib.sgml @@ -109,6 +109,7 @@ CREATE EXTENSION extension_name; 详情见各组件文档。 +&adminpack; &amcheck; &auth-delay; &auto-explain; @@ -131,6 +132,7 @@ CREATE EXTENSION extension_name; &isn; &lo; <ree; + &oldsnapshot; &pageinspect; &passwordcheck; &pgbuffercache; diff --git a/zh/16/custom-rmgr.sgml b/zh/16/custom-rmgr.sgml index fae118f0..d19fcb32 100644 --- a/zh/16/custom-rmgr.sgml +++ b/zh/16/custom-rmgr.sgml @@ -10,6 +10,7 @@ 一个扩展,尤其是表访问方法或 索引访问方法,可能需要使用 WAL 来进行恢复、 复制和/或逻辑解码。 + 相比通用 WAL(不支持逻辑解码),自定义资源管理器更加灵活,但扩展实现起来也更复杂。 要创建新的自定义 WAL 资源管理器,首先定义一个 diff --git a/zh/16/datatype.sgml b/zh/16/datatype.sgml index 63ad0ac5..31e349dd 100644 --- a/zh/16/datatype.sgml +++ b/zh/16/datatype.sgml @@ -354,19 +354,19 @@ smallint 2字节 小范围整数 - -32768 to +32767 + -32768 到 +32767 integer 4字节 整数的典型选择 - -2147483648 to +2147483647 + -2147483648 到 +2147483647 bigint 8字节 大范围整数 - -9223372036854775808 to +9223372036854775807 + -9223372036854775808 到 +9223372036854775807 @@ -866,9 +866,8 @@ FROM generate_series(-3.5, 3.5, 1) as x; - 本节描述的是 PostgreSQL 特有的创建 - 自动递增列的方法。另一种方法是使用 SQL 标准的标识列特性, - 参见 。 + 本节介绍 PostgreSQL 特有的自动递增列创建方法。 + 另一种方法是使用 SQL 标准的标识列特性,参见 @@ -947,7 +946,7 @@ ALTER SEQUENCE tablename_money 类型以固定的小数精度存储货币金额; 参见 。小数精度由数据库的 设置决定。表中显示的范围假定 - 有两位小数。输入支持多种格式,包括整数和浮点文字,以及典型的 + 有两位小数。输入支持多种格式,包括整数字面量和浮点数字面量,以及典型的 货币格式,例如 '$1,000.00'。输出通常也采用 后一种形式,但会受到区域设置影响。 @@ -1373,7 +1372,7 @@ SELECT '\xDEADBEEF'::bytea; - <type>bytea</type>文字转义字节 + <type>bytea</type>字面量中需要转义的字节 @@ -2638,7 +2637,7 @@ SELECT '2 years 15 months 100 weeks 99 hours 123456789 milliseconds'::interval; 3 years 3 mons 700 days 133:17:36.789 - 这里,周被理解为 7 days,而较小和较大的时间单位 + 这里,周按7 天计算并单独保留,而较小和较大的时间单位 则被合并并规范化了。 @@ -4066,17 +4065,16 @@ a0ee-bc99-9c0b-4ef8-bb6d-6bb9-bd38-0a11 xml 数据类型可用于存储 XML 数据。与把 XML 数据存储在 - text 字段中相比,它的优势在于会检查输入值是否格式 - 良好,并且提供了可执行类型安全操作的支持函数;见 - 。使用该数据类型要求安装时启用 + text 字段中相比,它的优势在于会检查输入值的良构性,并且提供了可执行类型安全操作的支持函数;见 + 。使用该数据类型要求构建时使用 configure --with-libxml - xml 类型既可以存储符合 XML 标准定义的格式良好的 + xml 类型既可以存储 XML 标准所定义的良构 文档,也可以存储 内容 片段;后者是参照 XQuery 和 XPath 数据模型中更宽松的 - document node + 文档节点 概念来定义的。粗略地说,这意味着内容片段可以拥有多个顶层元素或字符 节点。表达式 xmlvalue IS DOCUMENT @@ -4245,7 +4243,7 @@ SET xmloption TO { DOCUMENT | CONTENT }; - 是一种用户定义的数据类型,它基于另一种底层类型。根据需要,它可以有约束来限制其有效值为底层类型所允许值的一个子集。如果没有约束,它的行为就和底层类型一样 — 例如,任何适用于底层类型的操作符或函数都对该域类型有效。底层类型可以是任何内置或者用户定义的基础类型、枚举类型、数组类型、复合类型、范围类型或者另一个域。 + 是一种用户定义的数据类型,它基于另一种底层类型。根据需要,它可以有约束来限制其有效值为底层类型所允许值的一个子集。除此之外,它的行为与底层类型相同 — 例如,任何适用于底层类型的操作符或函数都对该域类型有效。底层类型可以是任何内置或者用户定义的基础类型、枚举类型、数组类型、复合类型、范围类型或者另一个域。 diff --git a/zh/16/dblink.sgml b/zh/16/dblink.sgml index 1f96231d..483c07ec 100644 --- a/zh/16/dblink.sgml +++ b/zh/16/dblink.sgml @@ -11,39 +11,6 @@ dblink 是一个支持在数据库会话内连接到其他 PostgreSQL 数据库的模块。 - - dblink 可以在 Extension 等待事件类型下报告以下等待事件。 - - - - - DblinkConnect - - - 等待与远程服务器建立连接。 - - - - - - DblinkGetConnect - - - 当在已打开连接列表中找不到该连接时,等待建立与远程服务器的连接。 - - - - - - DblinkGetResult - - - 等待接收来自远程服务器的查询结果。 - - - - - 另请参见 ,它使用更现代且更符合标准的基础设施提供了基本相同的功能。 @@ -65,8 +32,8 @@ -dblink_connect(text connstr) 返回 text -dblink_connect(text connname, text connstr) 返回 text +dblink_connect(text connstr) returns text +dblink_connect(text connname, text connstr) returns text @@ -128,25 +95,16 @@ dblink_connect(text connname, text connstr) 返回 text 注解 - 如果不可信用户能够访问一个尚未采用模式的安全使用方式的数据库,则应在每个会话开始时从 + 如果不受信任的用户能够访问一个尚未采用模式的安全使用方式的数据库,则应在每个会话开始时从 search_path 中移除公共可写模式。例如,可以把 options=-csearch_path= 加到 connstr 中。这个注意事项并非 dblink 所特有;它适用于每一种执行任意 SQL 命令的接口。 - - 外部数据包装器 dblink_fdw 还有一个额外的布尔选项 - use_scram_passthrough,用于控制 - dblink 是否在连接远程数据库时使用 SCRAM 透传认证。 - 使用 SCRAM 透传认证时,dblink 会使用 SCRAM 哈希后的凭据,而不是明文用户密码来连接远程服务器。 - 这样可以避免在 PostgreSQL 系统目录中存储明文用户密码。关于更多细节和限制,请参见 - postgres_fdw 中对应的 - use_scram_passthrough - 选项文档。 - + - 只有超级用户才能使用 dblink_connect 创建既不使用密码认证、SCRAM 透传,也不使用 GSSAPI 认证的连接。 + 只有超级用户才能使用 dblink_connect 创建非密码认证且非 GSSAPI 认证的连接。 如果非超级用户需要这种能力,请改用 dblink_connect_u @@ -173,10 +131,9 @@ SELECT dblink_connect('myconn', 'dbname=postgres options=-csearch_path='); OK (1 row) --- FOREIGN DATA WRAPPER functionality --- Note: local connections that don't use SCRAM pass-through require password --- authentication for this to work properly. Otherwise, you will receive --- the following error from dblink_connect(): +-- FOREIGN DATA WRAPPER 功能 +-- 注意:要使本例正常工作,本地连接必须要求密码认证。 +-- 否则,dblink_connect() 将报告以下错误: -- ERROR: password is required -- DETAIL: Non-superuser cannot connect if the server does not request a password. -- HINT: Target server's authentication method must be changed. @@ -239,8 +196,8 @@ DROP SERVER fdtest; -dblink_connect_u(text connstr) 返回 text -dblink_connect_u(text connname, text connstr) 返回 text +dblink_connect_u(text connstr) returns text +dblink_connect_u(text connname, text connstr) returns text @@ -260,7 +217,7 @@ dblink_connect_u(text connname, text connstr) 返回 text 因此,dblink_connect_u() 在初始安装时会撤销 PUBLIC 的全部权限,从而除了超级用户之外无法调用它。 在某些情况下,可能适合向被认为可信的特定用户授予 - EXECUTE 权限,但必须谨慎操作。还建议服务器用户的任何 + dblink_connect_u()EXECUTE 权限,但必须谨慎操作。还建议服务器用户的任何 ~/.pgpass 文件不要包含指定通配主机名的记录。 @@ -287,8 +244,8 @@ dblink_connect_u(text connname, text connstr) 返回 text -dblink_disconnect() 返回 text -dblink_disconnect(text connname) 返回 text +dblink_disconnect() returns text +dblink_disconnect(text connname) returns text @@ -360,9 +317,9 @@ SELECT dblink_disconnect('myconn'); -dblink(text connname, text sql [, bool fail_on_error]) 返回 setof record -dblink(text connstr, text sql [, bool fail_on_error]) 返回 setof record -dblink(text sql [, bool fail_on_error]) 返回 setof record +dblink(text connname, text sql [, bool fail_on_error]) returns setof record +dblink(text connstr, text sql [, bool fail_on_error]) returns setof record +dblink(text sql [, bool fail_on_error]) returns setof record @@ -439,7 +396,7 @@ SELECT * WHERE proname LIKE 'bytea%'; - FROM 子句中的 alias 部分必须指定该函数将返回的列名和类型。(在别名中指定列名实际上是标准 SQL 语法,但指定列类型则是 + FROM 子句中的 别名 部分必须指定该函数将返回的列名和类型。(在别名中指定列名实际上是标准 SQL 语法,但指定列类型则是 PostgreSQL 的扩展。)这样系统才能在尝试执行该函数之前,就知道 * 应展开成什么,以及 WHERE 子句中的 proname 指的是什么。运行时,如果远程数据库返回的实际查询结果与 @@ -559,9 +516,9 @@ SELECT * FROM dblink('myconn', 'select proname, prosrc from pg_proc') -dblink_exec(text connname, text sql [, bool fail_on_error]) 返回 text -dblink_exec(text connstr, text sql [, bool fail_on_error]) 返回 text -dblink_exec(text sql [, bool fail_on_error]) 返回 text +dblink_exec(text connname, text sql [, bool fail_on_error]) returns text +dblink_exec(text connstr, text sql [, bool fail_on_error]) returns text +dblink_exec(text sql [, bool fail_on_error]) returns text @@ -686,8 +643,8 @@ DETAIL: ERROR: null value in column "relnamespace" violates not-null constrain -dblink_open(text cursorname, text sql [, bool fail_on_error]) 返回 text -dblink_open(text connname, text cursorname, text sql [, bool fail_on_error]) 返回 text +dblink_open(text cursorname, text sql [, bool fail_on_error]) returns text +dblink_open(text connname, text cursorname, text sql [, bool fail_on_error]) returns text @@ -800,8 +757,8 @@ SELECT dblink_open('foo', 'select proname, prosrc from pg_proc'); -dblink_fetch(text cursorname, int howmany [, bool fail_on_error]) 返回 setof record -dblink_fetch(text connname, text cursorname, int howmany [, bool fail_on_error]) 返回 setof record +dblink_fetch(text cursorname, int howmany [, bool fail_on_error]) returns setof record +dblink_fetch(text connname, text cursorname, int howmany [, bool fail_on_error]) returns setof record @@ -943,8 +900,8 @@ SELECT * FROM dblink_fetch('foo', 5) AS (funcname name, source text); -dblink_close(text cursorname [, bool fail_on_error]) 返回 text -dblink_close(text connname, text cursorname [, bool fail_on_error]) 返回 text +dblink_close(text cursorname [, bool fail_on_error]) returns text +dblink_close(text connname, text cursorname [, bool fail_on_error]) returns text @@ -1049,7 +1006,7 @@ SELECT dblink_close('foo'); -dblink_get_connections() 返回 text[] +dblink_get_connections() returns text[] @@ -1065,7 +1022,7 @@ dblink_get_connections() 返回 text[] 返回值 - 返回一个包含连接名称的 text 数组;如果没有,则返回 NULL。 + 返回包含连接名称的文本数组;如果没有连接,则返回 NULL。 @@ -1094,7 +1051,7 @@ SELECT dblink_get_connections(); -dblink_error_message(text connname) 返回 text +dblink_error_message(text connname) returns text @@ -1165,7 +1122,7 @@ SELECT dblink_error_message('dtest1'); -dblink_send_query(text connname, text sql) 返回 int +dblink_send_query(text connname, text sql) returns int @@ -1240,7 +1197,7 @@ SELECT dblink_send_query('dtest1', 'SELECT * FROM foo WHERE f1 < 3'); -dblink_is_busy(text connname) 返回 int +dblink_is_busy(text connname) returns int @@ -1302,8 +1259,8 @@ SELECT dblink_is_busy('dtest1'); -dblink_get_notify() 返回 setof (notify_name text, be_pid int, extra text) -dblink_get_notify(text connname) 返回 setof (notify_name text, be_pid int, extra text) +dblink_get_notify() returns setof (notify_name text, be_pid int, extra text) +dblink_get_notify(text connname) returns setof (notify_name text, be_pid int, extra text) @@ -1382,7 +1339,7 @@ SELECT * FROM dblink_get_notify(); -dblink_get_result(text connname [, bool fail_on_error]) 返回 setof record +dblink_get_result(text connname [, bool fail_on_error]) returns setof record @@ -1528,7 +1485,7 @@ contrib_regression=# SELECT * FROM dblink_get_result('dtest1') AS t1(f1 int, f2 -dblink_cancel_query(text connname) 返回 text +dblink_cancel_query(text connname) returns text @@ -1591,7 +1548,7 @@ SELECT dblink_cancel_query('dtest1'); -dblink_get_pkey(text relname) 返回 setof dblink_pkey_results +dblink_get_pkey(text relname) returns setof dblink_pkey_results @@ -1680,7 +1637,7 @@ dblink_build_sql_insert(text relname, int2vector primary_key_attnums, integer num_primary_key_atts, text[] src_pk_att_vals_array, - text[] tgt_pk_att_vals_array) 返回 text + text[] tgt_pk_att_vals_array) returns text @@ -1749,7 +1706,7 @@ dblink_build_sql_insert(text relname, 返回值 - 以 text 形式返回所请求的 SQL 语句。 + 以文本形式返回所请求的 SQL 语句。 @@ -1796,7 +1753,7 @@ SELECT dblink_build_sql_insert('foo', '1 2', 2, '{"1", "a"}', '{"1", "b''a"}'); dblink_build_sql_delete(text relname, int2vector primary_key_attnums, integer num_primary_key_atts, - text[] tgt_pk_att_vals_array) 返回 text + text[] tgt_pk_att_vals_array) returns text @@ -1856,7 +1813,7 @@ dblink_build_sql_delete(text relname, 返回值 - 以 text 形式返回所请求的 SQL 语句。 + 以文本形式返回所请求的 SQL 语句。 @@ -1904,7 +1861,7 @@ dblink_build_sql_update(text relname, int2vector primary_key_attnums, integer num_primary_key_atts, text[] src_pk_att_vals_array, - text[] tgt_pk_att_vals_array) 返回 text + text[] tgt_pk_att_vals_array) returns text @@ -1974,7 +1931,7 @@ dblink_build_sql_update(text relname, 返回值 - 以 text 形式返回所请求的 SQL 语句。 + 以文本形式返回所请求的 SQL 语句。 diff --git a/zh/16/ddl.sgml b/zh/16/ddl.sgml index 5b89a720..f509d5b2 100644 --- a/zh/16/ddl.sgml +++ b/zh/16/ddl.sgml @@ -232,19 +232,17 @@ INSERT INTO people (id, name, address) VALUES (DEFAULT, 'C' 生成列是一种特殊列,其值总是根据其他列计算得出。因此,对列而言,它就像视图对表一样。生成列有两种:存储型和虚拟型。存储型生成列在写入时(插入或更新时)计算,并像普通列一样占用存储空间。虚拟生成列不占用存储空间,而是在读取时计算。因此,虚拟生成列类似于视图,存储型生成列类似于物化视图(只是它总会自动更新)。 + PostgreSQL 目前只实现了存储型生成列。 - - 要创建生成列,可在CREATE TABLE中使用GENERATED ALWAYS AS子句,例如: - + 要创建生成列,可使用GENERATED ALWAYS + AS子句,在CREATE TABLE中,例如: CREATE TABLE people ( ..., height_cm numeric, - height_in numeric GENERATED ALWAYS AS (height_cm / 2.54) + height_in numeric GENERATED ALWAYS AS (height_cm / 2.54) STORED ); - - 生成列默认是虚拟型。使用关键字VIRTUALSTORED可以显式指定类型。更多细节见。 - +必须指定关键字STORED来选择存储型生成列。参见了解更多细节。 生成列不能直接写入。在INSERTUPDATE命令中,不能为生成列指定值,但可以指定关键字DEFAULT。 @@ -273,11 +271,7 @@ CREATE TABLE people ( 生成表达式不能引用系统列,tableoid 除外。 - - - 虚拟生成列不能使用用户定义类型,并且其生成表达式不得引用用户定义函数或类型,也就是说,它只能使用内置函数或类型。该限制也包括间接使用的情况,例如操作符或类型转换背后的函数或类型。(这一限制不适用于存储型生成列。) - - + 生成列不能具有列默认值或标识定义。 @@ -297,13 +291,9 @@ CREATE TABLE people ( 对于继承和分区: - - 如果父列是生成列,其子列也必须是同种类(存储型或虚拟型)的生成列;不过,子列可以使用不同的生成表达式。 - + 如果父列是生成列,其子列也必须是生成列;不过,子列可以使用不同的生成表达式。在插入或更新一行时,实际应用的是该行所在物理表关联的生成表达式。(这与列默认值不同:默认值使用的是查询中所指名表关联的默认值。) + - - 对于存储型生成列,在插入或更新一行时,实际应用的是该行所在物理表关联的生成表达式。(这与列默认值不同:默认值使用的是查询中所指名表关联的默认值。)对于虚拟生成列,在读取表时,应用的是查询中所指名表的生成表达式。 - @@ -317,7 +307,7 @@ CREATE TABLE people ( - 类似地,对于分区表,如果在CREATE TABLE ... PARTITION OF中编写子列定义时未写任何GENERATED子句,则会自动从父列复制该子句。ALTER TABLE ... ATTACH PARTITION要求父列和子列在生成状态上已经匹配,但不要求它们的生成表达式相同。 + 类似地,对于分区表,如果在CREATE TABLE ... PARTITION OF中编写子列定义时未写任何GENERATED子句,则会自动从父列复制该GENERATED子句。ALTER TABLE ... ATTACH PARTITION要求父列和子列在生成状态上已经匹配,但不要求它们的生成表达式相同。 @@ -338,24 +328,16 @@ CREATE TABLE people ( 生成列与其底层基础列分别维护访问权限。因此,可以安排成某个角色能够读取生成列,但不能读取底层基础列。 - - 对于虚拟生成列,只有在生成表达式只使用防泄漏函数时,这种安排才完全安全(见),但系统不会强制检查这一点。 - - - - - 生成表达式中所用函数的权限,会在表达式实际执行时分别在写入或读取时检查,就像生成表达式是由使用生成列的查询直接调用的一样。生成列的用户必须拥有调用生成表达式中所有函数的权限。生成表达式中的函数是以执行查询的用户的权限还是函数所有者的权限来执行,取决于这些函数被定义为SECURITY INVOKER还是SECURITY DEFINER。 - + + 从概念上说,生成列会在BEFORE触发器运行之后更新。因此,BEFORE触发器中对基础列所做的修改会反映到生成列中。反过来,在BEFORE触发器中访问生成列是不允许的。 - - 生成列会在逻辑复制时被跳过,也不能在CREATE PUBLICATION的列列表中指定。 - + 逻辑复制会跳过生成列,并且不能在CREATE PUBLICATION的列列表中指定生成列。 @@ -1418,7 +1400,7 @@ ALTER TABLE products RENAME TO items; DELETETRUNCATEREFERENCESTRIGGERCREATECONNECTTEMPORARYEXECUTEUSAGE、 - SETALTER SYSTEM以及MAINTAIN。 + SETALTER SYSTEM。 适用于特定对象的权限取决于对象的类型(表、函数等)。 有关这些权限含义的更多详细信息如下所示。 后续的各节和各章还将展示这些权限是如何使用的。 @@ -1667,16 +1649,6 @@ REVOKE ALL ON accounts FROM PUBLIC; - - MAINTAIN - - - 允许在关系上执行VACUUMANALYZE、 - CLUSTERREFRESH MATERIALIZED VIEW、 - 例如 REINDEXVACUUM 这类命令。 - - - 其他命令所需的权限列在各自命令的参考页面上。 @@ -1819,11 +1791,6 @@ REVOKE ALL ON accounts FROM PUBLIC; A PARAMETER - - MAINTAIN - m - TABLE -
@@ -1921,7 +1888,7 @@ REVOKE ALL ON accounts FROM PUBLIC; TABLE(以及类似表的对象) - arwdDxtm + arwdDxt \dp @@ -3436,7 +3403,16 @@ ALTER INDEX measurement_city_id_logdate_key - 创建表,所有的表都将从它继承。这个表将不包含数据。不要在这个表上定义任何检查约束,除非想让它们应用到所有的子表上。同样,在这个表上定义索引或者唯一约束也没有意义。对于我们的示例来说,根表是最初定义的measurement表。 + 创建表,所有的表都将从它继承。这个表将不包含数据。不要在这个表上定义任何检查约束,除非想让它们应用到所有的子表上。同样,在这个表上定义索引或者唯一约束也没有意义。对于我们的示例来说,根表是最初定义的measurement表: + + +CREATE TABLE measurement ( + city_id int not null, + logdate date not null, + peaktemp int, + unitsales int +); + @@ -4045,7 +4021,7 @@ DROP TABLE products CASCADE; - 对于一个将其主体定义为字符串文字的用户定义函数或过程,PostgreSQL会跟踪与函数的外部可见属性相关的依赖关系,例如其参数和结果类型,但不会跟踪只有通过检查函数主体才能知道的依赖关系。例如,考虑以下情况: + 对于一个将其主体定义为字符串字面量的用户定义函数或过程,PostgreSQL会跟踪与函数的外部可见属性相关的依赖关系,例如其参数和结果类型,但不会跟踪只有通过检查函数主体才能知道的依赖关系。例如,考虑以下情况: CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', diff --git a/zh/16/dfunc.sgml b/zh/16/dfunc.sgml index 91898df4..f19e208a 100644 --- a/zh/16/dfunc.sgml +++ b/zh/16/dfunc.sgml @@ -46,18 +46,17 @@ FreeBSD - FreeBSDshared library + FreeBSD共享库 生成 PIC 的编译器选项是 。 创建共享库时使用的编译器选项是 -cc -fPIC -c foo.c -cc -shared -o foo.so foo.o +gcc -fPIC -c foo.c +gcc -shared -o foo.so foo.o - 这从 FreeBSD 13.0 起适用; - 更早版本使用的是 gcc 编译器。 + 这从 FreeBSD 3.0 版起适用。 @@ -65,7 +64,7 @@ cc -shared -o foo.so foo.o Linux - Linuxshared library + Linux共享库 @@ -82,7 +81,7 @@ cc -shared -o foo.so foo.o macOS - macOSshared library + macOS共享库 @@ -98,7 +97,7 @@ cc -bundle -flat_namespace -undefined suppress -o foo.so foo.o NetBSD - NetBSDshared library + NetBSD共享库 @@ -116,7 +115,7 @@ gcc -shared -o foo.so foo.o OpenBSD - OpenBSDshared library + OpenBSD共享库 @@ -133,7 +132,7 @@ ld -Bshareable -o foo.so foo.o Solaris - Solarisshared library + Solaris共享库 diff --git a/zh/16/diskusage.sgml b/zh/16/diskusage.sgml index cfcd855d..be6f91e6 100644 --- a/zh/16/diskusage.sgml +++ b/zh/16/diskusage.sgml @@ -15,15 +15,15 @@ - 每个表都有一个主堆磁盘文件,其中存储了大部分数据。如果该表有任何值可能较宽的列,还可能会有一个与该表关联的TOAST文件,用于存储宽到无法方便地放入主表中的值(见)。如果存在,还会在TOAST表上有一个有效索引。也可能会有与基表关联的索引。每个表和索引都存储在单独的磁盘文件中 — 如果文件会超过 1 GB,则可能分成多个文件。这些文件的命名约定见。 - + 每个表都有一个主堆磁盘文件,大部分数据都存储在那里。如果表中有任何列可能包含较宽的值,还可能有一个与该表关联的 TOAST 文件,用于存储那些不适合放在主表中的过宽值(参见)。如果该 TOAST 表存在,则它会有一个有效索引。基础表本身也可能带有索引。每个表和索引都存储在单独的磁盘文件中;如果某个文件会超过 1 GB,则可能拆分为多个文件。关于这些文件的命名规则,请参见。 + - 可以通过三种方式监控磁盘空间:使用中列出的 SQL 函数,使用模块,或者手工检查系统目录。SQL 函数最容易使用,通常也是推荐的方法。本节其余部分展示如何通过检查系统目录来完成此事。 - + 你可以通过三种方式监控磁盘空间:使用中列出的 SQL 函数、使用模块,或者手工检查系统目录。SQL 函数最容易使用,通常也是推荐的方法。本节余下内容展示如何通过检查系统目录来完成这项工作。 + - 在最近做过 vacuum 或 analyze 的数据库上使用psql时,可以发出查询以查看任意表的磁盘使用情况: + 在最近进行过清理或分析 的数据库上使用 psql,你可以发出查询来查看任意表的磁盘使用情况: SELECT pg_relation_filepath(oid), relpages FROM pg_class WHERE relname = 'customer'; @@ -32,11 +32,11 @@ SELECT pg_relation_filepath(oid), relpages FROM pg_class WHERE relname = 'custom base/16384/16806 | 60 (1 row) - 每个页通常为 8 KB。(请记住,relpages只会由VACUUMANALYZE以及少数 DDL 命令(如CREATE INDEX)更新。)如果你想直接检查该表的磁盘文件,文件路径名就很有用。 - + 每一页通常是 8 KB。(请记住,relpages 只会由 VACUUMANALYZE 以及少数 DDL 命令如 CREATE INDEX 更新。)如果你想直接检查该表的磁盘文件,那么文件路径名会很有用。 + - 要显示TOAST表使用的空间,可使用如下查询: + 要显示 TOAST 表使用的空间,可以使用如下查询: SELECT relname, relpages FROM pg_class, @@ -54,10 +54,10 @@ ORDER BY relname; pg_toast_16806 | 0 pg_toast_16806_index | 1 - + - 也可以很容易地显示索引大小: + 也可以很容易地显示索引所占空间: SELECT c2.relname, c2.relpages FROM pg_class c, pg_class c2, pg_index i @@ -70,10 +70,10 @@ ORDER BY c2.relname; -------------------+---------- customer_id_index | 26 - + - 利用这些信息,可以很容易找出最大的表和索引: + 利用这些信息,你可以很容易地找出最大的表和索引: SELECT relname, relpages FROM pg_class @@ -84,28 +84,28 @@ ORDER BY relpages DESC; bigtable | 3290 customer | 3144 - + 磁盘已满故障 - 数据库管理员最重要的磁盘监控任务,是确保磁盘不会被写满。数据盘被写满不会导致数据损坏,但可能使有用的活动无法继续进行。如果存放 WAL 文件的磁盘逐渐被写满,数据库服务器可能会进入 panic 状态并随后关闭。 - + 数据库管理员最重要的磁盘监控任务,是确保磁盘不会被写满。数据磁盘写满不会导致数据损坏,但可能会阻止有用的活动继续进行。如果保存 WAL 文件的磁盘被写满,则数据库服务器可能会 panic 并随后关闭。 + - 如果无法通过删除其他内容来释放磁盘上的额外空间,可以利用表空间将部分数据库文件移到其他文件系统上。有关更多信息,请参见。 - + 如果你无法通过删除其他文件来释放更多磁盘空间,那么可以利用表空间把部分数据库文件移动到其他文件系统上。详见。 + - 有些文件系统在接近写满时性能很差,因此不要等到磁盘完全写满才采取措施。 - + 有些文件系统在接近写满时性能会明显变差,因此不要等到磁盘完全写满才采取措施。 + - 如果系统支持按用户设置磁盘配额,那么数据库自然会受限于运行服务器的那个用户所被施加的配额。超出配额与磁盘空间完全耗尽会产生同样的不良影响。 - + 如果你的系统支持按用户设置磁盘配额,那么数据库自然也会受到运行服务器的那个用户所拥有配额的限制。超出配额会带来与磁盘空间完全耗尽相同的不良影响。 + diff --git a/zh/16/docguide.sgml b/zh/16/docguide.sgml index 1477ede1..5a04b279 100644 --- a/zh/16/docguide.sgml +++ b/zh/16/docguide.sgml @@ -306,7 +306,7 @@ checking for dbtoepub... dbtoepub - 对于 U.S. letter 格式: + 对于美国信纸格式: doc/src/sgml$ make postgres-US.pdf @@ -320,7 +320,7 @@ checking for dbtoepub... dbtoepub 因此,在某些系统上,构建会因内存相关错误而失败。这通常可以通过在配置文件 ~/.foprc中配置 Java 堆设置来解决,例如: -# FOP binary distribution +# FOP 二进制发行版 FOP_OPTS='-Xmx1500m' # Debian JAVA_ARGS='-Xmx1500m' @@ -345,6 +345,21 @@ LOGLEVEL=-Dorg.apache.commons.logging.simplelog.defaultlog=WARN + + 纯文本文件 + + + 安装说明也以纯文本形式分发,以便在没有更好的阅读工具时使用。 + INSTALL文件对应,并针对不同语境作了少量调整。 + 要重新生成该文件,请切换到doc/src/sgml目录,然后输入make INSTALL。 + 构建文本输出还需要Pandoc 1.13 或更新版本作为额外的构建工具。 + + + + 过去,发行说明和回归测试说明也曾以纯文本形式分发,但现已停止这种做法。 + + + 语法检查 diff --git a/zh/16/ecpg.sgml b/zh/16/ecpg.sgml index 46ce5efb..d844c57c 100644 --- a/zh/16/ecpg.sgml +++ b/zh/16/ecpg.sgml @@ -1139,7 +1139,7 @@ oid=313780, datname=testdb, size=8183012 - 结构体主变量将列尽数吸收成结构体的域。额外的列可以被分配给其他主变量。例如,上面的程序也可以使用结构体外部的size变量重新构造: + 结构体主变量吸收的列数与结构体的字段数相同。额外的列可以被分配给其他主变量。例如,上面的程序也可以使用结构体外部的size变量改写: EXEC SQL BEGIN DECLARE SECTION; typedef struct @@ -1440,7 +1440,7 @@ while (1) 用户定义的基础类型 - ECPG 并不直接支持新的用户定义的基本类型。你可以使用外部字符串表示以及类型char[]VARCHAR[]的主变量,并且这种方案事实上对很多类型都是合适和足够的。 + ECPG 并不直接支持新的用户定义的基础类型。你可以使用外部字符串表示以及类型char[]VARCHAR[]的主变量,并且这种方案事实上对很多类型都是合适和足够的。 @@ -3980,7 +3980,6 @@ datdba = 10 (type: 1) encoding = 0 (type: 5) datistemplate = t (type: 1) datallowconn = t (type: 1) -dathasloginevt = f (type: 1) datconnlimit = -1 (type: 5) datfrozenxid = 379 (type: 1) dattablespace = 1663 (type: 1) @@ -4005,7 +4004,6 @@ datdba = 10 (type: 1) encoding = 0 (type: 5) datistemplate = f (type: 1) datallowconn = t (type: 1) -dathasloginevt = f (type: 1) datconnlimit = -1 (type: 5) datfrozenxid = 379 (type: 1) dattablespace = 1663 (type: 1) @@ -4743,7 +4741,7 @@ EXEC SQL INCLUDE "filename"; 当前目录 /usr/local/include - PostgreSQL 的包括目录,在编译时定义(例如/usr/local/pgsql/include + PostgreSQL 的头文件目录,在编译时定义(例如/usr/local/pgsql/include /usr/include @@ -4870,7 +4868,7 @@ EXEC SQL UPDATE Tbl SET col = MYNUMBER; - 此示例将完全编译三个SET TIMEZONE命令之一: + 此示例将完全编译三个SET TIMEZONE命令之一: EXEC SQL ifdef TZVAR; EXEC SQL SET TIMEZONE TO TZVAR; @@ -5498,7 +5496,7 @@ DATABASE connection_target 使用 user_name/passworduser_name IDENTIFIED BY password或者 - user_name USING password之一,这个参数也能指定用户名和密码. + user_name USING password之一,这个参数也能指定用户名和密码。 @@ -6078,9 +6076,7 @@ EXECUTE IMMEDIATE string - 如果你使用文字字符串,请注意任何你可能希望在SQL语句中包括的双引号必须写为八进制转义(\042) ,而不是通常的C惯语\"。 - 这是因为字符串在EXEC SQL段里面,所以ECPG 语法分析器根据SQL规则而不是C规则来解析它。 - 任何内嵌的反斜杠后续将按照C规格处理;但是\"会造成直接语法错误,因为它被视为文字的终结。 + 如果使用字符串字面量,请注意,要在 SQL 语句中包含的双引号必须写为八进制转义(\042),而不是通常的 C 写法\"。这是因为字符串位于EXEC SQL段中,ECPG 词法分析器会按照 SQL 规则而非 C 规则解析它。内嵌的反斜杠随后会按照 C 规则处理;但\"会被视为字面量的结束,因此会立即引起语法错误。 @@ -6413,9 +6409,7 @@ PREPARE prepared_name FROM - 如果你使用文字字符串,请注意任何你可能希望在SQL语句中包括的双引号必须写为八进制转义(\042) ,而不是通常的C惯语\"。 - 这是因为字符串在EXEC SQL段里面,所以ECPG 语法分析器根据SQL规则而不是C规则来解析它。 - 任何内嵌的反斜杠后续将按照C规格处理;但是\"会造成直接语法错误,因为它被视为文字的终结。 + 如果使用字符串字面量,请注意,要在 SQL 语句中包含的双引号必须写为八进制转义(\042),而不是通常的 C 写法\"。这是因为字符串位于EXEC SQL段中,ECPG 词法分析器会按照 SQL 规则而非 C 规则解析它。内嵌的反斜杠随后会按照 C 规则处理;但\"会被视为字面量的结束,因此会立即引起语法错误。 @@ -7672,19 +7666,19 @@ int rjulmdy(date d, short mdy[3]); rdefmtdate - 使用格式掩码将字符字符串转换为日期类型的值。 + 使用格式掩码将字符串转换为日期类型的值。 int rdefmtdate(date *d, char *fmt, char *str); 该函数接收一个指向应该保存操作结果的日期值的指针(d), 用于解析日期的格式掩码(fmt)和包含日期文本表示的C char*字符串 (str)。文本表示应与格式掩码匹配。但是,你不需要将字符串 - 与格式掩码进行一一映射。该函数仅分析顺序顺序,并查找表示年份位置的文字 + 与格式掩码进行一一映射。该函数只分析先后顺序,并查找表示年份位置的字面文本 yyyyyy,表示月份位置的mm 和表示日期位置的dd - 该函数返回以下值: + 该函数返回以下值: diff --git a/zh/16/event-trigger.sgml b/zh/16/event-trigger.sgml index 8c2404df..306d9e25 100644 --- a/zh/16/event-trigger.sgml +++ b/zh/16/event-trigger.sgml @@ -20,12 +20,11 @@ - 事件触发器行为概览 + 事件触发器行为概述 只要与事件触发器关联的事件在其定义所在数据库中发生,事件触发器就会被触发。 - 目前支持的事件有 - login、 + 目前仅支持以下事件: ddl_command_startddl_command_endtable_rewrite @@ -33,120 +32,49 @@ 未来版本可能会增加对更多事件的支持。 - - login - - - 当已认证用户登录系统时,会发生 login 事件。 - 该事件的触发器过程中的任何缺陷都可能导致系统无法成功登录。 - 可以通过在连接字符串或配置文件中将 设为 - false 来绕过这类问题。或者,也可以将系统重启到单用户模式 - (该模式下事件触发器被禁用)。关于如何使用单用户模式的细节,参见 - 参考页。 - login 事件也会在备库上触发。 - 为防止服务器变得无法访问,这类触发器在备库上运行时必须避免向数据库写 - 入任何内容。此外,还建议避免在 login 事件触发器中执行长 - 时间运行的查询。请注意,例如在 psql 中取消一个连 - 接,并不会取消正在执行中的 login 触发器。 - - - - 关于如何使用 login 事件触发器的示例,参见 - 。 - - - - - ddl_command_start - - - ddl_command_start 事件发生在 DDL 命令即将执行之前。 - 此处的 DDL 命令包括: - - CREATE - ALTER - DROP - COMMENT - GRANT - IMPORT FOREIGN SCHEMA - REINDEX - REFRESH MATERIALIZED VIEW - REVOKE - SECURITY LABEL - + + ddl_command_start 事件发生在 + CREATEALTERDROP、 + SECURITY LABEL、 + COMMENTGRANTREVOKE + 命令即将执行之前。在事件触发器触发之前,不会检查受影响对象究竟存在还是不存在。 + 但有一个例外:对于以共享对象 — 数据库、角色和表空间 — + 为目标的 DDL 命令或者针对事件触发器本身的命令,不会发生该事件。事件触发器机制 + 不支持这些对象类型。 ddl_command_start 也会在 SELECT INTO 命令即将执行之前发生,因为它等价于 CREATE TABLE AS - - 但有一个例外:对于以共享对象为目标的 DDL 命令,不会发生该事件: - - 数据库 - 角色(角色定义和角色成员关系) - 表空间 - 参数权限 - ALTER SYSTEM - - 针对事件触发器本身的命令也不会引发该事件。 - - - - 在事件触发器触发之前,不会检查受影响对象究竟存在还是不存在。 - - - - - ddl_command_end - - - ddl_command_end 事件发生在与 - ddl_command_start 相同的一组命令执行之后。 + + ddl_command_end 事件发生在上述同一组命令执行之后。 要获取这些 DDL 操作的更多细节,可在 ddl_command_end 事件触发器代码中使用集合返回函数 pg_event_trigger_ddl_commands()(见 )。注意,触发器是在这些动作已发生 之后(但在事务提交之前)触发的,因此读取系统目录时,看到的已是变更后的状态。 - - - sql_drop - - + 对于任何删除数据库对象的操作,sql_drop 事件都发生在 - ddl_command_end 事件触发器之前。请注意,除了显而易见的 - DROP 命令外,某些 ALTER 命令也会触发 - sql_drop 事件。 - - - - 要列出已删除的对象,可在 sql_drop 事件触发器代码中使用 + ddl_command_end 事件触发器之前。要列出已删除的对象,可在 + sql_drop 事件触发器代码中使用 集合返回函数 pg_event_trigger_dropped_objects()(见 )。注意,触发器是在这些对象已经从 系统目录中删除之后执行的,因此已无法再查找它们。 - - - - table_rewrite - + table_rewrite 事件发生在表即将因 ALTER TABLEALTER TYPE 命令中的某些 操作而被重写之前。虽然还有其他控制语句也可以重写表,例如 CLUSTERVACUUM,但它们不会触发 table_rewrite 事件。要找出被重写表的 OID,请使用函数 - pg_event_trigger_table_rewrite_oid();要找出重写的一个或多个 - 原因, - 可使用函数 pg_event_trigger_table_rewrite_reason()(见 )。 + pg_event_trigger_table_rewrite_oid()(见 + )。要找出重写的一个或多个原因, + 可使用函数 pg_event_trigger_table_rewrite_reason() - - - - 已中止事务中的事件触发器 - + 事件触发器(与其他函数一样)不能在已中止的事务中执行。因此,如果 DDL 命令因 错误而失败,任何关联的 ddl_command_end 触发器都不会执行。 反之,如果 ddl_command_start 触发器因错误而失败,后续事 @@ -154,12 +82,13 @@ ddl_command_end 触发器因错误而失败,DDL 语句的效果将被回 滚,就像包含该语句的事务在任何其他情况下中止时那样。 - - - - 创建事件触发器 + 有关事件触发器机制所支持命令的完整列表,参见 + 。 + + + 事件触发器通过命令 创建。 为了创建事件触发器,必须先创建一个返回类型为 event_trigger 的特殊函数。 @@ -176,7 +105,927 @@ ddl_command_start 触发器就可以只针对用户希望拦截的特定命 令触发。这类触发器的一个常见用途是限制用户可执行的 DDL 操作范围。 - + + + + 事件触发器触发矩阵 + + + 列出了事件触发器所支持的 + 所有命令。 + + + + 按命令标签分类的事件触发器支持 + + + + + + + + + + 命令标签 + ddl_&zwsp;command_&zwsp;start + ddl_&zwsp;command_&zwsp;end + sql_&zwsp;drop + table_&zwsp;rewrite + 备注 + + + + + ALTER AGGREGATE + X + X + - + - + + + + ALTER COLLATION + X + X + - + - + + + + ALTER CONVERSION + X + X + - + - + + + + ALTER DOMAIN + X + X + - + - + + + + ALTER DEFAULT PRIVILEGES + X + X + - + - + + + + ALTER EXTENSION + X + X + - + - + + + + ALTER FOREIGN DATA WRAPPER + X + X + - + - + + + + ALTER FOREIGN TABLE + X + X + X + - + + + + ALTER FUNCTION + X + X + - + - + + + + ALTER LANGUAGE + X + X + - + - + + + + ALTER LARGE OBJECT + X + X + - + - + + + + ALTER MATERIALIZED VIEW + X + X + - + X + + + + ALTER OPERATOR + X + X + - + - + + + + ALTER OPERATOR CLASS + X + X + - + - + + + + ALTER OPERATOR FAMILY + X + X + - + - + + + + ALTER POLICY + X + X + - + - + + + + ALTER PROCEDURE + X + X + - + - + + + + ALTER PUBLICATION + X + X + - + - + + + + ALTER ROUTINE + X + X + - + - + + + + ALTER SCHEMA + X + X + - + - + + + + ALTER SEQUENCE + X + X + - + - + + + + ALTER SERVER + X + X + - + - + + + + ALTER STATISTICS + X + X + - + - + + + + ALTER SUBSCRIPTION + X + X + - + - + + + + ALTER TABLE + X + X + X + X + + + + ALTER TEXT SEARCH CONFIGURATION + X + X + - + - + + + + ALTER TEXT SEARCH DICTIONARY + X + X + - + - + + + + ALTER TEXT SEARCH PARSER + X + X + - + - + + + + ALTER TEXT SEARCH TEMPLATE + X + X + - + - + + + + ALTER TRIGGER + X + X + - + - + + + + ALTER TYPE + X + X + - + X + + + + ALTER USER MAPPING + X + X + - + - + + + + ALTER VIEW + X + X + - + - + + + + COMMENT + X + X + - + - + 仅限本地对象 + + + CREATE ACCESS METHOD + X + X + - + - + + + + CREATE AGGREGATE + X + X + - + - + + + + CREATE CAST + X + X + - + - + + + + CREATE COLLATION + X + X + - + - + + + + CREATE CONVERSION + X + X + - + - + + + + CREATE DOMAIN + X + X + - + - + + + + CREATE EXTENSION + X + X + - + - + + + + CREATE FOREIGN DATA WRAPPER + X + X + - + - + + + + CREATE FOREIGN TABLE + X + X + - + - + + + + CREATE FUNCTION + X + X + - + - + + + + CREATE INDEX + X + X + - + - + + + + CREATE LANGUAGE + X + X + - + - + + + + CREATE MATERIALIZED VIEW + X + X + - + - + + + + CREATE OPERATOR + X + X + - + - + + + + CREATE OPERATOR CLASS + X + X + - + - + + + + CREATE OPERATOR FAMILY + X + X + - + - + + + + CREATE POLICY + X + X + - + - + + + + CREATE PROCEDURE + X + X + - + - + + + + CREATE PUBLICATION + X + X + - + - + + + + CREATE RULE + X + X + - + - + + + + CREATE SCHEMA + X + X + - + - + + + + CREATE SEQUENCE + X + X + - + - + + + + CREATE SERVER + X + X + - + - + + + + CREATE STATISTICS + X + X + - + - + + + + CREATE SUBSCRIPTION + X + X + - + - + + + + CREATE TABLE + X + X + - + - + + + + CREATE TABLE AS + X + X + - + - + + + + CREATE TEXT SEARCH CONFIGURATION + X + X + - + - + + + + CREATE TEXT SEARCH DICTIONARY + X + X + - + - + + + + CREATE TEXT SEARCH PARSER + X + X + - + - + + + + CREATE TEXT SEARCH TEMPLATE + X + X + - + - + + + + CREATE TRIGGER + X + X + - + - + + + + CREATE TYPE + X + X + - + - + + + + CREATE USER MAPPING + X + X + - + - + + + + CREATE VIEW + X + X + - + - + + + + DROP ACCESS METHOD + X + X + X + - + + + + DROP AGGREGATE + X + X + X + - + + + + DROP CAST + X + X + X + - + + + + DROP COLLATION + X + X + X + - + + + + DROP CONVERSION + X + X + X + - + + + + DROP DOMAIN + X + X + X + - + + + + DROP EXTENSION + X + X + X + - + + + + DROP FOREIGN DATA WRAPPER + X + X + X + - + + + + DROP FOREIGN TABLE + X + X + X + - + + + + DROP FUNCTION + X + X + X + - + + + + DROP INDEX + X + X + X + - + + + + DROP LANGUAGE + X + X + X + - + + + + DROP MATERIALIZED VIEW + X + X + X + - + + + + DROP OPERATOR + X + X + X + - + + + + DROP OPERATOR CLASS + X + X + X + - + + + + DROP OPERATOR FAMILY + X + X + X + - + + + + DROP OWNED + X + X + X + - + + + + DROP POLICY + X + X + X + - + + + + DROP PROCEDURE + X + X + X + - + + + + DROP PUBLICATION + X + X + X + - + + + + DROP ROUTINE + X + X + X + - + + + + DROP RULE + X + X + X + - + + + + DROP SCHEMA + X + X + X + - + + + + DROP SEQUENCE + X + X + X + - + + + + DROP SERVER + X + X + X + - + + + + DROP STATISTICS + X + X + X + - + + + + DROP SUBSCRIPTION + X + X + X + - + + + + DROP TABLE + X + X + X + - + + + + DROP TEXT SEARCH CONFIGURATION + X + X + X + - + + + + DROP TEXT SEARCH DICTIONARY + X + X + X + - + + + + DROP TEXT SEARCH PARSER + X + X + X + - + + + + DROP TEXT SEARCH TEMPLATE + X + X + X + - + + + + DROP TRIGGER + X + X + X + - + + + + DROP TYPE + X + X + X + - + + + + DROP USER MAPPING + X + X + X + - + + + + DROP VIEW + X + X + X + - + + + + GRANT + X + X + - + - + 仅限本地对象 + + + IMPORT FOREIGN SCHEMA + X + X + - + - + + + + REFRESH MATERIALIZED VIEW + X + X + - + - + + + + REVOKE + X + X + - + - + 仅限本地对象 + + + SECURITY LABEL + X + X + - + - + 仅限本地对象 + + + SELECT INTO + X + X + - + - + + + + +
@@ -210,7 +1059,7 @@ CALLED_AS_EVENT_TRIGGER(fcinfo) ((fcinfo)->context != NULL && IsA((fcinfo)->context, EventTriggerData)) - 如果该宏返回 true,那么就可以安全地将 fcinfo->context + 如果该宏返回真,那么就可以安全地将 fcinfo->context 转换为 EventTriggerData * 类型,并使用它所指向的 EventTriggerData 结构体。该函数 不得修改 EventTriggerData @@ -248,7 +1097,7 @@ typedef struct EventTriggerData 描述调用该函数对应的事件,可为 - "login""ddl_command_start"、 + "ddl_command_start""ddl_command_end""sql_drop""table_rewrite" 之一。 关于这些事件的含义,参见 。 @@ -281,7 +1130,7 @@ typedef struct EventTriggerData 事件触发器函数必须返回一个 NULL 指针 (不是 SQL 空值,也就是不要将 - isNull 设为 true)。 + isNull 设为真)。 @@ -300,13 +1149,10 @@ typedef struct EventTriggerData 中提到的例外)。
- - 以下是该触发器函数的源代码: -下面是触发器函数的源代码: - - - 数据库登录事件触发器示例 - - - 作用于 login 事件的事件触发器可用于记录用户登录、验证连 - 接并根据当前情况分配角色,或者初始化会话数据。非常重要的一点是,任何使用 - login 事件的事件触发器在执行任何写操作之前都必须检查数 - 据库是否处于恢复状态。向备库写入会导致其变得不可访问。 - - - - 以下示例演示了这些用法。 - --- create test tables and roles -CREATE TABLE user_login_log ( - "user" text, - "session_start" timestamp with time zone -); -CREATE ROLE day_worker; -CREATE ROLE night_worker; - --- the example trigger function -CREATE OR REPLACE FUNCTION init_session() - RETURNS event_trigger SECURITY DEFINER - LANGUAGE plpgsql AS -$$ -DECLARE - hour integer = EXTRACT('hour' FROM current_time at time zone 'utc'); - rec boolean; -BEGIN --- 1. Forbid logging in between 2AM and 4AM. -IF hour BETWEEN 2 AND 4 THEN - RAISE EXCEPTION 'Login forbidden'; -END IF; - --- The checks below cannot be performed on standby servers so --- ensure the database is not in recovery before we perform any --- operations. -SELECT pg_is_in_recovery() INTO rec; -IF rec THEN - RETURN; -END IF; - --- 2. Assign some roles. At daytime, grant the day_worker role, else the --- night_worker role. -IF hour BETWEEN 8 AND 20 THEN - EXECUTE 'REVOKE night_worker FROM ' || quote_ident(session_user); - EXECUTE 'GRANT day_worker TO ' || quote_ident(session_user); -ELSE - EXECUTE 'REVOKE day_worker FROM ' || quote_ident(session_user); - EXECUTE 'GRANT night_worker TO ' || quote_ident(session_user); -END IF; - --- 3. Initialize user session data -CREATE TEMP TABLE session_storage (x float, y integer); -ALTER TABLE session_storage OWNER TO session_user; - --- 4. Log the connection time -INSERT INTO public.user_login_log VALUES (session_user, current_timestamp); - -END; -$$; - --- trigger definition -CREATE EVENT TRIGGER init_session - ON login - EXECUTE FUNCTION init_session(); -ALTER EVENT TRIGGER init_session ENABLE ALWAYS; - - - diff --git a/zh/16/extend.sgml b/zh/16/extend.sgml index 6749ade7..a37a4b09 100644 --- a/zh/16/extend.sgml +++ b/zh/16/extend.sgml @@ -59,7 +59,7 @@ 类型、函数、访问方法等的信息。这些表可以由用户修改,而 PostgreSQL 又是基于这些表来运行的,这意味着 PostgreSQL 可以由用户扩展。相比之下,传统数据库 - 系统通常只能通过修改源代码中的硬编码过程,或加载由 + 系统只能通过修改源代码中的硬编码过程,或加载由 DBMS 供应商专门编写的模块来扩展。
@@ -92,7 +92,7 @@ 数据类型 - 组合 + 复合 @@ -517,7 +517,7 @@ RETURNS anycompatible AS ... 哪些 SQL 对象种类可以成为扩展成员,见 ALTER EXTENSION 的说明。特别是,数据库集簇范围内的对象,如数据库、角色和表空间,不能 - 成为扩展成员,因为扩展只在单个数据库内可见。(尽管扩展脚本并不禁止创 + 成为扩展成员,因为扩展只在单个数据库内可见。(尽管并不禁止扩展脚本创 建这类对象,但如果这样做,它们不会作为扩展的一部分受到跟踪。)还要注意, 虽然表可以成为扩展成员,但其附属对象(如索引)并不直接被视为扩展成员。 另一个重要点是,模式可以属于扩展,但反过来不成立:扩展本身只有一个非 @@ -552,10 +552,7 @@ RETURNS anycompatible AS ... 件指定不同的目录。 - - 扩展控制文件的其他查找位置可通过参数 - extension_control_path 配置。 - + 扩展控制文件的格式与 postgresql.conf 文件相同, @@ -575,8 +572,8 @@ RETURNS anycompatible AS ... 包含扩展 SQL 脚本文件的目录。除非给出的是绝对路 - 径,否则该名称相对于找到控制文件的目录。默认情况下,会在找到控制 - 文件的同一目录中查找脚本文件。 + 径,否则该名称相对于安装的 SHAREDIR 目录。默认行为 + 等价于指定 directory = 'extension'
@@ -621,8 +618,8 @@ RETURNS anycompatible AS ... 该参数的值会替换脚本文件中每次出现的 MODULE_PATHNAME。如果未设置该参数,则不会进行替 - 换。通常会把它设置为简单的 - shared_library_name, + 换。通常会把它设置为 + $libdir/shared_library_name, 然后在 C 语言函数的 CREATE FUNCTION 命令中使用 MODULE_PATHNAME,这样脚本文件就无需把共享库的名 字硬编码进去。 @@ -672,21 +669,7 @@ RETURNS anycompatible AS ... trusted (boolean) - - 如果该参数被设为 true(默认并非如此),则允许某些 - 非超级用户安装 superuser 设为 - true 的扩展。具体来说,任何在当前数据库上具有 - CREATE 权限的用户都被允许安装。当执行 - CREATE EXTENSION 的用户不是超级用户,但因该参数 - 而被允许安装时,安装或更新脚本会以引导超级用户的身份运行,而不是以 - 调用用户的身份运行。如果 superuser 为 - false,这个参数就没有意义。一般来说,对于可能让 - 用户访问原本只有超级用户才能使用的能力(如文件系统访问)的扩展,不 - 应把它设为 true。此外,把一个扩展标记为 - trusted,还需要付出大量额外努力来确保安装和更 - 新脚本写得足够安全;见 - 。 - + 如果将此参数设为 true(不是默认值),则允许某些非超级用户安装 superuser 设为 true 的扩展。具体而言,当前数据库上具有 CREATE 权限的任何人都可以安装。当执行 CREATE EXTENSION 的用户不是超级用户,但凭借此参数获准安装时,安装或更新脚本会以引导超级用户的身份运行,而不是调用用户的身份。如果 superuserfalse,则此参数不起作用。通常,对于可能允许访问原本仅限超级用户使用的能力(例如文件系统访问)的扩展,不应将此参数设为真。此外,将扩展标记为受信任的,需要投入大量额外工作来安全地编写其安装和更新脚本;参见 @@ -747,8 +730,8 @@ RETURNS anycompatible AS ... 如果扩展脚本中包含字符串 @extowner@,该字符串会被 替换为调用 CREATE EXTENSION 或 - ALTER EXTENSION 的用户名称(会作适当引用)。通常, - 这个特性被标记为 trusted 的扩展用来把选定对象的 + ALTER EXTENSION 的用户名称(会适当加上引号)。通常, + 这个特性被标记为受信任的扩展用来把选定对象的 所有权赋给调用用户, 而不是赋给引导超级用户。(不过这样做时应当谨慎。例如,把一个 C 语言 函数的所有权赋给非超级用户,会为该用户创建一条权限提升路径。) @@ -973,7 +956,7 @@ SELECT pg_catalog.pg_extension_config_dump('my_config', 'WHERE NOT standard_entr 在有合适更新脚本可用的前提下, - ALTER EXTENSION UPDATE 命令可以把已安装的扩展更新 + ALTER EXTENSION UPDATE 命令会把已安装的扩展更新 到指定的新版本。更新脚本运行在 CREATE EXTENSION 为安装脚本提供的同一环境中:尤其 是,search_path 的设置方式完全相同,而且脚本创建的 @@ -999,7 +982,7 @@ SELECT pg_catalog.pg_extension_config_dump('my_config', 'WHERE NOT standard_entr 例如,它并不知道 1.1 是否跟在 1.0 之后。它只是匹配可用的版本名,并选择需要应用 更新脚本最少的那条路径。(实际上,版本名可以是任何不包含 - --,且不以前导或尾随 - 结尾的字 + --,且不以 - 开头或结尾的字 符串。) @@ -1072,19 +1055,9 @@ SELECT * FROM pg_extension_update_paths('extension_name - - 将 superuser 属性设为 true 的 - 扩展,还必须考虑其安装脚本和更新脚本中操作所带来的安全风险。恶意用户并不难创建出特洛伊木 - 马对象,从而在后续粗心编写的扩展脚本执行时造成破坏,并借此获得超级用 - 户权限。 - + superuser 属性设为真的扩展,还必须考虑其安装和更新脚本所执行操作的安全风险。恶意用户可以创建木马对象,破坏以后对编写不慎的扩展脚本的执行,从而获得超级用户权限;这并非特别困难。 - - 如果一个扩展被标记为 trusted,那么安装用户可以自己 - 选择安装模式,而该用户可能会有意使用不安全的模式,希望借此获得超级用 - 户权限。因此,从安全角度看,trusted 扩展暴露程度 - 极高,必须仔细审查其所有脚本命令,确保不存在任何可被利用之处。 - + 如果扩展被标记为 trusted,那么安装用户可以选择其安装模式,而该用户可能故意使用不安全的模式,试图获得超级用户权限。因此,从安全角度看,受信任的扩展面临的风险极高,必须仔细检查其全部脚本命令,确保无法被攻破。 关于如何安全地编写函数,建议见下面的 @@ -1132,7 +1105,7 @@ SELECT * FROM pg_extension_update_paths('extension_namemyschema.myfunc(bigint),那么像 myschema.myfunc(42) 这样的调用,就可能被恶意函数 myschema.myfunc(integer) 截获。要注意函数和操作符 - 参数的数据类型必须与声明的实参类型精确匹配,必要时请使用显式类型转 + 所传参数的数据类型必须与声明的参数类型精确匹配,必要时请使用显式类型转 换。 @@ -1169,10 +1142,12 @@ SELECT * FROM pg_extension_update_paths('extension_name - 安全的跨扩展引用通常要求使用 - @extschema:name@ 语法为其 - 他扩展对象的名称加上模式限定,并且还要仔细匹配函数和操作符的参数类 - 型。 + 跨扩展引用要做到完全安全是极其困难的,部分原因是无法确定另一个扩展 + 位于哪个模式中。如果两个扩展都安装在同一个模式中,风险就会降低, + 因为这样恶意对象就无法在安装时的 search_path 中 + 被放到被引用扩展之前。但目前还没有机制来强制要求这一点。就目前而言, + 最佳实践是:如果一个扩展依赖于另一个扩展,就不要将它标记为受信任的, + 除非那个被依赖的扩展始终安装在 pg_catalog 中。 @@ -1181,7 +1156,7 @@ SELECT * FROM pg_extension_update_paths('extension_name扩展示例 - 下面给出一个纯 SQL 扩展的完整示例:一个双元素组合 + 下面给出一个纯 SQL 扩展的完整示例:一个双元素复合 类型,它可以在两个槽位中存储任意类型的值,这两个槽位名为 kv。非文本值会自动强制转换为文本后 再存储。 @@ -1262,7 +1237,7 @@ include $(PGXS) 如果你打算分发自己的 PostgreSQL 扩展模块, - 那么为它们搭建一个可移植的构建系统会相当困难。因此, + 那么为它们搭建一个可移植的构建系统可能相当困难。因此, PostgreSQL 安装提供了一套称为 PGXS 的扩展构建基础设施,使简单的扩展模块可以针对 已安装好的服务器直接构建。PGXS 主要面向包含 C 代码 @@ -1313,7 +1288,7 @@ include $(PGXS) MODULE_big - 要从多个源文件构建的共享库(在 OBJS 中列出对象 + 要从多个源文件构建的共享库(在 OBJS 中列出目标 文件) @@ -1323,7 +1298,7 @@ include $(PGXS) PROGRAM - 要构建的可执行程序(在 OBJS 中列出对象文件) + 要构建的可执行程序(在 OBJS 中列出目标文件)
@@ -1618,33 +1593,7 @@ include $(PGXS) make 命令行上设置都可以。 - - 你还可以在执行 make install 时,通过设置 - make 变量 prefix 来选择一个独立 - 的目录前缀,以安装扩展文件,例如: - -make install prefix=/usr/local/postgresql - - 这样会把扩展控制文件和 SQL 文件安装到 - /usr/local/postgresql/share,把共享模块安装到 - /usr/local/postgresql/lib。如果该前缀不包含 - postgrespgsql 字符串,例如: - -make install prefix=/usr/local/extras - - 那么 postgresql 会被附加到目录名中,从而把控制文件 - 和 SQL 文件安装到 - /usr/local/extras/share/postgresql/extension, - 把共享模块安装到 - /usr/local/extras/lib/postgresql。无论哪种情况, - 你都需要设置 extension_control_path 和 - ,以便 - PostgreSQL 服务器能找到这些文件: - -extension_control_path = '/usr/local/extras/share/postgresql:$system' -dynamic_library_path = '/usr/local/extras/lib/postgresql:$libdir' - - + 如果你想保持构建目录与源代码目录分离,也可以在扩展源代码树之外的目录 @@ -1678,7 +1627,7 @@ make VPATH=/path/to/extension/source/tree install 正在运行的 PostgreSQL 服务器。列在 REGRESS 中的脚本文件必须位于扩展目录下名为 sql/ 的子目录中。这些文件必须具有 - .sql 扩展名,而该扩展名不应出现在 makefile 的 + .sql 扩展名,而该扩展名不能出现在 makefile 的 REGRESS 列表中。对于每个测试,还应在名为 expected/ 的子目录中有一个包含期望输出的文件,其主 干名相同,扩展名为 .out。 @@ -1697,7 +1646,7 @@ make VPATH=/path/to/extension/source/tree install 必须有一个正在运行的 PostgreSQL 服务器。列 在 ISOLATION 中的脚本文件必须位于扩展目录下名为 specs/ 的子目录中。这些文件必须具有 - .spec 扩展名,而该扩展名不应出现在 makefile 的 + .spec 扩展名,而该扩展名不能出现在 makefile 的 ISOLATION 列表中。对于每个测试,还应在名为 expected/ 的子目录中有一个包含期望输出的文件,其主 干名相同,扩展名为 .out。 diff --git a/zh/16/features.sgml b/zh/16/features.sgml index f212af45..866569f6 100644 --- a/zh/16/features.sgml +++ b/zh/16/features.sgml @@ -408,7 +408,7 @@ SELECT XMLQUERY('$a is $b' PASSING BY VALUE x AS a, < DOCUMENTCONTENT形式的值。 一个 XQuery/XPath 表达式的上下文项必须是单个 XML 节点或原子值, 但 XPath 1.0 又进一步限制它只能是 XML 节点,并且没有允许CONTENT的节点类型。 - 归根结底,格式良好的DOCUMENT是 + 归根结底,良构的DOCUMENTPostgreSQL能够作为 XPath 上下文项提供的唯一 XML 值形式。 diff --git a/zh/16/func.sgml b/zh/16/func.sgml index dc4c0e80..e75f23e6 100644 --- a/zh/16/func.sgml +++ b/zh/16/func.sgml @@ -39,20 +39,17 @@ repeat('Pg', 4) PgPgPgPg 逻辑操作符 - operator - logical + 操作符 + 逻辑 - Boolean - operators - operators, logical + 布尔 + 操作符 + 操作符,逻辑 - - 常用的逻辑操作符有: - - + 可以使用以下常见逻辑操作符: AND(操作符) @@ -65,15 +62,15 @@ repeat('Pg', 4) PgPgPgPg - conjunction + 合取 - disjunction + 析取 - negation + 否定 @@ -82,9 +79,7 @@ repeat('Pg', 4) PgPgPgPg NOT boolean boolean - SQL使用三值的逻辑系统,包括真、假和nullnull表示未知。观察下面的真值表: - - + SQL使用由真、假和null构成的三值逻辑系统,其中null表示未知。请看下面的真值表: @@ -181,8 +176,8 @@ repeat('Pg', 4) PgPgPgPg 比较函数和操作符 - comparison - operators + 比较 + 操作符 @@ -265,14 +260,14 @@ repeat('Pg', 4) PgPgPgPg - <> 表示 not equal 的标准 SQL 符号。 - != 是一个别名,在解析的早期阶段会被转换为 <>。 - 因此,它不可能实现 !=<> 操作符分别表示不同的含义。 + <>不等于 的标准 SQL 符号。 + != 是一个别名,在解析的早期阶段就会被转换为 <>。 + 因此,不可能让 !=<> 操作符执行不同的操作。 - 这些比较操作符适用于所有具有自然排序的内置数据类型,包括数字、字符串和日期/时间类型。 + 这些比较操作符适用于所有具有自然排序的内置数据类型,包括数值、字符串和日期/时间类型。 此外,如果其组成数据类型具有可比性,则也可以比较数组、复合类型和范围。 @@ -318,7 +313,7 @@ repeat('Pg', 4) PgPgPgPg boolean - 之间(包括范围端点)。 + 位于两者之间(包括范围端点)。 2 BETWEEN 1 AND 3 @@ -378,7 +373,7 @@ repeat('Pg', 4) PgPgPgPg boolean - 不相等,将空(null)视为可比值。 + 不相等,将 null 视为可比值。 1 IS DISTINCT FROM NULL @@ -396,7 +391,7 @@ repeat('Pg', 4) PgPgPgPg boolean - 相等,将空(null)视为可比值。 + 相等,将 null 视为可比值。 1 IS NOT DISTINCT FROM NULL @@ -414,7 +409,7 @@ repeat('Pg', 4) PgPgPgPg boolean - 测试值是否为空。 + 测试值是否为 null。 1.5 IS NULL @@ -428,7 +423,7 @@ repeat('Pg', 4) PgPgPgPg boolean - 测试值是否不为空。 + 测试值是否不为 null。 'null' IS NOT NULL @@ -442,7 +437,7 @@ repeat('Pg', 4) PgPgPgPg boolean - 测试值是否为空(非标准语法)。 + 测试值是否为 null(非标准语法)。 @@ -452,7 +447,7 @@ repeat('Pg', 4) PgPgPgPg boolean - 测试值是否不为空(非标准语法)。 + 测试值是否不为 null(非标准语法)。 @@ -573,30 +568,22 @@ repeat('Pg', 4) PgPgPgPg BETWEEN SYMMETRIC - - BETWEEN谓词可以简化范围测试: - + BETWEEN谓词可以简化范围测试: a BETWEEN x AND y - - 等效于 - +等价于 a >= x AND a <= y - - 注意BETWEEN认为终点值是包含在范围内的。 - BETWEEN SYMMETRIC 就像BETWEEN,除了没有要求AND的左边的参数小于或等于右边的参数。 - 如果不是的话,这两个参数将自动交换,因此总是隐含一个非空范围。 - +注意,BETWEEN将两个端点值都视为包含在范围内。BETWEEN SYMMETRIC类似于BETWEEN,但不要求AND左侧的参数小于或等于右侧的参数。如果不是这样,这两个参数会自动交换,以确保表示的范围始终非空。 - BETWEEN的各种变量都是以普通比较操作符的方式实现的,因此适用于任何可以比较的数据类型。 + BETWEEN的各种变体都是以普通比较操作符的方式实现的,因此适用于任何可以比较的数据类型。 - 在BETWEEN语法中使用AND会与使用AND作为逻辑操作符产生歧义。 - 为了解决这个问题,只允许有限的一组表达类型作为BETWEEN子句的第二个参数。 - 如果您需要在BETWEEN中写一个更复杂的子表达式,在子表达式两边写上圆括号。 + 在BETWEEN语法中使用AND,会与将AND用作逻辑操作符产生歧义。 + 为了解决这个问题,只允许有限的一组表达式类型作为BETWEEN子句的第二个参数。 + 如果你需要在BETWEEN中写一个更复杂的子表达式,请在该子表达式两边加上圆括号。 @@ -607,12 +594,12 @@ repeat('Pg', 4) PgPgPgPg IS NOT DISTINCT FROM - 当有一个输入为空时,普通的比较操作符会得到空(表示未知),而不是真或假。例如,7 = NULL得到空,7 <> NULL也一样。如果这种行为不合适,可以使用IS NOT DISTINCT FROM谓词: + 当任一输入为 null 时,普通的比较操作符会得到 null(表示未知),而不是真或假。例如,7 = NULL得到 null,7 <> NULL也一样。如果这种行为不合适,可以使用IS NOT DISTINCT FROM谓词: a IS DISTINCT FROM b a IS NOT DISTINCT FROM b - 对于非空输入,IS DISTINCT FROM<>操作符一样。不过,如果两个输入都为空,它会返回假。而如果只有一个输入为空,它会返回真。类似地,IS NOT DISTINCT FROM对于非空输入的行为与=相同,但是当两个输入都为空时它返回真,并且当只有一个输入为空时返回假。因此,这些谓词实际上把空值当作一种普通数据值,而不是未知。 + 对于非 null 输入,IS DISTINCT FROM<>操作符一样。不过,如果两个输入都为 null,它会返回假。而如果只有一个输入为 null,它会返回真。类似地,IS NOT DISTINCT FROM对于非 null 输入的行为与=相同,但是当两个输入都为 null 时它返回真,并且当只有一个输入为 null 时返回假。因此,这些谓词实际上把 null 当作一种普通数据值,而不是未知 @@ -628,44 +615,32 @@ repeat('Pg', 4) PgPgPgPg NOTNULL - 要检查一个值是否为空,使用下面的谓词: + 要检查一个值是否为 null,使用下面的谓词: expression IS NULL expression IS NOT NULL - 或者等效,但并不标准的谓词: + 或者等效但非标准的谓词: expression ISNULL expression NOTNULL - null valuecomparing + 空值比较 - 不要expression = NULL,因为NULL并不等于NULL。(空值表示未知值,而我们并不知道两个未知值是否相等。) + 不要expression = NULL,因为NULL并不等于NULL。(null 值表示未知值,而我们并不知道两个未知值是否相等。) - 有些应用可能要求表达式expression = NULLexpression得出空值时返回真。我们强烈建议这样的应用修改成遵循 SQL 标准。但是,如果这样修改不可能完成,那么我们可以使用配置变量。如果打开它,PostgreSQL将把x = NULL子句转换成x IS NULL。 + 有些应用可能期望表达式expression = NULLexpression求值为 null 时返回真。我们强烈建议此类应用修改为遵循 SQL 标准。但是,如果无法这样修改,那么可以使用配置变量。如果将其打开,PostgreSQL会把x = NULL子句转换成x IS NULL - 如果expression是行值,那么当行表达式本身为空或其所有字段都为空时,IS NULL为真;而当行表达式本身非空且其所有字段都非空时,IS NOT NULL为真。由于这种行为,IS NULLIS NOT NULL并不总是对行值表达式返回相反的结果;特别是,一个同时包含空字段和非空字段的行值表达式会对这两种测试都返回假。例如: - - -SELECT ROW(1,2.5,'this is a test') = ROW(1, 3, 'not the same'); - -SELECT ROW(table.*) IS NULL FROM table; -- detect all-null rows - -SELECT ROW(table.*) IS NOT NULL FROM table; -- detect all-non-null rows - -SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in rows - - - 在某些情况下,写成row IS DISTINCT FROM NULL或者row IS NOT DISTINCT FROM NULL可能更合适,因为它们只会检查整个行值是否为空,而不会再对行字段做额外测试。 + 如果expression是行值,那么当行表达式本身为 null 或其所有字段都为 null 时,IS NULL 为真;而当行表达式本身非 null 且其所有字段都非 null 时,IS NOT NULL 为真。由于这种行为,IS NULLIS NOT NULL并不总是对行值表达式返回相反的结果;特别是,一个同时包含 null 和非 null 字段的行值表达式会对这两种测试都返回假。在某些情况下,写成row IS DISTINCT FROM NULL或者row IS NOT DISTINCT FROM NULL可能更合适,因为它们只会检查整个行值是否为 null,而不会再对行字段做额外测试。 @@ -696,7 +671,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in boolean_expression IS UNKNOWN boolean_expression IS NOT UNKNOWN - 这些谓词将总是返回真或假,从来不返回空值,即使操作数为空也是如此。空值输入被视为逻辑值未知。请注意,IS UNKNOWNIS NOT UNKNOWN实际上分别与IS NULLIS NOT NULL相同,只是输入表达式必须是布尔类型。 + 这些谓词总是返回真或假,从不返回空值,即使操作数为 null 也是如此。null 输入被当作逻辑值未知。请注意,IS UNKNOWNIS NOT UNKNOWN实际上分别等同于IS NULLIS NOT NULL,只是输入表达式必须是布尔类型。 @@ -733,7 +708,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in integer - 返回非空参数的数量。 + 返回非 null 参数的数量。 num_nonnulls(1, NULL, 2) @@ -750,7 +725,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in integer - 返回空参数的数量。 + 返回 null 参数的数量。 num_nulls(1, NULL, 2) @@ -768,11 +743,11 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in 数学函数和操作符 - PostgreSQL为很多类型提供了数学操作符。对于那些没有标准数学表达的类型(如日期/时间类型),我们将在后续小节中描述实际的行为。 + PostgreSQL为很多类型提供了数学操作符。对于那些没有标准数学惯例的类型(如日期/时间类型),我们将在后续小节中描述实际的行为。 - 显示了可用于标准数字类型的数学操作符。 + 显示了可用于标准数值类型的数学操作符。 除非另有说明,显示为可接受 numeric_type 的操作符对所有的 smallintintegerbigintnumericrealdouble precision类型都可用。 显示为可接受 integral_type 的操作符对 smallintintegerbigint类型是可用的。 除了特别说明之处,操作符的每种形式都返回与其参数相同的数据类型。 @@ -821,7 +796,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in numeric_type - 一元加(无操作) + 一元正号(不执行操作) + 3.5 @@ -849,7 +824,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in numeric_type - 否定 + 取负 - (-4) @@ -877,7 +852,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in numeric_type - 除(对于整型,除法将结果截断为零) + 除法(对于整数类型,除法将结果向零截断) 5.0 / 2 @@ -917,14 +892,14 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in double precision - 指数 + 求幂 2 ^ 3 8 - 不像典型的数学实践,多次使用 ^ 将会默认从左到右关联: + 与通常的数学惯例不同,多次使用^时默认从左到右结合: 2 ^ 3 ^ 3 @@ -984,7 +959,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in integral_type - 按位与(AND) + 按位与 91 & 15 @@ -998,7 +973,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in integral_type - 按位或(OR) + 按位或 32 | 3 @@ -1012,7 +987,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in integral_type - 按位异或(exclusive OR) + 按位异或 17 # 5 @@ -1026,7 +1001,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in integral_type - 按位求反(NOT) + 按位非 ~1 @@ -1071,7 +1046,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in 许多这样的函数以多种具有不同的参数类型的形式提供。 除非注明,任何给定形式的函数都返回与其参数相同的数据类型;跨类型情况的解决方法与上述对操作符的解释相同。 使用double precision数据的函数大多是在主机系统的 C 库上实现的; - 因此,边界情况下的准确性和行为会因主机系统的区别而不同。 + 因此,精度和边界情况下的行为可能因主机系统而异。 @@ -1202,7 +1177,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in numeric - y/x 的整数商(截断为零位) + y/x 的整数商(向零截断) div(9, 4) @@ -1210,27 +1185,6 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in - - - - exp - - exp ( numeric ) - numeric - - - exp ( double precision ) - double precision - - - 指数 (e 的给定次方) - - - exp(1.0) - 2.7182818284590452 - - - @@ -1265,6 +1219,27 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in + + + + exp + + exp ( numeric ) + numeric + + + exp ( double precision ) + double precision + + + 指数函数(e的给定次幂) + + + exp(1.0) + 2.7182818284590452 + + + @@ -1428,7 +1403,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in integer - 精确表示所提供值所需的最小刻度(小数位数) + 精确表示给定值所需的最少小数位数 min_scale(8.4100) @@ -1525,7 +1500,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in double precision - 四舍五入到最近的整数。 + 舍入到最接近的整数。 对于numeric,遇到恰好位于中点的情况时按远离零的方向舍入。 对于double precision,中点取舍规则取决于平台,但舍入到最接近的偶数是最常见的规则。 @@ -1562,7 +1537,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in integer - 参数的刻度(小数点后的位数) + 参数的小数位数(小数部分的十进制位数) scale(8.4100) @@ -1621,7 +1596,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in numeric - 通过删除尾数部分的零来降低值的刻度(小数位数) + 通过移除尾随零来减少值的小数位数 trim_scale(8.4100) @@ -1642,7 +1617,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in double precision - 截断整数 (向零靠近) + 向零截断为整数 trunc(42.8) @@ -1660,7 +1635,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in numeric - 截断 vs 位小数位置的数字 + 将v截断到s位小数 trunc(42.4382, 2) @@ -1753,6 +1728,26 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in + + + + random_normal + + + random_normal ( + mean double precision + , stddev double precision ) + double precision + + + 从具有给定参数的正态分布中返回一个随机值;mean默认为 0.0,stddev默认为 1.0。 + + + random_normal(0.0, 1.0) + 0.051285419 + + + @@ -1762,7 +1757,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in void - 为后续的random()调用设置种子;参数必须在-1.0和1.0之间,包括边界值 + 为后续的random()random_normal()调用设置种子;参数必须在-1.0和1.0之间,包括边界值 setseed(0.12345) @@ -1777,6 +1772,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in 它速度快,但不适用于加密应用;请参阅模块以获取更安全的替代方案。 如果调用setseed(),则当前会话中后续random()调用的结果序列可以通过使用相同参数重新发出setseed()来重复。 在同一会话中没有任何先前的setseed()调用时,第一个random()调用从平台相关的随机位源获取种子。 + 这些说明同样适用于random_normal() @@ -2086,7 +2082,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in - 另一种使用以角度度量的角的方法是使用早前展示的单位转换函数radians()degrees()。不过,使用基于角度的三角函数更好,因为这类方法能避免sind(30)等特殊情况下的舍入偏差。 + 另一种使用以角度度量的角的方法是使用早前展示的单位转换函数radians()degrees()。不过,使用基于角度的三角函数更好,因为这类方法能避免sind(30)等特殊情况下的舍入误差。 @@ -2159,7 +2155,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in double precision - 双曲切线 + 双曲正切 tanh(1) @@ -2210,7 +2206,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in double precision - 反双曲切线 + 反双曲正切 atanh(0.5) @@ -2232,7 +2228,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in 这里的字符串包括charactercharacter varyingtext类型的值。 除非另有说明,这些函数和操作符都声明为接受并返回text类型。 它们也可互换地接受character varying参数。 - 在应用函数或操作符之前,character类型的值会先转换为text,因此会去除其尾随空格。 + 在应用函数或操作符之前,character类型的值会先转换为text,因此会去除 character 值的尾随空格。 @@ -2243,7 +2239,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in 字符串串接操作符(||)将接受非字符串输入,只要至少一个输入是一种字符串类型,如所示。 - 对于其他情况,向text插入一个显式强制,可用于接受非字符串输入。 + 对于其他情况,可以添加到text的显式强制转换,以接受非字符串输入。 @@ -2271,14 +2267,14 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in - character string - concatenation + 字符串 + 串接 text || text text - 连接两个字符串。 + 串接两个字符串。 'Post' || 'greSQL' @@ -2297,7 +2293,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in 将非字符串输入转换为文本,然后将两个字符串串接起来。 - (非字符串输入不能是数组类型,因为那样会与数组的||操作符产生歧义。如果要连接数组的文本表示,请显式地将其转换为text。) + (非字符串输入不能是数组类型,因为那样会与数组的||操作符产生歧义。如果要串接数组的文本表示,请显式地将其转换为text。) 'Value: ' || 42 @@ -2308,17 +2304,35 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in - normalized + btrim + btrim ( string text + , characters text ) + text + + + 从string的开头和结尾移除仅由characters中字符(默认为空格)组成的最长字符串。 + + + btrim('xyxtrimyyx', 'xyz') + trim + + + + + - Unicode normalization + 规范化 + + + Unicode 规范化 text IS NOT form NORMALIZED boolean - 检查字符串是否在指定的 Unicode 规范化表单中。 - 可选的form关键词指定表单:NFC (默认的), NFD, NFKC, 或 NFKD。 + 检查字符串是否处于指定的 Unicode 规范化形式中。 + 可选的form关键字指定形式:NFC(默认)、NFDNFKCNFKD。 只有在服务器编码为UTF8时,才能使用此表达式。 请注意,使用这个表达式检查规范化通常比规范化可能已经规范化的字符串要快。 @@ -2351,13 +2365,13 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in char_length - character string - length + 字符串 + 长度 - length + 长度 字符串 - character string, length + 字符串,长度 char_length ( text ) integer @@ -2387,7 +2401,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 根据数据库的语言环境规则,将字符串转换为全部小写。 + 根据数据库的区域设置规则,将字符串转换为全部小写。 lower('TOM') @@ -2395,22 +2409,57 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in + + + + lpad + + lpad ( string text, + length integer + , fill text ) + text + + + 在string前面添加字符fill(默认为空格),将其填充到长度length。如果string已经长于length,则从右侧截断。 + + + lpad('hi', 5, 'xy') + xyxhi + + + + + + + ltrim + + ltrim ( string text + , characters text ) + text + + + 从string的开头移除仅由characters中字符(默认为空格)组成的最长字符串。 + + + ltrim('zzzytest', 'xyz') + test + + + normalize - Unicode normalization + Unicode 规范化 normalize ( text , form ) text - 将字符串转换为指定的Unicode规范化形式。 - 可选的form关键字指定了如下形式:NFC (the default),NFDNFKC,或NFKD。 - 该函数只能在服务器编码为UTF8时使用。 + 将字符串转换为指定的 Unicode 规范化形式。可选的 form 关键字指定如下形式:NFC(默认值)、NFDNFKCNFKD。该函数只能在服务器编码为 UTF8 时使用。 normalize(U&'\0061\0308bc', NFC) @@ -2461,8 +2510,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 替换stringstart字符开始的子串,并用newsubstring扩展到count字符。 - 如果省略了count,则默认为newsubstring的长度。 + 用newsubstring替换string中从第start个字符开始、长度为count个字符的子字符串。如果省略count,则默认为newsubstring的长度。 overlay('Txxxxas' placing 'hom' from 2 for 4) @@ -2487,6 +2535,43 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in + + + + rpad + + rpad ( string text, + length integer + , fill text ) + text + + + 在string后面追加字符fill(默认为空格),将其填充到长度length。如果string已经长于length,则截断它。 + + + rpad('hi', 5, 'xy') + hixyx + + + + + + + rtrim + + rtrim ( string text + , characters text ) + text + + + 从string的结尾移除仅由characters中字符(默认为空格)组成的最长字符串。 + + + rtrim('testxxzx', 'xyz') + test + + + @@ -2496,9 +2581,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 如果已指定,提取stringstart字符开始的子串, - 并且在count字符后停止。如果已指定的话。 - 提供至少一个startcount中的至少一个。 + 提取string的子字符串:若指定了起始位置,则从第start个字符开始;若指定了长度,则在提取count个字符后停止。startcount至少需要指定一个。 substring('Thomas' from 2 for 3) @@ -2538,8 +2621,8 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 提取匹配 SQL 正则表达式的第一个字串;参见 。 - 第一种形式自从SQL:2003被指定,第二种形式仅在SQL:1999中,并应认为是废弃的。 + 提取匹配 SQL 正则表达式的第一个子字符串;参见 。 + 第一种形式自 SQL:2003 起由标准规定;第二种形式只出现在 SQL:1999 中,应视为已过时。 substring('Thomas' similar '%#"o_a#"_' escape '#') @@ -2591,7 +2674,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 根据数据库的定位规则,将字符串转换为所有大写。 + 根据数据库的区域设置规则,将字符串转换为全部大写。 upper('tom') @@ -2658,7 +2741,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in integer - 返回参数的第一个字符的数字代码。在UTF8编码中,返回该字符的Unicode代码点。 + 返回参数的第一个字符的数字代码。在UTF8编码中,返回该字符的Unicode 码点。 在其他多字节编码中,该参数必须是一个ASCII字符。 @@ -2667,23 +2750,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in - - - - btrim - - btrim ( string text - , characters text ) - text - - - 从string的开头或结尾删除最长的只包含characters(默认是一个空格)的字符串 - - - btrim('xyxtrimyyx', 'xyz') - trim - - + @@ -2694,7 +2761,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 返回给定代码的字符。在UTF8编码中该参数被视作一个Unicode代码点。 + 返回给定代码的字符。在UTF8编码中该参数被视作一个Unicode 码点。 在其他多字节编码中该参数必须指定一个ASCII字符。 chr(0) 字符不被允许,因为文本数据类型不能存储这种字符。 @@ -2714,7 +2781,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 连接所有参数的文本表示。空参数被忽略。 + 串接所有参数的文本表示。NULL 参数被忽略。 concat('abcde', 2, NULL, 22) @@ -2733,7 +2800,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 用分隔符连接除第一个参数外的所有参数。第一个参数用作分隔符字符串,不应为NULL。其他NULL参数将被忽略。 + 用分隔符串接除第一个参数外的所有参数。第一个参数用作分隔符字符串,不应为NULL。其他NULL参数将被忽略。 concat_ws(',', 'abcde', 2, NULL, 22) @@ -2812,43 +2879,9 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in - - - - lpad - - lpad ( string text, - length integer - , fill text ) - text - - - 将string扩展为长度length,通过前置字符fill(默认空格)。 - 如果string已经超过length那么它将被截断(在右侧)。 - - - lpad('hi', 5, 'xy') - xyxhi - - - - - - ltrim - - ltrim ( string text - , characters text ) - text - - - 从string开始删除包含characters(默认空格)中仅包含字符的最长字符串。 - - - ltrim('zzzytest', 'xyz') - test - - + + @@ -2877,10 +2910,10 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text[] - 将qualified_identifier拆分为一个标识符数组,删除单个标识符的任何引用。 + 将qualified_identifier拆分为一个标识符数组,去除各个标识符的引号。 默认情况下,最后一个标识符之后的额外字符被视为错误;但是,如果第二个参数为false,则忽略这些额外的字符。 (这种行为对于解析类似函数的对象的名称有作用。) - 请注意,此函数不会截断超长标识符。如果你想截断,你可以把结果给到name[]。 + 请注意,此函数不会截断超长标识符。如果你想截断,你可以将结果转换为name[] parse_ident('"SomeSchema".someTable') @@ -2914,9 +2947,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 返回适合引用的给定字符串,作为SQL语句字符串中的标识符。 - 只有在必要的情况下才添加引号(例如,如果字符串包含非标识符字符或将被大小写折叠)。 - 嵌入的引号被适当地加双引号。参见。 + 为给定字符串添加适当的引号并返回,使其可用作SQL语句字符串中的标识符。仅在必要时(即字符串包含不能用于标识符的字符,或会发生大小写折叠时)添加引号。内嵌的引号会被适当地双写。另见 quote_ident('Foo bar') @@ -2933,9 +2964,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 返回在SQL语句字符串中被正确引用的给定字符串,用作字符串字面值。 - 其中嵌入的单引号和反斜线会被适当地双写。 - 请注意,如果参数为 NULLquote_literal会返回 NULL;如果该参数可能为空,quote_nullable通常更合适。另请参阅。 + 为给定字符串添加适当的引号并返回,使其可用作SQL语句字符串中的字符串字面量。内嵌的单引号和反斜杠会被适当地双写。注意,quote_literal在输入为NULL时返回NULL;如果参数可能为 null,quote_nullable通常更合适。另见 quote_literal(E'O\'Reilly') @@ -2949,8 +2978,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 将给定值转换为文本,然后将其作为字面值引用。 - 其中嵌入的单引号和反斜线会被适当地双写。 + 将给定值转换为文本,然后作为字面量加引号。内嵌的单引号和反斜杠会被适当地双写。 quote_literal(42.5) @@ -2967,8 +2995,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 返回在SQL语句字符串中被正确引用的给定字符串字面值;如果参数为NULL,则返回NULL。 - 其中嵌入的单引号和反斜线会被适当地双写。参见。 + 为给定字符串添加适当的引号并返回,使其可用作SQL语句字符串中的字符串字面量;如果参数为NULL,则返回NULL。内嵌的单引号和反斜杠会被适当地双写。另见 quote_nullable(NULL) @@ -2982,8 +3009,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 将给定值转换为文本,然后将其作为字面值引用;如果参数为NULL,则返回NULL。 - 其中嵌入的单引号和反斜线会被适当地双写。 + 将给定值转换为文本,然后作为字面量加引号;如果参数为NULL,则返回NULL。内嵌的单引号和反斜杠会被适当地双写。 quote_nullable(42.5) @@ -3024,7 +3050,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in integer - 返回string中第N个匹配项的POSIX正则表达式pattern出现的位置,如果没有这样的匹配项,则返回零;参见。 + 返回 POSIX 正则表达式patternstring中第N次匹配的位置;如果没有这样的匹配,则返回零。参见 regexp_instr('ABCDEF', 'c(.)(..)', 1, 1, 0, 'i') @@ -3063,7 +3089,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text[] - 返回第一个匹配的POSIX正则表达式patternstring中的子字符串;参见。 + 返回 POSIX 正则表达式patternstring的第一次匹配中的子字符串;参见 regexp_match('foobarbequebaz', '(bar)(beque)') @@ -3080,8 +3106,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in setof text[] - 返回第一个匹配的 POSIX 正则表达式patternstring中的子字符串,或者如果使用了g标志,则返回所有匹配的子字符串; - 参见。 + 返回 POSIX 正则表达式patternstring的第一次匹配中的子字符串;如果使用g标志,则返回所有匹配中的子字符串。参见 regexp_matches('foobarbequebaz', 'ba.', 'g') @@ -3121,7 +3146,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 替换字符串中第N个与 POSIX 正则表达式pattern匹配的子字符串,如果N为零,则替换所有匹配项;参见。 + 替换第N个与 POSIX 正则表达式pattern匹配的子字符串;如果N为零,则替换所有这样的匹配。参见 regexp_replace('Thomas', '.', 'X', 3, 2) @@ -3180,8 +3205,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 返回string中与第N个出现的POSIX正则表达式pattern匹配的子字符串, - 如果没有这样的匹配,则返回NULL;参见。 + 返回string中 POSIX 正则表达式pattern的第N次匹配对应的子字符串;如果没有这样的匹配,则返回NULL。参见 regexp_substr('ABCDEF', 'c(.)(..)', 1, 1, 'i') @@ -3221,7 +3245,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 将string 中当前的子串from替换为子串to。 + 将string中所有出现的子字符串from替换为子字符串to replace('abcdefabcdef', 'cd', 'XX') @@ -3256,7 +3280,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 返回字符串中的最后n个字符,或者在n>为负时,返回除了前面的|n|字符之外的所有字符。 + 返回字符串中的最后n个字符;如果n为负数,则返回除前 |n| 个字符之外的全部字符。 right('abcde', 2) @@ -3264,43 +3288,9 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in - - - - rpad - - rpad ( string text, - length integer - , fill text ) - text - - - 扩展 string 到长度 length,通过追加fill 字符(默认为空格). - 如果string 已经比 length 长,则截断它。 - - - rpad('hi', 5, 'xy') - hixyx - - - - - - rtrim - - rtrim ( string text - , characters text ) - text - - - 从string末尾删除包含characters(默认为空格)中仅包含字符的最长字符串。 - - - rtrim('testxxzx', 'xyz') - test - - + + @@ -3313,7 +3303,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 在delimiter出现时拆分string,并且返回第n个字段(从一计数),或者当n为负数时,返回|n|'th-from-last 字段。 + 在出现delimiter时拆分string,并返回第n个字段(从一开始计数);如果n为负数,则返回倒数第 |n| 个字段。 split_part('abc~@~def~@~ghi', '~@~', 2) @@ -3397,8 +3387,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in integer - 返回substringstring中首次出现的位置;如果不存在则返回零。 - (与(substringstring中的)位置相同,但是请注意反转的参数顺序) + 返回substringstring中首次出现的位置;如果不存在则返回零。(与position(substring in string)相同,但请注意参数顺序相反。) strpos('high', 'ig') @@ -3415,8 +3404,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 提取stringstart字符开始的子字符串,并扩展count字符,如果指定了的话。 - (与 子字符串(stringstart 开始计数 count)相同。) + 提取string中从第start个字符开始的子字符串;若指定了长度,则提取count个字符。(与substring(string from start for count)相同。) substr('alphabet', 3) @@ -3447,10 +3435,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 将string从另一个编码中转换为ASCII,该编码可按名称或编号标识。 - 如果encoding被省略,则假定数据库编码(这在实践中是唯一有用的案例)。转换主要包括降音。 - 转换仅支持来自 LATIN1LATIN2LATIN9WIN1250 的编码。 - (其他情况请参见 模块,以获得更灵活的解决方案。) + 将string从其他编码转换为ASCII,源编码可以用名称或编号指定。如果省略encoding,则使用数据库编码(实际上,这也是唯一有用的情况)。转换主要是去除重音符号。只支持从LATIN1LATIN2LATIN9WIN1250编码转换。(另一种更灵活的解决方案参见模块。) to_ascii('Karél') @@ -3491,7 +3476,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in string中与from集合中匹配的每个字符替换为to集合中相应的字符。 - 如果from长于tofrom中出现的额外字符被删除。 + 如果from长于to,输入中出现的from中的额外字符会被删除。 translate('12345', '143', 'ax') @@ -3508,10 +3493,10 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 计算参数中的转义Unicode字符。 + 解析参数中转义的 Unicode 字符。 Unicode字符可以被指定为\XXXX (4个十六进制数字),\+XXXXXX(6个十六进制数字),\uXXXX(4个十六进制数字),或\UXXXXXXXX (8个十六进制数字)。 要指定反斜杠,请写入两个反斜杠。 - 所有其他字符都是按字面意义的。 + 所有其他字符均按字面解释。 @@ -3519,7 +3504,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in - 这个函数提供了一个(非标准的)替代到Unicode转义的字符串常量(参见)。 + 此函数提供了带 Unicode 转义的字符串常量的另一种(非标准)写法(参见)。 @@ -3537,12 +3522,12 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in
- concatconcat_wsformat函数是可变的,因此可以把要串接或格式化的值作为一个标记了VARIADIC关键字的数组进行传递(见)。 - 数组的元素被当作函数的独立普通参数一样处理。如果可变数组参数为 NULL,concatconcat_ws返回 NULL,但format把 NULL 当作一个零元素数组。 + concatconcat_wsformat是可变参数函数,因此可以把要串接或格式化的值作为一个标记了VARIADIC关键字的数组进行传递(见)。 + 数组的元素被当作函数的独立普通参数一样处理。如果可变参数数组为 NULL,concatconcat_ws返回 NULL,但format把 NULL 当作一个零元素数组。 - 还可以参阅中的string_agg,以及中的字符串和bytea类型之间转换的功能。 + 还可以参阅中的聚合函数string_agg,以及中的字符串和bytea类型之间转换的函数。 @@ -3560,22 +3545,22 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in format(formatstr text [, formatarg "any" [, ...] ]) - formatstr是一个格式字符串,它指定了结果应该如何被格式化。格式字符串中的文本被直接复制到结果中,除了使用格式说明符的地方。格式说明符在字符串中扮演着占位符的角色,它定义后续的函数参数如何被格式化及插入到结果中。每一个formatarg参数会被根据其数据类型的常规输出规则转换为文本,并接着根据格式说明符被格式化和插入到结果字符串中。 + formatstr是指定结果格式的字符串。格式字符串中的文本会直接复制到结果中,但格式说明符所在的位置除外。格式说明符充当字符串中的占位符,定义如何格式化后续函数参数并将其插入结果。每个formatarg参数都按照其数据类型通常的输出规则转换为文本,再根据格式说明符进行格式化并插入结果字符串。
- 格式说明符由一个%字符开始并且有这样的形式 + 格式说明符以%字符开头,格式如下: %[position][flags][width]type - 其中的各组件域是: + 其中各组成字段为: position(可选) - 一个形式为n$的字符串,其中n是要打印的参数的索引。索引 1 表示formatstr之后的第一个参数。如果position被忽略,默认会使用序列中的下一个参数。 + 一个形式为n$的字符串,其中n是要打印的参数的索引。索引 1 表示formatstr之后的第一个参数。如果position被省略,默认会使用序列中的下一个参数。 @@ -3583,9 +3568,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in flags(可选) - - 控制格式说明符的输出如何被格式化的附加选项。当前唯一支持的标志是一个负号(-),它将导致格式说明符的输出会被左对齐(left-justified)。除非width域也被指定,否者这个域不会产生任何效果。 - + 用于控制格式说明符输出格式的附加选项。目前唯一支持的标志是减号(-),它使格式说明符的输出左对齐。只有同时指定了width字段时,它才有效。 @@ -3597,8 +3580,8 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in - 如果宽度来自于一个函数参数,则参数在被格式说明符的值使用之前就被消耗掉了。如果宽度参数是负值,结果会在长度为abs(width)的域中被左对齐(如果-标志被指定)。 - + 如果宽度来自一个函数参数,会先使用该宽度参数,再使用作为格式说明符值的参数。如果宽度参数为负数,结果会在长度为abs(width)的字段中左对齐(如同指定了-标志)。 +
@@ -3615,12 +3598,12 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in - I将参数值视作 SQL 标识符,并在必要时用双写引号包围它。如果参数为空,将会是一个错误(等效于quote_ident)。 + I将参数值视作 SQL 标识符,并在必要时用双引号包围它。如果参数为 null,则会报错(等效于quote_ident)。 - L将参数值引用为 SQL 文字。一个空值将被显示为不带引号的字符串NULL(等效于quote_nullable)。 + L将参数值作为 SQL 字面量加引号。null 值显示为不带引号的字符串NULL(等效于quote_nullable)。 @@ -3631,13 +3614,10 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in - 除了以上所述的格式说明符之外,要输出一个文字形式的%字符,可以使用特殊序列%%。 + 除了以上所述的格式说明符之外,要输出一个字面形式的%字符,可以使用特殊序列%% - - 下面有一些基本的格式转换的示例: - - + 下面是一些基本格式转换的示例: SELECT format('Hello %s', 'World'); 结果:Hello World @@ -3648,14 +3628,11 @@ SELECT format('INSERT INTO %I VALUES(%L)', 'Foo bar', E'O\'Reilly'); 结果:INSERT INTO "Foo bar" VALUES('O''Reilly') SELECT format('INSERT INTO %I VALUES(%L)', 'locations', 'C:\Program Files'); -结果:INSERT INTO locations VALUES(E'C:\\Program Files') +结果:INSERT INTO locations VALUES('C:\Program Files') - - 下面是使用width域和-标志的示例: - - + 下面是使用width字段和-标志的示例: SELECT format('|%10s|', 'foo'); 结果:| foo| @@ -3676,10 +3653,7 @@ SELECT format('|%-*s|', -10, 'foo'); - - 这些示例展示了position域的示例: - - + 这些示例展示了如何使用position字段: SELECT format('Testing %3$s, %2$s, %1$s', 'one', 'two', 'three'); 结果:Testing three, two, one @@ -3691,10 +3665,8 @@ SELECT format('|%1$*2$s|', 'foo', 10, 'bar'); - - 不同于标准的 C 函数sprintfPostgreSQLformat函数允许将带有或者不带有position域的格式说明符被混在同一个格式字符串中。一个不带有position域的格式说明符总是使用最后一个被消耗的参数的下一个参数。另外,format函数不要求所有函数参数都被用在格式字符串中。例如: - - + 不同于标准 C 函数sprintf, + PostgreSQLformat函数允许在同一个格式字符串中,混合使用带有或不带有position字段的格式说明符。不带position字段的格式说明符,总是使用最后一个已使用参数之后的下一个参数。此外,format函数不要求格式字符串使用全部函数参数。例如: SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); 结果:Testing three, two, three @@ -3712,17 +3684,17 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); 二进制串函数和操作符 - binary data - functions + 二进制数据 + 函数 - 本节描述那些检查和操作二进制字符串的函数和操作符,这是类型bytea的值。 + 本节描述用于检查和操作二进制字符串(即bytea类型的值)的函数和操作符。 其中许多函数在用途和语法上都与上一节中描述的文本字符串函数等效。 - SQL定义了一些使用关键字而不是逗号来分割参数的串函数。详情请见PostgreSQL也提供了这些函数使用常规函数调用语法的版本(参阅)。 + SQL定义了一些使用关键字而不是逗号来分隔参数的字符串函数。详情请见PostgreSQL也提供了这些函数使用常规函数调用语法的版本(参阅)。 @@ -3749,14 +3721,14 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); - binary string - concatenation + 二进制串 + 串接 bytea || bytea bytea - 连接两个二进制字符串。 + 串接两个二进制字符串。 '\x123456'::bytea || '\x789a00bcde'::bytea @@ -3781,6 +3753,42 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); + + + + btrim + + btrim ( bytes bytea, + bytesremoved bytea ) + bytea + + + 从bytes的开头和结尾移除仅由bytesremoved中字节组成的最长字符串。 + + + btrim('\x1234567890'::bytea, '\x9012'::bytea) + \x345678 + + + + + + + ltrim + + ltrim ( bytes bytea, + bytesremoved bytea ) + bytea + + + 从bytes的开头移除仅由bytesremoved中字节组成的最长字符串。 + + + ltrim('\x1234567890'::bytea, '\x9012'::bytea) + \x34567890 + + + @@ -3807,8 +3815,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bytea - 将bytes的子字符串替换为newsubstring,该子字符串从start字节开始,并以count字节扩展。 - 如果忽略了count,则默认为newsubstring的长度。 + 用newsubstring替换bytes中从第start个字节开始、长度为count个字节的子字符串。如果省略count,则默认为newsubstring的长度。 overlay('\x1234567890'::bytea placing '\002\003'::bytea from 2 for 3) @@ -3833,6 +3840,24 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); + + + + rtrim + + rtrim ( bytes bytea, + bytesremoved bytea ) + bytea + + + 从bytes的结尾移除仅由bytesremoved中字节组成的最长字符串。 + + + rtrim('\x1234567890'::bytea, '\x9012'::bytea) + \x12345678 + + + @@ -3842,8 +3867,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bytea - 提取bytesstart字节开始的子字符串,如果指定了,并且在count字节之后停止,如果指定了的话。 - 至少提供startcount中的一个。 + 提取bytes的子字符串:若指定了起始位置,则从第start个字节开始;若指定了长度,则在提取count个字节后停止。startcount至少需要指定一个。 substring('\x1234567890'::bytea from 3 for 2) @@ -3862,7 +3886,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bytea - 删除bytesremoved中只包含字节的最长字符串,从bytes的开始、结束,或两端(BOTH 为默认的)。 + 从bytes的开头、结尾或两端(默认为BOTH)移除仅由bytesremoved中字节组成的最长字符串。 trim('\x9012'::bytea from '\x1234567890'::bytea) @@ -3878,7 +3902,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bytea - 这是trim()的非标准语法。 + 这是一个非标准的trim()语法。 trim(both from '\x1234567890'::bytea, '\x9012'::bytea) @@ -3890,7 +3914,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three');
- 还有一些二进制串处理函数可以使用,在列出。 其中有一些是在内部使用,用于实现列出的 SQL 标准串函数。 + 还有一些二进制串处理函数可以使用,在列出。 其中有一些是在内部使用,用于实现列出的 SQL 标准串函数。 @@ -3927,7 +3951,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bigint - 返回二进制字符串中设置的位数(也被认为popcount)。 + 返回二进制字符串中被置位的位数(也称为popcount)。 bit_count('\x1234567890'::bytea) @@ -3935,23 +3959,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); - - - - btrim - - btrim ( bytes bytea, - bytesremoved bytea ) - bytea - - - 从bytes的开始和结束处删除只包含bytesremoved中出现的字节的最长字符串 - - - btrim('\x1234567890'::bytea, '\x9012'::bytea) - \x345678 - - + @@ -3963,7 +3971,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); integer - 从二进制字符串中提取 n'th 位。 + 从二进制字符串中提取 编号为 n 的 位。 get_bit('\x1234567890'::bytea, 30) @@ -3981,7 +3989,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); integer - 从二进制字符串中提取 n'th 字节。 + 从二进制字符串中提取 编号为 n 的 字节。 get_byte('\x1234567890'::bytea, 4) @@ -3995,13 +4003,13 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); length - binary string - length + 二进制串 + 长度 - length - 二进制字符串 - binary strings, length + 长度 + 二进制串 + 二进制串,长度 length ( bytea ) integer @@ -4030,23 +4038,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); - - - - ltrim - - ltrim ( bytes bytea, - bytesremoved bytea ) - bytea - - - 从bytes开头移除出现在bytesremoved中的只包含字节的最长字符串。 - - - ltrim('\x1234567890'::bytea, '\x9012'::bytea) - \x34567890 - - + @@ -4065,23 +4057,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); - - - - rtrim - - rtrim ( bytes bytea, - bytesremoved bytea ) - bytea - - - 从bytes结尾移除出现在bytesremoved中的只包含字节的最长字符串。 - - - rtrim('\x1234567890'::bytea, '\x9012'::bytea) - \x12345678 - - + @@ -4094,7 +4070,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bytea - 设置二进制字符串中的n'th位为newvalue。 + 设置二进制字符串中的编号为 n 的位为newvalue set_bit('\x1234567890'::bytea, 30, 0) @@ -4113,7 +4089,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bytea - 设置二进制字符串中的 n'th 字节到 newvalue。 + 设置二进制字符串中的 编号为 n 的 字节到 newvalue set_byte('\x1234567890'::bytea, 4, 64) @@ -4168,7 +4144,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); sha384('abc'::bytea) - \xcb00753f45a35e8bb5a03d699ac65007&zwsp;272c32ab0ed1631a8b605a43ff5bed&zwsp;8086072ba1e7cc2358baeca134c825a7 + \xcb00753f45a35e8bb5a03d699ac65007&zwsp;272c32ab0eded1631a8b605a43ff5bed&zwsp;8086072ba1e7cc2358baeca134c825a7 @@ -4185,7 +4161,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); sha512('abc'::bytea) - \xddaf35a193617abacc417349ae204131&zwsp;12e6fa4e89a97ea20a9ee64b55d39a&zwsp;2192992a274fc1a836ba3c23a3feebbd&zwsp;454d4423643ce80e2a9ac94fa54ca49f + \xddaf35a193617abacc417349ae204131&zwsp;12e6fa4e89a97ea20a9eeee64b55d39a&zwsp;2192992a274fc1a836ba3c23a3feebbd&zwsp;454d4423643ce80e2a9ac94fa54ca49f @@ -4198,8 +4174,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bytea - 从start字节开始提取bytes的子字符串,并扩展为count字节,如果这是指定的。 - (与 substring(bytesstartcount) 相同.) + 提取bytes中从第start个字节开始的子字符串;若指定了长度,则提取count个字节。(与substring(bytes from start for count)相同。) substr('\x1234567890'::bytea, 3, 2) @@ -4211,7 +4186,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three');
- 函数get_byteset_byte把一个二进制串中的一个字节计数为字节 0。 + 函数get_byteset_byte把二进制串中的第一个字节编号为字节 0。 函数get_bitset_bit在每一个字节中从右边起计数位; 例如位 0 是第一个字节的最低有效位,而位 15 是第二个字节的最高有效位。 @@ -4219,16 +4194,16 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); 由于历史原因,函数md5返回的是一个十六进制编码的text值,而SHA-2函数返回类型bytea。 可以使用函数encodedecode在两者之间转换。 - 例如encode(sha256('abc'),'hex')可以得到一个十六进制编码的文本表示,或者decode(md5('abc'), 'hex')得到一个bytea 值。 + 例如encode(sha256('abc'), 'hex')可以得到一个十六进制编码的文本表示,或者decode(md5('abc'), 'hex')得到一个bytea 值。 - character string + 字符串 转换为二进制字符串 - binary string + 二进制串 转换为字符串 用于在不同字符集(编码)之间转换字符串的函数,以及用于以文本形式表示任意二进制数据的函数,在中显示。 @@ -4237,7 +4212,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); - 文本/字符串转换函数 + 文本/二进制串转换函数 @@ -4369,9 +4344,9 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); base64格式是RFC 2045第6.8节中描述的。根据RFC,编码行在76个字符处换行。 - 然而,与MIME CRLF换行符不同,结尾只使用换行符。 + 然而,与MIME CRLF换行符不同,行尾只使用一个换行符。 decode函数会忽略回车、换行、空格和制表符。 - 否则,当decode提供无效的base64数据时,包括尾部填充不正确时,会引发错误。 + 否则,当向decode传入无效的 base64 数据时,包括尾部填充不正确时,会引发错误。 @@ -4383,8 +4358,8 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); - escape格式将零字节和高位设置的字节转换为八进制转义序列 - (\nnn),并将反斜杠加倍。 + escape格式将零字节和最高位被置位的字节转换为八进制转义序列 + (\nnn),并将反斜杠双写。 其他字节值会直接表示。如果反斜杠后面不是第二个反斜杠或三个八进制数字,则decode函数会引发错误; 它会接受其他字节值不变。 @@ -4399,10 +4374,10 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); hex格式将每4位数据表示为一个十六进制数字,0f, - 先写入每个字节的高阶数字。 encode函数以小写输出a-f十六进制数字。 + 先写入每个字节的高位数字。 encode函数以小写输出a-f十六进制数字。 因为数据的最小单位是8位,所以encode总是返回偶数个字符。 decode函数接受a-f字符的大小写。 - 当decode提供无效的十六进制数据时,包括提供奇数个字符时,会引发错误。 + 当向decode传入无效的十六进制数据时,包括提供奇数个字符时,会引发错误。 @@ -4419,14 +4394,14 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); 位串函数和操作符 - bit strings - functions + 位串 + 函数 本节描述用于检查和操作位串的函数和操作符,也就是操作类型为bitbit varying的值的函数和操作符。 - (虽然这些表中只提到了bit类型,但bit varying类型的值可以互换使用。) - 位字符串支持中显示的常用比较操作符,就像中显示的操作符。 + (虽然这些表中只提到了bit类型,但bit varying类型的值可以互换使用。) + 位串支持中显示的常用比较操作符,以及中显示的操作符。
@@ -4456,7 +4431,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bit - 连接 + 串接 B'10001' || B'011' @@ -4512,7 +4487,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bit - 按位求反 + 按位非 ~ B'10001' @@ -4552,12 +4527,12 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three');
- 一些可用于二进制字符串的函数也可用于位字符串,如中所示。 + 一些可用于二进制字符串的函数也可用于位串,如中所示。 - 位字符串函数 + 位串函数 @@ -4585,7 +4560,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bigint - 返回位字符串中设置的位数(也被视为popcount)。 + 返回位串中被置位的位数(也称为popcount)。 bit_count(B'10111') @@ -4602,7 +4577,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); integer - 返回位字符串中的位数。 + 返回位串中的位数。 bit_length(B'10111') @@ -4616,14 +4591,14 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); length - bit string - length + 位串 + 长度 length ( bit ) integer - 返回位字符串中的位数。 + 返回位串中的位数。 length(B'10111') @@ -4640,7 +4615,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); integer - 返回位字符串中的字节数。 + 返回位串中的字节数。 octet_length(B'1011111011') @@ -4657,8 +4632,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bit - 替换从start位开始的bits的子字符串,并将newsubstring扩展count位。 - 如果count被省略,默认为newsubstring的长度。 + 用newsubstring替换bits中从第start位开始、长度为count位的子串。如果省略count,则默认为newsubstring的长度。 overlay(B'01010101010101010' placing B'11111' from 2 for 3) @@ -4675,7 +4649,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); integer - 返回substringbits中首次出现的位置(以位为单位);如果不存在则返回 0。 + 返回substringbits中首次出现的位置;如果不存在则返回零。 position(B'010' in B'000001101011') @@ -4692,8 +4666,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bit - 如果指定了起始位,则提取从start位开始的bits的子字符串,如果指定了计数位,则在count位之后停止。 - startcount至少提供一个。 + 提取bits的子串:若指定了起始位置,则从第start位开始;若指定了长度,则在提取count位后停止。startcount至少需要指定一个。 substring(B'110010111111' from 3 for 2) @@ -4711,7 +4684,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); integer - 从位字符串中提取第n位;第一个(最左)位为第0位。 + 从位串中提取编号为n的位;第一位(最左侧的位)编号为位 0。 get_bit(B'101010101010101010', 6) @@ -4730,7 +4703,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bit - 将位字符串中的第n位设置为newvalue;第一个(最左)位是第0位。 + 将位串中编号为n的位设置为newvalue;第一位(最左侧的位)编号为位 0。 set_bit(B'101010101010101010', 6, 0) @@ -4741,18 +4714,12 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three');
- - 另外,我们可以在整数和bit之间来回转换。 - 将一个整数转换为bit(n)会复制最右边的n位。 - 将一个整数转换为比整数本身更宽的位字符串宽度将在左边进行符号扩展。一些示例: - + 此外,还可以在整数值与bit类型之间进行类型转换。将整数转换为bit(n)会复制最右侧的n位。将整数转换为宽度超过该整数自身位宽的位串时,会在左侧进行符号扩展。下面是一些示例: 44::bit(10) 0000101100 44::bit(3) 100 cast(-44 as bit(12)) 111111010100 '1110'::bit(4)::integer 14 - - 请注意,如果只是转换为bit,意思是转换成bit(1),因此只会转换整数的最低有效位。 - +注意,仅转换为bit意味着转换为bit(1),因此只会得到该整数的最低有效位。 @@ -4760,11 +4727,11 @@ cast(-44 as bit(12)) 111111010100 模式匹配 - pattern matching + 模式匹配 - PostgreSQL提供了三种独立的模式匹配实现:SQL LIKE操作符、较新的SIMILAR TO操作符(在 SQL:1999 中加入)以及POSIX风格的正则表达式。除这些基本的这个串匹配这个模式吗?操作符外,还有一些函数可用于提取或替换匹配的子串,以及在匹配位置分割字符串。 + PostgreSQL提供了三种独立的模式匹配方法:传统的SQL LIKE操作符、较新的SIMILAR TO操作符(在 SQL:1999 中加入),以及POSIX风格的正则表达式。除了用于判断这个字符串是否匹配这个模式?的基本操作符外,还提供了提取或替换匹配子字符串、在匹配位置分割字符串的函数。 @@ -4777,25 +4744,20 @@ cast(-44 as bit(12)) 111111010100 - 虽然大部分的正则表达式搜索都能被很快地执行,但是正则表达式仍可能被 - 人为地弄成需要任意长的时间和任意量的内存进行处理。要当心从不怀好意 - 的来源接受正则表达式搜索模式。如果必须这样做,建议加上语句超时限制。 + 虽然大多数正则表达式搜索都能很快完成,但特意构造的正则表达式可能需要任意长的处理时间和任意多的内存。接受来自恶意来源的正则表达式搜索模式时应当谨慎。如果必须这样做,建议设置语句超时。 - 使用SIMILAR TO模式的搜索具有同样的安全性危险, - 因为SIMILAR TO提供了很多和 - POSIX-风格正则表达式相同的能力。 + 使用SIMILAR TO模式进行搜索具有同样的安全风险,因为SIMILAR TO提供了许多与POSIX风格正则表达式相同的能力。 - LIKE搜索比其他两种选项简单得多,因此在使用 - 不怀好意的模式来源时要更安全些。 + LIKE搜索比另外两种方法简单得多,因此,当模式可能来自恶意来源时,使用它更安全。 - SIMILAR TOPOSIX-风格正则表达式不支持非确定性排序规则。如果需要的话,可以使用LIKE或在表达式中应用不同的排序规则来绕过这个限制。 + 这三种模式匹配操作符都不支持非确定性排序规则。如有需要,可以对表达式应用不同的排序规则来绕过这一限制。 @@ -4815,7 +4777,11 @@ cast(-44 as bit(12)) 111111010100
- 如果pattern不包含百分号或者下划线,那么该模式只代表它本身的串;这时候LIKE的行为就象等号操作符。在pattern里的下划线 (_)代表(匹配)任何单个字符; 而一个百分号(%)匹配任何零或更多个字符的序列。 + 如果pattern不包含百分号或下划线,那么该模式只表示它 + 本身的字符串;在这种情况下,LIKE的行为就像等号操作符。 + pattern中的下划线(_)代表 + (匹配)任意单个字符;百分号(%)匹配任意由零个或多个 + 字符组成的序列。 @@ -4829,23 +4795,26 @@ cast(-44 as bit(12)) 111111010100 - LIKE模式匹配总是覆盖整个串。因此,要匹配在串内任何位置的序列,该模式必须以百分号开头和结尾。 + LIKE模式匹配总是覆盖整个字符串。因此,如果想要匹配字符串内 + 任意位置上的一个序列,该模式就必须以百分号开头并以百分号结尾。 - 要匹配文本的下划线或者百分号,而不是匹配其它字符, 在pattern里相应的字符必须 前导转义字符。缺省的转义字符是反斜线,但是你可以用ESCAPE子句指定一个不同的转义字符。 要匹配转义字符本身,写两个转义字符。 + 要匹配字面量下划线或百分号而不是把它们当作通配符, + pattern中相应的字符前面必须带有转义字符。 + 默认的转义字符是反斜线,但也可以使用ESCAPE子句选择其他 + 转义字符。要匹配转义字符本身,请写两个转义字符。 - 如果你关掉了,你在文串常量中写的任何反斜线都需要被双写。详见。 + 如果你关掉了,你在字符串常量中写的任何反斜线都需要被双写。详见 - 请注意反斜线在串文本里已经有特殊含义了,所以如果你写一个 包含反斜线的模式常量,那你就要在 SQL 语句里写两个反斜线。 因此,写一个匹配单个反斜线的模式实际上要在语句里写四个反斜线。 你可以通过用 ESCAPE 选择一个不同的转义字符 来避免这样;这样反斜线就不再是 LIKE 的特殊字符了。 但仍然是字符文本分析器的特殊字符,所以你还是需要两个反斜线。) - 我们也可以通过写ESCAPE ''的方式不选择转义字符,这样可以有效地禁用转义机制,但是没有办法关闭下划线和百分号在模式中的特殊含义。 + 也可以通过写 ESCAPE '' 来选择不使用转义字符。这会禁用转义机制,从而无法关闭模式中下划线和百分号的特殊含义。 @@ -4854,7 +4823,7 @@ cast(-44 as bit(12)) 111111010100 - 关键字ILIKE可以替代LIKE,使匹配根据当前区域设置变为大小写不敏感。(但这不支持非确定性排序规则。)这不属于SQL标准,而是PostgreSQL的扩展。 + 可以用关键字 ILIKE 代替 LIKE,使匹配根据当前区域设置忽略大小写。这不属于 SQL 标准,而是 PostgreSQL 的扩展。 @@ -4865,14 +4834,11 @@ cast(-44 as bit(12)) 111111010100 - 短语LIKEILIKENOT LIKE,和 NOT ILIKEPostgreSQL语法中通常被视为操作符; - 例如,它们可以用于expression operator的任何(subquery)构造,尽管这里不能包含ESCAPE子句。 - 在某些晦涩难懂的情况下,可能需要用底层操作符名称替代。 + 在 PostgreSQL 语法中,LIKEILIKENOT LIKENOT ILIKE 通常被当作操作符;例如,它们可以用于 expression operator ANY (subquery) 构造,但其中不能包含 ESCAPE 子句。在某些不常见的情况下,可能需要改用底层操作符名称。 - 另请参阅以^@开头的操作符和相应的starts_with()函数, - 在需要简单匹配字符串开头的情况下非常有用。 + 另请参见用于匹配字符串开头的操作符 ^@ 和相应的 starts_with() 函数,它们适用于只需匹配字符串开头的情况。 @@ -4881,8 +4847,8 @@ cast(-44 as bit(12)) 111111010100 <function>SIMILAR TO</function>正则表达式 - regular expression - + 正则表达式 + @@ -4899,9 +4865,7 @@ cast(-44 as bit(12)) 111111010100 - SIMILAR TO操作符根据自己的模式是否匹配给定串而返回真或者假。 - 它和LIKE非常类似,只不过它使用 SQL 标准定义的正则表达式理解模式。 - SQL 正则表达式是在LIKE标记和普通的(POSIX)正则表达式标记的奇怪的杂交。 + SIMILAR TO操作符根据其模式是否匹配给定字符串返回真或假。它与LIKE非常相似,但使用 SQL 标准定义的正则表达式来解释模式。SQL 正则表达式是LIKE表示法与普通(POSIX)正则表达式表示法的一种奇特结合。 @@ -4973,8 +4937,7 @@ cast(-44 as bit(12)) 111111010100 - 另一个非标准扩展是,在转义字符后面跟着一个字母或数字提供了对为POSIX正则表达式定义的转义序列的访问;参见下面的 - ,和 。 + 另一个非标准扩展是在转义字符后跟一个字母或数字,以使用 POSIX 正则表达式定义的转义序列;参见下文的 @@ -4990,19 +4953,19 @@ cast(-44 as bit(12)) 111111010100 - 带有三个参数的substring函数可以提取匹配SQL正则表达式模式的子字符串。 该函数可以按照标准SQL99语法编写。 + 带有三个参数的substring函数可以提取匹配 SQL 正则表达式模式的子字符串。该函数可以按照标准 SQL 语法书写: substring(string similar pattern escape escape-character) - 或使用现在废除的 SQL:1999 语法: + 也可以使用现已过时的 SQL:1999 语法: substring(string from pattern for escape-character) - 或作为一个普通的三参数函数: + 或写成普通的三参数函数: substring(string, pattern, escape-character) - 与SIMILAR TO一样,指定的模式必须与整个数据字符串匹配,否则函数失败并返回空值。 为了表示匹配的数据子字符串的模式中,模式中应该包含两个转义字符的出现,并在后面加上一个双引号(")。 匹配成功后,将返回与这些分隔符之间的模式部分匹配的文本。 + 与SIMILAR TO一样,指定的模式必须匹配整个数据字符串,否则函数失败并返回空值。为了指明要提取的子字符串所对应的模式部分,模式中应包含两个分隔符,每个分隔符都由转义字符后跟双引号(")组成。匹配成功时,返回与这两个分隔符之间的模式部分匹配的文本。 @@ -5010,7 +4973,7 @@ substring(string, pattern, - 作为对SQL标准的扩展,PostgreSQL只允许有一个转义双引号分隔符,在这种情况下,第三个正则表达式被视为空;或者没有分隔符,在这种情况下,第一个和第三个正则表达式被视为空。 + 作为对SQL标准的扩展,PostgreSQL允许仅有一个转义双引号分隔符,在这种情况下,第三个正则表达式被视为空;或者没有分隔符,在这种情况下,第一个和第三个正则表达式被视为空。 @@ -5027,8 +4990,8 @@ substring('foobar' similar '#"o_b#"%' escape '#') NULLPOSIX正则表达式 - regular expression - pattern matching + 正则表达式 + 模式匹配 @@ -5103,7 +5066,7 @@ substring('foobar' similar '#"o_b#"%' escape '#') NULLboolean - 字符串匹配正则表达式,大小写敏感 + 字符串匹配正则表达式,区分大小写 'thomas' ~ 't.*ma' @@ -5117,7 +5080,7 @@ substring('foobar' similar '#"o_b#"%' escape '#') NULLboolean - 字符串匹配正则表达式,大小写不敏感 + 字符串匹配正则表达式,不区分大小写 'thomas' ~* 'T.*ma' @@ -5131,7 +5094,7 @@ substring('foobar' similar '#"o_b#"%' escape '#') NULLboolean - 字符串不匹配正则表达式,大小写敏感 + 字符串不匹配正则表达式,区分大小写 'thomas' !~ 't.*max' @@ -5145,7 +5108,7 @@ substring('foobar' similar '#"o_b#"%' escape '#') NULLboolean - 字符串不匹配正则表达式,大小写不敏感 + 字符串不匹配正则表达式,不区分大小写 'thomas' !~* 'T.*ma' @@ -5157,11 +5120,11 @@ substring('foobar' similar '#"o_b#"%' escape '#') NULL - POSIX正则表达式提供了比LIKESIMILAR TO操作符更强大的含义。许多 Unix 工具,例如egrepsedawk使用一种与我们这里描述的类似的模式匹配语言。 + POSIX正则表达式提供了比LIKESIMILAR TO操作符更强大的模式匹配方式。许多 Unix 工具,例如egrepsedawk,都使用与这里描述的模式匹配语言相似的语言。 - 正则表达式是一个字符序列,它是定义一个串集合 (一个正则集)的缩写。 如果一个串是正则表达式描述的正则集中的一员时, 我们就说这个串匹配该正则表达式。 和LIKE一样,模式字符准确地匹配串字符, 除非在正则表达式语言里有特殊字符 — 不过正则表达式用的 特殊字符和LIKE用的不同。 和LIKE模式不一样的是,正则表达式允许匹配串里的任何位置,除非该正则表达式显式地挂接在串的开头或者结尾。 + 正则表达式是一个字符序列,是定义一组字符串(一个正则集)的简写。如果字符串属于正则表达式描述的正则集,就称该字符串匹配此正则表达式。与LIKE一样,模式中的字符精确匹配字符串中的字符,除非该模式字符在正则表达式语言中有特殊含义 — 但正则表达式使用的特殊字符与LIKE不同。与LIKE模式不同,正则表达式可以匹配字符串中的任意位置,除非显式将其锚定到字符串开头或末尾。 @@ -5182,8 +5145,8 @@ substring('foobar' similar '#"o_b#"%' escape '#') NULL 带两个参数的substring函数,即substring(string from pattern),提供了抽取一个匹配 POSIX 正则表达式模式的子串的方法。 - 如果没有匹配它返回空值,否则就是匹配模式的文本中的第一部分。 - 但是如果该模式包含任何圆括号,那么将返回匹配第一对子表达式(对应第一个左圆括号的) 的文本。 + 如果没有匹配它返回空值,否则返回文本中首次匹配模式的那部分内容。 + 但是如果该模式包含任何圆括号,那么将返回匹配第一个圆括号子表达式(左圆括号最先出现的那个)的文本。 如果你想在表达式里使用圆括号而又不想导致这个例外,那么你可以在整个表达式外边放上一对圆括号。 如果你需要在想抽取的子表达式前有圆括号,参阅后文描述的非捕获性圆括号。 @@ -5212,7 +5175,7 @@ substring('foobar' from 'o(.)b') o - 一些示例: + 一些示例: regexp_count('ABCABCAXYaxy', 'A.') 3 regexp_count('ABCABCAXYaxy', 'A.', 1, 'i') 4 @@ -5220,26 +5183,26 @@ regexp_count('ABCABCAXYaxy', 'A.', 1, 'i') 4 - regexp_instr函数返回字符串中第N个匹配项的起始或结束位置,如果没有这样的匹配项则返回零。 + regexp_instr函数返回 POSIX 正则表达式模式在字符串中第N个匹配项的起始或结束位置,如果没有这样的匹配项则返回零。 它的语法为regexp_instr(string, pattern , start , N , endoption , flags , subexpr - ). + )。 在string中搜索pattern,通常从字符串的开头开始,但如果提供了start参数,则从该字符索引开始。 如果指定了N,则定位模式的第N个匹配项,否则定位第一个匹配项。 如果省略了endoption参数或将其指定为0,则函数返回匹配项的第一个字符的位置。否则,endoption 必须为1,函数返回匹配项后面字符的位置。 flags参数是一个可选的文本字符串,包含零个或多个单字母标志,可以改变函数的行为。支持的标志在中描述。 - 对于包含括号子表达式的模式,subexpr是一个整数,表示感兴趣的子表达式:结果标识与该子表达式匹配的子字符串的位置。 - 子表达式按其前导括号的顺序编号。 - 当省略或将subexpr指定为零时,结果标识整个匹配的位置,而不考虑括号子表达式。 + 对于包含圆括号子表达式的模式,subexpr是一个整数,表示感兴趣的子表达式:结果标识与该子表达式匹配的子字符串的位置。 + 子表达式按其左圆括号的顺序编号。 + 当省略或将subexpr指定为零时,结果标识整个匹配的位置,而不考虑圆括号子表达式。 - 一些示例: + 一些示例: regexp_instr('number of your street, town zip, FR', '[^,]+', 1, 2) 23 @@ -5261,7 +5224,7 @@ regexp_instr('ABCDEFGHI', '(c..)(...)', 1, 1, 0, 'i', 2) - 一些示例: + 一些示例: regexp_like('Hello World', 'world') false regexp_like('Hello World', 'world', 'i') true @@ -5269,18 +5232,18 @@ regexp_like('Hello World', 'world', 'i') true - regexp_match函数返回一个文本数组,其中包含与POSIX正则表达式模式对字符串的第一个匹配的子字符串。它的语法为 + regexp_match函数返回一个文本数组,包含字符串首次匹配 POSIX 正则表达式模式时匹配的子字符串。它的语法为 regexp_match(string, pattern , flags )。 如果没有匹配,结果为NULL。 - 如果找到匹配,并且pattern不包含括号子表达式,则结果是包含与整个模式匹配的子字符串的单元素文本数组。 - 如果找到匹配,并且pattern包含括号子表达式,则结果是一个文本数组,其中n的元素是匹配 - pattern的第n个括号子表达式的子字符串(不包括非捕获括号;详情见下文)。 + 如果找到匹配,并且pattern不包含圆括号子表达式,则结果是包含与整个模式匹配的子字符串的单元素文本数组。 + 如果找到匹配,并且pattern包含圆括号子表达式,则结果是一个文本数组,其中第n个元素是匹配 + pattern的第n个圆括号子表达式的子字符串(不包括非捕获括号;详情见下文)。 flags参数是一个可选的文本字符串,其中包含零个或多个单个字母标志,用于更改函数的行为。支持的标志在中描述。 - 一些示例: + 一些示例: SELECT regexp_match('foobarbequebaz', 'bar.*que'); regexp_match @@ -5299,10 +5262,10 @@ SELECT regexp_match('foobarbequebaz', '(bar)(beque)'); - 在通常情况下,当您只想要整个匹配的子字符串或NULL表示没有匹配时, + 在通常情况下,当你只想要整个匹配的子字符串或NULL表示没有匹配时, 最好的解决方案是使用regexp_substr()。 然而,在PostgreSQL版本15及以上版本中才存在 - regexp_substr()。在旧版本中工作时,您可以提取 + regexp_substr()。在旧版本中工作时,你可以提取 regexp_match()结果的第一个元素,例如: SELECT (regexp_match('foobarbequebaz', 'bar.*que'))[1]; @@ -5345,44 +5308,25 @@ SELECT regexp_matches('foobarbequebazilbarfbonk', '(b[^b]+)(b[^b]+)', 'g'); - 在大部分情况下,regexp_matches()应该与g标志一起使用,因为如果只是想要第一个匹配,使用regexp_match()会更加简单高效。不过,regexp_match()仅存在于PostgreSQL版本10以及更高的版本中。当在较老的版本中使用时,一种常用的技巧是把regexp_matches()调用放在子选择中,例如: + 在大部分情况下,regexp_matches()应该与g标志一起使用,因为如果只是想要第一个匹配,使用regexp_match()会更加简单高效。不过,regexp_match()仅存在于PostgreSQL版本10以及更高的版本中。当在较老的版本中使用时,一种常用的技巧是把regexp_matches()调用放在子查询中,例如: SELECT col1, (SELECT regexp_matches(col2, '(bar)(beque)')) FROM tab; - 如果有一个匹配,则这个语句会产生一个文本数组,否则返回NULL,这和regexp_match()的做法一样。如果没有子选择,这个查询对于没有匹配的表行根本不会产生输出,显然那不是想要的行为。 + 如果有一个匹配,则这个语句会产生一个文本数组,否则返回NULL,这和regexp_match()的做法一样。如果没有子查询,这个查询对于没有匹配的表行根本不会产生输出,这通常不是预期行为。 - regexp_replace函数提供了对匹配POSIX正则表达式模式的子字符串进行替换的功能。 - 它的语法为 - regexp_replace(source, + regexp_replace函数将匹配 POSIX 正则表达式模式的子字符串替换为新文本。它的语法为 regexp_replace(source, pattern, replacement , start , N - , flags ). - (注意,除非指定了start,否则无法指定N, - 但flags可以在任何情况下给出。) - 如果pattern没有匹配到source字符串, - 则返回未更改的source字符串。如果有匹配,则返回带有 - replacement字符串替换匹配子字符串的source字符串。 - replacement字符串可以包含\n, - 其中n为1至9,表示应插入与模式的第n个括号子表达式匹配的源子字符串, - 也可以包含\&表示应插入与整个模式匹配的子字符串。 - 如果需要在替换文本中放置一个字面上的反斜杠,则写\\。 - 在string中搜索pattern, - 通常从字符串的开头开始,但如果提供了start参数,则从该字符索引开始。 - 默认情况下,只替换模式的第一个匹配项。 - 如果指定了N且大于零,则替换模式的第N个匹配项。 - 如果给出了g标志,或者指定了N且为零,则在或之后的所有匹配项 - 位置都将被替换。 (当指定了N时,g标志将被忽略。) - flags参数是一个可选的文本字符串,包含零个或多个单字母标志,用于更改函数的行为。 - 支持的标志(尽管不包括g)在中描述。 + , flags )。(注意,只有指定了start,才能指定N,但flags在任何情况下都可以给出。)如果没有匹配pattern的内容,则原样返回源字符串source。如果有匹配,则返回将匹配的子字符串替换为replacement后的sourcereplacement字符串可以包含\n,其中n为 1 至 9,表示插入与模式中第n个圆括号子表达式匹配的源子字符串;也可以包含\&,表示插入与整个模式匹配的子字符串。要在替换文本中放入字面的反斜线,应写成\\。在string中搜索pattern时,通常从字符串开头开始;如果提供了start参数,则从该字符索引开始。默认只替换模式的第一个匹配项。如果指定了N且其值大于零,则替换模式的第N个匹配项。如果给出g标志,或指定了N且其值为零,则替换start位置及其后的所有匹配项。(指定N时,g标志会被忽略。)flags参数是可选的文本字符串,可包含零个或多个单字母标志,用于改变函数行为。支持的标志(不包括g)在中介绍。 - 一些示例: + 一些示例: regexp_replace('foobarbaz', 'b..', 'X') fooXbaz @@ -5398,7 +5342,7 @@ regexp_replace('A PostgreSQL function', 'a|e|i|o|u', 'X', 1, 3, 'i') - regexp_split_to_table把一个 POSIX 正则表达式模式当作一个定界符来分离一个串。它的语法形式是regexp_split_to_table(string, pattern , flags )。如果没有与pattern的匹配,该函数返回string。如果有至少有一个匹配,对每一个匹配它都返回从上一个匹配的末尾(或者串的开头)到这次匹配开头之间的文本。当没有更多匹配时,它返回从上一次匹配的末尾到串末尾之间的文本。flags参数是一个可选的文本串,它包含零个或更多单字母标志,这些标识可以改变该函数的行为。regexp_split_to_table能支持的标志在中描述。 + regexp_split_to_table把一个 POSIX 正则表达式模式当作一个定界符来分割字符串。它的语法形式是regexp_split_to_table(string, pattern , flags )。如果没有与pattern的匹配,该函数返回string。如果至少有一个匹配,对每一个匹配它都返回从上一个匹配的末尾(或者串的开头)到这次匹配开头之间的文本。当没有更多匹配时,它返回从上一次匹配的末尾到串末尾之间的文本。flags参数是一个可选的文本串,它包含零个或更多单字母标志,这些标志可以改变该函数的行为。regexp_split_to_table能支持的标志在中描述。 @@ -5406,7 +5350,7 @@ regexp_replace('A PostgreSQL function', 'a|e|i|o|u', 'X', 1, 3, 'i') - 一些示例: + 一些示例: SELECT foo FROM regexp_split_to_table('the quick brown fox jumps over the lazy dog', '\s+') AS foo; foo @@ -5452,9 +5396,9 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; - 正如最后一个示例所示,regexp分割函数会忽略出现在字符串开头或结尾 - 或紧跟在前一个匹配项之后的零长度匹配。这与其他regexp函数实现的 - 严格的regexp匹配定义相矛盾,但在实践中通常是最方便的行为。 + 正如最后一个示例所示,正则表达式分割函数会忽略出现在字符串开头或结尾 + 或紧跟在前一个匹配项之后的零长度匹配。这与其他正则表达式函数实现的 + 严格的正则表达式匹配定义相矛盾,但在实践中通常是最方便的行为。 其他软件系统如Perl使用类似的定义。 @@ -5467,23 +5411,23 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; , N , flags , subexpr - )。 + )。 patternstring中进行搜索, 通常从字符串的开头开始,但如果提供了start参数,则从该字符索引开始。 如果指定了N,则返回模式的第N次匹配, 否则返回第一次匹配。参数flags是一个可选文本字符串, 包含零个或多个单字母标志,可以改变函数的行为。支持的标志在中描述。 - 对于包含括号子表达式的模式,subexpr是一个整数, + 对于包含圆括号子表达式的模式,subexpr是一个整数, 表示感兴趣的子表达式:结果是与该子表达式匹配的子字符串。 - 子表达式按其前导括号的顺序编号。 - 当省略或为零时,subexpr的结果是整个匹配,而不考虑括号子表达式。 + 子表达式按其左圆括号的顺序编号。 + 当subexpr省略或为零时,结果是整个匹配,而不考虑圆括号子表达式。 - 一些示例: + 一些示例: regexp_substr('number of your street, town zip, FR', '[^,]+', 1, 2) - 城镇 邮编 + town zip regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) FGH @@ -5520,7 +5464,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 一个量化原子是一个原子, 后面可能跟着一个量词。没有量词的时候,它匹配一个原子, 有量词的时候,它可以匹配若干个原子。一个原子可以是在里面显示的任何可能。 可能的量词和它们的含义在里显示。 + 一个量化原子是一个原子,后面可以跟一个量词。没有量词时,匹配一次原子所匹配的内容;有量词时,按量词指定的次数匹配原子所匹配的内容。原子可以是列出的任何一种形式。可用量词及其含义见 @@ -5544,12 +5488,12 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) (re) - (其中re是任何正则表达式) 匹配一个对re的匹配,匹配将为可能的报告被记下 + (其中re是任意正则表达式)匹配re所匹配的内容,并记录该匹配,以备输出结果 (?:re) - 同上,但是匹配不会为了报告而被记下 (一个非捕获圆括号集) (只对 ARE) + 同上,但不记录匹配结果(非捕获圆括号;仅适用于 ARE) @@ -5564,17 +5508,17 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) \k - (其中k是一个非字母数字字符) 匹配一个被当作普通字符看待的特定字符, 例如,\\匹配一个反斜线字符 + (其中k既不是字母也不是数字)把该字符视为普通字符并匹配它,例如,\\匹配反斜线字符 \c - 其中c是一个字母数字 (可能跟着其它字符),它是一个转义, 参阅(仅对 ARE; 在 ERE 和 BRE 中,它匹配c + 其中c是字母或数字(后面可能还有其他字符),这是一个转义,参见(仅适用于 ARE;在 ERE 和 BRE 中,它匹配c { - 如果后面跟着一个字符,而不是数字, 那么就匹配左花括弧{;如果跟着一个数字, 那么它是range的开始(见下文) + 如果后面跟着非数字字符,则匹配左花括号{;如果后面跟着数字,则是bound的开头(见下文) @@ -5592,7 +5536,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 如果你关掉了,你在文串常量中写的任何反斜线都需要被双写。详见。 + 如果你关掉了,你在字符串常量中写的任何反斜线都需要被双写。详见 @@ -5681,7 +5625,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 非贪婪的量词(只在 ARE 中可用)匹配对应的正常 (贪婪)模式,区别是它寻找最少的匹配,而不是最多的匹配。详见。 + 非贪婪量词(仅适用于 ARE)与对应的普通(贪婪)量词匹配相同的可能内容,但优先选择最少的匹配次数,而不是最多的匹配次数。详见 @@ -5708,39 +5652,39 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) ^ - 串开头的匹配 + 在字符串开头匹配 $ - 串末尾的匹配 + 在字符串末尾匹配 (?=re) - 在某个位置上,如果从该位置开始的子串能够匹配re,则匹配正向先行断言(仅对 ARE) + 正向先行断言在这样的位置匹配:存在从该位置开始且匹配re的子字符串(仅适用于 ARE) (?!re) - 在某个位置上,如果从该位置开始的子串不能匹配re,则匹配负向先行断言(仅对 ARE) + 负向先行断言在这样的位置匹配:不存在任何从该位置开始且匹配re的子字符串(仅适用于 ARE) (?<=re) - 在某个位置上,如果以该位置结束的某个子串能够匹配re,则匹配正向后行断言(仅对 ARE) + 正向后行断言在这样的位置匹配:存在以该位置结束且匹配re的子字符串(仅适用于 ARE) (?<!re) - 在某个位置上,如果以该位置结束的任何子串都不能匹配re,则匹配负向后行断言(仅对 ARE) + 负向后行断言在这样的位置匹配:不存在任何以该位置结束且匹配re的子字符串(仅适用于 ARE) - Lookahead 和 lookbehind 约束不能包含反向引用 (参阅),并且其中的所有圆括号 都被认为是非捕获的。 + 先行和后行约束不能包含反向引用(参见),其中的所有圆括号都视为非捕获圆括号。 @@ -5749,11 +5693,11 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) 方括号表达式 - 方括号表达式是一个包围在[]中的字符列表。它通常匹配列表中的任意单个字符(但见下文)。 如果列表以^开头,它匹配任意单个在该列表参与部分中的字符。如果该列表中两个字符用-隔开, 那它就是那两个字符(包括在内)之间的所有字符范围的缩写,例如,在ASCII[0-9]匹配任何十进制数字。两个范围共享一个端点是非法的,例如,a-c-e。范围与字符集关系密切, 可移植的程序应该避免依靠它们。 + 方括号表达式是用[]括起来的字符列表。通常,它匹配列表中的任意单个字符(但请参见下文)。如果列表以^开头,则匹配任意在列表剩余部分中的单个字符。如果列表中的两个字符用-分隔,则表示排序序列中这两个字符之间的完整字符范围(包含两个端点);例如,ASCII中的[0-9]匹配任意十进制数字。两个范围共享一个端点是不合法的,例如a-c-e。范围高度依赖排序序列,因此可移植程序应避免依赖它们。 - 想在列表中包含文本],可以让它做列表的首字符(如果使用了^,需要放在其后)。 想在列表中包含文本-,可以让它做列表的首字符或者尾字符,或者一个范围的第二个端点。 想在列表中把文本-当做范围的起点, 把它用[..]包围起来,这样它就成为一个排序元素(见下文)。 除了这些字符本身、一些用[的组合(见下段)以及转义(只在 ARE 中有效)以外,所有其它特殊字符 在方括号表达式里都失去它们的特殊含义。特别是,在 ERE 和 BRE 规则下\不是特殊的, 但在 ARE 里,它是特殊的(引入一个转义)。 + 想在列表中包含字面字符],可以让它做列表的首字符(如果使用了^,需要放在其后)。 想在列表中包含字面字符-,可以让它做列表的首字符或者尾字符,或者一个范围的第二个端点。 想在列表中把字面字符-当做范围的起点, 把它用[..]包围起来,这样它就成为一个排序元素(见下文)。 除了这些字符本身、一些用[的组合(见下段)以及转义(只在 ARE 中有效)以外,所有其它特殊字符 在方括号表达式里都失去它们的特殊含义。特别是,在 ERE 和 BRE 规则下\不是特殊的, 但在 ARE 里,它是特殊的(引入一个转义)。 @@ -5768,30 +5712,11 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 在方括号表达式里,包围在[==]里的排序元素是一个等价类, 代表等效于那一个的所有排序元素的字符序列,包括它本身(如果没有其它等效排序元素,那么就好象封装定界符是[..])。例如,如果o^是一个等价类的成员,那么[[=o=]][[=^=]][o^]都是同义的。一个等价类不能是一个范围的端点。 + 在方括号表达式里,包围在[==]里的排序元素是一个等价类, 代表等效于那一个的所有排序元素的字符序列,包括它本身(如果没有其它等效排序元素,那么就好像封装定界符是[..])。例如,如果o^是一个等价类的成员,那么[[=o=]][[=^=]][o^]都是同义的。一个等价类不能是一个范围的端点。 - 在方括号表达式里,在[::]里面封装的字符类的名字代表属于该类的所有字符的列表。 - 字符类不能作为范围的端点使用。 - POSIX标准定义了这些字符类的名称: - alnum (字符和数字), - alpha (字符), - blank (空格和制表符tab), - cntrl (控制符), - digit (数位数), - graph (空格除外可打印字符), - lower (小写字母), - print (包含空格可打印字符), - punct (标点符号), - space (空白), - upper (大写字母), - 和 xdigit (十六进制数). - 对于7位ASCII字符集中的字符来说,这些标准字符类的行为在不同平台上一般是一致的。 - 一个给定的非 ASCII 字符是否被认为属于这些类别中的一个,取决于正则表达式函数或操作符所使用的排序规则(见),或者在默认情况下取决于数据库的LC_CTYPE locale 设置(见)。 - 非ASCII字符的分类在不同的平台上会有不同的分类,即使是在类似命名的locale中也是如此。 - (但C locale从不认为任何非ASCII字符属于上述任何一类)。 - 除了这些标准字符类之外,PostgreSQL定义了word字符类,等同于alnum加上下划线(_), 以及ascii字符类,它完全包含7位ASCII字符集。 + 在方括号表达式中,用[::]括起来的字符类名称表示属于该类的所有字符。字符类不能作为范围的端点。POSIX标准定义了以下字符类名称:alnum(字母和数字)、alpha(字母)、blank(空格和制表符)、cntrl(控制字符)、digit(数字)、graph(空格以外的可打印字符)、lower(小写字母)、print(包括空格的可打印字符)、punct(标点符号)、space(任意空白字符)、upper(大写字母)和xdigit(十六进制数字)。对于 7 位 ASCII 字符集中的字符,这些标准字符类在各平台上的行为通常一致。给定的非 ASCII 字符是否属于其中某个类,取决于正则表达式函数或操作符使用的排序规则(参见),默认则取决于数据库的LC_CTYPE区域设置(参见)。即使区域设置名称相似,非 ASCII 字符的分类也可能因平台而异。(但C区域设置不会将任何非 ASCII 字符归入这些类。)除了这些标准字符类,PostgreSQL还定义了word字符类,即alnum加上下划线(_),以及恰好包含 7 位 ASCII 字符集的ascii字符类。 @@ -5808,11 +5733,11 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) 正则表达式转义 - 转义是以\开头,后面跟着一个字母数字字符的特殊序列。 转义有好几种变体:字符输入转义、字符类简写转义、约束转义以及反向引用。在 ARE 里, 如果一个\后面跟着一个字母数字,但是并未组成一个合法的转义, 那么它是非法的。在 ERE 中没有转义:在方括号表达式之外,一个后面跟着字母数字字符的\只是表示该字符是一个普通的字符,而且在一个方括号表达式里,\是一个普通的字符(后者实际上在 ERE 和 ARE 不兼容)。 + 转义是以\开头,后面跟着一个字母或数字字符的特殊序列。 转义有好几种变体:字符输入转义、字符类简写转义、约束转义以及反向引用。在 ARE 里, 如果一个\后面跟着一个字母或数字,但是并未组成一个合法的转义, 那么它是非法的。在 ERE 中没有转义:在方括号表达式之外,一个后面跟着字母或数字字符的\只是表示该字符是一个普通的字符,而且在一个方括号表达式里,\是一个普通的字符(后者是 ERE 与 ARE 之间唯一的实际不兼容之处)。 - 字符输入转义用于便于我们在 RE 中声明那些不可打印的或其他习惯的字符。它们显示在中。 + 字符输入转义便于在 RE 中指定不可打印或其他不便输入的字符,见 @@ -5820,13 +5745,13 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 约束转义是一个约束,如果满足特定的条件,它匹配该空串。它们显示在中。 + 约束转义是以转义形式书写的约束,在满足特定条件时匹配空字符串,见 - 反向引用\n)匹配数字\n指定的被前面的圆括号子表达式匹配的同一个串 (参阅)。 + 反向引用\n)匹配前面编号为n的圆括号子表达式所匹配的同一字符串 (参阅)。 例如, ([bc])\1匹配bb或者cc, 但是不匹配bc或者cb。 - RE 中子表达式必须完全在反向引用前面。子表达式以它们的先导圆括号的顺序编号。 + RE 中子表达式必须完全在反向引用前面。子表达式以它们的左圆括号的顺序编号。 非捕获圆括号并不定义子表达式。 反向引用仅考虑被引用的子表达式匹配的字符串字符,而不考虑其中包含的任何约束。 例如,(^\d)\1 将匹配 22。 @@ -5869,7 +5794,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) \e - 排序序列名为ESC的字符,如果无法做到该字符为八进制值 033 + 排序序列名称为ESC的字符;若不存在这样的字符,则使用八进制值为033的字符 @@ -5879,7 +5804,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) \n - 新行,和 C 中一样 + 换行符,与 C 中相同 @@ -6003,7 +5928,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 类-缩写转义也适用于括号表达式,尽管上面显示的定义在该上下文中在语法上并不完全有效。 + 字符类简写转义也适用于括号表达式,尽管上面显示的定义在该上下文中在语法上并不完全有效。 例如,[a-c\d] 等同于 [a-c[:digit:]] @@ -6044,7 +5969,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) \Y - 只在一个词的不是开头或末尾的点上匹配 + 只在不属于单词开头或末尾的位置匹配 @@ -6056,7 +5981,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 一个词被定义成在上面[[:<:]][[:>:]]中的声明。在方括号表达式里,约束转义是非法的。 + 单词的定义与上文[[:<:]][[:>:]]的说明相同。方括号表达式中不允许使用约束转义。 @@ -6076,12 +6001,12 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) \m - (其中m是一个非零位)一个到第m个子表达式的反向引用 + (其中m是一个非零数字)一个到第m个子表达式的反向引用 \mnn - (其中m是一个非零位,并且nn是一些更多的位,并且十六进制值mnn不超过目前能看到的封闭捕获圆括号的数目)一个到第mnn个子表达式的反向引用 + (其中m是一个非零数字,并且nn是后续的若干数字,并且十进制值mnn不大于此前已出现的捕获右圆括号数)一个到第mnn个子表达式的反向引用 @@ -6090,7 +6015,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 在八进制字符输入转义和反向引用之间有一个历史继承的歧义存在,这个歧义是 通过下面的启发式规则解决的,像上面描述地那样。前导零总是表示这是一个八进制转义。 而单个非零数字,如果没有跟着任何其它位,那么总是被认为反向引用。 一个多位的非零开头的序列也被认为是反向引用,只要它出现在合适的子表达式后面 (也就是说,在反向引用的合法范围中的数),否则就被认为是一个八进制。 + 八进制字符输入转义与反向引用之间存在固有歧义,按上文提到的启发式规则解决:前导零始终表示八进制转义。单个非零数字,如果后面没有其他数字,始终视为反向引用。不以零开头的多位数字序列,如果前面已有相应的子表达式(即该数字在反向引用的合法范围内),则视为反向引用,否则视为八进制转义。 @@ -6104,11 +6029,11 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 如果一个 RE 以***:开头,那么剩下的 RE 都被当作 ARE(这在PostgreSQL中通常是无效的,因为 RE 被假定为 ARE,但是如果 ERE 或 BRE 模式通过flags参数被指定为一个正则表达式函数时,它确实能产生效果)。如果一个 RE 以***=开头, 那么剩下的 RE 被当作一个文本串,所有的字符都被认为是一个普通字符。 + RE 可以以两种特殊的引导前缀之一开头。如果 RE 以***:开头,余下部分就被视为 ARE。(这在PostgreSQL中通常没有影响,因为 RE 默认被视为 ARE;但如果通过正则表达式函数的flags参数指定了 ERE 或 BRE 模式,它就会产生影响。)如果 RE 以***=开头,余下部分就作为按字面解释的字符串处理,所有字符都视为普通字符。 - 一个 ARE 可以以嵌入选项开头:一个序列(?xyz)(这里的xyz是一个或多个字母字符)声明影响剩余 RE 的选项。 这些选项覆盖任何前面判断的选项 — 特别地,它们可以覆盖一个正则表达式操作符隐含的大小写敏感的行为,或者覆盖flags参数中的正则表达式函数。可用的选项字母在中显示。注意这些同样的选项字母也被用在正则表达式函数的flags参数中。 + 一个 ARE 可以以嵌入选项开头:一个序列(?xyz)(这里的xyz是一个或多个字母字符)声明影响剩余 RE 的选项。 这些选项覆盖任何先前确定的选项 — 特别地,它们可以覆盖一个正则表达式操作符隐含的大小写敏感的行为,或者覆盖正则表达式函数的flags参数所指定的选项。可用的选项字母在中显示。注意这些同样的选项字母也被用在正则表达式函数的flags参数中。
@@ -6153,32 +6078,32 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) n - 新行敏感的匹配(见 + 换行敏感的匹配(见 p - 部分新行敏感的匹配(见 + 部分换行敏感的匹配(见 q - RE的剩余部分是一个文字(quoted)串,全部是普通字符 + RE 的剩余部分按字面(加引号)解释,所有字符都视为普通字符 s - 非新行敏感的匹配(默认) + 非换行敏感的匹配(默认) t - 紧语法(默认,见下文) + 紧凑语法(默认;见下文) w - 逆部分新行敏感(怪异)的匹配(见 + 逆部分换行敏感(怪异)的匹配(见 @@ -6190,16 +6115,16 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2)
- 嵌入选项在)终止序列时发生作用。它们只在 ARE 的开始处起作用 (在任何可能存在的***:控制器后面)。 + 嵌入选项从结束该序列的)处开始生效。它们只能出现在 ARE 的开头(如果存在***:引导前缀,则位于该前缀之后)。 - 除了通常的()RE 语法(这种情况下所有字符都有效), 还有一种扩展语法,可以通过声明嵌入的x选项获得。在扩展语法里,RE 中的空白字符被忽略,就像那些在#和其后的新行(或 RE 的末尾)之间的字符一样。这样就允许我们给一个复杂的 RE 分段和注释。不过这个基本规则有三种例外: + 除了通常的紧凑 RE 语法(其中所有字符都有意义)之外,还有一种扩展语法,可以通过指定嵌入的x选项来使用。在扩展语法中,RE 中的空白字符会被忽略,同样被忽略的还有#与其后的换行符(或 RE 末尾)之间的所有字符。这使得复杂的 RE 可以分段并添加注释。此基本规则有三个例外: - 空白字符或前置了\#将被保留 + 空白字符或 # 的前面若有 \,该字符就会被保留。 @@ -6214,14 +6139,14 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 为了这个目的,空白是空格、制表符、新行以及任何属于 whitespace 字符类的字符。 + 在这里,空白字符包括空格、制表符、换行符,以及属于space字符类的任何字符。 - 最后,在 ARE 里,方括号表达式外面,序列(?#ttt)(其中ttt是任意不包含一个))的文本)是一个注释, 它被完全忽略。同样,这样的东西是不允许出现在多字符符号的字符中间的,例如 (?:。这种注释更像是一种历史产物而不是一种有用的设施,并且它们的使用已经被废弃;请使用扩展语法来替代。 + 最后,在 ARE 里,方括号表达式外面,序列(?#ttt)(其中ttt是任意不包含一个)的文本)是一个注释, 它被完全忽略。同样,这样的东西是不允许出现在多字符符号的字符中间的,例如 (?:。这种注释更像是一种历史产物而不是一种有用的设施,并且它们的使用已经被废弃;请使用扩展语法来替代。
- 如果声明了一个初始的***=控制器,那么所有这些元语法扩展都不能使用,因为这样表示把用户输入当作一个文字串而不是 RE 对待。 + 如果指定了开头的***=引导前缀,那么这些元语法扩展都不能使用,因为这表示把用户输入作为按字面解释的字符串,而非 RE 处理。 @@ -6238,7 +6163,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 大多数原子以及所有约束,都没有贪婪属性(因为它们毕竟无法匹配个数变化的文本)。 + 大多数原子以及所有约束,都没有贪婪属性(因为它们毕竟无法匹配长度不定的文本)。 @@ -6290,7 +6215,7 @@ SELECT SUBSTRING('XY1234Z', 'Y*?([0-9]{1,3})');
- 简而言之,如果一个 RE 同时包含贪婪和非贪婪的子表达式,那么总的匹配长度要么是尽可能长,要么是尽可能短,这取决于给整个 RE 赋予的属性。给子表达式赋予的属性只影响在这个匹配里,各个子表达式之间相互允许吃掉的多少。 + 简而言之,如果一个 RE 同时包含贪婪和非贪婪的子表达式,那么总的匹配长度要么是尽可能长,要么是尽可能短,这取决于给整个 RE 赋予的属性。给子表达式赋予的属性只影响在这个匹配里,各个子表达式相对于其他子表达式能吃掉多少内容。 @@ -6324,23 +6249,23 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 如果声明了大小写无关的匹配,那么效果就好像所有大小写区别在字母表中消失了。如果在多个情况中一个字母以一个普通字符的形式出现在方括号表达式外面,那么它实际上被转换成 一个包含大小写的方括号表达式,也就是说,x 变成 [xX]。 如果它出现在一个方括号表达式里面,那么它的所有大小写的同族都被加入 方括号表达式中,也就是说,x变成[xX]。当它出现在一个方括号表达式内时,它的所有大小写副本都被加入到方括号表达式中,例如, [x]会变成[xX],而[^x]会变成[^xX]。 + 如果指定不区分大小写的匹配,其效果近似于字母表中的所有大小写差别都消失了。当存在大小写形式的字母作为普通字符出现在方括号表达式之外时,实际上会转换为包含其大小写形式的方括号表达式,例如x变成[xX]。当它出现在方括号表达式内部时,其所有大小写形式都会加入该表达式,例如[x]变成[xX][^x]变成[^xX] 如果指定了换行敏感的匹配,.和使用^的方括号表达式 将永远不会匹配换行字符(这样,匹配就不会跨越行,除非 RE 显式地包含了换行)并且^$除了分别匹配串开头和结尾之外,还将分别匹配换行后面和前面的空串。 但是 ARE 转义\A\Z仍然匹配串的开头和结尾。 - 此外,字符类缩写符\D\W将匹配换行,而无论这种模式如何。 + 此外,字符类简写\D\W将匹配换行,而无论这种模式如何。 (在PostgreSQL 14之前,它们在换行敏感模式下不匹配换行。 写入[^[:digit:]][^[:word:]]以获取旧的行为。) - 如果指定了部分新行敏感的匹配,那么它影响.和方括号表达式, 这个时候和新行敏感的匹配一样,但是不影响^$。 + 如果指定了部分换行敏感的匹配,那么它影响.和方括号表达式, 这个时候和换行敏感的匹配一样,但是不影响^$ - 如果指定了逆新行敏感匹配,那么它影响^$,其作用和在新行敏感的匹配里一样,但是不影响.和方括号表达式。这个并不是很有用,只是为了满足对称性而提供的。 + 如果指定了逆部分换行敏感匹配,那么它影响^$,其作用和在换行敏感的匹配里一样,但是不影响.和方括号表达式。这个并不是很有用,只是为了满足对称性而提供的。 @@ -6353,11 +6278,11 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}');
- ARE 实际上和 POSIX ERE 不兼容的唯一的特性是在方括号表达式里\并不失去它特殊的含义。所有其它 ARE 特性都使用在 POSIX ERE 里面是非法或者是未定义、未声明效果的语法;指示器的***就是在 POSIX 的 BRE 和 ERE 之外的语法。 + ARE 与 POSIX ERE 实际不兼容的唯一特性是:\在方括号表达式中不会失去特殊含义。其他所有 ARE 特性所使用的语法,在 POSIX ERE 中都是非法的,或其效果未定义或未指定;引导前缀的***语法同样不属于 POSIX 的 BRE 或 ERE 语法。 - 许多 ARE 扩展都是从 Perl 那里借来的(但是有些被做了修改来清理它们),以及一些 Perl 里没有出现的扩展。要注意的不兼容性包括\b\B、对结尾的新行缺乏特别的处理、对那些被新行敏感匹配的东西附加的补齐方括号表达式、在 lookahead/lookbehind 约束里对圆括号和反向引用的限制以及最长/最短 匹配(而不是第一匹配)的语义。 + 许多 ARE 扩展借鉴自 Perl,但其中一些经过了整理和修改,也未实现少数 Perl 扩展。需要注意的不兼容之处包括\b\B、不对末尾换行符作特殊处理、取反的方括号表达式也受换行敏感匹配影响、先行和后行约束中对圆括号及反向引用的限制,以及采用最长或最短匹配而非首次匹配的语义。 @@ -6366,7 +6291,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 基本正则表达式 - BREs 在几个方面和 ERE 不太一样。在 BRE 中,|+?都是普通字符并且没有与它们功能等价的东西。范围的定界符是\{\}, 因为 {}本身是普通字符。嵌套的子表达式的圆括号是\(\),因为()自身是普通字符。除非在 RE 开头或者是圆括号子表达式开头,^都是一个普通字符。 除非在 RE 结尾或者是圆括号子表达式的结尾,$是一个普通字符。如果*出现在 RE 开头或者是圆括号封装的子表达式开头 (前面可能有^),那么它是个普通字符。最后,可以用单数字的反向引用,\<\>分别是[[:<:]][[:>:]]的同义词;在 BRE 中没有其它可用的转义。 + BRE 在几个方面和 ERE 不太一样。在 BRE 中,|+?都是普通字符并且没有与它们功能等价的东西。范围的定界符是\{\},而{}本身是普通字符。嵌套的子表达式的圆括号是\(\),而()自身是普通字符。除非在 RE 开头或者是圆括号子表达式开头,^都是一个普通字符。 除非在 RE 结尾或者是圆括号子表达式的结尾,$是一个普通字符。如果*出现在 RE 开头或者是圆括号封装的子表达式开头 (前面可能有^),那么它是个普通字符。最后,可以用单数字的反向引用,\<\>分别是[[:<:]][[:>:]]的同义词;在 BRE 中没有其它可用的转义。 @@ -6422,7 +6347,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); SQL标准 - PostgreSQL + PostgreSQL @@ -6479,16 +6404,13 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 使用\p{UnicodeProperty}或其反义\P{UnicodeProperty}来定义XQuery字符类元素是不被支持的。 + 使用\p{UnicodeProperty}或其取反形式\P{UnicodeProperty}来定义XQuery字符类元素是不被支持的。 - POSIX解释字符类,如\w - (参见) - 根据当前区域设置(你可以通过将COLLATE子句附加到操作符或函数上来控制)。 - XQuery通过参考Unicode字符属性来指定这些类别,因此只有遵循Unicode规则的区域设置才能获得等效行为。 + POSIX 根据当前区域设置解释\w等字符类(参见);你可以通过为操作符或函数附加COLLATE子句来控制该区域设置。XQuery 根据 Unicode 字符属性定义这些类,因此只有使用遵循 Unicode 规则的区域设置时,才能得到等效行为。 @@ -6501,10 +6423,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 在描述的字符输入转义中 - 中, - XQuery仅支持\n\r, - 和\t。 + 在描述的字符输入转义中,XQuery 仅支持 \n\r\t @@ -6516,7 +6435,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - XQuery没有前瞻或后顾约束,也没有在中描述的任何约束转义。 + XQuery没有先行或后行约束,也没有在中描述的任何约束转义。 @@ -6536,7 +6455,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); XQuery的s(允许点匹配换行符) 和m(允许^ - 和$匹配换行符)标志提供 + 和$在换行处匹配)标志提供 与POSIX的npw标志相同的行为,但它们 匹配POSIX的sm标志的行为。 @@ -6567,11 +6486,11 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 数据类型格式化函数 - formatting + 格式化 - PostgreSQL格式化函数提供一套强大的工具用于把各种数据类型 (日期/时间、整数、浮点、数字) 转换成格式化的字符串以及反过来从格式化的字符串转换成 指定的数据类型。列出了这些函数。这些函数都遵循一个公共的调用规范: 第一个参数是待格式化的值,而第二个是一个定义输出或输入格式的模板。 + PostgreSQL格式化函数提供一套强大的工具用于把各种数据类型 (日期/时间、整数、浮点数、数值) 转换成格式化的字符串以及反过来从格式化的字符串转换成 指定的数据类型。列出了这些函数。这些函数都遵循一个公共的调用规范: 第一个参数是待格式化的值,而第二个是一个定义输出或输入格式的模板。 @@ -6622,7 +6541,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); text - 根据给定的格式将间隔转换为字符串。 + 根据给定的格式将时间间隔转换为字符串。 to_char(interval '15h 2m 12s', 'HH24:MI:SS') @@ -6678,7 +6597,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); numeric - 根据给定的格式将字符串转换为数字。 + 根据给定的格式将字符串转换为数值。 to_number('12,454.8-', '99G999D9S') @@ -6719,7 +6638,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 展示了可以用于格式化日期和时间值的模版。 + 展示了可以用于格式化日期和时间值的模板模式。
@@ -6802,24 +6721,24 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); SSSS, SSSSS - 午夜后的秒 (0–86399) + 自午夜起的秒数 (0–86399) AM, am, - PM or pm - 正午指示器(不带句号) + PMpm + 上午/下午标记(不带句点) A.M., a.m., - P.M. or p.m. - 正午指示器(带句号) + P.M.p.m. + 上午/下午标记(带句点) Y,YYY - 带逗号的年(4 位或者更多位) with comma + 带逗号的年(4 位或者更多位) @@ -6876,17 +6795,17 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); MONTH - 全大写形式的月名(空格补齐到 9 字符) + 大写的月份全称(空格补齐到 9 字符) Month - 全首字母大写形式的月名(空格补齐到 9 字符) + 首字母大写的月份全称(空格补齐到 9 字符) month - 全小写形式的月名(空格补齐到 9 字符) + 小写的月份全称(空格补齐到 9 字符) @@ -6911,72 +6830,72 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); DAY - 全大写形式的日名(空格补齐到 9 字符) + 大写的星期全称(空格补齐到 9 字符) Day - 全首字母大写形式的日名(空格补齐到 9 字符) + 首字母大写的星期全称(空格补齐到 9 字符) day - 全小写形式的日名(空格补齐到 9 字符) + 小写的星期全称(空格补齐到 9 字符) DY - 简写的大写形式的日名(英语 3 字符,本地化长度可变) + 大写的星期简称(英语 3 字符,本地化长度可变) Dy - 简写的首字母大写形式的日名(英语 3 字符,本地化长度可变) + 首字母大写的星期简称(英语 3 字符,本地化长度可变) dy - 简写的小写形式的日名(英语 3 字符,本地化长度可变) + 小写的星期简称(英语 3 字符,本地化长度可变) DDD - 一年中的日(001–366) + 年内日序数(001–366) IDDD - ISO 8601 周编号方式的年中的日 (001–371; 年的第 1 日时第一个 ISO 周的周一) + ISO 8601 周编号方式的年中的日 (001–371; 年的第 1 日是第一个 ISO 周的周一) DD - 月中的日 (01–31) + 月内日序数 (01–31) D - 周中的日,周日 (1) 到周六 (7) + 星期几,周日 (1) 到周六 (7) ID - 周中的 ISO 8601 日,周一 (1) 到周日 (7) + ISO 8601 星期几,周一 (1) 到周日 (7) W - 月中的周 (1–5) (第一周从该月的第一天开始) + 月内周序数 (1–5) (第一周从该月的第一天开始) WW - 年中的周数 (1–53) (第一周从该年的第一天开始) + 年中的周编号 (1–53) (第一周从该年的第一天开始) IW - ISO 8601 周编号方式的年中的周数 (01–53; 新的一年的第一个周四在第一周) + ISO 8601 周编号方式的年中的周编号 (01–53; 新的一年的第一个周四在第一周) @@ -7026,24 +6945,24 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); OF - 从UTC开始的时区偏移(仅在to_char中支持) + 相对于 UTC 的时区偏移(仅在to_char中支持)
- 修饰语可以被应用于模板模式来修改它们的行为。例如,FMMonth就是带着FM修饰语的Month模式。展示了可用于日期/时间格式化的修饰语模式。 + 修饰符可以被应用于模板模式来修改它们的行为。例如,FMMonth就是带着FM修饰符的Month模式。展示了可用于日期/时间格式化的修饰符模式。 - 用于日期/时间格式化的模板模式修饰语 + 用于日期/时间格式化的模板模式修饰符 - 修饰语 + 修饰符 描述 示例 @@ -7051,37 +6970,37 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - FM prefix + FM 前缀 填充模式(抑制前导零和填充的空格) FMMonth - TH suffix + TH 后缀 大写形式的序数后缀 - DDTH, e.g., 12TH + DDTH,例如, 12TH - th suffix + th 后缀 小写形式的序数后缀 - DDth, e.g., 12th + DDth,例如, 12th - FX prefix - 固定的格式化全局选项(见使用须知) + FX 前缀 + 固定格式全局选项(见使用须知) FX Month DD Day - TM prefix - 翻译模式(基于使用本地化的日和月名) + TM 前缀 + 翻译模式(基于使用本地化的星期名和月份名) TMMonth - SP suffix + SP 后缀 拼写模式(未实现) DDSP @@ -7098,8 +7017,8 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); FM抑制了在模式输出中添加前导零和尾随空格的行为,这些前导零和尾随空格 本来会被添加以使输出成为固定宽度。在PostgreSQL中, - FM仅修改下一个规范,而在Oracle中FM影响所有后续 - 规范,并且重复的FM修饰符切换填充模式的开启和关闭。 + FM仅修改下一个格式说明,而在Oracle中FM影响所有后续 + 格式说明,并且重复的FM修饰符切换填充模式的开启和关闭。 @@ -7157,10 +7076,10 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 一个TZH模板模式可以匹配有符号数。 - 没有FX选项,减号可能会有歧义,并且可能被解释为分隔符。 - 此歧义解决如下:如果模板字符串中TZH之前的分隔符数量少于输入字符串中减号之前的分隔符数量, - 则减号被解释为TZH的一部分。 - 否则,减号被视为值之间的分隔符。 + 没有FX选项,负号可能会有歧义,并且可能被解释为分隔符。 + 此歧义解决如下:如果模板字符串中TZH之前的分隔符数量少于输入字符串中负号之前的分隔符数量, + 则负号被解释为TZH的一部分。 + 否则,负号被视为值之间的分隔符。 例如,to_timestamp('2000 -10', 'YYYY TZH')匹配 -10TZH,但 to_timestamp('2000 -10', 'YYYY  TZH') @@ -7171,12 +7090,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 普通文本允许在to_char模板中,并且将被直接输出。您可以将子字符串放在双引号中, - 以强制将其解释为文字文本,即使它包含模板模式。例如,在'"Hello Year "YYYY'中, - YYYY将被年份数据替换,但Year中的单个Y不会被替换。 - 在to_dateto_numberto_timestamp中, - 文本和双引号字符串会导致跳过字符串中包含的字符数;例如"XX"跳过两个输入字符 - (无论它们是否为XX)。 + 普通文本可以出现在to_char模板中,并会按字面输出。可以用双引号括起子串,使其即使包含模式关键字也强制按字面文本解释。例如,在'"Hello Year "YYYY'中,YYYY会被年份数据替换,但Year中单独的Y不会被替换。在to_dateto_numberto_timestamp中,字面文本和双引号字符串会跳过与该字符串所含字符数相同数量的输入字符;例如,"XX"跳过两个输入字符(无论它们是否为XX)。 @@ -7195,7 +7109,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 如果您想在输出中使用双引号,必须在其前面加上反斜杠,例如'\"YYYY Month\"' - 反斜杠在双引号之外不起特殊作用。在双引号字符串内部,反斜杠会使下一个字符被直接解释,无论是什么(但除非下一个字符是双引号或另一个反斜杠,否则没有特殊效果)。 + 反斜杠在双引号之外不起特殊作用。在双引号字符串内部,反斜杠会使下一个字符被按字面解释,无论是什么(但除非下一个字符是双引号或另一个反斜杠,否则没有特殊效果)。 @@ -7258,14 +7172,14 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 年份、周数和星期几:例如to_date('2006-42-4', 'IYYY-IW-ID') + 年份、周编号和星期几:例如to_date('2006-42-4', 'IYYY-IW-ID') 返回日期2006-10-19。 如果省略星期几,则假定为1(星期一)。 - 年份和年内天数:例如to_date('2006-291', 'IYYY-IDDD')也返回2006-10-19。 + 年份和年内日序数:例如to_date('2006-291', 'IYYY-IDDD')也返回2006-10-19 @@ -7273,14 +7187,14 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 尝试使用ISO 8601周编号字段和公历日期字段的混合输入日期是荒谬的,并将导致错误。 - 在ISO 8601周编号年的背景下,月份日期的概念没有意义。 + 在ISO 8601周编号年的背景下,月份月内日序数的概念没有意义。 在公历年的背景下,ISO周没有意义。 - 当to_date拒绝混合使用公历和ISO周编号日期字段时, - to_char不会,因为输出格式规范如YYYY-MM-DD (IYYY-IDDD)可能很有用。 + 虽然to_date会拒绝混合使用公历和ISO周编号日期字段, + 但to_char不会,因为输出格式规范如YYYY-MM-DD (IYYY-IDDD)可能很有用。 但要避免编写类似IYYY-MM-DD的内容;那会在年初附近产生令人惊讶的结果。 (有关更多信息,请参见。) @@ -7299,7 +7213,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 这是一个更复杂的示例: to_timestamp('15:12:02.020.001230', 'HH24:MI:SS.MS.US') - 是15小时,12分钟和2秒 + 20毫秒 + 1230微秒 = 2.021230秒。 + 为15小时12分钟,秒数为2秒 + 20毫秒 + 1230微秒 = 2.021230秒。 @@ -7307,7 +7221,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); to_char(..., 'ID')的星期几编号与extract(isodow from ...)函数匹配, - 但to_char(..., 'D')的不匹配extract(dow from ...)的星期编号。 + 但to_char(..., 'D')的不匹配extract(dow from ...)的星期几编号。 @@ -7324,12 +7238,12 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 展示了可以用于格式化数字值的模版模式。 + 展示了可以用于格式化数值的模板模式。
- 用于数字格式化的模板模式 + 用于数值格式化的模板模式 @@ -7342,21 +7256,21 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 9 - 数位(如果无意义可以被删除) + 数位(非有效位可以被省略) 0 - 数位(即便没有意义也不会被删除) + 数位(即便是非有效位也不会被省略) - . (period) + .(句点) 小数点 - , (comma) + ,(逗号) 分组(千)分隔符 @@ -7367,22 +7281,22 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); S - 带符号的数字(使用区域) + 紧贴数值的正负号(使用区域设置) L - 货币符号(使用区域) + 货币符号(使用区域设置) D - 小数点(使用区域) + 小数点(使用区域设置) G - 分组分隔符(使用区域) + 分组分隔符(使用区域设置) @@ -7406,7 +7320,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - TH or th + THth 序数后缀 @@ -7424,7 +7338,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}');
- 数字格式化的使用注意事项: + 数值格式化的使用注意事项: @@ -7440,14 +7354,14 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 如果格式提供的小数位数少于被格式化的数字,则to_char()将会将数字四舍五入到指定的小数位数。 + 如果格式指定的小数位数少于被格式化数值的小数位数,to_char()会将该数值舍入到指定的小数位数。 - 模式字符SLDG表示当前区域设置定义的符号、货币符号、小数点和千位分隔符字符 + 模式字符SLDG表示当前区域设置定义的正负号、货币符号、小数点和千位分隔符字符 (参见)。模式字符句点和逗号表示这些确切字符,具有小数点和千位分隔符的含义,不受区域设置影响。 @@ -7456,15 +7370,14 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 如果在to_char()的模式中没有明确指定符号,将为符号保留一列,并将其锚定到(出现在)数字的左侧。 - 如果S出现在一些9的左侧,它也将锚定到数字。 + 如果to_char()的模式中没有明确指定正负号的位置,就会为正负号保留一列,并使其紧贴数值(紧靠数值左侧)。如果S紧邻若干个9的左侧,它同样会紧贴数值。 - 使用SGPLMI格式化的符号不与数字绑定; + 使用SGPLMI格式化的正负号不紧贴数值; 例如,to_char(-12, 'MI9999')会产生'-  12', 但to_char(-12, 'S9999')会产生'  -12'。 (Oracle实现不允许在9之前使用MI,而是要求9MI之前。) @@ -7491,7 +7404,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); to_number函数中,如果使用非数据模板模式,如LTH, - 则会跳过相应数量的输入字符,无论它们是否与模板模式匹配,除非它们是数据字符(即数字、符号、小数点或逗号)。 + 则会跳过相应数量的输入字符,无论它们是否与模板模式匹配,除非它们是数据字符(即数字、正负号、小数点或逗号)。 例如,TH会跳过两个非数据字符。 @@ -7502,7 +7415,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); Vto_char一起, 将输入值乘以10^n, 其中n是跟在V后面的数字位数。 - Vto_number一起以类似的方式除法。 + Vto_number一起以类似的方式进行除法。 to_charto_number不支持与小数点结合使用的V (例如,不允许使用99.9V99)。 @@ -7518,17 +7431,17 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}');
- 某些修饰语可以被应用到任何模板来改变其行为。例如,FM99.99是带有FM修饰语的99.99模式。中展示了用于数字格式化模式修饰语。 + 某些修饰符可以被应用到任何模板来改变其行为。例如,FM99.99是带有FM修饰符的99.99模式。中展示了用于数值格式化的模式修饰符。 - 用于数字格式化的模板模式修饰语 + 用于数值格式化的模板模式修饰符 - 修饰语 + 修饰符 描述 示例 @@ -7536,19 +7449,19 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - FM prefix - 填充模式(抑制拖尾零和填充的空白) + FM 前缀 + 填充模式(抑制尾随零和填充的空白) FM99.99 - TH suffix + TH 后缀 大写序数后缀 999TH - th suffix + th 后缀 小写序数后缀 999th @@ -7732,10 +7645,10 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 时间/日期函数和操作符 + 日期/时间函数和操作符 - 展示了可用于处理日期/时间值的函数,其细节在随后的小节中描述。演示了基本算术操作符 (+*等)的行为。 而与格式化相关的函数,可以参考。你应该很熟悉中的日期/时间数据类型的背景知识。 + 展示了可用于处理日期/时间值的函数,其细节在随后的小节中描述。演示了基本算术操作符 (+*等)的行为。 而与格式化相关的函数,可以参考。你应当熟悉中的日期/时间数据类型的背景知识。 @@ -7821,7 +7734,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); interval - 添加时间间隔 + 将两个时间间隔相加 interval '1 day' + interval '1 hour' @@ -7863,7 +7776,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); interval - 取否一个时间间隔 + 对时间间隔取负 - interval '23 hours' @@ -7877,7 +7790,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); integer - 减去日期,生成经过的天数 + 将两个日期相减,得到相隔的天数 date '2001-10-01' - date '2001-09-28' @@ -7919,7 +7832,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); interval - 减去时间 + 将两个时间相减 time '05:00' - time '03:00' @@ -7961,7 +7874,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); interval - 减去时间间隔 + 将两个时间间隔相减 interval '1 day' - interval '1 hour' @@ -7975,12 +7888,12 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); interval - 减去时间戳(将24小时间隔转换为天数,类似于justify_hours() - 时间戳 '2001-09-29 03:00' - 时间戳 '2001-07-27 12:00' - 63 天 15:00:00 + timestamp '2001-09-29 03:00' - timestamp '2001-07-27 12:00' + 63 days 15:00:00 @@ -7990,7 +7903,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); interval - 将时间间隔乘以数量 + 将时间间隔乘以一个标量 interval '1 second' * 900 @@ -8012,7 +7925,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); interval - 用时间间隔除以数量 + 将时间间隔除以一个标量 interval '1 hour' / 1.5 @@ -8053,7 +7966,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); interval - 减去参数,生成一个使用年和月,而不是只用日的符号化的结果 + 将两个参数相减,生成一个使用年和月,而不是只用日的符号化的结果 age(timestamp '2001-04-10', timestamp '1957-06-13') @@ -8067,7 +7980,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); interval - 从 current_date 减去参数(在午夜) + 从current_date(午夜时刻)减去参数 age(timestamp '1957-06-13') @@ -8118,7 +8031,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); time with time zone - 一天中的当前时间;参见 + 一天中的当前时刻;参见 current_time @@ -8132,7 +8045,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); time with time zone - 一天中的当前时间;有限精度;参见 + 一天中的当前时刻,精度受限;参见 current_time(2) @@ -8149,7 +8062,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); timestamp with time zone - 当前日期和时间 (当前事务的开始);参见 + 当前日期和时间(当前事务开始时);参见 current_timestamp @@ -8163,7 +8076,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); timestamp with time zone - 当前日期和时间 (当前事务的开始);有限精度;参见 + 当前日期和时间(当前事务开始时),精度受限;参见 current_timestamp(0) @@ -8211,7 +8124,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); double precision - 获取时间戳字段 (等同于 extract);参见 + 获取时间戳子字段 (等同于 extract);参见 date_part('hour', timestamp '2001-02-16 20:38:40') @@ -8335,7 +8248,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); boolean - 测试有限日期(不是+/-无限) + 测试日期是否有限(不是正负无穷) isfinite(date '2001-02-16') @@ -8349,7 +8262,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); boolean - 测试有限时间戳(不是+/-无限) + 测试时间戳是否有限(不是正负无穷) isfinite(timestamp 'infinity') @@ -8416,7 +8329,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); interval - 使用 justify_daysjustify_hours调整时间间隔; 通过额外的符号调整 + 使用 justify_daysjustify_hours调整时间间隔,并额外调整符号 justify_interval(interval '1 mon -1 hour') @@ -8433,7 +8346,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); time - 一天中当前时间;参见 + 一天中的当前时刻;参见 localtime @@ -8447,7 +8360,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); time - 一天中的当前时间,有限精度;参见 + 一天中的当前时刻,精度受限;参见 localtime(0) @@ -8464,7 +8377,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); timestamp - 当前日期和时间(当前事务的开始);参见 + 当前日期和时间(当前事务开始时);参见 localtimestamp @@ -8478,7 +8391,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); timestamp - 当前日期和时间(当前事务的开始);有限精度;参见 + 当前日期和时间(当前事务开始时),精度受限;参见 localtimestamp(2) @@ -8606,7 +8519,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); timestamp with time zone - 当前日期和时间(当前事务的开始);参见 + 当前日期和时间(当前事务开始时);参见 now() @@ -8623,7 +8536,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); timestamp with time zone - 当前日期和时间(当前语句的开始);参见 + 当前日期和时间(当前语句开始时);参见 statement_timestamp() @@ -8658,7 +8571,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); timestamp with time zone - 当前日期和时间(当前事务的开始);参见 + 当前日期和时间(当前事务开始时);参见 transaction_timestamp() @@ -8675,7 +8588,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); timestamp with time zone - 将Unix纪元转换为带时区的时间戳(从1970-01-01 00:00:00+00开始的秒) + 将 Unix 纪元时间(自 1970-01-01 00:00:00+00 起的秒数)转换为带时区的时间戳 to_timestamp(1284352323) @@ -8695,7 +8608,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); (start1, end1) OVERLAPS (start2, end2) (start1, length1) OVERLAPS (start2, length2) - 这个表达式在两个时间域(用它们的端点定义)重叠的时候得到真,当它们不重叠时得到假。端点可以用一对日期、时间或者时间戳来指定;或者是用一个后面跟着一个间隔的日期、时间或时间戳来指定。当一对值被提供时,起点或终点都可以被写在前面,OVERLAPS会自动地把较早的值作为起点。每一个时间段被认为是表示半开的间隔start <= time < end,除非startend相等,这种情况下它表示单个时间实例。例如这表示两个只有一个共同端点的时间段不重叠。 + 这个表达式在两个时间段(用它们的端点定义)重叠的时候得到真,当它们不重叠时得到假。端点可以用一对日期、时间或者时间戳来指定;或者是用一个后面跟着一个间隔的日期、时间或时间戳来指定。当一对值被提供时,起点或终点都可以被写在前面,OVERLAPS会自动地把较早的值作为起点。每一个时间段被认为是表示半开区间start <= time < end,除非startend相等,这种情况下它表示单个时刻。例如这表示两个只有一个共同端点的时间段不重叠。 @@ -8714,16 +8627,19 @@ SELECT (DATE '2001-10-30', DATE '2001-10-30') OVERLAPS - 当把一个interval值添加到timestamp with time zone上(或从中减去)时,天这一部分会按照指定的天数增减该timestamp with time zone的日期,同时保持一天中的时间不变。 - 对于跨越夏令时变更的情况(当会话时区被设置为能够识别 DST 的时区时),这意味着interval '1 day'并不一定等于interval '24 hours'。 - 例如,当会话的时区设置为America/Denver时: + 当把一个interval值加到timestamptimestamp with time zone值上(或从中减去一个interval值)时,会依次处理interval值的月、日和微秒字段。 + 首先,非零的月字段会按指定月数增减时间戳的日期,同时保持其在月份中的日不变;如果该日超出了新月份的月末,则使用该月的最后一天。(例如,3 月 31 日加 1 个月得到 4 月 30 日,加 2 个月则得到 5 月 31 日。) + 然后,日字段会按指定天数增减时间戳的日期。在这两个步骤中,一天中的本地时刻保持不变。最后,如果微秒字段不为零,则直接加上或减去该值。 + 在识别夏令时的时区中对timestamp with time zone值进行运算时,这意味着加上或减去(例如)interval '1 day'与加上或减去interval '24 + hours'的结果不一定相同。 + 例如,当会话时区设为America/Denver时: SELECT timestamp with time zone '2005-04-02 12:00:00-07' + interval '1 day'; 结果:2005-04-03 12:00:00-06 SELECT timestamp with time zone '2005-04-02 12:00:00-07' + interval '24 hours'; 结果:2005-04-03 13:00:00-06 - - 发生这种情况是因为在America/Denver时区,夏令时在2005-04-03 02:00:00发生切换,导致跳过了一个小时。 + + 发生这种情况是因为在2005-04-03 02:00:00America/Denver时区切换了夏令时,跳过了一个小时。 @@ -8731,15 +8647,9 @@ SELECT timestamp with time zone '2005-04-02 12:00:00-07' + interval '24 hours'; - 日期和时间戳的减法也可能会很复杂。执行减法的一种概念上很简单的方法是,使用 - EXTRACT(EPOCH FROM ...)把每个值都转换成秒数,然后执行减法, - 这样会得到两个值之间的数。这种方法将会适应每个月中天数、 - 时区改变和夏令时调整。使用-操作符的日期或时间 - 戳减法会返回值之间的天数(24小时)以及时/分/秒,也会做同样的调整。 - age函数会返回年、月、日以及时/分/秒,执行按域的减法,然后对 - 负值域进行调整。下面的查询展示了这些方法的不同。示例中的结果由 - timezone = 'US/Eastern'产生,这使得两个使用的日期之间存在着夏令 - 时的变化: + 日期和时间戳的减法也可能很复杂。一种概念上简单的方法是,先用EXTRACT(EPOCH FROM ...)将各值转换为秒数,然后将结果相减;这样得到的是两个值之间的数。这种方法会针对每个月的天数、时区变化和夏令时变化进行调整。 + 用-操作符将日期或时间戳值相减,会返回两个值之间的天数(每一天为 24 小时)和时/分/秒,也会作相同的调整。age函数返回年、月、日和时/分/秒,它会逐字段相减,然后调整负值字段。 + 以下查询显示了这些方法的差异。示例结果在timezone = 'US/Eastern'设置下产生;所用的两个日期之间发生了夏令时切换: @@ -8791,7 +8701,7 @@ EXTRACT(field FROM source) - 这个世纪;对于interval值,年份字段除以100 + 世纪;对于interval值,年份字段除以100 @@ -8814,7 +8724,7 @@ SELECT EXTRACT(CENTURY FROM INTERVAL '2001 years'); - 月份的日期(1–31);对于interval值,表示天数 + 一个月中的第几天(1–31);对于interval值,表示天数 @@ -8867,7 +8777,7 @@ SELECT EXTRACT(DOW FROM TIMESTAMP '2001-02-16 20:38:40'); - 一年中的日子(1-365/366) + 一年中的第几天(1–365/366) @@ -8882,7 +8792,7 @@ SELECT EXTRACT(DOY FROM TIMESTAMP '2001-02-16 20:38:40'); - 对于timestamp with time zone值,自1970-01-01 00:00:00 UTC以来的秒数(负值表示该时间戳之前的时间); + 对于timestamp with time zone值,自1970-01-01 00:00:00 UTC以来的秒数(早于该时刻的时间戳对应负值); 对于datetimestamp值,自1970-01-01 00:00:00以来的名义秒数,不考虑时区或夏令时规则; 对于interval值,间隔中的总秒数 @@ -8906,8 +8816,8 @@ SELECT to_timestamp(982384720.12); - 注意,将to_timestamp应用于从datetimestamp值中提取的时代可能会产生误导性的结果: - 结果将有效地假定原始值是以UTC时间给出的,这可能并非事实。 + 注意,将to_timestamp应用于从datetimestamp值中提取的 epoch 值可能会产生误导性的结果: + 结果实际上会假定原始值是以UTC时间给出的,这可能并非事实。 @@ -8963,8 +8873,7 @@ SELECT EXTRACT(ISOYEAR FROM DATE '2006-01-02'); - 每个ISO 8601周编号年从包含1月4日的星期一开始,因此在一月初或十二月底,ISO年可能与格里高利年不同。 - 有关更多信息,请参见week字段。 + 每个 ISO 8601 周编号年都从包含 1 月 4 日的那一周的星期一开始,因此在 1 月初或 12 月末,ISO 年可能与格里高利年不同。更多信息请参见 week 字段。 @@ -9007,7 +8916,7 @@ SELECT EXTRACT(MICROSECONDS FROM TIME '17:12:28.5'); - 千年; 对于interval值,年份字段除以1000 + 千年; 对于interval值,年份字段除以1000 @@ -9018,7 +8927,7 @@ SELECT EXTRACT(MILLENNIUM FROM INTERVAL '2001 years'); - 20世纪的年份在第二个千年。第三个千年从2001年1月1日开始。 + 1900 年代的年份属于第二个千年。第三个千年始于 2001 年 1 月 1 日。 @@ -9028,7 +8937,7 @@ SELECT EXTRACT(MILLENNIUM FROM INTERVAL '2001 years'); - 第二个字段,包括小数部分,乘以1000。请注意,这包括完整的秒数。 + 秒字段,包括小数部分,乘以1000。请注意,这包括完整的秒数。 @@ -9058,7 +8967,7 @@ SELECT EXTRACT(MINUTE FROM TIMESTAMP '2001-02-16 20:38:40'); - 月份在一年中的编号(1-12);对于interval值,月份模12的余数(0-11) + 月份在一年中的编号(1–12);对于interval值,月份模12的余数(0–11) @@ -9077,7 +8986,7 @@ SELECT EXTRACT(MONTH FROM INTERVAL '2 years 13 months'); - 日期所在的年份季度(1-4) + 日期所在的年份季度(1–4) @@ -9119,7 +9028,7 @@ SELECT EXTRACT(SECOND FROM TIME '17:12:28.5'); - 时间区偏移的小时组件 + 时区偏移的小时部分 @@ -9129,7 +9038,7 @@ SELECT EXTRACT(SECOND FROM TIME '17:12:28.5'); - 时间区偏移的分钟组件 + 时区偏移的分钟部分 @@ -9139,16 +9048,11 @@ SELECT EXTRACT(SECOND FROM TIME '17:12:28.5'); - 一年中ISO 8601周编号周的数量。根据定义,ISO周从周一开始, - 一年的第一周包含该年的1月4日。换句话说,一年的第一个星期四在该年的第1周。 + 一年中按ISO 8601 周编号体系计算的周序号。根据定义,ISO 周从周一开始,一年的第一周包含该年的 1 月 4 日。换句话说,一年的第一个星期四在该年的第 1 周。 - 在ISO周编号系统中,早年1月的日期可能属于前一年的第52周或第53周,而 - 晚年12月的日期可能属于下一年的第一周。例如,2005-01-01 - 属于2004年的第53周,2006-01-01 属于2005年的第52周, - 而2012-12-31 属于2013年的第一周。建议同时使用 - isoyear 字段和week以获得一致的结果。 + 在 ISO 周编号体系中,1 月初的日期可能属于前一年的第 52 周或第 53 周,而 12 月末的日期可能属于下一年的第一周。例如,2005-01-01属于 2004 年的第 53 周,2006-01-01属于 2005 年的第 52 周,而2012-12-31属于 2013 年的第一周。建议将isoyear字段与week一起使用,以获得一致的结果。 @@ -9163,7 +9067,7 @@ SELECT EXTRACT(WEEK FROM TIMESTAMP '2001-02-16 20:38:40'); - 年份字段。请记住,没有0 AD,所以要小心地从AD年中减去BC年。 + 年份字段。请记住,没有0 AD,所以把BC年份从AD年份中减去时需要小心。 @@ -9190,7 +9094,7 @@ SELECT EXTRACT(MINUTES FROM INTERVAL '80 minutes'); - 当输入值为 +/-Infinity 时,extract对于单调增的域(epochjulianyearisoyeardecadecentury以及millennium)返回 +/-Infinity。对于其他域返回 NULL。PostgreSQL 9.6 之前的版本对所有输入无穷的情况都返回零。 + 当输入值为 +/-Infinity 时,extract对于单调递增的字段(epochjulianyearisoyeardecadecentury以及millennium)返回 +/-Infinity。对于其他字段返回 NULL。PostgreSQL 9.6 之前的版本对所有输入无穷的情况都返回零。 @@ -9199,15 +9103,12 @@ SELECT EXTRACT(MINUTES FROM INTERVAL '80 minutes'); - 在传统的Ingres上建模的date_part函数等价于SQL标准函数extract: + date_part函数仿照传统的Ingres实现,后者对应SQL标准的extract函数: date_part('field', source) - 请注意这里的field参数必须是一个串值,而不是一个名字。 - 有效的date_part域名 和extract相同。 - 由于历史原因,date_part函数返回double precision类型的值。 - 这可能导致在某些使用中损失精度。 - 建议使用extract替代。 + 注意,此处的field参数必须是字符串值,而不能是名称。date_part的有效字段名与extract相同。 + 由于历史原因,date_part函数返回double precision类型的值,可能在某些用途中损失精度。建议改用extract @@ -9234,11 +9135,12 @@ SELECT date_part('hour', INTERVAL '4 hours 3 minutes'); date_trunc(field, source [, time_zone ]) - source是类型timestampinterval的值表达式(类型datetime的值都分别被自动转换成timestamp, timestamp with time zone,或者interval)。field选择对输入值选用什么样的精度进行截断。返回的值是timestamp, timestamp with time zone,类型或者所有小于选定的 精度的域都设置为零(或者一,对于日期和月份)的interval。 + sourcetimestamptimestamp with time zoneinterval类型的值表达式。(datetime类型的值会分别自动转换为timestampinterval。) + field选择输入值的截断精度。返回值同样为timestamptimestamp with time zoneinterval类型,其中低于所选精度的所有字段都设为零(日和月则设为一)。 - field的有效值是∶ + field的有效值是: microseconds milliseconds @@ -9257,7 +9159,7 @@ date_trunc(field, source [ - 当输入值的类型为timestamp with time zone时。截断是针对特定时区进行的。 例如,截断为day,产生的值是 是该区域的午夜。 默认情况下,截断是在以下方面进行的 到当前的设置,但在当前的 可以提供可选的time_zone参数。以指定不同的时区。 可以指定时区名称 中描述的任何一种方式。 + 当输入值为timestamp with time zone类型时,截断会以特定时区为准;例如,截断到day会得到该时区的午夜。默认情况下,截断以当前的设置为准,但可以通过可选的time_zone参数指定其他时区。时区名称可以用中描述的任意方式指定。 @@ -9299,11 +9201,11 @@ date_bin(stride, source, < sourcetimestamptimestamp with time zone类型的值表达式。 (类型date的值会自动转换为timestamp。) strideinterval类型的值表达式。 - 返回值同样是timestamptimestamp with time zone类型,并且它标记着放置source的bin的开始。 + 返回值同样是timestamptimestamp with time zone类型,并且它表示source所在分箱的起点。 - 示例: + 示例: SELECT date_bin('15 minutes', TIMESTAMP '2020-02-11 15:44:17', TIMESTAMP '2001-01-01'); 结果: 2020-02-11 15:30:00 @@ -9322,28 +9224,24 @@ SELECT date_bin('15 minutes', TIMESTAMP '2020-02-11 15:44:17', TIMESTAMP '2001-0 - <literal>AT TIME ZONE</literal> 和 <literal>AT LOCAL</literal> + <literal>AT TIME ZONE</literal> - time zone - conversion + 时区 + 转换 AT TIME ZONE - - AT LOCAL - - - AT TIME ZONE 操作符可在带时区和不带时区的时间戳之间进行转换,也可将 time with time zone 值转换到不同的时区。 展示了它的各种变体。 + AT TIME ZONE 操作符可将不带时区的时间戳转换为时区的时间戳或反向转换,也可将 time with time zone 值转换到不同的时区。 展示了它的各种变体。
- <literal>AT TIME ZONE</literal> 和 <literal>AT LOCAL</literal> 变体 + <literal>AT TIME ZONE</literal> 变体 @@ -9376,20 +9274,6 @@ SELECT date_bin('15 minutes', TIMESTAMP '2020-02-11 15:44:17', TIMESTAMP '2001-0 - - - timestamp without time zone AT LOCAL - timestamp with time zone - - - 将给定的不带时区时间戳转换为带时区时间戳,所用时区为会话的 TimeZone 值。 - - - timestamp '2001-02-16 20:38:40' at local - 2001-02-17 03:38:40+00 - - - timestamp with time zone AT TIME ZONE zone @@ -9404,50 +9288,20 @@ SELECT date_bin('15 minutes', TIMESTAMP '2020-02-11 15:44:17', TIMESTAMP '2001-0 - - - timestamp with time zone AT LOCAL - timestamp without time zone - - - 将给定的带时区时间戳转换为无时区时间戳,所用时区为会话的 TimeZone 值。 - - - timestamp with time zone '2001-02-16 20:38:40-05' at local - 2001-02-16 18:38:40 - - - time with time zone AT TIME ZONE zone - time with time zone - - - 将给定的带时区时间转换到新的时区。由于没有提供日期,这会使用目标时区当前生效的 UTC 偏移量。 - - - time with time zone '05:34:17-05' at time zone 'UTC' - 10:34:17+00 - - - - - - time with time zone AT LOCAL - time with time zone - - - 将给定的带时区时间转换到新的时区,所用时区为会话的 TimeZone 值。由于没有提供日期,这会使用会话 TimeZone 当前生效的 UTC 偏移量。 + time with time zone - 假定会话的 TimeZone 设为 UTC: + 将给定的带时区时间转换到新的时区。由于没有提供日期,这会使用目标时区当前生效的 UTC 偏移量。 - time with time zone '05:34:17-05' at local + time with time zone '05:34:17-05' at time zone 'UTC' 10:34:17+00 +
@@ -9458,12 +9312,7 @@ SELECT date_bin('15 minutes', TIMESTAMP '2020-02-11 15:44:17', TIMESTAMP '2001-0 使用间隔值只对与 UTC 存在固定偏移量的时区有意义,因此在实践中并不常见。
- - 语法 AT LOCAL 可以作为 AT TIME ZONE local 的简写,其中 local 是会话的 TimeZone 值。 - - - - 示例(假设当前的设置为America/Los_Angeles): + 示例(假设当前设置为America/Los_Angeles): SELECT TIMESTAMP '2001-02-16 20:38:40' AT TIME ZONE 'America/Denver'; 结果:2001-02-16 19:38:40-08 @@ -9471,36 +9320,10 @@ SELECT TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40-05' AT TIME ZONE 'America/D 结果:2001-02-16 18:38:40 SELECT TIMESTAMP '2001-02-16 20:38:40' AT TIME ZONE 'Asia/Tokyo' AT TIME ZONE 'America/Chicago'; 结果:2001-02-16 05:38:40 -SELECT TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40-05' AT LOCAL; -结果:2001-02-16 17:38:40 -SELECT TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40-05' AT TIME ZONE '+05'; -结果:2001-02-17 06:38:40 -SELECT TIME WITH TIME ZONE '20:38:40-05' AT LOCAL; -结果:17:38:40-08 - - 第一个示例为缺少时区的值添加时区,并使用当前的 TimeZone 设置显示该值。 - 第二个示例将带时区的时间戳值转换到指定时区,并返回无时区的值。 - 这允许存储和显示与当前 TimeZone 设置不同的值。第三个示例将东京时间转换为芝加哥时间。第四个示例展示了 AT LOCAL 的用法。第五个示例使用数值型 UTC 偏移量作为时区。最后一个示例展示了 time with time zone 值转换为会话本地时区的结果。 - - - - 函数timezone(zone, timestamp)等效于 SQL 兼容的结构timestamp AT TIME ZONE zone。 - - - - 结构 timestamp AT LOCAL 等效于 timestamp AT TIME ZONE local。 - +
第一个示例为不带时区的值添加时区,并使用当前TimeZone设置显示该值。第二个示例将带时区的时间戳值移到指定时区,并返回不带时区的值。这样就可以存储和显示与当前TimeZone设置不同的值。第三个示例将东京时间转换为芝加哥时间。
- 函数timezone(zone, timestamp with time zone)等效于 SQL 兼容的结构timestamp with time zone AT TIME ZONE zone。 - - - - 结构 timestamp with time zone AT LOCAL 等效于 timestamp with time zone AT TIME ZONE local。 - - - - 函数timezone(zone, time with time zone)等效于 SQL 兼容的结构time with time zone AT TIME ZONE zone。结构 time with time zone AT LOCAL 等效于 time with time zone AT TIME ZONE local。 + 函数timezone(zone, timestamp)等效于符合 SQL 标准的结构timestamp AT TIME ZONE zone @@ -9509,13 +9332,13 @@ SELECT TIME WITH TIME ZONE '20:38:40-05' AT LOCAL; 当前日期/时间 - date - current + 日期 + 当前 - time - current + 时间 + 当前 @@ -9534,15 +9357,15 @@ LOCALTIMESTAMP(precision) - CURRENT_TIMECURRENT_TIMESTAMP传递带有时区的值;LOCALTIMELOCALTIMESTAMP传递的值不带时区。 + CURRENT_TIMECURRENT_TIMESTAMP返回带时区的值;LOCALTIMELOCALTIMESTAMP返回不带时区的值。 - CURRENT_TIMECURRENT_TIMESTAMPLOCALTIMELOCALTIMESTAMP可以有选择地接受一个精度参数,该精度会使结果的秒字段圆整到指定的小数位数。如果没有精度参数,结果将给出可用的全部精度。 + CURRENT_TIMECURRENT_TIMESTAMPLOCALTIMELOCALTIMESTAMP可以有选择地接受一个精度参数,该精度会使结果的秒字段舍入到指定的小数位数。如果没有精度参数,结果将给出可用的全部精度。 - 一些示例: + 一些示例: SELECT CURRENT_TIME; 结果: 14:39:53.662522-05 @@ -9564,7 +9387,7 @@ SELECT LOCALTIMESTAMP; - 许多其它数据库系统可能会更频繁地推进这些值。 + 其他数据库系统可能会更频繁地推进这些值。 @@ -9581,11 +9404,11 @@ now() - transaction_timestamp()等价于CURRENT_TIMESTAMP,但是其命名清楚地反映了它的返回值。statement_timestamp()返回当前语句的开始时刻(更准确的说是收到 客户端最后一条命令的时间)。statement_timestamp()transaction_timestamp()在一个事务的第一条命令期间返回值相同,但是在随后的命令中却不一定相同。 clock_timestamp()返回真正的当前时间,因此它的值甚至在同一条 SQL 命令中都会变化。timeofday()是一个有历史原因的PostgreSQL函数。和clock_timestamp()相似,timeofday()也返回真实的当前时间,但是它的结果是一个格式化的text串,而不是timestamp with time zone值。now()PostgreSQL的一个传统,等效于transaction_timestamp()。 + transaction_timestamp()等价于CURRENT_TIMESTAMP,但是其命名清楚地反映了它的返回值。statement_timestamp()返回当前语句的开始时刻(更准确地说,是接收到客户端最近一条命令消息的时间)。statement_timestamp()transaction_timestamp()在一个事务的第一条语句期间返回值相同,但是在随后的语句中却不一定相同。 clock_timestamp()返回真正的当前时间,因此它的值甚至在同一条 SQL 语句中都会变化。timeofday()是一个有历史原因的PostgreSQL函数。和clock_timestamp()相似,它也返回真实的当前时间,但是它的结果是一个格式化的text串,而不是timestamp with time zone值。now()PostgreSQL中与transaction_timestamp()等价的传统函数。 - 所有日期/时间类型还接受特殊的文字值now,用于指定当前的日期和时间(重申,被解释为当前事务的开始时刻)。 因此,下面三个都返回相同的结果: + 所有日期/时间数据类型也都接受特殊字面值now来指定当前日期和时间(同样解释为事务开始时间)。因此,下面三种写法都返回相同的结果: SELECT CURRENT_TIMESTAMP; SELECT now(); @@ -9597,7 +9420,7 @@ SELECT TIMESTAMP 'now'; -- 但请参阅下面的提示 当指定以后要计算的值时,不要使用第三种形式,例如在表列的DEFAULT子句中。 - 系统将在分析这个常量的时候把now转换为一个timestamp, 这样需要默认值时就会得到创建表的时间!而前两种形式要到实际使用缺省值的时候才被计算, 因为它们是函数调用。因此它们可以给出每次插入行的时刻。 + 系统将在分析这个常量的时候把now转换为一个timestamp, 这样需要默认值时就会得到创建表的时间!而前两种形式要到实际使用默认值的时候才被计算, 因为它们是函数调用。因此它们可以给出每次插入行的时刻。 (参见 。) @@ -9620,24 +9443,24 @@ SELECT TIMESTAMP 'now'; -- 但请参阅下面的提示 - sleep + 休眠 - delay + 延迟 - 下面的这些函数可以用于让服务器进程延时执行: + 以下函数可用于延迟服务器进程的执行: pg_sleep ( double precision ) pg_sleep_for ( interval ) pg_sleep_until ( timestamp with time zone ) - pg_sleep使当前会话的进程休眠,直到过去给定的秒数。可以指定几分之一秒的延迟。 - pg_sleep_for是一个方便的函数,允许将睡眠时间指定为时间间隔。 - pg_sleep_until是一个方便的函数,用于需要特定的唤醒时间。例如: + pg_sleep使当前会话的进程休眠,直到经过指定的秒数。可以指定带小数部分的秒数作为延迟时间。 + pg_sleep_for是一个便捷函数,允许以interval指定休眠时间。 + pg_sleep_until是在需要指定唤醒时间时使用的便捷函数。例如: SELECT pg_sleep(1.5); @@ -9672,7 +9495,7 @@ SELECT pg_sleep_until('tomorrow 03:00'); 枚举支持函数 - 对于枚举类型(在中描述), 有一些函数允许更清洁的编码,而不需要为一个枚举类型硬写特定的值。它们被列在中。本例假定一个枚举类型被创建为: + 对于枚举类型(见),有些函数可以避免硬编码枚举类型中的特定值,使程序更简洁。这些函数列在中。以下示例假定枚举类型按如下方式创建: CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple'); @@ -9758,8 +9581,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple anyarray - 以一个数组返回在给定两个枚举值之间的范围。值必须来自相同的枚举类型。 - 如果第一个参数为空,其结果将从枚举类型的第一个值开始。如果第二参数为空,其结果将以枚举类型的最后一个值结束。 + 以有序数组返回两个给定枚举值之间的范围。两个值必须来自同一枚举类型。如果第一个参数为 null,结果从该枚举类型的第一个值开始;如果第二个参数为 null,结果以该枚举类型的最后一个值结束。 enum_range('orange'::rainbow, 'green'::rainbow) @@ -9779,8 +9601,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple - 请注意,除了双参数形式的enum_range外, 这些函数忽略传递给它们的具体值,它们只关心声明的数据类型。 - 空值或类型的一个特定值可以通过,并得到相同的结果。这些函数更多地被用于一个表列或函数参数,而不是一个硬写的类型名,如示例中所使用。 + 请注意,除了enum_range的双参数形式外,这些函数都忽略传入的具体值,只关心其声明的数据类型。传入 null 或该类型的某个具体值,结果都相同。通常会将这些函数用于表列或函数参数,而不是像示例那样使用硬编码的类型名。 @@ -9791,7 +9612,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple 几何类型pointboxlseglinepath、 - polygoncircle有一大堆本地支持函数和操作符,如中所示。 + polygoncircle有大量内置支持函数和操作符,如中所示。 @@ -9836,7 +9657,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple path - 连接两个打开的路径(如果其中一个路径是关闭的,则返回NULL)。 + 连接两个开放路径(如果任一路径是封闭的,则返回NULL)。 path '[(0,0),(1,1)]' + path '[(2,2),(3,3),(4,4)]' @@ -9865,12 +9686,12 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple geometric_type - 将第一个参数的每个点乘上第二个point(将点视为由实部和虚部表示的复数,并执行标准的复数乘法)。 + 将第一个参数的每个点乘上第二个point(将点视为由实部和虚部表示的复数,并执行标准的复数乘法)。 如果将第二个point解释为向量,这等价于将对象的大小和到原点的距离按向量的长度缩放,并以向量与x轴的夹角绕原点逆时针旋转。 - 适用于point, box,Rotating 用这些操作符“旋转”一个盒子,只会移动它的角点:这个盒子仍然被认为有平行于轴的边。 - 因此,盒子的大小并没有像真正的旋转那样得到保留。 - path, circle.。 + 适用于pointbox用这些操作符旋转一个矩形框,只会移动它的角点:这个矩形框仍然被认为有平行于轴的边。 + 因此,矩形框的大小并没有像真正的旋转那样得到保留。 + pathcircle path '((0,0),(1,0),(1,1))' * point '(3.0,0)' @@ -9889,7 +9710,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple 将第一个参数的每个点除以第二个point(将点视为由实部和虚部表示的复数,并执行标准的复数除法)。 - 如果将第二个point解释为向量,这等价于将物体的大小和到原点的距离按向量的长度向下缩放,并以向量与x轴的夹角围绕原点顺时针旋转。 + 如果将第二个point解释为向量,这等价于将对象的大小和到原点的距离按向量长度的倒数缩放,并以向量与x轴的夹角围绕原点顺时针旋转。 适用于 point, box, path,circle @@ -9966,7 +9787,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple box - 计算两个方框的交集,如果没有则为NULL。 + 计算两个矩形框的交集,如果没有则为NULL。 box '(2,2),(-1,-1)' # box '(1,1),(-2,-2)' @@ -9980,7 +9801,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple point - 计算第一个对象上距离第二个对象最近的点。 + 计算第二个对象上距离第一个对象最近的点。 可用于以下类型的配对: (point, box), (point, lseg), @@ -10002,7 +9823,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple 计算对象之间的距离。 - 对于所有七种几何类型,所有point与另一种几何类型的组合, + 适用于所有七种几何类型,所有point与另一种几何类型的组合, 以及以下这些额外的类型对: (box, lseg), (lseg, line), @@ -10042,7 +9863,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 第一个对象包含在第二个对象之中还是在第二个对象之上? 适用于这些类型对: + 第一个对象是否位于第二个对象内部或其上? 适用于这些类型对: (point, box), (point, lseg), (point, line), @@ -10142,7 +9963,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 第一个对象是否确定位于第二个对象下面? + 第一个对象是否严格位于第二个对象下面? 适用于 point, box, polygon, circle @@ -10157,7 +9978,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 第一个对象是否确定位于第二个对象上面? + 第一个对象是否严格位于第二个对象上面? 适用于 point, box, polygon, circle. @@ -10230,7 +10051,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 这些对象是否相交? 适用于这些类型对: + 这些对象是否相交? 适用于这些类型对: (box, box), (lseg, box), (lseg, lseg), @@ -10255,7 +10076,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 线是水平的? + 线是否水平? ?- lseg '[(-1,0),(1,0)]' @@ -10287,7 +10108,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 线是纵向的? + 线是否竖直? ?| lseg '[(-1,0),(1,0)]' @@ -10319,7 +10140,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 线是垂直的? + 两条线是否互相垂直? lseg '[(0,0),(0,1)]' ?-| lseg '[(0,0),(1,0)]' @@ -10337,7 +10158,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 线是平行的? + 两条线是否平行? lseg '[(-1,0),(1,0)]' ?|| lseg '[(-1,2),(1,2)]' @@ -10366,16 +10187,16 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple - 请注意same as操作符(~=),表示pointboxpolygoncircle类型的一般相等概念。 - 这些类型中的某些还有一个=操作符,但是=只比较相同的面积。 - 其它的标量比较操作符 (<=等等),在这些类型可用的地方,同样比较区域。 + 注意,相同操作符~=表示pointboxpolygoncircle类型通常意义上的相等。 + 某些几何类型还有=操作符,但=仅比较面积是否相等。 + 对于提供其他标量比较操作符(<=等)的类型,这些操作符同样比较面积。 - 在PostgreSQL14之前, 该点严格低于/高于比较操作符 point <<| pointpoint |>> point 分别被称为 <^>^。 + 在PostgreSQL14之前, 用于判断点是否严格位于另一点下方/上方的比较操作符 point <<| pointpoint |>> point 分别被称为 <^>^。 这些名字仍然可以使用,但是已被弃用并且最终将被移除。 @@ -10672,7 +10493,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple box - 计算内接于圆的方框。 + 计算内接于圆的矩形框。 box(circle '<(0,0),2>') @@ -10731,7 +10552,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple box - 计算两个方框的边界框。 + 计算两个矩形框的边界框。 bound_box(box '(1,1),(0,0)', box '(4,4),(3,3)') @@ -10748,7 +10569,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple circle - 计算包围方框的最小圆。 + 计算包围矩形框的最小圆。 circle(box '(1,1),(0,0)') @@ -10841,7 +10662,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple path - 将多边形转换为具有点的相同列表的封闭路径。 + 将多边形转换为具有相同点列表的封闭路径。 path(polygon '((0,0),(1,1),(2,0))') @@ -10949,7 +10770,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple polygon(circle '<(0,0),2>') - (-2,0,)&zwsp; (-1.73205080758774,0.9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999998999998989898989676868686887898999999999998989898989898999978987878787808070876888788989898989898989898989898989898989898989898968686868688768686887878989896868686889899999999999990000890000899900000000890000890000890000000000000000 + ((-2,0),&zwsp;(-1.7320508075688774,0.9999999999999999),&zwsp;(-1.0000000000000002,1.7320508075688772),&zwsp;(-1.2246063538223773e-16,2),&zwsp;(0.9999999999999996,1.7320508075688774),&zwsp;(1.732050807568877,1.0000000000000007),&zwsp;(2,2.4492127076447545e-16),&zwsp;(1.7320508075688776,-0.9999999999999994),&zwsp;(1.0000000000000009,-1.7320508075688767),&zwsp;(3.673819061467132e-16,-2),&zwsp;(-0.9999999999999987,-1.732050807568878),&zwsp;(-1.7320508075688767,-1.0000000000000009)) @@ -10963,7 +10784,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple polygon(4, circle '<(3,0),1>') - ((2,0,)&zwsp; (3,1,)&zwsp; (4,1.2246063538223773e-16), &zwsp; (3,-1)). + ((2,0),&zwsp;(3,1),&zwsp;(4,1.2246063538223773e-16),&zwsp;(3,-1)) @@ -10973,7 +10794,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple polygon - 将封闭路径转换为具有点的相同列表的多边形。 + 将封闭路径转换为具有相同点列表的多边形。 polygon(path '((0,0),(1,1),(2,0))') @@ -10986,7 +10807,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple
- 我们可以把一个point的两个组成数字当作具有索引 0 和 1 的数组访问。例如,如果t.p是一个point列,那么SELECT p[0] FROM t检索 X 坐标而 UPDATE t SET p[1] = ...改变 Y 坐标。同样,box或者lseg类型的值可以当作两个point值的数组值看待。 + 可以把一个point当作下标为 0 和 1 的数组,访问它的两个数值分量。例如,如果t.p是一个point列,那么SELECT p[0] FROM t检索 X 坐标而 UPDATE t SET p[1] = ...改变 Y 坐标。同样,box或者lseg类型的值可以当作两个point值组成的数组看待。 @@ -11002,8 +10823,8 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple 任何cidr 值都可以隐式地转换到inet;因此,下面在inet上操作的操作符和函数也可以在cidr值上工作。 - (对于inetcidr有单独的函数,这是因为这两种情况的行为应该是不同的。) - 此外,它允许将inet值转换为cidr。 + (如果inetcidr各有单独的函数,是因为这两种情况下的行为应当不同。) + 此外,也允许将inet值转换为cidr。 当这样做的时候,子网掩码右边的任何位都被静默地置零,以创建一个有效的cidr值。 @@ -11034,8 +10855,8 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean
- 子网是否严格包含在子网中?这个操作符和后续的四个操作符测试子网包含情况。 - 它们只考虑两个地址的网络部分(忽略网络掩码右侧的任何位),并确定一个网络与另一个网络相同或者是相同的子网。 + 子网是否严格包含在另一个子网中?这个操作符和后续四个操作符测试子网包含关系。 + 它们只考虑两个地址的网络部分(忽略网络掩码右侧的所有位),并判断一个网络是否与另一个网络相同,或是另一个网络的子网。 inet '192.168.1.5' << inet '192.168.1/24' @@ -11057,7 +10878,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 子网是否包含或等于子网? + 子网是否被包含于或等于子网? inet '192.168.1/24' <<= inet '192.168.1/24' @@ -11117,7 +10938,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple inet - 计算位 NOT. + 计算按位非。 ~ inet '192.168.1.6' @@ -11131,7 +10952,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple inet - 计算位 AND. + 计算按位与。 inet '192.168.1.6' & inet '0.0.0.255' @@ -11145,7 +10966,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple inet - 计算位 OR. + 计算按位或。 inet '192.168.1.6' | inet '0.0.0.255' @@ -11246,9 +11067,8 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple text - 创建缩写的文本显示格式。 - (结果与inet输出函数产生的结果相同;只有在与显式转换为text的结果相比时它才算是缩写形式, - 由于历史原因,它永远不会抑制子网掩码部分。) + 创建文本形式的缩写显示格式。 + (结果与inet输出函数产生的结果相同;只有与显式类型转换为text的结果相比时,才称为缩写形式。由于历史原因,后一种转换从不省略网络掩码部分。) abbrev(inet '10.1.0.0/32') @@ -11262,7 +11082,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple text - 创建缩写的文本显示格式。(缩写包括在子网掩码的右侧删除所有零字节;更多的示例请见 。) + 创建文本形式的缩写显示格式。(缩写形式会省略网络掩码右侧值为零的字节;更多示例见。) abbrev(cidr '10.1.0.0/16') @@ -11381,7 +11201,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple integer - 以比特位返回子网掩码长度。 + 返回子网掩码长度,以位为单位。 masklen(inet '192.168.1.5/24') @@ -11483,7 +11303,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple MAC地址类型, macaddrmacaddr8,支持中所示的常用比较操作符以及中所示的特殊函数。 - 此外,它们支持位元逻辑操作符~, &| (NOT, AND 和 OR),就像上面对IP地址所示的那样。 + 此外,它们支持按位逻辑操作符~&|(非、与和或),就像上面对IP地址所示的那样。 @@ -11547,7 +11367,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple macaddr8 - 将地址的第7位设置为1,创建所谓的modified EUI-64,用于包含在IPv6地址中。 + 将地址的第 7 位设置为 1,生成所谓的修订 EUI-64 格式,以便用于 IPv6 地址。 macaddr8_set7bit(macaddr8 '00:34:56:ab:cd:ef') @@ -11565,7 +11385,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple 文本搜索函数和操作符 - 全文搜索 + 全文检索 函数和操作符 @@ -11578,7 +11398,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple 以及 - 总结了为全文搜索提供的函数和操作符。PostgreSQL的文本搜索功能的详细解释可参考。 + 总结了为全文检索提供的函数和操作符。PostgreSQL的文本搜索功能的详细解释可参考
@@ -11658,11 +11478,11 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsvector - 连接两个tsvector。如果两个输入都包含词素位置,则相应地调整第二个输入的位置。 + 连接两个tsvector。如果两个输入都包含词位位置,则相应地调整第二个输入的位置。 'a:1 b:2'::tsvector || 'c:1 d:2 b:3'::tsvector - 'a':1'b':2,5'c':3'd':4 + 'a':1 'b':2,5 'c':3 'd':4 @@ -11700,7 +11520,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsquery - 否定tsquery,生成一个与输入查询不匹配的匹配文档的查询。 + 对tsquery取反,生成匹配那些不满足输入查询的文档的查询。 !! 'cat'::tsquery @@ -11714,7 +11534,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsquery - 构造一个短语查询,如果两个输入查询在连续的词素上匹配,该查询将进行匹配。 + 构造一个短语查询;当两个输入查询分别匹配相邻的词位时,该查询匹配。 to_tsquery('fat') <-> to_tsquery('rat') @@ -11728,7 +11548,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 第一个tsquery包含了第二个吗?(这只考虑出现在一个查询中的所有词素是否出现在另一个查询中,忽略了组合操作符。) + 第一个tsquery包含了第二个吗?(这只考虑出现在一个查询中的所有词位是否出现在另一个查询中,忽略了组合操作符。) 'cat'::tsquery @> 'cat & rat'::tsquery @@ -11742,7 +11562,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 第一个tsquery包含在第二个中吗?(这只考虑出现在一个查询中的所有词素是否出现在另一个查询中,而忽略了组合操作符。) + 第一个tsquery包含在第二个中吗?(这只考虑出现在一个查询中的所有词位是否出现在另一个查询中,而忽略了组合操作符。) 'cat'::tsquery <@ 'cat & rat'::tsquery @@ -11759,7 +11579,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple 除了这些专用操作符之外, 中所示的常用比较操作符也适用于tsvectortsquery类型。 - 它们对于文本搜索不是很有用,但是允许使用。例如,建在这些类型列上的唯一索引。 + 这些操作符对文本搜索用处不大,但可以用于其他用途,例如在这些类型的列上建立唯一索引。
@@ -11793,7 +11613,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple 将文本字符串数组转换为tsvector。 - 给定的字符串被直接用作词元,不经过进一步处理。数组元素不得为空字符串 + 给定的字符串被直接用作词位,不经过进一步处理。数组元素不得为空字符串 或NULL @@ -11864,8 +11684,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsquery - 将文本转换为tsquery,根据指定的或默认配置对单词进行标准化。 - 字符串中的任何标点符号都会被忽略(它不决定查询操作符)。结果查询匹配文本中包含所有非停止词的文档。 + 将文本转换为tsquery,根据指定的或默认配置对单词进行正规化。字符串中的任何标点符号都会被忽略(它们不决定查询操作符)。生成的查询匹配包含文本中所有非停用词的文档。 plainto_tsquery('english', 'The Fat Rats') @@ -11884,8 +11703,8 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsquery - 将文本转换为tsquery,根据指定的或默认配置对单词进行标准化。 - 字符串中的任何标点符号都会被忽略(它不决定查询操作符)。结果查询匹配包含文本中所有非停止词的短语。 + 将文本转换为tsquery,根据指定的或默认配置对单词进行正规化。 + 字符串中的任何标点符号都会被忽略(它不决定查询操作符)。结果查询匹配包含文本中所有非停用词的短语。 phraseto_tsquery('english', 'The Fat Rats') @@ -11908,8 +11727,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsquery - 将文本转换为tsquery,根据指定的或默认配置对单词进行标准化。引用的单词序列被转换为短语测试。 - or一词被理解为产生OR操作符,而破折号产生NOT操作符;其他标点符号被忽略。这类似于一些常见的网络搜索工具的行为。 + 将文本转换为tsquery,根据指定的或默认配置对单词进行正规化。带引号的单词序列被转换为短语测试。or一词产生 OR 操作符,短横线产生 NOT 操作符;其他标点符号会被忽略。这类似于一些常见网络搜索工具的行为。 websearch_to_tsquery('english', '"fat rat" or cat dog') @@ -11955,14 +11773,13 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple setweight - 为特定词元设置权重 + 为特定词位设置权重 setweight ( vector tsvector, weight "char", lexemes text[] ) tsvector - 为vector中列出的lexemes赋予指定的weight。 - lexemes中的字符串被视为词元,不经过进一步处理。不匹配vector中任何词元的字符串将被忽略。 + 为vector中列在lexemes内的元素赋予指定的weightlexemes中的字符串按原样用作词位,不经过进一步处理。不匹配vector中任何词位的字符串将被忽略。 setweight('fat:2,4 cat:3 rat:5,6B'::tsvector, 'A', '{cat,rat}') @@ -11998,7 +11815,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsquery - 将文本转换为tsquery,根据指定的或默认配置对单词进行标准化。单词必须由有效的tsquery操作符组合。 + 将文本转换为tsquery,根据指定的或默认配置对单词进行正规化。单词必须由有效的tsquery操作符组合。 to_tsquery('english', 'The & Fat & Rats') @@ -12017,7 +11834,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsvector - 将文本转换为tsvector,根据指定的或默认配置对单词进行标准化。结果中包含位置信息。 + 将文本转换为tsvector,根据指定的或默认配置对单词进行正规化。结果中包含位置信息。 to_tsvector('english', 'The Fat Rats') @@ -12039,9 +11856,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsvector - 将JSON文档中的每个字符串值转换为tsvector,根据指定的或默认配置对单词进行标准化。 - 然后将结果按文档顺序连接起来以产生输出。位置信息就像在每对字符串值之间存在一个停止词一样生成。 - (注意,当输入为jsonb时,JSON对象的字段的document order取决于实现;请观察这些示例中的差异。) + 将 JSON 文档中的每个字符串值转换为tsvector,根据指定的或默认配置对单词进行正规化。然后将结果按文档顺序连接起来以产生输出。生成位置信息时,视为每对字符串值之间存在一个停用词。(注意,当输入为jsonb时,JSON 对象字段的文档顺序取决于具体实现;请注意这些示例中的差异。) to_tsvector('english', '{"aa": "The Fat Rats", "b": "dog"}'::json) @@ -12075,15 +11890,15 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsvector - 选择filter请求的JSON文档中的每个项,并将每个项转换为tsvector,根据指定的或默认配置对单词进行标准化。 - 然后将结果按文档顺序连接起来以产生输出。位置信息就像在每对选定的项目之间存在一个停止词一样生成。 - (注意,当输入为jsonb时,JSON对象字段的document order取决于实现。) - filter必须是一个jsonb数组,其中包含0个或多个关键字: + 选择filter请求的JSON文档中的每个项,并将每个项转换为tsvector,根据指定的或默认配置对单词进行正规化。 + 然后将结果按文档顺序连接起来以产生输出。位置信息就像在每对选定的项目之间存在一个停用词一样生成。 + (注意,当输入为jsonb时,JSON对象字段的文档顺序取决于实现。) + filter必须是一个jsonb数组,其中包含0个或多个关键字: "string"(包括所有字符串值), "numeric"(包括所有数值), "boolean"(包括所有布尔值), "key"(包括所有键),或 - "all"(包括以上所有关键字)。 + "all"(包括以上所有内容)。 作为一种特殊情况,该filter也可以是这些关键字之一的简单JSON值。 @@ -12105,8 +11920,8 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsvector - 从vector中删除给定的lexeme的任何出现。 - lexeme字符串被视为原样的词元,不经过进一步处理。 + 从vector中删除给定的lexeme的所有出现。 + lexeme字符串被视为原样的词位,不经过进一步处理。 ts_delete('fat:2,4 cat:3 rat:5A'::tsvector, 'fat') @@ -12120,9 +11935,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsvector - 从vector中删除lexemes中的任何出现。 - lexemes中的字符串被视为词元,不经过进一步处理。 - 不匹配vector中任何词元的字符串将被忽略。 + 从vector中删除lexemes所列词位的所有出现。lexemes中的字符串按原样用作词位,不经过进一步处理。不匹配vector中任何词位的字符串将被忽略。 ts_delete('fat:2,4 cat:3 rat:5A'::tsvector, ARRAY['fat','rat']) @@ -12160,9 +11973,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple text - 以缩写形式显示documentquery的匹配项,该匹配项必须是原始文本,而不是tsvector。 - 在匹配查询之前,文档中的单词将根据指定的或默认的配置进行规范化。 - 中讨论了该函数的使用,还描述了可用的options。 + 以缩略形式显示querydocument中的匹配项;后者必须是原始文本,不能是tsvector。在匹配查询之前,文档中的单词将根据指定的或默认配置进行正规化。中讨论了该函数的使用,还描述了可用的options ts_headline('The fat cat ate the rat.', 'cat') @@ -12188,8 +11999,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple text - 以缩写形式显示匹配JSONdocument中字符串值中的query。 - 更多细节请参阅 。 + 以缩略形式显示query在 JSON document字符串值中的匹配项。更多细节请参见 ts_headline('{"cat":"raining cats and dogs"}'::jsonb, 'cat') @@ -12267,8 +12077,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsquery - 根据目标替换部分query,并替换通过执行SELECT命令获得的查询。 - 详情参见。 + 根据执行SELECT命令得到的目标和替换项,替换query中的相应部分。详情参见 SELECT ts_rewrite('a & b'::tsquery, 'SELECT t,s FROM aliases') @@ -12299,7 +12108,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsquery - 构造一个短语查询,用于搜索query1query2的匹配项,这些匹配项恰好出现在distance词位之间。 + 构造一个短语查询,用于搜索query1query2的匹配项,其匹配位置恰好相距distance个词位。 tsquery_phrase(to_tsquery('fat'), to_tsquery('cat'), 10) @@ -12328,7 +12137,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple unnest - for tsvector + 用于 tsvector unnest ( tsvector ) setof record @@ -12358,7 +12167,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple - 所有接受一个可选的regconfig参数的文本搜索函数在该参数被忽略时,使用由指定的配置。 + 所有接受一个可选的regconfig参数的文本搜索函数在省略该参数时,会使用由指定的配置。 @@ -12405,7 +12214,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple lexemes text[] ) - 根据指定的或默认的文本搜索配置从document中提取和标准化标记,并返回关于每个标记是如何处理的信息。 + 根据指定的或默认的文本搜索配置从document中提取和正规化词元,并返回关于每个词元是如何处理的信息。 详情参见 @@ -12423,8 +12232,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple text[] - 如果字典知道输入标记,则返回替换词位数组;如果字典知道标记,但它是停止词,则返回空数组;如果它不是已知词,则返回NULL。 - 详情参见。 + 如果词典识别输入词元,则返回由替换词位组成的数组;如果词典识别该词元,但它是停用词,则返回空数组;如果词典无法识别该词元,则返回NULL。详情参见 ts_lexize('english_stem', 'stars') @@ -12444,7 +12252,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple token text ) - 使用命名的解析器从document中提取标记。详情参见。 + 使用指定名称的解析器从document中提取词元。详情参见 ts_parse('default', 'foo - bar') @@ -12461,7 +12269,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple token text ) - 使用 OID 指定的解析器从document中提取标记。 + 使用 OID 指定的解析器从document中提取词元。 详情参见 @@ -12482,7 +12290,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple description text ) - 返回一个表,该表描述命名解析器可以识别的每种类型的标记。详情参见。 + 返回一个表,该表描述指定名称的解析器可以识别的每种类型的词元。详情参见 ts_token_type('default') @@ -12499,7 +12307,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple description text ) - 返回一个表,该表描述 OID 指定的解析器可以识别的每种标记类型。详情参见。 + 返回一个表,该表描述 OID 指定的解析器可以识别的每种词元类型。详情参见 ts_token_type(3722) @@ -12520,7 +12328,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple nentry integer ) - 执行sqlquery,该查询必须返回单个tsvector列,并返回数据中每个不同词元的统计信息。 + 执行sqlquery,该查询必须返回单个tsvector列,并返回数据中每个不同词位的统计信息。 详情参见 @@ -12535,7 +12343,6 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple - UUID 函数 @@ -12548,20 +12355,16 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple - PostgreSQL 提供一个用于生成 UUID 的函数: + PostgreSQL包含一个生成 UUID 的函数: gen_random_uuid () uuid - 该函数返回一个版本 4(随机)的 UUID。这是最常用的 UUID 类型,适用于大多数应用。 - + 该函数返回版本 4(随机)UUID。这是最常用的 UUID 类型,适用于大多数应用。 - - 模块还提供实现其他标准 UUID 生成算法的附加函数。 - + 模块还提供了额外的函数,用于实现其他标准 UUID 生成算法。 - PostgreSQL 还为 UUID 提供了 - 中展示的常用比较操作符。 + PostgreSQL也为 UUID 提供了中展示的常用比较操作符。 @@ -12999,7 +12802,7 @@ SELECT xmlexists('//town[text() = ''Toronto'']' PASSING BY VALUE 'T - 示例: + 示例: - 示例: + 示例: test', ARRAY[ARRAY['my', 'http://example.com']]); @@ -13116,7 +12919,7 @@ SELECT xpath('//mydefns:b/text()', 'test - 示例: + 示例: test', ARRAY[ARRAY['my', 'http://example.com']]); @@ -13169,7 +12972,7 @@ SELECT xpath_exists('/my:a/text()', 'test document_expressionrow_expression提供上下文项。 - 它必须是一个格式良好的 XML 文档;不接受内容片段或森林。BY REFBY VALUE子句会被接受,但会被忽略,如中所述。 + 它必须是一个良构的 XML 文档;不接受内容片段或森林。BY REFBY VALUE子句会被接受,但会被忽略,如中所述。 @@ -13218,7 +13021,7 @@ SELECT xpath_exists('/my:a/text()', 'test - XML 元素的字符串值,是该元素及其后代中所有文本节点的字符串值按文档顺序连接后的结果。没有后代文本节点的元素,其字符串值为空字符串(而不是NULL)。任何xsi:nil属性都会被忽略。请注意,两个非文本元素之间仅包含空白的text()节点会被保留,而text()节点上的前导空白也不会被折叠。关于其他 XML 节点类型以及非 XML 值的字符串值定义规则,可参阅 XPath 1.0 中的string函数。 + 一个 XML 元素的字符串值,是该元素及其所有后代中包含的文本节点按文档顺序拼接而成的字符串。没有后代文本节点的元素,其字符串值为空字符串(不是 NULL)。所有 xsi:nil 属性都会被忽略。注意,两个非文本元素之间仅含空白的 text() 节点会被保留,text() 节点的前导空白也不会被折叠。其他 XML 节点类型及非 XML 值的字符串值定义规则,可参考 XPath 1.0 的 string 函数。 @@ -13238,7 +13041,7 @@ SELECT xpath_exists('/my:a/text()', 'test - 示例: + 示例: - 下面的示例展示了多个text()节点的连接,列名作为XPath过滤器的使用,以及对空格、XML注释和处理指令的处理: + 下面的示例展示了多个text()节点的连接,列名作为XPath过滤器的使用,以及对空格、XML注释和处理指令的处理: JSON 函数和操作符 + + SQL/JSON + 函数和表达式 + - 本节描述: + 本节描述: @@ -13574,14 +13381,45 @@ table2-mapping - SQL/JSON路径语言 + SQL/JSON 路径语言 - 要了解有关SQL/JSON标准的更多信息,请参阅。有关PostgreSQL中支持的JSON类型的详细信息,见 。 + 为了在 SQL 环境中为 JSON 数据类型提供原生支持,PostgreSQL 实现了 + SQL/JSON 数据模型。该模型由项序列组成。每个项可以保存 SQL 标量值, + 以及额外的 SQL/JSON null 值,还可以保存使用 JSON 数组和对象的复合数据结构。该模型是 JSON 规范 + RFC 7159 中隐含数据模型的形式化表示。 + + + + SQL/JSON 允许你将 JSON 数据与常规 SQL 数据一同处理,并提供事务支持,包括: + + + + + 将 JSON 数据上传到数据库,并将其作为字符或二进制字符串存储在常规 SQL 列中。 + + + + + 从关系数据生成 JSON 对象和数组。 + + + + + 使用 SQL/JSON 查询函数和 SQL/JSON 路径语言表达式查询 JSON 数据。 + + + + + + + 要了解有关 SQL/JSON 标准的更多信息,请参阅。有关 + PostgreSQL 中支持的 JSON 类型的详细信息,见 + @@ -13736,14 +13574,13 @@ table2-mapping - 如果JSON输入没有匹配请求的正确结构,字段/元素/路径提取操作符返回NULL,而不是失败;例如,如果不存在这样的键或数组元素。 + 如果 JSON 输入没有匹配请求的正确结构,字段/元素/路径提取操作符会返回 NULL,而不是失败;例如,如果不存在这样的键或数组元素。 - 还有一些操作符仅适用于jsonb,如表所示。 - 第描述了如何使用这些操作符来有效地搜索索引的jsonb数据。 - + 还有一些操作符仅适用于jsonb,如所示。介绍了如何使用这些操作符有效地搜索已建立索引的jsonb数据。 +
@@ -13818,7 +13655,7 @@ table2-mapping boolean - 文本数组中的字符串是否作为顶级键或数组元素存在? + 文本数组中的任一字符串是否作为顶级键或数组元素存在? '{"a":1, "b":2, "c":3}'::jsonb ?| array['b', 'd'] @@ -13850,7 +13687,7 @@ table2-mapping 连接两个数组将生成一个包含每个输入的所有元素的数组。 连接两个对象将生成一个包含它们键的并集的对象,当存在重复的键时取第二个对象的值。 所有其他情况都通过将非数组输入转换为单元素数组来处理,然后按照两个数组的方式进行处理。 - 不递归操作:只有顶级数组或对象结构被合并。 + 不递归操作:只有顶级数组或对象结构会被合并。 '["a", "b"]'::jsonb || '["a", "d"]'::jsonb @@ -13869,7 +13706,7 @@ table2-mapping [{"a": "b"}, 42] - 要将一个数组作为单个条目附加到另一个数组中,请将其包装在另一个数组附加层中,例如: + 要将一个数组作为单个元素追加到另一个数组中,请先在它外面再包装一层数组,例如: '[1, 2]'::jsonb || jsonb_build_array('[3, 4]'::jsonb) @@ -13971,15 +13808,13 @@ table2-mapping - jsonpath操作符@?@@抑制以下错误:缺少对象字段或数组元素,意外的JSON项目类型,日期时间和数字错误。 - 还可以告诉以下描述的与jsonpath相关的函数来抑制这些类型的错误。 - 在搜索不同结构的JSON文档集合时,此行为可能会有所帮助。 + jsonpath操作符@?@@会抑制以下错误:缺少对象字段或数组元素、JSON 项类型不符合预期,以及日期时间和数值错误。下文介绍的jsonpath相关函数也可以设置为抑制这些类型的错误。在搜索结构各异的 JSON 文档集合时,这一行为可能很有用。 - 显示可用于构造jsonjsonb值的函数。 - + 列出了可用于构造jsonjsonb值的函数。表中的某些函数具有RETURNING子句,用于指定返回的数据类型。该类型必须是jsonjsonbbytea、字符串类型(textcharvarchar),或者可以转换为json的类型。默认返回json类型。 +
@@ -14018,14 +13853,14 @@ table2-mapping jsonb - 将任何SQL值转换为jsonjsonb。数组和组合递归地转换为数组和对象(多维数组在JSON中变成数组的数组)。 - 否则,如果存在从SQL数据类型到json的类型转换,则类型转换函数将用于执行转换; + 将任何SQL值转换为jsonjsonb。数组和复合值递归地转换为数组和对象(多维数组在JSON中变成数组的数组)。 + 否则,如果存在从SQL数据类型到json的类型转换,则类型转换函数将用于执行转换; - 例如,扩展有一个从hstorejson的转换,这样通过json创建函数转换的hstore值将被表示为json对象,而不是原始字符串值 + 例如,扩展有一个从hstorejson的类型转换,因此通过 JSON 创建函数转换的hstore值将表示为 JSON 对象,而不是基本的字符串值。 - 否则,将生成一个标量json值。对于除数字、布尔值或空值之外的任何标量,将使用文本表示,并根据需要进行转义,使其成为有效的JSON字符串值。 + 否则,将生成一个标量 JSON 值。对于除数字、布尔值或空值之外的任何标量,将使用文本表示,并根据需要进行转义,使其成为有效的JSON字符串值。 to_json('Fred said "Hi."'::text) @@ -14033,7 +13868,7 @@ table2-mapping to_jsonb(row(42, 'Fred said "Hi."'::text)) - {"f1":42,"f2":"Fred said \"Hi.\""} + {"f1": 42, "f2": "Fred said \"Hi.\""} @@ -14054,6 +13889,39 @@ table2-mapping + + + + json_array + json_array ( + { value_expression FORMAT JSON } , ... + { NULL | ABSENT } ON NULL + RETURNING data_type FORMAT JSON ENCODING UTF8 ) + + + json_array ( + query_expression + RETURNING data_type FORMAT JSON ENCODING UTF8 ) + + + 从一系列value_expression参数或query_expression的结果构造 JSON 数组;后者必须是返回单列的 SELECT 查询。如果指定了ABSENT ON NULL,则忽略 NULL 值。使用query_expression时始终如此。 + + + json_array(1,true,json '{"a":null}') + [1, true, {"a":null}] + + + json_array(SELECT * FROM (VALUES(1),(2)) t) + [1, 2] + + + @@ -14063,7 +13931,7 @@ table2-mapping json - 将SQL组合值转换为JSON对象。该行为与to_json相同,只是如果可选boolean参数为真,换行符将在顶级元素之间添加。 + 将SQL 复合值转换为JSON对象。该行为与to_json相同,只是如果可选boolean参数为真,换行符将在顶级元素之间添加。 row_to_json(row(1,'foo')) @@ -14112,7 +13980,7 @@ table2-mapping 根据可变参数列表构建一个JSON对象。按照惯例,参数列表由交替的键和值组成。 - 关键参数强制转换为文本;值参数按照to_jsonto_jsonb进行转换。 + 键参数会被强制转换为文本;值参数则按照to_jsonto_jsonb进行转换。 json_build_object('foo', 1, 2, row(3,'bar')) @@ -14120,6 +13988,25 @@ table2-mapping + + + json_object + json_object ( + { key_expression { VALUE | ':' } + value_expression FORMAT JSON ENCODING UTF8 }, ... + { NULL | ABSENT } ON NULL + { WITH | WITHOUT } UNIQUE KEYS + RETURNING data_type FORMAT JSON ENCODING UTF8 ) + + + 根据给定的所有键值对构造 JSON 对象;如果没有给出键值对,则构造空对象。key_expression是定义JSON键的标量表达式,会被转换为text类型。它不能为NULL,其类型也不能具有到json的类型转换。如果指定了WITH UNIQUE KEYS,则key_expression不能重复。如果指定了ABSENT ON NULL,则value_expression求值为NULL的键值对会从输出中省略;如果指定了NULL ON NULL或省略了该子句,则保留该键,并将其值设为NULL。 + + + json_object('code' VALUE 'P123', 'title': 'Jaws') + {"code" : "P123", "title" : "Jaws"} + + + @@ -14136,8 +14023,7 @@ table2-mapping jsonb - 从文本数组构建JSON对象。该数组必须有两个维度,一个维度的成员数为偶数,在这种情况下,它们被视为交替的键/值对; - 另一个维度的成员数为二维,每个内部数组恰好有两个元素,它们被视为键/值对。所有值都转换为JSON字符串。 + 从文本数组构造 JSON 对象。该数组必须是一维且包含偶数个成员,此时将成员按交替的键/值对处理;或者是二维数组,且每个内部数组恰好有两个元素,将这两个元素作为一个键/值对。所有值都转换为 JSON 字符串。 json_object('{a, 1, b, "def", c, 3.5}') @@ -14158,7 +14044,7 @@ table2-mapping jsonb - 这种形式的json_object从单独的文本数组中成对地获取键和值。否则,它与单参数形式相同。 + 这种形式的json_object从单独的文本数组中成对地获取键和值。除此之外,它与单参数形式相同。 json_object('{a,b}', '{1,2}') @@ -14169,6 +14055,81 @@ table2-mapping
+ + 详细介绍了用于测试 JSON 的 SQL/JSON 功能。 + + + + SQL/JSON 测试函数 + + + + + 函数签名 + + + 描述 + + + 示例 + + + + + + + IS JSON + expression IS NOT JSON + { VALUE | SCALAR | ARRAY | OBJECT } + { WITH | WITHOUT } UNIQUE KEYS + + + 该谓词测试 expression 是否可以解析为 JSON,也可以指定具体类型。 + 如果指定 SCALARARRAYOBJECT, + 则测试 JSON 是否属于该特定类型。如果指定 WITH UNIQUE KEYS, + 则 expression 中的任意对象还会被检查是否存在重复键。 + + + +SELECT js, + js IS JSON "json?", + js IS JSON SCALAR "scalar?", + js IS JSON OBJECT "object?", + js IS JSON ARRAY "array?" +FROM (VALUES + ('123'), ('"abc"'), ('{"a": "b"}'), ('[1,2]'),('abc')) foo(js); + js | json? | scalar? | object? | array? +------------+-------+---------+---------+-------- + 123 | t | t | f | f + "abc" | t | t | f | f + {"a": "b"} | t | f | t | f + [1,2] | t | f | f | t + abc | f | f | f | f + + + + +SELECT js, + js IS JSON OBJECT "object?", + js IS JSON ARRAY "array?", + js IS JSON ARRAY WITH UNIQUE KEYS "array w. UK?", + js IS JSON ARRAY WITHOUT UNIQUE KEYS "array w/o UK?" +FROM (VALUES ('[{"a":"1"}, + {"b":"2","b":"3"}]')) foo(js); +-[ RECORD 1 ]-+-------------------- +js | [{"a":"1"}, + + | {"b":"2","b":"3"}] +object? | f +array? | t +array w. UK? | f +array w/o UK? | t + + + + + +
+ 显示可用于处理jsonjsonb值的函数。 @@ -14520,8 +14481,7 @@ table2-mapping setof anyelement
- 将对象的顶级 JSON 数组展开为一组具有 base 参数复合类型的行。 - 对于json[b]_populate_record,将如上所述处理JSON数组的每个元素。 + 将由对象组成的顶级 JSON 数组展开为一组行,其复合类型与base参数相同。JSON 数组中的每个元素都按照上文对json[b]_populate_record的说明进行处理。 create type twoints as (a int, b int); @@ -14590,8 +14550,8 @@ table2-mapping 将顶级JSON对象数组展开为一组由AS子句定义的复合类型的行。 - (与所有返回record的函数一样,调用查询必须使用AS子句显式定义记录的结构。) - 对于json[b]_populate_record,将如上所述处理JSON数组的每个元素。 + (与所有返回record的函数一样,调用查询必须使用AS子句显式定义记录的结构。) + JSON 数组中的每个元素都按照上文对json[b]_populate_record的说明进行处理。 select * from json_to_recordset('[{"a":1,"b":"foo"}, {"a":"2","c":"bar"}]') as x(a int, b text) @@ -14617,7 +14577,7 @@ table2-mapping 返回target,将path指定的项替换为new_value, 如果create_if_missing为真(此为默认值)并且path指定的项不存在,则添加new_value。 路径中的所有前面步骤都必须存在,否则将不加改变地返回target。 - 与面向路径操作符一样,负整数出现在JSON数组末尾的path计数中。 + 与面向路径的操作符一样,path中的负整数从 JSON 数组末尾计数。 如果最后一个路径步骤是超出范围的数组索引,并且create_if_missing为真,那么如果索引为负,新值将添加到数组的开头,如果索引为正,则添加到数组的结尾。 @@ -14664,8 +14624,8 @@ table2-mapping 如果path指派的项是一个数组元素,如果 insert_after为假(此为默认值),则new_value将被插入到该项之前,如果 insert_after为真则在该项之后。 如果由path指派的项是一个对象字段,则只在对象不包含该键时才插入 new_value。 路径中的所有前面步骤都必须存在,否则将不加改变地返回target。 - 与面向路径操作符一样,负整数出现在JSON数组末尾的 path计数中。 - 如果最后一个路径步骤是超出范围的数组下标,则如果下标为负,则将新值添加到数组的开头;如果下标为正,则将新值添加到数组的结尾。 + 与面向路径的操作符一样,path中的负整数从 JSON 数组末尾计数。 + 如果最后一个路径步骤是超出范围的数组下标,那么当下标为负时,新值会被添加到数组开头;当下标为正时,新值会被添加到数组末尾。 jsonb_insert('{"a": [0,1,2]}', '{a, 1}', '"new_value"') @@ -14682,26 +14642,20 @@ table2-mapping json_strip_nulls - json_strip_nulls ( target json ,strip_in_arrays boolean ) + json_strip_nulls ( json ) json jsonb_strip_nulls - jsonb_strip_nulls ( target jsonb ,strip_in_arrays boolean ) + jsonb_strip_nulls ( jsonb ) jsonb - - 递归地删除给定 JSON 值中所有值为 null 的对象字段。如果strip_in_arrays为 true(默认值为 false),那么数组中的 null 元素也会被删除;否则不会删除。不是对象字段值的裸露 null 值永远不会被删除。 - + 递归删除给定 JSON 值中所有值为 null 的对象字段。不是对象字段的 null 值保持不变。 json_strip_nulls('[{"f1":1, "f2":null}, 2, null, 3]') [{"f1":1},2,null,3] - - - jsonb_strip_nulls('[1,2,null,3,4]', true) - [1,2,3,4] @@ -14714,7 +14668,7 @@ table2-mapping boolean
- 检查JSON路径是否返回指定JSON值的任何项。如果指定了vars参数,则它必须是一个JSON对象,并且它的字段提供要替换到jsonpath表达式中的名称值。 + 检查JSON路径是否返回指定JSON值的任何项。如果指定了vars参数,则它必须是一个JSON对象,并且它的字段提供要替换到jsonpath表达式中的具名值。 如果指定了silent参数并为true,函数会抑制与@?@@操作符相同的错误。 @@ -14856,7 +14810,7 @@ table2-mapping text - 将给定的JSON值转换为精美打印的,缩进的文本。 + 将给定的 JSON 值转换为经过美化并带有缩进的文本。 jsonb_pretty('[{"f1":1,"f2":null}, 2]') @@ -14889,8 +14843,8 @@ table2-mapping text - 以文本字符串形式返回顶级JSON值的类型。可能的类型有object, array,string, number,boolean, 和 null。 - (null的结果不应该与SQL NULL 混淆;参见示例。) + 以文本字符串形式返回顶级JSON值的类型。可能的类型有objectarraystringnumberbooleannull。 + (null 的结果不应与 SQL NULL 混淆;参见示例。) json_typeof('-123.4') @@ -14909,79 +14863,9 @@ table2-mapping - - 介绍了用于测试 JSON 的 SQL/JSON 功能。 - - - SQL/JSON 测试函数 - - - - - 函数签名 - - - 说明 - - - 示例 - - - - - - - IS JSON - expression IS NOT JSON - { VALUE | SCALAR | ARRAY | OBJECT } - { WITH | WITHOUT } UNIQUE KEYS - - - 这个谓词测试 expression 是否可以解析为 JSON,也可以测试其是否为指定类型。 - 如果指定了 SCALARARRAYOBJECT,则会检查 JSON 是否属于对应类型。 - 如果指定了 WITH UNIQUE KEYS,则还会检查 expression 中的任意对象是否包含重复键。 - - - -SELECT js, - js IS JSON "json?", - js IS JSON SCALAR "scalar?", - js IS JSON OBJECT "object?", - js IS JSON ARRAY "array?" -FROM (VALUES - ('123'), ('"abc"'), ('{"a": "b"}'), ('[1,2]'),('abc')) foo(js); - js | json? | scalar? | object? | array? -------------+-------+---------+---------+-------- - 123 | t | t | f | f - "abc" | t | t | f | f - {"a": "b"} | t | f | t | f - [1,2] | t | f | f | t - abc | f | f | f | f - - - - -SELECT js, - js IS JSON OBJECT "object?", - js IS JSON ARRAY "array?", - js IS JSON ARRAY WITH UNIQUE KEYS "array w. UK?", - js IS JSON ARRAY WITHOUT UNIQUE KEYS "array w/o UK?" -FROM (VALUES ('[{"a":"1"}, - {"b":"2","b":"3"}]')) foo(js); --[ RECORD 1 ]-+-------------------- -js | [{"a":"1"}, + - | {"b":"2","b":"3"}] -object? | f -array? | t -array w. UK? | f -array w/o UK? | t - - - - - -
+ + @@ -15009,13 +14893,11 @@ array w/o UK? | t
- 要引用正在查询的JSON值(context item项),在路径表达式中使用$变量。 - 它后面可以跟着一个或多个accessor operators,这些操作符在JSON结构中逐级向下检索上下文项的子项。 - 后面的每个操作符处理前一个求值步骤的结果。 - + 要引用正在查询的 JSON 值(上下文项),请在路径表达式中使用$变量。它后面可以跟一个或多个访问操作符,沿 JSON 结构逐层向下获取上下文项的子项。每个后续操作符都处理上一步求值的结果。 +
- 例如,假设你有一些你想要解析的来自GPS跟踪器的JSON数据,例如: + 例如,假设你有一些你想要解析的来自GPS跟踪器的JSON数据,例如: { "track": { @@ -15036,50 +14918,38 @@ array w/o UK? | t - - 为了检索可用的轨迹段,你需要使用.key访问操作符来向下浏览周边的JSON对象: - + 要获取可用的轨迹片段,需要使用.key访问操作符,逐层访问外围的 JSON 对象: $.track.segments - 要检索数组的内容,通常使用[*]操作符。例如,下面的路径将返回所有可用轨道段的位置坐标: + 要检索数组的内容,通常使用[*]操作符。例如,下面的路径将返回所有可用轨迹段的位置坐标: $.track.segments[*].location - - 要只返回第一个段的坐标,可以在[]访问操作符中指定相应的下标。重新调用相对于0的JSON数组索引: - + 要仅返回第一个片段的坐标,可以在[]访问操作符中指定相应下标。注意,JSON 数组下标从 0 开始: $.track.segments[0].location - - 每个路径求值步骤的结果可以由中列出的一个或多个jsonpath操作符和方法来处理。 - 每个方法名之前必须有一个点。例如,你可以得到一个数组的大小: - + 每一步路径求值的结果都可以使用一个或多个jsonpath操作符和方法处理,它们列于。每个方法名之前都必须有一个点。例如,可以获取数组的大小: $.track.segments.size() - - 在路径表达式中使用jsonpath操作符和方法的更多示例见下面。 +有关在路径表达式中使用jsonpath操作符和方法的更多示例,见下文 - - 在定义路径时,还可以使用一个或多个与SQL中的WHERE子句类似的filter expressions。 - 过滤器表达式以问号开头,并在圆括号中提供条件: - - + 定义路径时,还可以使用一个或多个过滤表达式,其作用类似于 SQL 中的WHERE子句。过滤表达式以问号开头,并在圆括号中提供条件: ? (condition) - 过滤表达式必须在它们应该应用的路径求值步骤之后写入。该步骤的结果将被筛选,以只包括满足所提供条件的那些项。 + 过滤表达式必须在它们应该应用的路径求值步骤之后指定。该步骤的结果会经过过滤,只保留满足给定条件的项。 SQL/JSON定义了三值逻辑,因此条件可以是 true, false,或 unknownunknown值发挥与SQL NULL相同的角色,可以使用is unknown谓词进行测试。 - 进一步的路径求值步骤只使用筛选器表达式返回true的那些项。 + 进一步的路径求值步骤只使用过滤表达式返回true的那些项。 @@ -15087,153 +14957,104 @@ $.track.segments.size() 在一个过滤表达式中,@变量表示被过滤的值(也就是说,前面路径步骤的一个结果)。你可以在 @后面写访问操作符来检索组件项。 - - 例如,假设你想要检索所有高于130的心率值。你可以使用下面的表达式来实现这一点: - + 例如,假设你想检索所有高于 130 的心率值。可以用下面的表达式实现: $.track.segments[*].HR ? (@ > 130) - - 为了获得具有这些值的片段的开始时间,必须在返回开始时间之前过滤掉不相关的片段,所以过滤表达式应用于上一步,条件中使用的路径不同: - + 为了获得具有这些值的轨迹段的开始时间,必须先过滤掉不相关的轨迹段,再返回开始时间。因此,过滤表达式应用于上一步,条件中使用的路径也不同: $.track.segments[*] ? (@.HR > 130)."start time" - - 如果需要,可以按顺序使用几个过滤器表达式。例如,下面的表达式选择所有包含有相关坐标和高心率值的位置的段的开始时间: - + 如有需要,可以依次使用多个过滤表达式。例如,下面的表达式选择位置坐标符合要求且心率较高的所有轨迹段的开始时间: $.track.segments[*] ? (@.location[1] < 13.4) ? (@.HR > 130)."start time" - - 也允许在不同嵌套层级中使用过滤器表达式。下面的示例首先根据位置筛选所有的片段,然后返回这些片段的高心率值,如果适用的话: - + 也可以在不同嵌套层级使用过滤表达式。下面的示例先按位置筛选所有轨迹段,再返回这些轨迹段中的高心率值(如果存在): $.track.segments[*] ? (@.location[1] < 13.4).HR ? (@ > 130) - - - - 你也可以在彼此之间嵌套过滤器表达式: - -$.track ? (exists(@.segments[*] ? (@.HR > 130))).segments.size() - - 如果包含任何具有高心率值的片段,则该表达式返回曲目的大小,否则返回空序列。 - - - - 与 SQL 标准的偏差 - - - PostgreSQL 对 SQL/JSON 路径语言的实现与 SQL/JSON 标准有以下偏差。 - - - - 布尔谓词检查表达式 - - 作为对 SQL 标准的扩展,PostgreSQL 的路径表达式可以是布尔谓词,而 SQL 标准只允许在过滤器内部使用谓词。SQL 标准路径表达式返回被查询 JSON 值中的相关元素,而谓词检查表达式返回该谓词的单个三值 jsonb 结果:truefalsenull。例如,下面是一个符合 SQL 标准的过滤表达式: - -=> select jsonb_path_query(:'json', '$.track.segments ?(@[*].HR > 130)'); - jsonb_path_query ------------------------------------------------------------&zwsp;---------------------- - {"HR": 135, "location": [47.706, 13.2635], "start time": "2018-10-14 10:39:21"} - - 类似的谓词检查表达式则会直接返回 true,表示存在匹配项: - -=> select jsonb_path_query(:'json', '$.track.segments[*].HR > 130'); - jsonb_path_query ------------------- - true - - + - - - 谓词检查表达式是 @@ 操作符(以及 jsonb_path_match 函数)所必需的,不应与 @? 操作符(或 jsonb_path_exists 函数)一起使用。 - - - + 还可以将过滤表达式相互嵌套: +$.track ? (exists(@.segments[*] ? (@.HR > 130))).segments.size() +如果轨迹包含任何具有高心率值的轨迹段,该表达式返回轨迹的大小,否则返回空序列。 + + PostgreSQL 对 SQL/JSON 路径语言的实现与 SQL/JSON 标准有以下偏差: + + + + + 路径表达式可以是布尔谓词,尽管 SQL/JSON 标准只允许在过滤器中使用谓词。 + 这对于实现 @@ 操作符是必要的。例如, + 下面的 jsonpath 表达式在 PostgreSQL 中是有效的: + +$.track.segments[*].HR < 70 + + + - - 正则表达式解释 + 对于 like_regex 过滤器中使用的正则表达式模式,其解释方式存在一些细微差异,详见 - - + + - + 严格模式与宽松模式 + 当查询JSON数据时,路径表达式可能与实际的JSON数据结构不匹配。 - 试图访问不存在的对象成员或数组元素会导致结构错误。SQL/JSON路径表达式有两种处理结构错误的模式: + 试图访问不存在的对象成员或数组元素会导致结构错误。SQL/JSON路径表达式有两种处理结构错误的模式: - 不严格的(lax)(默认)—路径引擎隐式地将查询的数据适配到指定的路径。任何剩余的结构错误都将被抑制并转换为空SQL/JSON序列。 + 宽松模式(lax,默认)—路径引擎隐式地将查询的数据适配到指定的路径。任何剩余的结构错误都将被抑制并转换为空SQL/JSON序列。 - - 严格的(strict) —如果发生了结构错误,则会引发错误。 - + 严格模式(strict)— 如果发生结构错误,就会引发错误。 - 如果JSON数据不符合期望的模式,不严格的(lax)模式有助于匹配JSON文档结构和路径表达式。 - 如果操作不匹配特定操作的要求,可以自动将其包装为SQL/JSON数组,也可以在执行该操作之前将其元素转换为SQL/JSON序列来解包装。 - 此外,比较操作符会自动以lax模式打开它们的操作数,因此你可以开包即用的就能比较SQL/JSON数组。 - 大小为1的数组被认为等于它的唯一元素。只有在以下情况下才不会自动展开: + 如果 JSON 数据不符合预期模式,宽松模式有助于使 JSON 文档结构与路径表达式相匹配。如果操作数不满足某个操作的要求,可以在执行该操作之前自动将其包装为 SQL/JSON 数组,或通过将其元素转换为 SQL/JSON 序列来解包。此外,在宽松模式下,比较操作符会自动解包其操作数,因此可以直接比较 SQL/JSON 数组。大小为 1 的数组被视为等于其唯一元素。以下情况不会自动解包: - 路径表达式包含type()size()方法,它们分别返回数组中的元素类型和数量。 + 路径表达式包含type()size()方法,它们分别返回类型和数组中的元素数量。 - 查询的JSON数据包含嵌套的数组。在本例中,只有最外层的数组被打开,而所有内部数组保持不变。 - 因此,隐式展开在每个路径求值步骤中只能向下进行一级。 + 查询的JSON数据包含嵌套的数组。在本例中,只有最外层的数组被解包,而所有内部数组保持不变。 + 因此,隐式解包在每个路径求值步骤中只能向下进行一级。 - - 例如,当查询上面列出的GPS数据时,当使用不严格的(lax)模式时,你可以从它存储了一组片段的事实中抽象出来: - + 例如,查询上面列出的 GPS 数据时,使用宽松模式可以不必关心它将轨迹段存储为数组这一细节: lax $.track.segments.location - - 在严格的(strict)模式中,指定的路径必须与查询的JSON文档的结构完全匹配才能返回SQL/JSON项,因此使用该路径表达式会导致错误。 - 要得到与不严格的(lax)模式相同的结果,你必须显式地打开segments数组: - + 在严格模式下,指定路径必须与所查询 JSON 文档的结构完全匹配,才能返回 SQL/JSON 项,因此使用此路径表达式会导致错误。要得到与宽松模式相同的结果,必须显式解包segments数组: strict $.track.segments[*].location - - .**访问器在使用lax模式时可能导致令人惊讶的结果。 - 例如,下面的查询选择每个HR值两次: - + .**访问器在宽松模式下可能产生出人意料的结果。例如,下面的查询会选出每个HR值两次: lax $.**.HR - - 发生这个,是因为.**访问器会全部选择segments数组和它的每个元素。 - 而当使用lax模式时,.HR访问器会自动打开数组。 - 为了避免意外的结果,我们建议仅在严格模式下使用.**访问器。 - 下面的查询选择每个HR值仅一次: - +这是因为.**访问器既选择segments数组,又选择其每个元素,而.HR访问器在宽松模式下会自动解包数组。为避免意外结果,建议将.**访问器仅用于严格模式。下面的查询只选出每个HR值一次: strict $.**.HR @@ -15245,7 +15066,7 @@ strict $.**.HR SQL/JSON 路径操作符和方法 - 显示了jsonpath中可用的操作符和方法。 + 显示了jsonpath中可用的操作符和方法。 请注意,虽然一元操作符和方法可以应用于由前一个路径步骤产生的多个值,二元操作符(加法等)只能应用于单个值。 @@ -15318,7 +15139,7 @@ strict $.**.HR number - 否定;与减法不同,它可以迭代多个值 + 取负;与减法不同,可以遍历多个值。 jsonb_path_query_array('{"x": [2,3,4]}', '- $.x') @@ -15360,7 +15181,7 @@ strict $.**.HR number - 模数 (余数) + 取模(余数) jsonb_path_query('[32]', '$[0] % 10') @@ -15456,7 +15277,7 @@ strict $.**.HR string . datetime() datetime_type - (see note) + (见注) 从字符串转换过来的日期/时间值 @@ -15471,7 +15292,7 @@ strict $.**.HR string . datetime(template) datetime_type - (see note) + (见注) 使用指定的to_timestamp模板从字符串转换过来的日期/时间值 @@ -15508,7 +15329,7 @@ strict $.**.HR datetime()方法依次尝试将其输入字符串与date, timetz, time,timestamptz, 和 timestamp的ISO格式进行匹配。 - 它在第一个匹配格式时停止,并发出相应的数据类型。 + 它在第一个匹配格式时停止,并返回相应数据类型的值。 @@ -15516,26 +15337,26 @@ strict $.**.HR - datetime()datetime(template)方法使用与to_timestamp SQL函数相同的解析规则(see ),但有三个例外。 + datetime()datetime(template)方法使用与to_timestamp SQL函数相同的解析规则(参见),但有三个例外。 首先,这些方法不允许不匹配的模板模式。 - 其次,模板字符串中只允许以下分隔符:减号、句点、solidus(斜杠)、逗号、撇号、分号、冒号和空格。 + 其次,模板字符串中只允许以下分隔符:减号、句点、斜杠、逗号、撇号、分号、冒号和空格。 第三,模板字符串中的分隔符必须与输入字符串完全匹配。 - 如果需要比较不同的日期/时间类型,则应用隐式转换。 + 如果需要比较不同的日期/时间类型,则应用隐式类型转换。 date值可以转换为timestamptimestamptz, timestamp可以转换为timestamptz, time可以转换为timetz。 但是,除了第一个转换外,其他所有转换都依赖于当前设置,因此只能在时区感知的jsonpath函数中执行。 - 显示了适用的过滤器表达式元素。 + 显示了可用的过滤表达式元素。 - <type>jsonpath</type> 过滤器表达式元素 + <type>jsonpath</type> 过滤表达式元素 @@ -15684,7 +15505,7 @@ strict $.**.HR value - JSON常数null(注意,与SQL不同,与null比较可以正常工作) + JSON 常量null(注意,与SQL不同,与null比较可以正常工作) jsonb_path_query('[{"name": "Mary", "job": null}, {"name": "Michael", "job": "driver"}]', '$[*] ? (@.job == null) .name') @@ -15754,7 +15575,7 @@ strict $.**.HR boolean - 测试第一个操作数是否与第二个操作数给出的正则表达式匹配,可选使用由一串flag字符描述的修改(参见)。 + 测试第一个操作数是否与第二个操作数给出的正则表达式匹配;可以用一串flag标志字符调整匹配行为(参见)。 jsonb_path_query_array('["abc", "abd", "aBdC", "abdacb", "babc"]', '$[*] ? (@ like_regex "^ab.*c")') @@ -15810,31 +15631,28 @@ strict $.**.HR LIKE_REGEX - in SQL/JSON + 用于 SQL/JSON - - SQL/JSON路径表达式允许通过like_regex过滤器将文本匹配为正则表达式。 - 例如,下面的SQL/JSON路径查询将不区分大小写地匹配以英语元音开头的数组中的所有字符串: - + SQL/JSON 路径表达式允许使用like_regex过滤器,将文本与正则表达式进行匹配。例如,以下 SQL/JSON 路径查询会以不区分大小写的方式,匹配数组中所有以英语元音字母开头的字符串: $[*] ? (@ like_regex "^[aeiou]" flag "i") - 可选的flag字符串可以包括一个或多个字符i用于不区分大小写的匹配,m允许^$在换行时匹配,s允许.匹配换行符,q引用整个模式(将行为简化为一个简单的子字符串匹配)。 + 可选的flag字符串可以包括一个或多个字符i用于不区分大小写的匹配,m允许^$在换行时匹配,s允许.匹配换行符,q将整个模式按字面量处理(将行为简化为一个简单的子字符串匹配)。 SQL/JSON标准借用了来自LIKE_REGEX操作符的正则表达式定义,其使用了XQuery标准。 PostgreSQL目前不支持LIKE_REGEX操作符。因此,like_regex过滤器是使用中描述的POSIX正则表达式引擎来实现的。 - 这导致了与标准SQL/JSON行为的各种细微差异,这在中进行了分类。 - 但是请注意,这里描述的标志字母不兼容并不适用于SQL/JSON,因为它将XQuery标志字母翻译为符合POSIX引擎的预期。 + 这导致了与标准SQL/JSON行为的各种细微差异,这些差异列在中。 + 但是请注意,这里描述的标志字母不兼容并不适用于SQL/JSON,因为 SQL/JSON 会将 XQuery 标志字母转换为 POSIX 引擎所预期的形式。 - 请记住,like_regex的模式参数是一个JSON路径字符串文字,根据给出的规则编写。 - 这特别意味着在正则表达式中要使用的任何反斜杠都必须加倍。例如,匹配只包含数字的根文档的字符串值: + 请记住,like_regex的模式参数是一个JSON 路径字符串字面量,根据给出的规则编写。 + 这特别意味着在正则表达式中要使用的任何反斜杠都必须加倍。例如,匹配根文档中仅包含数字的字符串值: $.* ? (@ like_regex "^\\d+$") @@ -15849,11 +15667,11 @@ $.* ? (@ like_regex "^\\d+$") 序列操作函数 - sequence + 序列 - 本节描述对序列对象进行操作的函数,也称为序列生成器或简称序列。 + 本节描述用于操作序列对象(也称为序列生成器,或简称序列)的函数。 序列对象是使用创建的特殊单行表。 序列对象通常用于为表中的行生成惟一标识符。在中列出的序列函数,提供了简单的、多用户安全方法,用于从序列对象中获取连续的序列值。 @@ -15885,12 +15703,12 @@ $.* ? (@ like_regex "^\\d+$") bigint - 将序列对象推进到下一个值并返回该值。这是自动完成的:即使多个会话并发地执行nextval,每个会话也会安全地接收到不同的序列值。 - 如果序列对象是用默认形参创建的,则连续的nextval调用将返回以1开始的连续值。 + 将序列对象推进到下一个值并返回该值。这个操作是原子的:即使多个会话并发地执行nextval,每个会话也会安全地接收到不同的序列值。 + 如果序列对象是用默认参数创建的,则连续的nextval调用将返回以1开始的连续值。 其他行为可以通过在命令中使用适当的参数获得。 - 这个函数需要USAGEUPDATE权限在序列上。 + 这个函数需要序列上的USAGEUPDATE权限。 @@ -15903,16 +15721,16 @@ $.* ? (@ like_regex "^\\d+$") bigint - 设置序列对象的当前值,以及可选的它的is_called标志。 + 设置序列对象的当前值,并可选地设置其is_called标志。 双参数形式将序列的last_value字段设置为指定的值,并将其is_called字段设置为true,意味着下一个nextval将在返回值之前推进序列。 currval将报告的值也设置为指定的值。在三参数形式中,is_called可以设置为truefalsetrue与双参数形式具有相同的效果。 - 如果设置为false,下一个nextval将返回指定的值,序列推进从下面的nextval开始。 - 而且,currval报告的值在这种情况下不会改变。例如, + 如果设置为false,下一个nextval将返回指定的值,序列推进从再下一次调用nextval开始。 + 而且,currval报告的值在这种情况下不会改变。例如: -SELECT setval('myseq', 42); Next nextval will return 43 +SELECT setval('myseq', 42); 下一次 nextval 将返回 43 SELECT setval('myseq', 42, true); 同上 -SELECT setval('myseq', 42, false); Next nextval will return 42 +SELECT setval('myseq', 42, false); 下一次 nextval 将返回 42 setval返回的结果就是它的第二个参数的值。 @@ -15930,8 +15748,7 @@ SELECT setval('myseq', 42, false); Next nextvalbigint - 返回nextval在当前会话中为该序列最近获取的值。(如果在这个会话中没有为这个序列调用nextval会报告错误。) - 因为它返回的是一个会话本地值,所以它给出了一个可预测的答案,即自当前会话以来,其他会话是否执行了nextval。 + 返回当前会话中最近一次针对该序列调用nextval所获得的值。(如果当前会话从未针对该序列调用过nextval,则会报错。)由于返回的是会话局部值,无论其他会话是否在当前会话调用之后执行过nextval,结果都是可预测的。 这个函数需要序列上的USAGESELECT权限。 @@ -15983,9 +15800,7 @@ SELECT setval('myseq', 42, false); Next nextval - 序列函数所要操作的序列由regclass参数指定,该参数只是pg_class系统目录中序列的OID。 - 你不必手工查找OID,不过,因为regclass数据类型的输入转换器将为您完成这项工作。 - 详见 + 序列函数所要操作的序列由regclass参数指定,该参数就是序列在pg_class系统目录中的 OID。不过,不必手动查找 OID,因为regclass数据类型的输入转换器会完成这项工作。详见 @@ -16032,7 +15847,7 @@ CASE WHEN condition THEN result - CASE子句可以用于任何表达式可以出现的地方。每一个condition是一个返回boolean结果的表达式。如果结果为真,那么CASE表达式的结果就是符合条件的result,并且剩下的CASE表达式不会被处理。如果条件的结果不为真,那么以相同方式搜寻任何随后的WHEN子句。如果没有WHEN condition为真,那么CASE表达式的值就是在ELSE子句里的result。如果省略了ELSE子句而且没有条件为真,结果为空。 + CASE子句可以用于任何表达式可以出现的地方。每一个condition是一个返回boolean结果的表达式。如果结果为真,那么CASE表达式的结果就是紧随该条件后的result,并且剩下的CASE表达式不会被处理。如果条件的结果不为真,那么以相同方式搜寻任何随后的WHEN子句。如果没有WHEN condition为真,那么CASE表达式的值就是在ELSE子句里的result。如果省略了ELSE子句而且没有条件为真,结果为 null。 @@ -16076,7 +15891,7 @@ CASE expression END - 第一个expression会被计算,然后与所有在WHEN子句中的每一个value对比,直到找到一个相等的。如果没有找到匹配的,则返回在ELSE子句中的result(或者控制)。 这类似于 C 里的switch语句。 + 第一个expression会被计算,然后与所有在WHEN子句中的每一个value对比,直到找到一个相等的。如果没有找到匹配的,则返回在ELSE子句中的result(或者 null 值)。 这类似于 C 里的switch语句。 @@ -16107,11 +15922,7 @@ SELECT ... WHERE CASE WHEN x <> 0 THEN y/x > 1.5 ELSE false END; - 如中所述,在有几种情况中一个表达式的子表达式 - 会被计算多次,因此CASE只计算必要的表达式这 - 一原则并非不可打破。例如一个常量子表达式1/0通常将会在规划时导致一次 - 除零错误,即便它位于一个执行时永远也不会进入的CASE分支时也是 - 如此。 + 如所述,在多种情况下,表达式中的子表达式会在不同阶段求值,因此CASE只计算必要的子表达式这一原则并非绝对成立。例如,常量子表达式1/0通常会在规划时导致除零错误,即便它位于一个运行时永远不会进入的CASE分支中也是如此。 @@ -16136,19 +15947,19 @@ SELECT ... WHERE CASE WHEN x <> 0 THEN y/x > 1.5 ELSE false END; - COALESCE函数返回其第一个非空参数的值。只有当所有参数都为空时,它才返回空值。它常用于在为显示目的检索数据时,用缺省值替换空值。例如: + COALESCE函数返回参数中第一个不为 null 的值。只有所有参数都为 null 时,才返回 null。它常用于在检索数据以供显示时,用默认值替换 null 值。例如: SELECT COALESCE(description, short_description, '(none)') ... - 如果description不为空,这将会返回它的值,否则如果short_description非空则返回short_description的值,如果前两个都为空则返回(none)。 + 此表达式返回description,前提是它不为 null,否则返回short_description,前提是它不为 null,否则返回(none) - 所有参数都必须转换为一个公共数据类型,它将是结果的类型 (详情参见 )。 + 所有参数都必须能转换为同一个数据类型,它将是结果的类型(详情参见)。 - 和CASE表达式一样,COALESCE将不会 计算无助于判断结果的参数;也就是说,在第一个非空参数右边的参数不会被计算。这个 SQL 标准函数提供了类似于NVLIFNULL的能力,它们被用在某些其他数据库系统中。 + 和CASE表达式一样,COALESCE只计算确定结果所需的参数;也就是说,在第一个不为 null 的参数右边的参数不会被计算。这个 SQL 标准函数提供了类似于NVLIFNULL的能力,它们被用在某些其他数据库系统中。 @@ -16164,12 +15975,12 @@ SELECT COALESCE(description, short_description, '(none)') ... - 当value1value2相等时,NULLIF返回一个空值。 + 当value1value2相等时,NULLIF返回 null。 否则它返回value1。 这些可以用于执行前文给出的COALESCE示例的逆操作: SELECT NULLIF(value, '(none)') ... - 在这个示例中,如果value(none),将返回空值,否则返回value的值。 + 在这个示例中,如果value(none),将返回 null,否则返回value的值。 @@ -16204,11 +16015,11 @@ SELECT NULLIF(value, '(none)') ... - GREATESTLEAST函数从一个任意的数字表达式列表里选取最大或者最小的数值。 这些表达式必须都可以转换成一个普通的数据类型,它将会是结果类型 (参阅获取细节)。列表中的 NULL 数值将被忽略。只有所有表达式的结果都是 NULL 的时候,结果才会是 NULL。 + GREATESTLEAST函数从由任意数量的表达式组成的列表中选取最大值或最小值。这些表达式都必须能转换为同一个数据类型,该类型将作为结果类型(详情参见)。 - 请注意GREATESTLEAST都不是 SQL 标准,但却是很常见的扩展。某些其他数据库让它们在任何参数为 NULL 时返回 NULL,而不是在所有参数都为 NULL 时才返回 NULL。 + 参数列表中的 NULL 值会被忽略。只有所有表达式的求值结果都为 NULL 时,结果才为 NULL。(这与 SQL 标准不同。按照标准,只要有任意参数为 NULL,返回值就为 NULL。一些其他数据库采用这种行为。) @@ -16220,9 +16031,9 @@ SELECT NULLIF(value, '(none)') ... 显示了可以用于数组类型的专用的操作符。 除此之外,中所示的常用比较操作符也适用于数组。 - 比较操作符逐个元素的比较数组内容,使用默认的元素数据类型的B-树比较函数,并根据第一个差值进行排序。 + 比较操作符逐个元素比较数组内容,使用元素数据类型的默认 B-树比较函数,并根据第一个差异进行排序。 多维数组的元素按照行序进行访问(最后的下标变化最快)。 - 如果两个数组的内容相同但维数不等,那么维度信息中的第一个不同将决定排序顺序。 + 如果两个数组的内容相同但维度信息不同,那么维度信息中的第一个不同将决定排序顺序。
@@ -16253,7 +16064,7 @@ SELECT NULLIF(value, '(none)') ... 第一个数组是否包含第二个数组,也就是说,出现在第二个数组中的每个元素是否等于第一个数组中的某个元素? - (重复值不需要特殊处理,因此ARRAY[1]ARRAY[1,1]被认为包含对方。) + (重复元素不作特殊处理,因此ARRAY[1]ARRAY[1,1]被认为包含对方。) ARRAY[1,4,3] @> ARRAY[3,1,3] @@ -16295,8 +16106,7 @@ SELECT NULLIF(value, '(none)') ... anycompatiblearray - 连接两个数组。连接空(null)或空数组不会产生任何效果;否则,数组必须具有相同的维度数(如第一个示例所示),或者维度数相差一维(如第二个示例所示)。 - 如果数组的元素类型并不完全相同,它们将被强制转换为一个共同的类型(参见)。 + 连接两个数组。连接 null 或空数组不会产生任何效果;否则,数组必须具有相同的维数(如第一个示例所示),或维数相差一维(如第二个示例所示)。如果数组的元素类型不同,则会将它们强制转换为同一个类型(参见)。 ARRAY[1,2,3] || ARRAY[4,5,6,7] @@ -16328,7 +16138,7 @@ SELECT NULLIF(value, '(none)') ... anycompatiblearray - 将元素连接到数组的末尾(数组必须为空或一维的[one-dimensional])。 + 将元素连接到数组的末尾(数组必须为空或一维)。 ARRAY[4,5,6] || 7 @@ -16340,7 +16150,7 @@ SELECT NULLIF(value, '(none)') ...
- 参阅获取有关数组操作符行为的更多细节。有关哪些操作符支持被索引的操作,请参阅。 + 参阅获取有关数组操作符行为的更多细节。有关哪些操作符支持索引操作,请参阅 @@ -16429,8 +16239,7 @@ SELECT NULLIF(value, '(none)') ... anyarray - 返回一个包含给定值的拷贝的数组,其维数与第二个参数指定的长度相同。 - 可选的第三个参数提供每个维度的下界值(默认为全部为 1)。 + 返回用给定值的副本填充的数组,各维的长度由第二个参数指定。可选的第三个参数提供各维的下界值(默认均为1)。 array_fill(11, ARRAY[2,3]) @@ -16511,7 +16320,7 @@ SELECT NULLIF(value, '(none)') ... integer - 返回阵列中第二个参数中第一次发生的下标,如果它不存在,则返回NULL。 + 返回第二个参数在数组中首次出现的下标;若不存在,则返回NULL。 如果给出了第三个参数,则搜索从该下标开始。数组必须是一维的。比较是使用IS NOT DISTINCT FROM语义进行的,所以可以搜索NULL @@ -16529,9 +16338,9 @@ SELECT NULLIF(value, '(none)') ... integer[] - 返回作为第一个参数的数组中第二个参数所有出现的下标的数组。 + 返回第二个参数在第一个参数所给数组中所有出现位置的下标数组。 数组必须是一维的。使用IS NOT DISTINCT FROM语义完成比较,所以可以搜索NULL。 - 只有当数组为NULL时才返回NULL;如果在数组中没有找到该值,则返回空数组。 + 只有当数组为NULL时才返回NULL;如果在数组中没有找到该值,则返回空数组。 array_positions(ARRAY['A','A','B','A'], 'A') @@ -16690,7 +16499,7 @@ SELECT NULLIF(value, '(none)') ... anyarray - 通过删除最后的n元素来裁剪数组。 + 通过删除最后的n个元素来裁剪数组。 如果数组是多维的,则只裁剪第一个维度。 @@ -16739,7 +16548,7 @@ SELECT NULLIF(value, '(none)') ... 将多个数组(可能是不同的数据类型)展开到一组行中。 如果数组的长度不完全相同,那么较短的数组将用NULL填充。 - 这种形式只在查询的FROM子句中允许;参见。 + 这种形式只允许出现在查询的 FROM 子句中;参见 select * from unnest(ARRAY[1,2], ARRAY['foo','bar','baz']) as x(a,b) @@ -16890,7 +16699,7 @@ SELECT NULLIF(value, '(none)') ... boolean - 第一个范围是否严格符合第二个(范围)? + 第一个范围是否严格地在第二个(范围)的右边? int8range(50,60) >> int8range(20,30) @@ -16974,7 +16783,7 @@ SELECT NULLIF(value, '(none)') ... anyrange - 计算范围的差异。第二个范围必须不能包含在第一个(范围)中,以使差异不是一个单一的范围。 + 计算范围的差集。第二个范围不能被包含在第一个范围中而导致差集无法表示为单个范围。 int8range(5,15) - int8range(10,20) @@ -17068,7 +16877,7 @@ SELECT NULLIF(value, '(none)') ... boolean - 第一个多范围是否被第二个所包括? + 第一个多范围是否被第二个所包含? '{[2,4)}'::int4multirange <@ '{[1,7)}'::int4multirange @@ -17082,7 +16891,7 @@ SELECT NULLIF(value, '(none)') ... boolean - 多范围是否被范围所包括。 + 多范围是否被范围所包含? '{[2,4)}'::int4multirange <@ int4range(1,7) @@ -17096,7 +16905,7 @@ SELECT NULLIF(value, '(none)') ... boolean - 范围是否被多范围所包括? + 范围是否被多范围所包含? int4range(2,4) <@ '{[1,7)}'::int4multirange @@ -17194,7 +17003,7 @@ SELECT NULLIF(value, '(none)') ... boolean - 范围是否完全的在多范围左边? + 范围是否完全在多范围左边? int8range(1,10) << '{[100,110)}'::int8multirange @@ -17236,7 +17045,7 @@ SELECT NULLIF(value, '(none)') ... boolean - 范围是否完全在多范围右边。 + 范围是否完全在多范围右边? int8range(50,60) >> '{[20,30)}'::int8multirange @@ -17404,7 +17213,7 @@ SELECT NULLIF(value, '(none)') ... anymultirange - 计算多范围的差异。 + 计算多范围的差集。 '{[5,20)}'::int8multirange - '{[10,15)}'::int8multirange @@ -17416,21 +17225,21 @@ SELECT NULLIF(value, '(none)') ... - 当涉及一个空范围或多范围时,左部/右部/相邻操作符总是返回假;即一个空范围被认为不在任何其他范围前面或者后面。 + 涉及空范围或空多范围时,左侧、右侧和相邻操作符总是返回假;也就是说,空范围不被视为位于任何其他范围之前或之后。 - 在其他情况下,空范围和多范围被视为加法单位元:任何值与空值做并集的结果仍然是它自身。 - 任何值减去空值的结果也仍然是它自身。 - 空的多范围与空的范围具有完全相同的点。 + 在其他运算中,空范围和空多范围被视为加法单位元:任何值与空值求并集,结果仍是该值本身。 + 任何值减去空值,结果也仍是该值本身。 + 空多范围与空范围具有完全相同的点。 每个范围都包含空范围。 每个多范围包含任意多个空范围。 - 范围交集和差异操作符将失败,如果结果范围需要包含两个不相交的子范围,因为这样的范围无法表示。 - 还有用于求交集和差集的单独操作符,它们接受多范围参数并返回多范围,即使参数彼此不相交也不会失败。 - 因此,如果需要对可能不相交的范围进行交集或差异操作,你可以通过首先将范围转换为多范围来避免错误。 + 如果结果范围需要包含两个不相交的子范围,范围并集和差集操作符会失败,因为这样的范围无法表示。 + 另有接受多范围参数并返回多范围的并集和差集操作符,即使参数彼此不相交,也不会失败。 + 因此,如果需要对可能不相交的范围求并集或差集,可以先将范围转换为多范围来避免错误。 @@ -17468,7 +17277,7 @@ SELECT NULLIF(value, '(none)') ... anyelement - 提取范围的下界(如果范围为空或下界为无限,则为NULL)。 + 提取范围的下界(如果范围为空或没有下界,则返回NULL)。 lower(numrange(1.1,2.2)) @@ -17485,7 +17294,7 @@ SELECT NULLIF(value, '(none)') ... anyelement - 提取范围的上限(如果范围为空或上限为无限,则为NULL)。 + 提取范围的上界(如果范围为空或没有上界,则返回NULL)。 upper(numrange(1.1,2.2)) @@ -17553,7 +17362,7 @@ SELECT NULLIF(value, '(none)') ... boolean - 范围的下界是无限的吗? + 范围是否没有下界?(下界为-Infinity时返回假。) lower_inf('(,)'::daterange) @@ -17570,7 +17379,7 @@ SELECT NULLIF(value, '(none)') ... boolean - 范围的上界是无限的吗? + 范围是否没有上界?(上界为Infinity时返回假。) upper_inf('(,)'::daterange) @@ -17627,7 +17436,7 @@ SELECT NULLIF(value, '(none)') ... anyelement - 提取多范围的下界 (NULL 如果多范围为空或下界为无穷的)。 + 提取多范围的下界(如果多范围为空或没有下界,则返回NULL)。 lower('{[1.1,2.2)}'::nummultirange) @@ -17644,7 +17453,7 @@ SELECT NULLIF(value, '(none)') ... anyelement - 提取多范围的上界 (NULL 如果多范围为空或上界为无穷的)。 + 提取多范围的上界(如果多范围为空或没有上界,则返回NULL)。 upper('{[1.1,2.2)}'::nummultirange) @@ -17678,7 +17487,7 @@ SELECT NULLIF(value, '(none)') ... boolean - 多范围的下界是否包括? + 多范围的下界是否包含在内? lower_inc('{[1.1,2.2)}'::nummultirange) @@ -17695,7 +17504,7 @@ SELECT NULLIF(value, '(none)') ... boolean - 多范围的上界是否包括? + 多范围的上界是否包含在内? upper_inc('{[1.1,2.2)}'::nummultirange) @@ -17712,7 +17521,7 @@ SELECT NULLIF(value, '(none)') ... boolean - 多范围的下界是无限的么? + 多范围是否没有下界?(下界为-Infinity时返回假。) lower_inf('{(,)}'::datemultirange) @@ -17729,7 +17538,7 @@ SELECT NULLIF(value, '(none)') ... boolean - 多范围的上界是无限的么? + 多范围是否没有上界?(上界为Infinity时返回假。) upper_inf('{(,)}'::datemultirange) @@ -17757,7 +17566,7 @@ SELECT NULLIF(value, '(none)') ... - multirange (function) + multirange(函数) multirange ( anyrange ) anymultirange @@ -17775,14 +17584,14 @@ SELECT NULLIF(value, '(none)') ... unnest - for multirange + 用于多范围 unnest ( anymultirange ) setof anyrange - 扩展多范围为一组范围。 - 范围按存储顺序读出(升序)。 + 将多范围展开为一组范围。 + 范围按存储顺序(升序)读出。 unnest('{[1,2), [3,4)}'::int4multirange) @@ -17798,7 +17607,7 @@ SELECT NULLIF(value, '(none)') ... - lower_incupper_inclower_inf、 和 upper_inf 函数对空范围(empty range)或多范围都返回假(false)。 + lower_incupper_inclower_infupper_inf 函数对空范围或空多范围都返回假。 @@ -17812,11 +17621,11 @@ SELECT NULLIF(value, '(none)') ... - 聚合函数从一个输入值的集合计算出一个单一值。 - 内置的通用聚合函数在中列出,而统计性聚合是在中列出。 + 聚合函数从一个输入值的集合计算出一个单一结果。 + 内置的通用聚合函数在中列出,而统计聚合函数在中列出。 内置的组内有序集聚合函数在中列出,而内置的组内假想集聚合在中列出。 与聚合函数紧密相关的分组操作在中列出。 - 中会解释针对聚合函数的特殊语法考虑。额外的介绍信息请参考。 + 中会解释针对聚合函数的特殊语法注意事项。更多入门信息请参考 @@ -17844,6 +17653,20 @@ SELECT NULLIF(value, '(none)') ... + + + + any_value + + any_value ( anyelement ) + 与输入类型相同 + + + 从非空输入值中返回任意一个值。 + + + + @@ -17855,7 +17678,7 @@ SELECT NULLIF(value, '(none)') ... 将所有输入值,包括空值,收集到一个数组中。 - No + @@ -17864,15 +17687,15 @@ SELECT NULLIF(value, '(none)') ... anyarray - 将所有输入数组连接到一个更高维度的数组中。(输入必须都具有相同的维度,并且不能为空的(empty)或空值(null)。) + 将所有输入数组连接成维数增加一维的数组。(所有输入的维数必须相同,且不能是空数组或空值(NULL)。) - No + - average + 平均值 avg @@ -17907,7 +17730,7 @@ SELECT NULLIF(value, '(none)') ... 计算所有非空输入值的平均值(算术平均值)。 - Yes + @@ -17931,9 +17754,9 @@ SELECT NULLIF(value, '(none)') ... bit - 计算所有非空输入值的逐位AND。 + 计算所有非空输入值的按位与。
- Yes + @@ -17957,9 +17780,9 @@ SELECT NULLIF(value, '(none)') ... bit
- 计算所有非空输入值的逐位OR。 + 计算所有非空输入值的按位或。
- Yes + @@ -17986,7 +17809,7 @@ SELECT NULLIF(value, '(none)') ... 计算所有非空输入值的按位异或。 可用作一组无序的值集合的校验和。
- Yes + @@ -18000,7 +17823,7 @@ SELECT NULLIF(value, '(none)') ... 如果全部非空输入值都为真则返回真,否则返回假。 - Yes + @@ -18014,7 +17837,7 @@ SELECT NULLIF(value, '(none)') ... 如果任何非空输入值为真则返回真,否则返回假。 - Yes + @@ -18028,7 +17851,7 @@ SELECT NULLIF(value, '(none)') ... 计算输入行的数量。 - Yes + @@ -18039,7 +17862,7 @@ SELECT NULLIF(value, '(none)') ... 计算输入值不为空的输入行的数量。 - Yes + @@ -18051,9 +17874,9 @@ SELECT NULLIF(value, '(none)') ... boolean
- 这是对应bool_and的SQL标准的等效物。 + 这是标准 SQL 中与bool_and等价的函数。 - Yes + @@ -18074,7 +17897,71 @@ SELECT NULLIF(value, '(none)') ... 收集所有输入值,包括空值,到一个JSON数组。根据to_jsonto_jsonb将值转换为JSON。 - No + + + + + + + json_agg_strict + + json_agg_strict ( anyelement ) + json + + + + jsonb_agg_strict + + jsonb_agg_strict ( anyelement ) + jsonb + + + 将所有非空输入值收集到一个JSON数组中,跳过空值。根据to_jsonto_jsonb将值转换为JSON。 + + + + + + + json_arrayagg + json_arrayagg ( + value_expression + ORDER BY sort_expression + { NULL | ABSENT } ON NULL + RETURNING data_type FORMAT JSON ENCODING UTF8 ) + + + 行为与json_array相同,只是它作为一个聚合函数,因此只接受一个 + value_expression参数。 + 如果指定了ABSENT ON NULL,则会省略所有 NULL 值。 + 如果指定了ORDER BY,元素将按该顺序出现在数组中,而不是按输入顺序。 + + + SELECT json_arrayagg(v) FROM (VALUES(2),(1)) t(v) + [2, 1] + + + + + + + json_objectagg + json_objectagg ( + { key_expression { VALUE | ':' } value_expression } + { NULL | ABSENT } ON NULL + { WITH | WITHOUT } UNIQUE KEYS + RETURNING data_type FORMAT JSON ENCODING UTF8 ) + + + 行为与json_object相同,只是它作为一个聚合函数,因此只接受一个 + key_expression参数和一个 + value_expression参数。 + + + SELECT json_objectagg(k:v) FROM (VALUES ('a'::text,current_date),('b',current_date + 1)) AS t(k,v) + { "a" : "2022-05-10", "b" : "2022-05-11" } + + @@ -18097,10 +17984,89 @@ SELECT NULLIF(value, '(none)') ... jsonb
- 将所有键/值对收集到一个JSON对象中。关键参数强制转换为文本;值参数按照to_jsonto_jsonb进行转换。 + 将所有键/值对收集到一个JSON对象中。键参数强制转换为文本;值参数按照to_jsonto_jsonb进行转换。 值可以为空,但键不能(为空)。 - No + + + + + + + json_object_agg_strict + + json_object_agg_strict ( + key "any", + value "any" ) + json + + + + jsonb_object_agg_strict + + jsonb_object_agg_strict ( + key "any", + value "any" ) + jsonb + + + 将所有键/值对收集到一个JSON对象中。键参数强制转换为文本;值参数按照to_jsonto_jsonb进行转换。 + key不能为空。如果value为空,则跳过该条目。 + + + + + + + + json_object_agg_unique + + json_object_agg_unique ( + key "any", + value "any" ) + json + + + + jsonb_object_agg_unique + + jsonb_object_agg_unique ( + key "any", + value "any" ) + jsonb + + + 将所有键/值对收集到一个JSON对象中。键参数强制转换为文本;值参数按照to_jsonto_jsonb进行转换。 + 值可以为空,但键不能为空。如果存在重复键,则会抛出错误。 + + + + + + + + json_object_agg_unique_strict + + json_object_agg_unique_strict ( + key "any", + value "any" ) + json + + + + jsonb_object_agg_unique_strict + + jsonb_object_agg_unique_strict ( + key "any", + value "any" ) + jsonb + + + 将所有键/值对收集到一个JSON对象中。键参数强制转换为文本;值参数按照to_jsonto_jsonb进行转换。 + key不能为空。如果value为空,则跳过该条目。 + 如果存在重复键,则会抛出错误。 + + @@ -18108,8 +18074,8 @@ SELECT NULLIF(value, '(none)') ... 最大值 - max ( see text ) - same as input type + max ( 见说明 ) + 与输入类型相同
计算非空输入值的最大值。适用于任何数字、字符串、日期/时间或枚举类型, @@ -18126,8 +18092,8 @@ SELECT NULLIF(value, '(none)') ... 最小值 - min ( see text ) - same as input type + min ( 见说明 ) + 与输入类型相同 计算非空输入值的最小值。适用于任何数字、字符串、日期/时间或枚举类型, @@ -18156,7 +18122,7 @@ SELECT NULLIF(value, '(none)') ... 计算非空输入值的并集。 - No + @@ -18176,7 +18142,7 @@ SELECT NULLIF(value, '(none)') ... 计算非空输入值的交集。 - No + @@ -18194,9 +18160,9 @@ SELECT NULLIF(value, '(none)') ... bytea - 将非 NULL 输入值连接成一个字符串。第一个值之后的每个值前面都会放置相应的delimiter(如果它不为 NULL)。 + 将非 NULL 输入值连接成一个字符串。在第一个值之后,每个值前面都会放置相应的delimiter(如果它不为 NULL)。 - No + @@ -18238,7 +18204,7 @@ SELECT NULLIF(value, '(none)') ... 计算非空输入值的总和。 - Yes + @@ -18250,31 +18216,24 @@ SELECT NULLIF(value, '(none)') ... xml
- 连接非空的XML输入值(参见)。 + 连接非空的 XML 输入值(参见)。 - No + - 应该注意的是,除了count之外,这些函数在没有选中任何行时都会返回空值。 - 特别地,sum在没有输入行时返回空值,而不是预期中的零;array_agg在没有输入行时返回空值,而不是空数组。 - 必要时,可以用coalesce函数把空值替换成零或空数组。 + 需要注意,除了count之外,这些函数在没有选中任何行时都会返回空值。特别地,sum在没有输入行时返回空值,而不是预期中的零;array_agg在没有输入行时返回空值,而不是空数组。必要时,可以用coalesce函数把空值替换成零或空数组。 - 聚合函数 array_agg,json_agg, jsonb_agg,json_object_agg, jsonb_object_agg, - string_agg,和 xmlagg,以及类似的用户定义的聚合函数,根据输入值的顺序产生富有意义的不同的结果值。 - 默认情况下,这种排序是不指定的,但可以通过在聚合调用中写入ORDER BY子句来控制,如所示。 - 或者,从排序的子查询提供输入值通常也可以。例如: - + 聚合函数array_aggjson_aggjsonb_aggjson_agg_strictjsonb_agg_strictjson_object_aggjsonb_object_aggjson_object_agg_strictjsonb_object_agg_strictjson_object_agg_uniquejsonb_object_agg_uniquejson_object_agg_unique_strictjsonb_object_agg_unique_strictstring_aggxmlagg,以及类似的用户定义聚合函数,其结果值会随输入值的顺序发生实质性变化。默认情况下,输入顺序未指定,但可以在聚合调用中写入ORDER BY子句来控制,如所示。也可以用已排序的子查询提供输入值,这通常也能奏效。例如: - - 注意,如果外部查询级别包含其他处理,例如关联,则此方法可能会失败,因为这可能导致子查询的输出在计算聚合之前重新排序。 + 需要注意,如果外层查询包含连接等额外处理,这种方法可能失效,因为子查询的输出可能在计算聚合之前被重新排序。 @@ -18288,31 +18247,24 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; - 布尔聚合 bool_andbool_or 对应于标准SQL聚合 everyanysome. - PostgreSQL 支持 every, 但不支持 anysome, 因为标准语法中存在模糊性: - + 布尔聚合bool_andbool_or对应于标准 SQL 聚合everyanysome。 + PostgreSQL支持every,但不支持anysome,因为标准语法中存在歧义: SELECT b1 = ANY((SELECT b2 FROM t2 ...)) FROM t1 ...; - - 这里ANY可以被认为是引入子查询,或者是聚合函数,如果子查询返回一行布尔值。因此,不能为这些聚合提供标准名称。 +此处的ANY既可以被视为引入一个子查询,也可以在该子查询返回一行布尔值时被视为聚合函数。因此,不能将标准名称用于这些聚合。 - 习惯使用其他SQL数据库管理系统的用户可能会对count聚合应用于整个表时的性能感到失望。一个类似下面的查询: - + 习惯于其他 SQL 数据库管理系统的用户,可能会对count聚合用于整个表时的性能感到失望。如下查询: SELECT count(*) FROM sometable; - - 将需要与表大小成比例的工作:PostgreSQL将需要扫描整个表或包含表中所有行的索引。 +所需的工作量与表大小成正比:PostgreSQL需要扫描整个表,或者完整扫描一个包含表中所有行的索引。 - 显示了统计分析中常用的聚合函数。 - (这些被分离出来仅仅是为了避免使更常用的聚合列表混乱。) - 显示为接受numeric_type的函数可用于所有类型smallint, integer,bigint, numeric, real, 和 double precision。 - 在描述中提及N时,它意味着所有输入表达式都非空的输入行数。在所有情况下,如果计算没有意义,则返回null,例如当N为0时。 + 列出了统计分析中常用的聚合函数。(将它们单独列出,只是为了避免更常用的聚合函数列表过于杂乱。)标为接受numeric_type的函数适用于smallintintegerbigintnumericrealdouble precision这些类型。描述中提到的N表示所有输入表达式都非空的输入行数。无论哪种情况,如果计算没有意义,例如N为 0,就返回 null。 @@ -18347,7 +18299,7 @@ SELECT count(*) FROM sometable; - correlation + 相关性 corr @@ -18358,14 +18310,14 @@ SELECT count(*) FROM sometable; 计算相关系数。 - Yes + - covariance - population + 协方差 + 总体 covar_pop @@ -18376,14 +18328,14 @@ SELECT count(*) FROM sometable; 计算总体协方差。 - Yes + - covariance - sample + 协方差 + 样本 covar_samp @@ -18394,7 +18346,7 @@ SELECT count(*) FROM sometable; 计算样本协方差。 - Yes + @@ -18406,9 +18358,9 @@ SELECT count(*) FROM sometable; double precision
- 计算自变量的平均值,sum(X)/N. + 计算自变量的平均值,即sum(X)/N - Yes + @@ -18420,9 +18372,9 @@ SELECT count(*) FROM sometable; double precision
- 计算因变量的平均值,sum(Y)/N. + 计算因变量的平均值,即sum(Y)/N - Yes + @@ -18436,13 +18388,13 @@ SELECT count(*) FROM sometable; 计算两个输入都非空的行数。 - Yes + - regression intercept + 回归截距 regr_intercept @@ -18451,9 +18403,9 @@ SELECT count(*) FROM sometable; double precision - 计算由(XY)对决定的最小二乘拟合的线性方程的Y-截距。 + 计算由(XY)数值对确定的最小二乘拟合线性方程的 y 轴截距。 - Yes + @@ -18467,13 +18419,13 @@ SELECT count(*) FROM sometable; 计算相关系数的平方。 - Yes + - regression slope + 回归斜率 regr_slope @@ -18482,9 +18434,9 @@ SELECT count(*) FROM sometable; double precision - 计算由(X, Y)对决定的最小二乘拟合的线性方程的斜率。 + 计算由(XY)数值对确定的最小二乘拟合线性方程的斜率。 - Yes + @@ -18496,10 +18448,9 @@ SELECT count(*) FROM sometable; double precision
- 计算自变量的平方和 - sum(X^2) - sum(X)^2/N. + 计算自变量的平方和,即sum(X^2) - sum(X)^2/N - Yes + @@ -18511,10 +18462,9 @@ SELECT count(*) FROM sometable; double precision
- 计算独立变量乘以因变量的sum of products, - sum(X*Y) - sum(X) * sum(Y)/N. + 计算自变量与因变量的乘积和,即sum(X*Y) - sum(X) * sum(Y)/N - Yes + @@ -18526,69 +18476,62 @@ SELECT count(*) FROM sometable; double precision
- 计算因变量的平方和, - sum(Y^2) - sum(Y)^2/N. + 计算因变量的平方和,即sum(Y^2) - sum(Y)^2/N - Yes + - standard deviation + 标准差 stddev stddev ( numeric_type ) - double precision - for real or double precision, - otherwise numeric + 对于realdouble precision输入,返回double precision;否则返回numeric - 这是stddev_samp的一个历史别称。 + 这是stddev_samp的一个历史别名。 - Yes + - standard deviation - population + 标准差 + 总体 stddev_pop stddev_pop ( numeric_type ) - double precision - for real or double precision, - otherwise numeric + 对于realdouble precision输入,返回double precision;否则返回numeric 计算输入值的总体标准差。 - Yes + - standard deviation - sample + 标准差 + 样本 stddev_samp stddev_samp ( numeric_type ) - double precision - for real or double precision, - otherwise numeric + 对于realdouble precision输入,返回double precision;否则返回numeric 计算输入值的样本标准差。 - Yes + @@ -18597,54 +18540,48 @@ SELECT count(*) FROM sometable; variance variance ( numeric_type ) - double precision - for real or double precision, - otherwise numeric + 对于realdouble precision输入,返回double precision;否则返回numeric
- 这是 var_samp 的一个历史别称。 + 这是 var_samp 的一个历史别名。 - Yes + - variance - population + 方差 + 总体 var_pop var_pop ( numeric_type ) - double precision - for real or double precision, - otherwise numeric + 对于realdouble precision输入,返回double precision;否则返回numeric - 计算输入值的总体方差(总体标准差的平方)。 + 计算输入值的总体方差(总体标准差的平方)。 - Yes + - variance - sample + 方差 + 样本 var_samp var_samp ( numeric_type ) - double precision - for real or double precision, - otherwise numeric + 对于realdouble precision输入,返回double precision;否则返回numeric - 计算输入值的样本方差(样本标准差的平方)。 + 计算输入值的样本方差(样本标准差的平方)。 - Yes + @@ -18655,11 +18592,11 @@ SELECT count(*) FROM sometable; 这些函数有时被称为逆分布函数。 它们的聚合输入通过ORDER BY引入,还可以接受未聚合的直接参数,但后者只计算一次。 所有这些函数都会忽略其聚合输入中的空值。 - 对于使用fraction参数的函数,分数值必须在 0 到 1 之间;否则会报错。但是,如果fraction为 null,则结果也为 null。 + 对于使用fraction参数的函数,比例值必须在 0 到 1 之间;否则会报错。但是,如果fraction为 null,则结果也为 null。
- ordered-set aggregate + 有序集聚合 内置 @@ -18691,16 +18628,16 @@ SELECT count(*) FROM sometable; - mode - statistical + 众数 + 统计 mode () WITHIN GROUP ( ORDER BY anyelement ) anyelement - 计算mode,即聚合参数最频繁的值(如果有多个相同频繁的值,第一个可以任意选择)。聚合参数必须是可排序类型。 + 计算众数,即聚合参数中出现次数最多的值(若多个值的出现次数相同且最多,则任意选择其中第一个)。聚合参数必须是可排序类型。 - No + @@ -18718,9 +18655,9 @@ SELECT count(*) FROM sometable; 计算连续百分位点,该值对应于聚合参数值有序集合中的指定fraction。 - 如果需要,这将在相邻的输入项之间插入。 + 必要时会在相邻输入项之间进行插值。 - No + @@ -18735,7 +18672,7 @@ SELECT count(*) FROM sometable; 计算多个连续百分位点。结果是一个与fractions参数具有相同维度的数组,其中每个非空元素都被替换为对应百分位点的值(必要时会进行插值)。 - No + @@ -18751,7 +18688,7 @@ SELECT count(*) FROM sometable; 计算离散百分位数,即聚合参数值的有序集合中的第一个值,该值在排序中的位置等于或超过指定的fraction。 聚合参数必须是可排序类型。 - No + @@ -18764,14 +18701,14 @@ SELECT count(*) FROM sometable; 结果是一个与fractions参数具有相同维数的数组,每个非空元素都被对应于该百分位数的输入值替换。 聚合参数必须是可排序类型。 - No + - hypothetical-set aggregate + 假想集聚合 内置 @@ -18807,52 +18744,52 @@ SELECT count(*) FROM sometable; rank - hypothetical + 假设行 rank ( args ) WITHIN GROUP ( ORDER BY sorted_args ) bigint - 计算假设行的排名,包括间隔,就是说在它的同等行组中第一行的行号。 + 计算假设行的排名,允许空缺;即该行所属同等行组中第一行的行号。 - No + dense_rank - hypothetical + 假设行 dense_rank ( args ) WITHIN GROUP ( ORDER BY sorted_args ) bigint - 计算假设行的排名,没有间隔;这个功能有效地计数同等行组。 + 计算假设行的排名,没有空缺;此函数实际上对同等行组进行计数。 - No + percent_rank - hypothetical + 假设行 percent_rank ( args ) WITHIN GROUP ( ORDER BY sorted_args ) double precision - 计算假设行的相关排行,也就是(rank - 1) / (total rows - 1)。取值范围为 0 到 1(含)。 + 计算假设行的相对排名,即(rank - 1)/(总行数 - 1)。取值范围为 0 到 1(含)。 - No + cume_dist - hypothetical + 假设行 cume_dist ( args ) WITHIN GROUP ( ORDER BY sorted_args ) double precision @@ -18860,7 +18797,7 @@ SELECT count(*) FROM sometable; 计算累积分布,也就是(位于假设行之前或与假设行同等的行数)/(总行数)。取值范围为 1/N 到 1。 - No + @@ -18893,8 +18830,7 @@ SELECT count(*) FROM sometable; integer - 返回一个位掩码以指示哪个GROUP BY表达式没有包含在当前分组集中。 - 比特位被分配给最右边的参数对应于最低有效位;如果对应的表达式包含在生成当前结果行的分组集的分组条件中,则每个位为0,如果不包含则为1。 + 返回一个位掩码,指示哪些GROUP BY表达式未包含在当前分组集中。分配比特位时,最右侧参数对应最低有效位;如果相应表达式包含在生成当前结果行的分组集的分组条件中,该位为 0,否则为 1。 @@ -18902,9 +18838,7 @@ SELECT count(*) FROM sometable; - 所示的分组操作与分组集(参见)共同使用,以区分结果行。 - GROUPING函数的参数实际上并不求值,但它们必须与相关查询级别的GROUP BY子句中给出的表达式完全匹配。例如: - + 在中列出的分组操作与分组集配合使用(参见),以区分结果行。传给GROUPING函数的参数不会实际求值,但它们必须与相关查询层级的GROUP BY子句中的表达式完全匹配。例如: => SELECT * FROM items_sold; make | model | sales -------+-------+------- @@ -18925,9 +18859,7 @@ SELECT count(*) FROM sometable; Bar | | 1 | 20 | | 3 | 50 (7 rows) - - 在这里,前四行中的grouping0表明这些已经正常分组,在两个分组列上。 - 值1表示model没有在倒数两行中分组,值3表示无论是make还是model都没有在最后一行中分组(因此,这是所有输入行的聚合)。 +这里,前四行的grouping值为0,表明这些行按两个分组列正常分组。值1表明model未用于倒数第二、第三行的分组,值3则表明最后一行既未按make分组,也未按model分组(因此该行聚合了全部输入行)。 @@ -18951,7 +18883,7 @@ SELECT count(*) FROM sometable; - 除了这些函数之外,任何内置的或用户定义的普通聚合(例如非有序集或假想集聚合)都可以作为窗口函数使用;关于内置聚合的列表,参见。 + 除了这些函数之外,任何内置的或用户定义的普通聚合(即不属于有序集或假想集聚合)都可以作为窗口函数使用;关于内置聚合的列表,参见。 聚合函数只有在调用后带有OVER子句时才作为窗口函数;否则,它们就是普通聚合,并为整个结果集返回一行。 @@ -18982,7 +18914,7 @@ SELECT count(*) FROM sometable; bigint - 返回其分区内的当前行数,从1开始计数。 + 返回当前行在其分区内的编号,从 1 开始计数。 @@ -18995,7 +18927,7 @@ SELECT count(*) FROM sometable; bigint - 返回当前行的排名,包含间隔;即同等行组中第一行的row_number。 + 返回当前行的排名,允许空缺;即同等行组中第一行的row_number @@ -19008,7 +18940,7 @@ SELECT count(*) FROM sometable; bigint - 返回当前行的排名,不包括间隔;这个功能有效地计数同等行组。 + 返回当前行的排名,没有空缺;此函数实际上对同等行组进行计数。 @@ -19047,7 +18979,7 @@ SELECT count(*) FROM sometable; integer - 返回一个从1到参数值的整数,并将分区划分为尽可能相等的值。 + 返回从 1 到参数值的整数,将分区尽可能均等地划分。 @@ -19062,9 +18994,7 @@ SELECT count(*) FROM sometable; anycompatible - 返回分区中在当前行之前offset行的value;如果没有这样的行,则返回default(必须与value相兼容的类型)。 - offsetdefault都是针对当前行求值的。 - 如果省略,offset默认为1,defaultNULL。 + 返回在分区内当前行之前offset行处计算的value;如果没有这样的行,则返回default(其类型必须与value兼容)。offsetdefault都针对当前行求值。如果省略,offset默认为 1,default默认为NULL @@ -19079,10 +19009,7 @@ SELECT count(*) FROM sometable; anycompatible - 返回分区中在当前行之后offset行的value; - 如果没有这样的行,则返回default(必须与value兼容的类型)。 - offsetdefault都是针对当前行求值的。 - 如果省略,offset默认为1,defaultNULL。 + 返回在分区内当前行之后offset行处计算的value;如果没有这样的行,则返回default(其类型必须与value兼容)。offsetdefault都针对当前行求值。如果省略,offset默认为 1,default默认为NULL @@ -19137,14 +19064,14 @@ SELECT count(*) FROM sometable; 注意first_valuelast_valuenth_value只考虑窗口帧内的行,它默认情况下包含从分区的开始行直到当前行的最后一个同等行。 这对last_value可能不会给出有用的结果,有时对nth_value也一样。 - 你可以通过向OVER子句增加一个合适的帧声明(RANGEGROUPS)来重定义帧。 + 你可以通过向OVER子句增加一个合适的帧声明(RANGEROWSGROUPS)来重定义帧。 关于帧声明的更多信息请参考 当一个聚合函数被用作窗口函数时,它将在当前行的窗口帧内的行上聚合。 - 一个使用ORDER BY和默认窗口帧定义的聚合产生一种运行时求和类型的行为,这可能是或者不是想要的结果。 - 为了获取在整个分区上的聚合,忽略ORDER BY或者使用ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING。 + 一个使用ORDER BY和默认窗口帧定义的聚合产生一种累计求和类型的行为,这可能是或者不是想要的结果。 + 为了获取在整个分区上的聚合,省略ORDER BY或者使用ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING。 其它窗口帧声明可以用来获得其它的效果。 @@ -19153,7 +19080,7 @@ SELECT count(*) FROM sometable; SQL 标准为leadlagfirst_valuelast_valuenth_value定义了一个RESPECT NULLSIGNORE NULLS选项。 这在PostgreSQL中没有实现:行为总是与标准的默认相同,即RESPECT NULLS。 - 同样,标准中用于nth_valueFROM FIRSTFROM LAST选项没有实现: 只有支持默认的FROM FIRST行为(你可以通过反转ORDER BY的排序达到FROM LAST的结果)。 + 同样,标准中用于nth_valueFROM FIRSTFROM LAST选项没有实现: 只支持默认的FROM FIRST行为(你可以通过反转ORDER BY的排序达到FROM LAST的结果)。 @@ -19188,11 +19115,11 @@ SELECT count(*) FROM sometable; - subquery + 子查询 - 本节描述PostgreSQL中可用的SQL兼容的子查询表达式。所有本节中成文的表达式都返回布尔值(真/假)结果。 + 本节描述PostgreSQL中可用的SQL兼容的子查询表达式。本节介绍的所有表达式形式都返回布尔值(真/假)结果。 @@ -19207,7 +19134,7 @@ EXISTS (subquery) - 子查询可以引用来自周围的查询的变量,这些变量在该子查询的任何一次计算中都起常量的作用。 + 子查询可以引用外层查询的变量,这些变量在该子查询的任何一次计算中都起常量的作用。 @@ -19219,7 +19146,7 @@ EXISTS (subquery) - 下面这个简单的示例类似在col2上的一次内联接,但是它为每个 tab1的行生成最多一个输出,即使存在多个匹配tab2的行也如此∶ + 下面这个简单的示例类似在col2上的一次内连接,但是它为每个 tab1的行最多生成一行输出,即使存在多个匹配tab2的行也如此: SELECT col1 FROM tab1 @@ -19240,7 +19167,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 请注意如果左手边表达式得到空值,或者没有相等的右手边值, 并且至少有一个右手边行得到空值,那么IN结构的结果将是空值,而不是假。这个行为是遵照 SQL 处理空值的一般规则的。 + 请注意,如果左侧表达式得到空值,或者右侧没有相等的值且至少有一行得到空值,则IN结构的结果将是空值,而不是假。这符合 SQL 对空值布尔组合的一般规则。 @@ -19272,7 +19199,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 请注意如果左手边表达式得到空值,或者没有相等的右手边值, 并且至少有一个右手边行得到空值,那么NOT IN结构的结果将是空值,而不是真。这个行为是遵照 SQL 处理空值的一般规则的。 + 请注意,如果左侧表达式得到空值,或者右侧没有相等的值且至少有一行得到空值,则NOT IN结构的结果将是空值,而不是真。这符合 SQL 对空值布尔组合的一般规则。 @@ -19284,7 +19211,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 这种形式的NOT IN左手边是一个行构造器,如中所述。右手边是一个圆括号括起来的子查询,它必须返回与左手边行中表达式数量完全相同的列数。左手边表达式会被求值,并与子查询结果逐行比较。如果只找到不相等的子查询行,则NOT IN的结果为;如果找到相等行,那么结果为(包括子查询不返回任何行的情况)。 + 这种形式的NOT IN左侧是一个行构造器,如中所述。右侧是一个用圆括号括起来的子查询,必须返回与左侧行中表达式数量完全相同的列数。对左侧表达式求值后,将其按行与子查询结果的每一行比较。如果只找到不相等的子查询行(包括子查询不返回任何行的情况),则NOT IN的结果为。如果找到任何相等行,则结果为 @@ -19302,7 +19229,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 这种形式的右侧是一个圆括号括起来的子查询,它必须恰好返回一列。左侧表达式会被求值,并使用给定的operator与子查询结果的每一行进行比较。如果得到任何真值结果,那么ANY的结果就是。如果没有找到真值结果,那么结果就是(包括子查询不返回任何行的情况)。 + 这种形式的右侧是一个用括号括起来的子查询,它必须恰好返回一列。左侧表达式会被求值,并使用给定的 operator 与子查询结果的每一行进行比较。该操作符必须产生布尔结果。如果得到任何真值结果,那么ANY的结果就是。如果没有找到真值结果,那么结果是(包括子查询没有返回任何行的情况)。 @@ -19310,7 +19237,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 请注意,如果没有任何比较成功,并且至少有一个右手边行会为该操作符产生空值结果,那么ANY结构的结果将是空值,而不是假。这一行为符合 SQL 处理空值布尔组合的一般规则。 + 请注意,如果没有任何比较返回真,并且至少有一个右侧行的操作符结果为空值,则ANY结构的结果将是空值,而不是假。这符合 SQL 对空值布尔组合的一般规则。 @@ -19323,7 +19250,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 这种形式的左侧是一个行构造器,如所述。右侧是一个用括号括起来的子查询,它必须返回与左侧行中表达式数量完全相同的列数。左侧表达式会被求值,并使用给定的operator与子查询结果的每一行逐行比较。如果比较对任何子查询行返回真,则ANY的结果为。如果比较对每一个子查询行都返回假,则结果为(包括子查询不返回行的情况)。如果比较对任何行都不返回真,并且至少有一次比较返回 NULL,则结果为 NULL。 + 这种形式的ANY左侧是一个行构造器,如所述。右侧是一个用括号括起来的子查询,它必须返回与左侧行中表达式数量完全相同的列数。左侧表达式会被求值,并使用给定的operator与子查询结果的每一行逐行比较。如果比较对任何子查询行返回真,则ANY的结果为。如果比较对每一个子查询行都返回假,则结果为(包括子查询不返回行的情况)。如果比较对任何行都不返回真,并且至少有一次比较返回 NULL,则结果为 NULL。 @@ -19339,7 +19266,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 这种形式的ALL右侧是一个圆括号括起来的子查询,它必须只返回一列。左侧表达式会被求值,并使用给定的operator与子查询结果的每一行进行比较。该操作符必须产生布尔结果。如果所有行都得到真(包括子查询不返回任何行的情况),ALL的结果就是。如果发现任何假值结果,结果就是。如果比较对任何行都不返回假,并且至少有一次比较返回 NULL,则结果为 NULL。 + 右侧是一个用圆括号括起来的子查询,必须恰好返回一列。左侧表达式会被求值,并使用给定的operator与子查询结果的每一行进行比较。该操作符必须产生布尔结果。如果所有行都得到真(包括子查询不返回任何行的情况),则ALL的结果为。如果得到任何假值结果,则结果为。如果与任何子查询行的比较都不返回假,并且至少有一次比较返回 NULL,则结果为 NULL。 @@ -19377,7 +19304,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 左手边是一个行构造器,如所述。右手边是一个圆括号括起来的子查询,该子查询必须返回与左手边行中表达式数目完全相同的列数。此外,该子查询不能返回超过一行;如果它返回零行,那么结果就是空值。左手边会被求值,并与右手边的子查询结果行逐行比较。 + 左侧是一个行构造器,如所述。右侧是一个用圆括号括起来的子查询,必须返回与左侧行中表达式数量完全相同的列数。此外,该子查询不能返回超过一行;如果它返回零行,则结果为空值。对左侧求值后,将所得的行与子查询返回的唯一一行进行比较。 @@ -19416,12 +19343,12 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 逐行比较 + 行比较 比较 - 逐行 + 复合类型 @@ -19438,7 +19365,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 本节描述几个特殊的结构,用于在值的组之间进行多重比较。这些形式语法上和前面一节的子查询形式相关,但是不涉及子查询。 这种形式涉及的数组子表达式是PostgreSQL的扩展; 其它的是SQL兼容的。所有本节记录的表达式形式都返回布尔(Boolean)结果(真/假)。 + 本节描述几个特殊的结构,用于在值的组之间进行多重比较。这些形式语法上和前面一节的子查询形式相关,但是不涉及子查询。 涉及数组子表达式的形式是PostgreSQL的扩展; 其余形式是SQL兼容的。本节介绍的所有表达式形式都返回布尔(Boolean)结果(真/假)。 @@ -19449,14 +19376,12 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 右侧是一个用括号括起来的表达式列表。如果左侧表达式的结果等于右侧任何一个表达式的结果,则结果为true。 - 这是一个简写表示法,如下所示: - + 右侧是一个用圆括号括起来的表达式列表。如果左侧表达式的结果等于右侧任一表达式的结果,则结果为。这等价于以下写法: expression = value1 -或 +OR expression = value2 -或 +OR ... @@ -19474,9 +19399,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 右侧是一个用括号括起来的表达式列表。如果左侧表达式的结果与所有右侧表达式都不相等,则结果为true。 - 这是一个简写表示法,用于 - + 右侧是一个用圆括号括起来的表达式列表。如果左侧表达式的结果与右侧所有表达式的结果都不相等,则结果为。这等价于以下写法: expression <> value1 AND @@ -19500,7 +19423,7 @@ AND - <literal>ANY</literal>/<literal>SOME</literal> (array) + <literal>ANY</literal>/<literal>SOME</literal>(数组) expression operator ANY (array expression) @@ -19522,7 +19445,7 @@ AND - <literal>ALL</literal> (array) + <literal>ALL</literal>(数组) expression operator ALL (array expression) @@ -19546,20 +19469,7 @@ AND - 每一边都是一个行构造器, - 如在中描述的那样。 - 这两个行构造器必须具有相同数量的字段。 - 给定的operator应用于每一对 - 对应的字段。(由于字段可能是不同类型的,这意味着每对可能选择不同的具体操作符。) - 所有选定的操作符必须是某个B-树操作符类的成员,或者是B-树操作符类的=成员的否定形式, - 这意味着只有当operator是 - =、 - <>、 - <、 - <=、 - >或 - >=时才可能进行行构造器比较, - 或者具有类似于这些操作符的语义。 + 两侧都是行构造器,如所述。两个行构造器必须具有相同数量的字段。给定的operator应用于每一对对应字段。(由于字段可能具有不同的类型,因此可能为各对字段选择不同的具体操作符。)所选操作符必须是某个 B-树操作符类的成员,或者是 B-树操作符类中=成员的否定操作符。这意味着只有当operator=<><<=>>=,或具有与这些操作符类似的语义时,才可以进行行构造器比较。 @@ -19570,12 +19480,7 @@ AND 对于<<=>>=这几种情况,会从左到右比较各行元素,一旦找到一对不相等或含有 NULL 的元素就立即停止。如果这对元素中的任意一个为 NULL,那么行比较的结果就是未知(NULL);否则,这对元素的比较结果决定整个行比较的结果。例如,ROW(1,2,NULL) < ROW(1,3,0)的结果为真,而不是 NULL,因为第三对元素不会被考虑。 - - - 在PostgreSQL 8.2 之前,<<=>>=这几种情况并不是按照 SQL 规范处理的。像ROW(a,b) < ROW(c,d)这样的比较会被实现为a < c AND b < d,而正确行为应当等价于a < c OR (a = c AND b < d)。 - - row_constructor IS DISTINCT FROM row_constructor @@ -19604,21 +19509,21 @@ AND - SQL 规范要求在结果依赖于比较两个 NULL 值或者一个 NULL 与一个非 NULL 时逐行比较返回 NULL。 + SQL 规范要求在结果依赖于比较两个 NULL 值或者一个 NULL 与一个非 NULL 时行比较返回 NULL。 PostgreSQL只有在比较两个行构造器(如)的结果或者比较一个行构造器与一个子查询的输出时才这样做(如中所述)。 - 在其他比较两个复合类型值的环境中,两个 NULL 域值被认为相等,并且一个 NULL 被认为大于一个非 NULL。 + 在其他比较两个复合类型值的环境中,两个 NULL 字段值被认为相等,并且一个 NULL 被认为大于一个非 NULL。 为了得到复合类型的一致的排序和索引行为,这样做是必要的。 - 每一边都会被计算并且它们会被逐行比较。当operator是 + 对两侧分别求值后,按行进行比较。当operator=<><<=>或者 - >=时或者具有与这些类似的语义时,允许复合类型的比较(更准确地说,如果一个操作符是一个 B-树操作符类的成员,或者是一个 B-树操作符类的=成员的否定词,它就可以是一个行比较操作符)。 - 上述操作符的行为与用于行构造器(见)的IS [ NOT ] DISTINCT FROM相同。 + >=时或者具有与这些类似的语义时,允许复合类型的比较(更准确地说,如果一个操作符是一个 B-树操作符类的成员,或者是一个 B-树操作符类的=成员的否定操作符,它就可以是一个行比较操作符)。 + 上述操作符的默认行为与用于行构造器(见)的IS [ NOT ] DISTINCT FROM相同。 @@ -19629,9 +19534,9 @@ AND *<=*>以及 *>=。 - 这些操作符比较两行的内部二进制表达。即使两行用相等操作符的比较为真,两行也可能具有不同的二进制表达。 - 行在这些比较操作符之下的排序是决定性的,其他倒没什么意义。 - 这些操作符在内部被用于物化视图并且可能对其他如复制和B-树复制(参见 )之类的特殊功能有用,但是它们并不打算用在书写查询这类普通用途中。 + 这些操作符比较两行的内部二进制表示。即使两行用相等操作符的比较为真,两行也可能具有不同的二进制表示。 + 使用这些比较操作符得到的行排序是确定的,但除此之外没有其他意义。 + 这些操作符在内部被用于物化视图并且可能对其他如复制和 B-树去重(参见 )之类的特殊功能有用,但是它们并不打算用在书写查询这类普通用途中。 @@ -19646,13 +19551,13 @@ AND - 本节描述那些可能返回多于一行的函数。目前这个类中被使用最广泛的是级数生成函数, 如所述。其他更特殊的集合返回函数在本手册的其他地方描述。 - 组合多集合返回函数的方法可见。 + 本节描述那些可能返回多于一行的函数。目前这个类中被使用最广泛的是序列生成函数, 如所述。其他更特殊的集合返回函数在本手册的其他地方描述。 + 组合多个集合返回函数的方法可见 - 级数生成函数 + 序列生成函数 @@ -19708,9 +19613,7 @@ AND
- 当step为正时,如果start大于stop则返回零行。 - 相反,当step为负时,如果start小于stop则返回零行。 - 如果任何输入为NULL也会返回零行。step为零是一个错误。下面是一些示例: + 当step为正数时,如果start大于stop,则返回零行。反之,当step为负数时,如果start小于stop,则返回零行。如果任一输入为NULL,也返回零行。如果step为零,则会报错。下面是一些示例: SELECT * FROM generate_series(2,4); generate_series @@ -19741,7 +19644,7 @@ SELECT generate_series(1.1, 4, 1.3); 3.7 (3 rows) --- this example relies on the date-plus-integer operator: +-- 此示例使用日期加整数的操作符: SELECT current_date + s.a AS dates FROM generate_series(0,14,7) AS s(a); dates ------------ @@ -19765,7 +19668,7 @@ SELECT * FROM generate_series('2008-03-01 00:00'::timestamp, 2008-03-04 08:00:00 (9 rows) --- 此示例假定 TimeZone 设置为 UTC;注意 DST 转换: +-- 此示例假定 TimeZone 设为 UTC;请注意夏令时(DST)切换: SELECT * FROM generate_series('2001-10-22 00:00 -04:00'::timestamptz, '2001-11-01 00:00 -05:00'::timestamptz, '1 day'::interval, 'America/New_York'); @@ -19813,7 +19716,7 @@ SELECT * FROM generate_series('2001-10-22 00:00 -04:00'::timestamptz, setof integer - 生成一个包含给定数组第dim维度的有效下标的序列。 + 生成一个包含给定数组第dim维的有效下标的序列。 @@ -19823,7 +19726,7 @@ SELECT * FROM generate_series('2001-10-22 00:00 -04:00'::timestamptz, setof integer
- 生成一个包含给定数组第dim维度的有效下标的序列。当reverse为真时,以相反的顺序返回序列。 + 生成一个包含给定数组第dim维的有效下标的序列。当reverse为真时,以相反的顺序返回序列。 @@ -19832,9 +19735,9 @@ SELECT * FROM generate_series('2001-10-22 00:00 -04:00'::timestamptz, generate_subscripts是一个快捷函数,它为给定数组的指定维度生成一组合法的下标。 - 对于不具有请求维度的数组返回零行,对于任何输入为NULL数组也返回零行。下面是一些示例: + 如果数组不具有所请求的维度,或者任一输入为NULL,则返回零行。下面是一些示例: --- basic usage: +-- 基本用法: SELECT generate_subscripts('{NULL,1,NULL,2}'::int[], 1) AS s; s --- @@ -19844,8 +19747,8 @@ SELECT generate_subscripts('{NULL,1,NULL,2}'::int[], 1) AS s; 4 (4 rows) --- presenting an array, the subscript and the subscripted --- value requires a subquery: +-- 展示数组、下标和下标对应的值 +-- 需要使用子查询: SELECT * FROM arrays; a -------------------- @@ -19864,7 +19767,7 @@ FROM (SELECT generate_subscripts(a, 1) AS s, a FROM arrays) foo; {100,200,300} | 3 | 300 (5 rows) --- unnest a 2D array: +-- 展开二维数组: CREATE OR REPLACE FUNCTION unnest2(anyarray) RETURNS SETOF anyelement AS $$ select $1[i][j] @@ -19884,15 +19787,13 @@ SELECT * FROM unnest2(ARRAY[[1,2],[3,4]]); - ordinality + 序号 - 当FROM子句中的函数以WITH ORDINALITY作为后缀时,将在函数的输出列上附加一个bigint列,该列从1开始,函数输出的每一行加1。 - 这在 unnest()等集合返回函数的情况下最有用。 - + 当FROM子句中的函数后面加上WITH ORDINALITY时,一个bigint列会追加到函数的输出列中,其值从 1 开始,对函数输出的每一行递增 1。这种方式对集合返回函数尤其有用,例如unnest() --- set returning function WITH ORDINALITY: +-- 集合返回函数与 WITH ORDINALITY: SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); ls | n -----------------+---- @@ -19925,11 +19826,15 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); 系统信息函数和操作符 + + 本节描述的函数用于获取有关PostgreSQL安装的各种信息。 + + 会话信息函数 - 展示了多个可以抽取会话和系统信息的函数。 + 列出了多个用于提取会话和系统信息的函数。 @@ -19970,7 +19875,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); name - 返回当前数据库的名称。(在SQL标准中数据库被称为catalogs,因此current_catalog是该标准的拼写方式。) + 返回当前数据库的名称。(SQL 标准将数据库称为目录(catalogs),因此current_catalog是标准中的写法。) @@ -19983,7 +19888,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); text - 返回当前所执行查询的文本,由客户端提交的(可能包含一个以上的语句)。 + 返回客户端提交的当前正在执行的查询文本(可能包含多条语句)。 @@ -20006,8 +19911,8 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); current_schema - schema - current + 模式 + 当前 current_schema name @@ -20028,16 +19933,14 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); current_schemas - search path - current + 搜索路径 + 当前 current_schemas ( include_implicit boolean ) name[]
- 返回当前在有效搜索路径中的所有模式的名称的数组,以优先级顺序。 - (当前 设置中与已存在的、可搜索模式不相符的项将被省略。) - 如果布尔参数为true,则类似pg_catalog的隐式搜索的系统模式将包含在结果中。 + 返回当前有效搜索路径中所有模式名称的数组,按优先级排序。(当前设置中不对应于已存在且可搜索的模式的项会被省略。)如果布尔参数为true,结果还会包含pg_catalog等隐式搜索的系统模式。 @@ -20047,8 +19950,8 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); current_user - user - current + 用户 + 当前 current_user name @@ -20067,7 +19970,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); inet
- 返回当前客户端的IP地址,如果当前连接是通过Unix-域套接字则返回NULL + 返回当前客户端的 IP 地址;如果当前连接通过 Unix 域套接字建立,则返回NULL @@ -20080,7 +19983,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); integer
- 返回当前客户端的IP端口号,如果当前连接是通过Unix-域套接字则返回NULL。 + 返回当前客户端的IP端口号,如果当前连接是通过Unix 域套接字则返回NULL @@ -20093,7 +19996,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); inet
- 返回服务器接受当前连接的IP地址,如果当前连接是通过Unix-域套接字则返回NULL。 + 返回服务器接受当前连接的IP地址,如果当前连接是通过Unix 域套接字则返回NULL @@ -20106,7 +20009,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); integer
- 返回服务器接受当前连接的IP端口号,如果当前连接是通过Unix-域套接字则返回NULL。 + 返回服务器接受当前连接的IP端口号,如果当前连接是通过Unix 域套接字则返回NULL @@ -20132,12 +20035,10 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); integer[]
- 返回阻止服务器进程的会话的进程ID数组,该进程ID与指定的进程ID一起获取锁定,如果没有这样的服务器进程或者没有被阻塞,则返回一个空数组。 + 返回一个数组,包含阻止指定进程 ID 对应的服务器进程获取锁的会话进程 ID;如果不存在这样的服务器进程,或该进程未被阻塞,则返回空数组。 - 如果一个服务器进程持有一个与被阻塞进程的锁请求冲突的锁(硬阻塞),或者正在等待一个与被阻塞进程的锁请求冲突并且在等待队列中位于其前面的锁(软阻塞),那么这个服务器进程就会阻塞另一个服务器进程。 - 当使用并行查询时结果总是列出客户端可见的进程ID(即pg_backend_pid的结果),即使实际的锁是由子工作进程持有或等待的。 - 因此,结果中可能存在重复的pid。还要注意当准备好的事务持有冲突锁时,它将用零进程ID表示。 + 一个服务器进程会在以下情况下阻塞另一个进程:它持有与被阻塞进程请求的锁冲突的锁(硬阻塞);或者它正在等待一个会与被阻塞进程请求的锁冲突的锁,并且在等待队列中位于被阻塞进程之前(软阻塞)。使用并行查询时,即使实际持锁或等待锁的是子工作进程,结果也始终列出客户端可见的进程 ID(即pg_backend_pid的结果)。因此,结果中可能出现重复的 PID。另外,如果持有冲突锁的是一个预备事务,结果中会用进程 ID 0 表示它。 频繁调用这个函数可能会对数据库性能产生一些影响,因为它需要在短时间内独占访问锁管理器的共享状态。 @@ -20153,8 +20054,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); timestamp with time zone - 返回服务器配置文件最后加载的时间。如果当前会话当时是活跃的,那么这将是会话本身重新读取配置文件的时间(因此在不同的会话中读取会稍有不同)。 - 否则,就是postmaster进程重新读取配置文件的时间。 + 返回服务器配置文件最近一次加载的时间。如果当时当前会话已经存在,则返回该会话自身重新读取配置文件的时间(因此不同会话中的返回时间会略有不同)。否则,返回 postmaster 进程重新读取配置文件的时间。 @@ -20164,16 +20064,16 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); pg_current_logfile - Logging - pg_current_logfile函数 + 日志记录 + pg_current_logfile 函数 current_logfiles - 和pg_current_logfile函数 + 和pg_current_logfile 函数 - Logging - current_logfiles文件和pg_current_logfile函数 + 日志记录 + current_logfiles 文件和pg_current_logfile 函数 pg_current_logfile ( text ) text @@ -20188,9 +20088,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); 如果请求的日志格式未在中配置,则结果为NULL。 结果反映current_logfiles文件的内容。 - - 默认情况下,此函数仅限于超级用户以及具有pg_monitor角色权限的角色,但可以向其他用户授予 EXECUTE 权限以运行该函数。 - + @@ -20254,7 +20152,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); double precision - 返回当前被等待处理的通知所占用的异步通知队列最大尺寸的分数(0–1)。更多信息请参见。 + 返回待处理通知当前占用的空间占异步通知队列最大容量的比例(0–1)。更多信息请参见 @@ -20280,11 +20178,11 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); integer[] - 返回一个进程ID数组,该进程ID是阻塞服务器进程获取安全快照的会话的进程ID数组,如果没有这样的服务器进程或者没有阻塞,则返回一个空数组。 + 返回一个数组,包含阻止指定进程 ID 对应的服务器进程获取安全快照的会话进程 ID;如果不存在这样的服务器进程,或该进程未被阻塞,则返回空数组。 运行SERIALIZABLE事务的会话会阻止SERIALIZABLE READ ONLY DEFERRABLE事务获取快照,直到后者确定可以安全地避免获取谓词锁。 - 关于可串行化和可延迟事务的更多信息,请参见。 + 关于可序列化和可延迟事务的更多信息,请参见 频繁调用这个函数可能会对数据库性能产生一些影响,因为它需要在短时间内访问谓词锁管理器的共享状态。 @@ -20300,7 +20198,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); integer - 返回当前嵌套层次的PostgreSQL触发器(如果没有调用则为 0,直接或间接,从一个触发器内部开始)。 + 返回PostgreSQL触发器的当前嵌套层级(如果不是从触发器内部直接或间接调用,则为 0)。 @@ -20313,7 +20211,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); name - 返回会话用户名. + 返回会话用户名。 @@ -20343,7 +20241,8 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); - + + version @@ -20352,9 +20251,12 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); text - 返回描述PostgreSQL服务器的版本的字符串。 - 你还可以从 中获得此信息,或者对于机器可读的版本,使用。 - 软件开发人员可以使用server_version_num(从8.2起可用)或,而不是解析文本版本。 + 返回描述PostgreSQL + 服务器版本的字符串。你还可以从 + 获得此信息,或者对于机器可读的 + 版本,使用。软件 + 开发人员应该使用server_version_num(自 8.2 起可用) + 或,而不是解析文本版本。 @@ -20364,17 +20266,12 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); - current_catalogcurrent_rolecurrent_schemacurrent_usersession_useruserSQL里有特殊的语法地位: 它们被调用时结尾不要跟着圆括号。 - 在 PostgreSQL 中,圆括号可以有选择性地被用于current_schema,但是不能和其他的一起用。 + current_catalogcurrent_rolecurrent_schemacurrent_usersession_useruserSQL中具有特殊语法:调用时不得在后面加圆括号。在 PostgreSQL 中,current_schema可以选择加圆括号,其他函数则不可以。 - session_user通常是发起当前数据库连接的用户,不过超级用户可以用修改这个设置。 - current_user是用于权限检查的用户标识。通常, 它总是等于会话用户,但是可以被改变。 - 它也会在函数执行的过程中随着属性SECURITY DEFINER的改变而改变。 - 在 Unix 的说法里,那么会话用户是真实用户,而当前用户是有效用户。 - current_role以及usercurrent_user的同义词(SQL标准在current_rolecurrent_user之间做了区分,但PostgreSQL不区分,因为它把用户和角色统一成了一种实体)。 + session_user通常是发起当前数据库连接的用户,但超级用户可以用修改此设置。current_user是用于权限检查的用户标识,通常等于会话用户,但可以用更改。在执行具有SECURITY DEFINER属性的函数期间,它也会改变。用 Unix 的术语来说,会话用户是真实用户,当前用户是有效用户current_roleusercurrent_user的同义词。(SQL 标准区分current_rolecurrent_user,但PostgreSQL不区分,因为它将用户和角色统一为同一种实体。)
@@ -20384,18 +20281,12 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); 访问权限查询函数 - privilege - querying + 权限 + 查询 - 列出那些允许编程查询对象访问权限的函数。参阅获取更多有关权限的信息。 - 在这些函数中,可以通过名称或OID (pg_authid.oid)指定被查询权限的用户,或者如果名称被指定为public,则检查PUBLIC伪角色的权限。 - 同样,user参数可以完全省略,在这种情况下,假设为current_user。被查询的对象也可以通过名称或OID来指定。 - 通过名称指定时,可以包含相关的模式名称。感兴趣的访问权限由一个文本字符串指定,它必须计算为对象类型的一个适当的权限关键字(例如,SELECT)。 - 还可以将 WITH GRANT OPTION添加到权限类型中,以测试该权限是否由授予选项持有。 - 同样,可以用逗号分隔列出多个权限类型,在这种情况下,如果所列出的权限中有任何一个被持有,结果将为真。 - (权限字符串的大小写不重要,权限名之间允许有额外的空格,但在权限名中不允许。)一些示例: + 列出了允许以编程方式查询对象访问权限的函数。(关于权限的更多信息,请参见。)在这些函数中,可以通过名称或 OID(pg_authid.oid)指定要查询权限的用户;如果名称为public,则检查 PUBLIC 伪角色的权限。也可以完全省略user参数,此时使用current_user。要查询的对象也可以通过名称或 OID 指定。通过名称指定时,如适用,可以包含模式名。所需访问权限由文本字符串指定,其值必须为适用于该对象类型的权限关键字之一(例如SELECT)。还可以在权限类型后附加WITH GRANT OPTION,以检查是否拥有该权限及其授予选项。也可以用逗号分隔列出多个权限类型;只要拥有列出的任一权限,结果就为真。(权限字符串不区分大小写,权限名之间允许有额外的空白,但权限名内部不允许。)例如: SELECT has_table_privilege('myschema.mytable', 'select'); SELECT has_table_privilege('joe', 'mytable', 'INSERT, SELECT WITH GRANT OPTION'); @@ -20432,9 +20323,7 @@ SELECT has_table_privilege('joe', 'mytable', 'INSERT, SELECT WITH GRANT OPTION') boolean - 用户是否对表的任何列有权限? - 如果对整个表持有权限,或者对至少一个列有列级的权限授予,则会成功。 - 允许的权限类型为SELECT, INSERT,UPDATE, 和 REFERENCES + 用户是否对表的至少一列具有权限?如果拥有整个表的权限,或至少一列获得了该权限的列级授权,则返回真。允许的权限类型为SELECTINSERTUPDATEREFERENCES @@ -20485,7 +20374,7 @@ SELECT has_table_privilege('joe', 'mytable', 'INSERT, SELECT WITH GRANT OPTION') boolean - 用户是否拥有外部数据包装的权限?唯一允许的权限类型是USAGE。 + 用户是否具有外部数据包装器权限?唯一允许的权限类型为USAGE @@ -20573,7 +20462,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); boolean - 用户是否有顺序权限?允许的权限类型有USAGE, SELECT, 和UPDATE。 + 用户是否具有序列权限?允许的权限类型为USAGESELECTUPDATE @@ -20605,7 +20494,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); boolean - 用户对表有权限吗?允许的权限类型有SELECTINSERTUPDATEDELETETRUNCATEREFERENCESTRIGGER。 + 用户是否具有表权限?允许的权限类型为SELECTINSERTUPDATEDELETETRUNCATEREFERENCESTRIGGER @@ -20654,11 +20543,11 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); boolean - 用户对角色有权限吗?允许的权限类型有MEMBERUSAGESET。 + 用户是否具有角色权限?允许的权限类型为MEMBERUSAGESETMEMBER表示对该角色的直接或间接成员资格,而不考虑由此授予的具体权限。 USAGE表示该角色的权限是否无需执行SET ROLE即可立即使用,而SET表示是否可以使用SET ROLE命令切换到该角色。 任一权限类型后面都可以附加WITH ADMIN OPTIONWITH GRANT OPTION,用于测试是否持有 ADMIN 权限(这六种写法测试的都是同一件事)。 - 此函数不允许特殊情况下将user设置为public,因为PUBLIC伪角色永远不能成为真实角色的成员。 + 此函数不允许将user设置为public这一特殊情况,因为 PUBLIC 伪角色永远不能成为实际角色的成员。 @@ -20672,7 +20561,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); boolean - 在当前用户和当前环境的上下文之中,指定表的行级安全是活动的吗? + 在当前用户和当前环境的上下文中,指定表的行级安全性是否生效? @@ -20680,8 +20569,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); - 显示了aclitem类型的可用操作符,它是访问权限的目录表示。 - 有关如何读取访问权限值的信息,请参阅 。 + 列出了aclitem类型可用的操作符;该类型是访问权限在系统目录中的表示形式。有关如何解读访问权限值的信息,请参见 @@ -20714,8 +20602,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); boolean - aclitem相等吗?(注意,aclitem类型缺少比较操作符的通常集合;它只有相等。 - 反而言之,aclitem数组只能进行相等比较。) + 两个aclitem是否相等?(注意,aclitem类型没有通常的整套比较操作符,而只支持相等比较。因此,aclitem数组也只能进行相等比较。) 'calvin=r*w/hobbes'::aclitem = 'calvin=r*w*/hobbes'::aclitem @@ -20732,7 +20619,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); boolean - 数组是否包含指定的权限?(如果有一个数组条目与aclitem的被授权人和授予人相匹配,并且至少具有权限的指定集,则此选项为真。) + 数组是否包含指定的权限?(如果数组中存在一个条目,其被授权者和授权者与该aclitem相同,且至少包含指定的全部权限,则返回真。) '{calvin=r*w/hobbes,hobbes=r*w*/postgres}'::aclitem[] @> 'calvin=r*/hobbes'::aclitem @@ -20744,7 +20631,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute');
- 显示了一些额外的函数来管理aclitem类型。 + 列出了一些用于管理aclitem类型的其他函数。 @@ -20776,23 +20663,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); aclitem[] - 构造一个aclitem数组,保存属于具有OID ownerId的角色的对象类型type的默认访问权限。 - 这表示当对象的ACL条目为空时将假定的访问权限。(默认访问权限在中描述。) - type参数必须是以下之一: - 'c'表示COLUMN, - 'r'表示TABLE和类似表的对象, - 's'表示SEQUENCE, - 'd'表示DATABASE, - 'f'表示FUNCTIONPROCEDURE, - 'l'表示LANGUAGE, - 'L'表示LARGE OBJECT, - 'n'表示SCHEMA, - 'p'表示PARAMETER, - 't'表示TABLESPACE, - 'F'表示FOREIGN DATA WRAPPER, - 'S'表示FOREIGN SERVER, - 或 - 'T'表示TYPEDOMAIN。 + 构造一个aclitem数组,保存类型为type、属于 OID 为ownerId的角色的对象的默认访问权限。当对象的ACL条目为空值时,会采用这些访问权限。(默认访问权限见。)type参数必须为以下值之一:'c' 表示COLUMN,'r' 表示TABLE和类似表的对象,'s' 表示SEQUENCE,'d' 表示DATABASE,'f' 表示FUNCTIONPROCEDURE,'l' 表示LANGUAGE,'L' 表示LARGE OBJECT,'n' 表示SCHEMA,'p' 表示PARAMETER,'t' 表示TABLESPACE,'F' 表示FOREIGN DATA WRAPPER,'S' 表示FOREIGN SERVER,'T' 表示TYPEDOMAIN @@ -20809,9 +20680,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); is_grantableboolean ) - 以行集的形式返回aclitem数组。如果受让人是伪角色PUBLIC,则在grantee列中用0表示。 - 每个被授予的权限都表示为SELECT, INSERT等。 - 注意,每个权限被分割成单独的一行,因此在privilege_type列中只出现一个关键字。 + 以行集的形式返回aclitem数组。如果被授权者是伪角色 PUBLIC,则在grantee列中用零表示。每项授予的权限表示为SELECTINSERT等(完整列表见)。注意,每项权限都会拆成单独的一行,因此privilege_type列中只会出现一个关键字。 @@ -20828,7 +20697,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); aclitem - 使用给定的属性构造 aclitem 。 + 使用给定的属性构造aclitemprivileges是以逗号分隔的权限名列表,例如SELECTINSERT等,列出的所有权限都会设置在结果中。(权限字符串不区分大小写,权限名之间允许有额外的空白,但权限名内部不允许。) @@ -20842,14 +20711,9 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); 模式可见性查询函数 - 展示了用于判断特定对象在当前模式搜索路径中是否可见的函数。 - 例如,如果一个表所在的模式在当前搜索路径中并且在它之前没有出现过相同的名字,这个表就被说是可见的。 - 这等价于在语句中表可以被用名称引用但不加显式的模式限定。因此,要列出所有可见表的名字: - + 列出了判断某个特定对象是否可见的函数,其判断依据是当前模式搜索路径。例如,如果表所在的模式位于搜索路径中,并且在搜索路径的更前面没有同名表,就称该表可见。这等价于说,可以只通过表名引用该表,而不必显式地用模式限定。因此,要列出所有可见表的名称: SELECT relname FROM pg_class WHERE pg_table_is_visible(oid); - - 对于函数和操作符,如果路径前面没有相同名称和参数数据类型的对象,那么搜索路径中的对象就是可见的。 - 对于操作符类和操作符族,要考虑名称和关联的索引访问方法。 +对于函数和操作符,只要搜索路径中更靠前的位置没有对象具有与被检查对象相同的名称和参数数据类型,就称被检查对象可见。对于操作符类和操作符族,会同时考虑名称及关联的索引访问方法。 @@ -20988,7 +20852,7 @@ SELECT relname FROM pg_class WHERE pg_table_is_visible(oid); boolean - 文本搜索配置在搜索路径中可见吗? + 全文检索配置是否在搜索路径中可见? @@ -21001,7 +20865,7 @@ SELECT relname FROM pg_class WHERE pg_table_is_visible(oid); boolean - 文本搜索字典在搜索路径中可见吗? + 全文检索词典是否在搜索路径中可见? @@ -21014,7 +20878,7 @@ SELECT relname FROM pg_class WHERE pg_table_is_visible(oid); boolean - 文本搜索解析器在搜索路径中可见吗? + 全文检索解析器是否在搜索路径中可见? @@ -21027,7 +20891,7 @@ SELECT relname FROM pg_class WHERE pg_table_is_visible(oid); boolean - 文本搜索模板在搜索路径中可见吗? + 全文检索模板是否在搜索路径中可见? @@ -21048,11 +20912,10 @@ SELECT relname FROM pg_class WHERE pg_table_is_visible(oid);
- 所有这些函数都要求用对象 OID 来标识将被检查的对象。如果你想用名称来测试一个对象,使用 OID 别名类型(regclassregtyperegprocedureregoperatorregconfigregdictionary)将会很方便。例如: - + 所有这些函数都需要用对象 OID 标识要检查的对象。如果想按名称测试对象,使用 OID 别名类型会很方便(regclassregtype, + regprocedureregoperatorregconfig,或regdictionary),例如: SELECT pg_type_is_visible('myschema.widget'::regtype); - - 注意以这种方式测试一个非模式限定的类型名没什么意义 — 如果该名称完全能被识别,它必须是可见的。 +注意,用这种方式测试不带模式限定的类型名并没有太大意义:只要该名称能够被识别,它就必然可见。 @@ -21142,7 +21005,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); 返回一组记录,描述存在于PostgreSQL系统目录中的外键关系。 fktable 列包含引用目录的名称,fkcols列包含引用列的名称。 类似地,pktable列包含被引用目录的名称,而pkcols列包含被引用列的名称。 - 如果is_array为真,则最后一个引用列是一个数组,其每个元素都应该与引用目录中的某个条目匹配。 + 如果is_array为真,则最后一个引用列是一个数组,其每个元素都应该与被引用目录中的某个条目匹配。 如果is_opt为真,则允许引用列包含零而不是有效引用。 @@ -21156,7 +21019,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 重构为了约束的创建命令。(这是一个反编译的重构,而不是命令的原始文本。) + 重建约束的创建命令。(这是反编译重建的结果,并非命令的原始文本。) @@ -21169,8 +21032,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 反编译存储在系统目录中的表达式的内部形式,例如列的默认值。 - 如果表达式可能包含变量,则指定它们所指向的关系的OID作为第二个参数;如果没有预期的变量,传递0就可以了。 + 反编译存储在系统目录中的表达式的内部形式,例如列的默认值。如果表达式可能包含 Var 节点,请将它们所引用的关系的 OID 指定为第二个参数;如果预计不含 Var 节点,传入零即可。 @@ -21183,8 +21045,8 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 重构为了函数或过程的创建命令。(这是一个反编译的重构,而不是命令的原始文本。) - 结果是一个完整的CREATE OR REPLACE FUNCTIONCREATE OR REPLACE PROCEDURE语句。 + 重建函数或过程的创建命令。(这是反编译重建的结果,并非命令的原始文本。) + 结果是一条完整的CREATE OR REPLACE FUNCTIONCREATE OR REPLACE PROCEDURE语句。 @@ -21197,7 +21059,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 重新构造函数或过程的参数列表,以其在 CREATE FUNCTION里面需要出现的形式(包括默认值)。 + 重建函数或过程的参数列表,采用其在CREATE FUNCTION中应有的形式(包括默认值)。 @@ -21210,7 +21072,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 重新构造标识函数或过程所需的参数列表,以其应出现在ALTER FUNCTION等命令中的形式。这个表单省略默认值。 + 重建标识函数或过程所需的参数列表,采用其在ALTER FUNCTION等命令中应有的形式。这种形式省略默认值。 @@ -21223,7 +21085,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 重构函数的RETURNS子句,以其需要出现在CREATE FUNCTION中的形式。对于过程,返回NULL。 + 重建函数的RETURNS子句,采用其在CREATE FUNCTION中应有的形式。对于过程,返回NULL @@ -21236,7 +21098,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 重构针对索引的创建命令。(这是一个反编译的重构,而不是命令的原始文本。)如果提供了column而且不为零,则只重构该列的定义。 + 重建索引的创建命令。(这是反编译重建的结果,并非命令的原始文本。)如果提供了column而且不为零,则只重建该列的定义。 @@ -21254,11 +21116,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); baredesc text ) - 返回一组描述服务器识别的SQL关键字的记录。word列包含关键字。 - catcode列包含一个类别代码:U表示无保留关键字,C表示可以是列名的关键字,T表示可以是类型或函数名的关键字,或者R表示完全保留关键字。 - 如果关键字可以在SELECT列表中用作bare列标签,则barelabel列包含true,或者false,如果它只能在AS之后使用。 - catdesc列包含可能本地化字符串,描述关键字的类别。 - baredesc列包含可能本地化的字符串,描述关键字的列标签状态。 + 返回描述服务器所识别 SQL 关键字的一组记录。word列包含关键字。catcode列包含类别代码:U表示非保留关键字,C表示可用作列名的关键字,T表示可用作类型名或函数名的关键字,R表示完全保留的关键字。如果关键字可以在SELECT列表中用作列标签,barelabel列为true;如果只能在AS之后使用,则为falsecatdesc列包含描述关键字类别的字符串,该字符串可能已被本地化。baredesc列包含描述关键字列标签状态的字符串,该字符串可能已被本地化。 @@ -21270,8 +21128,20 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 重构分区约束的定义。 - (这是反编译得到的重构结果,而不是命令的原始文本。) + 重建分区约束的定义。(这是反编译重建的结果,并非命令的原始文本。) + + + + + + + pg_get_partkeydef + + pg_get_partkeydef ( table oid ) + text + + + 重建分区表的分区键定义,采用其在CREATE TABLEPARTITION BY子句中的形式。(这是反编译重建的结果,并非命令的原始文本。) @@ -21284,7 +21154,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 重构针对规则的创建命令。(这是一个反编译的重构,而不是命令的原始文本。) + 重建规则的创建命令。(这是反编译重建的结果,并非命令的原始文本。) @@ -21299,15 +21169,15 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); 返回与列相关联的序列名称,如果没有序列与该列相关联则返回NULL。 如果列是标识列,则关联序列是在内部为该列创建的序列。 - 对于使用一种串行类型(serial, smallserial, bigserial)创建的列,它是为该串行列定义创建的序列。 + 对于使用一种 serial 类型(serial, smallserial, bigserial)创建的列,它是为该 serial 列定义创建的序列。 在后一种情况下,可以使用ALTER SEQUENCE OWNED BY修改或删除关联。 - (这个函数可能应该被称为pg_get_owned_sequence;它的当前名称反映了它在历史上曾与串行类型的列一起使用。) + (这个函数可能应该被称为pg_get_owned_sequence;它的当前名称反映了它在历史上曾与 serial 类型的列一起使用。) 第一个参数是具有可选模式的表名,第二个参数是列名。 由于第一个参数可能包含模式名和表名,因此按照通常的SQL规则解析它,这意味着默认情况下它是小写的。 第二个参数只是一个列名,按照字面来处理,因此保留了它的大小写。结果经过了适当的格式化,可以传递给序列函数(参见)。 - 典型的用法是读取序列的当前值以获取标识或串行列,示例如下: + 典型用法是读取标识列或 serial 列所用序列的当前值,例如: SELECT currval(pg_get_serial_sequence('sometable', 'id')); @@ -21323,7 +21193,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); text - 重构针对扩展统计对象的创建命令。(这是一个反编译的重构,而不是命令的原始文本。) + 重建扩展统计对象的创建命令。(这是反编译重建的结果,并非命令的原始文本。) @@ -21336,7 +21206,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); text - 重构针对触发器的创建命令。(这是一个反编译的重构,而不是命令的原始文本。) + 重建触发器的创建命令。(这是反编译重建的结果,并非命令的原始文本。) @@ -21362,7 +21232,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); text - 重构针对视图或物化视图的SELECT命令。(这是一个反编译的重构,而不是命令的原始文本。) + 重建定义视图或物化视图的SELECT命令。(这是反编译重建的结果,并非命令的原始文本。) @@ -21372,8 +21242,8 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); text - 重构针对视图或物化视图的底层SELECT命令。(这是一个反编译的重构,而不是命令的原始文本。) - 在这种形式的函数中,总是启用美观打印,并对长行进行换行,以尽量使它们小于指定的列数。 + 重建定义视图或物化视图的SELECT命令。(这是反编译重建的结果,并非命令的原始文本。) + 这种形式始终启用美化输出,并将长行折行,尽量使每行长度小于指定列数。 @@ -21383,7 +21253,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); text - 根据视图的文本名称而不是它的OID,重构针对视图或物化视图的底层SELECT命令。(这是弃用;请使用OID变体。) + 根据视图的文本名称而不是其 OID,重建定义视图或物化视图的SELECT命令。(此形式已弃用;请使用 OID 变体。) @@ -21396,7 +21266,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); boolean - 测试一个索引列是否具有命名属性。列出了常用索引列属性。 + 测试一个索引列是否具有指定名称的属性。列出了常用索引列属性。 (注意,扩展访问方法可以为其索引定义额外的属性名。) 如果属性名未知或不适用于特定对象,或者OID或列号不能识别有效的对象,则返回NULL @@ -21411,7 +21281,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); boolean - 测试一个索引是否具有命名属性。列出了常用的索引属性。 + 测试一个索引是否具有指定名称的属性。列出了常用的索引属性。 (注意,扩展访问方法可以为其索引定义额外的属性名。) 如果属性名未知或不适用于特定对象,或者OID不能识别有效的对象,则返回NULL @@ -21426,7 +21296,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); boolean - 测试索引访问方法是否具有命名属性。访问方法属性如所示。 + 测试索引访问方法是否具有指定名称的属性。访问方法属性如所示。 如果属性名未知或不适用于特定对象,或者OID不能识别有效的对象,则返回NULL @@ -21455,9 +21325,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); text[] - 返回与给定GUC相关联的标志数组,如果不存在则返回NULL。 - 如果GUC存在但没有要显示的标志,则结果为空数组。 - 仅公开列出在中最有用的标志。 + 返回与给定 GUC 关联的标志数组;如果该 GUC 不存在,则返回NULL。如果 GUC 存在但没有要显示的标志,则结果为空数组。此函数仅公开中列出的最有用的标志。 @@ -21470,9 +21338,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); setof oid - 返回具有存储在指定表空间中的对象的数据库的OIDs集。 - 如果这个函数返回了任何行,那么表空间就不是空的,且不能被删除。 - 要识别填充表空间的特定对象,需要连接到由pg_tablespace_databases标识的数据库,并查询它们的pg_class目录。 + 返回在指定表空间中存储了对象的数据库 OID 集合。如果此函数返回任何行,则说明该表空间不为空,不能删除。要查看存放在该表空间中的具体对象,需要连接到pg_tablespace_databases标识的数据库,并查询它们的pg_class系统目录。 @@ -21498,12 +21364,10 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); regtype - 返回传递值给它的数据类型的OID。这对于故障排除或动态构造SQL查询很有帮助。 - 函数声明为返回regtype,它是一个OID别名类型(see ); - 这意味着,为了比较,它与OID相同,但显示为类型名。 + 返回所传入值的数据类型的 OID。这有助于排查问题或动态构造 SQL 查询。函数声明的返回类型是regtype,它是一种 OID 别名类型(参见);这意味着它在比较时与 OID 相同,但显示为类型名。 - 例如: + 例如: SELECT pg_typeof(33); pg_typeof @@ -21527,11 +21391,12 @@ SELECT typlen FROM pg_type WHERE oid = pg_typeof(33); text - 返回传递值给它的排序规则的名称。如果需要,该值会被引号括起来,并使用模式限定。 - 如果没有为参数表达式派生排序规则,则返回NULL。如果参数不是可排序数据类型,则会引发错误。 + 返回传入值的排序规则名称。必要时会为返回的名称加上引号和模式限定。 + 如果无法为参数表达式推导出排序规则,则返回NULL。 + 如果参数不属于支持排序规则的数据类型,则报错。 - 例如: + 例如: SELECT collation for (description) FROM pg_description LIMIT 1; pg_collation_for @@ -21556,7 +21421,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); 将文本关系名转换为它的OID。通过将字符串类型转换为regclass可以得到类似的结果(参见); - 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。 @@ -21569,8 +21434,8 @@ SELECT collation for ('foo' COLLATE "de_DE"); regcollation - 将文本排序规则名称转换为它的OID。通过将字符串类型转换为regcollation(参见)可以得到类似的结果; - 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 将文本排序规则名称转换为它的OID。通过将字符串类型转换为regcollation(参见)可以得到类似的结果; + 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。 @@ -21583,8 +21448,8 @@ SELECT collation for ('foo' COLLATE "de_DE"); regnamespace - 将文本模式名转换为它的OID。通过将字符串转换为regnamespace类型(参见)可以得到类似的结果; - 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 将文本模式名转换为它的OID。通过将字符串转换为regnamespace类型(参见)可以得到类似的结果; + 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。 @@ -21597,8 +21462,8 @@ SELECT collation for ('foo' COLLATE "de_DE"); regoper - 将文本操作符名称转换为它的OID。通过将字符串类型转换为regoper(参见)可以得到类似的结果; - 但是,如果找不到名称或名称有多义性,该函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 将文本操作符名称转换为它的OID。通过将字符串类型转换为regoper(参见)可以得到类似的结果; + 但是,如果找不到名称或名称有多义性,该函数将返回NULL而不会抛出错误。 @@ -21611,8 +21476,8 @@ SELECT collation for ('foo' COLLATE "de_DE"); regoperator - 将文本操作符名称(带有参数类型)转换为其OID。通过将字符串转换为regoperator类型(参见节)可以得到类似的结果; - 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 将文本操作符名称(带有参数类型)转换为其OID。通过将字符串转换为regoperator类型(参见节)可以得到类似的结果; + 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。 @@ -21625,8 +21490,8 @@ SELECT collation for ('foo' COLLATE "de_DE"); regproc - 将文本函数或过程名转换为其OID。通过将字符串转换为regproc类型(参见)可以得到类似的结果; - 但是,如果找不到名称或名称有多义性,该函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 将文本函数或过程名转换为其OID。通过将字符串转换为regproc类型(参见)可以得到类似的结果; + 但是,如果找不到名称或名称有多义性,该函数将返回NULL而不会抛出错误。 @@ -21640,7 +21505,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); 将文本函数或过程名(带有参数类型)转换为其OID。通过将字符串类型转换为regprocedure可以得到类似的结果(参见); - 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。 @@ -21654,7 +21519,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); 将文本角色名转换为它的OID。通过将字符串类型转换为regrole可以得到类似的结果(参见); - 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。 @@ -21667,8 +21532,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); regtype - 将文本类型名转换为它的OID。通过将字符串类型转换为regtype可以得到类似的结果(参见); - 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 将文本形式的类型名转换为其 OID。将字符串转换为 regtype 类型也能得到类似的结果(参见 );不过,如果找不到该名称,此函数会返回 NULL,而不会报错。 @@ -21676,10 +21540,10 @@ SELECT collation for ('foo' COLLATE "de_DE"); - 大多数重构(反编译)数据库对象的函数都有一个可选的 pretty标志,如果为true,结果将被pretty-printed。 - 美观打印会抑制不必要的圆括号,并为易读性增加空格。 - 美观打印的格式可读性更好,但是默认格式更有可能被PostgreSQL的未来版本以同样的方式解释; - 因此,避免为转储目的使用美观打印的输出。为pretty参数传递false会产生与省略参数相同的结果。 + 大多数重建(反编译)数据库对象的函数都有一个可选的pretty标志;若为true,则对结果进行美化输出。 + 美化输出会省略不必要的圆括号,并增加空白以提高可读性。 + 美化后的格式更易读,但默认格式更有可能被PostgreSQL的未来版本以同样的方式解释,因此用于转储时应避免美化输出。 + 为pretty参数传入false与省略该参数的结果相同。 @@ -21724,19 +21588,20 @@ SELECT collation for ('foo' COLLATE "de_DE"); distance_orderable - 列是否能通过一个distance操作符(例如ORDER BY col <-> constant)按序扫描? + + 能否按距离操作符的结果有序地扫描该列,例如ORDER BY col <-> constant returnable - 列值是否可以通过一次只用索引扫描返回? + 列值是否可以通过一次仅索引扫描返回? search_array - 列是否天然支持col = ANY(array)搜索? + 列是否原生支持col = ANY(array)搜索? @@ -21751,7 +21616,7 @@ SELECT collation for ('foo' COLLATE "de_DE");
- 索引性质 + 索引属性 @@ -21788,7 +21653,7 @@ SELECT collation for ('foo' COLLATE "de_DE");
- 索引访问方法性质 + 索引访问方法属性 @@ -21841,15 +21706,20 @@ SELECT collation for ('foo' COLLATE "de_DE"); EXPLAIN - 带有此标志的参数包含在EXPLAIN (SETTINGS)命令中。 + 带有此标志的参数会在EXPLAIN (SETTINGS)命令的输出中显示。 NO_SHOW_ALL - 具有此标志的参数将被排除在SHOW ALL命令之外。 + 带有此标志的参数不会在SHOW ALL命令的输出中显示。 + NO_RESET + 带有此标志的参数不支持RESET命令。 + + + NO_RESET_ALL 具有此标志的参数将被排除在RESET ALL命令之外。 @@ -21873,16 +21743,15 @@ SELECT collation for ('foo' COLLATE "de_DE"); - 对象信息和定位函数 + 对象信息和寻址函数 - 列出了与数据库对象 - 标识和定位有关的函数。 + 列出了与数据库对象标识和寻址有关的函数。
- 对象信息和定位函数 + 对象信息和寻址函数 @@ -21907,9 +21776,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); text - 返回由目录OID、对象OID和子对象ID(例如表中的列号)标识的数据库对象的文本描述;当引用整个对象时,子对象ID为0)。 - 这个描述是人类可读的,并且可以根据服务器配置进行翻译。这对于决定pg_depend目录中引用的对象的标识特别有用。 - 此函数对于未定义的对象返回NULL值 + 返回数据库对象的文本描述,对象由系统目录 OID、对象 OID 和子对象 ID 指定(例如表中的列号;引用整个对象时,子对象 ID 为零)。该描述供人阅读,并可能根据服务器配置被翻译。这对于确定pg_depend系统目录中所引用对象的标识尤其有用。对于未定义的对象,此函数返回NULL @@ -21926,13 +21793,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); identitytext ) - 返回包含足够信息的行以唯一标识由目录OID、对象OID和子对象ID指定的数据库对象。 - 这些信息是为了机器可读的,永远不会被翻译。 - type标识数据库对象的类型; - schema是对象所属的模式名,NULL表示不属于模式的对象类型; - name是对象的名称,如果有必要,用引号括起来,如果名称(随着模式名称,如果相关)足以唯一地标识对象,否则为NULL; - identity是完整的对象标识,其精确格式依赖于对象类型,格式中的每个名称都是模式限定的,并在必要时用引号括起来。 - 未定义的对象由NULL值标识。 + 返回一行,其中包含足以唯一标识数据库对象的信息,该对象由系统目录 OID、对象 OID 和子对象 ID 指定。这些信息供机器读取,永远不会被翻译。type标识数据库对象的类型;schema是对象所属的模式名,对于不属于模式的对象类型则为NULL;如果对象名(以及适用时的模式名)足以唯一标识该对象,name就是对象名,并在必要时加引号,否则为NULLidentity是完整的对象标识,其具体格式取决于对象类型,格式中的每个名称都会根据需要加上模式限定和引号。未定义的对象以NULL值标识。 @@ -21948,10 +21809,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); object_argstext[] ) - 返回包含足够信息的行以唯一标识由目录OID、对象OID和子对象ID指定的数据库对象。 - 返回的信息独立于当前服务器,也就是说,它可以用于标识另一个服务器中具有相同名称的对象。 - type标识数据库对象的类型;object_namesobject_args是文本数组,它们一起构成对对象的引用。 - 这三个值可以传递给pg_get_object_address以获得对象的内部地址。 + 返回一行,其中包含足以唯一标识数据库对象的信息,该对象由系统目录 OID、对象 OID 和子对象 ID 指定。返回的信息与当前服务器无关,也就是说,它也能用于标识另一台服务器上名称相同的对象。type标识数据库对象的类型;object_namesobject_args是文本数组,共同构成对该对象的引用。将这三个值传给pg_get_object_address可以获得对象的内部地址。 @@ -21967,12 +21825,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); objsubidinteger ) - 返回包含足够信息的行以唯一标识由类型代码、对象名称和参数数组指定的数据库对象。 - 返回的值将在系统目录中使用,例如pg_depend; - 它们可以传递给其他系统函数,比如 pg_describe_objectpg_identify_object。 - classid是包含该对象的系统目录的OID;objid是对象本身的OID, objsubid是子对象的ID,如果没有则为零。 - 这个函数是pg_identify_object_as_address的反向函数。 - 未定义的对象以NULL值标识。 + 返回一行,其中包含足以唯一标识数据库对象的信息,该对象由类型代码、对象名称数组和参数数组指定。返回的值就是pg_depend等系统目录中使用的值;它们可以传给pg_describe_objectpg_identify_object等其他系统函数。classid是包含该对象的系统目录的 OID;objid是对象自身的 OID;objsubid是子对象 ID,没有子对象时为零。此函数执行pg_identify_object_as_address的逆操作。未定义的对象以NULL值标识。 @@ -21991,7 +21844,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); - 中展示的函数抽取注释,注释是由命令在以前存储的。如果对指定参数找不到注释,则返回空值。 + 中的函数用于提取此前通过命令存储的注释。如果找不到与指定参数对应的注释,则返回空值。
@@ -22021,7 +21874,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); text - 返回表列的注释,该注释由该表的OID和列号指定。(obj_description不能用于表的列,因为列没有自己的oid。) + 返回表列的注释,列由所属表的 OID 和列号指定。(obj_description不能用于表列,因为列没有自身的 OID。) @@ -22034,8 +21887,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); text - 返回OID指定的数据库对象的注释和包含该对象的系统目录的名称。 - 例如,obj_description(123456, 'pg_class')将检索OID为123456的表的注释。 + 返回数据库对象的注释,对象由其 OID 和所在系统目录的名称指定。例如,obj_description(123456, 'pg_class')会获取 OID 为 123456 的表的注释。 @@ -22045,8 +21897,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); text - 返回仅由其OID指定的数据库对象的注释。 - 这个已被弃用(deprecated)因为无法保证oid在不同的系统目录中是唯一的;因此,可能会返回错误的注释。 + 返回仅由其 OID 指定的数据库对象的注释。此形式已弃用,因为无法保证 OID 在不同系统目录之间唯一,因而可能返回错误的注释。 @@ -22059,9 +21910,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); text - 返回共享数据库对象的注释,该对象由其OID和包含的系统编目的名称指定。 - 这与obj_description类似,只是它用于检索共享对象(也就是数据库、角色和表空间)上的注释。 - 有些系统编目对每个集簇中的所有数据库都是全局的,其中对象的描述也全局存储。 + 返回共享数据库对象的注释,对象由其 OID 和所在系统目录的名称指定。此函数与obj_description类似,但用于获取共享对象(即数据库、角色和表空间)的注释。有些系统目录由数据库集簇中的所有数据库全局共享,其中对象的描述也全局存储。 @@ -22155,12 +22004,21 @@ SELECT collation for ('foo' COLLATE "de_DE"); 事务,就像直接将该字符串转换为该类型一样。 - SELECT * FROM pg_input_error_info('42000000000', 'integer') + select * from pg_input_error_info('42000000000', 'integer') message | detail | hint | sql_error_code ------------------------------------------------------+--------+------+---------------- value "42000000000" is out of range for type integer | | | 22003 + + + + select message, detail from pg_input_error_info('1234.567', 'numeric(7,4)') + + + message | detail +------------------------+----------------------------------&zwsp;------------------------------------------------- + numeric field overflow | A field with precision 7, scale 4 must round to an absolute value less than 10^3. @@ -22197,6 +22055,32 @@ SELECT collation for ('foo' COLLATE "de_DE"); + + + + age + + age ( xid ) + integer + + + 返回给定事务 ID 与当前事务计数器之间的事务数。 + + + + + + + mxid_age + + mxid_age ( xid ) + integer + + + 返回给定多事务 ID 与当前多事务计数器之间的多事务 ID 数。 + + + @@ -22206,7 +22090,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); xid8 - 返回当前事务的ID。如果当前事务还没有一个ID(因为它还没有执行任何数据库更新),它将分配一个新的事务。 + 返回当前事务的ID。如果当前事务还没有一个ID(因为它还没有执行任何数据库更新),它将分配一个新的事务 ID;详见。如果在子事务中执行,它将返回顶层事务的ID;详见 @@ -22219,8 +22103,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); xid8 - 返回当前事务的ID,如果还没有分配ID则返回NULL。 - (如果事务可能是只读的,最好使用这种变体,以避免不必要地消耗XID。) + 返回当前事务的 ID;如果尚未分配 ID,则返回NULL。(如果事务本来可能是只读的,最好使用此变体,以免不必要地消耗 XID。)如果在子事务中执行,则返回顶层事务 ID。 @@ -22233,10 +22116,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); text - 报告最近的事务的提交状态。如果事务为最近的,系统会保留事务的提交状态,则结果是 in progresscommittedaborted。 - 如果该事务的时间足够久,并且系统中没有对该事务的引用,而且提交状态信息已经被丢弃,则结果为NULL。 - 应用可以使用此函数,例如,确定在进行COMMIT时,应用程序和数据库服务器断开连接后,它们的事务是已提交还是中止。 - 注意,准备好的事务报告为in progress的事务;如果应用需要确定一个事务ID是否属于一个准备好的事务,则必须检查pg_prepared_xacts。 + 报告近期事务的提交状态。只要事务足够新,系统仍保留其提交状态,结果就为in progresscommittedaborted。如果事务已足够旧,系统中不再有对它的引用,且提交状态信息已被丢弃,则返回NULL。例如,在COMMIT进行过程中应用与数据库服务器断开连接时,应用可以用此函数判断事务是提交了还是中止了。注意,预备事务被报告为in progress;如果需要确定某个事务 ID 是否为预备事务,应用必须检查pg_prepared_xacts @@ -22249,7 +22129,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); pg_snapshot - 返回当前snapshot,显示哪些事务 ID正在进行中的数据结构。 + 返回当前快照,即显示哪些事务 ID 正在进行中的数据结构。快照中只包含顶层事务 ID,不显示子事务 ID;详见 @@ -22301,8 +22181,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); boolean - 根据此快照,给定的事务ID是否可见(visible)(也就是说,它是否在快照拍摄之前完成)? - 注意,这个函数不会给出子事务ID的正确答案。 + 根据此快照,给定的事务 ID 是否可见(即该事务是否在生成快照之前完成)?注意,此函数无法为子事务 ID(subxid)给出正确结果;详见 @@ -22326,7 +22205,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); 内部事务 ID 类型xid是 32 位宽,每 40 亿个事务就会回卷一次(wrap around)。 - 但是,中所示的函数使用的是 64 位类型xid8,它在一次安装的生命周期内不会回卷,必要时可以通过强制转换将其转换为xid。 + 但是,中所示的函数(agemxid_agepg_get_multixact_members除外)使用的是 64 位类型xid8,它在一次安装的生命周期内不会回卷,必要时可以通过类型转换将其转换为xid;详见。 数据类型pg_snapshot存储特定时刻事务ID可见性的信息。 其组成如所描述。pg_snapshot的文本表示形式是xmin:xmax:xip_list。 例如10:20:10,14,15表示xmin=10, xmax=20, xip_list=10, 14, 15。 @@ -22349,21 +22228,22 @@ SELECT collation for ('foo' COLLATE "de_DE"); xmin - 仍然处于活动状态的最低事务ID。所有小于xmin的事务 ID要么提交且可见,要么回滚并死亡。 + 仍然处于活动状态的最小事务 ID。所有小于xmin的事务 ID 要么已经提交且可见,要么已经回滚而失效。 xmax - 比最高完成的事务ID还高出一个值。所有大于或等于xmax的事务 ID到快照时还没有完成,因此不可见。 + 已完成事务中的最大事务 ID 加一。所有大于或等于xmax的事务 ID 在生成快照时尚未完成,因此不可见。 xip_list - 快照时正在进行的事务。一个事务ID为xmin <= X < xmax且不在快照时已经完成的列表中,因此根据其提交状态,该事务ID要么是可见的,要么是死的。此列表不包括子事务的事务 ID。 + 生成快照时正在进行的事务。满足xmin <= X < + xmax且不在此列表中的事务 ID 在生成快照时已经完成,因此根据其提交状态,要么可见,要么失效。此列表不包含子事务的事务 ID(subxid)。 @@ -22508,8 +22388,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); 已提交事务信息函数 - 中的函数提供了关于过去的事务何时被提交的信息。 - 它们只在启用配置选项时提供有用的数据,并且只针对在启用该选项后提交的事务。 + 中的函数提供过去事务的提交时间信息。只有启用配置选项后,这些函数才会提供有用的数据,并且只针对启用该选项之后提交的事务。提交时间戳信息会在 vacuum 过程中定期清理。
@@ -22554,7 +22433,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); roidentoid) - 返回事务的提交时间戳和复制起源。 + 返回事务的提交时间戳和复制源。 @@ -22570,7 +22449,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); roidentoid ) - 返回最近提交的事务的事务ID、提交时间戳和复制源头。 + 返回最近提交事务的事务 ID、提交时间戳和复制源。 @@ -22584,9 +22463,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); 控制数据函数 - 中所展示的函数能打印initdb期间初始化的信息,例如目录版本。 - 它们也能显示有关预写式日志和检查点处理的信息。这些信息是集簇范围内的,不与任何特定的一个数据库相关。 - 这些函数提供大致相同的信息,对于同一种来源,就像应用。 + 中的函数显示在initdb期间初始化的信息,例如系统目录版本。它们也显示有关预写式日志和检查点处理的信息。这些信息适用于整个数据库集簇,而非某个特定数据库。这些函数与应用程序从相同来源提供大部分相同的信息。
@@ -22616,7 +22493,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); record - 返回有关当前检查点状态的信息, 如 所展示。 + 返回有关当前检查点状态的信息, 如 所展示。 @@ -22655,7 +22532,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); record - 返回有关恢复状态的信息,如 所展示。 + 返回有关恢复状态的信息,如 所展示。 @@ -22949,9 +22826,9 @@ SELECT collation for ('foo' COLLATE "de_DE"); - configuration - of the server - functions + 配置 + 服务器 + 函数 @@ -22988,7 +22865,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); text - 返回设置的setting_name的当前值。 + 返回设置setting_name的当前值。 如果没有这样的设置,current_setting将抛出一个错误,除非missing_ok被提供并且为true(在此情况下返回NULL)。 这个函数对应于SQL命令 @@ -23010,9 +22887,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); text - 将参数setting_name设置为new_value,并返回该值。 - 如果is_localtrue,新值将仅在当前事务期间应用。 - 如果您希望新值应用于当前会话的其余部分,请使用false代替。这个函数对应于SQL命令。 + 将参数setting_name设置为new_value,并返回该值。如果is_localtrue,新值仅在当前事务期间生效。如果希望新值在当前会话的剩余时间内生效,则使用false。此函数对应 SQL 命令 set_config('log_statement_stats', 'off', false) @@ -23035,7 +22910,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); - 在中展示的函数向其它服务器进程发送控制信号。默认情况下这些函数只能被超级用户使用,但是如果需要,可以利用GRANT把访问权限授予给其他用户。 + 在中展示的函数向其它服务器进程发送控制信号。默认情况下这些函数只能被超级用户使用,但是如果需要,可以利用GRANT把访问权限授予给其他用户(注明的例外除外)。 @@ -23083,11 +22958,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); boolean - 请求记录具有指定进程ID的后端的内存上下文。此函数可以将请求发送到后端和辅助进程,但不包括记录器。这些内存上下文将以 - LOG消息级别记录。它们将根据设置的日志配置出现在服务器日志中 - (有关更多信息,请参见), - 但无论如何都不会发送给客户端 - ()。 + 请求记录具有指定进程 ID 的后端进程的内存上下文。此函数可以向除日志记录进程以外的后端进程和辅助进程发送请求。这些内存上下文将以LOG消息级别记录,并根据日志配置出现在服务器日志中(详见);无论如何设置,都不会发送给客户端。 @@ -23136,7 +23007,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); 终止具有指定进程ID的后端进程的会话。如果调用角色是正在终止的后端的角色的成员,或者调用角色具有pg_signal_backend的权限,则也允许执行此操作,但只有超级用户才能终止超级用户后端。 - 如果未指定或超时timeout为零,则此函数无论进程是否实际终止,都将返回true,仅表示信号发送成功。如果指定了timeout(以毫秒为单位)且大于零,则函数将等待直到进程实际终止或直到给定时间已过。如果进程被终止,函数将返回true。在超时时,会发出警告并返回false。 + 如果未指定timeout或其值为零,则此函数无论进程是否实际终止,都将返回true,仅表示信号发送成功。如果指定了timeout(以毫秒为单位)且大于零,则函数将等待直到进程实际终止或直到给定时间已过。如果进程被终止,函数将返回true。在超时时,会发出警告并返回false @@ -23185,7 +23056,7 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 备份控制函数 - backup + 备份 @@ -23225,13 +23096,9 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 pg_lsn - 在预写式日志中创建一个命名标记记录,稍后可以将其用作恢复目标,并返回相应的预写日志位置。 - 然后可以将给定的名称与 一起使用,以指定进行恢复的点。 - 要避免创建多个名称相同的恢复点,因为恢复将在第一个名称与恢复目标匹配的恢复点停止。 + 在预写式日志中创建一条命名标记记录,供以后用作恢复目标,并返回相应的预写式日志位置。随后可以在中使用给定名称,指定恢复到哪一点。应避免创建多个同名恢复点,因为恢复会在第一个名称匹配恢复目标的恢复点停止。 - - 默认情况下,该函数仅限超级用户使用,但可以授权给其他用户执行该函数。 - + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -23243,7 +23110,7 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 pg_lsn - 返回当前预写式日志刷新位置(参见下面的说明)。 + 返回当前预写式日志刷盘位置(参见下文说明)。 @@ -23256,7 +23123,7 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 pg_lsn - 返回当前预式日志插入位置(参见下面的说明)。 + 返回当前预写式日志插入位置(参见下文说明)。 @@ -23269,7 +23136,7 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 pg_lsn - 返回当前预写式日志写位置(参见下面的说明)。 + 返回当前预写式日志写入位置(参见下文说明)。 @@ -23285,15 +23152,9 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 pg_lsn - 准备服务器开始在线备份。唯一必需的参数是备份的任意用户定义标签。 - (通常这将是备份转储文件存储的名称。) - 如果将可选的第二个参数指定为true, - 它将尽快执行pg_backup_start。这将强制立即进行检查点, - 这将导致I/O操作的激增,从而减慢任何同时执行的查询。 + 准备服务器开始在线备份。唯一必需的参数是用户任意指定的备份标签。(通常是备份转储文件将要保存的名称。)如果可选的第二个参数为true,则尽快执行pg_backup_start。这会强制立即执行检查点,使 I/O 操作量陡增,并降低并发执行的查询的速度。 - - 默认情况下,此函数仅限于超级用户,但可以授予其他用户执行权限以运行该函数。 - + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -23310,31 +23171,18 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 spcmapfile text ) - 完成在线备份。函数的结果中返回备份标签文件和表空间映射文件的期望内容,并必须写入备份区域的文件中。 - 这些文件不得写入实时数据目录(这样做将导致PostgreSQL在崩溃时无法重新启动)。 + 结束在线备份。备份标签文件和表空间映射文件所需的内容作为函数结果的一部分返回,必须将其写入备份区域中的文件。切勿将这些文件写入正在使用的数据目录(否则发生崩溃后 PostgreSQL 将无法重新启动)。 - 有一个类型为boolean的可选参数。 - 如果为false,则在备份完成后立即返回,而无需等待WAL进行归档。 - 此行为仅适用于独立监视WAL归档的备份软件。否则,可能会缺少使备份一致所需的WAL,使备份无效。 - 默认情况下或当此参数为true时,pg_backup_stop将在启用归档时等待WAL进行归档。 - (在备库上,这意味着仅当archive_mode = always时才会等待。 - 如果主库上的写入活动较低,则可能有必要在主库上运行pg_switch_wal以触发立即段切换。) + 有一个boolean类型的可选参数。如果为 false,该函数会在备份完成后立即返回,不等待 WAL 归档。这种行为只适用于自行监控 WAL 归档的备份软件;否则,可能缺少使备份保持一致所需的 WAL,导致备份无法使用。默认情况下或该参数为 true 时,若已启用归档,pg_backup_stop会等待 WAL 归档。(在备库上,这意味着只有archive_mode = always时才会等待。如果主库的写入活动很少,可以在主库上运行pg_switch_wal,触发立即切换日志段。) - 在主库上执行时,此函数还会在预写式日志归档区域中创建一个备份历史文件。 - 历史文件包括给定给pg_backup_start的标签、备份的起始和结束预写式日志位置,以及备份的起始和结束时间。 - 在记录结束位置后,当前的预写式日志插入点会自动前进到下一个预写式日志文件,以便立即归档结束的预写式日志文件以完成备份。 + 在主库上执行时,该函数还会在预写式日志归档区域创建备份历史文件。历史文件包括传给pg_backup_start的标签、备份的起止预写式日志位置以及备份的起止时间。记录结束位置后,当前预写式日志插入点会自动推进到下一个预写式日志文件,使包含结束位置的预写式日志文件可以立即归档,从而完成备份。 - 函数的结果是一个记录。 - lsn列保存备份的结束预写式日志位置(可以忽略)。 - 第二列返回备份标签文件的内容,第三列返回表空间映射文件的内容。 - 这些必须作为备份的一部分存储,并作为恢复过程的一部分。 + 该函数的结果是一条记录。lsn列保存备份结束时的预写式日志位置(同样可以忽略)。第二列返回备份标签文件的内容,第三列返回表空间映射文件的内容。这些内容必须作为备份的一部分保存,恢复时需要用到它们。 - - 默认情况下,此函数仅限于超级用户,但可以授予其他用户EXECUTE权限来运行该函数。 - + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -23346,13 +23194,9 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 pg_lsn - 强制服务器切换到一个新的预写式日志文件,这允许对当前文件进行归档(假设你正在使用连续归档)。 - 其结果是在刚刚完成的预写式日志文件中结束预写式日志位置加1。 - 如果自从上次预写式日志切换以来没有提前写日志活动,pg_switch_wal将不做任何操作,并返回当前正在使用的提前写日志文件的起始位置。 + 强制服务器切换到新的预写式日志文件,使当前文件可以归档(假设正在使用连续归档)。返回值是刚完成的预写式日志文件中的结束预写式日志位置加 1。如果自上次切换预写式日志以来没有发生任何预写式日志活动,pg_switch_wal不执行任何操作,并返回当前使用的预写式日志文件的起始位置。 - - 默认情况下该函数仅限超级用户使用,但可以授权其他用户执行该函数。 - + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -23364,7 +23208,7 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 text - 将预写式日志位置转换为保持该位置的WAL文件的名称。 + 将预写式日志位置转换为包含该位置的 WAL 文件的名称。 @@ -23383,6 +23227,21 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 + + + + pg_split_walfile_name + + pg_split_walfile_name ( file_name text ) + record + ( segment_number numeric, + timeline_id bigint ) + + + 从 WAL 文件名中提取序列号和时间线 ID。 + + + @@ -23392,34 +23251,38 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 numeric - 计算两个预写式日志位置之间的字节(lsn1 - lsn2)差异。 - 这可以与pg_stat_replication中所示的一些函数一起使用,以获得复制延迟。 + 计算两个预写式日志位置之间的字节差(lsn1 - lsn2)。可以将它与pg_stat_replication中的某些函数配合使用,以获取复制延迟。
- - pg_current_wal_lsn 显示当前预写式日志写位置,与上述函数所用的格式相同。 - 类似地,pg_current_wal_insert_lsn显示当前预写式日志插入位置,pg_current_wal_flush_lsn显示当前预写式日志刷新位置。 - 插入位置是预写式日志在任何时刻的逻辑(logical) 结束,而写位置是已经从服务器内部缓冲区实际写入的内容的结束,而刷新位置是已知的要写入持久化存储的最后一个位置。 - 写位置是可以从服务器外部检查的最后位置,如果你对归档部分完成的预写式日志文件感兴趣,那么它通常就是你想要的位置。 - 插入和刷新位置主要用于服务器调试目的。这些都是只读操作,不需要超级用户权限。 - + pg_current_wal_lsn 显示当前预写式日志写入位置,格式与上述函数相同。类似地,pg_current_wal_insert_lsn 显示当前预写式日志插入位置,pg_current_wal_flush_lsn 显示当前预写式日志刷盘位置。插入位置是预写式日志在任意时刻的逻辑末尾;写入位置是实际从服务器内部缓冲区写出的内容的末尾;刷盘位置则是已知已经写入持久存储的最后位置。写入位置是能从服务器外部检查到的内容的末尾,如果要归档尚未写满的预写式日志文件,通常需要这个位置。插入位置和刷盘位置主要用于服务器调试。这些都是只读操作,不需要超级用户权限。 - - 您可以使用pg_walfile_name_offsetpg_lsn值中提取相应的预写式日志文件名和字节偏移量。例如: - + 可以使用pg_walfile_name_offset从一个pg_lsn值中提取相应的预写式日志文件名和字节偏移量。例如: postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); file_name | file_offset --------------------------+------------- 00000001000000000000000D | 4039624 (1 row) +类似地,pg_walfile_name仅提取预写式日志文件名。当指定的预写式日志位置恰好位于预写式日志文件边界时,这两个函数都返回前一个预写式日志文件的名称。这通常正是管理预写式日志归档时所需的行为,因为前一个文件是当前需要归档的最后一个文件。 + + + pg_split_walfile_name可用于根据文件偏移量和 WAL 文件名计算 + LSN,例如: + +postgres=# \set file_name '000000010000000100C000AB' +postgres=# \set offset 256 +postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset AS lsn + FROM pg_split_walfile_name(:'file_name') pd, + pg_show_all_settings() ps + WHERE ps.name = 'wal_segment_size'; + lsn +--------------- + C001/AB000100 +(1 row) - 类似地,pg_walfile_name仅提取预写式日志文件名。 - 当给定的预写式日志位置恰好位于预写式日志文件边界时,这两个函数都会返回前一个预写式日志文件的名称。 - 这通常是管理预写式日志归档行为的期望行为,因为前一个文件是当前需要归档的最后一个文件。 @@ -23473,9 +23336,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); pg_lsn - 返回已接收并通过流复制同步到磁盘的最后一个预写式日志位置。 - 当流复制正在进行时这将单调地增加。如果恢复已经完成,那么在恢复期间,接收到的最后一条WAL记录的位置将保持静态,并同步到磁盘。 - 如果流复制已禁用,或者尚未启动,函数将返回NULL。 + 返回流复制最近接收并同步到磁盘的预写式日志位置。在流复制进行期间,该值单调增加。如果恢复已完成,该值将保持为恢复期间最后接收并同步到磁盘的 WAL 记录的位置。如果禁用了流复制,或者流复制尚未开始,此函数返回 NULL @@ -23488,8 +23349,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); pg_lsn - 返回恢复期间重新播放的最后一个预写式日志位置。如果恢复仍在进行中这将会单调地增加。 - 如果恢复已经完成,那么恢复期间应用的最后WAL记录的位置将保持静态。当服务器正常启动且没有恢复时,函数返回NULL。 + 返回恢复期间最近重放的预写式日志位置。如果恢复仍在进行,该值单调增加。如果恢复已完成,该值将保持为该次恢复期间最后应用的 WAL 记录的位置。如果服务器未经恢复而正常启动,此函数返回 NULL @@ -23502,10 +23362,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); timestamp with time zone - 返回恢复期间重放的最后一个事务的时间戳。这是在主库上为该事务生成提交或中止 WAL记录的时间。 - 如果在恢复期间没有重放任何事务,该函数将返回NULL。否则,如果恢复仍在进行中,这将单调地增加。 - 如果恢复已经完成,那么在恢复期间应用最后一个事务时,这将会保持静态。 - 当服务器正常启动且没有恢复时,函数返回NULL。 + 返回恢复期间最近重放事务的时间戳,即该事务的提交或中止 WAL 记录在主库上生成的时间。如果恢复期间尚未重放任何事务,此函数返回 NULL。否则,如果恢复仍在进行,该值单调增加。如果恢复已完成,该值将保持为该次恢复期间最后应用的事务的时间戳。如果服务器未经恢复而正常启动,此函数返回 NULL @@ -23529,7 +23386,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); - 控制恢复进度的功能如 所示。这些函数只能在恢复过程中执行。 + 列出的函数用于控制恢复进度。这些函数只能在恢复期间执行。 @@ -23559,7 +23416,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); boolean - 如果请求了恢复暂停了则返回真。 + 如果已请求暂停恢复,则返回真。 @@ -23573,7 +23430,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); 返回恢复暂停状态。 - 如果没有请求pause,返回值是not paused,如果请求暂停但恢复还没有暂停,返回值是pause requested,如果恢复实际已经暂停,返回值是paused。 + 如果没有请求暂停,返回值是not paused,如果请求暂停但恢复还没有暂停,返回值是pause requested,如果恢复实际已经暂停,返回值是paused @@ -23587,11 +23444,11 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); 将备库提升为主库状态。 - 当wait设置为true(默认值)时,函数将等待直到升级完成或wait_seconds秒数已过,如果升级成功则返回true,否则返回false。 - 如果wait设置为false,则该函数在向postmaster发送SIGUSR1信号以触发升级后立即返回true。 + 当wait设置为true(默认值)时,函数将等待直到提升完成或wait_seconds秒数已过,如果提升成功则返回true,否则返回false。 + 如果wait设置为false,则该函数在向postmaster发送SIGUSR1信号以触发提升后立即返回true - 默认情况下这个函数仅限超级用户使用,但可以授权给其他用户执行该函数。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -23612,7 +23469,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); 如果热备是激活的,所有新查询将看到相同的一致的数据库快照,并且在恢复继续之前不会生成进一步的查询冲突。 - 默认情况下该函数仅限超级用户使用,但可以授权其他用户执行该函数。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -23628,7 +23485,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); 如果暂停了,则重新启动恢复。 - 默认情况下该函数仅限超级用户使用,但可以授权其他用户执行该函数。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -23636,8 +23493,8 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn);
- pg_wal_replay_pausepg_wal_replay_resume不能在提升(promotion)进行时执行。 - 如果在恢复暂停时触发了提升(promotion),则暂停状态结束,升级继续进行。 + pg_wal_replay_pausepg_wal_replay_resume不能在提升进行时执行。 + 如果在恢复暂停时触发了提升,则暂停状态结束,提升继续进行。 @@ -23656,7 +23513,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); - 为了解决这个问题,PostgreSQL允许一个事务导出它正在使用的快照。只要导出的事务仍然保持打开,其他事务可以导入它的快照,并且因此可以保证它们可以看到和第一个事务看到的完全一样的数据库视图。但是注意这些事务中的任何一个对数据库所作的更改对其他事务仍然保持不可见,和未提交事务所作的修改一样。因此这些事务是针对以前存在的数据同步,而对由它们自己所作的更改则采取正常的动作。 + 为了解决这个问题,PostgreSQL允许一个事务导出它正在使用的快照。只要导出快照的事务仍然保持打开,其他事务可以导入它的快照,并且因此可以保证它们可以看到和第一个事务看到的完全一样的数据库视图。但是注意这些事务中的任何一个对数据库所作的更改对其他事务仍然保持不可见,和未提交事务所作的修改一样。因此这些事务是针对以前存在的数据同步,而对由它们自己所作的更改则采取正常的动作。 @@ -23696,7 +23553,19 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); 如果需要的话,一个事务可以导出多个快照。 请注意,这样做仅在READ COMMITTED事务中有用,因为在REPEATABLE READ和更高的隔离级别中,事务在它们的生命周期中使用相同的快照。 - 一旦事务导出了快照,它就不能用 进行准备。 + 一旦事务导出了快照,它就不能用 进行预备。 + + + + + + pg_log_standby_snapshot + + pg_log_standby_snapshot () + pg_lsn + + + 为进行中的事务拍摄快照并将其写入 WAL,无须等待后台写入器或检查点进程记录快照。这对备用服务器上的逻辑解码很有用,因为创建逻辑复制槽必须等待此类记录在备用服务器上重放。 @@ -23712,7 +23581,6 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); 中展示的函数用于控制以及与复制特性交互。 有关底层特性的信息请见以及。 - 复制原点函数的使用仅限于超级用户。 默认只允许超级用户使用复制源的函数,但可以通过GRANT命令允许其他用户使用。 复制槽的函数只限于超级用户和拥有REPLICATION权限的用户。 @@ -23758,12 +23626,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); lsn pg_lsn ) - 创建一个新的名为slot_name的物理复制槽。 - 第二个参数是可选的,当它为true时,立即为这个物理槽指定要被保留的LSN。 - 否则该LSN会被保留在来自一个流复制客户端的第一个连接上。 - 来自一个物理槽的更改只能通过流复制协议进行流式传输 — 见。 - 当可选的第三参数temporary被设置为真时,指定那个槽不会被持久地存储在磁盘上并且仅对当前会话的使用有意义。 - 临时槽也会在发生任何错误时被释放。这个函数对应于复制协议命令CREATE_REPLICATION_SLOT ... PHYSICAL。 + 创建名为 slot_name 的新物理复制槽。可选的第二个参数为 true 时,指定立即为此复制槽保留 LSN;否则在流复制客户端首次连接时保留 LSN。从物理槽流式传输更改只能使用流复制协议 — 参见。可选的第三个参数 temporary 为真时,指定该槽不永久存储到磁盘,且仅供当前会话使用。发生任何错误时,临时槽也会被释放。此函数对应复制协议命令 CREATE_REPLICATION_SLOT ... PHYSICAL @@ -23776,9 +23639,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); void - 丢弃名为slot_name的物理或逻辑复制槽。 - 和复制协议命令DROP_REPLICATION_SLOT相同。对于逻辑槽, - 在连接到在其中创建该槽的同一个数据库时,必须调用这个函数。 + 删除名为slot_name的物理或逻辑复制槽。与复制协议命令DROP_REPLICATION_SLOT相同。 @@ -23793,7 +23654,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); lsn pg_lsn ) - 创建一个名为slot_name的新逻辑(解码)复制插槽,使用输出插件plugin。可选的第三个参数temporary,当设置为true时,指定插槽不应永久存储到磁盘,仅供当前会话使用。临时插槽也会在任何错误发生时释放。可选的第四个参数twophase,当设置为true时,指定为此插槽启用已准备事务的解码。调用此函数的效果与复制协议命令CREATE_REPLICATION_SLOT ... LOGICAL相同。 + 创建一个名为slot_name的新逻辑(解码)复制槽,使用输出插件plugin。可选的第三个参数temporary,当设置为真时,指定槽不应永久存储到磁盘,仅供当前会话使用。临时槽也会在任何错误发生时释放。可选的第四个参数twophase,当设置为真时,指定为此槽启用预备事务的解码。调用此函数的效果与复制协议命令CREATE_REPLICATION_SLOT ... LOGICAL相同。 @@ -23809,8 +23670,9 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); 将一个名为src_slot_name的现有物理复制槽复制到一个名为dst_slot_name的物理复制槽。 - 被复制的物理槽开始从与源槽相同的LSN开始保留WAL。temporary是可选的。 + 复制后的物理槽从与源槽相同的LSN开始保留WAL。temporary是可选的。 如果省略了temporary,则使用与源槽相同的值。 + 不能复制已失效的槽。 @@ -23825,9 +23687,10 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); lsn pg_lsn ) - 复制一个名为src_slot_name的现有逻辑复制槽到一个名为dst_slot_name的逻辑复制槽,选择性的改变输出插件和持久性。 + 复制一个名为src_slot_name的现有逻辑复制槽到一个名为dst_slot_name的逻辑复制槽,可选地更改输出插件和持久性。 被复制的逻辑槽从与源逻辑槽相同的LSN开始。temporaryplugin都是可选的。 如果它们被省略了,使用与源逻辑槽相同的值。 + 不能复制已失效的槽。 @@ -23843,11 +23706,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); data text ) - 返回槽slot_name中的改变,从最后一次使用更改的点开始。 - 如果upto_lsnupto_nchanges为 NULL,逻辑解码将一直继续到 WAL 的末尾。 - 如果upto_lsn为非 NULL,解码将只包括那些在指定 LSN 之前提交的事务。 - 如果upto_nchanges为非 NULL,解码将在其产生的行数超过指定值后停止。 - 不过要注意,被返回的实际行数可能更大,因为对这个限制的检查只会在增加了解码每个新的提交事务产生的行之后进行。 + 返回槽 slot_name 中自上次消费更改的位置起的更改。如果 upto_lsnupto_nchanges 都为 NULL,逻辑解码会持续到 WAL 末尾。如果 upto_lsn 非 NULL,解码仅包含在指定 LSN 之前提交的事务。如果 upto_nchanges 非 NULL,解码产生的行数超过指定值时就会停止。不过,实际返回行数可能更大,因为只有在添加完对每个新事务提交进行解码所产生的行后,才会检查此限制。 @@ -23912,9 +23771,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); end_lsn pg_lsn ) - 将复制槽的当前确认的位置提前到名为slot_name的复制槽的当前确认位置。 - 该槽不会向后移动,也不会移动到当前插入位置之外。返回该槽的名称和它被推进到的真实位置。 - 如果有任何进展,则在下一个检查点中写出更新后的槽位置信息。所以如果发生崩溃,该槽位可能会返回到之前的位置。 + 推进名为 slot_name 的复制槽当前已确认的位置。该槽不会后退,也不会越过当前插入位置。返回槽名及其实际推进到的位置。如果发生了推进,更新后的槽位置信息会在下一个检查点写出。因此,发生崩溃时,槽可能回到更早的位置。 @@ -23966,8 +23823,8 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); void - 将当前会话标记为从给定的原点回放,从而允许跟踪回放进度。 - 只能在当前没有选择原点时使用。使用pg_replication_origin_session_reset 命令来撤销。 + 将当前会话标记为从给定的复制源重放,从而允许跟踪重放进度。 + 只能在当前没有选择复制源时使用。使用pg_replication_origin_session_reset来撤销。 @@ -24006,7 +23863,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); pg_lsn - 返回当前会话中选择的复制源的重放位置。参数flush决定对应的本地事务是否被确保已经刷入磁盘。 + 返回当前会话中选择的复制源的重放位置。参数flush决定是否保证对应的本地事务已刷盘。 @@ -24060,7 +23917,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); pg_lsn - 返回给定复制元的重放位置。参数flush决定对应的本地事务是否被确保已经刷入磁盘。 + 返回给定复制源的重放位置。参数flush决定是否保证对应的本地事务已刷盘。 @@ -24077,11 +23934,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); pg_lsn - 发出逻辑解码消息。这可以用于通过WAL将通用消息传递给逻辑解码插件。 - transactional参数指定消息是否应该是当前事务的一部分, - 还是应该立即写入并在逻辑解码器读取记录时立即解码。 - prefix参数是一个文本前缀,逻辑解码插件可以使用它轻松识别对它们有趣的消息。 - content参数是消息的内容,可以以文本或二进制形式给出。 + 发出逻辑解码消息。这可用于通过 WAL 向逻辑解码插件传递通用消息。transactional 参数指定消息是作为当前事务的一部分,还是立即写入并在逻辑解码器读到该记录时立即解码。prefix 参数是一个文本前缀,便于逻辑解码插件识别其关注的消息。content 参数是消息内容,可以文本或二进制形式给出。 @@ -24186,13 +24039,13 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); bigint - 计算指定关系的一个fork所使用的磁盘空间。 - (注意在大多数情况下,使用更高级的函数 pg_total_relation_sizepg_table_size更方便,它们将所有分叉(forks)的大小相加。) - 使用一个参数,这将返回关系的主数据分叉的大小。第二个参数可以用来指定要检查哪个分叉: + 计算指定关系的一个分支所使用的磁盘空间。 + (注意在大多数情况下,使用更高级的函数 pg_total_relation_sizepg_table_size更方便,它们将所有分支的大小相加。) + 使用一个参数,这将返回关系的主数据分支的大小。第二个参数可以用来指定要检查哪个分支: - main返回关系的主数据分叉的大小。 + main返回关系的主数据分支的大小。 @@ -24207,7 +24060,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); - init 返回初始化分叉的大小,如果有的话,与关系相关。 + init 返回与该关系关联的初始化分支(如有)的大小。 @@ -24223,7 +24076,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); bigint - 将人可阅读的格式的大小(由pg_size_pretty返回)转换为字节。 + 将人类可读格式的大小(由pg_size_pretty返回)转换为字节。有效的单位为bytesBkBMBGBTBPB @@ -24254,7 +24107,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); bigint - 计算指定表所使用的磁盘空间,不包括索引(但包括它的TOAST表,如果有的话,空闲空间映射,以及可见性映射)。 + 计算指定表所使用的磁盘空间,不包括索引(但包括其 TOAST 表(如有)、空闲空间映射和可见性映射)。 @@ -24288,7 +24141,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); 计算指定表所使用的总磁盘空间,包括所有索引和TOAST数据。 - 结果等价pg_table_size + pg_indexes_size。 + 结果等价于pg_table_size + pg_indexes_size @@ -24296,11 +24149,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); - 上述操作表和索引的函数接受一个regclass参数,它是该表或索引在pg_class系统目录中的 OID。 - 你不必手工去查找该 OID,因为regclass数据类型的输入转换器会为你代劳。 - 只写包围在单引号内的表名,这样它看起来像一个文字常量。 - 为了与普通SQL名称的处理相兼容,该字符串将被转换为小写形式,除非其中在表名周围包含双引号。 - 详见。 + 上述操作表和索引的函数接受一个regclass参数,即该表或索引在pg_class系统目录中的 OID。不必手工查找该 OID,因为regclass数据类型的输入转换器会代为查找。详见 @@ -24334,7 +24183,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); oid - 返回当前分配给指定关系的filenode数字。文件节点是用于该关系的文件名称的基本组件(更多信息请参阅 )。 + 返回当前分配给指定关系的文件结点编号。文件结点是用于该关系的文件名称的基本组件(更多信息请参阅 )。 对于大多数关系,其结果与pg_class.relfilenode相同,但对于某些系统目录,relfilenode为0,并且必须使用这个函数来获得正确的值。 如果传递的是一个没有存储的关系,例如一个视图,那么函数将返回NULL。 @@ -24349,7 +24198,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); text - 返回关系的完整文件路径名称(相对于数据库集簇的数据目录,即关系的PGDATA)。 + 返回关系的完整文件路径名称(相对于数据库集簇的数据目录,即PGDATA)。 @@ -24362,8 +24211,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); regclass - 返回一个给定表空间OID和存储它的文件节点的关系的OID。这本质上是pg_relation_filepath的反向映射。 - 对于数据库默认表空间中的关系,表空间可以指定为0。如果当前数据库中没有与给定值相关联的关系,则返回 NULL。 + 根据关系所在表空间的 OID 和文件结点返回该关系的 OID。这本质上是pg_relation_filepath的反向映射。对于数据库默认表空间中的关系,表空间可以指定为 0。如果当前数据库中没有与给定值关联的关系,或者该关系是临时关系,则返回NULL @@ -24430,13 +24278,13 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); integer - 基于在操作系统中找到的所有区域设置(locale),将排序规则加入系统目录pg_collation中。 - 这是 initdb 会用到的,更多细节请参考。 - 如果后来在操作系统上安装了额外的区域环境,可以再次运行这个函数加入新区域环境的排序规则。 - 匹配pg_collation中现有条目的区域环境将被跳过(但是这个函数不会移除以在操作系统中不再存在的区域环境为基础的排序规则对象)。 - schema参数通常是pg_catalog,但这并非强制要求,排序规则也可以安装到其他模式中。 - 该函数返回其创建的新排序规则对象的数量。 - 此函数仅限超级用户使用。 + 根据操作系统中找到的所有区域设置,向系统目录pg_collation添加排序规则。 + initdb使用的就是此函数;更多信息见。 + 如果以后在操作系统中安装了其他区域设置,可以再次运行此函数,为新区域设置添加排序规则。 + 与pg_collation中现有条目匹配的区域设置会被跳过。 + (但此函数不会删除基于操作系统中已不存在的区域设置的排序规则对象。) + schema参数通常为pg_catalog,但并非必须如此;也可以将排序规则安装到其他模式中。 + 函数返回新建的排序规则对象数量。此函数仅限超级用户使用。 @@ -24515,7 +24363,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); - 例如,要检查分区表measurement中包含的数据的总大小,可以使用以下查询: + 例如,要检查分区表measurement中包含的数据的总大小,可以使用以下查询: SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size FROM pg_partition_tree('measurement'); @@ -24530,7 +24378,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size 显示了索引维护任务可以使用的函数。 - (注意,这些维护任务通常由自动清理(autovacuum)自动完成;只有在特殊情况下才需要使用这些函数。) + (注意,这些维护任务通常由 autovacuum 自动完成;只有在特殊情况下才需要使用这些函数。) 这些函数在恢复过程中无法执行。这些函数的使用局限于超级用户和给定索引的所有者。 @@ -24561,7 +24409,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size integer - 扫描指定的BRIN索引以查找基表中当前尚未生成索引摘要的页面范围; + 扫描指定的BRIN索引以查找基表中当前尚未生成索引摘要的页面范围; 对于任何这样的范围,它都通过扫描这些表页来创建一个新的摘要索引元组。 返回插入到索引中的新页面范围摘要的数量。 @@ -24577,7 +24425,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size 对覆盖给定块的页面范围执行摘要(如果尚未摘要)。 - 这类似于brin_summarize_new_values,只是它只处理覆盖给定表块数的页范围。 + 这类似于brin_summarize_new_values,区别在于它只处理包含给定表块编号的页面范围。 @@ -24603,9 +24451,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size bigint - 清理指定GIN索引的pending列表,通过移除里面的条目,以大批的方式,到主要的GIN数据结构。 - 返回从挂起列表中删除的页数。如果参数是使用禁用fastupdate选项构建的GIN索引,则不会发生清理,结果为零,因为索引没有挂起的列表。 - 关于挂起列表和fastupdate选项的详细信息,请参见。 + 将指定 GIN 索引的待处理列表中的条目批量移入主 GIN 数据结构,从而清理该列表。返回从待处理列表中移除的页数。如果参数是禁用fastupdate选项构建的 GIN 索引,则不会进行清理,结果为零,因为该索引没有待处理列表。有关待处理列表和fastupdate选项的详细信息,参见 @@ -24620,21 +24466,20 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size 中展示的函数提供了对数据库服务器所在机器上的文件的本地访问。 - 只能访问数据库集簇目录以及log_directory中的文件,除非用户是超级用户或者被授予了角色pg_read_server_files。 + 只能访问数据库集簇目录以及log_directory中的文件,除非用户是超级用户或者被授予了角色pg_read_server_files。 使用相对路径访问集簇目录里面的文件,以及匹配 log_directory配置设置的路径访问日志文件。 - 注意在pg_read_file()或者相关函数上,向用户授予EXECUTE权限, - 以允许他们有能力读取服务器上该数据库服务器进程能读取的任何文件;这些函数会绕过所有的数据库内权限检查。 - 这意味着,例如,具有这种访问的用户能够读取pg_authid表中存储着认证信息的内容,也能读取数据库中的任何表数据。 - 因此,授予对这些函数的访问应该要很仔细地考虑。 + 注意,向用户授予pg_read_file()或相关函数的 EXECUTE 权限,会使其能够读取服务器上数据库服务器进程能读取的任何文件;这些函数会绕过数据库内部的所有权限检查。例如,具有这种访问权限的用户能够读取存储认证信息的pg_authid表的内容,以及数据库中的任何表数据。因此,授予这些函数的访问权限时应仔细考虑。 + + + + 授予这些函数的权限时,请注意:表中列出可选参数的条目,大多由多个参数列表不同的实际函数实现。若要使用其中某个函数,就必须单独授予该函数的权限。psql\df命令可以帮助检查实际的函数签名。 - 这些函数中的一些函数有可选的missing_ok参数,可以指定当文件或目录不存在时的行为。 - 如果为true,函数返回NULL或着空结果集,根据适合情况。 - 如果为false,会产生一个错误。默认为false。 + 这些函数中的一些函数接受可选的missing_ok参数,用于指定文件或目录不存在时的行为。如果为true,函数会视情况返回NULL或空结果集。如果为false,则会报错。(除文件未找到之外的失败情况,在任何情况下都会报错。)默认为false @@ -24664,12 +24509,12 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size setof text - 返回指定目录中所有文件(和目录以及其他指定文件)的名称。 - include_dot_dirs参数标示在结果集中是否包括...;默认为不包括它们。 - 要包括它们在missing_oktrue时能够有用,以从不存在的目录中辨别一个空目录。 + 返回指定目录中所有文件的名称(包括目录及其他特殊文件)。 + include_dot_dirs参数指示结果集中是否包含...;默认不包含它们。 + 在missing_oktrue时,包含它们有助于区分不存在的目录和空目录。 - 这个函数默认限制为超级用户,但是其他用户可以被授予EXECUTE以运行此函数。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -24688,7 +24533,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size 返回服务器日志目录中每个普通文件的名称、大小和最后修改时间(mtime)。以点开头的文件名、目录和其他特殊文件将被排除。 - 默认情况下,此函数仅限于超级用户和具有pg_monitor角色权限的角色,但其他用户可以被授予EXECUTE权限来运行该函数。 + 默认情况下,此函数仅限超级用户和具有pg_monitor角色权限的角色使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -24708,8 +24553,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size 以点开头的文件名、目录和其他特殊文件将被排除。 - 默认情况下,此函数仅限于超级用户和具有pg_monitor角色权限的角色, - 但其他用户可以被授予EXECUTE权限来运行该函数。 + 默认情况下,此函数仅限超级用户和具有pg_monitor角色权限的角色使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -24729,7 +24573,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size 以点开头的文件名、目录和其他特殊文件将被排除。 - 默认情况下,此函数仅限于超级用户和pg_monitor角色的成员,但其他用户可以被授予EXECUTE权限来运行该函数。 + 默认情况下,此函数仅限超级用户和pg_monitor角色的成员使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -24749,7 +24593,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size 以点开头的文件名、目录和其他特殊文件将被排除。 - 默认情况下,此函数仅限于超级用户和pg_monitor角色的成员,但其他用户可以被授予EXECUTE权限来运行该函数。 + 默认情况下,此函数仅限超级用户和pg_monitor角色的成员使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -24769,7 +24613,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size 其中slot_name是作为函数输入提供的复制槽的名称。以点开头的文件名、目录和其他特殊文件将被排除。 - 默认情况下,此函数仅限于超级用户和pg_monitor角色的成员,但其他用户可以被授予EXECUTE权限来运行该函数。 + 默认情况下,此函数仅限超级用户和pg_monitor角色的成员使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -24785,11 +24629,11 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size modificationtimestamp with time zone ) - 返回服务器的WAL归档状态目录(pg_wal/archive_status)中的每个普通文件的名称、大小、和最后修改时间(mtime)。 - 文件名以一个点(dot)开始,目录和其他指定的文件不包括。 + 返回服务器 WAL 归档状态目录(pg_wal/archive_status)中每个普通文件的名称、大小和最后修改时间(mtime)。 + 以点号开头的文件名、目录以及其他特殊文件都不会包含在结果中。 - 这个函数默认限制在超级用户和pg_monitor角色的成员,但是其他用户可以被授予EXECUTE以运行此函数。 + 默认情况下,此函数仅限超级用户和pg_monitor角色的成员使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -24806,12 +24650,12 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size modificationtimestamp with time zone ) - 返回针对指定tablespace的临时文件目录中的每个普通文件的名称、大小、和最后修改时间(mtime)。 - 如果tablespace没有提供,pg_default 表空间为被检验的。 - 文件名以一个点(dot)开始,目录和其他指定的文件不包括。 + 返回针对指定tablespace的临时文件目录中每个普通文件的名称、大小和最后修改时间(mtime)。 + 如果未提供tablespace,则检查pg_default表空间。 + 以点号开头的文件名、目录以及其他特殊文件都不会包含在结果中。 - 这个函数默认限制在超级用户和pg_monitor角色的成员,但是其他用户可以被授予EXECUTE以运行此函数。 + 默认情况下,此函数仅限超级用户和pg_monitor角色的成员使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -24820,16 +24664,16 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size pg_read_file - pg_read_file ( filenametext, offset bigint, length bigint , missing_ok boolean ) + pg_read_file ( filenametext, offset bigint, length bigint , missing_ok boolean ) text - 返回一个文本文件的全部或部分,开始于给定的字节offset,在最大的length字节返回(如果文件的结尾先达到了则减少)。 - 如果offset为负,他于文件的结尾有关。如果offsetlength 被省略,整个文件被返回。 - 从文件中读的字节在服务器的编码中解释为字符串;如果它们在哪些编码中不是有效的则抛出错误。 + 返回一个文本文件的全部或部分,从给定的字节offset开始,最多返回length字节(如果先到达文件末尾,则返回更少)。 + 如果offset为负,则它相对于文件末尾计算。如果省略offsetlength,则返回整个文件。 + 从文件中读取的字节会按数据库编码解释为字符串;如果它们在该编码下无效,则会抛出错误。 - 这个函数默认限制在超级用户,但是其他用户可以被授予EXECUTE以运行此函数。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -24838,18 +24682,18 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size pg_read_binary_file - pg_read_binary_file ( filenametext, offset bigint, length bigint , missing_ok boolean ) + pg_read_binary_file ( filenametext, offset bigint, length bigint , missing_ok boolean ) bytea - 返回文件的全部或部分。这个函数与pg_read_file 是完全相同的,除了它可以读任意的二进制数据,返回结果为bytea而不是text; - 因此,没有编码检查会被执行。 + 返回文件的全部或部分。该函数与pg_read_file完全相同,只是它可以读取任意二进制数据,并返回bytea而不是text; + 因此不会执行编码检查。 - 这个函数默认限制在超级用户,但是其他用户可以被授予EXECUTE以运行此函数。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 - 与 convert_from函数组合,这个函数能被用于以指定的编码读文本文件并转换到数据库的编码: + 与convert_from函数配合使用时,该函数可用于按指定编码读取文本文件,并将其转换为数据库编码: SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); @@ -24871,10 +24715,10 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); isdir boolean ) - 返回一个记录,包含文件的大小、最后访问时间戳、最后修改时间戳,最后文件状态变更时间戳(仅在UNIX平台)、文件建立时间戳(仅Windows),和一个标志旗如果它是一个目录。 + 返回一个记录,包含文件大小、最后访问时间戳、最后修改时间戳、最后文件状态变更时间戳(仅限 Unix 平台)、文件创建时间戳(仅限 Windows)以及一个指示其是否为目录的标志。 - 这个函数默认限制在超级用户,但是其他用户可以被授予EXECUTE以运行此函数。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -24894,11 +24738,11 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); - 所有这些函数都打算用于锁定应用程序定义的资源,可以通过一个64位键值或两个32位键值来标识(注意这两个键空间不能重叠)。 - 如果另一个会话已经在相同的资源标识符上持有一个冲突的锁,函数将等待直到资源变成可用,或者返回一个false结果,合适于函数的。 - 锁可以是共享或排他的:共享锁不会与同一资源上的其他共享锁发生冲突,只会与排他锁发生冲突。 - 锁可以在会话级(这样它们被保持直到释放或会话结束)或在事务级(这样它们被保持直到当前事务结束;没有手动释放的供应)。 - 多个会话级锁请求堆栈,因此如果同一个资源标识符被锁定三次,那么必须有三个解锁请求来释放资源,在会话结束之前。 + 这些函数用于锁定应用程序定义的资源;资源可用一个 64 位键值或两个 32 位键值标识(这两个键空间互不重叠)。 + 如果另一个会话已对同一资源标识符持有冲突锁,函数会根据自身的行为等待资源可用,或返回false。 + 锁可以是共享的或排他的:共享锁不会与同一资源上的其他共享锁冲突,只会与排他锁冲突。 + 锁可以在会话级获取(一直保持到释放或会话结束),也可以在事务级获取(一直保持到当前事务结束,不能手动释放)。 + 多次会话级锁请求会累加,因此,如果同一资源标识符被锁定三次,就必须请求解锁三次,才能在会话结束前释放该资源。
@@ -25049,8 +24893,8 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); boolean - 获取一个排他的会话级咨询锁,如果适用。 - 这将立即获得锁并返回true,或者如果不能立即获取锁则立即返回 false而无需等待。 + 尝试获取一个排他的会话级咨询锁。 + 如果能立即获取到锁,就返回true;否则立即返回false,而不等待。 @@ -25067,8 +24911,8 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); boolean - 获取一个共享的会话级咨询锁,如果适用。 - 这将立即获得锁并返回true,或者如果不能立即获取锁则立即返回 false而无需等待。 + 尝试获取一个共享的会话级咨询锁。 + 如果能立即获取到锁,就返回true;否则立即返回false,而不等待。 @@ -25085,8 +24929,8 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); boolean - 获取一个排他的事务级咨询锁,如果适用。 - 这将立即获得锁并返回true,或者如果不能立即获取锁则立即返回 false而无需等待。 + 尝试获取一个排他的事务级咨询锁。 + 如果能立即获取到锁,就返回true;否则立即返回false,而不等待。 @@ -25103,8 +24947,8 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); boolean - 获取一个共享的事务级咨询锁,如果适用。 - 这将立即获得锁并返回true,或者如果不能立即获取锁则立即返回 false而无需等待。 + 尝试获取一个共享的事务级咨询锁。 + 如果能立即获取到锁,就返回true;否则立即返回false,而不等待。 @@ -25159,7 +25003,7 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); trigger - 阻止不做事的更新操作。详见下文。 + 抑制不改变数据的更新操作。详见下文。 CREATE TRIGGER ... suppress_redundant_updates_trigger() @@ -25175,8 +25019,7 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); trigger - 自动从相关的纯文本文档列更新tsvector列。 - 要使用的文本搜索配置是以名称指定为触发器参数。详情请参见。 + 根据关联的纯文本文档列自动更新tsvector列。所用的全文检索配置以名称形式指定为触发器参数。详见 CREATE TRIGGER ... tsvector_update_trigger(tsvcol, 'pg_catalog.swedish', title, body) @@ -25192,8 +25035,7 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); trigger - 自动从相关的纯文本文档列更新tsvector列。 - 要使用的文本搜索配置取自表的regconfig列。详情请参见。 + 根据关联的纯文本文档列自动更新tsvector列。所用的全文检索配置取自表的regconfig列。详见 CREATE TRIGGER ... tsvector_update_trigger_column(tsvcol, tsconfigcol, title, body) @@ -25210,23 +25052,15 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); - 理想的情况下,你应该避免运行实际上并没有改变记录中数据的更新。 - 冗余更新会花费大量不必要的时间,尤其是如果有大量索引要改变, 并将最终不得不清理被死亡行占用的空间。 - 但是,在客户端代码中检测这种情况并不总是容易的,甚至不可能做到。 而写表达式来检测它们容易产生错误。 - 作为替代,使用suppress_redundant_updates_trigger可以跳过不改变数据的更新。 但是,你需要小心使用它。 - 触发器需要很短但不能忽略的时间来处理每条记录,所以如果受更新影响的大多数记录确实变化了,此触发器的使用将使更新比平均水平运行得更慢。 + 理想情况下,应避免执行实际上不会改变记录中数据的更新。冗余更新会耗费大量不必要的时间,尤其是在需要修改许多索引时;它们还会使死行占用空间,最终需要通过清理回收。但是,在客户端代码中检测这种情况并不总是容易,甚至可能无法做到,而编写用于检测的表达式也容易出错。另一种办法是使用suppress_redundant_updates_trigger,跳过不改变数据的更新。但使用时应当谨慎。此触发器处理每条记录的耗时虽小,却不可忽略,因此如果更新涉及的大多数记录确实会改变,使用此触发器反而会增加更新的平均耗时。 - suppress_redundant_updates_trigger函数可以像这样添加到表中: - + 该suppress_redundant_updates_trigger函数可以按如下方式添加到表中: CREATE TRIGGER z_min_update BEFORE UPDATE ON tablename FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); - - 在大多数情况下,你需要为每一行最后触发这个触发器,这样它就不会覆盖可能希望更改该行的其他触发器。 - 请记住,触发器是按照名称顺序触发的,你将为此选择一个触发器名称,该名称位于表中可能存在的任何其他触发器的名称之后。 - (因此在示例中使用了z前缀。) +大多数情况下,需要让该触发器对每一行最后触发,以免覆盖其他可能修改该行的触发器的效果。由于触发器按名称顺序触发,应选择一个排序位于表上其他所有触发器名称之后的名称。(这就是示例中使用z前缀的原因。) @@ -25235,7 +25069,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); 事件触发器函数 - PostgreSQL提供了这些助手函数来从事件触发器检索信息。 + PostgreSQL提供了这些辅助函数来从事件触发器检索信息。 @@ -25257,7 +25091,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); 当在一个ddl_command_end事件触发器的函数中调用时,pg_event_trigger_ddl_commands返回被每一个用户动作执行的DDL命令的列表。 如果在其他任何环境中调用这个函数,会发生错误。 - pg_event_trigger_ddl_commands为每一个被执行的基本命令返回一行,某些只有一个单一 SQL 句子的命令可能会返回多于一行。 + pg_event_trigger_ddl_commands为每一个被执行的基本命令返回一行,某些由单条 SQL 语句构成的命令可能会返回多于一行。 这个函数返回下面的列: @@ -25274,7 +25108,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); classid oid - 对象所属的目录的 OID + 对象所属系统目录的 OID objid @@ -25284,7 +25118,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); objsubid integer - 对象的子-id(例如列的属性号) + 子对象 ID(例如列的属性编号) command_tag @@ -25300,16 +25134,14 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); schema_name text - 该对象所属的模式的名称(如果有),如果没有则为NULL。 - 没有引号。 + 对象所属模式的名称(若有);否则为NULL。不加引号。 object_identity text - 对象标识的文本表现形式,用模式限定。如果必要,出现在 - 该标识中的每一个标识符都会被引用。 + 对象标识的文本表示形式,带模式限定。标识中包含的每个标识符在必要时都会加引号。 @@ -25321,8 +25153,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); command pg_ddl_command - 以内部格式表达的该命令的一个完整表现形式。这不能被直接输出, - 但是可以把它传递给其他函数来得到有关于该命令不同部分的信息。 + 命令的完整内部表示,不能直接输出,但可以将其传给其他函数以获取关于该命令的不同信息。 @@ -25344,8 +25175,8 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); - pg_event_trigger_dropped_objects返回被调用sql_drop事件的命令删除的所有对象的列表。 - 如果调用在任何其他上下文中,会引发一个错误。这个函数返回以下列: + 在命令的sql_drop事件中调用pg_event_trigger_dropped_objects时,它返回该命令删除的所有对象的列表。 + 如果调用在任何其他上下文中,会引发一个错误。这个函数返回以下列: @@ -25361,7 +25192,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); classid oid - 对象所属的目录的 OID + 对象原先所属系统目录的 OID objid @@ -25371,7 +25202,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); objsubid integer - 子对象ID(如列的属性号) + 子对象 ID(例如列的属性编号) original @@ -25382,7 +25213,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); normal boolean - 指示在依赖图中有一个普通依赖关系指向该对象的标志 + 如果依赖图中存在指向该对象的普通依赖关系,则为真。 @@ -25401,29 +25232,28 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); schema_name text - 对象所属模式的名称(如果存在);否则为NULL。不应用引用。 + 对象原先所属模式的名称(若有);否则为NULL。不加引号。 object_name text - 如果模式和名称的组合能被用于对象的一个唯一标识符,则是对象的名称;否则是NULL。不应用引用,并且名称不是模式限定的。 + 如果模式和名称的组合可用作该对象的唯一标识符,则为对象名称;否则为NULL。不加引号,并且该名称永远不带模式限定。 object_identity text - 对象身份的文本表现,模式限定的。每一个以及所有身份中出现的标识符在必要时加引号。 + 对象标识的文本表示形式,带模式限定。标识中包含的每个标识符在必要时都会加引号。 address_names text[] - 一个数组,它可以和object_typeaddress_args, - 一起通过pg_get_object_address函数在一台包含有同类相同名称对象的远程服务器上重建该对象地址。 + 一个数组,可与object_typeaddress_args一起,通过pg_get_object_address函数在包含同类同名对象的远程服务器上重建该对象地址。 @@ -25522,7 +25352,7 @@ CREATE EVENT TRIGGER test_event_trigger_for_drops
- 这些函数可以在事件触发器中使用,就像这样: + 这些函数可以在事件触发器中使用,就像这样: CREATE FUNCTION test_event_trigger_table_rewrite_oid() RETURNS event_trigger @@ -25548,12 +25378,12 @@ CREATE EVENT TRIGGER test_table_rewrite_oid 统计信息函数 - function - statistics + 函数 + 统计信息 - PostgreSQL提供了一个函数来检查使用CREATE STATISTICS命令定义的复杂统计。 + PostgreSQL提供了一个函数来检查使用CREATE STATISTICS命令定义的复杂统计信息。 @@ -25569,7 +25399,7 @@ CREATE EVENT TRIGGER test_table_rewrite_oid - pg_mcv_list_items返回一组记录,描述存储在多列MCV列表中的所有项目。它返回以下列: + pg_mcv_list_items返回一组记录,描述存储在多列MCV列表中的所有项目。它返回以下列: @@ -25605,7 +25435,7 @@ CREATE EVENT TRIGGER test_table_rewrite_oid base_frequency double precision - MCV项目的基本频率 + MCV项目的基础频率 @@ -25613,7 +25443,7 @@ CREATE EVENT TRIGGER test_table_rewrite_oid - pg_mcv_list_items函数可以这样使用: + pg_mcv_list_items函数可以这样使用: SELECT m.* FROM pg_statistic_ext join pg_statistic_ext_data on (oid = stxoid), diff --git a/zh/16/generic-wal.sgml b/zh/16/generic-wal.sgml index 5b96333b..5edefc7c 100644 --- a/zh/16/generic-wal.sgml +++ b/zh/16/generic-wal.sgml @@ -8,7 +8,8 @@ - 与自定义 WAL 资源管理器相比,Generic WAL 对扩展来说更容易实现,而且在应用这些记录时不要求加载扩展库。 + 与自定义 WAL 资源管理器相比,通用 WAL 对扩展而言实现更简单, + 而且应用这些记录时不需要加载扩展库。 diff --git a/zh/16/gin.sgml b/zh/16/gin.sgml index 785d8c75..6a611952 100644 --- a/zh/16/gin.sgml +++ b/zh/16/gin.sgml @@ -8,7 +8,7 @@ GIN - + 简介 @@ -47,13 +47,13 @@ Teodor Sigaev 和 Oleg Bartunov 维护。关于 GIN 的更多信息, 可在他们的 网站 上找到。 - + - + 内置操作符类 - PostgreSQL 核心发布包含 + PostgreSQL 核心发行版包含 所示的 GIN 操作符类。 (在 中描述的一些可选模块还提供额外的 GIN 操作符类。) @@ -111,9 +111,12 @@ @@ (jsonb,jsonpath) - tsvector_ops + tsvector_ops @@ (tsvector,tsquery) + + @@@ (tsvector,tsquery) + @@ -124,9 +127,9 @@ 详见 - + - + 可扩展性 @@ -152,7 +155,7 @@ 给定一个要建立索引的项,返回一个用 palloc 分配的键数组。返回键的数量必须存入 *nkeys。如果任一键可以为 null,还要另外 palloc 一个包含 *nkeysbool 字段的数组,将其地址存入 - *nullFlags,并按需设置这些空值标志。如果所有键都非空, + *nullFlags,并按需设置这些空值标志。如果所有键都不是 null, *nullFlags 可以保持为 NULL(其初始值)。 如果该项不包含任何键,则返回值可以为 NULL @@ -172,7 +175,7 @@ query 的数据类型,以及应采用何种方法提取键值。返回键的数量必须存入 *nkeys。如果任一键可以为 null,还要另外 palloc 一个包含 *nkeysbool 字段的数组,将其地址存入 - *nullFlags,并按需设置这些空值标志。如果所有键都非空, + *nullFlags,并按需设置这些空值标志。如果所有键都不是 null, *nullFlags 可以保持为 NULL(其初始值)。 如果 query 不包含任何键,则返回值可以为 NULL。 @@ -185,7 +188,7 @@ 被设置为 GIN_SEARCH_MODE_INCLUDE_EMPTY,则除至少包含一个匹配键的项之外, 完全不含任何键的项也会被视为候选匹配。(例如,该模式对于实现是子集操作符很有用。) 若 *searchMode 被设置为 GIN_SEARCH_MODE_ALL, - 则索引中所有非空项都会被视为候选匹配,无论它们是否匹配任一返回键。 + 则索引中所有非 null 项都会被视为候选匹配,无论它们是否匹配任一返回键。 (该模式比前两种选择慢得多,因为它基本上需要扫描整个索引;但为了正确处理某些边界情况, 可能有此必要。在大多数情况下都需要此模式的操作符,大概并不适合作为 GIN 操作符类的候选。)用于设置该模式的符号定义在 @@ -218,7 +221,7 @@ 操作符类还必须提供一个函数,用于检查被索引项是否匹配查询。它有两种形式:布尔型 consistent 函数,以及三值型 triConsistent 函数。 triConsistent 覆盖了两者的功能,因此仅提供 triConsistent - 就已经足够。不过,如果布尔变体的计算明显更便宜,那么同时提供两者会更有利。 + 就已经足够。不过,如果布尔变体的计算代价明显更低,那么同时提供两者可能更有利。 若只提供布尔变体,则一些依赖于在取回所有键之前先排除索引项的优化将被禁用。 @@ -233,10 +236,10 @@ 该函数无法直接访问被索引项的值,因为 GIN 并不显式存储项。 它所能利用的是这样一种信息:从查询中提取出的哪些键值出现在给定的被索引项中。 check 数组长度为 nkeys,这与先前针对该 - query 数据由 extractQuery 返回的键数量相同。 + query datum 由 extractQuery 返回的键数量相同。 如果被索引项包含相应查询键,则 check 数组中的对应元素为 true; 也就是说,如果 check[i] == true,则 extractQuery - 结果数组中的第 i 个键存在于该被索引项中。传入原始 query 数据值, + 结果数组中的第 i 个键存在于该被索引项中。传入原始 query datum, 是为了让 consistent 方法在需要时可以查看它;同样也会传入先前由 extractQuery 返回的 queryKeys[]nullFlags[] 数组。extra_data 则是 @@ -274,7 +277,7 @@ 而 GIN_MAYBE 表示该键是否存在尚不确定。存在 GIN_MAYBE 值时,只有当无论索引项是否包含对应查询键,该项都确定匹配时,函数才应返回 GIN_TRUE。同样,只有当无论是否包含 GIN_MAYBE 键, - 该项都确定不匹配时,函数才必须返回 GIN_FALSE。如果结果依赖于 + 该项都确定不匹配时,函数才能返回 GIN_FALSE。如果结果依赖于 GIN_MAYBE 条目,也就是说,无法根据已知的查询键确认或否定匹配, 则函数必须返回 GIN_MAYBE。 @@ -306,7 +309,7 @@ 或者,如果操作符类没有提供 compare 方法,GIN 将查找该索引键数据类型的默认 B-树操作符类,并使用其比较函数。建议在仅面向单一数据类型的 - GIN 操作符类中显式指定比较函数,因为查找 B-树操作符类会消耗少量周期。 + GIN 操作符类中显式指定比较函数,因为查找 B-树操作符类会消耗少量处理器周期。 不过,多态 GIN 操作符类(例如 array_ops)通常无法指定单一比较函数。 @@ -367,15 +370,15 @@ 尽管依据具体操作符,实际类型可能是别的类型。 - + - + 实现 在内部,一个 GIN 索引包含一个基于键构建的 B-树索引,其中每个键都是一个或多个被索引项中的某个元素 - (例如数组成员),而叶子页中的每个元组要么包含一个指向堆指针 B-树的指针(posting tree), - 要么在列表足够小、能够连同键值一起放入单个索引元组时,直接包含一个简单的堆指针列表(posting list)。 + (例如数组成员),而叶子页中的每个元组要么包含一个指向堆指针 B-树的指针(倒排树), + 要么在列表足够小、能够连同键值一起放入单个索引元组时,直接包含一个简单的堆指针列表(倒排列表)。 展示了 GIN 索引的这些组成部分。 @@ -399,7 +402,7 @@ - + GIN 快速更新技术 @@ -422,13 +425,13 @@ - 如果一致的响应时间比更新速度更重要,可以通过关闭 GIN 索引的 + 如果稳定的响应时间比更新速度更重要,可以通过关闭 GIN 索引的 fastupdate 存储参数来禁用待处理列表机制。详见 - + - + 部分匹配算法 @@ -442,11 +445,11 @@ 对于虽然不匹配但仍处在待搜索范围内的索引键,返回小于零; 如果索引键已经超出了可能匹配的范围,则返回大于零。 - - - + + + GIN 提示和技巧 @@ -461,7 +464,7 @@ 当为 GIN 启用 fastupdate 时 (详见 ),这种代价会比未启用时小一些。 - 但对于非常大的更新,最好仍然是删除并重建索引。 + 但对于非常大的更新,删除并重建索引仍然可能是最佳选择。 @@ -520,24 +523,24 @@ - + - + 限制 GIN 假定可索引操作符是严格的。这意味着,当项值为 null 时, 根本不会对其调用 extractValue(而是自动创建一个占位符索引项); 当查询值为 null 时,也不会调用 extractQuery(而是认为该查询不可满足)。 - 不过要注意,非空组合项或查询值内部包含的 null 键值仍然受支持。 + 不过要注意,非 null 的组合项或查询值内部包含的 null 键值仍然受支持。 - + - + 示例 - PostgreSQL 核心发布包含前面在 + PostgreSQL 核心发行版包含前面在 中展示过的 GIN 操作符类。 下列 contrib 模块也包含 GIN 操作符类: @@ -571,6 +574,6 @@ - + diff --git a/zh/16/gist.sgml b/zh/16/gist.sgml index a9a1e4a2..2413cefa 100644 --- a/zh/16/gist.sgml +++ b/zh/16/gist.sgml @@ -4,11 +4,11 @@ GiST 索引 - index + 索引 GiST - + 简介 @@ -30,9 +30,9 @@ 网站上还有更多信息。 - + - + 内置操作符类 @@ -201,9 +201,9 @@ CREATE INDEX ON my_table USING GIST (my_inet_column inet_ops); - + - + 可扩展性 @@ -211,7 +211,7 @@ CREATE INDEX ON my_table USING GIST (my_inet_column inet_ops); - 这种可扩展性不应与其他标准搜索树在可处理数据方面的可扩展性相混淆。例如,PostgreSQL支持可扩展的 B-树和哈希索引。这意味着你可以用PostgreSQL在任意数据类型上构建 B-树或哈希索引。但 B-树只支持范围谓词(<=>),而哈希索引只支持等值查询。 + 这种可扩展性不应与其他标准搜索树在可处理数据方面的可扩展性相混淆。例如,PostgreSQL支持可扩展的 B-树和 hash 索引。这意味着你可以用PostgreSQL在任意数据类型上构建 B-树或 hash 索引。但 B-树只支持范围谓词(<=>),而 hash 索引只支持等值查询。 @@ -223,7 +223,7 @@ CREATE INDEX ON my_table USING GIST (my_inet_column inet_ops); - 一个GiST索引操作符类必须提供五个方法,另外还有七个可选方法。通过正确实现sameconsistentunion方法可以保证索引的正确性,而索引的效率(大小与速度)则取决于penaltypicksplit方法。两个可选方法是compressdecompress,它们允许索引的内部树数据使用与其所索引数据不同的类型。叶子必须是被索引数据类型,而其他树节点可以是任意 C 结构体(但这里仍必须遵守PostgreSQL的数据类型规则,关于变长数据可参见varlena)。如果树的内部数据类型在 SQL 层存在,可以使用CREATE OPERATOR CLASS命令的STORAGE选项。可选的第八个方法是distance,若操作符类希望支持有序扫描(最近邻搜索),则需要它。可选的第九个方法fetch在操作符类希望支持仅索引扫描时需要,除非省略了compress方法。可选的第十个方法options在操作符类具有用户指定参数时需要。可选的第十一个方法sortsupport用于加速构建GiST索引。可选的第十二个方法translate_cmptype用于把比较类型(来自src/include/access/cmptype.h)转换为该操作符类使用的策略号。这样核心代码就可以为时态约束索引查找操作符。 + 一个GiST索引操作符类必须提供五个方法,另外还有六个可选方法。通过正确实现sameconsistentunion方法可以保证索引的正确性,而索引的效率(大小与速度)则取决于penaltypicksplit方法。两个可选方法是compressdecompress,它们允许索引的内部树数据使用与其所索引数据不同的类型。叶子必须是被索引数据类型,而其他树节点可以是任意 C 结构体(但这里仍必须遵守PostgreSQL的数据类型规则,关于变长数据可参见varlena)。如果树的内部数据类型在 SQL 层存在,可以使用CREATE OPERATOR CLASS命令的STORAGE选项。可选的第八个方法是distance,若操作符类希望支持有序扫描(最近邻搜索),则需要它。可选的第九个方法fetch在操作符类希望支持仅索引扫描时需要,除非省略了compress方法。可选的第十个方法options在操作符类具有用户指定参数时需要。可选的第十一个方法sortsupport用于加速构建GiST索引。 @@ -262,15 +262,14 @@ my_consistent(PG_FUNCTION_ARGS) bool retval; /* - * determine return value as a function of strategy, key and query. + * 根据 strategy、key 和 query 确定返回值。 * - * Use GIST_LEAF(entry) to know where you're called in the index tree, - * which comes handy when supporting the = operator for example (you could - * check for non empty union() in non-leaf nodes and equality in leaf - * nodes). + * 使用 GIST_LEAF(entry) 判断当前调用位于索引树的哪个位置。 + * 例如,支持 = 操作符时这很有用(可以在非叶节点检查 + * union() 是否非空,在叶节点检查是否相等)。 */ - *recheck = true; /* or false if check is exact */ + *recheck = true; /* 如果检查是精确的,则为 false */ PG_RETURN_BOOL(retval); } @@ -386,10 +385,10 @@ my_compress(PG_FUNCTION_ARGS) if (entry->leafkey) { - /* replace entry->key with a compressed version */ + /* 将 entry->key 替换为压缩后的形式 */ compressed_data_type *compressed_data = palloc(sizeof(compressed_data_type)); - /* fill *compressed_data from entry->key ... */ + /* 根据 entry->key 填充 *compressed_data ... */ retval = palloc(sizeof(GISTENTRY)); gistentryinit(*retval, PointerGetDatum(compressed_data), @@ -397,7 +396,7 @@ my_compress(PG_FUNCTION_ARGS) } else { - /* typically we needn't do anything with non-leaf entries */ + /* 通常无需对非叶项做任何处理 */ retval = entry; } @@ -460,7 +459,7 @@ my_decompress(PG_FUNCTION_ARGS) CREATE OR REPLACE FUNCTION my_penalty(internal, internal, internal) RETURNS internal AS 'MODULE_PATHNAME' -LANGUAGE C STRICT; -- in some cases penalty functions need not be strict +LANGUAGE C STRICT; -- 某些情况下 penalty 函数不必是严格函数 而 C 模块中的对应代码则可以遵循如下框架: @@ -482,7 +481,7 @@ my_penalty(PG_FUNCTION_ARGS) } - 出于历史原因,penalty函数并不是直接返回一个float结果;相反,它必须把该值存储到第三个参数指示的位置。返回值本身会被忽略,不过通常会返回该参数的地址。 + 出于历史原因,penalty函数并不是直接返回一个float结果;相反,它必须把该值存储到第三个参数指示的位置。返回值本身会被忽略,不过通常会返回该参数所指向的地址。 @@ -543,7 +542,7 @@ my_picksplit(PG_FUNCTION_ARGS) unionL = NULL; unionR = NULL; - /* Initialize the raw entry vector. */ + /* 初始化原始项向量。 */ raw_entryvec = (GISTENTRY **) malloc(entryvec->n * sizeof(void *)); for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) raw_entryvec[i] = &(entryvec->vector[i]); @@ -556,9 +555,9 @@ my_picksplit(PG_FUNCTION_ARGS) Assert(tmp_union != NULL); /* - * Choose where to put the index entries and update unionL and unionR - * accordingly. Append the entries to either v->spl_left or - * v->spl_right, and care about the counters. + * 选择索引项的存放位置,并相应更新 unionL 和 unionR。 + * 将项追加到 v->spl_left 或 v->spl_right, + * 同时更新计数器。 */ if (my_choice_is_left(unionL, curl, unionR, curr)) @@ -575,7 +574,7 @@ my_picksplit(PG_FUNCTION_ARGS) else { /* - * Same on the right + * 对右侧执行相同操作 */ } } @@ -629,7 +628,7 @@ my_same(PG_FUNCTION_ARGS) } - 出于历史原因,same函数并不是直接返回一个布尔结果;相反,它必须把该标志存储到第三个参数指示的位置。返回值本身会被忽略,不过通常会返回该参数的地址。 + 出于历史原因,same函数并不是直接返回一个布尔结果;相反,它必须把该标志存储到第三个参数指示的位置。返回值本身会被忽略,不过通常会返回该参数所指向的地址。 @@ -668,7 +667,7 @@ my_distance(PG_FUNCTION_ARGS) double retval; /* - * determine return value as a function of strategy, key and query. + * 根据 strategy、key 和 query 确定返回值。 */ PG_RETURN_FLOAT8(retval); @@ -679,11 +678,11 @@ my_distance(PG_FUNCTION_ARGS) - 在确定距离时允许有一定近似,只要结果永不大于该项的实际距离即可。因此,例如在几何应用中,到外包盒的距离通常就足够了。对于内部树节点,返回的距离不能大于其任一子节点的距离。如果返回的距离不精确,函数必须将*recheck设为 true。(对内部树节点则不必这样做;对它们总是假定计算结果不精确。)在这种情况下,执行器会在从堆中取出元组后计算准确距离,并在必要时重新排序这些元组。 + 在确定距离时允许有一定近似,只要结果永不大于该项的实际距离即可。因此,例如在几何应用中,到包围盒的距离通常就足够了。对于内部树节点,返回的距离不能大于其任一子节点的距离。如果返回的距离不精确,函数必须将*recheck设为 true。(对内部树节点则不必这样做;对它们总是假定计算结果不精确。)在这种情况下,执行器会在从堆中取出元组后计算准确距离,并在必要时重新排序这些元组。 - 如果距离函数对任何叶节点都返回*recheck = true,原始排序操作符的返回类型必须是float8float4,且距离函数的结果值必须能与原始排序操作符的结果进行比较,因为执行器会同时使用距离函数结果和重新计算得到的排序操作符结果进行排序。否则,距离函数的结果值可以是任意有限的float8值,只要这些结果值的相对顺序与排序操作符返回的顺序一致即可。(无穷大和负无穷在内部用于处理空值等情况,因此不建议distance函数返回这些值。) + 如果距离函数对任意一个叶节点返回*recheck = true,原始排序操作符的返回类型必须是float8float4,且距离函数的结果值必须能与原始排序操作符的结果进行比较,因为执行器会同时使用距离函数结果和重新计算得到的排序操作符结果进行排序。否则,距离函数的结果值可以是任意有限的float8值,只要这些结果值的相对顺序与排序操作符返回的顺序一致即可。(无穷大和负无穷在内部用于处理空值等情况,因此不建议distance函数返回这些值。) @@ -727,10 +726,10 @@ my_fetch(PG_FUNCTION_ARGS) fetched_data = palloc(sizeof(fetched_data_type)); /* - * Convert 'fetched_data' into the a Datum of the original datatype. + * 将 'fetched_data' 转换为原始数据类型的 Datum。 */ - /* fill *retval from fetched_data. */ + /* 根据 fetched_data 填充 *retval。 */ gistentryinit(*retval, PointerGetDatum(converted_datum), entry->rel, entry->page, entry->offset, FALSE); @@ -781,26 +780,26 @@ typedef enum MyEnumType typedef struct { - int32 vl_len_; /* varlena header (do not touch directly!) */ - int int_param; /* integer parameter */ - double real_param; /* real parameter */ - MyEnumType enum_param; /* enum parameter */ - int str_param; /* string parameter */ + int32 vl_len_; /* varlena 首部(不要直接操作!) */ + int int_param; /* 整数参数 */ + double real_param; /* 实数参数 */ + MyEnumType enum_param; /* 枚举参数 */ + int str_param; /* 字符串参数 */ } MyOptionsStruct; -/* String representation of enum values */ +/* 枚举值的字符串表示 */ static relopt_enum_elt_def myEnumValues[] = { {"on", MY_ENUM_ON}, {"off", MY_ENUM_OFF}, {"auto", MY_ENUM_AUTO}, - {(const char *) NULL} /* list terminator */ + {(const char *) NULL} /* 列表终止项 */ }; static char *str_param_default = "default"; /* - * Sample validator: checks that string is not longer than 8 bytes. + * 验证器示例:检查字符串长度不超过 8 字节。 */ static void validate_my_string_relopt(const char *value) @@ -812,7 +811,7 @@ validate_my_string_relopt(const char *value) } /* - * Sample filler: switches characters to lower case. + * 填充函数示例:将字符转换为小写。 */ static Size fill_my_string_relopt(const char *value, void *ptr) @@ -821,7 +820,7 @@ fill_my_string_relopt(const char *value, void *ptr) int len = strlen(tmp); if (ptr) - strcpy(ptr, tmp); + strcpy((char *) ptr, tmp); pfree(tmp); return len + 1; @@ -865,10 +864,9 @@ my_compress(PG_FUNCTION_ARGS) char *str_param = str_param_default; /* - * Normally, when opclass contains 'options' method, then options are always - * passed to support functions. However, if you add 'options' method to - * existing opclass, previously defined indexes have no options, so the - * check is required. + * 通常,操作符类包含 'options' 方法时,总会把选项传给支持函数。 + * 但是,如果把 'options' 方法添加到已有操作符类中, + * 先前定义的索引没有选项,因此需要进行检查。 */ if (PG_HAS_OPCLASS_OPTIONS()) { @@ -880,7 +878,7 @@ my_compress(PG_FUNCTION_ARGS) str_param = GET_STRING_RELOPTION(options, str_param); } - /* the rest implementation of support function */ + /* 支持函数的其余实现 */ } @@ -924,7 +922,7 @@ PG_FUNCTION_INFO_V1(my_sortsupport); static int my_fastcmp(Datum x, Datum y, SortSupport ssup) { - /* establish order between x and y by computing some sorting value z */ + /* 通过计算某个排序值 z 来确定 x 和 y 的顺序 */ int z1 = ComputeSpatialCode(x); int z2 = ComputeSpatialCode(y); @@ -944,85 +942,22 @@ my_sortsupport(PG_FUNCTION_ARGS) - - - translate_cmptype - - - 给定一个来自src/include/access/cmptype.hCompareType值,返回该操作符类用于匹配功能的策略号。如果该操作符类没有匹配策略,函数应返回InvalidStrategy。 - - - - 这用于时态索引约束(即PRIMARY - KEYUNIQUE)。如果该操作符类提供此函数,并且它会为COMPARE_EQ返回结果,那么它就可以用于索引约束中非WITHOUT OVERLAPS的部分。 - - - - 这个支持函数对应于索引访问方法回调函数amtranslatecmptype(见)。GiST 索引的amtranslatecmptype回调函数只是调用相应操作符族的translate_cmptype支持函数,因为 GiST 索引访问方法本身并没有固定的策略号。 - - - - 该函数的SQL声明必须如下所示: - - -CREATE OR REPLACE FUNCTION my_translate_cmptype(integer) -RETURNS smallint -AS 'MODULE_PATHNAME' -LANGUAGE C STRICT; - - - 而操作符族注册必须如下所示: - -ALTER OPERATOR FAMILY my_opfamily USING gist ADD - FUNCTION 12 ("any", "any") my_translate_cmptype(int); - - - - - 而 C 模块中的对应代码则可以遵循如下框架: - - -PG_FUNCTION_INFO_V1(my_translate_cmptype); - -Datum -my_translate_cmptype(PG_FUNCTION_ARGS) -{ - CompareType cmptype = PG_GETARG_INT32(0); - StrategyNumber ret = InvalidStrategy; - - switch (cmptype) - { - case COMPARE_EQ: - ret = BTEqualStrategyNumber; - } - - PG_RETURN_UINT16(ret); -} - - - - - PostgreSQL提供了一个翻译函数:gist_translate_cmptype_common,用于使用RT*StrategyNumber常量的操作符类。btree_gist扩展又定义了第二个翻译函数gist_translate_cmptype_btree,用于使用BT*StrategyNumber常量的操作符类。 - - - 所有 GiST 支持方法通常都在短生命周期的内存上下文中被调用;也就是说,每处理完一个元组,CurrentMemoryContext都会被重置。因此通常无需过分担心释放所有通过 palloc 分配的内容。不过,在某些情况下,让支持方法在重复调用之间缓存数据是有用的。要做到这一点,可将寿命更长的数据分配在fcinfo->flinfo->fn_mcxt中,并在fcinfo->flinfo->fn_extra中保存指向它的指针。这类数据会在一次索引操作期间存活(例如一次 GiST 索引扫描、索引构建或索引元组插入)。在替换fn_extra值时要注意 pfree 旧值,否则泄漏会在整个操作期间不断累积。 - + - + 实现 - + GiST 索引构建方法 - 构建 GiST 索引最简单的方法就是把所有项逐个插入。这对于大型索引往往很慢,因为如果索引元组分散在整个索引中,而索引又大到无法放入缓存,就需要大量随机 I/O。PostgreSQL支持两种用于 GiST 索引初始构建的替代方法:sortedbuffered模式。 + 构建 GiST 索引最简单的方法就是把所有项逐个插入。这对于大型索引往往很慢,因为如果索引元组分散在整个索引中,而索引又大到无法放入缓存,就需要大量随机 I/O。PostgreSQL支持两种用于 GiST 索引初始构建的替代方法:排序缓冲模式。 @@ -1041,10 +976,10 @@ my_translate_cmptype(PG_FUNCTION_ARGS) 如果不能排序,那么默认情况下,当索引大小达到时,GiST 索引构建会切换到缓冲方法。也可以通过 CREATE INDEX 命令的buffering参数手工强制启用或禁止缓冲。默认行为在大多数情况下都不错,但如果输入数据是有序的,关闭缓冲模式可能会略微加快构建速度。 - + - + 示例 @@ -1068,7 +1003,7 @@ my_translate_cmptype(PG_FUNCTION_ARGS) hstore - 用于存储 (key, value) 对的模块 + 用于存储(键,值)对的模块 @@ -1102,6 +1037,6 @@ my_translate_cmptype(PG_FUNCTION_ARGS) - + diff --git a/zh/16/glossary.sgml b/zh/16/glossary.sgml index 4d535c3a..027c40d8 100644 --- a/zh/16/glossary.sgml +++ b/zh/16/glossary.sgml @@ -36,19 +36,6 @@ - - 访问方法 - - - PostgreSQL 用来访问表和索引中数据的接口。 - 这种抽象允许增加对新型数据存储的支持。 - - - 更多信息见 。 - - - - 分析函数 @@ -73,29 +60,6 @@ - - 异步 I/O - AIO - - 异步 I/O - - - - 异步 I/OAIO)描述的是以 - 非阻塞方式(异步地)执行 I/O,这与同步 - I/O 形成对比;后者会在整个 - I/O 持续期间阻塞。 - - - 使用 AIO 时,启动一次 I/O 操作 - 与等待其结果是分离的,这允许并发发起多个 I/O 操作, - 也允许在 I/O 的同时并发执行 - CPU 密集型操作。这种更高并发性的代价是复杂性增加。 - - - - - 原子 @@ -174,7 +138,6 @@ WAL 归档器WAL 接收进程 (但不包括 WAL 发送进程)、 - WAL 汇总器 以及 WAL 写入器 @@ -382,7 +345,7 @@ 客户端(进程) - 任何进程,可能是远程的,通过连接到某个 + 任何进程,可能是远程的,通过连接到某个 实例来建立 会话, 以与一个数据库交互。 @@ -830,7 +793,7 @@ 一台通过网络与其他计算机通信的计算机。这个术语有时被用作 服务器的同义词。 - 它也用来指客户端进程运行所在的计算机。 + 它也用来指客户端进程运行所在的计算机。 @@ -850,41 +813,6 @@ - - 增量备份 - - - 一种特殊的 基础备份, - 对于某些文件,它可能只包含自前一次备份以来被修改过的页面, - 而不是每个文件的完整内容。和基础备份一样,它由 - 工具生成。 - - - 恢复增量备份时要使用 工具, - 它会把增量备份与基础备份合并。随后,恢复过程可以利用 - WAL 把 - 数据库集簇 - 带到一致状态。 - - - 更多信息见 。 - - - - - - 输入/输出 - I/O - - - 输入/输出(I/O)描述程序与外围设备之间的通信。 - 在数据库系统语境中,I/O 通常但不限于 - 指与存储设备或网络的交互。 - - - - - 插入 @@ -914,7 +842,7 @@ 实例处理 DBMS 的所有关键特性: 对文件和共享内存的读写访问、保证 ACID 属性、 - 与客户端进程的连接、 + 与客户端进程连接、 权限验证、崩溃恢复、复制等。 @@ -1009,14 +937,7 @@ - - 逻辑复制集簇 - - - 一组发布者实例和订阅者实例,其中发布者实例把变更复制到订阅者实例。 - - - + 日志记录 @@ -1164,7 +1085,7 @@ - 当它用于指代查询中的 + 当它用于指代查询中的 窗口函数时, 分区是一种用户定义的准则,用来标识 查询结果集中哪些相邻的 @@ -2043,19 +1964,7 @@ - - WAL 汇总器 - - - 一种 辅助进程, - 用于为增量备份 - 汇总 WAL 数据。 - - - 更多信息见 WAL 汇总相关配置。 - - - + WAL 写入器 diff --git a/zh/16/hash.sgml b/zh/16/hash.sgml index 078e8dd8..81f5f878 100644 --- a/zh/16/hash.sgml +++ b/zh/16/hash.sgml @@ -1,72 +1,72 @@ -哈希索引 +Hash 索引 索引 - 哈希 + Hash - + 概述 PostgreSQL - 提供了持久化的磁盘哈希索引实现,并且完全支持崩溃恢复。任何数据类型都可以使用哈希索引,包括那些没有明确定义线性顺序的数据类型。哈希索引只存储被索引数据的哈希值,因此对被索引数据列的大小没有限制。 + 提供了持久化的磁盘 hash 索引实现,并且完全支持崩溃恢复。任何数据类型都可以使用 hash 索引,包括那些没有明确定义线性顺序的数据类型。Hash 索引只存储被索引数据的 hash 值,因此对被索引数据列的大小没有限制。 - 哈希索引仅支持单列索引,也不支持唯一性检查。 + Hash 索引仅支持单列索引,也不支持唯一性检查。 - 哈希索引仅支持=操作符,因此指定范围操作的 WHERE 子句无法利用哈希索引。 + Hash 索引仅支持=操作符,因此指定范围操作的 WHERE 子句无法利用 hash 索引。 - 每个哈希索引元组只存储 4 字节的哈希值,而不存储实际的列值。因此,在为 UUID、URL 等较长的数据项建立索引时,哈希索引可能比 B-树小得多。由于没有列值,所有哈希索引扫描也都是有损的。哈希索引可以参与位图索引扫描和反向扫描。 + 每个 hash 索引元组只存储 4 字节的 hash 值,而不存储实际的列值。因此,在为 UUID、URL 等较长的数据项建立索引时,hash 索引可能比 B-树小得多。由于没有列值,所有 hash 索引扫描也都是有损的。Hash 索引可以参与位图索引扫描和反向扫描。 - 哈希索引最适合于在较大表上执行等值扫描、且以 SELECT 和 UPDATE 为主的工作负载。在 B-树索引中,搜索必须沿树向下直到找到叶页。在拥有数百万行的表中,这种向下遍历会增加访问数据的时间。在哈希索引中,与叶页对应的页称为桶页。相比之下,哈希索引允许直接访问桶页,因此可能减少大表中的索引访问时间。这种“逻辑 I/O”的减少,在索引/数据大于 shared_buffers/RAM 时会更加明显。 + Hash 索引最适合于在较大表上执行等值扫描、且以 SELECT 和 UPDATE 为主的工作负载。在 B-树索引中,搜索必须沿树向下直到找到叶页。在拥有数百万行的表中,这种向下遍历会增加访问数据的时间。在 hash 索引中,与叶页对应的页称为桶页。相比之下,hash 索引允许直接访问桶页,因此可能减少大表中的索引访问时间。这种“逻辑 I/O”的减少,在索引/数据大于 shared_buffers/RAM 时会更加明显。 - 哈希索引在设计上能够应对哈希值分布不均的情况。如果哈希值分布均匀,那么直接访问桶页的效果很好。当插入导致桶页填满时,额外的溢出页就会链接到该特定桶页上,从而在局部扩展用于存放匹配该哈希值的索引元组的空间。查询期间扫描某个哈希桶时,需要遍历其全部溢出页。因此,对于某些数据,不平衡的哈希索引在所需块访问次数方面实际上可能比 B-树更差。 + Hash 索引在设计上能够应对 hash 值分布不均的情况。如果 hash 值分布均匀,那么直接访问桶页的效果很好。当插入导致桶页填满时,额外的溢出页就会链接到该特定桶页上,从而在局部扩展用于存放匹配该 hash 值的索引元组的空间。查询期间扫描某个 hash 桶时,需要遍历其全部溢出页。因此,对于某些数据,不平衡的 hash 索引在所需块访问次数方面实际上可能比 B-树更差。 - 由于会出现这些溢出情况,可以说哈希索引最适合用于唯一值、近乎唯一值,或者每个哈希桶中行数较少的数据。 + 由于会出现这些溢出情况,可以说 hash 索引最适合用于唯一值、近乎唯一值,或者每个 hash 桶中行数较少的数据。 避免问题的一种可能办法,是使用部分索引条件把高度非唯一的值排除在索引之外,但这在很多情况下可能并不适用。 - 与 B-树一样,哈希索引也会执行简单的索引元组删除。这是一种延迟维护操作,用于删除那些已知可以安全删除的索引元组(即其项标识符的 LP_DEAD 位已经被设置的那些元组)。如果插入操作发现页上没有可用空间,我们会尝试通过移除死索引元组来避免创建新的溢出页。如果该页当时已被钉住,就无法执行移除。死索引指针也会在 VACUUM 期间被删除。 + 与 B-树一样,hash 索引也会执行简单的索引元组删除。这是一种延迟维护操作,用于删除那些已知可以安全删除的索引元组(即其项标识符的 LP_DEAD 位已经被设置的那些元组)。如果插入操作发现页上没有可用空间,我们会尝试通过移除死索引元组来避免创建新的溢出页。如果该页当时已被钉住,就无法执行移除。死索引指针也会在 VACUUM 期间被删除。 - 如果可能,VACUUM 还会尝试将索引元组压缩到尽可能少的溢出页上,以最小化溢出链。 + 如果可能,VACUUM 还会尝试将索引元组集中存放在尽可能少的溢出页上,以最小化溢出链。 如果某个溢出页变为空页,该溢出页就可以被回收并在其他桶中重用,不过我们从不将它们返还给操作系统。 - 目前除了使用 REINDEX 重建哈希索引之外,还没有缩小哈希索引的方法。 + 目前除了使用 REINDEX 重建 hash 索引之外,还没有缩小 hash 索引的方法。 同样也没有减少桶数量的方法。 - 随着被索引行数的增长,哈希索引可能会扩展桶页数量。哈希键到桶号的映射经过选择,使得索引能够增量扩展。当需要向索引中添加一个新桶时,恰好只需要“拆分”一个现有桶,并根据更新后的键到桶号映射,将其中一部分元组转移到新桶。 + 随着被索引行数的增长,Hash 索引可能会扩展桶页数量。hash 键到桶号的映射经过选择,使得索引能够增量扩展。当需要向索引中添加一个新桶时,恰好只需要“拆分”一个现有桶,并根据更新后的键到桶号映射,将其中一部分元组转移到新桶。 - 这种扩展是在前台进行的,因此可能会增加用户插入操作的执行时间。因此,哈希索引可能不适合行数快速增长的表。 + 这种扩展是在前台进行的,因此可能会增加用户插入操作的执行时间。因此,hash 索引可能不适合行数快速增长的表。 - + - + 实现 - 哈希索引中有四种页:元页(第零页),其中包含静态分配的控制信息;主桶页;溢出页;以及位图页,后者用于跟踪已被释放且可供重用的溢出页。在寻址时,位图页被视为溢出页的一个子集。 + hash 索引中有四种页:元页(第零页),其中包含静态分配的控制信息;主桶页;溢出页;以及位图页,后者用于跟踪已被释放且可供重用的溢出页。在寻址时,位图页被视为溢出页的一个子集。 @@ -74,17 +74,17 @@ - 主桶页和溢出页是独立分配的,因为任何一个给定索引相对于其桶数,可能需要更多或更少的溢出页。哈希代码使用了一组颇有意思的寻址规则,以支持可变数量的溢出页,同时又不必在主桶页创建后再移动它们。 + 主桶页和溢出页是独立分配的,因为任何一个给定索引相对于其桶数,可能需要更多或更少的溢出页。hash 实现代码使用了一组颇有意思的寻址规则,以支持可变数量的溢出页,同时又不必在主桶页创建后再移动它们。 - 被索引表中的每一行,都由哈希索引中的单个索引元组表示。哈希索引元组存储在桶页中,如果存在溢出页,也会存储在溢出页中。为了加快搜索速度,我们将任一索引页中的索引项按哈希码排序,从而可以在索引页内使用二分查找。但请注意,并不假定同一桶中不同索引页之间的哈希码具有任何相对顺序。 + 被索引表中的每一行,都由 hash 索引中的单个索引元组表示。Hash 索引元组存储在桶页中,如果存在溢出页,也会存储在溢出页中。为了加快搜索速度,我们将任一索引页中的索引项按 hash 码排序,从而可以在索引页内使用二分查找。但请注意,并不假定同一桶中不同索引页之间的 hash 码具有任何相对顺序。 - 用于扩展哈希索引的桶拆分算法过于复杂,这里不再展开说明;但在src/backend/access/hash/README中有更详细的描述。该拆分算法具备崩溃安全性,如果未能成功完成,可以重新启动。 + 用于扩展 hash 索引的桶拆分算法过于复杂,这里不再展开说明;但在src/backend/access/hash/README中有更详细的描述。该拆分算法具备崩溃安全性,如果未能成功完成,可以重新启动。 - + diff --git a/zh/16/high-availability.sgml b/zh/16/high-availability.sgml index 94e7bdaf..59c4033d 100644 --- a/zh/16/high-availability.sgml +++ b/zh/16/high-availability.sgml @@ -19,7 +19,7 @@ - 某些方案通过只允许一台服务器修改数据来处理同步。能够修改数据的服务器称为读/写、主库(master)主库(primary)服务器。跟踪主库变更的服务器称为备库。只能在被提升为主库之后才能连接的备库称为温备,而能够接受连接并提供只读查询的备库称为热备。 + 某些方案通过只允许一台服务器修改数据来处理同步。能够修改数据的服务器称为读/写、主库(master)主库(primary)服务器。跟踪主库变更的服务器称为备库(standby)备库(secondary)。只能在被提升为主库之后才能连接的备库称为温备,而能够接受连接并提供只读查询的备库称为热备 @@ -102,7 +102,7 @@ protocol to make nodes agree on a serializable transactional order. - 基于触发器的主库-备库复制 + 基于触发器的主备复制 @@ -238,7 +238,7 @@ protocol to make nodes agree on a serializable transactional order. - 主库无额外负载 + 主库无额外开销 @@ -354,7 +354,7 @@ protocol to make nodes agree on a serializable transactional order. - 连续归档可用于创建一种高可用性(HA)集簇配置,其中有一个或多个备库随时准备在主库失效时接管操作。这种能力通常称为温备日志传送。 + 持续归档可用于创建一种高可用性(HA)集簇配置,其中有一个或多个备库随时准备在主库失效时接管操作。这种能力通常称为温备日志传送 @@ -528,7 +528,7 @@ archive_cleanup_command = 'pg_archivecleanup /path/to/archive %r' 认证 - 正确设置复制访问权限非常重要,因为从 WAL 流中很容易提取出需要权限才能访问的信息,因此必须确保只有受信任的用户才能读取它。备库必须以具有 REPLICATION 权限的账户或超级用户身份向主库认证。建议专门创建一个具有 REPLICATIONLOGIN 权限的用户账户用于复制。虽然 REPLICATION 权限的权限很高,但它并不允许用户修改主系统上的任何数据,而 SUPERUSER 权限则允许。 + 正确设置复制访问权限非常重要,因为从 WAL 流中很容易提取出需要权限才能访问的信息,因此必须确保只有受信任的用户才能读取它。备库必须以具有 REPLICATION 权限的账户或超级用户身份向主库认证。建议专门创建一个具有 REPLICATIONLOGIN 权限的用户账户用于复制。虽然 REPLICATION 权限很高,但它并不允许用户修改主系统上的任何数据,而 SUPERUSER 权限则允许。 @@ -539,7 +539,7 @@ archive_cleanup_command = 'pg_archivecleanup /path/to/archive %r' # as a replication standby if the user's password is correctly supplied. # # TYPE DATABASE USER ADDRESS METHOD -host replication foo 192.168.1.100/32 scram-sha-256 +host replication foo 192.168.1.100/32 md5 @@ -559,7 +559,7 @@ primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass' 流复制的一个重要健康指标,是主库上已经生成但尚未在备库上应用的 WAL 记录量。你可以通过比较主库上的当前 WAL 写入位置和备库收到的最后一个 WAL 位置来计算这种滞后。这些位置分别可以用主库上的 pg_current_wal_lsn 和备库上的 pg_last_wal_receive_lsn 取得(详见 )。备库上的最后一个 WAL 接收位置也会显示在 WAL 接收进程的进程状态中,即通过 ps 命令显示的状态(详见 )。 - 你可以通过 pg_stat_replication 视图取得 WAL 发送进程列表。pg_current_wal_lsn 与该视图的 sent_lsn 字段之间存在较大差异,可能表示主库负载很重;而 sent_lsn 与备库上的 pg_last_wal_receive_lsn 之间存在较大差异,则可能表示网络延迟,或者备库负载很重。 + 你可以通过 pg_stat_replication 视图取得 WAL 发送进程列表。pg_current_wal_lsn 与该视图的 sent_lsn 字段之间存在较大差异,可能表示主库负载很重;而 sent_lsn 与备库上的 pg_last_wal_receive_lsn 之间存在差异,则可能表示网络延迟,或者备库负载很重。 在热备上,WAL 接收进程的状态可以通过 @@ -575,21 +575,12 @@ primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass' 流复制 - 复制槽提供了一种自动化方法,以确保主库在所有备库都收到 WAL 段之前不会删除它们,并且即使备库处于断开状态,主库也不会删除可能导致恢复冲突的行。 + 复制槽提供了一种自动化方法,以确保主库在所有备库都收到 WAL 段之前不会删除它们,并且即使备库处于断开状态,主库也不会删除那些一旦删除就可能导致恢复冲突的行。 + 除了使用复制槽,也可以通过 防止旧 WAL 段被删除,或者使用 将这些段保存在归档中。不过,这些方法通常会保留多于实际所需的 WAL 段,而复制槽只保留已知必需的段数。另一方面,复制槽保留的 WAL 段也可能过多,填满分配给 pg_wal 的空间; 可以限制复制槽保留的 WAL 文件大小。 - 如果不使用复制槽,也可以通过阻止旧的 WAL 段被移除,或者通过把这些段保存到归档中。这些方法的一个缺点是,它们通常会保留多于实际所需数量的 WAL 段,而复制槽只会保留已知确实需要的段数。 - - - 类似地,如果不配合复制槽单独使用 ,它虽然能防止相关的行被清理而避免因清理产生的问题,但在备库未连接的那段时间内并不能提供保护。 - - - - - 注意,复制槽可能会导致服务器保留过多的 WAL 段,以至于占满分配给pg_wal的空间。可以使用来限制复制槽保留的 WAL 文件大小。 - - - + 类似地,如果不配合复制槽单独使用 ,它虽然能防止相关的行被清理移除,但在备库未连接的那段时间内并不能提供保护。 + 复制槽克服了这些缺点。 查询和管理复制槽 @@ -604,7 +595,7 @@ primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass' 复制槽可以通过流复制协议(见)或者 SQL 函数(见)创建和删除。 - + 配置示例 你可以像下面这样创建一个复制槽: @@ -685,7 +676,7 @@ primary_slot_name = 'node_a_slot' - 只读事务和事务回滚不需要等待备库的回应。子事务提交也不需要等待备库响应,只有顶层提交才需要等待。数据装载或索引构建等长时间运行的动作,不会一直等到最终提交消息。所有两阶段提交操作都需要等待提交,包括 prepare 和 commit。 + 只读事务和事务回滚不需要等待备库的回应。子事务提交也不需要等待备库响应,只有顶层提交才需要等待。数据装载或索引构建等长时间运行的动作,直到最终提交时才会等待。所有两阶段提交操作都需要等待提交,包括准备和提交两个阶段。 @@ -700,7 +691,7 @@ primary_slot_name = 'node_a_slot' - 当提交记录已经在主库上写入磁盘之后,WAL 记录就会被发送到备库。每当新的一批 WAL 数据被写入磁盘时,备库就会发送回复消息,除非备库上的wal_receiver_status_interval被设置为零。如果synchronous_commit被设置为remote_apply,那么备库会在提交记录被重放时发送回复消息,从而使该事务变得可见。如果根据主库上的synchronous_standby_names设置,该备库被选为同步备库,那么它发出的回复会与其他同步备库的回复一起,用于决定何时释放那些正在等待确认提交记录已被收到的事务。这些参数允许管理员指定哪些备库应作为同步备库。注意,同步复制的配置主要在主库上进行。被命名的备库必须直接连接到主库;主库并不知道使用级联复制的下游备库。 + 当提交记录已经在主库上写入磁盘之后,WAL 记录就会被发送到备库。每当新的一批 WAL 数据被写入磁盘时,备库就会发送回复消息,除非备库上的wal_receiver_status_interval被设置为零。如果synchronous_commit被设置为remote_apply,那么备库会在提交记录被重放、该事务变得可见时发送回复消息。如果根据主库上的synchronous_standby_names设置,该备库被选为同步备库,那么它发出的回复会与其他同步备库的回复一起,用于决定何时释放那些正在等待确认提交记录已被收到的事务。这些参数允许管理员指定哪些备库应作为同步备库。注意,同步复制的配置主要在主库上进行。被命名的备库必须直接连接到主库;主库并不知道使用级联复制的下游备库。 @@ -712,7 +703,7 @@ primary_slot_name = 'node_a_slot' - 如果请求快速关闭,用户将停止等待。不过,与使用异步复制时一样,在所有尚未解决的 WAL 记录传输到当前已连接的备库之前,服务器不会完全关闭。 + 如果请求快速关闭,用户将停止等待。不过,与使用异步复制时一样,在所有尚未传送的 WAL 记录传输到当前已连接的备库之前,服务器不会完全关闭。 @@ -734,14 +725,14 @@ synchronous_standby_names = 'FIRST 2 (s1, s2, s3)' 在这个例子中,如果四台备库s1s2s3s4都在运行,则s1s2会被选为同步备库,因为它们的名字在备库名称列表中出现得更早。s3是潜在的同步备库,当s1s2中的任意一台失效时,它就会接替其角色。由于s4的名称不在列表中,因此它是异步备库。 - ANY方法指定基于法定人数的同步复制,使事务提交等待,直到它们的 WAL 记录被复制到列表中所要求数量的同步备库中的至少这么多台。 + ANY方法指定基于法定人数的同步复制,使事务提交等待,直到它们的 WAL 记录被复制到列表中至少所要求数量的同步备库。 基于法定人数的多同步备库的synchronous_standby_names示例如下: synchronous_standby_names = 'ANY 2 (s1, s2, s3)' - 在这个例子中,如果四台备库s1s2s3s4都在运行,事务提交将等待来自s1s2s3中的任意两台备库的回复。由于s4的名字不在列表中,因此它是异步备库。 + 在这个例子中,如果四台备库s1s2s3s4都在运行,事务提交将等待来自s1s2s3中的至少任意两台备库的回复。由于s4的名字不在列表中,因此它是异步备库。 备库的同步状态可以通过pg_stat_replication视图查看。 @@ -764,7 +755,7 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' - 通过在应用级别(在主库上)指定同步复制选项,我们可以只对最重要的变更提供同步复制,而不会拖慢整体工作负载。应用级别选项是让高性能应用获得同步复制收益的一种重要而实用的工具。 + 通过在应用级别(在主库上)指定同步复制选项,我们可以只对最重要的变更提供同步复制,而不会拖慢大部分工作负载。应用级别选项是让高性能应用获得同步复制收益的一种重要而实用的工具。 @@ -797,7 +788,7 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' - 如果主库在提交正等待确认时重启,这些等待中的事务会在主库恢复后被标记为已完全提交。无法确定在主库崩溃时,所有备库是否已经收到全部尚未处理的 WAL 数据。因此,某些事务可能不会在备库上显示为已提交,即使它们在主库上显示为已提交。我们所提供的保证是:只有在确认 WAL 数据已经被所有同步备库安全接收之后,应用才会收到事务成功提交的显式确认。 + 如果主库在提交正等待确认时重启,这些等待中的事务会在主库恢复后被标记为已完全提交。无法确定在主库崩溃时,所有备库是否已经收到全部待传送的 WAL 数据。因此,某些事务可能不会在备库上显示为已提交,即使它们在主库上显示为已提交。我们所提供的保证是:只有在确认 WAL 数据已经被所有同步备库安全接收之后,应用才会收到事务成功提交的显式确认。 @@ -808,9 +799,7 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' 如果主库与剩余的备库隔离开了,你应当故障切换到那些剩余备库中最佳的候选者。 - - 如果你需要在事务正在等待时重新创建一台备库,请确保pg_backup_start()pg_backup_stop()是在一个把synchronous_commit设置为off的会话中运行的,否则这些请求将永远等待备库出现。 - + 如果需要在事务等待期间重新创建备库,请确保在 synchronous_commit = off 的会话中运行 pg_backup_start() 和 pg_backup_stop() 命令,否则这些请求会一直等待备库出现。 @@ -831,43 +820,43 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' 如果archive_mode被设置为on,那么归档器在恢复期间或备库模式下不会启用。如果备库被提升,它会在提升后开始归档,但不会归档任何不是由它自己生成的 WAL 或时间线历史文件。要在归档中获得完整的一系列 WAL 文件,就必须确保所有 WAL 在到达备库之前已经被归档。对于基于文件的日志传送,这天然成立,因为备库只能恢复归档中找到的文件;但在启用流复制时则不是这样。当服务器不处于恢复模式时,onalways模式之间没有区别。 - + - - 故障切换 + + 故障切换 - + 如果主库失效,备库就应该开始执行故障切换过程。 - + 如果备库失效,则不需要发生故障切换。如果备库能够重新启动,即使是在稍后某个时间点,恢复过程也可以立即重新开始,从而利用可重启恢复的优势。如果备库无法重新启动,则应创建一个全新的备库实例。 - + 如果主库失效,而备库成为新的主库,那么旧主库之后如果重新启动,你必须有一种机制通知它,它已经不再是主库。这有时被称为STONITH(Shoot The Other Node In The Head),它对于避免两个系统都认为自己是主库的情况至关重要,因为那种情况会导致混乱,并最终造成数据丢失。 - + 许多故障切换系统只使用两个系统,即主库和备库,并通过某种心跳机制连接它们,以持续验证两者之间的连通性以及主库的可用性。也可以使用第三个系统(称为见证服务器)来防止某些不恰当的故障切换,但除非设置得足够谨慎并经过严格测试,否则额外增加的复杂性可能并不值得。 - + PostgreSQL并不提供用于识别主库故障并通知备库的系统软件。现在已经存在许多这样的工具,并且它们通常能很好地与成功故障切换所需的操作系统设施整合在一起,例如 IP 地址迁移。 - - 一旦故障切换到备库,系统中就只剩下一台服务器在运行。这被称为退化状态。原来的备库现在成为主库,而原来的主库已经停机,并且可能持续停机。要恢复到正常运行状态,就必须重新创建一台备库:要么在原主库恢复后在其上重建,要么在第三台可能是全新的服务器上重建。在大型集簇上,可以使用工具来加快这一过程。一旦完成,就可以认为主库和备库已经交换了角色。有些人会选择使用第三台服务器,在新的备库重建完成之前为新的主库提供备份,但显然这会让系统配置和操作流程更加复杂。 + + 一旦故障切换到备库,系统中就只剩下一台服务器在运行。这被称为退化状态。原来的备库现在成为主库,而原来的主库已经停机,并且可能持续停机。要恢复到正常运行状态,就必须重新创建一台备库:要么在原主库恢复后在其上重建,要么在第三台可能是全新的服务器上重建。在大型集簇上,可以使用工具来加快这一过程。一旦完成,就可以认为主库和备库已经交换了角色。有些人会选择使用第三台服务器,在新的备库重建完成之前为新的主库提供后备支持,但显然这会让系统配置和操作流程更加复杂。 - + 因此,从主库切换到备库可以很快,但重新准备故障切换集簇仍然需要时间。定期在主库与备库之间进行切换是有益的,因为它允许每个系统定期停机维护。这也相当于对故障切换机制进行测试,以确保真正需要它时它能够正常工作。建议编写书面的管理操作规程。 - + 要触发日志传送备库的故障切换,请运行pg_ctl promote或调用pg_promote()。如果你设置的是仅用于从主库卸载只读查询的报表服务器,而不是用于高可用目的,那么就不需要执行提升。 - + 热备 @@ -888,7 +877,7 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' 用户概览 - 当备库上的参数被设置为真时,一旦恢复把系统带到一致状态并为热备做好准备,它就会开始接受连接。所有这类连接都严格是只读的,甚至不能写入临时表。 + 当备库上的参数被设置为真时,一旦恢复把系统带到一致状态,它就会开始接受连接。所有这类连接都严格是只读的,甚至不能写入临时表。 @@ -916,7 +905,7 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' - 事务管理命令: + 事务管理命令: @@ -930,7 +919,7 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' - EXCEPTION块或其他内部子事务 + EXCEPTION块和其他内部子事务 @@ -970,7 +959,7 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' 数据操纵语言(DML):INSERTUPDATEDELETEMERGECOPY FROM、 - TRUNCATE。请注意,恢复期间不存在任何允许执行触发器的动作。这个限制甚至适用于临时表,因为不分配事务 ID 就无法读取或写入表行,而这在热备环境中目前是不可能的。 + TRUNCATE。请注意,恢复期间不存在任何允许执行触发器的动作。这个限制甚至适用于临时表,因为不分配事务 ID 就无法读取或写入表行,而目前热备环境中无法分配事务 ID。 @@ -1005,13 +994,13 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' - BEGIN READ WRITE, + BEGIN READ WRITESTART TRANSACTION READ WRITE - SET TRANSACTION READ WRITE, + SET TRANSACTION READ WRITESET SESSION CHARACTERISTICS AS TRANSACTION READ WRITE @@ -1027,7 +1016,7 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' 两阶段提交命令:PREPARE TRANSACTIONCOMMIT PREPAREDROLLBACK PREPARED, - 因为即使是只读事务,在 prepare 阶段(两阶段提交的第一阶段)也需要写入 WAL。 + 因为即使是只读事务,在准备阶段(两阶段提交的第一阶段)也需要写入 WAL。 @@ -1113,24 +1102,22 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' - 一旦max_standby_archive_delaymax_standby_streaming_delay指定的延迟被超越,冲突查询将被取消。这通常仅导致一个取消错误,尽管在重放一个DROP DATABASE的情况下整个冲突会话都将被中断。另外,如果冲突发生在一个被空闲事务持有的锁上,该冲突会话会被中断(这种行为可能在未来被改变)。 + 一旦max_standby_archive_delaymax_standby_streaming_delay指定的延迟被超越,冲突查询将被取消。这通常仅导致一个取消错误,尽管在重放一个DROP DATABASE的情况下整个冲突会话都将被终止。另外,如果冲突发生在一个被空闲事务持有的锁上,该冲突会话会被终止(这种行为可能在未来被改变)。 - - 被取消的查询可能会立即被重试(当然是在开始一个新的事务后)。因为查询取消依赖于 WAL 记录被重放的本质,如果一个被取消的查询被再次执行,它可能会很好地成功完成。 - + 被取消的查询可以立即重试(当然,要先开始一个新事务)。由于查询取消取决于正在重放的 WAL 记录的性质,被取消的查询再次执行时完全可能成功。 - 记住延迟参数是从 WAL 数据被备库收到后流逝的时间。因此,留给备库上任何一个查询的宽限期从不会超过延迟参数,并且如果备库已经由于等待之前的查询完成而落后或者因为过重的更新负载而无法跟上主库,宽限期可能会更少。 + 请记住,延迟参数要与备库收到 WAL 数据之后经过的时间进行比较。因此,留给备库上任何一个查询的宽限期从不会超过延迟参数,并且如果备库已经由于等待之前的查询完成而落后或者因为过重的更新负载而无法跟上主库,宽限期可能会更少。 - 备库查询与 WAL 重放发生冲突的最常见原因是过早清理。正常情况下,当没有事务需要看到旧行版本时,PostgreSQL允许清理这些旧行版本,以保证按照 MVCC 规则得到正确的数据可见性。不过,这条规则只能应用于在主库上执行的事务。因此,主库上的清理有可能移除某个备库事务仍然可见的行版本。 + 备库查询与 WAL 重放发生冲突的最常见原因是过早清理。正常情况下,当不再有事务需要看到旧行版本来保证符合 MVCC 规则的数据可见性时,PostgreSQL允许清理这些旧行版本。不过,这条规则只能应用于在主库上执行的事务。因此,主库上的清理有可能移除某个备库事务仍然可见的行版本。 行版本清理并不是与备库查询发生冲突的唯一潜在原因。所有仅索引扫描(包括在备库上运行的那些)都必须使用一个MVCC快照,它与可见性映射一致。因此,每当VACUUM在可见性映射中把某个页面标记为全可见,而该页面中包含一行或多行对所有备库查询都不可见的数据时,就必须产生冲突。所以,即使针对一个没有更新或删除任何需要清理行的表执行VACUUM,也可能导致冲突。 + linkend="vacuum-for-visibility-map">在可见性映射中把某个页面标记为全可见,而该页面中包含并非对所有备库查询都可见的一行或多行数据时,就必须产生冲突。所以,即使针对一个没有需要清理的已更新或已删除行的表执行VACUUM,也可能导致冲突。 @@ -1165,7 +1152,7 @@ LOG: consistent recovery state reached LOG: database system is ready to accept read-only connections - 一致性信息在主库上每个检查点时记录一次。在主库的wal_level未设置为replicalogical期间所写入的 WAL 被读取时,无法启用热备。即使已经达到一致状态,如果同时满足下列两个条件,恢复快照也可能还没有准备好用于热备,从而推迟接受只读连接。要启用热备,就需要在主库上结束那些包含超过 64 个子事务的长生命周期写事务。 + 一致性信息在主库上每个检查点时记录一次。在主库的wal_level未设置为replicalogical期间所写入的 WAL 被读取时,无法启用热备。如果同时存在以下两种情况,达到一致状态也可能会被推迟: @@ -1233,7 +1220,7 @@ HINT: You can then restart the server after making the necessary configuration - 主库上写出的事务状态 "hint bits" 不会被 WAL 记录,因此备库上的数据很可能会再次写出这些提示位。这样一来,即使所有用户都是只读的,备库仍然会执行磁盘写操作;不过数据值本身并不会发生变化。用户仍然会写出大型排序临时文件,并重新生成 relcache 信息文件,因此在热备模式下,数据库没有任何部分是真正只读的。还要注意,使用dblink模块写入远程数据库,以及借助 PL 函数执行其他数据库外部操作,依然是可能的,即使该事务在本地是只读的。 + 主库上写出的事务状态“提示位” 不会被 WAL 记录,因此备库上的数据很可能会再次写出这些提示位。这样一来,即使所有用户都是只读的,备库仍然会执行磁盘写操作;不过数据值本身并不会发生变化。用户仍然会写出大型排序临时文件,并重新生成 relcache 信息文件,因此在热备模式下,数据库没有任何部分是真正只读的。还要注意,使用dblink模块写入远程数据库,以及借助 PL 函数执行其他数据库外部操作,依然是可能的,即使该事务在本地是只读的。 @@ -1242,7 +1229,7 @@ HINT: You can then restart the server after making the necessary configuration - 数据定义语言:例如 CREATE INDEX + 数据定义语言(DDL):例如 CREATE INDEX @@ -1317,7 +1304,7 @@ HINT: You can then restart the server after making the necessary configuration - 累积统计系统在恢复期间是活动的。所有扫描、读取、块访问、索引使用等,都会在备库上照常记录。不过,WAL 重放不会增加关系和数据库级别的特定计数器。也就是说,重放不会增加pg_stat_all_tables中的列(例如n_tup_ins),启动进程执行的读写也不会被记录到pg_statio_视图中,相关的pg_stat_database列也不会增加。 + 累积统计系统在恢复期间是活动的。所有扫描、读取、块访问、索引使用等,都会在备库上照常记录。不过,WAL 重放不会增加关系和数据库级别的特定计数器。也就是说,重放不会增加pg_stat_all_tables中的列(例如n_tup_ins),启动进程执行的读写也不会被记录到pg_statio视图中,相关的pg_stat_database列也不会增加。 diff --git a/zh/16/history.sgml b/zh/16/history.sgml index 0fc63086..0834f9b4 100644 --- a/zh/16/history.sgml +++ b/zh/16/history.sgml @@ -168,8 +168,7 @@ - 关于此后每个 PostgreSQL 发布版本发生了哪些变化的详情,可在 - https://www.postgresql.org/docs/release/ 查阅。 + 自那以后 PostgreSQL 发生了哪些变化,可见 diff --git a/zh/16/images/fixup-svg.xsl b/zh/16/images/fixup-svg.xsl index d6c46b36..cf7169bb 100644 --- a/zh/16/images/fixup-svg.xsl +++ b/zh/16/images/fixup-svg.xsl @@ -32,6 +32,11 @@ Fix stroke="transparent" attribute, which is invalid SVG. none + + + 'Alibaba PuHuiTi 3.0',serif + + diff --git a/zh/16/images/gin.gv b/zh/16/images/gin.gv index 097e9102..b8e26542 100644 --- a/zh/16/images/gin.gv +++ b/zh/16/images/gin.gv @@ -1,11 +1,12 @@ digraph "gin" { layout=dot; - node [label="", shape=box, style=filled, fillcolor=gray, width=1.4]; + fontname="Alibaba PuHuiTi 3.0"; + node [fontname="Alibaba PuHuiTi 3.0", label="", shape=box, style=filled, fillcolor=gray, width=1.4]; - m1 [label="meta page"]; + m1 [label="元页"]; subgraph cluster01 { - label="entry tree"; + label="键项树"; subgraph egroup1 { rank=same; e1; @@ -27,13 +28,13 @@ digraph "gin" { e4 -> e8; e4 -> e9; - e6 [fillcolor=green, label="posting list"]; - e8 [fillcolor=green, label="posting list"]; - e9 [fillcolor=green, label="posting list"]; + e6 [fillcolor=green, label="倒排列表"]; + e8 [fillcolor=green, label="倒排列表"]; + e9 [fillcolor=green, label="倒排列表"]; } subgraph cluster02 { - label="posting tree"; + label="倒排树"; subgraph pgroup1 { rank=same; p1; @@ -45,22 +46,22 @@ digraph "gin" { p1 -> p2; p1 -> p3; - p2 [fillcolor=green, label="heap ptr"]; - p3 [fillcolor=green, label="heap ptr"]; + p2 [fillcolor=green, label="堆指针"]; + p3 [fillcolor=green, label="堆指针"]; } subgraph cluster03 { - label="posting tree"; + label="倒排树"; subgraph pgroup3 { rank=same; p4; } - p4 [fillcolor=green, label="heap ptr"]; + p4 [fillcolor=green, label="堆指针"]; } subgraph cluster04 { - label="posting tree"; + label="倒排树"; subgraph pgroup4 { rank=same; p5; @@ -72,12 +73,12 @@ digraph "gin" { p5 -> p6; p5 -> p7; - p6 [fillcolor=green, label="heap ptr"]; - p7 [fillcolor=green, label="heap ptr"]; + p6 [fillcolor=green, label="堆指针"]; + p7 [fillcolor=green, label="堆指针"]; } subgraph cluster05 { - label="pending list"; + label="待处理列表"; node [style=filled, fillcolor=red]; n1 -> n2 -> n3 -> n4; } diff --git a/zh/16/images/gin.svg b/zh/16/images/gin.svg index 04fe85ba..79cf14a9 100644 --- a/zh/16/images/gin.svg +++ b/zh/16/images/gin.svg @@ -9,33 +9,33 @@ cluster01 -entry tree +键项树 cluster02 -posting tree +倒排树 cluster03 -posting tree +倒排树 cluster04 -posting tree +倒排树 cluster05 -pending list +待处理列表 m1 -meta page +元页 @@ -113,7 +113,7 @@ e6 -posting list +倒排列表 @@ -142,7 +142,7 @@ e8 -posting list +倒排列表 @@ -154,7 +154,7 @@ e9 -posting list +倒排列表 @@ -195,7 +195,7 @@ p4 -heap ptr +堆指针 @@ -224,7 +224,7 @@ p2 -heap ptr +堆指针 @@ -236,7 +236,7 @@ p3 -heap ptr +堆指针 @@ -254,7 +254,7 @@ p6 -heap ptr +堆指针 @@ -266,7 +266,7 @@ p7 -heap ptr +堆指针 diff --git a/zh/16/indexam.sgml b/zh/16/indexam.sgml index 84d9e5dd..882d20bf 100644 --- a/zh/16/indexam.sgml +++ b/zh/16/indexam.sgml @@ -21,7 +21,7 @@ - 索引本质上是从一些数据键值到行版本(元组)在索引父表中的元组标识符TID)的映射。一个 TID 由块号以及该块中的项号组成(见 元组标识符(TIDs)的映射。一个 TID 由块号以及该块中的项号组成(见 )。这些信息足以从表中取出某个特定的行版本。索引并不直接知道在 MVCC 之下同一逻辑行可能会存在多个现存版本;对索引来说,每个元组都是一个独立对象,需要它自己的索引条目。因此,对一行的更新总会为该行创建全新的索引条目,即使键值并未改变也是如此。(HOT 元组是这一说法的例外;但索引同样不直接处理它们。)当死元组自身被回收时(通过清理),它们对应的索引条目也会被回收。 @@ -44,89 +44,75 @@ typedef struct IndexAmRoutine NodeTag type; /* - * Total number of strategies (operators) by which we can traverse/search - * this AM. Zero if AM does not have a fixed set of strategy assignments. + * 可用于遍历或搜索此 AM 的策略(操作符)总数。 + * 如果 AM 没有固定的一组策略分配,则为零。 */ uint16 amstrategies; - /* total number of support functions that this AM uses */ + /* 此 AM 使用的支持函数总数 */ uint16 amsupport; - /* opclass options support function number or 0 */ + /* 操作符类选项支持函数编号,或为 0 */ uint16 amoptsprocnum; - /* does AM support ORDER BY indexed column's value? */ + /* AM 是否支持按被索引列的值进行 ORDER BY? */ bool amcanorder; - /* does AM support ORDER BY result of an operator on indexed column? */ + /* AM 是否支持按被索引列上操作符的结果进行 ORDER BY? */ bool amcanorderbyop; - /* does AM support hashing using API consistent with the hash AM? */ - bool amcanhash; - /* do operators within an opfamily have consistent equality semantics? */ - bool amconsistentequality; - /* do operators within an opfamily have consistent ordering semantics? */ - bool amconsistentordering; - /* does AM support backward scanning? */ + /* AM 是否支持反向扫描? */ bool amcanbackward; - /* does AM support UNIQUE indexes? */ + /* AM 是否支持 UNIQUE 索引? */ bool amcanunique; - /* does AM support multi-column indexes? */ + /* AM 是否支持多列索引? */ bool amcanmulticol; - /* does AM require scans to have a constraint on the first index column? */ + /* AM 是否要求扫描必须约束第一个索引列? */ bool amoptionalkey; - /* does AM handle ScalarArrayOpExpr quals? */ + /* AM 是否处理 ScalarArrayOpExpr 限定条件? */ bool amsearcharray; - /* does AM handle IS NULL/IS NOT NULL quals? */ + /* AM 是否处理 IS NULL/IS NOT NULL 限定条件? */ bool amsearchnulls; - /* can index storage data type differ from column data type? */ + /* 索引存储数据类型是否可以不同于列数据类型? */ bool amstorage; - /* can an index of this type be clustered on? */ + /* 是否可以按此类型的索引进行聚簇? */ bool amclusterable; - /* does AM handle predicate locks? */ + /* AM 是否处理谓词锁? */ bool ampredlocks; - /* does AM support parallel scan? */ + /* AM 是否支持并行扫描? */ bool amcanparallel; - /* does AM support parallel build? */ - bool amcanbuildparallel; - /* does AM support columns included with clause INCLUDE? */ + /* AM 是否支持由 INCLUDE 子句包含的列? */ bool amcaninclude; - /* does AM use maintenance_work_mem? */ + /* AM 是否使用 maintenance_work_mem? */ bool amusemaintenanceworkmem; - /* does AM summarize tuples, with at least all tuples in the block - * summarized in one summary */ + /* AM 是否对元组进行摘要,且一个摘要至少涵盖 + * 块中的所有元组? */ bool amsummarizing; - /* OR of parallel vacuum flags */ + /* 并行清理标志的 OR 组合 */ uint8 amparallelvacuumoptions; - /* type of data stored in index, or InvalidOid if variable */ + /* 索引中存储的数据类型;如果可变,则为 InvalidOid */ Oid amkeytype; - /* interface functions */ + /* 接口函数 */ ambuild_function ambuild; ambuildempty_function ambuildempty; aminsert_function aminsert; - aminsertcleanup_function aminsertcleanup; /* can be NULL */ ambulkdelete_function ambulkdelete; amvacuumcleanup_function amvacuumcleanup; - amcanreturn_function amcanreturn; /* can be NULL */ + amcanreturn_function amcanreturn; /* 可以为 NULL */ amcostestimate_function amcostestimate; - amgettreeheight_function amgettreeheight; /* can be NULL */ amoptions_function amoptions; - amproperty_function amproperty; /* can be NULL */ - ambuildphasename_function ambuildphasename; /* can be NULL */ + amproperty_function amproperty; /* 可以为 NULL */ + ambuildphasename_function ambuildphasename; /* 可以为 NULL */ amvalidate_function amvalidate; - amadjustmembers_function amadjustmembers; /* can be NULL */ + amadjustmembers_function amadjustmembers; /* 可以为 NULL */ ambeginscan_function ambeginscan; amrescan_function amrescan; - amgettuple_function amgettuple; /* can be NULL */ - amgetbitmap_function amgetbitmap; /* can be NULL */ + amgettuple_function amgettuple; /* 可以为 NULL */ + amgetbitmap_function amgetbitmap; /* 可以为 NULL */ amendscan_function amendscan; - ammarkpos_function ammarkpos; /* can be NULL */ - amrestrpos_function amrestrpos; /* can be NULL */ + ammarkpos_function ammarkpos; /* 可以为 NULL */ + amrestrpos_function amrestrpos; /* 可以为 NULL */ - /* interface functions to support parallel index scans */ - amestimateparallelscan_function amestimateparallelscan; /* can be NULL */ - aminitparallelscan_function aminitparallelscan; /* can be NULL */ - amparallelrescan_function amparallelrescan; /* can be NULL */ - - /* interface functions to support planning */ - amtranslate_strategy_function amtranslatestrategy; /* can be NULL */ - amtranslate_cmptype_function amtranslatecmptype; /* can be NULL */ + /* 支持并行索引扫描的接口函数 */ + amestimateparallelscan_function amestimateparallelscan; /* 可以为 NULL */ + aminitparallelscan_function aminitparallelscan; /* 可以为 NULL */ + amparallelrescan_function amparallelrescan; /* 可以为 NULL */ } IndexAmRoutine; @@ -140,7 +126,7 @@ typedef struct IndexAmRoutine - IndexAmRoutine 的某些标志字段还有一些不那么直观的含义。amcanunique 的要求见 amcanmulticol 标志表明该访问方法支持多键列索引,而 amoptionalkey 表明它允许在第一索引列上没有给出可索引限制子句时进行扫描。当 amcanmulticol 为假时,amoptionalkey 实质上表示该访问方法是否支持没有任何限制子句的全索引扫描。支持多个索引列的访问方法必须支持在第一列之后省略任意一个或全部列限制条件的扫描;但它们可以要求第一索引列必须出现某种限制条件,这通过把 amoptionalkey 设为假来表示。索引 AM 可能把 amoptionalkey 设为假的一个原因,是它不索引 NULL 值。由于大多数可索引操作符都是严格的(strict),因此对 NULL 输入不可能返回 true,所以乍看之下不存储 NULL 值的索引条目似乎很有吸引力:无论如何,这些条目似乎都不可能被索引扫描返回。然而,当某个索引扫描对给定索引列没有限制子句时,这个论证就不成立了。实践中这意味着,若索引把 amoptionalkey 设为真,就必须索引 NULL 值,因为规划器可能决定在完全没有扫描键的情况下使用这种索引。与此相关的另一个限制是,支持多个索引列的索引访问方法必须支持对第一列之后各列中的 NULL 值建立索引,因为规划器会假定该索引可用于不限制这些列的查询。例如,考虑一个在 (a,b) 上的索引以及查询 WHERE a = 4。系统会假定该索引可用于扫描满足 a = 4 的行;如果索引省略了 b 为 NULL 的行,这个假定就是错误的。不过,省略第一索引列为 NULL 的行是可以的。对 NULL 值建立索引的索引访问方法还可以设置 amsearchnulls,表示它支持把 IS NULLIS NOT NULL 子句作为搜索条件。 + IndexAmRoutine 的某些标志字段还有一些不那么直观的含义。amcanunique 的要求见 amcanmulticol 标志表明该访问方法支持多键列索引,而 amoptionalkey 表明它允许在第一索引列上没有给出可索引限制子句时进行扫描。当 amcanmulticol 为假时,amoptionalkey 实质上表示该访问方法是否支持没有任何限制子句的全索引扫描。支持多个索引列的访问方法必须支持在第一列之后省略任意一个或全部列限制条件的扫描;但它们可以要求第一索引列必须出现某种限制条件,这通过把 amoptionalkey 设为假来表示。索引 AM 可能把 amoptionalkey 设为假的一个原因,是它不索引 NULL 值。由于大多数可索引操作符都是严格的(strict),因此对 NULL 输入不可能返回 true,所以乍看之下不存储 NULL 值的索引条目似乎很有吸引力:无论如何,这些条目似乎都不可能被索引扫描返回。然而,当某个索引扫描对给定索引列没有限制子句时,这个论证就不成立了。实践中这意味着,若索引把 amoptionalkey 设为真,就必须索引 NULL 值,因为规划器可能决定在完全没有扫描键的情况下使用这种索引。与此相关的另一个限制是,支持多个索引列的索引访问方法必须支持对第一列之后各列中的 NULL 值建立索引,因为规划器会假定该索引可用于不限制这些列的查询。例如,考虑一个在 (a,b) 上的索引以及查询 WHERE a = 4。系统会假定该索引可用于扫描满足 a = 4 的行;如果索引省略了 b 为 NULL 的行,这个假定就是错误的。不过,省略第一索引列为 NULL 的行是可以的。对 NULL 值建立索引的索引访问方法还可以设置 amsearchnulls,表示它支持把 IS NULLIS NOT NULL 子句作为搜索条件。 @@ -148,7 +134,7 @@ typedef struct IndexAmRoutine - amsummarizing 标志指示该访问方法是否会对被索引元组做摘要,并且摘要粒度至少达到每个块一个摘要。不指向单个元组,而是指向块范围(例如 BRIN)的访问方法,可能允许继续使用 HOT 优化。这不适用于索引谓词中引用的属性,对这类属性的更新总会禁用 HOT。 + amsummarizing 标志指示该访问方法是否会对被索引元组做摘要,并且摘要粒度至少为一个块。不指向单个元组,而是指向块范围(例如 BRIN)的访问方法,可能允许继续使用 HOT 优化。这不适用于索引谓词中引用的属性,对这类属性的更新总会禁用 HOT @@ -166,9 +152,7 @@ IndexBuildResult * ambuild (Relation heapRelation, Relation indexRelation, IndexInfo *indexInfo); - - 构建一个新索引。索引关系已经在物理上创建,但还是空的。它必须填入访问方法所需的任何固定数据,以及表中所有现有元组对应的条目。通常,ambuild 函数会调用 table_index_build_scan() 来扫描表中已有的元组,并计算需要插入索引的键值。该函数必须返回一个通过 palloc 分配的结构体,其中包含有关新索引的统计信息。amcanbuildparallel 标志指示该访问方法是否支持并行索引构建。设为 true 时,系统会尝试为构建分配并行工作进程。只支持非并行索引构建的访问方法应把该标志保留为 false。 - +构建新索引。索引关系已在物理上创建,但内容为空。必须填入访问方法所需的固定数据,以及表中所有已有元组对应的条目。通常,ambuild函数会调用table_index_build_scan()扫描表中现有的元组,并计算需要插入索引的键。函数必须返回一个通过 palloc 分配的结构体,其中包含新索引的统计信息。 @@ -206,16 +190,7 @@ aminsert (Relation indexRelation, - 如果索引 AM 希望在一条 SQL 语句中的连续索引插入之间缓存数据,它可以在 indexInfo->ii_Context 中分配空间,并把数据指针存入 indexInfo->ii_AmCache(该指针初始为 NULL)。如果在索引插入后需要释放内存之外的资源,可以提供 aminsertcleanup,它会在内存释放之前被调用。 - - - - -void -aminsertcleanup (Relation indexRelation, - IndexInfo *indexInfo); - - 清理由 indexInfo->ii_AmCache 在连续插入之间维护的状态。如果这些数据需要额外的清理步骤(例如释放已钉住的缓冲区),而仅释放内存还不够,那么这个函数就很有用。 + 如果索引 AM 希望在一条 SQL 语句中的连续索引插入之间缓存数据,它可以在 indexInfo->ii_Context 中分配空间,并把数据指针存入 indexInfo->ii_AmCache(该指针初始为 NULL)。 @@ -226,7 +201,7 @@ ambulkdelete (IndexVacuumInfo *info, IndexBulkDeleteCallback callback, void *callback_state); - 从索引中删除元组。这是一个批量删除操作,通常应通过扫描整个索引并检查每个条目是否应被删除来实现。必须调用传入的 callback 函数,其调用形式为 callback(TID, callback_state) returns bool,以确定由其引用 TID 标识的某个索引条目是否应删除。该函数必须返回 NULL,或者返回一个通过 palloc 分配的结构体,其中包含此次删除操作影响的统计信息。如果不需要向 amvacuumcleanup 传递信息,返回 NULL 也是可以的。 + 从索引中删除元组。这是一个批量删除操作,旨在通过扫描整个索引并检查每个条目是否应被删除来实现。必须调用传入的 callback 函数,其调用形式为 callback(TID, callback_state) returns bool,以确定由其引用 TID 标识的某个索引条目是否应删除。该函数必须返回 NULL,或者返回一个通过 palloc 分配的结构体,其中包含此次删除操作影响的统计信息。如果不需要向 amvacuumcleanup 传递信息,返回 NULL 也是可以的。 @@ -251,8 +226,7 @@ amvacuumcleanup (IndexVacuumInfo *info, bool amcanreturn (Relation indexRelation, int attno); - 检查索引是否能够在给定列上支持 仅索引扫描,做法是返回该列原始的被索引值。属性编号从 1 开始,也就是说第一列的 attno 为 1。若支持则返回真,否则返回假。如果支持包含列,这个函数应始终对包含列返回真,因为不能取回的包含列几乎没有意义。如果访问方法根本不支持仅索引扫描,那么它的 IndexAmRoutine 结构体中的 amcanreturn 字段可以设为 NULL。 + 检查索引能否通过返回给定列原始的被索引值,在该列上支持 仅索引扫描。属性编号从 1 开始,也就是说第一列的 attno 为 1。若支持则返回真,否则返回假。如果支持包含列,这个函数应始终对包含列返回真,因为不能取回的包含列几乎没有意义。如果访问方法根本不支持仅索引扫描,那么它的 IndexAmRoutine 结构体中的 amcanreturn 字段可以设为 NULL。 @@ -267,15 +241,7 @@ amcostestimate (PlannerInfo *root, double *indexCorrelation, double *indexPages); - 估计一次索引扫描的开销。该函数将在后面的 中详细讨论。 - - - - -int -amgettreeheight (Relation rel); - - 计算树形索引的高度。这一信息会通过 path->indexinfo->tree_height 提供给 amcostestimate 函数,可用于支持开销估计。其结果不会在其他地方使用,因此这个函数实际上也可以用来计算索引上任何一种适合装入整数、且开销估计函数可能想知道的数据。如果计算代价较高,把结果缓存到 RelationData.rd_amcache 中可能会有用。 + 估计一次索引扫描的代价。该函数将在后面的 中详细讨论。 @@ -284,7 +250,7 @@ bytea * amoptions (ArrayType *reloptions, bool validate); - 解析并验证索引的 reloptions 数组。只有当该索引存在非空的 reloptions 数组时才会调用此函数。reloptions 是一个 text 数组,其中的条目形如 name=value。该函数应构造一个 bytea 值,并将其复制到索引 relcache 条目的 rd_options 字段中。这个 bytea 值中的数据内容由访问方法自行定义;大多数标准访问方法使用结构体 StdRdOptions。当 validate 为真时,若存在未识别选项或无效取值,函数应报告合适的错误消息;当 validate 为假时,无效条目应被静默忽略。(当装载已存储在 pg_catalog 中的选项时,validate 为假;此时只有在访问方法改变了选项规则时才可能发现无效条目,而忽略过时条目是合适的。)如果希望采用默认行为,返回 NULL 也是可以的。 + 解析并验证索引的 reloptions 数组。只有当该索引存在非 NULL 的 reloptions 数组时才会调用此函数。reloptions 是一个 text 数组,其中的条目形如 name=value。该函数应构造一个 bytea 值,并将其复制到索引 relcache 条目的 rd_options 字段中。这个 bytea 值中的数据内容由访问方法自行定义;大多数标准访问方法使用结构体 StdRdOptions。当 validate 为真时,若存在未识别选项或无效取值,函数应报告合适的错误消息;当 validate 为假时,无效条目应被静默忽略。(当装载已存储在 pg_catalog 中的选项时,validate 为假;此时只有在访问方法改变了选项规则时才可能发现无效条目,而忽略过时条目是合适的。)如果希望采用默认行为,返回 NULL 也是可以的。 @@ -298,7 +264,7 @@ amproperty (Oid index_oid, int attno, - 支持排序操作符的访问方法应当实现 AMPROP_DISTANCE_ORDERABLE 属性测试,因为核心代码不知道如何完成该测试,只会返回 NULL。若实现成本低于打开索引并调用 amcanreturn(这正是核心代码的默认行为),那么实现 AMPROP_RETURNABLE 测试也可能是有利的。对于其他所有标准属性,默认行为应当已经足够。 + 支持排序操作符的访问方法应当实现 AMPROP_DISTANCE_ORDERABLE 属性测试,因为核心代码不知道如何完成该测试,只会返回 NULL。若完成该测试的代价低于打开索引并调用 amcanreturn(这正是核心代码的默认行为),那么实现 AMPROP_RETURNABLE 测试也可能是有利的。对于其他所有标准属性,默认行为应当已经足够。 @@ -360,11 +326,11 @@ bool amgettuple (IndexScanDesc scan, ScanDirection direction); - 在给定扫描中取出下一个元组,并按给定方向移动(在索引中向前或向后)。若成功取得元组则返回真;若不再有匹配元组则返回假。在返回真时,元组的 TID 会存入 scan 结构体中。请注意,成功仅表示索引中存在一个匹配扫描键的条目,并不表示该元组一定仍然存在于堆中,或者一定能通过调用者的快照测试。成功时,amgettuple 还必须把 scan->xs_recheck 设为真或假。假表示可以确定该索引条目匹配扫描键;真表示这一点并不确定,因此在取到堆元组后必须根据扫描键所代表的条件重新检查它。这一机制支持有损索引操作符。请注意,重检只会扩展到扫描条件;部分索引谓词(如果有)永远不会由 amgettuple 的调用者重新检查。 + 在给定扫描中取出下一个元组,并按给定方向移动(在索引中向前或向后)。若成功取得元组则返回真;若不再有匹配元组则返回假。在返回真时,元组的 TID 会存入 scan 结构体中。请注意,成功仅表示索引中存在一个匹配扫描键的条目,并不表示该元组一定仍然存在于堆中,或者一定能通过调用者的快照测试。成功时,amgettuple 还必须把 scan->xs_recheck 设为真或假。假表示可以确定该索引条目匹配扫描键;真表示这一点并不确定,因此在取到堆元组后必须根据扫描键所代表的条件重新检查它。这一机制支持有损索引操作符。请注意,重检只针对扫描条件;部分索引谓词(如果有)永远不会由 amgettuple 的调用者重新检查。 - 如果索引支持 仅索引扫描(即其任一列上 amcanreturn 返回真),那么成功时 AM 还必须检查 scan->xs_want_itup;若其为真,就必须返回该索引条目的原始被索引数据。对于 amcanreturn 返回假的列,可以把其值作为 NULL 返回。数据可以通过以下两种形式之一返回:一种是把 IndexTuple 指针存入 scan->xs_itup,其元组描述符为 scan->xs_itupdesc;另一种是把 HeapTuple 指针存入 scan->xs_hitup,其元组描述符为 scan->xs_hitupdesc。(当重建出的数据可能装不进 IndexTuple 时,应使用后一种格式。)无论采用哪种形式,指针所引用数据的管理责任都在访问方法一侧。对这份数据的有效性必须至少保持到该扫描下一次调用 amgettupleamrescanamendscan 为止。 + 如果索引支持 仅索引扫描(即其至少一列上 amcanreturn 返回真),那么成功时 AM 还必须检查 scan->xs_want_itup;若其为真,就必须返回该索引条目的原始被索引数据。对于 amcanreturn 返回假的列,可以把其值作为 NULL 返回。数据可以通过以下两种形式之一返回:一种是把 IndexTuple 指针存入 scan->xs_itup,其元组描述符为 scan->xs_itupdesc;另一种是把 HeapTuple 指针存入 scan->xs_hitup,其元组描述符为 scan->xs_hitupdesc。(当重建出的数据可能装不进 IndexTuple 时,应使用后一种格式。)无论采用哪种形式,指针所引用数据的管理责任都在访问方法一侧。这份数据必须至少保持有效,直到该扫描下一次调用 amgettupleamrescanamendscan @@ -377,7 +343,7 @@ int64 amgetbitmap (IndexScanDesc scan, TIDBitmap *tbm); - 取出给定扫描中的所有元组,并将其加入调用者提供的 TIDBitmap 中(也就是把这组元组 ID 与位图中已有的集合做 OR)。返回值是取得的元组数量(这可能只是近似计数,例如某些 AM 不会检测重复项)。在把元组 ID 插入位图时,amgetbitmap 可以指出某些具体的元组 ID 需要重新检查扫描条件。这类似于 amgettuplexs_recheck 输出参数。注意:在当前实现中,对这一特性的支持与位图自身的有损存储支持混在一起,因此调用者会对可重检元组同时重新检查扫描条件和部分索引谓词(如果有)。不过,这并不一定永远如此。amgetbitmapamgettuple 不能在同一次索引扫描中同时使用;使用 amgetbitmap 时还有其他限制,详见 。 + 取出给定扫描中的所有元组,并将其加入调用者提供的 TIDBitmap 中(也就是把这组元组 ID 与位图中已有的集合做 OR)。返回值是取得的元组数量(这可能只是近似计数,例如某些 AM 不会检测重复项)。在把元组 ID 插入位图时,amgetbitmap 可以指出某些具体的元组 ID 需要重新检查扫描条件。这类似于 amgettuplexs_recheck 输出参数。注意:在当前实现中,对这一特性的支持与位图自身的有损存储支持混在一起,因此调用者会对需要重检的元组同时重新检查扫描条件和部分索引谓词(如果有)。不过,这并不一定永远如此。amgetbitmapamgettuple 不能在同一次索引扫描中同时使用;使用 amgetbitmap 时还有其他限制,详见 @@ -389,7 +355,7 @@ amgetbitmap (IndexScanDesc scan, void amendscan (IndexScanDesc scan); - 结束一次扫描并释放资源。scan 结构体本身不应被释放,但访问方法内部获取的任何锁或 pin,以及由 ambeginscan 和其他扫描相关函数分配的其他内存,都必须被释放。 + 结束一次扫描并释放资源。scan 结构体本身不应被释放,但必须释放访问方法内部获取的所有锁、解除所有钉住状态,并释放由 ambeginscan 和其他扫描相关函数分配的其他内存。 @@ -423,15 +389,8 @@ amrestrpos (IndexScanDesc scan); Size -amestimateparallelscan (Relation indexRelation, - int nkeys, - int norderbys); - - 估计并返回执行并行扫描时该访问方法所需动态共享内存的字节数。(这个数字是额外需求,并不替代 ParallelIndexScanDescData 中 AM 无关数据所需的空间。) - - - - nkeysnorderbys 参数表示扫描中将使用的限定条件和排序操作符数量;同样的数值也会传给 amrescan。请注意,此时还没有提供扫描键的实际值。 +amestimateparallelscan (void); +估算并返回访问方法执行并行扫描所需的动态共享内存字节数。(此数值是额外需要的空间,不包括以下结构体中与访问方法无关的数据所需的空间:ParallelIndexScanDescData。) @@ -458,17 +417,6 @@ amparallelrescan (IndexScanDesc scan); 如果实现了此函数,当并行索引扫描必须重新开始时就会调用它。它应重置由 aminitparallelscan 建立的任何共享状态,以便扫描从头开始重新执行。 - - -CompareType -amtranslatestrategy (StrategyNumber strategy, Oid opfamily, Oid opcintype); - -StrategyNumber -amtranslatecmptype (CompareType cmptype, Oid opfamily, Oid opcintype); - - 如果实现了这些函数,规划器和执行器就会调用它们,在固定的 CompareType 值与访问方法所使用的特定策略编号之间进行转换。提供了与内置 btree 或 hash 访问方法相似功能的访问方法可以实现这些函数;通过实现这些转换,系统就能理解该访问方法操作的语义,并在多个地方把它们当作 btree 或 hash 索引的替代。如果该访问方法的功能与这些内置访问方法并不相似,就不需要实现这些函数。若不实现,访问方法会在某些规划器和执行器决策中被忽略,但除此之外仍然完全可用。 - - @@ -524,7 +472,7 @@ amtranslatecmptype (CompareType cmptype, Oid opfamily, Oid opcintype); - 除了使用 amgettuple 外,索引扫描也可以使用 amgetbitmap,在一次调用中取出所有元组。与 amgettuple 相比,这通常明显更高效,因为它可以避免访问方法内部的反复加锁和解锁。原则上,amgetbitmap 应具有与重复调用 amgettuple 相同的效果,但为了简化实现,我们施加了若干限制。首先,amgetbitmap 一次性返回全部元组,因此不支持标记或恢复扫描位置。其次,元组是通过一个位图返回的,没有特定顺序,这也是为什么 amgetbitmap 不带 direction 参数的原因。(这种扫描也永远不会提供排序操作符。)此外,使用 amgetbitmap 时也没有仅索引扫描的支持,因为没有办法返回索引元组的内容。最后,amgetbitmap 不保证对返回的元组做任何锁定,其影响见 。 + 除了使用 amgettuple 外,索引扫描也可以使用 amgetbitmap,在一次调用中取出所有元组。与 amgettuple 相比,这可能明显更高效,因为它可以避免访问方法内部的反复加锁和解锁。原则上,amgetbitmap 应具有与重复调用 amgettuple 相同的效果,但为了简化实现,我们施加了若干限制。首先,amgetbitmap 一次性返回全部元组,因此不支持标记或恢复扫描位置。其次,元组是通过一个位图返回的,没有特定顺序,这也是为什么 amgetbitmap 不带 direction 参数的原因。(这种扫描也永远不会提供排序操作符。)此外,使用 amgetbitmap 时也没有仅索引扫描的支持,因为没有办法返回索引元组的内容。最后,amgetbitmap 不保证对返回的元组做任何锁定,其影响见 @@ -541,7 +489,7 @@ amtranslatecmptype (CompareType cmptype, Oid opfamily, Oid opcintype); - 构建一种支持并发更新的索引类型,通常需要对所需行为进行大量而细致的分析。对于 B-树和哈希索引类型,可以阅读 src/backend/access/nbtree/READMEsrc/backend/access/hash/README 中涉及的设计决策。 + 构建一种支持并发更新的索引类型,通常需要对所需行为进行大量而细致的分析。对于 B-树和 hash 索引类型,可以阅读 src/backend/access/nbtree/READMEsrc/backend/access/hash/README 中涉及的设计决策。 @@ -560,12 +508,12 @@ amtranslatecmptype (CompareType cmptype, Oid opfamily, Oid opcintype); - 索引扫描必须在保存 amgettuple 最近一次返回条目的索引页面上维护一个 pin,而 ambulkdelete 不能从被其他后端钉住的页面中删除条目。下面会解释为什么需要这条规则。 + 索引扫描必须在保存 amgettuple 最近一次返回条目的索引页面上保持钉住状态,而 ambulkdelete 不能从被其他后端钉住的页面中删除条目。下面会解释为什么需要这条规则。 - 如果没有第三条规则,索引读取者就有可能在某个索引条目被 VACUUM 删除之前先看到它,然后在对应的堆条目已被 VACUUM 删除之后才到达那里。如果读取者到达时,该项号仍未被重新使用,就不会造成严重问题,因为空项槽位会被 heap_fetch() 忽略。但如果第三个后端已经把这个项槽位重新用作别的东西呢?在使用 MVCC 兼容快照时不会有问题,因为该槽位的新占用者一定太新,无法通过快照测试。然而,对于非 MVCC 兼容的快照(例如 SnapshotAny),就可能错误地接受并返回一行实际上并不匹配扫描键的数据。我们可以要求在所有情况下都对堆行重新检查扫描键,以防范这种情形,但那样代价太高。于是,我们改为把索引页面上的 pin 作为一种代理,表示读取者可能仍处于从索引条目前往匹配堆条目的飞行中。让 ambulkdelete 在这种 pin 上阻塞,能够保证 VACUUM 不会在读取者处理完之前删除对应的堆条目。这种方案运行时开销很小,只有在真正发生冲突的少数情况下才会增加阻塞开销。 + 如果没有第三条规则,索引读取者就有可能在某个索引条目被 VACUUM 删除之前先看到它,然后在对应的堆条目已被 VACUUM 删除之后才到达那里。如果读取者到达时,该项号仍未被重新使用,就不会造成严重问题,因为空项槽位会被 heap_fetch() 忽略。但如果第三个后端已经把这个项槽位重新用作别的东西呢?在使用 MVCC 兼容快照时不会有问题,因为该槽位的新占用者一定太新,无法通过快照测试。然而,对于非 MVCC 兼容的快照(例如 SnapshotAny),就可能错误地接受并返回一行实际上并不匹配扫描键的数据。我们可以要求在所有情况下都对堆行重新检查扫描键,以防范这种情形,但那样代价太高。于是,我们改为把索引页面的钉住状态作为一种代理,表示读取者从索引条目到匹配堆条目的访问过程可能仍在进行中。让 ambulkdelete 因这种钉住状态而阻塞,能够保证 VACUUM 不会在读取者处理完之前删除对应的堆条目。这种方案运行时开销很小,只有在真正发生冲突的少数情况下才会增加阻塞开销。 @@ -573,7 +521,7 @@ amtranslatecmptype (CompareType cmptype, Oid opfamily, Oid opcintype); - 在 amgetbitmap 索引扫描中,访问方法不会在任何返回的元组上保留索引 pin。因此,只有把这种扫描与 MVCC 兼容的快照一起使用才是安全的。 + 在 amgetbitmap 索引扫描中,访问方法不会为任何返回的元组保持索引页面的钉住状态。因此,只有把这种扫描与 MVCC 兼容的快照一起使用才是安全的。 @@ -612,7 +560,7 @@ amtranslatecmptype (CompareType cmptype, Oid opfamily, Oid opcintype); - 此外,在按照上述规则报告唯一性违背之前,访问方法必须立即重新检查正在插入那一行的存活性。如果它已经是提交后死亡的状态,就不应报告违背。(这种情况不会出现在插入由当前事务刚创建的行这一普通场景中,但在 CREATE UNIQUE INDEX CONCURRENTLY 期间却可能发生。) + 此外,就在按照上述规则报告唯一性违背之前,访问方法必须重新检查正在插入那一行的存活性。如果它已经是提交后死亡的状态,就不应报告违背。(这种情况不会出现在插入由当前事务刚创建的行这一普通场景中,但在 CREATE UNIQUE INDEX CONCURRENTLY 期间却可能发生。) @@ -620,7 +568,7 @@ amtranslatecmptype (CompareType cmptype, Oid opfamily, Oid opcintype); - 如果唯一约束是可延迟的,情况会更复杂:我们需要能够为新行插入一个索引条目,但把任何唯一性违背错误延迟到语句结束时甚至更晚才报告。为了避免对索引进行不必要的重复搜索,索引访问方法应在初始插入期间执行一次初步唯一性检查。如果这表明确实不存在冲突的存活元组,那么事情就结束了。否则,我们会安排在真正强制约束时再做一次重检。若在重检时,插入的元组与另外某个具有相同键值的元组都仍然存活,就必须报告错误。(注意,就此用途而言,存活实际上是指索引条目 HOT 链中的任一元组是存活的。)为实现这一点,传给 aminsert 函数的 checkUnique 参数会取以下值之一: + 如果唯一约束是可延迟的,情况会更复杂:我们需要能够为新行插入一个索引条目,但把任何唯一性违背错误延迟到语句结束时甚至更晚才报告。为了避免对索引进行不必要的重复搜索,索引访问方法应在初始插入期间执行一次初步唯一性检查。如果这表明确实不存在冲突的存活元组,那么事情就结束了。否则,我们会安排在真正强制约束时再做一次重检。若在重检时,插入的元组与另外某个具有相同键值的元组都仍然存活,就必须报告错误。(注意,就此用途而言,存活实际上是指索引条目 HOT 链中至少有一个元组是存活的。)为实现这一点,传给 aminsert 函数的 checkUnique 参数会取以下值之一: @@ -657,10 +605,10 @@ amtranslatecmptype (CompareType cmptype, Oid opfamily, Oid opcintype); - 索引开销估计函数 + 索引代价估算函数 - amcostestimate 函数会收到描述某种可能索引扫描方式的信息,其中包括已经确定可用于该索引的 WHERE 子句和 ORDER BY 子句列表。它必须返回访问该索引的开销估计,以及 WHERE 子句的选择率(也就是在索引扫描期间将从父表中检索出的行所占比例)。对于简单情况,开销估计器几乎所有工作都可以通过调用优化器中的标准例程来完成;之所以提供 amcostestimate 函数,是为了让索引访问方法能够提供与索引类型有关的专门知识,以便在可能时改进标准估计。 + amcostestimate 函数会收到描述某种可能索引扫描方式的信息,其中包括已经确定可用于该索引的 WHERE 子句和 ORDER BY 子句列表。它必须返回访问该索引的代价估算,以及 WHERE 子句选择率的估计值(也就是在索引扫描期间将从父表中检索出的行所占比例)。对于简单情况,代价估算器几乎所有工作都可以通过调用优化器中的标准例程来完成;之所以提供 amcostestimate 函数,是为了让索引访问方法能够提供与索引类型有关的专门知识,以便在可能时改进标准估计。 @@ -694,7 +642,7 @@ amcostestimate (PlannerInfo *root, path - 当前正在考虑的索引访问路径。除开销和选择率字段外,其余字段都有效。 + 当前正在考虑的索引访问路径。除代价和选择率字段外,其余字段都有效。 @@ -703,7 +651,7 @@ amcostestimate (PlannerInfo *root, loop_count - 在开销估计中应计入的索引扫描重复次数。当考虑在嵌套循环连接内部使用参数化扫描时,这个参数通常会大于 1。请注意,开销估计仍应只针对一次扫描;更大的 loop_count 只表示可以适当考虑多次扫描之间的一些缓存效应。 + 在代价估算中应计入的索引扫描重复次数。当考虑在嵌套循环连接内部使用参数化扫描时,这个参数通常会大于 1。请注意,代价估算仍应只针对一次扫描;更大的 loop_count 只表示可以适当考虑多次扫描之间的一些缓存效应。 @@ -718,7 +666,7 @@ amcostestimate (PlannerInfo *root, *indexStartupCost - 设为索引启动处理的开销。 + 设为索引启动处理的代价。 @@ -727,7 +675,7 @@ amcostestimate (PlannerInfo *root, *indexTotalCost - 设为索引处理的总开销。 + 设为索引处理的总代价。 @@ -762,19 +710,19 @@ amcostestimate (PlannerInfo *root, - 请注意,开销估计函数必须用 C 编写,而不能用 SQL 或任何可用的过程语言,因为它们必须访问规划器/优化器的内部数据结构。 + 请注意,代价估算函数必须用 C 编写,而不能用 SQL 或任何可用的过程语言,因为它们必须访问规划器/优化器的内部数据结构。 - 索引访问开销应使用 src/backend/optimizer/path/costsize.c 所采用的参数来计算:顺序磁盘块读取的开销为 seq_page_cost,非顺序读取的开销为 random_page_cost,处理一条索引行的开销通常应取为 cpu_index_tuple_cost。此外,在索引处理期间调用的任何比较操作符(特别是对 indexquals 本身的求值)都应计入适当倍数的 cpu_operator_cost。 + 索引访问代价应使用 src/backend/optimizer/path/costsize.c 所采用的参数来计算:顺序磁盘块读取的代价为 seq_page_cost,非顺序读取的代价为 random_page_cost,处理一条索引行的代价通常应取为 cpu_index_tuple_cost。此外,在索引处理期间调用的任何比较操作符(特别是对 indexquals 本身的求值)都应计入适当倍数的 cpu_operator_cost - 访问开销应包括与扫描索引本身有关的全部磁盘和 CPU 开销,但包括取出或处理由索引标识出的父表行的开销。 + 访问代价应包括与扫描索引本身有关的全部磁盘和 CPU 代价,但包括取出或处理由索引标识出的父表行的代价。 - 启动开销是整个扫描总开销中必须在开始取第一行之前先付出的那一部分。对大多数索引来说,这可以视为零;但启动开销较高的索引类型可能希望把它设为非零。 + 启动代价是整个扫描总代价中必须在开始取第一行之前先付出的那一部分。对大多数索引来说,这可以视为零;但启动代价较高的索引类型可能希望把它设为非零。 @@ -782,7 +730,7 @@ amcostestimate (PlannerInfo *root, - indexCorrelation 应设为索引顺序与表顺序之间的相关性(范围从 -1.0 到 1.0)。该值用于调整从父表取行开销的估计。 + indexCorrelation 应设为索引顺序与表顺序之间的相关性(范围从 -1.0 到 1.0)。该值用于调整从父表取行代价的估计。 @@ -794,9 +742,9 @@ amcostestimate (PlannerInfo *root, - 开销估计 + 代价估算 - 一个典型的开销估计器会按如下步骤进行: + 一个典型的代价估算器会按如下步骤进行: @@ -825,14 +773,14 @@ amcostestimate (PlannerInfo *root, - 计算索引访问开销。一个通用估计器可能会这样做: + 计算索引访问代价。一个通用估计器可能会这样做: /* - * Our generic assumption is that the index pages will be read - * sequentially, so they cost seq_page_cost each, not random_page_cost. - * Also, we charge for evaluation of the indexquals at each index row. - * All the costs are assumed to be paid incrementally during the scan. + * 通用假设是索引页面将按顺序读取, + * 因此每页代价为 seq_page_cost,而非 random_page_cost。 + * 此外,还要计入在每个索引行上对 indexquals 求值的代价。 + * 假定所有代价都在扫描过程中逐步付出。 */ cost_qual_eval(&index_qual_cost, path->indexquals, root); *indexStartupCost = index_qual_cost.startup; @@ -852,7 +800,7 @@ cost_qual_eval(&index_qual_cost, path->indexquals, root); - 开销估计器函数的示例可在 src/backend/utils/adt/selfuncs.c 中找到。 + 代价估算器函数的示例可在 src/backend/utils/adt/selfuncs.c 中找到。 diff --git a/zh/16/indices.sgml b/zh/16/indices.sgml index 84fbb8ac..d2578d63 100644 --- a/zh/16/indices.sgml +++ b/zh/16/indices.sgml @@ -31,7 +31,7 @@ SELECT content FROM test1 WHERE id = constant; - 大多数非小说类书籍也采用了类似的方法:读者经常查找的术语和概念会被收集到书末按字母顺序排列的索引中。感兴趣的读者可以相对快速地浏览索引并翻到相应页面,而不必通读整本书才能找到自己感兴趣的内容。正如作者需要预判读者可能查找哪些条目一样,数据库程序员也需要预见哪些索引会有用。 + 大多数非虚构类书籍也采用了类似的方法:读者经常查找的术语和概念会被收集到书末按字母顺序排列的索引中。感兴趣的读者可以相对快速地浏览索引并翻到相应页面,而不必通读整本书才能找到自己感兴趣的内容。正如作者需要预判读者可能查找哪些条目一样,数据库程序员也需要预见哪些索引会有用。 @@ -71,7 +71,7 @@ CREATE INDEX test1_id_index ON test1 (id); comparison-value operator indexed-column - 那么如果原始operator有一个可交换操作符,并且该操作符属于该索引的操作符类,就可以把它翻转成可索引的形式。 + 那么如果原始operator有一个交换子操作符,并且该操作符属于该索引的操作符类,就可以把它翻转成可索引的形式。 @@ -100,12 +100,12 @@ CREATE INDEX name ON table B-树 - index + 索引 B-树 B-树 - index + 索引 @@ -133,12 +133,12 @@ CREATE INDEX name ON table Hash - index + 索引 hash hash - index + 索引 @@ -154,12 +154,12 @@ CREATE INDEX name ON table GiST - index + 索引 GiST GiST - index + 索引 @@ -178,7 +178,7 @@ CREATE INDEX name ON table SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10; ]]> - 这会找出距离给定目标点最近的十个地点。是否能做到这一点,同样取决于所使用的具体操作符类。在中,可以按这种方式使用的操作符列在Ordering Operators这一列中。 + 这会找出距离给定目标点最近的十个地点。是否能做到这一点,同样取决于所使用的具体操作符类。在中,可以按这种方式使用的操作符列在排序操作符这一列中。 @@ -186,12 +186,12 @@ SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10; SP-GiST - index + 索引 SP-GiST SP-GiST - index + 索引 @@ -205,7 +205,7 @@ SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10; - 与 GiST 一样,SP-GiST 支持最近邻搜索。对于支持距离排序的 SP-GiST 操作符类,相应操作符列在Ordering Operators列中。 + 与 GiST 一样,SP-GiST 支持最近邻搜索。对于支持距离排序的 SP-GiST 操作符类,相应操作符列在排序操作符列中。 @@ -213,12 +213,12 @@ SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10; GIN - index + 索引 GIN GIN - index + 索引 @@ -240,12 +240,12 @@ SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10; BRIN - index + 索引 BRIN BRIN - index + 索引 @@ -265,8 +265,8 @@ SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10; 多列索引 - index - multicolumn + 索引 + 多列 @@ -292,28 +292,18 @@ CREATE INDEX test2_mm_idx ON test2 (major, minor); 当前,只有 B-树、GiST、GIN 和 BRIN 索引类型支持多键列索引。能否有多个键列,与索引中能否添加INCLUDE列无关。索引最多可以有 32 列,包括INCLUDE列。(这个限制在构建PostgreSQL时可以修改;参见文件pg_config_manual.h。) - - 多列 B-树索引可以用于涉及索引任意列子集的查询条件,但当对前导(最左)列存在约束时,索引效率最高。精确的规则是:对前导列的等值约束,再加上第一个没有等值约束列上的任意不等约束,总会被用来限制被扫描的索引范围。这些列右侧列上的约束会在索引中进行检查,因此总能减少访问表本体的次数,但不一定会减少必须扫描的索引范围。如果 B-树索引扫描能够有效应用跳过扫描优化,那么它在通过反复的索引搜索遍历索引时,会利用每一列约束。这可能减少需要读取的索引部分,即便一个或多个列(位于查询谓词中最低有效索引列之前)缺少常规的等值约束。跳过扫描的工作方式是内部生成一个动态的等值约束,使其匹配索引列中的每个可能值(不过这只适用于某个列缺少来自查询谓词的等值约束,且生成的约束能够与查询谓词中较后列的约束联合使用时)。 - - - - 例如,给定一个(x, y)上的索引和查询条件WHERE y = 7700,B-树索引扫描可能能够应用跳过扫描优化。这通常发生在查询规划器预计:针对每个可能的N反复执行WHERE x = N AND y = 7700搜索(或者针对索引中实际存储的每个x值),在当前表上可用索引的前提下,这是最快的方法。一般来说,只有当不同的x值很少,以致规划器预计扫描能跳过索引的大部分内容时,才会采用这种方法(因为大多数叶子页都不可能包含相关元组)。如果不同的x值很多,那么就必须扫描整个索引,因此在大多数情况下,规划器会更倾向于顺序扫描表而不是使用该索引。 - - - - 在至少具有一部分来自查询谓词的有用约束的 B-树扫描中,跳过扫描优化也可以被选择性地应用。例如,给定一个(a, b, c)上的索引和查询条件WHERE a = 5 AND b >= 42 AND c < 77,该索引可能必须从第一个a = 5 且b = 42 的条目扫描,一直到最后一个a = 5 的条目。c >= 77 的索引项永远不需要在表层面进行过滤,但是否值得在索引内部跳过它们,则未必。发生跳过时,扫描会启动一次新的索引搜索,把自身从当前a = 5 且b = N 分组的末尾重新定位(也就是索引中第一个a = 5 AND b = N AND c >= 77元组出现的位置),移动到下一个这类分组的起始位置(也就是索引中第一个a = 5 AND b = N + 1元组出现的位置)。 - + 多列 B-树索引可以用于涉及索引任意列子集的查询条件,但当对前导(最左)列存在约束时,索引效率最高。精确的规则是:对前导列的等值约束,再加上第一个没有等值约束的列上的任何不等约束,会被用来限制索引扫描的范围。这些列右侧列上的约束会在索引中进行检查,因此可以减少访问表本体的次数,但不会缩小必须扫描的索引范围。例如,给定一个 (a, b, c) 上的索引和查询条件 WHERE a = 5 AND b >= 42 AND c < 77,索引必须从第一个 a = 5 且 b = 42 的条目扫描到最后一个 a = 5 的条目。c >= 77 的索引项会被排除,但仍然必须扫描这些项。原则上,这个索引也可以用于只对 b 和/或 c 有约束、而对 a 没有约束的查询,但必须扫描整个索引,因此在大多数情况下,规划器会倾向于顺序扫描表,而不是使用该索引。 多列 GiST 索引可以用于涉及索引任意列子集的查询条件。附加列上的条件会限制索引返回的项,但决定索引需要扫描多少内容的,最重要的仍是第一列上的条件。如果第一列只有很少几个非重复值,即使其他列有很多非重复值,GiST 索引也会相对低效。 - 多列 GIN 索引可以用于涉及索引任意列子集的查询条件。与 B-树或 GiST 不同,无论查询条件使用的是哪一列索引列,GIN 的索引搜索效果都一样。 + 多列 GIN 索引可以用于涉及索引任意列子集的查询条件。与 B-树或 GiST 不同,无论查询条件使用的是哪些索引列,GIN 的索引搜索效果都一样。 - 多列 BRIN 索引可以用于涉及索引任意列子集的查询条件。和 GIN 一样、不同于 B-树或 GiST,无论查询条件使用的是哪一列索引列,索引搜索效果都一样。在单个表上使用多个 BRIN 索引,而不是使用一个多列 BRIN 索引的唯一理由,是需要不同的pages_per_range存储参数。 + 多列 BRIN 索引可以用于涉及索引任意列子集的查询条件。和 GIN 一样、不同于 B-树或 GiST,无论查询条件使用的是哪些索引列,索引搜索效果都一样。在单个表上使用多个 BRIN 索引,而不是使用一个多列 BRIN 索引的唯一理由,是需要不同的pages_per_range存储参数。 @@ -330,8 +320,8 @@ CREATE INDEX test2_mm_idx ON test2 (major, minor); 索引和<literal>ORDER BY</literal> - index - and ORDER BY + 索引 + ORDER BY @@ -339,7 +329,7 @@ CREATE INDEX test2_mm_idx ON test2 (major, minor); - 规划器在满足ORDER BY要求时,会考虑两种方案:扫描一个与该要求匹配的可用索引,或者按物理顺序扫描表再显式排序。对于需要扫描表中很大一部分内容的查询,显式排序通常会比使用索引更快,因为它遵循顺序访问模式,需要的磁盘 I/O 更少。只有在只需取出少量行时,索引才更有价值。一个重要的特例是ORDER BYLIMIT n组合使用:显式排序必须处理所有数据才能找出最前面的n行,而如果有一个与ORDER BY匹配的索引,就可以直接取回前n行,而完全不必扫描剩余数据。 + 规划器在满足ORDER BY要求时,会考虑两种方案:扫描一个与该要求匹配的可用索引,或者按物理顺序扫描表再显式排序。对于需要扫描表中很大一部分内容的查询,显式排序通常会比使用索引更快,因为它遵循顺序访问模式,需要的磁盘 I/O 更少。只需取出少量行时,索引更有价值。一个重要的特例是ORDER BYLIMIT n组合使用:显式排序必须处理所有数据才能找出最前面的n行,而如果有一个与ORDER BY匹配的索引,就可以直接取回前n行,而完全不必扫描剩余数据。 @@ -369,12 +359,12 @@ CREATE INDEX test3_desc_index ON test3 (id DESC NULLS LAST); 组合多个索引 - index - combining multiple indexes + 索引 + 组合多个索引 - bitmap scan + 位图扫描 @@ -391,7 +381,7 @@ CREATE INDEX test3_desc_index ON test3 (id DESC NULLS LAST); - 除了最简单的应用之外,通常会有多种可能有用的索引组合,数据库开发者必须权衡决定提供哪些索引。有时多列索引最好,但有时创建独立索引并依赖索引组合功能会更合适。例如,如果你的工作负载包含一组查询:有时只涉及列x,有时只涉及列y,有时同时涉及两列,那么你可以选择分别在xy上创建两个独立索引,并依赖索引组合来处理同时使用两列的查询。你也可以创建一个(x, y)上的多列索引。对于同时涉及两列的查询,这个索引通常会比索引组合更高效,但正如中所讨论的,它对于只涉及y的查询就没那么有用了。具体能有多大用处,取决于 B-树索引跳过扫描优化的效果;如果x的非重复值不超过几百个,跳过扫描会让针对特定y值的搜索仍然具有相当不错的效率。再加上一个(x, y)上的多列索引和一个单独的y索引,也可能工作得相当好。对于只涉及x的查询,多列索引也可以使用,但它会比单独的x索引更大,因此更慢。最后一种选择是同时创建这三个索引,但这大概只有在该表被搜索的频率远高于被更新的频率,并且三类查询都很常见时才合理。如果其中一种查询远没有另外两种常见,那么你大概只需创建最适合常见查询类型的两个索引即可。 + 除了最简单的应用之外,通常会有多种可能有用的索引组合,数据库开发者必须权衡决定提供哪些索引。有时多列索引最好,但有时创建独立索引并依赖索引组合功能会更合适。例如,如果你的工作负载包含一组查询:有时只涉及列x,有时只涉及列y,有时同时涉及两列,那么你可以选择分别在xy上创建两个独立索引,并依赖索引组合来处理同时使用两列的查询。你也可以创建一个(x, y)上的多列索引。对于同时涉及两列的查询,这个索引通常会比索引组合更高效,但正如中所讨论的,它对于只涉及y的查询几乎没有用处,因此不应只创建这一个索引。将这个多列索引与一个单独的y索引组合起来,能够取得相当好的效果。对于只涉及x的查询,多列索引也可以使用,但它会比单独的x索引更大,因此更慢。最后一种选择是同时创建这三个索引,但这大概只有在该表被搜索的频率远高于被更新的频率,并且三类查询都很常见时才合理。如果其中一种查询远没有另外两种常见,那么你大概只需创建最适合常见查询类型的两个索引即可。 @@ -401,8 +391,8 @@ CREATE INDEX test3_desc_index ON test3 (id DESC NULLS LAST); 唯一索引 - index - unique + 索引 + 唯一 @@ -433,8 +423,8 @@ CREATE UNIQUE INDEX name ON table表达式索引 - index - on expressions + 索引 + 基于表达式 @@ -481,8 +471,8 @@ CREATE INDEX people_names ON people ((first_name || ' ' || last_name)); 部分索引 - index - partial + 索引 + 部分 @@ -490,7 +480,7 @@ CREATE INDEX people_names ON people ((first_name || ' ' || last_name)); - 使用部分索引的一个主要原因是避免索引常见值。由于搜索常见值的查询(即占全部表行百分之几以上的值)反正也不会使用索引,因此完全没有必要把这些行保留在索引里。这会减小索引尺寸,从而加快那些确实会使用该索引的查询。它也会加快很多表更新操作,因为索引并不需要在所有情况下都更新。展示了这种思路的一种可能应用。 + 使用部分索引的一个主要原因是避免索引常见值。由于搜索常见值(即占全部表行百分之几以上的值)的查询反正也不会使用索引,因此完全没有必要把这些行保留在索引里。这会减小索引尺寸,从而加快那些确实会使用该索引的查询。它也会加快很多表更新操作,因为索引并不需要在所有情况下都更新。展示了这种思路的一种可能应用。 @@ -578,7 +568,7 @@ SELECT * FROM orders WHERE order_nr = 3501; - 也说明了:索引列和谓词中使用的列不必一致。PostgreSQL支持带任意谓词的部分索引,只要其中只涉及正在建立索引的那张表的列。不过要记住,谓词必须与那些希望从该索引受益的查询中使用的条件相匹配。更准确地说,只有当系统能够识别出查询的WHERE条件在数学上蕴含该索引的谓词时,部分索引才能用于该查询。PostgreSQL并没有一个复杂的定理证明器,来识别那些写法不同但数学上等价的表达式。(不仅构建这样一个通用定理证明器极其困难,而且它很可能也会慢到失去实际用途。)系统可以识别简单的不等式蕴含,例如x < 1蕴含x < 2;否则,谓词条件必须与查询WHERE条件的某一部分完全匹配,否则索引不会被识别为可用。匹配发生在查询规划阶段,而不是运行时。因此,参数化查询子句无法与部分索引配合工作。例如,一个带参数的预备查询可能写成x < ?,而对于参数的所有可能取值,它都不可能蕴含x < 2。 + 也说明了:索引列和谓词中使用的列不必一致。PostgreSQL支持带任意谓词的部分索引,只要其中只涉及正在建立索引的那张表的列。不过要记住,谓词必须与那些希望从该索引受益的查询中使用的条件相匹配。更准确地说,只有当系统能够识别出查询的WHERE条件在数学上蕴含该索引的谓词时,部分索引才能用于该查询。PostgreSQL并没有一个复杂的定理证明器,来识别那些写法不同但数学上等价的表达式。(不仅构建这样一个通用定理证明器极其困难,而且它很可能也会慢到失去实际用途。)系统可以识别简单的不等式蕴含,例如x < 1蕴含x < 2;否则,谓词条件必须与查询WHERE条件的某一部分完全匹配,否则索引不会被识别为可用。匹配发生在查询规划阶段,而不是运行时。因此,参数化查询子句无法与部分索引配合工作。例如,一个带参数的预备查询可能写成x < ?,而它无法保证在参数的所有可能取值下都蕴含x < 2 @@ -590,7 +580,7 @@ SELECT * FROM orders WHERE order_nr = 3501; 建立一个部分唯一索引 - 假设我们有一张描述测试结果的表。我们希望确保对于给定的subjecttarget组合,只有一条成功记录,但可以有任意多条失败记录。实现方法之一如下: + 假设我们有一张描述测试结果的表。我们希望确保对于给定的测试对象和目标组合,只有一条成功记录,但可以有任意多条失败记录。实现方法之一如下: CREATE TABLE tests ( subject text, @@ -671,7 +661,7 @@ CREATE INDEX mytable_cat_data ON mytable (category, data); - PostgreSQL中的所有索引都是二级索引,也就是说,每个索引都与表的主数据区分开存储(在PostgreSQL术语中,这个主数据区称为表的)。这意味着,在普通索引扫描中,每次取回一行都需要同时从索引和堆中取数据。此外,尽管满足某个可索引WHERE条件的索引项通常在索引中彼此接近,但它们引用的表行却可能分布在堆中的任何位置。因此,索引扫描的堆访问部分会涉及大量对堆的随机访问,这可能很慢,尤其是在传统旋转介质上。(正如中所述,位图扫描试图通过按排序顺序进行堆访问来缓解这项成本,但那也只能缓解到一定程度。) + PostgreSQL中的所有索引都是二级索引,也就是说,每个索引都与表的主数据区分开存储(在PostgreSQL术语中,这个主数据区称为表的)。这意味着,在普通索引扫描中,每次取回一行都需要同时从索引和堆中取数据。此外,尽管满足某个可索引WHERE条件的索引项通常在索引中彼此接近,但它们引用的表行却可能分布在堆中的任何位置。因此,索引扫描的堆访问部分会涉及大量对堆的随机访问,这可能很慢,尤其是在传统旋转介质上。(正如中所述,位图扫描试图通过按排序顺序进行堆访问来缓解这项代价,但那也只能缓解到一定程度。) @@ -686,7 +676,7 @@ CREATE INDEX mytable_cat_data ON mytable (category, data); - 查询只能引用存储在索引中的列。例如,给定一个表,它有列xyz,而索引建立在xy上,那么下面这些查询可以使用仅索引扫描: + 查询只能引用存储在索引中的列。例如,假设某个表的xy列上有一个索引,且该表还有一列z,那么下面这些查询可以使用仅索引扫描: SELECT x, y FROM tab WHERE x = 'key'; SELECT x FROM tab WHERE x = 'key' AND y < 42; @@ -713,7 +703,7 @@ SELECT x FROM tab WHERE x = 'key' AND z < 42; INCLUDE - in index definitions + 在索引定义中 为了有效利用仅索引扫描特性,你可以选择创建一个覆盖索引,也就是专门设计来包含某一类高频查询所需列的索引。由于查询通常需要取回的列不止是用于搜索的那些列,PostgreSQL允许你创建一种索引,其中某些列只是负载,而不是搜索键的一部分。这是通过添加一个INCLUDE子句列出这些额外列来实现的。例如,如果你经常运行如下查询: @@ -735,7 +725,7 @@ CREATE UNIQUE INDEX tab_x_y ON tab(x) INCLUDE (y); - 向索引中添加非键负载列时,明智的做法是保持保守,尤其是宽列。如果某个索引元组超过该索引类型允许的最大尺寸,数据插入就会失败。无论如何,非键列都会复制索引对应表中的数据并让索引膨胀,因此可能拖慢搜索。另外请记住,除非表变化足够缓慢,以至于仅索引扫描很可能无需访问堆,否则把负载列包含在索引中并没有太大意义。如果反正必须访问堆元组,那么顺便从那里取出该列的值也不会增加额外成本。其他限制包括:当前不支持把表达式作为包含列;并且当前只有 B-树、GiST 和 SP-GiST 索引支持包含列。 + 向索引中添加非键负载列时,明智的做法是保持保守,尤其是宽列。如果某个索引元组超过该索引类型允许的最大尺寸,数据插入就会失败。无论如何,非键列都会复制索引对应表中的数据并让索引膨胀,因此可能拖慢搜索。另外请记住,除非表变化足够缓慢,以至于仅索引扫描很可能无需访问堆,否则把负载列包含在索引中并没有太大意义。如果反正必须访问堆元组,那么顺便从那里取出该列的值也不会增加额外代价。其他限制包括:当前不支持把表达式作为包含列;并且当前只有 B-树、GiST 和 SP-GiST 索引支持包含列。 @@ -781,11 +771,11 @@ SELECT target FROM tests WHERE subject = 'some-subject' AND success; 操作符类和操作符族 - operator class + 操作符类 - operator family + 操作符族 @@ -903,8 +893,8 @@ CREATE INDEX test1c_content_y_index ON test1c (content COLLATE "y"); 检查索引使用情况 - index - examining usage + 索引 + 检查使用情况 diff --git a/zh/16/information_schema.sgml b/zh/16/information_schema.sgml index 1e149423..57292dca 100644 --- a/zh/16/information_schema.sgml +++ b/zh/16/information_schema.sgml @@ -388,7 +388,7 @@ collation_catalog sql_identifier - 包含此属性排序规则的数据库名(总是当前数据库),如果默认或者该属性的数据类型不可排序则为空 + 包含该属性排序规则的数据库名称(总是当前数据库);如果使用默认排序规则,或该属性的数据类型不支持排序规则,则为 null。 @@ -397,7 +397,7 @@ collation_schema sql_identifier - 包含此属性排序规则的模式名,如果默认或者该属性的数据类型不可排序则为空 + 包含该属性排序规则的模式名称;如果使用默认排序规则,或该属性的数据类型不支持排序规则,则为 null。 @@ -406,7 +406,7 @@ collation_name sql_identifier - 该属性排序规则的名称,如果默认或者该属性的数据类型不可排序则为空 + 该属性排序规则的名称;如果使用默认排序规则,或该属性的数据类型不支持排序规则,则为 null。 @@ -1626,7 +1626,7 @@ collation_catalog sql_identifier - 包含此属性排序规则的数据库名(总是当前数据库),如果默认或者该属性的数据类型不可排序则为空 + 包含该列排序规则的数据库名称(总是当前数据库);如果使用默认排序规则,或该列的数据类型不支持排序规则,则为 null。 @@ -1635,7 +1635,7 @@ collation_schema sql_identifier - 该列的包含排序规则的模式名,如果默认或者该列的数据类型不可排序则为空 + 包含该列排序规则的模式名称;如果使用默认排序规则,或该列的数据类型不支持排序规则,则为 null。 @@ -1644,7 +1644,7 @@ collation_name sql_identifier - 该列的排序规则的名称,如果默认或者该列的数据类型不可排序则为空 + 该列排序规则的名称;如果使用默认排序规则,或该列的数据类型不支持排序规则,则为 null。 @@ -2385,7 +2385,7 @@ collation_catalog sql_identifier - 包含此域排序规则的数据库名(总是当前数据库),如果默认或者该域的数据类型不可排序则为空 + 包含该域排序规则的数据库名称(总是当前数据库);如果使用默认排序规则,或该域的数据类型不支持排序规则,则为 null。 @@ -2394,7 +2394,7 @@ collation_schema sql_identifier - 包含此域排序规则的模式名,如果默认或者该域的数据类型不可排序则为空 + 包含该域排序规则的模式名称;如果使用默认排序规则,或该域的数据类型不支持排序规则,则为 null。 @@ -2403,7 +2403,7 @@ collation_name sql_identifier - 该域排序规则的名称,如果默认或者该域的数据类型不可排序则为空 + 该域排序规则的名称;如果使用默认排序规则,或该域的数据类型不支持排序规则,则为 null。 @@ -2558,7 +2558,7 @@ <literal>element_types</literal> - 视图element_types包含数组元素的数据类型描述符。当一个表列、复合类型属性、域、函数参数或函数返回值被定义为一种数组类型,相应的信息模式视图只在列data_type中包含ARRAY。要获得该数组元素类型的信息,你可以连接该相应的视图和这个视图。例如,要显示一个表的列及其数据类型和数组元素类型,你可以: + 视图element_types包含数组元素的数据类型描述符。当一个表列、复合类型属性、域、函数参数或函数返回值被定义为一种数组类型时,相应的信息模式视图只在列data_type中包含ARRAY。要获得该数组元素类型的信息,你可以连接该相应的视图和这个视图。例如,要显示一个表的列及其数据类型和数组元素类型(如果适用),你可以: SELECT c.column_name, c.data_type, e.data_type AS element_type FROM information_schema.columns c LEFT JOIN information_schema.element_types e @@ -2689,7 +2689,7 @@ ORDER BY c.ordinal_position; collation_catalog sql_identifier - 包含元素类型排序规则的数据库名称(总是当前数据库), 如果默认或该元素的数据类型是不可排序的则为空 + 包含该元素类型排序规则的数据库名称(总是当前数据库);如果使用默认排序规则,或该元素类型不支持排序规则,则为 null。 @@ -2698,7 +2698,7 @@ ORDER BY c.ordinal_position; collation_schema sql_identifier - 包含元素类型排序规则的模式名称, 如果默认或该元素的数据类型是不可排序的则为空 + 包含该元素类型排序规则的模式名称;如果使用默认排序规则,或该元素类型不支持排序规则,则为 null。 @@ -2707,7 +2707,7 @@ ORDER BY c.ordinal_position; collation_name sql_identifier - 元素类型的排序规则名, 如果默认或该元素的数据类型是不可排序的则为空 + 该元素类型排序规则的名称;如果使用默认排序规则,或该元素类型不支持排序规则,则为 null。 @@ -2765,6 +2765,15 @@ ORDER BY c.ordinal_position; + + + domain_default character_data + + + 尚未实现 + + + udt_catalog sql_identifier @@ -6291,7 +6300,7 @@ ORDER BY c.ordinal_position; enforced yes_or_no - 如果该约束被强制执行,则为YES,否则为NO + 适用于PostgreSQL尚不提供的功能(当前总是YES @@ -7145,7 +7154,7 @@ ORDER BY c.ordinal_position; - SQL 了解两种用户定义类型:结构类型(在PostgreSQL中也称为复合类型)以及 distinct type(PostgreSQL 尚未实现)。为兼顾将来,请使用列user_defined_type_category来区分它们。其他用户定义类型,如基类型和枚举(两者都是PostgreSQL的扩展),不会在这里显示。域的相关信息见。 + SQL 中有两种用户定义类型:结构类型(在PostgreSQL中也称为复合类型)以及独立类型(distinct type,PostgreSQL 尚未实现)。为兼顾将来,请使用列user_defined_type_category来区分它们。其他用户定义类型,如基础类型和枚举(两者都是PostgreSQL的扩展),不会在这里显示。域的相关信息见 @@ -7877,7 +7886,7 @@ ORDER BY c.ordinal_position; check_optioncharacter_data - CASCADEDLOCAL 如果视图上有CHECK OPTION 定义,如果没有则为NONE。 + CASCADEDLOCAL 如果视图上有CHECK OPTION 定义,如果没有则为NONE diff --git a/zh/16/install-windows.sgml b/zh/16/install-windows.sgml index 3a656da7..c4d5e9ec 100644 --- a/zh/16/install-windows.sgml +++ b/zh/16/install-windows.sgml @@ -4,8 +4,8 @@ 在 <productname>Windows</productname> 上从源代码安装 - installation - on Windows + 安装 + 在 Windows 上 @@ -114,8 +114,7 @@ $ENV{MSBFLAGS}="/m"; - Bison and - Flex + BisonFlex 从 Git 构建需要BisonFlex,但从发布文件构建则不需要。只有 2.3 及以上版本的Bison可以工作。Flex必须为 2.5.35 或更高版本。 @@ -160,8 +159,7 @@ $ENV{MSBFLAGS}="/m"; - libxml2 and - libxslt + libxml2libxslt XML 支持需要它们。二进制文件可从下载,源代码可从获取。请注意,libxml2 需要 iconv,而它可从相同的下载位置获得。 @@ -347,7 +345,7 @@ $ENV{PROVE_TESTS}='t/020*.pl t/010*.pl' - 某些 TAP 测试依赖一组外部命令,这些命令会选择性触发与其相关的测试。每个这样的变量都可以在buildenv.pl中设置或取消设置: + 部分 TAP 测试依赖一些外部命令,相关测试会根据这些命令是否可用而选择性触发。以下各变量都可以在 buildenv.pl 中设置或取消设置: GZIP_PROGRAM diff --git a/zh/16/installation.sgml b/zh/16/installation.sgml index 7f75ecb4..6f682947 100644 --- a/zh/16/installation.sgml +++ b/zh/16/installation.sgml @@ -1,12 +1,21 @@ + 从源代码安装 - installation + 安装 + 本章介绍如何使用源代码发布包安装 PostgreSQL。如果你安装的是预打包的发行版, @@ -14,6 +23,8 @@ + 如果你要为 Microsoft Windows 构建 PostgreSQL,并打算使用 MinGW 或 Cygwin,请阅读本章;但如果打算使用 Microsoft 的 Visual C++,请改为参见 + 需求 @@ -47,19 +58,9 @@ - - + Meson - - - 另一种方式是使用 Meson - 构建 PostgreSQL。这是在 Windows 上通过 - Visual Studio 构建 - PostgreSQL 的唯一方法。对于其他平台, - 使用 Meson 目前仍属于实验性功能。如果你选择使用 - Meson,则不需要 GNU - make,但下面列出的其他要求仍然适用。 - + 另一种方式是使用 Meson 构建 PostgreSQL。这目前仍属于实验性功能,并且只能从 Git 检出构建(不能使用发布的 tar 包)。如果你选择使用 Meson,则不需要 GNU make,但下面列出的其他要求仍然适用。 Meson 的最低要求版本是 0.54。 @@ -83,40 +84,6 @@ - - - - flex - - - lex - - - bison - - - yacc - - - 需要 FlexBison。 - 不能使用其他 lex 和 - yacc 程序。 - Bison 至少需要 2.3 版本。 - - - - - - - perl - - - 在构建过程中以及运行某些测试套件时,需要 Perl - 5.14 或更高版本。(这一要求与构建 PL/Perl - 的要求是分开的;见下文。) - - - @@ -224,8 +191,8 @@ 要构建 PL/Python 服务器端编程语言, 你需要带有头文件以及 sysconfig 模块的 - Python 安装。最低支持版本是 - Python 3.6.8。 + Python 安装。最低要求版本是 + Python 3.2。 @@ -273,12 +240,7 @@ 如果你希望支持加密的客户端连接,就需要 OpenSSL。 在没有 /dev/urandom 的平台上(Windows 除外), 生成随机数也需要 OpenSSL。 - 最低要求版本是 1.1.1。 - - - 此外,也支持通过 OpenSSL 兼容层使用 - LibreSSL。最低要求版本是 3.4 - (来自 OpenBSD 7.0)。 + 最低要求版本是 1.0.1。 @@ -290,14 +252,6 @@ - - - 你需要 Curl 来构建一个可选模块, - 该模块为客户端应用实现了 - OAuth 设备授权流程。 - - - 如果你希望支持用该方法压缩数据,就需要 LZ4; @@ -323,6 +277,26 @@ + 如果你从 Git 树构建,而不是使用已发布的源码包,或者你要进行服务器开发,还需要以下软件包: + + + flex + + lex + + bison + + yacc + 从 Git 检出构建,或者修改了扫描器和解析器的实际定义文件时,需要 FlexBison。如果需要它们,请确保使用 Flex 2.5.35 或更高版本,以及 Bison 2.3 或更高版本。不能使用其他 lexyacc 程序。 + + + + perl + 从 Git 检出构建,或者修改了使用 Perl 脚本的任何构建步骤的输入文件时,需要 Perl 5.14 或更高版本。在 Windows 上构建时,无论如何都需要 Perl。运行某些测试套件也需要 Perl + + + + 如果你需要获取 GNU 软件包,可以从本地的 GNU 镜像站点获取(站点列表见 @@ -362,7 +336,7 @@ 使用 Autoconf 和 Make 进行构建和安装 - 简短版本 + 简要说明 @@ -379,7 +353,7 @@ su - postgres /usr/local/pgsql/bin/createdb test /usr/local/pgsql/bin/psql test - 较长版本见本其余部分。 + 详细说明见本的其余部分。 @@ -607,7 +581,7 @@ build-postgresql: <filename>configure</filename> 选项 - 配置选项 + configure 选项 @@ -857,19 +831,9 @@ build-postgresql: + 构建时支持基于 LLVMJIT 编译(见 。这要求已安装 LLVM 库。当前 LLVM 的最低要求版本是 3.9。 - 构建时支持基于 LLVM 的 - JIT 编译(见 )。 - 这要求已安装 LLVM 库。 - 当前 LLVM 的最低要求版本是 14。 - - - llvm-configllvm-config - 将用于查找所需的编译选项。系统会在你的 PATH 中搜索 - llvm-config。如果这样找不到你想要的程序,请使用 - LLVM_CONFIG 指定正确的 llvm-config - 路径。例如: - + llvm-configllvm-config 用于查找所需的编译选项。首先查找 llvm-config,然后查找 llvm-config-$major-$minor(遍历所有受支持版本),搜索位置为 PATH。如果这样无法找到所需程序,请使用 LLVM_CONFIG 指定正确程序的路径,即 llvm-config。例如: ./configure ... --with-llvm LLVM_CONFIG='/path/to/llvm/bin/llvm-config' @@ -911,10 +875,8 @@ build-postgresql: 构建时支持 SSL(加密)连接。 - 唯一支持的 LIBRARY, - 它同时适用于 OpenSSL 和 - LibreSSL。这要求安装 - OpenSSL 软件包。 + 唯一支持的 LIBRARY。 + 这要求安装 OpenSSL 软件包。 configure 会检查所需的头文件和库, 以确认你的 OpenSSL 安装足够后才继续。 @@ -989,7 +951,7 @@ build-postgresql: 构建时支持 systemdsystemd 服务通知。如果服务器是在 systemd 下启动, - 这会改进集成;否则没有影响。更多信息见 。 + 这会改进集成;否则没有影响。更多信息见 要使用此选项,需要安装 libsystemd 及其相关头文件。 @@ -1031,7 +993,7 @@ build-postgresql: ,使用 OSSP UUID library + url="http://www.ossp.org/pkg/lib/uuid/">OSSP UUID 库 @@ -1047,45 +1009,6 @@ build-postgresql: - - - - - 构建时支持 libcurl,用于 OAuth 2.0 客户端流程。 - 此特性要求 libcurl 7.61.0 或更高版本。 - 使用该选项构建时,会检查所需的头文件和库,以确认你的 - curl 安装足够后才继续。 - - - - - - - - - 构建时支持 libnuma,用于基础 NUMA 支持。 - 仅在实现了 libnuma 库的平台上受支持。 - - - - - - - - - 构建时支持 liburing,以启用异步 I/O 的 io_uring 支持。 - - - 为了检测所需的编译器和链接器选项,PostgreSQL 会查询 - pkg-config。 - - - 如果 liburing 安装在不常见的位置,你可以设置与 - pkg-config 相关的环境变量(见其文档)。 - - - - @@ -1094,13 +1017,7 @@ build-postgresql: 这一特性要求 libxml2 2.6.23 或更高版本。 - - 为了检测所需的编译器和链接器选项,如果系统已安装 - pkg-config 且知道 libxml2,PostgreSQL - 会查询 pkg-config。否则,如果找得到由 libxml2 - 安装的 xml2-config 程序,就会使用它。 - 优先使用 pkg-config,因为它能更好地处理多架构安装。 - + 为检测所需的编译器和链接器选项,PostgreSQL 会查询 pkg-config,前提是已安装该程序且其中有 libxml2 的信息。否则,如果找到 libxml2 安装的 xml2-config 程序,就会使用它。优先使用 pkg-config,因为它能更好地处理多架构安装。 如果 libxml2 安装在不常见的位置,你可以设置与 @@ -1128,21 +1045,12 @@ build-postgresql: - - - - - 构建时支持 SElinux,以启用 扩展。 - - - - - 反功能 + 禁用特性 本节描述的选项允许禁用某些默认会构建的 @@ -1158,8 +1066,7 @@ build-postgresql: 构建时不支持 ICUICU - 库,从而禁用 ICU 排序规则特性(见 )。 + 库,从而禁用 ICU 排序规则特性(见 @@ -1201,6 +1108,27 @@ build-postgresql: + + + + 即使 PostgreSQL 不支持该平台的 CPU 自旋锁,也允许构建成功。缺少自旋锁支持会导致性能极差;因此,仅应在构建中止并告知平台缺少自旋锁支持时使用此选项。如果在你的平台上构建 PostgreSQL 必须使用此选项,请向 PostgreSQL 开发者报告该问题。 + + + + + + + 禁用 CPU 原子操作。在不支持此类操作的平台上,此选项不产生影响。在支持的平台上,它会导致性能下降。此选项仅用于调试或性能比较。 + + + + + + + 禁用客户端库的线程安全性。这会使 libpqECPG 程序中的并发线程无法安全地控制各自私有的连接句柄。仅在缺乏完善线程支持的平台上使用此选项。 + + + @@ -1287,8 +1215,7 @@ build-postgresql: - 不在 PostgreSQL 的可执行文件中标记, - 使其在运行时到安装的库目录中搜索共享库(见 )。 + 不在 PostgreSQL 的可执行文件中添加指示其到安装的库目录中搜索共享库的标记(见 )。 在大多数平台上,这种标记使用库目录的绝对路径,因此如果你之后移动安装位置, 它就没有帮助了。不过这样一来,你就需要通过其他方式让可执行文件找到共享库。 通常这要求配置操作系统的动态链接器搜索该库目录;更多细节见 @@ -1305,7 +1232,7 @@ build-postgresql: 杂项 - 调整默认端口号 相当常见, + 使用 调整默认端口号相当常见, 尤其是在测试性构建中。本节中的其他选项只推荐给高级用户。 @@ -1340,10 +1267,10 @@ build-postgresql: - 设置 segment size,单位为 GB。 + 设置 段大小,单位为 GB。 大表会被分成多个操作系统文件,每个文件的大小等于段大小。 这可以避免很多平台上的文件大小限制问题。默认段大小 1GB 在所有支持的平台上 - 都是安全的。如果你的操作系统支持 largefile + 都是安全的。如果你的操作系统支持 大文件 (如今大多数都支持),你可以使用更大的段大小。 这有助于减少处理超大表时消耗的文件描述符数量。 但请注意不要选择超出你的平台和打算使用的文件系统所支持的值。 @@ -1359,7 +1286,7 @@ build-postgresql: - 设置 block size,单位为 KB。 + 设置 块大小,单位为 KB。 这是表内部存储和 I/O 的单位。默认值 8KB 适合大多数场景, 但在特殊情况下,其他取值也可能有用。 该值必须是 1 到 32(KB)之间的 2 的幂。 @@ -1373,7 +1300,7 @@ build-postgresql: - 设置 WAL block size,单位为 KB。 + 设置 WAL 块大小,单位为 KB。 这是 WAL 日志内部存储和 I/O 的单位。默认值 8KB 适合大多数场景, 但在特殊情况下,其他取值也可能有用。 该值必须是 1 到 64(KB)之间的 2 的幂。 @@ -1423,11 +1350,11 @@ build-postgresql: - 在服务器中启用 assertion 检查,用于测试许多 - 不应该发生的条件。这对代码开发非常有价值,但这些测试会显著拖慢 + 在服务器中启用 断言 检查,用于测试许多 + 不可能发生的条件。这对代码开发非常有价值,但这些测试可能会显著拖慢 服务器速度。此外,启用这些测试并不一定会增强服务器稳定性! 断言检查并未按严重程度分类,因此即使某个 bug 相对无害,只要触发了断言失败, - 仍可能导致服务器重启。该选项不建议用于生产环境,但如果你在做开发工作 + 仍会导致服务器重启。该选项不建议用于生产环境,但如果你在做开发工作 或运行测试版,就应当启用它。 @@ -1438,7 +1365,7 @@ build-postgresql: 启用使用 Perl TAP 工具的测试。这要求安装 Perl 以及 Perl 模块 - IPC::Run。更多信息见 。 + IPC::Run更多信息见 @@ -1461,7 +1388,7 @@ build-postgresql: 如果使用 GCC,所有程序和库都会带代码覆盖率测试插桩进行编译。 运行时,它们会在构建目录中生成包含代码覆盖率指标的文件。 - 更多信息见 。 + 更多信息见 该选项只适用于 GCC,并且仅在开发工作中使用。 @@ -1472,7 +1399,7 @@ build-postgresql: 如果使用 GCC,所有程序和库都会被编译成可进行性能分析的形式。 - 后端退出时,会创建一个子目录,其中包含带有 profile 数据的 + 后端退出时,会创建一个子目录,其中包含带有性能分析数据的 gmon.out 文件。 该选项只适用于 GCC,并且仅在开发工作中使用。 @@ -1487,7 +1414,7 @@ build-postgresql: DTracePostgreSQL 编译为支持动态跟踪工具 DTrace。 - 更多信息见 。 + 更多信息见 @@ -1513,18 +1440,6 @@ build-postgresql: - - - - - 将 PostgreSQL 编译为支持服务器中的注入点。 - 注入点允许在预定义的代码路径中,从服务器内部运行用户定义的代码。 - 这有助于以受控方式测试并研究并发场景。该选项默认关闭。 - 该选项仅供开发人员测试使用。 - - - - @@ -1547,7 +1462,7 @@ build-postgresql: <filename>configure</filename> 环境变量 - configure environment variables + configure 环境变量 @@ -1614,7 +1529,7 @@ build-postgresql: 在使用 --with-llvm 编译时, - 用于处理源代码以内联的 clang 程序路径 + 用于处理源代码以进行内联的 clang 程序路径 @@ -1772,21 +1687,9 @@ build-postgresql: - - 有时,在事后把额外的编译器标志加入到 - configure 选定的那组选项中会很有用。 - 一个重要例子是,gcc - 不能包含在传给 configureCFLAGS 中, - 因为这会破坏 configure 的很多内置测试。 - 要添加这类标志,请在运行 make 时把它们放入环境变量 - COPTCOPT 的内容会被附加到 - configure 设置好的 CFLAGS、 - CXXFLAGSLDFLAGS 上。例如,你可以这样做: - + 有时,事后补充编译器标志会很有用;原有标志由 configure 选定。一个重要的例子是 gcc 选项不能包含在以下变量中:CFLAGS(该变量会传给 configure),因为它会破坏 configure 的许多内置测试。要添加此类标志,请将其放入 COPT 环境变量,再运行 makeCOPT 的内容会被加入以下两组选项:CFLAGSLDFLAGS;这两组选项原本由以下程序设置:configure。例如,你可以执行: make COPT='-Werror' - - 或者: - +或者: export COPT='-Werror' make @@ -1818,7 +1721,7 @@ build-postgresql: 使用 Meson 构建和安装 - 简短版本 + 简要说明 @@ -1836,7 +1739,7 @@ su - postgres /usr/local/pgsql/bin/createdb test /usr/local/pgsql/bin/psql test - 较长版本见本其余部分。 + 详细说明见本的其余部分。 @@ -2210,8 +2113,7 @@ ninja install 构建时支持 ICUICU - 库,从而启用 ICU 排序规则特性(见 )。默认值是 auto,并且要求安装 + 库,从而启用 ICU 排序规则特性(见 。默认值是 auto,并且要求安装 ICU4C 软件包。当前 ICU4C 的最低要求版本是 4.2。 @@ -2221,13 +2123,7 @@ ninja install - - 构建时支持基于 LLVM 的 - JIT 编译(见 )。 - 这要求已安装 LLVM 库。 - 当前 LLVM 的最低要求版本是 14。 - 默认禁用。 - + 构建时支持基于 LLVMJIT 编译(见 。这要求已安装 LLVM 库。当前 LLVM 的最低要求版本是 3.9。默认禁用。 llvm-configllvm-config @@ -2336,14 +2232,13 @@ ninja install - 构建时支持 - systemdsystemd - 服务通知。如果服务器是在 systemd 下启动, - 这会改进集成;否则没有影响。更多信息见 - 。默认值是 auto。 - 要使用此选项,需要安装 libsystemd - 及其相关头文件。 - + 构建时支持 + systemdsystemd + 服务通知。如果服务器是在 systemd 下启动, + 这会改进集成;否则没有影响。更多信息见 + 默认值是 auto。要使用此选项,需要安装 libsystemd + 及其相关头文件。 + @@ -2361,11 +2256,11 @@ ninja install - 构建 模块 - (它提供生成 UUID 的函数),并使用指定的 UUID 库。 - UUID - LIBRARY 必须是以下之一: - + 构建 模块 + (它提供生成 UUID 的函数),并使用指定的 UUID 库。 + UUID + LIBRARY 必须是以下之一: + @@ -2373,65 +2268,26 @@ ninja install - - ,使用 FreeBSD 以及其他某些 BSD 衍生系统中的 UUID 函数 - - + + ,使用 FreeBSD 以及其他某些 BSD 衍生系统中的 UUID 函数 + + - - ,使用 e2fsprogs 项目创建的 UUID 库; - 该库存在于大多数 Linux 系统和 macOS 中,也可用于其他平台 - - + + ,使用 e2fsprogs 项目创建的 UUID 库; + 该库存在于大多数 Linux 系统和 macOS 中,也可用于其他平台 + + - ,使用 OSSP UUID library - + ,使用 OSSP UUID 库 + - - - - - 构建时支持 libcurl,用于 OAuth 2.0 客户端流程。 - 此特性要求 libcurl 7.61.0 或更高版本。 - 使用该选项构建时,会检查所需的头文件和库,以确认你的 - Curl 安装足够后才继续。 - 该选项的默认值是 auto。 - - - - - - - - - 构建时支持 liburing,以启用异步 I/O 的 io_uring 支持。 - 默认值是 auto。 - - - - 如果 liburing 安装在不常见的位置,你可以设置与 - pkg-config 相关的环境变量(见其文档)。 - - - - - - - - - 构建时支持 libnuma,用于基础 NUMA 支持。 - 仅在实现了 libnuma 库的平台上受支持。 - 该选项的默认值是 auto。 - - - - @@ -2459,22 +2315,11 @@ ninja install - - - - - - 构建时支持 SElinux,以启用 扩展。 - 默认值是 auto。 - - - - - 反功能 + 禁用特性 @@ -2517,6 +2362,23 @@ ninja install + + + + + 该选项默认值是 true;将其设为 false 时,即使 PostgreSQL 不支持该平台的 CPU 自旋锁,也允许构建成功。缺乏自旋锁支持会导致非常差的性能;因此,只有在构建中止并提示该平台缺少自旋锁支持时,才应修改此选项。如果在你的平台上构建 PostgreSQL 需要把该选项设为 false,请向 PostgreSQL 开发者报告该问题。 + + + + + + + + + 该选项默认值是 true;将其设为 false 会禁用 CPU 原子操作的使用。对于缺乏此类操作的平台,该选项不起作用。对于具备此类操作的平台,禁用原子操作会导致性能很差。修改此选项仅对调试或进行性能比较有用。 + + + @@ -2530,7 +2392,7 @@ ninja install 设置这个选项,可以覆盖所有 auto 特性的取值 (也就是那些在找到所需软件时会自动启用的特性)。 - 当你想一次性禁用或启用所有 optional 特性, + 当你想一次性禁用或启用所有 可选 特性, 而不必逐个手工设置时,这会很有用。 该参数的默认值是 auto。 @@ -2543,7 +2405,7 @@ ninja install Meson 默认使用的后端是 ninja,这对大多数用例已经足够。 不过,如果你希望与 Visual Studio 完全集成,可以把 - BACKEND 设为 vs。 + 设为 vs @@ -2646,9 +2508,8 @@ ninja install - 该选项默认值是 true。如果设为 false,则不会在 - PostgreSQL 的可执行文件中标记, - 使其在运行时到安装的库目录中搜索共享库(见 )。 + 该选项默认值是 true。如果设为 false,则不在 + PostgreSQL 的可执行文件中添加指示其到安装的库目录中搜索共享库的标记(见 )。 在大多数平台上,这种标记使用库目录的绝对路径,因此如果你之后移动安装位置, 它就没有帮助了。不过这样一来,你就需要通过其他方式让可执行文件找到共享库。 通常这要求配置操作系统的动态链接器搜索该库目录;更多细节见 @@ -2749,10 +2610,10 @@ ninja install - 设置 segment size,单位为 GB。 + 设置 段大小,单位为 GB。 大表会被分成多个操作系统文件,每个文件的大小等于段大小。 这可以避免很多平台上的文件大小限制问题。默认段大小 1GB 在所有支持的平台上 - 都是安全的。如果你的操作系统支持 largefile + 都是安全的。如果你的操作系统支持 大文件 (如今大多数都支持),你可以使用更大的段大小。 这有助于减少处理超大表时消耗的文件描述符数量。 但请注意不要选择超出你的平台和打算使用的文件系统所支持的值。 @@ -2766,7 +2627,7 @@ ninja install - 设置 block size,单位为 KB。 + 设置 块大小,单位为 KB。 这是表内部存储和 I/O 的单位。默认值 8KB 适合大多数场景, 但在特殊情况下,其他取值也可能有用。 该值必须是 1 到 32(KB)之间的 2 的幂。 @@ -2778,7 +2639,7 @@ ninja install - 设置 WAL block size,单位为 KB。 + 设置 WAL 块大小,单位为 KB。 这是 WAL 日志内部存储和 I/O 的单位。默认值 8KB 适合大多数场景, 但在特殊情况下,其他取值也可能有用。 该值必须是 1 到 64(KB)之间的 2 的幂。 @@ -2864,11 +2725,11 @@ ninja install - 在服务器中启用 assertion 检查,用于测试许多 - 不应该发生的条件。这对代码开发非常有价值,但这些测试会显著拖慢 + 在服务器中启用 断言 检查,用于测试许多 + 不可能发生的条件。这对代码开发非常有价值,但这些测试会显著拖慢 服务器速度。此外,启用这些测试并不一定会增强服务器稳定性! 断言检查并未按严重程度分类,因此即使某个 bug 相对无害,只要触发了断言失败, - 仍可能导致服务器重启。该选项不建议用于生产环境,但如果你在做开发工作 + 仍会导致服务器重启。该选项不建议用于生产环境,但如果你在做开发工作 或运行测试版,就应当启用它。 @@ -2879,8 +2740,7 @@ ninja install 启用使用 Perl TAP 工具的测试。默认值是 auto,并要求安装 Perl 以及 - Perl 模块 IPC::Run。更多信息见 - 。 + Perl 模块 IPC::Run更多信息见 @@ -2888,12 +2748,7 @@ ninja install - - 启用额外测试套件;这些测试默认不会运行,因为它们不适合在多用户系统上运行、 - 需要特殊软件,或者资源消耗较大。该参数是以空白分隔的测试名称列表。 - 详见 。如果在运行测试时设置了 - PG_TEST_EXTRA 环境变量,那么它会覆盖这个构建时选项。 - + 启用运行时需要特殊软件的测试套件。该选项通过以空白分隔的列表接受参数。详见 @@ -2901,11 +2756,11 @@ ninja install - 如果使用 GCC,所有程序和库都会带代码覆盖率测试插桩进行编译。 - 运行时,它们会在构建目录中生成包含代码覆盖率指标的文件。 - 更多信息见 。 - 该选项只适用于 GCC,并且仅在开发工作中使用。 - + 如果使用 GCC,所有程序和库都会带代码覆盖率测试插桩进行编译。 + 运行时,它们会在构建目录中生成包含代码覆盖率指标的文件。 + 更多信息见 + 该选项只适用于 GCC,并且仅在开发工作中使用。 + @@ -2914,10 +2769,10 @@ ninja install - DTrace - + DTrace + 启用该选项会将 PostgreSQL 编译为支持动态跟踪工具 - DTrace。更多信息见 。 + DTrace。更多信息见 @@ -2929,18 +2784,6 @@ ninja install - - - - - 将 PostgreSQL 编译为支持服务器中的注入点。 - 注入点允许在预定义的代码路径中,从服务器内部运行用户定义的代码。 - 这有助于以受控方式测试并研究并发场景。该选项默认关闭。 - 该选项仅供开发人员测试使用。 - - - - @@ -2956,7 +2799,6 @@ ninja install - @@ -3111,16 +2953,12 @@ export MANPATH 成员机器,以便持续确保兼容性。 - - 一般来说,可以预期 PostgreSQL 能在以下 CPU - 架构上工作:x86、PowerPC、S/390、SPARC、ARM、MIPS 和 RISC-V, - 以及在适用情况下的大端、小端、32 位和 64 位变体。 - + 一般来说,可以预期 PostgreSQL 能在以下 CPU 架构上工作:x86、PowerPC、S/390、SPARC、ARM、MIPS、RISC-V 和 PA-RISC,以及在适用情况下的大端、小端、32 位和 64 位变体。对于不受支持的 CPU 类型,通常可以通过配置 来构建,但性能会很差。 可以预期 PostgreSQL 能在这些操作系统的当前版本上工作: - Linux、Windows、FreeBSD、OpenBSD、NetBSD、DragonFlyBSD、macOS、Solaris - 和 illumos。其他类 Unix 系统也可能可用,但目前未在测试。 + Linux、Windows、FreeBSD、OpenBSD、NetBSD、DragonFlyBSD、macOS、AIX、 + Solaris 和 illumos。其他类 Unix 系统也可能可用,但目前未在测试。 大多数情况下,某个操作系统所支持的全部 CPU 架构也都可以工作。 尤其是在使用较旧系统时,请查看下面的 , @@ -3136,8 +2974,8 @@ export MANPATH 历史版本的 PostgreSQL 或 POSTGRES 也曾运行在 - Alpha、Itanium、M32R、M68K、M88K、NS32K、PA-RISC、SuperH 和 VAX 等 - CPU 架构上,以及 4.3BSD、AIX、BEOS、BSD/OS、DG/UX、Dynix、HP-UX、IRIX、 + Alpha、Itanium、M32R、M68K、M88K、NS32K、SuperH 和 VAX 等 + CPU 架构上,以及 4.3BSD、BEOS、BSD/OS、DG/UX、Dynix、HP-UX、IRIX、 NeXTSTEP、QNX、SCO、SINIX、Sprite、SunOS、Tru64 UNIX 和 ULTRIX 等 操作系统上。 @@ -3169,79 +3007,31 @@ export MANPATH 在 AIX 上构建 PostgreSQL - - AIX 7.1 之前的版本,社区不再测试,也不再支持。 - + AIX 7.1 之前的版本已不再由 PostgreSQL 社区测试或支持。 内存管理 - - AIX 在内存管理方面有些特殊。即使系统中仍有很多 GB 的空闲 RAM, - 运行应用时也可能出现内存不足或地址空间错误。一个例子是加载扩展时出现异常错误。 - 例如,以 PostgreSQL 安装所有者身份运行: - + AIX 的内存管理方式有些特殊。服务器可能有数 GB 乃至更多的空闲 RAM,但运行应用程序时仍会出现内存不足或地址空间错误。例如,加载扩展可能因不寻常的错误而失败。以下是以 PostgreSQL 安装所有者身份运行的例子: =# CREATE EXTENSION plperl; ERROR: could not load library "/opt/dbs/pgsql/lib/plperl.so": A memory address is not in the address space for the process. - - 以不是所有者、但属于 PostgreSQL 安装所属组的用户运行: - +以 PostgreSQL 安装所属组中非所有者的成员身份运行: =# CREATE EXTENSION plperl; ERROR: could not load library "/opt/dbs/pgsql/lib/plperl.so": Bad address - - 另一个例子是 PostgreSQL 服务器日志中出现内存不足错误,而且每次接近或超过 256 MB 的内存分配都会失败。 - +另一个例子是 PostgreSQL 服务器日志中的内存不足错误,此时每次接近或超过 256 MB 的内存分配都会失败。 - - 这些问题的总根源在于服务器进程默认使用的位数和内存模型。默认情况下, - 在 AIX 上构建的所有二进制文件都是 32 位的,这与硬件类型或内核无关。 - 这些 32 位进程最多只能使用 4 GB 内存,按 256 MB 分段,并使用几种模型之一。 - 默认模型因为与栈共享一个段,所以堆中可用空间少于 256 MB。 - + 这些问题的总体原因是服务器进程使用的默认位数和内存模型。默认情况下,在 AIX 上构建的所有二进制文件都是 32 位的。这与硬件类型或所用内核无关。这些 32 位进程的内存上限为 4 GB,按几种模型之一以 256 MB 的段布局。默认情况下,堆与栈共享一个段,因此堆可用空间不足 256 MB。 - - 对于上面的 plperl 示例,请检查 umask 以及 - PostgreSQL 安装目录中二进制文件的权限。该示例中的二进制文件是 32 位的, - 并且被安装为 750 模式而不是 755。由于权限这样设置,只有所有者或所属组成员才能加载该库。 - 因为它不是 world-readable,加载器会把对象放入进程堆,而不是本应使用的共享库段。 - + 对于上面的 plperl 示例,请检查你的 umask 和 PostgreSQL 安装中二进制文件的权限。该示例涉及的二进制文件是 32 位的,安装时使用模式 750 而非 755。由于权限以这种方式设置,只有所有者或所属组的成员可以加载该库。因为它不是所有用户可读,加载器会将该对象放入进程的堆中,而不是通常应放置的共享库段。 - - 这个问题的“理想”解决方案是使用 64 位构建的 PostgreSQL,但这并不总是可行, - 因为带 32 位处理器的系统可以构建 64 位二进制文件,却不能运行它们。 - + 这个问题的理想解决办法是使用 64 位构建的 PostgreSQL,但这并非总是可行,因为采用 32 位处理器的系统可以构建 64 位二进制文件,却无法运行它们。 - - 如果需要 32 位二进制文件,请在启动 PostgreSQL 服务器之前把 - LDR_CNTRL 设为 - MAXDATA=0xn0000000, - 其中 1 <= n <= 8,并尝试不同的值和 postgresql.conf - 设置,找到一个令人满意的配置。使用 LDR_CNTRL 会告诉 AIX, - 你希望为服务器保留 MAXDATA 字节的堆空间,并按 256 MB 段分配。 - 找到可行配置后,可以使用 ldedit 修改二进制文件, - 使其默认使用所需的堆大小。也可以通过重新构建 PostgreSQL 并传入 - configure LDFLAGS="-Wl,-bmaxdata:0xn0000000" - 达到同样效果。 - + 如果需要 32 位二进制文件,请在启动 PostgreSQL 服务器之前,将 LDR_CNTRL 设为 MAXDATA=0xn0000000,其中 1 <= n <= 8,并尝试不同的值及 postgresql.conf 设置,找到能令人满意地工作的配置。这样使用 LDR_CNTRL 会告知 AIX,为服务器的堆预留 MAXDATA 字节,按 256 MB 的段分配。找到可用配置后,可以使用 ldedit 修改二进制文件,使其默认使用所需的堆大小。也可以重新构建 PostgreSQL,传入 configure LDFLAGS="-Wl,-bmaxdata:0xn0000000" 来达到相同效果。 - - 对于 64 位构建,请把 OBJECT_MODE 设为 64,并向 - configure 传入 CC="gcc -maix64" - 和 LDFLAGS="-Wl,-bbigtoc"。 - (xlc 的选项可能不同。)如果你没有导出 - OBJECT_MODE,构建可能会因链接器错误而失败。 - 当设置了 OBJECT_MODE 时,它会告诉 AIX 的构建工具, - 例如 arasld, - 默认处理哪种类型的对象。 - + 对于 64 位构建,将 OBJECT_MODE 设为 64,并向 configure 传入 CC="gcc -maix64"LDFLAGS="-Wl,-bbigtoc"。(xlc 的选项可能不同。)如果未导出 OBJECT_MODE,构建可能因链接器错误而失败。设置 OBJECT_MODE 后,它会告知 AIX 的 arasld 等构建工具默认处理哪种对象。 - - 默认情况下,分页空间可能会发生过量承诺。虽然我们没有见过这种情况,但当系统耗尽内存并且访问了过量承诺的内存时,AIX 会终止进程。 - 我们见过最接近的情况,是因为系统判定没有足够内存再启动一个进程,导致 fork 失败。 - 和 AIX 的许多其他部分一样,如果这成为问题,分页空间分配方式以及内存不足时的进程终止行为, - 都可以在系统范围或进程范围内配置。 - + 默认情况下,可能发生分页空间过量分配。虽然我们尚未见过这种情况,但当内存耗尽且访问了过量分配的空间时,AIX 会终止进程。我们遇到过最接近的情况是,系统认为没有足够内存容纳另一个进程,导致 fork 失败。与 AIX 的许多其他部分一样,如果这成为问题,可以在系统或进程级别配置分页空间分配方式和内存不足时终止进程的行为。 @@ -3253,10 +3043,7 @@ ERROR: could not load library "/opt/dbs/pgsql/lib/plperl.so": Bad address 在其上安装 - - 可以使用 Cygwin 这个 Windows 上的类 Linux 环境来构建 PostgreSQL, - 但这种方式不如原生 Windows 构建,且如今已不再推荐在 Cygwin 下运行服务器。 - + 可以使用 Cygwin 这个 Windows 上的类 Linux 环境来构建 PostgreSQL,但这种方式不如原生 Windows 构建(见 ,且如今已不再推荐在 Cygwin 下运行服务器。 从源代码构建时,请按照 Unix 风格的安装过程(也就是 @@ -3274,14 +3061,14 @@ ERROR: could not load library "/opt/dbs/pgsql/lib/plperl.so": Bad address 不支持 adduser 命令;请使用 Windows 中相应的 - 用户管理应用。除此之外,跳过这一步即可。 + 用户管理应用。也可以跳过这一步。 不支持 su 命令;请在 Windows 上使用 ssh 来模拟 su。 - 除此之外,跳过这一步即可。 + 也可以跳过这一步。 @@ -3312,16 +3099,11 @@ ERROR: could not load library "/opt/dbs/pgsql/lib/plperl.so": Bad address - - 并行回归测试(make check)可能会因为 - listen() backlog 队列溢出而产生伪造的回归测试失败, - 进而导致连接拒绝错误或挂起。你可以像下面这样使用 make 变量 - MAX_CONNECTIONS 来限制连接数: + 并行回归测试(make check)可能因 listen() 的待处理连接队列溢出而误报回归测试失败;队列溢出会导致连接被拒绝的错误或挂起。可以使用 make 变量 MAX_CONNECTIONS 限制连接数,方法如下: make MAX_CONNECTIONS=5 check - (在某些系统上,同时连接数大致最多可达到 10 个。) - +(在某些系统上,并发连接数最高可达约 10 个。) @@ -3394,7 +3176,7 @@ xcrun --show-sdk-path macOS 的 - System Integrity Protection(SIP)特性会破坏 + 系统完整性保护(SIP)特性会破坏 make check,因为它会阻止把所需的 DYLD_LIBRARY_PATH 设置传递给被测试的可执行文件。 你可以通过在 make check 之前先执行 @@ -3404,21 +3186,24 @@ xcrun --show-sdk-path - MinGW + MinGW/原生 Windows MinGW 在其上安装 - - 可以使用 MinGW 这个 Windows 上的类 Unix 构建环境来构建 Windows 版 - PostgreSQL。推荐为此使用 MSYS2 环境,并安装所需的前置软件包。 - + Windows 版 PostgreSQL 可以使用 MinGW(用于 Microsoft 操作系统的类 Unix 构建环境)构建,也可以使用 Microsoft 的 Visual C++ 编译器套件构建。MinGW 构建过程使用本章介绍的常规构建系统;Visual C++ 构建方式完全不同,详见 + + 原生 Windows 移植版本要求 32 位或 64 位的 Windows 2000 或更高版本。更早的操作系统没有足够的基础设施(但可以在其上使用 Cygwin)。可以从 下载 MinGW 这一类 Unix 构建工具,以及 MSYS 这一运行 configure 等 shell 脚本所需的 Unix 工具集。运行生成的二进制文件不需要它们;只有创建二进制文件时才需要。 - - 收集崩溃转储 + 要使用 MinGW 构建 64 位二进制文件,请从 安装 64 位工具集,将其 bin 目录放入 PATH,并使用 --host=x86_64-w64-mingw32 选项运行 configure + + 安装好所有组件后,建议在 CMD.EXE 下运行 psql,因为 MSYS 控制台存在缓冲问题。 + + + 在 Windows 上收集崩溃转储 + 如果 PostgreSQL 在 Windows 上崩溃,它能够生成 @@ -3460,7 +3245,7 @@ xcrun --show-sdk-path 你可以从 下载 Sun Studio。许多 GNU 工具已经集成到 Solaris 10 中, - 或者包含在 Solaris companion CD 中。如果你需要适用于较旧 Solaris 版本的 + 或者包含在 Solaris 配套光盘中。如果你需要适用于较旧 Solaris 版本的 软件包,可以到 查找这些工具。 如果你更想要源码,请看 。 @@ -3468,10 +3253,10 @@ xcrun --show-sdk-path - configure 抱怨测试程序失败 + configure 报告测试程序失败 - 如果 configure 抱怨某个测试程序失败, + 如果 configure 报告某个测试程序失败, 这多半是因为运行时链接器找不到某些库,通常是 libz、libreadline, 或其他非标准库如 libssl。要把它指向正确位置,请在 configure 命令行中设置环境变量 LDFLAGS, @@ -3526,7 +3311,6 @@ make: *** [postgres] Error 1 - diff --git a/zh/16/isn.sgml b/zh/16/isn.sgml index 714bfb87..3c227b4e 100644 --- a/zh/16/isn.sgml +++ b/zh/16/isn.sgml @@ -215,69 +215,53 @@ - make_valid - make_valid ( isn ) - isn + isn_weak + isn_weak ( boolean ) + boolean - 清除该值上的“校验位无效”标记。 + 设置弱输入模式,并返回新的设置值。 - is_valid - is_valid ( isn ) + isn_weak () boolean - 检查该值是否带有“校验位无效”标记。 + 返回弱模式的当前状态。 - isn_weak - isn_weak ( boolean ) - boolean + make_valid + make_valid ( isn ) + isn - 设置弱输入模式,并返回新的设置值。保留此函数是为了向后兼容。推荐通过isn.weak配置参数来设置弱模式。 + 将无效编号变为有效(清除无效标记)。 - isn_weak () + is_valid + is_valid ( isn ) boolean - 返回弱模式的当前状态。保留此函数是为了向后兼容。推荐通过isn.weak配置参数来检查弱模式。 + 检查是否存在无效标记。
- - - 配置参数 - - - - - isn.weak (boolean) - - isn.weak 配置参数 - - - - - isn.weak启用弱输入模式,使得即使 ISN 输入值的校验位有误也会被接受。默认值为false,此时会拒绝无效校验位。 - - - - + + 模式用于允许向表中插入无效数据。这里的“无效”指的是校验位错误,而不是缺少数字。 + 为什么会需要使用弱模式呢?例如,手头可能有一大批 ISBN 编号,数量多到难免会有一些编号因为某些奇怪的原因而带有错误的校验位(也许这些编号是从印刷清单扫描得到的,而 OCR 把数字识别错了;也许这些编号是人工录入的……谁知道呢)。总之,可能想把这些混乱情况清理干净,但同时仍希望先把所有编号都装入数据库,并借助外部工具在数据库中定位无效编号,以便核对信息并更容易完成校验;例如,可能会想把表中所有无效编号都查询出来。 @@ -288,7 +272,7 @@ - 即使未启用弱模式,也可以通过在编号末尾附加!字符来强制插入被标记为无效的编号。 + 即使未启用弱模式,也可以通过在编号末尾附加 ! 字符来强制插入无效编号。 @@ -325,11 +309,11 @@ SELECT issn('3251231?'); SELECT ismn('979047213542?'); --Using the weak mode: -SET isn.weak TO true; +SELECT isn_weak(true); INSERT INTO test VALUES('978-0-11-000533-4'); INSERT INTO test VALUES('9780141219307'); INSERT INTO test VALUES('2-205-00876-X'); -SET isn.weak TO false; +SELECT isn_weak(false); SELECT id FROM test WHERE NOT is_valid(id); UPDATE test SET id = make_valid(id) WHERE id = '2-205-00876-X!'; @@ -355,7 +339,7 @@ SELECT isbn13(id) FROM test; 用于进行连字符分隔的前缀还整理自: - + diff --git a/zh/16/libpq.sgml b/zh/16/libpq.sgml index b589c56b..48f1214a 100644 --- a/zh/16/libpq.sgml +++ b/zh/16/libpq.sgml @@ -41,7 +41,7 @@ - 如果不可信用户能够访问一个没有采用模式的安全使用方式的数据库,那么每个会话开始时都应从search_path中移除公开可写的模式。可以把参数关键词options设置为-csearch_path=。也可以在连接后发出PQexec(conn, "SELECT pg_catalog.set_config('search_path', '', false)")。这种考虑并非专门针对libpq;它适用于每一种可执行任意 SQL 命令的接口。 + 如果不受信任的用户能够访问一个没有采用模式的安全使用方式的数据库,那么每个会话开始时都应从search_path中移除公开可写的模式。可以把参数关键词options设置为-csearch_path=。也可以在连接后发出PQexec(conn, "SELECT pg_catalog.set_config('search_path', '', false)")。这种考虑并非专门针对libpq;它适用于每一种可执行任意 SQL 命令的接口。 @@ -214,7 +214,7 @@ PostgresPollingStatusType PQconnectPoll(PGconn *conn); - hostaddrhost参数必须被合适地使用,以防止做DNS查询。详见中这些参数的文档。 + 必须正确使用 hostaddr 参数,以避免执行 DNS 查询。详细信息请参见中该参数的说明。 @@ -779,7 +779,7 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname 参数关键词 - 目前被识别的参数关键字包括: + 目前被识别的参数关键字包括: @@ -950,11 +950,6 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname 服务器必须请求 MD5 哈希密码认证。 - - - 对 MD5 加密密码的支持已被废弃,并将在未来的PostgreSQL版本中移除。关于迁移到其他密码类型的细节,请参见。 - - @@ -985,15 +980,6 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname - - oauth - - - 服务器必须向客户端请求 OAuth Bearer 令牌。 - - - - none @@ -1354,34 +1340,7 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname - - sslnegotiation - - - 如果使用 SSL,此选项控制如何与服务器协商 SSL 加密。在默认的postgres模式下,客户端会先询问服务器是否支持 SSL;在direct模式下,客户端会在建立 TCP/IP 连接后直接开始标准 SSL 握手。传统的PostgreSQL协议协商能兼容更多不同的服务器配置;如果已知服务器支持直接SSL连接,则后一种方式可以减少一次往返,从而降低连接延迟,也允许使用与协议无关的 SSL 网络工具。直接 SSL 选项是在PostgreSQL 17 中引入的。 - - - - - postgres - - - 执行PostgreSQL协议协商。如果未提供该选项,这是默认值。 - - - - - direct - - - 在建立 TCP/IP 连接后直接开始 SSL 握手。仅当sslmode=require或更高时才允许使用该模式,因为更弱的设置可能在服务器不支持直接 SSL 握手时导致意外回退到明文认证。 - - - - - - sslcompression @@ -1429,19 +1388,7 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname - - sslkeylogfile - - - 这个参数指定libpq记录此 SSL 上下文所用密钥的位置。这对于调试PostgreSQL协议交互,或者借助Wireshark之类的网络检查工具分析客户端连接很有用。如果未建立 SSL 连接,或者使用的是LibreSSL(其不支持密钥记录),则会忽略此参数。密钥将按NSS格式记录。 - - - 密钥记录会在 keylog 文件中暴露潜在敏感信息。应当像处理文件一样谨慎处理 keylog 文件。 - - - - - + sslpassword @@ -1515,12 +1462,20 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname sslrootcert - - 这个参数指定一个包含SSL证书颁发机构(CA)证书的文件名。 - 如果文件存在,服务器的证书将被验证是否由这些机构之一签名。 - 默认值是~/.postgresql/root.crt。 + 此参数指定包含 SSL 证书颁发机构(CA)证书的文件名。如果文件存在,则会验证服务器证书是否由这些机构之一签名。默认值为~/.postgresql/root.crt。 + + + 也可以指定特殊值system,此时会加载 SSL 实现提供的受信任 CA 根证书。这些根证书的确切位置因 SSL 实现和平台而异。对于OpenSSL,还可以通过SSL_CERT_DIRSSL_CERT_FILE环境变量进一步修改这些位置。 + + + + 使用sslrootcert=system时,默认的sslmode会改为verify-full,任何较弱的设置都会引发错误。在大多数情况下,任何人都很容易为其控制的主机名获取受系统信任的证书,因此verify-ca及所有更弱的模式都无法发挥作用。 + + + 特殊值system优先于同名的本地证书文件。如果遇到这种情况,请改用其他路径,例如sslrootcert=./system + @@ -1617,47 +1572,9 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname - - min_protocol_version - - - 这个参数指定该连接允许的最低协议版本。默认情况下,允许使用 - libpq所支持的任何 - PostgreSQL协议版本, - 目前即3.0。如果服务器至少不支持这一协议版本, - 则连接将被关闭。 - - - 当前支持的值是3.03.2 - 和latestlatest等价于 - 正在使用的libpq版本所支持的最新协议版本, - 目前即3.2。 - - - - - max_protocol_version - - - 这个参数指定要向服务器请求的协议版本。默认会使用 - PostgreSQL协议的3.0版本; - 但如果连接字符串指定了依赖更高协议版本的特性,则会使用 - libpq支持的最新版本。如果服务器不支持客户端请求的协议版本, - 连接会自动降级为服务器支持的较低次版本协议。连接尝试完成后, - 你可以使用PQfullProtocolVersion()来确定 - 最终协商得到的确切协议版本。 - - - 当前支持的值是3.03.2 - 和latestlatest等价于 - 正在使用的libpq版本所支持的最新协议版本, - 目前即3.2。 - - - krbsrvname @@ -1699,23 +1616,9 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname - - scram_client_key - - - 以 Base64 编码的 SCRAM client key。外部数据包装器或类似中间件可以利用它启用透传式 SCRAM 认证。一个实现示例见。普通用户或客户端应用不应直接指定它。 - - - - - scram_server_key - - - 以 Base64 编码的 SCRAM server key。外部数据包装器或类似中间件可以利用它启用透传式 SCRAM 认证。一个实现示例见。普通用户或客户端应用不应直接指定它。 - - - + + service @@ -1832,63 +1735,13 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname - - oauth_issuer - - - 如果服务器为该连接请求 OAuth 令牌,要联系的受信任签发者的 HTTPS URL。所有 OAuth 连接都必须设置此参数;它应当与服务器 HBA 配置中的issuer设置完全一致。 - - - 作为标准认证握手的一部分,libpq会向服务器请求一个发现文档,也就是一个提供一组 OAuth 配置参数的 URL。服务器必须提供一个可由oauth_issuer的各组成部分直接构造出来的 URL,并且该值必须与发现文档自身声明的签发者标识符完全一致,否则连接会失败。这是为了防止 OAuth 客户端遭受一类 - “混淆攻击(mix-up attacks)”。 - - - 你也可以显式把oauth_issuer设置为 OAuth 发现所使用的/.well-known/ URI。在这种情况下,如果服务器要求使用不同的 URL,连接就会失败;不过,自定义 OAuth 流程也许能够通过使用先前缓存的令牌来加速标准握手。(此时也建议设置,因为客户端将没有机会向服务器询问正确的 scope 设置,而令牌的默认 scope 可能不足以完成连接。)libpq当前支持以下 well-known 端点: - - /.well-known/openid-configuration - /.well-known/oauth-authorization-server - - - - - 在 OAuth 连接握手期间,签发者拥有极高的权限。经验法则是:如果你不会信任某个 URL 的运营者来处理你对服务器的访问,或者不会信任其直接冒充你,那么这个 URL 就不应被信任为oauth_issuer。 - - - - - - oauth_client_id - - - 由授权服务器发放的 OAuth 2.0 客户端标识符。如果PostgreSQL服务器为该连接请求 OAuth 令牌,并且没有安装自定义 OAuth 钩子来提供该令牌,那么就必须设置此参数;否则连接会失败。 - - - - - oauth_client_secret - - - 与 OAuth 授权服务器通信时要使用的客户端密码(如果有)。该参数是否必需由 OAuth 提供者决定;“public” 客户端通常不使用 secret,而 “confidential” 客户端通常会使用。 - - - - - oauth_scope - - - 发送给授权服务器的访问请求 scope,以 OAuth scope 标识符的空格分隔列表指定(该列表可以为空)。该参数是可选的,面向高级用法。 - - - 通常客户端会从PostgreSQL服务器获得合适的 scope 设置。如果使用这个参数,服务器请求的 scope 列表会被忽略。这可以防止不那么受信任的服务器向最终用户请求不恰当的访问 scope。不过,如果客户端的 scope 设置不包含服务器所要求的 scope,服务器很可能会拒绝已经签发的令牌,连接也会失败。 - - - 空 scope 列表的含义取决于提供者。OAuth 授权服务器可以选择签发带有“默认 scope”的令牌,不管那具体是什么;也可以完全拒绝该令牌请求。 - - - + + + + @@ -1955,7 +1808,7 @@ char *PQpass(const PGconn *conn); 将返回连接参数中指定的密码,如果连接参数中没有密码并且能从密码文件中得到密码,则它将返回得到的密码。 - 在后一种情况中,如果连接参数中指定了多个主机,在连接被建立之前都不能依赖的结果。连接的状态可以用函数检查。 + 在后一种情况中,如果连接参数中指定了多个主机,在连接被建立之前都不能依赖的结果。连接的状态可以用函数检查。 @@ -2109,46 +1962,43 @@ PGTransactionStatusType PQtransactionStatus(const PGconn *conn); - 查找服务器的一个当前参数设置。 + 查找服务器某个参数的当前设置。 const char *PQparameterStatus(const PGconn *conn, const char *paramName); - 某一参数值会被服务器在连接开始或值改变时自动报告。可以被用来询问这些设置。它为已知的参数返回当前值,为未知的参数返回NULL。 + 服务器会在连接启动时,以及某些参数值发生变化时,自动报告这些参数值。可用于查询这些设置。如果已知该参数,则返回其当前值;如果未知,则返回NULL - 自当前发布开始会被报告的参数包括 - server_version、 - server_encoding、 - client_encoding、 - application_name、 - default_transaction_read_only, - in_hot_standby, - is_superuser、 - session_authorization、 - DateStyle、 - IntervalStyle、 - TimeZone、 - integer_datetimes以及 - standard_conforming_strings。 - (server_encodingTimeZone以及integer_datetimes在 8.0 以前的发布中不被报告; - standard_conforming_strings在 8.1 以前的发布中不被报告; - IntervalStyle在 8.4 以前的发布中不被报告; - application_name在 9.0 以前的发布中不被报告; - default_transaction_read_onlyin_hot_standby 在14以前的发布中不被报告) - 注意 server_version、 - server_encoding以及 - integer_datetimes在启动之后无法改变。 + 当前版本报告的参数包括: + + application_name + client_encoding + DateStyle + default_transaction_read_only + in_hot_standby + integer_datetimes + IntervalStyle + is_superuser + scram_iterations + server_encoding + server_version + session_authorization + standard_conforming_strings + TimeZone + + (8.0 之前的版本不报告 server_encodingTimeZoneinteger_datetimes;8.1 之前的版本不报告 standard_conforming_strings;8.4 之前的版本不报告 IntervalStyle;9.0 之前的版本不报告 application_name;14 之前的版本不报告 default_transaction_read_onlyin_hot_standby;16 之前的版本不报告 scram_iterations。) + 注意,server_versionserver_encodinginteger_datetimes 在启动后不能改变。 - 如果没有为standard_conforming_strings报告值,应用能假设它是off,也就是说反斜线会被视为字符串中的转义。还有,这个参数的存在可以被作为转义字符串语法(E'...')被接受的指示。 + 如果服务器未报告standard_conforming_strings的值,应用程序可以假定其为off,即反斜杠在字符串字面量中被视为转义字符。此外,服务器报告此参数也表明它接受转义字符串语法(E'...')。 - 尽管被返回的指针被声明成const,它事实上指向与PGconn结构体相关的可变存储。假定该指针在存储之间保持有效是不明智的。 + 返回的指针虽然被声明为const,但实际上指向与PGconn结构体关联的可变存储。不能假定该指针在执行其他查询后仍然有效。 @@ -2283,6 +2133,22 @@ int PQconnectionUsedPassword(const PGconn *conn);
+ + + PQconnectionUsedGSSAPIPQconnectionUsedGSSAPI + + + 如果连接的认证方法使用了 GSSAPI,则返回真(1);否则返回假(0)。 + +int PQconnectionUsedGSSAPI(const PGconn *conn); + + + + + 此函数可用于检测连接是否使用 GSSAPI 进行了认证。 + + +
@@ -2383,13 +2249,16 @@ const char *PQsslAttribute(const PGconn *conn, const char *attribute_name); PQsslAttributeNamesPQsslAttributeNames - - 返回可用的SSL属性名称数组。 - 数组以NULL指针结尾。 + 返回可用于 PQsslAttribute() 的 SSL 属性名称数组。数组以 NULL 指针结尾。 const char * const * PQsslAttributeNames(const PGconn *conn); + + + + + 如果 conn 为 NULL,则返回默认 SSL 库可用的属性;如果 libpq 编译时未启用任何 SSL 支持,则返回空列表。如果 conn 不为 NULL,则返回该连接所用 SSL 库可用的属性;如果连接未加密,则返回空列表。 @@ -2569,7 +2438,7 @@ PGresult *PQexecParams(PGconn *conn, paramTypes[] - 通过 OID 指定要赋予给参数符号的数据类型。如果paramTypesNULL或者该数组中任何特定元素为零,服务器会用对待未知类型文字串的方式为参数符号推测一种数据类型。 + 通过 OID 指定要赋予给参数符号的数据类型。如果paramTypesNULL或者该数组中任何特定元素为零,服务器会用对待未指定类型的字符串字面量的方式为参数符号推测一种数据类型。 @@ -2663,10 +2532,10 @@ PGresult *PQprepare(PGconn *conn, 该函数从query串创建一个名为stmtName的预备语句,该串必须包含一个单一 SQL 命令。 stmtName可以是""来创建一个未命名语句,在这种情况下任何已存在未命名语句将被自动替换。 - 如果语句名称已经在当前会话中被定义,则是一种错误。如果使用了任何参数,它们在查询中以$1$2等引用。 + 否则,如果语句名称已经在当前会话中被定义,则是一种错误。如果使用了任何参数,它们在查询中以$1$2等引用。 nParams是参数的个数,其类型在数组paramTypes[]中被预先指定(当nParams为零时,该数组指针可以是NULL)。 paramTypes[]通过 OID 指定要赋予给参数符号的数据类型。 - 如果paramTypesNULL或者该数组中任何特定元素为零,服务器会用对待未知类型文字串的方式为参数符号推测一种数据类型。 + 如果paramTypesNULL或者该数组中任何特定元素为零,服务器会用对待未指定类型的字符串字面量的方式为参数符号推测一种数据类型。 还有,查询能够使用编号高于nParams的参数符号,它们的数据类型也会被自动推测(找出推测出的数据类型的方法见)。 @@ -2774,47 +2643,9 @@ PGresult *PQdescribePortal(PGconn *conn, const char *portalName); - - PQclosePreparedPQclosePrepared - - - - 提交一个请求以关闭指定的预备语句,并等待完成。 - -PGresult *PQclosePrepared(PGconn *conn, const char *stmtName); - - - - - 允许应用程序关闭先前准备好的预备语句。关闭语句会释放它在服务器上的全部相关资源,并允许重复使用其名称。 - - - - stmtName可以是""NULL来引用未命名语句。如果不存在该名称的语句也没有关系;在这种情况下,该操作不会执行任何操作。成功时,会返回一个状态为PGRES_COMMAND_OKPGresult。 - - - - - - PQclosePortalPQclosePortal - - - 提交一个请求以关闭指定的 portal,并等待完成。 - -PGresult *PQclosePortal(PGconn *conn, const char *portalName); - - - - 允许应用程序关闭先前创建的 portal。关闭 portal 会释放它在服务器上的全部相关资源,并允许重复使用其名称。(libpq不直接提供对 portal 的访问,但你可以使用这个函数来关闭通过DECLARE CURSOR SQL 命令创建的游标。) - - - portalName可以是""NULL来引用未命名的 portal。如果不存在该名称的 portal 也没有关系;在这种情况下,该操作不会执行任何操作。成功时,会返回一个状态为PGRES_COMMAND_OKPGresult。 - - -
@@ -3076,7 +2907,7 @@ char *PQresultErrorField(const PGresult *res, int fieldcode); PG_DIAG_MESSAGE_DETAIL - 细节:一个可选的次级错误消息,它携带了关于问题的等多细节。可能有多行。 + 细节:一个可选的次级错误消息,它携带了关于问题的更多细节。可能有多行。 @@ -3094,7 +2925,7 @@ char *PQresultErrorField(const PGresult *res, int fieldcode); PG_DIAG_STATEMENT_POSITION - 包含一个十进制整数的字符串,它表示一个错误游标位置,该位置是原始语句字符串的索引。第一个字符的索引是 1,位置以字符计算而不是以及字节计算。 + 包含一个十进制整数的字符串,它表示一个错误游标位置,该位置是原始语句字符串的索引。第一个字符的索引是 1,位置以字符计算而不是以字节计算。 @@ -3888,8 +3719,8 @@ unsigned char *PQescapeByteaConn(PGconn *conn, - 当某些字节值被用作一个SQL语句中的bytea文字的一部分时,它们必须被转义。 - 转义使用十六进制编码或反斜线转义的字节。详见。 + 当某些字节值被用作一个SQL语句中的bytea字面量的一部分时,它们必须被转义。 + 使用十六进制编码或反斜杠转义来转义这些字节。详见 @@ -3939,7 +3770,8 @@ unsigned char *PQescapeBytea(const unsigned char *from, - 将二进制数据的一个字符串表示转换成二进制数据 — 它是的逆向函数。当检索文本格式的bytea数据时,需要这个函数,但检索二进制个事时则不需要它。 + 将二进制数据的字符串表示转换为二进制数据,这是的逆操作。 + 以文本格式取得bytea数据时需要此操作;以二进制格式取得时则不需要。 unsigned char *PQunescapeBytea(const unsigned char *from, size_t *to_length); @@ -3947,14 +3779,15 @@ unsigned char *PQunescapeBytea(const unsigned char *from, size_t *to_length); - from参数指向一个字符串,例如被应用到一个bytea列上所返回的。 - 把这个串表示转换成它的二进制表示。 - 它返回一个指向用malloc()分配的缓冲区的指针,在错误时返回NULL,并且把缓冲区的尺寸放在to_length中。 - 当结果不再需要时,它必须使用释放。 + from参数指向一个字符串,例如对bytea列调用时返回的字符串。 + 将这个字符串表示转换为二进制表示。 + 它返回指向通过malloc()分配的缓冲区的指针,出错时返回NULL,并将缓冲区大小存入to_length。 + 不再需要结果时,必须使用释放它。 - 这种转换并不完全是PQescapeBytea的逆函数,因为当从PQgetvalue接收到字符串时,我们并不能期待它被转义。特别地这意味着不需要考虑字符串引用,并且因此也不需要一个参数。 + 此转换并不完全是的逆操作,因为从收到的字符串并非经过转义的形式。 + 具体而言,这意味着无需考虑字符串引号,因此也不需要PGconn参数。 @@ -4003,26 +3836,13 @@ unsigned char *PQunescapeBytea(const unsigned char *from, size_t *to_length); - - 不喜欢这些限制的应用程序可以使用构建自的底层函数: - 。 - 还有 - , - , - , - , - , - 以及 - , - 它们可以与配合使用,分别复制 - , - , - , - , - , - 和 - - 的功能。 + 如果应用程序不希望受到这些限制,可以改用构成的底层函数:。此外,还有, + , + , + ,以及,它们可以与配合使用,分别实现以下函数的功能:, + , + , + ,以及 @@ -4160,35 +3980,9 @@ int PQsendDescribePortal(PGconn *conn, const char *portalName); - - PQsendClosePreparedPQsendClosePrepared - - - - 提交一个关闭指定预备语句的请求,而不等待完成。 - -int PQsendClosePrepared(PGconn *conn, const char *stmtName); - - - 这是的异步版本:如果成功分派请求则返回 1,否则返回 0。调用成功后,使用获取结果。其参数处理方式与相同。 - - - - - PQsendClosePortalPQsendClosePortal - - - 提交一个关闭指定 portal 的请求,而不等待完成。 - -int PQsendClosePortal(PGconn *conn, const char *portalName); - - 这是的异步版本:如果成功分派请求则返回 1,否则返回 0。调用成功后,使用获取结果。其参数处理方式与相同。 - - - @@ -4473,68 +4267,46 @@ int PQflush(PGconn *conn); - 发出查询 - 进入管道模式后,应用程序使用或其姊妹函数来分派请求。 - 这些请求在客户端排队,直到刷新到服务器端;当使用建立管道中的同步点时,或者调用时,会发生这种情况。 - 函数在管道模式下也可以工作。 - 结果处理如下所述。 + 进入管道模式后,应用程序使用 或其处理预备查询的对应函数 发送请求。这些请求在客户端排队,直到发送到服务器;使用 在管道中建立同步点,或调用 时会发送它们。函数 、&zwsp; 也可用于管道模式。结果处理方式见下文。 - 服务器执行语句,并返回结果,按客户端发送它们的顺序。 - 服务器将立即开始执行管道中的命令,不等待管道的结束。 - 注意,结果被缓冲在服务器端;当使用PQpipelineSync建立同步点时,或者PQsendFlushRequest被调用时,服务器会刷新该缓冲区。 - 如果任何语句遇到错误,服务器将中止当前事务,并且不执行队列中的任何后续命令,直到下一个同步点;对于每一个这样的命令都会产生一个PGRES_PIPELINE_ABORTED结果。 - (即使管道中的命令将回滚事务,依然如此。) - 查询处理在同步点之后恢复。 + 服务器按客户端发送的顺序执行语句并返回结果。服务器会立即开始执行管道中的命令,无需等待管道结束。结果会缓存在服务器端;使用 PQpipelineSync 建立同步点,或调用 PQsendFlushRequest 时,服务器会发送该缓冲区中的数据。如果任何语句发生错误,服务器会中止当前事务,并停止执行队列中的后续命令,直到下一个同步点;每条被跳过的命令都会产生一个 PGRES_PIPELINE_ABORTED 结果。(即使管道中的命令会回滚事务,也仍然如此。)到达同步点后,查询处理恢复。 - 一个操作依赖于前一个操作的结果是没问题的; - 例如,一个查询可以定义一个同一管道中的下一个查询将用到的表。 - 类似地,应用可以创建一个命名的预备语句,并在同一管道中与后续语句一起执行它。 + 一个操作可以依赖先前操作的结果;例如,一个查询可以定义一张表,供同一管道中的下一个查询使用。类似地,应用程序可以创建命名的预备语句,并通过同一管道中后续的语句执行它。 - 处理结果 - 为了在管道中处理一个查询的结果,应用重复调用PQgetResult并处理每个结果,直到PQgetResult返回空。 - 可以再次使用PQgetResult检索管道中下一个查询的结果,并且循环重复 - 应用像通常一样处理单个语句结果。 - 当管道中所有查询的结果都返回时,PQgetResult返回一个结果,其包含状态值PGRES_PIPELINE_SYNC。 + 要处理管道中一个查询的结果,应用程序应重复调用 PQgetResult 并处理每个结果,直到 PQgetResult 返回空指针。然后再次调用 PQgetResult 获取管道中下一个查询的结果,重复这一过程。应用程序按通常方式处理各条语句的结果。当管道中所有查询的结果都已返回时,PQgetResult 会返回一个包含状态值 PGRES_PIPELINE_SYNC 的结果。 - 客户端可以选择延迟结果处理,直到完整的管道被发送,或者与管道中发送的更多的查询交错在一起;参见。 + 客户端可以等到整条管道发送完毕后再处理结果,也可以在继续发送管道中的查询时交错处理结果;参见 - 要进入单行模式,在使用PQgetResult检索结果之前调用PQsetSingleRowMode。 - 此模式选择仅对当前处理的查询有效。 - 有关使用PQsetSingleRowMode的更多信息,请参阅。 + 要进入单行模式,应在使用 PQgetResult 获取结果之前调用 PQsetSingleRowMode。该模式选择仅对当前正在处理的查询有效。关于 PQsetSingleRowMode 的更多信息,参见 - PQgetResult行为与普通异步处理相同,除了它可能包含新的PGresult类型PGRES_PIPELINE_SYNCPGRES_PIPELINE_ABORTED。 - 对于每个在管道中相应的点的PQpipelineSyncPGRES_PIPELINE_SYNC确定报告一次。 - PGRES_PIPELINE_ABORTED在第一个错误和所有后续结果的正常查询结果中发出,直到下一个PGRES_PIPELINE_SYNC;参见。 + PQgetResult 的行为与普通异步处理相同,只是返回结果可能具有新的 PGresult 类型 PGRES_PIPELINE_SYNCPGRES_PIPELINE_ABORTED。对于每次 PQpipelineSync 调用,都会在管道中的对应位置恰好报告一次 PGRES_PIPELINE_SYNC。对于第一个错误及其后的所有结果,会用 PGRES_PIPELINE_ABORTED 代替正常查询结果,直到下一个 PGRES_PIPELINE_SYNC;参见 - PQisBusyPQconsumeInput、等正常操作,在处理管道结果时。 - 特别是,在管道中间调用PQisBusy 时,如果到目前为止发出的所有查询的结果都已被消耗,则返回0。 + PQisBusyPQconsumeInput 等函数在处理管道结果时照常工作。特别地,在管道处理过程中调用 PQisBusy 时,如果到目前为止已发出查询的所有结果均已被消费,则返回 0。 - libpq不向应用提供有关当前正在处理的查询的任何信息(除了PQgetResult返回空,以表示我们开始返回下一个查询的结果)。 - 应用必须保持跟踪它发送查询的顺序,以将它们与相应的结果相关联。 - 应用通常会为此使用状态机或FIFO队列。 + libpq 不向应用程序提供当前正在处理哪个查询的信息(除了 PQgetResult 返回空指针,表示开始返回下一个查询的结果)。应用程序必须跟踪查询的发送顺序,以便将查询与对应结果关联起来。应用程序通常会使用状态机或 FIFO 队列实现这一点。 @@ -4581,7 +4353,7 @@ int PQflush(PGconn *conn); 客户端应用通常应该维护一个尚未分派的工作队列和一个已分派但尚未处理结果的工作队列。 当套接字是可写时,它将可以分派更多的工作。 当套接字是可读时,它将读取结果并处理它们,将它们匹配到相应结果队列中的下一个条目。 - 基于可用内存,来自套接字的结果将被经常读取:这里不需要等到管道结束才读取结果。 + 基于可用内存,来自套接字的结果将被经常读取:这里不需要等到管道结束才读取结果。 管道将范围涵盖到工作的逻辑单元,通常(但不是必然)每个管道一个事务。 在管道之间,不需要退出管道模式再重新进入管道模式,也不需要等待一个管道结束后再发送下一个。 @@ -4612,7 +4384,7 @@ PGpipelineStatus PQpipelineStatus(const PGconn *conn); - PQpipelineStatus 可以返回下列值中的一个: + PQpipelineStatus 可以返回下列值中的一个: @@ -4720,22 +4492,7 @@ int PQpipelineSync(PGconn *conn); - - PQsendPipelineSyncPQsendPipelineSync - - - - 通过发送sync message但不刷新发送缓冲区,来标记管道中的一个同步点。它可作为隐式事务的分界符和错误恢复点;参见。 - -int PQsendPipelineSync(PGconn *conn); - - - - 成功时返回 1。如果连接不处于管道模式,或者发送sync message失败,则返回 0。请注意,该消息本身不会自动刷新到服务器;必要时请使用PQflush。 - - - @@ -4756,8 +4513,8 @@ int PQsendFlushRequest(PGconn *conn); - 当PQpipelineSync被调用的结果,或者在非管道模式下的任何请求时,服务器自动刷新它的输出缓冲区;这个函数用于使得服务器在不建立同步点的情况下以管道模式刷新其输出缓冲区。 - 请注意,请求不是自身能自动刷新到服务器;如果需要时使用PQflush。 + 当PQpipelineSync被调用的结果,或者在非管道模式下的任何请求时,服务器自动刷新它的输出缓冲区;这个函数用于使得服务器在不建立同步点的情况下以管道模式刷新其输出缓冲区。 + 请注意,请求不是自身能自动刷新到服务器;如果需要时使用PQflush @@ -4777,7 +4534,7 @@ int PQsendFlushRequest(PGconn *conn); 当服务器比较远,即网络延迟(ping time)高的时候,管道模式最有用,以及在许多小操作正在快速连续执行的时候。 当每个查询的执行时间是客户端/服务器往返时间的许多倍时,使用管道命令的优势通常会更少。 - 不用管道模式,在往返时间为300毫秒的服务器上运行一个100条语句的操作,仅网络延迟就需要30秒;使用管道,等待来自服务器的结果可能只消耗仅仅0.3秒。 + 不用管道模式,在往返时间为300毫秒的服务器上运行一个100条语句的操作,仅网络延迟就需要30秒;使用管道,等待来自服务器的结果可能只消耗仅仅0.3秒。 @@ -4788,7 +4545,7 @@ int PQsendFlushRequest(PGconn *conn); 当来自一个操作的信息需要客户端产生下一个操作时,管道模式是没有用的。 在这种情况下,客户机将不得不引入一个同步点,并等待完整的客户端/服务器往返以获取它需要的结果。 但是,通常可以调整客户端设计以交换服务器端所需的信息。 - 读-修改-写循环是非常好的选择;例如: + 读-修改-写循环是非常好的选择;例如: BEGIN; SELECT x FROM mytable WHERE id = 42 FOR UPDATE; @@ -4797,7 +4554,7 @@ SELECT x FROM mytable WHERE id = 42 FOR UPDATE; UPDATE mytable SET x = 3 WHERE id = 42; COMMIT; - 可以更有效地开展以下工作: + 可以更有效地开展以下工作: UPDATE mytable SET x = x + 1 WHERE id = 42; @@ -4810,29 +4567,18 @@ UPDATE mytable SET x = x + 1 WHERE id = 42; - 分块检索查询结果 - - - libpq - single-row mode - + 逐行检索查询结果 libpq - chunked mode + 单行模式 - - 通常,libpq会收集一条 SQL 命令的完整结果,并将其作为单个PGresult返回给应用程序。对于返回大量行的命令,这可能并不适用。对于这类情况,应用程序可以将用于单行模式分块模式。在这些模式下,结果行会在从服务器收到时立即返回给应用程序;单行模式每次返回一行,分块模式则每次返回一组行。 - + 通常,libpq 会收集一条 SQL 命令的完整结果,并将其作为单个 PGresult 返回给应用程序。对于返回大量行的命令,这种方式可能不可行。在这种情况下,应用程序可以在单行模式下使用 。此模式在从服务器收到结果行时,每次将一行返回给应用程序。 - - 要进入这些模式之一,请在成功调用(或其兄弟函数)后立即调用。这种模式选择只对当前正在执行的查询生效。然后按所述,反复调用直到其返回空指针。如果查询返回了任何行,这些行会作为一个或多个PGresult对象返回。它们看起来与普通查询结果相同,只是状态码在单行模式下为PGRES_SINGLE_TUPLE,在分块模式下为PGRES_TUPLES_CHUNK,而不是PGRES_TUPLES_OK。每个PGRES_SINGLE_TUPLE对象恰好包含一行结果,而PGRES_TUPLES_CHUNK对象至少包含一行、至多包含指定的每块行数。最后一行之后,或者如果查询返回零行,则会返回一个状态为PGRES_TUPLES_OK且不含行的对象,表示不会再有更多行到达。(但请注意,仍然必须继续调用直到其返回空指针。)所有这些PGresult对象都会包含与普通查询结果相同的行描述数据(列名、类型等)。每个对象在使用完之后都应像往常一样通过释放。 - + 要进入单行模式,请在成功调用 (或其同类函数)后,立即调用 。此模式选择仅对当前正在执行的查询生效。然后按照 所述,反复调用 ,直到返回空指针。如果查询返回了行,每一行都作为独立的 PGresult 对象返回。这些对象看起来与普通查询结果相同,只是状态码为 PGRES_SINGLE_TUPLE,而不是 PGRES_TUPLES_OK。最后一行之后,或者查询返回零行时立即返回一个不含行、状态为 PGRES_TUPLES_OK 的对象,表示不会再有更多行到达。(但注意,仍然必须继续调用 ,直到返回空指针。)所有这些 PGresult 对象都包含与该查询普通 PGresult 对象相同的行描述数据(列名、类型等)。每个对象都应像往常一样使用 释放。 - - 在使用管道模式时,必须在用PQgetResult提取该查询结果之前,为管道中的每个查询分别激活单行模式或分块模式。更多信息见。 - + 在使用管道模式时,必须在用 PQgetResult 获取某个查询的结果之前,为管道中的该查询激活单行模式。更多信息见 @@ -4853,31 +4599,11 @@ int PQsetSingleRowMode(PGconn *conn); - - - PQsetChunkedRowsModePQsetChunkedRowsMode - - - - 为当前正在执行的查询选择分块模式。 - - -int PQsetChunkedRowsMode(PGconn *conn, int chunkSize); - - - - - 该函数与类似,不同之处在于它指定每个PGresult最多返回chunkSize行,而不一定只返回一行。此函数也只能在调用或其某个兄弟函数之后立即调用,并且必须在该连接上执行任何其他操作之前调用,例如。如果调用时机正确,该函数会为当前查询激活分块模式并返回 1;否则模式保持不变并返回 0。无论如何,当前查询结束后都会恢复为普通模式。 - - - - - 在处理一个查询的过程中,服务器可能先返回一些行,然后遇到错误并中止该查询。通常,libpq会丢弃这些行,只报告错误。但在单行模式或分块模式下,部分行可能已经返回给应用程序。因此,应用程序可能会先看到一些PGRES_SINGLE_TUPLEPGRES_TUPLES_CHUNKPGresult对象,然后再看到一个PGRES_FATAL_ERROR对象。为了获得正确的事务语义,如果查询最终失败,应用程序必须能丢弃或撤销之前对这些已处理行所做的操作。 - + 处理查询时,服务器可能先返回一些行,然后遇到错误,导致查询中止。通常,libpq 会丢弃这些行,只报告错误。但在单行模式下,这些行已经返回给了应用程序。因此,应用程序会先看到一些 PGRES_SINGLE_TUPLE PGresult 对象,随后看到一个 PGRES_FATAL_ERROR 对象。为了保证正确的事务行为,如果查询最终失败,应用程序必须能够丢弃或撤销此前对这些行所做的全部操作。 @@ -4886,365 +4612,94 @@ int PQsetChunkedRowsMode(PGconn *conn, int chunkSize); 取消进行中的查询 - canceling SQL queries - - - query cancellation + 取消 + SQL 命令 - - 发送取消请求的函数 - - - PQcancelCreatePQcancelCreate + 客户端应用程序可以使用本节介绍的函数,请求取消服务器仍在处理的命令。 + + PQgetCancelPQgetCancel - - 准备用于发送取消请求的连接。 - -PGcancelConn *PQcancelCreate(PGconn *conn); + 创建一个数据结构,其中包含取消通过特定数据库连接发出的命令所需的信息。 +PGcancel *PQgetCancel(PGconn *conn); - 创建一个PGcancelConnPGcancelConn对象,但不会立即通过这条连接发送取消请求。可以使用以阻塞方式发送取消请求,或者使用以非阻塞方式发送。返回值可以传给,以检查该PGcancelConn对象是否成功创建。PGcancelConn是不透明结构,不应由应用程序直接访问。它可用于以线程安全的方式取消原始连接上正在执行的查询。 + 基于一个PGconn连接对象创建PGcancelPGcancel对象。如果给定的connNULL或无效连接,则返回NULLPGcancel是不透明结构体,不应由应用程序直接访问;它只能传给 + + + + + PQfreeCancelPQfreeCancel + - 在为取消请求建立连接时,会重用原始客户端连接的许多连接参数。特别是,如果原始连接要求对连接进行加密和/或验证目标主机(通过sslmodegssencmode),则取消请求连接也会使用同样的要求。不过,仅在客户端认证期间或认证后才会用到的连接选项会被忽略,因为取消请求不需要认证,并且提交取消请求后该连接就会立即关闭。 + 释放由创建的数据结构。 + +void PQfreeCancel(PGcancel *cancel); + - 请注意,当PQcancelCreate返回非空指针时,你必须在使用完毕后调用,以释放该结构及其关联内存块。即使取消请求失败或被放弃,也必须这样做。 + 释放先前由创建的数据对象。 - - PQcancelBlockingPQcancelBlocking + + PQcancelPQcancel - 以阻塞方式请求服务器放弃处理当前命令。 + 请求服务器放弃当前命令的处理。 -int PQcancelBlocking(PGcancelConn *cancelConn); +int PQcancel(PGcancel *cancel, char *errbuf, int errbufsize); - 请求通过给定的PGcancelConn发送,该对象必须由创建。成功分派取消请求时返回 1,否则返回 0。若失败,可通过获取错误信息。 + 返回值为 1 表示取消请求成功发送,为 0 表示未成功发送。如果未成功发送,errbuf将填充解释性错误消息。errbuf必须是大小为errbufsize的字符数组(推荐大小为 256 字节)。 + + + + 取消请求成功分派并不保证一定会产生效果。如果取消成功,当前命令会提前终止并返回错误结果;如果取消失败(例如服务器已经处理完该命令),则不会有任何可见结果。 - 取消请求成功分派并不保证一定会产生效果。如果取消成功,被取消的命令会提前终止并返回一个错误结果;如果取消失败(例如服务器已经处理完该命令),则不会有任何可见结果。 + 如果errbuf是信号处理程序中的局部变量,则可以安全地从信号处理程序中调用。对于而言,PGcancel对象是只读的,因此也可以从与操作PGconn对象的线程不同的线程中调用。 + - - PQcancelStartPQcancelStart - PQcancelPollPQcancelPoll + + + PQrequestCancelPQrequestCancel - 以非阻塞方式请求服务器放弃处理当前命令。 + 的一个已废弃变体。 -int PQcancelStart(PGcancelConn *cancelConn); - -PostgresPollingStatusType PQcancelPoll(PGcancelConn *cancelConn); +int PQrequestCancel(PGconn *conn); - 请求通过给定的PGcancelConn发送,该对象必须由创建。能够启动取消请求时返回 1,否则返回 0。若失败,可通过获取错误信息。 - - - - 如果PQcancelStart成功,下一阶段就是轮询libpq,使其继续推进取消连接序列。使用获取底层套接字描述符。(注意:不要假定该套接字在多次调用PQcancelPoll之间保持不变。)循环规则如下:如果PQcancelPoll(cancelConn)上一次返回PGRES_POLLING_READING,就等待该套接字准备好可读(由select()poll()或类似系统函数指示),然后再次调用PQcancelPoll(cancelConn)。反之,如果其上一次返回PGRES_POLLING_WRITING,就等待套接字准备好可写,然后再次调用。第一次迭代时,也就是尚未调用过PQcancelPoll(cancelConn)时,按其上次返回PGRES_POLLING_WRITING来处理。持续这一循环,直到PQcancelPoll(cancelConn)返回PGRES_POLLING_FAILED,表示连接过程失败,或者返回PGRES_POLLING_OK,表示取消请求已成功分派。 + 请求服务器放弃当前命令的处理。它直接作用于PGconn对象,失败时会把错误消息存储到PGconn对象中(可通过获取)。虽然功能相同,但这种方法在多线程程序或信号处理程序中并不安全,因为它可能覆盖PGconn中的错误消息,从而破坏当前连接上正在进行的操作。 + + + + - - 取消请求成功分派并不保证一定会产生效果。如果取消成功,被取消的命令会提前终止并返回一个错误结果;如果取消失败(例如服务器已经处理完该命令),则不会有任何可见结果。 - + - - 在连接期间的任意时刻,都可以通过调用检查取消连接的状态。如果返回CONNECTION_BAD,则取消过程失败;如果返回CONNECTION_OK,则取消请求已成功分派。这两种状态同样可以从前面描述的PQcancelPoll返回值中检测到。其他状态也可能仅在异步取消过程中出现,它们表示连接过程的当前阶段,并可能有助于向用户提供反馈。这些状态如下: + - - - CONNECTION_ALLOCATED - - - 等待调用以真正打开套接字。这是刚调用之后的连接状态。此时尚未开始与服务器建立连接。要真正开始发送取消请求,请使用。 - - - - - - CONNECTION_STARTED - - - 等待连接建立。 - - - - - - CONNECTION_MADE - - - 连接正常,等待发送。 - - - - - - CONNECTION_AWAITING_RESPONSE - - - 等待服务器响应。 - - - - - - CONNECTION_SSL_STARTUP - - - 协商 SSL 加密。 - - - - - - CONNECTION_GSS_STARTUP - - - 协商 GSS 加密。 - - - - - - 请注意,尽管这些常量会继续保留(为了保持兼容性),应用程序也绝不应依赖它们按某个特定顺序出现,甚至不应依赖它们一定会出现,或者依赖状态值始终属于这些已记录的取值之一。应用程序可以这样写: - -switch(PQcancelStatus(conn)) -{ - case CONNECTION_STARTED: - feedback = "Connecting..."; - break; - - case CONNECTION_MADE: - feedback = "Connected to server..."; - break; -. -. -. - default: - feedback = "Connecting..."; -} - - - - - 在使用PQcancelPoll时,连接参数connect_timeout会被忽略;是否已经过去过长时间应由应用程序自行判断。除此之外,PQcancelStart后接PQcancelPoll循环,等效于。 - - - - - - PQcancelStatusPQcancelStatus - - - - 返回取消连接的状态。 - -ConnStatusType PQcancelStatus(const PGcancelConn *cancelConn); - - - - - 该状态可以是多种取值之一。不过,在异步取消过程之外只能看到三种:CONNECTION_ALLOCATEDCONNECTION_OKCONNECTION_BAD。使用成功创建的PGcancelConn初始状态为CONNECTION_ALLOCATED。成功分派取消请求后状态为CONNECTION_OK;取消失败则表现为CONNECTION_BAD。处于 OK 状态时,会一直保持到调用。 - - - - 其他可能返回的状态代码,请参见条目。 - - - - 取消请求成功分派并不保证一定会产生效果。如果取消成功,被取消的命令会提前终止并返回一个错误结果;如果取消失败(例如服务器已经处理完该命令),则不会有任何可见结果。 - - - - - - PQcancelSocketPQcancelSocket - - - - 获取到服务器的取消连接套接字的文件描述符编号。 - -int PQcancelSocket(const PGcancelConn *cancelConn); - - - - - 有效描述符将大于等于 0;结果为 -1 表示当前没有打开到服务器的连接。对该PGcancelConn调用本节中的任意函数(PQcancelSocket自身除外)都可能改变这一状态。 - - - - - - - PQcancelErrorMessagePQcancelErrorMessage - error messagein PGcancelConn - - - - - 返回最近一次针对取消连接执行操作时生成的错误消息。 - -char *PQcancelErrorMessage(const PGcancelConn *cancelconn); - - - - - 几乎所有接受PGcancelConn参数的libpq函数在失败时都会为设置消息。按照libpq的约定,非空的结果可能包含多行,并带有结尾换行符。调用者不应直接释放该结果;当关联的PGcancelConn句柄传给时,它会被释放。也不应假定该结果字符串在多次对PGcancelConn结构执行操作之间保持不变。 - - - - - - PQcancelFinishPQcancelFinish - - - 关闭取消连接(如果它尚未完成发送取消请求),同时释放PGcancelConn对象使用的内存。 - -void PQcancelFinish(PGcancelConn *cancelConn); - - - - - 请注意,即使取消尝试失败(由指示),应用程序也应调用来释放PGcancelConn对象使用的内存。在调用后,不得再次使用该PGcancelConn指针。 - - - - - - PQcancelResetPQcancelReset - - - 重置PGcancelConn,以便将其重新用于新的取消连接。 - -void PQcancelReset(PGcancelConn *cancelConn); - - - - - 如果PGcancelConn当前正用于发送取消请求,则会关闭该连接。随后它会将PGcancelConn对象重新准备好,使其能够用于发送新的取消请求。 - - - - 这使得可以为一个PGconn创建一个PGcancelConn,并在原始PGconn的整个生命周期中重复使用它。 - - - - - - - - 发送取消请求的过时函数 - - - 这些函数代表较旧的取消请求发送方式。虽然它们仍然可以工作,但由于即使原始连接通过sslmodegssencmode要求加密,它们发送取消请求时也不会以加密方式进行,因此已被废弃。因此,强烈不建议在新代码中继续使用这些旧方法,已有代码也建议迁移到新的函数。 - - - - - PQgetCancelPQgetCancel - - - - 创建一个数据结构,其中包含使用取消命令所需的信息。 - -PGcancel *PQgetCancel(PGconn *conn); - - - - - 基于一个PGconn连接对象创建PGcancelPGcancel对象。如果给定的connNULL或无效连接,则返回NULLPGcancel是不透明结构体,不应由应用程序直接访问;它只能传给。 - - - - - - PQfreeCancelPQfreeCancel - - - - 释放由创建的数据结构。 - -void PQfreeCancel(PGcancel *cancel); - - - - - 释放先前由创建的数据对象。 - - - - - - PQcancelPQcancel - - - - 请求服务器放弃当前命令的处理。 - -int PQcancel(PGcancel *cancel, char *errbuf, int errbufsize); - - - - - 返回值为 1 表示取消请求成功发送,为 0 表示未成功发送。如果未成功发送,errbuf将填充解释性错误消息。errbuf必须是大小为errbufsize的字符数组(推荐大小为 256 字节)。 - - - - 取消请求成功分派并不保证一定会产生效果。如果取消成功,当前命令会提前终止并返回错误结果;如果取消失败(例如服务器已经处理完该命令),则不会有任何可见结果。 - - - - 如果errbuf是信号处理程序中的局部变量,则可以安全地从信号处理程序中调用。对于而言,PGcancel对象是只读的,因此也可以从与操作PGconn对象的线程不同的线程中调用。 - - - - - - - - PQrequestCancelPQrequestCancel - - - - 的一个已废弃变体。 - -int PQrequestCancel(PGconn *conn); - - - - - 请求服务器放弃当前命令的处理。它直接作用于PGconn对象,失败时会把错误消息存储到PGconn对象中(可通过获取)。虽然功能相同,但这种方法在多线程程序或信号处理程序中并不安全,因为它可能覆盖PGconn中的错误消息,从而破坏当前连接上正在进行的操作。 - - - - - - - - - - - 快速路径接口 + 快速路径接口 fast path @@ -5296,7 +4751,7 @@ typedef struct - 要传递NULL参数到函数,将参数结构体的len字段设置为-1;isintu 字段就不相关了。 + 要传递NULL参数到函数,将参数结构体的len字段设置为-1isintu 字段就不相关了。 @@ -5553,7 +5008,7 @@ int PQgetCopyData(PGconn *conn, 当async为真时(非零),将不会阻塞等待输入; 如果COPY仍在处理过程中并且没有可用的完整行,那么它将返回零 (在这种情况下等待读准备好,然后在再次调用之前,调用)。 - 当async为假(零)时,PQgetCopyData将阻塞,直到数据可用或者操作完成。 + 当async为假(零)时,将阻塞,直到数据可用或者操作完成。 @@ -5853,7 +5308,7 @@ void PQtrace(PGconn *conn, FILE *stream); - 每行包括:一个可选的时间戳,一个方向指示器(F表示从客户端到服务器的消息或B表示从服务器到客户端的消息),消息长度、消息类型、和消息内容。 + 每行包括:一个可选的时间戳,一个方向指示器(F表示从客户端到服务器的消息或B表示从服务器到客户端的消息),消息长度、消息类型、和消息内容。 非消息内容字段(时间戳、方向、长度和消息类型)由一个制表符分隔。 消息内容用空格分隔。 协议字符串用双引号括起来,而用作数据值的字符串用单引号括起来。 @@ -5994,27 +5449,7 @@ char *PQencryptPasswordConn(PGconn *conn, const char *passwd, const char *user, - - PQchangePasswordPQchangePassword - - - - 修改一个PostgreSQL密码。 - -PGresult *PQchangePassword(PGconn *conn, const char *user, const char *passwd); - - 此函数使用PQencryptPasswordConn构造并执行ALTER USER ... PASSWORD '...'命令,从而更改该用户的密码。它存在的原因与PQencryptPasswordConn相同,但更方便,因为它会替你同时构造并执行命令。传给的算法参数是NULL,因此会按照服务器的设置进行加密。 - - - - userpasswd参数分别是目标用户的 SQL 名称以及新的明文密码。 - - - 返回一个表示ALTER USER命令结果的PGresult指针;如果例程在发出任何命令前就失败,则返回空指针。应调用检查返回值中是否有错误(包括空指针的情况,此时它会返回PGRES_FATAL_ERROR)。可使用获取更多错误信息。 - - - @@ -6027,7 +5462,7 @@ PGresult *PQchangePassword(PGconn *conn, const char *user, const char *passwd); char *PQencryptPassword(const char *passwd, const char *user); - 的一个较老的已经被废弃的版本。其差别是不要求一个连接对象,并且总是用md5作为加密算法。 + 的旧版本,现已弃用。其差别是不需要连接对象,并且总是用md5作为加密算法。 @@ -6047,11 +5482,12 @@ PGresult *PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status); 这是libpq内部用于分配并初始化一个空PGresult对象的函数。 - 如果不能分配内存,那么这个函数返回NULL。 - 它也是可以对外使用的,因为一些应用认为它可以用于产生结果对象(特别是带有错误状态的对象)本身。 - 如果conn非空,并且status表示一个错误,那么指定连接的当前错误消息会被复制到PGresult中。 - 如果conn非空,那么连接中的任何已注册事件过程也会被复制到PGresult中(它们不会获得PGEVT_RESULTCREATE调用,但会看到)。 - 注意在该对象上最终应该调用,正如对libpq本身返回的PGresult对象所作的那样。 + 如果无法分配内存,此函数返回NULL。 + 将它导出供外部调用,是因为一些应用需要自行生成结果对象,特别是带有错误状态的对象。 + 如果conn非空,并且status表示错误,指定连接的当前错误消息会被复制到PGresult中。 + 此外,如果conn非空,连接中注册的所有事件过程也会被复制到PGresult中。 + (这些过程不会收到PGEVT_RESULTCREATE调用,但可参见。) + 注意,最终应对该对象调用,就像处理libpq自身返回的PGresult一样。 @@ -6411,8 +5847,8 @@ typedef struct - 结果创建事件是响应任何生成结果的查询执行函数而触发的,包括 - 。此事件只会在结果成功创建后触发。 + 任何生成结果的查询执行函数都会触发结果创建事件,其中包括。 + 只有成功创建结果后才会触发该事件。 typedef struct @@ -6422,11 +5858,9 @@ typedef struct } PGEventResultCreate; - 当接收到PGEVT_RESULTCREATE事件时, - 应将evtInfo指针转换为 - PGEventResultCreate *。 - conn是用于生成结果的连接。 - 这是初始化需要与结果关联的任何instanceData的理想位置。 + 收到PGEVT_RESULTCREATE事件时,应将evtInfo指针转换为PGEventResultCreate *。 + 其中,conn是用于生成结果的连接。 + 这是初始化需要与结果关联的instanceData的理想位置。 如果事件过程失败(返回零),那么该事件过程将在结果的剩余生命周期内被忽略; 也就是说,它将不会接收到针对此结果或从中复制的结果的 PGEVT_RESULTCOPYPGEVT_RESULTDESTROY事件。 @@ -6864,6 +6298,15 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough) + + + + PGREQUIREAUTH + + PGREQUIREAUTH的行为与连接参数相同。 + + + @@ -6976,6 +6419,15 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough) + + + + PGSSLCERTMODE + + PGSSLCERTMODE的行为与连接参数相同。 + + + @@ -7086,6 +6538,15 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough) + + + + PGGSSDELEGATION + + PGGSSDELEGATION的行为与连接参数相同。 + + + @@ -7125,6 +6586,15 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough) 下面的环境变量可用来为每一个PostgreSQL会话指定默认行为(为每一个用户或每一个数据库设置默认行为的方法还可见命令)。 + + + + PGLOADBALANCEHOSTS + + PGLOADBALANCEHOSTS的行为与连接参数相同。 + + + @@ -7195,20 +6665,15 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough) - 用户的主目录中的文件.pgpass可以包含密码, - 如果连接需要密码(且未指定其他密码)。在Microsoft Windows中, - 该文件的名称为%APPDATA%\postgresql\pgpass.conf - (其中%APPDATA%指用户配置文件中的应用数据子目录)。 - 或者,可以使用连接参数 - 或环境变量PGPASSFILE指定要使用的密码文件。 - + 用户主目录中的.pgpass文件可保存密码,供连接需要密码且尚未通过其他方式指定密码时使用。在 Microsoft Windows 上,文件名为%APPDATA%\postgresql\pgpass.conf(其中%APPDATA%指用户配置文件中的应用数据子目录)。也可以通过连接参数或环境变量PGPASSFILE指定要使用的密码文件。 + 这个文件应该包含下列格式的行: hostname:port:database:username:password - (你可以向该文件增加一个提醒:把上面的行复制到该文件并且在前面加上#)。前四个域的每一个都可以是文字值或者匹配任何东西的*。第一个匹配当前连接参数的行中的密码域将被使用(因此,在使用通配符时把更特殊的项放在前面)。如果一个条目需要包含:或者\,用\对该字符转义。如果指定了host连接参数,主机名字段会被匹配到host,否则如果指定了hostaddr参数则匹配到hostaddr,如果两者都没有给出,则会搜索主机名localhost。当连接是一个Unix域套接字连接并且host参数匹配libpq的默认套接字目录路径时,也会搜索主机名localhost。在一台备库上,值为replication的数据库字段匹配连接到主库的流复制连接。否则数据库字段的用途有限,因为用户对同一个集簇中的所有数据库都有相同的密码。 + (你可以向该文件增加一个提醒:把上面的行复制到该文件并且在前面加上#)。前四个字段的每一个都可以是字面值或者匹配任何东西的*。第一个匹配当前连接参数的行中的密码字段将被使用(因此,在使用通配符时把更特殊的项放在前面)。如果一个条目需要包含:或者\,用\对该字符转义。如果指定了host连接参数,主机名字段会被匹配到host,否则如果指定了hostaddr参数则匹配到hostaddr,如果两者都没有给出,则会搜索主机名localhost。当连接是一个Unix域套接字连接并且host参数匹配libpq的默认套接字目录路径时,也会搜索主机名localhost。在一台备库上,值为replication的数据库字段匹配连接到主库的流复制连接。否则数据库字段的用途有限,因为用户对同一个集簇中的所有数据库都有相同的密码。 @@ -7645,7 +7110,7 @@ ldap://ldap.acme.com/cn=dbserver,cn=hosts?pgconnectinfo?base?(objectclass=*) 构建时带有SSL支持,您应该调用告诉libpq libssl和/或libcrypto库已被您的应用程序初始化,以便 libpq不会再初始化这些库。 - 但是,当使用OpenSSL版本1.1.0或更高版本时,重复初始化不再成问题。 + 但是,当使用OpenSSL版本1.1.0或更高版本时,无需这样做,因为重复初始化不再成问题。 @@ -7669,7 +7134,7 @@ void PQinitOpenSSL(int do_ssl, int do_crypto); - 如果你的应用使用并且初始化OpenSSL或者它的底层libcrypto库,你必须在第一次打开数据库连接前以合适的非零参数调用这个函数。 + 如果你的应用使用并且初始化OpenSSL或者它的底层libcrypto库,你必须在第一次打开数据库连接前调用这个函数,并把相应参数设为零。 同时要确保在打开一个数据库连接前已经完成了初始化。 @@ -7702,240 +7167,17 @@ void PQinitSSL(int do_ssl); - - OAuth 支持 - - - libpq通过一个可选模块实现了对 OAuth v2 Device Authorization 客户端流程的支持,该流程记录在 - RFC 8628中。关于如何启用内置的 Device Authorization 流程,请参见安装文档。 - - - 当启用支持并安装该可选模块后,如果服务器在认证期间请求 Bearer 令牌,libpq默认会使用内置流程。即使运行客户端应用的系统没有可用的 Web 浏览器,例如通过SSH运行客户端时,也可以使用这一流程。 - - - 内置流程默认会打印一个需要访问的 URL 以及一个要在该处输入的用户代码: - -$ psql 'dbname=postgres oauth_issuer=https://example.com oauth_client_id=...' -Visit https://example.com/device and enter the code: ABCD-EFGH - - (这一提示可以被定制。)然后,用户将在其 OAuth 提供者处登录,提供者会询问是否允许 libpq 和服务器代表其执行操作。在继续之前,始终应当仔细检查显示的 URL 和权限,确认它们符合预期。不要向不受信任的第三方授予权限。 - - - 客户端应用可以实现自己的流程,以定制交互方式以及与应用程序的集成。关于如何向libpq添加自定义流程的更多信息,请参见。 - - - 要使某个 OAuth 客户端流程可用,连接字符串至少必须包含。(这些设置由你所在组织的 OAuth 提供者决定。)此外,内置流程还要求 OAuth 授权服务器发布一个设备授权端点。 - - - - - 当前 Windows 上尚不支持内置的 Device Authorization 流程。不过,仍然可以实现自定义客户端流程。 - - - - - Authdata 钩子 - - - 客户端可以通过下面的钩子 API 修改或替换 OAuth 流程的行为: - - - - PQsetAuthDataHookPQsetAuthDataHook - - - - 设置PGauthDataHook,以覆盖libpq对其 OAuth 客户端流程一个或多个方面的处理。 - -void PQsetAuthDataHook(PQauthDataHook_type hook); - - 如果hookNULL,则会重新安装默认处理器。否则,应用程序需要传入一个回调函数指针,其签名如下: - -int hook_fn(PGauthData type, PGconn *conn, void *data); - - 当应用程序需要执行某个动作时,libpq会调用该回调。type描述所提出的请求,conn是正在认证的连接句柄,而data指向该请求特有的元数据。这个指针所指内容由type决定;支持的列表见。 - - - 钩子可以串联起来,以支持协作式和/或回退式行为。一般来说,钩子实现应检查传入的type(以及可能的请求元数据和/或当前conn的设置),以决定是否处理某一项 authdata。如果不处理,则应把请求委托给链中的前一个钩子(可通过PQgetAuthDataHook获取)。 - - - 返回一个大于零的整数表示成功。返回负整数表示发生错误并放弃此次连接尝试。(值零保留给默认实现。) - - - - - - PQgetAuthDataHookPQgetAuthDataHook - - - - 获取当前的PGauthDataHook值。 - -PQauthDataHook_type PQgetAuthDataHook(void); - - 在初始化阶段(即首次调用PQsetAuthDataHook之前),该函数会返回PQdefaultAuthDataHook。 - - - - - - - - 钩子类型 - - 下面定义了这些PGauthData类型及其对应的data结构: - - - - - PQAUTHDATA_PROMPT_OAUTH_DEVICE - PQAUTHDATA_PROMPT_OAUTH_DEVICE - - - - 在内置的设备授权客户端流程期间,替换默认的用户提示。data指向一个PGpromptOAuthDevice实例: - -typedef struct _PGpromptOAuthDevice -{ - const char *verification_uri; /* verification URI to visit */ - const char *user_code; /* user code to enter */ - const char *verification_uri_complete; /* optional combination of URI and - * code, or NULL */ - int expires_in; /* seconds until user code expires */ -} PGpromptOAuthDevice; - - - - 可被包含在libpq中的 OAuth Device Authorization 流程要求最终用户使用浏览器访问一个 URL,然后输入一个代码,以允许libpq代表其连接到服务器。默认提示只是把verification_uriuser_code打印到标准错误。替换实现可以按任意偏好的方式展示这些信息,例如使用 GUI。 - - - 该回调只会在内置设备授权流程中被调用。如果应用程序安装了自定义 OAuth 流程,或者libpq构建时未启用内置流程支持,则不会使用这种 authdata 类型。 - - - 如果提供了非空的verification_uri_complete,则可以选择把它用于非文本形式的验证(例如显示二维码)。在这种情况下,仍应向最终用户显示 URL 和用户代码,因为该代码需要由提供者手工确认,而 URL 也使得用户在无法使用非文本方式时仍可继续。更多信息见 - RFC 8628 第 3.3.1 节。 - - - - - - - PQAUTHDATA_OAUTH_BEARER_TOKEN - PQAUTHDATA_OAUTH_BEARER_TOKEN - - - - 添加一个自定义流程实现;如果内置流程已安装,则用它替换内置流程。该钩子应当要么直接返回一个适用于当前 user/issuer/scope 组合的 Bearer 令牌(如果能在不阻塞的情况下获得),要么设置一个异步回调来获取令牌。 - - - data指向一个PGoauthBearerRequest实例,应该由实现填充: - -typedef struct PGoauthBearerRequest -{ - /* Hook inputs (constant across all calls) */ - const char *openid_configuration; /* OIDC discovery URL */ - const char *scope; /* required scope(s), or NULL */ - - /* Hook outputs */ - - /* - * Callback implementing a custom asynchronous OAuth flow. The signature is - * platform-dependent: PQ_SOCKTYPE is SOCKET on Windows, and int everywhere - * else. - */ - PostgresPollingStatusType (*async) (PGconn *conn, - struct PGoauthBearerRequest *request, - PQ_SOCKTYPE *altsock); - /* Callback to clean up custom allocations. */ - void (*cleanup) (PGconn *conn, struct PGoauthBearerRequest *request); - - char *token; /* acquired Bearer token */ - void *user; /* hook-defined allocated data */ -} PGoauthBearerRequest; - - - - libpq会向该钩子提供两项信息:openid_configuration包含描述授权服务器所支持流程的 OAuth 发现文档 URL,而scope包含访问服务器所需的 OAuth scope 列表(以空格分隔,可以为空)。两者中的任意一个或两个都可能为NULL,表示无法发现该信息。(在这种情况下,实现可以通过其他预先配置的知识来确定要求,或者选择失败。) - - - 该钩子的最终输出是token,它必须指向一个可在该连接上使用的有效 Bearer 令牌。(该令牌应由所指定的发行者签发,并持有所请求的 scope,否则连接会被服务器的验证器模块拒绝。)分配得到的令牌字符串必须在libpq完成连接之前始终有效;该钩子应设置cleanup回调,以便在libpq不再需要该令牌时调用。 - - - 如果某个实现无法在首次调用钩子时立即产生token,则应设置async回调,以处理与授权服务器之间的非阻塞通信。 - - - 在PQAUTHDATA_OAUTH_BEARER_TOKEN钩子回调中执行阻塞操作,会干扰诸如PQconnectPoll之类的非阻塞连接 API,并阻止并发连接继续推进。那些只使用同步连接原语(例如PQconnectdb)的应用程序,可以在钩子中同步获取令牌,而不是实现async回调,但这样它们必然一次只能处理一个连接。 - - - 从钩子返回后,将立即调用该回调以启动流程。当回调在不阻塞的情况下无法继续推进时,它应在设置*altsock后返回PGRES_POLLING_READINGPGRES_POLLING_WRITING,其中*altsock是当可以再次取得进展时会被标记为可读/可写的文件描述符。(然后,这个描述符会通过PQsocket()提供给顶层轮询循环。)当流程完成时,在设置好token之后返回PGRES_POLLING_OK;如果失败,则返回PGRES_POLLING_FAILED。 - - - 实现可能希望在多次调用asynccleanup回调之间保存额外的数据用于记账。为此提供了user指针;libpq不会触碰其内容,应用程序可以按自己的需要使用它。(记得在令牌清理时释放相关分配。) - - - - - - - - - - 调试与开发者设置 - - - 通过设置环境变量PGOAUTHDEBUG=UNSAFE,可以启用一种危险的调试模式。该功能仅用于便于本地开发和测试。它会做一些你绝不会希望生产系统去做的事情: - - - - - 允许在与 OAuth 提供者交互期间使用未加密的 HTTP - - - - - 允许使用环境变量PGOAUTHCAFILE完全替换系统受信任的 CA 列表 - - - - - 在 OAuth 流程期间把 HTTP 流量(其中包含多个关键机密)打印到标准错误 - - - - - 允许使用零秒重试间隔,这可能导致客户端忙等并无谓地消耗 CPU - - - - - - - 不要把 OAuth 流量的输出分享给第三方。它包含可被用来攻击你的客户端和服务器的机密。 - - - - 在线程化程序中的行为 - threads - with libpq + 线程 + 用于 libpq - - 从版本 17 起,libpq始终是可重入且线程安全的。不过仍有一条限制:不得有两个线程同时操作同一个PGconn对象。特别是,不能从不同线程通过同一个连接对象并发发出命令。(如果需要并发运行命令,请使用多个连接。) - - - - PGresult对象在创建后通常是只读的,因此可以在线程之间自由传递。不过,如果你使用中描述的任何会修改PGresult的函数,则需要自行避免对同一个PGresult执行并发操作。 - - - - 在较早版本中,libpq能否提供线程支持取决于编译选项。下面这个函数允许查询libpq的线程安全状态: - + libpq 默认是可重入且线程安全的。编译应用程序代码时,可能需要使用特殊的编译器命令行选项。有关如何构建支持线程的应用程序,请参阅系统文档,或查看 src/Makefile.global 中的 PTHREAD_CFLAGSPTHREAD_LIBS。以下函数可用于查询 libpq 的线程安全状态: @@ -7950,22 +7192,22 @@ int PQisthreadsafe(); - 如果libpq是线程安全的则返回 1,否则返回 0。在版本 17 及以上始终返回 1。 + 如果libpq是线程安全的则返回 1,否则返回 0。 - - 已废弃的函数不是线程安全的,不应在多线程程序中使用。可以用替代;可以用替代。 - + 线程使用的一项限制是:两个线程不能同时操作同一个 PGconn 对象。尤其不能通过同一个连接对象从不同线程并发发出命令。(如果需要并发执行命令,请使用多个连接。) - 如果你在应用程序中使用 Kerberos(除了libpq内部之外),则需要在 Kerberos 调用周围加锁,因为 Kerberos 函数不是线程安全的。可参考libpq源代码中的PQregisterThreadLock函数,它提供了一种在libpq与应用程序之间协作加锁的方法。 + PGresult对象在创建后通常是只读的,因此可以在线程之间自由传递。不过,如果你使用中描述的任何会修改PGresult的函数,则需要自行避免对同一个PGresult执行并发操作。 + 已弃用的 函数不是线程安全的,不应在多线程程序中使用。可以用 替代 ,用 替代 + - 同样地,如果你在应用程序中使用Curl,并且在启动新线程之前还没有先对 libcurl 进行全局初始化,那么你也需要通过PQregisterThreadLock协作地为任何可能初始化 libcurl 的代码加锁。对于支持线程安全初始化的较新版本Curl,这一限制已被解除;这类构建可以通过其版本元数据中声明的threadsafe特性识别出来。 + 如果你在应用程序中使用 Kerberos(除了libpq内部之外),则需要在 Kerberos 调用周围加锁,因为 Kerberos 函数不是线程安全的。可参考libpq源代码中的PQregisterThreadLock函数,它提供了一种在libpq与应用程序之间协作加锁的方法。 diff --git a/zh/16/logical-replication.sgml b/zh/16/logical-replication.sgml index 2e7d9988..d1164807 100644 --- a/zh/16/logical-replication.sgml +++ b/zh/16/logical-replication.sgml @@ -93,6 +93,26 @@ )。 + + 已发布的表若要复制 UPDATEDELETE + 操作,必须配置复制标识,以便在订阅端识别应更新或删除的行。 + 默认情况下,如果存在主键,则主键就是复制标识。也可以将另一个唯一索引 + (满足某些附加要求)设置为复制标识。如果表没有合适的键,可将复制标识设为 + FULL,表示整行作为键。指定复制标识 + FULL 时,订阅端在查找行时可以使用索引。 + 候选索引必须是 btree、非部分索引,且最左索引字段必须是引用已发布表 + 列的列(而非表达式)。这些非唯一索引属性的限制,遵循了主键的一部分限制规则。 + 如果没有合适索引,订阅端查找会非常低效,因此复制标识 + FULL 仅应在没有其他方案时作为后备选项。如果发布端设置的是非 + FULL 的复制标识,则订阅端也必须设置由相同或更少列组成的 + 复制标识。关于如何设置复制标识, + 见 。 + 如果一个没有复制标识的表被加入一个复制 UPDATE 或 + DELETE 操作的发布,那么后续的 UPDATE 或 + DELETE 操作将在发布端引发错误。 + 无论复制标识如何,INSERT 操作都可以继续执行。 + + 每个发布都可以有多个订阅者。 @@ -110,48 +130,6 @@ 都是事务性的,因此事务提交后,表会在正确的快照点开始或停止复制。 - - 复制标识 - - - 已发布的表若要复制 UPDATE 和 - DELETE 操作,必须配置 - 复制标识,以便在订阅端识别应更新或删除的行。 - - - - 默认情况下,如果存在主键,则主键就是复制标识。也可以将另一个唯一索引 - (满足某些附加要求)设置为复制标识。如果表没有合适的键,可将复制标识设为 - FULL,表示整行作为键。指定复制标识 - FULL 时,订阅端在查找行时可以使用索引。 - 候选索引必须是 btree 或 hash、非部分索引,且最左索引字段必须是引用已发布表 - 列的列(而非表达式)。这些非唯一索引属性的限制,遵循了主键的一部分限制规则。 - 如果没有合适索引,订阅端查找会非常低效,因此复制标识 - FULL 仅应在没有其他方案时作为后备选项。 - - - - 如果发布端设置的是非 FULL 的复制标识,则订阅端也必须设置 - 由相同或更少列组成的复制标识。 - - - - 对于复制标识定义为 NOTHING、无主键时的 - DEFAULT,或使用已删除索引的 USING INDEX - 的表,如果将其包含在复制 UPDATE 或 - DELETE 的发布中,则不支持这些操作。尝试执行时会在发布端报错。 - - - - 无论复制标识如何,INSERT 操作都可以继续执行。 - - - - 关于如何设置复制标识,见 - ALTER TABLE...REPLICA IDENTITY。 - - - @@ -219,7 +197,7 @@ bigint 列。目标表还可包含发布表未提供的额外列,这些列会填充为目标 表定义中的默认值。不过,二进制格式逻辑复制限制更严格。详见 CREATE SUBSCRIPTION 的 - binary + binary 选项。 @@ -230,7 +208,7 @@ 如前所述,每个(活动)订阅都从远端(发布侧)的一个复制槽接收变更。 - 额外的表同步槽通常是临时的,由系统内部创建用于执行初始表同步,在不再需要时 + 额外的表同步槽通常只会短暂存在,由系统内部创建用于执行初始表同步,在不再需要时 自动删除。这些表同步槽的名称是自动生成的: pg_%u_sync_%u_%llu (参数分别为:订阅 oid、 @@ -238,9 +216,9 @@ 通常,远端复制槽会在使用 - CREATE SUBSCRIPTION + CREATE SUBSCRIPTION 创建订阅时自动创建,并在使用 - DROP SUBSCRIPTION + DROP SUBSCRIPTION 删除订阅时自动删除。但在某些场景下,分别操作订阅与底层复制槽会更有用或更必要。 常见场景如下: @@ -265,7 +243,7 @@ 删除订阅时希望保留复制槽。这在将订阅者数据库迁移到其他主机并从那里激活时 很有用。此时应在尝试删除订阅前,使用 - ALTER SUBSCRIPTION + ALTER SUBSCRIPTION 将槽与订阅解除关联。 @@ -290,60 +268,76 @@ 在发布端创建一些测试表。 -/* pub # */ CREATE TABLE t1(a int, b text, PRIMARY KEY(a)); -/* pub # */ CREATE TABLE t2(c int, d text, PRIMARY KEY(c)); -/* pub # */ CREATE TABLE t3(e int, f text, PRIMARY KEY(e)); +test_pub=# CREATE TABLE t1(a int, b text, PRIMARY KEY(a)); +CREATE TABLE +test_pub=# CREATE TABLE t2(c int, d text, PRIMARY KEY(c)); +CREATE TABLE +test_pub=# CREATE TABLE t3(e int, f text, PRIMARY KEY(e)); +CREATE TABLE 在订阅端创建同样的表。 -/* sub # */ CREATE TABLE t1(a int, b text, PRIMARY KEY(a)); -/* sub # */ CREATE TABLE t2(c int, d text, PRIMARY KEY(c)); -/* sub # */ CREATE TABLE t3(e int, f text, PRIMARY KEY(e)); +test_sub=# CREATE TABLE t1(a int, b text, PRIMARY KEY(a)); +CREATE TABLE +test_sub=# CREATE TABLE t2(c int, d text, PRIMARY KEY(c)); +CREATE TABLE +test_sub=# CREATE TABLE t3(e int, f text, PRIMARY KEY(e)); +CREATE TABLE 在发布端向表中插入数据。 -/* pub # */ INSERT INTO t1 VALUES (1, 'one'), (2, 'two'), (3, 'three'); -/* pub # */ INSERT INTO t2 VALUES (1, 'A'), (2, 'B'), (3, 'C'); -/* pub # */ INSERT INTO t3 VALUES (1, 'i'), (2, 'ii'), (3, 'iii'); +test_pub=# INSERT INTO t1 VALUES (1, 'one'), (2, 'two'), (3, 'three'); +INSERT 0 3 +test_pub=# INSERT INTO t2 VALUES (1, 'A'), (2, 'B'), (3, 'C'); +INSERT 0 3 +test_pub=# INSERT INTO t3 VALUES (1, 'i'), (2, 'ii'), (3, 'iii'); +INSERT 0 3 为这些表创建发布。发布 pub2pub3a 禁用了部分 - publish + publish 操作。发布 pub3b 使用了行过滤器(见 )。 - 5); -]]> + +test_pub=# CREATE PUBLICATION pub1 FOR TABLE t1; +CREATE PUBLICATION +test_pub=# CREATE PUBLICATION pub2 FOR TABLE t2 WITH (publish = 'truncate'); +CREATE PUBLICATION +test_pub=# CREATE PUBLICATION pub3a FOR TABLE t3 WITH (publish = 'truncate'); +CREATE PUBLICATION +test_pub=# CREATE PUBLICATION pub3b FOR TABLE t3 WHERE (e > 5); +CREATE PUBLICATION + 为这些发布创建订阅。订阅 sub3 同时订阅 pub3apub3b。默认情况下所有订阅都会复制 初始数据。 -/* sub # */ CREATE SUBSCRIPTION sub1 -/* sub - */ CONNECTION 'host=localhost dbname=test_pub application_name=sub1' -/* sub - */ PUBLICATION pub1; -/* sub # */ CREATE SUBSCRIPTION sub2 -/* sub - */ CONNECTION 'host=localhost dbname=test_pub application_name=sub2' -/* sub - */ PUBLICATION pub2; -/* sub # */ CREATE SUBSCRIPTION sub3 -/* sub - */ CONNECTION 'host=localhost dbname=test_pub application_name=sub3' -/* sub - */ PUBLICATION pub3a, pub3b; +test_sub=# CREATE SUBSCRIPTION sub1 +test_sub-# CONNECTION 'host=localhost dbname=test_pub application_name=sub1' +test_sub-# PUBLICATION pub1; +CREATE SUBSCRIPTION +test_sub=# CREATE SUBSCRIPTION sub2 +test_sub-# CONNECTION 'host=localhost dbname=test_pub application_name=sub2' +test_sub-# PUBLICATION pub2; +CREATE SUBSCRIPTION +test_sub=# CREATE SUBSCRIPTION sub3 +test_sub-# CONNECTION 'host=localhost dbname=test_pub application_name=sub3' +test_sub-# PUBLICATION pub3a, pub3b; +CREATE SUBSCRIPTION 注意,无论发布的 publish 操作如何,初始表数据都会被复制。 -/* sub # */ SELECT * FROM t1; +test_sub=# SELECT * FROM t1; a | b ---+------- 1 | one @@ -351,7 +345,7 @@ 3 | three (3 rows) -/* sub # */ SELECT * FROM t2; +test_sub=# SELECT * FROM t2; c | d ---+--- 1 | A @@ -365,7 +359,7 @@ pub3a 没有行过滤器,所以复制后的表 t3 会包含所有行,即使它们不匹配发布 pub3b 的行过滤器。 -/* sub # */ SELECT * FROM t3; +test_sub=# SELECT * FROM t3; e | f ---+----- 1 | i @@ -377,15 +371,18 @@ 在发布端向表继续插入数据。 -/* pub # */ INSERT INTO t1 VALUES (4, 'four'), (5, 'five'), (6, 'six'); -/* pub # */ INSERT INTO t2 VALUES (4, 'D'), (5, 'E'), (6, 'F'); -/* pub # */ INSERT INTO t3 VALUES (4, 'iv'), (5, 'v'), (6, 'vi'); +test_pub=# INSERT INTO t1 VALUES (4, 'four'), (5, 'five'), (6, 'six'); +INSERT 0 3 +test_pub=# INSERT INTO t2 VALUES (4, 'D'), (5, 'E'), (6, 'F'); +INSERT 0 3 +test_pub=# INSERT INTO t3 VALUES (4, 'iv'), (5, 'v'), (6, 'vi'); +INSERT 0 3 现在发布端数据如下: -/* pub # */ SELECT * FROM t1; +test_pub=# SELECT * FROM t1; a | b ---+------- 1 | one @@ -396,7 +393,7 @@ 6 | six (6 rows) -/* pub # */ SELECT * FROM t2; +test_pub=# SELECT * FROM t2; c | d ---+--- 1 | A @@ -407,7 +404,7 @@ 6 | F (6 rows) -/* pub # */ SELECT * FROM t3; +test_pub=# SELECT * FROM t3; e | f ---+----- 1 | i @@ -422,10 +419,10 @@ 注意在常规复制阶段会使用相应的 publish 操作。 这意味着发布 pub2pub3a 不会复制 - INSERT。另外,发布 pub3b 只会复制与其 + INSERT。另外,发布 pub3b 只会复制与 pub3b 的 行过滤器匹配的数据。现在订阅端数据如下: -/* sub # */ SELECT * FROM t1; +test_sub=# SELECT * FROM t1; a | b ---+------- 1 | one @@ -436,7 +433,7 @@ 6 | six (6 rows) -/* sub # */ SELECT * FROM t2; +test_sub=# SELECT * FROM t2; c | d ---+--- 1 | A @@ -444,7 +441,7 @@ 3 | C (3 rows) -/* sub # */ SELECT * FROM t3; +test_sub=# SELECT * FROM t3; e | f ---+----- 1 | i @@ -468,7 +465,8 @@ 首先,创建示例所需的发布。 -/* pub # */ CREATE PUBLICATION pub1 FOR ALL TABLES; +test_pub=# CREATE PUBLICATION pub1 FOR ALL TABLES; +CREATE PUBLICATION 示例 1:订阅指定 connect = false @@ -479,12 +477,13 @@ 创建订阅。 -/* sub # */ CREATE SUBSCRIPTION sub1 -/* sub - */ CONNECTION 'host=localhost dbname=test_pub' -/* sub - */ PUBLICATION pub1 -/* sub - */ WITH (connect=false); +test_sub=# CREATE SUBSCRIPTION sub1 +test_sub-# CONNECTION 'host=localhost dbname=test_pub' +test_sub-# PUBLICATION pub1 +test_sub-# WITH (connect=false); WARNING: subscription was created, but is not connected HINT: To initiate replication, you must manually create the replication slot, enable the subscription, and refresh the subscription. +CREATE SUBSCRIPTION @@ -492,7 +491,7 @@ HINT: To initiate replication, you must manually create the replication slot, e 在发布端手工创建槽。由于 CREATE SUBSCRIPTION 时未指定名称, 要创建的槽名与订阅名相同,例如 "sub1"。 -/* pub # */ SELECT * FROM pg_create_logical_replication_slot('sub1', 'pgoutput'); +test_pub=# SELECT * FROM pg_create_logical_replication_slot('sub1', 'pgoutput'); slot_name | lsn -----------+----------- sub1 | 0/19404D0 @@ -503,8 +502,10 @@ HINT: To initiate replication, you must manually create the replication slot, e 在订阅端完成订阅激活。之后 pub1 的表将开始复制。 -/* sub # */ ALTER SUBSCRIPTION sub1 ENABLE; -/* sub # */ ALTER SUBSCRIPTION sub1 REFRESH PUBLICATION; +test_sub=# ALTER SUBSCRIPTION sub1 ENABLE; +ALTER SUBSCRIPTION +test_sub=# ALTER SUBSCRIPTION sub1 REFRESH PUBLICATION; +ALTER SUBSCRIPTION @@ -512,19 +513,20 @@ HINT: To initiate replication, you must manually create the replication slot, e 示例 2:订阅指定 connect = false,并同时指定 - slot_name + slot_name 选项。 创建订阅。 -/* sub # */ CREATE SUBSCRIPTION sub1 -/* sub - */ CONNECTION 'host=localhost dbname=test_pub' -/* sub - */ PUBLICATION pub1 -/* sub - */ WITH (connect=false, slot_name='myslot'); +test_sub=# CREATE SUBSCRIPTION sub1 +test_sub-# CONNECTION 'host=localhost dbname=test_pub' +test_sub-# PUBLICATION pub1 +test_sub-# WITH (connect=false, slot_name='myslot'); WARNING: subscription was created, but is not connected HINT: To initiate replication, you must manually create the replication slot, enable the subscription, and refresh the subscription. +CREATE SUBSCRIPTION @@ -532,7 +534,7 @@ HINT: To initiate replication, you must manually create the replication slot, e 在发布端使用与 CREATE SUBSCRIPTION 指定一致的名称手工创建槽, 例如 "myslot"。 -/* pub # */ SELECT * FROM pg_create_logical_replication_slot('myslot', 'pgoutput'); +test_pub=# SELECT * FROM pg_create_logical_replication_slot('myslot', 'pgoutput'); slot_name | lsn -----------+----------- myslot | 0/19059A0 @@ -543,8 +545,10 @@ HINT: To initiate replication, you must manually create the replication slot, e 在订阅端,剩余激活步骤与前例相同。 -/* sub # */ ALTER SUBSCRIPTION sub1 ENABLE; -/* sub # */ ALTER SUBSCRIPTION sub1 REFRESH PUBLICATION; +test_sub=# ALTER SUBSCRIPTION sub1 ENABLE; +ALTER SUBSCRIPTION +test_sub=# ALTER SUBSCRIPTION sub1 REFRESH PUBLICATION; +ALTER SUBSCRIPTION @@ -558,17 +562,18 @@ HINT: To initiate replication, you must manually create the replication slot, e 创建订阅。设置 slot_name = NONE 时,还需要设置 enabled = falsecreate_slot = false -/* sub # */ CREATE SUBSCRIPTION sub1 -/* sub - */ CONNECTION 'host=localhost dbname=test_pub' -/* sub - */ PUBLICATION pub1 -/* sub - */ WITH (slot_name=NONE, enabled=false, create_slot=false); +test_sub=# CREATE SUBSCRIPTION sub1 +test_sub-# CONNECTION 'host=localhost dbname=test_pub' +test_sub-# PUBLICATION pub1 +test_sub-# WITH (slot_name=NONE, enabled=false, create_slot=false); +CREATE SUBSCRIPTION 在发布端使用任意名称手工创建槽,例如 "myslot"。 -/* pub # */ SELECT * FROM pg_create_logical_replication_slot('myslot', 'pgoutput'); +test_pub=# SELECT * FROM pg_create_logical_replication_slot('myslot', 'pgoutput'); slot_name | lsn -----------+----------- myslot | 0/1905930 @@ -579,15 +584,18 @@ HINT: To initiate replication, you must manually create the replication slot, e 在订阅端,将订阅关联到刚创建的槽名。 -/* sub # */ ALTER SUBSCRIPTION sub1 SET (slot_name='myslot'); +test_sub=# ALTER SUBSCRIPTION sub1 SET (slot_name='myslot'); +ALTER SUBSCRIPTION 剩余的订阅激活步骤与前例相同。 -/* sub # */ ALTER SUBSCRIPTION sub1 ENABLE; -/* sub # */ ALTER SUBSCRIPTION sub1 REFRESH PUBLICATION; +test_sub=# ALTER SUBSCRIPTION sub1 ENABLE; +ALTER SUBSCRIPTION +test_sub=# ALTER SUBSCRIPTION sub1 REFRESH PUBLICATION; +ALTER SUBSCRIPTION @@ -614,7 +622,7 @@ HINT: To initiate replication, you must manually create the replication slot, e 行过滤器会在发布更改之前应用。如果行过滤器求值为falseNULL, 则该行不会被复制。WHERE子句表达式会使用复制连接所用的同一角色来求值(即在 - CONNECTION + CONNECTION 子句中指定的角色)。行过滤器对TRUNCATE命令没有影响。 @@ -703,7 +711,7 @@ HINT: To initiate replication, you must manually create the replication slot, e 分区表 - 如果发布包含分区表,则发布参数publish_via_partition_root确定使用哪个行过滤器。 + 如果发布包含分区表,则发布参数publish_via_partition_root确定使用哪个行过滤器。 如果publish_via_partition_roottrue,则使用根分区表的行过滤器。 否则,如果publish_via_partition_rootfalse(默认值),则使用各个分区的行过滤器。 @@ -728,7 +736,7 @@ HINT: To initiate replication, you must manually create the replication slot, e - 由于初始数据同步在复制现有表数据时不会考虑publish参数, + 由于初始数据同步在复制现有表数据时不会考虑publish参数, 因此有些使用 DML 时本不会复制的行,也可能在此阶段被复制。参见 ,并查看 中的示例。 @@ -750,7 +758,7 @@ HINT: To initiate replication, you must manually create the replication slot, e 组合多个行过滤器 - 如果某个订阅包含多个发布,而其中同一张表针对相同的publish操作使用了不同的行过滤器, + 如果某个订阅包含多个发布,而其中同一张表针对相同的publish操作使用了不同的行过滤器, 那么这些表达式会按 OR 组合,因此满足任意一个表达式的行都会被复制。这意味着,如果出现以下任一情况,那么同一张表上的其他所有行过滤器都会变得多余: @@ -760,12 +768,12 @@ HINT: To initiate replication, you must manually create the replication slot, e - 其中某个发布是使用FOR ALL TABLES创建的。该子句不允许行过滤器。 + 其中某个发布是使用FOR ALL TABLES创建的。该子句不允许行过滤器。 - 其中某个发布是使用FOR TABLES IN SCHEMA创建的,并且该表属于所引用的模式。该子句不允许行过滤器。 + 其中某个发布是使用FOR TABLES IN SCHEMA创建的,并且该表属于所引用的模式。该子句不允许行过滤器。 @@ -780,54 +788,60 @@ HINT: To initiate replication, you must manually create the replication slot, e 创建一些表,供下面的示例使用。 -/* pub # */ CREATE TABLE t1(a int, b int, c text, PRIMARY KEY(a,c)); -/* pub # */ CREATE TABLE t2(d int, e int, f int, PRIMARY KEY(d)); -/* pub # */ CREATE TABLE t3(g int, h int, i int, PRIMARY KEY(g)); +test_pub=# CREATE TABLE t1(a int, b int, c text, PRIMARY KEY(a,c)); +CREATE TABLE +test_pub=# CREATE TABLE t2(d int, e int, f int, PRIMARY KEY(d)); +CREATE TABLE +test_pub=# CREATE TABLE t3(g int, h int, i int, PRIMARY KEY(g)); +CREATE TABLE 创建一些发布。发布p1包含一个表(t1),该表带有行过滤器。 发布p2包含两个表,其中t1没有行过滤器,而t2带有行过滤器。 发布p3包含两个表,并且这两个表都带有行过滤器。 - 5 AND c = 'NSW'); -/* pub # */ CREATE PUBLICATION p2 FOR TABLE t1, t2 WHERE (e = 99); -/* pub # */ CREATE PUBLICATION p3 FOR TABLE t2 WHERE (d = 10), t3 WHERE (g = 10); -]]> + +test_pub=# CREATE PUBLICATION p1 FOR TABLE t1 WHERE (a > 5 AND c = 'NSW'); +CREATE PUBLICATION +test_pub=# CREATE PUBLICATION p2 FOR TABLE t1, t2 WHERE (e = 99); +CREATE PUBLICATION +test_pub=# CREATE PUBLICATION p3 FOR TABLE t2 WHERE (d = 10), t3 WHERE (g = 10); +CREATE PUBLICATION + psql可用于显示每个发布的行过滤表达式(如果已定义)。 - +test_pub=# \dRp+ + Publication p1 + Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root +----------+------------+---------+---------+---------+-----------+---------- + postgres | f | t | t | t | t | f Tables: "public.t1" WHERE ((a > 5) AND (c = 'NSW'::text)) - Publication p2 - Owner | All tables | Inserts | Updates | Deletes | Truncates | Generated columns | Via root -----------+------------+---------+---------+---------+-----------+-------------------+---------- - postgres | f | t | t | t | t | none | f + Publication p2 + Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root +----------+------------+---------+---------+---------+-----------+---------- + postgres | f | t | t | t | t | f Tables: "public.t1" "public.t2" WHERE (e = 99) - Publication p3 - Owner | All tables | Inserts | Updates | Deletes | Truncates | Generated columns | Via root -----------+------------+---------+---------+---------+-----------+-------------------+---------- - postgres | f | t | t | t | t | none | f + Publication p3 + Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root +----------+------------+---------+---------+---------+-----------+---------- + postgres | f | t | t | t | t | f Tables: "public.t2" WHERE (d = 10) "public.t3" WHERE (g = 10) -]]> + psql可用于显示每个表的行过滤表达式(如果已定义)。可以看到,表t1属于两个发布,但只有在p1中带有行过滤器; 表t2也属于两个发布,并且在这两个发布中具有不同的行过滤器。 - +test_pub=# \d t1 Table "public.t1" Column | Type | Collation | Nullable | Default --------+---------+-----------+----------+--------- @@ -840,7 +854,7 @@ Publications: "p1" WHERE ((a > 5) AND (c = 'NSW'::text)) "p2" -/* pub # */ \d t2 +test_pub=# \d t2 Table "public.t2" Column | Type | Collation | Nullable | Default --------+---------+-----------+----------+--------- @@ -853,7 +867,7 @@ Publications: "p2" WHERE (e = 99) "p3" WHERE (d = 10) -/* pub # */ \d t3 +test_pub=# \d t3 Table "public.t3" Column | Type | Collation | Nullable | Default --------+---------+-----------+----------+--------- @@ -864,31 +878,41 @@ Indexes: "t3_pkey" PRIMARY KEY, btree (g) Publications: "p3" WHERE (g = 10) -]]> + 在订阅端节点上,创建一个与发布端定义相同的表t1, 然后创建订阅s1来订阅发布p1 -/* sub # */ CREATE TABLE t1(a int, b int, c text, PRIMARY KEY(a,c)); -/* sub # */ CREATE SUBSCRIPTION s1 -/* sub - */ CONNECTION 'host=localhost dbname=test_pub application_name=s1' -/* sub - */ PUBLICATION p1; +test_sub=# CREATE TABLE t1(a int, b int, c text, PRIMARY KEY(a,c)); +CREATE TABLE +test_sub=# CREATE SUBSCRIPTION s1 +test_sub-# CONNECTION 'host=localhost dbname=test_pub application_name=s1' +test_sub-# PUBLICATION p1; +CREATE SUBSCRIPTION 插入一些行。只有满足发布p1t1 WHERE子句的那些行会被复制。 -/* pub # */ INSERT INTO t1 VALUES (2, 102, 'NSW'); -/* pub # */ INSERT INTO t1 VALUES (3, 103, 'QLD'); -/* pub # */ INSERT INTO t1 VALUES (4, 104, 'VIC'); -/* pub # */ INSERT INTO t1 VALUES (5, 105, 'ACT'); -/* pub # */ INSERT INTO t1 VALUES (6, 106, 'NSW'); -/* pub # */ INSERT INTO t1 VALUES (7, 107, 'NT'); -/* pub # */ INSERT INTO t1 VALUES (8, 108, 'QLD'); -/* pub # */ INSERT INTO t1 VALUES (9, 109, 'NSW'); - -/* pub # */ SELECT * FROM t1; +test_pub=# INSERT INTO t1 VALUES (2, 102, 'NSW'); +INSERT 0 1 +test_pub=# INSERT INTO t1 VALUES (3, 103, 'QLD'); +INSERT 0 1 +test_pub=# INSERT INTO t1 VALUES (4, 104, 'VIC'); +INSERT 0 1 +test_pub=# INSERT INTO t1 VALUES (5, 105, 'ACT'); +INSERT 0 1 +test_pub=# INSERT INTO t1 VALUES (6, 106, 'NSW'); +INSERT 0 1 +test_pub=# INSERT INTO t1 VALUES (7, 107, 'NT'); +INSERT 0 1 +test_pub=# INSERT INTO t1 VALUES (8, 108, 'QLD'); +INSERT 0 1 +test_pub=# INSERT INTO t1 VALUES (9, 109, 'NSW'); +INSERT 0 1 + +test_pub=# SELECT * FROM t1; a | b | c ---+-----+----- 2 | 102 | NSW @@ -902,7 +926,7 @@ Publications: (8 rows) -/* sub # */ SELECT * FROM t1; +test_sub=# SELECT * FROM t1; a | b | c ---+-----+----- 6 | 106 | NSW @@ -913,9 +937,10 @@ Publications: 更新一些数据,此时旧行和新行的值都满足发布p1t1 WHERE子句。该UPDATE会像平常一样复制该更改。 -/* pub # */ UPDATE t1 SET b = 999 WHERE a = 6; +test_pub=# UPDATE t1 SET b = 999 WHERE a = 6; +UPDATE 1 -/* pub # */ SELECT * FROM t1; +test_pub=# SELECT * FROM t1; a | b | c ---+-----+----- 2 | 102 | NSW @@ -929,7 +954,7 @@ Publications: (8 rows) -/* sub # */ SELECT * FROM t1; +test_sub=# SELECT * FROM t1; a | b | c ---+-----+----- 9 | 109 | NSW @@ -941,9 +966,10 @@ Publications: 更新一些数据,此时旧行的值不满足发布p1t1 WHERE子句,而新行的值满足该子句。 UPDATE会被转换为INSERT,并且该更改会被复制。可以在订阅端看到新行。 -/* pub # */ UPDATE t1 SET a = 555 WHERE a = 2; +test_pub=# UPDATE t1 SET a = 555 WHERE a = 2; +UPDATE 1 -/* pub # */ SELECT * FROM t1; +test_pub=# SELECT * FROM t1; a | b | c -----+-----+----- 3 | 103 | QLD @@ -957,7 +983,7 @@ Publications: (8 rows) -/* sub # */ SELECT * FROM t1; +test_sub=# SELECT * FROM t1; a | b | c -----+-----+----- 9 | 109 | NSW @@ -970,9 +996,10 @@ Publications: 更新一些数据,此时旧行的值满足发布p1t1 WHERE子句,而新行的值不再满足该子句。 UPDATE会被转换为DELETE,并且该更改会被复制。可以看到该行已从订阅端移除。 -/* pub # */ UPDATE t1 SET c = 'VIC' WHERE a = 9; +test_pub=# UPDATE t1 SET c = 'VIC' WHERE a = 9; +UPDATE 1 -/* pub # */ SELECT * FROM t1; +test_pub=# SELECT * FROM t1; a | b | c -----+-----+----- 3 | 103 | QLD @@ -986,7 +1013,7 @@ Publications: (8 rows) -/* sub # */ SELECT * FROM t1; +test_sub=# SELECT * FROM t1; a | b | c -----+-----+----- 6 | 999 | NSW @@ -995,42 +1022,50 @@ Publications: - 下面的示例展示了发布参数publish_via_partition_root + 下面的示例展示了发布参数publish_via_partition_root 在分区表场景下如何决定使用父表还是子表的行过滤器。 在发布端创建一个分区表。 -/* pub # */ CREATE TABLE parent(a int PRIMARY KEY) PARTITION BY RANGE(a); -/* pub # */ CREATE TABLE child PARTITION OF parent DEFAULT; +test_pub=# CREATE TABLE parent(a int PRIMARY KEY) PARTITION BY RANGE(a); +CREATE TABLE +test_pub=# CREATE TABLE child PARTITION OF parent DEFAULT; +CREATE TABLE 在订阅端创建相同的表。 -/* sub # */ CREATE TABLE parent(a int PRIMARY KEY) PARTITION BY RANGE(a); -/* sub # */ CREATE TABLE child PARTITION OF parent DEFAULT; +test_sub=# CREATE TABLE parent(a int PRIMARY KEY) PARTITION BY RANGE(a); +CREATE TABLE +test_sub=# CREATE TABLE child PARTITION OF parent DEFAULT; +CREATE TABLE 创建一个发布p4,然后订阅它。发布参数publish_via_partition_root设置为 true。 分区表(parent)和分区(child)上都定义了行过滤器。 -= 5) -/* pub - */ WITH (publish_via_partition_root=true); -]]> -/* sub # */ CREATE SUBSCRIPTION s4 -/* sub - */ CONNECTION 'host=localhost dbname=test_pub application_name=s4' -/* sub - */ PUBLICATION p4; +test_pub=# CREATE PUBLICATION p4 FOR TABLE parent WHERE (a < 5), child WHERE (a >= 5) +test_pub-# WITH (publish_via_partition_root=true); +CREATE PUBLICATION + + +test_sub=# CREATE SUBSCRIPTION s4 +test_sub-# CONNECTION 'host=localhost dbname=test_pub application_name=s4' +test_sub-# PUBLICATION p4; +CREATE SUBSCRIPTION 直接向parentchild表插入一些值。它们会使用parent的行过滤器进行复制(因为publish_via_partition_root为 true)。 -/* pub # */ INSERT INTO parent VALUES (2), (4), (6); -/* pub # */ INSERT INTO child VALUES (3), (5), (7); +test_pub=# INSERT INTO parent VALUES (2), (4), (6); +INSERT 0 3 +test_pub=# INSERT INTO child VALUES (3), (5), (7); +INSERT 0 3 -/* pub # */ SELECT * FROM parent ORDER BY a; +test_pub=# SELECT * FROM parent ORDER BY a; a --- 2 @@ -1042,7 +1077,7 @@ Publications: (6 rows) -/* sub # */ SELECT * FROM parent ORDER BY a; +test_sub=# SELECT * FROM parent ORDER BY a; a --- 2 @@ -1054,23 +1089,29 @@ Publications: 重复相同的测试,但将publish_via_partition_root设为不同的值。 这里发布参数publish_via_partition_root设置为 false,并且在分区(child)上定义了行过滤器。 -= 5) -/* pub - */ WITH (publish_via_partition_root=false); -]]> -/* sub # */ ALTER SUBSCRIPTION s4 REFRESH PUBLICATION; +test_pub=# DROP PUBLICATION p4; +DROP PUBLICATION +test_pub=# CREATE PUBLICATION p4 FOR TABLE parent, child WHERE (a >= 5) +test_pub-# WITH (publish_via_partition_root=false); +CREATE PUBLICATION + + +test_sub=# ALTER SUBSCRIPTION s4 REFRESH PUBLICATION; +ALTER SUBSCRIPTION 像前面一样在发布端执行插入。它们会使用child的行过滤器进行复制(因为publish_via_partition_root为 false)。 -/* pub # */ TRUNCATE parent; -/* pub # */ INSERT INTO parent VALUES (2), (4), (6); -/* pub # */ INSERT INTO child VALUES (3), (5), (7); - -/* pub # */ SELECT * FROM parent ORDER BY a; +test_pub=# TRUNCATE parent; +TRUNCATE TABLE +test_pub=# INSERT INTO parent VALUES (2), (4), (6); +INSERT 0 3 +test_pub=# INSERT INTO child VALUES (3), (5), (7); +INSERT 0 3 + +test_pub=# SELECT * FROM parent ORDER BY a; a --- 2 @@ -1082,7 +1123,7 @@ Publications: (6 rows) -/* sub # */ SELECT * FROM child ORDER BY a; +test_sub=# SELECT * FROM child ORDER BY a; a --- 5 @@ -1119,12 +1160,12 @@ Publications: 当发布还发布 - FOR TABLES IN SCHEMA + FOR TABLES IN SCHEMA 时,不支持指定列列表。 - 对于分区表,发布参数publish_via_partition_root + 对于分区表,发布参数publish_via_partition_root 决定使用哪个列列表。如果publish_via_partition_roottrue,则使用根分区表的列列表。 否则,如果publish_via_partition_rootfalse(默认值),则使用各个分区的列列表。 @@ -1172,23 +1213,25 @@ Publications: 创建一个表t1,供下面的示例使用。 -/* pub # */ CREATE TABLE t1(id int, a text, b text, c text, d text, e text, PRIMARY KEY(id)); +test_pub=# CREATE TABLE t1(id int, a text, b text, c text, d text, e text, PRIMARY KEY(id)); +CREATE TABLE 创建一个发布p1。为表t1定义一个列列表,以减少将被复制的列数。请注意,列列表中列名的顺序并不重要。 -/* pub # */ CREATE PUBLICATION p1 FOR TABLE t1 (id, b, a, d); +test_pub=# CREATE PUBLICATION p1 FOR TABLE t1 (id, b, a, d); +CREATE PUBLICATION psql可用于显示每个发布的列列表(如果已定义)。 -/* pub # */ \dRp+ - Publication p1 - Owner | All tables | Inserts | Updates | Deletes | Truncates | Generated columns | Via root -----------+------------+---------+---------+---------+-----------+-------------------+---------- - postgres | f | t | t | t | t | none | f +test_pub=# \dRp+ + Publication p1 + Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root +----------+------------+---------+---------+---------+-----------+---------- + postgres | f | t | t | t | t | f Tables: "public.t1" (id, a, b, d) @@ -1196,7 +1239,7 @@ Tables: psql可用于显示每个表的列列表(如果已定义)。 -/* pub # */ \d t1 +test_pub=# \d t1 Table "public.t1" Column | Type | Collation | Nullable | Default --------+---------+-----------+----------+--------- @@ -1215,19 +1258,24 @@ Publications: 在订阅端节点上,创建一个名为t1的表,它现在只需要发布端表t1中的部分列,然后创建订阅s1来订阅发布p1 -/* sub # */ CREATE TABLE t1(id int, b text, a text, d text, PRIMARY KEY(id)); -/* sub # */ CREATE SUBSCRIPTION s1 -/* sub - */ CONNECTION 'host=localhost dbname=test_pub application_name=s1' -/* sub - */ PUBLICATION p1; +test_sub=# CREATE TABLE t1(id int, b text, a text, d text, PRIMARY KEY(id)); +CREATE TABLE +test_sub=# CREATE SUBSCRIPTION s1 +test_sub-# CONNECTION 'host=localhost dbname=test_pub application_name=s1' +test_sub-# PUBLICATION p1; +CREATE SUBSCRIPTION 在发布端节点上,向表t1插入一些行。 -/* pub # */ INSERT INTO t1 VALUES(1, 'a-1', 'b-1', 'c-1', 'd-1', 'e-1'); -/* pub # */ INSERT INTO t1 VALUES(2, 'a-2', 'b-2', 'c-2', 'd-2', 'e-2'); -/* pub # */ INSERT INTO t1 VALUES(3, 'a-3', 'b-3', 'c-3', 'd-3', 'e-3'); -/* pub # */ SELECT * FROM t1 ORDER BY id; +test_pub=# INSERT INTO t1 VALUES(1, 'a-1', 'b-1', 'c-1', 'd-1', 'e-1'); +INSERT 0 1 +test_pub=# INSERT INTO t1 VALUES(2, 'a-2', 'b-2', 'c-2', 'd-2', 'e-2'); +INSERT 0 1 +test_pub=# INSERT INTO t1 VALUES(3, 'a-3', 'b-3', 'c-3', 'd-3', 'e-3'); +INSERT 0 1 +test_pub=# SELECT * FROM t1 ORDER BY id; id | a | b | c | d | e ----+-----+-----+-----+-----+----- 1 | a-1 | b-1 | c-1 | d-1 | e-1 @@ -1239,7 +1287,7 @@ Publications: 只有发布p1的列列表中包含的数据会被复制。 -/* sub # */ SELECT * FROM t1 ORDER BY id; +test_sub=# SELECT * FROM t1 ORDER BY id; id | b | a | d ----+-----+-----+----- 1 | b-1 | a-1 | d-1 @@ -1256,62 +1304,61 @@ Publications: 冲突 - 逻辑复制的行为类似于普通 DML 操作:即使订阅节点上的数据已在本地被修改, - 传入的数据仍会更新它。如果传入数据违反任何约束,复制就会停止。这称为 - 冲突。在复制 UPDATE 或 - DELETE 操作时,找不到数据不会产生冲突,这类操作会被直接跳过。 + 逻辑复制的行为类似于普通的 DML 操作,即使数据在订阅端本地已被更改,仍会更新数据。如果传入的数据违反了任何约束,复制将停止。这称为冲突。当复制UPDATEDELETE操作时,缺失的数据不会产生冲突,这类操作只会被简单跳过。 - 逻辑复制操作会以订阅所有者角色的权限执行。目标表上的权限失败会导致复制冲突, - 目标表上启用的行级安全也会导致复制冲突,只要订阅所有者受其约束,而不管任何策略 - 是否通常会拒绝正在复制的 INSERTUPDATE、 - DELETETRUNCATE。这一行级安全限制 - 可能会在 PostgreSQL 的未来版本中取消。 + 逻辑复制操作会以订阅所有者角色的权限执行。目标表上的权限失败会导致复制冲突; + 目标表上启用的、且订阅所有者受其约束的 + 行级安全 也会导致复制冲突,而不考虑任何 + 策略通常是否会拒绝当前复制的 INSERT、 + UPDATEDELETE 或 + TRUNCATE。未来版本的 PostgreSQL + 可能会取消这一行级安全限制。 - 冲突会产生错误并停止复制;必须由用户手工解决。冲突的详细信息可以在订阅端的 - 服务器日志中找到。 + 冲突将产生一个错误并停止复制;它必须由用户手动解决。冲突的详细信息可在订阅端的服务器日志中找到。 - 解决方法可以是在订阅端更改数据或权限,使其不再与传入变更冲突;也可以跳过与现有 - 数据冲突的事务。当冲突导致错误时,复制不会继续,逻辑复制工作者会向订阅端的 - 服务器日志输出如下消息: + 解决方法可以是修改订阅端上的数据或权限,使其不再与传入变更冲突;也可以跳过与 + 现有数据冲突的事务。当冲突导致错误时,复制不会继续,逻辑复制工作进程会向订阅端 + 的服务器日志输出如下消息: ERROR: duplicate key value violates unique constraint "test_pkey" DETAIL: Key (c)=(1) already exists. CONTEXT: processing remote data for replication origin "pg_16395" during "INSERT" for replication target relation "public.test" in transaction 725 finished at 0/14C0378 - 事务的 LSN 和复制源名称可以从服务器日志中找到(上述示例中的 LSN 为 - 0/14C0378,复制源为 pg_16395)。可以使用 - ALTER SUBSCRIPTION ... SKIP 并提供 finish LSN - (即 LSN 0/14C0378)来跳过导致冲突的事务。finish LSN 可以是事务在发布端提交 - 或准备完成时的 LSN。或者,也可以通过调用 + 可以从服务器日志中找到包含违规变更的事务的 LSN 以及复制源名称 + (在上述示例中分别是 LSN 0/14C0378 和复制源 pg_16395)。 + 可以使用 + ALTER SUBSCRIPTION ... SKIP + 并提供 完成 LSN(即 LSN 0/14C0378)来跳过产生冲突的事务。这个 完成 LSN + 可以是该事务在发布端提交或预备时的 LSN。或者,也可以调用 pg_replication_origin_advance() 函数来跳过该事务。 - 在使用该函数之前,需要先临时禁用订阅,可以使用 - ALTER SUBSCRIPTION ... DISABLE,或者将订阅与 - disable_on_error 选项一起使用。然后,可以使用 - pg_replication_origin_advance(),传入 - node_name(即 pg_16395)以及 finish - LSN 的下一个 LSN(即 0/14C0379)。当前各个复制源的位置可以在 + 在使用此函数之前,需要暂时禁用订阅,可以使用 + + ALTER SUBSCRIPTION ... DISABLE,或者让订阅使用 + disable_on_error + 选项。然后,可以使用 pg_replication_origin_advance() 函数, + 传入 node_name(即 pg_16395) + 以及 完成 LSN 的下一个 LSN(即 0/14C0379)。当前各复制源的位置可以在 pg_replication_origin_status 系统视图中查看。 - 请注意,跳过整个事务也会跳过那些本来不会违反任何约束的变更,这很容易使订阅端 - 变得不一致。 + 请注意,跳过整个事务也会跳过那些本来可能不违反任何约束的变更,这很容易导致 + 订阅端不一致。 当 - streaming - 模式为 parallel 时,失败事务的 finish LSN 可能不会被记录。 - 在这种情况下,可能需要把 streaming 模式改为 on 或 - off,并再次制造相同冲突,以便把失败事务的 finish LSN 写入 - 服务器日志。关于 finish LSN 的用法,请参见 - ALTER SUBSCRIPTION ... - SKIP。 + streaming + 模式为 parallel 时,失败事务的 完成 LSN 可能不会被记录。 + 这种情况下,可能需要把 streaming 模式改为 on 或 + off,并再次触发相同的冲突,以便将失败事务的 完成 LSN + 写入服务器日志。关于 完成 LSN 的用法,请参见 + ALTER SUBSCRIPTION ... SKIP @@ -1328,9 +1375,9 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER 数据库模式和 DDL 命令不会被复制。初始模式可以手工使用 pg_dump --schema-only 复制。之后的模式更改需要手工保持同步。 (不过请注意,两端的模式其实不需要绝对一致。)当活动数据库中的模式定义发生变化时, - 逻辑复制仍然具有一定鲁棒性:如果发布端修改了模式,而复制数据开始到达订阅端时 + 逻辑复制仍然能够稳健运行:如果发布端修改了模式,而复制数据开始到达订阅端时 与表模式不匹配,复制就会报错,直到模式被更新。在很多情况下,可以通过先在订阅端 - 应用增量式的模式变更来避免间歇性错误。 + 应用仅添加内容的模式变更来避免间歇性错误。 @@ -1376,27 +1423,24 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER 也可以进一步再分区,甚至可以是独立表。)发布还可以指定,复制变更时改用分区根表 的标识和模式,而不是使用实际产生变更的各个叶子分区的标识和模式(见 CREATE PUBLICATION 的 - publish_via_partition_root + publish_via_partition_root 参数)。 - - - 对已发布表使用 - REPLICA IDENTITY FULL - 时,需要注意:如果表中包含某些数据类型的属性(例如 point 或 box),而这些类型 - 没有 B-tree 或 Hash 的默认操作符类,那么 UPDATE 和 - DELETE 操作就无法在订阅端应用。不过,可以通过确保该表具有 - 主键或已定义复制标识来规避这一限制。 - - + 架构 + + 逻辑复制首先复制发布者数据库上的数据快照。完成后,发布者上的变更会在发生时 + 实时发送给订阅者。订阅者会按照发布者上提交的顺序应用数据,因此对于单个订阅 + 中的任何发布,可以保证事务一致性。 + + 逻辑复制采用了与物理流复制类似的架构(见 )。它由 walsender @@ -1427,10 +1471,9 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER 初始快照 - 对现有订阅表中的初始数据,会取快照并由一种特殊应用进程的并行实例来复制。 - 这些特殊的应用进程是为每张待同步表启动的专用表同步工作者。每个表同步进程 - 都会创建自己的复制槽,并复制现有数据。复制一完成,该表内容就会对其他后端可见。 - 现有数据复制完成后,工作者会进入同步模式,通过标准逻辑复制流式发送在初始数据 + 对现有订阅表中的初始数据,会取快照并由一种特殊应用进程的一个并行实例来复制。 + 该进程会创建自己的复制槽,并复制现有数据。复制一完成,该表内容就会对其他后端可见。 + 现有数据复制完成后,工作进程会进入同步模式,通过标准逻辑复制流式发送在初始数据 复制期间发生的任何变更,使该表与主应用进程达到同步状态。在这一同步阶段, 变更会按照它们在发布端发生的顺序被应用和提交。同步完成后,该表的复制控制权 会交还给主应用进程,之后复制将照常继续。 @@ -1438,17 +1481,10 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER 发布的 - publish + publish 参数只影响哪些 DML 操作会被复制。初始数据同步在复制现有表数据时不会考虑该参数。 - - - 如果表同步工作者在复制期间失败,应用工作者会检测到这一失败,并重新启动表同步 - 工作者以继续同步过程。这种行为确保了瞬时错误不会永久破坏复制配置。另见 - wal_retrieve_retry_interval。 - - @@ -1465,15 +1501,15 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER 与订阅相关的监控信息可在 pg_stat_subscription - 中查看。这个视图为每个订阅工作者包含一行。一个订阅根据其状态,可能有零个或多个 - 活跃的订阅工作者。 + 中查看。这个视图为每个订阅工作进程包含一行。一个订阅根据其状态,可能有零个或多个 + 活跃的订阅工作进程。 通常,一个已启用的订阅会有一个应用进程在运行。被禁用的订阅或已崩溃的订阅在这个 视图中将没有任何行。如果某张表的初始数据同步正在进行,则还会有针对这些正在同步 - 的表的额外工作者。并且,如果使用 - streaming + 的表的额外工作进程。并且,如果使用 + streaming 并以并行方式应用事务,则还可能出现额外的并行应用工作进程。 @@ -1486,7 +1522,7 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER (或为超级用户)。如果该角色既没有 SUPERUSER,也没有 BYPASSRLS,则发布端的行安全性策略可能会生效。如果该角色 不信任所有表所有者,请在连接字符串中包含 - options=-row_security=off;这样一来,如果某个表所有者随后 + options=-crow_security=off;这样一来,如果某个表所有者随后 添加了行安全性策略,复制将停止,而不是执行该策略。该角色的访问权限必须在 pg_hba.conf 中配置,并且它还必须具有 LOGIN 属性。 @@ -1551,14 +1587,14 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER - 在订阅端,订阅所有者的权限会在每个事务应用时重新检查。如果某个工作者正在应用 + 在订阅端,订阅所有者的权限会在每个事务应用时重新检查。如果某个工作进程正在应用 事务时,订阅的所有权被并发事务更改,那么当前事务的应用仍会继续使用旧所有者的 权限。 - 配置参数 + 配置设置 逻辑复制需要设置若干配置选项。大多数选项只在复制的一侧相关。不过, @@ -1602,7 +1638,7 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER max_logical_replication_workers - 必须至少设置为订阅数量(用于主应用工作进程),再加上用于表同步工作进程 + 必须至少设置为订阅数量(用于领导者应用工作进程),再加上用于表同步工作进程 和并行应用工作进程的预留量。 diff --git a/zh/16/maintenance.sgml b/zh/16/maintenance.sgml index a75a7f52..46135b06 100644 --- a/zh/16/maintenance.sgml +++ b/zh/16/maintenance.sgml @@ -378,32 +378,24 @@ 不一定会冻结表中的每一个旧行版本。在这种情况下,VACUUM 最终需要执行一次 激进扫描,它会冻结所有符合条件且尚未冻结的 XID 和 MXID 值, 包括那些来自全部可见(all-visible)但未全部冻结(all-frozen)页面的值。 - - - - 如果一个表正在积累全部可见但尚未全部冻结的页面,普通清理可能会选择扫描这些本可跳过的页面, - 以尝试冻结它们。这样可以减少下一次激进扫描必须扫描的页面数。这类页面称为 - 积极扫描页。通过增大 ,可以调整积极扫描, - 使其尝试冻结更多全部可见页面。即使积极扫描已将全部可见但未全部冻结页面的数量降到最低, - 大多数表仍然需要周期性地进行激进扫描。不过,任何成功被积极冻结的页面在激进扫描时都可以跳过, - 因此积极冻结可以尽量减小激进扫描的开销。 - - - + 在实际使用中,大多数表需要周期性地进行激进扫描。 - 控制何时对表执行激进扫描。如果距离上一次这类扫描以来经过的事务数大于 + 控制VACUUM何时对表执行激进扫描:如果距离上一次这类扫描以来经过的事务数大于 vacuum_freeze_table_age 减去 vacuum_freeze_min_age,就会扫描所有全部可见但未全部冻结的页面。 把 vacuum_freeze_table_age 设为 0 会强制 VACUUM 始终采用其激进策略。 + + + + 一个表在不被清理的情况下所能维持的最长时间,是最后一次激进扫描时的 vacuum_freeze_min_age 值从 20 亿事务中扣除后的结果。 如果超过这个时间仍不清理,就可能导致数据丢失。为了确保不会发生这种情况, - 任何可能包含未冻结行且其 XID 早于配置参数 所指定年龄的表,都会触发自动清理。 (即使自动清理已被禁用,也会如此。) @@ -491,12 +483,10 @@ SELECT datname, age(datfrozenxid) FROM pg_database; - 虽然 VACUUM 主要扫描自上次清理以来被修改过的页面, - 但它也可能为了冻结它们而积极扫描某些全部可见但未全部冻结的页面; - 不过,只有当表中每一个可能包含未冻结 XID 的页面都被扫描时, + VACUUM 通常只扫描自上次清理以来被修改过的页面,但只有 + 当表中每一个可能包含未冻结 XID 的页面都被扫描时, relfrozenxid 才会被推进。当 - relfrozenxid 比 - vacuum_freeze_table_age 旧、使用了 VACUUM 的 + relfrozenxid的年龄超过vacuum_freeze_table_age个事务、使用了 VACUUMFREEZE 选项,或者所有尚未全部冻结的页面碰巧都需要清理以移除死行版本时, 就会发生这种情况。当 VACUUM 扫描了表中每个尚未全部冻结的页面时, 它应把 age(relfrozenxid) 设为略高于所用 @@ -515,7 +505,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; WARNING: database "mydb" must be vacuumed within 39985967 transactions -HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. +HINT: To avoid a database shutdown, execute a database-wide VACUUM in that database. (如提示所建议,手工执行 VACUUM 应能解决问题;但要注意, @@ -524,13 +514,13 @@ HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that 如果忽略这些警告,一旦距离回卷只剩不到三百万个事务,系统就会拒绝分配新的 XID: -ERROR: database is not accepting commands that assign new XIDs to avoid wraparound data loss in database "mydb" -HINT: Execute a database-wide VACUUM in that database. +ERROR: database is not accepting commands to avoid wraparound data loss in database "mydb" +HINT: Stop the postmaster and vacuum that database in single-user mode. 在这种状态下,已经在进行中的事务可以继续,但只能启动只读事务。 修改数据库记录或截断关系的操作都会失败。VACUUM 命令仍然可以正常执行。 - 请注意,与早期版本中有时给出的建议相反,为了恢复正常运行, + 与提示内容相反,为了恢复正常运行, 不需要也不希望停止 postmaster 或进入单用户模式。相反,请按以下步骤操作: @@ -595,22 +585,22 @@ HINT: Execute a database-wide VACUUM in that database. 多事务(multitransaction,MultiXact) ID 用于支持多个事务对行加锁。由于元组头中用于存储锁信息的空间有限, 当有多个事务同时锁定一行时,这些信息会被编码为一个多事务 ID, - 简称 multixact ID。某个特定 multixact ID 包含哪些事务 ID 的信息, + 简称 multixact ID。某个特定 多事务 ID 包含哪些事务 ID 的信息, 会单独存放在 pg_multixact 子目录中,而元组头的 - xmax 字段中只出现 multixact ID。和事务 ID 一样, - multixact ID 也是以 32 位计数器及其对应存储实现的,因此同样需要仔细处理老化管理、 - 存储清理和回卷问题。还有一个单独的存储区域保存每个 multixact 的成员列表, + xmax 字段中只出现 多事务 ID。和事务 ID 一样, + 多事务 ID 也是以 32 位计数器及其对应存储实现的,因此同样需要仔细处理老化管理、 + 存储清理和回卷问题。还有一个单独的存储区域保存每个 多事务 的成员列表, 它也使用 32 位计数器,因此同样必须被管理。 中介绍的系统函数 pg_get_multixact_members() - 可用于检查与某个 multixact ID 关联的事务 ID。 + 可用于检查与某个 多事务 ID 关联的事务 ID。 每当 VACUUM 扫描表的任何部分时,它都会把遇到的、早于 - 的任何 multixact ID 替换为另一个值,该值可能是零值、单个事务 ID,或者更新的 multixact ID。 + 的任何 多事务 ID 替换为另一个值,该值可能是零值、单个事务 ID,或者更新的 多事务 ID。 对于每个表,pg_class.relminmxid - 保存该表任何元组中仍可能出现的最老 multixact ID。如果这个值早于 + 保存该表任何元组中仍可能出现的最老 多事务 ID。如果这个值早于 ,就会强制执行一次激进扫描。 正如上一节所述,激进扫描意味着只有那些已知为全部冻结的页面才会被跳过。 可以对 pg_class.relminmxid @@ -620,14 +610,14 @@ HINT: Execute a database-wide VACUUM in that database. 无论出于何种原因而发生,激进的 VACUUM保证 能够推进表的 relminmxid。最终,随着所有数据库中的所有表都被扫描, - 并推进其最老的 multixact 值,较老 multixact 的磁盘存储就可以被移除。 + 并推进其最老的 多事务 值,较老 多事务 的磁盘存储就可以被移除。 - 作为一项安全措施,对于 multixact 年龄大于 的任何表,都会进行一次激进扫描。 - 此外,如果 multixact 成员占用的存储超过大约 10GB,则会更频繁地对所有表进行激进扫描, - 从 multixact 年龄最老的表开始。即便自动清理名义上被禁用,这两类激进扫描也都会发生。 + 此外,如果 多事务 成员占用的存储超过大约 10GB,则会更频繁地对所有表进行激进扫描, + 从 多事务 年龄最老的表开始。即便自动清理名义上被禁用,这两类激进扫描也都会发生。 成员存储区域在到达回卷之前最多可增长到大约 20GB。 @@ -644,11 +634,11 @@ HINT: Execute a database-wide VACUUM in that database. - 如果没有可能出现在 multixact 中,那么正在运行的事务和预备事务都可以忽略。 + 如果没有可能出现在 多事务 中,那么正在运行的事务和预备事务都可以忽略。 - 与事务 ID 回卷不同,复制槽不会直接阻止 multixact 清理。 - 因此,删除陈旧的复制槽通常与解决 multixact ID 回卷问题无关。 + 与事务 ID 回卷不同,复制槽不会直接阻止 多事务 清理。 + 因此,删除陈旧的复制槽通常与解决 多事务 ID 回卷问题无关。 MXID 信息不会直接出现在诸如 pg_stat_activity 这样的系统视图中; @@ -703,50 +693,15 @@ HINT: Execute a database-wide VACUUM in that database. 的限制。 - - 对于 relfrozenxid 值早于 - 个事务的表,总是会执行清理 - (这也适用于那些通过存储参数修改了冻结最大年龄的表,见下文)。 - 否则,如果自上次 VACUUM 以来已经失效的元组数超过了 - 清理阈值,就会对该表执行清理。清理阈值定义如下: - -vacuum threshold = Minimum(vacuum max threshold, vacuum base threshold + vacuum scale factor * number of tuples) - - 其中,vacuum max threshold 是 - , - vacuum base threshold 是 - , - vacuum scale factor 是 - , - 而元组数是 - pg_class.reltuples。 + 凡是 relfrozenxid 值的年龄超过 个事务的表,始终都会被清理(这也适用于通过存储参数修改了最大冻结年龄的表,见下文)。否则,如果自上次 VACUUM 以来失效的元组数超过清理阈值,就会清理该表。清理阈值定义为: +vacuum threshold = vacuum base threshold + vacuum scale factor * number of tuples +其中,清理基础阈值为 ,清理比例因子为 ,元组数为 pg_class.reltuples - - 如果自上次清理以来插入的元组数超过了定义的插入阈值,也会对该表执行清理,该阈值定义如下: - -vacuum insert threshold = vacuum base insert threshold + vacuum insert scale factor * number of tuples * percent of table not frozen - - 其中,vacuum insert base threshold 是 - , - vacuum insert scale factor 是 - , - 元组数是 - pg_class.reltuples, - 而表中未冻结部分的百分比是 - 1 - pg_class.relallfrozen / pg_class.relpages。 - 这样的清理可能使表的一部分被标记为全部可见, - 并且也允许元组被冻结,从而减少后续清理所需的工作。对于只接收 - INSERT 操作、但没有或几乎没有 UPDATE / - DELETE 操作的表,降低该表的 - 可能是有益的, - 因为这会让元组在更早的清理中被冻结。过时元组数和插入元组数取自累积统计系统; - 这是一个由每次 UPDATEDELETE 和 - INSERT 操作更新的最终一致计数。如果该表的 - relfrozenxid 值早于 - vacuum_freeze_table_age 个事务,就会执行一次激进扫描, - 以冻结旧元组并推进 relfrozenxid。 - + 如果自上次清理以来插入的元组数超过了定义的插入阈值,也会清理该表。插入阈值定义为: +vacuum insert threshold = vacuum base insert threshold + vacuum insert scale factor * number of tuples +其中,清理插入基础阈值为 ,清理插入比例因子为 。这种清理可以将表的部分区域标记为全部可见,并允许冻结元组,从而减少后续清理所需的工作。对于有 INSERT 操作,但没有或几乎没有 UPDATE/DELETE 操作的表,降低表的 可能有益,因为这可能让元组在更早的清理中被冻结。失效元组数和插入元组数来自累积统计系统;这些计数只是近似值,由每次 UPDATE, + DELETEINSERT 操作更新。(之所以只是近似值,是因为高负载下可能丢失部分信息。)如果表的 relfrozenxid 值的年龄超过 vacuum_freeze_table_age 个事务,就会执行激进清理,冻结旧元组并推进 relfrozenxid;否则,只扫描自上次清理以来被修改过的页面。 对于分析操作,也使用了一个类似的条件:其阈值定义如下: @@ -944,7 +899,7 @@ pg_ctl start | rotatelogs /var/log/pgsql_log 86400 不过,在很多系统上,syslog 并不十分可靠, 尤其是在日志消息很大时;它可能恰恰在你最需要消息的时候截断或丢弃它们。 此外,在 Linux 上, - syslog 会把每条消息都刷新到磁盘,导致性能较差。 + syslog 会把每条消息都刷盘,导致性能较差。 (你可以在 syslog 配置文件的文件名开头使用一个 - 来禁用同步。) diff --git a/zh/16/monitoring.sgml b/zh/16/monitoring.sgml index 1b7df846..77b98004 100644 --- a/zh/16/monitoring.sgml +++ b/zh/16/monitoring.sgml @@ -87,15 +87,15 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - 累计统计系统 + 累积统计系统 - statistics + 统计信息 PostgreSQL累积统计系统支持收集和报告有关服务器活动的信息。 - 目前,对表和索引的访问以磁盘块和单个行的术语进行计数。每个表中的总行数, + 目前,对表和索引的访问分别以磁盘块和单行计数。每个表中的总行数, 以及每个表的清理和分析操作的信息也被计数。如果启用,对用户定义函数的调用 和每个函数中花费的总时间也会被计数。 @@ -107,7 +107,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - 统计收集配置 + 统计信息收集配置 由于收集统计信息会增加查询执行的开销,因此可以配置系统是否收集信息。这由通常在postgresql.conf中设置的配置参数控制(有关设置配置参数的详细信息,请参阅)。 @@ -117,9 +117,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 参数启用对任意服务器进程当前执行命令的监控。 - - 参数track_cost_delay_timing启用对基于代价的清理延迟的监控。 - + 参数控制是否收集关于表和索引访问的累积统计信息。 @@ -133,9 +131,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 参数启用对块读取、写入、扩展和 fsync 时间的监控。 - - 参数启用对 WAL 读取、写入和 fsync 时间的监控。 - + 参数启用对 WAL 写入和 fsync 时间的监控。 通常,这些参数会设置在postgresql.conf中,以便它们适用于所有服务器进程,但也可以在单个会话中使用命令打开或关闭它们。(为防止普通用户隐藏其活动不被管理员发现,只有超级用户才能使用SET更改这些参数。) @@ -160,11 +156,11 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - 另一个重要的观点是,当服务器进程被要求显示任何累积的统计信息时,在默认配置中,访问的值会被缓存直到当前事务结束。因此,只要您继续当前事务,统计信息将显示静态信息。类似地,当在事务中首次请求任何当前会话的查询信息时,会收集关于所有会话当前查询的信息,并且相同的信息将在整个事务中显示。这是一个特性,而不是一个错误,因为它允许您在统计信息上执行多个查询并将结果相关联,而不必担心数字在您眼前发生变化。 + 另一个重要的观点是,当服务器进程被要求显示任何累积的统计信息时,在默认配置中,访问的值会被缓存直到当前事务结束。因此,只要你继续当前事务,统计信息将显示静态信息。类似地,当在事务中首次请求这类当前查询信息时,会收集关于所有会话当前查询的信息,并且相同的信息将在整个事务中显示。这是一个特性,而不是一个错误,因为它允许你在统计信息上执行多个查询并将结果相关联,而不必担心数字在你眼前发生变化。 - 在交互式分析统计信息或使用昂贵的查询时,访问各个统计信息之间的时间差可能导致缓存统计信息中出现显著的偏差。为了最小化偏差,可以将stats_fetch_consistency设置为snapshot,但这会增加用于缓存不需要的统计数据的内存使用量。相反,如果已知统计信息只被访问一次,那么缓存访问的统计信息是不必要的,可以通过将stats_fetch_consistency设置为none来避免。 + 在交互式分析统计信息或使用开销较大的查询时,访问各个统计信息之间的时间差可能导致缓存统计信息中出现显著的偏差。为了最小化偏差,可以将stats_fetch_consistency设置为snapshot,但这会增加用于缓存不需要的统计数据的内存使用量。相反,如果已知统计信息只被访问一次,那么缓存访问的统计信息是不必要的,可以通过将stats_fetch_consistency设置为none来避免。 - 您可以调用pg_stat_clear_snapshot()来丢弃当前事务的统计快照或缓存的值(如果有)。下一次使用统计信息时(在快照模式下),将会创建一个新的快照,或者(在缓存模式下)将访问的统计信息缓存起来。 + 你可以调用pg_stat_clear_snapshot()来丢弃当前事务的统计快照或缓存的值(如果有)。下一次使用统计信息时(在快照模式下),将会创建一个新的快照,或者(在缓存模式下)将访问的统计信息缓存起来。 @@ -176,11 +172,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 相反,它们在事务期间持续更新。 - - 动态统计视图中显示的一些信息在中受到安全限制。 - 普通用户只能查看关于他们自己会话的所有信息(属于他们是成员的角色的会话)。在关于其他会话的行中,许多列将为空。 - 但是,请注意,所有用户都可以看到会话的存在以及其一般属性,如会话用户和数据库。超级用户和具有内置角色pg_read_all_stats权限的角色(另请参阅)可以查看所有会话的所有信息。 - + 所列动态统计视图中的一些信息受到安全限制。普通用户只能查看其自身会话的全部信息(包括属于其所加入角色的会话)。对于其他会话的行,许多列将为空值。不过,会话的存在及其一般属性(例如会话用户和数据库)对所有用户都可见。超级用户和具有内置角色pg_read_all_stats权限的角色(另请参阅)可以查看所有会话的全部信息。 @@ -215,7 +207,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser pg_stat_wal_receiverpg_stat_wal_receiver - 只有一行,显示有关 WAL 接收进程从其连接服务器接收到的统计信息。有关详细信息,请参阅pg_stat_wal_receiver。 + 只有一行,显示 WAL 接收进程从其所连接服务器接收数据的统计信息。有关详细信息,请参阅pg_stat_wal_receiver @@ -305,36 +297,51 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - + pg_stat_bgwriterpg_stat_bgwriter 只有一行,显示有关后台写入器活动的信息。有关详细信息,请参阅pg_stat_bgwriter - + + pg_stat_databasepg_stat_database + 每个数据库一行,显示数据库范围的统计信息。有关详细信息,请参阅pg_stat_database。 + + + + + pg_stat_database_conflictspg_stat_database_conflicts + 每个数据库一行,显示数据库范围内因备库上的恢复冲突而导致查询被取消的统计信息。有关详细信息,请参阅pg_stat_database_conflicts + + + pg_stat_iopg_stat_io 对于每种后端类型、上下文和目标对象的组合各有一行,包含集簇范围的 I/O 统计信息。有关详细信息,请参阅pg_stat_io - - pg_stat_walpg_stat_wal - 只有一行,显示有关 WAL 活动的统计信息。有关详细信息,请参阅pg_stat_wal。 - + + pg_stat_replication_slotspg_stat_replication_slots + 每个复制槽一行,显示有关复制槽使用情况的统计信息。有关详细信息,请参阅pg_stat_replication_slots - - pg_stat_databasepg_stat_database - 每个数据库一行,显示数据库范围的统计信息。有关详细信息,请参阅pg_stat_database。 - + + pg_stat_slrupg_stat_slru + 每个 SLRU 一行,显示操作统计信息。有关详细信息,请参阅pg_stat_slru - - pg_stat_database_conflictspg_stat_database_conflicts - 每个数据库一行,显示数据库范围内因备库上的恢复冲突而导致查询被取消的统计信息。有关详细信息,请参阅pg_stat_database_conflicts + + pg_stat_subscription_statspg_stat_subscription_stats + 每个订阅一行,显示有关错误的统计信息。有关详细信息,请参阅pg_stat_subscription_stats - + + pg_stat_walpg_stat_wal + 只有一行,显示有关 WAL 活动的统计信息。有关详细信息,请参阅pg_stat_wal。 + + + + pg_stat_all_tablespg_stat_all_tables 当前数据库中每个表一行,显示有关访问指定表的统计信息。详见 @@ -342,116 +349,101 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - + pg_stat_sys_tablespg_stat_sys_tables pg_stat_all_tables一样,但只显示系统表。 - + pg_stat_user_tablespg_stat_user_tables pg_stat_all_tables一样,但只显示用户表。 - + pg_stat_xact_all_tablespg_stat_xact_all_tables - pg_stat_all_tables相似,但计数动作只在当前事务内发生(还没有被包括在pg_stat_all_tables和相关视图中)。用于生存和死亡行数量的列以及清理和分析动作在此视图中不出现。 + pg_stat_all_tables 相似,但只统计当前事务中截至目前执行的操作(这些操作尚计入 pg_stat_all_tables 及相关视图)。此视图不包含存活行和死行数量以及清理、分析操作的列。 - + pg_stat_xact_sys_tablespg_stat_xact_sys_tables pg_stat_xact_all_tables一样,但只显示系统表。 - + pg_stat_xact_user_tablespg_stat_xact_user_tables pg_stat_xact_all_tables一样,但只显示用户表。 - + pg_stat_all_indexespg_stat_all_indexes 当前数据库中的每个索引一行,显示有关访问该特定索引的统计信息。有关详细信息,请参阅pg_stat_all_indexes - + pg_stat_sys_indexespg_stat_sys_indexes pg_stat_all_indexes一样,但只显示系统表上的索引。 - + pg_stat_user_indexespg_stat_user_indexes pg_stat_all_indexes一样,但只显示用户表上的索引。 - + + pg_stat_user_functionspg_stat_user_functions + 每个被跟踪的函数一行,显示有关该函数执行的统计信息。有关详细信息,请参阅pg_stat_user_functions + + + + pg_stat_xact_user_functionspg_stat_xact_user_functions + pg_stat_user_functions相似,但是只统计在当前事务期间的调用(还没有被包括在pg_stat_user_functions中)。 + + + pg_statio_all_tablespg_statio_all_tables 当前数据库中的每个表一行,显示有关访问该特定表的 I/O 统计信息。有关详细信息,请参阅pg_statio_all_tables - + pg_statio_sys_tablespg_statio_sys_tables pg_statio_all_tables一样,但只显示系统表。 - + pg_statio_user_tablespg_statio_user_tables pg_statio_all_tables一样,但只显示用户表。 - + pg_statio_all_indexespg_statio_all_indexes 当前数据库中的每个索引一行,显示有关访问该特定索引的 I/O 统计信息。有关详细信息,请参阅pg_statio_all_indexes - + pg_statio_sys_indexespg_statio_sys_indexes pg_statio_all_indexes一样,但只显示系统表上的索引。 - + pg_statio_user_indexespg_statio_user_indexes pg_statio_all_indexes一样,但只显示用户表上的索引。 - + pg_statio_all_sequencespg_statio_all_sequences 当前数据库中的每个序列一行,显示有关访问该特定序列的 I/O 统计信息。有关详细信息,请参阅pg_statio_all_sequences - + pg_statio_sys_sequencespg_statio_sys_sequences pg_statio_all_sequences一样,但只显示系统序列(目前没有定义系统序列,因此这个视图总是为空)。 - + pg_statio_user_sequencespg_statio_user_sequences pg_statio_all_sequences一样,但只显示用户序列。 - - pg_stat_user_functionspg_stat_user_functions - 每个被跟踪的函数一行,显示有关该函数执行的统计信息。有关详细信息,请参阅pg_stat_user_functions - - - - pg_stat_xact_user_functionspg_stat_xact_user_functions - pg_stat_user_functions相似,但是只统计在当前事务期间的调用(还没有被包括在pg_stat_user_functions中)。 - - - - pg_stat_slrupg_stat_slru - 每个 SLRU 一行,显示操作统计信息。有关详细信息,请参阅pg_stat_slru - - - - pg_stat_replication_slotspg_stat_replication_slots - 每个复制槽一行,显示有关复制槽使用情况的统计信息。有关详细信息,请参阅pg_stat_replication_slots - - - - pg_stat_subscription_statspg_stat_subscription_stats - 每个订阅一行,显示有关错误和冲突的统计信息。有关详细信息,请参阅pg_stat_subscription_stats - -
@@ -527,7 +519,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser leader_pid integer
- 如果该进程是并行查询工作进程,则为并行组领导者的进程 ID;如果该进程是并行应用工作进程,则为领导应用工作进程的进程 ID。NULL 表示该进程是并行组领导者或领导应用工作进程,或者不参与任何并行操作。 + 如果该进程是并行查询工作进程,则为并行组领导者的进程 ID;如果该进程是并行应用工作进程,则为领导者应用工作进程的进程 ID。NULL 表示该进程是并行组领导者或领导者应用工作进程,或者不参与任何并行操作。 @@ -563,7 +555,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser client_addr inet
- 连接到这个后端的客户端的 IP 地址。如果这个字段为空,它表示客户端通过服务器机器上的一个 Unix 套接字连接或者这是一个内部进程,如自动清理。 + 连接到这个后端的客户端的 IP 地址。如果这个字段为空值,它表示客户端通过服务器机器上的一个 Unix 套接字连接或者这是一个内部进程,如自动清理。 @@ -582,7 +574,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser client_port integer - 客户端用于与此后端通信的TCP端口号,如果使用Unix套接字,则为-1。如果该字段为空,它表示这是一个内部服务器进程。 + 客户端用于与此后端通信的TCP端口号,如果使用Unix套接字,则为-1。如果该字段为空值,它表示这是一个内部服务器进程。 @@ -600,8 +592,8 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser xact_start timestamp with time zone - 这个进程的当前事务被启动的时间,如果没有活动事务则为空。 - 如果当前查询是它的第一个事务,这一列等于query_start列。 + 这个进程的当前事务被启动的时间,如果没有活动事务则为空值。 + 如果当前查询是其事务中的第一个查询,这一列等于query_start列。 @@ -628,7 +620,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser wait_event_type text - 后端正在等待的事件类型(如果有);否则为NULL。请参阅。 + 后端正在等待的事件类型(如果有);否则为空值。请参阅 @@ -637,7 +629,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser wait_event text - 如果此后端当前正在等待,则返回等待事件名称,否则为NULL。请参阅。 + 如果此后端当前正在等待,则返回等待事件名称,否则为空值。请参阅 @@ -645,44 +637,24 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser state text - - 这个后端的当前总体状态。可能的值为: - - - - starting: 后端正处于初始启动阶段。客户端认证在此阶段执行。 - - + 该后端当前的总体状态。可能的值为: - - active: 后端正在执行一个查询。 - + active:后端正在执行一个查询。 - - idle: 后端正在等待一个新的客户端命令。 - + idle:后端正在等待新的客户端命令。 - - idle in transaction: 后端在一个事务中,但是当前没有正在执行一个查询。 - + idle in transaction:后端处于事务中,但当前没有执行查询。 - - idle in transaction (aborted): 这个状态与 - idle in transaction相似,除了在该事务中的一个语句导致了一个错误。 - + idle in transaction (aborted):该状态与idle in transaction类似,但事务中的某个语句导致了错误。 - - fastpath function call: 后端正在执行一个 fast-path 函数。 - + fastpath function call:后端正在执行一个快速路径函数。 - - disabled: 如果在这个后端中被禁用,则报告这个状态。 - + disabled:如果在此后端中禁用了,就会报告此状态。 @@ -692,9 +664,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser backend_xid xid - - 这个后端的顶层事务 ID,如果存在。 - + 这个后端的顶层事务 ID(如果存在);请参阅 @@ -702,7 +672,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser backend_xmin xid - 当前后端的xmin范围。 + 当前后端的xmin视界。 @@ -714,7 +684,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 这个后端的最近查询的标识符。 如果stateactive,这个字段显示当前正在执行的查询的标识符。 在所有其他状态,它显示执行的最后一个查询的标识符。 - 默认不计算查询标识符,因此该字段将为空,除非启用参数或配置了计算查询标识符的第三方模块。 + 默认不计算查询标识符,因此该字段将为空值,除非启用参数或配置了计算查询标识符的第三方模块。 @@ -732,19 +702,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser backend_type text - - 当前后端的类型。可能的类型为 - autovacuum launcher, autovacuum worker, - logical replication launcher, - logical replication worker, - parallel worker, background writer, - client backend, checkpointer, - archiver, standalone backend, - startup, walreceiver, - walsender, walwriter 以及 - walsummarizer。 - 此外,由扩展注册的后台工作进程还可能有额外的类型。 - + 当前后端的类型。可能的类型为autovacuum launcherautovacuum workerlogical replication launcherlogical replication workerparallel workerbackground writerclient backendcheckpointerarchiverstandalone backendstartupwalreceiverwalsenderwalwriter。此外,由扩展注册的后台工作进程还可能有额外的类型。 @@ -753,7 +711,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - wait_eventstate列彼此独立。如果某个后端处于active状态,它既可能正在等待某个事件,也可能没有等待。如果状态为activewait_event非空,就意味着某个查询正在执行,但在系统中的某处被阻塞了。为将报告开销保持在较低水平,系统不会尝试为某个后端同步活动数据的不同方面。因此,视图各列之间可能暂时存在不一致。 + wait_eventstate列彼此独立。如果某个后端处于active状态,它可能在等待(waiting)某个事件,也可能没有等待。如果状态为activewait_event非空,就意味着某个查询正在执行,但在系统中的某处被阻塞了。 @@ -780,10 +738,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser BufferPin - 服务器进程正在等待对数据缓冲的独占访问。 - 如果另一个进程持有一个打开的游标,该游标最后一次从相关缓冲区读取数据,则缓冲区销等待可能是漫长的。 - 参见。 - + 服务器进程正在等待独占访问一个数据缓冲区。如果另一个进程持有尚未关闭的游标,且该游标最近读取的数据来自此缓冲区,缓冲区钉住等待就可能持续较长时间。参见 @@ -799,14 +754,11 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - - InjectionPoint - 服务器进程正在等待某个测试注入点达到预定义结果。该类型没有预定义的等待点。 - + IO - 服务器进程正在等待一个I/O操作完成。wait_event将识别特定的等待点;参见。 + 服务器进程正在等待一个 I/O 操作完成。wait_event将识别特定的等待点;参见 @@ -818,17 +770,14 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser Lock - 服务器进程正在等待一个重量级锁。重量级锁,也称为锁管理器锁或简单锁,主要保护表等SQL可见对象。 + 服务器进程正在等待一个重量级锁。重量级锁,也称为锁管理器锁或简称为锁,主要保护表等SQL可见对象。 然而,它们也用于确保某些内部操作的互斥,例如关系扩展。wait_event将识别等待的锁的类型;参见 LWLock - 服务器进程正在等待一个轻量级锁。大多数这样的锁保护共享内存中的特定数据结构。 - wait_event将包含标识轻量级锁用途的名称。 - (有些锁有特定的名称;其他锁是一组锁的一部分,每个锁具有类似的目的。)参见。 - + 服务器进程正在等待一个轻量级锁。大多数这样的锁保护共享内存中的某个特定数据结构。wait_event将包含标识该轻量级锁用途的名称。(有些锁具有专门的名称,另一些锁属于一组用途相似的锁。)参见 @@ -861,12 +810,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser AutoVacuumMain - 在自动清理启动过程的主循环中等待。 + 在自动清理启动进程的主循环中等待。 BgWriterHibernate - 在后台写入器中等待,休眠状态。 + 在后台写入器进程中休眠等待。 @@ -889,9 +838,14 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 在逻辑复制启动器进程的主循环中等待。 + + LogicalParallelApplyMain + 在逻辑复制并行应用进程的主循环中等待。 + + RecoveryWalStream - 流恢复期间,在启动进程主循环等待WAL到达。 + 在流恢复期间,在启动进程的主循环中等待 WAL 到达。 @@ -901,7 +855,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser WalReceiverMain - 在WAL 接收进程的主循环中等待。 + 在 WAL 接收进程的主循环中等待。 @@ -911,7 +865,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser WalWriterMain - 在WAL写入进程的主循环中等待。 + 在 WAL 写入进程的主循环中等待。 @@ -933,7 +887,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser BufferPin - 等待获得缓冲区上的独占销。 + 等待获得缓冲区上的独占钉住。 @@ -970,12 +924,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser LibPQWalReceiverConnect - 在WAL 接收进程等待与远程服务器建立连接。 + 在 WAL 接收进程中等待与远程服务器建立连接。 LibPQWalReceiverReceive - 在WAL 接收进程中等待从远程服务器接收数据。 + 在 WAL 接收进程中等待从远程服务器接收数据。 @@ -985,7 +939,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser WalSenderWaitForWAL - 在 WAL 发送进程中等待 WAL 被刷新。 + 在 WAL 发送进程中等待 WAL 刷盘。 @@ -1039,7 +993,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser BaseBackupSync - 等待由基础备份写入的数据达到持久存储。 + 等待基础备份写入的数据同步到持久存储。 @@ -1053,13 +1007,13 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - BufFileWrite - 等待对缓冲文件的写入。 + BufFileTruncate + 等待一个缓冲文件被截断。 - BufFileTruncate - 等待一个缓冲文件被截断。 + BufFileWrite + 等待对缓冲文件的写入。 @@ -1069,12 +1023,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser ControlFileSync - 等待pg_control文件到达持久存储。 + 等待 pg_control 文件同步到持久存储。 ControlFileSyncUpdate - 等待更新pg_control文件以达到持久存储。 + 等待对 pg_control 文件的更新同步到持久存储。 @@ -1084,7 +1038,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser ControlFileWriteUpdate - 等待写入更新pg_control文件。 + 等待写入以更新 pg_control 文件。 @@ -1094,12 +1048,17 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser CopyFileWrite - 在文件拷贝操作期间等待写入。 + 在文件复制操作期间等待写入。 + + + + DSMAllocate + 等待分配动态共享内存段。 DSMFillZeroWrite - 等待用零填充动态共享内存备份(backing)文件。 + 等待用零填充动态共享内存的后备文件。 @@ -1109,12 +1068,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser DataFileFlush - 等待关系数据文件达到持久存储。 + 等待关系数据文件同步到持久存储。 DataFileImmediateSync - 等待关系数据文件到持久存储的立即同步。 + 等待关系数据文件立即同步到持久存储。 @@ -1129,7 +1088,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser DataFileSync - 等待对关系数据文件的更改达到持久存储。 + 等待对关系数据文件的更改同步到持久存储。 @@ -1149,7 +1108,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser LockFileAddToDataDirSync - 等待数据到达持久存储,同时向数据目录锁文件添加一行。 + 在向数据目录锁文件中添加一行时,等待数据同步到持久存储。 @@ -1164,7 +1123,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser LockFileCreateSync - 在创建数据目录锁文件时等待数据到达持久存储。 + 在创建数据目录锁文件时,等待数据同步到持久存储。 @@ -1179,12 +1138,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser LogicalRewriteCheckpointSync - 等待逻辑重写映射到在检查点到达持久存储。 + 在检查点期间等待逻辑重写映射同步到持久存储。 LogicalRewriteMappingSync - 在逻辑重写期间等待映射数据到达持久存储 + 在逻辑重写期间等待映射数据同步到持久存储。 @@ -1194,12 +1153,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser LogicalRewriteSync - 等待逻辑重写映射到达持久存储。 + 等待逻辑重写映射同步到持久存储。 LogicalRewriteTruncate - 等待在逻辑重写期间截断映射数据。 + 在逻辑重写期间等待截断映射数据。 @@ -1213,8 +1172,8 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - RelationMapSync - 等待关系映射文件到达持久存储。 + RelationMapReplace + 等待关系映射文件的替换结果同步到持久存储。 @@ -1224,17 +1183,17 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser ReorderBufferRead - 在重新排序缓冲区管理期间等待读取。 + 在重排序缓冲区管理期间等待读取。 ReorderBufferWrite - 在重新排序缓冲区管理期间等待写操作。 + 在重排序缓冲区管理期间等待写入。 ReorderLogicalMappingRead - 在重新排序缓冲区管理期间等待读取逻辑映射。 + 在重排序缓冲区管理期间等待读取逻辑映射。 @@ -1244,12 +1203,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser ReplicationSlotRestoreSync - 等待复制槽控制文件到达持久存储,同时将其恢复到内存中。 + 在将复制槽控制文件恢复到内存期间,等待该文件同步到持久存储。 ReplicationSlotSync - 等待复制槽控制文件到达持久存储。 + 等待复制槽控制文件同步到持久存储。 @@ -1259,7 +1218,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser SLRUFlushSync - 在检查点或数据库关闭期间等待SLRU数据到达持久存储。 + 在检查点或数据库关闭期间,等待 SLRU 数据同步到持久存储。 @@ -1269,7 +1228,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser SLRUSync - 在写页面后等待SLRU数据到达持久存储。 + 在页面写入后等待 SLRU 数据同步到持久存储。 @@ -1279,22 +1238,22 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser SnapbuildRead - 等待读取序列化的历史目录快照。 + 等待读取序列化的历史系统目录快照。 SnapbuildSync - 等待序列化历史目录快照到达持久存储。 + 等待序列化的历史系统目录快照同步到持久存储。 SnapbuildWrite - 等待串行历史目录快照的写入。 + 等待写入序列化的历史系统目录快照。 TimelineHistoryFileSync - 等待通过流复制接收的时间线历史文件到达持久存储。 + 等待通过流复制接收的时间线历史文件同步到持久存储。 @@ -1309,7 +1268,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser TimelineHistorySync - 等待新创建的时间线历史文件到达持久存储。 + 等待新创建的时间线历史文件同步到持久存储。 @@ -1324,7 +1283,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser TwophaseFileSync - 等待两阶段状态文件到达持久存储。 + 等待两阶段状态文件同步到持久存储。 @@ -1334,7 +1293,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser VersionFileSync - 等待版本文件达到持久存储,同时创建数据库。 + 在创建数据库时,等待版本文件同步到持久存储。 @@ -1344,7 +1303,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser WALBootstrapSync - 在引导过程中等待WAL达到持久存储。 + 在引导过程中等待 WAL 同步到持久存储。 @@ -1359,7 +1318,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser WALCopySync - 等待通过复制一个已有WAL段到持久存储来创建一个新的WAL段。 + 等待通过复制现有 WAL 段创建的新 WAL 段同步到持久存储。 @@ -1369,7 +1328,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser WALInitSync - 等待一个新初始化的WAL文件到持久存储。 + 等待新初始化的 WAL 文件同步到持久存储。 @@ -1384,22 +1343,22 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser WALSenderTimelineHistoryRead - 在walsender时间线命令期间等待从时间线历史文件读取。 + 在 WAL 发送进程执行时间线命令期间,等待从时间线历史文件读取。 WALSync - 等待WAL文件到达持久存储。 + 等待 WAL 文件同步到持久存储。 WALSyncMethodAssign - 等待数据到达持久存储,同时分配一个新的WAL同步方法。 + 在设置新的 WAL 同步方法时,等待数据同步到持久存储。 WALWrite - 等待写入WAL文件。 + 等待写入 WAL 文件。 @@ -1456,12 +1415,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser BtreePage - 正等待继续并行B-树扫描所需的页号变得可用。 + 等待继续并行 B-树扫描所需的页号变得可用。 BufferIO - 等待缓冲I/O结束。 + 等待缓冲区 I/O 完成。 @@ -1476,82 +1435,92 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser ExecuteGather - 在执行Gather 计划节点时,等待子进程的活动。 + 在执行 Gather 计划节点时,等待子进程的活动。 HashBatchAllocate - 等待一个选定的并行哈希参与者分配哈希表。 + 等待选出的 Parallel Hash 参与者分配哈希表。 HashBatchElect - 等待选择一个并行哈希参与者来分配哈希表。 + 等待选出负责分配哈希表的 Parallel Hash 参与者。 HashBatchLoad - 等待其他并行哈希参与者完成哈希表的加载。 + 等待其他 Parallel Hash 参与者完成哈希表的加载。 HashBuildAllocate - 等待一个选定的并行哈希参与者分配初始哈希表。 + 等待选出的 Parallel Hash 参与者分配初始哈希表。 HashBuildElect - 等待选择一个并行哈希参与者来分配初始哈希表。 + 等待选出负责分配初始哈希表的 Parallel Hash 参与者。 HashBuildHashInner - 等待其他并行哈希参与者完成内部关系的散列。 + 等待其他 Parallel Hash 参与者完成对内层关系的哈希处理。 HashBuildHashOuter - 等待其他Parallel 哈希参与者完成对外部关系的分区。 - - - - HashGrowBatchesAllocate - 等待选定的并行哈希参与者分配更多批处理。 + 等待其他 Parallel Hash 参与者完成对外层关系的分区。 HashGrowBatchesDecide - 等待选择一个并行哈希参与者来决定未来的批处理增长。 + 等待选出负责决定后续批次增长的 Parallel Hash 参与者。 HashGrowBatchesElect - 等待选择一个Parallel 哈希参与者来分配更多批处理。 + 等待选出负责分配更多批次的 Parallel Hash 参与者。 HashGrowBatchesFinish - 等待当选的平行散列参与者决定未来的批量增长。 + 等待选出的 Parallel Hash 参与者决定后续的批次增长。 - HashGrowBatchesRepartition - 等待一个选定的并行哈希参与者决定未来的批处理增长。 + HashGrowBatchesReallocate + 等待选出的 Parallel Hash 参与者分配更多批次。 - HashGrowBucketsAllocate - 等待选定的并行哈希参与者完成更多bucket的分配。 + HashGrowBatchesRepartition + 等待其他 Parallel Hash 参与者完成重新分区。 HashGrowBucketsElect - 等待选择一个并行哈希参与者来分配更多的buckets。 + 等待选出负责分配更多桶的 Parallel Hash 参与者。 + + + + HashGrowBucketsReallocate + 等待选出的 Parallel Hash 参与者完成更多桶的分配。 HashGrowBucketsReinsert - 等待其他Parallel 哈希参与者完成将元组插入到新buckets中。 + 等待其他 Parallel Hash 参与者完成向新桶插入元组。 + + + + LogicalApplySendData + 等待逻辑复制领导者应用进程向并行应用进程发送数据。 + + + + LogicalParallelApplyStateChange + 等待逻辑复制并行应用进程改变状态。 @@ -1586,22 +1555,22 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser ParallelBitmapScan - 等待并行位图扫描被初始化。 + 等待并行位图扫描完成初始化。 ParallelCreateIndexScan - 等待并行CREATE INDEX 工作进程完成堆扫描。 + 等待并行 CREATE INDEX 工作进程完成堆扫描。 ParallelFinish - 等待并行工作人员完成计算。 + 等待并行工作进程完成计算。 ProcArrayGroupUpdate - 等待组领导在并行操作结束时清除事务ID。 + 等待组领导者在事务结束时清除事务 ID。 @@ -1616,12 +1585,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser RecoveryConflictSnapshot - 等待vacuum清理的恢复冲突解决。 + 等待解决清理操作引发的恢复冲突。 RecoveryConflictTablespace - 等待恢复冲突解决删除表空间。 + 等待解决删除表空间引发的恢复冲突。 @@ -1656,7 +1625,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser SyncRep - 在同步复制期间等待远程服务器的确认。 + 在同步复制期间等待来自远程服务器的确认。 @@ -1671,7 +1640,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser XactGroupUpdate - 等待分组组长在并行操作结束时更新事务状态。 + 等待组领导者在事务结束时更新事务状态。 @@ -1693,7 +1662,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser advisory - 等待获得一个建议用户锁。 + 等待获取用户咨询锁。 + + + + applytransaction + 等待获取逻辑复制订阅者正在应用的远程事务上的锁。 @@ -1703,8 +1677,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser frozenid - 等待升级 pg_database.datfrozenxid - 和 pg_database.datminmxid. + 等待更新 pg_database.datfrozenxidpg_database.datminmxid @@ -1719,12 +1692,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser relation - 等待获得一个关系的锁。 + 等待获取关系上的锁。 spectoken - 等待获取推测的插入锁。 + 等待获取推测插入锁。 @@ -1744,7 +1717,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser virtualxid - 等待获取虚拟事务ID锁。 + 等待获取虚拟事务 ID 锁;参见 @@ -1766,7 +1739,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser AddinShmemInit - 等待管理共享内存中的扩展空间分配。 + 等待管理扩展在共享内存中的空间分配。 @@ -1781,7 +1754,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser AutovacuumSchedule - 等待确保选择为自动清理的表仍然需要清理。 + 等待确认选中进行自动清理的表是否仍需清理。 @@ -1811,7 +1784,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser CommitTs - 等待读取或更新事务提交时间戳的最后一个值集。 + 等待读取或更新最近设置的事务提交时间戳值。 @@ -1841,42 +1814,52 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser LockManager - 等待读取或更新关于heavyweight锁。 + 等待读取或更新有关重量级锁的信息。 + + + + LogicalRepLauncherDSA + 等待访问逻辑复制启动进程的动态共享内存分配器。 + + + + LogicalRepLauncherHash + 等待访问逻辑复制启动进程的共享哈希表。 LogicalRepWorker - 等待读取或更新逻辑复制工作器的状态。 + 等待读取或更新逻辑复制工作进程的状态。 MultiXactGen - 等待读取或更新共享的multixact状态。 + 等待读取或更新共享的多事务状态。 MultiXactMemberBuffer - 在multixact成员SLRU缓冲区上等待I/O。 + 等待多事务成员 SLRU 缓冲区上的 I/O。 MultiXactMemberSLRU - 等待访问multixact成员SLRU缓存。 + 等待访问多事务成员 SLRU 缓存。 MultiXactOffsetBuffer - 在multixact 偏移 SLRU缓冲区上等待I/O。 + 等待多事务偏移量 SLRU 缓冲区上的 I/O。 MultiXactOffsetSLRU - 等待访问multixact 偏移 SLRU缓存。 + 等待访问多事务偏移量 SLRU 缓存。 MultiXactTruncation - 等待读取或截断multixact信息。 + 等待读取或截断多事务信息。 @@ -1891,7 +1874,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser NotifyQueueTail - 等待NOTIFY消息存储上的更新限制。 + 等待更新 NOTIFY 消息存储的限制。 @@ -1911,12 +1894,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser ParallelAppend - 在并行附加计划执行期间等待选择下一个子计划。 + 在 Parallel Append 计划执行期间等待选择下一个子计划。 ParallelHashJoin - 在并行哈希连接计划执行期间等待同步工作器。 + 在 Parallel Hash Join 计划执行期间等待同步工作进程。 @@ -1931,12 +1914,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser PerSessionRecordType - 等待访问有关复合类型的并行查询信息。 + 等待访问并行查询中有关复合类型的信息。 PerSessionRecordTypmod - 等待访问有关标识匿名记录类型的类型修饰符的并行查询信息。 + 等待访问并行查询中用于标识匿名记录类型的类型修饰符信息。 @@ -1944,6 +1927,21 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 在并行查询期间等待访问当前可串行化事务持有的谓词锁列表。 + + PgStatsData + 等待访问共享内存中的统计数据。 + + + + PgStatsDSA + 等待访问统计信息的动态共享内存分配器。 + + + + PgStatsHash + 等待访问统计信息的共享内存哈希表。 + + PredicateLockManager 等待访问可串行化事务使用的谓词锁信息。 @@ -1951,7 +1949,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser ProcArray - 等待访问每个进程共享的数据结构(通常情况,是获取快照或报告会话的事务ID)。 + 等待访问各进程的共享数据结构(通常是为了获取快照或报告会话的事务 ID)。 @@ -1986,7 +1984,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser ReplicationSlotIO - 在复制槽上等待 I/O。 + 在复制槽上等待I/O。 @@ -2004,21 +2002,6 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 等待访问可串行化事务持有的谓词锁列表。 - - PgStatsDSA - 等待统计动态共享内存分配器访问 - - - - PgStatsHash - 等待统计共享内存哈希表访问 - - - - PgStatsData - 等待共享内存统计数据访问 - - SerializableXactHash 等待读取或更新关于可串行化事务的信息。 @@ -2046,12 +2029,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser SInvalRead - 等待从共享目录失效队列中检索消息。 + 等待从共享系统目录失效队列中取出消息。 SInvalWrite - 等待向共享编目失效队列添加消息。 + 等待向共享系统目录失效队列添加消息。 @@ -2081,7 +2064,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser TwoPhaseState - 等待读取或更新已准备事务的状态。 + 等待读取或更新预备事务的状态。 @@ -2101,7 +2084,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser WrapLimitsVacuum - 等待更新事务 ID和multixact消费的限制。 + 等待更新事务 ID 和多事务消耗量的限制。 @@ -2130,8 +2113,8 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - 扩展可以将ExtensionInjectionPointLWLock 类型添加到所示的列表中。 - 在某些情况下,扩展分配的 LWLock 名称无法在所有服务器进程中使用;因此,LWLock 等待事件可能只会被报告为extension,而不是扩展分配的名称。 + 扩展可以将LWLock 类型添加到所示的列表中。 + 在某些情况下,扩展分配的名称无法在所有服务器进程中使用;因此,LWLock 等待事件可能只会被报告为extension,而不是扩展分配的名称。 @@ -2151,12 +2134,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser BaseBackupThrottle - 当有限流活动时在基础备份期间等待。 + 在基础备份期间因限流而等待。 CheckpointWriteDelay - 在执行检查点时写入之间的等待时间。 + 在执行检查点时,在各次写入之间等待。 @@ -2176,12 +2159,17 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser RegisterSyncRequest - 在发送同步请求到检查点程序时等待,因为请求队列已满。 + 向检查点进程发送同步请求时,因请求队列已满而等待。 + + + + SpinDelay + 在获取有竞争的自旋锁时等待。 VacuumDelay - 在一个基于代价的清理延迟点。 + 在基于代价的清理延迟点等待。 @@ -2193,7 +2181,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - 这里是一个查看等待事件的示例: + 以下示例展示如何查看等待事件: SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event is NOT NULL; @@ -2204,17 +2192,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i (2 rows) - -SELECT a.pid, a.wait_event, w.description - FROM pg_stat_activity a JOIN - pg_wait_events w ON (a.wait_event_type = w.type AND - a.wait_event = w.name) - WHERE a.wait_event is NOT NULL and a.state = 'active'; --[ RECORD 1 ]------------------------------------------------------&zwsp;------------ -pid | 686674 -wait_event | WALInitSync -description | Waiting for a newly initialized WAL file to reach durable storage - + @@ -2291,7 +2269,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage 连接到这个 WAL 发送进程的客户端的 IP 地址。 - 如果这个域为空,它表示该客户端通过服务器机器上的一个Unix 套接字连接。 + 如果这个字段为空值,它表示该客户端通过服务器机器上的一个Unix 套接字连接。 @@ -2342,27 +2320,27 @@ description | Waiting for a newly initialized WAL file to reach durable storage - startup: 此 WAL 发送进程正在启动。 + startup: 此 WAL 发送进程正在启动。 - catchup: 与此 WAL 发送进程连接的备库正在赶上主库。 + catchup: 与此 WAL 发送进程连接的备库正在赶上主库。 - streaming: 在其连接的备库赶上主库之后,此 WAL 发送进程正在流式传输更改。 + streaming: 在其连接的备库赶上主库之后,此 WAL 发送进程正在流式传输更改。 - backup: 此 WAL 发送进程正在发送一个备份。 + backup: 此 WAL 发送进程正在发送一个备份。 - stopping: 此 WAL 发送进程正在停止。 + stopping: 此 WAL 发送进程正在停止。 @@ -2409,30 +2387,21 @@ description | Waiting for a newly initialized WAL file to reach durable storage write_lag interval - - 从本地刷写最近的 WAL,到收到该备库已写入该 WAL(但尚未刷盘或应用)的通知之间经过的时间。 - 如果该服务器被配置为同步备库,可用此值衡量在提交时 synchronous_commit 级别 remote_write 所导致的延迟。 - + 从在本地将最近的 WAL 刷盘,到收到该备库已写入该 WAL(但尚未刷盘或应用)的通知之间经过的时间。如果该服务器被配置为同步备库,可用此值衡量在提交时synchronous_commit级别remote_write所导致的延迟。 flush_lag interval - - 从本地刷写最近的 WAL,到收到该备库已写入并刷写该 WAL(但尚未应用)的通知之间经过的时间。 - 如果该服务器被配置为同步备库,可用此值衡量在提交时 synchronous_commit 级别 on 所导致的延迟。 - + 从在本地将最近的 WAL 刷盘,到收到该备库已写入该 WAL 并将其刷盘(但尚未应用)的通知之间经过的时间。如果该服务器被配置为同步备库,可用此值衡量在提交时synchronous_commit级别on所导致的延迟。 replay_lag interval - - 从本地刷写最近的 WAL,到收到该备库已写入、刷写并应用该 WAL 的通知之间经过的时间。 - 如果该服务器被配置为同步备库,可用此值衡量在提交时 synchronous_commit 级别 remote_apply 所导致的延迟。 - + 从在本地将最近的 WAL 刷盘,到收到该备库已写入该 WAL、将其刷盘并应用的通知之间经过的时间。如果该服务器被配置为同步备库,可用此值衡量在提交时synchronous_commit级别remote_apply所导致的延迟。 @@ -2454,22 +2423,22 @@ description | Waiting for a newly initialized WAL file to reach durable storage - async: 该备库是异步的。 + async: 该备库是异步的。 - potential: 该备库当前是异步的,但在当前同步备库失效时可能变为同步的。 + potential: 该备库当前是异步的,但在当前某个同步备库失效时可能变为同步的。 - sync: 该备库是同步的。 + sync: 该备库是同步的。 - quorum: 该备库被作为法定人数同步复制候选备库。 + quorum: 该备库被作为法定人数同步复制候选备库。 @@ -2478,7 +2447,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - reply_time 带时区的时间戳 + reply_time timestamp with time zone 从备库收到的最后一条回复消息的发送时间 @@ -2489,17 +2458,17 @@ description | Waiting for a newly initialized WAL file to reach durable storage - pg_stat_replication视图中报告的滞后时间,是最近的 WAL 被写入、刷写和重放,以及发送端获知这些操作完成所花费时间的度量。如果远程服务器被配置为同步备库,这些时间表示各个同步提交级别带来或可能带来的提交延迟。对于异步备库,replay_lag列是最近事务对查询变得可见所需延迟时间的近似值。如果备库已经完全追上发送服务器且没有新的 WAL 活动,系统会在短时间内继续显示最近测得的滞后时间,随后显示为 NULL。 + pg_stat_replication视图中报告的滞后时间,是最近的 WAL 被写入、刷盘和重放,以及发送端获知这些操作完成所花费时间的度量。如果远程服务器被配置为同步备库,这些时间表示各个同步提交级别带来或可能带来的提交延迟。对于异步备库,replay_lag列是最近事务对查询变得可见所需延迟时间的近似值。如果备库已经完全追上发送服务器且没有新的 WAL 活动,系统会在短时间内继续显示最近测得的滞后时间,随后显示为 空值。 - 对于物理复制,滞后时间会自动测量。逻辑解码插件可以选择发出跟踪消息;如果没有这样做,跟踪机制会将滞后显示为 NULL。 + 对于物理复制,滞后时间会自动测量。逻辑解码插件可以选择发出跟踪消息;如果没有这样做,跟踪机制会将滞后显示为 空值。 - 报告出的滞后时间并不是根据当前重放速率预测该备库还需多久才能追上发送服务器。在持续生成新 WAL 时,那样的系统可能会显示相近的时间;但当发送端空闲时,就会显示不同的值。特别是当备库已经完全追上时,pg_stat_replication显示的是写入、刷写和重放最近报告的 WAL 位置所花费的时间,而不是某些用户可能预期的零。这样做符合为最近写事务测量同步提交和事务可见性延迟的目的。为减少用户因预期另一种滞后模型而产生的混淆,在一个已完全重放且处于空闲状态的系统上,lag 列会在较短时间后恢复为 NULL。监控系统应自行决定将这种情况表示为缺失数据、零,还是继续显示最近一次已知值。 + 报告出的滞后时间并不是根据当前重放速率预测该备库还需多久才能追上发送服务器。在持续生成新 WAL 时,那样的系统可能会显示相近的时间;但当发送端空闲时,就会显示不同的值。特别是当备库已经完全追上时,pg_stat_replication显示的是写入、刷盘和重放最近报告的 WAL 位置所花费的时间,而不是某些用户可能预期的零。这样做符合为最近写事务测量同步提交和事务可见性延迟的目的。为减少用户因预期另一种滞后模型而产生的混淆,在一个已完全重放且处于空闲状态的系统上,滞后列会在较短时间后恢复为 空值。监控系统应自行决定将这种情况表示为缺失数据、零,还是继续显示最近一次已知值。 @@ -2538,19 +2507,14 @@ description | Waiting for a newly initialized WAL file to reach durable storage slot_name text - - 唯一的,复制槽的集簇范围标识符 - + 复制槽在整个集簇范围内的唯一标识符 spill_txns bigint - - 当逻辑解码在解码来自WAL的更改时所使用的内存超过logical_decoding_work_mem,溢出到磁盘的事务数。 - 顶级事务和子事务的计数器都是递增的。 - + 当逻辑解码从 WAL 解码更改时所使用的内存超过logical_decoding_work_mem后,溢出到磁盘的事务数。顶层事务和子事务都会使此计数器递增。 @@ -2558,7 +2522,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage spill_count bigint - 在为该槽位解码来自WAL的更改时,事务溢出到磁盘的次数。 + 在为该槽解码来自WAL的更改时,事务溢出到磁盘的次数。 此计数器在每次事务被溢出时递增,并且同一事务可能被溢出多次。 @@ -2567,20 +2531,14 @@ description | Waiting for a newly initialized WAL file to reach durable storage spill_bytes bigint - - 在对来自WAL的更改执行解码时,已解码的事务数据溢出到磁盘的数量。 - 这个和其他溢出计数器可用于测量逻辑解码期间发生的I/O,并且允许调优logical_decoding_work_mem。 - + 为此槽从 WAL 解码更改时,溢出到磁盘的已解码事务数据量。此计数器及其他溢出计数器可用于衡量逻辑解码期间发生的 I/O,并用于调优logical_decoding_work_mem stream_txns bigint - - 在逻辑解码在解码来自该槽位的WAL更改的时候,所使用的内存超过logical_decoding_work_mem之后,流式传输到解码输出插件的正在进行的事务数。 - 流式传输仅对顶级事务有效(子事务不能独立进行流式传输),因此子事务的计数器不会增加。 - + 当逻辑解码为此槽从 WAL 解码更改时所使用的内存超过logical_decoding_work_mem后,流式传输到解码输出插件的进行中事务数。流式传输仅适用于顶层事务(子事务不能单独进行流式传输),因此子事务不会使此计数器递增。 @@ -2588,7 +2546,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage stream_countbigint - 在为该槽位解码来自WAL的更改时,将正在进行的事务流式传输到解码输出插件的次数。 + 在为该槽解码来自WAL的更改时,将进行中事务流式传输到解码输出插件的次数。 此计数器在每次事务流式传输时递增,并且同一事务可能被流式传输多次。 @@ -2598,8 +2556,8 @@ description | Waiting for a newly initialized WAL file to reach durable storage stream_bytesbigint - 在为该槽位解码来自WAL的更改时,为将正在进行的事务流式传输到解码输出插件而解码的事务数据的数量。 - 这个和针对此槽位的其他流式传输计数器可用于调优logical_decoding_work_mem。 + 在为该槽解码来自WAL的更改时,为将进行中事务流式传输到解码输出插件而解码的事务数据量。 + 这个和针对此槽的其他流式传输计数器可用于调优logical_decoding_work_mem @@ -2610,7 +2568,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage 针对此槽的,发送到解码输出插件的已解码事务数。 - 这只计算顶级事务,对子事务不会增加。 + 这只计算顶层事务,对子事务不会增加。 注意,这包括流式传输和/或溢出的事务。 @@ -2620,7 +2578,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage total_bytesbigint - 在对此槽位的WAL进行解码时,为将事务发送到解码输出插件而解码的事务数据量。 + 在为此槽从 WAL 解码更改时,为将事务发送到解码输出插件而解码的事务数据量。 注意这包括流式传输和/或溢出的数据。 @@ -2630,9 +2588,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage stats_reset timestamp with time zone - - 这些统计最后重置的时间 - + 这些统计信息上次被重置的时间 @@ -2647,9 +2603,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage pg_stat_wal_receiver - - pg_stat_wal_receiver事务只包含一行,它显示了从 WAL 接收进程所连接的服务器得到的有关该接收进程的统计信息。 - + pg_stat_wal_receiver视图只包含一行,显示 WAL 接收进程从其所连接服务器接收数据的统计信息。 @@ -2674,7 +2628,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage pidinteger - WAL 接收进程的进程ID + WAL 接收进程的进程 ID @@ -2683,7 +2637,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage statustext - WAL接收进程的活动状态 + WAL 接收进程的活动状态 @@ -2692,7 +2646,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage receive_start_lsnpg_lsn - WAL 接收进程启动时使用的第一个写前日志位置 + WAL 接收进程启动时使用的第一个预写式日志位置 @@ -2701,7 +2655,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage receive_start_tliinteger - WAL 接收进程启动时使用的第一个时间线数字 + WAL 接收进程启动时使用的第一个时间线编号 @@ -2710,7 +2664,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage written_lsnpg_lsn - 已经接收并写入磁盘的最后一个预写式日志位置,但没有刷入。这不能用于数据完整性检查。 + 已经接收并写入磁盘的最后一个预写式日志位置,但尚未刷盘。此字段不应用于数据完整性检查。 @@ -2719,7 +2673,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage flushed_lsnpg_lsn - 已经接收并刷入到磁盘的最后一个预写式日志位置,该字段的初始值是启动WAL 接收进程时使用的第一个日志位置 + 已经接收并刷入到磁盘的最后一个预写式日志位置,该字段的初始值是启动 WAL 接收进程时使用的第一个日志位置 @@ -2728,7 +2682,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage received_tliinteger - 接收并刷入到磁盘的最后一个预写式日志位置的时间线数字,该字段的初始值为启动WAL 接收进程时使用的第一个日志位置的时间线数字 + 接收并刷入到磁盘的最后一个预写式日志位置的时间线编号,该字段的初始值为启动 WAL 接收进程时使用的第一个日志位置的时间线编号 @@ -2773,7 +2727,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage slot_nametext - 这个WAL 接收进程使用的复制槽的名称 + 这个 WAL 接收进程使用的复制槽的名称 @@ -2782,8 +2736,8 @@ description | Waiting for a newly initialized WAL file to reach durable storage sender_hosttext - 这个WAL 接收进程连接到的PostgreSQL实例的主机。 - 这可以是主机名、IP地址,或者目录路径,如果连接是通过Unix套接字进行的。(路径的情况可以区分,因为它总是以/开头的绝对路径。) + 这个 WAL 接收进程连接到的PostgreSQL实例的主机。 + 这可以是主机名、IP地址,或者目录路径,如果连接是通过Unix套接字进行的。(路径的情况可以区分,因为它总是以/开头的绝对路径。) @@ -2792,7 +2746,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage sender_portinteger - 这个WAL 接收进程连接的PostgreSQL实例的端口号。 + 这个 WAL 接收进程连接的PostgreSQL实例的端口号。 @@ -2801,7 +2755,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage conninfotext - 这个WAL 接收进程使用的连接字符串,对安全敏感的字段进行了模糊处理。 + 这个 WAL 接收进程使用的连接字符串,对安全敏感的字段进行了模糊处理。 @@ -2847,9 +2801,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage stats_reset timestamp with time zone - - 这些统计数据上次重置的时间 - + 这些统计信息上次被重置的时间 @@ -2924,9 +2876,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage wal_distance int - - 预取器向前查看多少字节 - + 预取器向前查看的字节数 @@ -2935,9 +2885,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage block_distance int - - 预取器正在查看多少个块之前 - + 预取器向前查看的块数 @@ -2946,9 +2894,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage io_depth int - - 已启动但尚未完成的预取数量 - + 已启动但尚未确认完成的预取数量 @@ -2991,7 +2937,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + subname name @@ -3000,77 +2946,78 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + - worker_type text + pid integer - 订阅工作进程的类型。可能的类型有 applyparallel applytable synchronization。 + 订阅工作进程的进程 ID - + - pid integer + leader_pid integer - 订阅工作进程的进程 ID + 如果此进程是并行应用工作进程,则为领导者应用工作进程的进程 ID;如果此进程是领导者应用工作进程或同步工作进程,则为 NULL - + relid oid - 该工作进程正在同步的关系的 OID;主应用工作进程则为 NULL + 该工作进程正在同步的关系的 OID;对于领导者应用工作进程和并行应用工作进程,则为空值 - + received_lsn pg_lsn - 接收到的最后一个预写式日志位置,该字段的初始值为0 + 接收到的最后一个预写式日志位置,该字段的初始值为 0;对于并行应用工作进程,则为 NULL - + last_msg_send_time timestamp with time zone - 从源 WAL 发送进程收到的最后一条消息的发送时间 + 从源 WAL 发送进程收到的最后一条消息的发送时间;对于并行应用工作进程,则为 NULL - + last_msg_receipt_time timestamp with time zone - 从源 WAL 发送进程收到的最后一条消息的接收时间 + 从源 WAL 发送进程收到的最后一条消息的接收时间;对于并行应用工作进程,则为 NULL - + latest_end_lsn pg_lsn - 向源 WAL 发送进程报告的最后一个预写式日志位置 + 向源 WAL 发送进程报告的最后一个预写式日志位置;对于并行应用工作进程,则为 NULL - + latest_end_time timestamp with time zone - 向 WAL 发送进程报告最后一个预写式日志位置的时间 + 向源 WAL 发送进程报告最后一个预写式日志位置的时间;对于并行应用工作进程,则为 NULL +
@@ -3146,9 +3093,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage stats_reset timestamp with time zone - - 这些统计数据最后一次重置的时间 - + 这些统计信息上次被重置的时间
@@ -3209,7 +3154,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage version text - 使用SSL的版本,如果此连接上没有使用SSL则为NULL + 使用SSL的版本,如果此连接上没有使用SSL则为空值
@@ -3218,7 +3163,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage cipher text - 正在使用的SSL密码的名称,如果此连接上没有使用SSL则为NULL + 正在使用的SSL 密码套件的名称,如果此连接上没有使用SSL则为空值
@@ -3227,7 +3172,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage bits integer - 使用的加密算法中的位数,如果此连接上没有使用SSL则为NULL + 使用的加密算法中的位数,如果此连接上没有使用SSL则为空值
@@ -3236,8 +3181,8 @@ description | Waiting for a newly initialized WAL file to reach durable storage client_dn text - 区别名称(DN,Distinguished Name)字段与使用的客户端证书,如果没有提供客户端证书或在此连接上没有使用SSL,则为NULL。 - 如果DN字段长于NAMEDATALEN(标准构建中为64个字符),则该字段将被截断。 + 所用客户端证书中的区别名称(DN,Distinguished Name)字段,如果没有提供客户端证书或在此连接上没有使用SSL,则为空值。 + 如果DN字段长于NAMEDATALEN(标准构建中为64个字符),则该字段将被截断。
@@ -3246,8 +3191,8 @@ description | Waiting for a newly initialized WAL file to reach durable storage client_serial numeric - 客户端证书的序列号,如果没有提供客户端证书或在此连接上没有使用SSL,则为NULL。 - 证书序列号和证书颁发者的组合唯一标识一个证书(除非颁发者错误地重用序列号)。 + 客户端证书的序列号,如果没有提供客户端证书或在此连接上没有使用SSL,则为空值。 + 证书序列号和证书颁发者的组合唯一标识一个证书(除非颁发者错误地重用序列号)。
@@ -3256,7 +3201,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage issuer_dn text - 客户端证书颁发者的区别名称(DN,Distinguished Name),如果没有提供客户端证书或在此连接上没有使用SSL,则为NULL。该字段像client_dn一样被截断。 + 客户端证书颁发者的区别名称(DN,Distinguished Name),如果没有提供客户端证书或在此连接上没有使用SSL,则为空值。该字段像client_dn一样被截断。
@@ -3274,7 +3219,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage pg_stat_gssapi视图将包含每一个后端一个行,显示该连接上的GSSAPI使用情况。 - 它可以加入到pg_stat_activitypg_stat_replication上的pid列,获取更多关于连接的详细信息。 + 可以通过pid列将它与pg_stat_activitypg_stat_replication连接,获取更多关于连接的详细信息。 @@ -3318,8 +3263,8 @@ description | Waiting for a newly initialized WAL file to reach durable storage principaltext - 用于验证此连接的主体,如果未使用GSSAPI对此连接进行认证,则为NULL。 - 如果主体长度超过NAMEDATALEN(标准构建中为64个字符),则该字段被截断。 + 用于认证此连接的主体,如果未使用GSSAPI对此连接进行认证,则为空值。 + 如果主体长度超过NAMEDATALEN(标准构建中为64个字符),则该字段被截断。 @@ -3433,9 +3378,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage stats_reset timestamp with time zone - - 这些统计数据最后一次重置的时间 - + 这些统计信息上次被重置的时间 @@ -3459,9 +3402,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage pg_stat_io 视图对每种后端类型、目标 I/O 对象和 I/O 上下文的组合各提供一行,显示整个集簇范围内的 I/O 统计信息。没有意义的组合会被省略。 - - 目前会跟踪关系(例如表、索引)的 I/O 以及 WAL 活动。不过,绕过共享缓冲区的关系 I/O(例如将表从一个表空间移动到另一个表空间时)目前不会被跟踪。 - + 目前会跟踪关系(例如表、索引)的 I/O。不过,绕过共享缓冲区的关系 I/O(例如将表从一个表空间移动到另一个表空间时)目前不会被跟踪。
<structname>pg_stat_io</structname> 视图 @@ -3485,7 +3426,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage backend_typetext - 后端类型(例如后台工作进程、autovacuum 工作进程)。有关 backend_type 的更多信息,请参阅pg_stat_activity。某些 backend_type 不会累计 I/O 操作统计信息,因此不会出现在该视图中。 + 后端类型(例如后台工作进程、自动清理工作进程)。有关 backend_type 的更多信息,请参阅pg_stat_activity。某些 backend_type 不会累积 I/O 操作统计信息,因此不会出现在该视图中。 @@ -3497,7 +3438,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage I/O 操作的目标对象。可能的值有: - + @@ -3509,12 +3450,9 @@ description | Waiting for a newly initialized WAL file to reach durable storage temp relation:临时关系。 - - - wal:预写式日志。 - - + + @@ -3532,14 +3470,10 @@ description | Waiting for a newly initialized WAL file to reach durable storage normal:某类 I/O 操作的默认或标准 context。例如,默认情况下关系数据会读入共享缓冲区并从共享缓冲区写出,因此关系数据与共享缓冲区之间的读写会在 contextnormal 时跟踪。 + - init:创建 WAL 段时执行的 I/O 操作会在 contextinit 时跟踪。 - - - - - vacuum:对永久关系执行 vacuum 和 analyze 时,在共享缓冲区之外执行的 I/O 操作。临时表 vacuum 与其他临时表 I/O 操作共用同一本地缓冲池,因此会在 contextnormal 时跟踪。 + vacuum:对永久关系执行清理和分析 时,在共享缓冲区之外执行的 I/O 操作。临时表清理 与其他临时表 I/O 操作共用同一本地缓冲池,因此会在 contextnormal 时跟踪。 @@ -3562,18 +3496,21 @@ description | Waiting for a newly initialized WAL file to reach durable storage reads bigint - 读取操作的数量。 + 读取操作的次数,每次操作的大小由op_bytes指定。 + + - read_bytes numeric + read_time double precision - 读取操作的总大小(以字节为单位)。 + 在读取操作中花费的时间,以毫秒计(如果启用了 + ,否则为零)。 @@ -3581,21 +3518,24 @@ description | Waiting for a newly initialized WAL file to reach durable storage - read_time double precision + writes bigint - 等待读取操作所花费的时间,以毫秒计(如果启用了 object 不是 wal,或者启用了 objectwal;否则为零)。 + 写入操作的次数,每次操作的大小由op_bytes指定。 + + - writes bigint + write_time double precision - 写入操作的数量。 + 在写入操作中花费的时间,以毫秒计(如果启用了 + ,否则为零)。 @@ -3603,10 +3543,10 @@ description | Waiting for a newly initialized WAL file to reach durable storage - write_bytes numeric + writebacks bigint - 写入操作的总大小(以字节为单位)。 + 进程请求内核写出到永久存储的、大小为op_bytes的单元数。 @@ -3614,10 +3554,12 @@ description | Waiting for a newly initialized WAL file to reach durable storage - write_time double precision + writeback_time double precision - 等待写入操作所花费的时间,以毫秒计(如果启用了 object 不是 wal,或者启用了 objectwal;否则为零)。 + 在写回操作中花费的时间,以毫秒计(如果启用了 + ,否则为零)。这包括排队写出请求 + 所花费的时间,以及可能实际写出脏数据所花费的时间。 @@ -3625,32 +3567,24 @@ description | Waiting for a newly initialized WAL file to reach durable storage - writebacks bigint + extends bigint - 进程请求内核写出到永久存储的、大小为 BLCKSZ(通常为 8kB)的单位数量。 + 关系扩展操作的次数,每次操作的大小由op_bytes指定。 - - - - writeback_time double precision - - - 等待写回操作所花费的时间,以毫秒计(如果启用了 ,否则为零)。这包括排队写出请求所花费的时间,以及可能实际写出脏数据所花费的时间。 - - - + - extends bigint + extend_time double precision - 关系扩展操作的数量。 + 在扩展操作中花费的时间,以毫秒计(如果启用了 + ,否则为零)。 @@ -3658,21 +3592,14 @@ description | Waiting for a newly initialized WAL file to reach durable storage - extend_bytes numeric + op_bytes bigint - 关系扩展操作的总大小(以字节为单位)。 - - - - - - - - extend_time double precision + 每个 I/O 读取、写入或扩展单位的字节数。 - 等待扩展操作所花费的时间,以毫秒计(如果启用了 object 不是 wal,或者启用了 objectwal;否则为零)。 + 关系数据的读取、写入和扩展以block_size为单位进行,该值 + 来自构建时参数BLCKSZ,默认值为8192 @@ -3730,7 +3657,8 @@ description | Waiting for a newly initialized WAL file to reach durable storage fsync_time double precision - 等待 fsync 操作所花费的时间,以毫秒计(如果启用了 object 不是 wal,或者启用了 objectwal;否则为零)。 + 在 fsync 操作中花费的时间,以毫秒计(如果启用了 + ,否则为零)。 @@ -3740,9 +3668,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage stats_reset timestamp with time zone - - 这些统计信息上次被重置的时间。 - + 这些统计信息上次被重置的时间。 @@ -3754,12 +3680,10 @@ description | Waiting for a newly initialized WAL file to reach durable storage - 此外,某些 I/O 操作永远不会由某些后端类型执行,或者永远不会针对某些 I/O 对象和/或在某些 I/O 上下文中执行。这些单元格会是 NULL。例如,临时表不会执行 fsync,因此当 objecttemp relation 时,fsyncs 将为 NULL。又如,后台写入器不会执行读取,因此当 backend_typebackground writer 时,reads 将为 NULL。 + 此外,某些 I/O 操作永远不会由某些后端类型执行,或者永远不会针对某些 I/O 对象和/或在某些 I/O 上下文中执行。这些单元格会是空值。例如,临时表不会执行 fsync,因此当 objecttemp relation 时,fsyncs 将为空值。又如,后台写入器不会执行读取,因此当 backend_typebackground writer 时,reads 将为空值。 - - 对于 objectwal 的行,fsyncsfsync_time 跟踪在 issue_xlog_fsync 中完成的 WAL 文件 fsync 活动;writeswrite_time 跟踪在 XLogWrite 中完成的 WAL 文件写入活动。更多信息请参阅。 - + pg_stat_io 可用于指导数据库调优。例如: @@ -3771,7 +3695,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - 客户端后端依赖检查点进程确保数据持久化到永久存储。客户端后端出现大量 fsyncs 可能表明共享缓冲区或检查点进程配置不当。有关配置检查点进程的更多信息,请参阅。 + 客户端后端依赖检查点进程确保数据持久化到永久存储。client backend出现大量 fsyncs 可能表明共享缓冲区或检查点进程配置不当。有关配置检查点进程的更多信息,请参阅 @@ -3783,9 +3707,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - - 跟踪 I/O 等待时间的列只有在启用 时才会非零。若自上次统计信息重置以来的整个时间段内并未始终启用 track_io_timing,则用户在将这些列与对应的 I/O 操作结合引用时应格外小心。 - + 跟踪 I/O 时间的列只有在启用时才会非零。若自上次统计信息重置以来的整个时间段内并未始终启用track_io_timing,则用户在将这些列与对应的 I/O 操作结合引用时应格外小心。 @@ -3798,7 +3720,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - pg_stat_bgwriter 视图始终只有一行,包含有关集簇后台写入器的数据。 + pg_stat_bgwriter 视图始终只有一行,包含整个集簇的全局数据。
@@ -3816,6 +3738,41 @@ description | Waiting for a newly initialized WAL file to reach durable storage + + + checkpoints_timed bigint + + 已执行的计划检查点数 + + + + + checkpoints_req bigint + + 已执行的请求检查点数 + + + + + checkpoint_write_time double precision + + 检查点处理中将文件写入磁盘部分所花费的总时间,单位为毫秒 + + + + + checkpoint_sync_time double precision + + 检查点处理中将文件同步到磁盘部分所花费的总时间,单位为毫秒 + + + + + buffers_checkpoint bigint + + 检查点期间写入的缓冲区数 + + buffers_clean bigint @@ -3834,6 +3791,20 @@ description | Waiting for a newly initialized WAL file to reach durable storage + + + buffers_backend bigint + + 后端直接写入的缓冲区数 + + + + + buffers_backend_fsync bigint + + 后端必须自行执行fsync调用的次数(通常即使后端自行写入,也由后台写入器处理这些调用) + + buffers_alloc bigint @@ -3847,9 +3818,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage stats_reset timestamp with time zone - - 这些统计信息上次被重置的时间 - + 这些统计信息上次被重置的时间 @@ -3909,7 +3878,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage wal_bytesnumeric - 生成的WAL总数,以字节计 + 生成的 WAL 总量,以字节计 @@ -3918,7 +3887,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage wal_buffers_fullbigint - 因为缓冲区已满,WAL数据被写入磁盘的次数 + 因为 WAL 缓冲区已满,WAL 数据被写入磁盘的次数 @@ -3937,7 +3906,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage wal_syncbigint - 通过issue_xlog_fsync 请求将WAL文件同步到磁盘的次数(如果onfdatasync, fsyncfsync_writethrough,否则为零)。 + 通过issue_xlog_fsync 请求将WAL文件同步到磁盘的次数(如果onfdatasyncfsyncfsync_writethrough,否则为零)。 有关内部WAL函数issue_xlog_fsync的更多信息,参见 @@ -3947,7 +3916,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage wal_write_timedouble precision - 通过XLogWrite请求将WAL缓冲区写入磁盘所消耗的总时间,以毫秒计(如果是启用的,否则为零)。 + 通过XLogWrite请求将WAL缓冲区写入磁盘所消耗的总时间,以毫秒计(如果是启用的,否则为零)。 这包括当wal_sync_methodopen_datasyncopen_sync时的同步时间。 @@ -3957,7 +3926,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage wal_sync_timedouble precision - 通过issue_xlog_fsync请求将WAL文件同步到磁盘所消耗的总时间,以毫秒计(如果 track_wal_io_timing 被启用,fsync is on, 和 wal_sync_methodfdatasync, fsyncfsync_writethrough, 否则为零). + 通过 issue_xlog_fsync 请求将 WAL 文件同步到磁盘所花费的总时间,以毫秒计(如果启用了 track_wal_io_timingfsyncon,且 wal_sync_methodfdatasyncfsyncfsync_writethrough,否则为零)。 @@ -3965,9 +3934,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage stats_reset timestamp with time zone - - 这些统计数据最后一次重置的时间 - + 这些统计信息上次被重置的时间 @@ -4013,7 +3980,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + datname name @@ -4022,17 +3989,17 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + numbackends integer 当前连接到此数据库的后端数,对于共享对象则为NULL。 - 这是该视图中唯一返回反映当前状态的值的列;所有其他列返回自上次重置以来累积的值。 + 这是该视图中唯一返回反映当前状态的值的列;所有其他列返回自上次重置以来累积的值。 - + xact_commit bigint @@ -4041,7 +4008,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + xact_rollback bigint @@ -4050,7 +4017,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + blks_read bigint @@ -4059,7 +4026,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + blks_hit bigint @@ -4068,7 +4035,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + tup_returned bigint @@ -4077,7 +4044,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + tup_fetched bigint @@ -4086,7 +4053,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + tup_inserted bigint @@ -4095,7 +4062,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + tup_updated bigint @@ -4104,7 +4071,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + tup_deleted bigint @@ -4113,7 +4080,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + conflicts bigint @@ -4122,7 +4089,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + temp_files bigint @@ -4131,7 +4098,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + temp_bytes bigint @@ -4140,7 +4107,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + deadlocks bigint @@ -4149,7 +4116,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + checksum_failures bigint @@ -4158,7 +4125,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + checksum_last_failure timestamp with time zone @@ -4167,7 +4134,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + blk_read_time double precision @@ -4176,7 +4143,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + blk_write_time double precision @@ -4185,25 +4152,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - - - parallel_workers_to_launch bigint - - - 计划由该数据库上的查询启动的并行工作进程数 - - - - - - parallel_workers_launched bigint - - - 由该数据库上的查询启动的并行工作进程数 - - - - + session_time double precision @@ -4212,7 +4161,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + active_time double precision @@ -4221,7 +4170,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + idle_in_transaction_time double precision @@ -4230,7 +4179,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + sessions bigint @@ -4239,7 +4188,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + sessions_abandoned bigint @@ -4248,7 +4197,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + sessions_fatal bigint @@ -4257,7 +4206,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + sessions_killed bigint @@ -4266,7 +4215,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + stats_reset timestamp with time zone @@ -4274,6 +4223,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage 这些统计数据最后一次重置的时间 +
@@ -4360,7 +4310,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage confl_bufferpin bigint - 此数据库中由于固定缓冲区而被取消的查询数 + 此数据库中由于缓冲区被钉住而被取消的查询数
@@ -4467,7 +4417,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage seq_tup_read bigint - 连续扫描获取的实时行数 + 顺序扫描获取的存活行数
@@ -4494,7 +4444,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage idx_tup_fetch bigint - 索引扫描获取的实时行数 + 索引扫描获取的存活行数
@@ -4511,9 +4461,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage n_tup_upd bigint - - 更新的行数(包括HOT更新的行) - + 更新的总行数。(包括计入n_tup_hot_updn_tup_newpage_upd的行更新,以及其余非HOT更新。)
@@ -4529,9 +4477,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage n_tup_hot_upd bigint - - HOT更新的行数(即,不需要单独的索引更新) - + 进行HOT 更新的行数。这些更新不需要在索引中存储后继版本。 @@ -4539,7 +4485,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage n_tup_newpage_upd bigint - 更新的行数,其中后继版本转到新的堆页,留下一个原始版本,其t_ctid字段指向不同的堆页。这些始终是非 HOT 更新。 + 更新的行数,其中后继版本转到的堆页,留下一个原始版本,其t_ctid字段指向不同的堆页。这些始终是非 HOT 更新。 @@ -4584,7 +4530,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage last_vacuum timestamp with time zone - 最后一次手动清理这个表(不包括VACUUM FULL) + 最后一次手动清理这个表的时间(不包括VACUUM FULL
@@ -4602,7 +4548,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage last_analyze timestamp with time zone - 上一次手动分析这个表 + 上一次手动分析这个表的时间
@@ -4611,7 +4557,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage last_autoanalyze timestamp with time zone - 自动清理守护进程最后一次分析这个表 + 自动清理守护进程最后一次分析这个表的时间
@@ -4620,7 +4566,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage vacuum_count bigint - 这个表被手动清理的次数(VACUUM FULL不计数) + 这个表被手动清理的次数(VACUUM FULL不计数)
@@ -4651,41 +4597,13 @@ description | Waiting for a newly initialized WAL file to reach durable storage
- - - total_vacuum_time double precision - - - 手动 VACUUM 此表所花费的总时间,以毫秒计(不包括 VACUUM FULL)。(这包括由于基于成本的延迟而睡眠的时间。) - - - - - total_autovacuum_time double precision - - - 自动清理守护进程对该表执行 VACUUM 所花费的总时间,以毫秒计。(这包括由于基于成本的延迟而睡眠的时间。) - - - - - total_analyze_time double precision - - - 手动分析该表所花费的总时间,以毫秒计。(这包括由于基于成本的延迟而睡眠的时间。) - - - - - total_autoanalyze_time double precision - - - 自动清理守护进程分析该表所花费的总时间,以毫秒计。(这包括由于基于成本的延迟而睡眠的时间。) - - + + + + @@ -4798,7 +4716,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage idx_tup_fetch bigint - 使用此索引进行简单索引扫描获取的活动表行数 + 使用此索引进行简单索引扫描获取的存活表行数
@@ -4806,13 +4724,13 @@ description | Waiting for a newly initialized WAL file to reach durable storage - 索引可以被简单索引扫描、位图索引扫描以及优化器使用。在一次位图扫描中,多个索引的输出可以被通过 AND 或 OR 规则组合,因此当使用一次位图扫描时难以将取得的个体堆行与特定的索引关联起来。因此,一次位图扫描会增加它使用的索引的pg_stat_all_indexes.idx_tup_read计数,并且为每个表增加pg_stat_all_tables.idx_tup_fetch计数,但是它不影响pg_stat_all_indexes.idx_tup_fetch。如果所提供的常量值不在优化器统计信息记录的范围之内,优化器也会访问索引来检查,因为优化器统计信息可能已经“不新鲜”了。 + 索引可以被简单索引扫描、位图索引扫描以及优化器使用。在一次位图扫描中,多个索引的输出可以被通过 AND 或 OR 规则组合,因此当使用一次位图扫描时难以将取得的个体堆行与特定的索引关联起来。因此,一次位图扫描会增加它使用的索引的pg_stat_all_indexes.idx_tup_read计数,并且为该表增加pg_stat_all_tables.idx_tup_fetch计数,但是它不影响pg_stat_all_indexes.idx_tup_fetch。如果所提供的常量值不在优化器统计信息记录的范围之内,优化器也会访问索引来检查,因为优化器统计信息可能已经过时。 - 即使不用位图扫描,idx_tup_readidx_tup_fetch计数也可能不同,因为idx_tup_read统计从该索引取得的索引项而idx_tup_fetch统计从表取得的活着的行。如果使用该索引取得了任何死亡行或还未提交的行,或者如果通过一次只用索引扫描的方式避免了任何堆获取,后者将较小。 + 即使不用位图扫描,idx_tup_readidx_tup_fetch计数也可能不同,因为idx_tup_read统计从该索引取得的索引项而idx_tup_fetch统计从表取得的存活行。如果使用该索引取得了任何死亡行或还未提交的行,或者如果通过一次仅索引扫描的方式避免了任何堆获取,后者将较小。 @@ -4915,7 +4833,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage toast_blks_read bigint - 从这个表的TOAST表中读取的磁盘块的数量(如果有的话) + 从这个表的TOAST表中读取的磁盘块的数量(如果有的话)
@@ -4924,7 +4842,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage toast_blks_hit bigint - 这个表的TOAST表中的缓冲区命中数(如果有的话) + 这个表的TOAST表中的缓冲区命中数(如果有的话)
@@ -4933,7 +4851,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage tidx_blks_read bigint - 从这个表的TOAST表索引中读取的磁盘块的数量(如果有的话) + 从这个表的TOAST表索引中读取的磁盘块的数量(如果有的话)
@@ -4942,7 +4860,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage tidx_blks_hit bigint - 这个表的TOAST表索引中的缓冲区命中数(如果有的话) + 这个表的TOAST表索引中的缓冲区命中数(如果有的话)
@@ -5229,7 +5147,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - PostgreSQL通过SLRU(simple least-recently-used,简单的最近-最少-使用)缓存访问某些磁盘上的信息。 + PostgreSQL通过SLRU(simple least-recently-used,简单最近最少使用)缓存访问某些磁盘上的信息。 pg_stat_slru视图将为每个被跟踪的SLRU缓存包含一行,显示关于访问缓存页面的统计信息。 @@ -5274,7 +5192,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage blks_hit bigint - 已经在SLRU中的磁盘块被发现的次数,因此不需要读取(这只包括SLRU中的命中,而不是操作系统的文件系统缓存) + 已经在SLRU中的磁盘块被发现的次数,因此不需要读取(这只包括SLRU中的命中,而不是操作系统的文件系统缓存)
@@ -5310,7 +5228,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage flushes bigint - 此SLRU的脏数据刷新数 + 此SLRU的脏数据刷盘次数
@@ -5319,7 +5237,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage truncates bigint - 这个SLRU的截断数 + 这个SLRU的截断次数
@@ -5327,9 +5245,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage stats_reset timestamp with time zone - - 这些统计数据最后一次重置的时间 - + 这些统计信息上次被重置的时间
@@ -5349,7 +5265,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - 与累积统计系统相关的其他功能在中列出。 + 与累积统计系统相关的其他函数在中列出。 @@ -5381,21 +5297,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - - - - pg_stat_get_backend_io - - pg_stat_get_backend_io ( integer ) - setof record - - - 返回指定进程 ID 的后端的 I/O 统计信息。输出字段与 pg_stat_io 视图中的字段完全相同。 - - - 该函数不会返回检查点进程、后台写入器、启动进程和 自动清理启动器的 I/O 统计信息,因为这些统计信息已经在 pg_stat_io 视图中可见,而且每种都只有一个。 - - + @@ -5411,21 +5313,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - - - - pg_stat_get_backend_wal - - pg_stat_get_backend_wal ( integer ) - record - - - 返回指定进程 ID 的后端的 WAL 统计信息。输出字段与 pg_stat_wal 视图中的字段完全相同。 - - - 该函数不会返回检查点进程、后台写入器、启动进程和 自动清理启动器的 WAL 统计信息。 - - + @@ -5436,7 +5324,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage timestamp with time zone - 返回当前统计快照的时间戳,如果没有统计快照则返回NULL。如果在事务中第一次访问累积统计信息时将快照设置为stats_fetch_consistencysnapshot。 + 返回当前统计快照的时间戳;如果尚未获取统计快照,则返回 NULL。如果 stats_fetch_consistency 设置为 snapshot,则会在事务中第一次访问累积统计信息时获取快照。 @@ -5492,9 +5380,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage 将当前数据库的所有统计计数器重置为零。 - - 默认情况下该函数仅限于超级用户,但是其他用户可以被授予EXECUTE来运行此函数。 - + 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 @@ -5506,32 +5392,12 @@ description | Waiting for a newly initialized WAL file to reach durable storage void - 根据参数将一些集簇范围的统计计数器重置为零。参数可以是bgwriter, - 用于重置在pg_stat_bgwriter视图中显示的所有计数器, - archiver,用于重置在pg_stat_archiver视图中显示的所有计数器, - wal,用于重置在pg_stat_wal视图中显示的所有计数器, - 或recovery_prefetch,用于重置在pg_stat_recovery_prefetch视图中显示的所有计数器。 + 根据参数将一些集簇范围的统计计数器重置为零。参数可以为 bgwriter,用于重置 pg_stat_bgwriter 视图中显示的所有计数器;archiver,用于重置 pg_stat_archiver 视图中显示的所有计数器;io,用于重置 pg_stat_io 视图中显示的所有计数器;wal,用于重置 pg_stat_wal 视图中显示的所有计数器;或 recovery_prefetch,用于重置 pg_stat_recovery_prefetch 视图中显示的所有计数器。 - - 默认情况下,此函数仅限超级用户使用,但可以授予其他用户EXECUTE权限来运行该函数。 - + 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 - - - - pg_stat_reset_backend_stats - - pg_stat_reset_backend_stats ( integer ) - void - - - 将指定进程 ID 的单个后端进程的统计信息重置为零。 - - - 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 - - + @@ -5542,11 +5408,9 @@ description | Waiting for a newly initialized WAL file to reach durable storage void - 重置当前数据库中的单个表或索引的统计信息,或者在集簇中跨所有数据库共享的统计信息为零。 + 将单个表或索引的统计信息重置为零;该对象可以位于当前数据库中,也可以由集簇中的所有数据库共享。 - - 默认情况下,此函数仅限超级用户使用,但可以授予其他用户EXECUTE权限来运行该函数。 - + 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 @@ -5560,9 +5424,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage 将当前数据库中单个函数的统计信息重置为零。 - - 默认情况下该函数仅限于超级用户,但是其他用户可以被授予EXECUTE来运行此函数。 - + 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 @@ -5574,15 +5436,9 @@ description | Waiting for a newly initialized WAL file to reach durable storage void - 将单个SLRU缓存或集簇中所有SLRU的统计信息重置为零。 - 如果该参数为NULL,则所有SLRU缓存的pg_stat_slru视图中显示的计数器将被重置。 - 参数可以是CommitTsMultiXactMemberMultiXactOffsetNotify、 - SerialSubtrans、 或Xact中的一个,以便只重置该条目的计数器。 - 如果参数是other(或实际上,任何无法识别的名称),那么所有其他SLRU缓存的计数器,如扩展定义的缓存,将被重置。 + 将单个 SLRU 缓存或集簇中所有 SLRU 的统计信息重置为零。如果参数为空值,则重置 pg_stat_slru 视图中所有 SLRU 缓存的全部计数器。参数可以为 CommitTs、&zwsp;MultiXactMember、&zwsp;MultiXactOffset、&zwsp;Notify、&zwsp;Serial、&zwsp;SubtransXact 中的一个,以便只重置对应条目的计数器。如果参数为 other(实际上,任何无法识别的名称都可以),则重置其他所有 SLRU 缓存的计数器,例如扩展定义的缓存。 - - 默认情况下该函数仅限于超级用户,但是其他用户可以被授予EXECUTE来运行此函数。 - + 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 @@ -5597,9 +5453,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage 重置由参数定义的复制槽的统计信息。 如果参数为NULL,则重置所有复制槽的统计信息。 - - 该函数默认仅限于超级用户,但可以授予其他用户EXECUTE权限来运行该函数。 - + 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 @@ -5614,9 +5468,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage 重置pg_stat_subscription_stats视图中显示的单个订阅的统计信息为零。 如果参数是NULL,则重置所有订阅的统计信息。 - - 默认情况下,此函数仅限超级用户使用,但其他用户可以被授予EXECUTE权限来运行该函数。 - + 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 @@ -5632,17 +5484,18 @@ description | Waiting for a newly initialized WAL file to reach durable storage - pg_stat_get_activitypg_stat_activity视图的底层函数, - 它返回一个行集合,其中包含有关每个后端进程所有可用的信息。有时只获得该信息的一个子集可能会更方便。 - 在那些情况中,可以使用一组更老的针对每个后端的统计访问函数,这些显示在中。 - 这些访问函数使用一个后端 ID 号,范围从 1 到当前活动后端数目。 - 函数pg_stat_get_backend_idset提供了一种方便的方法为每个活动后端产生一行来调用这些函数。 - 例如,要显示PID以及所有后端当前的查询: + pg_stat_get_activitypg_stat_activity 视图的底层函数, + 返回一组记录,其中包含有关每个后端进程的全部可用信息。有时只获取其中一部分信息会更方便。 + 在这种情况下,可以使用另一组针对每个后端的统计信息访问函数,见 。 + 这些访问函数使用会话的后端 ID 号,它是一个值较小的正整数,与任何并发会话的后端 ID 都不同, + 但会话退出后,其 ID 可立即被重新使用。后端 ID 的用途之一是标识会话的临时模式(如果有)。 + 函数 pg_stat_get_backend_idset 提供了一种便捷的方法,可列出所有活动后端的 ID 号来调用这些函数。 + 例如,要显示所有后端的 PID 和当前查询: -SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - pg_stat_get_backend_activity(s.backendid) AS query - FROM (SELECT pg_stat_get_backend_idset() AS backendid) AS s; +SELECT pg_stat_get_backend_pid(backendid) AS pid, + pg_stat_get_backend_activity(backendid) AS query +FROM pg_stat_get_backend_idset() AS backendid; @@ -5664,19 +5517,6 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - - - - pg_stat_get_backend_idset - - pg_stat_get_backend_idset () - setof integer - - - 返回当前活动后端ID号的集合(从1到活动后端数)。 - - - @@ -5696,7 +5536,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, pg_stat_get_backend_activity_start pg_stat_get_backend_activity_start ( integer ) - 有时区的时间戳 + timestamp with time zone 返回后端最近一次查询开始的时间。 @@ -5742,6 +5582,19 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, + + + + pg_stat_get_backend_idset + + pg_stat_get_backend_idset () + setof integer + + + 返回当前活动后端 ID 号的集合。 + + + @@ -5761,11 +5614,9 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, pg_stat_get_backend_start pg_stat_get_backend_start ( integer ) - 有时区的时间戳 + timestamp with time zone - - 返回该进程开始的时间。 - + 返回该进程开始的时间。 @@ -5797,28 +5648,28 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - pg_stat_get_backend_wait_event_type + pg_stat_get_backend_wait_event - pg_stat_get_backend_wait_event_type ( integer ) + pg_stat_get_backend_wait_event ( integer ) text - 如果后端当前正在等待,则返回等待事件类型名称,否则返回NULL。 - 请参阅。 + 如果后端当前正在等待,则返回等待事件名称,否则为空值。 + 请参阅 - pg_stat_get_backend_wait_event + pg_stat_get_backend_wait_event_type - pg_stat_get_backend_wait_event ( integer ) + pg_stat_get_backend_wait_event_type ( integer ) text - 如果后端当前正在等待,则返回等待事件名称,否则为NULL。 - 请参阅。 + 如果后端当前正在等待,则返回等待事件类型名称,否则返回空值。 + 请参阅 @@ -5828,7 +5679,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, pg_stat_get_backend_xact_start pg_stat_get_backend_xact_start ( integer ) - 有时区的时间戳 + timestamp with time zone 返回后端当前事务开始的时间。 @@ -5846,23 +5697,23 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, 查看锁 - lock - monitoring + + 监控 - 监控数据库活动的另外一个有用的工具是pg_locks系统表。这样就允许数据库管理员查看在锁管理器里面未解决的锁的信息。例如,这个功能可以被用于: + 监控数据库活动的另外一个有用的工具是pg_locks系统表。这样就允许数据库管理员查看锁管理器中当前存在的锁的信息。例如,这个功能可以被用于: - 查看当前所有未解决的锁、在一个特定数据库中的关系上所有的锁、在一个特定关系上所有的锁,或者由一个特定PostgreSQL会话持有的所有的锁。 + 查看当前存在的所有锁、在一个特定数据库中的关系上所有的锁、在一个特定关系上所有的锁,或者由一个特定PostgreSQL会话持有的所有的锁。 - 判断当前数据库中带有最多未授予锁的关系(它很可能是数据库客户端的竞争源)。 + 判断当前数据库中带有最多未授予锁的关系(它可能是数据库客户端之间的竞争来源)。 @@ -6024,14 +5875,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - - - delay_time double precision - - - 因基于成本的延迟而睡眠的总时间(参见),以毫秒计(如果启用了 track_cost_delay_timing,否则为零)。 - - +
@@ -6061,14 +5905,14 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, acquiring sample rows - 该命令当前正在扫描relid给出的表以获得样例行。 + 该命令当前正在扫描relid给出的表以获得样本行。 acquiring inherited sample rows - 该命令当前正在扫描子表以获得样例行。列child_tables_total,child_tables_done, + 该命令当前正在扫描子表以获得样本行。列child_tables_totalchild_tables_done、 和current_child_table_relid包含此阶段的进度信息。 @@ -6076,14 +5920,14 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, computing statistics - 该命令从表扫描期间获得的样例行计算统计信息。 + 该命令从表扫描期间获得的样本行计算统计信息。 computing extended statistics - 该命令从表扫描期间获得的样例行计算扩展统计信息。 + 该命令从表扫描期间获得的样本行计算扩展统计信息。 @@ -6099,29 +5943,25 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - - 注意当在分区表上运行ANALYZE时,它的所有分区也会被递归分析。 - 在这种情况下,首先报告父表的ANALYZE进度,收集它的继承统计信息,然后是每个分区的(继承统计信息)。 - + 请注意,当在分区表上运行ANALYZE时,其所有分区也会被递归分析。在这种情况下,会先报告父表的ANALYZE进度,并收集其继承统计信息,随后再报告每个分区的进度。 - + - CREATE INDEX 进度报告 + CLUSTER 进度报告 - pg_stat_progress_create_index + pg_stat_progress_cluster - 每当运行CREATE INDEXREINDEX时,pg_stat_progress_create_index视图将包含当前正在创建索引的每个后端的一行。 - 下面的表描述了将要报告的信息,并提供了关于如何解释它的信息。 + 每当CLUSTERVACUUM FULL运行时,pg_stat_progress_cluster视图将为每个当前正在运行这两种命令之一的后端包含一行。下面的表格描述了将被报告的信息,并提供了关于如何解释这些信息的信息。 - +
- <structname>pg_stat_progress_create_index</structname> 视图 + <structname>pg_stat_progress_cluster</structname> 视图 @@ -6169,229 +6009,306 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, relidoid - 正在创建索引的表的OID。 + 正在聚簇的表的OID。 - index_relid oid + command text - 正在创建或重建索引的OID。在非并发 CREATE INDEX的时候,此为 0。 + 正在运行的命令。CLUSTERVACUUM FULL - command text + phase text - 在运行的命令: CREATE INDEX,CREATE INDEX CONCURRENTLY, - REINDEX, 或 REINDEX CONCURRENTLY. + 当前处理阶段。参见 - phase text + cluster_index_relid oid - 索引创建的当前处理阶段。 参见 。 + 如果正在使用索引对表进行扫描,这就是正在使用的索引的OID;否则为0。 - lockers_total bigint + heap_tuples_scanned bigint - 在适用的情况下,需要等待的储物柜总数 + 扫描的堆元组数。 + 该计数器仅在阶段为seq scanning heapindex scanning heap + 或 writing new heap 时才会递增。 - lockers_done bigint + heap_tuples_written bigint - 已经等待的储物柜数量。 + 写入的堆元组的数量。这个计数器只有在阶段为seq scanning heapindex scanning heap + 或 writing new heap时才会递增。 - current_locker_pid bigint + heap_blks_total bigint - 目前正在等待的储物柜的进程ID。 + 表中的堆块总数。 这个数字以seq scanning heap开始时的数量为准。 - blocks_total bigint + heap_blks_scanned bigint - 本阶段要处理的区块总数。 + 扫描的堆块数量。该计数器仅在阶段为seq scanning heap时才会递增。 - blocks_done bigint + index_rebuild_count bigint - 当前阶段已经处理的区块数量。 + 已重建的索引数。该计数器仅在rebuilding index阶段时才会递增。 + + +
+ + + + CLUSTER 和 VACUUM FULL 阶段 + + + + + + + 阶段 + 描述 + + + + + + + initializing + + 命令正在准备开始扫描堆。这个阶段预计会非常短暂。 + + + + + seq scanning heap + + 该命令目前采用顺序扫描的方式对表进行扫描。 + + + + + index scanning heap + + CLUSTER目前正在使用索引扫描表。 + + + + + sorting tuples + + CLUSTER目前正在对元组进行排序。 + + + + + writing new heap + + CLUSTER目前正在写入新的堆。 + + + + + swapping relation files + + 目前,该命令正在将新建立的文件调换到位。 + + + + + rebuilding index + + 该命令目前正在重建一个索引。 + + + + + performing final cleanup + + 该命令正在执行最后的清理工作。 当此阶段完成后,CLUSTERVACUUM FULL将结束。 + + + + +
+
+ + + + COPY 进度报告 + + + pg_stat_progress_copy + + + + 当COPY正在运行时,pg_stat_progress_copy视图会为每个当前正在执行COPY命令的后端包含一行。下表描述了会报告哪些信息,以及应如何解释这些信息。 + + + + + <structname>pg_stat_progress_copy</structname> 视图 + + - tuples_total bigint + 列类型 - 当前阶段要处理的元组总数。 + 描述 + + + - tuples_done bigint + pid integer - 在当前阶段已经处理的元组数量。 + 后端的进程ID。 - partitions_total bigint + datid oid - 在分区表上创建索引时,该列被设置为要在其上创建索引的分区总数。 - 在REINDEX期间,此字段为0。 + 后端连接到的数据库的OID。 - partitions_done bigint + datname name - 当在分区表上创建索引时,该列被设置为在其上建立索引的分区数。 - 在REINDEX期间,此字段为0。 + 后端连接到的数据库的名称。 - - -
- - - - CREATE INDEX 的阶段 - - - - - 阶段 - 描述 - - - - - - 初始化 - - CREATE INDEXREINDEX正在准备创建索引。 这个阶段预计会非常短暂。 - - - - - 构建前等待读写器 - - CREATE INDEX CONCURRENTLYREINDEX CONCURRENTLY正在等待有可能看到表的写锁的事务完成。 当不在并发模式时,这个阶段会被跳过。lockers_totallockers_donecurrent_locker_pid 列包含了这个阶段的进度信息。 - + + relid oid + + + 执行COPY命令的表的OID。 + 如果从SELECT查询中复制,它被设置为0。 + - 新建索引 - - 索引是由访问方法专用代码建立的。 在这一阶段,支持进度报告的访问方法填写自己的进度数据,子阶段在这一栏中表示。 通常情况下,blocks_totalblocks_done将包含进度数据,也可能包含tuples_totaltuples_done。 - + + command text + + + 正在运行的命令: COPY FROMCOPY TO。 + - 在验证前等待读写器 - - CREATE INDEX CONCURRENTLYREINDEX CONCURRENTLY正在等待有可能写入表的事务完成写锁的事务。当不在并发模式时,这个阶段会被跳过。lockers_totallockers_donecurrent_locker_pid 列包含了这个阶段的进度信息。 - + + type text + + 读取或写入数据的 I/O 类型:FILEPROGRAMPIPE(用于COPY FROM STDINCOPY TO STDOUT),或CALLBACK(例如在逻辑复制的初始表同步期间使用)。 - 索引验证:扫描索引 - - CREATE INDEX CONCURRENTLY正在扫描索引,搜索需要验证的元组。如果不是并发模式,则会跳过此阶段。列 blocks_total(设为索引总大小)和 blocks_done 包含该阶段的进度信息。 - + + bytes_processed bigint + + + 已经被COPY命令处理的字节数。 + - 索引验证:排序元组 - - CREATE INDEX CONCURRENTLY正在对索引扫描阶段的输出进行排序。 - + + bytes_total bigint + + + COPY FROM命令的源文件大小,以字节计。 + 如果不可用则设置为0。 + - 索引验证:扫描表 - - CREATE INDEX CONCURRENTLY正在扫描表,以验证前两个阶段收集的索引元组。如果不是并发模式,则会跳过此阶段。blocks_total 列(设为表总大小)和 blocks_done 列包含该阶段的进度信息。 - + + tuples_processed bigint + + + 已经被COPY命令处理的元组数。 + - 等待旧照 - - CREATE INDEX CONCURRENTLYREINDEX CONCURRENTLY正在等待可能看到表的事务释放快照。 当不处于并发模式时,这个阶段会被跳过。 lockers_totallockers_donecurrent_locker_pid 列包含了这个阶段的进度信息。 - + + tuples_excluded bigint + + + 没有处理的元组数,因为它们被COPY命令的WHERE子句所排除。 + - - 标记 dead之前等待readers - - REINDEX CONCURRENTLY等待表上有读锁的事务完成后,再将旧索引标记为死索引。当不在并发模式时,这个阶段被跳过。lockers_totallockers_donecurrent_locker_pid 列包含了这个阶段的进度信息。 - - - - 在 dropping之前等待readers - - REINDEX CONCURRENTLY等待表上有读锁的事务完成后,再丢弃旧索引。当不在并发模式时,这个阶段被跳过。列 lockers_totallockers_donecurrent_locker_pid包含了这个阶段的进度信息。 - -
-
- + - VACUUM 进度报告 + CREATE INDEX 进度报告 - pg_stat_progress_vacuum + pg_stat_progress_create_index - 只要VACUUM正在运行,pg_stat_progress_vacuum视图就会为每个当前正在清理的后端(包括自动清理工作进程)包含一行。下表描述了将报告的信息,并说明如何解释这些信息。VACUUM FULL命令的进度通过pg_stat_progress_cluster报告,因为VACUUM FULLCLUSTER都会重写表,而常规的VACUUM只会原地修改表。参见。 + 每当运行CREATE INDEXREINDEX时,pg_stat_progress_create_index视图将包含当前正在创建索引的每个后端的一行。 + 下面的表描述了将要报告的信息,并提供了关于如何解释它的信息。 - +
- <structname>pg_stat_progress_vacuum</structname> 视图 + <structname>pg_stat_progress_create_index</structname> 视图 @@ -6411,9 +6328,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, pid integer - - 后端的进程ID。 - + 正在创建索引的后端的进程 ID。 @@ -6439,204 +6354,217 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, relid oid - 被vacuum的表的OID。 + 正在创建索引的表的OID。 - phase text + index_relid oid - vacuum的当前处理阶段。参见 。 + 正在创建或重建索引的OID。在非并发 CREATE INDEX的时候,此为 0。 - heap_blks_total bigint + command text - 该表中堆块的总数。这个数字在扫描开始时报告,之后增加的块将不会(并且不需要)被这个VACUUM访问。 + 具体命令类型: CREATE INDEXCREATE INDEX CONCURRENTLY、 + REINDEXREINDEX CONCURRENTLY - heap_blks_scanned bigint + phase text - 被扫描的堆块数量。由于visibility map被用来优化扫描,一些块将被跳过而不做检查, - 被跳过的块会被包括在这个总数中,因此当清理完成时这个数字最终将会等于heap_blks_total。 - 仅当处于扫描堆阶段时这个计数器才会前进。 + 索引创建的当前处理阶段。 参见 - heap_blks_vacuumed bigint + lockers_total bigint - - 被清理的堆块数量。除非表没有索引,这个计数器仅在处于清理堆阶段时才会前进。 - 不包含死亡元组的块会被跳过,因此这个计数器可能有时会向前跳跃一个比较大的增量。 - + 在适用的情况下,需要等待的持锁进程总数。 - index_vacuum_count bigint + lockers_done bigint - - 已完成的索引清理周期数。 - + 已完成等待的持锁进程数量。 - max_dead_tuple_bytes bigint + current_locker_pid bigint - - 在需要执行索引清理周期之前可存储的死亡元组数据量,取决于。 - + 当前正在等待的持锁进程的进程 ID。 - dead_tuple_bytes bigint + blocks_total bigint - 自上一个索引清理周期以来收集到的死亡元组数据量。 + 本阶段要处理的块总数。 - num_dead_item_ids bigint + blocks_done bigint - 自上一个索引清理周期以来收集到的死项标识符数量。 + 当前阶段已经处理的块数量。 - indexes_total bigint + tuples_total bigint - 将要执行 vacuum 或清理的索引总数。该数字会在 vacuuming indexescleaning up indexes 阶段开始时报告。 + 当前阶段要处理的元组总数。 - indexes_processed bigint + tuples_done bigint - 已处理的索引数量。该计数器只会在 vacuuming indexescleaning up indexes 阶段推进。 + 在当前阶段已经处理的元组数量。 - delay_time double precision + partitions_total bigint - - 因基于成本的延迟而睡眠的总时间(参见),以毫秒计(如果启用了 track_cost_delay_timing,否则为零)。这包括任何相关并行工作进程的睡眠时间;不过,并行工作进程最多每秒才会上报一次自己的睡眠时间,因此该值可能略有滞后。 - + 要创建或附加索引的分区总数,包括直接分区和间接分区。在REINDEX期间,或索引未分区时,此值为0 + + + + + partitions_done bigint + + 已创建或附加索引的分区数量,包括直接分区和间接分区。在REINDEX期间,或索引未分区时,此值为0
- +
- VACUUM的阶段 + CREATE INDEX 阶段 - + 阶段 描述 + - + + initializing + + CREATE INDEXREINDEX正在准备创建索引。 这个阶段预计会非常短暂。 + + - - 初始化 - - VACUUM正在准备开始扫描堆。这个阶段应该很简短。 - - + + waiting for writers before build + + CREATE INDEX CONCURRENTLYREINDEX CONCURRENTLY正在等待持有写锁且可能看到该表的事务结束。 当不在并发模式时,这个阶段会被跳过。lockers_totallockers_donecurrent_locker_pid 列包含了这个阶段的进度信息。 + + - - 扫描堆 - - VACUUM正在扫描堆。如果需要,它将会对每个页面进行修建以及碎片整理,并且可能会执行冻结动作。heap_blks_scanned列可以用来监控扫描的进度。 - - + + building index + + 索引是由访问方法专用代码建立的。 在这一阶段,支持进度报告的访问方法填写自己的进度数据,子阶段在这一栏中表示。 通常情况下,blocks_totalblocks_done将包含进度数据,tuples_totaltuples_done也可能包含进度数据。 + + - - 清理索引 - - VACUUM当前正在清理索引。 - 如果一个表拥有索引,那么每次清理时这个阶段会在堆扫描完成后至少发生一次。 - 如果不足以存放找到的死亡元组(或者, 在autovacuum情况下,如果设置了) ,则每次清理时会多次清理索引。 - - + + waiting for writers before validation + + CREATE INDEX CONCURRENTLYREINDEX CONCURRENTLY正在等待持有写锁且可能写入该表的事务结束。当不在并发模式时,这个阶段会被跳过。lockers_totallockers_donecurrent_locker_pid 列包含了这个阶段的进度信息。 + + - - 清理堆 - - VACUUM当前正在清理堆。清理堆与扫描堆不是同一个概念,清理堆发生在每一次清理索引的实例之后。如果heap_blks_scanned小于heap_blks_total,系统将在这个阶段完成之后回去扫描堆;否则,系统将在这个阶段完成后开始清理索引。 - - + + index validation: scanning index + + CREATE INDEX CONCURRENTLY正在扫描索引,搜索需要验证的元组。如果不是并发模式,则会跳过此阶段。列 blocks_total(设为索引总大小)和 blocks_done 包含该阶段的进度信息。 + + + + + index validation: sorting tuples + + CREATE INDEX CONCURRENTLY正在对索引扫描阶段的输出进行排序。 + + + + + index validation: scanning table + + CREATE INDEX CONCURRENTLY正在扫描表,以验证前两个阶段收集的索引元组。如果不是并发模式,则会跳过此阶段。blocks_total 列(设为表总大小)和 blocks_done 列包含该阶段的进度信息。 + + - - 清除索引 - - VACUUM当前正在清除索引。这个阶段发生在堆被完全扫描并且对堆和索引的所有清理都已经完成以后。 - - + + waiting for old snapshots + + CREATE INDEX CONCURRENTLYREINDEX CONCURRENTLY正在等待可能看到表的事务释放快照。 当不处于并发模式时,这个阶段会被跳过。 lockers_totallockers_donecurrent_locker_pid 列包含了这个阶段的进度信息。 + + - - 截断堆 - - VACUUM正在截断堆,以便把关系尾部的空页面返还给操作系统。这个阶段发生在清除完索引之后。 - - + + waiting for readers before marking dead + + REINDEX CONCURRENTLY等待表上有读锁的事务完成后,再将旧索引标记为死索引。当不在并发模式时,这个阶段被跳过。lockers_totallockers_donecurrent_locker_pid 列包含了这个阶段的进度信息。 + + - - 执行最终清理 - - VACUUM正在执行最终清理。在此阶段,VACUUM将清理空闲空间映射, - 更新pg_class中的统计信息,并向累积统计系统报告统计信息。当此阶段完成时, - VACUUM将结束。 - - - + + waiting for readers before dropping + + REINDEX CONCURRENTLY等待表上有读锁的事务完成后,再丢弃旧索引。当不在并发模式时,这个阶段被跳过。列 lockers_totallockers_donecurrent_locker_pid包含了这个阶段的进度信息。 + + +
- + - CLUSTER 进度报告 + VACUUM 进度报告 - pg_stat_progress_cluster + pg_stat_progress_vacuum - 每当CLUSTERVACUUM FULL运行时,pg_stat_progress_cluster视图将包含当前正在运行的每一个后台的记录。下面的表格描述了将被报告的信息,并提供了关于如何解释这些信息的信息。 + 只要VACUUM正在运行,pg_stat_progress_vacuum视图就会为每个当前正在清理的后端(包括自动清理工作进程)包含一行。下表描述了将报告的信息,并说明如何解释这些信息。VACUUM FULL命令的进度通过pg_stat_progress_cluster报告,因为VACUUM FULLCLUSTER都会重写表,而常规的VACUUM只会原地修改表。参见 - +
- <structname>pg_stat_progress_cluster</structname> 视图 + <structname>pg_stat_progress_vacuum</structname> 视图 @@ -6684,16 +6612,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, relidoid - 被集群的表的OID。 - - - - - - command text - - - 正在运行的命令。CLUSTERVACUUM FULL。 + 正在清理的表的OID。 @@ -6702,73 +6621,85 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, phasetext - 当前处理阶段。参见。 + 清理的当前处理阶段。参见 - cluster_index_relid oid + heap_blks_total bigint - 如果正在使用索引对表进行扫描,这就是正在使用的索引的OID;否则为0。 + 该表中堆块的总数。这个数字以扫描开始时的数量为准,之后增加的块将不会(并且不需要)被这个VACUUM访问。 - heap_tuples_scanned bigint + heap_blks_scanned bigint - 扫描的堆元组数。 - 该计数器仅在阶段为seq scanning heapindex scanning heap - 或 writing new heap 时才会递增。 + 被扫描的堆块数量。由于可见性映射被用来优化扫描,一些块将被跳过而不做检查, + 被跳过的块会被包括在这个总数中,因此当清理完成时这个数字最终将会等于heap_blks_total。 + 仅当处于scanning heap阶段时这个计数器才会前进。 - heap_tuples_written bigint + heap_blks_vacuumed bigint - 写入的堆元组的数量。这个计数器只有在阶段为seq scanning heap,index scanning heap - 或 writing new heap时才会前进。 + 被清理的堆块数量。除非表没有索引,这个计数器仅在处于vacuuming heap阶段时才会前进。 + 不包含死亡元组的块会被跳过,因此这个计数器可能有时会向前跳跃一个比较大的增量。 - heap_blks_total bigint + index_vacuum_count bigint - 表中的堆块总数。 这个数字是在seq scanning heap的开始时报告的。 + 已完成的索引清理周期数。 - heap_blks_scanned bigint + max_dead_tuples bigint - 扫描的堆块数量。该计数器仅在阶段为seq scanning heap时才会递增。 + 在需要执行索引清理周期之前可存储的死亡元组数量,取决于 - index_rebuild_count bigint + num_dead_tuples bigint - 已重建的索引数。该计数器仅在重建索引阶段时才会递增。 + 自上一个索引清理周期以来收集到的死亡元组数量。 + + + + + + + + + + + +
- +
- CLUSTER 和 VACUUM FULL 阶段 + VACUUM 阶段 @@ -6783,63 +6714,57 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - 初始化 - - 该命令准备开始扫描堆栈。 这个阶段预计会非常短暂。 - - - - - seq扫描堆 + initializing - 该命令目前采用顺序扫描的方式对表进行扫描。 + VACUUM正在准备开始扫描堆。这个阶段应该很简短。 - 索引扫描堆 + scanning heap - CLUSTER目前正在使用索引扫描表。 + VACUUM正在扫描堆。如果需要,它将会对每个页面进行剪枝以及碎片整理,并且可能会执行冻结动作。heap_blks_scanned列可以用来监控扫描的进度。 - 元组排序 - - CLUSTER目前正在对元组进行排序。 - + vacuuming indexes + VACUUM当前正在清理索引。如果表有索引,每次清理都会在堆扫描完成后至少执行一次此阶段。如果(或者,对于自动清理,已设置的)不足以存储找到的死亡元组数量,则每次清理可能多次执行此阶段。 - 新写入堆 + vacuuming heap - CLUSTER目前正在编写新的堆。 + VACUUM当前正在清理堆。清理堆与扫描堆不是同一个概念,清理堆发生在每次索引清理之后。如果heap_blks_scanned小于heap_blks_total,系统将在这个阶段完成之后回去扫描堆;否则,系统将在这个阶段完成后开始索引收尾清理。 - 交换关系文件 + cleaning up indexes - 目前,该命令正在将新建立的文件调换到位。 + VACUUM当前正在进行索引收尾清理。这个阶段发生在堆被完全扫描并且对堆和索引的所有清理都已经完成以后。 - 重建索引 + truncating heap - 该命令目前正在重建一个索引。 + VACUUM正在截断堆,以便把关系尾部的空页面返还给操作系统。这个阶段发生在索引收尾清理完成之后。 - 清理 + performing final cleanup - 该命令正在执行最后的清理工作。 当此阶段完成后,CLUSTERVACUUM FULL将结束。 + VACUUM正在执行最终清理。在此阶段,VACUUM将清理空闲空间映射, + 更新pg_class中的统计信息,并向累积统计系统报告统计信息。当此阶段完成时, + VACUUM将结束。
+
@@ -6900,7 +6825,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, 将被流式传输的数据总量。该值在streaming database files阶段开始时进行估算并报告。 注意,这只是一个近似值,因为数据库可能会在streaming database files阶段期间发生变化,而 WAL 日志也可能在稍后的备份阶段被包含进来。 一旦流式传输的数据量超过了估计的总大小,该值始终与backup_streamed相同。 - 如果在pg_basebackup中禁用估算(也就是说,指定了--no-estimate-size选项),这为NULL。 + 如果在pg_basebackup中禁用估算(也就是说,指定了--no-estimate-size选项),这为NULL
@@ -6957,7 +6882,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid,
- 等待检查点完成 + waiting for checkpoint to finish WAL 发送进程当前正在执行pg_backup_start以准备进行基础备份,并等待备份起始检查点完成。 @@ -6978,7 +6903,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - 等待wal归档完成 + waiting for wal archiving to finish WAL发送进程当前正在执行pg_backup_stop以完成备份, 并等待基础备份所需的所有 WAL 文件成功归档。 @@ -7001,141 +6926,6 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - - - COPY 进度报告 - - - pg_stat_progress_copy - - - - 当COPY正在运行时,pg_stat_progress_copy视图会为每个当前正在执行COPY命令的后端包含一行。下表描述了会报告哪些信息,以及应如何解释这些信息。 - - - - - <structname>pg_stat_progress_copy</structname> 视图 - - - - - - 列类型 - - - 描述 - - - - - - - - - pid integer - - - 后端的进程ID。 - - - - - - datid oid - - - 后端连接到的数据库的OID。 - - - - - - datname name - - - 后端连接到的数据库的名称。 - - - - - - relid oid - - - 执行COPY命令的表的OID。 - 如果从SELECT查询中复制,它被设置为0。 - - - - - - command text - - - 正在运行的命令: COPY FROM, 或 COPY TO。 - - - - - - type text - - - 数据被读取或写入的io类型:FILE, PROGRAM, PIPE (对于COPY FROM STDINCOPY TO STDOUT),或 CALLBACK(例如在逻辑复制中初始表同步期间使用)。 - - - - - - bytes_processed bigint - - - 已经被COPY命令处理的字节数。 - - - - - - bytes_total bigint - - - COPY FROM命令的源文件大小,以字节计。 - 如果不可用则设置为0。 - - - - - - tuples_processed bigint - - - 已经被COPY命令处理的元组数。 - - - - - - tuples_excluded bigint - - - 没有处理的元组数,因为它们被COPY命令的WHERE子句所排除。 - - - - - - tuples_skipped bigint - - - 因包含格式错误的数据而被跳过的元组数。只有当 ON_ERROR 选项指定的值不是 stop 时,此计数器才会递增。 - - - - -
-
-
@@ -7161,7 +6951,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - 动态追踪的编译 + 为动态追踪编译 默认情况下,探针是不可用的,因此你将需要显式地告诉配置脚本让探针在PostgreSQL中可用。要包括 DTrace 支持,在配置时指定。更多信息请见。 @@ -7173,7 +6963,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, 内置探针 - 如所示,源代码中提供了一些标准探针。显式了在探针中使用的类型。当然,可以增加更多探针来增强PostgreSQL的可观测性。 + 如所示,源代码中提供了一些标准探针。显示了在探针中使用的类型。当然,可以增加更多探针来增强PostgreSQL的可观测性。 @@ -7209,13 +6999,13 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, transaction-abort (LocalTransactionId) - 当一个事务失败完成时触发的探针。arg0 是事务 ID。 + 当一个事务失败结束时触发的探针。arg0 是事务 ID。 query-start (const char *) - 当一个查询的处理被开始时触发的探针。arg0 是查询字符串。 + 当一个查询的处理开始时触发的探针。arg0 是查询字符串。 @@ -7227,7 +7017,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, query-parse-start (const char *) - 当一个查询的解析被开始时触发的探针。arg0 是查询字符串。 + 当一个查询的解析开始时触发的探针。arg0 是查询字符串。 @@ -7239,7 +7029,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, query-rewrite-start (const char *) - 当一个查询的重写被开始时触发的探针。arg0 是查询字符串。 + 当一个查询的重写开始时触发的探针。arg0 是查询字符串。 @@ -7251,7 +7041,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, query-plan-start () - 当一个查询的规划被开始时触发的探针。 + 当一个查询的规划开始时触发的探针。 @@ -7263,7 +7053,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, query-execute-start () - 当一个查询的执行被开始时触发的探针。 + 当一个查询的执行开始时触发的探针。 @@ -7281,19 +7071,19 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, checkpoint-start (int) - 当一个检查点被开始时触发的探针。arg0 传递位标志来区分不同的检查点类型,例如关闭(shutdown)、立即(immediate)或强制(force)。 + 当一个检查点开始时触发的探针。arg0 传递位标志来区分不同的检查点类型,例如关闭(shutdown)、立即(immediate)或强制(force)。 checkpoint-done (int, int, int, int, int) - 当一个检查点完成时触发的探针(检查点处理过程中序列中列出的下一个触发的探针)。arg0 是要写的缓冲区数量。arg1 是缓冲区的总数。arg2、arg3 和 arg4 分别包含了增加、删除和循环回收的 WAL 文件的数量。 + 当一个检查点完成时触发的探针(下面列出的探针会在检查点处理过程中依次触发)。arg0 是已写入的缓冲区数量。arg1 是缓冲区的总数。arg2、arg3 和 arg4 分别包含了增加、删除和循环回收的 WAL 文件的数量。 clog-checkpoint-start (bool) - 当一个检查点的 CLOG 部分被开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 + 当一个检查点的 CLOG 部分开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 @@ -7305,7 +7095,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, subtrans-checkpoint-start (bool) - 当一个检查点的 SUBTRANS 部分被开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 + 当一个检查点的 SUBTRANS 部分开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 @@ -7317,7 +7107,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, multixact-checkpoint-start (bool) - 当一个检查点的 MultiXact 部分被开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 + 当一个检查点的 MultiXact 部分开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 @@ -7329,7 +7119,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, buffer-checkpoint-start (int) - 当一个检查点的写缓冲区部分被开始时触发的探针。arg0 传递位标志来区分不同的检查点类型,例如关闭(shutdown)、立即(immediate)或强制(force)。 + 当一个检查点的写缓冲区部分开始时触发的探针。arg0 传递位标志来区分不同的检查点类型,例如关闭(shutdown)、立即(immediate)或强制(force)。 @@ -7365,7 +7155,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, twophase-checkpoint-start () - 当一个检查点的两阶段部分被开始时触发的探针。 + 当一个检查点的两阶段部分开始时触发的探针。 @@ -7374,22 +7164,54 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, 当一个检查点的两阶段部分完成时触发的探针。 + + buffer-extend-start + (ForkNumber, BlockNumber, Oid, Oid, Oid, int, unsigned int) + 当关系扩展开始时触发的探针。 + arg0 包含要扩展的分支。arg1、arg2 和 arg3 包含用于标识该关系的 + 表空间、数据库和关系 OID。对于本地缓冲区,arg4 是创建临时关系的后端 ID; + 对于共享缓冲区,则为 InvalidBackendId(-1)。 + arg5 是调用者希望扩展的块数。 + + + + buffer-extend-done + (ForkNumber, BlockNumber, Oid, Oid, Oid, int, unsigned int, BlockNumber) + 当关系扩展完成时触发的探针。 + arg0 包含要扩展的分支。arg1、arg2 和 arg3 包含用于标识该关系的 + 表空间、数据库和关系 OID。对于本地缓冲区,arg4 是创建临时关系的后端 ID; + 对于共享缓冲区,则为 InvalidBackendId(-1)。 + arg5 是关系实际扩展的块数;由于资源限制,该值可能小于 + buffer-extend-start中的数量。arg6 包含第一个新块的 + BlockNumber。 + + buffer-read-start - (ForkNumber, BlockNumber, Oid, Oid, Oid, int, bool) - 当一次缓冲区读被开始时触发的探针。arg0 和 arg1 包含该页的分叉号和块号(如果这是一次关系扩展请求,arg1 为 -1)。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是 InvalidBackendId(-1)。arg6 为真表示一次关系扩展请求,为假表示正常读。 + (ForkNumber, BlockNumber, Oid, Oid, Oid, int) + 当缓冲区读取开始时触发的探针。 + arg0 和 arg1 包含该页的分支号和块号。 + arg2、arg3 和 arg4 包含用于标识该关系的表空间、数据库和关系 OID。 + 对于本地缓冲区,arg5 是创建临时关系的后端 ID;对于共享缓冲区, + 则为 InvalidBackendId(-1)。 + buffer-read-done - (ForkNumber, BlockNumber, Oid, Oid, Oid, int, bool, bool) - 当一次缓冲区读完成时触发的探针。arg0 和 arg1 包含该页的分叉号和块号(如果这是一次关系扩展请求,arg1 现在包含新增加块的块号)。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是 InvalidBackendId(-1)。arg6 为真表示一次关系扩展请求,为假表示正常读。arg7 为真表示在池中找到该缓冲区,为假表示没有找到。 + (ForkNumber, BlockNumber, Oid, Oid, Oid, int, bool) + 当缓冲区读取完成时触发的探针。 + arg0 和 arg1 包含该页的分支号和块号。 + arg2、arg3 和 arg4 包含用于标识该关系的表空间、数据库和关系 OID。 + 对于本地缓冲区,arg5 是创建临时关系的后端 ID;对于共享缓冲区, + 则为 InvalidBackendId(-1)。 + 如果在缓冲池中找到了该缓冲区,arg6 为真;否则为假。 buffer-flush-start (ForkNumber, BlockNumber, Oid, Oid, Oid) - 在发出对一个共享缓冲区的任意写请求之前触发的探针。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。 + 在发出对一个共享缓冲区的任意写请求之前触发的探针。arg0 和 arg1 包含该页的分支号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。 @@ -7398,17 +7220,9 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, 当一个写请求完成时触发的探针(注意这只反映传递数据给内核的时间,它通常并没有实际地被写入到磁盘)。参数和buffer-flush-start的相同。 - - buffer-write-dirty-start - (ForkNumber, BlockNumber, Oid, Oid, Oid) - 当一个服务器进程开始写一个脏缓冲区时触发的探针(如果这经常发生,表示太小,或需要调整后台写入器的控制参数)。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。 - - - buffer-write-dirty-done - (ForkNumber, BlockNumber, Oid, Oid, Oid) - 当一次脏缓冲区写完成时触发的探针。参数与buffer-write-dirty-start相同。 - + + wal-buffer-write-dirty-start @@ -7419,13 +7233,13 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, wal-buffer-write-dirty-done () - 当一次脏 WAL 缓冲区完成时触发的探针。 + 当一次脏 WAL 缓冲区写入完成时触发的探针。 wal-insert (unsigned char, unsigned char) - 当一个 WAL 记录被插入时触发的探针。arg0 是该记录的资源管理者(rmid)。arg1 包含 info 标志。 + 当一个 WAL 记录被插入时触发的探针。arg0 是该记录的资源管理器(rmid)。arg1 包含 info 标志。 @@ -7437,31 +7251,31 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, smgr-md-read-start (ForkNumber, BlockNumber, Oid, Oid, Oid, int) - 当开始从一个关系读取一块时触发的探针。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。 + 当开始从一个关系读取一块时触发的探针。arg0 和 arg1 包含该页的分支号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。 smgr-md-read-done (ForkNumber, BlockNumber, Oid, Oid, Oid, int, int, int) - 当一次块读取完成时触发的探针。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。arg6 是实际读取的字节数,而 arg7 是请求读取的字节数(如果两者不同就意味着麻烦)。 + 当一次块读取完成时触发的探针。arg0 和 arg1 包含该页的分支号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。arg6 是实际读取的字节数,而 arg7 是请求读取的字节数(如果两者不同就意味着麻烦)。 smgr-md-write-start (ForkNumber, BlockNumber, Oid, Oid, Oid, int) - 当开始向一个关系中写入一个块时触发的探针。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。 + 当开始向一个关系中写入一个块时触发的探针。arg0 和 arg1 包含该页的分支号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。 smgr-md-write-done (ForkNumber, BlockNumber, Oid, Oid, Oid, int, int, int) - 当一个块写操作完成时触发的探针。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3和arg4 包含表空间、数据库和关系 OID来标识该关系。对于一个本地缓冲区,arg5 是创建临时关系的后端 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。arg6 是实际写的字节数,而 arg7 是要求写的字节数(如果这两者不同,则意味着麻烦)。 + 当一个块写操作完成时触发的探针。arg0 和 arg1 包含该页的分支号和块号。arg2、arg3和arg4 包含表空间、数据库和关系 OID来标识该关系。对于一个本地缓冲区,arg5 是创建临时关系的后端 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。arg6 是实际写的字节数,而 arg7 是要求写的字节数(如果这两者不同,则意味着麻烦)。 sort-start (int, bool, int, int, bool, int) - 当一次排序操作开始时触发的探针。arg0 指示是堆排序、索引排序或数据排序。arg1 为真表示强制唯一值。arg2 是键列数。arg3 是允许使用的工作内存大小(以千字节计)。如果要求随机访问排序结果,则 arg4 为真。arg5 为 0 时表示串行,为 1 时表示并行工作进程,为 2 时表示并行领导者。 + 当一次排序操作开始时触发的探针。arg0 指示是堆排序、索引排序或 datum 排序。arg1 为真表示强制唯一值。arg2 是键列数。arg3 是允许使用的工作内存大小(以千字节计)。如果要求随机访问排序结果,则 arg4 为真。arg5 为 0 时表示串行,为 1 时表示并行工作进程,为 2 时表示并行领导者。 @@ -7475,7 +7289,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, (char *, LWLockMode) 当成功获得一个 LWLock 时触发的探针。 arg0 是该 LWLock 所在的切片(Tranche)。 - arg1 所请求的锁模式,是排他或共享。 + arg1 是所请求的锁模式,是排他或共享。 @@ -7490,34 +7304,34 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, (char *, LWLockMode) 当一个 LWLock不是当即可用并且一个服务器进程因此开始等待该锁变为可用时触发的探针。 arg0 是该 LWLock 所在的切片(Tranche)。 - arg1 请求的锁模式,是排他或共享。 + arg1 是所请求的锁模式,是排他或共享。 lwlock-wait-done (char *, LWLockMode) 当一个进程从对一个 LWLock 的等待中被释放时(它实际还没有得到该锁)时触发的探针。arg0 是该 LWLock 所在的切片(Tranche)。 - arg1 所请求的锁模式,是排他或共享。 + arg1 是所请求的锁模式,是排他或共享。 lwlock-condacquire (char *, LWLockMode) 当调用者指定无需等待而成功获得一个 LWLock 时触发的探针。arg0 是该 LWLock 所在的切片(Tranche)。 - arg1 所请求的锁模式,是排他或共享。 + arg1 是所请求的锁模式,是排他或共享。 lwlock-condacquire-fail (char *, LWLockMode) 当调用者指定无需等待而没有成功获得一个 LWLock 时触发的探针。arg0 是该 LWLock 所在的切片(Tranche)。 - arg1 所请求的锁模式,是排他或共享。 + arg1 是所请求的锁模式,是排他或共享。 lock-wait-start (unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, LOCKMODE) - 当一个重量级锁(lmgr锁)的请求由于锁不可用开始等待时触发的探针。arg0 到 arg3 是标识被锁定对象的标签域。arg4 指示被锁对象的类型。arg5 表示被请求的锁类型。 + 当一个重量级锁(lmgr锁)的请求由于锁不可用开始等待时触发的探针。arg0 到 arg3 是标识被锁定对象的标签字段。arg4 指示被锁对象的类型。arg5 表示被请求的锁类型。 @@ -7538,7 +7352,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid,
- 定义用在探针参数中的类型 + 探针参数中使用的已定义类型 @@ -7632,7 +7446,7 @@ Total time (ns) 2312105013 - 你应该记住,DTrace 脚本需要细心地编写和调试,否则被收集的追踪信息可能会毫无意义。在大部分发现问题的情况中,它就是发生问题的部件,而不是底层系统。当讨论使用动态追踪发现的信息时,一定要附上使用的脚本以便其也被检查和讨论。 + 你应该记住,DTrace 脚本需要细心地编写和调试,否则被收集的追踪信息可能会毫无意义。在大多数发现问题的情况下,出错的是插桩,而不是底层系统。当讨论使用动态追踪发现的信息时,一定要附上使用的脚本以便其也被检查和讨论。 @@ -7648,7 +7462,7 @@ Total time (ns) 2312105013 - 决定探针名称以及探针可用的数据 + 决定探针名称以及要通过探针提供的数据 @@ -7662,7 +7476,7 @@ Total time (ns) 2312105013 - 如果pg_trace.h还不存在于包含该探针点的模块中,包括它,并且在源代码中期望的位置插入TRACE_POSTGRESQL探针宏 + 如果pg_trace.h尚未被包含该探针点的模块引用,则将它包含进来,并且在源代码中期望的位置插入TRACE_POSTGRESQL探针宏 @@ -7698,14 +7512,14 @@ Total time (ns) 2312105013 probe transaction__start(LocalTransactionId); - 注意探针名字中双下划线的使用。在一个使用探针的 DTrace 脚本中,双下划线需要被替换为一个连字符,因此 ,对用户而言transaction-start是文档名。 + 注意探针名字中双下划线的使用。在一个使用探针的 DTrace 脚本中,双下划线需要被替换为一个连字符,因此,文档中应向用户说明的名称是transaction-start - 在编译时,transaction__start被转换成一个宏调用TRACE_POSTGRESQL_TRANSACTION_START(注意这里是单下划线),可以通过包括头文件pg_trace.h获得。将宏调用加入到源代码中的合适位置。在这种情况下,看起来类似: + 在编译时,transaction__start被转换成一个名为TRACE_POSTGRESQL_TRANSACTION_START的宏(注意这里是单下划线),可以通过包含头文件pg_trace.h获得。将宏调用加入到源代码中的合适位置。在这种情况下,看起来类似: TRACE_POSTGRESQL_TRANSACTION_START(vxid.localTransactionId); @@ -7742,7 +7556,7 @@ TRACE_POSTGRESQL_TRANSACTION_START(vxid.localTransactionId); - 在大多数平台上,如果用编译了PostgreSQL,无论何时当控制经过一个追踪宏时,都会评估该宏的参数,即使没有进行追踪也会这样做。通常不需要担心你是否只在报告一些局部变量的值。但是要注意不要将开销大的函数调用放入参数中。如果你需要这样做,考虑通过检查追踪是否真的被启用来保护该宏: + 在大多数平台上,如果用编译了PostgreSQL,无论何时当控制经过一个追踪宏时,都会对该宏的参数求值,即使没有进行追踪也会这样做。如果只是报告少数局部变量的值,通常无需担心这一点。但是要注意不要将开销大的函数调用放入参数中。如果你需要这样做,考虑通过检查追踪是否真的被启用来保护该宏: if (TRACE_POSTGRESQL_TRANSACTION_START_ENABLED()) diff --git a/zh/16/mvcc.sgml b/zh/16/mvcc.sgml index a8bdfa9a..dab1c30f 100644 --- a/zh/16/mvcc.sgml +++ b/zh/16/mvcc.sgml @@ -4,7 +4,7 @@ 并发控制 - concurrency + 并发 @@ -15,7 +15,7 @@ 介绍 - Multiversion Concurrency Control + 多版本并发控制 @@ -23,7 +23,7 @@ - Serializable Snapshot Isolation + 可串行化快照隔离 @@ -50,7 +50,7 @@ 事务隔离 - transaction isolation + 事务隔离 @@ -68,7 +68,7 @@ 脏读 - dirty read + 脏读 @@ -80,7 +80,7 @@ 不可重复读 - nonrepeatable read + 不可重复读 @@ -92,7 +92,7 @@ 幻读 - phantom read + 幻读 @@ -104,7 +104,7 @@ 串行化异常 - serialization anomaly + 串行化异常 @@ -117,7 +117,7 @@ - transaction isolation level + 事务隔离级别 SQL 标准以及 PostgreSQL 实现的事务隔离级别见 @@ -244,12 +244,12 @@ 读已提交隔离级别 - transaction isolation level - read committed + 事务隔离级别 + 读已提交 - read committed + 读已提交 @@ -306,11 +306,7 @@ 不过,由于 MERGE 可以指定多个动作并且这些动作可以带条件, 因此会从第一个动作开始,在该行的已更新版本上重新评估各动作的条件, 即使最初匹配的动作在动作列表中出现得更靠后。 - 另一方面,如果该行被并发更新以致连接条件不再成立,那么 MERGE - 接下来会评估命令的 NOT MATCHED BY SOURCE 和 - NOT MATCHED [BY TARGET] 动作,并分别执行每一类中第一个成功的动作。 - 如果该行被并发删除,那么 MERGE 会评估命令的 - NOT MATCHED [BY TARGET] 动作,并执行第一个成功的动作。 + 另一方面,如果该行被并发更新或删除,导致连接条件不成立,那么 MERGE 接下来会评估条件的 NOT MATCHED 动作,并执行第一个成功的动作。 如果 MERGE 尝试执行 INSERT,且存在唯一索引并且并发插入了重复行, 则会引发唯一性违例错误;MERGE 不会通过重新开始评估 MATCHED 条件来尝试避免此类错误。 @@ -319,7 +315,7 @@ 由于上述规则,更新命令可能看到一个不一致的快照:它能够看到并发更新命令在它试图更新的同一行上的效果, 却看不到这些命令对数据库中其他行的影响。这种行为使得读已提交模式不适合涉及复杂搜索条件的命令; - 不过,对于较简单的场景它恰到好处。例如,考虑将 100 美元从一个账户转到另一个账户: + 不过,对于较简单的场景它恰到好处。例如,考虑以如下事务更新银行余额: BEGIN; @@ -328,13 +324,13 @@ UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 7534; COMMIT; - 如果另一个事务并发地尝试更改账户 7534 的余额,我们显然希望第二条语句从该账户行的已更新版本开始。 + 如果两个这样的事务并发地尝试更改账户 12345 的余额,我们显然希望第二个事务从该账户行的已更新版本开始。 因为每个命令只影响一个预先确定的行,让它看到该行的已更新版本不会造成任何麻烦的不一致。 在读已提交模式下,更复杂的用法可能产生不理想的结果。例如,考虑一个 - DELETE 命令,它所处理的数据会被另一个命令同时加入和移出其筛选条件。 + DELETE 命令,另一个命令正在修改数据,使某些行开始满足其筛选条件、另一些行不再满足。 假设 website 是一个有两行的表,其中 website.hits 分别等于 910: @@ -342,7 +338,7 @@ COMMIT; BEGIN; UPDATE website SET hits = hits + 1; --- run from another session: DELETE FROM website WHERE hits = 10; +-- 从另一个会话运行: DELETE FROM website WHERE hits = 10; COMMIT; @@ -370,12 +366,12 @@ COMMIT; 可重复读隔离级别 - transaction isolation level - repeatable read + 事务隔离级别 + 可重复读 - repeatable read + 可重复读 @@ -428,9 +424,7 @@ ERROR: could not serialize access due to concurrent update 可重复读模式提供了严格的保证,即每个事务都看到数据库的一个完全稳定的视图。 不过,这个视图并不一定总能与同一级别并发事务的某种串行(一次一个)执行保持一致。 - 例如,即使该级别上的只读事务可能看到一条控制记录被更新,表明某个批处理已经完成, - 但它并不一定能看到作为该批处理逻辑组成部分的某条明细记录, - 因为它读到的是控制记录的较早版本。如果不仔细使用显式锁来阻塞冲突事务, + 例如,即使是该级别的只读事务,也可能看到一条表明某批次已完成的控制记录,却看不到逻辑上属于该批次的某条明细记录,因为创建该明细记录的事务读取了控制记录的较早版本。如果不仔细使用显式锁来阻塞冲突事务, 试图依靠运行在这一隔离级别的事务来强制业务规则,往往无法正确工作。 @@ -438,7 +432,7 @@ ERROR: could not serialize access due to concurrent update 可重复读隔离级别是通过一种技术实现的,这种技术在学术数据库文献中以及某些其他数据库产品中被称为 快照隔离。与使用会降低并发性的传统加锁技术的系统相比, 其行为和性能可能会表现出差异。有些其他系统甚至把可重复读和快照隔离作为两个行为不同的独立隔离级别提供。 - 用来区分这两种技术的允许现象,直到 SQL 标准制定之后才被数据库研究人员正式定义,因此超出了本手册的范围。 + 用来区分这两种技术的允许现象,直到 SQL 标准制定之后才被数据库研究人员正式定义,并且超出了本手册的范围。 完整讨论请参阅 @@ -454,20 +448,20 @@ ERROR: could not serialize access due to concurrent update 可串行化隔离级别 - transaction isolation level - serializable + 事务隔离级别 + 可串行化 - serializable + 可串行化 - predicate locking + 谓词锁 - serialization anomaly + 串行化异常 @@ -480,48 +474,30 @@ ERROR: could not serialize access due to concurrent update 一旦检测到可能导致串行化异常的条件,就会触发串行化失败 - - 例如,考虑一张表 mytab,其初始内容为: - + 例如,考虑表mytab,它最初包含以下内容: class | value -------+------- 1 | 10 1 | 20 2 | 100 2 | 200 - - 假设可串行化事务 A 计算: - +假设可串行化事务 A 执行以下计算: SELECT SUM(value) FROM mytab WHERE class = 1; - - 然后将结果(30)作为一条新行的 value 插入,并把 - class 设为 2。与此同时,可串行化事务 B 计算: - +然后将结果(30)作为新行的value插入,且该行满足class = 2。与此同时,可串行化事务 B 执行以下计算: SELECT SUM(value) FROM mytab WHERE class = 2; - - 并得到结果 300,再把它插入为一条新行,其 - class1。然后两个事务都尝试提交。 - 如果任一事务是在可重复读隔离级别下运行,则二者都可以提交; - 但由于不存在与该结果一致的串行执行顺序,使用可串行化事务时将允许其中一个事务提交, - 并按如下消息回滚另一个事务: - - +得到结果 300,并将它插入一个新行,该行满足class = 1。然后两个事务都尝试提交。如果任一事务运行在可重复读隔离级别,两个事务都可以提交;但由于不存在与该结果一致的串行执行顺序,使用可串行化事务时,只会允许一个事务提交,另一个则会被回滚,并收到以下消息: ERROR: could not serialize access due to read/write dependencies among transactions - - - 这是因为,如果 A 先于 B 执行,B 算出的和将是 330 而不是 300; - 反过来,另一种顺序也会使 A 算出不同的和。 - +这是因为,如果 A 在 B 之前执行,B 算出的总和应该是 330,而不是 300;同样,按另一种顺序执行,A 算出的总和也会不同。 当依赖可串行化事务来防止异常时,重要的是:从永久用户表读取的任何数据,在读取它的事务成功提交之前, - 都不应视为有效。即使对于只读事务也是如此;唯一的例外是可推迟只读事务中读取的数据, + 都不应视为有效。即使对于只读事务也是如此;唯一的例外是可延迟只读事务中读取的数据, 它一经读出就可视为有效,因为这种事务会等到能够获取一个保证不存在此类问题的快照后才开始读取数据。 在所有其他情况下,应用不能依赖后来被中止事务中读到的结果;相反,应重试事务直到成功。 - 为了保证真正的可串行化,PostgreSQL 使用了谓词锁, + 为了保证真正的可串行性,PostgreSQL 使用了谓词锁, 也就是说,系统会保留一些锁,以便判断某个写操作如果先发生,是否会影响并发事务先前读取的结果。 在 PostgreSQL 中,这些锁不会造成任何阻塞,因此会参与形成死锁。 它们用于识别并标记并发可串行化事务之间的依赖关系,而这些依赖在某些组合下可能导致串行化异常。 @@ -543,7 +519,7 @@ ERROR: could not serialize access due to read/write dependencies among transact - 持续使用可串行化事务可以简化开发。任何一组成功提交的并发可串行化事务,都保证与把它们一次一个运行的效果相同;这意味着,如果你能够证明某个事务在单独运行时会做正确的事,那么即使不了解其他事务会做什么,也可以相信它在任何可串行化事务的混合执行中也会做正确的事,否则它就不会成功提交。重要的是,采用这种技术的环境应当有一套通用机制来处理串行化失败(其 SQLSTATE 值总是 40001),因为很难准确预测究竟哪些事务会对读/写依赖关系有贡献,并因此需要被回滚来防止串行化异常。监视读/写依赖关系会带来开销,被串行化失败中止的事务重新启动也会带来开销;但在把这些开销与显式锁以及 SELECT FOR UPDATESELECT FOR SHARE 所涉及的成本和阻塞进行权衡之后,可串行化事务在某些环境中仍然是性能最佳的选择。 + 统一采用可串行化事务可以简化开发。任何一组成功提交的并发可串行化事务,都保证与把它们一次一个运行的效果相同;这意味着,如果你能够证明某个事务在单独运行时会做正确的事,那么即使不了解其他事务会做什么,也可以相信它在任何可串行化事务的混合执行中也会做正确的事,否则它就不会成功提交。重要的是,采用这种技术的环境应当有一套通用机制来处理串行化失败(其 SQLSTATE 值总是 40001),因为很难准确预测究竟哪些事务会对读/写依赖关系有贡献,并因此需要被回滚来防止串行化异常。监视读/写依赖关系会带来开销,被串行化失败中止的事务重新启动也会带来开销;但在把这些开销与显式锁以及 SELECT FOR UPDATESELECT FOR SHARE 所涉及的成本和阻塞进行权衡之后,可串行化事务在某些环境中仍然是性能最佳的选择。 @@ -587,7 +563,7 @@ ERROR: could not serialize access due to read/write dependencies among transact - 当系统因谓词锁表内存不足而被迫把多个页级谓词锁合并为单个关系级谓词锁时,串行化失败的比例可能会上升。你可以通过增加 来避免这种情况。 + 当系统因谓词锁表内存不足而被迫把多个页级谓词锁合并为单个关系级谓词锁时,串行化失败的比例可能会上升。你可以通过增加 和/或 来避免这种情况。 @@ -611,7 +587,7 @@ ERROR: could not serialize access due to read/write dependencies among transact 显式锁定 - lock + @@ -715,7 +691,7 @@ ERROR: could not serialize access due to read/write dependencies among transact CREATE STATISTICSCOMMENT ONREINDEX CONCURRENTLY, 以及某些 ALTER INDEX - 和 ALTER TABLE 变体会获取这种锁 + 和 ALTER TABLE 变体获取这种锁 (有关详细信息,请参阅这些命令的文档)。 @@ -980,7 +956,7 @@ ERROR: could not serialize access due to read/write dependencies among transact - 行为与 FOR SHARE 类似,不过锁更弱:SELECT FOR UPDATE 会被阻塞,但 SELECT FOR NO KEY UPDATE 不会。键共享锁会阻塞其他事务执行会修改键值的 DELETEUPDATE,但不会阻塞其他 UPDATE,也不会阻止 SELECT FOR NO KEY UPDATESELECT FOR SHARESELECT FOR KEY SHARE。 + 行为与 FOR SHARE 类似,不过锁更弱:SELECT FOR UPDATE 会被阻塞,但 SELECT FOR NO KEY UPDATE 不会。键共享锁会阻塞其他事务执行 DELETE 或任何会修改键值的 UPDATE,但不会阻塞其他 UPDATE,也不会阻止 SELECT FOR NO KEY UPDATESELECT FOR SHARESELECT FOR KEY SHARE @@ -1058,7 +1034,7 @@ ERROR: could not serialize access due to read/write dependencies among transact 死锁 - deadlock + 死锁 @@ -1101,12 +1077,12 @@ UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 22222; 咨询锁 - advisory lock + 咨询锁 - lock - advisory + + 咨询 @@ -1138,12 +1114,12 @@ UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 22222; 在某些使用咨询锁的方法中,特别是涉及显式排序和 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(id) FROM foo WHERE id = 12345; -- 可以 +SELECT pg_advisory_lock(id) FROM foo WHERE id > 12345 LIMIT 100; -- 危险! SELECT pg_advisory_lock(q.id) FROM ( SELECT id FROM foo WHERE id > 12345 LIMIT 100 -) q; -- ok +) q; -- 可以 在上面的查询中,第二种形式是危险的,因为不能保证在执行加锁函数之前先应用 LIMIT。 这可能导致获取了一些应用并未预期的锁,因此应用也不会去释放它们(直到会话结束)。 @@ -1161,12 +1137,12 @@ SELECT pg_advisory_lock(q.id) FROM 应用级别的数据一致性检查 - 在读已提交事务下,想要通过业务规则强制数据一致性非常困难,因为数据视图会随每条语句而变化, + 用读已提交事务强制执行有关数据完整性的业务规则非常困难,因为数据视图会随每条语句而变化, 而且一旦发生写冲突,即使是单条语句也未必局限于该语句自己的快照。 - 虽然可重复读事务在整个执行期间都具有稳定的数据视图,但在使用 MVCC 快照进行数据一致性检查时,还存在一个微妙问题,即所谓的读/写冲突。如果一个事务写入数据,而并发事务试图读取相同的数据(无论是在写入之前还是之后),它都看不到另一个事务的工作。于是,读取者看起来就像是先执行的一方,而不管究竟是谁先启动,也不管谁先提交。如果事情只停留在这一步,就没有问题;但如果读取者还写入了数据,而这些数据又被另一个并发事务读取,那么现在就会有一个事务看起来像是在前面提到的任一事务之前执行。如果看起来最后执行的事务实际上最先提交,就很容易在事务执行顺序图中形成一个环。一旦出现这样的环,不借助额外机制,一致性检查就无法正确工作。 + 虽然可重复读事务在整个执行期间都具有稳定的数据视图,但在使用 MVCC 快照进行数据一致性检查时,还存在一个微妙问题,即所谓的读/写冲突。如果一个事务写入数据,而并发事务试图读取相同的数据(无论是在写入之前还是之后),它都看不到另一个事务的工作。于是,读取者看起来就像是先执行的一方,而不管究竟是谁先启动,也不管谁先提交。如果事情只停留在这一步,就没有问题;但如果读取者还写入了数据,而这些数据又被另一个并发事务读取,那么现在就会有一个事务看起来像是在前面提到的任一事务之前执行。如果看起来最后执行的事务实际上最先提交,就很容易在事务执行顺序图中形成一个环。一旦出现这样的环,不借助额外机制,完整性检查就无法正确工作。 @@ -1183,7 +1159,7 @@ SELECT pg_advisory_lock(q.id) FROM - 使用这种技术时,如果应用软件通过某个框架运行,并由该框架自动重试因串行化错误而回滚的事务,就可以避免给应用程序员带来不必要的负担。把 default_transaction_isolation 设置为 serializable 可能是个好主意。通过在触发器中检查事务隔离级别来采取某些措施,以确保不会因为疏忽或为了绕过完整性检查而使用其他事务隔离级别,也是明智的。 + 使用这种技术时,如果应用软件通过某个框架运行,并由该框架自动重试因串行化失败而回滚的事务,就可以避免给应用程序员带来不必要的负担。把 default_transaction_isolation 设置为 serializable 可能是个好主意。通过在触发器中检查事务隔离级别来采取某些措施,以确保不会因为疏忽或为了绕过完整性检查而使用其他事务隔离级别,也是明智的。 @@ -1200,7 +1176,7 @@ SELECT pg_advisory_lock(q.id) FROM - 使用显式锁定强制一致性 + 使用显式阻塞锁强制一致性 当存在非可串行化写入时,要确保某一行当前仍然有效,并保护它不受并发更新影响, @@ -1223,7 +1199,7 @@ SELECT pg_advisory_lock(q.id) FROM 在非可串行化的 MVCC 环境下,全局有效性检查需要额外考虑。 - 例如,一个银行应用可能希望检查一个表中的所有收入总和等于另一个表中的所有支出总和, + 例如,一个银行应用可能希望检查一个表中的贷方金额总和等于另一个表中的借方金额总和, 而这两个表都在被活跃更新。在读已提交模式下,比较两个连续的 SELECT sum(...) 命令的结果并不可靠,因为第二个查询很可能会包含第一个查询没有统计到的事务提交结果。 在单个可重复读事务中完成这两次求和,只能准确反映在该可重复读事务开始之前已提交事务的效果 @@ -1251,10 +1227,10 @@ SELECT pg_advisory_lock(q.id) FROM 串行化失败处理 - serialization failure + 串行化失败 - retryable error + 可重试错误 @@ -1291,7 +1267,7 @@ SELECT pg_advisory_lock(q.id) FROM 重试事务并不保证重试后的事务一定能够完成;可能需要多次重试。 在争用非常激烈的情况下,完成一个事务可能需要尝试很多次。 - 如果涉及相互冲突的已准备事务,那么在已准备事务提交或回滚之前,可能根本无法取得进展。 + 如果涉及相互冲突的预备事务,那么在预备事务提交或回滚之前,可能根本无法取得进展。 @@ -1319,8 +1295,8 @@ SELECT pg_advisory_lock(q.id) FROM 锁定和索引 - index - locks + 索引 + @@ -1333,7 +1309,7 @@ SELECT pg_advisory_lock(q.id) FROM - 读写访问使用短期的页级共享/排他锁。每个索引行在被取出或插入之后,锁都会立即释放。这些索引类型在不存在死锁条件的前提下提供了最高的并发性。 + 读写访问使用短期的页级共享/排他锁。每个索引行在被取出或插入之后,锁都会立即释放。这些索引类型提供最高的并发性,并且不会产生死锁。 @@ -1355,7 +1331,7 @@ SELECT pg_advisory_lock(q.id) FROM - 读写访问使用短期的页级共享/排他锁。每个索引行在被取出或插入之后,锁都会立即释放。但要注意,插入一个 GIN 索引值通常会导致每行产生多个索引键插入,因此 GIN 可能为了插入单个值而做大量工作。 + 读写访问使用短期的页级共享/排他锁。每个索引行在被取出或插入之后,锁都会立即释放。但要注意,插入一个使用 GIN 索引的值通常会导致每行产生多个索引键插入,因此 GIN 可能为了插入单个值而做大量工作。 diff --git a/zh/16/oid2name.sgml b/zh/16/oid2name.sgml index 4b80f64a..40bb461a 100644 --- a/zh/16/oid2name.sgml +++ b/zh/16/oid2name.sgml @@ -8,7 +8,7 @@ oid2name 1 - Application + 应用程序 diff --git a/zh/16/pageinspect.sgml b/zh/16/pageinspect.sgml index 46b0b0c9..5a7090c6 100644 --- a/zh/16/pageinspect.sgml +++ b/zh/16/pageinspect.sgml @@ -370,20 +370,20 @@ test=# SELECT itemoffset, ctid, itemlen, nulls, vars, data, dead, htid, tids[0:2 13 | (16,8292) | 616 | f | f | 2f 00 00 00 00 00 00 00 | f | (4,17) | {"(4,17)","(4,21)"} (13 rows) - 这是一个 B-树叶页。所有指向表的元组恰好都是 posting list 元组(它们总共存储了 100 个 6 字节的 TID)。此外,在itemoffset 编号 1 处还有一个high key元组。这个示例中,ctid用于存储每个元组的编码信息,不过叶页元组通常会直接在ctid字段中存储一个堆 TID。tids是作为 posting list 存储的 TID 列表。 + 这是一个 B-树叶页。所有指向表的元组恰好都是倒排列表元组(每个都存储了 100 个 6 字节的 TID)。此外,在itemoffset 编号 1 处还有一个高键元组。这个示例中,ctid用于存储每个元组的编码信息,不过叶页元组通常会直接在ctid字段中存储一个堆 TID。tids是作为倒排列表存储的 TID 列表。 在内部页(此处未显示)中,ctid的块号部分是一个downlink(下行链接),也就是该索引中另一页的块号。ctid的偏移部分(第二个数字)存储着关于该元组的编码信息,例如实际存在的列数(后缀截断可能移除了不需要的后缀列)。被截断的列被视为具有minus infinity值。 - htid显示该元组的堆 TID,而不考虑底层元组表示形式。这个值可能与ctid相同,也可能是从 posting list 元组以及内部页元组所使用的替代表示中解码出来的。内部页中的元组通常会把实现层面的堆 TID 列截断掉,这会表现为htid值为 NULL。 + htid显示该元组的堆 TID,而不考虑底层元组表示形式。这个值可能与ctid相同,也可能是从倒排列表元组以及内部页元组所使用的替代表示中解码出来的。内部页中的元组通常会把实现层面的堆 TID 列截断掉,这会表现为htid值为 NULL。 - 请注意,任何非最右页(即btpo_next字段值非零的页面)的第一项都是该页的high key,这意味着它的data充当该页上所有项的上界,而它的ctid字段并不指向另一个块。另外,在内部页上,第一个真正的数据项(第一个不是high key的项)一定会把所有列都截断掉,因此其data字段中没有实际值。不过,这样的项在其ctid字段中确实有一个有效的下行链接。 + 请注意,任何非最右页(即btpo_next字段值非零的页面)的第一项都是该页的高键,这意味着它的data充当该页上所有项的上界,而它的ctid字段并不指向另一个块。另外,在内部页上,第一个真正的数据项(第一个不是高键的项)一定会把所有列都截断掉,因此其data字段中没有实际值。不过,这样的项在其ctid字段中确实有一个有效的下行链接。 - 关于 B-树索引结构的更多细节,参见。关于去重和 posting list 的更多细节,参见。关于去重和倒排列表的更多细节,参见 diff --git a/zh/16/parallel.sgml b/zh/16/parallel.sgml index 424f847e..e3832749 100644 --- a/zh/16/parallel.sgml +++ b/zh/16/parallel.sgml @@ -222,7 +222,7 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%'; - Parallel Append + 并行追加 每当 PostgreSQL 需要将来自多个源的行合并成一个结果集时,它就会使用 AppendMergeAppend 计划节点。这种情况常见于实现 UNION ALL 或扫描分区表时。这样的节点和其他任何计划中的情形一样,也可以用于并行计划。不过,在并行计划中,规划器也可能改用 Parallel Append 节点。 @@ -286,9 +286,11 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%'; - - 引用相关 SubPlan 的计划节点。 - + 附带 InitPlan 的计划节点。 + + + + 引用相关 SubPlan 的计划节点。 @@ -300,7 +302,7 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%'; - 如果函数或聚合会写数据库、修改事务状态(而不是通过子事务进行错误恢复)、访问序列,或者对设置做持久更改,那么它们必须标记为 PARALLEL UNSAFE。类似地,如果函数访问临时表、客户端连接状态、游标、预备语句,或者系统无法在工作进程之间同步的各种后端本地状态,那么它必须标记为 PARALLEL RESTRICTED。例如,setseedrandom 就因为最后一个原因而属于并行受限。 + 如果函数或聚合会写入数据库、访问序列、修改事务状态(即使只是临时修改,例如 PL/pgSQL 函数建立 EXCEPTION 块来捕获错误),或者对设置作出持久更改,那么它们必须标记为 PARALLEL UNSAFE。类似地,如果函数访问临时表、客户端连接状态、游标、预备语句,或者系统无法在工作进程之间同步的各种后端本地状态,那么它必须标记为 PARALLEL RESTRICTED。例如,setseedrandom 就因为最后一个原因而属于并行受限。 diff --git a/zh/16/pgcrypto.sgml b/zh/16/pgcrypto.sgml index 0b84ec2a..e1a7a986 100644 --- a/zh/16/pgcrypto.sgml +++ b/zh/16/pgcrypto.sgml @@ -179,29 +179,6 @@ hmac(data bytea, key bytea, type text) returns bytea 13 原始 UNIX crypt - - sha256crypt - 无限制 - - 最多 32 - 80 - 改编自公开可用的参考实现 - Unix crypt using SHA-256 and SHA-512 - - - - - sha512crypt - 无限制 - - 最多 32 - 123 - 改编自公开可用的参考实现 - Unix crypt using SHA-256 and SHA-512 - - - -
@@ -254,17 +231,14 @@ gen_salt(type text [, iter_count integer ]) returns text
- type参数指定哈希算法。 - 接受的类型有:desxdesmd5、 - bfsha256cryptsha512crypt。 - 最后两种即 sha256cryptsha512crypt, - 是现代的、基于 SHA-2 的密码哈希。 + type参数指定 hash 算法。 + 接受的类型有:desxdesmd5bf iter_count参数允许用户为支持该参数的算法指定迭代次数。 - 次数越高,密码哈希所需时间越长,从而破解它所需时间也越长。 - 不过,如果次数过高,计算一个哈希可能需要数年时间 — 这显然不切实际。 + 次数越高,对密码进行 hash 所需的时间越长,从而破解它所需时间也越长。 + 不过,如果次数过高,计算一个 hash 可能需要数年时间 — 这显然不切实际。 若省略iter_count参数,则使用默认迭代次数。 允许的iter_count值取决于算法,如所示。 @@ -293,12 +267,6 @@ gen_salt(type text [, iter_count integer ]) returns text 4 31 - - sha256crypt, sha512crypt - 5000 - 1000 - 999999999 - @@ -308,31 +276,24 @@ gen_salt(type text [, iter_count integer ]) returns text - 为了选择合适的迭代次数,可以考虑原始 DES crypt 在当时硬件上的设计速度是每秒 4 次哈希。 - 低于每秒 4 次哈希可能会影响可用性,而高于每秒 100 次哈希则很可能过快。 + 为了选择合适的迭代次数,可以考虑原始 DES crypt 在当时硬件上的设计速度是每秒 4 次 hash。 + 低于每秒 4 次 hash 可能会影响可用性,而高于每秒 100 次 hash 则很可能过快。 - 概述了不同哈希算法之间的相对速度差异。 + 概述了不同 hash 算法之间的相对速度差异。 该表展示了在 8 字符密码上尝试所有字符组合所需的时间,假定密码只包含小写字母, 或者包含大小写字母和数字。在crypt-bf条目中, 斜杠后的数字是gen_saltiter_count参数值。 - - 对sha256cryptsha512crypt而言, - 默认的iter_count5000 对现代硬件来说被认为过低, - 但可以调高以生成更强的密码哈希。除此之外, - sha256cryptsha512crypt都被认为是安全的。 - - - 哈希算法速度 + Hash 算法速度 算法 - 每秒哈希次数 + 每秒 hash 次数 针对[a-z] 针对[A-Za-z0-9] 相对于md5 hash的耗时倍数 diff --git a/zh/16/pgstatstatements.sgml b/zh/16/pgstatstatements.sgml index f606e149..d2070419 100644 --- a/zh/16/pgstatstatements.sgml +++ b/zh/16/pgstatstatements.sgml @@ -326,40 +326,20 @@ - shared_blk_read_time double precision + blk_read_time double precision - 该语句读取共享块所花费的总时间,单位为毫秒 + 该语句读取数据文件块所花费的总时间,单位为毫秒 (如果启用了 ,否则为零) - shared_blk_write_time double precision + blk_write_time double precision - 该语句写入共享块所花费的总时间,单位为毫秒 - (如果启用了 ,否则为零) - - - - - - local_blk_read_time double precision - - - 该语句读取本地块所花费的总时间,单位为毫秒 - (如果启用了 ,否则为零) - - - - - - local_blk_write_time double precision - - - 该语句写入本地块所花费的总时间,单位为毫秒 + 该语句写入数据文件块所花费的总时间,单位为毫秒 (如果启用了 ,否则为零) @@ -411,15 +391,6 @@ - - - wal_buffers_full bigint - - - WAL 缓冲区变满的次数 - - - jit_functions bigint @@ -492,63 +463,10 @@ - - - jit_deform_count bigint - - - 该语句 JIT 编译的元组拆解函数总数 - - - - - - jit_deform_time double precision - - - 该语句对元组拆解函数进行 JIT 编译所花费的总时间,单位为毫秒 - - - - - parallel_workers_to_launch bigint - - - 计划启动的并行工作进程数 - - - - - parallel_workers_launched bigint - - - 实际启动的并行工作进程数 - - - - - stats_since timestamp with time zone - - - 开始为该语句收集统计信息的时间 - - - - - minmax_stats_since timestamp with time zone - - - 开始为该语句收集最小/最大统计信息的时间 - (字段 min_plan_time、 - max_plan_time、 - min_exec_time 和 - max_exec_time) - -
diff --git a/zh/16/plhandler.sgml b/zh/16/plhandler.sgml index 38562e46..4048d572 100644 --- a/zh/16/plhandler.sgml +++ b/zh/16/plhandler.sgml @@ -17,11 +17,11 @@ - 调用处理器与其他函数一样被调用:它会接收一个指向 FunctionCallInfoBaseData struct 的指针,其中包含参数值以及被调用函数的相关信息;同时它还应返回一个 Datum 结果(如果希望返回 SQL 空值结果,还可以设置 isnull 字段,也就是 FunctionCallInfoBaseData 结构体中的该字段)。调用处理器与普通被调函数之间的区别在于,flinfo->fn_oid 字段在 FunctionCallInfoBaseData 结构体中保存的是实际要调用函数的 OID,而不是调用处理器本身的 OID。调用处理器必须使用这个字段来判定要执行哪个函数。另外,传入的参数列表是按照目标函数而不是调用处理器的声明来设置的。 + 调用处理器与其他函数一样被调用:它会接收一个指向 FunctionCallInfoBaseData struct 的指针,其中包含参数值以及被调用函数的相关信息;同时它还应返回一个 Datum 结果(如果希望返回 SQL 空值结果,还需要设置 isnull 字段,也就是 FunctionCallInfoBaseData 结构体中的该字段)。调用处理器与普通被调函数之间的区别在于,flinfo->fn_oid 字段在 FunctionCallInfoBaseData 结构体中保存的是实际要调用函数的 OID,而不是调用处理器本身的 OID。调用处理器必须使用这个字段来判定要执行哪个函数。另外,传入的参数列表是按照目标函数而不是调用处理器的声明来设置的。 - 调用处理器必须从系统目录 pg_proc 中取出该函数的条目,并分析被调用函数的参数类型和返回类型。该函数的 AS 子句可在其 CREATE FUNCTION 命令对应的 prosrc 列里找到,也就是 pg_proc 行中的该列。这里通常是一段过程语言源文本,但理论上也可以是其他内容,例如某个文件的路径名,或者任何能详细告诉调用处理器该做什么的信息。 + 调用处理器必须从系统目录 pg_proc 中取出该函数的条目,并分析被调用函数的参数类型和返回类型。该函数的 CREATE FUNCTION 命令中的 AS 子句内容,保存在 pg_proc 对应行的 prosrc 列中。这里通常是一段过程语言源文本,但理论上也可以是其他内容,例如某个文件的路径名,或者任何能详细告诉调用处理器该做什么的信息。 @@ -46,7 +46,7 @@ 验证器函数通常应遵循 参数:如果它被关闭,就应跳过任何开销高昂或依赖上下文的检查。如果该语言允许在编译时执行代码,验证器还必须抑制会诱发此类执行的检查。特别是,pg_dump 会关闭这个参数,这样它就可以装载过程语言函数,而不必担心函数体对其他数据库对象的副作用或依赖关系。(正因为有这一要求,调用处理器不应假设验证器已经完整检查了函数。提供验证器的目的,并不是让调用处理器省略检查,而是在 CREATE FUNCTION 命令中存在明显错误时立即通知用户。)虽然究竟检查哪些内容主要由验证器函数自行决定,但要注意,核心 CREATE FUNCTION 代码只会执行附加到函数上的 SET 子句,前提是 check_function_bodies 打开。因此,当 check_function_bodies 关闭时,那些结果可能受 GUC 参数影响的检查肯定都应跳过,以避免在恢复转储时出现虚假的失败。 + linkend="guc-check-function-bodies"/> 参数:如果它被关闭,就应跳过任何开销高昂或依赖上下文的检查。如果该语言允许在编译时执行代码,验证器还必须抑制会诱发此类执行的检查。特别是,pg_dump 会关闭这个参数,这样它就可以装载过程语言函数,而不必担心副作用或函数体对其他数据库对象的依赖关系。(正因为有这一要求,调用处理器不应假设验证器已经完整检查了函数。提供验证器的目的,并不是让调用处理器省略检查,而是在 CREATE FUNCTION 命令中存在明显错误时立即通知用户。)虽然究竟检查哪些内容主要由验证器函数自行决定,但要注意,只有在 check_function_bodies 打开时,核心 CREATE FUNCTION 代码才会执行函数附带的 SET 子句。因此,当 check_function_bodies 关闭时,那些结果可能受 GUC 参数影响的检查肯定都应跳过,以避免在恢复转储时出现虚假的失败。 diff --git a/zh/16/plperl.sgml b/zh/16/plperl.sgml index 7fc5b272..a7da7851 100644 --- a/zh/16/plperl.sgml +++ b/zh/16/plperl.sgml @@ -13,7 +13,7 @@ - PL/Perl 是一种可载入的过程语言,它允许使用 + PL/Perl 是一种可加载的过程语言,它允许使用 Perl 编程语言编写 PostgreSQL 函数和过程。 @@ -32,8 +32,7 @@ - 如果把该语言安装到 template1 中,之后创建的所有 - 数据库都会自动安装该语言。 + 如果把某种语言安装到template1中,之后创建的所有数据库都会自动安装该语言。 @@ -57,9 +56,9 @@ CREATE FUNCTION funcname (argument-types) RETURNS return-type --- function attributes can go here +-- 函数属性可以写在这里 AS $$ - # PL/Perl function body goes here + # PL/Perl 函数体写在这里 $$ LANGUAGE plperl; @@ -78,7 +77,7 @@ $$ LANGUAGE plperl; DO $$ - # PL/Perl code + # PL/Perl 代码 $$ LANGUAGE plperl; @@ -136,15 +135,14 @@ $$ LANGUAGE plperl; 如果一个 SQL 空值空值in PL/Perl被传给一个函数,在 - Perl 中该参数值将呈现为undefined。上述函数定义对于 - 空输入的行为并不理想(实际上,它会把它们当作零)。我们可以在函数 + sortas="PL/Perl">在 PL/Perl 中被传给一个函数,在 + Perl 中该参数值将呈现为未定义。上述函数定义对于 + 空值输入的行为并不理想(实际上,它会把它们当作零)。我们可以在函数 定义中添加 STRICT,让 PostgreSQL 采取更合理的做法:如果传入空值, - 函数将根本不会被调用,而是自动返回空结果。另一种方式是在函数体中 + 函数将根本不会被调用,而是自动返回空值结果。另一种方式是在函数体中 检查未定义输入。例如,假设我们希望在 - perl_max 的两个参数中一个为空、另一个非空时, - 返回非空参数而不是空值: + perl_max 的两个参数中一个为空值、另一个非空值时,返回非空值参数而不是空值: CREATE FUNCTION perl_max (integer, integer) RETURNS integer AS $$ @@ -186,7 +184,7 @@ $$ LANGUAGE plperl; bool_plperl 扩展提供了合适的转换。要使用它, 请先安装该扩展: -CREATE EXTENSION bool_plperl; -- or bool_plperlu for PL/PerlU +CREATE EXTENSION bool_plperl; -- 对于 PL/PerlU,则使用 bool_plperlu 然后对接收或返回 bool 的 PL/Perl 函数使用 TRANSFORM 函数属性,例如: @@ -199,7 +197,7 @@ AS $$ $$ LANGUAGE plperl; 应用该转换后,Perl 会将 bool 参数视为 - 1 或空值,从而能正确表示真或假。如果函数结果类型为 + 1 或空字符串,从而能正确表示真或假。如果函数结果类型为 bool,则其真或假取决于 Perl 是否会将返回值求值为真。 对函数内部执行的 SPI 查询,其布尔查询参数和结果也会进行类似的转换 ()。 @@ -232,12 +230,12 @@ CREATE OR REPLACE FUNCTION concat_array_elements(text[]) RETURNS TEXT AS $$ my $result = ""; return undef if (!defined $arg); - # as an array reference + # 作为数组引用 for (@$arg) { $result .= $_; } - # also works as a string + # 也可以作为字符串使用 $result .= $arg; return $result; @@ -248,7 +246,8 @@ SELECT concat_array_elements(ARRAY['PL','/','Perl']); - 多维数组会以所有 Perl 程序员都熟悉的方式,表示为对低维数组引用的引用。 + 多维数组按 Perl 程序员熟悉的方式表示为指向较低维数组的引用, + 而这些数组的元素又是引用。 @@ -357,11 +356,11 @@ SELECT * FROM perl_set(); 如果希望在代码中使用 strict 编译指示,可以有几种 选择。对于临时的全局用法,可以 SET - plperl.use_strict 为 true。这会影响后续编译的 + plperl.use_strict 为真。这会影响后续编译的 PL/Perl 函数,但不会影响当前会话中已经编译的 函数。对于永久的全局用法,可以在 postgresql.conf 文件中将 - plperl.use_strict 设为 true。 + plperl.use_strict 设为真。 @@ -417,7 +416,7 @@ use strict; spi_exec_query(query [, limit]) spi_exec_query - in PL/Perl + 在 PL/Perl 中 @@ -503,7 +502,7 @@ SELECT * FROM test_munge(); spi_query(command) spi_query - in PL/Perl + 在 PL/Perl 中 @@ -511,7 +510,7 @@ SELECT * FROM test_munge(); spi_fetchrow(cursor) spi_fetchrow - in PL/Perl + 在 PL/Perl 中 @@ -519,7 +518,7 @@ SELECT * FROM test_munge(); spi_cursor_close(cursor) spi_cursor_close - in PL/Perl + 在 PL/Perl 中 @@ -539,7 +538,7 @@ CREATE OR REPLACE FUNCTION lotsa_md5 (INTEGER) RETURNS SETOF foo_type AS $$ my $file = '/usr/share/dict/words'; my $t = localtime; elog(NOTICE, "opening file $file at $t" ); - open my $fh, '<', $file # ooh, it's a file access! + open my $fh, '<', $file # 注意,这里访问了文件! or elog(ERROR, "cannot open $file for reading: $!"); my @words = <$fh>; close $fh; @@ -579,7 +578,7 @@ SELECT * from lotsa_md5(500); spi_prepare(command, argument types) spi_prepare - in PL/Perl + 在 PL/Perl 中 @@ -587,7 +586,7 @@ SELECT * from lotsa_md5(500); spi_query_prepared(plan, arguments) spi_query_prepared - in PL/Perl + 在 PL/Perl 中 @@ -595,7 +594,7 @@ SELECT * from lotsa_md5(500); spi_exec_prepared(plan [, attributes], arguments) spi_exec_prepared - in PL/Perl + 在 PL/Perl 中 @@ -603,7 +602,7 @@ SELECT * from lotsa_md5(500); spi_freeplan(plan) spi_freeplan - in PL/Perl + 在 PL/Perl 中 @@ -612,7 +611,7 @@ SELECT * from lotsa_md5(500); spi_preparespi_query_preparedspi_exec_preparedspi_freeplan - 提供相同的功能,但用于预处理查询。spi_prepare + 提供相同的功能,但用于预备查询。spi_prepare 接受一个带编号参数占位符($1、$2 等)的查询字符串,以及参数类型的 字符串列表: @@ -631,7 +630,7 @@ $plan = spi_prepare('SELECT * FROM test WHERE id > $1 AND name = $2', - 预处理查询的优点在于,一个准备好的计划可以用于多次查询执行。当计划 + 预备查询的优点在于,一个准备好的计划可以用于多次查询执行。当计划 不再需要时,可以用 spi_freeplan 将其释放: CREATE OR REPLACE FUNCTION init() RETURNS VOID AS $$ @@ -708,7 +707,7 @@ SELECT release_hosts_query(); spi_commit() spi_commit - in PL/Perl + 在 PL/Perl 中 @@ -716,7 +715,7 @@ SELECT release_hosts_query(); spi_rollback() spi_rollback - in PL/Perl + 在 PL/Perl 中 @@ -756,7 +755,7 @@ CALL transaction_test1(); - PL/Perl 中的工具函数 + PL/Perl 中的辅助函数 @@ -765,7 +764,7 @@ CALL transaction_test1(); elog(level, msg) elog - in PL/Perl + 在 PL/Perl 中 @@ -791,7 +790,7 @@ CALL transaction_test1(); quote_literal(string) quote_literal - in PL/Perl + 在 PL/Perl 中 @@ -812,7 +811,7 @@ CALL transaction_test1(); quote_nullable(string) quote_nullable - in PL/Perl + 在 PL/Perl 中 @@ -831,7 +830,7 @@ CALL transaction_test1(); quote_ident(string) quote_ident - in PL/Perl + 在 PL/Perl 中 @@ -850,7 +849,7 @@ CALL transaction_test1(); decode_bytea(string) decode_bytea - in PL/Perl + 在 PL/Perl 中 @@ -868,7 +867,7 @@ CALL transaction_test1(); encode_bytea(string) encode_bytea - in PL/Perl + 在 PL/Perl 中 @@ -885,7 +884,7 @@ CALL transaction_test1(); encode_array_literal(array) encode_array_literal - in PL/Perl + 在 PL/Perl 中 @@ -908,7 +907,7 @@ CALL transaction_test1(); encode_typed_literal(value, typename) encode_typed_literal - in PL/Perl + 在 PL/Perl 中 @@ -926,7 +925,7 @@ CALL transaction_test1(); encode_array_constructor(array) encode_array_constructor - in PL/Perl + 在 PL/Perl 中 @@ -947,7 +946,7 @@ CALL transaction_test1(); looks_like_number(string) looks_like_number - in PL/Perl + 在 PL/Perl 中 @@ -967,7 +966,7 @@ CALL transaction_test1(); is_array_ref(argument) is_array_ref - in PL/Perl + 在 PL/Perl 中 @@ -1025,9 +1024,9 @@ CREATE OR REPLACE FUNCTION myfuncs() RETURNS void AS $$ }; $$ LANGUAGE plperl; -SELECT myfuncs(); /* initializes the function */ +SELECT myfuncs(); /* 初始化函数 */ -/* Set up a function that uses the quote function */ +/* 创建一个使用加引号函数的函数 */ CREATE OR REPLACE FUNCTION use_quote(TEXT) RETURNS text AS $$ my $text_to_quote = shift; @@ -1042,11 +1041,9 @@ $$ LANGUAGE plperl; - 出于安全原因,PL/Perl 会为某个 SQL 角色调用的函数在该角色专用的独立 - Perl 解释器中执行。这可以防止一个用户意外或恶意地干扰另一个用户的 + 出于安全原因,PL/Perl 会在每个 SQL 角色各自独立的 Perl 解释器中执行该角色调用的函数。这可以防止一个用户意外或恶意地干扰另一个用户的 PL/Perl 函数行为。每个这样的解释器都有自己的 - %_SHARED 变量值和其他全局状态。因此,只有在两个 - PL/Perl 函数都由同一 SQL 角色执行时,它们才会共享 + %_SHARED 变量值和其他全局状态。因此,当且仅当两个 PL/Perl 函数都由同一 SQL 角色执行时,它们才会共享 %_SHARED 的值。在某些应用中,一个会话可能会在多个 SQL 角色下执行代码(通过 SECURITY DEFINER 函数、 使用 SET ROLE 等),这时可能需要显式采取措施, @@ -1059,29 +1056,29 @@ $$ LANGUAGE plperl; - 可信与不可信的 PL/Perl + 受信任与不受信任的 PL/Perl - trusted + 受信任的 PL/Perl 通常,PL/Perl 会被安装为一种名为 plperl 的 - 可信编程语言。在这种设置下,为了保持安全性,某些 Perl + 受信任的编程语言。在这种设置下,为了保持安全性,某些 Perl 操作会被禁用。一般来说,受限制的是那些与环境交互的操作,包括文件句柄 操作、requireuse (针对外部模块)。它无法像 C 函数那样访问数据库服务器进程的内部, - 也无法以服务器进程的权限获取操作系统级访问。因此,可以允许任何无权限 + 也无法以服务器进程的权限获取操作系统级访问。因此,可以允许任何无特权 的数据库用户使用这种语言。 - 可信 PL/Perl 依赖 Perl 的 Opcode 模块来维持安全性。 + 受信任的 PL/Perl 依赖 Perl 的 Opcode 模块来维持安全性。 Perl 的 文档 - 指出,该模块对于可信 PL/Perl 这一使用场景并不有效。若你的安全需求 + 指出,该模块对于受信任的 PL/Perl 这一使用场景并不有效。若你的安全需求 不能接受该警告中的不确定性,请考虑执行 REVOKE USAGE ON LANGUAGE plperl FROM PUBLIC @@ -1105,16 +1102,16 @@ $$ LANGUAGE plperl; 有时需要编写不受这些限制的 Perl 函数。例如,可能需要一个能发送邮件的 Perl 函数。为处理这类情况,也可以把 PL/Perl 安装成一种 - 不可信语言(通常称为 + 不受信任的语言(通常称为 PL/PerlUPL/PerlU)。 在这种情况下,完整的 Perl 语言都可用。安装该语言时,使用语言名 - plperlu 就会选择不可信的 PL/Perl 变体。 + plperlu 就会选择不受信任的 PL/Perl 变体。 PL/PerlU 函数的编写者必须注意,函数不能被 用于任何非预期用途,因为它能够执行以数据库管理员身份登录的用户所能 - 做的任何事情。请注意,数据库系统只允许数据库超级用户用不可信语言创建 + 做的任何事情。请注意,数据库系统只允许数据库超级用户用不受信任的语言创建 函数。 @@ -1249,7 +1246,7 @@ $$ LANGUAGE plperl; $_TD->{relname} - 触发该触发器的表名。该字段已废弃,并且可能会在未来版本中移除。 + 触发该触发器的表名。该字段已弃用,并且可能会在未来版本中移除。 请改用 $_TD->{table_name}。 @@ -1328,12 +1325,12 @@ CREATE TABLE test ( CREATE OR REPLACE FUNCTION valid_id() RETURNS trigger AS $$ if (($_TD->{new}{i} >= 100) || ($_TD->{new}{i} <= 0)) { - return "SKIP"; # skip INSERT/UPDATE command + return "SKIP"; # 跳过 INSERT/UPDATE 命令 } elsif ($_TD->{new}{v} ne "immortal") { $_TD->{new}{v} .= "(modified by trigger)"; - return "MODIFY"; # modify row and execute INSERT/UPDATE command + return "MODIFY"; # 修改行并执行 INSERT/UPDATE 命令 } else { - return; # execute INSERT/UPDATE command + return; # 执行 INSERT/UPDATE 命令 } $$ LANGUAGE plperl; @@ -1490,7 +1487,7 @@ DO 'elog(WARNING, join ", ", sort keys %INC)' LANGUAGE plperl; 也会发生。这是在 plperl.on_init 完成的任何初始化 之后进行的。执行这段代码时 SPI 函数不可用。 plperl.on_plperl_init 中的 Perl 代码是在对解释器 - 进行锁定之后执行的,因此只能执行可信操作。 + 进行锁定之后执行的,因此只能执行受信任的操作。 diff --git a/zh/16/plpgsql.sgml b/zh/16/plpgsql.sgml index 73d6dfb2..55fda406 100644 --- a/zh/16/plpgsql.sgml +++ b/zh/16/plpgsql.sgml @@ -144,7 +144,7 @@ CREATE FUNCTION somefunc(integer, text) RETURNS integer AS 'function body text' LANGUAGE plpgsql; - 就 CREATE FUNCTION 而言,函数体目前只是一个字符串字面量。编写函数体时,通常最好使用美元引用(见 ),而不是普通的单引号语法。如果不使用美元引用,函数体中的任何单引号或反斜线都必须通过双写进行转义。本章几乎所有示例的函数体都使用了美元引用。 + 就 CREATE FUNCTION 而言,函数体只是一个字符串字面量。编写函数体时,通常最好使用美元引用(见 ),而不是普通的单引号语法。如果不使用美元引用,函数体中的任何单引号或反斜线都必须通过双写进行转义。本章几乎所有示例的函数体都使用了美元引用。 @@ -340,7 +340,7 @@ $$ LANGUAGE plpgsql; - 当 PL/pgSQL 函数声明了输出参数时,输出参数也会像普通输入参数一样获得 $n 名称和可选别名。输出参数本质上是一个初始值为 NULL 的变量,应在函数执行期间给它赋值。该参数的最终值就是返回值。例如,sales-tax 的示例也可以这样写: + 当 PL/pgSQL 函数声明了输出参数时,输出参数也会像普通输入参数一样获得 $n 名称和可选别名。输出参数本质上是一个初始值为 NULL 的变量,应在函数执行期间给它赋值。该参数的最终值就是返回值。例如,销售税的示例也可以这样写: CREATE FUNCTION sales_tax(subtotal real, OUT tax real) AS $$ @@ -465,7 +465,7 @@ $$ LANGUAGE plpgsql; SELECT add_three_values(1, 2, 4.7); - 可以正常工作,并会自动把整数输入提升为 numeric。如果使用 anyelement,则必须手工把这三个输入转换成同一类型。 + 可以正常工作,并会自动把整数输入提升为 numeric。如果使用 anyelement,则必须手工把这三个输入转换成同一类型。
@@ -499,26 +499,15 @@ DECLARE 复制类型 -name table.column%TYPE -name variable%TYPE +variable%TYPE - %TYPE 提供表列或先前已声明的 PL/pgSQL 变量的数据类型。你可以用它来声明用于保存数据库值的变量。例如,假设 users 表中有一个名为 user_id 的列。要声明一个与 users.user_id 具有相同数据类型的变量,可以这样写: - + %TYPE提供变量或表列的数据类型。可以用它声明将保存数据库值的变量。例如,假设有一个名为user_id的列,位于users表中。要声明一个数据类型与users.user_id相同的变量,可以写: user_id users.user_id%TYPE; - - 也可以在 %TYPE 后写数组修饰,从而创建保存被引用类型数组的变量: - -user_ids users.user_id%TYPE[]; -user_ids users.user_id%TYPE ARRAY[4]; -- 等价于上面一行 - - 与声明数组表列时一样,写多个方括号还是写具体数组维度都无关紧要:PostgreSQL 会把同一元素类型的所有数组都视为同一种类型,而不考虑维度数。(见 。) - - 使用 %TYPE 的好处是,你不必知道所引用结构的实际数据类型;更重要的是,如果被引用项的数据类型将来发生变化(例如把 user_id 的类型从 integer 改成 real),你可能就不需要修改函数定义。 @@ -546,10 +535,6 @@ user_ids users.user_id%TYPE ARRAY[4]; -- 等价于上面一行 行变量既可以通过 table_name%ROWTYPE 记法声明为与现有表或视图的行具有相同类型,也可以通过给出某个复合类型的名称来声明。(由于每个表都有一个同名的关联复合类型,所以在 PostgreSQL 中实际上写不写 %ROWTYPE 并无区别;不过带 %ROWTYPE 的形式可移植性更好。) - - 与 %TYPE 一样,%ROWTYPE 后也可以跟数组修饰,用于声明保存被引用复合类型数组的变量。 - - 函数参数也可以是复合类型(完整的表行)。在这种情况下,相应的标识符 $n 就是一个行变量,并且可以从中选取字段,例如 $1.user_id @@ -594,12 +579,12 @@ SELECT merge_fields(t.*) FROM table1 t WHERE ... ; <application>PL/pgSQL</application>变量的排序规则 - collation - in PL/pgSQL + 排序规则 + 在 PL/pgSQL 中 - 当 PL/pgSQL 函数具有一个或多个可排序数据类型参数时,每次函数调用都会根据分配给实际参数的排序规则确定出一个排序规则,如 所述。如果该排序规则能成功确定出来(即参数之间的隐式排序规则没有冲突),那么所有可排序参数都会被视为隐式带有该排序规则。这会影响函数中那些受排序规则影响的操作。例如,考虑 + 当 PL/pgSQL 函数具有一个或多个支持排序规则的数据类型参数时,每次函数调用都会根据分配给实际参数的排序规则确定出一个排序规则,如 所述。如果该排序规则能成功确定出来(即参数之间的隐式排序规则没有冲突),那么所有支持排序规则的参数都会被视为隐式带有该排序规则。这会影响函数中那些受排序规则影响的操作。例如,考虑 CREATE FUNCTION less_than(a text, b text) RETURNS boolean AS $$ @@ -616,7 +601,7 @@ SELECT less_than(text_field_1, text_field_2 COLLATE "C") FROM table1; - 此外,确定出的排序规则也会被视为任何可排序数据类型局部变量的排序规则。因此,即使把这个函数写成下面这样,其行为也不会有任何不同: + 此外,确定出的排序规则也会被视为任何支持排序规则的数据类型局部变量的排序规则。因此,即使把这个函数写成下面这样,其行为也不会有任何不同: CREATE FUNCTION less_than(a text, b text) RETURNS boolean AS $$ @@ -631,11 +616,11 @@ $$ LANGUAGE plpgsql; - 如果函数没有可排序数据类型的参数,或者无法为它们确定共同排序规则,那么参数和局部变量将使用其数据类型的默认排序规则(通常是数据库默认排序规则,但对于域类型变量也可能不同)。 + 如果函数没有支持排序规则的数据类型的参数,或者无法为它们确定共同排序规则,那么参数和局部变量将使用其数据类型的默认排序规则(通常是数据库默认排序规则,但对于域类型变量也可能不同)。 - 通过在可排序数据类型局部变量的声明中加入 COLLATE 选项,可以为其指定不同的排序规则,例如 + 通过在支持排序规则的数据类型局部变量的声明中加入 COLLATE 选项,可以为其指定不同的排序规则,例如 DECLARE @@ -666,7 +651,7 @@ $$ LANGUAGE plpgsql; 表达式 - PL/pgSQL语句中使用的所有表达式都会由服务器的主SQL执行器处理。例如,当你写下这样一条PL/pgSQL语句时: + PL/pgSQL 语句中使用的所有表达式都会由服务器的主 SQL 执行器处理。例如,当写下这样一条 PL/pgSQL 语句时: IF expression THEN ... @@ -674,7 +659,7 @@ IF expression THEN ... SELECT expression - 来计算该表达式。如中详细讨论的那样,在构造该SELECT命令时,PL/pgSQL变量名的每一次出现都会被替换成查询参数。这使得该SELECT的查询计划只需准备一次,然后就能在后续以不同变量值求值时重用。因此,表达式第一次被使用时,实际发生的事情本质上相当于执行了一条PREPARE命令。例如,如果已经声明了两个整数变量xy,并写下 + 来计算该表达式。如 中详细讨论的那样,在构造该 SELECT 命令时,PL/pgSQL 变量名的每一次出现都会被替换成查询参数。这使得该 SELECT 的查询计划只需准备一次,然后就能在后续以不同变量值求值时重用。因此,表达式第一次被使用时,实际发生的事情本质上相当于执行了一条 PREPARE 命令。例如,如果已经声明了两个整数变量 xy,并写下 IF x < y THEN ... @@ -682,7 +667,7 @@ IF x < y THEN ... PREPARE statement_name(integer, integer) AS SELECT $1 < $2; - 然后,在每次执行IF语句时,这条预备语句都会以当前PL/pgSQL变量值作为参数值被EXECUTE。通常这些细节对PL/pgSQL用户并不重要,但在诊断问题时了解它们会很有帮助。更多信息见。 + 然后,在每次执行 IF 语句时,这条预备语句都会以当前 PL/pgSQL 变量值作为参数值由 EXECUTE 执行。通常这些细节对 PL/pgSQL 用户并不重要,但在诊断问题时了解它们会很有帮助。更多信息见 @@ -699,7 +684,7 @@ PREPARE statement_name(integer, integer) AS SELECT $1 基本语句 - 在这一节和接下来的小节中,我们会描述PL/pgSQL能明确理解的所有语句类型。任何不被识别为这些语句类型之一的被假定为是一个 SQL 命令,并且会被发送给主数据库引擎执行,具体如中所述。 + 在这一节和接下来的小节中,我们会描述 PL/pgSQL 能明确理解的所有语句类型。任何不被识别为这些语句类型之一的语句都被视为 SQL 命令,并会被发送给主数据库引擎执行,具体如 中所述。 @@ -715,8 +700,7 @@ PREPARE statement_name(integer, integer) AS SELECT $1 SELECT命令被发送到主数据库引擎的方式计算。 该表达式必须得到一个单一值(如果该变量是一个行或记录变量, 它可能是一个行值)。该目标变量可以是一个简单变量( - 可以选择用一个块名限定)、一个行或记录变量的域或是一个简单 - 变量或域的数组的元素或者数组的切片。 + 可以选择用一个块名限定)、行或记录目标的字段,或者数组目标的元素或切片。 等号(=)可以被用来代替 PL/SQL-兼容的 := @@ -757,8 +741,8 @@ complex_array[n].realpart = 12.3; - 如果命令返回行(例如 SELECT,或者带 RETURNINGINSERT/UPDATE/DELETE/MERGE),有两种方式处理。 - 当命令最多返回一行,或者你只关心第一行的输出时,像往常一样编写命令,但要添加一个INTO子句来捕获输出,如中所述。为了处理所有的输出行,把命令写成FOR循环的数据源,如 中所述。 + 如果命令返回行(例如 SELECT,或者带 RETURNINGINSERT/UPDATE/DELETE),有两种方式处理。 + 当命令最多返回一行,或者只关心第一行的输出时,可照常编写该命令,但要添加一个 INTO 子句来捕获输出,如 中所述。要处理所有输出行,可将该命令写成 FOR 循环的数据源,如 中所述。 @@ -766,29 +750,29 @@ complex_array[n].realpart = 12.3; - PL/pgSQL变量值可以自动插入到可优化的SQL命令中,这些命令包括SELECTINSERTUPDATEDELETEMERGE以及某些包含其中之一的实用程序命令,比如EXPLAINCREATE TABLE ... AS SELECT。在这些命令中,命令文本中出现的任何PL/pgSQL变量名都会被查询参数替换,然后变量的当前值会在运行时作为参数值提供。这与前面描述的表达式处理完全相同;详情请参见。 + PL/pgSQL 变量值可以自动插入可优化的 SQL 命令中,这些命令包括 SELECTINSERTUPDATEDELETEMERGE 以及某些包含其中之一的工具命令,比如 EXPLAINCREATE TABLE ... AS SELECT。在这些命令中,命令文本中出现的任何 PL/pgSQL 变量名都会被查询参数替换,然后变量的当前值会在运行时作为参数值提供。这与前面描述的表达式处理完全相同;详情请参见 - 当以这种方式执行一个可优化的 SQL 命令时,如中讨论的,PL/pgSQL会为该命令缓存并重用执行计划。 + 当以这种方式执行一个可优化的 SQL 命令时,如中讨论的,PL/pgSQL可能会为该命令缓存并重用执行计划。 - 不可优化的SQL命令(也称为实用命令)不能够接受查询参数。 所以自动替换PL/pgSQL的变量在这类命令中不起作用。 要在从PL/pgSQL执行的实用程序命令中包含非常量文本,你必须将实用程序命令构建为一个字符串,然后EXECUTE它,如中所讨论的。 + 不可优化的 SQL 命令(也称为工具命令)不能接受查询参数。因此,自动替换 PL/pgSQL 变量在这类命令中不起作用。要在从 PL/pgSQL 执行的工具命令中包含非常量文本,必须将工具命令构建为一个字符串,然后用 EXECUTE 执行它,如 中所讨论的。 - EXECUTE也必须使用,如果你想以某种其他方式修改命令,而不是提供数据值,例如改变表名。 + 如果想通过其他方式修改命令,而不只是提供数据值,例如改变表名,也必须使用 EXECUTE - 有时候计算一个表达式或SELECT查询但抛弃其结果是有用的,例如调用一个有副作用但是没有有用的结果值的函数。在PL/pgSQL中要这样做,可使用PERFORM语句: + 有时需要计算一个表达式或 SELECT 查询但丢弃其结果,例如调用一个有副作用但没有有用结果值的函数。要在 PL/pgSQL 中这样做,可使用 PERFORM 语句: PERFORM query; - 这会执行query并且丢弃掉结果。以写一个SQL SELECT命令相同的方式写该query,并且将初始的关键词SELECT替换为PERFORM。对于WITH查询,使用PERFORM并且接着把该查询放在圆括号中(在这种情况中,该查询只能返回一行)。PL/pgSQL变量将被替换到该查询中,正如上面描述的查询,并且计划被以相同的方式被缓存。还有,如果该查询产生至少一行,特殊变量FOUND会被设置为真,而如果它不产生行则设置为假(见)。 + 这会执行 query 并丢弃结果。query 的写法与 SQL SELECT 命令相同,只需把开头的关键词 SELECT 替换为 PERFORM。对于 WITH 查询,使用 PERFORM 并将该查询放在圆括号中(在这种情况下,该查询只能返回一行)。PL/pgSQL 变量会像上文所述那样替换到查询中,计划也会以相同方式缓存。此外,如果该查询产生至少一行,特殊变量 FOUND 会被设置为真;如果不产生行,则设置为假(见 )。 @@ -812,12 +796,12 @@ PERFORM create_mv('cs_session_page_requests_mv', my_query); SELECT INTO - in PL/pgSQL + 在 PL/pgSQL 中 RETURNING INTO - in PL/pgSQL + 在 PL/pgSQL 中 @@ -828,10 +812,9 @@ SELECT select_expressions INTO STRICTexpressions
INTO STRICT target; UPDATE ... RETURNING expressions INTO STRICT target; DELETE ... RETURNING expressions INTO STRICT target; -MERGE ... RETURNING expressions INTO STRICT target; - 其中target可以是记录变量、行变量,或者由简单变量和记录/行字段组成的逗号分隔列表。PL/pgSQL变量会像前文所述那样替换进命令的其余部分(也就是除了INTO子句之外的所有部分),并且计划也会以同样的方式缓存。这适用于SELECT、带有RETURNINGINSERT/UPDATE/DELETE/MERGE,以及某些返回行集的工具命令,例如EXPLAIN。除了INTO子句之外,该 SQL 命令的写法与在PL/pgSQL之外完全相同。 + 其中target可以是记录变量、行变量,或者由简单变量和记录/行字段组成的逗号分隔列表。PL/pgSQL变量会像前文所述那样替换进命令的其余部分(也就是除了INTO子句之外的所有部分),并且计划也会以同样的方式缓存。这适用于SELECT、带有RETURNINGINSERT/UPDATE/DELETE,以及某些返回行集的工具命令,例如EXPLAIN。除了INTO子句之外,该 SQL 命令的写法与在PL/pgSQL之外完全相同。 @@ -842,7 +825,7 @@ MERGE ... RETURNING expressions INTO STRICT - 如果一个行变量或一个变量列表被用作目标,该命令的结果列必须完全匹配该结果的结构,包括数量和数据类型,否则会发生一个运行时错误。当一个记录变量是目标时,它会自动地把自身配置成命令的结果列组成的行类型。 + 如果一个行变量或一个变量列表被用作目标,该命令的结果列必须完全匹配该目标的结构,包括数量和数据类型,否则会发生一个运行时错误。当一个记录变量是目标时,它会自动地把自身配置成命令的结果列组成的行类型。 @@ -850,7 +833,7 @@ MERGE ... RETURNING expressions INTO STRICT - 如果STRICT没有在INTO子句中被指定,那么target将被设置为该命令返回的第一个行,或者在该命令不返回行时设置为空(注意除非使用了ORDER BY,否则第一行的界定并不清楚)。第一行之后的任何结果行都会被抛弃。你可以检查特殊的FOUND变量(见)来确定是否返回了一行: + 如果STRICT没有在INTO子句中被指定,那么target将被设置为该命令返回的第一个行,或者在该命令不返回行时设置为空值(注意除非使用了ORDER BY,否则第一行的界定并不清楚)。第一行之后的任何结果行都会被抛弃。你可以检查特殊的FOUND变量(见)来确定是否返回了一行: SELECT * INTO myrec FROM emp WHERE empname = myname; @@ -875,11 +858,11 @@ END; - 对于带有RETURNINGINSERT/UPDATE/DELETE/MERGE,即使没有指定STRICTPL/pgSQL也会针对多于一个返回行的情况报告一个错误。这是因为没有类似于ORDER BY的选项可以用来决定应该返回哪个被影响的行。 + 对于带有RETURNINGINSERT/UPDATE/DELETE,即使没有指定STRICTPL/pgSQL也会针对多于一个返回行的情况报告一个错误。这是因为没有类似于ORDER BY的选项可以用来决定应该返回哪个被影响的行。 - 如果为函数启用了print_strict_params,那么当由于不满足STRICT要求而抛出错误时,错误消息的DETAIL部分将包含传给该命令的参数信息。你可以通过设置plpgsql.print_strict_params来修改所有函数的print_strict_params设置,不过只有此后重新编译的函数才会受影响。也可以通过编译器选项按函数启用它,例如: + 如果为函数启用了print_strict_params,那么当由于不满足STRICT要求而抛出错误时,错误消息的DETAIL部分将包含传给该命令的参数信息。你可以通过设置plpgsql.print_strict_params来修改所有函数的print_strict_params设置,不过该设置只会影响此后编译的函数。也可以通过编译器选项按函数启用它,例如: CREATE FUNCTION get_userid(username text) RETURNS int AS $$ @@ -915,33 +898,31 @@ CONTEXT: PL/pgSQL function get_userid(text) line 6 at SQL statement 执行动态命令 - 很多时候你将想要在PL/pgSQL函数中产生动态命令,也就是每次执行中会涉及到不同表或不同数据类型的命令。PL/pgSQL通常对于命令所做的缓存计划尝试(如中讨论)在这种情境下无法工作。要处理这一类问题,需要提供EXECUTE语句: + 很多时候你将想要在PL/pgSQL函数中产生动态命令,也就是每次执行中会涉及到不同表或不同数据类型的命令。PL/pgSQL通常对于命令所做的缓存计划尝试(如中讨论)在这种情境下无法工作。要处理这一类问题,提供了EXECUTE语句: EXECUTE command-string INTO STRICT target USING expression , ... ; - 其中command-string是一个能得到一个包含要被执行命令字符串(类型text)的表达式。可选的target是一个记录变量、一个行变量或者一个逗号分隔的简单变量以及记录/行域的列表,该命令的结果将存储在其中。可选的USING表达式提供要被插入到该命令中的值。 + 其中command-string是一个能得到一个包含要被执行命令字符串(类型text)的表达式。可选的target是一个记录变量、一个行变量或者一个逗号分隔的简单变量以及记录/行字段的列表,该命令的结果将存储在其中。可选的USING表达式提供要被插入到该命令中的值。 在计算得到的命令字符串中,不会做PL/pgSQL变量的替换。任何所需的变量值必须在命令字符串被构造时被插入其中,或者你可以使用下面描述的参数。 - - 还有,对于通过EXECUTE执行的命令不会有计划被缓存。该命令反而在每次运行时都会被做计划。因此,该命令字符串可以在执行不同表和列上动作的函数中被动态创建。 - + 此外,通过 EXECUTE 执行的命令不会缓存计划,而是在每次运行该语句时重新规划。因此,可以在函数中动态构造命令字符串,对不同的表和列执行操作。 - INTO子句指定一个返回行的 SQL 命令的结果应该被赋值到哪里。如果提供了一个行或变量列表,它必须完全匹配查询命令结果的结构(当一个记录变量被提供时,它会自动把它自己配置为匹配结果结构)。如果返回多个行,只有第一个行会被赋值给INTO变量。如果没有返回行,NULL 会被赋值给INTO变量。如果没有指定INTO变量,该查询结果会被抛弃。 + INTO子句指定一个返回行的 SQL 命令的结果应该被赋值到哪里。如果提供了一个行变量或变量列表,它必须完全匹配查询命令结果的结构(当一个记录变量被提供时,它会自动把它自己配置为匹配结果结构)。如果返回多个行,只有第一个行会被赋值给INTO变量。如果没有返回行,NULL 会被赋值给INTO变量。如果没有指定INTO子句,该查询结果会被抛弃。 - 如果给出了STRICT选项,除非该查询刚好产生一行,否则将会报告一个错误。 + 如果给出了STRICT选项,除非该命令刚好产生一行,否则将会报告一个错误。 - 命令字符串可以使用参数值,它们在命令中用$1$2等引用。这些符号引用在USING子句中提供的值。这种方法常常更适合于把数据值作为文本插入到命令字符串中:它避免了将该值转换为文本以及转换回来的运行时负荷,并且它更不容易被 SQL 注入攻击,因为不需要引用或转义。一个示例是: + 命令字符串可以使用参数值,它们在命令中用$1$2等引用。这些符号引用在USING子句中提供的值。这种方法通常比把数据值作为文本插入命令字符串更可取:它避免了将该值转换为文本以及转换回来的运行时负荷,并且它更不容易被 SQL 注入攻击,因为不需要引用或转义。一个示例是: EXECUTE 'SELECT count(*) FROM mytable WHERE inserted_by = $1 AND inserted <= $2' INTO c @@ -959,25 +940,25 @@ EXECUTE 'SELECT count(*) FROM ' USING checked_user, checked_date; 一种更干净的方法是使用format()的 - %I规范,插入自带引号的表名或者列名: + %I 格式说明符,插入表名或列名并自动为其加上引号: EXECUTE format('SELECT count(*) FROM %I ' 'WHERE inserted_by = $1 AND inserted <= $2', tabname) INTO c USING checked_user, checked_date; - (此示例依赖于隐式连接由换行符分隔的字符串文字的 SQL 规则) + (此示例依赖于隐式连接由换行符分隔的字符串字面量的 SQL 规则) 参数符号的另一个限制是它们仅适用于可优化的SQL命令 (SELECT, INSERT, UPDATE, DELETE, MERGE以及包含其中一个的某些命令)。 - 在其他语句类型(通称为实用程序语句)中,即使它们只是数据值,您也必须以文本方式插入值。 + 在其他语句类型(通称为工具语句)中,即使它们只是数据值,你也必须以文本方式插入值。 - 在上面第一个示例中,带有一个简单的常量命令字符串和一些USING参数的EXECUTE命令在功能上等效于直接用PL/pgSQL写的命令,并且允许自动发生PL/pgSQL变量替换。重要的不同之处在于,EXECUTE会在每一次执行时根据当前的参数值重新计划该命令,而PL/pgSQL则是创建一个通用计划并且将其缓存以便重用。在最佳计划强依赖于参数值的情况中,使用EXECUTE来明确地保证不会选择一个通用计划是很有帮助的。 + 在上面第一个示例中,带有一个简单的常量命令字符串和一些USING参数的EXECUTE命令在功能上等效于直接用PL/pgSQL写的命令,并且允许自动发生PL/pgSQL变量替换。重要的不同之处在于,EXECUTE会在每一次执行时根据当前的参数值重新计划该命令,而PL/pgSQL则可能创建一个通用计划并且将其缓存以便重用。在最佳计划强依赖于参数值的情况中,使用EXECUTE来明确地保证不会选择一个通用计划是很有帮助的。 @@ -985,10 +966,7 @@ EXECUTE format('SELECT count(*) FROM %I ' - - - PL/pgSQL中的EXECUTE语句与EXECUTE PostgreSQL服务器支持的 SQL 语句无关。服务器的EXECUTE语句不能直接在PL/pgSQL函数中使用(并且也没有必要)。 - + PL/pgSQLEXECUTE 语句与 PostgreSQL 服务器支持的 SQL EXECUTE 语句无关。服务器的 EXECUTE 语句不能直接用于 PL/pgSQL 函数中(也没有这个必要)。 @@ -1052,19 +1030,19 @@ EXECUTE 'UPDATE tbl SET ' || ' WHERE key = ' || quote_nullable(keyvalue); - 如果正在处理的参数值可能为空,那么通常应该用quote_nullable来代替quote_literal。 + 如果正在处理的参数值可能为空值,那么通常应该用quote_nullable来代替quote_literal - 通常,必须小心地确保查询中的空值不会递送意料之外的结果。例如如果keyvalue为空,下面的WHERE子句 + 通常,必须小心地确保查询中的空值不会产生意料之外的结果。例如如果keyvalue为空值,下面的WHERE子句 'WHERE key = ' || quote_nullable(keyvalue) - 永远不会成功,因为在=操作符中使用空操作数得到的结果总是为空。如果想让空和一个普通键值一样工作,你应该将上面的命令重写成 + 永远不会成功,因为在=操作符中使用空值操作数得到的结果总是空值。如果想让空值像普通键值一样工作,你应该将上面的命令重写成 'WHERE key IS NOT DISTINCT FROM ' || quote_nullable(keyvalue) - (目前,IS NOT DISTINCT FROM的处理效率不如=,因此只有在非常必要时才这样做。关于空和IS DISTINCT的详细信息请见)。 + (目前,IS NOT DISTINCT FROM的处理效率不如=,因此只有在非常必要时才这样做。关于空值和IS DISTINCT的详细信息请见)。 @@ -1077,7 +1055,7 @@ EXECUTE 'UPDATE tbl SET ' || '$$ WHERE key = ' || quote_literal(keyvalue); - 因为如果newvalue的内容碰巧含有$$,那么这段代码就会出问题。同样的缺点可能适用于你选择的任何其他美元符号引用定界符。因此,要想安全地引用事先不知道的文本,必须恰当地使用quote_literalquote_nullablequote_ident。 + 因为如果newvalue的内容碰巧含有$$,那么这段代码就会出问题。同样的问题也适用于你选择的任何其他美元符号引用定界符。因此,要想安全地引用事先不知道的文本,必须恰当地使用quote_literalquote_nullablequote_ident @@ -1116,7 +1094,7 @@ EXECUTE format('UPDATE tbl SET %I = $1 WHERE key = $2', colname) GET CURRENT DIAGNOSTICS variable { = | := } item , ... ; - 这条命令允许检索系统状态指示符。CURRENT是一个噪声词(另见中的GET STACKED DIAGNOSTICS)。每个item是一个关键字, 它标识一个要被赋予给指定变量的状态值(变量应具有正确的数据类型来接收状态值)。中展示了当前可用的状态项。冒号等号(:=)可以被用来取代 SQL 标准的=符号。例如: + 这条命令允许检索系统状态指示符。CURRENT是一个噪声词(另见中的GET STACKED DIAGNOSTICS)。每个item是一个关键字, 它标识一个要被赋予给指定variable的状态值(变量应具有正确的数据类型来接收状态值)。中展示了当前可用的状态项。冒号等号(:=)可以被用来取代 SQL 标准的=符号。例如: GET DIAGNOSTICS integer_var = ROW_COUNT; @@ -1161,13 +1139,13 @@ GET DIAGNOSTICS integer_var = ROW_COUNT; 第二种确定命令效果的方法是检查名为FOUND的特殊变量,类型为boolean。 - 在每次PL/pgSQL函数调用中,FOUND都是以 false 开头。 + 在每次PL/pgSQL函数调用中,FOUND的初始值都是 false。 它由以下类型的语句设置: - SELECT INTO语句在分配行时将FOUND设置为true, + SELECT INTO语句在为目标赋上一行值时将FOUND设置为true, 如果没有返回行则设置为false。 @@ -1199,7 +1177,7 @@ GET DIAGNOSTICS integer_var = ROW_COUNT; FORFOREACH语句在迭代一次或多次时将 FOUND设置为true,否则设置为false。 - 当循环退出时,FOUND被设置为这种方式; + 当循环退出时,FOUND会按上述方式设置; 在循环执行过程中,FOUND不会被循环语句修改, 尽管它可能会被循环体内的其他语句执行修改。 @@ -1295,7 +1273,7 @@ RETURN expression; - 如果函数返回的是标量类型,表达式结果会自动转换为函数的返回类型。但如果要返回一个组合(行)值,你必须写出一个恰好生成所需列集合的表达式。这可能需要显式类型转换。 + 如果函数返回的是标量类型,表达式结果会按照赋值部分的说明自动转换为函数的返回类型。但如果要返回一个复合(行)值,你必须写出一个恰好生成所需列集合的表达式。这可能需要显式类型转换。 @@ -1307,7 +1285,7 @@ RETURN expression; - 一个函数的返回值不能是未定义。如果控制到达了函数最顶层的块而没有碰到一个RETURN语句,那么会发生一个运行时错误。不过,这个限制不适用于带输出参数的函数以及返回void的函数。在这些情况中,如果顶层的块结束,将自动执行一个RETURN语句。 + 一个函数的返回值不能是未定义。如果控制到达了函数最顶层块的末尾而没有碰到一个RETURN语句,那么会发生一个运行时错误。不过,这个限制不适用于带输出参数的函数以及返回void的函数。在这些情况中,如果顶层的块结束,将自动执行一个RETURN语句。 @@ -1331,12 +1309,12 @@ RETURN (1, 2, 'three'::text); -- 必须把列类型转换成正确的类型 RETURN NEXT - in PL/pgSQL + 在 PL/pgSQL 中 RETURN QUERY - in PL/pgSQL + 在 PL/pgSQL 中 @@ -1346,7 +1324,7 @@ RETURN QUERY EXECUTE command-string < - 当 PL/pgSQL 函数被声明为返回 SETOF sometype 时,返回过程会略有不同。在这种情况下,要返回的各个项通过一系列 RETURN NEXTRETURN QUERY 命令指定,最后再用一个不带参数的 RETURN 命令表明函数已经执行完毕。RETURN NEXT 可用于标量和组合数据类型;对于组合结果类型,会返回完整的结果RETURN QUERY 会把查询执行结果追加到函数的结果集中。在同一个集合返回函数中,RETURN NEXTRETURN QUERY 可以自由混用,此时它们的结果会被串接起来。 + 当 PL/pgSQL 函数被声明为返回 SETOF sometype 时,返回过程会略有不同。在这种情况下,要返回的各个项通过一系列 RETURN NEXTRETURN QUERY 命令指定,最后再用一个不带参数的 RETURN 命令表明函数已经执行完毕。RETURN NEXT 可用于标量和复合数据类型;对于复合结果类型,会返回完整的结果RETURN QUERY 会把查询执行结果追加到函数的结果集中。在同一个集合返回函数中,RETURN NEXTRETURN QUERY 可以自由混用,此时它们的结果会被串接起来。 @@ -1511,7 +1489,7 @@ END IF; - IF-THEN语句是IF的最简单形式。 如果条件为真,在THENEND IF之间的语句将被执行。否则,将忽略它们。 + IF-THEN语句是IF的最简单形式。 如果条件为真,在THENEND IF之间的语句将被执行。否则,将忽略它们。 @@ -1594,7 +1572,7 @@ ELSIF number > 0 THEN ELSIF number < 0 THEN result := 'negative'; ELSE - -- 嗯,唯一的其他可能性是数字为空 + -- 嗯,唯一的其他可能性是 number 为 null result := 'NULL'; END IF; @@ -1690,9 +1668,7 @@ END CASE; - - 这种形式的CASEIF-THEN-ELSIF完全等价,唯一的区别是:如果省略了ELSE子句,CASE会报错,而不是简单地什么也不做。 - + 这种形式的CASEIF-THEN-ELSIF完全等价,唯一的区别是:如果执行到被省略的ELSE子句,就会报错,而不是简单地什么也不做。 @@ -1702,12 +1678,12 @@ END CASE; 简单循环 - loop + 循环 在 PL/pgSQL 中 - 使用LOOPEXITCONTINUEWHILEFORFOREACH语句,你可以安排PL/pgSQL重复一系列命令。 + 使用LOOPEXITCONTINUEWHILEFORFOREACH语句,你可以安排PL/pgSQL函数重复一系列命令。 @@ -1862,22 +1838,22 @@ END LOOP label ; - 这种形式的FOR会创建一个在一个整数范围上迭代的循环。变量name会自动定义为类型integer并且只在循环内存在(任何该变量名的现有定义在此循环内都将被忽略)。给出范围上下界的两个表达式在进入循环的时候计算一次。如果没有指定BY子句,迭代步长为 1,否则步长是BY中指定的值,该值也只在循环进入时计算一次。如果指定了REVERSE,那么在每次迭代后步长值会被减除而不是增加。 + 这种形式的FOR会创建一个在一个整数范围上迭代的循环。变量name会自动定义为类型integer并且只在循环内存在(任何该变量名的现有定义在此循环内都将被忽略)。给出范围上下界的两个表达式在进入循环的时候计算一次。如果没有指定BY子句,迭代步长为 1,否则步长是BY中指定的值,该值也只在循环进入时计算一次。如果指定了REVERSE,那么在每次迭代后会减去步长,而不是加上步长。 整数FOR循环的一些示例: FOR i IN 1..10 LOOP - -- 我在循环中将取值 1,2,3,4,5,6,7,8,9,10 + -- i 在循环中将取值 1,2,3,4,5,6,7,8,9,10 END LOOP; FOR i IN REVERSE 10..1 LOOP - -- 我在循环中将取值 10,9,8,7,6,5,4,3,2,1 + -- i 在循环中将取值 10,9,8,7,6,5,4,3,2,1 END LOOP; FOR i IN REVERSE 10..1 BY 2 LOOP - -- 我在循环中将取值 10,8,6,4,2 + -- i 在循环中将取值 10,8,6,4,2 END LOOP; @@ -1941,7 +1917,7 @@ $$ LANGUAGE plpgsql; - 在这类 FOR 语句中使用的 query,可以是任何向调用者返回行的 SQL 命令:最常见的是 SELECT,但也可以是带 RETURNING 子句的 INSERTUPDATEDELETEMERGE。某些实用程序命令,如 EXPLAIN,也可以用于此处。 + 在这类 FOR 语句中使用的 query,可以是任何向调用者返回行的 SQL 命令:最常见的是 SELECT,但也可以是带 RETURNING 子句的 INSERTUPDATEDELETE。某些工具命令,如 EXPLAIN,也可以用于此处。 @@ -1956,7 +1932,7 @@ FOR target IN EXECUTE text_expressionstatements END LOOP label ; - 这个示例类似前面的形式,只不过源查询被指定为一个字符串表达式,在每次进入FOR循环时都会计算它并且重新计划。这允许程序员在一个预先计划好了的命令的速度和一个动态命令的灵活性之间进行选择,就像一个纯EXECUTE语句那样。在使用EXECUTE时,可以通过USING将参数值插入到动态命令中。 + 这个示例类似前面的形式,只不过源查询被指定为一个字符串表达式,在每次进入FOR循环时都会计算它并且重新计划。这允许程序员在一个预先计划好了的命令的速度和一个动态命令的灵活性之间进行选择,就像一个纯EXECUTE语句那样。与EXECUTE一样,可以通过USING将参数值插入到动态命令中。 @@ -1969,7 +1945,7 @@ END LOOP label ; 遍历数组 - FOREACH循环很像FOR循环,但它不是遍历 SQL 查询返回的行,而是遍历数组值的元素。(一般来说,FOREACH用于遍历组合值表达式的组成部分;未来还可能加入遍历数组以外其他组合值的变体。)用于遍历数组的FOREACH语句如下: + FOREACH循环很像FOR循环,但它不是遍历 SQL 查询返回的行,而是遍历数组值的元素。(一般来说,FOREACH用于遍历复合值表达式的组成部分;未来还可能加入遍历数组以外其他复合值的变体。)用于遍历数组的FOREACH语句如下: <<label>> @@ -1997,7 +1973,7 @@ END; $$ LANGUAGE plpgsql; - 元素会按存储顺序访问,而不管数组有多少维。尽管target通常只是单个变量,但在遍历组合值(记录)数组时,它也可以是一个变量列表。在这种情况下,每个数组元素都会按组合值的连续列给这些变量赋值。 + 元素会按存储顺序访问,而不管数组有多少维。尽管target通常只是单个变量,但在遍历复合值(记录)数组时,它也可以是一个变量列表。在这种情况下,每个数组元素都会按复合值的连续列给这些变量赋值。 @@ -2030,8 +2006,8 @@ NOTICE: row = {10,11,12} 捕获错误 - exceptions - in PL/pgSQL + 异常 + 在 PL/pgSQL 中 @@ -2054,7 +2030,7 @@ END; - 如果没有发生错误,这种形式的块只是简单地执行所有statements, 并且接着控制转到END之后的下一个语句。但是如果在statements内发生了一个错误,则会放弃对statements的进一步处理,然后控制会转到EXCEPTION列表。系统会在列表中寻找匹配所发生错误的第一个condition。如果找到一个匹配,则执行对应的handler_statements,并且接着把控制转到END之后的下一个语句。如果没有找到匹配,该错误就会传播出去,就好像根本没有EXCEPTION一样:错误可以被一个带有EXCEPTION的闭合块捕捉,如果没有EXCEPTION则中止该函数的处理。 + 如果没有发生错误,这种形式的块只是简单地执行所有statements, 并且接着控制转到END之后的下一个语句。但是如果在statements内发生了一个错误,则会放弃对statements的进一步处理,然后控制会转到EXCEPTION列表。系统会在列表中寻找匹配所发生错误的第一个condition。如果找到一个匹配,则执行对应的handler_statements,并且接着把控制转到END之后的下一个语句。如果没有找到匹配,该错误就会传播出去,就好像根本没有EXCEPTION一样:错误可以被一个带有EXCEPTION的外围块捕捉,如果没有这样的块则中止该函数的处理。 @@ -2091,7 +2067,7 @@ END; - 进入和退出一个包含EXCEPTION子句的块要比不包含EXCEPTION的块开销大的多。因此,只在必要的时候使用EXCEPTION。 + 进入和退出一个包含EXCEPTION子句的块要比不包含该子句的块开销大得多。因此,只在必要的时候使用EXCEPTION @@ -2118,9 +2094,9 @@ BEGIN IF found THEN RETURN; END IF; - -- 不在这里,那么尝试插入该键 + -- 该键不存在,因此尝试插入 -- 如果其他某人并发地插入同一个键, - -- 我们可能得到一个唯一键失败 + -- 就可能发生违反唯一约束的错误 BEGIN INSERT INTO db(a,b) VALUES (key, data); RETURN; @@ -2159,7 +2135,7 @@ SELECT merge_db(1, 'dennis'); GET STACKED DIAGNOSTICS variable { = | := } item , ... ; - 每个item是一个关键词,它标识一个被赋予给指定变量(应该具有接收该值的正确数据类型)的状态值。中显示了当前可用的状态项。 + 每个item是一个关键词,它标识一个被赋予给指定variable(应该具有接收该值的正确数据类型)的状态值。中显示了当前可用的状态项。 @@ -2271,7 +2247,7 @@ END; 获得执行位置信息 - GET DIAGNOSTICS(之前在中描述)命令检索有关当前执行状态的信息(反之上文讨论的GET STACKED DIAGNOSTICS命令会把有关执行状态的信息报告成一个以前的错误)。它的PG_CONTEXT状态项可用于标识当前执行位置。状态项PG_CONTEXT将返回一个文本字符串,其中有描述该调用栈的多行文本。第一行会指向当前函数以及当前正在执行GET DIAGNOSTICS的命令。第二行及其后的行表示调用栈中更上层的调用函数。例如: + GET DIAGNOSTICS(之前在中描述)命令检索有关当前执行状态的信息(反之上文讨论的GET STACKED DIAGNOSTICS命令报告先前发生错误时的执行状态信息)。它的PG_CONTEXT状态项可用于标识当前执行位置。状态项PG_CONTEXT将返回一个文本字符串,其中包含一行或多行描述该调用栈的文本。第一行会指向当前函数以及当前正在执行的GET DIAGNOSTICS命令。第二行及其后的行表示调用栈中更上层的调用函数。例如: CREATE OR REPLACE FUNCTION outer_func() RETURNS integer AS $$ @@ -2315,7 +2291,7 @@ CONTEXT: PL/pgSQL function outer_func() line 3 at RETURN 游标 - cursor + 游标 在 PL/pgSQL 中 @@ -2347,7 +2323,7 @@ DECLARE - 当游标查询使用 FOR UPDATE/SHARE 时,不能使用 SCROLL 选项。此外,对于涉及易失函数的查询,最好使用 NO SCROLLSCROLL 的实现假定重新读取查询输出会得到一致的结果,而易失函数并不满足这一假设。 + 当游标查询使用 FOR UPDATE/SHARE 时,不能使用 SCROLL 选项。此外,对于涉及易失函数的查询,最好使用 NO SCROLLSCROLL 的实现假定重新读取查询输出会得到一致的结果,而易失函数可能无法满足这一假设。 @@ -2372,7 +2348,7 @@ DECLARE - 打开游标会创建一个称为 portal 的服务器内部数据结构,它保存游标查询的执行状态。portal 具有一个名称,在其存在期间该名称在会话内必须唯一。默认情况下,PL/pgSQL 会为其创建的每个 portal 分配唯一名称。不过,如果你给游标变量赋一个非空字符串值,该字符串会被用作 portal 名称。这个特性可用于中描述的用法。 + 打开游标会创建一个称为 portal 的服务器内部数据结构,它保存游标查询的执行状态。portal 具有一个名称,在其存在期间该名称在会话内必须唯一。默认情况下,PL/pgSQL 会为其创建的每个 portal 分配唯一名称。不过,如果你给游标变量赋一个非 NULL 的字符串值,该字符串会被用作 portal 名称。这个特性可用于中描述的用法。 @@ -2422,7 +2398,7 @@ OPEN curs1 FOR EXECUTE format('SELECT * FROM %I WHERE col1 = $1',tabname) USING 打开已绑定游标 -OPEN bound_cursorvar ( argument_name { := | => } argument_value , ... ) ; +OPEN bound_cursorvar ( argument_name := argument_value , ... ) ; @@ -2434,7 +2410,7 @@ OPEN bound_cursorvar ( - 使用位置命名记号可以传递参数值。在位置记号中,所有参数都必须按照顺序指定。在命名记号中,每一个参数的名字使用:==>与参数表达式分隔。类似于中描述的调用函数,也允许混合位置和命名记号。 + 使用位置命名记号可以传递参数值。在位置记号中,所有参数都必须按照顺序指定。在命名记号中,每一个参数的名字使用:=与参数表达式分隔。类似于中描述的调用函数,也允许混合位置和命名记号。 @@ -2443,7 +2419,6 @@ OPEN bound_cursorvar ( @@ -2498,7 +2473,7 @@ FETCH direction { FROM | IN } RELATIVE countFORWARD或者 BACKWARD。 - 省略direction和指定NEXT是一样的。在使用count的形式中,count可以是任意的整数值表达式(与SQL命令FETCH不一样,FETCH仅允许整数常量)。除非游标被使用SCROLL选项声明或打开,否则要求反向移动的direction值很可能会失败。 + 省略direction和指定NEXT是一样的。在使用count的形式中,count可以是任意的整数值表达式(与SQL命令FETCH不一样,后者仅允许整数常量)。除非游标被使用SCROLL选项声明或打开,否则要求反向移动的direction值很可能会失败。 @@ -2586,13 +2561,13 @@ CLOSE curs1; - 游标使用的 portal 名称既可以由程序员指定,也可以自动生成。要指定 portal 名称,只需在打开refcursor变量之前给它赋一个字符串值。OPEN会把该refcursor变量的字符串值用作底层 portal 的名称。不过,如果refcursor变量为 null,OPEN就会自动生成一个与任何现有 portal 都不冲突的名称,并把它赋回给refcursor变量。 + 游标使用的 portal 名称既可以由程序员指定,也可以自动生成。要指定 portal 名称,只需在打开refcursor变量之前给它赋一个字符串值。OPEN会把该refcursor变量的字符串值用作底层 portal 的名称。不过,如果refcursor变量为 null(这是默认值),OPEN就会自动生成一个与任何现有 portal 都不冲突的名称,并把它赋回给refcursor变量。 - 在 PostgreSQL 16 之前,已绑定游标变量会被初始化为其自身名称,而不是保持为空,因此默认情况下底层 portal 名称与游标变量名相同。之所以改动,是因为该行为在不同函数里同名游标之间带来了过高的名称冲突风险。 + 在 PostgreSQL 16 之前,已绑定游标变量会被初始化为其自身名称,而不是保持为 NULL,因此默认情况下底层 portal 名称与游标变量名相同。之所以改动,是因为该行为在不同函数里同名游标之间带来了过高的名称冲突风险。 @@ -2679,7 +2654,7 @@ COMMIT; <<label>> -FOR recordvar IN bound_cursorvar ( argument_name { := | => } argument_value , ... ) LOOP +FOR recordvar IN bound_cursorvar ( argument_name := argument_value , ... ) LOOP statements END LOOP label ; @@ -2726,7 +2701,7 @@ CALL transaction_test1(); 连锁的事务 - 在 PL/pgSQL + 在 PL/pgSQL 中 @@ -2738,13 +2713,7 @@ CALL transaction_test1(); 只有在从顶层调用的CALLDO中才能进行事务控制,在没有任何其他中间命令的嵌套CALLDO调用中也能进行事务控制。例如,如果调用栈是CALL proc1()CALL proc2()CALL proc3(),那么第二个和第三个过程可以执行事务控制动作。但是如果调用栈是CALL proc1()SELECT func2()CALL proc3(),则最后一个过程不能做事务控制,因为中间有SELECT - - PL/pgSQL 不支持保存点(SAVEPOINT/ROLLBACK TO SAVEPOINT/RELEASE SAVEPOINT)。保存点的典型用法可以用带异常处理器的代码块替代(见)。在内部,实现为带异常处理器的代码块会形成一个子事务,这意味着在这类代码块内部不能结束事务。 - - - - 对于游标循环,还有一些特殊注意事项。请看下面这个示例: - + 游标循环需要特别考虑。来看这个例子: CREATE PROCEDURE transaction_test2() LANGUAGE plpgsql AS $$ @@ -2759,13 +2728,13 @@ END; $$; CALL transaction_test2(); - - 通常,游标会在事务提交时自动关闭。但是,作为这类循环一部分创建的游标,会在第一次 COMMITROLLBACK 时自动转换为可保持游标。这意味着该游标会在第一次 COMMITROLLBACK 时被完整求值,而不是逐行求值。循环结束后,该游标仍会被自动移除,因此这一点对用户通常不可见。但必须注意,游标查询获取的任何表锁或行锁,在第一次 COMMITROLLBACK 之后都不再保持。 - +通常,游标会在事务提交时自动关闭。但是,在这样的循环中创建的游标,会自动转换为可保持游标,转换发生于第一次COMMITROLLBACK。这意味着,游标将在第一次执行以下命令时被完整求值:COMMITROLLBACK,而不是逐行求值。循环结束后游标仍然会被自动移除,因此这些行为对用户大多是不可见的。 由非只读命令(例如 UPDATE ... RETURNING)驱动的游标循环中,不允许使用事务命令。 + + 不能在带有异常处理器的块中结束事务。 @@ -2786,28 +2755,17 @@ CALL transaction_test2(); 在 PL/pgSQL 中 - - 使用RAISE语句报告消息以及抛出错误。 - - -RAISE level 'format' , expression , ... USING option { = | := } expression , ... ; -RAISE level condition_name USING option { = | := } expression , ... ; -RAISE level SQLSTATE 'sqlstate' USING option { = | := } expression , ... ; -RAISE level USING option { = | := } expression , ... ; + 使用RAISE语句报告消息和抛出错误。 +RAISE level 'format' , expression , ... USING option = expression , ... ; +RAISE level condition_name USING option = expression , ... ; +RAISE level SQLSTATE 'sqlstate' USING option = expression , ... ; +RAISE level USING option = expression , ... ; RAISE ; - +其中,level选项指定错误的严重程度。允许的级别为DEBUG, + LOGINFO, + NOTICEWARNING以及EXCEPTION,其中EXCEPTION是默认值。EXCEPTION会抛出错误(通常会中止当前事务);其他级别只会生成不同优先级的消息。特定优先级的消息是报告给客户端、写入服务器日志,还是两者都做,由配置变量控制。更多信息见中的说明。 - level选项指定了错误的严重性。允许的级别有DEBUGLOGINFONOTICE, WARNING以及EXCEPTION,默认级别是EXCEPTIONEXCEPTION会抛出一个错误(通常会中止当前事务)。其他级别仅仅是产生不同优先级的消息。不管一个特定优先级的消息是被报告给客户端、还是写到服务器日志、亦或是二者同时都做,这都由配置变量控制。详见。 - - - - 在第一种语法变体中,在level之后(如果有),写一个format字符串 - (必须是一个简单的字符串文字,而不是一个表达式)。格式字符串指定要报告的错误消息文本。 - 格式字符串后跟要插入到消息中的可选参数表达式。 - 在格式字符串中,%将被下一个可选参数的值的字符串表示替换。写 - %%以发出一个字面上的%。 - 参数的数量必须与格式字符串中的%占位符的数量匹配,否则在函数编译期间会引发错误。 - + level(如果有)之后,可以指定一个format字符串(必须是简单的字符串字面量,不能是表达式)。格式字符串指定要报告的错误消息文本。格式字符串之后可以跟上可选的参数表达式,其值将被插入消息中。在格式字符串内,%会被替换为下一个可选参数值的字符串表示。写成%%可以输出一个字面的%。参数个数必须与格式字符串中%占位符的个数匹配,否则会在函数编译期间报错。 在这个示例中,v_job_id的值将替换字符串中的%: @@ -2816,36 +2774,21 @@ RAISE NOTICE 'Calling cs_create_job(%)', v_job_id; - - 在第二和第三种语法变体中,condition_name 和 - sqlstate 分别指定错误条件名称或五字符 SQLSTATE 代码。 - 有效的错误条件名称和预定义 SQLSTATE 代码见 。 - - - - 下面是 condition_name 和 - sqlstate 的用法示例: - -RAISE division_by_zero; -RAISE WARNING SQLSTATE '22012'; - - - - - 在任意一种语法变体中,都可以通过写一个后面跟着option = expression项的USING,为错误报告附加额外信息。每一个expression可以是任意字符串值的表达式。允许的option关键词是: - - + 可以为错误报告附加额外信息,方法是写出USING,后面跟上option = expression项目。每个expression都可以是任意字符串值表达式。允许的option关键字为: MESSAGE - 设置错误消息文本。该选项不能用于第一种语法变体,因为消息文本已经给出。 + 设置错误消息文本。该选项不能用于在USING之前包含格式字符串的RAISE形式。 DETAIL - 提供一个错误的细节消息。 + 提供错误的详细信息。 @@ -2859,7 +2802,7 @@ RAISE WARNING SQLSTATE '22012'; ERRCODE - 指定要报告的错误代码(SQLSTATE),可以用中所示的条件名,或者直接作为一个五字符 SQLSTATE 代码。该选项不能用于第二和第三种语法变体,因为错误代码已经给出。 + 指定要报告的错误代码(SQLSTATE),可以用中所示的条件名,或者直接作为一个五字符 SQLSTATE 代码。 @@ -2876,9 +2819,7 @@ RAISE WARNING SQLSTATE '22012'; - - 这个示例将用给定的错误消息和提示中止事务: - + 这个例子会中止事务,并给出指定的错误消息和提示: RAISE EXCEPTION 'Nonexistent ID --> %', user_id USING HINT = 'Please check your user ID'; @@ -2893,14 +2834,19 @@ RAISE 'Duplicate user ID: %', user_id USING ERRCODE = '23505'; - 另一种得到前面示例相同结果的方式是: + 还有第二种RAISE语法,其中主参数是要报告的条件名或 SQLSTATE,例如: + +RAISE division_by_zero; +RAISE SQLSTATE '22012'; + + 在这种语法中,USING可以用来提供自定义的错误消息、细节或提示。另一种达到前面示例同样效果的方式是: RAISE unique_violation USING MESSAGE = 'Duplicate user ID: ' || user_id; - 如第四种语法变体所示,也可以写成RAISE USINGRAISE level USING,并把其余内容都放在USING列表里。 + 还有另一种变体是写RAISE USINGRAISE level USING,并把其余内容都放在USING列表里。 @@ -2923,7 +2869,7 @@ RAISE unique_violation USING MESSAGE = 'Duplicate user ID: ' || user_id; - 当用 SQLSTATE 代码指定错误代码时,你并不受限于预定义错误代码,而是可以选择任何由五位数字和/或大写 ASCII 字母构成的错误代码,唯一不能使用的是 00000。我们建议尽量避免抛出以三个零结尾的错误代码,因为这些是类别代码,只能用于捕获整个类别。 + 当用 SQLSTATE 代码指定错误代码时,你并不受限于预定义错误代码,而是可以选择任何由五位数字和/或大写 ASCII 字母构成的错误代码,唯一不能使用的是 00000。我们建议尽量避免抛出以三个零结尾的错误代码,因为这些是类别代码,只能通过捕获整个类别来捕获这类错误。 @@ -2935,12 +2881,12 @@ RAISE unique_violation USING MESSAGE = 'Duplicate user ID: ' || user_id; ASSERT - in PL/pgSQL + 在 PL/pgSQL 中 - assertions - in PL/pgSQL + 断言 + 在 PL/pgSQL 中 @@ -2957,15 +2903,14 @@ ASSERT condition , condition是一个布尔 表达式,它被期望总是计算为真。如果确实如此, - ASSERT语句不会再做什么。但如果结果是假 - 或者空,那么将发生一个ASSERT_FAILURE异常(如果在计算 + ASSERT语句不会再做什么。但如果结果是假或者空值,那么将发生一个ASSERT_FAILURE异常(如果在计算 condition时发生错误, 它会被报告为一个普通错误)。 如果提供了可选的message, - 它是一个结果(如果非空)被用来替换默认错误消息文本 + 它是一个结果(如果不为 NULL)被用来替换默认错误消息文本 assertion failed的表达式(如果 condition失败)。 message表达式在 @@ -2998,7 +2943,7 @@ ASSERT condition , - PL/pgSQL可以被用来在数据更改或者数据库事件上定义触发器函数。触发器函数用CREATE FUNCTION命令创建,它被声明为一个没有参数并且返回类型为trigger(对于数据更改触发器)或者event_trigger(对于数据库事件触发器)的函数。名为PG_something的特殊局部变量将被自动创建用以描述触发该调用的条件。 + PL/pgSQL可以被用来在数据更改或者数据库事件上定义触发器函数。触发器函数用CREATE FUNCTION命令创建,它被声明为一个没有参数并且返回类型为trigger(对于数据更改触发器)或者event_trigger(对于数据库事件触发器)的函数。名为TG_something的特殊局部变量将被自动创建用以描述触发该调用的条件。 @@ -3009,10 +2954,7 @@ ASSERT condition , 数据更改触发器被声明为一个没有参数并且返回类型为trigger的函数。注意,如下所述,即便该函数准备接收一些在CREATE TRIGGER中指定的参数 — 这类参数通过TG_ARGV传递,也必须把它声明为没有参数。 - - 当一个PL/pgSQL函数当做触发器调用时,在顶层块会自动创建一些特殊变量。它们是: - - + 当一个PL/pgSQL函数作为触发器被调用时,会在顶层块中自动创建一些特殊变量。它们是: NEW record @@ -3132,11 +3074,11 @@ ASSERT condition , - INSTEAD OF触发器(总是行级触发器,并且可能只被用于视图)能够返回空来表示它们没有执行任何更新,并且对该行剩余的操作可以被跳过(即后续的触发器不会被引发,并且该行不会被计入外围INSERT/UPDATE/DELETE的行影响状态中)。否则一个非空值应该被返回用以表示该触发器执行了所请求的操作。对于INSERTUPDATE操作,返回值应该是NEW,触发器函数可能对它进行了修改来支持INSERT RETURNINGUPDATE RETURNING(这也将影响被传递给任何后续触发器的行值,或者被传递给带有ON CONFLICT DO UPDATEINSERT语句中一个特殊的EXCLUDED别名引用)。对于DELETE操作,返回值应该是OLD。 + INSTEAD OF触发器(总是行级触发器,并且只能用于视图)能够返回 null 来表示它们没有执行任何更新,并且对该行剩余的操作应被跳过(即后续的触发器不会被引发,并且该行不会被计入外围INSERT/UPDATE/DELETE的行影响状态中)。否则应该返回一个非 null 值用以表示该触发器执行了所请求的操作。对于INSERTUPDATE操作,返回值应该是NEW,触发器函数可能对它进行了修改来支持INSERT RETURNINGUPDATE RETURNING(这也将影响被传递给任何后续触发器的行值,或者被传递给带有ON CONFLICT DO UPDATEINSERT语句中一个特殊的EXCLUDED别名引用)。对于DELETE操作,返回值应该是OLD - 一个AFTER行级触发器或一个BEFOREAFTER语句级触发器的返回值总是会被忽略,它可能也是空。不过,任何这些类型的触发器可能仍会通过抛出一个错误来中止整个操作。 + 一个AFTER行级触发器或一个BEFOREAFTER语句级触发器的返回值总是会被忽略,因此也可以返回 null。不过,任何这些类型的触发器可能仍会通过抛出一个错误来中止整个操作。 @@ -3310,11 +3252,10 @@ INSTEAD OF INSERT OR UPDATE OR DELETE ON emp_view - - 一个 <application>PL/pgSQL</application> 用于维护汇总表的触发器函数 + 一个用于维护汇总表的 <application>PL/pgSQL</application> 触发器函数 - 这里详述的模式有一部分是基于 Ralph Kimball 所作的数据仓工具包中的Grocery Store示例。 + 这里详述的模式有一部分是基于 Ralph Kimball 所作的数据仓库工具包中的Grocery Store示例。 @@ -3457,7 +3398,7 @@ SELECT * FROM sales_summary_bytime; 使用过渡表审计 - 这个示例产生和相同的结果,但并未使用一个为每一行都触发的触发器,而是在把相关信息收集到一个过渡表中之后用了一个只为每个语句引发一次的触发器。当调用语句修改了很多行时,这种方法明显比行触发器方法快。注意我们必须为每一种事件建立一个单独的触发器声明,因为每种情况的REFERENCING子句必须不同。但是这并不能阻止我们使用单一的触发器函数(实际上,使用三个单独的函数会更好,因为可以避免在TG_OP上的运行时测试)。 + 这个示例产生和相同的结果,但并未使用一个为每一行都触发的触发器,而是在把相关信息收集到一个过渡表中之后用了一个只为每个语句引发一次的触发器。当调用语句修改了很多行时,这种方法可能显著快于行触发器方法。注意我们必须为每一种事件建立一个单独的触发器声明,因为每种情况的REFERENCING子句必须不同。但是这并不能阻止我们使用单一的触发器函数(实际上,使用三个单独的函数可能会更好,因为可以避免在TG_OP上的运行时测试)。 @@ -3519,10 +3460,7 @@ CREATE TRIGGER emp_audit_del PL/pgSQL可以被用来定义事件触发器。PostgreSQL要求一个可以作为事件触发器调用的函数必须被声明为没有参数并且返回类型为event_trigger - - 当一个PL/pgSQL函数被作为一个事件触发器调用,在顶层块中会自动创建一些特殊变量。它们是: - - + 当一个PL/pgSQL函数作为事件触发器被调用时,会在顶层块中自动创建一些特殊变量。它们是: TG_EVENT text @@ -3573,9 +3511,7 @@ CREATE EVENT TRIGGER snitch ON ddl_command_start EXECUTE FUNCTION snitch(); <application>PL/pgSQL</application> 内部机制 - - 这一节讨论了一些PL/pgSQL用户应该知道的一些重要的实现细节。 - + 本节讨论一些实现细节,了解这些细节对 PL/pgSQL 用户通常很重要。 @@ -3653,7 +3589,7 @@ CREATE FUNCTION stamp_user(id int, comment text) RETURNS void AS $$ END; $$ LANGUAGE plpgsql; - 在UPDATE命令中,curtimecomment以及id将引用该函数的变量和参数,不管users有没有这些名称的列。注意,我们不得不在WHERE子句中对users.id的引用加以限定,以便让它引用表列。但是我们不需要在UPDATE列表中把对comment的引用限定为一个目标,因为语法上那必须是users的一列。我们可以用下面的方式写一个相同的不依赖于variable_conflict设置的函数: + 在UPDATE命令中,curtimecomment以及id将引用该函数的变量和参数,不管users有没有这些名称的列。注意,我们不得不在WHERE子句中对users.id的引用加以限定,以便让它引用表列。但是我们不需要对UPDATE列表中作为目标的comment引用加以限定,因为语法上那必须是users的一列。我们可以用下面的方式写一个相同的不依赖于variable_conflict设置的函数: CREATE FUNCTION stamp_user(id int, comment text) RETURNS void AS $$ <<fn>> @@ -3672,7 +3608,7 @@ $$ LANGUAGE plpgsql; - 目前,变量替换只在 SELECTINSERTUPDATEDELETEMERGE 以及包含其中之一的命令中生效(例如 EXPLAINCREATE TABLE ... AS SELECT),因为主 SQL 引擎只允许在这些命令中使用查询参数。若要在其他语句类型(统称为实用语句)中使用非常量名称或值,就必须把该实用语句构造为字符串,再用 EXECUTE 执行。 + 目前,变量替换只在 SELECTINSERTUPDATEDELETEMERGE 以及包含其中之一的命令中生效(例如 EXPLAINCREATE TABLE ... AS SELECT),因为主 SQL 引擎只允许在这些命令中使用查询参数。若要在其他语句类型(统称为工具语句)中使用非常量名称或值,就必须把该工具语句构造为字符串,再用 EXECUTE 执行。 @@ -3694,7 +3630,7 @@ $$ LANGUAGE plpgsql; - PL/pgSQL(更准确地说,是 SPI 管理器)还会尝试缓存与某个预备语句相关的执行计划。如果没有使用缓存计划,那么每次执行该语句时都会生成新的执行计划,而当前参数值(也就是 PL/pgSQL 变量值)可用于优化所选计划。如果该语句没有参数,或者会被执行很多次,SPI 管理器就会考虑创建一个不依赖具体参数值的通用计划,并将其缓存起来供重复使用。通常只有在执行计划对其中引用的 PL/pgSQL 变量值不太敏感时,才会这样做。如果执行计划对参数值非常敏感,那么每次重新生成计划总体上反而更划算。关于预备语句的行为,详见 。 + PL/pgSQL(更准确地说,是 SPI 管理器)还可以尝试缓存与某个预备语句相关的执行计划。如果没有使用缓存计划,那么每次执行该语句时都会生成新的执行计划,而当前参数值(也就是 PL/pgSQL 变量值)可用于优化所选计划。如果该语句没有参数,或者会被执行很多次,SPI 管理器就会考虑创建一个不依赖具体参数值的通用计划,并将其缓存起来供重复使用。通常只有在执行计划对其中引用的 PL/pgSQL 变量值不太敏感时,才会这样做。如果执行计划对参数值非常敏感,那么每次重新生成计划总体上反而更划算。关于预备语句的行为,详见 @@ -3743,7 +3679,7 @@ $$ LANGUAGE plpgsql; - 在logfunc2中,PostgreSQL的主解析器不知道应该把'now'解释成什么类型,因此返回一个text类型的数据值,其中包含字符串now。在确定对本地变量curtime的赋值时,PL/pgSQL解释器通过调用用于该转换的textouttimestamp_in函数,把这个字符串转换为timestamp类型。因此,计算得到的时间戳会按程序员预期在每次执行时更新。虽然这恰好能得到预期结果,但效率并不高,因此使用now()函数仍然是更好的主意。 + 在logfunc2中,PostgreSQL的主解析器不知道应该把'now'解释成什么类型,因此返回一个text类型的数据值,其中包含字符串now。在随后给局部变量curtime赋值时,PL/pgSQL解释器通过调用用于该转换的textouttimestamp_in函数,把这个字符串转换为timestamp类型。因此,计算得到的时间戳会按程序员预期在每次执行时更新。虽然这恰好能得到预期结果,但效率并不高,因此使用now()函数仍然是更好的主意。 @@ -3772,7 +3708,7 @@ $$ LANGUAGE plpgsql; - 另一种开发PL/pgSQL的好方法,是使用有助于过程语言开发的 GUI 数据库访问工具。这类工具的一个例子是pgAdmin,当然也有其他工具。它们通常提供一些方便的特性,例如转义单引号,以及让重新创建和调试函数变得更容易。 + 另一种使用PL/pgSQL进行开发的好方法,是使用有助于过程语言开发的 GUI 数据库访问工具。这类工具的一个例子是pgAdmin,当然也有其他工具。它们通常提供一些方便的特性,例如转义单引号,以及让重新创建和调试函数变得更容易。 @@ -3780,7 +3716,7 @@ $$ LANGUAGE plpgsql; 引号的处理 - 一个PL/pgSQL函数的代码在一个CREATE FUNCTION中被指定为一个字符串。如果你用通常的方式把该字符串写在单引号中间,那么该函数体中的任何单引号都必须被双写;同样任何反斜线也必须被双写(假定使用了转义字符串语法)。双写引号最多有点冗长,并且在更复杂的情况中代码会变得完全无法理解,因为你很容易发现你需要半打或者更多相邻的引号。我们推荐你转而把函数体写成一个美元引用的字符串(见)。在美元引用方法中,你从不需要双写任何引号。但是要注意为你需要的每一层嵌套选择一个不同的美元引用定界符。例如,你可能把CREATE FUNCTION命令写成: + 一个PL/pgSQL函数的代码在一个CREATE FUNCTION中被指定为一个字符串字面量。如果你用通常的方式把该字符串写在单引号中间,那么该函数体中的任何单引号都必须被双写;同样任何反斜线也必须被双写(假定使用了转义字符串语法)。双写引号本身就很繁琐,并且在更复杂的情况中代码会变得完全无法理解,因为你很容易发现你需要半打或者更多相邻的引号。我们推荐你转而把函数体写成一个美元引用的字符串(见)。在美元引用方法中,你从不需要双写任何引号。但是要注意为你需要的每一层嵌套选择一个不同的美元引用定界符。例如,你可能把CREATE FUNCTION命令写成: CREATE OR REPLACE FUNCTION testfunc(integer) RETURNS integer AS $PROC$ .... @@ -3817,7 +3753,7 @@ CREATE FUNCTION foo() RETURNS integer AS ' - 用于函数体内的字符串,例如: + 用于函数体内的字符串字面量,例如: a_output := ''Blah''; SELECT * FROM users WHERE f_name=''foobar''; @@ -3827,7 +3763,7 @@ SELECT * FROM users WHERE f_name=''foobar''; a_output := 'Blah'; SELECT * FROM users WHERE f_name='foobar'; - 这恰好就是PL/pgSQL在两种情况中会看到的。 + 这恰好就是PL/pgSQL解析器在两种情况中会看到的。 @@ -3850,7 +3786,7 @@ a_output := a_output || '' AND name LIKE ''''foobar'''' AND xyz'' a_output := a_output || $$ AND name LIKE 'foobar' AND xyz$$ - 要小心在这周围的任何美元引用定界符不只是$$。 + 要小心在这周围的任何美元引用定界符都不能是$$ @@ -3883,7 +3819,7 @@ a_output := a_output || $$ AND name LIKE 'foobar'$$ - 当你想在一个字符串常量(占 8 个引号)中有两个单引号时并且这会挨着该字符串常量的末尾(另外 2 个)。如果你正在写一个产生其他函数的函数(如中),你将很可能只需要这种。例如: + 当字符串常量中需要两个单引号(这需要 8 个引号),而且它们紧邻该字符串常量的末尾(还需 2 个引号)时。通常只有在编写生成其他函数的函数时(如所示),才会需要这种写法。例如: a_output := a_output || '' if v_'' || referrer_keys.kind || '' like '''''''''' @@ -3925,9 +3861,7 @@ a_output := a_output || $$ if v_$$ || referrer_keys.kind || $$ like '$$ 因此建议你在一个单独的开发环境中进行测试。 - - 根据需要设置 plpgsql.extra_warningsplpgsql.extra_errors,适当情况下,在开发和/或测试环境中可以设置为 "all"。 - + 建议在开发和/或测试环境中,根据需要将 plpgsql.extra_warningsplpgsql.extra_errors 设置为 "all" 这些额外的检查通过配置变量plpgsql.extra_warnings来启用警告, @@ -4041,18 +3975,16 @@ HINT: Make sure the query returns the exact list of columns. - PL/pgSQL与 PL/SQL 在许多方面都非常类似。它是一种块结构的、命令式的语言并且所有变量必须先被声明。赋值、循环和条件则很类似。在从PL/SQLPL/pgSQL移植时必须记住一些事情: - - + PL/pgSQL在许多方面都与 PL/SQL 类似。它是一种具有块结构的命令式语言,所有变量都必须声明。赋值、循环和条件语句也都很相似。在从PL/SQL移植到PL/pgSQL时,应当记住以下主要差异: - 如果一个 SQL 命令中使用的名字可能是一个表的列名或者是对一个函数中变量的引用,那么PL/SQL会将它当作一个列名。默认情况下, PL/pgSQL会抛出名称模糊的错误, 你可以指定plpgsql.variable_conflict=use_column来改变这一行为以匹配PL/SQL。如中所述。通常最好是首先避免这种歧义,但如果不得不移植依赖于该行为的大量代码,那么设置variable_conflict将是最好的方案。 + 如果一个 SQL 命令中使用的名字可能是一个表的列名或者是对一个函数中变量的引用,那么PL/SQL会将它当作一个列名。默认情况下, PL/pgSQL会抛出名称有歧义的错误, 你可以指定plpgsql.variable_conflict=use_column来改变这一行为以匹配PL/SQL。如中所述。通常最好是首先避免这种歧义,但如果不得不移植依赖于该行为的大量代码,那么设置variable_conflict可能是最好的方案。 - 在PostgreSQL中,函数体必须写成字符串文本。因此你需要使用美元符引用或者转义函数体中的单引号(见)。 + 在PostgreSQL中,函数体必须写成字符串字面量。因此你需要使用美元符引用或者转义函数体中的单引号(见)。 @@ -4142,13 +4074,13 @@ show errors; - 在PostgreSQL中,函数体被认为是一个字符串,所以你需要使用引号或者美元符号包围它。这代替了Oracle 方法中的用于终止的/。 + 在PostgreSQL中,函数体被认为是一个字符串字面量,所以你需要使用引号或者美元引用定界符包围它。这代替了Oracle 方法中的用于终止的/ - 在PostgreSQL中没有show errors命令, 并且也不需要这个命令,因为错误是自动报告的。 + 在PostgreSQL中没有show errors命令, 并且也不需要这个命令,因为错误是自动报告的。 @@ -4180,9 +4112,7 @@ $$ LANGUAGE plpgsql; 从<application>PL/SQL</application>移植一个创建另一个函数的函数到<application>PL/pgSQL</application> - - 下面的过程从一个SELECT语句抓取行,并且为了效率而构建一个带有IF语句中结果的大型函数。 - + 下面的过程从 SELECT 语句读取行,并将结果写入 IF 语句,从而构造一个大型函数,以提高效率。 这是 Oracle 版本: @@ -4213,8 +4143,7 @@ show errors; - - 这里是PostgreSQL的版本: + 下面是这个函数的最终移植结果,目标数据库为PostgreSQL CREATE OR REPLACE PROCEDURE cs_update_referrer_type_proc() AS $func$ DECLARE @@ -4247,9 +4176,7 @@ BEGIN EXECUTE func_cmd; END; $func$ LANGUAGE plpgsql; - - 请注意,这里先单独构造了函数体,再通过 quote_literal 传入,以便把其中的引号正确双写。之所以需要这种技术,是因为我们无法安全地使用美元引用来定义新函数:我们并不确切知道会从 referrer_key.key_string 字段插入什么字符串。(这里假定 referrer_key.kind 始终可信地只会是 hostdomainurl,但 referrer_key.key_string 可能是任意内容,尤其可能包含美元符号。)实际上,这个函数比 Oracle 原版还有改进,因为当 referrer_key.key_stringreferrer_key.referrer_type 中包含引号时,它也不会生成无效代码。 - +注意,这里单独构造函数体,然后将其传给quote_literal,使其中的每个引号都变成两个。这种技术是必需的,因为不能安全地使用美元引用来定义新函数:我们无法确定会插入什么字符串,其来源是referrer_key.key_string字段。(这里假定referrer_key.kind可信,其值总是hostdomainurl,但是referrer_key.key_string可能是任何内容,尤其可能包含美元符号。)这个函数实际上改进了 Oracle 原版:当referrer_key.key_stringreferrer_key.referrer_type中包含引号时,它也不会生成有问题的代码。 @@ -4269,7 +4196,7 @@ $func$ LANGUAGE plpgsql; CREATE OR REPLACE PROCEDURE cs_parse_url( v_url IN VARCHAR2, - v_host OUT VARCHAR2, -- 这将被传回去 + v_host OUT VARCHAR2, -- 这个值将被返回 v_path OUT VARCHAR2, -- 这个也是 v_query OUT VARCHAR2) -- 还有这个 IS @@ -4312,9 +4239,9 @@ show errors; CREATE OR REPLACE FUNCTION cs_parse_url( v_url IN VARCHAR, - v_host OUT VARCHAR, -- 这将被传递回去 + v_host OUT VARCHAR, -- 这个值将被返回 v_path OUT VARCHAR, -- 这个也是 - v_query OUT VARCHAR) -- 以及这个 + v_query OUT VARCHAR) -- 还有这个 AS $$ DECLARE a_pos1 INTEGER; @@ -4357,7 +4284,7 @@ SELECT * FROM cs_parse_url('http://foobar.com/query.cgi?baz'); - 展示了如何移植一个使用了多种 Oracle 特性的过程。 + 展示了如何移植一个使用了多种 Oracle 专属特性的过程。 @@ -4397,7 +4324,7 @@ show errors - 这是我们如何将这个过程移植到PL/pgSQL: + 下面展示了如何将这个过程移植到PL/pgSQL CREATE OR REPLACE PROCEDURE cs_create_job(v_job_id integer) AS $$ @@ -4472,7 +4399,7 @@ EXCEPTION END; - 如果你正在移植一个以这种方式使用SAVEPOINTROLLBACK TO的 Oracle 过程,工作会比较简单:只要忽略SAVEPOINTROLLBACK TO即可。如果你的 Oracle 过程以不同方式使用SAVEPOINTROLLBACK TO,那就需要认真思考了。 + 如果你正在移植一个以这种方式使用SAVEPOINTROLLBACK TO的 Oracle 过程,工作会比较简单:只要省略SAVEPOINTROLLBACK TO即可。如果你的 Oracle 过程以不同方式使用SAVEPOINTROLLBACK TO,那就需要认真思考了。 @@ -4489,11 +4416,11 @@ END; 优化 <application>PL/pgSQL</application> 函数 - PostgreSQL提供了两种函数创建修饰符来优化执行:volatility(对于给定的相同参数,函数是否总是返回相同的结果)以及strictness (如果任何参数为空,函数是否返回空)。详见参考页。 + PostgreSQL提供了两种函数创建修饰符来优化执行:volatility(对于给定的相同参数,函数是否总是返回相同的结果)以及strictness (如果任何参数为空值,函数是否返回空值)。详见参考页。 - 在利用这些优化属性时,你的CREATE FUNCTION语句应该看起来像这样: + 在利用这些优化属性时,你的CREATE FUNCTION语句可能像这样: CREATE FUNCTION foo(...) RETURNS integer AS $$ diff --git a/zh/16/plpython.sgml b/zh/16/plpython.sgml index 25d33332..19a3c11b 100644 --- a/zh/16/plpython.sgml +++ b/zh/16/plpython.sgml @@ -45,7 +45,7 @@ CREATE FUNCTION funcname (argument-list) RETURNS return-type AS $$ - # PL/Python function body + # PL/Python 函数体 $$ LANGUAGE plpython3u; @@ -85,7 +85,7 @@ def __plpython_procedure_pymax_23456(): CREATE FUNCTION pystrip(x text) RETURNS text AS $$ - x = x.strip() # error + x = x.strip() # 错误 return x $$ LANGUAGE plpython3u; @@ -95,7 +95,7 @@ CREATE FUNCTION pystrip(x text) RETURNS text AS $$ global x - x = x.strip() # ok now + x = x.strip() # 现在可以正常工作 return x $$ LANGUAGE plpython3u; @@ -216,7 +216,7 @@ $$ LANGUAGE plpython3u; 如果把 SQL 空值空值在 PL/Python 中传给函数,参数值在 Python 中会显示为None。例如,中展示的pymax定义在处理空输入时就会返回错误结果。我们可以在函数定义中添加STRICT,让PostgreSQL做出更合理的处理:如果传入空值,函数根本不会被调用,而是自动返回空结果。另一种办法是在函数体中检查空输入: + sortas="PL/Python">在 PL/Python 中传给函数,参数值在 Python 中会显示为None。例如,中展示的pymax定义在处理空值输入时就会返回错误结果。我们可以在函数定义中添加STRICT,让PostgreSQL做出更合理的处理:如果传入空值,函数根本不会被调用,而是自动返回空值结果。另一种办法是在函数体中检查空值输入: CREATE FUNCTION pymax (a integer, b integer) @@ -329,21 +329,21 @@ CREATE TYPE named_value AS ( ); - 组合结果可以按以下形式返回: + 复合结果可以按以下形式返回: 序列类型(元组或列表,但不能是集合,因为集合不可通过索引访问) - 返回的序列对象必须包含与组合结果类型字段数相同的项。索引为 0 的项会赋给复合类型的第一个字段,索引为 1 的项赋给第二个字段,依此类推。例如: + 返回的序列对象必须包含与复合结果类型字段数相同的项。索引为 0 的项会赋给复合类型的第一个字段,索引为 1 的项赋给第二个字段,依此类推。例如: CREATE FUNCTION make_pair (name text, value integer) RETURNS named_value AS $$ return ( name, value ) - # or alternatively, as list: return [ name, value ] + # 也可以使用列表: return [ name, value ] $$ LANGUAGE plpython3u; @@ -391,7 +391,7 @@ AS $$ self.value = v return named_value(name, value) - # or simply + # 或者简写为 class nv: pass nv.name = name nv.value = value @@ -452,8 +452,8 @@ CREATE TYPE greeting AS ( CREATE FUNCTION greet (how text) RETURNS SETOF greeting AS $$ - # return tuple containing lists as composite types - # all other combinations work also + # 返回包含列表的元组,以列表表示复合类型 + # 其他组合方式也都可用 return ( [ how, "World" ], [ how, "PostgreSQL" ], [ how, "PL/Python" ] ) $$ LANGUAGE plpython3u; @@ -511,7 +511,7 @@ $$ LANGUAGE plpython3u; - 也支持带OUT参数的返回集函数(使用RETURNS SETOF record)。例如: + 也支持带OUT参数的集合返回函数(使用RETURNS SETOF record)。例如: CREATE FUNCTION multiout_simple_setof(n integer, OUT integer, OUT integer) RETURNS SETOF record AS $$ return [(1, 2)] * n @@ -546,7 +546,7 @@ SELECT * FROM multiout_simple_setof(3); DO $$ - # PL/Python code + # PL/Python 代码 $$ LANGUAGE plpython3u; @@ -795,7 +795,7 @@ CREATE FUNCTION usesavedplan() RETURNS trigger AS $$ else: plan = plpy.prepare("SELECT 1") SD["plan"] = plan - # rest of function + # 函数的其余部分 $$ LANGUAGE plpython3u; @@ -812,11 +812,11 @@ $$ LANGUAGE plpython3u; - 游标对象提供fetch方法,它接受一个整数参数并返回结果对象。每次调用fetch,返回对象都会包含下一批行,数量不会超过该参数值。一旦所有行都已取完,fetch就会开始返回空结果对象。游标对象还提供迭代器接口,每次产生一行,直到所有行为止。以这种方式获取的数据不会作为结果对象返回,而是以字典形式返回,每个字典对应一行结果。 + 游标对象提供fetch方法,它接受一个整数参数并返回结果对象。每次调用fetch,返回对象都会包含下一批行,数量不会超过该参数值。一旦所有行都已取完,fetch就会开始返回空结果对象。游标对象还提供迭代器接口,每次产生一行,直到取完所有行。以这种方式获取的数据不会作为结果对象返回,而是以字典形式返回,每个字典对应一行结果。 - 下面示例展示了如何处理大表中的数据: + 下面示例展示了处理大表中数据的两种方式: CREATE FUNCTION count_odd_iterator() RETURNS integer AS $$ odd = 0 @@ -842,7 +842,7 @@ $$ LANGUAGE plpython3u; CREATE FUNCTION count_odd_prepared() RETURNS integer AS $$ odd = 0 plan = plpy.prepare("select num from largetable where num % $1 <> 0", ["integer"]) -rows = list(plpy.cursor(plan, [2])) # or: = list(plan.cursor([2])) +rows = list(plpy.cursor(plan, [2])) # 或者:= list(plan.cursor([2])) return len(rows) $$ LANGUAGE plpython3u; @@ -995,7 +995,7 @@ CALL transaction_test1(); - 实用函数 + 辅助函数 plpy模块还提供以下函数: @@ -1049,7 +1049,7 @@ PL/Python function "raise_custom_exception" - 另一组实用函数是plpy.quote_literal(string)plpy.quote_nullable(string)以及plpy.quote_ident(string)。它们等价于中描述的内置引用函数。在构造临时查询时,这些函数很有用。中动态 SQL 的一个 PL/Python 等价写法如下: + 另一组辅助函数是plpy.quote_literal(string)plpy.quote_nullable(string)以及plpy.quote_ident(string)。它们等价于中描述的内置加引号函数。在构造临时查询时,这些函数很有用。中动态 SQL 的一个 PL/Python 等价写法如下: plpy.execute("UPDATE tbl SET %s = %s WHERE key = %s" % ( plpy.quote_ident(colname), diff --git a/zh/16/pltcl.sgml b/zh/16/pltcl.sgml index 1511515d..988756c0 100644 --- a/zh/16/pltcl.sgml +++ b/zh/16/pltcl.sgml @@ -13,7 +13,7 @@ - PL/Tcl 是一种适用于 PostgreSQL 数据库系统的可载入的过程语言,它允许使用 Tcl 语言 来编写 PostgreSQL 函数和过程。 + PL/Tcl 是一种适用于 PostgreSQL 数据库系统的可加载的过程语言,它允许使用 Tcl 语言 来编写 PostgreSQL 函数和过程。 @@ -54,7 +54,7 @@ CREATE FUNCTION funcname (argument-types) RETURNS return-type AS $$ - # PL/Tcl function body + # PL/Tcl 函数体 $$ LANGUAGE pltcl; @@ -75,11 +75,11 @@ CREATE FUNCTION tcl_max(integer, integer) RETURNS integer AS $$ $$ LANGUAGE pltcl STRICT; - 注意STRICT子句,它让我们不必考虑空输入值:如果传入的是空值,函数根本不会被调用,而是会自动返回空结果。 + 注意STRICT子句,它让我们不必考虑空值输入:如果传入的是空值,函数根本不会被调用,而是会自动返回空值结果。 - 在非严格函数中,如果某个参数的实际值为空,对应的$n变量会被设置为空串。要检测某个特定参数是否为空,可使用函数argisnull。例如,假设我们希望在tcl_max的两个参数中一个为空、一个非空时返回非空参数,而不是返回空值: + 在非严格函数中,如果某个参数的实际值为空值,对应的$n变量会被设置为空串。要检测某个特定参数是否为空值,可使用函数argisnull。例如,假设我们希望在tcl_max的两个参数中一个为空值、一个非空值时返回非空值参数,而不是返回空值: CREATE FUNCTION tcl_max(integer, integer) RETURNS integer AS $$ @@ -99,7 +99,7 @@ $$ LANGUAGE pltcl; - 复合类型参数会作为 Tcl 数组传递给函数。数组元素名就是该复合类型的属性名。如果传入行中的某个属性为 NULL,它就不会出现在数组中。下面是一个示例: + 复合类型参数会作为 Tcl 数组传递给函数。数组元素名就是该复合类型的属性名。如果传入行中的某个属性为空值,它就不会出现在数组中。下面是一个示例: CREATE TABLE employee ( @@ -185,7 +185,7 @@ $$ LANGUAGE pltcl; PL/Tcl 中的数据值 - 提供给 PL/Tcl 函数代码的参数值,只是将输入参数转换成文本形式(就像用SELECT语句将它们显示出来一样)。反过来,returnreturn_next命令会接受任何字符串,只要它是该函数声明结果类型或组合结果类型中指定列的可接受输入格式。 + 提供给 PL/Tcl 函数代码的参数值,只是将输入参数转换成文本形式(就像用SELECT语句将它们显示出来一样)。反过来,returnreturn_next命令会接受任何字符串,只要它是该函数声明结果类型或复合结果类型中指定列的可接受输入格式。 @@ -195,8 +195,8 @@ $$ LANGUAGE pltcl; PL/Tcl 中的全局数据 - global data - in PL/Tcl + 全局数据 + 在 PL/Tcl 中 @@ -234,7 +234,7 @@ $$ LANGUAGE pltcl; - 执行以字符串形式给出的 SQL 命令。命令出错时会引发错误。否则,spi_exec的返回值是该命令处理的行数(选出、插入、更新或删除的行),如果命令是实用程序语句则返回零。此外,如果命令是SELECT语句,则所选列的值会按下文所述放入 Tcl 变量中。 + 执行以字符串形式给出的 SQL 命令。命令出错时会引发错误。否则,spi_exec的返回值是该命令处理的行数(选出、插入、更新或删除的行),如果命令是工具语句则返回零。此外,如果命令是SELECT语句,则所选列的值会按下文所述放入 Tcl 变量中。 @@ -275,7 +275,7 @@ spi_exec -array C "SELECT * FROM pg_class" { - 如果查询结果中的某一列为空,则对应的目标变量会被unset,而不是被设值。 + 如果查询结果中的某一列为空值,则对应的目标变量会被unset,而不是被设值。 @@ -287,7 +287,7 @@ spi_exec -array C "SELECT * FROM pg_class" { 准备并保存一个查询计划以供后续执行。保存的计划会在当前会话的整个生命周期内保留。 准备查询 - 在PL/Tcl中 + 在 PL/Tcl 中 @@ -317,7 +317,7 @@ spi_exec -array C "SELECT * FROM pg_class" { 可选的-nulls值是由空格和'n'字符组成的字符串,用来告诉spi_execp哪些参数是空值。 - 如果给出,它的长度必须与value-list完全相同。如果未给出,则所有参数值都视为非空。 + 如果给出,它的长度必须与value-list完全相同。如果未给出,则所有参数值都视为非空值。 @@ -331,7 +331,7 @@ spi_exec -array C "SELECT * FROM pg_class" { CREATE FUNCTION t1_count(integer, integer) RETURNS integer AS $$ if {![ info exists GD(plan) ]} { - # prepare the saved plan on the first call + # 在首次调用时准备并保存计划 set GD(plan) [ spi_prepare \ "SELECT count(*) AS cnt FROM t1 WHERE num >= \$1 AND num <= \$2" \ [ list int4 int4 ] ] @@ -367,7 +367,7 @@ $$ LANGUAGE pltcl; 将给定字符串中的所有单引号和反斜杠字符都加倍。 - 这可用于安全地引用那些要插入到传给spi_execspi_prepare的 SQL 命令中的字符串。 + 这可用于安全地为那些要插入到传给spi_execspi_prepare的 SQL 命令中的字符串加引号。 例如,考虑如下 SQL 命令字符串: @@ -393,7 +393,7 @@ SELECT 'doesn''t' AS ret "SELECT '[ quote $val ]' AS ret" - spi_execp的一个优点是,你不必像这样对参数值做引用,因为这些参数永远不会作为 SQL 命令字符串的一部分被解析。 + spi_execp的一个优点是,你不必像这样给参数值加引号,因为这些参数永远不会作为 SQL 命令字符串的一部分被解析。 @@ -404,7 +404,7 @@ SELECT 'doesn''t' AS ret elog level msg elog - 在PL/Tcl中 + 在 PL/Tcl 中 @@ -436,8 +436,8 @@ SELECT 'doesn''t' AS ret PL/Tcl 中的触发器函数 - trigger - in PL/Tcl + 触发器 + 在 PL/Tcl 中 @@ -525,7 +525,7 @@ SELECT 'doesn''t' AS ret $NEW - 对于INSERTUPDATE动作,这是一个包含新表行值的关联数组;对于DELETE则为空。该数组以列名为索引。值为 NULL 的列不会出现在数组中。对于语句级触发器,不会设置这个变量。 + 对于INSERTUPDATE动作,这是一个包含新表行值的关联数组;对于DELETE则为空。该数组以列名为索引。值为空值的列不会出现在数组中。对于语句级触发器,不会设置这个变量。 @@ -534,7 +534,7 @@ SELECT 'doesn''t' AS ret $OLD - 对于UPDATEDELETE动作,这是一个包含旧表行值的关联数组;对于INSERT则为空。该数组以列名为索引。值为 NULL 的列不会出现在数组中。对于语句级触发器,不会设置这个变量。 + 对于UPDATEDELETE动作,这是一个包含旧表行值的关联数组;对于INSERT则为空。该数组以列名为索引。值为空值的列不会出现在数组中。对于语句级触发器,不会设置这个变量。 @@ -598,8 +598,8 @@ CREATE TRIGGER trig_mytab_modcount BEFORE INSERT OR UPDATE ON mytab PL/Tcl 中的事件触发器函数 - event trigger - in PL/Tcl + 事件触发器 + 在 PL/Tcl 中 @@ -615,7 +615,7 @@ CREATE TRIGGER trig_mytab_modcount BEFORE INSERT OR UPDATE ON mytab $TG_event - 触发器因其而被触发的事件名称。 + 该触发器所针对的事件名称。 @@ -624,7 +624,7 @@ CREATE TRIGGER trig_mytab_modcount BEFORE INSERT OR UPDATE ON mytab $TG_tag - 触发器因其而被触发的命令标签。 + 该触发器所针对的命令标签。 @@ -632,7 +632,7 @@ CREATE TRIGGER trig_mytab_modcount BEFORE INSERT OR UPDATE ON mytab - 事件触发器函数的返回值会被忽略。 + 触发器函数的返回值会被忽略。 @@ -653,8 +653,8 @@ CREATE EVENT TRIGGER tcl_a_snitch ON ddl_command_start EXECUTE FUNCTION tclsnitc PL/Tcl 中的错误处理 - exceptions - in PL/Tcl + 异常 + 在 PL/Tcl 中 @@ -682,9 +682,9 @@ if {[catch { spi_exec $sql_command }]} { if {[lindex $::errorCode 0] == "POSTGRES"} { array set errorArray $::errorCode if {$errorArray(condition) == "undefined_table"} { - # deal with missing table + # 处理表不存在的情况 } else { - # deal with some other type of SQL error + # 处理其他类型的 SQL 错误 } } } @@ -698,8 +698,8 @@ if {[catch { spi_exec $sql_command }]} { PL/Tcl 中的显式子事务 - subtransactions - in PL/Tcl + 子事务 + 在 PL/Tcl 中 @@ -797,7 +797,7 @@ CALL transaction_test1(); pltcl.start_proc (string) - pltcl.start_proc configuration parameter + pltcl.start_proc 配置参数 @@ -825,7 +825,7 @@ CALL transaction_test1(); pltclu.start_proc (string) - pltclu.start_proc configuration parameter + pltclu.start_proc 配置参数 @@ -844,11 +844,7 @@ CALL transaction_test1(); Tcl 过程名 - 在PostgreSQL中,如果函数位于不同模式中,或者参数个数或参数类型不同,就可以复用同一个函数名。不过,Tcl 要求所有过程名都必须不同。PL/Tcl 处理这一问题的方式是:在内部 Tcl 过程名中包含参数类型名,并在必要时把函数对象 ID(OID)追加到内部 Tcl 过程名后面,以确保它与同一 Tcl 解释器中所有先前已装载的函数名都不同。因此,名称相同但参数类型不同的PostgreSQL函数,也会对应不同的 Tcl 过程。这通常不是 PL/Tcl 程序员需要关心的事情,但在调试时可能会看见。 - - - - 因此,再加上其他一些原因,一个 PL/Tcl 函数不能在 Tcl 内部直接调用另一个 PL/Tcl 函数。如果确实需要这样做,就必须通过 SQL 并使用spi_exec或相关命令来实现。 + 在PostgreSQL中,只要参数个数或参数类型不同,就可以复用同一个函数名。不过,Tcl 要求所有过程名都必须不同。PL/Tcl 处理这一问题的方式是:在内部 Tcl 过程名中包含系统表 pg_proc 中的函数对象 ID 作为其名称的一部分。因此,名称相同但参数类型不同的PostgreSQL函数,也会对应不同的 Tcl 过程。这通常不是 PL/Tcl 程序员需要关心的事情,但在调试时可能会看见。 diff --git a/zh/16/postgres-fdw.sgml b/zh/16/postgres-fdw.sgml index 0c4767a8..3f689ca3 100644 --- a/zh/16/postgres-fdw.sgml +++ b/zh/16/postgres-fdw.sgml @@ -38,7 +38,7 @@ - 对于每个需要被允许访问各外部服务器的数据库用户,使用 + 对于每个需要获准访问各个外部服务器的数据库用户,使用 创建用户映射。将要使用的 远程用户名和密码指定为用户映射的 userpassword 选项。 @@ -56,7 +56,7 @@ - 现在,只需从外部表执行 SELECT,即可访问其底层远程表中 + 现在,只需对外部表执行 SELECT,即可访问其底层远程表中 存储的数据。也可以使用 INSERTUPDATEDELETECOPYTRUNCATE 修改远程表。 @@ -120,8 +120,7 @@ application_name 可以出现在连接选项和 - 中的任一处,或同时出现在 - 二者中。 + 中的任一处,或同时出现在二者中。 如果两者都存在,postgres_fdw.application_name 会覆盖连接设置。与 libpq 不同, postgres_fdw 允许 application_name @@ -172,7 +171,7 @@ OPTIONS (ADD password_required 'false'); password_required=false。还要记住,被映射用户可能 使用 postgres 服务器所运行的系统用户 unix 主目录中的任何客户端证书、 .pgpass.pg_service.conf - 等文件。(有关如何查找主目录的细节,见 。) + 等文件。 他们还可以利用通过 peerident 等认证方式授予的任何信任关系。 @@ -250,7 +249,7 @@ OPTIONS (ADD password_required 'false'); - fdw_startup_cost (floating point) + fdw_startup_cost (浮点数) 该选项可为外部服务器指定,是一个浮点值,会被加到该服务器上任何 @@ -261,13 +260,13 @@ OPTIONS (ADD password_required 'false'); - fdw_tuple_cost (floating point) + fdw_tuple_cost (浮点数) 该选项可为外部服务器指定,是一个浮点值,用作该服务器上外部表扫描的 每个元组的额外代价。它表示服务器之间数据传输的额外开销。可以增大或 减小该数值,以反映到远程服务器更高或更低的网络延迟。默认值为 - 0.2。 + 0.01 @@ -339,7 +338,7 @@ OPTIONS (ADD password_required 'false'); 该选项是一个以逗号分隔的 PostgreSQL 扩展 名称列表,这些扩展必须在本地和远程服务器上都已安装且版本兼容。 - 属于列出扩展且为 immutable 的函数和操作符,将被视为可下推到远程服务器 + 属于列出扩展且不可变的函数和操作符,将被视为可下推到远程服务器 执行。该选项只能为外部服务器指定,不能按表指定。 @@ -381,7 +380,7 @@ OPTIONS (ADD password_required 'false'); - 该选项也适用于向外部表执行 COPY。在这种情况下, + 该选项也适用于向外部表复制数据。在这种情况下, postgres_fdw 实际一次复制的行数会以与插入场景 类似的方式确定,但由于 COPY 命令的实现限制, 最多只能为 1000 行。 @@ -573,8 +572,7 @@ OPTIONS (ADD password_required 'false'); COLLATE 选项。默认值为 true。 如果远程服务器的排序规则名称集合与本地服务器不同,则可能需要关闭此 选项;如果远程服务器运行在不同操作系统上,这种情况尤其可能发生。 - 不过,如果这样做,导入表列的排序规则极有可能与底层数据不匹配, - 从而导致查询行为异常。 + 不过,如果这样做,导入表列的排序规则就存在与底层数据不匹配的严重风险,从而导致查询行为异常。 @@ -661,68 +659,6 @@ OPTIONS (ADD password_required 'false'); - - - use_scram_passthrough (boolean) - - - 该选项控制 postgres_fdw 在连接到外部服务器时 - 是否使用 SCRAM 透传认证。使用 SCRAM 透传认证时, - postgres_fdw 使用 SCRAM 哈希后的凭据,而不是 - 明文用户密码连接远程服务器。这样可以避免在 PostgreSQL 系统目录中 - 存储明文用户密码。 - - - - 要使用 SCRAM 透传认证: - - - - 远程服务器必须请求 scram-sha-256 认证方法; - 否则连接将失败。 - - - - - - 远程服务器可以是任何支持 SCRAM 的 PostgreSQL 版本。 - 对 use_scram_passthrough 的支持只要求客户端 - 一侧(FDW 侧)具备。 - - - - - - 用户映射密码不会被使用。 - - - - - - 运行 postgres_fdw 的服务器与远程服务器, - 必须针对用于在 postgres_fdw 上认证到外部 - 服务器的该用户,拥有完全相同的 SCRAM secret(加密密码) - (盐值和迭代次数都必须相同,而不仅仅是密码相同)。 - - - - 因而,如果要建立到多个主机的 FDW 连接,例如用于分区外部表或分片, - 则所有主机都必须为相关用户保存完全相同的 SCRAM secret。 - - - - - - 发起对外 FDW 连接的 PostgreSQL 实例中,当前会话的传入客户端连接 - 也必须使用 SCRAM 认证。(因此称为透传:SCRAM - 必须在进入和离开时都被使用。)这是 SCRAM 协议的技术要求。 - - - - - - - @@ -731,111 +667,22 @@ OPTIONS (ADD password_required 'false'); 函数 - - postgres_fdw_get_connections( - IN check_conn boolean DEFAULT false, OUT server_name text, - OUT user_name text, OUT valid boolean, OUT used_in_xact boolean, - OUT closed boolean, OUT remote_backend_pid int4) - returns setof record - - - 此函数返回 postgres_fdw 从本地会话到外部服务器所建立的所有打开连接的 - 信息。如果没有打开的连接,则不返回任何记录。 - - - 如果将 check_conn 设置为 true, - 该函数会检查每个连接的状态,并在 closed 列中显示 - 结果。该特性当前仅在支持对 poll 系统调用的非标准 - POLLRDHUP 扩展的系统上可用,包括 Linux。 - 这对于检查事务中使用的所有连接是否仍然打开很有帮助。如果任一连接已经 - 关闭,该事务将无法成功提交,因此在检测到关闭连接后,最好尽快回滚, - 而不是继续执行到末尾。如果函数报告的某个连接同时满足 - used_in_xactclosed 都为 - true,用户即可立即回滚事务。 - - - 此函数的用法示例: + + postgres_fdw_get_connections(OUT server_name text, OUT valid boolean) returns setof record + + + 此函数返回postgres_fdw从本地会话向外部服务器建立的所有打开连接的外部服务器名称。它还返回每个连接是否有效。如果外部服务器连接在当前本地事务中被使用,但其外部服务器或用户映射被更改或删除,则返回false(注意,如果服务器被删除,无效连接的服务器名称将为NULL),然后这样的无效连接将在该事务结束时被关闭。否则返回true。如果没有打开的连接,则不返回任何记录。 + 该函数的用法示例: -postgres=# SELECT * FROM postgres_fdw_get_connections(true); - server_name | user_name | valid | used_in_xact | closed | remote_backend_pid --------------+-----------+-------+--------------+----------------------------- - loopback1 | postgres | t | t | f | 1353340 - loopback2 | public | t | t | f | 1353120 - loopback3 | | f | t | f | 1353156 +postgres=# SELECT * FROM postgres_fdw_get_connections() ORDER BY 1; + server_name | valid +-------------+------- + loopback1 | t + loopback2 | f - 输出列见 。 - - -
- <function>postgres_fdw_get_connections</function> 输出列 - - - - - 类型 - 描述 - - - - - - server_name - text - - 此连接的外部服务器名称。如果服务器已被删除但连接仍保持打开 - (即被标记为无效),则该值为 NULL。 - - - - user_name - text - - 映射到此连接所属外部服务器的本地用户名称;如果使用的是 public - 映射,则为 public。 - 如果用户映射已被删除但连接仍保持打开(即被标记为无效),则该值为 - NULL。 - - - - valid - boolean - - 如果此连接无效,则为假;无效意味着它在当前事务中被使用,但其外部 - 服务器或用户映射已被更改或删除。无效连接将在事务结束时关闭。 - 否则返回真。 - - - - used_in_xact - boolean - - 如果此连接在当前事务中被使用,则为真。 - - - - closed - boolean - - 如果此连接已关闭,则为真,否则为假。如果 - check_conn 被设置为 false, - 或当前平台不提供连接状态检查,则返回 NULL。 - - - - remote_backend_pid - int4 - - 外部服务器上处理此连接的远程后端进程 ID。如果远程后端已终止且 - 连接已关闭(closedtrue), - 此处仍会显示该已终止后端的进程 ID。 - - - - -
- - - +
+ + postgres_fdw_disconnect(server_name text) returns boolean @@ -930,8 +777,7 @@ postgres=# SELECT postgres_fdw_disconnect_all();
- 请注意,postgres_fdw 当前不支持将远程事务预备为 - 两阶段提交。 + 请注意,postgres_fdw 当前不支持为两阶段提交预备远程事务。 @@ -942,9 +788,9 @@ postgres=# SELECT postgres_fdw_disconnect_all(); postgres_fdw 会尽力优化远程查询,以减少从外部 服务器传输的数据量。这是通过将查询的 WHERE 子句发送到 远程服务器执行,以及不获取当前查询不需要的表列来实现的。为降低查询被 - 错误执行的风险,除非 WHERE 子句仅使用内置数据类型、 - 操作符和函数,或属于外部服务器 extensions 选项列出的 - 扩展,否则不会将其发送到远程服务器。这类子句中的操作符和函数还必须是 + 错误执行的风险,只有当 WHERE 子句使用的所有数据类型、 + 操作符和函数都是内置的,或属于外部服务器 extensions + 选项列出的扩展时,才会将该子句发送到远程服务器。这类子句中的操作符和函数还必须是 IMMUTABLE。对于 UPDATEDELETE 查询,postgres_fdw 会在 查询中不存在无法发送到远程服务器的 WHERE 子句、没有 @@ -1029,8 +875,6 @@ postgres=# SELECT postgres_fdw_disconnect_all(); postgres_fdw 可用于最早追溯到 PostgreSQL 8.3 的远程服务器。只读能力可追溯到 8.1。 -
- 不过有一个限制是,postgres_fdw 通常假定: 如果外部表的 WHERE 子句中出现不可变的内置函数和 操作符,那么把它们发送到远程服务器执行是安全的。因此,某个在远程服务器 @@ -1040,51 +884,9 @@ postgres=# SELECT postgres_fdw_disconnect_all(); OFFSET 0 的子 SELECT 中,作为优化 栅栏,并将有问题的函数或操作符放到子 SELECT 之外。 - - 另一个限制是,在外部表上执行 INSERT 语句并带有 - ON CONFLICT DO NOTHING 子句时,远程服务器必须运行 - PostgreSQL 9.5 或更高版本,因为更早版本 - 不支持此特性。 - - - 等待事件 - - - postgres_fdw 可以在等待事件类型 - Extension 下报告以下等待事件: - - - - - PostgresFdwCleanupResult - - - 等待远程服务器上的事务中止。 - - - - - - PostgresFdwConnect - - - 等待与远程服务器建立连接。 - - - - - PostgresFdwGetResult - - - 等待接收来自远程服务器的查询结果。 - - - - - 配置参数 @@ -1094,7 +896,7 @@ postgres=# SELECT postgres_fdw_disconnect_all(); postgres_fdw.application_name (string) - postgres_fdw.application_name configuration parameter + postgres_fdw.application_name 配置参数 @@ -1108,7 +910,7 @@ postgres=# SELECT postgres_fdw_disconnect_all(); postgres_fdw.application_name 可以是任意长度的任意 字符串,甚至可以包含非 ASCII 字符。不过,当它被传递并作为外部服务器中 的 application_name 使用时,请注意它会被截断到少于 - NAMEDATALEN 个字符。所有不可打印 ASCII 字符都会被 + NAMEDATALEN 个字符。除可打印 ASCII 字符以外的所有字符都会被 替换为C 风格的十六进制转义。 有关细节见 。 @@ -1162,7 +964,7 @@ postgres=# SELECT postgres_fdw_disconnect_all(); %% - 字面值 % + 字面字符 % diff --git a/zh/16/postgres.sgml b/zh/16/postgres.sgml index e30061e1..39e6af6b 100644 --- a/zh/16/postgres.sgml +++ b/zh/16/postgres.sgml @@ -114,6 +114,7 @@ &installbin; &installation; + &installw; &runtime; &config; &client-auth; @@ -124,6 +125,7 @@ &backup; &high-availability; &monitoring; + &diskusage; &wal; &logical-replication; &jit; diff --git a/zh/16/protocol.sgml b/zh/16/protocol.sgml index 094b6a82..d89b1d04 100644 --- a/zh/16/protocol.sgml +++ b/zh/16/protocol.sgml @@ -226,11 +226,7 @@ 前端现在必须发送一个 PasswordMessage,其中包含密码;该密码先与用户名一起经过 MD5 加密,再使用 AuthenticationMD5Password 消息中指定的 4 字节随机盐重新加密。如果密码正确,服务器响应 AuthenticationOk;否则响应 ErrorResponse。实际的 PasswordMessage 可以用 SQL 计算:concat('md5', md5(concat(md5(concat(password, username)), random-salt)))。(请记住 md5() 函数返回的是十六进制字符串。) - - - 对 MD5 加密密码的支持已弃用,并将在未来版本 PostgreSQL 中移除。关于迁移到其他密码类型,请参阅 。 - - + @@ -832,7 +828,7 @@ SELCT 1/0;
- 目前,系统会为以下参数发送 ParameterStatus: + 目前,会为一组固定的参数生成 ParameterStatus,参数如下: application_name client_encoding @@ -843,17 +839,14 @@ SELCT 1/0; IntervalStyle is_superuser scram_iterations - search_path server_encoding server_version session_authorization standard_conforming_strings TimeZone - (default_transaction_read_onlyin_hot_standby 在 14 之前不报告; - scram_iterations 在 16 之前不报告; - search_path 在 18 之前不报告。) - 注意 server_versionserver_encodinginteger_datetimes 是启动后不可更改的伪参数。未来该集合可能变化,甚至可能变为可配置。因此,前端应忽略其不理解或不关心的 ParameterStatus。 + (8.0 之前的版本不报告 server_encodingTimeZoneinteger_datetimes;8.1 之前的版本不报告 standard_conforming_strings;8.4 之前的版本不报告 IntervalStyle;9.0 之前的版本不报告 application_name;14 之前的版本不报告 default_transaction_read_onlyin_hot_standby;16 之前的版本不报告 scram_iterations。) + 注意,server_versionserver_encodinginteger_datetimes 是启动后不能改变的伪参数。这组参数将来可能变化,甚至可能变为可配置。因此,前端应直接忽略其不理解或不关心的参数的 ParameterStatus。 @@ -1368,7 +1361,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" CREATE_REPLICATION_SLOT slot_name [ TEMPORARY ] { PHYSICAL | LOGICAL output_plugin } [ ( option [, ...] ) ] - 创建复制槽 + CREATE_REPLICATION_SLOT @@ -1425,14 +1418,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - - FAILOVER [ boolean ] - - - 若为 true,则该复制槽会同步到备库,从而在故障切换后恢复逻辑复制。默认值为 false。 - - - + RESERVE_WAL [ boolean ] @@ -1450,13 +1436,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" SNAPSHOT { 'export' | 'use' | 'nothing' } - - 决定在逻辑复制槽初始化期间如何处理所创建的快照。'export' - 这是默认选项,将导出快照供其他会话使用。此选项不能在事务内使用。 - 'use'将为执行命令的当前事务使用快照。此选项必须在事务中使用, - 并且CREATE_REPLICATION_SLOT必须是在该事务中运行的第一个命令。 - 最后,'nothing'将像往常一样仅用于逻辑解码使用快照,但不会执行其他操作。 - + 决定如何处理初始化逻辑复制槽时创建的快照。默认选项 'export' 会导出快照供其他会话使用,此选项不能在事务内使用。'use' 会将快照用于执行该命令的当前事务;此选项必须在事务内使用,且 CREATE_REPLICATION_SLOT 必须是该事务中执行的第一条命令。最后,'nothing' 只会像平常一样将快照用于逻辑解码,不会对其执行其他操作。 @@ -1487,7 +1467,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" snapshot_name (text) - 该命令导出的快照标识符。该快照在此连接上执行下一条命令之前,或复制连接关闭之前有效。如果所创建的是物理复制槽,则为 null。 + 该命令导出的快照标识符。该快照在此连接上执行下一条命令之前,或复制连接关闭之前有效。如果所创建的是物理复制槽,则为空值。 @@ -1496,7 +1476,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" output_plugin (text) - 新建复制槽所使用的输出插件名称。如果所创建的是物理复制槽,则为 null。 + 新建复制槽所使用的输出插件名称。如果所创建的是物理复制槽,则为空值。 @@ -2029,28 +2009,16 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - - - UPLOAD_MANIFEST - UPLOAD_MANIFEST - - - - 上传备份清单(backup manifest),为执行增量备份做准备。 - - - - + BASE_BACKUP [ ( option [, ...] ) ] BASE_BACKUP - - 指示服务器开始流式传输基本备份。 + 指示服务器开始流式传输基础备份。 在备份开始之前,系统将自动进入备份模式,并在备份完成后退出备份模式。 接受以下选项: @@ -2058,10 +2026,9 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" LABEL 'label' - 设置备份的标签。如果未指定,则将使用base backup作为备份标签。 - 标签的引用规则与打开的标准SQL字符串相同。 + 标签的引号使用规则与打开的标准SQL字符串相同。 @@ -2099,13 +2066,12 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" PROGRESS [ boolean ] - - 如果设置为true,则请求生成进度报告所需的信息。这将在每个表空间的头部发送一个近似大小, + 如果设置为true,则请求生成进度报告所需的信息。这将在每个表空间的首部发送一个近似大小, 可用于计算流式传输的进度。这是通过在传输开始之前先枚举所有文件大小来计算的, 可能会对性能产生负面影响。特别是,在流式传输数据之前可能需要更长的时间。 由于备份期间数据库文件可能会发生变化,因此大小仅为近似值, - 在近似值和实际文件发送之间可能会增长或缩小。默认值为false。 + 在估算与实际发送文件之间的这段时间里可能会增长或缩小。默认值为false。 @@ -2113,9 +2079,8 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" CHECKPOINT { 'fast' | 'spread' } - - 设置在基本备份开始时执行的检查点类型。默认值为spread。 + 设置在基础备份开始时执行的检查点类型。默认值为spread @@ -2123,10 +2088,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" WAL [ boolean ] - - - 如果设置为true,则在备份中包含必要的WAL段。这将包括在开始和停止备份之间的所有文件在基本目录tar文件的pg_wal目录中。默认值为false。 - + 如果设置为 true,则在备份中包含必要的 WAL 段。这会把开始备份到停止备份之间的所有文件放入基础目录 tar 文件内的pg_wal目录中。默认值为 false。 @@ -2212,9 +2174,8 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" VERIFY_CHECKSUMS [ boolean ] - - 如果为true,则在进行基本备份时验证校验和(如果已启用)。如果为false,则跳过此步骤。默认值为true。 + 如果为true,则在进行基础备份时验证校验和(如果已启用)。如果为false,则跳过此步骤。默认值为true。 @@ -2222,14 +2183,13 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" MANIFEST manifest_option - 当指定此选项的值为yesforce-encode时, 将创建一个备份清单并随备份一起发送。该清单是备份中每个文件的列表, 除了可能包含的任何WAL文件。它还存储每个文件的大小、最后修改时间, 以及可选的校验和。 值为force-encode会强制对所有文件名进行十六进制编码; - 否则,仅对文件名为非UTF8八位序列的文件执行此类型的编码。 + 否则,仅对文件名为非 UTF8 字节序列的文件执行此类型的编码。 force-encode主要用于测试目的,以确保读取备份清单的客户端 能够处理这种情况。为了与之前的版本兼容,默认值为MANIFEST 'no' @@ -2249,15 +2209,6 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - - - INCREMENTAL - - - 请求执行增量备份。使用该选项执行基础备份前,必须先执行 UPLOAD_MANIFEST 命令。 - - - @@ -2271,14 +2222,14 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" 第二个普通结果集中的每个表空间都有一行。 - 这一行中的字段是: + 这一行中的字段是: spcoid (oid) - 表空间的OID,如果是基本目录则为null。 + 表空间的OID,如果是基础目录则为null。 @@ -2287,7 +2238,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" spclocation (text) - 表空间目录的完整路径,如果是基本目录则为null。 + 表空间目录的完整路径,如果是基础目录则为null。 @@ -2310,8 +2261,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - - new archive (B) + 新归档 (B) @@ -2338,22 +2288,17 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - String - - - - 对于主数据目录,使用空字符串。对于其他表空间,使用从创建此归档的目录的完整路径。 - - + + 对于主数据目录,使用空字符串。对于其他表空间,使用创建此归档所用目录的完整路径。 + - - manifest (B) + 清单 (B) @@ -2401,8 +2346,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - - progress report (B) + 进度报告 (B) @@ -2460,13 +2404,11 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - - 不记录 WAL 的关系(Unlogged表),除了需要在恢复时重新创建(空的)不记录 WAL 的关系的init fork。 - + 不记录 WAL 的关系,但不包括恢复时重新创建(空的)不记录 WAL 的关系所需的初始化分支。 - pg_wal,包括子目录。如果备份包含WAL文件,则将包含pg_wal的合成版本,但它只包含备份工作所需的文件,而不包含其余内容。 + pg_wal,包括子目录。如果备份包含WAL文件,则将包含pg_wal的合成版本,但它只包含使备份可用所需的文件,而不包含其余内容。 @@ -2479,7 +2421,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 除了常规文件和目录之外的文件,如符号链接(除了上述列出的目录之外的符号链接)以及特殊设备和操作系统文件,将被跳过。(pg_tblspc中的符号链接将被保留。) + 除了普通文件和目录之外的文件,如符号链接(除了上述列出的目录之外的符号链接)以及特殊设备和操作系统文件,将被跳过。(pg_tblspc中的符号链接将被保留。) @@ -2512,7 +2454,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 逻辑复制参数 + 逻辑流复制参数 使用 START_REPLICATION 命令时,pgoutput 接受以下选项: @@ -2527,13 +2469,13 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" 协议版本。目前支持的版本有 1234。必须指定一个有效版本。 - 版本2仅支持服务器版本14及以上,并允许流式传输大型进行中的事务。 + 版本 2 仅在服务器版本 14 及以上受支持,允许流式传输正在进行的大型事务。 - 版本3仅支持服务器版本15及以上,并允许流式传输两阶段提交。 + 版本 3 仅在服务器版本 15 及以上受支持,允许流式传输两阶段提交。 - 版本4仅支持服务器版本 16 及以上,并允许对大型进行中事务的流进行并行应用。 + 版本 4 仅在服务器版本 16 及以上受支持,允许并行应用正在进行的大型事务的流。 @@ -2544,8 +2486,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 用于订阅(接收更改)的发布名称的逗号分隔列表。各个发布名称按标准对象名处理,可按需加引号。 - 至少需要一个发布名称。 + 要订阅(接收变更)的发布名称列表,以逗号分隔。各个发布名称按标准对象名处理,可按需加引号。至少需要一个发布名称。 @@ -2556,7 +2497,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 使用二进制传输模式的布尔选项。二进制模式比文本模式更快,但略微不够稳健。 + 使用二进制传输模式的布尔选项。二进制模式比文本模式更快,但稳健性略差。 @@ -2567,7 +2508,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 一个布尔选项,用于启用发送由 pg_logical_emit_message 写入的消息。 + 布尔选项,用于启用发送由 pg_logical_emit_message 写入的消息。 @@ -2607,9 +2548,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - - 在上述命令中,若参数类型为 boolean,可省略 value 部分;省略等同于指定 TRUE。 - + @@ -3456,58 +3395,45 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - CancelRequest (F) - - Int32 + Int32(16) - - 消息内容的长度(以字节为单位),包括其自身。 + 消息内容的长度,以字节为单位,包括此长度字段本身。 - Int32(80877102) - - 取消请求代码。该值被选择为在最高的16位中包含1234,在最低的16位中包含5678。 - (为避免混淆,此代码不得与任何协议版本号相同。) + 取消请求代码。此值的最高 16 位为 1234,最低 16 位为 5678。(为避免混淆,此代码不能与任何协议版本号相同。) - Int32 - - 目标后端的进程ID。 + 目标后端的进程 ID。 - Int32 - - 目标后端的 secret key。该字段长度由消息总长度决定并延伸至消息末尾,最大长度为 256 字节。 + 目标后端的密钥。 - - 在协议 3.2 之前,secret key 固定为 4 字节。 - @@ -5587,7 +5513,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 严重性: 字段内容为ERROR, FATAL, 或 + 严重性: 字段内容为ERROR, FATAL, 或 PANIC (在错误消息中), 或 WARNING, NOTICE, DEBUG, INFO, 或 LOG (在通知消息中), @@ -5601,7 +5527,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 严重性:字段内容为ERRORFATAL或 + 严重性:字段内容为ERRORFATALPANIC(在错误消息中),或WARNINGNOTICEDEBUGINFOLOG(在通知消息中)。 这与S字段相同,只是内容不会被本地化。仅在由PostgreSQL版本9.6 @@ -5625,7 +5551,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 消息: 主要的人类可读错误消息。 + 消息: 主要的人类可读错误消息。 这应该准确但简洁(通常一行)。 总是存在。 @@ -5647,7 +5573,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 提示: 关于问题应该怎么做的一个可选建议。 + 提示: 关于问题应该怎么做的一个可选建议。 这意在与细节不同,它提供建议(可能不合适)而不是硬性事实。 可能会跨越多行。 @@ -5681,7 +5607,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 内部查询: 一个失败的内部生成命令的文本。 + 内部查询: 一个失败的内部生成命令的文本。 例如,这可能是由PL/pgSQL函数发出的SQL查询。 @@ -5714,7 +5640,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 表名: 如果错误与特定表相关联,则为表的名称。(有关表模式名称的名称,请参考模式名称字段。) + 表名: 如果错误与特定表相关联,则为表的名称。(有关表模式名称的名称,请参考模式名称字段。) @@ -5724,7 +5650,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 列名: 如果错误与特定表列相关联,则为列的名称。(请参考模式和表名字段以识别表。) + 列名: 如果错误与特定表列相关联,则为列的名称。(请参考模式和表名字段以识别表。) @@ -5734,7 +5660,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 数据类型名称: 如果错误与特定数据类型相关联,则为数据类型的名称。 + 数据类型名称: 如果错误与特定数据类型相关联,则为数据类型的名称。 (有关数据类型模式的名称,请参阅模式名称字段。) @@ -5745,7 +5671,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 约束名称: 如果错误与特定约束相关联,则为约束的名称。请参考上面列出的字段,了解相关表或域。 + 约束名称: 如果错误与特定约束相关联,则为约束的名称。请参考上面列出的字段,了解相关表或域。 (为此,即使索引不是使用约束语法创建的,也将其视为约束。) @@ -5756,7 +5682,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 文件: 报告错误的源代码位置的文件名。 + 文件: 报告错误的源代码位置的文件名。 @@ -5894,7 +5820,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 标志; 逻辑解码消息是非事务性的时为0,是事务性的时为1。 + 标志; 逻辑解码消息是非事务性的时为0,是事务性的时为1。 @@ -5968,7 +5894,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 标志; 目前未使用。 + 标志; 目前未使用。 @@ -6666,7 +6592,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 标志; 目前未使用。 + 标志; 目前未使用。 @@ -6744,6 +6670,27 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" + + Int64 (XLogRecPtr) + + + 中止操作的 LSN,仅当 streaming 设置为 parallel 时出现。 + 此字段从协议版本 4 起可用。 + + + + + + Int64 (TimestampTz) + + + 事务的中止时间戳,仅当 streaming 设置为 parallel 时出现。 + 该值为自 PostgreSQL 纪元(2000-01-01)以来的微秒数。 + 此字段从协议版本 4 起可用。 + + + + @@ -6850,7 +6797,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 标志; 目前未使用。 + 标志; 目前未使用。 @@ -6935,7 +6882,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 标志; 目前未使用。 + 标志; 目前未使用。 @@ -7020,7 +6967,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 标志; 目前未使用。 + 标志; 目前未使用。 @@ -7116,7 +7063,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 标志; 目前未使用。 + 标志; 目前未使用。 @@ -7276,76 +7223,36 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 自协议2.0以来的变化总结 + 自协议 2.0 以来的变更总结 - 本节为那些试图将现有客户端库更新到协议3.0的开发人员提供了一个快速变更清单。 + 本节提供一份简要的变更清单,供准备将现有客户端库更新到协议 3.0 的开发者参考。 - - 初始启动数据包使用灵活的字符串列表格式,而不是固定格式。请注意,现在可以直接在启动数据包中指定运行时参数的会话默认值。 - (实际上,以前可以使用options字段来做到这一点,但考虑到options的有限宽度以及缺乏引用值中空格的任何方法,这并不是一种非常安全的技术。) - + 初始启动包采用灵活的字符串列表格式,取代了固定格式。注意,运行时参数的会话默认值现在可以直接在启动包中指定。(实际上,以前也能通过 options 字段实现,但由于 options 的宽度有限,且无法用引号保护值中的空白字符,这种方法并不稳妥。) - - 所有消息现在都在消息类型字节后面立即跟着长度计数(除了启动数据包,它们没有类型字节)。另外请注意,PasswordMessage现在有一个类型字节。 - + 现在,所有消息都在消息类型字节之后紧跟一个长度计数(启动包除外,它没有类型字节)。另请注意,PasswordMessage 现在也有类型字节。 - - ErrorResponse和NoticeResponse('E'和'N') - 消息现在包含多个字段,客户端代码可以从中组装出所需级别的错误消息。请注意, - 单个字段通常不会以换行符结尾,而在旧协议中发送的单个字符串总是以换行符结尾。 - + ErrorResponse 和 NoticeResponse('E' 和 'N')消息现在包含多个字段,客户端代码可以利用这些字段组合出所需详细程度的错误消息。注意,各字段通常不会以换行符结束,而旧协议发送的单个字符串总是以换行符结束。 - - ReadyForQuery('Z')消息包括事务状态指示器。 - + ReadyForQuery('Z')消息包含一个事务状态指示器。 - - 二进制行和数据行消息类型之间的区别已经消失;单个数据行消息类型用于以所有格式返回数据。 - 请注意,DataRow的布局已更改,以使其更容易解析。 - 此外,二进制值的表示已更改:它不再直接与服务器的内部表示形式绑定。 - + BinaryRow 与 DataRow 消息类型不再有区别;单一的 DataRow 消息类型用于返回所有格式的数据。注意,DataRow 的布局已经改变,使其更容易解析。另外,二进制值的表示方式也已改变,不再直接取决于服务器内部的表示方式。 - - 有一个新的扩展查询子协议,它增加了前端消息类型Parse、Bind、Execute、Describe、Close、Flush和Sync, - 以及后端消息类型ParseComplete、BindComplete、PortalSuspended、ParameterDescription、NoData和CloseComplete。 - 现有客户端不必关心这个子协议,但利用它可能会提高性能或功能。 - + 新增了扩展查询子协议,其中增加了前端消息类型 Parse、Bind、Execute、Describe、Close、Flush 和 Sync,以及后端消息类型 ParseComplete、BindComplete、PortalSuspended、ParameterDescription、NoData 和 CloseComplete。现有客户端不必关注这个子协议,但使用它可能有助于改善性能或功能。 - - COPY数据现在封装到CopyData和CopyDone消息中。在COPY期间有一种明确定义的错误恢复方式。 - 特殊的\.最后一行不再需要,并且在COPY OUT期间不发送。 - (在文本模式的COPY IN期间仍然被识别为终止符,但在CSV模式中不会被识别。文本模式中的这种行为已弃用,并且最终可能会被移除。)支持二进制COPY。 - CopyInResponse和CopyOutResponse消息包括指示列数和每列格式的字段。 - + COPY 数据现在封装在 CopyData 和 CopyDone 消息中。COPY 期间的错误恢复已有明确定义的方法。不再需要特殊的最后一行 \.COPY OUT 期间也不再发送它。(在 COPY IN 期间仍会将它识别为终止符,但这种用法已弃用,最终将被移除。)现已支持二进制 COPY。CopyInResponse 和 CopyOutResponse 消息包含了表示列数及各列格式的字段。 - - FunctionCall和FunctionCallResponse消息的布局已更改。 - FunctionCall现在可以支持将NULL参数传递给函数。它还可以处理以文本或二进制格式传递参数和检索结果。 - 不再需要考虑FunctionCall可能存在安全漏洞,因为它不提供对内部服务器数据表示的直接访问。 - + FunctionCall 和 FunctionCallResponse 消息的布局已经改变。FunctionCall 现在支持向函数传递 NULL 参数,也可以使用文本或二进制格式传递参数和取得结果。由于它不再提供对服务器内部数据表示的直接访问,因此也不再有理由将 FunctionCall 视为潜在的安全漏洞。 - - 后端在连接启动期间向客户端库发送ParameterStatus('S')消息,以传达其认为对客户端库有趣的所有参数。 - 随后,每当这些参数中任何一个的活动值发生变化时,都会发送ParameterStatus消息。 - + 在连接启动期间,后端会为其认为客户端库关注的所有参数发送 ParameterStatus('S')消息。之后,只要这些参数中任何一个的当前值发生变化,就会发送一条 ParameterStatus 消息。 - - RowDescription('T')消息携带了描述行的每列的新表OID和列号字段。它还显示了每列的格式代码。 - + RowDescription('T')消息针对所描述行中的每一列,增加了表 OID 和列编号字段,并显示各列的格式代码。 - - CursorResponse('P')消息不再由后端生成。 - + 后端不再生成 CursorResponse('P')消息。 - - NotificationResponse('A')消息有一个额外的字符串字段,可以携带一个有效负载字符串, - 从NOTIFY事件发送者传递过来。 - + NotificationResponse('A')消息增加了一个字符串字段,可以携带 NOTIFY 事件发送者传来的载荷字符串。 - - EmptyQueryResponse('I')消息曾包含一个空字符串参数;现已移除。 - + EmptyQueryResponse('I')消息以前包含一个空字符串参数,现在已将其移除。 diff --git a/zh/16/queries.sgml b/zh/16/queries.sgml index 3293bbb9..7bf86e1e 100644 --- a/zh/16/queries.sgml +++ b/zh/16/queries.sgml @@ -512,7 +512,7 @@ FROM (VALUES ('anne', 'smith'), ('bob', 'jones'), ('joe', 'blow')) - 表函数是那些生成行集合的函数,这些行可以由基本数据类型(标量类型)组成,也可以由复合数据类型(表行)组成。它们在查询的FROM子句中用法类似于表、视图或子查询。表函数返回的列可以像表、视图或子查询的列一样,出现在SELECTJOINWHERE子句中。 + 表函数是那些生成行集合的函数,这些行可以由基础类型(标量类型)组成,也可以由复合数据类型(表行)组成。它们在查询的FROM子句中用法类似于表、视图或子查询。表函数返回的列可以像表、视图或子查询的列一样,出现在SELECTJOINWHERE子句中。 @@ -550,7 +550,7 @@ UNNEST( array_expression , ... - 如果没有提供列的别名,那么对于一个返回基数据类型的函数,列名也与该函数 + 如果没有提供列的别名,那么对于一个返回基础类型的函数,列名也与该函数 名相同。对于一个返回复合类型的函数,结果列会从该类型的属性得到名称。 diff --git a/zh/16/rangetypes.sgml b/zh/16/rangetypes.sgml index f60e0af7..68409fa3 100644 --- a/zh/16/rangetypes.sgml +++ b/zh/16/rangetypes.sgml @@ -209,7 +209,7 @@ SELECT '{[3,7), [8,9)}'::int4multirange; 构造范围和多范围 - 每种范围类型都有一个与范围类型同名的构造函数。使用构造函数通常比书写范围文字常量更方便,因为这样无需对界限值进行额外引用。构造函数接受两个或三个参数。两个参数的形式构造标准形式的范围(下界包含,上界排除),而三个参数的形式则按第三个参数指定的界限形式构造范围。第三个参数必须是下列字符串之一: + 每种范围类型都有一个与范围类型同名的构造函数。使用构造函数通常比书写范围字面量更方便,因为这样无需为界限值额外加引号。构造函数接受两个或三个参数。两个参数的形式构造标准形式的范围(下界包含,上界排除),而三个参数的形式则按第三个参数指定的界限形式构造范围。第三个参数必须是下列字符串之一: ()(][)或者 diff --git a/zh/16/ref/abort.sgml b/zh/16/ref/abort.sgml index 95835c70..caed1f42 100644 --- a/zh/16/ref/abort.sgml +++ b/zh/16/ref/abort.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ABORT 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/allfiles.sgml b/zh/16/ref/allfiles.sgml index 883cd94a..32bc6f0c 100644 --- a/zh/16/ref/allfiles.sgml +++ b/zh/16/ref/allfiles.sgml @@ -202,10 +202,8 @@ PostgreSQL documentation - - @@ -220,7 +218,6 @@ PostgreSQL documentation - diff --git a/zh/16/ref/alter_aggregate.sgml b/zh/16/ref/alter_aggregate.sgml index 6e6d9e05..ce4e87f4 100644 --- a/zh/16/ref/alter_aggregate.sgml +++ b/zh/16/ref/alter_aggregate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER AGGREGATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/alter_collation.sgml b/zh/16/ref/alter_collation.sgml index 85fd5517..c8273dd3 100644 --- a/zh/16/ref/alter_collation.sgml +++ b/zh/16/ref/alter_collation.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER COLLATION 7 - SQL - Language Statements + SQL - 语言语句 @@ -102,7 +102,7 @@ ALTER COLLATION name SET SCHEMA new_sche 注解 - 创建排序规则对象时,该排序规则的提供者特定版本会记录在系统目录中。 + 创建排序规则对象时,会在系统目录中记录由提供程序确定的排序规则版本。 使用该排序规则时,会将当前版本与记录的版本进行比较;如果二者不匹 配,就会发出警告,例如: diff --git a/zh/16/ref/alter_conversion.sgml b/zh/16/ref/alter_conversion.sgml index d6c8e82c..613b3ec3 100644 --- a/zh/16/ref/alter_conversion.sgml +++ b/zh/16/ref/alter_conversion.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER CONVERSION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/alter_database.sgml b/zh/16/ref/alter_database.sgml index 1a68485f..79326c48 100644 --- a/zh/16/ref/alter_database.sgml +++ b/zh/16/ref/alter_database.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER DATABASE 7 - SQL - Language Statements + SQL - 语言语句 @@ -66,7 +66,7 @@ ALTER DATABASE name RESET ALL - 第四种形式更改数据库的默认表空间。只有数据库拥有者或者超级用户可以这样做;你还必须对新表空间具有创建权限。该命令会将数据库旧默认表空间中的所有表和索引在物理上移动到新表空间中。对于该数据库而言,新默认表空间必须为空,并且不能有人连接到该数据库。位于非默认表空间中的表和索引不受影响。复制文件到新表空间的具体实现由服务器内部决定。 + 第四种形式更改数据库的默认表空间。只有数据库拥有者或者超级用户可以这样做;你还必须对新表空间具有创建权限。该命令会将数据库旧默认表空间中的所有表和索引在物理上移动到新表空间中。对于该数据库而言,新默认表空间必须为空,并且不能有人连接到该数据库。位于非默认表空间中的表和索引不受影响。 @@ -90,9 +90,7 @@ ALTER DATABASE name RESET ALL allowconn - - 如果为假,则没有人能连接到这个数据库。 - + 如果为 false,则任何人都不能连接到该数据库。 @@ -109,7 +107,7 @@ ALTER DATABASE name RESET ALL istemplate - 如果为真,则任何具有CREATEDB权限的用户都可以从这个数据库克隆。如果为假,则只有超级用户或者该数据库的拥有者可以克隆它。 + 如果为 true,则任何具有 CREATEDB 权限的用户都可以克隆该数据库;如果为 false,则只有超级用户或该数据库的拥有者可以克隆它。 diff --git a/zh/16/ref/alter_default_privileges.sgml b/zh/16/ref/alter_default_privileges.sgml index 2fca3f17..644de19c 100644 --- a/zh/16/ref/alter_default_privileges.sgml +++ b/zh/16/ref/alter_default_privileges.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER DEFAULT PRIVILEGES 7 - SQL - Language Statements + SQL - 语言语句 @@ -121,7 +121,7 @@ REVOKE [ GRANT OPTION FOR ] - 当前,只有模式、表(包括视图和外部表)、序列、函数、类型(包括域)以及大对象的权限可以修改。 + 当前,只有模式、表(包括视图和外部表)、序列、函数、类型(包括域)的权限可以修改。 对于此命令,函数包括聚合函数和过程。此命令中的FUNCTIONSROUTINES等价。(今后更推荐使用ROUTINES, 因为这是同时指代函数和过程的标准术语。在较早的PostgreSQL版本中, @@ -156,8 +156,8 @@ REVOKE [ GRANT OPTION FOR ] 一个现有模式的名称。如果指定,将修改以后在该模式中创建的对象的默认权限。 如果省略IN SCHEMA,则修改全局默认权限。 - 在为模式和大对象设置权限时,不允许使用IN SCHEMA, - 因为模式不能嵌套,而大对象不属于任何模式。 + 在为模式设置权限时,不允许使用IN SCHEMA, + 因为模式不能嵌套。 diff --git a/zh/16/ref/alter_domain.sgml b/zh/16/ref/alter_domain.sgml index a0fe964c..95aaee6c 100644 --- a/zh/16/ref/alter_domain.sgml +++ b/zh/16/ref/alter_domain.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER DOMAIN 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/alter_event_trigger.sgml b/zh/16/ref/alter_event_trigger.sgml index 326f30e1..b9407346 100644 --- a/zh/16/ref/alter_event_trigger.sgml +++ b/zh/16/ref/alter_event_trigger.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER EVENT TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -58,7 +58,7 @@ ALTER EVENT TRIGGER name RENAME TO new_owner - 该事件触发器的新拥有者的用户名。 + 该事件触发器的新所有者的用户名。 @@ -94,7 +94,7 @@ ALTER EVENT TRIGGER name RENAME TO - 另见 + 参见 diff --git a/zh/16/ref/alter_extension.sgml b/zh/16/ref/alter_extension.sgml index 9471390f..3ceae003 100644 --- a/zh/16/ref/alter_extension.sgml +++ b/zh/16/ref/alter_extension.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER EXTENSION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/alter_foreign_data_wrapper.sgml b/zh/16/ref/alter_foreign_data_wrapper.sgml index 06bdb8be..52dbfc7e 100644 --- a/zh/16/ref/alter_foreign_data_wrapper.sgml +++ b/zh/16/ref/alter_foreign_data_wrapper.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER FOREIGN DATA WRAPPER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/alter_foreign_table.sgml b/zh/16/ref/alter_foreign_table.sgml index 14958ed9..287ffa90 100644 --- a/zh/16/ref/alter_foreign_table.sgml +++ b/zh/16/ref/alter_foreign_table.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER FOREIGN TABLE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/alter_function.sgml b/zh/16/ref/alter_function.sgml index 5de95078..5c9bc999 100644 --- a/zh/16/ref/alter_function.sgml +++ b/zh/16/ref/alter_function.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation ALTER FUNCTION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/alter_group.sgml b/zh/16/ref/alter_group.sgml index 6f8814dc..cf493632 100644 --- a/zh/16/ref/alter_group.sgml +++ b/zh/16/ref/alter_group.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER GROUP 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/alter_index.sgml b/zh/16/ref/alter_index.sgml index 06134114..978d61e1 100644 --- a/zh/16/ref/alter_index.sgml +++ b/zh/16/ref/alter_index.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER INDEX 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/alter_language.sgml b/zh/16/ref/alter_language.sgml index 7af98f20..000fe499 100644 --- a/zh/16/ref/alter_language.sgml +++ b/zh/16/ref/alter_language.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER LANGUAGE 7 - SQL - Language Statements + SQL - 语言语句 @@ -31,8 +31,8 @@ ALTER [ PROCEDURAL ] LANGUAGE name OWNER TO { ALTER LANGUAGE更改一种过程语言的定义。 - 目前唯一的功能是重命名该语言或为其指定新的拥有者。 - 要使用ALTER LANGUAGE,你必须是超级用户或者该语言的拥有者。 + 目前唯一的功能是重命名该语言或为其指定新的所有者。 + 要使用ALTER LANGUAGE,你必须是超级用户或者该语言的所有者。 @@ -62,7 +62,7 @@ ALTER [ PROCEDURAL ] LANGUAGE name OWNER TO { new_owner - 该语言的新拥有者 + 该语言的新所有者 diff --git a/zh/16/ref/alter_large_object.sgml b/zh/16/ref/alter_large_object.sgml index ad3f61f7..be30f848 100644 --- a/zh/16/ref/alter_large_object.sgml +++ b/zh/16/ref/alter_large_object.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER LARGE OBJECT 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/alter_materialized_view.sgml b/zh/16/ref/alter_materialized_view.sgml index 71ac3ade..2ef84a4c 100644 --- a/zh/16/ref/alter_materialized_view.sgml +++ b/zh/16/ref/alter_materialized_view.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER MATERIALIZED VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/alter_opclass.sgml b/zh/16/ref/alter_opclass.sgml index b1872b37..a2228963 100644 --- a/zh/16/ref/alter_opclass.sgml +++ b/zh/16/ref/alter_opclass.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER OPERATOR CLASS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/alter_operator.sgml b/zh/16/ref/alter_operator.sgml index 9537f8e9..81ec7a47 100644 --- a/zh/16/ref/alter_operator.sgml +++ b/zh/16/ref/alter_operator.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER OPERATOR 7 - SQL - Language Statements + SQL - 语言语句 @@ -30,11 +30,7 @@ ALTER OPERATOR name ( { left_typename ( { left_type | NONE } , right_type ) SET ( { RESTRICT = { res_proc | NONE } | JOIN = { join_proc | NONE } - | COMMUTATOR = com_op - | NEGATOR = neg_op - | HASHES - | MERGES - } [, ... ] ) + } [, ... ] )
@@ -122,63 +118,19 @@ ALTER OPERATOR name ( { left_type - - com_op - - - 该操作符的交换子。只有当该操作符当前没有交换子时,才能修改此项。 - - - - - neg_op - - - 该操作符的求反器。只有当该操作符当前没有求反器时,才能修改此项。 - - - - - HASHES - - - 表示该操作符可以支持哈希连接。该属性只能启用,不能禁用。 - - - - - MERGES - - - 表示该操作符可以支持归并连接。该属性只能启用,不能禁用。 - - - - - - - 注解 - - 更多信息请参见和 - 。 - - - 由于交换子总是成对出现、彼此互为交换子, - ALTER OPERATOR SET COMMUTATOR也会把 - com_op的交换子设置为目标操作符。 - 同样,ALTER OPERATOR SET NEGATOR也会把 - neg_op的求反器设置为目标操作符。 - 因此,你不仅必须拥有目标操作符,也必须拥有其交换子或求反器操作符。 - + + + + 示例 @@ -193,16 +145,11 @@ ALTER OPERATOR @@ (text, text) OWNER TO joe; 更改类型int[]上的自定义操作符a && b的 限制和连接选择度估算函数: -ALTER OPERATOR && (int[], int[]) SET (RESTRICT = _int_contsel, JOIN = _int_contjoinsel); +ALTER OPERATOR && (_int4, _int4) SET (RESTRICT = _int_contsel, JOIN = _int_contjoinsel); - - 将&&操作符标记为其自身的交换子: - -ALTER OPERATOR && (int[], int[]) SET (COMMUTATOR = &&); - - + diff --git a/zh/16/ref/alter_opfamily.sgml b/zh/16/ref/alter_opfamily.sgml index a0b755c2..45e5007b 100644 --- a/zh/16/ref/alter_opfamily.sgml +++ b/zh/16/ref/alter_opfamily.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER OPERATOR FAMILY 7 - SQL - Language Statements + SQL - 语言语句 @@ -247,6 +247,9 @@ ALTER OPERATOR FAMILY name USING name RENAME TO ADD和DROP子句则会向发 布中添加或移除一个或多个表或模式。请注意,向已经被订阅的发布中添加 表或模式后,需要在订阅端执行 - ALTER SUBSCRIPTION ... REFRESH PUBLICATION + ALTER SUBSCRIPTION ... REFRESH PUBLICATION 操作后才会生效。还要注意,DROP TABLES IN SCHEMA 不会移除那些通过 - FOR TABLE/ADD TABLE + FOR TABLE/ADD TABLE 指定的模式中的表。 @@ -80,8 +80,8 @@ ALTER PUBLICATION name RENAME TO SET TABLES IN SCHEMA要求调用用户为超级用户。 要更改所有者,你必须能够对新的拥有角色执行SET ROLE, 并且该角色必须在数据库上具有CREATE权限。此外, - FOR ALL TABLES - 或FOR TABLES IN SCHEMA + FOR ALL TABLES + 或FOR TABLES IN SCHEMA 发布的新所有者也必须是超级用户。不过,超级用户可以不受这些限制而更 改发布的所有权。 @@ -148,20 +148,7 @@ ALTER PUBLICATION name RENAME TO 设置的 发布参数。详见该命令的说明。 - - - 更改 publish_via_partition_root 参数可能导致订 - 阅端发生数据丢失或重复,因为它会改变已发布表的标识和模式。请注 - 意,只有当根分区表被指定为复制目标时,才会发生此问题。 - - - 可通过以下方式避免此问题:在执行 - ALTER PUBLICATION ... SET之后、执行 - ALTER SUBSCRIPTION ... REFRESH PUBLICATION - 之前,不修改分区叶子表;并且刷新时仅使用 - copy_data = off选项。 - - + diff --git a/zh/16/ref/alter_role.sgml b/zh/16/ref/alter_role.sgml index 6c719424..2f07f843 100644 --- a/zh/16/ref/alter_role.sgml +++ b/zh/16/ref/alter_role.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation ALTER ROLE 7 - SQL - Language Statements + SQL - 语言语句 @@ -69,9 +69,7 @@ ALTER ROLE { role_specification | A (涵盖了所有可能的属性,但没有用于添加或移除成员资格的选项;为此请使用 GRANTREVOKE。) - 命令中未提及的属性保持原有设置不变。数据库超级用户可以更改任何角色的这些设置,但不能更改 - 引导超级用户的 - SUPERUSER属性。拥有CREATEROLE权限的非超级用户角色也可以更改其中的大多数属性, + 命令中未提及的属性保持原有设置不变。数据库超级用户可以更改任何角色的这些设置。拥有CREATEROLE权限的非超级用户角色也可以更改其中的大多数属性, 但只能更改其已被授予ADMIN OPTION的、非超级用户且非复制角色的这些属性。 非超级用户不能更改SUPERUSER属性;只有其自身也拥有相应属性时,才能更改 CREATEDBREPLICATIONBYPASSRLS属性。 diff --git a/zh/16/ref/alter_routine.sgml b/zh/16/ref/alter_routine.sgml index 4fc3e18d..79191e1e 100644 --- a/zh/16/ref/alter_routine.sgml +++ b/zh/16/ref/alter_routine.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER ROUTINE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/alter_rule.sgml b/zh/16/ref/alter_rule.sgml index 9449d787..9397274c 100644 --- a/zh/16/ref/alter_rule.sgml +++ b/zh/16/ref/alter_rule.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER RULE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/alter_schema.sgml b/zh/16/ref/alter_schema.sgml index 2baf518d..13df793e 100644 --- a/zh/16/ref/alter_schema.sgml +++ b/zh/16/ref/alter_schema.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER SCHEMA 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/alter_sequence.sgml b/zh/16/ref/alter_sequence.sgml index 05ba4edf..a1f6887d 100644 --- a/zh/16/ref/alter_sequence.sgml +++ b/zh/16/ref/alter_sequence.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER SEQUENCE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/alter_server.sgml b/zh/16/ref/alter_server.sgml index 5d870833..b3481a8a 100644 --- a/zh/16/ref/alter_server.sgml +++ b/zh/16/ref/alter_server.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER SERVER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/alter_statistics.sgml b/zh/16/ref/alter_statistics.sgml index 315ff6b7..561ca100 100644 --- a/zh/16/ref/alter_statistics.sgml +++ b/zh/16/ref/alter_statistics.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER STATISTICS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/alter_subscription.sgml b/zh/16/ref/alter_subscription.sgml index 280136f0..add853ce 100644 --- a/zh/16/ref/alter_subscription.sgml +++ b/zh/16/ref/alter_subscription.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER SUBSCRIPTION 7 - SQL - Language Statements + SQL - 语言语句 @@ -59,27 +59,9 @@ ALTER SUBSCRIPTION name RENAME TO < 将该槽与订阅解除关联并删除该订阅。 - - 命令ALTER SUBSCRIPTION ... REFRESH PUBLICATION、 - 带有refresh = true选项的 - ALTER SUBSCRIPTION ... {SET|ADD|DROP} PUBLICATION ...、 - ALTER SUBSCRIPTION ... SET (failover = true|false)以及 - ALTER SUBSCRIPTION ... SET (two_phase = false) - 不能在事务块内执行。 - + 命令ALTER SUBSCRIPTION ... REFRESH PUBLICATION以及带有refresh选项为trueALTER SUBSCRIPTION ... {SET|ADD|DROP} PUBLICATION ...不能在事务块内执行。这些命令在订阅启用了two_phase两阶段提交时也不能执行,除非copy_datafalse。要了解实际的两阶段状态,可参见pg_subscriptionsubtwophasestate列。 + - - 命令ALTER SUBSCRIPTION ... REFRESH PUBLICATION以及 - 带有refresh = true选项的 - ALTER SUBSCRIPTION ... {SET|ADD|DROP} PUBLICATION ..., - 在订阅启用了 - two_phase - 参数时也不能执行,除非 - copy_data - 为false。要了解实际的两阶段状态,可参见 - pg_subscription - 的subtwophasestate列。 - @@ -146,7 +128,7 @@ ALTER SUBSCRIPTION name RENAME TO < 从发布者获取缺失的表信息。这将开始复制自 - CREATE SUBSCRIPTION + CREATE SUBSCRIPTION 或上次执行REFRESH PUBLICATION以来添加到已订阅发布中的表。 @@ -168,13 +150,13 @@ ALTER SUBSCRIPTION name RENAME TO < 关于copy_data = true如何与 - origin + origin 参数相互作用的细节,请参见 关于以二进制格式复制预先存在的数据的细节,请参见 CREATE SUBSCRIPTION的 - binary + binary 参数。 @@ -204,62 +186,7 @@ ALTER SUBSCRIPTION name RENAME TO < SET ( subscription_parameter [= value] [, ... ] ) - - 该子句修改最初由设置的参数。 - 详情请参见该命令。可更改的参数有 - slot_name、 - synchronous_commit、 - binary、 - streaming、 - disable_on_error、 - password_required、 - run_as_owner、 - origin、 - failover - 以及 - two_phase。 - 只有超级用户才能设置password_required = false。 - - - - 更改 - slot_name - 时,所指定槽的failovertwo_phase属性值, - 可能与订阅中相应的 - failover - 和 - two_phase - 参数不同。创建该槽时,应确保槽的failover和 - two_phase属性与订阅中对应的参数一致。否则, - 发布者上的该槽的行为可能与这些订阅选项所表明的不同:例如,即使订阅的 - failover - 选项已禁用,发布者上的该槽仍可能被同步到备库;或者即使订阅的 - failover - 选项已启用,该槽也可能不会被同步到备库。 - - - - 只有在订阅被禁用时,才能更改 - failover - 和 - two_phase - 参数。 - - - - 当将 - two_phase - 从true改为false时,如果发现逻辑复制工作进程 - 在two_phase参数仍为true时执行的任何预备事务, - 后端进程会报告错误。你可以在发布者节点上处理这些预备事务,或者在订阅者上手工回滚 - 它们,然后再次尝试。与特定订阅对应、由逻辑复制工作进程预备的事务具有如下模式: - pg_gid_%u_%u - (参数:订阅oid,远端事务标识xid)。 - 要手工处理这类事务,需要回滚名称中包含相应订阅 ID 的所有预备事务。应用可以检查 - pg_prepared_xacts - 来找出所需的预备事务。在two_phase选项从true - 改为false之后,这些事务在提交时会由发布者再次复制。 - + 该子句修改最初由设置的参数。详情请参见该命令。可更改的参数有slot_namesynchronous_commitbinarystreamingdisable_on_errorpassword_requiredrun_as_ownerorigin。只有超级用户才能设置password_required = false @@ -269,9 +196,7 @@ ALTER SUBSCRIPTION name RENAME TO < 跳过应用远端事务的所有更改。如果传入数据违反任何约束,逻辑复制会停止,直到问题解决。 通过使用ALTER SUBSCRIPTION ... SKIP命令,逻辑复制工作进程会跳过 - 该事务中的所有数据修改操作。若订阅者上启用了 - two_phase, - 则此选项对因在订阅者上启用该参数而已经预备的事务没有作用。逻辑复制工作进程成功跳过该事务或完成一个事务后, + 该事务中的所有数据修改操作。此选项对因在订阅者上启用 two_phase 而已经预备的事务没有作用。逻辑复制工作进程成功跳过该事务或完成一个事务后, LSN(存储在pg_subscription.subskiplsn中) 会被清除。有关逻辑复制冲突的详细信息,请参见 。 diff --git a/zh/16/ref/alter_system.sgml b/zh/16/ref/alter_system.sgml index 176e854a..e843c7b6 100644 --- a/zh/16/ref/alter_system.sgml +++ b/zh/16/ref/alter_system.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER SYSTEM 7 - SQL - Language Statements + SQL - 语言语句 @@ -85,8 +85,7 @@ ALTER SYSTEM RESET ALL - 对于某些接受列表的参数,带引号的值会生成带双引号的输出,以保留空 - 格和逗号;对于另一些参数,则必须在单引号字符串内部使用双引号才能 + 对于某些接受列表的参数,带引号的值会生成带双引号的输出,以保留空白和逗号;对于另一些参数,则必须在单引号字符串内部使用双引号才能 达到这种效果。 @@ -97,22 +96,13 @@ ALTER SYSTEM RESET ALL 注解 - - 不能用这个命令来设置、 - ,以及不允许出现在 - postgresql.conf中的参数(例如 - 预置选项)。 - + 此命令不能用于设置,也不能用于设置postgresql.conf中不允许的参数(例如预设选项)。 关于设置这些参数的其他方法,见 - - 可以通过把设置为 - off来禁用ALTER SYSTEM,但这 - 并不是一种安全机制(该参数的文档中对此有详细说明)。 - + diff --git a/zh/16/ref/alter_table.sgml b/zh/16/ref/alter_table.sgml index 4798657b..2df03e17 100644 --- a/zh/16/ref/alter_table.sgml +++ b/zh/16/ref/alter_table.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TABLE 7 - SQL - Language Statements + SQL - 语言语句 @@ -1011,7 +1011,7 @@ WITH ( MODULUS numeric_literal, REM - 若要强制立即回收已删除列所占的空间,可以执行任何一种会导致整表重写的ALTER TABLE形式。这样会重新构造每一行,并用空值替换被删除的列。 + 若要强制立即回收已删除列所占的空间,可以执行任何一种会导致整表重写的ALTER TABLE形式。这样会重建每一行,并用空值替换被删除的列。 diff --git a/zh/16/ref/alter_tablespace.sgml b/zh/16/ref/alter_tablespace.sgml index f0297481..7369ec94 100644 --- a/zh/16/ref/alter_tablespace.sgml +++ b/zh/16/ref/alter_tablespace.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TABLESPACE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/alter_trigger.sgml b/zh/16/ref/alter_trigger.sgml index 9fc49c8b..874811aa 100644 --- a/zh/16/ref/alter_trigger.sgml +++ b/zh/16/ref/alter_trigger.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -127,7 +127,7 @@ ALTER TRIGGER emp_stamp ON emp DEPENDS ON EXTENSION emplib; - 另见 + 参见 diff --git a/zh/16/ref/alter_tsconfig.sgml b/zh/16/ref/alter_tsconfig.sgml index 7ae05dd5..891dce66 100644 --- a/zh/16/ref/alter_tsconfig.sgml +++ b/zh/16/ref/alter_tsconfig.sgml @@ -13,7 +13,7 @@ PostgreSQL documentation ALTER TEXT SEARCH CONFIGURATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/alter_tsdictionary.sgml b/zh/16/ref/alter_tsdictionary.sgml index 9679697e..163d788b 100644 --- a/zh/16/ref/alter_tsdictionary.sgml +++ b/zh/16/ref/alter_tsdictionary.sgml @@ -13,7 +13,7 @@ PostgreSQL documentation ALTER TEXT SEARCH DICTIONARY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/alter_tsparser.sgml b/zh/16/ref/alter_tsparser.sgml index 525064c9..0844cb0a 100644 --- a/zh/16/ref/alter_tsparser.sgml +++ b/zh/16/ref/alter_tsparser.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TEXT SEARCH PARSER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/alter_tstemplate.sgml b/zh/16/ref/alter_tstemplate.sgml index fa4157f9..a3eec599 100644 --- a/zh/16/ref/alter_tstemplate.sgml +++ b/zh/16/ref/alter_tstemplate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TEXT SEARCH TEMPLATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/alter_type.sgml b/zh/16/ref/alter_type.sgml index 58063799..6c1bc805 100644 --- a/zh/16/ref/alter_type.sgml +++ b/zh/16/ref/alter_type.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation ALTER TYPE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/alter_user.sgml b/zh/16/ref/alter_user.sgml index 362b5518..5a4f5dd4 100644 --- a/zh/16/ref/alter_user.sgml +++ b/zh/16/ref/alter_user.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER USER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/alter_user_mapping.sgml b/zh/16/ref/alter_user_mapping.sgml index 6bbeffc6..b1fc6606 100644 --- a/zh/16/ref/alter_user_mapping.sgml +++ b/zh/16/ref/alter_user_mapping.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER USER MAPPING 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/alter_view.sgml b/zh/16/ref/alter_view.sgml index 020f864b..63fcb79e 100644 --- a/zh/16/ref/alter_view.sgml +++ b/zh/16/ref/alter_view.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/analyze.sgml b/zh/16/ref/analyze.sgml index 1717fc7f..8a934dce 100644 --- a/zh/16/ref/analyze.sgml +++ b/zh/16/ref/analyze.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ANALYZE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/begin.sgml b/zh/16/ref/begin.sgml index 2343e66c..fc8fb312 100644 --- a/zh/16/ref/begin.sgml +++ b/zh/16/ref/begin.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation BEGIN 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/call.sgml b/zh/16/ref/call.sgml index 4a12245b..7dca6405 100644 --- a/zh/16/ref/call.sgml +++ b/zh/16/ref/call.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CALL 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/checkpoint.sgml b/zh/16/ref/checkpoint.sgml index 3cda7713..5e95964c 100644 --- a/zh/16/ref/checkpoint.sgml +++ b/zh/16/ref/checkpoint.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CHECKPOINT 7 - SQL - Language Statements + SQL - 语言语句 @@ -49,7 +49,7 @@ CHECKPOINT 只有超级用户,或者具有 - + pg_checkpoint 角色权限的用户,才能调用CHECKPOINT diff --git a/zh/16/ref/close.sgml b/zh/16/ref/close.sgml index 53c793c4..788e2c9a 100644 --- a/zh/16/ref/close.sgml +++ b/zh/16/ref/close.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation CLOSE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/cluster.sgml b/zh/16/ref/cluster.sgml index f22017f1..fb0c44b0 100644 --- a/zh/16/ref/cluster.sgml +++ b/zh/16/ref/cluster.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CLUSTER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/clusterdb.sgml b/zh/16/ref/clusterdb.sgml index fd83c9ba..ada12058 100644 --- a/zh/16/ref/clusterdb.sgml +++ b/zh/16/ref/clusterdb.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation clusterdb 1 - Application + 应用程序 diff --git a/zh/16/ref/comment.sgml b/zh/16/ref/comment.sgml index baa2f239..5148556c 100644 --- a/zh/16/ref/comment.sgml +++ b/zh/16/ref/comment.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation COMMENT 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/commit.sgml b/zh/16/ref/commit.sgml index 046c6d84..596d1550 100644 --- a/zh/16/ref/commit.sgml +++ b/zh/16/ref/commit.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation COMMIT 7 - SQL - Language Statements + SQL - 语言语句 @@ -39,7 +39,7 @@ COMMIT [ WORK | TRANSACTION ] [ AND [ NO ] CHAIN ] 参数 - chained transactions + 链式事务 diff --git a/zh/16/ref/commit_prepared.sgml b/zh/16/ref/commit_prepared.sgml index dcdba873..734b2833 100644 --- a/zh/16/ref/commit_prepared.sgml +++ b/zh/16/ref/commit_prepared.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation COMMIT PREPARED 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/copy.sgml b/zh/16/ref/copy.sgml index aef76bdf..92dd546b 100644 --- a/zh/16/ref/copy.sgml +++ b/zh/16/ref/copy.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation COPY 7 - SQL - Language Statements + SQL - 语言语句 @@ -497,15 +497,10 @@ COPY count 注解 - - COPY TO可用于普通表和已填充的物化视图。例如, - COPY table TO - 复制的行与 - SELECT * FROM ONLY table - 相同。但它不直接支持其他关系类型,如分区表、继承子表或视图。 - 要复制这类关系的全部行,请使用 - COPY (SELECT * FROM table) TO。 - + COPY TO 只能用于普通表,不能用于视图,且不会复制子表或子分区中的行。例如,COPY table TO 复制的行与 SELECT * FROM ONLY table 相同。语法 COPY (SELECT * FROM table) TO ... 可用于导出继承层次结构、分区表或视图中的所有行。 COPY FROM可用于普通表、外部表、分区表,以及具有 diff --git a/zh/16/ref/create_access_method.sgml b/zh/16/ref/create_access_method.sgml index d4cb6d2c..7f2d9d8e 100644 --- a/zh/16/ref/create_access_method.sgml +++ b/zh/16/ref/create_access_method.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE ACCESS METHOD 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/create_aggregate.sgml b/zh/16/ref/create_aggregate.sgml index 3b890824..252f9fab 100644 --- a/zh/16/ref/create_aggregate.sgml +++ b/zh/16/ref/create_aggregate.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation CREATE AGGREGATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/create_cast.sgml b/zh/16/ref/create_cast.sgml index 1e2c9275..94e78f9e 100644 --- a/zh/16/ref/create_cast.sgml +++ b/zh/16/ref/create_cast.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation CREATE CAST 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/create_collation.sgml b/zh/16/ref/create_collation.sgml index 6bb3f7ab..05eb40a0 100644 --- a/zh/16/ref/create_collation.sgml +++ b/zh/16/ref/create_collation.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE COLLATION 7 - SQL - Language Statements + SQL - 语言语句 @@ -93,12 +93,7 @@ CREATE COLLATION [ IF NOT EXISTS ] name FROM locale,则不能再指定这两个参数中的任何 一个。 - - 如果providerbuiltin, - 则必须指定locale,且其值只能是 - CC.UTF-8或 - PG_UNICODE_FAST。 - + @@ -130,8 +125,7 @@ CREATE COLLATION [ IF NOT EXISTS ] name FROM - 指定与该排序规则关联的区域设置服务所使用的提供者。可能的值是 - builtin、 + 指定与该排序规则关联的区域设置服务所使用的提供程序。可能的值是 icuICU (如果服务器在构建时启用了 ICU 支持)或libc。 默认值是libc。详见name
FROM - 非确定性排序规则仅受 ICU 提供者支持。 + 非确定性排序规则仅受 ICU 提供程序支持。 @@ -238,14 +232,14 @@ CREATE COLLATION french (locale = 'fr_FR.utf8'); - 使用 ICU 提供者并采用德语电话簿排序顺序创建一种排序规则: + 使用 ICU 提供程序并采用德语电话簿排序顺序创建一种排序规则: CREATE COLLATION german_phonebook (provider = icu, locale = 'de-u-co-phonebk'); - 使用 ICU 提供者、基于 ICU 根区域设置并带有自定义规则创建一种排序规 + 使用 ICU 提供程序、基于 ICU 根区域设置并带有自定义规则创建一种排序规 则: diff --git a/zh/16/ref/create_conversion.sgml b/zh/16/ref/create_conversion.sgml index da83218a..3fcb4447 100644 --- a/zh/16/ref/create_conversion.sgml +++ b/zh/16/ref/create_conversion.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE CONVERSION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/create_database.sgml b/zh/16/ref/create_database.sgml index 39446302..8773d5a0 100644 --- a/zh/16/ref/create_database.sgml +++ b/zh/16/ref/create_database.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE DATABASE 7 - SQL - Language Statements + SQL - 语言语句 @@ -29,7 +29,6 @@ CREATE DATABASE name [ LOCALE [=] locale ] [ LC_COLLATE [=] lc_collate ] [ LC_CTYPE [=] lc_ctype ] - [ BUILTIN_LOCALE [=] builtin_locale ] [ ICU_LOCALE [=] icu_locale ] [ ICU_RULES [=] icu_rules ] [ LOCALE_PROVIDER [=] locale_provider ] @@ -131,18 +130,10 @@ CREATE DATABASE name 也可以通过分别设置 、 - 、 - 或 + 来覆盖它。 - - 如果 是 - builtin,则必须指定 - locale 或 - builtin_locale,并将其设为 - CC.UTF-8 或 - PG_UNICODE_FAST之一。 - + 其他区域设置参数 、 @@ -185,23 +176,7 @@ CREATE DATABASE name - - builtin_locale - - - 指定用于数据库默认排序规则和字符分类的 builtin 提供程序区域设置, - 从而覆盖 的设置。 - 区域设置提供程序 - 必须是 builtin。默认值为 - 的设置(如果已指定),否则与模板数据库中的设置相同。 - - - builtin 提供程序可用的区域设置有 - CC.UTF-8 和 - PG_UNICODE_FAST。 - - - + icu_locale @@ -232,8 +207,7 @@ CREATE DATABASE name - 指定该数据库默认排序规则使用的提供程序。可能的值为 builtin、 - icuICU + 指定该数据库默认排序规则使用的提供程序。可能的值为 icuICU (如果服务器构建时启用了 ICU 支持)或 libc。 默认情况下,该值与 的区域设置提供程序相同。详见 @@ -357,7 +331,7 @@ CREATE DATABASE nameLC_CTYPE)兼容。如果区域设置为 C (或等价的 POSIX),则允许所有编码;但对于其他区域设置,只有一种编码能够正常工作。(不过,在 Windows 上,UTF-8 编码可与任何区域设置一起使用。) CREATE DATABASE 允许超级用户不考虑区域设置而指定 - SQL_ASCII 编码,但这种选择已被废弃;如果数据库中存储了与该区域设置不兼容编码的数据,字符串函数的行为可能会出错。 + SQL_ASCII 编码,但这种选择已弃用;如果数据库中存储了与该区域设置不兼容编码的数据,字符串函数的行为可能会出错。 @@ -407,7 +381,7 @@ CREATE DATABASE music TEMPLATE template0; 在这个示例中,如果指定的区域设置与 template1 中的不同, - 则必须使用 TEMPLATE template0 子句。(如果并不不同, + 则必须使用 TEMPLATE template0 子句。(如果相同, 那么显式指定区域设置就是多余的。) diff --git a/zh/16/ref/create_domain.sgml b/zh/16/ref/create_domain.sgml index 905dd30d..420bbf83 100644 --- a/zh/16/ref/create_domain.sgml +++ b/zh/16/ref/create_domain.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE DOMAIN 7 - SQL - Language Statements + SQL - 语言语句 @@ -86,7 +86,7 @@ CREATE DOMAIN name [ AS ] 该域的可选排序规则。如果未指定排序规则,则该域的排序规则行为与其 底层数据类型相同。如果指定了COLLATE,则底层 - 类型必须是一种可排序数据类型。 + 类型必须是一种支持排序规则的数据类型。 diff --git a/zh/16/ref/create_event_trigger.sgml b/zh/16/ref/create_event_trigger.sgml index 0d45c2be..d1bcd047 100644 --- a/zh/16/ref/create_event_trigger.sgml +++ b/zh/16/ref/create_event_trigger.sgml @@ -13,7 +13,7 @@ PostgreSQL documentation CREATE EVENT TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -44,7 +44,7 @@ CREATE EVENT TRIGGER name CREATE EVENT TRIGGER创建一个新的事件触发器。 每当指定的事件发生,并且与该触发器关联的WHEN条件(如果有)得到 满足时,就会执行该触发器函数。有关事件触发器的一般性介绍,见 - 。创建事件触发器的用户将成为其拥有者。 + 。创建事件触发器的用户将成为其所有者。 @@ -83,8 +83,7 @@ CREATE EVENT TRIGGER name - 用于过滤事件的变量名称。这使得可以将触发器限定为只在支持该变量的部 - 分情形下触发。当前唯一支持的 + 用于过滤事件的变量名称。这样可以将触发器限定为只在原本支持的部分情形下触发。当前唯一支持的 filter_variableTAG @@ -142,14 +141,7 @@ CREATE EVENT TRIGGER name - - 在单用户模式(见)下,以及当 - 被设置为false时, - 事件触发器都会被禁用。如果某个错误的事件触发器使数据库严重不可用, - 甚至无法删除该触发器,可以在将 - 设置为false的情况下重启,以临时禁用事件触发器, - 或者以单用户模式重启,这样就可以删除它。 - + 事件触发器在单用户模式下被禁用(参见 )。如果错误的事件触发器导致数据库严重失效,以至于无法删除触发器,可以重启到单用户模式,然后就能执行删除操作。 @@ -194,7 +186,7 @@ CREATE EVENT TRIGGER abort_ddl ON ddl_command_start - 另见 + 参见 diff --git a/zh/16/ref/create_extension.sgml b/zh/16/ref/create_extension.sgml index 6c07a377..7acc3a5e 100644 --- a/zh/16/ref/create_extension.sgml +++ b/zh/16/ref/create_extension.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE EXTENSION 7 - SQL - Language Statements + SQL - 语言语句 @@ -82,10 +82,9 @@ CREATE EXTENSION [ IF NOT EXISTS ] extension_name 要安装的扩展名称。PostgreSQL将根据 - 文件 extension_name.control - 中的详细信息创建该扩展;该文件位于服务器安装目录的 - SHAREDIR/extension 目录中。 + SHAREDIR/extension/extension_name.control + 文件中的详细信息创建该扩展。 @@ -167,7 +166,7 @@ CREATE EXTENSION [ IF NOT EXISTS ] extension_name 会在之后执行编写粗心的扩展脚本时实施攻击,使该用户获得超级用户权限。 不过,只有当特洛伊木马对象在脚本执行期间位于 search_path 中时,它们才会构成危险;这意味着它们 - 位于扩展的安装目标模式中,或位于它所依赖的某个扩展所属的模式中。 + 位于扩展的安装目标模式中,或位于它所依赖的某个扩展的目标模式中。 因此,处理那些脚本尚未经过仔细审查的扩展时,一个经验法则是: 只把它们安装到从未向任何不受信任用户授予、而且今后也不会授予 CREATE 权限的模式中。它们所依赖的任何扩展也应如此。 diff --git a/zh/16/ref/create_foreign_data_wrapper.sgml b/zh/16/ref/create_foreign_data_wrapper.sgml index bfa097ef..0611709d 100644 --- a/zh/16/ref/create_foreign_data_wrapper.sgml +++ b/zh/16/ref/create_foreign_data_wrapper.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE FOREIGN DATA WRAPPER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/create_foreign_table.sgml b/zh/16/ref/create_foreign_table.sgml index 787d3748..5e7768bf 100644 --- a/zh/16/ref/create_foreign_table.sgml +++ b/zh/16/ref/create_foreign_table.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE FOREIGN TABLE 7 - SQL - Language Statements + SQL - 语言语句 @@ -143,9 +143,7 @@ WITH ( MODULUS numeric_literal, REM COLLATE collation - - COLLATE子句为该列(必须是一种可排序数据类型)指定一个排序规则。如果未指定,则使用该列数据类型的默认排序规则。 - + COLLATE子句为列指定排序规则(该列必须属于支持排序规则的数据类型)。如果未指定,则使用列数据类型的默认排序规则。 diff --git a/zh/16/ref/create_function.sgml b/zh/16/ref/create_function.sgml index b6447707..5b894c32 100644 --- a/zh/16/ref/create_function.sgml +++ b/zh/16/ref/create_function.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation CREATE FUNCTION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/create_group.sgml b/zh/16/ref/create_group.sgml index 06195a91..9a6538ed 100644 --- a/zh/16/ref/create_group.sgml +++ b/zh/16/ref/create_group.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE GROUP 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/create_index.sgml b/zh/16/ref/create_index.sgml index 1c525288..cab7ed99 100644 --- a/zh/16/ref/create_index.sgml +++ b/zh/16/ref/create_index.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation CREATE INDEX 7 - SQL - Language Statements + SQL - 语言语句 @@ -57,7 +57,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] PostgreSQL提供了索引方法 - B-树、哈希、GiST、SP-GiST、GIN 以及 BRIN。用户也可以定义自己的索引 + B-树、hash、GiST、SP-GiST、GIN 以及 BRIN。用户也可以定义自己的索引 方法,但这相当复杂。 @@ -123,7 +123,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] 对于临时表,CREATE INDEX始终是非并发的, - 因为没有其他会话可以访问它们,而且非并发创建索引的成本更低。 + 因为没有其他会话可以访问它们,而且非并发创建索引的代价更低。 @@ -373,10 +373,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] 可选的WITH子句为索引指定存储参数。每一种 索引方法都有其各自允许的存储参数集合。 - - - - B-树、哈希、GiST 和 SP-GiST 索引方法都接受以下参数: + B-树、hash、GiST 和 SP-GiST 索引方法都接受以下参数: @@ -390,7 +387,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - 控制索引方法尝试将索引页填充到多满。对于 B-树,在初始构建索引时, + 索引的填充因子是一个百分比,用于确定索引方法尝试将索引页填充到多满。对于 B-树,在初始构建索引时, 以及在右侧扩展索引(加入新的最大键值)时,叶子页都会填充到这一 百分比。如果页面随后变成全满,就会发生分裂,从而导致磁盘上的 索引结构碎片化。B-树默认使用 90 的填充因子,但也可以选择 10 到 @@ -471,7 +468,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - 控制是否使用中描述的缓冲构建技术 + 确定是否使用中描述的缓冲构建技术 来构建索引。设置为OFF时禁用缓冲构建,设置为 ON时启用,设置为AUTO时初始为 禁用,但一旦索引大小达到, @@ -484,7 +481,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - GIN 索引接受以下参数: + GIN 索引接受不同的参数: @@ -498,8 +495,8 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - 控制中描述的快速更新技术的使用。 - ON 启用快速更新,OFF 禁用快速更新。 + 此设置控制中描述的快速更新技术的使用。 + 这是一个布尔参数:ON 启用快速更新,OFF 禁用快速更新。 默认值为ON @@ -528,7 +525,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - 为该索引覆盖的全局设置。 + 自定义参数。 该值以千字节为单位。 @@ -536,7 +533,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - BRIN 索引接受以下参数: + BRIN 索引接受不同的参数: @@ -566,7 +563,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - 定义当在下一页范围检测到插入时,是否为前一页范围排队执行一次提要操作 + 定义当在下一页范围检测到插入时,是否为前一页范围排队执行一次范围摘要操作 (详见)。 默认值为off @@ -580,8 +577,8 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] 并发构建索引 - index - building concurrently + 索引 + 并发构建 @@ -733,11 +730,6 @@ Indexes: 生成这些索引的统计信息。 - - 在 CREATE INDEX 执行期间, - 会被临时设置为 pg_catalog, pg_temp。 - - 对于大多数索引方法,索引的创建速度取决于 的设置。较大的值将会减少 @@ -748,7 +740,7 @@ Indexes: PostgreSQL可以在构建索引时利用多个 CPU, 以便更快处理表中的行。这项特性被称为并行索引构建。 - 对于支持并行构建索引的索引方法(当前为 B-树、GIN 和 BRIN), + 对于支持并行构建索引的索引方法(当前只有 B-树), maintenance_work_mem指定每次索引构建操作整体最多 可使用的内存量,而不管启动了多少工作者进程。通常,代价模型会自动决 定是否需要请求工作者进程,以及请求多少个。 diff --git a/zh/16/ref/create_language.sgml b/zh/16/ref/create_language.sgml index fca9e159..5d737764 100644 --- a/zh/16/ref/create_language.sgml +++ b/zh/16/ref/create_language.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE LANGUAGE 7 - SQL - Language Statements + SQL - 语言语句 @@ -96,7 +96,7 @@ CREATE [ OR REPLACE ] [ TRUSTED ] [ PROCEDURAL ] LANGUAGE name [ DEFAUL 会妨碍优化器识别该查询匹配一个索引。 + + 在PostgreSQL 8.4 之前,OPERATOR子句可以包含RECHECK选项。现在不再支持该选项,因为索引操作符是否有损会在运行时动态确定。这样可以高效处理操作符可能有损也可能无损的情况。 + diff --git a/zh/16/ref/create_operator.sgml b/zh/16/ref/create_operator.sgml index faae3140..9ea345ed 100644 --- a/zh/16/ref/create_operator.sgml +++ b/zh/16/ref/create_operator.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE OPERATOR 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/create_opfamily.sgml b/zh/16/ref/create_opfamily.sgml index 1577f0c1..9d31bb01 100644 --- a/zh/16/ref/create_opfamily.sgml +++ b/zh/16/ref/create_opfamily.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE OPERATOR FAMILY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/create_policy.sgml b/zh/16/ref/create_policy.sgml index 9a5fc65e..d3c49bc8 100644 --- a/zh/16/ref/create_policy.sgml +++ b/zh/16/ref/create_policy.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE POLICY 7 - SQL - Language Statements + SQL - 语言语句 @@ -515,9 +515,7 @@ CREATE POLICY name ON MERGE ... THEN INSERT - - 检查新行  - + 检查新行 diff --git a/zh/16/ref/create_procedure.sgml b/zh/16/ref/create_procedure.sgml index eaa88de6..fe20673f 100644 --- a/zh/16/ref/create_procedure.sgml +++ b/zh/16/ref/create_procedure.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation CREATE PROCEDURE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/create_publication.sgml b/zh/16/ref/create_publication.sgml index fb584413..83da98fe 100644 --- a/zh/16/ref/create_publication.sgml +++ b/zh/16/ref/create_publication.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE PUBLICATION 7 - SQL - Language Statements + SQL - 语言语句 @@ -57,7 +57,7 @@ CREATE PUBLICATION name - name + name 新发布的名称。 @@ -66,7 +66,7 @@ CREATE PUBLICATION name - FOR TABLE + FOR TABLE 指定要加入该发布的表列表。如果在表名前指定了ONLY, @@ -85,12 +85,9 @@ CREATE PUBLICATION name - 指定列列表时,只复制其中列出的列。列列表也可以包含存储生成列。 - 如果省略列列表,则该发布默认复制所有非生成列(包括今后新增的列)。 - 如果将publish_generated_columns设为 - stored,也可以复制存储生成列。指定列列表对 - TRUNCATE命令没有影响。有关列列表的详细信息, - 请参见。 + 指定列列表时,只复制其中列出的列。如果省略列列表,则该发布会复制该表的所有列, + 包括今后新增的列。指定列列表对TRUNCATE命令没有影响。 + 有关列列表的详细信息,请参见 @@ -110,7 +107,7 @@ CREATE PUBLICATION name - FOR ALL TABLES + FOR ALL TABLES 将该发布标记为复制数据库中所有表的更改,包括未来创建的表。 @@ -119,7 +116,7 @@ CREATE PUBLICATION name - FOR TABLES IN SCHEMA + FOR TABLES IN SCHEMA 将该发布标记为复制指定模式列表中所有表的更改,包括未来创建的表。 @@ -143,14 +140,14 @@ CREATE PUBLICATION name - WITH ( publication_parameter [= value] [, ... ] ) + WITH ( publication_parameter [= value] [, ... ] ) 该子句指定发布的可选参数。支持以下参数: - publish (string) + publish (string) 该参数决定新发布会向订阅者发布哪些 DML 操作。其值是一个以逗号分隔的操作列表。 @@ -168,7 +165,7 @@ CREATE PUBLICATION name - publish_via_partition_root (boolean) + publish_via_partition_root (boolean) 该参数控制如何发布分区表(或其任一分区)上的更改。设为 @@ -251,12 +248,7 @@ CREATE PUBLICATION name 操作符、类型和排序规则、系统列引用,或非不可变内置函数。 - - 属于REPLICA IDENTITY的生成列必须被显式发布, - 即要么将其列入列列表,要么启用publish_generated_columns - 选项,这样UPDATEDELETE - 操作才能被发布。 - + 如果指定了FOR TABLES IN SCHEMA,并且该表属于所引用的模式, diff --git a/zh/16/ref/create_role.sgml b/zh/16/ref/create_role.sgml index 1a777c5c..6a992222 100644 --- a/zh/16/ref/create_role.sgml +++ b/zh/16/ref/create_role.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE ROLE 7 - SQL - Language Statements + SQL - 语言语句 @@ -36,8 +36,10 @@ CREATE ROLE name [ [ WITH ] password' | PASSWORD NULL | VALID UNTIL 'timestamp' | IN ROLE role_name [, ...] + | IN GROUP role_name [, ...] | ROLE role_name [, ...] | ADMIN role_name [, ...] + | USER role_name [, ...] | SYSID uid @@ -233,13 +235,7 @@ in sync when changing the above synopsis! 的值是什么,它都会按原样存储(因为系统无法解密指定的已加密密码字符串, 再将其改用其他格式加密)。这样便可在转储/恢复期间重新装载已加密的密码。 - - - 对 MD5 加密密码的支持已被弃用,并将在未来的 - PostgreSQL版本中移除。关于迁移到其他密码类型 - 的细节,参见。 - - + @@ -264,6 +260,14 @@ in sync when changing the above synopsis! + + IN GROUP role_name + + IN GROUPIN ROLE的过时拼写。 + + + + ROLE role_name @@ -288,6 +292,15 @@ in sync when changing the above synopsis! + + USER role_name + + + USER子句是ROLE子句的过时拼写。 + + + + SYSID uid @@ -421,19 +434,9 @@ CREATE ROLE name [ WITH ADMIN PostgreSQL角色。 - - USER子句的行为与ROLE相同,但已经被弃用: - -USER role_name [, ...] - - - - IN GROUP子句的行为与IN ROLE相同,但已经被弃用: - -IN GROUP role_name [, ...] - - + + diff --git a/zh/16/ref/create_rule.sgml b/zh/16/ref/create_rule.sgml index 6d1486c9..e8b37c6d 100644 --- a/zh/16/ref/create_rule.sgml +++ b/zh/16/ref/create_rule.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE RULE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/create_schema.sgml b/zh/16/ref/create_schema.sgml index 74944401..92074e50 100644 --- a/zh/16/ref/create_schema.sgml +++ b/zh/16/ref/create_schema.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE SCHEMA 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/create_sequence.sgml b/zh/16/ref/create_sequence.sgml index ffbf9797..c786a61f 100644 --- a/zh/16/ref/create_sequence.sgml +++ b/zh/16/ref/create_sequence.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation CREATE SEQUENCE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/create_server.sgml b/zh/16/ref/create_server.sgml index 586067b0..0cb4f9ed 100644 --- a/zh/16/ref/create_server.sgml +++ b/zh/16/ref/create_server.sgml @@ -13,7 +13,7 @@ PostgreSQL documentation CREATE SERVER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/create_statistics.sgml b/zh/16/ref/create_statistics.sgml index ecafe6c6..f007156a 100644 --- a/zh/16/ref/create_statistics.sgml +++ b/zh/16/ref/create_statistics.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE STATISTICS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/create_subscription.sgml b/zh/16/ref/create_subscription.sgml index 9311f13b..67eea96f 100644 --- a/zh/16/ref/create_subscription.sgml +++ b/zh/16/ref/create_subscription.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE SUBSCRIPTION 7 - SQL - Language Statements + SQL - 语言语句 @@ -65,7 +65,7 @@ CREATE SUBSCRIPTION subscription_name - subscription_name + subscription_name 新订阅的名称。 @@ -74,7 +74,7 @@ CREATE SUBSCRIPTION subscription_name - CONNECTION 'conninfo' + CONNECTION 'conninfo' 定义如何连接到发布者数据库的libpq连接字符串。 @@ -84,7 +84,7 @@ CREATE SUBSCRIPTION subscription_name - PUBLICATION publication_name [, ...] + PUBLICATION publication_name [, ...] 要订阅的发布者上的发布名称。 @@ -93,7 +93,7 @@ CREATE SUBSCRIPTION subscription_name - WITH ( subscription_parameter [= value] [, ... ] ) + WITH ( subscription_parameter [= value] [, ... ] ) 该子句为订阅指定可选参数。 @@ -105,7 +105,7 @@ CREATE SUBSCRIPTION subscription_name - connect (boolean) + connect (boolean) 指定CREATE SUBSCRIPTION命令是否连接到 @@ -120,7 +120,7 @@ CREATE SUBSCRIPTION subscription_name 由于该选项为false时不会建立连接,因此不会订阅任何表。 - 要启动复制,你必须手工创建复制槽、在需要时启用故障切换、启用订阅, + 要启动复制,你必须手工创建复制槽、启用订阅, 并刷新订阅。示例见 @@ -128,7 +128,7 @@ CREATE SUBSCRIPTION subscription_name - create_slot (boolean) + create_slot (boolean) 指定该命令是否应在发布者上创建复制槽。默认值为 @@ -143,7 +143,7 @@ CREATE SUBSCRIPTION subscription_name - enabled (boolean) + enabled (boolean) 指定订阅是应当主动进行复制,还是仅完成设置但暂不启动。 @@ -153,7 +153,7 @@ CREATE SUBSCRIPTION subscription_name - slot_name (string) + slot_name (string) 要使用的发布者上的复制槽名称。默认使用订阅名称作为槽名。 @@ -167,17 +167,7 @@ CREATE SUBSCRIPTION subscription_name。 - - 将slot_name设为有效名称且 - create_slot设为false时, - 所指定复制槽的failover属性值可能与订阅中对应的 - failover参数不同。应始终确保该槽的 - failover属性与订阅中的对应参数一致,反之亦然。 - 否则,发布者上的该槽的行为可能与这些订阅选项所表明的不同:例如, - 即使订阅的failover选项已禁用,发布者上的该槽仍可能 - 被同步到备库;或者即使订阅的failover选项已启用, - 该槽也可能不会被同步到备库。 - + @@ -189,7 +179,7 @@ CREATE SUBSCRIPTION subscription_name - binary (boolean) + binary (boolean) 指定订阅是否请求发布者以二进制格式(而不是文本格式)发送数据。 @@ -221,7 +211,7 @@ CREATE SUBSCRIPTION subscription_name - copy_data (boolean) + copy_data (boolean) 指定复制开始时是否复制所订阅发布中的预先存在的数据。 @@ -239,39 +229,30 @@ CREATE SUBSCRIPTION subscription_name - - streaming (enum) + + streaming (enum) - 指定是否为该订阅启用进行中事务的流式传输。默认值为 - parallel,表示如果有可用的并行应用工作进程, - 接收到的更改会直接通过其中之一应用。如果没有空闲的并行应用工作进程 - 可以处理流式事务,那么这些更改会写入临时文件,并在事务提交后再应用。 - 注意,如果并行应用工作进程中发生错误,远端事务的 finish LSN - 可能不会记录到服务器日志中。 + 指定是否为该订阅启用进行中事务的流式传输。默认值为 off, + 表示所有事务都会先在发布者上完全解码,然后才整体发送给订阅者。 - - - 当发布者与订阅者的模式不同时,存在发生死锁的风险,尽管这种情况 - 很少见。应用工作进程会自动重试这些事务。 - - - - 如果设为on,接收到的更改会写入临时文件,然后仅在 - 事务在发布者上提交且被订阅者接收之后才应用。 + 如果设为 on,接收到的更改会写入临时文件,然后仅在事务 + 在发布者上提交且被订阅者接收之后才应用。 - 如果设为off,所有事务都会先在发布者上完全解码, - 然后才整体发送给订阅者。 + 如果设为 parallel,接收到的更改会直接通过可用的并行应用工作进程应用。 + 如果没有空闲的并行应用工作进程可以处理流式事务,那么这些更改会写入临时文件, + 并在事务提交后再应用。注意,如果并行应用工作进程中发生错误,远端事务的完成 LSN + 可能不会记录到服务器日志中。 - synchronous_commit (enum) + synchronous_commit (enum) 该参数的值会覆盖此订阅应用工作进程中的 @@ -296,8 +277,8 @@ CREATE SUBSCRIPTION subscription_name - - two_phase (boolean) + + two_phase (boolean) 指定是否为该订阅启用两阶段提交。默认值为 @@ -323,8 +304,8 @@ CREATE SUBSCRIPTION subscription_name - - disable_on_error (boolean) + + disable_on_error (boolean) 指定如果订阅工作进程在从发布者复制数据期间检测到任何错误,是否自动 @@ -334,7 +315,7 @@ CREATE SUBSCRIPTION subscription_name - password_required (boolean) + password_required (boolean) 如果设为true,则由于该订阅而建立的到发布者的连接 @@ -346,7 +327,7 @@ CREATE SUBSCRIPTION subscription_name - run_as_owner (boolean) + run_as_owner (boolean) 如果为true,所有复制操作都以订阅所有者的身份执行。 @@ -359,7 +340,7 @@ CREATE SUBSCRIPTION subscription_name - origin (string) + origin (string) 指定订阅是请求发布者仅发送没有复制源的更改,还是无论复制源如何都发送更改。 @@ -376,15 +357,7 @@ CREATE SUBSCRIPTION subscription_name - - failover (boolean) - - - 指定与该订阅关联的复制槽是否启用同步到备库,以便在故障切换后 - 能够从新的主库继续逻辑复制。默认值为false。 - - - + @@ -432,15 +405,15 @@ CREATE SUBSCRIPTION subscription_nameWHERE子句,如果其中某个发布没有 WHERE子句(针对相应的发布操作),或者该发布被声明为 - FOR ALL TABLES + FOR ALL TABLES 或 - FOR TABLES IN SCHEMA, + FOR TABLES IN SCHEMA, 则无论其他表达式如何定义,该行都会被发布。如果订阅者使用的是 15 之前 版本的PostgreSQL,那么在初始数据同步阶段 会忽略所有行过滤。在这种情况下,用户可能需要考虑删除那些初始复制过来、 但与后续过滤不兼容的数据。由于初始数据同步在复制现有表数据时不会考虑 发布的 - publish + publish 参数,因此有些使用 DML 时本不会复制的行,也可能在此阶段被复制。示例见 diff --git a/zh/16/ref/create_table.sgml b/zh/16/ref/create_table.sgml index a9af2bcb..0fbd5c15 100644 --- a/zh/16/ref/create_table.sgml +++ b/zh/16/ref/create_table.sgml @@ -4,7 +4,6 @@ PostgreSQL documentation --> - CREATE TABLE @@ -12,7 +11,7 @@ PostgreSQL documentation CREATE TABLE 7 - SQL - Language Statements + SQL - 语言语句 @@ -59,56 +58,55 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI [ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ] [ TABLESPACE tablespace_name ] -where column_constraint is: +其中column_constraint为: [ CONSTRAINT constraint_name ] -{ NOT NULL [ NO INHERIT ] | +{ NOT NULL | NULL | CHECK ( expression ) [ NO INHERIT ] | DEFAULT default_expr | - GENERATED ALWAYS AS ( generation_expr ) [ STORED | VIRTUAL ] | + GENERATED ALWAYS AS ( generation_expr ) STORED | GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( sequence_options ) ] | UNIQUE [ NULLS [ NOT ] DISTINCT ] index_parameters | PRIMARY KEY index_parameters | REFERENCES reftable [ ( refcolumn ) ] [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE referential_action ] [ ON UPDATE referential_action ] } -[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ] [ ENFORCED | NOT ENFORCED ] +[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ] -and table_constraint is: +table_constraint为: [ CONSTRAINT constraint_name ] { CHECK ( expression ) [ NO INHERIT ] | - NOT NULL column_name [ NO INHERIT ] | - UNIQUE [ NULLS [ NOT ] DISTINCT ] ( column_name [, ... ] [, column_name WITHOUT OVERLAPS ] ) index_parameters | - PRIMARY KEY ( column_name [, ... ] [, column_name WITHOUT OVERLAPS ] ) index_parameters | + UNIQUE [ NULLS [ NOT ] DISTINCT ] ( column_name [, ... ] ) index_parameters | + PRIMARY KEY ( column_name [, ... ] ) index_parameters | EXCLUDE [ USING index_method ] ( exclude_element WITH operator [, ... ] ) index_parameters [ WHERE ( predicate ) ] | - FOREIGN KEY ( column_name [, ... ] [, PERIOD column_name ] ) REFERENCES reftable [ ( refcolumn [, ... ] [, PERIOD refcolumn ] ) ] + FOREIGN KEY ( column_name [, ... ] ) REFERENCES reftable [ ( refcolumn [, ... ] ) ] [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE referential_action ] [ ON UPDATE referential_action ] } -[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ] [ ENFORCED | NOT ENFORCED ] +[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ] -and like_option is: +like_option为: { INCLUDING | EXCLUDING } { COMMENTS | COMPRESSION | CONSTRAINTS | DEFAULTS | GENERATED | IDENTITY | INDEXES | STATISTICS | STORAGE | ALL } -and partition_bound_spec is: +partition_bound_spec为: IN ( partition_bound_expr [, ...] ) | FROM ( { partition_bound_expr | MINVALUE | MAXVALUE } [, ...] ) TO ( { partition_bound_expr | MINVALUE | MAXVALUE } [, ...] ) | WITH ( MODULUS numeric_literal, REMAINDER numeric_literal ) -index_parameters in UNIQUE, PRIMARY KEY, and EXCLUDE constraints are: +UNIQUEPRIMARY KEYEXCLUDE约束中的index_parameters为: [ INCLUDE ( column_name [, ... ] ) ] [ WITH ( storage_parameter [= value] [, ... ] ) ] [ USING INDEX TABLESPACE tablespace_name ] -exclude_element in an EXCLUDE constraint is: +EXCLUDE约束中的exclude_element为: { column_name | ( expression ) } [ COLLATE collation ] [ opclass [ ( opclass_parameter = value [, ... ] ) ] ] [ ASC | DESC ] [ NULLS { FIRST | LAST } ] -referential_action in a FOREIGN KEY/REFERENCES constraint is: +FOREIGN KEY/REFERENCES 约束中的 referential_action 为: { NO ACTION | RESTRICT | CASCADE | SET NULL [ ( column_name [, ... ] ) ] | SET DEFAULT [ ( column_name [, ... ] ) ] } @@ -148,16 +146,13 @@ WITH ( MODULUS numeric_literal, REM - 参数 - - TEMPORARY or TEMP + TEMPORARYTEMP - 如果指定该选项,表将创建为临时表。 临时表会在会话结束时自动删除,或者也可在当前事务结束时删除(见下文 ON COMMIT)。 @@ -170,7 +165,7 @@ WITH ( MODULUS numeric_literal, REM - 可以在 TEMPORARYTEMP 前写 GLOBALLOCAL。这在当前的 PostgreSQL 中没有区别,而且已废弃;见下文 。 + 可以在 TEMPORARYTEMP 前写 GLOBALLOCAL。这在当前的 PostgreSQL 中没有区别,而且已弃用;见下文 @@ -178,7 +173,6 @@ WITH ( MODULUS numeric_literal, REM UNLOGGED - 如果指定该选项,表将创建为不记录 WAL 的表。写入不记录 WAL 的表的数据不会写入预写式日志(见 ),因此它们比普通表快得多。不过,它们不具备崩溃安全性:在崩溃或非正常关闭后,不记录 WAL 的表会被自动截断。不记录 WAL 的表的内容也不会复制到备库。在不记录 WAL 的表上创建的任何索引也都会自动成为不记录 WAL 的。 @@ -186,10 +180,6 @@ WITH ( MODULUS numeric_literal, REM 如果指定该选项,与不记录 WAL 的表一起创建的任何序列(用于标识列或 serial 列)也会创建为不记录 WAL 的。 - - - 这种形式不支持分区表。 - @@ -216,14 +206,9 @@ WITH ( MODULUS numeric_literal, REM OF type_name + 创建一个类型化表,其结构取自指定的复合类型(名称可以带模式限定)。类型化表与其类型绑定;例如,如果删除该类型(使用DROP TYPE ... CASCADE),该表也会被删除。 - - 创建一个类型化表,其结构取自指定的独立复合类型(即通过 创建的类型),同时该表自身也会生成一个新的复合类型。该表会依赖于所引用的类型,这意味着对该类型执行级联的 ALTER 或 DROP 操作会传播到该表。 - - - - 类型化表的列名和数据类型始终与其派生类型相同,因此不能再指定额外的列。但 CREATE TABLE 命令仍可为该表添加默认值和约束,并指定存储参数。 - + 创建类型化表时,列的数据类型由底层复合类型决定,不由CREATE TABLE命令指定。不过,CREATE TABLE命令可以为表添加默认值和约束,并指定存储参数。 @@ -252,11 +237,7 @@ WITH ( MODULUS numeric_literal, REM COLLATE collation - - - COLLATE 子句为该列(必须是一种可排序数据类型)赋予一个排序规则。 - 如果没有指定,将使用该列数据类型的默认排序规则。 - + COLLATE子句为列指定排序规则(该列必须属于支持排序规则的数据类型)。如果未指定,则使用列数据类型的默认排序规则。 @@ -265,7 +246,7 @@ WITH ( MODULUS numeric_literal, REM STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN | DEFAULT } TOAST - per-column storage settings + 逐列存储设置 @@ -335,7 +316,6 @@ WITH ( MODULUS numeric_literal, REM PARTITION BY { RANGE | LIST | HASH } ( { column_name | ( expression ) } [ opclass ] [, ...] ) - 可选的 PARTITION BY 子句指定表的分区策略。 这样创建的表称为分区表。 @@ -356,6 +336,8 @@ WITH ( MODULUS numeric_literal, REM 如果没有现有分区与新行中的值匹配,就会报错。 + 分区表不支持EXCLUDE约束;不过,可以在各个分区上定义这些约束。 + 有关表分区的更多讨论,请参阅 @@ -366,7 +348,6 @@ WITH ( MODULUS numeric_literal, REM PARTITION OF parent_table { FOR VALUES partition_bound_spec | DEFAULT } - 将该表创建为指定父表的分区。 可以使用 FOR VALUES 将其创建为特定值的分区,也可以使用 DEFAULT 创建为默认分区。 @@ -424,13 +405,13 @@ WITH ( MODULUS numeric_literal, REM 还要注意,某些元素类型(如 timestamp)具有 - "infinity" 的概念,那只是另一种可存储的值。这不同于 + “无穷大” 的概念,那只是另一种可存储的值。这不同于 MINVALUEMAXVALUE,后两者并非可存储 的实际值,而只是表示值无界的方式。MAXVALUE 可以视为大于任何 - 其他值,包括 "infinity";MINVALUE 可以视为小于任何 - 其他值,包括 "minus infinity"。因此,范围 + 其他值,包括 “无穷大”;MINVALUE 可以视为小于任何 + 其他值,包括 “负无穷大”。因此,范围 FROM ('infinity') TO (MAXVALUE) 并不是空范围;它只允许存储 - 一个值 — "infinity"。 + 一个值 — “无穷大”。 @@ -488,19 +469,15 @@ WITH ( MODULUS numeric_literal, REM LIKE source_table [ like_option ... ] - LIKE 子句指定一个表,新表会自动从中复制所有列名、数据类型及其非空约束。 - INHERITS 不同,新表和原表在创建完成后就完全脱钩了。对原表的修改不会应用到新表,也不可能在扫描原表时包含新表的数据。 - 同样与 INHERITS 不同,由 LIKE 复制的列和约束不会与同名的列和约束合并。如果同一名称被显式指定,或在另一个 LIKE 子句中指定,则会报错。 - 可选的 like_option 子句指定还要复制原表的哪些附加属性。 指定 INCLUDING 表示复制该属性,指定 EXCLUDING 表示省略该属性。默认是 EXCLUDING。 @@ -548,7 +525,7 @@ WITH ( MODULUS numeric_literal, REM INCLUDING GENERATED - 会复制被复制列定义中的生成表达式以及 STORED/VIRTUAL 的选择。默认情况下,新列将是常规基表列。 + 会复制被复制列定义中的生成表达式。默认情况下,新列将是普通基础列。 @@ -621,16 +598,11 @@ WITH ( MODULUS numeric_literal, REM - NOT NULL [ NO INHERIT ] + NOT NULL - 该列不允许包含空值。 - - - 标记为 NO INHERIT 的约束不会传播到子表。 - @@ -651,7 +623,6 @@ WITH ( MODULUS numeric_literal, REM CHECK ( expression ) [ NO INHERIT ] - CHECK 子句指定一个产生布尔结果的表达式。要使插入或更新成功,新行或更新后的行必须满足该表达式。计算结果为 TRUE 或 UNKNOWN 的表达式视为成功。如果插入或更新操作中的任何一行得到 FALSE 结果,就会抛出错误异常,并且插入或更新不会修改数据库。作为列约束指定的检查约束只应引用该列的值,而出现在表约束中的表达式可以引用多个列。 @@ -661,7 +632,7 @@ WITH ( MODULUS numeric_literal, REM - 一个被标记为NO INHERIT的约束将不会传播到子表。 + 标记为 NO INHERIT 的约束不会传播到子表。 @@ -687,25 +658,17 @@ WITH ( MODULUS numeric_literal, REM - - GENERATED ALWAYS AS ( generation_expr ) [ STORED | VIRTUAL ]generated column + GENERATED ALWAYS AS ( generation_expr ) STORED生成列 - 此子句将列创建为生成列。列不可写入,读取时会返回指定表达式的结果。 - - 指定 VIRTUAL 时,列会在读取时计算且不占用存储;指定 STORED 时,列会在写入时计算并存储在磁盘上。默认是 VIRTUAL。 - + 必须使用关键字STORED,表示该列将在写入时计算并存储在磁盘上。 生成表达式可以引用表中的其他列,但不能引用其他生成的列。使用的任何函数和操作符都必须是不可变的。不允许引用其他表。 - - - 虚拟生成列不能使用用户定义类型,且其生成表达式不得引用用户定义函数或类型,也就是只能使用内置函数或类型。此限制也包含间接使用(例如操作符或类型转换背后的函数或类型)。该限制不适用于存储型生成列。 - @@ -746,38 +709,17 @@ WITH ( MODULUS numeric_literal, REM - UNIQUE [ NULLS [ NOT ] DISTINCT ](列约束) - - - UNIQUE [ NULLS [ NOT ] DISTINCT ] ( column_name [, ... ] [, column_name WITHOUT OVERLAPS ] ) - INCLUDE ( column_name [, ...]) (表约束) - + UNIQUE [ NULLS [ NOT ] DISTINCT ] ( column_name [, ... ] ) + INCLUDE ( column_name [, ...]) (表约束) - UNIQUE 约束指定表中一列或多列组成的一组只能包含唯一值。 表级唯一约束的行为与列级唯一约束相同,只是它还能跨越多列。因此,该约束 要求任意两行在这些列中至少有一列不同。 - - 如果为最后一列指定了 WITHOUT OVERLAPS 选项,则该列检查的 - 是是否重叠,而不是是否相等。在这种情况下,只要重复值在 - WITHOUT OVERLAPS 列上不发生重叠,约束中的其他列就允许重 - 复。(如果该列是日期或时间戳范围,这有时被称为时态键;但 - PostgreSQL 允许在任意基础类型上定义范围。) - 实际上,这种约束是通过 EXCLUDE 约束而不是 - UNIQUE 约束来强制的。例如, - UNIQUE (id, valid_at WITHOUT OVERLAPS) 的行为类似于 - EXCLUDE USING GIST (id WITH =, valid_at WITH &&)。 - WITHOUT OVERLAPS 列必须是范围类型或多范围类型,且不允许 - 为空范围或空多范围。该约束中不带 WITHOUT OVERLAPS 的列可以 - 是任何可在 GiST 索引中按相等性比较的类型。默认仅支持范围类型,但可通过安装 - 扩展来使用其他类型(这也是该特性的预期用法)。 - - 就唯一约束而言,空值不被视为相等,除非指定了 NULLS NOT DISTINCT。 @@ -787,20 +729,17 @@ WITH ( MODULUS numeric_literal, REM 每个唯一约束都应引用一组列,这组列应不同于该表上任何其他唯一约束或 主键约束所引用的列集合。(否则,冗余的唯一约束将被丢弃。) + 在为多级分区层次结构建立唯一约束时,目标分区表分区键中的所有列,以及 其所有后代分区表分区键中的所有列,都必须包含在约束定义中。 - - 添加唯一约束会自动在约束所用的列或列组上创建唯一 B-树索引;但如果该约束 - 包含 WITHOUT OVERLAPS 子句,则会使用 GiST 索引。所创建 - 的索引与该唯一约束同名。 - + 添加唯一约束会自动在约束所用的列或列组上创建唯一 B-树索引。 可选的 INCLUDE 子句会向该索引添加一个或多个仅作为 - payload 的列:对这些列不强制唯一性,而且该索引也不能据此 + 载荷 的列:对这些列不强制唯一性,而且该索引也不能据此 进行搜索。不过,它们可以通过仅索引扫描取回。注意,尽管约束不在包含列上 强制执行,它仍然依赖于这些列。因此,对这类列执行某些操作(例如 DROP COLUMN)可能导致约束和索引被级联删除。 @@ -809,13 +748,10 @@ WITH ( MODULUS numeric_literal, REM - PRIMARY KEY(列约束) - - PRIMARY KEY ( column_name [, ... ] [, column_name WITHOUT OVERLAPS ] ) - INCLUDE ( column_name [, ...]) (表约束) + PRIMARY KEY ( column_name [, ... ] ) + INCLUDE ( column_name [, ...]) (表约束) - PRIMARY KEY 约束指定表的一列或多列只能包含唯一 (不重复)且非空的值。无论作为列约束还是表约束,一个表都只能指定一个 @@ -841,13 +777,11 @@ WITH ( MODULUS numeric_literal, REM 添加 PRIMARY KEY 约束会自动在约束所用的列或列组上创建 - 唯一 B-树索引;如果指定了 WITHOUT OVERLAPS,则会创建 - GiST 索引。 - + 唯一 B-树索引。 可选的 INCLUDE 子句会向该索引添加一个或多个仅作为 - payload 的列:对这些列不强制唯一性,而且该索引也不能据此 + 载荷 的列:对这些列不强制唯一性,而且该索引也不能据此 进行搜索。不过,它们可以通过仅索引扫描取回。注意,尽管约束不在包含列上 强制执行,它仍然依赖于这些列。因此,对这类列执行某些操作(例如 DROP COLUMN)可能导致约束和索引被级联删除。 @@ -858,7 +792,6 @@ WITH ( MODULUS numeric_literal, REM EXCLUDE [ USING index_method ] ( exclude_element WITH operator [, ... ] ) index_parameters [ WHERE ( predicate ) ] - EXCLUDE 子句定义一个排他约束。它保证如果任意两行在 指定列或表达式上使用指定操作符进行比较,这些比较不会全部返回 @@ -871,7 +804,7 @@ WITH ( MODULUS numeric_literal, REM - 排他约束通过一个与约束同名的索引来实现,因此每个指定操作符都必须与 + 排他约束通过索引来实现,因此每个指定操作符都必须与 索引访问方法 index_method 的适当操作符类关联 (见 )。每个 exclude_element 都定义了索引的一 @@ -883,7 +816,7 @@ WITH ( MODULUS numeric_literal, REM 访问方法必须支持 amgettuple(见 );目前这意味着不能使用 GIN。 虽然允许,但在排他约束上使用 B-树或 hash 索引意义不大,因为它们做不到 - 比普通唯一约束更好的事情。因此,实践中访问方法几乎总会是 + 比普通唯一约束更好的事情。因此,实践中访问方法总是 GiSTSP-GiST @@ -892,67 +825,21 @@ WITH ( MODULUS numeric_literal, REM 子集上指定排他约束;在内部,这会创建一个部分索引。注意, predicate 周围的圆括号是必需的。 - - 在为多级分区层次结构建立排他约束时,目标分区表分区键中的所有列,以及其 - 所有后代分区表分区键中的所有列,都必须包含在约束定义中。此外,这些列必 - 须使用等值操作符进行比较。这些限制保证潜在冲突的行会落在同一分区中。约 - 束也可以引用不属于任何分区键的其他列,这些列可以使用任何合适的操作符来 - 比较。 - - REFERENCES reftable [ ( refcolumn ) ] [ MATCH matchtype ] [ ON DELETE referential_action ] [ ON UPDATE referential_action ](列约束) - FOREIGN KEY ( column_name [, ... ] [, PERIOD column_name ] ) - REFERENCES reftable [ ( refcolumn [, ... ] [, PERIOD refcolumn ] ) ] - [ MATCH matchtype ] - [ ON DELETE referential_action ] - [ ON UPDATE referential_action ] + FOREIGN KEY ( column_name [, ... ] ) + REFERENCES reftable [ ( refcolumn [, ... ] ) ] + [ MATCH matchtype ] + [ ON DELETE referential_action ] + [ ON UPDATE referential_action ] (表约束) - - - 这些子句指定外键约束,要求新表的一列或多列组成的一组只能包含与被引用 - 表某一行的被引用列中值相匹配的值。若省略 - refcolumn 列表,则使用 - reftable 的主键。否则, - refcolumn 列表必须引用某个不可延 - 迟的唯一约束或主键约束的列,或者引用某个非部分唯一索引的列。 - - - - 如果最后一列标记为 PERIOD,则会按特殊方式处理。非 - PERIOD 列按相等性比较(并且至少需要一列),而 - PERIOD 列则不会。取而代之的是,只有当被引用表中基于键的 - 非 PERIOD 部分相匹配的记录,其合并后的 - PERIOD 值能够完整覆盖引用记录的 - PERIOD 值时,约束才算满足。换言之,该引用在其整个持续区 - 间内都必须有对应的被引用对象。该列必须是范围类型或多范围类型。此外,被 - 引用表必须具有用 WITHOUT OVERLAPS 声明的主键或唯一约 - 束。最后,如果外键包含 PERIOD - column_name 说明,则对应的 - refcolumn(如果存在)也必须标记 - 为 PERIOD。如果省略 - refcolumn 子句,从而选择 - reftable 的主键约束,则该主键的最后一列必须标记为 - WITHOUT OVERLAPS。 - - - - 对于每一对引用列和被引用列,如果它们属于可排序数据类型,则两者的排序规 - 则要么都必须是确定性的,要么必须完全相同。这样可以确保两列对“相等”具 - 有一致的定义。 - - - 用户必须对被引用表拥有 REFERENCES 权限(对整张表,或对 - 特定的被引用列)。添加外键约束需要在被引用表上获取 - SHARE ROW EXCLUSIVE 锁。注意,不能在临时表和永久表之间 - 定义外键约束。 - + 这些子句指定外键约束,要求新表中由一个或多个列组成的列组只能包含与被引用表中某一行的被引用列中的值相匹配的值。如果省略refcolumn列表,则使用reftable的主键。否则,refcolumn列表必须引用不可延迟的唯一约束或主键约束的列,或者是非部分唯一索引的列。用户必须拥有被引用表的REFERENCES权限(可以针对整个表,也可以针对具体的被引用列)。添加外键约束需要在被引用表上获取SHARE ROW EXCLUSIVE锁。请注意,不能在临时表和永久表之间定义外键约束。 插入到引用列中的值会按照给定的匹配类型,与被引用表及其被引用列中的值进 @@ -966,39 +853,18 @@ WITH ( MODULUS numeric_literal, REM NOT NULL 约束,以防止出现这些情况。) - - 此外,当被引用列中的数据发生变化时,会对本表列中的数据执行某些操作。 - ON DELETE 子句指定当被引用表中的被引用行被删除时要执行 - 的操作。同样,ON UPDATE 子句指定当被引用表中的被引用列 - 被更新为新值时要执行的操作。如果更新了行,但被引用列实际上并未改变,则 - 不执行任何操作。引用动作作为数据更改命令的一部分执行,即使该约束是延迟 - 的也一样。每个子句可用的操作如下: - - + 此外,当被引用列中的数据发生变化时,会对本表列中的数据执行某些操作。ON DELETE子句指定删除被引用表中的被引用行时要执行的操作。同样,ON UPDATE子句指定将被引用表中的被引用列更新为新值时要执行的操作。如果行被更新,但被引用列实际上没有变化,则不执行任何操作。除NO ACTION检查以外的引用操作都不能延迟,即使该约束声明为可延迟也是如此。每个子句可以指定以下操作: NO ACTION - - 如果删除或更新会导致外键约束违规,则产生错误。如果约束被延迟,且到 - 约束检查时仍然存在任何引用行,就会产生此错误。 - 这是默认操作。 - + 产生错误,指出删除或更新会违反外键约束。如果该约束被延迟,则会在约束检查时仍存在引用行的情况下产生这个错误。这是默认操作。 RESTRICT - - 如果待删除或更新的行在引用表中有匹配行,则产生错误。即使操作完成后 - 的状态并不违反外键约束,也会阻止该操作。特别地,它会阻止将被引用行 - 更新为“值不同但比较相等”的情况。(但不会阻止把列更新为相同值的 - 无操作更新。) - - - - 对于时态外键,该选项不受支持。 - + 产生错误,指出删除或更新会违反外键约束。这与NO ACTION相同,但检查不能延迟。 @@ -1008,10 +874,6 @@ WITH ( MODULUS numeric_literal, REM 分别删除任何引用已删除行的行,或将引用列的值更新为被引用列的新值。 - - - 对于时态外键,该选项不受支持。 - @@ -1022,10 +884,6 @@ WITH ( MODULUS numeric_literal, REM 将全部引用列,或指定的引用列子集,设置为空值。只有 ON DELETE 动作才能指定列子集。 - - - 对于时态外键,该选项不受支持。 - @@ -1037,19 +895,12 @@ WITH ( MODULUS numeric_literal, REM ON DELETE 动作才能指定列子集。(如果默认值不是空 值,则被引用表中必须有一行与这些默认值匹配,否则该操作会失败。) - - - 对于时态外键,该选项不受支持。 - - - 如果被引用列经常发生变化,那么最好在引用列上添加一个索引,以便更高效地 - 执行与该外键约束相关的引用动作。 - + 如果被引用列经常变化,可以考虑在引用列上添加索引,使与外键约束关联的引用操作能够更高效地执行。 @@ -1088,38 +939,15 @@ WITH ( MODULUS numeric_literal, REM - - ENFORCED - NOT ENFORCED - - - 当约束为 ENFORCED 时,数据库系统会在适当时机检查该约束(按需要在每条语句后或事务结束时),这是默认行为。若约束为 NOT ENFORCED,数据库系统将不再检查该约束,改由应用代码保证约束成立。对于不影响结果正确性的优化决策,数据库系统仍可能假定数据满足该约束。 - - - - NOT ENFORCED 约束可作为文档用途,适用于运行时检查约束代价过高的场景。 - - - - 当前该能力仅支持外键约束与 CHECK 约束。 - - - - USING method - 该可选子句指定存储新表内容所用的表访问方法;该方法必须是类型为 TABLE 的访问方法。详见 。如果未 指定此选项,则会为新表选择默认表访问方法。详见 - - - 创建分区时,若其分区表已设置表访问方法,则该分区会使用分区表的访问方法。 - @@ -1221,11 +1049,10 @@ WITH ( MODULUS numeric_literal, REM - 存储参数 - storage parameters + 存储参数 @@ -1244,10 +1071,9 @@ WITH ( MODULUS numeric_literal, REM - fillfactor (integer) - fillfactor storage parameter + fillfactor 存储参数 @@ -1266,18 +1092,16 @@ WITH ( MODULUS numeric_literal, REM - toast_tuple_target (integer) - toast_tuple_target storage parameter + toast_tuple_target 存储参数 - toast_tuple_target 指定在尝试压缩和/或将长列值移入 TOAST 表之前所需的最小元组长度,同时也是一旦开始 TOAST 化后试图将长度 - 缩减到的目标长度。这会影响标记为 External(用于移动)、Main(用于压缩) + 缩减到其以下的目标长度。这会影响标记为 External(用于移动)、Main(用于压缩) 或 Extended(用于两者)的列,并且只适用于新元组。对现有行没有影响。默认 情况下,该参数被设置为至少允许每个块容纳 4 个元组,在默认块大小下即为 2040 字节。有效值介于 128 字节与(块大小减去页头)之间,默认上限为 @@ -1289,16 +1113,14 @@ WITH ( MODULUS numeric_literal, REM - parallel_workers (integer) - parallel_workers storage parameter + parallel_workers 存储参数 - - 该参数设置在对该表执行并行扫描时可用于辅助扫描的工作进程数量。若未设置, + 该参数设置在对该表执行并行扫描时用于辅助扫描的工作进程数量。若未设置, 系统会根据关系大小决定一个值。规划器或使用并行扫描的实用命令实际选择的 工作进程数量可能更少,例如可能受 设置所限。 @@ -1307,10 +1129,9 @@ WITH ( MODULUS numeric_literal, REM - autovacuum_enabled, toast.autovacuum_enabled (boolean) - autovacuum_enabled storage parameter + autovacuum_enabled 存储参数 @@ -1330,10 +1151,9 @@ WITH ( MODULUS numeric_literal, REM - vacuum_index_cleanup, toast.vacuum_index_cleanup (enum) - vacuum_index_cleanup storage parameter + vacuum_index_cleanup 存储参数 @@ -1353,29 +1173,28 @@ WITH ( MODULUS numeric_literal, REM - vacuum_truncate, toast.vacuum_truncate (boolean) - vacuum_truncate - storage parameter + vacuum_truncate 存储参数 - - 参数的每表取值。若 - VACUUM 指定了 - TRUNCATE 参数,将覆盖此选项的值。 + 允许或禁止清理尝试截去该表末尾的空页。默认值为 + true。若为 true, + VACUUM 和自动清理都会执行截断,并将被截断页面占用的磁盘空间返还给操作系统。注意,截断操作需要对表持有 + ACCESS EXCLUSIVE 锁。若在 + VACUUM 中指定了 + TRUNCATE 参数,则会覆盖此选项的值。 - autovacuum_vacuum_threshold, toast.autovacuum_vacuum_threshold (integer) autovacuum_vacuum_threshold - storage parameter + 存储参数 @@ -1384,28 +1203,13 @@ WITH ( MODULUS numeric_literal, REM 参数的每表取值。 - - - - autovacuum_vacuum_max_threshold, toast.autovacuum_vacuum_max_threshold (integer) - - autovacuum_vacuum_max_threshold - storage parameter - - - - - 参数的每表取值。 - - - + - autovacuum_vacuum_scale_factor, toast.autovacuum_vacuum_scale_factor (floating point) autovacuum_vacuum_scale_factor - storage parameter + 存储参数 @@ -1417,11 +1221,10 @@ WITH ( MODULUS numeric_literal, REM - autovacuum_vacuum_insert_threshold, toast.autovacuum_vacuum_insert_threshold (integer) autovacuum_vacuum_insert_threshold - storage parameter + 存储参数 @@ -1434,11 +1237,10 @@ WITH ( MODULUS numeric_literal, REM - autovacuum_vacuum_insert_scale_factor, toast.autovacuum_vacuum_insert_scale_factor (floating point) autovacuum_vacuum_insert_scale_factor - storage parameter + 存储参数 @@ -1450,11 +1252,10 @@ WITH ( MODULUS numeric_literal, REM - autovacuum_analyze_threshold (integer) autovacuum_analyze_threshold - storage parameter + 存储参数 @@ -1466,11 +1267,10 @@ WITH ( MODULUS numeric_literal, REM - autovacuum_analyze_scale_factor (floating point) autovacuum_analyze_scale_factor - storage parameter + 存储参数 @@ -1482,11 +1282,10 @@ WITH ( MODULUS numeric_literal, REM - autovacuum_vacuum_cost_delay, toast.autovacuum_vacuum_cost_delay (floating point) autovacuum_vacuum_cost_delay - storage parameter + 存储参数 @@ -1498,11 +1297,10 @@ WITH ( MODULUS numeric_literal, REM - autovacuum_vacuum_cost_limit, toast.autovacuum_vacuum_cost_limit (integer) autovacuum_vacuum_cost_limit - storage parameter + 存储参数 @@ -1514,10 +1312,9 @@ WITH ( MODULUS numeric_literal, REM - autovacuum_freeze_min_age, toast.autovacuum_freeze_min_age (integer) - autovacuum_freeze_min_age storage parameter + autovacuum_freeze_min_age 存储参数 @@ -1531,11 +1328,10 @@ WITH ( MODULUS numeric_literal, REM - autovacuum_freeze_max_age, toast.autovacuum_freeze_max_age (integer) autovacuum_freeze_max_age - storage parameter + 存储参数 @@ -1549,10 +1345,9 @@ WITH ( MODULUS numeric_literal, REM - autovacuum_freeze_table_age, toast.autovacuum_freeze_table_age (integer) - autovacuum_freeze_table_age storage parameter + autovacuum_freeze_table_age 存储参数 @@ -1564,10 +1359,9 @@ WITH ( MODULUS numeric_literal, REM - autovacuum_multixact_freeze_min_age, toast.autovacuum_multixact_freeze_min_age (integer) - autovacuum_multixact_freeze_min_age storage parameter + autovacuum_multixact_freeze_min_age 存储参数 @@ -1582,11 +1376,10 @@ WITH ( MODULUS numeric_literal, REM - autovacuum_multixact_freeze_max_age, toast.autovacuum_multixact_freeze_max_age (integer) autovacuum_multixact_freeze_max_age - storage parameter + 存储参数 @@ -1601,10 +1394,9 @@ WITH ( MODULUS numeric_literal, REM - autovacuum_multixact_freeze_table_age, toast.autovacuum_multixact_freeze_table_age (integer) - autovacuum_multixact_freeze_table_age storage parameter + autovacuum_multixact_freeze_table_age 存储参数 @@ -1616,11 +1408,10 @@ WITH ( MODULUS numeric_literal, REM - log_autovacuum_min_duration, toast.log_autovacuum_min_duration (integer) log_autovacuum_min_duration - storage parameter + 存储参数 @@ -1629,27 +1420,12 @@ WITH ( MODULUS numeric_literal, REM 参数的每表取值。 - - - - vacuum_max_eager_freeze_failure_rate, toast.vacuum_max_eager_freeze_failure_rate (floating point) - - vacuum_max_eager_freeze_failure_rate - storage parameter - - - - - 参数的每表取值。 - - - user_catalog_table (boolean) - user_catalog_table storage parameter + user_catalog_table 存储参数 @@ -1667,11 +1443,9 @@ WITH ( MODULUS numeric_literal, REM - 注解 - - PostgreSQL为每一个唯一约束和主键约束创建一个索引来强制唯一性。因此,没有必要显式地为主键列创建一个索引(详见)。 + PostgreSQL为每一个唯一约束和主键约束自动创建一个索引来强制唯一性。因此,没有必要显式地为主键列创建一个索引(详见)。 @@ -1684,6 +1458,7 @@ WITH ( MODULUS numeric_literal, REM + 示例 @@ -1993,7 +1768,6 @@ CREATE TABLE cities_partdef - 兼容性 @@ -2096,19 +1870,17 @@ CREATE TABLE cities_partdef - <literal>NULL</literal> <quote>约束</quote> NULL 约束(实际上并不是约束)是 - PostgreSQL 对 SQL 标准的扩展;它也被其他一些数 - 据库系统采纳,以便兼容(以及与对称的 NOT NULL 约束保持一 - 致)。由于它本来就是任意列的默认值,所以它的存在只是噪声。 + PostgreSQL 对 SQL 标准的扩展;提供它是为了 + 与其他一些数据库系统兼容(以及与 NOT NULL 约束保持 + 对称)。由于它本来就是任意列的默认情况,所以它的存在只是噪声。 - 约束命名 @@ -2120,6 +1892,7 @@ CREATE TABLE cities_partdef 名,而索引名称在同一模式内的所有关系之间必须唯一。 + 目前,PostgreSQL根本不会为NOT NULL约束记录名称,因此它们不受唯一性限制。这种情况可能会在未来版本中改变。 @@ -2132,38 +1905,33 @@ CREATE TABLE cities_partdef - - 零列表 + 零列的表 PostgreSQL 允许创建没有列的表(例如 CREATE TABLE foo();)。这是对 SQL 标准的扩展,标准不允许 - 零列表。零列表本身并不十分有用,但若禁止它们,就会让 + 零列的表。零列的表本身并不十分有用,但若禁止它们,就会让 ALTER TABLE DROP COLUMN 出现奇怪的特殊情况,因此忽略这 一规范限制看起来更整洁。 - 多个标识列 PostgreSQL 允许一个表拥有多个标识列。 该标准指定一个表最多只能有一个标识列。 - 这主要是为了给模式更改或迁移提供更大的灵活性。 + 放宽这一限制主要是为了给模式更改或迁移提供更大的灵活性。 请注意,INSERT 命令仅支持一个适用于整个语句的覆盖子 句,因此对行为不同的多个标识列支持并不好。 - 生成列 - - STOREDVIRTUAL 选项都不是标准的一部分,但其他 SQL 实现也会使用。SQL 标准并不规定生成列的存储方式。 - + STORED选项不是标准的一部分,但其他 SQL 实现也使用它。SQL 标准没有规定生成列的存储方式。 @@ -2200,12 +1968,10 @@ CREATE TABLE cities_partdef - 类型化表 - 类型化表实现了 SQL 标准的一个子集。按照标准,类型化表除了具有与底层组合 - 类型相对应的列之外,还应有一个额外的自引用列。 + 类型化表实现了 SQL 标准的一个子集。按照标准,类型化表除了具有与底层复合类型相对应的列之外,还应有一个额外的自引用列PostgreSQL 不显式支持自引用列。 @@ -2232,6 +1998,7 @@ CREATE TABLE cities_partdef + 另见 diff --git a/zh/16/ref/create_table_as.sgml b/zh/16/ref/create_table_as.sgml index 7d80a1f0..03a60483 100644 --- a/zh/16/ref/create_table_as.sgml +++ b/zh/16/ref/create_table_as.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation CREATE TABLE AS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/create_tablespace.sgml b/zh/16/ref/create_tablespace.sgml index 32b0dbb1..88106ccd 100644 --- a/zh/16/ref/create_tablespace.sgml +++ b/zh/16/ref/create_tablespace.sgml @@ -13,7 +13,7 @@ PostgreSQL documentation CREATE TABLESPACE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/create_transform.sgml b/zh/16/ref/create_transform.sgml index 247e6a0f..ecea2c1e 100644 --- a/zh/16/ref/create_transform.sgml +++ b/zh/16/ref/create_transform.sgml @@ -13,7 +13,7 @@ PostgreSQL documentation CREATE TRANSFORM 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/create_trigger.sgml b/zh/16/ref/create_trigger.sgml index 236c79c4..9f177700 100644 --- a/zh/16/ref/create_trigger.sgml +++ b/zh/16/ref/create_trigger.sgml @@ -11,13 +11,13 @@ PostgreSQL documentation 过渡表 - ephemeral named relation + 临时命名关系 CREATE TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -70,7 +70,7 @@ CREATE [ OR REPLACE ] [ CONSTRAINT ] TRIGGER name UPDATEDELETE之前); 也可以在该操作完成之后引发(即在检查约束以及完成 INSERTUPDATE或 - DELETE之后);或者改为执行该操作 + DELETE之后);或者取代该操作执行 (用于视图上的插入、更新或删除)。如果触发器在事件之前引发,或者改为取代该事件执行, 则它可以跳过对当前行的操作,或者修改待插入的行 (仅适用于INSERTUPDATE操作)。 @@ -178,7 +178,7 @@ CREATE [ OR REPLACE ] [ CONSTRAINT ] TRIGGER name 调整其引发时机。约束触发器必须是普通表(不是外部表)上的 AFTER ROW 触发器。它们既可以在导致触发事件的语句结束时引发, 也可以在包含它的事务结束时引发;后一种情况称为延迟。 - 也可以使用SET CONSTRAINTS强制挂起的延迟触发立即引发。 + 也可以使用SET CONSTRAINTS强制尚待执行的延迟触发器立即引发。 约束触发器应当在其所实现的约束遭到违反时抛出异常。 @@ -394,7 +394,7 @@ UPDATE OF column_name1 [, column_name2CREATE TRIGGER的语法中,关键字 FUNCTIONPROCEDURE 是等价的, 但无论如何,被引用的对象都必须是函数而不是过程。 - 这里使用 PROCEDURE 关键字只是出于历史原因,并且已被废弃。 + 这里使用 PROCEDURE 关键字只是出于历史原因,并且已被弃用。 diff --git a/zh/16/ref/create_tsconfig.sgml b/zh/16/ref/create_tsconfig.sgml index 52c43127..52970b36 100644 --- a/zh/16/ref/create_tsconfig.sgml +++ b/zh/16/ref/create_tsconfig.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TEXT SEARCH CONFIGURATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/create_tsdictionary.sgml b/zh/16/ref/create_tsdictionary.sgml index 7a06b430..c45a7240 100644 --- a/zh/16/ref/create_tsdictionary.sgml +++ b/zh/16/ref/create_tsdictionary.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TEXT SEARCH DICTIONARY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/create_tsparser.sgml b/zh/16/ref/create_tsparser.sgml index d0c11ba5..358152ce 100644 --- a/zh/16/ref/create_tsparser.sgml +++ b/zh/16/ref/create_tsparser.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TEXT SEARCH PARSER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/create_tstemplate.sgml b/zh/16/ref/create_tstemplate.sgml index 947b18b9..702233e4 100644 --- a/zh/16/ref/create_tstemplate.sgml +++ b/zh/16/ref/create_tstemplate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TEXT SEARCH TEMPLATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/create_type.sgml b/zh/16/ref/create_type.sgml index 45a4d93a..879d0a86 100644 --- a/zh/16/ref/create_type.sgml +++ b/zh/16/ref/create_type.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation CREATE TYPE 7 - SQL - Language Statements + SQL - 语言语句 @@ -96,7 +96,7 @@ CREATE TYPE name 复合类型 - 第一种形式的CREATE TYPE创建复合类型。组合 + 第一种形式的CREATE TYPE创建复合类型。复合 类型由属性名和数据类型列表指定。如果某个属性的数据类型支持排序规 则,还可以指定该属性的排序规则。复合类型本质上与表的行类型相同, 但如果目的只是定义一种类型,使用CREATE TYPE @@ -322,7 +322,7 @@ CREATE TYPE name 数才知道,但仍有若干内部表示属性必须向 PostgreSQL声明。其中最重要的是 internallength。 - 基础数据类型可以是定长的,此时internallength为正整数;也可 以是变长的,此时将internallength设为 @@ -427,7 +427,7 @@ CREATE TYPE name collatable为真,则 该类型的列定义和表达式可以通过COLLATE子句携 带排序规则信息。是否实际使用这些排序规则信息取决于操作该类型的函 - 数实现;仅仅把类型标记为 collatable 并不会自动实现这一点。 + 数实现;仅仅把类型标记为支持排序规则并不会自动实现这一点。 @@ -876,7 +876,7 @@ CREATE TYPE float8_range AS RANGE (subtype = float8, subtype_diff = float8mi); - 这个示例创建基础数据类型box,然后在表定义中使用它: + 这个示例创建基础类型box,然后在表定义中使用它: CREATE TYPE box; diff --git a/zh/16/ref/create_user.sgml b/zh/16/ref/create_user.sgml index 218c51eb..9548a147 100644 --- a/zh/16/ref/create_user.sgml +++ b/zh/16/ref/create_user.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE USER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/create_user_mapping.sgml b/zh/16/ref/create_user_mapping.sgml index fe556318..1abe6abd 100644 --- a/zh/16/ref/create_user_mapping.sgml +++ b/zh/16/ref/create_user_mapping.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE USER MAPPING 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/create_view.sgml b/zh/16/ref/create_view.sgml index 80c6d1ab..292b1a4b 100644 --- a/zh/16/ref/create_view.sgml +++ b/zh/16/ref/create_view.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation CREATE VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/createdb.sgml b/zh/16/ref/createdb.sgml index 554d7377..cd3cfd3b 100644 --- a/zh/16/ref/createdb.sgml +++ b/zh/16/ref/createdb.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation createdb 1 - Application + 应用程序 @@ -143,15 +143,7 @@ PostgreSQL documentation - - - - - 当使用 builtin 提供程序时,指定区域设置名称。区域设置支持的说明见 - 。 - - - + @@ -173,7 +165,7 @@ PostgreSQL documentation - + diff --git a/zh/16/ref/createuser.sgml b/zh/16/ref/createuser.sgml index 0451cadd..eba45357 100644 --- a/zh/16/ref/createuser.sgml +++ b/zh/16/ref/createuser.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation createuser 1 - Application + 应用程序 @@ -139,7 +139,7 @@ PostgreSQL documentation - (已废弃) + (已弃用) diff --git a/zh/16/ref/deallocate.sgml b/zh/16/ref/deallocate.sgml index 27b9da86..6dea341e 100644 --- a/zh/16/ref/deallocate.sgml +++ b/zh/16/ref/deallocate.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation DEALLOCATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/declare.sgml b/zh/16/ref/declare.sgml index ed389e4d..9276a0e3 100644 --- a/zh/16/ref/declare.sgml +++ b/zh/16/ref/declare.sgml @@ -22,7 +22,7 @@ PostgreSQL documentation DECLARE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/delete.sgml b/zh/16/ref/delete.sgml index 4a79783c..653e86a2 100644 --- a/zh/16/ref/delete.sgml +++ b/zh/16/ref/delete.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DELETE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/discard.sgml b/zh/16/ref/discard.sgml index 29d4ea8d..f6572252 100644 --- a/zh/16/ref/discard.sgml +++ b/zh/16/ref/discard.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DISCARD 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/do.sgml b/zh/16/ref/do.sgml index 2ea6566a..cdbf189e 100644 --- a/zh/16/ref/do.sgml +++ b/zh/16/ref/do.sgml @@ -15,7 +15,7 @@ PostgreSQL documentation DO 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/drop_access_method.sgml b/zh/16/ref/drop_access_method.sgml index 407ec4cd..646100e1 100644 --- a/zh/16/ref/drop_access_method.sgml +++ b/zh/16/ref/drop_access_method.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP ACCESS METHOD 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/drop_aggregate.sgml b/zh/16/ref/drop_aggregate.sgml index 1c8a1122..9fd7ea4b 100644 --- a/zh/16/ref/drop_aggregate.sgml +++ b/zh/16/ref/drop_aggregate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP AGGREGATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/drop_cast.sgml b/zh/16/ref/drop_cast.sgml index 73860e3c..5e330ae0 100644 --- a/zh/16/ref/drop_cast.sgml +++ b/zh/16/ref/drop_cast.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP CAST 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/drop_collation.sgml b/zh/16/ref/drop_collation.sgml index b90849fc..b10b3206 100644 --- a/zh/16/ref/drop_collation.sgml +++ b/zh/16/ref/drop_collation.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP COLLATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/drop_conversion.sgml b/zh/16/ref/drop_conversion.sgml index b63d1291..35009708 100644 --- a/zh/16/ref/drop_conversion.sgml +++ b/zh/16/ref/drop_conversion.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP CONVERSION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/drop_database.sgml b/zh/16/ref/drop_database.sgml index 9bbd949f..10817b69 100644 --- a/zh/16/ref/drop_database.sgml +++ b/zh/16/ref/drop_database.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP DATABASE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/drop_domain.sgml b/zh/16/ref/drop_domain.sgml index d43f95c6..b292b189 100644 --- a/zh/16/ref/drop_domain.sgml +++ b/zh/16/ref/drop_domain.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP DOMAIN 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/drop_event_trigger.sgml b/zh/16/ref/drop_event_trigger.sgml index 80020f78..f4f0053f 100644 --- a/zh/16/ref/drop_event_trigger.sgml +++ b/zh/16/ref/drop_event_trigger.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP EVENT TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -30,7 +30,7 @@ DROP EVENT TRIGGER [ IF EXISTS ] name DROP EVENT TRIGGER移除一个现有的事件触发器。 - 要执行此命令,当前用户必须是该事件触发器的拥有者。 + 要执行此命令,当前用户必须是该事件触发器的所有者。 @@ -99,7 +99,7 @@ DROP EVENT TRIGGER snitch; - 另见 + 参见 diff --git a/zh/16/ref/drop_extension.sgml b/zh/16/ref/drop_extension.sgml index 5eb04c04..ccccb0b1 100644 --- a/zh/16/ref/drop_extension.sgml +++ b/zh/16/ref/drop_extension.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP EXTENSION 7 - SQL - Language Statements + SQL - 语言语句 @@ -59,8 +59,8 @@ DROP EXTENSION [ IF EXISTS ] name [ name - 已安装扩展的名称。 - + 一个已安装扩展的名称。 + @@ -95,7 +95,7 @@ DROP EXTENSION [ IF EXISTS ] name [ DROP EXTENSION hstore; - 如果数据库中正在使用hstore的任何对象, + 如果数据库中使用了hstore的任何对象, 例如某些表具有hstore类型的列,则该命令会失败。 加上CASCADE选项可以强制一并移除这些依赖对象。 diff --git a/zh/16/ref/drop_foreign_data_wrapper.sgml b/zh/16/ref/drop_foreign_data_wrapper.sgml index 9902c875..6f781f31 100644 --- a/zh/16/ref/drop_foreign_data_wrapper.sgml +++ b/zh/16/ref/drop_foreign_data_wrapper.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP FOREIGN DATA WRAPPER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/drop_foreign_table.sgml b/zh/16/ref/drop_foreign_table.sgml index 0b4d0bbd..c420e4ba 100644 --- a/zh/16/ref/drop_foreign_table.sgml +++ b/zh/16/ref/drop_foreign_table.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP FOREIGN TABLE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/drop_function.sgml b/zh/16/ref/drop_function.sgml index 32e1de58..f80cc1d8 100644 --- a/zh/16/ref/drop_function.sgml +++ b/zh/16/ref/drop_function.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP FUNCTION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/drop_group.sgml b/zh/16/ref/drop_group.sgml index f43389ca..4ee8fc55 100644 --- a/zh/16/ref/drop_group.sgml +++ b/zh/16/ref/drop_group.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP GROUP 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/drop_index.sgml b/zh/16/ref/drop_index.sgml index b65b810b..d7f892d9 100644 --- a/zh/16/ref/drop_index.sgml +++ b/zh/16/ref/drop_index.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP INDEX 7 - SQL - Language Statements + SQL - 语言语句 @@ -57,7 +57,7 @@ DROP INDEX [ CONCURRENTLY ] [ IF EXISTS ] name 对于临时表,DROP INDEX始终是非并发的, - 因为没有其他会话可以访问它们,而且非并发删除索引的成本更低。 + 因为没有其他会话可以访问它们,而且非并发删除索引的代价更低。 @@ -66,7 +66,7 @@ DROP INDEX [ CONCURRENTLY ] [ IF EXISTS ] nameIF EXISTS - 如果该索引不存在,则不要抛出错误。这种情况下会发出一个提示。 + 如果该索引不存在,则不要抛出错误。这种情况下会发出一条提示。 diff --git a/zh/16/ref/drop_language.sgml b/zh/16/ref/drop_language.sgml index 9696f612..8fb4de3f 100644 --- a/zh/16/ref/drop_language.sgml +++ b/zh/16/ref/drop_language.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP LANGUAGE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/drop_materialized_view.sgml b/zh/16/ref/drop_materialized_view.sgml index f3682552..71ad4326 100644 --- a/zh/16/ref/drop_materialized_view.sgml +++ b/zh/16/ref/drop_materialized_view.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP MATERIALIZED VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/drop_opclass.sgml b/zh/16/ref/drop_opclass.sgml index c3dd2e74..9d67dc64 100644 --- a/zh/16/ref/drop_opclass.sgml +++ b/zh/16/ref/drop_opclass.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP OPERATOR CLASS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/drop_operator.sgml b/zh/16/ref/drop_operator.sgml index 3cfb069c..19e93d4e 100644 --- a/zh/16/ref/drop_operator.sgml +++ b/zh/16/ref/drop_operator.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP OPERATOR 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/drop_opfamily.sgml b/zh/16/ref/drop_opfamily.sgml index 8e7097f9..06223045 100644 --- a/zh/16/ref/drop_opfamily.sgml +++ b/zh/16/ref/drop_opfamily.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP OPERATOR FAMILY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/drop_owned.sgml b/zh/16/ref/drop_owned.sgml index 2bc659bf..3ec24e66 100644 --- a/zh/16/ref/drop_owned.sgml +++ b/zh/16/ref/drop_owned.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP OWNED 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/drop_policy.sgml b/zh/16/ref/drop_policy.sgml index ee64ffa0..a939a688 100644 --- a/zh/16/ref/drop_policy.sgml +++ b/zh/16/ref/drop_policy.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP POLICY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/drop_procedure.sgml b/zh/16/ref/drop_procedure.sgml index 178e6684..19708931 100644 --- a/zh/16/ref/drop_procedure.sgml +++ b/zh/16/ref/drop_procedure.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP PROCEDURE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/drop_publication.sgml b/zh/16/ref/drop_publication.sgml index 6bc4bf59..048c1756 100644 --- a/zh/16/ref/drop_publication.sgml +++ b/zh/16/ref/drop_publication.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP PUBLICATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/drop_role.sgml b/zh/16/ref/drop_role.sgml index 6f3dd022..9fbfa99e 100644 --- a/zh/16/ref/drop_role.sgml +++ b/zh/16/ref/drop_role.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP ROLE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/drop_routine.sgml b/zh/16/ref/drop_routine.sgml index 4f2be77f..db15d5d2 100644 --- a/zh/16/ref/drop_routine.sgml +++ b/zh/16/ref/drop_routine.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP ROUTINE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/drop_rule.sgml b/zh/16/ref/drop_rule.sgml index ddb561f4..2968d946 100644 --- a/zh/16/ref/drop_rule.sgml +++ b/zh/16/ref/drop_rule.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP RULE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/drop_schema.sgml b/zh/16/ref/drop_schema.sgml index 9f622df3..94843c9a 100644 --- a/zh/16/ref/drop_schema.sgml +++ b/zh/16/ref/drop_schema.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP SCHEMA 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/drop_sequence.sgml b/zh/16/ref/drop_sequence.sgml index 4ba78640..586d3038 100644 --- a/zh/16/ref/drop_sequence.sgml +++ b/zh/16/ref/drop_sequence.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP SEQUENCE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/drop_server.sgml b/zh/16/ref/drop_server.sgml index 0864a4c2..8bdacdc8 100644 --- a/zh/16/ref/drop_server.sgml +++ b/zh/16/ref/drop_server.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP SERVER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/drop_statistics.sgml b/zh/16/ref/drop_statistics.sgml index 3120dc06..4773bfa8 100644 --- a/zh/16/ref/drop_statistics.sgml +++ b/zh/16/ref/drop_statistics.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP STATISTICS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/drop_subscription.sgml b/zh/16/ref/drop_subscription.sgml index 67421595..08022244 100644 --- a/zh/16/ref/drop_subscription.sgml +++ b/zh/16/ref/drop_subscription.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP SUBSCRIPTION 7 - SQL - Language Statements + SQL - 语言语句 @@ -39,7 +39,7 @@ DROP SUBSCRIPTION [ IF EXISTS ] name 如果该订阅与复制槽相关联,则不能在事务块内执行 DROP SUBSCRIPTION。 - (可以使用ALTER SUBSCRIPTION + (可以使用ALTER SUBSCRIPTION 来取消设置该槽。) @@ -90,11 +90,9 @@ DROP SUBSCRIPTION [ IF EXISTS ] nameDROP SUBSCRIPTION命令都会失败。 要在这种情况下继续,首先执行 - - ALTER SUBSCRIPTION ... DISABLE + ALTER SUBSCRIPTION ... DISABLE 禁用订阅,然后执行 - - ALTER SUBSCRIPTION ... SET (slot_name = NONE) + ALTER SUBSCRIPTION ... SET (slot_name = NONE) 将其与复制槽解除关联。此后,DROP SUBSCRIPTION将不会尝试删除订阅自身的复制槽。 如果还有某些表同步尚未完成,它仍可能连接到发布者,以删除由系统内部创建的表同步槽; 如果发布者不可达,则必须手工删除这些槽(以及仍然存在的主复制槽)。否则,这些槽会继续保留 WAL, diff --git a/zh/16/ref/drop_table.sgml b/zh/16/ref/drop_table.sgml index a2634c54..bdfbabf4 100644 --- a/zh/16/ref/drop_table.sgml +++ b/zh/16/ref/drop_table.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TABLE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/drop_tablespace.sgml b/zh/16/ref/drop_tablespace.sgml index c8b09e59..a31fd70f 100644 --- a/zh/16/ref/drop_tablespace.sgml +++ b/zh/16/ref/drop_tablespace.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TABLESPACE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/drop_transform.sgml b/zh/16/ref/drop_transform.sgml index be84b60c..09a3c9c7 100644 --- a/zh/16/ref/drop_transform.sgml +++ b/zh/16/ref/drop_transform.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TRANSFORM 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/drop_trigger.sgml b/zh/16/ref/drop_trigger.sgml index 1f85cf41..160a5ebd 100644 --- a/zh/16/ref/drop_trigger.sgml +++ b/zh/16/ref/drop_trigger.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -30,7 +30,7 @@ DROP TRIGGER [ IF EXISTS ] name ON DROP TRIGGER移除一个现有触发器的定义。 - 要执行此命令,当前用户必须是定义该触发器的表的拥有者。 + 要执行此命令,当前用户必须是定义该触发器的表的所有者。 @@ -109,7 +109,7 @@ DROP TRIGGER if_dist_exists ON films; - 另见 + 参见 diff --git a/zh/16/ref/drop_tsconfig.sgml b/zh/16/ref/drop_tsconfig.sgml index 2a7cdc52..ea139802 100644 --- a/zh/16/ref/drop_tsconfig.sgml +++ b/zh/16/ref/drop_tsconfig.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TEXT SEARCH CONFIGURATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/drop_tsdictionary.sgml b/zh/16/ref/drop_tsdictionary.sgml index 1eb24189..316c5d00 100644 --- a/zh/16/ref/drop_tsdictionary.sgml +++ b/zh/16/ref/drop_tsdictionary.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TEXT SEARCH DICTIONARY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/drop_tsparser.sgml b/zh/16/ref/drop_tsparser.sgml index 0cfa7acd..a65f47be 100644 --- a/zh/16/ref/drop_tsparser.sgml +++ b/zh/16/ref/drop_tsparser.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TEXT SEARCH PARSER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/drop_tstemplate.sgml b/zh/16/ref/drop_tstemplate.sgml index 282231c5..fa1faab0 100644 --- a/zh/16/ref/drop_tstemplate.sgml +++ b/zh/16/ref/drop_tstemplate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TEXT SEARCH TEMPLATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/drop_type.sgml b/zh/16/ref/drop_type.sgml index dab5bfa0..2f139da5 100644 --- a/zh/16/ref/drop_type.sgml +++ b/zh/16/ref/drop_type.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TYPE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/drop_user.sgml b/zh/16/ref/drop_user.sgml index 00d1d5f4..2e61d6ef 100644 --- a/zh/16/ref/drop_user.sgml +++ b/zh/16/ref/drop_user.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP USER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/drop_user_mapping.sgml b/zh/16/ref/drop_user_mapping.sgml index 2a79a65b..d23b0a16 100644 --- a/zh/16/ref/drop_user_mapping.sgml +++ b/zh/16/ref/drop_user_mapping.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP USER MAPPING 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/drop_view.sgml b/zh/16/ref/drop_view.sgml index 4feb47e5..8f995245 100644 --- a/zh/16/ref/drop_view.sgml +++ b/zh/16/ref/drop_view.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/dropdb.sgml b/zh/16/ref/dropdb.sgml index 70ad776f..10f79ed2 100644 --- a/zh/16/ref/dropdb.sgml +++ b/zh/16/ref/dropdb.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation dropdb 1 - Application + 应用程序 diff --git a/zh/16/ref/dropuser.sgml b/zh/16/ref/dropuser.sgml index 55aa53fa..3cdd48c0 100644 --- a/zh/16/ref/dropuser.sgml +++ b/zh/16/ref/dropuser.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation dropuser 1 - Application + 应用程序 diff --git a/zh/16/ref/ecpg-ref.sgml b/zh/16/ref/ecpg-ref.sgml index 002b8ef1..506be589 100644 --- a/zh/16/ref/ecpg-ref.sgml +++ b/zh/16/ref/ecpg-ref.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ecpg 1 - Application + 应用程序 diff --git a/zh/16/ref/end.sgml b/zh/16/ref/end.sgml index d042a740..10947ab0 100644 --- a/zh/16/ref/end.sgml +++ b/zh/16/ref/end.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation END 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/execute.sgml b/zh/16/ref/execute.sgml index 2aed0669..5e7274ff 100644 --- a/zh/16/ref/execute.sgml +++ b/zh/16/ref/execute.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation EXECUTE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/explain.sgml b/zh/16/ref/explain.sgml index 5d6ad75a..bb06dcca 100644 --- a/zh/16/ref/explain.sgml +++ b/zh/16/ref/explain.sgml @@ -21,7 +21,7 @@ PostgreSQL documentation EXPLAIN 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/fetch.sgml b/zh/16/ref/fetch.sgml index 71c12406..9ab88c49 100644 --- a/zh/16/ref/fetch.sgml +++ b/zh/16/ref/fetch.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation FETCH 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/grant.sgml b/zh/16/ref/grant.sgml index 90d2b6aa..214fdff1 100644 --- a/zh/16/ref/grant.sgml +++ b/zh/16/ref/grant.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation GRANT 7 - SQL - Language Statements + SQL - 语言语句 @@ -22,7 +22,7 @@ PostgreSQL documentation -GRANT { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER | MAINTAIN } +GRANT { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER } [, ...] | ALL [ PRIVILEGES ] } ON { [ TABLE ] table_name [, ...] | ALL TABLES IN SCHEMA schema_name [, ...] } @@ -102,7 +102,7 @@ GRANT role_name [, ...] TO role_specification ] -where role_specification can be: +其中role_specification可以是: [ GROUP ] role_name | PUBLIC @@ -167,7 +167,6 @@ GRANT role_name [, ...] TO USAGE SET ALTER SYSTEM - MAINTAIN 具体的权限类型见 。 diff --git a/zh/16/ref/import_foreign_schema.sgml b/zh/16/ref/import_foreign_schema.sgml index 6e912201..1957d60a 100644 --- a/zh/16/ref/import_foreign_schema.sgml +++ b/zh/16/ref/import_foreign_schema.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation IMPORT FOREIGN SCHEMA 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/initdb.sgml b/zh/16/ref/initdb.sgml index 28ee2e7d..e1a9c9e5 100644 --- a/zh/16/ref/initdb.sgml +++ b/zh/16/ref/initdb.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation initdb 1 - Application + 应用程序 @@ -208,7 +208,7 @@ PostgreSQL documentation - 当使用 ICU 提供程序时,指定 ICU 区域设置 ID。区域设置支持见 + 当使用 ICU 提供程序时,指定 ICU 区域设置。区域设置支持见 @@ -250,12 +250,6 @@ PostgreSQL documentation initdb运行时所在的环境。区域设置支持见 - - 如果builtin, - 则必须指定, - 并将其设置为CC.UTF-8或 - PG_UNICODE_FAST。 - @@ -283,18 +277,10 @@ PostgreSQL documentation - - - - - 当使用 builtin 提供程序时,指定区域设置名称。区域设置支持见 - 。 - - - + - + 该选项设置新集簇中创建的数据库所使用的区域设置提供程序。后续创建新数据库时, diff --git a/zh/16/ref/insert.sgml b/zh/16/ref/insert.sgml index e3cc2c2e..025d9d82 100644 --- a/zh/16/ref/insert.sgml +++ b/zh/16/ref/insert.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation INSERT 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/listen.sgml b/zh/16/ref/listen.sgml index 8c31cae2..7451cf82 100644 --- a/zh/16/ref/listen.sgml +++ b/zh/16/ref/listen.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation LISTEN 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/load.sgml b/zh/16/ref/load.sgml index bb0adb7c..89bdb114 100644 --- a/zh/16/ref/load.sgml +++ b/zh/16/ref/load.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation LOAD 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/lock.sgml b/zh/16/ref/lock.sgml index bc45eec4..0c68e7aa 100644 --- a/zh/16/ref/lock.sgml +++ b/zh/16/ref/lock.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation LOCK 7 - SQL - Language Statements + SQL - 语言语句 @@ -55,7 +55,7 @@ LOCK [ TABLE ] [ ONLY ] name [ * ] 因为SHARE锁模式与写入者获取的ROW EXCLUSIVE锁冲突, 而LOCK TABLE name IN SHARE MODE - 语句会一直等待,直到任何并发持有ROW EXCLUSIVE模式锁的事务提交或回滚。 + 语句会一直等待,直到所有并发持有ROW EXCLUSIVE模式锁的事务提交或回滚。 因此,一旦获得该锁,就不存在尚未提交的写入;而且在释放该锁之前,也不会有新的写入开始。 @@ -136,8 +136,8 @@ LOCK [ TABLE ] [ ONLY ] name [ * ] 注解 - 要锁定一个表,用户必须拥有与所指定lockmode对应的权限。 - 如果用户在该表上拥有MAINTAINUPDATE、 + 要锁定一个表,用户必须拥有与所指定lockmode对应的权限,或是该表的所有者或超级用户。 + 如果用户在该表上拥有UPDATEDELETETRUNCATE权限,则允许使用任意 lockmode。 如果用户在该表上拥有INSERT权限,则允许使用ROW EXCLUSIVE MODE @@ -166,9 +166,7 @@ LOCK [ TABLE ] [ ONLY ] name [ * ] 这些模式名称通常应理解为:用户打算在被锁定的表中获取行级锁。 此外,ROW EXCLUSIVE模式本身也是一种可共享的表锁。 请记住,就LOCK TABLE而言,所有锁模式的语义完全相同, - 差别只在于哪些模式彼此冲突。关于如何获取真正的行级锁,请参阅 - 文档中的和 - 。 + 差别只在于哪些模式彼此冲突。关于如何获取真正的行级锁,请参阅 (后者位于文档中)。 diff --git a/zh/16/ref/merge.sgml b/zh/16/ref/merge.sgml index aad3870e..15561f2f 100644 --- a/zh/16/ref/merge.sgml +++ b/zh/16/ref/merge.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation MERGE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/move.sgml b/zh/16/ref/move.sgml index e90c1b88..961359c8 100644 --- a/zh/16/ref/move.sgml +++ b/zh/16/ref/move.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation MOVE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/notify.sgml b/zh/16/ref/notify.sgml index 2aa6095b..a2df6be2 100644 --- a/zh/16/ref/notify.sgml +++ b/zh/16/ref/notify.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation NOTIFY 7 - SQL - Language Statements + SQL - 语言语句 @@ -88,7 +88,7 @@ NOTIFY channel [ , 注解 - 系统中有一个队列,用来保存那些已经发送但尚未被所有监听会话处理的通知。如果这个队列被塞满,那么调用NOTIFY的事务会在提交时失败。该队列非常大(标准安装中为 8GB),几乎足以满足所有用例。不过,如果某个会话执行了LISTEN后又长时间停留在一个事务里,就无法进行清理。一旦队列占用超过一半,你就会在日志文件中看到警告,指出究竟是哪个会话阻碍了清理。在这种情况下,应确保该会话结束其当前事务,以便清理能够继续进行。 + 系统中有一个队列,用来保存那些已经发送但尚未被所有监听会话处理的通知。如果这个队列被塞满,那么调用NOTIFY的事务会在提交时失败。该队列非常大(标准安装中为 8GB),几乎足以满足所有用例。不过,如果某个会话执行了LISTEN后又长时间停留在一个事务里,就无法进行清理。一旦队列占用达到一半,你就会在日志文件中看到警告,指出究竟是哪个会话阻碍了清理。在这种情况下,应确保该会话结束其当前事务,以便清理能够继续进行。 函数pg_notification_queue_usage返回当前被待处理通知占用的队列比例。详见。 diff --git a/zh/16/ref/pg_amcheck.sgml b/zh/16/ref/pg_amcheck.sgml index 855c42dd..a0f5e30f 100644 --- a/zh/16/ref/pg_amcheck.sgml +++ b/zh/16/ref/pg_amcheck.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_amcheck 1 - Application + 应用程序 @@ -284,14 +284,7 @@ PostgreSQL documentation 下列命令行选项控制 B-树索引的检查: - - - - - 对于检查的每个带唯一约束的索引,使用选项,验证重复条目中在索引里可见的项不超过一个。 - - - + @@ -488,17 +481,7 @@ PostgreSQL documentation - - 环境 - - 与大多数其他PostgreSQL工具一样,pg_amcheck也使用libpq支持的环境变量(见)。 - - - - 环境变量PG_COLOR指定是否在诊断消息中使用颜色。可能的值为alwaysautonever。 - - 注意 diff --git a/zh/16/ref/pg_basebackup.sgml b/zh/16/ref/pg_basebackup.sgml index 27ed1100..58b96459 100644 --- a/zh/16/ref/pg_basebackup.sgml +++ b/zh/16/ref/pg_basebackup.sgml @@ -4,7 +4,6 @@ PostgreSQL documentation --> - pg_basebackup @@ -12,7 +11,7 @@ PostgreSQL documentation pg_basebackup 1 - Application + 应用程序 @@ -28,19 +27,13 @@ PostgreSQL documentation - 描述 - pg_basebackup用于获取正在运行的PostgreSQL数据库集簇的基础备份。备份过程不会影响数据库的其他客户端,并且该备份既可用于时间点恢复(见),也可用作日志传送或流复制备库的起点(见)。 - pg_basebackup既可以执行完整基础备份,也可以执行增量基础备份。执行完整备份时,它会精确复制数据库集簇的文件。执行增量备份时,原本会包含在完整备份中的某些文件,可能会被这些文件的增量版本替代,其中仅包含自参考备份以来被修改过的块。增量备份不能直接使用;必须先使用将其与它所依赖的先前备份合并。关于增量备份的更多信息,见;关于从备份恢复的步骤,见。 - - - - 在任何模式下,pg_basebackup都会确保服务器自动进入和退出备份模式。备份始终针对整个数据库集簇;不可能只备份单个数据库或数据库对象。对于选择性备份,必须使用诸如之类的其他工具。 + pg_basebackup会精确复制数据库集簇的文件,同时确保服务器自动进入和退出备份模式。备份始终针对整个数据库集簇;不可能只备份单个数据库或数据库对象。对于选择性备份,必须使用诸如之类的其他工具。 @@ -80,7 +73,7 @@ PostgreSQL documentation - 备份所需的所有 WAL 记录都必须包含足够的全页写入, + 备份所需的所有 WAL 记录都必须包含足够的整页写入, 因此必须在主库上启用full_page_writes @@ -93,7 +86,6 @@ PostgreSQL documentation - 选项 @@ -160,16 +152,6 @@ PostgreSQL documentation - - - - - - 执行增量备份。必须提供参考备份的备份清单;该文件将被上传到服务器,随后服务器会返回所请求的增量备份。 - - - - @@ -179,10 +161,7 @@ PostgreSQL documentation 创建standby.signal standby.signalpg_basebackup --write-recovery-conf文件,并将连接设置追加到目标目录中的postgresql.auto.conf文件中(如果使用 tar 格式,则追加到基础归档文件内)。这样可以更方便地利用备份结果搭建备库。 - - - postgresql.auto.conf文件将记录连接设置,以及(如果指定)pg_basebackup正在使用的复制槽,以便后续的流复制使用相同的设置。只有当 dbname 在连接字符串或环境变量中被显式指定时,才会记录 dbname。 - + postgresql.auto.conf文件会记录pg_basebackup所用的连接设置,以及复制槽(如果指定了),以便流复制以后使用相同的设置。 @@ -207,7 +186,6 @@ PostgreSQL documentation - 在备份期间,将目录olddir中的表空间重定位到newdir。要使此选项生效,olddir必须与源服务器上定义的该表空间路径完全一致。(但如果源服务器上在olddir中没有表空间,也不算错误。)与此同时,newdir是接收主机文件系统中的一个目录。与主目标目录一样,newdir不必事先存在,但如果存在则必须为空。olddirnewdir都必须是绝对路径。如果任一路径中需要包含等号(=),请在其前面加上反斜杠。可以多次指定此选项,以处理多个表空间。 @@ -217,7 +195,7 @@ PostgreSQL documentation - 目前,此选项仅适用于 plain 输出格式;如果选择了 tar 格式,则会被忽略。 + 目前,此选项仅适用于 普通文件 输出格式;如果选择了 tar 格式,则会被忽略。 @@ -225,9 +203,8 @@ PostgreSQL documentation - - 设置写入 WAL(预写式日志)文件的目录。默认情况下,WAL 文件会放在目标目录的pg_wal子目录中,但此选项可用于将其放在其他位置。waldir必须是绝对路径。与主目标目录一样,waldir不必事先存在,但如果存在则必须为空。只有当备份采用 plain 格式时,才能指定此选项。 + 设置写入 WAL(预写式日志)文件的目录。默认情况下,WAL 文件会放在目标目录的pg_wal子目录中,但此选项可用于将其放在其他位置。waldir必须是绝对路径。与主目标目录一样,waldir不必事先存在,但如果存在则必须为空。只有当备份采用 普通文件 格式时,才能指定此选项。 @@ -305,23 +282,18 @@ PostgreSQL documentation - 请求对备份进行压缩。如果包含clientserver,则指定压缩执行的位置。在服务器端压缩会减少传输带宽占用,但会增加服务器 CPU 消耗。默认值是client,但使用--target时除外;此时备份不会发送到客户端,因此只有服务器端压缩才有意义。使用默认的-Xstream时,服务器端压缩不会应用于 WAL。若要压缩 WAL,请使用客户端压缩,或者指定-Xfetch - - 压缩方法可以设置为gziplz4zstdnone(不压缩),也可以直接指定一个整数(0 表示不压缩,大于 0 表示gzip)。还可以选择性地指定压缩细节字符串。如果细节字符串是整数,则表示压缩级别;否则,它应为逗号分隔的项目列表,每项的形式为keywordkeyword=value。目前支持的关键字有levellongworkers。当压缩方法以纯整数形式指定时,不能再使用细节字符串。 + 压缩方法可以设置为gziplz4zstdnone(不压缩),也可以直接指定一个整数(0 表示不压缩,大于 0 表示gzip)。还可以选择性地指定压缩细节字符串。如果细节字符串是整数,则表示压缩级别;否则,它应为逗号分隔的项目列表,每项的形式为keywordkeyword=value。目前支持的关键字有levellongworkers。当压缩方法以纯整数形式指定时,不能再使用细节字符串。 - 如果未指定压缩级别,则使用默认压缩级别。如果只指定了级别而未指定算法,那么级别大于 0 时使用gzip压缩,级别为 0 时则不压缩。 - - 当 tar 格式配合gziplz4zstd使用时,所有 tar 文件名都会分别自动加上.gz.lz4.zst后缀。使用 plain 格式时,不能指定客户端压缩,但仍可以请求服务器端压缩。这样做时,服务器会先压缩备份再传输,而客户端会对其进行解压并提取。 + 当 tar 格式配合gziplz4zstd使用时,所有 tar 文件名都会分别自动加上.gz.lz4.zst后缀。使用 普通文件 格式时,不能指定客户端压缩,但仍可以请求服务器端压缩。这样做时,服务器会先压缩备份再传输,而客户端会对其进行解压并提取。 - 当此选项与-Xstream组合使用时,如果选择了客户端 gzip 压缩,则pg_wal.tar会使用gzip压缩;但如果选择了其他压缩算法,或者选择了服务器端压缩,则不会被压缩。 @@ -329,7 +301,6 @@ PostgreSQL documentation - 以下命令行选项控制备份的生成和程序的调用: @@ -372,13 +343,12 @@ PostgreSQL documentation - 默认情况下,当pg_basebackup因错误中止时,它会删除在发现自己无法完成任务之前可能已创建的所有目录(例如目标目录和预写式日志目录)。此选项会禁止这种清理,因此对调试很有帮助。 - 请注意,无论如何表空间目录都不会被清理。 + 请注意,无论是否使用此选项,表空间目录都不会被清理。 @@ -424,36 +394,18 @@ PostgreSQL documentation - - 此选项只能与-X stream一起使用。它会使 WAL 流式传输使用指定的复制槽。如果此基础备份打算用作使用复制槽的流复制备库,那么该备库应使用与相同的复制槽名称。这样可以确保主库在基础备份结束与新备库开始流复制之间的这段时间内,不会移除任何必需的 WAL 数据。 + 此选项只能与-X stream一起使用。它会使 WAL 流式传输使用指定的复制槽。如果此基础备份打算用作使用复制槽的流复制备库,那么该备库应将同一个复制槽名称用作的值。这样可以确保主库在基础备份结束与新备库开始流复制之间的这段时间内,不会移除任何必需的 WAL 数据。 - 指定的复制槽必须已经存在,除非还同时使用了 - 如果未指定此选项,并且服务器支持临时复制槽(10 及以上版本),则会自动使用临时复制槽进行 WAL 流式传输。 - - - - - 设置为fsync(默认)时,pg_basebackup会递归打开并同步备份目录中的所有文件。使用 plain 格式时,查找文件会跟随 WAL 目录和各已配置表空间的符号链接。 - - - 在 Linux 上,也可以使用syncfs,让操作系统同步包含备份目录的整个文件系统。使用 plain 格式时,pg_basebackup还会同步包含 WAL 文件和各表空间的文件系统。关于使用syncfs时需要注意的限制,见。 - - - 使用时,此选项无效。 - - - - @@ -468,19 +420,15 @@ PostgreSQL documentation - 指定应用到备份清单中每个文件的校验和算法。目前可用的算法有NONECRC32CSHA224SHA256SHA384SHA512。默认值为CRC32C - 如果选择NONE,备份清单将不包含任何校验和。否则,它将包含使用指定算法为备份中每个文件计算的校验和。此外,清单始终会包含其自身内容的SHA256校验和。SHA算法明显比CRC32C更耗费 CPU,因此选择其中一种可能会增加完成备份所需的时间。 - - 对于希望验证备份未被篡改的用户,使用 SHA 哈希函数可以为每个文件提供具有密码学安全性的摘要;而 CRC-32C 算法提供的校验和计算速度要快得多,虽然它很适合发现由于意外改动造成的错误,但并不能抵御恶意修改。请注意,要想对能够访问备份的攻击者形成防护,备份清单就需要安全地保存在其他地方,或者以其他方式确认自备份完成后未被修改。 + 对于希望验证备份未被篡改的用户,使用 SHA hash 函数可以为每个文件提供具有密码学安全性的摘要;而 CRC32C 算法提供的校验和计算速度要快得多,虽然它很适合发现由于意外改动造成的错误,但并不能抵御恶意修改。请注意,要想对能够访问备份的攻击者形成防护,备份清单就需要安全地保存在其他地方,或者以其他方式确认自备份完成后未被修改。 - 可以使用根据备份清单检查备份的完整性。 @@ -570,9 +518,7 @@ PostgreSQL documentation 连接字符串的形式指定用于连接服务器的参数;这些参数会覆盖任何相互冲突的命令行选项。 - - 出于与其他客户端应用保持一致的考虑,此选项名为--dbname;但由于pg_basebackup并不连接到集簇中的某个特定数据库,连接字符串中包含的数据库名会被服务器忽略。不过,以这种方式提供的数据库名会覆盖默认数据库名(replication),从而用于在~/.pgpass中查找复制连接的密码。类似地,连接PostgreSQL时使用的中间件或代理,也可能出于连接路由等目的使用该名称。 - + 出于与其他客户端应用保持一致的考虑,此选项名为--dbname;但由于pg_basebackup并不连接到集簇中的某个特定数据库,连接字符串中的任何数据库名都会被忽略。 @@ -685,8 +631,7 @@ PostgreSQL documentation - - 注意 + 注解 在备份开始时,需要在源服务器上执行一次检查点。这可能需要一些时间(尤其是在未使用--checkpoint=fast选项时);在此期间,pg_basebackup看起来会处于空闲状态。 @@ -697,16 +642,14 @@ PostgreSQL documentation - 在 plain 格式中,除非使用了--tablespace-mapping选项,否则表空间会备份到其在源服务器上的相同路径。如果不使用此选项,那么当表空间正在使用时,就无法在与服务器相同的主机上执行 plain 格式的基础备份,因为备份将不得不写入与原始表空间相同的目录位置。 + 在 普通文件 格式中,除非使用了--tablespace-mapping选项,否则表空间会备份到其在源服务器上的相同路径。如果不使用此选项,那么当表空间正在使用时,就无法在与服务器相同的主机上执行 普通文件 格式的基础备份,因为备份将不得不写入与原始表空间相同的目录位置。 使用 tar 格式时,用户有责任在启动使用这些数据的 PostgreSQL 服务器之前解压每一个 tar 文件。如果存在额外表空间,则这些表空间对应的 tar 文件必须解压到正确的位置。在这种情况下,服务器会根据包含在base.tar文件中的tablespace_map文件内容,为这些表空间创建符号链接。 - - pg_basebackup可以与相同主版本或更低主版本的服务器配合工作,最低支持到 9.1。不过,WAL 流式传输模式(-X stream)仅适用于 9.3 及以上版本服务器,tar 格式(--format=tar)仅适用于 9.5 及以上版本服务器,而增量备份(--incremental)仅适用于 17 及以上版本服务器。 - + pg_basebackup可以与相同主版本或更低主版本的服务器配合工作,最低支持到 9.1。不过,WAL 流式传输模式(-X stream)仅适用于 9.3 及以上版本服务器,tar 格式(--format=tar)仅适用于 9.5 及以上版本服务器。 如果源集簇启用了数据文件的组权限,pg_basebackup会保留这些组权限。 @@ -756,8 +699,7 @@ PostgreSQL documentation - - 参见 + 另见 diff --git a/zh/16/ref/pg_checksums.sgml b/zh/16/ref/pg_checksums.sgml index bba74354..9ffb27fb 100644 --- a/zh/16/ref/pg_checksums.sgml +++ b/zh/16/ref/pg_checksums.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_checksums 1 - Application + 应用程序 diff --git a/zh/16/ref/pg_combinebackup.sgml b/zh/16/ref/pg_combinebackup.sgml deleted file mode 100644 index 5ae1aa14..00000000 --- a/zh/16/ref/pg_combinebackup.sgml +++ /dev/null @@ -1,325 +0,0 @@ - - - - - pg_combinebackup - - - - pg_combinebackup - 1 - Application - - - - pg_combinebackup - 从增量备份及其所依赖的备份重建完整备份 - - - - - pg_combinebackup - option - backup_directory - - - - - 描述 - - pg_combinebackup用于从 - 增量备份及其所依赖的 - 更早备份中重建一个合成的完整备份。 - - - - 请在命令行上按照从旧到新的顺序指定所有必需的备份。 - 也就是说,第一个备份目录应当是完整备份的路径, - 最后一个应当是您希望恢复的最终增量备份的路径。 - 重建后的备份将写入由选项指定的输出目录。 - - - - pg_combinebackup会尝试验证您指定的这些备份 - 是否构成一条合法的备份链,并且能否据此重建出正确的完整备份。 - 但它并不是为帮助您跟踪哪些备份依赖于哪些其他备份而设计的。 - 如果您删除了增量备份所依赖的一个或多个先前备份, - 就无法恢复该增量备份。 - 此外,pg_combinebackup只会尝试验证这些备份 - 相互之间的关系是否正确,而不会验证每个单独备份本身是否完好; - 如需完成该项验证,请使用 - 。 - - - - 由于pg_combinebackup的输出是一个合成完整备份, - 因此它可以作为将来调用pg_combinebackup时的输入。 - 在这种情况下,可以在命令行上指定这个合成完整备份, - 以代替原先用于重建它的那条备份链。 - - - - - 选项 - - - - - - - - - 在stderr上输出大量调试日志。 - - - - - - - - - - 在合成备份中使用硬链接,而不是复制文件。 - 这样重建合成备份可能更快(因为无需复制文件), - 并且占用更少磁盘空间;但在使用输出目录时必须格外小心, - 因为对该目录的任何修改(例如启动服务器)也可能影响输入目录。 - 同样,对输入目录的更改(例如在完整备份上启动服务器) - 也可能影响输出目录。 - 因此,此选项最适合输入目录只是副本、并且会在 - pg_combinebackup完成后被删除的场景。 - - - - 要求输入备份和输出目录位于同一文件系统中。 - - - - 如果备份清单不可用,或者其中不包含正确类型的校验和, - 仍会创建硬链接,但也会按块读取文件以计算校验和。 - - - - - - - - - - /会让 - pg_combinebackup确定将要执行哪些操作, - 而不实际创建目标目录或任何输出文件。 - 该选项与组合时尤其有用。 - - - - - - - - - - 默认情况下,pg_combinebackup会等待所有文件都被安全写入磁盘。 - 此选项会使pg_combinebackup不经等待就直接返回,因此速度更快, - 但这意味着如果随后操作系统崩溃,输出备份可能会损坏。 - 通常,此选项适合测试,但不应用于创建生产环境安装。 - - - - - - - - - - 指定合成完整备份写入的输出目录。 - 当前该参数是必需的。 - - - - - - - - - - 在重建备份期间,将目录olddir中的表空间重定位到 - newdir。 - olddir是命令行指定的最终备份中该表空间的绝对路径, - newdir是重建备份中要使用的绝对路径。 - 若路径中需要包含等号(=),请在其前加反斜杠。 - 可多次指定此选项以映射多个表空间。 - - - - - - - - - 使用高效的文件克隆(某些系统将其称为reflink), - 代替向新数据目录复制文件,这样可能实现几乎瞬时的数据文件复制。 - - - - 如果备份清单不可用,或者其中不包含正确类型的校验和, - 仍会使用文件克隆来复制文件,但也会按块读取该文件以计算校验和。 - - - - 文件克隆仅在某些操作系统和文件系统上受支持。 - 如果选择了该选项,但系统并不支持, - pg_combinebackup运行时将报错。 - 目前,它在 Linux(内核 4.5 及以上)上的 Btrfs 和 XFS - (在创建时启用了 reflink 支持的文件系统)以及 macOS 上的 APFS - 上受支持。 - - - - - - - - - 执行常规文件复制。这是默认行为。 - (另见 - 和/。) - - - - - - - - - 使用copy_file_range系统调用进行高效复制。 - 在某些文件系统上,这会得到与类似的结果, - 即共享物理磁盘块;而在其他文件系统上,它仍可能复制数据块, - 但会通过优化后的路径进行。目前支持 Linux 和 FreeBSD。 - - - - 如果备份清单不可用,或者其中不包含正确类型的校验和, - 仍会使用copy_file_range复制文件, - 但也会按块读取该文件以计算校验和。 - - - - - - - - - 与一样, - pg_combinebackup会在输出目录中写入备份清单。 - 此选项指定对清单中每个文件使用的校验和算法。 - 当前可用算法为NONECRC32C、 - SHA224SHA256、 - SHA384SHA512。 - 默认值为CRC32C。 - - - - - - - - - 禁用备份清单的生成。 - 若未指定该选项,则会将重建备份的清单写入输出目录。 - - - - - - - - - 当设置为fsync(这是默认值)时, - pg_combinebackup会递归打开并同步备份目录中的所有文件。 - 使用 plain 格式时,搜索文件时会跟随 WAL 目录和每个已配置表空间的符号链接。 - - - 在 Linux 上,也可以改用syncfs, - 让操作系统同步包含备份目录的整个文件系统。 - 使用 plain 格式时,pg_combinebackup - 还会同步包含 WAL 文件和各表空间的文件系统。 - 关于使用syncfs时需要注意的事项,请参见 - 。 - - - 当使用时,此选项无效。 - - - - - - - - - - 打印pg_combinebackup版本并退出。 - - - - - - - - - - 显示pg_combinebackup命令行参数帮助并退出。 - - - - - - - - - - - 限制 - - - pg_combinebackup在写入输出目录时不会重新计算页面校验和。 - 因此,如果用于重建的某些备份是在禁用校验和时创建的, - 而最终备份是在启用校验和时创建的, - 则生成的目录中可能包含校验和无效的页面。 - - - - 为避免这个问题,建议在使用 - 更改集簇的校验和状态之后重新创建一次新的完整备份。 - 否则,您也可以对由pg_combinebackup生成的目录 - 先禁用校验和,然后再按需重新启用,以修正这个问题。 - - - - - 环境 - - - 与多数PostgreSQL工具一样, - 本工具使用libpq支持的环境变量 - (参见)。 - - - - 环境变量PG_COLOR指定诊断消息是否使用颜色。 - 可选值为alwaysauto和 - never。 - - - - - 另见 - - - - - - - diff --git a/zh/16/ref/pg_config-ref.sgml b/zh/16/ref/pg_config-ref.sgml index 565638d9..b157f24c 100644 --- a/zh/16/ref/pg_config-ref.sgml +++ b/zh/16/ref/pg_config-ref.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation pg_config 1 - Application + 应用程序 diff --git a/zh/16/ref/pg_controldata.sgml b/zh/16/ref/pg_controldata.sgml index 818db6cc..5435edfa 100644 --- a/zh/16/ref/pg_controldata.sgml +++ b/zh/16/ref/pg_controldata.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_controldata 1 - Application + 应用程序 diff --git a/zh/16/ref/pg_createsubscriber.sgml b/zh/16/ref/pg_createsubscriber.sgml deleted file mode 100644 index dd963ffb..00000000 --- a/zh/16/ref/pg_createsubscriber.sgml +++ /dev/null @@ -1,549 +0,0 @@ - - - - - pg_createsubscriber - - - - pg_createsubscriber - 1 - Application - - - - pg_createsubscriber - 将物理副本转换为新的逻辑副本 - - - - - pg_createsubscriber - option - - - - - - dbname - - - - - datadir - - - - - connstr - - - - - - 描述 - - - pg_createsubscriber从物理备库创建新的逻辑副本。 - 指定数据库中的所有表都会包含在逻辑复制配置中。 - 每个数据库都会创建一对发布和订阅对象。 - 该工具必须在目标服务器上运行。 - - - - 成功运行后,目标服务器的状态类似于一个全新的逻辑复制配置。 - 逻辑复制配置与pg_createsubscriber之间的主要区别在于 - 数据同步的完成方式。pg_createsubscriber - 不会复制初始表数据。它只执行同步阶段,以确保每个表都达到同步状态。 - - - - pg_createsubscriber主要面向大型数据库系统, - 因为在逻辑复制配置中,大部分时间都花在复制初始数据上。 - 此外,在数据同步上花费较长时间的一个副作用通常是,会有大量在初始数据复制期间产生的更改需要应用, - 这会进一步延后逻辑副本可用的时间。对于较小的数据库,建议建立带初始数据同步的逻辑复制。 - 详见CREATE SUBSCRIPTION的 - - copy_data选项。 - - - - - - 选项 - - - pg_createsubscriber接受以下命令行参数: - - - - - - - - 在目标服务器上的每个数据库中创建一个订阅。 - 模板数据库以及不允许连接的数据库除外。 - 为发现所有数据库的列表,工具会使用 - 连接字符串中指定的数据库名连接到源服务器;如果未指定,则使用 - postgres数据库;如果该数据库不存在,则使用 - template1。 - 指定此选项时,会使用自动生成的订阅、发布和复制槽名称。 - 此选项不能与、 - 一起使用。 - - - - - - - - - - 要在其中创建订阅的数据库名称。通过多次指定 - 可以选择多个数据库。此选项不能与一起使用。 - 如果未提供选项,数据库名将从 - 选项中获取。如果在选项或 - 选项中都未指定数据库名,且又未指定选项, - 则会报告错误。 - - - - - - - - - - 包含物理副本中的集簇目录的目标目录。 - - - - - - - - - - 执行除实际修改目标目录之外的所有步骤。 - - - - - - - - - - 目标服务器监听连接的端口号。 - 默认为让目标服务器在 50432 端口上运行,以避免意外的客户端连接。 - - - - - - - - - - 到发布者的连接字符串。详情见。 - - - - - - - - - - 目标服务器上 postmaster 套接字所使用的目录。 - 默认值为当前目录。 - - - - - - - - - - 等待恢复结束的最大秒数。设为 0 表示禁用。 - 默认值为 0。 - - - - - - - - - - 为订阅启用 - two_phase - 两阶段提交。当指定多个数据库时,此选项会统一应用于在这些数据库上创建的所有订阅。 - 默认值为false。 - - - - - - - - - - 连接目标服务器所使用的用户名。 - 默认是当前操作系统用户名。 - - - - - - - - - - 启用详细模式。这将使 - pg_createsubscriber向标准错误输出进度消息 - 以及每个步骤的详细信息。重复指定该选项会让更多调试级消息出现在标准错误中。 - - - - - - - - - 从目标服务器上的指定数据库中删除指定类型的所有对象。 - - - - - - publications: - 为该订阅者建立的FOR ALL TABLES发布总是会被删除; - 指定此对象类型还会删除从源服务器复制过来的其他所有发布。 - - - - - - 被选中要删除的对象都会逐个记录到日志中,包括在 - 期间也是如此。没有机会干预或停止这些对象的删除,因此可以考虑使用 - pg_dump先对它们进行备份。 - - - - - - - - - 为目标数据目录使用指定的主配置文件。 - pg_createsubscriber在内部使用 - pg_ctl命令来启动和停止目标服务器。 - 如果实际的postgresql.conf配置文件存放在数据目录之外, - 此选项允许你显式指定它。 - - - - - - - - - 用于建立逻辑复制的发布名称。通过多次指定 - 可以指定多个发布。发布名称的数量必须与指定的数据库数量一致, - 否则会报告错误。多个发布名称开关的顺序必须与数据库开关的顺序一致。 - 如果未指定此选项,则会为发布分配一个生成的名称。此选项不能与 - 一起使用。 - - - - - - - - - 用于建立逻辑复制的复制槽名称。通过多次指定 - 可以指定多个复制槽。复制槽名称的数量必须与指定的数据库数量一致, - 否则会报告错误。多个复制槽名称开关的顺序必须与数据库开关的顺序一致。 - 如果未指定此选项,则使用订阅名称作为复制槽名称。此选项不能与 - 一起使用。 - - - - - - - - - 用于建立逻辑复制的订阅名称。通过多次指定 - 可以指定多个订阅。订阅名称的数量必须与指定的数据库数量一致, - 否则会报告错误。多个订阅名称开关的顺序必须与数据库开关的顺序一致。 - 如果未指定此选项,则会为订阅分配一个生成的名称。此选项不能与 - 一起使用。 - - - - - - - - - - 打印pg_createsubscriber版本并退出。 - - - - - - - - - - 显示pg_createsubscriber命令行参数的帮助并退出。 - - - - - - - - - 注意 - - - 前置条件 - - - 要让pg_createsubscriber将目标服务器转换为逻辑副本, - 需要满足一些前提条件。如果不满足这些条件,就会报告错误。 - 源服务器和目标服务器的主版本必须与 - pg_createsubscriber相同。 - 给定的目标数据目录必须与源数据目录具有相同的系统标识符。 - 为目标数据目录指定的数据库用户必须具备创建订阅以及使用pg_replication_origin_advance() - 的权限。 - - - - 目标服务器必须作为物理备库使用。 - 目标服务器必须将配置为大于等于指定数据库数量的值。 - 目标服务器必须将配置为大于指定数据库数量的值。 - 目标服务器必须接受本地连接。如果计划使用 - 开关,还需要适当地设置。 - - - - 源服务器必须接受来自目标服务器的连接。源服务器不能处于恢复中。 - 源服务器必须将设置为logical。 - 源服务器必须将配置为 - 大于等于指定数据库数量加现有复制槽数量的值。源服务器必须将配置为大于等于指定数据库数量与现有 WAL 发送器 - 进程数量之和的值。 - - - - - 警告 - - - 若pg_createsubscriber在目标服务器被提升后失败, - 数据目录很可能已处于不可恢复状态。此时建议重新创建新的备库。 - - - - 在转换过程中,pg_createsubscriber通常会使用不同的连接设置 - 来启动目标服务器。因此,对目标服务器的连接应该会失败。 - - - - 由于逻辑复制不复制 DDL 命令, - 运行pg_createsubscriber期间应避免执行会更改数据库模式的 DDL 命令。 - 若目标服务器已转换为逻辑副本,相关 DDL 可能不会被复制,从而引发错误。 - - - - 若pg_createsubscriber处理过程中失败, - 会删除在源服务器上创建的对象(发布、复制槽)。 - 如果目标服务器无法连接到源服务器,删除可能失败。 - 在这种情况下,警告消息会提示遗留的对象。 - 如果目标服务器正在运行,它会被停止。 - - - - 若复制使用了, - 在逻辑复制配置完成后会从源服务器移除该复制槽。 - - - - 如果目标服务器是同步副本, - 运行pg_createsubscriber期间, - 主库上的事务提交可能会在等待复制时阻塞。 - - - - 除非指定, - pg_createsubscriber会在禁用两阶段提交的情况下建立逻辑复制。 - 这意味着任何预备事务都会在COMMIT PREPARED时被复制, - 而不会事先进行预备。配置完成后,你可以手动删除并重新创建订阅, - 并启用two_phase - 选项。 - - - - pg_createsubscriber会使用pg_resetwal - 修改系统标识符。 - 这样可以避免目标服务器可能使用源服务器的 WAL 文件。 - 如果目标服务器还有备库,复制将会中断,应创建一个新的备库。 - - - - 若缺少必需 WAL 文件,复制可能失败。 - 为避免该问题,源服务器应将 - 设置为-1, - 以确保必需 WAL 文件不会被提前移除。 - - - - - 工作原理 - - - 基本思路是从源服务器获得复制起点,并从该位置开始建立逻辑复制: - - - - - - 使用指定命令行选项启动目标服务器。 - 若目标服务器已在运行,pg_createsubscriber会报错终止。 - - - - - - 检查目标服务器是否可以转换,同时也会对源服务器进行一些检查。 - 若任一前置条件不满足,pg_createsubscriber会报错终止。 - - - - - - 在源服务器上为每个指定的数据库创建一个发布和一个复制槽。 - 每个发布都以FOR ALL - TABLES创建。 - 若未指定,发布名称模式为 - pg_createsubscriber_%u_%x - (参数:数据库oid、随机int)。 - 若未指定,复制槽的名称模式如下: - pg_createsubscriber_%u_%x - (参数:数据库oid、随机int)。 - 这些复制槽将在后续步骤中被订阅使用。最后一个复制槽的 LSN 会在 - 参数中用作停止点,也会被订阅用作复制起点。 - 这样可以保证不会丢失任何事务。 - - - - - - 将恢复参数写入目标数据目录并重启目标服务器。 - 它指定了恢复将推进到的预写式日志位置的 LSN()。 - 它还将promote指定为服务器在达到恢复目标后应执行的动作。 - 为了避免恢复过程中出现意外行为,还会添加其他恢复参数,例如在达到一致状态后就结束恢复 - (实际上 WAL 应继续应用到复制起始位置)以及因多个恢复目标而导致失败。 - 当服务器退出备库模式并接受读写事务时,该步骤结束。 - 如果设置了选项,而恢复在给定秒数内没有结束, - pg_createsubscriber就会终止。 - - - - - - 在目标服务器上为每个指定数据库创建订阅。 - 若未指定,名称模式为 - pg_createsubscriber_%u_%x - (参数:数据库oid、随机int)。 - 该订阅不会复制源服务器上的现有数据,也不会创建复制槽, - 而是使用前一步中创建的复制槽。订阅会被创建,但尚不启用, - 因为必须在启动复制之前先将复制进度设置到复制起点。 - - - - - - 删除在目标服务器上被复制过来的发布(这些发布是在复制起点前创建的), - 它们在订阅者上没有用途。 - - - - - - 将每个订阅的复制进度设置为复制起点。 - 当目标服务器开始恢复过程时,它会追赶到复制起点。 - 这正是每个订阅要用作初始复制位置的 LSN。 - 由于订阅已经创建,因此可以取得复制源名称。 - 使用复制源名称和复制起点调用 - pg_replication_origin_advance() - 以设置初始复制位置。 - - - - - - 在目标服务器上启用每个指定数据库的订阅。 - 订阅将从复制起点开始应用事务。 - - - - - - 若备库使用了, - 该复制槽之后不再有用,故将其删除。 - - - - - - 若备库包含用于故障切换的复制槽,它们后续无法继续同步,故将其删除。 - - - - - - 更新目标服务器上的系统标识符。会运行 - 来修改系统标识符。由于pg_resetwal的要求,目标服务器会被停止。 - - - - - - - - 示例 - - - 要从位于foo的物理副本为数据库 - hrfinance创建逻辑副本: - -$ pg_createsubscriber -D /usr/local/pgsql/data -P "host=foo" -d hr -d finance - - - - - - 另见 - - - - - - diff --git a/zh/16/ref/pg_ctl-ref.sgml b/zh/16/ref/pg_ctl-ref.sgml index 6085da56..801cbc55 100644 --- a/zh/16/ref/pg_ctl-ref.sgml +++ b/zh/16/ref/pg_ctl-ref.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation pg_ctl 1 - Application + 应用程序 diff --git a/zh/16/ref/pg_dump.sgml b/zh/16/ref/pg_dump.sgml index 5bf6314d..4401864a 100644 --- a/zh/16/ref/pg_dump.sgml +++ b/zh/16/ref/pg_dump.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_dump 1 - Application + 应用程序 @@ -1529,7 +1529,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; 完整表复制之前,可能也适合先截断目标表。如果用户打算在刷新期间复制初始 数据,则必须以 two_phase = false 创建该槽。初始同步 之后,订阅者会自动启用 - two_phase + two_phase 选项,前提是该订阅最初是以 two_phase = true 选项创建的。 diff --git a/zh/16/ref/pg_dumpall.sgml b/zh/16/ref/pg_dumpall.sgml index bdec2662..c10a1658 100644 --- a/zh/16/ref/pg_dumpall.sgml +++ b/zh/16/ref/pg_dumpall.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_dumpall 1 - Application + 应用程序 diff --git a/zh/16/ref/pg_isready.sgml b/zh/16/ref/pg_isready.sgml index 2e93dde1..a09f7745 100644 --- a/zh/16/ref/pg_isready.sgml +++ b/zh/16/ref/pg_isready.sgml @@ -13,7 +13,7 @@ PostgreSQL documentation pg_isready 1 - Application + 应用程序 diff --git a/zh/16/ref/pg_receivewal.sgml b/zh/16/ref/pg_receivewal.sgml index 3c9e580a..bf520c28 100644 --- a/zh/16/ref/pg_receivewal.sgml +++ b/zh/16/ref/pg_receivewal.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation pg_receivewal 1 - Application + 应用程序 diff --git a/zh/16/ref/pg_recvlogical.sgml b/zh/16/ref/pg_recvlogical.sgml index 993fc2a9..726c8fa3 100644 --- a/zh/16/ref/pg_recvlogical.sgml +++ b/zh/16/ref/pg_recvlogical.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation pg_recvlogical 1 - Application + 应用程序 @@ -75,13 +75,7 @@ PostgreSQL documentation 创建一个名称由指定的新逻辑复制槽。 - - 此操作必须指定 。 - - - - 可与 一起指定 选项。 - + 可与一起指定,以启用对预备事务的解码。 @@ -91,9 +85,6 @@ PostgreSQL documentation 删除由指定名称的复制槽,然后退出。 - - 此操作必须指定 。 - @@ -105,10 +96,6 @@ PostgreSQL documentation 如果服务端的更改流因服务器关闭或断开连接而结束,则除非指定了,否则会循环重试。 - - 此操作必须指定 。 - - 流格式由创建该槽时指定的输出插件决定。 @@ -134,7 +121,6 @@ PostgreSQL documentation - 模式下,当接收达到指定的 LSN 时,自动停止复制,并以正常退出状态 0 退出。 如果在非模式下指定,则会报错。 @@ -151,26 +137,15 @@ PostgreSQL documentation - - - - - 启用后会将该槽同步到备库。此选项只能与 一起指定。 - - - + - 将接收到并解码后的事务数据写入该文件。指定-表示写入stdout - - 此参数对于 操作是必需的。 - @@ -178,10 +153,9 @@ PostgreSQL documentation - 指定pg_recvlogical应当以多高的频率发起fsync()调用, - 以确保输出文件被安全地刷入磁盘。 + 以确保输出文件安全刷盘。 @@ -200,7 +174,6 @@ PostgreSQL documentation - 模式下,从给定的 LSN 开始复制。关于其影响的详细信息,请参见 中的说明。 @@ -212,7 +185,6 @@ PostgreSQL documentation - 当指定且指定名称的槽已存在时,不报错。 @@ -223,7 +195,6 @@ PostgreSQL documentation - 当与服务器的连接丢失时,不要循环重试,直接退出。 @@ -234,7 +205,6 @@ PostgreSQL documentation - 将选项name传递给输出插件;如果指定了value, 则将其用作该选项的值。可用选项及其效果取决于所使用的输出插件。 @@ -246,7 +216,6 @@ PostgreSQL documentation - 创建该槽时,使用指定的逻辑解码输出插件。参见。 如果该槽已经存在,则此选项不起作用。 @@ -258,7 +227,6 @@ PostgreSQL documentation - 该选项与中同名选项的效果相同。参见该处说明。 @@ -269,27 +237,19 @@ PostgreSQL documentation - 模式下,使用名为slot_name的现有逻辑复制槽。 在模式下,以此名称创建该槽。 在模式下,删除此名称的槽。 - - 此参数对于任何一种操作都是必需的。 - - - (已废弃) + - - - 启用对预备事务的解码。此选项只能与一起指定。 - + 启用对预备事务的解码。此选项只能与一起指定。 @@ -297,7 +257,6 @@ PostgreSQL documentation - 启用详细模式。 @@ -314,14 +273,7 @@ PostgreSQL documentation - - 要连接到的数据库。其具体含义请参见各操作的说明。 - dbname可以是一个连接字符串。 - 如果是这种情况,连接字符串参数将覆盖任何冲突的命令行选项。 - - - 此参数在 操作中是必需的。 - + 要连接的数据库。有关其具体含义,请参阅各操作的说明。dbname可以是一个连接字符串。如果如此,连接字符串参数会覆盖任何与之冲突的命令行选项。默认值为用户名。 @@ -329,7 +281,7 @@ PostgreSQL documentation - + 指定服务器运行所在机器的主机名。如果该值以斜杠开头, 则它会被用作 Unix 域套接字的目录。默认值取自 PGHOST环境变量(如果已设置), @@ -342,7 +294,7 @@ PostgreSQL documentation - + 指定服务器监听连接所用的 TCP 端口,或本地 Unix 域套接字文件扩展名。 默认值取自PGPORT环境变量(如果已设置), 否则使用编译时的默认值。 @@ -354,7 +306,7 @@ PostgreSQL documentation - + 用于连接的用户名。默认为当前操作系统用户名。 @@ -364,7 +316,7 @@ PostgreSQL documentation - + 绝不提示输入密码。如果服务器要求密码认证,而密码又无法通过 .pgpass文件等其他方式获得, 则连接尝试将失败。此选项适用于批处理作业和脚本, @@ -377,7 +329,7 @@ PostgreSQL documentation - + 强制pg_recvlogical在连接数据库之前提示输入密码。 @@ -411,7 +363,7 @@ PostgreSQL documentation - + 显示pg_recvlogical命令行参数的帮助并退出。 diff --git a/zh/16/ref/pg_resetwal.sgml b/zh/16/ref/pg_resetwal.sgml index 9deadc8c..7dee0bce 100644 --- a/zh/16/ref/pg_resetwal.sgml +++ b/zh/16/ref/pg_resetwal.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_resetwal 1 - Application + 应用程序 diff --git a/zh/16/ref/pg_restore.sgml b/zh/16/ref/pg_restore.sgml index 7ae86b39..8cd4af1a 100644 --- a/zh/16/ref/pg_restore.sgml +++ b/zh/16/ref/pg_restore.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_restore 1 - Application + 应用程序 diff --git a/zh/16/ref/pg_rewind.sgml b/zh/16/ref/pg_rewind.sgml index 16ffc2e9..93617f49 100644 --- a/zh/16/ref/pg_rewind.sgml +++ b/zh/16/ref/pg_rewind.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation pg_rewind 1 - Application + 应用程序 diff --git a/zh/16/ref/pg_verifybackup.sgml b/zh/16/ref/pg_verifybackup.sgml index a2afbec0..fc95edfc 100644 --- a/zh/16/ref/pg_verifybackup.sgml +++ b/zh/16/ref/pg_verifybackup.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_verifybackup 1 - Application + 应用程序 @@ -28,32 +28,16 @@ PostgreSQL documentation 描述 - - pg_verifybackup用于依据服务器在备份时生成的 - backup_manifest,检查使用 - pg_basebackup获取的数据库集簇备份的完整性。备份 - 既可以采用“plain”格式,也可以采用“tar”格式;其中也包括使用 - pg_basebackup支持的任意算法压缩的 tar 格 - 式备份。不过,目前仅支持对 plain 格式备份执行WAL - 验证。因此,如果备份采用 tar 格式存储,应使用 - -n, --no-parse-wal选项。 - + pg_verifybackup用于检查通过pg_basebackup获取的数据库集簇备份的完整性,检查依据是服务器在备份时生成的backup_manifest。备份必须以“普通文件”格式存储;“tar”格式的备份可以在解包后检查。 需要注意,pg_verifybackup执行的验证并未、也 不可能涵盖运行中的服务器在尝试使用该备份时会执行的每一项检查。即使使 - 用了此工具,你仍应进行测试恢复,并确认生成的数据库按预期工作且包含正 - 确的数据。不过,pg_verifybackup能够检测出 + 用了此工具,你仍应进行测试恢复,并确认生成的数据库按预期工作且看起来包含正确的数据。不过,pg_verifybackup能够检测出 许多因存储问题或用户错误而常见的问题。 - - 备份验证分为四个阶段。首先,pg_verifybackup读取 - backup_manifest文件。如果该文件不存在、无法读取、 - 格式不正确、其系统标识符与备份目录中的pg_control - 不匹配,或者未能通过其自身内部校验和的验证, - pg_verifybackup就会以致命错误终止。 - + 备份验证分为四个阶段。首先,pg_verifybackup读取backup_manifest文件。如果该文件不存在、无法读取、格式不正确,或者未能通过其自身内部校验和的验证,pg_verifybackup就会以致命错误终止。 其次,pg_verifybackup将尝试验证当前存储在磁盘上 @@ -118,41 +102,6 @@ PostgreSQL documentation - - - - - - 指定备份格式。format可以是下列值之一: - - - - p - plain - - - 备份由普通文件组成,其布局与源服务器的数据目录和表空间相同。 - - - - - - t - tar - - - 备份由 tar 文件组成,这些文件可以经过压缩。有效的备份包括名为 - base.tar的主数据目录、名为 - pg_wal.tar的 WAL 文件,以及每个表空间 - 对应的单独 tar 文件,这些文件以该表空间的 OID 命名。如果备份 - 被压缩,则会在每个文件名末尾追加相应的压缩扩展名。 - - - - - - - @@ -237,9 +186,9 @@ PostgreSQL documentation - 还提供下列其他选项: + 其他选项也可用: - + @@ -270,7 +219,7 @@ PostgreSQL documentation 示例 - 要在mydbserver上创建服务器的基础备份,并验证该备 + 要为位于mydbserver的服务器创建基础备份,并验证该备 份的完整性: $ pg_basebackup -h mydbserver -D /usr/local/pgsql/data @@ -279,7 +228,7 @@ PostgreSQL documentation - 要在mydbserver上创建服务器的基础备份,将备份清单 + 要为位于mydbserver的服务器创建基础备份,将备份清单 移到备份目录之外的位置,然后验证该备份: $ pg_basebackup -h mydbserver -D /usr/local/pgsql/backup1234 diff --git a/zh/16/ref/pg_waldump.sgml b/zh/16/ref/pg_waldump.sgml index a4433e63..baa4bb42 100644 --- a/zh/16/ref/pg_waldump.sgml +++ b/zh/16/ref/pg_waldump.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_waldump 1 - Application + 应用程序 diff --git a/zh/16/ref/pg_walsummary.sgml b/zh/16/ref/pg_walsummary.sgml deleted file mode 100644 index b3abba5e..00000000 --- a/zh/16/ref/pg_walsummary.sgml +++ /dev/null @@ -1,125 +0,0 @@ - - - - - pg_walsummary - - - - pg_walsummary - 1 - Application - - - - pg_walsummary - 打印 WAL 汇总文件的内容 - - - - - pg_walsummary - option - file - - - - - 描述 - - pg_walsummary用于打印 WAL 汇总文件的内容。 - 这些二进制文件位于数据目录下的pg_wal/summaries子目录中, - 可使用本工具将其转换为文本。 - 通常并无此必要,因为 WAL 汇总文件主要是为了支持 - 增量备份而存在的, - 但在调试时可能会很有用。 - - - - WAL 汇总文件按表空间 OID、关系 OID 以及关系分支(fork)建立索引。 - 对于每个关系分支,它都存储该文件所汇总范围内被 WAL 修改的块列表。 - 它还可以存储一个limit block: - 如果该关系分支在相关 WAL 范围内被创建或截断,则其值为 0; - 否则,其值为该关系分支被截断后的最短长度。 - 如果该关系分支在相关 WAL 范围内未被创建、删除或截断, - 则 limit block 未定义,或者为无穷大,本工具不会打印它。 - - - - - 选项 - - - - - - - - - 默认情况下,pg_walsummary会为每个由一个或多个连续已修改块构成的范围输出一行。 - 这样可以使输出简洁得多,因为如果某个关系中从 0 到 999 的所有块都被修改了, - 则只会输出一行,而不是 1000 行单独的输出。 - 该选项要求为每个已修改块分别输出一行。 - - - - - - - - - - 除错误之外不打印任何输出。 - 当只想知道某个 WAL 汇总文件能否被成功解析,而并不关心其内容时,这会很有用。 - - - - - - - - - - 显示版本信息,然后退出。 - - - - - - - - - - 显示pg_walsummary命令行参数的帮助并退出。 - - - - - - - - - - - 环境 - - - 环境变量PG_COLOR用于指定是否在诊断消息中使用颜色。 - 可能的值为alwaysauto和 - never。 - - - - - 另见 - - - - - - - - diff --git a/zh/16/ref/pgarchivecleanup.sgml b/zh/16/ref/pgarchivecleanup.sgml index 5c2c0a53..fd4da23e 100644 --- a/zh/16/ref/pgarchivecleanup.sgml +++ b/zh/16/ref/pgarchivecleanup.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_archivecleanup 1 - Application + 应用程序 diff --git a/zh/16/ref/pgbench.sgml b/zh/16/ref/pgbench.sgml index cbade471..e0fa9e55 100644 --- a/zh/16/ref/pgbench.sgml +++ b/zh/16/ref/pgbench.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation pgbench 1 - Application + 应用程序 @@ -1685,7 +1685,7 @@ SELECT 4 AS four \; SELECT 5 AS five \aset greatest ( number , ... ) - double 如果任何参数是双精度的,否则 integer + 若任一参数为 double,则为 double,否则为 integer 选择参数中的最大值。 @@ -1755,7 +1755,7 @@ SELECT 4 AS four \; SELECT 5 AS five \aset least ( number , ... ) - double 如果任何参数是双精度的,否则 integer + 若任一参数为 double,则为 double,否则为 integer 选择参数中的最小值。 @@ -2602,7 +2602,7 @@ PGOPTIONS='-c default_table_access_method=wuzza' 安全性 - 如果不可信用户能够访问尚未采用模式的安全使用方式的数据库,就不要在该数据库中运行pgbenchpgbench使用非限定名称,并且不会更改搜索路径。 + 如果不受信任的用户能够访问尚未采用模式的安全使用方式的数据库,就不要在该数据库中运行pgbenchpgbench使用非限定名称,并且不会更改搜索路径。 diff --git a/zh/16/ref/pgtestfsync.sgml b/zh/16/ref/pgtestfsync.sgml index 86e69b30..6055bccf 100644 --- a/zh/16/ref/pgtestfsync.sgml +++ b/zh/16/ref/pgtestfsync.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_test_fsync 1 - Application + 应用程序 diff --git a/zh/16/ref/pgtesttiming.sgml b/zh/16/ref/pgtesttiming.sgml index f652980f..dc7208fc 100644 --- a/zh/16/ref/pgtesttiming.sgml +++ b/zh/16/ref/pgtesttiming.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_test_timing 1 - Application + 应用程序 diff --git a/zh/16/ref/pgupgrade.sgml b/zh/16/ref/pgupgrade.sgml index de30fcdc..690ecbec 100644 --- a/zh/16/ref/pgupgrade.sgml +++ b/zh/16/ref/pgupgrade.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_upgrade 1 - Application + 应用程序 @@ -40,7 +40,7 @@ PostgreSQL documentation pg_upgrade(以前称为 pg_migrator)允许将存储在 PostgreSQL 数据文件中的数据升级到更新的 PostgreSQL主版本,而无需执行主版本升级通常所需的数据转储/恢复, - 例如从 12.14 升级到 13.10,或从 14.9 升级到 15.5。它不用于次版本升级, + 例如从 12.14 升级到 13.10,或从 14.9 升级到 15.5。次版本升级不需要使用它, 例如从 12.7 升级到 12.8 或从 14.1 升级到 14.5。 @@ -58,10 +58,7 @@ PostgreSQL documentation 二进制兼容,这一点很重要,但 pg_upgrade 无法检查。 - - pg_upgrade 支持从 9.2.X 及更高版本升级到当前 - PostgreSQL主版本,包括快照版和 beta 版。 - + pg_upgrade 支持从 9.2.X 及更高版本升级到当前PostgreSQL主版本,包括快照版和 beta 版。 @@ -112,7 +109,7 @@ PostgreSQL documentation - 要使用的并发连接和进程/线程数 + 要使用的并发进程或线程数 @@ -209,115 +206,19 @@ PostgreSQL documentation - - 将文件复制到新集簇。这是默认行为。(另见 - 、 - 。) - + 将文件复制到新集簇。这是默认行为。(另见。) - - - - - 使用 copy_file_range 系统调用进行高效复制。在某些文件系统上, - 这会产生与 类似的结果,即共享物理磁盘块;在另一些文件系统上, - 它仍然会复制块,但会通过优化路径完成。目前,它在 Linux 和 FreeBSD 上受支持。 - - - - - - - - 不要把旧集簇中的统计信息恢复到新集簇中。 - - - - - option - - - 手工设置新集簇默认的 char 有符号性。可选值为 - signedunsigned。 - - - 在 C 语言中,char 类型在未显式指定时的默认有符号性因平台而异。 - 例如,在 x86 CPU 上 char 默认是 signed char, - 而在 ARM CPU 上默认是 unsigned char。 - - - 从 PostgreSQL 18 开始,数据库集簇会维护自身默认的 - char 有符号性设置,可用于确保在默认 char 有符号性不同的平台之间保持一致行为。 - 默认情况下,pg_upgrade 在从现有集簇升级时会保留该有符号性设置。 - 然而,从 PostgreSQL 17 或更早版本升级时, - pg_upgrade 会采用其构建所在平台的 char 有符号性。 - - - 该选项允许你显式设置新集簇默认的 char 有符号性,以覆盖任何继承值。 - 该选项主要适用于以下两种场景: - - - - 如果你计划在升级后迁移到不同平台,则不应使用该选项。在这种情况下,默认行为才是正确的。 - 应当先在原平台上不带此选项完成升级,然后再迁移集簇。这是推荐且最安全的方法。 - - - - - 如果你已经将集簇迁移到了默认 char 有符号性不同的平台上 - (例如从基于 x86 的系统迁移到基于 ARM 的系统),则应使用该选项来指定与原平台 - 默认 char 有符号性相匹配的值。此外,从迁移数据文件到运行 - pg_upgrade 之间,切勿修改任何数据文件。 - pg_upgrade 应当是新平台上首次启动该集簇的操作。 - - - - - - - - - - - 将数据目录从旧集簇移动到新集簇,然后用为新集簇生成的系统目录文件替换原有目录文件。 - 该模式的性能可能优于 、 - ,尤其是在关系很多的集簇上。 - - - 但是,这种模式会在旧集簇中产生大量垃圾文件,如果使用 - ,可能会延长文件同步步骤。因此, - 建议在 模式下使用 。 - - - 此外,一旦文件传输步骤开始,旧集簇就会被破坏性修改,因此不再能安全启动。 - 详见 。 - - - - - method - - - 设置为 fsync(默认)时,pg_upgrade 会递归打开并同步 - 升级后集簇数据目录中的所有文件。查找文件时会跟随 WAL 目录和各个已配置表空间的符号链接。 - - - 在 Linux 上,也可以使用 syncfs,让操作系统同步包含升级后集簇数据目录、 - 其 WAL 文件以及各个表空间的整个文件系统。见 - 了解使用 syncfs - 时需要注意的事项。 - - - 当使用 时,此选项无效。 - - - + + + + + @@ -473,7 +374,7 @@ NET STOP postgresql-&majorversion; 始终运行新服务器的 pg_upgrade 二进制,而不是旧服务器的。 pg_upgrade 需要指定新旧集簇的数据目录和可执行文件 (bin)目录。你还可以指定用户和端口值,以及是否希望将数据文件 - 链接、克隆或交换,而不是采用默认的复制行为。 + 链接或克隆,而不是采用默认的复制行为。 @@ -481,37 +382,21 @@ NET STOP postgresql-&majorversion; 新集簇,就无法再访问旧集簇。链接模式还要求新旧集簇的数据目录位于同一文件系统中。 (表空间和 pg_wal 可以位于不同文件系统中。)克隆模式具有相同的 速度和磁盘空间优势,但在启动新集簇后不会使旧集簇不可用。克隆模式同样要求新旧数据目录 - 位于同一文件系统中。该模式只在某些操作系统和文件系统上可用。如果关系很多,交换模式 - 可能最快,但一旦文件传输步骤开始,你将无法再访问旧集簇。交换模式也要求新旧集簇的数据 - 目录位于同一文件系统中。 - - - - 将 设置为 2 或更高可以让 pg_upgrade 并行处理多个数据库和表空间。 - 一个不错的起始值是机器上的 CPU 核心数。对于多数据库、多表空间的服务器,此选项可以显著 - 减少升级时间。 + 位于同一文件系统中。该模式只在某些操作系统和文件系统上可用。 - - 对于 Windows 用户,必须登录到管理员账户,然后以带引号的目录运行 - pg_upgrade,例如: + 选项允许使用多个 CPU 核心复制/链接文件,并行转储和恢复数据库模式;一个不错的起始值是 CPU 核心数与表空间数量中的较大值。对于运行在多处理器机器上的多数据库服务器,此选项可以显著减少升级时间。 - + Windows 用户必须先登录管理员帐号,然后以 postgres 用户身份启动 shell,并设置正确的路径: +RUNAS /USER:postgres "CMD.EXE" +SET PATH=%PATH%;C:\Program Files\PostgreSQL\&majorversion;\bin; +然后运行 pg_upgrade,并用引号括起目录,例如: pg_upgrade.exe --old-datadir "C:/Program Files/PostgreSQL/12/data" --new-datadir "C:/Program Files/PostgreSQL/&majorversion;/data" --old-bindir "C:/Program Files/PostgreSQL/12/bin" --new-bindir "C:/Program Files/PostgreSQL/&majorversion;/bin" - - - 启动后,pg_upgrade 会验证两个集簇是否兼容,然后执行升级。 - 即使旧服务器仍在运行,也可以使用 pg_upgrade --check 仅执行检查。 - pg_upgrade --check 还会概述升级后需要手工进行的调整。如果你打算 - 使用链接、克隆、copy-file-range 或交换模式,则应将 、 - 或 - 一起使用,以启用对应模式的专用检查。 - pg_upgrade 需要对当前目录具有写权限。 - +启动后,pg_upgrade会验证两个集簇是否兼容,然后执行升级。你可以使用 pg_upgrade --check 仅执行检查,即使旧服务器仍在运行。pg_upgrade --check还会概述升级后需要手工进行的调整。如果你打算使用链接或克隆模式,则应将选项 一起使用,以启用对应模式的专用检查。pg_upgrade需要对当前目录具有写权限。 显然,在升级期间不应有人访问这些集簇。pg_upgrade @@ -642,14 +527,7 @@ rsync --archive --delete --hard-links --size-only --no-inc-recursive /vol1/pg_tb 配置流复制和日志传送备库 - - 为服务器配置日志传送。(由于备库仍与主库保持同步,因此无需运行 - pg_backup_start()pg_backup_stop(), - 也无需进行文件系统备份。)如果旧主库早于 17.0,则主库上的任何槽都不会复制到新备库, - 因此旧备库上的所有槽都必须手工重建。如果旧主库为 17.0 或更高版本, - 则只有主库上的逻辑槽会复制到新备库,而旧备库上的其他槽不会复制, - 因此也必须手工重建。 - + 为服务器配置日志传送。(由于备库仍与主库保持同步,因此无需运行pg_backup_start()pg_backup_stop(),也无需进行文件系统备份。)复制槽不会被复制,必须重建。 @@ -700,28 +578,13 @@ psql --username=postgres --file=script.sql postgres 统计信息 - - 除非指定 pg_upgrade 会将大多数 - 优化器统计信息从旧集簇传输到新集簇。但这不会传输所有统计信息,例如通过 - 显式创建的统计信息、扩展添加的自定义统计信息, - 或由累积统计系统收集的统计信息。 - - - 由于并非所有统计信息都会由 pg_upgrade 传输,升级结束时你会被要求 - 运行命令来重新生成这些信息。你可能需要设置连接参数以匹配新集簇。 - - - 首先,使用 - vacuumdb --all --analyze-in-stages --missing-stats-only - 为尚无统计信息的关系快速生成最基本的优化器统计信息。然后,使用 - vacuumdb --all --analyze-only 以确保所有关系都拥有最新的累积统计信息, - 用于触发 vacuum 和 analyze。对于这两个命令,使用 都可以加快速度。 - 如果 vacuum_cost_delay 被设置为非零值,可以通过 - PGOPTIONS 覆盖它来加快统计信息生成,例如 PGOPTIONS='-c - vacuum_cost_delay=0' vacuumdb ...。 - + + + + + 由于优化器统计信息不会由pg_upgrade传输,升级结束时你会被要求运行命令来重新生成这些信息。你可能需要设置连接参数以匹配新集簇。 @@ -748,10 +611,7 @@ psql --username=postgres --file=script.sql postgres - - 如果既没有使用 ,也没有使用 , - 旧集簇不会被修改;可以重新启动。 - + 如果选项没有被使用,旧集簇就未被修改,可以重新启动。 @@ -786,130 +646,14 @@ psql --username=postgres --file=script.sql postgres - - - 如果使用了 选项,旧集簇可能已经被破坏性修改: - - - - 如果 pg_upgrade 在报告旧集簇不再能安全启动之前中止, - 则旧集簇没有被修改;可以重新启动。 - - - - - - 如果 pg_upgrade 已报告旧集簇不再能安全启动, - 则旧集簇已经被破坏性修改。在这种情况下,旧集簇必须从备份恢复。 - - - - - - - 环境 - - - 一些环境变量可以为命令行选项提供默认值: - - - PGBINOLD - - - - 旧 PostgreSQL 可执行文件目录;选项 - /。 - - - - - - PGBINNEW - - - - 新 PostgreSQL 可执行文件目录;选项 - /。 - - - - - - PGDATAOLD - - - - 旧数据库集簇配置目录;选项 - /。 - - - - - - PGDATANEW - - - - 新数据库集簇配置目录;选项 - /。 - - - - - - PGPORTOLD - - - - 旧集簇端口号;选项 - /。 - - - - - - PGPORTNEW - - - - 新集簇端口号;选项 - /。 - - - - - - PGSOCKETDIR - - - - 升级期间用于 postmaster 套接字的目录;选项 - /。 - - - - - - PGUSER - - - - 集簇安装用户名称;选项 - /。 - - - - - - 注解 diff --git a/zh/16/ref/postgres-ref.sgml b/zh/16/ref/postgres-ref.sgml index b62740d6..a2e9456b 100644 --- a/zh/16/ref/postgres-ref.sgml +++ b/zh/16/ref/postgres-ref.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation postgres 1 - Application + 应用程序 @@ -532,7 +532,7 @@ PostgreSQL documentation - 表明另一台服务器已经在运行的失败消息 + 表明另一个服务器已经在运行的失败消息 应仔细检查,例如可根据你的系统使用下面的命令: $ ps ax | grep postgres @@ -721,7 +721,7 @@ PostgreSQL documentation - 参见 + 另见 , diff --git a/zh/16/ref/prepare.sgml b/zh/16/ref/prepare.sgml index 6c456821..20228fb4 100644 --- a/zh/16/ref/prepare.sgml +++ b/zh/16/ref/prepare.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation PREPARE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/prepare_transaction.sgml b/zh/16/ref/prepare_transaction.sgml index 10d018b0..75776dab 100644 --- a/zh/16/ref/prepare_transaction.sgml +++ b/zh/16/ref/prepare_transaction.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation PREPARE TRANSACTION 7 - SQL - Language Statements + SQL - 语言语句 @@ -72,7 +72,7 @@ PREPARE TRANSACTION transaction_id - 当前不允许将执行过以下任一操作的事务置为预备状态:涉及临时表或会话临时命名空间的操作、创建任何WITH HOLD游标,或执行过LISTENUNLISTENNOTIFY。这些特性与当前会话绑定得过于紧密,因此在要进入预备状态的事务中没有意义。 + 当前不允许对执行过以下任一操作的事务执行PREPARE:涉及临时表或会话临时命名空间的操作、创建任何WITH HOLD游标,或执行过LISTENUNLISTENNOTIFY。这些特性与当前会话绑定得过于紧密,因此在要进入预备状态的事务中没有意义。 diff --git a/zh/16/ref/psql-ref.sgml b/zh/16/ref/psql-ref.sgml index f7651da7..91e1496b 100644 --- a/zh/16/ref/psql-ref.sgml +++ b/zh/16/ref/psql-ref.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation psql 1 - Application + 应用程序 @@ -534,7 +534,7 @@ testdb=> - 如果不可信用户能够访问尚未采用模式的安全使用方式的数据库,请在会话开始时从search_path中移除所有公众可写的 schema。可以在连接字符串中加入options=-csearch_path=,或者在执行其他 SQL 命令之前发出SELECT pg_catalog.set_config('search_path', '', false)。这种考虑并非psql特有;它适用于任何执行任意 SQL 命令的接口。 + 如果不受信任的用户能够访问尚未采用模式的安全使用方式的数据库,请在会话开始时从search_path中移除所有公众可写的模式。可以在连接字符串中加入options=-csearch_path=,或者在执行其他 SQL 命令之前发出SELECT pg_catalog.set_config('search_path', '', false)。这种考虑并非psql特有;它适用于任何执行任意 SQL 命令的接口。 @@ -582,12 +582,9 @@ testdb=> 很多元命令作用在当前查询缓冲区上。这就是一个缓冲区而已,它保存任何已经被键入但是还没有发送到服务器执行的SQL命令文本。这将包括之前输入的行以及在该元命令同一行上出现在前面的任何文本。 - - 许多元命令还允许在命令名后追加 x 作为选项。这会使结果以扩展模式显示,就像使用了 \x\pset expanded 一样。 - - 定义了以下元命令: + 定义了以下元命令: @@ -626,29 +623,6 @@ INSERT INTO tbl1 VALUES ($1, $2) \bind 'first value' 'second value' \g - - \bind_named statement_name [ parameter ] ... - - - - \bind_named 等同于 \bind,不同之处在于它把现有预备语句的名称作为第一个参数。空字符串表示未命名的预备语句。 - - - - 示例: - -INSERT INTO tbls1 VALUES ($1, $2) \parse stmt1 -\bind_named stmt1 'first value' 'second value' \g - - - - - 此命令会使用扩展查询协议(参见 - ),不同于psql通常使用的简单查询协议。因此,可以用它在psql中测试扩展查询协议。 - - - - \c\connect [ -reuse-previous=on|off ] [ dbname [ username ] [ host ] [ port ] | conninfo ] @@ -686,7 +660,7 @@ INSERT INTO tbls1 VALUES ($1, $2) \parse stmt1 - 示例: + 示例: => \c mydb myuser host.dom 6432 @@ -726,28 +700,6 @@ INSERT INTO tbls1 VALUES ($1, $2) \parse stmt1 - - \close_prepared prepared_statement_name - - - - 关闭指定的预备语句。空字符串表示未命名的预备语句。如果不存在该名称的预备语句,则该操作不执行任何操作。 - - - - 示例: - -SELECT $1 \parse stmt1 -\close_prepared stmt1 - - - - - 此命令会使用扩展查询协议,不同于psql通常使用的简单查询协议。因此,可以用它在psql中测试扩展查询协议。 - - - - \conninfo @@ -881,7 +833,7 @@ SELECT $1 \parse stmt1 - \d[Sx+] [ pattern ] + \d[S+] [ pattern ] @@ -914,66 +866,62 @@ SELECT $1 \parse stmt1 它等同于\dtvmsE,它将显示所有可见的表、视图、物化视图、序列和外部表的列表。 这纯粹是一种便利措施。 - - 与许多其他命令一样,如果在命令名后追加 x,结果会以扩展模式显示。但请注意,这只适用于不带 pattern 参数的 \d;并且 x 修饰符不能直接紧跟在 \d 后面(因为 \dx 是另一个命令)。x 只能出现在 S+ 修饰符之后。例如,\d+x 等同于 \dtvmsE+x,并以扩展模式显示所有关系的列表。 - - \da[Sx] [ pattern ] + \da[S] [ pattern ] 列出聚合函数,以及它们的返回类型和所作用的数据类型。如果指定了 pattern,则只显示名称与模式匹配的聚合。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。如果在命令名后追加 x,结果会以扩展模式显示。 - + class="parameter">pattern,则只显示名称与模式匹配的聚合。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。 - \dA[x+] [ pattern ] + \dA[+] [ pattern ] 列出访问方法。如果指定了 pattern,则只显示名称与模式匹配的访问方法。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则每个访问方法都会连同其关联的处理器函数和描述一起列出。 + class="parameter">pattern
,则只显示名称与模式匹配的访问方法。如果在命令名后追加 +,则每个访问方法都会连同其关联的处理器函数和描述一起列出。 - \dAc[x+] + \dAc[+] [access-method-pattern [input-type-pattern]] - 列出操作符类(参见 )。如果指定了 access-method-pattern,则只列出与名称匹配该模式的访问方法关联的操作符类。如果指定了 input-type-pattern,则只列出与名称匹配该模式的输入类型关联的操作符类。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则每个操作符类都会连同其关联的操作符族和所有者一起列出。 + 列出操作符类(参见 )。如果指定了 access-method-pattern,则只列出与名称匹配该模式的访问方法关联的操作符类。如果指定了 input-type-pattern,则只列出与名称匹配该模式的输入类型关联的操作符类。如果在命令名后追加 +,则每个操作符类都会连同其关联的操作符族和所有者一起列出。 - \dAf[x+] + \dAf[+] [access-method-pattern [input-type-pattern]] - 列出操作符族(参见 )。如果指定了 access-method-pattern,则只列出与名称匹配该模式的访问方法关联的操作符族。如果指定了 input-type-pattern,则只列出与名称匹配该模式的输入类型关联的操作符族。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则每个操作符族都会连同其所有者一起列出。 + 列出操作符族(参见 )。如果指定了 access-method-pattern,则只列出与名称匹配该模式的访问方法关联的操作符族。如果指定了 input-type-pattern,则只列出与名称匹配该模式的输入类型关联的操作符族。如果在命令名后追加 +,则每个操作符族都会连同其所有者一起列出。 - \dAo[x+] + \dAo[+] [access-method-pattern [operator-family-pattern]] @@ -981,69 +929,69 @@ SELECT $1 \parse stmt1 - 列出与操作符族关联的操作符(参见 )。如果指定了 access-method-pattern,则只列出与名称匹配该模式的访问方法所关联的操作符族成员。如果指定了 operator-family-pattern,则只列出名称与该模式匹配的操作符族成员。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则每个操作符都会连同其排序操作符族(如果它是排序操作符)以及其底层函数是否防漏一起列出。 + 列出与操作符族关联的操作符(参见 )。如果指定了 access-method-pattern,则只列出与名称匹配该模式的访问方法所关联的操作符族成员。如果指定了 operator-family-pattern,则只列出名称与该模式匹配的操作符族成员。如果在命令名后追加 +,则每个操作符都会连同其排序操作符族(如果它是排序操作符)以及其底层函数是否防漏一起列出。 - \dAp[x+] + \dAp[+] [access-method-pattern [operator-family-pattern]] - 列出与操作符族关联的支持函数(参见 )。如果指定了 access-method-pattern,则只列出与名称匹配该模式的访问方法所关联的操作符族函数。如果指定了 operator-family-pattern,则只列出名称与该模式匹配的操作符族函数。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,函数会以详细形式显示,并带有其实际参数列表。 + 列出与操作符族关联的支持函数(参见 )。如果指定了 access-method-pattern,则只列出与名称匹配该模式的访问方法所关联的操作符族函数。如果指定了 operator-family-pattern,则只列出名称与该模式匹配的操作符族函数。如果在命令名后追加 +,函数会以详细形式显示,并带有其实际参数列表。 - \db[x+] [ pattern ] + \db[+] [ pattern ] 列出表空间。如果指定了 pattern,则只显示名称与模式匹配的表空间。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则每个表空间都会连同其关联选项、磁盘大小、权限和描述一起列出。 + class="parameter">pattern
,则只显示名称与模式匹配的表空间。如果在命令名后追加 +,则每个表空间都会连同其关联选项、磁盘大小、权限和描述一起列出。 - \dc[Sx+] [ pattern ] + \dc[S+] [ pattern ] - 列出字符集编码之间的转换。如果指定了 pattern,则只列出名称与模式匹配的转换。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则每个对象都会连同其相关描述一起列出。 + 列出字符集编码之间的转换。如果指定了 pattern,则只列出名称与模式匹配的转换。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。如果在命令名后追加 +,则每个对象都会连同其相关描述一起列出。 - \dconfig[x+] [ pattern ] + \dconfig[+] [ pattern ] - 列出服务器配置参数及其值。如果指定了 pattern,则只列出名称与模式匹配的参数。不带 pattern 时,只列出被设置为非默认值的参数。(使用 \dconfig * 可查看所有参数。)如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则每个参数都会连同其数据类型、该参数可设置的上下文以及访问权限(如果已授予非默认访问权限)一起列出。 + 列出服务器配置参数及其值。如果指定了 pattern,则只列出名称与模式匹配的参数。不带 pattern 时,只列出被设置为非默认值的参数。(使用 \dconfig * 可查看所有参数。)如果在命令名后追加 +,则每个参数都会连同其数据类型、该参数可设置的上下文以及访问权限(如果已授予非默认访问权限)一起列出。 - \dC[x+] [ pattern ] + \dC[+] [ pattern ] - 列出类型转换。如果指定了 pattern,则只列出其源类型或目标类型与模式匹配的类型转换。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则会显示每个类型转换的附加信息,包括其底层函数是否防漏,以及该类型转换的描述。 + 列出类型转换。如果指定了 pattern,则只列出其源类型或目标类型与模式匹配的类型转换。如果在命令名后追加 +,则会显示每个类型转换的附加信息,包括其底层函数是否防漏,以及该类型转换的描述。 - \dd[Sx] [ pattern ] + \dd[S] [ pattern ] 显示constraintoperator class、 @@ -1052,8 +1000,7 @@ SELECT $1 \parse stmt1 \dd 显示与 - pattern 匹配的对象描述;如果没有给出参数,则显示相应类型的可见对象的描述。但无论哪种情况,只列出那些已有描述的对象。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。如果在命令名后追加 x,结果会以扩展模式显示。 - + pattern 匹配的对象描述;如果没有给出参数,则显示相应类型的可见对象的描述。但无论哪种情况,只列出那些已有描述的对象。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。 可以使用 COMMENT SQL 命令创建对象的描述。 @@ -1063,22 +1010,21 @@ SELECT $1 \parse stmt1 - \dD[Sx+] [ pattern ] + \dD[S+] [ pattern ] 列出域。如果指定了 pattern,则只显示名称与模式匹配的域。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则每个对象都会连同其相关权限和描述一起列出。 + class="parameter">pattern
,则只显示名称与模式匹配的域。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。如果在命令名后追加 +,则每个对象都会连同其相关权限和描述一起列出。 - \ddp[x] [ pattern ] + \ddp[ pattern ] - 列出默认访问权限设置。对于每个默认权限设置已偏离内置默认值的角色(以及适用时的模式),都会显示一条记录。如果指定了 pattern,则只列出角色名或模式名与模式匹配的记录。如果在命令名后追加 x,结果会以扩展模式显示。 - + 列出默认访问权限设置。对于每个默认权限设置已偏离内置默认值的角色(以及适用时的模式),都会显示一条记录。如果指定了 pattern,则只列出角色名或模式名与模式匹配的记录。 ALTER DEFAULT @@ -1089,51 +1035,51 @@ SELECT $1 \parse stmt1 - \dE[Sx+] [ pattern ] - \di[Sx+] [ pattern ] - \dm[Sx+] [ pattern ] - \ds[Sx+] [ pattern ] - \dt[Sx+] [ pattern ] - \dv[Sx+] [ pattern ] + \dE[S+] [ pattern ] + \di[S+] [ pattern ] + \dm[S+] [ pattern ] + \ds[S+] [ pattern ] + \dt[S+] [ pattern ] + \dv[S+] [ pattern ] 在这组命令中,字母 Eimstv - 分别表示外部表、索引、物化视图、序列、表和视图。你可以按任意顺序指定其中任意一个或多个字母,以获取这些类型对象的列表。例如,\dti 会列出表和索引。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则每个对象都会连同其持久性状态(永久、临时或不记录 WAL)、磁盘上的物理大小以及相关描述(如果有)一起列出。如果指定了 pattern,则只列出名称与模式匹配的对象。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。 + 分别表示外部表、索引、物化视图、序列、表和视图。你可以按任意顺序指定其中任意一个或多个字母,以获取这些类型对象的列表。例如,\dti 会列出表和索引。如果在命令名后追加 +,则每个对象都会连同其持久性状态(永久、临时或不记录 WAL)、磁盘上的物理大小以及相关描述(如果有)一起列出。如果指定了 pattern,则只列出名称与模式匹配的对象。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。 - \des[x+] [ pattern ] + \des[+] [ pattern ] 列出外部服务器(助记符:external - servers)。如果指定了 pattern,则只列出名称与模式匹配的服务器。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则会显示每个服务器的完整描述,包括服务器的访问权限、类型、版本、选项和描述。 + servers)。如果指定了 pattern,则只列出名称与模式匹配的服务器。如果在命令名后追加 +,则会显示每个服务器的完整描述,包括服务器的访问权限、类型、版本、选项和描述。 - \det[x+] [ pattern ] + \det[+] [ pattern ] - 列出外部表(助记符:external tables)。如果指定了 pattern,则只列出表名或模式名与模式匹配的条目。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则还会显示通用选项以及外部表描述。 + 列出外部表(助记符:external tables)。如果指定了 pattern,则只列出表名或模式名与模式匹配的条目。如果在命令名后追加 +,则还会显示通用选项以及外部表描述。 - \deu[x+] [ pattern ] + \deu[+] [ pattern ] 列出用户映射(助记符:external - users)。如果指定了 pattern,则只列出用户名与模式匹配的映射。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则会显示每个映射的附加信息。 + users)。如果指定了 pattern,则只列出用户名与模式匹配的映射。如果在命令名后追加 +,则会显示每个映射的附加信息。 @@ -1146,136 +1092,135 @@ SELECT $1 \parse stmt1 - \dew[x+] [ pattern ] + \dew[+] [ pattern ] 列出外部数据包装器(助记符:external - wrappers)。如果指定了 pattern,则只列出名称与模式匹配的外部数据包装器。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则还会显示外部数据包装器的访问权限、选项和描述。 + wrappers)。如果指定了 pattern,则只列出名称与模式匹配的外部数据包装器。如果在命令名后追加 +,则还会显示外部数据包装器的访问权限、选项和描述。 - \df[anptwSx+] [ pattern [ arg_pattern ... ] ] + \df[anptwS+] [ pattern [ arg_pattern ... ] ] 列出函数,以及它们的结果数据类型、参数数据类型和函数类型,函数类型分为 agg(聚合)、normalproceduretriggerwindow。要只显示特定类型的函数,请在命令后添加相应的字母 anptw。如果指定了 pattern,则只显示名称与模式匹配的函数。任何附加参数都是类型名模式,分别与函数第一、第二等参数的类型名匹配。(匹配到的函数可以比你指定的参数更多;若要防止这种情况,可将破折号 - 写成最后一个 arg_pattern。)默认情况下,只显示用户创建的对象;提供模式或 S - 修饰符可包括系统对象。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则会显示每个函数的附加信息,包括易变性、并行安全性、所有者、安全分类、是否防漏、访问权限、语言、内部名称(仅适用于 C 和 internal 函数)以及描述。特定函数的源代码可通过 \sf 查看。 + 修饰符可包括系统对象。如果在命令名后追加 +,则会显示每个函数的附加信息,包括易变性、并行安全性、所有者、安全分类、是否防漏、访问权限、语言、内部名称(仅适用于 C 和 internal 函数)以及描述。特定函数的源代码可通过 \sf 查看。 - \dF[x+] [ pattern ] + \dF[+] [ pattern ] - 列出文本搜索配置。如果指定了 pattern,则只显示名称与模式匹配的配置。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则会显示每个配置的完整描述,包括底层文本搜索解析器以及每种记号类型对应的词典列表。 + 列出文本搜索配置。如果指定了 pattern,则只显示名称与模式匹配的配置。如果在命令名后追加 +,则会显示每个配置的完整描述,包括底层文本搜索解析器以及每种记号类型对应的词典列表。 - \dFd[x+] [ pattern ] + \dFd[+] [ pattern ] - 列出文本搜索词典。如果指定了 pattern,则只显示名称与模式匹配的词典。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则会显示每个所选词典的附加信息,包括底层文本搜索模板和选项值。 + 列出文本搜索词典。如果指定了 pattern,则只显示名称与模式匹配的词典。如果在命令名后追加 +,则会显示每个所选词典的附加信息,包括底层文本搜索模板和选项值。 - \dFp[x+] [ pattern ] + \dFp[+] [ pattern ] - 列出文本搜索解析器。如果指定了 pattern,则只显示名称与模式匹配的解析器。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则会显示每个解析器的完整描述,包括底层函数和已识别的记号类型列表。 + 列出文本搜索解析器。如果指定了 pattern,则只显示名称与模式匹配的解析器。如果在命令名后追加 +,则会显示每个解析器的完整描述,包括底层函数和已识别的记号类型列表。 - \dFt[x+] [ pattern ] + \dFt[+] [ pattern ] - 列出文本搜索模板。如果指定了 pattern,则只显示名称与模式匹配的模板。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则会显示每个模板的附加信息,包括底层函数名。 + 列出文本搜索模板。如果指定了 pattern,则只显示名称与模式匹配的模板。如果在命令名后追加 +,则会显示每个模板的附加信息,包括底层函数名。 - \dg[Sx+] [ pattern ] + \dg[S+] [ pattern ] 列出数据库角色。(由于 usersgroups 的概念已经统一为 roles,此命令现在等同于 \du。)默认情况下,只显示用户创建的角色;提供 - S 修饰符可包括系统角色。如果指定了 pattern,则只列出名称与模式匹配的角色。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则会显示每个角色的附加信息;目前这会增加每个角色的注释。 + S 修饰符可包括系统角色。如果指定了 pattern,则只列出名称与模式匹配的角色。如果在命令名后追加 +,则会显示每个角色的附加信息;目前这会增加每个角色的注释。 - \dl[x+] + \dl[+] - 这是 \lo_list 的别名,后者会显示大对象列表。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则会列出每个大对象的相关权限(如果有)。 + 这是 \lo_list 的别名,后者会显示大对象列表。如果在命令名后追加 +,则会列出每个大对象的相关权限(如果有)。 - \dL[Sx+] [ pattern ] + \dL[S+] [ pattern ] 列出过程语言。如果指定了 pattern,则只列出名称与模式匹配的语言。默认情况下,只显示用户创建的语言;提供 S 修饰符可包括系统对象。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则每种语言都会连同其调用处理器、验证器、访问权限以及它是否为系统对象一起列出。 + class="parameter">pattern
,则只列出名称与模式匹配的语言。默认情况下,只显示用户创建的语言;提供 S 修饰符可包括系统对象。如果在命令名后追加 +,则每种语言都会连同其调用处理器、验证器、访问权限以及它是否为系统对象一起列出。 - \dn[Sx+] [ pattern ] + \dn[S+] [ pattern ] 列出模式(命名空间)。如果指定了 pattern,则只列出名称与模式匹配的模式。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则每个对象都会连同其相关权限和描述(如果有)一起列出。 + class="parameter">pattern
,则只列出名称与模式匹配的模式。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。如果在命令名后追加 +,则每个对象都会连同其相关权限和描述(如果有)一起列出。 - \do[Sx+] [ pattern [ arg_pattern [ arg_pattern ] ] ] + \do[S+] [ pattern [ arg_pattern [ arg_pattern ] ] ] - 列出操作符及其操作数类型和结果类型。如果指定了 pattern,则只列出名称与模式匹配的操作符。如果指定了一个 arg_pattern,则只列出其右参数类型名称与该模式匹配的前缀操作符。如果指定了两个 arg_pattern,则只列出参数类型名称与这些模式匹配的二元操作符。(对于一元操作符未使用的参数,也可以写成 -。)默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则会显示每个操作符的附加信息,包括底层函数名以及它是否防漏。 + 列出操作符及其操作数类型和结果类型。如果指定了 pattern,则只列出名称与模式匹配的操作符。如果指定了一个 arg_pattern,则只列出其右参数类型名称与该模式匹配的前缀操作符。如果指定了两个 arg_pattern,则只列出参数类型名称与这些模式匹配的二元操作符。(对于一元操作符未使用的参数,也可以写成 -。)默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。如果在命令名后追加 +,则会显示每个操作符的附加信息,包括底层函数名以及它是否防漏。 - \dO[Sx+] [ pattern ] + \dO[S+] [ pattern ] - 列出排序规则。如果指定了 pattern,则只列出名称与模式匹配的排序规则。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则每个排序规则都会连同其相关描述(如果有)一起列出。请注意,只会显示与当前数据库编码兼容的排序规则,因此在同一安装中的不同数据库里结果可能不同。 + 列出排序规则。如果指定了 pattern,则只列出名称与模式匹配的排序规则。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。如果在命令名后追加 +,则每个排序规则都会连同其相关描述(如果有)一起列出。请注意,只会显示与当前数据库编码兼容的排序规则,因此在同一安装中的不同数据库里结果可能不同。 - \dp[Sx] [ pattern ] + \dp[S] [ pattern ] - 列出表、视图和序列及其相关访问权限。如果指定了 pattern,则只列出名称与模式匹配的表、视图和序列。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。如果在命令名后追加 x,结果会以扩展模式显示。 - + 列出表、视图和序列及其相关访问权限。如果指定了 pattern,则只列出名称与模式匹配的表、视图和序列。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。 GRANT和 @@ -1288,7 +1233,7 @@ SELECT $1 \parse stmt1 - \dP[itnx+] [ pattern ] + \dP[itn+] [ pattern ] 列出分区关系。 @@ -1305,20 +1250,19 @@ SELECT $1 \parse stmt1 - 如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则还会显示每个关系分区大小的总和以及关系描述。如果 n+ 组合使用,则会显示两个大小:一个包括直接附加的叶分区的总大小,另一个显示包括间接附加子分区在内的所有分区总大小。 +如果在命令名后追加 +,则还会显示每个关系分区大小的总和以及关系描述。如果 n+ 组合使用,则会显示两个大小:一个包括直接附加的叶分区的总大小,另一个显示包括间接附加子分区在内的所有分区总大小。 - \drds[x] [ role-pattern [ database-pattern ] ] + \drds[ role-pattern [ database-pattern ] ] 列出已定义的配置设置。这些设置可以是特定于角色、特定于数据库,或者两者兼有。role-patterndatabase-pattern 分别用于选择要列出的特定角色和数据库。如果省略,或者指定了 - *,则会列出所有设置,包括那些未指定角色或数据库的设置。如果在命令名后追加 x,结果会以扩展模式显示。 - + *,则会列出所有设置,包括那些未指定角色或数据库的设置。 ALTER ROLE和 @@ -1330,7 +1274,7 @@ SELECT $1 \parse stmt1 - \drg[Sx] [ pattern ] + \drg[S] [ pattern ] 列出每个被授予角色成员身份的信息,包括被授予的选项(ADMIN、 @@ -1339,65 +1283,63 @@ SELECT $1 \parse stmt1 默认情况下,只显示授予用户创建角色的成员身份;提供 - S 修饰符可包括系统角色。如果指定了 pattern,则只列出名称与模式匹配的角色。如果在命令名后追加 x,结果会以扩展模式显示。 - + S 修饰符可包括系统角色。如果指定了 pattern,则只列出名称与模式匹配的角色。 - \dRp[x+] [ pattern ] + \dRp[+] [ pattern ] - 列出逻辑复制发布。如果指定了 pattern,则只列出名称与模式匹配的发布。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则还会显示与每个发布关联的表和模式。 + 列出逻辑复制发布。如果指定了 pattern,则只列出名称与模式匹配的发布。如果在命令名后追加 +,则还会显示与每个发布关联的表和模式。 - \dRs[x+] [ pattern ] + \dRs[+] [ pattern ] - 列出逻辑复制订阅。如果指定了 pattern,则只列出名称与模式匹配的订阅。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则会显示订阅的其他属性。 + 列出逻辑复制订阅。如果指定了 pattern,则只列出名称与模式匹配的订阅。如果在命令名后追加 +,则会显示订阅的其他属性。 - \dT[Sx+] [ pattern ] + \dT[S+] [ pattern ] - 列出数据类型。如果指定了 pattern,则只列出名称与模式匹配的类型。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则每个类型都会连同其内部名称和大小一起列出;对于 enum 类型,还会显示其允许值以及相关权限。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。 + 列出数据类型。如果指定了 pattern,则只列出名称与模式匹配的类型。如果在命令名后追加 +,则每个类型都会连同其内部名称和大小一起列出;对于 enum 类型,还会显示其允许值以及相关权限。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。 - \du[Sx+] [ pattern ] + \du[S+] [ pattern ] 列出数据库角色。(由于 usersgroups 的概念已经统一为 roles,此命令现在等同于 \dg。)默认情况下,只显示用户创建的角色;提供 - S 修饰符可包括系统角色。如果指定了 pattern,则只列出名称与模式匹配的角色。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则会显示每个角色的附加信息;目前这会增加每个角色的注释。 + S 修饰符可包括系统角色。如果指定了 pattern,则只列出名称与模式匹配的角色。如果在命令名后追加 +,则会显示每个角色的附加信息;目前这会增加每个角色的注释。 - \dx[x+] [ pattern ] + \dx[+] [ pattern ] - 列出已安装的扩展。如果指定了 pattern,则只列出名称与模式匹配的扩展。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则会列出属于每个匹配扩展的全部对象。 + 列出已安装的扩展。如果指定了 pattern,则只列出名称与模式匹配的扩展。如果在命令名后追加 +,则会列出属于每个匹配扩展的全部对象。 - \dX[x] [ pattern ] + \dX[ pattern ] - 列出扩展统计信息。如果指定了 pattern,则只列出名称与模式匹配的扩展统计信息。如果在命令名后追加 x,结果会以扩展模式显示。 - + 列出扩展统计信息。如果指定了 pattern,则只列出名称与模式匹配的扩展统计信息。 每种扩展统计信息的状态显示在以其统计类型命名的列中(例如 Ndistinct)。 @@ -1408,10 +1350,10 @@ SELECT $1 \parse stmt1 - \dy[x+] [ pattern ] + \dy[+] [ pattern ] - 列出事件触发器。如果指定了 pattern,则只列出名称与模式匹配的事件触发器。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则每个对象都会连同其相关描述一起列出。 + 列出事件触发器。如果指定了 pattern,则只列出名称与模式匹配的事件触发器。如果在命令名后追加 +,则每个对象都会连同其相关描述一起列出。 @@ -1658,11 +1600,7 @@ CREATE INDEX - 生成的查询按照返回的行的顺序执行,并在每行内从左到右执行,如果有多个列。NULL字段将被忽略。生成的查询文字 - 直接发送到服务器进行处理,因此它们不能是psql元命令,也不能包含psql - 变量引用。如果任何单个查询失败,剩余查询的执行将继续,除非设置了ON_ERROR_STOP。每个查询的执行 - 都受ECHO处理的影响。(通常在使用\gexec时,将ECHO设置为 - allqueries是明智的。)查询记录、单步模式、计时和其他查询执行功能也适用于每个生成的查询。 + 生成的查询按照返回行的顺序执行;如果有多列,则在每行内从左到右执行。NULL 字段会被忽略。生成的查询按原样发送到服务器进行处理,因此不能是psql元命令,也不能包含psql变量引用。如果某个查询失败,仍会继续执行其余查询,除非设置了ON_ERROR_STOP。每个查询的执行都受ECHO处理的影响。(通常,在使用\gexec时,适宜将ECHO设为allqueries。)查询日志、单步模式、计时及其他查询执行功能也适用于每个生成的查询。 如果当前查询缓冲区为空,则重新执行最近发送的查询。 @@ -1868,10 +1806,10 @@ SELECT - \l[x+] or \list[x+] [ pattern ] + \l[+] or \list[+] [ pattern ] - 列出服务器中的数据库,并显示其名称、所有者、字符集编码和访问权限。如果指定了 pattern,则只列出名称与模式匹配的数据库。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则还会显示数据库大小、默认表空间和描述。当前用户对其拥有 CONNECT 权限的数据库可以显示大小信息;如果当前用户是超级用户或具有 pg_read_all_stats 角色的权限,也可以显示大小信息。 + 列出服务器中的数据库,并显示其名称、所有者、字符集编码和访问权限。如果指定了 pattern,则只列出名称与模式匹配的数据库。如果在命令名后追加 +,则还会显示数据库大小、默认表空间和描述。当前用户对其拥有 CONNECT 权限的数据库可以显示大小信息;如果当前用户是超级用户或具有 pg_read_all_stats 角色的权限,也可以显示大小信息。 @@ -1902,7 +1840,7 @@ SELECT - 将文件存储到一个PostgreSQL大对象中。可选地,它将给定的注释与对象关联起来。例如: + 将文件存储到一个PostgreSQL大对象中。可选地,它将给定的注释与对象关联起来。例如: foo=> \lo_import '/home/peter/pictures/photo.xcf' 'a picture of me' lo_import 152801 @@ -1917,11 +1855,11 @@ lo_import 152801 - \lo_list[x+] + \lo_list[+] 显示当前存储在数据库中的全部 PostgreSQL - 大对象列表,以及为它们提供的任何注释。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则会列出每个大对象的相关权限(如果有)。 + 大对象列表,以及为它们提供的任何注释。如果在命令名后追加 +,则会列出每个大对象的相关权限(如果有)。 @@ -1981,28 +1919,6 @@ lo_import 152801 - - \parse statement_name - - - 基于目标预备语句对象的名称,从当前查询缓冲区创建一个预备语句。空字符串表示未命名的预备语句。 - - - - 示例: - -SELECT $1 \parse stmt1 - - - - - 此命令会使用扩展查询协议,不同于psql通常使用的简单查询协议。该命令会发出一条 - - 消息,因此可用于在psql中测试扩展查询协议。此命令只影响下一条被执行的查询;之后的所有查询默认仍会使用简单查询协议。 - - - - \password [ username ] @@ -2048,7 +1964,7 @@ SELECT $1 \parse stmt1 - 可调整打印选项有: + 可调整打印选项有: border @@ -2148,7 +2064,7 @@ SELECT $1 \parse stmt1 允许使用唯一缩写。 - aligned格式是标准的、人类可读的、格式良好的文本输出;这是默认设置。 + aligned格式是标准的、适合人阅读且排版整齐的文本输出;这是默认格式。 unaligned格式将一行中的所有列写在一行上,由当前活动的字段分隔符分隔。这对于创建可能被其他程序读取的输出很有用,例如,制表符分隔或逗号分隔格式。然而,如果字段分隔符字符出现在列的值中,则不会被特殊处理;因此,CSV格式可能更适合这些目的。 @@ -2565,61 +2481,6 @@ testdb=> \setenv LESS -imx4F - - \startpipeline - \sendpipeline - \syncpipeline - \endpipeline - \flushrequest - \flush - \getresults [ number_results ] - - - - 这组命令实现 SQL 语句的管道化。一个管道必须以 \startpipeline 开始,并以 \endpipeline 结束。其间可以出现任意数量的 \syncpipeline 命令,它会发送一条同步消息,但不会结束当前管道,并会刷新发送缓冲区。在管道模式下,语句会被发送到服务器,而不等待前面语句的结果。更多细节见 。 - - - - 管道进行期间执行的所有查询都使用扩展查询协议。以分号结束的查询会被追加到管道中。元命令 \bind、 - \bind_named\close_prepared 和 - \parse 可以在进行中的管道里使用。管道进行期间,\sendpipeline 会将当前查询缓冲区追加到管道中。其他元命令,如 - \g\gx 或 - \gdesc,则不允许在管道模式中使用。 - - - - \flushrequest 会向管道追加一条 flush 命令,使得可以在不发送 sync 或结束管道的情况下通过 - \getresults 读取结果。\getresults 会自动将尚未发送的数据推送到服务器。\flush 可用于手动推送未发送的数据。 - - - - \getresults 接受一个可选的 - number_results 参数。如果提供,则只读取前 - number_results 个待处理结果。若省略该参数或其值为 0,则读取所有待处理结果。 - - - - 当管道模式处于活动状态时,可使用一个专用的提示符变量来报告管道状态。详见 。 - - - - COPY 在管道模式中不支持。 - - - - 示例: - -\startpipeline -SELECT * FROM pg_class; -SELECT 1 \bind \sendpipeline -\flushrequest -\getresults -\endpipeline - - - - - @@ -2718,11 +2579,10 @@ SELECT 1 \bind \sendpipeline - \watch [ i[nterval]=seconds ] [ c[ount]=times ] [ m[in_rows]=rows ] [ seconds ] + \watch [ i[nterval]=seconds ] [ c[ount]=times ] [ seconds ] - 重复执行当前查询缓冲区(如同 \g 一样),直到被中断、查询失败、达到执行次数上限(如果给定)或查询返回的行数低于最小要求。两次执行之间等待指定的秒数(默认 2 秒)。默认等待时间可通过变量 - 修改。为保持向后兼容, + 重复执行当前查询缓冲区(如同 \g 一样),直到被中断、查询失败或达到执行次数上限(如果给定)。两次执行之间等待指定的秒数(默认 2 秒)。为保持向后兼容, seconds 可以带或不带 interval= 前缀。每次查询结果都会带有一个头部,其中包含 \pset title 字符串(如果有)、查询开始时的时间以及延迟间隔。 @@ -2744,11 +2604,10 @@ SELECT 1 \bind \sendpipeline - \z[Sx] [ pattern ] + \z[S] [ pattern ] - 列出表、视图和序列及其相关访问权限。如果指定了 pattern,则只列出名称与模式匹配的表、视图和序列。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。如果在命令名后追加 x,结果会以扩展模式显示。 - + 列出表、视图和序列及其相关访问权限。如果指定了 pattern,则只列出名称与模式匹配的表、视图和序列。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。 这是\dp的别名(显示权限)。 @@ -3126,34 +2985,8 @@ bar - - PIPELINE_COMMAND_COUNT - - - 正在运行的管道中排队的命令数 。 - - - - - PIPELINE_RESULT_COUNT - - - 正在进行的管道中,有多少条命令后面跟着 \flushrequest 或 - \syncpipeline,从而强制服务器发送结果。这些结果可以通过 - \getresults 取回。 - - - - - PIPELINE_SYNC_COUNT - - - 正在运行的管道中排队的同步消息数量 。 - - - PORT @@ -3203,14 +3036,6 @@ bar - - SERVICE - - - 服务名称(如果适用)。 - - - SHELL_ERROR @@ -3312,14 +3137,6 @@ bar - - WATCH_INTERVAL - - - 此变量设置\watch在两次执行查询之间等待的默认间隔,单位为秒。默认值为 2 秒。若在命令中指定了间隔,则会覆盖此变量。 - - - @@ -3329,7 +3146,7 @@ bar <acronym>SQL</acronym> 中插入变量 - psql变量的一个关键特性是可以把它们替换(插入)到常规SQL语句中,也可以把它们作为元命令的参数。此外,psql还提供了功能来确保被用作 SQL 文字和标识符的变量值会被正确地引用。插入一个值而不需要加引用的语法是在变量名前面加上一个冒号(:)。例如, + psql变量的一个关键特性是可以把它们替换(插入)到常规SQL语句中,也可以把它们作为元命令的参数。此外,psql还提供了功能来确保被用作 SQL 字面量和标识符的变量值会被正确地加引号。插入一个值而不加引号的语法是在变量名前面加上一个冒号(:)。例如, testdb=> \set foo 'my_table' testdb=> SELECT * FROM :foo; @@ -3416,10 +3233,6 @@ testdb=> INSERT INTO my_table VALUES (:'content'); - - %s - 服务名称。 - %/ @@ -3450,16 +3263,6 @@ testdb=> INSERT INTO my_table VALUES (:'content'); - - %P - - - 管道状态:不在管道中时为 off, - 在进行中的管道中时为 on, - 在已中止的管道中时为 abort。 - - - %R @@ -3989,28 +3792,6 @@ testdb=> \df int*pl * bigint - - 这里,+ 选项用于显示其中一个函数的附加信息,而 x 用于以扩展模式显示结果: - -testdb=> \df+x int*pl integer bigint -List of functions --[ RECORD 1 ]-------+----------------------------- -Schema | pg_catalog -Name | int48pl -Result data type | bigint -Argument data types | integer, bigint -Type | func -Volatility | immutable -Parallel | safe -Owner | postgres -Security | invoker -Leakproof? | no -Access privileges | -Language | internal -Internal name | int48pl -Description | implementation of + operator - - 在适合的情况下,可以使用 \crosstabview 命令将查询结果显示为交叉表: diff --git a/zh/16/ref/reassign_owned.sgml b/zh/16/ref/reassign_owned.sgml index 824834b8..ba7d9f7b 100644 --- a/zh/16/ref/reassign_owned.sgml +++ b/zh/16/ref/reassign_owned.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation REASSIGN OWNED 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/refresh_materialized_view.sgml b/zh/16/ref/refresh_materialized_view.sgml index 2ccb7ac0..7d0fed7a 100644 --- a/zh/16/ref/refresh_materialized_view.sgml +++ b/zh/16/ref/refresh_materialized_view.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation REFRESH MATERIALIZED VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/reindex.sgml b/zh/16/ref/reindex.sgml index cbc30ec6..bd52b65d 100644 --- a/zh/16/ref/reindex.sgml +++ b/zh/16/ref/reindex.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation REINDEX 7 - SQL - Language Statements + SQL - 语言语句 @@ -188,10 +188,7 @@ REINDEX [ ( option [, ...] ) ] { DA VERBOSE - - - 在每个索引被重建时,以 INFO 级别打印进度报告。 - + 在每个索引被重建时打印进度报告。 @@ -276,22 +273,13 @@ REINDEX [ ( option [, ...] ) ] { DA - 在REINDEX运行期间,会临时改为pg_catalog, - pg_temp。 - - - - 对单个索引或表重新索引,需要在相应表上具有 MAINTAIN - 权限。注意,对分区索引或分区表执行REINDEX时,需 - 要在该分区表上具有 MAINTAIN 权限,但在处理各个分 - 区时会跳过权限检查。对模式或数据库重新索引,则需要是该模式或数据库的 - 拥有者,或者具有角色的 - 权限。特别要注意,这意味着非超级用户也可能重建其他用户拥有的表的索引。 - 不过,作为一个特殊例外,REINDEX DATABASE、 - REINDEX SCHEMAREINDEX SYSTEM - 会跳过共享系统目录上的索引,除非用户对该目录具有 - MAINTAIN权限。 + 对单个索引或表重新索引,要求用户是该索引或表的拥有者。对模式或数据库 + 重新索引,则要求用户是该模式或数据库的拥有者。特别要注意,这意味着 + 非超级用户也可能重建其他用户拥有的表的索引。不过,作为一个特殊例外, + 当非超级用户执行REINDEX DATABASE、 + REINDEX SCHEMAREINDEX SYSTEM + 时,除非该用户拥有共享系统目录(而这通常并非如此),否则会跳过共享 + 系统目录上的索引。当然,超级用户始终可以重新索引任何对象。 @@ -304,7 +292,7 @@ REINDEX [ ( option [, ...] ) ] { DA 当对分区索引或分区表执行带TABLESPACE子句的 REINDEX时,只有叶分区的表空间引用会被更新。由于 - 分区索引本身不会更新,建议另外对相应的分区表单独执行 + 分区索引本身不会更新,建议另外对这些分区索引单独执行 ALTER TABLE ONLY,以便后续附加的任何新分区都继承 新表空间。如果命令失败,可能不会把所有索引都移动到新表空间。重新运行 该命令将重建所有叶分区,并把先前未处理的索引移动到新表空间。 @@ -322,8 +310,8 @@ REINDEX [ ( option [, ...] ) ] { DA 并发重建索引 - index - rebuilding concurrently + 索引 + 并发重建 diff --git a/zh/16/ref/reindexdb.sgml b/zh/16/ref/reindexdb.sgml index 20dc32bf..c9d7bfeb 100644 --- a/zh/16/ref/reindexdb.sgml +++ b/zh/16/ref/reindexdb.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation reindexdb 1 - Application + 应用程序 @@ -55,22 +55,30 @@ PostgreSQL documentation - - - - - - - - + dbname + - - - dbname - - - - + + reindexdb + connection-option + option + + + + + + + + + reindexdb + connection-option + option + + + + + + dbname @@ -162,9 +170,7 @@ PostgreSQL documentation reindexdb将打开njobs个到数据库的连接,因此请确保设置足够高,能容纳所有连接。 - - 注意,该选项与选项不兼容。 - + 注意,该选项与 选项不兼容。 @@ -373,6 +379,12 @@ PostgreSQL documentation + + 注解 + + reindexdb 可能需要多次连接到 PostgreSQL 服务器,每次都要求输入密码。在这种情况下,使用 ~/.pgpass 文件会很方便。更多信息见 + + 示例 diff --git a/zh/16/ref/release_savepoint.sgml b/zh/16/ref/release_savepoint.sgml index 59f96e68..a88766b0 100644 --- a/zh/16/ref/release_savepoint.sgml +++ b/zh/16/ref/release_savepoint.sgml @@ -10,13 +10,13 @@ PostgreSQL documentation 保存点 - releasing + 释放 RELEASE SAVEPOINT 7 - SQL - Language Statements + SQL - 语言语句 @@ -99,7 +99,7 @@ BEGIN; SAVEPOINT sp2; INSERT INTO table1 VALUES (3); RELEASE SAVEPOINT sp2; - INSERT INTO table1 VALUES (4))); -- generates an error + INSERT INTO table1 VALUES (4))); -- 产生错误 在这个例子中,应用程序请求释放保存点sp2,值 3 是在其中插入的。 这样会把该插入操作的事务上下文改为sp1。 @@ -107,8 +107,8 @@ BEGIN; 而值 3 现在也位于同一事务上下文中,因此同样会丢失。 由于此后所有其他命令都会被忽略,应用程序现在只能在以下两个命令中选择一个: -ROLLBACK; -ROLLBACK TO SAVEPOINT sp1; + ROLLBACK; + ROLLBACK TO SAVEPOINT sp1; 选择ROLLBACK将中止所有内容,包括值 1; 而ROLLBACK TO SAVEPOINT sp1会保留值 1,并允许事务继续。 diff --git a/zh/16/ref/reset.sgml b/zh/16/ref/reset.sgml index e8aeae8c..5e249ff9 100644 --- a/zh/16/ref/reset.sgml +++ b/zh/16/ref/reset.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation RESET 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/revoke.sgml b/zh/16/ref/revoke.sgml index 8d7945a5..3ef5f192 100644 --- a/zh/16/ref/revoke.sgml +++ b/zh/16/ref/revoke.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation REVOKE 7 - SQL - Language Statements + SQL - 语言语句 @@ -23,7 +23,7 @@ PostgreSQL documentation REVOKE [ GRANT OPTION FOR ] - { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER | MAINTAIN } + { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER } [, ...] | ALL [ PRIVILEGES ] } ON { [ TABLE ] table_name [, ...] | ALL TABLES IN SCHEMA schema_name [, ...] } @@ -131,7 +131,7 @@ REVOKE [ { ADMIN | INHERIT | SET } OPTION FOR ] [ GRANTED BY role_specification ] [ CASCADE | RESTRICT ] -where role_specification can be: +其中role_specification可以是: [ GROUP ] role_name | PUBLIC diff --git a/zh/16/ref/rollback.sgml b/zh/16/ref/rollback.sgml index d1c8fdd2..1a91b03e 100644 --- a/zh/16/ref/rollback.sgml +++ b/zh/16/ref/rollback.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ROLLBACK 7 - SQL - Language Statements + SQL - 语言语句 @@ -37,7 +37,7 @@ ROLLBACK [ WORK | TRANSACTION ] [ AND [ NO ] CHAIN ] 参数 - chained transactions + 链式事务 diff --git a/zh/16/ref/rollback_prepared.sgml b/zh/16/ref/rollback_prepared.sgml index 7ffe1af8..7438d9cc 100644 --- a/zh/16/ref/rollback_prepared.sgml +++ b/zh/16/ref/rollback_prepared.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ROLLBACK PREPARED 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/rollback_to.sgml b/zh/16/ref/rollback_to.sgml index 843a612e..d5d8c0e0 100644 --- a/zh/16/ref/rollback_to.sgml +++ b/zh/16/ref/rollback_to.sgml @@ -10,13 +10,13 @@ PostgreSQL documentation 保存点 - rolling back + 回滚 ROLLBACK TO SAVEPOINT 7 - SQL - Language Statements + SQL - 语言语句 @@ -73,8 +73,8 @@ ROLLBACK [ WORK | TRANSACTION ] TO [ SAVEPOINT ] savepoint_name 就保存点而言,游标带有一些非事务性的行为。凡是在某个保存点内打开的游标, 在回滚该保存点时都会被关闭。如果先前打开的游标在某个随后又被回滚的保存点内受到了 - FETCHMOVE命令的影响,那么该游标会保留在这些命令使其指向的位置上 - (也就是说,由FETCHMOVE引起的游标移动不会被回滚)。 + FETCHMOVE命令的影响,那么该游标会保留在FETCH使其指向的位置上 + (也就是说,由FETCH引起的游标移动不会被回滚)。 关闭游标同样不会因回滚而撤销。不过,如果游标查询导致了其他副作用(例如该查询调用的 易变函数带来的副作用),且这些副作用发生在后来被回滚的保存点期间,那么它们 被回滚。如果某个游标的执行导致事务中止,该游标会进入不可执行状态, diff --git a/zh/16/ref/savepoint.sgml b/zh/16/ref/savepoint.sgml index fdca4151..5f9bea25 100644 --- a/zh/16/ref/savepoint.sgml +++ b/zh/16/ref/savepoint.sgml @@ -10,13 +10,13 @@ PostgreSQL documentation 保存点 - defining + 定义 SAVEPOINT 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/security_label.sgml b/zh/16/ref/security_label.sgml index fc969a4a..9c2b13d0 100644 --- a/zh/16/ref/security_label.sgml +++ b/zh/16/ref/security_label.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SECURITY LABEL 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/select.sgml b/zh/16/ref/select.sgml index 1b47aa6d..19abe844 100644 --- a/zh/16/ref/select.sgml +++ b/zh/16/ref/select.sgml @@ -21,7 +21,7 @@ PostgreSQL documentation SELECT 7 - SQL - Language Statements + SQL - 语言语句 @@ -1485,7 +1485,7 @@ SELECT * FROM (SELECT * FROM mytable FOR UPDATE) ss ORDER BY column1; REPEATABLE READSERIALIZABLE事务隔离级别下, - 这将导致序列化失败(带有SQLSTATE'40001'), + 这将导致串行化失败(SQLSTATE'40001'), 因此在这些隔离级别下不可能接收到无序的行。 diff --git a/zh/16/ref/select_into.sgml b/zh/16/ref/select_into.sgml index a05e57e8..12a48774 100644 --- a/zh/16/ref/select_into.sgml +++ b/zh/16/ref/select_into.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SELECT INTO 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/set.sgml b/zh/16/ref/set.sgml index ab67075e..9702d560 100644 --- a/zh/16/ref/set.sgml +++ b/zh/16/ref/set.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SET 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/set_constraints.sgml b/zh/16/ref/set_constraints.sgml index 53d0c7a0..e5588db7 100644 --- a/zh/16/ref/set_constraints.sgml +++ b/zh/16/ref/set_constraints.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SET CONSTRAINTS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/set_role.sgml b/zh/16/ref/set_role.sgml index ed65dec8..1e345db6 100644 --- a/zh/16/ref/set_role.sgml +++ b/zh/16/ref/set_role.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SET ROLE 7 - SQL - Language Statements + SQL - 语言语句 @@ -30,16 +30,7 @@ RESET ROLE 描述 - - 这个命令将当前 SQL 会话的当前用户标识符设置为 - role_name。 - 角色名既可以写成标识符,也可以写成字符串字面量。 - 执行SET ROLE之后,对 SQL 命令的权限检查会按照 - 最初登录的就是该角色那样进行。注意, - SET ROLE和 - SET SESSION AUTHORIZATION是例外:对这两个命令的权限检查, - 分别仍然使用当前会话用户和初始会话用户(即已认证用户)。 - + 该命令把当前 SQL 会话的当前用户标识符设置为 role_name。角色名可以写成标识符或字符串字面量。在 SET ROLE 之后,SQL 命令的权限检查会视同指定角色是最初登录的角色。 当前会话用户必须对指定的 @@ -81,6 +72,8 @@ RESET ROLE 那么无论是否使用SET ROLE,该角色的权限都无法行使。 + 请注意,当超级用户选择通过 SET ROLE 切换到非超级用户角色时,会失去其超级用户权限。 + SET ROLE的效果与 SET SESSION AUTHORIZATION相近, diff --git a/zh/16/ref/set_session_auth.sgml b/zh/16/ref/set_session_auth.sgml index e520dd49..9ec07ce6 100644 --- a/zh/16/ref/set_session_auth.sgml +++ b/zh/16/ref/set_session_auth.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SET SESSION AUTHORIZATION 7 - SQL - Language Statements + SQL - 语言语句 @@ -46,7 +46,7 @@ RESET SESSION AUTHORIZATION - 只有当初始会话用户(即已认证用户)具有超级用户权限时, + 只有当初始会话用户(即已认证用户)最初具有超级用户权限时, 才能更改会话用户标识符。否则,只有当该命令指定的是已认证用户名时, 才会被接受。 diff --git a/zh/16/ref/set_transaction.sgml b/zh/16/ref/set_transaction.sgml index ca7f3e50..8b3470a9 100644 --- a/zh/16/ref/set_transaction.sgml +++ b/zh/16/ref/set_transaction.sgml @@ -26,7 +26,7 @@ PostgreSQL documentation SET TRANSACTION 7 - SQL - Language Statements + SQL - 语言语句 @@ -66,7 +66,7 @@ SET SESSION CHARACTERISTICS AS TRANSACTION transa - 一个事务的隔离级别决定当其他事务并行运行时该事务能看见什么数据: + 一个事务的隔离级别决定当其他事务并发运行时该事务能看见什么数据: @@ -137,7 +137,7 @@ SET SESSION CHARACTERISTICS AS TRANSACTION transa 事务属性才会生效。当为一个事务同时选择这三个属性时,该事务在 首次获取其快照时可能会阻塞;在此之后,它便可以运行,而无需承担普通 SERIALIZABLE事务的常规开销,也不会有促成 - 序列化失败或因序列化失败而被取消的风险。这种模式非常适合长时间运行的 + 串行化失败或因串行化失败而被取消的风险。这种模式非常适合长时间运行的 报表或备份。 diff --git a/zh/16/ref/show.sgml b/zh/16/ref/show.sgml index 3b4be6bd..81bd6a80 100644 --- a/zh/16/ref/show.sgml +++ b/zh/16/ref/show.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SHOW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/start_transaction.sgml b/zh/16/ref/start_transaction.sgml index 57a74b2f..5026fa70 100644 --- a/zh/16/ref/start_transaction.sgml +++ b/zh/16/ref/start_transaction.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation START TRANSACTION 7 - SQL - Language Statements + SQL - 语言语句 @@ -64,15 +64,16 @@ START TRANSACTION [ transaction_mode - DEFERRABLE 这一 - transaction_mode 是 - PostgreSQL语言扩展。 + DEFERRABLE + transaction_mode + 是PostgreSQL的一种语言扩展。 SQL 标准要求在连续的transaction_modes之间有逗号, - 但出于历史原因PostgreSQL允许省略逗号。 + 但出于历史原因, + PostgreSQL允许省略逗号。 diff --git a/zh/16/ref/truncate.sgml b/zh/16/ref/truncate.sgml index aa2ce51c..ff1e0bc9 100644 --- a/zh/16/ref/truncate.sgml +++ b/zh/16/ref/truncate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation TRUNCATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/unlisten.sgml b/zh/16/ref/unlisten.sgml index 5e73e99e..6b52f1af 100644 --- a/zh/16/ref/unlisten.sgml +++ b/zh/16/ref/unlisten.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation UNLISTEN 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/ref/update.sgml b/zh/16/ref/update.sgml index a3c965df..4ace7c49 100644 --- a/zh/16/ref/update.sgml +++ b/zh/16/ref/update.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation UPDATE 7 - SQL - Language Statements + SQL - 语言语句 @@ -313,12 +313,12 @@ UPDATE count 在被移动的行上并发执行UPDATE或 - DELETE时,有可能收到序列化失败错误。假设会话 1 - 正在更新某个分区键,与此同时,一个对该行可见的并发会话 2 对该行 + DELETE时,有可能收到串行化失败错误。假设会话 1 + 正在对某个分区键执行UPDATE,与此同时,一个能够看到该行的并发会话 2 对该行 执行UPDATEDELETE操作。在 这种情况下,会话 2 的UPDATE或 - DELETE将检测到行移动,并引发序列化失败错误 - (其 SQLSTATE 代码始终为'40001')。如果发生 + DELETE将检测到行移动,并引发串行化失败错误 + (其 SQLSTATE 代码始终为'40001')。如果发生 这种情况,应用程序可能需要重试事务。在表未分区或没有发生行移动 的通常情况下,会话 2 会识别出新更新的那一行,并在这个新行版本上执行 UPDATE/DELETE。 diff --git a/zh/16/ref/vacuum.sgml b/zh/16/ref/vacuum.sgml index c3b9c5ec..b185d665 100644 --- a/zh/16/ref/vacuum.sgml +++ b/zh/16/ref/vacuum.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation VACUUM 7 - SQL - Language Statements + SQL - 语言语句 @@ -22,6 +22,7 @@ PostgreSQL documentation VACUUM [ ( option [, ...] ) ] [ table_and_columns [, ...] ] +VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ ANALYZE ] [ table_and_columns [, ...] ] 其中option可以是下列之一: @@ -42,7 +43,7 @@ VACUUM [ ( option [, ...] ) ] [ 其中table_and_columns是: - [ ONLY ] table_name [ * ] [ ( column_name [, ...] ) ] + table_name [ ( column_name [, ...] ) ] @@ -75,11 +76,13 @@ VACUUM [ ( option [, ...] ) ] [ 并行清理。 - 如需禁用该功能,可以使用PARALLEL选项并将并行工作者数指定为零。 + 如需禁用该功能,可以使用PARALLEL选项并将并行工作进程数指定为零。 VACUUM FULL会把表的全部内容重写到一个没有额外空闲空间的新磁盘文件中, 从而让未使用的空间能够返还给操作系统。这种形式要慢得多,并且在处理每个表时都需要 ACCESS EXCLUSIVE锁。 + + 当选项列表用圆括号括起来时,选项可以按任意顺序书写。如果不加圆括号,则必须严格按照上面所示的顺序指定选项。带圆括号的语法是在PostgreSQL 9.0 中加入的;不带圆括号的语法已被弃用。 @@ -113,9 +116,7 @@ VACUUM [ ( option [, ...] ) ] [ VERBOSE - - 为每个表以INFO级别输出详细的清理活动报告。 - + 为每个表输出详细的清理活动报告。 @@ -209,14 +210,7 @@ VACUUM [ ( option [, ...] ) ] [ TRUNCATE - - 指定VACUUM应尝试截去表末尾的空页,使这些被截断页面占用的磁盘空间 - 能够返还给操作系统。通常这是期望的行为,也是默认行为,除非 - 被设为 false,或者待清理表的 - vacuum_truncate选项被设为 false。将此选项设为 false 有助于避免 - 截断操作所需的表级ACCESS EXCLUSIVE锁。使用FULL选项时, - 此选项会被忽略。 - + 指定VACUUM应尝试截去表末尾的空页,使这些被截断页面占用的磁盘空间能够返还给操作系统。通常这是期望的行为,也是默认行为,除非待清理表的vacuum_truncate选项被设为 false。将此选项设为 false 有助于避免截断操作所需的表级ACCESS EXCLUSIVE锁。使用FULL选项时,此选项会被忽略。 @@ -320,12 +314,7 @@ VACUUM [ ( option [, ...] ) ] [ table_name - - 要清理的特定表或物化视图的名称(可选地带模式限定)。 - 如果在表名前指定ONLY,则只清理该表。 - 如果未指定ONLY,则还会清理该表及其所有继承子表或分区(如果有)。 - 也可以在表名后显式指定*,以明确表示要清理继承子表(或分区)。 - + 要清理的特定表或物化视图的名称(可选地带模式限定)。如果指定的表是分区表,则清理它的所有叶子分区。 @@ -353,14 +342,11 @@ VACUUM [ ( option [, ...] ) ] [ 注解 - 要清理一个表,通常必须拥有该表上的MAINTAIN权限。 + 要清理一个表,通常调用者必须是该表的拥有者或超级用户。 不过,数据库拥有者可以清理其数据库中的所有表,但共享系统目录除外。 - VACUUM会跳过调用用户无权清理的任何表。 - - - - 当VACUUM运行时,会被临时改为 - pg_catalog, pg_temp。 + (对共享系统目录的这一限制意味着,真正意义上的全数据库 + VACUUM 只能由超级用户执行。) + VACUUM 会跳过调用用户无权清理的任何表。 @@ -374,7 +360,7 @@ VACUUM [ ( option [, ...] ) ] [ - 我们建议定期对所有数据库执行清理,以移除死行。PostgreSQL提供了一个autovacuum机制, + 我们建议定期对所有数据库执行清理,以移除死行。PostgreSQL提供了一个自动清理(autovacuum)机制, 可以自动执行常规清理维护。有关自动与手动清理的更多信息,参见 @@ -392,8 +378,8 @@ VACUUM [ ( option [, ...] ) ] [ VACUUM会显著增加 I/O 流量,这可能导致其他活动会话性能变差。 - 因此,有时建议使用基于代价的清理延迟特性。对于并行清理,每个工作者的睡眠时长 - 都与该工作者完成的工作量成比例。详见。 + 因此,有时建议使用基于代价的清理延迟特性。对于并行清理,每个工作进程的睡眠时长 + 都与该工作进程完成的工作量成比例。详见 @@ -409,7 +395,7 @@ VACUUM [ ( option [, ...] ) ] [ 示例 - 清理单个表onek,对其执行优化器分析,并打印详细的清理活动报告: + 清理单个表onek,对其进行分析以供优化器使用,并打印详细的清理活动报告: VACUUM (VERBOSE, ANALYZE) onek; @@ -422,14 +408,6 @@ VACUUM (VERBOSE, ANALYZE) onek; 在SQL标准中没有VACUUM语句。 - - - 下列语法在PostgreSQL 9.0版本之前使用,并且目前仍受支持: - -VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ ANALYZE ] [ table_and_columns [, ...] ] - - 请注意,在这种语法中,选项必须严格按所示顺序指定。 - diff --git a/zh/16/ref/vacuumdb.sgml b/zh/16/ref/vacuumdb.sgml index 4396e2e0..040dcb38 100644 --- a/zh/16/ref/vacuumdb.sgml +++ b/zh/16/ref/vacuumdb.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation vacuumdb 1 - Application + 应用程序 @@ -36,13 +36,7 @@ PostgreSQL documentation - - - dbname - - - - + dbname @@ -53,44 +47,40 @@ PostgreSQL documentation - - + + + + + + + schema + + + + + + + + + + schema + + - schema - - - dbname - - - - + dbname vacuumdb connection-option option - - - - - - - - schema - - - - - - dbname - - - - + + + + @@ -132,8 +122,8 @@ PostgreSQL documentation - 指定给定一次 缓冲区访问策略(Buffer Access Strategy) - 环形缓冲区大小,供 vacuumdb 调用使用。这个大小用于计算将作为该策略一部分被重用的共享缓冲区数量。参见 + 为一次给定的 vacuumdb 调用指定缓冲区访问策略(Buffer Access Strategy) + 环形缓冲区大小。这个大小用于计算将作为该策略一部分被重用的共享缓冲区数量。参见 @@ -187,7 +177,7 @@ PostgreSQL documentation - 积极地冻结元组。 + 激进地冻结元组。 @@ -225,12 +215,12 @@ PostgreSQL documentation - 仅对 multixact ID 年龄至少为 mxid_age - 的表执行清理或分析命令。此设置可用于优先处理表,以防止 multixact ID 回卷 + 仅对 多事务 ID 年龄至少为 mxid_age + 的表执行清理或分析命令。此设置可用于优先处理表,以防止 多事务 ID 回卷 (见 )。 - 就此选项而言,一个关系的 multixact ID 年龄,是其主关系及其关联的 + 就此选项而言,一个关系的 多事务 ID 年龄,是其主关系及其关联的 TOAST 表(如果存在)年龄中的较大者。由于 vacuumdb 发出的命令在必要时也会处理该关系的 TOAST 表,因此无需单独考虑它。 @@ -254,28 +244,7 @@ PostgreSQL documentation - - - - - 仅分析那些在列、索引表达式或扩展统计信息对象上缺少统计信息的关系。与 - 一起使用时,此选项可防止 - vacuumdb 临时用按较低统计目标生成的统计信息替换现有统计信息, - 从而避免查询优化器短暂地作出更差的选择。 - - - 此选项只能与 配合使用。 - - - 注意, 要求拥有 - SELECT 权限,以访问 - pg_statistic - 和 - pg_statistic_ext_data, - 而这些权限默认只授予超级用户。 - - - + @@ -579,6 +548,12 @@ PostgreSQL documentation + + 注解 + + vacuumdb可能需要多次连接到PostgreSQL服务器,每次都要询问密码。在这种情况下,使用~/.pgpass文件会比较方便。更多信息见 + + 示例 diff --git a/zh/16/ref/values.sgml b/zh/16/ref/values.sgml index e5b00372..8c6d7597 100644 --- a/zh/16/ref/values.sgml +++ b/zh/16/ref/values.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation VALUES 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/16/reference.sgml b/zh/16/reference.sgml index 31e44ec1..0968de0c 100644 --- a/zh/16/reference.sgml +++ b/zh/16/reference.sgml @@ -236,7 +236,6 @@ &pgamcheck; &pgBasebackup; &pgbench; - &pgCombinebackup; &pgConfig; &pgDump; &pgDumpall; @@ -266,7 +265,6 @@ &pgarchivecleanup; &pgChecksums; &pgControldata; - &pgCreateSubscriber; &pgCtl; &pgResetwal; &pgRewind; @@ -274,7 +272,6 @@ &pgtesttiming; &pgupgrade; &pgwaldump; - &pgwalsummary; &postgres; diff --git a/zh/16/regress.sgml b/zh/16/regress.sgml index 39fc858e..437361f0 100644 --- a/zh/16/regress.sgml +++ b/zh/16/regress.sgml @@ -385,34 +385,11 @@ make check LANG=C ENCODING=EUC_JP 自定义服务器设置 - 运行测试套件时,有几种方式可以使用自定义服务器设置。这对于启用额外日志、 - 调整资源限制,或启用额外的运行时检查(例如 - )可能很有用。但请注意, - 并非所有测试都能在任意设置下都顺利通过。 - - - - 在测试准备过程中,内部运行的各个initdb命令可以通过 - 环境变量PG_TEST_INITDB_EXTRA_OPTS传入附加选项。例如, - 要在启用校验和并使用自定义 WAL 段大小和work_mem - 设置的情况下运行测试,可使用: - -make check PG_TEST_INITDB_EXTRA_OPTS='-k --wal-segsize=4 -c work_mem=50MB' - - - - - 对于核心回归测试套件以及其他由pg_regress驱动的测试, - 自定义运行时服务器设置还可以通过PGOPTIONS环境变量 - 来设置(适用于允许这样设置的参数),例如: + 运行回归测试套件时使用的自定义服务器设置可以通过 + PGOPTIONS环境变量来设置(适用于允许这样设置的参数): make check PGOPTIONS="-c debug_parallel_query=regress -c work_mem=50MB" - (这利用了 libpq 提供的功能;详情见。) - - - 在针对临时安装运行时,也可以通过提供预先写好的 postgresql.conf来设置自定义参数: @@ -422,6 +399,10 @@ make check EXTRA_REGRESS_OPTS="--temp-config=test_postgresql.conf" + + 这对于启用额外日志、调整资源限制,或启用额外的运行时检查(例如 + )可能很有用。 + diff --git a/zh/16/release-16.sgml b/zh/16/release-16.sgml index 14d142e6..b468b6af 100644 --- a/zh/16/release-16.sgml +++ b/zh/16/release-16.sgml @@ -1717,14 +1717,14 @@ Branch: REL_14_STABLE [15fd7a3e2] 2026-07-28 10:56:39 +0200 --> - 在清理 GIN 索引 posting-tree 期间响应查询取消并遵守清理延迟 + 在清理 GIN 索引倒排树期间响应查询取消并遵守清理延迟 (Paul Kim、Alexander Korotkov) § - 常见值的 posting tree 可能很大,因此遗漏这项检查可能导致清理运行 + 常见值的倒排树可能很大,因此遗漏这项检查可能导致清理运行 很长时间后才注意到中断。 @@ -3373,7 +3373,7 @@ Branch: REL_15_STABLE [bab4f7fa5] 2026-05-05 10:32:42 +0900 Branch: REL_14_STABLE [172034f6e] 2026-05-05 10:34:07 +0900 --> - 在假定可排序类型上的等值条件意味着唯一性之前,检查是否存在非确定性排序规则 + 在假定支持排序规则的类型上的等值条件意味着唯一性之前,检查是否存在非确定性排序规则 (Richard Guo) § § @@ -8928,7 +8928,7 @@ Branch: REL_14_STABLE [5144e1f8f] 2025-03-11 12:50:35 +0100 Branch: REL_13_STABLE [f5b4a0b49] 2025-03-11 12:50:35 +0100 --> - 检测 BRIN 索引操作符类中缺失的支持过程,并报告错误而不是崩溃 + 检测 BRIN 索引操作符类中缺失的支持函数,并报告错误而不是崩溃 (Álvaro Herrera) § @@ -10169,7 +10169,7 @@ Branch: REL_14_STABLE [d9d5e1b48] 2024-12-07 14:28:16 -0500 Branch: REL_13_STABLE [531cbd8b7] 2024-12-07 14:28:16 -0500 --> - 修复操作符族成员操作符或支持过程可能成为悬空引用的情况 + 修复操作符族成员操作符或支持函数可能成为悬空引用的情况 (Tom Lane) § § diff --git a/zh/16/runtime.sgml b/zh/16/runtime.sgml index ece414fc..f4affc19 100644 --- a/zh/16/runtime.sgml +++ b/zh/16/runtime.sgml @@ -1,7 +1,6 @@ - 服务器设置和操作 @@ -13,11 +12,10 @@ - <productname>PostgreSQL</productname>用户账户 - postgres user + postgres 用户 @@ -34,7 +32,6 @@ - 创建一个数据库集簇 @@ -47,7 +44,7 @@ - 在做任何事情之前,必须先在磁盘上初始化一个数据库存储区域。我们把它称为数据库集簇。(SQL 标准使用术语 catalog cluster。)数据库集簇是由一个正在运行的数据库服务器实例管理的一组数据库。初始化之后,数据库集簇中会包含一个名为postgres的数据库,作为供工具、用户和第三方应用使用的默认数据库。数据库服务器本身并不要求该postgres数据库存在,但许多外部工具程序都假定它存在。初始化期间,集簇中还会创建另外两个数据库,名为template1template0。顾名思义,它们会作为后续新建数据库的模板;不应将它们用于实际工作。(关于在集簇中创建新数据库的信息,见。) + 在做任何事情之前,必须先在磁盘上初始化一个数据库存储区域。我们把它称为数据库集簇。(SQL 标准使用术语目录集簇(catalog cluster)。)数据库集簇是由一个正在运行的数据库服务器实例管理的一组数据库。初始化之后,数据库集簇中会包含一个名为postgres的数据库,作为供工具、用户和第三方应用使用的默认数据库。数据库服务器本身并不要求该postgres数据库存在,但许多外部工具程序都假定它存在。初始化期间,集簇中还会创建另外两个数据库,名为template1template0。顾名思义,它们会作为后续新建数据库的模板;不应将它们用于实际工作。(关于在集簇中创建新数据库的信息,见。) @@ -67,7 +64,6 @@ - 除了使用 选项,也可以设置环境变量 PGDATAPGDATA @@ -112,9 +108,7 @@ postgres$ initdb -D /usr/local/pgsql/data 另外,指定,以避免使用默认的trust认证方式;或者在运行initdb之后、首次启动服务器之前修改生成的pg_hba.conf文件。(其他合理方法包括使用peer认证,或使用文件系统权限限制连接。更多信息见。) - - initdb还会为数据库集簇初始化默认区域设置locale。通常,它只是采用环境中的区域设置,并将其应用到新初始化的数据库。你也可以为数据库指定不同的区域设置;更多信息见。该数据库集簇内部使用的默认排序顺序由initdb设定。虽然你可以创建采用不同排序顺序的新数据库,但initdb创建的模板数据库所使用的排序顺序,若不删除并重建它们就无法更改。使用非CPOSIX区域设置还会带来性能影响,因此第一次就做出正确选择很重要。 - + initdb 还会初始化数据库集簇的默认区域设置区域设置。通常,它会直接采用环境中的区域设置,并将其应用于初始化的数据库。可以为数据库指定不同的区域设置;更多信息见 。特定数据库集簇中使用的默认排序顺序由 initdb 设置,虽然你可以使用不同的排序顺序创建新数据库,但 initdb 创建的模板数据库所使用的顺序,只有删除并重建这些数据库才能更改。使用 CPOSIX 以外的区域设置还会影响性能。因此,一开始就作出正确选择很重要。 initdb还会为数据库集簇设置默认字符集编码。通常应选择与区域设置相匹配的字符集编码。详见。 @@ -139,7 +133,6 @@ postgres$ initdb -D /usr/local/pgsql/data - 文件系统 @@ -147,7 +140,6 @@ postgres$ initdb -D /usr/local/pgsql/data - NFS @@ -162,9 +154,7 @@ postgres$ initdb -D /usr/local/pgsql/data 对于在PostgreSQL中使用NFS,唯一硬性要求是文件系统必须使用hard选项挂载。使用hard选项时,如果出现网络问题,进程可能会无限期地挂起,因此这种配置需要配套谨慎的监控措施。soft选项会在网络问题出现时中断系统调用,但PostgreSQL不会重试以这种方式被中断的系统调用,因此任何此类中断都会导致报告 I/O 错误。 - - 没有必要使用sync挂载选项。async选项的行为已经足够,因为PostgreSQL会在适当的时候发出fsync调用来刷新写缓存。(这和它在本地文件系统上的工作方式类似。)但是,强烈建议在支持该选项的NFS服务器端系统上使用sync导出选项(主要是 Linux)。否则,NFS 客户端上的fsync或等效操作实际上并不能保证数据到达服务器上的持久存储,这可能导致类似于将参数设为关闭时那样的损坏。这些挂载和导出选项的默认值在不同厂商和版本间并不相同,因此无论如何都建议检查它们,并且最好显式指定,以避免歧义。 - + 没有必要使用 sync 挂载选项。async 选项的行为已经足够,因为 PostgreSQL 会在适当的时候发出 fsync 调用将写缓存刷盘。(这和它在本地文件系统上的工作方式类似。)但是,强烈建议在支持该选项的 NFS 服务器端系统上使用 sync 导出选项(主要是 Linux)。否则,NFS 客户端上的 fsync 或等效操作实际上并不能保证数据到达服务器上的持久存储,这可能导致类似于将参数 设为关闭时那样的损坏。这些挂载和导出选项的默认值在不同厂商和版本间并不相同,因此无论如何都建议检查它们,并且最好显式指定,以避免歧义。 在某些情况下,可以通过 NFS 或更底层的协议(例如 iSCSI)访问外部存储产品。在后一种情况下,存储会表现为块设备,可以在其上创建任意可用的文件系统。这种方式或许能让 DBA 不必应对 NFS 的某些特性,但当然,管理远程存储的复杂性会转移到其他层面。 @@ -175,7 +165,6 @@ postgres$ initdb -D /usr/local/pgsql/data - 启动数据库服务器 @@ -215,7 +204,7 @@ pg_ctl start -l logfile - 通常,你会希望在计算机启动时就启动数据库服务器。booting启动服务器时自动启动脚本依赖于操作系统。PostgreSQLcontrib/start-scripts 目录中附带了一些示例脚本。安装这些脚本需要 root 权限。 + 通常,你会希望在计算机启动时就启动数据库服务器。引导期间启动服务器自动启动脚本依赖于操作系统。PostgreSQLcontrib/start-scripts 目录中附带了一些示例脚本。安装这些脚本需要 root 权限。 @@ -232,14 +221,14 @@ su postgres -c 'pg_ctl start -D /usr/local/pgsql/data -l serverlog' 对于FreeBSD,请查看PostgreSQL源码发布包中的contrib/start-scripts/freebsd文件。 - FreeBSDstart script + FreeBSD启动脚本 OpenBSD上,把以下内容加入/etc/rc.local: - OpenBSDstart script + OpenBSD启动脚本 if [ -x /usr/local/pgsql/bin/pg_ctl -a -x /usr/local/pgsql/bin/postgres ]; then su -l postgres -c '/usr/local/pgsql/bin/pg_ctl start -s -l /var/postgresql/log -D /usr/local/pgsql/data' @@ -252,7 +241,7 @@ fi Linux系统上,可以把 - Linuxstart script + Linux启动脚本 /usr/local/pgsql/bin/pg_ctl start -l logfile -D /usr/local/pgsql/data @@ -291,14 +280,14 @@ WantedBy=multi-user.target NetBSD上,可根据偏好使用FreeBSDLinux的启动脚本。 - NetBSDstart script + NetBSD启动脚本 Solaris上,创建一个名为/etc/init.d/postgresql的文件,其中包含以下内容: - Solarisstart script + Solaris启动脚本 su - postgres -c "/usr/local/pgsql/bin/pg_ctl start -l logfile -D /usr/local/pgsql/data" @@ -360,7 +349,6 @@ DETAIL: Failed system call was semget(5440126, 17, 03600). - 客户端连接问题 @@ -372,7 +360,7 @@ DETAIL: Failed system call was semget(5440126, 17, 03600). psql: error: connection to server at "server.joe.com" (123.123.123.123), port 5432 failed: Connection refused Is the server running on that host and accepting TCP/IP connections? - 这是一个典型的我找不到可通信的服务器错误。上面这种情况发生在尝试使用 TCP/IP 通信时。一个常见错误是忘记配置,从而导致服务器不接受远程 TCP 连接。 + 这是一个典型的我找不到可通信的服务器错误。上面这种情况发生在尝试使用 TCP/IP 通信时。一个常见错误是忘记配置服务器以允许 TCP/IP 连接。 @@ -391,15 +379,13 @@ psql: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: No such - 管理内核资源 - PostgreSQL有时会耗尽操作系统的各种资源限制,尤其是在同一系统上运行多个服务器副本,或在非常大型的安装环境中时更是如此。本节解释PostgreSQL使用的内核资源,以及你可以采取哪些步骤来解决与内核资源消耗相关的问题。 + PostgreSQL有时会达到操作系统的各种资源上限,尤其是在同一系统上运行多个服务器实例,或在非常大型的安装环境中时更是如此。本节解释PostgreSQL使用的内核资源,以及你可以采取哪些步骤来解决与内核资源消耗相关的问题。 - 共享内存和信号量 @@ -419,11 +405,10 @@ psql: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: No such - System V IPC 功能通常受系统范围的分配限制约束。当PostgreSQL超出这些限制之一时,服务器会拒绝启动,并留下带有指导性的错误消息,说明问题所在以及应如何处理(另见)。相关内核参数在不同系统上的命名基本一致,给出了概览;不过,设置它们的方法却各不相同。下面给出一些平台上的建议。 + System V IPC 功能通常受系统范围的分配限制约束。当PostgreSQL超出这些限制之一时,服务器会拒绝启动,并应留下带有指导性的错误消息,说明问题所在以及应如何处理(另见)。相关内核参数在不同系统上的命名基本一致,给出了概览;不过,设置它们的方法却各不相同。下面给出一些平台上的建议。 - <systemitem class="osname">System V</systemitem> <acronym>IPC</acronym>参数 @@ -431,7 +416,6 @@ psql: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: No such - 名称 描述 @@ -440,11 +424,10 @@ psql: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: No such - SHMMAX 共享内存段的最大尺寸(字节) - 至少 1kB,但是默认值通常要高一些 + 至少 1kB,但是默认值通常高得多 @@ -475,13 +458,13 @@ psql: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: No such SEMMNI 信号量标识符(即,集合)的最大数目 - 至少 ceil(num_os_semaphores / 16),并为其他应用保留空间 + 至少 ceil((max_connections + autovacuum_max_workers + max_wal_senders + max_worker_processes + 6) / 16),并为其他应用保留空间 SEMMNS 系统范围内的最大信号量数目 - ceil(num_os_semaphores / 16) * 17,并为其他应用保留空间 + ceil((max_connections + autovacuum_max_workers + max_wal_senders + max_worker_processes + 6) / 16) * 17,并为其他应用保留空间 @@ -507,8 +490,8 @@ psql: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: No such
- PostgreSQL要求少量字节的 System V 共享内存(在 64 位平台上通常是 48 字节)用于每一个服务器拷贝。在大多数现代操作系统上,这个量很容易得到。 - 但是,如果你运行了很多个服务器副本,或者显式配置服务器以使用大量 System V 共享内存(参见 ), + PostgreSQL要求少量字节的 System V 共享内存(在 64 位平台上通常是 48 字节)用于每一个服务器实例。在大多数现代操作系统上,这个量很容易得到。 + 但是,如果你运行了很多个服务器实例,或者显式配置服务器以使用大量 System V 共享内存(参见 ), 可能需要增加SHMALL(系统范围内 System V 共享内存的总量)。注意在很多系统上SHMALL是以页面而不是字节来度量。 @@ -516,27 +499,36 @@ psql: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: No such 不太可能出问题的是共享内存段的最小尺寸(SHMMIN),对PostgreSQL来说应该最多大约是 32 字节(通常只是1)。而系统范围(SHMMNI)或每个进程(SHMSEG)的最大共享内存段数目不太可能会导致问题,除非你的系统把它们设成零。 - - 当使用 System V 信号量时,PostgreSQL会为每个允许连接()、每个允许自动清理工作进程()、每个允许 WAL 发送进程()、每个允许后台进程()等分配一个信号量,按 16 个一组。 - - - - 每组 16 个信号量还包含第 17 个信号量,用于存放magic number,以检测与其他应用信号量集合的冲突。系统最大信号量数由 SEMMNS 设定,因此至少应为 max_connections 加上 autovacuum_max_workersmax_wal_sendersmax_worker_processes,再加上每 16 个允许连接与工作进程所需的一个额外量(见中的公式)。SEMMNI决定系统中同一时刻可存在的信号量集合数上限,因此至少应为 ceil((max_connections + autovacuum_max_workers + max_wal_senders + max_worker_processes + 6) / 16)。降低允许连接数是对通常带有误导措辞设备上没有剩余空间(来自semget)这类失败的临时缓解手段。 - + 使用 System V 信号量时,PostgreSQL 为每个允许的连接()、自动清理工作进程()、WAL 发送进程()和后台进程()各使用一个信号量,每 16 个组成一组。每组还包含第 17 个信号量,其中存放一个魔数,用来检测与其他应用程序使用的信号量集的冲突。系统中的信号量最大数量由 SEMMNS 设置,因此它必须至少等于 max_connectionsautovacuum_max_workersmax_wal_sendersmax_worker_processes 之和,再为每 16 个允许的连接和工作进程额外增加一个信号量(参见 中的公式)。参数 SEMMNI 限制系统中同时存在的信号量集的数量。因此,此参数必须至少为 ceil((max_connections + autovacuum_max_workers + max_wal_senders + max_worker_processes + 6) / 16)。降低允许的连接数,可以临时规避 semget 函数的失败;此类失败通常会报告令人困惑的 No space left on device 在某些情况下,可能还需要增大SEMMAP,使其至少与SEMMNS处于同一数量级。如果系统提供这个参数(很多系统没有),它定义的是信号量资源映射的大小;映射中每个连续的可用信号量块都需要占用一项。每当一个信号量集合被释放时,它要么会并入与该释放块相邻的现有项,要么会登记为一个新的映射项。如果映射已满,被释放的信号量就会丢失(直到重启)。因此,随着时间推移,信号量空间碎片化可能会导致可用信号量少于应有数量。 - 与semaphore undo有关的其他各种设置,如SEMMNUSEMUME,不会影响PostgreSQL。 + 与信号量撤销有关的其他各种设置,如SEMMNUSEMUME,不会影响PostgreSQL - 当使用 POSIX 信号量时,所需数量与 System V 相同,即每个允许连接()、每个允许自动清理工作进程()、每个允许 WAL 发送进程()、每个允许后台进程()等各需一个。在优先使用该实现的平台上,POSIX 信号量数量没有特定内核上限。 + 当使用 POSIX 信号量时,所需数量与 System V 相同,即每个允许连接()、每个允许自动清理工作进程()、每个允许 WAL 发送进程()、每个允许后台进程()各需一个。在优先使用该实现的平台上,POSIX 信号量数量没有特定内核上限。 + + + AIX + AIXIPC 配置 + + + + 对于 SHMMAX 之类的参数,通常不需要任何特殊配置,因为看起来系统已经配置为允许将所有内存都用作共享内存。这类配置也常用于其他数据库,例如 DB/2。 + + + 不过,可能需要修改 /etc/security/limits 中的全局 ulimit 信息,因为文件大小(fsize)和文件数量(nofiles)的默认硬限制可能过低。 + + + + FreeBSD @@ -569,15 +561,11 @@ psql: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: No such - NetBSD NetBSDIPC 配置 - - - 默认共享内存设置通常就足够了,除非你已将 shared_memory_type 设置为 sysv。不过,你需要增大 kern.ipc.semmnikern.ipc.semmns,因为 NetBSD 对这两项的默认值小得实际上无法使用。 - + 默认共享内存设置通常就足够了,除非你已将 shared_memory_type 设置为 sysv。通常需要增大 kern.ipc.semmnikern.ipc.semmns,因为 NetBSD 对这两项的默认设置小得不便使用。 可以使用 sysctl 调整 IPC 参数,例如: @@ -594,15 +582,11 @@ psql: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: No such - OpenBSD OpenBSDIPC 配置 - - - 默认共享内存设置通常就足够了,除非你已将 shared_memory_type 设置为 sysv。不过,你需要增大 kern.seminfo.semmnikern.seminfo.semmns,因为 OpenBSD 对这两项的默认值小得实际上无法使用。 - + 默认共享内存设置通常已经足够,除非你将 shared_memory_type 设为 sysv。通常需要增大 kern.seminfo.semmnikern.seminfo.semmns,因为 OpenBSD 对这两项的默认设置小得令人担忧。 可以使用 sysctl 调整 IPC 参数,例如: @@ -627,7 +611,7 @@ psql: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: No such - 共享内存大小设置可以通过sysctl界面更改。例如,允许 16 GB: + 共享内存大小设置可以通过sysctl接口更改。例如,允许 16 GB: $ sysctl -w kernel.shmmax=17179869184 $ sysctl -w kernel.shmall=4194304 @@ -638,17 +622,15 @@ psql: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: No such - + macOS macOSIPC 配置 - 默认共享内存和信号量设置通常就足够了,除非你已将 shared_memory_type 设置为 sysv - 在 macOS 中配置共享内存的推荐方法是创建一个名为/etc/sysctl.conf的文件,其中包含这样的变量赋值: @@ -665,9 +647,7 @@ kern.sysv.shmall=1024 SHMMAX 只能设置为 4096 的倍数。 - - 在这个平台上,SHMALL以 4kB 的页面度量。 - + 在这个平台上,SHMALL 以 4 kB 的页为单位。 SHMMNI 之外,其他设置都可以使用 sysctl 动态更改。不过,最好还是通过/etc/sysctl.conf设置你希望使用的值,这样重启后仍能保留。 @@ -680,9 +660,8 @@ kern.sysv.shmall=1024 Solaris illumos - - 默认的共享内存和信号量设置对于大多数 PostgreSQL 应用通常已经足够。Solaris 现在将SHMMAX的默认值设为系统 RAM 的四分之一。要进一步调整这一设置,可使用与postgres用户关联的项目设置。例如,以root运行下列命令: + 默认的共享内存和信号量设置对于大多数 PostgreSQL 应用通常已经足够。Solaris 将SHMMAX的默认值设为系统 RAM 的四分之一。要进一步调整这一设置,可使用与postgres用户关联的项目设置。例如,以root运行下列命令: projadd -c "PostgreSQL DB User" -K "project.max-shm-memory=(privileged,8GB,deny)" -U postgres -G postgres user.postgres @@ -712,7 +691,6 @@ project.max-msg-ids=(priv,4096,deny)
- systemd RemoveIPC @@ -720,15 +698,15 @@ project.max-msg-ids=(priv,4096,deny) RemoveIPC - + 如果使用systemd,必须注意不要让操作系统过早移除 IPC 资源(包括共享内存)。这在从源码安装 PostgreSQL 时尤其值得关注。使用发行版软件包的用户较不容易受到影响,因为此时postgres用户通常会被创建为系统用户。 - + logind.conf 中的 RemoveIPC 设置控制当用户完全注销时是否移除 IPC 对象。系统用户不受此限制。原版 systemd 默认开启该设置,但某些操作系统发行版默认将其关闭。 - + 当此设置开启时,一个常见现象是,用于并行查询执行的共享内存对象会在看似随机的时间被删除,导致在尝试打开或删除它们时出现错误和警告,例如 WARNING: could not remove shared memory segment "/PostgreSQL.1450751626": No such file or directory @@ -736,19 +714,19 @@ WARNING: could not remove shared memory segment "/PostgreSQL.1450751626": No su 不同类型的 IPC 对象(共享内存与信号量、System V 与 POSIX)在 systemd 中的处理略有不同,因此你可能会发现某些 IPC 资源不会像其他资源那样被删除。但依赖这些细微差别并不可取。 - - 用户注销可能会作为维护作业的一部分发生,也可能在管理员以postgres用户或类似名称登录时手工触发,因此通常很难彻底防止。 + + 用户注销可能会作为维护作业的一部分发生,也可能在管理员以postgres用户登录或执行类似操作时手工触发,因此通常很难彻底防止。 - + 什么算作系统用户,是在编译 systemd 时依据 /etc/login.defs 中的 SYS_UID_MAX 设置确定的。 - + 打包和部署脚本应当谨慎地使用useradd -radduser --system或其等价方式,把postgres用户创建为系统用户。 - + 或者,如果该用户账户创建得不正确,或无法更改,建议在/etc/systemd/logind.conf或其他适当的配置文件中设置 RemoveIPC=no @@ -756,7 +734,6 @@ RemoveIPC=no - 上述两件事至少要确保做到其中之一,否则 PostgreSQL 服务器会变得非常不可靠。 @@ -814,11 +791,10 @@ default:\ - Linux 内存过量分配 - memory overcommit + 内存过量分配 @@ -826,14 +802,14 @@ default:\ - overcommit + 过量分配 - + Linux 上默认的虚拟内存行为对PostgreSQL并非最佳。由于内核实现内存过量分配的方式,如果 PostgreSQL 或其他进程的内存需求导致系统耗尽虚拟内存,内核可能会终止 PostgreSQL 的 postmaster(主管服务器进程)。 - + 如果发生这种情况,你会看到类似下面的内核消息(至于应到哪里查看此类消息,请参阅你的系统文档和配置): Out of Memory: Killed process 12345 (postgres). @@ -841,15 +817,15 @@ Out of Memory: Killed process 12345 (postgres). 这表示 postgres 进程因内存压力而被终止。尽管现有数据库连接仍会继续正常运行,但新连接将不再被接受。要恢复服务,必须重启PostgreSQL - + 避免该问题的一种办法,是让PostgreSQL运行在一台你能确定不会被其他进程耗尽内存的机器上。如果内存紧张,增加操作系统交换空间也有助于避免这个问题,因为内存不足(OOM)杀手只有在物理内存和交换空间都耗尽时才会被触发。 - - 如果导致系统耗尽内存的正是PostgreSQL自身,那么你可以通过调整配置来避免该问题。在某些情况下,调低与内存相关的配置参数会有帮助,尤其是shared_bufferswork_memhash_mem_multiplier。在其他情况下,允许数据库服务器接受过多连接也可能导致这一问题。很多时候,更好的做法是减小max_connections,并转而使用外部连接池软件。 + + 如果导致系统耗尽内存的正是PostgreSQL自身,那么你可以通过调整配置来避免该问题。在某些情况下,调低与内存相关的配置参数会有帮助,尤其是shared_bufferswork_memhash_mem_multiplier。在其他情况下,允许数据库服务器接受过多连接也可能导致这一问题。很多时候,更好的做法可能是减小max_connections,并转而使用外部连接池软件。 - + 还可以修改内核行为,使其不再过量分配内存。尽管这种设置无法彻底阻止OOM 杀手被触发,但能显著降低其发生概率,从而得到更稳健的系统行为。这可以通过使用sysctl选择严格的过量分配模式来实现: sysctl -w vm.overcommit_memory=2 @@ -857,26 +833,33 @@ sysctl -w vm.overcommit_memory=2 或者在/etc/sysctl.conf中加入等效设置。你可能还希望修改相关设置vm.overcommit_ratio。详细信息请参阅内核文档中的文件。 - - 另一种方法可在修改或不修改 vm.overcommit_memory 的情况下使用:把 PostgreSQL 主进程的 OOM score adjustment 值设为 -1000,从而保证它不会成为 OOM 杀手的目标。最简单的做法是在 PostgreSQL 启动脚本中、调用 postgres 之前执行以下命令: + + 另一种方法可在修改或不修改 vm.overcommit_memory 的情况下使用: + 把 postmaster 进程专属的OOM 评分调整值设为 -1000, + 从而保证它不会成为 OOM 杀手的目标。最简单的做法是在 PostgreSQL + 启动脚本中、调用 postgres 之前执行: echo -1000 > /proc/self/oom_score_adj - 请注意,这个操作必须以 root 身份完成,否则不会生效。因此,最容易放置该操作的位置是由 root 拥有的启动脚本。如果这样做,你还应该在调用 postgres 之前,在启动脚本中设置这些环境变量: + 请注意,这个操作必须以 root 身份完成,否则不会生效;因此,由 root 拥有的启动脚本是最容易执行该操作的位置。 + 如果这样做,还应在调用 postgres 之前,在启动脚本中设置以下环境变量: export PG_OOM_ADJUST_FILE=/proc/self/oom_score_adj export PG_OOM_ADJUST_VALUE=0 - 这些设置会使 postgres 子进程以默认值零的 OOM score adjustment 运行,因此 OOM 杀手在需要时仍可将它们作为目标。如果你希望子进程使用其他 OOM score adjustment 值,也可以为 PG_OOM_ADJUST_VALUE 指定其他数值(也可省略,此时默认为零)。如果不设置 PG_OOM_ADJUST_FILE,子进程就会和主进程使用相同的 OOM score adjustment,这并不明智,因为这样做的目的正是为了确保主进程拥有优先保护设置。 - + 这些设置会使 postmaster 子进程以常规的 OOM 评分调整值零运行,以便 OOM 杀手在需要时仍可将它们作为目标。 + 如果希望子进程以其他 OOM 评分调整值运行,也可以为 PG_OOM_ADJUST_VALUE 指定其他值。 + (也可以省略 PG_OOM_ADJUST_VALUE,此时默认为零。) + 如果不设置 PG_OOM_ADJUST_FILE,子进程就会和 postmaster 使用相同的 OOM 评分调整值, + 这并不明智,因为这样做的目的正是确保 postmaster 获得优先保护。 + - Linux 大页 - + 使用大页可以减少PostgreSQL这类会使用大块连续内存的软件所带来的开销,尤其是在取值较大时。要在PostgreSQL中使用这一特性,你需要一个启用了CONFIG_HUGETLBFS=yCONFIG_HUGETLB_PAGE=y的内核。你还需要把操作系统配置为提供足够多、且大小合适的大页。运行时计算参数会报告所需的大页数量。可以在启动服务器前用如下postgres命令查看: $ postgres -D $PGDATA -C shared_memory_size_in_huge_pages @@ -900,30 +883,31 @@ hugepages-1048576kB hugepages-2048kB 也可以在启动时通过内核参数(例如hugepagesz=2M hugepages=3170)提供这些设置。 - + 有时由于内存碎片,内核无法立即分配所需数量的大页,因此可能需要重复执行该命令,或者重启系统。(重启后,机器上的大部分内存应当都可立即转换为大页。)要检查某一给定大小的大页分配情况,请使用: $ cat /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages - - 你可能还需要授予数据库服务器的操作系统用户使用大页的权限,例如通过sysctl设置vm.hugetlb_shm_group,以及/或者授予其使用ulimit -l锁定内存的权限。 - + + 可能还需要通过 sysctl 设置 vm.hugetlb_shm_group, + 授予数据库服务器的操作系统用户使用大页的权限,以及/或者通过 ulimit -l 授予其锁定内存的权限。 + - + PostgreSQL对大页的默认行为是:只要可能就使用它们,采用系统默认的大页大小;如果失败,则回退到普通页面。要强制使用大页,可以在postgresql.conf中将设为on。请注意,在这种设置下,如果没有足够的大页可用,PostgreSQL将无法启动。 - + 关于Linux大页特性的详细说明,请参见 - + 关闭服务器 @@ -931,7 +915,7 @@ $ cat /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages - 有几种关闭数据库服务器的方法。在后台,它们都简化为向主管 postgres 进程发送信号。 + 有几种关闭数据库服务器的方法。这些方法在内部都是向主管 postgres 进程发送信号。 @@ -973,7 +957,7 @@ $ cat /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepagesSIGQUIT并等待它们终止。 如果有任何进程在 5 秒内未终止,它们将被发送SIGKILL。 一旦所有子进程退出,主管服务器进程将立即退出,而不进行正常的数据库关闭处理。 - 这会导致下次启动时通过回放 WAL 日志执行恢复。仅建议在紧急情况下使用。 + 这会导致下次启动时通过重放 WAL 日志执行恢复。仅建议在紧急情况下使用。 @@ -988,11 +972,7 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` - - - 最好不要使用SIGKILL关闭服务器。这样做将会阻止服务器释放共享内存和信号量。 - 此外,使用SIGKILL杀掉postgres进程时,postgres不会有机会将信号传播到它的子进程,所以可能也必须手工杀掉单个的子进程。 - + 最好不要使用 SIGKILL 关闭服务器。这样做会阻止服务器释放共享内存和信号量。此外,SIGKILL 会终止 postgres 进程,使其没有机会将信号转发给子进程,因此可能还需要手动逐个终止子进程。 @@ -1001,16 +981,15 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` - 升级 <productname>PostgreSQL</productname> 集簇 - upgrading + 升级 - version - compatibility + 版本 + 兼容性 @@ -1030,7 +1009,7 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` - 新的主版本通常还会引入一些用户可见的不兼容变化,因此应用程序可能也需要做出修改。所有用户可见的变化都列在发行说明()中;请特别留意标为Migration的小节。虽然你可以从一个主版本直接升级到另一个主版本,而不必逐个升级中间版本,但仍应阅读所有中间版本的主版本发行说明。 + 新的主版本通常还会引入一些用户可见的不兼容变化,因此应用程序可能也需要做出修改。所有用户可见的变化都列在发行说明()中;请特别留意标为迁移(Migration)的小节。虽然你可以从一个主版本直接升级到另一个主版本,而不必逐个升级中间版本,但仍应阅读所有中间版本的主版本发行说明。 @@ -1084,12 +1063,10 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` - 服务器端 C 语言 API - - 这涉及以后端函数 API 为代表的变更,该 API 使用 C 语言编写。这类变更会影响那些深入引用服务器内部后端函数的代码。 + 这涉及使用 C 语言编写的后端函数 API 的变更。这类变更会影响那些深入引用服务器内部后端函数的代码。 @@ -1097,32 +1074,30 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` - 通过<application>pg_dumpall</application>升级数据 - 一种升级方法是从某个主版本的PostgreSQL导出数据,再在另一个版本中恢复。要这样做,必须使用逻辑备份工具,例如pg_dumpall;文件系统级备份方法不起作用。(系统中有相应检查,会阻止你在不兼容版本的PostgreSQL上使用某个数据目录,因此即便误用错误版本的服务器去启动某个数据目录,通常也不会造成太大损害。) + 一种升级方法是从某个主版本的PostgreSQL转储数据,再在另一个版本中恢复。要这样做,必须使用逻辑备份工具,例如pg_dumpall;文件系统级备份方法不起作用。(系统中有相应检查,会阻止你在不兼容版本的PostgreSQL上使用某个数据目录,因此即便误用错误版本的服务器去启动某个数据目录,通常也不会造成太大损害。) - + 建议使用来自较新版本PostgreSQLpg_dumppg_dumpall程序,以利用这些程序可能包含的改进。当前版本的转储程序可以读取从 9.2 起任意服务器版本的数据。 - + 以下说明假定你现有的安装位于/usr/local/pgsql目录下,数据区域位于/usr/local/pgsql/data。请根据实际情况替换成你的路径。 - - 如果是在制作备份,请确认数据库此时没有正在进行更新。这不会影响备份的一致性,但那些变更当然不会包含在备份中。必要时,可修改/usr/local/pgsql/data/pg_hba.conf中的访问权限(或采用等效方法),禁止除你之外的其他人访问数据库。有关访问控制的更多信息见。 + 如果是在制作备份,请确认数据库此时没有正在进行更新。更新操作不会影响备份的完整性,但那些变更当然不会包含在备份中。必要时,可修改/usr/local/pgsql/data/pg_hba.conf(或等效文件)中的访问权限,禁止除你之外的其他人访问数据库。有关访问控制的更多信息见 pg_dumpall - use during upgrade + 在升级期间使用 要备份整个数据库安装,请输入: @@ -1137,13 +1112,12 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` - 关闭旧服务器: pg_ctl stop - 在那些会自动启动PostgreSQL的系统上,可能已经有某个启动脚本能完成同样的工作。例如,在Red Hat Linux系统上,也许下面这条命令就可以: + 在那些会在开机时自动启动PostgreSQL的系统上,可能已经有某个启动脚本能完成同样的工作。例如,在Red Hat Linux系统上,也许下面这条命令就可以: /etc/rc.d/init.d/postgresql stop @@ -1152,7 +1126,6 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` - 如果是从备份恢复,请重命名或删除旧的安装目录,前提是它不是按版本区分的目录。与其删除,不如重命名,这样如果你遇到问题需要回退,它仍然还在。请记住,该目录可能会占用相当可观的磁盘空间。要重命名该目录,可以使用类似下面的命令: @@ -1163,14 +1136,12 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` - 按照 安装新版本的 PostgreSQL - 如有需要,创建一个新的数据库集簇。请记住,执行这些命令时必须登录到专用数据库用户账户(如果你正在升级,就已经拥有这个账户)。 @@ -1180,14 +1151,12 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` - 恢复先前的pg_hba.conf,以及你对postgresql.conf所做的任何修改。 - 启动数据库服务器,同样要使用该专门的数据库用户账户: @@ -1197,13 +1166,9 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` - - - 最后,使用新的psql从备份恢复数据: - + 最后,使用以下命令从备份恢复数据: /usr/local/pgsql/bin/psql -d postgres -f outputfile - - 这里务必使用新的psql。 +这里应使用新版 psql @@ -1230,11 +1195,10 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 - 通过复制升级数据 - 也可以使用逻辑复制方法,创建一个运行较新版本PostgreSQL的备库。之所以可行,是因为逻辑复制支持不同主版本PostgreSQL之间进行复制。该备库可以与旧服务器部署在同一台机器上,也可以部署在不同机器上。一旦它与主库(运行旧版本PostgreSQL)同步,就可以切换主备角色,让备库提升为主库,并关闭旧的数据库实例。这种切换通常只会带来几秒钟的停机时间。 + 也可以使用逻辑复制方法,创建一个运行较新版本PostgreSQL的备库。之所以可行,是因为逻辑复制支持不同主版本PostgreSQL之间进行复制。该备库可以与旧服务器部署在同一台机器上,也可以部署在不同机器上。一旦它与主库(运行旧版本PostgreSQL)同步,就可以切换主备角色,让备库提升为主库,并关闭旧的数据库实例。这种切换使升级只需几秒钟的停机时间。 @@ -1244,7 +1208,6 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 - 防止服务器欺骗 @@ -1268,21 +1231,17 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 - 要防止 SSL 欺骗,服务器必须配置为仅接受 hostssl 连接(),并且具备 SSL 密钥和证书文件()。TCP 客户端必须使用 sslmode=verify-caverify-full 连接,并安装适当的根证书文件()。另外,也可使用 SSL 实现定义的系统 CA 池(system CA pool),即设置 sslrootcert=system;出于安全考虑,此时会强制使用 sslmode=verify-full,因为获得由公共 CA 签发的证书通常并不困难。 + 要通过 SSL 防止服务器欺骗,服务器必须配置为仅接受 hostssl 连接(),并且具备 SSL 密钥和证书文件()。TCP 客户端必须使用 sslmode=verify-caverify-full 连接,并安装适当的根证书文件()。另外,也可使用 SSL 实现定义的系统 CA 池,即设置 sslrootcert=system;出于安全考虑,此时会强制使用 sslmode=verify-full,因为获得由公共 CA 签发的证书通常并不困难。 在网络上使用 scram-sha-256 密码认证时,为防止服务器欺骗,应确保通过 SSL 连接服务器,并使用上一段描述的任一防欺骗方法。此外,libpq 中的 SCRAM 实现无法保护整个认证交换过程,但使用连接参数 channel_binding=require 可对服务器欺骗提供一定缓解。攻击者若用伪造服务器拦截 SCRAM 交换,可能通过离线分析推导出客户端哈希密码。 - - 要防止 GSSAPI 欺骗,必须将服务器配置为仅接受hostgssenc连接 () 并对它们使用gss认证。 - TCP 客户端则必须使用 gssencmode=require 发起连接。 - + 要通过 GSSAPI 防止服务器欺骗,服务器必须配置为仅接受 hostgssenc 连接(),并对这些连接使用 gss 认证。TCP 客户端必须使用 gssencmode=require 连接。 - 加密选项 @@ -1290,7 +1249,7 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 - PostgreSQL提供了多个层次的加密,并在防止数据因数据库服务器被盗、不可靠的管理员或不安全网络等原因而泄露方面提供了很高的灵活性。对于医疗记录、金融交易等敏感数据,加密也可能是合规要求的一部分。 + PostgreSQL提供了多个层次的加密,并在防止数据因数据库服务器被盗、不诚实的管理员或不安全网络等原因而泄露方面提供了很高的灵活性。为了保护医疗记录、金融交易等敏感数据,也可能需要使用加密。 @@ -1304,11 +1263,7 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 数据库用户密码以哈希形式存储(由 控制),因此管理员无法得知分配给用户的实际密码。如果客户端认证使用 SCRAM 或 MD5,明文密码甚至不会暂时出现在服务器端,因为客户端会在通过网络发送前完成加密。推荐使用 SCRAM,因为它是互联网标准,并且比 PostgreSQL 特有的 MD5 认证协议更安全。 - - - 对 MD5 加密密码的支持已弃用,并将在未来版本的 PostgreSQL 中移除。迁移到其他密码类型的细节见 。 - - + @@ -1394,7 +1349,6 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 - 使用 SSL 的安全 TCP/IP 连接 @@ -1410,7 +1364,6 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 术语SSLTLS经常被交替使用,用来表示基于TLS协议的安全加密连接。SSL协议是TLS协议的前身,尽管SSL协议本身已不再受支持,SSL一词仍常被用来泛指这类加密连接。在PostgreSQL中,SSLTLS也是这样互换使用的。 - 基本设置 @@ -1430,7 +1383,7 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 - 如果私钥受密码保护,服务器会提示输入该密码,并在输入之前不会启动。默认情况下,使用密码会禁用无需重启服务器即可更改 SSL 配置的能力,不过参见。此外,在 Windows 上完全无法使用带密码保护的私钥。 + 如果私钥受口令保护,服务器会提示输入该口令,并在输入之前不会启动。默认情况下,使用口令会禁用无需重启服务器即可更改 SSL 配置的能力,不过参见。此外,在 Windows 上完全无法使用带口令保护的私钥。 @@ -1443,7 +1396,6 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 - OpenSSL 配置 @@ -1455,9 +1407,8 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 - - 使用NULL-SHANULL-MD5密码套件,可以在几乎没有加密开销的情况下完成认证。不过,中间人仍然能够读取并转发客户端与服务器之间的通信。此外,与认证的开销相比,加密开销本身通常很小。基于这些原因,不建议使用 NULL 密码套件。 + 使用NULL-SHANULL-MD5密码套件,可以在没有加密开销的情况下完成认证。不过,中间人仍然能够读取并转发客户端与服务器之间的通信。此外,与认证的开销相比,加密开销本身很小。基于这些原因,不建议使用 NULL 密码套件。 @@ -1667,7 +1618,6 @@ openssl x509 -req -in server.csr -text -days 365 \ - 通过 <application>SSH</application> 隧道建立安全 TCP/IP 连接 @@ -1690,9 +1640,7 @@ psql -h localhost -p 63333 postgres 对数据库服务器来说,它看到的是来自主机foo.com上用户joelocalhost绑定地址的连接,并将应用为该用户到该绑定地址所配置的认证方式。请注意,服务器不会认为这是 SSL 加密连接,因为实际上SSH服务器与PostgreSQL服务器之间并没有加密。不过这通常不会带来额外安全风险,因为两者位于同一台机器上。 - - 要让这条隧道建立成功,你必须能够像建立终端会话那样,通过sshjoe@foo.com身份连接。 - + 要让这条隧道建立成功,你必须有权通过 sshjoe@foo.com 身份连接,就像尝试使用 ssh 创建终端会话一样。 你也可以把端口转发设成这样: @@ -1711,7 +1659,6 @@ ssh -L 63333:db.foo.com:5432 joe@shell.foo.com - 还有一些其他应用也能提供安全隧道,其思路与刚才描述的 SSH 方法类似。 diff --git a/zh/16/sepgsql.sgml b/zh/16/sepgsql.sgml index 4a040c99..6106c44d 100644 --- a/zh/16/sepgsql.sgml +++ b/zh/16/sepgsql.sgml @@ -76,15 +76,7 @@ Policy from config file: targeted 它,之后才能安装本模块。 - - 要构建此模块,使用 make 和 autoconf 时请指定 ,使用 meson 时请指定 。 - - 还要确保构建时已经安装 libselinux-devel RPM。 - + 要构建此模块,请将选项 --with-selinux 加入 PostgreSQL 的 configure 命令中。还要确保构建时已经安装 libselinux-devel RPM。 要使用此模块,必须将 sepgsql 包含在 diff --git a/zh/16/sourcerepo.sgml b/zh/16/sourcerepo.sgml index d76d7fcc..997ce588 100644 --- a/zh/16/sourcerepo.sgml +++ b/zh/16/sourcerepo.sgml @@ -12,6 +12,13 @@ url="https://wiki.postgresql.org/wiki/Working_with_Git">)上有一些关于使用 Git 的讨论。 + + 请注意,从源代码仓库构建PostgreSQL需要版本相当新的 + bisonflexPerl。 + 从发行版 tarball 构建则不需要这些工具,因为这些工具生成的文件已经包含在 tarball 中。 + 其他工具要求与中的说明相同。 + + 通过 <productname>Git</productname> 获取源代码 diff --git a/zh/16/spgist.sgml b/zh/16/spgist.sgml index ab0e8a51..fdfde866 100644 --- a/zh/16/spgist.sgml +++ b/zh/16/spgist.sgml @@ -4,15 +4,15 @@ SP-GiST 索引 - index + 索引 SP-GiST - + 简介 - SP-GiST 是 space-partitioned GiST + SP-GiST 是空间分区 GiST 的缩写。SP-GiST 支持分区搜索树,这使得开发多种不同的 非平衡数据结构成为可能,例如四叉树、k-d 树以及基数树(trie)。这些结构 的共同特征是,它们会反复将搜索空间划分为不必等大的分区。与这种划分规则良 @@ -43,13 +43,13 @@ 上还有更多信息。 - + - + 内置操作符类 - 核心 PostgreSQL 发行版包含了 + PostgreSQL 核心发行版包含了 SP-GiST 操作符类,如 所示。 @@ -183,9 +183,9 @@ (k-NN)搜索。 - + - + 可扩展性 @@ -232,11 +232,11 @@ - SP-GiST 核心代码会处理空项。虽然 - SP-GiST 索引确实会为被索引列中的空值存储项,但这一 - 点对索引操作符类代码是隐藏的:不会有空的索引项或搜索条件传递给操作符类 - 方法。(这里假定 SP-GiST 操作符是严格的,因此对空 - 值不可能成功。)因此,这里不再进一步讨论空值。 + SP-GiST 核心代码负责处理值为 null 的索引项。虽然 + SP-GiST 索引会为被索引列中的 null 值存储索引项, + 但索引操作符类代码看不到这些项:值为 null 的索引项或搜索条件绝不会传给 + 操作符类方法。(这里假定 SP-GiST 操作符是严格的, + 因此对 null 值不可能返回真。)所以这里不再讨论 null 值。 @@ -286,8 +286,8 @@ typedef struct spgConfigOut Oid prefixType; /* 内部元组前缀的数据类型 */ Oid labelType; /* 内部元组结点标签的数据类型 */ Oid leafType; /* 叶子元组值的数据类型 */ - bool canReturnData; /* 操作符类能重构原始数据 */ - bool longValuesOK; /* 操作符类能处理值 > 1 页 */ + bool canReturnData; /* 操作符类能重建原始数据 */ + bool longValuesOK; /* 操作符类能处理大小 > 1 页的值 */ } spgConfigOut; @@ -314,7 +314,7 @@ typedef struct spgConfigOut 类型与操作符类的输入类型相同,这也是最常见的情况。)出于向后兼容的原 因,config 方法也可以将 leafType 设为其他值,并且该值将被使用; - 但这已被废弃,因为这样会导致目录中对索引内容的标识不正确。此外,也允 + 但这已被弃用,因为这样会导致目录中对索引内容的标识不正确。此外,也允 许不初始化 leafType(即保持为零);这会 被解释为使用从 opckeytype 派生的索引存 储类型。 @@ -354,7 +354,7 @@ typedef struct spgChooseIn int level; /* 当前层级(从零开始计) */ /* 来自当前内部元组的数据 */ - bool allTheSame; /* 元组被标记为 all-the-same? */ + bool allTheSame; /* 元组被标记为全部相同? */ bool hasPrefix; /* 元组有前缀? */ Datum prefixDatum; /* 如果有,前缀值 */ int nNodes; /* 内部元组中的结点数 */ @@ -594,14 +594,14 @@ typedef struct spgInnerConsistentIn int nkeys; /* scankeys 数组的长度 */ int norderbys; /* orderbys 数组的长度 */ - Datum reconstructedValue; /* 在父元组处重构的值 */ + Datum reconstructedValue; /* 在父元组处重建的值 */ void *traversalValue; /* 操作符类特定的遍历值 */ MemoryContext traversalMemoryContext; /* 将新的遍历值放在这里 */ int level; /* 当前层级(从零开始计) */ bool returnData; /* 必须返回原始数据? */ /* 来自当前内部元组的数据 */ - bool allTheSame; /* 元组被标记为 all-the-same? */ + bool allTheSame; /* 元组被标记为全部相同? */ bool hasPrefix; /* 元组有前缀? */ Datum prefixDatum; /* 如果有,前缀值 */ int nNodes; /* 内部元组中的结点数 */ @@ -613,7 +613,7 @@ typedef struct spgInnerConsistentOut int nNodes; /* 需要访问的子结点数 */ int *nodeNumbers; /* 它们在结点数组中的索引 */ int *levelAdds; /* 对每个结点层级增加这么多 */ - Datum *reconstructedValues; /* 关联的重构值 */ + Datum *reconstructedValues; /* 关联的重建值 */ void **traversalValues; /* 操作符类特定的遍历值 */ double **distances; /* 关联距离 */ } spgInnerConsistentOut; @@ -624,7 +624,7 @@ typedef struct spgInnerConsistentOut 用 AND 组合 — 只有满足全部条件的索引项才是我们关心的。(注 意, nkeys = 0 表示所有索引项都满足该查 - 询。)通常 consistent 函数只关心每个数组元素的 + 询。)通常一致性检查函数只关心每个数组元素的 sk_strategysk_argument 字段,它们分别给出可索引操 作符和比较值。特别地,无需检查 sk_flags @@ -641,9 +641,8 @@ typedef struct spgInnerConsistentOut 遍历值(见下文)的内存上下文。level 是 当前内部元组的层级,根层为零。如果本查询需要重建数据,则 returnDatatrue; - 只有在 config 函数声明了 - canReturnData 时才会如此。若当前内部元组 - 被标记为 all-the-same,则 + 只有在 config 函数将 canReturnData 设为真时才会如此。若当前内部元组 + 被标记为 全部相同,则 allTheSame 为真;在这种情况下,所有结点 都具有相同的标签(如果有),因此要么全部匹配该查询,要么全部不匹配 (参见 )。若当前内部元组包 @@ -663,8 +662,7 @@ typedef struct spgInnerConsistentOut 非必然如此,所以这里使用数组。)如果需要值重建,则将 reconstructedValues 设为一个数组,其中包 含为每个待访问子结点重建的值;否则,将 - reconstructedValues 保持为 NULL。重构 - 值假定具有 spgConfigOut.leafType + reconstructedValues 保持为 NULL。重建的值假定具有 spgConfigOut.leafType 类型。(不过,由于核心系统除了可能复制它们以外不会对其做任何处理,只 要它们具有与 leafType 相同的 typlentypbyval 属性就足 @@ -713,7 +711,7 @@ typedef struct spgLeafConsistentIn int nkeys; /* scankeys 数组的长度 */ int norderbys; /* orderbys 数组的长度 */ - Datum reconstructedValue; /* 在父元组处重构的值 */ + Datum reconstructedValue; /* 在父元组处重建的值 */ void *traversalValue; /* 操作符类特定的遍历值 */ int level; /* 当前层级(从零开始计) */ bool returnData; /* 必须返回原始数据? */ @@ -723,7 +721,7 @@ typedef struct spgLeafConsistentIn typedef struct spgLeafConsistentOut { - Datum leafValue; /* 重构出的原始数据(如果有) */ + Datum leafValue; /* 重建出的原始数据(如果有) */ bool recheck; /* 如果必须重新检查操作符则设为真 */ bool recheckDistances; /* 如果必须重新检查距离则设为真 */ double *distances; /* 关联距离 */ @@ -734,7 +732,7 @@ typedef struct spgLeafConsistentOut scankeys 数组描述索引搜索条件。这些条件 用 AND 组合在一起 — 只有满足全部条件的索引项才满足该查询。(注 意 nkeys = 0 表示所有索引项都满足该查 - 询。)通常 consistent 函数只关心每个数组元素的 + 询。)通常一致性检查函数只关心每个数组元素的 sk_strategysk_argument 字段,它们分别给出可索引操 作符和比较值。特别地,无需检查 sk_flags @@ -750,8 +748,7 @@ typedef struct spgLeafConsistentOut NULL。level 是当前叶子元组的层级,根层为 零。如果本查询需要重建数据,则 returnDatatrue; - 只有在 config 函数声明了 - canReturnData 时才会如此。 + 只有在 config 函数将 canReturnData 设为真时才会如此。 leafDatum 是当前叶子元组中存储的、类型为 spgConfigOut.leafType 的键值。 @@ -844,13 +841,13 @@ LANGUAGE C STRICT; - 如果被索引列属于可应用排序规则的数据类型,则索引排序规则会通过标准的 + 如果被索引列属于支持排序规则的数据类型,则索引排序规则会通过标准的 PG_GET_COLLATION() 机制传递给所有支持方法。 - + - + 实现 @@ -858,7 +855,7 @@ LANGUAGE C STRICT; 现者有用的技巧。 - + SP-GiST 限制 @@ -895,9 +892,9 @@ LANGUAGE C STRICT; 用 choose 方法之后叶子 datum 仍没有变小, SP-GiST 核心就会报错。 - + - + 无结点标签的 SP-GiST @@ -919,10 +916,10 @@ LANGUAGE C STRICT; spgAddNode 是错误的,因为在这种情况下结点集合应被 视为固定不变。 - + - - <quote>All-the-Same</quote> 内部元组 + + <quote>全部相同</quote>的内部元组 picksplit 无法把提供的叶子值划分为至少两个结点 @@ -954,11 +951,11 @@ LANGUAGE C STRICT; 况代码,取决于 inner_consistent 函数平常对这些结 点含义做了多大程度的假定。 - - - + + + 示例 @@ -969,6 +966,6 @@ LANGUAGE C STRICT; src/backend/utils/adt/ - + diff --git a/zh/16/spi.sgml b/zh/16/spi.sgml index b4b8b0e2..4bf4e18a 100644 --- a/zh/16/spi.sgml +++ b/zh/16/spi.sgml @@ -76,7 +76,7 @@ int SPI_connect_ext(int options) SPI_connect 会为某次 C 函数调用打开到 SPI 管理器 的连接。如果要通过 SPI 执行命令,就必须调用此函数。不过,有些 SPI - 实用函数可以在未连接的 C 函数中调用。 + 辅助函数可以在未连接的 C 函数中调用。 @@ -114,15 +114,16 @@ int SPI_connect_ext(int options) - - - 这些函数返回 int 而不是 void 属于历史遗留设 - 计。所有失败情况都通过 ereport 或 - elog 报告。(在 - PostgreSQL v10 之前,部分但并非全部失败会以 - SPI_ERROR_CONNECT 作为结果值报告。) - + + SPI_ERROR_CONNECT + + + 发生错误时 + + + +
@@ -276,8 +277,7 @@ SPI_execute("INSERT INTO foo SELECT * FROM bar RETURNING *", false, 5); SPI_OK_SELECTSPI_OK_INSERT_RETURNINGSPI_OK_DELETE_RETURNING、 - SPI_OK_UPDATE_RETURNING 或 - SPI_OK_MERGE_RETURNING,则可以通过全局指针 + SPI_OK_UPDATE_RETURNING,则可以通过全局指针 SPITupleTable *SPI_tuptable 访问结果行。有些工具命令 (如 EXPLAIN)也会返回结果行集,此时 SPI_tuptable 同样会保存结果。另一些工具命令 @@ -291,16 +291,16 @@ SPI_execute("INSERT INTO foo SELECT * FROM bar RETURNING *", false, 5); typedef struct SPITupleTable { - /* Public members */ - TupleDesc tupdesc; /* tuple descriptor */ - HeapTuple *vals; /* array of tuples */ - uint64 numvals; /* number of valid tuples */ - - /* Private members, not intended for external callers */ - uint64 alloced; /* allocated length of vals array */ - MemoryContext tuptabcxt; /* memory context of result table */ - slist_node next; /* link for internal bookkeeping */ - SubTransactionId subid; /* subxact in which tuptable was created */ + /* 公共成员 */ + TupleDesc tupdesc; /* 元组描述符 */ + HeapTuple *vals; /* 元组数组 */ + uint64 numvals; /* 有效元组数 */ + + /* 私有成员,不供外部调用者使用 */ + uint64 alloced; /* vals 数组的已分配长度 */ + MemoryContext tuptabcxt; /* 结果表的内存上下文 */ + slist_node next; /* 用于内部管理的链接 */ + SubTransactionId subid; /* 创建 tuptable 的子事务 */ } SPITupleTable; SPI 调用者可以使用 tupdesc、 @@ -439,15 +439,6 @@ typedef struct SPITupleTable - - SPI_OK_MERGE_RETURNING - - - 执行了 MERGE RETURNING - - - - SPI_OK_UTILITY @@ -471,7 +462,7 @@ typedef struct SPITupleTable - 发生错误时,则返回下列负值之一: + 出错时,返回以下负值之一: @@ -521,7 +512,7 @@ typedef struct SPITupleTable SPI_ERROR_UNCONNECTED - 从未连接的 C 函数中调用 + 如果从一个未连接的 C 函数中调用 @@ -534,9 +525,9 @@ typedef struct SPITupleTable 所有 SPI 查询执行函数都会设置 SPI_processed 和 - SPI_tuptable(只设置指针,而不会复制结构体内容)。如果 + SPI_tuptable(只设置指针,而不更改结构体内容)。如果 需要在后续调用之后继续访问 SPI_execute 或其他查询 - 执行函数的结果表,请把这两个全局变量保存到本地 C 函数变量中。 + 执行函数的结果表,请把这两个全局变量保存到 C 函数的局部变量中。 @@ -581,7 +572,7 @@ int SPI_exec(const char * command, long count< const char * command - 包含要执行命令的字符串 + 包含待执行命令的字符串 @@ -590,7 +581,7 @@ int SPI_exec(const char * command, long count< long count - 要返回的最大行数,或者用0表示没有限制 + 要返回的最大行数,或者用 0 表示不限制 @@ -821,7 +812,7 @@ int SPI_execute_with_args(const char *command, SPI_execute_plan 达到类似效果。不过,使用本函数 时,查询计划总会针对所提供的具体参数值进行定制。对于一次性查询执行,应 优先选择本函数。如果同一条命令要用许多不同参数重复执行,则两种方式孰快 - 取决于重新计划的代价与定制计划收益之间的权衡。 + 取决于重新规划的代价与定制计划收益之间的权衡。 @@ -876,9 +867,9 @@ int SPI_execute_with_args(const char *command, 如果 nullsNULL,则 - SPI_execute_with_args 会假定没有参数为 NULL。 - 否则,如果对应参数值非 NULL,则 nulls 数组中 - 的对应项应为 ' ';如果对应参数值为 NULL,则 + SPI_execute_with_args 会假定没有参数为空值。 + 否则,如果对应参数值非空值,则 nulls 数组中 + 的对应项应为 ' ';如果对应参数值为空值,则 对应项应为 'n'。(后一种情况下,对应 values 项中的实际值无关紧要。)注意, nulls 不是文本字符串,而只是一个数组,因此不 @@ -932,7 +923,7 @@ int SPI_execute_with_args(const char *command, SPI_prepare - 准备一个语句,但不执行它 + 准备一个语句,但暂不执行 @@ -1011,8 +1002,7 @@ SPIPlanPtr SPI_prepare(const char * command, int 返回值 - SPI_prepare 返回一个指向非空 SPIPlan - 的指针,它是表示预备语句的不透明结构体。发生错误时会返回 + SPI_prepare 返回一个非空指针,指向表示预备语句的不透明结构体 SPIPlan。发生错误时会返回 NULL,并将 SPI_result 设为 SPI_execute 所使用的那些错误码之一;但如果 commandNULL,或者 @@ -1031,17 +1021,16 @@ SPIPlanPtr SPI_prepare(const char * command, int SPI_execute_plan 在最初几次使用时会根据提供的参数 值生成定制计划。当同一个预备语句被使用足够多次之后, SPI_execute_plan 会构建一个通用计划;如果它的代价 - 没有比定制计划高出太多,就会开始改用通用计划,而不是每次都重新计划。如 + 没有比定制计划高出太多,就会开始改用通用计划,而不是每次都重新规划。如 果这种默认行为不合适,可以把 CURSOR_OPT_GENERIC_PLANCURSOR_OPT_CUSTOM_PLAN 标志传给 SPI_prepare_cursor,分别强制使用通用计划或定制计划。 - 尽管预备语句的主要目的在于避免重复进行解析分析和计划,但只要语句中使用 + 尽管预备语句的主要目的在于避免重复进行解析分析和规划,但只要语句中使用 的数据库对象自上次使用该预备语句以来发生了定义性(DDL)变更, - PostgreSQL 就会在再次使用前强制重新分析并重 - 新计划该语句。此外,如果 的值在两次 + PostgreSQL 就会在再次使用前强制重新分析并重新规划该语句。此外,如果 的值在两次 使用之间发生变化,该语句也会基于新的 search_path 重 新解析。(后一种行为是从 PostgreSQL 9.3 开 始引入的。)有关预备语句行为的更多信息,请参见 @@ -1101,7 +1090,7 @@ SPIPlanPtr SPI_prepare_cursor(const char * command, int < - 此函数现已废弃,推荐改用 SPI_prepare_extended。 + 此函数现已弃用,推荐改用 SPI_prepare_extended @@ -1131,7 +1120,7 @@ SPIPlanPtr SPI_prepare_cursor(const char * command, int < Oid * argtypes - 指向数组的指针,该数组包含参数数据类型的 + 一个数组指针,它指向的数组包含参数的数据类型的 OID @@ -1200,7 +1189,7 @@ SPIPlanPtr SPI_prepare_extended(const char * command, SPI_prepare_extended 为指定命令创建并返回一个预备语 句,但并不执行该命令。它相当于 SPI_prepare,并额外 - 允许调用者指定选项,以控制外部参数引用的解析,以及查询解析和计划的其他 + 允许调用者指定选项,以控制外部参数引用的解析,以及查询解析和规划的其他 方面。 @@ -1240,7 +1229,7 @@ SPIPlanPtr SPI_prepare_extended(const char * command, ParserSetupHook parserSetup - 语法分析器钩子设置函数 + 解析器钩子设置函数 @@ -1318,7 +1307,7 @@ SPIPlanPtr SPI_prepare_params(const char * command, - 此函数现已废弃,推荐改用 SPI_prepare_extended。 + 此函数现已弃用,推荐改用 SPI_prepare_extended @@ -1339,7 +1328,7 @@ SPIPlanPtr SPI_prepare_params(const char * command, ParserSetupHook parserSetup - 语法分析器钩子设置函数 + 解析器钩子设置函数 @@ -1554,8 +1543,8 @@ bool SPI_is_cursor_plan(SPIPlanPtr plan) 返回值 - 如果 plan 能产生游标,则返回 - true;如果不能,则返回 false,并将 + 返回 truefalse,表示 + plan 能否产生游标,同时将 SPI_result 设为零。如果无法确定答案(例如 planNULL 或无效,或者在 未连接到 SPI 时调用),则会将 SPI_result 设为合适 @@ -1627,15 +1616,14 @@ int SPI_execute_plan(SPIPlanPtr plan, Datum * - 如果nullsNULL, - 那么SPI_execute_plan会假设没有参数 - 为空值。否则,如果对应的参数值为非空, - nulls - 数组的每一个项都应该是' ';如果对应参数值为空, - nulls数组的项应为'n'(在后 - 面的情况中,对应的values项中的值没有 - 关系)。注意nulls不是一个文本字符串, - 它只是一个数组:它不需要一个'\0'终止符。 + 如果 nullsNULL,则 + SPI_execute_plan 会假定没有参数为空值。 + 否则,如果对应参数值非空值,则 nulls 数组中 + 的对应项应为 ' ';如果对应参数值为空值,则 + 对应项应为 'n'。(后一种情况下,对应 + values 项中的实际值无关紧要。)注意, + nulls 不是文本字符串,而只是一个数组,因此不 + 需要 '\0' 终止符。 @@ -1708,7 +1696,7 @@ int SPI_execute_plan(SPIPlanPtr plan, Datum * SPI_execute_plan_extended - 执行一个由SPI_prepare准备的语句 + 执行由 SPI_prepare 准备好的语句 @@ -1793,8 +1781,9 @@ int SPI_execute_plan_extended(SPIPlanPtr plan, bool allow_nonatomic - true 允许以非原子方式执行 CALL 与 DO 语句 - (但除非向 SPI_connect_ext 传入了 + true 允许以非原子方式执行 CALL + 和 DO 语句(但除非向 + SPI_connect_ext 传入了 SPI_OPT_NONATOMIC 标志,否则该字段会被忽略) @@ -1814,7 +1803,7 @@ int SPI_execute_plan_extended(SPIPlanPtr plan, uint64 tcount - 要返回的最大行数,或者用0表示没有限制 + 要返回的最大行数,或者用 0 表示不限制 @@ -1899,7 +1888,7 @@ int SPI_execute_plan_with_paramlist(SPIPlanPtr plan, - 此函数现已废弃,推荐改用 SPI_execute_plan_extended。 + 此函数现已弃用,推荐改用 SPI_execute_plan_extended @@ -1936,7 +1925,7 @@ int SPI_execute_plan_with_paramlist(SPIPlanPtr plan, long count - 要返回的最大行数,或者用0表示没有限制 + 要返回的最大行数,或者用 0 表示不限制 @@ -2020,15 +2009,14 @@ int SPI_execp(SPIPlanPtr plan, Datum * values< - 如果nullsNULL, - 那么SPI_execp会假设没有参数 - 为空值。否则,如果对应的参数值为非空, - nulls - 数组的每一个项都应该是' ';如果对应参数值为空, - nulls数组的项应为'n'(在后 - 面的情况中,对应的values项中的值没有 - 关系)。注意nulls不是一个文本字符串, - 它只是一个数组:它不需要一个'\0'终止符。 + 如果 nullsNULL,则 + SPI_execp 会假定没有参数为空值。 + 否则,如果对应参数值非空值,则 nulls 数组中 + 的对应项应为 ' ';如果对应参数值为空值,则 + 对应项应为 'n'。(后一种情况下,对应 + values 项中的实际值无关紧要。)注意, + nulls 不是文本字符串,而只是一个数组,因此不 + 需要 '\0' 终止符。 @@ -2037,7 +2025,7 @@ int SPI_execp(SPIPlanPtr plan, Datum * values< long count - 要返回的最大行数,或者用0表示没有限制 + 要返回的最大行数,或者用 0 表示不限制 @@ -2145,15 +2133,14 @@ Portal SPI_cursor_open(const char * name, SPIPlanPtr - 如果nullsNULL, - 那么SPI_cursor_open会假设没有参数 - 为空值。否则,如果对应的参数值为非空, - nulls - 数组的每一个项都应该是' ';如果对应参数值为空, - nulls数组的项应为'n'(在后 - 面的情况中,对应的values项中的值没有 - 关系)。注意nulls不是一个文本字符串, - 它只是一个数组:它不需要一个'\0'终止符。 + 如果 nullsNULL,则 + SPI_cursor_open 会假定没有参数为空值。 + 否则,如果对应参数值非空值,则 nulls 数组中 + 的对应项应为 ' ';如果对应参数值为空值,则 + 对应项应为 'n'。(后一种情况下,对应 + values 项中的实际值无关紧要。)注意, + nulls 不是文本字符串,而只是一个数组,因此不 + 需要 '\0' 终止符。 @@ -2214,11 +2201,10 @@ Portal SPI_cursor_open_with_args(const char *name, - 对于一次性的查询执行,这个函数应该比 - SPI_prepare_cursor加上其后的 - SPI_cursor_open更好。如果相同的命令 - 要被用很多不同的参数执行,哪种方法更快就要取决于重做计划的 - 代价与定制计划带来的好处之间谁更有利。 + 对于一次性查询执行,应优先使用此函数,而不是先调用 + SPI_prepare_cursor 再调用 + SPI_cursor_open。如果同一条命令要用许多不同参数执行, + 哪种方法更快取决于重新规划的代价与定制计划收益之间的权衡。 @@ -2227,7 +2213,7 @@ Portal SPI_cursor_open_with_args(const char *name, - 此函数现已废弃,推荐改用 SPI_cursor_parse_open, + 此函数现已弃用,推荐改用 SPI_cursor_parse_open, 它提供了等价的功能,并使用更现代的查询参数处理 API。 @@ -2267,8 +2253,8 @@ Portal SPI_cursor_open_with_args(const char *name, Oid * argtypes - 一个长度为nargs的数组, - 包含参数的数据类型的OID + 一个长度为 nargs 的数组,包含参数数据类型的 + OID @@ -2277,8 +2263,7 @@ Portal SPI_cursor_open_with_args(const char *name, Datum * values - 一个长度为nargs的数组, - 包含实际的参数值 + 一个长度为 nargs 的数组,包含实际参数值 @@ -2287,20 +2272,19 @@ Portal SPI_cursor_open_with_args(const char *name, const char * nulls - 一个长度为nargs的数组, - 描述哪些参数为空值 + 一个长度为 nargs 的数组,用于描述哪些参数为 + 空值 - 如果nullsNULL, - 那么SPI_cursor_open_with_args会假设没有参数 - 为空值。否则,如果对应的参数值为非空, - nulls - 数组的每一个项都应该是' ';如果对应参数值为空, - nulls数组的项应为'n'(在后 - 面的情况中,对应的values项中的值没有 - 关系)。注意nulls不是一个文本字符串, - 它只是一个数组:它不需要一个'\0'终止符。 + 如果 nullsNULL,则 + SPI_cursor_open_with_args 会假定没有参数为空值。 + 否则,如果对应参数值非空值,则 nulls 数组中 + 的对应项应为 ' ';如果对应参数值为空值,则 + 对应项应为 'n'。(后一种情况下,对应 + values 项中的实际值无关紧要。)注意, + nulls 不是文本字符串,而只是一个数组,因此不 + 需要 '\0' 终止符。 @@ -2437,7 +2421,7 @@ Portal SPI_cursor_open_with_paramlist(const char *name, SPI_cursor_parse_open - 使用查询字符串和参数设置游标 + 使用查询字符串和参数建立游标 @@ -2463,7 +2447,7 @@ Portal SPI_cursor_parse_open(const char *name, 对于一次性查询执行,推荐优先使用此函数,而不是 SPI_prepare_cursorSPI_cursor_open_with_paramlist 的组合。如果同一条命 - 令要用很多不同参数执行,两种方法孰快则取决于重新计划的代价与定制计划带 + 令要用很多不同参数执行,两种方法孰快则取决于重新规划的代价与定制计划带 来的收益之间的权衡。 @@ -2700,7 +2684,7 @@ void SPI_cursor_fetch(Portal portal, bool forw 如果该游标的计划不是用CURSOR_OPT_SCROLL - 选项创建的,向后获取会失败。 + 选项创建的,向后获取可能失败。 @@ -2774,7 +2758,7 @@ void SPI_cursor_move(Portal portal, bool forwa 如果该游标的计划不是用CURSOR_OPT_SCROLL - 选项创建的,向后移动会失败。 + 选项创建的,向后移动可能失败。 @@ -2870,8 +2854,7 @@ void SPI_scroll_cursor_fetch(Portal portal, FetchDirectio 如果该游标的计划不是用CURSOR_OPT_SCROLL - 选项创建的,除FETCH_FORWARD之外的方向值会 - 失败。 + 选项创建的,除FETCH_FORWARD之外的方向值可能失败。 @@ -2968,8 +2951,7 @@ void SPI_scroll_cursor_move(Portal portal, FetchDirection 如果该游标的计划不是用CURSOR_OPT_SCROLL - 选项创建的,除FETCH_FORWARD之外的方向值会 - 失败。 + 选项创建的,除FETCH_FORWARD之外的方向值可能失败。 @@ -3191,8 +3173,8 @@ SPIPlanPtr SPI_saveplan(SPIPlanPtr plan) SPI_register_relation - ephemeral named relation - registering with SPI + 临时命名关系 + 向 SPI 注册 @@ -3216,7 +3198,7 @@ int SPI_register_relation(EphemeralNamedRelation enr) SPI_register_relation 使一个带有相关信息的临时命名关 - 系对通过当前 SPI 连接计划和执行的查询可用。 + 系对通过当前 SPI 连接规划和执行的查询可用。 @@ -3254,7 +3236,7 @@ int SPI_register_relation(EphemeralNamedRelation enr) - 在出错时,会返回下列负值之一: + 出错时,返回以下负值之一: @@ -3296,8 +3278,8 @@ int SPI_register_relation(EphemeralNamedRelation enr) SPI_unregister_relation - ephemeral named relation - unregistering from SPI + 临时命名关系 + 从 SPI 注销 @@ -3344,7 +3326,7 @@ int SPI_unregister_relation(const char * name) 返回值 - 如果该命令的执行成功,则会返回下列(非负)值: + 如果该命令的执行成功,则将返回下列(非负)值: @@ -3359,7 +3341,7 @@ int SPI_unregister_relation(const char * name) - 出现错误时,会返回下列负值之一: + 出错时,返回以下负值之一: @@ -3399,13 +3381,13 @@ int SPI_unregister_relation(const char * name) SPI_register_trigger_data - ephemeral named relation - registering with SPI + 临时命名关系 + 向 SPI 注册 - transition tables - implementation in PLs + 过渡表 + 在 PL 中实现 @@ -3429,8 +3411,8 @@ int SPI_register_trigger_data(TriggerData *tdata) SPI_register_trigger_data 使触发器捕获的所有临时关系 - 都能在通过当前 SPI 连接计划和执行的查询中使用。目前,这指的是通过 - REFERENCING OLD/NEW TABLE AS ... 子句定义、并由 + 都能在通过当前 SPI 连接规划和执行的查询中使用。目前,这指的是由带有 + REFERENCING OLD/NEW TABLE AS ... 子句的 AFTER 触发器捕获的过渡表。PL 触发器处理函数应在建 立 SPI 连接后调用此函数。 @@ -3456,7 +3438,7 @@ int SPI_register_trigger_data(TriggerData *tdata) 返回值 - 如果命令的执行成功,则会返回下列(非负)值: + 如果该命令的执行成功,则将返回下列(非负)值: @@ -3471,7 +3453,7 @@ int SPI_register_trigger_data(TriggerData *tdata) - 出现错误时,会返回下列负值之一: + 出错时,返回以下负值之一: @@ -3728,7 +3710,7 @@ char * SPI_getvalue(HeapTuple row, TupleDesc r 返回值 - 列值;如果该列为 NULL、colnumber 超出范围 + 列值;如果该列为空值、colnumber 超出范围 (SPI_result 被设置为 SPI_ERROR_NOATTRIBUTE)或者没有输出函数 可用(SPI_result 被设置为 @@ -3820,8 +3802,8 @@ Datum SPI_getbinval(HeapTuple row, TupleDesc r 返回值 - 返回该列的二进制值。如果该列为 NULL,则 - isnull 指向的变量会被设为 true,否则设为 false。 + 返回该列的二进制值。如果该列为空值,则 + isnull 指向的变量会被设为真,否则设为假。 @@ -3857,7 +3839,7 @@ char * SPI_gettype(TupleDesc rowdesc, int coln SPI_gettype返回该指定列的数据类型名称 - 的拷贝(当你不再需要该拷贝后,可以使用pfree + 的副本(当你不再需要该副本后,可以使用pfree 释放它)。 @@ -3989,7 +3971,7 @@ char * SPI_getrelname(Relation rel) SPI_getrelname返回该指定关系的名称 - 的拷贝(当你不再需要该拷贝后,可以使用pfree + 的副本(当你不再需要该副本后,可以使用pfree 释放它)。 @@ -4082,7 +4064,7 @@ char * SPI_getnspname(Relation rel) SPI_result_code_string - 将结果代码表示为字符串 + 返回错误码的字符串表示 @@ -4096,7 +4078,7 @@ const char * SPI_result_code_string(int code); SPI_result_code_string 返回各种 SPI 函数返回的,或 - 存放在 SPI_result 中的结果代码的字符串表示。 + 存放在 SPI_result 中的结果码的字符串表示。 @@ -4108,7 +4090,7 @@ const char * SPI_result_code_string(int code); int code - 结果代码 + 结果码 @@ -4119,7 +4101,7 @@ const char * SPI_result_code_string(int code); 返回值 - 结果代码的字符串表示。 + 结果码的字符串表示。 @@ -4131,8 +4113,8 @@ const char * SPI_result_code_string(int code); - memory context - in SPI + 内存上下文 + 在 SPI 中 PostgreSQL内存上下文 中分配内存。内存上下文为管理那些在许多不同位置创建、且生命周期各不相同 @@ -4157,7 +4139,7 @@ const char * SPI_result_code_string(int code); 办法是用 SPI_palloc 为返回对象分配内存。 SPI_palloc上层执行器上下文中分配 内存,也就是调用 SPI_connect 时的当前内存上下文; - 这正是从 C 函数返回值最合适的上下文。本节介绍的其他几个实用函数同样会返 + 这正是从 C 函数返回值最合适的上下文。本节介绍的其他几个辅助函数同样会返 回在上层执行器上下文中创建的对象。 @@ -4165,7 +4147,7 @@ const char * SPI_result_code_string(int code); 调用 SPI_connect 时,会把该 C 函数的私有上下文 (由 SPI_connect 创建)设为当前上下文。所有通过 pallocrepalloc 或 SPI - 实用函数分配的内存(本节另有说明的除外)都位于这个上下文中。当 C 函数通 + 辅助函数分配的内存(本节另有说明的除外)都位于这个上下文中。当 C 函数通 过 SPI_finish 与 SPI 管理器断开连接时,当前上下文 会恢复为上层执行器上下文,而在该 C 函数内存上下文中分配的所有内存都会被 释放,之后就不能再使用。 @@ -4360,7 +4342,7 @@ void SPI_pfree(void * pointer) SPI_copytuple - 在上层执行器上下文中创建一行的拷贝 + 在上层执行器上下文中创建一行的副本 @@ -4393,7 +4375,7 @@ HeapTuple SPI_copytuple(HeapTuple row) HeapTuple row - 要拷贝的行 + 要复制的行 @@ -4404,7 +4386,7 @@ HeapTuple SPI_copytuple(HeapTuple row) 返回值 - 拷贝后的行;出错时返回 NULL + 复制后的行;出错时返回 NULL (错误指示见 SPI_result @@ -4460,7 +4442,7 @@ HeapTupleHeader SPI_returntuple(HeapTuple row, TupleDesc HeapTuple row - 要拷贝的行 + 要复制的行 @@ -4469,7 +4451,7 @@ HeapTupleHeader SPI_returntuple(HeapTuple row, TupleDesc TupleDesc rowdesc - 行描述符(若要获得最佳缓存效果,大多数情况下应每次都传入同一个描述符) + 行描述符(若要获得最佳缓存效果,每次都传入同一个描述符) @@ -4480,7 +4462,7 @@ HeapTupleHeader SPI_returntuple(HeapTuple row, TupleDesc 返回值 - 指向拷贝后行的 HeapTupleHeader;出错时返回 + 指向复制后行的 HeapTupleHeader;出错时返回 NULL(错误指示见 SPI_result @@ -4582,13 +4564,14 @@ HeapTuple SPI_modifytuple(Relation rel, HeapTuple - 如果nullsNULL,那么 - SPI_modifytuple假定没有新值为空值。否则, - 如果对应的新值为非空,nulls数组的每一项都应 - 该是' ',而如果对应的新值为空值则为'n'(在 - 后一种情况中,对应的values项中的新值无关紧 - 要)。注意nulls不是一个文本字符串,只是一个 - 数组:它不需要一个'\0'终止符。 + 如果 nullsNULL,则 + SPI_modifytuple 会假定没有新值为空值。 + 否则,如果对应新值非空值,则 nulls 数组中 + 的对应项应为 ' ';如果对应新值为空值,则 + 对应项应为 'n'。(后一种情况下,对应 + values 项中的实际值无关紧要。)注意, + nulls 不是文本字符串,而只是一个数组,因此不 + 需要 '\0' 终止符。 @@ -4667,7 +4650,7 @@ void SPI_freetuple(HeapTuple row) SPI_freetuple释放之前在上层执行器上下文中 - 分配的一个行。 + 分配的一行。 @@ -4965,7 +4948,7 @@ void SPI_start_transaction(void) - 数据改变的可见性 + 数据更改的可见性 下列规则决定了使用 SPI 的函数(以及其他任何 C 函数)中数据更改的可见 diff --git a/zh/16/stylesheet-speedup-common.xsl b/zh/16/stylesheet-speedup-common.xsl index e3fb582a..403f350c 100644 --- a/zh/16/stylesheet-speedup-common.xsl +++ b/zh/16/stylesheet-speedup-common.xsl @@ -95,6 +95,6 @@ -en +zh_cn diff --git a/zh/16/syntax.sgml b/zh/16/syntax.sgml index b60a341f..d409cc09 100644 --- a/zh/16/syntax.sgml +++ b/zh/16/syntax.sgml @@ -21,7 +21,7 @@ 词法结构 - token + 词元 @@ -29,7 +29,7 @@ - 一个词元可以是关键词标识符带引号的标识符文字值(或常量),或者特殊字符符号。词元通常由空白(空格、制表符、换行)分隔,但如果不存在歧义,则不必如此(一般只有特殊字符与其他类型的词元相邻时才会这样)。 + 一个词元可以是关键词标识符带引号的标识符字面量(或常量),或者特殊字符符号。词元通常由空白(空格、制表符、换行)分隔,但如果不存在歧义,则不必如此(一般只有特殊字符与其他类型的词元相邻时才会这样)。 @@ -58,18 +58,18 @@ INSERT INTO MY_TABLE VALUES (3, 'hi there'); 标识符和关键词 - identifier - syntax of + 标识符 + 语法 - name - syntax of + 名称 + 语法 - key word - syntax of + 关键词 + 语法 @@ -83,7 +83,7 @@ INSERT INTO MY_TABLE VALUES (3, 'hi there'); - identifierlength + 标识符长度 系统对标识符最多只使用 NAMEDATALEN-1 个字节;在命令中可以写更长的名称,但它们会被截断。默认情况下, NAMEDATALEN 为 64,因此标识符的最大长度是 63 字节。如果这个限制有问题,可以通过修改 src/include/pg_config_manual.h 中的 NAMEDATALEN 常量来提高。 @@ -91,8 +91,8 @@ INSERT INTO MY_TABLE VALUES (3, 'hi there'); - case sensitivity - of SQL commands + 大小写敏感性 + SQL 命令 关键词和未加引号的标识符不区分大小写。因此: @@ -110,8 +110,8 @@ UPDATE my_table SET a = 5; - quotation marks - and identifiers + 引号 + 与标识符 还有第二类标识符:定界标识符带引号的标识符。它通过把任意字符序列括在双引号中形成(")。 定界标识符始终是标识符,绝不会是关键词。因此,"select" 可以用来引用名为 select 的列或表,而不加引号的 select 会被视为关键词,因此在期望表名或列名的位置使用时会导致解析错误。这个示例可以用带引号的标识符写成: @@ -133,7 +133,7 @@ UPDATE "my_table" SET "a" = 5; Unicode 转义 - in identifiers + 在标识符中 @@ -177,7 +177,7 @@ U&"d!0061t!+000061" UESCAPE '!' 常量 - constant + 常量 @@ -188,19 +188,15 @@ U&"d!0061t!+000061" UESCAPE '!' 字符串常量 - character string - constant + 字符串 + 常量 - - - quotation marks + + 引号 转义 - SQL 中的字符串常量是由单引号括起的任意字符序列,例如 - 'This is a string'。要在字符串常量中包含单引号字符,请写两个相邻的单引号,例如 - 'Dianne''s horse'。注意,这与双引号字符("不同 - + SQL 中的字符串常量是由单引号(')括起的任意字符序列,例如 'This is a string'。要在字符串常量中包含单引号字符,请写两个相邻的单引号,例如 'Dianne''s horse'。注意,这不同于双引号字符(")。 两个只由空白及至少一个新行分隔的字符串常量会被连接在一起,并且将作为一个写在一起的字符串常量来对待。例如: @@ -304,7 +300,7 @@ SELECT 'foo' 'bar'; - 如果配置参数off,那么PostgreSQL对常规字符串常量和转义字符串常量中的反斜线转义都识别。不过,从PostgreSQL 9.1 开始,该参数的默认值为on,意味着只在转义字符串常量中识别反斜线转义。这种行为更兼容标准,但是可能打断依赖于历史行为(反斜线转义总是会被识别)的应用。作为一种变通,你可以设置该参数为off,但是最好迁移到符合新的行为。如果你需要使用一个反斜线转义来表示一个特殊字符,为该字符串常量写上一个E。 + 如果配置参数off,那么PostgreSQL对常规字符串常量和转义字符串常量中的反斜线转义都识别。不过,从PostgreSQL 9.1 开始,该参数的默认值为on,意味着只在转义字符串常量中识别反斜线转义。这种行为更兼容标准,但是可能使依赖历史行为(始终识别反斜线转义)的应用无法正常工作。作为一种变通,你可以设置该参数为off,但最好修改应用,不再使用反斜线转义。如果你需要使用一个反斜线转义来表示一个特殊字符,为该字符串常量写上一个E @@ -322,7 +318,7 @@ SELECT 'foo' 'bar'; Unicode 转义 - in string constants + 在字符串常量中 @@ -368,7 +364,7 @@ U&'d!0061t!+000061' UESCAPE '!' 美元引用的字符串常量 - dollar quoting + 美元引用 @@ -411,8 +407,8 @@ $function$ 位串常量 - bit string - constant + 位串 + 常量 @@ -432,8 +428,8 @@ $function$ 数字常量 - number - constant + 数字 + 常量 @@ -510,12 +506,12 @@ $function$ - 为数字常量最初指定的数据类型,只是类型解析算法的起点。在大多数情况下,常量会根据上下文被自动强制转换成最合适的类型。必要时,你可以通过类型转换强制把一个数值解释为特定的数据类型。type cast + 为数字常量最初指定的数据类型,只是类型解析算法的起点。在大多数情况下,常量会根据上下文被自动强制转换成最合适的类型。必要时,你可以通过类型转换强制把一个数值解释为特定的数据类型。类型转换 例如,可以通过下面的写法强制把一个数值当作类型 realfloat4)处理: -REAL '1.23' -- string style -1.23::REAL -- PostgreSQL (historical) style +REAL '1.23' -- 字符串形式 +1.23::REAL -- PostgreSQL(历史)形式 这些实际上只是下面将要讨论的一般类型转换记法的特例。 @@ -526,8 +522,8 @@ REAL '1.23' -- string style 其他类型的常量 - data type - constant + 数据类型 + 常量 @@ -553,7 +549,7 @@ CAST ( 'string' AS type ) - 如中所述,::CAST() 以及函数调用语法也可以用来指定任意表达式的运行时类型转换。为避免语法歧义,type 'string' 语法只能用来指定简单字面常量的类型。该语法的另一个限制是不能用于数组类型;要指定数组常量的类型,请使用 ::CAST()。 + 如中所述,::CAST() 以及函数调用语法也可以用来指定任意表达式的运行时类型转换。为避免语法歧义,type 'string' 语法只能用来指定简单字面常量的类型。type 'string' 语法的另一个限制是不能用于数组类型;要指定数组常量的类型,请使用 ::CAST() @@ -566,8 +562,8 @@ CAST ( 'string' AS type ) 操作符 - operator - syntax + 操作符 + 语法 @@ -617,7 +613,7 @@ CAST ( 'string' AS type ) - 圆括号(())具有它们通常的含义,用来分组表达式并且强制优先。在某些情况中,圆括号被要求作为一个特定 SQL 命令的固定语法的一部分。 + 圆括号(())具有它们通常的含义,用来对表达式分组并确定运算优先级。在某些情况中,圆括号被要求作为一个特定 SQL 命令的固定语法的一部分。 @@ -635,7 +631,7 @@ CAST ( 'string' AS type ) - 分号(;)结束一个 SQL 命令。它不能出现在一个命令中间的任何位置,除了在一个字符串常量中或者一个被引用的标识符中。 + 分号(;)结束一个 SQL 命令。它不能出现在一个命令中间的任何位置,除了在一个字符串常量中或者一个带引号的标识符中。 @@ -647,7 +643,7 @@ CAST ( 'string' AS type ) - 星号(*)在某些上下文中用来表示表行或组合值的所有字段。当它被用作聚合函数的参数时,还有一种特殊含义,即该聚合不需要任何显式参数。 + 星号(*)在某些上下文中用来表示表行或复合值的所有字段。当它被用作聚合函数的参数时,还有一种特殊含义,即该聚合不需要任何显式参数。 @@ -665,22 +661,22 @@ CAST ( 'string' AS type ) 注释 - comment - in SQL + 注释 + 在 SQL 中 注释是一串以双连字符开始并延伸到行尾的字符,例如: --- This is a standard SQL comment +-- 这是一条标准 SQL 注释 另外,也可以使用 C 风格注释块: -/* multiline comment - * with nesting: /* nested block comment */ +/* 多行注释 + * 包含嵌套:/* 嵌套块注释 */ */ 这里该注释开始于/*并且延伸到匹配出现的*/。这些注释块可按照 SQL 标准中指定的方式嵌套,但和 C 中不同。这样我们可以注释掉一大段可能包含注释块的代码。 @@ -695,8 +691,8 @@ CAST ( 'string' AS type ) 操作符优先级 - operator - precedence + 操作符 + 优先级 @@ -740,7 +736,7 @@ CAST ( 'string' AS type ) + - - 一元加、一元减 + 一元正号、一元负号 @@ -752,19 +748,19 @@ CAST ( 'string' AS type ) AT - AT TIME ZONE, AT LOCAL + AT TIME ZONE ^ - 指数 + 求幂 * / % - 乘、除、模 + 乘、除、取模 @@ -776,7 +772,7 @@ CAST ( 'string' AS type ) (任意其他操作符) - 所有其他本地以及用户定义的操作符 + 所有其他内置以及用户定义的操作符 @@ -833,18 +829,7 @@ SELECT 3 OPERATOR(pg_catalog.+) 4; - - 版本 9.5 之前的PostgreSQL使用的操作符优先级 - 规则略有不同。特别是,<=>= - 和<>习惯于被当作普通操作符,IS - 测试习惯于具有较高的优先级。并且在一些认为NOT比 - BETWEEN优先级高的情况下,NOT BETWEEN - 和相关的结构的行为不一致。为了更好地兼容 SQL 标准并且减少对 - 逻辑上等价的结构不一致的处理,这些规则也得到了修改。在大部分情况下, - 这些变化不会导致行为上的变化,或者可能会产生no such operator - 错误,但可以通过增加圆括号解决。不过在一些极端情况中,查询可能在 - 没有被报告解析错误的情况下发生行为的改变。 - + PostgreSQL 9.5 之前的版本使用的操作符优先级规则略有不同。特别是,<=>=<> 过去被当作普通操作符;IS 测试过去具有较高的优先级;而 NOT BETWEEN 和相关结构的处理不一致,在某些情况下被认为具有 NOT 而不是 BETWEEN 的优先级。为了更好地符合 SQL 标准,并减少对逻辑等价结构的不一致处理造成的困惑,这些规则得到了修改。在大部分情况下,这些变化不会导致行为变化,或者可能会产生 no such operator 错误,但可以通过增加圆括号解决。不过在一些极端情况下,查询可能在没有报告任何解析错误的情况下改变行为。 @@ -1537,7 +1522,7 @@ SELECT * FROM tbl WHERE a COLLATE "C" > 'foo'; SELECT * FROM tbl WHERE (a > 'foo') COLLATE "C"; - 因为它尝试把一个排序规则应用到>操作符的结果,而它的数据类型是非可排序数据类型boolean。 + 因为它尝试把一个排序规则应用到>操作符的结果,而它的数据类型是不支持排序规则的数据类型boolean diff --git a/zh/16/system-views.sgml b/zh/16/system-views.sgml index 1617ce5f..410ebddb 100644 --- a/zh/16/system-views.sgml +++ b/zh/16/system-views.sgml @@ -45,11 +45,6 @@ - - pg_aios - 正在使用的异步 I/O 句柄 - - pg_available_extensions 可用的扩展 @@ -175,11 +170,6 @@ 共享内存分配 - - pg_shmem_allocations_numa - 共享内存分配的 NUMA 节点映射 - - pg_stats 规划器统计信息 @@ -225,293 +215,12 @@ 视图 - - pg_wait_events - 等待事件 - - - - - - - - - <structname>pg_aios</structname> - - - pg_aios - - - - pg_aios 视图列出当前正在使用的全部 - 句柄。I/O 句柄用于引用正在准备、执行或处于完成过程中的 - I/O 操作。pg_aios 为每个 I/O 句柄提供一行。 - - - - 该视图主要对 PostgreSQL 开发者有用, - 但在调优 PostgreSQL 时也可能有帮助。 - - - - <structname>pg_aios</structname> 列 - - - - - 列类型 - - - 描述 - - - - - - - - pid int4 - - - 发起该 I/O 的服务器进程 ID。 - - - - - - io_id int4 - - - I/O 句柄的标识符。I/O 完成后(或者在 I/O 启动前释放句柄时),句柄会被复用。每次复用时, - - pg_aios.io_generation - - 都会递增。 - - - - - - io_generation int8 - - - I/O 句柄的代次。 - - - - - - state text - - - I/O 句柄的状态: - - - - HANDED_OUT,已被代码引用但尚未使用 - - - - - DEFINED,执行所需的信息已知 - - - - - STAGED,已就绪,可执行 - - - - - SUBMITTED,已提交执行 - - - - - COMPLETED_IO,已完成,但结果尚未处理 - - - - - COMPLETED_SHARED,共享完成处理已完成 - - - - - COMPLETED_LOCAL,后端本地完成处理已完成 - - - - - - - - - operation text - - - 使用 I/O 句柄执行的操作: - - - - invalid,尚未知晓 - - - - - readv,向量化读取 - - - - - writev,向量化写入 - - - - - - - - - off int8 - - - I/O 操作的偏移量。 - - - - - - length int8 - - - I/O 操作的长度。 - - - - - - target text - - - I/O 的目标对象类型: - - - - smgr,关系上的 I/O - - - - - - - - - handle_data_len int2 - - - 与 I/O 操作关联的数据长度。对于指向或来自 - 的 I/O,该值表示 I/O 正在操作的缓冲区个数。 - - - - - - raw_result int4 - - - I/O 操作的底层结果;如果操作尚未完成,则为 NULL。 - - - - - - result text - - - I/O 操作的高级结果: - - - - UNKNOWN 表示操作结果尚未知晓。 - - - - - OK 表示 I/O 已成功完成。 - - - - - PARTIAL 表示 I/O 完成时没有出错,但未处理全部数据。通常调用方需要在单独的 I/O 中重试并完成剩余工作。 - - - - - WARNING 表示 I/O 完成时没有出错,但执行 I/O 时触发了警告。例如,在启用 时遇到损坏的缓冲区。 - - - - - ERROR 表示 I/O 因错误而失败。 - - - - - - - - - target_desc text - - - I/O 操作目标的描述。 - - - - - - f_sync bool - - - 标记该 I/O 是否同步执行。 - - - - - - f_localmem bool - - - 标记该 I/O 是否引用进程本地内存。 - - - - - - f_buffered bool - - - 标记该 I/O 是否为缓冲 I/O。 - - -
- - - pg_aios 视图是只读的。 - - - - 默认情况下,pg_aios视图只能由超级用户或具有 - pg_read_all_stats 角色权限的角色读取。 -
+ <structname>pg_available_extensions</structname> @@ -749,10 +458,10 @@ - type text + parent text - 内存上下文类型 + 此内存上下文的父上下文名称 @@ -761,18 +470,7 @@ level int4
- 该上下文在内存上下文层次中的层级,从 1 开始计数。上下文的层级也表示该上下文在 - path 列中的位置。 - - - - - - path int4[] - - - 由瞬态数字标识符组成的数组,用于描述内存上下文层次。第一个元素对应 - TopMemoryContext,后续元素包含中间父上下文,最后一个元素包含当前上下文的标识符。 + 与上下文树中 TopMemoryContext 的距离 @@ -827,24 +525,6 @@ 默认情况下,pg_backend_memory_contexts视图只能被超级用户或具有pg_read_all_stats角色权限的角色读取。 - - - 由于内存上下文会在查询运行期间创建和销毁,因此存储在 path 列中的标识符,在同一查询中多次调用该视图时可能不稳定。下面的示例展示了该列的一种有效用法,并计算 - CacheMemoryContext 及其全部子上下文所使用的总字节数: - - -WITH memory_contexts AS ( - SELECT * FROM pg_backend_memory_contexts -) -SELECT sum(c1.total_bytes) -FROM memory_contexts c1, memory_contexts c2 -WHERE c2.name = 'CacheMemoryContext' -AND c1.path[c2.level] = c2.path[c2.level]; - - - 这里使用了通用表表达式,以确保对视图进行两次求值时, - path 列中的上下文 ID 能够对应一致。 - @@ -1299,7 +979,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; address text - 主机名或IP地址,或者allsamehostsamenet之一,对于本地连接为空 + 主机名或IP地址,或者allsamehostsamenet之一,对于本地连接为 NULL @@ -1308,7 +988,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; netmask text - IP地址掩码,如果不适用则为空 + IP地址掩码,如果不适用则为 NULL @@ -1526,7 +1206,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; (参考 pg_tablespace.spcname) - 包含索引的表空间名(如果是数据库的默认值则为空) + 包含索引的表空间名(如果是数据库的默认值则为 NULL) @@ -1535,7 +1215,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; indexdef text - 索引定义(重构出的 命令) + 索引定义(重建出的 命令) @@ -1569,8 +1249,8 @@ AND c1.path[c2.level] = c2.path[c2.level]; 以及一般的数据库对象(由类OID和对象OID标识, 与pg_descriptionpg_depend中的方式相同)。 - 此外,扩展关系的权限被表示为一个单独的可锁定对象,以及更新 - pg_database.datfrozenxid 的更新权限。 + 此外,扩展关系的权利被表示为单独的可锁定对象,更新 + pg_database.datfrozenxid的权利也是如此。 此外,还可以对具有用户定义含义的数字施加咨询锁。 @@ -1617,7 +1297,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; (参考 pg_database.oid) - 锁目标存在的数据库的OID,如果目标是一个共享对象则为0,如果目标是一个事务ID则为空 + 锁目标存在的数据库的OID,如果目标是一个共享对象则为0,如果目标是一个事务ID则为 NULL @@ -1627,7 +1307,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; (参考 pg_class.oid) - 作为锁目标的关系的OID,如果目标不是一个关系或者只是关系的一部分则此列为空 + 作为锁目标的关系的OID,如果目标既不是关系,也不是关系的一部分则此列为 NULL @@ -1636,7 +1316,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; page int4 - 作为锁目标的页在关系中的页号,如果目标不是一个关系页或元组则此列为空 + 作为锁目标的页在关系中的页号,如果目标不是一个关系页或元组则此列为 NULL @@ -1645,7 +1325,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; tuple int2 - 作为锁目标的元组在页中的元组号,如果目标不是一个元组则此列为空 + 作为锁目标的元组在页中的元组号,如果目标不是一个元组则此列为 NULL @@ -1654,7 +1334,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; virtualxid text - 锁定目标事务的虚拟 ID,如果目标不是虚拟事务 ID,则为空;见 + 锁定目标事务的虚拟 ID,如果目标不是虚拟事务 ID,则为 NULL;见 @@ -1664,7 +1344,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; transactionid xid - 锁定目标事务的标识,如果目标不是事务 ID,则为空; + 锁定目标事务的标识,如果目标不是事务 ID,则为 NULL; @@ -1674,7 +1354,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; (参考 pg_class.oid) - 包含锁目标的系统目录的OID,如果目标不是一个普通数据库对象则此列为空 + 包含锁目标的系统目录的OID,如果目标不是一个普通数据库对象则此列为 NULL @@ -1684,7 +1364,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; (参考任意 OID 列) - 锁目标在它的系统目录中的OID,如果目标不是一个普通数据库对象则为空 + 锁目标在它的系统目录中的OID,如果目标不是一个普通数据库对象则为 NULL @@ -1693,7 +1373,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; objsubid int2 - 锁的目标列号(classidobjid指表本身),如果目标是某种其他普通数据库对象则此列为0,如果目标不是一个普通数据库对象则此列为空 + 锁的目标列号(classidobjid指表本身),如果目标是某种其他普通数据库对象则此列为0,如果目标不是一个普通数据库对象则此列为 NULL @@ -1711,7 +1391,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; pid int4 - 保持这个锁或者正在等待这个锁的服务器进程的PID,如果此锁被一个预备事务所持有则此列为空 + 保持这个锁或者正在等待这个锁的服务器进程的PID,如果此锁被一个预备事务所持有则此列为 NULL @@ -1747,8 +1427,8 @@ AND c1.path[c2.level] = c2.path[c2.level]; waitstart timestamptz - 服务器进程开始等待该锁的时间;如果锁已被授予则为空。 - 注意,在开始等待之后,即使grantedfalse,该值在极短时间内也可能仍为空。 + 服务器进程开始等待该锁的时间;如果锁已被授予则为 NULL。 + 注意,在开始等待之后,即使grantedfalse,该值在极短时间内也可能仍为 NULL。 @@ -1780,8 +1460,8 @@ AND c1.path[c2.level] = c2.path[c2.level]; 咨询锁可以在由单个 bigint 值或两个整数值组成的键上获取。 - 一个bigint键在classid列中显示其高阶半部分, - 在objid列中显示其低阶半部分,并且objsubid等于1。 + 一个bigint键在classid列中显示其高位半部分, + 在objid列中显示其低位半部分,并且objsubid等于1。 可以使用表达式(classid::bigint << 32) | objid::bigint重新组装原始bigint值。 整数键在classid列中显示第一个键,在objid列中显示第二个键, 并且 objsubid 等于 2。键的实际含义由用户自行决定。咨询锁在每个数据库内都是本地的, @@ -1830,15 +1510,15 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx pg_locks视图显示来自常规锁管理器和谓词锁管理器的数据,这两个是独立的系统; - 此外,常规锁管理器将其锁分为常规锁和fast-path锁。 + 此外,常规锁管理器将其锁分为常规锁和快速路径锁。 不能保证这些数据完全一致。 当查询该视图时, - fast-path 锁的数据(具有fastpath = true) + 快速路径锁的数据(具有fastpath = true) 从每个后端逐个收集,而不会冻结整个锁管理器的状态,因此在收集信息时可能会发生锁的获取或释放。 但请注意,这些锁已知不会与当前放置的任何其他锁发生冲突。 - 在查询所有后端的 fast-path 锁后,剩余的常规锁管理器将作为一个单元被锁定,并且所有剩余锁的一致快照将作为一个原子操作收集。 + 在查询所有后端的快速路径锁后,剩余的常规锁管理器将作为一个单元被锁定,并且所有剩余锁的一致快照将作为一个原子操作收集。 解锁常规锁管理器后,谓词锁管理器类似地被锁定,并且所有谓词锁将作为一个原子操作收集。 - 因此,除了 fast-path 锁外,每个锁管理器将提供一致的结果集,但由于我们不同时锁定两个锁管理器,因此在询问常规锁管理器后和在询问谓词锁管理器前,可能会发生锁的获取或释放。 + 因此,除了快速路径锁外,每个锁管理器将提供一致的结果集,但由于我们不同时锁定两个锁管理器,因此在询问常规锁管理器后和在询问谓词锁管理器前,可能会发生锁的获取或释放。 @@ -1914,7 +1594,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx (参考 pg_tablespace.spcname) - 包含物化视图的表空间名(如使用数据库默认表空间则为空) + 包含物化视图的表空间名(如使用数据库默认表空间则为 NULL) @@ -1941,7 +1621,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx definition text - 物化视图的定义(一个重构的查询) + 物化视图的定义(一个重建的查询) @@ -2132,7 +1812,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx 该预备语句返回列的类型,以 regtype 数组形式表示。该数组中某个元素对应的 OID 可以通过将 - regtype 值转换为 oid 获得。如果预备语句不提供结果(例如 DML 语句),则该字段为空。 + regtype 值转换为 oid 获得。如果预备语句不提供结果(例如 DML 语句),则该字段为 NULL。 @@ -2269,8 +1949,8 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx 视图pg_publication_tables提供发布与其所包含表之间映射关系的信息。与底层目录 pg_publication_rel不同,该视图会展开定义为 - FOR ALL TABLES - 和 FOR TABLES IN SCHEMA 的发布, + FOR ALL TABLES + 和 FOR TABLES IN SCHEMA 的发布, 因此对于这类发布,每个符合条件的表都会有一行。 @@ -2502,7 +2182,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx active bool - 如果该槽当前正被用于流送则为真 + 如果该槽当前正在使用中则为真 @@ -2511,7 +2191,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx active_pid int4 - 为该槽流送数据的会话的进程 ID。NULL 表示不活动。 + 如果该槽当前正在使用中,则为使用该槽的会话的进程 ID;不活动时为 NULL @@ -2547,7 +2227,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx confirmed_flush_lsn pg_lsn - 逻辑槽消费者已确认接收到数据的地址(LSN)。在此 LSN 之前提交的事务所对应的数据将不再可用。物理槽为 NULL。 + 逻辑槽消费者已确认接收的数据所到达的地址(LSN)。在此 LSN 之前提交的事务所对应的数据将不再可用。物理槽为 NULL @@ -2596,79 +2276,12 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - - - two_phase_at pg_lsn - - - 自哪个地址(LSN)起启用预备事务解码。对于 two_phase 为假的逻辑槽,以及物理槽,该值为 NULL。 - - - - - - inactive_since timestamptz - - - 槽变为不活动的时间。如果该槽当前正在被流送,则为 NULL。如果该槽变为无效,该值将不再更新。对于从主库同步而来的备库逻辑槽(其 synced 字段为 true),inactive_since 表示槽同步最近一次停止的时间。如果该槽始终保持同步,则为 NULL。这有助于跟踪备库上的槽同步何时被中断。 - - - conflicting bool - 如果该逻辑槽与恢复发生冲突(因此现已失效)则为真。当该列为真时,请检查 invalidation_reason 列以了解冲突原因。物理槽始终为 NULL。 - - - - - - invalidation_reason text - - - 该槽失效的原因。逻辑槽和物理槽都可能设置该值。若该槽未失效,则为 NULL。可能值为: - - - - wal_removed 表示所需的 WAL 已被移除。 - - - - - rows_removed 表示所需的行已被移除。该值只会设置在逻辑槽上。 - - - - - wal_level_insufficient 表示主库没有足够的 来执行逻辑解码。该值只会设置在逻辑槽上。 - - - - - idle_timeout 表示该槽保持不活动的时间已超过配置的 时长。 - - - - - - - - - failover bool - - - 如果这是一个允许同步到备库的逻辑槽则为真,这样逻辑复制就可以在故障切换后从新的主库恢复。物理槽始终为假。 - - - - - - synced bool - - - 如果这是一个从主库同步而来的逻辑槽则为真。在热备上,synced 列为真的槽既不能用于逻辑解码,也不能手工删除。该列在主库上的值没有意义;主库上该列默认对所有槽都为假,但也可能(如果是由已提升的备库遗留)为真。 + 如果该逻辑槽与恢复发生冲突(因此现已失效)则为真。物理槽始终为 NULL。 @@ -2686,7 +2299,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx 视图pg_roles提供数据库角色的信息。它本质上是 - pg_authid 的公开可读视图,并将密码字段清空。 + pg_authid 的公开可读视图,并隐藏密码字段。 @@ -2772,7 +2385,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx rolconnlimitint4 - 对于可以登录的角色,本列设置该角色可以同时发起最大连接数。-1表示无限制。 + 对于可以登录的角色,本列设置该角色能够建立的最大并发连接数。-1 表示无限制。 @@ -2790,7 +2403,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx rolvaliduntiltimestamptz - 密码过期时间(只用于密码认证),如果永不过期则为空 + 密码过期时间(仅用于密码认证);不设过期时间时为 NULL @@ -2888,7 +2501,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx definitiontext - 规则定义(创建命令的重构) + 规则定义(重建的创建命令) @@ -2974,7 +2587,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx (参考 pg_namespace.oid) - 如果适用,为此对象的命名空间 OID;否则为空。 + 如果适用,为此对象的命名空间 OID;否则为 NULL。 @@ -3281,7 +2894,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx min_valtext - 参数的最小允许值(对非数值参数为空) + 参数的最小允许值(对非数值参数为 NULL) @@ -3290,7 +2903,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx max_valtext - 参数的最大允许值(对非数值参数为空) + 参数的最大允许值(对非数值参数为 NULL) @@ -3299,7 +2912,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx enumvalstext[] - 枚举参数的允许值(对非枚举参数为空) + 枚举参数的允许值(对非枚举参数为 NULL) @@ -3487,7 +3100,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx 这个名称源于该表不应向公众开放读取,因为它包含密码。 pg_user - 是 pg_shadow 的公开可读视图,并将密码字段清空。 + 是 pg_shadow 的公开可读视图,并隐藏密码字段。
@@ -3676,79 +3289,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - - <structname>pg_shmem_allocations_numa</structname> - - - pg_shmem_allocations_numa - - - - pg_shmem_allocations_numa 显示服务器主共享内存段中的共享内存分配如何分布在各个 NUMA 节点上。这既包括 PostgreSQL 自身分配的内存,也包括扩展使用 所述机制分配的内存。只要共享内存段分布在多个 NUMA 节点上,该视图就会为每个共享内存段输出多行。监控系统不应查询此视图,因为它非常慢,而且如果共享内存此前尚未分配,还可能最终触发共享内存分配。目前该视图的限制是不会显示匿名共享内存分配。 - - - - 请注意,此视图不包括使用动态共享内存基础设施分配的内存。 - - - - - 在确定 NUMA 节点时,该视图会触碰共享内存段的所有内存页。这会强制分配共享内存(如果此前尚未分配),并且这些内存可能会被分配到单个 NUMA 节点上(取决于系统配置)。 - - - -
- <structname>pg_shmem_allocations_numa</structname> 列 - - - - - 列类型 - - - 描述 - - - - - - - - name text - - - 共享内存分配的名称 - - - - - - numa_node int4 - - - NUMA 节点 ID - - - - - - size int8 - - - 该分配在此特定 NUMA 内存节点上的大小,按字节计 - - - - - -
- - - 默认情况下,pg_shmem_allocations_numa视图只能由超级用户或具有 - pg_read_all_stats 角色权限的角色读取。 - -
- + <structname>pg_stats</structname> @@ -3826,7 +3367,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx null_frac float4 - 列项中为空的比例 + 列项中为 NULL 的比例 @@ -3854,7 +3395,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx most_common_vals anyarray - 列中高频值的一个列表(如果没有任何一个值看起来比其他值更常用,此列为空) + 列中高频值的一个列表(如果没有任何一个值看起来比其他值更常用,此列为 NULL) @@ -3863,7 +3404,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx most_common_freqs float4[] - 高频值的频率列表,即每一个高频值的出现次数除以总行数(如果most_common_vals为空,则此列为空) + 高频值的频率列表,即每一个高频值的出现次数除以总行数(如果most_common_vals为 NULL,则此列为 NULL) @@ -3872,7 +3413,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx histogram_bounds anyarray - 将列值划分成大小接近的组的值列表。如果存在most_common_vals,其中的值会被直方图计算所忽略(如果列类型没有一个<操作符或者most_common_vals等于整个值集合,则此列为空) + 将列值划分成大小接近的组的值列表。如果存在most_common_vals,其中的值会被直方图计算所忽略(如果列类型没有一个<操作符或者most_common_vals等于整个值集合,则此列为 NULL) @@ -3881,7 +3422,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx correlation float4 - 物理行顺序和列值逻辑顺序之间的统计关联。其范围从-1到+1。当值接近-1或+1时,在列上的一个索引扫描被认为比值接近0时的代价更低,因为这种情况减少了对磁盘的随机访问(如果列数据类型不具有一个<操作符,则此列为空) + 物理行顺序和列值逻辑顺序之间的统计关联。其范围从-1到+1。当值接近-1或+1时,在列上的一个索引扫描被认为比值接近0时的代价更低,因为这种情况减少了对磁盘的随机访问(如果列数据类型不具有一个<操作符,则此列为 NULL) @@ -3890,7 +3431,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx most_common_elems anyarray - 在列值中,最经常出现的非空元素列表(对标量类型为空) + 在列值中,最经常出现的非空元素列表(对标量类型为 NULL) @@ -3900,7 +3441,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx 最常用元素值的频度列表,即含有至少一个给定值实例的行的分数。 - 在每个元素的频度之后有二至三个附加值,它们是每个元素频度的最小和最大值,以及可选的空元素的频度(如果most_common_elems为空,则此列为空) + 在每个元素的频度之后有二至三个附加值,它们是每个元素频度的最小和最大值,以及可选的空元素的频度(如果most_common_elems为 NULL,则此列为 NULL) @@ -3909,42 +3450,10 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx elem_count_histogram float4[] - 在列值中可区分非空元素值计数的一个直方图,后面跟随可区分非空元素的平均数(对于标量类型为空) - - - - - - range_length_histogram anyarray - - - 范围类型列中非空且非 NULL 的范围值长度直方图。(对非范围类型为空。) - - - 该直方图使用范围函数 subtype_diff 计算,而不考虑范围边界是否包含端点。 + 在列值中可区分非空元素值计数的一个直方图,后面跟随可区分非空元素的平均数(对于标量类型为 NULL) - - - range_empty_frac float4 - - - 列项中值为空范围的比例。(对非范围类型为空。) - - - - - - range_bounds_histogram anyarray - - - 非空且非 NULL 的范围值下界和上界的直方图。(对非范围类型为空。) - - - 这两个直方图表示为单个数组列,其中下半部分表示下界的直方图,上半部分表示上界的直方图。 - - @@ -4108,7 +3617,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx most_common_vals text[] - 列中值的最常见组合的列表(如果没有组合看上去比其它的更常见,则为空。) + 列中值的最常见组合的列表(如果没有组合看上去比其它的更常见,则为 NULL。) @@ -4117,7 +3626,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx most_common_val_nulls bool[] - 值最常见组合的NULL标志的列表(当most_common_vals是空值时,为空。) + 值最常见组合的NULL标志的列表(当most_common_vals为 NULL 时,为 NULL。) @@ -4126,7 +3635,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx most_common_freqs float8[] - 最常见组合的频率的列表,即每个出现的数量除以行的总数(当most_common_vals是空值时,为空) + 最常见组合的频率的列表,即每个出现的数量除以行的总数(当most_common_vals为 NULL 时,为 NULL) @@ -4135,7 +3644,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx most_common_base_freqs float8[] - 最常见组合的基本频率的列表,即每个值频率的乘积。(当most_common_vals是空值时,为空。) + 最常见组合的基本频率的列表,即每个值频率的乘积。(当most_common_vals为 NULL 时,为 NULL。) @@ -4260,7 +3769,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx null_frac float4 - 表达式条目为空的比例 + 表达式条目为 NULL 的比例 @@ -4288,7 +3797,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx most_common_vals anyarray - 表达式中高频值的列表(如果没有值看起来比任何其他值更常见则为空) + 表达式中高频值的列表(如果没有值看起来比任何其他值更常见则为 NULL) @@ -4297,7 +3806,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx most_common_freqs float4[] - 高频值的频率列表,即每一个高频值的出现次数除以总行数(如果most_common_vals为空,则此列为空) + 高频值的频率列表,即每一个高频值的出现次数除以总行数(如果most_common_vals为 NULL,则此列为 NULL) @@ -4306,7 +3815,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx histogram_bounds anyarray - 将表达式的值划分成大小接近的组的值列表。如果存在most_common_vals,其中的值会被直方图计算所忽略(如果表达式的数据类型没有一个<操作符或者most_common_vals等于整个值集合,则此列为空) + 将表达式的值划分成大小接近的组的值列表。如果存在most_common_vals,其中的值会被直方图计算所忽略(如果表达式的数据类型没有一个<操作符或者most_common_vals等于整个值集合,则此列为 NULL) @@ -4315,7 +3824,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx correlation float4 - 物理行顺序和表达式值逻辑顺序之间的统计关联。其范围从-1到+1。当值接近-1或+1时,在表达式上的一个索引扫描被认为比值接近0时的代价更低,因为这种情况减少了对磁盘的随机访问(如果表达式的数据类型不具有一个<操作符,则此列为空) + 物理行顺序和表达式值逻辑顺序之间的统计关联。其范围从-1到+1。当值接近-1或+1时,在表达式上的一个索引扫描被认为比值接近0时的代价更低,因为这种情况减少了对磁盘的随机访问(如果表达式的数据类型不具有一个<操作符,则此列为 NULL) @@ -4324,7 +3833,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx most_common_elems anyarray - 与表达式的值一起最常出现的非空元素值的列表。(标量类型时为空) + 与表达式的值一起最常出现的非空元素值的列表。(标量类型时为 NULL) @@ -4334,7 +3843,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx 最常用元素值的频度列表,即含有至少一个给定值实例的行的分数。 - 在每个元素的频度之后有二至三个附加值,它们是每个元素频度的最小和最大值,以及可选的空元素的频度(如果most_common_elems为空,则此列为空) + 在每个元素的频度之后有二至三个附加值,它们是每个元素频度的最小和最大值,以及可选的空元素的频度(如果most_common_elems为 NULL,则此列为 NULL) @@ -4343,7 +3852,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx elem_count_histogram float4[] - 表达式值的不同非空元素值的计数的直方图,后面跟着不同非空元素的平均数量。(标量类型时为空) + 表达式值的不同非空元素值的计数的直方图,后面跟着不同非空元素的平均数量。(标量类型时为 NULL) @@ -4420,7 +3929,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx (参考 pg_tablespace.spcname) - 包含该表的表空间名称(如果使用数据库的默认表空间,此列为空) + 包含该表的表空间名称(如果使用数据库的默认表空间,此列为 NULL) @@ -4617,7 +4126,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx 视图pg_user提供数据库用户的信息。它本质上是 - pg_shadow 的公开可读视图,并将密码字段清空。 + pg_shadow 的公开可读视图,并隐藏密码字段。 @@ -4895,7 +4404,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx definitiontext - 视图定义(一个重构的查询) + 视图定义(一个重建的查询) @@ -4904,61 +4413,5 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - - <structname>pg_wait_events</structname> - - - pg_wait_events - - - - 视图pg_wait_events提供等待事件的相关描述。 - - -
- <structname>pg_wait_events</structname> 列 - - - - - 列类型 - - - 描述 - - - - - - - - type text - - - 等待事件类型 - - - - - - name text - - - 等待事件名称 - - - - - - description text - - - 等待事件描述 - - - - -
-
- + diff --git a/zh/16/textsearch.sgml b/zh/16/textsearch.sgml index b91b9f43..d4e1462f 100644 --- a/zh/16/textsearch.sgml +++ b/zh/16/textsearch.sgml @@ -2099,7 +2099,7 @@ ALTER TEXT SEARCH CONFIGURATION russian 分类词典示例 - 考虑简单的天文词库 thesaurus_astro,其中包含一些天文单词组合: + 考虑简单的天文词库 thesaurus_astro,其中包含一些天文单词组合: supernovae stars : sn @@ -2534,7 +2534,7 @@ ts_debug( config re - 以下是一个简单的示例: + 以下是一个简单的示例: SELECT * FROM ts_debug('english', 'a fat cat sat on a mat - it ate a fat rats'); diff --git a/zh/16/trigger.sgml b/zh/16/trigger.sgml index 9c318d8f..71cc5b76 100644 --- a/zh/16/trigger.sgml +++ b/zh/16/trigger.sgml @@ -4,7 +4,7 @@ 触发器 - trigger + 触发器 @@ -73,38 +73,15 @@ 如果触发器被定义为 约束触发器,则 AFTER 触发器的执行可被推迟到事务末尾,而不是语句末尾。 - 无论哪种情况,触发器都作为触发它的语句所属同一事务的一部分执行,因此只要语句或触发器任一方发生错误,二者的效果都会回滚。此外,触发器总是以将该触发事件排入队列的角色身份运行,除非触发器函数标记为 - SECURITY DEFINER,那样的话则以函数所有者身份运行。 - - - - 若 INSERT 包含 ON CONFLICT DO UPDATE - 子句,则被触发的行上可能先执行行级 - BEFORE INSERT 触发器,再执行 - BEFORE UPDATE 触发器。若触发器不是 - 幂等的,这种交互可能很复杂,因为 BEFORE - INSERT 触发器所做更改会被 - BEFORE UPDATE 触发器看到, - 包括对 EXCLUDED 列的更改。 - - - - 注意,当指定 ON CONFLICT DO UPDATE 时,语句级 - UPDATE 触发器会执行,不管 - UPDATE 是否实际影响了行(也不管是否走到了 - UPDATE 分支)。带有 - ON CONFLICT DO UPDATEINSERT - 会先执行语句级 BEFORE INSERT - 触发器,再执行语句级 BEFORE UPDATE - 触发器,然后执行语句级 AFTER UPDATE - 触发器,最后执行语句级 AFTER INSERT - 触发器。 + 无论哪种情况,触发器都作为触发它的语句所属同一事务的一部分执行,因此只要语句或触发器任一方发生错误,二者的效果都会回滚。 如果某条语句以继承层次或分区层次中的父表为目标,它不会导致受影响子表上的语句级触发器触发;只有父表上的语句级触发器会触发。不过,任何受影响子表上的行级触发器仍会触发。 + INSERT 包含 ON CONFLICT DO UPDATE 子句,则行级 BEFORE INSERT 触发器和行级 BEFORE UPDATE 触发器的效果可能都会体现在更新后行的最终状态中,前提是引用了 EXCLUDED 列。不过,即使没有引用 EXCLUDED 列,这两组行级 BEFORE 触发器也可能都会执行。如果同时存在会更改正在插入/更新的行的 BEFORE INSERTBEFORE UPDATE 行级触发器,就应考虑可能出现令人意外的结果(即使它们的修改大致等效,如果不具有幂等性,也可能出现问题)。注意,语句级 UPDATE 触发器会在指定 ON CONFLICT DO UPDATE 时执行,不管 UPDATE 是否实际影响了行(也不管是否走到了 UPDATE 分支)。INSERT 如果带有 ON CONFLICT DO UPDATE 子句,会先执行语句级 BEFORE INSERT 触发器,再执行语句级 BEFORE UPDATE 触发器,然后执行语句级 AFTER UPDATE 触发器,最后执行语句级 AFTER INSERT 触发器。 + 如果对分区表执行 UPDATE 导致某行移动到另一个分区,这将表现为从原始分区执行一次 DELETE,然后向新分区执行一次 INSERT。在这种情况下,原始分区上的所有行级 BEFORE UPDATE 触发器和所有行级 @@ -125,7 +102,7 @@ - 在执行 MERGE 命令时,对于该命令动作中指定的事件,无论该动作最终是否实际执行,语句级 + 在执行 MERGE 命令时,对于 MERGE 命令的动作中指定的事件,无论该动作最终是否实际执行,语句级 BEFOREAFTER 触发器都会触发。这与更新零行的 UPDATE 语句相同:尽管没有行被更新,语句级触发器仍会触发。只有在某行确实被更新、插入或删除时,行级触发器才会触发。因此,完全可能出现这样的情况:某类动作的语句级触发器已经触发,而同类动作的行级触发器却一个也没有触发。 @@ -169,19 +146,18 @@ 生成列还有一些额外注意事项。 - generated columnin - triggers + 生成列在触发器中 存储型生成列会在 BEFORE 触发器之后、AFTER 触发器之前计算。因此,可以在 AFTER 触发器中检查生成值。在 BEFORE 触发器中,OLD 行如预期那样包含旧的 生成值,但 NEW 行尚未包含新的生成值,因此不应访问。对于 C 语言接口,此时该列内容未定义;更高层编程语言应阻止在 BEFORE 触发器中访问 NEW 行中的存储型 - 生成列。在 BEFORE 触发器中对生成列值所做的修改会被忽略并随后被覆盖。虚拟生成列在触发器触发时永远不会被计算。在 C 语言接口中,它们在触发器函数中的内容是未定义的;更高层编程语言应阻止在触发器中访问虚拟生成列。 + 生成列。在 BEFORE 触发器中对生成列值所做的修改会被忽略并随后被覆盖。 - 如果在同一关系上的同一事件为其定义了多个触发器,它们会按触发器名称的字母顺序触发。对于 BEFOREINSTEAD OF + 如果为同一关系上的同一事件定义了多个触发器,它们会按触发器名称的字母顺序触发。对于 BEFOREINSTEAD OF 触发器,每个触发器返回的、可能已经被修改过的行都会成为下一个触发器的输入。如果任何一个 BEFOREINSTEAD OF 触发器返回 NULL,则会放弃对该行执行该操作,并且后续触发器(针对该行)都不会再触发。 @@ -191,7 +167,7 @@ 条件,不过这个特性对它们用处不大。)在 BEFORE 触发器中, WHEN 条件就在函数即将执行或本会执行之前求值,因此使用 WHEN 与在触发器函数开头测试同样的条件并无实质差别。不过,在 - AFTER 触发器中,WHEN 条件会在行更改发生后立即求值,并决定是否要在语句末尾将一个事件排入队列以触发该触发器。因此,当 AFTER 触发器的 WHEN + AFTER 触发器中,WHEN 条件会在行更改发生后立即求值,并决定是否要将一个事件排入队列,以便在语句末尾触发该触发器。因此,当 AFTER 触发器的 WHEN 条件不返回真时,就不必排队该事件,也不必在语句末尾重新取出该行。如果触发器只需要针对少数几行触发,这会让修改大量行的语句显著加快。 INSTEAD OF 触发器不支持 WHEN 条件。 @@ -208,17 +184,10 @@ 如果触发器函数执行 SQL 命令,那么这些命令可能会再次触发触发器。这就是所谓的级联触发器。对级联层数没有直接限制。级联还有可能导致同一个触发器被递归调用;例如,一个 INSERT 触发器可能执行一条向同一个表再插入一行的命令,从而导致该 INSERT 触发器再次触发。因此,在这种场景下,避免无限递归是触发器编写者自己的责任。 - - 若外键约束指定了引用动作(即级联更新或级联删除),这些动作会通过在引用表上执行 - 普通 SQL UPDATEDELETE 命令完成。 - 特别地,引用表上存在的触发器会因这些更改而触发。若此类触发器修改或阻止了这些 - 命令之一的效果,最终可能破坏引用完整性。避免这种情况是触发器编写者的责任。 - - - trigger - arguments for trigger functions + 触发器 + 触发器函数的参数 在定义触发器时,可以为它指定参数。在触发器定义中包含参数,是为了让需求相似的不同触发器能够调用同一个函数。举例来说,可以有一个通用触发器函数,它接受两个列名作为参数,把当前用户写入其中一个列,把当前时间戳写入另一个列。只要编写得当,这个触发器函数就应独立于它所作用的具体表。因此,同一个函数可用于任何具有适当列的表上的 INSERT 事件,例如自动跟踪某个事务表中记录的创建。如果把它定义成 UPDATE 触发器,还可以用来跟踪最近更新事件。 @@ -301,13 +270,13 @@ 用 C 编写触发器函数 - trigger - in C + 触发器 + 在 C 中 - transition tables - referencing from C trigger + 过渡表 + 从 C 触发器中引用 @@ -319,7 +288,7 @@ - 当函数由触发器管理器调用时,不会向它传递任何普通参数,但会传递一个指向 TriggerData 结构体的 context 指针。C 函数可以通过执行下列宏来检查自己是否由触发器管理器调用: + 当函数由触发器管理器调用时,不会向它传递任何普通参数,但会传递一个指向 TriggerData 结构体的 上下文 指针。C 函数可以通过执行下列宏来检查自己是否由触发器管理器调用: CALLED_AS_TRIGGER(fcinfo) @@ -378,7 +347,7 @@ typedef struct TriggerData TRIGGER_FIRED_BEFORE(tg_event) - 如果触发器在操作之前触发,则返回 true。 + 如果触发器在操作之前触发,则返回真。 @@ -387,7 +356,7 @@ typedef struct TriggerData TRIGGER_FIRED_AFTER(tg_event) - 如果触发器在操作之后触发,则返回 true。 + 如果触发器在操作之后触发,则返回真。 @@ -396,7 +365,7 @@ typedef struct TriggerData TRIGGER_FIRED_INSTEAD(tg_event) - 如果触发器是取代该操作而触发,则返回 true。 + 如果触发器是取代该操作而触发,则返回真。 @@ -405,7 +374,7 @@ typedef struct TriggerData TRIGGER_FIRED_FOR_ROW(tg_event) - 如果触发器是因行级事件触发,则返回 true。 + 如果触发器是因行级事件触发,则返回真。 @@ -414,7 +383,7 @@ typedef struct TriggerData TRIGGER_FIRED_FOR_STATEMENT(tg_event) - 如果触发器是因语句级事件触发,则返回 true。 + 如果触发器是因语句级事件触发,则返回真。 @@ -423,7 +392,7 @@ typedef struct TriggerData TRIGGER_FIRED_BY_INSERT(tg_event) - 如果触发器是由 INSERT 命令触发,则返回 true。 + 如果触发器是由 INSERT 命令触发,则返回真。 @@ -432,7 +401,7 @@ typedef struct TriggerData TRIGGER_FIRED_BY_UPDATE(tg_event) - 如果触发器是由 UPDATE 命令触发,则返回 true。 + 如果触发器是由 UPDATE 命令触发,则返回真。 @@ -441,7 +410,7 @@ typedef struct TriggerData TRIGGER_FIRED_BY_DELETE(tg_event) - 如果触发器是由 DELETE 命令触发,则返回 true。 + 如果触发器是由 DELETE 命令触发,则返回真。 @@ -450,7 +419,7 @@ typedef struct TriggerData TRIGGER_FIRED_BY_TRUNCATE(tg_event) - 如果触发器是由 TRUNCATE 命令触发,则返回 true。 + 如果触发器是由 TRUNCATE 命令触发,则返回真。 @@ -609,16 +578,16 @@ typedef struct Trigger - 一个完整的触发器实例 + 一个完整的触发器示例 这里给出一个非常简单的、用 C 编写的触发器函数示例。(用过程语言编写的触发器示例可见各过程语言的文档。) - 如果某条命令试图向列 x 中插入空值,函数 - trigf 就会报告表 ttest - 中的行数,并跳过实际操作。(这样,这个触发器就起到了非空约束的作用,但不会中止事务。) + 函数 trigf 会报告表 ttest 中的行数, + 并在命令试图向列 x 中插入空值时跳过实际操作。 + (这样,这个触发器就起到了非空约束的作用,但不会中止事务。) @@ -677,7 +646,8 @@ trigf(PG_FUNCTION_ARGS) tupdesc = trigdata->tg_relation->rd_att; /* connect to SPI manager */ - SPI_connect(); + if ((ret = SPI_connect()) < 0) + elog(ERROR, "trigf (fired %s): SPI_connect returned %d", when, ret); /* get number of rows in table */ ret = SPI_exec("SELECT count(*) FROM ttest", 0); diff --git a/zh/16/typeconv.sgml b/zh/16/typeconv.sgml index 15e7c27c..984ee0cf 100644 --- a/zh/16/typeconv.sgml +++ b/zh/16/typeconv.sgml @@ -30,7 +30,7 @@ -PostgreSQL扫描器/解析器将词法元素分成五个基本类别:整数、非整数数字、字符串、标识符和关键字。大多数非数值类型的常量会先被归类为字符串。SQL语言定义允许用字符串指定类型名,而PostgreSQL可以利用这一机制让解析器从一开始就沿着正确的路径处理。例如,查询: +PostgreSQL扫描器/解析器将词法元素分成五个基本类别:整数、非整数数字、字符串、标识符和关键字。大多数非数值类型的常量会先被归类为字符串。SQL语言定义允许给字符串指定类型名,而PostgreSQL可以利用这一机制让解析器从一开始就沿着正确的路径处理。例如,查询: SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; @@ -41,7 +41,7 @@ SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; (1 row) -包含两个文字常量,它们的类型分别是textpoint。如果没有为某个字符串文字指定类型,那么它最初会被赋予占位类型unknown,并在后文所述的后续阶段解析。 +包含两个字面量,它们的类型分别是textpoint。如果没有为某个字符串字面量指定类型,那么它最初会被赋予占位类型unknown,并在后文所述的后续阶段解析。 @@ -166,11 +166,11 @@ SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; -检查是否存在一个恰好接受输入参数类型的操作符。如果存在(在被考虑的操作符集合中至多只有一个精确匹配),就使用它。若通过限定名调用(这种情况并不常见)某个允许不可信用户创建对象的模式中的操作符,而又缺少精确匹配,就会带来安全隐患 +检查是否存在一个恰好接受输入参数类型的操作符。如果存在(在被考虑的操作符集合中至多只有一个精确匹配),就使用它。若通过限定名调用(这种情况并不常见)某个允许不受信任的用户创建对象的模式中的操作符,而又缺少精确匹配,就会带来安全隐患 - 对于未带模式限定的名称,不会出现这种隐患,因为包含允许不可信用户创建对象的模式的搜索路径不是一种模式的安全使用方式。 + 对于未带模式限定的名称,不会出现这种隐患,因为包含允许不受信任的用户创建对象的模式的搜索路径不是一种模式的安全使用方式。 。在这种情况下,应通过对参数进行类型转换来强制获得精确匹配。 @@ -186,7 +186,7 @@ SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; -如果二元操作符调用的一个参数是unknown类型,而另一个是域类型,则接着检查是否存在两边都恰好接受该域基类型的操作符;如果有,就使用它。 +如果二元操作符调用的一个参数是unknown类型,而另一个是域类型,则接着检查是否存在两边都恰好接受该域基础类型的操作符;如果有,就使用它。 @@ -201,13 +201,13 @@ SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; -丢弃那些输入类型不匹配,且也无法通过隐式类型转换实现匹配的候选操作符。为此,假定unknown文字可以转换为任何类型。如果只剩一个候选操作符,就使用它;否则继续下一步。 +丢弃那些输入类型不匹配,且也无法通过隐式类型转换实现匹配的候选操作符。为此,假定unknown字面量可以转换为任何类型。如果只剩一个候选操作符,就使用它;否则继续下一步。 -如果任何输入参数是域类型,则在后续所有步骤中都把它当作该域的基类型。这样可以确保在解决操作符歧义时,域的行为与其基类型一致。 +如果任何输入参数是域类型,则在后续所有步骤中都把它当作该域的基础类型。这样可以确保在解决操作符歧义时,域的行为与其基础类型一致。 @@ -219,13 +219,13 @@ SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; -遍历所有候选操作符,保留那些在需要类型转换的最多位置上接受首选类型(属于输入数据类型的类型分类)的候选项。如果没有候选项接受首选类型,则保留全部候选项。如果只剩一个候选操作符,就使用它;否则继续下一步。 +遍历所有候选操作符,在需要类型转换的位置上,保留接受首选类型(属于输入数据类型的类型分类)的位置数最多的候选项。如果没有候选项接受首选类型,则保留全部候选项。如果只剩一个候选操作符,就使用它;否则继续下一步。 -如果有任何输入参数是unknown,就检查剩余候选操作符在这些参数位置上接受哪些类型分类。在每个位置上,如果有任何候选项接受string分类,就选择该分类。(这种偏向字符串的做法是合适的,因为unknown类型的文字看起来像字符串。)否则,如果所有剩余候选项都接受同一种类型分类,就选择该分类;否则失败,因为在缺少更多线索的情况下无法推断出正确选择。然后丢弃不接受所选类型分类的候选项。此外,如果有任何候选项接受该分类中的首选类型,就丢弃在该参数上接受非首选类型的候选项。如果没有候选项通过这些测试,则保留全部候选项。如果只剩一个候选操作符,就使用它;否则继续下一步。 +如果有任何输入参数是unknown,就检查剩余候选操作符在这些参数位置上接受哪些类型分类。在每个位置上,如果有任何候选项接受string分类,就选择该分类。(这种偏向字符串的做法是合适的,因为unknown类型的字面量看起来像字符串。)否则,如果所有剩余候选项都接受同一种类型分类,就选择该分类;否则失败,因为在缺少更多线索的情况下无法推断出正确选择。然后丢弃不接受所选类型分类的候选项。此外,如果有任何候选项接受该分类中的首选类型,就丢弃在该参数上接受非首选类型的候选项。如果没有候选项通过这些测试,则保留全部候选项。如果只剩一个候选操作符,就使用它;否则继续下一步。 @@ -273,7 +273,7 @@ SELECT |/ CAST(40 AS double precision) AS "square root of 40"; -一个只有一个未指定参数的例子: +一个参数未指定类型的例子: SELECT text 'abc' || 'def' AS "text and unknown"; @@ -301,7 +301,7 @@ SELECT 'abc' || 'def' AS "unspecified"; -这里对使用哪种类型没有初始提示,因为查询中没有指定任何类型。因此,解析器会查找所有候选操作符,并发现既有接受字符串分类输入的候选项,也有接受位串分类输入的候选项。由于在可用时优先选择字符串分类,所以会选中该分类,再使用字符串的首选类型text作为解析这些unknown类型文字的具体类型。 +这里对使用哪种类型没有初始提示,因为查询中没有指定任何类型。因此,解析器会查找所有候选操作符,并发现既有接受字符串分类输入的候选项,也有接受位串分类输入的候选项。由于在可用时优先选择字符串分类,所以会选中该分类,再使用字符串的首选类型text作为解析这些unknown类型字面量的具体类型。 @@ -318,7 +318,7 @@ SELECT @ '-4.5' AS "abs"; 4.5 (1 row) -这里,系统在应用所选操作符之前,已经把unknown类型文字隐式解析为float8。我们可以验证使用的确实是float8,而不是其他类型: +这里,系统在应用所选操作符之前,已经把unknown类型字面量隐式解析为float8。我们可以验证使用的确实是float8,而不是其他类型: SELECT @ '-4.5e500' AS "abs"; @@ -352,7 +352,7 @@ SELECT ~ CAST('20' AS int8) AS "negation"; 数组包含操作符类型解析 -下面是另一个解析一边已知、一边未知输入的操作符的例子: +下面是另一个解析带有一个已知类型输入和一个未知类型输入的操作符的例子: SELECT array[1,2] <@ '{1,2,3}' as "is subset"; @@ -361,7 +361,7 @@ SELECT array[1,2] <@ '{1,2,3}' as "is subset"; t (1 row) -PostgreSQL操作符目录中为中缀操作符<@定义了多个条目,但左侧能够接受整数数组的只有两种:数组包含(anyarray <@ anyarray)和范围包含(anyelement <@ anyrange)。由于这些多态伪类型(见)都不被视为首选类型,解析器无法据此消除歧义。不过,告诉它可以假定unknown类型文字与另一输入具有相同类型,也就是整数数组。这样两个操作符中只有一个能够匹配,因此会选择数组包含。(如果选中范围包含,就会报错,因为该字符串的格式并不是合法的范围文字。) +PostgreSQL操作符目录中为中缀操作符<@定义了多个条目,但左侧能够接受整数数组的只有两种:数组包含(anyarray <@ anyarray)和范围包含(anyelement <@ anyrange)。由于这些多态伪类型(见)都不被视为首选类型,解析器无法据此消除歧义。不过,要求它假定unknown类型字面量与另一输入具有相同类型,也就是整数数组。这样两个操作符中只有一个能够匹配,因此会选择数组包含。(如果选中范围包含,就会报错,因为该字符串的格式并不是合法的范围字面量。) @@ -370,7 +370,7 @@ SELECT array[1,2] <@ '{1,2,3}' as "is subset"; 域类型上的自定义操作符 -用户有时会尝试声明只适用于某个域类型的操作符。这是可行的,但远没有看上去那样有用,因为操作符解析规则被设计成优先选择作用于域基类型的操作符。考虑下面的例子: +用户有时会尝试声明只适用于某个域类型的操作符。这是可行的,但远没有看上去那样有用,因为操作符解析规则被设计成优先选择作用于域基础类型的操作符。考虑下面的例子: CREATE DOMAIN mytext AS text CHECK(...); CREATE FUNCTION mytext_eq_text (mytext, text) RETURNS boolean AS ...; @@ -379,11 +379,11 @@ CREATE TABLE mytable (val mytext); SELECT * FROM mytable WHERE val = 'foo'; -这个查询不会使用自定义操作符。解析器首先会检查是否存在mytext = mytext操作符(),但并不存在;然后它会考虑该域的基类型text,并检查是否存在text = text操作符(),而这是存在的;于是它会把unknown类型的文字解析为text,并使用text = text操作符。要让自定义操作符被使用,唯一的方法是显式地对该文字做类型转换: +这个查询不会使用自定义操作符。解析器首先会检查是否存在mytext = mytext操作符(),但并不存在;然后它会考虑该域的基础类型text,并检查是否存在text = text操作符(),而这是存在的;于是它会把unknown类型的字面量解析为text,并使用text = text操作符。要让自定义操作符被使用,唯一的方法是显式地对该字面量做类型转换: SELECT * FROM mytable WHERE val = text 'foo'; -这样就会根据精确匹配规则立即找到mytext = text操作符。如果解析过程进入最佳匹配规则,它们会主动排斥作用于域类型的操作符。如果不是这样,这类操作符会导致过多的操作符歧义失败,因为类型转换规则总是把域视为可以转换到其基类型或从其基类型转换而来,因此域操作符会在所有与基类型上同名操作符相同的场景中都被视为可用。 +这样就会根据精确匹配规则立即找到mytext = text操作符。如果解析过程进入最佳匹配规则,它们会主动排斥作用于域类型的操作符。如果不是这样,这类操作符会导致过多的操作符歧义失败,因为类型转换规则总是把域视为可以转换到其基础类型或从其基础类型转换而来,因此域操作符会在所有与基础类型上同名操作符相同的场景中都被视为可用。 @@ -422,27 +422,27 @@ SELECT * FROM mytable WHERE val = text 'foo'; -如果函数声明了一个VARIADIC数组参数,而调用时没有使用VARIADIC关键字,则把该函数视为其数组参数按需要被其元素类型的一个或多个出现所替换,以匹配该调用。扩展之后,该函数的有效参数类型可能与某个非VARIADIC函数完全相同。在这种情况下,使用搜索路径中较早出现的函数;如果两个函数位于同一模式,则优先选择非VARIADIC函数。 +如果函数声明了一个VARIADIC数组参数,而调用时没有使用VARIADIC关键字,则把数组参数视为一个或多个其元素类型的参数,个数按匹配该调用的需要确定。扩展之后,该函数的有效参数类型可能与某个非VARIADIC函数完全相同。在这种情况下,使用搜索路径中较早出现的函数;如果两个函数位于同一模式,则优先选择非VARIADIC函数。 -通过限定名调用某个允许不可信用户创建对象的模式中找到的可变参数函数时,会带来安全隐患 +通过限定名调用某个允许不受信任的用户创建对象的模式中找到的可变参数函数时,会带来安全隐患 - 对于未带模式限定的名称,不会出现这种隐患,因为包含允许不可信用户创建对象的模式的搜索路径不是一种模式的安全使用方式。 + 对于未带模式限定的名称,不会出现这种隐患,因为包含允许不受信任的用户创建对象的模式的搜索路径不是一种模式的安全使用方式。 - 。恶意用户可以借此劫持调用,并以你的身份执行任意 SQL 函数。改为使用带有VARIADIC关键字的调用可以绕过这一隐患。对于填充VARIADIC "any"参数的调用,往往没有包含VARIADIC关键字的等价写法。要安全地发出这类调用,该函数所在模式必须只允许可信用户创建对象。 + 。恶意用户可以借此劫持调用,并以你的身份执行任意 SQL 函数。改为使用带有VARIADIC关键字的调用可以绕过这一隐患。对于填充VARIADIC "any"参数的调用,往往没有包含VARIADIC关键字的等价写法。要安全地发出这类调用,该函数所在模式必须只允许受信任的用户创建对象。 -带有参数默认值的函数,被认为可以匹配任何省略了零个或多个可默认参数位置的调用。如果不止一个这样的函数能匹配某个调用,则使用搜索路径中最早出现的那一个。如果同一模式中存在两个或更多这样的函数,并且它们在未使用默认值的参数位置上的参数类型相同(如果它们具有不同的可默认参数集合,这种情况是可能的),系统就无法判断该偏好哪一个;如果找不到更好的匹配,就会报有歧义的函数调用错误。 +带有参数默认值的函数,被认为可以匹配任何省略了零个或多个可使用默认值的参数位置的调用。如果不止一个这样的函数能匹配某个调用,则使用搜索路径中最早出现的那一个。如果同一模式中存在两个或更多这样的函数,并且它们在未使用默认值的参数位置上的参数类型相同(如果它们具有不同的带有默认值的参数集合,这种情况是可能的),系统就无法判断该偏好哪一个;如果找不到更好的匹配,就会报有歧义的函数调用错误。 -通过限定名调用某个允许不可信用户创建对象的模式中的任意函数时,会带来可用性隐患。恶意用户可以用现有函数的名字创建一个新函数,复制该函数的参数,并附加带有默认值的新参数。这样就会阻止对原始函数的新调用。为避免这种隐患,应把函数放在只允许可信用户创建对象的模式中。 +通过限定名调用某个允许不受信任的用户创建对象的模式中的任意函数时,会带来可用性隐患。恶意用户可以用现有函数的名字创建一个新函数,复制该函数的参数,并附加带有默认值的新参数。这样就会阻止对原始函数的新调用。为避免这种隐患,应把函数放在只允许受信任的用户创建对象的模式中。 @@ -451,14 +451,14 @@ SELECT * FROM mytable WHERE val = text 'foo'; -检查是否存在一个恰好接受输入参数类型的函数。如果存在(在被考虑的函数集合中至多只有一个精确匹配),就使用它。若通过限定名调用某个允许不可信用户创建对象的模式中的函数,而又缺少精确匹配,就会带来安全隐患。在这种情况下,应通过对参数进行类型转换来强制获得精确匹配。(涉及unknown的情况在这一步永远找不到匹配。) +检查是否存在一个恰好接受输入参数类型的函数。如果存在(在被考虑的函数集合中至多只有一个精确匹配),就使用它。若通过限定名调用某个允许不受信任的用户创建对象的模式中的函数,而又缺少精确匹配,就会带来安全隐患。在这种情况下,应通过对参数进行类型转换来强制获得精确匹配。(涉及unknown的情况在这一步永远找不到匹配。) -如果没有找到精确匹配,就检查该函数调用是否看起来像一种特殊的类型转换请求。这种情况发生在:函数调用只有一个参数,且函数名与某个数据类型的(内部)名称相同。此外,函数参数必须是unknown类型文字,或者是一种能够进行二进制强制转换到该命名数据类型的类型,或者是一种可以通过应用其 I/O 函数转换为该命名数据类型的类型(也就是说,该转换要么转到某种标准字符串类型,要么从某种标准字符串类型转来)。满足这些条件时,该函数调用会被当作一种CAST形式。 +如果没有找到精确匹配,就检查该函数调用是否看起来像一种特殊的类型转换请求。这种情况发生在:函数调用只有一个参数,且函数名与某个数据类型的(内部)名称相同。此外,函数参数必须是unknown类型字面量,或者是一种可以二进制强制转换为该命名数据类型的类型,或者是一种可以通过应用其 I/O 函数转换为该命名数据类型的类型(也就是说,该转换要么转到某种标准字符串类型,要么从某种标准字符串类型转来)。满足这些条件时,该函数调用会被当作一种CAST形式。 之所以有这一步,是为了在不存在实际类型转换函数的情况下仍支持函数风格的类型转换写法。如果存在类型转换函数,按惯例它会以其输出类型命名,因此无需为此设置特殊情况。更多说明见。 @@ -475,13 +475,13 @@ SELECT * FROM mytable WHERE val = text 'foo'; -丢弃那些输入类型不匹配,且也无法通过隐式类型转换实现匹配的候选函数。为此,假定unknown文字可以转换为任何类型。如果只剩一个候选函数,就使用它;否则继续下一步。 +丢弃那些输入类型不匹配,且也无法通过隐式类型转换实现匹配的候选函数。为此,假定unknown字面量可以转换为任何类型。如果只剩一个候选函数,就使用它;否则继续下一步。 -如果任何输入参数是域类型,则在后续所有步骤中都把它当作该域的基类型。这样可以确保在解决函数歧义时,域的行为与其基类型一致。 +如果任何输入参数是域类型,则在后续所有步骤中都把它当作该域的基础类型。这样可以确保在解决函数歧义时,域的行为与其基础类型一致。 @@ -493,13 +493,13 @@ SELECT * FROM mytable WHERE val = text 'foo'; -遍历所有候选函数,保留那些在需要类型转换的最多位置上接受首选类型(属于输入数据类型的类型分类)的候选项。如果没有候选项接受首选类型,则保留全部候选项。如果只剩一个候选函数,就使用它;否则继续下一步。 +遍历所有候选函数,在需要类型转换的位置上,保留接受首选类型(属于输入数据类型的类型分类)的位置数最多的候选项。如果没有候选项接受首选类型,则保留全部候选项。如果只剩一个候选函数,就使用它;否则继续下一步。 -如果有任何输入参数是unknown,就检查剩余候选函数在这些参数位置上接受哪些类型分类。在每个位置上,如果有任何候选项接受string分类,就选择该分类。(这种偏向字符串的做法是合适的,因为unknown类型的文字看起来像字符串。)否则,如果所有剩余候选项都接受同一种类型分类,就选择该分类;否则失败,因为在缺少更多线索的情况下无法推断出正确选择。然后丢弃不接受所选类型分类的候选项。此外,如果有任何候选项接受该分类中的首选类型,就丢弃在该参数上接受非首选类型的候选项。如果没有候选项通过这些测试,则保留全部候选项。如果只剩一个候选函数,就使用它;否则继续下一步。 +如果有任何输入参数是unknown,就检查剩余候选函数在这些参数位置上接受哪些类型分类。在每个位置上,如果有任何候选项接受string分类,就选择该分类。(这种偏向字符串的做法是合适的,因为unknown类型的字面量看起来像字符串。)否则,如果所有剩余候选项都接受同一种类型分类,就选择该分类;否则失败,因为在缺少更多线索的情况下无法推断出正确选择。然后丢弃不接受所选类型分类的候选项。此外,如果有任何候选项接受该分类中的首选类型,就丢弃在该参数上接受非首选类型的候选项。如果没有候选项通过这些测试,则保留全部候选项。如果只剩一个候选函数,就使用它;否则继续下一步。 @@ -680,7 +680,7 @@ SELECT substr(CAST (1234 AS text), 3); -否则,尝试把表达式转换为目标类型。如果这两种类型之间在pg_cast目录中登记了赋值类型转换(见),就可以这样做。另一种情况是,如果表达式是unknown类型文字,则会把文字字符串的内容送入目标类型的输入转换例程。 +否则,尝试把表达式转换为目标类型。如果这两种类型之间在pg_cast目录中登记了赋值类型转换(见),就可以这样做。另一种情况是,如果表达式是unknown类型字面量,则会把字符串字面量的内容送入目标类型的输入转换例程。 @@ -713,7 +713,7 @@ SELECT v, octet_length(v) FROM vv; -这里实际发生的是,两个unknown类型文字默认都被解析为text,从而使||操作符被解析为text的连接操作。然后,操作符得到的text结果被转换为bpcharblank-padded char,即character数据类型的内部名称),以匹配目标列类型。(由于从textbpchar的转换是二进制可强制转换的,这一步不会插入任何真实的函数调用。)最后,系统目录中找到尺寸调整函数bpchar(bpchar, integer, boolean),并把它应用到操作符结果以及存储列长度上。这个特定于类型的函数会执行所需的长度检查并补齐填充空格。 +这里实际发生的是,两个unknown类型字面量默认都被解析为text,从而使||操作符被解析为text的连接操作。然后,操作符得到的text结果被转换为bpchar用空格填充的字符,blank-padded char,即character数据类型的内部名称),以匹配目标列类型。(由于从textbpchar的转换是二进制可强制转换的,这一步不会插入任何真实的函数调用。)最后,系统从系统目录中找到尺寸调整函数bpchar(bpchar, integer, boolean),并把它应用到操作符结果以及存储列长度上。这个特定于类型的函数会执行所需的长度检查并补齐填充空格。 @@ -770,10 +770,10 @@ SQL 的UNION结构必须让可能不同的类型彼此匹配 -如果任何输入是域类型,则在后续所有步骤中都把它当作该域的基类型。 +如果任何输入是域类型,则在后续所有步骤中都把它当作该域的基础类型。 - 这在某种程度上类似于操作符和函数对域输入的处理方式;只要用户确保所有输入都隐式或显式地正好属于该域类型,这种行为就能让域类型在UNION或类似结构中得以保留。否则,就会使用该域的基类型。 + 这在某种程度上类似于操作符和函数对域输入的处理方式;只要用户确保所有输入都隐式或显式地正好属于该域类型,这种行为就能让域类型在UNION或类似结构中得以保留。否则,就会使用该域的基础类型。 @@ -832,7 +832,7 @@ SELECT text 'a' AS "text" UNION SELECT 'b'; b (2 rows) -这里,unknown类型文字'b'会被解析为text类型。 +这里,unknown类型字面量'b'会被解析为text类型。 @@ -850,7 +850,7 @@ SELECT 1.2 AS "numeric" UNION SELECT 1; 1.2 (2 rows) -文字常量1.2的类型是numeric,而integer1可以隐式转换为numeric,因此使用该类型。 +字面量1.2的类型是numeric,而integer1可以隐式转换为numeric,因此使用该类型。 @@ -905,17 +905,17 @@ ERROR: UNION types text and integer cannot be matched -前面各节给出的规则会为 SQL 查询中的所有表达式分配非unknown的数据类型,唯一的例外是作为SELECT命令简单输出列出现的未指定类型文字常量。例如,在 +前面各节给出的规则会为 SQL 查询中的所有表达式分配非unknown的数据类型,唯一的例外是作为SELECT命令简单输出列出现的未指定类型字面量。例如,在 SELECT 'Hello World'; -中,没有任何信息能够表明这个字符串文字应该视为哪种类型。在这种情况下,PostgreSQL会退回到把该文字解析为text类型。 +中,没有任何信息能够表明这个字符串字面量应该视为哪种类型。在这种情况下,PostgreSQL会退回到把该字面量解析为text类型。 -当SELECTUNION(或INTERSECTEXCEPT)结构的一端,或者出现在INSERT ... SELECT中时,这条规则不适用,因为前面各节给出的规则具有更高优先级。在前一种情况下,未指定类型文字的类型可以从UNION的另一侧取得;在后一种情况下,则从目标列取得。 +当SELECTUNION(或INTERSECTEXCEPT)结构的一端,或者出现在INSERT ... SELECT中时,这条规则不适用,因为前面各节给出的规则具有更高优先级。在前一种情况下,未指定类型字面量的类型可以从UNION的另一侧取得;在后一种情况下,则从目标列取得。 @@ -925,7 +925,7 @@ SELECT 'Hello World'; - 在PostgreSQL 10 之前,这条规则并不存在,SELECT输出列表中的未指定类型文字会被保留为unknown类型。这会带来各种不良后果,因此后来做了修改。 + 在PostgreSQL 10 之前,这条规则并不存在,SELECT输出列表中的未指定类型字面量会被保留为unknown类型。这会带来各种不良后果,因此后来做了修改。 diff --git a/zh/16/user-manag.sgml b/zh/16/user-manag.sgml index 8aca4397..59fbd18e 100644 --- a/zh/16/user-manag.sgml +++ b/zh/16/user-manag.sgml @@ -312,12 +312,12 @@ ALTER TABLE bobs_table OWNER TO alice; - 一旦有价值的对象都已转移给新拥有者,被删除角色所拥有的其余对象即可使用DROP OWNED命令删除。同样,由于该命令不能访问其他数据库中的对象,因此必须在包含该角色所拥有对象的每个数据库中运行它。另外,DROP + 一旦有价值的对象都已转移给新拥有者,待删除角色所拥有的其余对象即可使用DROP OWNED命令删除。同样,由于该命令不能访问其他数据库中的对象,因此必须在包含该角色所拥有对象的每个数据库中运行它。另外,DROP OWNED不会删除整个数据库或表空间,因此如果该角色拥有任何尚未转移给新拥有者的数据库或表空间,就必须手工删除它们。 - DROP OWNED还会负责移除授予目标角色、但不属于它自身对象的任何权限。由于REASSIGN OWNED不会处理这类对象,所以通常需要同时运行REASSIGN OWNEDDROP OWNED(按这个顺序!),才能完整移除待删除角色的依赖关系。 + DROP OWNED还会负责移除目标角色在其他角色所拥有的对象上获授的所有权限。由于REASSIGN OWNED不会处理这类对象,所以通常需要同时运行REASSIGN OWNEDDROP OWNED(按这个顺序!),才能完整移除待删除角色的依赖关系。 @@ -347,157 +347,120 @@ DROP ROLE doomed_role; - PostgreSQL提供了一组预定义角色,它们提供对某些常见且需要权限的能力和信息的访问。管理员(包括具有CREATEROLE权限的角色)可以把这些角色GRANT给其环境中的用户和/或其他角色,从而让这些用户获得所指定的能力和信息。例如: + PostgreSQL提供了一组预定义角色,它们提供对某些常见且需要权限的能力和信息的访问。管理员(包括具有CREATEROLE权限的角色)可以把这些角色GRANT给其环境中的用户和/或其他角色,从而让这些用户获得所指定的能力和信息。 + + + + 预定义角色在中描述。请注意,随着将来增加更多能力,各个角色的具体权限可能会发生变化。管理员应关注发行说明中的变更。 + + + + 预定义角色 + + + + + + 角色 + 允许的访问 + + + + + pg_read_all_data + 读取所有数据(表、视图、序列),其效果就像对这些对象拥有SELECT权限并对所有模式拥有 USAGE 权限一样,即使没有被显式授予。该角色没有设置角色属性BYPASSRLS。如果正在使用 RLS,管理员可能希望对被 GRANT 此角色的角色设置BYPASSRLS + + + pg_write_all_data + 写入所有数据(表、视图、序列),其效果就像对这些对象拥有INSERTUPDATEDELETE权限并对所有模式拥有 USAGE 权限一样,即使没有被显式授予。该角色没有设置角色属性BYPASSRLS。如果正在使用 RLS,管理员可能希望对被 GRANT 此角色的角色设置BYPASSRLS + + + pg_read_all_settings + 读取所有配置变量,即使是那些通常仅对超级用户可见的变量。 + + + pg_read_all_stats + 读取所有 pg_stat_* 视图,并使用各种与统计信息相关的扩展,包括通常仅对超级用户可见的内容。 + + + pg_stat_scan_tables + 执行可能在表上持有ACCESS SHARE锁并且持续较长时间的监控函数。 + + + pg_monitor + 读取或执行各种监控视图和函数。该角色是pg_read_all_settingspg_read_all_statspg_stat_scan_tables的成员。 + + + pg_database_owner + 无。其成员隐式地由当前数据库拥有者组成。 + + + pg_signal_backend + 向另一个后端发送信号,以取消查询或终止其会话。 + + + pg_read_server_files + 允许使用COPY和其他文件访问函数,从服务器上数据库可访问的任何位置读取文件。 + + + pg_write_server_files + 允许使用COPY和其他文件访问函数,向服务器上数据库可访问的任何位置写入文件。 + + + pg_execute_server_program + 允许使用COPY和其他允许执行服务器端程序的函数,以数据库运行所用用户的身份在数据库服务器上执行程序。 + + + pg_checkpoint + 允许执行CHECKPOINT命令。 + + + pg_use_reserved_connections + 允许使用通过保留的连接槽。 + + + pg_create_subscription + 允许在数据库上具有CREATE权限的用户执行CREATE SUBSCRIPTION + + + +
+ + + pg_monitorpg_read_all_settingspg_read_all_statspg_stat_scan_tables角色旨在让管理员能够方便地为监控数据库服务器配置一个角色。它们授予一组常见权限,使该角色能够读取各种有用的配置设置、统计信息以及其他通常仅限超级用户查看的系统信息。 + + + + pg_database_owner角色有一个隐式的、取决于具体情况的成员,即当前数据库的拥有者。像任何角色一样,它可以拥有对象或获得访问权限授权。因此,一旦pg_database_owner在模板数据库中拥有权限,由该模板实例化的每个数据库的拥有者都将行使这些权限。pg_database_owner不能成为任何角色的成员,也不能拥有非隐式成员。最初,这个角色拥有public模式,因此每个数据库拥有者都管理该模式在本数据库中的使用。 + + + + pg_signal_backend角色旨在让管理员能够允许受信任但非超级用户的角色向其他后端发送信号。目前这个角色允许发送信号来取消另一个后端上的查询或终止其会话。不过,被授予此角色的用户不能向由超级用户拥有的后端发送信号。见。 + + + + pg_read_server_filespg_write_server_filespg_execute_server_program角色旨在让管理员能够使受信任但非超级用户的角色能够以数据库运行所用用户的身份访问文件并在数据库服务器上运行程序。由于这些角色能够访问服务器文件系统上的任意文件,它们在直接访问文件时会绕过所有数据库级权限检查,并且可被用来获得超级用户级别的访问能力,因此向用户授予这些角色时必须极其谨慎。 + + + + 授予这些角色时应当谨慎,确保它们只在需要时使用,并理解这些角色会授予对需要特权才能访问的信息的访问。 + + + + 管理员可以使用GRANT命令把这些角色的访问授予用户,例如: GRANT pg_signal_backend TO admin_user; - - - 授予这些角色时应当谨慎,确保它们只在需要时使用,并理解这些角色会授予对敏感信息的访问。 - - - - - 下文介绍这些预定义角色。请注意,随着将来增加更多能力,各个角色的具体权限可能会发生变化。管理员应关注发行说明中的变更。 - - - - pg_checkpoint - - - pg_checkpoint允许执行CHECKPOINT命令。 - - - - - - pg_create_subscription - - - pg_create_subscription允许在数据库上具有CREATE权限的用户执行CREATE SUBSCRIPTION。 - - - - - - pg_database_owner - - - pg_database_owner始终恰好有一个隐式成员:当前数据库的拥有者。它不能被授予任何角色中的成员资格,也不能有任何角色被授予pg_database_owner中的成员资格。不过,和其他角色一样,它可以拥有对象并获得访问权限授权。因此,一旦pg_database_owner在某个模板数据库中拥有权限,由该模板实例化的每个数据库的拥有者都将拥有这些权限。最初,这个角色拥有public模式,因此每个数据库拥有者都管理该模式在本数据库中的使用。 - - - - - - pg_maintain - - - pg_maintain允许在所有关系上执行VACUUM、 - ANALYZE、 - CLUSTER、 - REFRESH MATERIALIZED VIEW、 - REINDEX - 以及LOCK TABLE,其效果就像对这些对象拥有MAINTAIN权限一样。 - - - - - - pg_monitor - pg_read_all_settings - pg_read_all_stats - pg_stat_scan_tables - - - 这些角色旨在让管理员能够方便地为监控数据库服务器配置一个角色。它们授予一组常见权限,使该角色能够读取各种有用的配置设置、统计信息以及其他通常仅限超级用户查看的系统信息。 - - - pg_monitor允许读取或执行各种监控视图和函数。该角色是pg_read_all_settingspg_read_all_statspg_stat_scan_tables的成员。 - - - pg_read_all_settings允许读取所有配置变量,即使是那些通常仅对超级用户可见的变量。 - - - pg_read_all_stats允许读取所有 pg_stat_* 视图,并使用各种与统计信息相关的扩展,即使是那些通常仅对超级用户可见的扩展。 - - - pg_stat_scan_tables允许执行可能在表上持有ACCESS SHARE锁并持续较长时间的监控函数(例如pgrowlocks(text),见扩展)。 - - - - - - pg_read_all_data - pg_write_all_data - - - pg_read_all_data允许读取所有数据(表、视图、序列),其效果就像对这些对象拥有SELECT权限并对所有模式拥有USAGE权限一样。该角色不会绕过行级安全(RLS)策略。如果正在使用 RLS,管理员可能希望对被授予此角色的角色设置BYPASSRLS。 - - - pg_write_all_data允许写入所有数据(表、视图、序列),其效果就像对这些对象拥有INSERTUPDATEDELETE权限并对所有模式拥有USAGE权限一样。该角色不会绕过行级安全(RLS)策略。如果正在使用 RLS,管理员可能希望对被授予此角色的角色设置BYPASSRLS。 - - - - - - pg_read_server_files - pg_write_server_files - pg_execute_server_program - - - 这些角色旨在允许管理员创建受信任但非超级用户的角色,使其能够以数据库运行所用操作系统用户的身份访问文件并在数据库服务器上运行程序。它们在直接访问文件时会绕过所有数据库级权限检查,并且可被用来获得超级用户级别的访问能力。因此,向用户授予这些角色时必须极其谨慎。 - - - pg_read_server_files允许使用COPY和其他文件访问函数,从服务器上数据库可访问的任何位置读取文件。 - - - pg_write_server_files允许使用COPY和其他文件访问函数,向服务器上数据库可访问的任何位置写入文件。 - - - pg_execute_server_program允许使用COPY和其他允许执行服务器端程序的函数,以数据库运行所用用户的身份在数据库服务器上执行程序。 - - - - - - pg_signal_autovacuum_worker - - - pg_signal_autovacuum_worker允许向自动清理工作进程发送信号,以取消当前表的清理操作或终止其会话。见。 - - - - - - pg_signal_backend - - - pg_signal_backend允许向另一个后端发送信号,以取消查询或终止其会话。注意,这个角色不允许向由超级用户拥有的后端发送信号。见。 - - - - - - pg_use_reserved_connections - - - pg_use_reserved_connections允许使用通过保留的连接槽。 - - - - - - 函数安全性 - 函数、触发器和行级安全策略允许用户把代码插入后端服务器,而其他用户可能会无意中执行这些代码。因此,这些机制使用户能够相对容易地对其他用户实施特洛伊木马攻击。最强的保护方式是严格控制谁能定义对象。如果这不可行,则应编写只引用拥有者可信对象的查询,并从search_path中移除任何允许不受信任用户创建对象的模式。 + 函数、触发器和行级安全策略允许用户把代码插入后端服务器,而其他用户可能会无意中执行这些代码。因此,这些机制使用户能够相对容易地对其他用户实施特洛伊木马攻击。最强的保护方式是严格控制谁能定义对象。如果这不可行,则应编写只引用拥有者可信的对象的查询,并从search_path中移除任何允许不受信任用户创建对象的模式。 diff --git a/zh/16/vacuumlo.sgml b/zh/16/vacuumlo.sgml index 9e80b19f..cc2c04f5 100644 --- a/zh/16/vacuumlo.sgml +++ b/zh/16/vacuumlo.sgml @@ -8,7 +8,7 @@ vacuumlo 1 - Application + 应用程序 diff --git a/zh/16/wal.sgml b/zh/16/wal.sgml index 86585b8e..c718b70c 100644 --- a/zh/16/wal.sgml +++ b/zh/16/wal.sgml @@ -158,7 +158,8 @@ - 数据页默认带有校验和,而记录在 WAL 记录中的整页镜像始终受校验和保护。 + 数据页默认并不带校验和,不过,记录在 WAL 记录中的整页镜像始终受保护;有关启用数据校验和的细节,见 initdb @@ -198,14 +199,14 @@ - 默认情况下,数据页受校验和保护,但也可以选择为集簇禁用。启用后,每个数据页 + 默认情况下,数据页不受校验和保护,但可以选择为集簇启用。启用后,每个数据页 都包含一个校验和,在页面写入时更新,并在页面每次被读取时进行验证。只有数据 页受校验和保护;内部数据结构和临时文件不受保护。 可以在使用 initdb - 初始化集簇时禁用校验和。之后也可以作为离线操作启用或禁用。数据校验和是在整个 + 初始化集簇时启用校验和。之后也可以作为离线操作启用或禁用。数据校验和是在整个 集簇级别启用或禁用的,不能为单个数据库或表分别指定。 @@ -390,9 +391,9 @@ 检查点检查点 是事务序列中的一些点,在这些点上可以保证堆和索引数据文件已经用检查点之前写入 - 的全部信息进行了更新。执行检查点时,所有脏数据页都会刷写到磁盘,并向 WAL - 文件写入一条特殊的检查点记录。(更改记录此前已经刷入 WAL - 文件。)如果发生崩溃,崩溃恢复过程会查看最新的检查点记录,以确定应该从 WAL + 的全部信息进行了更新。执行检查点时,所有脏数据页都会刷盘,并向 WAL + 文件写入一条特殊的检查点记录。(更改记录此前已写入 WAL + 文件并刷盘。)如果发生崩溃,崩溃恢复过程会查看最新的检查点记录,以确定应该从 WAL 的哪个位置(称为重做记录)开始执行 REDO。该点之前对数据文件所做的任何更改 都保证已经在磁盘上。因此,检查点之后,位于包含重做记录的段之前的 WAL 段不再需要, 可以被回收或删除。(若正在执行 WAL 归档,则这些 WAL 段必 @@ -420,7 +421,7 @@ 减小 checkpoint_timeout 和/或 max_wal_size 会让检查点更频繁地发生。这样可以加快崩溃后 - 恢复,因为需要重做的工作更少。不过,这必须与更频繁刷写脏数据页所增加的成本 + 恢复,因为需要重做的工作更少。不过,这必须与更频繁地将脏数据页刷盘所增加的成本 权衡。如果设置了 (默认就是如此), 还要考虑另一个因素。为了保证数据页一致性,每个检查点之后对某个数据页的首次 修改,都会导致把整页内容写入日志。在这种情况下,更短的检查点间隔会增加输出到 @@ -447,7 +448,7 @@ I/O 速率,使检查点在给定比例的 checkpoint_timeout 秒数 经过时完成,或者在 max_wal_size 即将超出之前完成,以较早 者为准。使用默认值 0.9 时,可以预期 PostgreSQL - 会在下一次计划检查点开始前稍早完成每个检查点(大约在检查点间隔的 90% 时)。 + 会在下一次计划检查点开始前稍早完成每个检查点(耗时约为上一次检查点持续时间的 90%)。 这样能尽可能摊平 I/O,从而使检查点 I/O 负载在整个检查点间隔内保持稳定。这样 做的缺点是,延长检查点会影响恢复时间,因为需要保留更多 WAL 段以备恢复时 使用。关心恢复耗时的用户,可能希望减小 @@ -463,7 +464,7 @@ 在 Linux 和 POSIX 平台上, - 允许在检查点写出的操作系统页面达到可配置的字节数后,强制把它们刷到磁盘。 + 允许在检查点写出的操作系统页面达到可配置的字节数后,强制将它们刷盘。 否则,这些页面可能会停留在操作系统页缓存中,从而在检查点末尾发出 fsync 时引发停顿。这个设置通常有助于降低事务延迟,但也可能 对性能产生不利影响,尤其是在工作负载大于 @@ -499,18 +500,16 @@ 在归档恢复或备库模式下,服务器会周期性地执行 重启点重启点, - 其行为类似于正常运行时的检查点:服务器会强制把自身状态写盘,更新 - pg_control 文件,以表明已经处理过的 WAL 数据无需再次扫描, - 然后回收 pg_wal 目录中的旧 WAL 段文件。 - 重启点不会比主库上的检查点更频繁,因为重启点只能在检查点记录处执行。 - 当到达某条检查点记录时,如果距上一次重启点至少已经过去 - 秒,或者 WAL 大小即将超过 - ,就会触发一次重启点。 - 不过,由于重启点只能在特定时机执行,恢复期间 max_wal_size - 经常会被超过,最多可能超出一个检查点周期对应的 WAL 量。 - (无论如何,max_wal_size 从来都不是硬上限,因此你始终应留出 - 充足余量,以免耗尽磁盘空间。) - + 其行为类似于正常运行时的检查点:服务器会强制将其所有状态刷盘,更新 + pg_control 文件,以表明已经处理过的 WAL 数据无需再次 + 扫描,然后回收 pg_wal 目录中的旧 WAL 段文件。重启点的 + 执行频率不会高于主库上的检查点,因为重启点只能在检查点记录处执行。当到达某条检查点记录且距离上次重启点 + 至少已经过去 checkpoint_timeout 秒,或者 WAL 大小即将超过 + max_wal_size 时,就会触发重启点。不过,由于重启点的可执行时机受到 + 限制,恢复期间经常会超出 max_wal_size,最多可能超出一个 + 检查点周期对应的 WAL 量。(无论如何,max_wal_size 从来 + 都不是硬上限,因此你始终应留出充足余量,以免耗尽磁盘空间。) + 有两个常用的内部 WAL 函数: @@ -524,7 +523,7 @@ 快。更糟的是,写 WAL 缓冲区还可能迫使系统创建新的 WAL 段, 这会花费更多时间。正常情况下,WAL 缓冲区应由 XLogFlush 请求负责写出并刷盘; - 该请求大多发生在事务提交时,以确保事务记录被刷入持久存储。在 WAL 输出量很高 + 该请求大多发生在事务提交时,以确保事务记录已刷盘至持久存储。在 WAL 输出量很高 的系统上,XLogFlush 请求可能不够频繁,无法避免 XLogInsertRecord 自己去执行写出。在这种系统上,应增加 WAL 缓冲区的数量,具体做法是修改参数 @@ -537,7 +536,7 @@ 参数 定义了组提交的领导者进程在 XLogFlush 内部获取锁之后会睡眠多少微秒,在此期间,组提 交的追随者会排队跟在领导者后面。这一延迟允许其他服务器进程把自己的提交记录添 - 加到 WAL 缓冲区中,以便它们都能由领导者最终执行的同步操作一并刷出。如果没有 + 加到 WAL 缓冲区中,以便它们都能由领导者最终执行的同步操作一并刷盘。如果没有 启用 ,或者当前处于活跃事务中的其他会话少于 个,就不会发生睡眠;这样可以避免在其他 会话不太可能很快提交时还去睡眠。请注意,在某些平台上,休眠请求的分辨率是 @@ -566,8 +565,7 @@ commit_delay 设为 0(默认值)时,仍然可能出现一种组 - 提交,但每个组只会包含那些恰好在前一次刷盘操作(若有)进行期间,到达“需要刷 - 出其提交记录”这一点的会话。客户端数量更高时,往往会出现一种 + 提交,但每个组只会包含那些恰好在前一次刷盘操作(若有)进行期间,到达“需要将其提交记录刷盘”这一点的会话。客户端数量更高时,往往会出现一种 gangway effect,以至于即使 commit_delay 为 0,组提交的效果也会变得很显著,因此显式设置 commit_delay 的帮助反而会变小。只有在以下两种条件同时 @@ -580,9 +578,9 @@ 参数 决定 PostgreSQL 将如何请求内核把 - WAL 更新强制刷到磁盘。就可靠性而言,所有选项应当都是相同 + WAL 更新强制刷盘。就可靠性而言,所有选项应当都是相同 的;例外是 fsync_writethrough,它有时能够在其他选项做不 - 到时强制刷新磁盘缓存。不过,具体哪个选项速度最快则高度依赖平台。可以使用 + 到时强制将磁盘缓存中的数据刷盘。不过,具体哪个选项速度最快则高度依赖平台。可以使用 程序测试不同选项的速度。请注意,如果 fsync 已被关闭,那么这个参数就没有意义。 @@ -596,14 +594,13 @@ - 有两个内部函数负责把 WAL 数据写入磁盘: - XLogWriteissue_xlog_fsync。 - 启用 后, - XLogWrite 写 WAL 数据以及 - issue_xlog_fsync 将 WAL 数据同步到磁盘所花费的总时间, - 会分别统计为 write_timefsync_time, - 记录在 中 - objectwal 的项下。 + 有两个内部函数负责把 WAL 数据写入磁盘: + XLogWriteissue_xlog_fsync。 + 启用 后, + XLogWrite 写 WAL 数据以及 + issue_xlog_fsync 将 WAL 数据同步到磁盘所花费的总时间, + 会分别统计为 wal_write_timewal_sync_time, + 并分别记录在 中。 XLogWrite 通常由 XLogInsertRecord (当 WAL 缓冲区没有空间容纳新记录时)、XLogFlush 以及 WAL 写入器调用,用于把 WAL 缓冲区写到磁盘并调用 @@ -615,15 +612,14 @@ issue_xlog_fsync 什么也不做。如果 wal_sync_methodfdatasyncfsyncfsync_writethrough, - 那么写操作会把 WAL 缓冲区移入内核缓存,而 - issue_xlog_fsync 会把它们同步到磁盘。无论 - track_wal_io_timing 是否开启, - XLogWrite 写 WAL 数据的次数和 - issue_xlog_fsync 同步 WAL 数据到磁盘的次数,也会分别统计 - 为 writesfsyncs,记录在 - pg_stat_ioobject 为 - wal 的项下。 - + 那么写操作会把 WAL 缓冲区移入内核缓存,而 + issue_xlog_fsync 会把它们同步到磁盘。无论 + track_wal_io_timing 是否开启, + XLogWrite 写 WAL 数据的次数和 + issue_xlog_fsync 同步 WAL 数据到磁盘的次数,也会分别统计 + 为 wal_writewal_sync,分别记录在 + pg_stat_wal 中。 + 参数 可用于在恢复期间降低 I/O 等待 @@ -631,7 +627,7 @@ PostgreSQL 缓冲池中的磁盘块发起读取。 分别限制预取的并发度和距离。 - 默认值是 try,这会在支持发出预读建议的系统上启用该特性。 + 默认值是 try,这会在posix_fadvise 可用的系统上启用该特性。 diff --git a/zh/16/xaggr.sgml b/zh/16/xaggr.sgml index b46b119e..d7ef45aa 100644 --- a/zh/16/xaggr.sgml +++ b/zh/16/xaggr.sgml @@ -43,11 +43,11 @@ SELECT sum(a) FROM test_complex;
- 如果没有非空输入值,上述sum定义将返回零(即初始状态值)。也许我们更希望在这种情况下返回空值 — SQL 标准要求sum这样做。实现这一点只需省略initcond短语,使初始状态值为空。通常这意味着sfunc需要检查输入的状态值是否为空。但对于sum以及maxmin这类其他简单聚合,只需把第一个非空输入值放入状态变量,然后从第二个非空输入值开始应用转移函数即可。如果初始状态值为空,并且转移函数被标记为strict(即不会对空输入调用),PostgreSQL会自动这样做。 + 如果没有非空输入值,上述sum定义将返回零(即初始状态值)。也许我们更希望在这种情况下返回空值 — SQL 标准要求sum这样做。实现这一点只需省略initcond短语,使初始状态值为空值。通常这意味着sfunc需要检查输入的状态值是否为空值。但对于sum以及maxmin这类其他简单聚合,只需把第一个非空输入值放入状态变量,然后从第二个非空输入值开始应用转移函数即可。如果初始状态值为空值,并且转移函数被标记为strict(即不会对空值输入调用),PostgreSQL会自动这样做。 - strict转移函数的另一项默认行为是,只要遇到空输入值,就会保留先前的状态值不变。因此,空值会被忽略。如果你需要对空输入采用其他行为,就不要把转移函数声明为 strict,而应在函数代码中自行检测空输入并完成所需处理。 + strict转移函数的另一项默认行为是,只要遇到空值输入,就会保留先前的状态值不变。因此,空值会被忽略。如果你需要对空值输入采用其他行为,就不要把转移函数声明为 strict,而应在函数代码中自行检测空值输入并完成所需处理。 @@ -72,7 +72,7 @@ CREATE AGGREGATE avg (float8) - SQL 中的聚合函数调用允许使用DISTINCTORDER BY选项,以控制哪些行会传递给聚合的转移函数,以及传递顺序。这些选项是在后台实现的,并不是聚合支持函数需要关心的事情。 + SQL 中的聚合函数调用允许使用DISTINCTORDER BY选项,以控制哪些行会传递给聚合的转移函数,以及传递顺序。这些选项由系统在内部实现,并不是聚合支持函数需要关心的事情。 @@ -292,7 +292,7 @@ SELECT percentile_disc(0.5) WITHIN GROUP (ORDER BY income) FROM households; - 与普通聚合不同,有序集聚合的输入行排序不是在幕后完成的,而是由聚合的支持函数负责。典型的实现方法是在聚合的状态值中保存一个tuplesort对象的引用,把输入行送入该对象,然后在最终函数中完成排序并读出数据。这样的设计使最终函数可以执行特殊操作,例如向待排序数据中注入额外的假想行。普通聚合通常可以使用由PL/pgSQL或其他 PL 语言编写的支持函数来实现,但有序集聚合通常必须用 C 编写,因为它们的状态值无法定义为任何 SQL 数据类型。(在上面的示例中,注意状态值被声明为internal类型,这很典型。)另外,由于最终函数执行了排序,之后就不可能再通过再次执行转移函数来继续加入输入行。这意味着最终函数不是READ_ONLY;在CREATE AGGREGATE中,必须将其声明为READ_WRITE,或者如果额外的最终函数调用能够利用已经排好序的状态,则声明为SHAREABLE。 + 与普通聚合不同,有序集聚合的输入行排序不是由系统在内部完成的,而是由聚合的支持函数负责。典型的实现方法是在聚合的状态值中保存一个tuplesort对象的引用,把输入行送入该对象,然后在最终函数中完成排序并读出数据。这样的设计使最终函数可以执行特殊操作,例如向待排序数据中注入额外的假想行。普通聚合通常可以使用由PL/pgSQL或其他 PL 语言编写的支持函数来实现,但有序集聚合通常必须用 C 编写,因为它们的状态值无法定义为任何 SQL 数据类型。(在上面的示例中,注意状态值被声明为internal类型,这很典型。)另外,由于最终函数执行了排序,之后就不可能再通过再次执行转移函数来继续加入输入行。这意味着最终函数不是READ_ONLY;在CREATE AGGREGATE中,必须将其声明为READ_WRITE,或者如果额外的最终函数调用能够利用已经排好序的状态,则声明为SHAREABLE @@ -366,7 +366,7 @@ if (AggCheckCallContext(fcinfo, NULL)) - AggCheckCallContext的第二个参数可用于取得保存聚合状态值的内存上下文。这对于希望把扩展对象(见)用作状态值的转移函数很有用。第一次调用时,转移函数应返回一个扩展对象,其内存上下文是聚合状态上下文的子上下文;之后的调用则持续返回同一个扩展对象。示例见array_append()。(array_append()并不是任何内置聚合的转移函数,但它的写法保证了在用作自定义聚合的转移函数时也能高效工作。) + AggCheckCallContext的第二个参数可用于取得保存聚合状态值的内存上下文。这对于希望把展开对象(见)用作状态值的转移函数很有用。第一次调用时,转移函数应返回一个展开对象,其内存上下文是聚合状态上下文的子上下文;之后的调用则持续返回同一个展开对象。示例见array_append()。(array_append()并不是任何内置聚合的转移函数,但它的写法保证了在用作自定义聚合的转移函数时也能高效工作。) diff --git a/zh/16/xfunc.sgml b/zh/16/xfunc.sgml index e917a737..ce3115d8 100644 --- a/zh/16/xfunc.sgml +++ b/zh/16/xfunc.sgml @@ -4,8 +4,8 @@ 用户定义的函数 - function - user-defined + 函数 + 用户定义的 @@ -36,15 +36,15 @@ - 每一类函数可以采用基本类型、复合类型或者它们的组合作为参数。此外,每一类函数可以返回一个基本类型或一个复合类型。函数也能被定义成返回基本类型或复合类型值的集合。 + 每一类函数可以采用基础类型、复合类型或者它们的组合作为参数。此外,每一类函数可以返回一个基础类型或一个复合类型。函数也能被定义成返回基础类型或复合类型值的集合。 - 很多类函数可以接受或者返回特定的伪类型(例如,多态类型),但是可用的功能会变化。详情可以参考每一种函数的描述。 + 很多类函数可以接受或者返回特定的伪类型(例如,多态类型),但是可用的功能因函数类别而异。详情可以参考每一种函数的描述。 - 定义SQL函数最容易,因此我们将从讨论SQL函数开始。大部分SQL函数的概念也能用到其他类型的函数上。 + 定义SQL函数最容易,因此我们将从讨论它们开始。大部分SQL函数的概念也能用到其他类型的函数上。 @@ -57,8 +57,8 @@ 用户定义的过程 - procedure - user-defined + 过程 + 用户定义的 @@ -101,7 +101,7 @@ - 函数和过程一起构成了例程routine。 + 函数和过程统称为例程例程。 有ALTER ROUTINEDROP ROUTINE这样的命令可以操作函数和过程而不需要知道它们是哪一种。 不过,要注意没有CREATE ROUTINE命令。 @@ -113,7 +113,7 @@ 函数 用户定义的 - in SQL + 在 SQL 中 @@ -124,13 +124,7 @@ 或者,一个 SQL 函数可以通过指定函数的返回类型为SETOF sometype被声明为返回一个集合(也就是多个行),或者等效地声明它为RETURNS TABLE(columns)。在这种情况下,最后一个查询的结果的所有行会被返回。下文将给出进一步的细节。 - - SQL 函数的函数体必须是一个由分号分隔的 SQL 语句列表。最后一条语句后的分号是可选的。除非该函数被声明为返回 - void,否则最后一条语句必须是 SELECT, - 或者是带有 RETURNING 子句的 INSERT、 - UPDATEDELETE 或 - MERGE。 - + SQL 函数的函数体必须是一个由分号分隔的 SQL 语句列表。最后一条语句后的分号是可选的。除非该函数被声明为返回 void,否则最后一条语句必须是 SELECT,或者是 INSERTUPDATEDELETE 并带有 RETURNING 子句。 任意一组 SQL 语言命令都可以打包并定义成函数。除 @@ -139,7 +133,7 @@ DELETEMERGE),以及其他 SQL 命令。(在 SQL 函数中不能使用事务控制命令,例如 COMMITSAVEPOINT,也不能使用某些 - 实用命令,例如 VACUUM。)不过,最后一条命令必须是 + 工具命令,例如 VACUUM。)不过,最后一条命令必须是 SELECT,或者带有 RETURNING 子句,并返回与函数声明返回类型相符的结果。或者,如果你想定义一个执行动作 但没有有用返回值的 SQL 函数,也可以把它定义为返回 void。 @@ -171,11 +165,23 @@ CREATE PROCEDURE clean_emp() AS ' CALL clean_emp(); - 在像这样的简单情况中,函数与过程返回void的差异主要是风格上面的。 + 在像这样的简单情况中,返回void的函数与过程之间的差异主要是风格上面的。 不过,过程还提供了函数所没有的额外能力,例如事务控制。 此外,过程是 SQL 标准的一部分,而返回void则是 PostgreSQL 扩展。 + + + 一个 SQL 函数的整个函数体在它的任何部分被执行前就已经被解析。 + 虽然 SQL 函数能包含修改系统目录的命令(例如CREATE TABLE), + 但在解析分析函数中后续命令时,这种命令的效果是不可见的。 + 因此,例如CREATE TABLE foo (...); INSERT INTO foo VALUES(...); + 如果被打包在一个单一的 SQL 函数中将不能按照预期工作, + 因为当INSERT命令被解析时foo还不存在。 + 在这类情况中建议使用PL/pgSQL代替 SQL 函数。 + + + CREATE FUNCTION 命令的语法要求把函数体写成一个字符串常量。对于字符串常量,通常使用美元引用最方便(见)。如果你选择使用常规的单引号字符串常量语法,那么必须在函数体中将单引号(')和反斜线(\)写成双份(假定使用转义字符串语法,见)。 @@ -226,10 +232,10 @@ INSERT INTO $1 VALUES (42); - 基本类型上的<acronym>SQL</acronym>函数 + 基础类型上的<acronym>SQL</acronym>函数 - 最简单的 SQL 函数没有参数,只是返回一个基本类型,例如 + 最简单的 SQL 函数没有参数,只是返回一个基础类型,例如 integer @@ -255,7 +261,7 @@ SELECT one(); - 定义接受基本类型参数的 SQL 函数也几乎同样容易: + 定义接受基础类型参数的 SQL 函数也几乎同样容易: CREATE FUNCTION add_em(x integer, y integer) RETURNS integer AS $$ @@ -393,17 +399,17 @@ SELECT name, double_salary(emp.*) AS dream 注意这里用 $1.salary 语法来选取参数行值中的一个字段。 还要注意,调用时的 SELECT 命令使用 - table_name.* 将表的当前整行取作一个组合值。该表行也可以仅用表名来引用: + table_name.* 将表的当前整行取作一个复合值。该表行也可以仅用表名来引用: SELECT name, double_salary(emp) AS dream FROM emp WHERE emp.cubicle ~= point '(2,1)'; - 但这种用法已被废弃,因为它很容易让人混淆(关于表行组合值这两种记法的更多细节,见)。 + 但这种用法已被弃用,因为它很容易让人混淆(关于表行复合值这两种记法的更多细节,见)。 - 有时候即时构造一个组合参数会很方便。这可以用ROW构造器完成。 + 有时候即时构造一个复合参数值会很方便。这可以用ROW构造器完成。 例如,我们可以调整被传递给函数的数据: SELECT name, double_salary(ROW(name, salary*1.1, age, cubicle)) AS dream @@ -432,7 +438,7 @@ $$ LANGUAGE SQL; - 查询中的选择列表顺序必须与列在复合类型中出现的顺序完全相同。(正如我们上面所做的那样,命名列与系统无关。) + 查询中的选择列表顺序必须与列在复合类型中出现的顺序完全相同。(系统不考虑像上面这样指定的列名。) @@ -444,7 +450,7 @@ ERROR: return type mismatch in function declared to return emp DETAIL: Final statement returns text instead of point at column 4. - 与基本类型的情况一样,系统不会自动插入显式转换,只会插入隐式或赋值转换。 + 与基础类型的情况一样,系统不会自动插入显式转换,只会插入隐式或赋值转换。 @@ -461,7 +467,7 @@ $$ LANGUAGE SQL; 这里我们写了一个只返回单列、且该列具有正确复合类型的 SELECT。 在这种场景下,这样写并不见得更好,但在某些情况下会很方便 - — 例如,需要通过调用另一个返回目标组合值的函数来计算结果时。 + — 例如,需要通过调用另一个返回目标复合值的函数来计算结果时。 还有一种情况是,如果我们要编写的函数返回的是基于复合类型的域,而不是普通复合类型, 那么就必须写成返回单列的形式,因为没有办法让整行结果发生所需的强制转换。 @@ -526,7 +532,7 @@ SELECT name(new_emp()); - 另一种使用函数返回复合类型的方法是将结果传递给另一个接受正确行类型作为输入的函数: + 另一种使用函数返回复合类型的方法是将结果传递给另一个接受正确行类型作为输入的函数: CREATE FUNCTION getname(emp) RETURNS text AS $$ @@ -614,7 +620,7 @@ DROP FUNCTION sum_n_product (int, int); <acronym>SQL</acronym>有输出参数的过程 - procedures + 过程 输出参数 @@ -636,7 +642,7 @@ $$ LANGUAGE SQL; CALL tp1(17, 100.0, NULL); 如果你写的是其他内容,它必须是一个能够像输入参数那样被隐式强制转换成该参数声明类型的表达式。 - 注意,无论如何这样的表达式不会被评估。 + 不过要注意,这样的表达式不会被求值。 @@ -648,12 +654,12 @@ CALL tp1(17, 100.0, NULL); 带有可变数量参数的<acronym>SQL</acronym>函数 - function - variadic + 函数 + 可变参数 - variadic function + 可变参数函数 @@ -684,27 +690,27 @@ SELECT mleast(ARRAY[10, -1, 5, 4.4]); -- doesn't work - 有时候,能够把一个已经构造好的数组传给 variadic 函数会很有用,尤其是当一个 variadic 函数想把它的数组参数再传给另一个函数时。此外,在允许不受信任用户创建对象的模式中调用 variadic 函数时,这是唯一安全的方式,见。你可以在调用中指定VARIADIC来做到这一点: + 有时候,能够把一个已经构造好的数组传给可变参数函数会很有用,尤其是当一个可变参数函数想把它的数组参数再传给另一个函数时。此外,在允许不受信任用户创建对象的模式中调用可变参数函数时,这是唯一安全的方式,见。你可以在调用中指定VARIADIC来做到这一点: SELECT mleast(VARIADIC ARRAY[10, -1, 5, 4.4]); - 这样会阻止函数的 variadic 参数按其元素类型展开,从而让数组实参能够按常规方式匹配。VARIADIC 只能附加在函数调用的最后一个实参上。 + 这样会阻止函数的可变参数按其元素类型展开,从而让数组实参能够按常规方式匹配。VARIADIC 只能附加在函数调用的最后一个实参上。 - 在调用中指定VARIADIC也是向 variadic 函数传递空数组的唯一方式,例如: + 在调用中指定VARIADIC也是向可变参数函数传递空数组的唯一方式,例如: SELECT mleast(VARIADIC ARRAY[]::numeric[]); - 仅仅写成SELECT mleast()是行不通的,因为 variadic 参数必须匹配至少一个实参。(如果你希望允许这种调用,可以再定义一个同名且不带参数的函数mleast。) + 仅仅写成SELECT mleast()是行不通的,因为可变参数必须匹配至少一个实参。(如果你希望允许这种调用,可以再定义一个同名且不带参数的函数mleast。) - 从 variadic 参数派生出的数组元素参数会被视为没有自己的名字。这意味着除非你指定了 VARIADIC,否则不能使用命名参数来调用 variadic 函数()。例如,下面的调用是可行的: + 从可变参数派生出的数组元素参数会被视为没有自己的名字。这意味着除非你指定了 VARIADIC,否则不能使用命名参数来调用可变参数函数()。例如,下面的调用是可行的: SELECT mleast(VARIADIC arr => ARRAY[10, -1, 5, 4.4]); @@ -723,7 +729,7 @@ SELECT mleast(arr => ARRAY[10, -1, 5, 4.4]); 带有参数默认值的<acronym>SQL</acronym>函数 - function + 函数 参数的默认值 @@ -732,7 +738,7 @@ SELECT mleast(arr => ARRAY[10, -1, 5, 4.4]); 没有给出足够多的实参,就会插入默认值来弥补缺失的实参。由于参数只 能从实参列表的尾部开始被省略,在一个有默认值的参数之后的所有参数 都不得不也具有默认值(尽管使用命名参数记法可以允许放松这种限制, - 这种限制仍然会被强制以便位置参数记法能工作)。不管你是否使用它,这种能力都要求在某些用户不信任其他用户的数据中调用函数时做一些预防措施,见。 + 这种限制仍然会被强制以便位置参数记法能工作)。不管你是否使用它,这种能力都要求在某些用户不信任其他用户的数据库中调用函数时做一些预防措施,见 @@ -775,13 +781,13 @@ ERROR: function foo() does not exist 所有的 SQL 函数都可以被用在查询的FROM子句中,但是 - 对于返回复合类型的函数特别有用。如果函数被定义为返回一种基本类型, + 对于返回复合类型的函数特别有用。如果函数被定义为返回一种基础类型, 该表函数会产生一个单列表。如果该函数被定义为返回一种复合类型,该 表函数会为该复合类型的每一个属性产生一列。 - 以下是一个示例: + 以下是一个示例: CREATE TABLE foo (fooid int, foosubid int, fooname text); @@ -814,8 +820,8 @@ SELECT *, upper(fooname) FROM getfoo(1) AS t1; 返回集合的<acronym>SQL</acronym>函数 - function - with SETOF + 函数 + 使用 SETOF @@ -948,7 +954,7 @@ SELECT x, generate_series(1,5) AS g FROM tab; SELECT x, g FROM tab, LATERAL generate_series(1,5) AS g; - 这会是完全一样的,除了在这个特别的示例中,规划器会选择把g放在嵌套循环连接的外侧,因为gtab没有实际的横向依赖。那会导致一种不同的输出行顺序。选择列表中的集合返回函数总是会被计算,就好像它们在FROM子句剩余部分的嵌套循环连接的内侧一样,因此在考虑来自FROM子句的下一行之前,这些函数会运行到完成。 + 这会是完全一样的,除了在这个特别的示例中,规划器可以选择把g放在嵌套循环连接的外侧,因为gtab没有实际的横向依赖。那会导致一种不同的输出行顺序。选择列表中的集合返回函数总是会被计算,就好像它们在FROM子句剩余部分的嵌套循环连接的内侧一样,因此在考虑来自FROM子句的下一行之前,这些函数会运行到完成。 @@ -968,15 +974,11 @@ SELECT srf1(srf2(x), srf3(y)), srf4(srf5(z)) FROM tab; SELECT x, CASE WHEN x > 0 THEN generate_series(1, 5) ELSE 0 END FROM tab; - 看起来这个语句应该产生满足x > 0的输入行的五次重复,以及不满足的行的一次重复。但实际上,由于在CASE表达时被计算前,generate_series(1, 5)会被运行在一个隐式的LATERAL FROM项中,它会为每个输入行产生五次重复。为了减少混乱,这类情况会产生一个解析时错误。 + 看起来这个语句应该产生满足x > 0的输入行的五次重复,以及不满足的行的一次重复。但实际上,由于在CASE表达式被计算前,generate_series(1, 5)会被运行在一个隐式的LATERAL FROM项中,它会为每个输入行产生五次重复。为了减少混乱,这类情况会产生一个解析时错误。 - - 如果一个函数的最后一条命令是带有 RETURNING 子句的 - INSERTUPDATE、 - DELETEMERGE,那么即使该函数没有声明为 SETOF,或者调用它的查询并未取走全部结果行,该命令也总会执行到完成。RETURNING 子句产生的额外结果行会被静默丢弃,但相应的表修改仍然会发生,并且会在函数返回前全部完成。 - + 如果一个函数的最后一条命令是 INSERTUPDATEDELETE 并带有 RETURNING,那么即使该函数没有声明为 SETOF,或者调用它的查询并未取走全部结果行,该命令也总会执行到完成。RETURNING 子句产生的额外结果行会被静默丢弃,但相应的表修改仍然会发生,并且会在函数返回前全部完成。 @@ -984,11 +986,11 @@ SELECT x, CASE WHEN x > 0 THEN generate_series(1, 5) ELSE 0 END FROM tab; 在 PostgreSQL 10 之前,除非多个集合返回函数始终产生相同数量的行,否则把它们放在同一个选择列表中的行为并不合理。 否则,得到的输出行数会是这些集合返回函数各自产生行数的最小公倍数。 此外,嵌套的集合返回函数也不像上文所描述的那样工作;相反,一个集合返回函数至多只能有一个集合返回参数, - 并且每一层嵌套都会独立运行。再加上过去还允许条件执行(即在 CASE 等结构内部使用集合返回函数), + 并且每一组嵌套的集合返回函数都会独立运行。再加上过去还允许条件执行(即在 CASE 等结构内部使用集合返回函数), 事情就更加复杂了。 如果你要编写需要在旧版 PostgreSQL 上运行的查询,建议使用 LATERAL 语法, 因为这样在不同版本之间能够得到一致的结果。 - 如果你的查询依赖于集合返回函数的条件执行,可以把条件判断移动到自定义集合返回函数内部来修复。例如, + 如果你的查询依赖于集合返回函数的条件执行,或许可以把条件判断移动到自定义集合返回函数内部来修复。例如, SELECT x, CASE WHEN y > 0 THEN generate_series(1, z) ELSE 5 END FROM tab; @@ -1006,7 +1008,7 @@ END$$ LANGUAGE plpgsql; SELECT x, case_generate_series(y > 0, 1, z, 5) FROM tab; - 这种写法在所有版本的 PostgreSQL 中都能正常工作。 + 这种写法在所有版本的 PostgreSQL 中的行为都相同。 @@ -1015,7 +1017,7 @@ SELECT x, case_generate_series(y > 0, 1, z, 5) FROM tab; 返回<literal>TABLE</literal>的<acronym>SQL</acronym>函数 - function + 函数 RETURNS TABLE @@ -1064,10 +1066,9 @@ SELECT make_array(1, 2) AS intarray, make_array('a'::text, 'b') AS textarray; 注意类型转换'a'::text的使用是为了指定该参数的类型 - 是text。如果该参数只是一个字符串这就是必须的,因为 + 是text。如果该参数只是一个字符串字面量,这就是必须的,因为 否则它会被当作unknown类型,并且 - unknown的数组也不是一种合法的类型。如果没有改类型 - 类型转换,将得到这样的错误: + unknown的数组也不是一种合法的类型。如果没有该类型转换,将得到这样的错误: ERROR: could not determine polymorphic type because input has type unknown @@ -1138,7 +1139,7 @@ SELECT * FROM dup(22); - 多态也可以用于 variadic 函数。例如: + 多态也可以用于可变参数函数。例如: CREATE FUNCTION anyleast (VARIADIC anyarray) RETURNS anyelement AS $$ SELECT min($1[i]) FROM generate_subscripts($1, 1) g(i); @@ -1173,14 +1174,14 @@ SELECT concat_values('|', 1, 4, 2); 带有排序规则的<acronym>SQL</acronym>函数 - collation - in SQL functions + 排序规则 + 在 SQL 函数中 - 当一个 SQL 函数有一个或多个可设定排序规则的数据类型参数时,会按 - 中的说明,为每次函数调用确定一个排序规则。 - 如果能够成功确定(也就是说,参数之间不存在隐式排序规则冲突),那么所有可设定排序规则的参数都会被视为隐式带有该排序规则。 + 当一个 SQL 函数有一个或多个支持排序规则的数据类型参数时,会按 + 中的说明,根据分配给实参的排序规则,为每次函数调用确定一个排序规则。 + 如果能够成功确定(也就是说,参数之间不存在隐式排序规则冲突),那么所有支持排序规则的参数都会被视为隐式带有该排序规则。 这会影响函数中对排序规则敏感的操作的行为。例如,使用上文的 anyleast 函数时, SELECT anyleast('abc'::text, 'ABC'); @@ -1200,7 +1201,7 @@ CREATE FUNCTION anyleast (VARIADIC anyarray) RETURNS anyelement AS $$ SELECT min($1[i] COLLATE "en_US") FROM generate_subscripts($1, 1) g(i); $$ LANGUAGE SQL; - 但请注意,如果把它用于不可设定排序规则的数据类型,就会抛出错误。 + 但请注意,如果把它用于不支持排序规则的数据类型,就会抛出错误。 @@ -1209,7 +1210,7 @@ $$ LANGUAGE SQL; - 这种可设定排序规则参数的行为,可以看作是仅适用于文本数据类型的一种受限多态形式。 + 这种支持排序规则的参数的行为,可以看作是仅适用于文本数据类型的一种受限多态形式。 @@ -1218,13 +1219,13 @@ $$ LANGUAGE SQL; 函数重载 - overloading - functions + 重载 + 函数 可以用同样的 SQL 名称定义多于一个函数,只要它们的参数不同即可。 - 换句话说,函数名可以被重载。不管你是否使用它,这种能力都要求在某些用户不信任其他用户的数据中调用函数时做一些预防措施,见。当一个查询 + 换句话说,函数名可以被重载。不管你是否使用它,这种能力都要求在某些用户不信任其他用户的数据库中调用函数时采取安全预防措施,见。当一个查询 被执行时,服务器将从数据类型和所提供的参数个数来决定要调用哪个 函数。重载也可用来模拟具有可变参数个数(最大个数有限)的函数。 @@ -1251,10 +1252,10 @@ CREATE FUNCTION test(smallint, double precision) RETURNS ... - 另一类可能的冲突发生在 variadic 函数和非 variadic 函数之间。例如,可以同时创建 + 另一类可能的冲突发生在可变参数函数和非可变参数函数之间。例如,可以同时创建 foo(numeric)foo(VARIADIC numeric[])。 这时,对于只提供一个 numeric 参数的调用(例如 foo(10.1)),就不清楚该匹配哪个函数。 - 规则是:优先使用在搜索路径中出现较早的那个函数;如果两者位于同一模式中,则优先使用非 variadic 函数。 + 规则是:优先使用在搜索路径中出现较早的那个函数;如果两者位于同一模式中,则优先使用非可变参数函数。 @@ -1281,8 +1282,8 @@ CREATE FUNCTION test(int, int) RETURNS int 函数易变性分类 - volatility - functions + 易变性 + 函数 VOLATILE @@ -1304,7 +1305,7 @@ CREATE FUNCTION test(int, int) RETURNS int 一个VOLATILE函数可以做任何事情,包括修改数据库。在 使用相同的参数连续调用时,它能返回不同的结果。优化器不会对这类函 - 数的行为做任何假定。对于在每一行都需要 volatile 函数值的查询,函数都会被重新求值。 + 数的行为做任何假定。使用易变函数的查询会在需要该函数值的每一行上重新对它求值。 @@ -1352,8 +1353,7 @@ CREATE FUNCTION test(int, int) RETURNS int 在考虑先规划然后立即执行的简单交互式查询时,在STABLEIMMUTABLE分类间的区别相对较小:一个函数是在规划时只 执行一次还是在查询执行开始期间只执行一次没有太大关系。但是如果计划 - 被保存下来然后在后面被重用,区别就大了。如果在不允许过早把一个函数 - 变成规划期间的一个常数时把它标记为IMMUTABLE,会导致 + 被保存下来然后在后面被重用,区别就大了。如果把一个实际上并非不可变的函数标记为IMMUTABLE,就可能在规划期间过早将它折叠成常量,导致 在后续重用该计划时继续使用陈旧的值。在使用预备语句,或使用会缓存执行计划的函数语言(如 PL/pgSQL)时,这会带来严重问题。 @@ -1421,7 +1421,7 @@ CREATE FUNCTION test(int, int) RETURNS int 内部函数 - functioninternal + 函数内部 内部函数由 C 编写并且已经被静态链接到PostgreSQL @@ -1459,9 +1459,9 @@ CREATE FUNCTION square_root(double precision) RETURNS double precision C 语言函数 - function - user-defined - in C + 函数 + 用户定义的 + 在 C 中 @@ -1485,17 +1485,17 @@ CREATE FUNCTION square_root(double precision) RETURNS double precision - 在一个会话中第一次调用一个特定可载入对象文件中的用户定义函数时, - 动态载入器会把那个对象文件载入到内存以便该函数被调用。因此用户 + 在一个会话中第一次调用一个特定可载入目标文件中的用户定义函数时, + 动态载入器会把那个目标文件载入到内存以便该函数被调用。因此用户 定义的 C 函数的CREATE FUNCTION必须 - 为该函数指定两块信息:可载入对象文件的名称,以及要在该对象文件中 + 为该函数指定两块信息:可载入目标文件的名称,以及要在该目标文件中 调用的特定函数的 C 名称(链接符号)。如果没有显式指定 C 名称,则 它被假定为和 SQL 函数名相同。 下面的算法被用来基于CREATE FUNCTION - 命令中给定的名称来定位共享对象文件: + 命令中给定的名称来定位共享目标文件: @@ -1554,47 +1554,27 @@ CREATE FUNCTION square_root(double precision) RETURNS double precision PostgreSQL不会自动编译 C 函数。在 - 从CREATE FUNCTION命令中引用对象文件 + 从CREATE FUNCTION命令中引用目标文件 之前,它必须先被编译好。更多信息请见 - magic block - - - PG_MODULE_MAGIC + 魔数块 - 为确保动态装载的对象文件不会被加载到不兼容的服务器中,PostgreSQL 会检查该文件是否包含内容正确的magic block。这样服务器就能检测出明显的不兼容情况,例如代码是针对另一个 PostgreSQL 主版本编译的。要加入 magic block,请在模块某一个(且只能一个)源文件中,在包含头文件 fmgr.h 之后写入: + 为确保动态装载的目标文件不会被加载到不兼容的服务器中,PostgreSQL 会检查该文件是否包含内容正确的魔数块。这样服务器就能检测出明显的不兼容情况,例如代码是针对另一个 PostgreSQL 主版本编译的。要加入魔数块,请在模块某一个(且只能一个)源文件中,在包含头文件 fmgr.h 之后写入: PG_MODULE_MAGIC; - -或者 - -PG_MODULE_MAGIC_EXT(parameters); - PG_MODULE_MAGIC_EXT 这种形式允许为模块指定附加信息;目前可以添加名称和/或版本字符串。(将来可能允许更多字段。)可以写成这样: - - -PG_MODULE_MAGIC_EXT( - .name = "my_module_name", - .version = "1.2.3" -); - - - 之后,名称和版本可以通过 pg_get_loaded_modules() 函数查看。版本字符串的具体含义不受 PostgreSQL 限制,但建议采用语义化版本规则。 - - - - 在第一次使用之后,动态载入对象文件会保留在内存中。在同一个会话中, + 在第一次使用之后,动态载入目标文件会保留在内存中。在同一个会话中, 后续对该文件中函数的调用只需付出一次很小的符号表查找开销。如果需要 - 强制重新载入一个对象文件(例如在重新编译之后),就需要开启一个新的会话。 + 强制重新载入一个目标文件(例如在重新编译之后),就需要开启一个新的会话。 @@ -1613,7 +1593,7 @@ PG_MODULE_MAGIC_EXT( - C 语言函数中的基本类型 + C 语言函数中的基础类型 数据类型 @@ -1622,16 +1602,16 @@ PG_MODULE_MAGIC_EXT( 要了解如何编写 C 语言函数,你需要了解 - PostgreSQL如何在内部表达基本数据类型 + PostgreSQL如何在内部表达基础类型 以及如何与函数传递它们。在内部, - PostgreSQL把基本类型视为一块内存数据块。 + PostgreSQL把基础类型视为一块内存数据块。 你为该类型定义的用户自定义函数,决定了 PostgreSQL 如何操作它。 也就是说,PostgreSQL 只负责把数据存到磁盘、再从磁盘取回, 而数据的输入、处理和输出则依赖你定义的这些函数。 - 基本类型可以有三种内部格式之一: + 基础类型可以有三种内部格式之一: @@ -1696,10 +1676,9 @@ typedef struct 最后,所有变长类型必须也以引用的方式传递。所有变长类型必须用一个 - 正好 4 字节的不透明长度域开始,该域会由SET_VARSIZE - 设置,绝不要直接设置该域!所有要被存储在该类型中的数据必须在内存 - 中接着该长度域的后面存储。长度域包含该结构体的总长度,也就是包括长 - 度域本身的尺寸。 + 正好 4 字节的不透明长度字段开始,该字段会由SET_VARSIZE + 设置,绝不要直接设置该字段!所有要被存储在该类型中的数据必须在内存 + 中接着该长度字段的后面存储。长度字段包含该结构体的总长度,也就是包括长度字段本身的尺寸。 @@ -1749,16 +1728,16 @@ memcpy(destination->data, buffer, 40); VARHDRSZsizeof(int32)一样, - 但是用宏VARHDRSZ来引用变长类型的载荷的 + 但是用宏VARHDRSZ来引用变长类型的额外开销的 尺寸被认为是比较好的风格。还有,必须 - 使用SET_VARSIZE宏来设置长度域,而不是用 + 使用SET_VARSIZE宏来设置长度字段,而不是用 简单的赋值来设置。 展示了 PostgreSQL 中许多内置 SQL 数据类型所对应的 C 类型。 - Defined In列给出了需要包含的头文件,以获取类型定义。 + 定义文件列给出了需要包含的头文件,以获取类型定义。 (实际的定义可能位于所列文件包含的其他文件中。建议用户坚持使用已定义的接口。) 请注意,在服务器代码的任何源文件中,都应该始终首先包含postgres.h, 因为它声明了很多你反正都会用到的内容,而且先包含其他头文件可能会带来可移植性问题。 @@ -1934,8 +1913,7 @@ memcpy(destination->data, buffer, 40); - 现在我们已经复习了基本类型所有可能的结构,现在可以展示一些 - 真实函数的示例了。 + 了解了基础类型所有可能的结构后,就可以看一些实际函数示例。 @@ -1943,7 +1921,7 @@ memcpy(destination->data, buffer, 40); 版本 1 的调用约定 - 版本-1 的调用规范依赖于宏来降低传参数和结果的复杂度。版本-1 函数的 + 版本-1 的调用约定依赖于宏来降低传参数和结果的复杂度。版本-1 函数的 C 声明总是: Datum funcname(PG_FUNCTION_ARGS) @@ -1955,35 +1933,11 @@ PG_FUNCTION_INFO_V1(funcname); 必须出现在同一个源文件中(按惯例会正好写在该函数本身之前)。 这种宏调用不是internal语言函数所需要的,因为 PostgreSQL会假定所有内部函数都使用 - 版本-1 规范。不过,对于动态载入函数是必需的。 - - - - 在版本-1 函数中,每一个实参都使用对应于该参数数据类型的PG_GETARG_xxx()宏取得。(在非严格的函数中,需要使用PG_ARGISNULL()对参数是否为空提前做检查;见下文。)结果要用对应于返回类型的PG_RETURN_xxx()宏返回。PG_GETARG_xxx()的参数是要取得的函数参数的编号,从零开始计。PG_RETURN_xxx()的参数是实际要返回的值。 - - - - 要调用另一个版本-1 函数,你可以使用 - DirectFunctionCalln(func, - arg1, ..., argn)。这在你想调用标准内部库中定义的函数时尤其有用,因为它提供了与其 SQL 签名相似的接口。 - - - - 这些便利函数以及类似函数都可以在 fmgr.h 中找到。 - DirectFunctionCalln 系列把 C 函数名作为其第一个参数。另有 - OidFunctionCalln 等一些变体,它们接收目标函数的 OID。所有这些函数都要求以 Datum 形式提供函数参数,返回值也同样是 Datum。注意,使用这些便利函数时,参数和结果都不能为 NULL。 - - - - 例如,要在 C 中调用 starts_with(text, text),你可以在系统目录中查到它的 C 实现是 - Datum text_starts_with(PG_FUNCTION_ARGS) - 函数。通常你会用 DirectFunctionCall2(text_starts_with, ...) 来调用它。不过,starts_with(text, - text) 需要排序规则信息,因此如果这样调用,会因无法确定字符串比较该使用哪一种排序规则而失败。你必须改用 DirectFunctionCall2Coll(text_starts_with, ...), - 并提供所需的排序规则,通常就是从 PG_GET_COLLATION() 传递进来,如下面的示例所示。 + 版本-1 调用约定。不过,对于动态载入函数是必需的。 - fmgr.h 还提供了便于在 C 类型和 Datum 之间转换的宏。例如,要把 Datum 转成 text*,可以使用 DatumGetTextPP(X)。虽然某些类型为反向转换提供了名为 TypeGetDatum(X) 之类的宏,但 text* 没有;对它而言,直接使用通用宏 PointerGetDatum(X) 即可。如果你的扩展定义了额外的类型,通常也很方便为这些类型定义类似的宏。 + 在版本-1 函数中,每一个实参都使用对应于该参数数据类型的PG_GETARG_xxx()宏取得。(在非严格的函数中,需要使用PG_ARGISNULL()对参数是否为空值提前做检查;见下文。)结果要用对应于返回类型的PG_RETURN_xxx()宏返回。PG_GETARG_xxx()的参数是要取得的函数参数的编号,从零开始计。PG_RETURN_xxx()的参数是实际要返回的值。 @@ -2084,25 +2038,6 @@ concat_text(PG_FUNCTION_ARGS) memcpy(VARDATA(new_text) + arg1_size, VARDATA_ANY(arg2), arg2_size); PG_RETURN_TEXT_P(new_text); } - -/* A wrapper around starts_with(text, text) */ - -PG_FUNCTION_INFO_V1(t_starts_with); - -Datum -t_starts_with(PG_FUNCTION_ARGS) -{ - text *t1 = PG_GETARG_TEXT_PP(0); - text *t2 = PG_GETARG_TEXT_PP(1); - Oid collid = PG_GET_COLLATION(); - bool result; - - result = DatumGetBool(DirectFunctionCall2Coll(text_starts_with, - collid, - PointerGetDatum(t1), - PointerGetDatum(t2))); - PG_RETURN_BOOL(result); -} ]]> @@ -2131,10 +2066,6 @@ CREATE FUNCTION copytext(text) RETURNS text CREATE FUNCTION concat_text(text, text) RETURNS text AS 'DIRECTORY/funcs', 'concat_text' LANGUAGE C STRICT; - -CREATE FUNCTION t_starts_with(text, text) RETURNS boolean - AS 'DIRECTORY/funcs', 't_starts_with' - LANGUAGE C STRICT; @@ -2142,11 +2073,11 @@ CREATE FUNCTION t_starts_with(text, text) RETURNS boolean - 注意我们已经把函数指定为strict,这意味着如果有任何输入值为空,系统应该自动假定得到空结果。通过这种做法,我们避免在函数代码中检查空值输入。如果不这样做,我们必须使用PG_ARGISNULL()明确地检查空值输入。 + 注意我们已经把函数指定为strict,这意味着如果有任何输入值为空值,系统应该自动假定结果为空值。通过这种做法,我们避免在函数代码中检查空值输入。如果不这样做,我们必须使用PG_ARGISNULL()明确地检查空值输入。 - 宏PG_ARGISNULL(n)允许一个函数测试是否每一个输入为空(当然,只需要在没有声明为strict的函数中这样做)。和PG_GETARG_xxx()宏一样,输入参数也是从零开始计数。注意应该在验证了一个参数不是空之后才执行PG_GETARG_xxx()。要返回一个空结果,应执行PG_RETURN_NULL(),它对严格的以及非严格的函数都有用。 + 宏PG_ARGISNULL(n)允许一个函数测试是否每一个输入为空值(当然,只需要在没有声明为strict的函数中这样做)。和PG_GETARG_xxx()宏一样,输入参数也是从零开始计数。注意应该在验证了一个参数不是空值之后才执行PG_GETARG_xxx()。要返回空值结果,应执行PG_RETURN_NULL(),它对严格的以及非严格的函数都有用。 @@ -2154,11 +2085,11 @@ CREATE FUNCTION t_starts_with(text, text) RETURNS boolean - 在版本-1接口中提供的其他选项是PG_GETARG_xxx()宏的两个变种。其中的第一种是PG_GETARG_xxx_COPY(),它确保返回的指定参数的拷贝可以被安全地写入(通常的宏有时会返回一个指向表中物理存储的值,它不能被写入。使用PG_GETARG_xxx_COPY()宏可以保证得到一个可写的结果)。第二种变种PG_GETARG_xxx_SLICE()宏有三个参数。第一个是函数参数的编号(如上文)。第二个和第三个是要被返回的段的偏移量和长度。偏移量从零开始计算,而负值的长度则表示要求返回该值的剩余部分。当大型值的存储类型为external时,这些宏提供了访问这些大型值的更有效的方法(列的存储类型可以使用ALTER TABLE tablename ALTER COLUMN colname SET STORAGE storagetype来指定。storagetypeplainexternalextended或者main)。 + 在版本-1接口中提供的其他选项是PG_GETARG_xxx()宏的两个变种。其中的第一种是PG_GETARG_xxx_COPY(),它确保返回的指定参数的拷贝可以被安全地写入(通常的宏有时会返回一个指向表中物理存储值的指针,不能写入该值。使用PG_GETARG_xxx_COPY()宏可以保证得到一个可写的结果)。第二种变种PG_GETARG_xxx_SLICE()宏有三个参数。第一个是函数参数的编号(如上文)。第二个和第三个是要被返回的段的偏移量和长度。偏移量从零开始计算,而负值的长度则表示要求返回该值的剩余部分。当大型值的存储类型为external时,这些宏提供了访问这些大型值的部分内容的更有效方法(列的存储类型可以使用ALTER TABLE tablename ALTER COLUMN colname SET STORAGE storagetype来指定。storagetypeplainexternalextended或者main)。 - 最后,版本-1 的函数调用规范可以返回集合结果()、实现触发器函数()和过程语言调用处理器()。更多细节 + 最后,版本-1 的函数调用约定可以返回集合结果()、实现触发器函数()和过程语言调用处理器()。更多细节 可见源代码发布中的src/backend/utils/fmgr/README @@ -2169,10 +2100,10 @@ CREATE FUNCTION t_starts_with(text, text) RETURNS boolean 在开始更高级的话题之前,我们应该讨论一下用于 PostgreSQL C 语言函数的编码规则。 - 虽然可以把不是 C 编写的函数载入到 - PostgreSQL中,这通常是很困难的, + 虽然有可能把不是 C 编写的函数载入到 + PostgreSQL中,但即使能够做到,通常也很困难, 因为其他语言(例如 C++、FORTRAN 或者 Pascal)通常不会遵循和 C - 相同的调用规范。也就是说,其他语言不会以同样的方式在函数之间传递 + 相同的调用约定。也就是说,其他语言不会以同样的方式在函数之间传递 参数以及返回值。由于这个原因,我们会假定你的 C 语言函数确实是用 C 编写的。 @@ -2184,7 +2115,7 @@ CREATE FUNCTION t_starts_with(text, text) RETURNS boolean 使用 pg_config - --includedir-serverpg_configwith user-defined C functions + --includedir-serverpg_config用于用户定义的 C 函数 查出 PostgreSQL 服务器头文件在你的系统上(或你的用户将要运行的系统上)安装于何处。 @@ -2197,7 +2128,7 @@ CREATE FUNCTION t_starts_with(text, text) RETURNS boolean - 记得按照中的说明,为你的共享库定义一个magic block。 + 记得按照中的说明,为你的共享库定义一个魔数块 @@ -2223,7 +2154,7 @@ CREATE FUNCTION t_starts_with(text, text) RETURNS boolean - 对象文件中定义的符号名不能彼此冲突,也不能与 + 目标文件中定义的符号名不能彼此冲突,也不能与 PostgreSQL 服务器可执行文件中定义的符号冲突。如果你收到这类错误消息,就必须重命名相关函数或变量。 @@ -2238,10 +2169,10 @@ CREATE FUNCTION t_starts_with(text, text) RETURNS boolean 复合类型没有像 C 结构体那样的固定布局。复合类型的实例可能包含 - 空值域。此外,继承层次中的复合类型可能具有和同一继承层次中 - 其他成员不同的域。因此, + 空值字段。此外,继承层次中的复合类型可能具有和同一继承层次中 + 其他成员不同的字段。因此, PostgreSQL提供了函数接口 - 来访问 C 的复合类型的域。 + 以便从 C 访问复合类型的字段。 @@ -2253,7 +2184,7 @@ SELECT name, c_overpaid(emp, 1500) AS overpaid WHERE name = 'Bill' OR name = 'Sam'; - 如果使用版本-1的调用规范,我们可以定义 + 如果使用版本-1的调用约定,我们可以定义 c_overpaid为: 也有GetAttributeByNum函数,它可以用目标属性 - 的属性号而不是属性名来选择目标属性。 + 的列号而不是属性名来选择目标属性。 @@ -2312,14 +2243,14 @@ CREATE FUNCTION c_overpaid(emp, integer) RETURNS boolean 要从 C 语言函数中返回一行或一个复合类型值,可以使用一套特殊的 API, - 它通过一组宏和函数隐藏了构造组合数据类型时的大部分复杂性。要使用这套 API,源文件中必须包含: + 它通过一组宏和函数隐藏了构造复合数据类型时的大部分复杂性。要使用这套 API,源文件中必须包含: #include "funcapi.h" - 构造组合数据值(下文简称元组)有两种方式: + 构造复合数据值(下文简称元组)有两种方式: 一种是从 Datum 值数组构造,另一种是从 C 字符串数组构造,这些字符串会传给该元组各列数据类型的输入转换函数。 无论采用哪种方式,首先都需要获取或构造描述该元组结构的 TupleDesc。 处理 Datum 时,需要把 TupleDesc 传给 BlessTupleDesc,然后为每一行调用 heap_form_tuple。 @@ -2328,13 +2259,13 @@ CREATE FUNCTION c_overpaid(emp, integer) RETURNS boolean - 有一些辅助函数可以用来设置所需的 TupleDesc。在大多数返回组合值的函数中,推荐的做法是调用: + 有一些辅助函数可以用来设置所需的 TupleDesc。在大多数返回复合值的函数中,推荐的做法是调用: TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc) - 传入与调用函数本身相同的 fcinfo 结构体(这当然要求使用版本 1 调用约定)。 + 传入调用函数本身收到的同一个 fcinfo 结构体(这当然要求使用版本 1 调用约定)。 resultTypeId 可以指定为 NULL,也可以指定为一个本地变量的地址,用于接收函数结果类型的 OID。 resultTupleDesc 应当是一个本地 TupleDesc 变量的地址。 检查返回结果是否为 TYPEFUNC_COMPOSITE;如果是,resultTupleDesc 就会被填入所需的 TupleDesc。 @@ -2353,7 +2284,7 @@ TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, get_call_result_type有一个兄弟 get_expr_result_type,它被用来解析被表示为一棵表达式 - 树的函数调用的输出类型。在尝试确定来自函数外部的结果类型时可以用它。 + 树的函数调用的输出类型。在尝试从函数自身外部确定结果类型时可以用它。 也有一个get_func_result_type,当只有函数的 OID 可用时 可以用它。不过这些函数无法处理被声明为返回record的 函数,并且get_func_result_type无法解析多态类型,因此你 @@ -2362,22 +2293,22 @@ TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, - 更早、现在已被废弃的获取TupleDesc的函数有: + 更早、现在已被弃用的获取TupleDesc的函数有: TupleDesc RelationNameGetTupleDesc(const char *relname) - 它可以为一个提到的关系的行类型得到TupleDesc, + 它可以为一个指定名称的关系的行类型得到TupleDesc, 还有: TupleDesc TypeGetTupleDesc(Oid typeoid, List *colaliases) 可以基于一个类型 OID 得到TupleDesc。这可以被用来 - 为一种基础或者复合类型获得TupleDesc。不过,对于 + 为一种基本或者复合类型获得TupleDesc。不过,对于 返回record的函数它不起作用,并且它无法解析多态类型。 - 一旦有了一个TupleDesc,如果计划处理 Datum可以调用: + 一旦有了一个TupleDesc,如果计划处理 Datum,可以调用: TupleDesc BlessTupleDesc(TupleDesc tupdesc) @@ -2387,7 +2318,7 @@ AttInMetadata *TupleDescGetAttInMetadata(TupleDesc tupdesc) 如果正在编写一个返回集合的函数,你可以把这些函数的结果保存在 FuncCallContext结构体中 — 分别使用 - tuple_desc或者attinmeta域。 + tuple_desc或者attinmeta字段。 @@ -2407,8 +2338,7 @@ HeapTuple BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values) values是一个 C 字符串数组,每一个元素是返回行 的一个属性。每一个 C 字符串应该是该属性数据类型的输入函数所期望 的格式。为了对一个属性返回空值,values数组中对 - 应的指针应该被设置为NULL。对于你返回的每一行都将 - 再次调用这个函数。 + 应的指针应该被设置为NULL。对于你返回的每一行都需要再次调用这个函数。 @@ -2443,13 +2373,13 @@ HeapTupleGetDatum(HeapTuple tuple) 使用 ValuePerCall 模式时,重要的是要记住查询不能保证运行完成; 也就是说,由于诸如LIMIT之类的选项, - 执行程序可能会在获取所有行之前停止调用 set-returning 函数。 + 执行器可能会在获取所有行之前停止调用集合返回函数。 这意味着在最后一次调用中执行清理活动是不安全的,因为这可能永远不会发生。 对于需要访问外部资源(例如文件描述符)的函数,建议使用 Materialize 模式。 - 本节的其余部分记录了一组使用 ValuePerCall 模式的 SRF 常用(尽管不是必须使用)的帮助程序宏。 + 本节的其余部分记录了一组使用 ValuePerCall 模式的 SRF 常用(尽管不是必须使用)的辅助宏。 有关 Materialize 模式的其他详细信息可以在src/backend/utils/fmgr/README中找到。 此外,PostgreSQL源代码分发中的contrib 模块包含许多使用 ValuePerCall 和 Materialize 模式的 SRF 示例。 @@ -2458,7 +2388,7 @@ HeapTupleGetDatum(HeapTuple tuple) 要使用此处描述的 ValuePerCall 支持宏,请包含funcapi.h。 这些宏与结构体FuncCallContext一起使用,该结构体包含需要跨调用保存的状态。 - 在调用 SRF 中,fcinfo->flinfo->fn_extra用于在调用之间保存 + 在使用这些宏的 SRF 中,fcinfo->flinfo->fn_extra用于在调用之间保存 指向FuncCallContext的指针。 宏在第一次使用时自动填充该字段,并期望在后续使用中找到相同的指针。 @@ -2491,7 +2421,7 @@ typedef struct FuncCallContext /* * 可选:指向包含属性类型输入元数据的结构的指针 * - * attinmeta 被用在返回元组(即组合数据类型)时,在返回基本数据类型 + * attinmeta 被用在返回元组(即复合数据类型)时,在返回基础类型 * 时不会使用。只有想用BuildTupleFromCStrings()创建返回元组时才需要它。 */ AttInMetadata *attinmeta; @@ -2508,7 +2438,7 @@ typedef struct FuncCallContext /* * 可选:指向包含元组描述的结构的指针 * - * tuple_desc 被用在返回元组(即组合数据类型)时,并且只有在用 + * tuple_desc 被用在返回元组(即复合数据类型)时,并且只有在用 * heap_form_tuple() 而不是 BuildTupleFromCStrings() 构建元组时才需要它。 * 注意这里存储的 TupleDesc 指针通常已经被先运行过 BlessTupleDesc()。 */ @@ -2612,7 +2542,7 @@ my_set_returning_function(PG_FUNCTION_ARGS) else { /* 这里已经完成了项的返回,所以只报告事实。 */ - /* (不要将清理代码放在这里的。) */ + /* (不要将清理代码放在这里。) */ SRF_RETURN_DONE(funcctx); } } @@ -2692,7 +2622,7 @@ retcomposite(PG_FUNCTION_ARGS) /* 构建一个元组 */ tuple = BuildTupleFromCStrings(attinmeta, values); - /* 将元组转换为数据 */ + /* 将元组转换为 datum */ result = HeapTupleGetDatum(tuple); /* 清理(这实际上并不是必要的) */ @@ -2748,10 +2678,10 @@ CREATE OR REPLACE FUNCTION retcomposite(IN integer, IN integer, fcinfo->flinfo访问。参数argnum则是从零 开始计。get_call_result_type也可被用作 get_fn_expr_rettype的一种替代品。还有 - get_fn_expr_variadic,它可以被用来找出 variadic 参数 + get_fn_expr_variadic,它可以被用来找出可变参数 是否已经被合并到了一个数组中。这主要用于 VARIADIC "any"函数,因为对于接收普通数组类型的 - variadic 函数来说总是会发生这类合并。 + 可变参数函数来说总是会发生这类合并。 @@ -2819,7 +2749,7 @@ CREATE FUNCTION make_array(anyelement) RETURNS anyarray 它与 anyelement 类似,但不会要求不同的 "any" 参数必须是同一种类型,也不会帮助确定函数的结果类型。 C 语言函数还可以把最后一个参数声明为 VARIADIC "any"。 这可以匹配一个或多个任意类型的实参(不必是同一种类型)。 - 这些参数不会像普通 variadic 函数那样被收集成一个数组,而是会单独传给函数。 + 这些参数不会像普通可变参数函数那样被收集成一个数组,而是会单独传给函数。 使用这种特性时,必须结合 PG_NARGS() 宏以及前面介绍的方法来确定实参的个数和类型。 此外,这种函数的用户也可能希望在函数调用中使用 VARIADIC 关键字,以便让函数把数组元素当作独立参数处理。 如果希望支持这种行为,函数本身就必须在使用 get_fn_expr_variadic 检测到实参被标记为 VARIADIC 后自行实现它。 @@ -2827,82 +2757,53 @@ CREATE FUNCTION make_array(anyelement) RETURNS anyarray - 共享内存 - - - 启动时请求共享内存 + 共享内存与 LWLocks - - 插件可以在服务器启动时预留共享内存。要做到这一点,插件的共享库必须通过 + + 插件可以在服务器启动时预留 LWLock 和一块共享内存。插件的共享库必须通过在 shared_preload_libraries - 预加载。该共享库还应当在其 _PG_init 函数中注册 - shmem_request_hook。这个 - shmem_request_hook 可以通过调用: - -void RequestAddinShmemSpace(Size size) - - 来预留共享内存。每个后端都应当通过调用: + 中指定它来预加载。共享库应在其 _PG_init 函数中注册 + shmem_request_hook。这个 shmem_request_hook + 可以预留 LWLock 或共享内存。要预留共享内存,应从你的 + shmem_request_hook 中调用: -void *ShmemInitStruct(const char *name, Size size, bool *foundPtr) +void RequestAddinShmemSpace(int size) - 来获取指向这块预留共享内存的指针。如果该函数把 - foundPtr 设为 false,调用者就应初始化这块预留共享内存的内容;如果 foundPtrtrue,说明该共享内存已经由其他后端初始化过,调用者无需再做初始化。 - 为避免竞争条件,每个后端在初始化其共享内存分配时都应使用 LWLock - AddinShmemInitLock,如下所示: + 要预留 LWLock,应从你的 shmem_request_hook 中调用: +void RequestNamedLWLockTranche(const char *tranche_name, int num_lwlocks) + + 这样会确保有一个包含 num_lwlocks 个 LWLock 的数组, + 可以通过名称 tranche_name 访问。 + 使用 GetNamedLWLockTranche 可以取得指向该数组的指针。 + + + shmem_request_hook 的示例可见于 + PostgreSQL 源代码树中的 + contrib/pg_stat_statements/pg_stat_statements.c。 + + 为避免可能的竞争条件,每个后端都应使用 LWLock AddinShmemInitLock 来连接和初始化分配给它的共享内存,如下所示: static mystruct *ptr = NULL; -bool found; + +if (!ptr) +{ + bool found; LWLockAcquire(AddinShmemInitLock, LW_EXCLUSIVE); ptr = ShmemInitStruct("my struct name", size, &found); if (!found) { - ... initialize contents of shared memory ... + initialize contents of shmem area; + acquire any requested LWLocks using: ptr->locks = GetNamedLWLockTranche("my tranche name"); } LWLockRelease(AddinShmemInitLock); +} - shmem_startup_hook 为初始化代码提供了一个方便的位置,但并不强制要求所有这类代码都放在这个钩子中。在 Windows 上(以及任何定义了 EXEC_BACKEND 的平台上),每个后端都会在附加到共享内存后不久执行已注册的 shmem_startup_hook,因此插件在该钩子中仍应像上例那样获取 AddinShmemInitLock。在其他平台上,只有 postmaster 进程会执行 shmem_startup_hook,每个后端会自动继承这些共享内存指针。 - - - - shmem_request_hook 与 - shmem_startup_hook 的一个完整示例可见于 - PostgreSQL 源代码树中的 - contrib/pg_stat_statements/pg_stat_statements.c。 - - - - - 启动后请求共享内存 - - - 还有另一种更灵活的预留共享内存的方法,可以在服务器启动之后、并且无需借助 - shmem_request_hook 来完成。为此,每个需要使用该共享内存的后端都应通过调用以下函数来获取一个指针: - -void *GetNamedDSMSegment(const char *name, size_t size, - void (*init_callback) (void *ptr), - bool *found) - - 如果给定名称的动态共享内存段尚不存在,该函数会分配该段,并使用提供的 - init_callback 回调函数对其进行初始化。如果该段已经由另一个后端分配并初始化过,该函数就只会把现有的动态共享内存段附加到当前后端。 - - - - 与在服务器启动时预留的共享内存不同,使用 - GetNamedDSMSegment 预留共享内存时,不需要获取 - AddinShmemInitLock,也不需要采取其他措施来避免竞争条件。该函数会确保只有一个后端分配并初始化该内存段,而其他所有后端都会获得指向同一块已完全分配并初始化好的内存段的指针。 - - - - GetNamedDSMSegment 的完整使用示例可见于 - src/test/modules/test_dsm_registry/test_dsm_registry.c - ,位于 PostgreSQL 源代码树中。 - @@ -2945,9 +2846,9 @@ void *GetNamedDSMSegment(const char *name, size_t size, - 如果从 C++ 代码调用后端函数,确定 C++ 调用栈值包含传统 C 风格 + 如果从 C++ 代码调用后端函数,确定 C++ 调用栈只包含传统 C 风格 的数据结构(POD)。这是必要的,因为后端错误会 - 产生远距离的longjmp(),它无法正确的退回具有非 + 产生远距离的longjmp(),它无法正确地展开具有非 POD 对象的 C++ 调用栈。 @@ -2966,8 +2867,8 @@ void *GetNamedDSMSegment(const char *name, size_t size, 函数优化信息 - optimization information - for functions + 优化信息 + 用于函数 @@ -3003,7 +2904,7 @@ supportfn(internal) returns internal - 对于返回 boolean 的目标函数,估计使用该函数的 WHERE 子句会筛选出多少行通常很有用。这可以通过实现 SupportRequestSelectivity 请求类型的支持函数来完成。 + 对于返回 boolean 的目标函数,估计使用该函数的 WHERE 子句筛选出的行所占的比例通常很有用。这可以通过实现 SupportRequestSelectivity 请求类型的支持函数来完成。 diff --git a/zh/16/xindex.sgml b/zh/16/xindex.sgml index 51723a8d..9bb5013f 100644 --- a/zh/16/xindex.sgml +++ b/zh/16/xindex.sgml @@ -5,7 +5,7 @@ 索引 - for user-defined data type + 用于用户定义的数据类型 @@ -19,12 +19,7 @@ 索引方法和操作符类 - - 操作符类与索引访问方法相关联,例如 - B-树 或 GIN。 - 自定义索引访问方法可通过 定义。 - 详见 。 - + pg_am 表为每个索引方法(内部称为访问方法)保存一行。对表进行常规访问的支持内置于 PostgreSQL 中,但所有索引方法都在 pg_am 中描述。可以编写必要的代码,然后在 pg_am 中创建一个条目,从而添加新的索引访问方法 — 但这超出了本章的范围(参见)。 索引方法的例程并不直接知道它将处理哪些数据类型。相反,一个操作符类操作符类标识了索引方法在处理特定数据类型时需要使用的那组操作。之所以称为操作符类,是因为它指定的一项内容就是可与索引一起使用的 WHERE 子句操作符集合(也就是能被转换成索引扫描条件的操作符)。操作符类还可以指定索引方法内部操作所需的一些支持函数,但这些函数并不直接对应任何可与索引一起使用的 WHERE 子句操作符。 @@ -353,12 +348,6 @@ 5 - - - 返回可由 C 调用的 skip 支持函数地址(可选) - - 6 - @@ -385,7 +374,7 @@ - 给定一个 64 位 salt,计算一个键的 64 位哈希值;如果 salt 为 0,结果的低 32 位必须与函数 1 计算出的值一致(可选) + 给定一个 64 位盐值,计算一个键的 64 位哈希值;如果盐值为 0,结果的低 32 位必须与函数 1 计算出的值一致(可选) 2 @@ -400,7 +389,7 @@ - GiST 索引有十二个支持函数,其中七个是可选的,如所示。 + GiST 索引有十一个支持函数,其中六个是可选的,如所示。 (详见。) @@ -475,11 +464,7 @@ (可选) 11 - - translate_cmptype - 把比较类型转换为该操作符类使用的策略号(可选) - 12 - + @@ -558,7 +543,7 @@ compare - 比较两个键,并返回一个小于零、等于零或大于零的整数,以表示第一个键是小于、等于还是大于第二个键 + 比较两个键,并返回一个小于零、等于零或大于零的整数,用以表示第一个键是小于、等于还是大于第二个键 1 @@ -732,7 +717,7 @@ CREATE OPERATOR < ( restrict = scalarltsel, join = scalarltjoinsel ); - 指定正确的交换子和求反器操作符很重要,同样也要指定合适的限制选择度函数和连接选择度函数,否则优化器将无法有效地利用索引。 + 指定正确的交换子和求反器操作符很重要,同样也要指定合适的限制选择率函数和连接选择率函数,否则优化器将无法有效地利用索引。 @@ -835,8 +820,7 @@ DEFAULT FOR TYPE int8 USING btree FAMILY integer_ops AS FUNCTION 1 btint8cmp(int8, int8) , FUNCTION 2 btint8sortsupport(internal) , FUNCTION 3 in_range(int8, int8, int8, boolean, boolean) , - FUNCTION 4 btequalimage(oid) , - FUNCTION 6 btint8skipsupport(internal) ; + FUNCTION 4 btequalimage(oid) ; CREATE OPERATOR CLASS int4_ops DEFAULT FOR TYPE int4 USING btree FAMILY integer_ops AS @@ -849,8 +833,7 @@ DEFAULT FOR TYPE int4 USING btree FAMILY integer_ops AS FUNCTION 1 btint4cmp(int4, int4) , FUNCTION 2 btint4sortsupport(internal) , FUNCTION 3 in_range(int4, int4, int4, boolean, boolean) , - FUNCTION 4 btequalimage(oid) , - FUNCTION 6 btint4skipsupport(internal) ; + FUNCTION 4 btequalimage(oid) ; CREATE OPERATOR CLASS int2_ops DEFAULT FOR TYPE int2 USING btree FAMILY integer_ops AS @@ -863,8 +846,7 @@ DEFAULT FOR TYPE int2 USING btree FAMILY integer_ops AS FUNCTION 1 btint2cmp(int2, int2) , FUNCTION 2 btint2sortsupport(internal) , FUNCTION 3 in_range(int2, int2, int2, boolean, boolean) , - FUNCTION 4 btequalimage(oid) , - FUNCTION 6 btint2skipsupport(internal) ; + FUNCTION 4 btequalimage(oid) ; ALTER OPERATOR FAMILY integer_ops USING btree ADD -- cross-type comparisons int8 vs int2 @@ -931,7 +913,7 @@ ALTER OPERATOR FAMILY integer_ops USING btree ADD - 要构建一个多数据类型的哈希操作符族,必须为该族支持的每一种数据类型创建相互兼容的哈希支持函数。这里的兼容性是指:对任意两个被该族中的等值操作符视为相等的值,这些函数都保证返回相同的哈希码,即使这两个值属于不同类型也是如此。当这些类型具有不同的物理表示时,这通常难以实现,但在某些情况下可以做到。此外,将该操作符族中一种数据类型的值通过隐式或二进制强制转换转换成该族中另一种数据类型时,不应改变所计算出的哈希值。注意,每种数据类型只有一个支持函数,而不是每个等值操作符一个。建议让操作符族保持完整,也就是说,对每一种数据类型组合都提供一个等值操作符。每个操作符类只应包含其数据类型对应的非跨数据类型等值操作符和支持函数。 + 要构建一个多数据类型的哈希操作符族,必须为该族支持的每一种数据类型创建相互兼容的哈希支持函数。这里的兼容性是指:对任意两个被该族中的等值操作符视为相等的值,这些函数都保证返回相同的哈希码,即使这两个值属于不同类型也是如此。当这些类型具有不同的物理表示时,这通常难以实现,但在某些情况下可以做到。此外,将该操作符族中一种数据类型的值通过隐式或二进制强制转换转为该族中另一种数据类型时,不得改变所计算出的哈希值。注意,每种数据类型只有一个支持函数,而不是每个等值操作符一个。建议让操作符族保持完整,也就是说,对每一种数据类型组合都提供一个等值操作符。每个操作符类只应包含其数据类型对应的非跨数据类型等值操作符和支持函数。 @@ -944,7 +926,7 @@ ALTER OPERATOR FAMILY integer_ops USING btree ADD - 在 PostgreSQL 8.3 之前,并没有操作符族这一概念,因此任何打算与索引一起使用的跨数据类型操作符都必须直接绑定到该索引的操作符类中。虽然这种做法仍然有效,但已经废弃,因为它会使索引的依赖关系过于宽泛,而且当两种数据类型都在同一操作符族中拥有操作符时,规划器能更有效地处理跨数据类型比较。 + 在 PostgreSQL 8.3 之前,并没有操作符族这一概念,因此任何打算与索引一起使用的跨数据类型操作符都必须直接绑定到该索引的操作符类中。虽然这种做法仍然有效,但已被弃用,因为它会使索引的依赖关系过于宽泛,而且当两种数据类型都在同一操作符族中拥有操作符时,规划器能更有效地处理跨数据类型比较。 @@ -961,7 +943,7 @@ ALTER OPERATOR FAMILY integer_ops USING btree ADD - 特别地,ORDER BYDISTINCT等 SQL 特性要求对值的比较和排序。为了在用户定义的数据类型上实现这些特性,PostgreSQL会为数据类型查找默认 B-树操作符类。这个操作符类的equals成员定义了用于GROUP BYDISTINCT的值的等值概念,而该操作符类施加的排序顺序定义了默认的ORDER BY顺序。 + 特别地,ORDER BYDISTINCT等 SQL 特性要求对值的比较和排序。为了在用户定义的数据类型上实现这些特性,PostgreSQL会为数据类型查找默认 B-树操作符类。这个操作符类的相等成员定义了用于GROUP BYDISTINCT的值的等值概念,而该操作符类施加的排序顺序定义了默认的ORDER BY顺序。 @@ -987,11 +969,11 @@ SELECT * FROM mytable ORDER BY somecol USING ~<~; - 用户定义类型的数组比较也依赖于该类型默认 B-树操作符类所定义的语义。如果没有默认 B-树操作符类,但有默认的哈希操作符类,则支持数组相等比较,但不支持顺序比较。 + 用户定义类型的数组比较也依赖于该类型默认 B-树操作符类所定义的语义。如果没有默认 B-树操作符类,但有默认的哈希操作符类,则支持数组相等比较,但不支持排序比较。 - 另一种需要更多数据类型相关知识的 SQL 特性,是窗口函数中的 RANGE offset PRECEDING/FOLLOWING 框架选项(见)。对于下面这样的查询 + 另一种需要更多数据类型相关知识的 SQL 特性,是窗口函数中的 RANGE offset PRECEDING/FOLLOWING 帧选项(见)。对于下面这样的查询 SELECT sum(x) OVER (ORDER BY x RANGE BETWEEN 5 PRECEDING AND 10 FOLLOWING) FROM mytable; @@ -1026,7 +1008,7 @@ SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10; - 搜索操作符必须返回布尔结果,而排序操作符通常返回其他类型的结果,例如表示距离的浮点数或数值。这种类型通常不同于被索引的数据类型。为了避免对不同数据类型行为作硬编码假设,在定义排序操作符时,必须指定一个 B-树操作符族,用来说明结果数据类型的排序顺序。正如上一节所述,B-树操作符族定义了 PostgreSQL 的顺序概念,因此这是一种自然的表示方式。由于点的 <-> 操作符返回 float8,因此可以在创建操作符类时这样指定它: + 搜索操作符必须返回布尔结果,而排序操作符通常返回其他类型的结果,例如用于表示距离的 float 或 numeric。这种类型通常不同于被索引的数据类型。为了避免对不同数据类型行为作硬编码假设,在定义排序操作符时,必须指定一个 B-树操作符族,用来说明结果数据类型的排序顺序。正如上一节所述,B-树操作符族定义了 PostgreSQL 的顺序概念,因此这是一种自然的表示方式。由于点的 <-> 操作符返回 float8,因此可以在创建操作符类时这样指定它: (point, point) FOR ORDER BY float_ops ]]> @@ -1039,7 +1021,7 @@ OPERATOR 15 <-> (point, point) FOR ORDER BY float_ops 操作符类的特殊特性 - 还有两个操作符类的特殊特性我们尚未讨论,主要是因为它们对最常用的索引方法并不太有用。 + 还有两个操作符类的特殊特性我们尚未讨论,主要是因为它们对最常用的索引方法没有用处。 @@ -1060,7 +1042,7 @@ CREATE OPERATOR CLASS polygon_ops STORAGE box; - 目前,只有 GiST、SP-GiST、GIN 和 BRIN 索引方法支持与列数据类型不同的 STORAGE 类型。GiST 的 compressdecompress 支持例程在使用 STORAGE 时必须处理数据类型转换。SP-GiST 同样需要 compress 支持函数在存储类型不同时完成转换;如果某个 SP-GiST 操作符类还支持取回数据,那么反向转换必须由 consistent 函数处理。在 GIN 中,STORAGE 类型标识key值的类型,它通常不同于被索引列的类型 — 例如,整数数组列上的某个操作符类,其键值可能只是整数。GIN 的 extractValueextractQuery 支持例程负责从被索引值中提取键。BRIN 与 GIN 类似:STORAGE 类型标识被存储的摘要值类型,而操作符类的支持过程负责正确解释这些摘要值。 + 目前,只有 GiST、SP-GiST、GIN 和 BRIN 索引方法支持与列数据类型不同的 STORAGE 类型。GiST 的 compressdecompress 支持例程在使用 STORAGE 时必须处理数据类型转换。SP-GiST 同样需要 compress 支持函数在存储类型不同时完成转换;如果某个 SP-GiST 操作符类还支持取回数据,那么反向转换必须由 consistent 函数处理。在 GIN 中,STORAGE 类型标识值的类型,它通常不同于被索引列的类型 — 例如,整数数组列上的某个操作符类,其键值可能只是整数。GIN 的 extractValueextractQuery 支持例程负责从被索引值中提取键。BRIN 与 GIN 类似:STORAGE 类型标识被存储的摘要值类型,而操作符类的支持函数负责正确解释这些摘要值。 diff --git a/zh/16/xml2.sgml b/zh/16/xml2.sgml index 1324ffd4..f3f40587 100644 --- a/zh/16/xml2.sgml +++ b/zh/16/xml2.sgml @@ -90,7 +90,7 @@ 对文档执行该查询,并将结果包在 XML 标签中。如果结果包含多个值,输出将类似于: <toptag> -<itemtag>Value 1 which could be an XML fragment</itemtag> +<itemtag>Value 1(可以是 XML 片段)</itemtag> <itemtag>Value 2....</itemtag> </toptag> @@ -173,7 +173,7 @@ xpath_table(text key, text document, text relation, text xpaths, text criteria) key - key 字段的名称 — 这只是一个作为输出表第一列使用的字段,也就是说,它用于标识每个输出行来自哪条记录(关于多个值,见下文注释) + 字段的名称 — 这只是一个作为输出表第一列使用的字段,也就是说,它用于标识每个输出行来自哪条记录(关于多个值,见下文注释) @@ -238,7 +238,7 @@ xpath_table('article_id', 'date_entered > ''2003-01-01'' ') AS t(article_id integer, author text, page_count integer, title text); - AS 子句定义了输出表中各列的名称和类型。第一列是 key 字段,其余各列对应 XPath 查询。如果 XPath 查询多于结果列,多出的查询将被忽略。如果结果列多于 XPath 查询,多出的列将为 NULL。 + AS 子句定义了输出表中各列的名称和类型。第一列是 字段,其余各列对应 XPath 查询。如果 XPath 查询多于结果列,多出的查询将被忽略。如果结果列多于 XPath 查询,多出的列将为 NULL。 @@ -267,7 +267,7 @@ WHERE t.author_id = p.person_id; - 在某些情况下,用户会知道某个 XPath 查询只会返回单个结果(例如唯一文档标识符)— 如果它与返回多个结果的 XPath 查询一起使用,这个单值结果只会出现在结果的第一行。解决办法是把 key 字段作为与一个更简单的 XPath 查询结果进行连接的条件之一。例如: + 在某些情况下,用户会知道某个 XPath 查询只会返回单个结果(例如唯一文档标识符)— 如果它与返回多个结果的 XPath 查询一起使用,这个单值结果只会出现在结果的第一行。解决办法是把键字段作为与一个更简单的 XPath 查询结果进行连接的条件之一。例如: CREATE TABLE test ( diff --git a/zh/16/xoper.sgml b/zh/16/xoper.sgml index b9968985..6c439275 100644 --- a/zh/16/xoper.sgml +++ b/zh/16/xoper.sgml @@ -127,6 +127,17 @@ SELECT (a + b) AS c FROM test_complex; 设就认为这种转换有效;= 操作符的创建者必须通过为该操 作符标记交换子信息,明确声明这种转换是有效的。 + + 定义一个与自身可交换的操作符时,直接定义即可。但定义一对可交换操作符时,情况就稍微复杂一些:第一个要定义的操作符如何引用另一个尚未定义的操作符呢?这个问题有两种解决办法: + + 一种办法是在定义第一个操作符时省略 COMMUTATOR 子句,然后在第二个操作符的定义中提供该子句。由于 PostgreSQL 知道可交换操作符是成对出现的,因此它在看到第二个定义时,会自动回头补全第一个定义中缺少的 COMMUTATOR 子句。 + + + + 另一种更直接的办法是在两个定义中都包含 COMMUTATOR 子句。当 PostgreSQL 处理第一个定义并发现 COMMUTATOR 引用了一个不存在的操作符时,系统会在系统目录中为该操作符建立一个占位项。这个占位项只有操作符名称、左右操作数类型和结果类型包含有效数据,因为这就是 PostgreSQL 此时能够推断出的全部信息。第一个操作符的目录项将链接到这个占位项。之后,当你定义第二个操作符时,系统会用第二个定义中的附加信息更新该占位项。如果在占位操作符补全之前尝试使用它,就只会得到一条错误消息。 + + + @@ -158,16 +169,19 @@ SELECT (a + b) AS c FROM test_complex; x <> y。这种情况比你想象得更常见,因为 NOT 操作可能会作为其他重排的结果被插入进来。 + + 可以使用上面解释的定义交换子对的相同方法,来定义成对的求反器操作符。 + <literal>RESTRICT</literal> - 如果给出 RESTRICT 子句,它指定该操作符的限制选择度估 + 如果给出 RESTRICT 子句,它指定该操作符的限制选择率估 算函数。(注意,这里是函数名,而不是操作符名。) RESTRICT 子句只对返回 boolean 的二元操 - 作符有意义。限制选择度估算器的作用,是针对当前操作符和某个特定常量值, + 作符有意义。限制选择率估算器的作用,是针对当前操作符和某个特定常量值, 猜测一张表中有多少比例的行会满足如下形式的 WHERE 子句条件: @@ -179,9 +193,9 @@ column OP constant - 编写新的限制选择度估算函数远远超出了本章的范围,不过幸运的是,对于你自 + 编写新的限制选择率估算函数远远超出了本章的范围,不过幸运的是,对于你自 己的很多操作符,通常都可以直接使用系统提供的某个标准估算器。标准的限制 - 选择度估算器如下: + 选择率估算器如下: eqsel 用于 = neqsel 用于 <> @@ -193,7 +207,7 @@ column OP constant - 对于选择度非常高或非常低的操作符,即使它们实际上并不是真正的相等或不等 + 对于选择率非常高或非常低的操作符,即使它们实际上并不是真正的相等或不等 比较,你也常常可以勉强使用 eqselneqsel。例如,几何类型中的近似相等操作符就使用 eqsel,其依据是它们通常只会匹配表中很小一部分项。 @@ -212,7 +226,7 @@ column OP constant - 另一个有用的内置选择度估算函数是 matchingsel。只要 + 另一个有用的内置选择率估算函数是 matchingsel。只要 已为输入数据类型收集了标准的 MCV 和/或直方图统计信息,它几乎就适用于任 何二元操作符。它的默认估计值被设定为 eqsel 所用默认 估计值的两倍,因此最适合那些比相等比较稍微宽松一些的比较操作符。(或者 @@ -222,7 +236,7 @@ column OP constant src/backend/utils/adt/geo_selfuncs.c 中,还为几 - 何操作符提供了其他选择度估算函数:areasel、 + 何操作符提供了其他选择率估算函数:areaselpositionselcontsel。截至 目前,这些函数都还只是桩实现,但你也许仍会想使用它们(或者更好的是,改 进它们)。 @@ -233,9 +247,9 @@ column OP constant <literal>JOIN</literal> - 如果给出 JOIN 子句,它指定该操作符的连接选择度估算函 + 如果给出 JOIN 子句,它指定该操作符的连接选择率估算函 数。(注意,这里是函数名,而不是操作符名。)JOIN 子 - 句只对返回 boolean 的二元操作符有意义。连接选择度估算器的 + 句只对返回 boolean 的二元操作符有意义。连接选择率估算器的 作用,是针对当前操作符,猜测两张表中有多少比例的行对会满足如下形式的 WHERE 子句条件: @@ -246,7 +260,7 @@ table1.column1 OP table2.column2 - 与前面一样,本章不会尝试解释如何编写连接选择度估算函数,而只是建议你在 + 与前面一样,本章不会尝试解释如何编写连接选择率估算函数,而只是建议你在 适用时使用某个标准估算器: eqjoinsel 用于 = @@ -305,7 +319,7 @@ table1.column1 OP table2.column2 一个可参与哈希连接的操作符,必须拥有一个交换子(如果两侧操作数数据类型 - 相同,则可以是它自身;如果不同,则应是相关的相等操作符),并且该交换子 + 相同,则为它自身;如果不同,则应是相关的相等操作符),并且该交换子 也必须出现在同一个操作符族中。否则,在使用该操作符时可能会发生规划器错 误。另外,对于支持多种数据类型的哈希操作符族,最好(虽然并非严格必需) 为每一种数据类型组合都提供相等操作符;这样可以获得更好的优化效果。 @@ -342,7 +356,7 @@ table1.column1 OP table2.column2 - 归并连接的基本思想,是先把左表和右表分别排序,然后并行扫描它们。因此, + 归并连接的基本思想,是先把左表和右表分别排序,然后同步扫描它们。因此, 两种数据类型都必须能够被完全排序,而连接操作符必须只能在那对值位于排序 次序中同一位置时才成功。实际效果上,这意味着连接操作符 必须表现得像相等比较一样。不过,只要两种不同的数据类型在逻辑上兼容,也 @@ -362,7 +376,7 @@ table1.column1 OP table2.column2 一个可参与归并连接的操作符,必须拥有一个交换子(如果两侧操作数数据类型 - 相同,则可以是它自身;如果不同,则应是相关的相等操作符),并且该交换子 + 相同,则为它自身;如果不同,则应是相关的相等操作符),并且该交换子 也必须出现在同一个操作符族中。否则,在使用该操作符时可能会发生规划器错 误。另外,对于支持多种数据类型的 btree 操作符族,最 好(虽然并非严格必需)为每一种数据类型组合都提供相等操作符;这样可以获 diff --git a/zh/16/xplang.sgml b/zh/16/xplang.sgml index 9075d7b6..0590ea2d 100644 --- a/zh/16/xplang.sgml +++ b/zh/16/xplang.sgml @@ -183,7 +183,7 @@ CREATE TRUSTED LANGUAGE plperl 在默认的PostgreSQL安装中, PL/pgSQL语言的调用处理器会被构建并安装到 - library目录中;此外, + 目录中;此外, PL/pgSQL语言本身也安装在所有数据库中。如 果在构建时配置了Tcl支持,那么 PL/TclPL/TclU diff --git a/zh/16/xtypes.sgml b/zh/16/xtypes.sgml index 3d1b66d1..b66c4aa1 100644 --- a/zh/16/xtypes.sgml +++ b/zh/16/xtypes.sgml @@ -218,7 +218,7 @@ CREATE TYPE complex ( 如果数据类型的内部表示是可变长度的,则这种内部表示必须遵循可变长度数 据的标准布局:前四个字节必须是一个从不直接访问的char[4] 字段(惯例上命名为vl_len_)。必须使用 - SET_VARSIZE()宏在该字段中存储该值的总大小(包括 + SET_VARSIZE()宏在该字段中存储该 datum 的总大小(包括 长度字段本身),并使用VARSIZE()取回它。(这些宏 之所以存在,是因为长度字段可能会随平台不同而采用编码形式。) @@ -260,7 +260,7 @@ CREATE TYPE complex ( PG_DETOAST_DATUM_PACKED(通常通过定义 GETARG_DATATYPE_PP宏来隐藏),并使用 VARSIZE_ANY_EXHDRVARDATA_ANY - 宏访问一个可能采用打包形式的值。再次注意,即使数据类型定义指定了 + 宏访问一个可能采用打包形式的 datum。再次注意,即使数据类型定义指定了 对齐方式,这些宏返回的数据也不是对齐的。如果对齐很重要,就必须使用常 规的PG_DETOAST_DATUM接口。 @@ -271,8 +271,7 @@ CREATE TYPE complex ( 较旧的代码常把vl_len_声明为 int32字段,而不是char[4]字段。只要结构体定 义中还有其他至少按int32对齐的字段,这样做是可以的。但 - 在处理可能未对齐的值时使用这种结构体定义就很危险;编译器可能据此假定该 - 值实际上是对齐的,从而在对齐要求严格的体系结构上导致核心转储。 + 在处理可能未对齐的 datum 时使用这种结构体定义就很危险;编译器可能据此假定该 datum 实际上是对齐的,从而在对齐要求严格的体系结构上导致核心转储。 diff --git a/zh/17/acronyms.sgml b/zh/17/acronyms.sgml index 954245b7..3fba4828 100644 --- a/zh/17/acronyms.sgml +++ b/zh/17/acronyms.sgml @@ -8,14 +8,6 @@ - - ACL - - - 访问控制列表 - - - AM diff --git a/zh/17/amcheck.sgml b/zh/17/amcheck.sgml index d1133f53..b6069aec 100644 --- a/zh/17/amcheck.sgml +++ b/zh/17/amcheck.sgml @@ -343,7 +343,7 @@ SET client_min_messages = DEBUG1; 这也包括因操作系统排序规则的比较规则发生变化而引起的问题。 - 像text这类可排序类型的数据值之间的比较必须是不可变的 + 像text这类支持排序规则的类型的 datum 之间的比较必须是不可变的 (正如用于 B-树索引扫描的所有比较都必须不可变一样), 这就意味着操作系统排序规则绝不能发生变化。 虽然这种情况比较少见,但操作系统排序规则的更新确实可能导致此类问题。 diff --git a/zh/17/backup-manifest.sgml b/zh/17/backup-manifest.sgml index cb7782a4..e092455d 100644 --- a/zh/17/backup-manifest.sgml +++ b/zh/17/backup-manifest.sgml @@ -4,7 +4,7 @@ 备份清单格式 - Backup Manifest + 备份清单 @@ -180,7 +180,7 @@ Start-LSN - 为了使用该备份,必须在指定时间线上从这个 LSN 开始回放。该 LSN 按 + 为了使用该备份,必须在指定时间线上从这个 LSN 开始重放。该 LSN 按 PostgreSQL 通常使用的格式存储;也就是说, 它是一个字符串,由两段十六进制字符串构成,每段长度在 1 到 8 之间,并 以斜杠分隔。 @@ -192,7 +192,7 @@ End-LSN - 使用该备份时,指定时间线上的回放可结束于此 LSN,而这也是允许的最早 + 使用该备份时,指定时间线上的重放可结束于此 LSN,而这也是允许的最早 LSN。其存储格式与 Start-LSN 相同。 diff --git a/zh/17/backup.sgml b/zh/17/backup.sgml index a549c4fb..a7df279f 100644 --- a/zh/17/backup.sgml +++ b/zh/17/backup.sgml @@ -3,7 +3,7 @@ 备份和恢复 - backup + 备份 与任何保存重要数据的系统一样,PostgreSQL数据库也应定期备份。虽然其过程基本简单,但清楚理解其底层技术和前提假设非常重要。 @@ -74,7 +74,7 @@ psql -X dbname < psql -X --set ON_ERROR_STOP=on dbname < dumpfile - 无论如何,你最终只会得到一个部分恢复的数据库。另一种做法是指定将整个转储作为单个事务恢复,这样恢复要么全部完成,要么全部回滚。可以通过把命令行选项传给psql来启用这种模式。使用这种模式时要注意,即便是一个很小的错误,也可能回滚一个已经运行了许多小时的恢复过程。不过,这仍可能比在部分恢复后手工清理一个复杂数据库更可取。 + 无论采用上述哪种方式,你最终只会得到一个部分恢复的数据库。另一种做法是指定将整个转储作为单个事务恢复,这样恢复要么全部完成,要么全部回滚。可以通过把命令行选项传给psql来启用这种模式。使用这种模式时要注意,即便是一个很小的错误,也可能回滚一个已经运行了许多小时的恢复过程。不过,这仍可能比在部分恢复后手工清理一个复杂数据库更可取。 @@ -194,7 +194,7 @@ pg_restore -d dbname - 对于非常大的数据库,你可能需要把split与前两种方法之一结合使用。 + 对于非常大的数据库,你可能需要把split与另外两种方法之一结合使用。 @@ -250,7 +250,7 @@ tar -cf backup.tar /usr/local/pgsql/data - 如果无法获得同时的快照,一种选择是将数据库服务器关闭足够长的时间,以建立所有冻结快照。另一种选择是执行持续归档基础备份(),因为这种备份不受备份期间文件系统变化的影响。这要求只在备份过程中启用持续归档;恢复则使用持续归档恢复()。 + 如果无法获得同时的快照,一种选择是将数据库服务器关闭足够长的时间,以建立所有冻结快照。另一种选择是执行持续归档基础备份(),因为这种备份不受备份期间文件系统变化的影响。这种方法只需在备份期间启用持续归档;恢复则使用持续归档恢复()。 @@ -266,11 +266,11 @@ tar -cf backup.tar /usr/local/pgsql/data 持续归档和时间点恢复(PITR) - continuous archiving + 持续归档 - point-in-time recovery + 时间点恢复 @@ -310,7 +310,7 @@ tar -cf backup.tar /usr/local/pgsql/data - 和普通文件系统备份技术一样,这种方法只能支持整个数据库集簇的恢复,而不支持其中某个子集的恢复。此外,它需要大量归档存储:基础备份可能很庞大,繁忙系统也会产生大量必须归档的 WAL 流量。尽管如此,在很多需要高可靠性的场景中,它仍是首选的备份技术。 + 和普通文件系统备份技术一样,这种方法只能支持整个数据库集簇的恢复,而不支持其中某个子集的恢复。此外,它需要大量归档存储:基础备份可能很庞大,繁忙系统也会产生许多兆字节的、必须归档的 WAL 流量。尽管如此,在很多需要高可靠性的场景中,它仍是首选的备份技术。 @@ -329,7 +329,7 @@ tar -cf backup.tar /usr/local/pgsql/data - 要启用 WAL 归档,请将配置参数设置为replica或更高,将设置为on,并在配置参数中指定要使用的 shell 命令,或者在配置参数中指定要使用的库。实际上,这些设置通常都会放在postgresql.conf文件中。 + 要启用 WAL 归档,请将配置参数设置为replica或更高,将设置为on,并在配置参数中指定要使用的 shell 命令,或者在配置参数中指定要使用的库。在实际使用中,这些设置总是放在postgresql.conf文件中。 @@ -345,20 +345,16 @@ test ! -f /mnt/server/archivedir/00000001000000A900000065 && cp pg_wal/0 对每个新的待归档文件都会生成一条类似的命令。 - - 归档命令会以运行PostgreSQL服务器的同一操作系统用户身份执行。由于这一系列被归档的 WAL 文件实际上包含了数据库中的几乎全部内容,因此你应确保归档数据不会被他人窥探;例如,把它归档到一个不向组或所有用户开放读权限的目录中。 - + 归档命令将以运行 PostgreSQL 服务器的同一用户身份执行。由于归档的一系列 WAL 文件实际上包含数据库中的全部内容,应确保归档数据不会被他人窥视;例如,将其归档到不允许所属组或其他用户读取的目录。 - - 重要的是,归档命令只有在成功时才返回零退出状态。收到零结果后,PostgreSQL会认为该文件已经成功归档,并会将其删除或回收。相反,非零状态会告诉PostgreSQL该文件尚未归档;系统会周期性重试,直到成功为止。 - + 归档命令必须当且仅当成功时才返回退出状态零。收到零状态后,PostgreSQL 会认为该文件已成功归档,并将其删除或回收。非零状态则告诉 PostgreSQL 该文件尚未归档;它会定期重试,直到成功。 另一种归档方式是把自定义归档模块用作archive_library。由于这类模块是用C编写的,创建自己的模块可能比编写 shell 命令需要更多工作。不过,归档模块可能比通过 shell 归档更高效,而且可以访问许多有用的服务器资源。有关归档模块的更多信息,见 - 当归档命令被信号终止(用于服务器关闭流程的SIGTERM除外),或者 shell 因退出状态大于 125 的错误(例如命令未找到)而失败,或者归档函数发出ERRORFATAL时,归档器进程会中止,并由 postmaster 重新启动。在这种情况下,失败不会记录到中。 + 当归档命令被信号终止(用于服务器关闭流程的SIGTERM除外),或者因 shell 报错(例如命令未找到)而以大于 125 的状态退出,或者归档函数发出ERRORFATAL时,归档器进程会中止,并由 postmaster 重新启动。在这种情况下,失败不会记录到中。 @@ -366,7 +362,7 @@ test ! -f /mnt/server/archivedir/00000001000000A900000065 && cp pg_wal/0 - 在少数情况下,PostgreSQL可能会尝试重新归档一个此前已经归档过的 WAL 文件。例如,如果系统在服务器把归档成功持久记录下来之前崩溃,服务器在重启后会再次尝试归档该文件(前提是归档仍然启用)。当归档命令或归档库遇到一个已存在的文件时,如果该文件与待归档 WAL 文件内容完全相同,且先前归档的文件已经完全持久化到存储,则前者应分别返回零状态或true。如果已存在文件的内容与正在归档的 WAL 文件不同,则归档命令或归档库必须分别返回非零状态或false。 + 在少数情况下,PostgreSQL可能会尝试重新归档一个此前已经归档过的 WAL 文件。例如,如果系统在服务器把归档成功持久记录下来之前崩溃,服务器在重启后会再次尝试归档该文件(前提是归档仍然启用)。当归档命令或归档库遇到一个已存在的文件时,如果该文件与待归档 WAL 文件内容完全相同,且先前归档的文件已经完全持久化到存储,则归档命令或归档库应分别返回零状态或true。如果已存在文件的内容与正在归档的 WAL 文件不同,则归档命令或归档库必须分别返回非零状态或false @@ -390,7 +386,7 @@ test ! -f /mnt/server/archivedir/00000001000000A900000065 && cp pg_wal/0 - 归档命令或归档函数只会在完整的 WAL 段上被调用。因此,如果服务器产生的 WAL 流量很小(或者存在低谷期),事务完成到其被安全写入归档存储之间可能会有很长延迟。为了限制未归档数据可能有多旧,你可以设置,强制服务器至少隔这么长时间切换到一个新的 WAL 段文件。注意,由强制切换而提前归档的文件长度仍与装满的文件相同。因此,把archive_timeout设得很短并不明智,这会使归档存储膨胀。archive_timeout设为大约 1 分钟通常是合理的。 + 归档命令或归档函数只会针对已完成的 WAL 段调用。因此,如果服务器产生的 WAL 流量很小(或者存在低谷期),事务完成到其被安全写入归档存储之间可能会有很长延迟。为了限制未归档数据可能有多旧,你可以设置,使服务器强制切换到新 WAL 段文件的间隔不超过这个值。注意,由强制切换而提前归档的文件长度仍与装满的文件相同。因此,把archive_timeout设得很短并不明智,这会使归档存储膨胀。archive_timeout设为大约 1 分钟通常是合理的。 @@ -438,7 +434,7 @@ test ! -f /mnt/server/archivedir/00000001000000A900000065 && cp pg_wal/0 - 恢复增量备份时,不仅需要增量备份本身,还必须具有所有更早的备份,以便提供增量备份中省略的那些块。关于这项要求的更多信息见。请注意,当集簇的校验和状态发生变化时,使用pg_combinebackup会受到限制;参见pg_combinebackup limitations。 + 恢复增量备份时,不仅需要增量备份本身,还必须具有提供增量备份中省略的块所需的所有较早备份。关于这项要求的更多信息见。请注意,当集簇的校验和状态发生变化时,使用pg_combinebackup会受到限制;参见pg_combinebackup 的限制。 @@ -446,7 +442,7 @@ test ! -f /mnt/server/archivedir/00000001000000A900000065 && cp pg_wal/0 - 增量备份通常只对相对较大的数据库有意义,因为其中相当一部分数据不变,或者变化缓慢。对于小数据库,忽略增量备份的存在而直接进行完整备份会更简单,也更容易管理。对于所有数据都被频繁修改的大数据库,增量备份也不会比完整备份小多少。 + 增量备份通常只对相当一部分数据不变或变化缓慢的较大数据库有意义。对于小数据库,忽略增量备份的存在而直接进行完整备份会更简单,也更容易管理。对于所有数据都被频繁修改的大数据库,增量备份也不会比完整备份小多少。 @@ -610,7 +606,7 @@ SELECT * FROM pg_backup_stop(wait_for_archive => true); - 这一切的关键在于设置一个恢复配置,描述你希望如何恢复,以及恢复应运行到什么位置。其中绝对必须指定的一项是restore_command,它告诉PostgreSQL如何检索已归档的 WAL 文件段。像archive_command一样,它也是一个 shell 命令字符串。它可以包含%f,会被替换为所需 WAL 文件的名称;也可以包含%p,会被替换为复制该 WAL 文件时要使用的路径名。(该路径名相对于当前工作目录,也就是集簇的数据目录。)如果需要在命令中嵌入实际的%字符,请写成%%。最简单而有用的命令类似如下: + 这一切的关键在于设置一个恢复配置,描述你希望如何恢复,以及恢复应运行到什么位置。其中绝对必须指定的一项是restore_command,它告诉PostgreSQL如何检索已归档的 WAL 段文件。像archive_command一样,它也是一个 shell 命令字符串。它可以包含%f,会被替换为所需 WAL 文件的名称;也可以包含%p,会被替换为复制该 WAL 文件时要使用的路径名。(该路径名相对于当前工作目录,也就是集簇的数据目录。)如果需要在命令中嵌入实际的%字符,请写成%%。最简单而有用的命令类似如下: restore_command = 'cp /mnt/server/archivedir/%f %p' @@ -618,11 +614,11 @@ restore_command = 'cp /mnt/server/archivedir/%f %p' - 重要的是,该命令在失败时必须返回非零退出状态。系统调用该命令来请求归档中不存在的文件;遇到这种情况时,它就应返回非零值。这不是一种错误情况。例外是,如果该命令被信号终止(用于数据库服务器关闭的SIGTERM除外),或者因 shell 错误(如命令未找到)而失败,那么恢复将中止,服务器也不会启动。 + 重要的是,该命令在失败时必须返回非零退出状态。系统调用该命令来请求归档中不存在的文件;遇到这种情况时,它必须返回非零值。这不是一种错误情况。例外是,如果该命令被信号终止(用于数据库服务器关闭的SIGTERM除外),或者因 shell 错误(如命令未找到)而失败,那么恢复将中止,服务器也不会启动。 - 被请求的文件并不全都是 WAL 段文件;你还应预期会收到对带有.history后缀文件的请求。另外请注意,%p路径的基本文件名会与%f不同;不要指望它们可以互换使用。 + 被请求的文件并不全都是 WAL 段文件;你还应预期会收到对带有.history后缀文件的请求。另外请注意,%p路径的文件名部分会与%f不同;不要指望它们可以互换使用。 @@ -630,16 +626,16 @@ restore_command = 'cp /mnt/server/archivedir/%f %p' - 通常,恢复会处理完所有可用的 WAL 段,从而把数据库恢复到当前时间点(或者在可用 WAL 段所允许的情况下尽可能接近当前时间点)。因此,一次正常恢复通常会以一条file not found消息结束,具体错误文本取决于你选择的restore_command。在恢复开始时,你也可能看到一条针对类似00000001.history文件的错误消息。这同样是正常的,在简单恢复场景中并不表示有问题;相关讨论见。 + 通常,恢复会处理完所有可用的 WAL 段,从而把数据库恢复到当前时间点(或者在可用 WAL 段所允许的情况下尽可能接近当前时间点)。因此,一次正常恢复会以一条file not found消息结束,具体错误文本取决于你选择的restore_command。在恢复开始时,你也可能看到一条针对类似00000001.history文件的错误消息。这同样是正常的,在简单恢复场景中并不表示有问题;相关讨论见 - 如果你希望恢复到过去的某个时间点(例如恢复到那位初级 DBA 删掉你的主事务表之前),只需指定所需的停止点即可。这个停止点也称为恢复目标,可以通过日期/时间、命名恢复点或者某个特定事务 ID 完成时刻来指定。在目前的实现下,只有日期/时间和命名恢复点这两种方式真正比较实用,因为没有工具能够帮助你足够准确地识别应使用哪个事务 ID。 + 如果你希望恢复到过去的某个时间点(例如恢复到那位初级 DBA 删掉你的主事务表之前),只需指定所需的停止点即可。这个停止点也称为恢复目标,可以通过日期/时间、命名恢复点或者某个特定事务 ID 完成时刻来指定。在撰写本文时,只有日期/时间和命名恢复点这两种方式真正比较实用,因为没有工具能够帮助你足够准确地识别应使用哪个事务 ID。 - 停止点必须晚于基础备份的结束时间,也就是pg_backup_stop的结束时间。你不能用某次基础备份恢复到该备份仍在进行中的时间点。(若要恢复到这样的时间点,必须回到更早的一次基础备份,再从那里向前滚动。) + 停止点必须晚于基础备份的结束时间,也就是pg_backup_stop的结束时间。你不能用某次基础备份恢复到该备份仍在进行中的时间点。(若要恢复到这样的时间点,必须回到更早的一次基础备份,再从那里向前重放日志。) @@ -653,12 +649,10 @@ restore_command = 'cp /mnt/server/archivedir/%f %p' 时间线 - timelines + 时间线 - - 把数据库恢复到过去某个时间点的能力,会带来一些复杂性,颇有点像关于时间旅行和平行宇宙的科幻小说。例如,在数据库的原始历史中,假设你在星期二晚上 5:15 删掉了一张关键表,但直到星期三中午才意识到自己的错误。于是你拿出备份,把系统恢复到星期二晚上 5:14,并重新上线运行。在数据库宇宙的这条历史中,你从未删掉那张表。但如果你后来发现这并不是个好主意,并且想回到原始历史中的星期三上午某个时间点,就办不到了,因为在数据库重新上线运行期间,它可能已经覆盖了某些 WAL 段文件,而这些文件本来能把你带回到现在想回去的那个时刻。因此,为了避免这种情况,你需要把时间点恢复之后生成的那一串 WAL 记录,与数据库原始历史中生成的那些 WAL 记录区分开来。 - + 能够将数据库恢复到过去某个时间点,也会带来一些类似科幻故事中时间旅行和平行宇宙的复杂情况。例如,假设在数据库原来的历史中,你在周二下午 5:15 删除了一张重要的表,直到周三中午才发现错误。你从容地取出备份,将数据库恢复到周二下午 5:14,然后重新投入运行。在数据库宇宙的这段历史中,你从未删除过那张表。但假设你后来发现这样做不太合适,希望回到原来历史中的周三上午某个时刻。如果数据库恢复运行后覆盖了通往该时刻所需的某些 WAL 段文件,就无法回去了。因此,为了避免这种情况,需要区分时间点恢复后产生的一系列 WAL 记录与数据库原来历史中产生的记录。 为了解决这个问题,PostgreSQL引入了时间线的概念。每当一次归档恢复完成时,系统都会创建一条新的时间线,用来标识此次恢复之后生成的 WAL 记录序列。时间线 ID 是 WAL 段文件名的一部分,因此新的时间线不会覆盖先前时间线产生的 WAL 数据。例如,在 WAL 文件名0000000100001234000055CD中,开头的00000001就是十六进制表示的时间线 ID。(注意,在服务器日志消息等其他场合,时间线 ID 通常以十进制打印。) @@ -672,9 +666,7 @@ restore_command = 'cp /mnt/server/archivedir/%f %p' 每当创建一条新的时间线时,PostgreSQL都会创建一个时间线历史文件,记录它是从哪条时间线、在何时分叉出来的。当从包含多条时间线的归档中恢复时,这些历史文件对于系统选取正确的 WAL 段文件是必需的。因此,它们会像 WAL 段文件一样被归档到 WAL 归档区域。历史文件只是很小的文本文件,因此长期保存它们既便宜也合适(而段文件通常很大)。如果你愿意,还可以在历史文件中加入注释,记录创建这条时间线的方式和原因。当你因实验而积累出一批错综复杂的时间线时,这类注释会特别有价值。 - - 恢复的默认行为是恢复到归档中找到的最新时间线。如果你希望恢复到执行基础备份时的当前时间线,或者恢复到某个指定的子时间线(也就是说,你想回到某个本身就是在一次恢复尝试之后才产生的状态),就需要指定current,或者在中指定目标时间线 ID。你不能恢复到那些在基础备份之前就已经分叉出去的时间线。 - + 默认的恢复行为是恢复到归档中找到的最新时间线。如果希望恢复到制作基础备份时的当前时间线,或者某条特定的子时间线(即希望返回到一次恢复尝试之后产生的某个状态),需要在 中指定 current 或目标时间线 ID。不能恢复到在基础备份之前就已分支出去的时间线。 @@ -685,14 +677,14 @@ restore_command = 'cp /mnt/server/archivedir/%f %p' - 单机热备份 + 独立热备份 - 可以利用PostgreSQL的备份设施生成单机热备份。这些备份不能用于时间点恢复,但它们的制作和恢复通常都比pg_dump转储快得多。(它们也比pg_dump转储大得多,因此在某些情况下速度优势可能会被抵消。) + 可以利用PostgreSQL的备份设施生成独立热备份。这些备份不能用于时间点恢复,但它们的制作和恢复通常都比pg_dump转储快得多。(它们也比pg_dump转储大得多,因此在某些情况下速度优势可能会被抵消。) - 和基础备份一样,生成单机热备份最简单的方法是使用工具。如果在调用它时包含-X参数,使用该备份所需的全部预写式日志都会自动包含在备份中,恢复该备份时也不需要额外动作。 + 和基础备份一样,生成独立热备份最简单的方法是使用工具。如果在调用它时包含-X参数,使用该备份所需的全部预写式日志都会自动包含在备份中,恢复该备份时也不需要额外动作。 @@ -723,7 +715,7 @@ archive_command = 'local_backup_script.sh "%p" "%f"' - 脚本中可能需要解决的需求示例包括: + 可以在脚本中处理的需求示例包括: @@ -732,7 +724,7 @@ archive_command = 'local_backup_script.sh "%p" "%f"' - 把 WAL 文件成批处理,使其每三个小时传输一次,而不是每生成一个就传一次 + 把 WAL 文件成批处理,使其每三个小时传输一次,而不是每次只传输一个 diff --git a/zh/17/brin.sgml b/zh/17/brin.sgml index cc6cc7b1..deeaac0f 100644 --- a/zh/17/brin.sgml +++ b/zh/17/brin.sgml @@ -4,7 +4,7 @@ BRIN 索引 - index + 索引 BRIN @@ -25,8 +25,7 @@ - 如果索引中存储的摘要信息与查询条件相一致BRIN - 索引就可以通过常规位图索引扫描来满足查询,并返回每个范围内所有页上的全部元组。 + BRIN 索引可以通过常规位图索引扫描来满足查询;对于每个范围,如果索引中存储的摘要信息与查询条件相一致,就会返回该范围内所有页上的全部元组。 查询执行器负责重新检查这些元组,并丢弃不匹配查询条件的元组 — 换句话说,这些索引是有损的。 由于 BRIN 索引非常小,与顺序扫描相比,扫描索引只会带来很小的额外开销, 但可以避免扫描那些已知不包含匹配元组的大块表数据。 @@ -85,7 +84,7 @@ 当启用自动摘要时,一旦检测到向下一个块范围第一页的第一项执行了插入, - 就会向 autovacuum 发送请求,要求对该块范围执行定向摘要。 + 就会向 autovacuum 发送请求,要求对前一个块范围执行定向摘要。 该请求会在同一数据库中的某个 autovacuum 工作进程下一次结束运行时得到处理。 如果请求队列已满,该请求就不会被记录,并会向服务器日志发送一条消息: @@ -790,13 +789,13 @@ LOG: request for BRIN range summarization for index "brin_wi_idx" page 128 was typedef struct BrinOpcInfo { - /* Number of columns stored in an index column of this opclass */ + /* 此操作符类在一个索引列中存储的列数 */ uint16 oi_nstored; - /* Opaque pointer for the opclass' private use */ + /* 供操作符类私有使用的不透明指针 */ void *oi_opaque; - /* Type cache entries of the stored columns */ + /* 所存储列的类型缓存条目 */ TypeCacheEntry *oi_typcache[FLEXIBLE_ARRAY_MEMBER]; } BrinOpcInfo; @@ -1012,62 +1011,62 @@ typedef struct BrinOpcInfo 操作符策略 1 - left-of 操作符 + 位于左侧的操作符 操作符策略 4 操作符策略 2 - does-not-extend-to-the-right-of 操作符 + 不延伸到右侧的操作符 操作符策略 5 操作符策略 3 - overlaps 操作符 + 重叠操作符 操作符策略 4 - does-not-extend-to-the-left-of 操作符 + 不延伸到左侧的操作符 操作符策略 1 操作符策略 5 - right-of 操作符 + 位于右侧的操作符 操作符策略 2 - 操作符策略 6, 18 - same-as-or-equal-to 操作符 + 操作符策略 6、18 + 相同或等于操作符 操作符策略 7 - 操作符策略 7, 16, 24, 25 - contains-or-equal-to 操作符 + 操作符策略 7、16、24、25 + 包含或等于操作符 - 操作符策略 8, 26, 27 - is-contained-by-or-equal-to 操作符 + 操作符策略 8、26、27 + 被包含或等于操作符 操作符策略 3 操作符策略 9 - does-not-extend-above 操作符 + 不延伸到上方的操作符 操作符策略 11 操作符策略 10 - is-below 操作符 + 位于下方的操作符 操作符策略 12 操作符策略 11 - is-above 操作符 + 位于上方的操作符 操作符策略 9 操作符策略 12 - does-not-extend-below 操作符 + 不延伸到下方的操作符 操作符策略 10 @@ -1113,12 +1112,12 @@ typedef struct BrinOpcInfo 要为仅实现等值操作符且支持哈希的数据类型编写操作符类,可以按 - 所示,将 bloom 支持过程与相应操作符一起使用。 - 所有操作符类成员(过程和操作符)都是必需的。 + 所示,将 bloom 支持函数与相应操作符一起使用。 + 所有操作符类成员(函数和操作符)都是必需的。 - bloom 操作符类的过程和支持编号 + bloom 操作符类的函数和支持编号 @@ -1128,28 +1127,28 @@ typedef struct BrinOpcInfo - 支持过程 1 + 支持函数 1 内部函数brin_bloom_opcinfo() - 支持过程 2 + 支持函数 2 内部函数brin_bloom_add_value() - 支持过程 3 + 支持函数 3 内部函数brin_bloom_consistent() - 支持过程 4 + 支持函数 4 内部函数brin_bloom_union() - 支持过程 5 + 支持函数 5 内部函数brin_bloom_options() - 支持过程 11 - 计算元素哈希值的函数 + 支持函数 11 + 计算元素 hash 值的函数 操作符策略 1 @@ -1160,20 +1159,20 @@ typedef struct BrinOpcInfo
- 支持过程编号 1 至 10 保留给 BRIN 内部函数,因此 SQL 层函数从编号 11 开始。 + 支持函数编号 1 至 10 保留给 BRIN 内部函数,因此 SQL 层函数从编号 11 开始。 支持函数 11 是构建索引所需的主要函数。 - 它应接受一个与操作符类数据类型相同的参数,并返回该值的哈希值。 + 它应接受一个与操作符类数据类型相同的参数,并返回该值的 hash 值。 minmax-multi 操作符类也面向实现全序集的数据类型,可以看作 minmax 操作符类的简单扩展。 minmax 操作符类把每个块范围中的值摘要为单个连续区间,而 minmax-multi 则允许将其摘要为多个较小区间,以改进对离群值的处理。 - 可以按 所示,将 minmax-multi 支持过程与相应操作符一起使用。 - 所有操作符类成员(过程和操作符)都是必需的。 + 可以按 所示,将 minmax-multi 支持函数与相应操作符一起使用。 + 所有操作符类成员(函数和操作符)都是必需的。 - minmax-multi 操作符类的过程和支持编号 + minmax-multi 操作符类的函数和支持编号 @@ -1183,27 +1182,27 @@ typedef struct BrinOpcInfo - 支持过程 1 + 支持函数 1 内部函数brin_minmax_multi_opcinfo() - 支持过程 2 + 支持函数 2 内部函数brin_minmax_multi_add_value() - 支持过程 3 + 支持函数 3 内部函数brin_minmax_multi_consistent() - 支持过程 4 + 支持函数 4 内部函数brin_minmax_multi_union() - 支持过程 5 + 支持函数 5 内部函数brin_minmax_multi_options() - 支持过程 11 + 支持函数 11 计算两个值之间距离(范围长度)的函数 diff --git a/zh/17/btree.sgml b/zh/17/btree.sgml index 99f5f71f..82bc9f65 100644 --- a/zh/17/btree.sgml +++ b/zh/17/btree.sgml @@ -4,7 +4,7 @@ B-树索引 - index + 索引 B-树 @@ -18,10 +18,10 @@ - 由于每个 B-树 操作符类都会为其数据类型施加一种排序顺序,B-树 + 由于每个 B-树操作符类都会为其数据类型施加一种排序顺序,B-树 操作符类(更准确地说,是操作符族)已经成为 PostgreSQL 用来统一表示和理解排序语义的方式。因此,它们具备了一些超出单纯支持 - B-树 索引所需范围的特性,系统中某些与 btree AM + B-树索引所需范围的特性,系统中某些与 B-树 AM 相距甚远的部分也会利用它们。 @@ -55,7 +55,7 @@ - = 操作符必须是一种等价关系;也就是说,对于该数据类型的所有非空值 + = 操作符必须是一种等价关系;也就是说,对于该数据类型的所有非 null 值 ABC: @@ -93,7 +93,7 @@ - < 操作符必须是一种强排序关系;也就是说,对于所有非空值 + < 操作符必须是一种强排序关系;也就是说,对于所有非 null 值 ABC: @@ -123,7 +123,7 @@ - 此外,该顺序还是全序的;也就是说,对于所有非空值 + 此外,该顺序还是全序的;也就是说,对于所有非 null 值 AB: @@ -177,18 +177,18 @@ B-树支持函数 - 如所示,btree 定义了一个必需和四个可选的支持函数。五个用户定义的方法如下: + 如所示,B-树定义了一个必需和四个可选的支持函数。五个用户定义的方法如下: order - 对于 B-树 操作符族为其提供比较操作符的每一种数据类型组合,都必须提供一个比较支持函数。该函数在 + 对于 B-树操作符族为其提供比较操作符的每一种数据类型组合,都必须提供一个比较支持函数。该函数在 pg_amproc 中注册,支持函数编号为 1,并且 amproclefttype/amprocrighttype 要等于该比较的左右数据类型(也就是与匹配操作符在 - pg_amop 中注册时相同的数据类型)。比较函数必须接受两个非空值 + pg_amop 中注册时相同的数据类型)。比较函数必须接受两个非 null 值 AB,并返回一个 int32 值,其值为 < 0、 @@ -197,12 +197,12 @@ < BA = BA - > B。不允许返回空值:该数据类型的所有值都必须可比较。示例见 + > B。不允许返回 null:该数据类型的所有值都必须可比较。示例见 src/backend/access/nbtree/nbtcompare.c - 如果参与比较的值属于可排序数据类型,则会通过标准的 + 如果参与比较的值属于支持排序规则的数据类型,则会通过标准的 PG_GET_COLLATION() 机制,把适当的排序规则 OID 传递给比较支持函数。 @@ -223,11 +223,11 @@ in_range - in_range support functions + in_range 支持函数 - support functions + 支持函数 in_range @@ -266,7 +266,7 @@ returns bool - in_range 函数的核心语义取决于这两个 Boolean + in_range 函数的核心语义取决于这两个布尔 标志参数。它应当先对 baseoffset 做加法或减法,再把 val 与结果比较,具体如下: @@ -383,7 +383,7 @@ returns bool - 如果被排序的类型(type1)属于可排序数据类型,则会通过标准的 + 如果被排序的类型(type1)属于支持排序规则的数据类型,则会通过标准的 PG_GET_COLLATION() 机制,把适当的排序规则 OID 传递给 in_range 函数。 @@ -408,12 +408,7 @@ returns bool equalimage(opcintype oid) returns bool - 返回值是关于某个操作符类及其排序规则的静态信息。返回 - true 表示:该操作符类的 - order 函数被保证只有在返回 - 0arguments are equal)时,其 - AB - 参数才是可以互换而不损失任何语义信息的。如果未注册 + 返回值是关于某个操作符类及其排序规则的静态信息。返回 true 表示可以保证:该操作符类的 order 函数只有在其 AB 参数也能够互换而不损失任何语义信息时,才会返回 0参数相等)。如果未注册 equalimage 函数,或其返回 false,就表示不能假定该条件成立。 @@ -421,7 +416,7 @@ equalimage(opcintype oid) returns bool opcintype 参数是该操作符类所索引数据类型的 pg_type.oid。这只是为了方便在不同操作符类之间复用同一个底层 equalimage 函数。如果 - opcintype 是可排序数据类型,则会通过标准的 + opcintype 是支持排序规则的数据类型,则会通过标准的 PG_GET_COLLATION() 机制,把适当的排序规则 OID 传递给 equalimage 函数。 @@ -453,7 +448,7 @@ equalimage(opcintype oid) returns bool 发行版中包含的操作符类遵循的惯例是:注册一个现成的通用 equalimage 函数。大多数操作符类注册 btequalimage(),这表示去重在无条件下都是安全的。像 - text 这样可排序数据类型的操作符类会注册 + text 这样支持排序规则的数据类型的操作符类会注册 btvarstrequalimage(),这表示在确定性排序规则下去重是安全的。第三方扩展的最佳实践则是注册它们自己的自定义函数,以保留控制权。 @@ -527,7 +522,7 @@ options(relopts local_relopts *) returns B-树索引会通过执行自底向上索引删除轮次,增量地删除这类版本频繁更替产生的索引元组。每一轮删除都是因预期中的版本频繁更替页拆分而触发的。这只会发生在那些没有被 - UPDATE 语句逻辑修改的索引上,否则过时版本就会集中积累在某些特定页面中。通常可以避免页拆分,不过也可能出现某些实现层面的启发式规则甚至一个垃圾索引元组都识别不出来、删不掉的情况(这时就要靠页拆分或一次去重轮次来解决新元组放不进叶页的问题)。任何一次索引扫描在单个逻辑行上必须穿越的最坏版本数,是影响整个系统响应能力和吞吐量的重要因素。一次自底向上索引删除轮次会基于涉及逻辑行与版本的定性区别,针对单个叶页中疑似垃圾的元组。这与自动清理工作进程执行的自顶向下索引清理不同,后者是在超出某些定量的表级阈值时触发的(见)。 + UPDATE 语句逻辑修改的索引上;如果不执行这类删除,过时版本就会集中积累在某些特定页面中。通常可以避免页拆分,不过也可能出现某些实现层面的启发式规则甚至一个垃圾索引元组都识别不出来、删不掉的情况(这时就要靠页拆分或一次去重轮次来解决新元组放不进叶页的问题)。任何一次索引扫描在单个逻辑行上必须穿越的最坏版本数,是影响整个系统响应能力和吞吐量的重要因素。一次自底向上索引删除轮次会基于涉及逻辑行与版本的定性区别,针对单个叶页中疑似垃圾的元组。这与自动清理工作进程执行的自顶向下索引清理不同,后者是在超出某些定量的表级阈值时触发的(见)。 @@ -567,7 +562,7 @@ options(relopts local_relopts *) returns 去重通过周期性地把一组组重复元组合并起来,为每一组形成一个 - posting list 元组。在这种表示中,列键值只出现一次,后面跟着一个排好序的 + 倒排列表 元组。在这种表示中,列键值只出现一次,后面跟着一个排好序的 TID 数组,指向表中的各行。这能显著减小那些每个值(或每一种不同列值组合)平均会出现多次的索引的存储大小。查询延迟可能显著降低,整体查询吞吐量也可能显著提升,例行索引清理的开销同样可能显著减少。 @@ -581,14 +576,14 @@ options(relopts local_relopts *) returns 去重过程是惰性发生的:当插入一个放不进现有叶页的新项时,只有在索引元组删除也无法为该新项释放足够空间的情况下,才会进行去重(通常只会短暂考虑删除,然后就跳过)。与 - GIN 的 posting list 元组不同,B-树的 posting list - 元组不需要在每次插入新的重复项时都扩展;它们只是叶页原始逻辑内容的一种替代物理表示。这种设计优先考虑混合读写工作负载下的一致性能。大多数客户端应用至少都能从去重中获得适度的性能收益。去重默认启用。 + GIN 的倒排列表元组不同,B-树的倒排列表 + 元组不需要在每次插入新的重复项时都扩展;它们只是叶页原始逻辑内容的一种替代物理表示。这种设计优先考虑混合读写工作负载下的稳定性能。大多数客户端应用至少都能从去重中获得适度的性能收益。去重默认启用。 CREATE INDEXREINDEX - 都会应用去重来创建 posting list - 元组,只是两者采用的策略略有不同。对于从表中取出的已排序输入中遇到的每一组普通重复元组,都会在被加入当前待写入叶页之前先合并成一个 - posting list 元组。每个 posting list 元组都会尽量容纳更多的 + 都会应用去重来创建倒排列表 + 元组,不过它们采用的策略与上述过程略有不同。对于从表中取出的已排序输入中遇到的每一组普通重复元组,都会在被加入当前待写入叶页之前先合并成一个 + 倒排列表元组。每个倒排列表元组都会尽量容纳更多的 TID。叶页按通常方式写出,不需要额外独立的去重过程。由于 CREATE INDEXREINDEX 都是一次性的批处理操作,这种策略非常适合它们。 @@ -597,14 +592,14 @@ options(relopts local_relopts *) returns 如果某个写密集型工作负载由于索引中的重复值很少甚至没有,而无法从去重中获益,那么它会承担很小且固定的性能损耗(除非显式禁用去重)。 deduplicate_items 存储参数可用于在单个索引内禁用去重。而只读工作负载绝不会因此遭受性能损失,因为读取 - posting list 元组至少与读取标准元组表示一样高效。禁用去重通常并没有帮助。 + 倒排列表元组至少与读取标准元组表示一样高效。禁用去重通常并没有帮助。 有时唯一索引(以及唯一约束)也可以使用去重。这允许叶页临时吸收因版本频繁更替产生的额外重复项。唯一索引中的去重能够增强自底向上索引删除,特别是在长事务持有阻塞垃圾回收的快照时。其目标是为自底向上索引删除策略再次发挥作用争取时间。把页拆分推迟到某个单独的长事务自然结束之后,可能使一次自底向上删除轮次在较早一次失败的地方获得成功。 - 系统会应用一种特殊的启发式规则,来判定唯一索引中是否应当执行一次去重轮次。它往往可以直接跳到拆分叶页,从而避免把周期浪费在无益的去重过程中而造成性能损耗。如果你担心去重的开销,可以考虑有选择地设置 + 系统会应用一种特殊的启发式规则,来判定唯一索引中是否应当执行一次去重轮次。它往往可以直接跳到拆分叶页,从而避免把处理器周期浪费在无益的去重过程中而造成性能损耗。如果你担心去重的开销,可以考虑有选择地设置 deduplicate_items = off。在唯一索引中保持去重启用,坏处很小。 @@ -628,7 +623,7 @@ options(relopts local_relopts *) returns numeric 不能使用去重。必须保留相等的 datum - 之间的小数位数。 + 之间的显示小数位数。 diff --git a/zh/17/catalogs.sgml b/zh/17/catalogs.sgml index deba1761..9ff7716f 100644 --- a/zh/17/catalogs.sgml +++ b/zh/17/catalogs.sgml @@ -678,7 +678,7 @@ t = 表(包括物化视图), - i = 索引. + i = 索引。 @@ -931,7 +931,7 @@
- amproclefttypeamprocrighttype列的通常解释是它们标识了一个特定支持过程所支持的操作符的左右输入类型。对于某些访问方法它们和支持过程本身的输入数据类型相匹配,而对其他的则不会匹配。对于一个索引有一个默认支持过程的概念,这些支持过程的amproclefttypeamprocrighttype都等于索引操作符类的opcintype。 + amproclefttypeamprocrighttype列的通常解释是它们标识了一个特定支持函数所支持的操作符的左右输入类型。对于某些访问方法它们和支持函数本身的输入数据类型相匹配,而对其他的则不会匹配。对于一个索引有一个默认支持函数的概念,这些支持函数的amproclefttypeamprocrighttype都等于索引操作符类的opcintype
@@ -1101,7 +1101,7 @@
atttypmod记录了在表创建时提供的类型相关数据(例如一个varchar列的最大长度)。 - 它会被传递给类型相关的输入函数和长度强制函数。对于那些不需要atttypmod的类型,这个值通常总是为-1。 + 它会被传递给类型相关的输入函数和长度强制转换函数。对于那些不需要atttypmod的类型,这个值通常为 -1。 @@ -1179,8 +1179,7 @@ atthasmissing bool
- 该列在行中完全缺失时会用到这个列的值,如果在行创建之后增加一个有非易失DEFAULT值的列,就会发生这种情况。 - 实际使用的值被存放在attmissingval列中。 + 此列有一个值,供该列在数据行中完全缺失时使用;在数据行创建之后添加带有非易失 DEFAULT 值的列时,就会出现这种情况。实际使用的值存储在 attmissingval 列中。 @@ -1209,7 +1208,7 @@ attisdropped bool
- 该列被删除且不再有效。一个删除的列仍然物理存在于表中,但是会被分析器忽略并因此无法通过SQL访问。 + 该列被删除且不再有效。一个删除的列仍然物理存在于表中,但是会被解析器忽略并因此无法通过SQL访问。 @@ -1237,7 +1236,7 @@ (引用 pg_collation.oid
- 该列被定义的排序规则,如果该列不是一个可排序数据类型则为0。 + 该列定义的排序规则;如果该列的数据类型不支持排序规则,则为零。 @@ -1260,7 +1259,7 @@ attacl aclitem[] - 列级访问权限, 如果此列上已有特别授予的权限 + 列级访问权限,如果此列上已有特别授予的权限 @@ -1288,7 +1287,7 @@ 这个列中是一个含有一个元素的数组,其中的值被用于该列在行中完全缺失时,如果在行创建之后增加一个有非易失DEFAULT值的列,就会发生这种情况。 - 只有当atthasmissing为真时才使用这个值。如果没有值则该列为空。 + 只有当atthasmissing为真时才使用这个值。如果没有值则该列为空值。 @@ -1296,9 +1295,7 @@ - 在一个被删除的列的pg_attribute的项中,atttypid被重置为0,但attlen以及其他从pg_type拷贝的域仍然有效。 - 这种安排用于处理一种情况,即被删除列的数据类型后来被删除,并且因此不再有相应的pg_type行。 - attlen和其他域可以被用来解释表的一行的内容。 + 在被删除列的 pg_attribute 条目中,atttypid 被重置为零,但 attlen 以及其他从 pg_type 复制的字段仍然有效。这种安排用于应对被删除列的数据类型后来也被删除、因而不再有相应 pg_type 行的情况。attlen 和其他字段可用于解释表中一行的内容。 @@ -1427,7 +1424,7 @@ rolconnlimit int4 - 对于可以登录的角色,本列设置该角色可以同时发起最大连接数。-1表示无限制。 + 对于可以登录的角色,本列设置该角色能够建立的最大并发连接数。-1 表示无限制。 @@ -1436,7 +1433,7 @@ rolpassword text - 加密后的密码;如果未设置则为空。其格式取决于所使用的加密方式。 + 加密后的密码;如果未设置则为空值。其格式取决于所使用的加密方式。 @@ -1445,7 +1442,7 @@ rolvaliduntil timestamptz - 密码过期时间(只用于密码鉴定),如果永不过期则为空 + 密码过期时间(仅用于密码认证);不设过期时间时为空值 @@ -1453,7 +1450,7 @@ - 对于一个MD5加密的密码,rolpassword列将由字符串md5后面跟上一个32字符的十六进制MD5哈希值构成。MD5哈希值将是该用户的密码串接上它们的用户名。例如,如果用户joe的密码是xyzzy,则PostgreSQL将存储xyzzyjoe的md5哈希。 + 对于一个MD5加密的密码,rolpassword列将由字符串md5后面跟上一个32字符的十六进制MD5哈希值构成。MD5 哈希值通过在用户密码后拼接用户名再计算得到。例如,如果用户joe的密码是xyzzy,则PostgreSQL将存储xyzzyjoe的md5哈希。 @@ -1584,7 +1581,7 @@ SCRAM-SHA-256$<iteration count>:&l - 需要注意的是,pg_cast并不表示系统知道如何执行的所有类型转换,它只包括那些不能从某些通用规则推导出的转换。例如,一个域及其基类型之间的转换并未显式地在pg_cast中展示。另一个重要的例外是自动的基于 I/O 的类型转换,它们通过数据类型自己的 I/O 函数来转换成(或者转换自)text或其他字符串类型,这些转换也没有显式地在pg_cast中表示。 + 需要注意的是,pg_cast并不表示系统知道如何执行的所有类型转换,它只包括那些不能从某些通用规则推导出的转换。例如,一个域及其基础类型之间的转换并未显式地在pg_cast中展示。另一个重要的例外是自动的基于 I/O 的类型转换,它们通过数据类型自己的 I/O 函数来转换成(或者转换自)text或其他字符串类型,这些转换也没有显式地在pg_cast中表示。 @@ -1689,7 +1686,7 @@ SCRAM-SHA-256$<iteration count>:&l - 目录pg_class描述了具有列或与表类似的其他对象。这包括索引(但请参见pg_index)、序列(但请参见pg_sequence)、视图、物化视图、复合类型和TOAST表;请参见relkind。 + 目录pg_class描述了表以及其他具有列或在其他方面与表类似的对象。这包括索引(但请参见pg_index)、序列(但请参见pg_sequence)、视图、物化视图、复合类型和TOAST表;请参见relkind。 在下面,当我们指的是所有这些类型的对象时,我们称之为关系(relations)。并非所有pg_class的列对所有关系类型都有意义。 @@ -1741,9 +1738,7 @@ SCRAM-SHA-256$<iteration count>:&l reltype oid (引用 pg_type.oid) - - 该关系可能对应的表行类型的数据类型 OID;对索引为 0,而序列和 TOAST 表没有pg_type项 - + 与此表的行类型对应的数据类型的 OID(如有);索引、序列和 TOAST 表没有pg_type项,此值为零 @@ -1862,7 +1857,7 @@ SCRAM-SHA-256$<iteration count>:&l relpersistence char - p = 永久表/序列, u = 不记录 WAL 的表/序列, + p = 永久表/序列,u = 不记录 WAL 的表/序列, t = 临时表/序列 @@ -1957,7 +1952,7 @@ SCRAM-SHA-256$<iteration count>:&l relispopulated bool - 如果表已被填充则为真(对于所有关系该列都为真,但对于某些物化视图却不是) + 如果关系已被填充则为真(对于所有关系该列都为真,但对于某些物化视图却不是) @@ -1999,7 +1994,7 @@ SCRAM-SHA-256$<iteration count>:&l relfrozenxid xid - 在此之前的所有事务ID在表中已经被替换为一个永久的(冻结的) 事务ID。 + 在此之前的所有事务ID在表中已经被替换为一个永久的(冻结的)事务ID。 这用于跟踪表是否需要被清理,以便阻止事务ID回卷或者允许pg_xact被收缩。 如果该关系不是一个表则为0(InvalidTransactionId)。 @@ -2010,7 +2005,7 @@ SCRAM-SHA-256$<iteration count>:&l relminmxid xid - 在此之前的多事务ID在表中已经被替换为一个事务ID。这被用于跟踪表是否需要被清理,以阻止 + 在此之前的所有多事务ID在表中已经被替换为一个事务ID。这被用于跟踪表是否需要被清理,以阻止 多事务ID回卷或者允许pg_multixact被收缩。如果关系不是一个表则 为0(InvalidMultiXactId)。 @@ -2039,7 +2034,7 @@ SCRAM-SHA-256$<iteration count>:&l relpartbound pg_node_tree - 如果表示一个分区(见relispartition),则为分区边界的内部表示 + 如果表是一个分区(见relispartition),则为分区边界的内部表示 @@ -2047,9 +2042,9 @@ SCRAM-SHA-256$<iteration count>:&l
- pg_class中的一些逻辑标志被以一种懒惰的方式维护:在正确状态时它们被保证为真,但是当条件不再为真时它们并不会被立刻重置为假。 + pg_class中的一些布尔标志采用延迟维护:当条件成立时,保证它们为真;但当条件不再成立时,可能不会立即将它们重置为假。 例如,relhasindexCREATE INDEX设置,但它从不会被DROP INDEX清除。 - 作为替代,VACUUM会在找到无索引表后清除其relhasindex。 + 作为替代,VACUUM会在找到无索引表后清除其relhasindex。 这种安排避免了竞争条件并且提高了并发性。 @@ -2123,9 +2118,10 @@ SCRAM-SHA-256$<iteration count>:&l collprovider char - 排序规则提供者:d = 数据库默认值, + 排序规则提供程序:d = 数据库默认值, b = builtin,c = libc, - i = icu + i = icu + @@ -2151,7 +2147,7 @@ SCRAM-SHA-256$<iteration count>:&l collcollate text - 此排序规则对象的 LC_COLLATE。如果提供者不是 libc,则 collcollate 为 + 此排序规则对象的 LC_COLLATE。如果提供程序不是 libc,则 collcollateNULL,改用 colllocale @@ -2161,7 +2157,7 @@ SCRAM-SHA-256$<iteration count>:&l collctype text - 此排序规则对象的 LC_CTYPE。如果提供者不是 libc,则 collctype 为 + 此排序规则对象的 LC_CTYPE。如果提供程序不是 libc,则 collctypeNULL,改用 colllocale @@ -2171,7 +2167,7 @@ SCRAM-SHA-256$<iteration count>:&l colllocale text - 此排序规则对象的提供者区域设置名称。如果提供者是 libc, + 此排序规则对象的提供程序区域设置名称。如果提供程序是 libc, 则 colllocaleNULL; 改用 collcollatecollctype。 @@ -2192,7 +2188,7 @@ SCRAM-SHA-256$<iteration count>:&l collversion text - 排序规则的提供者相关的版本。这是在排序规则创建时记录下来的,并且在使用排序规则时会被检查以检测可能导致数据损坏的排序规则定义的改变。 + 提供程序特有的排序规则版本。它会在创建排序规则时记录下来,并在使用时接受检查,以检测可能导致数据损坏的排序规则定义更改。 @@ -2500,10 +2496,7 @@ SCRAM-SHA-256$<iteration count>:&l conexclop oid[] (引用 pg_operator.oid) - - 如果是排他约束或 WITHOUT OVERLAPS - 主键/唯一约束,则这里列出每列的排他操作符。 - + 如果是排他约束,则列出每列的排他操作符 @@ -2519,9 +2512,9 @@ SCRAM-SHA-256$<iteration count>:&l - 在一个排他约束的情况中, conkey只对约束元素是单一列引用时有用。 - 对于其他情况,conkey为0且必须查阅相关索引来发现被约束的表达式。 - (对于索引,conkey因此和pg_index.indkey具有相同的内容)。 + 对于排他约束,conkey仅对作为简单列引用的约束元素有用。 + 对于其他情况,conkey中会出现一个 0,必须查阅关联索引来确定被约束的表达式。 + (因此,conkey与该索引的 pg_index.indkey具有相同的内容。) @@ -2715,8 +2708,9 @@ SCRAM-SHA-256$<iteration count>:&l datlocprovider char - 此数据库的区域设置提供者:b = builtin, - c = libc,i = icu + 此数据库的区域设置提供程序:b = builtin, + c = libc,i = icu + @@ -2815,7 +2809,7 @@ SCRAM-SHA-256$<iteration count>:&l datlocale text - 此数据库的提供者区域设置名称。如果提供者是 libc, + 此数据库的提供程序区域设置名称。如果提供程序是 libc, 则 datlocaleNULL; 改用 datcollatedatctype。 @@ -2836,7 +2830,7 @@ SCRAM-SHA-256$<iteration count>:&l datcollversion text - 该排序规则的提供者特定版本。它会在创建数据库时记录下来,并在使用时接受检查,以检测可能导致数据损坏的排序规则定义更改。 + 提供程序特有的排序规则版本。它会在创建数据库时记录下来,并在使用时接受检查,以检测可能导致数据损坏的排序规则定义更改。 @@ -3917,7 +3911,7 @@ SCRAM-SHA-256$<iteration count>:&l indisunique bool - 如为真, 这是唯一索引 + 如为真, 这是唯一索引 @@ -3926,8 +3920,8 @@ SCRAM-SHA-256$<iteration count>:&l indnullsnotdistinct bool - 该值只用于唯一索引。如果为 false,则该唯一索引会将 null 值视为非重复值(因此索引中可以包含多个 null 值,这是 PostgreSQL 的默认行为)。 - 如果为 true,则会将 null 值视为相等(因此索引中只能包含一个 null 值)。 + 该值只用于唯一索引。如果为 false,则该唯一索引会将 null 值视为彼此不同(因此索引的某一列中可以包含多个 null 值,这是 PostgreSQL 的默认行为)。 + 如果为 true,则会将 null 值视为相等(因此索引的某一列中只能包含一个 null 值)。 @@ -4035,7 +4029,7 @@ SCRAM-SHA-256$<iteration count>:&l (引用 pg_collation.oid - 对于索引键(indnkeyatts值)中的每一列,这包含要用于该索引的排序规则的OID,如果该列不是一种可排序数据类型则为零。 + 对于索引键(indnkeyatts值)中的每一列,这包含要用于该索引的排序规则的OID,如果该列的数据类型不支持排序规则则为零。 @@ -5107,7 +5101,7 @@ SCRAM-SHA-256$<iteration count>:&l (引用 pg_collation.oid - 对于分区键中的每一个列,这个域包含要用于分区的排序规则的OID,如果该列不是一种可排序数据类型则为零。 + 对于分区键中的每一个列,这个域包含要用于分区的排序规则的OID,如果该列的数据类型不支持排序规则则为零。 @@ -5939,7 +5933,11 @@ SCRAM-SHA-256$<iteration count>:&l - rngsubopc (加上rngcollation,如果元素类型是可排序的)决定了被该范围类型所使用的排序顺序。rngcanonical用于离散类型的元素类型。rngsubdiff是可选的,但是提供它可以提高范围类型上的GiST索引性能。 + rngsubopc(如果元素类型支持排序规则,则还包括 + rngcollation)决定范围类型所用的排序顺序。 + rngcanonical用于元素类型为离散类型的情况。 + rngsubdiff是可选的,但应当提供它, + 以提高范围类型上的 GiST 索引性能。 @@ -6627,8 +6625,8 @@ SCRAM-SHA-256$<iteration count>:&l 通常,每个已分析的表列都有一个条目,其中stainherit = false。 - 如果表具有继承子项或分区,则还会创建第二个条目,其中stainherit = true。 - 此行表示继承树上列的统计信息,即您可以通过SELECT column FROM table*看到的数据的统计信息, + 如果表具有继承子表或分区,则还会创建第二个条目,其中stainherit = true。 + 此行表示继承树上列的统计信息,即你可以通过SELECT column FROM table*看到的数据的统计信息, 而stainherit = false行表示SELECT column FROM ONLY table的结果。 @@ -6637,7 +6635,7 @@ SCRAM-SHA-256$<iteration count>:&l - 因为不同类型的统计信息适用于不同类型的数据, pg_statistic 被设计成不太在意自己存储的是什么类型的统计。 只有极为常用的统计信息(比如NULL的含量)才在pg_statistic里给予专用的字段。 其它所有东西都存储在槽位中,而槽位是一组相关的列, 它们的内容用槽位中的一个列里的代码表示。 更详细的信息请参阅 src/include/catalog/pg_statistic.h。 + 由于不同种类的数据可能适合不同种类的统计信息,pg_statistic 在设计上尽量不对所存储的统计信息种类作出假定。只有极为通用的统计信息(例如空值情况)才在 pg_statistic 中有专用的列。其余统计信息都存储在槽位中。每个槽位都是一组相关的列,其内容由其中一列的代码编号来标识。更多信息见 src/include/catalog/pg_statistic.h @@ -6693,7 +6691,7 @@ SCRAM-SHA-256$<iteration count>:&l stanullfrac float4 - 列的项为空的比例 + 列中空值所占的比例 @@ -6711,8 +6709,8 @@ SCRAM-SHA-256$<iteration count>:&l stadistinct float4 - 列中非空唯一值的数目。一个大于零的值是唯一值的真正数目。 - 一个小于零的值是表中行数的乘数的负值;例如,对于一个 80% 的值为非空且每个非空值平均出现两次的列,可以表示为stadistinct = -0.4。一个0值表示唯一值的数目未知。 + 列中不同非空数据值的数量。一个大于零的值是不同值的真正数目。 + 一个小于零的值是表中行数的乘数的负值;例如,对于一个约 80% 的值为非空且每个非空值平均出现两次的列,可以表示为stadistinct = -0.4。一个0值表示不同值的数目未知。 @@ -6743,8 +6741,8 @@ SCRAM-SHA-256$<iteration count>:&l (引用 pg_collation.oid - 用于导出存储在第N槽位中的统计信息的排序规则。 - 例如,可应用排序规则列的直方图槽会显示定义数据排序顺序的排序规则。对于不可应用排序规则的数据,则为零。 + 用于生成存储在第N槽位中的统计信息的排序规则。 + 例如,支持排序规则的列的直方图槽会显示定义数据排序顺序的排序规则。对于不支持排序规则的数据,则为零。 @@ -6753,7 +6751,7 @@ SCRAM-SHA-256$<iteration count>:&l stanumbersN float4[] - 第N槽位的类型的数值类型统计, 如果该槽位不涉及数值类型则为NULL + 第N槽位中相应种类的数值统计信息;如果该槽位种类不涉及数值,则为 NULL @@ -6763,7 +6761,7 @@ SCRAM-SHA-256$<iteration count>:&l N槽位的类型的列值,如果该槽位类型不存储任何数据值则为 NULL。 - 每个数组的元素值实际上都是指定列的数据类型或者是一个相关类型(如数组元素类型), 因此,除了把这些列的类型定义成anyarray之外别无他法。 + 每个数组的元素值实际上都是指定列的数据类型或者是一个相关类型(如数组元素类型), 因此,无法把这些列的类型定义得比anyarray更具体。 @@ -6890,7 +6888,7 @@ SCRAM-SHA-256$<iteration count>:&l 统计信息对象属性中那些不是简单列引用的表达式树,以 nodeToString() 表示。 这是一个列表,每个表达式占一个元素。 - 如果所有统计信息对象属性都是简单引用,则为空。 + 如果所有统计信息对象属性都是简单引用,则为空值。 @@ -6899,8 +6897,8 @@ SCRAM-SHA-256$<iteration count>:&l - pg_statistic_ext条目在CREATE STATISTICS期间完全填充,但是随后不计算实际的统计值。 - 后来ANALYZE命令计算所需的值,并在pg_statistic_ext_data目录中填充条目。 + pg_statistic_ext条目在CREATE STATISTICS期间完全填充,但此时不会计算实际的统计值。 + 后续的ANALYZE命令计算所需的值,并在pg_statistic_ext_data目录中填充条目。 @@ -6917,14 +6915,7 @@ SCRAM-SHA-256$<iteration count>:&l - 通常,每个已分析的统计对象都有一个条目,其中stxdinherit = - false。如果表具有继承子项或分区,还会创建第二个条目,其中 - stxdinherit = true。此行表示继承树上的统计对象,即, - 您将看到的数据的统计信息 - SELECT * FROM table*, - 而stxdinherit = false行 - 表示 - SELECT * FROM ONLY table的结果。 + 通常,每个已分析的统计信息对象都有一个 stxdinherit = false 的条目。如果表有继承子表或分区,还会创建第二个 stxdinherit = true 的条目。后者表示该统计信息对象在整个继承树上的统计信息,即通过 SELECT * FROM table* 看到的数据的统计信息;而 stxdinherit = false 的行表示 SELECT * FROM ONLY table 的结果。 @@ -6994,7 +6985,7 @@ SCRAM-SHA-256$<iteration count>:&l stxdmcv pg_mcv_list - MCV(最频值)列表统计信息,序列化为pg_mcv_list类型 + MCV(高频值)列表统计信息,序列化为pg_mcv_list类型 @@ -7003,7 +6994,7 @@ SCRAM-SHA-256$<iteration count>:&l stxdexpr pg_statistic[] - 每个表达式的统计信息,序列化为pg_statistic类型的数组 + 每个表达式的统计信息,序列化为pg_statistic类型的数组。 @@ -7070,7 +7061,7 @@ SCRAM-SHA-256$<iteration count>:&l subskiplsn pg_lsn - 事务的完成LSN,其更改将被跳过,如果是有效LSN;否则0/0。 + 若为有效 LSN,则表示要跳过其更改的事务的完成 LSN;否则为 0/0 @@ -7118,7 +7109,7 @@ SCRAM-SHA-256$<iteration count>:&l 控制如何处理进行中事务的流式传输: f = 不允许对进行中事务进行流式传输, - t = 将进行中事务的更改溢写到磁盘,并在事务在发布者端提交且被订阅者接收后立即应用, + t = 将进行中事务的更改溢写到磁盘,并在事务在发布者端提交且被订阅者接收后一次性应用, p = 如果可用,则直接使用并行应用工作进程应用更改(如果没有工作进程,则与 t 相同) @@ -7605,7 +7596,7 @@ SCRAM-SHA-256$<iteration count>:&l tgdeferrable bool - 如果约束触发器可推迟则为真 + 如果约束触发器可延迟则为真 @@ -7614,7 +7605,7 @@ SCRAM-SHA-256$<iteration count>:&l tginitdeferred bool - 如果约束触发器初始可推迟则为真 + 如果约束触发器初始处于延迟状态则为真 @@ -8150,7 +8141,7 @@ SCRAM-SHA-256$<iteration count>:&l 目录pg_type存储有关数据类型的信息。 - 基类型和枚举类型(标量类型)使用CREATE TYPE创建,而域使用CREATE DOMAIN创建。 + 基础类型和枚举类型(标量类型)使用CREATE TYPE创建,而域使用CREATE DOMAIN创建。 数据库中的每一个表都会有一个自动创建的复合类型,用于表示表的行结构。 也可以使用CREATE TYPE AS创建复合类型。 @@ -8236,7 +8227,7 @@ SCRAM-SHA-256$<iteration count>:&l typtype可以是: - b表示一个基类型, + b表示一个基础类型, c表示一个复合类型(例如一个表的行类型), d表示一个域, e表示一个枚举类型, @@ -8442,7 +8433,7 @@ SCRAM-SHA-256$<iteration count>:&l - e (外部的): 值可以存储在一个次要 TOAST 关系中 (如果有一个关系, 参见pg_class.reltoastrelid). + e (外部的): 值可以存储在一个次要 TOAST 关系中 (如果有一个关系, 参见pg_class.reltoastrelid). @@ -8485,7 +8476,7 @@ SCRAM-SHA-256$<iteration count>:&l typtypmod int4 - 域使用typtypmod来记录被应用于它们基类型的typmod(如果基类型不使用typmod,则为-1)。如果此类型不是一个域则为-1。 + 域使用typtypmod来记录被应用于它们基础类型的typmod(如果基础类型不使用typmod,则为-1)。如果此类型不是一个域则为-1。 @@ -8505,8 +8496,8 @@ SCRAM-SHA-256$<iteration count>:&l typcollation指定此类型的排序规则。如果类型不支持排序规则,此列为零。 - 支持排序规则的基类型在这里会有一个非零值,典型值为DEFAULT_COLLATION_OID。 - 基于可应用排序规则类型的域,如果为其指定了排序规则 OID,则它的排序规则 OID 可以不同于其基类型。 + 支持排序规则的基础类型在这里会有一个非零值,典型值为DEFAULT_COLLATION_OID。 + 基于支持排序规则的类型的域,如果为其指定了排序规则 OID,则它的排序规则 OID 可以不同于其基础类型的排序规则 OID。 diff --git a/zh/17/charset.sgml b/zh/17/charset.sgml index 23fb8e2d..9a3d3062 100644 --- a/zh/17/charset.sgml +++ b/zh/17/charset.sgml @@ -29,7 +29,7 @@ 区域设置支持 - locale + 区域设置 区域设置支持是指应用程序在字母表、排序、数字格式等 @@ -558,10 +558,10 @@ SELECT 'N-45' < 'N-123' COLLATE mycollation5 as result; 概念 - 从概念上讲,每个可排序数据类型的表达式都有一个排序规则。(内置的可排序 - 数据类型包括textvarcharchar。 - 用户定义的基本类型也可以标记为可排序,当然,建立在可排序数据类型之上的 - 也是可排序的。) + 从概念上讲,每个支持排序规则的数据类型的表达式都有一个排序规则。 + (内置的支持排序规则的数据类型包括textvarcharchar。 + 用户定义的基础类型也可以标记为支持排序规则,当然,建立在支持排序规则的数据类型之上的 + 也支持排序规则。) 如果表达式是列引用,则该表达式的排序规则就是该列定义的排序规则。如果表 达式是常量,则其排序规则就是该常量数据类型的默认排序规则。更复杂表达式 的排序规则则按下文所述,从其输入表达式的排序规则推导出来。 @@ -586,7 +586,7 @@ SELECT 'N-45' < 'N-123' COLLATE mycollation5 as result; 对于函数或操作符调用,通过检查参数排序规则推导出的排序规则,会在运行时 - 用于执行指定操作。如果该函数或操作符调用的结果属于可排序数据类型,那么 + 用于执行指定操作。如果该函数或操作符调用的结果属于支持排序规则的数据类型,那么 在解析时它也会被用作该函数或操作符表达式的已定义排序规则,以便在外围表 达式需要知道其排序规则时使用。 @@ -668,7 +668,7 @@ SELECT a || b FROM test1; - 如果函数或操作符返回的是可排序数据类型,那么分配给该函数或操作符组合输 + 如果函数或操作符返回的是支持排序规则的数据类型,那么分配给该函数或操作符组合输 入表达式的排序规则,也被认为适用于其结果。因此,在 SELECT * FROM test1 ORDER BY a || 'foo'; @@ -714,8 +714,7 @@ SELECT * FROM test1 ORDER BY a || b COLLATE "fr_FR"; - 由icu提供的排序规则对象,对应于 ICU 库提供的具名整 - 理器。ICU 不支持将collatectype分开设 + 由icu提供的排序规则对象,对应于 ICU 库提供的具名排序器。ICU 不支持将collatectype分开设 置,因此二者总是相同的。此外,ICU 排序规则与编码无关,因此在一个数据库 中,某个给定名称的 ICU 排序规则始终只有一个。 diff --git a/zh/17/client-auth.sgml b/zh/17/client-auth.sgml index c52d9654..429c9d7b 100644 --- a/zh/17/client-auth.sgml +++ b/zh/17/client-auth.sgml @@ -48,6 +48,21 @@ 请参见配置参数 + + 在启动时以及主服务器进程收到 SIGHUPSIGHUP 信号时,pg_hba.conf 文件会被读取。 + 如果你在运行中的系统上编辑了该文件,就需要通知 postmaster(使用 pg_ctl reload、调用 SQL 函数 pg_reload_conf(),或者使用 kill -HUP)重新读取该文件。 + + + + + 前面的说明不适用于 Microsoft Windows:在Windows上,pg_hba.conf文件中的任何更改会立即被应用到后续的新连接上。 + + + + + 系统视图pg_hba_file_rules 有助于预先测试对 pg_hba.conf 文件的修改,也可以在加载该文件没有产生预期效果时用于诊断问题。视图中 error 字段非空的行表示文件对应行存在问题。 + + pg_hba.conf 文件的一般格式是一组记录,每行一条。 空白行会被忽略,# 注释字符后面的任何文本也会被忽略。 @@ -67,7 +82,7 @@ - 一条记录可以有多种格式: + 一条记录可以有多种格式: local database user auth-method auth-options @@ -239,7 +254,7 @@ include_dir directory IP地址范围使用标准的数字表示法来指定起始地址,然后是斜杠(/)和一个CIDR掩码长度。 掩码长度表示客户端IP地址必须匹配的高位比特数。给定IP地址中右侧的比特应为零。 - IP地址、/和CIDR掩码长度之间不得有任何空格。 + IP地址、/和CIDR掩码长度之间不得有任何空白。 @@ -253,8 +268,7 @@ include_dir directory 以IPv4格式给出的条目将仅匹配IPv4连接,以IPv6格式给出的条目将仅匹配IPv6连接, - 即使所代表的地址在IPv4-in-IPv6范围内。请注意,如果系统的C库不支持IPv6地址, - 以IPv6格式给出的条目将被拒绝。 + 即使所代表的地址在IPv4-in-IPv6范围内。 @@ -276,12 +290,12 @@ include_dir directory 以点(.)开头的主机名规范匹配实际主机名的后缀。 因此,.example.com将匹配foo.example.com - (但不仅仅是example.com)。 + (但不匹配单独的example.com)。 当在pg_hba.conf中指定主机名时,应确保名称解析相对快速。 - 最好设置一个本地名称解析缓存,如nscd。 + 设置一个本地名称解析缓存可能会有帮助,如nscd。 此外,还可能希望启用配置参数log_hostname,以便在日志中看到客户端的主机名而不是 IP 地址。 @@ -293,7 +307,7 @@ include_dir directory 用户有时会想知道为什么主机名以这种看似复杂的方式处理,包括两次名称解析,其中包括对客户端IP地址的反向查找。 - 如果客户端的反向DNS条目未设置或生成了一些不良的主机名,则使用该功能会变得复杂。 + 如果客户端的反向DNS条目未设置或返回了不符合预期的主机名,则使用该功能会变得复杂。 这主要是为了效率:这样,连接尝试最多需要两次解析器查找,一次反向查找和一次正向查找。 如果某个地址存在解析器问题,那就只会成为该客户端的问题。 一个假设的替代实现只进行正向查找的情况下,在每次连接尝试期间都必须解析pg_hba.conf中提到的每个主机名。 @@ -320,7 +334,7 @@ include_dir directory - 这两个字段可以用作IP地址/掩码长度 + 这两个字段可以用作IP-address/mask-length 表示法的替代方案。而不是指定掩码长度,实际掩码在一个单独的列中指定。 例如,255.0.0.0表示IPv4的CIDR掩码长度为8, 而255.255.255.255表示CIDR掩码长度为32。 @@ -502,11 +516,7 @@ include_dir directory auth-options - - - 在auth-method字段之后,可以是形如name=value的字段, - 用于指定认证方法的选项。关于哪些选项适用于哪些认证方法的详细信息见下文。 - + auth-method 字段之后,可以有一个或多个形如 name=value 的字段,用于指定认证方法的选项。下文会详细说明各认证方法有哪些可用选项。 除了下面列出的特定于方法的选项外,还有一个方法无关的认证选项 clientcert, @@ -519,7 +529,7 @@ include_dir directory - 对于任何使用客户端证书认证的记录(即使用 cert 认证方法的记录,或使用 clientcert 选项的记录),都可以通过 clientname 选项指定要匹配客户端证书凭据中的哪一部分。此选项有两个可选值。如果指定 clientname=CN,这也是默认值,则用户名将与证书的 Common Name (CN) 匹配。如果改为指定 clientname=DN,则用户名将与证书的完整 Distinguished Name (DN) 匹配。此选项通常最好与用户名映射配合使用。比较时使用的是 RFC 2253 格式的 DN。要查看以这种格式表示的客户端证书 DN,请执行 + 对于任何使用客户端证书认证的记录(即使用 cert 认证方法的记录,或使用 clientcert 选项的记录),都可以通过 clientname 选项指定要匹配客户端证书凭据中的哪一部分。此选项有两个可选值。如果指定 clientname=CN,这也是默认值,则用户名将与证书的 Common Name (CN) 匹配。如果改为指定 clientname=DN,则用户名将与证书的完整 Distinguished Name (DN) 匹配。此选项可能更适合与用户名映射配合使用。比较时使用的是 RFC 2253 格式的 DN。要查看以这种格式表示的客户端证书 DN,请执行 openssl x509 -in myclient.crt -noout -subject -nameopt RFC2253 | sed "s/^subject=//" @@ -561,25 +571,7 @@ openssl x509 -in myclient.crt -noout -subject -nameopt RFC2253 | sed "s/^subject 由 @ 构造引用的文件会被读取为名称列表,其中的名称可以用空白或逗号分隔。注释仍然用 # 引入,与 pg_hba.conf 中相同,并且允许嵌套的 @ 构造。除非 @ 后面的文件名是绝对路径,否则它会被视为相对于引用它的文件所在目录。 - - 因为每一次连接尝试都会顺序地检查pg_hba.conf记录,所以这些记录的顺序是非常关键的。通常,靠前的记录有比较严的连接匹配参数和比较弱的认证方法,而靠后的记录有比较松的匹配参数和比较强的认证方法。 例如,我们希望对本地 TCP/IP 连接使用trust认证,而对远程 TCP/IP 连接要求密码。在这种情况下为来自于 127.0.0.1 的连接指定trust认证的记录将出现在为一个更宽范围的客户端 IP 地址指定密码认证的记录前面。 - - - - 在启动以及主服务器进程收到SIGHUPSIGHUP信号时,pg_hba.conf文件会被读取。 - 如果你在活动的系统上编辑了该文件,你将需要通知 postmaster(使用pg_ctl reload,调用SQL函数pg_reload_conf(),或使用kill -HUP)使其重新读取该文件。 - - - - - - 前面的说明在Microsoft Windows上不为真:在Windows上,pg_hba.conf文件中的任何更改会立即被应用到后续的新连接上。 - - - - - 系统视图pg_hba_file_rules 有助于预先测试对 pg_hba.conf 文件的修改,也可以在加载该文件没有产生预期效果时用于诊断问题。视图中 error 字段非空的行表示文件对应行存在问题。 - + 由于每次连接尝试都会按顺序检查 pg_hba.conf 记录,因此记录的顺序很重要。通常,靠前的记录使用较严格的连接匹配条件和较弱的认证方法,靠后的记录使用较宽松的匹配条件和较强的认证方法。例如,可能希望对本地 TCP/IP 连接使用 trust 认证,而要求远程 TCP/IP 连接提供密码。此时,为来自 127.0.0.1 的连接指定 trust 认证的记录,应放在为更大范围的允许客户端 IP 地址指定密码认证的记录之前。 @@ -588,9 +580,7 @@ openssl x509 -in myclient.crt -noout -subject -nameopt RFC2253 | sed "s/^subject - - 中展示了pg_hba.conf项的一些示例。不同认证方法的详情请见下一节。 - + 展示了一些 pg_hba.conf 条目示例。有关不同认证方法的详细信息,参见下一节。 @@ -598,8 +588,8 @@ openssl x509 -in myclient.crt -noout -subject -nameopt RFC2253 | sed "s/^subject # 允许本地系统上的任何用户 -# 通过 Unix 域套接字以任意 -# 数据库用户名连接到任意数据库(本地连接的默认值)。 +# 通过 Unix 域套接字(本地连接的默认方式)以任意 +# 数据库用户名连接到任意数据库。 # # TYPE DATABASE USER ADDRESS METHOD local all all trust @@ -644,7 +634,7 @@ host postgres all 192.168.93.0/24 ident # TYPE DATABASE USER ADDRESS METHOD host postgres all 192.168.12.10/32 scram-sha-256 -# 如果用户的密码被正确提供,允许 example.com 中主机上 +# 如果用户的密码被正确提供,允许 example.com 域中主机上 # 的任意用户连接到任意数据库。 # # 为大部分用户要求SCRAM认证,但是用户'mike'是个例外, @@ -655,7 +645,7 @@ host all mike .example.com md5 host all all .example.com scram-sha-256 # 如果没有前面的 "host" 行,这三行 -# 将拒绝所有来自 192.168.54.1的连接(因为那些项将首先被匹配), +# 将拒绝所有来自 192.168.54.1的连接(因为该条目将首先被匹配), # 但是允许来自互联网其他任何地方的 # GSSAPI 加密连接。零掩码表示不会考虑主机 IP 地址中的任何位, # 因此它会匹配任意主机。未加密的 GSSAPI 连接 @@ -670,7 +660,7 @@ host all all 192.168.12.10/32 gss # 允许来自 192.168.x.x 主机的用户连接到任意数据库,如果它们能够 # 通过 ident 检查。例如,假设 ident说用户是 "bryanh" 并且他要求以 # PostgreSQL 用户 "guest1" 连接,如果在 pg_ident.conf 有一个映射 -# "omicron" 的选项说 "bryanh" 被允许以 "guest1" 连接,则该连接将被允许。 +# "omicron" 的条目表明 "bryanh" 被允许以 "guest1" 连接,则该连接将被允许。 # # TYPE DATABASE USER ADDRESS METHOD host all all 192.168.0.0/16 ident map=omicron @@ -727,6 +717,18 @@ local db1,db2,@demodbs all md5 与 pg_hba.conf 一样,此文件中的各行也可以是 include 指令,并遵循相同的规则。 + + 在启动时以及主服务器进程收到 SIGHUPSIGHUP 信号时,pg_ident.conf 文件会被读取。 + 如果你在运行中的系统上编辑了该文件,就需要通知 postmaster(使用 pg_ctl reload、调用 SQL 函数 pg_reload_conf(),或者使用 kill -HUP)重新读取该文件。 + + + + 系统视图 + pg_ident_file_mappings + 可以帮助预先测试对pg_ident.conf文件的更改,或者在加载文件后未产生预期效果时诊断问题。 + 视图中具有非空error字段的行表示文件相应行中存在问题。 + + 对于给定的一个操作系统用户可以对应多少个数据库用户,没有任何限制,反之亦然。因此,映射中的条目应理解为该操作系统用户被允许以该数据库用户身份连接,而不是意味着两者等价。只要存在任何一条映射项把外部认证系统获得的用户名与用户请求连接时使用的数据库用户名配对起来,该连接就会被允许。值 all 还可以用作 database-username,表示只要 system-username 匹配,该用户就被允许以任意现有数据库用户身份登录。若给 all 加上引号,则它会失去该特殊含义。 @@ -755,18 +757,6 @@ mymap /^(.*)@otherdomain\.com$ guest - - 在启动时以及主服务器进程收到 SIGHUPSIGHUP 信号时,pg_ident.conf 文件会被读取。 - 如果你在运行中的系统上编辑了该文件,就需要通知 postmaster(使用 pg_ctl reload、调用 SQL 函数 pg_reload_conf(),或者使用 kill -HUP)重新读取该文件。 - - - - 系统视图 - pg_ident_file_mappings - 可以帮助预先测试对pg_ident.conf文件的更改,或者在加载文件后未产生预期效果时诊断问题。 - 视图中具有非空error字段的行表示文件相应行中存在问题。 - - 展示了一个可与 中的 pg_hba.conf 文件配合使用的 pg_ident.conf 文件。在这个示例中,任何登录到 192.168 网络中某台机器上的用户,如果其操作系统用户名不是 bryanhannrobert,都不会被授予访问权限。Unix 用户 robert 只有在尝试以 PostgreSQL 用户 bob 身份连接时才被允许访问,而不能以 robert 或其他身份连接。ann 只能以 ann 身份连接。用户 bryanh 则可以以 bryanhguest1 身份连接。 @@ -860,7 +850,7 @@ omicron bryanh guest1 - Peer 认证通常适用于本地连接,不过在某些情况下,信任认证也可能已经足够。 + 通常建议对本地连接使用 Peer 认证,不过在某些情况下,信任认证也可能已经足够。 密码认证是远程连接最容易采用的选择。 其余所有选项都需要某种外部安全基础设施(通常是认证服务器,或用于签发 SSL 证书的证书颁发机构),或者属于平台特定功能。 @@ -879,16 +869,14 @@ omicron bryanh guest1 - trust认证对于单用户工作站的本地连接是非常合适和方便的。通常它本身适用于一台多用户机器。不过,只要你利用文件系统权限限制了对服务器的 Unix 域套接字文件的访问,即使在多用户机器上,你也可以使用trust。 要做这些限制,你可以设置中描述的unix_socket_permissions配置参数(可能还有unix_socket_group)。 或者你可以设置unix_socket_directories配置参数来把 Unix 域套接字文件放在一个经过恰当限制的目录中。 + trust认证对于单用户工作站的本地连接是非常合适和方便的。通常它本身适用于一台多用户机器。不过,只要你利用文件系统权限限制了对服务器的 Unix 域套接字文件的访问,即使在多用户机器上,你也可能可以使用trust。 要做这些限制,你可以设置中描述的unix_socket_permissions配置参数(可能还有unix_socket_group)。 或者你可以设置unix_socket_directories配置参数来把 Unix 域套接字文件放在一个经过恰当限制的目录中。 设置文件系统权限只能有助于 Unix 套接字连接。本地 TCP/IP 连接不会被文件系统权限限制。因此,如果你想利用文件系统权限来控制本地安全,那么从pg_hba.conf中移除host ... 127.0.0.1 ...行,或者把它改为一个非trust认证方法。 - - 如果通过指定trustpg_hba.conf行让你信任每一个被允许连接到服务器的机器上的用户,trust认证只适合 TCP/IP 连接。为任何不是来自localhost(127.0.0.1)的 TCP/IP 连接使用trust很少是合理的。 - + 只有当你信任由 pg_hba.conf 中指定 trust 的行所允许连接的每台机器上的每个用户时,trust 认证才适合用于 TCP/IP 连接。对来自 localhost(127.0.0.1)以外的任何 TCP/IP 连接使用 trust,通常都不合理。 @@ -933,9 +921,7 @@ omicron bryanh guest1 md5 - - 方法md5使用一种自定义的安全性较低的挑战-响应机制。它能防止密码嗅探并且防止密码在服务器上以明文存储,但是无法保护攻击者想办法从服务器上窃取了密码哈希的情况。此外,现在认为MD5哈希算法对于确定攻击已经不再安全。 - + 方法md5使用一种自定义的、安全性较低的挑战-响应机制。它能防止密码嗅探,并避免在服务器上以明文存储密码;但如果攻击者设法从服务器上窃取了密码哈希,它就无法提供保护。此外,如今已不再认为 MD5 哈希算法能抵御有决心的攻击者。 为了简化从md5方法到较新的SCRAM方法的转变,如果在pg_hba.conf中指定了md5但是用户在服务器上的密码是为SCRAM(见下文)加密的,则将自动选择基于SCRAM的认证。 @@ -963,7 +949,7 @@ omicron bryanh guest1 - 要把现有安装从 md5 升级到 scram-sha-256,需要先确保所有正在使用的客户端库都足够新并支持 SCRAM,然后在 postgresql.conf 中设置 password_encryption = 'scram-sha-256',要求所有用户重新设置密码,并将 pg_hba.conf 中的认证方法说明改为 scram-sha-256。 + 要把现有安装从 md5 升级到 scram-sha-256,需要先确保所有正在使用的客户端库都足够新并支持 SCRAM,然后在 postgresql.conf 中设置 password_encryption = 'scram-sha-256',要求所有用户重新设置密码,并将 pg_hba.conf 中的认证方法设置改为 scram-sha-256 @@ -1027,7 +1013,7 @@ omicron bryanh guest1 keytab 文件用 Kerberos 软件生成;详见 Kerberos 文档。 - 下面展示了用 MIT 兼容的 Kerberos 5 实现的kadmin来做这个的示例: + 下面的示例展示了如何使用 MIT Kerberos 的 kadmin 工具生成该文件: kadmin% addprinc -randkey postgres/server.my.domain.org kadmin% ktadd -k krb5.keytab postgres/server.my.domain.org @@ -1117,7 +1103,7 @@ omicron bryanh guest1 如果设为 1,则会在 include_realm 选项中使用域的 SAM 兼容名称(也称为 NetBIOS 名称)。这是默认值。如果设为 0,则会使用 Kerberos 用户主体名中的真实 realm 名称。 - 不要禁用这个选项,除非你的服务器运行在一个域账号(这包括一个域成员系统上的虚拟服务账号)下并且所有通过 SSPI 认证的所有客户端也在使用域账号,否则认证将会失败。 + 不要禁用这个选项,除非你的服务器运行在一个域账号(这包括一个域成员系统上的虚拟服务账号)下并且所有通过 SSPI 认证的客户端也在使用域账号,否则认证将会失败。 @@ -1182,7 +1168,7 @@ omicron bryanh guest1 map - 允许在系统用户和数据库用户名称之间进行映射。详细信息请参见。 + 允许在系统用户名和数据库用户名之间进行映射。详见 @@ -1205,7 +1191,7 @@ omicron bryanh guest1
RFC 1413 - 标识协议的本意不是作为一种认证或访问控制协议。 + 标识协议的本意不是作为一种授权或访问控制协议。
@@ -1234,7 +1220,7 @@ omicron bryanh guest1 map - 允许在系统用户和数据库用户名称之间进行映射。详细信息请参见。 + 允许在系统用户名和数据库用户名之间进行映射。详见 @@ -1290,8 +1276,7 @@ omicron bryanh guest1 ldapscheme - 设置为ldaps以使用LDAPS。这是一种非标准的使用LDAP - 进行SSL加密的方式,受一些LDAP服务器实现支持。另请参阅ldaptls + 设置为ldaps以使用LDAPS。这是一种非标准的通过 SSL 使用 LDAP 的方式,受一些LDAP服务器实现支持。另请参阅ldaptls 选项作为替代。 @@ -1384,16 +1369,14 @@ omicron bryanh guest1 一个RFC 4516 - LDAP URL。这是以更紧凑和标准形式编写其他LDAP选项的替代方式。格式为 + LDAP URL。这是以更紧凑和标准形式编写部分其他 LDAP 选项的替代方式。格式为 ldap[s]://host[:port]/basedn[?[attribute][?[scope][?[filter]]]] scope必须是baseonesub中的一个,通常是最后一个。(默认为base,在此应用中通常无用。)attribute可以指定单个属性,此时将用作ldapsearchattribute的值。如果attribute为空,则filter可用作ldapsearchfilter的值。 - - URL方案ldaps选择了通过SSL进行LDAP连接的LDAPS方法,相当于使用ldapscheme=ldaps。要使用StartTLS操作进行加密LDAP连接,请使用正常的URL方案ldap并另外指定ldaptls选项。 - + URL 方案 ldaps 会选择 LDAPS 方法,通过 SSL 建立 LDAP 连接,等同于使用 ldapscheme=ldaps。要通过 StartTLS 操作使用加密的 LDAP 连接,请使用普通的 URL 方案 ldap,并在 ldapurl 之外指定 ldaptls 选项。 对于非匿名绑定,必须将ldapbinddnldapbindpasswd指定为单独的选项。 @@ -1412,22 +1395,11 @@ ldap[s]://host[:port]/ - 在使用搜索+绑定模式时,可以用ldapsearchattribute - 指定的单个属性执行搜索,也可以用ldapsearchfilter - 指定的自定义搜索过滤器执行搜索。指定 - ldapsearchattribute=foo等价于指定 - ldapsearchfilter="(foo=$username)"。如果这两个选项都未 - 指定,默认值是ldapsearchattribute=uid。 + 在使用搜索+绑定模式时,可以使用由 ldapsearchattribute 指定的单个属性执行搜索,也可以使用由 ldapsearchfilter 指定的自定义搜索过滤器执行搜索。指定 ldapsearchattribute=foo 等价于指定 ldapsearchfilter="(foo=$username)"。如果两个选项都未指定,则默认使用 ldapsearchattribute=uid - 如果PostgreSQL在编译时使用了 - OpenLDAP作为 LDAP 客户端库,则可以省略 - ldapserver设置。在这种情况下,会通过 - RFC 2782 - DNS SRV 记录查找主机名和端口列表。将会查找名称 - _ldap._tcp.DOMAIN,其中DOMAIN从 - ldapbasedn中提取。 + 如果 PostgreSQL 编译时使用了 OpenLDAP 作为 LDAP 客户端库,则可以省略 ldapserver 设置。在这种情况下,会通过 RFC 2782 DNS SRV 记录查找主机名和端口列表。查找的名称是 _ldap._tcp.DOMAIN,其中 DOMAINldapbasedn 中提取。 @@ -1435,10 +1407,7 @@ ldap[s]://host[:port]/ host ... ldap ldapserver=ldap.example.net ldapprefix="cn=" ldapsuffix=", dc=example, dc=net" - 当请求以数据库用户someuser连接数据库服务器时, - PostgreSQL将尝试使用 DN - cn=someuser, dc=example, dc=net以及客户端提供的密码 - 绑定到 LDAP 服务器。如果该连接成功,就会授予数据库访问权限。 + 当请求以数据库用户 someuser 连接数据库服务器时,PostgreSQL 将尝试使用 DN cn=someuser, dc=example, dc=net 和客户端提供的密码绑定到 LDAP 服务器。如果该连接成功,数据库访问就会被授予。 @@ -1446,12 +1415,7 @@ host ... ldap ldapserver=ldap.example.net ldapprefix="cn=" ldapsuffix=", dc=exam host ... ldap ldapserver=ldap.example.net ldapbasedn="dc=example, dc=net" ldapsearchattribute=uid - 当请求以数据库用户someuser连接数据库服务器时, - PostgreSQL将尝试匿名绑定到 LDAP 服务器 - (因为未指定ldapbinddn),并在指定的基础 DN 下执行 - (uid=someuser)搜索。如果找到了对应条目,它随后将尝试 - 使用所找到的信息和客户端提供的密码进行绑定。如果第二次绑定成功,就会授予 - 数据库访问权限。 + 当请求以数据库用户 someuser 连接数据库服务器时,PostgreSQL 将尝试对 LDAP 服务器进行匿名绑定(因为未指定 ldapbinddn),并在指定的基础 DN 下执行一次 (uid=someuser) 搜索。如果找到了对应条目,随后就会尝试使用该条目的信息以及客户端提供的密码进行绑定。如果第二次绑定成功,数据库访问就会被授予。 @@ -1459,23 +1423,18 @@ host ... ldap ldapserver=ldap.example.net ldapbasedn="dc=example, dc=net" ldapse host ... ldap ldapurl="ldap://ldap.example.net/dc=example,dc=net?uid?sub" - 某些其他支持 LDAP 认证的软件也使用相同的 URL 格式,因此会更容易共享这种 - 配置。 + 某些支持 LDAP 认证的其他软件也使用相同的 URL 格式,因此共享这类配置会更容易。 - 下面是一个搜索+绑定配置示例,它使用 - ldapsearchfilter而不是 - ldapsearchattribute,从而允许通过用户 ID 或电子邮件地址 - 进行认证: + 这里是一个搜索+绑定配置的示例,它使用 ldapsearchfilter 而不是 ldapsearchattribute 来允许用用户 ID 或电子邮件地址进行认证: host ... ldap ldapserver=ldap.example.net ldapbasedn="dc=example, dc=net" ldapsearchfilter="(|(uid=$username)(mail=$username))" - 下面是一个搜索+绑定配置示例,它使用 DNS SRV 发现来查找域名 - example.net的 LDAP 服务的主机名和端口: + 这是一个搜索+绑定配置的示例,它使用 DNS SRV 发现来查找域名 example.net 的 LDAP 服务的主机名和端口。 host ... ldap ldapbasedn="dc=example,dc=net" diff --git a/zh/17/config.sgml b/zh/17/config.sgml index 8f666a20..cf744a0a 100644 --- a/zh/17/config.sgml +++ b/zh/17/config.sgml @@ -51,7 +51,7 @@ 字符串: 通常值被包括在单引号内,值内部的任何单引号都需要被双写。不过,如果值是一个简单数字或者 标识符,引号通常可以被省略。 - (与 SQL 关键字匹配的值需要在某些上下文中引用。) + (与 SQL 关键字匹配的值在某些上下文中需要加引号。) @@ -70,7 +70,7 @@ 带单位的数字: 一些数字参数具有隐含单位,因为它们描述的是内存或时间量。单位可能是字节、千字节、块 - (通常为 8 千字节)、毫秒、秒或分钟。这类设置若给出不带修饰的数字值,就会使用该设置的默认单位, + (通常为 8 千字节)、毫秒、秒或分钟。这类设置若给出不带单位的数字值,就会使用该设置的默认单位, 可以通过 pg_settings.unit 了解该默认单位。为了方便, 也可以显式指定单位,例如把时间值写成 '120 ms',系统会将其转换为该参数的实际单位。 注意,要使用这一特性,值必须写成字符串(带引号)。单位名称区分大小写,并且数字值与单位之间可以有空白。 @@ -190,14 +190,14 @@ shared_buffers = 128MB - ALTER DATABASE命令允许针对一个数据库覆盖其全局设置。 + ALTER DATABASE命令允许针对各个数据库覆盖全局设置。 - ALTER ROLE命令允许用用户指定的值来覆盖全局设置和数据库设置。 + ALTER ROLE命令允许用针对特定用户设置的值来覆盖全局设置和数据库设置。 @@ -272,7 +272,7 @@ UPDATE pg_settings SET setting = reset_val WHERE name = 'configuration_parameter 通过 Shell 影响参数 - 除了在数据库或者角色层面上设置全局默认值或者进行覆盖,你还可以通过 shell 工具把设置 + 除了设置全局默认值或在数据库、角色级别覆盖默认值之外,你还可以通过 shell 工具把设置 传递给PostgreSQL。服务器和libpq 客户端库都能通过 shell 接受参数值。 @@ -281,8 +281,7 @@ UPDATE pg_settings SET setting = reset_val WHERE name = 'configuration_parameter - 在服务器启动期间,可以通过命令行参数把参数设置传递给 - postgres命令。例如: + 在服务器启动期间,可以通过 命令行参数或其等效形式 ,把参数设置传递给 postgres 命令。例如: postgres -c log_connections=yes --log-destination='syslog' @@ -297,7 +296,7 @@ postgres -c log_connections=yes --log-destination='syslog' 当通过libpq启动一个客户端会话时,可以使用PGOPTIONS 环境变量指定参数设置。这种方式建立的设置构成了会话生存期间的默认值,但是不会影响 其他的会话。由于历史原因,PGOPTIONS的格式和启动 - postgres命令时用到的相似,特别是标志必须被指定。 + postgres命令时用到的相似,具体来说,必须指定 ,或在参数名称前加上 --。 例如: env PGOPTIONS="-c geqo=off --statement-timeout=5min" psql @@ -344,7 +343,7 @@ include 'filename' 还有一个 include_if_exists 指令,其行为与 include 相同, 但在被引用文件不存在或无法读取时有所不同。普通的 include 会将其视为错误, - 而 include_if_exists 只会记录一条消息并继续处理引用配置文件。 + 而 include_if_exists 只会记录一条消息并继续处理引用它的配置文件。 @@ -355,21 +354,21 @@ include 'filename' postgresql.conf 文件也可以包含 include_dir 指令, 用来指定一个应被包含的配置文件目录。其用法如下: - include_dir 'directory' - - 非绝对目录名会被解释为相对于引用配置文件所在目录的路径。在指定目录中, +include_dir 'directory' + + 非绝对目录名会被解释为相对于引用它的配置文件所在目录的路径。在指定目录中, 只有名称以 .conf 结尾的非目录文件才会被包含。以 . 开头的文件名也会被忽略,以避免在某些平台上误处理隐藏文件。包含目录中的多个文件会按文件名顺序处理 (依据 C 区域规则排序,即数字在字母之前,大写字母在小写字母之前)。 - 包括文件或目录可以被用来在逻辑上分隔数据库配置的各个部分,而不是用一个很大的postgresql.conf文件。 + 包含文件或目录可以用来在逻辑上分隔数据库配置的各个部分,而不是用一个很大的postgresql.conf文件。 考虑一个有两台数据库服务器的公司,每一个都有不同的内存量。 - 很可能配置的元素都会被共享,例如用于日志的参数。但是两者关于内存的参数将会不同。 + 两者很可能会共享部分配置,例如日志设置。但是两者关于内存的参数将会不同。 并且还可能会有服务器相关的自定义。 一种管理这类情况的方法是将你的站点的自定义配置修改分成三个文件。 - 你可以把下面的内容加入到你的postgresql.conf文件末尾来包括它们: + 你可以把下面的内容加入到你的postgresql.conf文件末尾来包含它们: include 'shared.conf' include 'memory.conf' @@ -430,7 +429,7 @@ include_dir 'conf.d' - 指定用于数据存储的目录。这个选项只能在服务器启动时设置。 + 指定用于数据存储的目录。这个参数只能在服务器启动时设置。 @@ -490,7 +489,7 @@ include_dir 'conf.d' - 指定可被服务器创建的用于管理程序的额外进程 ID(PID)文件。这个参数只能在服务器启动的时候设置。 + 指定服务器应创建的额外进程 ID(PID)文件的名称,供服务器管理程序使用。这个参数只能在服务器启动的时候设置。 @@ -501,15 +500,15 @@ include_dir 'conf.d' - 如果你想把配置文件放在别的地方而不是数据目录中,那么postgres 命令行选项或者环境变量PGDATA必须指向包含配置文件的目录,并且postgresql.conf中(或者命令行上)的data_directory参数必须显示数据目录实际存放的地方。请注意,data_directory将覆盖PGDATA指定的数据目录位置,但是不覆盖配置文件的位置。 + 如果你想把配置文件放在别的地方而不是数据目录中,那么postgres 命令行选项或者环境变量PGDATA必须指向包含配置文件的目录,并且postgresql.conf中(或者命令行上)的data_directory参数必须设置为数据目录的实际位置。请注意,data_directory将覆盖PGDATA指定的数据目录位置,但是不覆盖配置文件的位置。 - 如果你愿意,可以使用选项config_filehba_file和/或ident_file单独指定配置文件名称和位置。config_file只能在postgres命令行上指定,但是其他文件可以在主配置文件中设置。如果所有三个参数外加data_directory被显式地设置,则不必指定PGDATA。 + 如果你愿意,可以使用选项config_filehba_file和/或ident_file单独指定配置文件名称和位置。config_file只能在postgres命令行上指定,但是其他参数可以在主配置文件中设置。如果所有三个参数外加data_directory被显式地设置,则不必指定PGDATA - 在设置任何这些参数时,相对路径将被解释为相对于postgres启动路径的路径。 + 在设置任何这些参数时,相对路径将被解释为相对于启动 postgres 时所在目录的路径。 @@ -533,7 +532,7 @@ include_dir 'conf.d' - 指定服务器用于监听来自客户端应用程序的连接的TCP/IP地址(指服务器网卡IP地址)。 + 指定服务器用于监听来自客户端应用程序的连接的TCP/IP地址。 该值采用逗号分隔的主机名和/或数字IP地址的形式。特殊条目*对应于所有可用的IP接口。 条目0.0.0.0允许监听所有IPv4地址,::允许监听所有IPv6地址。 如果列表为空,则服务器不会在任何IP接口上监听,此时只能使用Unix域套接字进行连接。 @@ -556,11 +555,11 @@ include_dir 'conf.d' - - - 服务器监听的 TCP 端口;默认是 5432 。请注意服务器会同一个端口号监听所有的 IP 地址。这个参数只能在服务器启动时设置。 - - + + 服务器监听的 TCP 端口,默认是 5432。请注意,服务器监听的所有 IP 地址都使用同一个端口号。 + 此参数只能在服务器启动时设置。 + + @@ -578,13 +577,13 @@ include_dir 'conf.d' - PostgreSQL 会直接根据 max_connections 的值来确定某些资源的规模。 + PostgreSQL 会直接根据 max_connections 的值来确定某些资源的规模。 增大该值会导致这些资源(包括共享内存)的分配随之增加。 当运行一个备库时,你必须设置这个参数等于或大于主库上的参数。 - 否则,备库上可能无法允许查询。 + 否则,备库上将不允许查询。 @@ -597,20 +596,10 @@ include_dir 'conf.d' - 确定为拥有 - pg_use_reserved_connections - 角色的连接保留多少个连接。当空闲连接槽的数量大于 - , - 但小于或等于superuser_reserved_connections与 - reserved_connections之和时,新连接将只接受超级用户以及拥有 - pg_use_reserved_connections权限的角色。如果可用连接槽的数量等于或少于 - superuser_reserved_connections,则新连接只接受超级用户。 + 确定为具有 pg_use_reserved_connections(见) 角色权限的角色保留多少个连接。当空闲连接槽的数量大于 ,但小于或等于 superuser_reserved_connectionsreserved_connections 之和时,新连接将只接受超级用户以及具有 pg_use_reserved_connections 角色权限的角色。如果可用连接槽的数量小于或等于 superuser_reserved_connections,则新连接只接受超级用户。 - 默认值为零连接。该值必须小于 - max_connections减去 - superuser_reserved_connections。 - 此参数只能在服务器启动时设置。 + 默认值为零个连接。该值必须小于 max_connections 减去 superuser_reserved_connections。此参数只能在服务器启动时设置。 @@ -628,7 +617,7 @@ include_dir 'conf.d' 决定为 PostgreSQL 超级用户连接保留多少个连接。 - 同时活跃的连接数最多始终只能达到 。当活跃并发连接数达到 + 同时活跃的连接数最多始终只能达到 。当活跃并发连接数至少达到 max_connections 减去 superuser_reserved_connections 时, 新连接将只接受超级用户。由该参数保留的连接槽是在 保留的连接槽耗尽之后,用于紧急情况的最后储备。 @@ -706,31 +695,23 @@ include_dir 'conf.d' - - 设置 Unix 域套接字的访问权限。Unix 域套接字使用普通的 Unix 文件系统权限集。这个参数值应该是数字的形式,也就是系统调用chmodumask接受的 形式(如果使用自定义的八进制格式,数字必须以一个0(零)开头)。 + 设置 Unix 域套接字的访问权限。Unix 域套接字使用通常的 Unix 文件系统权限集。参数值应是以 chmodumask 系统调用所接受格式指定的数字权限模式。(要使用惯用的八进制格式,数字必须以 0(零)开头。) - - 默认的权限是0777,意思是任何人都可以连接。合理的候选是0770(只有用户和同组的人可以访问, 又见unix_socket_group)和0700(只有用户自己可以访问)(请注意,对于 Unix 域套接字,只有写权限有麻烦,因此没有对读取和执行权限的设置和收回)。 + 默认权限是 0777,表示任何人都可以连接。合理的其他取值包括 0770(仅属主和所属组,另见 unix_socket_group)和 0700(仅属主)。(注意,对 Unix 域套接字而言,只有写权限起作用,因此设置或撤销读权限和执行权限没有意义。) - - 这个访问控制机制与中的用户认证没有关系。 + 此访问控制机制独立于 中描述的机制。 - - 这个参数只能在服务器启动时设置。 + 此参数只能在服务器启动时设置。 - - 这个参数与完全忽略套接字权限的系统无关,尤其是自版本10以上的Solaris。 - 在那些系统上,可以通过把unix_socket_directories指向一个把搜索权限 - 限制给指定用户的目录来实现相似的效果。 + 此参数对完全忽略套接字权限的系统无效,尤其是 Solaris(截至 Solaris 10)。在这些系统上,可以将 unix_socket_directories 指向一个仅向目标用户授予搜索权限的目录,以达到类似效果。 - - 抽象命名空间中的套接字没有文件权限,所以这种情况下这个设置也会被忽略。 + 抽象命名空间中的套接字没有文件权限,因此这种情况下也会忽略此设置。 @@ -743,10 +724,8 @@ include_dir 'conf.d' - - 通过Bonjour广告服务器的存在。默认值是关闭。 - 这个参数只能在服务器启动时设置。 + 启用通过 Bonjour 通告服务器存在的功能。默认值为关闭。此参数只能在服务器启动时设置。 @@ -759,11 +738,11 @@ include_dir 'conf.d' - - - 指定Bonjour服务名称。空字符串''(默认值)表示使用计算机名。 如果编译时没有打开Bonjour支持那么将忽略这个参数。这个参数只能在服务器启动时设置。 - - + + 指定 Bonjour 服务名。空字符串 ''(默认值)表示使用计算机名。 + 如果编译时未启用 Bonjour 支持,则此参数会被忽略。此参数只能在服务器启动时设置。 + + @@ -856,74 +835,21 @@ include_dir 'conf.d' - - 在运行查询时,设置检查客户端是否保持连接的可选检查的时间间隔。 - 这个检查通过轮询套接字来执行,并且在内核报告该连接关闭时,允许长时间运行的查询可以尽快中止。 + 设置查询执行期间可选的客户端连接检查的时间间隔,用于检查客户端是否仍然连接。检查通过轮询套接字执行;如果内核报告连接已经关闭,就可以更早中止长时间运行的查询。 - - 这个选项依赖于Linux、macOS、illumos和BSD家族操作系统暴露的内核事件, - 目前在其他系统上不可用。 + 此选项依赖 Linux、macOS、illumos 和 BSD 系列操作系统提供的内核事件,目前在其他系统上不可用。 - - 如果指定的值没有单位,则以毫秒为单位。 - 默认值为0,代表禁用连接检查。 - 没有连接检查,服务器将只在与套接字的下一次交互时检测连接的丢失,当它等待、接收或发送数据时。 + 如果指定值时没有单位,则以毫秒计。默认值为 0,表示禁用连接检查。如果不进行连接检查,服务器只有在下一次与套接字交互(等待、接收或发送数据)时,才会检测到连接丢失。 - - 为了让内核本身能够在包括网络故障在内的所有场景中,在已知的时间范围内可靠地检测丢失的TCP连接,它可能还需要调整操作系统的TCP保持连接设置, - 或者PostgreSQL, 设置。 - - - - - file_extend_method (enum) - - file_extend_method配置参数 - - - - - 指定在诸如COPY这类批量操作期间扩展数据文件时所使用的方法。 - 默认会根据操作系统选择第一个可用选项: - - - - posix_fallocate(Unix)使用标准 POSIX 接口分配磁盘空间,但某些系统缺少该接口。 - 如果接口存在但底层文件系统不支持,本选项会静默回退到write_zeros。 - 已知当前版本的 BTRFS 在使用该选项时会禁用压缩。 - 在提供该函数的系统上,这是默认值。 - - - - - write_zeros通过写出零字节块来扩展文件。 - 在不提供posix_fallocate函数的系统上,这是默认值。 - - - - 当数据文件扩展的块数不超过 8 个时,总是使用write_zeros方法。 + 要让内核本身在包括网络故障在内的所有场景中,能够在确定的时间范围内可靠地检测到 TCP 连接丢失,可能还需要调整操作系统的 TCP keepalive 设置,或 PostgreSQL 设置。 - - max_notify_queue_pages (integer) - - max_notify_queue_pages配置参数 - - - - - 指定 / 队列可分配页面的最大数量。 - 默认值是 1048576。对于 8 KB 页面,这允许最多消耗 8 GB 的磁盘空间。 - 此参数只能在服务器启动时设置。 - - - @@ -1011,7 +937,7 @@ include_dir 'conf.d' 设置服务器的Kerberos密钥文件的位置。 - 默认为FILE:/usr/local/pgsql/etc/krb5.keytab(其中目录部分是在构建时由sysconfdir指定的;用pg_config --sysconfdir来决定)。 + 默认为FILE:/usr/local/pgsql/etc/krb5.keytab(其中目录部分是在构建时由sysconfdir指定的;可用pg_config --sysconfdir来确定该目录)。 如果这个参数被设为空字符串,它将被忽略,并且系统依赖的默认值被应用。 这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 详情请参考。 @@ -1042,10 +968,7 @@ include_dir 'conf.d' - 设置是否应接受来自客户端的 GSSAPI 代理。默认值为off, - 这表示不会接受客户端的凭据。将其改为on会使服务器接受 - 客户端代理给它的凭据。此参数只能在postgresql.conf文件 - 或服务器命令行中设置。 + 设置是否接受客户端的 GSSAPI 委派。默认值为 off,表示不会接受客户端的凭证。将其改为 on 会使服务器接受客户端委派给它的凭证。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 @@ -1053,14 +976,10 @@ include_dir 'conf.d' - SSL - 查看以获取有关设置SSL的更多信息。 - 用TLS协议控制传输加密的配置参数被命名为ssl,出于历史原因, - 尽管对SSL协议的支持已被弃用。 - 在这种情况下,SSLTLS可互换使用。 + 关于 SSL 的设置,参见 。虽然对 SSL 协议的支持已被弃用,但由于历史原因,用于控制 TLS 协议传输加密的配置参数仍以 ssl 命名。在此语境中,SSLTLS 这两个术语可互换使用。 @@ -1144,13 +1063,13 @@ include_dir 'conf.d' 这个目录需要用OpenSSL 命令 openssl rehashc_rehash来准备。 - 详情参阅相应文档 + 详情参阅相应文档。 - 当使用此设置时,在连接时会按需加载指定目录下的CRLs。 - 新的CRLs可以添加到该目录中,并可以立即使用。 - 这与不同,那个会导致文件中的CRL在服务器启动时间或重新加载配置时加载。 + 当使用此设置时,在连接时会按需加载指定目录下的CRL。 + 新的CRL可以添加到该目录中,并可以立即使用。 + 这与不同,那个会导致文件中的CRL在服务器启动时或重新加载配置时加载。 两个设置可以一起使用。 @@ -1237,7 +1156,7 @@ include_dir 'conf.d' - 可用的密码组细节可能会随着OpenSSL 版本变化。 + 可用的密码套件细节可能会随着OpenSSL 版本变化。 可使用命令 openssl ciphers -v 'HIGH:MEDIUM:+3DES:!aNULL'来查看当前安装的OpenSSL版本的实际细节。 注意这个列表是根据服务器密钥类型在运行时过滤过的。 @@ -1252,43 +1171,30 @@ include_dir 'conf.d' - - 指定是否使用服务器的 SSL 密码首选项,而不是用客户端的。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 - 默认值是 on。 + 指定是否使用服务器的 SSL 密码套件优先顺序,而非客户端的优先顺序。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。默认值为 on - - 老的PostgreSQL版本没有这个设置并且总是使用客户端的首选项。这个设置主要用于与那些版本 - 的向后兼容性。使用服务器的首选项通常会更好,因为服务器更可能会被合适地配置。 + PostgreSQL 9.4 之前的版本没有此设置,始终采用客户端的优先顺序。此设置主要用于与这些旧版本保持向后兼容。采用服务器的优先顺序通常更好,因为服务器更可能得到适当配置。 - + + ssl_ecdh_curve (string) - ssl_ecdh_curve配置参数 + ssl_ecdh_curve 配置参数 - - 指定在 ECDH 密钥交换中使用的曲线名称。它需要被所有连接的客户端支持。 - 该参数只能在postgresql.conf文件中或服务器命令行上设置。 - 默认值为prime256v1。 + 指定在 ECDH 密钥交换中使用的曲线名称。所有连接的客户端都必须支持该曲线。它不必与服务器椭圆曲线密钥使用的曲线相同。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。默认值为 prime256v1 - - OpenSSL最常见的曲线名称是: - prime256v1 (NIST P-256)、 - secp384r1 (NIST P-384)、 - secp521r1 (NIST P-521)。 - openssl ecparam -list_curves 命令可以显示可用曲线的完整列表, - 但并非所有曲线都可用于 TLS,而且许多受支持的组名和别名并未列出。 + OpenSSL 中最常见的曲线名称为:prime256v1(NIST P-256)、secp384r1(NIST P-384)、secp521r1(NIST P-521)。可以用 openssl ecparam -list_curves 命令显示可用曲线的完整列表,但其中并非所有曲线都能用于 TLS - @@ -1300,19 +1206,14 @@ include_dir 'conf.d' - - 设置要使用的最小SSL/TLS协议版本。当前的可用版本包括: TLSv1, TLSv1.1, TLSv1.2, TLSv1.3. - 旧版本的 OpenSSL 库不支持所有值;如果选择了不支持的设置将会引发错误。 - TLS 1.0之前的协议版本,也就是SSL 版本 2 and 3,总是禁用的。 + 设置要使用的最低 SSL/TLS 协议版本。当前有效值为:TLSv1TLSv1.1TLSv1.2TLSv1.3。较旧版本的 OpenSSL 库不支持所有值;如果选择了不支持的设置,就会报错。TLS 1.0 之前的协议版本,即 SSL 2 和 3,始终被禁用。 - - 默认为TLSv1.2, 在本文撰写时的行业最佳实践。 + 默认值为 TLSv1.2,符合本文撰写时的行业最佳实践。 - - 这个参数只能在postgresql.conf文件中或通过服务器命令行进行设置。 + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 @@ -1325,15 +1226,11 @@ include_dir 'conf.d' - - 设定要使用的最大SSL/TLS协议版本。 - 有效的版本为 , 添加一个空字符串,允许任何协议版本。 - 默认为允许任何版本。设置最大协议版本主要用于测试,或者某个组件在与较新的协议配合工作时出现了问题。 + 设置要使用的最高 SSL/TLS 协议版本。有效值与 相同,此外还可设为空字符串,表示允许任意协议版本。默认允许任意版本。设置最高协议版本主要用于测试,或处理某些组件无法正常配合更新协议工作的问题。 - - 这个参数只能在postgresql.conf文件中或通过服务器命令行进行设置。 + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 @@ -1346,13 +1243,11 @@ include_dir 'conf.d' - - 指定含有用于SSL密码的所谓临时DH家族的Diffie-Hellman参数的文件名。默认值为空,这种情况下将使用内置的默认DH参数。使用自定义的DH参数可以降低攻击者破解众所周知的内置DH参数的风险。可以用命令openssl dhparam -out dhparams.pem 2048创建自己的DH参数文件。 + 指定包含 Diffie-Hellman 参数的文件名,这些参数用于所谓临时 DH 系列的 SSL 密码套件。默认值为空,此时使用编译时内置的默认 DH 参数。如果攻击者破解了众所周知的内置 DH 参数,使用自定义 DH 参数可以降低由此带来的风险。可以用命令 openssl dhparam -out dhparams.pem 2048 创建自己的 DH 参数文件。 - - 这个参数只能在postgresql.conf文件中或通过服务器命令行进行设置。 + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 @@ -1365,21 +1260,17 @@ include_dir 'conf.d' - - 设置当需要一个密码(例如一个私钥)来解密SSL文件时会调用的一个外部命令。默认情况下,这个参数为空,表示使用内置的提示机制。 + 设置获取用于解密私钥等 SSL 文件的口令时要调用的外部命令。默认值为空,表示使用内置的提示机制。 - - 该命令必须将密码打印到标准输出并且以代码0退出。在该参数值中,%p被替换为一个提示字符串(要得到文字%,应该写成%%)。注意该提示字符串将可能含有空格,因此要确保加上适当的引号。如果输出的末尾有单一的新行,它会被剥离掉。 + 该命令必须将口令输出到标准输出,并以退出码 0 结束。参数值中的 %p 会被替换为提示字符串。(要表示字面值 %,应写成 %%。)提示字符串可能包含空白,因此务必正确加引号。如果输出末尾有一个换行符,会将其去掉。 - - 该命令实际上并不一定要提示用户输入一个密码。它可以从文件中读取密码、从钥匙链得到密码等等。确保选中的机制足够安全是用户的责任。 + 该命令不一定要提示用户输入口令,也可以从文件读取口令、从钥匙链获取口令等。用户应自行确保所选机制足够安全。 - - 这个参数只能在postgresql.conf文件中或通过服务器命令行进行设置。 + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 @@ -1392,20 +1283,14 @@ include_dir 'conf.d' - - 这个参数决定在配置重载期间如果一个密钥文件需要密码时,是否也调用ssl_passphrase_command设置的密码命令。 - 如果这个参数为off(默认),那么在重载期间将忽略ssl_passphrase_command,如果在此期间需要密码则SSL配置将不会被重载。 - 对于要求一个TTY(当服务器正在运行时可能是不可用的)来进行提示的命令,这种设置是合适的。 - 例如,如果密码是从一个文件中得到的,将这个参数设置为on可能是合适的。 + 此参数决定:配置重载期间,如果密钥文件需要口令,是否也调用 ssl_passphrase_command 设置的口令命令。如果此参数为 off(默认值),则重载时会忽略 ssl_passphrase_command,如果需要口令,就不会重载 SSL 配置。此设置适合需要通过 TTY 提示用户的命令,因为服务器运行期间可能无法使用 TTY。例如,如果从文件中获取口令,则适合将此参数设为 on。 - 在Windows上运行时,必须将该参数设为on, - 因为该平台采用不同的进程模型,所有连接都会触发配置重载。 + 在 Windows 上运行时,必须将此参数设为 on,因为该平台的进程模型不同,每个连接都会执行配置重载。 - - 这个参数只能在postgresql.conf文件中或通过服务器命令行进行设置。 + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 @@ -1430,22 +1315,15 @@ include_dir 'conf.d' - - 设置数据库服务器将使用的共享内存缓冲区量。默认通常是 128 兆字节(128MB),但是如果你的内核设置不支持(在initdb时决定),那么可以会更少。 - 这个设置必须至少为 128 千字节。不过为了更好的性能,通常会使用明显高于最小值的设置。 - 如果指定值时没有单位,则以块为单位,即BLCKSZ字节,通常为8kB.(BLCKSZ 的非默认值改变最小值。) - 此参数只能在服务器启动时设置。 + 设置数据库服务器用于共享内存缓冲区的内存量。默认值通常为 128 兆字节(128MB),但如果内核设置不支持,则可能更小(在 initdb 期间确定)。此设置必须至少为 128 千字节。不过,要获得良好性能,通常需要远高于该最小值的设置。如果指定值时没有单位,则以块为单位,即 BLCKSZ 字节,通常为 8kB。(BLCKSZ 的非默认值会改变该最小值。)此参数只能在服务器启动时设置。 - - 如果有一个专用的 1GB 或更多内存的数据库服务器,一个合理的shared_buffers开始值是系统内存的 25%。即使更大的shared_buffers有效,也会造成一些工作负载, 但因为PostgreSQL同样依赖操作系统的高速缓冲区,将shared_buffers设置为超过 40% 的RAM不太可能比一个小点值工作得更好。为了能把对写大量新的或改变的数据的处理分布在一个较长的时间段内,shared_buffers更大的设置通常要求对max_wal_size也做相应增加。 + 如果专用数据库服务器具有 1GB 或更多内存,shared_buffers 的合理初始值是系统内存的 25%。对于某些工作负载,将 shared_buffers 设得更大也有效,但由于 PostgreSQL 同时依赖操作系统缓存,将超过 40% 的内存分配给 shared_buffers 不太可能比更小的值效果更好。将 shared_buffers 设得更大时,通常还需要相应增加 max_wal_size,以便将大量新数据或已修改数据的写入过程分散到更长的时间内。 - - 如果系统内存小于 1GB,一个较小的 RAM 百分数是合适的,这样可以为操作系统留下足够的空间。 + 对于内存少于 1GB 的系统,适合使用更小的内存比例,以便为操作系统留出足够空间。 - @@ -1459,7 +1337,7 @@ include_dir 'conf.d' - 控制是否为主共享内存区域请求巨型页。有效值是try(默认)、on以及off。该参数只能在服务器启动时设置。如果huge_pages被设置为try,则服务器将尝试请求巨型页,但是如果失败会退回到默认的方式。如果为on,请求巨型页失败将使得服务器无法启动。如果为off,则不会请求巨型页。 + 控制是否为主共享内存区域请求巨型页。有效值是try(默认)、on以及off。该参数只能在服务器启动时设置。如果huge_pages被设置为try,则服务器将尝试请求巨型页,但是如果失败会退回到默认的方式。如果为on,请求巨型页失败将使得服务器无法启动。如果为off,则不会请求巨型页。实际是否使用巨型页由服务器变量 表示。 @@ -1468,19 +1346,19 @@ include_dir 'conf.d' - 巨型页面的使用会导致更小的页面表以及花费在内存管理上的 CPU 时间更少,从而提高性能。更多有关Linux上使用巨型页面的细节请见。 + 巨型页的使用会导致更小的页表以及花费在内存管理上的 CPU 时间更少,从而提高性能。更多有关Linux上使用巨型页的细节请见 巨型页在Windows上被称为大页面。 要使用大页面,需要为运行PostgreSQL的Windows用户账号分配在内存中锁定页面的用户权限。 可以使用Windows的组策略工具(gpedit.msc)来分配用户权限在内存中锁定页面。 - 为了在命令窗口以单进程(而不是Windows服务)的方式启动数据库服务器,命令窗口必须以管理员身份运行或者禁用用户访问控制(UAC)。 + 为了在命令窗口以独立进程(而不是Windows服务)的方式启动数据库服务器,命令窗口必须以管理员身份运行或者禁用用户访问控制(UAC)。 当UAC被启用时,普通的命令窗口会在启动时收回用户权限在内存中锁定页面 - 注意这种设置仅影响主共享内存区域。Linux、FreeBSD以及Illumos之类的操作系统也能为普通内存分配自动使用巨型页(也被称为超级页或者页面),而不需要来自PostgreSQL的显式请求。在Linux上,这被称为transparent huge pagestransparent huge pages(THP,透明巨型页)。已知这种特性对某些Linux版本上的某些用户会导致PostgreSQL的性能退化,因此当前并不鼓励使用它(与huge_pages的显式使用不同)。 + 注意这种设置仅影响主共享内存区域。Linux、FreeBSD以及Illumos之类的操作系统也能为普通内存分配自动使用巨型页(也被称为超级页或者页面),而不需要来自PostgreSQL的显式请求。在Linux上,这被称为transparent huge pages透明巨型页(THP,透明巨型页)。已知这种特性对某些Linux版本上的某些用户会导致PostgreSQL的性能退化,因此当前并不鼓励使用它(与huge_pages的显式使用不同)。 @@ -1493,24 +1371,14 @@ include_dir 'conf.d' - - 控制巨型页的大小,当他们通过时。 - 默认为零 (0)。 - 当设置为0时,将使用系统默认的巨型页大小。 - 这个参数只能在服务器启动时设置。 + 控制通过 启用巨型页时所使用的页大小。默认值为零(0)。设置为 0 时,使用系统默认的巨型页大小。此参数只能在服务器启动时设置。 - - 一些现代64位服务器体系结构上常用的有效页尺寸包括: - 2MB1GB (Intel and AMD), - 16MB16GB (IBM POWER), - 还有 64kB, 2MB,32MB1GB (ARM). - 关于使用和支持的更多信息,参见。 + 现代 64 位服务器体系结构上常见的页大小包括:2MB1GB(Intel 和 AMD),16MB16GB(IBM POWER),以及 64kB2MB32MB1GB(ARM)。关于使用和支持的更多信息,参见 - - 非默认设置当前仅在Linux上支持。 + 目前只有 Linux 支持非默认设置。 @@ -1523,16 +1391,11 @@ include_dir 'conf.d' - - 为每个数据库会话设置用于临时缓冲区的最大内存.这些是仅用于访问临时表的会话本地缓冲。 - 如果指定值时没有单位,则以块为单位,即BLCKSZ字节,通常为8kB。 - 默认为8兆字节 (8MB)。(如果BLCKSZ不是8kB,则默认值按比例缩放。) - 这个设置可以在独立的会话内部被改变,但是只有在会话第一次使用临时表之前才能改变; 在会话中随后企图改变该值是无效的。 + 设置每个数据库会话用于临时缓冲区的最大内存量。这些是会话本地的缓冲区,仅用于访问临时表。如果指定值时没有单位,则以块为单位,即 BLCKSZ 字节,通常为 8kB。默认值为 8 兆字节(8MB)。(如果 BLCKSZ 不是 8kB,则默认值按比例变化。)可以在单个会话内更改此设置,但必须在该会话首次使用临时表之前更改;此后尝试更改该值,对该会话不会产生影响。 - - 一个会话将按照temp_buffers给出的限制根据需要分配临时缓冲区。如果在一个并不需要大量临时缓冲区的会话里设置一个大的数值, 其开销只是一个缓冲区描述符,或者说temp_buffers每增加一则增加大概 64 字节。不过,如果一个缓冲区被实际使用,那么它就会额外消耗 8192 字节(或者BLCKSZ字节)。 + 会话会按需分配临时缓冲区,上限为 temp_buffers。对于实际不需要很多临时缓冲区的会话,将此参数设得较大时,开销仅为 temp_buffers 每增加一就多分配一个缓冲区描述符,约为 64 字节。不过,如果实际使用了某个缓冲区,还会为它额外消耗 8192 字节(一般而言为 BLCKSZ 字节)。 @@ -1545,18 +1408,14 @@ include_dir 'conf.d' - - 设置可以同时处于prepared状态的事务的最大数目(见)。把这个参数设置 为零(这是默认设置)将禁用预备事务特性。这个参数只能在服务器启动时设置。 + 设置可同时处于预备状态的事务的最大数量(见 )。将此参数设为零(默认值)会禁用预备事务功能。此参数只能在服务器启动时设置。 - - 如果你不打算使用预备事务,可以把这个参数设置为零来防止意外创建预备事务。如果你正在使用预备事务,你将希望把max_prepared_transactions至少设置为一样大,因此每一个会话可以有一个预备事务待处理。 + 如果不打算使用预备事务,应将此参数设为零,以防意外创建预备事务。如果使用预备事务,通常应将 max_prepared_transactions 设为不小于 的值,以便每个会话都能有一个待处理的预备事务。 - - 当运行一个备库时,你必须设置这个参数等于或大于主库上的参数。 - 否则,备库上可能无法允许查询。 + 运行备库时,必须将此参数设为与主库相同或更大的值。否则,备库上将不允许执行查询。 @@ -1569,24 +1428,11 @@ include_dir 'conf.d' - - 设置查询操作(如排序或哈希表)在写入临时磁盘文件之前可使用的基本最大内存量。 - 如果未指定单位,则将其视为千字节。默认值为四兆字节(4MB)。 - 请注意,复杂查询可能同时执行多个排序和哈希操作, - 每个操作通常允许在开始将数据写入临时文件之前使用此值指定的内存量。 - 此外,可能有多个正在运行的会话同时执行此类操作。 - 因此,使用的总内存量可能是work_mem值的多倍; - 在选择值时必须牢记这一事实。排序操作用于ORDER BYDISTINCT和合并连接。 - 哈希表用于哈希连接、基于哈希的聚合、记忆节点和IN子查询的基于哈希的处理。 + 设置查询操作(如排序或哈希表)在写入临时磁盘文件之前可使用的基础最大内存量。如果未指定单位,则以千字节为单位。默认值为 4 兆字节(4MB)。请注意,复杂查询可能同时执行多个排序和哈希操作,每个操作在开始向临时文件写入数据之前,通常都可以使用此值指定的内存量。此外,多个正在运行的会话也可能并发执行此类操作。因此,使用的总内存量可能是 work_mem 值的数倍;选择此值时必须考虑这一点。排序操作用于 ORDER BYDISTINCT 和归并连接。哈希表用于哈希连接、基于哈希的聚合、Memoize 节点以及基于哈希的 IN 子查询处理。 - - 基于哈希的操作通常比等效的基于排序的操作更加敏感于内存可用性。 - 哈希表的内存限制是通过将work_mem乘以 - hash_mem_multiplier来计算的。这使得 - 基于哈希的操作可以使用超过通常的work_mem基本 - 量的内存。 + 与等效的排序操作相比,基于哈希的操作通常对可用内存更敏感。哈希表的内存上限由 work_mem 乘以 hash_mem_multiplier 计算得到。因此,基于哈希的操作可以使用超过通常的 work_mem 基础量的内存。 @@ -1599,17 +1445,11 @@ include_dir 'conf.d' - - 用于计算哈希操作可以使用的最大内存量。最终限制由将work_mem乘以hash_mem_multiplier确定。 - 默认值为2.0,这使得基于哈希的操作使用通常work_mem基础量的两倍。 + 用于计算基于哈希的操作可以使用的最大内存量。最终上限由 work_mem 乘以 hash_mem_multiplier 确定。默认值为 2.0,使基于哈希的操作可以使用通常的 work_mem 基础量的两倍。 - - 考虑在查询操作频繁溢出的环境中增加hash_mem_multiplier, - 特别是当简单增加work_mem导致内存压力时(内存压力通常表现为间歇性的内存不足错误)。 - 默认设置为2.0通常在混合工作负载中有效。在已将work_mem增加到40MB或更高的环境中, - 可以考虑将设置调高至2.0-8.0或更高。 + 如果查询操作经常溢写磁盘,可以考虑增加 hash_mem_multiplier,尤其是在单纯增加 work_mem 会导致内存压力的情况下(内存压力通常表现为间歇性的内存不足错误)。对于混合工作负载,默认值 2.0 通常有效。如果 work_mem 已增加到 40MB 或更高,则将该值进一步设为 2.0 - 8.0 或更高可能有效。 @@ -1622,19 +1462,11 @@ include_dir 'conf.d' - - 指定维护操作(如 VACUUMCREATE INDEX 和 - ALTER TABLE ADD FOREIGN KEY)可使用的最大内存量。 - 如果指定值时未带单位,则按千字节解释。默认值为 64 兆字节(64MB)。 - 由于数据库会话一次只能执行一个这样的操作,而一个安装通常也不会有很多此类操作并发运行, - 因此把该值设置得明显大于 work_mem 通常是安全的。更大的设置可能改善清理和恢复数据库转储的性能。 + 指定维护操作(如 VACUUMCREATE INDEXALTER TABLE ADD FOREIGN KEY)可使用的最大内存量。如果未指定单位,则以千字节为单位。默认值为 64 兆字节(64MB)。由于一个数据库会话一次只能执行一个此类操作,而一个数据库系统通常也不会并发运行很多此类操作,因此可以安全地将该值设得远大于 work_mem。更大的设置可能改善清理和恢复数据库转储的性能。 - - 注意当自动清理运行时,可能会分配最多达这个内存的倍,因此要小心不要把该默认值设置得太高。 - 通过独立地设置可能会对控制这种情况 - 有所帮助。 + 注意,自动清理运行时,最多可能分配此内存量的 倍,因此不要将默认值设得过高。单独设置 可能有助于控制这一点。 @@ -1647,15 +1479,10 @@ include_dir 'conf.d' - - 指定每个自动清理工作者进程能使用的最大内存量。 - 如果指定值时没有单位,则以千字节为单位。 - 其默认值为 -1,表示转而使用 的值。 - 当运行在其他上下文环境中时,这个设置对VACUUM的行为没有影响。 - 这个参数只能在postgresql.conf中或者服务器命令行上设置。 + 指定每个自动清理工作进程可使用的最大内存量。如果未指定单位,则以千字节为单位。默认值为 -1,表示改用 的值。该设置不影响其他上下文中运行的 VACUUM 的行为。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 - + @@ -1666,13 +1493,7 @@ include_dir 'conf.d' - VACUUMANALYZE命令使用的缓冲区访问策略大小。 - 设置为0将允许操作使用任意数量的shared_buffers。 - 否则,有效范围是 128KB 到 16GB。如果指定的大小超过shared_buffers的 1/8, - 将被静默限制到该值。默认值为 2MB。如果未指定单位,则视为千字节。 - 此参数可随时设置,并且可通过为 - 传递选项来覆盖。较高的设置可以让 - VACUUMANALYZE运行得更快,但设置过大可能会将过多有用页面从共享缓冲区逐出。 + 指定 VACUUMANALYZE 命令使用的缓冲区访问策略的大小。设为 0 时,允许操作使用任意数量的 shared_buffers 缓冲区。否则,有效大小范围为 128 kB16 GB。如果指定的大小超过 shared_buffers 大小的 1/8,则会在不提示的情况下限制为该值。默认值为 2MB。如果未指定单位,则以千字节为单位。此参数可以随时设置。在执行 时,可以通过 选项覆盖此设置。较大的设置可能使 VACUUMANALYZE 运行得更快,但设置过大可能会将过多其他有用页面逐出共享缓冲区。 @@ -1685,13 +1506,10 @@ include_dir 'conf.d' - - 指定逻辑解码要使用的最大内存量,在将某些解码的更改写入本地磁盘之前。 - 这将限制逻辑流复制连接使用的内存量。它默认为 64 兆字节(64MB)。 - 由于每个复制连接仅使用此大小的单个缓冲区,并且安装通常不会同时具有多个此类连接(受 max_wal_senders 的限制),因此将此值设置得明显高于 work_mem是安全的,从而减少写入磁盘的解码更改数量。 + 指定逻辑解码在将部分已解码的更改写入本地磁盘之前可使用的最大内存量。它限制了流式逻辑复制连接使用的内存量。默认值为 64 兆字节(64MB)。由于每个复制连接仅使用一个此大小的缓冲区,而一个数据库系统通常不会同时有很多此类连接(受 max_wal_senders 限制),因此可以安全地将该值设得远高于 work_mem,以减少写入磁盘的已解码更改数量。 - + @@ -1704,7 +1522,7 @@ include_dir 'conf.d' 指定用于缓存pg_commit_ts内容的内存量 (参见)。如果未指定单位,则视为块, - 即BLCKSZ字节,通常为 8KB。默认值为0, + 即BLCKSZ字节,通常为 8kB。默认值为0, 这会请求shared_buffers/512,最多 1024 个块、最少 16 个块。 此参数只能在服务器启动时设置。 @@ -1721,7 +1539,7 @@ include_dir 'conf.d' 指定用于缓存pg_multixact/members内容的共享内存量 (参见)。如果未指定单位,则视为块, - 即BLCKSZ字节,通常为 8KB。默认值为 32。此参数只能在服务器启动时设置。 + 即BLCKSZ字节,通常为 8kB。默认值为 32。此参数只能在服务器启动时设置。 @@ -1736,7 +1554,7 @@ include_dir 'conf.d' 指定用于缓存pg_multixact/offsets内容的共享内存量 (参见)。如果未指定单位,则视为块, - 即BLCKSZ字节,通常为 8KB。默认值为 16。此参数只能在服务器启动时设置。 + 即BLCKSZ字节,通常为 8kB。默认值为 16。此参数只能在服务器启动时设置。 @@ -1751,7 +1569,7 @@ include_dir 'conf.d' 指定用于缓存pg_notify内容的共享内存量 (参见)。如果未指定单位,则视为块, - 即BLCKSZ字节,通常为 8KB。默认值为 16。此参数只能在服务器启动时设置。 + 即BLCKSZ字节,通常为 8kB。默认值为 16。此参数只能在服务器启动时设置。 @@ -1766,7 +1584,7 @@ include_dir 'conf.d' 指定用于缓存pg_serial内容的共享内存量 (参见)。如果未指定单位,则视为块, - 即BLCKSZ字节,通常为 8KB。默认值为 32。此参数只能在服务器启动时设置。 + 即BLCKSZ字节,通常为 8kB。默认值为 32。此参数只能在服务器启动时设置。 @@ -1781,7 +1599,7 @@ include_dir 'conf.d' 指定用于缓存pg_subtrans内容的共享内存量 (参见)。如果未指定单位,则视为块, - 即BLCKSZ字节,通常为 8KB。默认值为0, + 即BLCKSZ字节,通常为 8kB。默认值为0, 这会请求shared_buffers/512,最多 1024 个块、最少 16 个块。 此参数只能在服务器启动时设置。 @@ -1798,7 +1616,7 @@ include_dir 'conf.d' 指定用于缓存pg_xact内容的共享内存量 (参见)。如果未指定单位,则视为块, - 即BLCKSZ字节,通常为 8KB。默认值为0, + 即BLCKSZ字节,通常为 8kB。默认值为0, 这会请求shared_buffers/512,最多 1024 个块、最少 16 个块。 此参数只能在服务器启动时设置。 @@ -1816,8 +1634,8 @@ include_dir 'conf.d' 指定服务器执行栈的最大安全深度。此参数的理想设置是由内核强制执行的实际栈大小限制 - (如由ulimit -s或本地等效设置),减去大约一兆字节的安全边界。 - 需要安全边界是因为服务器中并非每个例程都检查栈深度,而只在关键的潜在递归例程中检查。 + (如由ulimit -s或本地等效设置),减去大约一兆字节的安全余量。 + 需要安全余量是因为服务器中并非每个例程都检查栈深度,而只在关键的潜在递归例程中检查。 如果未指定单位,则将其视为千字节。默认设置为两兆字节(2MB), 这是保守且不太可能引起崩溃的小值。但是,这可能太小,无法执行复杂函数。 只有超级用户和具有适当SET权限的用户才能更改此设置。 @@ -1837,12 +1655,8 @@ include_dir 'conf.d' - - 指定服务器应用于主共享内存区域的共享内存实现,包括 PostgreSQL 的共享缓冲区和其他共享数据。 - 可能的值为 mmap (对使用 mmap 分配的匿名共享内存),sysv (通过 shmget 分配的系统V 共享内存),和windows (Windows共享内存)。 - 并非在所有平台上都支持全部值;第一个被支持的选项是该平台的默认选项。 - sysv 选项不是任何平台的默认选项,通常不建议使用,因为它通常需要非默认的内核设置来允许大量的地址分配(参见 )。 + 指定服务器用于主共享内存区域的共享内存实现,该区域存放 PostgreSQL 的共享缓冲区及其他共享数据。可选值为 mmap(使用 mmap 分配的匿名共享内存)、sysv(通过 shmget 分配的 System V 共享内存)和 windows(Windows 共享内存)。并非所有平台都支持所有值;第一个受支持的选项是该平台的默认值。sysv 不是任何平台的默认选项,通常不建议使用,因为它一般需要更改内核的默认设置才能分配大量内存(见 )。此参数只能在服务器启动时设置。 @@ -1855,16 +1669,8 @@ include_dir 'conf.d' - - 指定服务器应该使用的动态共享内存实现。可能的值包括posix(使用shm_open分配的POSIX共享内存), - sysv(通过shmget分配的System V共享内存), - windows(用于Windows共享内存), - 和mmap(使用存储在数据目录中的内存映射文件模拟共享内存)。 - 并非所有平台都支持所有值;通常第一个支持的选项是该平台的默认值。 - 通常不建议使用mmap选项,因为操作系统可能会反复将修改的页面写回磁盘,增加系统I/O负载; - 但在调试时,当pg_dynshmem目录存储在RAM磁盘上,或者其他共享内存设施不可用时,可能会有用。 - 该参数只能在服务器启动时设置。 + 指定服务器应使用的动态共享内存实现。可选值为 posix(使用 shm_open 分配的 POSIX 共享内存)、sysv(通过 shmget 分配的 System V 共享内存)、windows(Windows 共享内存)、mmap(使用存放在数据目录中的内存映射文件模拟共享内存)。并非所有平台都支持所有值;第一个受支持的选项通常是该平台的默认值。mmap 不是任何平台的默认选项,通常不建议使用,因为操作系统可能会反复将修改过的页面写回磁盘,增加系统 I/O 负载;不过,在调试、将 pg_dynshmem 目录存放在 RAM 磁盘上,或其他共享内存设施不可用时,它可能有用。此参数只能在服务器启动时设置。 @@ -1877,13 +1683,8 @@ include_dir 'conf.d' - - 指定在服务器启动时将要分配给并行查询使用的内存容量。 - 当此内存区域不够用或被并发查询耗尽时,新的并行查询尝试使用dynamic_shared_memory_type配置的方法从操作系统临时分配额外的共享内存,由于内存管理开销该方法可能慢一些。 - 在启动时由min_dynamic_shared_memory分配的内存受到操作系统上所支持的huge_pages设置的影响,并且在自动管理的操作系统上更可能从较大的页面中受益。 - 默认值是0(无)。 - 该参数只能在服务器启动时设置。 + 指定服务器启动时为并行查询分配的内存量。当此内存区域不足或被并发查询耗尽时,新的并行查询会尝试使用 dynamic_shared_memory_type 配置的方法,临时向操作系统分配额外的共享内存;由于内存管理开销,这可能较慢。在支持 huge_pages 设置的操作系统上,启动时通过 min_dynamic_shared_memory 分配的内存会受到该设置的影响;在自动管理巨型页的操作系统上,这些内存也可能更容易受益于较大的页。默认值为 0(不分配)。此参数只能在服务器启动时设置。 @@ -1904,17 +1705,57 @@ include_dir 'conf.d' + + 指定一个进程可用于临时文件的最大磁盘空间,例如排序和哈希临时文件,或保留游标的存储文件。尝试超过此限制的事务将被取消。如果未指定单位,则以千字节为单位。-1(默认值)表示没有限制。只有超级用户和具有适当 SET 权限的用户才能更改此设置。 + + + 此设置限制单个 PostgreSQL 进程在任意时刻使用的所有临时文件的总空间。需要注意,显式临时表所用的磁盘空间计入该上限;计入的是查询执行过程中内部使用的临时文件。 + + + + + file_extend_method (enum) + + file_extend_method配置参数 + + + - 指定进程可以用于临时文件(如排序和哈希临时文件)或保留游标的存储文件的最大磁盘空间。 - 尝试超过此限制的事务将被取消。 - 如果未指定单位,则将其视为千字节。 - -1(默认值)表示没有限制。 - 只有超级用户和具有适当SET权限的用户才能更改此设置。 + 指定在诸如COPY这类批量操作期间扩展数据文件时所使用的方法。 + 默认会根据操作系统选择第一个可用选项: + + + + posix_fallocate(Unix)使用标准 POSIX 接口分配磁盘空间,但某些系统缺少该接口。 + 如果接口存在但底层文件系统不支持,本选项会静默回退到write_zeros。 + 已知当前版本的 BTRFS 在使用该选项时会禁用压缩。 + 在提供该函数的系统上,这是默认值。 + + + + + write_zeros通过写入全零数据块来扩展文件。 + 在不提供posix_fallocate函数的系统上,这是默认值。 + + + + 当数据文件扩展的块数不超过 8 个时,总是使用write_zeros方法。 + + + + max_notify_queue_pages (integer) + + max_notify_queue_pages配置参数 + + + - 这个设置约束着一个给定PostgreSQL进程在任何瞬间所使用的所有临时文件的总空间。应该注意的是,与在查询执行中在幕后使用的临时文件相反,显式临时表所用的磁盘空间被这个设置所限制。 + 指定 / 队列可分配页面的最大数量。 + 默认值是 1048576。对于 8 KB 页面,这允许最多消耗 8 GB 的磁盘空间。 + 此参数只能在服务器启动时设置。 @@ -1935,35 +1776,32 @@ include_dir 'conf.d' - - 设置每个服务器子进程允许同时打开的最大文件数。默认值是一千个文件。 - - - 如果内核强制实施了安全的每进程上限,你通常不必担心这个设置。但在某些平台上 - (尤其是大多数 BSD 系统),如果许多进程都尝试打开大量文件,内核可能允许单个进程打开的文件数 - 远超系统在整体上真正能够支持的数量。如果你看到打开的文件过多之类的失败, - 可以尝试减小这个设置。这个参数只能在服务器启动时设置。 + 设置每个服务器子进程允许同时打开的最大文件数量。默认值为一千个文件。如果内核强制实施了安全的每进程上限,就不必担心此设置。但在某些平台上(尤其是大多数 BSD 系统),内核允许单个进程打开的文件数量很大,如果很多进程都尝试打开这么多文件,就会远超系统实际能够支持的总量。如果遇到 Too many open files(打开的文件过多)错误,可尝试减小此设置。此参数只能在服务器启动时设置。 - + + 基于代价的清理延迟 - 在命令的执行过程中,系统维持着一个内部计数器来跟踪各种被执行的I/O操作的估算开销。当累计的代价达到一个限制(由vacuum_cost_limit指定),执行这些操作的进程将按照vacuum_cost_delay所指定的休眠一小段时间。然后它将重置计数器并继续执行。 + 执行 命令期间,系统维护一个内部计数器,记录已执行的各种 I/O 操作的估算代价。 + 当累计代价达到上限(由 vacuum_cost_limit 指定)时,执行该操作的进程会休眠一小段时间,时长由 vacuum_cost_delay 指定。 + 随后重置计数器并继续执行。 - 这个特性的出发点是允许管理员降低这些命令对并发的数据库活动产生的I/O影响。在很多情况下,VACUUMANALYZE等维护命令能否快速完成并不重要,而非常重要的是这些命令不会对系统执行其他数据库操作的能力产生显著的影响。基于代价的清理延迟提供了一种方式让管理员能够保证这一点。 + 此功能让管理员能够降低这些命令对并发数据库活动的 I/O 影响。在许多情况下,VACUUMANALYZE 等维护命令是否快速完成并不重要, + 但避免它们显著干扰系统执行其他数据库操作的能力通常很重要。基于代价的清理延迟为管理员提供了实现这一点的方法。 - 对于手动发出的VACUUM命令,该特性默认被禁用。要启用它,只要把vacuum_cost_delay变量设为一个非零值。 + 对于手动执行的 VACUUM 命令,此功能默认禁用。要启用它,将 vacuum_cost_delay 变量设为非零值。 @@ -1975,19 +1813,13 @@ include_dir 'conf.d' - - - 当超出开销限制时进程将要休眠的时间量。如果指定值时没有单位,则以毫秒为单位。 - 其默认值为0,这将禁用基于代价的清理延迟特性。正值将启用基于代价的清理。 - - - - 在使用基于代价的清理时,vacuum_cost_delay的合适值通常很小,也许是小于1毫秒。 - 虽然vacuum_cost_delay可以被设置为毫秒级别的值,但是在较老的平台上可能无法准确地测量这种延迟。 - 在这样的平台上,增加 VACUUM的节流资源消耗在1ms以上,需要改变其他的清理开销参数。 - 尽管如此,你应该保持 vacuum_cost_delay 在平台能持续测量的情况下尽可能小;大延迟没有帮助。 - - + + 超过代价上限后,进程将休眠的时长。如果未指定单位,则以毫秒为单位。默认值为 0,表示禁用基于代价的清理延迟功能。正值会启用基于代价的清理。 + + + 使用基于代价的清理时,vacuum_cost_delay 的合适值通常很小,可能不到 1 毫秒。虽然 vacuum_cost_delay 可以设为以毫秒为单位的小数值,但较旧的平台可能无法准确计量这种延迟。在这些平台上,若要让 VACUUM 的资源用量超过延迟设为 1ms 时的水平,需要调整其他清理代价参数。尽管如此,仍应将 vacuum_cost_delay 设为平台能够稳定计量的尽可能小的值;较大的延迟没有帮助。 + + @@ -1998,11 +1830,10 @@ include_dir 'conf.d' - - - 清理一个在共享缓存中找到的缓冲区的估计代价。它表示锁住缓冲池、查找共享哈希表和扫描页内容的代价。默认值为1。 - - + + 清理在共享缓冲区缓存中找到的缓冲区时所计入的估算代价。它表示锁定缓冲池、查找共享哈希表和扫描页内容的代价。默认值为 1。 + + @@ -2013,13 +1844,10 @@ include_dir 'conf.d' - - - 清理一个必须从磁盘上读取的缓冲区的代价。 - 它表示锁住缓冲池、查找共享哈希表、从磁盘读取需要的块以及扫描其内容的代价。 - 默认值为2。 - - + + 清理必须从磁盘读取的缓冲区时所计入的估算代价。它表示锁定缓冲池、查找共享哈希表、从磁盘读取所需数据块并扫描其内容所需的工作量。默认值为 2。 + + @@ -2030,11 +1858,10 @@ include_dir 'conf.d' - - - 当清理修改一个之前干净的块时需要花费的估计代价。它表示再次把脏块刷出到磁盘所需要的额外I/O。默认值为20。 - - + + 清理操作修改原本干净的数据块时所计入的估算代价。它表示再次将脏块刷盘所需的额外 I/O。默认值为 20。 + + @@ -2045,34 +1872,31 @@ include_dir 'conf.d' - - - 将导致清理进程休眠的累计代价。默认值为200。 - - + + 会使清理进程休眠 vacuum_cost_delay 指定时长的累计代价。默认值为 200。 + + - - 有些操作会保持关键性的锁,这样可以尽快完成。基于代价的清理延迟在这类操作期间不会发生。因此有可能代价会累计至大大超过指定的限制。为了防止在这种情况下的无意义的长时间延迟,实际延迟的计算方式是vacuum_cost_delay * - accumulated_balance / - vacuum_cost_limit,且最大值是vacuum_cost_delay * 4。 + 某些操作持有关键的锁,因此应尽快完成。这些操作期间不会发生基于代价的清理延迟,所以累计代价可能远超指定上限。 + 为避免此时出现无益的长时间延迟,实际延迟按 vacuum_cost_delay * accumulated_balance / vacuum_cost_limit 计算, + 但最大不超过 vacuum_cost_delay * 4。 - - 后台写入器 - 有一个独立的服务器进程,叫做后台写入器,它的功能就是发出写(新的或修改过的)共享缓冲区的命令。 - 当干净的共享缓存数量出现不足时,后台写入器写入一些脏缓存到文件系统,并标记为干净。 - 不过,后台写入器确实会增加 I/O 的总负荷,因为虽然在每个检查点间隔中一个重复弄脏的页面可能只会写出一次,但在同一个间隔中后台写入器可能会把它写出好几次。 - 在这一小节讨论的参数可以被用于调节本地需求的行为。 + 有一个独立的服务器进程,称为后台写入器,负责写出(新的或修改过的)共享缓冲区。 + 当干净的共享缓冲区数量似乎不足时,后台写入器会将一些脏缓冲区写入文件系统,并将其标记为干净。 + 这可以降低处理用户查询的服务器进程找不到干净缓冲区、因而不得不自行写出脏缓冲区的可能性。 + 不过,后台写入器确实会使总体 I/O 负载有所增加:反复变脏的页面原本可能在每个检查点间隔中只写出一次, + 而后台写入器可能在同一间隔内随着它变脏而多次写出。本节参数可用于根据实际需求调整此行为。 @@ -2084,13 +1908,10 @@ include_dir 'conf.d' - - - 指定后台写入器活动轮次之间的延迟。在每个轮次中,写入器都会为一定数量的脏缓冲区发出写操作(可以用下面的参数控制)。 - 然后它就休眠 bgwriter_delay的时长, 然后重复动作。当缓冲池中没有脏缓冲区时,不管 bgwriter_delay,它都会进入更长的休眠。如果指定值时没有单位,则以毫秒为单位。默认值是 200 毫秒(200ms)。 - 注意在许多系统上,休眠延迟的有效解析度是 10 毫秒;因此,为bgwriter_delay设置一个 不是 10 的倍数的值与把它设置为下一个更高的 10 的倍数是一样的效果。这个选项只能在服务器命令行上或者在postgresql.conf文件中设置。 - - + + 指定后台写入器各轮活动之间的延迟。每一轮中,写入器会对一定数量的脏缓冲区发出写操作(由下面的参数控制),然后休眠 bgwriter_delay 指定的时长,再重复此过程。不过,当缓冲池中没有脏缓冲区时,它会进入更长的休眠,而不受 bgwriter_delay 限制。如果未指定单位,则以毫秒为单位。默认值为 200 毫秒(200ms)。注意,在某些系统上,休眠延迟的有效分辨率为 10 毫秒;将 bgwriter_delay 设为不是 10 的倍数的值,可能与将它设为下一个更大的 10 的倍数效果相同。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 + + @@ -2101,11 +1922,10 @@ include_dir 'conf.d' - - - 在每个轮次中,不超过这么多个缓冲区将被后台写入器写出。把这个参数设置为零可禁用后台写出(注意被一个独立、专用辅助进程管理的检查点不受影响)。默认值是 100 个缓冲区。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 - - + + 后台写入器每轮写出的缓冲区数量不会超过此值。设为零会禁用后台写入。(由另一个独立的专用辅助进程管理的检查点不受影响。)默认值为 100 个缓冲区。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 + + @@ -2116,11 +1936,10 @@ include_dir 'conf.d' - - - 每一轮次要写的脏缓冲区的数目基于最近几个轮次中服务器进程需要的新缓冲区的数目。 最近所需的平均值乘以bgwriter_lru_multiplier可以估算下一轮次中将会需要的缓冲区数目。脏缓冲区将被写出直到有很多干净可重用的缓冲区(然而,每一轮次中写出的缓冲区数不超过bgwriter_lru_maxpages)。 因此,设置为 1.0 表示一种刚刚好的策略,这种策略会写出正好符合预测值的数目的缓冲区。 更大大的值可以为需求高峰提供某种缓冲,而更小的值则需要服务进程来处理一些写出操作。默认值是 2.0。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 - - + + 每轮写出的脏缓冲区数量取决于最近几轮服务器进程所需的新缓冲区数量。将近期平均需求乘以 bgwriter_lru_multiplier,即可估算下一轮所需的缓冲区数量。写入器会写出脏缓冲区,直到可用的干净且可重用缓冲区达到这一数量。(不过,每轮写出的缓冲区数量不会超过 bgwriter_lru_maxpages。)因此,设为 1.0 表示采用恰好及时策略,写出的缓冲区数量恰好等于预测需求量。更大的值可为需求突增留出余量,而更小的值则有意将部分写操作留给服务器进程执行。默认值为 2.0。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 + + @@ -2131,18 +1950,16 @@ include_dir 'conf.d' - - - 只要后台写入的数据超过这个数量,尝试强制 OS 把这些写发送到底层存储上。这样做将限制内核页缓存中脏数据的量,降低了在检查点末尾发出一个 fsync 时或者 OS 在后台大批量写回数据时卡住的可能性。 - 那常常会导致大幅度压缩的事务延迟,但是也有一些情况(特别是负载超过但小于 OS 页面高速缓存)的性能会降低。这种设置可能会在某些平台上没有效果。 - 如果指定值时没有单位,则以块为单位,即为BLCKSZ 字节,通常为8kB.合法的范围在0(禁用受控写回)和2MB之间。Linux 上的默认值是512kB,其他平台上是0(如果BLCKSZ不是8kB,则默认值和最大值会按比例缩放至这个值)。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 - - + + 每当后台写入器写出的数据超过此数量时,就尝试强制操作系统将这些写操作发往底层存储。这样可以限制内核页缓存中的脏数据量,降低在检查点结束时调用 fsync,或操作系统在后台以较大批次写回数据时发生停顿的可能性。通常,这能大幅降低事务延迟,但在某些情况下性能可能下降,尤其是工作负载大于 而小于操作系统页缓存时。此设置在某些平台上可能没有效果。如果未指定单位,则以块为单位,即 BLCKSZ 字节,通常为 8kB。有效范围为 0(禁用强制写回)至 2MB。Linux 上的默认值为 512kB,其他平台为 0。(如果 BLCKSZ 不是 8kB,默认值和最大值将按比例变化。)此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 + + - 较小的bgwriter_lru_maxpagesbgwriter_lru_multiplier可以降低由后台写入器造成的额外 I/O 开销。但更可能的是,服务器进程将必须自己发出写入操作,这会延迟交互式查询。 + 较小的 bgwriter_lru_maxpagesbgwriter_lru_multiplier 可以降低后台写入器造成的额外 I/O 负载, + 但也会增加服务器进程必须自行发出写操作的可能性,从而延迟交互式查询。 @@ -2159,18 +1976,10 @@ include_dir 'conf.d' - - - 当单个后端写入数据的量超过这个数量时,尝试强制操作系统发送这些写入到底层存储。 - 这样做将限制内核的页面缓存中的脏数据量,降低在检查点末尾发出fsync时暂停的可能性,或者当操作系统在后台大批量的写回数据时。 - 通常的结果会大大减少事务延迟,但也有一些情况,特别是当工作负载大于,但小于操作系统的页面缓存时,性能可能会下降。 - 此设置在某些平台上可能无效。 - 如果指定此值时没有单位,则将其作为块,即BLCKSZ字节,通常为8kB。 - 有效范围在0,禁止强制回写,和2MB之间。 - 默认值是0,即没有强制回写。 - (如果BLCKSZ不是8kB,则最大值按其比例缩放。) - - + + 每当单个后端写出的数据超过此数量时,就尝试强制操作系统将这些写操作发往底层存储。这样可以限制内核页缓存中的脏数据量,降低在检查点结束时调用 fsync,或操作系统在后台以较大批次写回数据时发生停顿的可能性。通常,这能大幅降低事务延迟,但在某些情况下性能可能下降,尤其是工作负载大于 而小于操作系统页缓存时。此设置在某些平台上可能没有效果。如果未指定单位,则以块为单位,即 BLCKSZ 字节,通常为 8kB。有效范围为 0(禁用强制写回)至 2MB。默认值为 0,即不强制写回。(如果 BLCKSZ 不是 8kB,最大值将按比例变化。) + + @@ -2181,23 +1990,19 @@ include_dir 'conf.d' - - - 设置PostgreSQL预期可以同时执行的并发存储 I/O 操作数量。提高该值会增加任何单个PostgreSQL会话尝试并行发起的 I/O 操作数。允许的范围是11000,或者0表示禁用异步 I/O 请求。默认值是16。 - - - - 较高的值对高延迟存储和高 IOPS 设备影响最大,否则查询会经历明显的 I/O 停顿。不必要地设置过高,可能会增加系统中所有查询的 I/O 延迟。 - - - - 在支持预取建议的系统上,effective_io_concurrency还控制预取距离。 - - - - 对于位于特定表空间中的表,可以通过设置同名的表空间参数覆盖该值(见)。 - - + + 设置 PostgreSQL 预期可以同时执行的并发磁盘 I/O 操作数量。提高此值会增加单个 PostgreSQL 会话尝试并行发起的 I/O 操作数量。允许的范围为 1 至 1000,或设为零以禁用异步 I/O 请求。目前,此设置仅影响位图堆扫描。 + + + 对于磁盘,可以将为数据库提供存储的 RAID 0 条带或 RAID 1 镜像中的独立磁盘数量作为合理初始值。(对于 RAID 5,不应计入校验盘。)不过,如果数据库经常忙于执行并发会话发出的多个查询,较小的值可能就足以使磁盘阵列保持繁忙。超过使磁盘保持繁忙所需的值只会增加 CPU 开销。SSD 和其他基于内存的存储通常可以处理大量并发请求,因此最佳值可能达到数百。 + + + 异步 I/O 依赖于有效的 posix_fadvise 函数,而某些操作系统缺少此函数。如果该函数不存在,将此参数设为任何非零值都会报错。在某些操作系统(如 Solaris)上,该函数虽然存在,却实际上不做任何事情。 + + + 支持此功能的系统上默认值为 1,其他系统为 0。对于位于特定表空间中的表,可以通过设置同名的表空间参数覆盖此值(见 )。 + + @@ -2208,15 +2013,13 @@ include_dir 'conf.d' - - - 与effective_io_concurrency相似,但用于支持许多客户端会话完成的维护工作。 - - - 默认值是16。对于位于特定表空间中的表,可以通过设置同名的表空间参数覆盖该值(见)。 - - + 与 effective_io_concurrency 类似,但用于为多个客户端会话执行的维护工作。 + + + 支持此功能的系统上默认值为 10,其他系统为 0。对于位于特定表空间中的表,可以通过设置同名的表空间参数覆盖此值(见 )。 + + io_combine_limit (integer) @@ -2226,12 +2029,7 @@ include_dir 'conf.d' - 控制合并 I/O 操作时允许的最大 I/O 大小。如果设置值高于 - io_max_combine_limit 参数,则会静默使用较低的那个值, - 因此如果要增大 I/O 大小,可能需要同时提高这两个参数。 - 如果该值未指定单位,则按块计算,也就是 BLCKSZ 字节,通常为 8kB。 - 最大可能值取决于操作系统和块大小,但在 Unix 上通常为 1MB,在 Windows 上通常为 128kB。 - 默认值是 128kB。 + 控制合并 I/O 操作时允许的最大 I/O 大小。如果未指定单位,则以块为单位,即 BLCKSZ 字节,通常为 8kB。默认值为 128kB。 @@ -2244,20 +2042,16 @@ include_dir 'conf.d' - - - 设置系统能够支持的后台进程的最大数量。这个参数只能在服务器启动时设置。默认值为 8。 - - - - 在运行一个备库时,你必须把这个参数设置为等于或者高于主库上的值。 - 否则,备库上可能不会允许查询。 - - - - 在更改这个值时,考虑也对以及进行调整。 - - + + 设置集簇能够支持的后台进程的最大数量。此参数只能在服务器启动时设置。默认值为 8。 + + + 运行备库时,必须将此参数设为与主库相同或更大的值。否则,备库上将不允许执行查询。 + + + 更改此值时,也应考虑调整 、&zwsp;、&zwsp;。 + + @@ -2268,19 +2062,16 @@ include_dir 'conf.d' - - - 设置单个Gather或者Gather Merge节点能够开始的工作者的最大数量。并行工作者会从建立的进程池中取得,数量由限制。注意所要求的工作者数量在运行时可能实际无法被满足。如果这种事情发生,该计划将会以比预期更少的工作者运行,这可能会不太高效。默认值是2。把这个值设置为0将会禁用并行查询执行。 - - - - 注意并行查询可能消耗比非并行查询更多的资源,因为每一个工作者进程时一个完全独立的进程,它对系统产生的影响大致和一个额外的用户会话相同。在为这个设置选择值时,以及配置其他控制资源利用的设置(例如)时,应该把这个因素考虑在内。work_mem之类的资源限制会被独立地应用于每一个工作者,这意味着所有进程的总资源利用可能会比单个进程时高得多。例如,一个使用 4 个工作者的并行查询使用的 CPU 时间、内存、I/O 带宽可能是不使用工作者时的 5 倍之多。 - - - - 并行查询的更多信息请见。 - - + + 设置单个 GatherGather Merge 节点能够启动的工作进程的最大数量。并行工作进程取自 建立的进程池,并受到 的限制。注意,运行时实际可用的工作进程可能不足请求的数量。此时,计划会使用少于预期的工作进程运行,效率可能较低。默认值为 2。设为 0 会禁用并行查询执行。 + + + 注意,并行查询消耗的资源可能远多于非并行查询,因为每个工作进程都是完全独立的进程,对系统的影响大致相当于额外增加一个用户会话。选择此设置的值,以及配置其他控制资源使用的设置(如 )时,都应考虑这一点。work_mem 等资源限制分别应用于每个工作进程,因此所有进程的总资源用量可能远高于单个进程通常的用量。例如,使用 4 个工作进程的并行查询,其 CPU 时间、内存、I/O 带宽等用量可能达到完全不使用工作进程的查询的 5 倍。 + + + 并行查询的更多信息参见 。 + + @@ -2290,19 +2081,14 @@ include_dir 'conf.d' max_parallel_maintenance_workers配置参数 - - - - 设置单一工具性命令能够启动的并行工作者的最大数目。 - 当前,支持使用并行工作者的工具性命令是CREATE INDEX,并且只有在构建B-树索引时才能并行,并且 VACUUM 没有 FULL选项。 - 并行工作者从由创建的进程池中取出,数量由控制。 - 注意实际在运行时所请求数量的工作者可能不可用。如果发生这种情况,工具性操作将使用比预期数量少的工作者运行。默认值为2。将这个值设置为0可以禁用工具性命令对并行工作者的使用。 - - - - 注意并行工具性命令不应该消耗比同等数量非并行操作更多的内存。这种策略与并行查询不同,并行查询的资源限制通常是应用在每个工作者进程上。并行工具性命令把资源限制maintenance_work_mem当作对整个工具性命令的限制,而不管其中用到了多少个并行工作者进程。不过,并行工具性命令实际上可能仍会消耗更多的CPU资源和I/O带宽。 - - + + + 设置单个工具命令能够启动的并行工作进程的最大数量。目前,支持使用并行工作进程的工具命令包括:构建 B-树或 BRIN索引时的 CREATE INDEX,以及不带 FULL 选项的 VACUUM。并行工作进程取自 建立的进程池,并受到 的限制。注意,运行时实际可用的工作进程可能不足请求的数量。此时,工具操作会使用少于预期的工作进程运行。默认值为 2。设为 0 会禁止工具命令使用并行工作进程。 + + + 注意,并行工具命令的内存消耗不应明显高于等效的非并行操作。这与并行查询的策略不同,后者的资源限制通常分别应用于每个工作进程。并行工具命令将 maintenance_work_mem 视为整个工具命令的资源上限,而不论使用多少个并行工作进程。不过,并行工具命令仍可能消耗多得多的 CPU 资源和 I/O 带宽。 + + @@ -2313,17 +2099,14 @@ include_dir 'conf.d' - - - 设置系统为并行操作所支持的工作者的最大数量。默认值为8。 - 在增加或者减小这个值时,也要考虑对以及进行调整。 - 此外,要注意将这个值设置得大于将不会产生效果,因为并行工作者进程都是从所建立的工作者进程池中取出来的。 - - + + 设置集簇能够为并行操作提供的工作进程的最大数量。默认值为 8。增大或减小此值时,也应考虑调整 。此外,将此值设得大于 没有效果,因为并行工作进程取自该设置建立的工作进程池。 + + - + parallel_leader_participation (boolean) @@ -2331,17 +2114,12 @@ include_dir 'conf.d' - - - 允许 leader 进程在GatherGather Merge节点下参与执行查询计划,而不是仅仅等待 worker 进程。 - 默认值是on。 - 将其设置为off可以降低 worker 因 leader 读取元组速度不够快而被阻塞的可能性, - 但在生成第一条元组之前,leader 进程将需要等待 worker 进程启动。 - leader 对性能的帮助或拖累程度取决于计划类型、worker 数量以及查询持续时间。 - - + + 允许领导者进程执行 GatherGather Merge 节点下的查询计划,而不是等待工作进程。默认值为 on。将此值设置为 off,可以降低工作进程因领导者读取元组不够快而被阻塞的可能性,但在产生第一批元组之前,领导者进程必须等待工作进程启动。领导者对性能的帮助或妨碍程度取决于计划类型、工作进程数量和查询持续时间。 + + - + @@ -2372,7 +2150,7 @@ include_dir 'conf.d' - minimal级别生成最少的WAL日志量。它不记录在创建或重写事务中对永久关系的行信息。 + minimal级别生成最少的WAL日志量。对于在当前事务中创建或重写的永久关系,不记录其行信息。 这可以使操作速度更快(参见)。触发此优化的操作包括: ALTER ... SET TABLESPACE @@ -2383,15 +2161,15 @@ include_dir 'conf.d' REINDEX TRUNCATE - 然而,最小的WAL不包含足够的信息用于时点恢复,因此必须使用replica或更高级别来启用持续归档 + 然而,minimal 级别的 WAL 不包含足够的信息用于时间点恢复,因此必须使用replica或更高级别来启用持续归档 ()和流式二进制复制。 实际上,如果max_wal_senders不为零,服务器甚至不会以此模式启动。 - 请注意,将wal_level更改为minimal会使先前的基本备份无法用于时点恢复和备库。 + 请注意,将wal_level更改为minimal会使先前的基础备份无法用于时间点恢复和备库。 logical级别上,记录与replica相同的信息,以及从WAL中提取逻辑变更集所需的信息。 - 使用logical级别会增加WAL的容量,特别是如果许多表被配置为REPLICA IDENTITY FULL, + 使用logical级别会增加 WAL 的数量,特别是如果许多表被配置为REPLICA IDENTITY FULL, 并且执行了许多UPDATEDELETE语句。 @@ -2419,16 +2197,15 @@ include_dir 'conf.d' - 能安全关闭fsync的环境的示例包括从一个备份文件中初始加载一个新数据库集簇、使用一个数据库集簇来在数据库被删掉并重建之后处理一批数据,或者一个被经常重建并却不用于失效备援的只读数据库克隆。单独的高质量硬件不足以成为关闭fsync的理由。 + 可以安全关闭fsync的情形包括:从备份文件初始装载一个新数据库集簇;用数据库集簇处理一批数据,处理后就丢弃并重建该数据库;或者使用经常重建且不用于故障切换的只读数据库克隆。仅有高质量硬件不足以成为关闭fsync的理由。 - 当把fsync从关闭改成打开时,为了可靠的恢复,需要强制在内核中的所有被修改的缓冲区进入持久化存储。这可以在多个时机来完成: - 在集簇被关闭时或在fsync因为运行initdb --sync-only而打开时、运行sync时、卸载文件系统时或者重启服务器时。 + 为确保将fsync从关闭改为打开后能够可靠恢复,必须将内核中所有已修改的缓冲区强制写入持久存储。可以在集簇已关闭或fsync已开启时,通过运行initdb --sync-only、运行sync、卸载文件系统或重启服务器来完成。 - 在很多情况下,为不重要的事务关闭可以提供很多关闭fsync的潜在性能收益,并不会有的同时, 关闭fsync可以提供很多潜在的性能优势,而不会有伴随着的数据损坏风险。 + 在很多情况下,为非关键事务关闭,可以获得关闭fsync所带来的大部分潜在性能收益,同时避免伴随的数据损坏风险。 @@ -2447,44 +2224,32 @@ include_dir 'conf.d' - 指定数据库服务器返回success指示给客户端之前,必须要完成多少WAL处理。 - 合法的值为remote_apply, on(默认值), remote_write,local, 和 off。 + 指定数据库服务器向客户端返回成功指示之前,必须完成多少 WAL 处理。有效值为remote_applyon(默认值)、remote_writelocaloff - 如果synchronous_standby_names为空,则唯一有意义的设置为onoff ; - remote_applyremote_writelocal都提供与on相同的本地同步级别。 - 所有非off模式的本地行为都是等待WAL的本地刷新到磁盘。 - 在 off模式,无需等待,因此在向客户端报告成功和以后保证事务安全防止服务器崩溃之间可能会出现延迟。 - 当设置为off时,在向客户端报告成功和真正保证事务不会被服务器崩溃威胁之间会有延迟(最大的延迟是的三倍)。 - 不同于,将这个参数设置为off不会产生数据库不一致性的风险:一个操作系统或数据库崩溃可能会造成一些最近据说已提交的事务丢失,但数据库状态是一致的,就像这些事务已经被干净地中止。 - 因此,当性能比完全确保事务的持久性更重要时,关闭synchronous_commit可以作为一个有效的代替手段。更多讨论见。 + 如果synchronous_standby_names为空,只有onoff两种设置有意义;remote_applyremote_writelocal提供的本地同步级别都与on相同。所有非off模式在本地都会等待 WAL 刷写到磁盘。在off模式下则无需等待,因此,向客户端报告成功后,可能还要经过一段时间,才能保证事务不会因服务器崩溃而丢失。(最大延迟为的三倍。)与不同,将此参数设为off不会带来数据库不一致的风险:操作系统或数据库崩溃可能会使一些最近报告已提交的事务丢失,但数据库状态会与这些事务已正常中止时完全相同。因此,当性能比完全确保事务持久性更重要时,关闭synchronous_commit可以是一种有用的替代方案。更多讨论见 - 如果为非空,synchronous_commit也控制是否事务提交将等待它们的 WAL 记录在备库上被处理。 + 如果非空,synchronous_commit还控制事务提交是否等待备库处理其 WAL 记录。 - 当设置为 remote_apply 时,提交将等待,直到来自当前同步备库的答复显示他们已收到事务的提交记录并应用了它,以便它变得对备库上的查询可见,并写入备库上的持久存储。 - 这将导致比以前的设置更大的提交延迟,因为它等待 WAL 重放(replay)。 - 当设置为on时,提交将等待,直到来自于当前同步的备库的回复显示它们已经收到了事务的提交记录并将其刷入了磁盘。 - 这保证事务将不会被丢失,除非主库和所有同步备库都遭受到了数据库存储损坏的问题。 - 当这个参数被设置为remote_write时,提交将等待,直到来自当前的同步备库的回复指示它们已经收到了该事务的提交记录并且已经把该记录写到它们的文件系统,这种设置保证数据得以保存,在PostgreSQL的备库实例崩溃时,但是不能保证备库遭受操作系统级别崩溃时数据能被保持,因为数据不一定必须要在备库上达到持久存储。 - 设置local会导致提交等待本地刷写到磁盘,而不是复制。在使用同步复制时这通常是不可取的,但是为了完整性提供了这个选项。 + 设为remote_apply时,提交会等待当前同步备库回复,确认已收到并应用该事务的提交记录,使其对备库上的查询可见,并且已将其写入备库的持久存储。由于需要等待 WAL 重放,这会比之前的设置产生大得多的提交延迟。设为on时,提交会等待当前同步备库回复,确认已收到事务的提交记录,并已将其刷写到持久存储。这能保证事务不会丢失,除非主库和所有同步备库的数据库存储都损坏。设为remote_write时,提交会等待当前同步备库回复,确认已收到事务的提交记录,并已将其写入各自的文件系统。此设置能保证备库上的PostgreSQL实例崩溃时数据不丢失,但不能保证备库发生操作系统级别崩溃时数据不丢失,因为数据未必已写入备库的持久存储。设为local时,提交会等待本地刷盘,但不等待复制。使用同步复制时通常不希望采用这种设置,提供它是为了使选项完整。 - 这个参数可以随时被修改;任何一个事务的行为由其提交时生效的设置决定。因此,可以同步提交一些事务,同时异步提交其他事务。例如,当默认是相反时,实现一个单一多语句事务的异步提交,在事务中发出SET LOCAL synchronous_commit TO OFF。 + 此参数可以随时更改;每个事务的行为由提交时生效的设置决定。因此,让一些事务同步提交、另一些事务异步提交是可行且有用的。例如,当默认设置要求同步提交时,可以在一个包含多条语句的事务中执行SET LOCAL synchronous_commit TO OFF,使该事务异步提交。 - 概括了 synchronous_commit 设置的能力. + 汇总了synchronous_commit各种设置具备的能力。 - synchronous_commit Modes + synchronous_commit 模式 @@ -2494,10 +2259,10 @@ include_dir 'conf.d' - synchronous_commit setting - local durable commit - PG 崩溃备库持久提交 - OS 崩溃备库持久提交 + synchronous_commit 设置 + 本地提交持久性 + PG 崩溃后备库提交持久性 + OS 崩溃后备库提交持久性 备库查询一致性 @@ -2561,7 +2326,7 @@ include_dir 'conf.d' - 用来向强制 WAL 更新到磁盘的方法。如果fsync是关闭的,那么这个设置就不相关,因为 WAL 文件更新将根本不会被强制。可能的值是: + 用于将 WAL 更新强制写入磁盘的方法。如果fsync关闭,此设置就没有作用,因为 WAL 文件更新根本不会被强制写入磁盘。可选值为: @@ -2585,7 +2350,7 @@ include_dir 'conf.d' - fsync_writethrough(在每次提交时调用fsync(),强制任何磁盘写高速缓存的直通写) + fsync_writethrough(在每次提交时调用fsync(),强制穿透任何磁盘写缓存) @@ -2597,10 +2362,9 @@ include_dir 'conf.d' - open_* 选项也可以使用O_DIRECT(如果可用)。 不是在所有平台上都能使用所有这些选择。 - 默认值是列表中第一个被平台支持的那个, 不过fdatasync是 Linux和FreeBSD中的默认值。 - 默认值不一定是最理想的;有可能需要修改这个设置或系统配置的其他方面来创建一个崩溃-安全的配置,或达到最佳性能。 + 默认值是列表中第一个被平台支持的那个, 不过fdatasync是 Linux 和 FreeBSD 中的默认值。 + 默认值不一定最合适;可能需要更改此设置或系统配置的其他方面,以确保崩溃时的数据安全或达到最佳性能。 这些方面在中讨论。 这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 @@ -2617,11 +2381,11 @@ include_dir 'conf.d' - 当这个参数为打开时,PostgreSQL服务器在一个检查点之后的页面的第一次修改期间将每个页面的全部内容写到 WAL 中。这么做是因为在操作系统崩溃期间正在处理的一次页写入可能只有部分完成,从而导致在一个磁盘页面中混合有新旧数据。在崩溃后的恢复期间,通常存储在 WAL 中的行级改变数据不足以完全恢复这样一个页面。存储整页镜像可以保证页面被正确存储,但代价是增加了必须被写入 WAL 的数据量(因为 WAL 重放总是从一个检查点开始,所以在检查点后每个页面的第一次改变时这样做就够了。因此,一种减小全页面写开销的方法是增加检查点间隔参数值)。 + 启用此参数时,PostgreSQL服务器会在检查点之后首次修改每个磁盘页面时,将该页面的全部内容写入 WAL。这样做是因为,操作系统崩溃时正在进行的页面写入可能只完成了一部分,导致磁盘页面混有新旧数据。通常存储在 WAL 中的行级变更数据不足以在崩溃恢复时完整还原这样的页面。保存整页镜像能保证正确恢复页面,但会增加必须写入 WAL 的数据量。(由于 WAL 重放总是从检查点开始,只需在检查点之后首次修改每个页面时这样做。因此,减少整页写入开销的一种方法是增大检查点间隔参数。) - 把这个参数关闭会加快正常操作,但是在系统失败后可能导致不可恢复的数据损坏,或者静默的数据损坏。其风险类似于关闭fsync, 但是风险较小。并且只有在可关闭fsync的情况下才应该关闭它。 + 关闭此参数可以加快正常操作,但系统故障后可能出现不可恢复的数据损坏或静默数据损坏。风险与关闭fsync类似,虽然较小,但也只有在该参数建议的相同情形下才应关闭此参数。 @@ -2644,7 +2408,7 @@ include_dir 'conf.d' - 当这个参数为on时,PostgreSQL服务器一个检查点之后页面被第一次修改期间把该磁盘页面的整个内容都写入 WAL,即使对所谓的提示位做非关键修改也会这样做。 + 当这个参数为on时,PostgreSQL服务器在检查点之后首次修改页面时把该磁盘页面的整个内容都写入 WAL,即使对所谓的提示位做非关键修改也会这样做。 @@ -2669,9 +2433,8 @@ include_dir 'conf.d' 此参数启用使用指定的压缩方法对WAL进行压缩。 - 启用后,PostgreSQL服务器在 - 打开时或在基本备份期间, - 压缩写入WAL的整页镜像。 + 启用后,PostgreSQL服务器会压缩写入 WAL 的整页镜像,例如 + 在启用时、基础备份期间等。 在WAL重放期间,将对压缩的页镜像进行解压缩。 支持的方法有pglzlz4(如果PostgreSQL @@ -2684,8 +2447,7 @@ include_dir 'conf.d' - 启用压缩可以减少WAL卷的大小,而不会增加不可恢复的数据损坏的风险, - 但会增加在WAL记录期间进行压缩时的额外CPU消耗,以及在WAL重放期间进行解压缩时的成本。 + 启用压缩可以减少 WAL 数据量,而且不会增加不可恢复的数据损坏风险;代价是在记录 WAL 时压缩、重放 WAL 时解压会额外消耗一些 CPU。 @@ -2700,10 +2462,10 @@ include_dir 'conf.d' - 如果设置为on(默认值),此选项会导致新的 WAL 文件被零填充。 - 在某些文件系统上,这可确保在我们需要写入 WAL 记录之前分配空间。 - 但是,Copy-On-Write(COW)文件系统可能不会从此技术中受益,因此可以选择跳过不必要的工作。 - 如果设置为off,则在创建文件时仅写入最终字节,以便其具有预期大小。 + 如果设置为on(默认值),此选项会导致新的 WAL 文件被零填充。 + 在某些文件系统上,这可确保在我们需要写入 WAL 记录之前分配空间。 + 但是,写时复制(COW)文件系统可能不会从此技术中受益,因此可以选择跳过不必要的工作。 + 如果设置为off,则在创建文件时只写入最后一个字节,以便其具有预期大小。 @@ -2718,8 +2480,8 @@ include_dir 'conf.d' - 如果设置为 on (默认值),此选项通过重命名来回收 WAL 文件,从而避免创建新文件。 - 在 COW 文件系统上,创建新文件系统可能更快,因此提供了禁用此行为的选项。 + 如果设置为 on (默认值),此选项通过重命名来回收 WAL 文件,从而避免创建新文件。 + 在 COW 文件系统上,创建新文件可能更快,因此提供了禁用此行为的选项。 @@ -2734,12 +2496,12 @@ include_dir 'conf.d' - 用于还未写入磁盘的 WAL 数据的共享内存量。默认值 -1 选择等于的 1/32 的尺寸(大约3%),但是不小于64kB也不大于 WAL 段的尺寸(通常为16MB)。如果自动的选择太大或太小可以手工设置该值,但是任何小于32kB的正值都将被当作32kB。 + 用于还未写入磁盘的 WAL 数据的共享内存量。默认值 -1 选择等于的 1/32 的尺寸(大约3%),但是不小于64kB也不大于 WAL 段的尺寸(通常为16MB)。如果自动的选择太大或太小可以手工设置该值,但是任何小于32kB的正值都将被当作32kB。 如果指定值时没有单位,则以WAL块作为单位,即为 XLOG_BLCKSZ 字节,通常为8kB。这个参数只能在服务器启动时设置。 - 在每次事务提交时,WAL 缓冲区的内容被写出到磁盘,因此极大的值不可能提供显著的收益。不过,把这个值设置为几个兆字节可以在一个繁忙的服务器(其中很多客户端会在同一时间提交)上提高写性能。由默认设置 -1 选择的自动调节将在大部分情况下得到合理的结果。 + 在每次事务提交时,WAL 缓冲区的内容被写出到磁盘,因此极大的值不太可能带来显著收益。不过,把这个值设置为至少几个兆字节可以在一个繁忙的服务器(其中很多客户端会在同一时间提交)上提高写性能。由默认设置 -1 选择的自动调节将在大部分情况下得到合理的结果。 @@ -2757,9 +2519,9 @@ include_dir 'conf.d' 指定 WAL 写入器刷写 WAL 的频繁程度,以时间为单位。 在刷写WAL之后,写入器将根据wal_writer_delay所给出的时间长度进行睡眠,除非被一个异步提交的事务提前唤醒。 - 如果最近的刷写发生在 wal_writer_delay 之前,并且小于 wal_writer_flush_after WAL的值产生之后,那么WAL只会被写入操作系统,而不会被刷写到磁盘。 + 如果距上次刷盘的时间小于wal_writer_delay,并且自那以后产生的 WAL 数据量小于wal_writer_flush_after,则只将 WAL 写入操作系统,而不刷写到磁盘。 如果指定值时没有单位,则以毫秒作为单位。 - 默认值是 200 毫秒(200ms)。注意在很多系统上,有效的睡眠延迟粒度是 10 毫秒,把wal_writer_delay设置为一个不是 10 的倍数的值,其效果和把它设置为大于该值的下一个 10 的倍数产生的效果相同。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 + 默认值是 200 毫秒(200ms)。注意在某些系统上,有效的睡眠延迟粒度是 10 毫秒,把wal_writer_delay设置为一个不是 10 的倍数的值,其效果可能与将其设置为下一个更大的 10 的倍数相同。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 @@ -2774,8 +2536,8 @@ include_dir 'conf.d' - 指定 WAL 写入器刷写 WAL 的频繁程度,以卷为单位。 - 如果最近的刷写发生在 wal_writer_delay 之前,并且小于 wal_writer_flush_after WAL的值产生之后,那么WAL只会被写入操作系统,而不会被刷写到磁盘。 + 指定 WAL 写入器刷写 WAL 的频繁程度,按数据量衡量。 + 如果距上次刷盘的时间小于wal_writer_delay,并且自那以后产生的 WAL 数据量小于wal_writer_flush_after,则只将 WAL 写入操作系统,而不刷写到磁盘。 如果wal_writer_flush_after被设置为0,则WAL数据总是会被立即刷写。 如果指定值时没有单位,则以WAL块作为单位,即为XLOG_BLCKSZ字节,通常为8kB。 默认是1MB。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 @@ -2793,10 +2555,7 @@ include_dir 'conf.d' - 当wal_levelminimal,并且在创建或重写永久关系之后提交事务时,此设置将确定如何保留新数据。 - 如果数据小于此设置,将其写入 WAL 日志;否则,使用受影响文件的 fsync。 - 根据存储的属性,如果此类提交减慢了并发事务,提高或降低此值可能会有所帮助。 - 如果指定此值时没有单位,则视为千字节。默认为两兆字节(2MB)。 + 当wal_levelminimal,且事务在创建或重写永久关系后提交时,此设置决定如何持久保存新数据。如果数据量小于此设置,就将其写入 WAL;否则,对受影响的文件执行 fsync。如果这类提交拖慢了并发事务,根据存储的特性,增大或减小此值可能有所帮助。未指定单位时以千字节为单位。默认值为两兆字节(2MB)。 @@ -2811,20 +2570,20 @@ include_dir 'conf.d' - 设置commit_delay会在执行WAL刷新之前添加时间延迟。 + 设置commit_delay会在发起 WAL 刷盘之前添加时间延迟。 如果系统负载足够高,使得在给定时间间隔内有更多事务准备提交, - 这可以通过允许更多事务通过单个WAL刷新来提高组提交吞吐量。 - 然而,这也会增加延迟,最多为每个WAL刷新的commit_delay。 - 因为如果没有其他事务准备提交,延迟就是浪费的,所以只有在至少有 - commit_siblings其他事务活动时才会执行延迟, - 当要启动刷新时,如果fsync被禁用,则不会执行延迟。 + 这可以通过允许更多事务通过一次 WAL 刷盘来提高组提交吞吐量。 + 不过,每次 WAL 刷盘的延迟也会因此增加,最多增加commit_delay。 + 如果没有其他事务准备提交,等待就没有意义,因此仅当即将发起刷盘时至少还有 + commit_siblings个其他活动事务,才会等待。 + 此外,如果禁用了fsync,也不会等待。 如果未指定单位,则将其视为微秒。 默认commit_delay为零(无延迟)。 只有超级用户和具有适当SET权限的用户才能更改此设置。 - 在PostgreSQL的 9.3 发布之前,commit_delay的行为不同并且效果更差:它只影响提交,而不是所有 WAL 刷写,并且即使在 WAL 刷写马上就要完成时也会等待一整个配置的延迟。从PostgreSQL 9.3 中开始,第一个准备好刷写的进程会等待配置的间隔,而后续的进程只等到领先者完成刷写操作。 + 在PostgreSQL的 9.3 发布之前,commit_delay的行为不同并且效果更差:它只影响提交,而不是所有 WAL 刷写,并且即使 WAL 刷盘更早完成,也会等待整个配置的延迟时间。从PostgreSQL 9.3 开始,第一个准备好刷写的进程会等待配置的间隔,而后续的进程只等到领先者完成刷写操作。 @@ -2839,7 +2598,7 @@ include_dir 'conf.d' - 在执行commit_delay延迟时,要求的并发活动事务的最小数目。大一些的值会导致在延迟间隔期间更可能有至少另外一个事务准备好提交。默认值是五个事务。 + 执行commit_delay延迟前要求的并发活动事务的最小数目。大一些的值会导致在延迟间隔期间更可能有至少另外一个事务准备好提交。默认值是五个事务。 @@ -2862,7 +2621,7 @@ include_dir 'conf.d' 自动 WAL 检查点之间的最长时间。如果指定值时没有单位,则以秒为单位。 - 合理的范围在 30 秒到 1 天之间。默认是 5 分钟(5min)。增加这个参数的值会增加崩溃恢复所需的时间。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 + 合理的范围在 30 秒到 1 天之间。默认是 5 分钟(5min)。增加这个参数的值可能会增加崩溃恢复所需的时间。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 @@ -2877,11 +2636,11 @@ include_dir 'conf.d' - 指定检查点完成的目标,作为检查点之间总时间的一部分。 - 默认是 0.9,这将把检查点分布在几乎所有可用的时间间隔上,提供公平一致的I/O负载,同时也为检查点完成开销留下了一些时间。 - 减少此参数是不被推荐的,因为这会导致检查点完成得更快。 - 这个造成处于在检查点和下一个计划检查点之间较少IO之后的检查点会有更高的IO比例。 - 这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 + 指定检查点完成所用时间的目标值,以检查点之间总时间的比例表示。 + 默认值为 0.9,这会把检查点工作分散到几乎整个可用间隔内,使 I/O 负载较为平稳, + 同时为检查点完成时的额外工作留出一些时间。不建议减小此参数,因为这样会让检查点更快完成, + 导致检查点期间的 I/O 速率更高,而在检查点完成后到下一个计划检查点开始前的一段时间内 I/O 较少。 + 此参数只能在postgresql.conf文件中或服务器命令行上设置。 @@ -2898,7 +2657,7 @@ include_dir 'conf.d' 当执行检查点时写入的数据量超过此数量时,就尝试强制 OS 把这些写发送到底层存储。 这样做将会限制内核页面高速缓存中的脏数据数量,降低在检查点末尾发出fsync或者 OS 在后台大批量写回数据时被卡住的可能性。 - 那常常会导致大幅度压缩的事务延迟,但是也有一些情况(特别是负载超过但小于 OS 页面高速缓存)的性能会降低。 + 这通常能显著降低事务延迟,但是也有一些情况(特别是负载超过但小于 OS 页面高速缓存)的性能会降低。 这种设置可能会在某些平台上没有效果。 如果指定值时没有单位,则以块为单位,即为BLCKSZ 字节,通常为8kB。 合法的范围在0(禁用强制写回)和2MB之间。Linux 上的默认值是256kB,其他平台上是0(如果BLCKSZ不是8kB,则默认值和最大值会按比例缩放到它)。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 @@ -2978,10 +2737,9 @@ include_dir 'conf.d' 当启用archive_mode时,完成的WAL段会通过设置 或 - 发送到归档存储。除了off, - 要禁用,有两种模式:on和 + 发送到归档存储。除了用于禁用归档的off外,还有两种模式:onalways。在正常操作期间,这两种模式之间没有区别,但当设置为always时, - WAL归档程序在归档恢复或待机模式下也会被启用。在always模式下,从归档中恢复的所有文件 + WAL归档程序在归档恢复或备库模式下也会被启用。在always模式下,从归档中恢复的所有文件 或通过流复制传输的文件将被再次归档。详细信息请参见 @@ -3016,6 +2774,7 @@ include_dir 'conf.d' 这个参数只能在postgresql.conf文件或服务器命令行中设置。 除非在服务器启动时启用了archive_mode并且archive_library设置为空字符串,否则将被忽略。 + 如果archive_commandarchive_library都被设置,则会报错。 如果archive_command是空字符串(默认值),而archive_mode已启用(并且archive_library设置为空字符串), WAL归档将暂时被禁用,但服务器将继续积累WAL段文件,期望很快会提供命令。 将archive_command设置为一个什么都不做但返回true的命令,例如/bin/true(Windows上为REM), @@ -3035,6 +2794,7 @@ include_dir 'conf.d' 用于归档已完成的WAL文件段的库。如果设置为空字符串(默认值),则通过shell进行归档,并使用。 + 如果archive_commandarchive_library都被设置,则会报错。 否则,指定的共享库用于归档。当此参数更改时,postmaster会重新启动WAL归档进程。有关更多信息,请参见 @@ -3054,7 +2814,7 @@ include_dir 'conf.d' - 仅在完成的WAL段中调用。 + 只针对已完成的 WAL 段调用。 因此,如果您的服务器生成的WAL流量较少(或者在这样做时有间歇期),在事务完成和安全记录到归档存储之间可能会有很长的延迟。 为了限制未归档数据的年龄,您可以将archive_timeout设置为强制服务器定期切换到新的WAL段文件。 当此参数大于零时,只要自上次段文件切换以来经过了这段时间,并且存在任何数据库活动,包括单个检查点(如果没有数据库活动,则跳过检查点),服务器将切换到新的段文件。 @@ -3135,8 +2895,8 @@ include_dir 'conf.d' 归档恢复 - configuration - of recovery + 配置 + 恢复 一个备库 @@ -3145,7 +2905,7 @@ include_dir 'conf.d' - Recovery 涵盖使用服务器作为备库或用于执行目标恢复。 + 恢复 涵盖使用服务器作为备库或用于执行目标恢复。 通常情况,备库模式用于提供高可用性和/或读可扩展性,而目标恢复用于从数据丢失中恢复。 @@ -3214,7 +2974,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows 这个信息可以被用来把归档截断为支持从当前恢复重启所需的最小值。 对于单一备库配置,模块常常被用在archive_cleanup_command中,例如: archive_cleanup_command = 'pg_archivecleanup /mnt/server/archivedir %r' - 但是注意,如果多个备库正在从同一个归档目录中恢复,你将需要保证只有当任意服务器都不再需要 WAL 文件时才会删除它们。 + 但是注意,如果多个备库正在从同一个归档目录中恢复,你将需要保证只有当所有服务器都不再需要这些 WAL 文件时才会删除它们。 archive_cleanup_command通常被用于一种温备配置(见)中。 要在该命令中嵌入一个真正的%字符,需要写成%% @@ -3267,7 +3027,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows 默认情况下,恢复将会一直恢复到 WAL 日志的末尾。下面的参数可以被用来指定一个更早的停止点。 在recovery_targetrecovery_target_lsnrecovery_target_namerecovery_target_timerecovery_target_xid中, - 最多只能使用一个,如果在配置文件中使用了多个,将会产生一个错误。这个参数只能在服务器启动时设置。 + 最多只能使用一个,如果在配置文件中使用了多个,将会产生一个错误。这些参数只能在服务器启动时设置。 @@ -3300,7 +3060,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows - 这个参数指定(pg_create_restore_point()所创建)的已命名的恢复点,恢复将进入该恢复点。 + 这个参数指定(pg_create_restore_point()所创建)的已命名的恢复点,恢复将进行到该恢复点。 @@ -3315,7 +3075,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows - 此参数指定恢复将执行的时间戳。精确的停止点还受到得影响。 + 此参数指定恢复要进行到的时间戳。精确的停止点还受到的影响。 @@ -3335,7 +3095,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows - 这个参数指定恢复将进入的事务 ID。记住虽然事务 ID 是在事务开始时顺序分配的,但是事务可能以不同的数字顺序完成。 + 这个参数指定恢复要进行到的事务 ID。记住虽然事务 ID 是在事务开始时顺序分配的,但是事务可能以不同的数字顺序完成。 那些在指定事务之前(也可以包括该事务)提交的事务将被恢复。精确的停止点也受到的影响。 @@ -3351,7 +3111,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows - 此参数指定恢复将继续进行的预写日志位置的LSN。精确的停靠点也受 的影响。 + 此参数指定恢复要进行到的预写日志位置的 LSN。精确的停止点也受 的影响。 使用系统数据类型pg_lsn解析此参数。 @@ -3376,7 +3136,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows 指定我们是否仅在指定的恢复目标之后停止(on),或者仅在恢复目标之前停止(off)。 适用于或者被指定的情况。 - 这个设置分别控制事务是否有准确的目标WAL位置(LSN)、提交时间或事务ID将被包括在该恢复中。默认值为on。 + 这个设置控制恢复是否包含 WAL 位置(LSN)、提交时间或事务 ID 分别恰好等于目标值的事务。默认值为on @@ -3393,7 +3153,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows 指定恢复到一个特定的时间线中。该值可以是数字时间线 ID 或特殊值。 - 值current沿着与执行基本备份时相同的时间线恢复。 + 值current沿着与执行基础备份时相同的时间线恢复。 值latest将恢复到归档中能找到的最新时间线,这在备库中很有用。 latest是默认值。 @@ -3429,14 +3189,14 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows - 使用pause设置的目的是:如果这个恢复目标就是恢复最想要的位置,就允许对数据库执行查询。 + 使用pause设置的目的是允许对数据库执行查询,以检查这个恢复目标是否为最合适的恢复位置。 暂停的状态可以使用pg_wal_replay_resume()(见)继续,这会让恢复终结。 如果这个恢复目标不是想要的停止点,那么关闭服务器,将恢复目标设置改为一个稍后的目标并且重启以继续恢复。 要让实例在想要的重放点那里准备好,shutdown设置可以派上用场。 - 该实例将仍能重放更多 WAL 记录(并且事实上将不得不重放从下一次它被启动后最后一个检查点以来的 WAL 记录)。 + 该实例将仍能重放更多 WAL 记录(并且事实上,下次启动时必须重新回放自上一个检查点以来的 WAL 记录)。 @@ -3447,7 +3207,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows 如果没有设置恢复目标,这个设置没有效果。 如果没有启用pause设置的动作将和shutdown一样。 - 如果在升级期间达到恢复目标,pause 的设置将与 promote的行为相同。 + 如果在备库提升期间达到恢复目标,pause 的设置将与 promote的行为相同。 @@ -3462,9 +3222,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows WAL 汇总 - - 这些设置控制 WAL 汇总,这是执行所需的一项功能。 - + 这些设置控制 WAL 汇总。执行增量备份前必须启用这项功能。 @@ -3480,12 +3238,10 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows 默认值为off - 如果wal_level被设置为minimal,则无法以 - summarize_wal=on启动服务器。如果在服务器启动后将 - summarize_wal设置为on而 - wal_levelminimal,则汇总器会运行,但会拒绝为使用 - wal_level=minimal生成的任何 WAL 创建汇总文件。 - + 如果wal_level设为minimal,则不能以summarize_wal=on启动服务器。 + 如果在服务器启动后配置summarize_wal=on,而此时wal_level=minimal, + 汇总器会运行,但会拒绝为使用wal_level=minimal生成的任何 WAL 创建汇总文件。 + @@ -3517,7 +3273,15 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows 复制 - 这些设置控制内置流复制特性(见)的行为。服务器将可以是主库或备库。主库能发送数据,而备库总是被复制数据的接收者。当使用级联复制(见)时,备库也可以是发送者,同时也是接收者。这些参数主要用于发送服务器和备库,尽管某些只在主库上有意义。如果有必要,设置可以在集簇中变化而不出问题。 + 这些设置控制内置流复制特性(见)和内置逻辑复制特性(见)的行为。 + + + + 对于流复制,服务器将可以是主库或备库。主库能发送数据,而备库总是被复制数据的接收者。当使用级联复制(见)时,备库也可以是发送者,同时也是接收者。这些参数主要用于发送服务器和备库,尽管某些只在主库上有意义。如果有必要,设置可以在集簇中变化而不出问题。 + + + + 对于逻辑复制发布者(执行CREATE PUBLICATION的服务器)向订阅者(执行CREATE SUBSCRIPTION的服务器)复制数据。服务器也可以同时是发布者和订阅者。注意,下文各节将发布者称为“发送者”。有关逻辑复制配置设置的更多详细信息,请参见 @@ -3539,16 +3303,17 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows - 指定来自备库或流式基础备份客户端的并发连接的最大数量(即同时运行 WAL 发送进程的最大数)。 - 默认值是10。值0意味着禁用复制。 - 突然的流式传输客户端断开连接可能留下一个孤立连接槽(知道达到超时),因此这个参数应该设置得略高于最大客户端连接数,这样断开连接的客户端可以立刻重新连接。 - 这个参数只能在服务器启动时被设置。此外,wal_level必须设置为replica或更高级别以允许来自备库的连接。 + 指定来自备库或流式基础备份客户端的最大并发连接数(即同时运行的 WAL 发送进程的最大数量)。 + 默认值为 10。值 0 表示禁用复制。 + 流式客户端突然断开连接后,可能会留下一个孤立连接槽,直到超时才释放。 + 因此,此参数应设置得略高于预期的最大客户端数,使断开连接的客户端能够立即重新连接。 + 此参数只能在服务器启动时设置。此外,wal_level 必须设置为 + replica 或更高级别,才允许来自备库的连接。 - 在运行一个备库时,你必须把这个参数设置为等于或者高于主库上的值。 - 否则,备库上可能不会允许查询。 - + 运行备库时,必须将此参数设置为大于或等于主库上的值。否则,备库上将不允许查询。 + @@ -3557,6 +3322,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows max_replication_slots (integer) max_replication_slots配置参数 + 在发送服务器上 @@ -3568,6 +3334,9 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows 更高。 + + 请注意,此参数也适用于订阅者端,但含义不同。 + @@ -3627,16 +3396,19 @@ HINT: If it is safe for all REPLICATION users to use this library as an output - 指定在备库需要为流复制获取日志段文件的情况下,pg_wal目录下所能保留的过去日志文件段的最小尺寸。 - 如果一个连接到发送服务器的备库落后了超过wal_keep_size兆字节,发送服务器可以移除一个备库仍然需要的 WAL 段,在这种情况下复制连接将被中断。 - 最终结果是下行连接也将最终失败(不过,如果在使用 WAL 归档,备库可以通过从归档获取段来恢复)。 + 指定在 pg_wal 目录中保留的旧 WAL 文件的最小总量, + 以便备库需要时获取这些文件进行流复制。如果连接到发送服务器的备库落后超过 + wal_keep_size 兆字节,发送服务器可能会移除备库仍需要的 WAL 段, + 从而导致复制连接终止。下游连接最终也会因此失败。 + (不过,如果使用了 WAL 归档,备库可以通过从归档获取该段来恢复。) - 只设置pg_wal中保留的文件段的最小尺寸;系统可能需要为 WAL 归档或从一个检查点恢复保留更多段。 - 如果wal_keep_size为零(默认值), 更多的空间来 存放WAL归档或从一个检查点恢复。 - 如果wal_keep_segments是零(缺省), 系统不会为备库目的保留任何多余的段,因此备库可用的旧 WAL 段的数量是一个上个检查点位置和 WAL 归档状态的函数。 - 如果此值被指定时没有单位,则视为兆字节。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 + 此设置只规定 pg_wal 中保留的段的最小总量;系统可能需要为 WAL 归档 + 或从检查点恢复而保留更多段。如果 wal_keep_size 为零(默认值), + 系统不会为备库额外保留任何段,因此备库可用的旧 WAL 段数取决于前一个检查点的位置 + 和 WAL 归档的状态。如果指定值时没有单位,则按兆字节计算。 + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 @@ -3650,14 +3422,18 @@ HINT: If it is safe for all REPLICATION users to use this library as an output - - 指定在检查点时,replication slots(复制槽)允许在pg_wal目录中保留的WAL文件的最大大小。 - 如果max_slot_wal_keep_size为-1(默认值),复制槽可以保留无限量的WAL文件。否则,如果复制槽的restart_lsn落后于当前LSN超过给定大小, - 使用该槽的备机可能由于所需的WAL文件被删除而无法继续复制。您可以在pg_replication_slots中查看复制槽的WAL可用性。 - 如果未指定单位,则此值将被视为兆字节。此参数只能在postgresql.conf文件或服务器命令行中设置。 - - - + + 指定检查点时复制槽允许在 + pg_wal 目录中保留的 WAL 文件最大总量。 + 如果 max_slot_wal_keep_size 为 -1(默认值),复制槽可以保留无限量的 WAL 文件。 + 否则,如果复制槽的 restart_lsn 落后当前 LSN 超过给定大小,使用该槽的备库可能会 + 因为所需 WAL 文件被移除而无法继续复制。可以在 + pg_replication_slots 中查看复制槽的 WAL 可用情况。 + 如果指定值时没有单位,则按兆字节计算。此参数只能在 + postgresql.conf 文件中或服务器命令行上设置。 + + + wal_sender_timeout (integer) @@ -3668,14 +3444,14 @@ HINT: If it is safe for all REPLICATION users to use this library as an output - 中断那些停止活动超过这个时间量的复制连接。这对发送服务器检测一个费用服务器崩溃或网络中断有用。 - 如果指定值时没有单位,则以毫秒为单位。默认值是 60 秒。值0将禁用超时机制。 + 终止非活动时间超过此值的复制连接。这有助于发送服务器检测备库崩溃或网络中断。 + 如果指定值时没有单位,则按毫秒计算。默认值为 60 秒。值零禁用超时机制。 - 对于跨越多个地理位置分布的集簇,每个位置使用不同的值可以为集簇管理带来更大的灵活性。 - 对于具有低延迟网络连接的备库,较小的值有助于更快的故障检测; - 对于位于远端位置的具有高延迟网络连接的备库,较大的值有助于更好地判断备库的健康状况。 + 对于跨多个地理位置分布的集簇,在各位置使用不同的值可以提高集簇管理的灵活性。 + 对于网络延迟较低的备库,较小的值有助于更快地检测故障; + 对于地处远端、网络延迟较高的备库,较大的值有助于更准确地判断其健康状况。 @@ -3703,7 +3479,10 @@ HINT: If it is safe for all REPLICATION users to use this library as an output 主库 - 这些参数可以在发送复制数据给一个或多个备库的主库上设置。注意除了这些参数之外,在主库上必须设置合适的,并且也启用可选的 WAL 归档(见)。这些参数值与备库无关,尽管你可能希望为了准备好一个备库转变成主库来设置这些参数。 + 这些参数可以在向一个或多个备库发送复制数据的主库上设置。 + 除这些参数外,还必须在主库上适当设置 , + 也可以选择启用 WAL 归档(见 )。 + 这些参数在备库上的取值不影响备库运行,不过也可以预先设置,以备将来提升为主库。 @@ -3719,15 +3498,17 @@ HINT: If it is safe for all REPLICATION users to use this library as an output 所述,这个参数指定一个支持同步复制的备库的列表。 - 可能会有一个或者多个活动的同步备库,在这些备库确认收到它们的数据之后,等待提交的事务将被允许继续下去。 - 同步备库是那些名字出现在这个列表前面,并且当前已连接并且正在实时流式传输数据(如pg_stat_replication视图中streaming的状态所示)的服务器。 + 将有一个或多个活动的同步备库,在这些备库确认收到它们的数据之后,等待提交的事务将被允许继续下去。 + 同步备库是那些名字出现在这个列表中,并且当前已连接并且正在实时流式传输数据(如pg_stat_replication视图中streaming的状态所示)的服务器。 指定多于一台同步备库可以得到非常高的可用性并且能防止数据丢失。 用于这一目的的备库的名称是其application_name设置,它在备库的连接信息中设置。 - 在物理复制备库的情况下,这应该被设置在primary_conninfo设置中,如果设置了,默认是的设置,否则为 walreceiver。 - 对于逻辑复制,可以在订阅的连接信息中设置。对于其他复制流消费者,请参考其文档。 + 对于物理复制备库,应在 primary_conninfo 设置中指定。 + 若已设置 ,则默认使用其值;否则默认值为 walreceiver。 + 对于逻辑复制,可以在订阅的连接信息中设置,默认值为订阅名称。 + 对于其他复制流消费者,请参考其文档。 @@ -3741,11 +3522,11 @@ ANY num_sync ( num_sync指定一种基于优先的同步复制,并且会让事务提交等待,直到它们的WAL记录被复制到基于优先级选择的num_sync台同步备库上为止。例如,设置FIRST 3 (s1, s2, s3, s4)将导致每次提交都等待来自三台较高优先级的备库的答复,这三台备库将从备库s1s2s3以及s4中选出。在该列表中出现较早的备库将被给予较高的优先级,并且将被考虑为同步备库。列表中出现的其他备库表示潜在的同步备库。如果当前的任何同步备库因为某种原因断开连接,它将立刻被下一个最高优先级的备库替代。关键词FIRST是可选的。 + 关键词FIRST加上num_sync指定一种基于优先级的同步复制,并且会让事务提交等待,直到它们的WAL记录被复制到基于优先级选择的num_sync台同步备库上为止。例如,设置FIRST 3 (s1, s2, s3, s4)将导致每次提交都等待来自三台较高优先级的备库的答复,这三台备库将从备库s1s2s3以及s4中选出。在该列表中出现较早的备库将被给予较高的优先级,并且将被考虑为同步备库。列表中出现的其他备库表示潜在的同步备库。如果当前的任何同步备库因为某种原因断开连接,它将立刻被下一个最高优先级的备库替代。关键词FIRST是可选的。 - 关键词ANY加上num_sync指定一种基于规定数量的同步复制,并且会让事务提交等待,直到它们的WAL记录被复制到所列出备库中的至少num_sync台上为止。例如,设置ANY 3 (s1, s2, s3, s4)将导致每次提交会在收到s1s2s3以及s4中任意三台备库的回答后立刻继续下去。 + 关键词ANY加上num_sync指定一种基于法定人数的同步复制,并且会让事务提交等待,直到它们的WAL记录被复制到所列出备库中的至少num_sync台上为止。例如,设置ANY 3 (s1, s2, s3, s4)将导致每次提交会在收到s1s2s3以及s4中任意三台备库的回答后立刻继续下去。 @@ -3771,7 +3552,7 @@ ANY num_sync ( 参数设置为localoff。 + 如果这里没有指定同步备库名称,那么不启用同步复制并且事务提交将不会等待复制。这是默认的配置。即便当同步复制被启用时,个体事务也可以被配置为不等待复制,做法是将参数设置为localoff @@ -3788,16 +3569,16 @@ ANY num_sync ( pg_replication_slot_advance、 + pg_logical_slot_get_changes和 + pg_logical_slot_peek_changes + 将阻塞,直到synchronized_standby_slots中列出的所有物理槽都确认接收到了 WAL。 synchronized_standby_slots中物理复制槽对应的备库必须配置 @@ -3869,7 +3650,7 @@ ANY num_sync ( )。 这个参数只能在 postgresql.conf文件或服务器命令行上设置。 - 如果在 WAL 接收进程运行时更改此参数,则该进程将发出关机信号,并预期使用新设置重新启动(除非primary_conninfo为空字符串)。 + 如果在 WAL 接收进程运行时更改此参数,则会向该进程发送关闭信号,并预期它使用新设置重新启动。 如果没有设置primary_conninfo或服务器没有处于备库模式,则此设置无效。 @@ -3908,9 +3689,7 @@ ANY num_sync ( num_sync ( num_sync ( )。 - 默认为"关闭"。 此参数只能在postgresql.conf文件或服务器命令行中设置。 - 如果在 WAL 接收进程运行时更改此参数,则该进程将发出关机的信号,并预期使用新设置重新启动。 - + 指定在未使用配置要使用的永久复制槽时,WAL 接收进程是否应在远程实例上创建临时复制槽。默认值为 off。此参数只能在postgresql.conf文件中或服务器命令行上设置。如果在 WAL 接收进程运行时更改此参数,则会向该进程发送信号使其关闭,并预期它使用新设置重新启动。 @@ -3966,9 +3739,9 @@ ANY num_sync ( pg_stat_replication视图看到。 - 备库将报告它已经写入的上一个预写式日志位置、它已经刷到磁盘的上一个位置以及它已经应用的最后一个位置。 + 备库将报告最后写入的预写日志位置、最后刷盘的位置以及最后应用的位置。 这个参数的值是报告之间的最大时间量。 - 每次写入或刷出位置改变时会发送状态更新,或者按这个参数的指定的频度发送,如果设置为非零值。 + 每次写入或刷盘位置改变时会发送状态更新,或者按这个参数的指定的频度发送,如果设置为非零值。 在其他情况下发送更新时忽略此参数;例如,当现有的WAL处理完成或当synchronous_commit设置为remote_apply时。 因此,应用位置可能比真实位置略微滞后。 如果指定值时没有单位,则以秒为单位。 @@ -3988,7 +3761,7 @@ ANY num_sync ( num_sync ( num_sync ( + + recovery_min_apply_delay (integer) recovery_min_apply_delay 配置参数 - - 默认情况下,备库会尽快恢复来自于发送服务器的 WAL 记录。有一份数据的延时拷贝是有用的,它能提供机会纠正数据丢失错误。 - 这个参数允许你将恢复延迟一段指定的时间量。 - 例如,如果你设置这个参数为5min,对于一个事务提交,只有当备库上的系统时钟超过主库报告的提交时间至少 5分钟时,备库才会重放该事务。 - 如果指定值时没有单位,则以毫秒为单位。默认为0,不增加延迟。 + 默认情况下,备库会尽快恢复来自发送服务器的 WAL 记录。保留一份延迟的数据副本可能很有用,因为它提供了纠正数据丢失错误的机会。此参数允许将恢复延迟指定的时间。例如,将此参数设置为 5min 时,只有当备库系统时间比主库报告的提交时间至少晚五分钟,备库才会重放各事务的提交。如果没有指定单位,则以毫秒计。默认值为零,不增加延迟。 - - 有可能服务器之间的复制延迟会超过这个参数的值,在这种情况下则不会增加延迟。 - 注意延迟是根据主库上写 WAL 的时间戳以及备库上的当前时间来计算。 - 由于网络延迟或者级联复制配置导致的传输延迟可能会显著地减少实际等待时间。 - 如果主库和备库上的系统时钟不同步,这会导致恢复比预期的更早应用记录。 - 但这不是一个主要问题,因为这个参数有用的设置比服务器之间的典型事件偏差要大得多。 + 服务器之间的复制延迟可能超过此参数的值,这种情况下不会增加延迟。注意,延迟根据主库写入的 WAL 时间戳与备库当前时间之差计算。网络延迟或级联复制配置导致的传输延迟,可能显著缩短实际等待时间。如果主库和备库的系统时钟不同步,恢复时可能比预期更早应用记录;但这通常不是主要问题,因为此参数的实用取值远大于服务器间常见的时间偏差。 - - 只有在事务提交的 WAL 记录上才会发生延迟。其他记录还是会被尽可能快地重放,这不会成为问题,因为 MVCC 可见性规则确保了在对应的提交记录被应用之前它们的效果不会被看到。 + 延迟仅发生在事务提交的 WAL 记录上。其他记录会尽快重放;这不会造成问题,因为 MVCC 可见性规则确保在对应提交记录被应用之前,它们的效果不会可见。 - - 一旦恢复中的数据库已经达到一致状态,延迟就会产生,直到备库被提升或者触发。在那之后,备库将会结束恢复并且不再等待。 + 恢复中的数据库达到一致状态后开始延迟,直到备库被提升或触发。此后,备库会结束恢复,不再等待。 - - WAL记录必须保留在备库上,直到准备好应用。因此,较长的延迟将导致WAL文件的积累增加,增加备库的pg_wal目录的磁盘空间需求。 + WAL 记录必须保留在备库上,直到可以应用它们。因此,更长的延迟会导致更多 WAL 文件积压,增加备库 pg_wal 目录所需的磁盘空间。 - - 这个参数的目的是和流复制部署一起使用,但是,如果指定了该参数,除了崩溃恢复之外所有的情况下都会遵守它。 - 使用这个特性也会让hot_standby_feedback被延迟,这可能导致主库的膨胀,两者一起使用时要小心。 - + 此参数旨在用于流复制部署;不过,只要指定了此参数,它就会在除崩溃恢复以外的所有情况下生效。使用此功能也会延迟 hot_standby_feedback,可能导致主库膨胀;同时使用两者时应谨慎。 - 当synchronous_commit被设置为remote_apply时,同步复制会受到这个设置的影响,每一个COMMIT都需要等待被应用。 + 当 synchronous_commit 设置为 remote_apply 时,同步复制会受到此设置影响;每个 COMMIT 都必须等待提交被应用。 - - - 这个参数只能在postgresql.conf文件中或通过服务器命令行进行设置。 - - - + + + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 + + + - + sync_replication_slots (boolean) sync_replication_slots配置参数 @@ -4109,53 +3866,8 @@ ANY num_sync ( - createrole_self_grant (string) - - createrole_self_grant配置参数 - - - - - 如果一个拥有CREATEROLE但不拥有SUPERUSER权限的用户创建了角色,并且此选项被设置为非空值,则新创建的角色将以指定选项授予创建者。 - 该值必须是setinherit或它们的逗号分隔列表。默认值为空字符串,这会禁用此功能。 - - - 此选项的目的是允许非超级用户的CREATEROLE用户自动继承或自动获得对新创建角色执行SET ROLE的能力。 - 由于CREATEROLE用户始终会隐式获得其所创建角色的ADMIN OPTION,因此该用户总是可以通过执行GRANT语句达到相同效果,但自动授予在可用性上更方便。 - 超级用户会自动继承每个角色的权限,并且始终可以切换到任何角色;此设置可用于为CREATEROLE用户提供类似行为。 - - - - - event_triggers (boolean) - - event_triggers配置参数 - - - - - 允许临时禁用事件触发器的执行,以便对有故障的事件触发器进行故障排查和修复。 - 将其设置为false会禁用所有事件触发器;设置为true则允许所有事件触发器触发,这也是默认值。 - 只有超级用户和具有适当SET权限的用户才能更改此设置。 - - - - - restrict_nonsystem_relation_kind (string) - - restrict_nonsystem_relation_kind配置参数 - - - - - 设置禁止访问非系统关系的关系类型。该值采用关系类型的逗号分隔列表形式。 - 目前支持的关系类型是viewforeign-table。 - - - @@ -4165,11 +3877,7 @@ ANY num_sync ( @@ -4200,16 +3908,15 @@ ANY num_sync ( num_sync ( num_sync ( num_sync ( + enable_bitmapscan (boolean) - 位图扫描 + 位图扫描 - enable_bitmapscan配置参数 + enable_bitmapscan 配置参数 - - 允许或禁止查询规划器使用位图扫描计划类型。默认值是on。 + 启用或禁用查询规划器对位图扫描计划类型的使用。默认值为 on - - - + + + + + enable_gathermerge (boolean) - enable_gathermerge配置参数 + enable_gathermerge 配置参数 - - 启用或者禁用查询规划器对收集归并计划类型的使用。默认值是on。 + 启用或禁用查询规划器对收集归并计划类型的使用。默认值为 on - - + + - + enable_group_by_reordering (boolean) enable_group_by_reordering配置参数 @@ -4350,89 +4056,90 @@ ANY num_sync ( + + enable_hashagg (boolean) - enable_hashagg配置参数 + enable_hashagg 配置参数 - - 允许或禁用查询规划器使用哈希聚合计划类型。默认值是on。 + 启用或禁用查询规划器对哈希聚合计划类型的使用。默认值为 on - + + enable_hashjoin (boolean) - enable_hashjoin配置参数 + enable_hashjoin 配置参数 - - 允许或禁止查询规划器使用哈希连接计划类型。默认值是on。 + 启用或禁用查询规划器对哈希连接计划类型的使用。默认值为 on - + + enable_incremental_sort (boolean) enable_incremental_sort 配置参数 - - 启用或禁用查询规划器对增量排序步骤的使用。默认为on。 + 启用或禁用查询规划器对增量排序步骤的使用。默认值为 on - + + + + enable_indexscan (boolean) - 索引扫描 + 索引扫描 - enable_indexscan配置参数 + enable_indexscan 配置参数 - - 允许或禁止查询规划器使用索引扫描计划类型。默认值是on。 + 启用或禁用查询规划器对索引扫描和仅索引扫描计划类型的使用。默认值为 on。另请参见 - enable_indexonlyscan (boolean) - enable_indexonlyscan配置参数 + enable_indexonlyscan 配置参数 - - 允许或禁止查询规划器使用只用索引扫描计划类型(见)。默认值是on。 + 启用或禁用查询规划器对仅索引扫描计划类型的使用(参见 )。默认值为 on。还必须启用 ,查询规划器才会考虑仅索引扫描。 - + + enable_material (boolean) - enable_material配置参数 + enable_material 配置参数 @@ -4443,8 +4150,9 @@ ANY num_sync ( + + enable_memoize (boolean) enable_memoize 配置参数 @@ -4461,26 +4169,27 @@ ANY num_sync ( + + enable_mergejoin (boolean) - enable_mergejoin配置参数 + enable_mergejoin 配置参数 - - 允许或禁止查询规划器使用归并连接计划类型。默认值是on。 + 启用或禁用查询规划器对归并连接计划类型的使用。默认值为 on - + + enable_nestloop (boolean) - enable_nestloop配置参数 + enable_nestloop 配置参数 @@ -4506,17 +4215,17 @@ ANY num_sync ( + + enable_parallel_hash (boolean) - enable_parallel_hash配置参数 + enable_parallel_hash 配置参数 - - 允许或禁止查询规划器对并行哈希使用哈希连接计划类型。如果哈希连接计划也没有启用,这个参数没有效果。默认值是on。 + 启用或禁用查询规划器对使用并行哈希的哈希连接计划类型的使用。如果没有同时启用哈希连接计划,此参数不起作用。默认值为 on @@ -4536,41 +4245,37 @@ ANY num_sync ( + + + + enable_partitionwise_join (boolean) - enable_partitionwise_join配置参数 + enable_partitionwise_join 配置参数 - - 允许或者禁止查询规划器使用面向分区的连接,这使得分区表之间的连接以连接匹配的分区的方式来执行。 - 面向分区的连接当前只适用于连接条件包括所有分区键的情况,连接条件必须是相同的数据类型并且子分区集合要1对1匹配。 - 由于面向分区的连接规划在规划期间会使用可观的CPU时间和内存,所以默认值为off。 + 启用或禁用查询规划器对分区连接的使用,使分区表之间的连接可以通过连接相匹配的分区来完成。分区连接目前仅适用于连接条件包含所有分区键的情况;这些分区键必须具有相同的数据类型,并且子分区集合必须一一匹配。启用此设置后,最终计划中内存用量受 work_mem 限制的节点数量可能随所扫描分区的数量线性增加。这可能大幅增加查询执行期间的总内存消耗。查询规划在内存和 CPU 方面的开销也会显著增加。默认值为 off - enable_partitionwise_aggregate (boolean) - enable_partitionwise_aggregate配置参数 + enable_partitionwise_aggregate 配置参数 - - 启用或禁用查询规划器使用分区分组或聚合的功能,该功能允许在分区表上分别对每个分区执行分组或聚合操作。 - 如果GROUP BY子句不包括分区键,那么只能在每个分区的基础上执行部分聚合,并且必须在稍后进行最终化处理。 - 由于分区分组或聚合在规划期间可能会使用更多的CPU时间和内存,因此默认情况下为off。 + 启用或禁用查询规划器对分区分组或聚合的使用,使分区表上的分组或聚合可以在各个分区上分别执行。如果 GROUP BY 子句不包含分区键,则只能在各分区上执行部分聚合,随后还必须进行最终处理。启用此设置后,最终计划中内存用量受 work_mem 限制的节点数量可能随所扫描分区的数量线性增加。这可能大幅增加查询执行期间的总内存消耗。查询规划在内存和 CPU 方面的开销也会显著增加。默认值为 off - - + + - + enable_presorted_aggregate (boolean) enable_presorted_aggregate配置参数 @@ -5038,7 +4743,7 @@ ANY num_sync ( 包括在普通日志项中。只有可打印 ASCII 字符能被使用在application_name之中。其他字符将被替换为问号(?)。 + application_name可以是任意小于NAMEDATALEN个字符(标准编译中是 64 个字符)的字符串。应用通常在连接服务器时设置此值。该名称将被显示在pg_stat_activity视图中并被包括在 CSV 日志项中。它也会被通过包括在普通日志项中。只有可打印 ASCII 字符能被使用在application_name之中。其他字符将被替换为C 风格的十六进制转义序列。 @@ -5930,77 +5635,22 @@ local0.* /var/log/postgresql - - log_connections (string) + log_connections (boolean) - log_connections配置参数 + log_connections 配置参数 - - - 控制是否记录服务器每次连接的各个阶段。默认值为空字符串 - '',表示禁用所有连接日志。下列选项既可以单独指定, - 也可以用逗号分隔的列表指定: - - -
- 连接日志选项 - - - - - - 名称 - 说明 - - - - - receipt - 记录收到连接。 - - - authentication - 记录认证方法用于识别用户的原始身份。在大多数情况下,该身份字符串与PostgreSQL用户名一致,但某些第三方认证方法可能会在服务器存储之前修改原始用户标识符。无论此设置为何值,认证失败始终都会被记录。 - - - authorization - 记录授权成功完成。此时连接已经建立,但后端尚未完全初始化。日志消息会包含授权后的用户名,以及数据库名和应用名(如果适用)。 - - - setup_durations - 记录从 postmaster 接受传入连接开始,到连接准备好执行第一条查询为止,建立连接并完成后端初始化所花费的时间。日志消息会包含三个时长:总设置时长、fork 新后端所花费的时间,以及用户认证所花费的时间。 - - - all - 一个便捷别名,相当于指定所有选项。如果在其他选项列表中包含all,则会记录连接的所有方面。 - - - -
- - - 断开连接的日志由单独控制。 - - - 出于向后兼容性考虑,onoff、 - truefalseyes、 - no10仍然受支持。 - 正向值等价于指定receiptauthentication和 - authorization选项。 - - - - 只有超级用户和具有适当SET权限的用户可以在会话开始时更改此参数, - 并且在会话内部完全不能更改。 + 记录每次尝试连接服务器的操作,以及客户端认证(如有必要)和授权的成功完成。 + 只有超级用户和具有适当 SET 权限的用户可以在会话开始时更改此参数,在会话期间则完全不能更改。 + 默认值为 off - - 某些客户端程序(例如psql)在要求密码时会尝试连接两次,因此重复的收到连接消息并不一定表示一个错误。 + 某些客户端程序(例如 psql)在判断是否需要密码时会尝试连接两次, + 因此重复的收到连接消息并不一定表示有问题。
@@ -6218,13 +5868,13 @@ local0.* /var/log/postgresql %v - 虚拟事务 ID (backendID/localXID) + 虚拟事务 ID (procNumber/localXID);参见 %x - 事务 ID (如果未分配则为 0) + 事务 ID (如果未分配则为 0);参见 @@ -6243,7 +5893,7 @@ local0.* /var/log/postgresql %% - 纯文字 % + 字面字符 % @@ -6277,7 +5927,7 @@ FROM pg_stat_activity; - Syslog产生自己的时间戳和进程 ID 信息,因此如果你记录到syslog你可能不希望包括哪些转义。 + Syslog产生自己的时间戳和进程 ID 信息,因此如果你记录到syslog你可能不希望包括那些转义。 @@ -6810,12 +6460,12 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 为不同目的设置标识这个数据库集簇(实例)的名称。此集簇名称出现在该集簇中所有服务器进程的进程标题中。 - 此外,它还是备库连接的默认应用名称。(参见 .) + 设置一个用于各种目的、标识此数据库集簇(实例)的名称。集簇名称会出现在此集簇所有服务器进程的进程标题中。 + 此外,它还是备库连接的默认应用名称(参见)。 - 这个名称可以是任何长度不超过NAMEDATALEN个字符(在标准编译中是 64字符)的任何字符串。只有可打印的 ASCII 字符能被用在cluster_name值中。其他字符将被替换为问号(?)。如果这个参数被设置为空字符串''(也是默认值),将不会显示名称。这个参数只能在服务器启动时设置。 + 这个名称可以是任何长度少于NAMEDATALEN个字符(在标准编译中是 64字符)的任何字符串。只有可打印的 ASCII 字符能被用在cluster_name值中。其他字符将被替换为C 风格的十六进制转义序列。如果这个参数被设置为空字符串''(也是默认值),将不会显示名称。这个参数只能在服务器启动时设置。 @@ -6909,19 +6559,24 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - track_io_timing (boolean) - track_io_timing配置参数 + track_io_timing 配置参数 - - 启用数据库I/O调用的计时。 默认情况下,此参数处于关闭状态,因为它将重复查询操作系统的当前时间,这可能会在某些平台上造成显著的开销。 您可以使用工具来测量系统上计时的开销。 - I/O计时信息显示在 - pg_stat_database中,在的输出中,当使用BUFFERS选项时,在的输出中,当使用VERBOSE选项时,由autovacuum执行自动清理和自动分析时,当设置了时,以及由。 - 只有超级用户和具有适当SET权限的用户才能更改此设置。 + 启用数据库 I/O 调用的计时。此参数默认关闭,因为计时需要反复向操作系统查询 + 当前时间,在某些平台上可能会产生显著开销。可以使用 工具 + 测量本系统上的计时开销。I/O 计时信息会显示在 + pg_stat_database 中、 + pg_stat_io 中、 + 使用 BUFFERS 选项的 输出中、 + 使用 VERBOSE 选项的 输出中, + autovacuum 也会在执行自动清理和自动分析时输出这些信息 + (需设置 ), + 同样提供这些信息。只有超级用户和具有适当 + SET 权限的用户可以更改此设置。 @@ -6936,14 +6591,8 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 启用WAL I/O调用的定时。此参数默认关闭,因为它将重复查询操作系统的当前时间, - 这可能会在某些平台上造成显著的开销。 - 您可以使用pg_test_timing工具来 - 测量系统上定时的开销。 - I/O定时信息显示在 - pg_stat_wal中。 - 只有超级用户和具有适当SET权限的用户才能更改此设置。 - + 启用 WAL I/O 调用的计时。此参数默认关闭,因为它会反复向操作系统查询当前时间,可能在某些平台上产生显著开销。可以使用 pg_test_timing 工具测量系统上的计时开销。I/O 计时信息显示在 pg_stat_wal 中。只有超级用户和具有适当 SET 权限的用户才能更改此设置。 +
@@ -7038,7 +6687,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 确认只有一个查询标识符被计算和显示,如果一个查询标识符已经被计算,扩展计算标识符将抛出一个错误。 + 为确保只有一个查询标识符被计算和显示,计算查询标识符的扩展在查询标识符已被计算时应当抛出一个错误。 @@ -7087,16 +6736,14 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - Automatic Vacuuming + 自动清理 自动清理 配置参数 - - 这些参数控制 vacuuming 的行为。有关 vacuum 的目的和职责的更多信息,请参阅。 - + 这些设置控制autovacuum特性的行为。详情请参考 @@ -7123,7 +6770,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 注意即使该参数被禁用,系统也会在需要防止事务ID回卷时发起清理进程。详情请见。 + 注意即使该参数被禁用,系统也会在需要防止事务ID回卷时发起自动清理进程。详情请见 @@ -7152,7 +6799,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 指定自动清理在任意给定数据库上运行的最小延迟。在每一轮中后台进程检查数据库并根据需要为数据库中的表发出VACUUMANALYZE命令。 + 指定自动清理在任意给定数据库上各次运行之间的最小间隔。在每一轮中后台进程检查数据库并根据需要为数据库中的表发出VACUUMANALYZE命令。 如果指定值时没有单位,则以秒为单位。默认值为1分钟(1min)。该参数只能在postgresql.conf文件或在服务器命令行上设置。 @@ -7186,7 +6833,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; 指定在任何一个表中触发 VACUUM所需要插入的元组数。默认值为 1000 个元组。 如果指定了 -1,则autovacuum不会根据插入数量在任何表上触发 VACUUM操作。 - 此参数只能在postgresql.conf文件或服务器命令行中设置;但可以通过更改表存储参数来覆盖单个表的设置。 + 此参数只能在postgresql.conf文件或服务器命令行中设置;但可以通过更改表存储参数来覆盖单个表的设置。 @@ -7235,7 +6882,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; 指定一个要添加到autovacuum_vacuum_insert_threshold 中的表的大小的比例,在决定是否触发VACUUM时。 - 默认值为 0.2(表大小的 20%)。此参数只能在postgresql.conf文件或服务器命令行中设置;但可以通过更改表存储参数来覆盖单个表的设置。 + 默认值为 0.2(表大小的 20%)。此参数只能在postgresql.conf文件或服务器命令行中设置;但可以通过更改表存储参数来覆盖单个表的设置。 @@ -7324,7 +6971,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 指定用于自动VACUUM操作中的代价限制值。如果指定-1(默认值),则使用值。注意该值被按比例地分配到运行中的自动清理工作者上(如果有多个),因此每一个工作者的限制值之和不会超过这个变量中的值。该参数只能在postgresql.conf文件或在服务器命令中设置。但是对个别表可以通过修改表存储参数来覆盖该设置。 + 指定用于自动VACUUM操作中的代价限制值。如果指定-1(默认值),则使用值。注意该值被按比例地分配到运行中的自动清理工作进程上(如果有多个),因此每一个工作进程的限制值之和不会超过这个变量中的值。该参数只能在postgresql.conf文件或在服务器命令中设置。但是对个别表可以通过修改表存储参数来覆盖该设置。 @@ -7371,7 +7018,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; search_path配置参数 - pathfor schemas + 路径用于模式 @@ -7464,7 +7111,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; default_tablespace配置参数 - tablespacedefault + 表空间默认 @@ -7569,7 +7216,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; default_transaction_isolation (enum) - transaction isolation level + 事务隔离级别 设置默认值 @@ -7592,7 +7239,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; default_transaction_read_only (boolean) - read-only transaction + 只读事务 设置默认值 @@ -7615,7 +7262,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; default_transaction_deferrable (boolean) - deferrable transaction + 可延迟事务 设置默认值 @@ -7642,7 +7289,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; transaction_isolation (enum) - transaction isolation level + 事务隔离级别 transaction_isolation配置参数 @@ -7662,7 +7309,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; transaction_read_only (boolean) - read-only transaction + 只读事务 transaction_read_only 配置参数 @@ -7682,7 +7329,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; transaction_deferrable (boolean) - deferrable transaction + 可延迟事务 transaction_deferrable 配置参数 @@ -7826,7 +7473,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; 此选项可以用于确保空闲会话不会在不合理的时间内持有锁。 - 即使没有持有重要的锁的时候,打开的事务也会防止清理最近死亡的可能只对这个事务可见的元组;所以长时间保持空闲会导致表膨胀。 + 即使没有持有重要的锁的时候,打开的事务也会防止清理最近死亡的可能只对这个事务可见的元组;所以长时间保持空闲会导致表膨胀。 详见 @@ -7868,7 +7515,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 如果表的pg_class.relfrozenxid字段达到此设置指定的年龄,VACUUM就会执行一次激进扫描。激进扫描与常规VACUUM不同,它会访问每一个可能包含未冻结 XID 或 MXID 的页面,而不仅仅是那些可能包含死元组的页面。默认值为 1.5 亿个事务。尽管用户可以将该值设置在 0 到 20 亿之间,VACUUM仍会悄悄将其有效值限制为的 95%,以便在针对该表启动防回卷自动清理之前,周期性手工VACUUM仍有机会运行。详见。 + 如果表的pg_class.relfrozenxid字段达到此设置指定的年龄,VACUUM就会执行一次激进扫描。激进扫描与常规VACUUM不同,它会访问每一个可能包含未冻结 XID 或 MXID 的页面,而不仅仅是那些可能包含死元组的页面。默认值为 1.5 亿个事务。尽管用户可以将该值设置在 0 到 20 亿之间,VACUUM仍会悄悄将其有效值限制为不超过的 95%,以便在针对该表启动防回卷自动清理之前,周期性手工VACUUM仍有机会运行。详见 @@ -7883,7 +7530,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 指定VACUUM在决定是否冻结带有较旧 XID 的页面时应采用的截止年龄(以事务数计)。默认值为 5000 万个事务。尽管用户可以将该值设置在 0 到 10 亿之间,VACUUM仍会悄悄将其有效值限制为的一半,以避免强制自动清理之间的间隔过短。详见。 + 指定VACUUM在决定是否冻结带有较旧 XID 的页面时应采用的截止年龄(以事务数计)。默认值为 5000 万个事务。尽管用户可以将该值设置在 0 到 10 亿之间,VACUUM仍会悄悄将其有效值限制为不超过的一半,以避免强制自动清理之间的间隔过短。详见 @@ -7901,7 +7548,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; 指定表的pg_class.relfrozenxid字段在VACUUM采取非常措施以避免系统范围事务 ID 回卷失败之前所允许达到的最大年龄(以事务数计)。这是VACUUM的最后手段。失效保护通常会在为防止事务 ID 回卷而启动的自动清理已经运行一段时间后触发,但也可能在任何一次VACUUM期间触发。 - 当触发失效保护时,当前生效的任何基于成本的延迟都将不再应用,进一步的非关键维护任务(例如索引 vacuum)会被跳过,并且正在使用的任何缓冲区访问策略都会被禁用,从而使VACUUM可以自由使用全部共享缓冲区。 + 当触发失效保护时,当前生效的任何基于代价的延迟都将不再应用,进一步的非关键维护任务(例如索引清理)会被跳过,并且正在使用的任何缓冲区访问策略都会被禁用,从而使VACUUM可以自由使用全部共享缓冲区 默认值为 16 亿个事务。尽管用户可以将该值设置在 0 到 21 亿之间,VACUUM仍会悄悄将其有效值调整为不低于的 105%。 @@ -7919,7 +7566,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 如果表的pg_class.relminmxid字段达到此设置指定的年龄,VACUUM就会执行一次激进扫描。激进扫描与常规VACUUM不同,它会访问每一个可能包含未冻结 XID 或 MXID 的页面,而不仅仅是那些可能包含死元组的页面。默认值为 1.5 亿个 multixact。尽管用户可以将该值设置在 0 到 20 亿之间,VACUUM仍会悄悄将其有效值限制为的 95%,以便在针对该表启动防回卷清理之前,周期性手工VACUUM仍有机会运行。详见。 + 如果表的pg_class.relminmxid字段达到此设置指定的年龄,VACUUM就会执行一次激进扫描。激进扫描与常规VACUUM不同,它会访问每一个可能包含未冻结 XID 或 MXID 的页面,而不仅仅是那些可能包含死元组的页面。默认值为 1.5 亿个多事务。尽管用户可以将该值设置在 0 到 20 亿之间,VACUUM仍会悄悄将其有效值限制为不超过的 95%,以便在针对该表启动防回卷清理之前,周期性手工VACUUM仍有机会运行。详见 @@ -7934,33 +7581,33 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 指定VACUUM在决定是否冻结带有较旧 multixact ID 的页面时应采用的截止年龄(以 multixact 计)。默认值为 500 万个 multixact。尽管用户可以将该值设置在 0 到 10 亿之间,VACUUM仍会悄悄将其有效值限制为的一半,以避免强制自动清理之间的间隔过短。详见。 + 指定VACUUM在决定是否冻结带有较旧多事务 ID 的页面时应采用的截止年龄(以多事务计)。默认值为 500 万个多事务。尽管用户可以将该值设置在 0 到 10 亿之间,VACUUM仍会悄悄将其有效值限制为不超过的一半,以避免强制自动清理之间的间隔过短。详见 - + + vacuum_multixact_failsafe_age (integer) - vacuum_multixact_failsafe_age配置参数 + vacuum_multixact_failsafe_age 配置参数 - - 指定表的pg_class.relminmxid字段在VACUUM采取非常措施以避免系统范围 multixact ID 回卷失败之前所允许达到的最大年龄(以 multixact 计)。这是VACUUM的最后手段。失效保护通常会在为防止事务 ID 回卷而启动的自动清理已经运行一段时间后触发,但也可能在任何一次VACUUM期间触发。 + 指定表的 pg_class.relminmxid 字段在 VACUUM 采取特别措施避免系统范围的多事务 ID 回卷故障之前,所能达到的最大年龄(以多事务计)。这是 VACUUM 的最后手段。失效保护通常会在防止事务 ID 回卷的自动清理已经运行一段时间后触发,但也可能在任何 VACUUM 期间触发。 - 当触发失效保护时,当前生效的任何基于成本的延迟都将不再应用,进一步的非关键维护任务(例如索引 vacuum)会被跳过。 + 触发失效保护后,任何正在生效的基于代价的延迟都将不再应用,后续非必要的维护任务(例如索引清理)也会被跳过。 - 默认值为 16 亿个 multixact。尽管用户可以将该值设置在 0 到 21 亿之间,VACUUM仍会悄悄将其有效值调整为不低于的 105%。 + 默认值为 16 亿个多事务。虽然用户可以将此值设置为 0 到 21 亿之间的任意值,VACUUM 仍会将实际生效值自动调整为不低于 的 105%。 - + bytea_output (enum) @@ -8004,7 +7651,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; SET XML OPTION - XML option + XML 选项 @@ -8042,6 +7689,54 @@ SET XML OPTION { DOCUMENT | CONTENT }; + + createrole_self_grant (string) + + createrole_self_grant配置参数 + + + + + 如果一个拥有CREATEROLE但不拥有SUPERUSER权限的用户创建了角色,并且此选项被设置为非空值,则新创建的角色将以指定选项授予创建者。 + 该值必须是setinherit或它们的逗号分隔列表。默认值为空字符串,这会禁用此功能。 + + + 此选项的目的是允许非超级用户的CREATEROLE用户自动继承或自动获得对新创建角色执行SET ROLE的能力。 + 由于CREATEROLE用户始终会隐式获得其所创建角色的ADMIN OPTION,因此该用户总是可以通过执行GRANT语句达到相同效果,但自动授予在可用性上更方便。 + 超级用户会自动继承每个角色的权限,并且始终可以切换到任何角色;此设置可让CREATEROLE用户对其创建的用户获得类似的行为。 + + + + + + event_triggers (boolean) + + event_triggers配置参数 + + + + + 允许临时禁用事件触发器的执行,以便对有故障的事件触发器进行故障排查和修复。 + 将其设置为false会禁用所有事件触发器;设置为true则允许所有事件触发器触发,这也是默认值。 + 只有超级用户和具有适当SET权限的用户才能更改此设置。 + + + + + + restrict_nonsystem_relation_kind (string) + + restrict_nonsystem_relation_kind配置参数 + + + + + 设置禁止访问非系统关系的关系类型。该值采用关系类型的逗号分隔列表形式。 + 目前支持的关系类型是viewforeign-table。 + + + + @@ -8090,7 +7785,7 @@ SET XML OPTION { DOCUMENT | CONTENT }; TimeZone配置参数 - time zone + 时区 @@ -8106,7 +7801,7 @@ SET XML OPTION { DOCUMENT | CONTENT }; timezone_abbreviations配置参数 - time zone names + 时区名称 @@ -8120,11 +7815,11 @@ SET XML OPTION { DOCUMENT | CONTENT }; extra_float_digits (integer) - significant digits + 有效数字 - floating-point - display + 浮点数 + 显示 extra_float_digits配置参数 @@ -8152,7 +7847,7 @@ SET XML OPTION { DOCUMENT | CONTENT }; - 此参数的含义,以及其默认值,在 PostgreSQL 12 中发生了变化; + 此参数的含义,以及其默认值,在 PostgreSQL 12 中发生了变化; 参见 以便进一步讨论。 @@ -8165,7 +7860,7 @@ SET XML OPTION { DOCUMENT | CONTENT }; client_encoding配置参数 - character set + 字符集 @@ -8514,12 +8209,12 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' deadlock_timeout (integer) - deadlock + 死锁 期间超时 - timeout - deadlock + 超时 + 死锁 deadlock_timeout配置参数 @@ -8554,14 +8249,11 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' - 共享锁表跟踪在max_locks_per_transaction * ( + ) 个对象(如表)上的锁。因此,在任何一个时刻,只有不超过这么多个可区分对象能够被锁住。这个参数控制为每个事务分配的对象锁的平均数量。个体事务可以锁住更多对象,数量可以和锁表中能容纳的所有事务的锁一样多。这是能被锁住的行数,那个值是没有限制的。默认值 64 已经被历史证明是足够的,但是如果你有需要在一个事务中使用很多不同表的查询(例如查询一个有很多子表的父表),你可能需要提高这个值。这个参数只能在服务器启动时设置。 + 共享锁表为每个服务器进程或预备事务预留可容纳max_locks_per_transaction 个对象(例如表)的空间;因此,在任何时刻可被锁住的不同对象数都不能超过总容量。这个参数限制每个事务使用的对象锁的平均数量;只要所有事务的锁能放入锁表中,单个事务就可以锁住更多对象。这是能被锁住的行数,那个值是没有限制的。默认值 64 已经被历史证明是足够的,但是如果你有需要在一个事务中使用很多不同表的查询(例如查询一个有很多子表的父表),你可能需要提高这个值。这个参数只能在服务器启动时设置。 - 当运行一个备库时,你必须设置这个参数等于或大于主库上的参数。 - 否则,备库上可能无法允许查询。 + 运行备库时,必须将此参数设置为大于或等于主库上的值。否则,备库上将不允许查询。 @@ -8576,9 +8268,7 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' - 共享谓词锁表跟踪在max_pred_locks_per_transaction * ( + ) 个对象(如表)上的锁。因此,在任何一个时刻,只有不超过这么多个可区分对象能够被锁住。这个参数控制为每个事务分配的对象锁的平均数量。个体事务可以锁住更多对象,数量可以和锁表中能容纳的所有事务的锁一样多。这是能被锁住的行数,那个值是没有限制的。默认值 64 已经在测试中被证明通常是足够的,但是如果你有需要在一个可串行化事务中使用很多不同表的查询(例如查询一个有很多子表的父表),你可能需要提高这个值。这个参数只能在服务器启动时设置。 + 共享谓词锁表为每个服务器进程或预备事务预留可容纳max_pred_locks_per_transaction 个对象(例如表)的空间;因此,在任何时刻可被锁住的不同对象数都不能超过总容量。这个参数限制每个事务使用的对象锁的平均数量;只要所有事务的锁能放入锁表中,单个事务就可以锁住更多对象。这是能被锁住的行数,那个值是没有限制的。默认值 64 已经被历史证明是足够的,但是如果你有会在单个可串行化事务中访问许多不同表的客户端,则可能需要提高这个值。这个参数只能在服务器启动时设置。 @@ -8648,7 +8338,7 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' backslash_quote (enum) - stringsbackslash quotes + 字符串反斜线引号 backslash_quote配置参数 @@ -8668,7 +8358,7 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' escape_string_warning (boolean) - strings转义警告 + 字符串转义警告 escape_string_warning配置参数 @@ -8724,7 +8414,7 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' standard_conforming_strings (boolean) - stringsstandard conforming + 字符串标准符合 standard_conforming_strings配置参数 @@ -9115,7 +8805,7 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' server_encoding配置参数 - character set + 字符集 diff --git a/zh/17/datatype.sgml b/zh/17/datatype.sgml index ace7798b..e8c68135 100644 --- a/zh/17/datatype.sgml +++ b/zh/17/datatype.sgml @@ -354,19 +354,19 @@ smallint 2字节 小范围整数 - -32768 to +32767 + -32768 到 +32767 integer 4字节 整数的典型选择 - -2147483648 to +2147483647 + -2147483648 到 +2147483647 bigint 8字节 大范围整数 - -9223372036854775808 to +9223372036854775807 + -9223372036854775808 到 +9223372036854775807 @@ -866,9 +866,8 @@ FROM generate_series(-3.5, 3.5, 1) as x; - 本节描述的是 PostgreSQL 特有的创建 - 自动递增列的方法。另一种方法是使用 SQL 标准的标识列特性, - 参见 。 + 本节介绍 PostgreSQL 特有的自动递增列创建方法。 + 另一种方法是使用 SQL 标准的标识列特性,参见 @@ -947,7 +946,7 @@ ALTER SEQUENCE tablename_money 类型以固定的小数精度存储货币金额; 参见 。小数精度由数据库的 设置决定。表中显示的范围假定 - 有两位小数。输入支持多种格式,包括整数和浮点文字,以及典型的 + 有两位小数。输入支持多种格式,包括整数字面量和浮点数字面量,以及典型的 货币格式,例如 '$1,000.00'。输出通常也采用 后一种形式,但会受到区域设置影响。 @@ -1373,7 +1372,7 @@ SELECT '\xDEADBEEF'::bytea; - <type>bytea</type>文字转义字节 + <type>bytea</type>字面量中需要转义的字节 @@ -2626,7 +2625,7 @@ SELECT '2 years 15 months 100 weeks 99 hours 123456789 milliseconds'::interval; 3 years 3 mons 700 days 133:17:36.789 - 这里,周被理解为 7 days,而较小和较大的时间单位 + 这里,周按7 天计算并单独保留,而较小和较大的时间单位 则被合并并规范化了。 @@ -4045,17 +4044,16 @@ a0ee-bc99-9c0b-4ef8-bb6d-6bb9-bd38-0a11 xml 数据类型可用于存储 XML 数据。与把 XML 数据存储在 - text 字段中相比,它的优势在于会检查输入值是否格式 - 良好,并且提供了可执行类型安全操作的支持函数;见 - 。使用该数据类型要求安装时启用 + text 字段中相比,它的优势在于会检查输入值的良构性,并且提供了可执行类型安全操作的支持函数;见 + 。使用该数据类型要求构建时使用 configure --with-libxml - xml 类型既可以存储符合 XML 标准定义的格式良好的 + xml 类型既可以存储 XML 标准所定义的良构 文档,也可以存储 内容 片段;后者是参照 XQuery 和 XPath 数据模型中更宽松的 - document node + 文档节点 概念来定义的。粗略地说,这意味着内容片段可以拥有多个顶层元素或字符 节点。表达式 xmlvalue IS DOCUMENT @@ -4224,7 +4222,7 @@ SET xmloption TO { DOCUMENT | CONTENT }; - 是一种用户定义的数据类型,它基于另一种底层类型。根据需要,它可以有约束来限制其有效值为底层类型所允许值的一个子集。如果没有约束,它的行为就和底层类型一样 — 例如,任何适用于底层类型的操作符或函数都对该域类型有效。底层类型可以是任何内置或者用户定义的基础类型、枚举类型、数组类型、复合类型、范围类型或者另一个域。 + 是一种用户定义的数据类型,它基于另一种底层类型。根据需要,它可以有约束来限制其有效值为底层类型所允许值的一个子集。除此之外,它的行为与底层类型相同 — 例如,任何适用于底层类型的操作符或函数都对该域类型有效。底层类型可以是任何内置或者用户定义的基础类型、枚举类型、数组类型、复合类型、范围类型或者另一个域。 diff --git a/zh/17/dblink.sgml b/zh/17/dblink.sgml index c14b26d2..95b7765b 100644 --- a/zh/17/dblink.sgml +++ b/zh/17/dblink.sgml @@ -65,8 +65,8 @@ -dblink_connect(text connstr) 返回 text -dblink_connect(text connname, text connstr) 返回 text +dblink_connect(text connstr) returns text +dblink_connect(text connname, text connstr) returns text @@ -128,7 +128,7 @@ dblink_connect(text connname, text connstr) 返回 text 注解 - 如果不可信用户能够访问一个尚未采用模式的安全使用方式的数据库,则应在每个会话开始时从 + 如果不受信任的用户能够访问一个尚未采用模式的安全使用方式的数据库,则应在每个会话开始时从 search_path 中移除公共可写模式。例如,可以把 options=-csearch_path= 加到 connstr 中。这个注意事项并非 dblink 所特有;它适用于每一种执行任意 SQL 命令的接口。 @@ -162,10 +162,9 @@ SELECT dblink_connect('myconn', 'dbname=postgres options=-csearch_path='); OK (1 row) --- FOREIGN DATA WRAPPER functionality --- Note: local connection must require password authentication for this to work properly --- Otherwise, you will receive the following error from dblink_connect(): --- the following error from dblink_connect(): +-- FOREIGN DATA WRAPPER 功能 +-- 注意:要使本例正常工作,本地连接必须要求密码认证。 +-- 否则,dblink_connect() 将报告以下错误: -- ERROR: password is required -- DETAIL: Non-superuser cannot connect if the server does not request a password. -- HINT: Target server's authentication method must be changed. @@ -228,8 +227,8 @@ DROP SERVER fdtest; -dblink_connect_u(text connstr) 返回 text -dblink_connect_u(text connname, text connstr) 返回 text +dblink_connect_u(text connstr) returns text +dblink_connect_u(text connname, text connstr) returns text @@ -249,7 +248,7 @@ dblink_connect_u(text connname, text connstr) 返回 text 因此,dblink_connect_u() 在初始安装时会撤销 PUBLIC 的全部权限,从而除了超级用户之外无法调用它。 在某些情况下,可能适合向被认为可信的特定用户授予 - EXECUTE 权限,但必须谨慎操作。还建议服务器用户的任何 + dblink_connect_u()EXECUTE 权限,但必须谨慎操作。还建议服务器用户的任何 ~/.pgpass 文件不要包含指定通配主机名的记录。 @@ -276,8 +275,8 @@ dblink_connect_u(text connname, text connstr) 返回 text -dblink_disconnect() 返回 text -dblink_disconnect(text connname) 返回 text +dblink_disconnect() returns text +dblink_disconnect(text connname) returns text @@ -349,9 +348,9 @@ SELECT dblink_disconnect('myconn'); -dblink(text connname, text sql [, bool fail_on_error]) 返回 setof record -dblink(text connstr, text sql [, bool fail_on_error]) 返回 setof record -dblink(text sql [, bool fail_on_error]) 返回 setof record +dblink(text connname, text sql [, bool fail_on_error]) returns setof record +dblink(text connstr, text sql [, bool fail_on_error]) returns setof record +dblink(text sql [, bool fail_on_error]) returns setof record @@ -428,7 +427,7 @@ SELECT * WHERE proname LIKE 'bytea%'; - FROM 子句中的 alias 部分必须指定该函数将返回的列名和类型。(在别名中指定列名实际上是标准 SQL 语法,但指定列类型则是 + FROM 子句中的 别名 部分必须指定该函数将返回的列名和类型。(在别名中指定列名实际上是标准 SQL 语法,但指定列类型则是 PostgreSQL 的扩展。)这样系统才能在尝试执行该函数之前,就知道 * 应展开成什么,以及 WHERE 子句中的 proname 指的是什么。运行时,如果远程数据库返回的实际查询结果与 @@ -548,9 +547,9 @@ SELECT * FROM dblink('myconn', 'select proname, prosrc from pg_proc') -dblink_exec(text connname, text sql [, bool fail_on_error]) 返回 text -dblink_exec(text connstr, text sql [, bool fail_on_error]) 返回 text -dblink_exec(text sql [, bool fail_on_error]) 返回 text +dblink_exec(text connname, text sql [, bool fail_on_error]) returns text +dblink_exec(text connstr, text sql [, bool fail_on_error]) returns text +dblink_exec(text sql [, bool fail_on_error]) returns text @@ -675,8 +674,8 @@ DETAIL: ERROR: null value in column "relnamespace" violates not-null constrain -dblink_open(text cursorname, text sql [, bool fail_on_error]) 返回 text -dblink_open(text connname, text cursorname, text sql [, bool fail_on_error]) 返回 text +dblink_open(text cursorname, text sql [, bool fail_on_error]) returns text +dblink_open(text connname, text cursorname, text sql [, bool fail_on_error]) returns text @@ -789,8 +788,8 @@ SELECT dblink_open('foo', 'select proname, prosrc from pg_proc'); -dblink_fetch(text cursorname, int howmany [, bool fail_on_error]) 返回 setof record -dblink_fetch(text connname, text cursorname, int howmany [, bool fail_on_error]) 返回 setof record +dblink_fetch(text cursorname, int howmany [, bool fail_on_error]) returns setof record +dblink_fetch(text connname, text cursorname, int howmany [, bool fail_on_error]) returns setof record @@ -932,8 +931,8 @@ SELECT * FROM dblink_fetch('foo', 5) AS (funcname name, source text); -dblink_close(text cursorname [, bool fail_on_error]) 返回 text -dblink_close(text connname, text cursorname [, bool fail_on_error]) 返回 text +dblink_close(text cursorname [, bool fail_on_error]) returns text +dblink_close(text connname, text cursorname [, bool fail_on_error]) returns text @@ -1038,7 +1037,7 @@ SELECT dblink_close('foo'); -dblink_get_connections() 返回 text[] +dblink_get_connections() returns text[] @@ -1054,7 +1053,7 @@ dblink_get_connections() 返回 text[] 返回值 - 返回一个包含连接名称的 text 数组;如果没有,则返回 NULL。 + 返回包含连接名称的文本数组;如果没有连接,则返回 NULL。 @@ -1083,7 +1082,7 @@ SELECT dblink_get_connections(); -dblink_error_message(text connname) 返回 text +dblink_error_message(text connname) returns text @@ -1154,7 +1153,7 @@ SELECT dblink_error_message('dtest1'); -dblink_send_query(text connname, text sql) 返回 int +dblink_send_query(text connname, text sql) returns int @@ -1229,7 +1228,7 @@ SELECT dblink_send_query('dtest1', 'SELECT * FROM foo WHERE f1 < 3'); -dblink_is_busy(text connname) 返回 int +dblink_is_busy(text connname) returns int @@ -1291,8 +1290,8 @@ SELECT dblink_is_busy('dtest1'); -dblink_get_notify() 返回 setof (notify_name text, be_pid int, extra text) -dblink_get_notify(text connname) 返回 setof (notify_name text, be_pid int, extra text) +dblink_get_notify() returns setof (notify_name text, be_pid int, extra text) +dblink_get_notify(text connname) returns setof (notify_name text, be_pid int, extra text) @@ -1371,7 +1370,7 @@ SELECT * FROM dblink_get_notify(); -dblink_get_result(text connname [, bool fail_on_error]) 返回 setof record +dblink_get_result(text connname [, bool fail_on_error]) returns setof record @@ -1517,7 +1516,7 @@ contrib_regression=# SELECT * FROM dblink_get_result('dtest1') AS t1(f1 int, f2 -dblink_cancel_query(text connname) 返回 text +dblink_cancel_query(text connname) returns text @@ -1580,7 +1579,7 @@ SELECT dblink_cancel_query('dtest1'); -dblink_get_pkey(text relname) 返回 setof dblink_pkey_results +dblink_get_pkey(text relname) returns setof dblink_pkey_results @@ -1669,7 +1668,7 @@ dblink_build_sql_insert(text relname, int2vector primary_key_attnums, integer num_primary_key_atts, text[] src_pk_att_vals_array, - text[] tgt_pk_att_vals_array) 返回 text + text[] tgt_pk_att_vals_array) returns text @@ -1738,7 +1737,7 @@ dblink_build_sql_insert(text relname, 返回值 - 以 text 形式返回所请求的 SQL 语句。 + 以文本形式返回所请求的 SQL 语句。 @@ -1785,7 +1784,7 @@ SELECT dblink_build_sql_insert('foo', '1 2', 2, '{"1", "a"}', '{"1", "b''a"}'); dblink_build_sql_delete(text relname, int2vector primary_key_attnums, integer num_primary_key_atts, - text[] tgt_pk_att_vals_array) 返回 text + text[] tgt_pk_att_vals_array) returns text @@ -1845,7 +1844,7 @@ dblink_build_sql_delete(text relname, 返回值 - 以 text 形式返回所请求的 SQL 语句。 + 以文本形式返回所请求的 SQL 语句。 @@ -1893,7 +1892,7 @@ dblink_build_sql_update(text relname, int2vector primary_key_attnums, integer num_primary_key_atts, text[] src_pk_att_vals_array, - text[] tgt_pk_att_vals_array) 返回 text + text[] tgt_pk_att_vals_array) returns text @@ -1963,7 +1962,7 @@ dblink_build_sql_update(text relname, 返回值 - 以 text 形式返回所请求的 SQL 语句。 + 以文本形式返回所请求的 SQL 语句。 diff --git a/zh/17/ddl.sgml b/zh/17/ddl.sgml index 28c7f49b..1134c46a 100644 --- a/zh/17/ddl.sgml +++ b/zh/17/ddl.sgml @@ -231,20 +231,18 @@ INSERT INTO people (id, name, address) VALUES (DEFAULT, 'C' - 生成列是一种特殊列,其值总是根据其他列计算得出。因此,对列而言,它就像视图对表一样。生成列有两种:存储型和虚拟型。存储型生成列在写入时(插入或更新时)计算,并像普通列一样占用存储空间。虚拟生成列不占用存储空间,而是在读取时计算。因此,虚拟生成列类似于视图,存储型生成列类似于物化视图(只是它总会自动更新)。PostgreSQL目前仅实现了存储型生成列。 + 生成列是一种特殊列,其值总是根据其他列计算得出。因此,对列而言,它就像视图对表一样。生成列有两种:存储型和虚拟型。存储型生成列在写入时(插入或更新时)计算,并像普通列一样占用存储空间。虚拟生成列不占用存储空间,而是在读取时计算。因此,虚拟生成列类似于视图,存储型生成列类似于物化视图(只是它总会自动更新)。 + PostgreSQL 目前只实现了存储型生成列。 - - 要创建生成列,可在CREATE TABLE中使用GENERATED ALWAYS AS子句,例如: - + 要创建生成列,可使用GENERATED ALWAYS + AS子句,在CREATE TABLE中,例如: CREATE TABLE people ( ..., height_cm numeric, height_in numeric GENERATED ALWAYS AS (height_cm / 2.54) STORED ); - - 必须指定关键字STORED以选择存储型生成列。更多细节见。 - +必须指定关键字STORED来选择存储型生成列。参见了解更多细节。 生成列不能直接写入。在INSERTUPDATE命令中,不能为生成列指定值,但可以指定关键字DEFAULT。 @@ -292,13 +290,9 @@ CREATE TABLE people ( 对于继承和分区: - - 如果父列是生成列,其子列也必须是同种类(存储型或虚拟型)的生成列;不过,子列可以使用不同的生成表达式。 - + 如果父列是生成列,其子列也必须是生成列;不过,子列可以使用不同的生成表达式。在插入或更新一行时,实际应用的是该行所在物理表关联的生成表达式。(这与列默认值不同:默认值使用的是查询中所指名表关联的默认值。) + - - 对于存储型生成列,在插入或更新一行时,实际应用的是该行所在物理表关联的生成表达式。(这与列默认值不同:默认值使用的是查询中所指名表关联的默认值。)对于虚拟生成列,在读取表时,应用的是查询中所指名表的生成表达式。 - @@ -312,7 +306,7 @@ CREATE TABLE people ( - 类似地,对于分区表,如果在CREATE TABLE ... PARTITION OF中编写子列定义时未写任何GENERATED子句,则会自动从父列复制该子句。ALTER TABLE ... ATTACH PARTITION要求父列和子列在生成状态上已经匹配,但不要求它们的生成表达式相同。 + 类似地,对于分区表,如果在CREATE TABLE ... PARTITION OF中编写子列定义时未写任何GENERATED子句,则会自动从父列复制该GENERATED子句。ALTER TABLE ... ATTACH PARTITION要求父列和子列在生成状态上已经匹配,但不要求它们的生成表达式相同。 @@ -333,24 +327,16 @@ CREATE TABLE people ( 生成列与其底层基础列分别维护访问权限。因此,可以安排成某个角色能够读取生成列,但不能读取底层基础列。 - - 对于虚拟生成列,只有在生成表达式只使用防泄漏函数时,这种安排才完全安全(见),但系统不会强制检查这一点。 - - - - - 生成表达式中所用函数的权限,会在表达式实际执行时分别在写入或读取时检查,就像生成表达式是由使用生成列的查询直接调用的一样。生成列的用户必须拥有调用生成表达式中所有函数的权限。生成表达式中的函数是以执行查询的用户的权限还是函数所有者的权限来执行,取决于这些函数被定义为SECURITY INVOKER还是SECURITY DEFINER。 - + + 从概念上说,生成列会在BEFORE触发器运行之后更新。因此,BEFORE触发器中对基础列所做的修改会反映到生成列中。反过来,在BEFORE触发器中访问生成列是不允许的。 - - 生成列会在逻辑复制中被跳过,并且不能出现在CREATE PUBLICATION的列列表中。 - + 逻辑复制会跳过生成列,并且不能在CREATE PUBLICATION的列列表中指定生成列。 @@ -3248,8 +3234,8 @@ CREATE TABLE measurement_y2008m02 PARTITION OF measurement 作为一种替代方案,有时更方便的是在分区结构之外创建新表,并稍后将其附加为分区。这允许在新数据出现在分区表中之前加载、检查和转换新数据。 - 此外,ATTACH PARTITION操作只需要在分区表上持有SHARE UPDATE EXCLUSIVE锁,而不像CREATE TABLE ... PARTITION OF那样需要ACCESS EXCLUSIVE锁,因此对分区表上的并发操作更友好。 - CREATE TABLE ... LIKE选项有助于避免繁琐地重复父表定义: + 此外,ATTACH PARTITION操作只需要在分区表上持有SHARE UPDATE EXCLUSIVE锁,而不像CREATE TABLE ... PARTITION OF那样需要ACCESS EXCLUSIVE锁,因此对分区表上的并发操作更友好;更多细节请参见ALTER TABLE ... ATTACH PARTITION。 + CREATE TABLE ... LIKE选项有助于避免繁琐地重复父表定义: CREATE TABLE measurement_y2008m02 @@ -3431,7 +3417,16 @@ ALTER INDEX measurement_city_id_logdate_key - 创建表,所有的表都将从它继承。这个表将不包含数据。不要在这个表上定义任何检查约束,除非想让它们应用到所有的子表上。同样,在这个表上定义索引或者唯一约束也没有意义。对于我们的示例来说,根表是最初定义的measurement表。 + 创建表,所有的表都将从它继承。这个表将不包含数据。不要在这个表上定义任何检查约束,除非想让它们应用到所有的子表上。同样,在这个表上定义索引或者唯一约束也没有意义。对于我们的示例来说,根表是最初定义的measurement表: + + +CREATE TABLE measurement ( + city_id int not null, + logdate date not null, + peaktemp int, + unitsales int +); + @@ -4040,7 +4035,7 @@ DROP TABLE products CASCADE; - 对于一个将其主体定义为字符串文字的用户定义函数或过程,PostgreSQL会跟踪与函数的外部可见属性相关的依赖关系,例如其参数和结果类型,但不会跟踪只有通过检查函数主体才能知道的依赖关系。例如,考虑以下情况: + 对于一个将其主体定义为字符串字面量的用户定义函数或过程,PostgreSQL会跟踪与函数的外部可见属性相关的依赖关系,例如其参数和结果类型,但不会跟踪只有通过检查函数主体才能知道的依赖关系。例如,考虑以下情况: CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', diff --git a/zh/17/dfunc.sgml b/zh/17/dfunc.sgml index 91898df4..61d916ac 100644 --- a/zh/17/dfunc.sgml +++ b/zh/17/dfunc.sgml @@ -46,7 +46,7 @@ FreeBSD - FreeBSDshared library + FreeBSD共享库 @@ -65,7 +65,7 @@ cc -shared -o foo.so foo.o Linux - Linuxshared library + Linux共享库 @@ -82,7 +82,7 @@ cc -shared -o foo.so foo.o macOS - macOSshared library + macOS共享库 @@ -98,7 +98,7 @@ cc -bundle -flat_namespace -undefined suppress -o foo.so foo.o NetBSD - NetBSDshared library + NetBSD共享库 @@ -116,7 +116,7 @@ gcc -shared -o foo.so foo.o OpenBSD - OpenBSDshared library + OpenBSD共享库 @@ -133,7 +133,7 @@ ld -Bshareable -o foo.so foo.o Solaris - Solarisshared library + Solaris共享库 diff --git a/zh/17/docguide.sgml b/zh/17/docguide.sgml index c0e8df51..1dacec9b 100644 --- a/zh/17/docguide.sgml +++ b/zh/17/docguide.sgml @@ -306,7 +306,7 @@ checking for dbtoepub... dbtoepub - 对于 U.S. letter 格式: + 对于美国信纸格式: doc/src/sgml$ make postgres-US.pdf @@ -320,7 +320,7 @@ checking for dbtoepub... dbtoepub 因此,在某些系统上,构建会因内存相关错误而失败。这通常可以通过在配置文件 ~/.foprc中配置 Java 堆设置来解决,例如: -# FOP binary distribution +# FOP 二进制发行版 FOP_OPTS='-Xmx1500m' # Debian JAVA_ARGS='-Xmx1500m' diff --git a/zh/17/ecpg.sgml b/zh/17/ecpg.sgml index 46ce5efb..c0e673a5 100644 --- a/zh/17/ecpg.sgml +++ b/zh/17/ecpg.sgml @@ -1139,7 +1139,7 @@ oid=313780, datname=testdb, size=8183012 - 结构体主变量将列尽数吸收成结构体的域。额外的列可以被分配给其他主变量。例如,上面的程序也可以使用结构体外部的size变量重新构造: + 结构体主变量吸收的列数与结构体的字段数相同。额外的列可以被分配给其他主变量。例如,上面的程序也可以使用结构体外部的size变量改写: EXEC SQL BEGIN DECLARE SECTION; typedef struct @@ -1440,7 +1440,7 @@ while (1) 用户定义的基础类型 - ECPG 并不直接支持新的用户定义的基本类型。你可以使用外部字符串表示以及类型char[]VARCHAR[]的主变量,并且这种方案事实上对很多类型都是合适和足够的。 + ECPG 并不直接支持新的用户定义的基础类型。你可以使用外部字符串表示以及类型char[]VARCHAR[]的主变量,并且这种方案事实上对很多类型都是合适和足够的。 @@ -4743,7 +4743,7 @@ EXEC SQL INCLUDE "filename"; 当前目录 /usr/local/include - PostgreSQL 的包括目录,在编译时定义(例如/usr/local/pgsql/include + PostgreSQL 的头文件目录,在编译时定义(例如/usr/local/pgsql/include /usr/include @@ -4870,7 +4870,7 @@ EXEC SQL UPDATE Tbl SET col = MYNUMBER; - 此示例将完全编译三个SET TIMEZONE命令之一: + 此示例将完全编译三个SET TIMEZONE命令之一: EXEC SQL ifdef TZVAR; EXEC SQL SET TIMEZONE TO TZVAR; @@ -5498,7 +5498,7 @@ DATABASE connection_target 使用 user_name/passworduser_name IDENTIFIED BY password或者 - user_name USING password之一,这个参数也能指定用户名和密码. + user_name USING password之一,这个参数也能指定用户名和密码。 @@ -6078,9 +6078,7 @@ EXECUTE IMMEDIATE string - 如果你使用文字字符串,请注意任何你可能希望在SQL语句中包括的双引号必须写为八进制转义(\042) ,而不是通常的C惯语\"。 - 这是因为字符串在EXEC SQL段里面,所以ECPG 语法分析器根据SQL规则而不是C规则来解析它。 - 任何内嵌的反斜杠后续将按照C规格处理;但是\"会造成直接语法错误,因为它被视为文字的终结。 + 如果使用字符串字面量,请注意,要在 SQL 语句中包含的双引号必须写为八进制转义(\042),而不是通常的 C 写法\"。这是因为字符串位于EXEC SQL段中,ECPG 词法分析器会按照 SQL 规则而非 C 规则解析它。内嵌的反斜杠随后会按照 C 规则处理;但\"会被视为字面量的结束,因此会立即引起语法错误。 @@ -6413,9 +6411,7 @@ PREPARE prepared_name FROM - 如果你使用文字字符串,请注意任何你可能希望在SQL语句中包括的双引号必须写为八进制转义(\042) ,而不是通常的C惯语\"。 - 这是因为字符串在EXEC SQL段里面,所以ECPG 语法分析器根据SQL规则而不是C规则来解析它。 - 任何内嵌的反斜杠后续将按照C规格处理;但是\"会造成直接语法错误,因为它被视为文字的终结。 + 如果使用字符串字面量,请注意,要在 SQL 语句中包含的双引号必须写为八进制转义(\042),而不是通常的 C 写法\"。这是因为字符串位于EXEC SQL段中,ECPG 词法分析器会按照 SQL 规则而非 C 规则解析它。内嵌的反斜杠随后会按照 C 规则处理;但\"会被视为字面量的结束,因此会立即引起语法错误。 @@ -7672,19 +7668,19 @@ int rjulmdy(date d, short mdy[3]); rdefmtdate - 使用格式掩码将字符字符串转换为日期类型的值。 + 使用格式掩码将字符串转换为日期类型的值。 int rdefmtdate(date *d, char *fmt, char *str); 该函数接收一个指向应该保存操作结果的日期值的指针(d), 用于解析日期的格式掩码(fmt)和包含日期文本表示的C char*字符串 (str)。文本表示应与格式掩码匹配。但是,你不需要将字符串 - 与格式掩码进行一一映射。该函数仅分析顺序顺序,并查找表示年份位置的文字 + 与格式掩码进行一一映射。该函数只分析先后顺序,并查找表示年份位置的字面文本 yyyyyy,表示月份位置的mm 和表示日期位置的dd - 该函数返回以下值: + 该函数返回以下值: diff --git a/zh/17/event-trigger.sgml b/zh/17/event-trigger.sgml index 336dd8ff..d534b329 100644 --- a/zh/17/event-trigger.sgml +++ b/zh/17/event-trigger.sgml @@ -20,11 +20,11 @@ - 事件触发器行为概览 + 事件触发器行为概述 只要与事件触发器关联的事件在其定义所在数据库中发生,事件触发器就会被触发。 - 目前唯一支持的事件有 + 目前仅支持以下事件: loginddl_command_startddl_command_end、 @@ -61,7 +61,7 @@ - ddl_command_end 事件发生在与上述同一组命令执行之后。 + ddl_command_end 事件发生在上述同一组命令执行之后。 要获取这些 DDL 操作的更多细节,可在 ddl_command_end 事件触发器代码中使用集合返回函数 pg_event_trigger_ddl_commands()(见 @@ -1082,7 +1082,7 @@ CALLED_AS_EVENT_TRIGGER(fcinfo) ((fcinfo)->context != NULL && IsA((fcinfo)->context, EventTriggerData)) - 如果该宏返回 true,那么就可以安全地将 fcinfo->context + 如果该宏返回真,那么就可以安全地将 fcinfo->context 转换为 EventTriggerData * 类型,并使用它所指向的 EventTriggerData 结构体。该函数 不得修改 EventTriggerData @@ -1153,7 +1153,7 @@ typedef struct EventTriggerData 事件触发器函数必须返回一个 NULL 指针 (不是 SQL 空值,也就是不要将 - isNull 设为 true)。 + isNull 设为真)。 diff --git a/zh/17/extend.sgml b/zh/17/extend.sgml index d60965b5..f976300e 100644 --- a/zh/17/extend.sgml +++ b/zh/17/extend.sgml @@ -59,7 +59,7 @@ 类型、函数、访问方法等的信息。这些表可以由用户修改,而 PostgreSQL 又是基于这些表来运行的,这意味着 PostgreSQL 可以由用户扩展。相比之下,传统数据库 - 系统通常只能通过修改源代码中的硬编码过程,或加载由 + 系统只能通过修改源代码中的硬编码过程,或加载由 DBMS 供应商专门编写的模块来扩展。 @@ -92,7 +92,7 @@ 数据类型 - 组合 + 复合 @@ -517,7 +517,7 @@ RETURNS anycompatible AS ... 哪些 SQL 对象种类可以成为扩展成员,见 ALTER EXTENSION 的说明。特别是,数据库集簇范围内的对象,如数据库、角色和表空间,不能 - 成为扩展成员,因为扩展只在单个数据库内可见。(尽管扩展脚本并不禁止创 + 成为扩展成员,因为扩展只在单个数据库内可见。(尽管并不禁止扩展脚本创 建这类对象,但如果这样做,它们不会作为扩展的一部分受到跟踪。)还要注意, 虽然表可以成为扩展成员,但其附属对象(如索引)并不直接被视为扩展成员。 另一个重要点是,模式可以属于扩展,但反过来不成立:扩展本身只有一个非 @@ -667,21 +667,7 @@ RETURNS anycompatible AS ... trusted (boolean) - - 如果该参数被设为 true(默认并非如此),则允许某些 - 非超级用户安装 superuser 设为 - true 的扩展。具体来说,任何在当前数据库上具有 - CREATE 权限的用户都被允许安装。当执行 - CREATE EXTENSION 的用户不是超级用户,但因该参数 - 而被允许安装时,安装或更新脚本会以引导超级用户的身份运行,而不是以 - 调用用户的身份运行。如果 superuser 为 - false,这个参数就没有意义。一般来说,对于可能让 - 用户访问原本只有超级用户才能使用的能力(如文件系统访问)的扩展,不 - 应把它设为 true。此外,把一个扩展标记为 - trusted,还需要付出大量额外努力来确保安装和更 - 新脚本写得足够安全;见 - 。 - + 如果将此参数设为 true(不是默认值),则允许某些非超级用户安装 superuser 设为 true 的扩展。具体而言,当前数据库上具有 CREATE 权限的任何人都可以安装。当执行 CREATE EXTENSION 的用户不是超级用户,但凭借此参数获准安装时,安装或更新脚本会以引导超级用户的身份运行,而不是调用用户的身份。如果 superuserfalse,则此参数不起作用。通常,对于可能允许访问原本仅限超级用户使用的能力(例如文件系统访问)的扩展,不应将此参数设为真。此外,将扩展标记为受信任的,需要投入大量额外工作来安全地编写其安装和更新脚本;参见 @@ -742,8 +728,8 @@ RETURNS anycompatible AS ... 如果扩展脚本中包含字符串 @extowner@,该字符串会被 替换为调用 CREATE EXTENSION 或 - ALTER EXTENSION 的用户名称(会作适当引用)。通常, - 这个特性被标记为 trusted 的扩展用来把选定对象的 + ALTER EXTENSION 的用户名称(会适当加上引号)。通常, + 这个特性被标记为受信任的扩展用来把选定对象的 所有权赋给调用用户, 而不是赋给引导超级用户。(不过这样做时应当谨慎。例如,把一个 C 语言 函数的所有权赋给非超级用户,会为该用户创建一条权限提升路径。) @@ -968,7 +954,7 @@ SELECT pg_catalog.pg_extension_config_dump('my_config', 'WHERE NOT standard_entr 在有合适更新脚本可用的前提下, - ALTER EXTENSION UPDATE 命令可以把已安装的扩展更新 + ALTER EXTENSION UPDATE 命令会把已安装的扩展更新 到指定的新版本。更新脚本运行在 CREATE EXTENSION 为安装脚本提供的同一环境中:尤其 是,search_path 的设置方式完全相同,而且脚本创建的 @@ -994,7 +980,7 @@ SELECT pg_catalog.pg_extension_config_dump('my_config', 'WHERE NOT standard_entr 例如,它并不知道 1.1 是否跟在 1.0 之后。它只是匹配可用的版本名,并选择需要应用 更新脚本最少的那条路径。(实际上,版本名可以是任何不包含 - --,且不以前导或尾随 - 结尾的字 + --,且不以 - 开头或结尾的字 符串。) @@ -1067,19 +1053,9 @@ SELECT * FROM pg_extension_update_paths('extension_name - - 将 superuser 属性设为 true 的 - 扩展,还必须考虑其安装脚本和更新脚本中操作所带来的安全风险。恶意用户并不难创建出特洛伊木 - 马对象,从而在后续粗心编写的扩展脚本执行时造成破坏,并借此获得超级用 - 户权限。 - + superuser 属性设为真的扩展,还必须考虑其安装和更新脚本所执行操作的安全风险。恶意用户可以创建木马对象,破坏以后对编写不慎的扩展脚本的执行,从而获得超级用户权限;这并非特别困难。 - - 如果一个扩展被标记为 trusted,那么安装用户可以自己 - 选择安装模式,而该用户可能会有意使用不安全的模式,希望借此获得超级用 - 户权限。因此,从安全角度看,trusted 扩展暴露程度 - 极高,必须仔细审查其所有脚本命令,确保不存在任何可被利用之处。 - + 如果扩展被标记为 trusted,那么安装用户可以选择其安装模式,而该用户可能故意使用不安全的模式,试图获得超级用户权限。因此,从安全角度看,受信任的扩展面临的风险极高,必须仔细检查其全部脚本命令,确保无法被攻破。 关于如何安全地编写函数,建议见下面的 @@ -1127,7 +1103,7 @@ SELECT * FROM pg_extension_update_paths('extension_namemyschema.myfunc(bigint),那么像 myschema.myfunc(42) 这样的调用,就可能被恶意函数 myschema.myfunc(integer) 截获。要注意函数和操作符 - 参数的数据类型必须与声明的实参类型精确匹配,必要时请使用显式类型转 + 所传参数的数据类型必须与声明的参数类型精确匹配,必要时请使用显式类型转 换。 @@ -1178,7 +1154,7 @@ SELECT * FROM pg_extension_update_paths('extension_name扩展示例 - 下面给出一个纯 SQL 扩展的完整示例:一个双元素组合 + 下面给出一个纯 SQL 扩展的完整示例:一个双元素复合 类型,它可以在两个槽位中存储任意类型的值,这两个槽位名为 kv。非文本值会自动强制转换为文本后 再存储。 @@ -1259,7 +1235,7 @@ include $(PGXS) 如果你打算分发自己的 PostgreSQL 扩展模块, - 那么为它们搭建一个可移植的构建系统会相当困难。因此, + 那么为它们搭建一个可移植的构建系统可能相当困难。因此, PostgreSQL 安装提供了一套称为 PGXS 的扩展构建基础设施,使简单的扩展模块可以针对 已安装好的服务器直接构建。PGXS 主要面向包含 C 代码 @@ -1310,7 +1286,7 @@ include $(PGXS) MODULE_big - 要从多个源文件构建的共享库(在 OBJS 中列出对象 + 要从多个源文件构建的共享库(在 OBJS 中列出目标 文件) @@ -1320,7 +1296,7 @@ include $(PGXS) PROGRAM - 要构建的可执行程序(在 OBJS 中列出对象文件) + 要构建的可执行程序(在 OBJS 中列出目标文件) @@ -1647,7 +1623,7 @@ make VPATH=/path/to/extension/source/tree install 正在运行的 PostgreSQL 服务器。列在 REGRESS 中的脚本文件必须位于扩展目录下名为 sql/ 的子目录中。这些文件必须具有 - .sql 扩展名,而该扩展名不应出现在 makefile 的 + .sql 扩展名,而该扩展名不能出现在 makefile 的 REGRESS 列表中。对于每个测试,还应在名为 expected/ 的子目录中有一个包含期望输出的文件,其主 干名相同,扩展名为 .out。 @@ -1666,7 +1642,7 @@ make VPATH=/path/to/extension/source/tree install 必须有一个正在运行的 PostgreSQL 服务器。列 在 ISOLATION 中的脚本文件必须位于扩展目录下名为 specs/ 的子目录中。这些文件必须具有 - .spec 扩展名,而该扩展名不应出现在 makefile 的 + .spec 扩展名,而该扩展名不能出现在 makefile 的 ISOLATION 列表中。对于每个测试,还应在名为 expected/ 的子目录中有一个包含期望输出的文件,其主 干名相同,扩展名为 .out。 diff --git a/zh/17/fdwhandler.sgml b/zh/17/fdwhandler.sgml index b8119b32..4cbe9f54 100644 --- a/zh/17/fdwhandler.sgml +++ b/zh/17/fdwhandler.sgml @@ -753,7 +753,7 @@ RecheckForeignScan(ForeignScanState *node, - <command>EXPLAIN</command>的FDW例程 + <command>EXPLAIN</command> 的 FDW 例程 @@ -803,7 +803,7 @@ ExplainDirectModify(ForeignScanState *node, - <command>ANALYZE</command>的FDW例程 + <command>ANALYZE</command> 的 FDW 例程 diff --git a/zh/17/features.sgml b/zh/17/features.sgml index f212af45..866569f6 100644 --- a/zh/17/features.sgml +++ b/zh/17/features.sgml @@ -408,7 +408,7 @@ SELECT XMLQUERY('$a is $b' PASSING BY VALUE x AS a, < DOCUMENTCONTENT形式的值。 一个 XQuery/XPath 表达式的上下文项必须是单个 XML 节点或原子值, 但 XPath 1.0 又进一步限制它只能是 XML 节点,并且没有允许CONTENT的节点类型。 - 归根结底,格式良好的DOCUMENT是 + 归根结底,良构的DOCUMENTPostgreSQL能够作为 XPath 上下文项提供的唯一 XML 值形式。 diff --git a/zh/17/func.sgml b/zh/17/func.sgml index 38c1b02f..2ba7f97d 100644 --- a/zh/17/func.sgml +++ b/zh/17/func.sgml @@ -39,20 +39,17 @@ repeat('Pg', 4) PgPgPgPg 逻辑操作符 - operator - logical + 操作符 + 逻辑 - Boolean - operators - operators, logical + 布尔 + 操作符 + 操作符,逻辑 - - 常用的逻辑操作符有: - - + 可以使用以下常见逻辑操作符: AND(操作符) @@ -65,15 +62,15 @@ repeat('Pg', 4) PgPgPgPg - conjunction + 合取 - disjunction + 析取 - negation + 否定 @@ -82,9 +79,7 @@ repeat('Pg', 4) PgPgPgPg NOT boolean boolean - SQL使用三值的逻辑系统,包括真、假和nullnull表示未知。观察下面的真值表: - - + SQL使用由真、假和null构成的三值逻辑系统,其中null表示未知。请看下面的真值表: @@ -181,8 +176,8 @@ repeat('Pg', 4) PgPgPgPg 比较函数和操作符 - comparison - operators + 比较 + 操作符 @@ -265,14 +260,14 @@ repeat('Pg', 4) PgPgPgPg - <> 表示 not equal 的标准的SQL符号。 - != 是一个别名, 在解析的早期阶段被转换为 <> 。 - 因此, 它不可能实现 !=<> 操作符以做不同的事情。 + <>不等于 的标准 SQL 符号。 + != 是一个别名,在解析的早期阶段就会被转换为 <>。 + 因此,不可能让 !=<> 操作符执行不同的操作。 - 这些比较操作符适用于所有具有自然排序的内置数据类型,包括数字、字符串和日期/时间类型。 + 这些比较操作符适用于所有具有自然排序的内置数据类型,包括数值、字符串和日期/时间类型。 此外,如果其组成数据类型具有可比性,则也可以比较数组、复合类型和范围。 @@ -318,7 +313,7 @@ repeat('Pg', 4) PgPgPgPg boolean - 之间(包括范围端点)。 + 位于两者之间(包括范围端点)。 2 BETWEEN 1 AND 3 @@ -378,7 +373,7 @@ repeat('Pg', 4) PgPgPgPg boolean - 不相等,将空值(NULL)视为可比值。 + 不相等,将 NULL 视为可比值。 1 IS DISTINCT FROM NULL @@ -396,7 +391,7 @@ repeat('Pg', 4) PgPgPgPg boolean - 相等,将空值(NULL)视为可比值。 + 相等,将 NULL 视为可比值。 1 IS NOT DISTINCT FROM NULL @@ -414,7 +409,7 @@ repeat('Pg', 4) PgPgPgPg boolean - 测试值是否为空。 + 测试值是否为 null。 1.5 IS NULL @@ -428,7 +423,7 @@ repeat('Pg', 4) PgPgPgPg boolean - 测试值是否不为空。 + 测试值是否不为 null。 'null' IS NOT NULL @@ -442,7 +437,7 @@ repeat('Pg', 4) PgPgPgPg boolean - 测试值是否为空(非标准语法)。 + 测试值是否为 null(非标准语法)。 @@ -452,7 +447,7 @@ repeat('Pg', 4) PgPgPgPgboolean - 测试值是否不为空(非标准语法)。 + 测试值是否不为 null(非标准语法)。 @@ -573,30 +568,22 @@ repeat('Pg', 4) PgPgPgPg BETWEEN SYMMETRIC - - BETWEEN谓词可以简化范围测试: - + BETWEEN谓词可以简化范围测试: a BETWEEN x AND y - - 等效于 - +等价于 a >= x AND a <= y - - 注意BETWEEN认为终点值是包含在范围内的。 - BETWEEN SYMMETRIC 就像BETWEEN,除了没有要求AND的左边的参数小于或等于右边的参数。 - 如果不是的话,这两个参数将自动交换,因此总是隐含一个非空范围。 - +注意,BETWEEN将两个端点值都视为包含在范围内。BETWEEN SYMMETRIC类似于BETWEEN,但不要求AND左侧的参数小于或等于右侧的参数。如果不是这样,这两个参数会自动交换,以确保表示的范围始终非空。 - BETWEEN的各种变量都是以普通比较操作符的方式实现的,因此适用于任何可以比较的数据类型。 + BETWEEN的各种变体都是以普通比较操作符的方式实现的,因此适用于任何可以比较的数据类型。 - 在BETWEEN语法中使用AND会与使用AND作为逻辑操作符产生歧义。 - 为了解决这个问题,只允许有限的一组表达类型作为BETWEEN子句的第二个参数。 - 如果您需要在BETWEEN中写一个更复杂的子表达式,在子表达式两边写上圆括号。 + 在BETWEEN语法中使用AND,会与将AND用作逻辑操作符产生歧义。 + 为了解决这个问题,只允许有限的一组表达式类型作为BETWEEN子句的第二个参数。 + 如果你需要在BETWEEN中写一个更复杂的子表达式,请在该子表达式两边加上圆括号。 @@ -607,12 +594,12 @@ repeat('Pg', 4) PgPgPgPg IS NOT DISTINCT FROM - 当有一个输入为空时,普通的比较操作符会得到空(表示未知),而不是真或假。例如,7 = NULL得到空,7 <> NULL也一样。如果这种行为不合适,可以使用IS NOT DISTINCT FROM谓词: + 当任一输入为 null 时,普通的比较操作符会得到 null(表示未知),而不是真或假。例如,7 = NULL得到 null,7 <> NULL也一样。如果这种行为不合适,可以使用IS NOT DISTINCT FROM谓词: a IS DISTINCT FROM b a IS NOT DISTINCT FROM b - 对于非空输入,IS DISTINCT FROM<>操作符一样。不过,如果两个输入都为空,它会返回假。而如果只有一个输入为空,它会返回真。类似地,IS NOT DISTINCT FROM对于非空输入的行为与=相同,但是当两个输入都为空时它返回真,并且当只有一个输入为空时返回假。因此,这些谓词实际上把空值当作一种普通数据值,而不是未知。 + 对于非 null 输入,IS DISTINCT FROM<>操作符一样。不过,如果两个输入都为 null,它会返回假。而如果只有一个输入为 null,它会返回真。类似地,IS NOT DISTINCT FROM对于非 null 输入的行为与=相同,但是当两个输入都为 null 时它返回真,并且当只有一个输入为 null 时返回假。因此,这些谓词实际上把 null 当作一种普通数据值,而不是未知 @@ -628,17 +615,17 @@ repeat('Pg', 4) PgPgPgPg NOTNULL - 要检查一个值是否为空,使用下面的谓词: + 要检查一个值是否为 null,使用下面的谓词: expression IS NULL expression IS NOT NULL - 或者等效,但并不标准的谓词: + 或者等效但非标准的谓词: expression ISNULL expression NOTNULL - null valuecomparing + 空值比较 @@ -658,11 +645,11 @@ repeat('Pg', 4) PgPgPgPg SELECT ROW(1,2.5,'this is a test') = ROW(1, 3, 'not the same'); -SELECT ROW(table.*) IS NULL FROM table; -- detect all-null rows +SELECT ROW(table.*) IS NULL FROM table; -- 检测所有字段均为 null 的行 -SELECT ROW(table.*) IS NOT NULL FROM table; -- detect all-non-null rows +SELECT ROW(table.*) IS NOT NULL FROM table; -- 检测所有字段均非 null 的行 -SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in rows +SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- 检测至少有一个 null 字段的行 在某些情况下,写成row IS DISTINCT FROM NULL或者row IS NOT DISTINCT FROM NULL可能更合适,因为它们只会检查整个行值是否为 NULL,而不会再对行字段做额外测试。 @@ -696,7 +683,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in boolean_expression IS UNKNOWN boolean_expression IS NOT UNKNOWN - 这些谓词总是返回真或假,从不返回空值,即使操作数为空也是如此。空值输入被当作逻辑值未知。请注意,IS UNKNOWNIS NOT UNKNOWN实际上分别等同于IS NULLIS NOT NULL,只是输入表达式必须是布尔类型。 + 这些谓词总是返回真或假,从不返回空值,即使操作数为 null 也是如此。null 输入被当作逻辑值未知。请注意,IS UNKNOWNIS NOT UNKNOWN实际上分别等同于IS NULLIS NOT NULL,只是输入表达式必须是布尔类型。 @@ -733,7 +720,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in integer - 返回非空参数的数量。 + 返回非 null 参数的数量。 num_nonnulls(1, NULL, 2) @@ -750,7 +737,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in integer - 返回空参数的数量。 + 返回 null 参数的数量。 num_nulls(1, NULL, 2) @@ -768,12 +755,12 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in 数学函数和操作符 - PostgreSQL为很多类型提供了数学操作符。对于那些没有标准数学表达的类型(如日期/时间类型),我们将在后续小节中描述实际的行为。 + PostgreSQL为很多类型提供了数学操作符。对于那些没有标准数学惯例的类型(如日期/时间类型),我们将在后续小节中描述实际的行为。 - 显示了可用于标准数字类型的数学操作符。 - 除非另有说明, 显示为可接受 numeric_type 的操作符对所有的 smallintintegerbigintnumericrealdouble precision类型都可用。 + 显示了可用于标准数值类型的数学操作符。 + 除非另有说明, 显示为可接受 numeric_type 的操作符对所有的 smallintintegerbigintnumericrealdouble precision类型都可用。 显示为可接受 integral_type 的操作符对 smallintintegerbigint类型是可用的。 除了特别说明之处,操作符的每种形式都返回与其参数相同的数据类型。 涉及多个参数数据类型的调用, 例如 integer + numeric,可通过使用这些列表中稍后出现的类型来解析。 @@ -821,7 +808,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in numeric_type - 一元加(无操作) + 一元正号(不执行操作) + 3.5 @@ -849,7 +836,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in numeric_type - 否定 + 取负 - (-4) @@ -877,7 +864,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in numeric_type - 除(对于整型,除法将结果截断为零) + 除法(对于整数类型,除法将结果向零截断) 5.0 / 2 @@ -917,14 +904,14 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in double precision - 指数 + 求幂 2 ^ 3 8 - 不像典型的数学实践,多次使用 ^ 将会默认从左到右关联: + 与通常的数学惯例不同,多次使用^时默认从左到右结合: 2 ^ 3 ^ 3 @@ -984,7 +971,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in integral_type - 按位与(AND) + 按位与 91 & 15 @@ -998,7 +985,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in integral_type - 按位或(OR) + 按位或 32 | 3 @@ -1012,7 +999,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in integral_type - 按位异或(exclusive OR) + 按位异或 17 # 5 @@ -1026,7 +1013,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in integral_type - 按位求反(NOT) + 按位非 ~1 @@ -1069,9 +1056,9 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in 显示了可用的数学函数。 许多这样的函数以多种具有不同的参数类型的形式提供。 - 除非注明,任何给定形式的函数都返回与其参数相同的数据类型;跨类型情况的解决方法与上述对操作符的解释相同。 - 使用double precision数据的函数大多是在主机系统的C库上实现的; - 因此,边界情况下的准确性和行为会因主机系统的区别而不同。 + 除非注明,任何给定形式的函数都返回与其参数相同的数据类型;跨类型情况的解决方法与上述对操作符的解释相同。 + 使用double precision数据的函数大多是在主机系统的C库上实现的; + 因此,精度和边界情况下的行为可能因主机系统而异。
@@ -1202,7 +1189,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in numeric - y/x 的整数商(截断为零位) + y/x 的整数商(向零截断) div(9, 4) @@ -1210,27 +1197,6 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in - - - - exp - - exp ( numeric ) - numeric - - - exp ( double precision ) - double precision - - - 指数 (e 的给定次方) - - - exp(1.0) - 2.7182818284590452 - - - @@ -1265,6 +1231,27 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in + + + + exp + + exp ( numeric ) + numeric + + + exp ( double precision ) + double precision + + + 指数函数(e的给定次幂) + + + exp(1.0) + 2.7182818284590452 + + + @@ -1426,7 +1413,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in integer - 精确表示所提供值所需的最小刻度(小数位数) + 精确表示给定值所需的最少小数位数 min_scale(8.4100) @@ -1523,7 +1510,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in double precision - 四舍五入到最近的整数。 + 舍入到最接近的整数。 对于numeric,遇到恰好位于中点的情况时按远离零的方向舍入。 对于double precision,中点取舍规则取决于平台,但舍入到最接近的偶数是最常见的规则。 @@ -1560,7 +1547,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in integer - 参数的刻度(小数点后的位数) + 参数的小数位数(小数部分的十进制位数) scale(8.4100) @@ -1619,7 +1606,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in numeric - 通过删除尾数部分的零来降低值的刻度(小数位数) + 通过移除尾随零来减少值的小数位数 trim_scale(8.4100) @@ -1640,7 +1627,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in double precision - 截断整数 (向零靠近) + 向零截断为整数 trunc(42.8) @@ -1658,7 +1645,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in numeric - 截断 vs 位小数位置的数字 + 将v截断到s位小数 trunc(42.4382, 2) @@ -1751,6 +1738,55 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in + + + + random + + random ( min integer, max integer ) + integer + + + random ( min bigint, max bigint ) + bigint + + + random ( min numeric, max numeric ) + numeric + + + 返回范围min <= x <= max内的随机值。对于numeric类型,结果的小数位数与minmax中小数位数较多者相同。 + + + random(1, 10) + 7 + + + random(-0.499, 0.499) + 0.347 + + + + + + + random_normal + + + random_normal ( + mean double precision + , stddev double precision ) + double precision + + + 从具有给定参数的正态分布中返回一个随机值;mean默认为 0.0,stddev默认为 1.0。 + + + random_normal(0.0, 1.0) + 0.051285419 + + + @@ -1760,7 +1796,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in void - 为后续的random()调用设置种子;参数必须在-1.0和1.0之间,包括边界值 + 为后续的random()random_normal()调用设置种子;参数必须在-1.0和1.0之间,包括边界值 setseed(0.12345) @@ -1771,10 +1807,10 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in
- random()函数使用确定性伪随机数生成器。 + 在中列出的random()random_normal()函数使用确定性伪随机数生成器。 它速度快,但不适用于加密应用;请参阅模块以获取更安全的替代方案。 - 如果调用setseed(),则当前会话中后续random()调用的结果序列可以通过使用相同参数重新发出setseed()来重复。 - 在同一会话中没有任何先前的setseed()调用时,第一个random()调用从平台相关的随机位源获取种子。 + 如果调用setseed(),则当前会话中后续对这些函数的调用结果序列可以通过使用相同参数重新发出setseed()来重复。 + 在同一会话中没有任何先前的setseed()调用时,首次调用这些函数中的任何一个都会从平台相关的随机位源获取种子。 @@ -2084,7 +2120,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in - 另一种使用以角度度量的角的方法是使用早前展示的单位转换函数radians()degrees()。不过,使用基于角度的三角函数更好,因为这类方法能避免sind(30)等特殊情况下的舍入偏差。 + 另一种使用以角度度量的角的方法是使用早前展示的单位转换函数radians()degrees()。不过,使用基于角度的三角函数更好,因为这类方法能避免sind(30)等特殊情况下的舍入误差。 @@ -2157,7 +2193,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in double precision - 双曲切线 + 双曲正切 tanh(1) @@ -2208,7 +2244,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in double precision - 反双曲切线 + 反双曲正切 atanh(0.5) @@ -2230,7 +2266,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in 这里的字符串包括charactercharacter varyingtext类型的值。 除非另有说明,这些函数和操作符都声明为接受并返回text类型。 它们也可互换地接受character varying参数。 - 在应用函数或操作符之前,character类型的值会先转换为text,因此会去除其尾随空格。 + 在应用函数或操作符之前,character类型的值会先转换为text,因此会去除 character 值的尾随空格。 @@ -2241,7 +2277,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in 字符串串接操作符(||)将接受非字符串输入,只要至少一个输入是一种字符串类型,如所示。 - 对于其他情况,向text插入一个显式强制,可用于接受非字符串输入。 + 对于其他情况,可以添加到text的显式强制转换,以接受非字符串输入。 @@ -2269,14 +2305,14 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in - character string - concatenation + 字符串 + 串接 text || text text - 连接两个字符串。 + 串接两个字符串。 'Post' || 'greSQL' @@ -2294,8 +2330,8 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 将非字符串输入转换为文本,然后将两个字符串串联在一起。 - (非字符串输入不能为数组类型,因为这将在||操作符的数组中造成歧义。如果你想连接一个数组的文本相等的,请显式地将其转换为text 。) + 将非字符串输入转换为文本,然后将两个字符串串接起来。 + (非字符串输入不能是数组类型,因为那样会与数组的||操作符产生歧义。如果要串接数组的文本表示,请显式地将其转换为text。) 'Value: ' || 42 @@ -2306,17 +2342,35 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in - normalized + btrim + + btrim ( string text + , characters text ) + text + + + 从string的开头和结尾移除仅由characters中字符(默认为空格)组成的最长字符串。 + + + btrim('xyxtrimyyx', 'xyz') + trim + + + + + + + 规范化 - Unicode normalization + Unicode 规范化 - text IS [NOT ] [form ] NORMALIZED + text IS NOT form NORMALIZED boolean - 检查字符串是否在指定的 Unicode 规范化表单中。 - 可选的form关键词指定表单:NFC (默认的), NFD, NFKC, 或 NFKD。 + 检查字符串是否处于指定的 Unicode 规范化形式中。 + 可选的form关键字指定形式:NFC(默认)、NFDNFKCNFKD。 只有在服务器编码为UTF8时,才能使用此表达式。 请注意,使用这个表达式检查规范化通常比规范化可能已经规范化的字符串要快。 @@ -2349,13 +2403,13 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in char_length - character string - length + 字符串 + 长度 - length + 长度 字符串 - character string, length + 字符串,长度 char_length ( text ) integer @@ -2385,7 +2439,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 根据数据库的语言环境规则,将字符串转换为全部小写。 + 根据数据库的区域设置规则,将字符串转换为全部小写。 lower('TOM') @@ -2393,22 +2447,57 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in + + + + lpad + + lpad ( string text, + length integer + , fill text ) + text + + + 在string前面添加字符fill(默认为空格),将其填充到长度length。如果string已经长于length,则从右侧截断。 + + + lpad('hi', 5, 'xy') + xyxhi + + + + + + + ltrim + + ltrim ( string text + , characters text ) + text + + + 从string的开头移除仅由characters中字符(默认为空格)组成的最长字符串。 + + + ltrim('zzzytest', 'xyz') + test + + + normalize - Unicode normalization + Unicode 规范化 normalize ( text - [, form ] ) + , form ) text - 将字符串转换为指定的 Unicode 规范化形式。 - 可选的form关键字指定如下形式:NFC(默认值)、NFDNFKCNFKD。 - 该函数只能在服务器编码为UTF8时使用。 + 将字符串转换为指定的 Unicode 规范化形式。可选的 form 关键字指定如下形式:NFC(默认值)、NFDNFKCNFKD。该函数只能在服务器编码为 UTF8 时使用。 normalize(U&'\0061\0308bc', NFC) @@ -2455,12 +2544,11 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in overlay - overlay ( string text PLACING newsubstring text FROM start integer [ FOR count integer ] ) + overlay ( string text PLACING newsubstring text FROM start integer FOR count integer ) text - 替换stringstart字符开始的子串,并用newsubstring扩展到count字符。 - 如果省略了count,则默认为newsubstring的长度。 + 用newsubstring替换string中从第start个字符开始、长度为count个字符的子字符串。如果省略count,则默认为newsubstring的长度。 overlay('Txxxxas' placing 'hom' from 2 for 4) @@ -2477,7 +2565,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in integer - 返回string中指定的substring第一次出现的起始位置;如果不存在则返回零。 + 返回substringstring中首次出现的位置;如果不存在则返回零。 position('om' in 'Thomas') @@ -2485,18 +2573,53 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in + + + + rpad + + rpad ( string text, + length integer + , fill text ) + text + + + 在string后面追加字符fill(默认为空格),将其填充到长度length。如果string已经长于length,则截断它。 + + + rpad('hi', 5, 'xy') + hixyx + + + + + + + rtrim + + rtrim ( string text + , characters text ) + text + + + 从string的结尾移除仅由characters中字符(默认为空格)组成的最长字符串。 + + + rtrim('testxxzx', 'xyz') + test + + + substring - substring ( string text [ FROM start integer ] [ FOR count integer ] ) + substring ( string text FROM start integer FOR count integer ) text - 如果已指定,提取stringstart字符开始的子串, - 并且在count字符后停止。如果已指定的话。 - 提供至少一个startcount中的至少一个。 + 提取string的子字符串:若指定了起始位置,则从第start个字符开始;若指定了长度,则在提取count个字符后停止。startcount至少需要指定一个。 substring('Thomas' from 2 for 3) @@ -2518,7 +2641,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 提取匹配POSIX正则表达式的第一个子字符串; 参见 。 + 提取匹配 POSIX 正则表达式的第一个子字符串;参见 substring('Thomas' from '...$') @@ -2536,8 +2659,8 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 提取匹配 SQL 正则表达式的第一个字串;参见 。 - 第一种形式自从SQL:2003被指定,第二种形式仅在SQL:1999中,并应认为是废弃的。 + 提取匹配 SQL 正则表达式的第一个子字符串;参见 。 + 第一种形式自 SQL:2003 起由标准规定;第二种形式只出现在 SQL:1999 中,应视为已过时。 substring('Thomas' similar '%#"o_a#"_' escape '#') @@ -2580,6 +2703,19 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in + + + + unicode_assigned + + unicode_assigned ( text ) + boolean + + + 如果字符串中的所有字符都是已分配的 Unicode 码点,则返回true;否则返回false。此函数只能在服务器编码为UTF8时使用。 + + + @@ -2589,7 +2725,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 根据数据库的定位规则,将字符串转换为所有大写。 + 根据数据库的区域设置规则,将字符串转换为全部大写。 upper('tom') @@ -2656,7 +2792,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in integer - 返回参数的第一个字符的数字代码。在UTF8编码中,返回该字符的Unicode代码点。 + 返回参数的第一个字符的数字代码。在UTF8编码中,返回该字符的Unicode 码点。 在其他多字节编码中,该参数必须是一个ASCII字符。 @@ -2665,23 +2801,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in - - - - btrim - - btrim ( string text - , characters text ) - text - - - 从string的开头或结尾删除最长的只包含characters(默认是一个空格)的字符串 - - - btrim('xyxtrimyyx', 'xyz') - trim - - + @@ -2692,7 +2812,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 返回给定代码的字符。在UTF8编码中该参数被视作一个Unicode代码点。 + 返回给定代码的字符。在UTF8编码中该参数被视作一个Unicode 码点。 在其他多字节编码中该参数必须指定一个ASCII字符。 chr(0) 字符不被允许,因为文本数据类型不能存储这种字符。 @@ -2712,7 +2832,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 连接所有参数的文本表示。空参数被忽略。 + 串接所有参数的文本表示。NULL 参数被忽略。 concat('abcde', 2, NULL, 22) @@ -2731,7 +2851,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 用分隔符连接除第一个参数外的所有参数。第一个参数用作分隔符字符串,不应为NULL。其他NULL参数将被忽略。 + 用分隔符串接除第一个参数外的所有参数。第一个参数用作分隔符字符串,不应为NULL。其他NULL参数将被忽略。 concat_ws(',', 'abcde', 2, NULL, 22) @@ -2785,7 +2905,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 以字符串返回第一个 n 字符,或在 n 为负时, 返回最后 |n| 个字符之外的全部字符。 + 返回字符串最左侧的 n 个字符;如果 n 为负,则返回除最后 |n| 个字符之外的全部字符。 left('abcde', 2) @@ -2810,43 +2930,9 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in - - - - lpad - - lpad ( string text, - length integer - [, fill text ] ) - text - - - 将string扩展为长度length,通过前置字符fill(默认空格)。 - 如果string已经超过length那么它将被截断(在右侧)。 - - - lpad('hi', 5, 'xy') - xyxhi - - - - - - ltrim - - ltrim ( string text - , characters text ) - text - - - 从string开始删除包含characters(默认空格)中仅包含字符的最长字符串。 - - - ltrim('zzzytest', 'xyz') - test - - + + @@ -2875,10 +2961,10 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text[] - 将qualified_identifier拆分为一个标识符数组,删除单个标识符的任何引用。 + 将qualified_identifier拆分为一个标识符数组,去除各个标识符的引号。 默认情况下,最后一个标识符之后的额外字符被视为错误;但是,如果第二个参数为false,则忽略这些额外的字符。 (这种行为对于解析类似函数的对象的名称有作用。) - 请注意,此函数不会截断超长标识符。如果你想截断,你可以把结果给到name[]。 + 请注意,此函数不会截断超长标识符。如果你想截断,你可以将结果转换为name[] parse_ident('"SomeSchema".someTable') @@ -2912,9 +2998,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 返回适合引用的给定字符串,作为SQL语句字符串中的标识符。 - 只有在必要的情况下才添加引号(例如,如果字符串包含非标识符字符或将被大小写折叠)。 - 嵌入的引号被适当地加双引号。参见。 + 为给定字符串添加适当的引号并返回,使其可用作SQL语句字符串中的标识符。仅在必要时(即字符串包含不能用于标识符的字符,或会发生大小写折叠时)添加引号。内嵌的引号会被适当地双写。另见 quote_ident('Foo bar') @@ -2931,9 +3015,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 返回在SQL语句字符串中适当引用的给定字符串,作为字符串字面量使用。 - 内嵌的单引号和反斜杠会被适当地重复书写。 - 请注意,quote_literal在参数为 NULL 时返回 NULL;如果该参数可能为空,quote_nullable通常更合适。另请参阅。 + 为给定字符串添加适当的引号并返回,使其可用作SQL语句字符串中的字符串字面量。内嵌的单引号和反斜杠会被适当地双写。注意,quote_literal在输入为NULL时返回NULL;如果参数可能为 null,quote_nullable通常更合适。另见 quote_literal(E'O\'Reilly') @@ -2947,8 +3029,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 将给定的值转换为文本,然后将其作为字面量引用。 - 内嵌的单引号和反斜杠会被适当地加倍。 + 将给定值转换为文本,然后作为字面量加引号。内嵌的单引号和反斜杠会被适当地双写。 quote_literal(42.5) @@ -2965,8 +3046,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 返回在SQL语句字符串中适当引用的给定字符串字面量;如果参数为NULL,则返回NULL。 - 内嵌的单引号和反斜杠会被适当地重复书写。参见。 + 为给定字符串添加适当的引号并返回,使其可用作SQL语句字符串中的字符串字面量;如果参数为NULL,则返回NULL。内嵌的单引号和反斜杠会被适当地双写。另见 quote_nullable(NULL) @@ -2980,8 +3060,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 将给定值转换为文本,然后将其作为字面量引用;如果参数为NULL,则返回NULL。 - 内嵌的单引号和反斜杠会被适当地重复书写。 + 将给定值转换为文本,然后作为字面量加引号;如果参数为NULL,则返回NULL。内嵌的单引号和反斜杠会被适当地双写。 quote_nullable(42.5) @@ -3022,7 +3101,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in integer - 返回string中第N个匹配项的POSIX正则表达式pattern出现的位置,如果没有这样的匹配项,则返回零;参见。 + 返回 POSIX 正则表达式patternstring中第N次匹配的位置;如果没有这样的匹配,则返回零。参见 regexp_instr('ABCDEF', 'c(.)(..)', 1, 1, 0, 'i') @@ -3061,7 +3140,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text[] - 返回第一个匹配的POSIX正则表达式patternstring中的子字符串;参见。 + 返回 POSIX 正则表达式patternstring的第一次匹配中的子字符串;参见 regexp_match('foobarbequebaz', '(bar)(beque)') @@ -3078,8 +3157,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in setof text[] - 返回第一个匹配的 POSIX 正则表达式patternstring中的子字符串,或者如果使用了g标志,则返回所有匹配的子字符串; - 参见。 + 返回 POSIX 正则表达式patternstring的第一次匹配中的子字符串;如果使用g标志,则返回所有匹配中的子字符串。参见 regexp_matches('foobarbequebaz', 'ba.', 'g') @@ -3119,7 +3197,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 替换字符串中第N个与 POSIX 正则表达式pattern匹配的子字符串,如果N为零,则替换所有匹配项;参见。 + 替换第N个与 POSIX 正则表达式pattern匹配的子字符串;如果N为零,则替换所有这样的匹配。参见 regexp_replace('Thomas', '.', 'X', 3, 2) @@ -3178,8 +3256,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 返回string中与第N个出现的POSIX正则表达式pattern匹配的子字符串, - 如果没有这样的匹配,则返回NULL;参见。 + 返回string中 POSIX 正则表达式pattern的第N次匹配对应的子字符串;如果没有这样的匹配,则返回NULL。参见 regexp_substr('ABCDEF', 'c(.)(..)', 1, 1, 'i') @@ -3219,7 +3296,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 将string 中当前的子串from替换为子串to。 + 将string中所有出现的子字符串from替换为子字符串to replace('abcdefabcdef', 'cd', 'XX') @@ -3254,7 +3331,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 返回字符串中的最后n个字符,或者在n>为负时,返回除了前面的|n|字符之外的所有字符。 + 返回字符串中的最后n个字符;如果n为负数,则返回除前 |n| 个字符之外的全部字符。 right('abcde', 2) @@ -3262,71 +3339,37 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in + + + + - rpad + split_part - rpad ( string text, - length integer - [, fill text ] ) + split_part ( string text, + delimiter text, + n integer ) text - 扩展 string 到长度 length,通过追加fill 字符(默认为空格). - 如果string 已经比 length 长,则截断它。 + 在出现delimiter时拆分string,并返回第n个字段(从一开始计数);如果n为负数,则返回倒数第 |n| 个字段。 - rpad('hi', 5, 'xy') - hixyx + split_part('abc~@~def~@~ghi', '~@~', 2) + def + + + split_part('abc,def,ghi,jkl', ',', -2) + ghi - rtrim - - rtrim ( string text - , characters text ) - text - - - 从string末尾删除包含characters(默认为空格)中仅包含字符的最长字符串。 - - - rtrim('testxxzx', 'xyz') - test - - - - - - - split_part - - split_part ( string text, - delimiter text, - n integer ) - text - - - 在出现delimiter时拆分string,并返回第n个字段(从一开始计数);如果n为负数,则返回倒数第 |n| 个字段。 - - - split_part('abc~@~def~@~ghi', '~@~', 2) - def - - - split_part('abc,def,ghi,jkl', ',', -2) - ghi - - - - - - - starts_with + starts_with starts_with ( string text, prefix text ) boolean @@ -3345,7 +3388,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in string_to_array - string_to_array ( string text, delimiter text [, null_string text ] ) + string_to_array ( string text, delimiter text , null_string text ) text[] @@ -3366,7 +3409,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in string_to_table - string_to_table ( string text, delimiter text [, null_string text ] ) + string_to_table ( string text, delimiter text , null_string text ) setof text @@ -3395,8 +3438,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in integer - 返回string中指定的substring第一次出现的起始位置;如果不存在则返回零。 - (与(substringstring中的位置)相同,但请注意参数顺序是反过来的。) + 返回substringstring中首次出现的位置;如果不存在则返回零。(与position(substring in string)相同,但请注意参数顺序相反。) strpos('high', 'ig') @@ -3409,12 +3451,11 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in substr - substr ( string text, start integer [, count integer ] ) + substr ( string text, start integer , count integer ) text - 提取stringstart字符开始的子字符串,并扩展count字符,如果指定了的话。 - (与 子字符串(stringstart 开始计数 count)相同。) + 提取string中从第start个字符开始的子字符串;若指定了长度,则提取count个字符。(与substring(string from start for count)相同。) substr('alphabet', 3) @@ -3445,10 +3486,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 将string从另一个编码中转换为ASCII,该编码可按名称或编号标识。 - 如果encoding被省略,则假定数据库编码(这在实践中是唯一有用的案例)。转换主要包括降音。 - 转换仅支持来自 LATIN1LATIN2LATIN9、 和 WIN1250 的编码. - (其他请参见 模块, 更灵活的解决方案。) + 将string从其他编码转换为ASCII,源编码可以用名称或编号指定。如果省略encoding,则使用数据库编码(实际上,这也是唯一有用的情况)。转换主要是去除重音符号。只支持从LATIN1LATIN2LATIN9WIN1250编码转换。(另一种更灵活的解决方案参见模块。) to_ascii('Karél') @@ -3456,6 +3494,31 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in + + + + to_bin + + to_bin ( integer ) + text + + + to_bin ( bigint ) + text + + + 将数字转换为等价的二进制补码表示。 + + + to_bin(2147483647) + 1111111111111111111111111111111 + + + to_bin(-1234) + 11111111111111111111101100101110 + + + @@ -3469,11 +3532,40 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 将数字转换为其相应的十六进制表示形式。 + 将数字转换为等价的十六进制补码表示。 to_hex(2147483647) 7fffffff + + + to_hex(-1234) + fffffb2e + + + + + + + to_oct + + to_oct ( integer ) + text + + + to_oct ( bigint ) + text + + + 将数字转换为等价的八进制补码表示。 + + + to_oct(2147483647) + 17777777777 + + + to_oct(-1234) + 37777775456 @@ -3489,7 +3581,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in string中与from集合中匹配的每个字符替换为to集合中相应的字符。 - 如果from长于tofrom中出现的额外字符被删除。 + 如果from长于to,输入中出现的from中的额外字符会被删除。 translate('12345', '143', 'ax') @@ -3506,18 +3598,18 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 计算参数中的转义Unicode字符。 + 解析参数中转义的 Unicode 字符。 Unicode字符可以被指定为\XXXX (4个十六进制数字),\+XXXXXX(6个十六进制数字),\uXXXX(4个十六进制数字),或\UXXXXXXXX (8个十六进制数字)。 要指定反斜杠,请写入两个反斜杠。 - 所有其他字符都是按字面意义的。 + 所有其他字符均按字面解释。 - 如果服务器编码不是UTF-8,由这些转义序列之一标识的Unicode编码点将被转换为实际的服务器编码;如果不可能,则会报告错误。 + 如果服务器编码不是 UTF-8,由这些转义序列之一标识的 Unicode 码点将被转换为实际的服务器编码;如果无法转换,则会报告错误。 - 这个函数提供了一个(非标准的)替代到Unicode转义的字符串常量(参见)。 + 此函数提供了带 Unicode 转义的字符串常量的另一种(非标准)写法(参见)。 @@ -3535,12 +3627,12 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in - concatconcat_wsformat函数是可变的,因此可以把要串接或格式化的值作为一个标记了VARIADIC关键字的数组进行传递(见)。 - 数组的元素被当作函数的独立普通参数一样处理。如果可变数组参数为 NULL,concatconcat_ws返回 NULL,但format把 NULL 当作一个零元素数组。 + concatconcat_wsformat是可变参数函数,因此可以把要串接或格式化的值作为一个标记了VARIADIC关键字的数组进行传递(见)。 + 数组的元素被当作函数的独立普通参数一样处理。如果可变参数数组为 NULL,concatconcat_ws返回 NULL,但format把 NULL 当作一个零元素数组。 - 还可以参阅中的string_agg,以及中的字符串和bytea类型之间转换的功能。 + 还可以参阅中的聚合函数string_agg,以及中的字符串和bytea类型之间转换的函数。 @@ -3558,22 +3650,22 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in format(formatstr text [, formatarg "any" [, ...] ]) - formatstr是一个格式字符串,它指定了结果应该如何被格式化。格式字符串中的文本被直接复制到结果中,除了使用格式说明符的地方。格式说明符在字符串中扮演着占位符的角色,它定义后续的函数参数如何被格式化及插入到结果中。每一个formatarg参数会被根据其数据类型的常规输出规则转换为文本,并接着根据格式说明符被格式化和插入到结果字符串中。 + formatstr是指定结果格式的字符串。格式字符串中的文本会直接复制到结果中,但格式说明符所在的位置除外。格式说明符充当字符串中的占位符,定义如何格式化后续函数参数并将其插入结果。每个formatarg参数都按照其数据类型通常的输出规则转换为文本,再根据格式说明符进行格式化并插入结果字符串。 - 格式说明符由一个%字符开始并且有这样的形式 + 格式说明符以%字符开头,格式如下: %[position][flags][width]type - 其中的各组件域是: + 其中各组成字段为: position(可选) - 一个形式为n$的字符串,其中n是要打印的参数的索引。索引 1 表示formatstr之后的第一个参数。如果position被忽略,默认会使用序列中的下一个参数。 + 一个形式为n$的字符串,其中n是要打印的参数的索引。索引 1 表示formatstr之后的第一个参数。如果position被省略,默认会使用序列中的下一个参数。 @@ -3581,9 +3673,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in flags(可选) - - 控制格式说明符的输出如何被格式化的附加选项。当前唯一支持的标志是一个负号(-),它将导致格式说明符的输出会被左对齐(left-justified)。除非width域也被指定,否者这个域不会产生任何效果。 - + 用于控制格式说明符输出格式的附加选项。目前唯一支持的标志是减号(-),它使格式说明符的输出左对齐。只有同时指定了width字段时,它才有效。 @@ -3595,8 +3685,8 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in - 如果宽度来自于一个函数参数,则参数在被格式说明符的值使用之前就被消耗掉了。如果宽度参数是负值,结果会在长度为abs(width)的域中被左对齐(如果-标志被指定)。 - + 如果宽度来自一个函数参数,会先使用该宽度参数,再使用作为格式说明符值的参数。如果宽度参数为负数,结果会在长度为abs(width)的字段中左对齐(如同指定了-标志)。 +
@@ -3613,12 +3703,12 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in - I将参数值视作 SQL 标识符,并在必要时用双写引号包围它。如果参数为空,将会是一个错误(等效于quote_ident)。 + I将参数值视作 SQL 标识符,并在必要时用双引号包围它。如果参数为 null,则会报错(等效于quote_ident)。 - L将参数值引用为 SQL 文字。一个空值将被显示为不带引号的字符串NULL(等效于quote_nullable)。 + L将参数值作为 SQL 字面量加引号。null 值显示为不带引号的字符串NULL(等效于quote_nullable)。 @@ -3629,13 +3719,10 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in - 除了以上所述的格式说明符之外,要输出一个文字形式的%字符,可以使用特殊序列%%。 + 除了以上所述的格式说明符之外,要输出一个字面形式的%字符,可以使用特殊序列%% - - 下面有一些基本的格式转换的示例: - - + 下面是一些基本格式转换的示例: SELECT format('Hello %s', 'World'); 结果:Hello World @@ -3646,14 +3733,11 @@ SELECT format('INSERT INTO %I VALUES(%L)', 'Foo bar', E'O\'Reilly'); 结果:INSERT INTO "Foo bar" VALUES('O''Reilly') SELECT format('INSERT INTO %I VALUES(%L)', 'locations', 'C:\Program Files'); -结果:INSERT INTO locations VALUES(E'C:\\Program Files') +结果:INSERT INTO locations VALUES('C:\Program Files') - - 下面是使用width域和-标志的示例: - - + 下面是使用width字段和-标志的示例: SELECT format('|%10s|', 'foo'); 结果:| foo| @@ -3674,10 +3758,7 @@ SELECT format('|%-*s|', -10, 'foo'); - - 这些示例展示了position域的示例: - - + 这些示例展示了如何使用position字段: SELECT format('Testing %3$s, %2$s, %1$s', 'one', 'two', 'three'); 结果:Testing three, two, one @@ -3689,10 +3770,8 @@ SELECT format('|%1$*2$s|', 'foo', 10, 'bar'); - - 不同于标准的 C 函数sprintfPostgreSQLformat函数允许将带有或者不带有position域的格式说明符被混在同一个格式字符串中。一个不带有position域的格式说明符总是使用最后一个被消耗的参数的下一个参数。另外,format函数不要求所有函数参数都被用在格式字符串中。例如: - - + 不同于标准 C 函数sprintf, + PostgreSQLformat函数允许在同一个格式字符串中,混合使用带有或不带有position字段的格式说明符。不带position字段的格式说明符,总是使用最后一个已使用参数之后的下一个参数。此外,format函数不要求格式字符串使用全部函数参数。例如: SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); 结果:Testing three, two, three @@ -3710,17 +3789,17 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); 二进制串函数和操作符 - binary data - functions + 二进制数据 + 函数 - 本节描述那些检查和操作二进制字符串的函数和操作符,这是类型bytea的值。 + 本节描述用于检查和操作二进制字符串(即bytea类型的值)的函数和操作符。 其中许多函数在用途和语法上都与上一节中描述的文本字符串函数等效。 - SQL定义了一些使用关键字而不是逗号来分割参数的串函数。详情请见PostgreSQL也提供了这些函数使用常规函数调用语法的版本(参阅)。 + SQL定义了一些使用关键字而不是逗号来分隔参数的字符串函数。详情请见PostgreSQL也提供了这些函数使用常规函数调用语法的版本(参阅)。 @@ -3747,14 +3826,14 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); - binary string - concatenation + 二进制串 + 串接 bytea || bytea bytea - 连接两个二进制字符串。 + 串接两个二进制字符串。 '\x123456'::bytea || '\x789a00bcde'::bytea @@ -3779,6 +3858,42 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); + + + + btrim + + btrim ( bytes bytea, + bytesremoved bytea ) + bytea + + + 从bytes的开头和结尾移除仅由bytesremoved中字节组成的最长字符串。 + + + btrim('\x1234567890'::bytea, '\x9012'::bytea) + \x345678 + + + + + + + ltrim + + ltrim ( bytes bytea, + bytesremoved bytea ) + bytea + + + 从bytes的开头移除仅由bytesremoved中字节组成的最长字符串。 + + + ltrim('\x1234567890'::bytea, '\x9012'::bytea) + \x34567890 + + + @@ -3801,12 +3916,11 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); overlay - overlay ( bytes bytea PLACING newsubstring bytea FROM start integer [ FOR count integer ] ) + overlay ( bytes bytea PLACING newsubstring bytea FROM start integer FOR count integer ) bytea - 将bytes的子字符串替换为newsubstring,该子字符串从start字节开始,并以count字节扩展。 - 如果忽略了count,则默认为newsubstring的长度。 + 用newsubstring替换bytes中从第start个字节开始、长度为count个字节的子字符串。如果省略count,则默认为newsubstring的长度。 overlay('\x1234567890'::bytea placing '\002\003'::bytea from 2 for 3) @@ -3823,7 +3937,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); integer - 返回bytes中指定的substring的第一个起始索引,如果不存在,则为零。 + 返回substringbytes中首次出现的位置;如果不存在则返回零。 position('\x5678'::bytea in '\x1234567890'::bytea) @@ -3831,17 +3945,34 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); + + + + rtrim + + rtrim ( bytes bytea, + bytesremoved bytea ) + bytea + + + 从bytes的结尾移除仅由bytesremoved中字节组成的最长字符串。 + + + rtrim('\x1234567890'::bytea, '\x9012'::bytea) + \x12345678 + + + substring - substring ( bytes bytea [ FROM start integer ] [ FOR count integer ] ) + substring ( bytes bytea FROM start integer FOR count integer ) bytea - 提取bytesstart字节开始的子字符串,如果指定了,并且在count字节之后停止,如果指定了的话。 - 至少提供startcount中的一个。 + 提取bytes的子字符串:若指定了起始位置,则从第start个字节开始;若指定了长度,则在提取count个字节后停止。startcount至少需要指定一个。 substring('\x1234567890'::bytea from 3 for 2) @@ -3860,7 +3991,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bytea - 删除bytesremoved中只包含字节的最长字符串,从bytes的开始、结束,或两端(BOTH 为默认的)。 + 从bytes的开头、结尾或两端(默认为BOTH)移除仅由bytesremoved中字节组成的最长字符串。 trim('\x9012'::bytea from '\x1234567890'::bytea) @@ -3876,7 +4007,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bytea - 这是trim()的非标准语法。 + 这是一个非标准的trim()语法。 trim(both from '\x1234567890'::bytea, '\x9012'::bytea) @@ -3888,7 +4019,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three');
- 还有一些二进制串处理函数可以使用,在列出。 其中有一些是在内部使用,用于实现列出的 SQL 标准串函数。 + 还有一些二进制串处理函数可以使用,在列出。 其中有一些是在内部使用,用于实现列出的 SQL 标准串函数。 @@ -3925,7 +4056,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bigint - 返回二进制字符串中设置的位数(也被认为popcount)。 + 返回二进制字符串中被置位的位数(也称为popcount)。 bit_count('\x1234567890'::bytea) @@ -3933,23 +4064,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); - - - - btrim - - btrim ( bytes bytea, - bytesremoved bytea ) - bytea - - - 从bytes的开始和结束处删除只包含bytesremoved中出现的字节的最长字符串 - - - btrim('\x1234567890'::bytea, '\x9012'::bytea) - \x345678 - - + @@ -3961,7 +4076,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); integer - 从二进制字符串中提取 n'th 位。 + 从二进制字符串中提取 编号为 n 的 位。 get_bit('\x1234567890'::bytea, 30) @@ -3979,7 +4094,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); integer - 从二进制字符串中提取 n'th 字节。 + 从二进制字符串中提取 编号为 n 的 字节。 get_byte('\x1234567890'::bytea, 4) @@ -3993,13 +4108,13 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); length - binary string - length + 二进制串 + 长度 - length - 二进制字符串 - binary strings, length + 长度 + 二进制串 + 二进制串,长度 length ( bytea ) integer @@ -4028,23 +4143,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); - - - - ltrim - - ltrim ( bytes bytea, - bytesremoved bytea ) - bytea - - - 从bytes开头移除出现在bytesremoved中的只包含字节的最长字符串。 - - - ltrim('\x1234567890'::bytea, '\x9012'::bytea) - \x34567890 - - + @@ -4063,23 +4162,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); - - - - rtrim - - rtrim ( bytes bytea, - bytesremoved bytea ) - bytea - - - 从bytes结尾移除出现在bytesremoved中的只包含字节的最长字符串。 - - - rtrim('\x1234567890'::bytea, '\x9012'::bytea) - \x12345678 - - + @@ -4092,7 +4175,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bytea - 设置二进制字符串中的n'th位为newvalue。 + 设置二进制字符串中的编号为 n 的位为newvalue set_bit('\x1234567890'::bytea, 30, 0) @@ -4111,7 +4194,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bytea - 设置二进制字符串中的 n'th 字节到 newvalue。 + 设置二进制字符串中的 编号为 n 的 字节到 newvalue set_byte('\x1234567890'::bytea, 4, 64) @@ -4166,7 +4249,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); sha384('abc'::bytea) - \xcb00753f45a35e8bb5a03d699ac65007&zwsp;272c32ab0ed1631a8b605a43ff5bed&zwsp;8086072ba1e7cc2358baeca134c825a7 + \xcb00753f45a35e8bb5a03d699ac65007&zwsp;272c32ab0eded1631a8b605a43ff5bed&zwsp;8086072ba1e7cc2358baeca134c825a7 @@ -4183,7 +4266,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); sha512('abc'::bytea) - \xddaf35a193617abacc417349ae204131&zwsp;12e6fa4e89a97ea20a9ee64b55d39a&zwsp;2192992a274fc1a836ba3c23a3feebbd&zwsp;454d4423643ce80e2a9ac94fa54ca49f + \xddaf35a193617abacc417349ae204131&zwsp;12e6fa4e89a97ea20a9eeee64b55d39a&zwsp;2192992a274fc1a836ba3c23a3feebbd&zwsp;454d4423643ce80e2a9ac94fa54ca49f @@ -4192,12 +4275,11 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); substr - substr ( bytesbytea, startinteger [, countinteger ] ) + substr ( bytesbytea, startinteger, count integer ) bytea - 从start字节开始提取bytes的子字符串,并扩展为count字节,如果这是指定的。 - (与 substring(bytesstartcount) 相同.) + 提取bytes中从第start个字节开始的子字符串;若指定了长度,则提取count个字节。(与substring(bytes from start for count)相同。) substr('\x1234567890'::bytea, 3, 2) @@ -4209,7 +4291,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three');
- 函数get_byteset_byte把一个二进制串中的一个字节计数为字节 0。 + 函数get_byteset_byte把二进制串中的第一个字节编号为字节 0。 函数get_bitset_bit在每一个字节中从右边起计数位; 例如位 0 是第一个字节的最低有效位,而位 15 是第二个字节的最高有效位。 @@ -4217,16 +4299,16 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); 由于历史原因,函数md5返回的是一个十六进制编码的text值,而SHA-2函数返回类型bytea。 可以使用函数encodedecode在两者之间转换。 - 例如encode(sha256('abc'),'hex')可以得到一个十六进制编码的文本表示,或者decode(md5('abc'), 'hex')得到一个bytea 值。 + 例如encode(sha256('abc'), 'hex')可以得到一个十六进制编码的文本表示,或者decode(md5('abc'), 'hex')得到一个bytea 值。 - character string + 字符串 转换为二进制字符串 - binary string + 二进制串 转换为字符串 用于在不同字符集(编码)之间转换字符串的函数,以及用于以文本形式表示任意二进制数据的函数,在中显示。 @@ -4235,7 +4317,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); - 文本/字符串转换函数 + 文本/二进制串转换函数 @@ -4343,7 +4425,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bytea - 从文本表示中解码二进制数据;支持的format值与encode相同。 + 从文本表示中解码二进制数据;支持的format值与encode相同。 decode('MTIzAAE=', 'base64') @@ -4367,9 +4449,9 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); base64格式是RFC 2045第6.8节中描述的。根据RFC,编码行在76个字符处换行。 - 然而,与MIME CRLF换行符不同,结尾只使用换行符。 + 然而,与MIME CRLF换行符不同,行尾只使用一个换行符。 decode函数会忽略回车、换行、空格和制表符。 - 否则,当decode提供无效的base64数据时,包括尾部填充不正确时,会引发错误。 + 否则,当向decode传入无效的 base64 数据时,包括尾部填充不正确时,会引发错误。 @@ -4381,8 +4463,8 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); - escape格式将零字节和高位设置的字节转换为八进制转义序列 - (\nnn),并将反斜杠加倍。 + escape格式将零字节和最高位被置位的字节转换为八进制转义序列 + (\nnn),并将反斜杠双写。 其他字节值会直接表示。如果反斜杠后面不是第二个反斜杠或三个八进制数字,则decode函数会引发错误; 它会接受其他字节值不变。 @@ -4397,10 +4479,10 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); hex格式将每4位数据表示为一个十六进制数字,0f, - 先写入每个字节的高阶数字。 encode函数以小写输出a-f十六进制数字。 + 先写入每个字节的高位数字。 encode函数以小写输出a-f十六进制数字。 因为数据的最小单位是8位,所以encode总是返回偶数个字符。 decode函数接受a-f字符的大小写。 - 当decode提供无效的十六进制数据时,包括提供奇数个字符时,会引发错误。 + 当向decode传入无效的十六进制数据时,包括提供奇数个字符时,会引发错误。 @@ -4417,14 +4499,14 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); 位串函数和操作符 - bit strings - functions + 位串 + 函数 本节描述用于检查和操作位串的函数和操作符,也就是操作类型为bitbit varying的值的函数和操作符。 - (虽然这些表中只提到了bit类型,但bit varying类型的值可以互换使用。) - 位字符串支持中显示的常用比较操作符,就像中显示的操作符。 + (虽然这些表中只提到了bit类型,但bit varying类型的值可以互换使用。) + 位串支持中显示的常用比较操作符,以及中显示的操作符。
@@ -4454,7 +4536,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bit - 连接 + 串接 B'10001' || B'011' @@ -4510,7 +4592,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bit - 按位求反 + 按位非 ~ B'10001' @@ -4550,12 +4632,12 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three');
- 一些可用于二进制字符串的函数也可用于位字符串,如中所示。 + 一些可用于二进制字符串的函数也可用于位串,如中所示。 - 位字符串函数 + 位串函数 @@ -4583,7 +4665,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bigint - 返回位字符串中设置的位数(也被视为popcount)。 + 返回位串中被置位的位数(也称为popcount)。 bit_count(B'10111') @@ -4600,7 +4682,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); integer - 返回位字符串中的位数。 + 返回位串中的位数。 bit_length(B'10111') @@ -4614,14 +4696,14 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); length - bit string - length + 位串 + 长度 length ( bit ) integer - 返回位字符串中的位数。 + 返回位串中的位数。 length(B'10111') @@ -4638,7 +4720,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); integer - 返回位字符串中的字节数。 + 返回位串中的字节数。 octet_length(B'1011111011') @@ -4651,12 +4733,11 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); overlay - overlay ( bits bit PLACING newsubstring bit FROM start integer [ FOR count integer ] ) + overlay ( bits bit PLACING newsubstring bit FROM start integer FOR count integer ) bit - 替换从start位开始的bits的子字符串,并将newsubstring扩展count位。 - 如果count被省略,默认为newsubstring的长度。 + 用newsubstring替换bits中从第start位开始、长度为count位的子串。如果省略count,则默认为newsubstring的长度。 overlay(B'01010101010101010' placing B'11111' from 2 for 3) @@ -4673,7 +4754,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); integer - 按返回指定substring的第一个起始索引,以bits为单位,如果不存在则返回0。 + 返回substringbits中首次出现的位置;如果不存在则返回零。 position(B'010' in B'000001101011') @@ -4686,12 +4767,11 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); substring - substring ( bits bit [ FROM start integer ] [ FOR count integer ] ) + substring ( bits bit FROM start integer FOR count integer ) bit - 如果指定了起始位,则提取从start位开始的bits的子字符串,如果指定了计数位,则在count位之后停止。 - startcount至少提供一个。 + 提取bits的子串:若指定了起始位置,则从第start位开始;若指定了长度,则在提取count位后停止。startcount至少需要指定一个。 substring(B'110010111111' from 3 for 2) @@ -4709,7 +4789,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); integer - 从位字符串中提取第n位;第一个(最左)位为第0位。 + 从位串中提取编号为n的位;第一位(最左侧的位)编号为位 0。 get_bit(B'101010101010101010', 6) @@ -4728,7 +4808,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bit - 将位字符串中的第n位设置为newvalue;第一个(最左)位是第0位。 + 将位串中编号为n的位设置为newvalue;第一位(最左侧的位)编号为位 0。 set_bit(B'101010101010101010', 6, 0) @@ -4739,18 +4819,12 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three');
- - 另外,我们可以在整数和bit之间来回转换。 - 将一个整数转换为bit(n)会复制最右边的n位。 - 将一个整数转换为比整数本身更宽的位字符串宽度将在左边进行符号扩展。一些示例: - + 此外,还可以在整数值与bit类型之间进行类型转换。将整数转换为bit(n)会复制最右侧的n位。将整数转换为宽度超过该整数自身位宽的位串时,会在左侧进行符号扩展。下面是一些示例: 44::bit(10) 0000101100 44::bit(3) 100 cast(-44 as bit(12)) 111111010100 '1110'::bit(4)::integer 14 - - 请注意,如果只是转换为bit,意思是转换成bit(1),因此只会转换整数的最低有效位。 - +注意,仅转换为bit意味着转换为bit(1),因此只会得到该整数的最低有效位。
@@ -4758,11 +4832,11 @@ cast(-44 as bit(12)) 111111010100 模式匹配 - pattern matching + 模式匹配 - PostgreSQL提供了三种独立的实现模式匹配的方法:SQL LIKE操作符、更近一些的SIMILAR TO操作符(SQL:1999 里添加进来的)和POSIX-风格的正则表达式。除了这些基本的这个串匹配这个模式吗?操作符外,还有一些函数可用于提取或替换匹配子串并在匹配位置分离一个串。 + PostgreSQL提供了三种独立的模式匹配方法:传统的SQL LIKE操作符、较新的SIMILAR TO操作符(在 SQL:1999 中加入),以及POSIX风格的正则表达式。除了用于判断这个字符串是否匹配这个模式?的基本操作符外,还提供了提取或替换匹配子字符串、在匹配位置分割字符串的函数。 @@ -4775,26 +4849,20 @@ cast(-44 as bit(12)) 111111010100 - 虽然大部分的正则表达式搜索都能被很快地执行,但是正则表达式仍可能被 - 人为地弄成需要任意长的时间和任意量的内存进行处理。要当心从不怀好意 - 的来源接受正则表达式搜索模式。如果必须这样做,建议加上语句超时限制。 + 虽然大多数正则表达式搜索都能很快完成,但特意构造的正则表达式可能需要任意长的处理时间和任意多的内存。接受来自恶意来源的正则表达式搜索模式时应当谨慎。如果必须这样做,建议设置语句超时。 - 使用SIMILAR TO模式的搜索具有同样的安全性危险, - 因为SIMILAR TO提供了很多和 - POSIX-风格正则表达式相同的能力。 + 使用SIMILAR TO模式进行搜索具有同样的安全风险,因为SIMILAR TO提供了许多与POSIX风格正则表达式相同的能力。 - LIKE搜索比其他两种选项简单得多,因此在使用 - 不怀好意的模式来源时要更安全些。 + LIKE搜索比另外两种方法简单得多,因此,当模式可能来自恶意来源时,使用它更安全。 - 这三类模式匹配操作符都不支持非确定性排序规则。如果需要, - 可以对表达式应用不同的排序规则来绕过这一限制。 + 这三种模式匹配操作符都不支持非确定性排序规则。如有需要,可以对表达式应用不同的排序规则来绕过这一限制。 @@ -4855,8 +4923,7 @@ cast(-44 as bit(12)) 111111010100 - 也可以通过写ESCAPE ''来选择不使用转义字符。这会有效地 - 禁用转义机制,从而无法关闭模式中下划线和百分号的特殊含义。 + 也可以通过写 ESCAPE '' 来选择不使用转义字符。这会禁用转义机制,从而无法关闭模式中下划线和百分号的特殊含义。 @@ -4867,9 +4934,7 @@ cast(-44 as bit(12)) 111111010100 - 关键字ILIKE可以用于替换LIKE,它令该匹配根据 - 活动区域成为大小写无关。这不属于SQL标准,而是 - PostgreSQL扩展。 + 可以用关键字 ILIKE 代替 LIKE,使匹配根据当前区域设置忽略大小写。这不属于 SQL 标准,而是 PostgreSQL 的扩展。 @@ -4883,19 +4948,11 @@ cast(-44 as bit(12)) 111111010100 - 短语LIKEILIKE、 - NOT LIKENOT ILIKE在 - PostgreSQL语法中通常被当作操作符处理;例如, - 它们可以用于expression - operator ANY - (subquery)构造中,不过那里不能包含 - ESCAPE子句。在某些晦涩难懂的情况下,可能需要改用底层 - 操作符名。 + 在 PostgreSQL 语法中,LIKEILIKENOT LIKENOT ILIKE 通常被当作操作符;例如,它们可以用于 expression operator ANY (subquery) 构造,但其中不能包含 ESCAPE 子句。在某些不常见的情况下,可能需要改用底层操作符名称。 - 另请参阅以^@开头的操作符和相应的starts_with()函数, - 在需要简单匹配字符串开头的情况下非常有用。 + 另请参见用于匹配字符串开头的操作符 ^@ 和相应的 starts_with() 函数,它们适用于只需匹配字符串开头的情况。 @@ -4904,8 +4961,8 @@ cast(-44 as bit(12)) 111111010100 <function>SIMILAR TO</function>正则表达式 - regular expression - + 正则表达式 + @@ -4922,13 +4979,11 @@ cast(-44 as bit(12)) 111111010100 - SIMILAR TO操作符根据自己的模式是否匹配给定串而返回真或者假。 - 它和LIKE非常类似,只不过它使用 SQL 标准定义的正则表达式理解模式。 - SQL 正则表达式是在LIKE标记和普通的(POSIX)正则表达式标记的奇怪的杂交。 + SIMILAR TO操作符根据其模式是否匹配给定字符串返回真或假。它与LIKE非常相似,但使用 SQL 标准定义的正则表达式来解释模式。SQL 正则表达式是LIKE表示法与普通(POSIX)正则表达式表示法的一种奇特结合。 - 类似LIKESIMILAR TO操作符只有在它的模式匹配整个串的时候才能成功;这一点和普通的 正则表达式的行为不同,在普通的正则表达式里,模式匹配串的任意部分。 和LIKE类似的地方还有,SIMILAR TO使用_%作为分别代表任意单个字符和任意串的通配符(这些可以比得上 POSIX 正则表达式里的..*)。 + 与LIKE类似,SIMILAR TO操作符只有在其模式匹配整个字符串时才算成功;这一点不同于普通正则表达式,后者可以匹配字符串的任意部分。与LIKE相同,SIMILAR TO也使用_%作为通配符,分别匹配任意单个字符和任意字符串(分别类似于 POSIX 正则表达式中的..*)。 @@ -4996,8 +5051,7 @@ cast(-44 as bit(12)) 111111010100 - 另一个非标准扩展是,在转义字符后面跟着一个字母或数字提供了对为POSIX正则表达式定义的转义序列的访问;参见下面的 - ,和 。 + 另一个非标准扩展是在转义字符后跟一个字母或数字,以使用 POSIX 正则表达式定义的转义序列;参见下文的 @@ -5013,19 +5067,19 @@ cast(-44 as bit(12)) 111111010100 - 带有三个参数的substring函数可以提取匹配SQL正则表达式模式的子字符串。 该函数可以按照标准SQL99语法编写。 + 带有三个参数的substring函数可以提取匹配 SQL 正则表达式模式的子字符串。该函数可以按照标准 SQL 语法书写: substring(string similar pattern escape escape-character) - 或使用现在废除的 SQL:1999 语法: + 也可以使用现已过时的 SQL:1999 语法: substring(string from pattern for escape-character) - 或作为一个普通的三参数函数: + 或写成普通的三参数函数: substring(string, pattern, escape-character) - 与SIMILAR TO一样,指定的模式必须与整个数据字符串匹配,否则函数失败并返回空值。 为了表示匹配的数据子字符串的模式中,模式中应该包含两个转义字符的出现,并在后面加上一个双引号(")。 匹配成功后,将返回与这些分隔符之间的模式部分匹配的文本。 + 与SIMILAR TO一样,指定的模式必须匹配整个数据字符串,否则函数失败并返回空值。为了指明要提取的子字符串所对应的模式部分,模式中应包含两个分隔符,每个分隔符都由转义字符后跟双引号(")组成。匹配成功时,返回与这两个分隔符之间的模式部分匹配的文本。 @@ -5033,7 +5087,7 @@ substring(string, pattern, - 作为对SQL标准的扩展,PostgreSQL只允许有一个转义双引号分隔符,在这种情况下,第三个正则表达式被视为空;或者没有分隔符,在这种情况下,第一个和第三个正则表达式被视为空。 + 作为对SQL标准的扩展,PostgreSQL允许仅有一个转义双引号分隔符,在这种情况下,第三个正则表达式被视为空;或者没有分隔符,在这种情况下,第一个和第三个正则表达式被视为空。 @@ -5050,8 +5104,8 @@ substring('foobar' similar '#"o_b#"%' escape '#') NULLPOSIX正则表达式 - regular expression - pattern matching + 正则表达式 + 模式匹配 @@ -5126,7 +5180,7 @@ substring('foobar' similar '#"o_b#"%' escape '#') NULLboolean - 字符串匹配正则表达式,大小写敏感 + 字符串匹配正则表达式,区分大小写 'thomas' ~ 't.*ma' @@ -5140,7 +5194,7 @@ substring('foobar' similar '#"o_b#"%' escape '#') NULLboolean - 字符串匹配正则表达式,大小写不敏感 + 字符串匹配正则表达式,不区分大小写 'thomas' ~* 'T.*ma' @@ -5154,7 +5208,7 @@ substring('foobar' similar '#"o_b#"%' escape '#') NULLboolean - 字符串不匹配正则表达式,大小写敏感 + 字符串不匹配正则表达式,区分大小写 'thomas' !~ 't.*max' @@ -5168,7 +5222,7 @@ substring('foobar' similar '#"o_b#"%' escape '#') NULLboolean - 字符串不匹配正则表达式,大小写不敏感 + 字符串不匹配正则表达式,不区分大小写 'thomas' !~* 'T.*ma' @@ -5180,11 +5234,11 @@ substring('foobar' similar '#"o_b#"%' escape '#') NULL - POSIX正则表达式提供了比LIKESIMILAR TO操作符更强大的含义。许多 Unix 工具,例如egrepsedawk使用一种与我们这里描述的类似的模式匹配语言。 + POSIX正则表达式提供了比LIKESIMILAR TO操作符更强大的模式匹配方式。许多 Unix 工具,例如egrepsedawk,都使用与这里描述的模式匹配语言相似的语言。 - 正则表达式是一个字符序列,它是定义一个串集合 (一个正则集)的缩写。 如果一个串是正则表达式描述的正则集中的一员时, 我们就说这个串匹配该正则表达式。 和LIKE一样,模式字符准确地匹配串字符, 除非在正则表达式语言里有特殊字符 — 不过正则表达式用的 特殊字符和LIKE用的不同。 和LIKE模式不一样的是,正则表达式允许匹配串里的任何位置,除非该正则表达式显式地挂接在串的开头或者结尾。 + 正则表达式是一个字符序列,是定义一组字符串(一个正则集)的简写。如果字符串属于正则表达式描述的正则集,就称该字符串匹配此正则表达式。与LIKE一样,模式中的字符精确匹配字符串中的字符,除非该模式字符在正则表达式语言中有特殊含义 — 但正则表达式使用的特殊字符与LIKE不同。与LIKE模式不同,正则表达式可以匹配字符串中的任意位置,除非显式将其锚定到字符串开头或末尾。 @@ -5205,8 +5259,8 @@ substring('foobar' similar '#"o_b#"%' escape '#') NULL 带两个参数的substring函数,即substring(string from pattern),提供了抽取一个匹配 POSIX 正则表达式模式的子串的方法。 - 如果没有匹配它返回空值,否则就是匹配模式的文本中的第一部分。 - 但是如果该模式包含任何圆括号,那么将返回匹配第一对子表达式(对应第一个左圆括号的) 的文本。 + 如果没有匹配它返回空值,否则返回文本中首次匹配模式的那部分内容。 + 但是如果该模式包含任何圆括号,那么将返回匹配第一个圆括号子表达式(左圆括号最先出现的那个)的文本。 如果你想在表达式里使用圆括号而又不想导致这个例外,那么你可以在整个表达式外边放上一对圆括号。 如果你需要在想抽取的子表达式前有圆括号,参阅后文描述的非捕获性圆括号。 @@ -5235,7 +5289,7 @@ substring('foobar' from 'o(.)b') o - 一些示例: + 一些示例: regexp_count('ABCABCAXYaxy', 'A.') 3 regexp_count('ABCABCAXYaxy', 'A.', 1, 'i') 4 @@ -5243,26 +5297,26 @@ regexp_count('ABCABCAXYaxy', 'A.', 1, 'i') 4 - regexp_instr函数返回字符串中第N个匹配项的起始或结束位置,如果没有这样的匹配项则返回零。 + regexp_instr函数返回 POSIX 正则表达式模式在字符串中第N个匹配项的起始或结束位置,如果没有这样的匹配项则返回零。 它的语法为regexp_instr(string, pattern , start , N , endoption , flags , subexpr - ). + )。 在string中搜索pattern,通常从字符串的开头开始,但如果提供了start参数,则从该字符索引开始。 如果指定了N,则定位模式的第N个匹配项,否则定位第一个匹配项。 如果省略了endoption参数或将其指定为0,则函数返回匹配项的第一个字符的位置。否则,endoption 必须为1,函数返回匹配项后面字符的位置。 flags参数是一个可选的文本字符串,包含零个或多个单字母标志,可以改变函数的行为。支持的标志在中描述。 - 对于包含括号子表达式的模式,subexpr是一个整数,表示感兴趣的子表达式:结果标识与该子表达式匹配的子字符串的位置。 - 子表达式按其前导括号的顺序编号。 - 当省略或将subexpr指定为零时,结果标识整个匹配的位置,而不考虑括号子表达式。 + 对于包含圆括号子表达式的模式,subexpr是一个整数,表示感兴趣的子表达式:结果标识与该子表达式匹配的子字符串的位置。 + 子表达式按其左圆括号的顺序编号。 + 当省略或将subexpr指定为零时,结果标识整个匹配的位置,而不考虑圆括号子表达式。 - 一些示例: + 一些示例: regexp_instr('number of your street, town zip, FR', '[^,]+', 1, 2) 23 @@ -5284,7 +5338,7 @@ regexp_instr('ABCDEFGHI', '(c..)(...)', 1, 1, 0, 'i', 2) - 一些示例: + 一些示例: regexp_like('Hello World', 'world') false regexp_like('Hello World', 'world', 'i') true @@ -5292,18 +5346,18 @@ regexp_like('Hello World', 'world', 'i') true - regexp_match函数返回一个文本数组,其中包含与POSIX正则表达式模式对字符串的第一个匹配的子字符串。它的语法为 + regexp_match函数返回一个文本数组,包含字符串首次匹配 POSIX 正则表达式模式时匹配的子字符串。它的语法为 regexp_match(string, pattern , flags )。 如果没有匹配,结果为NULL。 - 如果找到匹配,并且pattern不包含括号子表达式,则结果是包含与整个模式匹配的子字符串的单元素文本数组。 - 如果找到匹配,并且pattern包含括号子表达式,则结果是一个文本数组,其中n的元素是匹配 - pattern的第n个括号子表达式的子字符串(不包括非捕获括号;详情见下文)。 + 如果找到匹配,并且pattern不包含圆括号子表达式,则结果是包含与整个模式匹配的子字符串的单元素文本数组。 + 如果找到匹配,并且pattern包含圆括号子表达式,则结果是一个文本数组,其中第n个元素是匹配 + pattern的第n个圆括号子表达式的子字符串(不包括非捕获括号;详情见下文)。 flags参数是一个可选的文本字符串,其中包含零个或多个单个字母标志,用于更改函数的行为。支持的标志在中描述。 - 一些示例: + 一些示例: SELECT regexp_match('foobarbequebaz', 'bar.*que'); regexp_match @@ -5322,10 +5376,10 @@ SELECT regexp_match('foobarbequebaz', '(bar)(beque)'); - 在通常情况下,当您只想要整个匹配的子字符串或NULL表示没有匹配时, + 在通常情况下,当你只想要整个匹配的子字符串或NULL表示没有匹配时, 最好的解决方案是使用regexp_substr()。 然而,在PostgreSQL版本15及以上版本中才存在 - regexp_substr()。在旧版本中工作时,您可以提取 + regexp_substr()。在旧版本中工作时,你可以提取 regexp_match()结果的第一个元素,例如: SELECT (regexp_match('foobarbequebaz', 'bar.*que'))[1]; @@ -5368,44 +5422,25 @@ SELECT regexp_matches('foobarbequebazilbarfbonk', '(b[^b]+)(b[^b]+)', 'g'); - 在大部分情况下,regexp_matches()应该与g标志一起使用,因为如果只是想要第一个匹配,使用regexp_match()会更加简单高效。不过,regexp_match()仅存在于PostgreSQL版本10以及更高的版本中。当在较老的版本中使用时,一种常用的技巧是把regexp_matches()调用放在子选择中,例如: + 在大部分情况下,regexp_matches()应该与g标志一起使用,因为如果只是想要第一个匹配,使用regexp_match()会更加简单高效。不过,regexp_match()仅存在于PostgreSQL版本10以及更高的版本中。当在较老的版本中使用时,一种常用的技巧是把regexp_matches()调用放在子查询中,例如: SELECT col1, (SELECT regexp_matches(col2, '(bar)(beque)')) FROM tab; - 如果有一个匹配,则这个语句会产生一个文本数组,否则返回NULL,这和regexp_match()的做法一样。如果没有子选择,这个查询对于没有匹配的表行根本不会产生输出,显然那不是想要的行为。 + 如果有一个匹配,则这个语句会产生一个文本数组,否则返回NULL,这和regexp_match()的做法一样。如果没有子查询,这个查询对于没有匹配的表行根本不会产生输出,这通常不是预期行为。 - regexp_replace函数提供了对匹配POSIX正则表达式模式的子字符串进行替换的功能。 - 它的语法为 - regexp_replace(source, + regexp_replace函数将匹配 POSIX 正则表达式模式的子字符串替换为新文本。它的语法为 regexp_replace(source, pattern, replacement , start , N - , flags ). - (注意,除非指定了start,否则无法指定N, - 但flags可以在任何情况下给出。) - 如果pattern没有匹配到source字符串, - 则返回未更改的source字符串。如果有匹配,则返回带有 - replacement字符串替换匹配子字符串的source字符串。 - replacement字符串可以包含\n, - 其中n为1至9,表示应插入与模式的第n个括号子表达式匹配的源子字符串, - 也可以包含\&表示应插入与整个模式匹配的子字符串。 - 如果需要在替换文本中放置一个字面上的反斜杠,则写\\。 - 在string中搜索pattern, - 通常从字符串的开头开始,但如果提供了start参数,则从该字符索引开始。 - 默认情况下,只替换模式的第一个匹配项。 - 如果指定了N且大于零,则替换模式的第N个匹配项。 - 如果给出了g标志,或者指定了N且为零,则在或之后的所有匹配项 - 位置都将被替换。 (当指定了N时,g标志将被忽略。) - flags参数是一个可选的文本字符串,包含零个或多个单字母标志,用于更改函数的行为。 - 支持的标志(尽管不包括g)在中描述。 + , flags )。(注意,只有指定了start,才能指定N,但flags在任何情况下都可以给出。)如果没有匹配pattern的内容,则原样返回源字符串source。如果有匹配,则返回将匹配的子字符串替换为replacement后的sourcereplacement字符串可以包含\n,其中n为 1 至 9,表示插入与模式中第n个圆括号子表达式匹配的源子字符串;也可以包含\&,表示插入与整个模式匹配的子字符串。要在替换文本中放入字面的反斜线,应写成\\。在string中搜索pattern时,通常从字符串开头开始;如果提供了start参数,则从该字符索引开始。默认只替换模式的第一个匹配项。如果指定了N且其值大于零,则替换模式的第N个匹配项。如果给出g标志,或指定了N且其值为零,则替换start位置及其后的所有匹配项。(指定N时,g标志会被忽略。)flags参数是可选的文本字符串,可包含零个或多个单字母标志,用于改变函数行为。支持的标志(不包括g)在中介绍。 - 一些示例: + 一些示例: regexp_replace('foobarbaz', 'b..', 'X') fooXbaz @@ -5421,7 +5456,7 @@ regexp_replace('A PostgreSQL function', 'a|e|i|o|u', 'X', 1, 3, 'i') - regexp_split_to_table把一个 POSIX 正则表达式模式当作一个定界符来分离一个串。它的语法形式是regexp_split_to_table(string, pattern , flags )。如果没有与pattern的匹配,该函数返回string。如果有至少有一个匹配,对每一个匹配它都返回从上一个匹配的末尾(或者串的开头)到这次匹配开头之间的文本。当没有更多匹配时,它返回从上一次匹配的末尾到串末尾之间的文本。flags参数是一个可选的文本串,它包含零个或更多单字母标志,这些标识可以改变该函数的行为。regexp_split_to_table能支持的标志在中描述。 + regexp_split_to_table把一个 POSIX 正则表达式模式当作一个定界符来分割字符串。它的语法形式是regexp_split_to_table(string, pattern , flags )。如果没有与pattern的匹配,该函数返回string。如果至少有一个匹配,对每一个匹配它都返回从上一个匹配的末尾(或者串的开头)到这次匹配开头之间的文本。当没有更多匹配时,它返回从上一次匹配的末尾到串末尾之间的文本。flags参数是一个可选的文本串,它包含零个或更多单字母标志,这些标志可以改变该函数的行为。regexp_split_to_table能支持的标志在中描述。 @@ -5429,7 +5464,7 @@ regexp_replace('A PostgreSQL function', 'a|e|i|o|u', 'X', 1, 3, 'i') - 一些示例: + 一些示例: SELECT foo FROM regexp_split_to_table('the quick brown fox jumps over the lazy dog', '\s+') AS foo; foo @@ -5475,9 +5510,9 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; - 正如最后一个示例所示,regexp分割函数会忽略出现在字符串开头或结尾 - 或紧跟在前一个匹配项之后的零长度匹配。这与其他regexp函数实现的 - 严格的regexp匹配定义相矛盾,但在实践中通常是最方便的行为。 + 正如最后一个示例所示,正则表达式分割函数会忽略出现在字符串开头或结尾 + 或紧跟在前一个匹配项之后的零长度匹配。这与其他正则表达式函数实现的 + 严格的正则表达式匹配定义相矛盾,但在实践中通常是最方便的行为。 其他软件系统如Perl使用类似的定义。 @@ -5490,23 +5525,23 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; , N , flags , subexpr - )。 + )。 patternstring中进行搜索, 通常从字符串的开头开始,但如果提供了start参数,则从该字符索引开始。 如果指定了N,则返回模式的第N次匹配, 否则返回第一次匹配。参数flags是一个可选文本字符串, 包含零个或多个单字母标志,可以改变函数的行为。支持的标志在中描述。 - 对于包含括号子表达式的模式,subexpr是一个整数, + 对于包含圆括号子表达式的模式,subexpr是一个整数, 表示感兴趣的子表达式:结果是与该子表达式匹配的子字符串。 - 子表达式按其前导括号的顺序编号。 - 当省略或为零时,subexpr的结果是整个匹配,而不考虑括号子表达式。 + 子表达式按其左圆括号的顺序编号。 + 当subexpr省略或为零时,结果是整个匹配,而不考虑圆括号子表达式。 - 一些示例: + 一些示例: regexp_substr('number of your street, town zip, FR', '[^,]+', 1, 2) - 城镇 邮编 + town zip regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) FGH @@ -5543,7 +5578,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 一个量化原子是一个原子, 后面可能跟着一个量词。没有量词的时候,它匹配一个原子, 有量词的时候,它可以匹配若干个原子。一个原子可以是在里面显示的任何可能。 可能的量词和它们的含义在里显示。 + 一个量化原子是一个原子,后面可以跟一个量词。没有量词时,匹配一次原子所匹配的内容;有量词时,按量词指定的次数匹配原子所匹配的内容。原子可以是列出的任何一种形式。可用量词及其含义见 @@ -5567,12 +5602,12 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) (re) - (其中re是任何正则表达式) 匹配一个对re的匹配,匹配将为可能的报告被记下 + (其中re是任意正则表达式)匹配re所匹配的内容,并记录该匹配,以备输出结果 (?:re) - 同上,但是匹配不会为了报告而被记下 (一个非捕获圆括号集) (只对 ARE) + 同上,但不记录匹配结果(非捕获圆括号;仅适用于 ARE) @@ -5587,17 +5622,17 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) \k - (其中k是一个非字母数字字符) 匹配一个被当作普通字符看待的特定字符, 例如,\\匹配一个反斜线字符 + (其中k既不是字母也不是数字)把该字符视为普通字符并匹配它,例如,\\匹配反斜线字符 \c - 其中c是一个字母数字 (可能跟着其它字符),它是一个转义, 参阅(仅对 ARE; 在 ERE 和 BRE 中,它匹配c + 其中c是字母或数字(后面可能还有其他字符),这是一个转义,参见(仅适用于 ARE;在 ERE 和 BRE 中,它匹配c { - 如果后面跟着一个字符,而不是数字, 那么就匹配左花括弧{;如果跟着一个数字, 那么它是range的开始(见下文) + 如果后面跟着非数字字符,则匹配左花括号{;如果后面跟着数字,则是bound的开头(见下文) @@ -5615,7 +5650,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 如果你关掉了,你在文串常量中写的任何反斜线都需要被双写。详见。 + 如果你关掉了,你在字符串常量中写的任何反斜线都需要被双写。详见 @@ -5704,7 +5739,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 非贪婪的量词(只在 ARE 中可用)匹配对应的正常 (贪婪)模式,区别是它寻找最少的匹配,而不是最多的匹配。详见。 + 非贪婪量词(仅适用于 ARE)与对应的普通(贪婪)量词匹配相同的可能内容,但优先选择最少的匹配次数,而不是最多的匹配次数。详见 @@ -5731,39 +5766,39 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) ^ - 串开头的匹配 + 在字符串开头匹配 $ - 串末尾的匹配 + 在字符串末尾匹配 (?=re) - 在某个位置上,如果从该位置开始的子串能够匹配re,则匹配正向先行断言(仅对 ARE) + 正向先行断言在这样的位置匹配:存在从该位置开始且匹配re的子字符串(仅适用于 ARE) (?!re) - 在某个位置上,如果从该位置开始的子串不能匹配re,则匹配负向先行断言(仅对 ARE) + 负向先行断言在这样的位置匹配:不存在任何从该位置开始且匹配re的子字符串(仅适用于 ARE) (?<=re) - 在某个位置上,如果以该位置结束的某个子串能够匹配re,则匹配正向后行断言(仅对 ARE) + 正向后行断言在这样的位置匹配:存在以该位置结束且匹配re的子字符串(仅适用于 ARE) (?<!re) - 在某个位置上,如果以该位置结束的任何子串都不能匹配re,则匹配负向后行断言(仅对 ARE) + 负向后行断言在这样的位置匹配:不存在任何以该位置结束且匹配re的子字符串(仅适用于 ARE) - Lookahead 和 lookbehind 约束不能包含反向引用 (参阅),并且其中的所有圆括号 都被认为是非捕获的。 + 先行和后行约束不能包含反向引用(参见),其中的所有圆括号都视为非捕获圆括号。 @@ -5772,11 +5807,11 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) 方括号表达式 - 方括号表达式是一个包围在[]中的字符列表。它通常匹配列表中的任意单个字符(但见下文)。 如果列表以^开头,它匹配任意单个在该列表参与部分中的字符。如果该列表中两个字符用-隔开, 那它就是那两个字符(包括在内)之间的所有字符范围的缩写,例如,在ASCII[0-9]匹配任何十进制数字。两个范围共享一个端点是非法的,例如,a-c-e。范围与字符集关系密切, 可移植的程序应该避免依靠它们。 + 方括号表达式是用[]括起来的字符列表。通常,它匹配列表中的任意单个字符(但请参见下文)。如果列表以^开头,则匹配任意在列表剩余部分中的单个字符。如果列表中的两个字符用-分隔,则表示排序序列中这两个字符之间的完整字符范围(包含两个端点);例如,ASCII中的[0-9]匹配任意十进制数字。两个范围共享一个端点是不合法的,例如a-c-e。范围高度依赖排序序列,因此可移植程序应避免依赖它们。 - 想在列表中包含文本],可以让它做列表的首字符(如果使用了^,需要放在其后)。 想在列表中包含文本-,可以让它做列表的首字符或者尾字符,或者一个范围的第二个端点。 想在列表中把文本-当做范围的起点, 把它用[..]包围起来,这样它就成为一个排序元素(见下文)。 除了这些字符本身、一些用[的组合(见下段)以及转义(只在 ARE 中有效)以外,所有其它特殊字符 在方括号表达式里都失去它们的特殊含义。特别是,在 ERE 和 BRE 规则下\不是特殊的, 但在 ARE 里,它是特殊的(引入一个转义)。 + 想在列表中包含字面字符],可以让它做列表的首字符(如果使用了^,需要放在其后)。 想在列表中包含字面字符-,可以让它做列表的首字符或者尾字符,或者一个范围的第二个端点。 想在列表中把字面字符-当做范围的起点, 把它用[..]包围起来,这样它就成为一个排序元素(见下文)。 除了这些字符本身、一些用[的组合(见下段)以及转义(只在 ARE 中有效)以外,所有其它特殊字符 在方括号表达式里都失去它们的特殊含义。特别是,在 ERE 和 BRE 规则下\不是特殊的, 但在 ARE 里,它是特殊的(引入一个转义)。 @@ -5791,30 +5826,11 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 在方括号表达式里,包围在[==]里的排序元素是一个等价类, 代表等效于那一个的所有排序元素的字符序列,包括它本身(如果没有其它等效排序元素,那么就好象封装定界符是[..])。例如,如果o^是一个等价类的成员,那么[[=o=]][[=^=]][o^]都是同义的。一个等价类不能是一个范围的端点。 + 在方括号表达式里,包围在[==]里的排序元素是一个等价类, 代表等效于那一个的所有排序元素的字符序列,包括它本身(如果没有其它等效排序元素,那么就好像封装定界符是[..])。例如,如果o^是一个等价类的成员,那么[[=o=]][[=^=]][o^]都是同义的。一个等价类不能是一个范围的端点。 - 在方括号表达式里,在[::]里面封装的字符类的名字代表属于该类的所有字符的列表。 - 字符类不能作为范围的端点使用。 - POSIX标准定义了这些字符类的名称: - alnum (字符和数字), - alpha (字符), - blank (空格和制表符tab), - cntrl (控制符), - digit (数位数), - graph (空格除外可打印字符), - lower (小写字母), - print (包含空格可打印字符), - punct (标点符号), - space (空白), - upper (大写字母), - 和 xdigit (十六进制数). - 对于7位ASCII字符集中的字符来说,这些标准字符类的行为在不同平台上一般是一致的。 - 一个给定的非 ASCII 字符是否被认为属于这些类别中的一个,取决于正则表达式函数或操作符所使用的排序规则(见),或者在默认情况下取决于数据库的LC_CTYPE locale 设置(见)。 - 非ASCII字符的分类在不同的平台上会有不同的分类,即使是在类似命名的locale中也是如此。 - (但C locale从不认为任何非ASCII字符属于上述任何一类)。 - 除了这些标准字符类之外,PostgreSQL定义了word字符类,等同于alnum加上下划线(_), 以及ascii字符类,它完全包含7位ASCII字符集。 + 在方括号表达式中,用[::]括起来的字符类名称表示属于该类的所有字符。字符类不能作为范围的端点。POSIX标准定义了以下字符类名称:alnum(字母和数字)、alpha(字母)、blank(空格和制表符)、cntrl(控制字符)、digit(数字)、graph(空格以外的可打印字符)、lower(小写字母)、print(包括空格的可打印字符)、punct(标点符号)、space(任意空白字符)、upper(大写字母)和xdigit(十六进制数字)。对于 7 位 ASCII 字符集中的字符,这些标准字符类在各平台上的行为通常一致。给定的非 ASCII 字符是否属于其中某个类,取决于正则表达式函数或操作符使用的排序规则(参见),默认则取决于数据库的LC_CTYPE区域设置(参见)。即使区域设置名称相似,非 ASCII 字符的分类也可能因平台而异。(但C区域设置不会将任何非 ASCII 字符归入这些类。)除了这些标准字符类,PostgreSQL还定义了word字符类,即alnum加上下划线(_),以及恰好包含 7 位 ASCII 字符集的ascii字符类。 @@ -5831,11 +5847,11 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) 正则表达式转义 - 转义是以\开头,后面跟着一个字母数字字符的特殊序列。 转义有好几种变体:字符输入转义、字符类简写转义、约束转义以及反向引用。在 ARE 里, 如果一个\后面跟着一个字母数字,但是并未组成一个合法的转义, 那么它是非法的。在 ERE 中没有转义:在方括号表达式之外,一个后面跟着字母数字字符的\只是表示该字符是一个普通的字符,而且在一个方括号表达式里,\是一个普通的字符(后者实际上在 ERE 和 ARE 不兼容)。 + 转义是以\开头,后面跟着一个字母或数字字符的特殊序列。 转义有好几种变体:字符输入转义、字符类简写转义、约束转义以及反向引用。在 ARE 里, 如果一个\后面跟着一个字母或数字,但是并未组成一个合法的转义, 那么它是非法的。在 ERE 中没有转义:在方括号表达式之外,一个后面跟着字母或数字字符的\只是表示该字符是一个普通的字符,而且在一个方括号表达式里,\是一个普通的字符(后者是 ERE 与 ARE 之间唯一的实际不兼容之处)。 - 字符输入转义用于便于我们在 RE 中声明那些不可打印的或其他习惯的字符。它们显示在中。 + 字符输入转义便于在 RE 中指定不可打印或其他不便输入的字符,见 @@ -5843,13 +5859,13 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 约束转义是一个约束,如果满足特定的条件,它匹配该空串。它们显示在中。 + 约束转义是以转义形式书写的约束,在满足特定条件时匹配空字符串,见 - 反向引用\n)匹配数字\n指定的被前面的圆括号子表达式匹配的同一个串 (参阅)。 + 反向引用\n)匹配前面编号为n的圆括号子表达式所匹配的同一字符串 (参阅)。 例如, ([bc])\1匹配bb或者cc, 但是不匹配bc或者cb。 - RE 中子表达式必须完全在反向引用前面。子表达式以它们的先导圆括号的顺序编号。 + RE 中子表达式必须完全在反向引用前面。子表达式以它们的左圆括号的顺序编号。 非捕获圆括号并不定义子表达式。 反向引用仅考虑被引用的子表达式匹配的字符串字符,而不考虑其中包含的任何约束。 例如,(^\d)\1 将匹配 22。 @@ -5892,7 +5908,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) \e - 排序序列名为ESC的字符,如果无法做到该字符为八进制值 033 + 排序序列名称为ESC的字符;若不存在这样的字符,则使用八进制值为033的字符 @@ -5902,7 +5918,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) \n - 新行,和 C 中一样 + 换行符,与 C 中相同 @@ -6026,7 +6042,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 类-缩写转义也适用于括号表达式,尽管上面显示的定义在该上下文中在语法上并不完全有效。 + 字符类简写转义也适用于括号表达式,尽管上面显示的定义在该上下文中在语法上并不完全有效。 例如,[a-c\d] 等同于 [a-c[:digit:]] @@ -6067,7 +6083,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) \Y - 只在一个词的不是开头或末尾的点上匹配 + 只在不属于单词开头或末尾的位置匹配 @@ -6079,7 +6095,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 一个词被定义成在上面[[:<:]][[:>:]]中的声明。在方括号表达式里,约束转义是非法的。 + 单词的定义与上文[[:<:]][[:>:]]的说明相同。方括号表达式中不允许使用约束转义。 @@ -6099,12 +6115,12 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) \m - (其中m是一个非零位)一个到第m个子表达式的反向引用 + (其中m是一个非零数字)一个到第m个子表达式的反向引用 \mnn - (其中m是一个非零位,并且nn是一些更多的位,并且十六进制值mnn不超过目前能看到的封闭捕获圆括号的数目)一个到第mnn个子表达式的反向引用 + (其中m是一个非零数字,并且nn是后续的若干数字,并且十进制值mnn不大于此前已出现的捕获右圆括号数)一个到第mnn个子表达式的反向引用 @@ -6113,7 +6129,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 在八进制字符输入转义和反向引用之间有一个历史继承的歧义存在,这个歧义是 通过下面的启发式规则解决的,像上面描述地那样。前导零总是表示这是一个八进制转义。 而单个非零数字,如果没有跟着任何其它位,那么总是被认为反向引用。 一个多位的非零开头的序列也被认为是反向引用,只要它出现在合适的子表达式后面 (也就是说,在反向引用的合法范围中的数),否则就被认为是一个八进制。 + 八进制字符输入转义与反向引用之间存在固有歧义,按上文提到的启发式规则解决:前导零始终表示八进制转义。单个非零数字,如果后面没有其他数字,始终视为反向引用。不以零开头的多位数字序列,如果前面已有相应的子表达式(即该数字在反向引用的合法范围内),则视为反向引用,否则视为八进制转义。 @@ -6127,11 +6143,11 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 如果一个 RE 以***:开头,那么剩下的 RE 都被当作 ARE(这在PostgreSQL中通常是无效的,因为 RE 被假定为 ARE,但是如果 ERE 或 BRE 模式通过flags参数被指定为一个正则表达式函数时,它确实能产生效果)。如果一个 RE 以***=开头, 那么剩下的 RE 被当作一个文本串,所有的字符都被认为是一个普通字符。 + RE 可以以两种特殊的引导前缀之一开头。如果 RE 以***:开头,余下部分就被视为 ARE。(这在PostgreSQL中通常没有影响,因为 RE 默认被视为 ARE;但如果通过正则表达式函数的flags参数指定了 ERE 或 BRE 模式,它就会产生影响。)如果 RE 以***=开头,余下部分就作为按字面解释的字符串处理,所有字符都视为普通字符。 - 一个 ARE 可以以嵌入选项开头:一个序列(?xyz)(这里的xyz是一个或多个字母字符)声明影响剩余 RE 的选项。 这些选项覆盖任何前面判断的选项 — 特别地,它们可以覆盖一个正则表达式操作符隐含的大小写敏感的行为,或者覆盖flags参数中的正则表达式函数。可用的选项字母在中显示。注意这些同样的选项字母也被用在正则表达式函数的flags参数中。 + 一个 ARE 可以以嵌入选项开头:一个序列(?xyz)(这里的xyz是一个或多个字母字符)声明影响剩余 RE 的选项。 这些选项覆盖任何先前确定的选项 — 特别地,它们可以覆盖一个正则表达式操作符隐含的大小写敏感的行为,或者覆盖正则表达式函数的flags参数所指定的选项。可用的选项字母在中显示。注意这些同样的选项字母也被用在正则表达式函数的flags参数中。
@@ -6176,32 +6192,32 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) n - 新行敏感的匹配(见 + 换行敏感的匹配(见 p - 部分新行敏感的匹配(见 + 部分换行敏感的匹配(见 q - RE的剩余部分是一个文字(quoted)串,全部是普通字符 + RE 的剩余部分按字面(加引号)解释,所有字符都视为普通字符 s - 非新行敏感的匹配(默认) + 非换行敏感的匹配(默认) t - 紧语法(默认,见下文) + 紧凑语法(默认;见下文) w - 逆部分新行敏感(怪异)的匹配(见 + 逆部分换行敏感(怪异)的匹配(见 @@ -6213,16 +6229,16 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2)
- 嵌入选项在)终止序列时发生作用。它们只在 ARE 的开始处起作用 (在任何可能存在的***:控制器后面)。 + 嵌入选项从结束该序列的)处开始生效。它们只能出现在 ARE 的开头(如果存在***:引导前缀,则位于该前缀之后)。 - 除了通常的()RE 语法(这种情况下所有字符都有效), 还有一种扩展语法,可以通过声明嵌入的x选项获得。在扩展语法里,RE 中的空白字符被忽略,就像那些在#和其后的新行(或 RE 的末尾)之间的字符一样。这样就允许我们给一个复杂的 RE 分段和注释。不过这个基本规则有三种例外: + 除了通常的紧凑 RE 语法(其中所有字符都有意义)之外,还有一种扩展语法,可以通过指定嵌入的x选项来使用。在扩展语法中,RE 中的空白字符会被忽略,同样被忽略的还有#与其后的换行符(或 RE 末尾)之间的所有字符。这使得复杂的 RE 可以分段并添加注释。此基本规则有三个例外: - 空白字符或前置了\#将被保留 + 空白字符或 # 的前面若有 \,该字符就会被保留。 @@ -6237,14 +6253,14 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 为了这个目的,空白是空格、制表符、新行以及任何属于 whitespace 字符类的字符。 + 在这里,空白字符包括空格、制表符、换行符,以及属于space字符类的任何字符。 - 最后,在 ARE 里,方括号表达式外面,序列(?#ttt)(其中ttt是任意不包含一个))的文本)是一个注释, 它被完全忽略。同样,这样的东西是不允许出现在多字符符号的字符中间的,例如 (?:。这种注释更像是一种历史产物而不是一种有用的设施,并且它们的使用已经被废弃;请使用扩展语法来替代。 + 最后,在 ARE 里,方括号表达式外面,序列(?#ttt)(其中ttt是任意不包含一个)的文本)是一个注释, 它被完全忽略。同样,这样的东西是不允许出现在多字符符号的字符中间的,例如 (?:。这种注释更像是一种历史产物而不是一种有用的设施,并且它们的使用已经被废弃;请使用扩展语法来替代。
- 如果声明了一个初始的***=控制器,那么所有这些元语法扩展都不能使用,因为这样表示把用户输入当作一个文字串而不是 RE 对待。 + 如果指定了开头的***=引导前缀,那么这些元语法扩展都不能使用,因为这表示把用户输入作为按字面解释的字符串,而非 RE 处理。 @@ -6261,7 +6277,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 大多数原子以及所有约束,都没有贪婪属性(因为它们毕竟无法匹配个数变化的文本)。 + 大多数原子以及所有约束,都没有贪婪属性(因为它们毕竟无法匹配长度不定的文本)。 @@ -6313,7 +6329,7 @@ SELECT SUBSTRING('XY1234Z', 'Y*?([0-9]{1,3})');
- 简而言之,如果一个 RE 同时包含贪婪和非贪婪的子表达式,那么总的匹配长度要么是尽可能长,要么是尽可能短,这取决于给整个 RE 赋予的属性。给子表达式赋予的属性只影响在这个匹配里,各个子表达式之间相互允许吃掉的多少。 + 简而言之,如果一个 RE 同时包含贪婪和非贪婪的子表达式,那么总的匹配长度要么是尽可能长,要么是尽可能短,这取决于给整个 RE 赋予的属性。给子表达式赋予的属性只影响在这个匹配里,各个子表达式相对于其他子表达式能吃掉多少内容。 @@ -6347,23 +6363,23 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 如果声明了大小写无关的匹配,那么效果就好像所有大小写区别在字母表中消失了。如果在多个情况中一个字母以一个普通字符的形式出现在方括号表达式外面,那么它实际上被转换成 一个包含大小写的方括号表达式,也就是说,x 变成 [xX]。 如果它出现在一个方括号表达式里面,那么它的所有大小写的同族都被加入 方括号表达式中,也就是说,x变成[xX]。当它出现在一个方括号表达式内时,它的所有大小写副本都被加入到方括号表达式中,例如, [x]会变成[xX],而[^x]会变成[^xX]。 + 如果指定不区分大小写的匹配,其效果近似于字母表中的所有大小写差别都消失了。当存在大小写形式的字母作为普通字符出现在方括号表达式之外时,实际上会转换为包含其大小写形式的方括号表达式,例如x变成[xX]。当它出现在方括号表达式内部时,其所有大小写形式都会加入该表达式,例如[x]变成[xX][^x]变成[^xX] 如果指定了换行敏感的匹配,.和使用^的方括号表达式 将永远不会匹配换行字符(这样,匹配就不会跨越行,除非 RE 显式地包含了换行)并且^$除了分别匹配串开头和结尾之外,还将分别匹配换行后面和前面的空串。 但是 ARE 转义\A\Z仍然匹配串的开头和结尾。 - 此外,字符类缩写符\D\W将匹配换行,而无论这种模式如何。 + 此外,字符类简写\D\W将匹配换行,而无论这种模式如何。 (在PostgreSQL 14之前,它们在换行敏感模式下不匹配换行。 写入[^[:digit:]][^[:word:]]以获取旧的行为。) - 如果指定了部分新行敏感的匹配,那么它影响.和方括号表达式, 这个时候和新行敏感的匹配一样,但是不影响^$。 + 如果指定了部分换行敏感的匹配,那么它影响.和方括号表达式, 这个时候和换行敏感的匹配一样,但是不影响^$ - 如果指定了逆新行敏感匹配,那么它影响^$,其作用和在新行敏感的匹配里一样,但是不影响.和方括号表达式。这个并不是很有用,只是为了满足对称性而提供的。 + 如果指定了逆部分换行敏感匹配,那么它影响^$,其作用和在换行敏感的匹配里一样,但是不影响.和方括号表达式。这个并不是很有用,只是为了满足对称性而提供的。 @@ -6376,11 +6392,11 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}');
- ARE 实际上和 POSIX ERE 不兼容的唯一的特性是在方括号表达式里\并不失去它特殊的含义。所有其它 ARE 特性都使用在 POSIX ERE 里面是非法或者是未定义、未声明效果的语法;指示器的***就是在 POSIX 的 BRE 和 ERE 之外的语法。 + ARE 与 POSIX ERE 实际不兼容的唯一特性是:\在方括号表达式中不会失去特殊含义。其他所有 ARE 特性所使用的语法,在 POSIX ERE 中都是非法的,或其效果未定义或未指定;引导前缀的***语法同样不属于 POSIX 的 BRE 或 ERE 语法。 - 许多 ARE 扩展都是从 Perl 那里借来的(但是有些被做了修改来清理它们),以及一些 Perl 里没有出现的扩展。要注意的不兼容性包括\b\B、对结尾的新行缺乏特别的处理、对那些被新行敏感匹配的东西附加的补齐方括号表达式、在 lookahead/lookbehind 约束里对圆括号和反向引用的限制以及最长/最短 匹配(而不是第一匹配)的语义。 + 许多 ARE 扩展借鉴自 Perl,但其中一些经过了整理和修改,也未实现少数 Perl 扩展。需要注意的不兼容之处包括\b\B、不对末尾换行符作特殊处理、取反的方括号表达式也受换行敏感匹配影响、先行和后行约束中对圆括号及反向引用的限制,以及采用最长或最短匹配而非首次匹配的语义。 @@ -6389,7 +6405,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 基本正则表达式 - BREs 在几个方面和 ERE 不太一样。在 BRE 中,|+?都是普通字符并且没有与它们功能等价的东西。范围的定界符是\{\}, 因为 {}本身是普通字符。嵌套的子表达式的圆括号是\(\),因为()自身是普通字符。除非在 RE 开头或者是圆括号子表达式开头,^都是一个普通字符。 除非在 RE 结尾或者是圆括号子表达式的结尾,$是一个普通字符。如果*出现在 RE 开头或者是圆括号封装的子表达式开头 (前面可能有^),那么它是个普通字符。最后,可以用单数字的反向引用,\<\>分别是[[:<:]][[:>:]]的同义词;在 BRE 中没有其它可用的转义。 + BRE 在几个方面和 ERE 不太一样。在 BRE 中,|+?都是普通字符并且没有与它们功能等价的东西。范围的定界符是\{\},而{}本身是普通字符。嵌套的子表达式的圆括号是\(\),而()自身是普通字符。除非在 RE 开头或者是圆括号子表达式开头,^都是一个普通字符。 除非在 RE 结尾或者是圆括号子表达式的结尾,$是一个普通字符。如果*出现在 RE 开头或者是圆括号封装的子表达式开头 (前面可能有^),那么它是个普通字符。最后,可以用单数字的反向引用,\<\>分别是[[:<:]][[:>:]]的同义词;在 BRE 中没有其它可用的转义。 @@ -6445,7 +6461,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); SQL标准 - PostgreSQL + PostgreSQL @@ -6502,16 +6518,13 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 使用\p{UnicodeProperty}或其反义\P{UnicodeProperty}来定义XQuery字符类元素是不被支持的。 + 使用\p{UnicodeProperty}或其取反形式\P{UnicodeProperty}来定义XQuery字符类元素是不被支持的。 - POSIX解释字符类,如\w - (参见) - 根据当前区域设置(你可以通过将COLLATE子句附加到操作符或函数上来控制)。 - XQuery通过参考Unicode字符属性来指定这些类别,因此只有遵循Unicode规则的区域设置才能获得等效行为。 + POSIX 根据当前区域设置解释\w等字符类(参见);你可以通过为操作符或函数附加COLLATE子句来控制该区域设置。XQuery 根据 Unicode 字符属性定义这些类,因此只有使用遵循 Unicode 规则的区域设置时,才能得到等效行为。 @@ -6524,10 +6537,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 在描述的字符输入转义中 - 中, - XQuery仅支持\n\r, - 和\t。 + 在描述的字符输入转义中,XQuery 仅支持 \n\r\t @@ -6539,7 +6549,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - XQuery没有前瞻或后顾约束,也没有在中描述的任何约束转义。 + XQuery没有先行或后行约束,也没有在中描述的任何约束转义。 @@ -6559,7 +6569,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); XQuery的s(允许点匹配换行符) 和m(允许^ - 和$匹配换行符)标志提供 + 和$在换行处匹配)标志提供 与POSIX的npw标志相同的行为,但它们 匹配POSIX的sm标志的行为。 @@ -6590,11 +6600,11 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 数据类型格式化函数 - formatting + 格式化 - PostgreSQL格式化函数提供一套强大的工具用于把各种数据类型 (日期/时间、整数、浮点、数字) 转换成格式化的字符串以及反过来从格式化的字符串转换成 指定的数据类型。列出了这些函数。这些函数都遵循一个公共的调用规范: 第一个参数是待格式化的值,而第二个是一个定义输出或输入格式的模板。 + PostgreSQL格式化函数提供一套强大的工具用于把各种数据类型 (日期/时间、整数、浮点数、数值) 转换成格式化的字符串以及反过来从格式化的字符串转换成 指定的数据类型。列出了这些函数。这些函数都遵循一个公共的调用规范: 第一个参数是待格式化的值,而第二个是一个定义输出或输入格式的模板。 @@ -6645,7 +6655,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); text - 根据给定的格式将间隔转换为字符串。 + 根据给定的格式将时间间隔转换为字符串。 to_char(interval '15h 2m 12s', 'HH24:MI:SS') @@ -6701,7 +6711,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); numeric - 根据给定的格式将字符串转换为数字。 + 根据给定的格式将字符串转换为数值。 to_number('12,454.8-', '99G999D9S') @@ -6742,7 +6752,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 展示了可以用于格式化日期和时间值的模版。 + 展示了可以用于格式化日期和时间值的模板模式。
@@ -6825,24 +6835,24 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); SSSS, SSSSS - 午夜后的秒 (0–86399) + 自午夜起的秒数 (0–86399) AM, am, - PM or pm - 正午指示器(不带句号) + PMpm + 上午/下午标记(不带句点) A.M., a.m., - P.M. or p.m. - 正午指示器(带句号) + P.M.p.m. + 上午/下午标记(带句点) Y,YYY - 带逗号的年(4 位或者更多位) with comma + 带逗号的年(4 位或者更多位) @@ -6899,17 +6909,17 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); MONTH - 全大写形式的月名(空格补齐到 9 字符) + 大写的月份全称(空格补齐到 9 字符) Month - 全首字母大写形式的月名(空格补齐到 9 字符) + 首字母大写的月份全称(空格补齐到 9 字符) month - 全小写形式的月名(空格补齐到 9 字符) + 小写的月份全称(空格补齐到 9 字符) @@ -6934,72 +6944,72 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); DAY - 全大写形式的日名(空格补齐到 9 字符) + 大写的星期全称(空格补齐到 9 字符) Day - 全首字母大写形式的日名(空格补齐到 9 字符) + 首字母大写的星期全称(空格补齐到 9 字符) day - 全小写形式的日名(空格补齐到 9 字符) + 小写的星期全称(空格补齐到 9 字符) DY - 简写的大写形式的日名(英语 3 字符,本地化长度可变) + 大写的星期简称(英语 3 字符,本地化长度可变) Dy - 简写的首字母大写形式的日名(英语 3 字符,本地化长度可变) + 首字母大写的星期简称(英语 3 字符,本地化长度可变) dy - 简写的小写形式的日名(英语 3 字符,本地化长度可变) + 小写的星期简称(英语 3 字符,本地化长度可变) DDD - 一年中的日(001–366) + 年内日序数(001–366) IDDD - ISO 8601 周编号方式的年中的日 (001–371; 年的第 1 日时第一个 ISO 周的周一) + ISO 8601 周编号方式的年中的日 (001–371; 年的第 1 日是第一个 ISO 周的周一) DD - 月中的日 (01–31) + 月内日序数 (01–31) D - 周中的日,周日 (1) 到周六 (7) + 星期几,周日 (1) 到周六 (7) ID - 周中的 ISO 8601 日,周一 (1) 到周日 (7) + ISO 8601 星期几,周一 (1) 到周日 (7) W - 月中的周 (1–5) (第一周从该月的第一天开始) + 月内周序数 (1–5) (第一周从该月的第一天开始) WW - 年中的周数 (1–53) (第一周从该年的第一天开始) + 年中的周编号 (1–53) (第一周从该年的第一天开始) IW - ISO 8601 周编号方式的年中的周数 (01–53; 新的一年的第一个周四在第一周) + ISO 8601 周编号方式的年中的周编号 (01–53; 新的一年的第一个周四在第一周) @@ -7029,12 +7039,12 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); TZ - 大写形式的时区缩写(仅在to_char中支持) + 大写形式的时区缩写 tz - 小写形式的时区缩写(仅在to_char中支持) + 小写形式的时区缩写 @@ -7049,24 +7059,24 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); OF - 从UTC开始的时区偏移(仅在to_char中支持) + 相对于 UTC 的时区偏移(HHHH:MM
- 修饰语可以被应用于模板模式来修改它们的行为。例如,FMMonth就是带着FM修饰语的Month模式。展示了可用于日期/时间格式化的修饰语模式。 + 修饰符可以被应用于模板模式来修改它们的行为。例如,FMMonth就是带着FM修饰符的Month模式。展示了可用于日期/时间格式化的修饰符模式。 - 用于日期/时间格式化的模板模式修饰语 + 用于日期/时间格式化的模板模式修饰符 - 修饰语 + 修饰符 描述 示例 @@ -7074,37 +7084,37 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - FM prefix + FM 前缀 填充模式(抑制前导零和填充的空格) FMMonth - TH suffix + TH 后缀 大写形式的序数后缀 - DDTH, e.g., 12TH + DDTH,例如, 12TH - th suffix + th 后缀 小写形式的序数后缀 - DDth, e.g., 12th + DDth,例如, 12th - FX prefix - 固定的格式化全局选项(见使用须知) + FX 前缀 + 固定格式全局选项(见使用须知) FX Month DD Day - TM prefix - 翻译模式(基于使用本地化的日和月名) + TM 前缀 + 翻译模式(基于使用本地化的星期名和月份名) TMMonth - SP suffix + SP 后缀 拼写模式(未实现) DDSP @@ -7121,8 +7131,8 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); FM抑制了在模式输出中添加前导零和尾随空格的行为,这些前导零和尾随空格 本来会被添加以使输出成为固定宽度。在PostgreSQL中, - FM仅修改下一个规范,而在Oracle中FM影响所有后续 - 规范,并且重复的FM修饰符切换填充模式的开启和关闭。 + FM仅修改下一个格式说明,而在Oracle中FM影响所有后续 + 格式说明,并且重复的FM修饰符切换填充模式的开启和关闭。 @@ -7180,10 +7190,10 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 一个TZH模板模式可以匹配有符号数。 - 没有FX选项,减号可能会有歧义,并且可能被解释为分隔符。 - 此歧义解决如下:如果模板字符串中TZH之前的分隔符数量少于输入字符串中减号之前的分隔符数量, - 则减号被解释为TZH的一部分。 - 否则,减号被视为值之间的分隔符。 + 没有FX选项,负号可能会有歧义,并且可能被解释为分隔符。 + 此歧义解决如下:如果模板字符串中TZH之前的分隔符数量少于输入字符串中负号之前的分隔符数量, + 则负号被解释为TZH的一部分。 + 否则,负号被视为值之间的分隔符。 例如,to_timestamp('2000 -10', 'YYYY TZH')匹配 -10TZH,但 to_timestamp('2000 -10', 'YYYY  TZH') @@ -7194,12 +7204,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 普通文本允许在to_char模板中,并且将被直接输出。您可以将子字符串放在双引号中, - 以强制将其解释为文字文本,即使它包含模板模式。例如,在'"Hello Year "YYYY'中, - YYYY将被年份数据替换,但Year中的单个Y不会被替换。 - 在to_dateto_numberto_timestamp中, - 文本和双引号字符串会导致跳过字符串中包含的字符数;例如"XX"跳过两个输入字符 - (无论它们是否为XX)。 + 普通文本可以出现在to_char模板中,并会按字面输出。可以用双引号括起子串,使其即使包含模式关键字也强制按字面文本解释。例如,在'"Hello Year "YYYY'中,YYYY会被年份数据替换,但Year中单独的Y不会被替换。在to_dateto_numberto_timestamp中,字面文本和双引号字符串会跳过与该字符串所含字符数相同数量的输入字符;例如,"XX"跳过两个输入字符(无论它们是否为XX)。 @@ -7218,7 +7223,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 如果您想在输出中使用双引号,必须在其前面加上反斜杠,例如'\"YYYY Month\"' - 反斜杠在双引号之外不起特殊作用。在双引号字符串内部,反斜杠会使下一个字符被直接解释,无论是什么(但除非下一个字符是双引号或另一个反斜杠,否则没有特殊效果)。 + 反斜杠在双引号之外不起特殊作用。在双引号字符串内部,反斜杠会使下一个字符被按字面解释,无论是什么(但除非下一个字符是双引号或另一个反斜杠,否则没有特殊效果)。 @@ -7281,14 +7286,14 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 年份、周数和星期几:例如to_date('2006-42-4', 'IYYY-IW-ID') + 年份、周编号和星期几:例如to_date('2006-42-4', 'IYYY-IW-ID') 返回日期2006-10-19。 如果省略星期几,则假定为1(星期一)。 - 年份和年内天数:例如to_date('2006-291', 'IYYY-IDDD')也返回2006-10-19。 + 年份和年内日序数:例如to_date('2006-291', 'IYYY-IDDD')也返回2006-10-19 @@ -7296,14 +7301,14 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 尝试使用ISO 8601周编号字段和公历日期字段的混合输入日期是荒谬的,并将导致错误。 - 在ISO 8601周编号年的背景下,月份日期的概念没有意义。 + 在ISO 8601周编号年的背景下,月份月内日序数的概念没有意义。 在公历年的背景下,ISO周没有意义。 - 当to_date拒绝混合使用公历和ISO周编号日期字段时, - to_char不会,因为输出格式规范如YYYY-MM-DD (IYYY-IDDD)可能很有用。 + 虽然to_date会拒绝混合使用公历和ISO周编号日期字段, + 但to_char不会,因为输出格式规范如YYYY-MM-DD (IYYY-IDDD)可能很有用。 但要避免编写类似IYYY-MM-DD的内容;那会在年初附近产生令人惊讶的结果。 (有关更多信息,请参见。) @@ -7322,7 +7327,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 这是一个更复杂的示例: to_timestamp('15:12:02.020.001230', 'HH24:MI:SS.MS.US') - 是15小时,12分钟和2秒 + 20毫秒 + 1230微秒 = 2.021230秒。 + 为15小时12分钟,秒数为2秒 + 20毫秒 + 1230微秒 = 2.021230秒。 @@ -7330,7 +7335,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); to_char(..., 'ID')的星期几编号与extract(isodow from ...)函数匹配, - 但to_char(..., 'D')的不匹配extract(dow from ...)的星期编号。 + 但to_char(..., 'D')的不匹配extract(dow from ...)的星期几编号。 @@ -7347,12 +7352,12 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 展示了可以用于格式化数字值的模版模式。 + 展示了可以用于格式化数值的模板模式。
- 用于数字格式化的模板模式 + 用于数值格式化的模板模式 @@ -7365,21 +7370,21 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 9 - 数位(如果无意义可以被删除) + 数位(非有效位可以被省略) 0 - 数位(即便没有意义也不会被删除) + 数位(即便是非有效位也不会被省略) - . (period) + .(句点) 小数点 - , (comma) + ,(逗号) 分组(千)分隔符 @@ -7390,22 +7395,22 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); S - 带符号的数字(使用区域) + 紧贴数值的正负号(使用区域设置) L - 货币符号(使用区域) + 货币符号(使用区域设置) D - 小数点(使用区域) + 小数点(使用区域设置) G - 分组分隔符(使用区域) + 分组分隔符(使用区域设置) @@ -7429,7 +7434,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - TH or th + THth 序数后缀 @@ -7447,7 +7452,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}');
- 数字格式化的使用注意事项: + 数值格式化的使用注意事项: @@ -7463,14 +7468,14 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 如果格式提供的小数位数少于被格式化的数字,则to_char()将会将数字四舍五入到指定的小数位数。 + 如果格式指定的小数位数少于被格式化数值的小数位数,to_char()会将该数值舍入到指定的小数位数。 - 模式字符SLDG表示当前区域设置定义的符号、货币符号、小数点和千位分隔符字符 + 模式字符SLDG表示当前区域设置定义的正负号、货币符号、小数点和千位分隔符字符 (参见)。模式字符句点和逗号表示这些确切字符,具有小数点和千位分隔符的含义,不受区域设置影响。 @@ -7479,15 +7484,14 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 如果在to_char()的模式中没有明确指定符号,将为符号保留一列,并将其锚定到(出现在)数字的左侧。 - 如果S出现在一些9的左侧,它也将锚定到数字。 + 如果to_char()的模式中没有明确指定正负号的位置,就会为正负号保留一列,并使其紧贴数值(紧靠数值左侧)。如果S紧邻若干个9的左侧,它同样会紧贴数值。 - 使用SGPLMI格式化的符号不与数字绑定; + 使用SGPLMI格式化的正负号不紧贴数值; 例如,to_char(-12, 'MI9999')会产生'-  12', 但to_char(-12, 'S9999')会产生'  -12'。 (Oracle实现不允许在9之前使用MI,而是要求9MI之前。) @@ -7514,7 +7518,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); to_number函数中,如果使用非数据模板模式,如LTH, - 则会跳过相应数量的输入字符,无论它们是否与模板模式匹配,除非它们是数据字符(即数字、符号、小数点或逗号)。 + 则会跳过相应数量的输入字符,无论它们是否与模板模式匹配,除非它们是数据字符(即数字、正负号、小数点或逗号)。 例如,TH会跳过两个非数据字符。 @@ -7525,7 +7529,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); Vto_char一起, 将输入值乘以10^n, 其中n是跟在V后面的数字位数。 - Vto_number一起以类似的方式除法。 + Vto_number一起以类似的方式进行除法。 to_charto_number不支持与小数点结合使用的V (例如,不允许使用99.9V99)。 @@ -7541,17 +7545,17 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}');
- 某些修饰语可以被应用到任何模板来改变其行为。例如,FM99.99是带有FM修饰语的99.99模式。中展示了用于数字格式化模式修饰语。 + 某些修饰符可以被应用到任何模板来改变其行为。例如,FM99.99是带有FM修饰符的99.99模式。中展示了用于数值格式化的模式修饰符。 - 用于数字格式化的模板模式修饰语 + 用于数值格式化的模板模式修饰符 - 修饰语 + 修饰符 描述 示例 @@ -7559,19 +7563,19 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - FM prefix - 填充模式(抑制拖尾零和填充的空白) + FM 前缀 + 填充模式(抑制尾随零和填充的空白) FM99.99 - TH suffix + TH 后缀 大写序数后缀 999TH - th suffix + th 后缀 小写序数后缀 999th @@ -7604,6 +7608,13 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 'Tuesday, 6  05:39:18' + to_char(current_timestamp AT TIME ZONE + 'UTC', 'YYYY-MM-DD"T"HH24:MI:SS"Z"') + '2022-12-06T05:39:18Z', + ISO 8601 扩展格式 + + + to_char(-0.1, '99.99') '  -.10' @@ -7755,10 +7766,10 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 时间/日期函数和操作符 + 日期/时间函数和操作符 - 展示了可用于处理日期/时间值的函数,其细节在随后的小节中描述。演示了基本算术操作符 (+*等)的行为。 而与格式化相关的函数,可以参考。你应该很熟悉中的日期/时间数据类型的背景知识。 + 展示了可用于处理日期/时间值的函数,其细节在随后的小节中描述。演示了基本算术操作符 (+*等)的行为。 而与格式化相关的函数,可以参考。你应当熟悉中的日期/时间数据类型的背景知识。 @@ -7844,7 +7855,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); interval - 添加时间间隔 + 将两个时间间隔相加 interval '1 day' + interval '1 hour' @@ -7886,7 +7897,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); interval - 取否一个时间间隔 + 对时间间隔取负 - interval '23 hours' @@ -7900,7 +7911,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); integer - 减去日期,生成经过的天数 + 将两个日期相减,得到相隔的天数 date '2001-10-01' - date '2001-09-28' @@ -7942,7 +7953,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); interval - 减去时间 + 将两个时间相减 time '05:00' - time '03:00' @@ -7984,7 +7995,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); interval - 减去时间间隔 + 将两个时间间隔相减 interval '1 day' - interval '1 hour' @@ -7998,12 +8009,12 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); interval - 减去时间戳(将24小时间隔转换为天数,类似于justify_hours() - 时间戳 '2001-09-29 03:00' - 时间戳 '2001-07-27 12:00' - 63 天 15:00:00 + timestamp '2001-09-29 03:00' - timestamp '2001-07-27 12:00' + 63 days 15:00:00 @@ -8013,7 +8024,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); interval - 将时间间隔乘以数量 + 将时间间隔乘以一个标量 interval '1 second' * 900 @@ -8035,7 +8046,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); interval - 用时间间隔除以数量 + 将时间间隔除以一个标量 interval '1 hour' / 1.5 @@ -8076,7 +8087,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); interval - 减去参数,生成一个使用年和月,而不是只用日的符号化的结果 + 将两个参数相减,生成一个使用年和月,而不是只用日的符号化的结果 age(timestamp '2001-04-10', timestamp '1957-06-13') @@ -8090,7 +8101,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); interval - 从 current_date 减去参数(在午夜) + 从current_date(午夜时刻)减去参数 age(timestamp '1957-06-13') @@ -8141,7 +8152,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); time with time zone - 一天中的当前时间;参见 + 一天中的当前时刻;参见 current_time @@ -8155,7 +8166,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); time with time zone - 一天中的当前时间;有限精度;参见 + 一天中的当前时刻,精度受限;参见 current_time(2) @@ -8172,7 +8183,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); timestamp with time zone - 当前日期和时间 (当前事务的开始);参见 + 当前日期和时间(当前事务开始时);参见 current_timestamp @@ -8186,7 +8197,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); timestamp with time zone - 当前日期和时间 (当前事务的开始);有限精度;参见 + 当前日期和时间(当前事务开始时),精度受限;参见 current_timestamp(0) @@ -8234,7 +8245,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); double precision - 获取时间戳字段 (等同于 extract);参见 + 获取时间戳子字段 (等同于 extract);参见 date_part('hour', timestamp '2001-02-16 20:38:40') @@ -8358,7 +8369,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); boolean - 测试有限日期(不是+/-无限) + 测试日期是否有限(不是正负无穷) isfinite(date '2001-02-16') @@ -8372,7 +8383,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); boolean - 测试有限时间戳(不是+/-无限) + 测试时间戳是否有限(不是正负无穷) isfinite(timestamp 'infinity') @@ -8386,7 +8397,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); boolean - 测试有限时间间隔 (当前总是为真) + 测试时间间隔是否有限(不是正负无穷) isfinite(interval '4 hours') @@ -8439,7 +8450,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); interval - 使用 justify_daysjustify_hours调整时间间隔; 通过额外的符号调整 + 使用 justify_daysjustify_hours调整时间间隔,并额外调整符号 justify_interval(interval '1 mon -1 hour') @@ -8456,7 +8467,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); time - 一天中当前时间;参见 + 一天中的当前时刻;参见 localtime @@ -8470,7 +8481,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); time - 一天中的当前时间,有限精度;参见 + 一天中的当前时刻,精度受限;参见 localtime(0) @@ -8487,7 +8498,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); timestamp - 当前日期和时间(当前事务的开始);参见 + 当前日期和时间(当前事务开始时);参见 localtimestamp @@ -8501,7 +8512,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); timestamp - 当前日期和时间(当前事务的开始);有限精度;参见 + 当前日期和时间(当前事务开始时),精度受限;参见 localtimestamp(2) @@ -8629,7 +8640,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); timestamp with time zone - 当前日期和时间(当前事务的开始);参见 + 当前日期和时间(当前事务开始时);参见 now() @@ -8646,7 +8657,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); timestamp with time zone - 当前日期和时间(当前语句的开始);参见 + 当前日期和时间(当前语句开始时);参见 statement_timestamp() @@ -8681,7 +8692,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); timestamp with time zone - 当前日期和时间(当前事务的开始);参见 + 当前日期和时间(当前事务开始时);参见 transaction_timestamp() @@ -8698,7 +8709,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); timestamp with time zone - 将Unix纪元转换为带时区的时间戳(从1970-01-01 00:00:00+00开始的秒) + 将 Unix 纪元时间(自 1970-01-01 00:00:00+00 起的秒数)转换为带时区的时间戳 to_timestamp(1284352323) @@ -8718,7 +8729,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); (start1, end1) OVERLAPS (start2, end2) (start1, length1) OVERLAPS (start2, length2) - 这个表达式在两个时间域(用它们的端点定义)重叠的时候得到真,当它们不重叠时得到假。端点可以用一对日期、时间或者时间戳来指定;或者是用一个后面跟着一个间隔的日期、时间或时间戳来指定。当一对值被提供时,起点或终点都可以被写在前面,OVERLAPS会自动地把较早的值作为起点。每一个时间段被认为是表示半开的间隔start <= time < end,除非startend相等,这种情况下它表示单个时间实例。例如这表示两个只有一个共同端点的时间段不重叠。 + 这个表达式在两个时间段(用它们的端点定义)重叠的时候得到真,当它们不重叠时得到假。端点可以用一对日期、时间或者时间戳来指定;或者是用一个后面跟着一个间隔的日期、时间或时间戳来指定。当一对值被提供时,起点或终点都可以被写在前面,OVERLAPS会自动地把较早的值作为起点。每一个时间段被认为是表示半开区间start <= time < end,除非startend相等,这种情况下它表示单个时刻。例如这表示两个只有一个共同端点的时间段不重叠。 @@ -8737,16 +8748,19 @@ SELECT (DATE '2001-10-30', DATE '2001-10-30') OVERLAPS - 当把一个interval值添加到timestamp with time zone上(或从中减去)时,天这一部分会按照指定的天数增减该timestamp with time zone的日期,同时保持一天中的时间不变。 - 对于跨越夏令时变更的情况(当会话时区被设置为能够识别 DST 的时区时),这意味着interval '1 day'并不一定等于interval '24 hours'。 - 例如,当会话的时区设置为America/Denver时: + 当把一个interval值加到timestamptimestamp with time zone值上(或从中减去一个interval值)时,会依次处理interval值的月、日和微秒字段。 + 首先,非零的月字段会按指定月数增减时间戳的日期,同时保持其在月份中的日不变;如果该日超出了新月份的月末,则使用该月的最后一天。(例如,3 月 31 日加 1 个月得到 4 月 30 日,加 2 个月则得到 5 月 31 日。) + 然后,日字段会按指定天数增减时间戳的日期。在这两个步骤中,一天中的本地时刻保持不变。最后,如果微秒字段不为零,则直接加上或减去该值。 + 在识别夏令时的时区中对timestamp with time zone值进行运算时,这意味着加上或减去(例如)interval '1 day'与加上或减去interval '24 + hours'的结果不一定相同。 + 例如,当会话时区设为America/Denver时: SELECT timestamp with time zone '2005-04-02 12:00:00-07' + interval '1 day'; 结果:2005-04-03 12:00:00-06 SELECT timestamp with time zone '2005-04-02 12:00:00-07' + interval '24 hours'; 结果:2005-04-03 13:00:00-06 - - 发生这种情况是因为在America/Denver时区,夏令时在2005-04-03 02:00:00发生切换,导致跳过了一个小时。 + + 发生这种情况是因为在2005-04-03 02:00:00America/Denver时区切换了夏令时,跳过了一个小时。 @@ -8754,15 +8768,9 @@ SELECT timestamp with time zone '2005-04-02 12:00:00-07' + interval '24 hours'; - 日期和时间戳的减法也可能会很复杂。执行减法的一种概念上很简单的方法是,使用 - EXTRACT(EPOCH FROM ...)把每个值都转换成秒数,然后执行减法, - 这样会得到两个值之间的数。这种方法将会适应每个月中天数、 - 时区改变和夏令时调整。使用-操作符的日期或时间 - 戳减法会返回值之间的天数(24小时)以及时/分/秒,也会做同样的调整。 - age函数会返回年、月、日以及时/分/秒,执行按域的减法,然后对 - 负值域进行调整。下面的查询展示了这些方法的不同。示例中的结果由 - timezone = 'US/Eastern'产生,这使得两个使用的日期之间存在着夏令 - 时的变化: + 日期和时间戳的减法也可能很复杂。一种概念上简单的方法是,先用EXTRACT(EPOCH FROM ...)将各值转换为秒数,然后将结果相减;这样得到的是两个值之间的数。这种方法会针对每个月的天数、时区变化和夏令时变化进行调整。 + 用-操作符将日期或时间戳值相减,会返回两个值之间的天数(每一天为 24 小时)和时/分/秒,也会作相同的调整。age函数返回年、月、日和时/分/秒,它会逐字段相减,然后调整负值字段。 + 以下查询显示了这些方法的差异。示例结果在timezone = 'US/Eastern'设置下产生;所用的两个日期之间发生了夏令时切换: @@ -8814,7 +8822,7 @@ EXTRACT(field FROM source) - 这个世纪;对于interval值,年份字段除以100 + 世纪;对于interval值,年份字段除以100 @@ -8837,7 +8845,7 @@ SELECT EXTRACT(CENTURY FROM INTERVAL '2001 years'); - 月份的日期(1–31);对于interval值,表示天数 + 一个月中的第几天(1–31);对于interval值,表示天数 @@ -8890,7 +8898,7 @@ SELECT EXTRACT(DOW FROM TIMESTAMP '2001-02-16 20:38:40'); - 一年中的日子(1-365/366) + 一年中的第几天(1–365/366) @@ -8905,7 +8913,7 @@ SELECT EXTRACT(DOY FROM TIMESTAMP '2001-02-16 20:38:40'); - 对于timestamp with time zone值,自1970-01-01 00:00:00 UTC以来的秒数(负值表示该时间戳之前的时间); + 对于timestamp with time zone值,自1970-01-01 00:00:00 UTC以来的秒数(早于该时刻的时间戳对应负值); 对于datetimestamp值,自1970-01-01 00:00:00以来的名义秒数,不考虑时区或夏令时规则; 对于interval值,间隔中的总秒数 @@ -8929,8 +8937,8 @@ SELECT to_timestamp(982384720.12); - 注意,将to_timestamp应用于从datetimestamp值中提取的时代可能会产生误导性的结果: - 结果将有效地假定原始值是以UTC时间给出的,这可能并非事实。 + 注意,将to_timestamp应用于从datetimestamp值中提取的 epoch 值可能会产生误导性的结果: + 结果实际上会假定原始值是以UTC时间给出的,这可能并非事实。 @@ -8986,8 +8994,7 @@ SELECT EXTRACT(ISOYEAR FROM DATE '2006-01-02'); - 每个ISO 8601周编号年从包含1月4日的星期一开始,因此在一月初或十二月底,ISO年可能与格里高利年不同。 - 有关更多信息,请参见week字段。 + 每个 ISO 8601 周编号年都从包含 1 月 4 日的那一周的星期一开始,因此在 1 月初或 12 月末,ISO 年可能与格里高利年不同。更多信息请参见 week 字段。 @@ -9030,7 +9037,7 @@ SELECT EXTRACT(MICROSECONDS FROM TIME '17:12:28.5'); - 千年; 对于interval值,年份字段除以1000 + 千年; 对于interval值,年份字段除以1000 @@ -9041,7 +9048,7 @@ SELECT EXTRACT(MILLENNIUM FROM INTERVAL '2001 years'); - 20世纪的年份在第二个千年。第三个千年从2001年1月1日开始。 + 1900 年代的年份属于第二个千年。第三个千年始于 2001 年 1 月 1 日。 @@ -9051,7 +9058,7 @@ SELECT EXTRACT(MILLENNIUM FROM INTERVAL '2001 years'); - 第二个字段,包括小数部分,乘以1000。请注意,这包括完整的秒数。 + 秒字段,包括小数部分,乘以1000。请注意,这包括完整的秒数。 @@ -9081,7 +9088,7 @@ SELECT EXTRACT(MINUTE FROM TIMESTAMP '2001-02-16 20:38:40'); - 月份在一年中的编号(1-12);对于interval值,月份模12的余数(0-11) + 月份在一年中的编号(1–12);对于interval值,月份模12的余数(0–11) @@ -9100,7 +9107,7 @@ SELECT EXTRACT(MONTH FROM INTERVAL '2 years 13 months'); - 日期所在的年份季度(1-4) + 日期所在的年份季度(1–4) @@ -9142,7 +9149,7 @@ SELECT EXTRACT(SECOND FROM TIME '17:12:28.5'); - 时间区偏移的小时组件 + 时区偏移的小时部分 @@ -9152,7 +9159,7 @@ SELECT EXTRACT(SECOND FROM TIME '17:12:28.5'); - 时间区偏移的分钟组件 + 时区偏移的分钟部分 @@ -9162,16 +9169,11 @@ SELECT EXTRACT(SECOND FROM TIME '17:12:28.5'); - 一年中ISO 8601周编号周的数量。根据定义,ISO周从周一开始, - 一年的第一周包含该年的1月4日。换句话说,一年的第一个星期四在该年的第1周。 + 一年中按ISO 8601 周编号体系计算的周序号。根据定义,ISO 周从周一开始,一年的第一周包含该年的 1 月 4 日。换句话说,一年的第一个星期四在该年的第 1 周。 - 在ISO周编号系统中,早年1月的日期可能属于前一年的第52周或第53周,而 - 晚年12月的日期可能属于下一年的第一周。例如,2005-01-01 - 属于2004年的第53周,2006-01-01 属于2005年的第52周, - 而2012-12-31 属于2013年的第一周。建议同时使用 - isoyear 字段和week以获得一致的结果。 + 在 ISO 周编号体系中,1 月初的日期可能属于前一年的第 52 周或第 53 周,而 12 月末的日期可能属于下一年的第一周。例如,2005-01-01属于 2004 年的第 53 周,2006-01-01属于 2005 年的第 52 周,而2012-12-31属于 2013 年的第一周。建议将isoyear字段与week一起使用,以获得一致的结果。 @@ -9186,7 +9188,7 @@ SELECT EXTRACT(WEEK FROM TIMESTAMP '2001-02-16 20:38:40'); - 年份字段。请记住,没有0 AD,所以要小心地从AD年中减去BC年。 + 年份字段。请记住,没有0 AD,所以把BC年份从AD年份中减去时需要小心。 @@ -9213,7 +9215,8 @@ SELECT EXTRACT(MINUTES FROM INTERVAL '80 minutes'); - 当输入值为 +/-Infinity 时,extract对于单调增的域(epochjulianyearisoyeardecadecentury以及millennium)返回 +/-Infinity。对于其他域返回 NULL。PostgreSQL 9.6 之前的版本对所有输入无穷的情况都返回零。 + 当输入值为 +/-Infinity 时,extract对单调递增的字段返回 +/-Infinity(对于timestamp输入,这些字段为epochjulianyearisoyeardecadecenturymillennium;对于interval输入,这些字段为epochhourdayyeardecadecenturymillennium)。 + 对于其他字段,返回 NULL。PostgreSQL 9.6 之前的版本对所有无穷输入都返回零。 @@ -9222,15 +9225,12 @@ SELECT EXTRACT(MINUTES FROM INTERVAL '80 minutes'); - 在传统的Ingres上建模的date_part函数等价于SQL标准函数extract: + date_part函数仿照传统的Ingres实现,后者对应SQL标准的extract函数: date_part('field', source) - 请注意这里的field参数必须是一个串值,而不是一个名字。 - 有效的date_part域名 和extract相同。 - 由于历史原因,date_part函数返回double precision类型的值。 - 这可能导致在某些使用中损失精度。 - 建议使用extract替代。 + 注意,此处的field参数必须是字符串值,而不能是名称。date_part的有效字段名与extract相同。 + 由于历史原因,date_part函数返回double precision类型的值,可能在某些用途中损失精度。建议改用extract @@ -9257,11 +9257,12 @@ SELECT date_part('hour', INTERVAL '4 hours 3 minutes'); date_trunc(field, source [, time_zone ]) - source是类型timestampinterval的值表达式(类型datetime的值都分别被自动转换成timestamp, timestamp with time zone,或者interval)。field选择对输入值选用什么样的精度进行截断。返回的值是timestamp, timestamp with time zone,类型或者所有小于选定的 精度的域都设置为零(或者一,对于日期和月份)的interval。 + sourcetimestamptimestamp with time zoneinterval类型的值表达式。(datetime类型的值会分别自动转换为timestampinterval。) + field选择输入值的截断精度。返回值同样为timestamptimestamp with time zoneinterval类型,其中低于所选精度的所有字段都设为零(日和月则设为一)。 - field的有效值是∶ + field的有效值是: microseconds milliseconds @@ -9280,7 +9281,7 @@ date_trunc(field, source [ - 当输入值的类型为timestamp with time zone时。截断是针对特定时区进行的。 例如,截断为day,产生的值是 是该区域的午夜。 默认情况下,截断是在以下方面进行的 到当前的设置,但在当前的 可以提供可选的time_zone参数。以指定不同的时区。 可以指定时区名称 中描述的任何一种方式。 + 当输入值为timestamp with time zone类型时,截断会以特定时区为准;例如,截断到day会得到该时区的午夜。默认情况下,截断以当前的设置为准,但可以通过可选的time_zone参数指定其他时区。时区名称可以用中描述的任意方式指定。 @@ -9322,11 +9323,11 @@ date_bin(stride, source, < sourcetimestamptimestamp with time zone类型的值表达式。 (类型date的值会自动转换为timestamp。) strideinterval类型的值表达式。 - 返回值同样是timestamptimestamp with time zone类型,并且它标记着放置source的bin的开始。 + 返回值同样是timestamptimestamp with time zone类型,并且它表示source所在分箱的起点。 - 示例: + 示例: SELECT date_bin('15 minutes', TIMESTAMP '2020-02-11 15:44:17', TIMESTAMP '2001-01-01'); 结果: 2020-02-11 15:30:00 @@ -9348,8 +9349,8 @@ SELECT date_bin('15 minutes', TIMESTAMP '2020-02-11 15:44:17', TIMESTAMP '2001-0 <literal>AT TIME ZONE</literal> 和 <literal>AT LOCAL</literal> - time zone - conversion + 时区 + 转换 @@ -9361,7 +9362,7 @@ SELECT date_bin('15 minutes', TIMESTAMP '2020-02-11 15:44:17', TIMESTAMP '2001-0 - AT TIME ZONE 操作符可在带时区和不带时区的时间戳之间进行转换,也可将 time with time zone 值转换到不同的时区。 展示了它的各种变体。 + AT TIME ZONE 操作符可将不带时区的时间戳转换为时区的时间戳或反向转换,也可将 time with time zone 值转换到不同的时区。 展示了它的各种变体。
@@ -9461,7 +9462,7 @@ SELECT date_bin('15 minutes', TIMESTAMP '2020-02-11 15:44:17', TIMESTAMP '2001-0 time with time zone - 将给定的带时区时间转换到新的时区,所用时区为会话的 TimeZone 值。由于没有提供日期,这会使用会话 TimeZone 当前生效的 UTC 偏移量。 + 将给定的带时区时间转换到新的时区。由于没有提供日期,这会使用会话 TimeZone 值当前生效的 UTC 偏移量。 假定会话的 TimeZone 设为 UTC: @@ -9497,30 +9498,35 @@ SELECT TIMESTAMP '2001-02-16 20:38:40' AT TIME ZONE 'Asia/Tokyo' AT TIME ZONE 'A SELECT TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40-05' AT LOCAL; 结果:2001-02-16 17:38:40 SELECT TIME WITH TIME ZONE '20:38:40-05' AT LOCAL; -结果:17:38:40-08 +结果:17:38:40 第一个示例为缺少时区的值添加时区,并使用当前的 TimeZone 设置显示该值。 - 第二个示例将带时区的时间戳值转换到指定时区,并返回无时区的值。 + 第二个示例将带时区的时间戳值转换到指定时区,并返回不带时区的值。 + 这样就可以存储和显示与当前 TimeZone 设置不同的值。 + 第三个示例将东京时间转换为芝加哥时间。 + 第四个示例将带时区的时间戳值转换到当前 TimeZone 设置指定的时区,并返回不带时区的值。 - 函数timezone(zone, timestamp)等效于 SQL 兼容的结构timestamp AT TIME ZONE zone。 + 第五个示例需要注意。由于输入值不包含日期,转换使用会话的当前日期。 + 因此,根据查看本示例时处于一年中的哪个时段,这个静态示例可能显示错误的结果,因为 + 'America/Los_Angeles' 实行夏令时。 - 结构 timestamp AT LOCAL 等效于 timestamp AT TIME ZONE local。 + 函数timezone(zone, timestamp)等效于符合 SQL 标准的结构timestamp AT TIME ZONE zone - 函数timezone(zone, timestamp with time zone)等效于 SQL 兼容的结构timestamp with time zone AT TIME ZONE zone。 + 函数timezone(zone, time)等效于符合 SQL 标准的结构time AT TIME ZONE zone - 结构 timestamp with time zone AT LOCAL 等效于 timestamp with time zone AT TIME ZONE local。 + 函数timezone(timestamp)等效于符合 SQL 标准的结构timestamp AT LOCAL - 函数timezone(zone, time with time zone)等效于 SQL 兼容的结构time with time zone AT TIME ZONE zone。结构 time with time zone AT LOCAL 等效于 time with time zone AT TIME ZONE local。 + 函数timezone(time)等效于符合 SQL 标准的结构time AT LOCAL @@ -9529,13 +9535,13 @@ SELECT TIME WITH TIME ZONE '20:38:40-05' AT LOCAL; 当前日期/时间 - date - current + 日期 + 当前 - time - current + 时间 + 当前 @@ -9554,15 +9560,15 @@ LOCALTIMESTAMP(precision) - CURRENT_TIMECURRENT_TIMESTAMP传递带有时区的值;LOCALTIMELOCALTIMESTAMP传递的值不带时区。 + CURRENT_TIMECURRENT_TIMESTAMP返回带时区的值;LOCALTIMELOCALTIMESTAMP返回不带时区的值。 - CURRENT_TIMECURRENT_TIMESTAMPLOCALTIMELOCALTIMESTAMP可以有选择地接受一个精度参数,该精度会使结果的秒字段圆整到指定的小数位数。如果没有精度参数,结果将给出可用的全部精度。 + CURRENT_TIMECURRENT_TIMESTAMPLOCALTIMELOCALTIMESTAMP可以有选择地接受一个精度参数,该精度会使结果的秒字段舍入到指定的小数位数。如果没有精度参数,结果将给出可用的全部精度。 - 一些示例: + 一些示例: SELECT CURRENT_TIME; 结果: 14:39:53.662522-05 @@ -9584,7 +9590,7 @@ SELECT LOCALTIMESTAMP; - 许多其它数据库系统可能会更频繁地推进这些值。 + 其他数据库系统可能会更频繁地推进这些值。 @@ -9601,11 +9607,11 @@ now() - transaction_timestamp()等价于CURRENT_TIMESTAMP,但是其命名清楚地反映了它的返回值。statement_timestamp()返回当前语句的开始时刻(更准确的说是收到 客户端最后一条命令的时间)。statement_timestamp()transaction_timestamp()在一个事务的第一条命令期间返回值相同,但是在随后的命令中却不一定相同。 clock_timestamp()返回真正的当前时间,因此它的值甚至在同一条 SQL 命令中都会变化。timeofday()是一个有历史原因的PostgreSQL函数。和clock_timestamp()相似,timeofday()也返回真实的当前时间,但是它的结果是一个格式化的text串,而不是timestamp with time zone值。now()PostgreSQL的一个传统,等效于transaction_timestamp()。 + transaction_timestamp()等价于CURRENT_TIMESTAMP,但是其命名清楚地反映了它的返回值。statement_timestamp()返回当前语句的开始时刻(更准确地说,是接收到客户端最近一条命令消息的时间)。statement_timestamp()transaction_timestamp()在一个事务的第一条语句期间返回值相同,但是在随后的语句中却不一定相同。 clock_timestamp()返回真正的当前时间,因此它的值甚至在同一条 SQL 语句中都会变化。timeofday()是一个有历史原因的PostgreSQL函数。和clock_timestamp()相似,它也返回真实的当前时间,但是它的结果是一个格式化的text串,而不是timestamp with time zone值。now()PostgreSQL中与transaction_timestamp()等价的传统函数。 - 所有日期/时间类型还接受特殊的文字值now,用于指定当前的日期和时间(重申,被解释为当前事务的开始时刻)。 因此,下面三个都返回相同的结果: + 所有日期/时间数据类型也都接受特殊字面值now来指定当前日期和时间(同样解释为事务开始时间)。因此,下面三种写法都返回相同的结果: SELECT CURRENT_TIMESTAMP; SELECT now(); @@ -9617,7 +9623,7 @@ SELECT TIMESTAMP 'now'; -- 但请参阅下面的提示 当指定以后要计算的值时,不要使用第三种形式,例如在表列的DEFAULT子句中。 - 系统将在分析这个常量的时候把now转换为一个timestamp, 这样需要默认值时就会得到创建表的时间!而前两种形式要到实际使用缺省值的时候才被计算, 因为它们是函数调用。因此它们可以给出每次插入行的时刻。 + 系统将在分析这个常量的时候把now转换为一个timestamp, 这样需要默认值时就会得到创建表的时间!而前两种形式要到实际使用默认值的时候才被计算, 因为它们是函数调用。因此它们可以给出每次插入行的时刻。 (参见 。) @@ -9640,24 +9646,24 @@ SELECT TIMESTAMP 'now'; -- 但请参阅下面的提示 - sleep + 休眠 - delay + 延迟 - 下面的这些函数可以用于让服务器进程延时执行: + 以下函数可用于延迟服务器进程的执行: pg_sleep ( double precision ) pg_sleep_for ( interval ) pg_sleep_until ( timestamp with time zone ) - pg_sleep使当前会话的进程休眠,直到过去给定的秒数。可以指定几分之一秒的延迟。 - pg_sleep_for是一个方便的函数,允许将睡眠时间指定为时间间隔。 - pg_sleep_until是一个方便的函数,用于需要特定的唤醒时间。例如: + pg_sleep使当前会话的进程休眠,直到经过指定的秒数。可以指定带小数部分的秒数作为延迟时间。 + pg_sleep_for是一个便捷函数,允许以interval指定休眠时间。 + pg_sleep_until是在需要指定唤醒时间时使用的便捷函数。例如: SELECT pg_sleep(1.5); @@ -9692,7 +9698,7 @@ SELECT pg_sleep_until('tomorrow 03:00'); 枚举支持函数 - 对于枚举类型(在中描述), 有一些函数允许更清洁的编码,而不需要为一个枚举类型硬写特定的值。它们被列在中。本例假定一个枚举类型被创建为: + 对于枚举类型(见),有些函数可以避免硬编码枚举类型中的特定值,使程序更简洁。这些函数列在中。以下示例假定枚举类型按如下方式创建: CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple'); @@ -9778,8 +9784,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple anyarray - 以一个数组返回在给定两个枚举值之间的范围。值必须来自相同的枚举类型。 - 如果第一个参数为空,其结果将从枚举类型的第一个值开始。如果第二参数为空,其结果将以枚举类型的最后一个值结束。 + 以有序数组返回两个给定枚举值之间的范围。两个值必须来自同一枚举类型。如果第一个参数为 null,结果从该枚举类型的第一个值开始;如果第二个参数为 null,结果以该枚举类型的最后一个值结束。 enum_range('orange'::rainbow, 'green'::rainbow) @@ -9799,8 +9804,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple
- 请注意,除了双参数形式的enum_range外, 这些函数忽略传递给它们的具体值,它们只关心声明的数据类型。 - 空值或类型的一个特定值可以通过,并得到相同的结果。这些函数更多地被用于一个表列或函数参数,而不是一个硬写的类型名,如示例中所使用。 + 请注意,除了enum_range的双参数形式外,这些函数都忽略传入的具体值,只关心其声明的数据类型。传入 null 或该类型的某个具体值,结果都相同。通常会将这些函数用于表列或函数参数,而不是像示例那样使用硬编码的类型名。
@@ -9811,7 +9815,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple 几何类型pointboxlseglinepath、 - polygoncircle有一大堆本地支持函数和操作符,如中所示。 + polygoncircle有大量内置支持函数和操作符,如中所示。 @@ -9856,7 +9860,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple path - 连接两个打开的路径(如果其中一个路径是关闭的,则返回NULL)。 + 连接两个开放路径(如果任一路径是封闭的,则返回NULL)。 path '[(0,0),(1,1)]' + path '[(2,2),(3,3),(4,4)]' @@ -9885,12 +9889,12 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple geometric_type - 将第一个参数的每个点乘上第二个point(将点视为由实部和虚部表示的复数,并执行标准的复数乘法)。 + 将第一个参数的每个点乘上第二个point(将点视为由实部和虚部表示的复数,并执行标准的复数乘法)。 如果将第二个point解释为向量,这等价于将对象的大小和到原点的距离按向量的长度缩放,并以向量与x轴的夹角绕原点逆时针旋转。 - 适用于point, box,Rotating 用这些操作符“旋转”一个盒子,只会移动它的角点:这个盒子仍然被认为有平行于轴的边。 - 因此,盒子的大小并没有像真正的旋转那样得到保留。 - path, circle.。 + 适用于pointbox用这些操作符旋转一个矩形框,只会移动它的角点:这个矩形框仍然被认为有平行于轴的边。 + 因此,矩形框的大小并没有像真正的旋转那样得到保留。 + pathcircle path '((0,0),(1,0),(1,1))' * point '(3.0,0)' @@ -9909,7 +9913,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple 将第一个参数的每个点除以第二个point(将点视为由实部和虚部表示的复数,并执行标准的复数除法)。 - 如果将第二个point解释为向量,这等价于将物体的大小和到原点的距离按向量的长度向下缩放,并以向量与x轴的夹角围绕原点顺时针旋转。 + 如果将第二个point解释为向量,这等价于将对象的大小和到原点的距离按向量长度的倒数缩放,并以向量与x轴的夹角围绕原点顺时针旋转。 适用于 point, box, path,circle @@ -9986,7 +9990,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple box - 计算两个方框的交集,如果没有则为NULL。 + 计算两个矩形框的交集,如果没有则为NULL。 box '(2,2),(-1,-1)' # box '(1,1),(-2,-2)' @@ -10000,7 +10004,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple point - 计算第一个对象上距离第二个对象最近的点。 + 计算第二个对象上距离第一个对象最近的点。 可用于以下类型的配对: (point, box), (point, lseg), @@ -10022,7 +10026,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple 计算对象之间的距离。 - 对于所有七种几何类型,所有point与另一种几何类型的组合, + 适用于所有七种几何类型,所有point与另一种几何类型的组合, 以及以下这些额外的类型对: (box, lseg), (lseg, line), @@ -10062,7 +10066,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 第一个对象包含在第二个对象之中还是在第二个对象之上? 适用于这些类型对: + 第一个对象是否位于第二个对象内部或其上? 适用于这些类型对: (point, box), (point, lseg), (point, line), @@ -10162,7 +10166,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 第一个对象是否确定位于第二个对象下面? + 第一个对象是否严格位于第二个对象下面? 适用于 point, box, polygon, circle @@ -10177,7 +10181,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 第一个对象是否确定位于第二个对象上面? + 第一个对象是否严格位于第二个对象上面? 适用于 point, box, polygon, circle. @@ -10250,7 +10254,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 这些对象是否相交? 适用于这些类型对: + 这些对象是否相交? 适用于这些类型对: (box, box), (lseg, box), (lseg, lseg), @@ -10275,7 +10279,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 线是水平的? + 线是否水平? ?- lseg '[(-1,0),(1,0)]' @@ -10307,7 +10311,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 线是纵向的? + 线是否竖直? ?| lseg '[(-1,0),(1,0)]' @@ -10339,7 +10343,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 线是垂直的? + 两条线是否互相垂直? lseg '[(0,0),(0,1)]' ?-| lseg '[(0,0),(1,0)]' @@ -10357,7 +10361,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 线是平行的? + 两条线是否平行? lseg '[(-1,0),(1,0)]' ?|| lseg '[(-1,2),(1,2)]' @@ -10386,16 +10390,16 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple - 请注意same as操作符(~=),表示pointboxpolygoncircle类型的一般相等概念。 - 这些类型中的某些还有一个=操作符,但是=只比较相同的面积。 - 其它的标量比较操作符 (<=等等),在这些类型可用的地方,同样比较区域。 + 注意,相同操作符~=表示pointboxpolygoncircle类型通常意义上的相等。 + 某些几何类型还有=操作符,但=仅比较面积是否相等。 + 对于提供其他标量比较操作符(<=等)的类型,这些操作符同样比较面积。 - 在PostgreSQL14之前, 该点严格低于/高于比较操作符 point <<| pointpoint |>> point 分别被称为 <^>^。 + 在PostgreSQL14之前, 用于判断点是否严格位于另一点下方/上方的比较操作符 point <<| pointpoint |>> point 分别被称为 <^>^。 这些名字仍然可以使用,但是已被弃用并且最终将被移除。 @@ -10692,7 +10696,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple box - 计算内接于圆的方框。 + 计算内接于圆的矩形框。 box(circle '<(0,0),2>') @@ -10751,7 +10755,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple box - 计算两个方框的边界框。 + 计算两个矩形框的边界框。 bound_box(box '(1,1),(0,0)', box '(4,4),(3,3)') @@ -10768,7 +10772,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple circle - 计算包围方框的最小圆。 + 计算包围矩形框的最小圆。 circle(box '(1,1),(0,0)') @@ -10861,7 +10865,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple path - 将多边形转换为具有点的相同列表的封闭路径。 + 将多边形转换为具有相同点列表的封闭路径。 path(polygon '((0,0),(1,1),(2,0))') @@ -10969,7 +10973,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple polygon(circle '<(0,0),2>') - (-2,0,)&zwsp; (-1.73205080758774,0.9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999998999998989898989676868686887898999999999998989898989898999978987878787808070876888788989898989898989898989898989898989898989898968686868688768686887878989896868686889899999999999990000890000899900000000890000890000890000000000000000 + ((-2,0),&zwsp;(-1.7320508075688774,0.9999999999999999),&zwsp;(-1.0000000000000002,1.7320508075688772),&zwsp;(-1.2246063538223773e-16,2),&zwsp;(0.9999999999999996,1.7320508075688774),&zwsp;(1.732050807568877,1.0000000000000007),&zwsp;(2,2.4492127076447545e-16),&zwsp;(1.7320508075688776,-0.9999999999999994),&zwsp;(1.0000000000000009,-1.7320508075688767),&zwsp;(3.673819061467132e-16,-2),&zwsp;(-0.9999999999999987,-1.732050807568878),&zwsp;(-1.7320508075688767,-1.0000000000000009)) @@ -10983,7 +10987,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple polygon(4, circle '<(3,0),1>') - ((2,0,)&zwsp; (3,1,)&zwsp; (4,1.2246063538223773e-16), &zwsp; (3,-1)). + ((2,0),&zwsp;(3,1),&zwsp;(4,1.2246063538223773e-16),&zwsp;(3,-1)) @@ -10993,7 +10997,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple polygon - 将封闭路径转换为具有点的相同列表的多边形。 + 将封闭路径转换为具有相同点列表的多边形。 polygon(path '((0,0),(1,1),(2,0))') @@ -11006,7 +11010,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple
- 我们可以把一个point的两个组成数字当作具有索引 0 和 1 的数组访问。例如,如果t.p是一个point列,那么SELECT p[0] FROM t检索 X 坐标而 UPDATE t SET p[1] = ...改变 Y 坐标。同样,box或者lseg类型的值可以当作两个point值的数组值看待。 + 可以把一个point当作下标为 0 和 1 的数组,访问它的两个数值分量。例如,如果t.p是一个point列,那么SELECT p[0] FROM t检索 X 坐标而 UPDATE t SET p[1] = ...改变 Y 坐标。同样,box或者lseg类型的值可以当作两个point值组成的数组看待。 @@ -11022,8 +11026,8 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple 任何cidr 值都可以隐式地转换到inet;因此,下面在inet上操作的操作符和函数也可以在cidr值上工作。 - (对于inetcidr有单独的函数,这是因为这两种情况的行为应该是不同的。) - 此外,它允许将inet值转换为cidr。 + (如果inetcidr各有单独的函数,是因为这两种情况下的行为应当不同。) + 此外,也允许将inet值转换为cidr。 当这样做的时候,子网掩码右边的任何位都被静默地置零,以创建一个有效的cidr值。 @@ -11054,8 +11058,8 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 子网是否严格包含在子网中?这个操作符和后续的四个操作符测试子网包含情况。 - 它们只考虑两个地址的网络部分(忽略网络掩码右侧的任何位),并确定一个网络与另一个网络相同或者是相同的子网。 + 子网是否严格包含在另一个子网中?这个操作符和后续四个操作符测试子网包含关系。 + 它们只考虑两个地址的网络部分(忽略网络掩码右侧的所有位),并判断一个网络是否与另一个网络相同,或是另一个网络的子网。 inet '192.168.1.5' << inet '192.168.1/24' @@ -11077,7 +11081,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 子网是否包含或等于子网? + 子网是否被包含于或等于子网? inet '192.168.1/24' <<= inet '192.168.1/24' @@ -11137,7 +11141,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple inet - 计算位 NOT. + 计算按位非。 ~ inet '192.168.1.6' @@ -11151,7 +11155,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple inet - 计算位 AND. + 计算按位与。 inet '192.168.1.6' & inet '0.0.0.255' @@ -11165,7 +11169,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple inet - 计算位 OR. + 计算按位或。 inet '192.168.1.6' | inet '0.0.0.255' @@ -11266,9 +11270,8 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple text - 创建缩写的文本显示格式。 - (结果与inet输出函数产生的结果相同;只有在与显式转换为text的结果相比时它才算是缩写形式, - 由于历史原因,它永远不会抑制子网掩码部分。) + 创建文本形式的缩写显示格式。 + (结果与inet输出函数产生的结果相同;只有与显式类型转换为text的结果相比时,才称为缩写形式。由于历史原因,后一种转换从不省略网络掩码部分。) abbrev(inet '10.1.0.0/32') @@ -11282,7 +11285,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple text - 创建缩写的文本显示格式。(缩写包括在子网掩码的右侧删除所有零字节;更多的示例请见 。) + 创建文本形式的缩写显示格式。(缩写形式会省略网络掩码右侧值为零的字节;更多示例见。) abbrev(cidr '10.1.0.0/16') @@ -11401,7 +11404,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple integer - 以比特位返回子网掩码长度。 + 返回子网掩码长度,以位为单位。 masklen(inet '192.168.1.5/24') @@ -11503,7 +11506,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple MAC地址类型, macaddrmacaddr8,支持中所示的常用比较操作符以及中所示的特殊函数。 - 此外,它们支持位元逻辑操作符~, &| (NOT, AND 和 OR),就像上面对IP地址所示的那样。 + 此外,它们支持按位逻辑操作符~&|(非、与和或),就像上面对IP地址所示的那样。 @@ -11567,7 +11570,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple macaddr8 - 将地址的第7位设置为1,创建所谓的modified EUI-64,用于包含在IPv6地址中。 + 将地址的第 7 位设置为 1,生成所谓的修订 EUI-64 格式,以便用于 IPv6 地址。 macaddr8_set7bit(macaddr8 '00:34:56:ab:cd:ef') @@ -11585,7 +11588,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple 文本搜索函数和操作符 - 全文搜索 + 全文检索 函数和操作符 @@ -11598,7 +11601,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple 以及 - 总结了为全文搜索提供的函数和操作符。PostgreSQL的文本搜索功能的详细解释可参考。 + 总结了为全文检索提供的函数和操作符。PostgreSQL的文本搜索功能的详细解释可参考
@@ -11654,23 +11657,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple - - - tsvector @@@ tsquery - boolean - - - tsquery @@@ tsvector - boolean - - - 这是@@已弃用的同义词。 - - - to_tsvector('fat cats ate rats') @@@ to_tsquery('cat & rat') - t - - + @@ -11678,11 +11665,11 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsvector - 连接两个tsvector。如果两个输入都包含词素位置,则相应地调整第二个输入的位置。 + 连接两个tsvector。如果两个输入都包含词位位置,则相应地调整第二个输入的位置。 'a:1 b:2'::tsvector || 'c:1 d:2 b:3'::tsvector - 'a':1'b':2,5'c':3'd':4 + 'a':1 'b':2,5 'c':3 'd':4 @@ -11720,7 +11707,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsquery - 否定tsquery,生成一个与输入查询不匹配的匹配文档的查询。 + 对tsquery取反,生成匹配那些不满足输入查询的文档的查询。 !! 'cat'::tsquery @@ -11734,7 +11721,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsquery - 构造一个短语查询,如果两个输入查询在连续的词素上匹配,该查询将进行匹配。 + 构造一个短语查询;当两个输入查询分别匹配相邻的词位时,该查询匹配。 to_tsquery('fat') <-> to_tsquery('rat') @@ -11748,7 +11735,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 第一个tsquery包含了第二个吗?(这只考虑出现在一个查询中的所有词素是否出现在另一个查询中,忽略了组合操作符。) + 第一个tsquery包含了第二个吗?(这只考虑出现在一个查询中的所有词位是否出现在另一个查询中,忽略了组合操作符。) 'cat'::tsquery @> 'cat & rat'::tsquery @@ -11762,7 +11749,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 第一个tsquery包含在第二个中吗?(这只考虑出现在一个查询中的所有词素是否出现在另一个查询中,而忽略了组合操作符。) + 第一个tsquery包含在第二个中吗?(这只考虑出现在一个查询中的所有词位是否出现在另一个查询中,而忽略了组合操作符。) 'cat'::tsquery <@ 'cat & rat'::tsquery @@ -11779,7 +11766,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple 除了这些专用操作符之外, 中所示的常用比较操作符也适用于tsvectortsquery类型。 - 它们对于文本搜索不是很有用,但是允许使用。例如,建在这些类型列上的唯一索引。 + 这些操作符对文本搜索用处不大,但可以用于其他用途,例如在这些类型的列上建立唯一索引。
@@ -11813,7 +11800,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple 将文本字符串数组转换为tsvector。 - 给定的字符串被直接用作词元,不经过进一步处理。数组元素不得为空字符串 + 给定的字符串被直接用作词位,不经过进一步处理。数组元素不得为空字符串 或NULL @@ -11884,8 +11871,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsquery - 将文本转换为tsquery,根据指定的或默认配置对单词进行标准化。 - 字符串中的任何标点符号都会被忽略(它不决定查询操作符)。结果查询匹配文本中包含所有非停止词的文档。 + 将文本转换为tsquery,根据指定的或默认配置对单词进行正规化。字符串中的任何标点符号都会被忽略(它们不决定查询操作符)。生成的查询匹配包含文本中所有非停用词的文档。 plainto_tsquery('english', 'The Fat Rats') @@ -11904,8 +11890,8 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsquery - 将文本转换为tsquery,根据指定的或默认配置对单词进行标准化。 - 字符串中的任何标点符号都会被忽略(它不决定查询操作符)。结果查询匹配包含文本中所有非停止词的短语。 + 将文本转换为tsquery,根据指定的或默认配置对单词进行正规化。 + 字符串中的任何标点符号都会被忽略(它不决定查询操作符)。结果查询匹配包含文本中所有非停用词的短语。 phraseto_tsquery('english', 'The Fat Rats') @@ -11928,8 +11914,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsquery - 将文本转换为tsquery,根据指定的或默认配置对单词进行标准化。引用的单词序列被转换为短语测试。 - or一词被理解为产生OR操作符,而破折号产生NOT操作符;其他标点符号被忽略。这类似于一些常见的网络搜索工具的行为。 + 将文本转换为tsquery,根据指定的或默认配置对单词进行正规化。带引号的单词序列被转换为短语测试。or一词产生 OR 操作符,短横线产生 NOT 操作符;其他标点符号会被忽略。这类似于一些常见网络搜索工具的行为。 websearch_to_tsquery('english', '"fat rat" or cat dog') @@ -11975,14 +11960,13 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple setweight - 为特定词元设置权重 + 为特定词位设置权重 setweight ( vector tsvector, weight "char", lexemes text[] ) tsvector - 为vector中列出的lexemes赋予指定的weight。 - lexemes中的字符串被视为词元,不经过进一步处理。不匹配vector中任何词元的字符串将被忽略。 + 为vector中列在lexemes内的元素赋予指定的weightlexemes中的字符串按原样用作词位,不经过进一步处理。不匹配vector中任何词位的字符串将被忽略。 setweight('fat:2,4 cat:3 rat:5,6B'::tsvector, 'A', '{cat,rat}') @@ -12018,7 +12002,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsquery - 将文本转换为tsquery,根据指定的或默认配置对单词进行标准化。单词必须由有效的tsquery操作符组合。 + 将文本转换为tsquery,根据指定的或默认配置对单词进行正规化。单词必须由有效的tsquery操作符组合。 to_tsquery('english', 'The & Fat & Rats') @@ -12037,7 +12021,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsvector - 将文本转换为tsvector,根据指定的或默认配置对单词进行标准化。结果中包含位置信息。 + 将文本转换为tsvector,根据指定的或默认配置对单词进行正规化。结果中包含位置信息。 to_tsvector('english', 'The Fat Rats') @@ -12059,9 +12043,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsvector - 将JSON文档中的每个字符串值转换为tsvector,根据指定的或默认配置对单词进行标准化。 - 然后将结果按文档顺序连接起来以产生输出。位置信息就像在每对字符串值之间存在一个停止词一样生成。 - (注意,当输入为jsonb时,JSON对象的字段的document order取决于实现;请观察这些示例中的差异。) + 将 JSON 文档中的每个字符串值转换为tsvector,根据指定的或默认配置对单词进行正规化。然后将结果按文档顺序连接起来以产生输出。生成位置信息时,视为每对字符串值之间存在一个停用词。(注意,当输入为jsonb时,JSON 对象字段的文档顺序取决于具体实现;请注意这些示例中的差异。) to_tsvector('english', '{"aa": "The Fat Rats", "b": "dog"}'::json) @@ -12095,15 +12077,15 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsvector - 选择filter请求的JSON文档中的每个项,并将每个项转换为tsvector,根据指定的或默认配置对单词进行标准化。 - 然后将结果按文档顺序连接起来以产生输出。位置信息就像在每对选定的项目之间存在一个停止词一样生成。 - (注意,当输入为jsonb时,JSON对象字段的document order取决于实现。) - filter必须是一个jsonb数组,其中包含0个或多个关键字: + 选择filter请求的JSON文档中的每个项,并将每个项转换为tsvector,根据指定的或默认配置对单词进行正规化。 + 然后将结果按文档顺序连接起来以产生输出。位置信息就像在每对选定的项目之间存在一个停用词一样生成。 + (注意,当输入为jsonb时,JSON对象字段的文档顺序取决于实现。) + filter必须是一个jsonb数组,其中包含0个或多个关键字: "string"(包括所有字符串值), "numeric"(包括所有数值), "boolean"(包括所有布尔值), "key"(包括所有键),或 - "all"(包括以上所有关键字)。 + "all"(包括以上所有内容)。 作为一种特殊情况,该filter也可以是这些关键字之一的简单JSON值。 @@ -12125,8 +12107,8 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsvector - 从vector中删除给定的lexeme的任何出现。 - lexeme字符串被视为原样的词元,不经过进一步处理。 + 从vector中删除给定的lexeme的所有出现。 + lexeme字符串被视为原样的词位,不经过进一步处理。 ts_delete('fat:2,4 cat:3 rat:5A'::tsvector, 'fat') @@ -12140,9 +12122,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsvector - 从vector中删除lexemes中的任何出现。 - lexemes中的字符串被视为词元,不经过进一步处理。 - 不匹配vector中任何词元的字符串将被忽略。 + 从vector中删除lexemes所列词位的所有出现。lexemes中的字符串按原样用作词位,不经过进一步处理。不匹配vector中任何词位的字符串将被忽略。 ts_delete('fat:2,4 cat:3 rat:5A'::tsvector, ARRAY['fat','rat']) @@ -12180,9 +12160,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple text - 以缩写形式显示documentquery的匹配项,该匹配项必须是原始文本,而不是tsvector。 - 在匹配查询之前,文档中的单词将根据指定的或默认的配置进行规范化。 - 中讨论了该函数的使用,还描述了可用的options。 + 以缩略形式显示querydocument中的匹配项;后者必须是原始文本,不能是tsvector。在匹配查询之前,文档中的单词将根据指定的或默认配置进行正规化。中讨论了该函数的使用,还描述了可用的options ts_headline('The fat cat ate the rat.', 'cat') @@ -12208,8 +12186,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple text - 以缩写形式显示匹配JSONdocument中字符串值中的query。 - 更多细节请参阅 。 + 以缩略形式显示query在 JSON document字符串值中的匹配项。更多细节请参见 ts_headline('{"cat":"raining cats and dogs"}'::jsonb, 'cat') @@ -12287,8 +12264,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsquery - 根据目标替换部分query,并替换通过执行SELECT命令获得的查询。 - 详情参见。 + 根据执行SELECT命令得到的目标和替换项,替换query中的相应部分。详情参见 SELECT ts_rewrite('a & b'::tsquery, 'SELECT t,s FROM aliases') @@ -12319,7 +12295,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsquery - 构造一个短语查询,用于搜索query1query2的匹配项,这些匹配项恰好出现在distance词位之间。 + 构造一个短语查询,用于搜索query1query2的匹配项,其匹配位置恰好相距distance个词位。 tsquery_phrase(to_tsquery('fat'), to_tsquery('cat'), 10) @@ -12348,7 +12324,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple unnest - for tsvector + 用于 tsvector unnest ( tsvector ) setof record @@ -12378,7 +12354,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple - 所有接受一个可选的regconfig参数的文本搜索函数在该参数被忽略时,使用由指定的配置。 + 所有接受一个可选的regconfig参数的文本搜索函数在省略该参数时,会使用由指定的配置。 @@ -12425,7 +12401,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple lexemes text[] ) - 根据指定的或默认的文本搜索配置从document中提取和标准化标记,并返回关于每个标记是如何处理的信息。 + 根据指定的或默认的文本搜索配置从document中提取和正规化词元,并返回关于每个词元是如何处理的信息。 详情参见 @@ -12443,8 +12419,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple text[] - 如果字典知道输入标记,则返回替换词位数组;如果字典知道标记,但它是停止词,则返回空数组;如果它不是已知词,则返回NULL。 - 详情参见。 + 如果词典识别输入词元,则返回由替换词位组成的数组;如果词典识别该词元,但它是停用词,则返回空数组;如果词典无法识别该词元,则返回NULL。详情参见 ts_lexize('english_stem', 'stars') @@ -12464,7 +12439,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple token text ) - 使用命名的解析器从document中提取标记。详情参见。 + 使用指定名称的解析器从document中提取词元。详情参见 ts_parse('default', 'foo - bar') @@ -12481,7 +12456,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple token text ) - 使用 OID 指定的解析器从document中提取标记。 + 使用 OID 指定的解析器从document中提取词元。 详情参见 @@ -12502,7 +12477,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple description text ) - 返回一个表,该表描述命名解析器可以识别的每种类型的标记。详情参见。 + 返回一个表,该表描述指定名称的解析器可以识别的每种类型的词元。详情参见 ts_token_type('default') @@ -12519,7 +12494,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple description text ) - 返回一个表,该表描述 OID 指定的解析器可以识别的每种标记类型。详情参见。 + 返回一个表,该表描述 OID 指定的解析器可以识别的每种词元类型。详情参见 ts_token_type(3722) @@ -12540,7 +12515,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple nentry integer ) - 执行sqlquery,该查询必须返回单个tsvector列,并返回数据中每个不同词元的统计信息。 + 执行sqlquery,该查询必须返回单个tsvector列,并返回数据中每个不同词位的统计信息。 详情参见 @@ -12558,7 +12533,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple UUID 函数 - + UUID 生成 @@ -12576,15 +12551,15 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple - PostgreSQL包含一个生成UUID的函数: + PostgreSQL包含一个生成 UUID 的函数: gen_random_uuid () uuid - 这个函数返回一个版本 4(随机)UUID。这是最常用的UUID类型,适用于大多数应用。 + 该函数返回版本 4(随机)UUID。这是最常用的 UUID 类型,适用于大多数应用。 - 模块提供了实现其他标准UUID生成算法的额外函数。 + 模块还提供了额外的函数,用于实现其他标准 UUID 生成算法。 @@ -12608,7 +12583,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple - PostgreSQL还提供了中展示的用于UUID的常规比较操作符。 + PostgreSQL也为 UUID 提供了中展示的常用比较操作符。 @@ -13073,7 +13048,7 @@ SELECT xmlexists('//town[text() = ''Toronto'']' PASSING BY VALUE 'T - 示例: + 示例: - 示例: + 示例: test', ARRAY[ARRAY['my', 'http://example.com']]); @@ -13190,7 +13165,7 @@ SELECT xpath('//mydefns:b/text()', 'test - 示例: + 示例: test', ARRAY[ARRAY['my', 'http://example.com']]); @@ -13242,8 +13217,8 @@ SELECT xpath_exists('/my:a/text()', 'test - document_expression提供了上下文。row_expression的项。 - 它必须是一个格式良好的XML文档;不接受片段/森林。BY REFBY VALUE子句 如上文所讨论的那样,被接受但被忽略了,正如在中所讨论的。 + document_expressionrow_expression提供上下文项。 + 它必须是一个良构的 XML 文档;不接受内容片段或森林。BY REFBY VALUE子句会被接受,但会被忽略,如中所述。 @@ -13292,7 +13267,7 @@ SELECT xpath_exists('/my:a/text()', 'test - 一个XML元素的字符串值是字符串值的协整,按文档的顺序。该元素中包含的所有文本节点及其子节点。字符串 元素的值是一个没有下级文本节点的元素的值是一个 空字符串(不是NULL)。任何xsi:nil属性都会被忽略。请注意,两个非文本之间的text()节点只用空格,而两个非文本 元素,并且保留了text()上的前导白格。节点不被扁平化。XPath 1.0中的string函数可以参考XPath 1.0中的 定义其他XML节点类型和非XML值的字符串值的规则。 + 一个 XML 元素的字符串值,是该元素及其所有后代中包含的文本节点按文档顺序拼接而成的字符串。没有后代文本节点的元素,其字符串值为空字符串(不是 NULL)。所有 xsi:nil 属性都会被忽略。注意,两个非文本元素之间仅含空白的 text() 节点会被保留,text() 节点的前导空白也不会被折叠。其他 XML 节点类型及非 XML 值的字符串值定义规则,可参考 XPath 1.0 的 string 函数。 @@ -13312,7 +13287,7 @@ SELECT xpath_exists('/my:a/text()', 'test - 示例: + 示例: - 下面的示例展示了多个text()节点的连接,列名作为XPath过滤器的使用,以及对空格、XML注释和处理指令的处理: + 下面的示例展示了多个text()节点的连接,列名作为XPath过滤器的使用,以及对空格、XML注释和处理指令的处理: JSON 函数和操作符 + + SQL/JSON + 函数和表达式 + - 本节描述: + 本节描述: @@ -13648,14 +13627,50 @@ table2-mapping - SQL/JSON路径语言 + SQL/JSON 路径语言 + + + + + SQL/JSON 查询函数 - 要了解有关SQL/JSON标准的更多信息,请参阅。有关PostgreSQL中支持的JSON类型的详细信息,见 。 + 为了在 SQL 环境中为 JSON 数据类型提供原生支持,PostgreSQL 实现了 + SQL/JSON 数据模型。该模型由项序列组成。每个项可以保存 SQL 标量值, + 以及额外的 SQL/JSON null 值,还可以保存使用 JSON 数组和对象的复合数据结构。该模型是 JSON 规范 + RFC 7159 中隐含数据模型的形式化表示。 + + + + SQL/JSON 允许你将 JSON 数据与常规 SQL 数据一同处理,并提供事务支持,包括: + + + + + 将 JSON 数据上传到数据库,并将其作为字符或二进制字符串存储在常规 SQL 列中。 + + + + + 从关系数据生成 JSON 对象和数组。 + + + + + 使用 SQL/JSON 查询函数和 SQL/JSON 路径语言表达式查询 JSON 数据。 + + + + + + + 要了解有关 SQL/JSON 标准的更多信息,请参阅。有关 + PostgreSQL 中支持的 JSON 类型的详细信息,见 + @@ -13810,14 +13825,13 @@ table2-mapping - 如果JSON输入没有匹配请求的正确结构,字段/元素/路径提取操作符返回NULL,而不是失败;例如,如果不存在这样的键或数组元素。 + 如果 JSON 输入没有匹配请求的正确结构,字段/元素/路径提取操作符会返回 NULL,而不是失败;例如,如果不存在这样的键或数组元素。 - 还有一些操作符仅适用于jsonb,如表所示。 - 第描述了如何使用这些操作符来有效地搜索索引的jsonb数据。 - + 还有一些操作符仅适用于jsonb,如所示。介绍了如何使用这些操作符有效地搜索已建立索引的jsonb数据。 +
@@ -13892,7 +13906,7 @@ table2-mapping boolean - 文本数组中的字符串是否作为顶级键或数组元素存在? + 文本数组中的任一字符串是否作为顶级键或数组元素存在? '{"a":1, "b":2, "c":3}'::jsonb ?| array['b', 'd'] @@ -13924,7 +13938,7 @@ table2-mapping 连接两个数组将生成一个包含每个输入的所有元素的数组。 连接两个对象将生成一个包含它们键的并集的对象,当存在重复的键时取第二个对象的值。 所有其他情况都通过将非数组输入转换为单元素数组来处理,然后按照两个数组的方式进行处理。 - 不递归操作:只有顶级数组或对象结构被合并。 + 不递归操作:只有顶级数组或对象结构会被合并。 '["a", "b"]'::jsonb || '["a", "d"]'::jsonb @@ -13943,7 +13957,7 @@ table2-mapping [{"a": "b"}, 42] - 要将一个数组作为单个条目附加到另一个数组中,请将其包装在另一个数组附加层中,例如: + 要将一个数组作为单个元素追加到另一个数组中,请先在它外面再包装一层数组,例如: '[1, 2]'::jsonb || jsonb_build_array('[3, 4]'::jsonb) @@ -14017,7 +14031,7 @@ table2-mapping boolean - JSON路径是否为指定的JSON值返回任何项? + JSON 路径是否为指定的 JSON 值返回任何项?(这只适用于 SQL 标准 JSON 路径表达式,不适用于谓词检查表达式,因为后者总是返回一个值。) '{"a":[1,2,3,4,5]}'::jsonb @? '$.a[*] ? (@ > 2)' @@ -14031,7 +14045,7 @@ table2-mapping boolean - 返回指定JSON值的JSON路径谓词检查的结果。只考虑结果的第一项。如果结果不是布尔值,则返回NULL。 + 返回对指定 JSON 值进行 JSON 路径谓词检查的结果。(这只适用于谓词检查表达式,不适用于 SQL 标准 JSON 路径表达式,因为如果路径结果不是单个布尔值,就会返回NULL。) '{"a":[1,2,3,4,5]}'::jsonb @@ '$.a[*] > 2' @@ -14045,15 +14059,13 @@ table2-mapping - jsonpath操作符@?@@抑制以下错误:缺少对象字段或数组元素,意外的JSON项目类型,日期时间和数字错误。 - 还可以告诉以下描述的与jsonpath相关的函数来抑制这些类型的错误。 - 在搜索不同结构的JSON文档集合时,此行为可能会有所帮助。 + jsonpath操作符@?@@会抑制以下错误:缺少对象字段或数组元素、JSON 项类型不符合预期,以及日期时间和数值错误。下文介绍的jsonpath相关函数也可以设置为抑制这些类型的错误。在搜索结构各异的 JSON 文档集合时,这一行为可能很有用。 - 显示可用于构造jsonjsonb值的函数。 - + 列出了可用于构造jsonjsonb值的函数。表中的某些函数具有RETURNING子句,用于指定返回的数据类型。该类型必须是jsonjsonbbytea、字符串类型(textcharvarchar),或者可以转换为json的类型。默认返回json类型。 +
@@ -14092,14 +14104,14 @@ table2-mapping jsonb - 将任何SQL值转换为jsonjsonb。数组和组合递归地转换为数组和对象(多维数组在JSON中变成数组的数组)。 - 否则,如果存在从SQL数据类型到json的类型转换,则类型转换函数将用于执行转换; + 将任何SQL值转换为jsonjsonb。数组和复合值递归地转换为数组和对象(多维数组在JSON中变成数组的数组)。 + 否则,如果存在从SQL数据类型到json的类型转换,则类型转换函数将用于执行转换; - 例如,扩展有一个从hstorejson的转换,这样通过json创建函数转换的hstore值将被表示为json对象,而不是原始字符串值 + 例如,扩展有一个从hstorejson的类型转换,因此通过 JSON 创建函数转换的hstore值将表示为 JSON 对象,而不是基本的字符串值。 - 否则,将生成一个标量json值。对于除数字、布尔值或空值之外的任何标量,将使用文本表示,并根据需要进行转义,使其成为有效的JSON字符串值。 + 否则,将生成一个标量 JSON 值。对于除数字、布尔值或空值之外的任何标量,将使用文本表示,并根据需要进行转义,使其成为有效的JSON字符串值。 to_json('Fred said "Hi."'::text) @@ -14107,7 +14119,7 @@ table2-mapping to_jsonb(row(42, 'Fred said "Hi."'::text)) - {"f1":42,"f2":"Fred said \"Hi.\""} + {"f1": 42, "f2": "Fred said \"Hi.\""} @@ -14129,15 +14141,48 @@ table2-mapping + - - row_to_json - + json_array + json_array ( + { value_expression FORMAT JSON } , ... + { NULL | ABSENT } ON NULL + RETURNING data_type FORMAT JSON ENCODING UTF8 ) + + + json_array ( + query_expression + RETURNING data_type FORMAT JSON ENCODING UTF8 ) + + + 从一系列value_expression参数或query_expression的结果构造 JSON 数组;后者必须是返回单列的 SELECT 查询。如果指定了ABSENT ON NULL,则忽略 NULL 值。使用query_expression时始终如此。 + + + json_array(1,true,json '{"a":null}') + [1, true, {"a":null}] + + + json_array(SELECT * FROM (VALUES(1),(2)) t) + [1, 2] + + + + + + + row_to_json + row_to_json ( record [, boolean ] ) json - 将SQL组合值转换为JSON对象。该行为与to_json相同,只是如果可选boolean参数为真,换行符将在顶级元素之间添加。 + 将SQL 复合值转换为JSON对象。该行为与to_json相同,只是如果可选boolean参数为真,换行符将在顶级元素之间添加。 row_to_json(row(1,'foo')) @@ -14186,7 +14231,7 @@ table2-mapping 根据可变参数列表构建一个JSON对象。按照惯例,参数列表由交替的键和值组成。 - 关键参数强制转换为文本;值参数按照to_jsonto_jsonb进行转换。 + 键参数会被强制转换为文本;值参数则按照to_jsonto_jsonb进行转换。 json_build_object('foo', 1, 2, row(3,'bar')) @@ -14194,6 +14239,25 @@ table2-mapping + + + json_object + json_object ( + { key_expression { VALUE | ':' } + value_expression FORMAT JSON ENCODING UTF8 }, ... + { NULL | ABSENT } ON NULL + { WITH | WITHOUT } UNIQUE KEYS + RETURNING data_type FORMAT JSON ENCODING UTF8 ) + + + 根据给定的所有键值对构造 JSON 对象;如果没有给出键值对,则构造空对象。key_expression是定义JSON键的标量表达式,会被转换为text类型。它不能为NULL,其类型也不能具有到json的类型转换。如果指定了WITH UNIQUE KEYS,则key_expression不能重复。如果指定了ABSENT ON NULL,则value_expression求值为NULL的键值对会从输出中省略;如果指定了NULL ON NULL或省略了该子句,则保留该键,并将其值设为NULL。 + + + json_object('code' VALUE 'P123', 'title': 'Jaws') + {"code" : "P123", "title" : "Jaws"} + + + @@ -14210,8 +14274,7 @@ table2-mapping jsonb - 从文本数组构建JSON对象。该数组必须有两个维度,一个维度的成员数为偶数,在这种情况下,它们被视为交替的键/值对; - 另一个维度的成员数为二维,每个内部数组恰好有两个元素,它们被视为键/值对。所有值都转换为JSON字符串。 + 从文本数组构造 JSON 对象。该数组必须是一维且包含偶数个成员,此时将成员按交替的键/值对处理;或者是二维数组,且每个内部数组恰好有两个元素,将这两个元素作为一个键/值对。所有值都转换为 JSON 字符串。 json_object('{a, 1, b, "def", c, 3.5}') @@ -14232,17 +14295,144 @@ table2-mapping jsonb - 这种形式的json_object从单独的文本数组中成对地获取键和值。否则,它与单参数形式相同。 + 这种形式的json_object从单独的文本数组中成对地获取键和值。除此之外,它与单参数形式相同。 json_object('{a,b}', '{1,2}') {"a": "1", "b": "2"} + + + + json 构造器 + json ( + expression + FORMAT JSON ENCODING UTF8 + { WITH | WITHOUT } UNIQUE KEYS ) + json + + + 将给定的textbytea字符串表达式(采用 UTF8 编码)转换为 JSON 值。如果expression为 NULL,则返回SQL空值。如果指定了WITH UNIQUE,则expression不能包含重复的对象键。 + + + json('{"a":123, "b":[true,"foo"], "a":"bar"}') + {"a":123, "b":[true,"foo"], "a":"bar"} + + + + + + + json_scalar + json_scalar ( expression ) + + + 将给定的 SQL 标量值转换为 JSON 标量值。如果输入为 NULL,则返回SQL空值。如果输入是数字或布尔值,则返回相应的 JSON 数字或布尔值。对于其他值,则返回 JSON 字符串。 + + + json_scalar(123.45) + 123.45 + + + json_scalar(CURRENT_TIMESTAMP) + "2022-05-10T10:51:04.62128-04:00" + + + + + + json_serialize ( + expression FORMAT JSON ENCODING UTF8 + RETURNING data_type FORMAT JSON ENCODING UTF8 ) + + + 将 SQL/JSON 表达式转换为字符或二进制字符串。expression可以是任意 JSON 类型、任意字符串类型,或采用 UTF8 编码的bytea RETURNING中使用的返回类型可以是任意字符串类型或bytea,默认为text。 + + + json_serialize('{ "a" : 1 } ' RETURNING bytea) + \x7b20226122203a2031207d20 + +
+ + 详细介绍了用于测试 JSON 的 SQL/JSON 功能。 + + + + SQL/JSON 测试函数 + + + + + 函数签名 + + + 描述 + + + 示例 + + + + + + + IS JSON + expression IS NOT JSON + { VALUE | SCALAR | ARRAY | OBJECT } + { WITH | WITHOUT } UNIQUE KEYS + + + 该谓词测试 expression 是否可以解析为 JSON,也可以指定具体类型。 + 如果指定 SCALARARRAYOBJECT, + 则测试 JSON 是否属于该特定类型。如果指定 WITH UNIQUE KEYS, + 则 expression 中的任意对象还会被检查是否存在重复键。 + + + +SELECT js, + js IS JSON "json?", + js IS JSON SCALAR "scalar?", + js IS JSON OBJECT "object?", + js IS JSON ARRAY "array?" +FROM (VALUES + ('123'), ('"abc"'), ('{"a": "b"}'), ('[1,2]'),('abc')) foo(js); + js | json? | scalar? | object? | array? +------------+-------+---------+---------+-------- + 123 | t | t | f | f + "abc" | t | t | f | f + {"a": "b"} | t | f | t | f + [1,2] | t | f | f | t + abc | f | f | f | f + + + + +SELECT js, + js IS JSON OBJECT "object?", + js IS JSON ARRAY "array?", + js IS JSON ARRAY WITH UNIQUE KEYS "array w. UK?", + js IS JSON ARRAY WITHOUT UNIQUE KEYS "array w/o UK?" +FROM (VALUES ('[{"a":"1"}, + {"b":"2","b":"3"}]')) foo(js); +-[ RECORD 1 ]-+-------------------- +js | [{"a":"1"}, + + | {"b":"2","b":"3"}] +object? | f +array? | t +array w. UK? | f +array w/o UK? | t + + + + + +
+ 显示可用于处理jsonjsonb值的函数。 @@ -14519,48 +14709,48 @@ table2-mapping anyelement
- 将顶级 JSON 对象展开为具有 base 参数复合类型的行。JSON 对象将被扫描,查找名称与输出行类型列名匹配的字段,并将其值插入到输出行的对应列中。 - (不对应任何输出列名的字段将被忽略。)在典型用法中,base 的值仅为 NULL,这意味着任何不匹配对象字段的输出列都会被填充为 NULL。 - 但是,如果base不为NULL,那么它包含的值将用于不匹配的列。 + 将顶级 JSON 对象展开为一个行,其复合类型与base参数相同。系统会扫描该 JSON 对象,查找名称与输出行类型列名匹配的字段,并将其值插入输出中的对应列。 + (不对应任何输出列名的字段会被忽略。)在典型用法中,base的值就是NULL,这意味着凡是不匹配对象字段的输出列都会被填充为空值。 + 但是,如果base不是NULL,那么其中包含的值将用于那些不匹配的列。 - 要将JSON值转换为输出列的SQL类型,需要按次序应用以下规则: + 要将 JSON 值转换为输出列的 SQL 类型,需要依次应用以下规则: - 在所有情况下,JSON空值都会转换为SQL空值。 + 在所有情况下,JSON 空值都会转换为 SQL 空值。 - 如果输出列的类型是jsonjsonb,则会精确地重制JSON值。 + 如果输出列的类型是jsonjsonb,则 JSON 值会被原样保留。 - 如果输出列是复合(行)类型,且JSON值是JSON对象,则该对象的字段将转换为输出行类型的列,通过这些规则的递归应用程序。 + 如果输出列是复合(行)类型,且 JSON 值是 JSON 对象,则该对象的字段会通过递归应用这些规则,被转换为输出行类型的各列。 - 同样,如果输出列是数组类型,而JSON值是JSON数组,则通过这些规则的递归应用程序将JSON数组的元素转换为输出数组的元素。 + 同样,如果输出列是数组类型,而 JSON 值是 JSON 数组,则会通过递归应用这些规则,把 JSON 数组的元素转换为输出数组的元素。 - 否则,如果JSON值是字符串,则将字符串的内容提供给输入转换函数,用以确定列的数据类型。 + 否则,如果 JSON 值是字符串,则会把该字符串的内容送入该列数据类型的输入转换函数。 - 否则,JSON值的普通文本表示将被提供给输入转换函数,以确定列的数据类型。 + 否则,JSON 值的普通文本表示会被送入该列数据类型的输入转换函数。 - 虽然下面的示例使用一个常量JSON值,典型的用法是在查询的FROM子句中从另一个表侧面地引用jsonjsonb列。 - 在FROM子句中编写json_populate_record是一种很好的实践,因为提取的所有列都可以使用,而不需要重复的函数调用。 + 虽然下面的示例使用的是常量 JSON 值,但典型用法是在查询的FROM子句中,以横向方式引用另一个表中的jsonjsonb列。 + 把json_populate_record写在FROM子句中是一种良好实践,因为这样抽取出的所有列都可以直接使用,而不需要重复调用函数。 create type subrowtype as (d int, e text); @@ -14578,6 +14768,55 @@ table2-mapping + + + + jsonb_populate_record_valid + + jsonb_populate_record_valid ( base anyelement, from_json json ) + boolean + + + 用于测试jsonb_populate_record的函数。对于给定的输入 JSON 对象,如果jsonb_populate_record能够无错误地完成,即该输入有效,则返回true;否则返回false。 + + + create type jsb_char2 as (a char(2)); + + + select jsonb_populate_record_valid(NULL::jsb_char2, '{"a": "aaa"}'); + + + jsonb_populate_record_valid +----------------------------- + f +(1 row) + + + select * from jsonb_populate_record(NULL::jsb_char2, '{"a": "aaa"}') q; + + +ERROR: value too long for type character(2) + + select jsonb_populate_record_valid(NULL::jsb_char2, '{"a": "aa"}'); + + + jsonb_populate_record_valid +----------------------------- + t +(1 row) + + + select * from jsonb_populate_record(NULL::jsb_char2, '{"a": "aa"}') q; + + + a +---- + aa +(1 row) + + + + @@ -14594,8 +14833,7 @@ table2-mapping setof anyelement - 将对象的顶级 JSON 数组展开为一组具有 base 参数复合类型的行。 - 对于json[b]_populate_record,将如上所述处理JSON数组的每个元素。 + 将由对象组成的顶级 JSON 数组展开为一组行,其复合类型与base参数相同。JSON 数组中的每个元素都按照上文对json[b]_populate_record的说明进行处理。 create type twoints as (a int, b int); @@ -14664,8 +14902,8 @@ table2-mapping 将顶级JSON对象数组展开为一组由AS子句定义的复合类型的行。 - (与所有返回record的函数一样,调用查询必须使用AS子句显式定义记录的结构。) - 对于json[b]_populate_record,将如上所述处理JSON数组的每个元素。 + (与所有返回record的函数一样,调用查询必须使用AS子句显式定义记录的结构。) + JSON 数组中的每个元素都按照上文对json[b]_populate_record的说明进行处理。 select * from json_to_recordset('[{"a":1,"b":"foo"}, {"a":"2","c":"bar"}]') as x(a int, b text) @@ -14691,7 +14929,7 @@ table2-mapping 返回target,将path指定的项替换为new_value, 如果create_if_missing为真(此为默认值)并且path指定的项不存在,则添加new_value。 路径中的所有前面步骤都必须存在,否则将不加改变地返回target。 - 与面向路径操作符一样,负整数出现在JSON数组末尾的path计数中。 + 与面向路径的操作符一样,path中的负整数从 JSON 数组末尾计数。 如果最后一个路径步骤是超出范围的数组索引,并且create_if_missing为真,那么如果索引为负,新值将添加到数组的开头,如果索引为正,则添加到数组的结尾。 @@ -14738,8 +14976,8 @@ table2-mapping 如果path指派的项是一个数组元素,如果 insert_after为假(此为默认值),则new_value将被插入到该项之前,如果 insert_after为真则在该项之后。 如果由path指派的项是一个对象字段,则只在对象不包含该键时才插入 new_value。 路径中的所有前面步骤都必须存在,否则将不加改变地返回target。 - 与面向路径操作符一样,负整数出现在JSON数组末尾的 path计数中。 - 如果最后一个路径步骤是超出范围的数组下标,则如果下标为负,则将新值添加到数组的开头;如果下标为正,则将新值添加到数组的结尾。 + 与面向路径的操作符一样,path中的负整数从 JSON 数组末尾计数。 + 如果最后一个路径步骤是超出范围的数组下标,那么当下标为负时,新值会被添加到数组开头;当下标为正时,新值会被添加到数组末尾。 jsonb_insert('{"a": [0,1,2]}', '{a, 1}', '"new_value"') @@ -14766,10 +15004,7 @@ table2-mapping jsonb_strip_nulls ( jsonb ) jsonb - - 从给定的JSON值中递归地删除所有具有空值的对象字段。 - 不是对象字段的空值不受影响。 - + 递归删除给定 JSON 值中所有值为 null 的对象字段。不是对象字段的 null 值保持不变。 json_strip_nulls('[{"f1":1, "f2":null}, 2, null, 3]') [{"f1":1},2,null,3] @@ -14785,7 +15020,7 @@ table2-mapping boolean - 检查JSON路径是否返回指定JSON值的任何项。如果指定了vars参数,则它必须是一个JSON对象,并且它的字段提供要替换到jsonpath表达式中的名称值。 + 检查 JSON 路径是否为指定的 JSON 值返回任何项。(这只对 SQL 标准 JSON 路径表达式有用,而不适用于谓词检查表达式,因为后者总是返回一个值。)如果指定了vars参数,则它必须是一个 JSON 对象,并且它的字段提供要替换到jsonpath表达式中的具名值。 如果指定了silent参数并为true,函数会抑制与@?@@操作符相同的错误。 @@ -14803,8 +15038,7 @@ table2-mapping boolean - 返回指定JSON值的JSON路径谓词检查的结果。只有结果的第一项被考虑在内。 - 如果结果不是布尔值,则返回NULL。可选的varssilent参数的作用与jsonb_path_exists相同。 + 返回指定 JSON 值的 JSON 路径谓词检查的 SQL 布尔结果。(这只对谓词检查表达式有用,而不适用于 SQL 标准 JSON 路径表达式,因为如果路径结果不是单个布尔值,它将失败或返回NULL。)可选的varssilent参数的作用与jsonb_path_exists相同。 jsonb_path_match('{"a":[1,2,3,4,5]}', 'exists($.a[*] ? (@ >= $min && @ <= $max))', '{"min":2, "max":4}') @@ -14821,7 +15055,7 @@ table2-mapping setof jsonb - 为指定的JSON值返回由JSON路径返回的所有JSON项。可选的varssilent参数的作用与jsonb_path_exists相同。 + 为指定的 JSON 值返回由 JSON 路径返回的所有 JSON 项。对于 SQL 标准 JSON 路径表达式,它返回从target中选出的 JSON 值。对于谓词检查表达式,它返回谓词检查的结果:truefalsenull。可选的varssilent参数的作用与jsonb_path_exists相同。 select * from jsonb_path_query('{"a":[1,2,3,4,5]}', '$.a[*] ? (@ >= $min && @ <= $max)', '{"min":2, "max":4}') @@ -14845,7 +15079,7 @@ table2-mapping jsonb - 以JSON数组的形式返回由JSON路径为指定的JSON值返回的所有JSON项。可选的varssilent参数的作用与jsonb_path_exists相同。 + 以JSON数组的形式返回由JSON路径为指定的JSON值返回的所有JSON项。参数与jsonb_path_query相同。 jsonb_path_query_array('{"a":[1,2,3,4,5]}', '$.a[*] ? (@ >= $min && @ <= $max)', '{"min":2, "max":4}') @@ -14863,7 +15097,7 @@ table2-mapping 为指定的JSON值返回由JSON路径返回的第一个JSON项。如果没有结果则返回NULL。 - 可选的varssilent参数的作用与 jsonb_path_exists相同。 + 参数与jsonb_path_query相同。 jsonb_path_query_first('{"a":[1,2,3,4,5]}', '$.a[*] ? (@ >= $min && @ <= $max)', '{"min":2, "max":4}') @@ -14927,7 +15161,7 @@ table2-mapping text - 将给定的JSON值转换为精美打印的,缩进的文本。 + 将给定的 JSON 值转换为经过美化并带有缩进的文本。 jsonb_pretty('[{"f1":1,"f2":null}, 2]') @@ -14960,8 +15194,8 @@ table2-mapping text - 以文本字符串形式返回顶级JSON值的类型。可能的类型有object, array,string, number,boolean, 和 null。 - (null的结果不应该与SQL NULL 混淆;参见示例。) + 以文本字符串形式返回顶级JSON值的类型。可能的类型有objectarraystringnumberbooleannull。 + (null 的结果不应与 SQL NULL 混淆;参见示例。) json_typeof('-123.4') @@ -14990,14 +15224,15 @@ table2-mapping - SQL/JSON路径表达式指定了要从JSON数据中检索的项目,类似于SQL访问XML时使用的XPath表达式。 + SQL/JSON路径表达式指定了要从JSON数据中检索的项,类似于访问 XML 内容时使用的 XPath 表达式。 在PostgreSQL中,路径表达式作为jsonpath数据类型实现,可以使用中描述的任何元素。 JSON 查询函数和操作符会将给定的路径表达式传递给路径引擎进行求值。 如果表达式与被查询的JSON数据匹配,则返回相应的JSON项或项集。 - 路径表达式是用SQL/JSON路径语言编写的,也可以包括算术表达式和函数。 + 如果没有匹配项,则根据所用函数返回NULLfalse或抛出错误。 + 路径表达式是用SQL/JSON路径语言编写的,也可以包括算术表达式和函数。 @@ -15006,15 +15241,13 @@ table2-mapping - 要引用正在查询的JSON值(context item项),在路径表达式中使用$变量。 - 它后面可以跟着一个或多个accessor operators,这些操作符在JSON结构中逐级向下检索上下文项的子项。 - 后面的每个操作符处理前一个求值步骤的结果。 - + 要引用正在查询的 JSON 值(上下文项),请在路径表达式中使用$变量。路径的第一个元素必须始终是$。它后面可以跟一个或多个访问操作符,沿 JSON 结构逐层向下获取上下文项的子项。每个访问操作符都处理上一步求值的结果,为每个输入项产生零个、一个或多个输出项。 + - 例如,假设你有一些你想要解析的来自GPS跟踪器的JSON数据,例如: + 例如,假设你有一些来自 GPS 跟踪器、想要解析的 JSON 数据,如下所示: -{ +SELECT '{ "track": { "segments": [ { @@ -15029,54 +15262,68 @@ table2-mapping } ] } -} +}' AS json \gset - + (可以将上述示例复制粘贴到psql中,为后续示例做好准备。此后,psql会将:'json'展开为一个包含该 JSON 值、且已正确加上引号的字符串常量。) + - 为了检索可用的轨迹段,你需要使用.key访问操作符来向下浏览周边的JSON对象: - -$.track.segments - + 要获取可用的轨迹段,需要使用.key访问操作符,逐层访问外围的 JSON 对象: + +=> select jsonb_path_query(:'json', '$.track.segments'); + jsonb_path_query +-----------------------------------------------------------&zwsp;-----------------------------------------------------------&zwsp;--------------------------------------------- + [{"HR": 73, "location": [47.763, 13.4034], "start time": "2018-10-14 10:05:14"}, {"HR": 135, "location": [47.706, 13.2635], "start time": "2018-10-14 10:39:21"}] + - 要检索数组的内容,通常使用[*]操作符。例如,下面的路径将返回所有可用轨道段的位置坐标: - -$.track.segments[*].location - + 要检索数组的内容,通常使用[*]操作符。例如,下面的路径将返回所有可用轨迹段的位置坐标: + +=> select jsonb_path_query(:'json', '$.track.segments[*].location'); + jsonb_path_query +------------------- + [47.763, 13.4034] + [47.706, 13.2635] + + + 这里从整个 JSON 输入值($)开始,随后 .track 访问器选择与对象键 "track" 关联的 JSON 对象,.segments 访问器再选择该对象中与键 "segments" 关联的 JSON 数组,[*] 访问器接着选择该数组的每个元素(产生一系列项),最后 .location 访问器选择这些对象中分别与键 "location" 关联的 JSON 数组。在这个示例中,每个对象都有一个 "location" 键;如果某个对象没有这个键,.location 访问器就不会为该输入项产生任何输出。 - 要只返回第一个段的坐标,可以在[]访问操作符中指定相应的下标。重新调用相对于0的JSON数组索引: - -$.track.segments[0].location - + 要只返回第一个段的坐标,可以在[]访问操作符中指定相应的下标。请记住,JSON数组索引从 0 开始: + +=> select jsonb_path_query(:'json', '$.track.segments[0].location'); + jsonb_path_query +------------------- + [47.763, 13.4034] + 每个路径求值步骤的结果可以由中列出的一个或多个jsonpath操作符和方法来处理。 - 每个方法名之前必须有一个点。例如,你可以得到一个数组的大小: - -$.track.segments.size() - + 每个方法名之前必须有一个点。例如,你可以得到一个数组的大小: + +=> select jsonb_path_query(:'json', '$.track.segments.size()'); + jsonb_path_query +------------------ + 2 + 在路径表达式中使用jsonpath操作符和方法的更多示例见下面 - 在定义路径时,还可以使用一个或多个与SQL中的WHERE子句类似的filter expressions。 - 过滤器表达式以问号开头,并在圆括号中提供条件: - - + 路径还可以包含过滤表达式,其作用类似于 SQL 中的WHERE子句。过滤表达式以问号开头,并在圆括号中提供条件: + ? (condition) - - + + - 过滤表达式必须在它们应该应用的路径求值步骤之后写入。该步骤的结果将被筛选,以只包括满足所提供条件的那些项。 + 过滤表达式必须在它们应该应用的路径求值步骤之后指定。该步骤的结果会经过过滤,只保留满足给定条件的项。 SQL/JSON定义了三值逻辑,因此条件可以是 true, false,或 unknownunknown值发挥与SQL NULL相同的角色,可以使用is unknown谓词进行测试。 - 进一步的路径求值步骤只使用筛选器表达式返回true的那些项。 + 进一步的路径求值步骤只使用过滤表达式返回true的那些项。 @@ -15085,40 +15332,54 @@ $.track.segments.size() - 例如,假设你想要检索所有高于130的心率值。你可以使用下面的表达式来实现这一点: - -$.track.segments[*].HR ? (@ > 130) - + 例如,假设你想要检索所有高于130的心率值。你可以使用下面的表达式来实现这一点: + +=> select jsonb_path_query(:'json', '$.track.segments[*].HR ? (@ > 130)'); + jsonb_path_query +------------------ + 135 + - 为了获得具有这些值的片段的开始时间,必须在返回开始时间之前过滤掉不相关的片段,所以过滤表达式应用于上一步,条件中使用的路径不同: - -$.track.segments[*] ? (@.HR > 130)."start time" - + 为了获得具有这些值的轨迹段的开始时间,必须先过滤掉不相关的轨迹段,再返回开始时间。因此,过滤表达式应用于上一步,条件中使用的路径也不同: + +=> select jsonb_path_query(:'json', '$.track.segments[*] ? (@.HR > 130)."start time"'); + jsonb_path_query +----------------------- + "2018-10-14 10:39:21" + - 如果需要,可以按顺序使用几个过滤器表达式。例如,下面的表达式选择所有包含有相关坐标和高心率值的位置的段的开始时间: - -$.track.segments[*] ? (@.location[1] < 13.4) ? (@.HR > 130)."start time" - + 如有需要,可以依次使用多个过滤表达式。例如,下面的表达式选择位置坐标符合要求且心率较高的所有轨迹段的开始时间: + +=> select jsonb_path_query(:'json', '$.track.segments[*] ? (@.location[1] < 13.4) ? (@.HR > 130)."start time"'); + jsonb_path_query +----------------------- + "2018-10-14 10:39:21" + - 也允许在不同嵌套层级中使用过滤器表达式。下面的示例首先根据位置筛选所有的片段,然后返回这些片段的高心率值,如果适用的话: - -$.track.segments[*] ? (@.location[1] < 13.4).HR ? (@ > 130) - + 也可以在不同嵌套层级使用过滤表达式。下面的示例先按位置筛选所有轨迹段,再返回这些轨迹段中的高心率值(如果存在): + +=> select jsonb_path_query(:'json', '$.track.segments[*] ? (@.location[1] < 13.4).HR ? (@ > 130)'); + jsonb_path_query +------------------ + 135 + - 你也可以在彼此之间嵌套过滤器表达式: - -$.track ? (exists(@.segments[*] ? (@.HR > 130))).segments.size() - - 如果包含任何具有高心率值的片段,则该表达式返回曲目的大小,否则返回空序列。 - + 还可以将过滤表达式相互嵌套。如果轨迹包含任何具有高心率值的轨迹段,下面的示例返回轨迹的大小,否则返回空序列: + +=> select jsonb_path_query(:'json', '$.track ? (exists(@.segments[*] ? (@.HR > 130))).segments.size()'); + jsonb_path_query +------------------ + 2 + + 与 SQL 标准的偏差 @@ -15167,74 +15428,120 @@ $.track ? (exists(@.segments[*] ? (@.HR > 130))).segments.size() 当查询JSON数据时,路径表达式可能与实际的JSON数据结构不匹配。 - 试图访问不存在的对象成员或数组元素会导致结构错误。SQL/JSON路径表达式有两种处理结构错误的模式: + 试图访问不存在的对象成员或数组元素会导致结构错误。SQL/JSON路径表达式有两种处理结构错误的模式: - 不严格的(lax)(默认)—路径引擎隐式地将查询的数据适配到指定的路径。任何剩余的结构错误都将被抑制并转换为空SQL/JSON序列。 - + 宽松模式(lax,默认)—路径引擎隐式地将被查询的数据适配到指定路径。凡是无法按下文所述方式修复的结构错误都会被抑制,产生的结果是不匹配。 + - - 严格的(strict) —如果发生了结构错误,则会引发错误。 - + 严格模式(strict)— 如果发生结构错误,就会引发错误。 - 如果JSON数据不符合期望的模式,不严格的(lax)模式有助于匹配JSON文档结构和路径表达式。 - 如果操作不匹配特定操作的要求,可以自动将其包装为SQL/JSON数组,也可以在执行该操作之前将其元素转换为SQL/JSON序列来解包装。 - 此外,比较操作符会自动以lax模式打开它们的操作数,因此你可以开包即用的就能比较SQL/JSON数组。 - 大小为1的数组被认为等于它的唯一元素。只有在以下情况下才不会自动展开: + 如果 JSON 数据不符合预期模式,宽松模式有助于使 JSON 文档结构与路径表达式相匹配。如果操作数不满足某个操作的要求,可以在执行该操作之前自动将其包装为 SQL/JSON 数组,或通过将其元素转换为 SQL/JSON 序列来解包。此外,在宽松模式下,比较操作符会自动解包其操作数,因此可以直接比较 SQL/JSON 数组。大小为 1 的数组被视为等于其唯一元素。以下情况不会自动解包: - 路径表达式包含type()size()方法,它们分别返回数组中的元素类型和数量。 + 路径表达式包含type()size()方法,它们分别返回类型和数组中的元素数量。 - 查询的JSON数据包含嵌套的数组。在本例中,只有最外层的数组被打开,而所有内部数组保持不变。 - 因此,隐式展开在每个路径求值步骤中只能向下进行一级。 + 查询的JSON数据包含嵌套的数组。在本例中,只有最外层的数组被解包,而所有内部数组保持不变。 + 因此,隐式解包在每个路径求值步骤中只能向下进行一级。 - 例如,当查询上面列出的GPS数据时,当使用不严格的(lax)模式时,你可以从它存储了一组片段的事实中抽象出来: - -lax $.track.segments.location - + 例如,查询上面列出的GPS数据时,使用宽松模式就无需关注轨迹段存储在数组中这一细节: + +=> select jsonb_path_query(:'json', 'lax $.track.segments.location'); + jsonb_path_query +------------------- + [47.763, 13.4034] + [47.706, 13.2635] + - 在严格的(strict)模式中,指定的路径必须与查询的JSON文档的结构完全匹配才能返回SQL/JSON项,因此使用该路径表达式会导致错误。 - 要得到与不严格的(lax)模式相同的结果,你必须显式地打开segments数组: - -strict $.track.segments[*].location - + 在严格模式下,指定的路径必须与查询的JSON文档的结构完全匹配,因此使用该路径表达式会导致错误。 + +=> select jsonb_path_query(:'json', 'strict $.track.segments.location'); +ERROR: jsonpath member accessor can only be applied to an object + + 要得到与宽松模式相同的结果,你必须显式地解包segments数组: + +=> select jsonb_path_query(:'json', 'strict $.track.segments[*].location'); + jsonb_path_query +------------------- + [47.763, 13.4034] + [47.706, 13.2635] + - .**访问器在使用lax模式时可能导致令人惊讶的结果。 - 例如,下面的查询选择每个HR值两次: - -lax $.**.HR - - 发生这个,是因为.**访问器会全部选择segments数组和它的每个元素。 - 而当使用lax模式时,.HR访问器会自动打开数组。 + .**访问器在宽松模式下可能产生意外结果。 + 例如,下面的查询选择每个HR值两次: + +=> select jsonb_path_query(:'json', 'lax $.**.HR'); + jsonb_path_query +------------------ + 73 + 135 + 73 + 135 + + 这是因为.**访问器既选择segments数组,又选择它的每个元素。 + 而在宽松模式下,.HR访问器会自动解包数组。 为了避免意外的结果,我们建议仅在严格模式下使用.**访问器。 - 下面的查询选择每个HR值仅一次: - -strict $.**.HR - + 下面的查询选择每个HR值仅一次: + +=> select jsonb_path_query(:'json', 'strict $.**.HR'); + jsonb_path_query +------------------ + 73 + 135 + + + 数组解包也可能产生意外结果。请看下面这个选取所有location数组的示例: + +=> select jsonb_path_query(:'json', 'lax $.track.segments[*].location'); + jsonb_path_query +------------------- + [47.763, 13.4034] + [47.706, 13.2635] +(2 rows) + + 它会如预期那样返回完整数组。但应用过滤表达式时,数组会被解包,以便对每个元素求值,最终只返回匹配该表达式的元素: + +=> select jsonb_path_query(:'json', 'lax $.track.segments[*].location ?(@[*] > 15)'); + jsonb_path_query +------------------ + 47.763 + 47.706 +(2 rows) + + 尽管路径表达式选取的是完整数组,结果仍然如此。使用严格模式可以恢复选取数组的行为: + +=> select jsonb_path_query(:'json', 'strict $.track.segments[*].location ?(@[*] > 15)'); + jsonb_path_query +------------------- + [47.763, 13.4034] + [47.706, 13.2635] +(2 rows) + + @@ -15242,8 +15549,7 @@ strict $.**.HR SQL/JSON 路径操作符和方法 - 显示了jsonpath中可用的操作符和方法。 - 请注意,虽然一元操作符和方法可以应用于由前一个路径步骤产生的多个值,二元操作符(加法等)只能应用于单个值。 + 列出了jsonpath中可用的操作符和方法。请注意,一元操作符和方法可以应用于前一个路径步骤产生的多个值,而二元操作符(加法等)只能应用于单个值。在宽松模式下,对数组应用方法时,会对数组中的每个值执行该方法。例外是.type().size(),它们作用于数组本身。 @@ -15254,228 +15560,442 @@ strict $.**.HR - 操作符/方法 + 操作符/方法 + + + 描述 + + + 示例 + + + + + + + + + number + number + number + + + 加法 + + + jsonb_path_query('[2]', '$[0] + 3') + 5 + + + + + + + number + number + + + 一元加号(无操作);与加法不同,这个可以迭代多个值 + + + jsonb_path_query_array('{"x": [2,3,4]}', '+ $.x') + [2, 3, 4] + + + + + + number - number + number + + + 减法 + + + jsonb_path_query('[2]', '7 - $[0]') + 5 + + + + + + - number + number + + + 取负;与减法不同,可以遍历多个值。 + + + jsonb_path_query_array('{"x": [2,3,4]}', '- $.x') + [-2, -3, -4] + + + + + + number * number + number + + + 乘法 + + + jsonb_path_query('[4]', '2 * $[0]') + 8 + + + + + + number / number + number + + + 除法 + + + jsonb_path_query('[8.5]', '$[0] / 2') + 4.2500000000000000 + + + + + + number % number + number + + + 取模(余数) + + + jsonb_path_query('[32]', '$[0] % 10') + 2 + + + + + + value . type() + string + + + JSON项的类型 (参见 json_typeof) + + + jsonb_path_query_array('[1, "2", {}]', '$[*].type()') + ["number", "string", "object"] + + + + + + value . size() + number + + + JSON项的大小(数组元素的数量,如果不是数组则为1) + + + jsonb_path_query('{"m": [11, 15]}', '$.m.size()') + 2 + + + + + + value . boolean() + boolean + + + 将 JSON 布尔值、数字或字符串转换为布尔值。 + + + jsonb_path_query_array('[1, "yes", false]', '$[*].boolean()') + [true, true, false] + + + + + + value . string() + string + + + 将 JSON 布尔值、数字、字符串或日期时间转换为字符串值。 + + + jsonb_path_query_array('[1.23, "xyz", false]', '$[*].string()') + ["1.23", "xyz", "false"] + + + jsonb_path_query('"2023-08-15 12:34:56"', '$.timestamp().string()') + "2023-08-15T12:34:56" + + + + + + value . double() + number - 描述 + 从JSON数字或字符串转换过来的近似浮点数 - 示例 + jsonb_path_query('{"len": "1.9"}', '$.len.double() * 2') + 3.8 - - - - number + number + number . ceiling() number - 加法 + 大于或等于给定数字的最接近的整数 - jsonb_path_query('[2]', '$[0] + 3') - 5 + jsonb_path_query('{"h": 1.3}', '$.h.ceiling()') + 2 - + number + number . floor() number - 一元加号(无操作);与加法不同,这个可以迭代多个值 + 小于或等于给定数字的最近整数 - jsonb_path_query_array('{"x": [2,3,4]}', '+ $.x') - [2, 3, 4] + jsonb_path_query('{"h": 1.7}', '$.h.floor()') + 1 - number - number + number . abs() number - 减法 + 给定数字的绝对值 - jsonb_path_query('[2]', '7 - $[0]') - 5 + jsonb_path_query('{"z": -0.3}', '$.z.abs()') + 0.3 - - number - number + value . bigint() + bigint - 否定;与减法不同,它可以迭代多个值 + 将 JSON 数字或字符串转换为大整数值。 - jsonb_path_query_array('{"x": [2,3,4]}', '- $.x') - [-2, -3, -4] + jsonb_path_query('{"len": "9876543219"}', '$.len.bigint()') + 9876543219 - number * number - number + value . decimal( [ precision [ , scale ] ] ) + decimal - 乘法 + 将 JSON 数字或字符串转换为经过舍入的十进制数值(precisionscale必须为整数值)。 - jsonb_path_query('[4]', '2 * $[0]') - 8 + jsonb_path_query('1234.5678', '$.decimal(6, 2)') + 1234.57 - number / number - number + value . integer() + integer - 除法 + 将 JSON 数字或字符串转换为整数值。 - jsonb_path_query('[8.5]', '$[0] / 2') - 4.2500000000000000 + jsonb_path_query('{"len": "12345"}', '$.len.integer()') + 12345 - number % number - number + value . number() + numeric - 模数 (余数) + 将 JSON 数字或字符串转换为数值。 - jsonb_path_query('[32]', '$[0] % 10') - 2 + jsonb_path_query('{"len": "123.45"}', '$.len.number()') + 123.45 - value . type() - string + string . datetime() + datetime_type + (见注) - JSON项的类型 (参见 json_typeof) + 从字符串转换过来的日期/时间值 - jsonb_path_query_array('[1, "2", {}]', '$[*].type()') - ["number", "string", "object"] + jsonb_path_query('["2015-8-1", "2015-08-12"]', '$[*] ? (@.datetime() < "2015-08-2".datetime())') + "2015-8-1" - value . size() - number + string . datetime(template) + datetime_type + (见注) - JSON项的大小(数组元素的数量,如果不是数组则为1) + 使用指定的to_timestamp模板从字符串转换过来的日期/时间值 - jsonb_path_query('{"m": [11, 15]}', '$.m.size()') - 2 + jsonb_path_query_array('["12:30", "18:40"]', '$[*].datetime("HH24:MI")') + ["12:30:00", "18:40:00"] - value . double() - number + string . date() + date - 从JSON数字或字符串转换过来的近似浮点数 + 将字符串转换为日期值。 - jsonb_path_query('{"len": "1.9"}', '$.len.double() * 2') - 3.8 + jsonb_path_query('"2023-08-15"', '$.date()') + "2023-08-15" - number . ceiling() - number + string . time() + time without time zone - 大于或等于给定数字的最接近的整数 + 将字符串转换为不带时区的时间值。 - jsonb_path_query('{"h": 1.3}', '$.h.ceiling()') - 2 + jsonb_path_query('"12:34:56"', '$.time()') + "12:34:56" - number . floor() - number + string . time(precision) + time without time zone - 小于或等于给定数字的最近整数 + 将字符串转换为不带时区的时间值,并将秒的小数部分调整到给定精度。 - jsonb_path_query('{"h": 1.7}', '$.h.floor()') - 1 + jsonb_path_query('"12:34:56.789"', '$.time(2)') + "12:34:56.79" - number . abs() - number + string . time_tz() + time with time zone - 给定数字的绝对值 + 将字符串转换为带时区的时间值。 - jsonb_path_query('{"z": -0.3}', '$.z.abs()') - 0.3 + jsonb_path_query('"12:34:56 +05:30"', '$.time_tz()') + "12:34:56+05:30" - string . datetime() - datetime_type - (see note) + string . time_tz(precision) + time with time zone - 从字符串转换过来的日期/时间值 + 将字符串转换为带时区的时间值,并将秒的小数部分调整到给定精度。 - jsonb_path_query('["2015-8-1", "2015-08-12"]', '$[*] ? (@.datetime() < "2015-08-2".datetime())') - "2015-8-1" + jsonb_path_query('"12:34:56.789 +05:30"', '$.time_tz(2)') + "12:34:56.79+05:30" - string . datetime(template) - datetime_type - (see note) + string . timestamp() + timestamp without time zone - 使用指定的to_timestamp模板从字符串转换过来的日期/时间值 + 将字符串转换为不带时区的时间戳值。 - jsonb_path_query_array('["12:30", "18:40"]', '$[*].datetime("HH24:MI")') - ["12:30:00", "18:40:00"] + jsonb_path_query('"2023-08-15 12:34:56"', '$.timestamp()') + "2023-08-15T12:34:56" + + + + + + string . timestamp(precision) + timestamp without time zone + + + 将字符串转换为不带时区的时间戳值,并将秒的小数部分调整到给定精度。 + + + jsonb_path_query('"2023-08-15 12:34:56.789"', '$.timestamp(2)') + "2023-08-15T12:34:56.79" + + + + + + string . timestamp_tz() + timestamp with time zone + + + 将字符串转换为带时区的时间戳值。 + + + jsonb_path_query('"2023-08-15 12:34:56 +05:30"', '$.timestamp_tz()') + "2023-08-15T12:34:56+05:30" + + + + + + string . timestamp_tz(precision) + timestamp with time zone + + + 将字符串转换为带时区的时间戳值,并将秒的小数部分调整到给定精度。 + + + jsonb_path_query('"2023-08-15 12:34:56.789 +05:30"', '$.timestamp_tz(2)') + "2023-08-15T12:34:56.79+05:30" @@ -15505,7 +16025,7 @@ strict $.**.HR datetime()方法依次尝试将其输入字符串与date, timetz, time,timestamptz, 和 timestamp的ISO格式进行匹配。 - 它在第一个匹配格式时停止,并发出相应的数据类型。 + 它在第一个匹配格式时停止,并返回相应数据类型的值。 @@ -15513,26 +16033,26 @@ strict $.**.HR - datetime()datetime(template)方法使用与to_timestamp SQL函数相同的解析规则(see ),但有三个例外。 + datetime()datetime(template)方法使用与to_timestamp SQL函数相同的解析规则(参见),但有三个例外。 首先,这些方法不允许不匹配的模板模式。 - 其次,模板字符串中只允许以下分隔符:减号、句点、solidus(斜杠)、逗号、撇号、分号、冒号和空格。 + 其次,模板字符串中只允许以下分隔符:减号、句点、斜杠、逗号、撇号、分号、冒号和空格。 第三,模板字符串中的分隔符必须与输入字符串完全匹配。 - 如果需要比较不同的日期/时间类型,则应用隐式转换。 + 如果需要比较不同的日期/时间类型,则应用隐式类型转换。 date值可以转换为timestamptimestamptz, timestamp可以转换为timestamptz, time可以转换为timetz。 - 但是,除了第一个转换外,其他所有转换都依赖于当前设置,因此只能在时区感知的jsonpath函数中执行。 + 但是,除了第一个转换外,其他所有转换都依赖于当前设置,因此只能在时区感知的jsonpath函数中执行。类似地,其他将字符串转换为日期/时间类型的日期/时间相关方法也会进行这种转换,这可能涉及当前的设置。因此,这些转换同样只能在时区感知的jsonpath函数中执行。 - 显示了适用的过滤器表达式元素。 + 显示了可用的过滤表达式元素。
- <type>jsonpath</type> 过滤器表达式元素 + <type>jsonpath</type> 过滤表达式元素 @@ -15681,7 +16201,7 @@ strict $.**.HR value - JSON常数null(注意,与SQL不同,与null比较可以正常工作) + JSON 常量null(注意,与SQL不同,与null比较可以正常工作) jsonb_path_query('[{"name": "Mary", "job": null}, {"name": "Michael", "job": "driver"}]', '$[*] ? (@.job == null) .name') @@ -15751,7 +16271,7 @@ strict $.**.HR boolean - 测试第一个操作数是否与第二个操作数给出的正则表达式匹配,可选使用由一串flag字符描述的修改(参见)。 + 测试第一个操作数是否与第二个操作数给出的正则表达式匹配;可以用一串flag标志字符调整匹配行为(参见)。 jsonb_path_query_array('["abc", "abd", "aBdC", "abdacb", "babc"]', '$[*] ? (@ like_regex "^ab.*c")') @@ -15807,31 +16327,28 @@ strict $.**.HR LIKE_REGEX - in SQL/JSON + 用于 SQL/JSON - - SQL/JSON路径表达式允许通过like_regex过滤器将文本匹配为正则表达式。 - 例如,下面的SQL/JSON路径查询将不区分大小写地匹配以英语元音开头的数组中的所有字符串: - + SQL/JSON 路径表达式允许使用like_regex过滤器,将文本与正则表达式进行匹配。例如,以下 SQL/JSON 路径查询会以不区分大小写的方式,匹配数组中所有以英语元音字母开头的字符串: $[*] ? (@ like_regex "^[aeiou]" flag "i") - 可选的flag字符串可以包括一个或多个字符i用于不区分大小写的匹配,m允许^$在换行时匹配,s允许.匹配换行符,q引用整个模式(将行为简化为一个简单的子字符串匹配)。 + 可选的flag字符串可以包括一个或多个字符i用于不区分大小写的匹配,m允许^$在换行时匹配,s允许.匹配换行符,q将整个模式按字面量处理(将行为简化为一个简单的子字符串匹配)。 SQL/JSON标准借用了来自LIKE_REGEX操作符的正则表达式定义,其使用了XQuery标准。 PostgreSQL目前不支持LIKE_REGEX操作符。因此,like_regex过滤器是使用中描述的POSIX正则表达式引擎来实现的。 - 这导致了与标准SQL/JSON行为的各种细微差异,这在中进行了分类。 - 但是请注意,这里描述的标志字母不兼容并不适用于SQL/JSON,因为它将XQuery标志字母翻译为符合POSIX引擎的预期。 + 这导致了与标准SQL/JSON行为的各种细微差异,这些差异列在中。 + 但是请注意,这里描述的标志字母不兼容并不适用于SQL/JSON,因为 SQL/JSON 会将 XQuery 标志字母转换为 POSIX 引擎所预期的形式。 - 请记住,like_regex的模式参数是一个JSON路径字符串文字,根据给出的规则编写。 - 这特别意味着在正则表达式中要使用的任何反斜杠都必须加倍。例如,匹配只包含数字的根文档的字符串值: + 请记住,like_regex的模式参数是一个JSON 路径字符串字面量,根据给出的规则编写。 + 这特别意味着在正则表达式中要使用的任何反斜杠都必须加倍。例如,匹配根文档中仅包含数字的字符串值: $.* ? (@ like_regex "^\\d+$") @@ -16151,18 +16668,18 @@ DETAIL: Missing "]" after array dimensions. 列。这些列可以通过一个看起来与顶层 COLUMNS 子句类似的 COLUMNS 子句来指定。由 NESTED COLUMNS 构造的行称为子行,它们会与父 - COLUMNS 子句中指定的列所构造的行联接, + COLUMNS 子句中指定的列所构造的行连接, 从而得到最终视图中的行。子列自身也可以包含 NESTED PATH 说明,因此可以提取位于任意嵌套层级中的数据。 在同一层级上由多个 NESTED PATH 生成的列彼此视为 - 兄弟,它们在与父行联接后的行通过 + 兄弟,它们在与父行连接后的行通过 UNION 进行组合。 - 由 JSON_TABLE 生成的行会与生成它们的行进行横向联接, + 由 JSON_TABLE 生成的行会与生成它们的行进行横向连接, 因此你无需显式地将构造出来的视图与保存 JSON - 数据的原始表进行联接。 + 数据的原始表进行连接。 @@ -16300,9 +16817,8 @@ JSON_TABLE ( 该值对应于将 PATH 表达式应用到行模式后是否产生任何值。 - 指定的 type 应当具有从 - boolean 类型进行强制转换的能力。 - + 应当存在从boolean到指定type的类型转换。 + 你还可以选择使用 ON ERROR 来指定: 当 JSON 路径求值期间发生错误,或者将 SQL/JSON 值强制转换为指定类型时发生错误时, @@ -16474,7 +16990,7 @@ SELECT jt.* FROM 下面是在上述查询基础上的修改版本,用来展示如何使用 NESTED PATH 填充 title 和 director - 列,并说明它们如何与父列 id 和 kind 联接: + 列,并说明它们如何与父列 id 和 kind 连接: SELECT jt.* FROM @@ -16531,7 +17047,7 @@ SELECT jt.* FROM 下面展示了另一个以不同 JSON 对象作为输入的查询。它展示了 NESTED 路径 $.movies[*] 和 - $.books[*] 之间通过 UNION 实现的“兄弟联接”, + $.books[*] 之间通过 UNION 实现的“兄弟连接”, 以及在 NESTED 层级上使用 FOR ORDINALITY 列(列 movie_idbook_idauthor_id): @@ -16583,11 +17099,11 @@ COLUMNS ( 序列操作函数 - sequence + 序列 - 本节描述对序列对象进行操作的函数,也称为序列生成器或简称序列。 + 本节描述用于操作序列对象(也称为序列生成器,或简称序列)的函数。 序列对象是使用创建的特殊单行表。 序列对象通常用于为表中的行生成惟一标识符。在中列出的序列函数,提供了简单的、多用户安全方法,用于从序列对象中获取连续的序列值。 @@ -16619,12 +17135,12 @@ COLUMNS ( bigint - 将序列对象推进到下一个值并返回该值。这是自动完成的:即使多个会话并发地执行nextval,每个会话也会安全地接收到不同的序列值。 - 如果序列对象是用默认形参创建的,则连续的nextval调用将返回以1开始的连续值。 + 将序列对象推进到下一个值并返回该值。这个操作是原子的:即使多个会话并发地执行nextval,每个会话也会安全地接收到不同的序列值。 + 如果序列对象是用默认参数创建的,则连续的nextval调用将返回以1开始的连续值。 其他行为可以通过在命令中使用适当的参数获得。 - 这个函数需要USAGEUPDATE权限在序列上。 + 这个函数需要序列上的USAGEUPDATE权限。 @@ -16637,16 +17153,16 @@ COLUMNS ( bigint - 设置序列对象的当前值,以及可选的它的is_called标志。 + 设置序列对象的当前值,并可选地设置其is_called标志。 双参数形式将序列的last_value字段设置为指定的值,并将其is_called字段设置为true,意味着下一个nextval将在返回值之前推进序列。 currval将报告的值也设置为指定的值。在三参数形式中,is_called可以设置为truefalsetrue与双参数形式具有相同的效果。 - 如果设置为false,下一个nextval将返回指定的值,序列推进从下面的nextval开始。 - 而且,currval报告的值在这种情况下不会改变。例如, + 如果设置为false,下一个nextval将返回指定的值,序列推进从再下一次调用nextval开始。 + 而且,currval报告的值在这种情况下不会改变。例如: -SELECT setval('myseq', 42); Next nextval will return 43 +SELECT setval('myseq', 42); 下一次 nextval 将返回 43 SELECT setval('myseq', 42, true); 同上 -SELECT setval('myseq', 42, false); Next nextval will return 42 +SELECT setval('myseq', 42, false); 下一次 nextval 将返回 42 setval返回的结果就是它的第二个参数的值。 @@ -16664,8 +17180,7 @@ SELECT setval('myseq', 42, false); Next nextvalbigint - 返回nextval在当前会话中为该序列最近获取的值。(如果在这个会话中没有为这个序列调用nextval会报告错误。) - 因为它返回的是一个会话本地值,所以它给出了一个可预测的答案,即自当前会话以来,其他会话是否执行了nextval。 + 返回当前会话中最近一次针对该序列调用nextval所获得的值。(如果当前会话从未针对该序列调用过nextval,则会报错。)由于返回的是会话局部值,无论其他会话是否在当前会话调用之后执行过nextval,结果都是可预测的。 这个函数需要序列上的USAGESELECT权限。 @@ -16717,9 +17232,7 @@ SELECT setval('myseq', 42, false); Next nextval - 序列函数所要操作的序列由regclass参数指定,该参数只是pg_class系统目录中序列的OID。 - 你不必手工查找OID,不过,因为regclass数据类型的输入转换器将为您完成这项工作。 - 详见 + 序列函数所要操作的序列由regclass参数指定,该参数就是序列在pg_class系统目录中的 OID。不过,不必手动查找 OID,因为regclass数据类型的输入转换器会完成这项工作。详见 @@ -16766,7 +17279,7 @@ CASE WHEN condition THEN result - CASE子句可以用于任何表达式可以出现的地方。每一个condition是一个返回boolean结果的表达式。如果结果为真,那么CASE表达式的结果就是符合条件的result,并且剩下的CASE表达式不会被处理。如果条件的结果不为真,那么以相同方式搜寻任何随后的WHEN子句。如果没有WHEN condition为真,那么CASE表达式的值就是在ELSE子句里的result。如果省略了ELSE子句而且没有条件为真,结果为空。 + CASE子句可以用于任何表达式可以出现的地方。每一个condition是一个返回boolean结果的表达式。如果结果为真,那么CASE表达式的结果就是紧随该条件后的result,并且剩下的CASE表达式不会被处理。如果条件的结果不为真,那么以相同方式搜寻任何随后的WHEN子句。如果没有WHEN condition为真,那么CASE表达式的值就是在ELSE子句里的result。如果省略了ELSE子句而且没有条件为真,结果为 null。 @@ -16810,7 +17323,7 @@ CASE expression END - 第一个expression会被计算,然后与所有在WHEN子句中的每一个value对比,直到找到一个相等的。如果没有找到匹配的,则返回在ELSE子句中的result(或者控制)。 这类似于 C 里的switch语句。 + 第一个expression会被计算,然后与所有在WHEN子句中的每一个value对比,直到找到一个相等的。如果没有找到匹配的,则返回在ELSE子句中的result(或者 null 值)。 这类似于 C 里的switch语句。 @@ -16841,11 +17354,7 @@ SELECT ... WHERE CASE WHEN x <> 0 THEN y/x > 1.5 ELSE false END; - 如中所述,在有几种情况中一个表达式的子表达式 - 会被计算多次,因此CASE只计算必要的表达式这 - 一原则并非不可打破。例如一个常量子表达式1/0通常将会在规划时导致一次 - 除零错误,即便它位于一个执行时永远也不会进入的CASE分支时也是 - 如此。 + 如所述,在多种情况下,表达式中的子表达式会在不同阶段求值,因此CASE只计算必要的子表达式这一原则并非绝对成立。例如,常量子表达式1/0通常会在规划时导致除零错误,即便它位于一个运行时永远不会进入的CASE分支中也是如此。 @@ -16870,19 +17379,19 @@ SELECT ... WHERE CASE WHEN x <> 0 THEN y/x > 1.5 ELSE false END; - COALESCE函数返回它的第一个非空参数的值。当且仅当所有参数都为空时才会返回空。它常用于在为显示目的检索数据时用缺省值替换空值。例如: + COALESCE函数返回参数中第一个不为 null 的值。只有所有参数都为 null 时,才返回 null。它常用于在检索数据以供显示时,用默认值替换 null 值。例如: SELECT COALESCE(description, short_description, '(none)') ... - 如果description不为空,这将会返回它的值,否则如果short_description非空则返回short_description的值,如果前两个都为空则返回(none)。 + 此表达式返回description,前提是它不为 null,否则返回short_description,前提是它不为 null,否则返回(none) - 所有参数都必须转换为一个公共数据类型,它将是结果的类型 (详情参见 )。 + 所有参数都必须能转换为同一个数据类型,它将是结果的类型(详情参见)。 - 和CASE表达式一样,COALESCE将不会 计算无助于判断结果的参数;也就是说,在第一个非空参数右边的参数不会被计算。这个 SQL 标准函数提供了类似于NVLIFNULL的能力,它们被用在某些其他数据库系统中。 + 和CASE表达式一样,COALESCE只计算确定结果所需的参数;也就是说,在第一个不为 null 的参数右边的参数不会被计算。这个 SQL 标准函数提供了类似于NVLIFNULL的能力,它们被用在某些其他数据库系统中。 @@ -16898,12 +17407,12 @@ SELECT COALESCE(description, short_description, '(none)') ... - 当value1value2相等时,NULLIF返回一个空值。 + 当value1value2相等时,NULLIF返回 null。 否则它返回value1。 这些可以用于执行前文给出的COALESCE示例的逆操作: SELECT NULLIF(value, '(none)') ... - 在这个示例中,如果value(none),将返回空值,否则返回value的值。 + 在这个示例中,如果value(none),将返回 null,否则返回value的值。 @@ -16938,11 +17447,11 @@ SELECT NULLIF(value, '(none)') ... - GREATESTLEAST函数从一个任意的数字表达式列表里选取最大或者最小的数值。 这些表达式必须都可以转换成一个普通的数据类型,它将会是结果类型 (参阅获取细节)。列表中的 NULL 数值将被忽略。只有所有表达式的结果都是 NULL 的时候,结果才会是 NULL。 + GREATESTLEAST函数从由任意数量的表达式组成的列表中选取最大值或最小值。这些表达式都必须能转换为同一个数据类型,该类型将作为结果类型(详情参见)。 - 请注意GREATESTLEAST都不是 SQL 标准,但却是很常见的扩展。某些其他数据库让它们在任何参数为 NULL 时返回 NULL,而不是在所有参数都为 NULL 时才返回 NULL。 + 参数列表中的 NULL 值会被忽略。只有所有表达式的求值结果都为 NULL 时,结果才为 NULL。(这与 SQL 标准不同。按照标准,只要有任意参数为 NULL,返回值就为 NULL。一些其他数据库采用这种行为。) @@ -16954,9 +17463,9 @@ SELECT NULLIF(value, '(none)') ... 显示了可以用于数组类型的专用的操作符。 除此之外,中所示的常用比较操作符也适用于数组。 - 比较操作符逐个元素的比较数组内容,使用默认的元素数据类型的B-树比较函数,并根据第一个差值进行排序。 + 比较操作符逐个元素比较数组内容,使用元素数据类型的默认 B-树比较函数,并根据第一个差异进行排序。 多维数组的元素按照行序进行访问(最后的下标变化最快)。 - 如果两个数组的内容相同但维数不等,那么维度信息中的第一个不同将决定排序顺序。 + 如果两个数组的内容相同但维度信息不同,那么维度信息中的第一个不同将决定排序顺序。
@@ -16987,7 +17496,7 @@ SELECT NULLIF(value, '(none)') ... 第一个数组是否包含第二个数组,也就是说,出现在第二个数组中的每个元素是否等于第一个数组中的某个元素? - (重复值不需要特殊处理,因此ARRAY[1]ARRAY[1,1]被认为包含对方。) + (重复元素不作特殊处理,因此ARRAY[1]ARRAY[1,1]被认为包含对方。) ARRAY[1,4,3] @> ARRAY[3,1,3] @@ -17029,8 +17538,7 @@ SELECT NULLIF(value, '(none)') ... anycompatiblearray - 连接两个数组。连接空值(NULL)或空数组不会产生任何效果(no-op);否则,数组必须具有相同的维度数(如第一个示例所示),或者维度数相差一个(如第二个示例所示)。 - 如果数组不是完全相同的元素类型,它们将被强制转换成一个共同的类型(参见)。 + 连接两个数组。连接 NULL 或空数组不会产生任何效果;否则,数组必须具有相同的维数(如第一个示例所示),或维数相差一维(如第二个示例所示)。如果数组的元素类型不同,则会将它们强制转换为同一个类型(参见)。 ARRAY[1,2,3] || ARRAY[4,5,6,7] @@ -17062,7 +17570,7 @@ SELECT NULLIF(value, '(none)') ... anycompatiblearray - 将元素连接到数组的末尾(数组必须为空或一维的[one-dimensional])。 + 将元素连接到数组的末尾(数组必须为空或一维)。 ARRAY[4,5,6] || 7 @@ -17074,7 +17582,7 @@ SELECT NULLIF(value, '(none)') ...
- 参阅获取有关数组操作符行为的更多细节。有关哪些操作符支持被索引的操作,请参阅。 + 参阅获取有关数组操作符行为的更多细节。有关哪些操作符支持索引操作,请参阅 @@ -17163,8 +17671,7 @@ SELECT NULLIF(value, '(none)') ... anyarray - 返回一个包含给定值的拷贝的数组,其维数与第二个参数指定的长度相同。 - 可选的第三个参数提供每个维度的下界值(默认为全部为 1)。 + 返回用给定值的副本填充的数组,各维的长度由第二个参数指定。可选的第三个参数提供各维的下界值(默认均为1)。 array_fill(11, ARRAY[2,3]) @@ -17245,7 +17752,7 @@ SELECT NULLIF(value, '(none)') ... integer - 返回阵列中第二个参数中第一次发生的下标,如果它不存在,则返回NULL。 + 返回第二个参数在数组中首次出现的下标;若不存在,则返回NULL。 如果给出了第三个参数,则搜索从该下标开始。数组必须是一维的。比较是使用IS NOT DISTINCT FROM语义进行的,所以可以搜索NULL @@ -17263,9 +17770,9 @@ SELECT NULLIF(value, '(none)') ... integer[] - 返回作为第一个参数的数组中第二个参数所有出现的下标的数组。 + 返回第二个参数在第一个参数所给数组中所有出现位置的下标数组。 数组必须是一维的。使用IS NOT DISTINCT FROM语义完成比较,所以可以搜索NULL。 - 只有当数组为NULL时才返回NULL;如果在数组中没有找到该值,则返回空数组。 + 只有当数组为NULL时才返回NULL;如果在数组中没有找到该值,则返回空数组。 array_positions(ARRAY['A','A','B','A'], 'A') @@ -17422,7 +17929,7 @@ SELECT NULLIF(value, '(none)') ... anyarray - 通过删除最后的n元素来裁剪数组。 + 通过删除最后的n个元素来裁剪数组。 如果数组是多维的,则只裁剪第一个维度。 @@ -17471,7 +17978,7 @@ SELECT NULLIF(value, '(none)') ... 将多个数组(可能是不同的数据类型)展开到一组行中。 如果数组的长度不完全相同,那么较短的数组将用NULL填充。 - 这种形式只在查询的FROM子句中允许;参见。 + 这种形式只允许出现在查询的 FROM 子句中;参见 select * from unnest(ARRAY[1,2], ARRAY['foo','bar','baz']) as x(a,b) @@ -17622,7 +18129,7 @@ SELECT NULLIF(value, '(none)') ... boolean - 第一个范围是否严格符合第二个(范围)? + 第一个范围是否严格地在第二个(范围)的右边? int8range(50,60) >> int8range(20,30) @@ -17706,7 +18213,7 @@ SELECT NULLIF(value, '(none)') ... anyrange - 计算范围的差异。第二个范围必须不能包含在第一个(范围)中,以使差异不是一个单一的范围。 + 计算范围的差集。第二个范围不能被包含在第一个范围中而导致差集无法表示为单个范围。 int8range(5,15) - int8range(10,20) @@ -17800,7 +18307,7 @@ SELECT NULLIF(value, '(none)') ... boolean - 第一个多范围是否被第二个所包括? + 第一个多范围是否被第二个所包含? '{[2,4)}'::int4multirange <@ '{[1,7)}'::int4multirange @@ -17814,7 +18321,7 @@ SELECT NULLIF(value, '(none)') ... boolean - 多范围是否被范围所包括。 + 多范围是否被范围所包含? '{[2,4)}'::int4multirange <@ int4range(1,7) @@ -17828,7 +18335,7 @@ SELECT NULLIF(value, '(none)') ... boolean - 范围是否被多范围所包括? + 范围是否被多范围所包含? int4range(2,4) <@ '{[1,7)}'::int4multirange @@ -17926,7 +18433,7 @@ SELECT NULLIF(value, '(none)') ... boolean - 范围是否完全的在多范围左边? + 范围是否完全在多范围左边? int8range(1,10) << '{[100,110)}'::int8multirange @@ -17968,7 +18475,7 @@ SELECT NULLIF(value, '(none)') ... boolean - 范围是否完全在多范围右边。 + 范围是否完全在多范围右边? int8range(50,60) >> '{[20,30)}'::int8multirange @@ -18136,7 +18643,7 @@ SELECT NULLIF(value, '(none)') ... anymultirange - 计算多范围的差异。 + 计算多范围的差集。 '{[5,20)}'::int8multirange - '{[10,15)}'::int8multirange @@ -18148,21 +18655,21 @@ SELECT NULLIF(value, '(none)') ... - 当涉及一个空范围或多范围时,左部/右部/相邻操作符总是返回假;即一个空范围被认为不在任何其他范围前面或者后面。 + 涉及空范围或空多范围时,左侧、右侧和相邻操作符总是返回假;也就是说,空范围不被视为位于任何其他范围之前或之后。 - 在其他地方,空范围和多范围被视为添加标识:与空值的任何交集都是它自己。 - 任何减去空值的都是它自己。 - 空的多范围与空的范围具有完全相同的点。 + 在其他运算中,空范围和空多范围被视为加法单位元:任何值与空值求并集,结果仍是该值本身。 + 任何值减去空值,结果也仍是该值本身。 + 空多范围与空范围具有完全相同的点。 每个范围都包含空范围。 每个多范围包含任意多个空范围。 - 范围交集和差异操作符将失败,如果结果范围需要包含两个不相交的子范围,因为这样的范围无法表示。 - 还有用于求交集和差集的单独操作符,它们接受多范围参数并返回多范围,即使参数彼此不相交也不会失败。 - 因此,如果需要对可能不相交的范围进行交集或差异操作,你可以通过首先将范围转换为多范围来避免错误。 + 如果结果范围需要包含两个不相交的子范围,范围并集和差集操作符会失败,因为这样的范围无法表示。 + 另有接受多范围参数并返回多范围的并集和差集操作符,即使参数彼此不相交,也不会失败。 + 因此,如果需要对可能不相交的范围求并集或差集,可以先将范围转换为多范围来避免错误。 @@ -18200,7 +18707,7 @@ SELECT NULLIF(value, '(none)') ... anyelement - 提取范围的下界(如果范围为空或下界为无限,则为NULL)。 + 提取范围的下界(如果范围为空或没有下界,则返回NULL)。 lower(numrange(1.1,2.2)) @@ -18217,7 +18724,7 @@ SELECT NULLIF(value, '(none)') ... anyelement - 提取范围的上限(如果范围为空或上限为无限,则为NULL)。 + 提取范围的上界(如果范围为空或没有上界,则返回NULL)。 upper(numrange(1.1,2.2)) @@ -18285,7 +18792,7 @@ SELECT NULLIF(value, '(none)') ... boolean - 范围的下界是无限的吗? + 范围是否没有下界?(下界为-Infinity时返回假。) lower_inf('(,)'::daterange) @@ -18302,7 +18809,7 @@ SELECT NULLIF(value, '(none)') ... boolean - 范围的上界是无限的吗? + 范围是否没有上界?(上界为Infinity时返回假。) upper_inf('(,)'::daterange) @@ -18359,7 +18866,7 @@ SELECT NULLIF(value, '(none)') ... anyelement - 提取多范围的下界 (NULL 如果多范围为空或下界为无穷的)。 + 提取多范围的下界(如果多范围为空或没有下界,则返回NULL)。 lower('{[1.1,2.2)}'::nummultirange) @@ -18376,7 +18883,7 @@ SELECT NULLIF(value, '(none)') ... anyelement - 提取多范围的上界 (NULL 如果多范围为空或上界为无穷的)。 + 提取多范围的上界(如果多范围为空或没有上界,则返回NULL)。 upper('{[1.1,2.2)}'::nummultirange) @@ -18410,7 +18917,7 @@ SELECT NULLIF(value, '(none)') ... boolean - 多范围的下界是否包括? + 多范围的下界是否包含在内? lower_inc('{[1.1,2.2)}'::nummultirange) @@ -18427,7 +18934,7 @@ SELECT NULLIF(value, '(none)') ... boolean - 多范围的上界是否包括? + 多范围的上界是否包含在内? upper_inc('{[1.1,2.2)}'::nummultirange) @@ -18444,7 +18951,7 @@ SELECT NULLIF(value, '(none)') ... boolean - 多范围的下界是无限的么? + 多范围是否没有下界?(下界为-Infinity时返回假。) lower_inf('{(,)}'::datemultirange) @@ -18461,7 +18968,7 @@ SELECT NULLIF(value, '(none)') ... boolean - 多范围的上界是无限的么? + 多范围是否没有上界?(上界为Infinity时返回假。) upper_inf('{(,)}'::datemultirange) @@ -18489,7 +18996,7 @@ SELECT NULLIF(value, '(none)') ... - multirange (function) + multirange(函数) multirange ( anyrange ) anymultirange @@ -18507,14 +19014,13 @@ SELECT NULLIF(value, '(none)') ... unnest - for multirange + 用于多范围 unnest ( anymultirange ) setof anyrange - 扩展多范围为一组范围。 - 范围按存储顺序读出(升序)。 + 将多范围按升序展开为一组范围。 unnest('{[1,2), [3,4)}'::int4multirange) @@ -18530,7 +19036,7 @@ SELECT NULLIF(value, '(none)') ... - lower_incupper_inclower_inf、 和 upper_inf 函数对空范围(empty range)或多范围都返回假(false)。 + lower_incupper_inclower_infupper_inf 函数对空范围或空多范围都返回假。 @@ -18544,17 +19050,22 @@ SELECT NULLIF(value, '(none)') ... - 聚合函数从一个输入值的集合计算出一个单一值。 - 内置的通用聚合函数在中列出,而统计性聚合是在中列出。 + 聚合函数从一个输入值的集合计算出一个单一结果。 + 内置的通用聚合函数在中列出,而统计聚合函数在中列出。 内置的组内有序集聚合函数在中列出,而内置的组内假想集聚合在中列出。 与聚合函数紧密相关的分组操作在中列出。 - 中会解释针对聚合函数的特殊语法考虑。额外的介绍信息请参考。 + 中会解释针对聚合函数的特殊语法注意事项。更多入门信息请参考 支持部分模式的聚合函数能够参与各种优化,例如并行聚合。 + + 虽然下面所有聚合函数都接受可选的ORDER BY子句 + (详见),但这里只在输出受排序影响的聚合函数签名中列出了该子句。 + + 通用聚合函数 @@ -18576,35 +19087,49 @@ SELECT NULLIF(value, '(none)') ... + + + + any_value + + any_value ( anyelement ) + 与输入类型相同 + + + 从非空输入值中返回任意一个值。 + + + + array_agg - array_agg ( anynonarray ) + array_agg ( anynonarray ORDER BY input_sort_columns ) anyarray 将所有输入值,包括空值,收集到一个数组中。 - No + - array_agg ( anyarray ) + array_agg ( anyarray ORDER BY input_sort_columns ) anyarray - 将所有输入数组连接到一个更高维度的数组中。(输入必须都具有相同的维度,并且不能为空(empty)或空值(NULL)。) + 将所有输入数组连接成维数增加一维的数组。(所有输入的维数必须相同,且不能是空数组或空值(NULL)。) - No + - average + 平均值 avg @@ -18639,7 +19164,7 @@ SELECT NULLIF(value, '(none)') ... 计算所有非空输入值的平均值(算术平均值)。 - Yes + @@ -18663,9 +19188,9 @@ SELECT NULLIF(value, '(none)') ... bit - 计算所有非空输入值的逐位AND。 + 计算所有非空输入值的按位与。 - Yes + @@ -18689,9 +19214,9 @@ SELECT NULLIF(value, '(none)') ... bit - 计算所有非空输入值的逐位OR。 + 计算所有非空输入值的按位或。 - Yes + @@ -18715,124 +19240,269 @@ SELECT NULLIF(value, '(none)') ... bit - 计算所有非空输入值的按位异或。 - 可用作一组无序的值集合的校验和。 + 计算所有非空输入值的按位异或。 + 可用作一组无序的值集合的校验和。 + + + + + + + + bool_and + + bool_and ( boolean ) + boolean + + + 如果全部非空输入值都为真则返回真,否则返回假。 + + + + + + + + bool_or + + bool_or ( boolean ) + boolean + + + 如果任何非空输入值为真则返回真,否则返回假。 + + + + + + + + count + + count ( * ) + bigint + + + 计算输入行的数量。 + + + + + + + count ( "any" ) + bigint + + + 计算输入值不为空的输入行的数量。 + + + + + + + + every + + every ( boolean ) + boolean + + + 这是标准 SQL 中与bool_and等价的函数。 + + + + + + + + json_agg + + json_agg ( anyelement ORDER BY input_sort_columns ) + json + + + + jsonb_agg + + jsonb_agg ( anyelement ORDER BY input_sort_columns ) + jsonb + + + 收集所有输入值,包括空值,到一个JSON数组。根据to_jsonto_jsonb将值转换为JSON。 + + + + + + + + json_agg_strict + + json_agg_strict ( anyelement ) + json + + + + jsonb_agg_strict + + jsonb_agg_strict ( anyelement ) + jsonb + + + 将所有非空输入值收集到一个JSON数组中,跳过空值。根据to_jsonto_jsonb将值转换为JSON。 - Yes + - - bool_and - - bool_and ( boolean ) - boolean + json_arrayagg + json_arrayagg ( + value_expression + ORDER BY sort_expression + { NULL | ABSENT } ON NULL + RETURNING data_type FORMAT JSON ENCODING UTF8 ) - 如果全部非空输入值都为真则返回真,否则返回假。 + 行为与json_array相同,只是它作为一个聚合函数,因此只接受一个 + value_expression参数。 + 如果指定了ABSENT ON NULL,则会省略所有 NULL 值。 + 如果指定了ORDER BY,元素将按该顺序出现在数组中,而不是按输入顺序。 + + + SELECT json_arrayagg(v) FROM (VALUES(2),(1)) t(v) + [2, 1] - Yes + - - bool_or - - bool_or ( boolean ) - boolean + json_objectagg + json_objectagg ( + { key_expression { VALUE | ':' } value_expression } + { NULL | ABSENT } ON NULL + { WITH | WITHOUT } UNIQUE KEYS + RETURNING data_type FORMAT JSON ENCODING UTF8 ) + + + 行为与json_object相同,只是它作为一个聚合函数,因此只接受一个 + key_expression参数和一个 + value_expression参数。 - - 如果任何非空输入值为真则返回真,否则返回假。 + + SELECT json_objectagg(k:v) FROM (VALUES ('a'::text,current_date),('b',current_date + 1)) AS t(k,v) + { "a" : "2022-05-10", "b" : "2022-05-11" } - Yes + - count + json_object_agg - count ( * ) - bigint + json_object_agg ( key + "any", value + "any" + ORDER BY input_sort_columns ) + json - - 计算输入行的数量。 - - Yes - - - - - count ( "any" ) - bigint + + + jsonb_object_agg + + jsonb_object_agg ( key + "any", value + "any" + ORDER BY input_sort_columns ) + jsonb - 计算输入值不为空的输入行的数量。 + 将所有键/值对收集到一个JSON对象中。键参数强制转换为文本;值参数按照to_jsonto_jsonb进行转换。 + 值可以为空,但键不能(为空)。 - Yes + - every + json_object_agg_strict - every ( boolean ) - boolean + json_object_agg_strict ( + key "any", + value "any" ) + json + + + + jsonb_object_agg_strict + + jsonb_object_agg_strict ( + key "any", + value "any" ) + jsonb - 这是对应bool_and的SQL标准的等效物。 + 将所有键/值对收集到一个JSON对象中。键参数强制转换为文本;值参数按照to_jsonto_jsonb进行转换。 + key不能为空。如果value为空,则跳过该条目。 - Yes + - json_agg + json_object_agg_unique - json_agg ( anyelement ) + json_object_agg_unique ( + key "any", + value "any" ) json - jsonb_agg + jsonb_object_agg_unique - jsonb_agg ( anyelement ) + jsonb_object_agg_unique ( + key "any", + value "any" ) jsonb - 收集所有输入值,包括空值,到一个JSON数组。根据to_jsonto_jsonb将值转换为JSON。 + 将所有键/值对收集到一个JSON对象中。键参数强制转换为文本;值参数按照to_jsonto_jsonb进行转换。 + 值可以为空,但键不能为空。如果存在重复键,则会抛出错误。 - No + - json_object_agg + json_object_agg_unique_strict - json_object_agg ( key - "any", value - "any" ) + json_object_agg_unique_strict ( + key "any", + value "any" ) json - jsonb_object_agg + jsonb_object_agg_unique_strict - jsonb_object_agg ( key - "any", value - "any" ) + jsonb_object_agg_unique_strict ( + key "any", + value "any" ) jsonb - 将所有键/值对收集到一个JSON对象中。关键参数强制转换为文本;值参数按照to_jsonto_jsonb进行转换。 - 值可以为空,但键不能(为空)。 + 将所有键/值对收集到一个JSON对象中。键参数强制转换为文本;值参数按照to_jsonto_jsonb进行转换。 + key不能为空。如果value为空,则跳过该条目。 + 如果存在重复键,则会抛出错误。 - No + @@ -18840,8 +19510,8 @@ SELECT NULLIF(value, '(none)') ... 最大值 - max ( see text ) - same as input type + max ( 见说明 ) + 与输入类型相同 计算非空输入值的最大值。适用于任何数字、字符串、日期/时间或枚举类型, @@ -18858,8 +19528,8 @@ SELECT NULLIF(value, '(none)') ... 最小值 - min ( see text ) - same as input type + min ( 见说明 ) + 与输入类型相同 计算非空输入值的最小值。适用于任何数字、字符串、日期/时间或枚举类型, @@ -18888,7 +19558,7 @@ SELECT NULLIF(value, '(none)') ... 计算非空输入值的并集。 - No + @@ -18908,7 +19578,7 @@ SELECT NULLIF(value, '(none)') ... 计算非空输入值的交集。 - No + @@ -18922,13 +19592,14 @@ SELECT NULLIF(value, '(none)') ... string_agg ( value - bytea, delimiter bytea ) + bytea, delimiter bytea + ORDER BY input_sort_columns ) bytea 将非 NULL 输入值连接成一个字符串。在第一个值之后,每个值前面都会放置相应的delimiter(如果它不为 NULL)。 - No + @@ -18970,7 +19641,7 @@ SELECT NULLIF(value, '(none)') ... 计算非空输入值的总和。 - Yes + @@ -18978,35 +19649,28 @@ SELECT NULLIF(value, '(none)') ... xmlagg - xmlagg ( xml ) + xmlagg ( xml ORDER BY input_sort_columns ) xml - 连接非空的XML输入值(参见)。 + 连接非空的 XML 输入值(参见)。 - No +
- 应该注意的是,除了count之外,这些函数在没有选择行时返回空值。 - 特别地,行数的sum返回空值(NULL),而不是预期的零;array_agg在没有输入行时返回空值(NULL),而不是空数组。 - 必要时可使用coalesce函数以零或空数组代替空值(NULL)。 + 需要注意,除了count之外,这些函数在没有选中任何行时都会返回空值。特别地,sum在没有输入行时返回空值(NULL),而不是预期中的零;array_agg在没有输入行时返回空值(NULL),而不是空数组。必要时,可以用coalesce函数把空值(NULL)替换成零或空数组。 - 聚合函数 array_agg,json_agg, jsonb_agg,json_object_agg, jsonb_object_agg, - string_agg,和 xmlagg,以及类似的用户定义的聚合函数,根据输入值的顺序产生富有意义的不同的结果值。 - 默认情况下,这种排序是不指定的,但可以通过在聚合调用中写入ORDER BY子句来控制,如所示。 - 或者,从排序的子查询提供输入值通常也可以。例如: - + 聚合函数array_aggjson_aggjsonb_aggjson_agg_strictjsonb_agg_strictjson_object_aggjsonb_object_aggjson_object_agg_strictjsonb_object_agg_strictjson_object_agg_uniquejsonb_object_agg_uniquejson_object_agg_unique_strictjsonb_object_agg_unique_strictstring_aggxmlagg,以及类似的用户定义聚合函数,其结果值会随输入值的顺序发生实质性变化。默认情况下,输入顺序未指定,但可以在聚合调用中写入ORDER BY子句来控制,如所示。也可以用已排序的子查询提供输入值,这通常也能奏效。例如: - - 注意,如果外部查询级别包含其他处理,例如关联,则此方法可能会失败,因为这可能导致子查询的输出在计算聚合之前重新排序。 + 需要注意,如果外层查询包含连接等额外处理,这种方法可能失效,因为子查询的输出可能在计算聚合之前被重新排序。 @@ -19020,31 +19684,24 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; - 布尔聚合 bool_andbool_or 对应于标准SQL聚合 everyanysome. - PostgreSQL 支持 every, 但不支持 anysome, 因为标准语法中存在模糊性: - + 布尔聚合bool_andbool_or对应于标准 SQL 聚合everyanysome。 + PostgreSQL支持every,但不支持anysome,因为标准语法中存在歧义: SELECT b1 = ANY((SELECT b2 FROM t2 ...)) FROM t1 ...; - - 这里ANY可以被认为是引入子查询,或者是聚合函数,如果子查询返回一行布尔值。因此,不能为这些聚合提供标准名称。 +此处的ANY既可以被视为引入一个子查询,也可以在该子查询返回一行布尔值时被视为聚合函数。因此,不能将标准名称用于这些聚合。 - 习惯使用其他SQL数据库管理系统的用户可能会对count聚合应用于整个表时的性能感到失望。一个类似下面的查询: - + 习惯于其他 SQL 数据库管理系统的用户,可能会对count聚合用于整个表时的性能感到失望。如下查询: SELECT count(*) FROM sometable; - - 将需要与表大小成比例的工作:PostgreSQL将需要扫描整个表或包含表中所有行的索引。 +所需的工作量与表大小成正比:PostgreSQL需要扫描整个表,或者完整扫描一个包含表中所有行的索引。 - 显示了统计分析中常用的聚合函数。 - (这些被分离出来仅仅是为了避免使更常用的聚合列表混乱。) - 显示为接受numeric_type的函数可用于所有类型smallint, integer,bigint, numeric, real, 和 double precision。 - 在描述中提及N时,它表示所有输入表达式都非空的输入行数。在所有情况下,如果计算没有意义,则返回NULL,例如当N为0时。 + 列出了统计分析中常用的聚合函数。(将它们单独列出,只是为了避免更常用的聚合函数列表过于杂乱。)标为接受numeric_type的函数适用于smallintintegerbigintnumericrealdouble precision这些类型。描述中提到的N表示所有输入表达式都非空的输入行数。无论哪种情况,如果计算没有意义,例如N为 0,就返回NULL @@ -19079,7 +19736,7 @@ SELECT count(*) FROM sometable; - correlation + 相关性 corr @@ -19090,14 +19747,14 @@ SELECT count(*) FROM sometable; 计算相关系数。 - Yes + - covariance - population + 协方差 + 总体 covar_pop @@ -19108,14 +19765,14 @@ SELECT count(*) FROM sometable; 计算总体协方差。 - Yes + - covariance - sample + 协方差 + 样本 covar_samp @@ -19126,7 +19783,7 @@ SELECT count(*) FROM sometable; 计算样本协方差。 - Yes + @@ -19138,9 +19795,9 @@ SELECT count(*) FROM sometable; double precision
- 计算自变量的平均值,sum(X)/N. + 计算自变量的平均值,即sum(X)/N
- Yes +
@@ -19152,9 +19809,9 @@ SELECT count(*) FROM sometable; double precision
- 计算因变量的平均值,sum(Y)/N. + 计算因变量的平均值,即sum(Y)/N
- Yes +
@@ -19168,13 +19825,13 @@ SELECT count(*) FROM sometable; 计算两个输入都非空的行数。 - Yes + - regression intercept + 回归截距 regr_intercept @@ -19183,9 +19840,9 @@ SELECT count(*) FROM sometable; double precision - 计算由(XY)对决定的最小二乘拟合的线性方程的Y-截距。 + 计算由(XY)数值对确定的最小二乘拟合线性方程的 y 轴截距。 - Yes + @@ -19199,13 +19856,13 @@ SELECT count(*) FROM sometable; 计算相关系数的平方。 - Yes + - regression slope + 回归斜率 regr_slope @@ -19214,9 +19871,9 @@ SELECT count(*) FROM sometable; double precision - 计算由(X, Y)对决定的最小二乘拟合的线性方程的斜率。 + 计算由(XY)数值对确定的最小二乘拟合线性方程的斜率。 - Yes + @@ -19228,10 +19885,9 @@ SELECT count(*) FROM sometable; double precision - 计算自变量的平方和 - sum(X^2) - sum(X)^2/N. + 计算自变量的平方和,即sum(X^2) - sum(X)^2/N - Yes + @@ -19243,10 +19899,9 @@ SELECT count(*) FROM sometable; double precision - 计算独立变量乘以因变量的sum of products, - sum(X*Y) - sum(X) * sum(Y)/N. + 计算自变量与因变量的乘积和,即sum(X*Y) - sum(X) * sum(Y)/N - Yes + @@ -19258,69 +19913,62 @@ SELECT count(*) FROM sometable; double precision - 计算因变量的平方和, - sum(Y^2) - sum(Y)^2/N. + 计算因变量的平方和,即sum(Y^2) - sum(Y)^2/N - Yes + - standard deviation + 标准差 stddev stddev ( numeric_type ) - double precision - for real or double precision, - otherwise numeric + 对于realdouble precision输入,返回double precision;否则返回numeric - 这是stddev_samp的一个历史别称。 + 这是stddev_samp的一个历史别名。 - Yes + - standard deviation - population + 标准差 + 总体 stddev_pop stddev_pop ( numeric_type ) - double precision - for real or double precision, - otherwise numeric + 对于realdouble precision输入,返回double precision;否则返回numeric 计算输入值的总体标准差。 - Yes + - standard deviation - sample + 标准差 + 样本 stddev_samp stddev_samp ( numeric_type ) - double precision - for real or double precision, - otherwise numeric + 对于realdouble precision输入,返回double precision;否则返回numeric 计算输入值的样本标准差。 - Yes + @@ -19329,54 +19977,48 @@ SELECT count(*) FROM sometable; variance variance ( numeric_type ) - double precision - for real or double precision, - otherwise numeric + 对于realdouble precision输入,返回double precision;否则返回numeric - 这是 var_samp 的一个历史别称。 + 这是 var_samp 的一个历史别名。 - Yes + - variance - population + 方差 + 总体 var_pop var_pop ( numeric_type ) - double precision - for real or double precision, - otherwise numeric + 对于realdouble precision输入,返回double precision;否则返回numeric - 计算输入值的总体方差(总体标准差的平方)。 + 计算输入值的总体方差(总体标准差的平方)。 - Yes + - variance - sample + 方差 + 样本 var_samp var_samp ( numeric_type ) - double precision - for real or double precision, - otherwise numeric + 对于realdouble precision输入,返回double precision;否则返回numeric - 计算输入值的样本方差(样本标准差的平方)。 + 计算输入值的样本方差(样本标准差的平方)。 - Yes + @@ -19387,11 +20029,11 @@ SELECT count(*) FROM sometable; 这些函数有时被称为逆分布函数。 它们的聚合输入通过ORDER BY引入,还可以接受未聚合的直接参数,但后者只计算一次。 所有这些函数在其聚合输入中都忽略空值(NULL)。 - 对于使用fraction参数的函数,分数值必须在 0 到 1 之间;否则会报错。但是,如果fractionNULL,结果也将是NULL。 + 对于使用fraction参数的函数,比例值必须在 0 到 1 之间;否则会报错。但是,如果fractionNULL,结果也将是NULL - ordered-set aggregate + 有序集聚合 内置 @@ -19423,16 +20065,16 @@ SELECT count(*) FROM sometable; - mode - statistical + 众数 + 统计 mode () WITHIN GROUP ( ORDER BY anyelement ) anyelement - 计算mode,即聚合参数最频繁的值(如果有多个相同频繁的值,第一个可以任意选择)。聚合参数必须是可排序类型。 + 计算众数,即聚合参数中出现次数最多的值(若多个值的出现次数相同且最多,则任意选择其中第一个)。聚合参数必须是可排序类型。 - No + @@ -19450,9 +20092,9 @@ SELECT count(*) FROM sometable; 计算连续百分位点,该值对应于聚合参数值有序集合中的指定fraction。 - 如果需要,这将在相邻的输入项之间插入。 + 必要时会在相邻输入项之间进行插值。 - No + @@ -19467,7 +20109,7 @@ SELECT count(*) FROM sometable; 计算多个连续百分位点。结果是一个与fractions参数具有相同维度的数组,其中每个非 NULL 元素都被替换为对应百分位点的值(必要时会进行插值)。 - No + @@ -19483,7 +20125,7 @@ SELECT count(*) FROM sometable; 计算离散百分位数,即聚合参数值的有序集合中的第一个值,该值在排序中的位置等于或超过指定的fraction。 聚合参数必须是可排序类型。 - No + @@ -19496,14 +20138,14 @@ SELECT count(*) FROM sometable; 结果是一个与fractions参数具有相同维数的数组,每个非空元素都被对应于该百分位数的输入值替换。 聚合参数必须是可排序类型。 - No + - hypothetical-set aggregate + 假想集聚合 内置 @@ -19539,52 +20181,52 @@ SELECT count(*) FROM sometable; rank - hypothetical + 假设行 rank ( args ) WITHIN GROUP ( ORDER BY sorted_args ) bigint - 计算假设行的排名,包括间隔,就是说在它的同等行组中第一行的行号。 + 计算假设行的排名,允许空缺;即该行所属同等行组中第一行的行号。 - No + dense_rank - hypothetical + 假设行 dense_rank ( args ) WITHIN GROUP ( ORDER BY sorted_args ) bigint - 计算假设行的排名,没有间隔;这个功能有效地计数同等行组。 + 计算假设行的排名,没有空缺;此函数实际上对同等行组进行计数。 - No + percent_rank - hypothetical + 假设行 percent_rank ( args ) WITHIN GROUP ( ORDER BY sorted_args ) double precision - 计算假设行的相关排行,也就是(rank - 1) / (total rows - 1)。取值范围为 0 到 1(含)。 + 计算假设行的相对排名,即(rank - 1)/(总行数 - 1)。取值范围为 0 到 1(含)。 - No + cume_dist - hypothetical + 假设行 cume_dist ( args ) WITHIN GROUP ( ORDER BY sorted_args ) double precision @@ -19592,7 +20234,7 @@ SELECT count(*) FROM sometable; 计算累积分布,也就是(位于假设行之前或与假设行同等的行数)/(总行数)。取值范围为 1/N 到 1。 - No + @@ -19625,8 +20267,7 @@ SELECT count(*) FROM sometable; integer - 返回一个位掩码以指示哪个GROUP BY表达式没有包含在当前分组集中。 - 比特位被分配给最右边的参数对应于最低有效位;如果对应的表达式包含在生成当前结果行的分组集的分组条件中,则每个位为0,如果不包含则为1。 + 返回一个位掩码,指示哪些GROUP BY表达式未包含在当前分组集中。分配比特位时,最右侧参数对应最低有效位;如果相应表达式包含在生成当前结果行的分组集的分组条件中,该位为 0,否则为 1。 @@ -19634,9 +20275,7 @@ SELECT count(*) FROM sometable; - 所示的分组操作与分组集(参见)共同使用,以区分结果行。 - GROUPING函数的参数实际上并不求值,但它们必须与相关查询级别的GROUP BY子句中给出的表达式完全匹配。例如: - + 在中列出的分组操作与分组集配合使用(参见),以区分结果行。传给GROUPING函数的参数不会实际求值,但它们必须与相关查询层级的GROUP BY子句中的表达式完全匹配。例如: => SELECT * FROM items_sold; make | model | sales -------+-------+------- @@ -19657,9 +20296,7 @@ SELECT count(*) FROM sometable; Bar | | 1 | 20 | | 3 | 50 (7 rows) - - 在这里,前四行中的grouping0表明这些已经正常分组,在两个分组列上。 - 值1表示model没有在倒数两行中分组,值3表示无论是make还是model都没有在最后一行中分组(因此,这是所有输入行的聚合)。 +这里,前四行的grouping值为0,表明这些行按两个分组列正常分组。值1表明model未用于倒数第二、第三行的分组,值3则表明最后一行既未按make分组,也未按model分组(因此该行聚合了全部输入行)。 @@ -19683,7 +20320,7 @@ SELECT count(*) FROM sometable; - 除了这些函数之外,任何内置的或用户定义的普通聚合(例如非有序集或假想集聚合)都可以作为窗口函数使用;关于内置聚合的列表,参见。 + 除了这些函数之外,任何内置的或用户定义的普通聚合(即不属于有序集或假想集聚合)都可以作为窗口函数使用;关于内置聚合的列表,参见。 聚合函数只有在调用后带有OVER子句时才作为窗口函数;否则,它们就是普通聚合,并为整个结果集返回一行。 @@ -19714,7 +20351,7 @@ SELECT count(*) FROM sometable; bigint - 返回其分区内的当前行数,从1开始计数。 + 返回当前行在其分区内的编号,从 1 开始计数。 @@ -19727,7 +20364,7 @@ SELECT count(*) FROM sometable; bigint - 返回当前行的排名,包含间隔;即同等行组中第一行的row_number。 + 返回当前行的排名,允许空缺;即同等行组中第一行的row_number @@ -19740,7 +20377,7 @@ SELECT count(*) FROM sometable; bigint - 返回当前行的排名,不包括间隔;这个功能有效地计数同等行组。 + 返回当前行的排名,没有空缺;此函数实际上对同等行组进行计数。 @@ -19779,7 +20416,7 @@ SELECT count(*) FROM sometable; integer - 返回一个从1到参数值的整数,并将分区划分为尽可能相等的值。 + 返回从 1 到参数值的整数,将分区尽可能均等地划分。 @@ -19794,9 +20431,7 @@ SELECT count(*) FROM sometable; anycompatible - 返回分区中在当前行之前offset行的value;如果没有这样的行,则返回default(必须与value相兼容的类型)。 - offsetdefault都是针对当前行求值的。 - 如果省略,offset默认为1,defaultNULL。 + 返回在分区内当前行之前offset行处计算的value;如果没有这样的行,则返回default(其类型必须与value兼容)。offsetdefault都针对当前行求值。如果省略,offset默认为 1,default默认为NULL @@ -19811,10 +20446,7 @@ SELECT count(*) FROM sometable; anycompatible - 返回分区中在当前行之后offset行的value; - 如果没有这样的行,则返回default(必须与value兼容的类型)。 - offsetdefault都是针对当前行求值的。 - 如果省略,offset默认为1,defaultNULL。 + 返回在分区内当前行之后offset行处计算的value;如果没有这样的行,则返回default(其类型必须与value兼容)。offsetdefault都针对当前行求值。如果省略,offset默认为 1,default默认为NULL @@ -19869,14 +20501,14 @@ SELECT count(*) FROM sometable; 注意first_valuelast_valuenth_value只考虑窗口帧内的行,它默认情况下包含从分区的开始行直到当前行的最后一个同等行。 这对last_value可能不会给出有用的结果,有时对nth_value也一样。 - 你可以通过向OVER子句增加一个合适的帧声明(RANGEGROUPS)来重定义帧。 + 你可以通过向OVER子句增加一个合适的帧声明(RANGEROWSGROUPS)来重定义帧。 关于帧声明的更多信息请参考 当一个聚合函数被用作窗口函数时,它将在当前行的窗口帧内的行上聚合。 - 一个使用ORDER BY和默认窗口帧定义的聚合产生一种运行时求和类型的行为,这可能是或者不是想要的结果。 - 为了获取在整个分区上的聚合,忽略ORDER BY或者使用ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING。 + 一个使用ORDER BY和默认窗口帧定义的聚合产生一种累计求和类型的行为,这可能是或者不是想要的结果。 + 为了获取在整个分区上的聚合,省略ORDER BY或者使用ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING。 其它窗口帧声明可以用来获得其它的效果。 @@ -19885,7 +20517,7 @@ SELECT count(*) FROM sometable; SQL 标准为leadlagfirst_valuelast_valuenth_value定义了一个RESPECT NULLSIGNORE NULLS选项。 这在PostgreSQL中没有实现:行为总是与标准的默认相同,即RESPECT NULLS。 - 同样,标准中用于nth_valueFROM FIRSTFROM LAST选项没有实现: 只有支持默认的FROM FIRST行为(你可以通过反转ORDER BY的排序达到FROM LAST的结果)。 + 同样,标准中用于nth_valueFROM FIRSTFROM LAST选项没有实现: 只支持默认的FROM FIRST行为(你可以通过反转ORDER BY的排序达到FROM LAST的结果)。 @@ -19992,11 +20624,11 @@ MERGE INTO products p - subquery + 子查询 - 本节描述PostgreSQL中可用的SQL兼容的子查询表达式。所有本节中成文的表达式都返回布尔值(真/假)结果。 + 本节描述PostgreSQL中可用的SQL兼容的子查询表达式。本节介绍的所有表达式形式都返回布尔值(真/假)结果。 @@ -20011,7 +20643,7 @@ EXISTS (subquery) - 子查询可以引用来自周围的查询的变量,这些变量在该子查询的任何一次计算中都起常量的作用。 + 子查询可以引用外层查询的变量,这些变量在该子查询的任何一次计算中都起常量的作用。 @@ -20023,7 +20655,7 @@ EXISTS (subquery) - 下面这个简单的示例类似在col2上的一次内联接,但是它为每个 tab1的行生成最多一个输出,即使存在多个匹配tab2的行也如此∶ + 下面这个简单的示例类似在col2上的一次内连接,但是它为每个 tab1的行最多生成一行输出,即使存在多个匹配tab2的行也如此: SELECT col1 FROM tab1 @@ -20040,15 +20672,15 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 右手边是一个圆括弧括起来的子查询, 它必须正好只返回一个列。左手边表达式将被计算并与子查询结果逐行进行比较。 如果找到任何等于子查询行的情况,那么IN的结果就是。 如果没有找到相等行,那么结果是(包括子查询没有返回任何行的情况)。 + 右手边是一个圆括号括起来的子查询,它必须恰好返回一列。左手边表达式会被求值,并与子查询结果逐行比较。如果找到任意相等的子查询行,那么IN的结果就是。如果没有找到相等行,那么结果就是(包括子查询不返回任何行的情况)。 - 请注意如果左手边表达式得到空值,或者没有相等的右手边值, 并且至少有一个右手边行得到空值,那么IN结构的结果将是空值,而不是假。这个行为是遵照 SQL 处理空值的一般规则的。 + 请注意,如果左侧表达式得到空值,或者右侧没有相等的值且至少有一行得到空值,则IN结构的结果将是空值,而不是假。这符合 SQL 对空值布尔组合的一般规则。 - 和EXISTS一样,假设子查询将被完成运行完全是不明智的。 + 和EXISTS一样,假定子查询一定会完整运行并不明智。 @@ -20056,7 +20688,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 这种形式的IN的左手边是一个行构造器, 如中所述。 右手边是一个圆括弧子查询,它必须返回和左手边返回的行中表达式所构成的完全一样多的列。 左手边表达式将被计算并与子查询结果逐行进行比较。如果找到任意相等的子查询行,则IN的结果为。如果没有找到相等行, 那么结果为(包括子查询不返回行的情况)。 + 这种形式的IN左手边是一个行构造器,如中所述。右手边是一个圆括号括起来的子查询,它必须返回与左手边行中表达式数量完全相同的列数。左手边表达式会被求值,并与子查询结果逐行比较。如果找到任意相等的子查询行,则IN的结果为。如果没有找到相等行,那么结果为(包括子查询不返回任何行的情况)。 @@ -20072,15 +20704,15 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 右手边是一个用圆括弧包围的子查询,它必须返回正好一个列。左手边表达式将被计算并与子查询结果逐行进行比较。 如果只找到不相等的子查询行(包括子查询不返回行的情况),那么NOT IN的结果是。 如果找到任何相等行,则结果为。 + 右手边是一个圆括号括起来的子查询,它必须恰好返回一列。左手边表达式会被求值,并与子查询结果逐行比较。如果只找到不相等的子查询行(包括子查询不返回任何行的情况),那么NOT IN的结果是。如果找到任何相等行,则结果为 - 请注意如果左手边表达式得到空值,或者没有相等的右手边值, 并且至少有一个右手边行得到空值,那么NOT IN结构的结果将是空值,而不是真。这个行为是遵照 SQL 处理空值的一般规则的。 + 请注意,如果左侧表达式得到空值,或者右侧没有相等的值且至少有一行得到空值,则NOT IN结构的结果将是空值,而不是真。这符合 SQL 对空值布尔组合的一般规则。 - 和EXISTS一样,假设子查询将被完成运行完全是不明智的。 + 和EXISTS一样,假定子查询一定会完整运行并不明智。 @@ -20088,7 +20720,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 这种形式的NOT IN的左手边是一个行构造器, 如中所述。 右手边是一个圆括弧子查询,它必须返回和左手边返回的行中表达式所构成的完全一样多的列。 左手边表达式将被计算并与子查询结果逐行进行比较。如果找到不等于子查询行的行,则NOT IN的结果为。如果找到相等行, 那么结果为(包括子查询不返回行的情况)。 + 这种形式的NOT IN左侧是一个行构造器,如中所述。右侧是一个用圆括号括起来的子查询,必须返回与左侧行中表达式数量完全相同的列数。对左侧表达式求值后,将其按行与子查询结果的每一行比较。如果只找到不相等的子查询行(包括子查询不返回任何行的情况),则NOT IN的结果为。如果找到任何相等行,则结果为 @@ -20106,7 +20738,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 这种形式的右侧是一个用括号括起来的子查询,它必须恰好返回一列。左侧表达式会被求值,并使用给定的 operator 与子查询结果的每一行进行比较。如果得到任何真值结果,那么ANY的结果就是。如果没有找到真值结果,那么结果是(包括子查询没有返回任何行的情况)。 + 这种形式的右侧是一个用括号括起来的子查询,它必须恰好返回一列。左侧表达式会被求值,并使用给定的 operator 与子查询结果的每一行进行比较。该操作符必须产生布尔结果。如果得到任何真值结果,那么ANY的结果就是。如果没有找到真值结果,那么结果是(包括子查询没有返回任何行的情况)。 @@ -20114,11 +20746,11 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 请注意如果没有任何成功并且至少有一个右手边行为该操作符结果生成空值, 那么ANY结构的结果将是空值,而不是假。 这个行为是遵照 SQL 处理空值布尔组合的一般规则制定的。 + 请注意,如果没有任何比较返回真,并且至少有一个右侧行的操作符结果为空值,则ANY结构的结果将是空值,而不是假。这符合 SQL 对空值布尔组合的一般规则。 - 和EXISTS一样,假设子查询将被完成运行完全是不明智的。 + 和EXISTS一样,假定子查询一定会完整运行并不明智。 @@ -20127,7 +20759,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 这种形式的左侧是一个行构造器,如所述。右侧是一个用括号括起来的子查询,它必须返回与左侧行中表达式数量完全相同的列数。左侧表达式会被求值,并使用给定的operator与子查询结果的每一行逐行比较。如果比较对任何子查询行返回真,则ANY的结果为。如果比较对每一个子查询行都返回假,则结果为(包括子查询不返回行的情况)。如果比较对任何行都不返回真,并且至少有一次比较返回 NULL,则结果为 NULL。 + 这种形式的ANY左侧是一个行构造器,如所述。右侧是一个用括号括起来的子查询,它必须返回与左侧行中表达式数量完全相同的列数。左侧表达式会被求值,并使用给定的operator与子查询结果的每一行逐行比较。如果比较对任何子查询行返回真,则ANY的结果为。如果比较对每一个子查询行都返回假,则结果为(包括子查询不返回行的情况)。如果比较对任何行都不返回真,并且至少有一次比较返回 NULL,则结果为 NULL。 @@ -20143,7 +20775,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 这种形式的 ALL 右侧是一个用括号括起来的子查询,它必须只返回一列。左侧表达式会被求值,并使用给定的 operator 与子查询结果的每一行进行比较。该操作符必须产生布尔结果。如果所有行都得到真(包括子查询没有返回任何行的情况),ALL 的结果就是。如果发现任何假值结果,结果就是。如果比较对任何行都不返回假,并且至少有一次比较返回 NULL,则结果为 NULL。 + 右侧是一个用圆括号括起来的子查询,必须恰好返回一列。左侧表达式会被求值,并使用给定的operator与子查询结果的每一行进行比较。该操作符必须产生布尔结果。如果所有行都得到真(包括子查询不返回任何行的情况),则ALL的结果为。如果得到任何假值结果,则结果为。如果与任何子查询行的比较都不返回假,并且至少有一次比较返回 NULL,则结果为 NULL。 @@ -20151,7 +20783,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 和EXISTS一样,假设子查询将被完成运行完全是不明智的。 + 和EXISTS一样,假定子查询一定会完整运行并不明智。 @@ -20181,7 +20813,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 左手边是一个行构造器,如所述。 右手边是一个圆括弧括起来的子查询,该查询必须返回和左手边行中表达式数目完全一样的列。 另外,该子查询不能返回超过一行的数量(如果它返回零行,那么结果就是空值)。 左手边被计算并逐行与右手边的子查询结果行比较。 + 左侧是一个行构造器,如所述。右侧是一个用圆括号括起来的子查询,必须返回与左侧行中表达式数量完全相同的列数。此外,该子查询不能返回超过一行;如果它返回零行,则结果为空值。对左侧求值后,将所得的行与子查询返回的唯一一行进行比较。 @@ -20220,12 +20852,12 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 逐行比较 + 行比较 比较 - 逐行 + 复合类型 @@ -20242,7 +20874,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 本节描述几个特殊的结构,用于在值的组之间进行多重比较。这些形式语法上和前面一节的子查询形式相关,但是不涉及子查询。 这种形式涉及的数组子表达式是PostgreSQL的扩展; 其它的是SQL兼容的。所有本节记录的表达式形式都返回布尔(Boolean)结果(真/假)。 + 本节描述几个特殊的结构,用于在值的组之间进行多重比较。这些形式语法上和前面一节的子查询形式相关,但是不涉及子查询。 涉及数组子表达式的形式是PostgreSQL的扩展; 其余形式是SQL兼容的。本节介绍的所有表达式形式都返回布尔(Boolean)结果(真/假)。 @@ -20253,14 +20885,12 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 右侧是一个用括号括起来的表达式列表。如果左侧表达式的结果等于右侧任何一个表达式的结果,则结果为true。 - 这是一个简写表示法,如下所示: - + 右侧是一个用圆括号括起来的表达式列表。如果左侧表达式的结果等于右侧任一表达式的结果,则结果为。这等价于以下写法: expression = value1 -或 +OR expression = value2 -或 +OR ... @@ -20278,9 +20908,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 右侧是一个用括号括起来的表达式列表。如果左侧表达式的结果与所有右侧表达式都不相等,则结果为true。 - 这是一个简写表示法,用于 - + 右侧是一个用圆括号括起来的表达式列表。如果左侧表达式的结果与右侧所有表达式的结果都不相等,则结果为。这等价于以下写法: expression <> value1 AND @@ -20304,7 +20932,7 @@ AND - <literal>ANY</literal>/<literal>SOME</literal> (array) + <literal>ANY</literal>/<literal>SOME</literal>(数组) expression operator ANY (array expression) @@ -20326,7 +20954,7 @@ AND - <literal>ALL</literal> (array) + <literal>ALL</literal>(数组) expression operator ALL (array expression) @@ -20350,20 +20978,7 @@ AND - 每一边都是一个行构造器, - 如在中描述的那样。 - 这两个行构造器必须具有相同数量的字段。 - 给定的operator应用于每一对 - 对应的字段。(由于字段可能是不同类型的,这意味着每对可能选择不同的具体操作符。) - 所有选定的操作符必须是某个B-树操作符类的成员,或者是B-树操作符类的=成员的否定形式, - 这意味着只有当operator是 - =、 - <>、 - <、 - <=、 - >或 - >=时才可能进行行构造器比较, - 或者具有类似于这些操作符的语义。 + 两侧都是行构造器,如所述。两个行构造器必须具有相同数量的字段。给定的operator应用于每一对对应字段。(由于字段可能具有不同的类型,因此可能为各对字段选择不同的具体操作符。)所选操作符必须是某个 B-树操作符类的成员,或者是 B-树操作符类中=成员的否定操作符。这意味着只有当operator=<><<=>>=,或具有与这些操作符类似的语义时,才可以进行行构造器比较。 @@ -20374,12 +20989,7 @@ AND 对于<<=>>=这几种情况,会从左到右比较各行元素,一旦找到一对不相等或含有 NULL 的元素就立即停止。如果这对元素中的任意一个为 NULL,那么行比较的结果就是未知(NULL);否则,这对元素的比较结果决定整个行比较的结果。例如,ROW(1,2,NULL) < ROW(1,3,0)的结果为真,而不是 NULL,因为第三对元素并不会被考虑。 - - - 在PostgreSQL 8.2 之前,<<=>>=这几种情况并不是按照 SQL 规范处理的。像ROW(a,b) < ROW(c,d)这样的比较会被实现为a < c AND b < d,而正确行为应当等价于a < c OR (a = c AND b < d)。 - - row_constructor IS DISTINCT FROM row_constructor @@ -20408,21 +21018,21 @@ AND - SQL 规范要求在结果依赖于比较两个 NULL 值或者一个 NULL 与一个非 NULL 时逐行比较返回 NULL。 + SQL 规范要求在结果依赖于比较两个 NULL 值或者一个 NULL 与一个非 NULL 时行比较返回 NULL。 PostgreSQL只有在比较两个行构造器(如)的结果或者比较一个行构造器与一个子查询的输出时才这样做(如中所述)。 - 在其他比较两个复合类型值的环境中,两个 NULL 域值被认为相等,并且一个 NULL 被认为大于一个非 NULL。 + 在其他比较两个复合类型值的环境中,两个 NULL 字段值被认为相等,并且一个 NULL 被认为大于一个非 NULL。 为了得到复合类型的一致的排序和索引行为,这样做是必要的。 - 每一边都会被计算并且它们会被逐行比较。当operator是 + 对两侧分别求值后,按行进行比较。当operator=<><<=>或者 - >=时或者具有与这些类似的语义时,允许复合类型的比较(更准确地说,如果一个操作符是一个 B-树操作符类的成员,或者是一个 B-树操作符类的=成员的否定词,它就可以是一个行比较操作符)。 - 上述操作符的行为与用于行构造器(见)的IS [ NOT ] DISTINCT FROM相同。 + >=时或者具有与这些类似的语义时,允许复合类型的比较(更准确地说,如果一个操作符是一个 B-树操作符类的成员,或者是一个 B-树操作符类的=成员的否定操作符,它就可以是一个行比较操作符)。 + 上述操作符的默认行为与用于行构造器(见)的IS [ NOT ] DISTINCT FROM相同。 @@ -20433,9 +21043,9 @@ AND *<=*>以及 *>=。 - 这些操作符比较两行的内部二进制表达。即使两行用相等操作符的比较为真,两行也可能具有不同的二进制表达。 - 行在这些比较操作符之下的排序是决定性的,其他倒没什么意义。 - 这些操作符在内部被用于物化视图并且可能对其他如复制和B-树复制(参见 )之类的特殊功能有用,但是它们并不打算用在书写查询这类普通用途中。 + 这些操作符比较两行的内部二进制表示。即使两行用相等操作符的比较为真,两行也可能具有不同的二进制表示。 + 使用这些比较操作符得到的行排序是确定的,但除此之外没有其他意义。 + 这些操作符在内部被用于物化视图并且可能对其他如复制和 B-树去重(参见 )之类的特殊功能有用,但是它们并不打算用在书写查询这类普通用途中。 @@ -20450,13 +21060,13 @@ AND - 本节描述那些可能返回多于一行的函数。目前这个类中被使用最广泛的是级数生成函数, 如所述。其他更特殊的集合返回函数在本手册的其他地方描述。 - 组合多集合返回函数的方法可见。 + 本节描述那些可能返回多于一行的函数。目前这个类中被使用最广泛的是序列生成函数, 如所述。其他更特殊的集合返回函数在本手册的其他地方描述。 + 组合多个集合返回函数的方法可见 - 级数生成函数 + 序列生成函数 @@ -20512,9 +21122,7 @@ AND
- 当step为正时,如果start大于stop则返回零行。 - 相反,当step为负时,如果start小于stop则返回零行。 - 如果任何输入为NULL也会返回零行。step为零是一个错误。下面是一些示例: + 当step为正数时,如果start大于stop,则返回零行。反之,当step为负数时,如果start小于stop,则返回零行。如果任一输入为NULL,也返回零行。如果step为零,则会报错。下面是一些示例: SELECT * FROM generate_series(2,4); generate_series @@ -20545,7 +21153,7 @@ SELECT generate_series(1.1, 4, 1.3); 3.7 (3 rows) --- this example relies on the date-plus-integer operator: +-- 此示例使用日期加整数的操作符: SELECT current_date + s.a AS dates FROM generate_series(0,14,7) AS s(a); dates ------------ @@ -20569,7 +21177,7 @@ SELECT * FROM generate_series('2008-03-01 00:00'::timestamp, 2008-03-04 08:00:00 (9 rows) --- 此示例假定 TimeZone 设置为 UTC;注意 DST 转换: +-- 此示例假定 TimeZone 设为 UTC;请注意夏令时(DST)切换: SELECT * FROM generate_series('2001-10-22 00:00 -04:00'::timestamptz, '2001-11-01 00:00 -05:00'::timestamptz, '1 day'::interval, 'America/New_York'); @@ -20617,7 +21225,7 @@ SELECT * FROM generate_series('2001-10-22 00:00 -04:00'::timestamptz, setof integer - 生成一个包含给定数组第dim维度的有效下标的序列。 + 生成一个包含给定数组第dim维的有效下标的序列。 @@ -20627,7 +21235,7 @@ SELECT * FROM generate_series('2001-10-22 00:00 -04:00'::timestamptz, setof integer
- 生成一个包含给定数组第dim维度的有效下标的序列。当reverse为真时,以相反的顺序返回序列。 + 生成一个包含给定数组第dim维的有效下标的序列。当reverse为真时,以相反的顺序返回序列。 @@ -20636,9 +21244,9 @@ SELECT * FROM generate_series('2001-10-22 00:00 -04:00'::timestamptz, generate_subscripts是一个快捷函数,它为给定数组的指定维度生成一组合法的下标。 - 对于不具有请求维度的数组返回零行,对于任何输入为NULL数组也返回零行。下面是一些示例: + 如果数组不具有所请求的维度,或者任一输入为NULL,则返回零行。下面是一些示例: --- basic usage: +-- 基本用法: SELECT generate_subscripts('{NULL,1,NULL,2}'::int[], 1) AS s; s --- @@ -20648,8 +21256,8 @@ SELECT generate_subscripts('{NULL,1,NULL,2}'::int[], 1) AS s; 4 (4 rows) --- presenting an array, the subscript and the subscripted --- value requires a subquery: +-- 展示数组、下标和下标对应的值 +-- 需要使用子查询: SELECT * FROM arrays; a -------------------- @@ -20668,7 +21276,7 @@ FROM (SELECT generate_subscripts(a, 1) AS s, a FROM arrays) foo; {100,200,300} | 3 | 300 (5 rows) --- unnest a 2D array: +-- 展开二维数组: CREATE OR REPLACE FUNCTION unnest2(anyarray) RETURNS SETOF anyelement AS $$ select $1[i][j] @@ -20688,15 +21296,13 @@ SELECT * FROM unnest2(ARRAY[[1,2],[3,4]]); - ordinality + 序号 - 当FROM子句中的函数以WITH ORDINALITY作为后缀时,将在函数的输出列上附加一个bigint列,该列从1开始,函数输出的每一行加1。 - 这在 unnest()等集合返回函数的情况下最有用。 - + 当FROM子句中的函数后面加上WITH ORDINALITY时,一个bigint列会追加到函数的输出列中,其值从 1 开始,对函数输出的每一行递增 1。这种方式对集合返回函数尤其有用,例如unnest() --- set returning function WITH ORDINALITY: +-- 集合返回函数与 WITH ORDINALITY: SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); ls | n -----------------+---- @@ -20729,11 +21335,15 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); 系统信息函数和操作符 + + 本节描述的函数用于获取有关PostgreSQL安装的各种信息。 + + 会话信息函数 - 展示了多个可以抽取会话和系统信息的函数。 + 列出了多个用于提取会话和系统信息的函数。 @@ -20774,7 +21384,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); name - 返回当前数据库的名称。(在SQL标准中数据库被称为catalogs,因此current_catalog是该标准的拼写方式。) + 返回当前数据库的名称。(SQL 标准将数据库称为目录(catalogs),因此current_catalog是标准中的写法。) @@ -20787,7 +21397,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); text - 返回当前所执行查询的文本,由客户端提交的(可能包含一个以上的语句)。 + 返回客户端提交的当前正在执行的查询文本(可能包含多条语句)。 @@ -20810,8 +21420,8 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); current_schema - schema - current + 模式 + 当前 current_schema name @@ -20832,16 +21442,14 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); current_schemas - search path - current + 搜索路径 + 当前 current_schemas ( include_implicit boolean ) name[]
- 返回当前在有效搜索路径中的所有模式的名称的数组,以优先级顺序。 - (当前 设置中与已存在的、可搜索模式不相符的项将被省略。) - 如果布尔参数为true,则类似pg_catalog的隐式搜索的系统模式将包含在结果中。 + 返回当前有效搜索路径中所有模式名称的数组,按优先级排序。(当前设置中不对应于已存在且可搜索的模式的项会被省略。)如果布尔参数为true,结果还会包含pg_catalog等隐式搜索的系统模式。 @@ -20851,8 +21459,8 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); current_user - user - current + 用户 + 当前 current_user name @@ -20871,7 +21479,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); inet
- 返回当前客户端的IP地址,如果当前连接是通过Unix-域套接字则返回NULL + 返回当前客户端的 IP 地址;如果当前连接通过 Unix 域套接字建立,则返回NULL @@ -20884,7 +21492,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); integer
- 返回当前客户端的IP端口号,如果当前连接是通过Unix-域套接字则返回NULL。 + 返回当前客户端的IP端口号,如果当前连接是通过Unix 域套接字则返回NULL @@ -20897,7 +21505,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); inet
- 返回服务器接受当前连接的IP地址,如果当前连接是通过Unix-域套接字则返回NULL。 + 返回服务器接受当前连接的IP地址,如果当前连接是通过Unix 域套接字则返回NULL @@ -20910,7 +21518,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); integer
- 返回服务器接受当前连接的IP端口号,如果当前连接是通过Unix-域套接字则返回NULL。 + 返回服务器接受当前连接的IP端口号,如果当前连接是通过Unix 域套接字则返回NULL @@ -20936,12 +21544,10 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); integer[] - 返回阻止服务器进程的会话的进程ID数组,该进程ID与指定的进程ID一起获取锁定,如果没有这样的服务器进程或者没有被阻塞,则返回一个空数组。 + 返回一个数组,包含阻止指定进程 ID 对应的服务器进程获取锁的会话进程 ID;如果不存在这样的服务器进程,或该进程未被阻塞,则返回空数组。 - 如果一个服务器进程持有一个与被阻塞进程的锁请求冲突的锁(硬阻塞),或者正在等待一个与被阻塞进程的锁请求冲突并且在等待队列中位于其前面的锁(软阻塞),那么这个服务器进程就会阻塞另一个服务器进程。 - 当使用并行查询时结果总是列出客户端可见的进程ID(即pg_backend_pid的结果),即使实际的锁是由子工作进程持有或等待的。 - 因此,结果中可能存在重复的pid。还要注意当准备好的事务持有冲突锁时,它将用零进程ID表示。 + 一个服务器进程会在以下情况下阻塞另一个进程:它持有与被阻塞进程请求的锁冲突的锁(硬阻塞);或者它正在等待一个会与被阻塞进程请求的锁冲突的锁,并且在等待队列中位于被阻塞进程之前(软阻塞)。使用并行查询时,即使实际持锁或等待锁的是子工作进程,结果也始终列出客户端可见的进程 ID(即pg_backend_pid的结果)。因此,结果中可能出现重复的 PID。另外,如果持有冲突锁的是一个预备事务,结果中会用进程 ID 0 表示它。 频繁调用这个函数可能会对数据库性能产生一些影响,因为它需要在短时间内独占访问锁管理器的共享状态。 @@ -20957,8 +21563,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); timestamp with time zone - 返回服务器配置文件最后加载的时间。如果当前会话当时是活跃的,那么这将是会话本身重新读取配置文件的时间(因此在不同的会话中读取会稍有不同)。 - 否则,就是postmaster进程重新读取配置文件的时间。 + 返回服务器配置文件最近一次加载的时间。如果当时当前会话已经存在,则返回该会话自身重新读取配置文件的时间(因此不同会话中的返回时间会略有不同)。否则,返回 postmaster 进程重新读取配置文件的时间。 @@ -20968,16 +21573,16 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); pg_current_logfile - Logging - pg_current_logfile函数 + 日志记录 + pg_current_logfile 函数 current_logfiles - 和pg_current_logfile函数 + 和pg_current_logfile 函数 - Logging - current_logfiles文件和pg_current_logfile函数 + 日志记录 + current_logfiles 文件和pg_current_logfile 函数 pg_current_logfile ( [ text ] ) text @@ -20993,7 +21598,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); 结果反映current_logfiles文件的内容。 - 默认情况下,此函数仅限于超级用户以及具有pg_monitor角色权限的角色,但可以向其他用户授予 EXECUTE 权限以运行该函数。 + 默认情况下,此函数仅限超级用户和具有pg_monitor角色权限的角色使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -21056,7 +21661,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); double precision - 返回当前被等待处理的通知所占用的异步通知队列最大尺寸的分数(0–1)。更多信息请参见。 + 返回待处理通知当前占用的空间占异步通知队列最大容量的比例(0–1)。更多信息请参见 @@ -21082,11 +21687,11 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); integer[] - 返回一个进程ID数组,该进程ID是阻塞服务器进程获取安全快照的会话的进程ID数组,如果没有这样的服务器进程或者没有阻塞,则返回一个空数组。 + 返回一个数组,包含阻止指定进程 ID 对应的服务器进程获取安全快照的会话进程 ID;如果不存在这样的服务器进程,或该进程未被阻塞,则返回空数组。 运行SERIALIZABLE事务的会话会阻止SERIALIZABLE READ ONLY DEFERRABLE事务获取快照,直到后者确定可以安全地避免获取谓词锁。 - 关于可串行化和可延迟事务的更多信息,请参见。 + 关于可序列化和可延迟事务的更多信息,请参见 频繁调用这个函数可能会对数据库性能产生一些影响,因为它需要在短时间内访问谓词锁管理器的共享状态。 @@ -21102,7 +21707,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); integer - 返回当前嵌套层次的PostgreSQL触发器(如果没有调用则为 0,直接或间接,从一个触发器内部开始)。 + 返回PostgreSQL触发器的当前嵌套层级(如果不是从触发器内部直接或间接调用,则为 0)。 @@ -21115,7 +21720,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); name - 返回会话用户名. + 返回会话用户名。 @@ -21145,20 +21750,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); - - - - version - - version () - text - - - 返回描述PostgreSQL服务器的版本的字符串。 - 你还可以从 中获得此信息,或者对于机器可读的版本,使用。 - 软件开发人员可以使用server_version_num(从8.2起可用)或,而不是解析文本版本。 - - + @@ -21166,17 +21758,12 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); - current_catalogcurrent_rolecurrent_schemacurrent_usersession_useruserSQL里有特殊的语法地位: 它们被调用时结尾不要跟着圆括号。 - 在 PostgreSQL 中,圆括号可以有选择性地被用于current_schema,但是不能和其他的一起用。 + current_catalogcurrent_rolecurrent_schemacurrent_usersession_useruserSQL中具有特殊语法:调用时不得在后面加圆括号。在 PostgreSQL 中,current_schema可以选择加圆括号,其他函数则不可以。 - session_user通常是发起当前数据库连接的用户,不过超级用户可以用修改这个设置。 - current_user是用于权限检查的用户标识。通常, 它总是等于会话用户,但是可以被改变。 - 它也会在函数执行的过程中随着属性SECURITY DEFINER的改变而改变。 - 在 Unix 的说法里,那么会话用户是真实用户,而当前用户是有效用户。 - current_role以及usercurrent_user的同义词(SQL标准在current_rolecurrent_user之间做了区分,但PostgreSQL不区分,因为它把用户和角色统一成了一种实体)。 + session_user通常是发起当前数据库连接的用户,但超级用户可以用修改此设置。current_user是用于权限检查的用户标识,通常等于会话用户,但可以用更改。在执行具有SECURITY DEFINER属性的函数期间,它也会改变。用 Unix 的术语来说,会话用户是真实用户,当前用户是有效用户current_roleusercurrent_user的同义词。(SQL 标准区分current_rolecurrent_user,但PostgreSQL不区分,因为它将用户和角色统一为同一种实体。)
@@ -21186,18 +21773,12 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); 访问权限查询函数 - privilege - querying + 权限 + 查询 - 列出那些允许编程查询对象访问权限的函数。参阅获取更多有关权限的信息。 - 在这些函数中,可以通过名称或OID (pg_authid.oid)指定被查询权限的用户,或者如果名称被指定为public,则检查PUBLIC伪角色的权限。 - 同样,user参数可以完全省略,在这种情况下,假设为current_user。被查询的对象也可以通过名称或OID来指定。 - 通过名称指定时,可以包含相关的模式名称。感兴趣的访问权限由一个文本字符串指定,它必须计算为对象类型的一个适当的权限关键字(例如,SELECT)。 - 还可以将 WITH GRANT OPTION添加到权限类型中,以测试该权限是否由授予选项持有。 - 同样,可以用逗号分隔列出多个权限类型,在这种情况下,如果所列出的权限中有任何一个被持有,结果将为真。 - (权限字符串的大小写不重要,权限名之间允许有额外的空格,但在权限名中不允许。)一些示例: + 列出了允许以编程方式查询对象访问权限的函数。(关于权限的更多信息,请参见。)在这些函数中,可以通过名称或 OID(pg_authid.oid)指定要查询权限的用户;如果名称为public,则检查 PUBLIC 伪角色的权限。也可以完全省略user参数,此时使用current_user。要查询的对象也可以通过名称或 OID 指定。通过名称指定时,如适用,可以包含模式名。所需访问权限由文本字符串指定,其值必须为适用于该对象类型的权限关键字之一(例如SELECT)。还可以在权限类型后附加WITH GRANT OPTION,以检查是否拥有该权限及其授予选项。也可以用逗号分隔列出多个权限类型;只要拥有列出的任一权限,结果就为真。(权限字符串不区分大小写,权限名之间允许有额外的空白,但权限名内部不允许。)例如: SELECT has_table_privilege('myschema.mytable', 'select'); SELECT has_table_privilege('joe', 'mytable', 'INSERT, SELECT WITH GRANT OPTION'); @@ -21234,9 +21815,7 @@ SELECT has_table_privilege('joe', 'mytable', 'INSERT, SELECT WITH GRANT OPTION') boolean - 用户是否对表的任何列有权限? - 如果对整个表持有权限,或者对至少一个列有列级的权限授予,则会成功。 - 允许的权限类型为SELECT, INSERT,UPDATE, 和 REFERENCES + 用户是否对表的至少一列具有权限?如果拥有整个表的权限,或至少一列获得了该权限的列级授权,则返回真。允许的权限类型为SELECTINSERTUPDATEREFERENCES @@ -21287,7 +21866,7 @@ SELECT has_table_privilege('joe', 'mytable', 'INSERT, SELECT WITH GRANT OPTION') boolean - 用户是否拥有外部数据包装的权限?唯一允许的权限类型是USAGE。 + 用户是否具有外部数据包装器权限?唯一允许的权限类型为USAGE @@ -21374,7 +21953,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); boolean - 用户是否有顺序权限?允许的权限类型有USAGE, SELECT, 和UPDATE。 + 用户是否具有序列权限?允许的权限类型为USAGESELECTUPDATE @@ -21455,11 +22034,11 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); boolean - 用户对角色有权限吗?允许的权限类型有MEMBERUSAGESET。 + 用户是否具有角色权限?允许的权限类型为MEMBERUSAGESETMEMBER表示对该角色的直接或间接成员资格,而不考虑由此授予的具体权限。 USAGE表示该角色的权限是否无需执行SET ROLE即可立即使用,而SET表示是否可以使用SET ROLE命令切换到该角色。 任一权限类型后面都可以附加WITH ADMIN OPTIONWITH GRANT OPTION,用于测试是否持有 ADMIN 权限(这六种写法测试的都是同一件事)。 - 此函数不允许特殊情况下将user设置为public,因为PUBLIC伪角色永远不能成为真实角色的成员。 + 此函数不允许将user设置为public这一特殊情况,因为 PUBLIC 伪角色永远不能成为实际角色的成员。 @@ -21473,7 +22052,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); boolean - 在当前用户和当前环境的上下文之中,指定表的行级安全是活动的吗? + 在当前用户和当前环境的上下文中,指定表的行级安全性是否生效? @@ -21481,8 +22060,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); - 显示了aclitem类型的可用操作符,它是访问权限的目录表示。 - 有关如何读取访问权限值的信息,请参阅 。 + 列出了aclitem类型可用的操作符;该类型是访问权限在系统目录中的表示形式。有关如何解读访问权限值的信息,请参见 @@ -21515,8 +22093,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); boolean - aclitem相等吗?(注意,aclitem类型缺少比较操作符的通常集合;它只有相等。 - 反而言之,aclitem数组只能进行相等比较。) + 两个aclitem是否相等?(注意,aclitem类型没有通常的整套比较操作符,而只支持相等比较。因此,aclitem数组也只能进行相等比较。) 'calvin=r*w/hobbes'::aclitem = 'calvin=r*w*/hobbes'::aclitem @@ -21533,7 +22110,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); boolean - 数组是否包含指定的权限?(如果有一个数组条目与aclitem的被授权人和授予人相匹配,并且至少具有权限的指定集,则此选项为真。) + 数组是否包含指定的权限?(如果数组中存在一个条目,其被授权者和授权者与该aclitem相同,且至少包含指定的全部权限,则返回真。) '{calvin=r*w/hobbes,hobbes=r*w*/postgres}'::aclitem[] @> 'calvin=r*/hobbes'::aclitem @@ -21545,7 +22122,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute');
- 显示了一些额外的函数来管理aclitem类型。 + 列出了一些用于管理aclitem类型的其他函数。 @@ -21577,23 +22154,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); aclitem[] - 构造一个aclitem数组,保存属于具有OID ownerId的角色的对象类型type的默认访问权限。 - 这表示当对象的ACL条目为空时将假定的访问权限。(默认访问权限在中描述。) - type参数必须是以下之一: - 'c'表示COLUMN, - 'r'表示TABLE和类似表的对象, - 's'表示SEQUENCE, - 'd'表示DATABASE, - 'f'表示FUNCTIONPROCEDURE, - 'l'表示LANGUAGE, - 'L'表示LARGE OBJECT, - 'n'表示SCHEMA, - 'p'表示PARAMETER, - 't'表示TABLESPACE, - 'F'表示FOREIGN DATA WRAPPER, - 'S'表示FOREIGN SERVER, - 或 - 'T'表示TYPEDOMAIN。 + 构造一个aclitem数组,保存类型为type、属于 OID 为ownerId的角色的对象的默认访问权限。当对象的ACL条目为空值时,会采用这些访问权限。(默认访问权限见。)type参数必须为以下值之一:'c' 表示COLUMN,'r' 表示TABLE和类似表的对象,'s' 表示SEQUENCE,'d' 表示DATABASE,'f' 表示FUNCTIONPROCEDURE,'l' 表示LANGUAGE,'L' 表示LARGE OBJECT,'n' 表示SCHEMA,'p' 表示PARAMETER,'t' 表示TABLESPACE,'F' 表示FOREIGN DATA WRAPPER,'S' 表示FOREIGN SERVER,'T' 表示TYPEDOMAIN @@ -21610,9 +22171,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); is_grantableboolean ) - 以行集的形式返回aclitem数组。如果受让人是伪角色PUBLIC,则在grantee列中用0表示。 - 每个被授予的权限都表示为SELECT, INSERT等。 - 注意,每个权限被分割成单独的一行,因此在privilege_type列中只出现一个关键字。 + 以行集的形式返回aclitem数组。如果被授权者是伪角色 PUBLIC,则在grantee列中用零表示。每项授予的权限表示为SELECTINSERT等(完整列表见)。注意,每项权限都会拆成单独的一行,因此privilege_type列中只会出现一个关键字。 @@ -21629,7 +22188,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); aclitem - 使用给定的属性构造 aclitem 。 + 使用给定的属性构造aclitemprivileges是以逗号分隔的权限名列表,例如SELECTINSERT等,列出的所有权限都会设置在结果中。(权限字符串不区分大小写,权限名之间允许有额外的空白,但权限名内部不允许。) @@ -21643,14 +22202,9 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); 模式可见性查询函数 - 展示了决定是否一个特定对象在当前模式搜索路径中可见的函数。 - 例如,如果一个表所在的模式在当前搜索路径中并且在它之前没有出现过相同的名字,这个表就被说是可见的。 - 这等价于在语句中表可以被用名称引用但不加显式的模式限定。因此,要列出所有可见表的名字: - + 列出了判断某个特定对象是否可见的函数,其判断依据是当前模式搜索路径。例如,如果表所在的模式位于搜索路径中,并且在搜索路径的更前面没有同名表,就称该表可见。这等价于说,可以只通过表名引用该表,而不必显式地用模式限定。因此,要列出所有可见表的名称: SELECT relname FROM pg_class WHERE pg_table_is_visible(oid); - - 对于函数和操作符,如果路径前面没有相同名称和参数数据类型的对象,那么搜索路径中的对象就是可见的。 - 对于操作符类和操作符族,要考虑名称和关联的索引访问方法。 +对于函数和操作符,只要搜索路径中更靠前的位置没有对象具有与被检查对象相同的名称和参数数据类型,就称被检查对象可见。对于操作符类和操作符族,会同时考虑名称及关联的索引访问方法。 @@ -21789,7 +22343,7 @@ SELECT relname FROM pg_class WHERE pg_table_is_visible(oid); boolean - 文本搜索配置在搜索路径可见吗? + 全文检索配置是否在搜索路径中可见? @@ -21802,7 +22356,7 @@ SELECT relname FROM pg_class WHERE pg_table_is_visible(oid); boolean - 文本搜索字典在搜索路径可见吗? + 全文检索词典是否在搜索路径中可见? @@ -21815,7 +22369,7 @@ SELECT relname FROM pg_class WHERE pg_table_is_visible(oid); boolean - 文本搜索解析器在搜索路径中可见吗? + 全文检索解析器是否在搜索路径中可见? @@ -21828,7 +22382,7 @@ SELECT relname FROM pg_class WHERE pg_table_is_visible(oid); boolean - 文本搜索模板在搜索路径可见吗? + 全文检索模板是否在搜索路径中可见? @@ -21849,11 +22403,10 @@ SELECT relname FROM pg_class WHERE pg_table_is_visible(oid);
- 所有这些函数都要求用对象 OID 来标识将被检查的对象。如果你想用名称来测试一个对象,使用 OID 别名类型(regclassregtyperegprocedureregoperatorregconfigregdictionary)将会很方便。例如: - + 所有这些函数都需要用对象 OID 标识要检查的对象。如果想按名称测试对象,使用 OID 别名类型会很方便(regclassregtype, + regprocedureregoperatorregconfig,或regdictionary),例如: SELECT pg_type_is_visible('myschema.widget'::regtype); - - 注意以这种方式测试一个非模式限定的类型名没什么意义 — 如果该名称完全能被识别,它必须是可见的。 +注意,用这种方式测试不带模式限定的类型名并没有太大意义:只要该名称能够被识别,它就必然可见。 @@ -21885,7 +22438,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); - + format_type @@ -21897,6 +22450,26 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); + + + + pg_basetype + + pg_basetype ( regtype ) + regtype + + + 返回由类型 OID 标识的域的基础类型 OID。如果参数是非域类型的 OID,则原样返回该参数。如果参数不是有效的类型 OID,则返回 NULL。如果存在域依赖链,则递归查找,直到找到基础类型。 + + + 假设执行了CREATE DOMAIN mytext AS text: + + + pg_basetype('mytext'::regtype) + text + + + @@ -21943,7 +22516,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); 返回一组记录,描述存在于PostgreSQL系统目录中的外键关系。 fktable 列包含引用目录的名称,fkcols列包含引用列的名称。 类似地,pktable列包含被引用目录的名称,而pkcols列包含被引用列的名称。 - 如果is_array为真,则最后一个引用列是一个数组,其每个元素都应该与引用目录中的某个条目匹配。 + 如果is_array为真,则最后一个引用列是一个数组,其每个元素都应该与被引用目录中的某个条目匹配。 如果is_opt为真,则允许引用列包含零而不是有效引用。 @@ -21953,11 +22526,11 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); pg_get_constraintdef - pg_get_constraintdef ( constraint oid [, pretty boolean ] ) + pg_get_constraintdef ( constraint oid , pretty boolean ) text - 重构为了约束的创建命令。(这是一个反编译的重构,而不是命令的原始文本。) + 重建约束的创建命令。(这是反编译重建的结果,并非命令的原始文本。) @@ -21970,8 +22543,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 反编译存储在系统目录中的表达式的内部形式,例如列的默认值。 - 如果表达式可能包含变量,则指定它们所指向的关系的OID作为第二个参数;如果没有预期的变量,传递0就可以了。 + 反编译存储在系统目录中的表达式的内部形式,例如列的默认值。如果表达式可能包含 Var 节点,请将它们所引用的关系的 OID 指定为第二个参数;如果预计不含 Var 节点,传入零即可。 @@ -21984,8 +22556,8 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 重构为了函数或过程的创建命令。(这是一个反编译的重构,而不是命令的原始文本。) - 结果是一个完整的CREATE OR REPLACE FUNCTIONCREATE OR REPLACE PROCEDURE语句。 + 重建函数或过程的创建命令。(这是反编译重建的结果,并非命令的原始文本。) + 结果是一条完整的CREATE OR REPLACE FUNCTIONCREATE OR REPLACE PROCEDURE语句。 @@ -21998,7 +22570,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 重新构造函数或过程的参数列表,以其在 CREATE FUNCTION里面需要出现的形式(包括默认值)。 + 重建函数或过程的参数列表,采用其在CREATE FUNCTION中应有的形式(包括默认值)。 @@ -22011,7 +22583,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 重新构造标识函数或过程所需的参数列表,以其应出现在ALTER FUNCTION等命令中的形式。这个表单省略默认值。 + 重建标识函数或过程所需的参数列表,采用其在ALTER FUNCTION等命令中应有的形式。这种形式省略默认值。 @@ -22024,7 +22596,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 重构函数的RETURNS子句,以其需要出现在CREATE FUNCTION中的形式。对于过程,返回NULL。 + 重建函数的RETURNS子句,采用其在CREATE FUNCTION中应有的形式。对于过程,返回NULL @@ -22033,11 +22605,11 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); pg_get_indexdef - pg_get_indexdef ( index oid [, column integer, pretty boolean ] ) + pg_get_indexdef ( index oid , column integer, pretty boolean ) text - 重构针对索引的创建命令。(这是一个反编译的重构,而不是命令的原始文本。)如果提供了column而且不为零,则只重构该列的定义。 + 重建索引的创建命令。(这是反编译重建的结果,并非命令的原始文本。)如果提供了column而且不为零,则只重建该列的定义。 @@ -22055,11 +22627,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); baredesc text ) - 返回一组描述服务器识别的SQL关键字的记录。word列包含关键字。 - catcode列包含一个类别代码:U表示无保留关键字,C表示可以是列名的关键字,T表示可以是类型或函数名的关键字,或者R表示完全保留关键字。 - 如果关键字可以在SELECT列表中用作bare列标签,则barelabel列包含true,或者false,如果它只能在AS之后使用。 - catdesc列包含可能本地化字符串,描述关键字的类别。 - baredesc列包含可能本地化的字符串,描述关键字的列标签状态。 + 返回描述服务器所识别 SQL 关键字的一组记录。word列包含关键字。catcode列包含类别代码:U表示非保留关键字,C表示可用作列名的关键字,T表示可用作类型名或函数名的关键字,R表示完全保留的关键字。如果关键字可以在SELECT列表中用作列标签,barelabel列为true;如果只能在AS之后使用,则为falsecatdesc列包含描述关键字类别的字符串,该字符串可能已被本地化。baredesc列包含描述关键字列标签状态的字符串,该字符串可能已被本地化。 @@ -22071,8 +22639,20 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 重构分区约束的定义。 - (这是反编译得到的重构结果,而不是命令的原始文本。) + 重建分区约束的定义。(这是反编译重建的结果,并非命令的原始文本。) + + + + + + + pg_get_partkeydef + + pg_get_partkeydef ( table oid ) + text + + + 重建分区表的分区键定义,采用其在CREATE TABLEPARTITION BY子句中的形式。(这是反编译重建的结果,并非命令的原始文本。) @@ -22081,11 +22661,11 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); pg_get_ruledef - pg_get_ruledef ( rule oid [, pretty boolean ] ) + pg_get_ruledef ( rule oid , pretty boolean ) text - 重构针对规则的创建命令。(这是一个反编译的重构,而不是命令的原始文本。) + 重建规则的创建命令。(这是反编译重建的结果,并非命令的原始文本。) @@ -22100,15 +22680,15 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); 返回与列相关联的序列名称,如果没有序列与该列相关联则返回NULL。 如果列是标识列,则关联序列是在内部为该列创建的序列。 - 对于使用一种串行类型(serial, smallserial, bigserial)创建的列,它是为该串行列定义创建的序列。 + 对于使用一种 serial 类型(serial, smallserial, bigserial)创建的列,它是为该 serial 列定义创建的序列。 在后一种情况下,可以使用ALTER SEQUENCE OWNED BY修改或删除关联。 - (这个函数可能应该被称为pg_get_owned_sequence;它的当前名称反映了它在历史上曾与串行类型的列一起使用。) + (这个函数可能应该被称为pg_get_owned_sequence;它的当前名称反映了它在历史上曾与 serial 类型的列一起使用。) 第一个参数是具有可选模式的表名,第二个参数是列名。 由于第一个参数可能包含模式名和表名,因此按照通常的SQL规则解析它,这意味着默认情况下它是小写的。 第二个参数只是一个列名,按照字面来处理,因此保留了它的大小写。结果经过了适当的格式化,可以传递给序列函数(参见)。 - 典型的用法是读取序列的当前值以获取标识或串行列,示例如下: + 典型用法是读取标识列或 serial 列所用序列的当前值,例如: SELECT currval(pg_get_serial_sequence('sometable', 'id')); @@ -22124,7 +22704,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); text - 重构针对扩展统计对象的创建命令。(这是一个反编译的重构,而不是命令的原始文本。) + 重建扩展统计对象的创建命令。(这是反编译重建的结果,并非命令的原始文本。) @@ -22133,11 +22713,11 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); pg_get_triggerdef -pg_get_triggerdef ( trigger oid [, pretty boolean ] ) +pg_get_triggerdef ( trigger oid , pretty boolean ) text - 重构针对触发器的创建命令。(这是一个反编译的重构,而不是命令的原始文本。) + 重建触发器的创建命令。(这是反编译重建的结果,并非命令的原始文本。) @@ -22159,11 +22739,11 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); pg_get_viewdef - pg_get_viewdef ( view oid [, pretty boolean ] ) + pg_get_viewdef ( view oid , pretty boolean ) text - 重构针对视图或物化视图的SELECT命令。(这是一个反编译的重构,而不是命令的原始文本。) + 重建定义视图或物化视图的SELECT命令。(这是反编译重建的结果,并非命令的原始文本。) @@ -22173,18 +22753,18 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); text - 重构针对视图或物化视图的底层SELECT命令。(这是一个反编译的重构,而不是命令的原始文本。) - 在这种形式的函数中,总是启用美观打印,并对长行进行换行,以尽量使它们小于指定的列数。 + 重建定义视图或物化视图的SELECT命令。(这是反编译重建的结果,并非命令的原始文本。) + 这种形式始终启用美化输出,并将长行折行,尽量使每行长度小于指定列数。 - pg_get_viewdef ( view text [, pretty boolean ] ) + pg_get_viewdef ( view text , pretty boolean ) text - 根据视图的文本名称而不是它的OID,重构针对视图或物化视图的底层SELECT命令。(这是弃用;请使用OID变体。) + 根据视图的文本名称而不是其 OID,重建定义视图或物化视图的SELECT命令。(此形式已弃用;请使用 OID 变体。) @@ -22197,7 +22777,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); boolean - 测试一个索引列是否具有命名属性。列出了常用索引列属性。 + 测试一个索引列是否具有指定名称的属性。列出了常用索引列属性。 (注意,扩展访问方法可以为其索引定义额外的属性名。) 如果属性名未知或不适用于特定对象,或者OID或列号不能识别有效的对象,则返回NULL @@ -22212,7 +22792,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); boolean - 测试一个索引是否具有命名属性。列出了常用的索引属性。 + 测试一个索引是否具有指定名称的属性。列出了常用的索引属性。 (注意,扩展访问方法可以为其索引定义额外的属性名。) 如果属性名未知或不适用于特定对象,或者OID不能识别有效的对象,则返回NULL @@ -22227,7 +22807,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); boolean - 测试索引访问方法是否具有命名属性。访问方法属性如所示。 + 测试索引访问方法是否具有指定名称的属性。访问方法属性如所示。 如果属性名未知或不适用于特定对象,或者OID不能识别有效的对象,则返回NULL @@ -22256,9 +22836,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); text[] - 返回与给定GUC相关联的标志数组,如果不存在则返回NULL。 - 如果GUC存在但没有要显示的标志,则结果为空数组。 - 仅公开列出在中最有用的标志。 + 返回与给定 GUC 关联的标志数组;如果该 GUC 不存在,则返回NULL。如果 GUC 存在但没有要显示的标志,则结果为空数组。此函数仅公开中列出的最有用的标志。 @@ -22271,9 +22849,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); setof oid - 返回具有存储在指定表空间中的对象的数据库的OIDs集。 - 如果这个函数返回了任何行,那么表空间就不是空的,且不能被删除。 - 要识别填充表空间的特定对象,需要连接到由pg_tablespace_databases标识的数据库,并查询它们的pg_class目录。 + 返回在指定表空间中存储了对象的数据库 OID 集合。如果此函数返回任何行,则说明该表空间不为空,不能删除。要查看存放在该表空间中的具体对象,需要连接到pg_tablespace_databases标识的数据库,并查询它们的pg_class系统目录。 @@ -22299,23 +22875,11 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); regtype - 返回传递值给它的数据类型的OID。这对于故障排除或动态构造SQL查询很有帮助。 - 函数声明为返回regtype,它是一个OID别名类型(see ); - 这意味着,为了比较,它与OID相同,但显示为类型名。 + 返回所传入值的数据类型的 OID。这有助于排查问题或动态构造 SQL 查询。函数声明的返回类型是regtype,它是一种 OID 别名类型(参见);这意味着它在比较时与 OID 相同,但显示为类型名。 - 例如: - -SELECT pg_typeof(33); - pg_typeof ------------ - integer - -SELECT typlen FROM pg_type WHERE oid = pg_typeof(33); - typlen --------- - 4 - + pg_typeof(33) + integer @@ -22328,22 +22892,17 @@ SELECT typlen FROM pg_type WHERE oid = pg_typeof(33); text - 返回传递值给它的排序规则的名称。如果需要,该值会被引号括起来,并使用模式限定。 - 如果没有为参数表达式派生排序规则,则返回NULL。如果参数不是可排序数据类型,则会引发错误。 + 返回传入值的排序规则名称。必要时会为返回的名称加上引号和模式限定。 + 如果无法为参数表达式推导出排序规则,则返回NULL。 + 如果参数不属于支持排序规则的数据类型,则报错。 - 例如: - -SELECT collation for (description) FROM pg_description LIMIT 1; - pg_collation_for ------------------- - "default" - -SELECT collation for ('foo' COLLATE "de_DE"); - pg_collation_for ------------------- - "de_DE" - + collation for ('foo'::text) + "default" + + + collation for ('foo' COLLATE "de_DE") + "de_DE" @@ -22357,7 +22916,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); 将文本关系名转换为它的OID。通过将字符串类型转换为regclass可以得到类似的结果(参见); - 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。 @@ -22370,8 +22929,8 @@ SELECT collation for ('foo' COLLATE "de_DE"); regcollation - 将文本排序规则名称转换为它的OID。通过将字符串类型转换为regcollation(参见)可以得到类似的结果; - 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 将文本排序规则名称转换为它的OID。通过将字符串类型转换为regcollation(参见)可以得到类似的结果; + 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。 @@ -22384,8 +22943,8 @@ SELECT collation for ('foo' COLLATE "de_DE"); regnamespace - 将文本模式名转换为它的OID。通过将字符串转换为regnamespace类型(参见)可以得到类似的结果; - 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 将文本模式名转换为它的OID。通过将字符串转换为regnamespace类型(参见)可以得到类似的结果; + 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。 @@ -22398,8 +22957,8 @@ SELECT collation for ('foo' COLLATE "de_DE"); regoper - 将文本操作符名称转换为它的OID。通过将字符串类型转换为regoper(参见)可以得到类似的结果; - 但是,如果找不到名称或名称有多义性,该函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 将文本操作符名称转换为它的OID。通过将字符串类型转换为regoper(参见)可以得到类似的结果; + 但是,如果找不到名称或名称有多义性,该函数将返回NULL而不会抛出错误。 @@ -22412,8 +22971,8 @@ SELECT collation for ('foo' COLLATE "de_DE"); regoperator - 将文本操作符名称(带有参数类型)转换为其OID。通过将字符串转换为regoperator类型(参见节)可以得到类似的结果; - 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 将文本操作符名称(带有参数类型)转换为其OID。通过将字符串转换为regoperator类型(参见节)可以得到类似的结果; + 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。 @@ -22426,8 +22985,8 @@ SELECT collation for ('foo' COLLATE "de_DE"); regproc - 将文本函数或过程名转换为其OID。通过将字符串转换为regproc类型(参见)可以得到类似的结果; - 但是,如果找不到名称或名称有多义性,该函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 将文本函数或过程名转换为其OID。通过将字符串转换为regproc类型(参见)可以得到类似的结果; + 但是,如果找不到名称或名称有多义性,该函数将返回NULL而不会抛出错误。 @@ -22441,7 +23000,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); 将文本函数或过程名(带有参数类型)转换为其OID。通过将字符串类型转换为regprocedure可以得到类似的结果(参见); - 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。 @@ -22455,12 +23014,12 @@ SELECT collation for ('foo' COLLATE "de_DE"); 将文本角色名转换为它的OID。通过将字符串类型转换为regrole可以得到类似的结果(参见); - 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。 - + to_regtype @@ -22468,8 +23027,26 @@ SELECT collation for ('foo' COLLATE "de_DE"); regtype - 将文本类型名转换为它的OID。通过将字符串类型转换为regtype可以得到类似的结果(参见); - 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 解析文本字符串,从中提取可能的类型名,并将该名称转换为类型 OID。字符串中的语法错误会导致报错;但如果字符串是语法有效的类型名,只是在系统目录中找不到该类型,结果就是 NULL。将字符串转换为 regtype 类型也能得到类似的结果(参见 ),区别在于类型转换会在找不到名称时报错。 + + + + + + to_regtypemod + + to_regtypemod ( text ) + integer + + + 解析文本字符串,从中提取可能的类型名称,并转换其类型修饰符(如果有)。字符串中的语法错误会引发错误;但如果字符串是语法有效的类型名称,只是在系统目录中找不到,则结果为NULL。如果没有类型修饰符,则结果为-1。 + + + to_regtypemod可以与结合,为生成适当的输入,从而将表示类型名称的字符串转换为规范形式。 + + + format_type(to_regtype('varchar(32)'), to_regtypemod('varchar(32)')) + character varying(32) @@ -22477,10 +23054,10 @@ SELECT collation for ('foo' COLLATE "de_DE"); - 大多数重构(反编译)数据库对象的函数都有一个可选的 pretty标志,如果为true,结果将被pretty-printed。 - 美观打印会抑制不必要的圆括号,并为易读性增加空格。 - 美观打印的格式可读性更好,但是默认格式更有可能被PostgreSQL的未来版本以同样的方式解释; - 因此,避免为转储目的使用美观打印的输出。为pretty参数传递false会产生与省略参数相同的结果。 + 大多数重建(反编译)数据库对象的函数都有一个可选的pretty标志;若为true,则对结果进行美化输出。 + 美化输出会省略不必要的圆括号,并增加空白以提高可读性。 + 美化后的格式更易读,但默认格式更有可能被PostgreSQL的未来版本以同样的方式解释,因此用于转储时应避免美化输出。 + 为pretty参数传入false与省略该参数的结果相同。 @@ -22525,19 +23102,20 @@ SELECT collation for ('foo' COLLATE "de_DE"); distance_orderable - 列能否通过一个distance操作符(例如ORDER BY col <-> constant)有序地扫描? + + 能否按距离操作符的结果有序地扫描该列,例如ORDER BY col <-> constant returnable - 列值是否可以通过一次只用索引扫描返回? + 列值是否可以通过一次仅索引扫描返回? search_array - 列是否天然支持col = ANY(array)搜索? + 列是否原生支持col = ANY(array)搜索? @@ -22552,7 +23130,7 @@ SELECT collation for ('foo' COLLATE "de_DE");
- 索引性质 + 索引属性 @@ -22589,7 +23167,7 @@ SELECT collation for ('foo' COLLATE "de_DE");
- 索引访问方法性质 + 索引访问方法属性 @@ -22642,15 +23220,20 @@ SELECT collation for ('foo' COLLATE "de_DE"); EXPLAIN - 带有此标志的参数包含在EXPLAIN (SETTINGS)命令中。 + 带有此标志的参数会在EXPLAIN (SETTINGS)命令的输出中显示。 NO_SHOW_ALL - 具有此标志的参数将被排除在SHOW ALL命令之外。 + 带有此标志的参数不会在SHOW ALL命令的输出中显示。 + NO_RESET + 带有此标志的参数不支持RESET命令。 + + + NO_RESET_ALL 具有此标志的参数将被排除在RESET ALL命令之外。 @@ -22674,16 +23257,15 @@ SELECT collation for ('foo' COLLATE "de_DE"); - 对象信息和定位函数 + 对象信息和寻址函数 - 列出了与数据库对象 - 标识和定位有关的函数。 + 列出了与数据库对象标识和寻址有关的函数。
- 对象信息和定位函数 + 对象信息和寻址函数 @@ -22708,9 +23290,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); text - 返回由目录OID、对象OID和子对象ID(例如表中的列号)标识的数据库对象的文本描述;当引用整个对象时,子对象ID为0)。 - 这个描述是人类可读的,并且可以根据服务器配置进行翻译。这对于决定pg_depend目录中引用的对象的标识特别有用。 - 此函数对于未定义的对象返回NULL值 + 返回数据库对象的文本描述,对象由系统目录 OID、对象 OID 和子对象 ID 指定(例如表中的列号;引用整个对象时,子对象 ID 为零)。该描述供人阅读,并可能根据服务器配置被翻译。这对于确定pg_depend系统目录中所引用对象的标识尤其有用。对于未定义的对象,此函数返回NULL @@ -22727,13 +23307,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); identitytext ) - 返回包含足够信息的行以唯一标识由目录OID、对象OID和子对象ID指定的数据库对象。 - 这些信息是为了机器可读的,永远不会被翻译。 - type标识数据库对象的类型; - schema是对象所属的模式名,NULL表示不属于模式的对象类型; - name是对象的名称,如果有必要,用引号括起来,如果名称(随着模式名称,如果相关)足以唯一地标识对象,否则为NULL; - identity是完整的对象标识,其精确格式依赖于对象类型,格式中的每个名称都是模式限定的,并在必要时用引号括起来。 - 未定义的对象由NULL值标识。 + 返回一行,其中包含足以唯一标识数据库对象的信息,该对象由系统目录 OID、对象 OID 和子对象 ID 指定。这些信息供机器读取,永远不会被翻译。type标识数据库对象的类型;schema是对象所属的模式名,对于不属于模式的对象类型则为NULL;如果对象名(以及适用时的模式名)足以唯一标识该对象,name就是对象名,并在必要时加引号,否则为NULLidentity是完整的对象标识,其具体格式取决于对象类型,格式中的每个名称都会根据需要加上模式限定和引号。未定义的对象以NULL值标识。 @@ -22749,10 +23323,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); object_argstext[] ) - 返回包含足够信息的行以唯一标识由目录OID、对象OID和子对象ID指定的数据库对象。 - 返回的信息独立于当前服务器,也就是说,它可以用于标识另一个服务器中具有相同名称的对象。 - type标识数据库对象的类型;object_namesobject_args是文本数组,它们一起构成对对象的引用。 - 这三个值可以传递给pg_get_object_address以获得对象的内部地址。 + 返回一行,其中包含足以唯一标识数据库对象的信息,该对象由系统目录 OID、对象 OID 和子对象 ID 指定。返回的信息与当前服务器无关,也就是说,它也能用于标识另一台服务器上名称相同的对象。type标识数据库对象的类型;object_namesobject_args是文本数组,共同构成对该对象的引用。将这三个值传给pg_get_object_address可以获得对象的内部地址。 @@ -22768,12 +23339,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); objsubidinteger ) - 返回包含足够信息的行以唯一标识由类型代码、对象名称和参数数组指定的数据库对象。 - 返回的值将在系统目录中使用,例如pg_depend; - 它们可以传递给其他系统函数,比如 pg_describe_objectpg_identify_object。 - classid是包含该对象的系统目录的OID;objid是对象本身的OID, objsubid是子对象的ID,如果没有则为零。 - 这个函数是pg_identify_object_as_address的反向函数。 - 未定义的对象以NULL值标识。 + 返回一行,其中包含足以唯一标识数据库对象的信息,该对象由类型代码、对象名称数组和参数数组指定。返回的值就是pg_depend等系统目录中使用的值;它们可以传给pg_describe_objectpg_identify_object等其他系统函数。classid是包含该对象的系统目录的 OID;objid是对象自身的 OID;objsubid是子对象 ID,没有子对象时为零。此函数执行pg_identify_object_as_address的逆操作。未定义的对象以NULL值标识。 @@ -22792,7 +23358,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); - 中展示的函数抽取注释,注释是由命令在以前存储的。如果对指定参数找不到注释,则返回空值。 + 中的函数用于提取此前通过命令存储的注释。如果找不到与指定参数对应的注释,则返回空值。
@@ -22822,7 +23388,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); text - 返回表列的注释,该注释由该表的OID和列号指定。(obj_description不能用于表的列,因为列没有自己的oid。) + 返回表列的注释,列由所属表的 OID 和列号指定。(obj_description不能用于表列,因为列没有自身的 OID。) @@ -22835,8 +23401,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); text - 返回OID指定的数据库对象的注释和包含该对象的系统目录的名称。 - 例如,obj_description(123456, 'pg_class')将检索OID为123456的表的注释。 + 返回数据库对象的注释,对象由其 OID 和所在系统目录的名称指定。例如,obj_description(123456, 'pg_class')会获取 OID 为 123456 的表的注释。 @@ -22846,8 +23411,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); text - 返回仅由其OID指定的数据库对象的注释。 - 这个已被弃用(deprecated)因为无法保证oid在不同的系统目录中是唯一的;因此,可能会返回错误的注释。 + 返回仅由其 OID 指定的数据库对象的注释。此形式已弃用,因为无法保证 OID 在不同系统目录之间唯一,因而可能返回错误的注释。 @@ -22860,9 +23424,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); text - 返回共享数据库对象的注释,该对象由其OID和包含的系统编目的名称指定。 - 这与obj_description类似,只是它用于检索共享对象(也就是数据库、角色和表空间)上的注释。 - 有些系统编目对每个集簇中的所有数据库都是全局的,其中对象的描述也全局存储。 + 返回共享数据库对象的注释,对象由其 OID 和所在系统目录的名称指定。此函数与obj_description类似,但用于获取共享对象(即数据库、角色和表空间)的注释。有些系统目录由数据库集簇中的所有数据库全局共享,其中对象的描述也全局存储。 @@ -22998,6 +23560,32 @@ SELECT collation for ('foo' COLLATE "de_DE"); + + + + age + + age ( xid ) + integer + + + 返回给定事务 ID 与当前事务计数器之间的事务数。 + + + + + + + mxid_age + + mxid_age ( xid ) + integer + + + 返回给定多事务 ID 与当前多事务计数器之间的多事务 ID 数。 + + + @@ -23007,7 +23595,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); xid8 - 返回当前事务的ID。如果当前事务还没有一个ID(因为它还没有执行任何数据库更新),它将分配一个新的事务。 + 返回当前事务的ID。如果当前事务还没有一个ID(因为它还没有执行任何数据库更新),它将分配一个新的事务 ID;详见。如果在子事务中执行,它将返回顶层事务的ID;详见 @@ -23020,8 +23608,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); xid8 - 返回当前事务的ID,如果还没有分配ID则返回NULL。 - (如果事务可能是只读的,最好使用这种变体,以避免不必要地消耗XID。) + 返回当前事务的 ID;如果尚未分配 ID,则返回NULL。(如果事务本来可能是只读的,最好使用此变体,以免不必要地消耗 XID。)如果在子事务中执行,则返回顶层事务 ID。 @@ -23034,10 +23621,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); text - 报告最近的事务的提交状态。如果事务为最近的,系统会保留事务的提交状态,则结果是 in progresscommittedaborted。 - 如果该事务的时间足够久,并且系统中没有对该事务的引用,而且提交状态信息已经被丢弃,则结果为NULL。 - 应用可以使用此函数,例如,确定在进行COMMIT时,应用程序和数据库服务器断开连接后,它们的事务是已提交还是中止。 - 注意,准备好的事务报告为in progress的事务;如果应用需要确定一个事务ID是否属于一个准备好的事务,则必须检查pg_prepared_xacts。 + 报告近期事务的提交状态。只要事务足够新,系统仍保留其提交状态,结果就为in progresscommittedaborted。如果事务已足够旧,系统中不再有对它的引用,且提交状态信息已被丢弃,则返回NULL。例如,在COMMIT进行过程中应用与数据库服务器断开连接时,应用可以用此函数判断事务是提交了还是中止了。注意,预备事务被报告为in progress;如果需要确定某个事务 ID 是否为预备事务,应用必须检查pg_prepared_xacts @@ -23050,7 +23634,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); pg_snapshot - 返回当前snapshot,显示哪些事务 ID正在进行中的数据结构。 + 返回当前快照,即显示哪些事务 ID 正在进行中的数据结构。快照中只包含顶层事务 ID,不显示子事务 ID;详见 @@ -23102,8 +23686,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); boolean - 根据此快照,给定的事务ID是否可见(visible)(也就是说,它是否在快照拍摄之前完成)? - 注意,这个函数不会给出子事务ID的正确答案。 + 根据此快照,给定的事务 ID 是否可见(即该事务是否在生成快照之前完成)?注意,此函数无法为子事务 ID(subxid)给出正确结果;详见 @@ -23127,7 +23710,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); 内部事务 ID 类型xid是 32 位宽,每 40 亿个事务就会回卷一次(wrap around)。 - 但是,中所示的函数使用的是 64 位类型xid8,它在一次安装的生命周期内不会回卷,必要时可以通过强制转换将其转换为xid。 + 但是,中所示的函数(agemxid_agepg_get_multixact_members除外)使用的是 64 位类型xid8,它在一次安装的生命周期内不会回卷,必要时可以通过类型转换将其转换为xid;详见。 数据类型pg_snapshot存储特定时刻事务ID可见性的信息。 其组成如所描述。pg_snapshot的文本表示形式是xmin:xmax:xip_list。 例如10:20:10,14,15表示xmin=10, xmax=20, xip_list=10, 14, 15。 @@ -23150,21 +23733,22 @@ SELECT collation for ('foo' COLLATE "de_DE"); xmin - 仍然处于活动状态的最低事务ID。所有小于xmin的事务 ID要么提交且可见,要么回滚并死亡。 + 仍然处于活动状态的最小事务 ID。所有小于xmin的事务 ID 要么已经提交且可见,要么已经回滚而失效。 xmax - 比最高完成的事务ID还高出一个值。所有大于或等于xmax的事务 ID到快照时还没有完成,因此不可见。 + 已完成事务中的最大事务 ID 加一。所有大于或等于xmax的事务 ID 在生成快照时尚未完成,因此不可见。 xip_list - 快照时正在进行的事务。一个事务ID为xmin <= X < xmax且不在快照时已经完成的列表中,因此根据其提交状态,该事务ID要么是可见的,要么是死的。此列表不包括子事务的事务 ID。 + 生成快照时正在进行的事务。满足xmin <= X < + xmax且不在此列表中的事务 ID 在生成快照时已经完成,因此根据其提交状态,要么可见,要么失效。此列表不包含子事务的事务 ID(subxid)。 @@ -23309,8 +23893,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); 已提交事务信息函数 - 中的函数提供了关于过去的事务何时被提交的信息。 - 它们只在启用配置选项时提供有用的数据,并且只针对在启用该选项后提交的事务。 + 中的函数提供过去事务的提交时间信息。只有启用配置选项后,这些函数才会提供有用的数据,并且只针对启用该选项之后提交的事务。提交时间戳信息会在 vacuum 过程中定期清理。
@@ -23355,7 +23938,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); roidentoid) - 返回事务的提交时间戳和复制起源。 + 返回事务的提交时间戳和复制源。 @@ -23371,7 +23954,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); roidentoid ) - 返回最近提交的事务的事务ID、提交时间戳和复制源头。 + 返回最近提交事务的事务 ID、提交时间戳和复制源。 @@ -23385,9 +23968,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); 控制数据函数 - 中所展示的函数能打印initdb期间初始化的信息,例如目录版本。 - 它们也能显示有关预写式日志和检查点处理的信息。这些信息是集簇范围内的,不与任何特定的一个数据库相关。 - 这些函数提供大致相同的信息,对于同一种来源,就像应用。 + 中的函数显示在initdb期间初始化的信息,例如系统目录版本。它们也显示有关预写式日志和检查点处理的信息。这些信息适用于整个数据库集簇,而非某个特定数据库。这些函数与应用程序从相同来源提供大部分相同的信息。
@@ -23417,7 +23998,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); record - 返回有关当前检查点状态的信息, 如 所展示。 + 返回有关当前检查点状态的信息, 如 所展示。 @@ -23456,7 +24037,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); record - 返回有关恢复状态的信息,如 所展示。 + 返回有关恢复状态的信息,如 所展示。 @@ -23750,6 +24331,8 @@ SELECT collation for ('foo' COLLATE "de_DE"); + + @@ -23865,7 +24448,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); WAL 记录修改过。每一行中,如果is_limit_block 为 true,则表示以下两种情况之一:(a) 该关系分支在相关 WAL 记录范围内 被截断到relblocknumber给出的长度;或者 (b) 该关系分支在 - 相关 WAL 记录范围内被创建或删除;在这些情况下, + 相关 WAL 记录范围内被创建或删除;在创建或删除的情况下, relblocknumber将为零。 @@ -23937,9 +24520,9 @@ SELECT collation for ('foo' COLLATE "de_DE"); - configuration - of the server - functions + 配置 + 服务器 + 函数 @@ -23976,7 +24559,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); text - 返回设置的setting_name的当前值。 + 返回设置setting_name的当前值。 如果没有这样的设置,current_setting将抛出一个错误,除非missing_ok被提供并且为true(在此情况下返回NULL)。 这个函数对应于SQL命令 @@ -23998,9 +24581,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); text - 将参数setting_name设置为new_value,并返回该值。 - 如果is_localtrue,新值将仅在当前事务期间应用。 - 如果您希望新值应用于当前会话的其余部分,请使用false代替。这个函数对应于SQL命令。 + 将参数setting_name设置为new_value,并返回该值。如果is_localtrue,新值仅在当前事务期间生效。如果希望新值在当前会话的剩余时间内生效,则使用false。此函数对应 SQL 命令 set_config('log_statement_stats', 'off', false) @@ -24023,7 +24604,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); - 在中展示的函数向其它服务器进程发送控制信号。默认情况下这些函数只能被超级用户使用,但是如果需要,可以利用GRANT把访问权限授予给其他用户。 + 在中展示的函数向其它服务器进程发送控制信号。默认情况下这些函数只能被超级用户使用,但是如果需要,可以利用GRANT把访问权限授予给其他用户(注明的例外除外)。 @@ -24071,11 +24652,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); boolean - 请求记录具有指定进程ID的后端的内存上下文。此函数可以将请求发送到后端和辅助进程,但不包括记录器。这些内存上下文将以 - LOG消息级别记录。它们将根据设置的日志配置出现在服务器日志中 - (有关更多信息,请参见), - 但无论如何都不会发送给客户端 - ()。 + 请求记录具有指定进程 ID 的后端进程的内存上下文。此函数可以向除日志记录进程以外的后端进程和辅助进程发送请求。这些内存上下文将以LOG消息级别记录,并根据日志配置出现在服务器日志中(详见);无论如何设置,都不会发送给客户端。 @@ -24124,7 +24701,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); 终止具有指定进程ID的后端进程的会话。如果调用角色是正在终止的后端的角色的成员,或者调用角色具有pg_signal_backend的权限,则也允许执行此操作,但只有超级用户才能终止超级用户后端。 - 如果未指定或超时timeout为零,则此函数无论进程是否实际终止,都将返回true,仅表示信号发送成功。如果指定了timeout(以毫秒为单位)且大于零,则函数将等待直到进程实际终止或直到给定时间已过。如果进程被终止,函数将返回true。在超时时,会发出警告并返回false。 + 如果未指定timeout或其值为零,则此函数无论进程是否实际终止,都将返回true,仅表示信号发送成功。如果指定了timeout(以毫秒为单位)且大于零,则函数将等待直到进程实际终止或直到给定时间已过。如果进程被终止,函数将返回true。在超时时,会发出警告并返回false @@ -24173,7 +24750,7 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 备份控制函数 - backup + 备份 @@ -24213,13 +24790,9 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 pg_lsn - 在预写式日志中创建一个命名标记记录,稍后可以将其用作恢复目标,并返回相应的预写日志位置。 - 然后可以将给定的名称与 一起使用,以指定进行恢复的点。 - 要避免创建多个名称相同的恢复点,因为恢复将在第一个名称与恢复目标匹配的恢复点停止。 + 在预写式日志中创建一条命名标记记录,供以后用作恢复目标,并返回相应的预写式日志位置。随后可以在中使用给定名称,指定恢复到哪一点。应避免创建多个同名恢复点,因为恢复会在第一个名称匹配恢复目标的恢复点停止。 - - 默认情况下,该函数仅限超级用户使用,但可以授权给其他用户执行该函数。 - + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -24231,7 +24804,7 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 pg_lsn - 返回当前预写式日志刷新位置(参见下面的说明)。 + 返回当前预写式日志刷盘位置(参见下文说明)。 @@ -24244,7 +24817,7 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 pg_lsn - 返回当前预式日志插入位置(参见下面的说明)。 + 返回当前预写式日志插入位置(参见下文说明)。 @@ -24257,7 +24830,7 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 pg_lsn - 返回当前预写式日志写位置(参见下面的说明)。 + 返回当前预写式日志写入位置(参见下文说明)。 @@ -24273,15 +24846,9 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 pg_lsn - 准备服务器开始在线备份。唯一必需的参数是备份的任意用户定义标签。 - (通常这将是备份转储文件存储的名称。) - 如果将可选的第二个参数指定为true, - 它将尽快执行pg_backup_start。这将强制立即进行检查点, - 这将导致I/O操作的激增,从而减慢任何同时执行的查询。 + 准备服务器开始在线备份。唯一必需的参数是用户任意指定的备份标签。(通常是备份转储文件将要保存的名称。)如果可选的第二个参数为true,则尽快执行pg_backup_start。这会强制立即执行检查点,使 I/O 操作量陡增,并降低并发执行的查询的速度。 - - 默认情况下,此函数仅限于超级用户,但可以授予其他用户执行权限以运行该函数。 - + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -24298,31 +24865,18 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 spcmapfile text ) - 完成在线备份。函数的结果中返回备份标签文件和表空间映射文件的期望内容,并必须写入备份区域的文件中。 - 这些文件不得写入实时数据目录(这样做将导致PostgreSQL在崩溃时无法重新启动)。 + 结束在线备份。备份标签文件和表空间映射文件所需的内容作为函数结果的一部分返回,必须将其写入备份区域中的文件。切勿将这些文件写入正在使用的数据目录(否则发生崩溃后 PostgreSQL 将无法重新启动)。 - 有一个类型为boolean的可选参数。 - 如果为false,则在备份完成后立即返回,而无需等待WAL进行归档。 - 此行为仅适用于独立监视WAL归档的备份软件。否则,可能会缺少使备份一致所需的WAL,使备份无效。 - 默认情况下或当此参数为true时,pg_backup_stop将在启用归档时等待WAL进行归档。 - (在备库上,这意味着仅当archive_mode = always时才会等待。 - 如果主库上的写入活动较低,则可能有必要在主库上运行pg_switch_wal以触发立即段切换。) + 有一个boolean类型的可选参数。如果为 false,该函数会在备份完成后立即返回,不等待 WAL 归档。这种行为只适用于自行监控 WAL 归档的备份软件;否则,可能缺少使备份保持一致所需的 WAL,导致备份无法使用。默认情况下或该参数为 true 时,若已启用归档,pg_backup_stop会等待 WAL 归档。(在备库上,这意味着只有archive_mode = always时才会等待。如果主库的写入活动很少,可以在主库上运行pg_switch_wal,触发立即切换日志段。) - 在主库上执行时,此函数还会在预写式日志归档区域中创建一个备份历史文件。 - 历史文件包括给定给pg_backup_start的标签、备份的起始和结束预写式日志位置,以及备份的起始和结束时间。 - 在记录结束位置后,当前的预写式日志插入点会自动前进到下一个预写式日志文件,以便立即归档结束的预写式日志文件以完成备份。 + 在主库上执行时,该函数还会在预写式日志归档区域创建备份历史文件。历史文件包括传给pg_backup_start的标签、备份的起止预写式日志位置以及备份的起止时间。记录结束位置后,当前预写式日志插入点会自动推进到下一个预写式日志文件,使包含结束位置的预写式日志文件可以立即归档,从而完成备份。 - 函数的结果是一个记录。 - lsn列保存备份的结束预写式日志位置(可以忽略)。 - 第二列返回备份标签文件的内容,第三列返回表空间映射文件的内容。 - 这些必须作为备份的一部分存储,并作为恢复过程的一部分。 + 该函数的结果是一条记录。lsn列保存备份结束时的预写式日志位置(同样可以忽略)。第二列返回备份标签文件的内容,第三列返回表空间映射文件的内容。这些内容必须作为备份的一部分保存,恢复时需要用到它们。 - - 默认情况下,此函数仅限于超级用户,但可以授予其他用户 EXECUTE 权限来运行该函数。 - + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -24334,13 +24888,9 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 pg_lsn - 强制服务器切换到一个新的预写式日志文件,这允许对当前文件进行归档(假设你正在使用连续归档)。 - 其结果是在刚刚完成的预写式日志文件中结束预写式日志位置加1。 - 如果自从上次预写式日志切换以来没有提前写日志活动,pg_switch_wal将不做任何操作,并返回当前正在使用的提前写日志文件的起始位置。 + 强制服务器切换到新的预写式日志文件,使当前文件可以归档(假设正在使用连续归档)。返回值是刚完成的预写式日志文件中的结束预写式日志位置加 1。如果自上次切换预写式日志以来没有发生任何预写式日志活动,pg_switch_wal不执行任何操作,并返回当前使用的预写式日志文件的起始位置。 - - 默认情况下该函数仅限超级用户使用,但可以授权其他用户执行该函数。 - + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -24352,7 +24902,7 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 text - 将预写式日志位置转换为保持该位置的WAL文件的名称。 + 将预写式日志位置转换为包含该位置的 WAL 文件的名称。 @@ -24371,6 +24921,21 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 + + + + pg_split_walfile_name + + pg_split_walfile_name ( file_name text ) + record + ( segment_number numeric, + timeline_id bigint ) + + + 从 WAL 文件名中提取序列号和时间线 ID。 + + + @@ -24380,34 +24945,38 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 numeric - 计算两个预写式日志位置之间的字节(lsn1 - lsn2)差异。 - 这可以与pg_stat_replication中所示的一些函数一起使用,以获得复制延迟。 + 计算两个预写式日志位置之间的字节差(lsn1 - lsn2)。可以将它与pg_stat_replication中的某些函数配合使用,以获取复制延迟。
- - pg_current_wal_lsn 显示当前预写式日志写位置,与上述函数所用的格式相同。 - 类似地,pg_current_wal_insert_lsn显示当前预写式日志插入位置,pg_current_wal_flush_lsn显示当前预写式日志刷新位置。 - 插入位置是预写式日志在任何时刻的逻辑(logical) 结束,而写位置是已经从服务器内部缓冲区实际写入的内容的结束,而刷新位置是已知的要写入持久化存储的最后一个位置。 - 写位置是可以从服务器外部检查的最后位置,如果你对归档部分完成的预写式日志文件感兴趣,那么它通常就是你想要的位置。 - 插入和刷新位置主要用于服务器调试目的。这些都是只读操作,不需要超级用户权限。 - + pg_current_wal_lsn 显示当前预写式日志写入位置,格式与上述函数相同。类似地,pg_current_wal_insert_lsn 显示当前预写式日志插入位置,pg_current_wal_flush_lsn 显示当前预写式日志刷盘位置。插入位置是预写式日志在任意时刻的逻辑末尾;写入位置是实际从服务器内部缓冲区写出的内容的末尾;刷盘位置则是已知已经写入持久存储的最后位置。写入位置是能从服务器外部检查到的内容的末尾,如果要归档尚未写满的预写式日志文件,通常需要这个位置。插入位置和刷盘位置主要用于服务器调试。这些都是只读操作,不需要超级用户权限。 - - 您可以使用pg_walfile_name_offsetpg_lsn值中提取相应的预写式日志文件名和字节偏移量。例如: - + 可以使用pg_walfile_name_offset从一个pg_lsn值中提取相应的预写式日志文件名和字节偏移量。例如: postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); file_name | file_offset --------------------------+------------- 00000001000000000000000D | 4039624 (1 row) +类似地,pg_walfile_name仅提取预写式日志文件名。 + + + pg_split_walfile_name可用于根据文件偏移量和 WAL 文件名计算 + LSN,例如: + +postgres=# \set file_name '000000010000000100C000AB' +postgres=# \set offset 256 +postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset AS lsn + FROM pg_split_walfile_name(:'file_name') pd, + pg_show_all_settings() ps + WHERE ps.name = 'wal_segment_size'; + lsn +--------------- + C001/AB000100 +(1 row) - 类似地,pg_walfile_name仅提取预写式日志文件名。 - 当给定的预写式日志位置恰好位于预写式日志文件边界时,这两个函数都会返回前一个预写式日志文件的名称。 - 这通常是管理预写式日志归档行为的期望行为,因为前一个文件是当前需要归档的最后一个文件。 @@ -24461,9 +25030,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); pg_lsn - 返回已接收并通过流复制同步到磁盘的最后一个预写式日志位置。 - 当流复制正在进行时这将单调地增加。如果恢复已经完成,那么在恢复期间,接收到的最后一条WAL记录的位置将保持静态,并同步到磁盘。 - 如果流复制已禁用,或者尚未启动,函数将返回NULL。 + 返回流复制最近接收并同步到磁盘的预写式日志位置。在流复制进行期间,该值单调增加。如果恢复已完成,该值将保持为恢复期间最后接收并同步到磁盘的 WAL 记录的位置。如果禁用了流复制,或者流复制尚未开始,此函数返回 NULL @@ -24476,8 +25043,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); pg_lsn - 返回恢复期间重新播放的最后一个预写式日志位置。如果恢复仍在进行中这将会单调地增加。 - 如果恢复已经完成,那么恢复期间应用的最后WAL记录的位置将保持静态。当服务器正常启动且没有恢复时,函数返回NULL。 + 返回恢复期间最近重放的预写式日志位置。如果恢复仍在进行,该值单调增加。如果恢复已完成,该值将保持为该次恢复期间最后应用的 WAL 记录的位置。如果服务器未经恢复而正常启动,此函数返回 NULL @@ -24490,10 +25056,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); timestamp with time zone - 返回恢复期间重放的最后一个事务的时间戳。这是在主库上为该事务生成提交或中止 WAL记录的时间。 - 如果在恢复期间没有重放任何事务,该函数将返回NULL。否则,如果恢复仍在进行中,这将单调地增加。 - 如果恢复已经完成,那么在恢复期间应用最后一个事务时,这将会保持静态。 - 当服务器正常启动且没有恢复时,函数返回NULL。 + 返回恢复期间最近重放事务的时间戳,即该事务的提交或中止 WAL 记录在主库上生成的时间。如果恢复期间尚未重放任何事务,此函数返回 NULL。否则,如果恢复仍在进行,该值单调增加。如果恢复已完成,该值将保持为该次恢复期间最后应用的事务的时间戳。如果服务器未经恢复而正常启动,此函数返回 NULL @@ -24517,7 +25080,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); - 控制恢复进度的功能如 所示。这些函数只能在恢复过程中执行。 + 列出的函数用于控制恢复进度。这些函数只能在恢复期间执行。 @@ -24547,7 +25110,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); boolean - 如果请求了恢复暂停了则返回真。 + 如果已请求暂停恢复,则返回真。 @@ -24561,7 +25124,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); 返回恢复暂停状态。 - 如果没有请求pause,返回值是not paused,如果请求暂停但恢复还没有暂停,返回值是pause requested,如果恢复实际已经暂停,返回值是paused。 + 如果没有请求暂停,返回值是not paused,如果请求暂停但恢复还没有暂停,返回值是pause requested,如果恢复实际已经暂停,返回值是paused @@ -24575,11 +25138,11 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); 将备库提升为主库状态。 - 当wait设置为true(默认值)时,函数将等待直到升级完成或wait_seconds秒数已过,如果升级成功则返回true,否则返回false。 - 如果wait设置为false,则该函数在向postmaster发送SIGUSR1信号以触发升级后立即返回true。 + 当wait设置为true(默认值)时,函数将等待直到提升完成或wait_seconds秒数已过,如果提升成功则返回true,否则返回false。 + 如果wait设置为false,则该函数在向postmaster发送SIGUSR1信号以触发提升后立即返回true - 默认情况下这个函数仅限超级用户使用,但可以授权给其他用户执行该函数。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -24600,7 +25163,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); 如果热备是激活的,所有新查询将看到相同的一致的数据库快照,并且在恢复继续之前不会生成进一步的查询冲突。 - 默认情况下该函数仅限超级用户使用,但可以授权其他用户执行该函数。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -24616,7 +25179,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); 如果暂停了,则重新启动恢复。 - 默认情况下该函数仅限超级用户使用,但可以授权其他用户执行该函数。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -24624,8 +25187,8 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn);
- pg_wal_replay_pausepg_wal_replay_resume不能在提升(promotion)进行时执行。 - 如果在恢复暂停时触发了提升(promotion),则暂停状态结束,升级继续进行。 + pg_wal_replay_pausepg_wal_replay_resume不能在提升进行时执行。 + 如果在恢复暂停时触发了提升,则暂停状态结束,提升继续进行。 @@ -24644,7 +25207,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); - 为了解决这个问题,PostgreSQL允许一个事务导出它正在使用的快照。只要导出的事务仍然保持打开,其他事务可以导入它的快照,并且因此可以保证它们可以看到和第一个事务看到的完全一样的数据库视图。但是注意这些事务中的任何一个对数据库所作的更改对其他事务仍然保持不可见,和未提交事务所作的修改一样。因此这些事务是针对以前存在的数据同步,而对由它们自己所作的更改则采取正常的动作。 + 为了解决这个问题,PostgreSQL允许一个事务导出它正在使用的快照。只要导出快照的事务仍然保持打开,其他事务可以导入它的快照,并且因此可以保证它们可以看到和第一个事务看到的完全一样的数据库视图。但是注意这些事务中的任何一个对数据库所作的更改对其他事务仍然保持不可见,和未提交事务所作的修改一样。因此这些事务是针对以前存在的数据同步,而对由它们自己所作的更改则采取正常的动作。 @@ -24684,7 +25247,19 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); 如果需要的话,一个事务可以导出多个快照。 请注意,这样做仅在READ COMMITTED事务中有用,因为在REPEATABLE READ和更高的隔离级别中,事务在它们的生命周期中使用相同的快照。 - 一旦事务导出了快照,它就不能用 进行准备。 + 一旦事务导出了快照,它就不能用 进行预备。 + + + + + + pg_log_standby_snapshot + + pg_log_standby_snapshot () + pg_lsn + + + 为进行中的事务拍摄快照并将其写入 WAL,无须等待后台写入器或检查点进程记录快照。这对备用服务器上的逻辑解码很有用,因为创建逻辑复制槽必须等待此类记录在备用服务器上重放。 @@ -24700,7 +25275,6 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); 中展示的函数用于控制以及与复制特性交互。 有关底层特性的信息请见以及。 - 复制原点函数的使用仅限于超级用户。 默认只允许超级用户使用复制源的函数,但可以通过GRANT命令允许其他用户使用。 复制槽的函数只限于超级用户和拥有REPLICATION权限的用户。 @@ -24746,12 +25320,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); lsn pg_lsn ) - 创建一个新的名为slot_name的物理复制槽。 - 第二个参数是可选的,当它为true时,立即为这个物理槽指定要被保留的LSN。 - 否则该LSN会被保留在来自一个流复制客户端的第一个连接上。 - 来自一个物理槽的更改只能通过流复制协议进行流式传输 — 见。 - 当可选的第三参数temporary被设置为真时,指定那个槽不会被持久地存储在磁盘上并且仅对当前会话的使用有意义。 - 临时槽也会在发生任何错误时被释放。这个函数对应于复制协议命令CREATE_REPLICATION_SLOT ... PHYSICAL。 + 创建名为 slot_name 的新物理复制槽。可选的第二个参数为 true 时,指定立即为此复制槽保留 LSN;否则在流复制客户端首次连接时保留 LSN。从物理槽流式传输更改只能使用流复制协议 — 参见。可选的第三个参数 temporary 为真时,指定该槽不永久存储到磁盘,且仅供当前会话使用。发生任何错误时,临时槽也会被释放。此函数对应复制协议命令 CREATE_REPLICATION_SLOT ... PHYSICAL @@ -24764,9 +25333,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); void - 丢弃名为slot_name的物理或逻辑复制槽。 - 和复制协议命令DROP_REPLICATION_SLOT相同。对于逻辑槽, - 在连接到在其中创建该槽的同一个数据库时,必须调用这个函数。 + 删除名为slot_name的物理或逻辑复制槽。与复制协议命令DROP_REPLICATION_SLOT相同。 @@ -24781,7 +25348,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); lsn pg_lsn ) - 创建一个名为slot_name的新逻辑(解码)复制槽,使用输出插件plugin。可选的第三个参数temporary,当设置为true时,指定插槽不应永久存储到磁盘,仅供当前会话使用。临时插槽也会在任何错误发生时释放。可选的第四个参数twophase,当设置为true时,指定为此插槽启用已准备事务的解码。可选的第五个参数failover,当设置为true时,指定启用此插槽同步到备库,以便在故障切换后可以恢复逻辑复制。调用此函数的效果与复制协议命令CREATE_REPLICATION_SLOT ... LOGICAL相同。 + 创建一个名为slot_name的新逻辑(解码)复制槽,使用输出插件plugin。可选的第三个参数temporary,当设置为真时,指定槽不应永久存储到磁盘,仅供当前会话使用。临时槽也会在任何错误发生时释放。可选的第四个参数twophase,当设置为真时,指定为此槽启用预备事务的解码。可选的第五个参数failover,当设置为真时,指定启用此槽同步到备库,以便在故障切换后可以恢复逻辑复制。调用此函数的效果与复制协议命令CREATE_REPLICATION_SLOT ... LOGICAL相同。 @@ -24797,8 +25364,9 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); 将一个名为src_slot_name的现有物理复制槽复制到一个名为dst_slot_name的物理复制槽。 - 被复制的物理槽开始从与源槽相同的LSN开始保留WAL。temporary是可选的。 + 复制后的物理槽从与源槽相同的LSN开始保留WAL。temporary是可选的。 如果省略了temporary,则使用与源槽相同的值。 + 不能复制已失效的槽。 @@ -24813,9 +25381,11 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); lsn pg_lsn ) - 复制一个名为src_slot_name的现有逻辑复制槽到一个名为dst_slot_name的逻辑复制槽,选择性的改变输出插件和持久性。 + 复制一个名为src_slot_name的现有逻辑复制槽到一个名为dst_slot_name的逻辑复制槽,可选地更改输出插件和持久性。 被复制的逻辑槽从与源逻辑槽相同的LSN开始。temporaryplugin都是可选的。 如果它们被省略了,使用与源逻辑槽相同的值。 + 源逻辑槽的failover选项不会被复制,而是默认设为false。这是为了避免故障切换到正在同步该槽的备库后无法继续逻辑复制的风险。 + 不能复制已失效的槽。 @@ -24831,16 +25401,12 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); data text ) - 返回槽slot_name中的改变,从最后一次使用更改的点开始。 - 如果upto_lsnupto_nchanges为 NULL,逻辑解码将一直继续到 WAL 的末尾。 - 如果upto_lsn为非 NULL,解码将只包括那些在指定 LSN 之前提交的事务。 - 如果upto_nchanges为非 NULL,解码将在其产生的行数超过指定值后停止。 - 不过要注意,被返回的实际行数可能更大,因为对这个限制的检查只会在增加了解码每个新的提交事务产生的行之后进行。 + 返回槽 slot_name 中自上次消费更改的位置起的更改。如果 upto_lsnupto_nchanges 都为 NULL,逻辑解码会持续到 WAL 末尾。如果 upto_lsn 非 NULL,解码仅包含在指定 LSN 之前提交的事务。如果 upto_nchanges 非 NULL,解码产生的行数超过指定值时就会停止。不过,实际返回行数可能更大,因为只有在添加完对每个新事务提交进行解码所产生的行后,才会检查此限制。如果指定的槽是逻辑故障切换槽,则只有在synchronized_standby_slots中指定的所有物理槽都确认已接收 WAL 后,该函数才会返回。 - + pg_logical_slot_peek_changes @@ -24890,7 +25456,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); - + pg_replication_slot_advance @@ -24900,9 +25466,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); end_lsn pg_lsn ) - 将复制槽的当前确认的位置提前到名为slot_name的复制槽的当前确认位置。 - 该槽不会向后移动,也不会移动到当前插入位置之外。返回该槽的名称和它被推进到的真实位置。 - 如果有任何进展,则在下一个检查点中写出更新后的槽位置信息。所以如果发生崩溃,该槽位可能会返回到之前的位置。 + 推进名为 slot_name 的复制槽当前已确认的位置。该槽不会后退,也不会越过当前插入位置。返回槽名及其实际推进到的位置。如果发生了推进,更新后的槽位置信息会在下一个检查点写出。因此,发生崩溃时,槽可能回到更早的位置。如果指定的槽是逻辑故障切换槽,则只有在 synchronized_standby_slots 中指定的所有物理槽都确认已接收 WAL 后,该函数才会返回。 @@ -24954,8 +25518,8 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); void - 将当前会话标记为从给定的原点回放,从而允许跟踪回放进度。 - 只能在当前没有选择原点时使用。使用pg_replication_origin_session_reset 命令来撤销。 + 将当前会话标记为从给定的复制源重放,从而允许跟踪重放进度。 + 只能在当前没有选择复制源时使用。使用pg_replication_origin_session_reset来撤销。 @@ -24994,7 +25558,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); pg_lsn - 返回当前会话中选择的复制源的重放位置。参数flush决定对应的本地事务是否被确保已经刷入磁盘。 + 返回当前会话中选择的复制源的重放位置。参数flush决定是否保证对应的本地事务已刷盘。 @@ -25048,7 +25612,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); pg_lsn - 返回给定复制元的重放位置。参数flush决定对应的本地事务是否被确保已经刷入磁盘。 + 返回给定复制源的重放位置。参数flush决定是否保证对应的本地事务已刷盘。 @@ -25057,19 +25621,15 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); pg_logical_emit_message - pg_logical_emit_message ( transactional boolean, prefix text, content text ) + pg_logical_emit_message ( transactional boolean, prefix text, content text [, flush boolean DEFAULT false] ) pg_lsn - pg_logical_emit_message ( transactional boolean, prefix text, content bytea ) + pg_logical_emit_message ( transactional boolean, prefix text, content bytea [, flush boolean DEFAULT false] ) pg_lsn - 发出逻辑解码消息。这可以用于通过WAL将通用消息传递给逻辑解码插件。 - transactional参数指定消息是否应该是当前事务的一部分, - 还是应该立即写入并在逻辑解码器读取记录时立即解码。 - prefix参数是一个文本前缀,逻辑解码插件可以使用它轻松识别对它们有趣的消息。 - content参数是消息的内容,可以以文本或二进制形式给出。 + 发出逻辑解码消息。这可用于通过 WAL 向逻辑解码插件传递通用消息。transactional 参数指定消息是作为当前事务的一部分,还是立即写入并在逻辑解码器读到该记录时立即解码。prefix 参数是一个文本前缀,便于逻辑解码插件识别其关注的消息。content 参数是消息内容,可以文本或二进制形式给出。 flush 参数(默认为 false)控制是否立即将消息对应的 WAL 记录刷盘。transactional 为真时,flush 不起作用,因为消息的 WAL 记录会与其事务一起刷盘。 @@ -25158,6 +25718,19 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); + + + + pg_column_toast_chunk_id + + pg_column_toast_chunk_id ( "any" ) + oid + + + 显示磁盘上经过TOAST处理的值的chunk_id。如果该值未经过TOAST处理或不在磁盘上,则返回NULL。有关TOAST的更多信息,请参见。 + + + @@ -25198,13 +25771,13 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); bigint - 计算指定关系的一个fork所使用的磁盘空间。 - (注意在大多数情况下,使用更高级的函数 pg_total_relation_sizepg_table_size更方便,它们将所有分叉(forks)的大小相加。) - 使用一个参数,这将返回关系的主数据分叉的大小。第二个参数可以用来指定要检查哪个分叉: + 计算指定关系的一个分支所使用的磁盘空间。 + (注意在大多数情况下,使用更高级的函数 pg_total_relation_sizepg_table_size更方便,它们将所有分支的大小相加。) + 使用一个参数,这将返回关系的主数据分支的大小。第二个参数可以用来指定要检查哪个分支: - main返回关系的主数据分叉的大小。 + main返回关系的主数据分支的大小。 @@ -25219,7 +25792,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); - init 返回初始化分叉的大小,如果有的话,与关系相关。 + init 返回与该关系关联的初始化分支(如有)的大小。 @@ -25235,7 +25808,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); bigint - 将人类可读格式的大小(由pg_size_pretty返回)转换为字节。 + 将人类可读格式的大小(由pg_size_pretty返回)转换为字节。有效的单位为bytesBkBMBGBTBPB @@ -25266,7 +25839,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); bigint - 计算指定表所使用的磁盘空间,不包括索引(但包括它的TOAST表,如果有的话,空闲空间映射,以及可见性映射)。 + 计算指定表所使用的磁盘空间,不包括索引(但包括其 TOAST 表(如有)、空闲空间映射和可见性映射)。 @@ -25308,11 +25881,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); - 上述操作表和索引的函数接受一个regclass参数,它是该表或索引在pg_class系统目录中的 OID。 - 你不必手工去查找该 OID,因为regclass数据类型的输入转换器会为你代劳。 - 只写包围在单引号内的表名,这样它看起来像一个文字常量。 - 为了与普通SQL名称的处理相兼容,该字符串将被转换为小写形式,除非其中在表名周围包含双引号。 - 详见。 + 上述操作表和索引的函数接受一个regclass参数,即该表或索引在pg_class系统目录中的 OID。不必手工查找该 OID,因为regclass数据类型的输入转换器会代为查找。详见 @@ -25346,7 +25915,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); oid - 返回当前分配给指定关系的filenode数字。文件节点是用于该关系的文件名称的基本组件(更多信息请参阅 )。 + 返回当前分配给指定关系的文件结点编号。文件结点是用于该关系的文件名称的基本组件(更多信息请参阅 )。 对于大多数关系,其结果与pg_class.relfilenode相同,但对于某些系统目录,relfilenode为0,并且必须使用这个函数来获得正确的值。 如果传递的是一个没有存储的关系,例如一个视图,那么函数将返回NULL。 @@ -25361,7 +25930,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); text - 返回关系的完整文件路径名称(相对于数据库集簇的数据目录,即关系的PGDATA)。 + 返回关系的完整文件路径名称(相对于数据库集簇的数据目录,即PGDATA)。 @@ -25374,8 +25943,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); regclass - 返回一个给定表空间OID和存储它的文件节点的关系的OID。这本质上是pg_relation_filepath的反向映射。 - 对于数据库默认表空间中的关系,表空间可以指定为0。如果当前数据库中没有与给定值相关联的关系,则返回 NULL。 + 根据关系所在表空间的 OID 和文件结点返回该关系的 OID。这本质上是pg_relation_filepath的反向映射。对于数据库默认表空间中的关系,表空间可以指定为 0。如果当前数据库中没有与给定值关联的关系,或者该关系是临时关系,则返回NULL @@ -25442,13 +26010,13 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); integer - 根据操作系统中找到的所有 locale,将排序规则导入系统目录pg_collation中。 - 这是 initdb 会用到的,更多细节请参考。 - 如果后来在操作系统上安装了额外的区域环境,可以再次运行这个函数加入新区域环境的排序规则。 - 匹配pg_collation中现有条目的区域环境将被跳过(但是这个函数不会移除以在操作系统中不再存在的区域环境为基础的排序规则对象)。 - schema参数通常是pg_catalog,但这并非强制要求,排序规则也可以安装到其他模式中。 - 该函数返回其创建的新排序规则对象的数量。 - 此函数仅限超级用户使用。 + 根据操作系统中找到的所有区域设置,向系统目录pg_collation添加排序规则。 + initdb使用的就是此函数;更多信息见。 + 如果以后在操作系统中安装了其他区域设置,可以再次运行此函数,为新区域设置添加排序规则。 + 与pg_collation中现有条目匹配的区域设置会被跳过。 + (但此函数不会删除基于操作系统中已不存在的区域设置的排序规则对象。) + schema参数通常为pg_catalog,但并非必须如此;也可以将排序规则安装到其他模式中。 + 函数返回新建的排序规则对象数量。此函数仅限超级用户使用。 @@ -25526,7 +26094,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); - 例如,要检查分区表measurement中包含的数据的总大小,可以使用以下查询: + 例如,要检查分区表measurement中包含的数据的总大小,可以使用以下查询: SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size FROM pg_partition_tree('measurement'); @@ -25541,7 +26109,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size 显示了索引维护任务可以使用的函数。 - (注意,这些维护任务通常由自动清理(autovacuum)自动完成;只有在特殊情况下才需要使用这些函数。) + (注意,这些维护任务通常由 autovacuum 自动完成;只有在特殊情况下才需要使用这些函数。) 这些函数在恢复过程中无法执行。这些函数的使用局限于超级用户和给定索引的所有者。 @@ -25572,7 +26140,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size integer - 扫描指定的BRIN索引以查找基表中当前尚未生成索引摘要的页面范围; + 扫描指定的BRIN索引以查找基表中当前尚未生成索引摘要的页面范围; 对于任何这样的范围,它都通过扫描这些表页来创建一个新的摘要索引元组。 返回插入到索引中的新页面范围摘要的数量。 @@ -25588,7 +26156,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size 对覆盖给定块的页面范围执行摘要(如果尚未摘要)。 - 这类似于brin_summarize_new_values,只是它只处理覆盖给定表块数的页范围。 + 这类似于brin_summarize_new_values,区别在于它只处理包含给定表块编号的页面范围。 @@ -25614,9 +26182,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size bigint - 清理指定GIN索引的pending列表,通过移除里面的条目,以大批的方式,到主要的GIN数据结构。 - 返回从挂起列表中删除的页数。如果参数是使用禁用fastupdate选项构建的GIN索引,则不会发生清理,结果为零,因为索引没有挂起的列表。 - 关于挂起列表和fastupdate选项的详细信息,请参见。 + 将指定 GIN 索引的待处理列表中的条目批量移入主 GIN 数据结构,从而清理该列表。返回从待处理列表中移除的页数。如果参数是禁用fastupdate选项构建的 GIN 索引,则不会进行清理,结果为零,因为该索引没有待处理列表。有关待处理列表和fastupdate选项的详细信息,参见 @@ -25631,21 +26197,20 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size 中展示的函数提供了对数据库服务器所在机器上的文件的本地访问。 - 只能访问数据库集簇目录以及log_directory中的文件,除非用户是超级用户或者被授予了角色pg_read_server_files。 + 只能访问数据库集簇目录以及log_directory中的文件,除非用户是超级用户或者被授予了角色pg_read_server_files。 使用相对路径访问集簇目录里面的文件,以及匹配 log_directory配置设置的路径访问日志文件。 - 注意,对于pg_read_file()或相关函数,向用户授予 EXECUTE 权限, - 以允许他们有能力读取服务器上该数据库服务器进程能读取的任何文件;这些函数会绕过所有的数据库内权限检查。 - 这意味着,例如,具有这种访问的用户能够读取pg_authid表中存储着认证信息的内容,也能读取数据库中的任何表数据。 - 因此,授予对这些函数的访问应该要很仔细地考虑。 + 注意,向用户授予pg_read_file()或相关函数的 EXECUTE 权限,会使其能够读取服务器上数据库服务器进程能读取的任何文件;这些函数会绕过数据库内部的所有权限检查。例如,具有这种访问权限的用户能够读取存储认证信息的pg_authid表的内容,以及数据库中的任何表数据。因此,授予这些函数的访问权限时应仔细考虑。 + + + + 授予这些函数的权限时,请注意:表中列出可选参数的条目,大多由多个参数列表不同的实际函数实现。若要使用其中某个函数,就必须单独授予该函数的权限。psql\df命令可以帮助检查实际的函数签名。 - 这些函数中的一些函数有可选的missing_ok参数,可以指定当文件或目录不存在时的行为。 - 如果为true,函数会视情况返回NULL或空结果集。 - 如果为false,会产生一个错误。默认为false。 + 这些函数中的一些函数接受可选的missing_ok参数,用于指定文件或目录不存在时的行为。如果为true,函数会视情况返回NULL或空结果集。如果为false,则会报错。(除文件未找到之外的失败情况,在任何情况下都会报错。)默认为false @@ -25675,12 +26240,12 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size setof text - 返回指定目录中所有文件的名称(也可能包括目录及其他特殊文件)。 + 返回指定目录中所有文件的名称(包括目录及其他特殊文件)。 include_dot_dirs参数指示结果集中是否包含...;默认不包含它们。 在missing_oktrue时,包含它们有助于区分不存在的目录和空目录。 - 默认情况下,此函数仅限超级用户使用,但其他用户可以被授予 EXECUTE 权限来运行它。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -25699,7 +26264,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size 返回服务器日志目录中每个普通文件的名称、大小和最后修改时间(mtime)。以点开头的文件名、目录和其他特殊文件将被排除。 - 默认情况下,此函数仅限于超级用户和具有pg_monitor角色权限的角色,但其他用户可以被授予 EXECUTE 权限来运行该函数。 + 默认情况下,此函数仅限超级用户和具有pg_monitor角色权限的角色使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -25719,8 +26284,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size 以点开头的文件名、目录和其他特殊文件将被排除。 - 默认情况下,此函数仅限于超级用户和具有pg_monitor角色权限的角色, - 但其他用户可以被授予 EXECUTE 权限来运行该函数。 + 默认情况下,此函数仅限超级用户和具有pg_monitor角色权限的角色使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -25740,7 +26304,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size 以点开头的文件名、目录和其他特殊文件将被排除。 - 默认情况下,此函数仅限于超级用户和pg_monitor角色的成员,但其他用户可以被授予 EXECUTE 权限来运行该函数。 + 默认情况下,此函数仅限超级用户和pg_monitor角色的成员使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -25760,7 +26324,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size 以点开头的文件名、目录和其他特殊文件将被排除。 - 默认情况下,此函数仅限于超级用户和pg_monitor角色的成员,但其他用户可以被授予 EXECUTE 权限来运行该函数。 + 默认情况下,此函数仅限超级用户和pg_monitor角色的成员使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -25780,7 +26344,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size 其中slot_name是作为函数输入提供的复制槽的名称。以点开头的文件名、目录和其他特殊文件将被排除。 - 默认情况下,此函数仅限于超级用户和pg_monitor角色的成员,但其他用户可以被授予 EXECUTE 权限来运行该函数。 + 默认情况下,此函数仅限超级用户和pg_monitor角色的成员使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -25800,7 +26364,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size 以点号开头的文件名、目录以及其他特殊文件都不会包含在结果中。 - 默认情况下,此函数仅限超级用户和pg_monitor角色成员使用,但其他用户可以被授予 EXECUTE 权限来运行它。 + 默认情况下,此函数仅限超级用户和pg_monitor角色的成员使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -25822,7 +26386,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size 以点号开头的文件名、目录以及其他特殊文件都不会包含在结果中。 - 默认情况下,此函数仅限超级用户和pg_monitor角色成员使用,但其他用户可以被授予 EXECUTE 权限来运行它。 + 默认情况下,此函数仅限超级用户和pg_monitor角色的成员使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -25831,16 +26395,16 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size pg_read_file - pg_read_file ( filenametext [, offsetbigint, lengthbigint [, missing_okboolean ] ] ) + pg_read_file ( filenametext [, offsetbigint, lengthbigint ] [, missing_okboolean ] ) text 返回一个文本文件的全部或部分,从给定的字节offset开始,最多返回length字节(如果先到达文件末尾,则返回更少)。 如果offset为负,则它相对于文件末尾计算。如果省略offsetlength,则返回整个文件。 - 从文件中读取的字节会按服务器编码解释为字符串;如果它们在该编码下无效,则会抛出错误。 + 从文件中读取的字节会按数据库编码解释为字符串;如果它们在该编码下无效,则会抛出错误。 - 默认情况下,此函数仅限超级用户使用,但其他用户可以被授予 EXECUTE 权限来运行它。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -25849,7 +26413,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size pg_read_binary_file - pg_read_binary_file ( filenametext [, offsetbigint, lengthbigint [, missing_okboolean ] ] ) + pg_read_binary_file ( filenametext [, offsetbigint, lengthbigint ] [, missing_okboolean ] ) bytea @@ -25857,7 +26421,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size 因此不会执行编码检查。 - 默认情况下,此函数仅限超级用户使用,但其他用户可以被授予 EXECUTE 权限来运行它。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 convert_from函数配合使用时,该函数可用于按指定编码读取文本文件,并将其转换为数据库编码: @@ -25885,7 +26449,7 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); 返回一个记录,包含文件大小、最后访问时间戳、最后修改时间戳、最后文件状态变更时间戳(仅限 Unix 平台)、文件创建时间戳(仅限 Windows)以及一个指示其是否为目录的标志。 - 默认情况下,此函数仅限超级用户使用,但其他用户可以被授予 EXECUTE 权限来运行它。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -25905,11 +26469,11 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); - 所有这些函数都打算用于锁定应用程序定义的资源,可以通过一个64位键值或两个32位键值来标识(注意这两个键空间不能重叠)。 - 如果另一个会话已经在相同的资源标识符上持有冲突锁,函数就会等待直到资源变为可用,或者在适用的函数中返回false。 + 这些函数用于锁定应用程序定义的资源;资源可用一个 64 位键值或两个 32 位键值标识(这两个键空间互不重叠)。 + 如果另一个会话已对同一资源标识符持有冲突锁,函数会根据自身的行为等待资源可用,或返回false。 锁可以是共享的或排他的:共享锁不会与同一资源上的其他共享锁冲突,只会与排他锁冲突。 - 锁可以是会话级的(这样它们会一直保持到显式释放或会话结束),也可以是事务级的(这样它们会保持到当前事务结束,且无法手工释放)。 - 多个会话级锁请求堆栈,因此如果同一个资源标识符被锁定三次,那么必须有三个解锁请求来释放资源,在会话结束之前。 + 锁可以在会话级获取(一直保持到释放或会话结束),也可以在事务级获取(一直保持到当前事务结束,不能手动释放)。 + 多次会话级锁请求会累加,因此,如果同一资源标识符被锁定三次,就必须请求解锁三次,才能在会话结束前释放该资源。
@@ -26170,7 +26734,7 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); trigger - 阻止不做事的更新操作。详见下文。 + 抑制不改变数据的更新操作。详见下文。 CREATE TRIGGER ... suppress_redundant_updates_trigger() @@ -26186,8 +26750,7 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); trigger - 自动从相关的纯文本文档列更新tsvector列。 - 要使用的文本搜索配置是以名称指定为触发器参数。详情请参见。 + 根据关联的纯文本文档列自动更新tsvector列。所用的全文检索配置以名称形式指定为触发器参数。详见 CREATE TRIGGER ... tsvector_update_trigger(tsvcol, 'pg_catalog.swedish', title, body) @@ -26203,8 +26766,7 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); trigger - 自动从相关的纯文本文档列更新tsvector列。 - 要使用的文本搜索配置取自表的regconfig列。详情请参见。 + 根据关联的纯文本文档列自动更新tsvector列。所用的全文检索配置取自表的regconfig列。详见 CREATE TRIGGER ... tsvector_update_trigger_column(tsvcol, tsconfigcol, title, body) @@ -26221,23 +26783,15 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); - 理想的情况下,你应该避免运行实际上并没有改变记录中数据的更新。 - 冗余更新会花费大量不必要的时间,尤其是如果有大量索引要改变, 并将最终不得不清理被死亡行占用的空间。 - 但是,在客户端代码中检测这种情况并不总是容易的,甚至不可能做到。 而写表达式来检测它们容易产生错误。 - 作为替代,使用suppress_redundant_updates_trigger可以跳过不改变数据的更新。 但是,你需要小心使用它。 - 触发器需要很短但不能忽略的时间来处理每条记录,所以如果受更新影响的大多数记录确实变化了,此触发器的使用将使更新比平均水平运行得更慢。 + 理想情况下,应避免执行实际上不会改变记录中数据的更新。冗余更新会耗费大量不必要的时间,尤其是在需要修改许多索引时;它们还会使死行占用空间,最终需要通过清理回收。但是,在客户端代码中检测这种情况并不总是容易,甚至可能无法做到,而编写用于检测的表达式也容易出错。另一种办法是使用suppress_redundant_updates_trigger,跳过不改变数据的更新。但使用时应当谨慎。此触发器处理每条记录的耗时虽小,却不可忽略,因此如果更新涉及的大多数记录确实会改变,使用此触发器反而会增加更新的平均耗时。 - suppress_redundant_updates_trigger函数可以像这样添加到表中: - + 该suppress_redundant_updates_trigger函数可以按如下方式添加到表中: CREATE TRIGGER z_min_update BEFORE UPDATE ON tablename FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); - - 在大多数情况下,你需要为每一行最后触发这个触发器,这样它就不会覆盖可能希望更改该行的其他触发器。 - 请记住,触发器是按照名称顺序触发的,你将为此选择一个触发器名称,该名称位于表中可能存在的任何其他触发器的名称之后。 - (因此在示例中使用了z前缀。) +大多数情况下,需要让该触发器对每一行最后触发,以免覆盖其他可能修改该行的触发器的效果。由于触发器按名称顺序触发,应选择一个排序位于表上其他所有触发器名称之后的名称。(这就是示例中使用z前缀的原因。) @@ -26246,7 +26800,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); 事件触发器函数 - PostgreSQL提供了这些助手函数来从事件触发器检索信息。 + PostgreSQL提供了这些辅助函数来从事件触发器检索信息。 @@ -26268,7 +26822,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); 当在一个ddl_command_end事件触发器的函数中调用时,pg_event_trigger_ddl_commands返回被每一个用户动作执行的DDL命令的列表。 如果在其他任何环境中调用这个函数,会发生错误。 - pg_event_trigger_ddl_commands为每一个被执行的基本命令返回一行,某些只有一个单一 SQL 句子的命令可能会返回多于一行。 + pg_event_trigger_ddl_commands为每一个被执行的基本命令返回一行,某些由单条 SQL 语句构成的命令可能会返回多于一行。 这个函数返回下面的列: @@ -26285,7 +26839,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); classid oid - 对象所属的目录的 OID + 对象所属系统目录的 OID objid @@ -26295,7 +26849,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); objsubid integer - 对象的子-id(例如列的属性号) + 子对象 ID(例如列的属性编号) command_tag @@ -26311,16 +26865,14 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); schema_name text - 该对象所属的模式的名称(如果有),如果没有则为NULL。 - 没有引号。 + 对象所属模式的名称(若有);否则为NULL。不加引号。 object_identity text - 对象标识的文本表现形式,用模式限定。如果必要,出现在 - 该标识中的每一个标识符都会被引用。 + 对象标识的文本表示形式,带模式限定。标识中包含的每个标识符在必要时都会加引号。 @@ -26332,8 +26884,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); command pg_ddl_command - 以内部格式表达的该命令的一个完整表现形式。这不能被直接输出, - 但是可以把它传递给其他函数来得到有关于该命令不同部分的信息。 + 命令的完整内部表示,不能直接输出,但可以将其传给其他函数以获取关于该命令的不同信息。 @@ -26355,8 +26906,8 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); - pg_event_trigger_dropped_objects返回被调用sql_drop事件的命令删除的所有对象的列表。 - 如果调用在任何其他上下文中,会引发一个错误。这个函数返回以下列: + 在命令的sql_drop事件中调用pg_event_trigger_dropped_objects时,它返回该命令删除的所有对象的列表。 + 如果调用在任何其他上下文中,会引发一个错误。这个函数返回以下列: @@ -26372,7 +26923,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); classid oid - 对象所属的目录的 OID + 对象原先所属系统目录的 OID objid @@ -26382,7 +26933,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); objsubid integer - 子对象ID(如列的属性号) + 子对象 ID(例如列的属性编号) original @@ -26393,7 +26944,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); normal boolean - 指示在依赖图中有一个普通依赖关系指向该对象的标志 + 如果依赖图中存在指向该对象的普通依赖关系,则为真。 @@ -26412,7 +26963,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); schema_name text - 对象所属模式的名称(如果存在);否则为NULL。不应用引用。 + 对象原先所属模式的名称(若有);否则为NULL。不加引号。 @@ -26433,8 +26984,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); address_names text[] - 一个数组,可与object_typeaddress_args一起, - 通过pg_get_object_address函数在包含同类同名对象的远程服务器上重建该对象地址。 + 一个数组,可与object_typeaddress_args一起,通过pg_get_object_address函数在包含同类同名对象的远程服务器上重建该对象地址。 @@ -26533,7 +27083,7 @@ CREATE EVENT TRIGGER test_event_trigger_for_drops
- 这些函数可以在事件触发器中使用,就像这样: + 这些函数可以在事件触发器中使用,就像这样: CREATE FUNCTION test_event_trigger_table_rewrite_oid() RETURNS event_trigger @@ -26559,12 +27109,12 @@ CREATE EVENT TRIGGER test_table_rewrite_oid 统计信息函数 - function - statistics + 函数 + 统计信息 - PostgreSQL提供了一个函数来检查使用CREATE STATISTICS命令定义的复杂统计。 + PostgreSQL提供了一个函数来检查使用CREATE STATISTICS命令定义的复杂统计信息。 @@ -26580,7 +27130,7 @@ CREATE EVENT TRIGGER test_table_rewrite_oid - pg_mcv_list_items返回一组记录,描述存储在多列MCV列表中的所有项目。它返回以下列: + pg_mcv_list_items返回一组记录,描述存储在多列MCV列表中的所有项目。它返回以下列: @@ -26616,7 +27166,7 @@ CREATE EVENT TRIGGER test_table_rewrite_oid base_frequency double precision - MCV项目的基本频率 + MCV项目的基础频率 @@ -26624,7 +27174,7 @@ CREATE EVENT TRIGGER test_table_rewrite_oid - pg_mcv_list_items函数可以这样使用: + pg_mcv_list_items函数可以这样使用: SELECT m.* FROM pg_statistic_ext join pg_statistic_ext_data on (oid = stxoid), diff --git a/zh/17/generate-targets-meson.pl b/zh/17/generate-targets-meson.pl index d127429c..fbef1dfd 100644 --- a/zh/17/generate-targets-meson.pl +++ b/zh/17/generate-targets-meson.pl @@ -4,10 +4,21 @@ # Copyright (c) 2000-2025, PostgreSQL Global Development Group use strict; +use utf8; +binmode STDOUT, ':encoding(UTF-8)'; use warnings FATAL => 'all'; + +my %titles = ( + 'Code' => '代码构建目标', + 'Developer' => '开发目标', + 'Documentation' => '文档构建目标', + 'Installation' => '安装目标', + 'Other' => '其他目标', +); + my $targets_meson_file = $ARGV[0]; -open my $targets_meson, '<', $targets_meson_file or die; +open my $targets_meson, '<:encoding(UTF-8)', $targets_meson_file or die; print "\n"; @@ -24,7 +35,7 @@ print qq( - $targets Targets + $titles{$targets} ); diff --git a/zh/17/gin.sgml b/zh/17/gin.sgml index 4ef19c51..249e1d37 100644 --- a/zh/17/gin.sgml +++ b/zh/17/gin.sgml @@ -53,7 +53,7 @@ 内置操作符类 - PostgreSQL 核心发布包含 + PostgreSQL 核心发行版包含 所示的 GIN 操作符类。 (在 中描述的一些可选模块还提供额外的 GIN 操作符类。) @@ -152,7 +152,7 @@ 给定一个要建立索引的项,返回一个用 palloc 分配的键数组。返回键的数量必须存入 *nkeys。如果任一键可以为 null,还要另外 palloc 一个包含 *nkeysbool 字段的数组,将其地址存入 - *nullFlags,并按需设置这些空值标志。如果所有键都非空, + *nullFlags,并按需设置这些空值标志。如果所有键都不是 null, *nullFlags 可以保持为 NULL(其初始值)。 如果该项不包含任何键,则返回值可以为 NULL @@ -172,7 +172,7 @@ query 的数据类型,以及应采用何种方法提取键值。返回键的数量必须存入 *nkeys。如果任一键可以为 null,还要另外 palloc 一个包含 *nkeysbool 字段的数组,将其地址存入 - *nullFlags,并按需设置这些空值标志。如果所有键都非空, + *nullFlags,并按需设置这些空值标志。如果所有键都不是 null, *nullFlags 可以保持为 NULL(其初始值)。 如果 query 不包含任何键,则返回值可以为 NULL @@ -185,7 +185,7 @@ 被设置为 GIN_SEARCH_MODE_INCLUDE_EMPTY,则除至少包含一个匹配键的项之外, 完全不含任何键的项也会被视为候选匹配。(例如,该模式对于实现是子集操作符很有用。) 若 *searchMode 被设置为 GIN_SEARCH_MODE_ALL, - 则索引中所有非空项都会被视为候选匹配,无论它们是否匹配任一返回键。 + 则索引中所有非 null 项都会被视为候选匹配,无论它们是否匹配任一返回键。 (该模式比前两种选择慢得多,因为它基本上需要扫描整个索引;但为了正确处理某些边界情况, 可能有此必要。在大多数情况下都需要此模式的操作符,大概并不适合作为 GIN 操作符类的候选。)用于设置该模式的符号定义在 @@ -218,7 +218,7 @@ 操作符类还必须提供一个函数,用于检查被索引项是否匹配查询。它有两种形式:布尔型 consistent 函数,以及三值型 triConsistent 函数。 triConsistent 覆盖了两者的功能,因此仅提供 triConsistent - 就已经足够。不过,如果布尔变体的计算明显更便宜,那么同时提供两者会更有利。 + 就已经足够。不过,如果布尔变体的计算代价明显更低,那么同时提供两者可能更有利。 若只提供布尔变体,则一些依赖于在取回所有键之前先排除索引项的优化将被禁用。 @@ -233,10 +233,10 @@ 该函数无法直接访问被索引项的值,因为 GIN 并不显式存储项。 它所能利用的是这样一种信息:从查询中提取出的哪些键值出现在给定的被索引项中。 check 数组长度为 nkeys,这与先前针对该 - query 数据由 extractQuery 返回的键数量相同。 + query datum 由 extractQuery 返回的键数量相同。 如果被索引项包含相应查询键,则 check 数组中的对应元素为 true; 也就是说,如果 check[i] == true,则 extractQuery - 结果数组中的第 i 个键存在于该被索引项中。传入原始 query 数据值, + 结果数组中的第 i 个键存在于该被索引项中。传入原始 query datum, 是为了让 consistent 方法在需要时可以查看它;同样也会传入先前由 extractQuery 返回的 queryKeys[]nullFlags[] 数组。extra_data 则是 @@ -274,7 +274,7 @@ 而 GIN_MAYBE 表示该键是否存在尚不确定。存在 GIN_MAYBE 值时,只有当无论索引项是否包含对应查询键,该项都确定匹配时,函数才应返回 GIN_TRUE。同样,只有当无论是否包含 GIN_MAYBE 键, - 该项都确定不匹配时,函数才必须返回 GIN_FALSE。如果结果依赖于 + 该项都确定不匹配时,函数才能返回 GIN_FALSE。如果结果依赖于 GIN_MAYBE 条目,也就是说,无法根据已知的查询键确认或否定匹配, 则函数必须返回 GIN_MAYBE。 @@ -306,7 +306,7 @@ 或者,如果操作符类没有提供 compare 方法,GIN 将查找该索引键数据类型的默认 B-树操作符类,并使用其比较函数。建议在仅面向单一数据类型的 - GIN 操作符类中显式指定比较函数,因为查找 B-树操作符类会消耗少量周期。 + GIN 操作符类中显式指定比较函数,因为查找 B-树操作符类会消耗少量处理器周期。 不过,多态 GIN 操作符类(例如 array_ops)通常无法指定单一比较函数。 @@ -374,8 +374,8 @@ 在内部,一个 GIN 索引包含一个基于键构建的 B-树索引,其中每个键都是一个或多个被索引项中的某个元素 - (例如数组成员),而叶子页中的每个元组要么包含一个指向堆指针 B-树的指针(posting tree), - 要么在列表足够小、能够连同键值一起放入单个索引元组时,直接包含一个简单的堆指针列表(posting list)。 + (例如数组成员),而叶子页中的每个元组要么包含一个指向堆指针 B-树的指针(倒排树), + 要么在列表足够小、能够连同键值一起放入单个索引元组时,直接包含一个简单的堆指针列表(倒排列表)。 展示了 GIN 索引的这些组成部分。 @@ -422,7 +422,7 @@ - 如果一致的响应时间比更新速度更重要,可以通过关闭 GIN 索引的 + 如果稳定的响应时间比更新速度更重要,可以通过关闭 GIN 索引的 fastupdate 存储参数来禁用待处理列表机制。详见 @@ -461,7 +461,7 @@ 当为 GIN 启用 fastupdate 时 (详见 ),这种代价会比未启用时小一些。 - 但对于非常大的更新,最好仍然是删除并重建索引。 + 但对于非常大的更新,删除并重建索引仍然可能是最佳选择。 @@ -529,7 +529,7 @@ GIN 假定可索引操作符是严格的。这意味着,当项值为 null 时, 根本不会对其调用 extractValue(而是自动创建一个占位符索引项); 当查询值为 null 时,也不会调用 extractQuery(而是认为该查询不可满足)。 - 不过要注意,非空组合项或查询值内部包含的 null 键值仍然受支持。 + 不过要注意,非 null 的组合项或查询值内部包含的 null 键值仍然受支持。 @@ -537,7 +537,7 @@ 示例 - PostgreSQL 核心发布包含前面在 + PostgreSQL 核心发行版包含前面在 中展示过的 GIN 操作符类。 下列 contrib 模块也包含 GIN 操作符类: diff --git a/zh/17/gist.sgml b/zh/17/gist.sgml index b900bfae..ea363b26 100644 --- a/zh/17/gist.sgml +++ b/zh/17/gist.sgml @@ -4,7 +4,7 @@ GiST 索引 - index + 索引 GiST @@ -211,7 +211,7 @@ CREATE INDEX ON my_table USING GIST (my_inet_column inet_ops); - 这种可扩展性不应与其他标准搜索树在可处理数据方面的可扩展性相混淆。例如,PostgreSQL支持可扩展的 B-树和哈希索引。这意味着你可以用PostgreSQL在任意数据类型上构建 B-树或哈希索引。但 B-树只支持范围谓词(<=>),而哈希索引只支持等值查询。 + 这种可扩展性不应与其他标准搜索树在可处理数据方面的可扩展性相混淆。例如,PostgreSQL支持可扩展的 B-树和 hash 索引。这意味着你可以用PostgreSQL在任意数据类型上构建 B-树或 hash 索引。但 B-树只支持范围谓词(<=>),而 hash 索引只支持等值查询。 @@ -223,6 +223,7 @@ CREATE INDEX ON my_table USING GIST (my_inet_column inet_ops); + 一个GiST索引操作符类必须提供五个方法,另外还有六个可选方法。通过正确实现sameconsistentunion方法可以保证索引的正确性,而索引的效率(大小与速度)则取决于penaltypicksplit方法。两个可选方法是compressdecompress,它们允许索引的内部树数据使用与其所索引数据不同的类型。叶子必须是被索引数据类型,而其他树节点可以是任意 C 结构体(但这里仍必须遵守PostgreSQL的数据类型规则,关于变长数据可参见varlena)。如果树的内部数据类型在 SQL 层存在,可以使用CREATE OPERATOR CLASS命令的STORAGE选项。可选的第八个方法是distance,若操作符类希望支持有序扫描(最近邻搜索),则需要它。可选的第九个方法fetch在操作符类希望支持仅索引扫描时需要,除非省略了compress方法。可选的第十个方法options在操作符类具有用户指定参数时需要。可选的第十一个方法sortsupport用于加速构建GiST索引。 @@ -261,15 +262,14 @@ my_consistent(PG_FUNCTION_ARGS) bool retval; /* - * determine return value as a function of strategy, key and query. + * 根据 strategy、key 和 query 确定返回值。 * - * Use GIST_LEAF(entry) to know where you're called in the index tree, - * which comes handy when supporting the = operator for example (you could - * check for non empty union() in non-leaf nodes and equality in leaf - * nodes). + * 使用 GIST_LEAF(entry) 判断当前调用位于索引树的哪个位置。 + * 例如,支持 = 操作符时这很有用(可以在非叶节点检查 + * union() 是否非空,在叶节点检查是否相等)。 */ - *recheck = true; /* or false if check is exact */ + *recheck = true; /* 如果检查是精确的,则为 false */ PG_RETURN_BOOL(retval); } @@ -385,10 +385,10 @@ my_compress(PG_FUNCTION_ARGS) if (entry->leafkey) { - /* replace entry->key with a compressed version */ + /* 将 entry->key 替换为压缩后的形式 */ compressed_data_type *compressed_data = palloc(sizeof(compressed_data_type)); - /* fill *compressed_data from entry->key ... */ + /* 根据 entry->key 填充 *compressed_data ... */ retval = palloc(sizeof(GISTENTRY)); gistentryinit(*retval, PointerGetDatum(compressed_data), @@ -396,7 +396,7 @@ my_compress(PG_FUNCTION_ARGS) } else { - /* typically we needn't do anything with non-leaf entries */ + /* 通常无需对非叶项做任何处理 */ retval = entry; } @@ -459,7 +459,7 @@ my_decompress(PG_FUNCTION_ARGS) CREATE OR REPLACE FUNCTION my_penalty(internal, internal, internal) RETURNS internal AS 'MODULE_PATHNAME' -LANGUAGE C STRICT; -- in some cases penalty functions need not be strict +LANGUAGE C STRICT; -- 某些情况下 penalty 函数不必是严格函数 而 C 模块中的对应代码则可以遵循如下框架: @@ -481,7 +481,7 @@ my_penalty(PG_FUNCTION_ARGS) } - 出于历史原因,penalty函数并不是直接返回一个float结果;相反,它必须把该值存储到第三个参数指示的位置。返回值本身会被忽略,不过通常会返回该参数的地址。 + 出于历史原因,penalty函数并不是直接返回一个float结果;相反,它必须把该值存储到第三个参数指示的位置。返回值本身会被忽略,不过通常会返回该参数所指向的地址。 @@ -542,7 +542,7 @@ my_picksplit(PG_FUNCTION_ARGS) unionL = NULL; unionR = NULL; - /* Initialize the raw entry vector. */ + /* 初始化原始项向量。 */ raw_entryvec = (GISTENTRY **) malloc(entryvec->n * sizeof(void *)); for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) raw_entryvec[i] = &(entryvec->vector[i]); @@ -555,9 +555,9 @@ my_picksplit(PG_FUNCTION_ARGS) Assert(tmp_union != NULL); /* - * Choose where to put the index entries and update unionL and unionR - * accordingly. Append the entries to either v->spl_left or - * v->spl_right, and care about the counters. + * 选择索引项的存放位置,并相应更新 unionL 和 unionR。 + * 将项追加到 v->spl_left 或 v->spl_right, + * 同时更新计数器。 */ if (my_choice_is_left(unionL, curl, unionR, curr)) @@ -574,7 +574,7 @@ my_picksplit(PG_FUNCTION_ARGS) else { /* - * Same on the right + * 对右侧执行相同操作 */ } } @@ -628,7 +628,7 @@ my_same(PG_FUNCTION_ARGS) } - 出于历史原因,same函数并不是直接返回一个布尔结果;相反,它必须把该标志存储到第三个参数指示的位置。返回值本身会被忽略,不过通常会返回该参数的地址。 + 出于历史原因,same函数并不是直接返回一个布尔结果;相反,它必须把该标志存储到第三个参数指示的位置。返回值本身会被忽略,不过通常会返回该参数所指向的地址。 @@ -667,7 +667,7 @@ my_distance(PG_FUNCTION_ARGS) double retval; /* - * determine return value as a function of strategy, key and query. + * 根据 strategy、key 和 query 确定返回值。 */ PG_RETURN_FLOAT8(retval); @@ -678,11 +678,11 @@ my_distance(PG_FUNCTION_ARGS) - 在确定距离时允许有一定近似,只要结果永不大于该项的实际距离即可。因此,例如在几何应用中,到外包盒的距离通常就足够了。对于内部树节点,返回的距离不能大于其任一子节点的距离。如果返回的距离不精确,函数必须将*recheck设为 true。(对内部树节点则不必这样做;对它们总是假定计算结果不精确。)在这种情况下,执行器会在从堆中取出元组后计算准确距离,并在必要时重新排序这些元组。 + 在确定距离时允许有一定近似,只要结果永不大于该项的实际距离即可。因此,例如在几何应用中,到包围盒的距离通常就足够了。对于内部树节点,返回的距离不能大于其任一子节点的距离。如果返回的距离不精确,函数必须将*recheck设为 true。(对内部树节点则不必这样做;对它们总是假定计算结果不精确。)在这种情况下,执行器会在从堆中取出元组后计算准确距离,并在必要时重新排序这些元组。 - 如果距离函数对任何叶节点都返回*recheck = true,原始排序操作符的返回类型必须是float8float4,且距离函数的结果值必须能与原始排序操作符的结果进行比较,因为执行器会同时使用距离函数结果和重新计算得到的排序操作符结果进行排序。否则,距离函数的结果值可以是任意有限的float8值,只要这些结果值的相对顺序与排序操作符返回的顺序一致即可。(无穷大和负无穷在内部用于处理空值等情况,因此不建议distance函数返回这些值。) + 如果距离函数对任意一个叶节点返回*recheck = true,原始排序操作符的返回类型必须是float8float4,且距离函数的结果值必须能与原始排序操作符的结果进行比较,因为执行器会同时使用距离函数结果和重新计算得到的排序操作符结果进行排序。否则,距离函数的结果值可以是任意有限的float8值,只要这些结果值的相对顺序与排序操作符返回的顺序一致即可。(无穷大和负无穷在内部用于处理空值等情况,因此不建议distance函数返回这些值。) @@ -726,10 +726,10 @@ my_fetch(PG_FUNCTION_ARGS) fetched_data = palloc(sizeof(fetched_data_type)); /* - * Convert 'fetched_data' into the a Datum of the original datatype. + * 将 'fetched_data' 转换为原始数据类型的 Datum。 */ - /* fill *retval from fetched_data. */ + /* 根据 fetched_data 填充 *retval。 */ gistentryinit(*retval, PointerGetDatum(converted_datum), entry->rel, entry->page, entry->offset, FALSE); @@ -780,26 +780,26 @@ typedef enum MyEnumType typedef struct { - int32 vl_len_; /* varlena header (do not touch directly!) */ - int int_param; /* integer parameter */ - double real_param; /* real parameter */ - MyEnumType enum_param; /* enum parameter */ - int str_param; /* string parameter */ + int32 vl_len_; /* varlena 首部(不要直接操作!) */ + int int_param; /* 整数参数 */ + double real_param; /* 实数参数 */ + MyEnumType enum_param; /* 枚举参数 */ + int str_param; /* 字符串参数 */ } MyOptionsStruct; -/* String representation of enum values */ +/* 枚举值的字符串表示 */ static relopt_enum_elt_def myEnumValues[] = { {"on", MY_ENUM_ON}, {"off", MY_ENUM_OFF}, {"auto", MY_ENUM_AUTO}, - {(const char *) NULL} /* list terminator */ + {(const char *) NULL} /* 列表终止项 */ }; static char *str_param_default = "default"; /* - * Sample validator: checks that string is not longer than 8 bytes. + * 验证器示例:检查字符串长度不超过 8 字节。 */ static void validate_my_string_relopt(const char *value) @@ -811,7 +811,7 @@ validate_my_string_relopt(const char *value) } /* - * Sample filler: switches characters to lower case. + * 填充函数示例:将字符转换为小写。 */ static Size fill_my_string_relopt(const char *value, void *ptr) @@ -864,10 +864,9 @@ my_compress(PG_FUNCTION_ARGS) char *str_param = str_param_default; /* - * Normally, when opclass contains 'options' method, then options are always - * passed to support functions. However, if you add 'options' method to - * existing opclass, previously defined indexes have no options, so the - * check is required. + * 通常,操作符类包含 'options' 方法时,总会把选项传给支持函数。 + * 但是,如果把 'options' 方法添加到已有操作符类中, + * 先前定义的索引没有选项,因此需要进行检查。 */ if (PG_HAS_OPCLASS_OPTIONS()) { @@ -879,7 +878,7 @@ my_compress(PG_FUNCTION_ARGS) str_param = GET_STRING_RELOPTION(options, str_param); } - /* the rest implementation of support function */ + /* 支持函数的其余实现 */ } @@ -923,7 +922,7 @@ PG_FUNCTION_INFO_V1(my_sortsupport); static int my_fastcmp(Datum x, Datum y, SortSupport ssup) { - /* establish order between x and y by computing some sorting value z */ + /* 通过计算某个排序值 z 来确定 x 和 y 的顺序 */ int z1 = ComputeSpatialCode(x); int z2 = ComputeSpatialCode(y); @@ -958,7 +957,7 @@ my_sortsupport(PG_FUNCTION_ARGS) GiST 索引构建方法 - 构建 GiST 索引最简单的方法就是把所有项逐个插入。这对于大型索引往往很慢,因为如果索引元组分散在整个索引中,而索引又大到无法放入缓存,就需要大量随机 I/O。PostgreSQL支持两种用于 GiST 索引初始构建的替代方法:sortedbuffered模式。 + 构建 GiST 索引最简单的方法就是把所有项逐个插入。这对于大型索引往往很慢,因为如果索引元组分散在整个索引中,而索引又大到无法放入缓存,就需要大量随机 I/O。PostgreSQL支持两种用于 GiST 索引初始构建的替代方法:排序缓冲模式。 @@ -1004,7 +1003,7 @@ my_sortsupport(PG_FUNCTION_ARGS) hstore - 用于存储 (key, value) 对的模块 + 用于存储(键,值)对的模块 diff --git a/zh/17/glossary.sgml b/zh/17/glossary.sgml index 1f3a9f5b..769b672e 100644 --- a/zh/17/glossary.sgml +++ b/zh/17/glossary.sgml @@ -359,7 +359,7 @@ 客户端(进程) - 任何进程,可能是远程的,通过连接到某个 + 任何进程,可能是远程的,通过连接到某个 实例来建立 会话, 以与一个数据库交互。 @@ -807,7 +807,7 @@ 一台通过网络与其他计算机通信的计算机。这个术语有时被用作 服务器的同义词。 - 它也用来指客户端进程运行所在的计算机。 + 它也用来指客户端进程运行所在的计算机。 @@ -878,7 +878,7 @@ 实例处理 DBMS 的所有关键特性: 对文件和共享内存的读写访问、保证 ACID 属性、 - 与客户端进程的连接、 + 与客户端进程连接、 权限验证、崩溃恢复、复制等。 @@ -1119,7 +1119,7 @@ - 当它用于指代查询中的 + 当它用于指代查询中的 窗口函数时, 分区是一种用户定义的准则,用来标识 查询结果集中哪些相邻的 diff --git a/zh/17/hash.sgml b/zh/17/hash.sgml index 49f4fdf6..0a5f55de 100644 --- a/zh/17/hash.sgml +++ b/zh/17/hash.sgml @@ -1,11 +1,11 @@ -哈希索引 +Hash 索引 索引 - 哈希 + Hash @@ -13,51 +13,51 @@ PostgreSQL - 提供了持久化的磁盘哈希索引实现,并且完全支持崩溃恢复。任何数据类型都可以使用哈希索引,包括那些没有明确定义线性顺序的数据类型。哈希索引只存储被索引数据的哈希值,因此对被索引数据列的大小没有限制。 + 提供了持久化的磁盘 hash 索引实现,并且完全支持崩溃恢复。任何数据类型都可以使用 hash 索引,包括那些没有明确定义线性顺序的数据类型。Hash 索引只存储被索引数据的 hash 值,因此对被索引数据列的大小没有限制。 - 哈希索引仅支持单列索引,也不支持唯一性检查。 + Hash 索引仅支持单列索引,也不支持唯一性检查。 - 哈希索引仅支持=操作符,因此指定范围操作的 WHERE 子句无法利用哈希索引。 + Hash 索引仅支持=操作符,因此指定范围操作的 WHERE 子句无法利用 hash 索引。 - 每个哈希索引元组只存储 4 字节的哈希值,而不存储实际的列值。因此,在为 UUID、URL 等较长的数据项建立索引时,哈希索引可能比 B-树小得多。由于没有列值,所有哈希索引扫描也都是有损的。哈希索引可以参与位图索引扫描和反向扫描。 + 每个 hash 索引元组只存储 4 字节的 hash 值,而不存储实际的列值。因此,在为 UUID、URL 等较长的数据项建立索引时,hash 索引可能比 B-树小得多。由于没有列值,所有 hash 索引扫描也都是有损的。Hash 索引可以参与位图索引扫描和反向扫描。 - 哈希索引最适合于在较大表上执行等值扫描、且以 SELECT 和 UPDATE 为主的工作负载。在 B-树索引中,搜索必须沿树向下直到找到叶页。在拥有数百万行的表中,这种向下遍历会增加访问数据的时间。在哈希索引中,与叶页对应的页称为桶页。相比之下,哈希索引允许直接访问桶页,因此可能减少大表中的索引访问时间。这种“逻辑 I/O”的减少,在索引/数据大于 shared_buffers/RAM 时会更加明显。 + Hash 索引最适合于在较大表上执行等值扫描、且以 SELECT 和 UPDATE 为主的工作负载。在 B-树索引中,搜索必须沿树向下直到找到叶页。在拥有数百万行的表中,这种向下遍历会增加访问数据的时间。在 hash 索引中,与叶页对应的页称为桶页。相比之下,hash 索引允许直接访问桶页,因此可能减少大表中的索引访问时间。这种“逻辑 I/O”的减少,在索引/数据大于 shared_buffers/RAM 时会更加明显。 - 哈希索引在设计上能够应对哈希值分布不均的情况。如果哈希值分布均匀,那么直接访问桶页的效果很好。当插入导致桶页填满时,额外的溢出页就会链接到该特定桶页上,从而在局部扩展用于存放匹配该哈希值的索引元组的空间。查询期间扫描某个哈希桶时,需要遍历其全部溢出页。因此,对于某些数据,不平衡的哈希索引在所需块访问次数方面实际上可能比 B-树更差。 + Hash 索引在设计上能够应对 hash 值分布不均的情况。如果 hash 值分布均匀,那么直接访问桶页的效果很好。当插入导致桶页填满时,额外的溢出页就会链接到该特定桶页上,从而在局部扩展用于存放匹配该 hash 值的索引元组的空间。查询期间扫描某个 hash 桶时,需要遍历其全部溢出页。因此,对于某些数据,不平衡的 hash 索引在所需块访问次数方面实际上可能比 B-树更差。 - 由于会出现这些溢出情况,可以说哈希索引最适合用于唯一值、近乎唯一值,或者每个哈希桶中行数较少的数据。 + 由于会出现这些溢出情况,可以说 hash 索引最适合用于唯一值、近乎唯一值,或者每个 hash 桶中行数较少的数据。 避免问题的一种可能办法,是使用部分索引条件把高度非唯一的值排除在索引之外,但这在很多情况下可能并不适用。 - 与 B-树一样,哈希索引也会执行简单的索引元组删除。这是一种延迟维护操作,用于删除那些已知可以安全删除的索引元组(即其项标识符的 LP_DEAD 位已经被设置的那些元组)。如果插入操作发现页上没有可用空间,我们会尝试通过移除死索引元组来避免创建新的溢出页。如果该页当时已被钉住,就无法执行移除。死索引指针也会在 VACUUM 期间被删除。 + 与 B-树一样,hash 索引也会执行简单的索引元组删除。这是一种延迟维护操作,用于删除那些已知可以安全删除的索引元组(即其项标识符的 LP_DEAD 位已经被设置的那些元组)。如果插入操作发现页上没有可用空间,我们会尝试通过移除死索引元组来避免创建新的溢出页。如果该页当时已被钉住,就无法执行移除。死索引指针也会在 VACUUM 期间被删除。 - 如果可能,VACUUM 还会尝试将索引元组压缩到尽可能少的溢出页上,以最小化溢出链。 + 如果可能,VACUUM 还会尝试将索引元组集中存放在尽可能少的溢出页上,以最小化溢出链。 如果某个溢出页变为空页,该溢出页就可以被回收并在其他桶中重用,不过我们从不将它们返还给操作系统。 - 目前除了使用 REINDEX 重建哈希索引之外,还没有缩小哈希索引的方法。 + 目前除了使用 REINDEX 重建 hash 索引之外,还没有缩小 hash 索引的方法。 同样也没有减少桶数量的方法。 - 随着被索引行数的增长,哈希索引可能会扩展桶页数量。哈希键到桶号的映射经过选择,使得索引能够增量扩展。当需要向索引中添加一个新桶时,恰好只需要“拆分”一个现有桶,并根据更新后的键到桶号映射,将其中一部分元组转移到新桶。 + 随着被索引行数的增长,Hash 索引可能会扩展桶页数量。hash 键到桶号的映射经过选择,使得索引能够增量扩展。当需要向索引中添加一个新桶时,恰好只需要“拆分”一个现有桶,并根据更新后的键到桶号映射,将其中一部分元组转移到新桶。 - 这种扩展是在前台进行的,因此可能会增加用户插入操作的执行时间。因此,哈希索引可能不适合行数快速增长的表。 + 这种扩展是在前台进行的,因此可能会增加用户插入操作的执行时间。因此,hash 索引可能不适合行数快速增长的表。 @@ -66,7 +66,7 @@ 实现 - 哈希索引中有四种页:元页(第零页),其中包含静态分配的控制信息;主桶页;溢出页;以及位图页,后者用于跟踪已被释放且可供重用的溢出页。在寻址时,位图页被视为溢出页的一个子集。 + hash 索引中有四种页:元页(第零页),其中包含静态分配的控制信息;主桶页;溢出页;以及位图页,后者用于跟踪已被释放且可供重用的溢出页。在寻址时,位图页被视为溢出页的一个子集。 @@ -74,15 +74,15 @@ - 主桶页和溢出页是独立分配的,因为任何一个给定索引相对于其桶数,可能需要更多或更少的溢出页。哈希代码使用了一组颇有意思的寻址规则,以支持可变数量的溢出页,同时又不必在主桶页创建后再移动它们。 + 主桶页和溢出页是独立分配的,因为任何一个给定索引相对于其桶数,可能需要更多或更少的溢出页。hash 实现代码使用了一组颇有意思的寻址规则,以支持可变数量的溢出页,同时又不必在主桶页创建后再移动它们。 - 被索引表中的每一行,都由哈希索引中的单个索引元组表示。哈希索引元组存储在桶页中,如果存在溢出页,也会存储在溢出页中。为了加快搜索速度,我们将任一索引页中的索引项按哈希码排序,从而可以在索引页内使用二分查找。但请注意,并不假定同一桶中不同索引页之间的哈希码具有任何相对顺序。 + 被索引表中的每一行,都由 hash 索引中的单个索引元组表示。Hash 索引元组存储在桶页中,如果存在溢出页,也会存储在溢出页中。为了加快搜索速度,我们将任一索引页中的索引项按 hash 码排序,从而可以在索引页内使用二分查找。但请注意,并不假定同一桶中不同索引页之间的 hash 码具有任何相对顺序。 - 用于扩展哈希索引的桶拆分算法过于复杂,这里不再展开说明;但在src/backend/access/hash/README中有更详细的描述。该拆分算法具备崩溃安全性,如果未能成功完成,可以重新启动。 + 用于扩展 hash 索引的桶拆分算法过于复杂,这里不再展开说明;但在src/backend/access/hash/README中有更详细的描述。该拆分算法具备崩溃安全性,如果未能成功完成,可以重新启动。 diff --git a/zh/17/high-availability.sgml b/zh/17/high-availability.sgml index c4f931b6..3ac9b6fa 100644 --- a/zh/17/high-availability.sgml +++ b/zh/17/high-availability.sgml @@ -19,7 +19,7 @@ - 某些方案通过只允许一台服务器修改数据来处理同步。能够修改数据的服务器称为读/写、主库(master)主库(primary)服务器。跟踪主库变更的服务器称为备库。只能在被提升为主库之后才能连接的备库称为温备,而能够接受连接并提供只读查询的备库称为热备。 + 某些方案通过只允许一台服务器修改数据来处理同步。能够修改数据的服务器称为读/写、主库(master)主库(primary)服务器。跟踪主库变更的服务器称为备库(standby)备库(secondary)。只能在被提升为主库之后才能连接的备库称为温备,而能够接受连接并提供只读查询的备库称为热备 @@ -102,7 +102,7 @@ protocol to make nodes agree on a serializable transactional order. - 基于触发器的主库-备库复制 + 基于触发器的主备复制 @@ -238,7 +238,7 @@ protocol to make nodes agree on a serializable transactional order. - 主库无额外负载 + 主库无额外开销 @@ -354,7 +354,7 @@ protocol to make nodes agree on a serializable transactional order. - 连续归档可用于创建一种高可用性(HA)集簇配置,其中有一个或多个备库随时准备在主库失效时接管操作。这种能力通常称为温备日志传送。 + 持续归档可用于创建一种高可用性(HA)集簇配置,其中有一个或多个备库随时准备在主库失效时接管操作。这种能力通常称为温备日志传送 @@ -528,7 +528,7 @@ archive_cleanup_command = 'pg_archivecleanup /path/to/archive %r' 认证 - 正确设置复制访问权限非常重要,因为从 WAL 流中很容易提取出需要权限才能访问的信息,因此必须确保只有受信任的用户才能读取它。备库必须以具有 REPLICATION 权限的账户或超级用户身份向主库认证。建议专门创建一个具有 REPLICATIONLOGIN 权限的用户账户用于复制。虽然 REPLICATION 权限的权限很高,但它并不允许用户修改主系统上的任何数据,而 SUPERUSER 权限则允许。 + 正确设置复制访问权限非常重要,因为从 WAL 流中很容易提取出需要权限才能访问的信息,因此必须确保只有受信任的用户才能读取它。备库必须以具有 REPLICATION 权限的账户或超级用户身份向主库认证。建议专门创建一个具有 REPLICATIONLOGIN 权限的用户账户用于复制。虽然 REPLICATION 权限很高,但它并不允许用户修改主系统上的任何数据,而 SUPERUSER 权限则允许。 @@ -559,7 +559,7 @@ primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass' 流复制的一个重要健康指标,是主库上已经生成但尚未在备库上应用的 WAL 记录量。你可以通过比较主库上的当前 WAL 写入位置和备库收到的最后一个 WAL 位置来计算这种滞后。这些位置分别可以用主库上的 pg_current_wal_lsn 和备库上的 pg_last_wal_receive_lsn 取得(详见 )。备库上的最后一个 WAL 接收位置也会显示在 WAL 接收进程的进程状态中,即通过 ps 命令显示的状态(详见 )。 - 你可以通过 pg_stat_replication 视图取得 WAL 发送进程列表。pg_current_wal_lsn 与该视图的 sent_lsn 字段之间存在较大差异,可能表示主库负载很重;而 sent_lsn 与备库上的 pg_last_wal_receive_lsn 之间存在较大差异,则可能表示网络延迟,或者备库负载很重。 + 你可以通过 pg_stat_replication 视图取得 WAL 发送进程列表。pg_current_wal_lsn 与该视图的 sent_lsn 字段之间存在较大差异,可能表示主库负载很重;而 sent_lsn 与备库上的 pg_last_wal_receive_lsn 之间存在差异,则可能表示网络延迟,或者备库负载很重。 在热备上,WAL 接收进程的状态可以通过 @@ -575,13 +575,13 @@ primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass' 流复制 - 复制槽提供了一种自动化方法,以确保主库在所有备库都收到 WAL 段之前不会删除它们,并且即使备库处于断开状态,主库也不会删除可能导致恢复冲突的行。 + 复制槽提供了一种自动化方法,以确保主库在所有备库都收到 WAL 段之前不会删除它们,并且即使备库处于断开状态,主库也不会删除那些一旦删除就可能导致恢复冲突的行。 如果不使用复制槽,也可以通过阻止旧的 WAL 段被移除,或者通过把这些段保存到归档中。这些方法的一个缺点是,它们通常会保留多于实际所需数量的 WAL 段,而复制槽只会保留已知确实需要的段数。 - 类似地,如果不配合复制槽单独使用 ,它虽然能防止相关的行被清理而避免因清理产生的问题,但在备库未连接的那段时间内并不能提供保护。 + 类似地,如果不配合复制槽单独使用 ,它虽然能防止相关的行被清理移除,但在备库未连接的那段时间内并不能提供保护。 @@ -685,7 +685,7 @@ primary_slot_name = 'node_a_slot' - 只读事务和事务回滚不需要等待备库的回应。子事务提交也不需要等待备库响应,只有顶层提交才需要等待。数据装载或索引构建等长时间运行的动作,不会一直等到最终提交消息。所有两阶段提交操作都需要等待提交,包括 prepare 和 commit。 + 只读事务和事务回滚不需要等待备库的回应。子事务提交也不需要等待备库响应,只有顶层提交才需要等待。数据装载或索引构建等长时间运行的动作,直到最终提交时才会等待。所有两阶段提交操作都需要等待提交,包括准备和提交两个阶段。 @@ -700,7 +700,7 @@ primary_slot_name = 'node_a_slot' - 当提交记录已经在主库上写入磁盘之后,WAL 记录就会被发送到备库。每当新的一批 WAL 数据被写入磁盘时,备库就会发送回复消息,除非备库上的wal_receiver_status_interval被设置为零。如果synchronous_commit被设置为remote_apply,那么备库会在提交记录被重放时发送回复消息,从而使该事务变得可见。如果根据主库上的synchronous_standby_names设置,该备库被选为同步备库,那么它发出的回复会与其他同步备库的回复一起,用于决定何时释放那些正在等待确认提交记录已被收到的事务。这些参数允许管理员指定哪些备库应作为同步备库。注意,同步复制的配置主要在主库上进行。被命名的备库必须直接连接到主库;主库并不知道使用级联复制的下游备库。 + 当提交记录已经在主库上写入磁盘之后,WAL 记录就会被发送到备库。每当新的一批 WAL 数据被写入磁盘时,备库就会发送回复消息,除非备库上的wal_receiver_status_interval被设置为零。如果synchronous_commit被设置为remote_apply,那么备库会在提交记录被重放、该事务变得可见时发送回复消息。如果根据主库上的synchronous_standby_names设置,该备库被选为同步备库,那么它发出的回复会与其他同步备库的回复一起,用于决定何时释放那些正在等待确认提交记录已被收到的事务。这些参数允许管理员指定哪些备库应作为同步备库。注意,同步复制的配置主要在主库上进行。被命名的备库必须直接连接到主库;主库并不知道使用级联复制的下游备库。 @@ -712,7 +712,7 @@ primary_slot_name = 'node_a_slot' - 如果请求快速关闭,用户将停止等待。不过,与使用异步复制时一样,在所有尚未解决的 WAL 记录传输到当前已连接的备库之前,服务器不会完全关闭。 + 如果请求快速关闭,用户将停止等待。不过,与使用异步复制时一样,在所有尚未传送的 WAL 记录传输到当前已连接的备库之前,服务器不会完全关闭。 @@ -734,14 +734,14 @@ synchronous_standby_names = 'FIRST 2 (s1, s2, s3)' 在这个例子中,如果四台备库s1s2s3s4都在运行,则s1s2会被选为同步备库,因为它们的名字在备库名称列表中出现得更早。s3是潜在的同步备库,当s1s2中的任意一台失效时,它就会接替其角色。由于s4的名称不在列表中,因此它是异步备库。 - ANY方法指定基于法定人数的同步复制,使事务提交等待,直到它们的 WAL 记录被复制到列表中所要求数量的同步备库中的至少这么多台。 + ANY方法指定基于法定人数的同步复制,使事务提交等待,直到它们的 WAL 记录被复制到列表中至少所要求数量的同步备库。 基于法定人数的多同步备库的synchronous_standby_names示例如下: synchronous_standby_names = 'ANY 2 (s1, s2, s3)' - 在这个例子中,如果四台备库s1s2s3s4都在运行,事务提交将等待来自s1s2s3中的任意两台备库的回复。由于s4的名字不在列表中,因此它是异步备库。 + 在这个例子中,如果四台备库s1s2s3s4都在运行,事务提交将等待来自s1s2s3中的至少任意两台备库的回复。由于s4的名字不在列表中,因此它是异步备库。 备库的同步状态可以通过pg_stat_replication视图查看。 @@ -764,7 +764,7 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' - 通过在应用级别(在主库上)指定同步复制选项,我们可以只对最重要的变更提供同步复制,而不会拖慢整体工作负载。应用级别选项是让高性能应用获得同步复制收益的一种重要而实用的工具。 + 通过在应用级别(在主库上)指定同步复制选项,我们可以只对最重要的变更提供同步复制,而不会拖慢大部分工作负载。应用级别选项是让高性能应用获得同步复制收益的一种重要而实用的工具。 @@ -797,7 +797,7 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' - 如果主库在提交正等待确认时重启,这些等待中的事务会在主库恢复后被标记为已完全提交。无法确定在主库崩溃时,所有备库是否已经收到全部尚未处理的 WAL 数据。因此,某些事务可能不会在备库上显示为已提交,即使它们在主库上显示为已提交。我们所提供的保证是:只有在确认 WAL 数据已经被所有同步备库安全接收之后,应用才会收到事务成功提交的显式确认。 + 如果主库在提交正等待确认时重启,这些等待中的事务会在主库恢复后被标记为已完全提交。无法确定在主库崩溃时,所有备库是否已经收到全部待传送的 WAL 数据。因此,某些事务可能不会在备库上显示为已提交,即使它们在主库上显示为已提交。我们所提供的保证是:只有在确认 WAL 数据已经被所有同步备库安全接收之后,应用才会收到事务成功提交的显式确认。 @@ -857,7 +857,7 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' - 一旦故障切换到备库,系统中就只剩下一台服务器在运行。这被称为退化状态。原来的备库现在成为主库,而原来的主库已经停机,并且可能持续停机。要恢复到正常运行状态,就必须重新创建一台备库:要么在原主库恢复后在其上重建,要么在第三台可能是全新的服务器上重建。在大型集簇上,可以使用工具来加快这一过程。一旦完成,就可以认为主库和备库已经交换了角色。有些人会选择使用第三台服务器,在新的备库重建完成之前为新的主库提供备份,但显然这会让系统配置和操作流程更加复杂。 + 一旦故障切换到备库,系统中就只剩下一台服务器在运行。这被称为退化状态。原来的备库现在成为主库,而原来的主库已经停机,并且可能持续停机。要恢复到正常运行状态,就必须重新创建一台备库:要么在原主库恢复后在其上重建,要么在第三台可能是全新的服务器上重建。在大型集簇上,可以使用工具来加快这一过程。一旦完成,就可以认为主库和备库已经交换了角色。有些人会选择使用第三台服务器,在新的备库重建完成之前为新的主库提供后备支持,但显然这会让系统配置和操作流程更加复杂。 @@ -920,7 +920,7 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' - 事务管理命令: + 事务管理命令: @@ -934,7 +934,7 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' - EXCEPTION块或其他内部子事务 + EXCEPTION块和其他内部子事务 @@ -974,7 +974,7 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' 数据操纵语言(DML):INSERTUPDATEDELETEMERGECOPY FROM、 - TRUNCATE。请注意,恢复期间不存在任何允许执行触发器的动作。这个限制甚至适用于临时表,因为不分配事务 ID 就无法读取或写入表行,而这在热备环境中目前是不可能的。 + TRUNCATE。请注意,恢复期间不存在任何允许执行触发器的动作。这个限制甚至适用于临时表,因为不分配事务 ID 就无法读取或写入表行,而目前热备环境中无法分配事务 ID。 @@ -1009,13 +1009,13 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' - BEGIN READ WRITE, + BEGIN READ WRITESTART TRANSACTION READ WRITE - SET TRANSACTION READ WRITE, + SET TRANSACTION READ WRITESET SESSION CHARACTERISTICS AS TRANSACTION READ WRITE @@ -1031,7 +1031,7 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' 两阶段提交命令:PREPARE TRANSACTIONCOMMIT PREPAREDROLLBACK PREPARED, - 因为即使是只读事务,在 prepare 阶段(两阶段提交的第一阶段)也需要写入 WAL。 + 因为即使是只读事务,在准备阶段(两阶段提交的第一阶段)也需要写入 WAL。 @@ -1117,24 +1117,22 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' - 一旦max_standby_archive_delaymax_standby_streaming_delay指定的延迟被超越,冲突查询将被取消。这通常仅导致一个取消错误,尽管在重放一个DROP DATABASE的情况下整个冲突会话都将被中断。另外,如果冲突发生在一个被空闲事务持有的锁上,该冲突会话会被中断(这种行为可能在未来被改变)。 + 一旦max_standby_archive_delaymax_standby_streaming_delay指定的延迟被超越,冲突查询将被取消。这通常仅导致一个取消错误,尽管在重放一个DROP DATABASE的情况下整个冲突会话都将被终止。另外,如果冲突发生在一个被空闲事务持有的锁上,该冲突会话会被终止(这种行为可能在未来被改变)。 - - 被取消的查询可能会立即被重试(当然是在开始一个新的事务后)。因为查询取消依赖于 WAL 记录被重放的本质,如果一个被取消的查询被再次执行,它可能会很好地成功完成。 - + 被取消的查询可以立即重试(当然,要先开始一个新事务)。由于查询取消取决于正在重放的 WAL 记录的性质,被取消的查询再次执行时完全可能成功。 - 记住延迟参数是从 WAL 数据被备库收到后流逝的时间。因此,留给备库上任何一个查询的宽限期从不会超过延迟参数,并且如果备库已经由于等待之前的查询完成而落后或者因为过重的更新负载而无法跟上主库,宽限期可能会更少。 + 请记住,延迟参数要与备库收到 WAL 数据之后经过的时间进行比较。因此,留给备库上任何一个查询的宽限期从不会超过延迟参数,并且如果备库已经由于等待之前的查询完成而落后或者因为过重的更新负载而无法跟上主库,宽限期可能会更少。 - 备库查询与 WAL 重放发生冲突的最常见原因是过早清理。正常情况下,当没有事务需要看到旧行版本时,PostgreSQL允许清理这些旧行版本,以保证按照 MVCC 规则得到正确的数据可见性。不过,这条规则只能应用于在主库上执行的事务。因此,主库上的清理有可能移除某个备库事务仍然可见的行版本。 + 备库查询与 WAL 重放发生冲突的最常见原因是过早清理。正常情况下,当不再有事务需要看到旧行版本来保证符合 MVCC 规则的数据可见性时,PostgreSQL允许清理这些旧行版本。不过,这条规则只能应用于在主库上执行的事务。因此,主库上的清理有可能移除某个备库事务仍然可见的行版本。 行版本清理并不是与备库查询发生冲突的唯一潜在原因。所有仅索引扫描(包括在备库上运行的那些)都必须使用一个MVCC快照,它与可见性映射一致。因此,每当VACUUM在可见性映射中把某个页面标记为全可见,而该页面中包含一行或多行对所有备库查询都不可见的数据时,就必须产生冲突。所以,即使针对一个没有更新或删除任何需要清理行的表执行VACUUM,也可能导致冲突。 + linkend="vacuum-for-visibility-map">在可见性映射中把某个页面标记为全可见,而该页面中包含并非对所有备库查询都可见的一行或多行数据时,就必须产生冲突。所以,即使针对一个没有需要清理的已更新或已删除行的表执行VACUUM,也可能导致冲突。 @@ -1237,7 +1235,7 @@ HINT: You can then restart the server after making the necessary configuration - 主库上写出的事务状态 "hint bits" 不会被 WAL 记录,因此备库上的数据很可能会再次写出这些提示位。这样一来,即使所有用户都是只读的,备库仍然会执行磁盘写操作;不过数据值本身并不会发生变化。用户仍然会写出大型排序临时文件,并重新生成 relcache 信息文件,因此在热备模式下,数据库没有任何部分是真正只读的。还要注意,使用dblink模块写入远程数据库,以及借助 PL 函数执行其他数据库外部操作,依然是可能的,即使该事务在本地是只读的。 + 主库上写出的事务状态“提示位” 不会被 WAL 记录,因此备库上的数据很可能会再次写出这些提示位。这样一来,即使所有用户都是只读的,备库仍然会执行磁盘写操作;不过数据值本身并不会发生变化。用户仍然会写出大型排序临时文件,并重新生成 relcache 信息文件,因此在热备模式下,数据库没有任何部分是真正只读的。还要注意,使用dblink模块写入远程数据库,以及借助 PL 函数执行其他数据库外部操作,依然是可能的,即使该事务在本地是只读的。 @@ -1246,7 +1244,7 @@ HINT: You can then restart the server after making the necessary configuration - 数据定义语言:例如 CREATE INDEX + 数据定义语言(DDL):例如 CREATE INDEX diff --git a/zh/17/images/fixup-svg.xsl b/zh/17/images/fixup-svg.xsl index d6c46b36..cf7169bb 100644 --- a/zh/17/images/fixup-svg.xsl +++ b/zh/17/images/fixup-svg.xsl @@ -32,6 +32,11 @@ Fix stroke="transparent" attribute, which is invalid SVG. none + + + 'Alibaba PuHuiTi 3.0',serif + + diff --git a/zh/17/images/gin.gv b/zh/17/images/gin.gv index 097e9102..b8e26542 100644 --- a/zh/17/images/gin.gv +++ b/zh/17/images/gin.gv @@ -1,11 +1,12 @@ digraph "gin" { layout=dot; - node [label="", shape=box, style=filled, fillcolor=gray, width=1.4]; + fontname="Alibaba PuHuiTi 3.0"; + node [fontname="Alibaba PuHuiTi 3.0", label="", shape=box, style=filled, fillcolor=gray, width=1.4]; - m1 [label="meta page"]; + m1 [label="元页"]; subgraph cluster01 { - label="entry tree"; + label="键项树"; subgraph egroup1 { rank=same; e1; @@ -27,13 +28,13 @@ digraph "gin" { e4 -> e8; e4 -> e9; - e6 [fillcolor=green, label="posting list"]; - e8 [fillcolor=green, label="posting list"]; - e9 [fillcolor=green, label="posting list"]; + e6 [fillcolor=green, label="倒排列表"]; + e8 [fillcolor=green, label="倒排列表"]; + e9 [fillcolor=green, label="倒排列表"]; } subgraph cluster02 { - label="posting tree"; + label="倒排树"; subgraph pgroup1 { rank=same; p1; @@ -45,22 +46,22 @@ digraph "gin" { p1 -> p2; p1 -> p3; - p2 [fillcolor=green, label="heap ptr"]; - p3 [fillcolor=green, label="heap ptr"]; + p2 [fillcolor=green, label="堆指针"]; + p3 [fillcolor=green, label="堆指针"]; } subgraph cluster03 { - label="posting tree"; + label="倒排树"; subgraph pgroup3 { rank=same; p4; } - p4 [fillcolor=green, label="heap ptr"]; + p4 [fillcolor=green, label="堆指针"]; } subgraph cluster04 { - label="posting tree"; + label="倒排树"; subgraph pgroup4 { rank=same; p5; @@ -72,12 +73,12 @@ digraph "gin" { p5 -> p6; p5 -> p7; - p6 [fillcolor=green, label="heap ptr"]; - p7 [fillcolor=green, label="heap ptr"]; + p6 [fillcolor=green, label="堆指针"]; + p7 [fillcolor=green, label="堆指针"]; } subgraph cluster05 { - label="pending list"; + label="待处理列表"; node [style=filled, fillcolor=red]; n1 -> n2 -> n3 -> n4; } diff --git a/zh/17/images/gin.svg b/zh/17/images/gin.svg index 04fe85ba..79cf14a9 100644 --- a/zh/17/images/gin.svg +++ b/zh/17/images/gin.svg @@ -9,33 +9,33 @@ cluster01 -entry tree +键项树 cluster02 -posting tree +倒排树 cluster03 -posting tree +倒排树 cluster04 -posting tree +倒排树 cluster05 -pending list +待处理列表 m1 -meta page +元页 @@ -113,7 +113,7 @@ e6 -posting list +倒排列表 @@ -142,7 +142,7 @@ e8 -posting list +倒排列表 @@ -154,7 +154,7 @@ e9 -posting list +倒排列表 @@ -195,7 +195,7 @@ p4 -heap ptr +堆指针 @@ -224,7 +224,7 @@ p2 -heap ptr +堆指针 @@ -236,7 +236,7 @@ p3 -heap ptr +堆指针 @@ -254,7 +254,7 @@ p6 -heap ptr +堆指针 @@ -266,7 +266,7 @@ p7 -heap ptr +堆指针 diff --git a/zh/17/indexam.sgml b/zh/17/indexam.sgml index db8de36c..b5634219 100644 --- a/zh/17/indexam.sgml +++ b/zh/17/indexam.sgml @@ -21,7 +21,7 @@ - 索引本质上是从一些数据键值到行版本(元组)在索引父表中的元组标识符TID)的映射。一个 TID 由块号以及该块中的项号组成(见 元组标识符(TIDs)的映射。一个 TID 由块号以及该块中的项号组成(见 )。这些信息足以从表中取出某个特定的行版本。索引并不直接知道在 MVCC 之下同一逻辑行可能会存在多个现存版本;对索引来说,每个元组都是一个独立对象,需要它自己的索引条目。因此,对一行的更新总会为该行创建全新的索引条目,即使键值并未改变也是如此。(HOT 元组是这一说法的例外;但索引同样不直接处理它们。)当死元组自身被回收时(通过清理),它们对应的索引条目也会被回收。 @@ -44,78 +44,78 @@ typedef struct IndexAmRoutine NodeTag type; /* - * Total number of strategies (operators) by which we can traverse/search - * this AM. Zero if AM does not have a fixed set of strategy assignments. + * 可用于遍历或搜索此 AM 的策略(操作符)总数。 + * 如果 AM 没有固定的一组策略分配,则为零。 */ uint16 amstrategies; - /* total number of support functions that this AM uses */ + /* 此 AM 使用的支持函数总数 */ uint16 amsupport; - /* opclass options support function number or 0 */ + /* 操作符类选项支持函数编号,或为 0 */ uint16 amoptsprocnum; - /* does AM support ORDER BY indexed column's value? */ + /* AM 是否支持按被索引列的值进行 ORDER BY? */ bool amcanorder; - /* does AM support ORDER BY result of an operator on indexed column? */ + /* AM 是否支持按被索引列上操作符的结果进行 ORDER BY? */ bool amcanorderbyop; - /* does AM support backward scanning? */ + /* AM 是否支持反向扫描? */ bool amcanbackward; - /* does AM support UNIQUE indexes? */ + /* AM 是否支持 UNIQUE 索引? */ bool amcanunique; - /* does AM support multi-column indexes? */ + /* AM 是否支持多列索引? */ bool amcanmulticol; - /* does AM require scans to have a constraint on the first index column? */ + /* AM 是否要求扫描必须约束第一个索引列? */ bool amoptionalkey; - /* does AM handle ScalarArrayOpExpr quals? */ + /* AM 是否处理 ScalarArrayOpExpr 限定条件? */ bool amsearcharray; - /* does AM handle IS NULL/IS NOT NULL quals? */ + /* AM 是否处理 IS NULL/IS NOT NULL 限定条件? */ bool amsearchnulls; - /* can index storage data type differ from column data type? */ + /* 索引存储数据类型是否可以不同于列数据类型? */ bool amstorage; - /* can an index of this type be clustered on? */ + /* 是否可以按此类型的索引进行聚簇? */ bool amclusterable; - /* does AM handle predicate locks? */ + /* AM 是否处理谓词锁? */ bool ampredlocks; - /* does AM support parallel scan? */ + /* AM 是否支持并行扫描? */ bool amcanparallel; - /* does AM support parallel build? */ + /* AM 是否支持并行构建? */ bool amcanbuildparallel; - /* does AM support columns included with clause INCLUDE? */ + /* AM 是否支持由 INCLUDE 子句包含的列? */ bool amcaninclude; - /* does AM use maintenance_work_mem? */ + /* AM 是否使用 maintenance_work_mem? */ bool amusemaintenanceworkmem; - /* does AM summarize tuples, with at least all tuples in the block - * summarized in one summary */ + /* AM 是否对元组进行摘要,且一个摘要至少涵盖 + * 块中的所有元组? */ bool amsummarizing; - /* OR of parallel vacuum flags */ + /* 并行清理标志的 OR 组合 */ uint8 amparallelvacuumoptions; - /* type of data stored in index, or InvalidOid if variable */ + /* 索引中存储的数据类型;如果可变,则为 InvalidOid */ Oid amkeytype; - /* interface functions */ + /* 接口函数 */ ambuild_function ambuild; ambuildempty_function ambuildempty; aminsert_function aminsert; - aminsertcleanup_function aminsertcleanup; /* can be NULL */ + aminsertcleanup_function aminsertcleanup; /* 可以为 NULL */ ambulkdelete_function ambulkdelete; amvacuumcleanup_function amvacuumcleanup; - amcanreturn_function amcanreturn; /* can be NULL */ + amcanreturn_function amcanreturn; /* 可以为 NULL */ amcostestimate_function amcostestimate; amoptions_function amoptions; - amproperty_function amproperty; /* can be NULL */ - ambuildphasename_function ambuildphasename; /* can be NULL */ + amproperty_function amproperty; /* 可以为 NULL */ + ambuildphasename_function ambuildphasename; /* 可以为 NULL */ amvalidate_function amvalidate; - amadjustmembers_function amadjustmembers; /* can be NULL */ + amadjustmembers_function amadjustmembers; /* 可以为 NULL */ ambeginscan_function ambeginscan; amrescan_function amrescan; - amgettuple_function amgettuple; /* can be NULL */ - amgetbitmap_function amgetbitmap; /* can be NULL */ + amgettuple_function amgettuple; /* 可以为 NULL */ + amgetbitmap_function amgetbitmap; /* 可以为 NULL */ amendscan_function amendscan; - ammarkpos_function ammarkpos; /* can be NULL */ - amrestrpos_function amrestrpos; /* can be NULL */ + ammarkpos_function ammarkpos; /* 可以为 NULL */ + amrestrpos_function amrestrpos; /* 可以为 NULL */ - /* interface functions to support parallel index scans */ - amestimateparallelscan_function amestimateparallelscan; /* can be NULL */ - aminitparallelscan_function aminitparallelscan; /* can be NULL */ - amparallelrescan_function amparallelrescan; /* can be NULL */ + /* 支持并行索引扫描的接口函数 */ + amestimateparallelscan_function amestimateparallelscan; /* 可以为 NULL */ + aminitparallelscan_function aminitparallelscan; /* 可以为 NULL */ + amparallelrescan_function amparallelrescan; /* 可以为 NULL */ } IndexAmRoutine; @@ -137,7 +137,7 @@ typedef struct IndexAmRoutine - amsummarizing 标志指示该访问方法是否会对被索引元组做摘要,并且摘要粒度至少达到每个块一个摘要。不指向单个元组,而是指向块范围(例如 BRIN)的访问方法,可能允许继续使用 HOT 优化。这不适用于索引谓词中引用的属性,对这类属性的更新总会禁用 HOT。 + amsummarizing 标志指示该访问方法是否会对被索引元组做摘要,并且摘要粒度至少为一个块。不指向单个元组,而是指向块范围(例如 BRIN)的访问方法,可能允许继续使用 HOT 优化。这不适用于索引谓词中引用的属性,对这类属性的更新总会禁用 HOT @@ -204,7 +204,7 @@ void aminsertcleanup (Relation indexRelation, IndexInfo *indexInfo); - 清理由 indexInfo->ii_AmCache 在连续插入之间维护的状态。如果这些数据需要额外的清理步骤(例如释放已钉住的缓冲区),而仅释放内存还不够,那么这个函数就很有用。 + 清理在 indexInfo->ii_AmCache 中跨连续插入维护的状态。如果这些数据需要额外的清理步骤(例如释放已钉住的缓冲区),而仅释放内存还不够,那么这个函数就很有用。 @@ -215,7 +215,7 @@ ambulkdelete (IndexVacuumInfo *info, IndexBulkDeleteCallback callback, void *callback_state); - 从索引中删除元组。这是一个批量删除操作,通常应通过扫描整个索引并检查每个条目是否应被删除来实现。必须调用传入的 callback 函数,其调用形式为 callback(TID, callback_state) returns bool,以确定由其引用 TID 标识的某个索引条目是否应删除。该函数必须返回 NULL,或者返回一个通过 palloc 分配的结构体,其中包含此次删除操作影响的统计信息。如果不需要向 amvacuumcleanup 传递信息,返回 NULL 也是可以的。 + 从索引中删除元组。这是一个批量删除操作,旨在通过扫描整个索引并检查每个条目是否应被删除来实现。必须调用传入的 callback 函数,其调用形式为 callback(TID, callback_state) returns bool,以确定由其引用 TID 标识的某个索引条目是否应删除。该函数必须返回 NULL,或者返回一个通过 palloc 分配的结构体,其中包含此次删除操作影响的统计信息。如果不需要向 amvacuumcleanup 传递信息,返回 NULL 也是可以的。 @@ -240,8 +240,7 @@ amvacuumcleanup (IndexVacuumInfo *info, bool amcanreturn (Relation indexRelation, int attno); - 检查索引是否能够在给定列上支持 仅索引扫描,做法是返回该列原始的被索引值。属性编号从 1 开始,也就是说第一列的 attno 为 1。若支持则返回真,否则返回假。如果支持包含列,这个函数应始终对包含列返回真,因为不能取回的包含列几乎没有意义。如果访问方法根本不支持仅索引扫描,那么它的 IndexAmRoutine 结构体中的 amcanreturn 字段可以设为 NULL。 + 检查索引能否通过返回给定列原始的被索引值,在该列上支持 仅索引扫描。属性编号从 1 开始,也就是说第一列的 attno 为 1。若支持则返回真,否则返回假。如果支持包含列,这个函数应始终对包含列返回真,因为不能取回的包含列几乎没有意义。如果访问方法根本不支持仅索引扫描,那么它的 IndexAmRoutine 结构体中的 amcanreturn 字段可以设为 NULL。 @@ -256,7 +255,7 @@ amcostestimate (PlannerInfo *root, double *indexCorrelation, double *indexPages); - 估计一次索引扫描的开销。该函数将在后面的 中详细讨论。 + 估计一次索引扫描的代价。该函数将在后面的 中详细讨论。 @@ -265,7 +264,7 @@ bytea * amoptions (ArrayType *reloptions, bool validate); - 解析并验证索引的 reloptions 数组。只有当该索引存在非空的 reloptions 数组时才会调用此函数。reloptions 是一个 text 数组,其中的条目形如 name=value。该函数应构造一个 bytea 值,并将其复制到索引 relcache 条目的 rd_options 字段中。这个 bytea 值中的数据内容由访问方法自行定义;大多数标准访问方法使用结构体 StdRdOptions。当 validate 为真时,若存在未识别选项或无效取值,函数应报告合适的错误消息;当 validate 为假时,无效条目应被静默忽略。(当装载已存储在 pg_catalog 中的选项时,validate 为假;此时只有在访问方法改变了选项规则时才可能发现无效条目,而忽略过时条目是合适的。)如果希望采用默认行为,返回 NULL 也是可以的。 + 解析并验证索引的 reloptions 数组。只有当该索引存在非 NULL 的 reloptions 数组时才会调用此函数。reloptions 是一个 text 数组,其中的条目形如 name=value。该函数应构造一个 bytea 值,并将其复制到索引 relcache 条目的 rd_options 字段中。这个 bytea 值中的数据内容由访问方法自行定义;大多数标准访问方法使用结构体 StdRdOptions。当 validate 为真时,若存在未识别选项或无效取值,函数应报告合适的错误消息;当 validate 为假时,无效条目应被静默忽略。(当装载已存储在 pg_catalog 中的选项时,validate 为假;此时只有在访问方法改变了选项规则时才可能发现无效条目,而忽略过时条目是合适的。)如果希望采用默认行为,返回 NULL 也是可以的。 @@ -279,7 +278,7 @@ amproperty (Oid index_oid, int attno, - 支持排序操作符的访问方法应当实现 AMPROP_DISTANCE_ORDERABLE 属性测试,因为核心代码不知道如何完成该测试,只会返回 NULL。若实现成本低于打开索引并调用 amcanreturn(这正是核心代码的默认行为),那么实现 AMPROP_RETURNABLE 测试也可能是有利的。对于其他所有标准属性,默认行为应当已经足够。 + 支持排序操作符的访问方法应当实现 AMPROP_DISTANCE_ORDERABLE 属性测试,因为核心代码不知道如何完成该测试,只会返回 NULL。若完成该测试的代价低于打开索引并调用 amcanreturn(这正是核心代码的默认行为),那么实现 AMPROP_RETURNABLE 测试也可能是有利的。对于其他所有标准属性,默认行为应当已经足够。 @@ -341,11 +340,11 @@ bool amgettuple (IndexScanDesc scan, ScanDirection direction); - 在给定扫描中取出下一个元组,并按给定方向移动(在索引中向前或向后)。若成功取得元组则返回真;若不再有匹配元组则返回假。在返回真时,元组的 TID 会存入 scan 结构体中。请注意,成功仅表示索引中存在一个匹配扫描键的条目,并不表示该元组一定仍然存在于堆中,或者一定能通过调用者的快照测试。成功时,amgettuple 还必须把 scan->xs_recheck 设为真或假。假表示可以确定该索引条目匹配扫描键;真表示这一点并不确定,因此在取到堆元组后必须根据扫描键所代表的条件重新检查它。这一机制支持有损索引操作符。请注意,重检只会扩展到扫描条件;部分索引谓词(如果有)永远不会由 amgettuple 的调用者重新检查。 + 在给定扫描中取出下一个元组,并按给定方向移动(在索引中向前或向后)。若成功取得元组则返回真;若不再有匹配元组则返回假。在返回真时,元组的 TID 会存入 scan 结构体中。请注意,成功仅表示索引中存在一个匹配扫描键的条目,并不表示该元组一定仍然存在于堆中,或者一定能通过调用者的快照测试。成功时,amgettuple 还必须把 scan->xs_recheck 设为真或假。假表示可以确定该索引条目匹配扫描键;真表示这一点并不确定,因此在取到堆元组后必须根据扫描键所代表的条件重新检查它。这一机制支持有损索引操作符。请注意,重检只针对扫描条件;部分索引谓词(如果有)永远不会由 amgettuple 的调用者重新检查。 - 如果索引支持 仅索引扫描(即其任一列上 amcanreturn 返回真),那么成功时 AM 还必须检查 scan->xs_want_itup;若其为真,就必须返回该索引条目的原始被索引数据。对于 amcanreturn 返回假的列,可以把其值作为 NULL 返回。数据可以通过以下两种形式之一返回:一种是把 IndexTuple 指针存入 scan->xs_itup,其元组描述符为 scan->xs_itupdesc;另一种是把 HeapTuple 指针存入 scan->xs_hitup,其元组描述符为 scan->xs_hitupdesc。(当重建出的数据可能装不进 IndexTuple 时,应使用后一种格式。)无论采用哪种形式,指针所引用数据的管理责任都在访问方法一侧。对这份数据的有效性必须至少保持到该扫描下一次调用 amgettupleamrescanamendscan 为止。 + 如果索引支持 仅索引扫描(即其至少一列上 amcanreturn 返回真),那么成功时 AM 还必须检查 scan->xs_want_itup;若其为真,就必须返回该索引条目的原始被索引数据。对于 amcanreturn 返回假的列,可以把其值作为 NULL 返回。数据可以通过以下两种形式之一返回:一种是把 IndexTuple 指针存入 scan->xs_itup,其元组描述符为 scan->xs_itupdesc;另一种是把 HeapTuple 指针存入 scan->xs_hitup,其元组描述符为 scan->xs_hitupdesc。(当重建出的数据可能装不进 IndexTuple 时,应使用后一种格式。)无论采用哪种形式,指针所引用数据的管理责任都在访问方法一侧。这份数据必须至少保持有效,直到该扫描下一次调用 amgettupleamrescanamendscan @@ -358,7 +357,7 @@ int64 amgetbitmap (IndexScanDesc scan, TIDBitmap *tbm); - 取出给定扫描中的所有元组,并将其加入调用者提供的 TIDBitmap 中(也就是把这组元组 ID 与位图中已有的集合做 OR)。返回值是取得的元组数量(这可能只是近似计数,例如某些 AM 不会检测重复项)。在把元组 ID 插入位图时,amgetbitmap 可以指出某些具体的元组 ID 需要重新检查扫描条件。这类似于 amgettuplexs_recheck 输出参数。注意:在当前实现中,对这一特性的支持与位图自身的有损存储支持混在一起,因此调用者会对可重检元组同时重新检查扫描条件和部分索引谓词(如果有)。不过,这并不一定永远如此。amgetbitmapamgettuple 不能在同一次索引扫描中同时使用;使用 amgetbitmap 时还有其他限制,详见 。 + 取出给定扫描中的所有元组,并将其加入调用者提供的 TIDBitmap 中(也就是把这组元组 ID 与位图中已有的集合做 OR)。返回值是取得的元组数量(这可能只是近似计数,例如某些 AM 不会检测重复项)。在把元组 ID 插入位图时,amgetbitmap 可以指出某些具体的元组 ID 需要重新检查扫描条件。这类似于 amgettuplexs_recheck 输出参数。注意:在当前实现中,对这一特性的支持与位图自身的有损存储支持混在一起,因此调用者会对需要重检的元组同时重新检查扫描条件和部分索引谓词(如果有)。不过,这并不一定永远如此。amgetbitmapamgettuple 不能在同一次索引扫描中同时使用;使用 amgetbitmap 时还有其他限制,详见 @@ -370,7 +369,7 @@ amgetbitmap (IndexScanDesc scan, void amendscan (IndexScanDesc scan); - 结束一次扫描并释放资源。scan 结构体本身不应被释放,但访问方法内部获取的任何锁或 pin,以及由 ambeginscan 和其他扫描相关函数分配的其他内存,都必须被释放。 + 结束一次扫描并释放资源。scan 结构体本身不应被释放,但必须释放访问方法内部获取的所有锁、解除所有钉住状态,并释放由 ambeginscan 和其他扫描相关函数分配的其他内存。 @@ -493,7 +492,7 @@ amparallelrescan (IndexScanDesc scan); - 除了使用 amgettuple 外,索引扫描也可以使用 amgetbitmap,在一次调用中取出所有元组。与 amgettuple 相比,这通常明显更高效,因为它可以避免访问方法内部的反复加锁和解锁。原则上,amgetbitmap 应具有与重复调用 amgettuple 相同的效果,但为了简化实现,我们施加了若干限制。首先,amgetbitmap 一次性返回全部元组,因此不支持标记或恢复扫描位置。其次,元组是通过一个位图返回的,没有特定顺序,这也是为什么 amgetbitmap 不带 direction 参数的原因。(这种扫描也永远不会提供排序操作符。)此外,使用 amgetbitmap 时也没有仅索引扫描的支持,因为没有办法返回索引元组的内容。最后,amgetbitmap 不保证对返回的元组做任何锁定,其影响见 。 + 除了使用 amgettuple 外,索引扫描也可以使用 amgetbitmap,在一次调用中取出所有元组。与 amgettuple 相比,这可能明显更高效,因为它可以避免访问方法内部的反复加锁和解锁。原则上,amgetbitmap 应具有与重复调用 amgettuple 相同的效果,但为了简化实现,我们施加了若干限制。首先,amgetbitmap 一次性返回全部元组,因此不支持标记或恢复扫描位置。其次,元组是通过一个位图返回的,没有特定顺序,这也是为什么 amgetbitmap 不带 direction 参数的原因。(这种扫描也永远不会提供排序操作符。)此外,使用 amgetbitmap 时也没有仅索引扫描的支持,因为没有办法返回索引元组的内容。最后,amgetbitmap 不保证对返回的元组做任何锁定,其影响见 @@ -510,7 +509,7 @@ amparallelrescan (IndexScanDesc scan); - 构建一种支持并发更新的索引类型,通常需要对所需行为进行大量而细致的分析。对于 B-树和哈希索引类型,可以阅读 src/backend/access/nbtree/READMEsrc/backend/access/hash/README 中涉及的设计决策。 + 构建一种支持并发更新的索引类型,通常需要对所需行为进行大量而细致的分析。对于 B-树和 hash 索引类型,可以阅读 src/backend/access/nbtree/READMEsrc/backend/access/hash/README 中涉及的设计决策。 @@ -529,12 +528,12 @@ amparallelrescan (IndexScanDesc scan); - 索引扫描必须在保存 amgettuple 最近一次返回条目的索引页面上维护一个 pin,而 ambulkdelete 不能从被其他后端钉住的页面中删除条目。下面会解释为什么需要这条规则。 + 索引扫描必须在保存 amgettuple 最近一次返回条目的索引页面上保持钉住状态,而 ambulkdelete 不能从被其他后端钉住的页面中删除条目。下面会解释为什么需要这条规则。 - 如果没有第三条规则,索引读取者就有可能在某个索引条目被 VACUUM 删除之前先看到它,然后在对应的堆条目已被 VACUUM 删除之后才到达那里。如果读取者到达时,该项号仍未被重新使用,就不会造成严重问题,因为空项槽位会被 heap_fetch() 忽略。但如果第三个后端已经把这个项槽位重新用作别的东西呢?在使用 MVCC 兼容快照时不会有问题,因为该槽位的新占用者一定太新,无法通过快照测试。然而,对于非 MVCC 兼容的快照(例如 SnapshotAny),就可能错误地接受并返回一行实际上并不匹配扫描键的数据。我们可以要求在所有情况下都对堆行重新检查扫描键,以防范这种情形,但那样代价太高。于是,我们改为把索引页面上的 pin 作为一种代理,表示读取者可能仍处于从索引条目前往匹配堆条目的飞行中。让 ambulkdelete 在这种 pin 上阻塞,能够保证 VACUUM 不会在读取者处理完之前删除对应的堆条目。这种方案运行时开销很小,只有在真正发生冲突的少数情况下才会增加阻塞开销。 + 如果没有第三条规则,索引读取者就有可能在某个索引条目被 VACUUM 删除之前先看到它,然后在对应的堆条目已被 VACUUM 删除之后才到达那里。如果读取者到达时,该项号仍未被重新使用,就不会造成严重问题,因为空项槽位会被 heap_fetch() 忽略。但如果第三个后端已经把这个项槽位重新用作别的东西呢?在使用 MVCC 兼容快照时不会有问题,因为该槽位的新占用者一定太新,无法通过快照测试。然而,对于非 MVCC 兼容的快照(例如 SnapshotAny),就可能错误地接受并返回一行实际上并不匹配扫描键的数据。我们可以要求在所有情况下都对堆行重新检查扫描键,以防范这种情形,但那样代价太高。于是,我们改为把索引页面的钉住状态作为一种代理,表示读取者从索引条目到匹配堆条目的访问过程可能仍在进行中。让 ambulkdelete 因这种钉住状态而阻塞,能够保证 VACUUM 不会在读取者处理完之前删除对应的堆条目。这种方案运行时开销很小,只有在真正发生冲突的少数情况下才会增加阻塞开销。 @@ -542,7 +541,7 @@ amparallelrescan (IndexScanDesc scan); - 在 amgetbitmap 索引扫描中,访问方法不会在任何返回的元组上保留索引 pin。因此,只有把这种扫描与 MVCC 兼容的快照一起使用才是安全的。 + 在 amgetbitmap 索引扫描中,访问方法不会为任何返回的元组保持索引页面的钉住状态。因此,只有把这种扫描与 MVCC 兼容的快照一起使用才是安全的。 @@ -581,7 +580,7 @@ amparallelrescan (IndexScanDesc scan); - 此外,在按照上述规则报告唯一性违背之前,访问方法必须立即重新检查正在插入那一行的存活性。如果它已经是提交后死亡的状态,就不应报告违背。(这种情况不会出现在插入由当前事务刚创建的行这一普通场景中,但在 CREATE UNIQUE INDEX CONCURRENTLY 期间却可能发生。) + 此外,就在按照上述规则报告唯一性违背之前,访问方法必须重新检查正在插入那一行的存活性。如果它已经是提交后死亡的状态,就不应报告违背。(这种情况不会出现在插入由当前事务刚创建的行这一普通场景中,但在 CREATE UNIQUE INDEX CONCURRENTLY 期间却可能发生。) @@ -589,7 +588,7 @@ amparallelrescan (IndexScanDesc scan); - 如果唯一约束是可延迟的,情况会更复杂:我们需要能够为新行插入一个索引条目,但把任何唯一性违背错误延迟到语句结束时甚至更晚才报告。为了避免对索引进行不必要的重复搜索,索引访问方法应在初始插入期间执行一次初步唯一性检查。如果这表明确实不存在冲突的存活元组,那么事情就结束了。否则,我们会安排在真正强制约束时再做一次重检。若在重检时,插入的元组与另外某个具有相同键值的元组都仍然存活,就必须报告错误。(注意,就此用途而言,存活实际上是指索引条目 HOT 链中的任一元组是存活的。)为实现这一点,传给 aminsert 函数的 checkUnique 参数会取以下值之一: + 如果唯一约束是可延迟的,情况会更复杂:我们需要能够为新行插入一个索引条目,但把任何唯一性违背错误延迟到语句结束时甚至更晚才报告。为了避免对索引进行不必要的重复搜索,索引访问方法应在初始插入期间执行一次初步唯一性检查。如果这表明确实不存在冲突的存活元组,那么事情就结束了。否则,我们会安排在真正强制约束时再做一次重检。若在重检时,插入的元组与另外某个具有相同键值的元组都仍然存活,就必须报告错误。(注意,就此用途而言,存活实际上是指索引条目 HOT 链中至少有一个元组是存活的。)为实现这一点,传给 aminsert 函数的 checkUnique 参数会取以下值之一: @@ -626,10 +625,10 @@ amparallelrescan (IndexScanDesc scan); - 索引开销估计函数 + 索引代价估算函数 - amcostestimate 函数会收到描述某种可能索引扫描方式的信息,其中包括已经确定可用于该索引的 WHERE 子句和 ORDER BY 子句列表。它必须返回访问该索引的开销估计,以及 WHERE 子句的选择率(也就是在索引扫描期间将从父表中检索出的行所占比例)。对于简单情况,开销估计器几乎所有工作都可以通过调用优化器中的标准例程来完成;之所以提供 amcostestimate 函数,是为了让索引访问方法能够提供与索引类型有关的专门知识,以便在可能时改进标准估计。 + amcostestimate 函数会收到描述某种可能索引扫描方式的信息,其中包括已经确定可用于该索引的 WHERE 子句和 ORDER BY 子句列表。它必须返回访问该索引的代价估算,以及 WHERE 子句选择率的估计值(也就是在索引扫描期间将从父表中检索出的行所占比例)。对于简单情况,代价估算器几乎所有工作都可以通过调用优化器中的标准例程来完成;之所以提供 amcostestimate 函数,是为了让索引访问方法能够提供与索引类型有关的专门知识,以便在可能时改进标准估计。 @@ -663,7 +662,7 @@ amcostestimate (PlannerInfo *root, path - 当前正在考虑的索引访问路径。除开销和选择率字段外,其余字段都有效。 + 当前正在考虑的索引访问路径。除代价和选择率字段外,其余字段都有效。 @@ -672,7 +671,7 @@ amcostestimate (PlannerInfo *root, loop_count - 在开销估计中应计入的索引扫描重复次数。当考虑在嵌套循环连接内部使用参数化扫描时,这个参数通常会大于 1。请注意,开销估计仍应只针对一次扫描;更大的 loop_count 只表示可以适当考虑多次扫描之间的一些缓存效应。 + 在代价估算中应计入的索引扫描重复次数。当考虑在嵌套循环连接内部使用参数化扫描时,这个参数通常会大于 1。请注意,代价估算仍应只针对一次扫描;更大的 loop_count 只表示可以适当考虑多次扫描之间的一些缓存效应。 @@ -687,7 +686,7 @@ amcostestimate (PlannerInfo *root, *indexStartupCost - 设为索引启动处理的开销。 + 设为索引启动处理的代价。 @@ -696,7 +695,7 @@ amcostestimate (PlannerInfo *root, *indexTotalCost - 设为索引处理的总开销。 + 设为索引处理的总代价。 @@ -731,19 +730,19 @@ amcostestimate (PlannerInfo *root, - 请注意,开销估计函数必须用 C 编写,而不能用 SQL 或任何可用的过程语言,因为它们必须访问规划器/优化器的内部数据结构。 + 请注意,代价估算函数必须用 C 编写,而不能用 SQL 或任何可用的过程语言,因为它们必须访问规划器/优化器的内部数据结构。 - 索引访问开销应使用 src/backend/optimizer/path/costsize.c 所采用的参数来计算:顺序磁盘块读取的开销为 seq_page_cost,非顺序读取的开销为 random_page_cost,处理一条索引行的开销通常应取为 cpu_index_tuple_cost。此外,在索引处理期间调用的任何比较操作符(特别是对 indexquals 本身的求值)都应计入适当倍数的 cpu_operator_cost。 + 索引访问代价应使用 src/backend/optimizer/path/costsize.c 所采用的参数来计算:顺序磁盘块读取的代价为 seq_page_cost,非顺序读取的代价为 random_page_cost,处理一条索引行的代价通常应取为 cpu_index_tuple_cost。此外,在索引处理期间调用的任何比较操作符(特别是对 indexquals 本身的求值)都应计入适当倍数的 cpu_operator_cost - 访问开销应包括与扫描索引本身有关的全部磁盘和 CPU 开销,但包括取出或处理由索引标识出的父表行的开销。 + 访问代价应包括与扫描索引本身有关的全部磁盘和 CPU 代价,但包括取出或处理由索引标识出的父表行的代价。 - 启动开销是整个扫描总开销中必须在开始取第一行之前先付出的那一部分。对大多数索引来说,这可以视为零;但启动开销较高的索引类型可能希望把它设为非零。 + 启动代价是整个扫描总代价中必须在开始取第一行之前先付出的那一部分。对大多数索引来说,这可以视为零;但启动代价较高的索引类型可能希望把它设为非零。 @@ -751,7 +750,7 @@ amcostestimate (PlannerInfo *root, - indexCorrelation 应设为索引顺序与表顺序之间的相关性(范围从 -1.0 到 1.0)。该值用于调整从父表取行开销的估计。 + indexCorrelation 应设为索引顺序与表顺序之间的相关性(范围从 -1.0 到 1.0)。该值用于调整从父表取行代价的估计。 @@ -763,9 +762,9 @@ amcostestimate (PlannerInfo *root, - 开销估计 + 代价估算 - 一个典型的开销估计器会按如下步骤进行: + 一个典型的代价估算器会按如下步骤进行: @@ -794,14 +793,14 @@ amcostestimate (PlannerInfo *root, - 计算索引访问开销。一个通用估计器可能会这样做: + 计算索引访问代价。一个通用估计器可能会这样做: /* - * Our generic assumption is that the index pages will be read - * sequentially, so they cost seq_page_cost each, not random_page_cost. - * Also, we charge for evaluation of the indexquals at each index row. - * All the costs are assumed to be paid incrementally during the scan. + * 通用假设是索引页面将按顺序读取, + * 因此每页代价为 seq_page_cost,而非 random_page_cost。 + * 此外,还要计入在每个索引行上对 indexquals 求值的代价。 + * 假定所有代价都在扫描过程中逐步付出。 */ cost_qual_eval(&index_qual_cost, path->indexquals, root); *indexStartupCost = index_qual_cost.startup; @@ -821,7 +820,7 @@ cost_qual_eval(&index_qual_cost, path->indexquals, root); - 开销估计器函数的示例可在 src/backend/utils/adt/selfuncs.c 中找到。 + 代价估算器函数的示例可在 src/backend/utils/adt/selfuncs.c 中找到。 diff --git a/zh/17/indices.sgml b/zh/17/indices.sgml index acb719ae..d2578d63 100644 --- a/zh/17/indices.sgml +++ b/zh/17/indices.sgml @@ -31,7 +31,7 @@ SELECT content FROM test1 WHERE id = constant; - 大多数非小说类书籍也采用了类似的方法:读者经常查找的术语和概念会被收集到书末按字母顺序排列的索引中。感兴趣的读者可以相对快速地浏览索引并翻到相应页面,而不必通读整本书才能找到自己感兴趣的内容。正如作者需要预判读者可能查找哪些条目一样,数据库程序员也需要预见哪些索引会有用。 + 大多数非虚构类书籍也采用了类似的方法:读者经常查找的术语和概念会被收集到书末按字母顺序排列的索引中。感兴趣的读者可以相对快速地浏览索引并翻到相应页面,而不必通读整本书才能找到自己感兴趣的内容。正如作者需要预判读者可能查找哪些条目一样,数据库程序员也需要预见哪些索引会有用。 @@ -71,7 +71,7 @@ CREATE INDEX test1_id_index ON test1 (id); comparison-value operator indexed-column - 那么如果原始operator有一个可交换操作符,并且该操作符属于该索引的操作符类,就可以把它翻转成可索引的形式。 + 那么如果原始operator有一个交换子操作符,并且该操作符属于该索引的操作符类,就可以把它翻转成可索引的形式。 @@ -100,12 +100,12 @@ CREATE INDEX name ON table B-树 - index + 索引 B-树 B-树 - index + 索引 @@ -133,12 +133,12 @@ CREATE INDEX name ON table Hash - index + 索引 hash hash - index + 索引 @@ -154,12 +154,12 @@ CREATE INDEX name ON table GiST - index + 索引 GiST GiST - index + 索引 @@ -186,12 +186,12 @@ SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10; SP-GiST - index + 索引 SP-GiST SP-GiST - index + 索引 @@ -213,12 +213,12 @@ SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10; GIN - index + 索引 GIN GIN - index + 索引 @@ -240,16 +240,16 @@ SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10; BRIN - index + 索引 BRIN BRIN - index + 索引 - BRIN 索引(块范围索引,Block Range Indexes)存储的是关于表中连续物理块范围内所保存值的摘要信息。因此,它最适用于那些列值与表行物理顺序高度相关的列。与 GiST、SP-GiST 和 GIN 一样,BRIN 也可以支持多种不同的索引策略,而 BRIN 索引可使用哪些具体操作符取决于所采用的索引策略。对于具有线性排序顺序的数据类型,每个块范围上被索引的数据对应于该列值的最小值和最大值。这支持使用下列操作符的索引化查询: + BRIN 索引(Block Range INdexes 的缩写)存储的是关于表中连续物理块范围内所保存值的摘要信息。因此,它最适用于那些列值与表行物理顺序高度相关的列。与 GiST、SP-GiST 和 GIN 一样,BRIN 也可以支持多种不同的索引策略,而 BRIN 索引可使用哪些具体操作符取决于所采用的索引策略。对于具有线性排序顺序的数据类型,每个块范围上被索引的数据对应于该列值的最小值和最大值。这支持使用下列操作符的索引化查询: <   <=   =   >=   > @@ -265,8 +265,8 @@ SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10; 多列索引 - index - multicolumn + 索引 + 多列 @@ -292,24 +292,18 @@ CREATE INDEX test2_mm_idx ON test2 (major, minor); 当前,只有 B-树、GiST、GIN 和 BRIN 索引类型支持多键列索引。能否有多个键列,与索引中能否添加INCLUDE列无关。索引最多可以有 32 列,包括INCLUDE列。(这个限制在构建PostgreSQL时可以修改;参见文件pg_config_manual.h。) - - 多列 B-树索引可以用于涉及索引任意列子集的查询条件,但当对前导(最左)列存在约束时,索引效率最高。精确的规则是:对前导列的等值约束,再加上第一个没有等值约束列上的任意不等约束,会被用来限制被扫描的索引范围。这些列右侧列上的约束会在索引中进行检查,因此能减少访问表本体的次数,但不会减少必须扫描的索引范围。 - - - - 例如,给定一个(a, b, c)上的索引和查询条件WHERE a = 5 AND b >= 42 AND c < 77,该索引将不得不从第一个a = 5 且b = 42 的条目扫描到最后一个a = 5 的条目。c >= 77 的索引项会被跳过,但仍然必须扫描过去。原则上,该索引也可用于只对b和/或c有约束而对a没有约束的查询,但整个索引都必须被扫描,因此在大多数情况下,规划器会更倾向于顺序扫描表而不是使用该索引。 - + 多列 B-树索引可以用于涉及索引任意列子集的查询条件,但当对前导(最左)列存在约束时,索引效率最高。精确的规则是:对前导列的等值约束,再加上第一个没有等值约束的列上的任何不等约束,会被用来限制索引扫描的范围。这些列右侧列上的约束会在索引中进行检查,因此可以减少访问表本体的次数,但不会缩小必须扫描的索引范围。例如,给定一个 (a, b, c) 上的索引和查询条件 WHERE a = 5 AND b >= 42 AND c < 77,索引必须从第一个 a = 5 且 b = 42 的条目扫描到最后一个 a = 5 的条目。c >= 77 的索引项会被排除,但仍然必须扫描这些项。原则上,这个索引也可以用于只对 b 和/或 c 有约束、而对 a 没有约束的查询,但必须扫描整个索引,因此在大多数情况下,规划器会倾向于顺序扫描表,而不是使用该索引。 多列 GiST 索引可以用于涉及索引任意列子集的查询条件。附加列上的条件会限制索引返回的项,但决定索引需要扫描多少内容的,最重要的仍是第一列上的条件。如果第一列只有很少几个非重复值,即使其他列有很多非重复值,GiST 索引也会相对低效。 - 多列 GIN 索引可以用于涉及索引任意列子集的查询条件。与 B-树或 GiST 不同,无论查询条件使用的是哪一列索引列,GIN 的索引搜索效果都一样。 + 多列 GIN 索引可以用于涉及索引任意列子集的查询条件。与 B-树或 GiST 不同,无论查询条件使用的是哪些索引列,GIN 的索引搜索效果都一样。 - 多列 BRIN 索引可以用于涉及索引任意列子集的查询条件。和 GIN 一样、不同于 B-树或 GiST,无论查询条件使用的是哪一列索引列,索引搜索效果都一样。在单个表上使用多个 BRIN 索引,而不是使用一个多列 BRIN 索引的唯一理由,是需要不同的pages_per_range存储参数。 + 多列 BRIN 索引可以用于涉及索引任意列子集的查询条件。和 GIN 一样、不同于 B-树或 GiST,无论查询条件使用的是哪些索引列,索引搜索效果都一样。在单个表上使用多个 BRIN 索引,而不是使用一个多列 BRIN 索引的唯一理由,是需要不同的pages_per_range存储参数。 @@ -326,7 +320,7 @@ CREATE INDEX test2_mm_idx ON test2 (major, minor); 索引和<literal>ORDER BY</literal> - index + 索引 ORDER BY @@ -335,7 +329,7 @@ CREATE INDEX test2_mm_idx ON test2 (major, minor); - 规划器在满足ORDER BY要求时,会考虑两种方案:扫描一个与该要求匹配的可用索引,或者按物理顺序扫描表再显式排序。对于需要扫描表中很大一部分内容的查询,显式排序通常会比使用索引更快,因为它遵循顺序访问模式,需要的磁盘 I/O 更少。只有在只需取出少量行时,索引才更有价值。一个重要的特例是ORDER BYLIMIT n组合使用:显式排序必须处理所有数据才能找出最前面的n行,而如果有一个与ORDER BY匹配的索引,就可以直接取回前n行,而完全不必扫描剩余数据。 + 规划器在满足ORDER BY要求时,会考虑两种方案:扫描一个与该要求匹配的可用索引,或者按物理顺序扫描表再显式排序。对于需要扫描表中很大一部分内容的查询,显式排序通常会比使用索引更快,因为它遵循顺序访问模式,需要的磁盘 I/O 更少。只需取出少量行时,索引更有价值。一个重要的特例是ORDER BYLIMIT n组合使用:显式排序必须处理所有数据才能找出最前面的n行,而如果有一个与ORDER BY匹配的索引,就可以直接取回前n行,而完全不必扫描剩余数据。 @@ -365,8 +359,8 @@ CREATE INDEX test3_desc_index ON test3 (id DESC NULLS LAST); 组合多个索引 - index - combining multiple indexes + 索引 + 组合多个索引 @@ -387,7 +381,7 @@ CREATE INDEX test3_desc_index ON test3 (id DESC NULLS LAST); - 除了最简单的应用之外,通常会有多种可能有用的索引组合,数据库开发者必须权衡决定提供哪些索引。有时多列索引最好,但有时创建独立索引并依赖索引组合功能会更合适。例如,如果你的工作负载包含一组查询:有时只涉及列x,有时只涉及列y,有时同时涉及两列,那么你可以选择分别在xy上创建两个独立索引,并依赖索引组合来处理同时使用两列的查询。你也可以创建一个(x, y)上的多列索引。对于同时涉及两列的查询,这个索引通常会比索引组合更高效,但正如中所讨论的,它对于只涉及y的查询几乎没有用,因此它不应成为唯一的索引。将该多列索引与一个单独的y索引配合使用,会有相当不错的效果。对于只涉及x的查询,多列索引也可以使用,但它会比单独的x索引更大,因此更慢。最后一种选择是同时创建这三个索引,但这大概只有在该表被搜索的频率远高于被更新的频率,并且三类查询都很常见时才合理。如果其中一种查询远没有另外两种常见,那么你大概只需创建最适合常见查询类型的两个索引即可。 + 除了最简单的应用之外,通常会有多种可能有用的索引组合,数据库开发者必须权衡决定提供哪些索引。有时多列索引最好,但有时创建独立索引并依赖索引组合功能会更合适。例如,如果你的工作负载包含一组查询:有时只涉及列x,有时只涉及列y,有时同时涉及两列,那么你可以选择分别在xy上创建两个独立索引,并依赖索引组合来处理同时使用两列的查询。你也可以创建一个(x, y)上的多列索引。对于同时涉及两列的查询,这个索引通常会比索引组合更高效,但正如中所讨论的,它对于只涉及y的查询几乎没有用处,因此不应只创建这一个索引。将这个多列索引与一个单独的y索引组合起来,能够取得相当好的效果。对于只涉及x的查询,多列索引也可以使用,但它会比单独的x索引更大,因此更慢。最后一种选择是同时创建这三个索引,但这大概只有在该表被搜索的频率远高于被更新的频率,并且三类查询都很常见时才合理。如果其中一种查询远没有另外两种常见,那么你大概只需创建最适合常见查询类型的两个索引即可。 @@ -397,8 +391,8 @@ CREATE INDEX test3_desc_index ON test3 (id DESC NULLS LAST); 唯一索引 - index - unique + 索引 + 唯一 @@ -429,8 +423,8 @@ CREATE UNIQUE INDEX name ON table表达式索引 - index - on expressions + 索引 + 基于表达式 @@ -477,8 +471,8 @@ CREATE INDEX people_names ON people ((first_name || ' ' || last_name)); 部分索引 - index - partial + 索引 + 部分 @@ -486,7 +480,7 @@ CREATE INDEX people_names ON people ((first_name || ' ' || last_name)); - 使用部分索引的一个主要原因是避免索引常见值。由于搜索常见值的查询(即占全部表行百分之几以上的值)反正也不会使用索引,因此完全没有必要把这些行保留在索引里。这会减小索引尺寸,从而加快那些确实会使用该索引的查询。它也会加快很多表更新操作,因为索引并不需要在所有情况下都更新。展示了这种思路的一种可能应用。 + 使用部分索引的一个主要原因是避免索引常见值。由于搜索常见值(即占全部表行百分之几以上的值)的查询反正也不会使用索引,因此完全没有必要把这些行保留在索引里。这会减小索引尺寸,从而加快那些确实会使用该索引的查询。它也会加快很多表更新操作,因为索引并不需要在所有情况下都更新。展示了这种思路的一种可能应用。 @@ -574,7 +568,7 @@ SELECT * FROM orders WHERE order_nr = 3501; - 也说明了:索引列和谓词中使用的列不必一致。PostgreSQL支持带任意谓词的部分索引,只要其中只涉及正在建立索引的那张表的列。不过要记住,谓词必须与那些希望从该索引受益的查询中使用的条件相匹配。更准确地说,只有当系统能够识别出查询的WHERE条件在数学上蕴含该索引的谓词时,部分索引才能用于该查询。PostgreSQL并没有一个复杂的定理证明器,来识别那些写法不同但数学上等价的表达式。(不仅构建这样一个通用定理证明器极其困难,而且它很可能也会慢到失去实际用途。)系统可以识别简单的不等式蕴含,例如x < 1蕴含x < 2;否则,谓词条件必须与查询WHERE条件的某一部分完全匹配,否则索引不会被识别为可用。匹配发生在查询规划阶段,而不是运行时。因此,参数化查询子句无法与部分索引配合工作。例如,一个带参数的预备查询可能写成x < ?,而对于参数的所有可能取值,它都不可能蕴含x < 2。 + 也说明了:索引列和谓词中使用的列不必一致。PostgreSQL支持带任意谓词的部分索引,只要其中只涉及正在建立索引的那张表的列。不过要记住,谓词必须与那些希望从该索引受益的查询中使用的条件相匹配。更准确地说,只有当系统能够识别出查询的WHERE条件在数学上蕴含该索引的谓词时,部分索引才能用于该查询。PostgreSQL并没有一个复杂的定理证明器,来识别那些写法不同但数学上等价的表达式。(不仅构建这样一个通用定理证明器极其困难,而且它很可能也会慢到失去实际用途。)系统可以识别简单的不等式蕴含,例如x < 1蕴含x < 2;否则,谓词条件必须与查询WHERE条件的某一部分完全匹配,否则索引不会被识别为可用。匹配发生在查询规划阶段,而不是运行时。因此,参数化查询子句无法与部分索引配合工作。例如,一个带参数的预备查询可能写成x < ?,而它无法保证在参数的所有可能取值下都蕴含x < 2 @@ -586,7 +580,7 @@ SELECT * FROM orders WHERE order_nr = 3501; 建立一个部分唯一索引 - 假设我们有一张描述测试结果的表。我们希望确保对于给定的subjecttarget组合,只有一条成功记录,但可以有任意多条失败记录。实现方法之一如下: + 假设我们有一张描述测试结果的表。我们希望确保对于给定的测试对象和目标组合,只有一条成功记录,但可以有任意多条失败记录。实现方法之一如下: CREATE TABLE tests ( subject text, @@ -682,7 +676,7 @@ CREATE INDEX mytable_cat_data ON mytable (category, data); - 查询只能引用存储在索引中的列。例如,给定一个表,它有列xyz,而索引建立在xy上,那么下面这些查询可以使用仅索引扫描: + 查询只能引用存储在索引中的列。例如,假设某个表的xy列上有一个索引,且该表还有一列z,那么下面这些查询可以使用仅索引扫描: SELECT x, y FROM tab WHERE x = 'key'; SELECT x FROM tab WHERE x = 'key' AND y < 42; @@ -709,7 +703,7 @@ SELECT x FROM tab WHERE x = 'key' AND z < 42; INCLUDE - in index definitions + 在索引定义中 为了有效利用仅索引扫描特性,你可以选择创建一个覆盖索引,也就是专门设计来包含某一类高频查询所需列的索引。由于查询通常需要取回的列不止是用于搜索的那些列,PostgreSQL允许你创建一种索引,其中某些列只是负载,而不是搜索键的一部分。这是通过添加一个INCLUDE子句列出这些额外列来实现的。例如,如果你经常运行如下查询: @@ -777,11 +771,11 @@ SELECT target FROM tests WHERE subject = 'some-subject' AND success; 操作符类和操作符族 - operator class + 操作符类 - operator family + 操作符族 @@ -899,8 +893,8 @@ CREATE INDEX test1c_content_y_index ON test1c (content COLLATE "y"); 检查索引使用情况 - index - examining usage + 索引 + 检查使用情况 diff --git a/zh/17/information_schema.sgml b/zh/17/information_schema.sgml index dbfa1169..3f835f00 100644 --- a/zh/17/information_schema.sgml +++ b/zh/17/information_schema.sgml @@ -388,7 +388,7 @@ collation_catalog sql_identifier - 包含此属性排序规则的数据库名(总是当前数据库),如果默认或者该属性的数据类型不可排序则为空 + 包含该属性排序规则的数据库名称(总是当前数据库);如果使用默认排序规则,或该属性的数据类型不支持排序规则,则为 null。 @@ -397,7 +397,7 @@ collation_schema sql_identifier - 包含此属性排序规则的模式名,如果默认或者该属性的数据类型不可排序则为空 + 包含该属性排序规则的模式名称;如果使用默认排序规则,或该属性的数据类型不支持排序规则,则为 null。 @@ -406,7 +406,7 @@ collation_name sql_identifier - 该属性排序规则的名称,如果默认或者该属性的数据类型不可排序则为空 + 该属性排序规则的名称;如果使用默认排序规则,或该属性的数据类型不支持排序规则,则为 null。 @@ -1626,7 +1626,7 @@ collation_catalog sql_identifier - 包含此属性排序规则的数据库名(总是当前数据库),如果默认或者该属性的数据类型不可排序则为空 + 包含该列排序规则的数据库名称(总是当前数据库);如果使用默认排序规则,或该列的数据类型不支持排序规则,则为 null。 @@ -1635,7 +1635,7 @@ collation_schema sql_identifier - 该列的包含排序规则的模式名,如果默认或者该列的数据类型不可排序则为空 + 包含该列排序规则的模式名称;如果使用默认排序规则,或该列的数据类型不支持排序规则,则为 null。 @@ -1644,7 +1644,7 @@ collation_name sql_identifier - 该列的排序规则的名称,如果默认或者该列的数据类型不可排序则为空 + 该列排序规则的名称;如果使用默认排序规则,或该列的数据类型不支持排序规则,则为 null。 @@ -2385,7 +2385,7 @@ collation_catalog sql_identifier - 包含此域排序规则的数据库名(总是当前数据库),如果默认或者该域的数据类型不可排序则为空 + 包含该域排序规则的数据库名称(总是当前数据库);如果使用默认排序规则,或该域的数据类型不支持排序规则,则为 null。 @@ -2394,7 +2394,7 @@ collation_schema sql_identifier - 包含此域排序规则的模式名,如果默认或者该域的数据类型不可排序则为空 + 包含该域排序规则的模式名称;如果使用默认排序规则,或该域的数据类型不支持排序规则,则为 null。 @@ -2403,7 +2403,7 @@ collation_name sql_identifier - 该域排序规则的名称,如果默认或者该域的数据类型不可排序则为空 + 该域排序规则的名称;如果使用默认排序规则,或该域的数据类型不支持排序规则,则为 null。 @@ -2558,7 +2558,7 @@ <literal>element_types</literal> - 视图element_types包含数组元素的数据类型描述符。当一个表列、复合类型属性、域、函数参数或函数返回值被定义为一种数组类型,相应的信息模式视图只在列data_type中包含ARRAY。要获得该数组元素类型的信息,你可以连接该相应的视图和这个视图。例如,要显示一个表的列及其数据类型和数组元素类型,你可以: + 视图element_types包含数组元素的数据类型描述符。当一个表列、复合类型属性、域、函数参数或函数返回值被定义为一种数组类型时,相应的信息模式视图只在列data_type中包含ARRAY。要获得该数组元素类型的信息,你可以连接该相应的视图和这个视图。例如,要显示一个表的列及其数据类型和数组元素类型(如果适用),你可以: SELECT c.column_name, c.data_type, e.data_type AS element_type FROM information_schema.columns c LEFT JOIN information_schema.element_types e @@ -2689,7 +2689,7 @@ ORDER BY c.ordinal_position; collation_catalog sql_identifier - 包含元素类型排序规则的数据库名称(总是当前数据库), 如果默认或该元素的数据类型是不可排序的则为空 + 包含该元素类型排序规则的数据库名称(总是当前数据库);如果使用默认排序规则,或该元素类型不支持排序规则,则为 null。 @@ -2698,7 +2698,7 @@ ORDER BY c.ordinal_position; collation_schema sql_identifier - 包含元素类型排序规则的模式名称, 如果默认或该元素的数据类型是不可排序的则为空 + 包含该元素类型排序规则的模式名称;如果使用默认排序规则,或该元素类型不支持排序规则,则为 null。 @@ -2707,7 +2707,7 @@ ORDER BY c.ordinal_position; collation_name sql_identifier - 元素类型的排序规则名, 如果默认或该元素的数据类型是不可排序的则为空 + 该元素类型排序规则的名称;如果使用默认排序规则,或该元素类型不支持排序规则,则为 null。 @@ -6291,9 +6291,8 @@ ORDER BY c.ordinal_position; enforced yes_or_no - Applies to a feature not available in - PostgreSQL (currently always - YES) + 适用于PostgreSQL尚不提供的功能(当前总是 + YES @@ -7147,7 +7146,7 @@ ORDER BY c.ordinal_position; - SQL 了解两种用户定义类型:结构类型(在PostgreSQL中也称为复合类型)以及 distinct type(PostgreSQL 尚未实现)。为兼顾将来,请使用列user_defined_type_category来区分它们。其他用户定义类型,如基类型和枚举(两者都是PostgreSQL的扩展),不会在这里显示。域的相关信息见。 + SQL 中有两种用户定义类型:结构类型(在PostgreSQL中也称为复合类型)以及独立类型(distinct type,PostgreSQL 尚未实现)。为兼顾将来,请使用列user_defined_type_category来区分它们。其他用户定义类型,如基础类型和枚举(两者都是PostgreSQL的扩展),不会在这里显示。域的相关信息见 @@ -7879,7 +7878,7 @@ ORDER BY c.ordinal_position; check_optioncharacter_data - CASCADEDLOCAL 如果视图上有CHECK OPTION 定义,如果没有则为NONE。 + CASCADEDLOCAL 如果视图上有CHECK OPTION 定义,如果没有则为NONE diff --git a/zh/17/installation.sgml b/zh/17/installation.sgml index acdb3156..2b32a972 100644 --- a/zh/17/installation.sgml +++ b/zh/17/installation.sgml @@ -4,7 +4,7 @@ 从源代码安装 - installation + 安装 @@ -345,7 +345,7 @@ 使用 Autoconf 和 Make 进行构建和安装 - 简短版本 + 简要说明 @@ -362,7 +362,7 @@ su - postgres /usr/local/pgsql/bin/createdb test /usr/local/pgsql/bin/psql test - 较长版本见本其余部分。 + 详细说明见本的其余部分。 @@ -590,7 +590,7 @@ build-postgresql: <filename>configure</filename> 选项 - 配置选项 + configure 选项 @@ -1012,7 +1012,7 @@ build-postgresql: ,使用 OSSP UUID library + url="http://www.ossp.org/pkg/lib/uuid/">OSSP UUID 库 @@ -1036,13 +1036,7 @@ build-postgresql: 这一特性要求 libxml2 2.6.23 或更高版本。 - - 为了检测所需的编译器和链接器选项,如果系统已安装 - pkg-config 且知道 libxml2,PostgreSQL - 会查询 pkg-config。否则,如果找得到由 libxml2 - 安装的 xml2-config 程序,就会使用它。 - 优先使用 pkg-config,因为它能更好地处理多架构安装。 - + 为检测所需的编译器和链接器选项,PostgreSQL 会查询 pkg-config,前提是已安装该程序且其中有 libxml2 的信息。否则,如果找到 libxml2 安装的 xml2-config 程序,就会使用它。优先使用 pkg-config,因为它能更好地处理多架构安装。 如果 libxml2 安装在不常见的位置,你可以设置与 @@ -1084,7 +1078,7 @@ build-postgresql: - 反功能 + 禁用特性 本节描述的选项允许禁用某些默认会构建的 @@ -1146,18 +1140,14 @@ build-postgresql: - - 允许即使 PostgreSQL 在该平台上不支持 CPU 自旋锁,也能构建成功。缺乏自旋锁支持会导致非常差的性能;因此,只有在构建中止并提示该平台缺少自旋锁支持时,才应使用此选项。如果在你的平台上构建 PostgreSQL 需要此选项,请向 PostgreSQL 开发者报告该问题。 - + 即使 PostgreSQL 不支持该平台的 CPU 自旋锁,也允许构建成功。缺少自旋锁支持会导致性能极差;因此,仅应在构建中止并告知平台缺少自旋锁支持时使用此选项。如果在你的平台上构建 PostgreSQL 必须使用此选项,请向 PostgreSQL 开发者报告该问题。 - - 禁用 CPU 原子操作的使用。对于缺乏此类操作的平台,此选项不起作用。对于具备此类操作的平台,这会导致性能很差。此选项仅对调试或进行性能比较有用。 - + 禁用 CPU 原子操作。在不支持此类操作的平台上,此选项不产生影响。在支持的平台上,它会导致性能下降。此选项仅用于调试或性能比较。 @@ -1247,8 +1237,7 @@ build-postgresql: - 不在 PostgreSQL 的可执行文件中标记, - 使其在运行时到安装的库目录中搜索共享库(见 )。 + 不在 PostgreSQL 的可执行文件中添加指示其到安装的库目录中搜索共享库的标记(见 )。 在大多数平台上,这种标记使用库目录的绝对路径,因此如果你之后移动安装位置, 它就没有帮助了。不过这样一来,你就需要通过其他方式让可执行文件找到共享库。 通常这要求配置操作系统的动态链接器搜索该库目录;更多细节见 @@ -1265,7 +1254,7 @@ build-postgresql: 杂项 - 调整默认端口号 相当常见, + 使用 调整默认端口号相当常见, 尤其是在测试性构建中。本节中的其他选项只推荐给高级用户。 @@ -1300,10 +1289,10 @@ build-postgresql: - 设置 segment size,单位为 GB。 + 设置 段大小,单位为 GB。 大表会被分成多个操作系统文件,每个文件的大小等于段大小。 这可以避免很多平台上的文件大小限制问题。默认段大小 1GB 在所有支持的平台上 - 都是安全的。如果你的操作系统支持 largefile + 都是安全的。如果你的操作系统支持 大文件 (如今大多数都支持),你可以使用更大的段大小。 这有助于减少处理超大表时消耗的文件描述符数量。 但请注意不要选择超出你的平台和打算使用的文件系统所支持的值。 @@ -1319,7 +1308,7 @@ build-postgresql: - 设置 block size,单位为 KB。 + 设置 块大小,单位为 KB。 这是表内部存储和 I/O 的单位。默认值 8KB 适合大多数场景, 但在特殊情况下,其他取值也可能有用。 该值必须是 1 到 32(KB)之间的 2 的幂。 @@ -1333,7 +1322,7 @@ build-postgresql: - 设置 WAL block size,单位为 KB。 + 设置 WAL 块大小,单位为 KB。 这是 WAL 日志内部存储和 I/O 的单位。默认值 8KB 适合大多数场景, 但在特殊情况下,其他取值也可能有用。 该值必须是 1 到 64(KB)之间的 2 的幂。 @@ -1383,11 +1372,11 @@ build-postgresql: - 在服务器中启用 assertion 检查,用于测试许多 - 不应该发生的条件。这对代码开发非常有价值,但这些测试会显著拖慢 + 在服务器中启用 断言 检查,用于测试许多 + 不可能发生的条件。这对代码开发非常有价值,但这些测试可能会显著拖慢 服务器速度。此外,启用这些测试并不一定会增强服务器稳定性! 断言检查并未按严重程度分类,因此即使某个 bug 相对无害,只要触发了断言失败, - 仍可能导致服务器重启。该选项不建议用于生产环境,但如果你在做开发工作 + 仍会导致服务器重启。该选项不建议用于生产环境,但如果你在做开发工作 或运行测试版,就应当启用它。 @@ -1432,7 +1421,7 @@ build-postgresql: 如果使用 GCC,所有程序和库都会被编译成可进行性能分析的形式。 - 后端退出时,会创建一个子目录,其中包含带有 profile 数据的 + 后端退出时,会创建一个子目录,其中包含带有性能分析数据的 gmon.out 文件。 该选项只适用于 GCC,并且仅在开发工作中使用。 @@ -1508,7 +1497,7 @@ build-postgresql: <filename>configure</filename> 环境变量 - configure environment variables + configure 环境变量 @@ -1575,7 +1564,7 @@ build-postgresql: 在使用 --with-llvm 编译时, - 用于处理源代码以内联的 clang 程序路径 + 用于处理源代码以进行内联的 clang 程序路径 @@ -1733,21 +1722,9 @@ build-postgresql: - - 有时,在事后把额外的编译器标志加入到 - configure 选定的那组选项中会很有用。 - 一个重要例子是,gcc - 不能包含在传给 configureCFLAGS 中, - 因为这会破坏 configure 的很多内置测试。 - 要添加这类标志,请在运行 make 时把它们放入环境变量 - COPTCOPT 的内容会被附加到 - configure 设置好的 CFLAGS 和 - LDFLAGS 上。例如,你可以这样做: - + 有时,事后补充编译器标志会很有用;原有标志由 configure 选定。一个重要的例子是 gcc 选项不能包含在以下变量中:CFLAGS(该变量会传给 configure),因为它会破坏 configure 的许多内置测试。要添加此类标志,请将其放入 COPT 环境变量,再运行 makeCOPT 的内容会被加入以下两组选项:CFLAGSLDFLAGS;这两组选项原本由以下程序设置:configure。例如,你可以执行: make COPT='-Werror' - - 或者: - +或者: export COPT='-Werror' make @@ -1779,7 +1756,7 @@ build-postgresql: 使用 Meson 构建和安装 - 简短版本 + 简要说明 @@ -1797,7 +1774,7 @@ su - postgres /usr/local/pgsql/bin/createdb test /usr/local/pgsql/bin/psql test - 较长版本见本其余部分。 + 详细说明见本的其余部分。 @@ -2322,11 +2299,11 @@ ninja install - 构建 模块 - (它提供生成 UUID 的函数),并使用指定的 UUID 库。 - UUID - LIBRARY 必须是以下之一: - + 构建 模块 + (它提供生成 UUID 的函数),并使用指定的 UUID 库。 + UUID + LIBRARY 必须是以下之一: + @@ -2334,21 +2311,21 @@ ninja install - - ,使用 FreeBSD 以及其他某些 BSD 衍生系统中的 UUID 函数 - - + + ,使用 FreeBSD 以及其他某些 BSD 衍生系统中的 UUID 函数 + + - - ,使用 e2fsprogs 项目创建的 UUID 库; - 该库存在于大多数 Linux 系统和 macOS 中,也可用于其他平台 - - + + ,使用 e2fsprogs 项目创建的 UUID 库; + 该库存在于大多数 Linux 系统和 macOS 中,也可用于其他平台 + + - ,使用 OSSP UUID library - + ,使用 OSSP UUID 库 + @@ -2396,7 +2373,7 @@ ninja install - 反功能 + 禁用特性 @@ -2443,7 +2420,7 @@ ninja install - 该选项默认值是 true;将其设为 false 可以让构建在平台不支持 CPU 自旋锁时仍然成功。缺乏自旋锁支持会导致非常差的性能;因此,只有在构建中止并提示该平台缺少自旋锁支持时,才应修改此选项。如果在你的平台上构建 PostgreSQL 需要把该选项设为 false,请向 PostgreSQL 开发者报告该问题。 + 该选项默认值是 true;将其设为 false 时,即使 PostgreSQL 不支持该平台的 CPU 自旋锁,也允许构建成功。缺乏自旋锁支持会导致非常差的性能;因此,只有在构建中止并提示该平台缺少自旋锁支持时,才应修改此选项。如果在你的平台上构建 PostgreSQL 需要把该选项设为 false,请向 PostgreSQL 开发者报告该问题。 @@ -2456,7 +2433,6 @@ ninja install - @@ -2470,7 +2446,7 @@ ninja install 设置这个选项,可以覆盖所有 auto 特性的取值 (也就是那些在找到所需软件时会自动启用的特性)。 - 当你想一次性禁用或启用所有 optional 特性, + 当你想一次性禁用或启用所有 可选 特性, 而不必逐个手工设置时,这会很有用。 该参数的默认值是 auto。 @@ -2586,9 +2562,8 @@ ninja install - 该选项默认值是 true。如果设为 false,则不会在 - PostgreSQL 的可执行文件中标记, - 使其在运行时到安装的库目录中搜索共享库(见 )。 + 该选项默认值是 true。如果设为 false,则不在 + PostgreSQL 的可执行文件中添加指示其到安装的库目录中搜索共享库的标记(见 )。 在大多数平台上,这种标记使用库目录的绝对路径,因此如果你之后移动安装位置, 它就没有帮助了。不过这样一来,你就需要通过其他方式让可执行文件找到共享库。 通常这要求配置操作系统的动态链接器搜索该库目录;更多细节见 @@ -2689,10 +2664,10 @@ ninja install - 设置 segment size,单位为 GB。 + 设置 段大小,单位为 GB。 大表会被分成多个操作系统文件,每个文件的大小等于段大小。 这可以避免很多平台上的文件大小限制问题。默认段大小 1GB 在所有支持的平台上 - 都是安全的。如果你的操作系统支持 largefile + 都是安全的。如果你的操作系统支持 大文件 (如今大多数都支持),你可以使用更大的段大小。 这有助于减少处理超大表时消耗的文件描述符数量。 但请注意不要选择超出你的平台和打算使用的文件系统所支持的值。 @@ -2706,7 +2681,7 @@ ninja install - 设置 block size,单位为 KB。 + 设置 块大小,单位为 KB。 这是表内部存储和 I/O 的单位。默认值 8KB 适合大多数场景, 但在特殊情况下,其他取值也可能有用。 该值必须是 1 到 32(KB)之间的 2 的幂。 @@ -2718,7 +2693,7 @@ ninja install - 设置 WAL block size,单位为 KB。 + 设置 WAL 块大小,单位为 KB。 这是 WAL 日志内部存储和 I/O 的单位。默认值 8KB 适合大多数场景, 但在特殊情况下,其他取值也可能有用。 该值必须是 1 到 64(KB)之间的 2 的幂。 @@ -2804,11 +2779,11 @@ ninja install - 在服务器中启用 assertion 检查,用于测试许多 - 不应该发生的条件。这对代码开发非常有价值,但这些测试会显著拖慢 + 在服务器中启用 断言 检查,用于测试许多 + 不可能发生的条件。这对代码开发非常有价值,但这些测试会显著拖慢 服务器速度。此外,启用这些测试并不一定会增强服务器稳定性! 断言检查并未按严重程度分类,因此即使某个 bug 相对无害,只要触发了断言失败, - 仍可能导致服务器重启。该选项不建议用于生产环境,但如果你在做开发工作 + 仍会导致服务器重启。该选项不建议用于生产环境,但如果你在做开发工作 或运行测试版,就应当启用它。 @@ -2828,12 +2803,7 @@ ninja install - - 启用额外测试套件;这些测试默认不会运行,因为它们不适合在多用户系统上运行、 - 需要特殊软件,或者资源消耗较大。该参数是以空白分隔的测试名称列表。 - 详见 。如果在运行测试时设置了 - PG_TEST_EXTRA 环境变量,那么它会覆盖这个构建时选项。 - + 启用运行时需要特殊软件的测试套件。该选项通过以空白分隔的列表接受参数。详见 @@ -3067,11 +3037,7 @@ export MANPATH 成员机器,以便持续确保兼容性。 - - 一般来说,可以预期 PostgreSQL 能在以下 CPU - 架构上工作:x86、PowerPC、S/390、SPARC、ARM、MIPS 和 RISC-V, - 以及在适用情况下的大端、小端、32 位和 64 位变体。 - + 一般来说,可以预期 PostgreSQL 能在以下 CPU 架构上工作:x86、PowerPC、S/390、SPARC、ARM、MIPS、RISC-V 和 PA-RISC,以及在适用情况下的大端、小端、32 位和 64 位变体。对于不受支持的 CPU 类型,通常可以通过配置 来构建,但性能会很差。 可以预期 PostgreSQL 能在这些操作系统的当前版本上工作: @@ -3092,7 +3058,7 @@ export MANPATH 历史版本的 PostgreSQL 或 POSTGRES 也曾运行在 - Alpha、Itanium、M32R、M68K、M88K、NS32K、PA-RISC、SuperH 和 VAX 等 + Alpha、Itanium、M32R、M68K、M88K、NS32K、SuperH 和 VAX 等 CPU 架构上,以及 4.3BSD、AIX、BEOS、BSD/OS、DG/UX、Dynix、HP-UX、IRIX、 NeXTSTEP、QNX、SCO、SINIX、Sprite、SunOS、Tru64 UNIX 和 ULTRIX 等 操作系统上。 @@ -3141,14 +3107,14 @@ export MANPATH 不支持 adduser 命令;请使用 Windows 中相应的 - 用户管理应用。除此之外,跳过这一步即可。 + 用户管理应用。也可以跳过这一步。 不支持 su 命令;请在 Windows 上使用 ssh 来模拟 su。 - 除此之外,跳过这一步即可。 + 也可以跳过这一步。 @@ -3179,16 +3145,11 @@ export MANPATH - - 并行回归测试(make check)可能会因为 - listen() backlog 队列溢出而产生伪造的回归测试失败, - 进而导致连接拒绝错误或挂起。你可以像下面这样使用 make 变量 - MAX_CONNECTIONS 来限制连接数: + 并行回归测试(make check)可能因 listen() 的待处理连接队列溢出而误报回归测试失败;队列溢出会导致连接被拒绝的错误或挂起。可以使用 make 变量 MAX_CONNECTIONS 限制连接数,方法如下: make MAX_CONNECTIONS=5 check - (在某些系统上,同时连接数大致最多可达到 10 个。) - +(在某些系统上,并发连接数最高可达约 10 个。) @@ -3261,7 +3222,7 @@ xcrun --show-sdk-path macOS 的 - System Integrity Protection(SIP)特性会破坏 + 系统完整性保护(SIP)特性会破坏 make check,因为它会阻止把所需的 DYLD_LIBRARY_PATH 设置传递给被测试的可执行文件。 你可以通过在 make check 之前先执行 @@ -3278,11 +3239,13 @@ xcrun --show-sdk-path 在其上安装 - - 可以使用 MinGW 这个 Windows 上的类 Unix 构建环境来构建 Windows 版 - PostgreSQL。推荐为此使用 MSYS2 环境,并安装所需的前置软件包。 - + Windows 版 PostgreSQL 可以使用 MinGW(用于 Microsoft 操作系统的类 Unix 构建环境)构建。MinGW 构建过程使用本章介绍的常规构建系统。 + + 可以从 下载 MinGW 这一类 Unix 构建工具,以及 MSYS 这一运行 configure 等 shell 脚本所需的 Unix 工具集。运行生成的二进制文件不需要它们;只有创建二进制文件时才需要。 + + 要使用 MinGW 构建 64 位二进制文件,请从 安装 64 位工具集,将其 bin 目录放入 PATH,并使用 --host=x86_64-w64-mingw32 选项运行 configure + + 安装好所有组件后,建议在 CMD.EXE 下运行 psql,因为 MSYS 控制台存在缓冲问题。 收集崩溃转储 @@ -3327,7 +3290,7 @@ xcrun --show-sdk-path 你可以从 下载 Sun Studio。许多 GNU 工具已经集成到 Solaris 10 中, - 或者包含在 Solaris companion CD 中。如果你需要适用于较旧 Solaris 版本的 + 或者包含在 Solaris 配套光盘中。如果你需要适用于较旧 Solaris 版本的 软件包,可以到 查找这些工具。 如果你更想要源码,请看 。 @@ -3335,10 +3298,10 @@ xcrun --show-sdk-path - configure 抱怨测试程序失败 + configure 报告测试程序失败 - 如果 configure 抱怨某个测试程序失败, + 如果 configure 报告某个测试程序失败, 这多半是因为运行时链接器找不到某些库,通常是 libz、libreadline, 或其他非标准库如 libssl。要把它指向正确位置,请在 configure 命令行中设置环境变量 LDFLAGS, @@ -3488,11 +3451,20 @@ make: *** [postgres] Error 1 BisonFlex + 需要 BisonFlex。只有 Bison 2.3 及更高版本可用。Flex 必须为 2.5.35 或更高版本。 + - BisonFlex - 的二进制文件可以从 下载。 + BisonFlex都包含在msys工具套件中,可从获取,它是MinGW编译器套件的一部分。 + + + 需要将包含 flex.exebison.exe 的目录加入 PATH 环境变量。对于 MinGW,该目录是 MinGW 安装目录下的 \msys\1.0\bin 子目录。 + + + + 来自 GnuWin32 的 Bison 发行版似乎存在一个 bug:如果安装在名称中含有空格的目录中,Bison 就会工作异常,例如英文安装中的默认位置C:\Program Files\GnuWin32。请考虑安装到C:\GnuWin32,或者在 PATH 环境设置中使用指向 GnuWin32 的 NTFS 短文件名路径(例如C:\PROGRA~1\GnuWin32)。 + + diff --git a/zh/17/libpq.sgml b/zh/17/libpq.sgml index dec70c30..438d2407 100644 --- a/zh/17/libpq.sgml +++ b/zh/17/libpq.sgml @@ -43,7 +43,7 @@ - 如果不可信用户能够访问一个没有采用模式的安全使用方式的数据库,那么每个会话开始时都应从 search_path 中移除公开可写的模式。可以把参数关键字 options 设置为 -csearch_path=。也可以在连接后发出 PQexec(conn, "SELECT pg_catalog.set_config('search_path', '', false)")。这种考虑并非专门针对 libpq;它适用于每一种可执行任意 SQL 命令的接口。 + 如果不受信任的用户能够访问一个没有采用模式的安全使用方式的数据库,那么每个会话开始时都应从search_path中移除公开可写的模式。可以把参数关键词options设置为-csearch_path=。也可以在连接后发出PQexec(conn, "SELECT pg_catalog.set_config('search_path', '', false)")。这种考虑并非专门针对libpq;它适用于每一种可执行任意 SQL 命令的接口。 @@ -182,7 +182,7 @@ PGconn *PQsetdb(char *pghost, PQconnectStartParamsPQconnectStartParams PQconnectStartPQconnectStart - PQconnectPollPQconnectPoll + PQconnectPollPQconnectPoll nonblocking connection @@ -216,7 +216,7 @@ PostgresPollingStatusType PQconnectPoll(PGconn *conn); - hostaddrhost参数必须被合适地使用,以防止做DNS查询。详见中这些参数的文档。 + 必须正确使用 hostaddr 参数,以避免执行 DNS 查询。详细信息请参见中该参数的说明。 @@ -291,11 +291,12 @@ PostgresPollingStatusType PQconnectPoll(PGconn *conn); - - CONNECTION_SETENV + + + CONNECTION_GSS_STARTUP - 协商环境驱动的参数设置。 + 协商 GSS 加密。 @@ -309,6 +310,15 @@ PostgresPollingStatusType PQconnectPoll(PGconn *conn); + + CONNECTION_CHECK_STANDBY + + + 检查连接的服务器是否处于备用模式。 + + + + CONNECTION_CONSUME @@ -353,8 +363,8 @@ switch(PQstatus(conn)) PQsocketPollPQsocketPoll - 轮询通过取得的连接底层套接字描述符。 - 该函数的主要用途,是驱动文档中描述的连接序列。 + 非阻塞连接 + 轮询通过取得的连接底层套接字描述符。此函数主要用于逐步执行文档中描述的连接过程。 typedef pg_int64 pg_usec_time_t; @@ -364,33 +374,19 @@ int PQsocketPoll(int sock, int forRead, int forWrite, - 该函数会轮询一个文件描述符,并且可选地设置超时。 - 如果forRead非零,则当套接字可读时返回; - 如果forWrite非零,则当套接字可写时返回。 + 此函数对文件描述符进行轮询,并可选择设置超时。如果forRead非零,则在套接字可读时结束。如果forWrite非零,则在套接字可写时结束。 - 超时由end_time指定,它表示停止等待的时间点, - 单位为自 Unix 纪元以来的微秒数(也就是 time_t 乘以 100 万)。 - 如果end_time-1,则无限等待。 - 如果end_time0(或者任何早于当前时间的值), - 则立即超时而不阻塞。底层系统调用的精度可能达不到微秒级,因此实际等待时间可能并不精确。 + 超时由end_time指定,它表示停止等待的时刻,以自 Unix 纪元以来的微秒数表示(即time_t乘以一百万)。如果end_time-1,则无限等待。如果 end_time 为0(或任何早于当前时刻的时间),则立即超时(不阻塞)。将所需的微秒数加到的结果上,即可方便地计算超时值。注意,底层系统调用的精度可能低于微秒,因此实际延迟可能不精确。 - 如果满足指定条件,该函数返回大于 0 的值;如果发生超时,返回 - 0;如果出错,返回 -1。可以通过检查 - errno(3) 来取得错误信息。如果 - forReadforWrite都为零, - 则该函数会立即返回超时指示。 + 如果满足指定条件,函数返回大于0的值;如果发生超时,返回0;如果发生错误,返回-1。可以通过检查errno(3)的值获取错误信息。如果forReadforWrite都为零,函数会立即返回超时指示。 - PQsocketPoll通过poll(2)或 - select(2)实现,具体取决于平台。更多信息请参见 - poll(2)中的POLLINPOLLOUT, - 或者select(2)中的readfds和 - writefds。 + PQsocketPoll根据平台使用poll(2)select(2)实现。更多信息请参见poll(2)中的POLLINPOLLOUT,或select(2)中的readfdswritefds @@ -827,7 +823,7 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname 参数关键词 - 目前被识别的参数关键字包括: + 目前被识别的参数关键字包括: @@ -1091,7 +1087,7 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname - 指定连接开始时发送到服务器的命令行选项。例如,将其设置为-c geqo=off会把会话的geqo参数值设为off。 + 指定连接开始时发送到服务器的命令行选项。例如,将其设置为-c geqo=off--geqo=off会把会话的geqo参数值设为off。 此字符串中的空格被视为分隔命令行参数,除非用反斜杠(\)转义;写\\表示字面上的反斜杠。 有关可用选项的详细讨论,请参阅 @@ -1535,12 +1531,20 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname sslrootcert - - 这个参数指定一个包含SSL证书颁发机构(CA)证书的文件名。 - 如果文件存在,服务器的证书将被验证是否由这些机构之一签名。 - 默认值是~/.postgresql/root.crt。 + 此参数指定包含 SSL 证书颁发机构(CA)证书的文件名。如果文件存在,则会验证服务器证书是否由这些机构之一签名。默认值为~/.postgresql/root.crt + + 也可以指定特殊值system,此时会加载 SSL 实现提供的受信任 CA 根证书。这些根证书的确切位置因 SSL 实现和平台而异。对于OpenSSL,还可以通过SSL_CERT_DIRSSL_CERT_FILE环境变量进一步修改这些位置。 + + + + 使用sslrootcert=system时,默认的sslmode会改为verify-full,任何较弱的设置都会引发错误。在大多数情况下,任何人都很容易为其控制的主机名获取受系统信任的证书,因此verify-ca及所有更弱的模式都无法发挥作用。 + + + 特殊值system优先于同名的本地证书文件。如果遇到这种情况,请改用其他路径,例如sslrootcert=./system。 + + @@ -1857,7 +1861,7 @@ char *PQpass(const PGconn *conn); 将返回连接参数中指定的密码,如果连接参数中没有密码并且能从密码文件中得到密码,则它将返回得到的密码。 - 在后一种情况中,如果连接参数中指定了多个主机,在连接被建立之前都不能依赖的结果。连接的状态可以用函数检查。 + 在后一种情况中,如果连接参数中指定了多个主机,在连接被建立之前都不能依赖的结果。连接的状态可以用函数检查。 @@ -2011,46 +2015,43 @@ PGTransactionStatusType PQtransactionStatus(const PGconn *conn); - 查找服务器的一个当前参数设置。 + 查找服务器某个参数的当前设置。 const char *PQparameterStatus(const PGconn *conn, const char *paramName); - 某一参数值会被服务器在连接开始或值改变时自动报告。可以被用来询问这些设置。它为已知的参数返回当前值,为未知的参数返回NULL。 + 服务器会在连接启动时,以及某些参数值发生变化时,自动报告这些参数值。可用于查询这些设置。如果已知该参数,则返回其当前值;如果未知,则返回NULL - 自当前发布开始会被报告的参数包括 - server_version、 - server_encoding、 - client_encoding、 - application_name、 - default_transaction_read_only, - in_hot_standby, - is_superuser、 - session_authorization、 - DateStyle、 - IntervalStyle、 - TimeZone、 - integer_datetimes以及 - standard_conforming_strings。 - (server_encodingTimeZone以及integer_datetimes在 8.0 以前的发布中不被报告; - standard_conforming_strings在 8.1 以前的发布中不被报告; - IntervalStyle在 8.4 以前的发布中不被报告; - application_name在 9.0 以前的发布中不被报告; - default_transaction_read_onlyin_hot_standby 在14以前的发布中不被报告) - 注意 server_version、 - server_encoding以及 - integer_datetimes在启动之后无法改变。 + 当前版本报告的参数包括: + + application_name + client_encoding + DateStyle + default_transaction_read_only + in_hot_standby + integer_datetimes + IntervalStyle + is_superuser + scram_iterations + server_encoding + server_version + session_authorization + standard_conforming_strings + TimeZone + + (14 之前的版本不报告 default_transaction_read_onlyin_hot_standby;16 之前的版本不报告 scram_iterations。) + 注意,server_versionserver_encodinginteger_datetimes 在启动后不能改变。 - 如果没有为standard_conforming_strings报告值,应用能假设它是off,也就是说反斜线会被视为字符串中的转义。还有,这个参数的存在可以被作为转义字符串语法(E'...')被接受的指示。 + 如果服务器未报告standard_conforming_strings的值,应用程序可以假定其为off,即反斜杠在字符串字面量中被视为转义字符。此外,服务器报告此参数也表明它接受转义字符串语法(E'...')。 - 尽管被返回的指针被声明成const,它事实上指向与PGconn结构体相关的可变存储。假定该指针在存储之间保持有效是不明智的。 + 返回的指针虽然被声明为const,但实际上指向与PGconn结构体关联的可变存储。不能假定该指针在执行其他查询后仍然有效。 @@ -2185,6 +2186,22 @@ int PQconnectionUsedPassword(const PGconn *conn); + + + PQconnectionUsedGSSAPIPQconnectionUsedGSSAPI + + + 如果连接的认证方法使用了 GSSAPI,则返回真(1);否则返回假(0)。 + +int PQconnectionUsedGSSAPI(const PGconn *conn); + + + + + 此函数可用于检测连接是否使用 GSSAPI 进行了认证。 + + + @@ -2269,6 +2286,14 @@ const char *PQsslAttribute(const PGconn *conn, const char *attribute_name); + + alpn + + + TLS 应用层协议协商(ALPN)扩展选定的应用协议。libpq 唯一支持的协议是 postgresql,因此该属性主要用于检查服务器是否支持 ALPN。如果未使用 ALPN,则为空字符串。 + + + @@ -2285,13 +2310,16 @@ const char *PQsslAttribute(const PGconn *conn, const char *attribute_name); PQsslAttributeNamesPQsslAttributeNames - - 返回可用的SSL属性名称数组。 - 数组以NULL指针结尾。 + 返回可用于 PQsslAttribute() 的 SSL 属性名称数组。数组以 NULL 指针结尾。 const char * const * PQsslAttributeNames(const PGconn *conn); + + + + + 如果 conn 为 NULL,则返回默认 SSL 库可用的属性;如果 libpq 编译时未启用任何 SSL 支持,则返回空列表。如果 conn 不为 NULL,则返回该连接所用 SSL 库可用的属性;如果连接未加密,则返回空列表。 @@ -2471,7 +2499,7 @@ PGresult *PQexecParams(PGconn *conn, paramTypes[] - 通过 OID 指定要赋予给参数符号的数据类型。如果paramTypesNULL或者该数组中任何特定元素为零,服务器会用对待未知类型文字串的方式为参数符号推测一种数据类型。 + 通过 OID 指定要赋予给参数符号的数据类型。如果paramTypesNULL或者该数组中任何特定元素为零,服务器会用对待未指定类型的字符串字面量的方式为参数符号推测一种数据类型。 @@ -2565,10 +2593,10 @@ PGresult *PQprepare(PGconn *conn, 该函数从query串创建一个名为stmtName的预备语句,该串必须包含一个单一 SQL 命令。 stmtName可以是""来创建一个未命名语句,在这种情况下任何已存在未命名语句将被自动替换。 - 如果语句名称已经在当前会话中被定义,则是一种错误。如果使用了任何参数,它们在查询中以$1$2等引用。 + 否则,如果语句名称已经在当前会话中被定义,则是一种错误。如果使用了任何参数,它们在查询中以$1$2等引用。 nParams是参数的个数,其类型在数组paramTypes[]中被预先指定(当nParams为零时,该数组指针可以是NULL)。 paramTypes[]通过 OID 指定要赋予给参数符号的数据类型。 - 如果paramTypesNULL或者该数组中任何特定元素为零,服务器会用对待未知类型文字串的方式为参数符号推测一种数据类型。 + 如果paramTypesNULL或者该数组中任何特定元素为零,服务器会用对待未指定类型的字符串字面量的方式为参数符号推测一种数据类型。 还有,查询能够使用编号高于nParams的参数符号,它们的数据类型也会被自动推测(找出推测出的数据类型的方法见)。 @@ -2581,7 +2609,6 @@ PGresult *PQprepare(PGconn *conn, 用于的预备语句也能通过执行 SQL 语句来创建。 - 还有,尽管没有libpq函数来删除一个预备语句,SQL 语句可被用于此目的。 @@ -2829,13 +2856,21 @@ ExecStatusType PQresultStatus(const PGresult *res); - + + PGRES_TUPLES_CHUNK + + + PGresult包含当前命令返回的若干结果元组。此状态仅在为查询选择了分块模式时出现(参见)。元组数不会超过传递给的上限。 + + + + + PGRES_PIPELINE_SYNC - PGresult表示管道模式中的同步点,由请求。 - 此状态仅在选择管道模式时发生。 - + PGresult 表示管道模式中的同步点,由 请求。此状态仅在已选择管道模式时出现。 + @@ -2978,7 +3013,7 @@ char *PQresultErrorField(const PGresult *res, int fieldcode); PG_DIAG_MESSAGE_DETAIL - 细节:一个可选的次级错误消息,它携带了关于问题的等多细节。可能有多行。 + 细节:一个可选的次级错误消息,它携带了关于问题的更多细节。可能有多行。 @@ -2996,7 +3031,7 @@ char *PQresultErrorField(const PGresult *res, int fieldcode); PG_DIAG_STATEMENT_POSITION - 包含一个十进制整数的字符串,它表示一个错误游标位置,该位置是原始语句字符串的索引。第一个字符的索引是 1,位置以字符计算而不是以及字节计算。 + 包含一个十进制整数的字符串,它表示一个错误游标位置,该位置是原始语句字符串的索引。第一个字符的索引是 1,位置以字符计算而不是以字节计算。 @@ -3790,8 +3825,8 @@ unsigned char *PQescapeByteaConn(PGconn *conn, - 当某些字节值被用作一个SQL语句中的bytea文字的一部分时,它们必须被转义。 - 转义使用十六进制编码或反斜线转义的字节。详见。 + 当某些字节值被用作一个SQL语句中的bytea字面量的一部分时,它们必须被转义。 + 使用十六进制编码或反斜杠转义来转义这些字节。详见 @@ -3841,7 +3876,8 @@ unsigned char *PQescapeBytea(const unsigned char *from, - 将二进制数据的一个字符串表示转换成二进制数据 — 它是的逆向函数。当检索文本格式的bytea数据时,需要这个函数,但检索二进制个事时则不需要它。 + 将二进制数据的字符串表示转换为二进制数据,这是的逆操作。 + 以文本格式取得bytea数据时需要此操作;以二进制格式取得时则不需要。 unsigned char *PQunescapeBytea(const unsigned char *from, size_t *to_length); @@ -3849,14 +3885,15 @@ unsigned char *PQunescapeBytea(const unsigned char *from, size_t *to_length); - from参数指向一个字符串,例如被应用到一个bytea列上所返回的。 - 把这个串表示转换成它的二进制表示。 - 它返回一个指向用malloc()分配的缓冲区的指针,在错误时返回NULL,并且把缓冲区的尺寸放在to_length中。 - 当结果不再需要时,它必须使用释放。 + from参数指向一个字符串,例如对bytea列调用时返回的字符串。 + 将这个字符串表示转换为二进制表示。 + 它返回指向通过malloc()分配的缓冲区的指针,出错时返回NULL,并将缓冲区大小存入to_length。 + 不再需要结果时,必须使用释放它。 - 这种转换并不完全是PQescapeBytea的逆函数,因为当从PQgetvalue接收到字符串时,我们并不能期待它被转义。特别地这意味着不需要考虑字符串引用,并且因此也不需要一个参数。 + 此转换并不完全是的逆操作,因为从收到的字符串并非经过转义的形式。 + 具体而言,这意味着无需考虑字符串引号,因此也不需要PGconn参数。 @@ -3905,26 +3942,17 @@ unsigned char *PQunescapeBytea(const unsigned char *from, size_t *to_length); - - 不喜欢这些限制的应用程序可以使用构建自的底层函数: - 。 - 还有 - , - , - , - , - , - 以及 - , - 它们可以与配合使用,分别复制 - , - , - , - , - , - 和 - - 的功能。 + 如果应用程序不希望受到这些限制,可以改用构成的底层函数:。此外,还有, + , + , + , + , + ,以及,它们可以与配合使用,分别实现以下函数的功能:, + , + , + , + , + ,以及 @@ -4099,15 +4127,16 @@ int PQsendClosePortal(PGconn *conn, const char *portalName); - 等待来自先前的、 + 等待先前的 、 - 或 - - 调用的下一个结果,并返回它。 - 当命令完成且不会再有更多结果时,将返回空指针。 + 、 + 、 + 、 + 或 + 调用产生的下一个结果,并返回该结果。当命令执行完毕且不再有其他结果时,返回空指针。 PGresult *PQgetResult(PGconn *conn); @@ -4211,7 +4240,7 @@ int PQisBusy(PGconn *conn); 一个使用/的客户端也可以尝试取消一个正在被服务器处理的命令,见。 - 但是,不管的返回值是什么,应用都必须继续使用进行正常的结果读取序列。一次成功的取消只会导致命令比不取消时更快终止。 + 但是,不管的返回值是什么,应用都必须继续使用进行正常的结果读取序列。一次成功的取消只会导致命令比不取消时更快终止。 @@ -4375,68 +4404,42 @@ int PQflush(PGconn *conn); - 发出查询 - 进入管道模式后,应用程序使用或其姊妹函数来分派请求。 - 这些请求在客户端排队,直到刷新到服务器端;当使用建立管道中的同步点时,或者调用时,会发生这种情况。 - 函数在管道模式下也可以工作。 - 结果处理如下所述。 + 进入管道模式后,应用程序使用 或其处理预备查询的对应函数 发送请求。这些请求在客户端排队,直到发送到服务器;使用 在管道中建立同步点,或调用 时会发送它们。函数 、&zwsp;、&zwsp;、&zwsp; 也可用于管道模式。结果处理方式见下文。 - 服务器执行语句,并返回结果,按客户端发送它们的顺序。 - 服务器将立即开始执行管道中的命令,不等待管道的结束。 - 注意,结果被缓冲在服务器端;当使用PQpipelineSync建立同步点时,或者PQsendFlushRequest被调用时,服务器会刷新该缓冲区。 - 如果任何语句遇到错误,服务器将中止当前事务,并且不执行队列中的任何后续命令,直到下一个同步点;对于每一个这样的命令都会产生一个PGRES_PIPELINE_ABORTED结果。 - (即使管道中的命令将回滚事务,依然如此。) - 查询处理在同步点之后恢复。 + 服务器按客户端发送的顺序执行语句并返回结果。服务器会立即开始执行管道中的命令,无需等待管道结束。结果会缓存在服务器端;使用 PQpipelineSyncPQsendPipelineSync 建立同步点,或调用 PQsendFlushRequest 时,服务器会发送该缓冲区中的数据。如果任何语句发生错误,服务器会中止当前事务,并停止执行队列中的后续命令,直到下一个同步点;每条被跳过的命令都会产生一个 PGRES_PIPELINE_ABORTED 结果。(即使管道中的命令会回滚事务,也仍然如此。)到达同步点后,查询处理恢复。 - 一个操作依赖于前一个操作的结果是没问题的; - 例如,一个查询可以定义一个同一管道中的下一个查询将用到的表。 - 类似地,应用可以创建一个命名的预备语句,并在同一管道中与后续语句一起执行它。 + 一个操作可以依赖先前操作的结果;例如,一个查询可以定义一张表,供同一管道中的下一个查询使用。类似地,应用程序可以创建命名的预备语句,并通过同一管道中后续的语句执行它。 - 处理结果 - 为了在管道中处理一个查询的结果,应用重复调用PQgetResult并处理每个结果,直到PQgetResult返回空。 - 可以再次使用PQgetResult检索管道中下一个查询的结果,并且循环重复 - 应用像通常一样处理单个语句结果。 - 当管道中所有查询的结果都返回时,PQgetResult返回一个结果,其包含状态值PGRES_PIPELINE_SYNC。 - - - - 客户端可以选择延迟结果处理,直到完整的管道被发送,或者与管道中发送的更多的查询交错在一起;参见。 + 要处理管道中一个查询的结果,应用程序应重复调用 PQgetResult 并处理每个结果,直到 PQgetResult 返回空指针。然后再次调用 PQgetResult 获取管道中下一个查询的结果,重复这一过程。应用程序按通常方式处理各条语句的结果。当管道中所有查询的结果都已返回时,PQgetResult 会返回一个包含状态值 PGRES_PIPELINE_SYNC 的结果。 - 要进入单行模式,在使用PQgetResult检索结果之前调用PQsetSingleRowMode。 - 此模式选择仅对当前处理的查询有效。 - 有关使用PQsetSingleRowMode的更多信息,请参阅。 + 客户端可以等到整条管道发送完毕后再处理结果,也可以在继续发送管道中的查询时交错处理结果;参见 - PQgetResult行为与普通异步处理相同,除了它可能包含新的PGresult类型PGRES_PIPELINE_SYNCPGRES_PIPELINE_ABORTED。 - 对于每个在管道中相应的点的PQpipelineSyncPGRES_PIPELINE_SYNC确定报告一次。 - PGRES_PIPELINE_ABORTED在第一个错误和所有后续结果的正常查询结果中发出,直到下一个PGRES_PIPELINE_SYNC;参见。 + PQgetResult 的行为与普通异步处理相同,只是返回结果可能具有新的 PGresult 类型 PGRES_PIPELINE_SYNCPGRES_PIPELINE_ABORTED。对于每次 PQpipelineSyncPQsendPipelineSync 调用,都会在管道中的对应位置恰好报告一次 PGRES_PIPELINE_SYNC。对于第一个错误及其后的所有结果,会用 PGRES_PIPELINE_ABORTED 代替正常查询结果,直到下一个 PGRES_PIPELINE_SYNC;参见 - PQisBusyPQconsumeInput、等正常操作,在处理管道结果时。 - 特别是,在管道中间调用PQisBusy 时,如果到目前为止发出的所有查询的结果都已被消耗,则返回0。 + PQisBusyPQconsumeInput 等函数在处理管道结果时照常工作。特别地,在管道处理过程中调用 PQisBusy 时,如果到目前为止已发出查询的所有结果均已被消费,则返回 0。 - libpq不向应用提供有关当前正在处理的查询的任何信息(除了PQgetResult返回空,以表示我们开始返回下一个查询的结果)。 - 应用必须保持跟踪它发送查询的顺序,以将它们与相应的结果相关联。 - 应用通常会为此使用状态机或FIFO队列。 + libpq 不向应用程序提供当前正在处理哪个查询的信息(除了 PQgetResult 返回空指针,表示开始返回下一个查询的结果)。应用程序必须跟踪查询的发送顺序,以便将查询与对应结果关联起来。应用程序通常会使用状态机或 FIFO 队列实现这一点。 @@ -4483,7 +4486,7 @@ int PQflush(PGconn *conn); 客户端应用通常应该维护一个尚未分派的工作队列和一个已分派但尚未处理结果的工作队列。 当套接字是可写时,它将可以分派更多的工作。 当套接字是可读时,它将读取结果并处理它们,将它们匹配到相应结果队列中的下一个条目。 - 基于可用内存,来自套接字的结果将被经常读取:这里不需要等到管道结束才读取结果。 + 基于可用内存,来自套接字的结果将被经常读取:这里不需要等到管道结束才读取结果。 管道将范围涵盖到工作的逻辑单元,通常(但不是必然)每个管道一个事务。 在管道之间,不需要退出管道模式再重新进入管道模式,也不需要等待一个管道结束后再发送下一个。 @@ -4514,7 +4517,7 @@ PGpipelineStatus PQpipelineStatus(const PGconn *conn); - PQpipelineStatus 可以返回下列值中的一个: + PQpipelineStatus 可以返回下列值中的一个: @@ -4658,8 +4661,8 @@ int PQsendFlushRequest(PGconn *conn); - 当PQpipelineSync被调用的结果,或者在非管道模式下的任何请求时,服务器自动刷新它的输出缓冲区;这个函数用于使得服务器在不建立同步点的情况下以管道模式刷新其输出缓冲区。 - 请注意,请求不是自身能自动刷新到服务器;如果需要时使用PQflush。 + 当PQpipelineSync被调用的结果,或者在非管道模式下的任何请求时,服务器自动刷新它的输出缓冲区;这个函数用于使得服务器在不建立同步点的情况下以管道模式刷新其输出缓冲区。 + 请注意,请求不是自身能自动刷新到服务器;如果需要时使用PQflush @@ -4679,7 +4682,7 @@ int PQsendFlushRequest(PGconn *conn); 当服务器比较远,即网络延迟(ping time)高的时候,管道模式最有用,以及在许多小操作正在快速连续执行的时候。 当每个查询的执行时间是客户端/服务器往返时间的许多倍时,使用管道命令的优势通常会更少。 - 不用管道模式,在往返时间为300毫秒的服务器上运行一个100条语句的操作,仅网络延迟就需要30秒;使用管道,等待来自服务器的结果可能只消耗仅仅0.3秒。 + 不用管道模式,在往返时间为300毫秒的服务器上运行一个100条语句的操作,仅网络延迟就需要30秒;使用管道,等待来自服务器的结果可能只消耗仅仅0.3秒。 @@ -4690,7 +4693,7 @@ int PQsendFlushRequest(PGconn *conn); 当来自一个操作的信息需要客户端产生下一个操作时,管道模式是没有用的。 在这种情况下,客户机将不得不引入一个同步点,并等待完整的客户端/服务器往返以获取它需要的结果。 但是,通常可以调整客户端设计以交换服务器端所需的信息。 - 读-修改-写循环是非常好的选择;例如: + 读-修改-写循环是非常好的选择;例如: BEGIN; SELECT x FROM mytable WHERE id = 42 FOR UPDATE; @@ -4699,7 +4702,7 @@ SELECT x FROM mytable WHERE id = 42 FOR UPDATE; UPDATE mytable SET x = 3 WHERE id = 42; COMMIT; - 可以更有效地开展以下工作: + 可以更有效地开展以下工作: UPDATE mytable SET x = x + 1 WHERE id = 42; @@ -4716,12 +4719,12 @@ UPDATE mytable SET x = x + 1 WHERE id = 42; libpq - single-row mode + 单行模式 libpq - chunked mode + 分块模式 @@ -5101,22 +5104,23 @@ void PQfreeCancel(PGcancel *cancel); - 请求服务器放弃当前命令的处理。 + 的一个已弃用且不安全的变体,但可以在信号处理程序中安全调用。 int PQcancel(PGcancel *cancel, char *errbuf, int errbufsize); + - 返回值为 1 表示取消请求成功发送,为 0 表示未成功发送。如果未成功发送,errbuf将填充解释性错误消息。errbuf必须是大小为errbufsize的字符数组(推荐大小为 256 字节)。 + 仅因向后兼容而保留,应改用 唯一的优势在于:当 errbuf 是信号处理程序中的局部变量时,可以在信号处理程序中安全调用它。不过,通常认为这一优势不足以抵消该函数的安全问题。 - 取消请求成功分派并不保证一定会产生效果。如果取消成功,当前命令会提前终止并返回错误结果;如果取消失败(例如服务器已经处理完该命令),则不会有任何可见结果。 + 对于 而言,PGcancel 对象是只读的,因此也可以从与操作 PGconn 对象的线程不同的线程中调用它。 - 如果errbuf是信号处理程序中的局部变量,则可以安全地从信号处理程序中调用。对于而言,PGcancel对象是只读的,因此也可以从与操作PGconn对象的线程不同的线程中调用。 + 的返回值为 1 表示取消请求成功发送,为 0 表示未成功发送。如果未成功发送,errbuf 将填充解释性错误消息。errbuf 必须是大小为 errbufsize 的字符数组(推荐大小为 256 字节)。 @@ -5128,14 +5132,19 @@ int PQcancel(PGcancel *cancel, char *errbuf, int errbufsize); - 的一个已废弃变体。 + 的一个已弃用且不安全的变体。 int PQrequestCancel(PGconn *conn); + + + + + 仅因向后兼容而保留,应改用 。与 相比,使用 没有任何优势。 - 请求服务器放弃当前命令的处理。它直接作用于PGconn对象,失败时会把错误消息存储到PGconn对象中(可通过获取)。虽然功能相同,但这种方法在多线程程序或信号处理程序中并不安全,因为它可能覆盖PGconn中的错误消息,从而破坏当前连接上正在进行的操作。 + 请求服务器放弃当前命令的处理。它直接作用于 PGconn 对象,失败时会把错误消息存储到 PGconn 对象中(可通过 获取)。虽然功能相同,但这种方法在多线程程序或信号处理程序中并不安全,因为它可能覆盖 PGconn 中的错误消息,从而破坏当前连接上正在进行的操作。 @@ -5198,7 +5207,7 @@ typedef struct - 要传递NULL参数到函数,将参数结构体的len字段设置为-1;isintu 字段就不相关了。 + 要传递NULL参数到函数,将参数结构体的len字段设置为-1isintu 字段就不相关了。 @@ -5455,7 +5464,7 @@ int PQgetCopyData(PGconn *conn, 当async为真时(非零),将不会阻塞等待输入; 如果COPY仍在处理过程中并且没有可用的完整行,那么它将返回零 (在这种情况下等待读准备好,然后在再次调用之前,调用)。 - 当async为假(零)时,PQgetCopyData将阻塞,直到数据可用或者操作完成。 + 当async为假(零)时,将阻塞,直到数据可用或者操作完成。 @@ -5755,7 +5764,7 @@ void PQtrace(PGconn *conn, FILE *stream); - 每行包括:一个可选的时间戳,一个方向指示器(F表示从客户端到服务器的消息或B表示从服务器到客户端的消息),消息长度、消息类型、和消息内容。 + 每行包括:一个可选的时间戳,一个方向指示器(F表示从客户端到服务器的消息或B表示从服务器到客户端的消息),消息长度、消息类型、和消息内容。 非消息内容字段(时间戳、方向、长度和消息类型)由一个制表符分隔。 消息内容用空格分隔。 协议字符串用双引号括起来,而用作数据值的字符串用单引号括起来。 @@ -5929,7 +5938,7 @@ PGresult *PQchangePassword(PGconn *conn, const char *user, const char *passwd); char *PQencryptPassword(const char *passwd, const char *user); - 的一个较老的已经被废弃的版本。其差别是不要求一个连接对象,并且总是用md5作为加密算法。 + 的旧版本,现已弃用。其差别是不需要连接对象,并且总是用md5作为加密算法。 @@ -5949,11 +5958,12 @@ PGresult *PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status); 这是libpq内部用于分配并初始化一个空PGresult对象的函数。 - 如果不能分配内存,那么这个函数返回NULL。 - 它也是可以对外使用的,因为一些应用认为它可以用于产生结果对象(特别是带有错误状态的对象)本身。 - 如果conn非空,并且status表示一个错误,那么指定连接的当前错误消息会被复制到PGresult中。 - 如果conn非空,那么连接中的任何已注册事件过程也会被复制到PGresult中(它们不会获得PGEVT_RESULTCREATE调用,但会看到)。 - 注意在该对象上最终应该调用,正如对libpq本身返回的PGresult对象所作的那样。 + 如果无法分配内存,此函数返回NULL。 + 将它导出供外部调用,是因为一些应用需要自行生成结果对象,特别是带有错误状态的对象。 + 如果conn非空,并且status表示错误,指定连接的当前错误消息会被复制到PGresult中。 + 此外,如果conn非空,连接中注册的所有事件过程也会被复制到PGresult中。 + (这些过程不会收到PGEVT_RESULTCREATE调用,但可参见。) + 注意,最终应对该对象调用,就像处理libpq自身返回的PGresult一样。 @@ -6133,6 +6143,23 @@ int PQlibVersion(void); + + PQgetCurrentTimeUSecPQgetCurrentTimeUSec + + + + 获取当前时间,以自 Unix 纪元以来的微秒数表示(即time_t乘以一百万)。 + +pg_usec_time_t PQgetCurrentTimeUSec(void); + + + + + 此函数主要用于计算供使用的超时值。 + + + + @@ -6313,8 +6340,8 @@ typedef struct - 结果创建事件是响应任何生成结果的查询执行函数而触发的,包括 - 。此事件只会在结果成功创建后触发。 + 任何生成结果的查询执行函数都会触发结果创建事件,其中包括。 + 只有成功创建结果后才会触发该事件。 typedef struct @@ -6324,11 +6351,9 @@ typedef struct } PGEventResultCreate; - 当接收到PGEVT_RESULTCREATE事件时, - 应将evtInfo指针转换为 - PGEventResultCreate *。 - conn是用于生成结果的连接。 - 这是初始化需要与结果关联的任何instanceData的理想位置。 + 收到PGEVT_RESULTCREATE事件时,应将evtInfo指针转换为PGEventResultCreate *。 + 其中,conn是用于生成结果的连接。 + 这是初始化需要与结果关联的instanceData的理想位置。 如果事件过程失败(返回零),那么该事件过程将在结果的剩余生命周期内被忽略; 也就是说,它将不会接收到针对此结果或从中复制的结果的 PGEVT_RESULTCOPYPGEVT_RESULTDESTROY事件。 @@ -6698,6 +6723,15 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough) + + + + PGSSLNEGOTIATION + + PGSSLNEGOTIATION的行为与连接参数相同。 + + + @@ -6766,6 +6800,15 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough) + + + + PGREQUIREAUTH + + PGREQUIREAUTH的行为与连接参数相同。 + + + @@ -6878,6 +6921,15 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough) + + + + PGSSLCERTMODE + + PGSSLCERTMODE的行为与连接参数相同。 + + + @@ -6988,6 +7040,15 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough) + + + + PGGSSDELEGATION + + PGGSSDELEGATION的行为与连接参数相同。 + + + @@ -7027,6 +7088,15 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough) 下面的环境变量可用来为每一个PostgreSQL会话指定默认行为(为每一个用户或每一个数据库设置默认行为的方法还可见命令)。 + + + + PGLOADBALANCEHOSTS + + PGLOADBALANCEHOSTS的行为与连接参数相同。 + + + @@ -7097,20 +7167,15 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough) - 用户的主目录中的文件.pgpass可以包含密码, - 如果连接需要密码(且未指定其他密码)。在Microsoft Windows中, - 该文件的名称为%APPDATA%\postgresql\pgpass.conf - (其中%APPDATA%指用户配置文件中的应用数据子目录)。 - 或者,可以使用连接参数 - 或环境变量PGPASSFILE指定要使用的密码文件。 - + 用户主目录中的.pgpass文件可保存密码,供连接需要密码且尚未通过其他方式指定密码时使用。在 Microsoft Windows 上,文件名为%APPDATA%\postgresql\pgpass.conf(其中%APPDATA%指用户配置文件中的应用数据子目录)。也可以通过连接参数或环境变量PGPASSFILE指定要使用的密码文件。 + 这个文件应该包含下列格式的行: hostname:port:database:username:password - (你可以向该文件增加一个提醒:把上面的行复制到该文件并且在前面加上#)。前四个域的每一个都可以是文字值或者匹配任何东西的*。第一个匹配当前连接参数的行中的密码域将被使用(因此,在使用通配符时把更特殊的项放在前面)。如果一个条目需要包含:或者\,用\对该字符转义。如果指定了host连接参数,主机名字段会被匹配到host,否则如果指定了hostaddr参数则匹配到hostaddr,如果两者都没有给出,则会搜索主机名localhost。当连接是一个Unix域套接字连接并且host参数匹配libpq的默认套接字目录路径时,也会搜索主机名localhost。在一台备库上,值为replication的数据库字段匹配连接到主库的流复制连接。否则数据库字段的用途有限,因为用户对同一个集簇中的所有数据库都有相同的密码。 + (你可以向该文件增加一个提醒:把上面的行复制到该文件并且在前面加上#)。前四个字段的每一个都可以是字面值或者匹配任何东西的*。第一个匹配当前连接参数的行中的密码字段将被使用(因此,在使用通配符时把更特殊的项放在前面)。如果一个条目需要包含:或者\,用\对该字符转义。如果指定了host连接参数,主机名字段会被匹配到host,否则如果指定了hostaddr参数则匹配到hostaddr,如果两者都没有给出,则会搜索主机名localhost。当连接是一个Unix域套接字连接并且host参数匹配libpq的默认套接字目录路径时,也会搜索主机名localhost。在一台备库上,值为replication的数据库字段匹配连接到主库的流复制连接。否则数据库字段的用途有限,因为用户对同一个集簇中的所有数据库都有相同的密码。 @@ -7547,7 +7612,7 @@ ldap://ldap.acme.com/cn=dbserver,cn=hosts?pgconnectinfo?base?(objectclass=*) 构建时带有SSL支持,您应该调用告诉libpq libssl和/或libcrypto库已被您的应用程序初始化,以便 libpq不会再初始化这些库。 - 但是,当使用OpenSSL版本1.1.0或更高版本时,重复初始化不再成问题。 + 但是,当使用OpenSSL版本1.1.0或更高版本时,无需这样做,因为重复初始化不再成问题。 @@ -7571,7 +7636,7 @@ void PQinitOpenSSL(int do_ssl, int do_crypto); - 如果你的应用使用并且初始化OpenSSL或者它的底层libcrypto库,你必须在第一次打开数据库连接前以合适的非零参数调用这个函数。 + 如果你的应用使用并且初始化OpenSSL或者它的底层libcrypto库,你必须在第一次打开数据库连接前调用这个函数,并把相应参数设为零。 同时要确保在打开一个数据库连接前已经完成了初始化。 @@ -7608,8 +7673,8 @@ void PQinitSSL(int do_ssl); 在线程化程序中的行为 - threads - with libpq + 线程 + 用于 libpq diff --git a/zh/17/logical-replication.sgml b/zh/17/logical-replication.sgml index f98f0963..13357fc6 100644 --- a/zh/17/logical-replication.sgml +++ b/zh/17/logical-replication.sgml @@ -208,7 +208,7 @@ 如前所述,每个(活动)订阅都从远端(发布侧)的一个复制槽接收变更。 - 额外的表同步槽通常是临时的,由系统内部创建用于执行初始表同步,在不再需要时 + 额外的表同步槽通常只会短暂存在,由系统内部创建用于执行初始表同步,在不再需要时 自动删除。这些表同步槽的名称是自动生成的: pg_%u_sync_%u_%llu (参数分别为:订阅 oid、 @@ -419,7 +419,7 @@ test_pub=# SELECT * FROM t3; 注意在常规复制阶段会使用相应的 publish 操作。 这意味着发布 pub2pub3a 不会复制 - INSERT。另外,发布 pub3b 只会复制与其 + INSERT。另外,发布 pub3b 只会复制与 pub3b 的 行过滤器匹配的数据。现在订阅端数据如下: test_sub=# SELECT * FROM t1; @@ -625,7 +625,7 @@ ALTER SUBSCRIPTION - 要确认某个订阅对应的备库确实已做好故障切换准备,请按下列步骤验证该订阅需要的 + 要确认备库确实已为某个订阅端做好故障切换准备,请按下列步骤验证该订阅端需要的 所有逻辑复制槽都已同步到备库: @@ -694,7 +694,7 @@ test_standby=# SELECT slot_name, (synced AND NOT temporary AND invalidation_reas 上述步骤中的前两步针对的是 PostgreSQL 订阅端。 - 建议在每次故障切换后,都在将由目标备库服务的各个订阅节点上执行这两步,以获得完整的复制槽 + 建议在每个将于故障切换后由指定备库提供服务的订阅端节点上执行这两步,以获得完整的复制槽 列表,然后在第 3 步中统一验证故障切换就绪状态。 非 PostgreSQL 订阅端则可使用其自身方法识别各自订阅使用的复制槽。 @@ -1418,10 +1418,7 @@ test_sub=# SELECT * FROM t1 ORDER BY id; 冲突 - 逻辑复制的行为在一点上类似于普通 DML 操作:即使订阅节点上的数据已在本地被修改, - 传入的变更仍会更新它。如果传入数据违反了任何约束,复制就会停止,这种情况称为 - 冲突。在复制 UPDATE 或 - DELETE 操作时,丢失的数据不会产生冲突,这类操作会被直接跳过。 + 逻辑复制的行为类似于普通的 DML 操作,即使数据在订阅端本地已被更改,仍会更新数据。如果传入的数据违反了任何约束,复制将停止。这称为冲突。当复制UPDATEDELETE操作时,缺失的数据不会产生冲突,这类操作只会被简单跳过。 @@ -1435,13 +1432,12 @@ test_sub=# SELECT * FROM t1 ORDER BY id; - 冲突会产生错误并使复制停止;这类冲突必须由用户手工解决。有关冲突的详细信息 - 可以在订阅端的服务器日志中找到。 + 冲突将产生一个错误并停止复制;它必须由用户手动解决。冲突的详细信息可在订阅端的服务器日志中找到。 解决方法可以是修改订阅端上的数据或权限,使其不再与传入变更冲突;也可以跳过与 - 现有数据冲突的事务。当冲突导致错误时,复制不会继续,逻辑复制工作者会向订阅端 + 现有数据冲突的事务。当冲突导致错误时,复制不会继续,逻辑复制工作进程会向订阅端 的服务器日志输出如下消息: ERROR: duplicate key value violates unique constraint "test_pkey" @@ -1452,8 +1448,8 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER (在上述示例中分别是 LSN 0/14C0378 和复制源 pg_16395)。 可以使用 ALTER SUBSCRIPTION ... SKIP - 并提供 finish LSN(即 LSN 0/14C0378)来跳过产生冲突的事务。这个 finish LSN - 可以是该事务在发布端提交或准备完成时的 LSN。或者,也可以调用 + 并提供 完成 LSN(即 LSN 0/14C0378)来跳过产生冲突的事务。这个 完成 LSN + 可以是该事务在发布端提交或预备时的 LSN。或者,也可以调用 pg_replication_origin_advance() 函数来跳过该事务。 在使用此函数之前,需要暂时禁用订阅,可以使用 @@ -1462,7 +1458,7 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER disable_on_error 选项。然后,可以使用 pg_replication_origin_advance() 函数, 传入 node_name(即 pg_16395) - 以及 finish LSN 的下一个 LSN(即 0/14C0379)。当前各复制源的位置可以在 + 以及 完成 LSN 的下一个 LSN(即 0/14C0379)。当前各复制源的位置可以在 pg_replication_origin_status 系统视图中查看。 请注意,跳过整个事务也会跳过那些本来可能不违反任何约束的变更,这很容易导致 @@ -1472,10 +1468,10 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER streaming - 模式为 parallel 时,失败事务的 finish LSN 可能不会被记录。 + 模式为 parallel 时,失败事务的 完成 LSN 可能不会被记录。 这种情况下,可能需要把 streaming 模式改为 on 或 - off,并再次触发相同的冲突,以便将失败事务的 finish LSN - 写入服务器日志。关于 finish LSN 的用法,请参见 + off,并再次触发相同的冲突,以便将失败事务的 完成 LSN + 写入服务器日志。关于 完成 LSN 的用法,请参见 ALTER SUBSCRIPTION ... SKIP @@ -1493,9 +1489,9 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER 数据库模式和 DDL 命令不会被复制。初始模式可以手工使用 pg_dump --schema-only 复制。之后的模式更改需要手工保持同步。 (不过请注意,两端的模式其实不需要绝对一致。)当活动数据库中的模式定义发生变化时, - 逻辑复制仍然具有一定鲁棒性:如果发布端修改了模式,而复制数据开始到达订阅端时 + 逻辑复制仍然能够稳健运行:如果发布端修改了模式,而复制数据开始到达订阅端时 与表模式不匹配,复制就会报错,直到模式被更新。在很多情况下,可以通过先在订阅端 - 应用增量式的模式变更来避免间歇性错误。 + 应用仅添加内容的模式变更来避免间歇性错误。 @@ -1551,7 +1547,7 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER 对已发布表使用 REPLICA IDENTITY FULL 时,需要注意:如果表中包含某些数据类型的属性(例如 point 或 box),而这些类型 - 没有 B-tree 或 Hash 的默认操作符类,那么 UPDATE 和 + 没有 B-树 或 Hash 的默认操作符类,那么 UPDATEDELETE 操作就无法在订阅端应用。不过,可以通过确保该表具有 主键或已定义复制标识来规避这一限制。 @@ -1600,7 +1596,7 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER 对现有订阅表中的初始数据,会取快照并由一种特殊应用进程的一个并行实例来复制。 该进程会创建自己的复制槽,并复制现有数据。复制一完成,该表内容就会对其他后端可见。 - 现有数据复制完成后,工作者会进入同步模式,通过标准逻辑复制流式发送在初始数据 + 现有数据复制完成后,工作进程会进入同步模式,通过标准逻辑复制流式发送在初始数据 复制期间发生的任何变更,使该表与主应用进程达到同步状态。在这一同步阶段, 变更会按照它们在发布端发生的顺序被应用和提交。同步完成后,该表的复制控制权 会交还给主应用进程,之后复制将照常继续。 @@ -1628,14 +1624,14 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER 与订阅相关的监控信息可在 pg_stat_subscription - 中查看。这个视图为每个订阅工作者包含一行。一个订阅根据其状态,可能有零个或多个 - 活跃的订阅工作者。 + 中查看。这个视图为每个订阅工作进程包含一行。一个订阅根据其状态,可能有零个或多个 + 活跃的订阅工作进程。 通常,一个已启用的订阅会有一个应用进程在运行。被禁用的订阅或已崩溃的订阅在这个 视图中将没有任何行。如果某张表的初始数据同步正在进行,则还会有针对这些正在同步 - 的表的额外工作者。并且,如果使用 + 的表的额外工作进程。并且,如果使用 streaming 并以并行方式应用事务,则还可能出现额外的并行应用工作进程。 @@ -1714,14 +1710,14 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER - 在订阅端,订阅所有者的权限会在每个事务应用时重新检查。如果某个工作者正在应用 + 在订阅端,订阅所有者的权限会在每个事务应用时重新检查。如果某个工作进程正在应用 事务时,订阅的所有权被并发事务更改,那么当前事务的应用仍会继续使用旧所有者的 权限。 - 配置参数 + 配置设置 逻辑复制需要设置若干配置选项。大多数选项只在复制的一侧生效。但 @@ -1765,7 +1761,7 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER max_logical_replication_workers - 必须至少设置为订阅数量(用于主应用工作进程),再加上用于表同步工作进程 + 必须至少设置为订阅数量(用于领导者应用工作进程),再加上用于表同步工作进程 和并行应用工作进程的预留量。 diff --git a/zh/17/logicaldecoding.sgml b/zh/17/logicaldecoding.sgml index 8c88864c..a06053eb 100644 --- a/zh/17/logicaldecoding.sgml +++ b/zh/17/logicaldecoding.sgml @@ -357,7 +357,7 @@ postgres=# select * from pg_logical_slot_get_changes('regression_slot', NULL, NU 中列出的槽,向逻辑订阅者发送更改时仍然会有一定延迟。使用 synchronized_standby_slots 时,主库在与 synchronized_standby_slots 中指定的物理复制槽相关联 - 的备库确认已接收到截至主库最新刷写位置的 WAL 之前,不会完全关闭。 + 的备库确认已接收到截至主库最新刷盘位置的 WAL 之前,不会完全关闭。 diff --git a/zh/17/maintenance.sgml b/zh/17/maintenance.sgml index 01e63c57..e4c0f89c 100644 --- a/zh/17/maintenance.sgml +++ b/zh/17/maintenance.sgml @@ -380,7 +380,7 @@ 包括那些来自全部可见(all-visible)但未全部冻结(all-frozen)页面的值。 在实际使用中,大多数表需要周期性地进行激进扫描。 - 控制何时对表执行激进扫描:如果距离上一次这类扫描以来经过的事务数大于 + 控制VACUUM何时对表执行激进扫描:如果距离上一次这类扫描以来经过的事务数大于 vacuum_freeze_table_age 减去 vacuum_freeze_min_age,就会扫描所有全部可见但未全部冻结的页面。 把 vacuum_freeze_table_age 设为 0 会强制 @@ -391,7 +391,7 @@ 一个表在不被清理的情况下所能维持的最长时间,是最后一次激进扫描时的 vacuum_freeze_min_age 值从 20 亿事务中扣除后的结果。 如果超过这个时间仍不清理,就可能导致数据丢失。为了确保不会发生这种情况, - 任何可能包含未冻结行且其 XID 早于配置参数 所指定年龄的表,都会触发自动清理。 (即使自动清理已被禁用,也会如此。) @@ -482,8 +482,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; VACUUM 通常只扫描自上次清理以来被修改过的页面,但只有 当表中每一个可能包含未冻结 XID 的页面都被扫描时, relfrozenxid 才会被推进。当 - relfrozenxid 比 - vacuum_freeze_table_age 旧、使用了 VACUUM 的 + relfrozenxid的年龄超过vacuum_freeze_table_age个事务、使用了 VACUUMFREEZE 选项,或者所有尚未全部冻结的页面碰巧都需要清理以移除死行版本时, 就会发生这种情况。当 VACUUM 扫描了表中每个尚未全部冻结的页面时, 它应把 age(relfrozenxid) 设为略高于所用 @@ -582,22 +581,22 @@ HINT: Execute a database-wide VACUUM in that database. 多事务(multitransaction,MultiXact) ID 用于支持多个事务对行加锁。由于元组头中用于存储锁信息的空间有限, 当有多个事务同时锁定一行时,这些信息会被编码为一个多事务 ID, - 简称 multixact ID。某个特定 multixact ID 包含哪些事务 ID 的信息, + 简称 multixact ID。某个特定 多事务 ID 包含哪些事务 ID 的信息, 会单独存放在 pg_multixact 子目录中,而元组头的 - xmax 字段中只出现 multixact ID。和事务 ID 一样, - multixact ID 也是以 32 位计数器及其对应存储实现的,因此同样需要仔细处理老化管理、 - 存储清理和回卷问题。还有一个单独的存储区域保存每个 multixact 的成员列表, + xmax 字段中只出现 多事务 ID。和事务 ID 一样, + 多事务 ID 也是以 32 位计数器及其对应存储实现的,因此同样需要仔细处理老化管理、 + 存储清理和回卷问题。还有一个单独的存储区域保存每个 多事务 的成员列表, 它也使用 32 位计数器,因此同样必须被管理。 中介绍的系统函数 pg_get_multixact_members() - 可用于检查与某个 multixact ID 关联的事务 ID。 + 可用于检查与某个 多事务 ID 关联的事务 ID。 每当 VACUUM 扫描表的任何部分时,它都会把遇到的、早于 - 的任何 multixact ID 替换为另一个值,该值可能是零值、单个事务 ID,或者更新的 multixact ID。 + 的任何 多事务 ID 替换为另一个值,该值可能是零值、单个事务 ID,或者更新的 多事务 ID。 对于每个表,pg_class.relminmxid - 保存该表任何元组中仍可能出现的最老 multixact ID。如果这个值早于 + 保存该表任何元组中仍可能出现的最老 多事务 ID。如果这个值早于 ,就会强制执行一次激进扫描。 正如上一节所述,激进扫描意味着只有那些已知为全部冻结的页面才会被跳过。 可以对 pg_class.relminmxid @@ -607,14 +606,14 @@ HINT: Execute a database-wide VACUUM in that database. 无论出于何种原因而发生,激进的 VACUUM保证 能够推进表的 relminmxid。最终,随着所有数据库中的所有表都被扫描, - 并推进其最老的 multixact 值,较老 multixact 的磁盘存储就可以被移除。 + 并推进其最老的 多事务 值,较老 多事务 的磁盘存储就可以被移除。 - 作为一项安全措施,对于 multixact 年龄大于 的任何表,都会进行一次激进扫描。 - 此外,如果 multixact 成员占用的存储超过大约 10GB,则会更频繁地对所有表进行激进扫描, - 从 multixact 年龄最老的表开始。即便自动清理名义上被禁用,这两类激进扫描也都会发生。 + 此外,如果 多事务 成员占用的存储超过大约 10GB,则会更频繁地对所有表进行激进扫描, + 从 多事务 年龄最老的表开始。即便自动清理名义上被禁用,这两类激进扫描也都会发生。 成员存储区域在到达回卷之前最多可增长到大约 20GB。 @@ -631,11 +630,11 @@ HINT: Execute a database-wide VACUUM in that database. - 如果没有可能出现在 multixact 中,那么正在运行的事务和预备事务都可以忽略。 + 如果没有可能出现在 多事务 中,那么正在运行的事务和预备事务都可以忽略。 - 与事务 ID 回卷不同,复制槽不会直接阻止 multixact 清理。 - 因此,删除陈旧的复制槽通常与解决 multixact ID 回卷问题无关。 + 与事务 ID 回卷不同,复制槽不会直接阻止 多事务 清理。 + 因此,删除陈旧的复制槽通常与解决 多事务 ID 回卷问题无关。 MXID 信息不会直接出现在诸如 pg_stat_activity 这样的系统视图中; @@ -691,7 +690,7 @@ HINT: Execute a database-wide VACUUM in that database. - 对于 relfrozenxid 值早于 + 对于 relfrozenxid值的年龄超过 个事务的表,总是会执行清理 (这也适用于那些通过存储参数修改了冻结最大年龄的表,见下文)。 否则,如果自上次 VACUUM 以来已经失效的元组数超过了 @@ -724,7 +723,7 @@ vacuum insert threshold = vacuum base insert threshold + vacuum insert scale fac 因为这会让元组在更早的清理中被冻结。过时元组数和插入元组数取自累积统计系统; 这是一个由每次 UPDATEDELETEINSERT 操作更新的最终一致计数。如果该表的 - relfrozenxid 值早于 + relfrozenxid值的年龄超过 vacuum_freeze_table_age 个事务,就会执行一次激进扫描, 以冻结旧元组并推进 relfrozenxid;否则,只扫描自 上次清理以来被修改过的页面。 @@ -926,7 +925,7 @@ pg_ctl start | rotatelogs /var/log/pgsql_log 86400 不过,在很多系统上,syslog 并不十分可靠, 尤其是在日志消息很大时;它可能恰恰在你最需要消息的时候截断或丢弃它们。 此外,在 Linux 上, - syslog 会把每条消息都刷新到磁盘,导致性能较差。 + syslog 会把每条消息都刷盘,导致性能较差。 (你可以在 syslog 配置文件的文件名开头使用一个 - 来禁用同步。) diff --git a/zh/17/monitoring.sgml b/zh/17/monitoring.sgml index e63606c8..93852c3c 100644 --- a/zh/17/monitoring.sgml +++ b/zh/17/monitoring.sgml @@ -49,13 +49,13 @@ postgres 15606 0.0 0.0 58772 3052 ? Ss 18:07 0:00 postgres: tgl postgres 15610 0.0 0.0 58772 3056 ? Ss 18:07 0:00 postgres: tgl regression [local] idle in transaction - (ps 的正确调用方式因平台而异,显示细节也不同。此示例来自一个较新的 Linux 系统。)此处列出的第一个进程是主服务器进程。它显示的命令参数是启动时使用的参数。接下来的四个进程是由主进程自动启动的后台工作进程。(如果系统设置为不运行自动清理,则不会出现 autovacuum launcher 进程。)其余的每个进程都是处理一个客户端连接的服务器进程。每个此类进程都会将其命令行显示为 + (ps的正确调用方式因平台而异,显示细节也不同。此示例来自一个较新的 Linux 系统。)此处列出的第一个进程是主服务器进程。它显示的命令参数是启动时使用的参数。接下来的四个进程是由主进程自动启动的后台工作进程。(如果您已将系统设置为不运行自动清理,则不会出现autovacuum launcher进程。)其余的每个进程都是处理一个客户端连接的服务器进程。每个此类进程都会将其命令行显示为 postgres: user database host activity - 用户、数据库和(客户端)主机项在客户端连接的整个生命周期内保持不变,但活动指示器会发生变化。活动可以是 idle(即等待客户端命令)、idle in transaction(在 BEGIN 块内等待客户端)或命令类型名称,例如 SELECT。此外,如果服务器进程当前正在等待另一个会话持有的锁,则会附加 waiting。在上例中,可以推断进程 15606 正在等待进程 15610 完成其事务,从而释放某些锁。(进程 15610 必须是阻塞者,因为没有其他活动会话。在更复杂的情况下,有必要查看 pg_locks 系统视图以确定谁在阻塞谁。) + 用户、数据库和(客户端)主机项在客户端连接的整个生命周期内保持不变,但活动指示器会发生变化。活动可以是idle(即等待客户端命令)、idle in transaction(在BEGIN块内等待客户端)或命令类型名称,例如SELECT。此外,如果服务器进程当前正在等待另一个会话持有的锁,则会附加waiting。在上例中,我们可以推断进程 15606 正在等待进程 15610 完成其事务,从而释放某些锁。(进程 15610 必须是阻塞者,因为没有其他活动会话。在更复杂的情况下,有必要查看pg_locks系统视图以确定谁在阻塞谁。) @@ -74,28 +74,28 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - 如果关闭了 ,则活动指示器不会更新;进程标题仅在新进程启动时设置一次。在某些平台上,这可以节省可观的每命令开销;在其他平台上,则微不足道。 + 如果您关闭了,则活动指示器不会更新;进程标题仅在新进程启动时设置一次。在某些平台上,这可以节省可观的每命令开销;在其他平台上,则微不足道。 - Solaris 需要特殊处理。必须使用 /usr/ucb/ps,而不是 /bin/ps。还必须使用两个 标志,而不仅仅是一个。此外,对 postgres 命令的原始调用必须具有比每个服务器进程提供的更短的 ps 状态显示。如果未满足这三个条件,每个服务器进程的 ps 输出都会显示原始的 postgres 命令行。 + Solaris需要特殊处理。您必须使用/usr/ucb/ps,而不是/bin/ps。您还必须使用两个标志,而不仅仅是一个。此外,您对postgres命令的原始调用必须具有比每个服务器进程提供的更短的ps状态显示。如果未满足这三个条件,每个服务器进程的ps输出都会显示原始的postgres命令行。 - 累计统计系统 + 累积统计系统 - statistics + 统计信息 PostgreSQL累积统计系统支持收集和报告有关服务器活动的信息。 - 目前,对表和索引的访问以磁盘块和单个行的术语进行计数。每个表中的总行数, + 目前,对表和索引的访问分别以磁盘块和单行计数。每个表中的总行数, 以及每个表的清理和分析操作的信息也被计数。如果启用,对用户定义函数的调用 和每个函数中花费的总时间也会被计数。 @@ -107,7 +107,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - 统计收集配置 + 统计信息收集配置 由于收集统计信息会增加查询执行的开销,因此可以配置系统是否收集信息。这由通常在postgresql.conf中设置的配置参数控制(有关设置配置参数的详细信息,请参阅)。 @@ -129,9 +129,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 参数启用对块读取、写入、扩展和 fsync 时间的监控。 - - 参数启用对 WAL 读取、写入和 fsync 时间的监控。 - + 参数启用对 WAL 写入和 fsync 时间的监控。 通常,这些参数会设置在postgresql.conf中,以便它们适用于所有服务器进程,但也可以在单个会话中使用命令打开或关闭它们。(为防止普通用户隐藏其活动不被管理员发现,只有超级用户才能使用SET更改这些参数。) @@ -156,11 +154,11 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - 另一个重要点是,当服务器进程被要求显示任何累积统计信息时,在默认配置中,访问到的值会被缓存直到当前事务结束。因此,只要当前事务继续存在,统计信息就会保持静态。类似地,当在事务中首次请求任何当前会话的查询信息时,会收集关于所有会话当前查询的信息,并且相同的信息会在整个事务期间显示。这是一个特性,而不是错误,因为它允许在统计信息上执行多个查询并关联其结果,而不必担心数字在查询过程中发生变化。 + 另一个重要的观点是,当服务器进程被要求显示任何累积的统计信息时,在默认配置中,访问的值会被缓存直到当前事务结束。因此,只要你继续当前事务,统计信息将显示静态信息。类似地,当在事务中首次请求这类当前查询信息时,会收集关于所有会话当前查询的信息,并且相同的信息将在整个事务中显示。这是一个特性,而不是一个错误,因为它允许你在统计信息上执行多个查询并将结果相关联,而不必担心数字在你眼前发生变化。 - 在交互式分析统计信息或使用昂贵的查询时,访问各个统计信息之间的时间差可能导致缓存统计信息中出现显著的偏差。为了最小化偏差,可以将stats_fetch_consistency设置为snapshot,但这会增加用于缓存不需要的统计数据的内存使用量。相反,如果已知统计信息只被访问一次,那么缓存访问的统计信息是不必要的,可以通过将stats_fetch_consistency设置为none来避免。 + 在交互式分析统计信息或使用开销较大的查询时,访问各个统计信息之间的时间差可能导致缓存统计信息中出现显著的偏差。为了最小化偏差,可以将stats_fetch_consistency设置为snapshot,但这会增加用于缓存不需要的统计数据的内存使用量。相反,如果已知统计信息只被访问一次,那么缓存访问的统计信息是不必要的,可以通过将stats_fetch_consistency设置为none来避免。 - 可以调用 pg_stat_clear_snapshot() 丢弃当前事务的统计快照或缓存值(如果有)。下一次使用统计信息时,(在快照模式下)将创建一个新的快照,或者(在缓存模式下)缓存所访问的统计信息。 + 你可以调用pg_stat_clear_snapshot()来丢弃当前事务的统计快照或缓存的值(如果有)。下一次使用统计信息时(在快照模式下),将会创建一个新的快照,或者(在缓存模式下)将访问的统计信息缓存起来。 @@ -172,13 +170,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 相反,它们在事务期间持续更新。 - - 动态统计视图中显示的一些信息在中受到安全限制。 - 普通用户只能查看关于他们自己会话的所有信息(属于他们是成员的角色的会话)。在关于其他会话的行中,许多列将为空。 - 但是,请注意,所有用户都可以看到会话的存在以及其一般属性,例如会话用户和数据库。 - 超级用户以及具有内置角色pg_read_all_stats权限的角色 - (另请参阅)可以查看所有会话的全部信息。 - + 所列动态统计视图中的一些信息受到安全限制。普通用户只能查看其自身会话的全部信息(包括属于其所加入角色的会话)。对于其他会话的行,许多列将为空值。不过,会话的存在及其一般属性(例如会话用户和数据库)对所有用户都可见。超级用户和具有内置角色pg_read_all_stats权限的角色(另请参阅)可以查看所有会话的全部信息。
@@ -213,7 +205,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser pg_stat_wal_receiverpg_stat_wal_receiver - 只有一行,显示有关 WAL 接收进程从其连接服务器接收到的统计信息。有关详细信息,请参阅pg_stat_wal_receiver。 + 只有一行,显示 WAL 接收进程从其所连接服务器接收数据的统计信息。有关详细信息,请参阅pg_stat_wal_receiver @@ -297,63 +289,63 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - + pg_stat_archiverpg_stat_archiver 只有一行,显示有关 WAL 归档进程活动的信息。有关详细信息,请参阅pg_stat_archiver - + pg_stat_bgwriterpg_stat_bgwriter 只有一行,显示有关后台写入器活动的信息。有关详细信息,请参阅pg_stat_bgwriter - + pg_stat_checkpointerpg_stat_checkpointer 只有一行,显示有关检查点进程活动的信息。有关详细信息,请参阅pg_stat_checkpointer - + pg_stat_databasepg_stat_database 每个数据库一行,显示数据库范围的统计信息。有关详细信息,请参阅pg_stat_database - + pg_stat_database_conflictspg_stat_database_conflicts 每个数据库一行,显示数据库范围内因备库上的恢复冲突而导致查询被取消的统计信息。有关详细信息,请参阅pg_stat_database_conflicts - + pg_stat_iopg_stat_io 对于每种后端类型、上下文和目标对象的组合各有一行,包含集簇范围的 I/O 统计信息。有关详细信息,请参阅pg_stat_io - + pg_stat_replication_slotspg_stat_replication_slots 每个复制槽一行,显示有关复制槽使用情况的统计信息。有关详细信息,请参阅pg_stat_replication_slots - + pg_stat_slrupg_stat_slru 每个 SLRU 一行,显示操作统计信息。有关详细信息,请参阅pg_stat_slru - + pg_stat_subscription_statspg_stat_subscription_stats 每个订阅一行,显示有关错误的统计信息。有关详细信息,请参阅pg_stat_subscription_stats - + pg_stat_walpg_stat_wal 只有一行,显示有关 WAL 活动的统计信息。有关详细信息,请参阅pg_stat_wal - + pg_stat_all_tablespg_stat_all_tables 当前数据库中每个表一行,显示有关访问指定表的统计信息。详见 @@ -361,102 +353,102 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - + pg_stat_sys_tablespg_stat_sys_tables pg_stat_all_tables一样,但只显示系统表。 - + pg_stat_user_tablespg_stat_user_tables pg_stat_all_tables一样,但只显示用户表。 - + pg_stat_xact_all_tablespg_stat_xact_all_tables - pg_stat_all_tables相似,但计数动作只在当前事务内发生(还没有被包括在pg_stat_all_tables和相关视图中)。用于生存和死亡行数量的列以及清理和分析动作在此视图中不出现。 + pg_stat_all_tables 相似,但只统计当前事务中截至目前执行的操作(这些操作尚计入 pg_stat_all_tables 及相关视图)。此视图不包含存活行和死行数量以及清理、分析操作的列。 - + pg_stat_xact_sys_tablespg_stat_xact_sys_tables pg_stat_xact_all_tables一样,但只显示系统表。 - + pg_stat_xact_user_tablespg_stat_xact_user_tables pg_stat_xact_all_tables一样,但只显示用户表。 - + pg_stat_all_indexespg_stat_all_indexes 当前数据库中的每个索引一行,显示有关访问该特定索引的统计信息。有关详细信息,请参阅pg_stat_all_indexes - + pg_stat_sys_indexespg_stat_sys_indexes pg_stat_all_indexes一样,但只显示系统表上的索引。 - + pg_stat_user_indexespg_stat_user_indexes pg_stat_all_indexes一样,但只显示用户表上的索引。 - + + pg_stat_user_functionspg_stat_user_functions + 每个被跟踪的函数一行,显示有关该函数执行的统计信息。有关详细信息,请参阅pg_stat_user_functions + + + + pg_stat_xact_user_functionspg_stat_xact_user_functions + pg_stat_user_functions相似,但是只统计在当前事务期间的调用(还没有被包括在pg_stat_user_functions中)。 + + + pg_statio_all_tablespg_statio_all_tables 当前数据库中的每个表一行,显示有关访问该特定表的 I/O 统计信息。有关详细信息,请参阅pg_statio_all_tables - + pg_statio_sys_tablespg_statio_sys_tables pg_statio_all_tables一样,但只显示系统表。 - + pg_statio_user_tablespg_statio_user_tables pg_statio_all_tables一样,但只显示用户表。 - + pg_statio_all_indexespg_statio_all_indexes 当前数据库中的每个索引一行,显示有关访问该特定索引的 I/O 统计信息。有关详细信息,请参阅pg_statio_all_indexes - + pg_statio_sys_indexespg_statio_sys_indexes pg_statio_all_indexes一样,但只显示系统表上的索引。 - + pg_statio_user_indexespg_statio_user_indexes pg_statio_all_indexes一样,但只显示用户表上的索引。 - + pg_statio_all_sequencespg_statio_all_sequences 当前数据库中的每个序列一行,显示有关访问该特定序列的 I/O 统计信息。有关详细信息,请参阅pg_statio_all_sequences - + pg_statio_sys_sequencespg_statio_sys_sequences pg_statio_all_sequences一样,但只显示系统序列(目前没有定义系统序列,因此这个视图总是为空)。 - + pg_statio_user_sequencespg_statio_user_sequences pg_statio_all_sequences一样,但只显示用户序列。 - - pg_stat_user_functionspg_stat_user_functions - 每个被跟踪的函数一行,显示有关该函数执行的统计信息。有关详细信息,请参阅pg_stat_user_functions - - - - pg_stat_xact_user_functionspg_stat_xact_user_functions - pg_stat_user_functions相似,但是只统计在当前事务期间的调用(还没有被包括在pg_stat_user_functions中)。 - - - +
@@ -531,7 +523,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser leader_pid integer
- 如果该进程是并行查询工作进程,则为并行组领导者的进程 ID;如果该进程是并行应用工作进程,则为领导应用工作进程的进程 ID。NULL 表示该进程是并行组领导者或领导应用工作进程,或者不参与任何并行操作。 + 如果该进程是并行查询工作进程,则为并行组领导者的进程 ID;如果该进程是并行应用工作进程,则为领导者应用工作进程的进程 ID。NULL 表示该进程是并行组领导者或领导者应用工作进程,或者不参与任何并行操作。 @@ -567,7 +559,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser client_addr inet
- 连接到这个后端的客户端的 IP 地址。如果这个字段为空,它表示客户端通过服务器机器上的一个 Unix 套接字连接或者这是一个内部进程,如自动清理。 + 连接到这个后端的客户端的 IP 地址。如果这个字段为空值,它表示客户端通过服务器机器上的一个 Unix 套接字连接或者这是一个内部进程,如自动清理。 @@ -586,7 +578,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser client_port integer - 客户端用于与此后端通信的TCP端口号,如果使用Unix套接字,则为-1。如果该字段为空,它表示这是一个内部服务器进程。 + 客户端用于与此后端通信的TCP端口号,如果使用Unix套接字,则为-1。如果该字段为空值,它表示这是一个内部服务器进程。 @@ -604,8 +596,8 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser xact_start timestamp with time zone - 这个进程的当前事务被启动的时间,如果没有活动事务则为空。 - 如果当前查询是它的第一个事务,这一列等于query_start列。 + 这个进程的当前事务被启动的时间,如果没有活动事务则为空值。 + 如果当前查询是其事务中的第一个查询,这一列等于query_start列。 @@ -632,7 +624,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser wait_event_type text - 后端正在等待的事件类型(如果有);否则为NULL。请参阅。 + 后端正在等待的事件类型(如果有);否则为空值。请参阅 @@ -641,7 +633,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser wait_event text - 如果此后端当前正在等待,则返回等待事件名称,否则为NULL。请参阅。 + 如果此后端当前正在等待,则返回等待事件名称,否则为空值。请参阅 @@ -649,39 +641,24 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser state text - - 这个后端的当前总体状态。可能的值为: - + 该后端当前的总体状态。可能的值为: - - active: 后端正在执行一个查询。 - + active:后端正在执行一个查询。 - - idle: 后端正在等待一个新的客户端命令。 - + idle:后端正在等待新的客户端命令。 - - idle in transaction: 后端位于一个事务中,但当前没有正在执行的查询。 - + idle in transaction:后端处于事务中,但当前没有执行查询。 - - idle in transaction (aborted): 这个状态与 - idle in transaction 相似,只是该事务中的某个语句导致了错误。 - + idle in transaction (aborted):该状态与idle in transaction类似,但事务中的某个语句导致了错误。 - - fastpath function call: 后端正在执行一个 fast-path 函数。 - + fastpath function call:后端正在执行一个快速路径函数。 - - disabled: 如果在这个后端中被禁用,则报告这个状态。 - + disabled:如果在此后端中禁用了,就会报告此状态。 @@ -691,9 +668,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser backend_xid xid - - 这个后端的顶层事务 ID,如果存在。 - + 这个后端的顶层事务 ID(如果存在);请参阅 @@ -701,7 +676,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser backend_xmin xid - 当前后端的xmin范围。 + 当前后端的xmin视界。 @@ -713,7 +688,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 这个后端的最近查询的标识符。 如果stateactive,这个字段显示当前正在执行的查询的标识符。 在所有其他状态,它显示执行的最后一个查询的标识符。 - 默认不计算查询标识符,因此该字段将为空,除非启用参数或配置了计算查询标识符的第三方模块。 + 默认不计算查询标识符,因此该字段将为空值,除非启用参数或配置了计算查询标识符的第三方模块。 @@ -731,19 +706,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser backend_type text - - 当前后端的类型。可能的类型为 - autovacuum launcher, autovacuum worker, - logical replication launcher, - logical replication worker, - parallel worker, background writer, - client backend, checkpointer, - archiver, standalone backend, - startup, walreceiver, - walsender, walwriter 以及 - walsummarizer。 - 此外,由扩展注册的后台工作进程还可能有额外的类型。 - + 当前后端的类型。可能的类型为autovacuum launcherautovacuum workerlogical replication launcherlogical replication workerparallel workerbackground writerclient backendcheckpointerarchiverstandalone backendstartupwalreceiverwalsenderwalwriterwalsummarizer。此外,由扩展注册的后台工作进程还可能有额外的类型。 @@ -752,10 +715,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - wait_eventstate列彼此独立。 - 如果某个后端处于active状态,它可能正在等待某个事件,也可能没有等待。 - 如果状态为activewait_event非空, - 就表示某个查询正在执行,但在系统中的某处被阻塞了。 + wait_eventstate列彼此独立。如果某个后端处于active状态,它可能在等待(waiting)某个事件,也可能没有等待。如果状态为activewait_event非空,就意味着某个查询正在执行,但在系统中的某处被阻塞了。 @@ -782,10 +742,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser BufferPin - 服务器进程正在等待对数据缓冲的独占访问。 - 如果另一个进程持有一个打开的游标,该游标最后一次从相关缓冲区读取数据,则缓冲区销等待可能是漫长的。 - 参见。 - + 服务器进程正在等待独占访问一个数据缓冲区。如果另一个进程持有尚未关闭的游标,且该游标最近读取的数据来自此缓冲区,缓冲区钉住等待就可能持续较长时间。参见 @@ -808,7 +765,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser IO - 服务器进程正在等待一个I/O操作完成。wait_event将识别特定的等待点;参见。 + 服务器进程正在等待一个 I/O 操作完成。wait_event将识别特定的等待点;参见 @@ -820,17 +777,14 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser Lock - 服务器进程正在等待一个重量级锁。重量级锁,也称为锁管理器锁或简单锁,主要保护表等SQL可见对象。 + 服务器进程正在等待一个重量级锁。重量级锁,也称为锁管理器锁或简称为锁,主要保护表等SQL可见对象。 然而,它们也用于确保某些内部操作的互斥,例如关系扩展。wait_event将识别等待的锁的类型;参见 LWLock - 服务器进程正在等待一个轻量级锁。大多数这样的锁保护共享内存中的特定数据结构。 - wait_event将包含标识轻量级锁用途的名称。 - (有些锁有特定的名称;其他锁是一组锁的一部分,每个锁具有类似的目的。)参见。 - + 服务器进程正在等待一个轻量级锁。大多数这样的锁保护共享内存中的某个特定数据结构。wait_event将包含标识该轻量级锁用途的名称。(有些锁具有专门的名称,另一些锁属于一组用途相似的锁。)参见 @@ -862,17 +816,17 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - AutoVacuumMain - 在自动清理启动过程的主循环中等待。 + AutovacuumMain + 在自动清理启动进程的主循环中等待。 - BgWriterHibernate - 在后台写入器中等待,休眠状态。 + BgwriterHibernate + 在后台写入器进程中休眠等待。 - BgWriterMain + BgwriterMain 在后台写入器主循环中等待。 @@ -891,19 +845,34 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 在逻辑复制启动器进程的主循环中等待。 + + LogicalParallelApplyMain + 在逻辑复制并行应用进程的主循环中等待。 + + RecoveryWalStream - 流恢复期间,在启动进程主循环等待WAL到达。 + 在流恢复期间,在启动进程的主循环中等待 WAL 到达。 - SysLoggerMain + ReplicationSlotsyncMain + 在复制槽同步工作进程的主循环中等待。 + + + + ReplicationSlotsyncShutdown + 等待复制槽同步工作进程关闭。 + + + + SysloggerMain 在 syslogger 进程的主循环中等待。 WalReceiverMain - 在WAL 接收进程的主循环中等待。 + 在 WAL 接收进程的主循环中等待。 @@ -911,9 +880,14 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 在 WAL 发送进程的主循环中等待。 + + WalSummarizerWal + 在 WAL 汇总进程中等待生成更多 WAL。 + + WalWriterMain - 在WAL写入进程的主循环中等待。 + 在 WAL 写入进程的主循环中等待。 @@ -935,7 +909,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser BufferPin - 等待获得缓冲区上的独占销。 + 等待获得缓冲区上的独占钉住。 @@ -966,28 +940,33 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - GSSOpenServer + GssOpenServer 在建立GSSAPI会话时等待从客户端读取数据。 - LibPQWalReceiverConnect - 在WAL 接收进程等待与远程服务器建立连接。 + LibpqwalreceiverConnect + 在 WAL 接收进程中等待与远程服务器建立连接。 - LibPQWalReceiverReceive - 在WAL 接收进程中等待从远程服务器接收数据。 + LibpqwalreceiverReceive + 在 WAL 接收进程中等待从远程服务器接收数据。 - SSLOpenServer + SslOpenServer 在尝试连接时等待SSL。 - WalSenderWaitForWAL - 在 WAL 发送进程中等待 WAL 被刷新。 + WaitForStandbyConfirmation + 等待物理备库接收 WAL 并将其刷盘。 + + + + WalSenderWaitForWal + 在 WAL 发送进程中等待 WAL 刷盘。 @@ -1035,33 +1014,33 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - BaseBackupRead + BasebackupRead 等待基础备份从文件中读取。 - BaseBackupSync - 等待由基础备份写入的数据达到持久存储。 + BasebackupSync + 等待基础备份写入的数据同步到持久存储。 - BaseBackupWrite + BasebackupWrite 等待基础备份写入文件。 - BufFileRead + BuffileRead 等待从缓冲文件中读取。 - BufFileWrite - 等待对缓冲文件的写入。 + BuffileTruncate + 等待一个缓冲文件被截断。 - BufFileTruncate - 等待一个缓冲文件被截断。 + BuffileWrite + 等待对缓冲文件的写入。 @@ -1071,12 +1050,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser ControlFileSync - 等待pg_control文件到达持久存储。 + 等待 pg_control 文件同步到持久存储。 ControlFileSyncUpdate - 等待更新pg_control文件以达到持久存储。 + 等待对 pg_control 文件的更新同步到持久存储。 @@ -1086,7 +1065,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser ControlFileWriteUpdate - 等待写入更新pg_control文件。 + 等待写入以更新 pg_control 文件。 @@ -1096,12 +1075,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser CopyFileWrite - 在文件拷贝操作期间等待写入。 - - - - DSMFillZeroWrite - 等待用零填充动态共享内存备份(backing)文件。 + 在文件复制操作期间等待写入。 @@ -1111,12 +1085,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser DataFileFlush - 等待关系数据文件达到持久存储。 + 等待关系数据文件同步到持久存储。 DataFileImmediateSync - 等待关系数据文件到持久存储的立即同步。 + 等待关系数据文件立即同步到持久存储。 @@ -1131,7 +1105,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser DataFileSync - 等待对关系数据文件的更改达到持久存储。 + 等待对关系数据文件的更改同步到持久存储。 @@ -1145,17 +1119,27 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - LockFileAddToDataDirRead + DsmAllocate + 等待分配动态共享内存段。 + + + + DsmFillZeroWrite + 等待用零填充动态共享内存的后备文件。 + + + + LockFileAddtodatadirRead 在向数据目录锁文件中添加一行时等待读取。 - LockFileAddToDataDirSync - 等待数据到达持久存储,同时向数据目录锁文件添加一行。 + LockFileAddtodatadirSync + 在向数据目录锁文件中添加一行时,等待数据同步到持久存储。 - LockFileAddToDataDirWrite + LockFileAddtodatadirWrite 在向数据目录锁文件中添加一行时等待写操作。 @@ -1166,7 +1150,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser LockFileCreateSync - 在创建数据目录锁文件时等待数据到达持久存储。 + 在创建数据目录锁文件时,等待数据同步到持久存储。 @@ -1175,18 +1159,18 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - LockFileReCheckDataDirRead + LockFileRecheckdatadirRead 在重新检查数据目录锁文件期间等待读取。 LogicalRewriteCheckpointSync - 等待逻辑重写映射到在检查点到达持久存储。 + 在检查点期间等待逻辑重写映射同步到持久存储。 LogicalRewriteMappingSync - 在逻辑重写期间等待映射数据到达持久存储 + 在逻辑重写期间等待映射数据同步到持久存储。 @@ -1196,12 +1180,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser LogicalRewriteSync - 等待逻辑重写映射到达持久存储。 + 等待逻辑重写映射同步到持久存储。 LogicalRewriteTruncate - 等待在逻辑重写期间截断映射数据。 + 在逻辑重写期间等待截断映射数据。 @@ -1215,8 +1199,8 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - RelationMapSync - 等待关系映射文件到达持久存储。 + RelationMapReplace + 等待关系映射文件的替换结果同步到持久存储。 @@ -1226,17 +1210,17 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser ReorderBufferRead - 在重新排序缓冲区管理期间等待读取。 + 在重排序缓冲区管理期间等待读取。 ReorderBufferWrite - 在重新排序缓冲区管理期间等待写操作。 + 在重排序缓冲区管理期间等待写入。 ReorderLogicalMappingRead - 在重新排序缓冲区管理期间等待读取逻辑映射。 + 在重排序缓冲区管理期间等待读取逻辑映射。 @@ -1246,12 +1230,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser ReplicationSlotRestoreSync - 等待复制槽控制文件到达持久存储,同时将其恢复到内存中。 + 在将复制槽控制文件恢复到内存期间,等待该文件同步到持久存储。 ReplicationSlotSync - 等待复制槽控制文件到达持久存储。 + 等待复制槽控制文件同步到持久存储。 @@ -1260,43 +1244,43 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - SLRUFlushSync - 在检查点或数据库关闭期间等待SLRU数据到达持久存储。 + SlruFlushSync + 在检查点或数据库关闭期间,等待 SLRU 数据同步到持久存储。 - SLRURead + SlruRead 等待读取SLRU页面。 - SLRUSync - 在写页面后等待SLRU数据到达持久存储。 + SlruSync + 在页面写入后等待 SLRU 数据同步到持久存储。 - SLRUWrite + SlruWrite 等待SLRU页面的写入。 SnapbuildRead - 等待读取序列化的历史目录快照。 + 等待读取序列化的历史系统目录快照。 SnapbuildSync - 等待序列化历史目录快照到达持久存储。 + 等待序列化的历史系统目录快照同步到持久存储。 SnapbuildWrite - 等待串行历史目录快照的写入。 + 等待写入序列化的历史系统目录快照。 TimelineHistoryFileSync - 等待通过流复制接收的时间线历史文件到达持久存储。 + 等待通过流复制接收的时间线历史文件同步到持久存储。 @@ -1311,7 +1295,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser TimelineHistorySync - 等待新创建的时间线历史文件到达持久存储。 + 等待新创建的时间线历史文件同步到持久存储。 @@ -1326,7 +1310,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser TwophaseFileSync - 等待两阶段状态文件到达持久存储。 + 等待两阶段状态文件同步到持久存储。 @@ -1336,7 +1320,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser VersionFileSync - 等待版本文件达到持久存储,同时创建数据库。 + 在创建数据库时,等待版本文件同步到持久存储。 @@ -1345,63 +1329,73 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - WALBootstrapSync - 在引导过程中等待WAL达到持久存储。 + WalsenderTimelineHistoryRead + 在 WAL 发送进程执行时间线命令期间,等待从时间线历史文件读取。 + + + + WalBootstrapSync + 在引导过程中等待 WAL 同步到持久存储。 - WALBootstrapWrite + WalBootstrapWrite 在引导过程中等待WAL页面的写入。 - WALCopyRead + WalCopyRead 通过复制一个已有WAL段来创建一个新的WAL段时等待读取。 - WALCopySync - 等待通过复制一个已有WAL段到持久存储来创建一个新的WAL段。 + WalCopySync + 等待通过复制现有 WAL 段创建的新 WAL 段同步到持久存储。 - WALCopyWrite + WalCopyWrite 通过复制一个已有WAL段来创建一个新的WAL段时等待写入。 - WALInitSync - 等待一个新初始化的WAL文件到持久存储。 + WalInitSync + 等待新初始化的 WAL 文件同步到持久存储。 - WALInitWrite + WalInitWrite 在初始化一个新的WAL文件时等待写入。 - WALRead + WalRead 等待WAL文件的读取。 - WALSenderTimelineHistoryRead - 在walsender时间线命令期间等待从时间线历史文件读取。 + WalSummaryRead + 等待从 WAL 汇总文件读取。 - WALSync - 等待WAL文件到达持久存储。 + WalSummaryWrite + 等待写入 WAL 汇总文件。 - WALSyncMethodAssign - 等待数据到达持久存储,同时分配一个新的WAL同步方法。 + WalSync + 等待 WAL 文件同步到持久存储。 - WALWrite - 等待写入WAL文件。 + WalSyncMethodAssign + 在设置新的 WAL 同步方法时,等待数据同步到持久存储。 + + + + WalWrite + 等待写入 WAL 文件。 @@ -1447,23 +1441,33 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - BgWorkerShutdown + BgworkerShutdown 等待后台工作进程关闭。 - BgWorkerStartup + BgworkerStartup 等待后台工作进程启动。 BtreePage - 正等待继续并行B-树扫描所需的页号变得可用。 + 等待继续并行 B-树扫描所需的页号变得可用。 - BufferIO - 等待缓冲I/O结束。 + BufferIo + 等待缓冲区 I/O 完成。 + + + + CheckpointDelayComplete + 等待阻碍检查点完成的后端。 + + + + CheckpointDelayStart + 等待阻碍检查点开始的后端。 @@ -1478,82 +1482,92 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser ExecuteGather - 在执行Gather 计划节点时,等待子进程的活动。 + 在执行 Gather 计划节点时,等待子进程的活动。 HashBatchAllocate - 等待一个选定的并行哈希参与者分配哈希表。 + 等待选出的 Parallel Hash 参与者分配哈希表。 HashBatchElect - 等待选择一个并行哈希参与者来分配哈希表。 + 等待选出负责分配哈希表的 Parallel Hash 参与者。 HashBatchLoad - 等待其他并行哈希参与者完成哈希表的加载。 + 等待其他 Parallel Hash 参与者完成哈希表的加载。 HashBuildAllocate - 等待一个选定的并行哈希参与者分配初始哈希表。 + 等待选出的 Parallel Hash 参与者分配初始哈希表。 HashBuildElect - 等待选择一个并行哈希参与者来分配初始哈希表。 + 等待选出负责分配初始哈希表的 Parallel Hash 参与者。 HashBuildHashInner - 等待其他并行哈希参与者完成内部关系的散列。 + 等待其他 Parallel Hash 参与者完成对内层关系的哈希处理。 HashBuildHashOuter - 等待其他Parallel 哈希参与者完成对外部关系的分区。 - - - - HashGrowBatchesAllocate - 等待选定的并行哈希参与者分配更多批处理。 + 等待其他 Parallel Hash 参与者完成对外层关系的分区。 HashGrowBatchesDecide - 等待选择一个并行哈希参与者来决定未来的批处理增长。 + 等待选出负责决定后续批次增长的 Parallel Hash 参与者。 HashGrowBatchesElect - 等待选择一个Parallel 哈希参与者来分配更多批处理。 + 等待选出负责分配更多批次的 Parallel Hash 参与者。 HashGrowBatchesFinish - 等待当选的平行散列参与者决定未来的批量增长。 + 等待选出的 Parallel Hash 参与者决定后续的批次增长。 - HashGrowBatchesRepartition - 等待一个选定的并行哈希参与者决定未来的批处理增长。 + HashGrowBatchesReallocate + 等待选出的 Parallel Hash 参与者分配更多批次。 - HashGrowBucketsAllocate - 等待选定的并行哈希参与者完成更多bucket的分配。 + HashGrowBatchesRepartition + 等待其他 Parallel Hash 参与者完成重新分区。 HashGrowBucketsElect - 等待选择一个并行哈希参与者来分配更多的buckets。 + 等待选出负责分配更多桶的 Parallel Hash 参与者。 + + + + HashGrowBucketsReallocate + 等待选出的 Parallel Hash 参与者完成更多桶的分配。 HashGrowBucketsReinsert - 等待其他Parallel 哈希参与者完成将元组插入到新buckets中。 + 等待其他 Parallel Hash 参与者完成向新桶插入元组。 + + + + LogicalApplySendData + 等待逻辑复制领导者应用进程向并行应用进程发送数据。 + + + + LogicalParallelApplyStateChange + 等待逻辑复制并行应用进程改变状态。 @@ -1586,24 +1600,29 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 等待将字节发送到共享消息队列。 + + MultixactCreation + 等待多事务创建完成。 + + ParallelBitmapScan - 等待并行位图扫描被初始化。 + 等待并行位图扫描完成初始化。 ParallelCreateIndexScan - 等待并行CREATE INDEX 工作进程完成堆扫描。 + 等待并行 CREATE INDEX 工作进程完成堆扫描。 ParallelFinish - 等待并行工作人员完成计算。 + 等待并行工作进程完成计算。 - ProcArrayGroupUpdate - 等待组领导在并行操作结束时清除事务ID。 + ProcarrayGroupUpdate + 等待组领导者在事务结束时清除事务 ID。 @@ -1618,12 +1637,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser RecoveryConflictSnapshot - 等待vacuum清理的恢复冲突解决。 + 等待解决清理操作引发的恢复冲突。 RecoveryConflictTablespace - 等待恢复冲突解决删除表空间。 + 等待解决删除表空间引发的恢复冲突。 @@ -1658,7 +1677,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser SyncRep - 在同步复制期间等待远程服务器的确认。 + 在同步复制期间等待来自远程服务器的确认。 @@ -1666,14 +1685,24 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 等待WAL 接收进程退出。 + + WalReceiverUpstreamCatchup + 等待上游服务器的 WAL 刷盘位置追上请求的起始点。 + + WalReceiverWaitStart 等待启动进程为流复制发送初始数据。 + + WalSummaryReady + 等待生成新的 WAL 汇总。 + + XactGroupUpdate - 等待分组组长在并行操作结束时更新事务状态。 + 等待组领导者在事务结束时更新事务状态。 @@ -1695,7 +1724,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser advisory - 等待获得一个建议用户锁。 + 等待获取用户咨询锁。 + + + + applytransaction + 等待获取逻辑复制订阅者正在应用的远程事务上的锁。 @@ -1705,8 +1739,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser frozenid - 等待升级 pg_database.datfrozenxid - 和 pg_database.datminmxid. + 等待更新 pg_database.datfrozenxidpg_database.datminmxid @@ -1721,12 +1754,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser relation - 等待获得一个关系的锁。 + 等待获取关系上的锁。 spectoken - 等待获取推测的插入锁。 + 等待获取推测插入锁。 @@ -1746,7 +1779,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser virtualxid - 等待获取虚拟事务ID锁。 + 等待获取虚拟事务 ID 锁;参见 @@ -1768,7 +1801,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser AddinShmemInit - 等待管理共享内存中的扩展空间分配。 + 等待管理扩展在共享内存中的空间分配。 @@ -1783,7 +1816,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser AutovacuumSchedule - 等待确保选择为自动清理的表仍然需要清理。 + 等待确认选中进行自动清理的表是否仍需清理。 @@ -1813,7 +1846,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser CommitTs - 等待读取或更新事务提交时间戳的最后一个值集。 + 等待读取或更新最近设置的事务提交时间戳值。 @@ -1831,11 +1864,31 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 等待读取或更新pg_control文件或创建一个新的WAL文件。 + + DSMRegistry + 等待读取或更新动态共享内存注册表。 + + + + DSMRegistryDSA + 等待访问动态共享内存注册表的动态共享内存分配器。 + + + + DSMRegistryHash + 等待访问动态共享内存注册表的共享哈希表。 + + DynamicSharedMemoryControl 等待读取或更新动态共享内存分配信息。 + + InjectionPoint + 等待读取或更新注入点相关信息。 + + LockFastPath 等待读取或更新进程的快速路径锁信息。 @@ -1843,42 +1896,52 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser LockManager - 等待读取或更新关于heavyweight锁。 + 等待读取或更新有关重量级锁的信息。 + + + + LogicalRepLauncherDSA + 等待访问逻辑复制启动进程的动态共享内存分配器。 + + + + LogicalRepLauncherHash + 等待访问逻辑复制启动进程的共享哈希表。 LogicalRepWorker - 等待读取或更新逻辑复制工作器的状态。 + 等待读取或更新逻辑复制工作进程的状态。 MultiXactGen - 等待读取或更新共享的multixact状态。 + 等待读取或更新共享的多事务状态。 MultiXactMemberBuffer - 在multixact成员SLRU缓冲区上等待I/O。 + 等待多事务成员 SLRU 缓冲区上的 I/O。 MultiXactMemberSLRU - 等待访问multixact成员SLRU缓存。 + 等待访问多事务成员 SLRU 缓存。 MultiXactOffsetBuffer - 在multixact 偏移 SLRU缓冲区上等待I/O。 + 等待多事务偏移量 SLRU 缓冲区上的 I/O。 MultiXactOffsetSLRU - 等待访问multixact 偏移 SLRU缓存。 + 等待访问多事务偏移量 SLRU 缓存。 MultiXactTruncation - 等待读取或截断multixact信息。 + 等待读取或截断多事务信息。 @@ -1893,7 +1956,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser NotifyQueueTail - 等待NOTIFY消息存储上的更新限制。 + 等待更新 NOTIFY 消息存储的限制。 @@ -1906,19 +1969,14 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 等待分配一个新的OID。 - - OldSnapshotTimeMap - 等待读取或更新旧的快照控制信息。 - - ParallelAppend - 在并行附加计划执行期间等待选择下一个子计划。 + 在 Parallel Append 计划执行期间等待选择下一个子计划。 ParallelHashJoin - 在并行哈希连接计划执行期间等待同步工作器。 + 在 Parallel Hash Join 计划执行期间等待同步工作进程。 @@ -1926,6 +1984,11 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 等待并行查询动态共享内存分配。 + + ParallelVacuumDSA + 等待为并行清理分配动态共享内存。 + + PerSessionDSA 等待并行查询动态共享内存分配。 @@ -1933,12 +1996,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser PerSessionRecordType - 等待访问有关复合类型的并行查询信息。 + 等待访问并行查询中有关复合类型的信息。 PerSessionRecordTypmod - 等待访问有关标识匿名记录类型的类型修饰符的并行查询信息。 + 等待访问并行查询中用于标识匿名记录类型的类型修饰符信息。 @@ -1946,6 +2009,21 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 在并行查询期间等待访问当前可串行化事务持有的谓词锁列表。 + + PgStatsData + 等待访问共享内存中的统计数据。 + + + + PgStatsDSA + 等待访问统计信息的动态共享内存分配器。 + + + + PgStatsHash + 等待访问统计信息的共享内存哈希表。 + + PredicateLockManager 等待访问可串行化事务使用的谓词锁信息。 @@ -1953,7 +2031,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser ProcArray - 等待访问每个进程共享的数据结构(通常情况,是获取快照或报告会话的事务ID)。 + 等待访问各进程的共享数据结构(通常是为了获取快照或报告会话的事务 ID)。 @@ -1996,6 +2074,11 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 在可串行化事务冲突的SLRU缓冲区上等待I/O。 + + SerialControl + 等待读取或更新共享的 pg_serial 状态。 + + SerializableFinishedList 等待访问已完成的可串行化事务列表。 @@ -2006,21 +2089,6 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 等待访问可串行化事务持有的谓词锁列表。 - - PgStatsDSA - 等待统计动态共享内存分配器访问 - - - - PgStatsHash - 等待统计共享内存哈希表访问 - - - - PgStatsData - 等待共享内存统计数据访问 - - SerializableXactHash 等待读取或更新关于可串行化事务的信息。 @@ -2048,12 +2116,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser SInvalRead - 等待从共享目录失效队列中检索消息。 + 等待从共享系统目录失效队列中取出消息。 SInvalWrite - 等待向共享编目失效队列添加消息。 + 等待向共享系统目录失效队列添加消息。 @@ -2083,7 +2151,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser TwoPhaseState - 等待读取或更新已准备事务的状态。 + 等待读取或更新预备事务的状态。 + + + + WaitEventCustom + 等待读取或更新自定义等待事件信息。 @@ -2096,6 +2169,11 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 等待将WAL数据插入内存缓冲区。 + + WALSummarizer + 等待读取或更新 WAL 汇总状态。 + + WALWrite 等待WAL缓冲区写入磁盘。 @@ -2103,7 +2181,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser WrapLimitsVacuum - 等待更新事务 ID和multixact消费的限制。 + 等待更新事务 ID 和多事务消耗量的限制。 @@ -2129,13 +2207,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - - - 扩展可以将ExtensionInjectionPointLWLock 类型添加到所示的列表中。 - 在某些情况下,扩展分配的 LWLock 名称无法在所有服务器进程中使用;因此,LWLock 等待事件可能只会被报告为extension,而不是扩展分配的名称。 - - @@ -2153,12 +2225,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser BaseBackupThrottle - 当有限流活动时在基础备份期间等待。 + 在基础备份期间因限流而等待。 CheckpointWriteDelay - 在执行检查点时写入之间的等待时间。 + 在执行检查点时,在各次写入之间等待。 @@ -2178,24 +2250,34 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser RegisterSyncRequest - 在发送同步请求到检查点程序时等待,因为请求队列已满。 + 向检查点进程发送同步请求时,因请求队列已满而等待。 + + + + SpinDelay + 在获取有竞争的自旋锁时等待。 VacuumDelay - 在一个基于代价的清理延迟点。 + 在基于代价的清理延迟点等待。 VacuumTruncate 等待获取独占锁以截断被清理的表末尾的空页面。 + + + WalSummarizerError + 在 WAL 汇总进程出错后等待。 +
- 这里是一个查看等待事件的示例: + 以下示例展示如何查看等待事件: SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event is NOT NULL; @@ -2219,6 +2301,14 @@ description | Waiting for a newly initialized WAL file to reach durable storage + + + + 扩展可以将ExtensionInjectionPointLWLock 事件添加到所示的列表中。 + 在某些情况下,扩展分配的 LWLock 名称无法在所有服务器进程中使用;它可能只会被报告为extension,而不是扩展分配的名称。 + + + @@ -2293,7 +2383,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage 连接到这个 WAL 发送进程的客户端的 IP 地址。 - 如果这个域为空,它表示该客户端通过服务器机器上的一个Unix 套接字连接。 + 如果这个字段为空值,它表示该客户端通过服务器机器上的一个Unix 套接字连接。
@@ -2344,27 +2434,27 @@ description | Waiting for a newly initialized WAL file to reach durable storage - startup: 此 WAL 发送进程正在启动。 + startup: 此 WAL 发送进程正在启动。 - catchup: 与此 WAL 发送进程连接的备库正在赶上主库。 + catchup: 与此 WAL 发送进程连接的备库正在赶上主库。 - streaming: 在其连接的备库赶上主库之后,此 WAL 发送进程正在流式传输更改。 + streaming: 在其连接的备库赶上主库之后,此 WAL 发送进程正在流式传输更改。 - backup: 此 WAL 发送进程正在发送一个备份。 + backup: 此 WAL 发送进程正在发送一个备份。 - stopping: 此 WAL 发送进程正在停止。 + stopping: 此 WAL 发送进程正在停止。 @@ -2411,30 +2501,21 @@ description | Waiting for a newly initialized WAL file to reach durable storage write_lag interval - - 从本地刷写最近的 WAL,到收到该备库已写入该 WAL(但尚未刷盘或应用)的通知之间经过的时间。 - 如果该服务器被配置为同步备库,可用此值衡量在提交时 synchronous_commit 级别 remote_write 所导致的延迟。 - + 从在本地将最近的 WAL 刷盘,到收到该备库已写入该 WAL(但尚未刷盘或应用)的通知之间经过的时间。如果该服务器被配置为同步备库,可用此值衡量在提交时synchronous_commit级别remote_write所导致的延迟。
flush_lag interval - - 从本地刷写最近的 WAL,到收到该备库已写入并刷写该 WAL(但尚未应用)的通知之间经过的时间。 - 如果该服务器被配置为同步备库,可用此值衡量在提交时 synchronous_commit 级别 on 所导致的延迟。 - + 从在本地将最近的 WAL 刷盘,到收到该备库已写入该 WAL 并将其刷盘(但尚未应用)的通知之间经过的时间。如果该服务器被配置为同步备库,可用此值衡量在提交时synchronous_commit级别on所导致的延迟。 replay_lag interval - - 从本地刷写最近的 WAL,到收到该备库已写入、刷写并应用该 WAL 的通知之间经过的时间。 - 如果该服务器被配置为同步备库,可用此值衡量在提交时 synchronous_commit 级别 remote_apply 所导致的延迟。 - + 从在本地将最近的 WAL 刷盘,到收到该备库已写入该 WAL、将其刷盘并应用的通知之间经过的时间。如果该服务器被配置为同步备库,可用此值衡量在提交时synchronous_commit级别remote_apply所导致的延迟。 @@ -2456,22 +2537,22 @@ description | Waiting for a newly initialized WAL file to reach durable storage - async: 该备库是异步的。 + async: 该备库是异步的。 - potential: 该备库当前是异步的,但在当前同步备库失效时可能变为同步的。 + potential: 该备库当前是异步的,但在当前某个同步备库失效时可能变为同步的。 - sync: 该备库是同步的。 + sync: 该备库是同步的。 - quorum: 该备库被作为法定人数同步复制候选备库。 + quorum: 该备库被作为法定人数同步复制候选备库。 @@ -2480,7 +2561,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - reply_time 带时区的时间戳 + reply_time timestamp with time zone 从备库收到的最后一条回复消息的发送时间 @@ -2491,17 +2572,17 @@ description | Waiting for a newly initialized WAL file to reach durable storage - pg_stat_replication视图中报告的滞后时间,是最近的 WAL 被写入、刷写和重放,以及发送端获知这些操作完成所花费时间的度量。如果远程服务器被配置为同步备库,这些时间表示各个同步提交级别带来或可能带来的提交延迟。对于异步备库,replay_lag列是最近事务对查询变得可见所需延迟时间的近似值。如果备库已经完全追上发送服务器且没有新的 WAL 活动,系统会在短时间内继续显示最近测得的滞后时间,随后显示为 NULL。 + pg_stat_replication视图中报告的滞后时间,是最近的 WAL 被写入、刷盘和重放,以及发送端获知这些操作完成所花费时间的度量。如果远程服务器被配置为同步备库,这些时间表示各个同步提交级别带来或可能带来的提交延迟。对于异步备库,replay_lag列是最近事务对查询变得可见所需延迟时间的近似值。如果备库已经完全追上发送服务器且没有新的 WAL 活动,系统会在短时间内继续显示最近测得的滞后时间,随后显示为 空值。 - 对于物理复制,滞后时间会自动测量。逻辑解码插件可以选择发出跟踪消息;如果没有这样做,跟踪机制会将滞后显示为 NULL。 + 对于物理复制,滞后时间会自动测量。逻辑解码插件可以选择发出跟踪消息;如果没有这样做,跟踪机制会将滞后显示为 空值。 - 报告出的滞后时间并不是根据当前重放速率预测该备库还需多久才能追上发送服务器。在持续生成新 WAL 时,那样的系统可能会显示相近的时间;但当发送端空闲时,就会显示不同的值。特别是当备库已经完全追上时,pg_stat_replication显示的是写入、刷写和重放最近报告的 WAL 位置所花费的时间,而不是某些用户可能预期的零。这样做符合为最近写事务测量同步提交和事务可见性延迟的目的。为减少用户因预期另一种滞后模型而产生的混淆,在一个已完全重放且处于空闲状态的系统上,lag 列会在较短时间后恢复为 NULL。监控系统应自行决定将这种情况表示为缺失数据、零,还是继续显示最近一次已知值。 + 报告出的滞后时间并不是根据当前重放速率预测该备库还需多久才能追上发送服务器。在持续生成新 WAL 时,那样的系统可能会显示相近的时间;但当发送端空闲时,就会显示不同的值。特别是当备库已经完全追上时,pg_stat_replication显示的是写入、刷盘和重放最近报告的 WAL 位置所花费的时间,而不是某些用户可能预期的零。这样做符合为最近写事务测量同步提交和事务可见性延迟的目的。为减少用户因预期另一种滞后模型而产生的混淆,在一个已完全重放且处于空闲状态的系统上,滞后列会在较短时间后恢复为 空值。监控系统应自行决定将这种情况表示为缺失数据、零,还是继续显示最近一次已知值。 @@ -2540,19 +2621,14 @@ description | Waiting for a newly initialized WAL file to reach durable storage slot_name text - - 唯一的,复制槽的集簇范围标识符 - + 复制槽在整个集簇范围内的唯一标识符 spill_txns bigint - - 当逻辑解码在解码来自WAL的更改时所使用的内存超过logical_decoding_work_mem,溢出到磁盘的事务数。 - 顶级事务和子事务的计数器都是递增的。 - + 当逻辑解码从 WAL 解码更改时所使用的内存超过logical_decoding_work_mem后,溢出到磁盘的事务数。顶层事务和子事务都会使此计数器递增。 @@ -2560,7 +2636,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage spill_count bigint - 在为该槽位解码来自WAL的更改时,事务溢出到磁盘的次数。 + 在为该槽解码来自WAL的更改时,事务溢出到磁盘的次数。 此计数器在每次事务被溢出时递增,并且同一事务可能被溢出多次。 @@ -2569,20 +2645,14 @@ description | Waiting for a newly initialized WAL file to reach durable storage spill_bytes bigint - - 在对来自WAL的更改执行解码时,已解码的事务数据溢出到磁盘的数量。 - 这个和其他溢出计数器可用于测量逻辑解码期间发生的I/O,并且允许调优logical_decoding_work_mem。 - + 为此槽从 WAL 解码更改时,溢出到磁盘的已解码事务数据量。此计数器及其他溢出计数器可用于衡量逻辑解码期间发生的 I/O,并用于调优logical_decoding_work_mem stream_txns bigint - - 在逻辑解码在解码来自该槽位的WAL更改的时候,所使用的内存超过logical_decoding_work_mem之后,流式传输到解码输出插件的正在进行的事务数。 - 流式传输仅对顶级事务有效(子事务不能独立进行流式传输),因此子事务的计数器不会增加。 - + 当逻辑解码为此槽从 WAL 解码更改时所使用的内存超过logical_decoding_work_mem后,流式传输到解码输出插件的进行中事务数。流式传输仅适用于顶层事务(子事务不能单独进行流式传输),因此子事务不会使此计数器递增。 @@ -2590,7 +2660,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage stream_countbigint - 在为该槽位解码来自WAL的更改时,将正在进行的事务流式传输到解码输出插件的次数。 + 在为该槽解码来自WAL的更改时,将进行中事务流式传输到解码输出插件的次数。 此计数器在每次事务流式传输时递增,并且同一事务可能被流式传输多次。 @@ -2600,8 +2670,8 @@ description | Waiting for a newly initialized WAL file to reach durable storage stream_bytesbigint - 在为该槽位解码来自WAL的更改时,为将正在进行的事务流式传输到解码输出插件而解码的事务数据的数量。 - 这个和针对此槽位的其他流式传输计数器可用于调优logical_decoding_work_mem。 + 在为该槽解码来自WAL的更改时,为将进行中事务流式传输到解码输出插件而解码的事务数据量。 + 这个和针对此槽的其他流式传输计数器可用于调优logical_decoding_work_mem
@@ -2612,7 +2682,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage 针对此槽的,发送到解码输出插件的已解码事务数。 - 这只计算顶级事务,对子事务不会增加。 + 这只计算顶层事务,对子事务不会增加。 注意,这包括流式传输和/或溢出的事务。
@@ -2622,7 +2692,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage total_bytesbigint - 在对此槽位的WAL进行解码时,为将事务发送到解码输出插件而解码的事务数据量。 + 在为此槽从 WAL 解码更改时,为将事务发送到解码输出插件而解码的事务数据量。 注意这包括流式传输和/或溢出的数据。 @@ -2632,9 +2702,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage stats_reset timestamp with time zone - - 这些统计最后重置的时间 - + 这些统计信息上次被重置的时间
@@ -2649,9 +2717,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage pg_stat_wal_receiver - - pg_stat_wal_receiver事务只包含一行,它显示了从 WAL 接收进程所连接的服务器得到的有关该接收进程的统计信息。 - + pg_stat_wal_receiver视图只包含一行,显示 WAL 接收进程从其所连接服务器接收数据的统计信息。 @@ -2676,7 +2742,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage pidinteger - WAL 接收进程的进程ID + WAL 接收进程的进程 ID @@ -2685,7 +2751,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage statustext - WAL接收进程的活动状态 + WAL 接收进程的活动状态 @@ -2694,7 +2760,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage receive_start_lsnpg_lsn - WAL 接收进程启动时使用的第一个写前日志位置 + WAL 接收进程启动时使用的第一个预写式日志位置 @@ -2703,7 +2769,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage receive_start_tliinteger - WAL 接收进程启动时使用的第一个时间线数字 + WAL 接收进程启动时使用的第一个时间线编号 @@ -2712,7 +2778,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage written_lsnpg_lsn - 已经接收并写入磁盘的最后一个预写式日志位置,但没有刷入。这不能用于数据完整性检查。 + 已经接收并写入磁盘的最后一个预写式日志位置,但尚未刷盘。此字段不应用于数据完整性检查。 @@ -2721,7 +2787,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage flushed_lsnpg_lsn - 已经接收并刷入到磁盘的最后一个预写式日志位置,该字段的初始值是启动WAL 接收进程时使用的第一个日志位置 + 已经接收并刷入到磁盘的最后一个预写式日志位置,该字段的初始值是启动 WAL 接收进程时使用的第一个日志位置 @@ -2730,7 +2796,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage received_tliinteger - 接收并刷入到磁盘的最后一个预写式日志位置的时间线数字,该字段的初始值为启动WAL 接收进程时使用的第一个日志位置的时间线数字 + 接收并刷入到磁盘的最后一个预写式日志位置的时间线编号,该字段的初始值为启动 WAL 接收进程时使用的第一个日志位置的时间线编号 @@ -2775,7 +2841,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage slot_nametext - 这个WAL 接收进程使用的复制槽的名称 + 这个 WAL 接收进程使用的复制槽的名称 @@ -2784,8 +2850,8 @@ description | Waiting for a newly initialized WAL file to reach durable storage sender_hosttext - 这个WAL 接收进程连接到的PostgreSQL实例的主机。 - 这可以是主机名、IP地址,或者目录路径,如果连接是通过Unix套接字进行的。(路径的情况可以区分,因为它总是以/开头的绝对路径。) + 这个 WAL 接收进程连接到的PostgreSQL实例的主机。 + 这可以是主机名、IP地址,或者目录路径,如果连接是通过Unix套接字进行的。(路径的情况可以区分,因为它总是以/开头的绝对路径。) @@ -2794,7 +2860,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage sender_portinteger - 这个WAL 接收进程连接的PostgreSQL实例的端口号。 + 这个 WAL 接收进程连接的PostgreSQL实例的端口号。 @@ -2803,7 +2869,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage conninfotext - 这个WAL 接收进程使用的连接字符串,对安全敏感的字段进行了模糊处理。 + 这个 WAL 接收进程使用的连接字符串,对安全敏感的字段进行了模糊处理。 @@ -2849,9 +2915,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage stats_reset timestamp with time zone - - 这些统计数据上次重置的时间 - + 这些统计信息上次被重置的时间 @@ -2926,9 +2990,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage wal_distance int - - 预取器向前查看多少字节 - + 预取器向前查看的字节数 @@ -2937,9 +2999,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage block_distance int - - 预取器正在查看多少个块之前 - + 预取器向前查看的块数 @@ -2948,9 +3008,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage io_depth int - - 已启动但尚未完成的预取数量 - + 已启动但尚未确认完成的预取数量 @@ -2993,7 +3051,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + subname name @@ -3002,7 +3060,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + worker_type text @@ -3011,7 +3069,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + pid integer @@ -3020,59 +3078,69 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + + + leader_pid integer + + + 如果此进程是并行应用工作进程,则为领导者应用工作进程的进程 ID;如果此进程是领导者应用工作进程或表同步工作进程,则为 NULL + + + + relid oid - 该工作进程正在同步的关系的 OID;主应用工作进程则为 NULL + 该工作进程正在同步的关系的 OID;对于领导者应用工作进程和并行应用工作进程,则为空值 - + received_lsn pg_lsn - 接收到的最后一个预写式日志位置,该字段的初始值为0 + 接收到的最后一个预写式日志位置,该字段的初始值为 0;对于并行应用工作进程,则为 NULL - + last_msg_send_time timestamp with time zone - 从源 WAL 发送进程收到的最后一条消息的发送时间 + 从源 WAL 发送进程收到的最后一条消息的发送时间;对于并行应用工作进程,则为 NULL - + last_msg_receipt_time timestamp with time zone - 从源 WAL 发送进程收到的最后一条消息的接收时间 + 从源 WAL 发送进程收到的最后一条消息的接收时间;对于并行应用工作进程,则为 NULL - + latest_end_lsn pg_lsn - 向源 WAL 发送进程报告的最后一个预写式日志位置 + 向源 WAL 发送进程报告的最后一个预写式日志位置;对于并行应用工作进程,则为 NULL - + latest_end_time timestamp with time zone - 向 WAL 发送进程报告最后一个预写式日志位置的时间 + 向源 WAL 发送进程报告最后一个预写式日志位置的时间;对于并行应用工作进程,则为 NULL +
@@ -3148,9 +3216,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage stats_reset timestamp with time zone - - 这些统计数据最后一次重置的时间 - + 这些统计信息上次被重置的时间
@@ -3211,7 +3277,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage version text - 使用SSL的版本,如果此连接上没有使用SSL则为NULL + 使用SSL的版本,如果此连接上没有使用SSL则为空值
@@ -3220,7 +3286,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage cipher text - 正在使用的SSL密码的名称,如果此连接上没有使用SSL则为NULL + 正在使用的SSL 密码套件的名称,如果此连接上没有使用SSL则为空值
@@ -3229,7 +3295,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage bits integer - 使用的加密算法中的位数,如果此连接上没有使用SSL则为NULL + 使用的加密算法中的位数,如果此连接上没有使用SSL则为空值
@@ -3238,8 +3304,8 @@ description | Waiting for a newly initialized WAL file to reach durable storage client_dn text - 区别名称(DN,Distinguished Name)字段与使用的客户端证书,如果没有提供客户端证书或在此连接上没有使用SSL,则为NULL。 - 如果DN字段长于NAMEDATALEN(标准构建中为64个字符),则该字段将被截断。 + 所用客户端证书中的区别名称(DN,Distinguished Name)字段,如果没有提供客户端证书或在此连接上没有使用SSL,则为空值。 + 如果DN字段长于NAMEDATALEN(标准构建中为64个字符),则该字段将被截断。
@@ -3248,8 +3314,8 @@ description | Waiting for a newly initialized WAL file to reach durable storage client_serial numeric - 客户端证书的序列号,如果没有提供客户端证书或在此连接上没有使用SSL,则为NULL。 - 证书序列号和证书颁发者的组合唯一标识一个证书(除非颁发者错误地重用序列号)。 + 客户端证书的序列号,如果没有提供客户端证书或在此连接上没有使用SSL,则为空值。 + 证书序列号和证书颁发者的组合唯一标识一个证书(除非颁发者错误地重用序列号)。
@@ -3258,7 +3324,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage issuer_dn text - 客户端证书颁发者的区别名称(DN,Distinguished Name),如果没有提供客户端证书或在此连接上没有使用SSL,则为NULL。该字段像client_dn一样被截断。 + 客户端证书颁发者的区别名称(DN,Distinguished Name),如果没有提供客户端证书或在此连接上没有使用SSL,则为空值。该字段像client_dn一样被截断。
@@ -3276,7 +3342,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage pg_stat_gssapi视图将包含每一个后端一个行,显示该连接上的GSSAPI使用情况。 - 它可以加入到pg_stat_activitypg_stat_replication上的pid列,获取更多关于连接的详细信息。 + 可以通过pid列将它与pg_stat_activitypg_stat_replication连接,获取更多关于连接的详细信息。 @@ -3320,8 +3386,8 @@ description | Waiting for a newly initialized WAL file to reach durable storage principaltext - 用于验证此连接的主体,如果未使用GSSAPI对此连接进行认证,则为NULL。 - 如果主体长度超过NAMEDATALEN(标准构建中为64个字符),则该字段被截断。 + 用于认证此连接的主体,如果未使用GSSAPI对此连接进行认证,则为空值。 + 如果主体长度超过NAMEDATALEN(标准构建中为64个字符),则该字段被截断。 @@ -3435,9 +3501,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage stats_reset timestamp with time zone - - 这些统计数据最后一次重置的时间 - + 这些统计信息上次被重置的时间 @@ -3461,11 +3525,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage pg_stat_io 视图对每种后端类型、目标 I/O 对象和 I/O 上下文的组合各提供一行,显示整个集簇范围内的 I/O 统计信息。没有意义的组合会被省略。 - - Currently, I/O on relations (e.g. tables, indexes) is tracked. However, - relation I/O which bypasses shared buffers (e.g. when moving a table from one - tablespace to another) is currently not tracked. - + 目前会跟踪关系(例如表、索引)的 I/O。不过,绕过共享缓冲区的关系 I/O(例如将表从一个表空间移动到另一个表空间时)目前不会被跟踪。
<structname>pg_stat_io</structname> 视图 @@ -3489,7 +3549,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage backend_typetext - 后端类型(例如后台工作进程、autovacuum 工作进程)。有关 backend_type 的更多信息,请参阅pg_stat_activity。某些 backend_type 不会累计 I/O 操作统计信息,因此不会出现在该视图中。 + 后端类型(例如后台工作进程、自动清理工作进程)。有关 backend_type 的更多信息,请参阅pg_stat_activity。某些 backend_type 不会累积 I/O 操作统计信息,因此不会出现在该视图中。 @@ -3501,7 +3561,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage I/O 操作的目标对象。可能的值有: - + @@ -3514,6 +3574,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage + @@ -3533,7 +3594,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - vacuum:对永久关系执行 vacuum 和 analyze 时,在共享缓冲区之外执行的 I/O 操作。临时表 vacuum 与其他临时表 I/O 操作共用同一本地缓冲池,因此会在 contextnormal 时跟踪。 + vacuum:对永久关系执行清理和分析 时,在共享缓冲区之外执行的 I/O 操作。临时表清理 与其他临时表 I/O 操作共用同一本地缓冲池,因此会在 contextnormal 时跟踪。 @@ -3722,9 +3783,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage stats_reset timestamp with time zone - - 这些统计信息上次被重置的时间。 - + 这些统计信息上次被重置的时间。 @@ -3736,7 +3795,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - 此外,某些 I/O 操作永远不会由某些后端类型执行,或者永远不会针对某些 I/O 对象和/或在某些 I/O 上下文中执行。这些单元格会是 NULL。例如,临时表不会执行 fsync,因此当 objecttemp relation 时,fsyncs 将为 NULL。又如,后台写入器不会执行读取,因此当 backend_typebackground writer 时,reads 将为 NULL。 + 此外,某些 I/O 操作永远不会由某些后端类型执行,或者永远不会针对某些 I/O 对象和/或在某些 I/O 上下文中执行。这些单元格会是空值。例如,临时表不会执行 fsync,因此当 objecttemp relation 时,fsyncs 将为空值。又如,后台写入器不会执行读取,因此当 backend_typebackground writer 时,reads 将为空值。 @@ -3749,7 +3808,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - 客户端后端依赖检查点进程确保数据持久化到永久存储。客户端后端出现大量 fsyncs 可能表明共享缓冲区或检查点进程配置不当。有关配置检查点进程的更多信息,请参阅。 + 客户端后端依赖检查点进程确保数据持久化到永久存储。client backend出现大量 fsyncs 可能表明共享缓冲区或检查点进程配置不当。有关配置检查点进程的更多信息,请参阅 @@ -3761,12 +3820,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - - 只有在启用时,跟踪 I/O 时间的列才会 - 非零。若自上次统计信息重置以来的整个期间并未始终启用 - track_io_timing,则在将这些列与相应的 I/O 操作结合引用时 - 应格外小心。 - + 跟踪 I/O 时间的列只有在启用时才会非零。若自上次统计信息重置以来的整个时间段内并未始终启用track_io_timing,则用户在将这些列与对应的 I/O 操作结合引用时应格外小心。 @@ -3828,9 +3882,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage stats_reset timestamp with time zone - - 这些统计信息上次被重置的时间 - + 这些统计信息上次被重置的时间 @@ -3878,9 +3930,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage num_requested bigint - - 已执行的请求检查点数量 - + 已执行的请求检查点数 @@ -3941,9 +3991,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage stats_reset timestamp with time zone - - 这些统计信息上次被重置的时间 - + 这些统计信息上次被重置的时间 @@ -4003,7 +4051,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage wal_bytes numeric - 生成的WAL总数,以字节计 + 生成的 WAL 总量,以字节计 @@ -4012,7 +4060,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage wal_buffers_full bigint - 因为缓冲区已满,WAL数据被写入磁盘的次数 + 因为 WAL 缓冲区已满,WAL 数据被写入磁盘的次数 @@ -4031,7 +4079,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage wal_sync bigint - 通过issue_xlog_fsync 请求将WAL文件同步到磁盘的次数(如果onfdatasync, fsyncfsync_writethrough,否则为零)。 + 通过issue_xlog_fsync 请求将WAL文件同步到磁盘的次数(如果onfdatasyncfsyncfsync_writethrough,否则为零)。 有关内部WAL函数issue_xlog_fsync的更多信息,参见 @@ -4041,7 +4089,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage wal_write_time double precision - 通过XLogWrite请求将WAL缓冲区写入磁盘所消耗的总时间,以毫秒计(如果是启用的,否则为零)。 + 通过XLogWrite请求将WAL缓冲区写入磁盘所消耗的总时间,以毫秒计(如果是启用的,否则为零)。 这包括当wal_sync_methodopen_datasyncopen_sync时的同步时间。 @@ -4051,11 +4099,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage wal_sync_time double precision - 通过issue_xlog_fsync请求将 WAL 文件同步到磁盘所花费的 - 总时间,以毫秒计(如果启用了track_wal_io_timing、 - fsyncon,且 - wal_sync_methodfdatasync、 - fsyncfsync_writethrough,否则为零)。 + 通过 issue_xlog_fsync 请求将 WAL 文件同步到磁盘所花费的总时间,以毫秒计(如果启用了 track_wal_io_timingfsyncon,且 wal_sync_methodfdatasyncfsyncfsync_writethrough,否则为零)。 @@ -4063,9 +4107,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage stats_reset timestamp with time zone - - 这些统计数据最后一次重置的时间 - + 这些统计信息上次被重置的时间 @@ -4111,7 +4153,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + datname name @@ -4120,17 +4162,17 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + numbackends integer 当前连接到此数据库的后端数,对于共享对象则为NULL。 - 这是该视图中唯一返回反映当前状态的值的列;所有其他列返回自上次重置以来累积的值。 + 这是该视图中唯一返回反映当前状态的值的列;所有其他列返回自上次重置以来累积的值。 - + xact_commit bigint @@ -4139,7 +4181,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + xact_rollback bigint @@ -4148,7 +4190,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + blks_read bigint @@ -4157,7 +4199,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + blks_hit bigint @@ -4166,7 +4208,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + tup_returned bigint @@ -4175,7 +4217,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + tup_fetched bigint @@ -4184,7 +4226,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + tup_inserted bigint @@ -4193,7 +4235,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + tup_updated bigint @@ -4202,7 +4244,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + tup_deleted bigint @@ -4211,7 +4253,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + conflicts bigint @@ -4220,7 +4262,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + temp_files bigint @@ -4229,7 +4271,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + temp_bytes bigint @@ -4238,7 +4280,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + deadlocks bigint @@ -4247,7 +4289,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + checksum_failures bigint @@ -4257,7 +4299,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + checksum_last_failure timestamp with time zone @@ -4267,7 +4309,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + blk_read_time double precision @@ -4276,7 +4318,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + blk_write_time double precision @@ -4285,25 +4327,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - - - parallel_workers_to_launch bigint - - - 计划由该数据库上的查询启动的并行工作进程数 - - - - - - parallel_workers_launched bigint - - - 由该数据库上的查询启动的并行工作进程数 - - - - + session_time double precision @@ -4312,7 +4336,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + active_time double precision @@ -4321,7 +4345,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + idle_in_transaction_time double precision @@ -4330,7 +4354,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + sessions bigint @@ -4339,7 +4363,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + sessions_abandoned bigint @@ -4348,7 +4372,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + sessions_fatal bigint @@ -4357,7 +4381,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + sessions_killed bigint @@ -4366,7 +4390,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + stats_reset timestamp with time zone @@ -4374,6 +4398,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage 这些统计数据最后一次重置的时间 +
@@ -4460,7 +4485,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage confl_bufferpin bigint - 此数据库中由于固定缓冲区而被取消的查询数 + 此数据库中由于缓冲区被钉住而被取消的查询数
@@ -4567,7 +4592,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage seq_tup_read bigint - 连续扫描获取的实时行数 + 顺序扫描获取的存活行数
@@ -4594,7 +4619,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage idx_tup_fetch bigint - 索引扫描获取的实时行数 + 索引扫描获取的存活行数
@@ -4611,9 +4636,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage n_tup_upd bigint - - 更新的行数(包括HOT更新的行) - + 更新的总行数。(包括计入n_tup_hot_updn_tup_newpage_upd的行更新,以及其余非HOT更新。)
@@ -4629,9 +4652,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage n_tup_hot_upd bigint - - HOT更新的行数(即,不需要单独的索引更新) - + 进行HOT 更新的行数。这些更新不需要在索引中存储后继版本。 @@ -4639,7 +4660,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage n_tup_newpage_upd bigint - 更新的行数,其中后继版本转到新的堆页,留下一个原始版本,其t_ctid字段指向不同的堆页。这些始终是非 HOT 更新。 + 更新的行数,其中后继版本转到的堆页,留下一个原始版本,其t_ctid字段指向不同的堆页。这些始终是非 HOT 更新。 @@ -4684,7 +4705,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage last_vacuum timestamp with time zone - 最后一次手动清理这个表(不包括VACUUM FULL) + 最后一次手动清理这个表的时间(不包括VACUUM FULL
@@ -4702,7 +4723,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage last_analyze timestamp with time zone - 上一次手动分析这个表 + 上一次手动分析这个表的时间
@@ -4711,7 +4732,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage last_autoanalyze timestamp with time zone - 自动清理守护进程最后一次分析这个表 + 自动清理守护进程最后一次分析这个表的时间
@@ -4720,7 +4741,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage vacuum_count bigint - 这个表被手动清理的次数(VACUUM FULL不计数) + 这个表被手动清理的次数(VACUUM FULL不计数)
@@ -4862,7 +4883,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage idx_tup_fetch bigint - 使用此索引进行简单索引扫描获取的活动表行数 + 使用此索引进行简单索引扫描获取的存活表行数
@@ -4870,13 +4891,13 @@ description | Waiting for a newly initialized WAL file to reach durable storage - 索引可以被简单索引扫描、位图索引扫描以及优化器使用。在一次位图扫描中,多个索引的输出可以被通过 AND 或 OR 规则组合,因此当使用一次位图扫描时难以将取得的个体堆行与特定的索引关联起来。因此,一次位图扫描会增加它使用的索引的pg_stat_all_indexes.idx_tup_read计数,并且为每个表增加pg_stat_all_tables.idx_tup_fetch计数,但是它不影响pg_stat_all_indexes.idx_tup_fetch。如果所提供的常量值不在优化器统计信息记录的范围之内,优化器也会访问索引来检查,因为优化器统计信息可能已经“不新鲜”了。 + 索引可以被简单索引扫描、位图索引扫描以及优化器使用。在一次位图扫描中,多个索引的输出可以被通过 AND 或 OR 规则组合,因此当使用一次位图扫描时难以将取得的个体堆行与特定的索引关联起来。因此,一次位图扫描会增加它使用的索引的pg_stat_all_indexes.idx_tup_read计数,并且为该表增加pg_stat_all_tables.idx_tup_fetch计数,但是它不影响pg_stat_all_indexes.idx_tup_fetch。如果所提供的常量值不在优化器统计信息记录的范围之内,优化器也会访问索引来检查,因为优化器统计信息可能已经过时。 - 即使不用位图扫描,idx_tup_readidx_tup_fetch计数也可能不同,因为idx_tup_read统计从该索引取得的索引项而idx_tup_fetch统计从表取得的活着的行。如果使用该索引取得了任何死亡行或还未提交的行,或者如果通过一次只用索引扫描的方式避免了任何堆获取,后者将较小。 + 即使不用位图扫描,idx_tup_readidx_tup_fetch计数也可能不同,因为idx_tup_read统计从该索引取得的索引项而idx_tup_fetch统计从表取得的存活行。如果使用该索引取得了任何死亡行或还未提交的行,或者如果通过一次仅索引扫描的方式避免了任何堆获取,后者将较小。 @@ -4990,7 +5011,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage toast_blks_read bigint - 从这个表的TOAST表中读取的磁盘块的数量(如果有的话) + 从这个表的TOAST表中读取的磁盘块的数量(如果有的话)
@@ -4999,7 +5020,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage toast_blks_hit bigint - 这个表的TOAST表中的缓冲区命中数(如果有的话) + 这个表的TOAST表中的缓冲区命中数(如果有的话)
@@ -5008,7 +5029,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage tidx_blks_read bigint - 从这个表的TOAST表索引中读取的磁盘块的数量(如果有的话) + 从这个表的TOAST表索引中读取的磁盘块的数量(如果有的话)
@@ -5017,7 +5038,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage tidx_blks_hit bigint - 这个表的TOAST表索引中的缓冲区命中数(如果有的话) + 这个表的TOAST表索引中的缓冲区命中数(如果有的话)
@@ -5303,10 +5324,9 @@ description | Waiting for a newly initialized WAL file to reach durable storage pg_stat_slru - - PostgreSQL通过SLRU(simple least-recently-used,简单的最近-最少-使用)缓存访问某些磁盘上的信息。 - pg_stat_slru视图将为每个被跟踪的SLRU缓存包含一行,显示关于访问缓存页面的统计信息。 - + PostgreSQL通过SLRU简单最近最少使用)缓存访问某些磁盘上的信息。pg_stat_slru视图将为每个被跟踪的 SLRU 缓存包含一行,显示关于访问缓存页面的统计信息。 + + 对于核心服务器中的每个SLRU缓存,都有一个以_buffers为后缀的配置参数来控制其大小。 @@ -5349,7 +5369,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage blks_hitbigint - 已经在SLRU中的磁盘块被发现的次数,因此不需要读取(这只包括SLRU中的命中,而不是操作系统的文件系统缓存) + 已经在SLRU中的磁盘块被发现的次数,因此不需要读取(这只包括SLRU中的命中,而不是操作系统的文件系统缓存) @@ -5385,7 +5405,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage flushesbigint - 此SLRU的脏数据刷新数 + 此SLRU的脏数据刷盘次数 @@ -5394,7 +5414,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage truncatesbigint - 这个SLRU的截断数 + 这个SLRU的截断次数 @@ -5402,9 +5422,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage stats_reset timestamp with time zone - - 这些统计数据最后一次重置的时间 - + 这些统计信息上次被重置的时间 @@ -5424,7 +5442,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - 与累积统计系统相关的其他功能在中列出。 + 与累积统计系统相关的其他函数在中列出。
@@ -5479,7 +5497,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage timestamp with time zone - 返回当前统计快照的时间戳,如果没有统计快照则返回NULL。如果在事务中第一次访问累积统计信息时将快照设置为stats_fetch_consistencysnapshot。 + 返回当前统计快照的时间戳;如果尚未获取统计快照,则返回 NULL。如果 stats_fetch_consistency 设置为 snapshot,则会在事务中第一次访问累积统计信息时获取快照。 @@ -5535,9 +5553,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage 将当前数据库的所有统计计数器重置为零。 - - 默认情况下该函数仅限于超级用户,但是其他用户可以被授予EXECUTE来运行此函数。 - + 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 @@ -5545,36 +5561,42 @@ description | Waiting for a newly initialized WAL file to reach durable storage pg_stat_reset_shared - pg_stat_reset_shared ( text ) + pg_stat_reset_shared ( [ target text DEFAULT NULL ] ) void - 根据参数将一些集簇范围的统计计数器重置为零。参数可以是bgwriter, - 用于重置在pg_stat_bgwriter视图中显示的所有计数器, - archiver,用于重置在pg_stat_archiver视图中显示的所有计数器, - wal,用于重置在pg_stat_wal视图中显示的所有计数器, - 或recovery_prefetch,用于重置在pg_stat_recovery_prefetch视图中显示的所有计数器。 + 根据参数将一些集簇范围的统计计数器重置为零。target 可以是: + + + archiver:重置 pg_stat_archiver 视图中显示的所有计数器。 + + + bgwriter:重置 pg_stat_bgwriter 视图中显示的所有计数器。 + + + checkpointer:重置 pg_stat_checkpointer 视图中显示的所有计数器。 + + + io:重置 pg_stat_io 视图中显示的所有计数器。 + + + recovery_prefetch:重置 pg_stat_recovery_prefetch 视图中显示的所有计数器。 + + + slru:重置 pg_stat_slru 视图中显示的所有计数器。 + + + wal:重置 pg_stat_wal 视图中显示的所有计数器。 + + + NULL 或未指定:重置上述所有视图中的所有计数器。 + + - - 默认情况下,此函数仅限超级用户使用,但可以授予其他用户EXECUTE权限来运行该函数。 - + 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 - - - - pg_stat_reset_backend_stats - - pg_stat_reset_backend_stats ( integer ) - void - - - 将指定进程 ID 的单个后端进程的统计信息重置为零。 - - - 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 - - + @@ -5585,9 +5607,9 @@ description | Waiting for a newly initialized WAL file to reach durable storage void - 重置当前数据库中的单个表或索引的统计信息,或者在集簇中跨所有数据库共享的统计信息为零。 - 默认情况下,此函数仅限超级用户使用,但可以授予其他用户EXECUTE权限来运行该函数。 - + 将单个表或索引的统计信息重置为零;该对象可以位于当前数据库中,也可以由集簇中的所有数据库共享。 + + 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 @@ -5601,9 +5623,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage 将当前数据库中单个函数的统计信息重置为零。 - - 默认情况下该函数仅限于超级用户,但是其他用户可以被授予EXECUTE来运行此函数。 - + 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 @@ -5611,19 +5631,13 @@ description | Waiting for a newly initialized WAL file to reach durable storage pg_stat_reset_slru - pg_stat_reset_slru ( text ) + pg_stat_reset_slru ( [ target text DEFAULT NULL ] ) void - 将单个SLRU缓存或集簇中所有SLRU的统计信息重置为零。 - 如果该参数为NULL,则所有SLRU缓存的pg_stat_slru视图中显示的计数器将被重置。 - 参数可以是CommitTsMultiXactMemberMultiXactOffsetNotify、 - SerialSubtrans、 或Xact中的一个,以便只重置该条目的计数器。 - 如果参数是other(或实际上,任何无法识别的名称),那么所有其他SLRU缓存的计数器,如扩展定义的缓存,将被重置。 + 将单个 SLRU 缓存或集簇中所有 SLRU 的统计信息重置为零。如果 targetNULL 或未指定,则重置 pg_stat_slru 视图中所有 SLRU 缓存的全部计数器。参数可以为 commit_timestamp、&zwsp;multixact_member、&zwsp;multixact_offset、&zwsp;notify、&zwsp;serializable、&zwsp;subtransactiontransaction 中的一个,以便只重置对应条目的计数器。如果参数为 other(实际上,任何无法识别的名称都可以),则重置其他所有 SLRU 缓存的计数器,例如扩展定义的缓存。 - - 默认情况下该函数仅限于超级用户,但是其他用户可以被授予EXECUTE来运行此函数。 - + 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 @@ -5638,9 +5652,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage 重置由参数定义的复制槽的统计信息。 如果参数为NULL,则重置所有复制槽的统计信息。 - - 该函数默认仅限于超级用户,但可以授予其他用户EXECUTE权限来运行该函数。 - + 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 @@ -5655,9 +5667,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage 重置pg_stat_subscription_stats视图中显示的单个订阅的统计信息为零。 如果参数是NULL,则重置所有订阅的统计信息。 - - 默认情况下,此函数仅限超级用户使用,但其他用户可以被授予EXECUTE权限来运行该函数。 - + 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 @@ -5673,17 +5683,18 @@ description | Waiting for a newly initialized WAL file to reach durable storage - pg_stat_get_activitypg_stat_activity视图的底层函数, - 它返回一个行集合,其中包含有关每个后端进程所有可用的信息。有时只获得该信息的一个子集可能会更方便。 - 在那些情况中,可以使用一组更老的针对每个后端的统计访问函数,这些显示在中。 - 这些访问函数使用一个后端 ID 号,范围从 1 到当前活动后端数目。 - 函数pg_stat_get_backend_idset提供了一种方便的方法为每个活动后端产生一行来调用这些函数。 - 例如,要显示PID以及所有后端当前的查询: + pg_stat_get_activitypg_stat_activity 视图的底层函数, + 返回一组记录,其中包含有关每个后端进程的全部可用信息。有时只获取其中一部分信息会更方便。 + 在这种情况下,可以使用另一组针对每个后端的统计信息访问函数,见 。 + 这些访问函数使用会话的后端 ID 号,它是一个值较小的非负整数(>= 0),与任何并发会话的后端 ID 都不同, + 但会话退出后,其 ID 可立即被重新使用。后端 ID 的用途之一是标识会话的临时模式(如果有)。 + 函数 pg_stat_get_backend_idset 提供了一种便捷的方法,可列出所有活动后端的 ID 号来调用这些函数。 + 例如,要显示所有后端的 PID 和当前查询: -SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - pg_stat_get_backend_activity(s.backendid) AS query - FROM (SELECT pg_stat_get_backend_idset() AS backendid) AS s; +SELECT pg_stat_get_backend_pid(backendid) AS pid, + pg_stat_get_backend_activity(backendid) AS query +FROM pg_stat_get_backend_idset() AS backendid; @@ -5705,19 +5716,6 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - - - - pg_stat_get_backend_idset - - pg_stat_get_backend_idset () - setof integer - - - 返回当前活动后端ID号的集合(从1到活动后端数)。 - - - @@ -5737,7 +5735,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, pg_stat_get_backend_activity_start pg_stat_get_backend_activity_start ( integer ) - 有时区的时间戳 + timestamp with time zone 返回后端最近一次查询开始的时间。 @@ -5783,6 +5781,19 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, + + + + pg_stat_get_backend_idset + + pg_stat_get_backend_idset () + setof integer + + + 返回当前活动后端 ID 号的集合。 + + + @@ -5802,11 +5813,9 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, pg_stat_get_backend_start pg_stat_get_backend_start ( integer ) - 有时区的时间戳 + timestamp with time zone - - 返回该进程开始的时间。 - + 返回该进程开始的时间。 @@ -5838,28 +5847,28 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - pg_stat_get_backend_wait_event_type + pg_stat_get_backend_wait_event - pg_stat_get_backend_wait_event_type ( integer ) + pg_stat_get_backend_wait_event ( integer ) text - 如果后端当前正在等待,则返回等待事件类型名称,否则返回NULL。 - 请参阅。 + 如果后端当前正在等待,则返回等待事件名称,否则为空值。 + 请参阅 - pg_stat_get_backend_wait_event + pg_stat_get_backend_wait_event_type - pg_stat_get_backend_wait_event ( integer ) + pg_stat_get_backend_wait_event_type ( integer ) text - 如果后端当前正在等待,则返回等待事件名称,否则为NULL。 - 请参阅。 + 如果后端当前正在等待,则返回等待事件类型名称,否则返回空值。 + 请参阅 @@ -5869,7 +5878,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, pg_stat_get_backend_xact_start pg_stat_get_backend_xact_start ( integer ) - 有时区的时间戳 + timestamp with time zone 返回后端当前事务开始的时间。 @@ -5887,23 +5896,23 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, 查看锁 - lock - monitoring + + 监控 - 监控数据库活动的另外一个有用的工具是pg_locks系统表。这样就允许数据库管理员查看在锁管理器里面未解决的锁的信息。例如,这个功能可以被用于: + 监控数据库活动的另外一个有用的工具是pg_locks系统表。这样就允许数据库管理员查看锁管理器中当前存在的锁的信息。例如,这个功能可以被用于: - 查看当前所有未解决的锁、在一个特定数据库中的关系上所有的锁、在一个特定关系上所有的锁,或者由一个特定PostgreSQL会话持有的所有的锁。 + 查看当前存在的所有锁、在一个特定数据库中的关系上所有的锁、在一个特定关系上所有的锁,或者由一个特定PostgreSQL会话持有的所有的锁。 - 判断当前数据库中带有最多未授予锁的关系(它很可能是数据库客户端的竞争源)。 + 判断当前数据库中带有最多未授予锁的关系(它可能是数据库客户端之间的竞争来源)。 @@ -6093,14 +6102,14 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, acquiring sample rows - 该命令当前正在扫描relid给出的表以获得样例行。 + 该命令当前正在扫描relid给出的表以获得样本行。 acquiring inherited sample rows - 该命令当前正在扫描子表以获得样例行。列child_tables_total,child_tables_done, + 该命令当前正在扫描子表以获得样本行。列child_tables_totalchild_tables_done、 和current_child_table_relid包含此阶段的进度信息。 @@ -6108,14 +6117,14 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, computing statistics - 该命令从表扫描期间获得的样例行计算统计信息。 + 该命令从表扫描期间获得的样本行计算统计信息。 computing extended statistics - 该命令从表扫描期间获得的样例行计算扩展统计信息。 + 该命令从表扫描期间获得的样本行计算扩展统计信息。 @@ -6131,30 +6140,25 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - - 请注意,当在分区表上运行ANALYZE时,其所有分区也会被 - 递归分析。在这种情况下,会先报告父表的ANALYZE进度, - 并收集其继承统计信息,随后再报告每个分区的进度。 - + 请注意,当在分区表上运行ANALYZE时,其所有分区也会被递归分析。在这种情况下,会先报告父表的ANALYZE进度,并收集其继承统计信息,随后再报告每个分区的进度。 - + - CREATE INDEX 进度报告 + CLUSTER 进度报告 - pg_stat_progress_create_index + pg_stat_progress_cluster - 每当运行CREATE INDEXREINDEX时,pg_stat_progress_create_index视图将包含当前正在创建索引的每个后端的一行。 - 下面的表描述了将要报告的信息,并提供了关于如何解释它的信息。 + 每当CLUSTERVACUUM FULL运行时,pg_stat_progress_cluster视图将为每个当前正在运行这两种命令之一的后端包含一行。下面的表格描述了将被报告的信息,并提供了关于如何解释这些信息的信息。 -
+
- <structname>pg_stat_progress_create_index</structname> 视图 + <structname>pg_stat_progress_cluster</structname> 视图 @@ -6202,16 +6206,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, relidoid - 正在创建索引的表的OID。 - - - - - - index_relid oid - - - 正在创建或重建索引的OID。在非并发 CREATE INDEX的时候,此为 0。 + 正在聚簇的表的OID。 @@ -6220,8 +6215,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, commandtext - 在运行的命令: CREATE INDEX,CREATE INDEX CONCURRENTLY, - REINDEX, 或 REINDEX CONCURRENTLY. + 正在运行的命令。CLUSTERVACUUM FULL @@ -6230,201 +6224,295 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, phasetext - 索引创建的当前处理阶段。 参见 。 - - - - - - lockers_total bigint - - - 在适用的情况下,需要等待的储物柜总数 - - - - - - lockers_done bigint - - - 已经等待的储物柜数量。 - - - - - - current_locker_pid bigint - - - 目前正在等待的储物柜的进程ID。 + 当前处理阶段。参见 - blocks_total bigint + cluster_index_relid oid - 本阶段要处理的区块总数。 + 如果正在使用索引对表进行扫描,这就是正在使用的索引的OID;否则为0。 - blocks_done bigint + heap_tuples_scanned bigint - 当前阶段已经处理的区块数量。 + 扫描的堆元组数。 + 该计数器仅在阶段为seq scanning heapindex scanning heap + 或 writing new heap 时才会递增。 - tuples_total bigint + heap_tuples_written bigint - 当前阶段要处理的元组总数。 + 写入的堆元组的数量。这个计数器只有在阶段为seq scanning heapindex scanning heap + 或 writing new heap时才会递增。 - tuples_done bigint + heap_blks_total bigint - 在当前阶段已经处理的元组数量。 + 表中的堆块总数。 这个数字以seq scanning heap开始时的数量为准。 - partitions_total bigint + heap_blks_scanned bigint - 在分区表上创建索引时,该列被设置为要在其上创建索引的分区总数。 - 在REINDEX期间,此字段为0。 + 扫描的堆块数量。该计数器仅在阶段为seq scanning heap时才会递增。 - partitions_done bigint + index_rebuild_count bigint - 当在分区表上创建索引时,该列被设置为在其上建立索引的分区数。 - 在REINDEX期间,此字段为0。 + 已重建的索引数。该计数器仅在rebuilding index阶段时才会递增。
- +
- CREATE INDEX 的阶段 + CLUSTER 和 VACUUM FULL 阶段 - + 阶段 描述 - - - 初始化 - - CREATE INDEXREINDEX正在准备创建索引。 这个阶段预计会非常短暂。 - - + - - 构建前等待读写器 - - CREATE INDEX CONCURRENTLYREINDEX CONCURRENTLY正在等待有可能看到表的写锁的事务完成。 当不在并发模式时,这个阶段会被跳过。lockers_totallockers_donecurrent_locker_pid 列包含了这个阶段的进度信息。 + + initializing + + 命令正在准备开始扫描堆。这个阶段预计会非常短暂。 - + - - 新建索引 - - 索引是由访问方法专用代码建立的。 在这一阶段,支持进度报告的访问方法填写自己的进度数据,子阶段在这一栏中表示。 通常情况下,blocks_totalblocks_done将包含进度数据,也可能包含tuples_totaltuples_done。 - - + + seq scanning heap + + 该命令目前采用顺序扫描的方式对表进行扫描。 + + - - 在验证前等待读写器 - - CREATE INDEX CONCURRENTLYREINDEX CONCURRENTLY正在等待有可能写入表的事务完成写锁的事务。当不在并发模式时,这个阶段会被跳过。lockers_totallockers_donecurrent_locker_pid 列包含了这个阶段的进度信息。 - - + + index scanning heap + + CLUSTER目前正在使用索引扫描表。 + + - - 索引验证:扫描索引 - - CREATE INDEX CONCURRENTLY正在扫描索引,搜索需要验证的元组。如果不是并发模式,则会跳过此阶段。列 blocks_total(设为索引总大小)和 blocks_done 包含该阶段的进度信息。 - - + + sorting tuples + + CLUSTER目前正在对元组进行排序。 + + - - 索引验证:排序元组 - - CREATE INDEX CONCURRENTLY正在对索引扫描阶段的输出进行排序。 - + + writing new heap + + CLUSTER目前正在写入新的堆。 + + + + + swapping relation files + + 目前,该命令正在将新建立的文件调换到位。 + + + + + rebuilding index + + 该命令目前正在重建一个索引。 + + + + + performing final cleanup + + 该命令正在执行最后的清理工作。 当此阶段完成后,CLUSTERVACUUM FULL将结束。 + + + + +
+ + + + + COPY 进度报告 + + + pg_stat_progress_copy + + + + 当COPY正在运行时,pg_stat_progress_copy视图会为每个当前正在执行COPY命令的后端包含一行。下表描述了会报告哪些信息,以及应如何解释这些信息。 + + + + + <structname>pg_stat_progress_copy</structname> 视图 + + + + + + 列类型 + + + 描述 + + + + - 索引验证:扫描表 - - CREATE INDEX CONCURRENTLY正在扫描表,以验证前两个阶段收集的索引元组。如果不是并发模式,则会跳过此阶段。blocks_total 列(设为表总大小)和 blocks_done 列包含该阶段的进度信息。 - + + pid integer + + + 后端的进程ID。 + - 等待旧照 - - CREATE INDEX CONCURRENTLYREINDEX CONCURRENTLY正在等待可能看到表的事务释放快照。 当不处于并发模式时,这个阶段会被跳过。 lockers_totallockers_donecurrent_locker_pid 列包含了这个阶段的进度信息。 - + + datid oid + + + 后端连接到的数据库的OID。 + - 标记 dead之前等待readers - - REINDEX CONCURRENTLY等待表上有读锁的事务完成后,再将旧索引标记为死索引。当不在并发模式时,这个阶段被跳过。lockers_totallockers_donecurrent_locker_pid 列包含了这个阶段的进度信息。 - + + datname name + + + 后端连接到的数据库的名称。 + - 在 dropping之前等待readers - - REINDEX CONCURRENTLY等待表上有读锁的事务完成后,再丢弃旧索引。当不在并发模式时,这个阶段被跳过。列 lockers_totallockers_donecurrent_locker_pid包含了这个阶段的进度信息。 - + + relid oid + + + 执行COPY命令的表的OID。 + 如果从SELECT查询中复制,它被设置为0。 + + + + + + command text + + + 正在运行的命令: COPY FROMCOPY TO。 + + + + + + type text + + 读取或写入数据的 I/O 类型:FILEPROGRAMPIPE(用于COPY FROM STDINCOPY TO STDOUT),或CALLBACK(例如在逻辑复制的初始表同步期间使用)。 + + + + + bytes_processed bigint + + + 已经被COPY命令处理的字节数。 + + + + + + bytes_total bigint + + + COPY FROM命令的源文件大小,以字节计。 + 如果不可用则设置为0。 + + + + + + tuples_processed bigint + + + 已经被COPY命令处理的元组数。 + + + + + + tuples_excluded bigint + + + 没有处理的元组数,因为它们被COPY命令的WHERE子句所排除。 + + + + + + tuples_skipped bigint + + + 因包含格式错误的数据而被跳过的元组数。只有当 ON_ERROR 选项指定的值不是 stop 时,此计数器才会递增。 +
-
- + - VACUUM 进度报告 + CREATE INDEX 进度报告 - pg_stat_progress_vacuum + pg_stat_progress_create_index - 只要VACUUM正在运行,pg_stat_progress_vacuum视图就会为每个当前正在清理的后端(包括自动清理工作进程)包含一行。下表描述了将报告的信息,并说明如何解释这些信息。VACUUM FULL命令的进度通过pg_stat_progress_cluster报告,因为VACUUM FULLCLUSTER都会重写表,而常规的VACUUM只会原地修改表。参见。 + 每当运行CREATE INDEXREINDEX时,pg_stat_progress_create_index视图将包含当前正在创建索引的每个后端的一行。 + 下面的表描述了将要报告的信息,并提供了关于如何解释它的信息。 - +
- <structname>pg_stat_progress_vacuum</structname> 视图 + <structname>pg_stat_progress_create_index</structname> 视图 @@ -6444,9 +6532,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, pid integer - - 后端的进程ID。 - + 正在创建索引的后端的进程 ID。 @@ -6472,195 +6558,217 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, relid oid - 被vacuum的表的OID。 + 正在创建索引的表的OID。 - phase text + index_relid oid - vacuum的当前处理阶段。参见 。 + 正在创建或重建索引的OID。在非并发 CREATE INDEX的时候,此为 0。 - heap_blks_total bigint + command text - 该表中堆块的总数。这个数字在扫描开始时报告,之后增加的块将不会(并且不需要)被这个VACUUM访问。 + 具体命令类型: CREATE INDEXCREATE INDEX CONCURRENTLY、 + REINDEXREINDEX CONCURRENTLY - heap_blks_scanned bigint + phase text - 被扫描的堆块数量。由于visibility map被用来优化扫描,一些块将被跳过而不做检查, - 被跳过的块会被包括在这个总数中,因此当清理完成时这个数字最终将会等于heap_blks_total。 - 仅当处于扫描堆阶段时这个计数器才会前进。 + 索引创建的当前处理阶段。 参见 - heap_blks_vacuumed bigint + lockers_total bigint - - 被清理的堆块数量。除非表没有索引,这个计数器仅在处于清理堆阶段时才会前进。 - 不包含死亡元组的块会被跳过,因此这个计数器可能有时会向前跳跃一个比较大的增量。 - + 在适用的情况下,需要等待的持锁进程总数。 - index_vacuum_count bigint + lockers_done bigint - - 已完成的索引清理周期数。 - + 已完成等待的持锁进程数量。 - max_dead_tuple_bytes bigint + current_locker_pid bigint - - 在需要执行索引清理周期之前可存储的死亡元组数据量,取决于。 - + 当前正在等待的持锁进程的进程 ID。 - dead_tuple_bytes bigint + blocks_total bigint - 自上一个索引清理周期以来收集到的死亡元组数据量。 + 本阶段要处理的块总数。 - num_dead_item_ids bigint + blocks_done bigint - 自上一个索引清理周期以来收集到的死项标识符数量。 + 当前阶段已经处理的块数量。 - indexes_total bigint + tuples_total bigint - 将要执行 vacuum 或清理的索引总数。该数字会在 vacuuming indexescleaning up indexes 阶段开始时报告。 + 当前阶段要处理的元组总数。 - indexes_processed bigint + tuples_done bigint - 已处理的索引数量。该计数器只会在 vacuuming indexescleaning up indexes 阶段推进。 + 在当前阶段已经处理的元组数量。 + + + + partitions_total bigint + + 要创建或附加索引的分区总数,包括直接分区和间接分区。在REINDEX期间,或索引未分区时,此值为0 + + + + + partitions_done bigint + + 已创建或附加索引的分区数量,包括直接分区和间接分区。在REINDEX期间,或索引未分区时,此值为0 +
- +
- VACUUM的阶段 + CREATE INDEX 阶段 - + 阶段 描述 + - + + initializing + + CREATE INDEXREINDEX正在准备创建索引。 这个阶段预计会非常短暂。 + + - - 初始化 - - VACUUM正在准备开始扫描堆。这个阶段应该很简短。 - - + + waiting for writers before build + + CREATE INDEX CONCURRENTLYREINDEX CONCURRENTLY正在等待持有写锁且可能看到该表的事务结束。 当不在并发模式时,这个阶段会被跳过。lockers_totallockers_donecurrent_locker_pid 列包含了这个阶段的进度信息。 + + - - 扫描堆 - - VACUUM正在扫描堆。如果需要,它将会对每个页面进行修建以及碎片整理,并且可能会执行冻结动作。heap_blks_scanned列可以用来监控扫描的进度。 - - + + building index + + 索引是由访问方法专用代码建立的。 在这一阶段,支持进度报告的访问方法填写自己的进度数据,子阶段在这一栏中表示。 通常情况下,blocks_totalblocks_done将包含进度数据,tuples_totaltuples_done也可能包含进度数据。 + + - - 清理索引 - - VACUUM当前正在清理索引。 - 如果一个表拥有索引,那么每次清理时这个阶段会在堆扫描完成后至少发生一次。 - 如果不足以存放找到的死亡元组(或者, 在autovacuum情况下,如果设置了) ,则每次清理时会多次清理索引。 - - + + waiting for writers before validation + + CREATE INDEX CONCURRENTLYREINDEX CONCURRENTLY正在等待持有写锁且可能写入该表的事务结束。当不在并发模式时,这个阶段会被跳过。lockers_totallockers_donecurrent_locker_pid 列包含了这个阶段的进度信息。 + + - - 清理堆 - - VACUUM当前正在清理堆。清理堆与扫描堆不是同一个概念,清理堆发生在每一次清理索引的实例之后。如果heap_blks_scanned小于heap_blks_total,系统将在这个阶段完成之后回去扫描堆;否则,系统将在这个阶段完成后开始清理索引。 - - + + index validation: scanning index + + CREATE INDEX CONCURRENTLY正在扫描索引,搜索需要验证的元组。如果不是并发模式,则会跳过此阶段。列 blocks_total(设为索引总大小)和 blocks_done 包含该阶段的进度信息。 + + - - 清除索引 - - VACUUM当前正在清除索引。这个阶段发生在堆被完全扫描并且对堆和索引的所有清理都已经完成以后。 - - + + index validation: sorting tuples + + CREATE INDEX CONCURRENTLY正在对索引扫描阶段的输出进行排序。 + + + + + index validation: scanning table + + CREATE INDEX CONCURRENTLY正在扫描表,以验证前两个阶段收集的索引元组。如果不是并发模式,则会跳过此阶段。blocks_total 列(设为表总大小)和 blocks_done 列包含该阶段的进度信息。 + + + + + waiting for old snapshots + + CREATE INDEX CONCURRENTLYREINDEX CONCURRENTLY正在等待可能看到表的事务释放快照。 当不处于并发模式时,这个阶段会被跳过。 lockers_totallockers_donecurrent_locker_pid 列包含了这个阶段的进度信息。 + + - - 截断堆 - - VACUUM正在截断堆,以便把关系尾部的空页面返还给操作系统。这个阶段发生在清除完索引之后。 - - + + waiting for readers before marking dead + + REINDEX CONCURRENTLY等待表上有读锁的事务完成后,再将旧索引标记为死索引。当不在并发模式时,这个阶段被跳过。lockers_totallockers_donecurrent_locker_pid 列包含了这个阶段的进度信息。 + + - - 执行最终清理 - - VACUUM正在执行最终清理。在此阶段,VACUUM将清理空闲空间映射, - 更新pg_class中的统计信息,并向累积统计系统报告统计信息。当此阶段完成时, - VACUUM将结束。 - - - + + waiting for readers before dropping + + REINDEX CONCURRENTLY等待表上有读锁的事务完成后,再丢弃旧索引。当不在并发模式时,这个阶段被跳过。列 lockers_totallockers_donecurrent_locker_pid包含了这个阶段的进度信息。 + + +
- + - CLUSTER 进度报告 + VACUUM 进度报告 - pg_stat_progress_cluster + pg_stat_progress_vacuum - 每当CLUSTERVACUUM FULL运行时,pg_stat_progress_cluster视图将包含当前正在运行的每一个后台的记录。下面的表格描述了将被报告的信息,并提供了关于如何解释这些信息的信息。 + 只要VACUUM正在运行,pg_stat_progress_vacuum视图就会为每个当前正在清理的后端(包括自动清理工作进程)包含一行。下表描述了将报告的信息,并说明如何解释这些信息。VACUUM FULL命令的进度通过pg_stat_progress_cluster报告,因为VACUUM FULLCLUSTER都会重写表,而常规的VACUUM只会原地修改表。参见 - +
- <structname>pg_stat_progress_cluster</structname> 视图 + <structname>pg_stat_progress_vacuum</structname> 视图 @@ -6708,91 +6816,109 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, relidoid - 被集群的表的OID。 + 正在清理的表的OID。 - command text + phase text - 正在运行的命令。CLUSTERVACUUM FULL。 + 清理的当前处理阶段。参见 - phase text + heap_blks_total bigint - 当前处理阶段。参见。 + 该表中堆块的总数。这个数字以扫描开始时的数量为准,之后增加的块将不会(并且不需要)被这个VACUUM访问。 - cluster_index_relid oid + heap_blks_scanned bigint - 如果正在使用索引对表进行扫描,这就是正在使用的索引的OID;否则为0。 + 被扫描的堆块数量。由于可见性映射被用来优化扫描,一些块将被跳过而不做检查, + 被跳过的块会被包括在这个总数中,因此当清理完成时这个数字最终将会等于heap_blks_total。 + 仅当处于scanning heap阶段时这个计数器才会前进。 - heap_tuples_scanned bigint + heap_blks_vacuumed bigint - 扫描的堆元组数。 - 该计数器仅在阶段为seq scanning heapindex scanning heap - 或 writing new heap 时才会递增。 + 被清理的堆块数量。除非表没有索引,这个计数器仅在处于vacuuming heap阶段时才会前进。 + 不包含死亡元组的块会被跳过,因此这个计数器可能有时会向前跳跃一个比较大的增量。 - heap_tuples_written bigint + index_vacuum_count bigint - 写入的堆元组的数量。这个计数器只有在阶段为seq scanning heap,index scanning heap - 或 writing new heap时才会前进。 + 已完成的索引清理周期数。 - heap_blks_total bigint + max_dead_tuple_bytes bigint - 表中的堆块总数。 这个数字是在seq scanning heap的开始时报告的。 + 在需要执行索引清理周期之前可存储的死亡元组数据量,取决于 - heap_blks_scanned bigint + dead_tuple_bytes bigint - 扫描的堆块数量。该计数器仅在阶段为seq scanning heap时才会递增。 + 自上一个索引清理周期以来收集到的死亡元组数据量。 - index_rebuild_count bigint + num_dead_item_ids bigint + + + 自上一个索引清理周期以来收集到的死项标识符数量。 + + + + + + indexes_total bigint + + + 将要执行清理或收尾清理的索引总数。该数字会在 vacuuming indexescleaning up indexes 阶段开始时报告。 + + + + + + indexes_processed bigint - 已重建的索引数。该计数器仅在重建索引阶段时才会递增。 + 已处理的索引数量。该计数器只会在 vacuuming indexescleaning up indexes 阶段推进。
- +
- CLUSTER 和 VACUUM FULL 阶段 + VACUUM 阶段 @@ -6807,63 +6933,57 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - 初始化 - - 该命令准备开始扫描堆栈。 这个阶段预计会非常短暂。 - - - - - seq扫描堆 + initializing - 该命令目前采用顺序扫描的方式对表进行扫描。 + VACUUM正在准备开始扫描堆。这个阶段应该很简短。 - 索引扫描堆 + scanning heap - CLUSTER目前正在使用索引扫描表。 + VACUUM正在扫描堆。如果需要,它将会对每个页面进行剪枝以及碎片整理,并且可能会执行冻结动作。heap_blks_scanned列可以用来监控扫描的进度。 - 元组排序 - - CLUSTER目前正在对元组进行排序。 - + vacuuming indexes + VACUUM当前正在清理索引。如果表有索引,每次清理都会在堆扫描完成后至少执行一次此阶段。如果(或者,对于自动清理,已设置的)不足以存储找到的死亡元组数量,则每次清理可能多次执行此阶段。 - 新写入堆 + vacuuming heap - CLUSTER目前正在编写新的堆。 + VACUUM当前正在清理堆。清理堆与扫描堆不是同一个概念,清理堆发生在每次索引清理之后。如果heap_blks_scanned小于heap_blks_total,系统将在这个阶段完成之后回去扫描堆;否则,系统将在这个阶段完成后开始索引收尾清理。 - 交换关系文件 + cleaning up indexes - 目前,该命令正在将新建立的文件调换到位。 + VACUUM当前正在进行索引收尾清理。这个阶段发生在堆被完全扫描并且对堆和索引的所有清理都已经完成以后。 - 重建索引 + truncating heap - 该命令目前正在重建一个索引。 + VACUUM正在截断堆,以便把关系尾部的空页面返还给操作系统。这个阶段发生在索引收尾清理完成之后。 - 清理 + performing final cleanup - 该命令正在执行最后的清理工作。 当此阶段完成后,CLUSTERVACUUM FULL将结束。 + VACUUM正在执行最终清理。在此阶段,VACUUM将清理空闲空间映射, + 更新pg_class中的统计信息,并向累积统计系统报告统计信息。当此阶段完成时, + VACUUM将结束。
+
@@ -6924,7 +7044,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, 将被流式传输的数据总量。该值在streaming database files阶段开始时进行估算并报告。 注意,这只是一个近似值,因为数据库可能会在streaming database files阶段期间发生变化,而 WAL 日志也可能在稍后的备份阶段被包含进来。 一旦流式传输的数据量超过了估计的总大小,该值始终与backup_streamed相同。 - 如果在pg_basebackup中禁用估算(也就是说,指定了--no-estimate-size选项),这为NULL。 + 如果在pg_basebackup中禁用估算(也就是说,指定了--no-estimate-size选项),这为NULL
@@ -6981,7 +7101,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid,
- 等待检查点完成 + waiting for checkpoint to finish WAL 发送进程当前正在执行pg_backup_start以准备进行基础备份,并等待备份起始检查点完成。 @@ -7002,7 +7122,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - 等待wal归档完成 + waiting for wal archiving to finish WAL发送进程当前正在执行pg_backup_stop以完成备份, 并等待基础备份所需的所有 WAL 文件成功归档。 @@ -7025,141 +7145,6 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - - - COPY 进度报告 - - - pg_stat_progress_copy - - - - 当COPY正在运行时,pg_stat_progress_copy视图会为每个当前正在执行COPY命令的后端包含一行。下表描述了会报告哪些信息,以及应如何解释这些信息。 - - - - - <structname>pg_stat_progress_copy</structname> 视图 - - - - - - 列类型 - - - 描述 - - - - - - - - - pid integer - - - 后端的进程ID。 - - - - - - datid oid - - - 后端连接到的数据库的OID。 - - - - - - datname name - - - 后端连接到的数据库的名称。 - - - - - - relid oid - - - 执行COPY命令的表的OID。 - 如果从SELECT查询中复制,它被设置为0。 - - - - - - command text - - - 正在运行的命令: COPY FROM, 或 COPY TO。 - - - - - - type text - - - 数据被读取或写入的io类型:FILE, PROGRAM, PIPE (对于COPY FROM STDINCOPY TO STDOUT),或 CALLBACK(例如在逻辑复制中初始表同步期间使用)。 - - - - - - bytes_processed bigint - - - 已经被COPY命令处理的字节数。 - - - - - - bytes_total bigint - - - COPY FROM命令的源文件大小,以字节计。 - 如果不可用则设置为0。 - - - - - - tuples_processed bigint - - - 已经被COPY命令处理的元组数。 - - - - - - tuples_excluded bigint - - - 没有处理的元组数,因为它们被COPY命令的WHERE子句所排除。 - - - - - - tuples_skipped bigint - - - 因包含格式错误的数据而被跳过的元组数。只有当 ON_ERROR 选项指定的值不是 stop 时,此计数器才会递增。 - - - - -
-
- @@ -7185,7 +7170,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - 动态追踪的编译 + 为动态追踪编译 默认情况下,探针是不可用的,因此你将需要显式地告诉配置脚本让探针在PostgreSQL中可用。要包括 DTrace 支持,在配置时指定。更多信息请见。 @@ -7197,7 +7182,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, 内置探针 - 如所示,源代码中提供了一些标准探针。显式了在探针中使用的类型。当然,可以增加更多探针来增强PostgreSQL的可观测性。 + 如所示,源代码中提供了一些标准探针。显示了在探针中使用的类型。当然,可以增加更多探针来增强PostgreSQL的可观测性。 @@ -7233,13 +7218,13 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, transaction-abort (LocalTransactionId) - 当一个事务失败完成时触发的探针。arg0 是事务 ID。 + 当一个事务失败结束时触发的探针。arg0 是事务 ID。 query-start (const char *) - 当一个查询的处理被开始时触发的探针。arg0 是查询字符串。 + 当一个查询的处理开始时触发的探针。arg0 是查询字符串。 @@ -7251,7 +7236,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, query-parse-start (const char *) - 当一个查询的解析被开始时触发的探针。arg0 是查询字符串。 + 当一个查询的解析开始时触发的探针。arg0 是查询字符串。 @@ -7263,7 +7248,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, query-rewrite-start (const char *) - 当一个查询的重写被开始时触发的探针。arg0 是查询字符串。 + 当一个查询的重写开始时触发的探针。arg0 是查询字符串。 @@ -7275,7 +7260,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, query-plan-start () - 当一个查询的规划被开始时触发的探针。 + 当一个查询的规划开始时触发的探针。 @@ -7287,7 +7272,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, query-execute-start () - 当一个查询的执行被开始时触发的探针。 + 当一个查询的执行开始时触发的探针。 @@ -7305,19 +7290,19 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, checkpoint-start (int) - 当一个检查点被开始时触发的探针。arg0 传递位标志来区分不同的检查点类型,例如关闭(shutdown)、立即(immediate)或强制(force)。 + 当一个检查点开始时触发的探针。arg0 传递位标志来区分不同的检查点类型,例如关闭(shutdown)、立即(immediate)或强制(force)。 checkpoint-done (int, int, int, int, int) - 当一个检查点完成时触发的探针(检查点处理过程中序列中列出的下一个触发的探针)。arg0 是要写的缓冲区数量。arg1 是缓冲区的总数。arg2、arg3 和 arg4 分别包含了增加、删除和循环回收的 WAL 文件的数量。 + 当一个检查点完成时触发的探针(下面列出的探针会在检查点处理过程中依次触发)。arg0 是已写入的缓冲区数量。arg1 是缓冲区的总数。arg2、arg3 和 arg4 分别包含了增加、删除和循环回收的 WAL 文件的数量。 clog-checkpoint-start (bool) - 当一个检查点的 CLOG 部分被开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 + 当一个检查点的 CLOG 部分开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 @@ -7329,7 +7314,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, subtrans-checkpoint-start (bool) - 当一个检查点的 SUBTRANS 部分被开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 + 当一个检查点的 SUBTRANS 部分开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 @@ -7341,7 +7326,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, multixact-checkpoint-start (bool) - 当一个检查点的 MultiXact 部分被开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 + 当一个检查点的 MultiXact 部分开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 @@ -7353,7 +7338,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, buffer-checkpoint-start (int) - 当一个检查点的写缓冲区部分被开始时触发的探针。arg0 传递位标志来区分不同的检查点类型,例如关闭(shutdown)、立即(immediate)或强制(force)。 + 当一个检查点的写缓冲区部分开始时触发的探针。arg0 传递位标志来区分不同的检查点类型,例如关闭(shutdown)、立即(immediate)或强制(force)。 @@ -7389,7 +7374,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, twophase-checkpoint-start () - 当一个检查点的两阶段部分被开始时触发的探针。 + 当一个检查点的两阶段部分开始时触发的探针。 @@ -7398,22 +7383,54 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, 当一个检查点的两阶段部分完成时触发的探针。 + + buffer-extend-start + (ForkNumber, BlockNumber, Oid, Oid, Oid, int, unsigned int) + 当关系扩展开始时触发的探针。 + arg0 包含要扩展的分支。arg1、arg2 和 arg3 包含用于标识该关系的 + 表空间、数据库和关系 OID。对于本地缓冲区,arg4 是创建临时关系的后端 ID; + 对于共享缓冲区,则为 INVALID_PROC_NUMBER(-1)。 + arg5 是调用者希望扩展的块数。 + + + + buffer-extend-done + (ForkNumber, BlockNumber, Oid, Oid, Oid, int, unsigned int, BlockNumber) + 当关系扩展完成时触发的探针。 + arg0 包含要扩展的分支。arg1、arg2 和 arg3 包含用于标识该关系的 + 表空间、数据库和关系 OID。对于本地缓冲区,arg4 是创建临时关系的后端 ID; + 对于共享缓冲区,则为 INVALID_PROC_NUMBER(-1)。 + arg5 是关系实际扩展的块数;由于资源限制,该值可能小于 + buffer-extend-start中的数量。arg6 包含第一个新块的 + BlockNumber。 + + buffer-read-start - (ForkNumber, BlockNumber, Oid, Oid, Oid, int, bool) - 当一次缓冲区读被开始时触发的探针。arg0 和 arg1 包含该页的分叉号和块号(如果这是一次关系扩展请求,arg1 为 -1)。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是 InvalidBackendId(-1)。arg6 为真表示一次关系扩展请求,为假表示正常读。 + (ForkNumber, BlockNumber, Oid, Oid, Oid, int) + 当缓冲区读取开始时触发的探针。 + arg0 和 arg1 包含该页的分支号和块号。 + arg2、arg3 和 arg4 包含用于标识该关系的表空间、数据库和关系 OID。 + 对于本地缓冲区,arg5 是创建临时关系的后端 ID;对于共享缓冲区, + 则为 INVALID_PROC_NUMBER(-1)。 + buffer-read-done - (ForkNumber, BlockNumber, Oid, Oid, Oid, int, bool, bool) - 当一次缓冲区读完成时触发的探针。arg0 和 arg1 包含该页的分叉号和块号(如果这是一次关系扩展请求,arg1 现在包含新增加块的块号)。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是 InvalidBackendId(-1)。arg6 为真表示一次关系扩展请求,为假表示正常读。arg7 为真表示在池中找到该缓冲区,为假表示没有找到。 + (ForkNumber, BlockNumber, Oid, Oid, Oid, int, bool) + 当缓冲区读取完成时触发的探针。 + arg0 和 arg1 包含该页的分支号和块号。 + arg2、arg3 和 arg4 包含用于标识该关系的表空间、数据库和关系 OID。 + 对于本地缓冲区,arg5 是创建临时关系的后端 ID;对于共享缓冲区, + 则为 INVALID_PROC_NUMBER(-1)。 + 如果在缓冲池中找到了该缓冲区,arg6 为真;否则为假。 buffer-flush-start (ForkNumber, BlockNumber, Oid, Oid, Oid) - 在发出对一个共享缓冲区的任意写请求之前触发的探针。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。 + 在发出对一个共享缓冲区的任意写请求之前触发的探针。arg0 和 arg1 包含该页的分支号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。 @@ -7422,17 +7439,9 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, 当一个写请求完成时触发的探针(注意这只反映传递数据给内核的时间,它通常并没有实际地被写入到磁盘)。参数和buffer-flush-start的相同。 - - buffer-write-dirty-start - (ForkNumber, BlockNumber, Oid, Oid, Oid) - 当一个服务器进程开始写一个脏缓冲区时触发的探针(如果这经常发生,表示太小,或需要调整后台写入器的控制参数)。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。 - - - buffer-write-dirty-done - (ForkNumber, BlockNumber, Oid, Oid, Oid) - 当一次脏缓冲区写完成时触发的探针。参数与buffer-write-dirty-start相同。 - + + wal-buffer-write-dirty-start @@ -7443,13 +7452,13 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, wal-buffer-write-dirty-done () - 当一次脏 WAL 缓冲区完成时触发的探针。 + 当一次脏 WAL 缓冲区写入完成时触发的探针。 wal-insert (unsigned char, unsigned char) - 当一个 WAL 记录被插入时触发的探针。arg0 是该记录的资源管理者(rmid)。arg1 包含 info 标志。 + 当一个 WAL 记录被插入时触发的探针。arg0 是该记录的资源管理器(rmid)。arg1 包含 info 标志。 @@ -7461,31 +7470,31 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, smgr-md-read-start (ForkNumber, BlockNumber, Oid, Oid, Oid, int) - 当开始从一个关系读取一块时触发的探针。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。 + 当开始从一个关系读取一块时触发的探针。arg0 和 arg1 包含该页的分支号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是INVALID_PROC_NUMBER(-1)。 smgr-md-read-done (ForkNumber, BlockNumber, Oid, Oid, Oid, int, int, int) - 当一次块读取完成时触发的探针。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。arg6 是实际读取的字节数,而 arg7 是请求读取的字节数(如果两者不同就意味着麻烦)。 + 当一次块读取完成时触发的探针。arg0 和 arg1 包含该页的分支号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是INVALID_PROC_NUMBER(-1)。arg6 是实际读取的字节数,而 arg7 是请求读取的字节数(如果两者不同,则表示发生了短读)。 smgr-md-write-start (ForkNumber, BlockNumber, Oid, Oid, Oid, int) - 当开始向一个关系中写入一个块时触发的探针。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。 + 当开始向一个关系中写入一个块时触发的探针。arg0 和 arg1 包含该页的分支号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是INVALID_PROC_NUMBER(-1)。 smgr-md-write-done (ForkNumber, BlockNumber, Oid, Oid, Oid, int, int, int) - 当一个块写操作完成时触发的探针。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3和arg4 包含表空间、数据库和关系 OID来标识该关系。对于一个本地缓冲区,arg5 是创建临时关系的后端 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。arg6 是实际写的字节数,而 arg7 是要求写的字节数(如果这两者不同,则意味着麻烦)。 + 当一个块写操作完成时触发的探针。arg0 和 arg1 包含该页的分支号和块号。arg2、arg3和arg4 包含表空间、数据库和关系 OID来标识该关系。对于一个本地缓冲区,arg5 是创建临时关系的后端 ID;对于一个共享缓冲区,arg5 是INVALID_PROC_NUMBER(-1)。arg6 是实际写的字节数,而 arg7 是要求写的字节数(如果这两者不同,则表示发生了短写)。 sort-start (int, bool, int, int, bool, int) - 当一次排序操作开始时触发的探针。arg0 指示是堆排序、索引排序或数据排序。arg1 为真表示强制唯一值。arg2 是键列数。arg3 是允许使用的工作内存大小(以千字节计)。如果要求随机访问排序结果,则 arg4 为真。arg5 为 0 时表示串行,为 1 时表示并行工作进程,为 2 时表示并行领导者。 + 当一次排序操作开始时触发的探针。arg0 指示是堆排序、索引排序或 datum 排序。arg1 为真表示强制唯一值。arg2 是键列数。arg3 是允许使用的工作内存大小(以千字节计)。如果要求随机访问排序结果,则 arg4 为真。arg5 为 0 时表示串行,为 1 时表示并行工作进程,为 2 时表示并行领导者。 @@ -7499,7 +7508,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, (char *, LWLockMode) 当成功获得一个 LWLock 时触发的探针。 arg0 是该 LWLock 所在的切片(Tranche)。 - arg1 所请求的锁模式,是排他或共享。 + arg1 是所请求的锁模式,是排他或共享。 @@ -7514,34 +7523,34 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, (char *, LWLockMode) 当一个 LWLock不是当即可用并且一个服务器进程因此开始等待该锁变为可用时触发的探针。 arg0 是该 LWLock 所在的切片(Tranche)。 - arg1 请求的锁模式,是排他或共享。 + arg1 是所请求的锁模式,是排他或共享。 lwlock-wait-done (char *, LWLockMode) 当一个进程从对一个 LWLock 的等待中被释放时(它实际还没有得到该锁)时触发的探针。arg0 是该 LWLock 所在的切片(Tranche)。 - arg1 所请求的锁模式,是排他或共享。 + arg1 是所请求的锁模式,是排他或共享。 lwlock-condacquire (char *, LWLockMode) 当调用者指定无需等待而成功获得一个 LWLock 时触发的探针。arg0 是该 LWLock 所在的切片(Tranche)。 - arg1 所请求的锁模式,是排他或共享。 + arg1 是所请求的锁模式,是排他或共享。 lwlock-condacquire-fail (char *, LWLockMode) 当调用者指定无需等待而没有成功获得一个 LWLock 时触发的探针。arg0 是该 LWLock 所在的切片(Tranche)。 - arg1 所请求的锁模式,是排他或共享。 + arg1 是所请求的锁模式,是排他或共享。 lock-wait-start (unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, LOCKMODE) - 当一个重量级锁(lmgr锁)的请求由于锁不可用开始等待时触发的探针。arg0 到 arg3 是标识被锁定对象的标签域。arg4 指示被锁对象的类型。arg5 表示被请求的锁类型。 + 当一个重量级锁(lmgr锁)的请求由于锁不可用开始等待时触发的探针。arg0 到 arg3 是标识被锁定对象的标签字段。arg4 指示被锁对象的类型。arg5 表示被请求的锁类型。 @@ -7562,7 +7571,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid,
- 定义用在探针参数中的类型 + 探针参数中使用的已定义类型 @@ -7656,7 +7665,7 @@ Total time (ns) 2312105013 - 你应该记住,DTrace 脚本需要细心地编写和调试,否则被收集的追踪信息可能会毫无意义。在大部分发现问题的情况中,它就是发生问题的部件,而不是底层系统。当讨论使用动态追踪发现的信息时,一定要附上使用的脚本以便其也被检查和讨论。 + 你应该记住,DTrace 脚本需要细心地编写和调试,否则被收集的追踪信息可能会毫无意义。在大多数发现问题的情况下,出错的是插桩,而不是底层系统。当讨论使用动态追踪发现的信息时,一定要附上使用的脚本以便其也被检查和讨论。 @@ -7672,7 +7681,7 @@ Total time (ns) 2312105013 - 决定探针名称以及探针可用的数据 + 决定探针名称以及要通过探针提供的数据 @@ -7686,7 +7695,7 @@ Total time (ns) 2312105013 - 如果pg_trace.h还不存在于包含该探针点的模块中,包括它,并且在源代码中期望的位置插入TRACE_POSTGRESQL探针宏 + 如果pg_trace.h尚未被包含该探针点的模块引用,则将它包含进来,并且在源代码中期望的位置插入TRACE_POSTGRESQL探针宏 @@ -7722,14 +7731,14 @@ Total time (ns) 2312105013 probe transaction__start(LocalTransactionId); - 注意探针名字中双下划线的使用。在一个使用探针的 DTrace 脚本中,双下划线需要被替换为一个连字符,因此 ,对用户而言transaction-start是文档名。 + 注意探针名字中双下划线的使用。在一个使用探针的 DTrace 脚本中,双下划线需要被替换为一个连字符,因此,文档中应向用户说明的名称是transaction-start - 在编译时,transaction__start被转换成一个宏调用TRACE_POSTGRESQL_TRANSACTION_START(注意这里是单下划线),可以通过包括头文件pg_trace.h获得。将宏调用加入到源代码中的合适位置。在这种情况下,看起来类似: + 在编译时,transaction__start被转换成一个名为TRACE_POSTGRESQL_TRANSACTION_START的宏(注意这里是单下划线),可以通过包含头文件pg_trace.h获得。将宏调用加入到源代码中的合适位置。在这种情况下,看起来类似: TRACE_POSTGRESQL_TRANSACTION_START(vxid.localTransactionId); @@ -7766,7 +7775,7 @@ TRACE_POSTGRESQL_TRANSACTION_START(vxid.localTransactionId); - 在大多数平台上,如果用编译了PostgreSQL,无论何时当控制经过一个追踪宏时,都会评估该宏的参数,即使没有进行追踪也会这样做。通常不需要担心你是否只在报告一些局部变量的值。但是要注意不要将开销大的函数调用放入参数中。如果你需要这样做,考虑通过检查追踪是否真的被启用来保护该宏: + 在大多数平台上,如果用编译了PostgreSQL,无论何时当控制经过一个追踪宏时,都会对该宏的参数求值,即使没有进行追踪也会这样做。如果只是报告少数局部变量的值,通常无需担心这一点。但是要注意不要将开销大的函数调用放入参数中。如果你需要这样做,考虑通过检查追踪是否真的被启用来保护该宏: if (TRACE_POSTGRESQL_TRANSACTION_START_ENABLED()) @@ -7807,7 +7816,7 @@ if (TRACE_POSTGRESQL_TRANSACTION_START_ENABLED()) - 在最近执行过 VACUUMANALYZE 的数据库上使用 psql,你可以发出查询来查看任意表的磁盘使用情况: + 在最近进行过清理或分析 的数据库上使用 psql,你可以发出查询来查看任意表的磁盘使用情况: SELECT pg_relation_filepath(oid), relpages FROM pg_class WHERE relname = 'customer'; diff --git a/zh/17/mvcc.sgml b/zh/17/mvcc.sgml index a8e65484..ad5d4f4d 100644 --- a/zh/17/mvcc.sgml +++ b/zh/17/mvcc.sgml @@ -4,7 +4,7 @@ 并发控制 - concurrency + 并发 @@ -15,7 +15,7 @@ 介绍 - Multiversion Concurrency Control + 多版本并发控制 @@ -23,7 +23,7 @@ - Serializable Snapshot Isolation + 可串行化快照隔离 @@ -50,7 +50,7 @@ 事务隔离 - transaction isolation + 事务隔离 @@ -68,7 +68,7 @@ 脏读 - dirty read + 脏读 @@ -80,7 +80,7 @@ 不可重复读 - nonrepeatable read + 不可重复读 @@ -92,7 +92,7 @@ 幻读 - phantom read + 幻读 @@ -104,7 +104,7 @@ 串行化异常 - serialization anomaly + 串行化异常 @@ -117,7 +117,7 @@ - transaction isolation level + 事务隔离级别 SQL 标准以及 PostgreSQL 实现的事务隔离级别见 @@ -244,12 +244,12 @@ 读已提交隔离级别 - transaction isolation level - read committed + 事务隔离级别 + 读已提交 - read committed + 读已提交 @@ -334,7 +334,7 @@ COMMIT; 在读已提交模式下,更复杂的用法可能产生不理想的结果。例如,考虑一个 - DELETE 命令,它所处理的数据会被另一个命令同时加入和移出其筛选条件。 + DELETE 命令,另一个命令正在修改数据,使某些行开始满足其筛选条件、另一些行不再满足。 假设 website 是一个有两行的表,其中 website.hits 分别等于 910: @@ -342,7 +342,7 @@ COMMIT; BEGIN; UPDATE website SET hits = hits + 1; --- run from another session: DELETE FROM website WHERE hits = 10; +-- 从另一个会话运行: DELETE FROM website WHERE hits = 10; COMMIT; @@ -370,12 +370,12 @@ COMMIT; 可重复读隔离级别 - transaction isolation level - repeatable read + 事务隔离级别 + 可重复读 - repeatable read + 可重复读 @@ -428,9 +428,7 @@ ERROR: could not serialize access due to concurrent update 可重复读模式提供了严格的保证,即每个事务都看到数据库的一个完全稳定的视图。 不过,这个视图并不一定总能与同一级别并发事务的某种串行(一次一个)执行保持一致。 - 例如,即使该级别上的只读事务可能看到一条控制记录被更新,表明某个批处理已经完成, - 但它并不一定能看到作为该批处理逻辑组成部分的某条明细记录, - 因为它读到的是控制记录的较早版本。如果不仔细使用显式锁来阻塞冲突事务, + 例如,即使是该级别的只读事务,也可能看到一条表明某批次已完成的控制记录,却看不到逻辑上属于该批次的某条明细记录,因为创建该明细记录的事务读取了控制记录的较早版本。如果不仔细使用显式锁来阻塞冲突事务, 试图依靠运行在这一隔离级别的事务来强制业务规则,往往无法正确工作。 @@ -438,7 +436,7 @@ ERROR: could not serialize access due to concurrent update 可重复读隔离级别是通过一种技术实现的,这种技术在学术数据库文献中以及某些其他数据库产品中被称为 快照隔离。与使用会降低并发性的传统加锁技术的系统相比, 其行为和性能可能会表现出差异。有些其他系统甚至把可重复读和快照隔离作为两个行为不同的独立隔离级别提供。 - 用来区分这两种技术的允许现象,直到 SQL 标准制定之后才被数据库研究人员正式定义,因此超出了本手册的范围。 + 用来区分这两种技术的允许现象,直到 SQL 标准制定之后才被数据库研究人员正式定义,并且超出了本手册的范围。 完整讨论请参阅 @@ -454,20 +452,20 @@ ERROR: could not serialize access due to concurrent update 可串行化隔离级别 - transaction isolation level - serializable + 事务隔离级别 + 可串行化 - serializable + 可串行化 - predicate locking + 谓词锁 - serialization anomaly + 串行化异常 @@ -480,48 +478,30 @@ ERROR: could not serialize access due to concurrent update 一旦检测到可能导致串行化异常的条件,就会触发串行化失败 - - 例如,考虑一张表 mytab,其初始内容为: - + 例如,考虑表mytab,它最初包含以下内容: class | value -------+------- 1 | 10 1 | 20 2 | 100 2 | 200 - - 假设可串行化事务 A 计算: - +假设可串行化事务 A 执行以下计算: SELECT SUM(value) FROM mytab WHERE class = 1; - - 然后将结果(30)作为一条新行的 value 插入,并把 - class 设为 2。与此同时,可串行化事务 B 计算: - +然后将结果(30)作为新行的value插入,且该行满足class = 2。与此同时,可串行化事务 B 执行以下计算: SELECT SUM(value) FROM mytab WHERE class = 2; - - 并得到结果 300,再把它插入为一条新行,其 - class1。然后两个事务都尝试提交。 - 如果任一事务是在可重复读隔离级别下运行,则二者都可以提交; - 但由于不存在与该结果一致的串行执行顺序,使用可串行化事务时将允许其中一个事务提交, - 并按如下消息回滚另一个事务: - - +得到结果 300,并将它插入一个新行,该行满足class = 1。然后两个事务都尝试提交。如果任一事务运行在可重复读隔离级别,两个事务都可以提交;但由于不存在与该结果一致的串行执行顺序,使用可串行化事务时,只会允许一个事务提交,另一个则会被回滚,并收到以下消息: ERROR: could not serialize access due to read/write dependencies among transactions - - - 这是因为,如果 A 先于 B 执行,B 算出的和将是 330 而不是 300; - 反过来,另一种顺序也会使 A 算出不同的和。 - +这是因为,如果 A 在 B 之前执行,B 算出的总和应该是 330,而不是 300;同样,按另一种顺序执行,A 算出的总和也会不同。 当依赖可串行化事务来防止异常时,重要的是:从永久用户表读取的任何数据,在读取它的事务成功提交之前, - 都不应视为有效。即使对于只读事务也是如此;唯一的例外是可推迟只读事务中读取的数据, + 都不应视为有效。即使对于只读事务也是如此;唯一的例外是可延迟只读事务中读取的数据, 它一经读出就可视为有效,因为这种事务会等到能够获取一个保证不存在此类问题的快照后才开始读取数据。 在所有其他情况下,应用不能依赖后来被中止事务中读到的结果;相反,应重试事务直到成功。 - 为了保证真正的可串行化,PostgreSQL 使用了谓词锁, + 为了保证真正的可串行性,PostgreSQL 使用了谓词锁, 也就是说,系统会保留一些锁,以便判断某个写操作如果先发生,是否会影响并发事务先前读取的结果。 在 PostgreSQL 中,这些锁不会造成任何阻塞,因此会参与形成死锁。 它们用于识别并标记并发可串行化事务之间的依赖关系,而这些依赖在某些组合下可能导致串行化异常。 @@ -543,7 +523,7 @@ ERROR: could not serialize access due to read/write dependencies among transact - 持续使用可串行化事务可以简化开发。任何一组成功提交的并发可串行化事务,都保证与把它们一次一个运行的效果相同;这意味着,如果你能够证明某个事务在单独运行时会做正确的事,那么即使不了解其他事务会做什么,也可以相信它在任何可串行化事务的混合执行中也会做正确的事,否则它就不会成功提交。重要的是,采用这种技术的环境应当有一套通用机制来处理串行化失败(其 SQLSTATE 值总是 40001),因为很难准确预测究竟哪些事务会对读/写依赖关系有贡献,并因此需要被回滚来防止串行化异常。监视读/写依赖关系会带来开销,被串行化失败中止的事务重新启动也会带来开销;但在把这些开销与显式锁以及 SELECT FOR UPDATESELECT FOR SHARE 所涉及的成本和阻塞进行权衡之后,可串行化事务在某些环境中仍然是性能最佳的选择。 + 统一采用可串行化事务可以简化开发。任何一组成功提交的并发可串行化事务,都保证与把它们一次一个运行的效果相同;这意味着,如果你能够证明某个事务在单独运行时会做正确的事,那么即使不了解其他事务会做什么,也可以相信它在任何可串行化事务的混合执行中也会做正确的事,否则它就不会成功提交。重要的是,采用这种技术的环境应当有一套通用机制来处理串行化失败(其 SQLSTATE 值总是 40001),因为很难准确预测究竟哪些事务会对读/写依赖关系有贡献,并因此需要被回滚来防止串行化异常。监视读/写依赖关系会带来开销,被串行化失败中止的事务重新启动也会带来开销;但在把这些开销与显式锁以及 SELECT FOR UPDATESELECT FOR SHARE 所涉及的成本和阻塞进行权衡之后,可串行化事务在某些环境中仍然是性能最佳的选择。 @@ -587,7 +567,7 @@ ERROR: could not serialize access due to read/write dependencies among transact - 当系统因谓词锁表内存不足而被迫把多个页级谓词锁合并为单个关系级谓词锁时,串行化失败的比例可能会上升。你可以通过增加 来避免这种情况。 + 当系统因谓词锁表内存不足而被迫把多个页级谓词锁合并为单个关系级谓词锁时,串行化失败的比例可能会上升。你可以通过增加 和/或 来避免这种情况。 @@ -611,7 +591,7 @@ ERROR: could not serialize access due to read/write dependencies among transact 显式锁定 - lock + @@ -715,7 +695,7 @@ ERROR: could not serialize access due to read/write dependencies among transact CREATE STATISTICSCOMMENT ONREINDEX CONCURRENTLY, 以及某些 ALTER INDEX - 和 ALTER TABLE 变体会获取这种锁 + 和 ALTER TABLE 变体获取这种锁 (有关详细信息,请参阅这些命令的文档)。 @@ -980,7 +960,7 @@ ERROR: could not serialize access due to read/write dependencies among transact - 行为与 FOR SHARE 类似,不过锁更弱:SELECT FOR UPDATE 会被阻塞,但 SELECT FOR NO KEY UPDATE 不会。键共享锁会阻塞其他事务执行会修改键值的 DELETEUPDATE,但不会阻塞其他 UPDATE,也不会阻止 SELECT FOR NO KEY UPDATESELECT FOR SHARESELECT FOR KEY SHARE。 + 行为与 FOR SHARE 类似,不过锁更弱:SELECT FOR UPDATE 会被阻塞,但 SELECT FOR NO KEY UPDATE 不会。键共享锁会阻塞其他事务执行 DELETE 或任何会修改键值的 UPDATE,但不会阻塞其他 UPDATE,也不会阻止 SELECT FOR NO KEY UPDATESELECT FOR SHARESELECT FOR KEY SHARE @@ -1058,7 +1038,7 @@ ERROR: could not serialize access due to read/write dependencies among transact 死锁 - deadlock + 死锁 @@ -1101,12 +1081,12 @@ UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 22222; 咨询锁 - advisory lock + 咨询锁 - lock - advisory + + 咨询 @@ -1138,12 +1118,12 @@ UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 22222; 在某些使用咨询锁的方法中,特别是涉及显式排序和 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(id) FROM foo WHERE id = 12345; -- 可以 +SELECT pg_advisory_lock(id) FROM foo WHERE id > 12345 LIMIT 100; -- 危险! SELECT pg_advisory_lock(q.id) FROM ( SELECT id FROM foo WHERE id > 12345 LIMIT 100 -) q; -- ok +) q; -- 可以 在上面的查询中,第二种形式是危险的,因为不能保证在执行加锁函数之前先应用 LIMIT。 这可能导致获取了一些应用并未预期的锁,因此应用也不会去释放它们(直到会话结束)。 @@ -1161,12 +1141,12 @@ SELECT pg_advisory_lock(q.id) FROM 应用级别的数据一致性检查 - 在读已提交事务下,想要通过业务规则强制数据一致性非常困难,因为数据视图会随每条语句而变化, + 用读已提交事务强制执行有关数据完整性的业务规则非常困难,因为数据视图会随每条语句而变化, 而且一旦发生写冲突,即使是单条语句也未必局限于该语句自己的快照。 - 虽然可重复读事务在整个执行期间都具有稳定的数据视图,但在使用 MVCC 快照进行数据一致性检查时,还存在一个微妙问题,即所谓的读/写冲突。如果一个事务写入数据,而并发事务试图读取相同的数据(无论是在写入之前还是之后),它都看不到另一个事务的工作。于是,读取者看起来就像是先执行的一方,而不管究竟是谁先启动,也不管谁先提交。如果事情只停留在这一步,就没有问题;但如果读取者还写入了数据,而这些数据又被另一个并发事务读取,那么现在就会有一个事务看起来像是在前面提到的任一事务之前执行。如果看起来最后执行的事务实际上最先提交,就很容易在事务执行顺序图中形成一个环。一旦出现这样的环,不借助额外机制,一致性检查就无法正确工作。 + 虽然可重复读事务在整个执行期间都具有稳定的数据视图,但在使用 MVCC 快照进行数据一致性检查时,还存在一个微妙问题,即所谓的读/写冲突。如果一个事务写入数据,而并发事务试图读取相同的数据(无论是在写入之前还是之后),它都看不到另一个事务的工作。于是,读取者看起来就像是先执行的一方,而不管究竟是谁先启动,也不管谁先提交。如果事情只停留在这一步,就没有问题;但如果读取者还写入了数据,而这些数据又被另一个并发事务读取,那么现在就会有一个事务看起来像是在前面提到的任一事务之前执行。如果看起来最后执行的事务实际上最先提交,就很容易在事务执行顺序图中形成一个环。一旦出现这样的环,不借助额外机制,完整性检查就无法正确工作。 @@ -1183,7 +1163,7 @@ SELECT pg_advisory_lock(q.id) FROM - 使用这种技术时,如果应用软件通过某个框架运行,并由该框架自动重试因串行化错误而回滚的事务,就可以避免给应用程序员带来不必要的负担。把 default_transaction_isolation 设置为 serializable 可能是个好主意。通过在触发器中检查事务隔离级别来采取某些措施,以确保不会因为疏忽或为了绕过完整性检查而使用其他事务隔离级别,也是明智的。 + 使用这种技术时,如果应用软件通过某个框架运行,并由该框架自动重试因串行化失败而回滚的事务,就可以避免给应用程序员带来不必要的负担。把 default_transaction_isolation 设置为 serializable 可能是个好主意。通过在触发器中检查事务隔离级别来采取某些措施,以确保不会因为疏忽或为了绕过完整性检查而使用其他事务隔离级别,也是明智的。 @@ -1200,7 +1180,7 @@ SELECT pg_advisory_lock(q.id) FROM - 使用显式锁定强制一致性 + 使用显式阻塞锁强制一致性 当存在非可串行化写入时,要确保某一行当前仍然有效,并保护它不受并发更新影响, @@ -1223,7 +1203,7 @@ SELECT pg_advisory_lock(q.id) FROM 在非可串行化的 MVCC 环境下,全局有效性检查需要额外考虑。 - 例如,一个银行应用可能希望检查一个表中的所有收入总和等于另一个表中的所有支出总和, + 例如,一个银行应用可能希望检查一个表中的贷方金额总和等于另一个表中的借方金额总和, 而这两个表都在被活跃更新。在读已提交模式下,比较两个连续的 SELECT sum(...) 命令的结果并不可靠,因为第二个查询很可能会包含第一个查询没有统计到的事务提交结果。 在单个可重复读事务中完成这两次求和,只能准确反映在该可重复读事务开始之前已提交事务的效果 @@ -1251,10 +1231,10 @@ SELECT pg_advisory_lock(q.id) FROM 串行化失败处理 - serialization failure + 串行化失败 - retryable error + 可重试错误 @@ -1291,7 +1271,7 @@ SELECT pg_advisory_lock(q.id) FROM 重试事务并不保证重试后的事务一定能够完成;可能需要多次重试。 在争用非常激烈的情况下,完成一个事务可能需要尝试很多次。 - 如果涉及相互冲突的已准备事务,那么在已准备事务提交或回滚之前,可能根本无法取得进展。 + 如果涉及相互冲突的预备事务,那么在预备事务提交或回滚之前,可能根本无法取得进展。 @@ -1319,8 +1299,8 @@ SELECT pg_advisory_lock(q.id) FROM 锁定和索引 - index - locks + 索引 + @@ -1333,7 +1313,7 @@ SELECT pg_advisory_lock(q.id) FROM - 读写访问使用短期的页级共享/排他锁。每个索引行在被取出或插入之后,锁都会立即释放。这些索引类型在不存在死锁条件的前提下提供了最高的并发性。 + 读写访问使用短期的页级共享/排他锁。每个索引行在被取出或插入之后,锁都会立即释放。这些索引类型提供最高的并发性,并且不会产生死锁。 @@ -1355,7 +1335,7 @@ SELECT pg_advisory_lock(q.id) FROM - 读写访问使用短期的页级共享/排他锁。每个索引行在被取出或插入之后,锁都会立即释放。但要注意,插入一个 GIN 索引值通常会导致每行产生多个索引键插入,因此 GIN 可能为了插入单个值而做大量工作。 + 读写访问使用短期的页级共享/排他锁。每个索引行在被取出或插入之后,锁都会立即释放。但要注意,插入一个使用 GIN 索引的值通常会导致每行产生多个索引键插入,因此 GIN 可能为了插入单个值而做大量工作。 diff --git a/zh/17/oid2name.sgml b/zh/17/oid2name.sgml index 4b80f64a..40bb461a 100644 --- a/zh/17/oid2name.sgml +++ b/zh/17/oid2name.sgml @@ -8,7 +8,7 @@ oid2name 1 - Application + 应用程序 diff --git a/zh/17/pageinspect.sgml b/zh/17/pageinspect.sgml index 8f7a931b..ed557738 100644 --- a/zh/17/pageinspect.sgml +++ b/zh/17/pageinspect.sgml @@ -370,20 +370,20 @@ test=# SELECT itemoffset, ctid, itemlen, nulls, vars, data, dead, htid, tids[0:2 13 | (16,8292) | 616 | f | f | 2f 00 00 00 00 00 00 00 | f | (4,17) | {"(4,17)","(4,21)"} (13 rows) - 这是一个 B-树叶页。所有指向表的元组恰好都是 posting list 元组(它们总共存储了 100 个 6 字节的 TID)。此外,在itemoffset 编号 1 处还有一个high key元组。这个示例中,ctid用于存储每个元组的编码信息,不过叶页元组通常会直接在ctid字段中存储一个堆 TID。tids是作为 posting list 存储的 TID 列表。 + 这是一个 B-树叶页。所有指向表的元组恰好都是倒排列表元组(每个都存储了 100 个 6 字节的 TID)。此外,在itemoffset 编号 1 处还有一个高键元组。这个示例中,ctid用于存储每个元组的编码信息,不过叶页元组通常会直接在ctid字段中存储一个堆 TID。tids是作为倒排列表存储的 TID 列表。 在内部页(此处未显示)中,ctid的块号部分是一个downlink(下行链接),也就是该索引中另一页的块号。ctid的偏移部分(第二个数字)存储着关于该元组的编码信息,例如实际存在的列数(后缀截断可能移除了不需要的后缀列)。被截断的列被视为具有minus infinity值。 - htid显示该元组的堆 TID,而不考虑底层元组表示形式。这个值可能与ctid相同,也可能是从 posting list 元组以及内部页元组所使用的替代表示中解码出来的。内部页中的元组通常会把实现层面的堆 TID 列截断掉,这会表现为htid值为 NULL。 + htid显示该元组的堆 TID,而不考虑底层元组表示形式。这个值可能与ctid相同,也可能是从倒排列表元组以及内部页元组所使用的替代表示中解码出来的。内部页中的元组通常会把实现层面的堆 TID 列截断掉,这会表现为htid值为 NULL。 - 请注意,任何非最右页(即btpo_next字段值非零的页面)的第一项都是该页的high key,这意味着它的data充当该页上所有项的上界,而它的ctid字段并不指向另一个块。另外,在内部页上,第一个真正的数据项(第一个不是high key的项)一定会把所有列都截断掉,因此其data字段中没有实际值。不过,这样的项在其ctid字段中确实有一个有效的下行链接。 + 请注意,任何非最右页(即btpo_next字段值非零的页面)的第一项都是该页的高键,这意味着它的data充当该页上所有项的上界,而它的ctid字段并不指向另一个块。另外,在内部页上,第一个真正的数据项(第一个不是高键的项)一定会把所有列都截断掉,因此其data字段中没有实际值。不过,这样的项在其ctid字段中确实有一个有效的下行链接。 - 关于 B-树索引结构的更多细节,参见。关于去重和 posting list 的更多细节,参见。关于去重和倒排列表的更多细节,参见 diff --git a/zh/17/parallel.sgml b/zh/17/parallel.sgml index 424f847e..8beb9974 100644 --- a/zh/17/parallel.sgml +++ b/zh/17/parallel.sgml @@ -222,7 +222,7 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%'; - Parallel Append + 并行追加 每当 PostgreSQL 需要将来自多个源的行合并成一个结果集时,它就会使用 AppendMergeAppend 计划节点。这种情况常见于实现 UNION ALL 或扫描分区表时。这样的节点和其他任何计划中的情形一样,也可以用于并行计划。不过,在并行计划中,规划器也可能改用 Parallel Append 节点。 @@ -300,7 +300,7 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%'; - 如果函数或聚合会写数据库、修改事务状态(而不是通过子事务进行错误恢复)、访问序列,或者对设置做持久更改,那么它们必须标记为 PARALLEL UNSAFE。类似地,如果函数访问临时表、客户端连接状态、游标、预备语句,或者系统无法在工作进程之间同步的各种后端本地状态,那么它必须标记为 PARALLEL RESTRICTED。例如,setseedrandom 就因为最后一个原因而属于并行受限。 + 如果函数或聚合会写数据库、修改事务状态(使用子事务进行错误恢复的情况除外)、访问序列,或者对设置做持久更改,那么它们必须标记为 PARALLEL UNSAFE。类似地,如果函数访问临时表、客户端连接状态、游标、预备语句,或者系统无法在工作进程之间同步的各种后端本地状态,那么它必须标记为 PARALLEL RESTRICTED。例如,setseedrandom 就因为最后一个原因而属于并行受限。 diff --git a/zh/17/perform.sgml b/zh/17/perform.sgml index 91ee1593..f13e238b 100644 --- a/zh/17/perform.sgml +++ b/zh/17/perform.sgml @@ -722,9 +722,9 @@ EXPLAIN ANALYZE SELECT * FROM tenk1 WHERE unique1 < 100 AND unique2 > 9000 of the planner - + - 单列统计信息 + <anchor id="zh18-auto-perform-sect2-1" xreflabel="单列统计信息"/>单列统计信息 如上一节所见,查询规划器需要估计查询将检索多少行,才能对查询计划做出良好选择。本节简要介绍系统用于这些估计的统计信息。 @@ -859,9 +859,9 @@ WHERE tablename = 'road'; 下面的小节介绍当前支持的扩展统计信息类型。 - + - 函数依赖 + <anchor id="zh18-auto-perform-sect3-1" xreflabel="函数依赖"/>函数依赖 最简单的一类扩展统计信息跟踪函数依赖,这是数据库范式定义中使用的概念。如果知道列a的值就足以确定列b的值,也就是说,不存在两行具有相同的a值却拥有不同的b值,那么就称列b函数依赖于列a。在完全规范化的数据库中,函数依赖应当只存在于主键和超键上。不过在实践中,很多数据集出于各种原因并未完全规范化,常见情形之一就是为了性能而有意进行反规范化。即使在完全规范化的数据库中,某些列之间也可能存在部分相关性,这可以表现为部分函数依赖。 @@ -897,9 +897,9 @@ SELECT stxname, stxkeys, stxddependencies 在为涉及函数依赖列的查询计算选择度时,规划器会使用依赖系数来调整针对条件的选择度估计,这样就不会产生低估。 - + - 函数依赖的限制 + <anchor id="zh18-auto-perform-sect4-1" xreflabel="函数依赖的限制"/>函数依赖的限制 当前只有在考虑简单等值条件(将列与常量值比较)和具有常量值的IN @@ -925,9 +925,9 @@ SELECT * FROM zipcodes WHERE city = 'San Francisco' AND zip = '90210'; - + - 多元可区分值计数 + <anchor id="zh18-auto-perform-sect3-2" xreflabel="多元可区分值计数"/>多元可区分值计数 单列统计信息存储每一列中可区分值的数量。在组合多个列(例如GROUP BY a, b)时,如果规划器只有单列统计数据,则对可区分值数量的估计常常会错误,导致选择不好的计划。 @@ -960,9 +960,9 @@ nd | {"1, 2": 33178, "1, 5": 33178, "2, 5": 27435, "1, 2, 5": 33178} - + - 多元 MCV 列表 + <anchor id="zh18-auto-perform-sect3-3" xreflabel="多元 MCV 列表"/>多元 MCV 列表 另一类按列存储的统计信息是高频值列表。这允许对单列做出非常准确的估计,但对于同时涉及多个列条件的查询,仍可能产生显著误差。 diff --git a/zh/17/pgcrypto.sgml b/zh/17/pgcrypto.sgml index e716961a..5dd09a55 100644 --- a/zh/17/pgcrypto.sgml +++ b/zh/17/pgcrypto.sgml @@ -225,15 +225,14 @@ gen_salt(type text [, iter_count integer ]) returns text - type参数指定哈希算法。 - 接受的类型有:desxdesmd5 - 和 bf。 + type参数指定 hash 算法。 + 接受的类型有:desxdesmd5bf iter_count参数允许用户为支持该参数的算法指定迭代次数。 - 次数越高,密码哈希所需时间越长,从而破解它所需时间也越长。 - 不过,如果次数过高,计算一个哈希可能需要数年时间 — 这显然不切实际。 + 次数越高,对密码进行 hash 所需的时间越长,从而破解它所需时间也越长。 + 不过,如果次数过高,计算一个 hash 可能需要数年时间 — 这显然不切实际。 若省略iter_count参数,则使用默认迭代次数。 允许的iter_count值取决于算法,如所示。 @@ -271,24 +270,24 @@ gen_salt(type text [, iter_count integer ]) returns text - 为了选择合适的迭代次数,可以考虑原始 DES crypt 在当时硬件上的设计速度是每秒 4 次哈希。 - 低于每秒 4 次哈希可能会影响可用性,而高于每秒 100 次哈希则很可能过快。 + 为了选择合适的迭代次数,可以考虑原始 DES crypt 在当时硬件上的设计速度是每秒 4 次 hash。 + 低于每秒 4 次 hash 可能会影响可用性,而高于每秒 100 次 hash 则很可能过快。 - 概述了不同哈希算法之间的相对速度差异。 + 概述了不同 hash 算法之间的相对速度差异。 该表展示了在 8 字符密码上尝试所有字符组合所需的时间,假定密码只包含小写字母, 或者包含大小写字母和数字。在crypt-bf条目中, 斜杠后的数字是gen_saltiter_count参数值。
- 哈希算法速度 + Hash 算法速度 算法 - 每秒哈希次数 + 每秒 hash 次数 针对[a-z] 针对[A-Za-z0-9] 相对于md5 hash的耗时倍数 diff --git a/zh/17/plhandler.sgml b/zh/17/plhandler.sgml index 38562e46..4048d572 100644 --- a/zh/17/plhandler.sgml +++ b/zh/17/plhandler.sgml @@ -17,11 +17,11 @@ - 调用处理器与其他函数一样被调用:它会接收一个指向 FunctionCallInfoBaseData struct 的指针,其中包含参数值以及被调用函数的相关信息;同时它还应返回一个 Datum 结果(如果希望返回 SQL 空值结果,还可以设置 isnull 字段,也就是 FunctionCallInfoBaseData 结构体中的该字段)。调用处理器与普通被调函数之间的区别在于,flinfo->fn_oid 字段在 FunctionCallInfoBaseData 结构体中保存的是实际要调用函数的 OID,而不是调用处理器本身的 OID。调用处理器必须使用这个字段来判定要执行哪个函数。另外,传入的参数列表是按照目标函数而不是调用处理器的声明来设置的。 + 调用处理器与其他函数一样被调用:它会接收一个指向 FunctionCallInfoBaseData struct 的指针,其中包含参数值以及被调用函数的相关信息;同时它还应返回一个 Datum 结果(如果希望返回 SQL 空值结果,还需要设置 isnull 字段,也就是 FunctionCallInfoBaseData 结构体中的该字段)。调用处理器与普通被调函数之间的区别在于,flinfo->fn_oid 字段在 FunctionCallInfoBaseData 结构体中保存的是实际要调用函数的 OID,而不是调用处理器本身的 OID。调用处理器必须使用这个字段来判定要执行哪个函数。另外,传入的参数列表是按照目标函数而不是调用处理器的声明来设置的。 - 调用处理器必须从系统目录 pg_proc 中取出该函数的条目,并分析被调用函数的参数类型和返回类型。该函数的 AS 子句可在其 CREATE FUNCTION 命令对应的 prosrc 列里找到,也就是 pg_proc 行中的该列。这里通常是一段过程语言源文本,但理论上也可以是其他内容,例如某个文件的路径名,或者任何能详细告诉调用处理器该做什么的信息。 + 调用处理器必须从系统目录 pg_proc 中取出该函数的条目,并分析被调用函数的参数类型和返回类型。该函数的 CREATE FUNCTION 命令中的 AS 子句内容,保存在 pg_proc 对应行的 prosrc 列中。这里通常是一段过程语言源文本,但理论上也可以是其他内容,例如某个文件的路径名,或者任何能详细告诉调用处理器该做什么的信息。 @@ -46,7 +46,7 @@ 验证器函数通常应遵循 参数:如果它被关闭,就应跳过任何开销高昂或依赖上下文的检查。如果该语言允许在编译时执行代码,验证器还必须抑制会诱发此类执行的检查。特别是,pg_dump 会关闭这个参数,这样它就可以装载过程语言函数,而不必担心函数体对其他数据库对象的副作用或依赖关系。(正因为有这一要求,调用处理器不应假设验证器已经完整检查了函数。提供验证器的目的,并不是让调用处理器省略检查,而是在 CREATE FUNCTION 命令中存在明显错误时立即通知用户。)虽然究竟检查哪些内容主要由验证器函数自行决定,但要注意,核心 CREATE FUNCTION 代码只会执行附加到函数上的 SET 子句,前提是 check_function_bodies 打开。因此,当 check_function_bodies 关闭时,那些结果可能受 GUC 参数影响的检查肯定都应跳过,以避免在恢复转储时出现虚假的失败。 + linkend="guc-check-function-bodies"/> 参数:如果它被关闭,就应跳过任何开销高昂或依赖上下文的检查。如果该语言允许在编译时执行代码,验证器还必须抑制会诱发此类执行的检查。特别是,pg_dump 会关闭这个参数,这样它就可以装载过程语言函数,而不必担心副作用或函数体对其他数据库对象的依赖关系。(正因为有这一要求,调用处理器不应假设验证器已经完整检查了函数。提供验证器的目的,并不是让调用处理器省略检查,而是在 CREATE FUNCTION 命令中存在明显错误时立即通知用户。)虽然究竟检查哪些内容主要由验证器函数自行决定,但要注意,只有在 check_function_bodies 打开时,核心 CREATE FUNCTION 代码才会执行函数附带的 SET 子句。因此,当 check_function_bodies 关闭时,那些结果可能受 GUC 参数影响的检查肯定都应跳过,以避免在恢复转储时出现虚假的失败。 diff --git a/zh/17/plperl.sgml b/zh/17/plperl.sgml index 7fc5b272..a7da7851 100644 --- a/zh/17/plperl.sgml +++ b/zh/17/plperl.sgml @@ -13,7 +13,7 @@ - PL/Perl 是一种可载入的过程语言,它允许使用 + PL/Perl 是一种可加载的过程语言,它允许使用 Perl 编程语言编写 PostgreSQL 函数和过程。 @@ -32,8 +32,7 @@ - 如果把该语言安装到 template1 中,之后创建的所有 - 数据库都会自动安装该语言。 + 如果把某种语言安装到template1中,之后创建的所有数据库都会自动安装该语言。 @@ -57,9 +56,9 @@ CREATE FUNCTION funcname (argument-types) RETURNS return-type --- function attributes can go here +-- 函数属性可以写在这里 AS $$ - # PL/Perl function body goes here + # PL/Perl 函数体写在这里 $$ LANGUAGE plperl; @@ -78,7 +77,7 @@ $$ LANGUAGE plperl; DO $$ - # PL/Perl code + # PL/Perl 代码 $$ LANGUAGE plperl; @@ -136,15 +135,14 @@ $$ LANGUAGE plperl; 如果一个 SQL 空值空值in PL/Perl被传给一个函数,在 - Perl 中该参数值将呈现为undefined。上述函数定义对于 - 空输入的行为并不理想(实际上,它会把它们当作零)。我们可以在函数 + sortas="PL/Perl">在 PL/Perl 中被传给一个函数,在 + Perl 中该参数值将呈现为未定义。上述函数定义对于 + 空值输入的行为并不理想(实际上,它会把它们当作零)。我们可以在函数 定义中添加 STRICT,让 PostgreSQL 采取更合理的做法:如果传入空值, - 函数将根本不会被调用,而是自动返回空结果。另一种方式是在函数体中 + 函数将根本不会被调用,而是自动返回空值结果。另一种方式是在函数体中 检查未定义输入。例如,假设我们希望在 - perl_max 的两个参数中一个为空、另一个非空时, - 返回非空参数而不是空值: + perl_max 的两个参数中一个为空值、另一个非空值时,返回非空值参数而不是空值: CREATE FUNCTION perl_max (integer, integer) RETURNS integer AS $$ @@ -186,7 +184,7 @@ $$ LANGUAGE plperl; bool_plperl 扩展提供了合适的转换。要使用它, 请先安装该扩展: -CREATE EXTENSION bool_plperl; -- or bool_plperlu for PL/PerlU +CREATE EXTENSION bool_plperl; -- 对于 PL/PerlU,则使用 bool_plperlu 然后对接收或返回 bool 的 PL/Perl 函数使用 TRANSFORM 函数属性,例如: @@ -199,7 +197,7 @@ AS $$ $$ LANGUAGE plperl; 应用该转换后,Perl 会将 bool 参数视为 - 1 或空值,从而能正确表示真或假。如果函数结果类型为 + 1 或空字符串,从而能正确表示真或假。如果函数结果类型为 bool,则其真或假取决于 Perl 是否会将返回值求值为真。 对函数内部执行的 SPI 查询,其布尔查询参数和结果也会进行类似的转换 ()。 @@ -232,12 +230,12 @@ CREATE OR REPLACE FUNCTION concat_array_elements(text[]) RETURNS TEXT AS $$ my $result = ""; return undef if (!defined $arg); - # as an array reference + # 作为数组引用 for (@$arg) { $result .= $_; } - # also works as a string + # 也可以作为字符串使用 $result .= $arg; return $result; @@ -248,7 +246,8 @@ SELECT concat_array_elements(ARRAY['PL','/','Perl']); - 多维数组会以所有 Perl 程序员都熟悉的方式,表示为对低维数组引用的引用。 + 多维数组按 Perl 程序员熟悉的方式表示为指向较低维数组的引用, + 而这些数组的元素又是引用。 @@ -357,11 +356,11 @@ SELECT * FROM perl_set(); 如果希望在代码中使用 strict 编译指示,可以有几种 选择。对于临时的全局用法,可以 SET - plperl.use_strict 为 true。这会影响后续编译的 + plperl.use_strict 为真。这会影响后续编译的 PL/Perl 函数,但不会影响当前会话中已经编译的 函数。对于永久的全局用法,可以在 postgresql.conf 文件中将 - plperl.use_strict 设为 true。 + plperl.use_strict 设为真。 @@ -417,7 +416,7 @@ use strict; spi_exec_query(query [, limit]) spi_exec_query - in PL/Perl + 在 PL/Perl 中 @@ -503,7 +502,7 @@ SELECT * FROM test_munge(); spi_query(command) spi_query - in PL/Perl + 在 PL/Perl 中 @@ -511,7 +510,7 @@ SELECT * FROM test_munge(); spi_fetchrow(cursor) spi_fetchrow - in PL/Perl + 在 PL/Perl 中 @@ -519,7 +518,7 @@ SELECT * FROM test_munge(); spi_cursor_close(cursor) spi_cursor_close - in PL/Perl + 在 PL/Perl 中 @@ -539,7 +538,7 @@ CREATE OR REPLACE FUNCTION lotsa_md5 (INTEGER) RETURNS SETOF foo_type AS $$ my $file = '/usr/share/dict/words'; my $t = localtime; elog(NOTICE, "opening file $file at $t" ); - open my $fh, '<', $file # ooh, it's a file access! + open my $fh, '<', $file # 注意,这里访问了文件! or elog(ERROR, "cannot open $file for reading: $!"); my @words = <$fh>; close $fh; @@ -579,7 +578,7 @@ SELECT * from lotsa_md5(500); spi_prepare(command, argument types) spi_prepare - in PL/Perl + 在 PL/Perl 中 @@ -587,7 +586,7 @@ SELECT * from lotsa_md5(500); spi_query_prepared(plan, arguments) spi_query_prepared - in PL/Perl + 在 PL/Perl 中 @@ -595,7 +594,7 @@ SELECT * from lotsa_md5(500); spi_exec_prepared(plan [, attributes], arguments) spi_exec_prepared - in PL/Perl + 在 PL/Perl 中 @@ -603,7 +602,7 @@ SELECT * from lotsa_md5(500); spi_freeplan(plan) spi_freeplan - in PL/Perl + 在 PL/Perl 中 @@ -612,7 +611,7 @@ SELECT * from lotsa_md5(500); spi_preparespi_query_preparedspi_exec_preparedspi_freeplan - 提供相同的功能,但用于预处理查询。spi_prepare + 提供相同的功能,但用于预备查询。spi_prepare 接受一个带编号参数占位符($1、$2 等)的查询字符串,以及参数类型的 字符串列表: @@ -631,7 +630,7 @@ $plan = spi_prepare('SELECT * FROM test WHERE id > $1 AND name = $2', - 预处理查询的优点在于,一个准备好的计划可以用于多次查询执行。当计划 + 预备查询的优点在于,一个准备好的计划可以用于多次查询执行。当计划 不再需要时,可以用 spi_freeplan 将其释放: CREATE OR REPLACE FUNCTION init() RETURNS VOID AS $$ @@ -708,7 +707,7 @@ SELECT release_hosts_query(); spi_commit() spi_commit - in PL/Perl + 在 PL/Perl 中 @@ -716,7 +715,7 @@ SELECT release_hosts_query(); spi_rollback() spi_rollback - in PL/Perl + 在 PL/Perl 中 @@ -756,7 +755,7 @@ CALL transaction_test1(); - PL/Perl 中的工具函数 + PL/Perl 中的辅助函数 @@ -765,7 +764,7 @@ CALL transaction_test1(); elog(level, msg) elog - in PL/Perl + 在 PL/Perl 中 @@ -791,7 +790,7 @@ CALL transaction_test1(); quote_literal(string) quote_literal - in PL/Perl + 在 PL/Perl 中 @@ -812,7 +811,7 @@ CALL transaction_test1(); quote_nullable(string) quote_nullable - in PL/Perl + 在 PL/Perl 中 @@ -831,7 +830,7 @@ CALL transaction_test1(); quote_ident(string) quote_ident - in PL/Perl + 在 PL/Perl 中 @@ -850,7 +849,7 @@ CALL transaction_test1(); decode_bytea(string) decode_bytea - in PL/Perl + 在 PL/Perl 中 @@ -868,7 +867,7 @@ CALL transaction_test1(); encode_bytea(string) encode_bytea - in PL/Perl + 在 PL/Perl 中 @@ -885,7 +884,7 @@ CALL transaction_test1(); encode_array_literal(array) encode_array_literal - in PL/Perl + 在 PL/Perl 中 @@ -908,7 +907,7 @@ CALL transaction_test1(); encode_typed_literal(value, typename) encode_typed_literal - in PL/Perl + 在 PL/Perl 中 @@ -926,7 +925,7 @@ CALL transaction_test1(); encode_array_constructor(array) encode_array_constructor - in PL/Perl + 在 PL/Perl 中 @@ -947,7 +946,7 @@ CALL transaction_test1(); looks_like_number(string) looks_like_number - in PL/Perl + 在 PL/Perl 中 @@ -967,7 +966,7 @@ CALL transaction_test1(); is_array_ref(argument) is_array_ref - in PL/Perl + 在 PL/Perl 中 @@ -1025,9 +1024,9 @@ CREATE OR REPLACE FUNCTION myfuncs() RETURNS void AS $$ }; $$ LANGUAGE plperl; -SELECT myfuncs(); /* initializes the function */ +SELECT myfuncs(); /* 初始化函数 */ -/* Set up a function that uses the quote function */ +/* 创建一个使用加引号函数的函数 */ CREATE OR REPLACE FUNCTION use_quote(TEXT) RETURNS text AS $$ my $text_to_quote = shift; @@ -1042,11 +1041,9 @@ $$ LANGUAGE plperl; - 出于安全原因,PL/Perl 会为某个 SQL 角色调用的函数在该角色专用的独立 - Perl 解释器中执行。这可以防止一个用户意外或恶意地干扰另一个用户的 + 出于安全原因,PL/Perl 会在每个 SQL 角色各自独立的 Perl 解释器中执行该角色调用的函数。这可以防止一个用户意外或恶意地干扰另一个用户的 PL/Perl 函数行为。每个这样的解释器都有自己的 - %_SHARED 变量值和其他全局状态。因此,只有在两个 - PL/Perl 函数都由同一 SQL 角色执行时,它们才会共享 + %_SHARED 变量值和其他全局状态。因此,当且仅当两个 PL/Perl 函数都由同一 SQL 角色执行时,它们才会共享 %_SHARED 的值。在某些应用中,一个会话可能会在多个 SQL 角色下执行代码(通过 SECURITY DEFINER 函数、 使用 SET ROLE 等),这时可能需要显式采取措施, @@ -1059,29 +1056,29 @@ $$ LANGUAGE plperl; - 可信与不可信的 PL/Perl + 受信任与不受信任的 PL/Perl - trusted + 受信任的 PL/Perl 通常,PL/Perl 会被安装为一种名为 plperl 的 - 可信编程语言。在这种设置下,为了保持安全性,某些 Perl + 受信任的编程语言。在这种设置下,为了保持安全性,某些 Perl 操作会被禁用。一般来说,受限制的是那些与环境交互的操作,包括文件句柄 操作、requireuse (针对外部模块)。它无法像 C 函数那样访问数据库服务器进程的内部, - 也无法以服务器进程的权限获取操作系统级访问。因此,可以允许任何无权限 + 也无法以服务器进程的权限获取操作系统级访问。因此,可以允许任何无特权 的数据库用户使用这种语言。 - 可信 PL/Perl 依赖 Perl 的 Opcode 模块来维持安全性。 + 受信任的 PL/Perl 依赖 Perl 的 Opcode 模块来维持安全性。 Perl 的 文档 - 指出,该模块对于可信 PL/Perl 这一使用场景并不有效。若你的安全需求 + 指出,该模块对于受信任的 PL/Perl 这一使用场景并不有效。若你的安全需求 不能接受该警告中的不确定性,请考虑执行 REVOKE USAGE ON LANGUAGE plperl FROM PUBLIC @@ -1105,16 +1102,16 @@ $$ LANGUAGE plperl; 有时需要编写不受这些限制的 Perl 函数。例如,可能需要一个能发送邮件的 Perl 函数。为处理这类情况,也可以把 PL/Perl 安装成一种 - 不可信语言(通常称为 + 不受信任的语言(通常称为 PL/PerlUPL/PerlU)。 在这种情况下,完整的 Perl 语言都可用。安装该语言时,使用语言名 - plperlu 就会选择不可信的 PL/Perl 变体。 + plperlu 就会选择不受信任的 PL/Perl 变体。 PL/PerlU 函数的编写者必须注意,函数不能被 用于任何非预期用途,因为它能够执行以数据库管理员身份登录的用户所能 - 做的任何事情。请注意,数据库系统只允许数据库超级用户用不可信语言创建 + 做的任何事情。请注意,数据库系统只允许数据库超级用户用不受信任的语言创建 函数。 @@ -1249,7 +1246,7 @@ $$ LANGUAGE plperl; $_TD->{relname} - 触发该触发器的表名。该字段已废弃,并且可能会在未来版本中移除。 + 触发该触发器的表名。该字段已弃用,并且可能会在未来版本中移除。 请改用 $_TD->{table_name}。 @@ -1328,12 +1325,12 @@ CREATE TABLE test ( CREATE OR REPLACE FUNCTION valid_id() RETURNS trigger AS $$ if (($_TD->{new}{i} >= 100) || ($_TD->{new}{i} <= 0)) { - return "SKIP"; # skip INSERT/UPDATE command + return "SKIP"; # 跳过 INSERT/UPDATE 命令 } elsif ($_TD->{new}{v} ne "immortal") { $_TD->{new}{v} .= "(modified by trigger)"; - return "MODIFY"; # modify row and execute INSERT/UPDATE command + return "MODIFY"; # 修改行并执行 INSERT/UPDATE 命令 } else { - return; # execute INSERT/UPDATE command + return; # 执行 INSERT/UPDATE 命令 } $$ LANGUAGE plperl; @@ -1490,7 +1487,7 @@ DO 'elog(WARNING, join ", ", sort keys %INC)' LANGUAGE plperl; 也会发生。这是在 plperl.on_init 完成的任何初始化 之后进行的。执行这段代码时 SPI 函数不可用。 plperl.on_plperl_init 中的 Perl 代码是在对解释器 - 进行锁定之后执行的,因此只能执行可信操作。 + 进行锁定之后执行的,因此只能执行受信任的操作。 diff --git a/zh/17/plpgsql.sgml b/zh/17/plpgsql.sgml index 46d0fc21..fbc68cac 100644 --- a/zh/17/plpgsql.sgml +++ b/zh/17/plpgsql.sgml @@ -70,7 +70,7 @@ - 借助 PL/pgSQL,可将一段计算逻辑和一系列查询放在数据库服务器内部执行。这样既具备了过程语言的能力,也保留了 SQL 的易用性,同时还能显著减少客户端/服务器通信开销。 + 借助 PL/pgSQL,你可以把一段计算逻辑和一系列查询放在数据库服务器内部执行。这样既具备了过程语言的能力,也保留了 SQL 的易用性,同时还能显著减少客户端/服务器通信开销。 @@ -95,7 +95,7 @@ - 此外,通过 PL/pgSQL 可使用 SQL 的全部数据类型、操作符和函数。 + 此外,通过 PL/pgSQL 你可以使用 SQL 的全部数据类型、操作符和函数。 @@ -144,7 +144,7 @@ CREATE FUNCTION somefunc(integer, text) RETURNS integer AS 'function body text' LANGUAGE plpgsql; - 就 CREATE FUNCTION 而言,函数体目前只是一个字符串字面量。编写函数体时,通常最好使用美元引用(见 ),而不是普通的单引号语法。如果不使用美元引用,函数体中的任何单引号或反斜线都必须通过双写进行转义。本章几乎所有示例的函数体都使用了美元引用。 + 就 CREATE FUNCTION 而言,函数体只是一个字符串字面量。编写函数体时,通常最好使用美元引用(见 ),而不是普通的单引号语法。如果不使用美元引用,函数体中的任何单引号或反斜线都必须通过双写进行转义。本章几乎所有示例的函数体都使用了美元引用。 @@ -172,7 +172,7 @@ END label ; - 只有在希望通过 EXIT 语句标识某个块,或者希望用块名限定块内声明的变量名时,才需要 label。如果在 END 之后写了标签,它必须与块开始处的标签一致。 + 只有在你希望通过 EXIT 语句标识某个块,或者希望用块名限定块内声明的变量名时,才需要 label。如果在 END 之后写了标签,它必须与块开始处的标签一致。 @@ -340,7 +340,7 @@ $$ LANGUAGE plpgsql; - 当 PL/pgSQL 函数声明了输出参数时,输出参数也会像普通输入参数一样获得 $n 名称和可选别名。输出参数本质上是一个初始值为 NULL 的变量,应在函数执行期间给它赋值。该参数的最终值就是返回值。例如,sales_tax 的示例也可以这样写: + 当 PL/pgSQL 函数声明了输出参数时,输出参数也会像普通输入参数一样获得 $n 名称和可选别名。输出参数本质上是一个初始值为 NULL 的变量,应在函数执行期间给它赋值。该参数的最终值就是返回值。例如,销售税的示例也可以这样写: CREATE FUNCTION sales_tax(subtotal real, OUT tax real) AS $$ @@ -398,7 +398,7 @@ SELECT * FROM sum_n_product(2, 4); -----+------ 6 | 8 - 但是,当从 PL/pgSQL 中调用过程时,应当为每个输出参数写一个变量;该变量会接收调用结果。详见 。 + 但是,当从 PL/pgSQL 中调用过程时,你应当为每个输出参数写一个变量;该变量会接收调用结果。详见 @@ -465,7 +465,7 @@ $$ LANGUAGE plpgsql; SELECT add_three_values(1, 2, 4.7); - 可以正常工作,并会自动把整数输入提升为 numeric。如果使用 anyelement,则必须手工把这三个输入转换成同一类型。 + 可以正常工作,并会自动把整数输入提升为 numeric。如果使用 anyelement,则必须手工把这三个输入转换成同一类型。 @@ -504,7 +504,7 @@ DECLARE - %TYPE 提供表列或先前已声明的 PL/pgSQL 变量的数据类型。可用它来声明用于保存数据库值的变量。例如,假设 users 表中有一个名为 user_id 的列。要声明一个与 users.user_id 具有相同数据类型的变量,可以这样写: + %TYPE 提供表列或先前已声明的 PL/pgSQL 变量的数据类型。你可以用它来声明用于保存数据库值的变量。例如,假设 users 表中有一个名为 user_id 的列。要声明一个与 users.user_id 具有相同数据类型的变量,可以这样写: user_id users.user_id%TYPE; @@ -516,11 +516,11 @@ user_id users.user_id%TYPE; user_ids users.user_id%TYPE[]; user_ids users.user_id%TYPE ARRAY[4]; -- 等价于上面一行 - 与声明数组表列时一样,写多个方括号还是写具体数组维度都无关紧要:PostgreSQL 会把同一元素类型的所有数组都视为同一种类型,而不考虑维度数。(见 。) + 与声明数组表列时一样,写多对方括号还是写具体数组维度都无关紧要:PostgreSQL 会把同一元素类型的所有数组都视为同一种类型,而不考虑维度数。(见 。) - 使用 %TYPE 的好处是,无需知道所引用结构的实际数据类型;更重要的是,如果被引用项的数据类型将来发生变化(例如把 user_id 的类型从 integer 改成 real),可能就不需要修改函数定义。 + 使用 %TYPE 的好处是,你不必知道所引用结构的实际数据类型;更重要的是,如果被引用项的数据类型将来发生变化(例如把 user_id 的类型从 integer 改成 real),你可能就不需要修改函数定义。 @@ -594,12 +594,12 @@ SELECT merge_fields(t.*) FROM table1 t WHERE ... ; <application>PL/pgSQL</application>变量的排序规则 - collation - in PL/pgSQL + 排序规则 + 在 PL/pgSQL 中 - 当 PL/pgSQL 函数具有一个或多个可排序数据类型参数时,每次函数调用都会根据分配给实际参数的排序规则确定出一个排序规则,如 所述。如果该排序规则能成功确定出来(即参数之间的隐式排序规则没有冲突),那么所有可排序参数都会被视为隐式带有该排序规则。这会影响函数中那些受排序规则影响的操作。例如,考虑 + 当 PL/pgSQL 函数具有一个或多个支持排序规则的数据类型参数时,每次函数调用都会根据分配给实际参数的排序规则确定出一个排序规则,如 所述。如果该排序规则能成功确定出来(即参数之间的隐式排序规则没有冲突),那么所有支持排序规则的参数都会被视为隐式带有该排序规则。这会影响函数中那些受排序规则影响的操作。例如,考虑 CREATE FUNCTION less_than(a text, b text) RETURNS boolean AS $$ @@ -616,7 +616,7 @@ SELECT less_than(text_field_1, text_field_2 COLLATE "C") FROM table1; - 此外,确定出的排序规则也会被视为任何可排序数据类型局部变量的排序规则。因此,即使把这个函数写成下面这样,其行为也不会有任何不同: + 此外,确定出的排序规则也会被视为任何支持排序规则的数据类型局部变量的排序规则。因此,即使把这个函数写成下面这样,其行为也不会有任何不同: CREATE FUNCTION less_than(a text, b text) RETURNS boolean AS $$ @@ -631,11 +631,11 @@ $$ LANGUAGE plpgsql; - 如果函数没有可排序数据类型的参数,或者无法为它们确定共同排序规则,那么参数和局部变量将使用其数据类型的默认排序规则(通常是数据库默认排序规则,但对于域类型变量也可能不同)。 + 如果函数没有支持排序规则的数据类型的参数,或者无法为它们确定共同排序规则,那么参数和局部变量将使用其数据类型的默认排序规则(通常是数据库默认排序规则,但对于域类型变量也可能不同)。 - 通过在可排序数据类型局部变量的声明中加入 COLLATE 选项,可以为其指定不同的排序规则,例如 + 通过在支持排序规则的数据类型局部变量的声明中加入 COLLATE 选项,可以为其指定不同的排序规则,例如 DECLARE @@ -715,8 +715,7 @@ PREPARE statement_name(integer, integer) AS SELECT $1 SELECT命令被发送到主数据库引擎的方式计算。 该表达式必须得到一个单一值(如果该变量是一个行或记录变量, 它可能是一个行值)。该目标变量可以是一个简单变量( - 可以选择用一个块名限定)、一个行或记录变量的域或是一个简单 - 变量或域的数组的元素或者数组的切片。 + 可以选择用一个块名限定)、行或记录目标的字段,或者数组目标的元素或切片。 等号(=)可以被用来代替 PL/SQL-兼容的 := @@ -762,19 +761,19 @@ complex_array[n].realpart = 12.3; - 仅仅执行静态定义的 SQL 命令通常是不够的。通常,还会希望某条命令使用可变的数据值,甚至以更根本的方式变化,例如在不同时间使用不同的表名。根据具体情况,同样也有两种处理方式。 + 仅仅执行静态定义的 SQL 命令通常是不够的。通常,你会希望一条命令使用可变的数据值,甚至还希望以更根本的方式变化,例如在不同时间使用不同的表名。根据具体情况,同样也有两种处理方式。 - PL/pgSQL 变量值可以自动插入可优化的 SQL 命令中,这些命令包括 SELECTINSERTUPDATEDELETEMERGE 以及某些包含其中之一的实用程序命令,比如 EXPLAINCREATE TABLE ... AS SELECT。在这些命令中,命令文本中出现的任何 PL/pgSQL 变量名都会被查询参数替换,然后变量的当前值会在运行时作为参数值提供。这与前面描述的表达式处理完全相同;详情请参见 。 + PL/pgSQL 变量值可以自动插入可优化的 SQL 命令中,这些命令包括 SELECTINSERTUPDATEDELETEMERGE 以及某些包含其中之一的工具命令,比如 EXPLAINCREATE TABLE ... AS SELECT。在这些命令中,命令文本中出现的任何 PL/pgSQL 变量名都会被查询参数替换,然后变量的当前值会在运行时作为参数值提供。这与前面描述的表达式处理完全相同;详情请参见 - 当以这种方式执行一个可优化的 SQL 命令时,如 中讨论的,PL/pgSQL 会为该命令缓存并重用执行计划。 + 当以这种方式执行一个可优化的 SQL 命令时,如中讨论的,PL/pgSQL可能会为该命令缓存并重用执行计划。 - 不可优化的 SQL 命令(也称为实用命令)不能接受查询参数。因此,自动替换 PL/pgSQL 变量在这类命令中不起作用。要在从 PL/pgSQL 执行的实用程序命令中包含非常量文本,必须将实用程序命令构建为一个字符串,然后用 EXECUTE 执行它,如 中所讨论的。 + 不可优化的 SQL 命令(也称为工具命令)不能接受查询参数。因此,自动替换 PL/pgSQL 变量在这类命令中不起作用。要在从 PL/pgSQL 执行的工具命令中包含非常量文本,必须将工具命令构建为一个字符串,然后用 EXECUTE 执行它,如 中所讨论的。 @@ -812,12 +811,12 @@ PERFORM create_mv('cs_session_page_requests_mv', my_query); SELECT INTO - in PL/pgSQL + 在 PL/pgSQL 中 RETURNING INTO - in PL/pgSQL + 在 PL/pgSQL 中 @@ -842,7 +841,7 @@ MERGE ... RETURNING expressions INTO STRICT - 如果一个行变量或一个变量列表被用作目标,该命令的结果列必须完全匹配该结果的结构,包括数量和数据类型,否则会发生一个运行时错误。当一个记录变量是目标时,它会自动地把自身配置成命令的结果列组成的行类型。 + 如果一个行变量或一个变量列表被用作目标,该命令的结果列必须完全匹配该目标的结构,包括数量和数据类型,否则会发生一个运行时错误。当一个记录变量是目标时,它会自动地把自身配置成命令的结果列组成的行类型。 @@ -850,7 +849,7 @@ MERGE ... RETURNING expressions INTO STRICT - 如果STRICT没有在INTO子句中被指定,那么target将被设置为该命令返回的第一个行,或者在该命令不返回行时设置为空(注意除非使用了ORDER BY,否则第一行的界定并不清楚)。第一行之后的任何结果行都会被抛弃。你可以检查特殊的FOUND变量(见)来确定是否返回了一行: + 如果STRICT没有在INTO子句中被指定,那么target将被设置为该命令返回的第一个行,或者在该命令不返回行时设置为空值(注意除非使用了ORDER BY,否则第一行的界定并不清楚)。第一行之后的任何结果行都会被抛弃。你可以检查特殊的FOUND变量(见)来确定是否返回了一行: SELECT * INTO myrec FROM emp WHERE empname = myname; @@ -879,7 +878,7 @@ END; - 如果为函数启用了print_strict_params,那么当由于不满足STRICT要求而抛出错误时,错误消息的DETAIL部分将包含传给该命令的参数信息。你可以通过设置plpgsql.print_strict_params来修改所有函数的print_strict_params设置,不过只有此后重新编译的函数才会受影响。也可以通过编译器选项按函数启用它,例如: + 如果为函数启用了print_strict_params,那么当由于不满足STRICT要求而抛出错误时,错误消息的DETAIL部分将包含传给该命令的参数信息。你可以通过设置plpgsql.print_strict_params来修改所有函数的print_strict_params设置,不过该设置只会影响此后编译的函数。也可以通过编译器选项按函数启用它,例如: CREATE FUNCTION get_userid(username text) RETURNS int AS $$ @@ -915,33 +914,31 @@ CONTEXT: PL/pgSQL function get_userid(text) line 6 at SQL statement 执行动态命令 - 很多时候你将想要在PL/pgSQL函数中产生动态命令,也就是每次执行中会涉及到不同表或不同数据类型的命令。PL/pgSQL通常对于命令所做的缓存计划尝试(如中讨论)在这种情境下无法工作。要处理这一类问题,需要提供EXECUTE语句: + 很多时候你将想要在PL/pgSQL函数中产生动态命令,也就是每次执行中会涉及到不同表或不同数据类型的命令。PL/pgSQL通常对于命令所做的缓存计划尝试(如中讨论)在这种情境下无法工作。要处理这一类问题,提供了EXECUTE语句: EXECUTE command-string INTO STRICT target USING expression , ... ; - 其中command-string是一个能得到一个包含要被执行命令字符串(类型text)的表达式。可选的target是一个记录变量、一个行变量或者一个逗号分隔的简单变量以及记录/行域的列表,该命令的结果将存储在其中。可选的USING表达式提供要被插入到该命令中的值。 + 其中command-string是一个能得到一个包含要被执行命令字符串(类型text)的表达式。可选的target是一个记录变量、一个行变量或者一个逗号分隔的简单变量以及记录/行字段的列表,该命令的结果将存储在其中。可选的USING表达式提供要被插入到该命令中的值。 在计算得到的命令字符串中,不会做PL/pgSQL变量的替换。任何所需的变量值必须在命令字符串被构造时被插入其中,或者你可以使用下面描述的参数。 - - 还有,对于通过EXECUTE执行的命令不会有计划被缓存。该命令反而在每次运行时都会被做计划。因此,该命令字符串可以在执行不同表和列上动作的函数中被动态创建。 - + 此外,通过 EXECUTE 执行的命令不会缓存计划,而是在每次运行该语句时重新规划。因此,可以在函数中动态构造命令字符串,对不同的表和列执行操作。 - INTO子句指定一个返回行的 SQL 命令的结果应该被赋值到哪里。如果提供了一个行或变量列表,它必须完全匹配查询命令结果的结构(当一个记录变量被提供时,它会自动把它自己配置为匹配结果结构)。如果返回多个行,只有第一个行会被赋值给INTO变量。如果没有返回行,NULL 会被赋值给INTO变量。如果没有指定INTO变量,该查询结果会被抛弃。 + INTO子句指定一个返回行的 SQL 命令的结果应该被赋值到哪里。如果提供了一个行变量或变量列表,它必须完全匹配查询命令结果的结构(当一个记录变量被提供时,它会自动把它自己配置为匹配结果结构)。如果返回多个行,只有第一个行会被赋值给INTO变量。如果没有返回行,NULL 会被赋值给INTO变量。如果没有指定INTO子句,该查询结果会被抛弃。 - 如果给出了STRICT选项,除非该查询刚好产生一行,否则将会报告一个错误。 + 如果给出了STRICT选项,除非该命令刚好产生一行,否则将会报告一个错误。 - 命令字符串可以使用参数值,它们在命令中用$1$2等引用。这些符号引用在USING子句中提供的值。这种方法常常更适合于把数据值作为文本插入到命令字符串中:它避免了将该值转换为文本以及转换回来的运行时负荷,并且它更不容易被 SQL 注入攻击,因为不需要引用或转义。一个示例是: + 命令字符串可以使用参数值,它们在命令中用$1$2等引用。这些符号引用在USING子句中提供的值。这种方法通常比把数据值作为文本插入命令字符串更可取:它避免了将该值转换为文本以及转换回来的运行时负荷,并且它更不容易被 SQL 注入攻击,因为不需要引用或转义。一个示例是: EXECUTE 'SELECT count(*) FROM mytable WHERE inserted_by = $1 AND inserted <= $2' INTO c @@ -959,25 +956,25 @@ EXECUTE 'SELECT count(*) FROM ' USING checked_user, checked_date; 一种更干净的方法是使用format()的 - %I规范,插入自带引号的表名或者列名: + %I 格式说明符,插入表名或列名并自动为其加上引号: EXECUTE format('SELECT count(*) FROM %I ' 'WHERE inserted_by = $1 AND inserted <= $2', tabname) INTO c USING checked_user, checked_date; - (此示例依赖于隐式连接由换行符分隔的字符串文字的 SQL 规则) + (此示例依赖于隐式连接由换行符分隔的字符串字面量的 SQL 规则) 参数符号的另一个限制是它们仅适用于可优化的SQL命令 (SELECT, INSERT, UPDATE, DELETE, MERGE以及包含其中一个的某些命令)。 - 在其他语句类型(通称为实用程序语句)中,即使它们只是数据值,您也必须以文本方式插入值。 + 在其他语句类型(通称为工具语句)中,即使它们只是数据值,你也必须以文本方式插入值。 - 在上面第一个示例中,带有一个简单的常量命令字符串和一些USING参数的EXECUTE命令在功能上等效于直接用PL/pgSQL写的命令,并且允许自动发生PL/pgSQL变量替换。重要的不同之处在于,EXECUTE会在每一次执行时根据当前的参数值重新计划该命令,而PL/pgSQL则是创建一个通用计划并且将其缓存以便重用。在最佳计划强依赖于参数值的情况中,使用EXECUTE来明确地保证不会选择一个通用计划是很有帮助的。 + 在上面第一个示例中,带有一个简单的常量命令字符串和一些USING参数的EXECUTE命令在功能上等效于直接用PL/pgSQL写的命令,并且允许自动发生PL/pgSQL变量替换。重要的不同之处在于,EXECUTE会在每一次执行时根据当前的参数值重新计划该命令,而PL/pgSQL则可能创建一个通用计划并且将其缓存以便重用。在最佳计划强依赖于参数值的情况中,使用EXECUTE来明确地保证不会选择一个通用计划是很有帮助的。 @@ -986,9 +983,7 @@ EXECUTE format('SELECT count(*) FROM %I ' - - PL/pgSQL中的EXECUTE语句与EXECUTE PostgreSQL服务器支持的 SQL 语句无关。服务器的EXECUTE语句不能直接在PL/pgSQL函数中使用(并且也没有必要)。 - + PL/pgSQLEXECUTE 语句与 PostgreSQL 服务器支持的 SQL EXECUTE 语句无关。服务器的 EXECUTE 语句不能直接用于 PL/pgSQL 函数中(也没有这个必要)。 @@ -1052,19 +1047,19 @@ EXECUTE 'UPDATE tbl SET ' || ' WHERE key = ' || quote_nullable(keyvalue); - 如果正在处理的参数值可能为空,那么通常应该用quote_nullable来代替quote_literal。 + 如果正在处理的参数值可能为空值,那么通常应该用quote_nullable来代替quote_literal - 通常,必须小心地确保查询中的空值不会递送意料之外的结果。例如如果keyvalue为空,下面的WHERE子句 + 通常,必须小心地确保查询中的空值不会产生意料之外的结果。例如如果keyvalue为空值,下面的WHERE子句 'WHERE key = ' || quote_nullable(keyvalue) - 永远不会成功,因为在=操作符中使用空操作数得到的结果总是为空。如果想让空和一个普通键值一样工作,你应该将上面的命令重写成 + 永远不会成功,因为在=操作符中使用空值操作数得到的结果总是空值。如果想让空值像普通键值一样工作,你应该将上面的命令重写成 'WHERE key IS NOT DISTINCT FROM ' || quote_nullable(keyvalue) - (目前,IS NOT DISTINCT FROM的处理效率不如=,因此只有在非常必要时才这样做。关于空和IS DISTINCT的详细信息请见)。 + (目前,IS NOT DISTINCT FROM的处理效率不如=,因此只有在非常必要时才这样做。关于空值和IS DISTINCT的详细信息请见)。 @@ -1077,7 +1072,7 @@ EXECUTE 'UPDATE tbl SET ' || '$$ WHERE key = ' || quote_literal(keyvalue); - 因为如果newvalue的内容碰巧含有$$,那么这段代码就会出问题。同样的缺点可能适用于你选择的任何其他美元符号引用定界符。因此,要想安全地引用事先不知道的文本,必须恰当地使用quote_literalquote_nullablequote_ident。 + 因为如果newvalue的内容碰巧含有$$,那么这段代码就会出问题。同样的问题也适用于你选择的任何其他美元符号引用定界符。因此,要想安全地引用事先不知道的文本,必须恰当地使用quote_literalquote_nullablequote_ident @@ -1116,7 +1111,7 @@ EXECUTE format('UPDATE tbl SET %I = $1 WHERE key = $2', colname) GET CURRENT DIAGNOSTICS variable { = | := } item , ... ; - 这条命令允许检索系统状态指示符。CURRENT是一个噪声词(另见中的GET STACKED DIAGNOSTICS)。每个item是一个关键字, 它标识一个要被赋予给指定变量的状态值(变量应具有正确的数据类型来接收状态值)。中展示了当前可用的状态项。冒号等号(:=)可以被用来取代 SQL 标准的=符号。例如: + 这条命令允许检索系统状态指示符。CURRENT是一个噪声词(另见中的GET STACKED DIAGNOSTICS)。每个item是一个关键字, 它标识一个要被赋予给指定variable的状态值(变量应具有正确的数据类型来接收状态值)。中展示了当前可用的状态项。冒号等号(:=)可以被用来取代 SQL 标准的=符号。例如: GET DIAGNOSTICS integer_var = ROW_COUNT; @@ -1161,13 +1156,13 @@ GET DIAGNOSTICS integer_var = ROW_COUNT; 第二种确定命令效果的方法是检查名为FOUND的特殊变量,类型为boolean。 - 在每次PL/pgSQL函数调用中,FOUND都是以 false 开头。 + 在每次PL/pgSQL函数调用中,FOUND的初始值都是 false。 它由以下类型的语句设置: - SELECT INTO语句在分配行时将FOUND设置为true, + SELECT INTO语句在为目标赋上一行值时将FOUND设置为true, 如果没有返回行则设置为false。 @@ -1199,7 +1194,7 @@ GET DIAGNOSTICS integer_var = ROW_COUNT; FORFOREACH语句在迭代一次或多次时将 FOUND设置为true,否则设置为false。 - 当循环退出时,FOUND被设置为这种方式; + 当循环退出时,FOUND会按上述方式设置; 在循环执行过程中,FOUND不会被循环语句修改, 尽管它可能会被循环体内的其他语句执行修改。 @@ -1295,7 +1290,7 @@ RETURN expression; - 如果函数返回的是标量类型,表达式结果会自动转换为函数的返回类型。但如果要返回一个组合(行)值,你必须写出一个恰好生成所需列集合的表达式。这可能需要显式类型转换。 + 如果函数返回的是标量类型,表达式结果会按照赋值部分的说明自动转换为函数的返回类型。但如果要返回一个复合(行)值,你必须写出一个恰好生成所需列集合的表达式。这可能需要显式类型转换。 @@ -1307,7 +1302,7 @@ RETURN expression; - 一个函数的返回值不能是未定义。如果控制到达了函数最顶层的块而没有碰到一个RETURN语句,那么会发生一个运行时错误。不过,这个限制不适用于带输出参数的函数以及返回void的函数。在这些情况中,如果顶层的块结束,将自动执行一个RETURN语句。 + 一个函数的返回值不能是未定义。如果控制到达了函数最顶层块的末尾而没有碰到一个RETURN语句,那么会发生一个运行时错误。不过,这个限制不适用于带输出参数的函数以及返回void的函数。在这些情况中,如果顶层的块结束,将自动执行一个RETURN语句。 @@ -1331,12 +1326,12 @@ RETURN (1, 2, 'three'::text); -- 必须把列类型转换成正确的类型 RETURN NEXT - in PL/pgSQL + 在 PL/pgSQL 中 RETURN QUERY - in PL/pgSQL + 在 PL/pgSQL 中 @@ -1346,7 +1341,7 @@ RETURN QUERY EXECUTE command-string < - 当 PL/pgSQL 函数被声明为返回 SETOF sometype 时,返回过程会略有不同。在这种情况下,要返回的各个项通过一系列 RETURN NEXTRETURN QUERY 命令指定,最后再用一个不带参数的 RETURN 命令表明函数已经执行完毕。RETURN NEXT 可用于标量和组合数据类型;对于组合结果类型,会返回完整的结果RETURN QUERY 会把查询执行结果追加到函数的结果集中。在同一个集合返回函数中,RETURN NEXTRETURN QUERY 可以自由混用,此时它们的结果会被串接起来。 + 当 PL/pgSQL 函数被声明为返回 SETOF sometype 时,返回过程会略有不同。在这种情况下,要返回的各个项通过一系列 RETURN NEXTRETURN QUERY 命令指定,最后再用一个不带参数的 RETURN 命令表明函数已经执行完毕。RETURN NEXT 可用于标量和复合数据类型;对于复合结果类型,会返回完整的结果RETURN QUERY 会把查询执行结果追加到函数的结果集中。在同一个集合返回函数中,RETURN NEXTRETURN QUERY 可以自由混用,此时它们的结果会被串接起来。 @@ -1511,7 +1506,7 @@ END IF; - IF-THEN语句是IF的最简单形式。 如果条件为真,在THENEND IF之间的语句将被执行。否则,将忽略它们。 + IF-THEN语句是IF的最简单形式。 如果条件为真,在THENEND IF之间的语句将被执行。否则,将忽略它们。 @@ -1594,7 +1589,7 @@ ELSIF number > 0 THEN ELSIF number < 0 THEN result := 'negative'; ELSE - -- 嗯,唯一的其他可能性是数字为空 + -- 嗯,唯一的其他可能性是 number 为 null result := 'NULL'; END IF; @@ -1690,9 +1685,7 @@ END CASE; - - 这种形式的CASEIF-THEN-ELSIF完全等价,唯一的区别是:如果省略了ELSE子句,CASE会报错,而不是简单地什么也不做。 - + 这种形式的CASEIF-THEN-ELSIF完全等价,唯一的区别是:如果执行到被省略的ELSE子句,就会报错,而不是简单地什么也不做。 @@ -1702,12 +1695,12 @@ END CASE; 简单循环 - loop + 循环 在 PL/pgSQL 中 - 使用LOOPEXITCONTINUEWHILEFORFOREACH语句,你可以安排PL/pgSQL重复一系列命令。 + 使用LOOPEXITCONTINUEWHILEFORFOREACH语句,你可以安排PL/pgSQL函数重复一系列命令。 @@ -1862,22 +1855,22 @@ END LOOP label ; - 这种形式的FOR会创建一个在一个整数范围上迭代的循环。变量name会自动定义为类型integer并且只在循环内存在(任何该变量名的现有定义在此循环内都将被忽略)。给出范围上下界的两个表达式在进入循环的时候计算一次。如果没有指定BY子句,迭代步长为 1,否则步长是BY中指定的值,该值也只在循环进入时计算一次。如果指定了REVERSE,那么在每次迭代后步长值会被减除而不是增加。 + 这种形式的FOR会创建一个在一个整数范围上迭代的循环。变量name会自动定义为类型integer并且只在循环内存在(任何该变量名的现有定义在此循环内都将被忽略)。给出范围上下界的两个表达式在进入循环的时候计算一次。如果没有指定BY子句,迭代步长为 1,否则步长是BY中指定的值,该值也只在循环进入时计算一次。如果指定了REVERSE,那么在每次迭代后会减去步长,而不是加上步长。 整数FOR循环的一些示例: FOR i IN 1..10 LOOP - -- 我在循环中将取值 1,2,3,4,5,6,7,8,9,10 + -- i 在循环中将取值 1,2,3,4,5,6,7,8,9,10 END LOOP; FOR i IN REVERSE 10..1 LOOP - -- 我在循环中将取值 10,9,8,7,6,5,4,3,2,1 + -- i 在循环中将取值 10,9,8,7,6,5,4,3,2,1 END LOOP; FOR i IN REVERSE 10..1 BY 2 LOOP - -- 我在循环中将取值 10,8,6,4,2 + -- i 在循环中将取值 10,8,6,4,2 END LOOP; @@ -1941,7 +1934,7 @@ $$ LANGUAGE plpgsql; - 在这类 FOR 语句中使用的 query,可以是任何向调用者返回行的 SQL 命令:最常见的是 SELECT,但也可以是带 RETURNING 子句的 INSERTUPDATEDELETEMERGE。某些实用程序命令,如 EXPLAIN,也可以用于此处。 + 在这类 FOR 语句中使用的 query,可以是任何向调用者返回行的 SQL 命令:最常见的是 SELECT,但也可以是带 RETURNING 子句的 INSERTUPDATEDELETEMERGE。某些工具命令,如 EXPLAIN,也可以用于此处。 @@ -1956,7 +1949,7 @@ FOR target IN EXECUTE text_expressionstatements END LOOP label ; - 这个示例类似前面的形式,只不过源查询被指定为一个字符串表达式,在每次进入FOR循环时都会计算它并且重新计划。这允许程序员在一个预先计划好了的命令的速度和一个动态命令的灵活性之间进行选择,就像一个纯EXECUTE语句那样。在使用EXECUTE时,可以通过USING将参数值插入到动态命令中。 + 这个示例类似前面的形式,只不过源查询被指定为一个字符串表达式,在每次进入FOR循环时都会计算它并且重新计划。这允许程序员在一个预先计划好了的命令的速度和一个动态命令的灵活性之间进行选择,就像一个纯EXECUTE语句那样。与EXECUTE一样,可以通过USING将参数值插入到动态命令中。 @@ -1969,7 +1962,7 @@ END LOOP label ; 遍历数组 - FOREACH循环很像FOR循环,但它不是遍历 SQL 查询返回的行,而是遍历数组值的元素。(一般来说,FOREACH用于遍历组合值表达式的组成部分;未来还可能加入遍历数组以外其他组合值的变体。)用于遍历数组的FOREACH语句如下: + FOREACH循环很像FOR循环,但它不是遍历 SQL 查询返回的行,而是遍历数组值的元素。(一般来说,FOREACH用于遍历复合值表达式的组成部分;未来还可能加入遍历数组以外其他复合值的变体。)用于遍历数组的FOREACH语句如下: <<label>> @@ -1997,7 +1990,7 @@ END; $$ LANGUAGE plpgsql; - 元素会按存储顺序访问,而不管数组有多少维。尽管target通常只是单个变量,但在遍历组合值(记录)数组时,它也可以是一个变量列表。在这种情况下,每个数组元素都会按组合值的连续列给这些变量赋值。 + 元素会按存储顺序访问,而不管数组有多少维。尽管target通常只是单个变量,但在遍历复合值(记录)数组时,它也可以是一个变量列表。在这种情况下,每个数组元素都会按复合值的连续列给这些变量赋值。 @@ -2030,8 +2023,8 @@ NOTICE: row = {10,11,12} 捕获错误 - exceptions - in PL/pgSQL + 异常 + 在 PL/pgSQL 中 @@ -2054,7 +2047,7 @@ END; - 如果没有发生错误,这种形式的块只是简单地执行所有statements, 并且接着控制转到END之后的下一个语句。但是如果在statements内发生了一个错误,则会放弃对statements的进一步处理,然后控制会转到EXCEPTION列表。系统会在列表中寻找匹配所发生错误的第一个condition。如果找到一个匹配,则执行对应的handler_statements,并且接着把控制转到END之后的下一个语句。如果没有找到匹配,该错误就会传播出去,就好像根本没有EXCEPTION一样:错误可以被一个带有EXCEPTION的闭合块捕捉,如果没有EXCEPTION则中止该函数的处理。 + 如果没有发生错误,这种形式的块只是简单地执行所有statements, 并且接着控制转到END之后的下一个语句。但是如果在statements内发生了一个错误,则会放弃对statements的进一步处理,然后控制会转到EXCEPTION列表。系统会在列表中寻找匹配所发生错误的第一个condition。如果找到一个匹配,则执行对应的handler_statements,并且接着把控制转到END之后的下一个语句。如果没有找到匹配,该错误就会传播出去,就好像根本没有EXCEPTION一样:错误可以被一个带有EXCEPTION的外围块捕捉,如果没有这样的块则中止该函数的处理。 @@ -2091,7 +2084,7 @@ END; - 进入和退出一个包含EXCEPTION子句的块要比不包含EXCEPTION的块开销大的多。因此,只在必要的时候使用EXCEPTION。 + 进入和退出一个包含EXCEPTION子句的块要比不包含该子句的块开销大得多。因此,只在必要的时候使用EXCEPTION @@ -2118,9 +2111,9 @@ BEGIN IF found THEN RETURN; END IF; - -- 不在这里,那么尝试插入该键 + -- 该键不存在,因此尝试插入 -- 如果其他某人并发地插入同一个键, - -- 我们可能得到一个唯一键失败 + -- 就可能发生违反唯一约束的错误 BEGIN INSERT INTO db(a,b) VALUES (key, data); RETURN; @@ -2159,7 +2152,7 @@ SELECT merge_db(1, 'dennis'); GET STACKED DIAGNOSTICS variable { = | := } item , ... ; - 每个item是一个关键词,它标识一个被赋予给指定变量(应该具有接收该值的正确数据类型)的状态值。中显示了当前可用的状态项。 + 每个item是一个关键词,它标识一个被赋予给指定variable(应该具有接收该值的正确数据类型)的状态值。中显示了当前可用的状态项。
@@ -2271,7 +2264,7 @@ END; 获得执行位置信息 - GET DIAGNOSTICS(之前在中描述)命令检索有关当前执行状态的信息(反之上文讨论的GET STACKED DIAGNOSTICS命令会把有关执行状态的信息报告成一个以前的错误)。它的PG_CONTEXT状态项可用于标识当前执行位置。状态项PG_CONTEXT将返回一个文本字符串,其中有描述该调用栈的多行文本。第一行会指向当前函数以及当前正在执行GET DIAGNOSTICS的命令。第二行及其后的行表示调用栈中更上层的调用函数。例如: + GET DIAGNOSTICS(之前在中描述)命令检索有关当前执行状态的信息(反之上文讨论的GET STACKED DIAGNOSTICS命令报告先前发生错误时的执行状态信息)。它的PG_CONTEXT状态项可用于标识当前执行位置。状态项PG_CONTEXT将返回一个文本字符串,其中包含一行或多行描述该调用栈的文本。第一行会指向当前函数以及当前正在执行的GET DIAGNOSTICS命令。第二行及其后的行表示调用栈中更上层的调用函数。例如: CREATE OR REPLACE FUNCTION outer_func() RETURNS integer AS $$ @@ -2315,7 +2308,7 @@ CONTEXT: PL/pgSQL function outer_func() line 3 at RETURN 游标 - cursor + 游标 在 PL/pgSQL 中 @@ -2347,7 +2340,7 @@ DECLARE - 当游标查询使用 FOR UPDATE/SHARE 时,不能使用 SCROLL 选项。此外,对于涉及易失函数的查询,最好使用 NO SCROLLSCROLL 的实现假定重新读取查询输出会得到一致的结果,而易失函数并不满足这一假设。 + 当游标查询使用 FOR UPDATE/SHARE 时,不能使用 SCROLL 选项。此外,对于涉及易失函数的查询,最好使用 NO SCROLLSCROLL 的实现假定重新读取查询输出会得到一致的结果,而易失函数可能无法满足这一假设。 @@ -2372,7 +2365,7 @@ DECLARE - 打开游标会创建一个称为 portal 的服务器内部数据结构,它保存游标查询的执行状态。portal 具有一个名称,在其存在期间该名称在会话内必须唯一。默认情况下,PL/pgSQL 会为其创建的每个 portal 分配唯一名称。不过,如果你给游标变量赋一个非空字符串值,该字符串会被用作 portal 名称。这个特性可用于中描述的用法。 + 打开游标会创建一个称为 portal 的服务器内部数据结构,它保存游标查询的执行状态。portal 具有一个名称,在其存在期间该名称在会话内必须唯一。默认情况下,PL/pgSQL 会为其创建的每个 portal 分配唯一名称。不过,如果你给游标变量赋一个非 NULL 的字符串值,该字符串会被用作 portal 名称。这个特性可用于中描述的用法。 @@ -2497,7 +2490,7 @@ FETCH direction { FROM | IN } RELATIVE countFORWARD或者 BACKWARD。 - 省略direction和指定NEXT是一样的。在使用count的形式中,count可以是任意的整数值表达式(与SQL命令FETCH不一样,FETCH仅允许整数常量)。除非游标被使用SCROLL选项声明或打开,否则要求反向移动的direction值很可能会失败。 + 省略direction和指定NEXT是一样的。在使用count的形式中,count可以是任意的整数值表达式(与SQL命令FETCH不一样,后者仅允许整数常量)。除非游标被使用SCROLL选项声明或打开,否则要求反向移动的direction值很可能会失败。 @@ -2585,13 +2578,13 @@ CLOSE curs1; - 游标使用的 portal 名称既可以由程序员指定,也可以自动生成。要指定 portal 名称,只需在打开refcursor变量之前给它赋一个字符串值。OPEN会把该refcursor变量的字符串值用作底层 portal 的名称。不过,如果refcursor变量为 null,OPEN就会自动生成一个与任何现有 portal 都不冲突的名称,并把它赋回给refcursor变量。 + 游标使用的 portal 名称既可以由程序员指定,也可以自动生成。要指定 portal 名称,只需在打开refcursor变量之前给它赋一个字符串值。OPEN会把该refcursor变量的字符串值用作底层 portal 的名称。不过,如果refcursor变量为 null(这是默认值),OPEN就会自动生成一个与任何现有 portal 都不冲突的名称,并把它赋回给refcursor变量。 - 在 PostgreSQL 16 之前,已绑定游标变量会被初始化为其自身名称,而不是保持为空,因此默认情况下底层 portal 名称与游标变量名相同。之所以改动,是因为该行为在不同函数里同名游标之间带来了过高的名称冲突风险。 + 在 PostgreSQL 16 之前,已绑定游标变量会被初始化为其自身名称,而不是保持为 NULL,因此默认情况下底层 portal 名称与游标变量名相同。之所以改动,是因为该行为在不同函数里同名游标之间带来了过高的名称冲突风险。 @@ -2725,7 +2718,7 @@ CALL transaction_test1(); 连锁的事务 - 在 PL/pgSQL + 在 PL/pgSQL 中 @@ -2738,7 +2731,7 @@ CALL transaction_test1(); - PL/pgSQL 不支持保存点(SAVEPOINT/ROLLBACK TO SAVEPOINT/RELEASE SAVEPOINT)。保存点的典型用法可以用带异常处理器的代码块替代(见)。在内部,实现为带异常处理器的代码块会形成一个子事务,这意味着在这类代码块内部不能结束事务。 + PL/pgSQL 不支持保存点(SAVEPOINT/ROLLBACK TO SAVEPOINT/RELEASE SAVEPOINT)。保存点的典型用法可以用带异常处理器的代码块替代(见)。带异常处理器的代码块在内部会形成一个子事务,这意味着在这类代码块内部不能结束事务。 @@ -2785,28 +2778,17 @@ CALL transaction_test2(); 在 PL/pgSQL 中 - - 使用RAISE语句报告消息以及抛出错误。 - - + 使用RAISE语句报告消息和抛出错误。 RAISE level 'format' , expression , ... USING option = expression , ... ; RAISE level condition_name USING option = expression , ... ; RAISE level SQLSTATE 'sqlstate' USING option = expression , ... ; RAISE level USING option = expression , ... ; RAISE ; - - - level选项指定了错误的严重性。允许的级别有DEBUGLOGINFONOTICE, WARNING以及EXCEPTION,默认级别是EXCEPTIONEXCEPTION会抛出一个错误(通常会中止当前事务)。其他级别仅仅是产生不同优先级的消息。不管一个特定优先级的消息是被报告给客户端、还是写到服务器日志、亦或是二者同时都做,这都由配置变量控制。详见。 - +其中,level选项指定错误的严重程度。允许的级别为DEBUG, + LOGINFO, + NOTICEWARNING以及EXCEPTION,其中EXCEPTION是默认值。EXCEPTION会抛出错误(通常会中止当前事务);其他级别只会生成不同优先级的消息。特定优先级的消息是报告给客户端、写入服务器日志,还是两者都做,由配置变量控制。更多信息见中的说明。 - - 在level之后(如果有),可以指定一个format字符串 - (必须是一个简单的字符串文字,而不是一个表达式)。格式字符串指定要报告的错误消息文本。 - 格式字符串后跟要插入到消息中的可选参数表达式。 - 在格式字符串中,%将被下一个可选参数的值的字符串表示替换。写 - %%以发出一个字面上的%。 - 参数的数量必须与格式字符串中的%占位符的数量匹配,否则在函数编译期间会引发错误。 - + level(如果有)之后,可以指定一个format字符串(必须是简单的字符串字面量,不能是表达式)。格式字符串指定要报告的错误消息文本。格式字符串之后可以跟上可选的参数表达式,其值将被插入消息中。在格式字符串内,%会被替换为下一个可选参数值的字符串表示。写成%%可以输出一个字面的%。参数个数必须与格式字符串中%占位符的个数匹配,否则会在函数编译期间报错。 在这个示例中,v_job_id的值将替换字符串中的%: @@ -2815,10 +2797,10 @@ RAISE NOTICE 'Calling cs_create_job(%)', v_job_id; - - 都可以通过写一个后面跟着option = expression项的USING,为错误报告附加额外信息。每一个expression可以是任意字符串值的表达式。允许的option关键词是: - - + 可以为错误报告附加额外信息,方法是写出USING,后面跟上option = expression项目。每个expression都可以是任意字符串值表达式。允许的option关键字为: MESSAGE @@ -2829,7 +2811,7 @@ RAISE NOTICE 'Calling cs_create_job(%)', v_job_id; DETAIL - 提供一个错误的细节消息。 + 提供错误的详细信息。 @@ -2860,9 +2842,7 @@ RAISE NOTICE 'Calling cs_create_job(%)', v_job_id; - - 这个示例将用给定的错误消息和提示中止事务: - + 这个例子会中止事务,并给出指定的错误消息和提示: RAISE EXCEPTION 'Nonexistent ID --> %', user_id USING HINT = 'Please check your user ID'; @@ -2912,7 +2892,7 @@ RAISE unique_violation USING MESSAGE = 'Duplicate user ID: ' || user_id; - 当用 SQLSTATE 代码指定错误代码时,你并不受限于预定义错误代码,而是可以选择任何由五位数字和/或大写 ASCII 字母构成的错误代码,唯一不能使用的是 00000。我们建议尽量避免抛出以三个零结尾的错误代码,因为这些是类别代码,只能用于捕获整个类别。 + 当用 SQLSTATE 代码指定错误代码时,你并不受限于预定义错误代码,而是可以选择任何由五位数字和/或大写 ASCII 字母构成的错误代码,唯一不能使用的是 00000。我们建议尽量避免抛出以三个零结尾的错误代码,因为这些是类别代码,只能通过捕获整个类别来捕获这类错误。 @@ -2924,12 +2904,12 @@ RAISE unique_violation USING MESSAGE = 'Duplicate user ID: ' || user_id; ASSERT - in PL/pgSQL + 在 PL/pgSQL 中 - assertions - in PL/pgSQL + 断言 + 在 PL/pgSQL 中 @@ -2946,15 +2926,14 @@ ASSERT condition , condition是一个布尔 表达式,它被期望总是计算为真。如果确实如此, - ASSERT语句不会再做什么。但如果结果是假 - 或者空,那么将发生一个ASSERT_FAILURE异常(如果在计算 + ASSERT语句不会再做什么。但如果结果是假或者空值,那么将发生一个ASSERT_FAILURE异常(如果在计算 condition时发生错误, 它会被报告为一个普通错误)。 如果提供了可选的message, - 它是一个结果(如果非空)被用来替换默认错误消息文本 + 它是一个结果(如果不为 NULL)被用来替换默认错误消息文本 assertion failed的表达式(如果 condition失败)。 message表达式在 @@ -2987,7 +2966,7 @@ ASSERT condition , - PL/pgSQL可以被用来在数据更改或者数据库事件上定义触发器函数。触发器函数用CREATE FUNCTION命令创建,它被声明为一个没有参数并且返回类型为trigger(对于数据更改触发器)或者event_trigger(对于数据库事件触发器)的函数。名为PG_something的特殊局部变量将被自动创建用以描述触发该调用的条件。 + PL/pgSQL可以被用来在数据更改或者数据库事件上定义触发器函数。触发器函数用CREATE FUNCTION命令创建,它被声明为一个没有参数并且返回类型为trigger(对于数据更改触发器)或者event_trigger(对于数据库事件触发器)的函数。名为TG_something的特殊局部变量将被自动创建用以描述触发该调用的条件。 @@ -2998,10 +2977,7 @@ ASSERT condition , 数据更改触发器被声明为一个没有参数并且返回类型为trigger的函数。注意,如下所述,即便该函数准备接收一些在CREATE TRIGGER中指定的参数 — 这类参数通过TG_ARGV传递,也必须把它声明为没有参数。 - - 当一个PL/pgSQL函数当做触发器调用时,在顶层块会自动创建一些特殊变量。它们是: - - + 当一个PL/pgSQL函数作为触发器被调用时,会在顶层块中自动创建一些特殊变量。它们是: NEW record @@ -3121,11 +3097,11 @@ ASSERT condition , - INSTEAD OF触发器(总是行级触发器,并且可能只被用于视图)能够返回空来表示它们没有执行任何更新,并且对该行剩余的操作可以被跳过(即后续的触发器不会被引发,并且该行不会被计入外围INSERT/UPDATE/DELETE的行影响状态中)。否则一个非空值应该被返回用以表示该触发器执行了所请求的操作。对于INSERTUPDATE操作,返回值应该是NEW,触发器函数可能对它进行了修改来支持INSERT RETURNINGUPDATE RETURNING(这也将影响被传递给任何后续触发器的行值,或者被传递给带有ON CONFLICT DO UPDATEINSERT语句中一个特殊的EXCLUDED别名引用)。对于DELETE操作,返回值应该是OLD。 + INSTEAD OF触发器(总是行级触发器,并且只能用于视图)能够返回 null 来表示它们没有执行任何更新,并且对该行剩余的操作应被跳过(即后续的触发器不会被引发,并且该行不会被计入外围INSERT/UPDATE/DELETE的行影响状态中)。否则应该返回一个非 null 值用以表示该触发器执行了所请求的操作。对于INSERTUPDATE操作,返回值应该是NEW,触发器函数可能对它进行了修改来支持INSERT RETURNINGUPDATE RETURNING(这也将影响被传递给任何后续触发器的行值,或者被传递给带有ON CONFLICT DO UPDATEINSERT语句中一个特殊的EXCLUDED别名引用)。对于DELETE操作,返回值应该是OLD - 一个AFTER行级触发器或一个BEFOREAFTER语句级触发器的返回值总是会被忽略,它可能也是空。不过,任何这些类型的触发器可能仍会通过抛出一个错误来中止整个操作。 + 一个AFTER行级触发器或一个BEFOREAFTER语句级触发器的返回值总是会被忽略,因此也可以返回 null。不过,任何这些类型的触发器可能仍会通过抛出一个错误来中止整个操作。 @@ -3300,10 +3276,10 @@ INSTEAD OF INSERT OR UPDATE OR DELETE ON emp_view - 一个 <application>PL/pgSQL</application> 用于维护汇总表的触发器函数 + 一个用于维护汇总表的 <application>PL/pgSQL</application> 触发器函数 - 这里详述的模式有一部分是基于 Ralph Kimball 所作的数据仓工具包中的Grocery Store示例。 + 这里详述的模式有一部分是基于 Ralph Kimball 所作的数据仓库工具包中的Grocery Store示例。 @@ -3446,7 +3422,7 @@ SELECT * FROM sales_summary_bytime; 使用过渡表审计 - 这个示例产生和相同的结果,但并未使用一个为每一行都触发的触发器,而是在把相关信息收集到一个过渡表中之后用了一个只为每个语句引发一次的触发器。当调用语句修改了很多行时,这种方法明显比行触发器方法快。注意我们必须为每一种事件建立一个单独的触发器声明,因为每种情况的REFERENCING子句必须不同。但是这并不能阻止我们使用单一的触发器函数(实际上,使用三个单独的函数会更好,因为可以避免在TG_OP上的运行时测试)。 + 这个示例产生和相同的结果,但并未使用一个为每一行都触发的触发器,而是在把相关信息收集到一个过渡表中之后用了一个只为每个语句引发一次的触发器。当调用语句修改了很多行时,这种方法可能显著快于行触发器方法。注意我们必须为每一种事件建立一个单独的触发器声明,因为每种情况的REFERENCING子句必须不同。但是这并不能阻止我们使用单一的触发器函数(实际上,使用三个单独的函数可能会更好,因为可以避免在TG_OP上的运行时测试)。 @@ -3508,10 +3484,7 @@ CREATE TRIGGER emp_audit_del PL/pgSQL可以被用来定义事件触发器。PostgreSQL要求一个可以作为事件触发器调用的函数必须被声明为没有参数并且返回类型为event_trigger - - 当一个PL/pgSQL函数被作为一个事件触发器调用,在顶层块中会自动创建一些特殊变量。它们是: - - + 当一个PL/pgSQL函数作为事件触发器被调用时,会在顶层块中自动创建一些特殊变量。它们是: TG_EVENT text @@ -3562,9 +3535,7 @@ CREATE EVENT TRIGGER snitch ON ddl_command_start EXECUTE FUNCTION snitch(); <application>PL/pgSQL</application> 内部机制 - - 这一节讨论了一些PL/pgSQL用户应该知道的一些重要的实现细节。 - + 本节讨论一些实现细节,了解这些细节对 PL/pgSQL 用户通常很重要。 @@ -3642,7 +3613,7 @@ CREATE FUNCTION stamp_user(id int, comment text) RETURNS void AS $$ END; $$ LANGUAGE plpgsql; - 在UPDATE命令中,curtimecomment以及id将引用该函数的变量和参数,不管users有没有这些名称的列。注意,我们不得不在WHERE子句中对users.id的引用加以限定,以便让它引用表列。但是我们不需要在UPDATE列表中把对comment的引用限定为一个目标,因为语法上那必须是users的一列。我们可以用下面的方式写一个相同的不依赖于variable_conflict设置的函数: + 在UPDATE命令中,curtimecomment以及id将引用该函数的变量和参数,不管users有没有这些名称的列。注意,我们不得不在WHERE子句中对users.id的引用加以限定,以便让它引用表列。但是我们不需要对UPDATE列表中作为目标的comment引用加以限定,因为语法上那必须是users的一列。我们可以用下面的方式写一个相同的不依赖于variable_conflict设置的函数: CREATE FUNCTION stamp_user(id int, comment text) RETURNS void AS $$ <<fn>> @@ -3661,7 +3632,7 @@ $$ LANGUAGE plpgsql; - 目前,变量替换只在 SELECTINSERTUPDATEDELETEMERGE 以及包含其中之一的命令中生效(例如 EXPLAINCREATE TABLE ... AS SELECT),因为主 SQL 引擎只允许在这些命令中使用查询参数。若要在其他语句类型(统称为实用语句)中使用非常量名称或值,就必须把该实用语句构造为字符串,再用 EXECUTE 执行。 + 目前,变量替换只在 SELECTINSERTUPDATEDELETEMERGE 以及包含其中之一的命令中生效(例如 EXPLAINCREATE TABLE ... AS SELECT),因为主 SQL 引擎只允许在这些命令中使用查询参数。若要在其他语句类型(统称为工具语句)中使用非常量名称或值,就必须把该工具语句构造为字符串,再用 EXECUTE 执行。 @@ -3683,7 +3654,7 @@ $$ LANGUAGE plpgsql; - PL/pgSQL(更准确地说,是 SPI 管理器)还会尝试缓存与某个预备语句相关的执行计划。如果没有使用缓存计划,那么每次执行该语句时都会生成新的执行计划,而当前参数值(也就是 PL/pgSQL 变量值)可用于优化所选计划。如果该语句没有参数,或者会被执行很多次,SPI 管理器就会考虑创建一个不依赖具体参数值的通用计划,并将其缓存起来供重复使用。通常只有在执行计划对其中引用的 PL/pgSQL 变量值不太敏感时,才会这样做。如果执行计划对参数值非常敏感,那么每次重新生成计划总体上反而更划算。关于预备语句的行为,详见 。 + PL/pgSQL(更准确地说,是 SPI 管理器)还可以尝试缓存与某个预备语句相关的执行计划。如果没有使用缓存计划,那么每次执行该语句时都会生成新的执行计划,而当前参数值(也就是 PL/pgSQL 变量值)可用于优化所选计划。如果该语句没有参数,或者会被执行很多次,SPI 管理器就会考虑创建一个不依赖具体参数值的通用计划,并将其缓存起来供重复使用。通常只有在执行计划对其中引用的 PL/pgSQL 变量值不太敏感时,才会这样做。如果执行计划对参数值非常敏感,那么每次重新生成计划总体上反而更划算。关于预备语句的行为,详见 @@ -3732,7 +3703,7 @@ $$ LANGUAGE plpgsql; - 在logfunc2中,PostgreSQL的主解析器不知道应该把'now'解释成什么类型,因此返回一个text类型的数据值,其中包含字符串now。在确定对本地变量curtime的赋值时,PL/pgSQL解释器通过调用用于该转换的textouttimestamp_in函数,把这个字符串转换为timestamp类型。因此,计算得到的时间戳会按程序员预期在每次执行时更新。虽然这恰好能得到预期结果,但效率并不高,因此使用now()函数仍然是更好的主意。 + 在logfunc2中,PostgreSQL的主解析器不知道应该把'now'解释成什么类型,因此返回一个text类型的数据值,其中包含字符串now。在随后给局部变量curtime赋值时,PL/pgSQL解释器通过调用用于该转换的textouttimestamp_in函数,把这个字符串转换为timestamp类型。因此,计算得到的时间戳会按程序员预期在每次执行时更新。虽然这恰好能得到预期结果,但效率并不高,因此使用now()函数仍然是更好的主意。 @@ -3761,7 +3732,7 @@ $$ LANGUAGE plpgsql; - 另一种开发PL/pgSQL的好方法,是使用有助于过程语言开发的 GUI 数据库访问工具。这类工具的一个例子是pgAdmin,当然也有其他工具。它们通常提供一些方便的特性,例如转义单引号,以及让重新创建和调试函数变得更容易。 + 另一种使用PL/pgSQL进行开发的好方法,是使用有助于过程语言开发的 GUI 数据库访问工具。这类工具的一个例子是pgAdmin,当然也有其他工具。它们通常提供一些方便的特性,例如转义单引号,以及让重新创建和调试函数变得更容易。 @@ -3769,7 +3740,7 @@ $$ LANGUAGE plpgsql; 引号的处理 - 一个PL/pgSQL函数的代码在一个CREATE FUNCTION中被指定为一个字符串。如果你用通常的方式把该字符串写在单引号中间,那么该函数体中的任何单引号都必须被双写;同样任何反斜线也必须被双写(假定使用了转义字符串语法)。双写引号最多有点冗长,并且在更复杂的情况中代码会变得完全无法理解,因为你很容易发现你需要半打或者更多相邻的引号。我们推荐你转而把函数体写成一个美元引用的字符串(见)。在美元引用方法中,你从不需要双写任何引号。但是要注意为你需要的每一层嵌套选择一个不同的美元引用定界符。例如,你可能把CREATE FUNCTION命令写成: + 一个PL/pgSQL函数的代码在一个CREATE FUNCTION中被指定为一个字符串字面量。如果你用通常的方式把该字符串写在单引号中间,那么该函数体中的任何单引号都必须被双写;同样任何反斜线也必须被双写(假定使用了转义字符串语法)。双写引号本身就很繁琐,并且在更复杂的情况中代码会变得完全无法理解,因为你很容易发现你需要半打或者更多相邻的引号。我们推荐你转而把函数体写成一个美元引用的字符串(见)。在美元引用方法中,你从不需要双写任何引号。但是要注意为你需要的每一层嵌套选择一个不同的美元引用定界符。例如,你可能把CREATE FUNCTION命令写成: CREATE OR REPLACE FUNCTION testfunc(integer) RETURNS integer AS $PROC$ .... @@ -3806,7 +3777,7 @@ CREATE FUNCTION foo() RETURNS integer AS ' - 用于函数体内的字符串,例如: + 用于函数体内的字符串字面量,例如: a_output := ''Blah''; SELECT * FROM users WHERE f_name=''foobar''; @@ -3816,7 +3787,7 @@ SELECT * FROM users WHERE f_name=''foobar''; a_output := 'Blah'; SELECT * FROM users WHERE f_name='foobar'; - 这恰好就是PL/pgSQL在两种情况中会看到的。 + 这恰好就是PL/pgSQL解析器在两种情况中会看到的。 @@ -3839,7 +3810,7 @@ a_output := a_output || '' AND name LIKE ''''foobar'''' AND xyz'' a_output := a_output || $$ AND name LIKE 'foobar' AND xyz$$ - 要小心在这周围的任何美元引用定界符不只是$$。 + 要小心在这周围的任何美元引用定界符都不能是$$ @@ -3872,7 +3843,7 @@ a_output := a_output || $$ AND name LIKE 'foobar'$$ - 当你想在一个字符串常量(占 8 个引号)中有两个单引号时并且这会挨着该字符串常量的末尾(另外 2 个)。如果你正在写一个产生其他函数的函数(如中),你将很可能只需要这种。例如: + 当字符串常量中需要两个单引号(这需要 8 个引号),而且它们紧邻该字符串常量的末尾(还需 2 个引号)时。通常只有在编写生成其他函数的函数时(如所示),才会需要这种写法。例如: a_output := a_output || '' if v_'' || referrer_keys.kind || '' like '''''''''' @@ -3914,9 +3885,7 @@ a_output := a_output || $$ if v_$$ || referrer_keys.kind || $$ like '$$ 因此建议你在一个单独的开发环境中进行测试。 - - 根据需要设置 plpgsql.extra_warningsplpgsql.extra_errors,适当情况下,在开发和/或测试环境中可以设置为 "all"。 - + 建议在开发和/或测试环境中,根据需要将 plpgsql.extra_warningsplpgsql.extra_errors 设置为 "all" 这些额外的检查通过配置变量plpgsql.extra_warnings来启用警告, @@ -4030,18 +3999,16 @@ HINT: Make sure the query returns the exact list of columns. - PL/pgSQL与 PL/SQL 在许多方面都非常类似。它是一种块结构的、命令式的语言并且所有变量必须先被声明。赋值、循环和条件则很类似。在从PL/SQLPL/pgSQL移植时必须记住一些事情: - - + PL/pgSQL在许多方面都与 PL/SQL 类似。它是一种具有块结构的命令式语言,所有变量都必须声明。赋值、循环和条件语句也都很相似。在从PL/SQL移植到PL/pgSQL时,应当记住以下主要差异: - 如果一个 SQL 命令中使用的名字可能是一个表的列名或者是对一个函数中变量的引用,那么PL/SQL会将它当作一个列名。默认情况下, PL/pgSQL会抛出名称模糊的错误, 你可以指定plpgsql.variable_conflict=use_column来改变这一行为以匹配PL/SQL。如中所述。通常最好是首先避免这种歧义,但如果不得不移植依赖于该行为的大量代码,那么设置variable_conflict将是最好的方案。 + 如果一个 SQL 命令中使用的名字可能是一个表的列名或者是对一个函数中变量的引用,那么PL/SQL会将它当作一个列名。默认情况下, PL/pgSQL会抛出名称有歧义的错误, 你可以指定plpgsql.variable_conflict=use_column来改变这一行为以匹配PL/SQL。如中所述。通常最好是首先避免这种歧义,但如果不得不移植依赖于该行为的大量代码,那么设置variable_conflict可能是最好的方案。 - 在PostgreSQL中,函数体必须写成字符串文本。因此你需要使用美元符引用或者转义函数体中的单引号(见)。 + 在PostgreSQL中,函数体必须写成字符串字面量。因此你需要使用美元符引用或者转义函数体中的单引号(见)。 @@ -4131,13 +4098,13 @@ show errors; - 在PostgreSQL中,函数体被认为是一个字符串,所以你需要使用引号或者美元符号包围它。这代替了Oracle 方法中的用于终止的/。 + 在PostgreSQL中,函数体被认为是一个字符串字面量,所以你需要使用引号或者美元引用定界符包围它。这代替了Oracle 方法中的用于终止的/ - 在PostgreSQL中没有show errors命令, 并且也不需要这个命令,因为错误是自动报告的。 + 在PostgreSQL中没有show errors命令, 并且也不需要这个命令,因为错误是自动报告的。 @@ -4169,9 +4136,7 @@ $$ LANGUAGE plpgsql; 从<application>PL/SQL</application>移植一个创建另一个函数的函数到<application>PL/pgSQL</application> - - 下面的过程从一个SELECT语句抓取行,并且为了效率而构建一个带有IF语句中结果的大型函数。 - + 下面的过程从 SELECT 语句读取行,并将结果写入 IF 语句,从而构造一个大型函数,以提高效率。 这是 Oracle 版本: @@ -4202,8 +4167,7 @@ show errors; - - 这里是PostgreSQL的版本: + 下面是这个函数的最终移植结果,目标数据库为PostgreSQL CREATE OR REPLACE PROCEDURE cs_update_referrer_type_proc() AS $func$ DECLARE @@ -4236,9 +4200,7 @@ BEGIN EXECUTE func_cmd; END; $func$ LANGUAGE plpgsql; - - 请注意,这里先单独构造了函数体,再通过 quote_literal 传入,以便把其中的引号正确双写。之所以需要这种技术,是因为我们无法安全地使用美元引用来定义新函数:我们并不确切知道会从 referrer_key.key_string 字段插入什么字符串。(这里假定 referrer_key.kind 始终可信地只会是 hostdomainurl,但 referrer_key.key_string 可能是任意内容,尤其可能包含美元符号。)实际上,这个函数比 Oracle 原版还有改进,因为当 referrer_key.key_stringreferrer_key.referrer_type 中包含引号时,它也不会生成无效代码。 - +注意,这里单独构造函数体,然后将其传给quote_literal,使其中的每个引号都变成两个。这种技术是必需的,因为不能安全地使用美元引用来定义新函数:我们无法确定会插入什么字符串,其来源是referrer_key.key_string字段。(这里假定referrer_key.kind可信,其值总是hostdomainurl,但是referrer_key.key_string可能是任何内容,尤其可能包含美元符号。)这个函数实际上改进了 Oracle 原版:当referrer_key.key_stringreferrer_key.referrer_type中包含引号时,它也不会生成有问题的代码。 @@ -4258,7 +4220,7 @@ $func$ LANGUAGE plpgsql; CREATE OR REPLACE PROCEDURE cs_parse_url( v_url IN VARCHAR2, - v_host OUT VARCHAR2, -- 这将被传回去 + v_host OUT VARCHAR2, -- 这个值将被返回 v_path OUT VARCHAR2, -- 这个也是 v_query OUT VARCHAR2) -- 还有这个 IS @@ -4301,9 +4263,9 @@ show errors; CREATE OR REPLACE FUNCTION cs_parse_url( v_url IN VARCHAR, - v_host OUT VARCHAR, -- 这将被传递回去 + v_host OUT VARCHAR, -- 这个值将被返回 v_path OUT VARCHAR, -- 这个也是 - v_query OUT VARCHAR) -- 以及这个 + v_query OUT VARCHAR) -- 还有这个 AS $$ DECLARE a_pos1 INTEGER; @@ -4346,7 +4308,7 @@ SELECT * FROM cs_parse_url('http://foobar.com/query.cgi?baz'); - 展示了如何移植一个使用了多种 Oracle 特性的过程。 + 展示了如何移植一个使用了多种 Oracle 专属特性的过程。 @@ -4386,7 +4348,7 @@ show errors - 这是我们如何将这个过程移植到PL/pgSQL: + 下面展示了如何将这个过程移植到PL/pgSQL CREATE OR REPLACE PROCEDURE cs_create_job(v_job_id integer) AS $$ @@ -4461,7 +4423,7 @@ EXCEPTION END; - 如果你正在移植一个以这种方式使用SAVEPOINTROLLBACK TO的 Oracle 过程,工作会比较简单:只要忽略SAVEPOINTROLLBACK TO即可。如果你的 Oracle 过程以不同方式使用SAVEPOINTROLLBACK TO,那就需要认真思考了。 + 如果你正在移植一个以这种方式使用SAVEPOINTROLLBACK TO的 Oracle 过程,工作会比较简单:只要省略SAVEPOINTROLLBACK TO即可。如果你的 Oracle 过程以不同方式使用SAVEPOINTROLLBACK TO,那就需要认真思考了。 @@ -4478,11 +4440,11 @@ END; 优化 <application>PL/pgSQL</application> 函数 - PostgreSQL提供了两种函数创建修饰符来优化执行:volatility(对于给定的相同参数,函数是否总是返回相同的结果)以及strictness (如果任何参数为空,函数是否返回空)。详见参考页。 + PostgreSQL提供了两种函数创建修饰符来优化执行:volatility(对于给定的相同参数,函数是否总是返回相同的结果)以及strictness (如果任何参数为空值,函数是否返回空值)。详见参考页。 - 在利用这些优化属性时,你的CREATE FUNCTION语句应该看起来像这样: + 在利用这些优化属性时,你的CREATE FUNCTION语句可能像这样: CREATE FUNCTION foo(...) RETURNS integer AS $$ diff --git a/zh/17/plpython.sgml b/zh/17/plpython.sgml index 25d33332..19a3c11b 100644 --- a/zh/17/plpython.sgml +++ b/zh/17/plpython.sgml @@ -45,7 +45,7 @@ CREATE FUNCTION funcname (argument-list) RETURNS return-type AS $$ - # PL/Python function body + # PL/Python 函数体 $$ LANGUAGE plpython3u; @@ -85,7 +85,7 @@ def __plpython_procedure_pymax_23456(): CREATE FUNCTION pystrip(x text) RETURNS text AS $$ - x = x.strip() # error + x = x.strip() # 错误 return x $$ LANGUAGE plpython3u; @@ -95,7 +95,7 @@ CREATE FUNCTION pystrip(x text) RETURNS text AS $$ global x - x = x.strip() # ok now + x = x.strip() # 现在可以正常工作 return x $$ LANGUAGE plpython3u; @@ -216,7 +216,7 @@ $$ LANGUAGE plpython3u; 如果把 SQL 空值空值在 PL/Python 中传给函数,参数值在 Python 中会显示为None。例如,中展示的pymax定义在处理空输入时就会返回错误结果。我们可以在函数定义中添加STRICT,让PostgreSQL做出更合理的处理:如果传入空值,函数根本不会被调用,而是自动返回空结果。另一种办法是在函数体中检查空输入: + sortas="PL/Python">在 PL/Python 中传给函数,参数值在 Python 中会显示为None。例如,中展示的pymax定义在处理空值输入时就会返回错误结果。我们可以在函数定义中添加STRICT,让PostgreSQL做出更合理的处理:如果传入空值,函数根本不会被调用,而是自动返回空值结果。另一种办法是在函数体中检查空值输入: CREATE FUNCTION pymax (a integer, b integer) @@ -329,21 +329,21 @@ CREATE TYPE named_value AS ( ); - 组合结果可以按以下形式返回: + 复合结果可以按以下形式返回: 序列类型(元组或列表,但不能是集合,因为集合不可通过索引访问) - 返回的序列对象必须包含与组合结果类型字段数相同的项。索引为 0 的项会赋给复合类型的第一个字段,索引为 1 的项赋给第二个字段,依此类推。例如: + 返回的序列对象必须包含与复合结果类型字段数相同的项。索引为 0 的项会赋给复合类型的第一个字段,索引为 1 的项赋给第二个字段,依此类推。例如: CREATE FUNCTION make_pair (name text, value integer) RETURNS named_value AS $$ return ( name, value ) - # or alternatively, as list: return [ name, value ] + # 也可以使用列表: return [ name, value ] $$ LANGUAGE plpython3u; @@ -391,7 +391,7 @@ AS $$ self.value = v return named_value(name, value) - # or simply + # 或者简写为 class nv: pass nv.name = name nv.value = value @@ -452,8 +452,8 @@ CREATE TYPE greeting AS ( CREATE FUNCTION greet (how text) RETURNS SETOF greeting AS $$ - # return tuple containing lists as composite types - # all other combinations work also + # 返回包含列表的元组,以列表表示复合类型 + # 其他组合方式也都可用 return ( [ how, "World" ], [ how, "PostgreSQL" ], [ how, "PL/Python" ] ) $$ LANGUAGE plpython3u; @@ -511,7 +511,7 @@ $$ LANGUAGE plpython3u; - 也支持带OUT参数的返回集函数(使用RETURNS SETOF record)。例如: + 也支持带OUT参数的集合返回函数(使用RETURNS SETOF record)。例如: CREATE FUNCTION multiout_simple_setof(n integer, OUT integer, OUT integer) RETURNS SETOF record AS $$ return [(1, 2)] * n @@ -546,7 +546,7 @@ SELECT * FROM multiout_simple_setof(3); DO $$ - # PL/Python code + # PL/Python 代码 $$ LANGUAGE plpython3u; @@ -795,7 +795,7 @@ CREATE FUNCTION usesavedplan() RETURNS trigger AS $$ else: plan = plpy.prepare("SELECT 1") SD["plan"] = plan - # rest of function + # 函数的其余部分 $$ LANGUAGE plpython3u; @@ -812,11 +812,11 @@ $$ LANGUAGE plpython3u; - 游标对象提供fetch方法,它接受一个整数参数并返回结果对象。每次调用fetch,返回对象都会包含下一批行,数量不会超过该参数值。一旦所有行都已取完,fetch就会开始返回空结果对象。游标对象还提供迭代器接口,每次产生一行,直到所有行为止。以这种方式获取的数据不会作为结果对象返回,而是以字典形式返回,每个字典对应一行结果。 + 游标对象提供fetch方法,它接受一个整数参数并返回结果对象。每次调用fetch,返回对象都会包含下一批行,数量不会超过该参数值。一旦所有行都已取完,fetch就会开始返回空结果对象。游标对象还提供迭代器接口,每次产生一行,直到取完所有行。以这种方式获取的数据不会作为结果对象返回,而是以字典形式返回,每个字典对应一行结果。 - 下面示例展示了如何处理大表中的数据: + 下面示例展示了处理大表中数据的两种方式: CREATE FUNCTION count_odd_iterator() RETURNS integer AS $$ odd = 0 @@ -842,7 +842,7 @@ $$ LANGUAGE plpython3u; CREATE FUNCTION count_odd_prepared() RETURNS integer AS $$ odd = 0 plan = plpy.prepare("select num from largetable where num % $1 <> 0", ["integer"]) -rows = list(plpy.cursor(plan, [2])) # or: = list(plan.cursor([2])) +rows = list(plpy.cursor(plan, [2])) # 或者:= list(plan.cursor([2])) return len(rows) $$ LANGUAGE plpython3u; @@ -995,7 +995,7 @@ CALL transaction_test1(); - 实用函数 + 辅助函数 plpy模块还提供以下函数: @@ -1049,7 +1049,7 @@ PL/Python function "raise_custom_exception" - 另一组实用函数是plpy.quote_literal(string)plpy.quote_nullable(string)以及plpy.quote_ident(string)。它们等价于中描述的内置引用函数。在构造临时查询时,这些函数很有用。中动态 SQL 的一个 PL/Python 等价写法如下: + 另一组辅助函数是plpy.quote_literal(string)plpy.quote_nullable(string)以及plpy.quote_ident(string)。它们等价于中描述的内置加引号函数。在构造临时查询时,这些函数很有用。中动态 SQL 的一个 PL/Python 等价写法如下: plpy.execute("UPDATE tbl SET %s = %s WHERE key = %s" % ( plpy.quote_ident(colname), diff --git a/zh/17/pltcl.sgml b/zh/17/pltcl.sgml index 78e190a3..2c682c9d 100644 --- a/zh/17/pltcl.sgml +++ b/zh/17/pltcl.sgml @@ -13,7 +13,7 @@ - PL/Tcl 是一种适用于 PostgreSQL 数据库系统的可载入的过程语言,它允许使用 Tcl 语言 来编写 PostgreSQL 函数和过程。 + PL/Tcl 是一种适用于 PostgreSQL 数据库系统的可加载的过程语言,它允许使用 Tcl 语言 来编写 PostgreSQL 函数和过程。 @@ -54,7 +54,7 @@ CREATE FUNCTION funcname (argument-types) RETURNS return-type AS $$ - # PL/Tcl function body + # PL/Tcl 函数体 $$ LANGUAGE pltcl; @@ -75,11 +75,11 @@ CREATE FUNCTION tcl_max(integer, integer) RETURNS integer AS $$ $$ LANGUAGE pltcl STRICT; - 注意STRICT子句,它让我们不必考虑空输入值:如果传入的是空值,函数根本不会被调用,而是会自动返回空结果。 + 注意STRICT子句,它让我们不必考虑空值输入:如果传入的是空值,函数根本不会被调用,而是会自动返回空值结果。 - 在非严格函数中,如果某个参数的实际值为空,对应的$n变量会被设置为空串。要检测某个特定参数是否为空,可使用函数argisnull。例如,假设我们希望在tcl_max的两个参数中一个为空、一个非空时返回非空参数,而不是返回空值: + 在非严格函数中,如果某个参数的实际值为空值,对应的$n变量会被设置为空串。要检测某个特定参数是否为空值,可使用函数argisnull。例如,假设我们希望在tcl_max的两个参数中一个为空值、一个非空值时返回非空值参数,而不是返回空值: CREATE FUNCTION tcl_max(integer, integer) RETURNS integer AS $$ @@ -99,7 +99,7 @@ $$ LANGUAGE pltcl; - 复合类型参数会作为 Tcl 数组传递给函数。数组元素名就是该复合类型的属性名。如果传入行中的某个属性为 NULL,它就不会出现在数组中。下面是一个示例: + 复合类型参数会作为 Tcl 数组传递给函数。数组元素名就是该复合类型的属性名。如果传入行中的某个属性为空值,它就不会出现在数组中。下面是一个示例: CREATE TABLE employee ( @@ -185,7 +185,7 @@ $$ LANGUAGE pltcl; PL/Tcl 中的数据值 - 提供给 PL/Tcl 函数代码的参数值,只是将输入参数转换成文本形式(就像用SELECT语句将它们显示出来一样)。反过来,returnreturn_next命令会接受任何字符串,只要它是该函数声明结果类型或组合结果类型中指定列的可接受输入格式。 + 提供给 PL/Tcl 函数代码的参数值,只是将输入参数转换成文本形式(就像用SELECT语句将它们显示出来一样)。反过来,returnreturn_next命令会接受任何字符串,只要它是该函数声明结果类型或复合结果类型中指定列的可接受输入格式。 @@ -195,8 +195,8 @@ $$ LANGUAGE pltcl; PL/Tcl 中的全局数据 - global data - in PL/Tcl + 全局数据 + 在 PL/Tcl 中 @@ -234,7 +234,7 @@ $$ LANGUAGE pltcl; - 执行以字符串形式给出的 SQL 命令。命令出错时会引发错误。否则,spi_exec的返回值是该命令处理的行数(选出、插入、更新或删除的行),如果命令是实用程序语句则返回零。此外,如果命令是SELECT语句,则所选列的值会按下文所述放入 Tcl 变量中。 + 执行以字符串形式给出的 SQL 命令。命令出错时会引发错误。否则,spi_exec的返回值是该命令处理的行数(选出、插入、更新或删除的行),如果命令是工具语句则返回零。此外,如果命令是SELECT语句,则所选列的值会按下文所述放入 Tcl 变量中。 @@ -275,7 +275,7 @@ spi_exec -array C "SELECT * FROM pg_class" { - 如果查询结果中的某一列为空,则对应的目标变量会被unset,而不是被设值。 + 如果查询结果中的某一列为空值,则对应的目标变量会被unset,而不是被设值。 @@ -287,7 +287,7 @@ spi_exec -array C "SELECT * FROM pg_class" { 准备并保存一个查询计划以供后续执行。保存的计划会在当前会话的整个生命周期内保留。 准备查询 - 在PL/Tcl中 + 在 PL/Tcl 中 @@ -317,7 +317,7 @@ spi_exec -array C "SELECT * FROM pg_class" { 可选的-nulls值是由空格和'n'字符组成的字符串,用来告诉spi_execp哪些参数是空值。 - 如果给出,它的长度必须与value-list完全相同。如果未给出,则所有参数值都视为非空。 + 如果给出,它的长度必须与value-list完全相同。如果未给出,则所有参数值都视为非空值。 @@ -331,7 +331,7 @@ spi_exec -array C "SELECT * FROM pg_class" { CREATE FUNCTION t1_count(integer, integer) RETURNS integer AS $$ if {![ info exists GD(plan) ]} { - # prepare the saved plan on the first call + # 在首次调用时准备并保存计划 set GD(plan) [ spi_prepare \ "SELECT count(*) AS cnt FROM t1 WHERE num >= \$1 AND num <= \$2" \ [ list int4 int4 ] ] @@ -367,7 +367,7 @@ $$ LANGUAGE pltcl; 将给定字符串中的所有单引号和反斜杠字符都加倍。 - 这可用于安全地引用那些要插入到传给spi_execspi_prepare的 SQL 命令中的字符串。 + 这可用于安全地为那些要插入到传给spi_execspi_prepare的 SQL 命令中的字符串加引号。 例如,考虑如下 SQL 命令字符串: @@ -393,7 +393,7 @@ SELECT 'doesn''t' AS ret "SELECT '[ quote $val ]' AS ret" - spi_execp的一个优点是,你不必像这样对参数值做引用,因为这些参数永远不会作为 SQL 命令字符串的一部分被解析。 + spi_execp的一个优点是,你不必像这样给参数值加引号,因为这些参数永远不会作为 SQL 命令字符串的一部分被解析。 @@ -404,7 +404,7 @@ SELECT 'doesn''t' AS ret elog level msg elog - 在PL/Tcl中 + 在 PL/Tcl 中 @@ -436,8 +436,8 @@ SELECT 'doesn''t' AS ret PL/Tcl 中的触发器函数 - trigger - in PL/Tcl + 触发器 + 在 PL/Tcl 中 @@ -525,7 +525,7 @@ SELECT 'doesn''t' AS ret $NEW - 对于INSERTUPDATE动作,这是一个包含新表行值的关联数组;对于DELETE则为空。该数组以列名为索引。值为 NULL 的列不会出现在数组中。对于语句级触发器,不会设置这个变量。 + 对于INSERTUPDATE动作,这是一个包含新表行值的关联数组;对于DELETE则为空。该数组以列名为索引。值为空值的列不会出现在数组中。对于语句级触发器,不会设置这个变量。 @@ -534,7 +534,7 @@ SELECT 'doesn''t' AS ret $OLD - 对于UPDATEDELETE动作,这是一个包含旧表行值的关联数组;对于INSERT则为空。该数组以列名为索引。值为 NULL 的列不会出现在数组中。对于语句级触发器,不会设置这个变量。 + 对于UPDATEDELETE动作,这是一个包含旧表行值的关联数组;对于INSERT则为空。该数组以列名为索引。值为空值的列不会出现在数组中。对于语句级触发器,不会设置这个变量。 @@ -598,8 +598,8 @@ CREATE TRIGGER trig_mytab_modcount BEFORE INSERT OR UPDATE ON mytab PL/Tcl 中的事件触发器函数 - event trigger - in PL/Tcl + 事件触发器 + 在 PL/Tcl 中 @@ -615,7 +615,7 @@ CREATE TRIGGER trig_mytab_modcount BEFORE INSERT OR UPDATE ON mytab $TG_event - 触发器因其而被触发的事件名称。 + 该触发器所针对的事件名称。 @@ -624,7 +624,7 @@ CREATE TRIGGER trig_mytab_modcount BEFORE INSERT OR UPDATE ON mytab $TG_tag - 触发器因其而被触发的命令标签。 + 该触发器所针对的命令标签。 @@ -632,7 +632,7 @@ CREATE TRIGGER trig_mytab_modcount BEFORE INSERT OR UPDATE ON mytab - 事件触发器函数的返回值会被忽略。 + 触发器函数的返回值会被忽略。 @@ -653,8 +653,8 @@ CREATE EVENT TRIGGER tcl_a_snitch ON ddl_command_start EXECUTE FUNCTION tclsnitc PL/Tcl 中的错误处理 - exceptions - in PL/Tcl + 异常 + 在 PL/Tcl 中 @@ -682,9 +682,9 @@ if {[catch { spi_exec $sql_command }]} { if {[lindex $::errorCode 0] == "POSTGRES"} { array set errorArray $::errorCode if {$errorArray(condition) == "undefined_table"} { - # deal with missing table + # 处理表不存在的情况 } else { - # deal with some other type of SQL error + # 处理其他类型的 SQL 错误 } } } @@ -698,8 +698,8 @@ if {[catch { spi_exec $sql_command }]} { PL/Tcl 中的显式子事务 - subtransactions - in PL/Tcl + 子事务 + 在 PL/Tcl 中 @@ -797,7 +797,7 @@ CALL transaction_test1(); pltcl.start_proc (string) - pltcl.start_proc configuration parameter + pltcl.start_proc 配置参数 @@ -825,7 +825,7 @@ CALL transaction_test1(); pltclu.start_proc (string) - pltclu.start_proc configuration parameter + pltclu.start_proc 配置参数 diff --git a/zh/17/postgres-fdw.sgml b/zh/17/postgres-fdw.sgml index 236b91a1..a08f992b 100644 --- a/zh/17/postgres-fdw.sgml +++ b/zh/17/postgres-fdw.sgml @@ -38,7 +38,7 @@ - 对于每个需要被允许访问各外部服务器的数据库用户,使用 + 对于每个需要获准访问各个外部服务器的数据库用户,使用 创建用户映射。将要使用的 远程用户名和密码指定为用户映射的 userpassword 选项。 @@ -56,7 +56,7 @@ - 现在,只需从外部表执行 SELECT,即可访问其底层远程表中 + 现在,只需对外部表执行 SELECT,即可访问其底层远程表中 存储的数据。也可以使用 INSERTUPDATEDELETECOPYTRUNCATE 修改远程表。 @@ -70,6 +70,17 @@ + + 请注意,postgres_fdw 当前不支持带有 + ON CONFLICT DO UPDATE 子句的 + INSERT 语句。不过,在省略唯一索引推断规范的前提下,支持 + ON CONFLICT DO NOTHING 子句。 + 还要注意,postgres_fdw 支持在分区表上执行的 + UPDATE 语句所引发的行移动,但当前尚不能处理这样一种情况: + 为插入被移动行而选择的远程分区,同时也是同一命令中其他位置将被更新的 + UPDATE 目标分区。 + + 通常建议将外部表的列声明为与被引用远程表的对应列具有完全相同的数据类型, 并在适用时具有相同的排序规则。尽管 postgres_fdw @@ -110,8 +121,7 @@ application_name 可以出现在连接选项和 - 中的任一处,或同时出现在 - 二者中。 + 中的任一处,或同时出现在二者中。 如果两者都存在,postgres_fdw.application_name 会覆盖连接设置。与 libpq 不同, postgres_fdw 允许 application_name @@ -162,7 +172,8 @@ OPTIONS (ADD password_required 'false'); password_required=false。还要记住,被映射用户可能 使用 postgres 服务器所运行的系统用户 unix 主目录中的任何客户端证书、 .pgpass.pg_service.conf - 等文件。 他们还可以利用通过 peerident + 等文件。 + 他们还可以利用通过 peerident 等认证方式授予的任何信任关系。 @@ -239,7 +250,7 @@ OPTIONS (ADD password_required 'false'); - fdw_startup_cost (floating point) + fdw_startup_cost (浮点数) 该选项可为外部服务器指定,是一个浮点值,会被加到该服务器上任何 @@ -250,7 +261,7 @@ OPTIONS (ADD password_required 'false'); - fdw_tuple_cost (floating point) + fdw_tuple_cost (浮点数) 该选项可为外部服务器指定,是一个浮点值,用作该服务器上外部表扫描的 @@ -328,7 +339,7 @@ OPTIONS (ADD password_required 'false'); 该选项是一个以逗号分隔的 PostgreSQL 扩展 名称列表,这些扩展必须在本地和远程服务器上都已安装且版本兼容。 - 属于列出扩展且为 immutable 的函数和操作符,将被视为可下推到远程服务器 + 属于列出扩展且不可变的函数和操作符,将被视为可下推到远程服务器 执行。该选项只能为外部服务器指定,不能按表指定。 @@ -370,7 +381,7 @@ OPTIONS (ADD password_required 'false'); - 该选项也适用于向外部表执行 COPY。在这种情况下, + 该选项也适用于向外部表复制数据。在这种情况下, postgres_fdw 实际一次复制的行数会以与插入场景 类似的方式确定,但由于 COPY 命令的实现限制, 最多只能为 1000 行。 @@ -562,8 +573,7 @@ OPTIONS (ADD password_required 'false'); COLLATE 选项。默认值为 true。 如果远程服务器的排序规则名称集合与本地服务器不同,则可能需要关闭此 选项;如果远程服务器运行在不同操作系统上,这种情况尤其可能发生。 - 不过,如果这样做,导入表列的排序规则极有可能与底层数据不匹配, - 从而导致查询行为异常。 + 不过,如果这样做,导入表列的排序规则就存在与底层数据不匹配的严重风险,从而导致查询行为异常。 @@ -769,8 +779,7 @@ postgres=# SELECT postgres_fdw_disconnect_all(); - 请注意,postgres_fdw 当前不支持将远程事务预备为 - 两阶段提交。 + 请注意,postgres_fdw 当前不支持为两阶段提交预备远程事务。 @@ -781,9 +790,9 @@ postgres=# SELECT postgres_fdw_disconnect_all(); postgres_fdw 会尽力优化远程查询,以减少从外部 服务器传输的数据量。这是通过将查询的 WHERE 子句发送到 远程服务器执行,以及不获取当前查询不需要的表列来实现的。为降低查询被 - 错误执行的风险,除非 WHERE 子句仅使用内置数据类型、 - 操作符和函数,或属于外部服务器 extensions 选项列出的 - 扩展,否则不会将其发送到远程服务器。这类子句中的操作符和函数还必须是 + 错误执行的风险,只有当 WHERE 子句使用的所有数据类型、 + 操作符和函数都是内置的,或属于外部服务器 extensions + 选项列出的扩展时,才会将该子句发送到远程服务器。这类子句中的操作符和函数还必须是 IMMUTABLE。对于 UPDATEDELETE 查询,postgres_fdw 会在 查询中不存在无法发送到远程服务器的 WHERE 子句、没有 @@ -939,7 +948,7 @@ postgres=# SELECT postgres_fdw_disconnect_all(); postgres_fdw.application_name 可以是任意长度的任意 字符串,甚至可以包含非 ASCII 字符。不过,当它被传递并作为外部服务器中 的 application_name 使用时,请注意它会被截断到少于 - NAMEDATALEN 个字符。所有不可打印 ASCII 字符都会被 + NAMEDATALEN 个字符。除可打印 ASCII 字符以外的所有字符都会被 替换为C 风格的十六进制转义。 有关细节见 。 @@ -993,7 +1002,7 @@ postgres=# SELECT postgres_fdw_disconnect_all(); %% - 字面值 % + 字面字符 % diff --git a/zh/17/protocol.sgml b/zh/17/protocol.sgml index 4d7912f7..f28ff9c9 100644 --- a/zh/17/protocol.sgml +++ b/zh/17/protocol.sgml @@ -171,11 +171,7 @@ 前端现在必须发送一个 PasswordMessage,其中包含密码;该密码先与用户名一起经过 MD5 加密,再使用 AuthenticationMD5Password 消息中指定的 4 字节随机盐重新加密。如果密码正确,服务器响应 AuthenticationOk;否则响应 ErrorResponse。实际的 PasswordMessage 可以用 SQL 计算:concat('md5', md5(concat(md5(concat(password, username)), random-salt)))。(请记住 md5() 函数返回的是十六进制字符串。) - - - 对 MD5 加密密码的支持已弃用,并将在未来版本 PostgreSQL 中移除。关于迁移到其他密码类型,请参阅 。 - - + @@ -777,7 +773,7 @@ SELCT 1/0; - 目前,系统会为以下参数发送 ParameterStatus: + 目前,会为一组固定的参数生成 ParameterStatus,参数如下: application_name client_encoding @@ -788,17 +784,14 @@ SELCT 1/0; IntervalStyle is_superuser scram_iterations - search_path server_encoding server_version session_authorization standard_conforming_strings TimeZone - (default_transaction_read_onlyin_hot_standby 在 14 之前不报告; - scram_iterations 在 16 之前不报告; - search_path 在 18 之前不报告。) - 注意 server_versionserver_encodinginteger_datetimes 是启动后不可更改的伪参数。未来该集合可能变化,甚至可能变为可配置。因此,前端应忽略其不理解或不关心的 ParameterStatus。 + (14 之前的版本不报告 default_transaction_read_onlyin_hot_standby;16 之前的版本不报告 scram_iterations。) + 注意,server_versionserver_encodinginteger_datetimes 是启动后不能改变的伪参数。这组参数将来可能变化,甚至可能变为可配置。因此,前端应直接忽略其不理解或不关心的参数的 ParameterStatus。 @@ -1249,7 +1242,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" CREATE_REPLICATION_SLOT slot_name [ TEMPORARY ] { PHYSICAL | LOGICAL output_plugin } [ ( option [, ...] ) ] - 创建复制槽 + CREATE_REPLICATION_SLOT @@ -1306,15 +1299,6 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - - FAILOVER [ boolean ] - - - 若为 true,则该复制槽会同步到备库,从而在故障切换后恢复逻辑复制。默认值为 false。 - - - - RESERVE_WAL [ boolean ] @@ -1331,13 +1315,14 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" SNAPSHOT { 'export' | 'use' | 'nothing' } - - 决定在逻辑复制槽初始化期间如何处理所创建的快照。'export' - 这是默认选项,将导出快照供其他会话使用。此选项不能在事务内使用。 - 'use'将为执行命令的当前事务使用快照。此选项必须在事务中使用, - 并且CREATE_REPLICATION_SLOT必须是在该事务中运行的第一个命令。 - 最后,'nothing'将像往常一样仅用于逻辑解码使用快照,但不会执行其他操作。 - + 决定如何处理初始化逻辑复制槽时创建的快照。默认选项 'export' 会导出快照供其他会话使用,此选项不能在事务内使用。'use' 会将快照用于执行该命令的当前事务;此选项必须在事务内使用,且 CREATE_REPLICATION_SLOT 必须是该事务中执行的第一条命令。最后,'nothing' 只会像平常一样将快照用于逻辑解码,不会对其执行其他操作。 + + + + + FAILOVER [ boolean ] + + 若为 true,则允许该复制槽同步到备库,以便在故障切换后恢复逻辑复制。默认值为 false。 @@ -1368,7 +1353,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" snapshot_name (text) - 该命令导出的快照标识符。该快照在此连接上执行下一条命令之前,或复制连接关闭之前有效。如果所创建的是物理复制槽,则为 null。 + 该命令导出的快照标识符。该快照在此连接上执行下一条命令之前,或复制连接关闭之前有效。如果所创建的是物理复制槽,则为空值。 @@ -1377,7 +1362,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" output_plugin (text) - 新建复制槽所使用的输出插件名称。如果所创建的是物理复制槽,则为 null。 + 新建复制槽所使用的输出插件名称。如果所创建的是物理复制槽,则为空值。 @@ -1931,7 +1916,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 指示服务器开始流式传输基本备份。 + 指示服务器开始流式传输基础备份。 在备份开始之前,系统将自动进入备份模式,并在备份完成后退出备份模式。 接受以下选项: @@ -1942,7 +1927,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" 设置备份的标签。如果未指定,则将使用base backup作为备份标签。 - 标签的引用规则与打开的标准SQL字符串相同。 + 标签的引号使用规则与打开的标准SQL字符串相同。 @@ -1982,11 +1967,11 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 如果设置为true,则请求生成进度报告所需的信息。这将在每个表空间的头部发送一个近似大小, + 如果设置为true,则请求生成进度报告所需的信息。这将在每个表空间的首部发送一个近似大小, 可用于计算流式传输的进度。这是通过在传输开始之前先枚举所有文件大小来计算的, 可能会对性能产生负面影响。特别是,在流式传输数据之前可能需要更长的时间。 由于备份期间数据库文件可能会发生变化,因此大小仅为近似值, - 在近似值和实际文件发送之间可能会增长或缩小。默认值为false。 + 在估算与实际发送文件之间的这段时间里可能会增长或缩小。默认值为false。 @@ -1996,7 +1981,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 设置在基本备份开始时执行的检查点类型。默认值为spread。 + 设置在基础备份开始时执行的检查点类型。默认值为spread @@ -2005,9 +1990,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" WAL [ boolean ] - - 如果设置为true,则在备份中包含必要的WAL段。这将包括在开始和停止备份之间的所有文件在基本目录tar文件的pg_wal目录中。默认值为false。 - + 如果设置为 true,则在备份中包含必要的 WAL 段。这会把开始备份到停止备份之间的所有文件放入基础目录 tar 文件内的pg_wal目录中。默认值为 false。 @@ -2095,7 +2078,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 如果为true,则在进行基本备份时验证校验和(如果已启用)。如果为false,则跳过此步骤。默认值为true。 + 如果为true,则在进行基础备份时验证校验和(如果已启用)。如果为false,则跳过此步骤。默认值为true。 @@ -2110,7 +2093,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" 除了可能包含的任何WAL文件。它还存储每个文件的大小、最后修改时间, 以及可选的校验和。 值为force-encode会强制对所有文件名进行十六进制编码; - 否则,仅对文件名为非UTF8八位序列的文件执行此类型的编码。 + 否则,仅对文件名为非 UTF8 字节序列的文件执行此类型的编码。 force-encode主要用于测试目的,以确保读取备份清单的客户端 能够处理这种情况。为了与之前的版本兼容,默认值为MANIFEST 'no' @@ -2152,14 +2135,14 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" 第二个普通结果集中的每个表空间都有一行。 - 这一行中的字段是: + 这一行中的字段是: spcoid (oid) - 表空间的OID,如果是基本目录则为null。 + 表空间的OID,如果是基础目录则为null。 @@ -2168,7 +2151,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" spclocation (text) - 表空间目录的完整路径,如果是基本目录则为null。 + 表空间目录的完整路径,如果是基础目录则为null。 @@ -2192,7 +2175,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - new archive (B) + 新归档 (B) @@ -2224,7 +2207,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 对于主数据目录,使用空字符串。对于其他表空间,使用从创建此归档的目录的完整路径。 + 对于主数据目录,使用空字符串。对于其他表空间,使用创建此归档所用目录的完整路径。 @@ -2234,7 +2217,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - manifest (B) + 清单 (B) @@ -2283,7 +2266,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - progress report (B) + 进度报告 (B) @@ -2341,13 +2324,11 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - - 不记录 WAL 的关系(Unlogged表),除了需要在恢复时重新创建(空的)不记录 WAL 的关系的init fork。 - + 不记录 WAL 的关系,但不包括恢复时重新创建(空的)不记录 WAL 的关系所需的初始化分支。 - pg_wal,包括子目录。如果备份包含WAL文件,则将包含pg_wal的合成版本,但它只包含备份工作所需的文件,而不包含其余内容。 + pg_wal,包括子目录。如果备份包含WAL文件,则将包含pg_wal的合成版本,但它只包含使备份可用所需的文件,而不包含其余内容。 @@ -2360,7 +2341,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 除了常规文件和目录之外的文件,如符号链接(除了上述列出的目录之外的符号链接)以及特殊设备和操作系统文件,将被跳过。(pg_tblspc中的符号链接将被保留。) + 除了普通文件和目录之外的文件,如符号链接(除了上述列出的目录之外的符号链接)以及特殊设备和操作系统文件,将被跳过。(pg_tblspc中的符号链接将被保留。) @@ -2393,7 +2374,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 逻辑复制参数 + 逻辑流复制参数 使用 START_REPLICATION 命令时,pgoutput 接受以下选项: @@ -2408,13 +2389,13 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" 协议版本。目前支持的版本有 1234。必须指定一个有效版本。 - 版本2仅支持服务器版本14及以上,并允许流式传输大型进行中的事务。 + 版本 2 仅在服务器版本 14 及以上受支持,允许流式传输正在进行的大型事务。 - 版本3仅支持服务器版本15及以上,并允许流式传输两阶段提交。 + 版本 3 仅在服务器版本 15 及以上受支持,允许流式传输两阶段提交。 - 版本4仅支持服务器版本 16 及以上,并允许对大型进行中事务的流进行并行应用。 + 版本 4 仅在服务器版本 16 及以上受支持,允许并行应用正在进行的大型事务的流。 @@ -2425,8 +2406,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 用于订阅(接收更改)的发布名称的逗号分隔列表。各个发布名称按标准对象名处理,可按需加引号。 - 至少需要一个发布名称。 + 要订阅(接收变更)的发布名称列表,以逗号分隔。各个发布名称按标准对象名处理,可按需加引号。至少需要一个发布名称。 @@ -2437,7 +2417,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 使用二进制传输模式的布尔选项。二进制模式比文本模式更快,但略微不够稳健。 + 使用二进制传输模式的布尔选项。二进制模式比文本模式更快,但稳健性略差。 @@ -2448,7 +2428,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 一个布尔选项,用于启用发送由 pg_logical_emit_message 写入的消息。 + 布尔选项,用于启用发送由 pg_logical_emit_message 写入的消息。 @@ -2488,9 +2468,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - - 在上述命令中,若参数类型为 boolean,可省略 value 部分;省略等同于指定 TRUE。 - + @@ -3337,58 +3315,45 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - CancelRequest (F) - - Int32 + Int32(16) - - 消息内容的长度(以字节为单位),包括其自身。 + 消息内容的长度,以字节为单位,包括此长度字段本身。 - Int32(80877102) - - 取消请求代码。该值被选择为在最高的16位中包含1234,在最低的16位中包含5678。 - (为避免混淆,此代码不得与任何协议版本号相同。) + 取消请求代码。此值的最高 16 位为 1234,最低 16 位为 5678。(为避免混淆,此代码不能与任何协议版本号相同。) - Int32 - - 目标后端的进程ID。 + 目标后端的进程 ID。 - Int32 - - 目标后端的 secret key。该字段长度由消息总长度决定并延伸至消息末尾,最大长度为 256 字节。 + 目标后端的密钥。 - - secret key 为 4 字节。 - @@ -5468,7 +5433,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 严重性: 字段内容为ERROR, FATAL, 或 + 严重性: 字段内容为ERROR, FATAL, 或 PANIC (在错误消息中), 或 WARNING, NOTICE, DEBUG, INFO, 或 LOG (在通知消息中), @@ -5482,7 +5447,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 严重性:字段内容为ERRORFATAL或 + 严重性:字段内容为ERRORFATALPANIC(在错误消息中),或WARNINGNOTICEDEBUGINFOLOG(在通知消息中)。 这与S字段相同,只是内容不会被本地化。仅在由PostgreSQL版本9.6 @@ -5506,7 +5471,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 消息: 主要的人类可读错误消息。 + 消息: 主要的人类可读错误消息。 这应该准确但简洁(通常一行)。 总是存在。 @@ -5528,7 +5493,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 提示: 关于问题应该怎么做的一个可选建议。 + 提示: 关于问题应该怎么做的一个可选建议。 这意在与细节不同,它提供建议(可能不合适)而不是硬性事实。 可能会跨越多行。 @@ -5562,7 +5527,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 内部查询: 一个失败的内部生成命令的文本。 + 内部查询: 一个失败的内部生成命令的文本。 例如,这可能是由PL/pgSQL函数发出的SQL查询。 @@ -5595,7 +5560,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 表名: 如果错误与特定表相关联,则为表的名称。(有关表模式名称的名称,请参考模式名称字段。) + 表名: 如果错误与特定表相关联,则为表的名称。(有关表模式名称的名称,请参考模式名称字段。) @@ -5605,7 +5570,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 列名: 如果错误与特定表列相关联,则为列的名称。(请参考模式和表名字段以识别表。) + 列名: 如果错误与特定表列相关联,则为列的名称。(请参考模式和表名字段以识别表。) @@ -5615,7 +5580,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 数据类型名称: 如果错误与特定数据类型相关联,则为数据类型的名称。 + 数据类型名称: 如果错误与特定数据类型相关联,则为数据类型的名称。 (有关数据类型模式的名称,请参阅模式名称字段。) @@ -5626,7 +5591,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 约束名称: 如果错误与特定约束相关联,则为约束的名称。请参考上面列出的字段,了解相关表或域。 + 约束名称: 如果错误与特定约束相关联,则为约束的名称。请参考上面列出的字段,了解相关表或域。 (为此,即使索引不是使用约束语法创建的,也将其视为约束。) @@ -5637,7 +5602,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 文件: 报告错误的源代码位置的文件名。 + 文件: 报告错误的源代码位置的文件名。 @@ -5775,7 +5740,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 标志; 逻辑解码消息是非事务性的时为0,是事务性的时为1。 + 标志; 逻辑解码消息是非事务性的时为0,是事务性的时为1。 @@ -5849,7 +5814,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 标志; 目前未使用。 + 标志; 目前未使用。 @@ -6547,7 +6512,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 标志; 目前未使用。 + 标志; 目前未使用。 @@ -6625,6 +6590,27 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" + + Int64 (XLogRecPtr) + + + 中止操作的 LSN,仅当 streaming 设置为 parallel 时出现。 + 此字段从协议版本 4 起可用。 + + + + + + Int64 (TimestampTz) + + + 事务的中止时间戳,仅当 streaming 设置为 parallel 时出现。 + 该值为自 PostgreSQL 纪元(2000-01-01)以来的微秒数。 + 此字段从协议版本 4 起可用。 + + + + @@ -6731,7 +6717,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 标志; 目前未使用。 + 标志; 目前未使用。 @@ -6816,7 +6802,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 标志; 目前未使用。 + 标志; 目前未使用。 @@ -6901,7 +6887,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 标志; 目前未使用。 + 标志; 目前未使用。 @@ -6997,7 +6983,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 标志; 目前未使用。 + 标志; 目前未使用。 @@ -7157,76 +7143,36 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 自协议2.0以来的变化总结 + 自协议 2.0 以来的变更总结 - 本节为那些试图将现有客户端库更新到协议3.0的开发人员提供了一个快速变更清单。 + 本节提供一份简要的变更清单,供准备将现有客户端库更新到协议 3.0 的开发者参考。 - - 初始启动数据包使用灵活的字符串列表格式,而不是固定格式。请注意,现在可以直接在启动数据包中指定运行时参数的会话默认值。 - (实际上,以前可以使用options字段来做到这一点,但考虑到options的有限宽度以及缺乏引用值中空格的任何方法,这并不是一种非常安全的技术。) - + 初始启动包采用灵活的字符串列表格式,取代了固定格式。注意,运行时参数的会话默认值现在可以直接在启动包中指定。(实际上,以前也能通过 options 字段实现,但由于 options 的宽度有限,且无法用引号保护值中的空白字符,这种方法并不稳妥。) - - 所有消息现在都在消息类型字节后面立即跟着长度计数(除了启动数据包,它们没有类型字节)。另外请注意,PasswordMessage现在有一个类型字节。 - + 现在,所有消息都在消息类型字节之后紧跟一个长度计数(启动包除外,它没有类型字节)。另请注意,PasswordMessage 现在也有类型字节。 - - ErrorResponse和NoticeResponse('E'和'N') - 消息现在包含多个字段,客户端代码可以从中组装出所需级别的错误消息。请注意, - 单个字段通常不会以换行符结尾,而在旧协议中发送的单个字符串总是以换行符结尾。 - + ErrorResponse 和 NoticeResponse('E' 和 'N')消息现在包含多个字段,客户端代码可以利用这些字段组合出所需详细程度的错误消息。注意,各字段通常不会以换行符结束,而旧协议发送的单个字符串总是以换行符结束。 - - ReadyForQuery('Z')消息包括事务状态指示器。 - + ReadyForQuery('Z')消息包含一个事务状态指示器。 - - 二进制行和数据行消息类型之间的区别已经消失;单个数据行消息类型用于以所有格式返回数据。 - 请注意,DataRow的布局已更改,以使其更容易解析。 - 此外,二进制值的表示已更改:它不再直接与服务器的内部表示形式绑定。 - + BinaryRow 与 DataRow 消息类型不再有区别;单一的 DataRow 消息类型用于返回所有格式的数据。注意,DataRow 的布局已经改变,使其更容易解析。另外,二进制值的表示方式也已改变,不再直接取决于服务器内部的表示方式。 - - 有一个新的扩展查询子协议,它增加了前端消息类型Parse、Bind、Execute、Describe、Close、Flush和Sync, - 以及后端消息类型ParseComplete、BindComplete、PortalSuspended、ParameterDescription、NoData和CloseComplete。 - 现有客户端不必关心这个子协议,但利用它可能会提高性能或功能。 - + 新增了扩展查询子协议,其中增加了前端消息类型 Parse、Bind、Execute、Describe、Close、Flush 和 Sync,以及后端消息类型 ParseComplete、BindComplete、PortalSuspended、ParameterDescription、NoData 和 CloseComplete。现有客户端不必关注这个子协议,但使用它可能有助于改善性能或功能。 - - COPY数据现在封装到CopyData和CopyDone消息中。在COPY期间有一种明确定义的错误恢复方式。 - 特殊的\.最后一行不再需要,并且在COPY OUT期间不发送。 - (在文本模式的COPY IN期间仍然被识别为终止符,但在CSV模式中不会被识别。文本模式中的这种行为已弃用,并且最终可能会被移除。)支持二进制COPY。 - CopyInResponse和CopyOutResponse消息包括指示列数和每列格式的字段。 - + COPY 数据现在封装在 CopyData 和 CopyDone 消息中。COPY 期间的错误恢复已有明确定义的方法。不再需要特殊的最后一行 \.COPY OUT 期间也不再发送它。(在 COPY IN 期间仍会将它识别为终止符,但这种用法已弃用,最终将被移除。)现已支持二进制 COPY。CopyInResponse 和 CopyOutResponse 消息包含了表示列数及各列格式的字段。 - - FunctionCall和FunctionCallResponse消息的布局已更改。 - FunctionCall现在可以支持将NULL参数传递给函数。它还可以处理以文本或二进制格式传递参数和检索结果。 - 不再需要考虑FunctionCall可能存在安全漏洞,因为它不提供对内部服务器数据表示的直接访问。 - + FunctionCall 和 FunctionCallResponse 消息的布局已经改变。FunctionCall 现在支持向函数传递 NULL 参数,也可以使用文本或二进制格式传递参数和取得结果。由于它不再提供对服务器内部数据表示的直接访问,因此也不再有理由将 FunctionCall 视为潜在的安全漏洞。 - - 后端在连接启动期间向客户端库发送ParameterStatus('S')消息,以传达其认为对客户端库有趣的所有参数。 - 随后,每当这些参数中任何一个的活动值发生变化时,都会发送ParameterStatus消息。 - + 在连接启动期间,后端会为其认为客户端库关注的所有参数发送 ParameterStatus('S')消息。之后,只要这些参数中任何一个的当前值发生变化,就会发送一条 ParameterStatus 消息。 - - RowDescription('T')消息携带了描述行的每列的新表OID和列号字段。它还显示了每列的格式代码。 - + RowDescription('T')消息针对所描述行中的每一列,增加了表 OID 和列编号字段,并显示各列的格式代码。 - - CursorResponse('P')消息不再由后端生成。 - + 后端不再生成 CursorResponse('P')消息。 - - NotificationResponse('A')消息有一个额外的字符串字段,可以携带一个有效负载字符串, - 从NOTIFY事件发送者传递过来。 - + NotificationResponse('A')消息增加了一个字符串字段,可以携带 NOTIFY 事件发送者传来的载荷字符串。 - - EmptyQueryResponse('I')消息曾包含一个空字符串参数;现已移除。 - + EmptyQueryResponse('I')消息以前包含一个空字符串参数,现在已将其移除。 diff --git a/zh/17/queries.sgml b/zh/17/queries.sgml index 49ad3b90..7a419d4c 100644 --- a/zh/17/queries.sgml +++ b/zh/17/queries.sgml @@ -512,7 +512,7 @@ FROM (VALUES ('anne', 'smith'), ('bob', 'jones'), ('joe', 'blow')) - 表函数是那些生成行集合的函数,这些行可以由基本数据类型(标量类型)组成,也可以由复合数据类型(表行)组成。它们在查询的FROM子句中用法类似于表、视图或子查询。表函数返回的列可以像表、视图或子查询的列一样,出现在SELECTJOINWHERE子句中。 + 表函数是那些生成行集合的函数,这些行可以由基础类型(标量类型)组成,也可以由复合数据类型(表行)组成。它们在查询的FROM子句中用法类似于表、视图或子查询。表函数返回的列可以像表、视图或子查询的列一样,出现在SELECTJOINWHERE子句中。 @@ -550,7 +550,7 @@ UNNEST( array_expression , ... - 如果没有提供列的别名,那么对于一个返回基数据类型的函数,列名也与该函数 + 如果没有提供列的别名,那么对于一个返回基础类型的函数,列名也与该函数 名相同。对于一个返回复合类型的函数,结果列会从该类型的属性得到名称。 diff --git a/zh/17/rangetypes.sgml b/zh/17/rangetypes.sgml index f60e0af7..68409fa3 100644 --- a/zh/17/rangetypes.sgml +++ b/zh/17/rangetypes.sgml @@ -209,7 +209,7 @@ SELECT '{[3,7), [8,9)}'::int4multirange; 构造范围和多范围 - 每种范围类型都有一个与范围类型同名的构造函数。使用构造函数通常比书写范围文字常量更方便,因为这样无需对界限值进行额外引用。构造函数接受两个或三个参数。两个参数的形式构造标准形式的范围(下界包含,上界排除),而三个参数的形式则按第三个参数指定的界限形式构造范围。第三个参数必须是下列字符串之一: + 每种范围类型都有一个与范围类型同名的构造函数。使用构造函数通常比书写范围字面量更方便,因为这样无需为界限值额外加引号。构造函数接受两个或三个参数。两个参数的形式构造标准形式的范围(下界包含,上界排除),而三个参数的形式则按第三个参数指定的界限形式构造范围。第三个参数必须是下列字符串之一: ()(][)或者 diff --git a/zh/17/ref/abort.sgml b/zh/17/ref/abort.sgml index 95835c70..caed1f42 100644 --- a/zh/17/ref/abort.sgml +++ b/zh/17/ref/abort.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ABORT 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/alter_aggregate.sgml b/zh/17/ref/alter_aggregate.sgml index 6e6d9e05..ce4e87f4 100644 --- a/zh/17/ref/alter_aggregate.sgml +++ b/zh/17/ref/alter_aggregate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER AGGREGATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/alter_collation.sgml b/zh/17/ref/alter_collation.sgml index 85fd5517..c8273dd3 100644 --- a/zh/17/ref/alter_collation.sgml +++ b/zh/17/ref/alter_collation.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER COLLATION 7 - SQL - Language Statements + SQL - 语言语句 @@ -102,7 +102,7 @@ ALTER COLLATION name SET SCHEMA new_sche 注解 - 创建排序规则对象时,该排序规则的提供者特定版本会记录在系统目录中。 + 创建排序规则对象时,会在系统目录中记录由提供程序确定的排序规则版本。 使用该排序规则时,会将当前版本与记录的版本进行比较;如果二者不匹 配,就会发出警告,例如: diff --git a/zh/17/ref/alter_conversion.sgml b/zh/17/ref/alter_conversion.sgml index d6c8e82c..613b3ec3 100644 --- a/zh/17/ref/alter_conversion.sgml +++ b/zh/17/ref/alter_conversion.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER CONVERSION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/alter_database.sgml b/zh/17/ref/alter_database.sgml index bdd7c828..79326c48 100644 --- a/zh/17/ref/alter_database.sgml +++ b/zh/17/ref/alter_database.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER DATABASE 7 - SQL - Language Statements + SQL - 语言语句 @@ -90,9 +90,7 @@ ALTER DATABASE name RESET ALL allowconn - - 如果为假,则没有人能连接到这个数据库。 - + 如果为 false,则任何人都不能连接到该数据库。 @@ -109,7 +107,7 @@ ALTER DATABASE name RESET ALL istemplate - 如果为真,则任何具有CREATEDB权限的用户都可以从这个数据库克隆。如果为假,则只有超级用户或者该数据库的拥有者可以克隆它。 + 如果为 true,则任何具有 CREATEDB 权限的用户都可以克隆该数据库;如果为 false,则只有超级用户或该数据库的拥有者可以克隆它。 diff --git a/zh/17/ref/alter_default_privileges.sgml b/zh/17/ref/alter_default_privileges.sgml index 2fca3f17..644de19c 100644 --- a/zh/17/ref/alter_default_privileges.sgml +++ b/zh/17/ref/alter_default_privileges.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER DEFAULT PRIVILEGES 7 - SQL - Language Statements + SQL - 语言语句 @@ -121,7 +121,7 @@ REVOKE [ GRANT OPTION FOR ] - 当前,只有模式、表(包括视图和外部表)、序列、函数、类型(包括域)以及大对象的权限可以修改。 + 当前,只有模式、表(包括视图和外部表)、序列、函数、类型(包括域)的权限可以修改。 对于此命令,函数包括聚合函数和过程。此命令中的FUNCTIONSROUTINES等价。(今后更推荐使用ROUTINES, 因为这是同时指代函数和过程的标准术语。在较早的PostgreSQL版本中, @@ -156,8 +156,8 @@ REVOKE [ GRANT OPTION FOR ] 一个现有模式的名称。如果指定,将修改以后在该模式中创建的对象的默认权限。 如果省略IN SCHEMA,则修改全局默认权限。 - 在为模式和大对象设置权限时,不允许使用IN SCHEMA, - 因为模式不能嵌套,而大对象不属于任何模式。 + 在为模式设置权限时,不允许使用IN SCHEMA, + 因为模式不能嵌套。 diff --git a/zh/17/ref/alter_domain.sgml b/zh/17/ref/alter_domain.sgml index a0fe964c..95aaee6c 100644 --- a/zh/17/ref/alter_domain.sgml +++ b/zh/17/ref/alter_domain.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER DOMAIN 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/alter_event_trigger.sgml b/zh/17/ref/alter_event_trigger.sgml index 326f30e1..b9407346 100644 --- a/zh/17/ref/alter_event_trigger.sgml +++ b/zh/17/ref/alter_event_trigger.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER EVENT TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -58,7 +58,7 @@ ALTER EVENT TRIGGER name RENAME TO new_owner - 该事件触发器的新拥有者的用户名。 + 该事件触发器的新所有者的用户名。 @@ -94,7 +94,7 @@ ALTER EVENT TRIGGER name RENAME TO - 另见 + 参见 diff --git a/zh/17/ref/alter_extension.sgml b/zh/17/ref/alter_extension.sgml index 9471390f..3ceae003 100644 --- a/zh/17/ref/alter_extension.sgml +++ b/zh/17/ref/alter_extension.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER EXTENSION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/alter_foreign_data_wrapper.sgml b/zh/17/ref/alter_foreign_data_wrapper.sgml index 06bdb8be..52dbfc7e 100644 --- a/zh/17/ref/alter_foreign_data_wrapper.sgml +++ b/zh/17/ref/alter_foreign_data_wrapper.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER FOREIGN DATA WRAPPER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/alter_foreign_table.sgml b/zh/17/ref/alter_foreign_table.sgml index 14958ed9..287ffa90 100644 --- a/zh/17/ref/alter_foreign_table.sgml +++ b/zh/17/ref/alter_foreign_table.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER FOREIGN TABLE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/alter_function.sgml b/zh/17/ref/alter_function.sgml index 5de95078..5c9bc999 100644 --- a/zh/17/ref/alter_function.sgml +++ b/zh/17/ref/alter_function.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation ALTER FUNCTION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/alter_group.sgml b/zh/17/ref/alter_group.sgml index 6f8814dc..cf493632 100644 --- a/zh/17/ref/alter_group.sgml +++ b/zh/17/ref/alter_group.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER GROUP 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/alter_index.sgml b/zh/17/ref/alter_index.sgml index 06134114..978d61e1 100644 --- a/zh/17/ref/alter_index.sgml +++ b/zh/17/ref/alter_index.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER INDEX 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/alter_language.sgml b/zh/17/ref/alter_language.sgml index 7af98f20..000fe499 100644 --- a/zh/17/ref/alter_language.sgml +++ b/zh/17/ref/alter_language.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER LANGUAGE 7 - SQL - Language Statements + SQL - 语言语句 @@ -31,8 +31,8 @@ ALTER [ PROCEDURAL ] LANGUAGE name OWNER TO { ALTER LANGUAGE更改一种过程语言的定义。 - 目前唯一的功能是重命名该语言或为其指定新的拥有者。 - 要使用ALTER LANGUAGE,你必须是超级用户或者该语言的拥有者。 + 目前唯一的功能是重命名该语言或为其指定新的所有者。 + 要使用ALTER LANGUAGE,你必须是超级用户或者该语言的所有者。 @@ -62,7 +62,7 @@ ALTER [ PROCEDURAL ] LANGUAGE name OWNER TO { new_owner - 该语言的新拥有者 + 该语言的新所有者 diff --git a/zh/17/ref/alter_large_object.sgml b/zh/17/ref/alter_large_object.sgml index ad3f61f7..be30f848 100644 --- a/zh/17/ref/alter_large_object.sgml +++ b/zh/17/ref/alter_large_object.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER LARGE OBJECT 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/alter_materialized_view.sgml b/zh/17/ref/alter_materialized_view.sgml index 71ac3ade..2ef84a4c 100644 --- a/zh/17/ref/alter_materialized_view.sgml +++ b/zh/17/ref/alter_materialized_view.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER MATERIALIZED VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/alter_opclass.sgml b/zh/17/ref/alter_opclass.sgml index b1872b37..a2228963 100644 --- a/zh/17/ref/alter_opclass.sgml +++ b/zh/17/ref/alter_opclass.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER OPERATOR CLASS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/alter_operator.sgml b/zh/17/ref/alter_operator.sgml index 9537f8e9..0e908cac 100644 --- a/zh/17/ref/alter_operator.sgml +++ b/zh/17/ref/alter_operator.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER OPERATOR 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/alter_opfamily.sgml b/zh/17/ref/alter_opfamily.sgml index a0b755c2..45e5007b 100644 --- a/zh/17/ref/alter_opfamily.sgml +++ b/zh/17/ref/alter_opfamily.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER OPERATOR FAMILY 7 - SQL - Language Statements + SQL - 语言语句 @@ -247,6 +247,9 @@ ALTER OPERATOR FAMILY name USING name RENAME TO 设置的 发布参数。详见该命令的说明。 - - - 更改 publish_via_partition_root 参数可能导致订 - 阅端发生数据丢失或重复,因为它会改变已发布表的标识和模式。请注 - 意,只有当根分区表被指定为复制目标时,才会发生此问题。 - - - 可通过以下方式避免此问题:在执行 - ALTER PUBLICATION ... SET之后、执行 - ALTER SUBSCRIPTION ... REFRESH PUBLICATION - 之前,不修改分区叶子表;并且刷新时仅使用 - copy_data = off选项。 - - + diff --git a/zh/17/ref/alter_role.sgml b/zh/17/ref/alter_role.sgml index 6c719424..0f2402d9 100644 --- a/zh/17/ref/alter_role.sgml +++ b/zh/17/ref/alter_role.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation ALTER ROLE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/alter_routine.sgml b/zh/17/ref/alter_routine.sgml index 4fc3e18d..79191e1e 100644 --- a/zh/17/ref/alter_routine.sgml +++ b/zh/17/ref/alter_routine.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER ROUTINE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/alter_rule.sgml b/zh/17/ref/alter_rule.sgml index 9449d787..9397274c 100644 --- a/zh/17/ref/alter_rule.sgml +++ b/zh/17/ref/alter_rule.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER RULE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/alter_schema.sgml b/zh/17/ref/alter_schema.sgml index 2baf518d..13df793e 100644 --- a/zh/17/ref/alter_schema.sgml +++ b/zh/17/ref/alter_schema.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER SCHEMA 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/alter_sequence.sgml b/zh/17/ref/alter_sequence.sgml index 05ba4edf..a1f6887d 100644 --- a/zh/17/ref/alter_sequence.sgml +++ b/zh/17/ref/alter_sequence.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER SEQUENCE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/alter_server.sgml b/zh/17/ref/alter_server.sgml index 5d870833..b3481a8a 100644 --- a/zh/17/ref/alter_server.sgml +++ b/zh/17/ref/alter_server.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER SERVER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/alter_statistics.sgml b/zh/17/ref/alter_statistics.sgml index 315ff6b7..561ca100 100644 --- a/zh/17/ref/alter_statistics.sgml +++ b/zh/17/ref/alter_statistics.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER STATISTICS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/alter_subscription.sgml b/zh/17/ref/alter_subscription.sgml index 280136f0..be56a363 100644 --- a/zh/17/ref/alter_subscription.sgml +++ b/zh/17/ref/alter_subscription.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER SUBSCRIPTION 7 - SQL - Language Statements + SQL - 语言语句 @@ -59,14 +59,7 @@ ALTER SUBSCRIPTION name RENAME TO < 将该槽与订阅解除关联并删除该订阅。 - - 命令ALTER SUBSCRIPTION ... REFRESH PUBLICATION、 - 带有refresh = true选项的 - ALTER SUBSCRIPTION ... {SET|ADD|DROP} PUBLICATION ...、 - ALTER SUBSCRIPTION ... SET (failover = true|false)以及 - ALTER SUBSCRIPTION ... SET (two_phase = false) - 不能在事务块内执行。 - + 命令ALTER SUBSCRIPTION ... REFRESH PUBLICATION、带有refresh选项为trueALTER SUBSCRIPTION ... {SET|ADD|DROP} PUBLICATION ...以及ALTER SUBSCRIPTION ... SET (failover = true|false)不能在事务块内执行。 命令ALTER SUBSCRIPTION ... REFRESH PUBLICATION以及 @@ -204,22 +197,7 @@ ALTER SUBSCRIPTION name RENAME TO < SET ( subscription_parameter [= value] [, ... ] ) - - 该子句修改最初由设置的参数。 - 详情请参见该命令。可更改的参数有 - slot_name、 - synchronous_commit、 - binary、 - streaming、 - disable_on_error、 - password_required、 - run_as_owner、 - origin、 - failover - 以及 - two_phase。 - 只有超级用户才能设置password_required = false。 - + 该子句修改最初由设置的参数。详情请参见该命令。可更改的参数有slot_namesynchronous_commitbinarystreamingdisable_on_errorpassword_requiredrun_as_owneroriginfailover。只有超级用户才能设置password_required = false 更改 @@ -237,29 +215,6 @@ ALTER SUBSCRIPTION name RENAME TO < failover 选项已启用,该槽也可能不会被同步到备库。 - - - 只有在订阅被禁用时,才能更改 - failover - 和 - two_phase - 参数。 - - - - 当将 - two_phase - 从true改为false时,如果发现逻辑复制工作进程 - 在two_phase参数仍为true时执行的任何预备事务, - 后端进程会报告错误。你可以在发布者节点上处理这些预备事务,或者在订阅者上手工回滚 - 它们,然后再次尝试。与特定订阅对应、由逻辑复制工作进程预备的事务具有如下模式: - pg_gid_%u_%u - (参数:订阅oid,远端事务标识xid)。 - 要手工处理这类事务,需要回滚名称中包含相应订阅 ID 的所有预备事务。应用可以检查 - pg_prepared_xacts - 来找出所需的预备事务。在two_phase选项从true - 改为false之后,这些事务在提交时会由发布者再次复制。 - @@ -269,9 +224,7 @@ ALTER SUBSCRIPTION name RENAME TO < 跳过应用远端事务的所有更改。如果传入数据违反任何约束,逻辑复制会停止,直到问题解决。 通过使用ALTER SUBSCRIPTION ... SKIP命令,逻辑复制工作进程会跳过 - 该事务中的所有数据修改操作。若订阅者上启用了 - two_phase, - 则此选项对因在订阅者上启用该参数而已经预备的事务没有作用。逻辑复制工作进程成功跳过该事务或完成一个事务后, + 该事务中的所有数据修改操作。此选项对因在订阅者上启用 two_phase 而已经预备的事务没有作用。逻辑复制工作进程成功跳过该事务或完成一个事务后, LSN(存储在pg_subscription.subskiplsn中) 会被清除。有关逻辑复制冲突的详细信息,请参见 。 diff --git a/zh/17/ref/alter_system.sgml b/zh/17/ref/alter_system.sgml index 22c645e6..1c9249b1 100644 --- a/zh/17/ref/alter_system.sgml +++ b/zh/17/ref/alter_system.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER SYSTEM 7 - SQL - Language Statements + SQL - 语言语句 @@ -85,8 +85,7 @@ ALTER SYSTEM RESET ALL - 对于某些接受列表的参数,带引号的值会生成带双引号的输出,以保留空 - 格和逗号;对于另一些参数,则必须在单引号字符串内部使用双引号才能 + 对于某些接受列表的参数,带引号的值会生成带双引号的输出,以保留空白和逗号;对于另一些参数,则必须在单引号字符串内部使用双引号才能 达到这种效果。 diff --git a/zh/17/ref/alter_table.sgml b/zh/17/ref/alter_table.sgml index 4798657b..2df03e17 100644 --- a/zh/17/ref/alter_table.sgml +++ b/zh/17/ref/alter_table.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TABLE 7 - SQL - Language Statements + SQL - 语言语句 @@ -1011,7 +1011,7 @@ WITH ( MODULUS numeric_literal, REM - 若要强制立即回收已删除列所占的空间,可以执行任何一种会导致整表重写的ALTER TABLE形式。这样会重新构造每一行,并用空值替换被删除的列。 + 若要强制立即回收已删除列所占的空间,可以执行任何一种会导致整表重写的ALTER TABLE形式。这样会重建每一行,并用空值替换被删除的列。 diff --git a/zh/17/ref/alter_tablespace.sgml b/zh/17/ref/alter_tablespace.sgml index f0297481..7369ec94 100644 --- a/zh/17/ref/alter_tablespace.sgml +++ b/zh/17/ref/alter_tablespace.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TABLESPACE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/alter_trigger.sgml b/zh/17/ref/alter_trigger.sgml index 9fc49c8b..874811aa 100644 --- a/zh/17/ref/alter_trigger.sgml +++ b/zh/17/ref/alter_trigger.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -127,7 +127,7 @@ ALTER TRIGGER emp_stamp ON emp DEPENDS ON EXTENSION emplib; - 另见 + 参见 diff --git a/zh/17/ref/alter_tsconfig.sgml b/zh/17/ref/alter_tsconfig.sgml index 7ae05dd5..891dce66 100644 --- a/zh/17/ref/alter_tsconfig.sgml +++ b/zh/17/ref/alter_tsconfig.sgml @@ -13,7 +13,7 @@ PostgreSQL documentation ALTER TEXT SEARCH CONFIGURATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/alter_tsdictionary.sgml b/zh/17/ref/alter_tsdictionary.sgml index 9679697e..163d788b 100644 --- a/zh/17/ref/alter_tsdictionary.sgml +++ b/zh/17/ref/alter_tsdictionary.sgml @@ -13,7 +13,7 @@ PostgreSQL documentation ALTER TEXT SEARCH DICTIONARY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/alter_tsparser.sgml b/zh/17/ref/alter_tsparser.sgml index 525064c9..0844cb0a 100644 --- a/zh/17/ref/alter_tsparser.sgml +++ b/zh/17/ref/alter_tsparser.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TEXT SEARCH PARSER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/alter_tstemplate.sgml b/zh/17/ref/alter_tstemplate.sgml index fa4157f9..a3eec599 100644 --- a/zh/17/ref/alter_tstemplate.sgml +++ b/zh/17/ref/alter_tstemplate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TEXT SEARCH TEMPLATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/alter_type.sgml b/zh/17/ref/alter_type.sgml index 58063799..6c1bc805 100644 --- a/zh/17/ref/alter_type.sgml +++ b/zh/17/ref/alter_type.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation ALTER TYPE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/alter_user.sgml b/zh/17/ref/alter_user.sgml index 362b5518..5a4f5dd4 100644 --- a/zh/17/ref/alter_user.sgml +++ b/zh/17/ref/alter_user.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER USER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/alter_user_mapping.sgml b/zh/17/ref/alter_user_mapping.sgml index 6bbeffc6..b1fc6606 100644 --- a/zh/17/ref/alter_user_mapping.sgml +++ b/zh/17/ref/alter_user_mapping.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER USER MAPPING 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/alter_view.sgml b/zh/17/ref/alter_view.sgml index 020f864b..63fcb79e 100644 --- a/zh/17/ref/alter_view.sgml +++ b/zh/17/ref/alter_view.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/analyze.sgml b/zh/17/ref/analyze.sgml index 1717fc7f..8a934dce 100644 --- a/zh/17/ref/analyze.sgml +++ b/zh/17/ref/analyze.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ANALYZE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/begin.sgml b/zh/17/ref/begin.sgml index 2343e66c..fc8fb312 100644 --- a/zh/17/ref/begin.sgml +++ b/zh/17/ref/begin.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation BEGIN 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/call.sgml b/zh/17/ref/call.sgml index 4a12245b..7dca6405 100644 --- a/zh/17/ref/call.sgml +++ b/zh/17/ref/call.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CALL 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/checkpoint.sgml b/zh/17/ref/checkpoint.sgml index 9694e0c6..5e95964c 100644 --- a/zh/17/ref/checkpoint.sgml +++ b/zh/17/ref/checkpoint.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CHECKPOINT 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/close.sgml b/zh/17/ref/close.sgml index 53c793c4..788e2c9a 100644 --- a/zh/17/ref/close.sgml +++ b/zh/17/ref/close.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation CLOSE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/cluster.sgml b/zh/17/ref/cluster.sgml index f22017f1..fb0c44b0 100644 --- a/zh/17/ref/cluster.sgml +++ b/zh/17/ref/cluster.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CLUSTER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/clusterdb.sgml b/zh/17/ref/clusterdb.sgml index fd83c9ba..ada12058 100644 --- a/zh/17/ref/clusterdb.sgml +++ b/zh/17/ref/clusterdb.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation clusterdb 1 - Application + 应用程序 diff --git a/zh/17/ref/comment.sgml b/zh/17/ref/comment.sgml index baa2f239..5148556c 100644 --- a/zh/17/ref/comment.sgml +++ b/zh/17/ref/comment.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation COMMENT 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/commit.sgml b/zh/17/ref/commit.sgml index 046c6d84..596d1550 100644 --- a/zh/17/ref/commit.sgml +++ b/zh/17/ref/commit.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation COMMIT 7 - SQL - Language Statements + SQL - 语言语句 @@ -39,7 +39,7 @@ COMMIT [ WORK | TRANSACTION ] [ AND [ NO ] CHAIN ] 参数 - chained transactions + 链式事务 diff --git a/zh/17/ref/commit_prepared.sgml b/zh/17/ref/commit_prepared.sgml index dcdba873..734b2833 100644 --- a/zh/17/ref/commit_prepared.sgml +++ b/zh/17/ref/commit_prepared.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation COMMIT PREPARED 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/copy.sgml b/zh/17/ref/copy.sgml index aef76bdf..92dd546b 100644 --- a/zh/17/ref/copy.sgml +++ b/zh/17/ref/copy.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation COPY 7 - SQL - Language Statements + SQL - 语言语句 @@ -497,15 +497,10 @@ COPY count 注解 - - COPY TO可用于普通表和已填充的物化视图。例如, - COPY table TO - 复制的行与 - SELECT * FROM ONLY table - 相同。但它不直接支持其他关系类型,如分区表、继承子表或视图。 - 要复制这类关系的全部行,请使用 - COPY (SELECT * FROM table) TO。 - + COPY TO 只能用于普通表,不能用于视图,且不会复制子表或子分区中的行。例如,COPY table TO 复制的行与 SELECT * FROM ONLY table 相同。语法 COPY (SELECT * FROM table) TO ... 可用于导出继承层次结构、分区表或视图中的所有行。 COPY FROM可用于普通表、外部表、分区表,以及具有 diff --git a/zh/17/ref/create_access_method.sgml b/zh/17/ref/create_access_method.sgml index d4cb6d2c..7f2d9d8e 100644 --- a/zh/17/ref/create_access_method.sgml +++ b/zh/17/ref/create_access_method.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE ACCESS METHOD 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/create_aggregate.sgml b/zh/17/ref/create_aggregate.sgml index 3b890824..252f9fab 100644 --- a/zh/17/ref/create_aggregate.sgml +++ b/zh/17/ref/create_aggregate.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation CREATE AGGREGATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/create_cast.sgml b/zh/17/ref/create_cast.sgml index 1e2c9275..94e78f9e 100644 --- a/zh/17/ref/create_cast.sgml +++ b/zh/17/ref/create_cast.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation CREATE CAST 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/create_collation.sgml b/zh/17/ref/create_collation.sgml index 6bb3f7ab..0188aa67 100644 --- a/zh/17/ref/create_collation.sgml +++ b/zh/17/ref/create_collation.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE COLLATION 7 - SQL - Language Statements + SQL - 语言语句 @@ -96,8 +96,7 @@ CREATE COLLATION [ IF NOT EXISTS ] name FROM 如果providerbuiltin, 则必须指定locale,且其值只能是 - CC.UTF-8或 - PG_UNICODE_FAST。 + CC.UTF-8 @@ -130,7 +129,7 @@ CREATE COLLATION [ IF NOT EXISTS ] name FROM - 指定与该排序规则关联的区域设置服务所使用的提供者。可能的值是 + 指定与该排序规则关联的区域设置服务所使用的提供程序。可能的值是 builtinicuICU (如果服务器在构建时启用了 ICU 支持)或libc。 @@ -154,7 +153,7 @@ CREATE COLLATION [ IF NOT EXISTS ] name FROM - 非确定性排序规则仅受 ICU 提供者支持。 + 非确定性排序规则仅受 ICU 提供程序支持。 @@ -238,14 +237,14 @@ CREATE COLLATION french (locale = 'fr_FR.utf8'); - 使用 ICU 提供者并采用德语电话簿排序顺序创建一种排序规则: + 使用 ICU 提供程序并采用德语电话簿排序顺序创建一种排序规则: CREATE COLLATION german_phonebook (provider = icu, locale = 'de-u-co-phonebk'); - 使用 ICU 提供者、基于 ICU 根区域设置并带有自定义规则创建一种排序规 + 使用 ICU 提供程序、基于 ICU 根区域设置并带有自定义规则创建一种排序规 则: diff --git a/zh/17/ref/create_conversion.sgml b/zh/17/ref/create_conversion.sgml index da83218a..3fcb4447 100644 --- a/zh/17/ref/create_conversion.sgml +++ b/zh/17/ref/create_conversion.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE CONVERSION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/create_database.sgml b/zh/17/ref/create_database.sgml index 39446302..3dee203d 100644 --- a/zh/17/ref/create_database.sgml +++ b/zh/17/ref/create_database.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE DATABASE 7 - SQL - Language Statements + SQL - 语言语句 @@ -140,8 +140,7 @@ CREATE DATABASE name builtin,则必须指定 localebuiltin_locale,并将其设为 - CC.UTF-8 或 - PG_UNICODE_FAST之一。 + CC.UTF-8之一。 @@ -197,8 +196,7 @@ CREATE DATABASE name builtin 提供程序可用的区域设置有 - CC.UTF-8 和 - PG_UNICODE_FAST。 + CC.UTF-8 @@ -357,7 +355,7 @@ CREATE DATABASE nameLC_CTYPE)兼容。如果区域设置为 C (或等价的 POSIX),则允许所有编码;但对于其他区域设置,只有一种编码能够正常工作。(不过,在 Windows 上,UTF-8 编码可与任何区域设置一起使用。) CREATE DATABASE 允许超级用户不考虑区域设置而指定 - SQL_ASCII 编码,但这种选择已被废弃;如果数据库中存储了与该区域设置不兼容编码的数据,字符串函数的行为可能会出错。 + SQL_ASCII 编码,但这种选择已弃用;如果数据库中存储了与该区域设置不兼容编码的数据,字符串函数的行为可能会出错。 @@ -407,7 +405,7 @@ CREATE DATABASE music TEMPLATE template0; 在这个示例中,如果指定的区域设置与 template1 中的不同, - 则必须使用 TEMPLATE template0 子句。(如果并不不同, + 则必须使用 TEMPLATE template0 子句。(如果相同, 那么显式指定区域设置就是多余的。) diff --git a/zh/17/ref/create_domain.sgml b/zh/17/ref/create_domain.sgml index 905dd30d..420bbf83 100644 --- a/zh/17/ref/create_domain.sgml +++ b/zh/17/ref/create_domain.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE DOMAIN 7 - SQL - Language Statements + SQL - 语言语句 @@ -86,7 +86,7 @@ CREATE DOMAIN name [ AS ] 该域的可选排序规则。如果未指定排序规则,则该域的排序规则行为与其 底层数据类型相同。如果指定了COLLATE,则底层 - 类型必须是一种可排序数据类型。 + 类型必须是一种支持排序规则的数据类型。 diff --git a/zh/17/ref/create_event_trigger.sgml b/zh/17/ref/create_event_trigger.sgml index 0d45c2be..32448118 100644 --- a/zh/17/ref/create_event_trigger.sgml +++ b/zh/17/ref/create_event_trigger.sgml @@ -13,7 +13,7 @@ PostgreSQL documentation CREATE EVENT TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -44,7 +44,7 @@ CREATE EVENT TRIGGER name CREATE EVENT TRIGGER创建一个新的事件触发器。 每当指定的事件发生,并且与该触发器关联的WHEN条件(如果有)得到 满足时,就会执行该触发器函数。有关事件触发器的一般性介绍,见 - 。创建事件触发器的用户将成为其拥有者。 + 。创建事件触发器的用户将成为其所有者。 @@ -83,8 +83,7 @@ CREATE EVENT TRIGGER name - 用于过滤事件的变量名称。这使得可以将触发器限定为只在支持该变量的部 - 分情形下触发。当前唯一支持的 + 用于过滤事件的变量名称。这样可以将触发器限定为只在原本支持的部分情形下触发。当前唯一支持的 filter_variableTAG @@ -194,7 +193,7 @@ CREATE EVENT TRIGGER abort_ddl ON ddl_command_start - 另见 + 参见 diff --git a/zh/17/ref/create_extension.sgml b/zh/17/ref/create_extension.sgml index 6120f3fa..7acc3a5e 100644 --- a/zh/17/ref/create_extension.sgml +++ b/zh/17/ref/create_extension.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE EXTENSION 7 - SQL - Language Statements + SQL - 语言语句 @@ -166,7 +166,7 @@ CREATE EXTENSION [ IF NOT EXISTS ] extension_name 会在之后执行编写粗心的扩展脚本时实施攻击,使该用户获得超级用户权限。 不过,只有当特洛伊木马对象在脚本执行期间位于 search_path 中时,它们才会构成危险;这意味着它们 - 位于扩展的安装目标模式中,或位于它所依赖的某个扩展所属的模式中。 + 位于扩展的安装目标模式中,或位于它所依赖的某个扩展的目标模式中。 因此,处理那些脚本尚未经过仔细审查的扩展时,一个经验法则是: 只把它们安装到从未向任何不受信任用户授予、而且今后也不会授予 CREATE 权限的模式中。它们所依赖的任何扩展也应如此。 diff --git a/zh/17/ref/create_foreign_data_wrapper.sgml b/zh/17/ref/create_foreign_data_wrapper.sgml index bfa097ef..0611709d 100644 --- a/zh/17/ref/create_foreign_data_wrapper.sgml +++ b/zh/17/ref/create_foreign_data_wrapper.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE FOREIGN DATA WRAPPER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/create_foreign_table.sgml b/zh/17/ref/create_foreign_table.sgml index 787d3748..5e7768bf 100644 --- a/zh/17/ref/create_foreign_table.sgml +++ b/zh/17/ref/create_foreign_table.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE FOREIGN TABLE 7 - SQL - Language Statements + SQL - 语言语句 @@ -143,9 +143,7 @@ WITH ( MODULUS numeric_literal, REM COLLATE collation - - COLLATE子句为该列(必须是一种可排序数据类型)指定一个排序规则。如果未指定,则使用该列数据类型的默认排序规则。 - + COLLATE子句为列指定排序规则(该列必须属于支持排序规则的数据类型)。如果未指定,则使用列数据类型的默认排序规则。 diff --git a/zh/17/ref/create_function.sgml b/zh/17/ref/create_function.sgml index b6447707..5b894c32 100644 --- a/zh/17/ref/create_function.sgml +++ b/zh/17/ref/create_function.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation CREATE FUNCTION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/create_group.sgml b/zh/17/ref/create_group.sgml index 06195a91..9a6538ed 100644 --- a/zh/17/ref/create_group.sgml +++ b/zh/17/ref/create_group.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE GROUP 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/create_index.sgml b/zh/17/ref/create_index.sgml index 1c525288..c8940c2e 100644 --- a/zh/17/ref/create_index.sgml +++ b/zh/17/ref/create_index.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation CREATE INDEX 7 - SQL - Language Statements + SQL - 语言语句 @@ -57,7 +57,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] PostgreSQL提供了索引方法 - B-树、哈希、GiST、SP-GiST、GIN 以及 BRIN。用户也可以定义自己的索引 + B-树、hash、GiST、SP-GiST、GIN 以及 BRIN。用户也可以定义自己的索引 方法,但这相当复杂。 @@ -123,7 +123,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] 对于临时表,CREATE INDEX始终是非并发的, - 因为没有其他会话可以访问它们,而且非并发创建索引的成本更低。 + 因为没有其他会话可以访问它们,而且非并发创建索引的代价更低。 @@ -373,10 +373,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] 可选的WITH子句为索引指定存储参数。每一种 索引方法都有其各自允许的存储参数集合。 - - - - B-树、哈希、GiST 和 SP-GiST 索引方法都接受以下参数: + B-树、hash、GiST 和 SP-GiST 索引方法都接受以下参数: @@ -390,7 +387,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - 控制索引方法尝试将索引页填充到多满。对于 B-树,在初始构建索引时, + 索引的填充因子是一个百分比,用于确定索引方法尝试将索引页填充到多满。对于 B-树,在初始构建索引时, 以及在右侧扩展索引(加入新的最大键值)时,叶子页都会填充到这一 百分比。如果页面随后变成全满,就会发生分裂,从而导致磁盘上的 索引结构碎片化。B-树默认使用 90 的填充因子,但也可以选择 10 到 @@ -471,7 +468,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - 控制是否使用中描述的缓冲构建技术 + 确定是否使用中描述的缓冲构建技术 来构建索引。设置为OFF时禁用缓冲构建,设置为 ON时启用,设置为AUTO时初始为 禁用,但一旦索引大小达到, @@ -484,7 +481,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - GIN 索引接受以下参数: + GIN 索引接受不同的参数: @@ -498,8 +495,8 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - 控制中描述的快速更新技术的使用。 - ON 启用快速更新,OFF 禁用快速更新。 + 此设置控制中描述的快速更新技术的使用。 + 这是一个布尔参数:ON 启用快速更新,OFF 禁用快速更新。 默认值为ON @@ -528,7 +525,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - 为该索引覆盖的全局设置。 + 自定义参数。 该值以千字节为单位。 @@ -536,7 +533,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - BRIN 索引接受以下参数: + BRIN 索引接受不同的参数: @@ -566,7 +563,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - 定义当在下一页范围检测到插入时,是否为前一页范围排队执行一次提要操作 + 定义当在下一页范围检测到插入时,是否为前一页范围排队执行一次范围摘要操作 (详见)。 默认值为off @@ -580,8 +577,8 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] 并发构建索引 - index - building concurrently + 索引 + 并发构建 @@ -748,7 +745,7 @@ Indexes: PostgreSQL可以在构建索引时利用多个 CPU, 以便更快处理表中的行。这项特性被称为并行索引构建。 - 对于支持并行构建索引的索引方法(当前为 B-树、GIN 和 BRIN), + 对于支持并行构建索引的索引方法(当前为 B-树和 BRIN), maintenance_work_mem指定每次索引构建操作整体最多 可使用的内存量,而不管启动了多少工作者进程。通常,代价模型会自动决 定是否需要请求工作者进程,以及请求多少个。 diff --git a/zh/17/ref/create_language.sgml b/zh/17/ref/create_language.sgml index fca9e159..5d737764 100644 --- a/zh/17/ref/create_language.sgml +++ b/zh/17/ref/create_language.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE LANGUAGE 7 - SQL - Language Statements + SQL - 语言语句 @@ -96,7 +96,7 @@ CREATE [ OR REPLACE ] [ TRUSTED ] [ PROCEDURAL ] LANGUAGE name [ DEFAUL 会妨碍优化器识别该查询匹配一个索引。 + + 在PostgreSQL 8.4 之前,OPERATOR子句可以包含RECHECK选项。现在不再支持该选项,因为索引操作符是否有损会在运行时动态确定。这样可以高效处理操作符可能有损也可能无损的情况。 + diff --git a/zh/17/ref/create_operator.sgml b/zh/17/ref/create_operator.sgml index faae3140..9ea345ed 100644 --- a/zh/17/ref/create_operator.sgml +++ b/zh/17/ref/create_operator.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE OPERATOR 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/create_opfamily.sgml b/zh/17/ref/create_opfamily.sgml index 1577f0c1..9d31bb01 100644 --- a/zh/17/ref/create_opfamily.sgml +++ b/zh/17/ref/create_opfamily.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE OPERATOR FAMILY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/create_policy.sgml b/zh/17/ref/create_policy.sgml index 9a5fc65e..b353d182 100644 --- a/zh/17/ref/create_policy.sgml +++ b/zh/17/ref/create_policy.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE POLICY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/create_procedure.sgml b/zh/17/ref/create_procedure.sgml index eaa88de6..fe20673f 100644 --- a/zh/17/ref/create_procedure.sgml +++ b/zh/17/ref/create_procedure.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation CREATE PROCEDURE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/create_publication.sgml b/zh/17/ref/create_publication.sgml index 1f0c45e0..8c4315c5 100644 --- a/zh/17/ref/create_publication.sgml +++ b/zh/17/ref/create_publication.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE PUBLICATION 7 - SQL - Language Statements + SQL - 语言语句 @@ -248,11 +248,7 @@ CREATE PUBLICATION name 操作符、类型和排序规则、系统列引用,或非不可变内置函数。 - - 任何列列表都必须包含REPLICA IDENTITY列,这样 - UPDATEDELETE操作才能被发布。 - 如果该发布只发布INSERT操作,则列列表不受此限制。 - + 如果指定了FOR TABLES IN SCHEMA,并且该表属于所引用的模式, diff --git a/zh/17/ref/create_role.sgml b/zh/17/ref/create_role.sgml index 1a777c5c..7b28beb3 100644 --- a/zh/17/ref/create_role.sgml +++ b/zh/17/ref/create_role.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE ROLE 7 - SQL - Language Statements + SQL - 语言语句 @@ -233,13 +233,7 @@ in sync when changing the above synopsis! 的值是什么,它都会按原样存储(因为系统无法解密指定的已加密密码字符串, 再将其改用其他格式加密)。这样便可在转储/恢复期间重新装载已加密的密码。 - - - 对 MD5 加密密码的支持已被弃用,并将在未来的 - PostgreSQL版本中移除。关于迁移到其他密码类型 - 的细节,参见。 - - + diff --git a/zh/17/ref/create_rule.sgml b/zh/17/ref/create_rule.sgml index 6d1486c9..e8b37c6d 100644 --- a/zh/17/ref/create_rule.sgml +++ b/zh/17/ref/create_rule.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE RULE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/create_schema.sgml b/zh/17/ref/create_schema.sgml index 74944401..92074e50 100644 --- a/zh/17/ref/create_schema.sgml +++ b/zh/17/ref/create_schema.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE SCHEMA 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/create_sequence.sgml b/zh/17/ref/create_sequence.sgml index ffbf9797..c786a61f 100644 --- a/zh/17/ref/create_sequence.sgml +++ b/zh/17/ref/create_sequence.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation CREATE SEQUENCE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/create_server.sgml b/zh/17/ref/create_server.sgml index 586067b0..0cb4f9ed 100644 --- a/zh/17/ref/create_server.sgml +++ b/zh/17/ref/create_server.sgml @@ -13,7 +13,7 @@ PostgreSQL documentation CREATE SERVER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/create_statistics.sgml b/zh/17/ref/create_statistics.sgml index ecafe6c6..f007156a 100644 --- a/zh/17/ref/create_statistics.sgml +++ b/zh/17/ref/create_statistics.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE STATISTICS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/create_subscription.sgml b/zh/17/ref/create_subscription.sgml index 9311f13b..bd0789cb 100644 --- a/zh/17/ref/create_subscription.sgml +++ b/zh/17/ref/create_subscription.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE SUBSCRIPTION 7 - SQL - Language Statements + SQL - 语言语句 @@ -243,29 +243,20 @@ CREATE SUBSCRIPTION subscription_namestreaming (enum) - 指定是否为该订阅启用进行中事务的流式传输。默认值为 - parallel,表示如果有可用的并行应用工作进程, - 接收到的更改会直接通过其中之一应用。如果没有空闲的并行应用工作进程 - 可以处理流式事务,那么这些更改会写入临时文件,并在事务提交后再应用。 - 注意,如果并行应用工作进程中发生错误,远端事务的 finish LSN - 可能不会记录到服务器日志中。 + 指定是否为该订阅启用进行中事务的流式传输。默认值为 off, + 表示所有事务都会先在发布者上完全解码,然后才整体发送给订阅者。 - - - 当发布者与订阅者的模式不同时,存在发生死锁的风险,尽管这种情况 - 很少见。应用工作进程会自动重试这些事务。 - - - - 如果设为on,接收到的更改会写入临时文件,然后仅在 - 事务在发布者上提交且被订阅者接收之后才应用。 + 如果设为 on,接收到的更改会写入临时文件,然后仅在事务 + 在发布者上提交且被订阅者接收之后才应用。 - 如果设为off,所有事务都会先在发布者上完全解码, - 然后才整体发送给订阅者。 + 如果设为 parallel,接收到的更改会直接通过可用的并行应用工作进程应用。 + 如果没有空闲的并行应用工作进程可以处理流式事务,那么这些更改会写入临时文件, + 并在事务提交后再应用。注意,如果并行应用工作进程中发生错误,远端事务的完成 LSN + 可能不会记录到服务器日志中。 diff --git a/zh/17/ref/create_table.sgml b/zh/17/ref/create_table.sgml index 737d099c..baad64dd 100644 --- a/zh/17/ref/create_table.sgml +++ b/zh/17/ref/create_table.sgml @@ -4,7 +4,6 @@ PostgreSQL documentation --> - CREATE TABLE @@ -12,7 +11,7 @@ PostgreSQL documentation CREATE TABLE 7 - SQL - Language Statements + SQL - 语言语句 @@ -59,56 +58,55 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI [ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ] [ TABLESPACE tablespace_name ] -where column_constraint is: +其中column_constraint为: [ CONSTRAINT constraint_name ] -{ NOT NULL [ NO INHERIT ] | +{ NOT NULL | NULL | CHECK ( expression ) [ NO INHERIT ] | DEFAULT default_expr | - GENERATED ALWAYS AS ( generation_expr ) [ STORED | VIRTUAL ] | + GENERATED ALWAYS AS ( generation_expr ) STORED | GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( sequence_options ) ] | UNIQUE [ NULLS [ NOT ] DISTINCT ] index_parameters | PRIMARY KEY index_parameters | REFERENCES reftable [ ( refcolumn ) ] [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE referential_action ] [ ON UPDATE referential_action ] } -[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ] [ ENFORCED | NOT ENFORCED ] +[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ] -and table_constraint is: +table_constraint为: [ CONSTRAINT constraint_name ] { CHECK ( expression ) [ NO INHERIT ] | - NOT NULL column_name [ NO INHERIT ] | - UNIQUE [ NULLS [ NOT ] DISTINCT ] ( column_name [, ... ] [, column_name WITHOUT OVERLAPS ] ) index_parameters | - PRIMARY KEY ( column_name [, ... ] [, column_name WITHOUT OVERLAPS ] ) index_parameters | + UNIQUE [ NULLS [ NOT ] DISTINCT ] ( column_name [, ... ] ) index_parameters | + PRIMARY KEY ( column_name [, ... ] ) index_parameters | EXCLUDE [ USING index_method ] ( exclude_element WITH operator [, ... ] ) index_parameters [ WHERE ( predicate ) ] | - FOREIGN KEY ( column_name [, ... ] [, PERIOD column_name ] ) REFERENCES reftable [ ( refcolumn [, ... ] [, PERIOD refcolumn ] ) ] + FOREIGN KEY ( column_name [, ... ] ) REFERENCES reftable [ ( refcolumn [, ... ] ) ] [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE referential_action ] [ ON UPDATE referential_action ] } -[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ] [ ENFORCED | NOT ENFORCED ] +[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ] -and like_option is: +like_option为: { INCLUDING | EXCLUDING } { COMMENTS | COMPRESSION | CONSTRAINTS | DEFAULTS | GENERATED | IDENTITY | INDEXES | STATISTICS | STORAGE | ALL } -and partition_bound_spec is: +partition_bound_spec为: IN ( partition_bound_expr [, ...] ) | FROM ( { partition_bound_expr | MINVALUE | MAXVALUE } [, ...] ) TO ( { partition_bound_expr | MINVALUE | MAXVALUE } [, ...] ) | WITH ( MODULUS numeric_literal, REMAINDER numeric_literal ) -index_parameters in UNIQUE, PRIMARY KEY, and EXCLUDE constraints are: +UNIQUEPRIMARY KEYEXCLUDE约束中的index_parameters为: [ INCLUDE ( column_name [, ... ] ) ] [ WITH ( storage_parameter [= value] [, ... ] ) ] [ USING INDEX TABLESPACE tablespace_name ] -exclude_element in an EXCLUDE constraint is: +EXCLUDE约束中的exclude_element为: { column_name | ( expression ) } [ COLLATE collation ] [ opclass [ ( opclass_parameter = value [, ... ] ) ] ] [ ASC | DESC ] [ NULLS { FIRST | LAST } ] -referential_action in a FOREIGN KEY/REFERENCES constraint is: +FOREIGN KEY/REFERENCES 约束中的 referential_action 为: { NO ACTION | RESTRICT | CASCADE | SET NULL [ ( column_name [, ... ] ) ] | SET DEFAULT [ ( column_name [, ... ] ) ] } @@ -148,16 +146,13 @@ WITH ( MODULUS numeric_literal, REM - 参数 - - TEMPORARY or TEMP + TEMPORARYTEMP - 如果指定该选项,表将创建为临时表。 临时表会在会话结束时自动删除,或者也可在当前事务结束时删除(见下文 ON COMMIT)。 @@ -170,7 +165,7 @@ WITH ( MODULUS numeric_literal, REM - 可以在 TEMPORARYTEMP 前写 GLOBALLOCAL。这在当前的 PostgreSQL 中没有区别,而且已废弃;见下文 。 + 可以在 TEMPORARYTEMP 前写 GLOBALLOCAL。这在当前的 PostgreSQL 中没有区别,而且已弃用;见下文 @@ -178,7 +173,6 @@ WITH ( MODULUS numeric_literal, REM UNLOGGED - 如果指定该选项,表将创建为不记录 WAL 的表。写入不记录 WAL 的表的数据不会写入预写式日志(见 ),因此它们比普通表快得多。不过,它们不具备崩溃安全性:在崩溃或非正常关闭后,不记录 WAL 的表会被自动截断。不记录 WAL 的表的内容也不会复制到备库。在不记录 WAL 的表上创建的任何索引也都会自动成为不记录 WAL 的。 @@ -186,10 +180,6 @@ WITH ( MODULUS numeric_literal, REM 如果指定该选项,与不记录 WAL 的表一起创建的任何序列(用于标识列或 serial 列)也会创建为不记录 WAL 的。 - - - 这种形式不支持分区表。 - @@ -216,14 +206,9 @@ WITH ( MODULUS numeric_literal, REM OF type_name + 创建一个类型化表,其结构取自指定的复合类型(名称可以带模式限定)。类型化表与其类型绑定;例如,如果删除该类型(使用DROP TYPE ... CASCADE),该表也会被删除。 - - 创建一个类型化表,其结构取自指定的独立复合类型(即通过 创建的类型),同时该表自身也会生成一个新的复合类型。该表会依赖于所引用的类型,这意味着对该类型执行级联的 ALTER 或 DROP 操作会传播到该表。 - - - - 类型化表的列名和数据类型始终与其派生类型相同,因此不能再指定额外的列。但 CREATE TABLE 命令仍可为该表添加默认值和约束,并指定存储参数。 - + 创建类型化表时,列的数据类型由底层复合类型决定,不由CREATE TABLE命令指定。不过,CREATE TABLE命令可以为表添加默认值和约束,并指定存储参数。 @@ -252,11 +237,7 @@ WITH ( MODULUS numeric_literal, REM COLLATE collation - - - COLLATE 子句为该列(必须是一种可排序数据类型)赋予一个排序规则。 - 如果没有指定,将使用该列数据类型的默认排序规则。 - + COLLATE子句为列指定排序规则(该列必须属于支持排序规则的数据类型)。如果未指定,则使用列数据类型的默认排序规则。 @@ -265,7 +246,7 @@ WITH ( MODULUS numeric_literal, REM STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN | DEFAULT } TOAST - per-column storage settings + 逐列存储设置 @@ -366,7 +347,6 @@ WITH ( MODULUS numeric_literal, REM PARTITION OF parent_table { FOR VALUES partition_bound_spec | DEFAULT } - 将该表创建为指定父表的分区。 可以使用 FOR VALUES 将其创建为特定值的分区,也可以使用 DEFAULT 创建为默认分区。 @@ -424,13 +404,13 @@ WITH ( MODULUS numeric_literal, REM 还要注意,某些元素类型(如 timestamp)具有 - "infinity" 的概念,那只是另一种可存储的值。这不同于 + “无穷大” 的概念,那只是另一种可存储的值。这不同于 MINVALUEMAXVALUE,后两者并非可存储 的实际值,而只是表示值无界的方式。MAXVALUE 可以视为大于任何 - 其他值,包括 "infinity";MINVALUE 可以视为小于任何 - 其他值,包括 "minus infinity"。因此,范围 + 其他值,包括 “无穷大”;MINVALUE 可以视为小于任何 + 其他值,包括 “负无穷大”。因此,范围 FROM ('infinity') TO (MAXVALUE) 并不是空范围;它只允许存储 - 一个值 — "infinity"。 + 一个值 — “无穷大”。 @@ -488,19 +468,15 @@ WITH ( MODULUS numeric_literal, REM LIKE source_table [ like_option ... ] - LIKE 子句指定一个表,新表会自动从中复制所有列名、数据类型及其非空约束。 - INHERITS 不同,新表和原表在创建完成后就完全脱钩了。对原表的修改不会应用到新表,也不可能在扫描原表时包含新表的数据。 - 同样与 INHERITS 不同,由 LIKE 复制的列和约束不会与同名的列和约束合并。如果同一名称被显式指定,或在另一个 LIKE 子句中指定,则会报错。 - 可选的 like_option 子句指定还要复制原表的哪些附加属性。 指定 INCLUDING 表示复制该属性,指定 EXCLUDING 表示省略该属性。默认是 EXCLUDING。 @@ -548,7 +524,7 @@ WITH ( MODULUS numeric_literal, REM INCLUDING GENERATED - 会复制被复制列定义中的生成表达式以及 STORED/VIRTUAL 的选择。默认情况下,新列将是常规基表列。 + 会复制被复制列定义中的生成表达式。默认情况下,新列将是普通基础列。 @@ -621,16 +597,11 @@ WITH ( MODULUS numeric_literal, REM - NOT NULL [ NO INHERIT ] + NOT NULL - 该列不允许包含空值。 - - - 标记为 NO INHERIT 的约束不会传播到子表。 - @@ -651,7 +622,6 @@ WITH ( MODULUS numeric_literal, REM CHECK ( expression ) [ NO INHERIT ] - CHECK 子句指定一个产生布尔结果的表达式。要使插入或更新成功,新行或更新后的行必须满足该表达式。计算结果为 TRUE 或 UNKNOWN 的表达式视为成功。如果插入或更新操作中的任何一行得到 FALSE 结果,就会抛出错误异常,并且插入或更新不会修改数据库。作为列约束指定的检查约束只应引用该列的值,而出现在表约束中的表达式可以引用多个列。 @@ -661,7 +631,7 @@ WITH ( MODULUS numeric_literal, REM - 一个被标记为NO INHERIT的约束将不会传播到子表。 + 标记为 NO INHERIT 的约束不会传播到子表。 @@ -687,25 +657,17 @@ WITH ( MODULUS numeric_literal, REM - - GENERATED ALWAYS AS ( generation_expr ) [ STORED | VIRTUAL ]generated column + GENERATED ALWAYS AS ( generation_expr ) STORED生成列 - 此子句将列创建为生成列。列不可写入,读取时会返回指定表达式的结果。 - - 指定 VIRTUAL 时,列会在读取时计算且不占用存储;指定 STORED 时,列会在写入时计算并存储在磁盘上。默认是 VIRTUAL。 - + 必须使用关键字STORED,表示该列将在写入时计算并存储在磁盘上。 生成表达式可以引用表中的其他列,但不能引用其他生成的列。使用的任何函数和操作符都必须是不可变的。不允许引用其他表。 - - - 虚拟生成列不能使用用户定义类型,且其生成表达式不得引用用户定义函数或类型,也就是只能使用内置函数或类型。此限制也包含间接使用(例如操作符或类型转换背后的函数或类型)。该限制不适用于存储型生成列。 - @@ -746,38 +708,17 @@ WITH ( MODULUS numeric_literal, REM - UNIQUE [ NULLS [ NOT ] DISTINCT ](列约束) - - - UNIQUE [ NULLS [ NOT ] DISTINCT ] ( column_name [, ... ] [, column_name WITHOUT OVERLAPS ] ) - INCLUDE ( column_name [, ...]) (表约束) - + UNIQUE [ NULLS [ NOT ] DISTINCT ] ( column_name [, ... ] ) + INCLUDE ( column_name [, ...]) (表约束) - UNIQUE 约束指定表中一列或多列组成的一组只能包含唯一值。 表级唯一约束的行为与列级唯一约束相同,只是它还能跨越多列。因此,该约束 要求任意两行在这些列中至少有一列不同。 - - 如果为最后一列指定了 WITHOUT OVERLAPS 选项,则该列检查的 - 是是否重叠,而不是是否相等。在这种情况下,只要重复值在 - WITHOUT OVERLAPS 列上不发生重叠,约束中的其他列就允许重 - 复。(如果该列是日期或时间戳范围,这有时被称为时态键;但 - PostgreSQL 允许在任意基础类型上定义范围。) - 实际上,这种约束是通过 EXCLUDE 约束而不是 - UNIQUE 约束来强制的。例如, - UNIQUE (id, valid_at WITHOUT OVERLAPS) 的行为类似于 - EXCLUDE USING GIST (id WITH =, valid_at WITH &&)。 - WITHOUT OVERLAPS 列必须是范围类型或多范围类型,且不允许 - 为空范围或空多范围。该约束中不带 WITHOUT OVERLAPS 的列可以 - 是任何可在 GiST 索引中按相等性比较的类型。默认仅支持范围类型,但可通过安装 - 扩展来使用其他类型(这也是该特性的预期用法)。 - - 就唯一约束而言,空值不被视为相等,除非指定了 NULLS NOT DISTINCT。 @@ -787,20 +728,17 @@ WITH ( MODULUS numeric_literal, REM 每个唯一约束都应引用一组列,这组列应不同于该表上任何其他唯一约束或 主键约束所引用的列集合。(否则,冗余的唯一约束将被丢弃。) + 在为多级分区层次结构建立唯一约束时,目标分区表分区键中的所有列,以及 其所有后代分区表分区键中的所有列,都必须包含在约束定义中。 - - 添加唯一约束会自动在约束所用的列或列组上创建唯一 B-树索引;但如果该约束 - 包含 WITHOUT OVERLAPS 子句,则会使用 GiST 索引。所创建 - 的索引与该唯一约束同名。 - + 添加唯一约束会自动在约束所用的列或列组上创建唯一 B-树索引。所创建的索引与该唯一约束同名。 可选的 INCLUDE 子句会向该索引添加一个或多个仅作为 - payload 的列:对这些列不强制唯一性,而且该索引也不能据此 + 载荷 的列:对这些列不强制唯一性,而且该索引也不能据此 进行搜索。不过,它们可以通过仅索引扫描取回。注意,尽管约束不在包含列上 强制执行,它仍然依赖于这些列。因此,对这类列执行某些操作(例如 DROP COLUMN)可能导致约束和索引被级联删除。 @@ -809,13 +747,10 @@ WITH ( MODULUS numeric_literal, REM - PRIMARY KEY(列约束) - - PRIMARY KEY ( column_name [, ... ] [, column_name WITHOUT OVERLAPS ] ) - INCLUDE ( column_name [, ...]) (表约束) + PRIMARY KEY ( column_name [, ... ] ) + INCLUDE ( column_name [, ...]) (表约束) - PRIMARY KEY 约束指定表的一列或多列只能包含唯一 (不重复)且非空的值。无论作为列约束还是表约束,一个表都只能指定一个 @@ -841,13 +776,11 @@ WITH ( MODULUS numeric_literal, REM 添加 PRIMARY KEY 约束会自动在约束所用的列或列组上创建 - 唯一 B-树索引;如果指定了 WITHOUT OVERLAPS,则会创建 - GiST 索引。 - + 唯一 B-树索引。该索引与主键约束同名。 可选的 INCLUDE 子句会向该索引添加一个或多个仅作为 - payload 的列:对这些列不强制唯一性,而且该索引也不能据此 + 载荷 的列:对这些列不强制唯一性,而且该索引也不能据此 进行搜索。不过,它们可以通过仅索引扫描取回。注意,尽管约束不在包含列上 强制执行,它仍然依赖于这些列。因此,对这类列执行某些操作(例如 DROP COLUMN)可能导致约束和索引被级联删除。 @@ -858,7 +791,6 @@ WITH ( MODULUS numeric_literal, REM EXCLUDE [ USING index_method ] ( exclude_element WITH operator [, ... ] ) index_parameters [ WHERE ( predicate ) ] - EXCLUDE 子句定义一个排他约束。它保证如果任意两行在 指定列或表达式上使用指定操作符进行比较,这些比较不会全部返回 @@ -883,7 +815,7 @@ WITH ( MODULUS numeric_literal, REM 访问方法必须支持 amgettuple(见 );目前这意味着不能使用 GIN。 虽然允许,但在排他约束上使用 B-树或 hash 索引意义不大,因为它们做不到 - 比普通唯一约束更好的事情。因此,实践中访问方法几乎总会是 + 比普通唯一约束更好的事情。因此,实践中访问方法总是 GiSTSP-GiST @@ -892,6 +824,7 @@ WITH ( MODULUS numeric_literal, REM 子集上指定排他约束;在内部,这会创建一个部分索引。注意, predicate 周围的圆括号是必需的。 + 在为多级分区层次结构建立排他约束时,目标分区表分区键中的所有列,以及其 所有后代分区表分区键中的所有列,都必须包含在约束定义中。此外,这些列必 @@ -903,56 +836,17 @@ WITH ( MODULUS numeric_literal, REM - REFERENCES reftable [ ( refcolumn ) ] [ MATCH matchtype ] [ ON DELETE referential_action ] [ ON UPDATE referential_action ](列约束) - FOREIGN KEY ( column_name [, ... ] [, PERIOD column_name ] ) - REFERENCES reftable [ ( refcolumn [, ... ] [, PERIOD refcolumn ] ) ] - [ MATCH matchtype ] - [ ON DELETE referential_action ] - [ ON UPDATE referential_action ] + FOREIGN KEY ( column_name [, ... ] ) + REFERENCES reftable [ ( refcolumn [, ... ] ) ] + [ MATCH matchtype ] + [ ON DELETE referential_action ] + [ ON UPDATE referential_action ] (表约束) - - - 这些子句指定外键约束,要求新表的一列或多列组成的一组只能包含与被引用 - 表某一行的被引用列中值相匹配的值。若省略 - refcolumn 列表,则使用 - reftable 的主键。否则, - refcolumn 列表必须引用某个不可延 - 迟的唯一约束或主键约束的列,或者引用某个非部分唯一索引的列。 - - - - 如果最后一列标记为 PERIOD,则会按特殊方式处理。非 - PERIOD 列按相等性比较(并且至少需要一列),而 - PERIOD 列则不会。取而代之的是,只有当被引用表中基于键的 - 非 PERIOD 部分相匹配的记录,其合并后的 - PERIOD 值能够完整覆盖引用记录的 - PERIOD 值时,约束才算满足。换言之,该引用在其整个持续区 - 间内都必须有对应的被引用对象。该列必须是范围类型或多范围类型。此外,被 - 引用表必须具有用 WITHOUT OVERLAPS 声明的主键或唯一约 - 束。最后,如果外键包含 PERIOD - column_name 说明,则对应的 - refcolumn(如果存在)也必须标记 - 为 PERIOD。如果省略 - refcolumn 子句,从而选择 - reftable 的主键约束,则该主键的最后一列必须标记为 - WITHOUT OVERLAPS。 - - - - 对于每一对引用列和被引用列,如果它们属于可排序数据类型,则两者的排序规 - 则要么都必须是确定性的,要么必须完全相同。这样可以确保两列对“相等”具 - 有一致的定义。 - - - 用户必须对被引用表拥有 REFERENCES 权限(对整张表,或对 - 特定的被引用列)。添加外键约束需要在被引用表上获取 - SHARE ROW EXCLUSIVE 锁。注意,不能在临时表和永久表之间 - 定义外键约束。 - + 这些子句指定外键约束,要求新表中由一个或多个列组成的列组只能包含与被引用表中某一行的被引用列中的值相匹配的值。如果省略refcolumn列表,则使用reftable的主键。否则,refcolumn列表必须引用不可延迟的唯一约束或主键约束的列,或者是非部分唯一索引的列。用户必须拥有被引用表的REFERENCES权限(可以针对整个表,也可以针对具体的被引用列)。添加外键约束需要在被引用表上获取SHARE ROW EXCLUSIVE锁。请注意,不能在临时表和永久表之间定义外键约束。 插入到引用列中的值会按照给定的匹配类型,与被引用表及其被引用列中的值进 @@ -966,39 +860,18 @@ WITH ( MODULUS numeric_literal, REM NOT NULL 约束,以防止出现这些情况。) - - 此外,当被引用列中的数据发生变化时,会对本表列中的数据执行某些操作。 - ON DELETE 子句指定当被引用表中的被引用行被删除时要执行 - 的操作。同样,ON UPDATE 子句指定当被引用表中的被引用列 - 被更新为新值时要执行的操作。如果更新了行,但被引用列实际上并未改变,则 - 不执行任何操作。引用动作作为数据更改命令的一部分执行,即使该约束是延迟 - 的也一样。每个子句可用的操作如下: - - + 此外,当被引用列中的数据发生变化时,会对本表列中的数据执行某些操作。ON DELETE子句指定删除被引用表中的被引用行时要执行的操作。同样,ON UPDATE子句指定将被引用表中的被引用列更新为新值时要执行的操作。如果行被更新,但被引用列实际上没有变化,则不执行任何操作。除NO ACTION检查以外的引用操作都不能延迟,即使该约束声明为可延迟也是如此。每个子句可以指定以下操作: NO ACTION - - 如果删除或更新会导致外键约束违规,则产生错误。如果约束被延迟,且到 - 约束检查时仍然存在任何引用行,就会产生此错误。 - 这是默认操作。 - + 产生错误,指出删除或更新会违反外键约束。如果该约束被延迟,则会在约束检查时仍存在引用行的情况下产生这个错误。这是默认操作。 RESTRICT - - 如果待删除或更新的行在引用表中有匹配行,则产生错误。即使操作完成后 - 的状态并不违反外键约束,也会阻止该操作。特别地,它会阻止将被引用行 - 更新为“值不同但比较相等”的情况。(但不会阻止把列更新为相同值的 - 无操作更新。) - - - - 对于时态外键,该选项不受支持。 - + 产生错误,指出删除或更新会违反外键约束。这与NO ACTION相同,但检查不能延迟。 @@ -1008,10 +881,6 @@ WITH ( MODULUS numeric_literal, REM 分别删除任何引用已删除行的行,或将引用列的值更新为被引用列的新值。 - - - 对于时态外键,该选项不受支持。 - @@ -1022,10 +891,6 @@ WITH ( MODULUS numeric_literal, REM 将全部引用列,或指定的引用列子集,设置为空值。只有 ON DELETE 动作才能指定列子集。 - - - 对于时态外键,该选项不受支持。 - @@ -1037,19 +902,12 @@ WITH ( MODULUS numeric_literal, REM ON DELETE 动作才能指定列子集。(如果默认值不是空 值,则被引用表中必须有一行与这些默认值匹配,否则该操作会失败。) - - - 对于时态外键,该选项不受支持。 - - - 如果被引用列经常发生变化,那么最好在引用列上添加一个索引,以便更高效地 - 执行与该外键约束相关的引用动作。 - + 如果被引用列经常变化,可以考虑在引用列上添加索引,使与外键约束关联的引用操作能够更高效地执行。 @@ -1088,24 +946,6 @@ WITH ( MODULUS numeric_literal, REM - - ENFORCED - NOT ENFORCED - - - 当约束为 ENFORCED 时,数据库系统会在适当时机检查该约束(按需要在每条语句后或事务结束时),这是默认行为。若约束为 NOT ENFORCED,数据库系统将不再检查该约束,改由应用代码保证约束成立。对于不影响结果正确性的优化决策,数据库系统仍可能假定数据满足该约束。 - - - - NOT ENFORCED 约束可作为文档用途,适用于运行时检查约束代价过高的场景。 - - - - 当前该能力仅支持外键约束与 CHECK 约束。 - - - - USING method @@ -1221,11 +1061,10 @@ WITH ( MODULUS numeric_literal, REM - 存储参数 - storage parameters + 存储参数 @@ -1244,10 +1083,9 @@ WITH ( MODULUS numeric_literal, REM - fillfactor (integer) - fillfactor storage parameter + fillfactor 存储参数 @@ -1266,18 +1104,16 @@ WITH ( MODULUS numeric_literal, REM - toast_tuple_target (integer) - toast_tuple_target storage parameter + toast_tuple_target 存储参数 - toast_tuple_target 指定在尝试压缩和/或将长列值移入 TOAST 表之前所需的最小元组长度,同时也是一旦开始 TOAST 化后试图将长度 - 缩减到的目标长度。这会影响标记为 External(用于移动)、Main(用于压缩) + 缩减到其以下的目标长度。这会影响标记为 External(用于移动)、Main(用于压缩) 或 Extended(用于两者)的列,并且只适用于新元组。对现有行没有影响。默认 情况下,该参数被设置为至少允许每个块容纳 4 个元组,在默认块大小下即为 2040 字节。有效值介于 128 字节与(块大小减去页头)之间,默认上限为 @@ -1289,16 +1125,14 @@ WITH ( MODULUS numeric_literal, REM - parallel_workers (integer) - parallel_workers storage parameter + parallel_workers 存储参数 - - 该参数设置在对该表执行并行扫描时可用于辅助扫描的工作进程数量。若未设置, + 该参数设置在对该表执行并行扫描时用于辅助扫描的工作进程数量。若未设置, 系统会根据关系大小决定一个值。规划器或使用并行扫描的实用命令实际选择的 工作进程数量可能更少,例如可能受 设置所限。 @@ -1307,10 +1141,9 @@ WITH ( MODULUS numeric_literal, REM - autovacuum_enabled, toast.autovacuum_enabled (boolean) - autovacuum_enabled storage parameter + autovacuum_enabled 存储参数 @@ -1330,10 +1163,9 @@ WITH ( MODULUS numeric_literal, REM - vacuum_index_cleanup, toast.vacuum_index_cleanup (enum) - vacuum_index_cleanup storage parameter + vacuum_index_cleanup 存储参数 @@ -1353,19 +1185,16 @@ WITH ( MODULUS numeric_literal, REM - vacuum_truncate, toast.vacuum_truncate (boolean) - vacuum_truncate - storage parameter + vacuum_truncate 存储参数 - - 启用或禁用 vacuum 尝试截去该表末尾的空页。默认值为 + 允许或禁止清理尝试截去该表末尾的空页。默认值为 true。若为 true, - VACUUM 和 autovacuum 都会执行截断,并将被截断页面占用的磁盘空间返还给操作系统。注意,截断操作需要对表持有 + VACUUM 和自动清理都会执行截断,并将被截断页面占用的磁盘空间返还给操作系统。注意,截断操作需要对表持有 ACCESS EXCLUSIVE 锁。若在 VACUUM 中指定了 TRUNCATE 参数,则会覆盖此选项的值。 @@ -1374,11 +1203,10 @@ WITH ( MODULUS numeric_literal, REM - autovacuum_vacuum_threshold, toast.autovacuum_vacuum_threshold (integer) autovacuum_vacuum_threshold - storage parameter + 存储参数 @@ -1387,14 +1215,13 @@ WITH ( MODULUS numeric_literal, REM 参数的每表取值。 - + - autovacuum_vacuum_scale_factor, toast.autovacuum_vacuum_scale_factor (floating point) autovacuum_vacuum_scale_factor - storage parameter + 存储参数 @@ -1406,11 +1233,10 @@ WITH ( MODULUS numeric_literal, REM - autovacuum_vacuum_insert_threshold, toast.autovacuum_vacuum_insert_threshold (integer) autovacuum_vacuum_insert_threshold - storage parameter + 存储参数 @@ -1423,11 +1249,10 @@ WITH ( MODULUS numeric_literal, REM - autovacuum_vacuum_insert_scale_factor, toast.autovacuum_vacuum_insert_scale_factor (floating point) autovacuum_vacuum_insert_scale_factor - storage parameter + 存储参数 @@ -1439,11 +1264,10 @@ WITH ( MODULUS numeric_literal, REM - autovacuum_analyze_threshold (integer) autovacuum_analyze_threshold - storage parameter + 存储参数 @@ -1455,11 +1279,10 @@ WITH ( MODULUS numeric_literal, REM - autovacuum_analyze_scale_factor (floating point) autovacuum_analyze_scale_factor - storage parameter + 存储参数 @@ -1471,11 +1294,10 @@ WITH ( MODULUS numeric_literal, REM - autovacuum_vacuum_cost_delay, toast.autovacuum_vacuum_cost_delay (floating point) autovacuum_vacuum_cost_delay - storage parameter + 存储参数 @@ -1487,11 +1309,10 @@ WITH ( MODULUS numeric_literal, REM - autovacuum_vacuum_cost_limit, toast.autovacuum_vacuum_cost_limit (integer) autovacuum_vacuum_cost_limit - storage parameter + 存储参数 @@ -1503,10 +1324,9 @@ WITH ( MODULUS numeric_literal, REM - autovacuum_freeze_min_age, toast.autovacuum_freeze_min_age (integer) - autovacuum_freeze_min_age storage parameter + autovacuum_freeze_min_age 存储参数 @@ -1520,11 +1340,10 @@ WITH ( MODULUS numeric_literal, REM - autovacuum_freeze_max_age, toast.autovacuum_freeze_max_age (integer) autovacuum_freeze_max_age - storage parameter + 存储参数 @@ -1538,10 +1357,9 @@ WITH ( MODULUS numeric_literal, REM - autovacuum_freeze_table_age, toast.autovacuum_freeze_table_age (integer) - autovacuum_freeze_table_age storage parameter + autovacuum_freeze_table_age 存储参数 @@ -1553,10 +1371,9 @@ WITH ( MODULUS numeric_literal, REM - autovacuum_multixact_freeze_min_age, toast.autovacuum_multixact_freeze_min_age (integer) - autovacuum_multixact_freeze_min_age storage parameter + autovacuum_multixact_freeze_min_age 存储参数 @@ -1571,11 +1388,10 @@ WITH ( MODULUS numeric_literal, REM - autovacuum_multixact_freeze_max_age, toast.autovacuum_multixact_freeze_max_age (integer) autovacuum_multixact_freeze_max_age - storage parameter + 存储参数 @@ -1590,10 +1406,9 @@ WITH ( MODULUS numeric_literal, REM - autovacuum_multixact_freeze_table_age, toast.autovacuum_multixact_freeze_table_age (integer) - autovacuum_multixact_freeze_table_age storage parameter + autovacuum_multixact_freeze_table_age 存储参数 @@ -1605,11 +1420,10 @@ WITH ( MODULUS numeric_literal, REM - log_autovacuum_min_duration, toast.log_autovacuum_min_duration (integer) log_autovacuum_min_duration - storage parameter + 存储参数 @@ -1618,13 +1432,12 @@ WITH ( MODULUS numeric_literal, REM 参数的每表取值。 - + - user_catalog_table (boolean) - user_catalog_table storage parameter + user_catalog_table 存储参数 @@ -1642,11 +1455,9 @@ WITH ( MODULUS numeric_literal, REM - 注解 - - PostgreSQL为每一个唯一约束和主键约束创建一个索引来强制唯一性。因此,没有必要显式地为主键列创建一个索引(详见)。 + PostgreSQL为每一个唯一约束和主键约束自动创建一个索引来强制唯一性。因此,没有必要显式地为主键列创建一个索引(详见)。 @@ -1659,6 +1470,7 @@ WITH ( MODULUS numeric_literal, REM + 示例 @@ -1968,7 +1780,6 @@ CREATE TABLE cities_partdef - 兼容性 @@ -2071,19 +1882,17 @@ CREATE TABLE cities_partdef - <literal>NULL</literal> <quote>约束</quote> NULL 约束(实际上并不是约束)是 - PostgreSQL 对 SQL 标准的扩展;它也被其他一些数 - 据库系统采纳,以便兼容(以及与对称的 NOT NULL 约束保持一 - 致)。由于它本来就是任意列的默认值,所以它的存在只是噪声。 + PostgreSQL 对 SQL 标准的扩展;提供它是为了 + 与其他一些数据库系统兼容(以及与 NOT NULL 约束保持 + 对称)。由于它本来就是任意列的默认情况,所以它的存在只是噪声。 - 约束命名 @@ -2095,6 +1904,10 @@ CREATE TABLE cities_partdef 名,而索引名称在同一模式内的所有关系之间必须唯一。 + + 目前,PostgreSQL 根本不会记录非空约束的名称, + 因此这些约束不受名称唯一性限制。这种情况可能会在未来版本中改变。 + @@ -2107,38 +1920,33 @@ CREATE TABLE cities_partdef - - 零列表 + 零列的表 PostgreSQL 允许创建没有列的表(例如 CREATE TABLE foo();)。这是对 SQL 标准的扩展,标准不允许 - 零列表。零列表本身并不十分有用,但若禁止它们,就会让 + 零列的表。零列的表本身并不十分有用,但若禁止它们,就会让 ALTER TABLE DROP COLUMN 出现奇怪的特殊情况,因此忽略这 一规范限制看起来更整洁。 - 多个标识列 PostgreSQL 允许一个表拥有多个标识列。 该标准指定一个表最多只能有一个标识列。 - 这主要是为了给模式更改或迁移提供更大的灵活性。 + 放宽这一限制主要是为了给模式更改或迁移提供更大的灵活性。 请注意,INSERT 命令仅支持一个适用于整个语句的覆盖子 句,因此对行为不同的多个标识列支持并不好。 - 生成列 - - STOREDVIRTUAL 选项都不是标准的一部分,但其他 SQL 实现也会使用。SQL 标准并不规定生成列的存储方式。 - + STORED选项不是标准的一部分,但其他 SQL 实现也使用它。SQL 标准没有规定生成列的存储方式。 @@ -2175,12 +1983,10 @@ CREATE TABLE cities_partdef - 类型化表 - 类型化表实现了 SQL 标准的一个子集。按照标准,类型化表除了具有与底层组合 - 类型相对应的列之外,还应有一个额外的自引用列。 + 类型化表实现了 SQL 标准的一个子集。按照标准,类型化表除了具有与底层复合类型相对应的列之外,还应有一个额外的自引用列PostgreSQL 不显式支持自引用列。 @@ -2207,6 +2013,7 @@ CREATE TABLE cities_partdef + 另见 diff --git a/zh/17/ref/create_table_as.sgml b/zh/17/ref/create_table_as.sgml index 7d80a1f0..03a60483 100644 --- a/zh/17/ref/create_table_as.sgml +++ b/zh/17/ref/create_table_as.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation CREATE TABLE AS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/create_tablespace.sgml b/zh/17/ref/create_tablespace.sgml index 32b0dbb1..88106ccd 100644 --- a/zh/17/ref/create_tablespace.sgml +++ b/zh/17/ref/create_tablespace.sgml @@ -13,7 +13,7 @@ PostgreSQL documentation CREATE TABLESPACE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/create_transform.sgml b/zh/17/ref/create_transform.sgml index 247e6a0f..ecea2c1e 100644 --- a/zh/17/ref/create_transform.sgml +++ b/zh/17/ref/create_transform.sgml @@ -13,7 +13,7 @@ PostgreSQL documentation CREATE TRANSFORM 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/create_trigger.sgml b/zh/17/ref/create_trigger.sgml index 236c79c4..9f177700 100644 --- a/zh/17/ref/create_trigger.sgml +++ b/zh/17/ref/create_trigger.sgml @@ -11,13 +11,13 @@ PostgreSQL documentation 过渡表 - ephemeral named relation + 临时命名关系 CREATE TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -70,7 +70,7 @@ CREATE [ OR REPLACE ] [ CONSTRAINT ] TRIGGER name UPDATEDELETE之前); 也可以在该操作完成之后引发(即在检查约束以及完成 INSERTUPDATE或 - DELETE之后);或者改为执行该操作 + DELETE之后);或者取代该操作执行 (用于视图上的插入、更新或删除)。如果触发器在事件之前引发,或者改为取代该事件执行, 则它可以跳过对当前行的操作,或者修改待插入的行 (仅适用于INSERTUPDATE操作)。 @@ -178,7 +178,7 @@ CREATE [ OR REPLACE ] [ CONSTRAINT ] TRIGGER name 调整其引发时机。约束触发器必须是普通表(不是外部表)上的 AFTER ROW 触发器。它们既可以在导致触发事件的语句结束时引发, 也可以在包含它的事务结束时引发;后一种情况称为延迟。 - 也可以使用SET CONSTRAINTS强制挂起的延迟触发立即引发。 + 也可以使用SET CONSTRAINTS强制尚待执行的延迟触发器立即引发。 约束触发器应当在其所实现的约束遭到违反时抛出异常。 @@ -394,7 +394,7 @@ UPDATE OF column_name1 [, column_name2CREATE TRIGGER的语法中,关键字 FUNCTIONPROCEDURE 是等价的, 但无论如何,被引用的对象都必须是函数而不是过程。 - 这里使用 PROCEDURE 关键字只是出于历史原因,并且已被废弃。 + 这里使用 PROCEDURE 关键字只是出于历史原因,并且已被弃用。 diff --git a/zh/17/ref/create_tsconfig.sgml b/zh/17/ref/create_tsconfig.sgml index 52c43127..52970b36 100644 --- a/zh/17/ref/create_tsconfig.sgml +++ b/zh/17/ref/create_tsconfig.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TEXT SEARCH CONFIGURATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/create_tsdictionary.sgml b/zh/17/ref/create_tsdictionary.sgml index 7a06b430..c45a7240 100644 --- a/zh/17/ref/create_tsdictionary.sgml +++ b/zh/17/ref/create_tsdictionary.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TEXT SEARCH DICTIONARY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/create_tsparser.sgml b/zh/17/ref/create_tsparser.sgml index d0c11ba5..358152ce 100644 --- a/zh/17/ref/create_tsparser.sgml +++ b/zh/17/ref/create_tsparser.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TEXT SEARCH PARSER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/create_tstemplate.sgml b/zh/17/ref/create_tstemplate.sgml index 947b18b9..702233e4 100644 --- a/zh/17/ref/create_tstemplate.sgml +++ b/zh/17/ref/create_tstemplate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TEXT SEARCH TEMPLATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/create_type.sgml b/zh/17/ref/create_type.sgml index 45a4d93a..879d0a86 100644 --- a/zh/17/ref/create_type.sgml +++ b/zh/17/ref/create_type.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation CREATE TYPE 7 - SQL - Language Statements + SQL - 语言语句 @@ -96,7 +96,7 @@ CREATE TYPE name 复合类型 - 第一种形式的CREATE TYPE创建复合类型。组合 + 第一种形式的CREATE TYPE创建复合类型。复合 类型由属性名和数据类型列表指定。如果某个属性的数据类型支持排序规 则,还可以指定该属性的排序规则。复合类型本质上与表的行类型相同, 但如果目的只是定义一种类型,使用CREATE TYPE @@ -322,7 +322,7 @@ CREATE TYPE name 数才知道,但仍有若干内部表示属性必须向 PostgreSQL声明。其中最重要的是 internallength。 - 基础数据类型可以是定长的,此时internallength为正整数;也可 以是变长的,此时将internallength设为 @@ -427,7 +427,7 @@ CREATE TYPE name collatable为真,则 该类型的列定义和表达式可以通过COLLATE子句携 带排序规则信息。是否实际使用这些排序规则信息取决于操作该类型的函 - 数实现;仅仅把类型标记为 collatable 并不会自动实现这一点。 + 数实现;仅仅把类型标记为支持排序规则并不会自动实现这一点。 @@ -876,7 +876,7 @@ CREATE TYPE float8_range AS RANGE (subtype = float8, subtype_diff = float8mi); - 这个示例创建基础数据类型box,然后在表定义中使用它: + 这个示例创建基础类型box,然后在表定义中使用它: CREATE TYPE box; diff --git a/zh/17/ref/create_user.sgml b/zh/17/ref/create_user.sgml index 218c51eb..9548a147 100644 --- a/zh/17/ref/create_user.sgml +++ b/zh/17/ref/create_user.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE USER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/create_user_mapping.sgml b/zh/17/ref/create_user_mapping.sgml index fe556318..1abe6abd 100644 --- a/zh/17/ref/create_user_mapping.sgml +++ b/zh/17/ref/create_user_mapping.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE USER MAPPING 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/create_view.sgml b/zh/17/ref/create_view.sgml index 80c6d1ab..292b1a4b 100644 --- a/zh/17/ref/create_view.sgml +++ b/zh/17/ref/create_view.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation CREATE VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/createdb.sgml b/zh/17/ref/createdb.sgml index 554d7377..0a70cb6a 100644 --- a/zh/17/ref/createdb.sgml +++ b/zh/17/ref/createdb.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation createdb 1 - Application + 应用程序 diff --git a/zh/17/ref/createuser.sgml b/zh/17/ref/createuser.sgml index 0451cadd..eba45357 100644 --- a/zh/17/ref/createuser.sgml +++ b/zh/17/ref/createuser.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation createuser 1 - Application + 应用程序 @@ -139,7 +139,7 @@ PostgreSQL documentation - (已废弃) + (已弃用) diff --git a/zh/17/ref/deallocate.sgml b/zh/17/ref/deallocate.sgml index 27b9da86..6dea341e 100644 --- a/zh/17/ref/deallocate.sgml +++ b/zh/17/ref/deallocate.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation DEALLOCATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/declare.sgml b/zh/17/ref/declare.sgml index ed389e4d..9276a0e3 100644 --- a/zh/17/ref/declare.sgml +++ b/zh/17/ref/declare.sgml @@ -22,7 +22,7 @@ PostgreSQL documentation DECLARE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/delete.sgml b/zh/17/ref/delete.sgml index 4a79783c..653e86a2 100644 --- a/zh/17/ref/delete.sgml +++ b/zh/17/ref/delete.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DELETE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/discard.sgml b/zh/17/ref/discard.sgml index 29d4ea8d..f6572252 100644 --- a/zh/17/ref/discard.sgml +++ b/zh/17/ref/discard.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DISCARD 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/do.sgml b/zh/17/ref/do.sgml index 2ea6566a..cdbf189e 100644 --- a/zh/17/ref/do.sgml +++ b/zh/17/ref/do.sgml @@ -15,7 +15,7 @@ PostgreSQL documentation DO 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/drop_access_method.sgml b/zh/17/ref/drop_access_method.sgml index 407ec4cd..646100e1 100644 --- a/zh/17/ref/drop_access_method.sgml +++ b/zh/17/ref/drop_access_method.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP ACCESS METHOD 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/drop_aggregate.sgml b/zh/17/ref/drop_aggregate.sgml index 1c8a1122..9fd7ea4b 100644 --- a/zh/17/ref/drop_aggregate.sgml +++ b/zh/17/ref/drop_aggregate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP AGGREGATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/drop_cast.sgml b/zh/17/ref/drop_cast.sgml index 73860e3c..5e330ae0 100644 --- a/zh/17/ref/drop_cast.sgml +++ b/zh/17/ref/drop_cast.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP CAST 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/drop_collation.sgml b/zh/17/ref/drop_collation.sgml index b90849fc..b10b3206 100644 --- a/zh/17/ref/drop_collation.sgml +++ b/zh/17/ref/drop_collation.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP COLLATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/drop_conversion.sgml b/zh/17/ref/drop_conversion.sgml index b63d1291..35009708 100644 --- a/zh/17/ref/drop_conversion.sgml +++ b/zh/17/ref/drop_conversion.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP CONVERSION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/drop_database.sgml b/zh/17/ref/drop_database.sgml index 9bbd949f..10817b69 100644 --- a/zh/17/ref/drop_database.sgml +++ b/zh/17/ref/drop_database.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP DATABASE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/drop_domain.sgml b/zh/17/ref/drop_domain.sgml index d43f95c6..b292b189 100644 --- a/zh/17/ref/drop_domain.sgml +++ b/zh/17/ref/drop_domain.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP DOMAIN 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/drop_event_trigger.sgml b/zh/17/ref/drop_event_trigger.sgml index 80020f78..f4f0053f 100644 --- a/zh/17/ref/drop_event_trigger.sgml +++ b/zh/17/ref/drop_event_trigger.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP EVENT TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -30,7 +30,7 @@ DROP EVENT TRIGGER [ IF EXISTS ] name DROP EVENT TRIGGER移除一个现有的事件触发器。 - 要执行此命令,当前用户必须是该事件触发器的拥有者。 + 要执行此命令,当前用户必须是该事件触发器的所有者。 @@ -99,7 +99,7 @@ DROP EVENT TRIGGER snitch; - 另见 + 参见 diff --git a/zh/17/ref/drop_extension.sgml b/zh/17/ref/drop_extension.sgml index 5eb04c04..ccccb0b1 100644 --- a/zh/17/ref/drop_extension.sgml +++ b/zh/17/ref/drop_extension.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP EXTENSION 7 - SQL - Language Statements + SQL - 语言语句 @@ -59,8 +59,8 @@ DROP EXTENSION [ IF EXISTS ] name [ name - 已安装扩展的名称。 - + 一个已安装扩展的名称。 + @@ -95,7 +95,7 @@ DROP EXTENSION [ IF EXISTS ] name [ DROP EXTENSION hstore; - 如果数据库中正在使用hstore的任何对象, + 如果数据库中使用了hstore的任何对象, 例如某些表具有hstore类型的列,则该命令会失败。 加上CASCADE选项可以强制一并移除这些依赖对象。 diff --git a/zh/17/ref/drop_foreign_data_wrapper.sgml b/zh/17/ref/drop_foreign_data_wrapper.sgml index 9902c875..6f781f31 100644 --- a/zh/17/ref/drop_foreign_data_wrapper.sgml +++ b/zh/17/ref/drop_foreign_data_wrapper.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP FOREIGN DATA WRAPPER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/drop_foreign_table.sgml b/zh/17/ref/drop_foreign_table.sgml index 0b4d0bbd..c420e4ba 100644 --- a/zh/17/ref/drop_foreign_table.sgml +++ b/zh/17/ref/drop_foreign_table.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP FOREIGN TABLE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/drop_function.sgml b/zh/17/ref/drop_function.sgml index 32e1de58..f80cc1d8 100644 --- a/zh/17/ref/drop_function.sgml +++ b/zh/17/ref/drop_function.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP FUNCTION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/drop_group.sgml b/zh/17/ref/drop_group.sgml index f43389ca..4ee8fc55 100644 --- a/zh/17/ref/drop_group.sgml +++ b/zh/17/ref/drop_group.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP GROUP 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/drop_index.sgml b/zh/17/ref/drop_index.sgml index b65b810b..d7f892d9 100644 --- a/zh/17/ref/drop_index.sgml +++ b/zh/17/ref/drop_index.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP INDEX 7 - SQL - Language Statements + SQL - 语言语句 @@ -57,7 +57,7 @@ DROP INDEX [ CONCURRENTLY ] [ IF EXISTS ] name 对于临时表,DROP INDEX始终是非并发的, - 因为没有其他会话可以访问它们,而且非并发删除索引的成本更低。 + 因为没有其他会话可以访问它们,而且非并发删除索引的代价更低。 @@ -66,7 +66,7 @@ DROP INDEX [ CONCURRENTLY ] [ IF EXISTS ] nameIF EXISTS - 如果该索引不存在,则不要抛出错误。这种情况下会发出一个提示。 + 如果该索引不存在,则不要抛出错误。这种情况下会发出一条提示。 diff --git a/zh/17/ref/drop_language.sgml b/zh/17/ref/drop_language.sgml index 9696f612..8fb4de3f 100644 --- a/zh/17/ref/drop_language.sgml +++ b/zh/17/ref/drop_language.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP LANGUAGE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/drop_materialized_view.sgml b/zh/17/ref/drop_materialized_view.sgml index f3682552..71ad4326 100644 --- a/zh/17/ref/drop_materialized_view.sgml +++ b/zh/17/ref/drop_materialized_view.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP MATERIALIZED VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/drop_opclass.sgml b/zh/17/ref/drop_opclass.sgml index c3dd2e74..9d67dc64 100644 --- a/zh/17/ref/drop_opclass.sgml +++ b/zh/17/ref/drop_opclass.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP OPERATOR CLASS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/drop_operator.sgml b/zh/17/ref/drop_operator.sgml index 3cfb069c..19e93d4e 100644 --- a/zh/17/ref/drop_operator.sgml +++ b/zh/17/ref/drop_operator.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP OPERATOR 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/drop_opfamily.sgml b/zh/17/ref/drop_opfamily.sgml index 8e7097f9..06223045 100644 --- a/zh/17/ref/drop_opfamily.sgml +++ b/zh/17/ref/drop_opfamily.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP OPERATOR FAMILY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/drop_owned.sgml b/zh/17/ref/drop_owned.sgml index 2bc659bf..3ec24e66 100644 --- a/zh/17/ref/drop_owned.sgml +++ b/zh/17/ref/drop_owned.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP OWNED 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/drop_policy.sgml b/zh/17/ref/drop_policy.sgml index ee64ffa0..a939a688 100644 --- a/zh/17/ref/drop_policy.sgml +++ b/zh/17/ref/drop_policy.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP POLICY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/drop_procedure.sgml b/zh/17/ref/drop_procedure.sgml index 178e6684..19708931 100644 --- a/zh/17/ref/drop_procedure.sgml +++ b/zh/17/ref/drop_procedure.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP PROCEDURE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/drop_publication.sgml b/zh/17/ref/drop_publication.sgml index 6bc4bf59..048c1756 100644 --- a/zh/17/ref/drop_publication.sgml +++ b/zh/17/ref/drop_publication.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP PUBLICATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/drop_role.sgml b/zh/17/ref/drop_role.sgml index 6f3dd022..9fbfa99e 100644 --- a/zh/17/ref/drop_role.sgml +++ b/zh/17/ref/drop_role.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP ROLE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/drop_routine.sgml b/zh/17/ref/drop_routine.sgml index 4f2be77f..db15d5d2 100644 --- a/zh/17/ref/drop_routine.sgml +++ b/zh/17/ref/drop_routine.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP ROUTINE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/drop_rule.sgml b/zh/17/ref/drop_rule.sgml index ddb561f4..2968d946 100644 --- a/zh/17/ref/drop_rule.sgml +++ b/zh/17/ref/drop_rule.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP RULE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/drop_schema.sgml b/zh/17/ref/drop_schema.sgml index 9f622df3..94843c9a 100644 --- a/zh/17/ref/drop_schema.sgml +++ b/zh/17/ref/drop_schema.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP SCHEMA 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/drop_sequence.sgml b/zh/17/ref/drop_sequence.sgml index 4ba78640..586d3038 100644 --- a/zh/17/ref/drop_sequence.sgml +++ b/zh/17/ref/drop_sequence.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP SEQUENCE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/drop_server.sgml b/zh/17/ref/drop_server.sgml index 0864a4c2..8bdacdc8 100644 --- a/zh/17/ref/drop_server.sgml +++ b/zh/17/ref/drop_server.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP SERVER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/drop_statistics.sgml b/zh/17/ref/drop_statistics.sgml index 3120dc06..4773bfa8 100644 --- a/zh/17/ref/drop_statistics.sgml +++ b/zh/17/ref/drop_statistics.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP STATISTICS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/drop_subscription.sgml b/zh/17/ref/drop_subscription.sgml index 67421595..c793c07f 100644 --- a/zh/17/ref/drop_subscription.sgml +++ b/zh/17/ref/drop_subscription.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP SUBSCRIPTION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/drop_table.sgml b/zh/17/ref/drop_table.sgml index a2634c54..bdfbabf4 100644 --- a/zh/17/ref/drop_table.sgml +++ b/zh/17/ref/drop_table.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TABLE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/drop_tablespace.sgml b/zh/17/ref/drop_tablespace.sgml index c8b09e59..a31fd70f 100644 --- a/zh/17/ref/drop_tablespace.sgml +++ b/zh/17/ref/drop_tablespace.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TABLESPACE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/drop_transform.sgml b/zh/17/ref/drop_transform.sgml index be84b60c..09a3c9c7 100644 --- a/zh/17/ref/drop_transform.sgml +++ b/zh/17/ref/drop_transform.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TRANSFORM 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/drop_trigger.sgml b/zh/17/ref/drop_trigger.sgml index 1f85cf41..160a5ebd 100644 --- a/zh/17/ref/drop_trigger.sgml +++ b/zh/17/ref/drop_trigger.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -30,7 +30,7 @@ DROP TRIGGER [ IF EXISTS ] name ON DROP TRIGGER移除一个现有触发器的定义。 - 要执行此命令,当前用户必须是定义该触发器的表的拥有者。 + 要执行此命令,当前用户必须是定义该触发器的表的所有者。 @@ -109,7 +109,7 @@ DROP TRIGGER if_dist_exists ON films; - 另见 + 参见 diff --git a/zh/17/ref/drop_tsconfig.sgml b/zh/17/ref/drop_tsconfig.sgml index 2a7cdc52..ea139802 100644 --- a/zh/17/ref/drop_tsconfig.sgml +++ b/zh/17/ref/drop_tsconfig.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TEXT SEARCH CONFIGURATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/drop_tsdictionary.sgml b/zh/17/ref/drop_tsdictionary.sgml index 1eb24189..316c5d00 100644 --- a/zh/17/ref/drop_tsdictionary.sgml +++ b/zh/17/ref/drop_tsdictionary.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TEXT SEARCH DICTIONARY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/drop_tsparser.sgml b/zh/17/ref/drop_tsparser.sgml index 0cfa7acd..a65f47be 100644 --- a/zh/17/ref/drop_tsparser.sgml +++ b/zh/17/ref/drop_tsparser.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TEXT SEARCH PARSER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/drop_tstemplate.sgml b/zh/17/ref/drop_tstemplate.sgml index 282231c5..fa1faab0 100644 --- a/zh/17/ref/drop_tstemplate.sgml +++ b/zh/17/ref/drop_tstemplate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TEXT SEARCH TEMPLATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/drop_type.sgml b/zh/17/ref/drop_type.sgml index dab5bfa0..2f139da5 100644 --- a/zh/17/ref/drop_type.sgml +++ b/zh/17/ref/drop_type.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TYPE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/drop_user.sgml b/zh/17/ref/drop_user.sgml index 00d1d5f4..2e61d6ef 100644 --- a/zh/17/ref/drop_user.sgml +++ b/zh/17/ref/drop_user.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP USER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/drop_user_mapping.sgml b/zh/17/ref/drop_user_mapping.sgml index 2a79a65b..d23b0a16 100644 --- a/zh/17/ref/drop_user_mapping.sgml +++ b/zh/17/ref/drop_user_mapping.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP USER MAPPING 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/drop_view.sgml b/zh/17/ref/drop_view.sgml index 4feb47e5..8f995245 100644 --- a/zh/17/ref/drop_view.sgml +++ b/zh/17/ref/drop_view.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/dropdb.sgml b/zh/17/ref/dropdb.sgml index 70ad776f..10f79ed2 100644 --- a/zh/17/ref/dropdb.sgml +++ b/zh/17/ref/dropdb.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation dropdb 1 - Application + 应用程序 diff --git a/zh/17/ref/dropuser.sgml b/zh/17/ref/dropuser.sgml index 55aa53fa..3cdd48c0 100644 --- a/zh/17/ref/dropuser.sgml +++ b/zh/17/ref/dropuser.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation dropuser 1 - Application + 应用程序 diff --git a/zh/17/ref/ecpg-ref.sgml b/zh/17/ref/ecpg-ref.sgml index 002b8ef1..506be589 100644 --- a/zh/17/ref/ecpg-ref.sgml +++ b/zh/17/ref/ecpg-ref.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ecpg 1 - Application + 应用程序 diff --git a/zh/17/ref/end.sgml b/zh/17/ref/end.sgml index d042a740..10947ab0 100644 --- a/zh/17/ref/end.sgml +++ b/zh/17/ref/end.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation END 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/execute.sgml b/zh/17/ref/execute.sgml index 2aed0669..5e7274ff 100644 --- a/zh/17/ref/execute.sgml +++ b/zh/17/ref/execute.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation EXECUTE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/explain.sgml b/zh/17/ref/explain.sgml index 5d6ad75a..bb06dcca 100644 --- a/zh/17/ref/explain.sgml +++ b/zh/17/ref/explain.sgml @@ -21,7 +21,7 @@ PostgreSQL documentation EXPLAIN 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/fetch.sgml b/zh/17/ref/fetch.sgml index 71c12406..9ab88c49 100644 --- a/zh/17/ref/fetch.sgml +++ b/zh/17/ref/fetch.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation FETCH 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/grant.sgml b/zh/17/ref/grant.sgml index 90d2b6aa..74073771 100644 --- a/zh/17/ref/grant.sgml +++ b/zh/17/ref/grant.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation GRANT 7 - SQL - Language Statements + SQL - 语言语句 @@ -102,7 +102,7 @@ GRANT role_name [, ...] TO role_specification ] -where role_specification can be: +其中role_specification可以是: [ GROUP ] role_name | PUBLIC diff --git a/zh/17/ref/import_foreign_schema.sgml b/zh/17/ref/import_foreign_schema.sgml index 6e912201..1957d60a 100644 --- a/zh/17/ref/import_foreign_schema.sgml +++ b/zh/17/ref/import_foreign_schema.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation IMPORT FOREIGN SCHEMA 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/initdb.sgml b/zh/17/ref/initdb.sgml index 28ee2e7d..dd5b2375 100644 --- a/zh/17/ref/initdb.sgml +++ b/zh/17/ref/initdb.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation initdb 1 - Application + 应用程序 @@ -208,7 +208,7 @@ PostgreSQL documentation - 当使用 ICU 提供程序时,指定 ICU 区域设置 ID。区域设置支持见 + 当使用 ICU 提供程序时,指定 ICU 区域设置。区域设置支持见 @@ -253,8 +253,7 @@ PostgreSQL documentation 如果builtin, 则必须指定, - 并将其设置为CC.UTF-8或 - PG_UNICODE_FAST。 + 并将其设置为CC.UTF-8 diff --git a/zh/17/ref/insert.sgml b/zh/17/ref/insert.sgml index e3cc2c2e..025d9d82 100644 --- a/zh/17/ref/insert.sgml +++ b/zh/17/ref/insert.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation INSERT 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/listen.sgml b/zh/17/ref/listen.sgml index 0a7c6e23..421010d0 100644 --- a/zh/17/ref/listen.sgml +++ b/zh/17/ref/listen.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation LISTEN 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/load.sgml b/zh/17/ref/load.sgml index bb0adb7c..89bdb114 100644 --- a/zh/17/ref/load.sgml +++ b/zh/17/ref/load.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation LOAD 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/lock.sgml b/zh/17/ref/lock.sgml index bc45eec4..fce3ac96 100644 --- a/zh/17/ref/lock.sgml +++ b/zh/17/ref/lock.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation LOCK 7 - SQL - Language Statements + SQL - 语言语句 @@ -55,7 +55,7 @@ LOCK [ TABLE ] [ ONLY ] name [ * ] 因为SHARE锁模式与写入者获取的ROW EXCLUSIVE锁冲突, 而LOCK TABLE name IN SHARE MODE - 语句会一直等待,直到任何并发持有ROW EXCLUSIVE模式锁的事务提交或回滚。 + 语句会一直等待,直到所有并发持有ROW EXCLUSIVE模式锁的事务提交或回滚。 因此,一旦获得该锁,就不存在尚未提交的写入;而且在释放该锁之前,也不会有新的写入开始。 @@ -166,9 +166,7 @@ LOCK [ TABLE ] [ ONLY ] name [ * ] 这些模式名称通常应理解为:用户打算在被锁定的表中获取行级锁。 此外,ROW EXCLUSIVE模式本身也是一种可共享的表锁。 请记住,就LOCK TABLE而言,所有锁模式的语义完全相同, - 差别只在于哪些模式彼此冲突。关于如何获取真正的行级锁,请参阅 - 文档中的和 - 。 + 差别只在于哪些模式彼此冲突。关于如何获取真正的行级锁,请参阅 (后者位于文档中)。 diff --git a/zh/17/ref/merge.sgml b/zh/17/ref/merge.sgml index c57732bd..bb13669c 100644 --- a/zh/17/ref/merge.sgml +++ b/zh/17/ref/merge.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation MERGE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/move.sgml b/zh/17/ref/move.sgml index e90c1b88..961359c8 100644 --- a/zh/17/ref/move.sgml +++ b/zh/17/ref/move.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation MOVE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/notify.sgml b/zh/17/ref/notify.sgml index 502baccc..a9f72d29 100644 --- a/zh/17/ref/notify.sgml +++ b/zh/17/ref/notify.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation NOTIFY 7 - SQL - Language Statements + SQL - 语言语句 @@ -88,7 +88,7 @@ NOTIFY channel [ , 注解 - 系统中有一个队列,用来保存那些已经发送但尚未被所有监听会话处理的通知。如果这个队列被塞满,那么调用NOTIFY的事务会在提交时失败。该队列非常大(标准安装中为 8GB),几乎足以满足所有用例。不过,如果某个会话执行了LISTEN后又长时间停留在一个事务里,就无法进行清理。一旦队列占用超过一半,你就会在日志文件中看到警告,指出究竟是哪个会话阻碍了清理。在这种情况下,应确保该会话结束其当前事务,以便清理能够继续进行。 + 系统中有一个队列,用来保存那些已经发送但尚未被所有监听会话处理的通知。如果这个队列被塞满,那么调用NOTIFY的事务会在提交时失败。该队列非常大(标准安装中为 8GB),几乎足以满足所有用例。不过,如果某个会话执行了LISTEN后又长时间停留在一个事务里,就无法进行清理。一旦队列占用达到一半,你就会在日志文件中看到警告,指出究竟是哪个会话阻碍了清理。在这种情况下,应确保该会话结束其当前事务,以便清理能够继续进行。 函数pg_notification_queue_usage返回当前被待处理通知占用的队列比例。详见。 diff --git a/zh/17/ref/pg_amcheck.sgml b/zh/17/ref/pg_amcheck.sgml index 855c42dd..55a6e2b7 100644 --- a/zh/17/ref/pg_amcheck.sgml +++ b/zh/17/ref/pg_amcheck.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_amcheck 1 - Application + 应用程序 diff --git a/zh/17/ref/pg_basebackup.sgml b/zh/17/ref/pg_basebackup.sgml index 91155fa9..1ae8f2c3 100644 --- a/zh/17/ref/pg_basebackup.sgml +++ b/zh/17/ref/pg_basebackup.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation pg_basebackup 1 - Application + 应用程序 @@ -80,7 +80,7 @@ PostgreSQL documentation - 备份所需的所有 WAL 记录都必须包含足够的全页写入, + 备份所需的所有 WAL 记录都必须包含足够的整页写入, 因此必须在主库上启用full_page_writes @@ -217,7 +217,7 @@ PostgreSQL documentation - 目前,此选项仅适用于 plain 输出格式;如果选择了 tar 格式,则会被忽略。 + 目前,此选项仅适用于 普通文件 输出格式;如果选择了 tar 格式,则会被忽略。 @@ -227,7 +227,7 @@ PostgreSQL documentation - 设置写入 WAL(预写式日志)文件的目录。默认情况下,WAL 文件会放在目标目录的pg_wal子目录中,但此选项可用于将其放在其他位置。waldir必须是绝对路径。与主目标目录一样,waldir不必事先存在,但如果存在则必须为空。只有当备份采用 plain 格式时,才能指定此选项。 + 设置写入 WAL(预写式日志)文件的目录。默认情况下,WAL 文件会放在目标目录的pg_wal子目录中,但此选项可用于将其放在其他位置。waldir必须是绝对路径。与主目标目录一样,waldir不必事先存在,但如果存在则必须为空。只有当备份采用 普通文件 格式时,才能指定此选项。 @@ -319,7 +319,7 @@ PostgreSQL documentation - 当 tar 格式配合gziplz4zstd使用时,所有 tar 文件名都会分别自动加上.gz.lz4.zst后缀。使用 plain 格式时,不能指定客户端压缩,但仍可以请求服务器端压缩。这样做时,服务器会先压缩备份再传输,而客户端会对其进行解压并提取。 + 当 tar 格式配合gziplz4zstd使用时,所有 tar 文件名都会分别自动加上.gz.lz4.zst后缀。使用 普通文件 格式时,不能指定客户端压缩,但仍可以请求服务器端压缩。这样做时,服务器会先压缩备份再传输,而客户端会对其进行解压并提取。 @@ -378,7 +378,7 @@ PostgreSQL documentation - 请注意,无论如何表空间目录都不会被清理。 + 请注意,无论是否使用此选项,表空间目录都不会被清理。 @@ -426,7 +426,7 @@ PostgreSQL documentation - 此选项只能与-X stream一起使用。它会使 WAL 流式传输使用指定的复制槽。如果此基础备份打算用作使用复制槽的流复制备库,那么该备库应使用与相同的复制槽名称。这样可以确保主库在基础备份结束与新备库开始流复制之间的这段时间内,不会移除任何必需的 WAL 数据。 + 此选项只能与-X stream一起使用。它会使 WAL 流式传输使用指定的复制槽。如果此基础备份打算用作使用复制槽的流复制备库,那么该备库应将同一个复制槽名称用作的值。这样可以确保主库在基础备份结束与新备库开始流复制之间的这段时间内,不会移除任何必需的 WAL 数据。 @@ -443,10 +443,10 @@ PostgreSQL documentation - 设置为fsync(默认)时,pg_basebackup会递归打开并同步备份目录中的所有文件。使用 plain 格式时,查找文件会跟随 WAL 目录和各已配置表空间的符号链接。 + 设置为fsync(默认)时,pg_basebackup会递归打开并同步备份目录中的所有文件。使用 普通文件 格式时,查找文件会跟随 WAL 目录和各已配置表空间的符号链接。 - 在 Linux 上,也可以使用syncfs,让操作系统同步包含备份目录的整个文件系统。使用 plain 格式时,pg_basebackup还会同步包含 WAL 文件和各表空间的文件系统。关于使用syncfs时需要注意的限制,见。 + 在 Linux 上,也可以使用syncfs,让操作系统同步包含备份目录的整个文件系统。使用 普通文件 格式时,pg_basebackup还会同步包含 WAL 文件和各表空间的文件系统。关于使用syncfs时需要注意的事项,见 使用时,此选项无效。 @@ -478,7 +478,7 @@ PostgreSQL documentation - 对于希望验证备份未被篡改的用户,使用 SHA 哈希函数可以为每个文件提供具有密码学安全性的摘要;而 CRC-32C 算法提供的校验和计算速度要快得多,虽然它很适合发现由于意外改动造成的错误,但并不能抵御恶意修改。请注意,要想对能够访问备份的攻击者形成防护,备份清单就需要安全地保存在其他地方,或者以其他方式确认自备份完成后未被修改。 + 对于希望验证备份未被篡改的用户,使用 SHA hash 函数可以为每个文件提供具有密码学安全性的摘要;而 CRC32C 算法提供的校验和计算速度要快得多,虽然它很适合发现由于意外改动造成的错误,但并不能抵御恶意修改。请注意,要想对能够访问备份的攻击者形成防护,备份清单就需要安全地保存在其他地方,或者以其他方式确认自备份完成后未被修改。 @@ -686,7 +686,7 @@ PostgreSQL documentation - 注意 + 注解 在备份开始时,需要在源服务器上执行一次检查点。这可能需要一些时间(尤其是在未使用--checkpoint=fast选项时);在此期间,pg_basebackup看起来会处于空闲状态。 @@ -697,7 +697,7 @@ PostgreSQL documentation - 在 plain 格式中,除非使用了--tablespace-mapping选项,否则表空间会备份到其在源服务器上的相同路径。如果不使用此选项,那么当表空间正在使用时,就无法在与服务器相同的主机上执行 plain 格式的基础备份,因为备份将不得不写入与原始表空间相同的目录位置。 + 在 普通文件 格式中,除非使用了--tablespace-mapping选项,否则表空间会备份到其在源服务器上的相同路径。如果不使用此选项,那么当表空间正在使用时,就无法在与服务器相同的主机上执行 普通文件 格式的基础备份,因为备份将不得不写入与原始表空间相同的目录位置。 @@ -757,7 +757,7 @@ PostgreSQL documentation - 参见 + 另见 diff --git a/zh/17/ref/pg_checksums.sgml b/zh/17/ref/pg_checksums.sgml index bba74354..9ffb27fb 100644 --- a/zh/17/ref/pg_checksums.sgml +++ b/zh/17/ref/pg_checksums.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_checksums 1 - Application + 应用程序 diff --git a/zh/17/ref/pg_combinebackup.sgml b/zh/17/ref/pg_combinebackup.sgml index 5ae1aa14..74126fe0 100644 --- a/zh/17/ref/pg_combinebackup.sgml +++ b/zh/17/ref/pg_combinebackup.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_combinebackup 1 - Application + 应用程序 @@ -77,32 +77,6 @@ PostgreSQL documentation - - - - - - 在合成备份中使用硬链接,而不是复制文件。 - 这样重建合成备份可能更快(因为无需复制文件), - 并且占用更少磁盘空间;但在使用输出目录时必须格外小心, - 因为对该目录的任何修改(例如启动服务器)也可能影响输入目录。 - 同样,对输入目录的更改(例如在完整备份上启动服务器) - 也可能影响输出目录。 - 因此,此选项最适合输入目录只是副本、并且会在 - pg_combinebackup完成后被删除的场景。 - - - - 要求输入备份和输出目录位于同一文件系统中。 - - - - 如果备份清单不可用,或者其中不包含正确类型的校验和, - 仍会创建硬链接,但也会按块读取文件以计算校验和。 - - - - @@ -184,8 +158,7 @@ PostgreSQL documentation 执行常规文件复制。这是默认行为。 - (另见 - 和/。) + (另见。) @@ -239,18 +212,18 @@ PostgreSQL documentation 当设置为fsync(这是默认值)时, pg_combinebackup会递归打开并同步备份目录中的所有文件。 - 使用 plain 格式时,搜索文件时会跟随 WAL 目录和每个已配置表空间的符号链接。 + 使用 普通文件 格式时,搜索文件时会跟随 WAL 目录和每个已配置表空间的符号链接。 在 Linux 上,也可以改用syncfs, 让操作系统同步包含备份目录的整个文件系统。 - 使用 plain 格式时,pg_combinebackup + 使用 普通文件 格式时,pg_combinebackup 还会同步包含 WAL 文件和各表空间的文件系统。 关于使用syncfs时需要注意的事项,请参见 - 当使用时,此选项无效。 + 使用时,此选项无效。 @@ -302,15 +275,11 @@ PostgreSQL documentation 环境 - 与多数PostgreSQL工具一样, - 本工具使用libpq支持的环境变量 - (参见)。 + 与大多数其他PostgreSQL工具一样,此工具也使用libpq支持的环境变量(见)。 - 环境变量PG_COLOR指定诊断消息是否使用颜色。 - 可选值为alwaysauto和 - never。 + 环境变量PG_COLOR指定是否在诊断消息中使用颜色。可能的值为alwaysautonever diff --git a/zh/17/ref/pg_config-ref.sgml b/zh/17/ref/pg_config-ref.sgml index 565638d9..b157f24c 100644 --- a/zh/17/ref/pg_config-ref.sgml +++ b/zh/17/ref/pg_config-ref.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation pg_config 1 - Application + 应用程序 diff --git a/zh/17/ref/pg_controldata.sgml b/zh/17/ref/pg_controldata.sgml index 818db6cc..5435edfa 100644 --- a/zh/17/ref/pg_controldata.sgml +++ b/zh/17/ref/pg_controldata.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_controldata 1 - Application + 应用程序 diff --git a/zh/17/ref/pg_createsubscriber.sgml b/zh/17/ref/pg_createsubscriber.sgml index 29bc59c1..77cca575 100644 --- a/zh/17/ref/pg_createsubscriber.sgml +++ b/zh/17/ref/pg_createsubscriber.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_createsubscriber 1 - Application + 应用程序 @@ -79,36 +79,11 @@ PostgreSQL documentation pg_createsubscriber接受以下命令行参数: - - - - - - 在目标服务器上的每个数据库中创建一个订阅。 - 模板数据库以及不允许连接的数据库除外。 - 为发现所有数据库的列表,工具会使用 - 连接字符串中指定的数据库名连接到源服务器;如果未指定,则使用 - postgres数据库;如果该数据库不存在,则使用 - template1。 - 指定此选项时,会使用自动生成的订阅、发布和复制槽名称。 - 此选项不能与、 - 一起使用。 - - - - - - 要在其中创建订阅的数据库名称。通过多次指定 - 可以选择多个数据库。此选项不能与一起使用。 - 如果未提供选项,数据库名将从 - 选项中获取。如果在选项或 - 选项中都未指定数据库名,且又未指定选项, - 则会报告错误。 - + 要在其中创建订阅的数据库名称。通过多次指定可以选择多个数据库。 @@ -170,25 +145,12 @@ PostgreSQL documentation - 等待恢复结束的最大秒数。设为 0 表示禁用。 + 等待恢复结束的最大秒数。设为 0 表示禁用超时限制。 默认值为 0。 - - - - - - 为订阅启用 - two_phase - 两阶段提交。当指定多个数据库时,此选项会统一应用于在这些数据库上创建的所有订阅。 - 默认值为false。 - - - - @@ -212,31 +174,6 @@ PostgreSQL documentation - - - - - 从目标服务器上的指定数据库中删除指定类型的所有对象。 - - - - - - publications: - 为该订阅者建立的FOR ALL TABLES发布总是会被删除; - 指定此对象类型还会删除从源服务器复制过来的其他所有发布。 - - - - - - 被选中要删除的对象都会逐个记录到日志中,包括在 - 期间也是如此。没有机会干预或停止这些对象的删除,因此可以考虑使用 - pg_dump先对它们进行备份。 - - - - @@ -257,9 +194,7 @@ PostgreSQL documentation 用于建立逻辑复制的发布名称。通过多次指定 可以指定多个发布。发布名称的数量必须与指定的数据库数量一致, 否则会报告错误。多个发布名称开关的顺序必须与数据库开关的顺序一致。 - 如果未指定此选项,则会为发布分配一个生成的名称。此选项不能与 - 一起使用。 - + 如果未指定此选项,则会为发布分配一个生成的名称。 @@ -270,9 +205,7 @@ PostgreSQL documentation 用于建立逻辑复制的复制槽名称。通过多次指定 可以指定多个复制槽。复制槽名称的数量必须与指定的数据库数量一致, 否则会报告错误。多个复制槽名称开关的顺序必须与数据库开关的顺序一致。 - 如果未指定此选项,则使用订阅名称作为复制槽名称。此选项不能与 - 一起使用。 - + 如果未指定此选项,则使用订阅名称作为复制槽名称。 @@ -283,9 +216,7 @@ PostgreSQL documentation 用于建立逻辑复制的订阅名称。通过多次指定 可以指定多个订阅。订阅名称的数量必须与指定的数据库数量一致, 否则会报告错误。多个订阅名称开关的顺序必须与数据库开关的顺序一致。 - 如果未指定此选项,则会为订阅分配一个生成的名称。此选项不能与 - 一起使用。 - + 如果未指定此选项,则会为订阅分配一个生成的名称。 @@ -313,7 +244,7 @@ PostgreSQL documentation - 注意 + 注解 前置条件 @@ -335,9 +266,7 @@ PostgreSQL documentation 目标服务器必须将配置为大于等于指定数据库数量的值。 目标服务器必须将配置为大于指定数据库数量的值。 - 目标服务器必须接受本地连接。如果计划使用 - 开关,还需要适当地设置。 - + 目标服务器必须接受本地连接。 源服务器必须接受来自目标服务器的连接。源服务器不能处于恢复中。 @@ -387,7 +316,6 @@ PostgreSQL documentation - 除非指定pg_createsubscriber会在禁用两阶段提交的情况下建立逻辑复制。 这意味着任何预备事务都会在COMMIT PREPARED时被复制, 而不会事先进行预备。配置完成后,你可以手动删除并重新创建订阅, @@ -401,13 +329,6 @@ PostgreSQL documentation 这样可以避免目标服务器可能使用源服务器的 WAL 文件。 如果目标服务器还有备库,复制将会中断,应创建一个新的备库。 - - - 若缺少必需 WAL 文件,复制可能失败。 - 为避免该问题,源服务器应将 - 设置为-1, - 以确保必需 WAL 文件不会被提前移除。 - @@ -456,9 +377,9 @@ PostgreSQL documentation 它指定了恢复将推进到的预写式日志位置的 LSN()。 它还将promote指定为服务器在达到恢复目标后应执行的动作。 - 为了避免恢复过程中出现意外行为,还会添加其他恢复参数,例如在达到一致状态后就结束恢复 - (实际上 WAL 应继续应用到复制起始位置)以及因多个恢复目标而导致失败。 + 还会添加其他恢复参数,以避免恢复过程中出现意外行为, + 例如一达到一致状态就结束恢复(WAL 应继续应用到复制起始位置),或者因指定多个恢复目标而失败。 当服务器退出备库模式并接受读写事务时,该步骤结束。 如果设置了选项,而恢复在给定秒数内没有结束, pg_createsubscriber就会终止。 diff --git a/zh/17/ref/pg_ctl-ref.sgml b/zh/17/ref/pg_ctl-ref.sgml index 6085da56..801cbc55 100644 --- a/zh/17/ref/pg_ctl-ref.sgml +++ b/zh/17/ref/pg_ctl-ref.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation pg_ctl 1 - Application + 应用程序 diff --git a/zh/17/ref/pg_dump.sgml b/zh/17/ref/pg_dump.sgml index 5bf6314d..663b424b 100644 --- a/zh/17/ref/pg_dump.sgml +++ b/zh/17/ref/pg_dump.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_dump 1 - Application + 应用程序 diff --git a/zh/17/ref/pg_dumpall.sgml b/zh/17/ref/pg_dumpall.sgml index bdec2662..c10a1658 100644 --- a/zh/17/ref/pg_dumpall.sgml +++ b/zh/17/ref/pg_dumpall.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_dumpall 1 - Application + 应用程序 diff --git a/zh/17/ref/pg_isready.sgml b/zh/17/ref/pg_isready.sgml index 2e93dde1..a09f7745 100644 --- a/zh/17/ref/pg_isready.sgml +++ b/zh/17/ref/pg_isready.sgml @@ -13,7 +13,7 @@ PostgreSQL documentation pg_isready 1 - Application + 应用程序 diff --git a/zh/17/ref/pg_receivewal.sgml b/zh/17/ref/pg_receivewal.sgml index 3c9e580a..bf520c28 100644 --- a/zh/17/ref/pg_receivewal.sgml +++ b/zh/17/ref/pg_receivewal.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation pg_receivewal 1 - Application + 应用程序 diff --git a/zh/17/ref/pg_recvlogical.sgml b/zh/17/ref/pg_recvlogical.sgml index 993fc2a9..c550ae78 100644 --- a/zh/17/ref/pg_recvlogical.sgml +++ b/zh/17/ref/pg_recvlogical.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation pg_recvlogical 1 - Application + 应用程序 @@ -75,13 +75,7 @@ PostgreSQL documentation 创建一个名称由指定的新逻辑复制槽。 - - 此操作必须指定 。 - - - - 可与 一起指定 选项。 - + 可与一起指定,以启用对预备事务的解码。 @@ -91,9 +85,6 @@ PostgreSQL documentation 删除由指定名称的复制槽,然后退出。 - - 此操作必须指定 。 - @@ -105,10 +96,6 @@ PostgreSQL documentation 如果服务端的更改流因服务器关闭或断开连接而结束,则除非指定了,否则会循环重试。 - - 此操作必须指定 。 - - 流格式由创建该槽时指定的输出插件决定。 @@ -134,7 +121,6 @@ PostgreSQL documentation - 模式下,当接收达到指定的 LSN 时,自动停止复制,并以正常退出状态 0 退出。 如果在非模式下指定,则会报错。 @@ -151,26 +137,15 @@ PostgreSQL documentation - - - - - 启用后会将该槽同步到备库。此选项只能与 一起指定。 - - - + - 将接收到并解码后的事务数据写入该文件。指定-表示写入stdout - - 此参数对于 操作是必需的。 - @@ -178,10 +153,9 @@ PostgreSQL documentation - 指定pg_recvlogical应当以多高的频率发起fsync()调用, - 以确保输出文件被安全地刷入磁盘。 + 以确保输出文件安全刷盘。 @@ -200,7 +174,6 @@ PostgreSQL documentation - 模式下,从给定的 LSN 开始复制。关于其影响的详细信息,请参见 中的说明。 @@ -212,7 +185,6 @@ PostgreSQL documentation - 当指定且指定名称的槽已存在时,不报错。 @@ -223,7 +195,6 @@ PostgreSQL documentation - 当与服务器的连接丢失时,不要循环重试,直接退出。 @@ -234,7 +205,6 @@ PostgreSQL documentation - 将选项name传递给输出插件;如果指定了value, 则将其用作该选项的值。可用选项及其效果取决于所使用的输出插件。 @@ -246,7 +216,6 @@ PostgreSQL documentation - 创建该槽时,使用指定的逻辑解码输出插件。参见。 如果该槽已经存在,则此选项不起作用。 @@ -258,7 +227,6 @@ PostgreSQL documentation - 该选项与中同名选项的效果相同。参见该处说明。 @@ -269,24 +237,18 @@ PostgreSQL documentation - 模式下,使用名为slot_name的现有逻辑复制槽。 在模式下,以此名称创建该槽。 在模式下,删除此名称的槽。 - - 此参数对于任何一种操作都是必需的。 - - - (已废弃) + - 启用对预备事务的解码。此选项只能与一起指定。 @@ -297,7 +259,6 @@ PostgreSQL documentation - 启用详细模式。 @@ -314,14 +275,7 @@ PostgreSQL documentation - - 要连接到的数据库。其具体含义请参见各操作的说明。 - dbname可以是一个连接字符串。 - 如果是这种情况,连接字符串参数将覆盖任何冲突的命令行选项。 - - - 此参数在 操作中是必需的。 - + 要连接的数据库。有关其具体含义,请参阅各操作的说明。dbname可以是一个连接字符串。如果如此,连接字符串参数会覆盖任何与之冲突的命令行选项。默认值为用户名。 @@ -329,7 +283,7 @@ PostgreSQL documentation - + 指定服务器运行所在机器的主机名。如果该值以斜杠开头, 则它会被用作 Unix 域套接字的目录。默认值取自 PGHOST环境变量(如果已设置), @@ -342,7 +296,7 @@ PostgreSQL documentation - + 指定服务器监听连接所用的 TCP 端口,或本地 Unix 域套接字文件扩展名。 默认值取自PGPORT环境变量(如果已设置), 否则使用编译时的默认值。 @@ -354,7 +308,7 @@ PostgreSQL documentation - + 用于连接的用户名。默认为当前操作系统用户名。 @@ -364,7 +318,7 @@ PostgreSQL documentation - + 绝不提示输入密码。如果服务器要求密码认证,而密码又无法通过 .pgpass文件等其他方式获得, 则连接尝试将失败。此选项适用于批处理作业和脚本, @@ -377,7 +331,7 @@ PostgreSQL documentation - + 强制pg_recvlogical在连接数据库之前提示输入密码。 @@ -411,7 +365,7 @@ PostgreSQL documentation - + 显示pg_recvlogical命令行参数的帮助并退出。 diff --git a/zh/17/ref/pg_resetwal.sgml b/zh/17/ref/pg_resetwal.sgml index 9deadc8c..7dee0bce 100644 --- a/zh/17/ref/pg_resetwal.sgml +++ b/zh/17/ref/pg_resetwal.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_resetwal 1 - Application + 应用程序 diff --git a/zh/17/ref/pg_restore.sgml b/zh/17/ref/pg_restore.sgml index 7ae86b39..8cd4af1a 100644 --- a/zh/17/ref/pg_restore.sgml +++ b/zh/17/ref/pg_restore.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_restore 1 - Application + 应用程序 diff --git a/zh/17/ref/pg_rewind.sgml b/zh/17/ref/pg_rewind.sgml index 16ffc2e9..93617f49 100644 --- a/zh/17/ref/pg_rewind.sgml +++ b/zh/17/ref/pg_rewind.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation pg_rewind 1 - Application + 应用程序 diff --git a/zh/17/ref/pg_verifybackup.sgml b/zh/17/ref/pg_verifybackup.sgml index a2afbec0..27c37867 100644 --- a/zh/17/ref/pg_verifybackup.sgml +++ b/zh/17/ref/pg_verifybackup.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_verifybackup 1 - Application + 应用程序 @@ -28,22 +28,12 @@ PostgreSQL documentation 描述 - - pg_verifybackup用于依据服务器在备份时生成的 - backup_manifest,检查使用 - pg_basebackup获取的数据库集簇备份的完整性。备份 - 既可以采用“plain”格式,也可以采用“tar”格式;其中也包括使用 - pg_basebackup支持的任意算法压缩的 tar 格 - 式备份。不过,目前仅支持对 plain 格式备份执行WAL - 验证。因此,如果备份采用 tar 格式存储,应使用 - -n, --no-parse-wal选项。 - + pg_verifybackup用于检查通过pg_basebackup获取的数据库集簇备份的完整性,检查依据是服务器在备份时生成的backup_manifest。备份必须以“普通文件”格式存储;“tar”格式的备份可以在解包后检查。 需要注意,pg_verifybackup执行的验证并未、也 不可能涵盖运行中的服务器在尝试使用该备份时会执行的每一项检查。即使使 - 用了此工具,你仍应进行测试恢复,并确认生成的数据库按预期工作且包含正 - 确的数据。不过,pg_verifybackup能够检测出 + 用了此工具,你仍应进行测试恢复,并确认生成的数据库按预期工作且看起来包含正确的数据。不过,pg_verifybackup能够检测出 许多因存储问题或用户错误而常见的问题。 @@ -118,41 +108,6 @@ PostgreSQL documentation - - - - - - 指定备份格式。format可以是下列值之一: - - - - p - plain - - - 备份由普通文件组成,其布局与源服务器的数据目录和表空间相同。 - - - - - - t - tar - - - 备份由 tar 文件组成,这些文件可以经过压缩。有效的备份包括名为 - base.tar的主数据目录、名为 - pg_wal.tar的 WAL 文件,以及每个表空间 - 对应的单独 tar 文件,这些文件以该表空间的 OID 命名。如果备份 - 被压缩,则会在每个文件名末尾追加相应的压缩扩展名。 - - - - - - - @@ -237,9 +192,9 @@ PostgreSQL documentation - 还提供下列其他选项: + 其他选项也可用: - + @@ -270,7 +225,7 @@ PostgreSQL documentation 示例 - 要在mydbserver上创建服务器的基础备份,并验证该备 + 要为位于mydbserver的服务器创建基础备份,并验证该备 份的完整性: $ pg_basebackup -h mydbserver -D /usr/local/pgsql/data @@ -279,7 +234,7 @@ PostgreSQL documentation - 要在mydbserver上创建服务器的基础备份,将备份清单 + 要为位于mydbserver的服务器创建基础备份,将备份清单 移到备份目录之外的位置,然后验证该备份: $ pg_basebackup -h mydbserver -D /usr/local/pgsql/backup1234 diff --git a/zh/17/ref/pg_waldump.sgml b/zh/17/ref/pg_waldump.sgml index a4433e63..baa4bb42 100644 --- a/zh/17/ref/pg_waldump.sgml +++ b/zh/17/ref/pg_waldump.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_waldump 1 - Application + 应用程序 diff --git a/zh/17/ref/pg_walsummary.sgml b/zh/17/ref/pg_walsummary.sgml index b3abba5e..bbc7cd38 100644 --- a/zh/17/ref/pg_walsummary.sgml +++ b/zh/17/ref/pg_walsummary.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_walsummary 1 - Application + 应用程序 @@ -41,11 +41,11 @@ PostgreSQL documentation WAL 汇总文件按表空间 OID、关系 OID 以及关系分支(fork)建立索引。 对于每个关系分支,它都存储该文件所汇总范围内被 WAL 修改的块列表。 - 它还可以存储一个limit block: + 它还可以存储一个界限块: 如果该关系分支在相关 WAL 范围内被创建或截断,则其值为 0; 否则,其值为该关系分支被截断后的最短长度。 如果该关系分支在相关 WAL 范围内未被创建、删除或截断, - 则 limit block 未定义,或者为无穷大,本工具不会打印它。 + 则 界限块 未定义,或者为无穷大,本工具不会打印它。 @@ -107,9 +107,7 @@ PostgreSQL documentation 环境 - 环境变量PG_COLOR用于指定是否在诊断消息中使用颜色。 - 可能的值为alwaysauto和 - never。 + 环境变量PG_COLOR指定是否在诊断消息中使用颜色。可能的值为alwaysautonever diff --git a/zh/17/ref/pgarchivecleanup.sgml b/zh/17/ref/pgarchivecleanup.sgml index 5c2c0a53..fd4da23e 100644 --- a/zh/17/ref/pgarchivecleanup.sgml +++ b/zh/17/ref/pgarchivecleanup.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_archivecleanup 1 - Application + 应用程序 diff --git a/zh/17/ref/pgbench.sgml b/zh/17/ref/pgbench.sgml index cbade471..e0fa9e55 100644 --- a/zh/17/ref/pgbench.sgml +++ b/zh/17/ref/pgbench.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation pgbench 1 - Application + 应用程序 @@ -1685,7 +1685,7 @@ SELECT 4 AS four \; SELECT 5 AS five \aset greatest ( number , ... ) - double 如果任何参数是双精度的,否则 integer + 若任一参数为 double,则为 double,否则为 integer 选择参数中的最大值。 @@ -1755,7 +1755,7 @@ SELECT 4 AS four \; SELECT 5 AS five \aset least ( number , ... ) - double 如果任何参数是双精度的,否则 integer + 若任一参数为 double,则为 double,否则为 integer 选择参数中的最小值。 @@ -2602,7 +2602,7 @@ PGOPTIONS='-c default_table_access_method=wuzza' 安全性 - 如果不可信用户能够访问尚未采用模式的安全使用方式的数据库,就不要在该数据库中运行pgbenchpgbench使用非限定名称,并且不会更改搜索路径。 + 如果不受信任的用户能够访问尚未采用模式的安全使用方式的数据库,就不要在该数据库中运行pgbenchpgbench使用非限定名称,并且不会更改搜索路径。 diff --git a/zh/17/ref/pgtestfsync.sgml b/zh/17/ref/pgtestfsync.sgml index 86e69b30..6055bccf 100644 --- a/zh/17/ref/pgtestfsync.sgml +++ b/zh/17/ref/pgtestfsync.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_test_fsync 1 - Application + 应用程序 diff --git a/zh/17/ref/pgtesttiming.sgml b/zh/17/ref/pgtesttiming.sgml index f652980f..dc7208fc 100644 --- a/zh/17/ref/pgtesttiming.sgml +++ b/zh/17/ref/pgtesttiming.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_test_timing 1 - Application + 应用程序 diff --git a/zh/17/ref/pgupgrade.sgml b/zh/17/ref/pgupgrade.sgml index 6bcdcc12..1a610170 100644 --- a/zh/17/ref/pgupgrade.sgml +++ b/zh/17/ref/pgupgrade.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_upgrade 1 - Application + 应用程序 @@ -40,7 +40,7 @@ PostgreSQL documentation pg_upgrade(以前称为 pg_migrator)允许将存储在 PostgreSQL 数据文件中的数据升级到更新的 PostgreSQL主版本,而无需执行主版本升级通常所需的数据转储/恢复, - 例如从 12.14 升级到 13.10,或从 14.9 升级到 15.5。它不用于次版本升级, + 例如从 12.14 升级到 13.10,或从 14.9 升级到 15.5。次版本升级不需要使用它, 例如从 12.7 升级到 12.8 或从 14.1 升级到 14.5。 @@ -58,10 +58,7 @@ PostgreSQL documentation 二进制兼容,这一点很重要,但 pg_upgrade 无法检查。 - - pg_upgrade 支持从 9.2.X 及更高版本升级到当前 - PostgreSQL主版本,包括快照版和 beta 版。 - + pg_upgrade 支持从 9.2.X 及更高版本升级到当前PostgreSQL主版本,包括快照版和 beta 版。 @@ -112,7 +109,7 @@ PostgreSQL documentation - 要使用的并发连接和进程/线程数 + 要使用的并发进程或线程数 @@ -209,11 +206,7 @@ PostgreSQL documentation - - 将文件复制到新集簇。这是默认行为。(另见 - 、 - 。) - + 将文件复制到新集簇。这是默认行为。(另见。) @@ -228,77 +221,11 @@ PostgreSQL documentation - - - - - 不要把旧集簇中的统计信息恢复到新集簇中。 - - - - - option - - - 手工设置新集簇默认的 char 有符号性。可选值为 - signedunsigned。 - - - 在 C 语言中,char 类型在未显式指定时的默认有符号性因平台而异。 - 例如,在 x86 CPU 上 char 默认是 signed char, - 而在 ARM CPU 上默认是 unsigned char。 - - - 从 PostgreSQL 18 开始,数据库集簇会维护自身默认的 - char 有符号性设置,可用于确保在默认 char 有符号性不同的平台之间保持一致行为。 - 默认情况下,pg_upgrade 在从现有集簇升级时会保留该有符号性设置。 - 然而,从 PostgreSQL 17 或更早版本升级时, - pg_upgrade 会采用其构建所在平台的 char 有符号性。 - - - 该选项允许你显式设置新集簇默认的 char 有符号性,以覆盖任何继承值。 - 该选项主要适用于以下两种场景: - - - - 如果你计划在升级后迁移到不同平台,则不应使用该选项。在这种情况下,默认行为才是正确的。 - 应当先在原平台上不带此选项完成升级,然后再迁移集簇。这是推荐且最安全的方法。 - - - - - 如果你已经将集簇迁移到了默认 char 有符号性不同的平台上 - (例如从基于 x86 的系统迁移到基于 ARM 的系统),则应使用该选项来指定与原平台 - 默认 char 有符号性相匹配的值。此外,从迁移数据文件到运行 - pg_upgrade 之间,切勿修改任何数据文件。 - pg_upgrade 应当是新平台上首次启动该集簇的操作。 - - - - - - - - - - - 将数据目录从旧集簇移动到新集簇,然后用为新集簇生成的系统目录文件替换原有目录文件。 - 该模式的性能可能优于 、 - ,尤其是在关系很多的集簇上。 - - - 但是,这种模式会在旧集簇中产生大量垃圾文件,如果使用 - ,可能会延长文件同步步骤。因此, - 建议在 模式下使用 。 - - - 此外,一旦文件传输步骤开始,旧集簇就会被破坏性修改,因此不再能安全启动。 - 详见 。 - - - + + + method @@ -494,6 +421,26 @@ make prefix=/usr/local/pgsql.new install + + 为订阅者升级做准备 + + 在新订阅者上设置订阅者配置。pg_upgrade会尝试迁移订阅依赖项,其中包括pg_subscription_rel系统目录中的订阅表信息,以及订阅的复制源。这样,新订阅者上的逻辑复制就能从旧订阅者停止的位置继续。只有旧集簇为 17.0 或更高版本时才支持迁移订阅依赖项。17.0 之前集簇上的订阅依赖项会被静默忽略。 + + 要让pg_upgrade能够升级订阅,需要满足一些先决条件。如果不满足这些条件,将报告错误。 + + + + 旧订阅者中的所有订阅表都应处于i(初始化)或r(就绪)状态。可以通过检查pg_subscription_rel.srsubstate来验证。 + + + 旧集簇中应存在与每个订阅相对应的复制源条目。可以通过检查pg_subscription和pg_replication_origin系统表来找到这些条目。 + + + 新集簇的max_replication_slots配置值必须大于或等于旧集簇中的订阅数量。 + + + + 停止两个服务器 @@ -537,7 +484,7 @@ NET STOP postgresql-&majorversion; 始终运行新服务器的 pg_upgrade 二进制,而不是旧服务器的。 pg_upgrade 需要指定新旧集簇的数据目录和可执行文件 (bin)目录。你还可以指定用户和端口值,以及是否希望将数据文件 - 链接、克隆或交换,而不是采用默认的复制行为。 + 链接或克隆,而不是采用默认的复制行为。 @@ -545,16 +492,10 @@ NET STOP postgresql-&majorversion; 新集簇,就无法再访问旧集簇。链接模式还要求新旧集簇的数据目录位于同一文件系统中。 (表空间和 pg_wal 可以位于不同文件系统中。)克隆模式具有相同的 速度和磁盘空间优势,但在启动新集簇后不会使旧集簇不可用。克隆模式同样要求新旧数据目录 - 位于同一文件系统中。该模式只在某些操作系统和文件系统上可用。如果关系很多,交换模式 - 可能最快,但一旦文件传输步骤开始,你将无法再访问旧集簇。交换模式也要求新旧集簇的数据 - 目录位于同一文件系统中。 + 位于同一文件系统中。该模式只在某些操作系统和文件系统上可用。 - - 将 设置为 2 或更高可以让 pg_upgrade 并行处理多个数据库和表空间。 - 一个不错的起始值是机器上的 CPU 核心数。对于多数据库、多表空间的服务器,此选项可以显著 - 减少升级时间。 - + 选项允许使用多个 CPU 核心复制/链接文件,并行转储和恢复数据库模式;一个不错的起始值是 CPU 核心数与表空间数量中的较大值。对于运行在多处理器机器上的多数据库服务器,此选项可以显著减少升级时间。 对于 Windows 用户,必须登录到管理员账户,然后以带引号的目录运行 @@ -570,10 +511,7 @@ pg_upgrade.exe 启动后,pg_upgrade 会验证两个集簇是否兼容,然后执行升级。 即使旧服务器仍在运行,也可以使用 pg_upgrade --check 仅执行检查。 - pg_upgrade --check 还会概述升级后需要手工进行的调整。如果你打算 - 使用链接、克隆、copy-file-range 或交换模式,则应将 、 - 或 - 一起使用,以启用对应模式的专用检查。 + pg_upgrade --check 还会概述升级后需要手工进行的调整。如果你打算使用链接或克隆模式,则应将选项一起使用,以启用对应模式的专用检查。 pg_upgrade 需要对当前目录具有写权限。 @@ -764,28 +702,15 @@ psql --username=postgres --file=script.sql postgres 统计信息 - - 除非指定 pg_upgrade 会将大多数 - 优化器统计信息从旧集簇传输到新集簇。但这不会传输所有统计信息,例如通过 - 显式创建的统计信息、扩展添加的自定义统计信息, - 或由累积统计系统收集的统计信息。 - - - 由于并非所有统计信息都会由 pg_upgrade 传输,升级结束时你会被要求 - 运行命令来重新生成这些信息。你可能需要设置连接参数以匹配新集簇。 - - - 首先,使用 - vacuumdb --all --analyze-in-stages --missing-stats-only - 为尚无统计信息的关系快速生成最基本的优化器统计信息。然后,使用 - vacuumdb --all --analyze-only 以确保所有关系都拥有最新的累积统计信息, - 用于触发 vacuum 和 analyze。对于这两个命令,使用 都可以加快速度。 - 如果 vacuum_cost_delay 被设置为非零值,可以通过 - PGOPTIONS 覆盖它来加快统计信息生成,例如 PGOPTIONS='-c - vacuum_cost_delay=0' vacuumdb ...。 - + + + + + 由于优化器统计信息不会由pg_upgrade传输,升级结束时你会被要求运行命令来重新生成这些信息。你可能需要设置连接参数以匹配新集簇。 + + 使用vacuumdb --all --analyze-only可以高效生成这些统计信息,使用还可以加快速度。可以使用选项快速生成最基本的统计信息。如果vacuum_cost_delay被设置为非零值,可以通过PGOPTIONS覆盖它来加快统计信息生成,例如PGOPTIONS='-c vacuum_cost_delay=0' vacuumdb ... @@ -812,10 +737,7 @@ psql --username=postgres --file=script.sql postgres - - 如果既没有使用 ,也没有使用 , - 旧集簇不会被修改;可以重新启动。 - + 如果选项没有被使用,旧集簇就未被修改,可以重新启动。 @@ -850,27 +772,7 @@ psql --username=postgres --file=script.sql postgres - - - 如果使用了 选项,旧集簇可能已经被破坏性修改: - - - - 如果 pg_upgrade 在报告旧集簇不再能安全启动之前中止, - 则旧集簇没有被修改;可以重新启动。 - - - - - - 如果 pg_upgrade 已报告旧集簇不再能安全启动, - 则旧集簇已经被破坏性修改。在这种情况下,旧集簇必须从备份恢复。 - - - - - diff --git a/zh/17/ref/postgres-ref.sgml b/zh/17/ref/postgres-ref.sgml index b62740d6..a2e9456b 100644 --- a/zh/17/ref/postgres-ref.sgml +++ b/zh/17/ref/postgres-ref.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation postgres 1 - Application + 应用程序 @@ -532,7 +532,7 @@ PostgreSQL documentation - 表明另一台服务器已经在运行的失败消息 + 表明另一个服务器已经在运行的失败消息 应仔细检查,例如可根据你的系统使用下面的命令: $ ps ax | grep postgres @@ -721,7 +721,7 @@ PostgreSQL documentation - 参见 + 另见 , diff --git a/zh/17/ref/prepare.sgml b/zh/17/ref/prepare.sgml index 6c456821..20228fb4 100644 --- a/zh/17/ref/prepare.sgml +++ b/zh/17/ref/prepare.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation PREPARE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/prepare_transaction.sgml b/zh/17/ref/prepare_transaction.sgml index 10d018b0..75776dab 100644 --- a/zh/17/ref/prepare_transaction.sgml +++ b/zh/17/ref/prepare_transaction.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation PREPARE TRANSACTION 7 - SQL - Language Statements + SQL - 语言语句 @@ -72,7 +72,7 @@ PREPARE TRANSACTION transaction_id - 当前不允许将执行过以下任一操作的事务置为预备状态:涉及临时表或会话临时命名空间的操作、创建任何WITH HOLD游标,或执行过LISTENUNLISTENNOTIFY。这些特性与当前会话绑定得过于紧密,因此在要进入预备状态的事务中没有意义。 + 当前不允许对执行过以下任一操作的事务执行PREPARE:涉及临时表或会话临时命名空间的操作、创建任何WITH HOLD游标,或执行过LISTENUNLISTENNOTIFY。这些特性与当前会话绑定得过于紧密,因此在要进入预备状态的事务中没有意义。 diff --git a/zh/17/ref/psql-ref.sgml b/zh/17/ref/psql-ref.sgml index f7651da7..902beb87 100644 --- a/zh/17/ref/psql-ref.sgml +++ b/zh/17/ref/psql-ref.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation psql 1 - Application + 应用程序 @@ -534,7 +534,7 @@ testdb=> - 如果不可信用户能够访问尚未采用模式的安全使用方式的数据库,请在会话开始时从search_path中移除所有公众可写的 schema。可以在连接字符串中加入options=-csearch_path=,或者在执行其他 SQL 命令之前发出SELECT pg_catalog.set_config('search_path', '', false)。这种考虑并非psql特有;它适用于任何执行任意 SQL 命令的接口。 + 如果不受信任的用户能够访问尚未采用模式的安全使用方式的数据库,请在会话开始时从search_path中移除所有公众可写的模式。可以在连接字符串中加入options=-csearch_path=,或者在执行其他 SQL 命令之前发出SELECT pg_catalog.set_config('search_path', '', false)。这种考虑并非psql特有;它适用于任何执行任意 SQL 命令的接口。 @@ -582,12 +582,9 @@ testdb=> 很多元命令作用在当前查询缓冲区上。这就是一个缓冲区而已,它保存任何已经被键入但是还没有发送到服务器执行的SQL命令文本。这将包括之前输入的行以及在该元命令同一行上出现在前面的任何文本。 - - 许多元命令还允许在命令名后追加 x 作为选项。这会使结果以扩展模式显示,就像使用了 \x\pset expanded 一样。 - - 定义了以下元命令: + 定义了以下元命令: @@ -626,29 +623,6 @@ INSERT INTO tbl1 VALUES ($1, $2) \bind 'first value' 'second value' \g - - \bind_named statement_name [ parameter ] ... - - - - \bind_named 等同于 \bind,不同之处在于它把现有预备语句的名称作为第一个参数。空字符串表示未命名的预备语句。 - - - - 示例: - -INSERT INTO tbls1 VALUES ($1, $2) \parse stmt1 -\bind_named stmt1 'first value' 'second value' \g - - - - - 此命令会使用扩展查询协议(参见 - ),不同于psql通常使用的简单查询协议。因此,可以用它在psql中测试扩展查询协议。 - - - - \c\connect [ -reuse-previous=on|off ] [ dbname [ username ] [ host ] [ port ] | conninfo ] @@ -686,7 +660,7 @@ INSERT INTO tbls1 VALUES ($1, $2) \parse stmt1 - 示例: + 示例: => \c mydb myuser host.dom 6432 @@ -726,28 +700,6 @@ INSERT INTO tbls1 VALUES ($1, $2) \parse stmt1 - - \close_prepared prepared_statement_name - - - - 关闭指定的预备语句。空字符串表示未命名的预备语句。如果不存在该名称的预备语句,则该操作不执行任何操作。 - - - - 示例: - -SELECT $1 \parse stmt1 -\close_prepared stmt1 - - - - - 此命令会使用扩展查询协议,不同于psql通常使用的简单查询协议。因此,可以用它在psql中测试扩展查询协议。 - - - - \conninfo @@ -881,7 +833,7 @@ SELECT $1 \parse stmt1 - \d[Sx+] [ pattern ] + \d[S+] [ pattern ] @@ -914,66 +866,62 @@ SELECT $1 \parse stmt1 它等同于\dtvmsE,它将显示所有可见的表、视图、物化视图、序列和外部表的列表。 这纯粹是一种便利措施。 - - 与许多其他命令一样,如果在命令名后追加 x,结果会以扩展模式显示。但请注意,这只适用于不带 pattern 参数的 \d;并且 x 修饰符不能直接紧跟在 \d 后面(因为 \dx 是另一个命令)。x 只能出现在 S+ 修饰符之后。例如,\d+x 等同于 \dtvmsE+x,并以扩展模式显示所有关系的列表。 - - \da[Sx] [ pattern ] + \da[S] [ pattern ] 列出聚合函数,以及它们的返回类型和所作用的数据类型。如果指定了 pattern,则只显示名称与模式匹配的聚合。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。如果在命令名后追加 x,结果会以扩展模式显示。 - + class="parameter">pattern,则只显示名称与模式匹配的聚合。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。 - \dA[x+] [ pattern ] + \dA[+] [ pattern ] 列出访问方法。如果指定了 pattern,则只显示名称与模式匹配的访问方法。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则每个访问方法都会连同其关联的处理器函数和描述一起列出。 + class="parameter">pattern,则只显示名称与模式匹配的访问方法。如果在命令名后追加 +,则每个访问方法都会连同其关联的处理器函数和描述一起列出。 - \dAc[x+] + \dAc[+] [access-method-pattern [input-type-pattern]] - 列出操作符类(参见 )。如果指定了 access-method-pattern,则只列出与名称匹配该模式的访问方法关联的操作符类。如果指定了 input-type-pattern,则只列出与名称匹配该模式的输入类型关联的操作符类。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则每个操作符类都会连同其关联的操作符族和所有者一起列出。 + 列出操作符类(参见 )。如果指定了 access-method-pattern,则只列出与名称匹配该模式的访问方法关联的操作符类。如果指定了 input-type-pattern,则只列出与名称匹配该模式的输入类型关联的操作符类。如果在命令名后追加 +,则每个操作符类都会连同其关联的操作符族和所有者一起列出。 - \dAf[x+] + \dAf[+] [access-method-pattern [input-type-pattern]] - 列出操作符族(参见 )。如果指定了 access-method-pattern,则只列出与名称匹配该模式的访问方法关联的操作符族。如果指定了 input-type-pattern,则只列出与名称匹配该模式的输入类型关联的操作符族。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则每个操作符族都会连同其所有者一起列出。 + 列出操作符族(参见 )。如果指定了 access-method-pattern,则只列出与名称匹配该模式的访问方法关联的操作符族。如果指定了 input-type-pattern,则只列出与名称匹配该模式的输入类型关联的操作符族。如果在命令名后追加 +,则每个操作符族都会连同其所有者一起列出。 - \dAo[x+] + \dAo[+] [access-method-pattern [operator-family-pattern]] @@ -981,69 +929,69 @@ SELECT $1 \parse stmt1 - 列出与操作符族关联的操作符(参见 )。如果指定了 access-method-pattern,则只列出与名称匹配该模式的访问方法所关联的操作符族成员。如果指定了 operator-family-pattern,则只列出名称与该模式匹配的操作符族成员。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则每个操作符都会连同其排序操作符族(如果它是排序操作符)以及其底层函数是否防漏一起列出。 + 列出与操作符族关联的操作符(参见 )。如果指定了 access-method-pattern,则只列出与名称匹配该模式的访问方法所关联的操作符族成员。如果指定了 operator-family-pattern,则只列出名称与该模式匹配的操作符族成员。如果在命令名后追加 +,则每个操作符都会连同其排序操作符族(如果它是排序操作符)以及其底层函数是否防漏一起列出。 - \dAp[x+] + \dAp[+] [access-method-pattern [operator-family-pattern]] - 列出与操作符族关联的支持函数(参见 )。如果指定了 access-method-pattern,则只列出与名称匹配该模式的访问方法所关联的操作符族函数。如果指定了 operator-family-pattern,则只列出名称与该模式匹配的操作符族函数。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,函数会以详细形式显示,并带有其实际参数列表。 + 列出与操作符族关联的支持函数(参见 )。如果指定了 access-method-pattern,则只列出与名称匹配该模式的访问方法所关联的操作符族函数。如果指定了 operator-family-pattern,则只列出名称与该模式匹配的操作符族函数。如果在命令名后追加 +,函数会以详细形式显示,并带有其实际参数列表。 - \db[x+] [ pattern ] + \db[+] [ pattern ] 列出表空间。如果指定了 pattern,则只显示名称与模式匹配的表空间。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则每个表空间都会连同其关联选项、磁盘大小、权限和描述一起列出。 + class="parameter">pattern,则只显示名称与模式匹配的表空间。如果在命令名后追加 +,则每个表空间都会连同其关联选项、磁盘大小、权限和描述一起列出。 - \dc[Sx+] [ pattern ] + \dc[S+] [ pattern ] - 列出字符集编码之间的转换。如果指定了 pattern,则只列出名称与模式匹配的转换。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则每个对象都会连同其相关描述一起列出。 + 列出字符集编码之间的转换。如果指定了 pattern,则只列出名称与模式匹配的转换。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。如果在命令名后追加 +,则每个对象都会连同其相关描述一起列出。 - \dconfig[x+] [ pattern ] + \dconfig[+] [ pattern ] - 列出服务器配置参数及其值。如果指定了 pattern,则只列出名称与模式匹配的参数。不带 pattern 时,只列出被设置为非默认值的参数。(使用 \dconfig * 可查看所有参数。)如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则每个参数都会连同其数据类型、该参数可设置的上下文以及访问权限(如果已授予非默认访问权限)一起列出。 + 列出服务器配置参数及其值。如果指定了 pattern,则只列出名称与模式匹配的参数。不带 pattern 时,只列出被设置为非默认值的参数。(使用 \dconfig * 可查看所有参数。)如果在命令名后追加 +,则每个参数都会连同其数据类型、该参数可设置的上下文以及访问权限(如果已授予非默认访问权限)一起列出。 - \dC[x+] [ pattern ] + \dC[+] [ pattern ] - 列出类型转换。如果指定了 pattern,则只列出其源类型或目标类型与模式匹配的类型转换。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则会显示每个类型转换的附加信息,包括其底层函数是否防漏,以及该类型转换的描述。 + 列出类型转换。如果指定了 pattern,则只列出其源类型或目标类型与模式匹配的类型转换。如果在命令名后追加 +,则会显示每个类型转换的附加信息,包括其底层函数是否防漏,以及该类型转换的描述。 - \dd[Sx] [ pattern ] + \dd[S] [ pattern ] 显示constraintoperator class、 @@ -1052,8 +1000,7 @@ SELECT $1 \parse stmt1 \dd 显示与 - pattern 匹配的对象描述;如果没有给出参数,则显示相应类型的可见对象的描述。但无论哪种情况,只列出那些已有描述的对象。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。如果在命令名后追加 x,结果会以扩展模式显示。 - + pattern 匹配的对象描述;如果没有给出参数,则显示相应类型的可见对象的描述。但无论哪种情况,只列出那些已有描述的对象。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。 可以使用 COMMENT SQL 命令创建对象的描述。 @@ -1063,22 +1010,21 @@ SELECT $1 \parse stmt1 - \dD[Sx+] [ pattern ] + \dD[S+] [ pattern ] 列出域。如果指定了 pattern,则只显示名称与模式匹配的域。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则每个对象都会连同其相关权限和描述一起列出。 + class="parameter">pattern,则只显示名称与模式匹配的域。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。如果在命令名后追加 +,则每个对象都会连同其相关权限和描述一起列出。 - \ddp[x] [ pattern ] + \ddp[ pattern ] - 列出默认访问权限设置。对于每个默认权限设置已偏离内置默认值的角色(以及适用时的模式),都会显示一条记录。如果指定了 pattern,则只列出角色名或模式名与模式匹配的记录。如果在命令名后追加 x,结果会以扩展模式显示。 - + 列出默认访问权限设置。对于每个默认权限设置已偏离内置默认值的角色(以及适用时的模式),都会显示一条记录。如果指定了 pattern,则只列出角色名或模式名与模式匹配的记录。 ALTER DEFAULT @@ -1089,51 +1035,51 @@ SELECT $1 \parse stmt1 - \dE[Sx+] [ pattern ] - \di[Sx+] [ pattern ] - \dm[Sx+] [ pattern ] - \ds[Sx+] [ pattern ] - \dt[Sx+] [ pattern ] - \dv[Sx+] [ pattern ] + \dE[S+] [ pattern ] + \di[S+] [ pattern ] + \dm[S+] [ pattern ] + \ds[S+] [ pattern ] + \dt[S+] [ pattern ] + \dv[S+] [ pattern ] 在这组命令中,字母 Eimstv - 分别表示外部表、索引、物化视图、序列、表和视图。你可以按任意顺序指定其中任意一个或多个字母,以获取这些类型对象的列表。例如,\dti 会列出表和索引。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则每个对象都会连同其持久性状态(永久、临时或不记录 WAL)、磁盘上的物理大小以及相关描述(如果有)一起列出。如果指定了 pattern,则只列出名称与模式匹配的对象。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。 + 分别表示外部表、索引、物化视图、序列、表和视图。你可以按任意顺序指定其中任意一个或多个字母,以获取这些类型对象的列表。例如,\dti 会列出表和索引。如果在命令名后追加 +,则每个对象都会连同其持久性状态(永久、临时或不记录 WAL)、磁盘上的物理大小以及相关描述(如果有)一起列出。如果指定了 pattern,则只列出名称与模式匹配的对象。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。 - \des[x+] [ pattern ] + \des[+] [ pattern ] 列出外部服务器(助记符:external - servers)。如果指定了 pattern,则只列出名称与模式匹配的服务器。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则会显示每个服务器的完整描述,包括服务器的访问权限、类型、版本、选项和描述。 + servers)。如果指定了 pattern,则只列出名称与模式匹配的服务器。如果在命令名后追加 +,则会显示每个服务器的完整描述,包括服务器的访问权限、类型、版本、选项和描述。 - \det[x+] [ pattern ] + \det[+] [ pattern ] - 列出外部表(助记符:external tables)。如果指定了 pattern,则只列出表名或模式名与模式匹配的条目。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则还会显示通用选项以及外部表描述。 + 列出外部表(助记符:external tables)。如果指定了 pattern,则只列出表名或模式名与模式匹配的条目。如果在命令名后追加 +,则还会显示通用选项以及外部表描述。 - \deu[x+] [ pattern ] + \deu[+] [ pattern ] 列出用户映射(助记符:external - users)。如果指定了 pattern,则只列出用户名与模式匹配的映射。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则会显示每个映射的附加信息。 + users)。如果指定了 pattern,则只列出用户名与模式匹配的映射。如果在命令名后追加 +,则会显示每个映射的附加信息。 @@ -1146,136 +1092,135 @@ SELECT $1 \parse stmt1 - \dew[x+] [ pattern ] + \dew[+] [ pattern ] 列出外部数据包装器(助记符:external - wrappers)。如果指定了 pattern,则只列出名称与模式匹配的外部数据包装器。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则还会显示外部数据包装器的访问权限、选项和描述。 + wrappers)。如果指定了 pattern,则只列出名称与模式匹配的外部数据包装器。如果在命令名后追加 +,则还会显示外部数据包装器的访问权限、选项和描述。 - \df[anptwSx+] [ pattern [ arg_pattern ... ] ] + \df[anptwS+] [ pattern [ arg_pattern ... ] ] 列出函数,以及它们的结果数据类型、参数数据类型和函数类型,函数类型分为 agg(聚合)、normalproceduretriggerwindow。要只显示特定类型的函数,请在命令后添加相应的字母 anptw。如果指定了 pattern,则只显示名称与模式匹配的函数。任何附加参数都是类型名模式,分别与函数第一、第二等参数的类型名匹配。(匹配到的函数可以比你指定的参数更多;若要防止这种情况,可将破折号 - 写成最后一个 arg_pattern。)默认情况下,只显示用户创建的对象;提供模式或 S - 修饰符可包括系统对象。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则会显示每个函数的附加信息,包括易变性、并行安全性、所有者、安全分类、是否防漏、访问权限、语言、内部名称(仅适用于 C 和 internal 函数)以及描述。特定函数的源代码可通过 \sf 查看。 + 修饰符可包括系统对象。如果在命令名后追加 +,则会显示每个函数的附加信息,包括易变性、并行安全性、所有者、安全分类、是否防漏、访问权限、语言、内部名称(仅适用于 C 和 internal 函数)以及描述。特定函数的源代码可通过 \sf 查看。 - \dF[x+] [ pattern ] + \dF[+] [ pattern ] - 列出文本搜索配置。如果指定了 pattern,则只显示名称与模式匹配的配置。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则会显示每个配置的完整描述,包括底层文本搜索解析器以及每种记号类型对应的词典列表。 + 列出文本搜索配置。如果指定了 pattern,则只显示名称与模式匹配的配置。如果在命令名后追加 +,则会显示每个配置的完整描述,包括底层文本搜索解析器以及每种记号类型对应的词典列表。 - \dFd[x+] [ pattern ] + \dFd[+] [ pattern ] - 列出文本搜索词典。如果指定了 pattern,则只显示名称与模式匹配的词典。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则会显示每个所选词典的附加信息,包括底层文本搜索模板和选项值。 + 列出文本搜索词典。如果指定了 pattern,则只显示名称与模式匹配的词典。如果在命令名后追加 +,则会显示每个所选词典的附加信息,包括底层文本搜索模板和选项值。 - \dFp[x+] [ pattern ] + \dFp[+] [ pattern ] - 列出文本搜索解析器。如果指定了 pattern,则只显示名称与模式匹配的解析器。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则会显示每个解析器的完整描述,包括底层函数和已识别的记号类型列表。 + 列出文本搜索解析器。如果指定了 pattern,则只显示名称与模式匹配的解析器。如果在命令名后追加 +,则会显示每个解析器的完整描述,包括底层函数和已识别的记号类型列表。 - \dFt[x+] [ pattern ] + \dFt[+] [ pattern ] - 列出文本搜索模板。如果指定了 pattern,则只显示名称与模式匹配的模板。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则会显示每个模板的附加信息,包括底层函数名。 + 列出文本搜索模板。如果指定了 pattern,则只显示名称与模式匹配的模板。如果在命令名后追加 +,则会显示每个模板的附加信息,包括底层函数名。 - \dg[Sx+] [ pattern ] + \dg[S+] [ pattern ] 列出数据库角色。(由于 usersgroups 的概念已经统一为 roles,此命令现在等同于 \du。)默认情况下,只显示用户创建的角色;提供 - S 修饰符可包括系统角色。如果指定了 pattern,则只列出名称与模式匹配的角色。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则会显示每个角色的附加信息;目前这会增加每个角色的注释。 + S 修饰符可包括系统角色。如果指定了 pattern,则只列出名称与模式匹配的角色。如果在命令名后追加 +,则会显示每个角色的附加信息;目前这会增加每个角色的注释。 - \dl[x+] + \dl[+] - 这是 \lo_list 的别名,后者会显示大对象列表。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则会列出每个大对象的相关权限(如果有)。 + 这是 \lo_list 的别名,后者会显示大对象列表。如果在命令名后追加 +,则会列出每个大对象的相关权限(如果有)。 - \dL[Sx+] [ pattern ] + \dL[S+] [ pattern ] 列出过程语言。如果指定了 pattern,则只列出名称与模式匹配的语言。默认情况下,只显示用户创建的语言;提供 S 修饰符可包括系统对象。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则每种语言都会连同其调用处理器、验证器、访问权限以及它是否为系统对象一起列出。 + class="parameter">pattern,则只列出名称与模式匹配的语言。默认情况下,只显示用户创建的语言;提供 S 修饰符可包括系统对象。如果在命令名后追加 +,则每种语言都会连同其调用处理器、验证器、访问权限以及它是否为系统对象一起列出。 - \dn[Sx+] [ pattern ] + \dn[S+] [ pattern ] 列出模式(命名空间)。如果指定了 pattern,则只列出名称与模式匹配的模式。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则每个对象都会连同其相关权限和描述(如果有)一起列出。 + class="parameter">pattern,则只列出名称与模式匹配的模式。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。如果在命令名后追加 +,则每个对象都会连同其相关权限和描述(如果有)一起列出。 - \do[Sx+] [ pattern [ arg_pattern [ arg_pattern ] ] ] + \do[S+] [ pattern [ arg_pattern [ arg_pattern ] ] ] - 列出操作符及其操作数类型和结果类型。如果指定了 pattern,则只列出名称与模式匹配的操作符。如果指定了一个 arg_pattern,则只列出其右参数类型名称与该模式匹配的前缀操作符。如果指定了两个 arg_pattern,则只列出参数类型名称与这些模式匹配的二元操作符。(对于一元操作符未使用的参数,也可以写成 -。)默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则会显示每个操作符的附加信息,包括底层函数名以及它是否防漏。 + 列出操作符及其操作数类型和结果类型。如果指定了 pattern,则只列出名称与模式匹配的操作符。如果指定了一个 arg_pattern,则只列出其右参数类型名称与该模式匹配的前缀操作符。如果指定了两个 arg_pattern,则只列出参数类型名称与这些模式匹配的二元操作符。(对于一元操作符未使用的参数,也可以写成 -。)默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。如果在命令名后追加 +,则会显示每个操作符的附加信息,包括底层函数名以及它是否防漏。 - \dO[Sx+] [ pattern ] + \dO[S+] [ pattern ] - 列出排序规则。如果指定了 pattern,则只列出名称与模式匹配的排序规则。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则每个排序规则都会连同其相关描述(如果有)一起列出。请注意,只会显示与当前数据库编码兼容的排序规则,因此在同一安装中的不同数据库里结果可能不同。 + 列出排序规则。如果指定了 pattern,则只列出名称与模式匹配的排序规则。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。如果在命令名后追加 +,则每个排序规则都会连同其相关描述(如果有)一起列出。请注意,只会显示与当前数据库编码兼容的排序规则,因此在同一安装中的不同数据库里结果可能不同。 - \dp[Sx] [ pattern ] + \dp[S] [ pattern ] - 列出表、视图和序列及其相关访问权限。如果指定了 pattern,则只列出名称与模式匹配的表、视图和序列。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。如果在命令名后追加 x,结果会以扩展模式显示。 - + 列出表、视图和序列及其相关访问权限。如果指定了 pattern,则只列出名称与模式匹配的表、视图和序列。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。 GRANT和 @@ -1288,7 +1233,7 @@ SELECT $1 \parse stmt1 - \dP[itnx+] [ pattern ] + \dP[itn+] [ pattern ] 列出分区关系。 @@ -1305,20 +1250,19 @@ SELECT $1 \parse stmt1 - 如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则还会显示每个关系分区大小的总和以及关系描述。如果 n+ 组合使用,则会显示两个大小:一个包括直接附加的叶分区的总大小,另一个显示包括间接附加子分区在内的所有分区总大小。 +如果在命令名后追加 +,则还会显示每个关系分区大小的总和以及关系描述。如果 n+ 组合使用,则会显示两个大小:一个包括直接附加的叶分区的总大小,另一个显示包括间接附加子分区在内的所有分区总大小。 - \drds[x] [ role-pattern [ database-pattern ] ] + \drds[ role-pattern [ database-pattern ] ] 列出已定义的配置设置。这些设置可以是特定于角色、特定于数据库,或者两者兼有。role-patterndatabase-pattern 分别用于选择要列出的特定角色和数据库。如果省略,或者指定了 - *,则会列出所有设置,包括那些未指定角色或数据库的设置。如果在命令名后追加 x,结果会以扩展模式显示。 - + *,则会列出所有设置,包括那些未指定角色或数据库的设置。 ALTER ROLE和 @@ -1330,7 +1274,7 @@ SELECT $1 \parse stmt1 - \drg[Sx] [ pattern ] + \drg[S] [ pattern ] 列出每个被授予角色成员身份的信息,包括被授予的选项(ADMIN、 @@ -1339,65 +1283,63 @@ SELECT $1 \parse stmt1 默认情况下,只显示授予用户创建角色的成员身份;提供 - S 修饰符可包括系统角色。如果指定了 pattern,则只列出名称与模式匹配的角色。如果在命令名后追加 x,结果会以扩展模式显示。 - + S 修饰符可包括系统角色。如果指定了 pattern,则只列出名称与模式匹配的角色。 - \dRp[x+] [ pattern ] + \dRp[+] [ pattern ] - 列出逻辑复制发布。如果指定了 pattern,则只列出名称与模式匹配的发布。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则还会显示与每个发布关联的表和模式。 + 列出逻辑复制发布。如果指定了 pattern,则只列出名称与模式匹配的发布。如果在命令名后追加 +,则还会显示与每个发布关联的表和模式。 - \dRs[x+] [ pattern ] + \dRs[+] [ pattern ] - 列出逻辑复制订阅。如果指定了 pattern,则只列出名称与模式匹配的订阅。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则会显示订阅的其他属性。 + 列出逻辑复制订阅。如果指定了 pattern,则只列出名称与模式匹配的订阅。如果在命令名后追加 +,则会显示订阅的其他属性。 - \dT[Sx+] [ pattern ] + \dT[S+] [ pattern ] - 列出数据类型。如果指定了 pattern,则只列出名称与模式匹配的类型。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则每个类型都会连同其内部名称和大小一起列出;对于 enum 类型,还会显示其允许值以及相关权限。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。 + 列出数据类型。如果指定了 pattern,则只列出名称与模式匹配的类型。如果在命令名后追加 +,则每个类型都会连同其内部名称和大小一起列出;对于 enum 类型,还会显示其允许值以及相关权限。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。 - \du[Sx+] [ pattern ] + \du[S+] [ pattern ] 列出数据库角色。(由于 usersgroups 的概念已经统一为 roles,此命令现在等同于 \dg。)默认情况下,只显示用户创建的角色;提供 - S 修饰符可包括系统角色。如果指定了 pattern,则只列出名称与模式匹配的角色。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则会显示每个角色的附加信息;目前这会增加每个角色的注释。 + S 修饰符可包括系统角色。如果指定了 pattern,则只列出名称与模式匹配的角色。如果在命令名后追加 +,则会显示每个角色的附加信息;目前这会增加每个角色的注释。 - \dx[x+] [ pattern ] + \dx[+] [ pattern ] - 列出已安装的扩展。如果指定了 pattern,则只列出名称与模式匹配的扩展。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则会列出属于每个匹配扩展的全部对象。 + 列出已安装的扩展。如果指定了 pattern,则只列出名称与模式匹配的扩展。如果在命令名后追加 +,则会列出属于每个匹配扩展的全部对象。 - \dX[x] [ pattern ] + \dX[ pattern ] - 列出扩展统计信息。如果指定了 pattern,则只列出名称与模式匹配的扩展统计信息。如果在命令名后追加 x,结果会以扩展模式显示。 - + 列出扩展统计信息。如果指定了 pattern,则只列出名称与模式匹配的扩展统计信息。 每种扩展统计信息的状态显示在以其统计类型命名的列中(例如 Ndistinct)。 @@ -1408,10 +1350,10 @@ SELECT $1 \parse stmt1 - \dy[x+] [ pattern ] + \dy[+] [ pattern ] - 列出事件触发器。如果指定了 pattern,则只列出名称与模式匹配的事件触发器。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则每个对象都会连同其相关描述一起列出。 + 列出事件触发器。如果指定了 pattern,则只列出名称与模式匹配的事件触发器。如果在命令名后追加 +,则每个对象都会连同其相关描述一起列出。 @@ -1658,11 +1600,7 @@ CREATE INDEX - 生成的查询按照返回的行的顺序执行,并在每行内从左到右执行,如果有多个列。NULL字段将被忽略。生成的查询文字 - 直接发送到服务器进行处理,因此它们不能是psql元命令,也不能包含psql - 变量引用。如果任何单个查询失败,剩余查询的执行将继续,除非设置了ON_ERROR_STOP。每个查询的执行 - 都受ECHO处理的影响。(通常在使用\gexec时,将ECHO设置为 - allqueries是明智的。)查询记录、单步模式、计时和其他查询执行功能也适用于每个生成的查询。 + 生成的查询按照返回行的顺序执行;如果有多列,则在每行内从左到右执行。NULL 字段会被忽略。生成的查询按原样发送到服务器进行处理,因此不能是psql元命令,也不能包含psql变量引用。如果某个查询失败,仍会继续执行其余查询,除非设置了ON_ERROR_STOP。每个查询的执行都受ECHO处理的影响。(通常,在使用\gexec时,适宜将ECHO设为allqueries。)查询日志、单步模式、计时及其他查询执行功能也适用于每个生成的查询。 如果当前查询缓冲区为空,则重新执行最近发送的查询。 @@ -1868,10 +1806,10 @@ SELECT - \l[x+] or \list[x+] [ pattern ] + \l[+] or \list[+] [ pattern ] - 列出服务器中的数据库,并显示其名称、所有者、字符集编码和访问权限。如果指定了 pattern,则只列出名称与模式匹配的数据库。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则还会显示数据库大小、默认表空间和描述。当前用户对其拥有 CONNECT 权限的数据库可以显示大小信息;如果当前用户是超级用户或具有 pg_read_all_stats 角色的权限,也可以显示大小信息。 + 列出服务器中的数据库,并显示其名称、所有者、字符集编码和访问权限。如果指定了 pattern,则只列出名称与模式匹配的数据库。如果在命令名后追加 +,则还会显示数据库大小、默认表空间和描述。当前用户对其拥有 CONNECT 权限的数据库可以显示大小信息;如果当前用户是超级用户或具有 pg_read_all_stats 角色的权限,也可以显示大小信息。 @@ -1902,7 +1840,7 @@ SELECT - 将文件存储到一个PostgreSQL大对象中。可选地,它将给定的注释与对象关联起来。例如: + 将文件存储到一个PostgreSQL大对象中。可选地,它将给定的注释与对象关联起来。例如: foo=> \lo_import '/home/peter/pictures/photo.xcf' 'a picture of me' lo_import 152801 @@ -1917,11 +1855,11 @@ lo_import 152801 - \lo_list[x+] + \lo_list[+] 显示当前存储在数据库中的全部 PostgreSQL - 大对象列表,以及为它们提供的任何注释。如果在命令名后追加 x,结果会以扩展模式显示。如果在命令名后追加 +,则会列出每个大对象的相关权限(如果有)。 + 大对象列表,以及为它们提供的任何注释。如果在命令名后追加 +,则会列出每个大对象的相关权限(如果有)。 @@ -1981,28 +1919,6 @@ lo_import 152801 - - \parse statement_name - - - 基于目标预备语句对象的名称,从当前查询缓冲区创建一个预备语句。空字符串表示未命名的预备语句。 - - - - 示例: - -SELECT $1 \parse stmt1 - - - - - 此命令会使用扩展查询协议,不同于psql通常使用的简单查询协议。该命令会发出一条 - - 消息,因此可用于在psql中测试扩展查询协议。此命令只影响下一条被执行的查询;之后的所有查询默认仍会使用简单查询协议。 - - - - \password [ username ] @@ -2048,7 +1964,7 @@ SELECT $1 \parse stmt1 - 可调整打印选项有: + 可调整打印选项有: border @@ -2148,7 +2064,7 @@ SELECT $1 \parse stmt1 允许使用唯一缩写。 - aligned格式是标准的、人类可读的、格式良好的文本输出;这是默认设置。 + aligned格式是标准的、适合人阅读且排版整齐的文本输出;这是默认格式。 unaligned格式将一行中的所有列写在一行上,由当前活动的字段分隔符分隔。这对于创建可能被其他程序读取的输出很有用,例如,制表符分隔或逗号分隔格式。然而,如果字段分隔符字符出现在列的值中,则不会被特殊处理;因此,CSV格式可能更适合这些目的。 @@ -2565,61 +2481,6 @@ testdb=> \setenv LESS -imx4F - - \startpipeline - \sendpipeline - \syncpipeline - \endpipeline - \flushrequest - \flush - \getresults [ number_results ] - - - - 这组命令实现 SQL 语句的管道化。一个管道必须以 \startpipeline 开始,并以 \endpipeline 结束。其间可以出现任意数量的 \syncpipeline 命令,它会发送一条同步消息,但不会结束当前管道,并会刷新发送缓冲区。在管道模式下,语句会被发送到服务器,而不等待前面语句的结果。更多细节见 。 - - - - 管道进行期间执行的所有查询都使用扩展查询协议。以分号结束的查询会被追加到管道中。元命令 \bind、 - \bind_named\close_prepared 和 - \parse 可以在进行中的管道里使用。管道进行期间,\sendpipeline 会将当前查询缓冲区追加到管道中。其他元命令,如 - \g\gx 或 - \gdesc,则不允许在管道模式中使用。 - - - - \flushrequest 会向管道追加一条 flush 命令,使得可以在不发送 sync 或结束管道的情况下通过 - \getresults 读取结果。\getresults 会自动将尚未发送的数据推送到服务器。\flush 可用于手动推送未发送的数据。 - - - - \getresults 接受一个可选的 - number_results 参数。如果提供,则只读取前 - number_results 个待处理结果。若省略该参数或其值为 0,则读取所有待处理结果。 - - - - 当管道模式处于活动状态时,可使用一个专用的提示符变量来报告管道状态。详见 。 - - - - COPY 在管道模式中不支持。 - - - - 示例: - -\startpipeline -SELECT * FROM pg_class; -SELECT 1 \bind \sendpipeline -\flushrequest -\getresults -\endpipeline - - - - - @@ -2721,8 +2582,7 @@ SELECT 1 \bind \sendpipeline \watch [ i[nterval]=seconds ] [ c[ount]=times ] [ m[in_rows]=rows ] [ seconds ] - 重复执行当前查询缓冲区(如同 \g 一样),直到被中断、查询失败、达到执行次数上限(如果给定)或查询返回的行数低于最小要求。两次执行之间等待指定的秒数(默认 2 秒)。默认等待时间可通过变量 - 修改。为保持向后兼容, + 重复执行当前查询缓冲区(如同 \g 一样),直到被中断、查询失败、达到执行次数上限(如果给定)或查询返回的行数低于最小要求。两次执行之间等待指定的秒数(默认 2 秒)。为保持向后兼容, seconds 可以带或不带 interval= 前缀。每次查询结果都会带有一个头部,其中包含 \pset title 字符串(如果有)、查询开始时的时间以及延迟间隔。 @@ -2744,11 +2604,10 @@ SELECT 1 \bind \sendpipeline - \z[Sx] [ pattern ] + \z[S] [ pattern ] - 列出表、视图和序列及其相关访问权限。如果指定了 pattern,则只列出名称与模式匹配的表、视图和序列。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。如果在命令名后追加 x,结果会以扩展模式显示。 - + 列出表、视图和序列及其相关访问权限。如果指定了 pattern,则只列出名称与模式匹配的表、视图和序列。默认情况下,只显示用户创建的对象;提供模式或 S 修饰符可包括系统对象。 这是\dp的别名(显示权限)。 @@ -3126,34 +2985,8 @@ bar - - PIPELINE_COMMAND_COUNT - - - 正在运行的管道中排队的命令数 。 - - - - - PIPELINE_RESULT_COUNT - - - 正在进行的管道中,有多少条命令后面跟着 \flushrequest 或 - \syncpipeline,从而强制服务器发送结果。这些结果可以通过 - \getresults 取回。 - - - - - PIPELINE_SYNC_COUNT - - - 正在运行的管道中排队的同步消息数量 。 - - - PORT @@ -3203,14 +3036,6 @@ bar - - SERVICE - - - 服务名称(如果适用)。 - - - SHELL_ERROR @@ -3312,14 +3137,6 @@ bar - - WATCH_INTERVAL - - - 此变量设置\watch在两次执行查询之间等待的默认间隔,单位为秒。默认值为 2 秒。若在命令中指定了间隔,则会覆盖此变量。 - - - @@ -3329,7 +3146,7 @@ bar <acronym>SQL</acronym> 中插入变量 - psql变量的一个关键特性是可以把它们替换(插入)到常规SQL语句中,也可以把它们作为元命令的参数。此外,psql还提供了功能来确保被用作 SQL 文字和标识符的变量值会被正确地引用。插入一个值而不需要加引用的语法是在变量名前面加上一个冒号(:)。例如, + psql变量的一个关键特性是可以把它们替换(插入)到常规SQL语句中,也可以把它们作为元命令的参数。此外,psql还提供了功能来确保被用作 SQL 字面量和标识符的变量值会被正确地加引号。插入一个值而不加引号的语法是在变量名前面加上一个冒号(:)。例如, testdb=> \set foo 'my_table' testdb=> SELECT * FROM :foo; @@ -3416,10 +3233,6 @@ testdb=> INSERT INTO my_table VALUES (:'content'); - - %s - 服务名称。 - %/ @@ -3450,16 +3263,6 @@ testdb=> INSERT INTO my_table VALUES (:'content'); - - %P - - - 管道状态:不在管道中时为 off, - 在进行中的管道中时为 on, - 在已中止的管道中时为 abort。 - - - %R @@ -3989,28 +3792,6 @@ testdb=> \df int*pl * bigint - - 这里,+ 选项用于显示其中一个函数的附加信息,而 x 用于以扩展模式显示结果: - -testdb=> \df+x int*pl integer bigint -List of functions --[ RECORD 1 ]-------+----------------------------- -Schema | pg_catalog -Name | int48pl -Result data type | bigint -Argument data types | integer, bigint -Type | func -Volatility | immutable -Parallel | safe -Owner | postgres -Security | invoker -Leakproof? | no -Access privileges | -Language | internal -Internal name | int48pl -Description | implementation of + operator - - 在适合的情况下,可以使用 \crosstabview 命令将查询结果显示为交叉表: diff --git a/zh/17/ref/reassign_owned.sgml b/zh/17/ref/reassign_owned.sgml index 824834b8..ba7d9f7b 100644 --- a/zh/17/ref/reassign_owned.sgml +++ b/zh/17/ref/reassign_owned.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation REASSIGN OWNED 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/refresh_materialized_view.sgml b/zh/17/ref/refresh_materialized_view.sgml index 2ccb7ac0..7d0fed7a 100644 --- a/zh/17/ref/refresh_materialized_view.sgml +++ b/zh/17/ref/refresh_materialized_view.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation REFRESH MATERIALIZED VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/reindex.sgml b/zh/17/ref/reindex.sgml index de685b67..73010807 100644 --- a/zh/17/ref/reindex.sgml +++ b/zh/17/ref/reindex.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation REINDEX 7 - SQL - Language Statements + SQL - 语言语句 @@ -189,9 +189,7 @@ REINDEX [ ( option [, ...] ) ] { DA VERBOSE - - 在每个索引被重建时,以 INFO 级别打印进度报告。 - + 在每个索引被重建时打印进度报告。 @@ -304,7 +302,7 @@ REINDEX [ ( option [, ...] ) ] { DA 当对分区索引或分区表执行带TABLESPACE子句的 REINDEX时,只有叶分区的表空间引用会被更新。由于 - 分区索引本身不会更新,建议另外对相应的分区表单独执行 + 分区索引本身不会更新,建议另外对这些分区索引单独执行 ALTER TABLE ONLY,以便后续附加的任何新分区都继承 新表空间。如果命令失败,可能不会把所有索引都移动到新表空间。重新运行 该命令将重建所有叶分区,并把先前未处理的索引移动到新表空间。 @@ -322,8 +320,8 @@ REINDEX [ ( option [, ...] ) ] { DA 并发重建索引 - index - rebuilding concurrently + 索引 + 并发重建 diff --git a/zh/17/ref/reindexdb.sgml b/zh/17/ref/reindexdb.sgml index 20dc32bf..5fc8edd5 100644 --- a/zh/17/ref/reindexdb.sgml +++ b/zh/17/ref/reindexdb.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation reindexdb 1 - Application + 应用程序 diff --git a/zh/17/ref/release_savepoint.sgml b/zh/17/ref/release_savepoint.sgml index 59f96e68..ca94cc38 100644 --- a/zh/17/ref/release_savepoint.sgml +++ b/zh/17/ref/release_savepoint.sgml @@ -10,13 +10,13 @@ PostgreSQL documentation 保存点 - releasing + 释放 RELEASE SAVEPOINT 7 - SQL - Language Statements + SQL - 语言语句 @@ -99,7 +99,7 @@ BEGIN; SAVEPOINT sp2; INSERT INTO table1 VALUES (3); RELEASE SAVEPOINT sp2; - INSERT INTO table1 VALUES (4))); -- generates an error + INSERT INTO table1 VALUES (4))); -- 产生错误 在这个例子中,应用程序请求释放保存点sp2,值 3 是在其中插入的。 这样会把该插入操作的事务上下文改为sp1。 diff --git a/zh/17/ref/reset.sgml b/zh/17/ref/reset.sgml index e8aeae8c..5e249ff9 100644 --- a/zh/17/ref/reset.sgml +++ b/zh/17/ref/reset.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation RESET 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/revoke.sgml b/zh/17/ref/revoke.sgml index 8d7945a5..c2d7aee8 100644 --- a/zh/17/ref/revoke.sgml +++ b/zh/17/ref/revoke.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation REVOKE 7 - SQL - Language Statements + SQL - 语言语句 @@ -131,7 +131,7 @@ REVOKE [ { ADMIN | INHERIT | SET } OPTION FOR ] [ GRANTED BY role_specification ] [ CASCADE | RESTRICT ] -where role_specification can be: +其中role_specification可以是: [ GROUP ] role_name | PUBLIC diff --git a/zh/17/ref/rollback.sgml b/zh/17/ref/rollback.sgml index d1c8fdd2..1a91b03e 100644 --- a/zh/17/ref/rollback.sgml +++ b/zh/17/ref/rollback.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ROLLBACK 7 - SQL - Language Statements + SQL - 语言语句 @@ -37,7 +37,7 @@ ROLLBACK [ WORK | TRANSACTION ] [ AND [ NO ] CHAIN ] 参数 - chained transactions + 链式事务 diff --git a/zh/17/ref/rollback_prepared.sgml b/zh/17/ref/rollback_prepared.sgml index 7ffe1af8..7438d9cc 100644 --- a/zh/17/ref/rollback_prepared.sgml +++ b/zh/17/ref/rollback_prepared.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ROLLBACK PREPARED 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/rollback_to.sgml b/zh/17/ref/rollback_to.sgml index 843a612e..d5d8c0e0 100644 --- a/zh/17/ref/rollback_to.sgml +++ b/zh/17/ref/rollback_to.sgml @@ -10,13 +10,13 @@ PostgreSQL documentation 保存点 - rolling back + 回滚 ROLLBACK TO SAVEPOINT 7 - SQL - Language Statements + SQL - 语言语句 @@ -73,8 +73,8 @@ ROLLBACK [ WORK | TRANSACTION ] TO [ SAVEPOINT ] savepoint_name 就保存点而言,游标带有一些非事务性的行为。凡是在某个保存点内打开的游标, 在回滚该保存点时都会被关闭。如果先前打开的游标在某个随后又被回滚的保存点内受到了 - FETCHMOVE命令的影响,那么该游标会保留在这些命令使其指向的位置上 - (也就是说,由FETCHMOVE引起的游标移动不会被回滚)。 + FETCHMOVE命令的影响,那么该游标会保留在FETCH使其指向的位置上 + (也就是说,由FETCH引起的游标移动不会被回滚)。 关闭游标同样不会因回滚而撤销。不过,如果游标查询导致了其他副作用(例如该查询调用的 易变函数带来的副作用),且这些副作用发生在后来被回滚的保存点期间,那么它们 被回滚。如果某个游标的执行导致事务中止,该游标会进入不可执行状态, diff --git a/zh/17/ref/savepoint.sgml b/zh/17/ref/savepoint.sgml index fdca4151..5f9bea25 100644 --- a/zh/17/ref/savepoint.sgml +++ b/zh/17/ref/savepoint.sgml @@ -10,13 +10,13 @@ PostgreSQL documentation 保存点 - defining + 定义 SAVEPOINT 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/security_label.sgml b/zh/17/ref/security_label.sgml index fc969a4a..9c2b13d0 100644 --- a/zh/17/ref/security_label.sgml +++ b/zh/17/ref/security_label.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SECURITY LABEL 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/select.sgml b/zh/17/ref/select.sgml index 1b47aa6d..19abe844 100644 --- a/zh/17/ref/select.sgml +++ b/zh/17/ref/select.sgml @@ -21,7 +21,7 @@ PostgreSQL documentation SELECT 7 - SQL - Language Statements + SQL - 语言语句 @@ -1485,7 +1485,7 @@ SELECT * FROM (SELECT * FROM mytable FOR UPDATE) ss ORDER BY column1; REPEATABLE READSERIALIZABLE事务隔离级别下, - 这将导致序列化失败(带有SQLSTATE'40001'), + 这将导致串行化失败(SQLSTATE'40001'), 因此在这些隔离级别下不可能接收到无序的行。 diff --git a/zh/17/ref/select_into.sgml b/zh/17/ref/select_into.sgml index a05e57e8..12a48774 100644 --- a/zh/17/ref/select_into.sgml +++ b/zh/17/ref/select_into.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SELECT INTO 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/set.sgml b/zh/17/ref/set.sgml index ab67075e..9702d560 100644 --- a/zh/17/ref/set.sgml +++ b/zh/17/ref/set.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SET 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/set_constraints.sgml b/zh/17/ref/set_constraints.sgml index 53d0c7a0..e5588db7 100644 --- a/zh/17/ref/set_constraints.sgml +++ b/zh/17/ref/set_constraints.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SET CONSTRAINTS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/set_role.sgml b/zh/17/ref/set_role.sgml index ed65dec8..c32755be 100644 --- a/zh/17/ref/set_role.sgml +++ b/zh/17/ref/set_role.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SET ROLE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/set_session_auth.sgml b/zh/17/ref/set_session_auth.sgml index e520dd49..e7692edc 100644 --- a/zh/17/ref/set_session_auth.sgml +++ b/zh/17/ref/set_session_auth.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SET SESSION AUTHORIZATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/set_transaction.sgml b/zh/17/ref/set_transaction.sgml index ca7f3e50..8b3470a9 100644 --- a/zh/17/ref/set_transaction.sgml +++ b/zh/17/ref/set_transaction.sgml @@ -26,7 +26,7 @@ PostgreSQL documentation SET TRANSACTION 7 - SQL - Language Statements + SQL - 语言语句 @@ -66,7 +66,7 @@ SET SESSION CHARACTERISTICS AS TRANSACTION transa - 一个事务的隔离级别决定当其他事务并行运行时该事务能看见什么数据: + 一个事务的隔离级别决定当其他事务并发运行时该事务能看见什么数据: @@ -137,7 +137,7 @@ SET SESSION CHARACTERISTICS AS TRANSACTION transa 事务属性才会生效。当为一个事务同时选择这三个属性时,该事务在 首次获取其快照时可能会阻塞;在此之后,它便可以运行,而无需承担普通 SERIALIZABLE事务的常规开销,也不会有促成 - 序列化失败或因序列化失败而被取消的风险。这种模式非常适合长时间运行的 + 串行化失败或因串行化失败而被取消的风险。这种模式非常适合长时间运行的 报表或备份。 diff --git a/zh/17/ref/show.sgml b/zh/17/ref/show.sgml index 3b4be6bd..81bd6a80 100644 --- a/zh/17/ref/show.sgml +++ b/zh/17/ref/show.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SHOW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/start_transaction.sgml b/zh/17/ref/start_transaction.sgml index 57a74b2f..5026fa70 100644 --- a/zh/17/ref/start_transaction.sgml +++ b/zh/17/ref/start_transaction.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation START TRANSACTION 7 - SQL - Language Statements + SQL - 语言语句 @@ -64,15 +64,16 @@ START TRANSACTION [ transaction_mode - DEFERRABLE 这一 - transaction_mode 是 - PostgreSQL语言扩展。 + DEFERRABLE + transaction_mode + 是PostgreSQL的一种语言扩展。 SQL 标准要求在连续的transaction_modes之间有逗号, - 但出于历史原因PostgreSQL允许省略逗号。 + 但出于历史原因, + PostgreSQL允许省略逗号。 diff --git a/zh/17/ref/truncate.sgml b/zh/17/ref/truncate.sgml index aa2ce51c..ff1e0bc9 100644 --- a/zh/17/ref/truncate.sgml +++ b/zh/17/ref/truncate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation TRUNCATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/unlisten.sgml b/zh/17/ref/unlisten.sgml index 5e73e99e..6b52f1af 100644 --- a/zh/17/ref/unlisten.sgml +++ b/zh/17/ref/unlisten.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation UNLISTEN 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/ref/update.sgml b/zh/17/ref/update.sgml index a3c965df..4ace7c49 100644 --- a/zh/17/ref/update.sgml +++ b/zh/17/ref/update.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation UPDATE 7 - SQL - Language Statements + SQL - 语言语句 @@ -313,12 +313,12 @@ UPDATE count 在被移动的行上并发执行UPDATE或 - DELETE时,有可能收到序列化失败错误。假设会话 1 - 正在更新某个分区键,与此同时,一个对该行可见的并发会话 2 对该行 + DELETE时,有可能收到串行化失败错误。假设会话 1 + 正在对某个分区键执行UPDATE,与此同时,一个能够看到该行的并发会话 2 对该行 执行UPDATEDELETE操作。在 这种情况下,会话 2 的UPDATE或 - DELETE将检测到行移动,并引发序列化失败错误 - (其 SQLSTATE 代码始终为'40001')。如果发生 + DELETE将检测到行移动,并引发串行化失败错误 + (其 SQLSTATE 代码始终为'40001')。如果发生 这种情况,应用程序可能需要重试事务。在表未分区或没有发生行移动 的通常情况下,会话 2 会识别出新更新的那一行,并在这个新行版本上执行 UPDATE/DELETE。 diff --git a/zh/17/ref/vacuum.sgml b/zh/17/ref/vacuum.sgml index f7803d37..49e54aca 100644 --- a/zh/17/ref/vacuum.sgml +++ b/zh/17/ref/vacuum.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation VACUUM 7 - SQL - Language Statements + SQL - 语言语句 @@ -42,7 +42,7 @@ VACUUM [ ( option [, ...] ) ] [ 其中table_and_columns是: - [ ONLY ] table_name [ * ] [ ( column_name [, ...] ) ] + table_name [ ( column_name [, ...] ) ] @@ -75,7 +75,7 @@ VACUUM [ ( option [, ...] ) ] [ 并行清理。 - 如需禁用该功能,可以使用PARALLEL选项并将并行工作者数指定为零。 + 如需禁用该功能,可以使用PARALLEL选项并将并行工作进程数指定为零。 VACUUM FULL会把表的全部内容重写到一个没有额外空闲空间的新磁盘文件中, 从而让未使用的空间能够返还给操作系统。这种形式要慢得多,并且在处理每个表时都需要 ACCESS EXCLUSIVE锁。 @@ -114,7 +114,7 @@ VACUUM [ ( option [, ...] ) ] [ VERBOSE - 为每个表以INFO级别输出详细的清理活动报告。 + 为每个表输出详细的清理活动报告。 @@ -319,12 +319,7 @@ VACUUM [ ( option [, ...] ) ] [ table_name - - 要清理的特定表或物化视图的名称(可选地带模式限定)。 - 如果在表名前指定ONLY,则只清理该表。 - 如果未指定ONLY,则还会清理该表及其所有继承子表或分区(如果有)。 - 也可以在表名后显式指定*,以明确表示要清理继承子表(或分区)。 - + 要清理的特定表或物化视图的名称(可选地带模式限定)。如果指定的表是分区表,则清理它的所有叶子分区。 @@ -373,7 +368,7 @@ VACUUM [ ( option [, ...] ) ] [ - 我们建议定期对所有数据库执行清理,以移除死行。PostgreSQL提供了一个autovacuum机制, + 我们建议定期对所有数据库执行清理,以移除死行。PostgreSQL提供了一个自动清理(autovacuum)机制, 可以自动执行常规清理维护。有关自动与手动清理的更多信息,参见 @@ -391,8 +386,8 @@ VACUUM [ ( option [, ...] ) ] [ VACUUM会显著增加 I/O 流量,这可能导致其他活动会话性能变差。 - 因此,有时建议使用基于代价的清理延迟特性。对于并行清理,每个工作者的睡眠时长 - 都与该工作者完成的工作量成比例。详见。 + 因此,有时建议使用基于代价的清理延迟特性。对于并行清理,每个工作进程的睡眠时长 + 都与该工作进程完成的工作量成比例。详见 @@ -408,7 +403,7 @@ VACUUM [ ( option [, ...] ) ] [ 示例 - 清理单个表onek,对其执行优化器分析,并打印详细的清理活动报告: + 清理单个表onek,对其进行分析以供优化器使用,并打印详细的清理活动报告: VACUUM (VERBOSE, ANALYZE) onek; diff --git a/zh/17/ref/vacuumdb.sgml b/zh/17/ref/vacuumdb.sgml index 4396e2e0..6810a55a 100644 --- a/zh/17/ref/vacuumdb.sgml +++ b/zh/17/ref/vacuumdb.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation vacuumdb 1 - Application + 应用程序 @@ -132,8 +132,8 @@ PostgreSQL documentation - 指定给定一次 缓冲区访问策略(Buffer Access Strategy) - 环形缓冲区大小,供 vacuumdb 调用使用。这个大小用于计算将作为该策略一部分被重用的共享缓冲区数量。参见 + 为一次给定的 vacuumdb 调用指定缓冲区访问策略(Buffer Access Strategy) + 环形缓冲区大小。这个大小用于计算将作为该策略一部分被重用的共享缓冲区数量。参见 @@ -187,7 +187,7 @@ PostgreSQL documentation - 积极地冻结元组。 + 激进地冻结元组。 @@ -225,12 +225,12 @@ PostgreSQL documentation - 仅对 multixact ID 年龄至少为 mxid_age - 的表执行清理或分析命令。此设置可用于优先处理表,以防止 multixact ID 回卷 + 仅对 多事务 ID 年龄至少为 mxid_age + 的表执行清理或分析命令。此设置可用于优先处理表,以防止 多事务 ID 回卷 (见 )。 - 就此选项而言,一个关系的 multixact ID 年龄,是其主关系及其关联的 + 就此选项而言,一个关系的 多事务 ID 年龄,是其主关系及其关联的 TOAST 表(如果存在)年龄中的较大者。由于 vacuumdb 发出的命令在必要时也会处理该关系的 TOAST 表,因此无需单独考虑它。 @@ -254,28 +254,7 @@ PostgreSQL documentation - - - - - 仅分析那些在列、索引表达式或扩展统计信息对象上缺少统计信息的关系。与 - 一起使用时,此选项可防止 - vacuumdb 临时用按较低统计目标生成的统计信息替换现有统计信息, - 从而避免查询优化器短暂地作出更差的选择。 - - - 此选项只能与 配合使用。 - - - 注意, 要求拥有 - SELECT 权限,以访问 - pg_statistic - 和 - pg_statistic_ext_data, - 而这些权限默认只授予超级用户。 - - - + diff --git a/zh/17/ref/values.sgml b/zh/17/ref/values.sgml index e5b00372..8c6d7597 100644 --- a/zh/17/ref/values.sgml +++ b/zh/17/ref/values.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation VALUES 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/17/release-17.sgml b/zh/17/release-17.sgml index a79cbac5..81095a63 100644 --- a/zh/17/release-17.sgml +++ b/zh/17/release-17.sgml @@ -1802,14 +1802,14 @@ Branch: REL_14_STABLE [15fd7a3e2] 2026-07-28 10:56:39 +0200 --> - 在清理 GIN 索引 posting-tree 期间响应查询取消并遵守清理延迟 + 在清理 GIN 索引倒排树期间响应查询取消并遵守清理延迟 (Paul Kim、Alexander Korotkov) § - 常见值的 posting tree 可能很大,因此遗漏这项检查可能导致清理运行 + 常见值的倒排树可能很大,因此遗漏这项检查可能导致清理运行 很长时间后才注意到中断。 @@ -3639,7 +3639,7 @@ Branch: REL_15_STABLE [bab4f7fa5] 2026-05-05 10:32:42 +0900 Branch: REL_14_STABLE [172034f6e] 2026-05-05 10:34:07 +0900 --> - 在假定可排序类型上的等值条件意味着唯一性之前,检查是否存在非确定性排序规则 + 在假定支持排序规则的类型上的等值条件意味着唯一性之前,检查是否存在非确定性排序规则 (Richard Guo) § § @@ -9725,7 +9725,7 @@ Branch: REL_14_STABLE [5144e1f8f] 2025-03-11 12:50:35 +0100 Branch: REL_13_STABLE [f5b4a0b49] 2025-03-11 12:50:35 +0100 --> - 检测 BRIN 索引操作符类中缺失的支持过程,并报告错误而不是崩溃 + 检测 BRIN 索引操作符类中缺失的支持函数,并报告错误而不是崩溃 (Álvaro Herrera) § @@ -11209,7 +11209,7 @@ Branch: REL_14_STABLE [d9d5e1b48] 2024-12-07 14:28:16 -0500 Branch: REL_13_STABLE [531cbd8b7] 2024-12-07 14:28:16 -0500 --> - 修复操作符族成员操作符或支持过程可能成为悬空引用的情况 + 修复操作符族成员操作符或支持函数可能成为悬空引用的情况 (Tom Lane) § § diff --git a/zh/17/runtime.sgml b/zh/17/runtime.sgml index c23cf69a..fcc59552 100644 --- a/zh/17/runtime.sgml +++ b/zh/17/runtime.sgml @@ -17,7 +17,7 @@ <productname>PostgreSQL</productname>用户账户 - postgres user + postgres 用户 @@ -47,7 +47,7 @@ - 在做任何事情之前,必须先在磁盘上初始化一个数据库存储区域。我们把它称为数据库集簇。(SQL 标准使用术语 catalog cluster。)数据库集簇是由一个正在运行的数据库服务器实例管理的一组数据库。初始化之后,数据库集簇中会包含一个名为postgres的数据库,作为供工具、用户和第三方应用使用的默认数据库。数据库服务器本身并不要求该postgres数据库存在,但许多外部工具程序都假定它存在。初始化期间,集簇中还会创建另外两个数据库,名为template1template0。顾名思义,它们会作为后续新建数据库的模板;不应将它们用于实际工作。(关于在集簇中创建新数据库的信息,见。) + 在做任何事情之前,必须先在磁盘上初始化一个数据库存储区域。我们把它称为数据库集簇。(SQL 标准使用术语目录集簇(catalog cluster)。)数据库集簇是由一个正在运行的数据库服务器实例管理的一组数据库。初始化之后,数据库集簇中会包含一个名为postgres的数据库,作为供工具、用户和第三方应用使用的默认数据库。数据库服务器本身并不要求该postgres数据库存在,但许多外部工具程序都假定它存在。初始化期间,集簇中还会创建另外两个数据库,名为template1template0。顾名思义,它们会作为后续新建数据库的模板;不应将它们用于实际工作。(关于在集簇中创建新数据库的信息,见。) @@ -112,9 +112,7 @@ postgres$ initdb -D /usr/local/pgsql/data 另外,指定,以避免使用默认的trust认证方式;或者在运行initdb之后、首次启动服务器之前修改生成的pg_hba.conf文件。(其他合理方法包括使用peer认证,或使用文件系统权限限制连接。更多信息见。) - - initdb还会为数据库集簇初始化默认区域设置locale。通常,它只是采用环境中的区域设置,并将其应用到新初始化的数据库。你也可以为数据库指定不同的区域设置;更多信息见。该数据库集簇内部使用的默认排序顺序由initdb设定。虽然你可以创建采用不同排序顺序的新数据库,但initdb创建的模板数据库所使用的排序顺序,若不删除并重建它们就无法更改。使用非CPOSIX区域设置还会带来性能影响,因此第一次就做出正确选择很重要。 - + initdb 还会初始化数据库集簇的默认区域设置区域设置。通常,它会直接采用环境中的区域设置,并将其应用于初始化的数据库。可以为数据库指定不同的区域设置;更多信息见 。特定数据库集簇中使用的默认排序顺序由 initdb 设置,虽然你可以使用不同的排序顺序创建新数据库,但 initdb 创建的模板数据库所使用的顺序,只有删除并重建这些数据库才能更改。使用 CPOSIX 以外的区域设置还会影响性能。因此,一开始就作出正确选择很重要。 initdb还会为数据库集簇设置默认字符集编码。通常应选择与区域设置相匹配的字符集编码。详见。 @@ -162,9 +160,7 @@ postgres$ initdb -D /usr/local/pgsql/data 对于在PostgreSQL中使用NFS,唯一硬性要求是文件系统必须使用hard选项挂载。使用hard选项时,如果出现网络问题,进程可能会无限期地挂起,因此这种配置需要配套谨慎的监控措施。soft选项会在网络问题出现时中断系统调用,但PostgreSQL不会重试以这种方式被中断的系统调用,因此任何此类中断都会导致报告 I/O 错误。 - - 没有必要使用sync挂载选项。async选项的行为已经足够,因为PostgreSQL会在适当的时候发出fsync调用来刷新写缓存。(这和它在本地文件系统上的工作方式类似。)但是,强烈建议在支持该选项的NFS服务器端系统上使用sync导出选项(主要是 Linux)。否则,NFS 客户端上的fsync或等效操作实际上并不能保证数据到达服务器上的持久存储,这可能导致类似于将参数设为关闭时那样的损坏。这些挂载和导出选项的默认值在不同厂商和版本间并不相同,因此无论如何都建议检查它们,并且最好显式指定,以避免歧义。 - + 没有必要使用 sync 挂载选项。async 选项的行为已经足够,因为 PostgreSQL 会在适当的时候发出 fsync 调用将写缓存刷盘。(这和它在本地文件系统上的工作方式类似。)但是,强烈建议在支持该选项的 NFS 服务器端系统上使用 sync 导出选项(主要是 Linux)。否则,NFS 客户端上的 fsync 或等效操作实际上并不能保证数据到达服务器上的持久存储,这可能导致类似于将参数 设为关闭时那样的损坏。这些挂载和导出选项的默认值在不同厂商和版本间并不相同,因此无论如何都建议检查它们,并且最好显式指定,以避免歧义。 在某些情况下,可以通过 NFS 或更底层的协议(例如 iSCSI)访问外部存储产品。在后一种情况下,存储会表现为块设备,可以在其上创建任意可用的文件系统。这种方式或许能让 DBA 不必应对 NFS 的某些特性,但当然,管理远程存储的复杂性会转移到其他层面。 @@ -215,7 +211,7 @@ pg_ctl start -l logfile - 通常,你会希望在计算机启动时就启动数据库服务器。与系统引导时启动服务器相关的booting启动服务器时自动启动脚本依赖于操作系统。PostgreSQLcontrib/start-scripts 目录中附带了一些示例脚本。安装这些脚本需要 root 权限。 + 通常,你会希望在计算机启动时就启动数据库服务器。引导期间启动服务器自动启动脚本依赖于操作系统。PostgreSQLcontrib/start-scripts 目录中附带了一些示例脚本。安装这些脚本需要 root 权限。 @@ -232,14 +228,14 @@ su postgres -c 'pg_ctl start -D /usr/local/pgsql/data -l serverlog' 对于FreeBSD,请查看PostgreSQL源码发布包中的contrib/start-scripts/freebsd文件。 - FreeBSDstart script + FreeBSD启动脚本 OpenBSD上,把以下内容加入/etc/rc.local: - OpenBSDstart script + OpenBSD启动脚本 if [ -x /usr/local/pgsql/bin/pg_ctl -a -x /usr/local/pgsql/bin/postgres ]; then su -l postgres -c '/usr/local/pgsql/bin/pg_ctl start -s -l /var/postgresql/log -D /usr/local/pgsql/data' @@ -252,7 +248,7 @@ fi Linux系统上,可以把 - Linuxstart script + Linux启动脚本 /usr/local/pgsql/bin/pg_ctl start -l logfile -D /usr/local/pgsql/data @@ -291,14 +287,14 @@ WantedBy=multi-user.target NetBSD上,可根据偏好使用FreeBSDLinux的启动脚本。 - NetBSDstart script + NetBSD启动脚本 Solaris上,创建一个名为/etc/init.d/postgresql的文件,其中包含以下内容: - Solarisstart script + Solaris启动脚本 su - postgres -c "/usr/local/pgsql/bin/pg_ctl start -l logfile -D /usr/local/pgsql/data" @@ -372,7 +368,7 @@ DETAIL: Failed system call was semget(5440126, 17, 03600). psql: error: connection to server at "server.joe.com" (123.123.123.123), port 5432 failed: Connection refused Is the server running on that host and accepting TCP/IP connections? - 这是一个典型的我找不到可通信的服务器错误。上面这种情况发生在尝试使用 TCP/IP 通信时。一个常见错误是忘记配置the server,从而导致服务器不允许 TCP/IP 连接。 + 这是一个典型的我找不到可通信的服务器错误。上面这种情况发生在尝试使用 TCP/IP 通信时。一个常见错误是忘记配置服务器以允许 TCP/IP 连接。 @@ -395,7 +391,7 @@ psql: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: No such 管理内核资源 - PostgreSQL有时会耗尽操作系统的各种资源限制,尤其是在同一系统上运行多个服务器副本,或在非常大型的安装环境中时更是如此。本节解释PostgreSQL使用的内核资源,以及你可以采取哪些步骤来解决与内核资源消耗相关的问题。 + PostgreSQL有时会达到操作系统的各种资源上限,尤其是在同一系统上运行多个服务器实例,或在非常大型的安装环境中时更是如此。本节解释PostgreSQL使用的内核资源,以及你可以采取哪些步骤来解决与内核资源消耗相关的问题。 @@ -419,7 +415,7 @@ psql: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: No such - System V IPC 功能通常受系统范围的分配限制约束。当PostgreSQL超出这些限制之一时,服务器会拒绝启动,并留下带有指导性的错误消息,说明问题所在以及应如何处理(另见)。相关内核参数在不同系统上的命名基本一致,给出了概览;不过,设置它们的方法却各不相同。下面给出一些平台上的建议。 + System V IPC 功能通常受系统范围的分配限制约束。当PostgreSQL超出这些限制之一时,服务器会拒绝启动,并应留下带有指导性的错误消息,说明问题所在以及应如何处理(另见)。相关内核参数在不同系统上的命名基本一致,给出了概览;不过,设置它们的方法却各不相同。下面给出一些平台上的建议。
@@ -444,7 +440,7 @@ psql: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: No such SHMMAX 共享内存段的最大尺寸(字节) - 至少 1kB,但是默认值通常要高一些 + 至少 1kB,但是默认值通常高得多 @@ -507,8 +503,8 @@ psql: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: No such
- PostgreSQL要求少量字节的 System V 共享内存(在 64 位平台上通常是 48 字节)用于每一个服务器拷贝。在大多数现代操作系统上,这个量很容易得到。 - 但是,如果你运行了很多个服务器副本,或者显式配置服务器以使用大量 System V 共享内存(参见 ), + PostgreSQL要求少量字节的 System V 共享内存(在 64 位平台上通常是 48 字节)用于每一个服务器实例。在大多数现代操作系统上,这个量很容易得到。 + 但是,如果你运行了很多个服务器实例,或者显式配置服务器以使用大量 System V 共享内存(参见 ), 可能需要增加SHMALL(系统范围内 System V 共享内存的总量)。注意在很多系统上SHMALL是以页面而不是字节来度量。 @@ -517,7 +513,7 @@ psql: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: No such
- 当使用 System V 信号量时,PostgreSQL会为每个允许连接()、每个允许自动清理工作进程()、每个允许 WAL 发送进程()和每个允许后台进程()分配一个信号量,按 19 个一组。每组还包含第 20 个信号量,用于存放magic number,以检测与其他应用信号量集合的冲突。系统最大信号量数由 SEMMNS 设定,因此至少应为 max_connections 加上每组 19 个所需信号量的一个附加量(见中的公式)。SEMMNI决定系统中同一时刻可存在的信号量集合数上限,因此至少应为 ceil((max_connections + autovacuum_max_workers + max_wal_senders + max_worker_processes + 7) / 19)。降低允许连接数是对通常带有误导措辞设备上没有剩余空间(来自semget)这类失败的临时缓解手段。 + 当使用 System V 信号量时,PostgreSQL会为每个允许连接()、每个允许自动清理工作进程()、每个允许 WAL 发送进程()和每个允许后台进程()分配一个信号量,按 19 个一组。每组还包含第 20 个信号量,用于存放魔数,以检测与其他应用信号量集合的冲突。系统最大信号量数由 SEMMNS 设定,因此至少应为 max_connectionsautovacuum_max_workersmax_wal_sendersmax_worker_processes之和,再加上每组 19 个所需信号量的一个附加量(见中的公式)。SEMMNI决定系统中同一时刻可存在的信号量集合数上限,因此至少应为 ceil((max_connections + autovacuum_max_workers + max_wal_senders + max_worker_processes + 7) / 19)。降低允许连接数是对通常带有误导措辞No space left on device(来自semget)这类失败的临时缓解手段。 @@ -525,11 +521,11 @@ psql: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: No such - 与semaphore undo有关的其他各种设置,如SEMMNUSEMUME,不会影响PostgreSQL。 + 与信号量撤销有关的其他各种设置,如SEMMNUSEMUME,不会影响PostgreSQL - 当使用 POSIX 信号量时,所需数量与 System V 相同,即每个允许连接()、每个允许自动清理工作进程()、每个允许 WAL 发送进程()、每个允许后台进程()等各需一个。在优先使用该实现的平台上,POSIX 信号量数量没有特定内核上限。 + 当使用 POSIX 信号量时,所需数量与 System V 相同,即每个允许连接()、每个允许自动清理工作进程()、每个允许 WAL 发送进程()、每个允许后台进程()各需一个。在优先使用该实现的平台上,POSIX 信号量数量没有特定内核上限。 @@ -571,9 +567,7 @@ psql: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: No such - - 默认共享内存设置通常就足够了,除非你已将 shared_memory_type 设置为 sysv。不过,你需要增大 kern.ipc.semmnikern.ipc.semmns,因为 NetBSD 对这两项的默认值小得实际上无法使用。 - + 默认共享内存设置通常就足够了,除非你已将 shared_memory_type 设置为 sysv。通常需要增大 kern.ipc.semmnikern.ipc.semmns,因为 NetBSD 对这两项的默认设置小得不便使用。 可以使用 sysctl 调整 IPC 参数,例如: @@ -596,9 +590,7 @@ psql: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: No such - - 默认共享内存设置通常就足够了,除非你已将 shared_memory_type 设置为 sysv。不过,你需要增大 kern.seminfo.semmnikern.seminfo.semmns,因为 OpenBSD 对这两项的默认值小得实际上无法使用。 - + 默认共享内存设置通常已经足够,除非你将 shared_memory_type 设为 sysv。通常需要增大 kern.seminfo.semmnikern.seminfo.semmns,因为 OpenBSD 对这两项的默认设置小得令人担忧。 可以使用 sysctl 调整 IPC 参数,例如: @@ -623,7 +615,7 @@ psql: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: No such - 共享内存大小设置可以通过sysctl界面更改。例如,允许 16 GB: + 共享内存大小设置可以通过sysctl接口更改。例如,允许 16 GB: $ sysctl -w kernel.shmmax=17179869184 $ sysctl -w kernel.shmall=4194304 @@ -661,9 +653,7 @@ kern.sysv.shmall=1024 SHMMAX 只能设置为 4096 的倍数。 - - 在这个平台上,SHMALL以 4kB 的页面度量。 - + 在这个平台上,SHMALL 以 4 kB 的页为单位。 SHMMNI 之外,其他设置都可以使用 sysctl 动态更改。不过,最好还是通过/etc/sysctl.conf设置你希望使用的值,这样重启后仍能保留。 @@ -678,7 +668,7 @@ kern.sysv.shmall=1024 - 默认的共享内存和信号量设置对于大多数 PostgreSQL 应用通常已经足够。Solaris 现在将SHMMAX的默认值设为系统 RAM 的四分之一。要进一步调整这一设置,可使用与postgres用户关联的项目设置。例如,以root运行下列命令: + 默认的共享内存和信号量设置对于大多数 PostgreSQL 应用通常已经足够。Solaris 将SHMMAX的默认值设为系统 RAM 的四分之一。要进一步调整这一设置,可使用与postgres用户关联的项目设置。例如,以root运行下列命令: projadd -c "PostgreSQL DB User" -K "project.max-shm-memory=(privileged,8GB,deny)" -U postgres -G postgres user.postgres @@ -733,7 +723,7 @@ WARNING: could not remove shared memory segment "/PostgreSQL.1450751626": No su - 用户注销可能会作为维护作业的一部分发生,也可能在管理员以postgres用户或类似名称登录时手工触发,因此通常很难彻底防止。 + 用户注销可能会作为维护作业的一部分发生,也可能在管理员以postgres用户登录或执行类似操作时手工触发,因此通常很难彻底防止。 @@ -814,7 +804,7 @@ default:\ Linux 内存过量分配 - memory overcommit + 内存过量分配 @@ -822,7 +812,7 @@ default:\ - overcommit + 过量分配 @@ -842,7 +832,7 @@ Out of Memory: Killed process 12345 (postgres). - 如果导致系统耗尽内存的正是PostgreSQL自身,那么你可以通过调整配置来避免该问题。在某些情况下,调低与内存相关的配置参数会有帮助,尤其是shared_bufferswork_memhash_mem_multiplier。在其他情况下,允许数据库服务器接受过多连接也可能导致这一问题。很多时候,更好的做法是减小max_connections,并转而使用外部连接池软件。 + 如果导致系统耗尽内存的正是PostgreSQL自身,那么你可以通过调整配置来避免该问题。在某些情况下,调低与内存相关的配置参数会有帮助,尤其是shared_bufferswork_memhash_mem_multiplier。在其他情况下,允许数据库服务器接受过多连接也可能导致这一问题。很多时候,更好的做法可能是减小max_connections,并转而使用外部连接池软件。 @@ -854,17 +844,25 @@ sysctl -w vm.overcommit_memory=2 - 另一种方法可在修改或不修改 vm.overcommit_memory 的情况下使用:把 PostgreSQL 主进程的 OOM score adjustment 值设为 -1000,从而保证它不会成为 OOM 杀手的目标。最简单的做法是在 PostgreSQL 启动脚本中、调用 postgres 之前执行以下命令: + 另一种方法可在修改或不修改 vm.overcommit_memory 的情况下使用: + 把 postmaster 进程专属的OOM 评分调整值设为 -1000, + 从而保证它不会成为 OOM 杀手的目标。最简单的做法是在 PostgreSQL + 启动脚本中、调用 postgres 之前执行: echo -1000 > /proc/self/oom_score_adj - 请注意,这个操作必须以 root 身份完成,否则不会生效。因此,最容易放置该操作的位置是由 root 拥有的启动脚本。如果这样做,你还应该在调用 postgres 之前,在启动脚本中设置这些环境变量: + 请注意,这个操作必须以 root 身份完成,否则不会生效;因此,由 root 拥有的启动脚本是最容易执行该操作的位置。 + 如果这样做,还应在调用 postgres 之前,在启动脚本中设置以下环境变量: export PG_OOM_ADJUST_FILE=/proc/self/oom_score_adj export PG_OOM_ADJUST_VALUE=0 - 这些设置会使 postgres 子进程以默认值零的 OOM score adjustment 运行,因此 OOM 杀手在需要时仍可将它们作为目标。如果你希望子进程使用其他 OOM score adjustment 值,也可以为 PG_OOM_ADJUST_VALUE 指定其他数值(也可省略,此时默认为零)。如果不设置 PG_OOM_ADJUST_FILE,子进程就会和主进程使用相同的 OOM score adjustment,这并不明智,因为这样做的目的正是为了确保主进程拥有优先保护设置。 - + 这些设置会使 postmaster 子进程以常规的 OOM 评分调整值零运行,以便 OOM 杀手在需要时仍可将它们作为目标。 + 如果希望子进程以其他 OOM 评分调整值运行,也可以为 PG_OOM_ADJUST_VALUE 指定其他值。 + (也可以省略 PG_OOM_ADJUST_VALUE,此时默认为零。) + 如果不设置 PG_OOM_ADJUST_FILE,子进程就会和 postmaster 使用相同的 OOM 评分调整值, + 这并不明智,因为这样做的目的正是确保 postmaster 获得优先保护。 +
@@ -904,8 +902,9 @@ $ cat /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages - 你可能还需要授予数据库服务器的操作系统用户使用大页的权限,例如通过sysctl设置vm.hugetlb_shm_group,以及/或者授予其使用ulimit -l锁定内存的权限。 - + 可能还需要通过 sysctl 设置 vm.hugetlb_shm_group, + 授予数据库服务器的操作系统用户使用大页的权限,以及/或者通过 ulimit -l 授予其锁定内存的权限。 + PostgreSQL对大页的默认行为是:只要可能就使用它们,采用系统默认的大页大小;如果失败,则回退到普通页面。要强制使用大页,可以在postgresql.conf中将设为on。请注意,在这种设置下,如果没有足够的大页可用,PostgreSQL将无法启动。 @@ -927,7 +926,7 @@ $ cat /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages - 有几种关闭数据库服务器的方法。在后台,它们都简化为向主管 postgres 进程发送信号。 + 有几种关闭数据库服务器的方法。这些方法在内部都是向主管 postgres 进程发送信号。 @@ -969,7 +968,7 @@ $ cat /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepagesSIGQUIT并等待它们终止。 如果有任何进程在 5 秒内未终止,它们将被发送SIGKILL。 一旦所有子进程退出,主管服务器进程将立即退出,而不进行正常的数据库关闭处理。 - 这会导致下次启动时通过回放 WAL 日志执行恢复。仅建议在紧急情况下使用。 + 这会导致下次启动时通过重放 WAL 日志执行恢复。仅建议在紧急情况下使用。 @@ -985,10 +984,7 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` - - 最好不要使用SIGKILL关闭服务器。这样做将会阻止服务器释放共享内存和信号量。 - 此外,使用SIGKILL杀掉postgres进程时,postgres不会有机会将信号传播到它的子进程,所以可能也必须手工杀掉单个的子进程。 - + 最好不要使用 SIGKILL 关闭服务器。这样做会阻止服务器释放共享内存和信号量。此外,SIGKILL 会终止 postgres 进程,使其没有机会将信号转发给子进程,因此可能还需要手动逐个终止子进程。 @@ -1001,12 +997,12 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`升级 PostgreSQL 集簇 - upgrading + 升级 - version - compatibility + 版本 + 兼容性 @@ -1026,7 +1022,7 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` - 新的主版本通常还会引入一些用户可见的不兼容变化,因此应用程序可能也需要做出修改。所有用户可见的变化都列在发行说明()中;请特别留意标为Migration的小节。虽然你可以从一个主版本直接升级到另一个主版本,而不必逐个升级中间版本,但仍应阅读所有中间版本的主版本发行说明。 + 新的主版本通常还会引入一些用户可见的不兼容变化,因此应用程序可能也需要做出修改。所有用户可见的变化都列在发行说明()中;请特别留意标为迁移(Migration)的小节。虽然你可以从一个主版本直接升级到另一个主版本,而不必逐个升级中间版本,但仍应阅读所有中间版本的主版本发行说明。 @@ -1085,7 +1081,7 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` - 这涉及以后端函数 API 为代表的变更,该 API 使用 C 语言编写。这类变更会影响那些深入引用服务器内部后端函数的代码。 + 这涉及使用 C 语言编写的后端函数 API 的变更。这类变更会影响那些深入引用服务器内部后端函数的代码。 @@ -1097,7 +1093,7 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`通过pg_dumpall升级数据 - 一种升级方法是从某个主版本的PostgreSQL导出数据,再在另一个版本中恢复。要这样做,必须使用逻辑备份工具,例如pg_dumpall;文件系统级备份方法不起作用。(系统中有相应检查,会阻止你在不兼容版本的PostgreSQL上使用某个数据目录,因此即便误用错误版本的服务器去启动某个数据目录,通常也不会造成太大损害。) + 一种升级方法是从某个主版本的PostgreSQL转储数据,再在另一个版本中恢复。要这样做,必须使用逻辑备份工具,例如pg_dumpall;文件系统级备份方法不起作用。(系统中有相应检查,会阻止你在不兼容版本的PostgreSQL上使用某个数据目录,因此即便误用错误版本的服务器去启动某个数据目录,通常也不会造成太大损害。) @@ -1112,13 +1108,13 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` - 如果是在制作备份,请确认数据库此时没有正在进行更新。这不会影响备份的一致性,但那些变更当然不会包含在备份中。必要时,可修改/usr/local/pgsql/data/pg_hba.conf中的访问权限(或采用等效方法),禁止除你之外的其他人访问数据库。有关访问控制的更多信息见。 + 如果是在制作备份,请确认数据库此时没有正在进行更新。更新操作不会影响备份的完整性,但那些变更当然不会包含在备份中。必要时,可修改/usr/local/pgsql/data/pg_hba.conf(或等效文件)中的访问权限,禁止除你之外的其他人访问数据库。有关访问控制的更多信息见 pg_dumpall - use during upgrade + 在升级期间使用 要备份整个数据库安装,请输入: @@ -1139,7 +1135,7 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` pg_ctl stop - 在那些会自动启动PostgreSQL的系统上,可能已经有某个启动脚本能完成同样的工作。例如,在Red Hat Linux系统上,也许下面这条命令就可以: + 在那些会在开机时自动启动PostgreSQL的系统上,可能已经有某个启动脚本能完成同样的工作。例如,在Red Hat Linux系统上,也许下面这条命令就可以: /etc/rc.d/init.d/postgresql stop @@ -1194,12 +1190,9 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` - - 最后,使用新的psql从备份恢复数据: - + 最后,使用以下命令从备份恢复数据: /usr/local/pgsql/bin/psql -d postgres -f outputfile - - 这里务必使用新的psql。 +这里应使用新版 psql @@ -1230,7 +1223,7 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 通过复制升级数据 - 也可以使用逻辑复制方法,创建一个运行较新版本PostgreSQL的备库。之所以可行,是因为逻辑复制支持不同主版本PostgreSQL之间进行复制。该备库可以与旧服务器部署在同一台机器上,也可以部署在不同机器上。一旦它与主库(运行旧版本PostgreSQL)同步,就可以切换主备角色,让备库提升为主库,并关闭旧的数据库实例。这种切换通常只会带来几秒钟的停机时间。 + 也可以使用逻辑复制方法,创建一个运行较新版本PostgreSQL的备库。之所以可行,是因为逻辑复制支持不同主版本PostgreSQL之间进行复制。该备库可以与旧服务器部署在同一台机器上,也可以部署在不同机器上。一旦它与主库(运行旧版本PostgreSQL)同步,就可以切换主备角色,让备库提升为主库,并关闭旧的数据库实例。这种切换使升级只需几秒钟的停机时间。 @@ -1264,17 +1257,14 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 - 要防止 SSL 欺骗,服务器必须配置为仅接受 hostssl 连接(),并且具备 SSL 密钥和证书文件()。TCP 客户端必须使用 sslmode=verify-caverify-full 连接,并安装适当的根证书文件()。另外,也可使用 SSL 实现定义的系统 CA 池(system CA pool),即设置 sslrootcert=system;出于安全考虑,此时会强制使用 sslmode=verify-full,因为获得由公共 CA 签发的证书通常并不困难。 + 要通过 SSL 防止服务器欺骗,服务器必须配置为仅接受 hostssl 连接(),并且具备 SSL 密钥和证书文件()。TCP 客户端必须使用 sslmode=verify-caverify-full 连接,并安装适当的根证书文件()。另外,也可使用 SSL 实现定义的系统 CA 池,即设置 sslrootcert=system;出于安全考虑,此时会强制使用 sslmode=verify-full,因为获得由公共 CA 签发的证书通常并不困难。 在网络上使用 scram-sha-256 密码认证时,为防止服务器欺骗,应确保通过 SSL 连接服务器,并使用上一段描述的任一防欺骗方法。此外,libpq 中的 SCRAM 实现无法保护整个认证交换过程,但使用连接参数 channel_binding=require 可对服务器欺骗提供一定缓解。攻击者若用伪造服务器拦截 SCRAM 交换,可能通过离线分析推导出客户端哈希密码。 - - 要防止 GSSAPI 欺骗,必须将服务器配置为仅接受hostgssenc连接 () 并对它们使用gss认证。 - TCP 客户端则必须使用 gssencmode=require 发起连接。 - + 要通过 GSSAPI 防止服务器欺骗,服务器必须配置为仅接受 hostgssenc 连接(),并对这些连接使用 gss 认证。TCP 客户端必须使用 gssencmode=require 连接。
@@ -1286,7 +1276,7 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 - PostgreSQL提供了多个层次的加密,并在防止数据因数据库服务器被盗、不可靠的管理员或不安全网络等原因而泄露方面提供了很高的灵活性。对于医疗记录、金融交易等敏感数据,加密也可能是合规要求的一部分。 + PostgreSQL提供了多个层次的加密,并在防止数据因数据库服务器被盗、不诚实的管理员或不安全网络等原因而泄露方面提供了很高的灵活性。为了保护医疗记录、金融交易等敏感数据,也可能需要使用加密。 @@ -1420,7 +1410,7 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 - 如果私钥受密码保护,服务器会提示输入该密码,并在输入之前不会启动。默认情况下,使用密码会禁用无需重启服务器即可更改 SSL 配置的能力,不过参见。此外,在 Windows 上完全无法使用带密码保护的私钥。 + 如果私钥受口令保护,服务器会提示输入该口令,并在输入之前不会启动。默认情况下,使用口令会禁用无需重启服务器即可更改 SSL 配置的能力,不过参见。此外,在 Windows 上完全无法使用带口令保护的私钥。 @@ -1447,7 +1437,7 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 - 使用NULL-SHANULL-MD5密码套件,可以在几乎没有加密开销的情况下完成认证。不过,中间人仍然能够读取并转发客户端与服务器之间的通信。此外,与认证的开销相比,加密开销本身通常很小。基于这些原因,不建议使用 NULL 密码套件。 + 使用NULL-SHANULL-MD5密码套件,可以在没有加密开销的情况下完成认证。不过,中间人仍然能够读取并转发客户端与服务器之间的通信。此外,与认证的开销相比,加密开销本身很小。基于这些原因,不建议使用 NULL 密码套件。 @@ -1680,9 +1670,7 @@ psql -h localhost -p 63333 postgres 对数据库服务器来说,它看到的是来自主机foo.com上用户joelocalhost绑定地址的连接,并将应用为该用户到该绑定地址所配置的认证方式。请注意,服务器不会认为这是 SSL 加密连接,因为实际上SSH服务器与PostgreSQL服务器之间并没有加密。不过这通常不会带来额外安全风险,因为两者位于同一台机器上。 - - 要让这条隧道建立成功,你必须能够像建立终端会话那样,通过sshjoe@foo.com身份连接。 - + 要让这条隧道建立成功,你必须有权通过 sshjoe@foo.com 身份连接,就像尝试使用 ssh 创建终端会话一样。 你也可以把端口转发设成这样: diff --git a/zh/17/spgist.sgml b/zh/17/spgist.sgml index 35430a86..ea4d1790 100644 --- a/zh/17/spgist.sgml +++ b/zh/17/spgist.sgml @@ -4,7 +4,7 @@ SP-GiST 索引 - index + 索引 SP-GiST @@ -12,7 +12,7 @@ 简介 - SP-GiST 是 space-partitioned GiST + SP-GiST 是空间分区 GiST 的缩写。SP-GiST 支持分区搜索树,这使得开发多种不同的 非平衡数据结构成为可能,例如四叉树、k-d 树以及基数树(trie)。这些结构 的共同特征是,它们会反复将搜索空间划分为不必等大的分区。与这种划分规则良 @@ -49,7 +49,7 @@ 内置操作符类 - 核心 PostgreSQL 发行版包含了 + PostgreSQL 核心发行版包含了 SP-GiST 操作符类,如 所示。 @@ -232,11 +232,11 @@ - SP-GiST 核心代码会处理空项。虽然 - SP-GiST 索引确实会为被索引列中的空值存储项,但这一 - 点对索引操作符类代码是隐藏的:不会有空的索引项或搜索条件传递给操作符类 - 方法。(这里假定 SP-GiST 操作符是严格的,因此对空 - 值不可能成功。)因此,这里不再进一步讨论空值。 + SP-GiST 核心代码负责处理值为 null 的索引项。虽然 + SP-GiST 索引会为被索引列中的 null 值存储索引项, + 但索引操作符类代码看不到这些项:值为 null 的索引项或搜索条件绝不会传给 + 操作符类方法。(这里假定 SP-GiST 操作符是严格的, + 因此对 null 值不可能返回真。)所以这里不再讨论 null 值。 @@ -286,8 +286,8 @@ typedef struct spgConfigOut Oid prefixType; /* 内部元组前缀的数据类型 */ Oid labelType; /* 内部元组结点标签的数据类型 */ Oid leafType; /* 叶子元组值的数据类型 */ - bool canReturnData; /* 操作符类能重构原始数据 */ - bool longValuesOK; /* 操作符类能处理值 > 1 页 */ + bool canReturnData; /* 操作符类能重建原始数据 */ + bool longValuesOK; /* 操作符类能处理大小 > 1 页的值 */ } spgConfigOut; @@ -314,7 +314,7 @@ typedef struct spgConfigOut 类型与操作符类的输入类型相同,这也是最常见的情况。)出于向后兼容的原 因,config 方法也可以将 leafType 设为其他值,并且该值将被使用; - 但这已被废弃,因为这样会导致目录中对索引内容的标识不正确。此外,也允 + 但这已被弃用,因为这样会导致目录中对索引内容的标识不正确。此外,也允 许不初始化 leafType(即保持为零);这会 被解释为使用从 opckeytype 派生的索引存 储类型。 @@ -354,7 +354,7 @@ typedef struct spgChooseIn int level; /* 当前层级(从零开始计) */ /* 来自当前内部元组的数据 */ - bool allTheSame; /* 元组被标记为 all-the-same? */ + bool allTheSame; /* 元组被标记为全部相同? */ bool hasPrefix; /* 元组有前缀? */ Datum prefixDatum; /* 如果有,前缀值 */ int nNodes; /* 内部元组中的结点数 */ @@ -594,14 +594,14 @@ typedef struct spgInnerConsistentIn int nkeys; /* scankeys 数组的长度 */ int norderbys; /* orderbys 数组的长度 */ - Datum reconstructedValue; /* 在父元组处重构的值 */ + Datum reconstructedValue; /* 在父元组处重建的值 */ void *traversalValue; /* 操作符类特定的遍历值 */ MemoryContext traversalMemoryContext; /* 将新的遍历值放在这里 */ int level; /* 当前层级(从零开始计) */ bool returnData; /* 必须返回原始数据? */ /* 来自当前内部元组的数据 */ - bool allTheSame; /* 元组被标记为 all-the-same? */ + bool allTheSame; /* 元组被标记为全部相同? */ bool hasPrefix; /* 元组有前缀? */ Datum prefixDatum; /* 如果有,前缀值 */ int nNodes; /* 内部元组中的结点数 */ @@ -613,7 +613,7 @@ typedef struct spgInnerConsistentOut int nNodes; /* 需要访问的子结点数 */ int *nodeNumbers; /* 它们在结点数组中的索引 */ int *levelAdds; /* 对每个结点层级增加这么多 */ - Datum *reconstructedValues; /* 关联的重构值 */ + Datum *reconstructedValues; /* 关联的重建值 */ void **traversalValues; /* 操作符类特定的遍历值 */ double **distances; /* 关联距离 */ } spgInnerConsistentOut; @@ -624,7 +624,7 @@ typedef struct spgInnerConsistentOut 用 AND 组合 — 只有满足全部条件的索引项才是我们关心的。(注 意, nkeys = 0 表示所有索引项都满足该查 - 询。)通常 consistent 函数只关心每个数组元素的 + 询。)通常一致性检查函数只关心每个数组元素的 sk_strategysk_argument 字段,它们分别给出可索引操 作符和比较值。特别地,无需检查 sk_flags @@ -641,9 +641,8 @@ typedef struct spgInnerConsistentOut 遍历值(见下文)的内存上下文。level 是 当前内部元组的层级,根层为零。如果本查询需要重建数据,则 returnDatatrue; - 只有在 config 函数声明了 - canReturnData 时才会如此。若当前内部元组 - 被标记为 all-the-same,则 + 只有在 config 函数将 canReturnData 设为真时才会如此。若当前内部元组 + 被标记为 全部相同,则 allTheSame 为真;在这种情况下,所有结点 都具有相同的标签(如果有),因此要么全部匹配该查询,要么全部不匹配 (参见 )。若当前内部元组包 @@ -663,8 +662,7 @@ typedef struct spgInnerConsistentOut 非必然如此,所以这里使用数组。)如果需要值重建,则将 reconstructedValues 设为一个数组,其中包 含为每个待访问子结点重建的值;否则,将 - reconstructedValues 保持为 NULL。重构 - 值假定具有 spgConfigOut.leafType + reconstructedValues 保持为 NULL。重建的值假定具有 spgConfigOut.leafType 类型。(不过,由于核心系统除了可能复制它们以外不会对其做任何处理,只 要它们具有与 leafType 相同的 typlentypbyval 属性就足 @@ -713,7 +711,7 @@ typedef struct spgLeafConsistentIn int nkeys; /* scankeys 数组的长度 */ int norderbys; /* orderbys 数组的长度 */ - Datum reconstructedValue; /* 在父元组处重构的值 */ + Datum reconstructedValue; /* 在父元组处重建的值 */ void *traversalValue; /* 操作符类特定的遍历值 */ int level; /* 当前层级(从零开始计) */ bool returnData; /* 必须返回原始数据? */ @@ -723,7 +721,7 @@ typedef struct spgLeafConsistentIn typedef struct spgLeafConsistentOut { - Datum leafValue; /* 重构出的原始数据(如果有) */ + Datum leafValue; /* 重建出的原始数据(如果有) */ bool recheck; /* 如果必须重新检查操作符则设为真 */ bool recheckDistances; /* 如果必须重新检查距离则设为真 */ double *distances; /* 关联距离 */ @@ -734,7 +732,7 @@ typedef struct spgLeafConsistentOut scankeys 数组描述索引搜索条件。这些条件 用 AND 组合在一起 — 只有满足全部条件的索引项才满足该查询。(注 意 nkeys = 0 表示所有索引项都满足该查 - 询。)通常 consistent 函数只关心每个数组元素的 + 询。)通常一致性检查函数只关心每个数组元素的 sk_strategysk_argument 字段,它们分别给出可索引操 作符和比较值。特别地,无需检查 sk_flags @@ -750,8 +748,7 @@ typedef struct spgLeafConsistentOut NULL。level 是当前叶子元组的层级,根层为 零。如果本查询需要重建数据,则 returnDatatrue; - 只有在 config 函数声明了 - canReturnData 时才会如此。 + 只有在 config 函数将 canReturnData 设为真时才会如此。 leafDatum 是当前叶子元组中存储的、类型为 spgConfigOut.leafType 的键值。 @@ -844,7 +841,7 @@ LANGUAGE C STRICT; - 如果被索引列属于可应用排序规则的数据类型,则索引排序规则会通过标准的 + 如果被索引列属于支持排序规则的数据类型,则索引排序规则会通过标准的 PG_GET_COLLATION() 机制传递给所有支持方法。 @@ -922,7 +919,7 @@ LANGUAGE C STRICT; - <quote>All-the-Same</quote> 内部元组 + <quote>全部相同</quote>的内部元组 picksplit 无法把提供的叶子值划分为至少两个结点 diff --git a/zh/17/spi.sgml b/zh/17/spi.sgml index 89c9f99d..edc6b6fa 100644 --- a/zh/17/spi.sgml +++ b/zh/17/spi.sgml @@ -76,7 +76,7 @@ int SPI_connect_ext(int options) SPI_connect 会为某次 C 函数调用打开到 SPI 管理器 的连接。如果要通过 SPI 执行命令,就必须调用此函数。不过,有些 SPI - 实用函数可以在未连接的 C 函数中调用。 + 辅助函数可以在未连接的 C 函数中调用。 @@ -292,16 +292,16 @@ SPI_execute("INSERT INTO foo SELECT * FROM bar RETURNING *", false, 5); typedef struct SPITupleTable { - /* Public members */ - TupleDesc tupdesc; /* tuple descriptor */ - HeapTuple *vals; /* array of tuples */ - uint64 numvals; /* number of valid tuples */ - - /* Private members, not intended for external callers */ - uint64 alloced; /* allocated length of vals array */ - MemoryContext tuptabcxt; /* memory context of result table */ - slist_node next; /* link for internal bookkeeping */ - SubTransactionId subid; /* subxact in which tuptable was created */ + /* 公共成员 */ + TupleDesc tupdesc; /* 元组描述符 */ + HeapTuple *vals; /* 元组数组 */ + uint64 numvals; /* 有效元组数 */ + + /* 私有成员,不供外部调用者使用 */ + uint64 alloced; /* vals 数组的已分配长度 */ + MemoryContext tuptabcxt; /* 结果表的内存上下文 */ + slist_node next; /* 用于内部管理的链接 */ + SubTransactionId subid; /* 创建 tuptable 的子事务 */ } SPITupleTable; SPI 调用者可以使用 tupdesc、 @@ -472,7 +472,7 @@ typedef struct SPITupleTable - 发生错误时,则返回下列负值之一: + 出错时,返回以下负值之一: @@ -522,7 +522,7 @@ typedef struct SPITupleTable SPI_ERROR_UNCONNECTED - 从未连接的 C 函数中调用 + 如果从一个未连接的 C 函数中调用 @@ -535,9 +535,9 @@ typedef struct SPITupleTable 所有 SPI 查询执行函数都会设置 SPI_processed 和 - SPI_tuptable(只设置指针,而不会复制结构体内容)。如果 + SPI_tuptable(只设置指针,而不更改结构体内容)。如果 需要在后续调用之后继续访问 SPI_execute 或其他查询 - 执行函数的结果表,请把这两个全局变量保存到本地 C 函数变量中。 + 执行函数的结果表,请把这两个全局变量保存到 C 函数的局部变量中。 @@ -582,7 +582,7 @@ int SPI_exec(const char * command, long count< const char * command - 包含要执行命令的字符串 + 包含待执行命令的字符串 @@ -591,7 +591,7 @@ int SPI_exec(const char * command, long count< long count - 要返回的最大行数,或者用0表示没有限制 + 要返回的最大行数,或者用 0 表示不限制 @@ -822,7 +822,7 @@ int SPI_execute_with_args(const char *command, SPI_execute_plan 达到类似效果。不过,使用本函数 时,查询计划总会针对所提供的具体参数值进行定制。对于一次性查询执行,应 优先选择本函数。如果同一条命令要用许多不同参数重复执行,则两种方式孰快 - 取决于重新计划的代价与定制计划收益之间的权衡。 + 取决于重新规划的代价与定制计划收益之间的权衡。 @@ -877,9 +877,9 @@ int SPI_execute_with_args(const char *command, 如果 nullsNULL,则 - SPI_execute_with_args 会假定没有参数为 NULL。 - 否则,如果对应参数值非 NULL,则 nulls 数组中 - 的对应项应为 ' ';如果对应参数值为 NULL,则 + SPI_execute_with_args 会假定没有参数为空值。 + 否则,如果对应参数值非空值,则 nulls 数组中 + 的对应项应为 ' ';如果对应参数值为空值,则 对应项应为 'n'。(后一种情况下,对应 values 项中的实际值无关紧要。)注意, nulls 不是文本字符串,而只是一个数组,因此不 @@ -933,7 +933,7 @@ int SPI_execute_with_args(const char *command, SPI_prepare - 准备一个语句,但不执行它 + 准备一个语句,但暂不执行 @@ -1012,8 +1012,7 @@ SPIPlanPtr SPI_prepare(const char * command, int 返回值 - SPI_prepare 返回一个指向非空 SPIPlan - 的指针,它是表示预备语句的不透明结构体。发生错误时会返回 + SPI_prepare 返回一个非空指针,指向表示预备语句的不透明结构体 SPIPlan。发生错误时会返回 NULL,并将 SPI_result 设为 SPI_execute 所使用的那些错误码之一;但如果 commandNULL,或者 @@ -1032,17 +1031,16 @@ SPIPlanPtr SPI_prepare(const char * command, int SPI_execute_plan 在最初几次使用时会根据提供的参数 值生成定制计划。当同一个预备语句被使用足够多次之后, SPI_execute_plan 会构建一个通用计划;如果它的代价 - 没有比定制计划高出太多,就会开始改用通用计划,而不是每次都重新计划。如 + 没有比定制计划高出太多,就会开始改用通用计划,而不是每次都重新规划。如 果这种默认行为不合适,可以把 CURSOR_OPT_GENERIC_PLANCURSOR_OPT_CUSTOM_PLAN 标志传给 SPI_prepare_cursor,分别强制使用通用计划或定制计划。 - 尽管预备语句的主要目的在于避免重复进行解析分析和计划,但只要语句中使用 + 尽管预备语句的主要目的在于避免重复进行解析分析和规划,但只要语句中使用 的数据库对象自上次使用该预备语句以来发生了定义性(DDL)变更, - PostgreSQL 就会在再次使用前强制重新分析并重 - 新计划该语句。此外,如果 的值在两次 + PostgreSQL 就会在再次使用前强制重新分析并重新规划该语句。此外,如果 的值在两次 使用之间发生变化,该语句也会基于新的 search_path 重 新解析。(后一种行为是从 PostgreSQL 9.3 开 始引入的。)有关预备语句行为的更多信息,请参见 @@ -1102,7 +1100,7 @@ SPIPlanPtr SPI_prepare_cursor(const char * command, int < - 此函数现已废弃,推荐改用 SPI_prepare_extended。 + 此函数现已弃用,推荐改用 SPI_prepare_extended @@ -1132,7 +1130,7 @@ SPIPlanPtr SPI_prepare_cursor(const char * command, int < Oid * argtypes - 指向数组的指针,该数组包含参数数据类型的 + 一个数组指针,它指向的数组包含参数的数据类型的 OID @@ -1201,7 +1199,7 @@ SPIPlanPtr SPI_prepare_extended(const char * command, SPI_prepare_extended 为指定命令创建并返回一个预备语 句,但并不执行该命令。它相当于 SPI_prepare,并额外 - 允许调用者指定选项,以控制外部参数引用的解析,以及查询解析和计划的其他 + 允许调用者指定选项,以控制外部参数引用的解析,以及查询解析和规划的其他 方面。 @@ -1241,7 +1239,7 @@ SPIPlanPtr SPI_prepare_extended(const char * command, ParserSetupHook parserSetup - 语法分析器钩子设置函数 + 解析器钩子设置函数 @@ -1319,7 +1317,7 @@ SPIPlanPtr SPI_prepare_params(const char * command, - 此函数现已废弃,推荐改用 SPI_prepare_extended。 + 此函数现已弃用,推荐改用 SPI_prepare_extended @@ -1340,7 +1338,7 @@ SPIPlanPtr SPI_prepare_params(const char * command, ParserSetupHook parserSetup - 语法分析器钩子设置函数 + 解析器钩子设置函数 @@ -1555,8 +1553,8 @@ bool SPI_is_cursor_plan(SPIPlanPtr plan) 返回值 - 如果 plan 能产生游标,则返回 - true;如果不能,则返回 false,并将 + 返回 truefalse,表示 + plan 能否产生游标,同时将 SPI_result 设为零。如果无法确定答案(例如 planNULL 或无效,或者在 未连接到 SPI 时调用),则会将 SPI_result 设为合适 @@ -1628,15 +1626,14 @@ int SPI_execute_plan(SPIPlanPtr plan, Datum * - 如果nullsNULL, - 那么SPI_execute_plan会假设没有参数 - 为空值。否则,如果对应的参数值为非空, - nulls - 数组的每一个项都应该是' ';如果对应参数值为空, - nulls数组的项应为'n'(在后 - 面的情况中,对应的values项中的值没有 - 关系)。注意nulls不是一个文本字符串, - 它只是一个数组:它不需要一个'\0'终止符。 + 如果 nullsNULL,则 + SPI_execute_plan 会假定没有参数为空值。 + 否则,如果对应参数值非空值,则 nulls 数组中 + 的对应项应为 ' ';如果对应参数值为空值,则 + 对应项应为 'n'。(后一种情况下,对应 + values 项中的实际值无关紧要。)注意, + nulls 不是文本字符串,而只是一个数组,因此不 + 需要 '\0' 终止符。 @@ -1709,7 +1706,7 @@ int SPI_execute_plan(SPIPlanPtr plan, Datum * SPI_execute_plan_extended - 执行一个由SPI_prepare准备的语句 + 执行由 SPI_prepare 准备好的语句 @@ -1794,8 +1791,9 @@ int SPI_execute_plan_extended(SPIPlanPtr plan, bool allow_nonatomic - true 允许以非原子方式执行 CALL 与 DO 语句 - (但除非向 SPI_connect_ext 传入了 + true 允许以非原子方式执行 CALL + 和 DO 语句(但除非向 + SPI_connect_ext 传入了 SPI_OPT_NONATOMIC 标志,否则该字段会被忽略) @@ -1815,7 +1813,7 @@ int SPI_execute_plan_extended(SPIPlanPtr plan, uint64 tcount - 要返回的最大行数,或者用0表示没有限制 + 要返回的最大行数,或者用 0 表示不限制 @@ -1900,7 +1898,7 @@ int SPI_execute_plan_with_paramlist(SPIPlanPtr plan, - 此函数现已废弃,推荐改用 SPI_execute_plan_extended。 + 此函数现已弃用,推荐改用 SPI_execute_plan_extended @@ -1937,7 +1935,7 @@ int SPI_execute_plan_with_paramlist(SPIPlanPtr plan, long count - 要返回的最大行数,或者用0表示没有限制 + 要返回的最大行数,或者用 0 表示不限制 @@ -2021,15 +2019,14 @@ int SPI_execp(SPIPlanPtr plan, Datum * values< - 如果nullsNULL, - 那么SPI_execp会假设没有参数 - 为空值。否则,如果对应的参数值为非空, - nulls - 数组的每一个项都应该是' ';如果对应参数值为空, - nulls数组的项应为'n'(在后 - 面的情况中,对应的values项中的值没有 - 关系)。注意nulls不是一个文本字符串, - 它只是一个数组:它不需要一个'\0'终止符。 + 如果 nullsNULL,则 + SPI_execp 会假定没有参数为空值。 + 否则,如果对应参数值非空值,则 nulls 数组中 + 的对应项应为 ' ';如果对应参数值为空值,则 + 对应项应为 'n'。(后一种情况下,对应 + values 项中的实际值无关紧要。)注意, + nulls 不是文本字符串,而只是一个数组,因此不 + 需要 '\0' 终止符。 @@ -2038,7 +2035,7 @@ int SPI_execp(SPIPlanPtr plan, Datum * values< long count - 要返回的最大行数,或者用0表示没有限制 + 要返回的最大行数,或者用 0 表示不限制 @@ -2146,15 +2143,14 @@ Portal SPI_cursor_open(const char * name, SPIPlanPtr - 如果nullsNULL, - 那么SPI_cursor_open会假设没有参数 - 为空值。否则,如果对应的参数值为非空, - nulls - 数组的每一个项都应该是' ';如果对应参数值为空, - nulls数组的项应为'n'(在后 - 面的情况中,对应的values项中的值没有 - 关系)。注意nulls不是一个文本字符串, - 它只是一个数组:它不需要一个'\0'终止符。 + 如果 nullsNULL,则 + SPI_cursor_open 会假定没有参数为空值。 + 否则,如果对应参数值非空值,则 nulls 数组中 + 的对应项应为 ' ';如果对应参数值为空值,则 + 对应项应为 'n'。(后一种情况下,对应 + values 项中的实际值无关紧要。)注意, + nulls 不是文本字符串,而只是一个数组,因此不 + 需要 '\0' 终止符。 @@ -2215,11 +2211,10 @@ Portal SPI_cursor_open_with_args(const char *name, - 对于一次性的查询执行,这个函数应该比 - SPI_prepare_cursor加上其后的 - SPI_cursor_open更好。如果相同的命令 - 要被用很多不同的参数执行,哪种方法更快就要取决于重做计划的 - 代价与定制计划带来的好处之间谁更有利。 + 对于一次性查询执行,应优先使用此函数,而不是先调用 + SPI_prepare_cursor 再调用 + SPI_cursor_open。如果同一条命令要用许多不同参数执行, + 哪种方法更快取决于重新规划的代价与定制计划收益之间的权衡。 @@ -2228,7 +2223,7 @@ Portal SPI_cursor_open_with_args(const char *name, - 此函数现已废弃,推荐改用 SPI_cursor_parse_open, + 此函数现已弃用,推荐改用 SPI_cursor_parse_open, 它提供了等价的功能,并使用更现代的查询参数处理 API。 @@ -2268,8 +2263,8 @@ Portal SPI_cursor_open_with_args(const char *name, Oid * argtypes - 一个长度为nargs的数组, - 包含参数的数据类型的OID + 一个长度为 nargs 的数组,包含参数数据类型的 + OID @@ -2278,8 +2273,7 @@ Portal SPI_cursor_open_with_args(const char *name, Datum * values - 一个长度为nargs的数组, - 包含实际的参数值 + 一个长度为 nargs 的数组,包含实际参数值 @@ -2288,20 +2282,19 @@ Portal SPI_cursor_open_with_args(const char *name, const char * nulls - 一个长度为nargs的数组, - 描述哪些参数为空值 + 一个长度为 nargs 的数组,用于描述哪些参数为 + 空值 - 如果nullsNULL, - 那么SPI_cursor_open_with_args会假设没有参数 - 为空值。否则,如果对应的参数值为非空, - nulls - 数组的每一个项都应该是' ';如果对应参数值为空, - nulls数组的项应为'n'(在后 - 面的情况中,对应的values项中的值没有 - 关系)。注意nulls不是一个文本字符串, - 它只是一个数组:它不需要一个'\0'终止符。 + 如果 nullsNULL,则 + SPI_cursor_open_with_args 会假定没有参数为空值。 + 否则,如果对应参数值非空值,则 nulls 数组中 + 的对应项应为 ' ';如果对应参数值为空值,则 + 对应项应为 'n'。(后一种情况下,对应 + values 项中的实际值无关紧要。)注意, + nulls 不是文本字符串,而只是一个数组,因此不 + 需要 '\0' 终止符。 @@ -2438,7 +2431,7 @@ Portal SPI_cursor_open_with_paramlist(const char *name, SPI_cursor_parse_open - 使用查询字符串和参数设置游标 + 使用查询字符串和参数建立游标 @@ -2464,7 +2457,7 @@ Portal SPI_cursor_parse_open(const char *name, 对于一次性查询执行,推荐优先使用此函数,而不是 SPI_prepare_cursorSPI_cursor_open_with_paramlist 的组合。如果同一条命 - 令要用很多不同参数执行,两种方法孰快则取决于重新计划的代价与定制计划带 + 令要用很多不同参数执行,两种方法孰快则取决于重新规划的代价与定制计划带 来的收益之间的权衡。 @@ -2701,7 +2694,7 @@ void SPI_cursor_fetch(Portal portal, bool forw 如果该游标的计划不是用CURSOR_OPT_SCROLL - 选项创建的,向后获取会失败。 + 选项创建的,向后获取可能失败。 @@ -2775,7 +2768,7 @@ void SPI_cursor_move(Portal portal, bool forwa 如果该游标的计划不是用CURSOR_OPT_SCROLL - 选项创建的,向后移动会失败。 + 选项创建的,向后移动可能失败。 @@ -2871,8 +2864,7 @@ void SPI_scroll_cursor_fetch(Portal portal, FetchDirectio 如果该游标的计划不是用CURSOR_OPT_SCROLL - 选项创建的,除FETCH_FORWARD之外的方向值会 - 失败。 + 选项创建的,除FETCH_FORWARD之外的方向值可能失败。 @@ -2969,8 +2961,7 @@ void SPI_scroll_cursor_move(Portal portal, FetchDirection 如果该游标的计划不是用CURSOR_OPT_SCROLL - 选项创建的,除FETCH_FORWARD之外的方向值会 - 失败。 + 选项创建的,除FETCH_FORWARD之外的方向值可能失败。 @@ -3192,8 +3183,8 @@ SPIPlanPtr SPI_saveplan(SPIPlanPtr plan) SPI_register_relation - ephemeral named relation - registering with SPI + 临时命名关系 + 向 SPI 注册 @@ -3217,7 +3208,7 @@ int SPI_register_relation(EphemeralNamedRelation enr) SPI_register_relation 使一个带有相关信息的临时命名关 - 系对通过当前 SPI 连接计划和执行的查询可用。 + 系对通过当前 SPI 连接规划和执行的查询可用。 @@ -3255,7 +3246,7 @@ int SPI_register_relation(EphemeralNamedRelation enr) - 在出错时,会返回下列负值之一: + 出错时,返回以下负值之一: @@ -3297,8 +3288,8 @@ int SPI_register_relation(EphemeralNamedRelation enr) SPI_unregister_relation - ephemeral named relation - unregistering from SPI + 临时命名关系 + 从 SPI 注销 @@ -3345,7 +3336,7 @@ int SPI_unregister_relation(const char * name) 返回值 - 如果该命令的执行成功,则会返回下列(非负)值: + 如果该命令的执行成功,则将返回下列(非负)值: @@ -3360,7 +3351,7 @@ int SPI_unregister_relation(const char * name) - 出现错误时,会返回下列负值之一: + 出错时,返回以下负值之一: @@ -3400,13 +3391,13 @@ int SPI_unregister_relation(const char * name) SPI_register_trigger_data - ephemeral named relation - registering with SPI + 临时命名关系 + 向 SPI 注册 - transition tables - implementation in PLs + 过渡表 + 在 PL 中实现 @@ -3430,8 +3421,8 @@ int SPI_register_trigger_data(TriggerData *tdata) SPI_register_trigger_data 使触发器捕获的所有临时关系 - 都能在通过当前 SPI 连接计划和执行的查询中使用。目前,这指的是通过 - REFERENCING OLD/NEW TABLE AS ... 子句定义、并由 + 都能在通过当前 SPI 连接规划和执行的查询中使用。目前,这指的是由带有 + REFERENCING OLD/NEW TABLE AS ... 子句的 AFTER 触发器捕获的过渡表。PL 触发器处理函数应在建 立 SPI 连接后调用此函数。 @@ -3457,7 +3448,7 @@ int SPI_register_trigger_data(TriggerData *tdata) 返回值 - 如果命令的执行成功,则会返回下列(非负)值: + 如果该命令的执行成功,则将返回下列(非负)值: @@ -3472,7 +3463,7 @@ int SPI_register_trigger_data(TriggerData *tdata) - 出现错误时,会返回下列负值之一: + 出错时,返回以下负值之一: @@ -3729,7 +3720,7 @@ char * SPI_getvalue(HeapTuple row, TupleDesc r 返回值 - 列值;如果该列为 NULL、colnumber 超出范围 + 列值;如果该列为空值、colnumber 超出范围 (SPI_result 被设置为 SPI_ERROR_NOATTRIBUTE)或者没有输出函数 可用(SPI_result 被设置为 @@ -3821,8 +3812,8 @@ Datum SPI_getbinval(HeapTuple row, TupleDesc r 返回值 - 返回该列的二进制值。如果该列为 NULL,则 - isnull 指向的变量会被设为 true,否则设为 false。 + 返回该列的二进制值。如果该列为空值,则 + isnull 指向的变量会被设为真,否则设为假。 @@ -3858,7 +3849,7 @@ char * SPI_gettype(TupleDesc rowdesc, int coln SPI_gettype返回该指定列的数据类型名称 - 的拷贝(当你不再需要该拷贝后,可以使用pfree + 的副本(当你不再需要该副本后,可以使用pfree 释放它)。 @@ -3990,7 +3981,7 @@ char * SPI_getrelname(Relation rel) SPI_getrelname返回该指定关系的名称 - 的拷贝(当你不再需要该拷贝后,可以使用pfree + 的副本(当你不再需要该副本后,可以使用pfree 释放它)。 @@ -4083,7 +4074,7 @@ char * SPI_getnspname(Relation rel) SPI_result_code_string - 将结果代码表示为字符串 + 返回错误码的字符串表示 @@ -4097,7 +4088,7 @@ const char * SPI_result_code_string(int code); SPI_result_code_string 返回各种 SPI 函数返回的,或 - 存放在 SPI_result 中的结果代码的字符串表示。 + 存放在 SPI_result 中的结果码的字符串表示。 @@ -4109,7 +4100,7 @@ const char * SPI_result_code_string(int code); int code - 结果代码 + 结果码 @@ -4120,7 +4111,7 @@ const char * SPI_result_code_string(int code); 返回值 - 结果代码的字符串表示。 + 结果码的字符串表示。 @@ -4132,8 +4123,8 @@ const char * SPI_result_code_string(int code); - memory context - in SPI + 内存上下文 + 在 SPI 中 PostgreSQL内存上下文 中分配内存。内存上下文为管理那些在许多不同位置创建、且生命周期各不相同 @@ -4158,7 +4149,7 @@ const char * SPI_result_code_string(int code); 办法是用 SPI_palloc 为返回对象分配内存。 SPI_palloc上层执行器上下文中分配 内存,也就是调用 SPI_connect 时的当前内存上下文; - 这正是从 C 函数返回值最合适的上下文。本节介绍的其他几个实用函数同样会返 + 这正是从 C 函数返回值最合适的上下文。本节介绍的其他几个辅助函数同样会返 回在上层执行器上下文中创建的对象。 @@ -4166,7 +4157,7 @@ const char * SPI_result_code_string(int code); 调用 SPI_connect 时,会把该 C 函数的私有上下文 (由 SPI_connect 创建)设为当前上下文。所有通过 pallocrepalloc 或 SPI - 实用函数分配的内存(本节另有说明的除外)都位于这个上下文中。当 C 函数通 + 辅助函数分配的内存(本节另有说明的除外)都位于这个上下文中。当 C 函数通 过 SPI_finish 与 SPI 管理器断开连接时,当前上下文 会恢复为上层执行器上下文,而在该 C 函数内存上下文中分配的所有内存都会被 释放,之后就不能再使用。 @@ -4361,7 +4352,7 @@ void SPI_pfree(void * pointer) SPI_copytuple - 在上层执行器上下文中创建一行的拷贝 + 在上层执行器上下文中创建一行的副本 @@ -4394,7 +4385,7 @@ HeapTuple SPI_copytuple(HeapTuple row) HeapTuple row - 要拷贝的行 + 要复制的行 @@ -4405,7 +4396,7 @@ HeapTuple SPI_copytuple(HeapTuple row) 返回值 - 拷贝后的行;出错时返回 NULL + 复制后的行;出错时返回 NULL (错误指示见 SPI_result @@ -4461,7 +4452,7 @@ HeapTupleHeader SPI_returntuple(HeapTuple row, TupleDesc HeapTuple row - 要拷贝的行 + 要复制的行 @@ -4470,7 +4461,7 @@ HeapTupleHeader SPI_returntuple(HeapTuple row, TupleDesc TupleDesc rowdesc - 行描述符(若要获得最佳缓存效果,大多数情况下应每次都传入同一个描述符) + 行描述符(若要获得最佳缓存效果,每次都传入同一个描述符) @@ -4481,7 +4472,7 @@ HeapTupleHeader SPI_returntuple(HeapTuple row, TupleDesc 返回值 - 指向拷贝后行的 HeapTupleHeader;出错时返回 + 指向复制后行的 HeapTupleHeader;出错时返回 NULL(错误指示见 SPI_result @@ -4583,13 +4574,14 @@ HeapTuple SPI_modifytuple(Relation rel, HeapTuple - 如果nullsNULL,那么 - SPI_modifytuple假定没有新值为空值。否则, - 如果对应的新值为非空,nulls数组的每一项都应 - 该是' ',而如果对应的新值为空值则为'n'(在 - 后一种情况中,对应的values项中的新值无关紧 - 要)。注意nulls不是一个文本字符串,只是一个 - 数组:它不需要一个'\0'终止符。 + 如果 nullsNULL,则 + SPI_modifytuple 会假定没有新值为空值。 + 否则,如果对应新值非空值,则 nulls 数组中 + 的对应项应为 ' ';如果对应新值为空值,则 + 对应项应为 'n'。(后一种情况下,对应 + values 项中的实际值无关紧要。)注意, + nulls 不是文本字符串,而只是一个数组,因此不 + 需要 '\0' 终止符。 @@ -4668,7 +4660,7 @@ void SPI_freetuple(HeapTuple row) SPI_freetuple释放之前在上层执行器上下文中 - 分配的一个行。 + 分配的一行。 @@ -4966,7 +4958,7 @@ void SPI_start_transaction(void) - 数据改变的可见性 + 数据更改的可见性 下列规则决定了使用 SPI 的函数(以及其他任何 C 函数)中数据更改的可见 diff --git a/zh/17/stylesheet-speedup-common.xsl b/zh/17/stylesheet-speedup-common.xsl index e3fb582a..403f350c 100644 --- a/zh/17/stylesheet-speedup-common.xsl +++ b/zh/17/stylesheet-speedup-common.xsl @@ -95,6 +95,6 @@ -en +zh_cn diff --git a/zh/17/syntax.sgml b/zh/17/syntax.sgml index c326ceff..ef6a7de2 100644 --- a/zh/17/syntax.sgml +++ b/zh/17/syntax.sgml @@ -21,7 +21,7 @@ 词法结构 - token + 词元 @@ -29,7 +29,7 @@ - 一个词元可以是关键词标识符带引号的标识符文字值(或常量),或者特殊字符符号。词元通常由空白(空格、制表符、换行)分隔,但如果不存在歧义,则不必如此(一般只有特殊字符与其他类型的词元相邻时才会这样)。 + 一个词元可以是关键词标识符带引号的标识符字面量(或常量),或者特殊字符符号。词元通常由空白(空格、制表符、换行)分隔,但如果不存在歧义,则不必如此(一般只有特殊字符与其他类型的词元相邻时才会这样)。 @@ -83,7 +83,7 @@ INSERT INTO MY_TABLE VALUES (3, 'hi there'); - identifierlength + 标识符长度 系统对标识符最多只使用 NAMEDATALEN-1 个字节;在命令中可以写更长的名称,但它们会被截断。默认情况下, NAMEDATALEN 为 64,因此标识符的最大长度是 63 字节。如果这个限制有问题,可以通过修改 src/include/pg_config_manual.h 中的 NAMEDATALEN 常量来提高。 @@ -177,7 +177,7 @@ U&"d!0061t!+000061" UESCAPE '!' 常量 - constant + 常量 @@ -192,15 +192,11 @@ U&"d!0061t!+000061" UESCAPE '!' 常量 - - + 引号 转义 - SQL 中的字符串常量是由单引号括起的任意字符序列,例如 - 'This is a string'。要在字符串常量中包含单引号字符,请写两个相邻的单引号,例如 - 'Dianne''s horse'。注意,这与双引号字符("不同 - + SQL 中的字符串常量是由单引号(')括起的任意字符序列,例如 'This is a string'。要在字符串常量中包含单引号字符,请写两个相邻的单引号,例如 'Dianne''s horse'。注意,这不同于双引号字符(")。 两个只由空白及至少一个新行分隔的字符串常量会被连接在一起,并且将作为一个写在一起的字符串常量来对待。例如: @@ -304,7 +300,7 @@ SELECT 'foo' 'bar'; - 如果配置参数off,那么PostgreSQL对常规字符串常量和转义字符串常量中的反斜线转义都识别。不过,从PostgreSQL 9.1 开始,该参数的默认值为on,意味着只在转义字符串常量中识别反斜线转义。这种行为更兼容标准,但是可能打断依赖于历史行为(反斜线转义总是会被识别)的应用。作为一种变通,你可以设置该参数为off,但是最好迁移到符合新的行为。如果你需要使用一个反斜线转义来表示一个特殊字符,为该字符串常量写上一个E。 + 如果配置参数off,那么PostgreSQL对常规字符串常量和转义字符串常量中的反斜线转义都识别。不过,从PostgreSQL 9.1 开始,该参数的默认值为on,意味着只在转义字符串常量中识别反斜线转义。这种行为更兼容标准,但是可能使依赖历史行为(始终识别反斜线转义)的应用无法正常工作。作为一种变通,你可以设置该参数为off,但最好修改应用,不再使用反斜线转义。如果你需要使用一个反斜线转义来表示一个特殊字符,为该字符串常量写上一个E @@ -432,8 +428,8 @@ $function$ 数字常量 - number - constant + 数字 + 常量 @@ -514,8 +510,8 @@ $function$ 例如,可以通过下面的写法强制把一个数值当作类型 realfloat4)处理: -REAL '1.23' -- string style -1.23::REAL -- PostgreSQL (historical) style +REAL '1.23' -- 字符串形式 +1.23::REAL -- PostgreSQL(历史)形式 这些实际上只是下面将要讨论的一般类型转换记法的特例。 @@ -526,8 +522,8 @@ REAL '1.23' -- string style 其他类型的常量 - data type - constant + 数据类型 + 常量 @@ -553,7 +549,7 @@ CAST ( 'string' AS type ) - 如中所述,::CAST() 以及函数调用语法也可以用来指定任意表达式的运行时类型转换。为避免语法歧义,type 'string' 语法只能用来指定简单字面常量的类型。该语法的另一个限制是不能用于数组类型;要指定数组常量的类型,请使用 ::CAST()。 + 如中所述,::CAST() 以及函数调用语法也可以用来指定任意表达式的运行时类型转换。为避免语法歧义,type 'string' 语法只能用来指定简单字面常量的类型。type 'string' 语法的另一个限制是不能用于数组类型;要指定数组常量的类型,请使用 ::CAST() @@ -566,8 +562,8 @@ CAST ( 'string' AS type ) 操作符 - operator - syntax + 操作符 + 语法 @@ -617,7 +613,7 @@ CAST ( 'string' AS type ) - 圆括号(())具有它们通常的含义,用来分组表达式并且强制优先。在某些情况中,圆括号被要求作为一个特定 SQL 命令的固定语法的一部分。 + 圆括号(())具有它们通常的含义,用来对表达式分组并确定运算优先级。在某些情况中,圆括号被要求作为一个特定 SQL 命令的固定语法的一部分。 @@ -635,7 +631,7 @@ CAST ( 'string' AS type ) - 分号(;)结束一个 SQL 命令。它不能出现在一个命令中间的任何位置,除了在一个字符串常量中或者一个被引用的标识符中。 + 分号(;)结束一个 SQL 命令。它不能出现在一个命令中间的任何位置,除了在一个字符串常量中或者一个带引号的标识符中。 @@ -647,7 +643,7 @@ CAST ( 'string' AS type ) - 星号(*)在某些上下文中用来表示表行或组合值的所有字段。当它被用作聚合函数的参数时,还有一种特殊含义,即该聚合不需要任何显式参数。 + 星号(*)在某些上下文中用来表示表行或复合值的所有字段。当它被用作聚合函数的参数时,还有一种特殊含义,即该聚合不需要任何显式参数。 @@ -665,22 +661,22 @@ CAST ( 'string' AS type ) 注释 - comment - in SQL + 注释 + 在 SQL 中 注释是一串以双连字符开始并延伸到行尾的字符,例如: --- This is a standard SQL comment +-- 这是一条标准 SQL 注释 另外,也可以使用 C 风格注释块: -/* multiline comment - * with nesting: /* nested block comment */ +/* 多行注释 + * 包含嵌套:/* 嵌套块注释 */ */ 这里该注释开始于/*并且延伸到匹配出现的*/。这些注释块可按照 SQL 标准中指定的方式嵌套,但和 C 中不同。这样我们可以注释掉一大段可能包含注释块的代码。 @@ -695,8 +691,8 @@ CAST ( 'string' AS type ) 操作符优先级 - operator - precedence + 操作符 + 优先级 @@ -740,7 +736,7 @@ CAST ( 'string' AS type ) + - - 一元加、一元减 + 一元正号、一元负号 @@ -758,13 +754,13 @@ CAST ( 'string' AS type ) ^ - 指数 + 求幂 * / % - 乘、除、模 + 乘、除、取模 @@ -776,7 +772,7 @@ CAST ( 'string' AS type ) (任意其他操作符) - 所有其他本地以及用户定义的操作符 + 所有其他内置以及用户定义的操作符 @@ -833,18 +829,7 @@ SELECT 3 OPERATOR(pg_catalog.+) 4; - - 版本 9.5 之前的PostgreSQL使用的操作符优先级 - 规则略有不同。特别是,<=>= - 和<>习惯于被当作普通操作符,IS - 测试习惯于具有较高的优先级。并且在一些认为NOT比 - BETWEEN优先级高的情况下,NOT BETWEEN - 和相关的结构的行为不一致。为了更好地兼容 SQL 标准并且减少对 - 逻辑上等价的结构不一致的处理,这些规则也得到了修改。在大部分情况下, - 这些变化不会导致行为上的变化,或者可能会产生no such operator - 错误,但可以通过增加圆括号解决。不过在一些极端情况中,查询可能在 - 没有被报告解析错误的情况下发生行为的改变。 - + PostgreSQL 9.5 之前的版本使用的操作符优先级规则略有不同。特别是,<=>=<> 过去被当作普通操作符;IS 测试过去具有较高的优先级;而 NOT BETWEEN 和相关结构的处理不一致,在某些情况下被认为具有 NOT 而不是 BETWEEN 的优先级。为了更好地符合 SQL 标准,并减少对逻辑等价结构的不一致处理造成的困惑,这些规则得到了修改。在大部分情况下,这些变化不会导致行为变化,或者可能会产生 no such operator 错误,但可以通过增加圆括号解决。不过在一些极端情况下,查询可能在没有报告任何解析错误的情况下改变行为。 @@ -1537,7 +1522,7 @@ SELECT * FROM tbl WHERE a COLLATE "C" > 'foo'; SELECT * FROM tbl WHERE (a > 'foo') COLLATE "C"; - 因为它尝试把一个排序规则应用到>操作符的结果,而它的数据类型是非可排序数据类型boolean。 + 因为它尝试把一个排序规则应用到>操作符的结果,而它的数据类型是不支持排序规则的数据类型boolean。 diff --git a/zh/17/system-views.sgml b/zh/17/system-views.sgml index a6dc783a..3af83276 100644 --- a/zh/17/system-views.sgml +++ b/zh/17/system-views.sgml @@ -986,7 +986,7 @@ address text - 主机名或IP地址,或者allsamehostsamenet之一,对于本地连接为空 + 主机名或IP地址,或者allsamehostsamenet之一,对于本地连接为 NULL
@@ -995,7 +995,7 @@ netmask text - IP地址掩码,如果不适用则为空 + IP地址掩码,如果不适用则为 NULL @@ -1213,7 +1213,7 @@ (参考 pg_tablespace.spcname) - 包含索引的表空间名(如果是数据库的默认值则为空) + 包含索引的表空间名(如果是数据库的默认值则为 NULL) @@ -1222,7 +1222,7 @@ indexdef text - 索引定义(重构出的 命令) + 索引定义(重建出的 命令) @@ -1256,8 +1256,8 @@ 以及一般的数据库对象(由类OID和对象OID标识, 与pg_descriptionpg_depend中的方式相同)。 - 此外,扩展关系的权限被表示为一个单独的可锁定对象,以及更新 - pg_database.datfrozenxid 的更新权限。 + 此外,扩展关系的权利被表示为单独的可锁定对象,更新 + pg_database.datfrozenxid的权利也是如此。 此外,还可以对具有用户定义含义的数字施加咨询锁。 @@ -1304,7 +1304,7 @@ (参考 pg_database.oid) - 锁目标存在的数据库的OID,如果目标是一个共享对象则为0,如果目标是一个事务ID则为空 + 锁目标存在的数据库的OID,如果目标是一个共享对象则为0,如果目标是一个事务ID则为 NULL @@ -1314,7 +1314,7 @@ (参考 pg_class.oid) - 作为锁目标的关系的OID,如果目标不是一个关系或者只是关系的一部分则此列为空 + 作为锁目标的关系的OID,如果目标既不是关系,也不是关系的一部分则此列为 NULL @@ -1323,7 +1323,7 @@ page int4 - 作为锁目标的页在关系中的页号,如果目标不是一个关系页或元组则此列为空 + 作为锁目标的页在关系中的页号,如果目标不是一个关系页或元组则此列为 NULL @@ -1332,7 +1332,7 @@ tuple int2 - 作为锁目标的元组在页中的元组号,如果目标不是一个元组则此列为空 + 作为锁目标的元组在页中的元组号,如果目标不是一个元组则此列为 NULL @@ -1341,7 +1341,7 @@ virtualxid text - 锁定目标事务的虚拟 ID,如果目标不是虚拟事务 ID,则为空;见 + 锁定目标事务的虚拟 ID,如果目标不是虚拟事务 ID,则为 NULL;见 @@ -1351,7 +1351,7 @@ transactionid xid - 锁定目标事务的标识,如果目标不是事务 ID,则为空; + 锁定目标事务的标识,如果目标不是事务 ID,则为 NULL; @@ -1361,7 +1361,7 @@ (参考 pg_class.oid) - 包含锁目标的系统目录的OID,如果目标不是一个普通数据库对象则此列为空 + 包含锁目标的系统目录的OID,如果目标不是一个普通数据库对象则此列为 NULL @@ -1371,7 +1371,7 @@ (参考任意 OID 列) - 锁目标在它的系统目录中的OID,如果目标不是一个普通数据库对象则为空 + 锁目标在它的系统目录中的OID,如果目标不是一个普通数据库对象则为 NULL @@ -1380,7 +1380,7 @@ objsubid int2 - 锁的目标列号(classidobjid指表本身),如果目标是某种其他普通数据库对象则此列为0,如果目标不是一个普通数据库对象则此列为空 + 锁的目标列号(classidobjid指表本身),如果目标是某种其他普通数据库对象则此列为0,如果目标不是一个普通数据库对象则此列为 NULL @@ -1398,7 +1398,7 @@ pid int4 - 保持这个锁或者正在等待这个锁的服务器进程的PID,如果此锁被一个预备事务所持有则此列为空 + 保持这个锁或者正在等待这个锁的服务器进程的PID,如果此锁被一个预备事务所持有则此列为 NULL @@ -1434,8 +1434,8 @@ waitstart timestamptz - 服务器进程开始等待该锁的时间;如果锁已被授予则为空。 - 注意,在开始等待之后,即使grantedfalse,该值在极短时间内也可能仍为空。 + 服务器进程开始等待该锁的时间;如果锁已被授予则为 NULL。 + 注意,在开始等待之后,即使grantedfalse,该值在极短时间内也可能仍为 NULL。 @@ -1467,8 +1467,8 @@ 咨询锁可以在由单个 bigint 值或两个整数值组成的键上获取。 - 一个bigint键在classid列中显示其高阶半部分, - 在objid列中显示其低阶半部分,并且objsubid等于1。 + 一个bigint键在classid列中显示其高位半部分, + 在objid列中显示其低位半部分,并且objsubid等于1。 可以使用表达式(classid::bigint << 32) | objid::bigint重新组装原始bigint值。 整数键在classid列中显示第一个键,在objid列中显示第二个键, 并且 objsubid 等于 2。键的实际含义由用户自行决定。咨询锁在每个数据库内都是本地的, @@ -1517,15 +1517,15 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx pg_locks视图显示来自常规锁管理器和谓词锁管理器的数据,这两个是独立的系统; - 此外,常规锁管理器将其锁分为常规锁和fast-path锁。 + 此外,常规锁管理器将其锁分为常规锁和快速路径锁。 不能保证这些数据完全一致。 当查询该视图时, - fast-path 锁的数据(具有fastpath = true) + 快速路径锁的数据(具有fastpath = true) 从每个后端逐个收集,而不会冻结整个锁管理器的状态,因此在收集信息时可能会发生锁的获取或释放。 但请注意,这些锁已知不会与当前放置的任何其他锁发生冲突。 - 在查询所有后端的 fast-path 锁后,剩余的常规锁管理器将作为一个单元被锁定,并且所有剩余锁的一致快照将作为一个原子操作收集。 + 在查询所有后端的快速路径锁后,剩余的常规锁管理器将作为一个单元被锁定,并且所有剩余锁的一致快照将作为一个原子操作收集。 解锁常规锁管理器后,谓词锁管理器类似地被锁定,并且所有谓词锁将作为一个原子操作收集。 - 因此,除了 fast-path 锁外,每个锁管理器将提供一致的结果集,但由于我们不同时锁定两个锁管理器,因此在询问常规锁管理器后和在询问谓词锁管理器前,可能会发生锁的获取或释放。 + 因此,除了快速路径锁外,每个锁管理器将提供一致的结果集,但由于我们不同时锁定两个锁管理器,因此在询问常规锁管理器后和在询问谓词锁管理器前,可能会发生锁的获取或释放。 @@ -1601,7 +1601,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx (参考 pg_tablespace.spcname) - 包含物化视图的表空间名(如使用数据库默认表空间则为空) + 包含物化视图的表空间名(如使用数据库默认表空间则为 NULL) @@ -1628,7 +1628,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx definition text - 物化视图的定义(一个重构的查询) + 物化视图的定义(一个重建的查询) @@ -1819,7 +1819,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx 该预备语句返回列的类型,以 regtype 数组形式表示。该数组中某个元素对应的 OID 可以通过将 - regtype 值转换为 oid 获得。如果预备语句不提供结果(例如 DML 语句),则该字段为空。 + regtype 值转换为 oid 获得。如果预备语句不提供结果(例如 DML 语句),则该字段为 NULL。 @@ -2234,7 +2234,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx confirmed_flush_lsn pg_lsn - 逻辑槽消费者已确认接收到数据的地址(LSN)。在此 LSN 之前提交的事务所对应的数据将不再可用。物理槽为 NULL。 + 逻辑槽消费者已确认接收的数据所到达的地址(LSN)。在此 LSN 之前提交的事务所对应的数据将不再可用。物理槽为 NULL @@ -2288,7 +2288,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx inactive_since timestamptz - 槽变为不活动的时间。如果该槽当前正在被流式传输,则为 NULL。注意,对于备库上从主服务器同步而来的槽(其 synced 字段为 true),inactive_since 表示槽同步(参见 )最近一次停止的时间。如果该槽始终保持同步,则为 NULL。在备库上,这对那些正在从主服务器同步而来的槽(其 synced 字段为 true)很有用,因为它们可以据此知道槽何时停止被同步。 + 槽变为不活动的时间。如果当前正在从该槽流式传输数据,则为 NULL。注意,对于备库上从主库同步而来的槽(其 synced 字段为 true),inactive_since 表示槽同步(参见 )最近一次停止的时间。如果该槽始终保持同步,则为 NULL。在备库上,这对那些正在从主库同步而来的槽(其 synced 字段为 true)很有用,因为它们可以据此知道槽何时停止被同步。 @@ -2320,7 +2320,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - wal_level_insufficient 表示主库没有足够的 来执行逻辑解码。该值只会设置在逻辑槽上。 + wal_level_insufficient 表示主库的 不足以支持逻辑解码。该值只会设置在逻辑槽上。 @@ -2359,7 +2359,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx 视图pg_roles提供数据库角色的信息。它本质上是 - pg_authid 的公开可读视图,并将密码字段清空。 + pg_authid 的公开可读视图,并隐藏密码字段。 @@ -2445,7 +2445,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx rolconnlimitint4 - 对于可以登录的角色,本列设置该角色可以同时发起最大连接数。-1表示无限制。 + 对于可以登录的角色,本列设置该角色能够建立的最大并发连接数。-1 表示无限制。 @@ -2463,7 +2463,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx rolvaliduntiltimestamptz - 密码过期时间(只用于密码认证),如果永不过期则为空 + 密码过期时间(仅用于密码认证);不设过期时间时为 NULL @@ -2561,7 +2561,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx definitiontext - 规则定义(创建命令的重构) + 规则定义(重建的创建命令) @@ -2647,7 +2647,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx (参考 pg_namespace.oid) - 如果适用,为此对象的命名空间 OID;否则为空。 + 如果适用,为此对象的命名空间 OID;否则为 NULL。 @@ -2954,7 +2954,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx min_valtext - 参数的最小允许值(对非数值参数为空) + 参数的最小允许值(对非数值参数为 NULL) @@ -2963,7 +2963,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx max_valtext - 参数的最大允许值(对非数值参数为空) + 参数的最大允许值(对非数值参数为 NULL) @@ -2972,7 +2972,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx enumvalstext[] - 枚举参数的允许值(对非枚举参数为空) + 枚举参数的允许值(对非枚举参数为 NULL) @@ -3160,7 +3160,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx 这个名称源于该表不应向公众开放读取,因为它包含密码。 pg_user - 是 pg_shadow 的公开可读视图,并将密码字段清空。 + 是 pg_shadow 的公开可读视图,并隐藏密码字段。
@@ -3426,7 +3426,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx null_fracfloat4 - 列项中为空的比例 + 列项中为 NULL 的比例 @@ -3454,7 +3454,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx most_common_valsanyarray - 列中高频值的一个列表(如果没有任何一个值看起来比其他值更常用,此列为空) + 列中高频值的一个列表(如果没有任何一个值看起来比其他值更常用,此列为 NULL) @@ -3463,7 +3463,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx most_common_freqsfloat4[] - 高频值的频率列表,即每一个高频值的出现次数除以总行数(如果most_common_vals为空,则此列为空) + 高频值的频率列表,即每一个高频值的出现次数除以总行数(如果most_common_vals为 NULL,则此列为 NULL) @@ -3472,7 +3472,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx histogram_boundsanyarray - 将列值划分成大小接近的组的值列表。如果存在most_common_vals,其中的值会被直方图计算所忽略(如果列类型没有一个<操作符或者most_common_vals等于整个值集合,则此列为空) + 将列值划分成大小接近的组的值列表。如果存在most_common_vals,其中的值会被直方图计算所忽略(如果列类型没有一个<操作符或者most_common_vals等于整个值集合,则此列为 NULL) @@ -3481,7 +3481,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx correlationfloat4 - 物理行顺序和列值逻辑顺序之间的统计关联。其范围从-1到+1。当值接近-1或+1时,在列上的一个索引扫描被认为比值接近0时的代价更低,因为这种情况减少了对磁盘的随机访问(如果列数据类型不具有一个<操作符,则此列为空) + 物理行顺序和列值逻辑顺序之间的统计关联。其范围从-1到+1。当值接近-1或+1时,在列上的一个索引扫描被认为比值接近0时的代价更低,因为这种情况减少了对磁盘的随机访问(如果列数据类型不具有一个<操作符,则此列为 NULL) @@ -3490,7 +3490,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx most_common_elemsanyarray - 在列值中,最经常出现的非空元素列表(对标量类型为空) + 在列值中,最经常出现的非空元素列表(对标量类型为 NULL) @@ -3500,7 +3500,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx 最常用元素值的频度列表,即含有至少一个给定值实例的行的分数。 - 在每个元素的频度之后有二至三个附加值,它们是每个元素频度的最小和最大值,以及可选的空元素的频度(如果most_common_elems为空,则此列为空) + 在每个元素的频度之后有二至三个附加值,它们是每个元素频度的最小和最大值,以及可选的空元素的频度(如果most_common_elems为 NULL,则此列为 NULL) @@ -3509,7 +3509,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx elem_count_histogramfloat4[] - 在列值中可区分非空元素值计数的一个直方图,后面跟随可区分非空元素的平均数(对于标量类型为空) + 在列值中可区分非空元素值计数的一个直方图,后面跟随可区分非空元素的平均数(对于标量类型为 NULL) @@ -3518,7 +3518,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx range_length_histogramanyarray - 范围类型列中非空且非 NULL 的范围值长度直方图。(对非范围类型为空。) + 范围类型列中非空且非 NULL 的范围值长度直方图。(非范围类型为 null。) 该直方图使用范围函数 subtype_diff 计算,而不考虑范围边界是否包含端点。 @@ -3530,7 +3530,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx range_empty_frac float4 - 列项中值为空范围的比例。(对非范围类型为空。) + 列项中值为空范围的比例。(非范围类型为 null。) @@ -3539,10 +3539,10 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx range_bounds_histogramanyarray - 非空且非 NULL 的范围值下界和上界的直方图。(对非范围类型为空。) + 非空且非 NULL 的范围值下界和上界的直方图。(非范围类型为 null。) - 这两个直方图表示为单个数组列,其中下半部分表示下界的直方图,上半部分表示上界的直方图。 + 这两个直方图表示为一个范围数组,其中各范围的下界表示下界直方图,上界表示上界直方图。 @@ -3708,7 +3708,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx most_common_valstext[] - 列中值的最常见组合的列表(如果没有组合看上去比其它的更常见,则为空。) + 列中值的最常见组合的列表(如果没有组合看上去比其它的更常见,则为 NULL。) @@ -3717,7 +3717,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx most_common_val_nullsbool[] - 值最常见组合的NULL标志的列表(当most_common_vals是空值时,为空。) + 值最常见组合的NULL标志的列表(当most_common_vals为 NULL 时,为 NULL。) @@ -3726,7 +3726,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx most_common_freqsfloat8[] - 最常见组合的频率的列表,即每个出现的数量除以行的总数(当most_common_vals是空值时,为空) + 最常见组合的频率的列表,即每个出现的数量除以行的总数(当most_common_vals为 NULL 时,为 NULL) @@ -3735,7 +3735,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx most_common_base_freqsfloat8[] - 最常见组合的基本频率的列表,即每个值频率的乘积。(当most_common_vals是空值时,为空。) + 最常见组合的基本频率的列表,即每个值频率的乘积。(当most_common_vals为 NULL 时,为 NULL。) @@ -3860,7 +3860,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx null_fracfloat4 - 表达式条目为空的比例 + 表达式条目为 NULL 的比例 @@ -3888,7 +3888,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx most_common_valsanyarray - 表达式中高频值的列表(如果没有值看起来比任何其他值更常见则为空) + 表达式中高频值的列表(如果没有值看起来比任何其他值更常见则为 NULL) @@ -3897,7 +3897,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx most_common_freqsfloat4[] - 高频值的频率列表,即每一个高频值的出现次数除以总行数(如果most_common_vals为空,则此列为空) + 高频值的频率列表,即每一个高频值的出现次数除以总行数(如果most_common_vals为 NULL,则此列为 NULL) @@ -3906,7 +3906,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx histogram_boundsanyarray - 将表达式的值划分成大小接近的组的值列表。如果存在most_common_vals,其中的值会被直方图计算所忽略(如果表达式的数据类型没有一个<操作符或者most_common_vals等于整个值集合,则此列为空) + 将表达式的值划分成大小接近的组的值列表。如果存在most_common_vals,其中的值会被直方图计算所忽略(如果表达式的数据类型没有一个<操作符或者most_common_vals等于整个值集合,则此列为 NULL) @@ -3915,7 +3915,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx correlationfloat4 - 物理行顺序和表达式值逻辑顺序之间的统计关联。其范围从-1到+1。当值接近-1或+1时,在表达式上的一个索引扫描被认为比值接近0时的代价更低,因为这种情况减少了对磁盘的随机访问(如果表达式的数据类型不具有一个<操作符,则此列为空) + 物理行顺序和表达式值逻辑顺序之间的统计关联。其范围从-1到+1。当值接近-1或+1时,在表达式上的一个索引扫描被认为比值接近0时的代价更低,因为这种情况减少了对磁盘的随机访问(如果表达式的数据类型不具有一个<操作符,则此列为 NULL) @@ -3924,7 +3924,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx most_common_elemsanyarray - 与表达式的值一起最常出现的非空元素值的列表。(标量类型时为空) + 与表达式的值一起最常出现的非空元素值的列表。(标量类型时为 NULL) @@ -3934,7 +3934,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx 最常用元素值的频度列表,即含有至少一个给定值实例的行的分数。 - 在每个元素的频度之后有二至三个附加值,它们是每个元素频度的最小和最大值,以及可选的空元素的频度(如果most_common_elems为空,则此列为空) + 在每个元素的频度之后有二至三个附加值,它们是每个元素频度的最小和最大值,以及可选的空元素的频度(如果most_common_elems为 NULL,则此列为 NULL) @@ -3943,7 +3943,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx elem_count_histogramfloat4[] - 表达式值的不同非空元素值的计数的直方图,后面跟着不同非空元素的平均数量。(标量类型时为空) + 表达式值的不同非空元素值的计数的直方图,后面跟着不同非空元素的平均数量。(标量类型时为 NULL) @@ -4020,7 +4020,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx (参考 pg_tablespace.spcname) - 包含该表的表空间名称(如果使用数据库的默认表空间,此列为空) + 包含该表的表空间名称(如果使用数据库的默认表空间,此列为 NULL) @@ -4216,7 +4216,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx 视图pg_user提供数据库用户的信息。它本质上是 - pg_shadow 的公开可读视图,并将密码字段清空。 + pg_shadow 的公开可读视图,并隐藏密码字段。
@@ -4494,7 +4494,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx definitiontext - 视图定义(一个重构的查询) + 视图定义(一个重建的查询) diff --git a/zh/17/targets-meson.txt b/zh/17/targets-meson.txt index d0021a5e..0fcabe3f 100644 --- a/zh/17/targets-meson.txt +++ b/zh/17/targets-meson.txt @@ -7,37 +7,37 @@ # remaining lines are target separated by whitespace from their description # Code Targets: - all Build everything other than documentation - backend Build backend and related modules - bin Build frontend binaries - contrib Build contrib modules - pl Build procedural languages + all 构建文档以外的所有内容 + backend 构建后端及相关模块 + bin 构建前端二进制程序 + contrib 构建 contrib 模块 + pl 构建过程语言 Developer Targets: - reformat-dat-files Rewrite catalog data files into standard format - expand-dat-files Expand all data files to include defaults - update-unicode Update unicode data to new version + reformat-dat-files 将系统目录数据文件改写为标准格式 + expand-dat-files 展开所有数据文件以包含默认值 + update-unicode 将 Unicode 数据更新到新版本 Documentation Targets: - html Build documentation in multi-page HTML format - man Build documentation in man page format - docs Build documentation in multi-page HTML and man page format - doc/src/sgml/postgres-A4.pdf Build documentation in PDF format, with A4 pages - doc/src/sgml/postgres-US.pdf Build documentation in PDF format, with US letter pages - doc/src/sgml/postgres.html Build documentation in single-page HTML format - alldocs Build documentation in all supported formats + html 构建多页 HTML 格式的文档 + man 构建手册页格式的文档 + docs 构建多页 HTML 和手册页格式的文档 + doc/src/sgml/postgres-A4.pdf 构建 A4 页面大小的 PDF 格式文档 + doc/src/sgml/postgres-US.pdf 构建 US letter 页面大小的 PDF 格式文档 + doc/src/sgml/postgres.html 构建单页 HTML 格式的文档 + alldocs 构建所有支持格式的文档 Installation Targets: - install Install postgres, excluding documentation - install-docs Install documentation in multi-page HTML and man page formats - install-html Install documentation in multi-page HTML format - install-man Install documentation in man page format - install-quiet Like "install", but installed files are not displayed - install-world Install postgres, including multi-page HTML and man page documentation - uninstall Remove installed files + install 安装 postgres,不包括文档 + install-docs 安装多页 HTML 和手册页格式的文档 + install-html 安装多页 HTML 格式的文档 + install-man 安装手册页格式的文档 + install-quiet 与“install”相同,但不显示安装的文件 + install-world 安装 postgres,包括多页 HTML 和手册页格式的文档 + uninstall 删除已安装的文件 Other Targets: - clean Remove all build products - test Run all enabled tests (including contrib) - world Build everything, including documentation - help List important targets + clean 删除所有构建产物 + test 运行所有已启用的测试(包括 contrib) + world 构建所有内容,包括文档 + help 列出重要的目标 diff --git a/zh/17/textsearch.sgml b/zh/17/textsearch.sgml index 2ba36ca8..0bb657b1 100644 --- a/zh/17/textsearch.sgml +++ b/zh/17/textsearch.sgml @@ -2099,7 +2099,7 @@ ALTER TEXT SEARCH CONFIGURATION russian 分类词典示例 - 考虑简单的天文词库 thesaurus_astro,其中包含一些天文单词组合: + 考虑简单的天文词库 thesaurus_astro,其中包含一些天文单词组合: supernovae stars : sn @@ -2534,7 +2534,7 @@ ts_debug( config re - 以下是一个简单的示例: + 以下是一个简单的示例: SELECT * FROM ts_debug('english', 'a fat cat sat on a mat - it ate a fat rats'); diff --git a/zh/17/trigger.sgml b/zh/17/trigger.sgml index 14df9325..0589f684 100644 --- a/zh/17/trigger.sgml +++ b/zh/17/trigger.sgml @@ -4,7 +4,7 @@ 触发器 - trigger + 触发器 @@ -73,8 +73,7 @@ 如果触发器被定义为 约束触发器,则 AFTER 触发器的执行可被推迟到事务末尾,而不是语句末尾。 - 无论哪种情况,触发器都作为触发它的语句所属同一事务的一部分执行,因此只要语句或触发器任一方发生错误,二者的效果都会回滚。此外,触发器总是以将该触发事件排入队列的角色身份运行,除非触发器函数标记为 - SECURITY DEFINER,那样的话则以函数所有者身份运行。 + 无论哪种情况,触发器都作为触发它的语句所属同一事务的一部分执行,因此只要语句或触发器任一方发生错误,二者的效果都会回滚。 @@ -125,7 +124,7 @@ - 在执行 MERGE 命令时,对于该命令动作中指定的事件,无论该动作最终是否实际执行,语句级 + 在执行 MERGE 命令时,对于 MERGE 命令的动作中指定的事件,无论该动作最终是否实际执行,语句级 BEFOREAFTER 触发器都会触发。这与更新零行的 UPDATE 语句相同:尽管没有行被更新,语句级触发器仍会触发。只有在某行确实被更新、插入或删除时,行级触发器才会触发。因此,完全可能出现这样的情况:某类动作的语句级触发器已经触发,而同类动作的行级触发器却一个也没有触发。 @@ -169,18 +168,18 @@ 生成列还有一些额外注意事项。 - generated columnin - triggers + 生成列在触发器中 存储型生成列会在 BEFORE 触发器之后、AFTER 触发器之前计算。因此,可以在 AFTER 触发器中检查生成值。在 BEFORE 触发器中,OLD 行如预期那样包含旧的 生成值,但 NEW 行尚未包含新的生成值,因此不应访问。对于 C 语言接口,此时该列内容未定义;更高层编程语言应阻止在 BEFORE 触发器中访问 NEW 行中的存储型 - 生成列。在 BEFORE 触发器中对生成列值所做的修改会被忽略并随后被覆盖。 + 生成列。在 BEFORE 触发器中对生成列值所做的修改会被忽略并随后被覆盖。 + - 如果在同一关系上的同一事件为其定义了多个触发器,它们会按触发器名称的字母顺序触发。对于 BEFOREINSTEAD OF + 如果为同一关系上的同一事件定义了多个触发器,它们会按触发器名称的字母顺序触发。对于 BEFOREINSTEAD OF 触发器,每个触发器返回的、可能已经被修改过的行都会成为下一个触发器的输入。如果任何一个 BEFOREINSTEAD OF 触发器返回 NULL,则会放弃对该行执行该操作,并且后续触发器(针对该行)都不会再触发。 @@ -190,7 +189,7 @@ 条件,不过这个特性对它们用处不大。)在 BEFORE 触发器中, WHEN 条件就在函数即将执行或本会执行之前求值,因此使用 WHEN 与在触发器函数开头测试同样的条件并无实质差别。不过,在 - AFTER 触发器中,WHEN 条件会在行更改发生后立即求值,并决定是否要在语句末尾将一个事件排入队列以触发该触发器。因此,当 AFTER 触发器的 WHEN + AFTER 触发器中,WHEN 条件会在行更改发生后立即求值,并决定是否要将一个事件排入队列,以便在语句末尾触发该触发器。因此,当 AFTER 触发器的 WHEN 条件不返回真时,就不必排队该事件,也不必在语句末尾重新取出该行。如果触发器只需要针对少数几行触发,这会让修改大量行的语句显著加快。 INSTEAD OF 触发器不支持 WHEN 条件。 @@ -216,8 +215,8 @@ - trigger - arguments for trigger functions + 触发器 + 触发器函数的参数 在定义触发器时,可以为它指定参数。在触发器定义中包含参数,是为了让需求相似的不同触发器能够调用同一个函数。举例来说,可以有一个通用触发器函数,它接受两个列名作为参数,把当前用户写入其中一个列,把当前时间戳写入另一个列。只要编写得当,这个触发器函数就应独立于它所作用的具体表。因此,同一个函数可用于任何具有适当列的表上的 INSERT 事件,例如自动跟踪某个事务表中记录的创建。如果把它定义成 UPDATE 触发器,还可以用来跟踪最近更新事件。 @@ -300,13 +299,13 @@ 用 C 编写触发器函数 - trigger - in C + 触发器 + 在 C 中 - transition tables - referencing from C trigger + 过渡表 + 从 C 触发器中引用 @@ -318,7 +317,7 @@ - 当函数由触发器管理器调用时,不会向它传递任何普通参数,但会传递一个指向 TriggerData 结构体的 context 指针。C 函数可以通过执行下列宏来检查自己是否由触发器管理器调用: + 当函数由触发器管理器调用时,不会向它传递任何普通参数,但会传递一个指向 TriggerData 结构体的 上下文 指针。C 函数可以通过执行下列宏来检查自己是否由触发器管理器调用: CALLED_AS_TRIGGER(fcinfo) @@ -377,7 +376,7 @@ typedef struct TriggerData TRIGGER_FIRED_BEFORE(tg_event) - 如果触发器在操作之前触发,则返回 true。 + 如果触发器在操作之前触发,则返回真。 @@ -386,7 +385,7 @@ typedef struct TriggerData TRIGGER_FIRED_AFTER(tg_event) - 如果触发器在操作之后触发,则返回 true。 + 如果触发器在操作之后触发,则返回真。 @@ -395,7 +394,7 @@ typedef struct TriggerData TRIGGER_FIRED_INSTEAD(tg_event) - 如果触发器是取代该操作而触发,则返回 true。 + 如果触发器是取代该操作而触发,则返回真。 @@ -404,7 +403,7 @@ typedef struct TriggerData TRIGGER_FIRED_FOR_ROW(tg_event) - 如果触发器是因行级事件触发,则返回 true。 + 如果触发器是因行级事件触发,则返回真。 @@ -413,7 +412,7 @@ typedef struct TriggerData TRIGGER_FIRED_FOR_STATEMENT(tg_event) - 如果触发器是因语句级事件触发,则返回 true。 + 如果触发器是因语句级事件触发,则返回真。 @@ -422,7 +421,7 @@ typedef struct TriggerData TRIGGER_FIRED_BY_INSERT(tg_event) - 如果触发器是由 INSERT 命令触发,则返回 true。 + 如果触发器是由 INSERT 命令触发,则返回真。 @@ -431,7 +430,7 @@ typedef struct TriggerData TRIGGER_FIRED_BY_UPDATE(tg_event) - 如果触发器是由 UPDATE 命令触发,则返回 true。 + 如果触发器是由 UPDATE 命令触发,则返回真。 @@ -440,7 +439,7 @@ typedef struct TriggerData TRIGGER_FIRED_BY_DELETE(tg_event) - 如果触发器是由 DELETE 命令触发,则返回 true。 + 如果触发器是由 DELETE 命令触发,则返回真。 @@ -449,7 +448,7 @@ typedef struct TriggerData TRIGGER_FIRED_BY_TRUNCATE(tg_event) - 如果触发器是由 TRUNCATE 命令触发,则返回 true。 + 如果触发器是由 TRUNCATE 命令触发,则返回真。 @@ -608,16 +607,16 @@ typedef struct Trigger - 一个完整的触发器实例 + 一个完整的触发器示例 这里给出一个非常简单的、用 C 编写的触发器函数示例。(用过程语言编写的触发器示例可见各过程语言的文档。) - 如果某条命令试图向列 x 中插入空值,函数 - trigf 就会报告表 ttest - 中的行数,并跳过实际操作。(这样,这个触发器就起到了非空约束的作用,但不会中止事务。) + 函数 trigf 会报告表 ttest 中的行数, + 并在命令试图向列 x 中插入空值时跳过实际操作。 + (这样,这个触发器就起到了非空约束的作用,但不会中止事务。) diff --git a/zh/17/typeconv.sgml b/zh/17/typeconv.sgml index 15e7c27c..984ee0cf 100644 --- a/zh/17/typeconv.sgml +++ b/zh/17/typeconv.sgml @@ -30,7 +30,7 @@ -PostgreSQL扫描器/解析器将词法元素分成五个基本类别:整数、非整数数字、字符串、标识符和关键字。大多数非数值类型的常量会先被归类为字符串。SQL语言定义允许用字符串指定类型名,而PostgreSQL可以利用这一机制让解析器从一开始就沿着正确的路径处理。例如,查询: +PostgreSQL扫描器/解析器将词法元素分成五个基本类别:整数、非整数数字、字符串、标识符和关键字。大多数非数值类型的常量会先被归类为字符串。SQL语言定义允许给字符串指定类型名,而PostgreSQL可以利用这一机制让解析器从一开始就沿着正确的路径处理。例如,查询: SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; @@ -41,7 +41,7 @@ SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; (1 row) -包含两个文字常量,它们的类型分别是textpoint。如果没有为某个字符串文字指定类型,那么它最初会被赋予占位类型unknown,并在后文所述的后续阶段解析。 +包含两个字面量,它们的类型分别是textpoint。如果没有为某个字符串字面量指定类型,那么它最初会被赋予占位类型unknown,并在后文所述的后续阶段解析。 @@ -166,11 +166,11 @@ SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; -检查是否存在一个恰好接受输入参数类型的操作符。如果存在(在被考虑的操作符集合中至多只有一个精确匹配),就使用它。若通过限定名调用(这种情况并不常见)某个允许不可信用户创建对象的模式中的操作符,而又缺少精确匹配,就会带来安全隐患 +检查是否存在一个恰好接受输入参数类型的操作符。如果存在(在被考虑的操作符集合中至多只有一个精确匹配),就使用它。若通过限定名调用(这种情况并不常见)某个允许不受信任的用户创建对象的模式中的操作符,而又缺少精确匹配,就会带来安全隐患 - 对于未带模式限定的名称,不会出现这种隐患,因为包含允许不可信用户创建对象的模式的搜索路径不是一种模式的安全使用方式。 + 对于未带模式限定的名称,不会出现这种隐患,因为包含允许不受信任的用户创建对象的模式的搜索路径不是一种模式的安全使用方式。 。在这种情况下,应通过对参数进行类型转换来强制获得精确匹配。 @@ -186,7 +186,7 @@ SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; -如果二元操作符调用的一个参数是unknown类型,而另一个是域类型,则接着检查是否存在两边都恰好接受该域基类型的操作符;如果有,就使用它。 +如果二元操作符调用的一个参数是unknown类型,而另一个是域类型,则接着检查是否存在两边都恰好接受该域基础类型的操作符;如果有,就使用它。 @@ -201,13 +201,13 @@ SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; -丢弃那些输入类型不匹配,且也无法通过隐式类型转换实现匹配的候选操作符。为此,假定unknown文字可以转换为任何类型。如果只剩一个候选操作符,就使用它;否则继续下一步。 +丢弃那些输入类型不匹配,且也无法通过隐式类型转换实现匹配的候选操作符。为此,假定unknown字面量可以转换为任何类型。如果只剩一个候选操作符,就使用它;否则继续下一步。 -如果任何输入参数是域类型,则在后续所有步骤中都把它当作该域的基类型。这样可以确保在解决操作符歧义时,域的行为与其基类型一致。 +如果任何输入参数是域类型,则在后续所有步骤中都把它当作该域的基础类型。这样可以确保在解决操作符歧义时,域的行为与其基础类型一致。 @@ -219,13 +219,13 @@ SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; -遍历所有候选操作符,保留那些在需要类型转换的最多位置上接受首选类型(属于输入数据类型的类型分类)的候选项。如果没有候选项接受首选类型,则保留全部候选项。如果只剩一个候选操作符,就使用它;否则继续下一步。 +遍历所有候选操作符,在需要类型转换的位置上,保留接受首选类型(属于输入数据类型的类型分类)的位置数最多的候选项。如果没有候选项接受首选类型,则保留全部候选项。如果只剩一个候选操作符,就使用它;否则继续下一步。 -如果有任何输入参数是unknown,就检查剩余候选操作符在这些参数位置上接受哪些类型分类。在每个位置上,如果有任何候选项接受string分类,就选择该分类。(这种偏向字符串的做法是合适的,因为unknown类型的文字看起来像字符串。)否则,如果所有剩余候选项都接受同一种类型分类,就选择该分类;否则失败,因为在缺少更多线索的情况下无法推断出正确选择。然后丢弃不接受所选类型分类的候选项。此外,如果有任何候选项接受该分类中的首选类型,就丢弃在该参数上接受非首选类型的候选项。如果没有候选项通过这些测试,则保留全部候选项。如果只剩一个候选操作符,就使用它;否则继续下一步。 +如果有任何输入参数是unknown,就检查剩余候选操作符在这些参数位置上接受哪些类型分类。在每个位置上,如果有任何候选项接受string分类,就选择该分类。(这种偏向字符串的做法是合适的,因为unknown类型的字面量看起来像字符串。)否则,如果所有剩余候选项都接受同一种类型分类,就选择该分类;否则失败,因为在缺少更多线索的情况下无法推断出正确选择。然后丢弃不接受所选类型分类的候选项。此外,如果有任何候选项接受该分类中的首选类型,就丢弃在该参数上接受非首选类型的候选项。如果没有候选项通过这些测试,则保留全部候选项。如果只剩一个候选操作符,就使用它;否则继续下一步。 @@ -273,7 +273,7 @@ SELECT |/ CAST(40 AS double precision) AS "square root of 40"; -一个只有一个未指定参数的例子: +一个参数未指定类型的例子: SELECT text 'abc' || 'def' AS "text and unknown"; @@ -301,7 +301,7 @@ SELECT 'abc' || 'def' AS "unspecified"; -这里对使用哪种类型没有初始提示,因为查询中没有指定任何类型。因此,解析器会查找所有候选操作符,并发现既有接受字符串分类输入的候选项,也有接受位串分类输入的候选项。由于在可用时优先选择字符串分类,所以会选中该分类,再使用字符串的首选类型text作为解析这些unknown类型文字的具体类型。 +这里对使用哪种类型没有初始提示,因为查询中没有指定任何类型。因此,解析器会查找所有候选操作符,并发现既有接受字符串分类输入的候选项,也有接受位串分类输入的候选项。由于在可用时优先选择字符串分类,所以会选中该分类,再使用字符串的首选类型text作为解析这些unknown类型字面量的具体类型。 @@ -318,7 +318,7 @@ SELECT @ '-4.5' AS "abs"; 4.5 (1 row) -这里,系统在应用所选操作符之前,已经把unknown类型文字隐式解析为float8。我们可以验证使用的确实是float8,而不是其他类型: +这里,系统在应用所选操作符之前,已经把unknown类型字面量隐式解析为float8。我们可以验证使用的确实是float8,而不是其他类型: SELECT @ '-4.5e500' AS "abs"; @@ -352,7 +352,7 @@ SELECT ~ CAST('20' AS int8) AS "negation"; 数组包含操作符类型解析 -下面是另一个解析一边已知、一边未知输入的操作符的例子: +下面是另一个解析带有一个已知类型输入和一个未知类型输入的操作符的例子: SELECT array[1,2] <@ '{1,2,3}' as "is subset"; @@ -361,7 +361,7 @@ SELECT array[1,2] <@ '{1,2,3}' as "is subset"; t (1 row) -PostgreSQL操作符目录中为中缀操作符<@定义了多个条目,但左侧能够接受整数数组的只有两种:数组包含(anyarray <@ anyarray)和范围包含(anyelement <@ anyrange)。由于这些多态伪类型(见)都不被视为首选类型,解析器无法据此消除歧义。不过,告诉它可以假定unknown类型文字与另一输入具有相同类型,也就是整数数组。这样两个操作符中只有一个能够匹配,因此会选择数组包含。(如果选中范围包含,就会报错,因为该字符串的格式并不是合法的范围文字。) +PostgreSQL操作符目录中为中缀操作符<@定义了多个条目,但左侧能够接受整数数组的只有两种:数组包含(anyarray <@ anyarray)和范围包含(anyelement <@ anyrange)。由于这些多态伪类型(见)都不被视为首选类型,解析器无法据此消除歧义。不过,要求它假定unknown类型字面量与另一输入具有相同类型,也就是整数数组。这样两个操作符中只有一个能够匹配,因此会选择数组包含。(如果选中范围包含,就会报错,因为该字符串的格式并不是合法的范围字面量。) @@ -370,7 +370,7 @@ SELECT array[1,2] <@ '{1,2,3}' as "is subset"; 域类型上的自定义操作符 -用户有时会尝试声明只适用于某个域类型的操作符。这是可行的,但远没有看上去那样有用,因为操作符解析规则被设计成优先选择作用于域基类型的操作符。考虑下面的例子: +用户有时会尝试声明只适用于某个域类型的操作符。这是可行的,但远没有看上去那样有用,因为操作符解析规则被设计成优先选择作用于域基础类型的操作符。考虑下面的例子: CREATE DOMAIN mytext AS text CHECK(...); CREATE FUNCTION mytext_eq_text (mytext, text) RETURNS boolean AS ...; @@ -379,11 +379,11 @@ CREATE TABLE mytable (val mytext); SELECT * FROM mytable WHERE val = 'foo'; -这个查询不会使用自定义操作符。解析器首先会检查是否存在mytext = mytext操作符(),但并不存在;然后它会考虑该域的基类型text,并检查是否存在text = text操作符(),而这是存在的;于是它会把unknown类型的文字解析为text,并使用text = text操作符。要让自定义操作符被使用,唯一的方法是显式地对该文字做类型转换: +这个查询不会使用自定义操作符。解析器首先会检查是否存在mytext = mytext操作符(),但并不存在;然后它会考虑该域的基础类型text,并检查是否存在text = text操作符(),而这是存在的;于是它会把unknown类型的字面量解析为text,并使用text = text操作符。要让自定义操作符被使用,唯一的方法是显式地对该字面量做类型转换: SELECT * FROM mytable WHERE val = text 'foo'; -这样就会根据精确匹配规则立即找到mytext = text操作符。如果解析过程进入最佳匹配规则,它们会主动排斥作用于域类型的操作符。如果不是这样,这类操作符会导致过多的操作符歧义失败,因为类型转换规则总是把域视为可以转换到其基类型或从其基类型转换而来,因此域操作符会在所有与基类型上同名操作符相同的场景中都被视为可用。 +这样就会根据精确匹配规则立即找到mytext = text操作符。如果解析过程进入最佳匹配规则,它们会主动排斥作用于域类型的操作符。如果不是这样,这类操作符会导致过多的操作符歧义失败,因为类型转换规则总是把域视为可以转换到其基础类型或从其基础类型转换而来,因此域操作符会在所有与基础类型上同名操作符相同的场景中都被视为可用。 @@ -422,27 +422,27 @@ SELECT * FROM mytable WHERE val = text 'foo'; -如果函数声明了一个VARIADIC数组参数,而调用时没有使用VARIADIC关键字,则把该函数视为其数组参数按需要被其元素类型的一个或多个出现所替换,以匹配该调用。扩展之后,该函数的有效参数类型可能与某个非VARIADIC函数完全相同。在这种情况下,使用搜索路径中较早出现的函数;如果两个函数位于同一模式,则优先选择非VARIADIC函数。 +如果函数声明了一个VARIADIC数组参数,而调用时没有使用VARIADIC关键字,则把数组参数视为一个或多个其元素类型的参数,个数按匹配该调用的需要确定。扩展之后,该函数的有效参数类型可能与某个非VARIADIC函数完全相同。在这种情况下,使用搜索路径中较早出现的函数;如果两个函数位于同一模式,则优先选择非VARIADIC函数。 -通过限定名调用某个允许不可信用户创建对象的模式中找到的可变参数函数时,会带来安全隐患 +通过限定名调用某个允许不受信任的用户创建对象的模式中找到的可变参数函数时,会带来安全隐患 - 对于未带模式限定的名称,不会出现这种隐患,因为包含允许不可信用户创建对象的模式的搜索路径不是一种模式的安全使用方式。 + 对于未带模式限定的名称,不会出现这种隐患,因为包含允许不受信任的用户创建对象的模式的搜索路径不是一种模式的安全使用方式。 - 。恶意用户可以借此劫持调用,并以你的身份执行任意 SQL 函数。改为使用带有VARIADIC关键字的调用可以绕过这一隐患。对于填充VARIADIC "any"参数的调用,往往没有包含VARIADIC关键字的等价写法。要安全地发出这类调用,该函数所在模式必须只允许可信用户创建对象。 + 。恶意用户可以借此劫持调用,并以你的身份执行任意 SQL 函数。改为使用带有VARIADIC关键字的调用可以绕过这一隐患。对于填充VARIADIC "any"参数的调用,往往没有包含VARIADIC关键字的等价写法。要安全地发出这类调用,该函数所在模式必须只允许受信任的用户创建对象。 -带有参数默认值的函数,被认为可以匹配任何省略了零个或多个可默认参数位置的调用。如果不止一个这样的函数能匹配某个调用,则使用搜索路径中最早出现的那一个。如果同一模式中存在两个或更多这样的函数,并且它们在未使用默认值的参数位置上的参数类型相同(如果它们具有不同的可默认参数集合,这种情况是可能的),系统就无法判断该偏好哪一个;如果找不到更好的匹配,就会报有歧义的函数调用错误。 +带有参数默认值的函数,被认为可以匹配任何省略了零个或多个可使用默认值的参数位置的调用。如果不止一个这样的函数能匹配某个调用,则使用搜索路径中最早出现的那一个。如果同一模式中存在两个或更多这样的函数,并且它们在未使用默认值的参数位置上的参数类型相同(如果它们具有不同的带有默认值的参数集合,这种情况是可能的),系统就无法判断该偏好哪一个;如果找不到更好的匹配,就会报有歧义的函数调用错误。 -通过限定名调用某个允许不可信用户创建对象的模式中的任意函数时,会带来可用性隐患。恶意用户可以用现有函数的名字创建一个新函数,复制该函数的参数,并附加带有默认值的新参数。这样就会阻止对原始函数的新调用。为避免这种隐患,应把函数放在只允许可信用户创建对象的模式中。 +通过限定名调用某个允许不受信任的用户创建对象的模式中的任意函数时,会带来可用性隐患。恶意用户可以用现有函数的名字创建一个新函数,复制该函数的参数,并附加带有默认值的新参数。这样就会阻止对原始函数的新调用。为避免这种隐患,应把函数放在只允许受信任的用户创建对象的模式中。 @@ -451,14 +451,14 @@ SELECT * FROM mytable WHERE val = text 'foo'; -检查是否存在一个恰好接受输入参数类型的函数。如果存在(在被考虑的函数集合中至多只有一个精确匹配),就使用它。若通过限定名调用某个允许不可信用户创建对象的模式中的函数,而又缺少精确匹配,就会带来安全隐患。在这种情况下,应通过对参数进行类型转换来强制获得精确匹配。(涉及unknown的情况在这一步永远找不到匹配。) +检查是否存在一个恰好接受输入参数类型的函数。如果存在(在被考虑的函数集合中至多只有一个精确匹配),就使用它。若通过限定名调用某个允许不受信任的用户创建对象的模式中的函数,而又缺少精确匹配,就会带来安全隐患。在这种情况下,应通过对参数进行类型转换来强制获得精确匹配。(涉及unknown的情况在这一步永远找不到匹配。) -如果没有找到精确匹配,就检查该函数调用是否看起来像一种特殊的类型转换请求。这种情况发生在:函数调用只有一个参数,且函数名与某个数据类型的(内部)名称相同。此外,函数参数必须是unknown类型文字,或者是一种能够进行二进制强制转换到该命名数据类型的类型,或者是一种可以通过应用其 I/O 函数转换为该命名数据类型的类型(也就是说,该转换要么转到某种标准字符串类型,要么从某种标准字符串类型转来)。满足这些条件时,该函数调用会被当作一种CAST形式。 +如果没有找到精确匹配,就检查该函数调用是否看起来像一种特殊的类型转换请求。这种情况发生在:函数调用只有一个参数,且函数名与某个数据类型的(内部)名称相同。此外,函数参数必须是unknown类型字面量,或者是一种可以二进制强制转换为该命名数据类型的类型,或者是一种可以通过应用其 I/O 函数转换为该命名数据类型的类型(也就是说,该转换要么转到某种标准字符串类型,要么从某种标准字符串类型转来)。满足这些条件时,该函数调用会被当作一种CAST形式。 之所以有这一步,是为了在不存在实际类型转换函数的情况下仍支持函数风格的类型转换写法。如果存在类型转换函数,按惯例它会以其输出类型命名,因此无需为此设置特殊情况。更多说明见。 @@ -475,13 +475,13 @@ SELECT * FROM mytable WHERE val = text 'foo'; -丢弃那些输入类型不匹配,且也无法通过隐式类型转换实现匹配的候选函数。为此,假定unknown文字可以转换为任何类型。如果只剩一个候选函数,就使用它;否则继续下一步。 +丢弃那些输入类型不匹配,且也无法通过隐式类型转换实现匹配的候选函数。为此,假定unknown字面量可以转换为任何类型。如果只剩一个候选函数,就使用它;否则继续下一步。 -如果任何输入参数是域类型,则在后续所有步骤中都把它当作该域的基类型。这样可以确保在解决函数歧义时,域的行为与其基类型一致。 +如果任何输入参数是域类型,则在后续所有步骤中都把它当作该域的基础类型。这样可以确保在解决函数歧义时,域的行为与其基础类型一致。 @@ -493,13 +493,13 @@ SELECT * FROM mytable WHERE val = text 'foo'; -遍历所有候选函数,保留那些在需要类型转换的最多位置上接受首选类型(属于输入数据类型的类型分类)的候选项。如果没有候选项接受首选类型,则保留全部候选项。如果只剩一个候选函数,就使用它;否则继续下一步。 +遍历所有候选函数,在需要类型转换的位置上,保留接受首选类型(属于输入数据类型的类型分类)的位置数最多的候选项。如果没有候选项接受首选类型,则保留全部候选项。如果只剩一个候选函数,就使用它;否则继续下一步。 -如果有任何输入参数是unknown,就检查剩余候选函数在这些参数位置上接受哪些类型分类。在每个位置上,如果有任何候选项接受string分类,就选择该分类。(这种偏向字符串的做法是合适的,因为unknown类型的文字看起来像字符串。)否则,如果所有剩余候选项都接受同一种类型分类,就选择该分类;否则失败,因为在缺少更多线索的情况下无法推断出正确选择。然后丢弃不接受所选类型分类的候选项。此外,如果有任何候选项接受该分类中的首选类型,就丢弃在该参数上接受非首选类型的候选项。如果没有候选项通过这些测试,则保留全部候选项。如果只剩一个候选函数,就使用它;否则继续下一步。 +如果有任何输入参数是unknown,就检查剩余候选函数在这些参数位置上接受哪些类型分类。在每个位置上,如果有任何候选项接受string分类,就选择该分类。(这种偏向字符串的做法是合适的,因为unknown类型的字面量看起来像字符串。)否则,如果所有剩余候选项都接受同一种类型分类,就选择该分类;否则失败,因为在缺少更多线索的情况下无法推断出正确选择。然后丢弃不接受所选类型分类的候选项。此外,如果有任何候选项接受该分类中的首选类型,就丢弃在该参数上接受非首选类型的候选项。如果没有候选项通过这些测试,则保留全部候选项。如果只剩一个候选函数,就使用它;否则继续下一步。 @@ -680,7 +680,7 @@ SELECT substr(CAST (1234 AS text), 3); -否则,尝试把表达式转换为目标类型。如果这两种类型之间在pg_cast目录中登记了赋值类型转换(见),就可以这样做。另一种情况是,如果表达式是unknown类型文字,则会把文字字符串的内容送入目标类型的输入转换例程。 +否则,尝试把表达式转换为目标类型。如果这两种类型之间在pg_cast目录中登记了赋值类型转换(见),就可以这样做。另一种情况是,如果表达式是unknown类型字面量,则会把字符串字面量的内容送入目标类型的输入转换例程。 @@ -713,7 +713,7 @@ SELECT v, octet_length(v) FROM vv; -这里实际发生的是,两个unknown类型文字默认都被解析为text,从而使||操作符被解析为text的连接操作。然后,操作符得到的text结果被转换为bpcharblank-padded char,即character数据类型的内部名称),以匹配目标列类型。(由于从textbpchar的转换是二进制可强制转换的,这一步不会插入任何真实的函数调用。)最后,系统目录中找到尺寸调整函数bpchar(bpchar, integer, boolean),并把它应用到操作符结果以及存储列长度上。这个特定于类型的函数会执行所需的长度检查并补齐填充空格。 +这里实际发生的是,两个unknown类型字面量默认都被解析为text,从而使||操作符被解析为text的连接操作。然后,操作符得到的text结果被转换为bpchar用空格填充的字符,blank-padded char,即character数据类型的内部名称),以匹配目标列类型。(由于从textbpchar的转换是二进制可强制转换的,这一步不会插入任何真实的函数调用。)最后,系统从系统目录中找到尺寸调整函数bpchar(bpchar, integer, boolean),并把它应用到操作符结果以及存储列长度上。这个特定于类型的函数会执行所需的长度检查并补齐填充空格。 @@ -770,10 +770,10 @@ SQL 的UNION结构必须让可能不同的类型彼此匹配 -如果任何输入是域类型,则在后续所有步骤中都把它当作该域的基类型。 +如果任何输入是域类型,则在后续所有步骤中都把它当作该域的基础类型。 - 这在某种程度上类似于操作符和函数对域输入的处理方式;只要用户确保所有输入都隐式或显式地正好属于该域类型,这种行为就能让域类型在UNION或类似结构中得以保留。否则,就会使用该域的基类型。 + 这在某种程度上类似于操作符和函数对域输入的处理方式;只要用户确保所有输入都隐式或显式地正好属于该域类型,这种行为就能让域类型在UNION或类似结构中得以保留。否则,就会使用该域的基础类型。 @@ -832,7 +832,7 @@ SELECT text 'a' AS "text" UNION SELECT 'b'; b (2 rows) -这里,unknown类型文字'b'会被解析为text类型。 +这里,unknown类型字面量'b'会被解析为text类型。 @@ -850,7 +850,7 @@ SELECT 1.2 AS "numeric" UNION SELECT 1; 1.2 (2 rows) -文字常量1.2的类型是numeric,而integer1可以隐式转换为numeric,因此使用该类型。 +字面量1.2的类型是numeric,而integer1可以隐式转换为numeric,因此使用该类型。 @@ -905,17 +905,17 @@ ERROR: UNION types text and integer cannot be matched -前面各节给出的规则会为 SQL 查询中的所有表达式分配非unknown的数据类型,唯一的例外是作为SELECT命令简单输出列出现的未指定类型文字常量。例如,在 +前面各节给出的规则会为 SQL 查询中的所有表达式分配非unknown的数据类型,唯一的例外是作为SELECT命令简单输出列出现的未指定类型字面量。例如,在 SELECT 'Hello World'; -中,没有任何信息能够表明这个字符串文字应该视为哪种类型。在这种情况下,PostgreSQL会退回到把该文字解析为text类型。 +中,没有任何信息能够表明这个字符串字面量应该视为哪种类型。在这种情况下,PostgreSQL会退回到把该字面量解析为text类型。 -当SELECTUNION(或INTERSECTEXCEPT)结构的一端,或者出现在INSERT ... SELECT中时,这条规则不适用,因为前面各节给出的规则具有更高优先级。在前一种情况下,未指定类型文字的类型可以从UNION的另一侧取得;在后一种情况下,则从目标列取得。 +当SELECTUNION(或INTERSECTEXCEPT)结构的一端,或者出现在INSERT ... SELECT中时,这条规则不适用,因为前面各节给出的规则具有更高优先级。在前一种情况下,未指定类型字面量的类型可以从UNION的另一侧取得;在后一种情况下,则从目标列取得。 @@ -925,7 +925,7 @@ SELECT 'Hello World'; - 在PostgreSQL 10 之前,这条规则并不存在,SELECT输出列表中的未指定类型文字会被保留为unknown类型。这会带来各种不良后果,因此后来做了修改。 + 在PostgreSQL 10 之前,这条规则并不存在,SELECT输出列表中的未指定类型字面量会被保留为unknown类型。这会带来各种不良后果,因此后来做了修改。 diff --git a/zh/17/user-manag.sgml b/zh/17/user-manag.sgml index 3eed953a..1d163869 100644 --- a/zh/17/user-manag.sgml +++ b/zh/17/user-manag.sgml @@ -312,12 +312,12 @@ ALTER TABLE bobs_table OWNER TO alice; - 一旦有价值的对象都已转移给新拥有者,被删除角色所拥有的其余对象即可使用DROP OWNED命令删除。同样,由于该命令不能访问其他数据库中的对象,因此必须在包含该角色所拥有对象的每个数据库中运行它。另外,DROP + 一旦有价值的对象都已转移给新拥有者,待删除角色所拥有的其余对象即可使用DROP OWNED命令删除。同样,由于该命令不能访问其他数据库中的对象,因此必须在包含该角色所拥有对象的每个数据库中运行它。另外,DROP OWNED不会删除整个数据库或表空间,因此如果该角色拥有任何尚未转移给新拥有者的数据库或表空间,就必须手工删除它们。 - DROP OWNED还会负责移除授予目标角色、但不属于它自身对象的任何权限。由于REASSIGN OWNED不会处理这类对象,所以通常需要同时运行REASSIGN OWNEDDROP OWNED(按这个顺序!),才能完整移除待删除角色的依赖关系。 + DROP OWNED还会负责移除目标角色在其他角色所拥有的对象上获授的所有权限。由于REASSIGN OWNED不会处理这类对象,所以通常需要同时运行REASSIGN OWNEDDROP OWNED(按这个顺序!),才能完整移除待删除角色的依赖关系。 @@ -380,15 +380,15 @@ DROP ROLE doomed_role; pg_read_all_stats - 读取所有 pg_stat_* 视图,并使用各种与统计信息相关的扩展,即使是那些通常仅对超级用户可见的扩展。 + 读取所有 pg_stat_* 视图,并使用各种与统计信息相关的扩展,包括通常仅对超级用户可见的内容。 pg_stat_scan_tables - 执行可能在表上持有ACCESS SHARE锁的监控函数,可能持续较长时间。 + 执行可能在表上持有ACCESS SHARE锁并且持续较长时间的监控函数。 pg_monitor - 读取/执行各种监控视图和函数。该角色是pg_read_all_settingspg_read_all_statspg_stat_scan_tables的成员。 + 读取或执行各种监控视图和函数。该角色是pg_read_all_settingspg_read_all_statspg_stat_scan_tables的成员。 pg_database_owner @@ -396,19 +396,19 @@ DROP ROLE doomed_role; pg_signal_backend - 向另一个后端发送信号以取消查询或终止其会话。 + 向另一个后端发送信号,以取消查询或终止其会话。 pg_read_server_files - 允许使用 COPY 和其他文件访问函数从服务器上数据库可访问的任何位置读取文件。 + 允许使用COPY和其他文件访问函数,从服务器上数据库可访问的任何位置读取文件。 pg_write_server_files - 允许使用 COPY 和其他文件访问函数向服务器上数据库可访问的任何位置写入文件。 + 允许使用COPY和其他文件访问函数,向服务器上数据库可访问的任何位置写入文件。 pg_execute_server_program - 允许使用 COPY 和其他允许执行服务器端程序的函数,以数据库运行所用用户的身份在数据库服务器上执行程序。 + 允许使用COPY和其他允许执行服务器端程序的函数,以数据库运行所用用户的身份在数据库服务器上执行程序。 pg_checkpoint @@ -431,7 +431,7 @@ DROP ROLE doomed_role;
- pg_monitorpg_read_all_settingspg_read_all_statspg_stat_scan_tables角色旨在让管理员能够方便地为监控数据库服务器配置一个角色。它们授予一组常见权限,使该角色能够读取各种有用的配置设置、统计信息以及其他通常仅限超级用户查看的系统信息。 + pg_monitorpg_read_all_settingspg_read_all_statspg_stat_scan_tables角色旨在让管理员能够方便地为监控数据库服务器配置一个角色。它们授予一组常见权限,使该角色能够读取各种有用的配置设置、统计信息以及其他通常仅限超级用户查看的系统信息。 @@ -439,15 +439,15 @@ DROP ROLE doomed_role; - pg_signal_backend角色旨在让管理员能够允许受信任但非超级用户的角色向其他后端发送信号。目前这个角色允许发送信号来取消另一个后端的查询或终止其会话。但被授予此角色的用户不能向由超级用户拥有的后端发送信号。见。 + pg_signal_backend角色旨在让管理员能够允许受信任但非超级用户的角色向其他后端发送信号。目前这个角色允许发送信号来取消另一个后端上的查询或终止其会话。不过,被授予此角色的用户不能向由超级用户拥有的后端发送信号。见 - pg_read_server_filespg_write_server_filespg_execute_server_program角色旨在允许管理员创建受信任但非超级用户的角色,使其能够以数据库运行所用用户的身份访问文件并在数据库服务器上运行程序。由于这些角色能访问服务器文件系统上的任何文件,在直接访问文件时它们会绕过所有数据库级权限检查,并且可被用来获得超级用户级别的访问能力,因此向用户授予这些角色时必须极其谨慎。 + pg_read_server_filespg_write_server_filespg_execute_server_program角色旨在让管理员能够使受信任但非超级用户的角色能够以数据库运行所用用户的身份访问文件并在数据库服务器上运行程序。由于这些角色能够访问服务器文件系统上的任意文件,它们在直接访问文件时会绕过所有数据库级权限检查,并且可被用来获得超级用户级别的访问能力,因此向用户授予这些角色时必须极其谨慎。 - 授予这些角色时应当谨慎,确保它们只在需要时使用,并理解这些角色会授予对敏感信息的访问。 + 授予这些角色时应当谨慎,确保它们只在需要时使用,并理解这些角色会授予对需要特权才能访问的信息的访问。 @@ -464,7 +464,7 @@ GRANT pg_signal_backend TO admin_user; 函数安全性 - 函数、触发器和行级安全策略允许用户把代码插入后端服务器,而其他用户可能会无意中执行这些代码。因此,这些机制使用户能够相对容易地对其他用户实施特洛伊木马攻击。最强的保护方式是严格控制谁能定义对象。如果这不可行,则应编写只引用拥有者可信对象的查询,并从search_path中移除任何允许不受信任用户创建对象的模式。 + 函数、触发器和行级安全策略允许用户把代码插入后端服务器,而其他用户可能会无意中执行这些代码。因此,这些机制使用户能够相对容易地对其他用户实施特洛伊木马攻击。最强的保护方式是严格控制谁能定义对象。如果这不可行,则应编写只引用拥有者可信的对象的查询,并从search_path中移除任何允许不受信任用户创建对象的模式。 diff --git a/zh/17/vacuumlo.sgml b/zh/17/vacuumlo.sgml index 9e80b19f..cc2c04f5 100644 --- a/zh/17/vacuumlo.sgml +++ b/zh/17/vacuumlo.sgml @@ -8,7 +8,7 @@ vacuumlo 1 - Application + 应用程序 diff --git a/zh/17/wal.sgml b/zh/17/wal.sgml index 994d2a5a..e84771c4 100644 --- a/zh/17/wal.sgml +++ b/zh/17/wal.sgml @@ -391,9 +391,9 @@ 检查点检查点 是事务序列中的一些点,在这些点上可以保证堆和索引数据文件已经用检查点之前写入 - 的全部信息进行了更新。执行检查点时,所有脏数据页都会刷写到磁盘,并向 WAL - 文件写入一条特殊的检查点记录。(更改记录此前已经刷入 WAL - 文件。)如果发生崩溃,崩溃恢复过程会查看最新的检查点记录,以确定应该从 WAL + 的全部信息进行了更新。执行检查点时,所有脏数据页都会刷盘,并向 WAL + 文件写入一条特殊的检查点记录。(更改记录此前已写入 WAL + 文件并刷盘。)如果发生崩溃,崩溃恢复过程会查看最新的检查点记录,以确定应该从 WAL 的哪个位置(称为重做记录)开始执行 REDO。该点之前对数据文件所做的任何更改 都保证已经在磁盘上。因此,检查点之后,位于包含重做记录的段之前的 WAL 段不再需要, 可以被回收或删除。(若正在执行 WAL 归档,则这些 WAL 段必 @@ -421,7 +421,7 @@ 减小 checkpoint_timeout 和/或 max_wal_size 会让检查点更频繁地发生。这样可以加快崩溃后 - 恢复,因为需要重做的工作更少。不过,这必须与更频繁刷写脏数据页所增加的成本 + 恢复,因为需要重做的工作更少。不过,这必须与更频繁地将脏数据页刷盘所增加的成本 权衡。如果设置了 (默认就是如此), 还要考虑另一个因素。为了保证数据页一致性,每个检查点之后对某个数据页的首次 修改,都会导致把整页内容写入日志。在这种情况下,更短的检查点间隔会增加输出到 @@ -448,7 +448,7 @@ I/O 速率,使检查点在给定比例的 checkpoint_timeout 秒数 经过时完成,或者在 max_wal_size 即将超出之前完成,以较早 者为准。使用默认值 0.9 时,可以预期 PostgreSQL - 会在下一次计划检查点开始前稍早完成每个检查点(大约在检查点间隔的 90% 时)。 + 会在下一次计划检查点开始前稍早完成每个检查点(耗时约为上一次检查点持续时间的 90%)。 这样能尽可能摊平 I/O,从而使检查点 I/O 负载在整个检查点间隔内保持稳定。这样 做的缺点是,延长检查点会影响恢复时间,因为需要保留更多 WAL 段以备恢复时 使用。关心恢复耗时的用户,可能希望减小 @@ -464,7 +464,7 @@ 在 Linux 和 POSIX 平台上, - 允许在检查点写出的操作系统页面达到可配置的字节数后,强制把它们刷到磁盘。 + 允许在检查点写出的操作系统页面达到可配置的字节数后,强制将它们刷盘。 否则,这些页面可能会停留在操作系统页缓存中,从而在检查点末尾发出 fsync 时引发停顿。这个设置通常有助于降低事务延迟,但也可能 对性能产生不利影响,尤其是在工作负载大于 @@ -502,7 +502,7 @@ 在归档恢复或备库模式下,服务器会周期性地执行 重启点重启点, - 其行为类似于正常运行时的检查点:服务器会强制把自身状态写盘,更新 + 其行为类似于正常运行时的检查点:服务器会强制将其所有状态刷盘,更新 pg_control 文件,以表明已经处理过的 WAL 数据无需再次 扫描,然后回收 pg_wal 目录中的旧 WAL 段文件。重启点的 执行频率不会高于主库上的检查点,因为重启点只能在检查点记录处执行。重启点既 @@ -524,9 +524,9 @@ - 在某些情况下,例如发生大规模 INSERT 时,主库上的 WAL 大小 + 在某些情况下,例如发生大规模 INSERT 时,主库上的 WAL 大小 会快速增长,此时备库端的 restartpoints_req 计数器 - 可能会出现突增。这是因为,虽然由于 WAL 消耗增加而提出了创建新重启点的请求, + 可能会出现突增。这是因为,虽然由于 XLOG 消耗增加而提出了创建新重启点的请求, 但自上一次重启点以来可安全使用的检查点记录尚未在备库端重放,所以这些请求无法 执行。这种行为是正常的,不会导致系统资源消耗增加。在与重启点相关的计数器中, 只有 restartpoints_done 才表明确实消耗了明显的 @@ -545,7 +545,7 @@ 快。更糟的是,写 WAL 缓冲区还可能迫使系统创建新的 WAL 段, 这会花费更多时间。正常情况下,WAL 缓冲区应由 XLogFlush 请求负责写出并刷盘; - 该请求大多发生在事务提交时,以确保事务记录被刷入持久存储。在 WAL 输出量很高 + 该请求大多发生在事务提交时,以确保事务记录已刷盘至持久存储。在 WAL 输出量很高 的系统上,XLogFlush 请求可能不够频繁,无法避免 XLogInsertRecord 自己去执行写出。在这种系统上,应增加 WAL 缓冲区的数量,具体做法是修改参数 @@ -558,7 +558,7 @@ 参数 定义了组提交的领导者进程在 XLogFlush 内部获取锁之后会睡眠多少微秒,在此期间,组提 交的追随者会排队跟在领导者后面。这一延迟允许其他服务器进程把自己的提交记录添 - 加到 WAL 缓冲区中,以便它们都能由领导者最终执行的同步操作一并刷出。如果没有 + 加到 WAL 缓冲区中,以便它们都能由领导者最终执行的同步操作一并刷盘。如果没有 启用 ,或者当前处于活跃事务中的其他会话少于 个,就不会发生睡眠;这样可以避免在其他 会话不太可能很快提交时还去睡眠。请注意,在某些平台上,休眠请求的分辨率是 @@ -587,8 +587,7 @@ commit_delay 设为 0(默认值)时,仍然可能出现一种组 - 提交,但每个组只会包含那些恰好在前一次刷盘操作(若有)进行期间,到达“需要刷 - 出其提交记录”这一点的会话。客户端数量更高时,往往会出现一种 + 提交,但每个组只会包含那些恰好在前一次刷盘操作(若有)进行期间,到达“需要将其提交记录刷盘”这一点的会话。客户端数量更高时,往往会出现一种 gangway effect,以至于即使 commit_delay 为 0,组提交的效果也会变得很显著,因此显式设置 commit_delay 的帮助反而会变小。只有在以下两种条件同时 @@ -601,9 +600,9 @@ 参数 决定 PostgreSQL 将如何请求内核把 - WAL 更新强制刷到磁盘。就可靠性而言,所有选项应当都是相同 + WAL 更新强制刷盘。就可靠性而言,所有选项应当都是相同 的;例外是 fsync_writethrough,它有时能够在其他选项做不 - 到时强制刷新磁盘缓存。不过,具体哪个选项速度最快则高度依赖平台。可以使用 + 到时强制将磁盘缓存中的数据刷盘。不过,具体哪个选项速度最快则高度依赖平台。可以使用 程序测试不同选项的速度。请注意,如果 fsync 已被关闭,那么这个参数就没有意义。 @@ -617,14 +616,13 @@ - 有两个内部函数负责把 WAL 数据写入磁盘: - XLogWriteissue_xlog_fsync。 - 启用 后, - XLogWrite 写 WAL 数据以及 - issue_xlog_fsync 将 WAL 数据同步到磁盘所花费的总时间, - 会分别统计为 wal_write_timewal_sync_time, - 记录在 中 - objectwal 的项下。 + 有两个内部函数负责把 WAL 数据写入磁盘: + XLogWriteissue_xlog_fsync。 + 启用 后, + XLogWrite 写 WAL 数据以及 + issue_xlog_fsync 将 WAL 数据同步到磁盘所花费的总时间, + 会分别统计为 wal_write_timewal_sync_time, + 并分别记录在 中。 XLogWrite 通常由 XLogInsertRecord (当 WAL 缓冲区没有空间容纳新记录时)、XLogFlush 以及 WAL 写入器调用,用于把 WAL 缓冲区写到磁盘并调用 @@ -636,15 +634,14 @@ issue_xlog_fsync 什么也不做。如果 wal_sync_methodfdatasyncfsyncfsync_writethrough, - 那么写操作会把 WAL 缓冲区移入内核缓存,而 - issue_xlog_fsync 会把它们同步到磁盘。无论 - track_wal_io_timing 是否开启, - XLogWrite 写 WAL 数据的次数和 - issue_xlog_fsync 同步 WAL 数据到磁盘的次数,也会分别统计 - 为 wal_writewal_sync,记录在 - pg_stat_ioobject 为 - wal 的项下。 - + 那么写操作会把 WAL 缓冲区移入内核缓存,而 + issue_xlog_fsync 会把它们同步到磁盘。无论 + track_wal_io_timing 是否开启, + XLogWrite 写 WAL 数据的次数和 + issue_xlog_fsync 同步 WAL 数据到磁盘的次数,也会分别统计 + 为 wal_writewal_sync,分别记录在 + pg_stat_wal 中。 + 参数 可用于在恢复期间降低 I/O 等待 diff --git a/zh/17/xaggr.sgml b/zh/17/xaggr.sgml index b46b119e..d7ef45aa 100644 --- a/zh/17/xaggr.sgml +++ b/zh/17/xaggr.sgml @@ -43,11 +43,11 @@ SELECT sum(a) FROM test_complex; - 如果没有非空输入值,上述sum定义将返回零(即初始状态值)。也许我们更希望在这种情况下返回空值 — SQL 标准要求sum这样做。实现这一点只需省略initcond短语,使初始状态值为空。通常这意味着sfunc需要检查输入的状态值是否为空。但对于sum以及maxmin这类其他简单聚合,只需把第一个非空输入值放入状态变量,然后从第二个非空输入值开始应用转移函数即可。如果初始状态值为空,并且转移函数被标记为strict(即不会对空输入调用),PostgreSQL会自动这样做。 + 如果没有非空输入值,上述sum定义将返回零(即初始状态值)。也许我们更希望在这种情况下返回空值 — SQL 标准要求sum这样做。实现这一点只需省略initcond短语,使初始状态值为空值。通常这意味着sfunc需要检查输入的状态值是否为空值。但对于sum以及maxmin这类其他简单聚合,只需把第一个非空输入值放入状态变量,然后从第二个非空输入值开始应用转移函数即可。如果初始状态值为空值,并且转移函数被标记为strict(即不会对空值输入调用),PostgreSQL会自动这样做。 - strict转移函数的另一项默认行为是,只要遇到空输入值,就会保留先前的状态值不变。因此,空值会被忽略。如果你需要对空输入采用其他行为,就不要把转移函数声明为 strict,而应在函数代码中自行检测空输入并完成所需处理。 + strict转移函数的另一项默认行为是,只要遇到空值输入,就会保留先前的状态值不变。因此,空值会被忽略。如果你需要对空值输入采用其他行为,就不要把转移函数声明为 strict,而应在函数代码中自行检测空值输入并完成所需处理。 @@ -72,7 +72,7 @@ CREATE AGGREGATE avg (float8) - SQL 中的聚合函数调用允许使用DISTINCTORDER BY选项,以控制哪些行会传递给聚合的转移函数,以及传递顺序。这些选项是在后台实现的,并不是聚合支持函数需要关心的事情。 + SQL 中的聚合函数调用允许使用DISTINCTORDER BY选项,以控制哪些行会传递给聚合的转移函数,以及传递顺序。这些选项由系统在内部实现,并不是聚合支持函数需要关心的事情。 @@ -292,7 +292,7 @@ SELECT percentile_disc(0.5) WITHIN GROUP (ORDER BY income) FROM households; - 与普通聚合不同,有序集聚合的输入行排序不是在幕后完成的,而是由聚合的支持函数负责。典型的实现方法是在聚合的状态值中保存一个tuplesort对象的引用,把输入行送入该对象,然后在最终函数中完成排序并读出数据。这样的设计使最终函数可以执行特殊操作,例如向待排序数据中注入额外的假想行。普通聚合通常可以使用由PL/pgSQL或其他 PL 语言编写的支持函数来实现,但有序集聚合通常必须用 C 编写,因为它们的状态值无法定义为任何 SQL 数据类型。(在上面的示例中,注意状态值被声明为internal类型,这很典型。)另外,由于最终函数执行了排序,之后就不可能再通过再次执行转移函数来继续加入输入行。这意味着最终函数不是READ_ONLY;在CREATE AGGREGATE中,必须将其声明为READ_WRITE,或者如果额外的最终函数调用能够利用已经排好序的状态,则声明为SHAREABLE。 + 与普通聚合不同,有序集聚合的输入行排序不是由系统在内部完成的,而是由聚合的支持函数负责。典型的实现方法是在聚合的状态值中保存一个tuplesort对象的引用,把输入行送入该对象,然后在最终函数中完成排序并读出数据。这样的设计使最终函数可以执行特殊操作,例如向待排序数据中注入额外的假想行。普通聚合通常可以使用由PL/pgSQL或其他 PL 语言编写的支持函数来实现,但有序集聚合通常必须用 C 编写,因为它们的状态值无法定义为任何 SQL 数据类型。(在上面的示例中,注意状态值被声明为internal类型,这很典型。)另外,由于最终函数执行了排序,之后就不可能再通过再次执行转移函数来继续加入输入行。这意味着最终函数不是READ_ONLY;在CREATE AGGREGATE中,必须将其声明为READ_WRITE,或者如果额外的最终函数调用能够利用已经排好序的状态,则声明为SHAREABLE @@ -366,7 +366,7 @@ if (AggCheckCallContext(fcinfo, NULL)) - AggCheckCallContext的第二个参数可用于取得保存聚合状态值的内存上下文。这对于希望把扩展对象(见)用作状态值的转移函数很有用。第一次调用时,转移函数应返回一个扩展对象,其内存上下文是聚合状态上下文的子上下文;之后的调用则持续返回同一个扩展对象。示例见array_append()。(array_append()并不是任何内置聚合的转移函数,但它的写法保证了在用作自定义聚合的转移函数时也能高效工作。) + AggCheckCallContext的第二个参数可用于取得保存聚合状态值的内存上下文。这对于希望把展开对象(见)用作状态值的转移函数很有用。第一次调用时,转移函数应返回一个展开对象,其内存上下文是聚合状态上下文的子上下文;之后的调用则持续返回同一个展开对象。示例见array_append()。(array_append()并不是任何内置聚合的转移函数,但它的写法保证了在用作自定义聚合的转移函数时也能高效工作。) diff --git a/zh/17/xfunc.sgml b/zh/17/xfunc.sgml index 878438e5..4f814eeb 100644 --- a/zh/17/xfunc.sgml +++ b/zh/17/xfunc.sgml @@ -4,8 +4,8 @@ 用户定义的函数 - function - user-defined + 函数 + 用户定义的 @@ -36,15 +36,15 @@ - 每一类函数可以采用基本类型、复合类型或者它们的组合作为参数。此外,每一类函数可以返回一个基本类型或一个复合类型。函数也能被定义成返回基本类型或复合类型值的集合。 + 每一类函数可以采用基础类型、复合类型或者它们的组合作为参数。此外,每一类函数可以返回一个基础类型或一个复合类型。函数也能被定义成返回基础类型或复合类型值的集合。 - 很多类函数可以接受或者返回特定的伪类型(例如,多态类型),但是可用的功能会变化。详情可以参考每一种函数的描述。 + 很多类函数可以接受或者返回特定的伪类型(例如,多态类型),但是可用的功能因函数类别而异。详情可以参考每一种函数的描述。 - 定义SQL函数最容易,因此我们将从讨论SQL函数开始。大部分SQL函数的概念也能用到其他类型的函数上。 + 定义SQL函数最容易,因此我们将从讨论它们开始。大部分SQL函数的概念也能用到其他类型的函数上。 @@ -57,8 +57,8 @@ 用户定义的过程 - procedure - user-defined + 过程 + 用户定义的 @@ -101,7 +101,7 @@ - 函数和过程一起构成了例程routine。 + 函数和过程统称为例程例程。 有ALTER ROUTINEDROP ROUTINE这样的命令可以操作函数和过程而不需要知道它们是哪一种。 不过,要注意没有CREATE ROUTINE命令。 @@ -113,7 +113,7 @@ 函数 用户定义的 - in SQL + 在 SQL 中 @@ -139,7 +139,7 @@ DELETEMERGE),以及其他 SQL 命令。(在 SQL 函数中不能使用事务控制命令,例如 COMMITSAVEPOINT,也不能使用某些 - 实用命令,例如 VACUUM。)不过,最后一条命令必须是 + 工具命令,例如 VACUUM。)不过,最后一条命令必须是 SELECT,或者带有 RETURNING 子句,并返回与函数声明返回类型相符的结果。或者,如果你想定义一个执行动作 但没有有用返回值的 SQL 函数,也可以把它定义为返回 void。 @@ -171,7 +171,7 @@ CREATE PROCEDURE clean_emp() AS ' CALL clean_emp(); - 在像这样的简单情况中,函数与过程返回void的差异主要是风格上面的。 + 在像这样的简单情况中,返回void的函数与过程之间的差异主要是风格上面的。 不过,过程还提供了函数所没有的额外能力,例如事务控制。 此外,过程是 SQL 标准的一部分,而返回void则是 PostgreSQL 扩展。 @@ -238,10 +238,10 @@ INSERT INTO $1 VALUES (42); - 基本类型上的<acronym>SQL</acronym>函数 + 基础类型上的<acronym>SQL</acronym>函数 - 最简单的 SQL 函数没有参数,只是返回一个基本类型,例如 + 最简单的 SQL 函数没有参数,只是返回一个基础类型,例如 integer @@ -267,7 +267,7 @@ SELECT one(); - 定义接受基本类型参数的 SQL 函数也几乎同样容易: + 定义接受基础类型参数的 SQL 函数也几乎同样容易: CREATE FUNCTION add_em(x integer, y integer) RETURNS integer AS $$ @@ -405,17 +405,17 @@ SELECT name, double_salary(emp.*) AS dream 注意这里用 $1.salary 语法来选取参数行值中的一个字段。 还要注意,调用时的 SELECT 命令使用 - table_name.* 将表的当前整行取作一个组合值。该表行也可以仅用表名来引用: + table_name.* 将表的当前整行取作一个复合值。该表行也可以仅用表名来引用: SELECT name, double_salary(emp) AS dream FROM emp WHERE emp.cubicle ~= point '(2,1)'; - 但这种用法已被废弃,因为它很容易让人混淆(关于表行组合值这两种记法的更多细节,见)。 + 但这种用法已被弃用,因为它很容易让人混淆(关于表行复合值这两种记法的更多细节,见)。 - 有时候即时构造一个组合参数会很方便。这可以用ROW构造器完成。 + 有时候即时构造一个复合参数值会很方便。这可以用ROW构造器完成。 例如,我们可以调整被传递给函数的数据: SELECT name, double_salary(ROW(name, salary*1.1, age, cubicle)) AS dream @@ -444,7 +444,7 @@ $$ LANGUAGE SQL; - 查询中的选择列表顺序必须与列在复合类型中出现的顺序完全相同。(正如我们上面所做的那样,命名列与系统无关。) + 查询中的选择列表顺序必须与列在复合类型中出现的顺序完全相同。(系统不考虑像上面这样指定的列名。) @@ -456,7 +456,7 @@ ERROR: return type mismatch in function declared to return emp DETAIL: Final statement returns text instead of point at column 4. - 与基本类型的情况一样,系统不会自动插入显式转换,只会插入隐式或赋值转换。 + 与基础类型的情况一样,系统不会自动插入显式转换,只会插入隐式或赋值转换。 @@ -473,7 +473,7 @@ $$ LANGUAGE SQL; 这里我们写了一个只返回单列、且该列具有正确复合类型的 SELECT。 在这种场景下,这样写并不见得更好,但在某些情况下会很方便 - — 例如,需要通过调用另一个返回目标组合值的函数来计算结果时。 + — 例如,需要通过调用另一个返回目标复合值的函数来计算结果时。 还有一种情况是,如果我们要编写的函数返回的是基于复合类型的域,而不是普通复合类型, 那么就必须写成返回单列的形式,因为没有办法让整行结果发生所需的强制转换。 @@ -538,7 +538,7 @@ SELECT name(new_emp()); - 另一种使用函数返回复合类型的方法是将结果传递给另一个接受正确行类型作为输入的函数: + 另一种使用函数返回复合类型的方法是将结果传递给另一个接受正确行类型作为输入的函数: CREATE FUNCTION getname(emp) RETURNS text AS $$ @@ -626,7 +626,7 @@ DROP FUNCTION sum_n_product (int, int); <acronym>SQL</acronym>有输出参数的过程 - procedures + 过程 输出参数 @@ -648,7 +648,7 @@ $$ LANGUAGE SQL; CALL tp1(17, 100.0, NULL); 如果你写的是其他内容,它必须是一个能够像输入参数那样被隐式强制转换成该参数声明类型的表达式。 - 注意,无论如何这样的表达式不会被评估。 + 不过要注意,这样的表达式不会被求值。 @@ -660,12 +660,12 @@ CALL tp1(17, 100.0, NULL); 带有可变数量参数的<acronym>SQL</acronym>函数 - function - variadic + 函数 + 可变参数 - variadic function + 可变参数函数 @@ -696,27 +696,27 @@ SELECT mleast(ARRAY[10, -1, 5, 4.4]); -- doesn't work - 有时候,能够把一个已经构造好的数组传给 variadic 函数会很有用,尤其是当一个 variadic 函数想把它的数组参数再传给另一个函数时。此外,在允许不受信任用户创建对象的模式中调用 variadic 函数时,这是唯一安全的方式,见。你可以在调用中指定VARIADIC来做到这一点: + 有时候,能够把一个已经构造好的数组传给可变参数函数会很有用,尤其是当一个可变参数函数想把它的数组参数再传给另一个函数时。此外,在允许不受信任用户创建对象的模式中调用可变参数函数时,这是唯一安全的方式,见。你可以在调用中指定VARIADIC来做到这一点: SELECT mleast(VARIADIC ARRAY[10, -1, 5, 4.4]); - 这样会阻止函数的 variadic 参数按其元素类型展开,从而让数组实参能够按常规方式匹配。VARIADIC 只能附加在函数调用的最后一个实参上。 + 这样会阻止函数的可变参数按其元素类型展开,从而让数组实参能够按常规方式匹配。VARIADIC 只能附加在函数调用的最后一个实参上。 - 在调用中指定VARIADIC也是向 variadic 函数传递空数组的唯一方式,例如: + 在调用中指定VARIADIC也是向可变参数函数传递空数组的唯一方式,例如: SELECT mleast(VARIADIC ARRAY[]::numeric[]); - 仅仅写成SELECT mleast()是行不通的,因为 variadic 参数必须匹配至少一个实参。(如果你希望允许这种调用,可以再定义一个同名且不带参数的函数mleast。) + 仅仅写成SELECT mleast()是行不通的,因为可变参数必须匹配至少一个实参。(如果你希望允许这种调用,可以再定义一个同名且不带参数的函数mleast。) - 从 variadic 参数派生出的数组元素参数会被视为没有自己的名字。这意味着除非你指定了 VARIADIC,否则不能使用命名参数来调用 variadic 函数()。例如,下面的调用是可行的: + 从可变参数派生出的数组元素参数会被视为没有自己的名字。这意味着除非你指定了 VARIADIC,否则不能使用命名参数来调用可变参数函数()。例如,下面的调用是可行的: SELECT mleast(VARIADIC arr => ARRAY[10, -1, 5, 4.4]); @@ -735,7 +735,7 @@ SELECT mleast(arr => ARRAY[10, -1, 5, 4.4]); 带有参数默认值的<acronym>SQL</acronym>函数 - function + 函数 参数的默认值 @@ -744,7 +744,7 @@ SELECT mleast(arr => ARRAY[10, -1, 5, 4.4]); 没有给出足够多的实参,就会插入默认值来弥补缺失的实参。由于参数只 能从实参列表的尾部开始被省略,在一个有默认值的参数之后的所有参数 都不得不也具有默认值(尽管使用命名参数记法可以允许放松这种限制, - 这种限制仍然会被强制以便位置参数记法能工作)。不管你是否使用它,这种能力都要求在某些用户不信任其他用户的数据中调用函数时做一些预防措施,见。 + 这种限制仍然会被强制以便位置参数记法能工作)。不管你是否使用它,这种能力都要求在某些用户不信任其他用户的数据库中调用函数时做一些预防措施,见 @@ -787,13 +787,13 @@ ERROR: function foo() does not exist 所有的 SQL 函数都可以被用在查询的FROM子句中,但是 - 对于返回复合类型的函数特别有用。如果函数被定义为返回一种基本类型, + 对于返回复合类型的函数特别有用。如果函数被定义为返回一种基础类型, 该表函数会产生一个单列表。如果该函数被定义为返回一种复合类型,该 表函数会为该复合类型的每一个属性产生一列。 - 以下是一个示例: + 以下是一个示例: CREATE TABLE foo (fooid int, foosubid int, fooname text); @@ -826,8 +826,8 @@ SELECT *, upper(fooname) FROM getfoo(1) AS t1; 返回集合的<acronym>SQL</acronym>函数 - function - with SETOF + 函数 + 使用 SETOF @@ -960,7 +960,7 @@ SELECT x, generate_series(1,5) AS g FROM tab; SELECT x, g FROM tab, LATERAL generate_series(1,5) AS g; - 这会是完全一样的,除了在这个特别的示例中,规划器会选择把g放在嵌套循环连接的外侧,因为gtab没有实际的横向依赖。那会导致一种不同的输出行顺序。选择列表中的集合返回函数总是会被计算,就好像它们在FROM子句剩余部分的嵌套循环连接的内侧一样,因此在考虑来自FROM子句的下一行之前,这些函数会运行到完成。 + 这会是完全一样的,除了在这个特别的示例中,规划器可以选择把g放在嵌套循环连接的外侧,因为gtab没有实际的横向依赖。那会导致一种不同的输出行顺序。选择列表中的集合返回函数总是会被计算,就好像它们在FROM子句剩余部分的嵌套循环连接的内侧一样,因此在考虑来自FROM子句的下一行之前,这些函数会运行到完成。 @@ -980,7 +980,7 @@ SELECT srf1(srf2(x), srf3(y)), srf4(srf5(z)) FROM tab; SELECT x, CASE WHEN x > 0 THEN generate_series(1, 5) ELSE 0 END FROM tab; - 看起来这个语句应该产生满足x > 0的输入行的五次重复,以及不满足的行的一次重复。但实际上,由于在CASE表达时被计算前,generate_series(1, 5)会被运行在一个隐式的LATERAL FROM项中,它会为每个输入行产生五次重复。为了减少混乱,这类情况会产生一个解析时错误。 + 看起来这个语句应该产生满足x > 0的输入行的五次重复,以及不满足的行的一次重复。但实际上,由于在CASE表达式被计算前,generate_series(1, 5)会被运行在一个隐式的LATERAL FROM项中,它会为每个输入行产生五次重复。为了减少混乱,这类情况会产生一个解析时错误。 @@ -996,11 +996,11 @@ SELECT x, CASE WHEN x > 0 THEN generate_series(1, 5) ELSE 0 END FROM tab; 在 PostgreSQL 10 之前,除非多个集合返回函数始终产生相同数量的行,否则把它们放在同一个选择列表中的行为并不合理。 否则,得到的输出行数会是这些集合返回函数各自产生行数的最小公倍数。 此外,嵌套的集合返回函数也不像上文所描述的那样工作;相反,一个集合返回函数至多只能有一个集合返回参数, - 并且每一层嵌套都会独立运行。再加上过去还允许条件执行(即在 CASE 等结构内部使用集合返回函数), + 并且每一组嵌套的集合返回函数都会独立运行。再加上过去还允许条件执行(即在 CASE 等结构内部使用集合返回函数), 事情就更加复杂了。 如果你要编写需要在旧版 PostgreSQL 上运行的查询,建议使用 LATERAL 语法, 因为这样在不同版本之间能够得到一致的结果。 - 如果你的查询依赖于集合返回函数的条件执行,可以把条件判断移动到自定义集合返回函数内部来修复。例如, + 如果你的查询依赖于集合返回函数的条件执行,或许可以把条件判断移动到自定义集合返回函数内部来修复。例如, SELECT x, CASE WHEN y > 0 THEN generate_series(1, z) ELSE 5 END FROM tab; @@ -1018,7 +1018,7 @@ END$$ LANGUAGE plpgsql; SELECT x, case_generate_series(y > 0, 1, z, 5) FROM tab; - 这种写法在所有版本的 PostgreSQL 中都能正常工作。 + 这种写法在所有版本的 PostgreSQL 中的行为都相同。 @@ -1027,7 +1027,7 @@ SELECT x, case_generate_series(y > 0, 1, z, 5) FROM tab; 返回<literal>TABLE</literal>的<acronym>SQL</acronym>函数 - function + 函数 RETURNS TABLE @@ -1076,10 +1076,9 @@ SELECT make_array(1, 2) AS intarray, make_array('a'::text, 'b') AS textarray; 注意类型转换'a'::text的使用是为了指定该参数的类型 - 是text。如果该参数只是一个字符串这就是必须的,因为 + 是text。如果该参数只是一个字符串字面量,这就是必须的,因为 否则它会被当作unknown类型,并且 - unknown的数组也不是一种合法的类型。如果没有改类型 - 类型转换,将得到这样的错误: + unknown的数组也不是一种合法的类型。如果没有该类型转换,将得到这样的错误: ERROR: could not determine polymorphic type because input has type unknown @@ -1150,7 +1149,7 @@ SELECT * FROM dup(22); - 多态也可以用于 variadic 函数。例如: + 多态也可以用于可变参数函数。例如: CREATE FUNCTION anyleast (VARIADIC anyarray) RETURNS anyelement AS $$ SELECT min($1[i]) FROM generate_subscripts($1, 1) g(i); @@ -1185,14 +1184,14 @@ SELECT concat_values('|', 1, 4, 2); 带有排序规则的<acronym>SQL</acronym>函数 - collation - in SQL functions + 排序规则 + 在 SQL 函数中 - 当一个 SQL 函数有一个或多个可设定排序规则的数据类型参数时,会按 - 中的说明,为每次函数调用确定一个排序规则。 - 如果能够成功确定(也就是说,参数之间不存在隐式排序规则冲突),那么所有可设定排序规则的参数都会被视为隐式带有该排序规则。 + 当一个 SQL 函数有一个或多个支持排序规则的数据类型参数时,会按 + 中的说明,根据分配给实参的排序规则,为每次函数调用确定一个排序规则。 + 如果能够成功确定(也就是说,参数之间不存在隐式排序规则冲突),那么所有支持排序规则的参数都会被视为隐式带有该排序规则。 这会影响函数中对排序规则敏感的操作的行为。例如,使用上文的 anyleast 函数时, SELECT anyleast('abc'::text, 'ABC'); @@ -1212,7 +1211,7 @@ CREATE FUNCTION anyleast (VARIADIC anyarray) RETURNS anyelement AS $$ SELECT min($1[i] COLLATE "en_US") FROM generate_subscripts($1, 1) g(i); $$ LANGUAGE SQL; - 但请注意,如果把它用于不可设定排序规则的数据类型,就会抛出错误。 + 但请注意,如果把它用于不支持排序规则的数据类型,就会抛出错误。 @@ -1221,7 +1220,7 @@ $$ LANGUAGE SQL; - 这种可设定排序规则参数的行为,可以看作是仅适用于文本数据类型的一种受限多态形式。 + 这种支持排序规则的参数的行为,可以看作是仅适用于文本数据类型的一种受限多态形式。 @@ -1230,13 +1229,13 @@ $$ LANGUAGE SQL; 函数重载 - overloading - functions + 重载 + 函数 可以用同样的 SQL 名称定义多于一个函数,只要它们的参数不同即可。 - 换句话说,函数名可以被重载。不管你是否使用它,这种能力都要求在某些用户不信任其他用户的数据中调用函数时做一些预防措施,见。当一个查询 + 换句话说,函数名可以被重载。不管你是否使用它,这种能力都要求在某些用户不信任其他用户的数据库中调用函数时采取安全预防措施,见。当一个查询 被执行时,服务器将从数据类型和所提供的参数个数来决定要调用哪个 函数。重载也可用来模拟具有可变参数个数(最大个数有限)的函数。 @@ -1263,10 +1262,10 @@ CREATE FUNCTION test(smallint, double precision) RETURNS ... - 另一类可能的冲突发生在 variadic 函数和非 variadic 函数之间。例如,可以同时创建 + 另一类可能的冲突发生在可变参数函数和非可变参数函数之间。例如,可以同时创建 foo(numeric)foo(VARIADIC numeric[])。 这时,对于只提供一个 numeric 参数的调用(例如 foo(10.1)),就不清楚该匹配哪个函数。 - 规则是:优先使用在搜索路径中出现较早的那个函数;如果两者位于同一模式中,则优先使用非 variadic 函数。 + 规则是:优先使用在搜索路径中出现较早的那个函数;如果两者位于同一模式中,则优先使用非可变参数函数。 @@ -1293,8 +1292,8 @@ CREATE FUNCTION test(int, int) RETURNS int 函数易变性分类 - volatility - functions + 易变性 + 函数 VOLATILE @@ -1316,7 +1315,7 @@ CREATE FUNCTION test(int, int) RETURNS int 一个VOLATILE函数可以做任何事情,包括修改数据库。在 使用相同的参数连续调用时,它能返回不同的结果。优化器不会对这类函 - 数的行为做任何假定。对于在每一行都需要 volatile 函数值的查询,函数都会被重新求值。 + 数的行为做任何假定。使用易变函数的查询会在需要该函数值的每一行上重新对它求值。 @@ -1364,8 +1363,7 @@ CREATE FUNCTION test(int, int) RETURNS int 在考虑先规划然后立即执行的简单交互式查询时,在STABLEIMMUTABLE分类间的区别相对较小:一个函数是在规划时只 执行一次还是在查询执行开始期间只执行一次没有太大关系。但是如果计划 - 被保存下来然后在后面被重用,区别就大了。如果在不允许过早把一个函数 - 变成规划期间的一个常数时把它标记为IMMUTABLE,会导致 + 被保存下来然后在后面被重用,区别就大了。如果把一个实际上并非不可变的函数标记为IMMUTABLE,就可能在规划期间过早将它折叠成常量,导致 在后续重用该计划时继续使用陈旧的值。在使用预备语句,或使用会缓存执行计划的函数语言(如 PL/pgSQL)时,这会带来严重问题。 @@ -1433,7 +1431,7 @@ CREATE FUNCTION test(int, int) RETURNS int 内部函数 - functioninternal + 函数内部 内部函数由 C 编写并且已经被静态链接到PostgreSQL @@ -1471,9 +1469,9 @@ CREATE FUNCTION square_root(double precision) RETURNS double precision C 语言函数 - function - user-defined - in C + 函数 + 用户定义的 + 在 C 中 @@ -1497,17 +1495,17 @@ CREATE FUNCTION square_root(double precision) RETURNS double precision - 在一个会话中第一次调用一个特定可载入对象文件中的用户定义函数时, - 动态载入器会把那个对象文件载入到内存以便该函数被调用。因此用户 + 在一个会话中第一次调用一个特定可载入目标文件中的用户定义函数时, + 动态载入器会把那个目标文件载入到内存以便该函数被调用。因此用户 定义的 C 函数的CREATE FUNCTION必须 - 为该函数指定两块信息:可载入对象文件的名称,以及要在该对象文件中 + 为该函数指定两块信息:可载入目标文件的名称,以及要在该目标文件中 调用的特定函数的 C 名称(链接符号)。如果没有显式指定 C 名称,则 它被假定为和 SQL 函数名相同。 下面的算法被用来基于CREATE FUNCTION - 命令中给定的名称来定位共享对象文件: + 命令中给定的名称来定位共享目标文件: @@ -1566,17 +1564,17 @@ CREATE FUNCTION square_root(double precision) RETURNS double precision PostgreSQL不会自动编译 C 函数。在 - 从CREATE FUNCTION命令中引用对象文件 + 从CREATE FUNCTION命令中引用目标文件 之前,它必须先被编译好。更多信息请见 - magic block + 魔数块 - 为确保动态装载的对象文件不会被加载到不兼容的服务器中,PostgreSQL 会检查该文件是否包含内容正确的magic block。这样服务器就能检测出明显的不兼容情况,例如代码是针对另一个 PostgreSQL 主版本编译的。要加入 magic block,请在模块某一个(且只能一个)源文件中,在包含头文件 fmgr.h 之后写入: + 为确保动态装载的目标文件不会被加载到不兼容的服务器中,PostgreSQL 会检查该文件是否包含内容正确的魔数块。这样服务器就能检测出明显的不兼容情况,例如代码是针对另一个 PostgreSQL 主版本编译的。要加入魔数块,请在模块某一个(且只能一个)源文件中,在包含头文件 fmgr.h 之后写入: PG_MODULE_MAGIC; @@ -1584,9 +1582,9 @@ PG_MODULE_MAGIC; - 在第一次使用之后,动态载入对象文件会保留在内存中。在同一个会话中, + 在第一次使用之后,动态载入目标文件会保留在内存中。在同一个会话中, 后续对该文件中函数的调用只需付出一次很小的符号表查找开销。如果需要 - 强制重新载入一个对象文件(例如在重新编译之后),就需要开启一个新的会话。 + 强制重新载入一个目标文件(例如在重新编译之后),就需要开启一个新的会话。 @@ -1605,7 +1603,7 @@ PG_MODULE_MAGIC; - C 语言函数中的基本类型 + C 语言函数中的基础类型 数据类型 @@ -1614,16 +1612,16 @@ PG_MODULE_MAGIC; 要了解如何编写 C 语言函数,你需要了解 - PostgreSQL如何在内部表达基本数据类型 + PostgreSQL如何在内部表达基础类型 以及如何与函数传递它们。在内部, - PostgreSQL把基本类型视为一块内存数据块。 + PostgreSQL把基础类型视为一块内存数据块。 你为该类型定义的用户自定义函数,决定了 PostgreSQL 如何操作它。 也就是说,PostgreSQL 只负责把数据存到磁盘、再从磁盘取回, 而数据的输入、处理和输出则依赖你定义的这些函数。 - 基本类型可以有三种内部格式之一: + 基础类型可以有三种内部格式之一: @@ -1688,10 +1686,9 @@ typedef struct 最后,所有变长类型必须也以引用的方式传递。所有变长类型必须用一个 - 正好 4 字节的不透明长度域开始,该域会由SET_VARSIZE - 设置,绝不要直接设置该域!所有要被存储在该类型中的数据必须在内存 - 中接着该长度域的后面存储。长度域包含该结构体的总长度,也就是包括长 - 度域本身的尺寸。 + 正好 4 字节的不透明长度字段开始,该字段会由SET_VARSIZE + 设置,绝不要直接设置该字段!所有要被存储在该类型中的数据必须在内存 + 中接着该长度字段的后面存储。长度字段包含该结构体的总长度,也就是包括长度字段本身的尺寸。 @@ -1741,16 +1738,16 @@ memcpy(destination->data, buffer, 40); VARHDRSZsizeof(int32)一样, - 但是用宏VARHDRSZ来引用变长类型的载荷的 + 但是用宏VARHDRSZ来引用变长类型的额外开销的 尺寸被认为是比较好的风格。还有,必须 - 使用SET_VARSIZE宏来设置长度域,而不是用 + 使用SET_VARSIZE宏来设置长度字段,而不是用 简单的赋值来设置。 展示了 PostgreSQL 中许多内置 SQL 数据类型所对应的 C 类型。 - Defined In列给出了需要包含的头文件,以获取类型定义。 + 定义文件列给出了需要包含的头文件,以获取类型定义。 (实际的定义可能位于所列文件包含的其他文件中。建议用户坚持使用已定义的接口。) 请注意,在服务器代码的任何源文件中,都应该始终首先包含postgres.h, 因为它声明了很多你反正都会用到的内容,而且先包含其他头文件可能会带来可移植性问题。 @@ -1926,8 +1923,7 @@ memcpy(destination->data, buffer, 40); - 现在我们已经复习了基本类型所有可能的结构,现在可以展示一些 - 真实函数的示例了。 + 了解了基础类型所有可能的结构后,就可以看一些实际函数示例。 @@ -1935,7 +1931,7 @@ memcpy(destination->data, buffer, 40); 版本 1 的调用约定 - 版本-1 的调用规范依赖于宏来降低传参数和结果的复杂度。版本-1 函数的 + 版本-1 的调用约定依赖于宏来降低传参数和结果的复杂度。版本-1 函数的 C 声明总是: Datum funcname(PG_FUNCTION_ARGS) @@ -1947,11 +1943,11 @@ PG_FUNCTION_INFO_V1(funcname); 必须出现在同一个源文件中(按惯例会正好写在该函数本身之前)。 这种宏调用不是internal语言函数所需要的,因为 PostgreSQL会假定所有内部函数都使用 - 版本-1 规范。不过,对于动态载入函数是必需的。 + 版本-1 调用约定。不过,对于动态载入函数是必需的。 - 在版本-1 函数中,每一个实参都使用对应于该参数数据类型的PG_GETARG_xxx()宏取得。(在非严格的函数中,需要使用PG_ARGISNULL()对参数是否为空提前做检查;见下文。)结果要用对应于返回类型的PG_RETURN_xxx()宏返回。PG_GETARG_xxx()的参数是要取得的函数参数的编号,从零开始计。PG_RETURN_xxx()的参数是实际要返回的值。 + 在版本-1 函数中,每一个实参都使用对应于该参数数据类型的PG_GETARG_xxx()宏取得。(在非严格的函数中,需要使用PG_ARGISNULL()对参数是否为空值提前做检查;见下文。)结果要用对应于返回类型的PG_RETURN_xxx()宏返回。PG_GETARG_xxx()的参数是要取得的函数参数的编号,从零开始计。PG_RETURN_xxx()的参数是实际要返回的值。 @@ -2087,11 +2083,11 @@ CREATE FUNCTION concat_text(text, text) RETURNS text - 注意我们已经把函数指定为strict,这意味着如果有任何输入值为空,系统应该自动假定得到空结果。通过这种做法,我们避免在函数代码中检查空值输入。如果不这样做,我们必须使用PG_ARGISNULL()明确地检查空值输入。 + 注意我们已经把函数指定为strict,这意味着如果有任何输入值为空值,系统应该自动假定结果为空值。通过这种做法,我们避免在函数代码中检查空值输入。如果不这样做,我们必须使用PG_ARGISNULL()明确地检查空值输入。 - 宏PG_ARGISNULL(n)允许一个函数测试是否每一个输入为空(当然,只需要在没有声明为strict的函数中这样做)。和PG_GETARG_xxx()宏一样,输入参数也是从零开始计数。注意应该在验证了一个参数不是空之后才执行PG_GETARG_xxx()。要返回一个空结果,应执行PG_RETURN_NULL(),它对严格的以及非严格的函数都有用。 + 宏PG_ARGISNULL(n)允许一个函数测试是否每一个输入为空值(当然,只需要在没有声明为strict的函数中这样做)。和PG_GETARG_xxx()宏一样,输入参数也是从零开始计数。注意应该在验证了一个参数不是空值之后才执行PG_GETARG_xxx()。要返回空值结果,应执行PG_RETURN_NULL(),它对严格的以及非严格的函数都有用。 @@ -2099,11 +2095,11 @@ CREATE FUNCTION concat_text(text, text) RETURNS text - 在版本-1接口中提供的其他选项是PG_GETARG_xxx()宏的两个变种。其中的第一种是PG_GETARG_xxx_COPY(),它确保返回的指定参数的拷贝可以被安全地写入(通常的宏有时会返回一个指向表中物理存储的值,它不能被写入。使用PG_GETARG_xxx_COPY()宏可以保证得到一个可写的结果)。第二种变种PG_GETARG_xxx_SLICE()宏有三个参数。第一个是函数参数的编号(如上文)。第二个和第三个是要被返回的段的偏移量和长度。偏移量从零开始计算,而负值的长度则表示要求返回该值的剩余部分。当大型值的存储类型为external时,这些宏提供了访问这些大型值的更有效的方法(列的存储类型可以使用ALTER TABLE tablename ALTER COLUMN colname SET STORAGE storagetype来指定。storagetypeplainexternalextended或者main)。 + 在版本-1接口中提供的其他选项是PG_GETARG_xxx()宏的两个变种。其中的第一种是PG_GETARG_xxx_COPY(),它确保返回的指定参数的拷贝可以被安全地写入(通常的宏有时会返回一个指向表中物理存储值的指针,不能写入该值。使用PG_GETARG_xxx_COPY()宏可以保证得到一个可写的结果)。第二种变种PG_GETARG_xxx_SLICE()宏有三个参数。第一个是函数参数的编号(如上文)。第二个和第三个是要被返回的段的偏移量和长度。偏移量从零开始计算,而负值的长度则表示要求返回该值的剩余部分。当大型值的存储类型为external时,这些宏提供了访问这些大型值的部分内容的更有效方法(列的存储类型可以使用ALTER TABLE tablename ALTER COLUMN colname SET STORAGE storagetype来指定。storagetypeplainexternalextended或者main)。 - 最后,版本-1 的函数调用规范可以返回集合结果()、实现触发器函数()和过程语言调用处理器()。更多细节 + 最后,版本-1 的函数调用约定可以返回集合结果()、实现触发器函数()和过程语言调用处理器()。更多细节 可见源代码发布中的src/backend/utils/fmgr/README @@ -2114,10 +2110,10 @@ CREATE FUNCTION concat_text(text, text) RETURNS text 在开始更高级的话题之前,我们应该讨论一下用于 PostgreSQL C 语言函数的编码规则。 - 虽然可以把不是 C 编写的函数载入到 - PostgreSQL中,这通常是很困难的, + 虽然有可能把不是 C 编写的函数载入到 + PostgreSQL中,但即使能够做到,通常也很困难, 因为其他语言(例如 C++、FORTRAN 或者 Pascal)通常不会遵循和 C - 相同的调用规范。也就是说,其他语言不会以同样的方式在函数之间传递 + 相同的调用约定。也就是说,其他语言不会以同样的方式在函数之间传递 参数以及返回值。由于这个原因,我们会假定你的 C 语言函数确实是用 C 编写的。 @@ -2129,7 +2125,7 @@ CREATE FUNCTION concat_text(text, text) RETURNS text 使用 pg_config - --includedir-serverpg_configwith user-defined C functions + --includedir-serverpg_config用于用户定义的 C 函数 查出 PostgreSQL 服务器头文件在你的系统上(或你的用户将要运行的系统上)安装于何处。 @@ -2142,7 +2138,7 @@ CREATE FUNCTION concat_text(text, text) RETURNS text - 记得按照中的说明,为你的共享库定义一个magic block。 + 记得按照中的说明,为你的共享库定义一个魔数块 @@ -2168,7 +2164,7 @@ CREATE FUNCTION concat_text(text, text) RETURNS text - 对象文件中定义的符号名不能彼此冲突,也不能与 + 目标文件中定义的符号名不能彼此冲突,也不能与 PostgreSQL 服务器可执行文件中定义的符号冲突。如果你收到这类错误消息,就必须重命名相关函数或变量。 @@ -2183,10 +2179,10 @@ CREATE FUNCTION concat_text(text, text) RETURNS text 复合类型没有像 C 结构体那样的固定布局。复合类型的实例可能包含 - 空值域。此外,继承层次中的复合类型可能具有和同一继承层次中 - 其他成员不同的域。因此, + 空值字段。此外,继承层次中的复合类型可能具有和同一继承层次中 + 其他成员不同的字段。因此, PostgreSQL提供了函数接口 - 来访问 C 的复合类型的域。 + 以便从 C 访问复合类型的字段。 @@ -2198,7 +2194,7 @@ SELECT name, c_overpaid(emp, 1500) AS overpaid WHERE name = 'Bill' OR name = 'Sam'; - 如果使用版本-1的调用规范,我们可以定义 + 如果使用版本-1的调用约定,我们可以定义 c_overpaid为: 也有GetAttributeByNum函数,它可以用目标属性 - 的属性号而不是属性名来选择目标属性。 + 的列号而不是属性名来选择目标属性。 @@ -2257,14 +2253,14 @@ CREATE FUNCTION c_overpaid(emp, integer) RETURNS boolean 要从 C 语言函数中返回一行或一个复合类型值,可以使用一套特殊的 API, - 它通过一组宏和函数隐藏了构造组合数据类型时的大部分复杂性。要使用这套 API,源文件中必须包含: + 它通过一组宏和函数隐藏了构造复合数据类型时的大部分复杂性。要使用这套 API,源文件中必须包含: #include "funcapi.h" - 构造组合数据值(下文简称元组)有两种方式: + 构造复合数据值(下文简称元组)有两种方式: 一种是从 Datum 值数组构造,另一种是从 C 字符串数组构造,这些字符串会传给该元组各列数据类型的输入转换函数。 无论采用哪种方式,首先都需要获取或构造描述该元组结构的 TupleDesc。 处理 Datum 时,需要把 TupleDesc 传给 BlessTupleDesc,然后为每一行调用 heap_form_tuple。 @@ -2273,13 +2269,13 @@ CREATE FUNCTION c_overpaid(emp, integer) RETURNS boolean - 有一些辅助函数可以用来设置所需的 TupleDesc。在大多数返回组合值的函数中,推荐的做法是调用: + 有一些辅助函数可以用来设置所需的 TupleDesc。在大多数返回复合值的函数中,推荐的做法是调用: TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc) - 传入与调用函数本身相同的 fcinfo 结构体(这当然要求使用版本 1 调用约定)。 + 传入调用函数本身收到的同一个 fcinfo 结构体(这当然要求使用版本 1 调用约定)。 resultTypeId 可以指定为 NULL,也可以指定为一个本地变量的地址,用于接收函数结果类型的 OID。 resultTupleDesc 应当是一个本地 TupleDesc 变量的地址。 检查返回结果是否为 TYPEFUNC_COMPOSITE;如果是,resultTupleDesc 就会被填入所需的 TupleDesc。 @@ -2298,7 +2294,7 @@ TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, get_call_result_type有一个兄弟 get_expr_result_type,它被用来解析被表示为一棵表达式 - 树的函数调用的输出类型。在尝试确定来自函数外部的结果类型时可以用它。 + 树的函数调用的输出类型。在尝试从函数自身外部确定结果类型时可以用它。 也有一个get_func_result_type,当只有函数的 OID 可用时 可以用它。不过这些函数无法处理被声明为返回record的 函数,并且get_func_result_type无法解析多态类型,因此你 @@ -2307,22 +2303,22 @@ TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, - 更早、现在已被废弃的获取TupleDesc的函数有: + 更早、现在已被弃用的获取TupleDesc的函数有: TupleDesc RelationNameGetTupleDesc(const char *relname) - 它可以为一个提到的关系的行类型得到TupleDesc, + 它可以为一个指定名称的关系的行类型得到TupleDesc, 还有: TupleDesc TypeGetTupleDesc(Oid typeoid, List *colaliases) 可以基于一个类型 OID 得到TupleDesc。这可以被用来 - 为一种基础或者复合类型获得TupleDesc。不过,对于 + 为一种基本或者复合类型获得TupleDesc。不过,对于 返回record的函数它不起作用,并且它无法解析多态类型。 - 一旦有了一个TupleDesc,如果计划处理 Datum可以调用: + 一旦有了一个TupleDesc,如果计划处理 Datum,可以调用: TupleDesc BlessTupleDesc(TupleDesc tupdesc) @@ -2332,7 +2328,7 @@ AttInMetadata *TupleDescGetAttInMetadata(TupleDesc tupdesc) 如果正在编写一个返回集合的函数,你可以把这些函数的结果保存在 FuncCallContext结构体中 — 分别使用 - tuple_desc或者attinmeta域。 + tuple_desc或者attinmeta字段。 @@ -2352,8 +2348,7 @@ HeapTuple BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values) values是一个 C 字符串数组,每一个元素是返回行 的一个属性。每一个 C 字符串应该是该属性数据类型的输入函数所期望 的格式。为了对一个属性返回空值,values数组中对 - 应的指针应该被设置为NULL。对于你返回的每一行都将 - 再次调用这个函数。 + 应的指针应该被设置为NULL。对于你返回的每一行都需要再次调用这个函数。 @@ -2388,13 +2383,13 @@ HeapTupleGetDatum(HeapTuple tuple) 使用 ValuePerCall 模式时,重要的是要记住查询不能保证运行完成; 也就是说,由于诸如LIMIT之类的选项, - 执行程序可能会在获取所有行之前停止调用 set-returning 函数。 + 执行器可能会在获取所有行之前停止调用集合返回函数。 这意味着在最后一次调用中执行清理活动是不安全的,因为这可能永远不会发生。 对于需要访问外部资源(例如文件描述符)的函数,建议使用 Materialize 模式。 - 本节的其余部分记录了一组使用 ValuePerCall 模式的 SRF 常用(尽管不是必须使用)的帮助程序宏。 + 本节的其余部分记录了一组使用 ValuePerCall 模式的 SRF 常用(尽管不是必须使用)的辅助宏。 有关 Materialize 模式的其他详细信息可以在src/backend/utils/fmgr/README中找到。 此外,PostgreSQL源代码分发中的contrib 模块包含许多使用 ValuePerCall 和 Materialize 模式的 SRF 示例。 @@ -2403,7 +2398,7 @@ HeapTupleGetDatum(HeapTuple tuple) 要使用此处描述的 ValuePerCall 支持宏,请包含funcapi.h。 这些宏与结构体FuncCallContext一起使用,该结构体包含需要跨调用保存的状态。 - 在调用 SRF 中,fcinfo->flinfo->fn_extra用于在调用之间保存 + 在使用这些宏的 SRF 中,fcinfo->flinfo->fn_extra用于在调用之间保存 指向FuncCallContext的指针。 宏在第一次使用时自动填充该字段,并期望在后续使用中找到相同的指针。 @@ -2436,7 +2431,7 @@ typedef struct FuncCallContext /* * 可选:指向包含属性类型输入元数据的结构的指针 * - * attinmeta 被用在返回元组(即组合数据类型)时,在返回基本数据类型 + * attinmeta 被用在返回元组(即复合数据类型)时,在返回基础类型 * 时不会使用。只有想用BuildTupleFromCStrings()创建返回元组时才需要它。 */ AttInMetadata *attinmeta; @@ -2453,7 +2448,7 @@ typedef struct FuncCallContext /* * 可选:指向包含元组描述的结构的指针 * - * tuple_desc 被用在返回元组(即组合数据类型)时,并且只有在用 + * tuple_desc 被用在返回元组(即复合数据类型)时,并且只有在用 * heap_form_tuple() 而不是 BuildTupleFromCStrings() 构建元组时才需要它。 * 注意这里存储的 TupleDesc 指针通常已经被先运行过 BlessTupleDesc()。 */ @@ -2557,7 +2552,7 @@ my_set_returning_function(PG_FUNCTION_ARGS) else { /* 这里已经完成了项的返回,所以只报告事实。 */ - /* (不要将清理代码放在这里的。) */ + /* (不要将清理代码放在这里。) */ SRF_RETURN_DONE(funcctx); } } @@ -2637,7 +2632,7 @@ retcomposite(PG_FUNCTION_ARGS) /* 构建一个元组 */ tuple = BuildTupleFromCStrings(attinmeta, values); - /* 将元组转换为数据 */ + /* 将元组转换为 datum */ result = HeapTupleGetDatum(tuple); /* 清理(这实际上并不是必要的) */ @@ -2693,10 +2688,10 @@ CREATE OR REPLACE FUNCTION retcomposite(IN integer, IN integer, fcinfo->flinfo访问。参数argnum则是从零 开始计。get_call_result_type也可被用作 get_fn_expr_rettype的一种替代品。还有 - get_fn_expr_variadic,它可以被用来找出 variadic 参数 + get_fn_expr_variadic,它可以被用来找出可变参数 是否已经被合并到了一个数组中。这主要用于 VARIADIC "any"函数,因为对于接收普通数组类型的 - variadic 函数来说总是会发生这类合并。 + 可变参数函数来说总是会发生这类合并。 @@ -2764,7 +2759,7 @@ CREATE FUNCTION make_array(anyelement) RETURNS anyarray 它与 anyelement 类似,但不会要求不同的 "any" 参数必须是同一种类型,也不会帮助确定函数的结果类型。 C 语言函数还可以把最后一个参数声明为 VARIADIC "any"。 这可以匹配一个或多个任意类型的实参(不必是同一种类型)。 - 这些参数不会像普通 variadic 函数那样被收集成一个数组,而是会单独传给函数。 + 这些参数不会像普通可变参数函数那样被收集成一个数组,而是会单独传给函数。 使用这种特性时,必须结合 PG_NARGS() 宏以及前面介绍的方法来确定实参的个数和类型。 此外,这种函数的用户也可能希望在函数调用中使用 VARIADIC 关键字,以便让函数把数组元素当作独立参数处理。 如果希望支持这种行为,函数本身就必须在使用 get_fn_expr_variadic 检测到实参被标记为 VARIADIC 后自行实现它。 @@ -3046,9 +3041,9 @@ extern bool InjectionPointDetach(const char *name); - 如果从 C++ 代码调用后端函数,确定 C++ 调用栈值包含传统 C 风格 + 如果从 C++ 代码调用后端函数,确定 C++ 调用栈只包含传统 C 风格 的数据结构(POD)。这是必要的,因为后端错误会 - 产生远距离的longjmp(),它无法正确的退回具有非 + 产生远距离的longjmp(),它无法正确地展开具有非 POD 对象的 C++ 调用栈。 @@ -3067,8 +3062,8 @@ extern bool InjectionPointDetach(const char *name); 函数优化信息 - optimization information - for functions + 优化信息 + 用于函数 @@ -3104,7 +3099,7 @@ supportfn(internal) returns internal - 对于返回 boolean 的目标函数,估计使用该函数的 WHERE 子句会筛选出多少行通常很有用。这可以通过实现 SupportRequestSelectivity 请求类型的支持函数来完成。 + 对于返回 boolean 的目标函数,估计使用该函数的 WHERE 子句筛选出的行所占的比例通常很有用。这可以通过实现 SupportRequestSelectivity 请求类型的支持函数来完成。 diff --git a/zh/17/xindex.sgml b/zh/17/xindex.sgml index 301168d1..e36724fb 100644 --- a/zh/17/xindex.sgml +++ b/zh/17/xindex.sgml @@ -4,8 +4,8 @@ 索引扩展接口 - index - for user-defined data type + 索引 + 用于用户定义的数据类型 @@ -27,7 +27,7 @@ - 索引方法的例程并不直接知道它将处理哪些数据类型。相反,一个操作符类operator class标识了索引方法在处理特定数据类型时需要使用的那组操作。之所以称为操作符类,是因为它指定的一项内容就是可与索引一起使用的 WHERE 子句操作符集合(也就是能被转换成索引扫描条件的操作符)。操作符类还可以指定索引方法内部操作所需的一些支持函数,但这些函数并不直接对应任何可与索引一起使用的 WHERE 子句操作符。 + 索引方法的例程并不直接知道它将处理哪些数据类型。相反,一个操作符类操作符类标识了索引方法在处理特定数据类型时需要使用的那组操作。之所以称为操作符类,是因为它指定的一项内容就是可与索引一起使用的 WHERE 子句操作符集合(也就是能被转换成索引扫描条件的操作符)。操作符类还可以指定索引方法内部操作所需的一些支持函数,但这些函数并不直接对应任何可与索引一起使用的 WHERE 子句操作符。 @@ -379,7 +379,7 @@ - 给定一个 64 位 salt,计算一个键的 64 位哈希值;如果 salt 为 0,结果的低 32 位必须与函数 1 计算出的值一致(可选) + 给定一个 64 位盐值,计算一个键的 64 位哈希值;如果盐值为 0,结果的低 32 位必须与函数 1 计算出的值一致(可选) 2 @@ -547,7 +547,7 @@ compare - 比较两个键,并返回一个小于零、等于零或大于零的整数,以表示第一个键是小于、等于还是大于第二个键 + 比较两个键,并返回一个小于零、等于零或大于零的整数,用以表示第一个键是小于、等于还是大于第二个键 1 @@ -721,7 +721,7 @@ CREATE OPERATOR < ( restrict = scalarltsel, join = scalarltjoinsel ); - 指定正确的交换子和求反器操作符很重要,同样也要指定合适的限制选择度函数和连接选择度函数,否则优化器将无法有效地利用索引。 + 指定正确的交换子和求反器操作符很重要,同样也要指定合适的限制选择率函数和连接选择率函数,否则优化器将无法有效地利用索引。 @@ -800,7 +800,7 @@ CREATE OPERATOR CLASS complex_abs_ops - 为了满足这些需求,PostgreSQL使用操作符族operator family这一概念。一个操作符族包含一个或多个操作符类,还可以包含属于整个族、但不属于族中任何单一类的可索引操作符及其相应的支持函数。我们称这样的操作符和函数在该族中是松散的,而不是绑定在某个特定类中。通常,每个操作符类只包含单一数据类型的操作符,而跨数据类型操作符则作为操作符族中的松散成员存在。 + 为了满足这些需求,PostgreSQL使用操作符族操作符族这一概念。一个操作符族包含一个或多个操作符类,还可以包含属于整个族、但不属于族中任何单一类的可索引操作符及其相应的支持函数。我们称这样的操作符和函数在该族中是松散的,而不是绑定在某个特定类中。通常,每个操作符类只包含单一数据类型的操作符,而跨数据类型操作符则作为操作符族中的松散成员存在。 @@ -917,7 +917,7 @@ ALTER OPERATOR FAMILY integer_ops USING btree ADD - 要构建一个多数据类型的哈希操作符族,必须为该族支持的每一种数据类型创建相互兼容的哈希支持函数。这里的兼容性是指:对任意两个被该族中的等值操作符视为相等的值,这些函数都保证返回相同的哈希码,即使这两个值属于不同类型也是如此。当这些类型具有不同的物理表示时,这通常难以实现,但在某些情况下可以做到。此外,将该操作符族中一种数据类型的值通过隐式或二进制强制转换转换成该族中另一种数据类型时,不应改变所计算出的哈希值。注意,每种数据类型只有一个支持函数,而不是每个等值操作符一个。建议让操作符族保持完整,也就是说,对每一种数据类型组合都提供一个等值操作符。每个操作符类只应包含其数据类型对应的非跨数据类型等值操作符和支持函数。 + 要构建一个多数据类型的哈希操作符族,必须为该族支持的每一种数据类型创建相互兼容的哈希支持函数。这里的兼容性是指:对任意两个被该族中的等值操作符视为相等的值,这些函数都保证返回相同的哈希码,即使这两个值属于不同类型也是如此。当这些类型具有不同的物理表示时,这通常难以实现,但在某些情况下可以做到。此外,将该操作符族中一种数据类型的值通过隐式或二进制强制转换转为该族中另一种数据类型时,不得改变所计算出的哈希值。注意,每种数据类型只有一个支持函数,而不是每个等值操作符一个。建议让操作符族保持完整,也就是说,对每一种数据类型组合都提供一个等值操作符。每个操作符类只应包含其数据类型对应的非跨数据类型等值操作符和支持函数。 @@ -930,7 +930,7 @@ ALTER OPERATOR FAMILY integer_ops USING btree ADD - 在 PostgreSQL 8.3 之前,并没有操作符族这一概念,因此任何打算与索引一起使用的跨数据类型操作符都必须直接绑定到该索引的操作符类中。虽然这种做法仍然有效,但已经废弃,因为它会使索引的依赖关系过于宽泛,而且当两种数据类型都在同一操作符族中拥有操作符时,规划器能更有效地处理跨数据类型比较。 + 在 PostgreSQL 8.3 之前,并没有操作符族这一概念,因此任何打算与索引一起使用的跨数据类型操作符都必须直接绑定到该索引的操作符类中。虽然这种做法仍然有效,但已被弃用,因为它会使索引的依赖关系过于宽泛,而且当两种数据类型都在同一操作符族中拥有操作符时,规划器能更有效地处理跨数据类型比较。 @@ -939,7 +939,7 @@ ALTER OPERATOR FAMILY integer_ops USING btree ADD 系统对操作符类的依赖 - ordering operator + 排序操作符 @@ -947,7 +947,7 @@ ALTER OPERATOR FAMILY integer_ops USING btree ADD - 特别地,ORDER BYDISTINCT等 SQL 特性要求对值的比较和排序。为了在用户定义的数据类型上实现这些特性,PostgreSQL会为数据类型查找默认 B-树操作符类。这个操作符类的equals成员定义了用于GROUP BYDISTINCT的值的等值概念,而该操作符类施加的排序顺序定义了默认的ORDER BY顺序。 + 特别地,ORDER BYDISTINCT等 SQL 特性要求对值的比较和排序。为了在用户定义的数据类型上实现这些特性,PostgreSQL会为数据类型查找默认 B-树操作符类。这个操作符类的相等成员定义了用于GROUP BYDISTINCT的值的等值概念,而该操作符类施加的排序顺序定义了默认的ORDER BY顺序。 @@ -973,11 +973,11 @@ SELECT * FROM mytable ORDER BY somecol USING ~<~; - 用户定义类型的数组比较也依赖于该类型默认 B-树操作符类所定义的语义。如果没有默认 B-树操作符类,但有默认的哈希操作符类,则支持数组相等比较,但不支持顺序比较。 + 用户定义类型的数组比较也依赖于该类型默认 B-树操作符类所定义的语义。如果没有默认 B-树操作符类,但有默认的哈希操作符类,则支持数组相等比较,但不支持排序比较。 - 另一种需要更多数据类型相关知识的 SQL 特性,是窗口函数中的 RANGE offset PRECEDING/FOLLOWING 框架选项(见)。对于下面这样的查询 + 另一种需要更多数据类型相关知识的 SQL 特性,是窗口函数中的 RANGE offset PRECEDING/FOLLOWING 帧选项(见)。对于下面这样的查询 SELECT sum(x) OVER (ORDER BY x RANGE BETWEEN 5 PRECEDING AND 10 FOLLOWING) FROM mytable; @@ -1012,7 +1012,7 @@ SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10; - 搜索操作符必须返回布尔结果,而排序操作符通常返回其他类型的结果,例如表示距离的浮点数或数值。这种类型通常不同于被索引的数据类型。为了避免对不同数据类型行为作硬编码假设,在定义排序操作符时,必须指定一个 B-树操作符族,用来说明结果数据类型的排序顺序。正如上一节所述,B-树操作符族定义了 PostgreSQL 的顺序概念,因此这是一种自然的表示方式。由于点的 <-> 操作符返回 float8,因此可以在创建操作符类时这样指定它: + 搜索操作符必须返回布尔结果,而排序操作符通常返回其他类型的结果,例如用于表示距离的 float 或 numeric。这种类型通常不同于被索引的数据类型。为了避免对不同数据类型行为作硬编码假设,在定义排序操作符时,必须指定一个 B-树操作符族,用来说明结果数据类型的排序顺序。正如上一节所述,B-树操作符族定义了 PostgreSQL 的顺序概念,因此这是一种自然的表示方式。由于点的 <-> 操作符返回 float8,因此可以在创建操作符类时这样指定它: (point, point) FOR ORDER BY float_ops ]]> @@ -1025,7 +1025,7 @@ OPERATOR 15 <-> (point, point) FOR ORDER BY float_ops 操作符类的特殊特性 - 还有两个操作符类的特殊特性我们尚未讨论,主要是因为它们对最常用的索引方法并不太有用。 + 还有两个操作符类的特殊特性我们尚未讨论,主要是因为它们对最常用的索引方法没有用处。 @@ -1046,7 +1046,7 @@ CREATE OPERATOR CLASS polygon_ops STORAGE box; - 目前,只有 GiST、SP-GiST、GIN 和 BRIN 索引方法支持与列数据类型不同的 STORAGE 类型。GiST 的 compressdecompress 支持例程在使用 STORAGE 时必须处理数据类型转换。SP-GiST 同样需要 compress 支持函数在存储类型不同时完成转换;如果某个 SP-GiST 操作符类还支持取回数据,那么反向转换必须由 consistent 函数处理。在 GIN 中,STORAGE 类型标识key值的类型,它通常不同于被索引列的类型 — 例如,整数数组列上的某个操作符类,其键值可能只是整数。GIN 的 extractValueextractQuery 支持例程负责从被索引值中提取键。BRIN 与 GIN 类似:STORAGE 类型标识被存储的摘要值类型,而操作符类的支持过程负责正确解释这些摘要值。 + 目前,只有 GiST、SP-GiST、GIN 和 BRIN 索引方法支持与列数据类型不同的 STORAGE 类型。GiST 的 compressdecompress 支持例程在使用 STORAGE 时必须处理数据类型转换。SP-GiST 同样需要 compress 支持函数在存储类型不同时完成转换;如果某个 SP-GiST 操作符类还支持取回数据,那么反向转换必须由 consistent 函数处理。在 GIN 中,STORAGE 类型标识值的类型,它通常不同于被索引列的类型 — 例如,整数数组列上的某个操作符类,其键值可能只是整数。GIN 的 extractValueextractQuery 支持例程负责从被索引值中提取键。BRIN 与 GIN 类似:STORAGE 类型标识被存储的摘要值类型,而操作符类的支持函数负责正确解释这些摘要值。 diff --git a/zh/17/xml2.sgml b/zh/17/xml2.sgml index 1324ffd4..f3f40587 100644 --- a/zh/17/xml2.sgml +++ b/zh/17/xml2.sgml @@ -90,7 +90,7 @@ 对文档执行该查询,并将结果包在 XML 标签中。如果结果包含多个值,输出将类似于: <toptag> -<itemtag>Value 1 which could be an XML fragment</itemtag> +<itemtag>Value 1(可以是 XML 片段)</itemtag> <itemtag>Value 2....</itemtag> </toptag> @@ -173,7 +173,7 @@ xpath_table(text key, text document, text relation, text xpaths, text criteria) key - key 字段的名称 — 这只是一个作为输出表第一列使用的字段,也就是说,它用于标识每个输出行来自哪条记录(关于多个值,见下文注释) + 字段的名称 — 这只是一个作为输出表第一列使用的字段,也就是说,它用于标识每个输出行来自哪条记录(关于多个值,见下文注释) @@ -238,7 +238,7 @@ xpath_table('article_id', 'date_entered > ''2003-01-01'' ') AS t(article_id integer, author text, page_count integer, title text); - AS 子句定义了输出表中各列的名称和类型。第一列是 key 字段,其余各列对应 XPath 查询。如果 XPath 查询多于结果列,多出的查询将被忽略。如果结果列多于 XPath 查询,多出的列将为 NULL。 + AS 子句定义了输出表中各列的名称和类型。第一列是 字段,其余各列对应 XPath 查询。如果 XPath 查询多于结果列,多出的查询将被忽略。如果结果列多于 XPath 查询,多出的列将为 NULL。 @@ -267,7 +267,7 @@ WHERE t.author_id = p.person_id; - 在某些情况下,用户会知道某个 XPath 查询只会返回单个结果(例如唯一文档标识符)— 如果它与返回多个结果的 XPath 查询一起使用,这个单值结果只会出现在结果的第一行。解决办法是把 key 字段作为与一个更简单的 XPath 查询结果进行连接的条件之一。例如: + 在某些情况下,用户会知道某个 XPath 查询只会返回单个结果(例如唯一文档标识符)— 如果它与返回多个结果的 XPath 查询一起使用,这个单值结果只会出现在结果的第一行。解决办法是把键字段作为与一个更简单的 XPath 查询结果进行连接的条件之一。例如: CREATE TABLE test ( diff --git a/zh/17/xoper.sgml b/zh/17/xoper.sgml index b9968985..3e471267 100644 --- a/zh/17/xoper.sgml +++ b/zh/17/xoper.sgml @@ -164,10 +164,10 @@ SELECT (a + b) AS c FROM test_complex; <literal>RESTRICT</literal> - 如果给出 RESTRICT 子句,它指定该操作符的限制选择度估 + 如果给出 RESTRICT 子句,它指定该操作符的限制选择率估 算函数。(注意,这里是函数名,而不是操作符名。) RESTRICT 子句只对返回 boolean 的二元操 - 作符有意义。限制选择度估算器的作用,是针对当前操作符和某个特定常量值, + 作符有意义。限制选择率估算器的作用,是针对当前操作符和某个特定常量值, 猜测一张表中有多少比例的行会满足如下形式的 WHERE 子句条件: @@ -179,9 +179,9 @@ column OP constant - 编写新的限制选择度估算函数远远超出了本章的范围,不过幸运的是,对于你自 + 编写新的限制选择率估算函数远远超出了本章的范围,不过幸运的是,对于你自 己的很多操作符,通常都可以直接使用系统提供的某个标准估算器。标准的限制 - 选择度估算器如下: + 选择率估算器如下: eqsel 用于 = neqsel 用于 <> @@ -193,7 +193,7 @@ column OP constant - 对于选择度非常高或非常低的操作符,即使它们实际上并不是真正的相等或不等 + 对于选择率非常高或非常低的操作符,即使它们实际上并不是真正的相等或不等 比较,你也常常可以勉强使用 eqselneqsel。例如,几何类型中的近似相等操作符就使用 eqsel,其依据是它们通常只会匹配表中很小一部分项。 @@ -212,7 +212,7 @@ column OP constant - 另一个有用的内置选择度估算函数是 matchingsel。只要 + 另一个有用的内置选择率估算函数是 matchingsel。只要 已为输入数据类型收集了标准的 MCV 和/或直方图统计信息,它几乎就适用于任 何二元操作符。它的默认估计值被设定为 eqsel 所用默认 估计值的两倍,因此最适合那些比相等比较稍微宽松一些的比较操作符。(或者 @@ -222,7 +222,7 @@ column OP constant src/backend/utils/adt/geo_selfuncs.c 中,还为几 - 何操作符提供了其他选择度估算函数:areasel、 + 何操作符提供了其他选择率估算函数:areaselpositionselcontsel。截至 目前,这些函数都还只是桩实现,但你也许仍会想使用它们(或者更好的是,改 进它们)。 @@ -233,9 +233,9 @@ column OP constant <literal>JOIN</literal> - 如果给出 JOIN 子句,它指定该操作符的连接选择度估算函 + 如果给出 JOIN 子句,它指定该操作符的连接选择率估算函 数。(注意,这里是函数名,而不是操作符名。)JOIN 子 - 句只对返回 boolean 的二元操作符有意义。连接选择度估算器的 + 句只对返回 boolean 的二元操作符有意义。连接选择率估算器的 作用,是针对当前操作符,猜测两张表中有多少比例的行对会满足如下形式的 WHERE 子句条件: @@ -246,7 +246,7 @@ table1.column1 OP table2.column2 - 与前面一样,本章不会尝试解释如何编写连接选择度估算函数,而只是建议你在 + 与前面一样,本章不会尝试解释如何编写连接选择率估算函数,而只是建议你在 适用时使用某个标准估算器: eqjoinsel 用于 = @@ -305,7 +305,7 @@ table1.column1 OP table2.column2 一个可参与哈希连接的操作符,必须拥有一个交换子(如果两侧操作数数据类型 - 相同,则可以是它自身;如果不同,则应是相关的相等操作符),并且该交换子 + 相同,则为它自身;如果不同,则应是相关的相等操作符),并且该交换子 也必须出现在同一个操作符族中。否则,在使用该操作符时可能会发生规划器错 误。另外,对于支持多种数据类型的哈希操作符族,最好(虽然并非严格必需) 为每一种数据类型组合都提供相等操作符;这样可以获得更好的优化效果。 @@ -342,7 +342,7 @@ table1.column1 OP table2.column2 - 归并连接的基本思想,是先把左表和右表分别排序,然后并行扫描它们。因此, + 归并连接的基本思想,是先把左表和右表分别排序,然后同步扫描它们。因此, 两种数据类型都必须能够被完全排序,而连接操作符必须只能在那对值位于排序 次序中同一位置时才成功。实际效果上,这意味着连接操作符 必须表现得像相等比较一样。不过,只要两种不同的数据类型在逻辑上兼容,也 @@ -362,7 +362,7 @@ table1.column1 OP table2.column2 一个可参与归并连接的操作符,必须拥有一个交换子(如果两侧操作数数据类型 - 相同,则可以是它自身;如果不同,则应是相关的相等操作符),并且该交换子 + 相同,则为它自身;如果不同,则应是相关的相等操作符),并且该交换子 也必须出现在同一个操作符族中。否则,在使用该操作符时可能会发生规划器错 误。另外,对于支持多种数据类型的 btree 操作符族,最 好(虽然并非严格必需)为每一种数据类型组合都提供相等操作符;这样可以获 diff --git a/zh/17/xplang.sgml b/zh/17/xplang.sgml index 9075d7b6..0590ea2d 100644 --- a/zh/17/xplang.sgml +++ b/zh/17/xplang.sgml @@ -183,7 +183,7 @@ CREATE TRUSTED LANGUAGE plperl 在默认的PostgreSQL安装中, PL/pgSQL语言的调用处理器会被构建并安装到 - library目录中;此外, + 目录中;此外, PL/pgSQL语言本身也安装在所有数据库中。如 果在构建时配置了Tcl支持,那么 PL/TclPL/TclU diff --git a/zh/17/xtypes.sgml b/zh/17/xtypes.sgml index 3d1b66d1..b66c4aa1 100644 --- a/zh/17/xtypes.sgml +++ b/zh/17/xtypes.sgml @@ -218,7 +218,7 @@ CREATE TYPE complex ( 如果数据类型的内部表示是可变长度的,则这种内部表示必须遵循可变长度数 据的标准布局:前四个字节必须是一个从不直接访问的char[4] 字段(惯例上命名为vl_len_)。必须使用 - SET_VARSIZE()宏在该字段中存储该值的总大小(包括 + SET_VARSIZE()宏在该字段中存储该 datum 的总大小(包括 长度字段本身),并使用VARSIZE()取回它。(这些宏 之所以存在,是因为长度字段可能会随平台不同而采用编码形式。) @@ -260,7 +260,7 @@ CREATE TYPE complex ( PG_DETOAST_DATUM_PACKED(通常通过定义 GETARG_DATATYPE_PP宏来隐藏),并使用 VARSIZE_ANY_EXHDRVARDATA_ANY - 宏访问一个可能采用打包形式的值。再次注意,即使数据类型定义指定了 + 宏访问一个可能采用打包形式的 datum。再次注意,即使数据类型定义指定了 对齐方式,这些宏返回的数据也不是对齐的。如果对齐很重要,就必须使用常 规的PG_DETOAST_DATUM接口。 @@ -271,8 +271,7 @@ CREATE TYPE complex ( 较旧的代码常把vl_len_声明为 int32字段,而不是char[4]字段。只要结构体定 义中还有其他至少按int32对齐的字段,这样做是可以的。但 - 在处理可能未对齐的值时使用这种结构体定义就很危险;编译器可能据此假定该 - 值实际上是对齐的,从而在对齐要求严格的体系结构上导致核心转储。 + 在处理可能未对齐的 datum 时使用这种结构体定义就很危险;编译器可能据此假定该 datum 实际上是对齐的,从而在对齐要求严格的体系结构上导致核心转储。 diff --git a/zh/18/amcheck.sgml b/zh/18/amcheck.sgml index 8a033656..655c0f44 100644 --- a/zh/18/amcheck.sgml +++ b/zh/18/amcheck.sgml @@ -361,7 +361,7 @@ SET client_min_messages = DEBUG1; 这也包括因操作系统排序规则的比较规则发生变化而引起的问题。 - 像text这类可排序类型的数据值之间的比较必须是不可变的 + 像text这类支持排序规则的类型的 datum 之间的比较必须是不可变的 (正如用于 B-树索引扫描的所有比较都必须不可变一样), 这就意味着操作系统排序规则绝不能发生变化。 虽然这种情况比较少见,但操作系统排序规则的更新确实可能导致此类问题。 diff --git a/zh/18/backup-manifest.sgml b/zh/18/backup-manifest.sgml index 5d61e7ff..3eec4b46 100644 --- a/zh/18/backup-manifest.sgml +++ b/zh/18/backup-manifest.sgml @@ -4,7 +4,7 @@ 备份清单格式 - Backup Manifest + 备份清单 @@ -180,7 +180,7 @@ Start-LSN - 为了使用该备份,必须在指定时间线上从这个 LSN 开始回放。该 LSN 按 + 为了使用该备份,必须在指定时间线上从这个 LSN 开始重放。该 LSN 按 PostgreSQL 通常使用的格式存储;也就是说, 它是一个字符串,由两段十六进制字符串构成,每段长度在 1 到 8 之间,并 以斜杠分隔。 @@ -192,7 +192,7 @@ End-LSN - 使用该备份时,指定时间线上的回放可结束于此 LSN,而这也是允许的最早 + 使用该备份时,指定时间线上的重放可结束于此 LSN,而这也是允许的最早 LSN。其存储格式与 Start-LSN 相同。 diff --git a/zh/18/backup.sgml b/zh/18/backup.sgml index a549c4fb..a7df279f 100644 --- a/zh/18/backup.sgml +++ b/zh/18/backup.sgml @@ -3,7 +3,7 @@ 备份和恢复 - backup + 备份 与任何保存重要数据的系统一样,PostgreSQL数据库也应定期备份。虽然其过程基本简单,但清楚理解其底层技术和前提假设非常重要。 @@ -74,7 +74,7 @@ psql -X dbname < psql -X --set ON_ERROR_STOP=on dbname < dumpfile - 无论如何,你最终只会得到一个部分恢复的数据库。另一种做法是指定将整个转储作为单个事务恢复,这样恢复要么全部完成,要么全部回滚。可以通过把命令行选项传给psql来启用这种模式。使用这种模式时要注意,即便是一个很小的错误,也可能回滚一个已经运行了许多小时的恢复过程。不过,这仍可能比在部分恢复后手工清理一个复杂数据库更可取。 + 无论采用上述哪种方式,你最终只会得到一个部分恢复的数据库。另一种做法是指定将整个转储作为单个事务恢复,这样恢复要么全部完成,要么全部回滚。可以通过把命令行选项传给psql来启用这种模式。使用这种模式时要注意,即便是一个很小的错误,也可能回滚一个已经运行了许多小时的恢复过程。不过,这仍可能比在部分恢复后手工清理一个复杂数据库更可取。 @@ -194,7 +194,7 @@ pg_restore -d dbname - 对于非常大的数据库,你可能需要把split与前两种方法之一结合使用。 + 对于非常大的数据库,你可能需要把split与另外两种方法之一结合使用。 @@ -250,7 +250,7 @@ tar -cf backup.tar /usr/local/pgsql/data - 如果无法获得同时的快照,一种选择是将数据库服务器关闭足够长的时间,以建立所有冻结快照。另一种选择是执行持续归档基础备份(),因为这种备份不受备份期间文件系统变化的影响。这要求只在备份过程中启用持续归档;恢复则使用持续归档恢复()。 + 如果无法获得同时的快照,一种选择是将数据库服务器关闭足够长的时间,以建立所有冻结快照。另一种选择是执行持续归档基础备份(),因为这种备份不受备份期间文件系统变化的影响。这种方法只需在备份期间启用持续归档;恢复则使用持续归档恢复()。 @@ -266,11 +266,11 @@ tar -cf backup.tar /usr/local/pgsql/data 持续归档和时间点恢复(PITR) - continuous archiving + 持续归档 - point-in-time recovery + 时间点恢复 @@ -310,7 +310,7 @@ tar -cf backup.tar /usr/local/pgsql/data - 和普通文件系统备份技术一样,这种方法只能支持整个数据库集簇的恢复,而不支持其中某个子集的恢复。此外,它需要大量归档存储:基础备份可能很庞大,繁忙系统也会产生大量必须归档的 WAL 流量。尽管如此,在很多需要高可靠性的场景中,它仍是首选的备份技术。 + 和普通文件系统备份技术一样,这种方法只能支持整个数据库集簇的恢复,而不支持其中某个子集的恢复。此外,它需要大量归档存储:基础备份可能很庞大,繁忙系统也会产生许多兆字节的、必须归档的 WAL 流量。尽管如此,在很多需要高可靠性的场景中,它仍是首选的备份技术。 @@ -329,7 +329,7 @@ tar -cf backup.tar /usr/local/pgsql/data - 要启用 WAL 归档,请将配置参数设置为replica或更高,将设置为on,并在配置参数中指定要使用的 shell 命令,或者在配置参数中指定要使用的库。实际上,这些设置通常都会放在postgresql.conf文件中。 + 要启用 WAL 归档,请将配置参数设置为replica或更高,将设置为on,并在配置参数中指定要使用的 shell 命令,或者在配置参数中指定要使用的库。在实际使用中,这些设置总是放在postgresql.conf文件中。 @@ -345,20 +345,16 @@ test ! -f /mnt/server/archivedir/00000001000000A900000065 && cp pg_wal/0 对每个新的待归档文件都会生成一条类似的命令。 - - 归档命令会以运行PostgreSQL服务器的同一操作系统用户身份执行。由于这一系列被归档的 WAL 文件实际上包含了数据库中的几乎全部内容,因此你应确保归档数据不会被他人窥探;例如,把它归档到一个不向组或所有用户开放读权限的目录中。 - + 归档命令将以运行 PostgreSQL 服务器的同一用户身份执行。由于归档的一系列 WAL 文件实际上包含数据库中的全部内容,应确保归档数据不会被他人窥视;例如,将其归档到不允许所属组或其他用户读取的目录。 - - 重要的是,归档命令只有在成功时才返回零退出状态。收到零结果后,PostgreSQL会认为该文件已经成功归档,并会将其删除或回收。相反,非零状态会告诉PostgreSQL该文件尚未归档;系统会周期性重试,直到成功为止。 - + 归档命令必须当且仅当成功时才返回退出状态零。收到零状态后,PostgreSQL 会认为该文件已成功归档,并将其删除或回收。非零状态则告诉 PostgreSQL 该文件尚未归档;它会定期重试,直到成功。 另一种归档方式是把自定义归档模块用作archive_library。由于这类模块是用C编写的,创建自己的模块可能比编写 shell 命令需要更多工作。不过,归档模块可能比通过 shell 归档更高效,而且可以访问许多有用的服务器资源。有关归档模块的更多信息,见 - 当归档命令被信号终止(用于服务器关闭流程的SIGTERM除外),或者 shell 因退出状态大于 125 的错误(例如命令未找到)而失败,或者归档函数发出ERRORFATAL时,归档器进程会中止,并由 postmaster 重新启动。在这种情况下,失败不会记录到中。 + 当归档命令被信号终止(用于服务器关闭流程的SIGTERM除外),或者因 shell 报错(例如命令未找到)而以大于 125 的状态退出,或者归档函数发出ERRORFATAL时,归档器进程会中止,并由 postmaster 重新启动。在这种情况下,失败不会记录到中。 @@ -366,7 +362,7 @@ test ! -f /mnt/server/archivedir/00000001000000A900000065 && cp pg_wal/0 - 在少数情况下,PostgreSQL可能会尝试重新归档一个此前已经归档过的 WAL 文件。例如,如果系统在服务器把归档成功持久记录下来之前崩溃,服务器在重启后会再次尝试归档该文件(前提是归档仍然启用)。当归档命令或归档库遇到一个已存在的文件时,如果该文件与待归档 WAL 文件内容完全相同,且先前归档的文件已经完全持久化到存储,则前者应分别返回零状态或true。如果已存在文件的内容与正在归档的 WAL 文件不同,则归档命令或归档库必须分别返回非零状态或false。 + 在少数情况下,PostgreSQL可能会尝试重新归档一个此前已经归档过的 WAL 文件。例如,如果系统在服务器把归档成功持久记录下来之前崩溃,服务器在重启后会再次尝试归档该文件(前提是归档仍然启用)。当归档命令或归档库遇到一个已存在的文件时,如果该文件与待归档 WAL 文件内容完全相同,且先前归档的文件已经完全持久化到存储,则归档命令或归档库应分别返回零状态或true。如果已存在文件的内容与正在归档的 WAL 文件不同,则归档命令或归档库必须分别返回非零状态或false @@ -390,7 +386,7 @@ test ! -f /mnt/server/archivedir/00000001000000A900000065 && cp pg_wal/0 - 归档命令或归档函数只会在完整的 WAL 段上被调用。因此,如果服务器产生的 WAL 流量很小(或者存在低谷期),事务完成到其被安全写入归档存储之间可能会有很长延迟。为了限制未归档数据可能有多旧,你可以设置,强制服务器至少隔这么长时间切换到一个新的 WAL 段文件。注意,由强制切换而提前归档的文件长度仍与装满的文件相同。因此,把archive_timeout设得很短并不明智,这会使归档存储膨胀。archive_timeout设为大约 1 分钟通常是合理的。 + 归档命令或归档函数只会针对已完成的 WAL 段调用。因此,如果服务器产生的 WAL 流量很小(或者存在低谷期),事务完成到其被安全写入归档存储之间可能会有很长延迟。为了限制未归档数据可能有多旧,你可以设置,使服务器强制切换到新 WAL 段文件的间隔不超过这个值。注意,由强制切换而提前归档的文件长度仍与装满的文件相同。因此,把archive_timeout设得很短并不明智,这会使归档存储膨胀。archive_timeout设为大约 1 分钟通常是合理的。 @@ -438,7 +434,7 @@ test ! -f /mnt/server/archivedir/00000001000000A900000065 && cp pg_wal/0 - 恢复增量备份时,不仅需要增量备份本身,还必须具有所有更早的备份,以便提供增量备份中省略的那些块。关于这项要求的更多信息见。请注意,当集簇的校验和状态发生变化时,使用pg_combinebackup会受到限制;参见pg_combinebackup limitations。 + 恢复增量备份时,不仅需要增量备份本身,还必须具有提供增量备份中省略的块所需的所有较早备份。关于这项要求的更多信息见。请注意,当集簇的校验和状态发生变化时,使用pg_combinebackup会受到限制;参见pg_combinebackup 的限制。 @@ -446,7 +442,7 @@ test ! -f /mnt/server/archivedir/00000001000000A900000065 && cp pg_wal/0 - 增量备份通常只对相对较大的数据库有意义,因为其中相当一部分数据不变,或者变化缓慢。对于小数据库,忽略增量备份的存在而直接进行完整备份会更简单,也更容易管理。对于所有数据都被频繁修改的大数据库,增量备份也不会比完整备份小多少。 + 增量备份通常只对相当一部分数据不变或变化缓慢的较大数据库有意义。对于小数据库,忽略增量备份的存在而直接进行完整备份会更简单,也更容易管理。对于所有数据都被频繁修改的大数据库,增量备份也不会比完整备份小多少。 @@ -610,7 +606,7 @@ SELECT * FROM pg_backup_stop(wait_for_archive => true); - 这一切的关键在于设置一个恢复配置,描述你希望如何恢复,以及恢复应运行到什么位置。其中绝对必须指定的一项是restore_command,它告诉PostgreSQL如何检索已归档的 WAL 文件段。像archive_command一样,它也是一个 shell 命令字符串。它可以包含%f,会被替换为所需 WAL 文件的名称;也可以包含%p,会被替换为复制该 WAL 文件时要使用的路径名。(该路径名相对于当前工作目录,也就是集簇的数据目录。)如果需要在命令中嵌入实际的%字符,请写成%%。最简单而有用的命令类似如下: + 这一切的关键在于设置一个恢复配置,描述你希望如何恢复,以及恢复应运行到什么位置。其中绝对必须指定的一项是restore_command,它告诉PostgreSQL如何检索已归档的 WAL 段文件。像archive_command一样,它也是一个 shell 命令字符串。它可以包含%f,会被替换为所需 WAL 文件的名称;也可以包含%p,会被替换为复制该 WAL 文件时要使用的路径名。(该路径名相对于当前工作目录,也就是集簇的数据目录。)如果需要在命令中嵌入实际的%字符,请写成%%。最简单而有用的命令类似如下: restore_command = 'cp /mnt/server/archivedir/%f %p' @@ -618,11 +614,11 @@ restore_command = 'cp /mnt/server/archivedir/%f %p' - 重要的是,该命令在失败时必须返回非零退出状态。系统调用该命令来请求归档中不存在的文件;遇到这种情况时,它就应返回非零值。这不是一种错误情况。例外是,如果该命令被信号终止(用于数据库服务器关闭的SIGTERM除外),或者因 shell 错误(如命令未找到)而失败,那么恢复将中止,服务器也不会启动。 + 重要的是,该命令在失败时必须返回非零退出状态。系统调用该命令来请求归档中不存在的文件;遇到这种情况时,它必须返回非零值。这不是一种错误情况。例外是,如果该命令被信号终止(用于数据库服务器关闭的SIGTERM除外),或者因 shell 错误(如命令未找到)而失败,那么恢复将中止,服务器也不会启动。 - 被请求的文件并不全都是 WAL 段文件;你还应预期会收到对带有.history后缀文件的请求。另外请注意,%p路径的基本文件名会与%f不同;不要指望它们可以互换使用。 + 被请求的文件并不全都是 WAL 段文件;你还应预期会收到对带有.history后缀文件的请求。另外请注意,%p路径的文件名部分会与%f不同;不要指望它们可以互换使用。 @@ -630,16 +626,16 @@ restore_command = 'cp /mnt/server/archivedir/%f %p' - 通常,恢复会处理完所有可用的 WAL 段,从而把数据库恢复到当前时间点(或者在可用 WAL 段所允许的情况下尽可能接近当前时间点)。因此,一次正常恢复通常会以一条file not found消息结束,具体错误文本取决于你选择的restore_command。在恢复开始时,你也可能看到一条针对类似00000001.history文件的错误消息。这同样是正常的,在简单恢复场景中并不表示有问题;相关讨论见。 + 通常,恢复会处理完所有可用的 WAL 段,从而把数据库恢复到当前时间点(或者在可用 WAL 段所允许的情况下尽可能接近当前时间点)。因此,一次正常恢复会以一条file not found消息结束,具体错误文本取决于你选择的restore_command。在恢复开始时,你也可能看到一条针对类似00000001.history文件的错误消息。这同样是正常的,在简单恢复场景中并不表示有问题;相关讨论见 - 如果你希望恢复到过去的某个时间点(例如恢复到那位初级 DBA 删掉你的主事务表之前),只需指定所需的停止点即可。这个停止点也称为恢复目标,可以通过日期/时间、命名恢复点或者某个特定事务 ID 完成时刻来指定。在目前的实现下,只有日期/时间和命名恢复点这两种方式真正比较实用,因为没有工具能够帮助你足够准确地识别应使用哪个事务 ID。 + 如果你希望恢复到过去的某个时间点(例如恢复到那位初级 DBA 删掉你的主事务表之前),只需指定所需的停止点即可。这个停止点也称为恢复目标,可以通过日期/时间、命名恢复点或者某个特定事务 ID 完成时刻来指定。在撰写本文时,只有日期/时间和命名恢复点这两种方式真正比较实用,因为没有工具能够帮助你足够准确地识别应使用哪个事务 ID。 - 停止点必须晚于基础备份的结束时间,也就是pg_backup_stop的结束时间。你不能用某次基础备份恢复到该备份仍在进行中的时间点。(若要恢复到这样的时间点,必须回到更早的一次基础备份,再从那里向前滚动。) + 停止点必须晚于基础备份的结束时间,也就是pg_backup_stop的结束时间。你不能用某次基础备份恢复到该备份仍在进行中的时间点。(若要恢复到这样的时间点,必须回到更早的一次基础备份,再从那里向前重放日志。) @@ -653,12 +649,10 @@ restore_command = 'cp /mnt/server/archivedir/%f %p' 时间线 - timelines + 时间线 - - 把数据库恢复到过去某个时间点的能力,会带来一些复杂性,颇有点像关于时间旅行和平行宇宙的科幻小说。例如,在数据库的原始历史中,假设你在星期二晚上 5:15 删掉了一张关键表,但直到星期三中午才意识到自己的错误。于是你拿出备份,把系统恢复到星期二晚上 5:14,并重新上线运行。在数据库宇宙的这条历史中,你从未删掉那张表。但如果你后来发现这并不是个好主意,并且想回到原始历史中的星期三上午某个时间点,就办不到了,因为在数据库重新上线运行期间,它可能已经覆盖了某些 WAL 段文件,而这些文件本来能把你带回到现在想回去的那个时刻。因此,为了避免这种情况,你需要把时间点恢复之后生成的那一串 WAL 记录,与数据库原始历史中生成的那些 WAL 记录区分开来。 - + 能够将数据库恢复到过去某个时间点,也会带来一些类似科幻故事中时间旅行和平行宇宙的复杂情况。例如,假设在数据库原来的历史中,你在周二下午 5:15 删除了一张重要的表,直到周三中午才发现错误。你从容地取出备份,将数据库恢复到周二下午 5:14,然后重新投入运行。在数据库宇宙的这段历史中,你从未删除过那张表。但假设你后来发现这样做不太合适,希望回到原来历史中的周三上午某个时刻。如果数据库恢复运行后覆盖了通往该时刻所需的某些 WAL 段文件,就无法回去了。因此,为了避免这种情况,需要区分时间点恢复后产生的一系列 WAL 记录与数据库原来历史中产生的记录。 为了解决这个问题,PostgreSQL引入了时间线的概念。每当一次归档恢复完成时,系统都会创建一条新的时间线,用来标识此次恢复之后生成的 WAL 记录序列。时间线 ID 是 WAL 段文件名的一部分,因此新的时间线不会覆盖先前时间线产生的 WAL 数据。例如,在 WAL 文件名0000000100001234000055CD中,开头的00000001就是十六进制表示的时间线 ID。(注意,在服务器日志消息等其他场合,时间线 ID 通常以十进制打印。) @@ -672,9 +666,7 @@ restore_command = 'cp /mnt/server/archivedir/%f %p' 每当创建一条新的时间线时,PostgreSQL都会创建一个时间线历史文件,记录它是从哪条时间线、在何时分叉出来的。当从包含多条时间线的归档中恢复时,这些历史文件对于系统选取正确的 WAL 段文件是必需的。因此,它们会像 WAL 段文件一样被归档到 WAL 归档区域。历史文件只是很小的文本文件,因此长期保存它们既便宜也合适(而段文件通常很大)。如果你愿意,还可以在历史文件中加入注释,记录创建这条时间线的方式和原因。当你因实验而积累出一批错综复杂的时间线时,这类注释会特别有价值。 - - 恢复的默认行为是恢复到归档中找到的最新时间线。如果你希望恢复到执行基础备份时的当前时间线,或者恢复到某个指定的子时间线(也就是说,你想回到某个本身就是在一次恢复尝试之后才产生的状态),就需要指定current,或者在中指定目标时间线 ID。你不能恢复到那些在基础备份之前就已经分叉出去的时间线。 - + 默认的恢复行为是恢复到归档中找到的最新时间线。如果希望恢复到制作基础备份时的当前时间线,或者某条特定的子时间线(即希望返回到一次恢复尝试之后产生的某个状态),需要在 中指定 current 或目标时间线 ID。不能恢复到在基础备份之前就已分支出去的时间线。 @@ -685,14 +677,14 @@ restore_command = 'cp /mnt/server/archivedir/%f %p' - 单机热备份 + 独立热备份 - 可以利用PostgreSQL的备份设施生成单机热备份。这些备份不能用于时间点恢复,但它们的制作和恢复通常都比pg_dump转储快得多。(它们也比pg_dump转储大得多,因此在某些情况下速度优势可能会被抵消。) + 可以利用PostgreSQL的备份设施生成独立热备份。这些备份不能用于时间点恢复,但它们的制作和恢复通常都比pg_dump转储快得多。(它们也比pg_dump转储大得多,因此在某些情况下速度优势可能会被抵消。) - 和基础备份一样,生成单机热备份最简单的方法是使用工具。如果在调用它时包含-X参数,使用该备份所需的全部预写式日志都会自动包含在备份中,恢复该备份时也不需要额外动作。 + 和基础备份一样,生成独立热备份最简单的方法是使用工具。如果在调用它时包含-X参数,使用该备份所需的全部预写式日志都会自动包含在备份中,恢复该备份时也不需要额外动作。 @@ -723,7 +715,7 @@ archive_command = 'local_backup_script.sh "%p" "%f"' - 脚本中可能需要解决的需求示例包括: + 可以在脚本中处理的需求示例包括: @@ -732,7 +724,7 @@ archive_command = 'local_backup_script.sh "%p" "%f"' - 把 WAL 文件成批处理,使其每三个小时传输一次,而不是每生成一个就传一次 + 把 WAL 文件成批处理,使其每三个小时传输一次,而不是每次只传输一个 diff --git a/zh/18/brin.sgml b/zh/18/brin.sgml index cc6cc7b1..deeaac0f 100644 --- a/zh/18/brin.sgml +++ b/zh/18/brin.sgml @@ -4,7 +4,7 @@ BRIN 索引 - index + 索引 BRIN @@ -25,8 +25,7 @@ - 如果索引中存储的摘要信息与查询条件相一致BRIN - 索引就可以通过常规位图索引扫描来满足查询,并返回每个范围内所有页上的全部元组。 + BRIN 索引可以通过常规位图索引扫描来满足查询;对于每个范围,如果索引中存储的摘要信息与查询条件相一致,就会返回该范围内所有页上的全部元组。 查询执行器负责重新检查这些元组,并丢弃不匹配查询条件的元组 — 换句话说,这些索引是有损的。 由于 BRIN 索引非常小,与顺序扫描相比,扫描索引只会带来很小的额外开销, 但可以避免扫描那些已知不包含匹配元组的大块表数据。 @@ -85,7 +84,7 @@ 当启用自动摘要时,一旦检测到向下一个块范围第一页的第一项执行了插入, - 就会向 autovacuum 发送请求,要求对该块范围执行定向摘要。 + 就会向 autovacuum 发送请求,要求对前一个块范围执行定向摘要。 该请求会在同一数据库中的某个 autovacuum 工作进程下一次结束运行时得到处理。 如果请求队列已满,该请求就不会被记录,并会向服务器日志发送一条消息: @@ -790,13 +789,13 @@ LOG: request for BRIN range summarization for index "brin_wi_idx" page 128 was typedef struct BrinOpcInfo { - /* Number of columns stored in an index column of this opclass */ + /* 此操作符类在一个索引列中存储的列数 */ uint16 oi_nstored; - /* Opaque pointer for the opclass' private use */ + /* 供操作符类私有使用的不透明指针 */ void *oi_opaque; - /* Type cache entries of the stored columns */ + /* 所存储列的类型缓存条目 */ TypeCacheEntry *oi_typcache[FLEXIBLE_ARRAY_MEMBER]; } BrinOpcInfo; @@ -1012,62 +1011,62 @@ typedef struct BrinOpcInfo 操作符策略 1 - left-of 操作符 + 位于左侧的操作符 操作符策略 4 操作符策略 2 - does-not-extend-to-the-right-of 操作符 + 不延伸到右侧的操作符 操作符策略 5 操作符策略 3 - overlaps 操作符 + 重叠操作符 操作符策略 4 - does-not-extend-to-the-left-of 操作符 + 不延伸到左侧的操作符 操作符策略 1 操作符策略 5 - right-of 操作符 + 位于右侧的操作符 操作符策略 2 - 操作符策略 6, 18 - same-as-or-equal-to 操作符 + 操作符策略 6、18 + 相同或等于操作符 操作符策略 7 - 操作符策略 7, 16, 24, 25 - contains-or-equal-to 操作符 + 操作符策略 7、16、24、25 + 包含或等于操作符 - 操作符策略 8, 26, 27 - is-contained-by-or-equal-to 操作符 + 操作符策略 8、26、27 + 被包含或等于操作符 操作符策略 3 操作符策略 9 - does-not-extend-above 操作符 + 不延伸到上方的操作符 操作符策略 11 操作符策略 10 - is-below 操作符 + 位于下方的操作符 操作符策略 12 操作符策略 11 - is-above 操作符 + 位于上方的操作符 操作符策略 9 操作符策略 12 - does-not-extend-below 操作符 + 不延伸到下方的操作符 操作符策略 10 @@ -1113,12 +1112,12 @@ typedef struct BrinOpcInfo 要为仅实现等值操作符且支持哈希的数据类型编写操作符类,可以按 - 所示,将 bloom 支持过程与相应操作符一起使用。 - 所有操作符类成员(过程和操作符)都是必需的。 + 所示,将 bloom 支持函数与相应操作符一起使用。 + 所有操作符类成员(函数和操作符)都是必需的。 - bloom 操作符类的过程和支持编号 + bloom 操作符类的函数和支持编号 @@ -1128,28 +1127,28 @@ typedef struct BrinOpcInfo - 支持过程 1 + 支持函数 1 内部函数brin_bloom_opcinfo() - 支持过程 2 + 支持函数 2 内部函数brin_bloom_add_value() - 支持过程 3 + 支持函数 3 内部函数brin_bloom_consistent() - 支持过程 4 + 支持函数 4 内部函数brin_bloom_union() - 支持过程 5 + 支持函数 5 内部函数brin_bloom_options() - 支持过程 11 - 计算元素哈希值的函数 + 支持函数 11 + 计算元素 hash 值的函数 操作符策略 1 @@ -1160,20 +1159,20 @@ typedef struct BrinOpcInfo
- 支持过程编号 1 至 10 保留给 BRIN 内部函数,因此 SQL 层函数从编号 11 开始。 + 支持函数编号 1 至 10 保留给 BRIN 内部函数,因此 SQL 层函数从编号 11 开始。 支持函数 11 是构建索引所需的主要函数。 - 它应接受一个与操作符类数据类型相同的参数,并返回该值的哈希值。 + 它应接受一个与操作符类数据类型相同的参数,并返回该值的 hash 值。 minmax-multi 操作符类也面向实现全序集的数据类型,可以看作 minmax 操作符类的简单扩展。 minmax 操作符类把每个块范围中的值摘要为单个连续区间,而 minmax-multi 则允许将其摘要为多个较小区间,以改进对离群值的处理。 - 可以按 所示,将 minmax-multi 支持过程与相应操作符一起使用。 - 所有操作符类成员(过程和操作符)都是必需的。 + 可以按 所示,将 minmax-multi 支持函数与相应操作符一起使用。 + 所有操作符类成员(函数和操作符)都是必需的。 - minmax-multi 操作符类的过程和支持编号 + minmax-multi 操作符类的函数和支持编号 @@ -1183,27 +1182,27 @@ typedef struct BrinOpcInfo - 支持过程 1 + 支持函数 1 内部函数brin_minmax_multi_opcinfo() - 支持过程 2 + 支持函数 2 内部函数brin_minmax_multi_add_value() - 支持过程 3 + 支持函数 3 内部函数brin_minmax_multi_consistent() - 支持过程 4 + 支持函数 4 内部函数brin_minmax_multi_union() - 支持过程 5 + 支持函数 5 内部函数brin_minmax_multi_options() - 支持过程 11 + 支持函数 11 计算两个值之间距离(范围长度)的函数 diff --git a/zh/18/btree.sgml b/zh/18/btree.sgml index 4f6b9006..845b6433 100644 --- a/zh/18/btree.sgml +++ b/zh/18/btree.sgml @@ -4,7 +4,7 @@ B-树索引 - index + 索引 B-树 @@ -18,10 +18,10 @@ - 由于每个 B-树 操作符类都会为其数据类型施加一种排序顺序,B-树 + 由于每个 B-树操作符类都会为其数据类型施加一种排序顺序,B-树 操作符类(更准确地说,是操作符族)已经成为 PostgreSQL 用来统一表示和理解排序语义的方式。因此,它们具备了一些超出单纯支持 - B-树 索引所需范围的特性,系统中某些与 btree AM + B-树索引所需范围的特性,系统中某些与 B-树 AM 相距甚远的部分也会利用它们。 @@ -55,7 +55,7 @@ - = 操作符必须是一种等价关系;也就是说,对于该数据类型的所有非空值 + = 操作符必须是一种等价关系;也就是说,对于该数据类型的所有非 null 值 ABC: @@ -93,7 +93,7 @@ - < 操作符必须是一种强排序关系;也就是说,对于所有非空值 + < 操作符必须是一种强排序关系;也就是说,对于所有非 null 值 ABC: @@ -123,7 +123,7 @@ - 此外,该顺序还是全序的;也就是说,对于所有非空值 + 此外,该顺序还是全序的;也就是说,对于所有非 null 值 AB: @@ -177,18 +177,18 @@ B-树支持函数 - 如所示,btree 定义了一个必需和五个可选的支持函数。六个用户定义的方法如下: + 如所示,B-树定义了一个必需和五个可选的支持函数。六个用户定义的方法如下: order - 对于 B-树 操作符族为其提供比较操作符的每一种数据类型组合,都必须提供一个比较支持函数。该函数在 + 对于 B-树操作符族为其提供比较操作符的每一种数据类型组合,都必须提供一个比较支持函数。该函数在 pg_amproc 中注册,支持函数编号为 1,并且 amproclefttype/amprocrighttype 要等于该比较的左右数据类型(也就是与匹配操作符在 - pg_amop 中注册时相同的数据类型)。比较函数必须接受两个非空值 + pg_amop 中注册时相同的数据类型)。比较函数必须接受两个非 null 值 AB,并返回一个 int32 值,其值为 < 0、 @@ -197,12 +197,12 @@ < BA = BA - > B。不允许返回空值:该数据类型的所有值都必须可比较。示例见 + > B。不允许返回 null:该数据类型的所有值都必须可比较。示例见 src/backend/access/nbtree/nbtcompare.c - 如果参与比较的值属于可排序数据类型,则会通过标准的 + 如果参与比较的值属于支持排序规则的数据类型,则会通过标准的 PG_GET_COLLATION() 机制,把适当的排序规则 OID 传递给比较支持函数。 @@ -223,11 +223,11 @@ in_range - in_range support functions + in_range 支持函数 - support functions + 支持函数 in_range @@ -266,7 +266,7 @@ returns bool - in_range 函数的核心语义取决于这两个 Boolean + in_range 函数的核心语义取决于这两个布尔 标志参数。它应当先对 baseoffset 做加法或减法,再把 val 与结果比较,具体如下: @@ -383,7 +383,7 @@ returns bool - 如果被排序的类型(type1)属于可排序数据类型,则会通过标准的 + 如果被排序的类型(type1)属于支持排序规则的数据类型,则会通过标准的 PG_GET_COLLATION() 机制,把适当的排序规则 OID 传递给 in_range 函数。 @@ -408,12 +408,7 @@ returns bool equalimage(opcintype oid) returns bool - 返回值是关于某个操作符类及其排序规则的静态信息。返回 - true 表示:该操作符类的 - order 函数被保证只有在返回 - 0arguments are equal)时,其 - AB - 参数才是可以互换而不损失任何语义信息的。如果未注册 + 返回值是关于某个操作符类及其排序规则的静态信息。返回 true 表示可以保证:该操作符类的 order 函数只有在其 AB 参数也能够互换而不损失任何语义信息时,才会返回 0参数相等)。如果未注册 equalimage 函数,或其返回 false,就表示不能假定该条件成立。 @@ -421,7 +416,7 @@ equalimage(opcintype oid) returns bool opcintype 参数是该操作符类所索引数据类型的 pg_type.oid。这只是为了方便在不同操作符类之间复用同一个底层 equalimage 函数。如果 - opcintype 是可排序数据类型,则会通过标准的 + opcintype 是支持排序规则的数据类型,则会通过标准的 PG_GET_COLLATION() 机制,把适当的排序规则 OID 传递给 equalimage 函数。 @@ -453,7 +448,7 @@ equalimage(opcintype oid) returns bool 发行版中包含的操作符类遵循的惯例是:注册一个现成的通用 equalimage 函数。大多数操作符类注册 btequalimage(),这表示去重在无条件下都是安全的。像 - text 这样可排序数据类型的操作符类会注册 + text 这样支持排序规则的数据类型的操作符类会注册 btvarstrequalimage(),这表示在确定性排序规则下去重是安全的。第三方扩展的最佳实践则是注册它们自己的自定义函数,以保留控制权。 @@ -493,19 +488,19 @@ options(relopts local_relopts *) returns skipsupport - 可选地,B-树 操作符族可以提供skip 支持函数,注册为支持函数编号 + 可选地,B-树操作符族可以提供跳过支持函数,注册为支持函数编号 6。这些函数为 B-树 代码提供了一种按键空间顺序遍历某个操作符类底层输入类型所能表示的全部可能值的方法。当核心代码应用跳过扫描优化时,就会用到它。相关 API 定义在 src/include/utils/skipsupport.h 中。 - 没有提供 skip 支持函数的操作符类,仍然可以使用跳过扫描。核心代码仍可采用其后备策略,尽管对于某些离散类型来说,这种策略可能并非最优。对于连续类型上的操作符类,提供 - skip 支持函数通常没有意义(甚至可能不可行)。 + 没有提供跳过支持函数的操作符类,仍然可以使用跳过扫描。核心代码仍可采用其后备策略,尽管对于某些离散类型来说,这种策略可能并非最优。对于连续类型上的操作符类,提供 + 跳过支持函数通常没有意义(甚至可能不可行)。 操作符族注册跨类型的 skipsupport - 函数并不合理,尝试这样做会导致错误。因为要确定下一个可被索引的值,必须通过递增一个从索引元组复制出来的值来完成。所生成的值都必须属于同一种底层数据类型(也就是被跳过的索引列的 opclass 输入类型)。 + 函数并不合理,尝试这样做会导致错误。因为要确定下一个可被索引的值,必须通过递增一个从索引元组复制出来的值来完成。所生成的值都必须属于同一种底层数据类型(也就是被跳过的索引列的操作符类输入类型)。 @@ -547,7 +542,7 @@ options(relopts local_relopts *) returns B-树索引会通过执行自底向上索引删除轮次,增量地删除这类版本频繁更替产生的索引元组。每一轮删除都是因预期中的版本频繁更替页拆分而触发的。这只会发生在那些没有被 - UPDATE 语句逻辑修改的索引上,否则过时版本就会集中积累在某些特定页面中。通常可以避免页拆分,不过也可能出现某些实现层面的启发式规则甚至一个垃圾索引元组都识别不出来、删不掉的情况(这时就要靠页拆分或一次去重轮次来解决新元组放不进叶页的问题)。任何一次索引扫描在单个逻辑行上必须穿越的最坏版本数,是影响整个系统响应能力和吞吐量的重要因素。一次自底向上索引删除轮次会基于涉及逻辑行与版本的定性区别,针对单个叶页中疑似垃圾的元组。这与自动清理工作进程执行的自顶向下索引清理不同,后者是在超出某些定量的表级阈值时触发的(见)。 + UPDATE 语句逻辑修改的索引上;如果不执行这类删除,过时版本就会集中积累在某些特定页面中。通常可以避免页拆分,不过也可能出现某些实现层面的启发式规则甚至一个垃圾索引元组都识别不出来、删不掉的情况(这时就要靠页拆分或一次去重轮次来解决新元组放不进叶页的问题)。任何一次索引扫描在单个逻辑行上必须穿越的最坏版本数,是影响整个系统响应能力和吞吐量的重要因素。一次自底向上索引删除轮次会基于涉及逻辑行与版本的定性区别,针对单个叶页中疑似垃圾的元组。这与自动清理工作进程执行的自顶向下索引清理不同,后者是在超出某些定量的表级阈值时触发的(见)。 @@ -587,7 +582,7 @@ options(relopts local_relopts *) returns 去重通过周期性地把一组组重复元组合并起来,为每一组形成一个 - posting list 元组。在这种表示中,列键值只出现一次,后面跟着一个排好序的 + 倒排列表 元组。在这种表示中,列键值只出现一次,后面跟着一个排好序的 TID 数组,指向表中的各行。这能显著减小那些每个值(或每一种不同列值组合)平均会出现多次的索引的存储大小。查询延迟可能显著降低,整体查询吞吐量也可能显著提升,例行索引清理的开销同样可能显著减少。 @@ -601,14 +596,14 @@ options(relopts local_relopts *) returns 去重过程是惰性发生的:当插入一个放不进现有叶页的新项时,只有在索引元组删除也无法为该新项释放足够空间的情况下,才会进行去重(通常只会短暂考虑删除,然后就跳过)。与 - GIN 的 posting list 元组不同,B-树的 posting list - 元组不需要在每次插入新的重复项时都扩展;它们只是叶页原始逻辑内容的一种替代物理表示。这种设计优先考虑混合读写工作负载下的一致性能。大多数客户端应用至少都能从去重中获得适度的性能收益。去重默认启用。 + GIN 的倒排列表元组不同,B-树的倒排列表 + 元组不需要在每次插入新的重复项时都扩展;它们只是叶页原始逻辑内容的一种替代物理表示。这种设计优先考虑混合读写工作负载下的稳定性能。大多数客户端应用至少都能从去重中获得适度的性能收益。去重默认启用。 CREATE INDEXREINDEX - 都会应用去重来创建 posting list - 元组,只是两者采用的策略略有不同。对于从表中取出的已排序输入中遇到的每一组普通重复元组,都会在被加入当前待写入叶页之前先合并成一个 - posting list 元组。每个 posting list 元组都会尽量容纳更多的 + 都会应用去重来创建倒排列表 + 元组,不过它们采用的策略与上述过程略有不同。对于从表中取出的已排序输入中遇到的每一组普通重复元组,都会在被加入当前待写入叶页之前先合并成一个 + 倒排列表元组。每个倒排列表元组都会尽量容纳更多的 TID。叶页按通常方式写出,不需要额外独立的去重过程。由于 CREATE INDEXREINDEX 都是一次性的批处理操作,这种策略非常适合它们。 @@ -617,14 +612,14 @@ options(relopts local_relopts *) returns 如果某个写密集型工作负载由于索引中的重复值很少甚至没有,而无法从去重中获益,那么它会承担很小且固定的性能损耗(除非显式禁用去重)。 deduplicate_items 存储参数可用于在单个索引内禁用去重。而只读工作负载绝不会因此遭受性能损失,因为读取 - posting list 元组至少与读取标准元组表示一样高效。禁用去重通常并没有帮助。 + 倒排列表元组至少与读取标准元组表示一样高效。禁用去重通常并没有帮助。 有时唯一索引(以及唯一约束)也可以使用去重。这允许叶页临时吸收因版本频繁更替产生的额外重复项。唯一索引中的去重能够增强自底向上索引删除,特别是在长事务持有阻塞垃圾回收的快照时。其目标是为自底向上索引删除策略再次发挥作用争取时间。把页拆分推迟到某个单独的长事务自然结束之后,可能使一次自底向上删除轮次在较早一次失败的地方获得成功。 - 系统会应用一种特殊的启发式规则,来判定唯一索引中是否应当执行一次去重轮次。它往往可以直接跳到拆分叶页,从而避免把周期浪费在无益的去重过程中而造成性能损耗。如果你担心去重的开销,可以考虑有选择地设置 + 系统会应用一种特殊的启发式规则,来判定唯一索引中是否应当执行一次去重轮次。它往往可以直接跳到拆分叶页,从而避免把处理器周期浪费在无益的去重过程中而造成性能损耗。如果你担心去重的开销,可以考虑有选择地设置 deduplicate_items = off。在唯一索引中保持去重启用,坏处很小。 @@ -648,7 +643,7 @@ options(relopts local_relopts *) returns numeric 不能使用去重。必须保留相等的 datum - 之间的小数位数。 + 之间的显示小数位数。 diff --git a/zh/18/catalogs.sgml b/zh/18/catalogs.sgml index bc63a522..6ae2f512 100644 --- a/zh/18/catalogs.sgml +++ b/zh/18/catalogs.sgml @@ -678,7 +678,7 @@ t = 表(包括物化视图), - i = 索引. + i = 索引。 @@ -931,7 +931,7 @@
- amproclefttypeamprocrighttype列的通常解释是它们标识了一个特定支持过程所支持的操作符的左右输入类型。对于某些访问方法它们和支持过程本身的输入数据类型相匹配,而对其他的则不会匹配。对于一个索引有一个默认支持过程的概念,这些支持过程的amproclefttypeamprocrighttype都等于索引操作符类的opcintype。 + amproclefttypeamprocrighttype列的通常解释是它们标识了一个特定支持函数所支持的操作符的左右输入类型。对于某些访问方法它们和支持函数本身的输入数据类型相匹配,而对其他的则不会匹配。对于一个索引有一个默认支持函数的概念,这些支持函数的amproclefttypeamprocrighttype都等于索引操作符类的opcintype
@@ -1092,7 +1092,7 @@
atttypmod记录了在表创建时提供的类型相关数据(例如一个varchar列的最大长度)。 - 它会被传递给类型相关的输入函数和长度强制函数。对于那些不需要atttypmod的类型,这个值通常总是为-1。 + 它会被传递给类型相关的输入函数和长度强制转换函数。对于那些不需要atttypmod的类型,这个值通常为 -1。 @@ -1170,8 +1170,7 @@ atthasmissing bool
- 该列在行中完全缺失时会用到这个列的值,如果在行创建之后增加一个有非易失DEFAULT值的列,就会发生这种情况。 - 实际使用的值被存放在attmissingval列中。 + 此列有一个值,供该列在数据行中完全缺失时使用;在数据行创建之后添加带有非易失 DEFAULT 值的列时,就会出现这种情况。实际使用的值存储在 attmissingval 列中。 @@ -1201,7 +1200,7 @@ attisdropped bool
- 该列被删除且不再有效。一个删除的列仍然物理存在于表中,但是会被分析器忽略并因此无法通过SQL访问。 + 该列被删除且不再有效。一个删除的列仍然物理存在于表中,但是会被解析器忽略并因此无法通过SQL访问。 @@ -1229,7 +1228,7 @@ (引用 pg_collation.oid
- 该列被定义的排序规则,如果该列不是一个可排序数据类型则为0。 + 该列定义的排序规则;如果该列的数据类型不支持排序规则,则为零。 @@ -1252,7 +1251,7 @@ attacl aclitem[]
- 列级访问权限, 如果此列上已有特别授予的权限 + 列级访问权限,如果此列上已有特别授予的权限 @@ -1280,7 +1279,7 @@
这个列中是一个含有一个元素的数组,其中的值被用于该列在行中完全缺失时,如果在行创建之后增加一个有非易失DEFAULT值的列,就会发生这种情况。 - 只有当atthasmissing为真时才使用这个值。如果没有值则该列为空。 + 只有当atthasmissing为真时才使用这个值。如果没有值则该列为空值。 @@ -1288,9 +1287,7 @@ - 在一个被删除的列的pg_attribute的项中,atttypid被重置为0,但attlen以及其他从pg_type拷贝的域仍然有效。 - 这种安排用于处理一种情况,即被删除列的数据类型后来被删除,并且因此不再有相应的pg_type行。 - attlen和其他域可以被用来解释表的一行的内容。 + 在被删除列的 pg_attribute 条目中,atttypid 被重置为零,但 attlen 以及其他从 pg_type 复制的字段仍然有效。这种安排用于应对被删除列的数据类型后来也被删除、因而不再有相应 pg_type 行的情况。attlen 和其他字段可用于解释表中一行的内容。 @@ -1419,7 +1416,7 @@ rolconnlimit int4
- 对于可以登录的角色,本列设置该角色可以同时发起最大连接数。-1表示无限制。 + 对于可以登录的角色,本列设置该角色能够建立的最大并发连接数。-1 表示无限制。 @@ -1428,7 +1425,7 @@ rolpassword text
- 加密后的密码;如果未设置则为空。其格式取决于所使用的加密方式。 + 加密后的密码;如果未设置则为空值。其格式取决于所使用的加密方式。 @@ -1437,7 +1434,7 @@ rolvaliduntil timestamptz
- 密码过期时间(只用于密码鉴定),如果永不过期则为空 + 密码过期时间(仅用于密码认证);不设过期时间时为空值 @@ -1445,13 +1442,11 @@ - 对于一个MD5加密的密码,rolpassword列将由字符串md5后面跟上一个32字符的十六进制MD5哈希值构成。MD5哈希值将是该用户的密码串接上它们的用户名。例如,如果用户joe的密码是xyzzy,则PostgreSQL将存储xyzzyjoe的md5哈希。 + 对于一个MD5加密的密码,rolpassword列将由字符串md5后面跟上一个32字符的十六进制MD5哈希值构成。MD5 哈希值通过在用户密码后拼接用户名再计算得到。例如,如果用户joe的密码是xyzzy,则PostgreSQL将存储xyzzyjoe的md5哈希。 - - 对 MD5 加密密码的支持已被弃用,并将在未来的 PostgreSQL 发布中移除。关于迁移到其他密码类型的详细信息,请参见。 - + 对 MD5 加密密码的支持已弃用,并将在PostgreSQL的未来版本中移除。迁移到其他密码类型的详细信息见 @@ -1582,7 +1577,7 @@ SCRAM-SHA-256$<iteration count>:&l - 需要注意的是,pg_cast并不表示系统知道如何执行的所有类型转换,它只包括那些不能从某些通用规则推导出的转换。例如,一个域及其基类型之间的转换并未显式地在pg_cast中展示。另一个重要的例外是自动的基于 I/O 的类型转换,它们通过数据类型自己的 I/O 函数来转换成(或者转换自)text或其他字符串类型,这些转换也没有显式地在pg_cast中表示。 + 需要注意的是,pg_cast并不表示系统知道如何执行的所有类型转换,它只包括那些不能从某些通用规则推导出的转换。例如,一个域及其基础类型之间的转换并未显式地在pg_cast中展示。另一个重要的例外是自动的基于 I/O 的类型转换,它们通过数据类型自己的 I/O 函数来转换成(或者转换自)text或其他字符串类型,这些转换也没有显式地在pg_cast中表示。 @@ -1687,7 +1682,7 @@ SCRAM-SHA-256$<iteration count>:&l - 目录pg_class描述了具有列或与表类似的其他对象。这包括索引(但请参见pg_index)、序列(但请参见pg_sequence)、视图、物化视图、复合类型和TOAST表;请参见relkind。 + 目录pg_class描述了表以及其他具有列或在其他方面与表类似的对象。这包括索引(但请参见pg_index)、序列(但请参见pg_sequence)、视图、物化视图、复合类型和TOAST表;请参见relkind。 在下面,当我们指的是所有这些类型的对象时,我们称之为关系(relations)。并非所有pg_class的列对所有关系类型都有意义。 @@ -1739,9 +1734,7 @@ SCRAM-SHA-256$<iteration count>:&l reltype oid (引用 pg_type.oid) - - 该关系可能对应的表行类型的数据类型 OID;对索引为 0,而序列和 TOAST 表没有pg_type项 - + 与此表的行类型对应的数据类型的 OID(如有);索引、序列和 TOAST 表没有pg_type项,此值为零 @@ -1876,7 +1869,7 @@ SCRAM-SHA-256$<iteration count>:&l relpersistence char - p = 永久表/序列, u = 不记录 WAL 的表/序列, + p = 永久表/序列,u = 不记录 WAL 的表/序列, t = 临时表/序列 @@ -1971,7 +1964,7 @@ SCRAM-SHA-256$<iteration count>:&l relispopulated bool - 如果表已被填充则为真(对于所有关系该列都为真,但对于某些物化视图却不是) + 如果关系已被填充则为真(对于所有关系该列都为真,但对于某些物化视图却不是) @@ -2013,7 +2006,7 @@ SCRAM-SHA-256$<iteration count>:&l relfrozenxid xid - 在此之前的所有事务ID在表中已经被替换为一个永久的(冻结的) 事务ID。 + 在此之前的所有事务ID在表中已经被替换为一个永久的(冻结的)事务ID。 这用于跟踪表是否需要被清理,以便阻止事务ID回卷或者允许pg_xact被收缩。 如果该关系不是一个表则为0(InvalidTransactionId)。 @@ -2024,7 +2017,7 @@ SCRAM-SHA-256$<iteration count>:&l relminmxid xid - 在此之前的多事务ID在表中已经被替换为一个事务ID。这被用于跟踪表是否需要被清理,以阻止 + 在此之前的所有多事务ID在表中已经被替换为一个事务ID。这被用于跟踪表是否需要被清理,以阻止 多事务ID回卷或者允许pg_multixact被收缩。如果关系不是一个表则 为0(InvalidMultiXactId)。 @@ -2053,7 +2046,7 @@ SCRAM-SHA-256$<iteration count>:&l relpartbound pg_node_tree - 如果表示一个分区(见relispartition),则为分区边界的内部表示 + 如果表是一个分区(见relispartition),则为分区边界的内部表示 @@ -2061,9 +2054,9 @@ SCRAM-SHA-256$<iteration count>:&l
- pg_class中的一些逻辑标志被以一种懒惰的方式维护:在正确状态时它们被保证为真,但是当条件不再为真时它们并不会被立刻重置为假。 + pg_class中的一些布尔标志采用延迟维护:当条件成立时,保证它们为真;但当条件不再成立时,可能不会立即将它们重置为假。 例如,relhasindexCREATE INDEX设置,但它从不会被DROP INDEX清除。 - 作为替代,VACUUM会在找到无索引表后清除其relhasindex。 + 作为替代,VACUUM会在找到无索引表后清除其relhasindex。 这种安排避免了竞争条件并且提高了并发性。 @@ -2137,9 +2130,10 @@ SCRAM-SHA-256$<iteration count>:&l collprovider char - 排序规则提供者:d = 数据库默认值, + 排序规则提供程序:d = 数据库默认值, b = builtin,c = libc, - i = icu + i = icu + @@ -2165,7 +2159,7 @@ SCRAM-SHA-256$<iteration count>:&l collcollate text - 此排序规则对象的 LC_COLLATE。如果提供者不是 libc,则 collcollate 为 + 此排序规则对象的 LC_COLLATE。如果提供程序不是 libc,则 collcollateNULL,改用 colllocale @@ -2175,7 +2169,7 @@ SCRAM-SHA-256$<iteration count>:&l collctype text - 此排序规则对象的 LC_CTYPE。如果提供者不是 libc,则 collctype 为 + 此排序规则对象的 LC_CTYPE。如果提供程序不是 libc,则 collctypeNULL,改用 colllocale @@ -2185,7 +2179,7 @@ SCRAM-SHA-256$<iteration count>:&l colllocale text - 此排序规则对象的提供者区域设置名称。如果提供者是 libc, + 此排序规则对象的提供程序区域设置名称。如果提供程序是 libc, 则 colllocaleNULL; 改用 collcollatecollctype。 @@ -2206,7 +2200,7 @@ SCRAM-SHA-256$<iteration count>:&l collversion text - 排序规则的提供者相关的版本。这是在排序规则创建时记录下来的,并且在使用排序规则时会被检查以检测可能导致数据损坏的排序规则定义的改变。 + 提供程序特有的排序规则版本。它会在创建排序规则时记录下来,并在使用时接受检查,以检测可能导致数据损坏的排序规则定义更改。 @@ -2552,9 +2546,9 @@ SCRAM-SHA-256$<iteration count>:&l - 在一个排他约束的情况中, conkey只对约束元素是单一列引用时有用。 - 对于其他情况,conkey为0且必须查阅相关索引来发现被约束的表达式。 - (对于索引,conkey因此和pg_index.indkey具有相同的内容)。 + 对于排他约束,conkey仅对作为简单列引用的约束元素有用。 + 对于其他情况,conkey中会出现一个 0,必须查阅关联索引来确定被约束的表达式。 + (因此,conkey与该索引的 pg_index.indkey具有相同的内容。) @@ -2748,8 +2742,9 @@ SCRAM-SHA-256$<iteration count>:&l datlocprovider char - 此数据库的区域设置提供者:b = builtin, - c = libc,i = icu + 此数据库的区域设置提供程序:b = builtin, + c = libc,i = icu + @@ -2848,7 +2843,7 @@ SCRAM-SHA-256$<iteration count>:&l datlocale text - 此数据库的提供者区域设置名称。如果提供者是 libc, + 此数据库的提供程序区域设置名称。如果提供程序是 libc, 则 datlocaleNULL; 改用 datcollatedatctype。 @@ -2869,7 +2864,7 @@ SCRAM-SHA-256$<iteration count>:&l datcollversion text - 该排序规则的提供者特定版本。它会在创建数据库时记录下来,并在使用时接受检查,以检测可能导致数据损坏的排序规则定义更改。 + 提供程序特有的排序规则版本。它会在创建数据库时记录下来,并在使用时接受检查,以检测可能导致数据损坏的排序规则定义更改。 @@ -3951,7 +3946,7 @@ SCRAM-SHA-256$<iteration count>:&l indisunique bool - 如为真, 这是唯一索引 + 如为真, 这是唯一索引 @@ -3960,8 +3955,8 @@ SCRAM-SHA-256$<iteration count>:&l indnullsnotdistinct bool - 该值只用于唯一索引。如果为 false,则该唯一索引会将 null 值视为非重复值(因此索引中可以包含多个 null 值,这是 PostgreSQL 的默认行为)。 - 如果为 true,则会将 null 值视为相等(因此索引中只能包含一个 null 值)。 + 该值只用于唯一索引。如果为 false,则该唯一索引会将 null 值视为彼此不同(因此索引的某一列中可以包含多个 null 值,这是 PostgreSQL 的默认行为)。 + 如果为 true,则会将 null 值视为相等(因此索引的某一列中只能包含一个 null 值)。 @@ -4069,7 +4064,7 @@ SCRAM-SHA-256$<iteration count>:&l (引用 pg_collation.oid - 对于索引键(indnkeyatts值)中的每一列,这包含要用于该索引的排序规则的OID,如果该列不是一种可排序数据类型则为零。 + 对于索引键(indnkeyatts值)中的每一列,这包含要用于该索引的排序规则的OID,如果该列的数据类型不支持排序规则则为零。 @@ -5141,7 +5136,7 @@ SCRAM-SHA-256$<iteration count>:&l (引用 pg_collation.oid - 对于分区键中的每一个列,这个域包含要用于分区的排序规则的OID,如果该列不是一种可排序数据类型则为零。 + 对于分区键中的每一个列,这个域包含要用于分区的排序规则的OID,如果该列的数据类型不支持排序规则则为零。 @@ -5983,7 +5978,11 @@ SCRAM-SHA-256$<iteration count>:&l - rngsubopc (加上rngcollation,如果元素类型是可排序的)决定了被该范围类型所使用的排序顺序。rngcanonical用于离散类型的元素类型。rngsubdiff是可选的,但是提供它可以提高范围类型上的GiST索引性能。 + rngsubopc(如果元素类型支持排序规则,则还包括 + rngcollation)决定范围类型所用的排序顺序。 + rngcanonical用于元素类型为离散类型的情况。 + rngsubdiff是可选的,但应当提供它, + 以提高范围类型上的 GiST 索引性能。 @@ -6671,8 +6670,8 @@ SCRAM-SHA-256$<iteration count>:&l 通常,每个已分析的表列都有一个条目,其中stainherit = false。 - 如果表具有继承子项或分区,则还会创建第二个条目,其中stainherit = true。 - 此行表示继承树上列的统计信息,即您可以通过SELECT column FROM table*看到的数据的统计信息, + 如果表具有继承子表或分区,则还会创建第二个条目,其中stainherit = true。 + 此行表示继承树上列的统计信息,即你可以通过SELECT column FROM table*看到的数据的统计信息, 而stainherit = false行表示SELECT column FROM ONLY table的结果。 @@ -6681,7 +6680,7 @@ SCRAM-SHA-256$<iteration count>:&l - 因为不同类型的统计信息适用于不同类型的数据, pg_statistic 被设计成不太在意自己存储的是什么类型的统计。 只有极为常用的统计信息(比如NULL的含量)才在pg_statistic里给予专用的字段。 其它所有东西都存储在槽位中,而槽位是一组相关的列, 它们的内容用槽位中的一个列里的代码表示。 更详细的信息请参阅 src/include/catalog/pg_statistic.h。 + 由于不同种类的数据可能适合不同种类的统计信息,pg_statistic 在设计上尽量不对所存储的统计信息种类作出假定。只有极为通用的统计信息(例如空值情况)才在 pg_statistic 中有专用的列。其余统计信息都存储在槽位中。每个槽位都是一组相关的列,其内容由其中一列的代码编号来标识。更多信息见 src/include/catalog/pg_statistic.h @@ -6737,7 +6736,7 @@ SCRAM-SHA-256$<iteration count>:&l stanullfrac float4 - 列的项为空的比例 + 列中空值所占的比例 @@ -6755,8 +6754,8 @@ SCRAM-SHA-256$<iteration count>:&l stadistinct float4 - 列中非空唯一值的数目。一个大于零的值是唯一值的真正数目。 - 一个小于零的值是表中行数的乘数的负值;例如,对于一个 80% 的值为非空且每个非空值平均出现两次的列,可以表示为stadistinct = -0.4。一个0值表示唯一值的数目未知。 + 列中不同非空数据值的数量。一个大于零的值是不同值的真正数目。 + 一个小于零的值是表中行数的乘数的负值;例如,对于一个约 80% 的值为非空且每个非空值平均出现两次的列,可以表示为stadistinct = -0.4。一个0值表示不同值的数目未知。 @@ -6787,8 +6786,8 @@ SCRAM-SHA-256$<iteration count>:&l (引用 pg_collation.oid - 用于导出存储在第N槽位中的统计信息的排序规则。 - 例如,可应用排序规则列的直方图槽会显示定义数据排序顺序的排序规则。对于不可应用排序规则的数据,则为零。 + 用于生成存储在第N槽位中的统计信息的排序规则。 + 例如,支持排序规则的列的直方图槽会显示定义数据排序顺序的排序规则。对于不支持排序规则的数据,则为零。 @@ -6797,7 +6796,7 @@ SCRAM-SHA-256$<iteration count>:&l stanumbersN float4[] - 第N槽位的类型的数值类型统计, 如果该槽位不涉及数值类型则为NULL + 第N槽位中相应种类的数值统计信息;如果该槽位种类不涉及数值,则为 NULL @@ -6807,7 +6806,7 @@ SCRAM-SHA-256$<iteration count>:&l N槽位的类型的列值,如果该槽位类型不存储任何数据值则为 NULL。 - 每个数组的元素值实际上都是指定列的数据类型或者是一个相关类型(如数组元素类型), 因此,除了把这些列的类型定义成anyarray之外别无他法。 + 每个数组的元素值实际上都是指定列的数据类型或者是一个相关类型(如数组元素类型), 因此,无法把这些列的类型定义得比anyarray更具体。 @@ -6934,7 +6933,7 @@ SCRAM-SHA-256$<iteration count>:&l 统计信息对象属性中那些不是简单列引用的表达式树,以 nodeToString() 表示。 这是一个列表,每个表达式占一个元素。 - 如果所有统计信息对象属性都是简单引用,则为空。 + 如果所有统计信息对象属性都是简单引用,则为空值。 @@ -6943,8 +6942,8 @@ SCRAM-SHA-256$<iteration count>:&l - pg_statistic_ext条目在CREATE STATISTICS期间完全填充,但是随后不计算实际的统计值。 - 后来ANALYZE命令计算所需的值,并在pg_statistic_ext_data目录中填充条目。 + pg_statistic_ext条目在CREATE STATISTICS期间完全填充,但此时不会计算实际的统计值。 + 后续的ANALYZE命令计算所需的值,并在pg_statistic_ext_data目录中填充条目。 @@ -6961,14 +6960,7 @@ SCRAM-SHA-256$<iteration count>:&l - 通常,每个已分析的统计对象都有一个条目,其中stxdinherit = - false。如果表具有继承子项或分区,还会创建第二个条目,其中 - stxdinherit = true。此行表示继承树上的统计对象,即, - 您将看到的数据的统计信息 - SELECT * FROM table*, - 而stxdinherit = false行 - 表示 - SELECT * FROM ONLY table的结果。 + 通常,每个已分析的统计信息对象都有一个 stxdinherit = false 的条目。如果表有继承子表或分区,还会创建第二个 stxdinherit = true 的条目。后者表示该统计信息对象在整个继承树上的统计信息,即通过 SELECT * FROM table* 看到的数据的统计信息;而 stxdinherit = false 的行表示 SELECT * FROM ONLY table 的结果。 @@ -7038,7 +7030,7 @@ SCRAM-SHA-256$<iteration count>:&l stxdmcv pg_mcv_list - MCV(最频值)列表统计信息,序列化为pg_mcv_list类型 + MCV(高频值)列表统计信息,序列化为pg_mcv_list类型 @@ -7047,7 +7039,7 @@ SCRAM-SHA-256$<iteration count>:&l stxdexpr pg_statistic[] - 每个表达式的统计信息,序列化为pg_statistic类型的数组 + 每个表达式的统计信息,序列化为pg_statistic类型的数组。 @@ -7114,7 +7106,7 @@ SCRAM-SHA-256$<iteration count>:&l subskiplsn pg_lsn - 事务的完成LSN,其更改将被跳过,如果是有效LSN;否则0/0。 + 若为有效 LSN,则表示要跳过其更改的事务的完成 LSN;否则为 0/0 @@ -7162,7 +7154,7 @@ SCRAM-SHA-256$<iteration count>:&l 控制如何处理进行中事务的流式传输: f = 不允许对进行中事务进行流式传输, - t = 将进行中事务的更改溢写到磁盘,并在事务在发布者端提交且被订阅者接收后立即应用, + t = 将进行中事务的更改溢写到磁盘,并在事务在发布者端提交且被订阅者接收后一次性应用, p = 如果可用,则直接使用并行应用工作进程应用更改(如果没有工作进程,则与 t 相同) @@ -7649,7 +7641,7 @@ SCRAM-SHA-256$<iteration count>:&l tgdeferrable bool - 如果约束触发器可推迟则为真 + 如果约束触发器可延迟则为真 @@ -7658,7 +7650,7 @@ SCRAM-SHA-256$<iteration count>:&l tginitdeferred bool - 如果约束触发器初始可推迟则为真 + 如果约束触发器初始处于延迟状态则为真 @@ -8194,7 +8186,7 @@ SCRAM-SHA-256$<iteration count>:&l 目录pg_type存储有关数据类型的信息。 - 基类型和枚举类型(标量类型)使用CREATE TYPE创建,而域使用CREATE DOMAIN创建。 + 基础类型和枚举类型(标量类型)使用CREATE TYPE创建,而域使用CREATE DOMAIN创建。 数据库中的每一个表都会有一个自动创建的复合类型,用于表示表的行结构。 也可以使用CREATE TYPE AS创建复合类型。 @@ -8280,7 +8272,7 @@ SCRAM-SHA-256$<iteration count>:&l typtype可以是: - b表示一个基类型, + b表示一个基础类型, c表示一个复合类型(例如一个表的行类型), d表示一个域, e表示一个枚举类型, @@ -8486,7 +8478,7 @@ SCRAM-SHA-256$<iteration count>:&l - e (外部的): 值可以存储在一个次要 TOAST 关系中 (如果有一个关系, 参见pg_class.reltoastrelid). + e (外部的): 值可以存储在一个次要 TOAST 关系中 (如果有一个关系, 参见pg_class.reltoastrelid). @@ -8529,7 +8521,7 @@ SCRAM-SHA-256$<iteration count>:&l typtypmod int4 - 域使用typtypmod来记录被应用于它们基类型的typmod(如果基类型不使用typmod,则为-1)。如果此类型不是一个域则为-1。 + 域使用typtypmod来记录被应用于它们基础类型的typmod(如果基础类型不使用typmod,则为-1)。如果此类型不是一个域则为-1。 @@ -8549,8 +8541,8 @@ SCRAM-SHA-256$<iteration count>:&l typcollation指定此类型的排序规则。如果类型不支持排序规则,此列为零。 - 支持排序规则的基类型在这里会有一个非零值,典型值为DEFAULT_COLLATION_OID。 - 基于可应用排序规则类型的域,如果为其指定了排序规则 OID,则它的排序规则 OID 可以不同于其基类型。 + 支持排序规则的基础类型在这里会有一个非零值,典型值为DEFAULT_COLLATION_OID。 + 基于支持排序规则的类型的域,如果为其指定了排序规则 OID,则它的排序规则 OID 可以不同于其基础类型的排序规则 OID。 diff --git a/zh/18/charset.sgml b/zh/18/charset.sgml index 089b63c5..011ecc63 100644 --- a/zh/18/charset.sgml +++ b/zh/18/charset.sgml @@ -29,7 +29,7 @@ 区域设置支持 - locale + 区域设置 区域设置支持是指应用程序在字母表、排序、数字格式等 @@ -197,7 +197,7 @@ initdb --locale=sv_SE 以及 POSIX 风格正则表达式);区域设置既会影响大小写不敏感匹配,也会 影响字符类正则表达式中的字符分类 LIKE与区域设置 - regular expressions与区域设置 + 正则表达式与区域设置 @@ -565,10 +565,10 @@ SELECT 'N-45' < 'N-123' COLLATE mycollation5 as result; 概念 - 从概念上讲,每个可排序数据类型的表达式都有一个排序规则。(内置的可排序 - 数据类型包括textvarcharchar。 - 用户定义的基本类型也可以标记为可排序,当然,建立在可排序数据类型之上的 - 也是可排序的。) + 从概念上讲,每个支持排序规则的数据类型的表达式都有一个排序规则。 + (内置的支持排序规则的数据类型包括textvarcharchar。 + 用户定义的基础类型也可以标记为支持排序规则,当然,建立在支持排序规则的数据类型之上的 + 也支持排序规则。) 如果表达式是列引用,则该表达式的排序规则就是该列定义的排序规则。如果表 达式是常量,则其排序规则就是该常量数据类型的默认排序规则。更复杂表达式 的排序规则则按下文所述,从其输入表达式的排序规则推导出来。 @@ -593,7 +593,7 @@ SELECT 'N-45' < 'N-123' COLLATE mycollation5 as result; 对于函数或操作符调用,通过检查参数排序规则推导出的排序规则,会在运行时 - 用于执行指定操作。如果该函数或操作符调用的结果属于可排序数据类型,那么 + 用于执行指定操作。如果该函数或操作符调用的结果属于支持排序规则的数据类型,那么 在解析时它也会被用作该函数或操作符表达式的已定义排序规则,以便在外围表 达式需要知道其排序规则时使用。 @@ -675,7 +675,7 @@ SELECT a || b FROM test1; - 如果函数或操作符返回的是可排序数据类型,那么分配给该函数或操作符组合输 + 如果函数或操作符返回的是支持排序规则的数据类型,那么分配给该函数或操作符组合输 入表达式的排序规则,也被认为适用于其结果。因此,在 SELECT * FROM test1 ORDER BY a || 'foo'; @@ -721,8 +721,7 @@ SELECT * FROM test1 ORDER BY a || b COLLATE "fr_FR"; - 由icu提供的排序规则对象,对应于 ICU 库提供的具名整 - 理器。ICU 不支持将collatectype分开设 + 由icu提供的排序规则对象,对应于 ICU 库提供的具名排序器。ICU 不支持将collatectype分开设 置,因此二者总是相同的。此外,ICU 排序规则与编码无关,因此在一个数据库 中,某个给定名称的 ICU 排序规则始终只有一个。 diff --git a/zh/18/client-auth.sgml b/zh/18/client-auth.sgml index f1e62a06..d103ebe1 100644 --- a/zh/18/client-auth.sgml +++ b/zh/18/client-auth.sgml @@ -48,6 +48,21 @@ 请参见配置参数 。 + + 在启动时以及主服务器进程收到 SIGHUPSIGHUP 信号时,pg_hba.conf 文件会被读取。 + 如果你在运行中的系统上编辑了该文件,就需要通知 postmaster(使用 pg_ctl reload、调用 SQL 函数 pg_reload_conf(),或者使用 kill -HUP)重新读取该文件。 + + + + + 前面的说明不适用于 Microsoft Windows:在Windows上,pg_hba.conf文件中的任何更改会立即被应用到后续的新连接上。 + + + + + 系统视图pg_hba_file_rules 有助于预先测试对 pg_hba.conf 文件的修改,也可以在加载该文件没有产生预期效果时用于诊断问题。视图中 error 字段非空的行表示文件对应行存在问题。 + + pg_hba.conf 文件的一般格式是一组记录,每行一条。 空白行会被忽略,# 注释字符后面的任何文本也会被忽略。 @@ -67,7 +82,7 @@ - 一条记录可以有多种格式: + 一条记录可以有多种格式: local database user auth-method auth-options @@ -239,7 +254,7 @@ include_dir directory IP地址范围使用标准的数字表示法来指定起始地址,然后是斜杠(/)和一个CIDR掩码长度。 掩码长度表示客户端IP地址必须匹配的高位比特数。给定IP地址中右侧的比特应为零。 - IP地址、/和CIDR掩码长度之间不得有任何空格。 + IP地址、/和CIDR掩码长度之间不得有任何空白。 @@ -253,8 +268,7 @@ include_dir directory 以IPv4格式给出的条目将仅匹配IPv4连接,以IPv6格式给出的条目将仅匹配IPv6连接, - 即使所代表的地址在IPv4-in-IPv6范围内。请注意,如果系统的C库不支持IPv6地址, - 以IPv6格式给出的条目将被拒绝。 + 即使所代表的地址在IPv4-in-IPv6范围内。 @@ -276,12 +290,12 @@ include_dir directory 以点(.)开头的主机名规范匹配实际主机名的后缀。 因此,.example.com将匹配foo.example.com - (但不仅仅是example.com)。 + (但不匹配单独的example.com)。 当在pg_hba.conf中指定主机名时,应确保名称解析相对快速。 - 最好设置一个本地名称解析缓存,如nscd。 + 设置一个本地名称解析缓存可能会有帮助,如nscd。 此外,还可能希望启用配置参数log_hostname,以便在日志中看到客户端的主机名而不是 IP 地址。 @@ -293,7 +307,7 @@ include_dir directory 用户有时会想知道为什么主机名以这种看似复杂的方式处理,包括两次名称解析,其中包括对客户端IP地址的反向查找。 - 如果客户端的反向DNS条目未设置或生成了一些不良的主机名,则使用该功能会变得复杂。 + 如果客户端的反向DNS条目未设置或返回了不符合预期的主机名,则使用该功能会变得复杂。 这主要是为了效率:这样,连接尝试最多需要两次解析器查找,一次反向查找和一次正向查找。 如果某个地址存在解析器问题,那就只会成为该客户端的问题。 一个假设的替代实现只进行正向查找的情况下,在每次连接尝试期间都必须解析pg_hba.conf中提到的每个主机名。 @@ -308,7 +322,7 @@ include_dir directory 请注意,这种行为与其他流行的基于主机名的访问控制实现一致,例如 - Apache HTTP服务器和TCP包装器。 + Apache HTTP 服务器和 TCP Wrappers。 @@ -320,7 +334,7 @@ include_dir directory - 这两个字段可以用作IP地址/掩码长度 + 这两个字段可以用作IP-address/mask-length 表示法的替代方案。而不是指定掩码长度,实际掩码在一个单独的列中指定。 例如,255.0.0.0表示IPv4的CIDR掩码长度为8, 而255.255.255.255表示CIDR掩码长度为32。 @@ -379,9 +393,7 @@ include_dir directory 执行 SCRAM-SHA-256 或 MD5 认证以校验用户密码。详见 - - 对 MD5 加密密码的支持已被弃用,并将在未来版本的 PostgreSQL 中移除。关于迁移到其他密码类型的细节,请参阅 。 - + 对 MD5 加密密码的支持已弃用,并将在PostgreSQL的未来版本中移除。迁移到其他密码类型的详细信息见 @@ -516,11 +528,7 @@ include_dir directory auth-options - - - 在auth-method字段之后,可以是形如name=value的字段, - 用于指定认证方法的选项。关于哪些选项适用于哪些认证方法的详细信息见下文。 - + auth-method 字段之后,可以有一个或多个形如 name=value 的字段,用于指定认证方法的选项。下文会详细说明各认证方法有哪些可用选项。 除了下面列出的特定于方法的选项外,还有一个方法无关的认证选项 clientcert, @@ -533,7 +541,7 @@ include_dir directory - 对于任何使用客户端证书认证的记录(即使用 cert 认证方法的记录,或使用 clientcert 选项的记录),都可以通过 clientname 选项指定要匹配客户端证书凭据中的哪一部分。此选项有两个可选值。如果指定 clientname=CN,这也是默认值,则用户名将与证书的 Common Name (CN) 匹配。如果改为指定 clientname=DN,则用户名将与证书的完整 Distinguished Name (DN) 匹配。此选项通常最好与用户名映射配合使用。比较时使用的是 RFC 2253 格式的 DN。要查看以这种格式表示的客户端证书 DN,请执行 + 对于任何使用客户端证书认证的记录(即使用 cert 认证方法的记录,或使用 clientcert 选项的记录),都可以通过 clientname 选项指定要匹配客户端证书凭据中的哪一部分。此选项有两个可选值。如果指定 clientname=CN,这也是默认值,则用户名将与证书的 Common Name (CN) 匹配。如果改为指定 clientname=DN,则用户名将与证书的完整 Distinguished Name (DN) 匹配。此选项可能更适合与用户名映射配合使用。比较时使用的是 RFC 2253 格式的 DN。要查看以这种格式表示的客户端证书 DN,请执行 openssl x509 -in myclient.crt -noout -subject -nameopt RFC2253 | sed "s/^subject=//" @@ -575,25 +583,7 @@ openssl x509 -in myclient.crt -noout -subject -nameopt RFC2253 | sed "s/^subject 由 @ 构造引用的文件会被读取为名称列表,其中的名称可以用空白或逗号分隔。注释仍然用 # 引入,与 pg_hba.conf 中相同,并且允许嵌套的 @ 构造。除非 @ 后面的文件名是绝对路径,否则它会被视为相对于引用它的文件所在目录。 - - 因为每一次连接尝试都会顺序地检查pg_hba.conf记录,所以这些记录的顺序是非常关键的。通常,靠前的记录有比较严的连接匹配参数和比较弱的认证方法,而靠后的记录有比较松的匹配参数和比较强的认证方法。 例如,我们希望对本地 TCP/IP 连接使用trust认证,而对远程 TCP/IP 连接要求密码。在这种情况下为来自于 127.0.0.1 的连接指定trust认证的记录将出现在为一个更宽范围的客户端 IP 地址指定密码认证的记录前面。 - - - - 在启动以及主服务器进程收到SIGHUPSIGHUP信号时,pg_hba.conf文件会被读取。 - 如果你在活动的系统上编辑了该文件,你将需要通知 postmaster(使用pg_ctl reload,调用SQL函数pg_reload_conf(),或使用kill -HUP)使其重新读取该文件。 - - - - - - 前面的说明在Microsoft Windows上不为真:在Windows上,pg_hba.conf文件中的任何更改会立即被应用到后续的新连接上。 - - - - - 系统视图pg_hba_file_rules 有助于预先测试对 pg_hba.conf 文件的修改,也可以在加载该文件没有产生预期效果时用于诊断问题。视图中 error 字段非空的行表示文件对应行存在问题。 - + 由于每次连接尝试都会按顺序检查 pg_hba.conf 记录,因此记录的顺序很重要。通常,靠前的记录使用较严格的连接匹配条件和较弱的认证方法,靠后的记录使用较宽松的匹配条件和较强的认证方法。例如,可能希望对本地 TCP/IP 连接使用 trust 认证,而要求远程 TCP/IP 连接提供密码。此时,为来自 127.0.0.1 的连接指定 trust 认证的记录,应放在为更大范围的允许客户端 IP 地址指定密码认证的记录之前。 @@ -602,9 +592,7 @@ openssl x509 -in myclient.crt -noout -subject -nameopt RFC2253 | sed "s/^subject - - 中展示了pg_hba.conf项的一些示例。不同认证方法的详情请见下一节。 - + 展示了一些 pg_hba.conf 条目示例。有关不同认证方法的详细信息,参见下一节。 @@ -612,8 +600,8 @@ openssl x509 -in myclient.crt -noout -subject -nameopt RFC2253 | sed "s/^subject # 允许本地系统上的任何用户 -# 通过 Unix 域套接字以任意 -# 数据库用户名连接到任意数据库(本地连接的默认值)。 +# 通过 Unix 域套接字(本地连接的默认方式)以任意 +# 数据库用户名连接到任意数据库。 # # TYPE DATABASE USER ADDRESS METHOD local all all trust @@ -658,7 +646,7 @@ host postgres all 192.168.93.0/24 ident # TYPE DATABASE USER ADDRESS METHOD host postgres all 192.168.12.10/32 scram-sha-256 -# 如果用户的密码被正确提供,允许 example.com 中主机上 +# 如果用户的密码被正确提供,允许 example.com 域中主机上 # 的任意用户连接到任意数据库。 # # 为大部分用户要求SCRAM认证,但是用户'mike'是个例外, @@ -669,7 +657,7 @@ host all mike .example.com md5 host all all .example.com scram-sha-256 # 如果没有前面的 "host" 行,这三行 -# 将拒绝所有来自 192.168.54.1的连接(因为那些项将首先被匹配), +# 将拒绝所有来自 192.168.54.1的连接(因为该条目将首先被匹配), # 但是允许来自互联网其他任何地方的 # GSSAPI 加密连接。零掩码表示不会考虑主机 IP 地址中的任何位, # 因此它会匹配任意主机。未加密的 GSSAPI 连接 @@ -684,7 +672,7 @@ host all all 192.168.12.10/32 gss # 允许来自 192.168.x.x 主机的用户连接到任意数据库,如果它们能够 # 通过 ident 检查。例如,假设 ident说用户是 "bryanh" 并且他要求以 # PostgreSQL 用户 "guest1" 连接,如果在 pg_ident.conf 有一个映射 -# "omicron" 的选项说 "bryanh" 被允许以 "guest1" 连接,则该连接将被允许。 +# "omicron" 的条目表明 "bryanh" 被允许以 "guest1" 连接,则该连接将被允许。 # # TYPE DATABASE USER ADDRESS METHOD host all all 192.168.0.0/16 ident map=omicron @@ -741,6 +729,18 @@ local db1,db2,@demodbs all scram-sha-256 与 pg_hba.conf 一样,此文件中的各行也可以是 include 指令,并遵循相同的规则。 + + 在启动时以及主服务器进程收到 SIGHUPSIGHUP 信号时,pg_ident.conf 文件会被读取。 + 如果你在运行中的系统上编辑了该文件,就需要通知 postmaster(使用 pg_ctl reload、调用 SQL 函数 pg_reload_conf(),或者使用 kill -HUP)重新读取该文件。 + + + + 系统视图 + pg_ident_file_mappings + 可以帮助预先测试对pg_ident.conf文件的更改,或者在加载文件后未产生预期效果时诊断问题。 + 视图中具有非空error字段的行表示文件相应行中存在问题。 + + 对于给定的一个操作系统用户可以对应多少个数据库用户,没有任何限制,反之亦然。因此,映射中的条目应理解为该操作系统用户被允许以该数据库用户身份连接,而不是意味着两者等价。只要存在任何一条映射项把外部认证系统获得的用户名与用户请求连接时使用的数据库用户名配对起来,该连接就会被允许。值 all 还可以用作 database-username,表示只要 system-username 匹配,该用户就被允许以任意现有数据库用户身份登录。若给 all 加上引号,则它会失去该特殊含义。 @@ -769,18 +769,6 @@ mymap /^(.*)@otherdomain\.com$ guest - - 在启动时以及主服务器进程收到 SIGHUPSIGHUP 信号时,pg_ident.conf 文件会被读取。 - 如果你在运行中的系统上编辑了该文件,就需要通知 postmaster(使用 pg_ctl reload、调用 SQL 函数 pg_reload_conf(),或者使用 kill -HUP)重新读取该文件。 - - - - 系统视图 - pg_ident_file_mappings - 可以帮助预先测试对pg_ident.conf文件的更改,或者在加载文件后未产生预期效果时诊断问题。 - 视图中具有非空error字段的行表示文件相应行中存在问题。 - - 展示了一个可与 中的 pg_hba.conf 文件配合使用的 pg_ident.conf 文件。在这个示例中,任何登录到 192.168 网络中某台机器上的用户,如果其操作系统用户名不是 bryanhannrobert,都不会被授予访问权限。Unix 用户 robert 只有在尝试以 PostgreSQL 用户 bob 身份连接时才被允许访问,而不能以 robert 或其他身份连接。ann 只能以 ann 身份连接。用户 bryanh 则可以以 bryanhguest1 身份连接。 @@ -879,7 +867,7 @@ omicron bryanh guest1 - Peer 认证通常适用于本地连接,不过在某些情况下,信任认证也可能已经足够。 + 通常建议对本地连接使用 Peer 认证,不过在某些情况下,信任认证也可能已经足够。 密码认证是远程连接最容易采用的选择。 其余所有选项都需要某种外部安全基础设施(通常是认证服务器,或用于签发 SSL 证书的证书颁发机构),或者属于平台特定功能。 @@ -898,16 +886,14 @@ omicron bryanh guest1 - trust认证对于单用户工作站的本地连接是非常合适和方便的。通常它本身适用于一台多用户机器。不过,只要你利用文件系统权限限制了对服务器的 Unix 域套接字文件的访问,即使在多用户机器上,你也可以使用trust。 要做这些限制,你可以设置中描述的unix_socket_permissions配置参数(可能还有unix_socket_group)。 或者你可以设置unix_socket_directories配置参数来把 Unix 域套接字文件放在一个经过恰当限制的目录中。 + trust认证对于单用户工作站的本地连接是非常合适和方便的。通常它本身适用于一台多用户机器。不过,只要你利用文件系统权限限制了对服务器的 Unix 域套接字文件的访问,即使在多用户机器上,你也可能可以使用trust。 要做这些限制,你可以设置中描述的unix_socket_permissions配置参数(可能还有unix_socket_group)。 或者你可以设置unix_socket_directories配置参数来把 Unix 域套接字文件放在一个经过恰当限制的目录中。 设置文件系统权限只能有助于 Unix 套接字连接。本地 TCP/IP 连接不会被文件系统权限限制。因此,如果你想利用文件系统权限来控制本地安全,那么从pg_hba.conf中移除host ... 127.0.0.1 ...行,或者把它改为一个非trust认证方法。 - - 如果通过指定trustpg_hba.conf行让你信任每一个被允许连接到服务器的机器上的用户,trust认证只适合 TCP/IP 连接。为任何不是来自localhost(127.0.0.1)的 TCP/IP 连接使用trust很少是合理的。 - + 只有当你信任由 pg_hba.conf 中指定 trust 的行所允许连接的每台机器上的每个用户时,trust 认证才适合用于 TCP/IP 连接。对来自 localhost(127.0.0.1)以外的任何 TCP/IP 连接使用 trust,通常都不合理。 @@ -952,17 +938,13 @@ omicron bryanh guest1 md5 - - 方法md5使用一种自定义的安全性较低的挑战-响应机制。它能防止密码嗅探并且防止密码在服务器上以明文存储,但是无法保护攻击者想办法从服务器上窃取了密码哈希的情况。此外,现在认为MD5哈希算法对于确定攻击已经不再安全。 - + 方法md5使用一种自定义的、安全性较低的挑战-响应机制。它能防止密码嗅探,并避免在服务器上以明文存储密码;但如果攻击者设法从服务器上窃取了密码哈希,它就无法提供保护。此外,如今已不再认为 MD5 哈希算法能抵御有决心的攻击者。 为了简化从md5方法到较新的SCRAM方法的转变,如果在pg_hba.conf中指定了md5但是用户在服务器上的密码是为SCRAM(见下文)加密的,则将自动选择基于SCRAM的认证。 - - 对 MD5 加密密码的支持已被弃用,并将在未来版本的 PostgreSQL 中移除。关于迁移到其他密码类型的细节,请参阅下文。 - + 对 MD5 加密密码的支持已弃用,并将在PostgreSQL的未来版本中移除。迁移到其他密码类型的详细信息见下文。 @@ -987,7 +969,7 @@ omicron bryanh guest1 - 要把现有安装从 md5 升级到 scram-sha-256,需要先确保所有正在使用的客户端库都足够新并支持 SCRAM,然后在 postgresql.conf 中设置 password_encryption = 'scram-sha-256',要求所有用户重新设置密码,并将 pg_hba.conf 中的认证方法说明改为 scram-sha-256。 + 要把现有安装从 md5 升级到 scram-sha-256,需要先确保所有正在使用的客户端库都足够新并支持 SCRAM,然后在 postgresql.conf 中设置 password_encryption = 'scram-sha-256',要求所有用户重新设置密码,并将 pg_hba.conf 中的认证方法设置改为 scram-sha-256 @@ -1051,7 +1033,7 @@ omicron bryanh guest1 keytab 文件用 Kerberos 软件生成;详见 Kerberos 文档。 - 下面展示了用 MIT 兼容的 Kerberos 5 实现的kadmin来做这个的示例: + 下面的示例展示了如何使用 MIT Kerberos 的 kadmin 工具生成该文件: kadmin% addprinc -randkey postgres/server.my.domain.org kadmin% ktadd -k krb5.keytab postgres/server.my.domain.org @@ -1141,7 +1123,7 @@ omicron bryanh guest1 如果设为 1,则会在 include_realm 选项中使用域的 SAM 兼容名称(也称为 NetBIOS 名称)。这是默认值。如果设为 0,则会使用 Kerberos 用户主体名中的真实 realm 名称。 - 不要禁用这个选项,除非你的服务器运行在一个域账号(这包括一个域成员系统上的虚拟服务账号)下并且所有通过 SSPI 认证的所有客户端也在使用域账号,否则认证将会失败。 + 不要禁用这个选项,除非你的服务器运行在一个域账号(这包括一个域成员系统上的虚拟服务账号)下并且所有通过 SSPI 认证的客户端也在使用域账号,否则认证将会失败。 @@ -1206,7 +1188,7 @@ omicron bryanh guest1 map - 允许在系统用户和数据库用户名称之间进行映射。详细信息请参见。 + 允许在系统用户名和数据库用户名之间进行映射。详见 @@ -1229,7 +1211,7 @@ omicron bryanh guest1
RFC 1413 - 标识协议的本意不是作为一种认证或访问控制协议。 + 标识协议的本意不是作为一种授权或访问控制协议。
@@ -1258,7 +1240,7 @@ omicron bryanh guest1 map - 允许在系统用户和数据库用户名称之间进行映射。详细信息请参见。 + 允许在系统用户名和数据库用户名之间进行映射。详见 @@ -1314,8 +1296,7 @@ omicron bryanh guest1 ldapscheme - 设置为ldaps以使用LDAPS。这是一种非标准的使用LDAP - 进行SSL加密的方式,受一些LDAP服务器实现支持。另请参阅ldaptls + 设置为ldaps以使用LDAPS。这是一种非标准的通过 SSL 使用 LDAP 的方式,受一些LDAP服务器实现支持。另请参阅ldaptls 选项作为替代。 @@ -1403,21 +1384,23 @@ omicron bryanh guest1 +
+ + + 以下选项提供了另一种写法,可以用更紧凑、标准的形式表示上述部分 LDAP 选项: ldapurl 一个RFC 4516 - LDAP URL。这是以更紧凑和标准形式编写其他LDAP选项的替代方式。格式为 + LDAP URL。格式为 ldap[s]://host[:port]/basedn[?[attribute][?[scope][?[filter]]]] scope必须是baseonesub中的一个,通常是最后一个。(默认为base,在此应用中通常无用。)attribute可以指定单个属性,此时将用作ldapsearchattribute的值。如果attribute为空,则filter可用作ldapsearchfilter的值。 - - URL方案ldaps选择了通过SSL进行LDAP连接的LDAPS方法,相当于使用ldapscheme=ldaps。要使用StartTLS操作进行加密LDAP连接,请使用正常的URL方案ldap并另外指定ldaptls选项。 - + URL 方案 ldaps 会选择 LDAPS 方法,通过 SSL 建立 LDAP 连接,等同于使用 ldapscheme=ldaps。要通过 StartTLS 操作使用加密的 LDAP 连接,请使用普通的 URL 方案 ldap,并在 ldapurl 之外指定 ldaptls 选项。 对于非匿名绑定,必须将ldapbinddnldapbindpasswd指定为单独的选项。 @@ -1428,8 +1411,7 @@ ldap[s]://host[:port]/ - - +
将简单绑定选项与搜索+绑定选项混用是错误的。若要在简单绑定模式下使用 ldapurl,该 URL 中不能包含 basedn 或查询元素。 @@ -1798,7 +1780,7 @@ host ... radius radiusservers="server1,server2" radiussecrets="""secret one"","" scope - 一个以空格分隔的 OAuth scope 列表,服务器需要借此既能授权客户端,又能认证用户。合适的取值由授权服务器以及所使用的 OAuth 验证模块决定(关于验证器的更多信息,见 )。此参数为必需项。 + 一个以空格分隔的 OAuth 作用域(scope)列表,服务器需要借此既能授权客户端,又能认证用户。合适的取值由授权服务器以及所使用的 OAuth 验证模块决定(关于验证器的更多信息,见 )。此参数为必需项。 diff --git a/zh/18/config.sgml b/zh/18/config.sgml index e429a63b..2ea829fd 100644 --- a/zh/18/config.sgml +++ b/zh/18/config.sgml @@ -51,7 +51,7 @@ 字符串: 通常值被包括在单引号内,值内部的任何单引号都需要被双写。不过,如果值是一个简单数字或者 标识符,引号通常可以被省略。 - (与 SQL 关键字匹配的值需要在某些上下文中引用。) + (与 SQL 关键字匹配的值在某些上下文中需要加引号。) @@ -70,7 +70,7 @@ 带单位的数字: 一些数字参数具有隐含单位,因为它们描述的是内存或时间量。单位可能是字节、千字节、块 - (通常为 8 千字节)、毫秒、秒或分钟。这类设置若给出不带修饰的数字值,就会使用该设置的默认单位, + (通常为 8 千字节)、毫秒、秒或分钟。这类设置若给出不带单位的数字值,就会使用该设置的默认单位, 可以通过 pg_settings.unit 了解该默认单位。为了方便, 也可以显式指定单位,例如把时间值写成 '120 ms',系统会将其转换为该参数的实际单位。 注意,要使用这一特性,值必须写成字符串(带引号)。单位名称区分大小写,并且数字值与单位之间可以有空白。 @@ -190,14 +190,14 @@ shared_buffers = 128MB - ALTER DATABASE命令允许针对一个数据库覆盖其全局设置。 + ALTER DATABASE命令允许针对各个数据库覆盖全局设置。 - ALTER ROLE命令允许用用户指定的值来覆盖全局设置和数据库设置。 + ALTER ROLE命令允许用针对特定用户设置的值来覆盖全局设置和数据库设置。 @@ -272,7 +272,7 @@ UPDATE pg_settings SET setting = reset_val WHERE name = 'configuration_parameter 通过 Shell 影响参数 - 除了在数据库或者角色层面上设置全局默认值或者进行覆盖,你还可以通过 shell 工具把设置 + 除了设置全局默认值或在数据库、角色级别覆盖默认值之外,你还可以通过 shell 工具把设置 传递给PostgreSQL。服务器和libpq 客户端库都能通过 shell 接受参数值。 @@ -281,8 +281,7 @@ UPDATE pg_settings SET setting = reset_val WHERE name = 'configuration_parameter - 在服务器启动期间,可以通过命令行参数把参数设置传递给 - postgres命令。例如: + 在服务器启动期间,可以通过 命令行参数或其等效形式 ,把参数设置传递给 postgres 命令。例如: postgres -c log_connections=all --log-destination='syslog' @@ -297,7 +296,7 @@ postgres -c log_connections=all --log-destination='syslog' 当通过libpq启动一个客户端会话时,可以使用PGOPTIONS 环境变量指定参数设置。这种方式建立的设置构成了会话生存期间的默认值,但是不会影响 其他的会话。由于历史原因,PGOPTIONS的格式和启动 - postgres命令时用到的相似,特别是标志必须被指定。 + postgres命令时用到的相似,具体来说,必须指定 ,或在参数名称前加上 --。 例如: env PGOPTIONS="-c geqo=off --statement-timeout=5min" psql @@ -344,7 +343,7 @@ include 'filename' 还有一个 include_if_exists 指令,其行为与 include 相同, 但在被引用文件不存在或无法读取时有所不同。普通的 include 会将其视为错误, - 而 include_if_exists 只会记录一条消息并继续处理引用配置文件。 + 而 include_if_exists 只会记录一条消息并继续处理引用它的配置文件。 @@ -355,21 +354,21 @@ include 'filename' postgresql.conf 文件也可以包含 include_dir 指令, 用来指定一个应被包含的配置文件目录。其用法如下: - include_dir 'directory' - - 非绝对目录名会被解释为相对于引用配置文件所在目录的路径。在指定目录中, +include_dir 'directory' + + 非绝对目录名会被解释为相对于引用它的配置文件所在目录的路径。在指定目录中, 只有名称以 .conf 结尾的非目录文件才会被包含。以 . 开头的文件名也会被忽略,以避免在某些平台上误处理隐藏文件。包含目录中的多个文件会按文件名顺序处理 (依据 C 区域规则排序,即数字在字母之前,大写字母在小写字母之前)。 - 包括文件或目录可以被用来在逻辑上分隔数据库配置的各个部分,而不是用一个很大的postgresql.conf文件。 + 包含文件或目录可以用来在逻辑上分隔数据库配置的各个部分,而不是用一个很大的postgresql.conf文件。 考虑一个有两台数据库服务器的公司,每一个都有不同的内存量。 - 很可能配置的元素都会被共享,例如用于日志的参数。但是两者关于内存的参数将会不同。 + 两者很可能会共享部分配置,例如日志设置。但是两者关于内存的参数将会不同。 并且还可能会有服务器相关的自定义。 一种管理这类情况的方法是将你的站点的自定义配置修改分成三个文件。 - 你可以把下面的内容加入到你的postgresql.conf文件末尾来包括它们: + 你可以把下面的内容加入到你的postgresql.conf文件末尾来包含它们: include 'shared.conf' include 'memory.conf' @@ -430,7 +429,7 @@ include_dir 'conf.d' - 指定用于数据存储的目录。这个选项只能在服务器启动时设置。 + 指定用于数据存储的目录。这个参数只能在服务器启动时设置。 @@ -490,7 +489,7 @@ include_dir 'conf.d' - 指定可被服务器创建的用于管理程序的额外进程 ID(PID)文件。这个参数只能在服务器启动的时候设置。 + 指定服务器应创建的额外进程 ID(PID)文件的名称,供服务器管理程序使用。这个参数只能在服务器启动的时候设置。 @@ -501,15 +500,15 @@ include_dir 'conf.d' - 如果你想把配置文件放在别的地方而不是数据目录中,那么postgres 命令行选项或者环境变量PGDATA必须指向包含配置文件的目录,并且postgresql.conf中(或者命令行上)的data_directory参数必须显示数据目录实际存放的地方。请注意,data_directory将覆盖PGDATA指定的数据目录位置,但是不覆盖配置文件的位置。 + 如果你想把配置文件放在别的地方而不是数据目录中,那么postgres 命令行选项或者环境变量PGDATA必须指向包含配置文件的目录,并且postgresql.conf中(或者命令行上)的data_directory参数必须设置为数据目录的实际位置。请注意,data_directory将覆盖PGDATA指定的数据目录位置,但是不覆盖配置文件的位置。 - 如果你愿意,可以使用选项config_filehba_file和/或ident_file单独指定配置文件名称和位置。config_file只能在postgres命令行上指定,但是其他文件可以在主配置文件中设置。如果所有三个参数外加data_directory被显式地设置,则不必指定PGDATA。 + 如果你愿意,可以使用选项config_filehba_file和/或ident_file单独指定配置文件名称和位置。config_file只能在postgres命令行上指定,但是其他参数可以在主配置文件中设置。如果所有三个参数外加data_directory被显式地设置,则不必指定PGDATA - 在设置任何这些参数时,相对路径将被解释为相对于postgres启动路径的路径。 + 在设置任何这些参数时,相对路径将被解释为相对于启动 postgres 时所在目录的路径。 @@ -533,7 +532,7 @@ include_dir 'conf.d' - 指定服务器用于监听来自客户端应用程序的连接的TCP/IP地址(指服务器网卡IP地址)。 + 指定服务器用于监听来自客户端应用程序的连接的TCP/IP地址。 该值采用逗号分隔的主机名和/或数字IP地址的形式。特殊条目*对应于所有可用的IP接口。 条目0.0.0.0允许监听所有IPv4地址,::允许监听所有IPv6地址。 如果列表为空,则服务器不会在任何IP接口上监听,此时只能使用Unix域套接字进行连接。 @@ -556,11 +555,11 @@ include_dir 'conf.d' - - - 服务器监听的 TCP 端口;默认是 5432 。请注意服务器会同一个端口号监听所有的 IP 地址。这个参数只能在服务器启动时设置。 - - + + 服务器监听的 TCP 端口,默认是 5432。请注意,服务器监听的所有 IP 地址都使用同一个端口号。 + 此参数只能在服务器启动时设置。 + + @@ -584,7 +583,7 @@ include_dir 'conf.d' 当运行一个备库时,你必须设置这个参数等于或大于主库上的参数。 - 否则,备库上可能无法允许查询。 + 否则,备库上将不允许查询。 @@ -597,20 +596,10 @@ include_dir 'conf.d' - 确定为拥有 - pg_use_reserved_connections - 角色的连接保留多少个连接。当空闲连接槽的数量大于 - , - 但小于或等于superuser_reserved_connections与 - reserved_connections之和时,新连接将只接受超级用户以及拥有 - pg_use_reserved_connections权限的角色。如果可用连接槽的数量等于或少于 - superuser_reserved_connections,则新连接只接受超级用户。 + 确定为具有 pg_use_reserved_connections 角色权限的角色保留多少个连接。当空闲连接槽的数量大于 ,但小于或等于 superuser_reserved_connectionsreserved_connections 之和时,新连接将只接受超级用户以及具有 pg_use_reserved_connections 角色权限的角色。如果可用连接槽的数量小于或等于 superuser_reserved_connections,则新连接只接受超级用户。 - 默认值为零连接。该值必须小于 - max_connections减去 - superuser_reserved_connections。 - 此参数只能在服务器启动时设置。 + 默认值为零个连接。该值必须小于 max_connections 减去 superuser_reserved_connections。此参数只能在服务器启动时设置。 @@ -628,7 +617,7 @@ include_dir 'conf.d' 决定为 PostgreSQL 超级用户连接保留多少个连接。 - 同时活跃的连接数最多始终只能达到 。当活跃并发连接数达到 + 同时活跃的连接数最多始终只能达到 。当活跃并发连接数至少达到 max_connections 减去 superuser_reserved_connections 时, 新连接将只接受超级用户。由该参数保留的连接槽是在 保留的连接槽耗尽之后,用于紧急情况的最后储备。 @@ -706,31 +695,23 @@ include_dir 'conf.d' - - 设置 Unix 域套接字的访问权限。Unix 域套接字使用普通的 Unix 文件系统权限集。这个参数值应该是数字的形式,也就是系统调用chmodumask接受的 形式(如果使用自定义的八进制格式,数字必须以一个0(零)开头)。 + 设置 Unix 域套接字的访问权限。Unix 域套接字使用通常的 Unix 文件系统权限集。参数值应是以 chmodumask 系统调用所接受格式指定的数字权限模式。(要使用惯用的八进制格式,数字必须以 0(零)开头。) - - 默认的权限是0777,意思是任何人都可以连接。合理的候选是0770(只有用户和同组的人可以访问, 又见unix_socket_group)和0700(只有用户自己可以访问)(请注意,对于 Unix 域套接字,只有写权限有麻烦,因此没有对读取和执行权限的设置和收回)。 + 默认权限是 0777,表示任何人都可以连接。合理的其他取值包括 0770(仅属主和所属组,另见 unix_socket_group)和 0700(仅属主)。(注意,对 Unix 域套接字而言,只有写权限起作用,因此设置或撤销读权限和执行权限没有意义。) - - 这个访问控制机制与中的用户认证没有关系。 + 此访问控制机制独立于 中描述的机制。 - - 这个参数只能在服务器启动时设置。 + 此参数只能在服务器启动时设置。 - - 这个参数与完全忽略套接字权限的系统无关,尤其是自版本10以上的Solaris。 - 在那些系统上,可以通过把unix_socket_directories指向一个把搜索权限 - 限制给指定用户的目录来实现相似的效果。 + 此参数对完全忽略套接字权限的系统无效,尤其是 Solaris(截至 Solaris 10)。在这些系统上,可以将 unix_socket_directories 指向一个仅向目标用户授予搜索权限的目录,以达到类似效果。 - - 抽象命名空间中的套接字没有文件权限,所以这种情况下这个设置也会被忽略。 + 抽象命名空间中的套接字没有文件权限,因此这种情况下也会忽略此设置。 @@ -743,10 +724,8 @@ include_dir 'conf.d' - - 通过Bonjour广告服务器的存在。默认值是关闭。 - 这个参数只能在服务器启动时设置。 + 启用通过 Bonjour 通告服务器存在的功能。默认值为关闭。此参数只能在服务器启动时设置。 @@ -759,11 +738,11 @@ include_dir 'conf.d' - - - 指定Bonjour服务名称。空字符串''(默认值)表示使用计算机名。 如果编译时没有打开Bonjour支持那么将忽略这个参数。这个参数只能在服务器启动时设置。 - - + + 指定 Bonjour 服务名。空字符串 ''(默认值)表示使用计算机名。 + 如果编译时未启用 Bonjour 支持,则此参数会被忽略。此参数只能在服务器启动时设置。 + + @@ -856,109 +835,23 @@ include_dir 'conf.d' - - 在运行查询时,设置检查客户端是否保持连接的可选检查的时间间隔。 - 这个检查通过轮询套接字来执行,并且在内核报告该连接关闭时,允许长时间运行的查询可以尽快中止。 + 设置查询执行期间可选的客户端连接检查的时间间隔,用于检查客户端是否仍然连接。检查通过轮询套接字执行;如果内核报告连接已经关闭,就可以更早中止长时间运行的查询。 - - 这个选项依赖于Linux、macOS、illumos和BSD家族操作系统暴露的内核事件, - 目前在其他系统上不可用。 + 此选项依赖 Linux、macOS、illumos 和 BSD 系列操作系统提供的内核事件,目前在其他系统上不可用。 - - 如果指定的值没有单位,则以毫秒为单位。 - 默认值为0,代表禁用连接检查。 - 没有连接检查,服务器将只在与套接字的下一次交互时检测连接的丢失,当它等待、接收或发送数据时。 + 如果指定值时没有单位,则以毫秒计。默认值为 0,表示禁用连接检查。如果不进行连接检查,服务器只有在下一次与套接字交互(等待、接收或发送数据)时,才会检测到连接丢失。 - - 为了让内核本身能够在包括网络故障在内的所有场景中,在已知的时间范围内可靠地检测丢失的TCP连接,它可能还需要调整操作系统的TCP保持连接设置, - 或者PostgreSQL, 设置。 + 要让内核本身在包括网络故障在内的所有场景中,能够在确定的时间范围内可靠地检测到 TCP 连接丢失,可能还需要调整操作系统的 TCP keepalive 设置,或 PostgreSQL 设置。 - - file_copy_method (enum) - - file_copy_method配置参数 - - - - - 指定用于复制文件的方法。可能的值包括 COPY(默认)和 - CLONE(如果操作系统支持)。 - - - 此参数会影响: - - - - - CREATE DATABASE ... STRATEGY=FILE_COPY - - - - - ALTER DATABASE ... SET TABLESPACE ... - - - - - CLONE 使用 copy_file_range()(Linux、FreeBSD) - 或 copyfile(macOS)系统调用,让内核有机会共享磁盘块, - 或把工作下推到某些文件系统的较低层。 - - - - - file_extend_method (enum) - - file_extend_method配置参数 - - - - - 指定在诸如COPY这类批量操作期间扩展数据文件时所使用的方法。 - 默认会根据操作系统选择第一个可用选项: - - - - posix_fallocate(Unix)使用标准 POSIX 接口分配磁盘空间,但某些系统缺少该接口。 - 如果接口存在但底层文件系统不支持,本选项会静默回退到write_zeros。 - 已知当前版本的 BTRFS 在使用该选项时会禁用压缩。 - 在提供该函数的系统上,这是默认值。 - - - - - write_zeros通过写出零字节块来扩展文件。 - 在不提供posix_fallocate函数的系统上,这是默认值。 - - - - 当数据文件扩展的块数不超过 8 个时,总是使用write_zeros方法。 - - - - - max_notify_queue_pages (integer) - - max_notify_queue_pages配置参数 - - - - - 指定 / 队列可分配页面的最大数量。 - 默认值是 1048576。对于 8 KB 页面,这允许最多消耗 8 GB 的磁盘空间。 - 此参数只能在服务器启动时设置。 - - - @@ -1009,10 +902,7 @@ include_dir 'conf.d' 详情参见 - - 对 MD5 加密密码的支持已被弃用,并将在未来的 PostgreSQL 版本中移除。 - 关于迁移到其他密码类型的细节,请参见 。 - + 对 MD5 加密密码的支持已弃用,并将在PostgreSQL的未来版本中移除。迁移到其他密码类型的详细信息见 @@ -1068,7 +958,7 @@ include_dir 'conf.d' 设置服务器的Kerberos密钥文件的位置。 - 默认为FILE:/usr/local/pgsql/etc/krb5.keytab(其中目录部分是在构建时由sysconfdir指定的;用pg_config --sysconfdir来决定)。 + 默认为FILE:/usr/local/pgsql/etc/krb5.keytab(其中目录部分是在构建时由sysconfdir指定的;可用pg_config --sysconfdir来确定该目录)。 如果这个参数被设为空字符串,它将被忽略,并且系统依赖的默认值被应用。 这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 详情请参考。 @@ -1099,10 +989,7 @@ include_dir 'conf.d' - 设置是否应接受来自客户端的 GSSAPI 代理。默认值为off, - 这表示不会接受客户端的凭据。将其改为on会使服务器接受 - 客户端代理给它的凭据。此参数只能在postgresql.conf文件 - 或服务器命令行中设置。 + 设置是否接受客户端的 GSSAPI 委派。默认值为 off,表示不会接受客户端的凭证。将其改为 on 会使服务器接受客户端委派给它的凭证。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 @@ -1132,14 +1019,10 @@ include_dir 'conf.d' - SSL - 查看以获取有关设置SSL的更多信息。 - 用TLS协议控制传输加密的配置参数被命名为ssl,出于历史原因, - 尽管对SSL协议的支持已被弃用。 - 在这种情况下,SSLTLS可互换使用。 + 关于 SSL 的设置,参见 。虽然对 SSL 协议的支持已被弃用,但由于历史原因,用于控制 TLS 协议传输加密的配置参数仍以 ssl 命名。在此语境中,SSLTLS 这两个术语可互换使用。 @@ -1223,13 +1106,13 @@ include_dir 'conf.d' 这个目录需要用OpenSSL 命令 openssl rehashc_rehash来准备。 - 详情参阅相应文档 + 详情参阅相应文档。 - 当使用此设置时,在连接时会按需加载指定目录下的CRLs。 - 新的CRLs可以添加到该目录中,并可以立即使用。 - 这与不同,那个会导致文件中的CRL在服务器启动时间或重新加载配置时加载。 + 当使用此设置时,在连接时会按需加载指定目录下的CRL。 + 新的CRL可以添加到该目录中,并可以立即使用。 + 这与不同,那个会导致文件中的CRL在服务器启动时或重新加载配置时加载。 两个设置可以一起使用。 @@ -1258,7 +1141,7 @@ include_dir 'conf.d' - 指定允许用于 TLS 版本 1.3 连接的密码套件列表。可以使用冒号分隔的列表指定多个密码套件。 + 指定允许用于 TLS 版本 1.3 连接的密码套件列表。可以使用冒号分隔的列表指定多个密码套件。 如果留空,将使用OpenSSL的默认密码套件集。 @@ -1333,7 +1216,7 @@ include_dir 'conf.d' - 可用的密码组细节可能会随着OpenSSL 版本变化。 + 可用的密码套件细节可能会随着OpenSSL 版本变化。 可使用命令 openssl ciphers -v 'HIGH:MEDIUM:+3DES:!aNULL'来查看当前安装的OpenSSL版本的实际细节。 注意这个列表是根据服务器密钥类型在运行时过滤过的。 @@ -1348,15 +1231,11 @@ include_dir 'conf.d' - - 指定是否使用服务器的 SSL 密码首选项,而不是用客户端的。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 - 默认值是 on。 + 指定是否使用服务器的 SSL 密码套件优先顺序,而非客户端的优先顺序。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。默认值为 on - - 老的PostgreSQL版本没有这个设置并且总是使用客户端的首选项。这个设置主要用于与那些版本 - 的向后兼容性。使用服务器的首选项通常会更好,因为服务器更可能会被合适地配置。 + PostgreSQL 9.4 之前的版本没有此设置,始终采用客户端的优先顺序。此设置主要用于与这些旧版本保持向后兼容。采用服务器的优先顺序通常更好,因为服务器更可能得到适当配置。 @@ -1382,7 +1261,7 @@ include_dir 'conf.d' prime256v1 (NIST P-256)、 secp384r1 (NIST P-384)、 secp521r1 (NIST P-521)。 - openssl ecparam -list_curves 命令可以显示可用曲线的完整列表, + openssl ecparam -list_curves 命令可以显示可用组的不完整列表, 但并非所有曲线都可用于 TLS,而且许多受支持的组名和别名并未列出。 @@ -1401,19 +1280,14 @@ include_dir 'conf.d' - - 设置要使用的最小SSL/TLS协议版本。当前的可用版本包括: TLSv1, TLSv1.1, TLSv1.2, TLSv1.3. - 旧版本的 OpenSSL 库不支持所有值;如果选择了不支持的设置将会引发错误。 - TLS 1.0之前的协议版本,也就是SSL 版本 2 and 3,总是禁用的。 + 设置要使用的最低 SSL/TLS 协议版本。当前有效值为:TLSv1TLSv1.1TLSv1.2TLSv1.3。较旧版本的 OpenSSL 库不支持所有值;如果选择了不支持的设置,就会报错。TLS 1.0 之前的协议版本,即 SSL 2 和 3,始终被禁用。 - - 默认为TLSv1.2, 在本文撰写时的行业最佳实践。 + 默认值为 TLSv1.2,符合本文撰写时的行业最佳实践。 - - 这个参数只能在postgresql.conf文件中或通过服务器命令行进行设置。 + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 @@ -1426,15 +1300,11 @@ include_dir 'conf.d' - - 设定要使用的最大SSL/TLS协议版本。 - 有效的版本为 , 添加一个空字符串,允许任何协议版本。 - 默认为允许任何版本。设置最大协议版本主要用于测试,或者某个组件在与较新的协议配合工作时出现了问题。 + 设置要使用的最高 SSL/TLS 协议版本。有效值与 相同,此外还可设为空字符串,表示允许任意协议版本。默认允许任意版本。设置最高协议版本主要用于测试,或处理某些组件无法正常配合更新协议工作的问题。 - - 这个参数只能在postgresql.conf文件中或通过服务器命令行进行设置。 + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 @@ -1447,13 +1317,11 @@ include_dir 'conf.d' - - 指定含有用于SSL密码的所谓临时DH家族的Diffie-Hellman参数的文件名。默认值为空,这种情况下将使用内置的默认DH参数。使用自定义的DH参数可以降低攻击者破解众所周知的内置DH参数的风险。可以用命令openssl dhparam -out dhparams.pem 2048创建自己的DH参数文件。 + 指定包含 Diffie-Hellman 参数的文件名,这些参数用于所谓临时 DH 系列的 SSL 密码套件。默认值为空,此时使用编译时内置的默认 DH 参数。如果攻击者破解了众所周知的内置 DH 参数,使用自定义 DH 参数可以降低由此带来的风险。可以用命令 openssl dhparam -out dhparams.pem 2048 创建自己的 DH 参数文件。 - - 这个参数只能在postgresql.conf文件中或通过服务器命令行进行设置。 + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 @@ -1466,21 +1334,17 @@ include_dir 'conf.d' - - 设置当需要一个密码(例如一个私钥)来解密SSL文件时会调用的一个外部命令。默认情况下,这个参数为空,表示使用内置的提示机制。 + 设置获取用于解密私钥等 SSL 文件的口令时要调用的外部命令。默认值为空,表示使用内置的提示机制。 - - 该命令必须将密码打印到标准输出并且以代码0退出。在该参数值中,%p被替换为一个提示字符串(要得到文字%,应该写成%%)。注意该提示字符串将可能含有空格,因此要确保加上适当的引号。如果输出的末尾有单一的新行,它会被剥离掉。 + 该命令必须将口令输出到标准输出,并以退出码 0 结束。参数值中的 %p 会被替换为提示字符串。(要表示字面值 %,应写成 %%。)提示字符串可能包含空白,因此务必正确加引号。如果输出末尾有一个换行符,会将其去掉。 - - 该命令实际上并不一定要提示用户输入一个密码。它可以从文件中读取密码、从钥匙链得到密码等等。确保选中的机制足够安全是用户的责任。 + 该命令不一定要提示用户输入口令,也可以从文件读取口令、从钥匙链获取口令等。用户应自行确保所选机制足够安全。 - - 这个参数只能在postgresql.conf文件中或通过服务器命令行进行设置。 + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 @@ -1493,20 +1357,14 @@ include_dir 'conf.d' - - 这个参数决定在配置重载期间如果一个密钥文件需要密码时,是否也调用ssl_passphrase_command设置的密码命令。 - 如果这个参数为off(默认),那么在重载期间将忽略ssl_passphrase_command,如果在此期间需要密码则SSL配置将不会被重载。 - 对于要求一个TTY(当服务器正在运行时可能是不可用的)来进行提示的命令,这种设置是合适的。 - 例如,如果密码是从一个文件中得到的,将这个参数设置为on可能是合适的。 + 此参数决定:配置重载期间,如果密钥文件需要口令,是否也调用 ssl_passphrase_command 设置的口令命令。如果此参数为 off(默认值),则重载时会忽略 ssl_passphrase_command,如果需要口令,就不会重载 SSL 配置。此设置适合需要通过 TTY 提示用户的命令,因为服务器运行期间可能无法使用 TTY。例如,如果从文件中获取口令,则适合将此参数设为 on。 - 在Windows上运行时,必须将该参数设为on, - 因为该平台采用不同的进程模型,所有连接都会触发配置重载。 + 在 Windows 上运行时,必须将此参数设为 on,因为该平台的进程模型不同,每个连接都会执行配置重载。 - - 这个参数只能在postgresql.conf文件中或通过服务器命令行进行设置。 + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 @@ -1531,22 +1389,15 @@ include_dir 'conf.d' - - 设置数据库服务器将使用的共享内存缓冲区量。默认通常是 128 兆字节(128MB),但是如果你的内核设置不支持(在initdb时决定),那么可以会更少。 - 这个设置必须至少为 128 千字节。不过为了更好的性能,通常会使用明显高于最小值的设置。 - 如果指定值时没有单位,则以块为单位,即BLCKSZ字节,通常为8kB.(BLCKSZ 的非默认值改变最小值。) - 此参数只能在服务器启动时设置。 + 设置数据库服务器用于共享内存缓冲区的内存量。默认值通常为 128 兆字节(128MB),但如果内核设置不支持,则可能更小(在 initdb 期间确定)。此设置必须至少为 128 千字节。不过,要获得良好性能,通常需要远高于该最小值的设置。如果指定值时没有单位,则以块为单位,即 BLCKSZ 字节,通常为 8kB。(BLCKSZ 的非默认值会改变该最小值。)此参数只能在服务器启动时设置。 - - 如果有一个专用的 1GB 或更多内存的数据库服务器,一个合理的shared_buffers开始值是系统内存的 25%。即使更大的shared_buffers有效,也会造成一些工作负载, 但因为PostgreSQL同样依赖操作系统的高速缓冲区,将shared_buffers设置为超过 40% 的RAM不太可能比一个小点值工作得更好。为了能把对写大量新的或改变的数据的处理分布在一个较长的时间段内,shared_buffers更大的设置通常要求对max_wal_size也做相应增加。 + 如果专用数据库服务器具有 1GB 或更多内存,shared_buffers 的合理初始值是系统内存的 25%。对于某些工作负载,将 shared_buffers 设得更大也有效,但由于 PostgreSQL 同时依赖操作系统缓存,将超过 40% 的内存分配给 shared_buffers 不太可能比更小的值效果更好。将 shared_buffers 设得更大时,通常还需要相应增加 max_wal_size,以便将大量新数据或已修改数据的写入过程分散到更长的时间内。 - - 如果系统内存小于 1GB,一个较小的 RAM 百分数是合适的,这样可以为操作系统留下足够的空间。 + 对于内存少于 1GB 的系统,适合使用更小的内存比例,以便为操作系统留出足够空间。 - @@ -1560,7 +1411,7 @@ include_dir 'conf.d' - 控制是否为主共享内存区域请求巨型页。有效值是try(默认)、on以及off。该参数只能在服务器启动时设置。如果huge_pages被设置为try,则服务器将尝试请求巨型页,但是如果失败会退回到默认的方式。如果为on,请求巨型页失败将使得服务器无法启动。如果为off,则不会请求巨型页。 + 控制是否为主共享内存区域请求巨型页。有效值是try(默认)、on以及off。该参数只能在服务器启动时设置。如果huge_pages被设置为try,则服务器将尝试请求巨型页,但是如果失败会退回到默认的方式。如果为on,请求巨型页失败将使得服务器无法启动。如果为off,则不会请求巨型页。实际是否使用巨型页由服务器变量 表示。 @@ -1569,19 +1420,19 @@ include_dir 'conf.d' - 巨型页面的使用会导致更小的页面表以及花费在内存管理上的 CPU 时间更少,从而提高性能。更多有关Linux上使用巨型页面的细节请见。 + 巨型页的使用会导致更小的页表以及花费在内存管理上的 CPU 时间更少,从而提高性能。更多有关Linux上使用巨型页的细节请见 巨型页在Windows上被称为大页面。 要使用大页面,需要为运行PostgreSQL的Windows用户账号分配在内存中锁定页面的用户权限。 可以使用Windows的组策略工具(gpedit.msc)来分配用户权限在内存中锁定页面。 - 为了在命令窗口以单进程(而不是Windows服务)的方式启动数据库服务器,命令窗口必须以管理员身份运行或者禁用用户访问控制(UAC)。 + 为了在命令窗口以独立进程(而不是Windows服务)的方式启动数据库服务器,命令窗口必须以管理员身份运行或者禁用用户访问控制(UAC)。 当UAC被启用时,普通的命令窗口会在启动时收回用户权限在内存中锁定页面 - 注意这种设置仅影响主共享内存区域。Linux、FreeBSD以及Illumos之类的操作系统也能为普通内存分配自动使用巨型页(也被称为超级页或者页面),而不需要来自PostgreSQL的显式请求。在Linux上,这被称为transparent huge pagestransparent huge pages(THP,透明巨型页)。已知这种特性对某些Linux版本上的某些用户会导致PostgreSQL的性能退化,因此当前并不鼓励使用它(与huge_pages的显式使用不同)。 + 注意这种设置仅影响主共享内存区域。Linux、FreeBSD以及Illumos之类的操作系统也能为普通内存分配自动使用巨型页(也被称为超级页或者页面),而不需要来自PostgreSQL的显式请求。在Linux上,这被称为transparent huge pages透明巨型页(THP,透明巨型页)。已知这种特性对某些Linux版本上的某些用户会导致PostgreSQL的性能退化,因此当前并不鼓励使用它(与huge_pages的显式使用不同)。 @@ -1594,24 +1445,14 @@ include_dir 'conf.d' - - 控制巨型页的大小,当他们通过时。 - 默认为零 (0)。 - 当设置为0时,将使用系统默认的巨型页大小。 - 这个参数只能在服务器启动时设置。 + 控制通过 启用巨型页时所使用的页大小。默认值为零(0)。设置为 0 时,使用系统默认的巨型页大小。此参数只能在服务器启动时设置。 - - 一些现代64位服务器体系结构上常用的有效页尺寸包括: - 2MB1GB (Intel and AMD), - 16MB16GB (IBM POWER), - 还有 64kB, 2MB,32MB1GB (ARM). - 关于使用和支持的更多信息,参见。 + 现代 64 位服务器体系结构上常见的页大小包括:2MB1GB(Intel 和 AMD),16MB16GB(IBM POWER),以及 64kB2MB32MB1GB(ARM)。关于使用和支持的更多信息,参见 - - 非默认设置当前仅在Linux上支持。 + 目前只有 Linux 支持非默认设置。 @@ -1624,16 +1465,11 @@ include_dir 'conf.d' - - 为每个数据库会话设置用于临时缓冲区的最大内存.这些是仅用于访问临时表的会话本地缓冲。 - 如果指定值时没有单位,则以块为单位,即BLCKSZ字节,通常为8kB。 - 默认为8兆字节 (8MB)。(如果BLCKSZ不是8kB,则默认值按比例缩放。) - 这个设置可以在独立的会话内部被改变,但是只有在会话第一次使用临时表之前才能改变; 在会话中随后企图改变该值是无效的。 + 设置每个数据库会话用于临时缓冲区的最大内存量。这些是会话本地的缓冲区,仅用于访问临时表。如果指定值时没有单位,则以块为单位,即 BLCKSZ 字节,通常为 8kB。默认值为 8 兆字节(8MB)。(如果 BLCKSZ 不是 8kB,则默认值按比例变化。)可以在单个会话内更改此设置,但必须在该会话首次使用临时表之前更改;此后尝试更改该值,对该会话不会产生影响。 - - 一个会话将按照temp_buffers给出的限制根据需要分配临时缓冲区。如果在一个并不需要大量临时缓冲区的会话里设置一个大的数值, 其开销只是一个缓冲区描述符,或者说temp_buffers每增加一则增加大概 64 字节。不过,如果一个缓冲区被实际使用,那么它就会额外消耗 8192 字节(或者BLCKSZ字节)。 + 会话会按需分配临时缓冲区,上限为 temp_buffers。对于实际不需要很多临时缓冲区的会话,将此参数设得较大时,开销仅为 temp_buffers 每增加一就多分配一个缓冲区描述符,约为 64 字节。不过,如果实际使用了某个缓冲区,还会为它额外消耗 8192 字节(一般而言为 BLCKSZ 字节)。 @@ -1646,18 +1482,14 @@ include_dir 'conf.d' - - 设置可以同时处于prepared状态的事务的最大数目(见)。把这个参数设置 为零(这是默认设置)将禁用预备事务特性。这个参数只能在服务器启动时设置。 + 设置可同时处于预备状态的事务的最大数量(见 )。将此参数设为零(默认值)会禁用预备事务功能。此参数只能在服务器启动时设置。 - - 如果你不打算使用预备事务,可以把这个参数设置为零来防止意外创建预备事务。如果你正在使用预备事务,你将希望把max_prepared_transactions至少设置为一样大,因此每一个会话可以有一个预备事务待处理。 + 如果不打算使用预备事务,应将此参数设为零,以防意外创建预备事务。如果使用预备事务,通常应将 max_prepared_transactions 设为不小于 的值,以便每个会话都能有一个待处理的预备事务。 - - 当运行一个备库时,你必须设置这个参数等于或大于主库上的参数。 - 否则,备库上可能无法允许查询。 + 运行备库时,必须将此参数设为与主库相同或更大的值。否则,备库上将不允许执行查询。 @@ -1670,24 +1502,11 @@ include_dir 'conf.d' - - 设置查询操作(如排序或哈希表)在写入临时磁盘文件之前可使用的基本最大内存量。 - 如果未指定单位,则将其视为千字节。默认值为四兆字节(4MB)。 - 请注意,复杂查询可能同时执行多个排序和哈希操作, - 每个操作通常允许在开始将数据写入临时文件之前使用此值指定的内存量。 - 此外,可能有多个正在运行的会话同时执行此类操作。 - 因此,使用的总内存量可能是work_mem值的多倍; - 在选择值时必须牢记这一事实。排序操作用于ORDER BYDISTINCT和合并连接。 - 哈希表用于哈希连接、基于哈希的聚合、记忆节点和IN子查询的基于哈希的处理。 + 设置查询操作(如排序或哈希表)在写入临时磁盘文件之前可使用的基础最大内存量。如果未指定单位,则以千字节为单位。默认值为 4 兆字节(4MB)。请注意,复杂查询可能同时执行多个排序和哈希操作,每个操作在开始向临时文件写入数据之前,通常都可以使用此值指定的内存量。此外,多个正在运行的会话也可能并发执行此类操作。因此,使用的总内存量可能是 work_mem 值的数倍;选择此值时必须考虑这一点。排序操作用于 ORDER BYDISTINCT 和归并连接。哈希表用于哈希连接、基于哈希的聚合、Memoize 节点以及基于哈希的 IN 子查询处理。 - - 基于哈希的操作通常比等效的基于排序的操作更加敏感于内存可用性。 - 哈希表的内存限制是通过将work_mem乘以 - hash_mem_multiplier来计算的。这使得 - 基于哈希的操作可以使用超过通常的work_mem基本 - 量的内存。 + 与等效的排序操作相比,基于哈希的操作通常对可用内存更敏感。哈希表的内存上限由 work_mem 乘以 hash_mem_multiplier 计算得到。因此,基于哈希的操作可以使用超过通常的 work_mem 基础量的内存。 @@ -1700,17 +1519,11 @@ include_dir 'conf.d' - - 用于计算哈希操作可以使用的最大内存量。最终限制由将work_mem乘以hash_mem_multiplier确定。 - 默认值为2.0,这使得基于哈希的操作使用通常work_mem基础量的两倍。 + 用于计算基于哈希的操作可以使用的最大内存量。最终上限由 work_mem 乘以 hash_mem_multiplier 确定。默认值为 2.0,使基于哈希的操作可以使用通常的 work_mem 基础量的两倍。 - - 考虑在查询操作频繁溢出的环境中增加hash_mem_multiplier, - 特别是当简单增加work_mem导致内存压力时(内存压力通常表现为间歇性的内存不足错误)。 - 默认设置为2.0通常在混合工作负载中有效。在已将work_mem增加到40MB或更高的环境中, - 可以考虑将设置调高至2.0-8.0或更高。 + 如果查询操作经常溢写磁盘,可以考虑增加 hash_mem_multiplier,尤其是在单纯增加 work_mem 会导致内存压力的情况下(内存压力通常表现为间歇性的内存不足错误)。对于混合工作负载,默认值 2.0 通常有效。如果 work_mem 已增加到 40MB 或更高,则将该值进一步设为 2.0 - 8.0 或更高可能有效。 @@ -1723,19 +1536,11 @@ include_dir 'conf.d' - - 指定维护操作(如 VACUUMCREATE INDEX 和 - ALTER TABLE ADD FOREIGN KEY)可使用的最大内存量。 - 如果指定值时未带单位,则按千字节解释。默认值为 64 兆字节(64MB)。 - 由于数据库会话一次只能执行一个这样的操作,而一个安装通常也不会有很多此类操作并发运行, - 因此把该值设置得明显大于 work_mem 通常是安全的。更大的设置可能改善清理和恢复数据库转储的性能。 + 指定维护操作(如 VACUUMCREATE INDEXALTER TABLE ADD FOREIGN KEY)可使用的最大内存量。如果未指定单位,则以千字节为单位。默认值为 64 兆字节(64MB)。由于一个数据库会话一次只能执行一个此类操作,而一个数据库系统通常也不会并发运行很多此类操作,因此可以安全地将该值设得远大于 work_mem。更大的设置可能改善清理和恢复数据库转储的性能。 - - 注意当自动清理运行时,可能会分配最多达这个内存的倍,因此要小心不要把该默认值设置得太高。 - 通过独立地设置可能会对控制这种情况 - 有所帮助。 + 注意,自动清理运行时,最多可能分配此内存量的 倍,因此不要将默认值设得过高。单独设置 可能有助于控制这一点。 @@ -1748,15 +1553,10 @@ include_dir 'conf.d' - - 指定每个自动清理工作者进程能使用的最大内存量。 - 如果指定值时没有单位,则以千字节为单位。 - 其默认值为 -1,表示转而使用 的值。 - 当运行在其他上下文环境中时,这个设置对VACUUM的行为没有影响。 - 这个参数只能在postgresql.conf中或者服务器命令行上设置。 + 指定每个自动清理工作进程可使用的最大内存量。如果未指定单位,则以千字节为单位。默认值为 -1,表示改用 的值。该设置不影响其他上下文中运行的 VACUUM 的行为。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 - + @@ -1767,13 +1567,7 @@ include_dir 'conf.d' - VACUUMANALYZE命令使用的缓冲区访问策略大小。 - 设置为0将允许操作使用任意数量的shared_buffers。 - 否则,有效范围是 128KB 到 16GB。如果指定的大小超过shared_buffers的 1/8, - 将被静默限制到该值。默认值为 2MB。如果未指定单位,则视为千字节。 - 此参数可随时设置,并且可通过为 - 传递选项来覆盖。较高的设置可以让 - VACUUMANALYZE运行得更快,但设置过大可能会将过多有用页面从共享缓冲区逐出。 + 指定 VACUUMANALYZE 命令使用的缓冲区访问策略的大小。设为 0 时,允许操作使用任意数量的 shared_buffers 缓冲区。否则,有效大小范围为 128 kB16 GB。如果指定的大小超过 shared_buffers 大小的 1/8,则会在不提示的情况下限制为该值。默认值为 2MB。如果未指定单位,则以千字节为单位。此参数可以随时设置。在执行 时,可以通过 选项覆盖此设置。较大的设置可能使 VACUUMANALYZE 运行得更快,但设置过大可能会将过多其他有用页面逐出共享缓冲区。 @@ -1786,13 +1580,10 @@ include_dir 'conf.d' - - 指定逻辑解码要使用的最大内存量,在将某些解码的更改写入本地磁盘之前。 - 这将限制逻辑流复制连接使用的内存量。它默认为 64 兆字节(64MB)。 - 由于每个复制连接仅使用此大小的单个缓冲区,并且安装通常不会同时具有多个此类连接(受 max_wal_senders 的限制),因此将此值设置得明显高于 work_mem是安全的,从而减少写入磁盘的解码更改数量。 + 指定逻辑解码在将部分已解码的更改写入本地磁盘之前可使用的最大内存量。它限制了流式逻辑复制连接使用的内存量。默认值为 64 兆字节(64MB)。由于每个复制连接仅使用一个此大小的缓冲区,而一个数据库系统通常不会同时有很多此类连接(受 max_wal_senders 限制),因此可以安全地将该值设得远高于 work_mem,以减少写入磁盘的已解码更改数量。 - + @@ -1805,7 +1596,7 @@ include_dir 'conf.d' 指定用于缓存pg_commit_ts内容的内存量 (参见)。如果未指定单位,则视为块, - 即BLCKSZ字节,通常为 8KB。默认值为0, + 即BLCKSZ字节,通常为 8kB。默认值为0, 这会请求shared_buffers/512,最多 1024 个块、最少 16 个块。 此参数只能在服务器启动时设置。 @@ -1822,7 +1613,7 @@ include_dir 'conf.d' 指定用于缓存pg_multixact/members内容的共享内存量 (参见)。如果未指定单位,则视为块, - 即BLCKSZ字节,通常为 8KB。默认值为 32。此参数只能在服务器启动时设置。 + 即BLCKSZ字节,通常为 8kB。默认值为 32。此参数只能在服务器启动时设置。 @@ -1837,7 +1628,7 @@ include_dir 'conf.d' 指定用于缓存pg_multixact/offsets内容的共享内存量 (参见)。如果未指定单位,则视为块, - 即BLCKSZ字节,通常为 8KB。默认值为 16。此参数只能在服务器启动时设置。 + 即BLCKSZ字节,通常为 8kB。默认值为 16。此参数只能在服务器启动时设置。 @@ -1852,7 +1643,7 @@ include_dir 'conf.d' 指定用于缓存pg_notify内容的共享内存量 (参见)。如果未指定单位,则视为块, - 即BLCKSZ字节,通常为 8KB。默认值为 16。此参数只能在服务器启动时设置。 + 即BLCKSZ字节,通常为 8kB。默认值为 16。此参数只能在服务器启动时设置。 @@ -1867,7 +1658,7 @@ include_dir 'conf.d' 指定用于缓存pg_serial内容的共享内存量 (参见)。如果未指定单位,则视为块, - 即BLCKSZ字节,通常为 8KB。默认值为 32。此参数只能在服务器启动时设置。 + 即BLCKSZ字节,通常为 8kB。默认值为 32。此参数只能在服务器启动时设置。 @@ -1882,7 +1673,7 @@ include_dir 'conf.d' 指定用于缓存pg_subtrans内容的共享内存量 (参见)。如果未指定单位,则视为块, - 即BLCKSZ字节,通常为 8KB。默认值为0, + 即BLCKSZ字节,通常为 8kB。默认值为0, 这会请求shared_buffers/512,最多 1024 个块、最少 16 个块。 此参数只能在服务器启动时设置。 @@ -1899,7 +1690,7 @@ include_dir 'conf.d' 指定用于缓存pg_xact内容的共享内存量 (参见)。如果未指定单位,则视为块, - 即BLCKSZ字节,通常为 8KB。默认值为0, + 即BLCKSZ字节,通常为 8kB。默认值为0, 这会请求shared_buffers/512,最多 1024 个块、最少 16 个块。 此参数只能在服务器启动时设置。 @@ -1917,8 +1708,8 @@ include_dir 'conf.d' 指定服务器执行栈的最大安全深度。此参数的理想设置是由内核强制执行的实际栈大小限制 - (如由ulimit -s或本地等效设置),减去大约一兆字节的安全边界。 - 需要安全边界是因为服务器中并非每个例程都检查栈深度,而只在关键的潜在递归例程中检查。 + (如由ulimit -s或本地等效设置),减去大约一兆字节的安全余量。 + 需要安全余量是因为服务器中并非每个例程都检查栈深度,而只在关键的潜在递归例程中检查。 如果未指定单位,则将其视为千字节。默认设置为两兆字节(2MB), 这是保守且不太可能引起崩溃的小值。但是,这可能太小,无法执行复杂函数。 只有超级用户和具有适当SET权限的用户才能更改此设置。 @@ -1938,12 +1729,8 @@ include_dir 'conf.d' - - 指定服务器应用于主共享内存区域的共享内存实现,包括 PostgreSQL 的共享缓冲区和其他共享数据。 - 可能的值为 mmap (对使用 mmap 分配的匿名共享内存),sysv (通过 shmget 分配的系统V 共享内存),和windows (Windows共享内存)。 - 并非在所有平台上都支持全部值;第一个被支持的选项是该平台的默认选项。 - sysv 选项不是任何平台的默认选项,通常不建议使用,因为它通常需要非默认的内核设置来允许大量的地址分配(参见 )。 + 指定服务器用于主共享内存区域的共享内存实现,该区域存放 PostgreSQL 的共享缓冲区及其他共享数据。可选值为 mmap(使用 mmap 分配的匿名共享内存)、sysv(通过 shmget 分配的 System V 共享内存)和 windows(Windows 共享内存)。并非所有平台都支持所有值;第一个受支持的选项是该平台的默认值。sysv 不是任何平台的默认选项,通常不建议使用,因为它一般需要更改内核的默认设置才能分配大量内存(见 )。此参数只能在服务器启动时设置。 @@ -1956,16 +1743,8 @@ include_dir 'conf.d' - - 指定服务器应该使用的动态共享内存实现。可能的值包括posix(使用shm_open分配的POSIX共享内存), - sysv(通过shmget分配的System V共享内存), - windows(用于Windows共享内存), - 和mmap(使用存储在数据目录中的内存映射文件模拟共享内存)。 - 并非所有平台都支持所有值;通常第一个支持的选项是该平台的默认值。 - 通常不建议使用mmap选项,因为操作系统可能会反复将修改的页面写回磁盘,增加系统I/O负载; - 但在调试时,当pg_dynshmem目录存储在RAM磁盘上,或者其他共享内存设施不可用时,可能会有用。 - 该参数只能在服务器启动时设置。 + 指定服务器应使用的动态共享内存实现。可选值为 posix(使用 shm_open 分配的 POSIX 共享内存)、sysv(通过 shmget 分配的 System V 共享内存)、windows(Windows 共享内存)、mmap(使用存放在数据目录中的内存映射文件模拟共享内存)。并非所有平台都支持所有值;第一个受支持的选项通常是该平台的默认值。mmap 不是任何平台的默认选项,通常不建议使用,因为操作系统可能会反复将修改过的页面写回磁盘,增加系统 I/O 负载;不过,在调试、将 pg_dynshmem 目录存放在 RAM 磁盘上,或其他共享内存设施不可用时,它可能有用。此参数只能在服务器启动时设置。 @@ -1978,13 +1757,8 @@ include_dir 'conf.d' - - 指定在服务器启动时将要分配给并行查询使用的内存容量。 - 当此内存区域不够用或被并发查询耗尽时,新的并行查询尝试使用dynamic_shared_memory_type配置的方法从操作系统临时分配额外的共享内存,由于内存管理开销该方法可能慢一些。 - 在启动时由min_dynamic_shared_memory分配的内存受到操作系统上所支持的huge_pages设置的影响,并且在自动管理的操作系统上更可能从较大的页面中受益。 - 默认值是0(无)。 - 该参数只能在服务器启动时设置。 + 指定服务器启动时为并行查询分配的内存量。当此内存区域不足或被并发查询耗尽时,新的并行查询会尝试使用 dynamic_shared_memory_type 配置的方法,临时向操作系统分配额外的共享内存;由于内存管理开销,这可能较慢。在支持 huge_pages 设置的操作系统上,启动时通过 min_dynamic_shared_memory 分配的内存会受到该设置的影响;在自动管理巨型页的操作系统上,这些内存也可能更容易受益于较大的页。默认值为 0(不分配)。此参数只能在服务器启动时设置。 @@ -2005,174 +1779,132 @@ include_dir 'conf.d' - - 指定进程可以用于临时文件(如排序和哈希临时文件)或保留游标的存储文件的最大磁盘空间。 - 尝试超过此限制的事务将被取消。 - 如果未指定单位,则将其视为千字节。 - -1(默认值)表示没有限制。 - 只有超级用户和具有适当SET权限的用户才能更改此设置。 + 指定一个进程可用于临时文件的最大磁盘空间,例如排序和哈希临时文件,或保留游标的存储文件。尝试超过此限制的事务将被取消。如果未指定单位,则以千字节为单位。-1(默认值)表示没有限制。只有超级用户和具有适当 SET 权限的用户才能更改此设置。 - - 这个设置约束着一个给定PostgreSQL进程在任何瞬间所使用的所有临时文件的总空间。应该注意的是,与在查询执行中在幕后使用的临时文件相反,显式临时表所用的磁盘空间被这个设置所限制。 + 此设置限制单个 PostgreSQL 进程在任意时刻使用的所有临时文件的总空间。需要注意,显式临时表所用的磁盘空间计入该上限;计入的是查询执行过程中内部使用的临时文件。 - - - - - - 内核资源使用 - - - - - max_files_per_process (integer) + + file_copy_method (enum) - max_files_per_process配置参数 + file_copy_method配置参数 - - 设置每个服务器子进程允许同时打开的最大文件数。默认值是一千个文件。 + 指定用于复制文件的方法。可能的值包括 COPY(默认)和 + CLONE(如果操作系统支持)。 + + + 此参数会影响: + + + + CREATE DATABASE ... STRATEGY=FILE_COPY + + + + + ALTER DATABASE ... SET TABLESPACE ... + + + - 如果内核强制实施了安全的每进程上限,你通常不必担心这个设置。但在某些平台上 - (尤其是大多数 BSD 系统),如果许多进程都尝试打开大量文件,内核可能允许单个进程打开的文件数 - 远超系统在整体上真正能够支持的数量。如果你看到打开的文件过多之类的失败, - 可以尝试减小这个设置。这个参数只能在服务器启动时设置。 + CLONE 使用 copy_file_range()(Linux、FreeBSD) + 或 copyfile(macOS)系统调用,使内核有机会在某些文件系统上共享磁盘块, + 或将工作交由更低层处理。 - - - + + file_extend_method (enum) + + file_extend_method配置参数 + + + + + 指定在诸如COPY这类批量操作期间扩展数据文件时所使用的方法。 + 默认会根据操作系统选择第一个可用选项: + + + + posix_fallocate(Unix)使用标准 POSIX 接口分配磁盘空间,但某些系统缺少该接口。 + 如果接口存在但底层文件系统不支持,本选项会静默回退到write_zeros。 + 已知当前版本的 BTRFS 在使用该选项时会禁用压缩。 + 在提供该函数的系统上,这是默认值。 + + + + + write_zeros通过写入全零数据块来扩展文件。 + 在不提供posix_fallocate函数的系统上,这是默认值。 + + + + 当数据文件扩展的块数不超过 8 个时,总是使用write_zeros方法。 + + + - 基于代价的清理延迟 + + max_notify_queue_pages (integer) + + max_notify_queue_pages配置参数 + + + + + 指定 / 队列可分配页面的最大数量。 + 默认值是 1048576。对于 8 KB 页面,这允许最多消耗 8 GB 的磁盘空间。 + 此参数只能在服务器启动时设置。 + + + - - 在命令的执行过程中,系统维持着一个内部计数器来跟踪各种被执行的I/O操作的估算开销。当累计的代价达到一个限制(由vacuum_cost_limit指定),执行这些操作的进程将按照vacuum_cost_delay所指定的休眠一小段时间。然后它将重置计数器并继续执行。 - + + - - 这个特性的出发点是允许管理员降低这些命令对并发的数据库活动产生的I/O影响。在很多情况下,VACUUMANALYZE等维护命令能否快速完成并不重要,而非常重要的是这些命令不会对系统执行其他数据库操作的能力产生显著的影响。基于代价的清理延迟提供了一种方式让管理员能够保证这一点。 - + - - 对于手动发出的VACUUM命令,该特性默认被禁用。要启用它,只要把vacuum_cost_delay变量设为一个非零值。 - + 内核资源使用 - - - vacuum_cost_delay (floating point) - - vacuum_cost_delay配置参数 - - - - - - 当超出开销限制时进程将要休眠的时间量。如果指定值时没有单位,则以毫秒为单位。 - 其默认值为0,这将禁用基于代价的清理延迟特性。正值将启用基于代价的清理。 - - - - 在使用基于代价的清理时,vacuum_cost_delay的合适值通常很小,也许是小于1毫秒。 - 虽然vacuum_cost_delay可以被设置为毫秒级别的值,但是在较老的平台上可能无法准确地测量这种延迟。 - 在这样的平台上,增加 VACUUM的节流资源消耗在1ms以上,需要改变其他的清理开销参数。 - 尽管如此,你应该保持 vacuum_cost_delay 在平台能持续测量的情况下尽可能小;大延迟没有帮助。 - - - - - - - vacuum_cost_page_hit (integer) - - vacuum_cost_page_hit配置参数 - - - - - - 清理一个在共享缓存中找到的缓冲区的估计代价。它表示锁住缓冲池、查找共享哈希表和扫描页内容的代价。默认值为1。 - - - - - - - vacuum_cost_page_miss (integer) - - vacuum_cost_page_miss配置参数 - - - - - - 清理一个必须从磁盘上读取的缓冲区的代价。 - 它表示锁住缓冲池、查找共享哈希表、从磁盘读取需要的块以及扫描其内容的代价。 - 默认值为2。 - - - - - - - vacuum_cost_page_dirty (integer) - - vacuum_cost_page_dirty配置参数 - - - - - - 当清理修改一个之前干净的块时需要花费的估计代价。它表示再次把脏块刷出到磁盘所需要的额外I/O。默认值为20。 - - - - - - - vacuum_cost_limit (integer) - - vacuum_cost_limit配置参数 - - - + - - 将导致清理进程休眠的累计代价。默认值为200。 - - - + max_files_per_process (integer) + + max_files_per_process配置参数 + + + + + 设置每个服务器子进程允许同时打开的最大文件数量。postmaster 中已经打开的文件不计入此上限。默认值为一千个文件。 + + + 如果内核强制实施了安全的每进程上限,就不必担心此设置。但在某些平台上(尤其是大多数 BSD 系统),内核允许单个进程打开的文件数量很大,如果很多进程都尝试打开这么多文件,就会远超系统实际能够支持的总量。如果遇到 Too many open files(打开的文件过多)错误,可尝试减小此设置。此参数只能在服务器启动时设置。 + + + - - - - - 有些操作会保持关键性的锁,这样可以尽快完成。基于代价的清理延迟在这类操作期间不会发生。因此有可能代价会累计至大大超过指定的限制。为了防止在这种情况下的无意义的长时间延迟,实际延迟的计算方式是vacuum_cost_delay * - accumulated_balance / - vacuum_cost_limit,且最大值是vacuum_cost_delay * 4。 - - - + 后台写入器 - 有一个独立的服务器进程,叫做后台写入器,它的功能就是发出写(新的或修改过的)共享缓冲区的命令。 - 当干净的共享缓存数量出现不足时,后台写入器写入一些脏缓存到文件系统,并标记为干净。 - 不过,后台写入器确实会增加 I/O 的总负荷,因为虽然在每个检查点间隔中一个重复弄脏的页面可能只会写出一次,但在同一个间隔中后台写入器可能会把它写出好几次。 - 在这一小节讨论的参数可以被用于调节本地需求的行为。 + 有一个独立的服务器进程,称为后台写入器,负责写出(新的或修改过的)共享缓冲区。 + 当干净的共享缓冲区数量似乎不足时,后台写入器会将一些脏缓冲区写入文件系统,并将其标记为干净。 + 这可以降低处理用户查询的服务器进程找不到干净缓冲区、因而不得不自行写出脏缓冲区的可能性。 + 不过,后台写入器确实会使总体 I/O 负载有所增加:反复变脏的页面原本可能在每个检查点间隔中只写出一次, + 而后台写入器可能在同一间隔内随着它变脏而多次写出。本节参数可用于根据实际需求调整此行为。 @@ -2184,13 +1916,10 @@ include_dir 'conf.d' - - - 指定后台写入器活动轮次之间的延迟。在每个轮次中,写入器都会为一定数量的脏缓冲区发出写操作(可以用下面的参数控制)。 - 然后它就休眠 bgwriter_delay的时长, 然后重复动作。当缓冲池中没有脏缓冲区时,不管 bgwriter_delay,它都会进入更长的休眠。如果指定值时没有单位,则以毫秒为单位。默认值是 200 毫秒(200ms)。 - 注意在许多系统上,休眠延迟的有效解析度是 10 毫秒;因此,为bgwriter_delay设置一个 不是 10 的倍数的值与把它设置为下一个更高的 10 的倍数是一样的效果。这个选项只能在服务器命令行上或者在postgresql.conf文件中设置。 - - + + 指定后台写入器各轮活动之间的延迟。每一轮中,写入器会对一定数量的脏缓冲区发出写操作(由下面的参数控制),然后休眠 bgwriter_delay 指定的时长,再重复此过程。不过,当缓冲池中没有脏缓冲区时,它会进入更长的休眠,而不受 bgwriter_delay 限制。如果未指定单位,则以毫秒为单位。默认值为 200 毫秒(200ms)。注意,在某些系统上,休眠延迟的有效分辨率为 10 毫秒;将 bgwriter_delay 设为不是 10 的倍数的值,可能与将它设为下一个更大的 10 的倍数效果相同。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 + + @@ -2201,11 +1930,10 @@ include_dir 'conf.d' - - - 在每个轮次中,不超过这么多个缓冲区将被后台写入器写出。把这个参数设置为零可禁用后台写出(注意被一个独立、专用辅助进程管理的检查点不受影响)。默认值是 100 个缓冲区。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 - - + + 后台写入器每轮写出的缓冲区数量不会超过此值。设为零会禁用后台写入。(由另一个独立的专用辅助进程管理的检查点不受影响。)默认值为 100 个缓冲区。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 + + @@ -2216,11 +1944,10 @@ include_dir 'conf.d' - - - 每一轮次要写的脏缓冲区的数目基于最近几个轮次中服务器进程需要的新缓冲区的数目。 最近所需的平均值乘以bgwriter_lru_multiplier可以估算下一轮次中将会需要的缓冲区数目。脏缓冲区将被写出直到有很多干净可重用的缓冲区(然而,每一轮次中写出的缓冲区数不超过bgwriter_lru_maxpages)。 因此,设置为 1.0 表示一种刚刚好的策略,这种策略会写出正好符合预测值的数目的缓冲区。 更大大的值可以为需求高峰提供某种缓冲,而更小的值则需要服务进程来处理一些写出操作。默认值是 2.0。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 - - + + 每轮写出的脏缓冲区数量取决于最近几轮服务器进程所需的新缓冲区数量。将近期平均需求乘以 bgwriter_lru_multiplier,即可估算下一轮所需的缓冲区数量。写入器会写出脏缓冲区,直到可用的干净且可重用缓冲区达到这一数量。(不过,每轮写出的缓冲区数量不会超过 bgwriter_lru_maxpages。)因此,设为 1.0 表示采用恰好及时策略,写出的缓冲区数量恰好等于预测需求量。更大的值可为需求突增留出余量,而更小的值则有意将部分写操作留给服务器进程执行。默认值为 2.0。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 + + @@ -2231,24 +1958,22 @@ include_dir 'conf.d' - - - 只要后台写入的数据超过这个数量,尝试强制 OS 把这些写发送到底层存储上。这样做将限制内核页缓存中脏数据的量,降低了在检查点末尾发出一个 fsync 时或者 OS 在后台大批量写回数据时卡住的可能性。 - 那常常会导致大幅度压缩的事务延迟,但是也有一些情况(特别是负载超过但小于 OS 页面高速缓存)的性能会降低。这种设置可能会在某些平台上没有效果。 - 如果指定值时没有单位,则以块为单位,即为BLCKSZ 字节,通常为8kB.合法的范围在0(禁用受控写回)和2MB之间。Linux 上的默认值是512kB,其他平台上是0(如果BLCKSZ不是8kB,则默认值和最大值会按比例缩放至这个值)。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 - - + + 每当后台写入器写出的数据超过此数量时,就尝试强制操作系统将这些写操作发往底层存储。这样可以限制内核页缓存中的脏数据量,降低在检查点结束时调用 fsync,或操作系统在后台以较大批次写回数据时发生停顿的可能性。通常,这能大幅降低事务延迟,但在某些情况下性能可能下降,尤其是工作负载大于 而小于操作系统页缓存时。此设置在某些平台上可能没有效果。如果未指定单位,则以块为单位,即 BLCKSZ 字节,通常为 8kB。有效范围为 0(禁用强制写回)至 2MB。Linux 上的默认值为 512kB,其他平台为 0。(如果 BLCKSZ 不是 8kB,默认值和最大值将按比例变化。)此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 + + - 较小的bgwriter_lru_maxpagesbgwriter_lru_multiplier可以降低由后台写入器造成的额外 I/O 开销。但更可能的是,服务器进程将必须自己发出写入操作,这会延迟交互式查询。 + 较小的 bgwriter_lru_maxpagesbgwriter_lru_multiplier 可以降低后台写入器造成的额外 I/O 负载, + 但也会增加服务器进程必须自行发出写操作的可能性,从而延迟交互式查询。 - 异步行为 + I/O @@ -2259,18 +1984,10 @@ include_dir 'conf.d' - - - 当单个后端写入数据的量超过这个数量时,尝试强制操作系统发送这些写入到底层存储。 - 这样做将限制内核的页面缓存中的脏数据量,降低在检查点末尾发出fsync时暂停的可能性,或者当操作系统在后台大批量的写回数据时。 - 通常的结果会大大减少事务延迟,但也有一些情况,特别是当工作负载大于,但小于操作系统的页面缓存时,性能可能会下降。 - 此设置在某些平台上可能无效。 - 如果指定此值时没有单位,则将其作为块,即BLCKSZ字节,通常为8kB。 - 有效范围在0,禁止强制回写,和2MB之间。 - 默认值是0,即没有强制回写。 - (如果BLCKSZ不是8kB,则最大值按其比例缩放。) - - + + 每当单个后端写出的数据超过此数量时,就尝试强制操作系统将这些写操作发往底层存储。这样可以限制内核页缓存中的脏数据量,降低在检查点结束时调用 fsync,或操作系统在后台以较大批次写回数据时发生停顿的可能性。通常,这能大幅降低事务延迟,但在某些情况下性能可能下降,尤其是工作负载大于 而小于操作系统页缓存时。此设置在某些平台上可能没有效果。如果未指定单位,则以块为单位,即 BLCKSZ 字节,通常为 8kB。有效范围为 0(禁用强制写回)至 2MB。默认值为 0,即不强制写回。(如果 BLCKSZ 不是 8kB,最大值将按比例变化。) + + @@ -2281,23 +1998,19 @@ include_dir 'conf.d' - - - 设置PostgreSQL预期可以同时执行的并发存储 I/O 操作数量。提高该值会增加任何单个PostgreSQL会话尝试并行发起的 I/O 操作数。允许的范围是11000,或者0表示禁用异步 I/O 请求。默认值是16。 - - - - 较高的值对高延迟存储和高 IOPS 设备影响最大,否则查询会经历明显的 I/O 停顿。不必要地设置过高,可能会增加系统中所有查询的 I/O 延迟。 - - - - 在支持预取建议的系统上,effective_io_concurrency还控制预取距离。 - - - - 对于位于特定表空间中的表,可以通过设置同名的表空间参数覆盖该值(见)。 - - + + 设置 PostgreSQL 预期可以同时执行的并发存储 I/O 操作数量。提高此值会增加单个 PostgreSQL 会话尝试并行发起的 I/O 操作数量。允许的范围为 11000,或设为 0 以禁用异步 I/O 请求。默认值为 16。 + + + 较高的值对以下存储影响最大:查询原本会出现明显 I/O 停顿的高延迟存储,以及高 IOPS 设备。不必要地设得过高,可能会增加系统中所有查询的 I/O 延迟。 + + + 在支持预取建议的系统上,effective_io_concurrency 还控制预取距离。 + + + 对于位于特定表空间中的表,可以通过设置同名的表空间参数覆盖此值(见 )。 + + @@ -2308,15 +2021,13 @@ include_dir 'conf.d' - - - 与effective_io_concurrency相似,但用于支持许多客户端会话完成的维护工作。 - - - 默认值是16。对于位于特定表空间中的表,可以通过设置同名的表空间参数覆盖该值(见)。 - - + 与 effective_io_concurrency 类似,但用于为多个客户端会话执行的维护工作。 + + + 默认值为 16。对于位于特定表空间中的表,可以通过设置同名的表空间参数覆盖此值(见 )。 + + @@ -2444,20 +2155,16 @@ include_dir 'conf.d' - - - 设置系统能够支持的后台进程的最大数量。这个参数只能在服务器启动时设置。默认值为 8。 - - - - 在运行一个备库时,你必须把这个参数设置为等于或者高于主库上的值。 - 否则,备库上可能不会允许查询。 - - - - 在更改这个值时,考虑也对以及进行调整。 - - + + 设置集簇能够支持的后台进程的最大数量。此参数只能在服务器启动时设置。默认值为 8。 + + + 运行备库时,必须将此参数设为与主库相同或更大的值。否则,备库上将不允许执行查询。 + + + 更改此值时,也应考虑调整 、&zwsp;、&zwsp;。 + + @@ -2468,19 +2175,16 @@ include_dir 'conf.d' - - - 设置单个Gather或者Gather Merge节点能够开始的工作者的最大数量。并行工作者会从建立的进程池中取得,数量由限制。注意所要求的工作者数量在运行时可能实际无法被满足。如果这种事情发生,该计划将会以比预期更少的工作者运行,这可能会不太高效。默认值是2。把这个值设置为0将会禁用并行查询执行。 - - - - 注意并行查询可能消耗比非并行查询更多的资源,因为每一个工作者进程时一个完全独立的进程,它对系统产生的影响大致和一个额外的用户会话相同。在为这个设置选择值时,以及配置其他控制资源利用的设置(例如)时,应该把这个因素考虑在内。work_mem之类的资源限制会被独立地应用于每一个工作者,这意味着所有进程的总资源利用可能会比单个进程时高得多。例如,一个使用 4 个工作者的并行查询使用的 CPU 时间、内存、I/O 带宽可能是不使用工作者时的 5 倍之多。 - - - - 并行查询的更多信息请见。 - - + + 设置单个 GatherGather Merge 节点能够启动的工作进程的最大数量。并行工作进程取自 建立的进程池,并受到 的限制。注意,运行时实际可用的工作进程可能不足请求的数量。此时,计划会使用少于预期的工作进程运行,效率可能较低。默认值为 2。设为 0 会禁用并行查询执行。 + + + 注意,并行查询消耗的资源可能远多于非并行查询,因为每个工作进程都是完全独立的进程,对系统的影响大致相当于额外增加一个用户会话。选择此设置的值,以及配置其他控制资源使用的设置(如 )时,都应考虑这一点。work_mem 等资源限制分别应用于每个工作进程,因此所有进程的总资源用量可能远高于单个进程通常的用量。例如,使用 4 个工作进程的并行查询,其 CPU 时间、内存、I/O 带宽等用量可能达到完全不使用工作进程的查询的 5 倍。 + + + 并行查询的更多信息参见 。 + + @@ -2491,18 +2195,13 @@ include_dir 'conf.d' - - - 设置单一工具性命令能够启动的并行工作者的最大数目。 - 当前,支持使用并行工作者的工具性命令是CREATE INDEX,并且只有在构建B-树索引时才能并行,并且 VACUUM 没有 FULL选项。 - 并行工作者从由创建的进程池中取出,数量由控制。 - 注意实际在运行时所请求数量的工作者可能不可用。如果发生这种情况,工具性操作将使用比预期数量少的工作者运行。默认值为2。将这个值设置为0可以禁用工具性命令对并行工作者的使用。 - - - - 注意并行工具性命令不应该消耗比同等数量非并行操作更多的内存。这种策略与并行查询不同,并行查询的资源限制通常是应用在每个工作者进程上。并行工具性命令把资源限制maintenance_work_mem当作对整个工具性命令的限制,而不管其中用到了多少个并行工作者进程。不过,并行工具性命令实际上可能仍会消耗更多的CPU资源和I/O带宽。 - - + + 设置单个工具命令能够启动的并行工作进程的最大数量。目前,支持使用并行工作进程的工具命令包括:构建 B-树、GIN 或 BRIN索引时的 CREATE INDEX,以及不带 FULL 选项的 VACUUM。并行工作进程取自 建立的进程池,并受到 的限制。注意,运行时实际可用的工作进程可能不足请求的数量。此时,工具操作会使用少于预期的工作进程运行。默认值为 2。设为 0 会禁止工具命令使用并行工作进程。 + + + 注意,并行工具命令的内存消耗不应明显高于等效的非并行操作。这与并行查询的策略不同,后者的资源限制通常分别应用于每个工作进程。并行工具命令将 maintenance_work_mem 视为整个工具命令的资源上限,而不论使用多少个并行工作进程。不过,并行工具命令仍可能消耗多得多的 CPU 资源和 I/O 带宽。 + + @@ -2513,17 +2212,14 @@ include_dir 'conf.d' - - - 设置系统为并行操作所支持的工作者的最大数量。默认值为8。 - 在增加或者减小这个值时,也要考虑对以及进行调整。 - 此外,要注意将这个值设置得大于将不会产生效果,因为并行工作者进程都是从所建立的工作者进程池中取出来的。 - - + + 设置集簇能够为并行操作提供的工作进程的最大数量。默认值为 8。增大或减小此值时,也应考虑调整 。此外,将此值设得大于 没有效果,因为并行工作进程取自该设置建立的工作进程池。 + + - + parallel_leader_participation (boolean) @@ -2531,17 +2227,12 @@ include_dir 'conf.d' - - - 允许 leader 进程在GatherGather Merge节点下参与执行查询计划,而不是仅仅等待 worker 进程。 - 默认值是on。 - 将其设置为off可以降低 worker 因 leader 读取元组速度不够快而被阻塞的可能性, - 但在生成第一条元组之前,leader 进程将需要等待 worker 进程启动。 - leader 对性能的帮助或拖累程度取决于计划类型、worker 数量以及查询持续时间。 - - + + 允许领导者进程执行 GatherGather Merge 节点下的查询计划,而不是等待工作进程。默认值为 on。将此值设置为 off,可以降低工作进程因领导者读取元组不够快而被阻塞的可能性,但在产生第一批元组之前,领导者进程必须等待工作进程启动。领导者对性能的帮助或妨碍程度取决于计划类型、工作进程数量和查询持续时间。 + + - + @@ -2572,7 +2263,7 @@ include_dir 'conf.d' - minimal级别生成最少的WAL日志量。它不记录在创建或重写事务中对永久关系的行信息。 + minimal级别生成最少的WAL日志量。对于在当前事务中创建或重写的永久关系,不记录其行信息。 这可以使操作速度更快(参见)。触发此优化的操作包括: ALTER ... SET TABLESPACE @@ -2583,15 +2274,15 @@ include_dir 'conf.d' REINDEX TRUNCATE - 然而,最小的WAL不包含足够的信息用于时点恢复,因此必须使用replica或更高级别来启用持续归档 + 然而,minimal 级别的 WAL 不包含足够的信息用于时间点恢复,因此必须使用replica或更高级别来启用持续归档 ()和流式二进制复制。 实际上,如果max_wal_senders不为零,服务器甚至不会以此模式启动。 - 请注意,将wal_level更改为minimal会使先前的基本备份无法用于时点恢复和备库。 + 请注意,将wal_level更改为minimal会使先前的基础备份无法用于时间点恢复和备库。 logical级别上,记录与replica相同的信息,以及从WAL中提取逻辑变更集所需的信息。 - 使用logical级别会增加WAL的容量,特别是如果许多表被配置为REPLICA IDENTITY FULL, + 使用logical级别会增加 WAL 的数量,特别是如果许多表被配置为REPLICA IDENTITY FULL, 并且执行了许多UPDATEDELETE语句。 @@ -2619,16 +2310,15 @@ include_dir 'conf.d' - 能安全关闭fsync的环境的示例包括从一个备份文件中初始加载一个新数据库集簇、使用一个数据库集簇来在数据库被删掉并重建之后处理一批数据,或者一个被经常重建并却不用于失效备援的只读数据库克隆。单独的高质量硬件不足以成为关闭fsync的理由。 + 可以安全关闭fsync的情形包括:从备份文件初始装载一个新数据库集簇;用数据库集簇处理一批数据,处理后就丢弃并重建该数据库;或者使用经常重建且不用于故障切换的只读数据库克隆。仅有高质量硬件不足以成为关闭fsync的理由。 - 当把fsync从关闭改成打开时,为了可靠的恢复,需要强制在内核中的所有被修改的缓冲区进入持久化存储。这可以在多个时机来完成: - 在集簇被关闭时或在fsync因为运行initdb --sync-only而打开时、运行sync时、卸载文件系统时或者重启服务器时。 + 为确保将fsync从关闭改为打开后能够可靠恢复,必须将内核中所有已修改的缓冲区强制写入持久存储。可以在集簇已关闭或fsync已开启时,通过运行initdb --sync-only、运行sync、卸载文件系统或重启服务器来完成。 - 在很多情况下,为不重要的事务关闭可以提供很多关闭fsync的潜在性能收益,并不会有的同时, 关闭fsync可以提供很多潜在的性能优势,而不会有伴随着的数据损坏风险。 + 在很多情况下,为非关键事务关闭,可以获得关闭fsync所带来的大部分潜在性能收益,同时避免伴随的数据损坏风险。 @@ -2647,44 +2337,32 @@ include_dir 'conf.d' - 指定数据库服务器返回success指示给客户端之前,必须要完成多少WAL处理。 - 合法的值为remote_apply, on(默认值), remote_write,local, 和 off。 + 指定数据库服务器向客户端返回成功指示之前,必须完成多少 WAL 处理。有效值为remote_applyon(默认值)、remote_writelocaloff - 如果synchronous_standby_names为空,则唯一有意义的设置为onoff ; - remote_applyremote_writelocal都提供与on相同的本地同步级别。 - 所有非off模式的本地行为都是等待WAL的本地刷新到磁盘。 - 在 off模式,无需等待,因此在向客户端报告成功和以后保证事务安全防止服务器崩溃之间可能会出现延迟。 - 当设置为off时,在向客户端报告成功和真正保证事务不会被服务器崩溃威胁之间会有延迟(最大的延迟是的三倍)。 - 不同于,将这个参数设置为off不会产生数据库不一致性的风险:一个操作系统或数据库崩溃可能会造成一些最近据说已提交的事务丢失,但数据库状态是一致的,就像这些事务已经被干净地中止。 - 因此,当性能比完全确保事务的持久性更重要时,关闭synchronous_commit可以作为一个有效的代替手段。更多讨论见。 + 如果synchronous_standby_names为空,只有onoff两种设置有意义;remote_applyremote_writelocal提供的本地同步级别都与on相同。所有非off模式在本地都会等待 WAL 刷写到磁盘。在off模式下则无需等待,因此,向客户端报告成功后,可能还要经过一段时间,才能保证事务不会因服务器崩溃而丢失。(最大延迟为的三倍。)与不同,将此参数设为off不会带来数据库不一致的风险:操作系统或数据库崩溃可能会使一些最近报告已提交的事务丢失,但数据库状态会与这些事务已正常中止时完全相同。因此,当性能比完全确保事务持久性更重要时,关闭synchronous_commit可以是一种有用的替代方案。更多讨论见 - 如果为非空,synchronous_commit也控制是否事务提交将等待它们的 WAL 记录在备库上被处理。 + 如果非空,synchronous_commit还控制事务提交是否等待备库处理其 WAL 记录。 - 当设置为 remote_apply 时,提交将等待,直到来自当前同步备库的答复显示他们已收到事务的提交记录并应用了它,以便它变得对备库上的查询可见,并写入备库上的持久存储。 - 这将导致比以前的设置更大的提交延迟,因为它等待 WAL 重放(replay)。 - 当设置为on时,提交将等待,直到来自于当前同步的备库的回复显示它们已经收到了事务的提交记录并将其刷入了磁盘。 - 这保证事务将不会被丢失,除非主库和所有同步备库都遭受到了数据库存储损坏的问题。 - 当这个参数被设置为remote_write时,提交将等待,直到来自当前的同步备库的回复指示它们已经收到了该事务的提交记录并且已经把该记录写到它们的文件系统,这种设置保证数据得以保存,在PostgreSQL的备库实例崩溃时,但是不能保证备库遭受操作系统级别崩溃时数据能被保持,因为数据不一定必须要在备库上达到持久存储。 - 设置local会导致提交等待本地刷写到磁盘,而不是复制。在使用同步复制时这通常是不可取的,但是为了完整性提供了这个选项。 + 设为remote_apply时,提交会等待当前同步备库回复,确认已收到并应用该事务的提交记录,使其对备库上的查询可见,并且已将其写入备库的持久存储。由于需要等待 WAL 重放,这会比之前的设置产生大得多的提交延迟。设为on时,提交会等待当前同步备库回复,确认已收到事务的提交记录,并已将其刷写到持久存储。这能保证事务不会丢失,除非主库和所有同步备库的数据库存储都损坏。设为remote_write时,提交会等待当前同步备库回复,确认已收到事务的提交记录,并已将其写入各自的文件系统。此设置能保证备库上的PostgreSQL实例崩溃时数据不丢失,但不能保证备库发生操作系统级别崩溃时数据不丢失,因为数据未必已写入备库的持久存储。设为local时,提交会等待本地刷盘,但不等待复制。使用同步复制时通常不希望采用这种设置,提供它是为了使选项完整。 - 这个参数可以随时被修改;任何一个事务的行为由其提交时生效的设置决定。因此,可以同步提交一些事务,同时异步提交其他事务。例如,当默认是相反时,实现一个单一多语句事务的异步提交,在事务中发出SET LOCAL synchronous_commit TO OFF。 + 此参数可以随时更改;每个事务的行为由提交时生效的设置决定。因此,让一些事务同步提交、另一些事务异步提交是可行且有用的。例如,当默认设置要求同步提交时,可以在一个包含多条语句的事务中执行SET LOCAL synchronous_commit TO OFF,使该事务异步提交。 - 概括了 synchronous_commit 设置的能力. + 汇总了synchronous_commit各种设置具备的能力。 - synchronous_commit Modes + synchronous_commit 模式 @@ -2694,10 +2372,10 @@ include_dir 'conf.d' - synchronous_commit setting - local durable commit - PG 崩溃备库持久提交 - OS 崩溃备库持久提交 + synchronous_commit 设置 + 本地提交持久性 + PG 崩溃后备库提交持久性 + OS 崩溃后备库提交持久性 备库查询一致性 @@ -2761,7 +2439,7 @@ include_dir 'conf.d' - 用来向强制 WAL 更新到磁盘的方法。如果fsync是关闭的,那么这个设置就不相关,因为 WAL 文件更新将根本不会被强制。可能的值是: + 用于将 WAL 更新强制写入磁盘的方法。如果fsync关闭,此设置就没有作用,因为 WAL 文件更新根本不会被强制写入磁盘。可选值为: @@ -2785,7 +2463,7 @@ include_dir 'conf.d' - fsync_writethrough(在每次提交时调用fsync(),强制任何磁盘写高速缓存的直通写) + fsync_writethrough(在每次提交时调用fsync(),强制穿透任何磁盘写缓存) @@ -2797,10 +2475,9 @@ include_dir 'conf.d' - open_* 选项也可以使用O_DIRECT(如果可用)。 不是在所有平台上都能使用所有这些选择。 - 默认值是列表中第一个被平台支持的那个, 不过fdatasync是 Linux和FreeBSD中的默认值。 - 默认值不一定是最理想的;有可能需要修改这个设置或系统配置的其他方面来创建一个崩溃-安全的配置,或达到最佳性能。 + 默认值是列表中第一个被平台支持的那个, 不过fdatasync是 Linux 和 FreeBSD 中的默认值。 + 默认值不一定最合适;可能需要更改此设置或系统配置的其他方面,以确保崩溃时的数据安全或达到最佳性能。 这些方面在中讨论。 这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 @@ -2817,11 +2494,11 @@ include_dir 'conf.d' - 当这个参数为打开时,PostgreSQL服务器在一个检查点之后的页面的第一次修改期间将每个页面的全部内容写到 WAL 中。这么做是因为在操作系统崩溃期间正在处理的一次页写入可能只有部分完成,从而导致在一个磁盘页面中混合有新旧数据。在崩溃后的恢复期间,通常存储在 WAL 中的行级改变数据不足以完全恢复这样一个页面。存储整页镜像可以保证页面被正确存储,但代价是增加了必须被写入 WAL 的数据量(因为 WAL 重放总是从一个检查点开始,所以在检查点后每个页面的第一次改变时这样做就够了。因此,一种减小全页面写开销的方法是增加检查点间隔参数值)。 + 启用此参数时,PostgreSQL服务器会在检查点之后首次修改每个磁盘页面时,将该页面的全部内容写入 WAL。这样做是因为,操作系统崩溃时正在进行的页面写入可能只完成了一部分,导致磁盘页面混有新旧数据。通常存储在 WAL 中的行级变更数据不足以在崩溃恢复时完整还原这样的页面。保存整页镜像能保证正确恢复页面,但会增加必须写入 WAL 的数据量。(由于 WAL 重放总是从检查点开始,只需在检查点之后首次修改每个页面时这样做。因此,减少整页写入开销的一种方法是增大检查点间隔参数。) - 把这个参数关闭会加快正常操作,但是在系统失败后可能导致不可恢复的数据损坏,或者静默的数据损坏。其风险类似于关闭fsync, 但是风险较小。并且只有在可关闭fsync的情况下才应该关闭它。 + 关闭此参数可以加快正常操作,但系统故障后可能出现不可恢复的数据损坏或静默数据损坏。风险与关闭fsync类似,虽然较小,但也只有在该参数建议的相同情形下才应关闭此参数。 @@ -2844,7 +2521,7 @@ include_dir 'conf.d' - 当这个参数为on时,PostgreSQL服务器一个检查点之后页面被第一次修改期间把该磁盘页面的整个内容都写入 WAL,即使对所谓的提示位做非关键修改也会这样做。 + 当这个参数为on时,PostgreSQL服务器在检查点之后首次修改页面时把该磁盘页面的整个内容都写入 WAL,即使对所谓的提示位做非关键修改也会这样做。 @@ -2869,9 +2546,8 @@ include_dir 'conf.d' 此参数启用使用指定的压缩方法对WAL进行压缩。 - 启用后,PostgreSQL服务器在 - 打开时或在基本备份期间, - 压缩写入WAL的整页镜像。 + 启用后,PostgreSQL服务器会压缩写入 WAL 的整页镜像,例如 + 在启用时、基础备份期间等。 在WAL重放期间,将对压缩的页镜像进行解压缩。 支持的方法有pglzlz4(如果PostgreSQL @@ -2884,8 +2560,7 @@ include_dir 'conf.d' - 启用压缩可以减少WAL卷的大小,而不会增加不可恢复的数据损坏的风险, - 但会增加在WAL记录期间进行压缩时的额外CPU消耗,以及在WAL重放期间进行解压缩时的成本。 + 启用压缩可以减少 WAL 数据量,而且不会增加不可恢复的数据损坏风险;代价是在记录 WAL 时压缩、重放 WAL 时解压会额外消耗一些 CPU。 @@ -2900,10 +2575,10 @@ include_dir 'conf.d' - 如果设置为on(默认值),此选项会导致新的 WAL 文件被零填充。 - 在某些文件系统上,这可确保在我们需要写入 WAL 记录之前分配空间。 - 但是,Copy-On-Write(COW)文件系统可能不会从此技术中受益,因此可以选择跳过不必要的工作。 - 如果设置为off,则在创建文件时仅写入最终字节,以便其具有预期大小。 + 如果设置为on(默认值),此选项会导致新的 WAL 文件被零填充。 + 在某些文件系统上,这可确保在我们需要写入 WAL 记录之前分配空间。 + 但是,写时复制(COW)文件系统可能不会从此技术中受益,因此可以选择跳过不必要的工作。 + 如果设置为off,则在创建文件时只写入最后一个字节,以便其具有预期大小。 @@ -2918,8 +2593,8 @@ include_dir 'conf.d' - 如果设置为 on (默认值),此选项通过重命名来回收 WAL 文件,从而避免创建新文件。 - 在 COW 文件系统上,创建新文件系统可能更快,因此提供了禁用此行为的选项。 + 如果设置为 on (默认值),此选项通过重命名来回收 WAL 文件,从而避免创建新文件。 + 在 COW 文件系统上,创建新文件可能更快,因此提供了禁用此行为的选项。 @@ -2934,12 +2609,12 @@ include_dir 'conf.d' - 用于还未写入磁盘的 WAL 数据的共享内存量。默认值 -1 选择等于的 1/32 的尺寸(大约3%),但是不小于64kB也不大于 WAL 段的尺寸(通常为16MB)。如果自动的选择太大或太小可以手工设置该值,但是任何小于32kB的正值都将被当作32kB。 + 用于还未写入磁盘的 WAL 数据的共享内存量。默认值 -1 选择等于的 1/32 的尺寸(大约3%),但是不小于64kB也不大于 WAL 段的尺寸(通常为16MB)。如果自动的选择太大或太小可以手工设置该值,但是任何小于32kB的正值都将被当作32kB。 如果指定值时没有单位,则以WAL块作为单位,即为 XLOG_BLCKSZ 字节,通常为8kB。这个参数只能在服务器启动时设置。 - 在每次事务提交时,WAL 缓冲区的内容被写出到磁盘,因此极大的值不可能提供显著的收益。不过,把这个值设置为几个兆字节可以在一个繁忙的服务器(其中很多客户端会在同一时间提交)上提高写性能。由默认设置 -1 选择的自动调节将在大部分情况下得到合理的结果。 + 在每次事务提交时,WAL 缓冲区的内容被写出到磁盘,因此极大的值不太可能带来显著收益。不过,把这个值设置为至少几个兆字节可以在一个繁忙的服务器(其中很多客户端会在同一时间提交)上提高写性能。由默认设置 -1 选择的自动调节将在大部分情况下得到合理的结果。 @@ -2957,9 +2632,9 @@ include_dir 'conf.d' 指定 WAL 写入器刷写 WAL 的频繁程度,以时间为单位。 在刷写WAL之后,写入器将根据wal_writer_delay所给出的时间长度进行睡眠,除非被一个异步提交的事务提前唤醒。 - 如果最近的刷写发生在 wal_writer_delay 之前,并且小于 wal_writer_flush_after WAL的值产生之后,那么WAL只会被写入操作系统,而不会被刷写到磁盘。 + 如果距上次刷盘的时间小于wal_writer_delay,并且自那以后产生的 WAL 数据量小于wal_writer_flush_after,则只将 WAL 写入操作系统,而不刷写到磁盘。 如果指定值时没有单位,则以毫秒作为单位。 - 默认值是 200 毫秒(200ms)。注意在很多系统上,有效的睡眠延迟粒度是 10 毫秒,把wal_writer_delay设置为一个不是 10 的倍数的值,其效果和把它设置为大于该值的下一个 10 的倍数产生的效果相同。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 + 默认值是 200 毫秒(200ms)。注意在某些系统上,有效的睡眠延迟粒度是 10 毫秒,把wal_writer_delay设置为一个不是 10 的倍数的值,其效果可能与将其设置为下一个更大的 10 的倍数相同。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 @@ -2974,8 +2649,8 @@ include_dir 'conf.d' - 指定 WAL 写入器刷写 WAL 的频繁程度,以卷为单位。 - 如果最近的刷写发生在 wal_writer_delay 之前,并且小于 wal_writer_flush_after WAL的值产生之后,那么WAL只会被写入操作系统,而不会被刷写到磁盘。 + 指定 WAL 写入器刷写 WAL 的频繁程度,按数据量衡量。 + 如果距上次刷盘的时间小于wal_writer_delay,并且自那以后产生的 WAL 数据量小于wal_writer_flush_after,则只将 WAL 写入操作系统,而不刷写到磁盘。 如果wal_writer_flush_after被设置为0,则WAL数据总是会被立即刷写。 如果指定值时没有单位,则以WAL块作为单位,即为XLOG_BLCKSZ字节,通常为8kB。 默认是1MB。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 @@ -2993,10 +2668,7 @@ include_dir 'conf.d' - 当wal_levelminimal,并且在创建或重写永久关系之后提交事务时,此设置将确定如何保留新数据。 - 如果数据小于此设置,将其写入 WAL 日志;否则,使用受影响文件的 fsync。 - 根据存储的属性,如果此类提交减慢了并发事务,提高或降低此值可能会有所帮助。 - 如果指定此值时没有单位,则视为千字节。默认为两兆字节(2MB)。 + 当wal_levelminimal,且事务在创建或重写永久关系后提交时,此设置决定如何持久保存新数据。如果数据量小于此设置,就将其写入 WAL;否则,对受影响的文件执行 fsync。如果这类提交拖慢了并发事务,根据存储的特性,增大或减小此值可能有所帮助。未指定单位时以千字节为单位。默认值为两兆字节(2MB)。 @@ -3011,20 +2683,20 @@ include_dir 'conf.d' - 设置commit_delay会在执行WAL刷新之前添加时间延迟。 + 设置commit_delay会在发起 WAL 刷盘之前添加时间延迟。 如果系统负载足够高,使得在给定时间间隔内有更多事务准备提交, - 这可以通过允许更多事务通过单个WAL刷新来提高组提交吞吐量。 - 然而,这也会增加延迟,最多为每个WAL刷新的commit_delay。 - 因为如果没有其他事务准备提交,延迟就是浪费的,所以只有在至少有 - commit_siblings其他事务活动时才会执行延迟, - 当要启动刷新时,如果fsync被禁用,则不会执行延迟。 + 这可以通过允许更多事务通过一次 WAL 刷盘来提高组提交吞吐量。 + 不过,每次 WAL 刷盘的延迟也会因此增加,最多增加commit_delay。 + 如果没有其他事务准备提交,等待就没有意义,因此仅当即将发起刷盘时至少还有 + commit_siblings个其他活动事务,才会等待。 + 此外,如果禁用了fsync,也不会等待。 如果未指定单位,则将其视为微秒。 默认commit_delay为零(无延迟)。 只有超级用户和具有适当SET权限的用户才能更改此设置。 - 在PostgreSQL的 9.3 发布之前,commit_delay的行为不同并且效果更差:它只影响提交,而不是所有 WAL 刷写,并且即使在 WAL 刷写马上就要完成时也会等待一整个配置的延迟。从PostgreSQL 9.3 中开始,第一个准备好刷写的进程会等待配置的间隔,而后续的进程只等到领先者完成刷写操作。 + 在PostgreSQL的 9.3 发布之前,commit_delay的行为不同并且效果更差:它只影响提交,而不是所有 WAL 刷写,并且即使 WAL 刷盘更早完成,也会等待整个配置的延迟时间。从PostgreSQL 9.3 开始,第一个准备好刷写的进程会等待配置的间隔,而后续的进程只等到领先者完成刷写操作。 @@ -3039,7 +2711,7 @@ include_dir 'conf.d' - 在执行commit_delay延迟时,要求的并发活动事务的最小数目。大一些的值会导致在延迟间隔期间更可能有至少另外一个事务准备好提交。默认值是五个事务。 + 执行commit_delay延迟前要求的并发活动事务的最小数目。大一些的值会导致在延迟间隔期间更可能有至少另外一个事务准备好提交。默认值是五个事务。 @@ -3062,7 +2734,7 @@ include_dir 'conf.d' 自动 WAL 检查点之间的最长时间。如果指定值时没有单位,则以秒为单位。 - 合理的范围在 30 秒到 1 天之间。默认是 5 分钟(5min)。增加这个参数的值会增加崩溃恢复所需的时间。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 + 合理的范围在 30 秒到 1 天之间。默认是 5 分钟(5min)。增加这个参数的值可能会增加崩溃恢复所需的时间。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 @@ -3077,11 +2749,11 @@ include_dir 'conf.d' - 指定检查点完成的目标,作为检查点之间总时间的一部分。 - 默认是 0.9,这将把检查点分布在几乎所有可用的时间间隔上,提供公平一致的I/O负载,同时也为检查点完成开销留下了一些时间。 - 减少此参数是不被推荐的,因为这会导致检查点完成得更快。 - 这个造成处于在检查点和下一个计划检查点之间较少IO之后的检查点会有更高的IO比例。 - 这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 + 指定检查点完成所用时间的目标值,以检查点之间总时间的比例表示。 + 默认值为 0.9,这会把检查点工作分散到几乎整个可用间隔内,使 I/O 负载较为平稳, + 同时为检查点完成时的额外工作留出一些时间。不建议减小此参数,因为这样会让检查点更快完成, + 导致检查点期间的 I/O 速率更高,而在检查点完成后到下一个计划检查点开始前的一段时间内 I/O 较少。 + 此参数只能在postgresql.conf文件中或服务器命令行上设置。 @@ -3098,7 +2770,7 @@ include_dir 'conf.d' 当执行检查点时写入的数据量超过此数量时,就尝试强制 OS 把这些写发送到底层存储。 这样做将会限制内核页面高速缓存中的脏数据数量,降低在检查点末尾发出fsync或者 OS 在后台大批量写回数据时被卡住的可能性。 - 那常常会导致大幅度压缩的事务延迟,但是也有一些情况(特别是负载超过但小于 OS 页面高速缓存)的性能会降低。 + 这通常能显著降低事务延迟,但是也有一些情况(特别是负载超过但小于 OS 页面高速缓存)的性能会降低。 这种设置可能会在某些平台上没有效果。 如果指定值时没有单位,则以块为单位,即为BLCKSZ 字节,通常为8kB。 合法的范围在0(禁用强制写回)和2MB之间。Linux 上的默认值是256kB,其他平台上是0(如果BLCKSZ不是8kB,则默认值和最大值会按比例缩放到它)。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 @@ -3178,10 +2850,9 @@ include_dir 'conf.d' 当启用archive_mode时,完成的WAL段会通过设置 或 - 发送到归档存储。除了off, - 要禁用,有两种模式:on和 + 发送到归档存储。除了用于禁用归档的off外,还有两种模式:onalways。在正常操作期间,这两种模式之间没有区别,但当设置为always时, - WAL归档程序在归档恢复或待机模式下也会被启用。在always模式下,从归档中恢复的所有文件 + WAL归档程序在归档恢复或备库模式下也会被启用。在always模式下,从归档中恢复的所有文件 或通过流复制传输的文件将被再次归档。详细信息请参见 @@ -3216,6 +2887,7 @@ include_dir 'conf.d' 这个参数只能在postgresql.conf文件或服务器命令行中设置。 除非在服务器启动时启用了archive_mode并且archive_library设置为空字符串,否则将被忽略。 + 如果archive_commandarchive_library都被设置,则会报错。 如果archive_command是空字符串(默认值),而archive_mode已启用(并且archive_library设置为空字符串), WAL归档将暂时被禁用,但服务器将继续积累WAL段文件,期望很快会提供命令。 将archive_command设置为一个什么都不做但返回true的命令,例如/bin/true(Windows上为REM), @@ -3235,6 +2907,7 @@ include_dir 'conf.d' 用于归档已完成的WAL文件段的库。如果设置为空字符串(默认值),则通过shell进行归档,并使用。 + 如果archive_commandarchive_library都被设置,则会报错。 否则,指定的共享库用于归档。当此参数更改时,postmaster会重新启动WAL归档进程。有关更多信息,请参见 @@ -3254,7 +2927,7 @@ include_dir 'conf.d' - 仅在完成的WAL段中调用。 + 只针对已完成的 WAL 段调用。 因此,如果您的服务器生成的WAL流量较少(或者在这样做时有间歇期),在事务完成和安全记录到归档存储之间可能会有很长的延迟。 为了限制未归档数据的年龄,您可以将archive_timeout设置为强制服务器定期切换到新的WAL段文件。 当此参数大于零时,只要自上次段文件切换以来经过了这段时间,并且存在任何数据库活动,包括单个检查点(如果没有数据库活动,则跳过检查点),服务器将切换到新的段文件。 @@ -3294,13 +2967,9 @@ include_dir 'conf.d' - 是否在恢复期间尝试预取在WAL中引用但尚未在缓冲池中的块。有效值为 - offon和 - try(默认值)。设置 - try仅在操作系统提供 - posix_fadvise函数时才启用 - 预取,该函数目前用于实现预取。请注意,一些操作系统提供该 - 函数,但它不起作用。 + 是否在恢复期间尝试预取 WAL 中引用但尚未在缓冲池中的块。 + 有效值为offontry(默认值)。 + try设置仅在操作系统支持发出预读建议时启用预取。 @@ -3335,8 +3004,8 @@ include_dir 'conf.d' 归档恢复 - configuration - of recovery + 配置 + 恢复 一个备库 @@ -3345,7 +3014,7 @@ include_dir 'conf.d' - Recovery 涵盖使用服务器作为备库或用于执行目标恢复。 + 恢复 涵盖使用服务器作为备库或用于执行目标恢复。 通常情况,备库模式用于提供高可用性和/或读可扩展性,而目标恢复用于从数据丢失中恢复。 @@ -3414,7 +3083,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows 这个信息可以被用来把归档截断为支持从当前恢复重启所需的最小值。 对于单一备库配置,模块常常被用在archive_cleanup_command中,例如: archive_cleanup_command = 'pg_archivecleanup /mnt/server/archivedir %r' - 但是注意,如果多个备库正在从同一个归档目录中恢复,你将需要保证只有当任意服务器都不再需要 WAL 文件时才会删除它们。 + 但是注意,如果多个备库正在从同一个归档目录中恢复,你将需要保证只有当所有服务器都不再需要这些 WAL 文件时才会删除它们。 archive_cleanup_command通常被用于一种温备配置(见)中。 要在该命令中嵌入一个真正的%字符,需要写成%% @@ -3467,7 +3136,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows 默认情况下,恢复将会一直恢复到 WAL 日志的末尾。下面的参数可以被用来指定一个更早的停止点。 在recovery_targetrecovery_target_lsnrecovery_target_namerecovery_target_timerecovery_target_xid中, - 最多只能使用一个,如果在配置文件中使用了多个,将会产生一个错误。这个参数只能在服务器启动时设置。 + 最多只能使用一个,如果在配置文件中使用了多个,将会产生一个错误。这些参数只能在服务器启动时设置。 @@ -3500,7 +3169,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows - 这个参数指定(pg_create_restore_point()所创建)的已命名的恢复点,恢复将进入该恢复点。 + 这个参数指定(pg_create_restore_point()所创建)的已命名的恢复点,恢复将进行到该恢复点。 @@ -3515,7 +3184,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows - 此参数指定恢复将执行的时间戳。精确的停止点还受到得影响。 + 此参数指定恢复要进行到的时间戳。精确的停止点还受到的影响。 @@ -3535,7 +3204,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows - 这个参数指定恢复将进入的事务 ID。记住虽然事务 ID 是在事务开始时顺序分配的,但是事务可能以不同的数字顺序完成。 + 这个参数指定恢复要进行到的事务 ID。记住虽然事务 ID 是在事务开始时顺序分配的,但是事务可能以不同的数字顺序完成。 那些在指定事务之前(也可以包括该事务)提交的事务将被恢复。精确的停止点也受到的影响。 @@ -3551,7 +3220,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows - 此参数指定恢复将继续进行的预写日志位置的LSN。精确的停靠点也受 的影响。 + 此参数指定恢复要进行到的预写日志位置的 LSN。精确的停止点也受 的影响。 使用系统数据类型pg_lsn解析此参数。 @@ -3576,7 +3245,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows 指定我们是否仅在指定的恢复目标之后停止(on),或者仅在恢复目标之前停止(off)。 适用于或者被指定的情况。 - 这个设置分别控制事务是否有准确的目标WAL位置(LSN)、提交时间或事务ID将被包括在该恢复中。默认值为on。 + 这个设置控制恢复是否包含 WAL 位置(LSN)、提交时间或事务 ID 分别恰好等于目标值的事务。默认值为on @@ -3593,7 +3262,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows 指定恢复到一个特定的时间线中。该值可以是数字时间线 ID 或特殊值。 - 值current沿着与执行基本备份时相同的时间线恢复。 + 值current沿着与执行基础备份时相同的时间线恢复。 值latest将恢复到归档中能找到的最新时间线,这在备库中很有用。 latest是默认值。 @@ -3629,14 +3298,14 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows - 使用pause设置的目的是:如果这个恢复目标就是恢复最想要的位置,就允许对数据库执行查询。 + 使用pause设置的目的是允许对数据库执行查询,以检查这个恢复目标是否为最合适的恢复位置。 暂停的状态可以使用pg_wal_replay_resume()(见)继续,这会让恢复终结。 如果这个恢复目标不是想要的停止点,那么关闭服务器,将恢复目标设置改为一个稍后的目标并且重启以继续恢复。 要让实例在想要的重放点那里准备好,shutdown设置可以派上用场。 - 该实例将仍能重放更多 WAL 记录(并且事实上将不得不重放从下一次它被启动后最后一个检查点以来的 WAL 记录)。 + 该实例将仍能重放更多 WAL 记录(并且事实上,下次启动时必须重新回放自上一个检查点以来的 WAL 记录)。 @@ -3647,7 +3316,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows 如果没有设置恢复目标,这个设置没有效果。 如果没有启用pause设置的动作将和shutdown一样。 - 如果在升级期间达到恢复目标,pause 的设置将与 promote的行为相同。 + 如果在备库提升期间达到恢复目标,pause 的设置将与 promote的行为相同。 @@ -3662,9 +3331,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows WAL 汇总 - - 这些设置控制 WAL 汇总,这是执行所需的一项功能。 - + 这些设置控制 WAL 汇总。执行增量备份前必须启用这项功能。 @@ -3680,12 +3347,10 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows 默认值为off - 如果wal_level被设置为minimal,则无法以 - summarize_wal=on启动服务器。如果在服务器启动后将 - summarize_wal设置为on而 - wal_levelminimal,则汇总器会运行,但会拒绝为使用 - wal_level=minimal生成的任何 WAL 创建汇总文件。 - + 如果wal_level设为minimal,则不能以summarize_wal=on启动服务器。 + 如果在服务器启动后配置summarize_wal=on,而此时wal_level=minimal, + 汇总器会运行,但会拒绝为使用wal_level=minimal生成的任何 WAL 创建汇总文件。 + @@ -3717,7 +3382,15 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows 复制 - 这些设置控制内置流复制特性(见)的行为。服务器将可以是主库或备库。主库能发送数据,而备库总是被复制数据的接收者。当使用级联复制(见)时,备库也可以是发送者,同时也是接收者。这些参数主要用于发送服务器和备库,尽管某些只在主库上有意义。如果有必要,设置可以在集簇中变化而不出问题。 + 这些设置控制内置流复制特性(见)和内置逻辑复制特性(见)的行为。 + + + + 对于流复制,服务器将可以是主库或备库。主库能发送数据,而备库总是被复制数据的接收者。当使用级联复制(见)时,备库也可以是发送者,同时也是接收者。这些参数主要用于发送服务器和备库,尽管某些只在主库上有意义。如果有必要,设置可以在集簇中变化而不出问题。 + + + + 对于逻辑复制发布者(执行CREATE PUBLICATION的服务器)向订阅者(执行CREATE SUBSCRIPTION的服务器)复制数据。服务器也可以同时是发布者和订阅者。注意,下文各节将发布者称为“发送者”。有关逻辑复制配置设置的更多详细信息,请参见 @@ -3739,16 +3412,17 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows - 指定来自备库或流式基础备份客户端的并发连接的最大数量(即同时运行 WAL 发送进程的最大数)。 - 默认值是10。值0意味着禁用复制。 - 突然的流式传输客户端断开连接可能留下一个孤立连接槽(知道达到超时),因此这个参数应该设置得略高于最大客户端连接数,这样断开连接的客户端可以立刻重新连接。 - 这个参数只能在服务器启动时被设置。此外,wal_level必须设置为replica或更高级别以允许来自备库的连接。 + 指定来自备库或流式基础备份客户端的最大并发连接数(即同时运行的 WAL 发送进程的最大数量)。 + 默认值为 10。值 0 表示禁用复制。 + 流式客户端突然断开连接后,可能会留下一个孤立连接槽,直到超时才释放。 + 因此,此参数应设置得略高于预期的最大客户端数,使断开连接的客户端能够立即重新连接。 + 此参数只能在服务器启动时设置。此外,wal_level 必须设置为 + replica 或更高级别,才允许来自备库的连接。 - 在运行一个备库时,你必须把这个参数设置为等于或者高于主库上的值。 - 否则,备库上可能不会允许查询。 - + 运行备库时,必须将此参数设置为大于或等于主库上的值。否则,备库上将不允许查询。 + @@ -3827,16 +3501,19 @@ HINT: If it is safe for all REPLICATION users to use this library as an output - 指定在备库需要为流复制获取日志段文件的情况下,pg_wal目录下所能保留的过去日志文件段的最小尺寸。 - 如果一个连接到发送服务器的备库落后了超过wal_keep_size兆字节,发送服务器可以移除一个备库仍然需要的 WAL 段,在这种情况下复制连接将被中断。 - 最终结果是下行连接也将最终失败(不过,如果在使用 WAL 归档,备库可以通过从归档获取段来恢复)。 + 指定在 pg_wal 目录中保留的旧 WAL 文件的最小总量, + 以便备库需要时获取这些文件进行流复制。如果连接到发送服务器的备库落后超过 + wal_keep_size 兆字节,发送服务器可能会移除备库仍需要的 WAL 段, + 从而导致复制连接终止。下游连接最终也会因此失败。 + (不过,如果使用了 WAL 归档,备库可以通过从归档获取该段来恢复。) - 只设置pg_wal中保留的文件段的最小尺寸;系统可能需要为 WAL 归档或从一个检查点恢复保留更多段。 - 如果wal_keep_size为零(默认值), 更多的空间来 存放WAL归档或从一个检查点恢复。 - 如果wal_keep_segments是零(缺省), 系统不会为备库目的保留任何多余的段,因此备库可用的旧 WAL 段的数量是一个上个检查点位置和 WAL 归档状态的函数。 - 如果此值被指定时没有单位,则视为兆字节。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 + 此设置只规定 pg_wal 中保留的段的最小总量;系统可能需要为 WAL 归档 + 或从检查点恢复而保留更多段。如果 wal_keep_size 为零(默认值), + 系统不会为备库额外保留任何段,因此备库可用的旧 WAL 段数取决于前一个检查点的位置 + 和 WAL 归档的状态。如果指定值时没有单位,则按兆字节计算。 + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 @@ -3850,14 +3527,18 @@ HINT: If it is safe for all REPLICATION users to use this library as an output - - 指定在检查点时,replication slots(复制槽)允许在pg_wal目录中保留的WAL文件的最大大小。 - 如果max_slot_wal_keep_size为-1(默认值),复制槽可以保留无限量的WAL文件。否则,如果复制槽的restart_lsn落后于当前LSN超过给定大小, - 使用该槽的备机可能由于所需的WAL文件被删除而无法继续复制。您可以在pg_replication_slots中查看复制槽的WAL可用性。 - 如果未指定单位,则此值将被视为兆字节。此参数只能在postgresql.conf文件或服务器命令行中设置。 - - - + + 指定检查点时复制槽允许在 + pg_wal 目录中保留的 WAL 文件最大总量。 + 如果 max_slot_wal_keep_size 为 -1(默认值),复制槽可以保留无限量的 WAL 文件。 + 否则,如果复制槽的 restart_lsn 落后当前 LSN 超过给定大小,使用该槽的备库可能会 + 因为所需 WAL 文件被移除而无法继续复制。可以在 + pg_replication_slots 中查看复制槽的 WAL 可用情况。 + 如果指定值时没有单位,则按兆字节计算。此参数只能在 + postgresql.conf 文件中或服务器命令行上设置。 + + + idle_replication_slot_timeout (integer) @@ -3896,14 +3577,14 @@ HINT: If it is safe for all REPLICATION users to use this library as an output - 中断那些停止活动超过这个时间量的复制连接。这对发送服务器检测一个费用服务器崩溃或网络中断有用。 - 如果指定值时没有单位,则以毫秒为单位。默认值是 60 秒。值0将禁用超时机制。 + 终止非活动时间超过此值的复制连接。这有助于发送服务器检测备库崩溃或网络中断。 + 如果指定值时没有单位,则按毫秒计算。默认值为 60 秒。值零禁用超时机制。 - 对于跨越多个地理位置分布的集簇,每个位置使用不同的值可以为集簇管理带来更大的灵活性。 - 对于具有低延迟网络连接的备库,较小的值有助于更快的故障检测; - 对于位于远端位置的具有高延迟网络连接的备库,较大的值有助于更好地判断备库的健康状况。 + 对于跨多个地理位置分布的集簇,在各位置使用不同的值可以提高集簇管理的灵活性。 + 对于网络延迟较低的备库,较小的值有助于更快地检测故障; + 对于地处远端、网络延迟较高的备库,较大的值有助于更准确地判断其健康状况。 @@ -3931,7 +3612,10 @@ HINT: If it is safe for all REPLICATION users to use this library as an output 主库 - 这些参数可以在发送复制数据给一个或多个备库的主库上设置。注意除了这些参数之外,在主库上必须设置合适的,并且也启用可选的 WAL 归档(见)。这些参数值与备库无关,尽管你可能希望为了准备好一个备库转变成主库来设置这些参数。 + 这些参数可以在向一个或多个备库发送复制数据的主库上设置。 + 除这些参数外,还必须在主库上适当设置 , + 也可以选择启用 WAL 归档(见 )。 + 这些参数在备库上的取值不影响备库运行,不过也可以预先设置,以备将来提升为主库。 @@ -3947,15 +3631,17 @@ HINT: If it is safe for all REPLICATION users to use this library as an output 所述,这个参数指定一个支持同步复制的备库的列表。 - 可能会有一个或者多个活动的同步备库,在这些备库确认收到它们的数据之后,等待提交的事务将被允许继续下去。 - 同步备库是那些名字出现在这个列表前面,并且当前已连接并且正在实时流式传输数据(如pg_stat_replication视图中streaming的状态所示)的服务器。 + 将有一个或多个活动的同步备库,在这些备库确认收到它们的数据之后,等待提交的事务将被允许继续下去。 + 同步备库是那些名字出现在这个列表中,并且当前已连接并且正在实时流式传输数据(如pg_stat_replication视图中streaming的状态所示)的服务器。 指定多于一台同步备库可以得到非常高的可用性并且能防止数据丢失。 用于这一目的的备库的名称是其application_name设置,它在备库的连接信息中设置。 - 在物理复制备库的情况下,这应该被设置在primary_conninfo设置中,如果设置了,默认是的设置,否则为 walreceiver。 - 对于逻辑复制,可以在订阅的连接信息中设置。对于其他复制流消费者,请参考其文档。 + 对于物理复制备库,应在 primary_conninfo 设置中指定。 + 若已设置 ,则默认使用其值;否则默认值为 walreceiver。 + 对于逻辑复制,可以在订阅的连接信息中设置,默认值为订阅名称。 + 对于其他复制流消费者,请参考其文档。 @@ -3965,15 +3651,17 @@ HINT: If it is safe for all REPLICATION users to use this library as an output ANY num_sync ( standby_name [, ...] ) standby_name [, ...] - 其中num_sync是事务需要等待其回复的同步备库的数量,standby_name是一个备库的名称。FIRST以及ANY指定从所列服务器中选取同步备库的方法。 + 其中num_sync是事务需要等待其回复的同步备库的数量,standby_name是一个备库的名称。 + num_sync 必须是大于零的整数。 + FIRST以及ANY指定从所列服务器中选取同步备库的方法。 - 关键词FIRST加上num_sync指定一种基于优先的同步复制,并且会让事务提交等待,直到它们的WAL记录被复制到基于优先级选择的num_sync台同步备库上为止。例如,设置FIRST 3 (s1, s2, s3, s4)将导致每次提交都等待来自三台较高优先级的备库的答复,这三台备库将从备库s1s2s3以及s4中选出。在该列表中出现较早的备库将被给予较高的优先级,并且将被考虑为同步备库。列表中出现的其他备库表示潜在的同步备库。如果当前的任何同步备库因为某种原因断开连接,它将立刻被下一个最高优先级的备库替代。关键词FIRST是可选的。 + 关键词FIRST加上num_sync指定一种基于优先级的同步复制,并且会让事务提交等待,直到它们的WAL记录被复制到基于优先级选择的num_sync台同步备库上为止。例如,设置FIRST 3 (s1, s2, s3, s4)将导致每次提交都等待来自三台较高优先级的备库的答复,这三台备库将从备库s1s2s3以及s4中选出。在该列表中出现较早的备库将被给予较高的优先级,并且将被考虑为同步备库。列表中出现的其他备库表示潜在的同步备库。如果当前的任何同步备库因为某种原因断开连接,它将立刻被下一个最高优先级的备库替代。关键词FIRST是可选的。 - 关键词ANY加上num_sync指定一种基于规定数量的同步复制,并且会让事务提交等待,直到它们的WAL记录被复制到所列出备库中的至少num_sync台上为止。例如,设置ANY 3 (s1, s2, s3, s4)将导致每次提交会在收到s1s2s3以及s4中任意三台备库的回答后立刻继续下去。 + 关键词ANY加上num_sync指定一种基于法定人数的同步复制,并且会让事务提交等待,直到它们的WAL记录被复制到所列出备库中的至少num_sync台上为止。例如,设置ANY 3 (s1, s2, s3, s4)将导致每次提交会在收到s1s2s3以及s4中任意三台备库的回答后立刻继续下去。 @@ -3999,7 +3687,7 @@ ANY num_sync ( 参数设置为localoff。 + 如果这里没有指定同步备库名称,那么不启用同步复制并且事务提交将不会等待复制。这是默认的配置。即便当同步复制被启用时,个体事务也可以被配置为不等待复制,做法是将参数设置为localoff @@ -4016,16 +3704,16 @@ ANY num_sync ( pg_replication_slot_advance、 + pg_logical_slot_get_changes和 + pg_logical_slot_peek_changes + 将阻塞,直到synchronized_standby_slots中列出的所有物理槽都确认接收到了 WAL。 synchronized_standby_slots中物理复制槽对应的备库必须配置 @@ -4097,7 +3785,7 @@ ANY num_sync ( )。 这个参数只能在 postgresql.conf文件或服务器命令行上设置。 - 如果在 WAL 接收进程运行时更改此参数,则该进程将发出关机信号,并预期使用新设置重新启动(除非primary_conninfo为空字符串)。 + 如果在 WAL 接收进程运行时更改此参数,则会向该进程发送关闭信号,并预期它使用新设置重新启动。 如果没有设置primary_conninfo或服务器没有处于备库模式,则此设置无效。 @@ -4136,9 +3824,7 @@ ANY num_sync ( num_sync ( num_sync ( )。 - 默认为"关闭"。 此参数只能在postgresql.conf文件或服务器命令行中设置。 - 如果在 WAL 接收进程运行时更改此参数,则该进程将发出关机的信号,并预期使用新设置重新启动。 - + 指定在未使用配置要使用的永久复制槽时,WAL 接收进程是否应在远程实例上创建临时复制槽。默认值为 off。此参数只能在postgresql.conf文件中或服务器命令行上设置。如果在 WAL 接收进程运行时更改此参数,则会向该进程发送信号使其关闭,并预期它使用新设置重新启动。 @@ -4194,9 +3874,9 @@ ANY num_sync ( pg_stat_replication视图看到。 - 备库将报告它已经写入的上一个预写式日志位置、它已经刷到磁盘的上一个位置以及它已经应用的最后一个位置。 + 备库将报告最后写入的预写日志位置、最后刷盘的位置以及最后应用的位置。 这个参数的值是报告之间的最大时间量。 - 每次写入或刷出位置改变时会发送状态更新,或者按这个参数的指定的频度发送,如果设置为非零值。 + 每次写入或刷盘位置改变时会发送状态更新,或者按这个参数的指定的频度发送,如果设置为非零值。 在其他情况下发送更新时忽略此参数;例如,当现有的WAL处理完成或当synchronous_commit设置为remote_apply时。 因此,应用位置可能比真实位置略微滞后。 如果指定值时没有单位,则以秒为单位。 @@ -4216,7 +3896,7 @@ ANY num_sync ( num_sync ( num_sync ( + + recovery_min_apply_delay (integer) recovery_min_apply_delay 配置参数 - - 默认情况下,备库会尽快恢复来自于发送服务器的 WAL 记录。有一份数据的延时拷贝是有用的,它能提供机会纠正数据丢失错误。 - 这个参数允许你将恢复延迟一段指定的时间量。 - 例如,如果你设置这个参数为5min,对于一个事务提交,只有当备库上的系统时钟超过主库报告的提交时间至少 5分钟时,备库才会重放该事务。 - 如果指定值时没有单位,则以毫秒为单位。默认为0,不增加延迟。 + 默认情况下,备库会尽快恢复来自发送服务器的 WAL 记录。保留一份延迟的数据副本可能很有用,因为它提供了纠正数据丢失错误的机会。此参数允许将恢复延迟指定的时间。例如,将此参数设置为 5min 时,只有当备库系统时间比主库报告的提交时间至少晚五分钟,备库才会重放各事务的提交。如果没有指定单位,则以毫秒计。默认值为零,不增加延迟。 - - 有可能服务器之间的复制延迟会超过这个参数的值,在这种情况下则不会增加延迟。 - 注意延迟是根据主库上写 WAL 的时间戳以及备库上的当前时间来计算。 - 由于网络延迟或者级联复制配置导致的传输延迟可能会显著地减少实际等待时间。 - 如果主库和备库上的系统时钟不同步,这会导致恢复比预期的更早应用记录。 - 但这不是一个主要问题,因为这个参数有用的设置比服务器之间的典型事件偏差要大得多。 + 服务器之间的复制延迟可能超过此参数的值,这种情况下不会增加延迟。注意,延迟根据主库写入的 WAL 时间戳与备库当前时间之差计算。网络延迟或级联复制配置导致的传输延迟,可能显著缩短实际等待时间。如果主库和备库的系统时钟不同步,恢复时可能比预期更早应用记录;但这通常不是主要问题,因为此参数的实用取值远大于服务器间常见的时间偏差。 - - 只有在事务提交的 WAL 记录上才会发生延迟。其他记录还是会被尽可能快地重放,这不会成为问题,因为 MVCC 可见性规则确保了在对应的提交记录被应用之前它们的效果不会被看到。 + 延迟仅发生在事务提交的 WAL 记录上。其他记录会尽快重放;这不会造成问题,因为 MVCC 可见性规则确保在对应提交记录被应用之前,它们的效果不会可见。 - - 一旦恢复中的数据库已经达到一致状态,延迟就会产生,直到备库被提升或者触发。在那之后,备库将会结束恢复并且不再等待。 + 恢复中的数据库达到一致状态后开始延迟,直到备库被提升或触发。此后,备库会结束恢复,不再等待。 - - WAL记录必须保留在备库上,直到准备好应用。因此,较长的延迟将导致WAL文件的积累增加,增加备库的pg_wal目录的磁盘空间需求。 + WAL 记录必须保留在备库上,直到可以应用它们。因此,更长的延迟会导致更多 WAL 文件积压,增加备库 pg_wal 目录所需的磁盘空间。 - - 这个参数的目的是和流复制部署一起使用,但是,如果指定了该参数,除了崩溃恢复之外所有的情况下都会遵守它。 - 使用这个特性也会让hot_standby_feedback被延迟,这可能导致主库的膨胀,两者一起使用时要小心。 - + 此参数旨在用于流复制部署;不过,只要指定了此参数,它就会在除崩溃恢复以外的所有情况下生效。使用此功能也会延迟 hot_standby_feedback,可能导致主库膨胀;同时使用两者时应谨慎。 - 当synchronous_commit被设置为remote_apply时,同步复制会受到这个设置的影响,每一个COMMIT都需要等待被应用。 + 当 synchronous_commit 设置为 remote_apply 时,同步复制会受到此设置影响;每个 COMMIT 都必须等待提交被应用。 - - - 这个参数只能在postgresql.conf文件中或通过服务器命令行进行设置。 - - - + + + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 + + + - + sync_replication_slots (boolean) sync_replication_slots配置参数 @@ -4341,53 +4005,8 @@ ANY num_sync ( - createrole_self_grant (string) - - createrole_self_grant配置参数 - - - - - 如果一个拥有CREATEROLE但不拥有SUPERUSER权限的用户创建了角色,并且此选项被设置为非空值,则新创建的角色将以指定选项授予创建者。 - 该值必须是setinherit或它们的逗号分隔列表。默认值为空字符串,这会禁用此功能。 - - - 此选项的目的是允许非超级用户的CREATEROLE用户自动继承或自动获得对新创建角色执行SET ROLE的能力。 - 由于CREATEROLE用户始终会隐式获得其所创建角色的ADMIN OPTION,因此该用户总是可以通过执行GRANT语句达到相同效果,但自动授予在可用性上更方便。 - 超级用户会自动继承每个角色的权限,并且始终可以切换到任何角色;此设置可用于为CREATEROLE用户提供类似行为。 - - - - - event_triggers (boolean) - - event_triggers配置参数 - - - - - 允许临时禁用事件触发器的执行,以便对有故障的事件触发器进行故障排查和修复。 - 将其设置为false会禁用所有事件触发器;设置为true则允许所有事件触发器触发,这也是默认值。 - 只有超级用户和具有适当SET权限的用户才能更改此设置。 - - - - - restrict_nonsystem_relation_kind (string) - - restrict_nonsystem_relation_kind配置参数 - - - - - 设置禁止访问非系统关系的关系类型。该值采用关系类型的逗号分隔列表形式。 - 目前支持的关系类型是viewforeign-table。 - - - @@ -4397,11 +4016,7 @@ ANY num_sync ( @@ -4417,7 +4032,7 @@ ANY num_sync ( ),从而实际上限制了服务器上可以创建多少逻辑复制订阅。 将其设置为低于当前正在跟踪的复制源数量(体现在pg_replication_origin_status中)会阻止服务器启动。 默认值为 10。该参数只能在服务器启动时设置。 - max_active_replication_origins至少必须设置为订阅者上要添加的订阅数量,再加上一些用于表同步的预留。 + max_active_replication_origins至少必须设置为订阅者上要添加的订阅数量,再加上一些用于表同步的预留。 @@ -4432,16 +4047,15 @@ ANY num_sync ( num_sync ( num_sync ( num_sync ( + + enable_bitmapscan (boolean) - 位图扫描 + 位图扫描 - enable_bitmapscan配置参数 + enable_bitmapscan 配置参数 - - 允许或禁止查询规划器使用位图扫描计划类型。默认值是on。 + 启用或禁用查询规划器对位图扫描计划类型的使用。默认值为 on - - + + - + enable_distinct_reordering (boolean) enable_distinct_reordering配置参数 @@ -4566,22 +4179,22 @@ ANY num_sync ( + + enable_gathermerge (boolean) - enable_gathermerge配置参数 + enable_gathermerge 配置参数 - - 启用或者禁用查询规划器对收集归并计划类型的使用。默认值是on。 + 启用或禁用查询规划器对收集归并计划类型的使用。默认值为 on - - + + - + enable_group_by_reordering (boolean) enable_group_by_reordering配置参数 @@ -4596,89 +4209,90 @@ ANY num_sync ( + + enable_hashagg (boolean) - enable_hashagg配置参数 + enable_hashagg 配置参数 - - 允许或禁用查询规划器使用哈希聚合计划类型。默认值是on。 + 启用或禁用查询规划器对哈希聚合计划类型的使用。默认值为 on - + + enable_hashjoin (boolean) - enable_hashjoin配置参数 + enable_hashjoin 配置参数 - - 允许或禁止查询规划器使用哈希连接计划类型。默认值是on。 + 启用或禁用查询规划器对哈希连接计划类型的使用。默认值为 on - + + enable_incremental_sort (boolean) enable_incremental_sort 配置参数 - - 启用或禁用查询规划器对增量排序步骤的使用。默认为on。 + 启用或禁用查询规划器对增量排序步骤的使用。默认值为 on - + + + + enable_indexscan (boolean) - 索引扫描 + 索引扫描 - enable_indexscan配置参数 + enable_indexscan 配置参数 - - 允许或禁止查询规划器使用索引扫描计划类型。默认值是on。 + 启用或禁用查询规划器对索引扫描和仅索引扫描计划类型的使用。默认值为 on。另请参见 - enable_indexonlyscan (boolean) - enable_indexonlyscan配置参数 + enable_indexonlyscan 配置参数 - - 允许或禁止查询规划器使用只用索引扫描计划类型(见)。默认值是on。 + 启用或禁用查询规划器对仅索引扫描计划类型的使用(参见 )。默认值为 on。还必须启用 ,查询规划器才会考虑仅索引扫描。 - + + enable_material (boolean) - enable_material配置参数 + enable_material 配置参数 @@ -4689,8 +4303,9 @@ ANY num_sync ( + + enable_memoize (boolean) enable_memoize 配置参数 @@ -4707,26 +4322,27 @@ ANY num_sync ( + + enable_mergejoin (boolean) - enable_mergejoin配置参数 + enable_mergejoin 配置参数 - - 允许或禁止查询规划器使用归并连接计划类型。默认值是on。 + 启用或禁用查询规划器对归并连接计划类型的使用。默认值为 on - + + enable_nestloop (boolean) - enable_nestloop配置参数 + enable_nestloop 配置参数 @@ -4752,17 +4368,17 @@ ANY num_sync ( + + enable_parallel_hash (boolean) - enable_parallel_hash配置参数 + enable_parallel_hash 配置参数 - - 允许或禁止查询规划器对并行哈希使用哈希连接计划类型。如果哈希连接计划也没有启用,这个参数没有效果。默认值是on。 + 启用或禁用查询规划器对使用并行哈希的哈希连接计划类型的使用。如果没有同时启用哈希连接计划,此参数不起作用。默认值为 on @@ -4782,41 +4398,37 @@ ANY num_sync ( + + + + enable_partitionwise_join (boolean) - enable_partitionwise_join配置参数 + enable_partitionwise_join 配置参数 - - 允许或者禁止查询规划器使用面向分区的连接,这使得分区表之间的连接以连接匹配的分区的方式来执行。 - 面向分区的连接当前只适用于连接条件包括所有分区键的情况,连接条件必须是相同的数据类型并且子分区集合要1对1匹配。 - 由于面向分区的连接规划在规划期间会使用可观的CPU时间和内存,所以默认值为off。 + 启用或禁用查询规划器对分区连接的使用,使分区表之间的连接可以通过连接相匹配的分区来完成。分区连接目前仅适用于连接条件包含所有分区键的情况;这些分区键必须具有相同的数据类型,并且子分区集合必须一一匹配。启用此设置后,最终计划中内存用量受 work_mem 限制的节点数量可能随所扫描分区的数量线性增加。这可能大幅增加查询执行期间的总内存消耗。查询规划在内存和 CPU 方面的开销也会显著增加。默认值为 off - enable_partitionwise_aggregate (boolean) - enable_partitionwise_aggregate配置参数 + enable_partitionwise_aggregate 配置参数 - - 启用或禁用查询规划器使用分区分组或聚合的功能,该功能允许在分区表上分别对每个分区执行分组或聚合操作。 - 如果GROUP BY子句不包括分区键,那么只能在每个分区的基础上执行部分聚合,并且必须在稍后进行最终化处理。 - 由于分区分组或聚合在规划期间可能会使用更多的CPU时间和内存,因此默认情况下为off。 + 启用或禁用查询规划器对分区分组或聚合的使用,使分区表上的分组或聚合可以在各个分区上分别执行。如果 GROUP BY 子句不包含分区键,则只能在各分区上执行部分聚合,随后还必须进行最终处理。启用此设置后,最终计划中内存用量受 work_mem 限制的节点数量可能随所扫描分区的数量线性增加。这可能大幅增加查询执行期间的总内存消耗。查询规划在内存和 CPU 方面的开销也会显著增加。默认值为 off - - + + - + enable_presorted_aggregate (boolean) enable_presorted_aggregate配置参数 @@ -5299,7 +4911,7 @@ ANY num_sync ( 包括在普通日志项中。只有可打印 ASCII 字符能被使用在application_name之中。其他字符将被替换为问号(?)。 + application_name可以是任意小于NAMEDATALEN个字符(标准编译中是 64 个字符)的字符串。应用通常在连接服务器时设置此值。该名称将被显示在pg_stat_activity视图中并被包括在 CSV 日志项中。它也会被通过包括在普通日志项中。只有可打印 ASCII 字符能被使用在application_name之中。其他字符将被替换为C 风格的十六进制转义序列。 @@ -6249,7 +5861,7 @@ local0.* /var/log/postgresql 出于向后兼容性考虑,onofftruefalseyesno10仍然受支持。 - 正向值等价于指定receiptauthentication和 + 表示启用的值等价于指定receiptauthenticationauthorization选项。 @@ -6261,7 +5873,7 @@ local0.* /var/log/postgresql - 某些客户端程序(例如psql)在要求密码时会尝试连接两次,因此重复的收到连接消息并不一定表示一个错误。 + 某些客户端程序(例如psql)在判断是否需要密码时会尝试连接两次,因此重复的收到连接消息并不一定表示一个错误。 @@ -6410,6 +6022,11 @@ local0.* /var/log/postgresql 远程主机名或 IP 地址 + + %L + 本地地址(客户端所连接的服务器 IP 地址) + + %b @@ -6479,13 +6096,13 @@ local0.* /var/log/postgresql %v - 虚拟事务 ID (backendID/localXID) + 虚拟事务 ID (procNumber/localXID);参见 %x - 事务 ID (如果未分配则为 0) + 事务 ID (如果未分配则为 0);参见 @@ -6504,7 +6121,7 @@ local0.* /var/log/postgresql %% - 纯文字 % + 字面字符 % @@ -6538,7 +6155,7 @@ FROM pg_stat_activity; - Syslog产生自己的时间戳和进程 ID 信息,因此如果你记录到syslog你可能不希望包括哪些转义。 + Syslog产生自己的时间戳和进程 ID 信息,因此如果你记录到syslog你可能不希望包括那些转义。 @@ -6579,6 +6196,21 @@ log_line_prefix = '%m [%p] %q%u@%d/%a ' + + log_lock_failures (boolean) + + log_lock_failures配置参数 + + + + + 控制当获取锁失败时是否生成详细日志消息。这有助于分析锁失败的原因。 + 目前,仅支持由于SELECT NOWAIT导致的锁失败。 + 默认值为off。只有超级用户和具有适当SET权限的用户才能更改此设置。 + + + + log_recovery_conflict_waits (boolean) @@ -6600,21 +6232,6 @@ log_line_prefix = '%m [%p] %q%u@%d/%a ' - - log_lock_failures (boolean) - - log_lock_failures配置参数 - - - - - 控制当获取锁失败时是否生成详细日志消息。这有助于分析锁失败的原因。 - 目前,仅支持由于SELECT NOWAIT导致的锁失败。 - 默认值为off。只有超级用户和具有适当SET权限的用户才能更改此设置。 - - - - log_parameter_max_length (integer) @@ -7087,12 +6704,12 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 为不同目的设置标识这个数据库集簇(实例)的名称。此集簇名称出现在该集簇中所有服务器进程的进程标题中。 - 此外,它还是备库连接的默认应用名称。(参见 .) + 设置一个用于各种目的、标识此数据库集簇(实例)的名称。集簇名称会出现在此集簇所有服务器进程的进程标题中。 + 此外,它还是备库连接的默认应用名称(参见)。 - 这个名称可以是任何长度不超过NAMEDATALEN个字符(在标准编译中是 64字符)的任何字符串。只有可打印的 ASCII 字符能被用在cluster_name值中。其他字符将被替换为问号(?)。如果这个参数被设置为空字符串''(也是默认值),将不会显示名称。这个参数只能在服务器启动时设置。 + 这个名称可以是任何长度少于NAMEDATALEN个字符(在标准编译中是 64字符)的任何字符串。只有可打印的 ASCII 字符能被用在cluster_name值中。其他字符将被替换为C 风格的十六进制转义序列。如果这个参数被设置为空字符串''(也是默认值),将不会显示名称。这个参数只能在服务器启动时设置。 @@ -7194,32 +6811,39 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 启用基于成本的清理延迟计时(参见)。 - 默认情况下该参数关闭,因为它需要反复查询操作系统当前时间,在某些平台上可能带来显著开销。 - 你可以使用pg_test_timing来衡量系统上的计时开销。 - 基于成本的清理延迟计时信息会显示在pg_stat_progress_vacuum、 - pg_stat_progress_analyze中, - 也会显示在带有VERBOSE选项的VACUUMANALYZE输出中, - 并且当设置了时,autovacuum 还会为自动清理和自动分析记录这些信息。 - 只有超级用户和具有适当SET权限的用户才能更改此设置。 + 启用基于代价的清理延迟计时(参见)。 + 默认情况下该参数关闭,因为它需要反复查询操作系统当前时间,在某些平台上可能带来显著开销。 + 你可以使用 工具来衡量系统上的计时开销。 + 基于代价的清理延迟计时信息会显示在pg_stat_progress_vacuum、 + pg_stat_progress_analyze中, + 也会显示在带有VERBOSE选项的输出中, + 并且当设置了时,autovacuum 还会为自动清理和自动分析记录这些信息。 + 只有超级用户和具有适当SET权限的用户才能更改此设置。 - track_io_timing (boolean) - track_io_timing配置参数 + track_io_timing 配置参数 - - 启用数据库I/O调用的计时。 默认情况下,此参数处于关闭状态,因为它将重复查询操作系统的当前时间,这可能会在某些平台上造成显著的开销。 您可以使用工具来测量系统上计时的开销。 - I/O计时信息显示在 - pg_stat_database中,在的输出中,当使用BUFFERS选项时,在的输出中,当使用VERBOSE选项时,由autovacuum执行自动清理和自动分析时,当设置了时,以及由。 - 只有超级用户和具有适当SET权限的用户才能更改此设置。 + 启用数据库 I/O 等待的计时。此参数默认关闭,因为计时需要反复向操作系统查询 + 当前时间,在某些平台上可能会产生显著开销。可以使用 工具 + 测量本系统上的计时开销。I/O 计时信息会显示在 + pg_stat_database 中、 + pg_stat_io 中(当 object 不是 wal 时)、 + pg_stat_get_backend_io() 函数的输出中 + (当 object 不是 wal 时)、 + 使用 BUFFERS 选项的 输出中、 + 使用 VERBOSE 选项的 输出中, + autovacuum 也会在执行自动清理和自动分析时输出这些信息 + (需设置 ), + 同样提供这些信息。只有超级用户和具有适当 + SET 权限的用户可以更改此设置。 @@ -7234,14 +6858,8 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 启用WAL I/O调用的定时。此参数默认关闭,因为它将重复查询操作系统的当前时间, - 这可能会在某些平台上造成显著的开销。 - 您可以使用pg_test_timing工具来 - 测量系统上定时的开销。 - I/O定时信息显示在 - pg_stat_wal中。 - 只有超级用户和具有适当SET权限的用户才能更改此设置。 - + 启用 WAL I/O 等待的计时。此参数默认关闭,因为它会反复向操作系统查询当前时间,可能在某些平台上产生显著开销。可以使用 pg_test_timing 工具测量系统上的计时开销。I/O 计时信息显示在 pg_stat_ioobjectwal 的行,以及 pg_stat_get_backend_io() 函数输出中 objectwal 的行。只有超级用户和具有适当 SET 权限的用户才能更改此设置。 + @@ -7336,7 +6954,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 确认只有一个查询标识符被计算和显示,如果一个查询标识符已经被计算,扩展计算标识符将抛出一个错误。 + 为确保只有一个查询标识符被计算和显示,计算查询标识符的扩展在查询标识符已被计算时应当抛出一个错误。 @@ -7385,19 +7003,19 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - Vacuuming + 清理 - 自动清理 + 清理 配置参数 - 这些参数控制 vacuuming 的行为。有关 vacuum 的目的和职责的更多信息,请参阅。 + 这些参数控制清理的行为。有关清理的目的和职责的更多信息,请参阅 - 自动 Vacuuming + 自动清理 这些设置控制autovacuum特性的行为。详情请参考 @@ -7424,7 +7042,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 注意即使该参数被禁用,系统也会在需要防止事务ID回卷时发起清理进程。详情请见。 + 注意即使该参数被禁用,系统也会在需要防止事务ID回卷时发起自动清理进程。详情请见 @@ -7456,7 +7074,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 指定能同时运行的自动清理进程(除了自动清理启动器之外)的最大数量。默认值为3。该参数只能在服务器启动时设置。 + 指定能同时运行的自动清理进程(除了自动清理启动器之外)的最大数量。默认值为3。该参数只能在postgresql.conf文件或服务器命令行中设置。 请注意,如果该值被设置得高于,将不会产生任何效果,因为 autovacuum 工作进程是从该设置建立的槽位池中获取的。 @@ -7474,29 +7092,13 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 指定自动清理在任意给定数据库上运行的最小延迟。在每一轮中后台进程检查数据库并根据需要为数据库中的表发出VACUUMANALYZE命令。 + 指定自动清理在任意给定数据库上各次运行之间的最小间隔。在每一轮中后台进程检查数据库并根据需要为数据库中的表发出VACUUMANALYZE命令。 如果指定值时没有单位,则以秒为单位。默认值为1分钟(1min)。该参数只能在postgresql.conf文件或在服务器命令行上设置。 - - autovacuum_vacuum_max_threshold (integer) - - autovacuum_vacuum_max_threshold配置参数 - - - - - 指定在任意一个表上触发VACUUM所需更新或删除元组数的最大值,也就是对 - autovacuum_vacuum_threshold和 - autovacuum_vacuum_scale_factor计算结果所施加的上限。 - 默认值为 100,000,000 个元组。如果指定为-1,autovacuum 将不会对触发 - VACUUM所需的更新或删除元组数强制施加最大值。 - 该参数只能在postgresql.conf文件中或服务器命令行上设置;但可以通过更改表存储参数覆盖单个表的该设置。 - - - + @@ -7527,7 +7129,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; 指定在任何一个表中触发 VACUUM所需要插入的元组数。默认值为 1000 个元组。 如果指定了 -1,则autovacuum不会根据插入数量在任何表上触发 VACUUM操作。 - 此参数只能在postgresql.conf文件或服务器命令行中设置;但可以通过更改表存储参数来覆盖单个表的设置。 + 此参数只能在postgresql.conf文件或服务器命令行中设置;但可以通过更改表存储参数来覆盖单个表的设置。 @@ -7559,7 +7161,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 指定一个表尺寸的分数,在决定是否触发VACUUM时将它加到autovacuum_vacuum_threshold上。默认值为0.2(表尺寸的20%)。该参数只能在postgresql.conf文件或在服务器命令中设置。但是对个别表可以通过修改表存储参数来覆盖该设置。 + 指定一个表尺寸的分数,在决定是否触发VACUUM时将它加到autovacuum_vacuum_threshold上。默认值为0.2(表尺寸的20%)。该参数只能在postgresql.conf文件或在服务器命令中设置。但是对个别表可以通过修改表存储参数来覆盖该设置。 @@ -7575,8 +7177,9 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 指定一个要添加到autovacuum_vacuum_insert_threshold 中的表的大小的比例,在决定是否触发VACUUM时。 - 默认值为 0.2(表大小的 20%)。此参数只能在postgresql.conf文件或服务器命令行中设置;但可以通过更改表存储参数来覆盖单个表的设置。 + 指定表中未冻结页面的比例,在决定是否触发VACUUM时,将由该比例计算出的数量加到 + autovacuum_vacuum_insert_threshold上。默认值为0.2(表中未冻结页面的 20%)。 + 该参数只能在postgresql.conf文件或服务器命令行中设置;但可以通过更改表存储参数为单个表覆盖该设置。 @@ -7592,11 +7195,29 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 指定一个表尺寸的分数,在决定是否触发ANALYZE时将它加到autovacuum_analyze_threshold上。默认值为0.1(表尺寸的10%)。该参数只能在postgresql.conf文件或在服务器命令中设置。但是对个别表可以通过修改表存储参数来覆盖该设置。 + 指定一个表尺寸的分数,在决定是否触发ANALYZE时将它加到autovacuum_analyze_threshold上。默认值为0.1(表尺寸的10%)。该参数只能在postgresql.conf文件或在服务器命令中设置。但是对个别表可以通过修改表存储参数来覆盖该设置。 + + autovacuum_vacuum_max_threshold (integer) + + autovacuum_vacuum_max_threshold配置参数 + + + + + 指定在任意一个表上触发VACUUM所需更新或删除元组数的最大值,也就是对 + autovacuum_vacuum_threshold和 + autovacuum_vacuum_scale_factor计算结果所施加的上限。 + 默认值为 100,000,000 个元组。如果指定为-1,autovacuum 将不会对触发 + VACUUM所需的更新或删除元组数强制施加最大值。 + 该参数只能在postgresql.conf文件中或服务器命令行上设置;但可以通过更改表存储参数覆盖单个表的该设置。 + + + + autovacuum_freeze_max_age (integer) @@ -7665,7 +7286,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 指定用于自动VACUUM操作中的代价限制值。如果指定-1(默认值),则使用值。注意该值被按比例地分配到运行中的自动清理工作者上(如果有多个),因此每一个工作者的限制值之和不会超过这个变量中的值。该参数只能在postgresql.conf文件或在服务器命令中设置。但是对个别表可以通过修改表存储参数来覆盖该设置。 + 指定用于自动VACUUM操作中的代价限制值。如果指定-1(默认值),则使用值。注意该值被按比例地分配到运行中的自动清理工作进程上(如果有多个),因此每一个工作进程的限制值之和不会超过这个变量中的值。该参数只能在postgresql.conf文件或在服务器命令中设置。但是对个别表可以通过修改表存储参数来覆盖该设置。 @@ -7673,6 +7294,108 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; + + 基于代价的清理延迟 + + + 执行 命令期间,系统维护一个内部计数器,记录已执行的各种 I/O 操作的估算代价。 + 当累计代价达到上限(由 vacuum_cost_limit 指定)时,执行该操作的进程会休眠一小段时间,时长由 vacuum_cost_delay 指定。 + 随后重置计数器并继续执行。 + + + + 此功能让管理员能够降低这些命令对并发数据库活动的 I/O 影响。在许多情况下,VACUUMANALYZE 等维护命令是否快速完成并不重要, + 但避免它们显著干扰系统执行其他数据库操作的能力通常很重要。基于代价的清理延迟为管理员提供了实现这一点的方法。 + + + + 对于手动执行的 VACUUM 命令,此功能默认禁用。要启用它,将 vacuum_cost_delay 变量设为非零值。 + + + + + + vacuum_cost_delay (floating point) + + vacuum_cost_delay配置参数 + + + + + 超过代价上限后,进程将休眠的时长。如果未指定单位,则以毫秒为单位。默认值为 0,表示禁用基于代价的清理延迟功能。正值会启用基于代价的清理。 + + + 使用基于代价的清理时,vacuum_cost_delay 的合适值通常很小,可能不到 1 毫秒。虽然 vacuum_cost_delay 可以设为以毫秒为单位的小数值,但较旧的平台可能无法准确计量这种延迟。在这些平台上,若要让 VACUUM 的资源用量超过延迟设为 1ms 时的水平,需要调整其他清理代价参数。尽管如此,仍应将 vacuum_cost_delay 设为平台能够稳定计量的尽可能小的值;较大的延迟没有帮助。 + + + + + + + vacuum_cost_page_hit (integer) + + vacuum_cost_page_hit配置参数 + + + + + 清理在共享缓冲区缓存中找到的缓冲区时所计入的估算代价。它表示锁定缓冲池、查找共享哈希表和扫描页内容的代价。默认值为 1。 + + + + + + + vacuum_cost_page_miss (integer) + + vacuum_cost_page_miss配置参数 + + + + + 清理必须从磁盘读取的缓冲区时所计入的估算代价。它表示锁定缓冲池、查找共享哈希表、从磁盘读取所需数据块并扫描其内容所需的工作量。默认值为 2。 + + + + + + + vacuum_cost_page_dirty (integer) + + vacuum_cost_page_dirty配置参数 + + + + + 清理操作修改原本干净的数据块时所计入的估算代价。它表示再次将脏块刷盘所需的额外 I/O。默认值为 20。 + + + + + + + vacuum_cost_limit (integer) + + vacuum_cost_limit配置参数 + + + + + 会使清理进程休眠 vacuum_cost_delay 指定时长的累计代价。默认值为 200。 + + + + + + + + 某些操作持有关键的锁,因此应尽快完成。这些操作期间不会发生基于代价的清理延迟,所以累计代价可能远超指定上限。 + 为避免此时出现无益的长时间延迟,实际延迟按 vacuum_cost_delay * accumulated_balance / vacuum_cost_limit 计算, + 但最大不超过 vacuum_cost_delay * 4。 + + + + 默认行为 @@ -7697,10 +7420,14 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 冻结 (Freezing) + 冻结 - 这些设置控制旧行版本的冻结。更多信息请参阅。 + 为了在事务 ID 回卷后仍保持正确性,PostgreSQL会将足够旧的行标记为已冻结。 + 这些行对所有事务都可见;其他事务不必检查插入这些行的 XID 就能确定其可见性。 + VACUUM负责将行标记为已冻结。以下设置控制VACUUM的冻结行为, + 应根据系统的 XID 消耗速率以及主要工作负载的数据访问模式进行调整。 + 有关事务 ID 回卷和这些参数的调优,详见 @@ -7712,7 +7439,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 当表的pg_class.relfrozenxid字段达到该设置指定的年龄时,VACUUM会执行激进扫描。激进扫描与常规VACUUM不同,它会访问每一个可能包含未冻结 XID 或 MXID 的页面,而不仅仅是那些可能包含死元组的页面。默认值是 1.5 亿个事务。尽管用户可以将该值设置为 0 到 20 亿之间的任意值,VACUUM会悄悄将有效值调整为的 95%,从而在触发防回卷 autovacuum 之前仍有机会执行一次常规手工VACUUM。更多信息请参见。 + 当表的pg_class.relfrozenxid字段达到该设置指定的年龄时,VACUUM会执行激进扫描。激进扫描与常规VACUUM不同,它会访问每一个可能包含未冻结 XID 或 MXID 的页面,而不仅仅是那些可能包含死元组的页面。默认值是 1.5 亿个事务。尽管用户可以将该值设置为 0 到 20 亿之间的任意值,VACUUM会悄悄将有效值限制为不超过的 95%,从而在触发防回卷 autovacuum 之前仍有机会执行一次常规手工VACUUM。更多信息请参见 @@ -7725,7 +7452,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 指定VACUUM在扫描表时用来决定是否冻结行版本的切断年龄(以事务计)。默认值是 5000 万个事务。尽管用户可以将该值设置为 0 到 10 亿之间的任意值,VACUUM会悄悄将有效值调整为的一半,这样强制 autovacuum 之间就不会间隔过短。更多信息请参见。 + 指定VACUUM用来决定是否触发对含有较旧 XID 的页面进行冻结的截止年龄(以事务计)。默认值是 5000 万个事务。尽管用户可以将该值设置为 0 到 10 亿之间的任意值,VACUUM会悄悄将有效值限制为不超过的一半,这样强制 autovacuum 之间就不会间隔过短。更多信息请参见 @@ -7741,7 +7468,10 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; 指定表的pg_class.relfrozenxid字段在VACUUM采取特别措施以避免系统范围事务 ID 回卷失败之前所允许达到的最大年龄(以事务计)。这是VACUUM的最后防线。失效保护通常会在防止事务 ID 回卷的 autovacuum 已经运行了一段时间后触发,但也有可能在任何VACUUM期间触发。 - 当失效保护被触发时,将不再应用任何有效的基于成本的延迟,并且会跳过进一步的非关键维护任务(例如索引 vacuum)。 + 当失效保护被触发时,将不再应用任何有效的基于代价的延迟,并且会跳过进一步的非关键维护任务(例如索引清理),而且任何正在使用的 + 缓冲区访问策略 + 都会被禁用,使 VACUUM 可以自由使用全部 + 共享缓冲区 默认值为 16 亿个事务。尽管用户可以将该值设置为 0 到 21 亿之间的任意值,VACUUM会悄悄将有效值调整为不低于的 105%。 @@ -7757,7 +7487,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 当表的pg_class.relminmxid字段达到该设置指定的年龄时,VACUUM会执行激进扫描。激进扫描与常规VACUUM不同,它会访问每一个可能包含未冻结 XID 或 MXID 的页面,而不是只扫描那些可能包含死元组的页面。默认值是 1.5 亿个 multixact。尽管用户可以将该值设置为 0 到 20 亿之间的任意值,VACUUM会悄悄将有效值调整为的 95%,从而在触发防回卷 autovacuum 之前仍有机会执行一次常规手工VACUUM。更多信息请参见。 + 当表的pg_class.relminmxid字段达到该设置指定的年龄时,VACUUM会执行激进扫描。激进扫描与常规VACUUM不同,它会访问每一个可能包含未冻结 XID 或 MXID 的页面,而不是只扫描那些可能包含死元组的页面。默认值是 1.5 亿个多事务。尽管用户可以将该值设置为 0 到 20 亿之间的任意值,VACUUM会悄悄将有效值限制为不超过的 95%,从而在触发防回卷 autovacuum 之前仍有机会执行一次常规手工VACUUM。更多信息请参见 @@ -7770,29 +7500,31 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 指定VACUUM在扫描表时用来决定是否将 multixact ID 替换为较新的事务 ID 或 multixact ID 的切断年龄(以 multixact 计)。默认值是 5000 万个 multixact。尽管用户可以将该值设置为 0 到 10 亿之间的任意值,VACUUM会悄悄将有效值调整为的一半,这样强制 autovacuum 之间就不会间隔过短。更多信息请参见。 + 指定VACUUM用来决定是否触发对含有较旧多事务 ID 的页面进行冻结的截止年龄(以多事务计)。默认值是 500 万个多事务。尽管用户可以将该值设置为 0 到 10 亿之间的任意值,VACUUM会悄悄将有效值限制为不超过的一半,这样强制 autovacuum 之间就不会间隔过短。更多信息请参见 + + - vacuum_multixact_failsafe_age (integer) - - vacuum_multixact_failsafe_age配置参数 - - - + vacuum_multixact_failsafe_age (integer) + + vacuum_multixact_failsafe_age 配置参数 + + + - 指定表的pg_class.relminmxid字段在VACUUM采取特别措施以避免系统范围 multixact ID 回卷失败之前所允许达到的最大年龄(以 multixact 计)。这是VACUUM的最后防线。失效保护通常会在防止事务 ID 回卷的 autovacuum 已经运行了一段时间后触发,但也有可能在任何VACUUM期间触发。 + 指定表的 pg_class.relminmxid 字段在 VACUUM 采取特别措施避免系统范围的多事务 ID 回卷故障之前,所能达到的最大年龄(以多事务计)。这是 VACUUM 的最后手段。失效保护通常会在防止事务 ID 回卷的自动清理已经运行一段时间后触发,但也可能在任何 VACUUM 期间触发。 - 当失效保护被触发时,将不再应用任何有效的基于成本的延迟,并且会跳过进一步的非关键维护任务(例如索引 vacuum)。 + 触发失效保护后,任何正在生效的基于代价的延迟都将不再应用,后续非必要的维护任务(例如索引清理)也会被跳过。 - 默认值为 16 亿个 multixact。尽管用户可以将该值设置为 0 到 21 亿之间的任意值,VACUUM会悄悄将有效值调整为不低于的 105%。 + 默认值为 16 亿个多事务。虽然用户可以将此值设置为 0 到 21 亿之间的任意值,VACUUM 仍会将实际生效值自动调整为不低于 的 105%。 - + vacuum_max_eager_freeze_failure_rate (floating point) @@ -7802,10 +7534,10 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 指定VACUUM在积极扫描模式下可以扫描但未能在可见性映射中设置为 all-frozen 的页面数量占整个关系总页面数的比例,超过该比例后就会禁用积极扫描。值0表示完全禁用积极扫描。默认值为0.03(3%)。 + 指定VACUUM在急切扫描模式下可以扫描但未能在可见性映射中设置为 all-frozen 的页面数量占整个关系总页面数的比例,超过该比例后就会禁用急切扫描。值0表示完全禁用急切扫描。默认值为0.03(3%)。 - 请注意,当积极扫描启用时,只有冻结失败才会计入上限,成功的冻结不会计入。成功冻结的页面在内部会被限制为关系中所有 all-visible 但未 all-frozen 页面数的 20%。对成功冻结页面设置上限有助于将成本分摊到多次常规 vacuum 中,并限制在下次积极 vacuum 之前页面再次被修改时积极冻结可能带来的浪费。 + 请注意,当急切扫描启用时,只有冻结失败才会计入上限,成功的冻结不会计入。成功冻结的页面在内部会被限制为关系中所有 all-visible 但未 all-frozen 页面数的 20%。对成功冻结页面设置上限有助于将成本分摊到多次常规清理 中,并限制在下次激进清理 之前页面再次被修改时急切冻结可能带来的浪费。 这个参数只能在postgresql.conf文件中或服务器命令行上设置; @@ -7859,7 +7591,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; search_path配置参数 - pathfor schemas + 路径用于模式 @@ -7952,7 +7684,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; default_tablespace配置参数 - tablespacedefault + 表空间默认 @@ -8057,7 +7789,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; default_transaction_isolation (enum) - transaction isolation level + 事务隔离级别 设置默认值 @@ -8080,7 +7812,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; default_transaction_read_only (boolean) - read-only transaction + 只读事务 设置默认值 @@ -8103,7 +7835,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; default_transaction_deferrable (boolean) - deferrable transaction + 可延迟事务 设置默认值 @@ -8130,7 +7862,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; transaction_isolation (enum) - transaction isolation level + 事务隔离级别 transaction_isolation配置参数 @@ -8150,7 +7882,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; transaction_read_only (boolean) - read-only transaction + 只读事务 transaction_read_only 配置参数 @@ -8170,7 +7902,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; transaction_deferrable (boolean) - deferrable transaction + 可延迟事务 transaction_deferrable 配置参数 @@ -8314,7 +8046,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; 此选项可以用于确保空闲会话不会在不合理的时间内持有锁。 - 即使没有持有重要的锁的时候,打开的事务也会防止清理最近死亡的可能只对这个事务可见的元组;所以长时间保持空闲会导致表膨胀。 + 即使没有持有重要的锁的时候,打开的事务也会防止清理最近死亡的可能只对这个事务可见的元组;所以长时间保持空闲会导致表膨胀。 详见 @@ -8390,7 +8122,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; SET XML OPTION - XML option + XML 选项 @@ -8428,6 +8160,54 @@ SET XML OPTION { DOCUMENT | CONTENT }; + + createrole_self_grant (string) + + createrole_self_grant配置参数 + + + + + 如果一个拥有CREATEROLE但不拥有SUPERUSER权限的用户创建了角色,并且此选项被设置为非空值,则新创建的角色将以指定选项授予创建者。 + 该值必须是setinherit或它们的逗号分隔列表。默认值为空字符串,这会禁用此功能。 + + + 此选项的目的是允许非超级用户的CREATEROLE用户自动继承或自动获得对新创建角色执行SET ROLE的能力。 + 由于CREATEROLE用户始终会隐式获得其所创建角色的ADMIN OPTION,因此该用户总是可以通过执行GRANT语句达到相同效果,但自动授予在可用性上更方便。 + 超级用户会自动继承每个角色的权限,并且始终可以切换到任何角色;此设置可让CREATEROLE用户对其创建的用户获得类似的行为。 + + + + + + event_triggers (boolean) + + event_triggers配置参数 + + + + + 允许临时禁用事件触发器的执行,以便对有故障的事件触发器进行故障排查和修复。 + 将其设置为false会禁用所有事件触发器;设置为true则允许所有事件触发器触发,这也是默认值。 + 只有超级用户和具有适当SET权限的用户才能更改此设置。 + + + + + + restrict_nonsystem_relation_kind (string) + + restrict_nonsystem_relation_kind配置参数 + + + + + 设置禁止访问非系统关系的关系类型。该值采用关系类型的逗号分隔列表形式。 + 目前支持的关系类型是viewforeign-table。 + + + + @@ -8476,7 +8256,7 @@ SET XML OPTION { DOCUMENT | CONTENT }; TimeZone配置参数 - time zone + 时区 @@ -8492,7 +8272,7 @@ SET XML OPTION { DOCUMENT | CONTENT }; timezone_abbreviations配置参数 - time zone names + 时区名称 @@ -8506,11 +8286,11 @@ SET XML OPTION { DOCUMENT | CONTENT }; extra_float_digits (integer) - significant digits + 有效数字 - floating-point - display + 浮点数 + 显示 extra_float_digits配置参数 @@ -8538,7 +8318,7 @@ SET XML OPTION { DOCUMENT | CONTENT }; - 此参数的含义,以及其默认值,在 PostgreSQL 12 中发生了变化; + 此参数的含义,以及其默认值,在 PostgreSQL 12 中发生了变化; 参见 以便进一步讨论。 @@ -8551,7 +8331,7 @@ SET XML OPTION { DOCUMENT | CONTENT }; client_encoding配置参数 - character set + 字符集 @@ -8911,8 +8691,12 @@ extension_control_path = 'C:\tools\postgresql;H:\my_project\share;$system' 推荐在postgresql.conf中设置该参数。 - 请注意,如果你设置该参数以便从非标准位置加载扩展,那么通常还需要把设置为相应的位置。 - + 请注意,如果设置此参数以便从非标准位置加载扩展,通常还需要将设置为相应的位置,例如: + +extension_control_path = '/usr/local/share/postgresql:$system' +dynamic_library_path = '/usr/local/lib/postgresql:$libdir' + + @@ -8945,12 +8729,12 @@ extension_control_path = 'C:\tools\postgresql;H:\my_project\share;$system' deadlock_timeout (integer) - deadlock + 死锁 期间超时 - timeout - deadlock + 超时 + 死锁 deadlock_timeout配置参数 @@ -8985,14 +8769,11 @@ extension_control_path = 'C:\tools\postgresql;H:\my_project\share;$system' - 共享锁表跟踪在max_locks_per_transaction * ( + ) 个对象(如表)上的锁。因此,在任何一个时刻,只有不超过这么多个可区分对象能够被锁住。这个参数控制为每个事务分配的对象锁的平均数量。个体事务可以锁住更多对象,数量可以和锁表中能容纳的所有事务的锁一样多。这是能被锁住的行数,那个值是没有限制的。默认值 64 已经被历史证明是足够的,但是如果你有需要在一个事务中使用很多不同表的查询(例如查询一个有很多子表的父表),你可能需要提高这个值。这个参数只能在服务器启动时设置。 + 共享锁表为每个服务器进程或预备事务预留可容纳max_locks_per_transaction 个对象(例如表)的空间;因此,在任何时刻可被锁住的不同对象数都不能超过总容量。这个参数限制每个事务使用的对象锁的平均数量;只要所有事务的锁能放入锁表中,单个事务就可以锁住更多对象。这是能被锁住的行数,那个值是没有限制的。默认值 64 已经被历史证明是足够的,但是如果你有需要在一个事务中使用很多不同表的查询(例如查询一个有很多子表的父表),你可能需要提高这个值。这个参数只能在服务器启动时设置。 - 当运行一个备库时,你必须设置这个参数等于或大于主库上的参数。 - 否则,备库上可能无法允许查询。 + 运行备库时,必须将此参数设置为大于或等于主库上的值。否则,备库上将不允许查询。 @@ -9007,9 +8788,7 @@ extension_control_path = 'C:\tools\postgresql;H:\my_project\share;$system' - 共享谓词锁表跟踪在max_pred_locks_per_transaction * ( + ) 个对象(如表)上的锁。因此,在任何一个时刻,只有不超过这么多个可区分对象能够被锁住。这个参数控制为每个事务分配的对象锁的平均数量。个体事务可以锁住更多对象,数量可以和锁表中能容纳的所有事务的锁一样多。这是能被锁住的行数,那个值是没有限制的。默认值 64 已经在测试中被证明通常是足够的,但是如果你有需要在一个可串行化事务中使用很多不同表的查询(例如查询一个有很多子表的父表),你可能需要提高这个值。这个参数只能在服务器启动时设置。 + 共享谓词锁表为每个服务器进程或预备事务预留可容纳max_pred_locks_per_transaction 个对象(例如表)的空间;因此,在任何时刻可被锁住的不同对象数都不能超过总容量。这个参数限制每个事务使用的对象锁的平均数量;只要所有事务的锁能放入锁表中,单个事务就可以锁住更多对象。这是能被锁住的行数,那个值是没有限制的。默认值 64 已经被历史证明是足够的,但是如果你有会在单个可串行化事务中访问许多不同表的客户端,则可能需要提高这个值。这个参数只能在服务器启动时设置。 @@ -9079,7 +8858,7 @@ extension_control_path = 'C:\tools\postgresql;H:\my_project\share;$system' backslash_quote (enum) - stringsbackslash quotes + 字符串反斜线引号 backslash_quote配置参数 @@ -9099,7 +8878,7 @@ extension_control_path = 'C:\tools\postgresql;H:\my_project\share;$system' escape_string_warning (boolean) - strings转义警告 + 字符串转义警告 escape_string_warning配置参数 @@ -9155,7 +8934,7 @@ extension_control_path = 'C:\tools\postgresql;H:\my_project\share;$system' standard_conforming_strings (boolean) - stringsstandard conforming + 字符串标准符合 standard_conforming_strings配置参数 @@ -9562,7 +9341,7 @@ extension_control_path = 'C:\tools\postgresql;H:\my_project\share;$system' server_encoding配置参数 - character set + 字符集 diff --git a/zh/18/datatype.sgml b/zh/18/datatype.sgml index 63ad0ac5..07cf22ec 100644 --- a/zh/18/datatype.sgml +++ b/zh/18/datatype.sgml @@ -354,19 +354,19 @@ smallint 2字节 小范围整数 - -32768 to +32767 + -32768 到 +32767 integer 4字节 整数的典型选择 - -2147483648 to +2147483647 + -2147483648 到 +2147483647 bigint 8字节 大范围整数 - -9223372036854775808 to +9223372036854775807 + -9223372036854775808 到 +9223372036854775807 @@ -866,9 +866,8 @@ FROM generate_series(-3.5, 3.5, 1) as x; - 本节描述的是 PostgreSQL 特有的创建 - 自动递增列的方法。另一种方法是使用 SQL 标准的标识列特性, - 参见 。 + 本节介绍 PostgreSQL 特有的自动递增列创建方法。 + 另一种方法是使用 SQL 标准的标识列特性,参见 @@ -947,7 +946,7 @@ ALTER SEQUENCE tablename_money 类型以固定的小数精度存储货币金额; 参见 。小数精度由数据库的 设置决定。表中显示的范围假定 - 有两位小数。输入支持多种格式,包括整数和浮点文字,以及典型的 + 有两位小数。输入支持多种格式,包括整数字面量和浮点数字面量,以及典型的 货币格式,例如 '$1,000.00'。输出通常也采用 后一种形式,但会受到区域设置影响。 @@ -1373,7 +1372,7 @@ SELECT '\xDEADBEEF'::bytea;
- <type>bytea</type>文字转义字节 + <type>bytea</type>字面量中需要转义的字节 @@ -2638,7 +2637,7 @@ SELECT '2 years 15 months 100 weeks 99 hours 123456789 milliseconds'::interval; 3 years 3 mons 700 days 133:17:36.789 - 这里,周被理解为 7 days,而较小和较大的时间单位 + 这里,周按7 天计算并单独保留,而较小和较大的时间单位 则被合并并规范化了。 @@ -4066,17 +4065,16 @@ a0ee-bc99-9c0b-4ef8-bb6d-6bb9-bd38-0a11 xml 数据类型可用于存储 XML 数据。与把 XML 数据存储在 - text 字段中相比,它的优势在于会检查输入值是否格式 - 良好,并且提供了可执行类型安全操作的支持函数;见 - 。使用该数据类型要求安装时启用 + text 字段中相比,它的优势在于会检查输入值的良构性,并且提供了可执行类型安全操作的支持函数;见 + 。使用该数据类型要求构建时使用 configure --with-libxml - xml 类型既可以存储符合 XML 标准定义的格式良好的 + xml 类型既可以存储 XML 标准所定义的良构 文档,也可以存储 内容 片段;后者是参照 XQuery 和 XPath 数据模型中更宽松的 - document node + 文档节点 概念来定义的。粗略地说,这意味着内容片段可以拥有多个顶层元素或字符 节点。表达式 xmlvalue IS DOCUMENT @@ -4245,7 +4243,7 @@ SET xmloption TO { DOCUMENT | CONTENT }; - 是一种用户定义的数据类型,它基于另一种底层类型。根据需要,它可以有约束来限制其有效值为底层类型所允许值的一个子集。如果没有约束,它的行为就和底层类型一样 — 例如,任何适用于底层类型的操作符或函数都对该域类型有效。底层类型可以是任何内置或者用户定义的基础类型、枚举类型、数组类型、复合类型、范围类型或者另一个域。 + 是一种用户定义的数据类型,它基于另一种底层类型。根据需要,它可以有约束来限制其有效值为底层类型所允许值的一个子集。除此之外,它的行为与底层类型相同 — 例如,任何适用于底层类型的操作符或函数都对该域类型有效。底层类型可以是任何内置或者用户定义的基础类型、枚举类型、数组类型、复合类型、范围类型或者另一个域。 diff --git a/zh/18/dblink.sgml b/zh/18/dblink.sgml index f93b91fa..b423a748 100644 --- a/zh/18/dblink.sgml +++ b/zh/18/dblink.sgml @@ -65,8 +65,8 @@ -dblink_connect(text connstr) 返回 text -dblink_connect(text connname, text connstr) 返回 text +dblink_connect(text connstr) returns text +dblink_connect(text connname, text connstr) returns text @@ -128,7 +128,7 @@ dblink_connect(text connname, text connstr) 返回 text 注解 - 如果不可信用户能够访问一个尚未采用模式的安全使用方式的数据库,则应在每个会话开始时从 + 如果不受信任的用户能够访问一个尚未采用模式的安全使用方式的数据库,则应在每个会话开始时从 search_path 中移除公共可写模式。例如,可以把 options=-csearch_path= 加到 connstr 中。这个注意事项并非 dblink 所特有;它适用于每一种执行任意 SQL 命令的接口。 @@ -139,7 +139,7 @@ dblink_connect(text connname, text connstr) 返回 text use_scram_passthrough,用于控制 dblink 是否在连接远程数据库时使用 SCRAM 透传认证。 该选项可为外部服务器或用户映射指定。用户映射的设置会覆盖外部服务器的设置。 - 使用 SCRAM 透传认证时,dblink 会使用 SCRAM 哈希后的凭据,而不是明文用户密码来连接远程服务器。 + 使用 SCRAM 透传认证时,dblink 会使用经 SCRAM Hash 处理的凭据,而不是明文用户密码来连接远程服务器。 这样可以避免在 PostgreSQL 系统目录中存储明文用户密码。关于更多细节和限制,请参见 postgres_fdw 中对应的 use_scram_passthrough @@ -174,10 +174,10 @@ SELECT dblink_connect('myconn', 'dbname=postgres options=-csearch_path='); OK (1 row) --- FOREIGN DATA WRAPPER functionality --- Note: local connections that don't use SCRAM pass-through require password --- authentication for this to work properly. Otherwise, you will receive --- the following error from dblink_connect(): +-- FOREIGN DATA WRAPPER 功能 +-- 注意:要使本例正常工作,不使用 SCRAM 透传的本地连接必须要求密码认证。 +-- 否则,dblink_connect() 将报告 +-- 以下错误: -- ERROR: password is required -- DETAIL: Non-superuser cannot connect if the server does not request a password. -- HINT: Target server's authentication method must be changed. @@ -240,8 +240,8 @@ DROP SERVER fdtest; -dblink_connect_u(text connstr) 返回 text -dblink_connect_u(text connname, text connstr) 返回 text +dblink_connect_u(text connstr) returns text +dblink_connect_u(text connname, text connstr) returns text @@ -261,7 +261,7 @@ dblink_connect_u(text connname, text connstr) 返回 text 因此,dblink_connect_u() 在初始安装时会撤销 PUBLIC 的全部权限,从而除了超级用户之外无法调用它。 在某些情况下,可能适合向被认为可信的特定用户授予 - EXECUTE 权限,但必须谨慎操作。还建议服务器用户的任何 + dblink_connect_u()EXECUTE 权限,但必须谨慎操作。还建议服务器用户的任何 ~/.pgpass 文件不要包含指定通配主机名的记录。 @@ -288,8 +288,8 @@ dblink_connect_u(text connname, text connstr) 返回 text -dblink_disconnect() 返回 text -dblink_disconnect(text connname) 返回 text +dblink_disconnect() returns text +dblink_disconnect(text connname) returns text @@ -361,9 +361,9 @@ SELECT dblink_disconnect('myconn'); -dblink(text connname, text sql [, bool fail_on_error]) 返回 setof record -dblink(text connstr, text sql [, bool fail_on_error]) 返回 setof record -dblink(text sql [, bool fail_on_error]) 返回 setof record +dblink(text connname, text sql [, bool fail_on_error]) returns setof record +dblink(text connstr, text sql [, bool fail_on_error]) returns setof record +dblink(text sql [, bool fail_on_error]) returns setof record @@ -440,7 +440,7 @@ SELECT * WHERE proname LIKE 'bytea%'; - FROM 子句中的 alias 部分必须指定该函数将返回的列名和类型。(在别名中指定列名实际上是标准 SQL 语法,但指定列类型则是 + FROM 子句中的 别名 部分必须指定该函数将返回的列名和类型。(在别名中指定列名实际上是标准 SQL 语法,但指定列类型则是 PostgreSQL 的扩展。)这样系统才能在尝试执行该函数之前,就知道 * 应展开成什么,以及 WHERE 子句中的 proname 指的是什么。运行时,如果远程数据库返回的实际查询结果与 @@ -560,9 +560,9 @@ SELECT * FROM dblink('myconn', 'select proname, prosrc from pg_proc') -dblink_exec(text connname, text sql [, bool fail_on_error]) 返回 text -dblink_exec(text connstr, text sql [, bool fail_on_error]) 返回 text -dblink_exec(text sql [, bool fail_on_error]) 返回 text +dblink_exec(text connname, text sql [, bool fail_on_error]) returns text +dblink_exec(text connstr, text sql [, bool fail_on_error]) returns text +dblink_exec(text sql [, bool fail_on_error]) returns text @@ -687,8 +687,8 @@ DETAIL: ERROR: null value in column "relnamespace" violates not-null constrain -dblink_open(text cursorname, text sql [, bool fail_on_error]) 返回 text -dblink_open(text connname, text cursorname, text sql [, bool fail_on_error]) 返回 text +dblink_open(text cursorname, text sql [, bool fail_on_error]) returns text +dblink_open(text connname, text cursorname, text sql [, bool fail_on_error]) returns text @@ -801,8 +801,8 @@ SELECT dblink_open('foo', 'select proname, prosrc from pg_proc'); -dblink_fetch(text cursorname, int howmany [, bool fail_on_error]) 返回 setof record -dblink_fetch(text connname, text cursorname, int howmany [, bool fail_on_error]) 返回 setof record +dblink_fetch(text cursorname, int howmany [, bool fail_on_error]) returns setof record +dblink_fetch(text connname, text cursorname, int howmany [, bool fail_on_error]) returns setof record @@ -944,8 +944,8 @@ SELECT * FROM dblink_fetch('foo', 5) AS (funcname name, source text); -dblink_close(text cursorname [, bool fail_on_error]) 返回 text -dblink_close(text connname, text cursorname [, bool fail_on_error]) 返回 text +dblink_close(text cursorname [, bool fail_on_error]) returns text +dblink_close(text connname, text cursorname [, bool fail_on_error]) returns text @@ -1050,7 +1050,7 @@ SELECT dblink_close('foo'); -dblink_get_connections() 返回 text[] +dblink_get_connections() returns text[] @@ -1066,7 +1066,7 @@ dblink_get_connections() 返回 text[] 返回值 - 返回一个包含连接名称的 text 数组;如果没有,则返回 NULL。 + 返回包含连接名称的文本数组;如果没有连接,则返回 NULL。 @@ -1095,7 +1095,7 @@ SELECT dblink_get_connections(); -dblink_error_message(text connname) 返回 text +dblink_error_message(text connname) returns text @@ -1166,7 +1166,7 @@ SELECT dblink_error_message('dtest1'); -dblink_send_query(text connname, text sql) 返回 int +dblink_send_query(text connname, text sql) returns int @@ -1241,7 +1241,7 @@ SELECT dblink_send_query('dtest1', 'SELECT * FROM foo WHERE f1 < 3'); -dblink_is_busy(text connname) 返回 int +dblink_is_busy(text connname) returns int @@ -1303,8 +1303,8 @@ SELECT dblink_is_busy('dtest1'); -dblink_get_notify() 返回 setof (notify_name text, be_pid int, extra text) -dblink_get_notify(text connname) 返回 setof (notify_name text, be_pid int, extra text) +dblink_get_notify() returns setof (notify_name text, be_pid int, extra text) +dblink_get_notify(text connname) returns setof (notify_name text, be_pid int, extra text) @@ -1383,7 +1383,7 @@ SELECT * FROM dblink_get_notify(); -dblink_get_result(text connname [, bool fail_on_error]) 返回 setof record +dblink_get_result(text connname [, bool fail_on_error]) returns setof record @@ -1529,7 +1529,7 @@ contrib_regression=# SELECT * FROM dblink_get_result('dtest1') AS t1(f1 int, f2 -dblink_cancel_query(text connname) 返回 text +dblink_cancel_query(text connname) returns text @@ -1592,7 +1592,7 @@ SELECT dblink_cancel_query('dtest1'); -dblink_get_pkey(text relname) 返回 setof dblink_pkey_results +dblink_get_pkey(text relname) returns setof dblink_pkey_results @@ -1681,7 +1681,7 @@ dblink_build_sql_insert(text relname, int2vector primary_key_attnums, integer num_primary_key_atts, text[] src_pk_att_vals_array, - text[] tgt_pk_att_vals_array) 返回 text + text[] tgt_pk_att_vals_array) returns text @@ -1750,7 +1750,7 @@ dblink_build_sql_insert(text relname, 返回值 - 以 text 形式返回所请求的 SQL 语句。 + 以文本形式返回所请求的 SQL 语句。 @@ -1797,7 +1797,7 @@ SELECT dblink_build_sql_insert('foo', '1 2', 2, '{"1", "a"}', '{"1", "b''a"}'); dblink_build_sql_delete(text relname, int2vector primary_key_attnums, integer num_primary_key_atts, - text[] tgt_pk_att_vals_array) 返回 text + text[] tgt_pk_att_vals_array) returns text @@ -1857,7 +1857,7 @@ dblink_build_sql_delete(text relname, 返回值 - 以 text 形式返回所请求的 SQL 语句。 + 以文本形式返回所请求的 SQL 语句。 @@ -1905,7 +1905,7 @@ dblink_build_sql_update(text relname, int2vector primary_key_attnums, integer num_primary_key_atts, text[] src_pk_att_vals_array, - text[] tgt_pk_att_vals_array) 返回 text + text[] tgt_pk_att_vals_array) returns text @@ -1975,7 +1975,7 @@ dblink_build_sql_update(text relname, 返回值 - 以 text 形式返回所请求的 SQL 语句。 + 以文本形式返回所请求的 SQL 语句。 diff --git a/zh/18/ddl.sgml b/zh/18/ddl.sgml index 75ca12b0..8b68c03c 100644 --- a/zh/18/ddl.sgml +++ b/zh/18/ddl.sgml @@ -317,7 +317,7 @@ CREATE TABLE people ( - 类似地,对于分区表,如果在CREATE TABLE ... PARTITION OF中编写子列定义时未写任何GENERATED子句,则会自动从父列复制该子句。ALTER TABLE ... ATTACH PARTITION要求父列和子列在生成状态上已经匹配,但不要求它们的生成表达式相同。 + 类似地,对于分区表,如果在CREATE TABLE ... PARTITION OF中编写子列定义时未写任何GENERATED子句,则会自动从父列复制该GENERATED子句。ALTER TABLE ... ATTACH PARTITION要求父列和子列在生成状态上已经匹配,但不要求它们的生成表达式相同。 @@ -3253,8 +3253,8 @@ CREATE TABLE measurement_y2008m02 PARTITION OF measurement 作为一种替代方案,有时更方便的是在分区结构之外创建新表,并稍后将其附加为分区。这允许在新数据出现在分区表中之前加载、检查和转换新数据。 - 此外,ATTACH PARTITION操作只需要在分区表上持有SHARE UPDATE EXCLUSIVE锁,而不像CREATE TABLE ... PARTITION OF那样需要ACCESS EXCLUSIVE锁,因此对分区表上的并发操作更友好。 - CREATE TABLE ... LIKE选项有助于避免繁琐地重复父表定义: + 此外,ATTACH PARTITION操作只需要在分区表上持有SHARE UPDATE EXCLUSIVE锁,而不像CREATE TABLE ... PARTITION OF那样需要ACCESS EXCLUSIVE锁,因此对分区表上的并发操作更友好;更多细节请参见ALTER TABLE ... ATTACH PARTITION。 + CREATE TABLE ... LIKE选项有助于避免繁琐地重复父表定义: CREATE TABLE measurement_y2008m02 @@ -3436,7 +3436,16 @@ ALTER INDEX measurement_city_id_logdate_key - 创建表,所有的表都将从它继承。这个表将不包含数据。不要在这个表上定义任何检查约束,除非想让它们应用到所有的子表上。同样,在这个表上定义索引或者唯一约束也没有意义。对于我们的示例来说,根表是最初定义的measurement表。 + 创建表,所有的表都将从它继承。这个表将不包含数据。不要在这个表上定义任何检查约束,除非想让它们应用到所有的子表上。同样,在这个表上定义索引或者唯一约束也没有意义。对于我们的示例来说,根表是最初定义的measurement表: + + +CREATE TABLE measurement ( + city_id int not null, + logdate date not null, + peaktemp int, + unitsales int +); + @@ -4045,7 +4054,7 @@ DROP TABLE products CASCADE; - 对于一个将其主体定义为字符串文字的用户定义函数或过程,PostgreSQL会跟踪与函数的外部可见属性相关的依赖关系,例如其参数和结果类型,但不会跟踪只有通过检查函数主体才能知道的依赖关系。例如,考虑以下情况: + 对于一个将其主体定义为字符串字面量的用户定义函数或过程,PostgreSQL会跟踪与函数的外部可见属性相关的依赖关系,例如其参数和结果类型,但不会跟踪只有通过检查函数主体才能知道的依赖关系。例如,考虑以下情况: CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', diff --git a/zh/18/dfunc.sgml b/zh/18/dfunc.sgml index 91898df4..61d916ac 100644 --- a/zh/18/dfunc.sgml +++ b/zh/18/dfunc.sgml @@ -46,7 +46,7 @@ FreeBSD - FreeBSDshared library + FreeBSD共享库 @@ -65,7 +65,7 @@ cc -shared -o foo.so foo.o Linux - Linuxshared library + Linux共享库 @@ -82,7 +82,7 @@ cc -shared -o foo.so foo.o macOS - macOSshared library + macOS共享库 @@ -98,7 +98,7 @@ cc -bundle -flat_namespace -undefined suppress -o foo.so foo.o NetBSD - NetBSDshared library + NetBSD共享库 @@ -116,7 +116,7 @@ gcc -shared -o foo.so foo.o OpenBSD - OpenBSDshared library + OpenBSD共享库 @@ -133,7 +133,7 @@ ld -Bshareable -o foo.so foo.o Solaris - Solarisshared library + Solaris共享库 diff --git a/zh/18/docguide.sgml b/zh/18/docguide.sgml index c0e8df51..1dacec9b 100644 --- a/zh/18/docguide.sgml +++ b/zh/18/docguide.sgml @@ -306,7 +306,7 @@ checking for dbtoepub... dbtoepub - 对于 U.S. letter 格式: + 对于美国信纸格式: doc/src/sgml$ make postgres-US.pdf @@ -320,7 +320,7 @@ checking for dbtoepub... dbtoepub 因此,在某些系统上,构建会因内存相关错误而失败。这通常可以通过在配置文件 ~/.foprc中配置 Java 堆设置来解决,例如: -# FOP binary distribution +# FOP 二进制发行版 FOP_OPTS='-Xmx1500m' # Debian JAVA_ARGS='-Xmx1500m' diff --git a/zh/18/ecpg.sgml b/zh/18/ecpg.sgml index 46ce5efb..c0e673a5 100644 --- a/zh/18/ecpg.sgml +++ b/zh/18/ecpg.sgml @@ -1139,7 +1139,7 @@ oid=313780, datname=testdb, size=8183012 - 结构体主变量将列尽数吸收成结构体的域。额外的列可以被分配给其他主变量。例如,上面的程序也可以使用结构体外部的size变量重新构造: + 结构体主变量吸收的列数与结构体的字段数相同。额外的列可以被分配给其他主变量。例如,上面的程序也可以使用结构体外部的size变量改写: EXEC SQL BEGIN DECLARE SECTION; typedef struct @@ -1440,7 +1440,7 @@ while (1) 用户定义的基础类型 - ECPG 并不直接支持新的用户定义的基本类型。你可以使用外部字符串表示以及类型char[]VARCHAR[]的主变量,并且这种方案事实上对很多类型都是合适和足够的。 + ECPG 并不直接支持新的用户定义的基础类型。你可以使用外部字符串表示以及类型char[]VARCHAR[]的主变量,并且这种方案事实上对很多类型都是合适和足够的。 @@ -4743,7 +4743,7 @@ EXEC SQL INCLUDE "filename"; 当前目录 /usr/local/include - PostgreSQL 的包括目录,在编译时定义(例如/usr/local/pgsql/include + PostgreSQL 的头文件目录,在编译时定义(例如/usr/local/pgsql/include /usr/include @@ -4870,7 +4870,7 @@ EXEC SQL UPDATE Tbl SET col = MYNUMBER; - 此示例将完全编译三个SET TIMEZONE命令之一: + 此示例将完全编译三个SET TIMEZONE命令之一: EXEC SQL ifdef TZVAR; EXEC SQL SET TIMEZONE TO TZVAR; @@ -5498,7 +5498,7 @@ DATABASE connection_target 使用 user_name/passworduser_name IDENTIFIED BY password或者 - user_name USING password之一,这个参数也能指定用户名和密码. + user_name USING password之一,这个参数也能指定用户名和密码。 @@ -6078,9 +6078,7 @@ EXECUTE IMMEDIATE string - 如果你使用文字字符串,请注意任何你可能希望在SQL语句中包括的双引号必须写为八进制转义(\042) ,而不是通常的C惯语\"。 - 这是因为字符串在EXEC SQL段里面,所以ECPG 语法分析器根据SQL规则而不是C规则来解析它。 - 任何内嵌的反斜杠后续将按照C规格处理;但是\"会造成直接语法错误,因为它被视为文字的终结。 + 如果使用字符串字面量,请注意,要在 SQL 语句中包含的双引号必须写为八进制转义(\042),而不是通常的 C 写法\"。这是因为字符串位于EXEC SQL段中,ECPG 词法分析器会按照 SQL 规则而非 C 规则解析它。内嵌的反斜杠随后会按照 C 规则处理;但\"会被视为字面量的结束,因此会立即引起语法错误。 @@ -6413,9 +6411,7 @@ PREPARE prepared_name FROM - 如果你使用文字字符串,请注意任何你可能希望在SQL语句中包括的双引号必须写为八进制转义(\042) ,而不是通常的C惯语\"。 - 这是因为字符串在EXEC SQL段里面,所以ECPG 语法分析器根据SQL规则而不是C规则来解析它。 - 任何内嵌的反斜杠后续将按照C规格处理;但是\"会造成直接语法错误,因为它被视为文字的终结。 + 如果使用字符串字面量,请注意,要在 SQL 语句中包含的双引号必须写为八进制转义(\042),而不是通常的 C 写法\"。这是因为字符串位于EXEC SQL段中,ECPG 词法分析器会按照 SQL 规则而非 C 规则解析它。内嵌的反斜杠随后会按照 C 规则处理;但\"会被视为字面量的结束,因此会立即引起语法错误。 @@ -7672,19 +7668,19 @@ int rjulmdy(date d, short mdy[3]); rdefmtdate - 使用格式掩码将字符字符串转换为日期类型的值。 + 使用格式掩码将字符串转换为日期类型的值。 int rdefmtdate(date *d, char *fmt, char *str); 该函数接收一个指向应该保存操作结果的日期值的指针(d), 用于解析日期的格式掩码(fmt)和包含日期文本表示的C char*字符串 (str)。文本表示应与格式掩码匹配。但是,你不需要将字符串 - 与格式掩码进行一一映射。该函数仅分析顺序顺序,并查找表示年份位置的文字 + 与格式掩码进行一一映射。该函数只分析先后顺序,并查找表示年份位置的字面文本 yyyyyy,表示月份位置的mm 和表示日期位置的dd - 该函数返回以下值: + 该函数返回以下值: diff --git a/zh/18/event-trigger.sgml b/zh/18/event-trigger.sgml index 1439bfb2..73f71eca 100644 --- a/zh/18/event-trigger.sgml +++ b/zh/18/event-trigger.sgml @@ -20,7 +20,7 @@ - 事件触发器行为概览 + 事件触发器行为概述 只要与事件触发器关联的事件在其定义所在数据库中发生,事件触发器就会被触发。 @@ -210,7 +210,7 @@ CALLED_AS_EVENT_TRIGGER(fcinfo) ((fcinfo)->context != NULL && IsA((fcinfo)->context, EventTriggerData)) - 如果该宏返回 true,那么就可以安全地将 fcinfo->context + 如果该宏返回真,那么就可以安全地将 fcinfo->context 转换为 EventTriggerData * 类型,并使用它所指向的 EventTriggerData 结构体。该函数 不得修改 EventTriggerData @@ -281,7 +281,7 @@ typedef struct EventTriggerData 事件触发器函数必须返回一个 NULL 指针 (不是 SQL 空值,也就是不要将 - isNull 设为 true)。 + isNull 设为真)。 diff --git a/zh/18/extend.sgml b/zh/18/extend.sgml index 32ac897b..a11f45d0 100644 --- a/zh/18/extend.sgml +++ b/zh/18/extend.sgml @@ -59,7 +59,7 @@ 类型、函数、访问方法等的信息。这些表可以由用户修改,而 PostgreSQL 又是基于这些表来运行的,这意味着 PostgreSQL 可以由用户扩展。相比之下,传统数据库 - 系统通常只能通过修改源代码中的硬编码过程,或加载由 + 系统只能通过修改源代码中的硬编码过程,或加载由 DBMS 供应商专门编写的模块来扩展。 @@ -92,7 +92,7 @@ 数据类型 - 组合 + 复合 @@ -517,7 +517,7 @@ RETURNS anycompatible AS ... 哪些 SQL 对象种类可以成为扩展成员,见 ALTER EXTENSION 的说明。特别是,数据库集簇范围内的对象,如数据库、角色和表空间,不能 - 成为扩展成员,因为扩展只在单个数据库内可见。(尽管扩展脚本并不禁止创 + 成为扩展成员,因为扩展只在单个数据库内可见。(尽管并不禁止扩展脚本创 建这类对象,但如果这样做,它们不会作为扩展的一部分受到跟踪。)还要注意, 虽然表可以成为扩展成员,但其附属对象(如索引)并不直接被视为扩展成员。 另一个重要点是,模式可以属于扩展,但反过来不成立:扩展本身只有一个非 @@ -672,21 +672,7 @@ RETURNS anycompatible AS ... trusted (boolean) - - 如果该参数被设为 true(默认并非如此),则允许某些 - 非超级用户安装 superuser 设为 - true 的扩展。具体来说,任何在当前数据库上具有 - CREATE 权限的用户都被允许安装。当执行 - CREATE EXTENSION 的用户不是超级用户,但因该参数 - 而被允许安装时,安装或更新脚本会以引导超级用户的身份运行,而不是以 - 调用用户的身份运行。如果 superuser 为 - false,这个参数就没有意义。一般来说,对于可能让 - 用户访问原本只有超级用户才能使用的能力(如文件系统访问)的扩展,不 - 应把它设为 true。此外,把一个扩展标记为 - trusted,还需要付出大量额外努力来确保安装和更 - 新脚本写得足够安全;见 - 。 - + 如果将此参数设为 true(不是默认值),则允许某些非超级用户安装 superuser 设为 true 的扩展。具体而言,当前数据库上具有 CREATE 权限的任何人都可以安装。当执行 CREATE EXTENSION 的用户不是超级用户,但凭借此参数获准安装时,安装或更新脚本会以引导超级用户的身份运行,而不是调用用户的身份。如果 superuserfalse,则此参数不起作用。通常,对于可能允许访问原本仅限超级用户使用的能力(例如文件系统访问)的扩展,不应将此参数设为真。此外,将扩展标记为受信任的,需要投入大量额外工作来安全地编写其安装和更新脚本;参见 @@ -747,8 +733,8 @@ RETURNS anycompatible AS ... 如果扩展脚本中包含字符串 @extowner@,该字符串会被 替换为调用 CREATE EXTENSION 或 - ALTER EXTENSION 的用户名称(会作适当引用)。通常, - 这个特性被标记为 trusted 的扩展用来把选定对象的 + ALTER EXTENSION 的用户名称(会适当加上引号)。通常, + 这个特性被标记为受信任的扩展用来把选定对象的 所有权赋给调用用户, 而不是赋给引导超级用户。(不过这样做时应当谨慎。例如,把一个 C 语言 函数的所有权赋给非超级用户,会为该用户创建一条权限提升路径。) @@ -973,7 +959,7 @@ SELECT pg_catalog.pg_extension_config_dump('my_config', 'WHERE NOT standard_entr 在有合适更新脚本可用的前提下, - ALTER EXTENSION UPDATE 命令可以把已安装的扩展更新 + ALTER EXTENSION UPDATE 命令会把已安装的扩展更新 到指定的新版本。更新脚本运行在 CREATE EXTENSION 为安装脚本提供的同一环境中:尤其 是,search_path 的设置方式完全相同,而且脚本创建的 @@ -999,7 +985,7 @@ SELECT pg_catalog.pg_extension_config_dump('my_config', 'WHERE NOT standard_entr 例如,它并不知道 1.1 是否跟在 1.0 之后。它只是匹配可用的版本名,并选择需要应用 更新脚本最少的那条路径。(实际上,版本名可以是任何不包含 - --,且不以前导或尾随 - 结尾的字 + --,且不以 - 开头或结尾的字 符串。) @@ -1072,19 +1058,9 @@ SELECT * FROM pg_extension_update_paths('extension_name - - 将 superuser 属性设为 true 的 - 扩展,还必须考虑其安装脚本和更新脚本中操作所带来的安全风险。恶意用户并不难创建出特洛伊木 - 马对象,从而在后续粗心编写的扩展脚本执行时造成破坏,并借此获得超级用 - 户权限。 - + superuser 属性设为真的扩展,还必须考虑其安装和更新脚本所执行操作的安全风险。恶意用户可以创建木马对象,破坏以后对编写不慎的扩展脚本的执行,从而获得超级用户权限;这并非特别困难。 - - 如果一个扩展被标记为 trusted,那么安装用户可以自己 - 选择安装模式,而该用户可能会有意使用不安全的模式,希望借此获得超级用 - 户权限。因此,从安全角度看,trusted 扩展暴露程度 - 极高,必须仔细审查其所有脚本命令,确保不存在任何可被利用之处。 - + 如果扩展被标记为 trusted,那么安装用户可以选择其安装模式,而该用户可能故意使用不安全的模式,试图获得超级用户权限。因此,从安全角度看,受信任的扩展面临的风险极高,必须仔细检查其全部脚本命令,确保无法被攻破。 关于如何安全地编写函数,建议见下面的 @@ -1132,7 +1108,7 @@ SELECT * FROM pg_extension_update_paths('extension_namemyschema.myfunc(bigint),那么像 myschema.myfunc(42) 这样的调用,就可能被恶意函数 myschema.myfunc(integer) 截获。要注意函数和操作符 - 参数的数据类型必须与声明的实参类型精确匹配,必要时请使用显式类型转 + 所传参数的数据类型必须与声明的参数类型精确匹配,必要时请使用显式类型转 换。 @@ -1181,7 +1157,7 @@ SELECT * FROM pg_extension_update_paths('extension_name扩展示例 - 下面给出一个纯 SQL 扩展的完整示例:一个双元素组合 + 下面给出一个纯 SQL 扩展的完整示例:一个双元素复合 类型,它可以在两个槽位中存储任意类型的值,这两个槽位名为 kv。非文本值会自动强制转换为文本后 再存储。 @@ -1262,7 +1238,7 @@ include $(PGXS) 如果你打算分发自己的 PostgreSQL 扩展模块, - 那么为它们搭建一个可移植的构建系统会相当困难。因此, + 那么为它们搭建一个可移植的构建系统可能相当困难。因此, PostgreSQL 安装提供了一套称为 PGXS 的扩展构建基础设施,使简单的扩展模块可以针对 已安装好的服务器直接构建。PGXS 主要面向包含 C 代码 @@ -1313,7 +1289,7 @@ include $(PGXS) MODULE_big - 要从多个源文件构建的共享库(在 OBJS 中列出对象 + 要从多个源文件构建的共享库(在 OBJS 中列出目标 文件) @@ -1323,7 +1299,7 @@ include $(PGXS) PROGRAM - 要构建的可执行程序(在 OBJS 中列出对象文件) + 要构建的可执行程序(在 OBJS 中列出目标文件) @@ -1678,7 +1654,7 @@ make VPATH=/path/to/extension/source/tree install 正在运行的 PostgreSQL 服务器。列在 REGRESS 中的脚本文件必须位于扩展目录下名为 sql/ 的子目录中。这些文件必须具有 - .sql 扩展名,而该扩展名不应出现在 makefile 的 + .sql 扩展名,而该扩展名不能出现在 makefile 的 REGRESS 列表中。对于每个测试,还应在名为 expected/ 的子目录中有一个包含期望输出的文件,其主 干名相同,扩展名为 .out。 @@ -1697,7 +1673,7 @@ make VPATH=/path/to/extension/source/tree install 必须有一个正在运行的 PostgreSQL 服务器。列 在 ISOLATION 中的脚本文件必须位于扩展目录下名为 specs/ 的子目录中。这些文件必须具有 - .spec 扩展名,而该扩展名不应出现在 makefile 的 + .spec 扩展名,而该扩展名不能出现在 makefile 的 ISOLATION 列表中。对于每个测试,还应在名为 expected/ 的子目录中有一个包含期望输出的文件,其主 干名相同,扩展名为 .out。 diff --git a/zh/18/fdwhandler.sgml b/zh/18/fdwhandler.sgml index b8119b32..4cbe9f54 100644 --- a/zh/18/fdwhandler.sgml +++ b/zh/18/fdwhandler.sgml @@ -753,7 +753,7 @@ RecheckForeignScan(ForeignScanState *node, - <command>EXPLAIN</command>的FDW例程 + <command>EXPLAIN</command> 的 FDW 例程 @@ -803,7 +803,7 @@ ExplainDirectModify(ForeignScanState *node, - <command>ANALYZE</command>的FDW例程 + <command>ANALYZE</command> 的 FDW 例程 diff --git a/zh/18/features.sgml b/zh/18/features.sgml index f212af45..866569f6 100644 --- a/zh/18/features.sgml +++ b/zh/18/features.sgml @@ -408,7 +408,7 @@ SELECT XMLQUERY('$a is $b' PASSING BY VALUE x AS a, < DOCUMENTCONTENT形式的值。 一个 XQuery/XPath 表达式的上下文项必须是单个 XML 节点或原子值, 但 XPath 1.0 又进一步限制它只能是 XML 节点,并且没有允许CONTENT的节点类型。 - 归根结底,格式良好的DOCUMENT是 + 归根结底,良构的DOCUMENTPostgreSQL能够作为 XPath 上下文项提供的唯一 XML 值形式。 diff --git a/zh/18/func.sgml b/zh/18/func.sgml index e5154fe8..d1b5038d 100644 --- a/zh/18/func.sgml +++ b/zh/18/func.sgml @@ -39,20 +39,17 @@ repeat('Pg', 4) PgPgPgPg 逻辑操作符 - operator - logical + 操作符 + 逻辑 - Boolean - operators - operators, logical + 布尔 + 操作符 + 操作符,逻辑 - - 常用的逻辑操作符有: - - + 可以使用以下常见逻辑操作符: AND(操作符) @@ -65,15 +62,15 @@ repeat('Pg', 4) PgPgPgPg - conjunction + 合取 - disjunction + 析取 - negation + 否定 @@ -82,9 +79,7 @@ repeat('Pg', 4) PgPgPgPg NOT boolean boolean - SQL使用三值的逻辑系统,包括真、假和nullnull表示未知。观察下面的真值表: - - + SQL使用由真、假和null构成的三值逻辑系统,其中null表示未知。请看下面的真值表: @@ -181,8 +176,8 @@ repeat('Pg', 4) PgPgPgPg 比较函数和操作符 - comparison - operators + 比较 + 操作符 @@ -265,14 +260,14 @@ repeat('Pg', 4) PgPgPgPg - <> 表示 not equal 的标准的SQL符号。 - != 是一个别名, 在解析的早期阶段被转换为 <> 。 - 因此, 它不可能实现 !=<> 操作符以做不同的事情。 + <>不等于 的标准 SQL 符号。 + != 是一个别名,在解析的早期阶段就会被转换为 <>。 + 因此,不可能让 !=<> 操作符执行不同的操作。 - 这些比较操作符适用于所有具有自然排序的内置数据类型,包括数字、字符串和日期/时间类型。 + 这些比较操作符适用于所有具有自然排序的内置数据类型,包括数值、字符串和日期/时间类型。 此外,如果其组成数据类型具有可比性,则也可以比较数组、复合类型和范围。 @@ -318,7 +313,7 @@ repeat('Pg', 4) PgPgPgPg boolean - 之间(包括范围端点)。 + 位于两者之间(包括范围端点)。 2 BETWEEN 1 AND 3 @@ -378,7 +373,7 @@ repeat('Pg', 4) PgPgPgPg boolean - 不相等, 将空(null)视为可比值。 + 不相等,将 null 视为可比值。 1 IS DISTINCT FROM NULL @@ -396,7 +391,7 @@ repeat('Pg', 4) PgPgPgPg boolean - 相等, 将空(null)视为可比值。 + 相等,将 null 视为可比值。 1 IS NOT DISTINCT FROM NULL @@ -414,7 +409,7 @@ repeat('Pg', 4) PgPgPgPg boolean - 测试值是否为空。 + 测试值是否为 null。 1.5 IS NULL @@ -428,7 +423,7 @@ repeat('Pg', 4) PgPgPgPg boolean - 测试值是否不为空。 + 测试值是否不为 null。 'null' IS NOT NULL @@ -442,7 +437,7 @@ repeat('Pg', 4) PgPgPgPg boolean - 测试值是否为空(非标准语法)。 + 测试值是否为 null(非标准语法)。 @@ -452,7 +447,7 @@ repeat('Pg', 4) PgPgPgPgboolean - 测试值是否不为空(非标准语法)。 + 测试值是否不为 null(非标准语法)。 @@ -573,30 +568,22 @@ repeat('Pg', 4) PgPgPgPg BETWEEN SYMMETRIC - - BETWEEN谓词可以简化范围测试: - + BETWEEN谓词可以简化范围测试: a BETWEEN x AND y - - 等效于 - +等价于 a >= x AND a <= y - - 注意BETWEEN认为终点值是包含在范围内的。 - BETWEEN SYMMETRIC 就像BETWEEN,除了没有要求AND的左边的参数小于或等于右边的参数。 - 如果不是的话,这两个参数将自动交换,因此总是隐含一个非空范围。 - +注意,BETWEEN将两个端点值都视为包含在范围内。BETWEEN SYMMETRIC类似于BETWEEN,但不要求AND左侧的参数小于或等于右侧的参数。如果不是这样,这两个参数会自动交换,以确保表示的范围始终非空。 - BETWEEN的各种变量都是以普通比较操作符的方式实现的,因此适用于任何可以比较的数据类型。 + BETWEEN的各种变体都是以普通比较操作符的方式实现的,因此适用于任何可以比较的数据类型。 - 在BETWEEN语法中使用AND会与使用AND作为逻辑操作符产生歧义。 - 为了解决这个问题,只允许有限的一组表达类型作为BETWEEN子句的第二个参数。 - 如果您需要在BETWEEN中写一个更复杂的子表达式,在子表达式两边写上圆括号。 + 在BETWEEN语法中使用AND,会与将AND用作逻辑操作符产生歧义。 + 为了解决这个问题,只允许有限的一组表达式类型作为BETWEEN子句的第二个参数。 + 如果你需要在BETWEEN中写一个更复杂的子表达式,请在该子表达式两边加上圆括号。 @@ -607,12 +594,12 @@ repeat('Pg', 4) PgPgPgPg IS NOT DISTINCT FROM - 当有一个输入为空时,普通的比较操作符会得到空(表示未知),而不是真或假。例如,7 = NULL得到空,7 <> NULL也一样。如果这种行为不合适,可以使用IS NOT DISTINCT FROM谓词: + 当任一输入为 null 时,普通的比较操作符会得到 null(表示未知),而不是真或假。例如,7 = NULL得到 null,7 <> NULL也一样。如果这种行为不合适,可以使用IS NOT DISTINCT FROM谓词: a IS DISTINCT FROM b a IS NOT DISTINCT FROM b - 对于非空输入,IS DISTINCT FROM<>操作符一样。不过,如果两个输入都为空,它会返回假。而如果只有一个输入为空,它会返回真。类似地,IS NOT DISTINCT FROM对于非空输入的行为与=相同,但是当两个输入都为空时它返回真,并且当只有一个输入为空时返回假。因此,这些谓词实际上把空值当作一种普通数据值,而不是未知。 + 对于非 null 输入,IS DISTINCT FROM<>操作符一样。不过,如果两个输入都为 null,它会返回假。而如果只有一个输入为 null,它会返回真。类似地,IS NOT DISTINCT FROM对于非 null 输入的行为与=相同,但是当两个输入都为 null 时它返回真,并且当只有一个输入为 null 时返回假。因此,这些谓词实际上把 null 当作一种普通数据值,而不是未知 @@ -628,17 +615,17 @@ repeat('Pg', 4) PgPgPgPg NOTNULL - 要检查一个值是否为空,使用下面的谓词: + 要检查一个值是否为 null,使用下面的谓词: expression IS NULL expression IS NOT NULL - 或者等效,但并不标准的谓词: + 或者等效但非标准的谓词: expression ISNULL expression NOTNULL - null valuecomparing + 空值比较 @@ -648,7 +635,7 @@ repeat('Pg', 4) PgPgPgPg - 有些应用可能要求表达式expression = NULLexpression得出空值时返回真。我们强烈建议这样的应用修改成遵循 SQL 标准。但是,如果这样修改不可能完成,那么我们可以使用配置变量。如果打开它,PostgreSQL将把x = NULL子句转换成x IS NULL。 + 有些应用可能期望表达式expression = NULLexpression求值为 null 时返回真。我们强烈建议此类应用修改为遵循 SQL 标准。但是,如果无法这样修改,那么可以使用配置变量。如果将其打开,PostgreSQL会把x = NULL子句转换成x IS NULL @@ -658,11 +645,11 @@ repeat('Pg', 4) PgPgPgPg SELECT ROW(1,2.5,'this is a test') = ROW(1, 3, 'not the same'); -SELECT ROW(table.*) IS NULL FROM table; -- detect all-null rows +SELECT ROW(table.*) IS NULL FROM table; -- 检测所有字段均为 null 的行 -SELECT ROW(table.*) IS NOT NULL FROM table; -- detect all-non-null rows +SELECT ROW(table.*) IS NOT NULL FROM table; -- 检测所有字段均非 null 的行 -SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in rows +SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- 检测至少有一个 null 字段的行 在某些情况下,写成row IS DISTINCT FROM NULL或者row IS NOT DISTINCT FROM NULL可能更合适,因为它们只会检查整个行值是否为 null,而不会再对行字段做额外测试。 @@ -696,7 +683,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in boolean_expression IS UNKNOWN boolean_expression IS NOT UNKNOWN - 这些谓词将总是返回真或假,从来不返回空值,即使操作数是空也如此。空值输入被当做逻辑值未知。 请注意实际上IS UNKNOWNIS NOT UNKNOWN分别与IS NULLIS NOT NULL相同, 只是输入表达式必须是布尔类型。 + 这些谓词总是返回真或假,从不返回空值,即使操作数为 null 也是如此。null 输入被当作逻辑值未知。请注意,IS UNKNOWNIS NOT UNKNOWN实际上分别等同于IS NULLIS NOT NULL,只是输入表达式必须是布尔类型。 @@ -733,7 +720,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in integer - 返回非空参数的数量。 + 返回非 null 参数的数量。 num_nonnulls(1, NULL, 2) @@ -750,7 +737,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in integer - 返回空参数的数量。 + 返回 null 参数的数量。 num_nulls(1, NULL, 2) @@ -768,12 +755,12 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in 数学函数和操作符 - PostgreSQL为很多类型提供了数学操作符。对于那些没有标准数学表达的类型(如日期/时间类型),我们将在后续小节中描述实际的行为。 + PostgreSQL为很多类型提供了数学操作符。对于那些没有标准数学惯例的类型(如日期/时间类型),我们将在后续小节中描述实际的行为。 - 显示了可用于标准数字类型的数学操作符。 - 除非另有说明, 显示为可接受 numeric_type 的操作符对所有的 smallintintegerbigintnumericrealdouble precision类型都可用。 + 显示了可用于标准数值类型的数学操作符。 + 除非另有说明, 显示为可接受 numeric_type 的操作符对所有的 smallintintegerbigintnumericrealdouble precision类型都可用。 显示为可接受 integral_type 的操作符对 smallintintegerbigint类型是可用的。 除了特别说明之处,操作符的每种形式都返回与其参数相同的数据类型。 涉及多个参数数据类型的调用, 例如 integer + numeric,可通过使用这些列表中稍后出现的类型来解析。 @@ -821,7 +808,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in numeric_type - 一元加(无操作) + 一元正号(不执行操作) + 3.5 @@ -849,7 +836,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in numeric_type - 否定 + 取负 - (-4) @@ -877,7 +864,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in numeric_type - 除(对于整型,除法将结果截断为零) + 除法(对于整数类型,除法将结果向零截断) 5.0 / 2 @@ -917,14 +904,14 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in double precision - 指数 + 求幂 2 ^ 3 8 - 不像典型的数学实践,多次使用 ^ 将会默认从左到右关联: + 与通常的数学惯例不同,多次使用^时默认从左到右结合: 2 ^ 3 ^ 3 @@ -984,7 +971,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in integral_type - 按位与(AND) + 按位与 91 & 15 @@ -998,7 +985,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in integral_type - 按位或(OR) + 按位或 32 | 3 @@ -1012,7 +999,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in integral_type - 按位异或(exclusive OR) + 按位异或 17 # 5 @@ -1026,7 +1013,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in integral_type - 按位求反(NOT) + 按位非 ~1 @@ -1069,9 +1056,9 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in 显示了可用的数学函数。 许多这样的函数以多种具有不同的参数类型的形式提供。 - 除非注明,任何给定形式的函数都返回与其参数相同的数据类型;跨类型情况的解决方法与上述对操作符的解释相同。 - 使用double precision数据的函数大多是在主机系统的C库上实现的; - 因此,边界情况下的准确性和行为会因主机系统的区别而不同。 + 除非注明,任何给定形式的函数都返回与其参数相同的数据类型;跨类型情况的解决方法与上述对操作符的解释相同。 + 使用double precision数据的函数大多是在主机系统的C库上实现的; + 因此,精度和边界情况下的行为可能因主机系统而异。
@@ -1202,7 +1189,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in numeric - y/x 的整数商(截断为零位) + y/x 的整数商(向零截断) div(9, 4) @@ -1210,27 +1197,6 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in - - - - exp - - exp ( numeric ) - numeric - - - exp ( double precision ) - double precision - - - 指数 (e 的给定次方) - - - exp(1.0) - 2.7182818284590452 - - - @@ -1265,6 +1231,27 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in + + + + exp + + exp ( numeric ) + numeric + + + exp ( double precision ) + double precision + + + 指数函数(e的给定次幂) + + + exp(1.0) + 2.7182818284590452 + + + @@ -1466,7 +1453,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in integer - 精确表示所提供值所需的最小刻度(小数位数) + 精确表示给定值所需的最少小数位数 min_scale(8.4100) @@ -1563,7 +1550,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in double precision - 四舍五入到最近的整数。 + 舍入到最接近的整数。 对于numeric,遇到恰好位于中点的情况时按远离零的方向舍入。 对于double precision,中点取舍规则取决于平台,但舍入到最接近的偶数是最常见的规则。 @@ -1600,7 +1587,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in integer - 参数的刻度(小数点后的位数) + 参数的小数位数(小数部分的十进制位数) scale(8.4100) @@ -1659,7 +1646,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in numeric - 通过删除尾数部分的零来降低值的刻度(小数位数) + 通过移除尾随零来减少值的小数位数 trim_scale(8.4100) @@ -1680,7 +1667,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in double precision - 截断整数 (向零靠近) + 向零截断为整数 trunc(42.8) @@ -1698,7 +1685,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in numeric - 截断 vs 位小数位置的数字 + 将v截断到s位小数 trunc(42.4382, 2) @@ -1791,6 +1778,55 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in + + + + random + + random ( min integer, max integer ) + integer + + + random ( min bigint, max bigint ) + bigint + + + random ( min numeric, max numeric ) + numeric + + + 返回范围min <= x <= max内的随机值。对于numeric类型,结果的小数位数与minmax中小数位数较多者相同。 + + + random(1, 10) + 7 + + + random(-0.499, 0.499) + 0.347 + + + + + + + random_normal + + + random_normal ( + mean double precision + , stddev double precision ) + double precision + + + 从具有给定参数的正态分布中返回一个随机值;mean默认为 0.0,stddev默认为 1.0。 + + + random_normal(0.0, 1.0) + 0.051285419 + + + @@ -1800,7 +1836,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in void - 为后续的random()调用设置种子;参数必须在-1.0和1.0之间,包括边界值 + 为后续的random()random_normal()调用设置种子;参数必须在-1.0和1.0之间,包括边界值 setseed(0.12345) @@ -1811,10 +1847,10 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in
- random()函数使用确定性伪随机数生成器。 + 在中列出的random()random_normal()函数使用确定性伪随机数生成器。 它速度快,但不适用于加密应用;请参阅模块以获取更安全的替代方案。 - 如果调用setseed(),则当前会话中后续random()调用的结果序列可以通过使用相同参数重新发出setseed()来重复。 - 在同一会话中没有任何先前的setseed()调用时,第一个random()调用从平台相关的随机位源获取种子。 + 如果调用setseed(),则当前会话中后续对这些函数的调用结果序列可以通过使用相同参数重新发出setseed()来重复。 + 在同一会话中没有任何先前的setseed()调用时,首次调用这些函数中的任何一个都会从平台相关的随机位源获取种子。 @@ -2124,7 +2160,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in - 另一种使用以角度度量的角的方法是使用早前展示的单位转换函数radians()degrees()。不过,使用基于角度的三角函数更好,因为这类方法能避免sind(30)等特殊情况下的舍入偏差。 + 另一种使用以角度度量的角的方法是使用早前展示的单位转换函数radians()degrees()。不过,使用基于角度的三角函数更好,因为这类方法能避免sind(30)等特殊情况下的舍入误差。 @@ -2197,7 +2233,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in double precision - 双曲切线 + 双曲正切 tanh(1) @@ -2248,7 +2284,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in double precision - 反双曲切线 + 反双曲正切 atanh(0.5) @@ -2270,7 +2306,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in 这里的字符串包括charactercharacter varyingtext类型的值。 除非另有说明,这些函数和操作符都声明为接受并返回text类型。 它们也可互换地接受character varying参数。 - 在应用函数或操作符之前,character类型的值会先转换为text,因此会去除其尾随空格。 + 在应用函数或操作符之前,character类型的值会先转换为text,因此会去除 character 值的尾随空格。 @@ -2281,7 +2317,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in 字符串串接操作符(||)将接受非字符串输入,只要至少一个输入是一种字符串类型,如所示。 - 对于其他情况,向text插入一个显式强制,可用于接受非字符串输入。 + 对于其他情况,可以添加到text的显式强制转换,以接受非字符串输入。 @@ -2309,14 +2345,14 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in - character string - concatenation + 字符串 + 串接 text || text text - 连接两个字符串。 + 串接两个字符串。 'Post' || 'greSQL' @@ -2334,8 +2370,8 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 将非字符串输入转换为文本,然后将两个字符串串联在一起。 - (非字符串输入不能为数组类型,因为这将在||操作符的数组中造成歧义。如果你想连接一个数组的文本相等的,请显式地将其转换为text 。) + 将非字符串输入转换为文本,然后将两个字符串串接起来。 + (非字符串输入不能是数组类型,因为那样会与数组的||操作符产生歧义。如果要串接数组的文本表示,请显式地将其转换为text。) 'Value: ' || 42 @@ -2346,17 +2382,35 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in - normalized + btrim + + btrim ( string text + , characters text ) + text + + + 从string的开头和结尾移除仅由characters中字符(默认为空格)组成的最长字符串。 + + + btrim('xyxtrimyyx', 'xyz') + trim + + + + + + + 规范化 - Unicode normalization + Unicode 规范化 text IS NOT form NORMALIZED boolean - 检查字符串是否在指定的 Unicode 规范化表单中。 - 可选的form关键词指定表单:NFC (默认的), NFD, NFKC, 或 NFKD。 + 检查字符串是否处于指定的 Unicode 规范化形式中。 + 可选的form关键字指定形式:NFC(默认)、NFDNFKCNFKD。 只有在服务器编码为UTF8时,才能使用此表达式。 请注意,使用这个表达式检查规范化通常比规范化可能已经规范化的字符串要快。 @@ -2389,13 +2443,13 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in char_length - character string - length + 字符串 + 长度 - length + 长度 字符串 - character string, length + 字符串,长度 char_length ( text ) integer @@ -2418,14 +2472,14 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in - + lower lower ( text ) text - 根据数据库的语言环境规则,将字符串转换为全部小写。 + 根据数据库的区域设置规则,将字符串转换为全部小写。 lower('TOM') @@ -2436,19 +2490,54 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in + lpad + + lpad ( string text, + length integer + , fill text ) + text + + + 在string前面添加字符fill(默认为空格),将其填充到长度length。如果string已经长于length,则从右侧截断。 + + + lpad('hi', 5, 'xy') + xyxhi + + + + + + + ltrim + + ltrim ( string text + , characters text ) + text + + + 从string的开头移除仅由characters中字符(默认为空格)组成的最长字符串。 + + + ltrim('zzzytest', 'xyz') + test + + + + + + normalize - Unicode normalization + Unicode 规范化 normalize ( text , form ) text - 将字符串转换为指定的Unicode规范化形式。 - 可选的form关键字指定了如下形式:NFC (the default),NFDNFKC,或NFKD。 - 该函数只能在服务器编码为UTF8时使用。 + 将字符串转换为指定的 Unicode 规范化形式。可选的 form 关键字指定如下形式:NFC(默认值)、NFDNFKCNFKD。该函数只能在服务器编码为 UTF8 时使用。 normalize(U&'\0061\0308bc', NFC) @@ -2499,8 +2588,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 替换stringstart字符开始的子串,并用newsubstring扩展到count字符。 - 如果省略了count,则默认为newsubstring的长度。 + 用newsubstring替换string中从第start个字符开始、长度为count个字符的子字符串。如果省略count,则默认为newsubstring的长度。 overlay('Txxxxas' placing 'hom' from 2 for 4) @@ -2517,7 +2605,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in integer - 返回string中指定的substring的第一个起始索引,如果不存在则返回零,。 + 返回substringstring中首次出现的位置;如果不存在则返回零。 position('om' in 'Thomas') @@ -2525,6 +2613,43 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in + + + + rpad + + rpad ( string text, + length integer + , fill text ) + text + + + 在string后面追加字符fill(默认为空格),将其填充到长度length。如果string已经长于length,则截断它。 + + + rpad('hi', 5, 'xy') + hixyx + + + + + + + rtrim + + rtrim ( string text + , characters text ) + text + + + 从string的结尾移除仅由characters中字符(默认为空格)组成的最长字符串。 + + + rtrim('testxxzx', 'xyz') + test + + + @@ -2534,9 +2659,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 如果已指定,提取stringstart字符开始的子串, - 并且在count字符后停止。如果已指定的话。 - 提供至少一个startcount中的至少一个。 + 提取string的子字符串:若指定了起始位置,则从第start个字符开始;若指定了长度,则在提取count个字符后停止。startcount至少需要指定一个。 substring('Thomas' from 2 for 3) @@ -2558,7 +2681,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 提取匹配POSIX正则表达式的第一个子字符串; 参见 。 + 提取匹配 POSIX 正则表达式的第一个子字符串;参见 substring('Thomas' from '...$') @@ -2576,8 +2699,8 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 提取匹配 SQL 正则表达式的第一个字串;参见 。 - 第一种形式自从SQL:2003被指定,第二种形式仅在SQL:1999中,并应认为是废弃的。 + 提取匹配 SQL 正则表达式的第一个子字符串;参见 。 + 第一种形式自 SQL:2003 起由标准规定;第二种形式只出现在 SQL:1999 中,应视为已过时。 substring('Thomas' similar '%#"o_a#"_' escape '#') @@ -2620,6 +2743,19 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in + + + + unicode_assigned + + unicode_assigned ( text ) + boolean + + + 如果字符串中的所有字符都是已分配的 Unicode 码点,则返回true;否则返回false。此函数只能在服务器编码为UTF8时使用。 + + + @@ -2629,7 +2765,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 根据数据库的定位规则,将字符串转换为所有大写。 + 根据数据库的区域设置规则,将字符串转换为全部大写。 upper('tom') @@ -2696,7 +2832,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in integer - 返回参数的第一个字符的数字代码。在UTF8编码中,返回该字符的Unicode代码点。 + 返回参数的第一个字符的数字代码。在UTF8编码中,返回该字符的Unicode 码点。 在其他多字节编码中,该参数必须是一个ASCII字符。 @@ -2705,23 +2841,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in - - - - btrim - - btrim ( string text - , characters text ) - text - - - 从string的开头或结尾删除最长的只包含characters(默认是一个空格)的字符串 - - - btrim('xyxtrimyyx', 'xyz') - trim - - + @@ -2732,7 +2852,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 返回给定代码的字符。在UTF8编码中该参数被视作一个Unicode代码点。 + 返回给定代码的字符。在UTF8编码中该参数被视作一个Unicode 码点。 在其他多字节编码中该参数必须指定一个ASCII字符。 chr(0) 字符不被允许,因为文本数据类型不能存储这种字符。 @@ -2748,11 +2868,11 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in concat concat ( val1 "any" - [, val2 "any" [, ...] ] ) + , val2 "any" , ... ) text - 连接所有参数的文本表示。空参数被忽略。 + 串接所有参数的文本表示。NULL 参数被忽略。 concat('abcde', 2, NULL, 22) @@ -2767,11 +2887,11 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in concat_ws ( sep text, val1 "any" - [, val2 "any" [, ...] ] ) + , val2 "any" , ... ) text - 用分隔符连接除第一个参数外的所有参数。第一个参数用作分隔符字符串,不应为NULL。其他NULL参数将被忽略。 + 用分隔符串接除第一个参数外的所有参数。第一个参数用作分隔符字符串,不应为NULL。其他NULL参数将被忽略。 concat_ws(',', 'abcde', 2, NULL, 22) @@ -2785,7 +2905,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in format format ( formatstr text - [, formatarg "any" [, ...] ] ) + , formatarg "any" , ... ) text @@ -2818,76 +2938,67 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in - left + casefold - left ( string text, - n integer ) + casefold ( text ) text - 以字符串返回第一个 n 字符,或在 n 为负时, 返回最后 |n| 个字符之外的全部字符。 + 根据排序规则对输入字符串执行大小写折叠。大小写折叠与大小写转换类似,但其目的是方便字符串的不区分大小写匹配,而大小写转换的目的是将字符串转换为特定的大小写形式。此函数只能在服务器编码为UTF8时使用。 - left('abcde', 2) - ab - - - - - - - length - - length ( text ) - integer + 通常,大小写折叠只是将字符转换为小写,但不同排序规则可能存在例外。例如,某些字符具有两种以上的小写变体,或者会折叠为大写。 - 返回字符串中的字符数。 + 大小写折叠可能改变字符串的长度。例如,在PG_UNICODE_FAST排序规则中,ß(U+00DF)会折叠为ss - length('jose') - 4 + casefold可用于 Unicode 默认无大小写匹配。它并不总能保留输入字符串的规范化形式(参见)。 + + + libc提供者不支持大小写折叠,因此casefold相同。 - lpad + left - lpad ( string text, - length integer - , fill text ) + left ( string text, + n integer ) text - 将string扩展为长度length,通过前置字符fill(默认空格)。 - 如果string已经超过length那么它将被截断(在右侧)。 + 返回字符串最左侧的 n 个字符;如果 n 为负,则返回除最后 |n| 个字符之外的全部字符。 - lpad('hi', 5, 'xy') - xyxhi + left('abcde', 2) + ab - ltrim + length - ltrim ( string text - , characters text ) - text + length ( text ) + integer - 从string开始删除包含characters(默认空格)中仅包含字符的最长字符串。 + 返回字符串中的字符数。 - ltrim('zzzytest', 'xyz') - test + length('jose') + 4 + + + + @@ -2911,14 +3022,14 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in parse_ident parse_ident ( qualified_identifier text - [, strict_mode boolean DEFAULT true ] ) + , strict_mode boolean DEFAULT true ) text[] - 将qualified_identifier拆分为一个标识符数组,删除单个标识符的任何引用。 + 将qualified_identifier拆分为一个标识符数组,去除各个标识符的引号。 默认情况下,最后一个标识符之后的额外字符被视为错误;但是,如果第二个参数为false,则忽略这些额外的字符。 (这种行为对于解析类似函数的对象的名称有作用。) - 请注意,此函数不会截断超长标识符。如果你想截断,你可以把结果给到name[]。 + 请注意,此函数不会截断超长标识符。如果你想截断,你可以将结果转换为name[] parse_ident('"SomeSchema".someTable') @@ -2952,9 +3063,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 返回适合引用的给定字符串,作为SQL语句字符串中的标识符。 - 只有在必要的情况下才添加引号(例如,如果字符串包含非标识符字符或将被大小写折叠)。 - 嵌入的引号被适当地加双引号。参见。 + 为给定字符串添加适当的引号并返回,使其可用作SQL语句字符串中的标识符。仅在必要时(即字符串包含不能用于标识符的字符,或会发生大小写折叠时)添加引号。内嵌的引号会被适当地双写。另见 quote_ident('Foo bar') @@ -2971,9 +3080,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 返回在SQL语句字符串中适当引用的给定字符串,用作字符串文字使用。 - 嵌入式单引号和反斜线适当的翻倍(转双引号或双斜线)。 - 请注意,quote_literal在参数为 null 时返回 null;如果这个参数可能为空,quote_nullable通常更合适。另请参阅。 + 为给定字符串添加适当的引号并返回,使其可用作SQL语句字符串中的字符串字面量。内嵌的单引号和反斜杠会被适当地双写。注意,quote_literal在输入为 null 时返回 null;如果参数可能为 null,quote_nullable通常更合适。另见 quote_literal(E'O\'Reilly') @@ -2987,8 +3094,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 将给定的值转换为文本,然后将其作为字面量引用。 - 内嵌的单引号和反斜杠被适当地翻倍。 + 将给定值转换为文本,然后作为字面量加引号。内嵌的单引号和反斜杠会被适当地双写。 quote_literal(42.5) @@ -3005,8 +3111,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 返回在SQL语句字符串中适当引用的给定字符串文字;或者,如果参数为null,则返回NULL。 - 内嵌的单引号和反斜杠被适当地翻倍。参见。 + 为给定字符串添加适当的引号并返回,使其可用作SQL语句字符串中的字符串字面量;如果参数为 null,则返回NULL。内嵌的单引号和反斜杠会被适当地双写。另见 quote_nullable(NULL) @@ -3020,8 +3125,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 将给定值转换为文本,然后将其作为字面量引用;或者,如果参数为null,则返回NULL。 - 内嵌的单引号和反斜杠被适当地翻倍。 + 将给定值转换为文本,然后作为字面量加引号;如果参数为 null,则返回NULL。内嵌的单引号和反斜杠会被适当地双写。 quote_nullable(42.5) @@ -3035,8 +3139,8 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in regexp_count regexp_count ( string text, pattern text - [, start integer - [, flags text ] ] ) + , start integer + , flags text ) integer @@ -3054,15 +3158,15 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in regexp_instr regexp_instr ( string text, pattern text - [, start integer - [, N integer - [, endoption integer - [, flags text - [, subexpr integer ] ] ] ] ] ) + , start integer + , N integer + , endoption integer + , flags text + , subexpr integer ) integer - 返回string中第N个匹配项的POSIX正则表达式pattern出现的位置,如果没有这样的匹配项,则返回零;参见。 + 返回 POSIX 正则表达式patternstring中第N次匹配的位置;如果没有这样的匹配,则返回零。参见 regexp_instr('ABCDEF', 'c(.)(..)', 1, 1, 0, 'i') @@ -3080,7 +3184,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in regexp_like regexp_like ( string text, pattern text - [, flags text ] ) + , flags text ) boolean @@ -3097,11 +3201,11 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in regexp_match - regexp_match ( string text, pattern text [, flags text ] ) + regexp_match ( string text, pattern text , flags text ) text[] - 返回第一个匹配的POSIX正则表达式patternstring中的子字符串;参见。 + 返回 POSIX 正则表达式patternstring的第一次匹配中的子字符串;参见 regexp_match('foobarbequebaz', '(bar)(beque)') @@ -3114,12 +3218,11 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in regexp_matches - regexp_matches ( string text, pattern text [, flags text ] ) + regexp_matches ( string text, pattern text , flags text ) setof text[] - 返回第一个匹配的 POSIX 正则表达式patternstring中的子字符串,或者如果使用了g标志,则返回所有匹配的子字符串; - 参见。 + 返回 POSIX 正则表达式patternstring的第一次匹配中的子字符串;如果使用g标志,则返回所有匹配中的子字符串。参见 regexp_matches('foobarbequebaz', 'ba.', 'g') @@ -3137,8 +3240,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in regexp_replace regexp_replace ( string text, pattern text, replacement text - [, start integer ] - [, flags text ] ) + , flags text ) text @@ -3153,17 +3255,21 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in regexp_replace ( string text, pattern text, replacement text, - start integer, - N integer - [, flags text ] ) + start integer + , N integer + , flags text ) text - 替换字符串中第N个与 POSIX 正则表达式pattern匹配的子字符串,如果N为零,则替换所有匹配项;参见。 + 替换第N个与 POSIX 正则表达式pattern匹配的子字符串;如果N为零,则替换所有这样的匹配。搜索从string的第start个字符开始。如果省略N,则默认为 1。参见 regexp_replace('Thomas', '.', 'X', 3, 2) ThoXas + + + regexp_replace(string=>'hello world', pattern=>'l', replacement=>'XX', start=>1, "N"=>2) + helXXo world @@ -3172,7 +3278,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in regexp_split_to_array - regexp_split_to_array ( string text, pattern text [, flags text ] ) + regexp_split_to_array ( string text, pattern text , flags text ) text[] @@ -3189,7 +3295,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in regexp_split_to_table - regexp_split_to_table ( string text, pattern text [, flags text ] ) + regexp_split_to_table ( string text, pattern text , flags text ) setof text @@ -3211,15 +3317,14 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in regexp_substr regexp_substr ( string text, pattern text - [, start integer - [, N integer - [, flags text - [, subexpr integer ] ] ] ] ) + , start integer + , N integer + , flags text + , subexpr integer ) text - 返回string中与第N个出现的POSIX正则表达式pattern匹配的子字符串, - 如果没有这样的匹配,则返回NULL;参见。 + 返回string中 POSIX 正则表达式pattern的第N次匹配对应的子字符串;如果没有这样的匹配,则返回NULL。参见 regexp_substr('ABCDEF', 'c(.)(..)', 1, 1, 'i') @@ -3259,7 +3364,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 将string 中当前的子串from替换为子串to。 + 将string中所有出现的子字符串from替换为子字符串to replace('abcdefabcdef', 'cd', 'XX') @@ -3294,7 +3399,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 返回字符串中的最后n个字符,或者在n>为负时,返回除了前面的|n|字符之外的所有字符。 + 返回字符串中的最后n个字符;如果n为负数,则返回除前 |n| 个字符之外的全部字符。 right('abcde', 2) @@ -3302,44 +3407,10 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in - - - - rpad - - rpad ( string text, - length integer - , fill text ) - text - - - 扩展 string 到长度 length,通过追加fill 字符(默认为空格). - 如果string 已经比 length 长,则截断它。 - - - rpad('hi', 5, 'xy') - hixyx - - - - - - - rtrim - - rtrim ( string text - , characters text ) - text - - - 从string末尾删除包含characters(默认为空格)中仅包含字符的最长字符串。 - - - rtrim('testxxzx', 'xyz') - test - - - + + + + @@ -3351,7 +3422,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 在delimiter出现时拆分string,并且返回第n个字段(从一计数),或者当n为负数时,返回|n|'th-from-last 字段。 + 在出现delimiter时拆分string,并返回第n个字段(从一开始计数);如果n为负数,则返回倒数第 |n| 个字段。 split_part('abc~@~def~@~ghi', '~@~', 2) @@ -3435,8 +3506,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in integer - 返回在string中指定的substring的第一个起始索引,如果不存在则为零。 - (与(substringstring中的)位置相同,但是请注意反转的参数顺序) + 返回substringstring中首次出现的位置;如果不存在则返回零。(与position(substring in string)相同,但请注意参数顺序相反。) strpos('high', 'ig') @@ -3453,8 +3523,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 提取stringstart字符开始的子字符串,并扩展count字符,如果指定了的话。 - (与 子字符串(stringstart 开始计数 count)相同。) + 提取string中从第start个字符开始的子字符串;若指定了长度,则提取count个字符。(与substring(string from start for count)相同。) substr('alphabet', 3) @@ -3485,10 +3554,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 将string从另一个编码中转换为ASCII,该编码可按名称或编号标识。 - 如果encoding被省略,则假定数据库编码(这在实践中是唯一有用的案例)。转换主要包括降音。 - 转换仅支持来自 LATIN1LATIN2LATIN9、 和 WIN1250 的编码. - (其他请参见 模块, 更灵活的解决方案。) + 将string从其他编码转换为ASCII,源编码可以用名称或编号指定。如果省略encoding,则使用数据库编码(实际上,这也是唯一有用的情况)。转换主要是去除重音符号。只支持从LATIN1LATIN2LATIN9WIN1250编码转换。(另一种更灵活的解决方案参见模块。) to_ascii('Karél') @@ -3496,6 +3562,31 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in + + + + to_bin + + to_bin ( integer ) + text + + + to_bin ( bigint ) + text + + + 将数字转换为等价的二进制补码表示。 + + + to_bin(2147483647) + 1111111111111111111111111111111 + + + to_bin(-1234) + 11111111111111111111101100101110 + + + @@ -3509,11 +3600,40 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 将数字转换为其相应的十六进制表示形式。 + 将数字转换为等价的十六进制补码表示。 to_hex(2147483647) 7fffffff + + + to_hex(-1234) + fffffb2e + + + + + + + to_oct + + to_oct ( integer ) + text + + + to_oct ( bigint ) + text + + + 将数字转换为等价的八进制补码表示。 + + + to_oct(2147483647) + 17777777777 + + + to_oct(-1234) + 37777775456 @@ -3529,7 +3649,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in string中与from集合中匹配的每个字符替换为to集合中相应的字符。 - 如果from长于tofrom中出现的额外字符被删除。 + 如果from长于to,输入中出现的from中的额外字符会被删除。 translate('12345', '143', 'ax') @@ -3546,18 +3666,18 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in text - 计算参数中的转义Unicode字符。 + 解析参数中转义的 Unicode 字符。 Unicode字符可以被指定为\XXXX (4个十六进制数字),\+XXXXXX(6个十六进制数字),\uXXXX(4个十六进制数字),或\UXXXXXXXX (8个十六进制数字)。 要指定反斜杠,请写入两个反斜杠。 - 所有其他字符都是按字面意义的。 + 所有其他字符均按字面解释。 - 如果服务器编码不是UTF-8,由这些转义序列之一标识的Unicode编码点将被转换为实际的服务器编码;如果不可能,则会报告错误。 + 如果服务器编码不是 UTF-8,由这些转义序列之一标识的 Unicode 码点将被转换为实际的服务器编码;如果无法转换,则会报告错误。 - 这个函数提供了一个(非标准的)替代到Unicode转义的字符串常量(参见)。 + 此函数提供了带 Unicode 转义的字符串常量的另一种(非标准)写法(参见)。 @@ -3575,12 +3695,12 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in - concatconcat_wsformat函数是可变的,因此可以把要串接或格式化的值作为一个标记了VARIADIC关键字的数组进行传递(见)。 - 数组的元素被当作函数的独立普通参数一样处理。如果可变数组参数为 NULL,concatconcat_ws返回 NULL,但format把 NULL 当作一个零元素数组。 + concatconcat_wsformat是可变参数函数,因此可以把要串接或格式化的值作为一个标记了VARIADIC关键字的数组进行传递(见)。 + 数组的元素被当作函数的独立普通参数一样处理。如果可变参数数组为 NULL,concatconcat_ws返回 NULL,但format把 NULL 当作一个零元素数组。 - 还可以参阅中的string_agg,以及中的字符串和bytea类型之间转换的功能。 + 还可以参阅中的聚合函数string_agg,以及中的字符串和bytea类型之间转换的函数。 @@ -3596,24 +3716,24 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in -format(formatstr text [, formatarg "any" [, ...] ]) +format(formatstr text , formatarg "any" , ... ) - formatstr是一个格式字符串,它指定了结果应该如何被格式化。格式字符串中的文本被直接复制到结果中,除了使用格式说明符的地方。格式说明符在字符串中扮演着占位符的角色,它定义后续的函数参数如何被格式化及插入到结果中。每一个formatarg参数会被根据其数据类型的常规输出规则转换为文本,并接着根据格式说明符被格式化和插入到结果字符串中。 + formatstr是指定结果格式的字符串。格式字符串中的文本会直接复制到结果中,但格式说明符所在的位置除外。格式说明符充当字符串中的占位符,定义如何格式化后续函数参数并将其插入结果。每个formatarg参数都按照其数据类型通常的输出规则转换为文本,再根据格式说明符进行格式化并插入结果字符串。 - 格式说明符由一个%字符开始并且有这样的形式 + 格式说明符以%字符开头,格式如下: %[position][flags][width]type - 其中的各组件域是: + 其中各组成字段为: position(可选) - 一个形式为n$的字符串,其中n是要打印的参数的索引。索引 1 表示formatstr之后的第一个参数。如果position被忽略,默认会使用序列中的下一个参数。 + 一个形式为n$的字符串,其中n是要打印的参数的索引。索引 1 表示formatstr之后的第一个参数。如果position被省略,默认会使用序列中的下一个参数。 @@ -3621,9 +3741,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in flags(可选) - - 控制格式说明符的输出如何被格式化的附加选项。当前唯一支持的标志是一个负号(-),它将导致格式说明符的输出会被左对齐(left-justified)。除非width域也被指定,否者这个域不会产生任何效果。 - + 用于控制格式说明符输出格式的附加选项。目前唯一支持的标志是减号(-),它使格式说明符的输出左对齐。只有同时指定了width字段时,它才有效。 @@ -3635,8 +3753,8 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in - 如果宽度来自于一个函数参数,则参数在被格式说明符的值使用之前就被消耗掉了。如果宽度参数是负值,结果会在长度为abs(width)的域中被左对齐(如果-标志被指定)。 - + 如果宽度来自一个函数参数,会先使用该宽度参数,再使用作为格式说明符值的参数。如果宽度参数为负数,结果会在长度为abs(width)的字段中左对齐(如同指定了-标志)。 +
@@ -3653,12 +3771,12 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in - I将参数值视作 SQL 标识符,并在必要时用双写引号包围它。如果参数为空,将会是一个错误(等效于quote_ident)。 + I将参数值视作 SQL 标识符,并在必要时用双引号包围它。如果参数为 null,则会报错(等效于quote_ident)。 - L将参数值引用为 SQL 文字。一个空值将被显示为不带引号的字符串NULL(等效于quote_nullable)。 + L将参数值作为 SQL 字面量加引号。null 值显示为不带引号的字符串NULL(等效于quote_nullable)。 @@ -3669,13 +3787,10 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in
- 除了以上所述的格式说明符之外,要输出一个文字形式的%字符,可以使用特殊序列%%。 + 除了以上所述的格式说明符之外,要输出一个字面形式的%字符,可以使用特殊序列%% - - 下面有一些基本的格式转换的示例: - - + 下面是一些基本格式转换的示例: SELECT format('Hello %s', 'World'); 结果:Hello World @@ -3686,14 +3801,11 @@ SELECT format('INSERT INTO %I VALUES(%L)', 'Foo bar', E'O\'Reilly'); 结果:INSERT INTO "Foo bar" VALUES('O''Reilly') SELECT format('INSERT INTO %I VALUES(%L)', 'locations', 'C:\Program Files'); -结果:INSERT INTO locations VALUES(E'C:\\Program Files') +结果:INSERT INTO locations VALUES('C:\Program Files') - - 下面是使用width域和-标志的示例: - - + 下面是使用width字段和-标志的示例: SELECT format('|%10s|', 'foo'); 结果:| foo| @@ -3714,10 +3826,7 @@ SELECT format('|%-*s|', -10, 'foo'); - - 这些示例展示了position域的示例: - - + 这些示例展示了如何使用position字段: SELECT format('Testing %3$s, %2$s, %1$s', 'one', 'two', 'three'); 结果:Testing three, two, one @@ -3729,10 +3838,8 @@ SELECT format('|%1$*2$s|', 'foo', 10, 'bar'); - - 不同于标准的 C 函数sprintfPostgreSQLformat函数允许将带有或者不带有position域的格式说明符被混在同一个格式字符串中。一个不带有position域的格式说明符总是使用最后一个被消耗的参数的下一个参数。另外,format函数不要求所有函数参数都被用在格式字符串中。例如: - - + 不同于标准 C 函数sprintf, + PostgreSQLformat函数允许在同一个格式字符串中,混合使用带有或不带有position字段的格式说明符。不带position字段的格式说明符,总是使用最后一个已使用参数之后的下一个参数。此外,format函数不要求格式字符串使用全部函数参数。例如: SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); 结果:Testing three, two, three @@ -3750,17 +3857,17 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); 二进制串函数和操作符 - binary data - functions + 二进制数据 + 函数 - 本节描述那些检查和操作二进制字符串的函数和操作符,这是类型bytea的值。 + 本节描述用于检查和操作二进制字符串(即bytea类型的值)的函数和操作符。 其中许多函数在用途和语法上都与上一节中描述的文本字符串函数等效。 - SQL定义了一些使用关键字而不是逗号来分割参数的串函数。详情请见PostgreSQL也提供了这些函数使用常规函数调用语法的版本(参阅)。 + SQL定义了一些使用关键字而不是逗号来分隔参数的字符串函数。详情请见PostgreSQL也提供了这些函数使用常规函数调用语法的版本(参阅)。 @@ -3787,14 +3894,14 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); - binary string - concatenation + 二进制串 + 串接 bytea || bytea bytea - 连接两个二进制字符串。 + 串接两个二进制字符串。 '\x123456'::bytea || '\x789a00bcde'::bytea @@ -3819,6 +3926,42 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); + + + + btrim + + btrim ( bytes bytea, + bytesremoved bytea ) + bytea + + + 从bytes的开头和结尾移除仅由bytesremoved中字节组成的最长字符串。 + + + btrim('\x1234567890'::bytea, '\x9012'::bytea) + \x345678 + + + + + + + ltrim + + ltrim ( bytes bytea, + bytesremoved bytea ) + bytea + + + 从bytes的开头移除仅由bytesremoved中字节组成的最长字符串。 + + + ltrim('\x1234567890'::bytea, '\x9012'::bytea) + \x34567890 + + + @@ -3845,8 +3988,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bytea - 将bytes的子字符串替换为newsubstring,该子字符串从start字节开始,并以count字节扩展。 - 如果忽略了count,则默认为newsubstring的长度。 + 用newsubstring替换bytes中从第start个字节开始、长度为count个字节的子字符串。如果省略count,则默认为newsubstring的长度。 overlay('\x1234567890'::bytea placing '\002\003'::bytea from 2 for 3) @@ -3863,7 +4005,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); integer - 返回bytes中指定的substring的第一个起始索引,如果不存在,则为零。 + 返回substringbytes中首次出现的位置;如果不存在则返回零。 position('\x5678'::bytea in '\x1234567890'::bytea) @@ -3871,6 +4013,24 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); + + + + rtrim + + rtrim ( bytes bytea, + bytesremoved bytea ) + bytea + + + 从bytes的结尾移除仅由bytesremoved中字节组成的最长字符串。 + + + rtrim('\x1234567890'::bytea, '\x9012'::bytea) + \x12345678 + + + @@ -3880,8 +4040,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bytea - 提取bytesstart字节开始的子字符串,如果指定了,并且在count字节之后停止,如果指定了的话。 - 至少提供startcount中的一个。 + 提取bytes的子字符串:若指定了起始位置,则从第start个字节开始;若指定了长度,则在提取count个字节后停止。startcount至少需要指定一个。 substring('\x1234567890'::bytea from 3 for 2) @@ -3900,7 +4059,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bytea - 删除bytesremoved中只包含字节的最长字符串,从bytes的开始、结束,或两端(BOTH 为默认的)。 + 从bytes的开头、结尾或两端(默认为BOTH)移除仅由bytesremoved中字节组成的最长字符串。 trim('\x9012'::bytea from '\x1234567890'::bytea) @@ -3916,7 +4075,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bytea - 这是trim()的非标准语法。 + 这是一个非标准的trim()语法。 trim(both from '\x1234567890'::bytea, '\x9012'::bytea) @@ -3928,7 +4087,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three');
- 还有一些二进制串处理函数可以使用,在列出。 其中有一些是在内部使用,用于实现列出的 SQL 标准串函数。 + 还有一些二进制串处理函数可以使用,在列出。 其中有一些是在内部使用,用于实现列出的 SQL 标准串函数。 @@ -3965,7 +4124,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bigint - 返回二进制字符串中设置的位数(也被认为popcount)。 + 返回二进制字符串中被置位的位数(也称为popcount)。 bit_count('\x1234567890'::bytea) @@ -3973,23 +4132,41 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); + + - btrim + crc32 - btrim ( bytes bytea, - bytesremoved bytea ) - bytea + crc32 ( bytea ) + bigint - 从bytes的开始和结束处删除只包含bytesremoved中出现的字节的最长字符串 + 计算二进制字符串的 CRC-32 值。 - btrim('\x1234567890'::bytea, '\x9012'::bytea) - \x345678 - - + crc32('abc'::bytea) + 891568578 + + + + + + + crc32c + + crc32c ( bytea ) + bigint + + + 计算二进制字符串的 CRC-32C 值。 + + + crc32c('abc'::bytea) + 910901175 + + @@ -4001,7 +4178,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); integer - 从二进制字符串中提取 n'th 位。 + 从二进制字符串中提取 编号为 n 的 位。 get_bit('\x1234567890'::bytea, 30) @@ -4019,7 +4196,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); integer - 从二进制字符串中提取 n'th 字节。 + 从二进制字符串中提取 编号为 n 的 字节。 get_byte('\x1234567890'::bytea, 4) @@ -4033,13 +4210,13 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); length - binary string - length + 二进制串 + 长度 - length - 二进制字符串 - binary strings, length + 长度 + 二进制串 + 二进制串,长度 length ( bytea ) integer @@ -4068,23 +4245,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); - - - - ltrim - - ltrim ( bytes bytea, - bytesremoved bytea ) - bytea - - - 从bytes开头移除出现在bytesremoved中的只包含字节的最长字符串。 - - - ltrim('\x1234567890'::bytea, '\x9012'::bytea) - \x34567890 - - + @@ -4103,23 +4264,24 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); + + - - - rtrim - - rtrim ( bytes bytea, - bytesremoved bytea ) - bytea - - - 从bytes结尾移除出现在bytesremoved中的只包含字节的最长字符串。 - - - rtrim('\x1234567890'::bytea, '\x9012'::bytea) - \x12345678 - - + + + reverse + + reverse ( bytea ) + bytea + + + 反转二进制字符串中字节的顺序。 + + + reverse('\xabcd'::bytea) + \xcdab + + @@ -4132,7 +4294,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bytea - 设置二进制字符串中的n'th位为newvalue。 + 设置二进制字符串中的编号为 n 的位为newvalue set_bit('\x1234567890'::bytea, 30, 0) @@ -4151,7 +4313,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bytea - 设置二进制字符串中的 n'th 字节到 newvalue。 + 设置二进制字符串中的 编号为 n 的 字节到 newvalue set_byte('\x1234567890'::bytea, 4, 64) @@ -4206,7 +4368,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); sha384('abc'::bytea) - \xcb00753f45a35e8bb5a03d699ac65007&zwsp;272c32ab0ed1631a8b605a43ff5bed&zwsp;8086072ba1e7cc2358baeca134c825a7 + \xcb00753f45a35e8bb5a03d699ac65007&zwsp;272c32ab0eded1631a8b605a43ff5bed&zwsp;8086072ba1e7cc2358baeca134c825a7 @@ -4223,7 +4385,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); sha512('abc'::bytea) - \xddaf35a193617abacc417349ae204131&zwsp;12e6fa4e89a97ea20a9ee64b55d39a&zwsp;2192992a274fc1a836ba3c23a3feebbd&zwsp;454d4423643ce80e2a9ac94fa54ca49f + \xddaf35a193617abacc417349ae204131&zwsp;12e6fa4e89a97ea20a9eeee64b55d39a&zwsp;2192992a274fc1a836ba3c23a3feebbd&zwsp;454d4423643ce80e2a9ac94fa54ca49f @@ -4236,8 +4398,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bytea - 从start字节开始提取bytes的子字符串,并扩展为count字节,如果这是指定的。 - (与 substring(bytesstartcount) 相同.) + 提取bytes中从第start个字节开始的子字符串;若指定了长度,则提取count个字节。(与substring(bytes from start for count)相同。) substr('\x1234567890'::bytea, 3, 2) @@ -4249,7 +4410,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three');
- 函数get_byteset_byte把一个二进制串中的一个字节计数为字节 0。 + 函数get_byteset_byte把二进制串中的第一个字节编号为字节 0。 函数get_bitset_bit在每一个字节中从右边起计数位; 例如位 0 是第一个字节的最低有效位,而位 15 是第二个字节的最高有效位。 @@ -4257,16 +4418,16 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); 由于历史原因,函数md5返回的是一个十六进制编码的text值,而SHA-2函数返回类型bytea。 可以使用函数encodedecode在两者之间转换。 - 例如encode(sha256('abc'),'hex')可以得到一个十六进制编码的文本表示,或者decode(md5('abc'), 'hex')得到一个bytea 值。 + 例如encode(sha256('abc'), 'hex')可以得到一个十六进制编码的文本表示,或者decode(md5('abc'), 'hex')得到一个bytea 值。 - character string + 字符串 转换为二进制字符串 - binary string + 二进制串 转换为字符串 用于在不同字符集(编码)之间转换字符串的函数,以及用于以文本形式表示任意二进制数据的函数,在中显示。 @@ -4275,7 +4436,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); - 文本/字符串转换函数 + 文本/二进制串转换函数 @@ -4383,7 +4544,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bytea - 从文本表示中解码二进制数据;支持的format值与encode相同。 + 从文本表示中解码二进制数据;支持的format值与encode相同。 decode('MTIzAAE=', 'base64') @@ -4407,9 +4568,9 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); base64格式是RFC 2045第6.8节中描述的。根据RFC,编码行在76个字符处换行。 - 然而,与MIME CRLF换行符不同,结尾只使用换行符。 + 然而,与MIME CRLF换行符不同,行尾只使用一个换行符。 decode函数会忽略回车、换行、空格和制表符。 - 否则,当decode提供无效的base64数据时,包括尾部填充不正确时,会引发错误。 + 否则,当向decode传入无效的 base64 数据时,包括尾部填充不正确时,会引发错误。 @@ -4421,8 +4582,8 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); - escape格式将零字节和高位设置的字节转换为八进制转义序列 - (\nnn),并将反斜杠加倍。 + escape格式将零字节和最高位被置位的字节转换为八进制转义序列 + (\nnn),并将反斜杠双写。 其他字节值会直接表示。如果反斜杠后面不是第二个反斜杠或三个八进制数字,则decode函数会引发错误; 它会接受其他字节值不变。 @@ -4437,10 +4598,10 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); hex格式将每4位数据表示为一个十六进制数字,0f, - 先写入每个字节的高阶数字。 encode函数以小写输出a-f十六进制数字。 + 先写入每个字节的高位数字。 encode函数以小写输出a-f十六进制数字。 因为数据的最小单位是8位,所以encode总是返回偶数个字符。 decode函数接受a-f字符的大小写。 - 当decode提供无效的十六进制数据时,包括提供奇数个字符时,会引发错误。 + 当向decode传入无效的十六进制数据时,包括提供奇数个字符时,会引发错误。 @@ -4448,6 +4609,19 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); + 此外,还可以在整数值与bytea类型之间进行类型转换。 + 将整数转换为bytea会产生 2、4 或 8 个字节,具体取决于整数类型的宽度。 + 结果是该整数的补码表示,最高有效字节在前。以下是一些示例: + +1234::smallint::bytea \x04d2 +cast(1234 as bytea) \x000004d2 +cast(-1234 as bytea) \xfffffb2e +'\x8000'::bytea::smallint -32768 +'\x8000'::bytea::integer 32768 + + 将bytea转换为整数时,如果bytea的长度超过整数类型的宽度,则会引发错误。 + + 参见中的聚合函数string_agg以及中的大对象函数。 @@ -4457,14 +4631,14 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); 位串函数和操作符 - bit strings - functions + 位串 + 函数 本节描述用于检查和操作位串的函数和操作符,也就是操作类型为bitbit varying的值的函数和操作符。 - (虽然这些表中只提到了bit类型,但bit varying类型的值可以互换使用。) - 位字符串支持中显示的常用比较操作符,就像中显示的操作符。 + (虽然这些表中只提到了bit类型,但bit varying类型的值可以互换使用。) + 位串支持中显示的常用比较操作符,以及中显示的操作符。
@@ -4494,7 +4668,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bit - 连接 + 串接 B'10001' || B'011' @@ -4550,7 +4724,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bit - 按位求反 + 按位非 ~ B'10001' @@ -4590,12 +4764,12 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three');
- 一些可用于二进制字符串的函数也可用于位字符串,如中所示。 + 一些可用于二进制字符串的函数也可用于位串,如中所示。 - 位字符串函数 + 位串函数 @@ -4623,7 +4797,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bigint - 返回位字符串中设置的位数(也被视为popcount)。 + 返回位串中被置位的位数(也称为popcount)。 bit_count(B'10111') @@ -4640,7 +4814,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); integer - 返回位字符串中的位数。 + 返回位串中的位数。 bit_length(B'10111') @@ -4654,14 +4828,14 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); length - bit string - length + 位串 + 长度 length ( bit ) integer - 返回位字符串中的位数。 + 返回位串中的位数。 length(B'10111') @@ -4678,7 +4852,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); integer - 返回位字符串中的字节数。 + 返回位串中的字节数。 octet_length(B'1011111011') @@ -4695,8 +4869,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bit - 替换从start位开始的bits的子字符串,并将newsubstring扩展count位。 - 如果count被省略,默认为newsubstring的长度。 + 用newsubstring替换bits中从第start位开始、长度为count位的子串。如果省略count,则默认为newsubstring的长度。 overlay(B'01010101010101010' placing B'11111' from 2 for 3) @@ -4713,7 +4886,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); integer - 按返回指定substring的第一个起始索引,以bits为单位,如果不存在则返回0。 + 返回substringbits中首次出现的位置;如果不存在则返回零。 position(B'010' in B'000001101011') @@ -4730,8 +4903,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bit - 如果指定了起始位,则提取从start位开始的bits的子字符串,如果指定了计数位,则在count位之后停止。 - startcount至少提供一个。 + 提取bits的子串:若指定了起始位置,则从第start位开始;若指定了长度,则在提取count位后停止。startcount至少需要指定一个。 substring(B'110010111111' from 3 for 2) @@ -4749,7 +4921,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); integer - 从位字符串中提取第n位;第一个(最左)位为第0位。 + 从位串中提取编号为n的位;第一位(最左侧的位)编号为位 0。 get_bit(B'101010101010101010', 6) @@ -4768,7 +4940,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bit - 将位字符串中的第n位设置为newvalue;第一个(最左)位是第0位。 + 将位串中编号为n的位设置为newvalue;第一位(最左侧的位)编号为位 0。 set_bit(B'101010101010101010', 6, 0) @@ -4779,18 +4951,12 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three');
- - 另外,我们可以在整数和bit之间来回转换。 - 将一个整数转换为bit(n)会复制最右边的n位。 - 将一个整数转换为比整数本身更宽的位字符串宽度将在左边进行符号扩展。一些示例: - + 此外,还可以在整数值与bit类型之间进行类型转换。将整数转换为bit(n)会复制最右侧的n位。将整数转换为宽度超过该整数自身位宽的位串时,会在左侧进行符号扩展。下面是一些示例: 44::bit(10) 0000101100 44::bit(3) 100 cast(-44 as bit(12)) 111111010100 '1110'::bit(4)::integer 14 - - 请注意,如果只是转换为bit,意思是转换成bit(1),因此只会转换整数的最低有效位。 - +注意,仅转换为bit意味着转换为bit(1),因此只会得到该整数的最低有效位。 @@ -4798,11 +4964,11 @@ cast(-44 as bit(12)) 111111010100 模式匹配 - pattern matching + 模式匹配 - PostgreSQL提供了三种独立的实现模式匹配的方法:SQL LIKE操作符、更近一些的SIMILAR TO操作符(SQL:1999 里添加进来的)和POSIX-风格的正则表达式。除了这些基本的这个串匹配这个模式吗?操作符外,还有一些函数可用于提取或替换匹配子串并在匹配位置分离一个串。 + PostgreSQL提供了三种独立的模式匹配方法:传统的SQL LIKE操作符、较新的SIMILAR TO操作符(在 SQL:1999 中加入),以及POSIX风格的正则表达式。除了用于判断这个字符串是否匹配这个模式?的基本操作符外,还提供了提取或替换匹配子字符串、在匹配位置分割字符串的函数。 @@ -4815,25 +4981,20 @@ cast(-44 as bit(12)) 111111010100 - 虽然大部分的正则表达式搜索都能被很快地执行,但是正则表达式仍可能被 - 人为地弄成需要任意长的时间和任意量的内存进行处理。要当心从不怀好意 - 的来源接受正则表达式搜索模式。如果必须这样做,建议加上语句超时限制。 + 虽然大多数正则表达式搜索都能很快完成,但特意构造的正则表达式可能需要任意长的处理时间和任意多的内存。接受来自恶意来源的正则表达式搜索模式时应当谨慎。如果必须这样做,建议设置语句超时。 - 使用SIMILAR TO模式的搜索具有同样的安全性危险, - 因为SIMILAR TO提供了很多和 - POSIX-风格正则表达式相同的能力。 + 使用SIMILAR TO模式进行搜索具有同样的安全风险,因为SIMILAR TO提供了许多与POSIX风格正则表达式相同的能力。 - LIKE搜索比其他两种选项简单得多,因此在使用 - 不怀好意的模式来源时要更安全些。 + LIKE搜索比另外两种方法简单得多,因此,当模式可能来自恶意来源时,使用它更安全。 - SIMILAR TOPOSIX-风格正则表达式不支持非确定性排序规则。如果需要的话,可以使用LIKE或在表达式中应用不同的排序规则来绕过这个限制。 + SIMILAR TOPOSIX 风格的正则表达式不支持非确定性排序规则。如有需要,可以使用 LIKE,或对表达式应用不同的排序规则来绕过这一限制。 @@ -4853,7 +5014,11 @@ cast(-44 as bit(12)) 111111010100
- 如果pattern不包含百分号或者下划线,那么该模式只代表它本身的串;这时候LIKE的行为就象等号操作符。在pattern里的下划线 (_)代表(匹配)任何单个字符; 而一个百分号(%)匹配任何零或更多个字符的序列。 + 如果pattern不包含百分号或下划线,那么该模式只表示它 + 本身的字符串;在这种情况下,LIKE的行为就像等号操作符。 + pattern中的下划线(_)代表 + (匹配)任意单个字符;百分号(%)匹配任意由零个或多个 + 字符组成的序列。 @@ -4867,23 +5032,41 @@ cast(-44 as bit(12)) 111111010100 - LIKE模式匹配总是覆盖整个串。因此,要匹配在串内任何位置的序列,该模式必须以百分号开头和结尾。 + LIKE 模式匹配支持非确定性排序规则(参见 ),例如不区分大小写的排序规则,或忽略标点符号的排序规则。因此,使用不区分大小写的排序规则时,可以得到: + +'AbC' LIKE 'abc' COLLATE case_insensitive true +'AbC' LIKE 'a%' COLLATE case_insensitive true + +对于忽略某些字符,或更一般地将不同长度的字符串视为相等的排序规则,语义会稍显复杂。考虑以下示例: + +'.foo.' LIKE 'foo' COLLATE ign_punct true +'.foo.' LIKE 'f_o' COLLATE ign_punct true +'.foo.' LIKE '_oo' COLLATE ign_punct false + +匹配时会把模式划分为通配符序列和非通配符字符串(通配符为 _%)。例如,模式 f_o 被划分为 f, _, o,模式 _oo 被划分为 _, oo。如果输入字符串能以某种方式划分,使通配符分别匹配一个字符或任意数量的字符,且非通配符片段在所用排序规则下相等,则输入字符串与模式匹配。例如,'.foo.' LIKE 'f_o' COLLATE ign_punct 为真,因为可以把 .foo. 划分为 .f, o, o.;此时 '.f' = 'f' COLLATE ign_punct'o' 匹配通配符 _,且 'o.' = 'o' COLLATE ign_punct。但 '.foo.' LIKE '_oo' COLLATE ign_punct 为假,因为无法将 .foo. 划分为首个字符匹配任意字符、而剩余字符串与 oo 比较相等的形式。(注意,单字符通配符始终恰好匹配一个字符,与排序规则无关。因此,在此示例中,_ 会匹配 .,但输入字符串的其余部分无法匹配模式的其余部分。) + + + + LIKE模式匹配总是覆盖整个字符串。因此,如果想要匹配字符串内 + 任意位置上的一个序列,该模式就必须以百分号开头并以百分号结尾。 - 要匹配文本的下划线或者百分号,而不是匹配其它字符, 在pattern里相应的字符必须 前导转义字符。缺省的转义字符是反斜线,但是你可以用ESCAPE子句指定一个不同的转义字符。 要匹配转义字符本身,写两个转义字符。 + 要匹配字面量下划线或百分号而不是把它们当作通配符, + pattern中相应的字符前面必须带有转义字符。 + 默认的转义字符是反斜线,但也可以使用ESCAPE子句选择其他 + 转义字符。要匹配转义字符本身,请写两个转义字符。 - 如果你关掉了,你在文串常量中写的任何反斜线都需要被双写。详见。 + 如果你关掉了,你在字符串常量中写的任何反斜线都需要被双写。详见 - 请注意反斜线在串文本里已经有特殊含义了,所以如果你写一个 包含反斜线的模式常量,那你就要在 SQL 语句里写两个反斜线。 因此,写一个匹配单个反斜线的模式实际上要在语句里写四个反斜线。 你可以通过用 ESCAPE 选择一个不同的转义字符 来避免这样;这样反斜线就不再是 LIKE 的特殊字符了。 但仍然是字符文本分析器的特殊字符,所以你还是需要两个反斜线。) - 我们也可以通过写ESCAPE ''的方式不选择转义字符,这样可以有效地禁用转义机制,但是没有办法关闭下划线和百分号在模式中的特殊含义。 + 也可以通过写 ESCAPE '' 来选择不使用转义字符。这会禁用转义机制,从而无法关闭模式中下划线和百分号的特殊含义。 @@ -4892,7 +5075,7 @@ cast(-44 as bit(12)) 111111010100 - 关键字ILIKE可以用于替换LIKE,它令该匹配根据活动区域成为大小写无关。(但这不支持非确定性排序规则。)这个不属于SQL标准而是一个PostgreSQL扩展。 + 可以用关键字 ILIKE 代替 LIKE,使匹配根据当前区域设置忽略大小写。(但它不支持非确定性排序规则。)这不属于 SQL 标准,而是 PostgreSQL 的扩展。 @@ -4903,14 +5086,11 @@ cast(-44 as bit(12)) 111111010100 - 短语LIKEILIKENOT LIKE,和 NOT ILIKEPostgreSQL语法中通常被视为操作符; - 例如,它们可以用于expression operator的任何(subquery)构造,尽管这里不能包含ESCAPE子句。 - 在某些晦涩难懂的情况下,可能需要用底层操作符名称替代。 + 在 PostgreSQL 语法中,LIKEILIKENOT LIKENOT ILIKE 通常被当作操作符;例如,它们可以用于 expression operator ANY (subquery) 构造,但其中不能包含 ESCAPE 子句。在某些不常见的情况下,可能需要改用底层操作符名称。 - 另请参阅以^@开头的操作符和相应的starts_with()函数, - 在需要简单匹配字符串开头的情况下非常有用。 + 另请参见用于匹配字符串开头的操作符 ^@ 和相应的 starts_with() 函数,它们适用于只需匹配字符串开头的情况。 @@ -4919,8 +5099,8 @@ cast(-44 as bit(12)) 111111010100 <function>SIMILAR TO</function>正则表达式 - regular expression - + 正则表达式 + @@ -4937,13 +5117,11 @@ cast(-44 as bit(12)) 111111010100 - SIMILAR TO操作符根据自己的模式是否匹配给定串而返回真或者假。 - 它和LIKE非常类似,只不过它使用 SQL 标准定义的正则表达式理解模式。 - SQL 正则表达式是在LIKE标记和普通的(POSIX)正则表达式标记的奇怪的杂交。 + SIMILAR TO操作符根据其模式是否匹配给定字符串返回真或假。它与LIKE非常相似,但使用 SQL 标准定义的正则表达式来解释模式。SQL 正则表达式是LIKE表示法与普通(POSIX)正则表达式表示法的一种奇特结合。 - 类似LIKESIMILAR TO操作符只有在它的模式匹配整个串的时候才能成功;这一点和普通的 正则表达式的行为不同,在普通的正则表达式里,模式匹配串的任意部分。 和LIKE类似的地方还有,SIMILAR TO使用_%作为分别代表任意单个字符和任意串的通配符(这些可以比得上 POSIX 正则表达式里的..*)。 + 与LIKE类似,SIMILAR TO操作符只有在其模式匹配整个字符串时才算成功;这一点不同于普通正则表达式,后者可以匹配字符串的任意部分。与LIKE相同,SIMILAR TO也使用_%作为通配符,分别匹配任意单个字符和任意字符串(分别类似于 POSIX 正则表达式中的..*)。 @@ -5011,8 +5189,7 @@ cast(-44 as bit(12)) 111111010100 - 另一个非标准扩展是,在转义字符后面跟着一个字母或数字提供了对为POSIX正则表达式定义的转义序列的访问;参见下面的 - ,和 。 + 另一个非标准扩展是在转义字符后跟一个字母或数字,以使用 POSIX 正则表达式定义的转义序列;参见下文的 @@ -5028,19 +5205,19 @@ cast(-44 as bit(12)) 111111010100 - 带有三个参数的substring函数可以提取匹配SQL正则表达式模式的子字符串。 该函数可以按照标准SQL99语法编写。 + 带有三个参数的substring函数可以提取匹配 SQL 正则表达式模式的子字符串。该函数可以按照标准 SQL 语法书写: substring(string similar pattern escape escape-character) - 或使用现在废除的 SQL:1999 语法: + 也可以使用现已过时的 SQL:1999 语法: substring(string from pattern for escape-character) - 或作为一个普通的三参数函数: + 或写成普通的三参数函数: substring(string, pattern, escape-character) - 与SIMILAR TO一样,指定的模式必须与整个数据字符串匹配,否则函数失败并返回空值。 为了表示匹配的数据子字符串的模式中,模式中应该包含两个转义字符的出现,并在后面加上一个双引号(")。 匹配成功后,将返回与这些分隔符之间的模式部分匹配的文本。 + 与SIMILAR TO一样,指定的模式必须匹配整个数据字符串,否则函数失败并返回空值。为了指明要提取的子字符串所对应的模式部分,模式中应包含两个分隔符,每个分隔符都由转义字符后跟双引号(")组成。匹配成功时,返回与这两个分隔符之间的模式部分匹配的文本。 @@ -5048,7 +5225,7 @@ substring(string, pattern, - 作为对SQL标准的扩展,PostgreSQL只允许有一个转义双引号分隔符,在这种情况下,第三个正则表达式被视为空;或者没有分隔符,在这种情况下,第一个和第三个正则表达式被视为空。 + 作为对SQL标准的扩展,PostgreSQL允许仅有一个转义双引号分隔符,在这种情况下,第三个正则表达式被视为空;或者没有分隔符,在这种情况下,第一个和第三个正则表达式被视为空。 @@ -5065,8 +5242,8 @@ substring('foobar' similar '#"o_b#"%' escape '#') NULLPOSIX正则表达式 - regular expression - pattern matching + 正则表达式 + 模式匹配 @@ -5141,7 +5318,7 @@ substring('foobar' similar '#"o_b#"%' escape '#') NULLboolean - 字符串匹配正则表达式,大小写敏感 + 字符串匹配正则表达式,区分大小写 'thomas' ~ 't.*ma' @@ -5155,7 +5332,7 @@ substring('foobar' similar '#"o_b#"%' escape '#') NULLboolean - 字符串匹配正则表达式,大小写不敏感 + 字符串匹配正则表达式,不区分大小写 'thomas' ~* 'T.*ma' @@ -5169,7 +5346,7 @@ substring('foobar' similar '#"o_b#"%' escape '#') NULLboolean - 字符串不匹配正则表达式,大小写敏感 + 字符串不匹配正则表达式,区分大小写 'thomas' !~ 't.*max' @@ -5183,7 +5360,7 @@ substring('foobar' similar '#"o_b#"%' escape '#') NULLboolean - 字符串不匹配正则表达式,大小写不敏感 + 字符串不匹配正则表达式,不区分大小写 'thomas' !~* 'T.*ma' @@ -5195,11 +5372,11 @@ substring('foobar' similar '#"o_b#"%' escape '#') NULL - POSIX正则表达式提供了比LIKESIMILAR TO操作符更强大的含义。许多 Unix 工具,例如egrepsedawk使用一种与我们这里描述的类似的模式匹配语言。 + POSIX正则表达式提供了比LIKESIMILAR TO操作符更强大的模式匹配方式。许多 Unix 工具,例如egrepsedawk,都使用与这里描述的模式匹配语言相似的语言。 - 正则表达式是一个字符序列,它是定义一个串集合 (一个正则集)的缩写。 如果一个串是正则表达式描述的正则集中的一员时, 我们就说这个串匹配该正则表达式。 和LIKE一样,模式字符准确地匹配串字符, 除非在正则表达式语言里有特殊字符 — 不过正则表达式用的 特殊字符和LIKE用的不同。 和LIKE模式不一样的是,正则表达式允许匹配串里的任何位置,除非该正则表达式显式地挂接在串的开头或者结尾。 + 正则表达式是一个字符序列,是定义一组字符串(一个正则集)的简写。如果字符串属于正则表达式描述的正则集,就称该字符串匹配此正则表达式。与LIKE一样,模式中的字符精确匹配字符串中的字符,除非该模式字符在正则表达式语言中有特殊含义 — 但正则表达式使用的特殊字符与LIKE不同。与LIKE模式不同,正则表达式可以匹配字符串中的任意位置,除非显式将其锚定到字符串开头或末尾。 @@ -5220,8 +5397,8 @@ substring('foobar' similar '#"o_b#"%' escape '#') NULL 带两个参数的substring函数,即substring(string from pattern),提供了抽取一个匹配 POSIX 正则表达式模式的子串的方法。 - 如果没有匹配它返回空值,否则就是匹配模式的文本中的第一部分。 - 但是如果该模式包含任何圆括号,那么将返回匹配第一对子表达式(对应第一个左圆括号的) 的文本。 + 如果没有匹配它返回空值,否则返回文本中首次匹配模式的那部分内容。 + 但是如果该模式包含任何圆括号,那么将返回匹配第一个圆括号子表达式(左圆括号最先出现的那个)的文本。 如果你想在表达式里使用圆括号而又不想导致这个例外,那么你可以在整个表达式外边放上一对圆括号。 如果你需要在想抽取的子表达式前有圆括号,参阅后文描述的非捕获性圆括号。 @@ -5250,7 +5427,7 @@ substring('foobar' from 'o(.)b') o - 一些示例: + 一些示例: regexp_count('ABCABCAXYaxy', 'A.') 3 regexp_count('ABCABCAXYaxy', 'A.', 1, 'i') 4 @@ -5258,30 +5435,30 @@ regexp_count('ABCABCAXYaxy', 'A.', 1, 'i') 4 - regexp_instr函数返回字符串中第N个匹配项的起始或结束位置,如果没有这样的匹配项则返回零。 + regexp_instr函数返回 POSIX 正则表达式模式在字符串中第N个匹配项的起始或结束位置,如果没有这样的匹配项则返回零。 它的语法为regexp_instr(string, pattern , start , N , endoption , flags , subexpr - ). + )。 在string中搜索pattern,通常从字符串的开头开始,但如果提供了start参数,则从该字符索引开始。 如果指定了N,则定位模式的第N个匹配项,否则定位第一个匹配项。 如果省略了endoption参数或将其指定为0,则函数返回匹配项的第一个字符的位置。否则,endoption 必须为1,函数返回匹配项后面字符的位置。 flags参数是一个可选的文本字符串,包含零个或多个单字母标志,可以改变函数的行为。支持的标志在中描述。 - 对于包含括号子表达式的模式,subexpr是一个整数,表示感兴趣的子表达式:结果标识与该子表达式匹配的子字符串的位置。 - 子表达式按其前导括号的顺序编号。 - 当省略或将subexpr指定为零时,结果标识整个匹配的位置,而不考虑括号子表达式。 + 对于包含圆括号子表达式的模式,subexpr是一个整数,表示感兴趣的子表达式:结果标识与该子表达式匹配的子字符串的位置。 + 子表达式按其左圆括号的顺序编号。 + 当省略或将subexpr指定为零时,结果标识整个匹配的位置,而不考虑圆括号子表达式。 - 一些示例: + 一些示例: regexp_instr('number of your street, town zip, FR', '[^,]+', 1, 2) 23 -regexp_instr('ABCDEFGHI', '(c..)(...)', 1, 1, 0, 'i', 2) +regexp_instr(string=>'ABCDEFGHI', pattern=>'(c..)(...)', start=>1, "N"=>1, endoption=>0, flags=>'i', subexpr=>2) 6 @@ -5299,7 +5476,7 @@ regexp_instr('ABCDEFGHI', '(c..)(...)', 1, 1, 0, 'i', 2)
- 一些示例: + 一些示例: regexp_like('Hello World', 'world') false regexp_like('Hello World', 'world', 'i') true @@ -5307,18 +5484,18 @@ regexp_like('Hello World', 'world', 'i') true - regexp_match函数返回一个文本数组,其中包含与POSIX正则表达式模式对字符串的第一个匹配的子字符串。它的语法为 + regexp_match函数返回一个文本数组,包含字符串首次匹配 POSIX 正则表达式模式时匹配的子字符串。它的语法为 regexp_match(string, pattern , flags )。 如果没有匹配,结果为NULL。 - 如果找到匹配,并且pattern不包含括号子表达式,则结果是包含与整个模式匹配的子字符串的单元素文本数组。 - 如果找到匹配,并且pattern包含括号子表达式,则结果是一个文本数组,其中n的元素是匹配 - pattern的第n个括号子表达式的子字符串(不包括非捕获括号;详情见下文)。 + 如果找到匹配,并且pattern不包含圆括号子表达式,则结果是包含与整个模式匹配的子字符串的单元素文本数组。 + 如果找到匹配,并且pattern包含圆括号子表达式,则结果是一个文本数组,其中第n个元素是匹配 + pattern的第n个圆括号子表达式的子字符串(不包括非捕获括号;详情见下文)。 flags参数是一个可选的文本字符串,其中包含零个或多个单个字母标志,用于更改函数的行为。支持的标志在中描述。 - 一些示例: + 一些示例: SELECT regexp_match('foobarbequebaz', 'bar.*que'); regexp_match @@ -5337,10 +5514,10 @@ SELECT regexp_match('foobarbequebaz', '(bar)(beque)'); - 在通常情况下,当您只想要整个匹配的子字符串或NULL表示没有匹配时, + 在通常情况下,当你只想要整个匹配的子字符串或NULL表示没有匹配时, 最好的解决方案是使用regexp_substr()。 然而,在PostgreSQL版本15及以上版本中才存在 - regexp_substr()。在旧版本中工作时,您可以提取 + regexp_substr()。在旧版本中工作时,你可以提取 regexp_match()结果的第一个元素,例如: SELECT (regexp_match('foobarbequebaz', 'bar.*que'))[1]; @@ -5383,44 +5560,26 @@ SELECT regexp_matches('foobarbequebazilbarfbonk', '(b[^b]+)(b[^b]+)', 'g'); - 在大部分情况下,regexp_matches()应该与g标志一起使用,因为如果只是想要第一个匹配,使用regexp_match()会更加简单高效。不过,regexp_match()仅存在于PostgreSQL版本10以及更高的版本中。当在较老的版本中使用时,一种常用的技巧是把regexp_matches()调用放在子选择中,例如: + 在大部分情况下,regexp_matches()应该与g标志一起使用,因为如果只是想要第一个匹配,使用regexp_match()会更加简单高效。不过,regexp_match()仅存在于PostgreSQL版本10以及更高的版本中。当在较老的版本中使用时,一种常用的技巧是把regexp_matches()调用放在子查询中,例如: SELECT col1, (SELECT regexp_matches(col2, '(bar)(beque)')) FROM tab; - 如果有一个匹配,则这个语句会产生一个文本数组,否则返回NULL,这和regexp_match()的做法一样。如果没有子选择,这个查询对于没有匹配的表行根本不会产生输出,显然那不是想要的行为。 + 如果有一个匹配,则这个语句会产生一个文本数组,否则返回NULL,这和regexp_match()的做法一样。如果没有子查询,这个查询对于没有匹配的表行根本不会产生输出,这通常不是预期行为。 - regexp_replace函数提供了对匹配POSIX正则表达式模式的子字符串进行替换的功能。 - 它的语法为 - regexp_replace(source, + regexp_replace函数将匹配 POSIX 正则表达式模式的子字符串替换为新文本。它的语法为 regexp_replace(string, pattern, replacement - , start + , flags ) 或 regexp_replace(string, + pattern, replacement, + start , N - - , flags ). - (注意,除非指定了start,否则无法指定N, - 但flags可以在任何情况下给出。) - 如果pattern没有匹配到source字符串, - 则返回未更改的source字符串。如果有匹配,则返回带有 - replacement字符串替换匹配子字符串的source字符串。 - replacement字符串可以包含\n, - 其中n为1至9,表示应插入与模式的第n个括号子表达式匹配的源子字符串, - 也可以包含\&表示应插入与整个模式匹配的子字符串。 - 如果需要在替换文本中放置一个字面上的反斜杠,则写\\。 - 在string中搜索pattern, - 通常从字符串的开头开始,但如果提供了start参数,则从该字符索引开始。 - 默认情况下,只替换模式的第一个匹配项。 - 如果指定了N且大于零,则替换模式的第N个匹配项。 - 如果给出了g标志,或者指定了N且为零,则在或之后的所有匹配项 - 位置都将被替换。 (当指定了N时,g标志将被忽略。) - flags参数是一个可选的文本字符串,包含零个或多个单字母标志,用于更改函数的行为。 - 支持的标志(尽管不包括g)在中描述。 + , flags )。如果没有匹配pattern的内容,则原样返回源字符串string。如果有匹配,则返回将匹配的子字符串替换为replacement后的stringreplacement字符串可以包含\n,其中n为 1 至 9,表示插入与模式中第n个圆括号子表达式匹配的源子字符串;也可以包含\&,表示插入与整个模式匹配的子字符串。要在替换文本中放入字面的反斜线,应写成\\。在string中搜索pattern时,通常从字符串开头开始;如果提供了start参数,则从该字符索引开始。默认只替换模式的第一个匹配项。如果指定了N且其值大于零,则替换模式的第N个匹配项。如果给出g标志,或指定了N且其值为零,则替换start位置及其后的所有匹配项。(指定N时,g标志会被忽略。)flags参数是可选的文本字符串,可包含零个或多个单字母标志,用于改变函数行为。支持的标志(不包括g)在中介绍。 - 一些示例: + 一些示例: regexp_replace('foobarbaz', 'b..', 'X') fooXbaz @@ -5430,13 +5589,13 @@ regexp_replace('foobarbaz', 'b(..)', 'X\1Y', 'g') fooXarYXazY regexp_replace('A PostgreSQL function', 'a|e|i|o|u', 'X', 1, 0, 'i') X PXstgrXSQL fXnctXXn -regexp_replace('A PostgreSQL function', 'a|e|i|o|u', 'X', 1, 3, 'i') +regexp_replace(string=>'A PostgreSQL function', pattern=>'a|e|i|o|u', replacement=>'X', start=>1, "N"=>3, flags=>'i') A PostgrXSQL function - regexp_split_to_table把一个 POSIX 正则表达式模式当作一个定界符来分离一个串。它的语法形式是regexp_split_to_table(string, pattern , flags )。如果没有与pattern的匹配,该函数返回string。如果有至少有一个匹配,对每一个匹配它都返回从上一个匹配的末尾(或者串的开头)到这次匹配开头之间的文本。当没有更多匹配时,它返回从上一次匹配的末尾到串末尾之间的文本。flags参数是一个可选的文本串,它包含零个或更多单字母标志,这些标识可以改变该函数的行为。regexp_split_to_table能支持的标志在中描述。 + regexp_split_to_table把一个 POSIX 正则表达式模式当作一个定界符来分割字符串。它的语法形式是regexp_split_to_table(string, pattern , flags )。如果没有与pattern的匹配,该函数返回string。如果至少有一个匹配,对每一个匹配它都返回从上一个匹配的末尾(或者串的开头)到这次匹配开头之间的文本。当没有更多匹配时,它返回从上一次匹配的末尾到串末尾之间的文本。flags参数是一个可选的文本串,它包含零个或更多单字母标志,这些标志可以改变该函数的行为。regexp_split_to_table能支持的标志在中描述。 @@ -5444,7 +5603,7 @@ regexp_replace('A PostgreSQL function', 'a|e|i|o|u', 'X', 1, 3, 'i') - 一些示例: + 一些示例: SELECT foo FROM regexp_split_to_table('the quick brown fox jumps over the lazy dog', '\s+') AS foo; foo @@ -5490,9 +5649,9 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; - 正如最后一个示例所示,regexp分割函数会忽略出现在字符串开头或结尾 - 或紧跟在前一个匹配项之后的零长度匹配。这与其他regexp函数实现的 - 严格的regexp匹配定义相矛盾,但在实践中通常是最方便的行为。 + 正如最后一个示例所示,正则表达式分割函数会忽略出现在字符串开头或结尾 + 或紧跟在前一个匹配项之后的零长度匹配。这与其他正则表达式函数实现的 + 严格的正则表达式匹配定义相矛盾,但在实践中通常是最方便的行为。 其他软件系统如Perl使用类似的定义。 @@ -5505,23 +5664,23 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; , N , flags , subexpr - )。 + )。 patternstring中进行搜索, 通常从字符串的开头开始,但如果提供了start参数,则从该字符索引开始。 如果指定了N,则返回模式的第N次匹配, 否则返回第一次匹配。参数flags是一个可选文本字符串, 包含零个或多个单字母标志,可以改变函数的行为。支持的标志在中描述。 - 对于包含括号子表达式的模式,subexpr是一个整数, + 对于包含圆括号子表达式的模式,subexpr是一个整数, 表示感兴趣的子表达式:结果是与该子表达式匹配的子字符串。 - 子表达式按其前导括号的顺序编号。 - 当省略或为零时,subexpr的结果是整个匹配,而不考虑括号子表达式。 + 子表达式按其左圆括号的顺序编号。 + 当subexpr省略或为零时,结果是整个匹配,而不考虑圆括号子表达式。 - 一些示例: + 一些示例: regexp_substr('number of your street, town zip, FR', '[^,]+', 1, 2) - 城镇 邮编 + town zip regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) FGH @@ -5558,7 +5717,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 一个量化原子是一个原子, 后面可能跟着一个量词。没有量词的时候,它匹配一个原子, 有量词的时候,它可以匹配若干个原子。一个原子可以是在里面显示的任何可能。 可能的量词和它们的含义在里显示。 + 一个量化原子是一个原子,后面可以跟一个量词。没有量词时,匹配一次原子所匹配的内容;有量词时,按量词指定的次数匹配原子所匹配的内容。原子可以是列出的任何一种形式。可用量词及其含义见 @@ -5582,12 +5741,12 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) (re) - (其中re是任何正则表达式) 匹配一个对re的匹配,匹配将为可能的报告被记下 + (其中re是任意正则表达式)匹配re所匹配的内容,并记录该匹配,以备输出结果 (?:re) - 同上,但是匹配不会为了报告而被记下 (一个非捕获圆括号集) (只对 ARE) + 同上,但不记录匹配结果(非捕获圆括号;仅适用于 ARE) @@ -5602,17 +5761,17 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) \k - (其中k是一个非字母数字字符) 匹配一个被当作普通字符看待的特定字符, 例如,\\匹配一个反斜线字符 + (其中k既不是字母也不是数字)把该字符视为普通字符并匹配它,例如,\\匹配反斜线字符 \c - 其中c是一个字母数字 (可能跟着其它字符),它是一个转义, 参阅(仅对 ARE; 在 ERE 和 BRE 中,它匹配c + 其中c是字母或数字(后面可能还有其他字符),这是一个转义,参见(仅适用于 ARE;在 ERE 和 BRE 中,它匹配c { - 如果后面跟着一个字符,而不是数字, 那么就匹配左花括弧{;如果跟着一个数字, 那么它是range的开始(见下文) + 如果后面跟着非数字字符,则匹配左花括号{;如果后面跟着数字,则是bound的开头(见下文) @@ -5630,7 +5789,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 如果你关掉了,你在文串常量中写的任何反斜线都需要被双写。详见。 + 如果你关掉了,你在字符串常量中写的任何反斜线都需要被双写。详见 @@ -5719,7 +5878,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 非贪婪的量词(只在 ARE 中可用)匹配对应的正常 (贪婪)模式,区别是它寻找最少的匹配,而不是最多的匹配。详见。 + 非贪婪量词(仅适用于 ARE)与对应的普通(贪婪)量词匹配相同的可能内容,但优先选择最少的匹配次数,而不是最多的匹配次数。详见 @@ -5746,39 +5905,39 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) ^ - 串开头的匹配 + 在字符串开头匹配 $ - 串末尾的匹配 + 在字符串末尾匹配 (?=re) - 在某个位置上,如果从该位置开始的子串能够匹配re,则匹配正向先行断言(仅对 ARE) + 正向先行断言在这样的位置匹配:存在从该位置开始且匹配re的子字符串(仅适用于 ARE) (?!re) - 在某个位置上,如果从该位置开始的子串不能匹配re,则匹配负向先行断言(仅对 ARE) + 负向先行断言在这样的位置匹配:不存在任何从该位置开始且匹配re的子字符串(仅适用于 ARE) (?<=re) - 在某个位置上,如果以该位置结束的某个子串能够匹配re,则匹配正向后行断言(仅对 ARE) + 正向后行断言在这样的位置匹配:存在以该位置结束且匹配re的子字符串(仅适用于 ARE) (?<!re) - 在某个位置上,如果以该位置结束的任何子串都不能匹配re,则匹配负向后行断言(仅对 ARE) + 负向后行断言在这样的位置匹配:不存在任何以该位置结束且匹配re的子字符串(仅适用于 ARE) - Lookahead 和 lookbehind 约束不能包含反向引用 (参阅),并且其中的所有圆括号 都被认为是非捕获的。 + 先行和后行约束不能包含反向引用(参见),其中的所有圆括号都视为非捕获圆括号。 @@ -5787,11 +5946,11 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) 方括号表达式 - 方括号表达式是一个包围在[]中的字符列表。它通常匹配列表中的任意单个字符(但见下文)。 如果列表以^开头,它匹配任意单个在该列表参与部分中的字符。如果该列表中两个字符用-隔开, 那它就是那两个字符(包括在内)之间的所有字符范围的缩写,例如,在ASCII[0-9]匹配任何十进制数字。两个范围共享一个端点是非法的,例如,a-c-e。范围与字符集关系密切, 可移植的程序应该避免依靠它们。 + 方括号表达式是用[]括起来的字符列表。通常,它匹配列表中的任意单个字符(但请参见下文)。如果列表以^开头,则匹配任意在列表剩余部分中的单个字符。如果列表中的两个字符用-分隔,则表示排序序列中这两个字符之间的完整字符范围(包含两个端点);例如,ASCII中的[0-9]匹配任意十进制数字。两个范围共享一个端点是不合法的,例如a-c-e。范围高度依赖排序序列,因此可移植程序应避免依赖它们。 - 想在列表中包含文本],可以让它做列表的首字符(如果使用了^,需要放在其后)。 想在列表中包含文本-,可以让它做列表的首字符或者尾字符,或者一个范围的第二个端点。 想在列表中把文本-当做范围的起点, 把它用[..]包围起来,这样它就成为一个排序元素(见下文)。 除了这些字符本身、一些用[的组合(见下段)以及转义(只在 ARE 中有效)以外,所有其它特殊字符 在方括号表达式里都失去它们的特殊含义。特别是,在 ERE 和 BRE 规则下\不是特殊的, 但在 ARE 里,它是特殊的(引入一个转义)。 + 想在列表中包含字面字符],可以让它做列表的首字符(如果使用了^,需要放在其后)。 想在列表中包含字面字符-,可以让它做列表的首字符或者尾字符,或者一个范围的第二个端点。 想在列表中把字面字符-当做范围的起点, 把它用[..]包围起来,这样它就成为一个排序元素(见下文)。 除了这些字符本身、一些用[的组合(见下段)以及转义(只在 ARE 中有效)以外,所有其它特殊字符 在方括号表达式里都失去它们的特殊含义。特别是,在 ERE 和 BRE 规则下\不是特殊的, 但在 ARE 里,它是特殊的(引入一个转义)。 @@ -5806,30 +5965,11 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 在方括号表达式里,包围在[==]里的排序元素是一个等价类, 代表等效于那一个的所有排序元素的字符序列,包括它本身(如果没有其它等效排序元素,那么就好象封装定界符是[..])。例如,如果o^是一个等价类的成员,那么[[=o=]][[=^=]][o^]都是同义的。一个等价类不能是一个范围的端点。 + 在方括号表达式里,包围在[==]里的排序元素是一个等价类, 代表等效于那一个的所有排序元素的字符序列,包括它本身(如果没有其它等效排序元素,那么就好像封装定界符是[..])。例如,如果o^是一个等价类的成员,那么[[=o=]][[=^=]][o^]都是同义的。一个等价类不能是一个范围的端点。 - 在方括号表达式里,在[::]里面封装的字符类的名字代表属于该类的所有字符的列表。 - 字符类不能作为范围的端点使用。 - POSIX标准定义了这些字符类的名称: - alnum (字符和数字), - alpha (字符), - blank (空格和制表符tab), - cntrl (控制符), - digit (数位数), - graph (空格除外可打印字符), - lower (小写字母), - print (包含空格可打印字符), - punct (标点符号), - space (空白), - upper (大写字母), - 和 xdigit (十六进制数). - 对于7位ASCII字符集中的字符来说,这些标准字符类的行为在不同平台上一般是一致的。 - 一个给定的非 ASCII 字符是否被认为属于这些类别中的一个,取决于正则表达式函数或操作符所使用的排序规则(见),或者在默认情况下取决于数据库的LC_CTYPE locale 设置(见)。 - 非ASCII字符的分类在不同的平台上会有不同的分类,即使是在类似命名的locale中也是如此。 - (但C locale从不认为任何非ASCII字符属于上述任何一类)。 - 除了这些标准字符类之外,PostgreSQL定义了word字符类,等同于alnum加上下划线(_), 以及ascii字符类,它完全包含7位ASCII字符集。 + 在方括号表达式中,用[::]括起来的字符类名称表示属于该类的所有字符。字符类不能作为范围的端点。POSIX标准定义了以下字符类名称:alnum(字母和数字)、alpha(字母)、blank(空格和制表符)、cntrl(控制字符)、digit(数字)、graph(空格以外的可打印字符)、lower(小写字母)、print(包括空格的可打印字符)、punct(标点符号)、space(任意空白字符)、upper(大写字母)和xdigit(十六进制数字)。对于 7 位 ASCII 字符集中的字符,这些标准字符类在各平台上的行为通常一致。给定的非 ASCII 字符是否属于其中某个类,取决于正则表达式函数或操作符使用的排序规则(参见),默认则取决于数据库的LC_CTYPE区域设置(参见)。即使区域设置名称相似,非 ASCII 字符的分类也可能因平台而异。(但C区域设置不会将任何非 ASCII 字符归入这些类。)除了这些标准字符类,PostgreSQL还定义了word字符类,即alnum加上下划线(_),以及恰好包含 7 位 ASCII 字符集的ascii字符类。 @@ -5846,11 +5986,11 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) 正则表达式转义 - 转义是以\开头,后面跟着一个字母数字字符的特殊序列。 转义有好几种变体:字符输入转义、字符类简写转义、约束转义以及反向引用。在 ARE 里, 如果一个\后面跟着一个字母数字,但是并未组成一个合法的转义, 那么它是非法的。在 ERE 中没有转义:在方括号表达式之外,一个后面跟着字母数字字符的\只是表示该字符是一个普通的字符,而且在一个方括号表达式里,\是一个普通的字符(后者实际上在 ERE 和 ARE 不兼容)。 + 转义是以\开头,后面跟着一个字母或数字字符的特殊序列。 转义有好几种变体:字符输入转义、字符类简写转义、约束转义以及反向引用。在 ARE 里, 如果一个\后面跟着一个字母或数字,但是并未组成一个合法的转义, 那么它是非法的。在 ERE 中没有转义:在方括号表达式之外,一个后面跟着字母或数字字符的\只是表示该字符是一个普通的字符,而且在一个方括号表达式里,\是一个普通的字符(后者是 ERE 与 ARE 之间唯一的实际不兼容之处)。 - 字符输入转义用于便于我们在 RE 中声明那些不可打印的或其他习惯的字符。它们显示在中。 + 字符输入转义便于在 RE 中指定不可打印或其他不便输入的字符,见 @@ -5858,13 +5998,13 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 约束转义是一个约束,如果满足特定的条件,它匹配该空串。它们显示在中。 + 约束转义是以转义形式书写的约束,在满足特定条件时匹配空字符串,见 - 反向引用\n)匹配数字\n指定的被前面的圆括号子表达式匹配的同一个串 (参阅)。 + 反向引用\n)匹配前面编号为n的圆括号子表达式所匹配的同一字符串 (参阅)。 例如, ([bc])\1匹配bb或者cc, 但是不匹配bc或者cb。 - RE 中子表达式必须完全在反向引用前面。子表达式以它们的先导圆括号的顺序编号。 + RE 中子表达式必须完全在反向引用前面。子表达式以它们的左圆括号的顺序编号。 非捕获圆括号并不定义子表达式。 反向引用仅考虑被引用的子表达式匹配的字符串字符,而不考虑其中包含的任何约束。 例如,(^\d)\1 将匹配 22。 @@ -5907,7 +6047,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) \e - 排序序列名为ESC的字符,如果无法做到该字符为八进制值 033 + 排序序列名称为ESC的字符;若不存在这样的字符,则使用八进制值为033的字符 @@ -5917,7 +6057,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) \n - 新行,和 C 中一样 + 换行符,与 C 中相同 @@ -6041,7 +6181,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 类-缩写转义也适用于括号表达式,尽管上面显示的定义在该上下文中在语法上并不完全有效。 + 字符类简写转义也适用于括号表达式,尽管上面显示的定义在该上下文中在语法上并不完全有效。 例如,[a-c\d] 等同于 [a-c[:digit:]] @@ -6082,7 +6222,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) \Y - 只在一个词的不是开头或末尾的点上匹配 + 只在不属于单词开头或末尾的位置匹配 @@ -6094,7 +6234,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 一个词被定义成在上面[[:<:]][[:>:]]中的声明。在方括号表达式里,约束转义是非法的。 + 单词的定义与上文[[:<:]][[:>:]]的说明相同。方括号表达式中不允许使用约束转义。 @@ -6114,12 +6254,12 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) \m - (其中m是一个非零位)一个到第m个子表达式的反向引用 + (其中m是一个非零数字)一个到第m个子表达式的反向引用 \mnn - (其中m是一个非零位,并且nn是一些更多的位,并且十六进制值mnn不超过目前能看到的封闭捕获圆括号的数目)一个到第mnn个子表达式的反向引用 + (其中m是一个非零数字,并且nn是后续的若干数字,并且十进制值mnn不大于此前已出现的捕获右圆括号数)一个到第mnn个子表达式的反向引用 @@ -6128,7 +6268,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 在八进制字符输入转义和反向引用之间有一个历史继承的歧义存在,这个歧义是 通过下面的启发式规则解决的,像上面描述地那样。前导零总是表示这是一个八进制转义。 而单个非零数字,如果没有跟着任何其它位,那么总是被认为反向引用。 一个多位的非零开头的序列也被认为是反向引用,只要它出现在合适的子表达式后面 (也就是说,在反向引用的合法范围中的数),否则就被认为是一个八进制。 + 八进制字符输入转义与反向引用之间存在固有歧义,按上文提到的启发式规则解决:前导零始终表示八进制转义。单个非零数字,如果后面没有其他数字,始终视为反向引用。不以零开头的多位数字序列,如果前面已有相应的子表达式(即该数字在反向引用的合法范围内),则视为反向引用,否则视为八进制转义。 @@ -6142,11 +6282,11 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 如果一个 RE 以***:开头,那么剩下的 RE 都被当作 ARE(这在PostgreSQL中通常是无效的,因为 RE 被假定为 ARE,但是如果 ERE 或 BRE 模式通过flags参数被指定为一个正则表达式函数时,它确实能产生效果)。如果一个 RE 以***=开头, 那么剩下的 RE 被当作一个文本串,所有的字符都被认为是一个普通字符。 + RE 可以以两种特殊的引导前缀之一开头。如果 RE 以***:开头,余下部分就被视为 ARE。(这在PostgreSQL中通常没有影响,因为 RE 默认被视为 ARE;但如果通过正则表达式函数的flags参数指定了 ERE 或 BRE 模式,它就会产生影响。)如果 RE 以***=开头,余下部分就作为按字面解释的字符串处理,所有字符都视为普通字符。 - 一个 ARE 可以以嵌入选项开头:一个序列(?xyz)(这里的xyz是一个或多个字母字符)声明影响剩余 RE 的选项。 这些选项覆盖任何前面判断的选项 — 特别地,它们可以覆盖一个正则表达式操作符隐含的大小写敏感的行为,或者覆盖flags参数中的正则表达式函数。可用的选项字母在中显示。注意这些同样的选项字母也被用在正则表达式函数的flags参数中。 + 一个 ARE 可以以嵌入选项开头:一个序列(?xyz)(这里的xyz是一个或多个字母字符)声明影响剩余 RE 的选项。 这些选项覆盖任何先前确定的选项 — 特别地,它们可以覆盖一个正则表达式操作符隐含的大小写敏感的行为,或者覆盖正则表达式函数的flags参数所指定的选项。可用的选项字母在中显示。注意这些同样的选项字母也被用在正则表达式函数的flags参数中。
@@ -6191,32 +6331,32 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) n - 新行敏感的匹配(见 + 换行敏感的匹配(见 p - 部分新行敏感的匹配(见 + 部分换行敏感的匹配(见 q - RE的剩余部分是一个文字(quoted)串,全部是普通字符 + RE 的剩余部分按字面(加引号)解释,所有字符都视为普通字符 s - 非新行敏感的匹配(默认) + 非换行敏感的匹配(默认) t - 紧语法(默认,见下文) + 紧凑语法(默认;见下文) w - 逆部分新行敏感(怪异)的匹配(见 + 逆部分换行敏感(怪异)的匹配(见 @@ -6228,16 +6368,16 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2)
- 嵌入选项在)终止序列时发生作用。它们只在 ARE 的开始处起作用 (在任何可能存在的***:控制器后面)。 + 嵌入选项从结束该序列的)处开始生效。它们只能出现在 ARE 的开头(如果存在***:引导前缀,则位于该前缀之后)。 - 除了通常的()RE 语法(这种情况下所有字符都有效), 还有一种扩展语法,可以通过声明嵌入的x选项获得。在扩展语法里,RE 中的空白字符被忽略,就像那些在#和其后的新行(或 RE 的末尾)之间的字符一样。这样就允许我们给一个复杂的 RE 分段和注释。不过这个基本规则有三种例外: + 除了通常的紧凑 RE 语法(其中所有字符都有意义)之外,还有一种扩展语法,可以通过指定嵌入的x选项来使用。在扩展语法中,RE 中的空白字符会被忽略,同样被忽略的还有#与其后的换行符(或 RE 末尾)之间的所有字符。这使得复杂的 RE 可以分段并添加注释。此基本规则有三个例外: - 空白字符或前置了\#将被保留 + 空白字符或 # 的前面若有 \,该字符就会被保留。 @@ -6252,14 +6392,14 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 为了这个目的,空白是空格、制表符、新行以及任何属于 whitespace 字符类的字符。 + 在这里,空白字符包括空格、制表符、换行符,以及属于space字符类的任何字符。 - 最后,在 ARE 里,方括号表达式外面,序列(?#ttt)(其中ttt是任意不包含一个))的文本)是一个注释, 它被完全忽略。同样,这样的东西是不允许出现在多字符符号的字符中间的,例如 (?:。这种注释更像是一种历史产物而不是一种有用的设施,并且它们的使用已经被废弃;请使用扩展语法来替代。 + 最后,在 ARE 里,方括号表达式外面,序列(?#ttt)(其中ttt是任意不包含一个)的文本)是一个注释, 它被完全忽略。同样,这样的东西是不允许出现在多字符符号的字符中间的,例如 (?:。这种注释更像是一种历史产物而不是一种有用的设施,并且它们的使用已经被废弃;请使用扩展语法来替代。
- 如果声明了一个初始的***=控制器,那么所有这些元语法扩展都不能使用,因为这样表示把用户输入当作一个文字串而不是 RE 对待。 + 如果指定了开头的***=引导前缀,那么这些元语法扩展都不能使用,因为这表示把用户输入作为按字面解释的字符串,而非 RE 处理。 @@ -6276,7 +6416,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 大多数原子以及所有约束,都没有贪婪属性(因为它们毕竟无法匹配个数变化的文本)。 + 大多数原子以及所有约束,都没有贪婪属性(因为它们毕竟无法匹配长度不定的文本)。 @@ -6328,7 +6468,7 @@ SELECT SUBSTRING('XY1234Z', 'Y*?([0-9]{1,3})');
- 简而言之,如果一个 RE 同时包含贪婪和非贪婪的子表达式,那么总的匹配长度要么是尽可能长,要么是尽可能短,这取决于给整个 RE 赋予的属性。给子表达式赋予的属性只影响在这个匹配里,各个子表达式之间相互允许吃掉的多少。 + 简而言之,如果一个 RE 同时包含贪婪和非贪婪的子表达式,那么总的匹配长度要么是尽可能长,要么是尽可能短,这取决于给整个 RE 赋予的属性。给子表达式赋予的属性只影响在这个匹配里,各个子表达式相对于其他子表达式能吃掉多少内容。 @@ -6362,23 +6502,23 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 如果声明了大小写无关的匹配,那么效果就好像所有大小写区别在字母表中消失了。如果在多个情况中一个字母以一个普通字符的形式出现在方括号表达式外面,那么它实际上被转换成 一个包含大小写的方括号表达式,也就是说,x 变成 [xX]。 如果它出现在一个方括号表达式里面,那么它的所有大小写的同族都被加入 方括号表达式中,也就是说,x变成[xX]。当它出现在一个方括号表达式内时,它的所有大小写副本都被加入到方括号表达式中,例如, [x]会变成[xX],而[^x]会变成[^xX]。 + 如果指定不区分大小写的匹配,其效果近似于字母表中的所有大小写差别都消失了。当存在大小写形式的字母作为普通字符出现在方括号表达式之外时,实际上会转换为包含其大小写形式的方括号表达式,例如x变成[xX]。当它出现在方括号表达式内部时,其所有大小写形式都会加入该表达式,例如[x]变成[xX][^x]变成[^xX] 如果指定了换行敏感的匹配,.和使用^的方括号表达式 将永远不会匹配换行字符(这样,匹配就不会跨越行,除非 RE 显式地包含了换行)并且^$除了分别匹配串开头和结尾之外,还将分别匹配换行后面和前面的空串。 但是 ARE 转义\A\Z仍然匹配串的开头和结尾。 - 此外,字符类缩写符\D\W将匹配换行,而无论这种模式如何。 + 此外,字符类简写\D\W将匹配换行,而无论这种模式如何。 (在PostgreSQL 14之前,它们在换行敏感模式下不匹配换行。 写入[^[:digit:]][^[:word:]]以获取旧的行为。) - 如果指定了部分新行敏感的匹配,那么它影响.和方括号表达式, 这个时候和新行敏感的匹配一样,但是不影响^$。 + 如果指定了部分换行敏感的匹配,那么它影响.和方括号表达式, 这个时候和换行敏感的匹配一样,但是不影响^$ - 如果指定了逆新行敏感匹配,那么它影响^$,其作用和在新行敏感的匹配里一样,但是不影响.和方括号表达式。这个并不是很有用,只是为了满足对称性而提供的。 + 如果指定了逆部分换行敏感匹配,那么它影响^$,其作用和在换行敏感的匹配里一样,但是不影响.和方括号表达式。这个并不是很有用,只是为了满足对称性而提供的。 @@ -6391,11 +6531,11 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}');
- ARE 实际上和 POSIX ERE 不兼容的唯一的特性是在方括号表达式里\并不失去它特殊的含义。所有其它 ARE 特性都使用在 POSIX ERE 里面是非法或者是未定义、未声明效果的语法;指示器的***就是在 POSIX 的 BRE 和 ERE 之外的语法。 + ARE 与 POSIX ERE 实际不兼容的唯一特性是:\在方括号表达式中不会失去特殊含义。其他所有 ARE 特性所使用的语法,在 POSIX ERE 中都是非法的,或其效果未定义或未指定;引导前缀的***语法同样不属于 POSIX 的 BRE 或 ERE 语法。 - 许多 ARE 扩展都是从 Perl 那里借来的(但是有些被做了修改来清理它们),以及一些 Perl 里没有出现的扩展。要注意的不兼容性包括\b\B、对结尾的新行缺乏特别的处理、对那些被新行敏感匹配的东西附加的补齐方括号表达式、在 lookahead/lookbehind 约束里对圆括号和反向引用的限制以及最长/最短 匹配(而不是第一匹配)的语义。 + 许多 ARE 扩展借鉴自 Perl,但其中一些经过了整理和修改,也未实现少数 Perl 扩展。需要注意的不兼容之处包括\b\B、不对末尾换行符作特殊处理、取反的方括号表达式也受换行敏感匹配影响、先行和后行约束中对圆括号及反向引用的限制,以及采用最长或最短匹配而非首次匹配的语义。 @@ -6404,7 +6544,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 基本正则表达式 - BREs 在几个方面和 ERE 不太一样。在 BRE 中,|+?都是普通字符并且没有与它们功能等价的东西。范围的定界符是\{\}, 因为 {}本身是普通字符。嵌套的子表达式的圆括号是\(\),因为()自身是普通字符。除非在 RE 开头或者是圆括号子表达式开头,^都是一个普通字符。 除非在 RE 结尾或者是圆括号子表达式的结尾,$是一个普通字符。如果*出现在 RE 开头或者是圆括号封装的子表达式开头 (前面可能有^),那么它是个普通字符。最后,可以用单数字的反向引用,\<\>分别是[[:<:]][[:>:]]的同义词;在 BRE 中没有其它可用的转义。 + BRE 在几个方面和 ERE 不太一样。在 BRE 中,|+?都是普通字符并且没有与它们功能等价的东西。范围的定界符是\{\},而{}本身是普通字符。嵌套的子表达式的圆括号是\(\),而()自身是普通字符。除非在 RE 开头或者是圆括号子表达式开头,^都是一个普通字符。 除非在 RE 结尾或者是圆括号子表达式的结尾,$是一个普通字符。如果*出现在 RE 开头或者是圆括号封装的子表达式开头 (前面可能有^),那么它是个普通字符。最后,可以用单数字的反向引用,\<\>分别是[[:<:]][[:>:]]的同义词;在 BRE 中没有其它可用的转义。 @@ -6460,7 +6600,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); SQL标准 - PostgreSQL + PostgreSQL @@ -6517,16 +6657,13 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 使用\p{UnicodeProperty}或其反义\P{UnicodeProperty}来定义XQuery字符类元素是不被支持的。 + 使用\p{UnicodeProperty}或其取反形式\P{UnicodeProperty}来定义XQuery字符类元素是不被支持的。 - POSIX解释字符类,如\w - (参见) - 根据当前区域设置(你可以通过将COLLATE子句附加到操作符或函数上来控制)。 - XQuery通过参考Unicode字符属性来指定这些类别,因此只有遵循Unicode规则的区域设置才能获得等效行为。 + POSIX 根据当前区域设置解释\w等字符类(参见);你可以通过为操作符或函数附加COLLATE子句来控制该区域设置。XQuery 根据 Unicode 字符属性定义这些类,因此只有使用遵循 Unicode 规则的区域设置时,才能得到等效行为。 @@ -6539,10 +6676,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 在描述的字符输入转义中 - 中, - XQuery仅支持\n\r, - 和\t。 + 在描述的字符输入转义中,XQuery 仅支持 \n\r\t @@ -6554,7 +6688,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - XQuery没有前瞻或后顾约束,也没有在中描述的任何约束转义。 + XQuery没有先行或后行约束,也没有在中描述的任何约束转义。 @@ -6574,7 +6708,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); XQuery的s(允许点匹配换行符) 和m(允许^ - 和$匹配换行符)标志提供 + 和$在换行处匹配)标志提供 与POSIX的npw标志相同的行为,但它们 匹配POSIX的sm标志的行为。 @@ -6605,11 +6739,11 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 数据类型格式化函数 - formatting + 格式化 - PostgreSQL格式化函数提供一套强大的工具用于把各种数据类型 (日期/时间、整数、浮点、数字) 转换成格式化的字符串以及反过来从格式化的字符串转换成 指定的数据类型。列出了这些函数。这些函数都遵循一个公共的调用规范: 第一个参数是待格式化的值,而第二个是一个定义输出或输入格式的模板。 + PostgreSQL格式化函数提供一套强大的工具用于把各种数据类型 (日期/时间、整数、浮点数、数值) 转换成格式化的字符串以及反过来从格式化的字符串转换成 指定的数据类型。列出了这些函数。这些函数都遵循一个公共的调用规范: 第一个参数是待格式化的值,而第二个是一个定义输出或输入格式的模板。 @@ -6660,7 +6794,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); text - 根据给定的格式将间隔转换为字符串。 + 根据给定的格式将时间间隔转换为字符串。 to_char(interval '15h 2m 12s', 'HH24:MI:SS') @@ -6716,7 +6850,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); numeric - 根据给定的格式将字符串转换为数字。 + 根据给定的格式将字符串转换为数值。 to_number('12,454.8-', '99G999D9S') @@ -6757,7 +6891,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 展示了可以用于格式化日期和时间值的模版。 + 展示了可以用于格式化日期和时间值的模板模式。
@@ -6840,24 +6974,24 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); SSSS, SSSSS - 午夜后的秒 (0–86399) + 自午夜起的秒数 (0–86399) AM, am, - PM or pm - 正午指示器(不带句号) + PMpm + 上午/下午标记(不带句点) A.M., a.m., - P.M. or p.m. - 正午指示器(带句号) + P.M.p.m. + 上午/下午标记(带句点) Y,YYY - 带逗号的年(4 位或者更多位) with comma + 带逗号的年(4 位或者更多位) @@ -6914,17 +7048,17 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); MONTH - 全大写形式的月名(空格补齐到 9 字符) + 大写的月份全称(空格补齐到 9 字符) Month - 全首字母大写形式的月名(空格补齐到 9 字符) + 首字母大写的月份全称(空格补齐到 9 字符) month - 全小写形式的月名(空格补齐到 9 字符) + 小写的月份全称(空格补齐到 9 字符) @@ -6949,72 +7083,72 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); DAY - 全大写形式的日名(空格补齐到 9 字符) + 大写的星期全称(空格补齐到 9 字符) Day - 全首字母大写形式的日名(空格补齐到 9 字符) + 首字母大写的星期全称(空格补齐到 9 字符) day - 全小写形式的日名(空格补齐到 9 字符) + 小写的星期全称(空格补齐到 9 字符) DY - 简写的大写形式的日名(英语 3 字符,本地化长度可变) + 大写的星期简称(英语 3 字符,本地化长度可变) Dy - 简写的首字母大写形式的日名(英语 3 字符,本地化长度可变) + 首字母大写的星期简称(英语 3 字符,本地化长度可变) dy - 简写的小写形式的日名(英语 3 字符,本地化长度可变) + 小写的星期简称(英语 3 字符,本地化长度可变) DDD - 一年中的日(001–366) + 年内日序数(001–366) IDDD - ISO 8601 周编号方式的年中的日 (001–371; 年的第 1 日时第一个 ISO 周的周一) + ISO 8601 周编号方式的年中的日 (001–371; 年的第 1 日是第一个 ISO 周的周一) DD - 月中的日 (01–31) + 月内日序数 (01–31) D - 周中的日,周日 (1) 到周六 (7) + 星期几,周日 (1) 到周六 (7) ID - 周中的 ISO 8601 日,周一 (1) 到周日 (7) + ISO 8601 星期几,周一 (1) 到周日 (7) W - 月中的周 (1–5) (第一周从该月的第一天开始) + 月内周序数 (1–5) (第一周从该月的第一天开始) WW - 年中的周数 (1–53) (第一周从该年的第一天开始) + 年中的周编号 (1–53) (第一周从该年的第一天开始) IW - ISO 8601 周编号方式的年中的周数 (01–53; 新的一年的第一个周四在第一周) + ISO 8601 周编号方式的年中的周编号 (01–53; 新的一年的第一个周四在第一周) @@ -7044,12 +7178,12 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); TZ - 大写形式的时区缩写(仅在to_char中支持) + 大写形式的时区缩写 tz - 小写形式的时区缩写(仅在to_char中支持) + 小写形式的时区缩写 @@ -7064,24 +7198,24 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); OF - 从UTC开始的时区偏移(仅在to_char中支持) + 相对于 UTC 的时区偏移(HHHH:MM
- 修饰语可以被应用于模板模式来修改它们的行为。例如,FMMonth就是带着FM修饰语的Month模式。展示了可用于日期/时间格式化的修饰语模式。 + 修饰符可以被应用于模板模式来修改它们的行为。例如,FMMonth就是带着FM修饰符的Month模式。展示了可用于日期/时间格式化的修饰符模式。 - 用于日期/时间格式化的模板模式修饰语 + 用于日期/时间格式化的模板模式修饰符 - 修饰语 + 修饰符 描述 示例 @@ -7089,37 +7223,37 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - FM prefix + FM 前缀 填充模式(抑制前导零和填充的空格) FMMonth - TH suffix + TH 后缀 大写形式的序数后缀 - DDTH, e.g., 12TH + DDTH,例如, 12TH - th suffix + th 后缀 小写形式的序数后缀 - DDth, e.g., 12th + DDth,例如, 12th - FX prefix - 固定的格式化全局选项(见使用须知) + FX 前缀 + 固定格式全局选项(见使用须知) FX Month DD Day - TM prefix - 翻译模式(基于使用本地化的日和月名) + TM 前缀 + 翻译模式(基于使用本地化的星期名和月份名) TMMonth - SP suffix + SP 后缀 拼写模式(未实现) DDSP @@ -7136,8 +7270,8 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); FM抑制了在模式输出中添加前导零和尾随空格的行为,这些前导零和尾随空格 本来会被添加以使输出成为固定宽度。在PostgreSQL中, - FM仅修改下一个规范,而在Oracle中FM影响所有后续 - 规范,并且重复的FM修饰符切换填充模式的开启和关闭。 + FM仅修改下一个格式说明,而在Oracle中FM影响所有后续 + 格式说明,并且重复的FM修饰符切换填充模式的开启和关闭。 @@ -7195,10 +7329,10 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 一个TZH模板模式可以匹配有符号数。 - 没有FX选项,减号可能会有歧义,并且可能被解释为分隔符。 - 此歧义解决如下:如果模板字符串中TZH之前的分隔符数量少于输入字符串中减号之前的分隔符数量, - 则减号被解释为TZH的一部分。 - 否则,减号被视为值之间的分隔符。 + 没有FX选项,负号可能会有歧义,并且可能被解释为分隔符。 + 此歧义解决如下:如果模板字符串中TZH之前的分隔符数量少于输入字符串中负号之前的分隔符数量, + 则负号被解释为TZH的一部分。 + 否则,负号被视为值之间的分隔符。 例如,to_timestamp('2000 -10', 'YYYY TZH')匹配 -10TZH,但 to_timestamp('2000 -10', 'YYYY  TZH') @@ -7209,12 +7343,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 普通文本允许在to_char模板中,并且将被直接输出。您可以将子字符串放在双引号中, - 以强制将其解释为文字文本,即使它包含模板模式。例如,在'"Hello Year "YYYY'中, - YYYY将被年份数据替换,但Year中的单个Y不会被替换。 - 在to_dateto_numberto_timestamp中, - 文本和双引号字符串会导致跳过字符串中包含的字符数;例如"XX"跳过两个输入字符 - (无论它们是否为XX)。 + 普通文本可以出现在to_char模板中,并会按字面输出。可以用双引号括起子串,使其即使包含模式关键字也强制按字面文本解释。例如,在'"Hello Year "YYYY'中,YYYY会被年份数据替换,但Year中单独的Y不会被替换。在to_dateto_numberto_timestamp中,字面文本和双引号字符串会跳过与该字符串所含字符数相同数量的输入字符;例如,"XX"跳过两个输入字符(无论它们是否为XX)。 @@ -7233,7 +7362,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 如果您想在输出中使用双引号,必须在其前面加上反斜杠,例如'\"YYYY Month\"' - 反斜杠在双引号之外不起特殊作用。在双引号字符串内部,反斜杠会使下一个字符被直接解释,无论是什么(但除非下一个字符是双引号或另一个反斜杠,否则没有特殊效果)。 + 反斜杠在双引号之外不起特殊作用。在双引号字符串内部,反斜杠会使下一个字符被按字面解释,无论是什么(但除非下一个字符是双引号或另一个反斜杠,否则没有特殊效果)。 @@ -7296,14 +7425,14 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 年份、周数和星期几:例如to_date('2006-42-4', 'IYYY-IW-ID') + 年份、周编号和星期几:例如to_date('2006-42-4', 'IYYY-IW-ID') 返回日期2006-10-19。 如果省略星期几,则假定为1(星期一)。 - 年份和年内天数:例如to_date('2006-291', 'IYYY-IDDD')也返回2006-10-19。 + 年份和年内日序数:例如to_date('2006-291', 'IYYY-IDDD')也返回2006-10-19 @@ -7311,14 +7440,14 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 尝试使用ISO 8601周编号字段和公历日期字段的混合输入日期是荒谬的,并将导致错误。 - 在ISO 8601周编号年的背景下,月份日期的概念没有意义。 + 在ISO 8601周编号年的背景下,月份月内日序数的概念没有意义。 在公历年的背景下,ISO周没有意义。 - 当to_date拒绝混合使用公历和ISO周编号日期字段时, - to_char不会,因为输出格式规范如YYYY-MM-DD (IYYY-IDDD)可能很有用。 + 虽然to_date会拒绝混合使用公历和ISO周编号日期字段, + 但to_char不会,因为输出格式规范如YYYY-MM-DD (IYYY-IDDD)可能很有用。 但要避免编写类似IYYY-MM-DD的内容;那会在年初附近产生令人惊讶的结果。 (有关更多信息,请参见。) @@ -7337,7 +7466,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 这是一个更复杂的示例: to_timestamp('15:12:02.020.001230', 'HH24:MI:SS.MS.US') - 是15小时,12分钟和2秒 + 20毫秒 + 1230微秒 = 2.021230秒。 + 为15小时12分钟,秒数为2秒 + 20毫秒 + 1230微秒 = 2.021230秒。 @@ -7345,7 +7474,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); to_char(..., 'ID')的星期几编号与extract(isodow from ...)函数匹配, - 但to_char(..., 'D')的不匹配extract(dow from ...)的星期编号。 + 但to_char(..., 'D')的不匹配extract(dow from ...)的星期几编号。 @@ -7362,12 +7491,12 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 展示了可以用于格式化数字值的模版模式。 + 展示了可以用于格式化数值的模板模式。
- 用于数字格式化的模板模式 + 用于数值格式化的模板模式 @@ -7380,21 +7509,21 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 9 - 数位(如果无意义可以被删除) + 数位(非有效位可以被省略) 0 - 数位(即便没有意义也不会被删除) + 数位(即便是非有效位也不会被省略) - . (period) + .(句点) 小数点 - , (comma) + ,(逗号) 分组(千)分隔符 @@ -7405,22 +7534,22 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); S - 带符号的数字(使用区域) + 紧贴数值的正负号(使用区域设置) L - 货币符号(使用区域) + 货币符号(使用区域设置) D - 小数点(使用区域) + 小数点(使用区域设置) G - 分组分隔符(使用区域) + 分组分隔符(使用区域设置) @@ -7439,12 +7568,12 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - RN - 罗马数字(输入在 1 和 3999 之间) + RNrn + 罗马数字(数值在 1 和 3999 之间) - TH or th + THth 序数后缀 @@ -7462,7 +7591,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}');
- 数字格式化的使用注意事项: + 数值格式化的使用注意事项: @@ -7478,14 +7607,14 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 如果格式提供的小数位数少于被格式化的数字,则to_char()将会将数字四舍五入到指定的小数位数。 + 如果格式指定的小数位数少于被格式化数值的小数位数,to_char()会将该数值舍入到指定的小数位数。 - 模式字符SLDG表示当前区域设置定义的符号、货币符号、小数点和千位分隔符字符 + 模式字符SLDG表示当前区域设置定义的正负号、货币符号、小数点和千位分隔符字符 (参见)。模式字符句点和逗号表示这些确切字符,具有小数点和千位分隔符的含义,不受区域设置影响。 @@ -7494,15 +7623,14 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 如果在to_char()的模式中没有明确指定符号,将为符号保留一列,并将其锚定到(出现在)数字的左侧。 - 如果S出现在一些9的左侧,它也将锚定到数字。 + 如果to_char()的模式中没有明确指定正负号的位置,就会为正负号保留一列,并使其紧贴数值(紧靠数值左侧)。如果S紧邻若干个9的左侧,它同样会紧贴数值。 - 使用SGPLMI格式化的符号不与数字绑定; + 使用SGPLMI格式化的正负号不紧贴数值; 例如,to_char(-12, 'MI9999')会产生'-  12', 但to_char(-12, 'S9999')会产生'  -12'。 (Oracle实现不允许在9之前使用MI,而是要求9MI之前。) @@ -7529,7 +7657,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); to_number函数中,如果使用非数据模板模式,如LTH, - 则会跳过相应数量的输入字符,无论它们是否与模板模式匹配,除非它们是数据字符(即数字、符号、小数点或逗号)。 + 则会跳过相应数量的输入字符,无论它们是否与模板模式匹配,除非它们是数据字符(即数字、正负号、小数点或逗号)。 例如,TH会跳过两个非数据字符。 @@ -7540,7 +7668,8 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); Vto_char一起, 将输入值乘以10^n, 其中n是跟在V后面的数字位数。 - Vto_number一起以类似的方式除法。 + Vto_number一起以类似的方式进行除法。 + V可以视为输入或输出字符串中隐含小数点位置的标记。 to_charto_number不支持与小数点结合使用的V (例如,不允许使用99.9V99)。 @@ -7552,21 +7681,27 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); EEEE(科学计数法)不能与任何其他格式模式或修饰符结合使用,除了数字和小数点模式之外,必须位于格式字符串的末尾(例如,9.99EEEE是一个有效模式)。
+ + + + 在to_number()中,RN模式将标准形式的罗马数字转换为数值。输入不区分大小写,因此RNrn等效。RN不能与其他格式化模式或修饰符组合使用,唯一的例外是FM;该修饰符只适用于to_char(),在to_number()中会被忽略。 + +
- 某些修饰语可以被应用到任何模板来改变其行为。例如,FM99.99是带有FM修饰语的99.99模式。中展示了用于数字格式化模式修饰语。 + 某些修饰符可以被应用到任何模板来改变其行为。例如,FM99.99是带有FM修饰符的99.99模式。中展示了用于数值格式化的模式修饰符。 - 用于数字格式化的模板模式修饰语 + 用于数值格式化的模板模式修饰符 - 修饰语 + 修饰符 描述 示例 @@ -7574,19 +7709,19 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - FM prefix - 填充模式(抑制拖尾零和填充的空白) + FM 前缀 + 填充模式(抑制尾随零和填充的空白) FM99.99 - TH suffix + TH 后缀 大写序数后缀 999TH - th suffix + th 后缀 小写序数后缀 999th @@ -7619,6 +7754,13 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 'Tuesday, 6  05:39:18' + to_char(current_timestamp AT TIME ZONE + 'UTC', 'YYYY-MM-DD"T"HH24:MI:SS"Z"') + '2022-12-06T05:39:18Z', + ISO 8601 扩展格式 + + + to_char(-0.1, '99.99') '  -.10' @@ -7770,10 +7912,10 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 时间/日期函数和操作符 + 日期/时间函数和操作符 - 展示了可用于处理日期/时间值的函数,其细节在随后的小节中描述。演示了基本算术操作符 (+*等)的行为。 而与格式化相关的函数,可以参考。你应该很熟悉中的日期/时间数据类型的背景知识。 + 展示了可用于处理日期/时间值的函数,其细节在随后的小节中描述。演示了基本算术操作符 (+*等)的行为。 而与格式化相关的函数,可以参考。你应当熟悉中的日期/时间数据类型的背景知识。 @@ -7859,7 +8001,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); interval - 添加时间间隔 + 将两个时间间隔相加 interval '1 day' + interval '1 hour' @@ -7901,7 +8043,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); interval - 取否一个时间间隔 + 对时间间隔取负 - interval '23 hours' @@ -7915,7 +8057,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); integer - 减去日期,生成经过的天数 + 将两个日期相减,得到相隔的天数 date '2001-10-01' - date '2001-09-28' @@ -7957,7 +8099,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); interval - 减去时间 + 将两个时间相减 time '05:00' - time '03:00' @@ -7999,7 +8141,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); interval - 减去时间间隔 + 将两个时间间隔相减 interval '1 day' - interval '1 hour' @@ -8013,12 +8155,12 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); interval - 减去时间戳(将24小时间隔转换为天数,类似于justify_hours() - 时间戳 '2001-09-29 03:00' - 时间戳 '2001-07-27 12:00' - 63 天 15:00:00 + timestamp '2001-09-29 03:00' - timestamp '2001-07-27 12:00' + 63 days 15:00:00 @@ -8028,7 +8170,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); interval - 将时间间隔乘以数量 + 将时间间隔乘以一个标量 interval '1 second' * 900 @@ -8050,7 +8192,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); interval - 用时间间隔除以数量 + 将时间间隔除以一个标量 interval '1 hour' / 1.5 @@ -8091,7 +8233,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); interval - 减去参数,生成一个使用年和月,而不是只用日的符号化的结果 + 将两个参数相减,生成一个使用年和月,而不是只用日的符号化的结果 age(timestamp '2001-04-10', timestamp '1957-06-13') @@ -8105,7 +8247,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); interval - 从 current_date 减去参数(在午夜) + 从current_date(午夜时刻)减去参数 age(timestamp '1957-06-13') @@ -8156,7 +8298,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); time with time zone - 一天中的当前时间;参见 + 一天中的当前时刻;参见 current_time @@ -8170,7 +8312,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); time with time zone - 一天中的当前时间;有限精度;参见 + 一天中的当前时刻,精度受限;参见 current_time(2) @@ -8187,7 +8329,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); timestamp with time zone - 当前日期和时间 (当前事务的开始);参见 + 当前日期和时间(当前事务开始时);参见 current_timestamp @@ -8201,7 +8343,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); timestamp with time zone - 当前日期和时间 (当前事务的开始);有限精度;参见 + 当前日期和时间(当前事务开始时),精度受限;参见 current_timestamp(0) @@ -8249,7 +8391,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); double precision - 获取时间戳字段 (等同于 extract);参见 + 获取时间戳子字段 (等同于 extract);参见 date_part('hour', timestamp '2001-02-16 20:38:40') @@ -8373,7 +8515,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); boolean - 测试有限日期(不是+/-无限) + 测试日期是否有限(不是正负无穷) isfinite(date '2001-02-16') @@ -8387,7 +8529,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); boolean - 测试有限时间戳(不是+/-无限) + 测试时间戳是否有限(不是正负无穷) isfinite(timestamp 'infinity') @@ -8401,7 +8543,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); boolean - 测试有限时间间隔 (当前总是为真) + 测试时间间隔是否有限(不是正负无穷) isfinite(interval '4 hours') @@ -8454,7 +8596,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); interval - 使用 justify_daysjustify_hours调整时间间隔; 通过额外的符号调整 + 使用 justify_daysjustify_hours调整时间间隔,并额外调整符号 justify_interval(interval '1 mon -1 hour') @@ -8471,7 +8613,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); time - 一天中当前时间;参见 + 一天中的当前时刻;参见 localtime @@ -8485,7 +8627,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); time - 一天中的当前时间,有限精度;参见 + 一天中的当前时刻,精度受限;参见 localtime(0) @@ -8502,7 +8644,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); timestamp - 当前日期和时间(当前事务的开始);参见 + 当前日期和时间(当前事务开始时);参见 localtimestamp @@ -8516,7 +8658,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); timestamp - 当前日期和时间(当前事务的开始);有限精度;参见 + 当前日期和时间(当前事务开始时),精度受限;参见 localtimestamp(2) @@ -8644,7 +8786,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); timestamp with time zone - 当前日期和时间(当前事务的开始);参见 + 当前日期和时间(当前事务开始时);参见 now() @@ -8661,7 +8803,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); timestamp with time zone - 当前日期和时间(当前语句的开始);参见 + 当前日期和时间(当前语句开始时);参见 statement_timestamp() @@ -8696,7 +8838,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); timestamp with time zone - 当前日期和时间(当前事务的开始);参见 + 当前日期和时间(当前事务开始时);参见 transaction_timestamp() @@ -8713,7 +8855,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); timestamp with time zone - 将Unix纪元转换为带时区的时间戳(从1970-01-01 00:00:00+00开始的秒) + 将 Unix 纪元时间(自 1970-01-01 00:00:00+00 起的秒数)转换为带时区的时间戳 to_timestamp(1284352323) @@ -8733,7 +8875,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); (start1, end1) OVERLAPS (start2, end2) (start1, length1) OVERLAPS (start2, length2) - 这个表达式在两个时间域(用它们的端点定义)重叠的时候得到真,当它们不重叠时得到假。端点可以用一对日期、时间或者时间戳来指定;或者是用一个后面跟着一个间隔的日期、时间或时间戳来指定。当一对值被提供时,起点或终点都可以被写在前面,OVERLAPS会自动地把较早的值作为起点。每一个时间段被认为是表示半开的间隔start <= time < end,除非startend相等,这种情况下它表示单个时间实例。例如这表示两个只有一个共同端点的时间段不重叠。 + 这个表达式在两个时间段(用它们的端点定义)重叠的时候得到真,当它们不重叠时得到假。端点可以用一对日期、时间或者时间戳来指定;或者是用一个后面跟着一个间隔的日期、时间或时间戳来指定。当一对值被提供时,起点或终点都可以被写在前面,OVERLAPS会自动地把较早的值作为起点。每一个时间段被认为是表示半开区间start <= time < end,除非startend相等,这种情况下它表示单个时刻。例如这表示两个只有一个共同端点的时间段不重叠。 @@ -8752,16 +8894,19 @@ SELECT (DATE '2001-10-30', DATE '2001-10-30') OVERLAPS - 当把一个interval值添加到timestamp with time zone上(或从中减去)时,天这一部分会按照指定的天数增减该timestamp with time zone的日期,同时保持一天中的时间不变。 - 对于跨越夏令时变更的情况(当会话时区被设置为能够识别 DST 的时区时),这意味着interval '1 day'并不一定等于interval '24 hours'。 - 例如,当会话的时区设置为America/Denver时: + 当把一个interval值加到timestamptimestamp with time zone值上(或从中减去一个interval值)时,会依次处理interval值的月、日和微秒字段。 + 首先,非零的月字段会按指定月数增减时间戳的日期,同时保持其在月份中的日不变;如果该日超出了新月份的月末,则使用该月的最后一天。(例如,3 月 31 日加 1 个月得到 4 月 30 日,加 2 个月则得到 5 月 31 日。) + 然后,日字段会按指定天数增减时间戳的日期。在这两个步骤中,一天中的本地时刻保持不变。最后,如果微秒字段不为零,则直接加上或减去该值。 + 在识别夏令时的时区中对timestamp with time zone值进行运算时,这意味着加上或减去(例如)interval '1 day'与加上或减去interval '24 + hours'的结果不一定相同。 + 例如,当会话时区设为America/Denver时: SELECT timestamp with time zone '2005-04-02 12:00:00-07' + interval '1 day'; 结果:2005-04-03 12:00:00-06 SELECT timestamp with time zone '2005-04-02 12:00:00-07' + interval '24 hours'; 结果:2005-04-03 13:00:00-06 - - 发生这种情况是因为在America/Denver时区,夏令时在2005-04-03 02:00:00发生切换,导致跳过了一个小时。 + + 发生这种情况是因为在2005-04-03 02:00:00America/Denver时区切换了夏令时,跳过了一个小时。 @@ -8769,15 +8914,9 @@ SELECT timestamp with time zone '2005-04-02 12:00:00-07' + interval '24 hours'; - 日期和时间戳的减法也可能会很复杂。执行减法的一种概念上很简单的方法是,使用 - EXTRACT(EPOCH FROM ...)把每个值都转换成秒数,然后执行减法, - 这样会得到两个值之间的数。这种方法将会适应每个月中天数、 - 时区改变和夏令时调整。使用-操作符的日期或时间 - 戳减法会返回值之间的天数(24小时)以及时/分/秒,也会做同样的调整。 - age函数会返回年、月、日以及时/分/秒,执行按域的减法,然后对 - 负值域进行调整。下面的查询展示了这些方法的不同。示例中的结果由 - timezone = 'US/Eastern'产生,这使得两个使用的日期之间存在着夏令 - 时的变化: + 日期和时间戳的减法也可能很复杂。一种概念上简单的方法是,先用EXTRACT(EPOCH FROM ...)将各值转换为秒数,然后将结果相减;这样得到的是两个值之间的数。这种方法会针对每个月的天数、时区变化和夏令时变化进行调整。 + 用-操作符将日期或时间戳值相减,会返回两个值之间的天数(每一天为 24 小时)和时/分/秒,也会作相同的调整。age函数返回年、月、日和时/分/秒,它会逐字段相减,然后调整负值字段。 + 以下查询显示了这些方法的差异。示例结果在timezone = 'US/Eastern'设置下产生;所用的两个日期之间发生了夏令时切换: @@ -8829,7 +8968,7 @@ EXTRACT(field FROM source) - 这个世纪;对于interval值,年份字段除以100 + 世纪;对于interval值,年份字段除以100 @@ -8852,7 +8991,7 @@ SELECT EXTRACT(CENTURY FROM INTERVAL '2001 years'); - 月份的日期(1–31);对于interval值,表示天数 + 一个月中的第几天(1–31);对于interval值,表示天数 @@ -8905,7 +9044,7 @@ SELECT EXTRACT(DOW FROM TIMESTAMP '2001-02-16 20:38:40'); - 一年中的日子(1-365/366) + 一年中的第几天(1–365/366) @@ -8920,7 +9059,7 @@ SELECT EXTRACT(DOY FROM TIMESTAMP '2001-02-16 20:38:40'); - 对于timestamp with time zone值,自1970-01-01 00:00:00 UTC以来的秒数(负值表示该时间戳之前的时间); + 对于timestamp with time zone值,自1970-01-01 00:00:00 UTC以来的秒数(早于该时刻的时间戳对应负值); 对于datetimestamp值,自1970-01-01 00:00:00以来的名义秒数,不考虑时区或夏令时规则; 对于interval值,间隔中的总秒数 @@ -8944,8 +9083,8 @@ SELECT to_timestamp(982384720.12); - 注意,将to_timestamp应用于从datetimestamp值中提取的时代可能会产生误导性的结果: - 结果将有效地假定原始值是以UTC时间给出的,这可能并非事实。 + 注意,将to_timestamp应用于从datetimestamp值中提取的 epoch 值可能会产生误导性的结果: + 结果实际上会假定原始值是以UTC时间给出的,这可能并非事实。 @@ -9001,8 +9140,7 @@ SELECT EXTRACT(ISOYEAR FROM DATE '2006-01-02'); - 每个ISO 8601周编号年从包含1月4日的星期一开始,因此在一月初或十二月底,ISO年可能与格里高利年不同。 - 有关更多信息,请参见week字段。 + 每个 ISO 8601 周编号年都从包含 1 月 4 日的那一周的星期一开始,因此在 1 月初或 12 月末,ISO 年可能与格里高利年不同。更多信息请参见 week 字段。 @@ -9045,7 +9183,7 @@ SELECT EXTRACT(MICROSECONDS FROM TIME '17:12:28.5'); - 千年; 对于interval值,年份字段除以1000 + 千年; 对于interval值,年份字段除以1000 @@ -9056,7 +9194,7 @@ SELECT EXTRACT(MILLENNIUM FROM INTERVAL '2001 years'); - 20世纪的年份在第二个千年。第三个千年从2001年1月1日开始。 + 1900 年代的年份属于第二个千年。第三个千年始于 2001 年 1 月 1 日。 @@ -9066,7 +9204,7 @@ SELECT EXTRACT(MILLENNIUM FROM INTERVAL '2001 years'); - 第二个字段,包括小数部分,乘以1000。请注意,这包括完整的秒数。 + 秒字段,包括小数部分,乘以1000。请注意,这包括完整的秒数。 @@ -9096,7 +9234,7 @@ SELECT EXTRACT(MINUTE FROM TIMESTAMP '2001-02-16 20:38:40'); - 月份在一年中的编号(1-12);对于interval值,月份模12的余数(0-11) + 月份在一年中的编号(1–12);对于interval值,月份模12的余数(0–11) @@ -9115,12 +9253,14 @@ SELECT EXTRACT(MONTH FROM INTERVAL '2 years 13 months'); - 日期所在的年份季度(1-4) + 日期所在的年份季度(1–4);对于interval值,为月份字段除以 3 加 1 SELECT EXTRACT(QUARTER FROM TIMESTAMP '2001-02-16 20:38:40'); 结果:1 +SELECT EXTRACT(QUARTER FROM INTERVAL '1 year 6 months'); +结果:3 @@ -9157,7 +9297,7 @@ SELECT EXTRACT(SECOND FROM TIME '17:12:28.5'); - 时间区偏移的小时组件 + 时区偏移的小时部分 @@ -9167,7 +9307,7 @@ SELECT EXTRACT(SECOND FROM TIME '17:12:28.5'); - 时间区偏移的分钟组件 + 时区偏移的分钟部分 @@ -9177,21 +9317,22 @@ SELECT EXTRACT(SECOND FROM TIME '17:12:28.5'); - 一年中ISO 8601周编号周的数量。根据定义,ISO周从周一开始, - 一年的第一周包含该年的1月4日。换句话说,一年的第一个星期四在该年的第1周。 + 一年中按ISO 8601 周编号体系计算的周序号。根据定义,ISO 周从周一开始,一年的第一周包含该年的 1 月 4 日。换句话说,一年的第一个星期四在该年的第 1 周。 - 在ISO周编号系统中,早年1月的日期可能属于前一年的第52周或第53周,而 - 晚年12月的日期可能属于下一年的第一周。例如,2005-01-01 - 属于2004年的第53周,2006-01-01 属于2005年的第52周, - 而2012-12-31 属于2013年的第一周。建议同时使用 - isoyear 字段和week以获得一致的结果。 + 在 ISO 周编号体系中,1 月初的日期可能属于前一年的第 52 周或第 53 周,而 12 月末的日期可能属于下一年的第一周。例如,2005-01-01属于 2004 年的第 53 周,2006-01-01属于 2005 年的第 52 周,而2012-12-31属于 2013 年的第一周。建议将isoyear字段与week一起使用,以获得一致的结果。 + + + + 对于interval值,week 字段就是整天数除以 7 的结果。 SELECT EXTRACT(WEEK FROM TIMESTAMP '2001-02-16 20:38:40'); 结果:7 +SELECT EXTRACT(WEEK FROM INTERVAL '13 days 24 hours'); +结果:1 @@ -9201,7 +9342,7 @@ SELECT EXTRACT(WEEK FROM TIMESTAMP '2001-02-16 20:38:40'); - 年份字段。请记住,没有0 AD,所以要小心地从AD年中减去BC年。 + 年份字段。请记住,没有0 AD,所以把BC年份从AD年份中减去时需要小心。 @@ -9228,7 +9369,8 @@ SELECT EXTRACT(MINUTES FROM INTERVAL '80 minutes'); - 当输入值为 +/-Infinity 时,extract对于单调增的域(epochjulianyearisoyeardecadecentury以及millennium)返回 +/-Infinity。对于其他域返回 NULL。PostgreSQL 9.6 之前的版本对所有输入无穷的情况都返回零。 + 当输入值为 +/-Infinity 时,extract对单调递增的字段返回 +/-Infinity(对于timestamp输入,这些字段为epochjulianyearisoyeardecadecenturymillennium;对于interval输入,这些字段为epochhourdayyeardecadecenturymillennium)。 + 对于其他字段,返回 NULL。PostgreSQL 9.6 之前的版本对所有无穷输入都返回零。 @@ -9237,15 +9379,12 @@ SELECT EXTRACT(MINUTES FROM INTERVAL '80 minutes'); - 在传统的Ingres上建模的date_part函数等价于SQL标准函数extract: + date_part函数仿照传统的Ingres实现,后者对应SQL标准的extract函数: date_part('field', source) - 请注意这里的field参数必须是一个串值,而不是一个名字。 - 有效的date_part域名 和extract相同。 - 由于历史原因,date_part函数返回double precision类型的值。 - 这可能导致在某些使用中损失精度。 - 建议使用extract替代。 + 注意,此处的field参数必须是字符串值,而不能是名称。date_part的有效字段名与extract相同。 + 由于历史原因,date_part函数返回double precision类型的值,可能在某些用途中损失精度。建议改用extract @@ -9272,11 +9411,12 @@ SELECT date_part('hour', INTERVAL '4 hours 3 minutes'); date_trunc(field, source [, time_zone ]) - source是类型timestampinterval的值表达式(类型datetime的值都分别被自动转换成timestamp, timestamp with time zone,或者interval)。field选择对输入值选用什么样的精度进行截断。返回的值是timestamp, timestamp with time zone,类型或者所有小于选定的 精度的域都设置为零(或者一,对于日期和月份)的interval。 + sourcetimestamptimestamp with time zoneinterval类型的值表达式。(datetime类型的值会分别自动转换为timestampinterval。) + field选择输入值的截断精度。返回值同样为timestamptimestamp with time zoneinterval类型,其中低于所选精度的所有字段都设为零(日和月则设为一)。 - field的有效值是∶ + field的有效值是: microseconds milliseconds @@ -9295,7 +9435,7 @@ date_trunc(field, source [ - 当输入值的类型为timestamp with time zone时。截断是针对特定时区进行的。 例如,截断为day,产生的值是 是该区域的午夜。 默认情况下,截断是在以下方面进行的 到当前的设置,但在当前的 可以提供可选的time_zone参数。以指定不同的时区。 可以指定时区名称 中描述的任何一种方式。 + 当输入值为timestamp with time zone类型时,截断会以特定时区为准;例如,截断到day会得到该时区的午夜。默认情况下,截断以当前的设置为准,但可以通过可选的time_zone参数指定其他时区。时区名称可以用中描述的任意方式指定。 @@ -9337,11 +9477,11 @@ date_bin(stride, source, < sourcetimestamptimestamp with time zone类型的值表达式。 (类型date的值会自动转换为timestamp。) strideinterval类型的值表达式。 - 返回值同样是timestamptimestamp with time zone类型,并且它标记着放置source的bin的开始。 + 返回值同样是timestamptimestamp with time zone类型,并且它表示source所在分箱的起点。 - 示例: + 示例: SELECT date_bin('15 minutes', TIMESTAMP '2020-02-11 15:44:17', TIMESTAMP '2001-01-01'); 结果: 2020-02-11 15:30:00 @@ -9363,8 +9503,8 @@ SELECT date_bin('15 minutes', TIMESTAMP '2020-02-11 15:44:17', TIMESTAMP '2001-0 <literal>AT TIME ZONE</literal> 和 <literal>AT LOCAL</literal> - time zone - conversion + 时区 + 转换 @@ -9376,7 +9516,7 @@ SELECT date_bin('15 minutes', TIMESTAMP '2020-02-11 15:44:17', TIMESTAMP '2001-0 - AT TIME ZONE 操作符可在带时区和不带时区的时间戳之间进行转换,也可将 time with time zone 值转换到不同的时区。 展示了它的各种变体。 + AT TIME ZONE 操作符可将不带时区的时间戳转换为时区的时间戳或反向转换,也可将 time with time zone 值转换到不同的时区。 展示了它的各种变体。
@@ -9476,7 +9616,7 @@ SELECT date_bin('15 minutes', TIMESTAMP '2020-02-11 15:44:17', TIMESTAMP '2001-0 time with time zone - 将给定的带时区时间转换到新的时区,所用时区为会话的 TimeZone 值。由于没有提供日期,这会使用会话 TimeZone 当前生效的 UTC 偏移量。 + 将给定的带时区时间转换到新的时区。由于没有提供日期,这会使用会话 TimeZone 值当前生效的 UTC 偏移量。 假定会话的 TimeZone 设为 UTC: @@ -9512,33 +9652,38 @@ SELECT TIMESTAMP '2001-02-16 20:38:40' AT TIME ZONE 'Asia/Tokyo' AT TIME ZONE 'A SELECT TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40-05' AT LOCAL; 结果:2001-02-16 17:38:40 SELECT TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40-05' AT TIME ZONE '+05'; -结果:2001-02-17 06:38:40 +结果:2001-02-16 20:38:40 SELECT TIME WITH TIME ZONE '20:38:40-05' AT LOCAL; -结果:17:38:40-08 +结果:17:38:40 第一个示例为缺少时区的值添加时区,并使用当前的 TimeZone 设置显示该值。 - 第二个示例将带时区的时间戳值转换到指定时区,并返回无时区的值。 - 这允许存储和显示与当前 TimeZone 设置不同的值。第三个示例将东京时间转换为芝加哥时间。第四个示例展示了 AT LOCAL 的用法。第五个示例使用数值型 UTC 偏移量作为时区。最后一个示例展示了 time with time zone 值转换为会话本地时区的结果。 + 第二个示例将带时区的时间戳值转换到指定时区,并返回不带时区的值。 + 这样就可以存储和显示与当前 TimeZone 设置不同的值。 + 第三个示例将东京时间转换为芝加哥时间。 + 第四个示例将带时区的时间戳值转换到当前 TimeZone 设置指定的时区,并返回不带时区的值。 + 第五个示例说明,POSIX 风格的时区说明中的正负号与 ISO-8601 日期时间字面量中的正负号含义相反,有关信息请参见 - 函数timezone(zone, timestamp)等效于 SQL 兼容的结构timestamp AT TIME ZONE zone。 + 第六个示例需要注意。由于输入值不包含日期,转换使用会话的当前日期。 + 因此,根据查看本示例时处于一年中的哪个时段,这个静态示例可能显示错误的结果,因为 + 'America/Los_Angeles' 实行夏令时。 - 结构 timestamp AT LOCAL 等效于 timestamp AT TIME ZONE local。 + 函数timezone(zone, timestamp)等效于符合 SQL 标准的结构timestamp AT TIME ZONE zone - 函数timezone(zone, timestamp with time zone)等效于 SQL 兼容的结构timestamp with time zone AT TIME ZONE zone。 + 函数timezone(zone, time)等效于符合 SQL 标准的结构time AT TIME ZONE zone - 结构 timestamp with time zone AT LOCAL 等效于 timestamp with time zone AT TIME ZONE local。 + 函数timezone(timestamp)等效于符合 SQL 标准的结构timestamp AT LOCAL - 函数timezone(zone, time with time zone)等效于 SQL 兼容的结构time with time zone AT TIME ZONE zone。结构 time with time zone AT LOCAL 等效于 time with time zone AT TIME ZONE local。 + 函数timezone(time)等效于符合 SQL 标准的结构time AT LOCAL @@ -9547,13 +9692,13 @@ SELECT TIME WITH TIME ZONE '20:38:40-05' AT LOCAL; 当前日期/时间 - date - current + 日期 + 当前 - time - current + 时间 + 当前 @@ -9572,15 +9717,15 @@ LOCALTIMESTAMP(precision) - CURRENT_TIMECURRENT_TIMESTAMP传递带有时区的值;LOCALTIMELOCALTIMESTAMP传递的值不带时区。 + CURRENT_TIMECURRENT_TIMESTAMP返回带时区的值;LOCALTIMELOCALTIMESTAMP返回不带时区的值。 - CURRENT_TIMECURRENT_TIMESTAMPLOCALTIMELOCALTIMESTAMP可以有选择地接受一个精度参数,该精度会使结果的秒字段圆整到指定的小数位数。如果没有精度参数,结果将给出可用的全部精度。 + CURRENT_TIMECURRENT_TIMESTAMPLOCALTIMELOCALTIMESTAMP可以有选择地接受一个精度参数,该精度会使结果的秒字段舍入到指定的小数位数。如果没有精度参数,结果将给出可用的全部精度。 - 一些示例: + 一些示例: SELECT CURRENT_TIME; 结果: 14:39:53.662522-05 @@ -9602,7 +9747,7 @@ SELECT LOCALTIMESTAMP; - 许多其它数据库系统可能会更频繁地推进这些值。 + 其他数据库系统可能会更频繁地推进这些值。 @@ -9619,11 +9764,11 @@ now() - transaction_timestamp()等价于CURRENT_TIMESTAMP,但是其命名清楚地反映了它的返回值。statement_timestamp()返回当前语句的开始时刻(更准确的说是收到 客户端最后一条命令的时间)。statement_timestamp()transaction_timestamp()在一个事务的第一条命令期间返回值相同,但是在随后的命令中却不一定相同。 clock_timestamp()返回真正的当前时间,因此它的值甚至在同一条 SQL 命令中都会变化。timeofday()是一个有历史原因的PostgreSQL函数。和clock_timestamp()相似,timeofday()也返回真实的当前时间,但是它的结果是一个格式化的text串,而不是timestamp with time zone值。now()PostgreSQL的一个传统,等效于transaction_timestamp()。 + transaction_timestamp()等价于CURRENT_TIMESTAMP,但是其命名清楚地反映了它的返回值。statement_timestamp()返回当前语句的开始时刻(更准确地说,是接收到客户端最近一条命令消息的时间)。statement_timestamp()transaction_timestamp()在一个事务的第一条语句期间返回值相同,但是在随后的语句中却不一定相同。 clock_timestamp()返回真正的当前时间,因此它的值甚至在同一条 SQL 语句中都会变化。timeofday()是一个有历史原因的PostgreSQL函数。和clock_timestamp()相似,它也返回真实的当前时间,但是它的结果是一个格式化的text串,而不是timestamp with time zone值。now()PostgreSQL中与transaction_timestamp()等价的传统函数。 - 所有日期/时间类型还接受特殊的文字值now,用于指定当前的日期和时间(重申,被解释为当前事务的开始时刻)。 因此,下面三个都返回相同的结果: + 所有日期/时间数据类型也都接受特殊字面值now来指定当前日期和时间(同样解释为事务开始时间)。因此,下面三种写法都返回相同的结果: SELECT CURRENT_TIMESTAMP; SELECT now(); @@ -9635,7 +9780,7 @@ SELECT TIMESTAMP 'now'; -- 但请参阅下面的提示 当指定以后要计算的值时,不要使用第三种形式,例如在表列的DEFAULT子句中。 - 系统将在分析这个常量的时候把now转换为一个timestamp, 这样需要默认值时就会得到创建表的时间!而前两种形式要到实际使用缺省值的时候才被计算, 因为它们是函数调用。因此它们可以给出每次插入行的时刻。 + 系统将在分析这个常量的时候把now转换为一个timestamp, 这样需要默认值时就会得到创建表的时间!而前两种形式要到实际使用默认值的时候才被计算, 因为它们是函数调用。因此它们可以给出每次插入行的时刻。 (参见 。) @@ -9658,24 +9803,24 @@ SELECT TIMESTAMP 'now'; -- 但请参阅下面的提示 - sleep + 休眠 - delay + 延迟 - 下面的这些函数可以用于让服务器进程延时执行: + 以下函数可用于延迟服务器进程的执行: pg_sleep ( double precision ) pg_sleep_for ( interval ) pg_sleep_until ( timestamp with time zone ) - pg_sleep使当前会话的进程休眠,直到过去给定的秒数。可以指定几分之一秒的延迟。 - pg_sleep_for是一个方便的函数,允许将睡眠时间指定为时间间隔。 - pg_sleep_until是一个方便的函数,用于需要特定的唤醒时间。例如: + pg_sleep使当前会话的进程休眠,直到经过指定的秒数。可以指定带小数部分的秒数作为延迟时间。 + pg_sleep_for是一个便捷函数,允许以interval指定休眠时间。 + pg_sleep_until是在需要指定唤醒时间时使用的便捷函数。例如: SELECT pg_sleep(1.5); @@ -9710,7 +9855,7 @@ SELECT pg_sleep_until('tomorrow 03:00'); 枚举支持函数 - 对于枚举类型(在中描述), 有一些函数允许更清洁的编码,而不需要为一个枚举类型硬写特定的值。它们被列在中。本例假定一个枚举类型被创建为: + 对于枚举类型(见),有些函数可以避免硬编码枚举类型中的特定值,使程序更简洁。这些函数列在中。以下示例假定枚举类型按如下方式创建: CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple'); @@ -9796,8 +9941,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple anyarray - 以一个数组返回在给定两个枚举值之间的范围。值必须来自相同的枚举类型。 - 如果第一个参数为空,其结果将从枚举类型的第一个值开始。如果第二参数为空,其结果将以枚举类型的最后一个值结束。 + 以有序数组返回两个给定枚举值之间的范围。两个值必须来自同一枚举类型。如果第一个参数为 null,结果从该枚举类型的第一个值开始;如果第二个参数为 null,结果以该枚举类型的最后一个值结束。 enum_range('orange'::rainbow, 'green'::rainbow) @@ -9817,8 +9961,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple
- 请注意,除了双参数形式的enum_range外, 这些函数忽略传递给它们的具体值,它们只关心声明的数据类型。 - 空值或类型的一个特定值可以通过,并得到相同的结果。这些函数更多地被用于一个表列或函数参数,而不是一个硬写的类型名,如示例中所使用。 + 请注意,除了enum_range的双参数形式外,这些函数都忽略传入的具体值,只关心其声明的数据类型。传入 null 或该类型的某个具体值,结果都相同。通常会将这些函数用于表列或函数参数,而不是像示例那样使用硬编码的类型名。 @@ -9829,7 +9972,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple 几何类型pointboxlseglinepath、 - polygoncircle有一大堆本地支持函数和操作符,如中所示。 + polygoncircle有大量内置支持函数和操作符,如中所示。 @@ -9874,7 +10017,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple path - 连接两个打开的路径(如果其中一个路径是关闭的,则返回NULL)。 + 连接两个开放路径(如果任一路径是封闭的,则返回NULL)。 path '[(0,0),(1,1)]' + path '[(2,2),(3,3),(4,4)]' @@ -9903,12 +10046,12 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple geometric_type - 将第一个参数的每个点乘上第二个point(将点视为由实部和虚部表示的复数,并执行标准的复数乘法)。 + 将第一个参数的每个点乘上第二个point(将点视为由实部和虚部表示的复数,并执行标准的复数乘法)。 如果将第二个point解释为向量,这等价于将对象的大小和到原点的距离按向量的长度缩放,并以向量与x轴的夹角绕原点逆时针旋转。 - 适用于point, box,Rotating 用这些操作符“旋转”一个盒子,只会移动它的角点:这个盒子仍然被认为有平行于轴的边。 - 因此,盒子的大小并没有像真正的旋转那样得到保留。 - path, circle.。 + 适用于pointbox用这些操作符旋转一个矩形框,只会移动它的角点:这个矩形框仍然被认为有平行于轴的边。 + 因此,矩形框的大小并没有像真正的旋转那样得到保留。 + pathcircle path '((0,0),(1,0),(1,1))' * point '(3.0,0)' @@ -9927,7 +10070,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple 将第一个参数的每个点除以第二个point(将点视为由实部和虚部表示的复数,并执行标准的复数除法)。 - 如果将第二个point解释为向量,这等价于将物体的大小和到原点的距离按向量的长度向下缩放,并以向量与x轴的夹角围绕原点顺时针旋转。 + 如果将第二个point解释为向量,这等价于将对象的大小和到原点的距离按向量长度的倒数缩放,并以向量与x轴的夹角围绕原点顺时针旋转。 适用于 point, box, path,circle @@ -10004,7 +10147,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple box - 计算两个方框的交集,如果没有则为NULL。 + 计算两个矩形框的交集,如果没有则为NULL。 box '(2,2),(-1,-1)' # box '(1,1),(-2,-2)' @@ -10018,7 +10161,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple point - 计算第一个对象上距离第二个对象最近的点。 + 计算第二个对象上距离第一个对象最近的点。 可用于以下类型的配对: (point, box), (point, lseg), @@ -10040,7 +10183,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple 计算对象之间的距离。 - 对于所有七种几何类型,所有point与另一种几何类型的组合, + 适用于所有七种几何类型,所有point与另一种几何类型的组合, 以及以下这些额外的类型对: (box, lseg), (lseg, line), @@ -10080,7 +10223,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 第一个对象包含在第二个对象之中还是在第二个对象之上? 适用于这些类型对: + 第一个对象是否位于第二个对象内部或其上? 适用于这些类型对: (point, box), (point, lseg), (point, line), @@ -10180,7 +10323,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 第一个对象是否确定位于第二个对象下面? + 第一个对象是否严格位于第二个对象下面? 适用于 point, box, polygon, circle @@ -10195,7 +10338,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 第一个对象是否确定位于第二个对象上面? + 第一个对象是否严格位于第二个对象上面? 适用于 point, box, polygon, circle. @@ -10268,7 +10411,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 这些对象是否相交? 适用于这些类型对: + 这些对象是否相交? 适用于这些类型对: (box, box), (lseg, box), (lseg, lseg), @@ -10293,7 +10436,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 线是水平的? + 线是否水平? ?- lseg '[(-1,0),(1,0)]' @@ -10325,7 +10468,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 线是纵向的? + 线是否竖直? ?| lseg '[(-1,0),(1,0)]' @@ -10357,7 +10500,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 线是垂直的? + 两条线是否互相垂直? lseg '[(0,0),(0,1)]' ?-| lseg '[(0,0),(1,0)]' @@ -10375,7 +10518,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 线是平行的? + 两条线是否平行? lseg '[(-1,0),(1,0)]' ?|| lseg '[(-1,2),(1,2)]' @@ -10404,16 +10547,16 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple - 请注意same as操作符(~=),表示pointboxpolygoncircle类型的一般相等概念。 - 这些类型中的某些还有一个=操作符,但是=只比较相同的面积。 - 其它的标量比较操作符 (<=等等),在这些类型可用的地方,同样比较区域。 + 注意,相同操作符~=表示pointboxpolygoncircle类型通常意义上的相等。 + 某些几何类型还有=操作符,但=仅比较面积是否相等。 + 对于提供其他标量比较操作符(<=等)的类型,这些操作符同样比较面积。 - 在PostgreSQL14之前, 该点严格低于/高于比较操作符 point <<| pointpoint |>> point 分别被称为 <^>^。 + 在PostgreSQL14之前, 用于判断点是否严格位于另一点下方/上方的比较操作符 point <<| pointpoint |>> point 分别被称为 <^>^。 这些名字仍然可以使用,但是已被弃用并且最终将被移除。 @@ -10710,7 +10853,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple box - 计算内接于圆的方框。 + 计算内接于圆的矩形框。 box(circle '<(0,0),2>') @@ -10769,7 +10912,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple box - 计算两个方框的边界框。 + 计算两个矩形框的边界框。 bound_box(box '(1,1),(0,0)', box '(4,4),(3,3)') @@ -10786,7 +10929,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple circle - 计算包围方框的最小圆。 + 计算包围矩形框的最小圆。 circle(box '(1,1),(0,0)') @@ -10879,7 +11022,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple path - 将多边形转换为具有点的相同列表的封闭路径。 + 将多边形转换为具有相同点列表的封闭路径。 path(polygon '((0,0),(1,1),(2,0))') @@ -10987,7 +11130,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple polygon(circle '<(0,0),2>') - (-2,0,)&zwsp; (-1.73205080758774,0.9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999998999998989898989676868686887898999999999998989898989898999978987878787808070876888788989898989898989898989898989898989898989898968686868688768686887878989896868686889899999999999990000890000899900000000890000890000890000000000000000 + ((-2,0),&zwsp;(-1.7320508075688774,0.9999999999999999),&zwsp;(-1.0000000000000002,1.7320508075688772),&zwsp;(-1.2246063538223773e-16,2),&zwsp;(0.9999999999999996,1.7320508075688774),&zwsp;(1.732050807568877,1.0000000000000007),&zwsp;(2,2.4492127076447545e-16),&zwsp;(1.7320508075688776,-0.9999999999999994),&zwsp;(1.0000000000000009,-1.7320508075688767),&zwsp;(3.673819061467132e-16,-2),&zwsp;(-0.9999999999999987,-1.732050807568878),&zwsp;(-1.7320508075688767,-1.0000000000000009)) @@ -11001,7 +11144,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple polygon(4, circle '<(3,0),1>') - ((2,0,)&zwsp; (3,1,)&zwsp; (4,1.2246063538223773e-16), &zwsp; (3,-1)). + ((2,0),&zwsp;(3,1),&zwsp;(4,1.2246063538223773e-16),&zwsp;(3,-1)) @@ -11011,7 +11154,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple polygon - 将封闭路径转换为具有点的相同列表的多边形。 + 将封闭路径转换为具有相同点列表的多边形。 polygon(path '((0,0),(1,1),(2,0))') @@ -11024,7 +11167,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple
- 我们可以把一个point的两个组成数字当作具有索引 0 和 1 的数组访问。例如,如果t.p是一个point列,那么SELECT p[0] FROM t检索 X 坐标而 UPDATE t SET p[1] = ...改变 Y 坐标。同样,box或者lseg类型的值可以当作两个point值的数组值看待。 + 可以把一个point当作下标为 0 和 1 的数组,访问它的两个数值分量。例如,如果t.p是一个point列,那么SELECT p[0] FROM t检索 X 坐标而 UPDATE t SET p[1] = ...改变 Y 坐标。同样,box或者lseg类型的值可以当作两个point值组成的数组看待。 @@ -11040,8 +11183,8 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple 任何cidr 值都可以隐式地转换到inet;因此,下面在inet上操作的操作符和函数也可以在cidr值上工作。 - (对于inetcidr有单独的函数,这是因为这两种情况的行为应该是不同的。) - 此外,它允许将inet值转换为cidr。 + (如果inetcidr各有单独的函数,是因为这两种情况下的行为应当不同。) + 此外,也允许将inet值转换为cidr。 当这样做的时候,子网掩码右边的任何位都被静默地置零,以创建一个有效的cidr值。 @@ -11072,8 +11215,8 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean
- 子网是否严格包含在子网中?这个操作符和后续的四个操作符测试子网包含情况。 - 它们只考虑两个地址的网络部分(忽略网络掩码右侧的任何位),并确定一个网络与另一个网络相同或者是相同的子网。 + 子网是否严格包含在另一个子网中?这个操作符和后续四个操作符测试子网包含关系。 + 它们只考虑两个地址的网络部分(忽略网络掩码右侧的所有位),并判断一个网络是否与另一个网络相同,或是另一个网络的子网。 inet '192.168.1.5' << inet '192.168.1/24' @@ -11095,7 +11238,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 子网是否包含或等于子网? + 子网是否被包含于或等于子网? inet '192.168.1/24' <<= inet '192.168.1/24' @@ -11155,7 +11298,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple inet - 计算位 NOT. + 计算按位非。 ~ inet '192.168.1.6' @@ -11169,7 +11312,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple inet - 计算位 AND. + 计算按位与。 inet '192.168.1.6' & inet '0.0.0.255' @@ -11183,7 +11326,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple inet - 计算位 OR. + 计算按位或。 inet '192.168.1.6' | inet '0.0.0.255' @@ -11284,9 +11427,8 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple text - 创建缩写的文本显示格式。 - (结果与inet输出函数产生的结果相同;只有在与显式转换为text的结果相比时它才算是缩写形式, - 由于历史原因,它永远不会抑制子网掩码部分。) + 创建文本形式的缩写显示格式。 + (结果与inet输出函数产生的结果相同;只有与显式类型转换为text的结果相比时,才称为缩写形式。由于历史原因,后一种转换从不省略网络掩码部分。) abbrev(inet '10.1.0.0/32') @@ -11300,7 +11442,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple text - 创建缩写的文本显示格式。(缩写包括在子网掩码的右侧删除所有零字节;更多的示例请见 。) + 创建文本形式的缩写显示格式。(缩写形式会省略网络掩码右侧值为零的字节;更多示例见。) abbrev(cidr '10.1.0.0/16') @@ -11419,7 +11561,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple integer - 以比特位返回子网掩码长度。 + 返回子网掩码长度,以位为单位。 masklen(inet '192.168.1.5/24') @@ -11521,7 +11663,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple MAC地址类型, macaddrmacaddr8,支持中所示的常用比较操作符以及中所示的特殊函数。 - 此外,它们支持位元逻辑操作符~, &| (NOT, AND 和 OR),就像上面对IP地址所示的那样。 + 此外,它们支持按位逻辑操作符~&|(非、与和或),就像上面对IP地址所示的那样。 @@ -11585,7 +11727,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple macaddr8 - 将地址的第7位设置为1,创建所谓的modified EUI-64,用于包含在IPv6地址中。 + 将地址的第 7 位设置为 1,生成所谓的修订 EUI-64 格式,以便用于 IPv6 地址。 macaddr8_set7bit(macaddr8 '00:34:56:ab:cd:ef') @@ -11603,7 +11745,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple 文本搜索函数和操作符 - 全文搜索 + 全文检索 函数和操作符 @@ -11616,7 +11758,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple 以及 - 总结了为全文搜索提供的函数和操作符。PostgreSQL的文本搜索功能的详细解释可参考。 + 总结了为全文检索提供的函数和操作符。PostgreSQL的文本搜索功能的详细解释可参考
@@ -11672,35 +11814,19 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple + + - tsvector @@@ tsquery - boolean - - - tsquery @@@ tsvector - boolean + tsvector || tsvector + tsvector - 这是@@已弃用的同义词。 - - - to_tsvector('fat cats ate rats') @@@ to_tsquery('cat & rat') - t - - - - - - tsvector || tsvector - tsvector - - - 连接两个tsvector。如果两个输入都包含词素位置,则相应地调整第二个输入的位置。 + 连接两个tsvector。如果两个输入都包含词位位置,则相应地调整第二个输入的位置。 'a:1 b:2'::tsvector || 'c:1 d:2 b:3'::tsvector - 'a':1'b':2,5'c':3'd':4 + 'a':1 'b':2,5 'c':3 'd':4 @@ -11738,7 +11864,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsquery - 否定tsquery,生成一个与输入查询不匹配的匹配文档的查询。 + 对tsquery取反,生成匹配那些不满足输入查询的文档的查询。 !! 'cat'::tsquery @@ -11752,7 +11878,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsquery - 构造一个短语查询,如果两个输入查询在连续的词素上匹配,该查询将进行匹配。 + 构造一个短语查询;当两个输入查询分别匹配相邻的词位时,该查询匹配。 to_tsquery('fat') <-> to_tsquery('rat') @@ -11766,7 +11892,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 第一个tsquery包含了第二个吗?(这只考虑出现在一个查询中的所有词素是否出现在另一个查询中,忽略了组合操作符。) + 第一个tsquery包含了第二个吗?(这只考虑出现在一个查询中的所有词位是否出现在另一个查询中,忽略了组合操作符。) 'cat'::tsquery @> 'cat & rat'::tsquery @@ -11780,7 +11906,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple boolean - 第一个tsquery包含在第二个中吗?(这只考虑出现在一个查询中的所有词素是否出现在另一个查询中,而忽略了组合操作符。) + 第一个tsquery包含在第二个中吗?(这只考虑出现在一个查询中的所有词位是否出现在另一个查询中,而忽略了组合操作符。) 'cat'::tsquery <@ 'cat & rat'::tsquery @@ -11797,7 +11923,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple 除了这些专用操作符之外, 中所示的常用比较操作符也适用于tsvectortsquery类型。 - 它们对于文本搜索不是很有用,但是允许使用。例如,建在这些类型列上的唯一索引。 + 这些操作符对文本搜索用处不大,但可以用于其他用途,例如在这些类型的列上建立唯一索引。
@@ -11831,7 +11957,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple 将文本字符串数组转换为tsvector。 - 给定的字符串被直接用作词元,不经过进一步处理。数组元素不得为空字符串 + 给定的字符串被直接用作词位,不经过进一步处理。数组元素不得为空字符串 或NULL @@ -11902,8 +12028,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsquery - 将文本转换为tsquery,根据指定的或默认配置对单词进行标准化。 - 字符串中的任何标点符号都会被忽略(它不决定查询操作符)。结果查询匹配文本中包含所有非停止词的文档。 + 将文本转换为tsquery,根据指定的或默认配置对单词进行正规化。字符串中的任何标点符号都会被忽略(它们不决定查询操作符)。生成的查询匹配包含文本中所有非停用词的文档。 plainto_tsquery('english', 'The Fat Rats') @@ -11922,8 +12047,8 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsquery - 将文本转换为tsquery,根据指定的或默认配置对单词进行标准化。 - 字符串中的任何标点符号都会被忽略(它不决定查询操作符)。结果查询匹配包含文本中所有非停止词的短语。 + 将文本转换为tsquery,根据指定的或默认配置对单词进行正规化。 + 字符串中的任何标点符号都会被忽略(它不决定查询操作符)。结果查询匹配包含文本中所有非停用词的短语。 phraseto_tsquery('english', 'The Fat Rats') @@ -11946,8 +12071,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsquery - 将文本转换为tsquery,根据指定的或默认配置对单词进行标准化。引用的单词序列被转换为短语测试。 - or一词被理解为产生OR操作符,而破折号产生NOT操作符;其他标点符号被忽略。这类似于一些常见的网络搜索工具的行为。 + 将文本转换为tsquery,根据指定的或默认配置对单词进行正规化。带引号的单词序列被转换为短语测试。or一词产生 OR 操作符,短横线产生 NOT 操作符;其他标点符号会被忽略。这类似于一些常见网络搜索工具的行为。 websearch_to_tsquery('english', '"fat rat" or cat dog') @@ -11993,14 +12117,13 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple setweight - 为特定词元设置权重 + 为特定词位设置权重 setweight ( vector tsvector, weight "char", lexemes text[] ) tsvector - 为vector中列出的lexemes赋予指定的weight。 - lexemes中的字符串被视为词元,不经过进一步处理。不匹配vector中任何词元的字符串将被忽略。 + 为vector中列在lexemes内的元素赋予指定的weightlexemes中的字符串按原样用作词位,不经过进一步处理。不匹配vector中任何词位的字符串将被忽略。 setweight('fat:2,4 cat:3 rat:5,6B'::tsvector, 'A', '{cat,rat}') @@ -12036,7 +12159,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsquery - 将文本转换为tsquery,根据指定的或默认配置对单词进行标准化。单词必须由有效的tsquery操作符组合。 + 将文本转换为tsquery,根据指定的或默认配置对单词进行正规化。单词必须由有效的tsquery操作符组合。 to_tsquery('english', 'The & Fat & Rats') @@ -12055,7 +12178,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsvector - 将文本转换为tsvector,根据指定的或默认配置对单词进行标准化。结果中包含位置信息。 + 将文本转换为tsvector,根据指定的或默认配置对单词进行正规化。结果中包含位置信息。 to_tsvector('english', 'The Fat Rats') @@ -12077,9 +12200,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsvector - 将JSON文档中的每个字符串值转换为tsvector,根据指定的或默认配置对单词进行标准化。 - 然后将结果按文档顺序连接起来以产生输出。位置信息就像在每对字符串值之间存在一个停止词一样生成。 - (注意,当输入为jsonb时,JSON对象的字段的document order取决于实现;请观察这些示例中的差异。) + 将 JSON 文档中的每个字符串值转换为tsvector,根据指定的或默认配置对单词进行正规化。然后将结果按文档顺序连接起来以产生输出。生成位置信息时,视为每对字符串值之间存在一个停用词。(注意,当输入为jsonb时,JSON 对象字段的文档顺序取决于具体实现;请注意这些示例中的差异。) to_tsvector('english', '{"aa": "The Fat Rats", "b": "dog"}'::json) @@ -12113,15 +12234,15 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsvector - 选择filter请求的JSON文档中的每个项,并将每个项转换为tsvector,根据指定的或默认配置对单词进行标准化。 - 然后将结果按文档顺序连接起来以产生输出。位置信息就像在每对选定的项目之间存在一个停止词一样生成。 - (注意,当输入为jsonb时,JSON对象字段的document order取决于实现。) - filter必须是一个jsonb数组,其中包含0个或多个关键字: + 选择filter请求的JSON文档中的每个项,并将每个项转换为tsvector,根据指定的或默认配置对单词进行正规化。 + 然后将结果按文档顺序连接起来以产生输出。位置信息就像在每对选定的项目之间存在一个停用词一样生成。 + (注意,当输入为jsonb时,JSON对象字段的文档顺序取决于实现。) + filter必须是一个jsonb数组,其中包含0个或多个关键字: "string"(包括所有字符串值), "numeric"(包括所有数值), "boolean"(包括所有布尔值), "key"(包括所有键),或 - "all"(包括以上所有关键字)。 + "all"(包括以上所有内容)。 作为一种特殊情况,该filter也可以是这些关键字之一的简单JSON值。 @@ -12143,8 +12264,8 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsvector - 从vector中删除给定的lexeme的任何出现。 - lexeme字符串被视为原样的词元,不经过进一步处理。 + 从vector中删除给定的lexeme的所有出现。 + lexeme字符串被视为原样的词位,不经过进一步处理。 ts_delete('fat:2,4 cat:3 rat:5A'::tsvector, 'fat') @@ -12158,9 +12279,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsvector - 从vector中删除lexemes中的任何出现。 - lexemes中的字符串被视为词元,不经过进一步处理。 - 不匹配vector中任何词元的字符串将被忽略。 + 从vector中删除lexemes所列词位的所有出现。lexemes中的字符串按原样用作词位,不经过进一步处理。不匹配vector中任何词位的字符串将被忽略。 ts_delete('fat:2,4 cat:3 rat:5A'::tsvector, ARRAY['fat','rat']) @@ -12198,9 +12317,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple text - 以缩写形式显示documentquery的匹配项,该匹配项必须是原始文本,而不是tsvector。 - 在匹配查询之前,文档中的单词将根据指定的或默认的配置进行规范化。 - 中讨论了该函数的使用,还描述了可用的options。 + 以缩略形式显示querydocument中的匹配项;后者必须是原始文本,不能是tsvector。在匹配查询之前,文档中的单词将根据指定的或默认配置进行正规化。中讨论了该函数的使用,还描述了可用的options ts_headline('The fat cat ate the rat.', 'cat') @@ -12226,8 +12343,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple text - 以缩写形式显示匹配JSONdocument中字符串值中的query。 - 更多细节请参阅 。 + 以缩略形式显示query在 JSON document字符串值中的匹配项。更多细节请参见 ts_headline('{"cat":"raining cats and dogs"}'::jsonb, 'cat') @@ -12305,8 +12421,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsquery - 根据目标替换部分query,并替换通过执行SELECT命令获得的查询。 - 详情参见。 + 根据执行SELECT命令得到的目标和替换项,替换query中的相应部分。详情参见 SELECT ts_rewrite('a & b'::tsquery, 'SELECT t,s FROM aliases') @@ -12337,7 +12452,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple tsquery - 构造一个短语查询,用于搜索query1query2的匹配项,这些匹配项恰好出现在distance词位之间。 + 构造一个短语查询,用于搜索query1query2的匹配项,其匹配位置恰好相距distance个词位。 tsquery_phrase(to_tsquery('fat'), to_tsquery('cat'), 10) @@ -12366,7 +12481,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple unnest - for tsvector + 用于 tsvector unnest ( tsvector ) setof record @@ -12396,7 +12511,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple - 所有接受一个可选的regconfig参数的文本搜索函数在该参数被忽略时,使用由指定的配置。 + 所有接受一个可选的regconfig参数的文本搜索函数在省略该参数时,会使用由指定的配置。 @@ -12443,7 +12558,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple lexemes text[] ) - 根据指定的或默认的文本搜索配置从document中提取和标准化标记,并返回关于每个标记是如何处理的信息。 + 根据指定的或默认的文本搜索配置从document中提取和正规化词元,并返回关于每个词元是如何处理的信息。 详情参见 @@ -12461,8 +12576,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple text[] - 如果字典知道输入标记,则返回替换词位数组;如果字典知道标记,但它是停止词,则返回空数组;如果它不是已知词,则返回NULL。 - 详情参见。 + 如果词典识别输入词元,则返回由替换词位组成的数组;如果词典识别该词元,但它是停用词,则返回空数组;如果词典无法识别该词元,则返回NULL。详情参见 ts_lexize('english_stem', 'stars') @@ -12482,7 +12596,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple token text ) - 使用命名的解析器从document中提取标记。详情参见。 + 使用指定名称的解析器从document中提取词元。详情参见 ts_parse('default', 'foo - bar') @@ -12499,7 +12613,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple token text ) - 使用 OID 指定的解析器从document中提取标记。 + 使用 OID 指定的解析器从document中提取词元。 详情参见 @@ -12520,7 +12634,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple description text ) - 返回一个表,该表描述命名解析器可以识别的每种类型的标记。详情参见。 + 返回一个表,该表描述指定名称的解析器可以识别的每种类型的词元。详情参见 ts_token_type('default') @@ -12537,7 +12651,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple description text ) - 返回一个表,该表描述 OID 指定的解析器可以识别的每种标记类型。详情参见。 + 返回一个表,该表描述 OID 指定的解析器可以识别的每种词元类型。详情参见 ts_token_type(3722) @@ -12558,7 +12672,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple nentry integer ) - 执行sqlquery,该查询必须返回单个tsvector列,并返回数据中每个不同词元的统计信息。 + 执行sqlquery,该查询必须返回单个tsvector列,并返回数据中每个不同词位的统计信息。 详情参见 @@ -12576,7 +12690,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple UUID 函数 - + UUID 生成 @@ -12740,8 +12854,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple
- PostgreSQL也为 UUID 提供了 - 中展示的常用比较操作符。 + PostgreSQL也为 UUID 提供了中展示的常用比较操作符。 关于PostgreSQLuuid数据类型的细节,请参见 @@ -13209,7 +13322,7 @@ SELECT xmlexists('//town[text() = ''Toronto'']' PASSING BY VALUE 'T - 示例: + 示例: - 示例: + 示例: test', ARRAY[ARRAY['my', 'http://example.com']]); @@ -13326,7 +13439,7 @@ SELECT xpath('//mydefns:b/text()', 'test - 示例: + 示例: test', ARRAY[ARRAY['my', 'http://example.com']]); @@ -13378,8 +13491,8 @@ SELECT xpath_exists('/my:a/text()', 'test - document_expression提供了上下文。row_expression的项。 - 它必须是一个格式良好的XML文档;不接受片段/森林。BY REFBY VALUE子句 如上文所讨论的那样,被接受但被忽略了,正如在中所讨论的。 + document_expressionrow_expression提供上下文项。 + 它必须是一个良构的 XML 文档;不接受内容片段或森林。BY REFBY VALUE子句会被接受,但会被忽略,如中所述。 @@ -13428,7 +13541,7 @@ SELECT xpath_exists('/my:a/text()', 'test - 一个XML元素的字符串值是字符串值的协整,按文档的顺序。该元素中包含的所有文本节点及其子节点。字符串 元素的值是一个没有下级文本节点的元素的值是一个 空字符串(不是NULL)。任何xsi:nil属性都会被忽略。请注意,两个非文本之间的text()节点只用空格,而两个非文本 元素,并且保留了text()上的前导白格。节点不被扁平化。XPath 1.0中的string函数可以参考XPath 1.0中的 定义其他XML节点类型和非XML值的字符串值的规则。 + 一个 XML 元素的字符串值,是该元素及其所有后代中包含的文本节点按文档顺序拼接而成的字符串。没有后代文本节点的元素,其字符串值为空字符串(不是 NULL)。所有 xsi:nil 属性都会被忽略。注意,两个非文本元素之间仅含空白的 text() 节点会被保留,text() 节点的前导空白也不会被折叠。其他 XML 节点类型及非 XML 值的字符串值定义规则,可参考 XPath 1.0 的 string 函数。 @@ -13448,7 +13561,7 @@ SELECT xpath_exists('/my:a/text()', 'test - 示例: + 示例: - 下面的示例展示了多个text()节点的连接,列名作为XPath过滤器的使用,以及对空格、XML注释和处理指令的处理: + 下面的示例展示了多个text()节点的连接,列名作为XPath过滤器的使用,以及对空格、XML注释和处理指令的处理: JSON 函数和操作符 + + SQL/JSON + 函数和表达式 + - 本节描述: + 本节描述: @@ -13784,14 +13901,50 @@ table2-mapping - SQL/JSON路径语言 + SQL/JSON 路径语言 + + + + + SQL/JSON 查询函数 - 要了解有关SQL/JSON标准的更多信息,请参阅。有关PostgreSQL中支持的JSON类型的详细信息,见 。 + 为了在 SQL 环境中为 JSON 数据类型提供原生支持,PostgreSQL 实现了 + SQL/JSON 数据模型。该模型由项序列组成。每个项可以保存 SQL 标量值, + 以及额外的 SQL/JSON null 值,还可以保存使用 JSON 数组和对象的复合数据结构。该模型是 JSON 规范 + RFC 7159 中隐含数据模型的形式化表示。 + + + + SQL/JSON 允许你将 JSON 数据与常规 SQL 数据一同处理,并提供事务支持,包括: + + + + + 将 JSON 数据上传到数据库,并将其作为字符或二进制字符串存储在常规 SQL 列中。 + + + + + 从关系数据生成 JSON 对象和数组。 + + + + + 使用 SQL/JSON 查询函数和 SQL/JSON 路径语言表达式查询 JSON 数据。 + + + + + + + 要了解有关 SQL/JSON 标准的更多信息,请参阅。有关 + PostgreSQL 中支持的 JSON 类型的详细信息,见 + @@ -13946,14 +14099,13 @@ table2-mapping - 如果JSON输入没有匹配请求的正确结构,字段/元素/路径提取操作符返回NULL,而不是失败;例如,如果不存在这样的键或数组元素。 + 如果 JSON 输入没有匹配请求的正确结构,字段/元素/路径提取操作符会返回 NULL,而不是失败;例如,如果不存在这样的键或数组元素。 - 还有一些操作符仅适用于jsonb,如表所示。 - 第描述了如何使用这些操作符来有效地搜索索引的jsonb数据。 - + 还有一些操作符仅适用于jsonb,如所示。介绍了如何使用这些操作符有效地搜索已建立索引的jsonb数据。 + @@ -14028,7 +14180,7 @@ table2-mapping boolean - 文本数组中的字符串是否作为顶级键或数组元素存在? + 文本数组中的任一字符串是否作为顶级键或数组元素存在? '{"a":1, "b":2, "c":3}'::jsonb ?| array['b', 'd'] @@ -14060,7 +14212,7 @@ table2-mapping 连接两个数组将生成一个包含每个输入的所有元素的数组。 连接两个对象将生成一个包含它们键的并集的对象,当存在重复的键时取第二个对象的值。 所有其他情况都通过将非数组输入转换为单元素数组来处理,然后按照两个数组的方式进行处理。 - 不递归操作:只有顶级数组或对象结构被合并。 + 不递归操作:只有顶级数组或对象结构会被合并。 '["a", "b"]'::jsonb || '["a", "d"]'::jsonb @@ -14079,7 +14231,7 @@ table2-mapping [{"a": "b"}, 42] - 要将一个数组作为单个条目附加到另一个数组中,请将其包装在另一个数组附加层中,例如: + 要将一个数组作为单个元素追加到另一个数组中,请先在它外面再包装一层数组,例如: '[1, 2]'::jsonb || jsonb_build_array('[3, 4]'::jsonb) @@ -14153,7 +14305,7 @@ table2-mapping boolean - JSON路径是否为指定的JSON值返回任何项? + JSON 路径是否为指定的 JSON 值返回任何项?(这只适用于 SQL 标准 JSON 路径表达式,不适用于谓词检查表达式,因为后者总是返回一个值。) '{"a":[1,2,3,4,5]}'::jsonb @? '$.a[*] ? (@ > 2)' @@ -14167,7 +14319,7 @@ table2-mapping boolean - 返回指定JSON值的JSON路径谓词检查的结果。只考虑结果的第一项。如果结果不是布尔值,则返回NULL。 + 返回对指定 JSON 值进行 JSON 路径谓词检查的结果。(这只适用于谓词检查表达式,不适用于 SQL 标准 JSON 路径表达式,因为如果路径结果不是单个布尔值,就会返回NULL。) '{"a":[1,2,3,4,5]}'::jsonb @@ '$.a[*] > 2' @@ -14181,15 +14333,13 @@ table2-mapping - jsonpath操作符@?@@抑制以下错误:缺少对象字段或数组元素,意外的JSON项目类型,日期时间和数字错误。 - 还可以告诉以下描述的与jsonpath相关的函数来抑制这些类型的错误。 - 在搜索不同结构的JSON文档集合时,此行为可能会有所帮助。 + jsonpath操作符@?@@会抑制以下错误:缺少对象字段或数组元素、JSON 项类型不符合预期,以及日期时间和数值错误。下文介绍的jsonpath相关函数也可以设置为抑制这些类型的错误。在搜索结构各异的 JSON 文档集合时,这一行为可能很有用。 - 显示可用于构造jsonjsonb值的函数。 - + 列出了可用于构造jsonjsonb值的函数。表中的某些函数具有RETURNING子句,用于指定返回的数据类型。该类型必须是jsonjsonbbytea、字符串类型(textcharvarchar),或者可以转换为json的类型。默认返回json类型。 +
@@ -14228,14 +14378,14 @@ table2-mapping jsonb - 将任何SQL值转换为jsonjsonb。数组和组合递归地转换为数组和对象(多维数组在JSON中变成数组的数组)。 - 否则,如果存在从SQL数据类型到json的类型转换,则类型转换函数将用于执行转换; + 将任何SQL值转换为jsonjsonb。数组和复合值递归地转换为数组和对象(多维数组在JSON中变成数组的数组)。 + 否则,如果存在从SQL数据类型到json的类型转换,则类型转换函数将用于执行转换; - 例如,扩展有一个从hstorejson的转换,这样通过json创建函数转换的hstore值将被表示为json对象,而不是原始字符串值 + 例如,扩展有一个从hstorejson的类型转换,因此通过 JSON 创建函数转换的hstore值将表示为 JSON 对象,而不是基本的字符串值。 - 否则,将生成一个标量json值。对于除数字、布尔值或空值之外的任何标量,将使用文本表示,并根据需要进行转义,使其成为有效的JSON字符串值。 + 否则,将生成一个标量 JSON 值。对于除数字、布尔值或空值之外的任何标量,将使用文本表示,并根据需要进行转义,使其成为有效的JSON字符串值。 to_json('Fred said "Hi."'::text) @@ -14243,7 +14393,7 @@ table2-mapping to_jsonb(row(42, 'Fred said "Hi."'::text)) - {"f1":42,"f2":"Fred said \"Hi.\""} + {"f1": 42, "f2": "Fred said \"Hi.\""} @@ -14264,6 +14414,39 @@ table2-mapping + + + + json_array + json_array ( + { value_expression FORMAT JSON } , ... + { NULL | ABSENT } ON NULL + RETURNING data_type FORMAT JSON ENCODING UTF8 ) + + + json_array ( + query_expression + RETURNING data_type FORMAT JSON ENCODING UTF8 ) + + + 从一系列value_expression参数或query_expression的结果构造 JSON 数组;后者必须是返回单列的 SELECT 查询。如果指定了ABSENT ON NULL,则忽略 NULL 值。使用query_expression时始终如此。 + + + json_array(1,true,json '{"a":null}') + [1, true, {"a":null}] + + + json_array(SELECT * FROM (VALUES(1),(2)) t) + [1, 2] + + + @@ -14273,7 +14456,7 @@ table2-mapping json - 将SQL组合值转换为JSON对象。该行为与to_json相同,只是如果可选boolean参数为真,换行符将在顶级元素之间添加。 + 将SQL 复合值转换为JSON对象。该行为与to_json相同,只是如果可选boolean参数为真,换行符将在顶级元素之间添加。 row_to_json(row(1,'foo')) @@ -14322,7 +14505,7 @@ table2-mapping 根据可变参数列表构建一个JSON对象。按照惯例,参数列表由交替的键和值组成。 - 关键参数强制转换为文本;值参数按照to_jsonto_jsonb进行转换。 + 键参数会被强制转换为文本;值参数则按照to_jsonto_jsonb进行转换。 json_build_object('foo', 1, 2, row(3,'bar')) @@ -14330,6 +14513,25 @@ table2-mapping + + + json_object + json_object ( + { key_expression { VALUE | ':' } + value_expression FORMAT JSON ENCODING UTF8 }, ... + { NULL | ABSENT } ON NULL + { WITH | WITHOUT } UNIQUE KEYS + RETURNING data_type FORMAT JSON ENCODING UTF8 ) + + + 根据给定的所有键值对构造 JSON 对象;如果没有给出键值对,则构造空对象。key_expression是定义JSON键的标量表达式,会被转换为text类型。它不能为NULL,其类型也不能具有到json的类型转换。如果指定了WITH UNIQUE KEYS,则key_expression不能重复。如果指定了ABSENT ON NULL,则value_expression求值为NULL的键值对会从输出中省略;如果指定了NULL ON NULL或省略了该子句,则保留该键,并将其值设为NULL。 + + + json_object('code' VALUE 'P123', 'title': 'Jaws') + {"code" : "P123", "title" : "Jaws"} + + + @@ -14346,8 +14548,7 @@ table2-mapping jsonb - 从文本数组构建JSON对象。该数组必须有两个维度,一个维度的成员数为偶数,在这种情况下,它们被视为交替的键/值对; - 另一个维度的成员数为二维,每个内部数组恰好有两个元素,它们被视为键/值对。所有值都转换为JSON字符串。 + 从文本数组构造 JSON 对象。该数组必须是一维且包含偶数个成员,此时将成员按交替的键/值对处理;或者是二维数组,且每个内部数组恰好有两个元素,将这两个元素作为一个键/值对。所有值都转换为 JSON 字符串。 json_object('{a, 1, b, "def", c, 3.5}') @@ -14368,17 +14569,144 @@ table2-mapping jsonb - 这种形式的json_object从单独的文本数组中成对地获取键和值。否则,它与单参数形式相同。 + 这种形式的json_object从单独的文本数组中成对地获取键和值。除此之外,它与单参数形式相同。 json_object('{a,b}', '{1,2}') {"a": "1", "b": "2"} + + + + json 构造器 + json ( + expression + FORMAT JSON ENCODING UTF8 + { WITH | WITHOUT } UNIQUE KEYS ) + json + + + 将给定的textbytea字符串表达式(采用 UTF8 编码)转换为 JSON 值。如果expression为 NULL,则返回SQL空值。如果指定了WITH UNIQUE,则expression不能包含重复的对象键。 + + + json('{"a":123, "b":[true,"foo"], "a":"bar"}') + {"a":123, "b":[true,"foo"], "a":"bar"} + + + + + + + json_scalar + json_scalar ( expression ) + + + 将给定的 SQL 标量值转换为 JSON 标量值。如果输入为 NULL,则返回SQL空值。如果输入是数字或布尔值,则返回相应的 JSON 数字或布尔值。对于其他值,则返回 JSON 字符串。 + + + json_scalar(123.45) + 123.45 + + + json_scalar(CURRENT_TIMESTAMP) + "2022-05-10T10:51:04.62128-04:00" + + + + + + json_serialize ( + expression FORMAT JSON ENCODING UTF8 + RETURNING data_type FORMAT JSON ENCODING UTF8 ) + + + 将 SQL/JSON 表达式转换为字符或二进制字符串。expression可以是任意 JSON 类型、任意字符串类型,或采用 UTF8 编码的bytea RETURNING中使用的返回类型可以是任意字符串类型或bytea,默认为text。 + + + json_serialize('{ "a" : 1 } ' RETURNING bytea) + \x7b20226122203a2031207d20 + +
+ + 详细介绍了用于测试 JSON 的 SQL/JSON 功能。 + + + + SQL/JSON 测试函数 + + + + + 函数签名 + + + 描述 + + + 示例 + + + + + + + IS JSON + expression IS NOT JSON + { VALUE | SCALAR | ARRAY | OBJECT } + { WITH | WITHOUT } UNIQUE KEYS + + + 该谓词测试 expression 是否可以解析为 JSON,也可以指定具体类型。 + 如果指定 SCALARARRAYOBJECT, + 则测试 JSON 是否属于该特定类型。如果指定 WITH UNIQUE KEYS, + 则 expression 中的任意对象还会被检查是否存在重复键。 + + + +SELECT js, + js IS JSON "json?", + js IS JSON SCALAR "scalar?", + js IS JSON OBJECT "object?", + js IS JSON ARRAY "array?" +FROM (VALUES + ('123'), ('"abc"'), ('{"a": "b"}'), ('[1,2]'),('abc')) foo(js); + js | json? | scalar? | object? | array? +------------+-------+---------+---------+-------- + 123 | t | t | f | f + "abc" | t | t | f | f + {"a": "b"} | t | f | t | f + [1,2] | t | f | f | t + abc | f | f | f | f + + + + +SELECT js, + js IS JSON OBJECT "object?", + js IS JSON ARRAY "array?", + js IS JSON ARRAY WITH UNIQUE KEYS "array w. UK?", + js IS JSON ARRAY WITHOUT UNIQUE KEYS "array w/o UK?" +FROM (VALUES ('[{"a":"1"}, + {"b":"2","b":"3"}]')) foo(js); +-[ RECORD 1 ]-+-------------------- +js | [{"a":"1"}, + + | {"b":"2","b":"3"}] +object? | f +array? | t +array w. UK? | f +array w/o UK? | t + + + + + +
+ 显示可用于处理jsonjsonb值的函数。 @@ -14655,48 +14983,48 @@ table2-mapping anyelement
- 将顶级 JSON 对象展开为具有 base 参数复合类型的行。JSON 对象将被扫描,查找名称与输出行类型列名匹配的字段,并将其值插入到输出行的对应列中。 - (不对应任何输出列名的字段将被忽略。)在典型用法中,base 的值仅为 NULL,这意味着任何不匹配对象字段的输出列都会被填充为 null。 - 但是,如果base不为NULL,那么它包含的值将用于不匹配的列。 + 将顶级 JSON 对象展开为一个行,其复合类型与base参数相同。系统会扫描该 JSON 对象,查找名称与输出行类型列名匹配的字段,并将其值插入输出中的对应列。 + (不对应任何输出列名的字段会被忽略。)在典型用法中,base的值就是NULL,这意味着凡是不匹配对象字段的输出列都会被填充为空值。 + 但是,如果base不是NULL,那么其中包含的值将用于那些不匹配的列。 - 要将JSON值转换为输出列的SQL类型,需要按次序应用以下规则: + 要将 JSON 值转换为输出列的 SQL 类型,需要依次应用以下规则: - 在所有情况下,JSON空值都会转换为SQL空值。 + 在所有情况下,JSON 空值都会转换为 SQL 空值。 - 如果输出列的类型是jsonjsonb,则会精确地重制JSON值。 + 如果输出列的类型是jsonjsonb,则 JSON 值会被原样保留。 - 如果输出列是复合(行)类型,且JSON值是JSON对象,则该对象的字段将转换为输出行类型的列,通过这些规则的递归应用程序。 + 如果输出列是复合(行)类型,且 JSON 值是 JSON 对象,则该对象的字段会通过递归应用这些规则,被转换为输出行类型的各列。 - 同样,如果输出列是数组类型,而JSON值是JSON数组,则通过这些规则的递归应用程序将JSON数组的元素转换为输出数组的元素。 + 同样,如果输出列是数组类型,而 JSON 值是 JSON 数组,则会通过递归应用这些规则,把 JSON 数组的元素转换为输出数组的元素。 - 否则,如果JSON值是字符串,则将字符串的内容提供给输入转换函数,用以确定列的数据类型。 + 否则,如果 JSON 值是字符串,则会把该字符串的内容送入该列数据类型的输入转换函数。 - 否则,JSON值的普通文本表示将被提供给输入转换函数,以确定列的数据类型。 + 否则,JSON 值的普通文本表示会被送入该列数据类型的输入转换函数。 - 虽然下面的示例使用一个常量JSON值,典型的用法是在查询的FROM子句中从另一个表侧面地引用jsonjsonb列。 - 在FROM子句中编写json_populate_record是一种很好的实践,因为提取的所有列都可以使用,而不需要重复的函数调用。 + 虽然下面的示例使用的是常量 JSON 值,但典型用法是在查询的FROM子句中,以横向方式引用另一个表中的jsonjsonb列。 + 把json_populate_record写在FROM子句中是一种良好实践,因为这样抽取出的所有列都可以直接使用,而不需要重复调用函数。 create type subrowtype as (d int, e text); @@ -14714,6 +15042,55 @@ table2-mapping + + + + jsonb_populate_record_valid + + jsonb_populate_record_valid ( base anyelement, from_json json ) + boolean + + + 用于测试jsonb_populate_record的函数。对于给定的输入 JSON 对象,如果jsonb_populate_record能够无错误地完成,即该输入有效,则返回true;否则返回false。 + + + create type jsb_char2 as (a char(2)); + + + select jsonb_populate_record_valid(NULL::jsb_char2, '{"a": "aaa"}'); + + + jsonb_populate_record_valid +----------------------------- + f +(1 row) + + + select * from jsonb_populate_record(NULL::jsb_char2, '{"a": "aaa"}') q; + + +ERROR: value too long for type character(2) + + select jsonb_populate_record_valid(NULL::jsb_char2, '{"a": "aa"}'); + + + jsonb_populate_record_valid +----------------------------- + t +(1 row) + + + select * from jsonb_populate_record(NULL::jsb_char2, '{"a": "aa"}') q; + + + a +---- + aa +(1 row) + + + + @@ -14730,8 +15107,7 @@ table2-mapping setof anyelement - 将对象的顶级 JSON 数组展开为一组具有 base 参数复合类型的行。 - 对于json[b]_populate_record,将如上所述处理JSON数组的每个元素。 + 将由对象组成的顶级 JSON 数组展开为一组行,其复合类型与base参数相同。JSON 数组中的每个元素都按照上文对json[b]_populate_record的说明进行处理。 create type twoints as (a int, b int); @@ -14800,8 +15176,8 @@ table2-mapping 将顶级JSON对象数组展开为一组由AS子句定义的复合类型的行。 - (与所有返回record的函数一样,调用查询必须使用AS子句显式定义记录的结构。) - 对于json[b]_populate_record,将如上所述处理JSON数组的每个元素。 + (与所有返回record的函数一样,调用查询必须使用AS子句显式定义记录的结构。) + JSON 数组中的每个元素都按照上文对json[b]_populate_record的说明进行处理。 select * from json_to_recordset('[{"a":1,"b":"foo"}, {"a":"2","c":"bar"}]') as x(a int, b text) @@ -14827,7 +15203,7 @@ table2-mapping 返回target,将path指定的项替换为new_value, 如果create_if_missing为真(此为默认值)并且path指定的项不存在,则添加new_value。 路径中的所有前面步骤都必须存在,否则将不加改变地返回target。 - 与面向路径操作符一样,负整数出现在JSON数组末尾的path计数中。 + 与面向路径的操作符一样,path中的负整数从 JSON 数组末尾计数。 如果最后一个路径步骤是超出范围的数组索引,并且create_if_missing为真,那么如果索引为负,新值将添加到数组的开头,如果索引为正,则添加到数组的结尾。 @@ -14874,8 +15250,8 @@ table2-mapping 如果path指派的项是一个数组元素,如果 insert_after为假(此为默认值),则new_value将被插入到该项之前,如果 insert_after为真则在该项之后。 如果由path指派的项是一个对象字段,则只在对象不包含该键时才插入 new_value。 路径中的所有前面步骤都必须存在,否则将不加改变地返回target。 - 与面向路径操作符一样,负整数出现在JSON数组末尾的 path计数中。 - 如果最后一个路径步骤是超出范围的数组下标,则如果下标为负,则将新值添加到数组的开头;如果下标为正,则将新值添加到数组的结尾。 + 与面向路径的操作符一样,path中的负整数从 JSON 数组末尾计数。 + 如果最后一个路径步骤是超出范围的数组下标,那么当下标为负时,新值会被添加到数组开头;当下标为正时,新值会被添加到数组末尾。 jsonb_insert('{"a": [0,1,2]}', '{a, 1}', '"new_value"') @@ -14924,7 +15300,7 @@ table2-mapping boolean - 检查JSON路径是否返回指定JSON值的任何项。如果指定了vars参数,则它必须是一个JSON对象,并且它的字段提供要替换到jsonpath表达式中的名称值。 + 检查 JSON 路径是否为指定的 JSON 值返回任何项。(这只对 SQL 标准 JSON 路径表达式有用,而不适用于谓词检查表达式,因为后者总是返回一个值。)如果指定了vars参数,则它必须是一个 JSON 对象,并且它的字段提供要替换到jsonpath表达式中的具名值。 如果指定了silent参数并为true,函数会抑制与@?@@操作符相同的错误。 @@ -14942,8 +15318,7 @@ table2-mapping boolean - 返回指定JSON值的JSON路径谓词检查的结果。只有结果的第一项被考虑在内。 - 如果结果不是布尔值,则返回NULL。可选的varssilent参数的作用与jsonb_path_exists相同。 + 返回指定 JSON 值的 JSON 路径谓词检查的 SQL 布尔结果。(这只对谓词检查表达式有用,而不适用于 SQL 标准 JSON 路径表达式,因为如果路径结果不是单个布尔值,它将失败或返回NULL。)可选的varssilent参数的作用与jsonb_path_exists相同。 jsonb_path_match('{"a":[1,2,3,4,5]}', 'exists($.a[*] ? (@ >= $min && @ <= $max))', '{"min":2, "max":4}') @@ -14960,7 +15335,7 @@ table2-mapping setof jsonb - 为指定的JSON值返回由JSON路径返回的所有JSON项。可选的varssilent参数的作用与jsonb_path_exists相同。 + 为指定的 JSON 值返回由 JSON 路径返回的所有 JSON 项。对于 SQL 标准 JSON 路径表达式,它返回从target中选出的 JSON 值。对于谓词检查表达式,它返回谓词检查的结果:truefalsenull。可选的varssilent参数的作用与jsonb_path_exists相同。 select * from jsonb_path_query('{"a":[1,2,3,4,5]}', '$.a[*] ? (@ >= $min && @ <= $max)', '{"min":2, "max":4}') @@ -14984,7 +15359,7 @@ table2-mapping jsonb - 以JSON数组的形式返回由JSON路径为指定的JSON值返回的所有JSON项。可选的varssilent参数的作用与jsonb_path_exists相同。 + 以JSON数组的形式返回由JSON路径为指定的JSON值返回的所有JSON项。参数与jsonb_path_query相同。 jsonb_path_query_array('{"a":[1,2,3,4,5]}', '$.a[*] ? (@ >= $min && @ <= $max)', '{"min":2, "max":4}') @@ -15002,7 +15377,7 @@ table2-mapping 为指定的JSON值返回由JSON路径返回的第一个JSON项。如果没有结果则返回NULL。 - 可选的varssilent参数的作用与 jsonb_path_exists相同。 + 参数与jsonb_path_query相同。 jsonb_path_query_first('{"a":[1,2,3,4,5]}', '$.a[*] ? (@ >= $min && @ <= $max)', '{"min":2, "max":4}') @@ -15066,7 +15441,7 @@ table2-mapping text - 将给定的JSON值转换为精美打印的,缩进的文本。 + 将给定的 JSON 值转换为经过美化并带有缩进的文本。 jsonb_pretty('[{"f1":1,"f2":null}, 2]') @@ -15099,8 +15474,8 @@ table2-mapping text - 以文本字符串形式返回顶级JSON值的类型。可能的类型有object, array,string, number,boolean, 和 null。 - (null的结果不应该与SQL NULL 混淆;参见示例。) + 以文本字符串形式返回顶级JSON值的类型。可能的类型有objectarraystringnumberbooleannull。 + (null 的结果不应与 SQL NULL 混淆;参见示例。) json_typeof('-123.4') @@ -15129,14 +15504,15 @@ table2-mapping - SQL/JSON路径表达式指定了要从JSON数据中检索的项目,类似于SQL访问XML时使用的XPath表达式。 + SQL/JSON路径表达式指定了要从JSON数据中检索的项,类似于访问 XML 内容时使用的 XPath 表达式。 在PostgreSQL中,路径表达式作为jsonpath数据类型实现,可以使用中描述的任何元素。 JSON 查询函数和操作符会将给定的路径表达式传递给路径引擎进行求值。 如果表达式与被查询的JSON数据匹配,则返回相应的JSON项或项集。 - 路径表达式是用SQL/JSON路径语言编写的,也可以包括算术表达式和函数。 + 如果没有匹配项,则根据所用函数返回NULLfalse或抛出错误。 + 路径表达式是用SQL/JSON路径语言编写的,也可以包括算术表达式和函数。 @@ -15145,15 +15521,13 @@ table2-mapping - 要引用正在查询的JSON值(context item项),在路径表达式中使用$变量。 - 它后面可以跟着一个或多个accessor operators,这些操作符在JSON结构中逐级向下检索上下文项的子项。 - 后面的每个操作符处理前一个求值步骤的结果。 - + 要引用正在查询的 JSON 值(上下文项),请在路径表达式中使用$变量。路径的第一个元素必须始终是$。它后面可以跟一个或多个访问操作符,沿 JSON 结构逐层向下获取上下文项的子项。每个访问操作符都处理上一步求值的结果,为每个输入项产生零个、一个或多个输出项。 + - 例如,假设你有一些你想要解析的来自GPS跟踪器的JSON数据,例如: + 例如,假设你有一些来自 GPS 跟踪器、想要解析的 JSON 数据,如下所示: -{ +SELECT '{ "track": { "segments": [ { @@ -15168,54 +15542,68 @@ table2-mapping } ] } -} +}' AS json \gset - + (可以将上述示例复制粘贴到psql中,为后续示例做好准备。此后,psql会将:'json'展开为一个包含该 JSON 值、且已正确加上引号的字符串常量。) +
- 为了检索可用的轨迹段,你需要使用.key访问操作符来向下浏览周边的JSON对象: - -$.track.segments - + 要获取可用的轨迹段,需要使用.key访问操作符,逐层访问外围的 JSON 对象: + +=> select jsonb_path_query(:'json', '$.track.segments'); + jsonb_path_query +-----------------------------------------------------------&zwsp;-----------------------------------------------------------&zwsp;--------------------------------------------- + [{"HR": 73, "location": [47.763, 13.4034], "start time": "2018-10-14 10:05:14"}, {"HR": 135, "location": [47.706, 13.2635], "start time": "2018-10-14 10:39:21"}] + - 要检索数组的内容,通常使用[*]操作符。例如,下面的路径将返回所有可用轨道段的位置坐标: - -$.track.segments[*].location - + 要检索数组的内容,通常使用[*]操作符。例如,下面的路径将返回所有可用轨迹段的位置坐标: + +=> select jsonb_path_query(:'json', '$.track.segments[*].location'); + jsonb_path_query +------------------- + [47.763, 13.4034] + [47.706, 13.2635] + + + 这里从整个 JSON 输入值($)开始,随后 .track 访问器选择与对象键 "track" 关联的 JSON 对象,.segments 访问器再选择该对象中与键 "segments" 关联的 JSON 数组,[*] 访问器接着选择该数组的每个元素(产生一系列项),最后 .location 访问器选择这些对象中分别与键 "location" 关联的 JSON 数组。在这个示例中,每个对象都有一个 "location" 键;如果某个对象没有这个键,.location 访问器就不会为该输入项产生任何输出。 - 要只返回第一个段的坐标,可以在[]访问操作符中指定相应的下标。重新调用相对于0的JSON数组索引: - -$.track.segments[0].location - + 要只返回第一个段的坐标,可以在[]访问操作符中指定相应的下标。请记住,JSON数组索引从 0 开始: + +=> select jsonb_path_query(:'json', '$.track.segments[0].location'); + jsonb_path_query +------------------- + [47.763, 13.4034] + 每个路径求值步骤的结果可以由中列出的一个或多个jsonpath操作符和方法来处理。 - 每个方法名之前必须有一个点。例如,你可以得到一个数组的大小: - -$.track.segments.size() - + 每个方法名之前必须有一个点。例如,你可以得到一个数组的大小: + +=> select jsonb_path_query(:'json', '$.track.segments.size()'); + jsonb_path_query +------------------ + 2 + 在路径表达式中使用jsonpath操作符和方法的更多示例见下面 - 在定义路径时,还可以使用一个或多个与SQL中的WHERE子句类似的filter expressions。 - 过滤器表达式以问号开头,并在圆括号中提供条件: - - + 路径还可以包含过滤表达式,其作用类似于 SQL 中的WHERE子句。过滤表达式以问号开头,并在圆括号中提供条件: + ? (condition) - - + +
- 过滤表达式必须在它们应该应用的路径求值步骤之后写入。该步骤的结果将被筛选,以只包括满足所提供条件的那些项。 + 过滤表达式必须在它们应该应用的路径求值步骤之后指定。该步骤的结果会经过过滤,只保留满足给定条件的项。 SQL/JSON定义了三值逻辑,因此条件可以是 true, false,或 unknownunknown值发挥与SQL NULL相同的角色,可以使用is unknown谓词进行测试。 - 进一步的路径求值步骤只使用筛选器表达式返回true的那些项。 + 进一步的路径求值步骤只使用过滤表达式返回true的那些项。 @@ -15224,40 +15612,54 @@ $.track.segments.size() - 例如,假设你想要检索所有高于130的心率值。你可以使用下面的表达式来实现这一点: - -$.track.segments[*].HR ? (@ > 130) - + 例如,假设你想要检索所有高于130的心率值。你可以使用下面的表达式来实现这一点: + +=> select jsonb_path_query(:'json', '$.track.segments[*].HR ? (@ > 130)'); + jsonb_path_query +------------------ + 135 + - 为了获得具有这些值的片段的开始时间,必须在返回开始时间之前过滤掉不相关的片段,所以过滤表达式应用于上一步,条件中使用的路径不同: - -$.track.segments[*] ? (@.HR > 130)."start time" - + 为了获得具有这些值的轨迹段的开始时间,必须先过滤掉不相关的轨迹段,再返回开始时间。因此,过滤表达式应用于上一步,条件中使用的路径也不同: + +=> select jsonb_path_query(:'json', '$.track.segments[*] ? (@.HR > 130)."start time"'); + jsonb_path_query +----------------------- + "2018-10-14 10:39:21" + - 如果需要,可以按顺序使用几个过滤器表达式。例如,下面的表达式选择所有包含有相关坐标和高心率值的位置的段的开始时间: - -$.track.segments[*] ? (@.location[1] < 13.4) ? (@.HR > 130)."start time" - + 如有需要,可以依次使用多个过滤表达式。例如,下面的表达式选择位置坐标符合要求且心率较高的所有轨迹段的开始时间: + +=> select jsonb_path_query(:'json', '$.track.segments[*] ? (@.location[1] < 13.4) ? (@.HR > 130)."start time"'); + jsonb_path_query +----------------------- + "2018-10-14 10:39:21" + - 也允许在不同嵌套层级中使用过滤器表达式。下面的示例首先根据位置筛选所有的片段,然后返回这些片段的高心率值,如果适用的话: - -$.track.segments[*] ? (@.location[1] < 13.4).HR ? (@ > 130) - + 也可以在不同嵌套层级使用过滤表达式。下面的示例先按位置筛选所有轨迹段,再返回这些轨迹段中的高心率值(如果存在): + +=> select jsonb_path_query(:'json', '$.track.segments[*] ? (@.location[1] < 13.4).HR ? (@ > 130)'); + jsonb_path_query +------------------ + 135 + - 你也可以在彼此之间嵌套过滤器表达式: - -$.track ? (exists(@.segments[*] ? (@.HR > 130))).segments.size() - - 如果包含任何具有高心率值的片段,则该表达式返回曲目的大小,否则返回空序列。 - + 还可以将过滤表达式相互嵌套。如果轨迹包含任何具有高心率值的轨迹段,下面的示例返回轨迹的大小,否则返回空序列: + +=> select jsonb_path_query(:'json', '$.track ? (exists(@.segments[*] ? (@.HR > 130))).segments.size()'); + jsonb_path_query +------------------ + 2 + +
与 SQL 标准的偏差 @@ -15306,74 +15708,120 @@ $.track ? (exists(@.segments[*] ? (@.HR > 130))).segments.size() 当查询JSON数据时,路径表达式可能与实际的JSON数据结构不匹配。 - 试图访问不存在的对象成员或数组元素会导致结构错误。SQL/JSON路径表达式有两种处理结构错误的模式: + 试图访问不存在的对象成员或数组元素会导致结构错误。SQL/JSON路径表达式有两种处理结构错误的模式: - 不严格的(lax)(默认)—路径引擎隐式地将查询的数据适配到指定的路径。任何剩余的结构错误都将被抑制并转换为空SQL/JSON序列。 - + 宽松模式(lax,默认)—路径引擎隐式地将被查询的数据适配到指定路径。凡是无法按下文所述方式修复的结构错误都会被抑制,产生的结果是不匹配。 +
- - 严格的(strict) —如果发生了结构错误,则会引发错误。 - + 严格模式(strict)— 如果发生结构错误,就会引发错误。 - 如果JSON数据不符合期望的模式,不严格的(lax)模式有助于匹配JSON文档结构和路径表达式。 - 如果操作不匹配特定操作的要求,可以自动将其包装为SQL/JSON数组,也可以在执行该操作之前将其元素转换为SQL/JSON序列来解包装。 - 此外,比较操作符会自动以lax模式打开它们的操作数,因此你可以开包即用的就能比较SQL/JSON数组。 - 大小为1的数组被认为等于它的唯一元素。只有在以下情况下才不会自动展开: + 如果 JSON 数据不符合预期模式,宽松模式有助于使 JSON 文档结构与路径表达式相匹配。如果操作数不满足某个操作的要求,可以在执行该操作之前自动将其包装为 SQL/JSON 数组,或通过将其元素转换为 SQL/JSON 序列来解包。此外,在宽松模式下,比较操作符会自动解包其操作数,因此可以直接比较 SQL/JSON 数组。大小为 1 的数组被视为等于其唯一元素。以下情况不会自动解包: - 路径表达式包含type()size()方法,它们分别返回数组中的元素类型和数量。 + 路径表达式包含type()size()方法,它们分别返回类型和数组中的元素数量。 - 查询的JSON数据包含嵌套的数组。在本例中,只有最外层的数组被打开,而所有内部数组保持不变。 - 因此,隐式展开在每个路径求值步骤中只能向下进行一级。 + 查询的JSON数据包含嵌套的数组。在本例中,只有最外层的数组被解包,而所有内部数组保持不变。 + 因此,隐式解包在每个路径求值步骤中只能向下进行一级。 - 例如,当查询上面列出的GPS数据时,当使用不严格的(lax)模式时,你可以从它存储了一组片段的事实中抽象出来: - -lax $.track.segments.location - + 例如,查询上面列出的GPS数据时,使用宽松模式就无需关注轨迹段存储在数组中这一细节: + +=> select jsonb_path_query(:'json', 'lax $.track.segments.location'); + jsonb_path_query +------------------- + [47.763, 13.4034] + [47.706, 13.2635] + - 在严格的(strict)模式中,指定的路径必须与查询的JSON文档的结构完全匹配才能返回SQL/JSON项,因此使用该路径表达式会导致错误。 - 要得到与不严格的(lax)模式相同的结果,你必须显式地打开segments数组: - -strict $.track.segments[*].location - + 在严格模式下,指定的路径必须与查询的JSON文档的结构完全匹配,因此使用该路径表达式会导致错误。 + +=> select jsonb_path_query(:'json', 'strict $.track.segments.location'); +ERROR: jsonpath member accessor can only be applied to an object + + 要得到与宽松模式相同的结果,你必须显式地解包segments数组: + +=> select jsonb_path_query(:'json', 'strict $.track.segments[*].location'); + jsonb_path_query +------------------- + [47.763, 13.4034] + [47.706, 13.2635] + - .**访问器在使用lax模式时可能导致令人惊讶的结果。 - 例如,下面的查询选择每个HR值两次: - -lax $.**.HR - - 发生这个,是因为.**访问器会全部选择segments数组和它的每个元素。 - 而当使用lax模式时,.HR访问器会自动打开数组。 + .**访问器在宽松模式下可能产生意外结果。 + 例如,下面的查询选择每个HR值两次: + +=> select jsonb_path_query(:'json', 'lax $.**.HR'); + jsonb_path_query +------------------ + 73 + 135 + 73 + 135 + + 这是因为.**访问器既选择segments数组,又选择它的每个元素。 + 而在宽松模式下,.HR访问器会自动解包数组。 为了避免意外的结果,我们建议仅在严格模式下使用.**访问器。 - 下面的查询选择每个HR值仅一次: - -strict $.**.HR - + 下面的查询选择每个HR值仅一次: + +=> select jsonb_path_query(:'json', 'strict $.**.HR'); + jsonb_path_query +------------------ + 73 + 135 + + + 数组解包也可能产生意外结果。请看下面这个选取所有location数组的示例: + +=> select jsonb_path_query(:'json', 'lax $.track.segments[*].location'); + jsonb_path_query +------------------- + [47.763, 13.4034] + [47.706, 13.2635] +(2 rows) + + 它会如预期那样返回完整数组。但应用过滤表达式时,数组会被解包,以便对每个元素求值,最终只返回匹配该表达式的元素: + +=> select jsonb_path_query(:'json', 'lax $.track.segments[*].location ?(@[*] > 15)'); + jsonb_path_query +------------------ + 47.763 + 47.706 +(2 rows) + + 尽管路径表达式选取的是完整数组,结果仍然如此。使用严格模式可以恢复选取数组的行为: + +=> select jsonb_path_query(:'json', 'strict $.track.segments[*].location ?(@[*] > 15)'); + jsonb_path_query +------------------- + [47.763, 13.4034] + [47.706, 13.2635] +(2 rows) + + @@ -15381,8 +15829,7 @@ strict $.**.HR SQL/JSON 路径操作符和方法 - 显示了jsonpath中可用的操作符和方法。 - 请注意,虽然一元操作符和方法可以应用于由前一个路径步骤产生的多个值,二元操作符(加法等)只能应用于单个值。 + 列出了jsonpath中可用的操作符和方法。请注意,一元操作符和方法可以应用于前一个路径步骤产生的多个值,而二元操作符(加法等)只能应用于单个值。在宽松模式下,对数组应用方法时,会对数组中的每个值执行该方法。例外是.type().size(),它们作用于数组本身。 @@ -15393,228 +15840,442 @@ strict $.**.HR - 操作符/方法 + 操作符/方法 + + + 描述 + + + 示例 + + + + + + + + + number + number + number + + + 加法 + + + jsonb_path_query('[2]', '$[0] + 3') + 5 + + + + + + + number + number + + + 一元加号(无操作);与加法不同,这个可以迭代多个值 + + + jsonb_path_query_array('{"x": [2,3,4]}', '+ $.x') + [2, 3, 4] + + + + + + number - number + number + + + 减法 + + + jsonb_path_query('[2]', '7 - $[0]') + 5 + + + + + + - number + number + + + 取负;与减法不同,可以遍历多个值。 + + + jsonb_path_query_array('{"x": [2,3,4]}', '- $.x') + [-2, -3, -4] + + + + + + number * number + number + + + 乘法 + + + jsonb_path_query('[4]', '2 * $[0]') + 8 + + + + + + number / number + number + + + 除法 + + + jsonb_path_query('[8.5]', '$[0] / 2') + 4.2500000000000000 + + + + + + number % number + number + + + 取模(余数) + + + jsonb_path_query('[32]', '$[0] % 10') + 2 + + + + + + value . type() + string + + + JSON项的类型 (参见 json_typeof) + + + jsonb_path_query_array('[1, "2", {}]', '$[*].type()') + ["number", "string", "object"] + + + + + + value . size() + number + + + JSON项的大小(数组元素的数量,如果不是数组则为1) + + + jsonb_path_query('{"m": [11, 15]}', '$.m.size()') + 2 + + + + + + value . boolean() + boolean + + + 将 JSON 布尔值、数字或字符串转换为布尔值。 + + + jsonb_path_query_array('[1, "yes", false]', '$[*].boolean()') + [true, true, false] + + + + + + value . string() + string + + + 将 JSON 布尔值、数字、字符串或日期时间转换为字符串值。 + + + jsonb_path_query_array('[1.23, "xyz", false]', '$[*].string()') + ["1.23", "xyz", "false"] + + + jsonb_path_query('"2023-08-15 12:34:56"', '$.timestamp().string()') + "2023-08-15T12:34:56" + + + + + + value . double() + number - 描述 + 从JSON数字或字符串转换过来的近似浮点数 - 示例 + jsonb_path_query('{"len": "1.9"}', '$.len.double() * 2') + 3.8 - - - - number + number + number . ceiling() number - 加法 + 大于或等于给定数字的最接近的整数 - jsonb_path_query('[2]', '$[0] + 3') - 5 + jsonb_path_query('{"h": 1.3}', '$.h.ceiling()') + 2 - + number + number . floor() number - 一元加号(无操作);与加法不同,这个可以迭代多个值 + 小于或等于给定数字的最近整数 - jsonb_path_query_array('{"x": [2,3,4]}', '+ $.x') - [2, 3, 4] + jsonb_path_query('{"h": 1.7}', '$.h.floor()') + 1 - number - number + number . abs() number - 减法 + 给定数字的绝对值 - jsonb_path_query('[2]', '7 - $[0]') - 5 + jsonb_path_query('{"z": -0.3}', '$.z.abs()') + 0.3 - - number - number + value . bigint() + bigint - 否定;与减法不同,它可以迭代多个值 + 将 JSON 数字或字符串转换为大整数值。 - jsonb_path_query_array('{"x": [2,3,4]}', '- $.x') - [-2, -3, -4] + jsonb_path_query('{"len": "9876543219"}', '$.len.bigint()') + 9876543219 - number * number - number + value . decimal( [ precision [ , scale ] ] ) + decimal - 乘法 + 将 JSON 数字或字符串转换为经过舍入的十进制数值(precisionscale必须为整数值)。 - jsonb_path_query('[4]', '2 * $[0]') - 8 + jsonb_path_query('1234.5678', '$.decimal(6, 2)') + 1234.57 - number / number - number + value . integer() + integer - 除法 + 将 JSON 数字或字符串转换为整数值。 - jsonb_path_query('[8.5]', '$[0] / 2') - 4.2500000000000000 + jsonb_path_query('{"len": "12345"}', '$.len.integer()') + 12345 - number % number - number + value . number() + numeric - 模数 (余数) + 将 JSON 数字或字符串转换为数值。 - jsonb_path_query('[32]', '$[0] % 10') - 2 + jsonb_path_query('{"len": "123.45"}', '$.len.number()') + 123.45 - value . type() - string + string . datetime() + datetime_type + (见注) - JSON项的类型 (参见 json_typeof) + 从字符串转换过来的日期/时间值 - jsonb_path_query_array('[1, "2", {}]', '$[*].type()') - ["number", "string", "object"] + jsonb_path_query('["2015-8-1", "2015-08-12"]', '$[*] ? (@.datetime() < "2015-08-2".datetime())') + "2015-8-1" - value . size() - number + string . datetime(template) + datetime_type + (见注) - JSON项的大小(数组元素的数量,如果不是数组则为1) + 使用指定的to_timestamp模板从字符串转换过来的日期/时间值 - jsonb_path_query('{"m": [11, 15]}', '$.m.size()') - 2 + jsonb_path_query_array('["12:30", "18:40"]', '$[*].datetime("HH24:MI")') + ["12:30:00", "18:40:00"] - value . double() - number + string . date() + date - 从JSON数字或字符串转换过来的近似浮点数 + 将字符串转换为日期值。 - jsonb_path_query('{"len": "1.9"}', '$.len.double() * 2') - 3.8 + jsonb_path_query('"2023-08-15"', '$.date()') + "2023-08-15" - number . ceiling() - number + string . time() + time without time zone - 大于或等于给定数字的最接近的整数 + 将字符串转换为不带时区的时间值。 - jsonb_path_query('{"h": 1.3}', '$.h.ceiling()') - 2 + jsonb_path_query('"12:34:56"', '$.time()') + "12:34:56" - number . floor() - number + string . time(precision) + time without time zone - 小于或等于给定数字的最近整数 + 将字符串转换为不带时区的时间值,并将秒的小数部分调整到给定精度。 - jsonb_path_query('{"h": 1.7}', '$.h.floor()') - 1 + jsonb_path_query('"12:34:56.789"', '$.time(2)') + "12:34:56.79" - number . abs() - number + string . time_tz() + time with time zone - 给定数字的绝对值 + 将字符串转换为带时区的时间值。 - jsonb_path_query('{"z": -0.3}', '$.z.abs()') - 0.3 + jsonb_path_query('"12:34:56 +05:30"', '$.time_tz()') + "12:34:56+05:30" - string . datetime() - datetime_type - (see note) + string . time_tz(precision) + time with time zone - 从字符串转换过来的日期/时间值 + 将字符串转换为带时区的时间值,并将秒的小数部分调整到给定精度。 - jsonb_path_query('["2015-8-1", "2015-08-12"]', '$[*] ? (@.datetime() < "2015-08-2".datetime())') - "2015-8-1" + jsonb_path_query('"12:34:56.789 +05:30"', '$.time_tz(2)') + "12:34:56.79+05:30" - string . datetime(template) - datetime_type - (see note) + string . timestamp() + timestamp without time zone - 使用指定的to_timestamp模板从字符串转换过来的日期/时间值 + 将字符串转换为不带时区的时间戳值。 - jsonb_path_query_array('["12:30", "18:40"]', '$[*].datetime("HH24:MI")') - ["12:30:00", "18:40:00"] + jsonb_path_query('"2023-08-15 12:34:56"', '$.timestamp()') + "2023-08-15T12:34:56" + + + + + + string . timestamp(precision) + timestamp without time zone + + + 将字符串转换为不带时区的时间戳值,并将秒的小数部分调整到给定精度。 + + + jsonb_path_query('"2023-08-15 12:34:56.789"', '$.timestamp(2)') + "2023-08-15T12:34:56.79" + + + + + + string . timestamp_tz() + timestamp with time zone + + + 将字符串转换为带时区的时间戳值。 + + + jsonb_path_query('"2023-08-15 12:34:56 +05:30"', '$.timestamp_tz()') + "2023-08-15T12:34:56+05:30" + + + + + + string . timestamp_tz(precision) + timestamp with time zone + + + 将字符串转换为带时区的时间戳值,并将秒的小数部分调整到给定精度。 + + + jsonb_path_query('"2023-08-15 12:34:56.789 +05:30"', '$.timestamp_tz(2)') + "2023-08-15T12:34:56.79+05:30" @@ -15644,7 +16305,7 @@ strict $.**.HR datetime()方法依次尝试将其输入字符串与date, timetz, time,timestamptz, 和 timestamp的ISO格式进行匹配。 - 它在第一个匹配格式时停止,并发出相应的数据类型。 + 它在第一个匹配格式时停止,并返回相应数据类型的值。 @@ -15652,26 +16313,26 @@ strict $.**.HR - datetime()datetime(template)方法使用与to_timestamp SQL函数相同的解析规则(see ),但有三个例外。 + datetime()datetime(template)方法使用与to_timestamp SQL函数相同的解析规则(参见),但有三个例外。 首先,这些方法不允许不匹配的模板模式。 - 其次,模板字符串中只允许以下分隔符:减号、句点、solidus(斜杠)、逗号、撇号、分号、冒号和空格。 + 其次,模板字符串中只允许以下分隔符:减号、句点、斜杠、逗号、撇号、分号、冒号和空格。 第三,模板字符串中的分隔符必须与输入字符串完全匹配。 - 如果需要比较不同的日期/时间类型,则应用隐式转换。 + 如果需要比较不同的日期/时间类型,则应用隐式类型转换。 date值可以转换为timestamptimestamptz, timestamp可以转换为timestamptz, time可以转换为timetz。 - 但是,除了第一个转换外,其他所有转换都依赖于当前设置,因此只能在时区感知的jsonpath函数中执行。 + 但是,除了第一个转换外,其他所有转换都依赖于当前设置,因此只能在时区感知的jsonpath函数中执行。类似地,其他将字符串转换为日期/时间类型的日期/时间相关方法也会进行这种转换,这可能涉及当前的设置。因此,这些转换同样只能在时区感知的jsonpath函数中执行。 - 显示了适用的过滤器表达式元素。 + 显示了可用的过滤表达式元素。
- <type>jsonpath</type> 过滤器表达式元素 + <type>jsonpath</type> 过滤表达式元素 @@ -15820,7 +16481,7 @@ strict $.**.HR value - JSON常数null(注意,与SQL不同,与null比较可以正常工作) + JSON 常量null(注意,与SQL不同,与null比较可以正常工作) jsonb_path_query('[{"name": "Mary", "job": null}, {"name": "Michael", "job": "driver"}]', '$[*] ? (@.job == null) .name') @@ -15890,7 +16551,7 @@ strict $.**.HR boolean - 测试第一个操作数是否与第二个操作数给出的正则表达式匹配,可选使用由一串flag字符描述的修改(参见)。 + 测试第一个操作数是否与第二个操作数给出的正则表达式匹配;可以用一串flag标志字符调整匹配行为(参见)。 jsonb_path_query_array('["abc", "abd", "aBdC", "abdacb", "babc"]', '$[*] ? (@ like_regex "^ab.*c")') @@ -15946,31 +16607,28 @@ strict $.**.HR LIKE_REGEX - in SQL/JSON + 用于 SQL/JSON - - SQL/JSON路径表达式允许通过like_regex过滤器将文本匹配为正则表达式。 - 例如,下面的SQL/JSON路径查询将不区分大小写地匹配以英语元音开头的数组中的所有字符串: - + SQL/JSON 路径表达式允许使用like_regex过滤器,将文本与正则表达式进行匹配。例如,以下 SQL/JSON 路径查询会以不区分大小写的方式,匹配数组中所有以英语元音字母开头的字符串: $[*] ? (@ like_regex "^[aeiou]" flag "i") - 可选的flag字符串可以包括一个或多个字符i用于不区分大小写的匹配,m允许^$在换行时匹配,s允许.匹配换行符,q引用整个模式(将行为简化为一个简单的子字符串匹配)。 + 可选的flag字符串可以包括一个或多个字符i用于不区分大小写的匹配,m允许^$在换行时匹配,s允许.匹配换行符,q将整个模式按字面量处理(将行为简化为一个简单的子字符串匹配)。 SQL/JSON标准借用了来自LIKE_REGEX操作符的正则表达式定义,其使用了XQuery标准。 PostgreSQL目前不支持LIKE_REGEX操作符。因此,like_regex过滤器是使用中描述的POSIX正则表达式引擎来实现的。 - 这导致了与标准SQL/JSON行为的各种细微差异,这在中进行了分类。 - 但是请注意,这里描述的标志字母不兼容并不适用于SQL/JSON,因为它将XQuery标志字母翻译为符合POSIX引擎的预期。 + 这导致了与标准SQL/JSON行为的各种细微差异,这些差异列在中。 + 但是请注意,这里描述的标志字母不兼容并不适用于SQL/JSON,因为 SQL/JSON 会将 XQuery 标志字母转换为 POSIX 引擎所预期的形式。 - 请记住,like_regex的模式参数是一个JSON路径字符串文字,根据给出的规则编写。 - 这特别意味着在正则表达式中要使用的任何反斜杠都必须加倍。例如,匹配只包含数字的根文档的字符串值: + 请记住,like_regex的模式参数是一个JSON 路径字符串字面量,根据给出的规则编写。 + 这特别意味着在正则表达式中要使用的任何反斜杠都必须加倍。例如,匹配根文档中仅包含数字的字符串值: $.* ? (@ like_regex "^\\d+$") @@ -16290,18 +16948,18 @@ DETAIL: Missing "]" after array dimensions. 列。这些列可以通过一个看起来与顶层 COLUMNS 子句类似的 COLUMNS 子句来指定。由 NESTED COLUMNS 构造的行称为子行,它们会与父 - COLUMNS 子句中指定的列所构造的行联接, + COLUMNS 子句中指定的列所构造的行连接, 从而得到最终视图中的行。子列自身也可以包含 NESTED PATH 说明,因此可以提取位于任意嵌套层级中的数据。 在同一层级上由多个 NESTED PATH 生成的列彼此视为 - 兄弟,它们在与父行联接后的行通过 + 兄弟,它们在与父行连接后的行通过 UNION 进行组合。 - 由 JSON_TABLE 生成的行会与生成它们的行进行横向联接, + 由 JSON_TABLE 生成的行会与生成它们的行进行横向连接, 因此你无需显式地将构造出来的视图与保存 JSON - 数据的原始表进行联接。 + 数据的原始表进行连接。 @@ -16439,9 +17097,8 @@ JSON_TABLE ( 该值对应于将 PATH 表达式应用到行模式后是否产生任何值。 - 指定的 type 应当具有从 - boolean 类型进行强制转换的能力。 - + 应当存在从boolean到指定type的类型转换。 + 你还可以选择使用 ON ERROR 来指定: 当 JSON 路径求值期间发生错误,或者将 SQL/JSON 值强制转换为指定类型时发生错误时, @@ -16613,7 +17270,7 @@ SELECT jt.* FROM 下面是在上述查询基础上的修改版本,用来展示如何使用 NESTED PATH 填充 title 和 director - 列,并说明它们如何与父列 id 和 kind 联接: + 列,并说明它们如何与父列 id 和 kind 连接: SELECT jt.* FROM @@ -16670,7 +17327,7 @@ SELECT jt.* FROM 下面展示了另一个以不同 JSON 对象作为输入的查询。它展示了 NESTED 路径 $.movies[*] 和 - $.books[*] 之间通过 UNION 实现的“兄弟联接”, + $.books[*] 之间通过 UNION 实现的“兄弟连接”, 以及在 NESTED 层级上使用 FOR ORDINALITY 列(列 movie_idbook_idauthor_id): @@ -16722,11 +17379,11 @@ COLUMNS ( 序列操作函数 - sequence + 序列 - 本节描述对序列对象进行操作的函数,也称为序列生成器或简称序列。 + 本节描述用于操作序列对象(也称为序列生成器,或简称序列)的函数。 序列对象是使用创建的特殊单行表。 序列对象通常用于为表中的行生成惟一标识符。在中列出的序列函数,提供了简单的、多用户安全方法,用于从序列对象中获取连续的序列值。 @@ -16758,12 +17415,12 @@ COLUMNS ( bigint - 将序列对象推进到下一个值并返回该值。这是自动完成的:即使多个会话并发地执行nextval,每个会话也会安全地接收到不同的序列值。 - 如果序列对象是用默认形参创建的,则连续的nextval调用将返回以1开始的连续值。 + 将序列对象推进到下一个值并返回该值。这个操作是原子的:即使多个会话并发地执行nextval,每个会话也会安全地接收到不同的序列值。 + 如果序列对象是用默认参数创建的,则连续的nextval调用将返回以1开始的连续值。 其他行为可以通过在命令中使用适当的参数获得。 - 这个函数需要USAGEUPDATE权限在序列上。 + 这个函数需要序列上的USAGEUPDATE权限。 @@ -16776,16 +17433,16 @@ COLUMNS ( bigint - 设置序列对象的当前值,以及可选的它的is_called标志。 + 设置序列对象的当前值,并可选地设置其is_called标志。 双参数形式将序列的last_value字段设置为指定的值,并将其is_called字段设置为true,意味着下一个nextval将在返回值之前推进序列。 currval将报告的值也设置为指定的值。在三参数形式中,is_called可以设置为truefalsetrue与双参数形式具有相同的效果。 - 如果设置为false,下一个nextval将返回指定的值,序列推进从下面的nextval开始。 - 而且,currval报告的值在这种情况下不会改变。例如, + 如果设置为false,下一个nextval将返回指定的值,序列推进从再下一次调用nextval开始。 + 而且,currval报告的值在这种情况下不会改变。例如: -SELECT setval('myseq', 42); Next nextval will return 43 +SELECT setval('myseq', 42); 下一次 nextval 将返回 43 SELECT setval('myseq', 42, true); 同上 -SELECT setval('myseq', 42, false); Next nextval will return 42 +SELECT setval('myseq', 42, false); 下一次 nextval 将返回 42 setval返回的结果就是它的第二个参数的值。 @@ -16803,8 +17460,7 @@ SELECT setval('myseq', 42, false); Next nextvalbigint - 返回nextval在当前会话中为该序列最近获取的值。(如果在这个会话中没有为这个序列调用nextval会报告错误。) - 因为它返回的是一个会话本地值,所以它给出了一个可预测的答案,即自当前会话以来,其他会话是否执行了nextval。 + 返回当前会话中最近一次针对该序列调用nextval所获得的值。(如果当前会话从未针对该序列调用过nextval,则会报错。)由于返回的是会话局部值,无论其他会话是否在当前会话调用之后执行过nextval,结果都是可预测的。 这个函数需要序列上的USAGESELECT权限。 @@ -16856,9 +17512,7 @@ SELECT setval('myseq', 42, false); Next nextval - 序列函数所要操作的序列由regclass参数指定,该参数只是pg_class系统目录中序列的OID。 - 你不必手工查找OID,不过,因为regclass数据类型的输入转换器将为您完成这项工作。 - 详见 + 序列函数所要操作的序列由regclass参数指定,该参数就是序列在pg_class系统目录中的 OID。不过,不必手动查找 OID,因为regclass数据类型的输入转换器会完成这项工作。详见 @@ -16905,7 +17559,7 @@ CASE WHEN condition THEN result - CASE子句可以用于任何表达式可以出现的地方。每一个condition是一个返回boolean结果的表达式。如果结果为真,那么CASE表达式的结果就是符合条件的result,并且剩下的CASE表达式不会被处理。如果条件的结果不为真,那么以相同方式搜寻任何随后的WHEN子句。如果没有WHEN condition为真,那么CASE表达式的值就是在ELSE子句里的result。如果省略了ELSE子句而且没有条件为真,结果为空。 + CASE子句可以用于任何表达式可以出现的地方。每一个condition是一个返回boolean结果的表达式。如果结果为真,那么CASE表达式的结果就是紧随该条件后的result,并且剩下的CASE表达式不会被处理。如果条件的结果不为真,那么以相同方式搜寻任何随后的WHEN子句。如果没有WHEN condition为真,那么CASE表达式的值就是在ELSE子句里的result。如果省略了ELSE子句而且没有条件为真,结果为 null。 @@ -16949,7 +17603,7 @@ CASE expression END - 第一个expression会被计算,然后与所有在WHEN子句中的每一个value对比,直到找到一个相等的。如果没有找到匹配的,则返回在ELSE子句中的result(或者控制)。 这类似于 C 里的switch语句。 + 第一个expression会被计算,然后与所有在WHEN子句中的每一个value对比,直到找到一个相等的。如果没有找到匹配的,则返回在ELSE子句中的result(或者 null 值)。 这类似于 C 里的switch语句。 @@ -16980,11 +17634,7 @@ SELECT ... WHERE CASE WHEN x <> 0 THEN y/x > 1.5 ELSE false END; - 如中所述,在有几种情况中一个表达式的子表达式 - 会被计算多次,因此CASE只计算必要的表达式这 - 一原则并非不可打破。例如一个常量子表达式1/0通常将会在规划时导致一次 - 除零错误,即便它位于一个执行时永远也不会进入的CASE分支时也是 - 如此。 + 如所述,在多种情况下,表达式中的子表达式会在不同阶段求值,因此CASE只计算必要的子表达式这一原则并非绝对成立。例如,常量子表达式1/0通常会在规划时导致除零错误,即便它位于一个运行时永远不会进入的CASE分支中也是如此。 @@ -17009,19 +17659,19 @@ SELECT ... WHERE CASE WHEN x <> 0 THEN y/x > 1.5 ELSE false END; - COALESCE函数返回它的第一个非空参数的值。当且仅当所有参数都为空时才会返回空。它常用于在为显示目的检索数据时用缺省值替换空值。例如: + COALESCE函数返回参数中第一个不为 null 的值。只有所有参数都为 null 时,才返回 null。它常用于在检索数据以供显示时,用默认值替换 null 值。例如: SELECT COALESCE(description, short_description, '(none)') ... - 如果description不为空,这将会返回它的值,否则如果short_description非空则返回short_description的值,如果前两个都为空则返回(none)。 + 此表达式返回description,前提是它不为 null,否则返回short_description,前提是它不为 null,否则返回(none) - 所有参数都必须转换为一个公共数据类型,它将是结果的类型 (详情参见 )。 + 所有参数都必须能转换为同一个数据类型,它将是结果的类型(详情参见)。 - 和CASE表达式一样,COALESCE将不会 计算无助于判断结果的参数;也就是说,在第一个非空参数右边的参数不会被计算。这个 SQL 标准函数提供了类似于NVLIFNULL的能力,它们被用在某些其他数据库系统中。 + 和CASE表达式一样,COALESCE只计算确定结果所需的参数;也就是说,在第一个不为 null 的参数右边的参数不会被计算。这个 SQL 标准函数提供了类似于NVLIFNULL的能力,它们被用在某些其他数据库系统中。 @@ -17037,12 +17687,12 @@ SELECT COALESCE(description, short_description, '(none)') ... - 当value1value2相等时,NULLIF返回一个空值。 + 当value1value2相等时,NULLIF返回 null。 否则它返回value1。 这些可以用于执行前文给出的COALESCE示例的逆操作: SELECT NULLIF(value, '(none)') ... - 在这个示例中,如果value(none),将返回空值,否则返回value的值。 + 在这个示例中,如果value(none),将返回 null,否则返回value的值。 @@ -17077,11 +17727,11 @@ SELECT NULLIF(value, '(none)') ... - GREATESTLEAST函数从一个任意的数字表达式列表里选取最大或者最小的数值。 这些表达式必须都可以转换成一个普通的数据类型,它将会是结果类型 (参阅获取细节)。列表中的 NULL 数值将被忽略。只有所有表达式的结果都是 NULL 的时候,结果才会是 NULL。 + GREATESTLEAST函数从由任意数量的表达式组成的列表中选取最大值或最小值。这些表达式都必须能转换为同一个数据类型,该类型将作为结果类型(详情参见)。 - 请注意GREATESTLEAST都不是 SQL 标准,但却是很常见的扩展。某些其他数据库让它们在任何参数为 NULL 时返回 NULL,而不是在所有参数都为 NULL 时才返回 NULL。 + 参数列表中的 NULL 值会被忽略。只有所有表达式的求值结果都为 NULL 时,结果才为 NULL。(这与 SQL 标准不同。按照标准,只要有任意参数为 NULL,返回值就为 NULL。一些其他数据库采用这种行为。) @@ -17093,9 +17743,9 @@ SELECT NULLIF(value, '(none)') ... 显示了可以用于数组类型的专用的操作符。 除此之外,中所示的常用比较操作符也适用于数组。 - 比较操作符逐个元素的比较数组内容,使用默认的元素数据类型的B-树比较函数,并根据第一个差值进行排序。 + 比较操作符逐个元素比较数组内容,使用元素数据类型的默认 B-树比较函数,并根据第一个差异进行排序。 多维数组的元素按照行序进行访问(最后的下标变化最快)。 - 如果两个数组的内容相同但维数不等,那么维度信息中的第一个不同将决定排序顺序。 + 如果两个数组的内容相同但维度信息不同,那么维度信息中的第一个不同将决定排序顺序。
@@ -17126,7 +17776,7 @@ SELECT NULLIF(value, '(none)') ... 第一个数组是否包含第二个数组,也就是说,出现在第二个数组中的每个元素是否等于第一个数组中的某个元素? - (重复值不需要特殊处理,因此ARRAY[1]ARRAY[1,1]被认为包含对方。) + (重复元素不作特殊处理,因此ARRAY[1]ARRAY[1,1]被认为包含对方。) ARRAY[1,4,3] @> ARRAY[3,1,3] @@ -17168,8 +17818,7 @@ SELECT NULLIF(value, '(none)') ... anycompatiblearray - 连接两个数组。连接空(null)或空数组是一个无操作(no-op);否则,数组必须具有相同的维度数(如第一个示例所示),或者维度数相差一个(如第二个示例所示)。 - 如果数组不是完全相同的元素类型,它们将被强制转换成一个共同的类型(参见)。 + 连接两个数组。连接 null 或空数组不会产生任何效果;否则,数组必须具有相同的维数(如第一个示例所示),或维数相差一维(如第二个示例所示)。如果数组的元素类型不同,则会将它们强制转换为同一个类型(参见)。 ARRAY[1,2,3] || ARRAY[4,5,6,7] @@ -17201,7 +17850,7 @@ SELECT NULLIF(value, '(none)') ... anycompatiblearray - 将元素连接到数组的末尾(数组必须为空或一维的[one-dimensional])。 + 将元素连接到数组的末尾(数组必须为空或一维)。 ARRAY[4,5,6] || 7 @@ -17213,7 +17862,7 @@ SELECT NULLIF(value, '(none)') ...
- 参阅获取有关数组操作符行为的更多细节。有关哪些操作符支持被索引的操作,请参阅。 + 参阅获取有关数组操作符行为的更多细节。有关哪些操作符支持索引操作,请参阅 @@ -17302,8 +17951,7 @@ SELECT NULLIF(value, '(none)') ... anyarray - 返回一个包含给定值的拷贝的数组,其维数与第二个参数指定的长度相同。 - 可选的第三个参数提供每个维度的下界值(默认为全部为 1)。 + 返回用给定值的副本填充的数组,各维的长度由第二个参数指定。可选的第三个参数提供各维的下界值(默认均为1)。 array_fill(11, ARRAY[2,3]) @@ -17384,7 +18032,7 @@ SELECT NULLIF(value, '(none)') ... integer - 返回阵列中第二个参数中第一次发生的下标,如果它不存在,则返回NULL。 + 返回第二个参数在数组中首次出现的下标;若不存在,则返回NULL。 如果给出了第三个参数,则搜索从该下标开始。数组必须是一维的。比较是使用IS NOT DISTINCT FROM语义进行的,所以可以搜索NULL @@ -17402,9 +18050,9 @@ SELECT NULLIF(value, '(none)') ... integer[] - 返回作为第一个参数的数组中第二个参数所有出现的下标的数组。 + 返回第二个参数在第一个参数所给数组中所有出现位置的下标数组。 数组必须是一维的。使用IS NOT DISTINCT FROM语义完成比较,所以可以搜索NULL。 - 只有当数组为NULL时才返回NULL;如果在数组中没有找到该值,则返回空数组。 + 只有当数组为NULL时才返回NULL;如果在数组中没有找到该值,则返回空数组。 array_positions(ARRAY['A','A','B','A'], 'A') @@ -17531,7 +18179,7 @@ SELECT NULLIF(value, '(none)') ... anyarray - 对数组的第一维进行排序。排序顺序由数组元素类型的默认排序规则决定;不过,如果元素类型支持排序规则,也可以通过给array参数添加COLLATE子句来指定要使用的排序规则。 + 对数组的第一维进行排序。排序顺序由数组元素类型的默认排序顺序决定;不过,如果元素类型支持排序规则,也可以通过给array参数添加COLLATE子句来指定要使用的排序规则。 如果descending为 true,则按降序排序,否则按升序排序。省略时默认按升序排序。如果nulls_first为 true,则空值出现在非空值之前,否则空值出现在非空值之后。省略时,nulls_first取与descending相同的值。 @@ -17604,7 +18252,7 @@ SELECT NULLIF(value, '(none)') ... anyarray - 通过删除最后的n元素来裁剪数组。 + 通过删除最后的n个元素来裁剪数组。 如果数组是多维的,则只裁剪第一个维度。 @@ -17653,7 +18301,7 @@ SELECT NULLIF(value, '(none)') ... 将多个数组(可能是不同的数据类型)展开到一组行中。 如果数组的长度不完全相同,那么较短的数组将用NULL填充。 - 这种形式只在查询的FROM子句中允许;参见。 + 这种形式只允许出现在查询的 FROM 子句中;参见 select * from unnest(ARRAY[1,2], ARRAY['foo','bar','baz']) as x(a,b) @@ -17804,7 +18452,7 @@ SELECT NULLIF(value, '(none)') ... boolean - 第一个范围是否严格符合第二个(范围)? + 第一个范围是否严格地在第二个(范围)的右边? int8range(50,60) >> int8range(20,30) @@ -17888,7 +18536,7 @@ SELECT NULLIF(value, '(none)') ... anyrange - 计算范围的差异。第二个范围必须不能包含在第一个(范围)中,以使差异不是一个单一的范围。 + 计算范围的差集。第二个范围不能被包含在第一个范围中而导致差集无法表示为单个范围。 int8range(5,15) - int8range(10,20) @@ -17982,7 +18630,7 @@ SELECT NULLIF(value, '(none)') ... boolean - 第一个多范围是否被第二个所包括? + 第一个多范围是否被第二个所包含? '{[2,4)}'::int4multirange <@ '{[1,7)}'::int4multirange @@ -17996,7 +18644,7 @@ SELECT NULLIF(value, '(none)') ... boolean - 多范围是否被范围所包括。 + 多范围是否被范围所包含? '{[2,4)}'::int4multirange <@ int4range(1,7) @@ -18010,7 +18658,7 @@ SELECT NULLIF(value, '(none)') ... boolean - 范围是否被多范围所包括? + 范围是否被多范围所包含? int4range(2,4) <@ '{[1,7)}'::int4multirange @@ -18108,7 +18756,7 @@ SELECT NULLIF(value, '(none)') ... boolean - 范围是否完全的在多范围左边? + 范围是否完全在多范围左边? int8range(1,10) << '{[100,110)}'::int8multirange @@ -18150,7 +18798,7 @@ SELECT NULLIF(value, '(none)') ... boolean - 范围是否完全在多范围右边。 + 范围是否完全在多范围右边? int8range(50,60) >> '{[20,30)}'::int8multirange @@ -18318,7 +18966,7 @@ SELECT NULLIF(value, '(none)') ... anymultirange - 计算多范围的差异。 + 计算多范围的差集。 '{[5,20)}'::int8multirange - '{[10,15)}'::int8multirange @@ -18330,21 +18978,21 @@ SELECT NULLIF(value, '(none)') ... - 当涉及一个空范围或多范围时,左部/右部/相邻操作符总是返回假;即一个空范围被认为不在任何其他范围前面或者后面。 + 涉及空范围或空多范围时,左侧、右侧和相邻操作符总是返回假;也就是说,空范围不被视为位于任何其他范围之前或之后。 - 在其他地方,空范围和多范围被视为添加标识:与空值的任何交集都是它自己。 - 任何减去空值的都是它自己。 - 空的多范围与空的范围具有完全相同的点。 + 在其他运算中,空范围和空多范围被视为加法单位元:任何值与空值求并集,结果仍是该值本身。 + 任何值减去空值,结果也仍是该值本身。 + 空多范围与空范围具有完全相同的点。 每个范围都包含空范围。 每个多范围包含任意多个空范围。 - 范围交集和差异操作符将失败,如果结果范围需要包含两个不相交的子范围,因为这样的范围无法表示。 - 还有用于求交集和差集的单独操作符,它们接受多范围参数并返回多范围,即使参数彼此不相交也不会失败。 - 因此,如果需要对可能不相交的范围进行交集或差异操作,你可以通过首先将范围转换为多范围来避免错误。 + 如果结果范围需要包含两个不相交的子范围,范围并集和差集操作符会失败,因为这样的范围无法表示。 + 另有接受多范围参数并返回多范围的并集和差集操作符,即使参数彼此不相交,也不会失败。 + 因此,如果需要对可能不相交的范围求并集或差集,可以先将范围转换为多范围来避免错误。 @@ -18382,7 +19030,7 @@ SELECT NULLIF(value, '(none)') ... anyelement - 提取范围的下界(如果范围为空或下界为无限,则为NULL)。 + 提取范围的下界(如果范围为空或没有下界,则返回NULL)。 lower(numrange(1.1,2.2)) @@ -18399,7 +19047,7 @@ SELECT NULLIF(value, '(none)') ... anyelement - 提取范围的上限(如果范围为空或上限为无限,则为NULL)。 + 提取范围的上界(如果范围为空或没有上界,则返回NULL)。 upper(numrange(1.1,2.2)) @@ -18467,7 +19115,7 @@ SELECT NULLIF(value, '(none)') ... boolean - 范围的下界是无限的吗? + 范围是否没有下界?(下界为-Infinity时返回假。) lower_inf('(,)'::daterange) @@ -18484,7 +19132,7 @@ SELECT NULLIF(value, '(none)') ... boolean - 范围的上界是无限的吗? + 范围是否没有上界?(上界为Infinity时返回假。) upper_inf('(,)'::daterange) @@ -18541,7 +19189,7 @@ SELECT NULLIF(value, '(none)') ... anyelement - 提取多范围的下界 (NULL 如果多范围为空或下界为无穷的)。 + 提取多范围的下界(如果多范围为空或没有下界,则返回NULL)。 lower('{[1.1,2.2)}'::nummultirange) @@ -18558,7 +19206,7 @@ SELECT NULLIF(value, '(none)') ... anyelement - 提取多范围的上界 (NULL 如果多范围为空或上界为无穷的)。 + 提取多范围的上界(如果多范围为空或没有上界,则返回NULL)。 upper('{[1.1,2.2)}'::nummultirange) @@ -18592,7 +19240,7 @@ SELECT NULLIF(value, '(none)') ... boolean - 多范围的下界是否包括? + 多范围的下界是否包含在内? lower_inc('{[1.1,2.2)}'::nummultirange) @@ -18609,7 +19257,7 @@ SELECT NULLIF(value, '(none)') ... boolean - 多范围的上界是否包括? + 多范围的上界是否包含在内? upper_inc('{[1.1,2.2)}'::nummultirange) @@ -18626,7 +19274,7 @@ SELECT NULLIF(value, '(none)') ... boolean - 多范围的下界是无限的么? + 多范围是否没有下界?(下界为-Infinity时返回假。) lower_inf('{(,)}'::datemultirange) @@ -18643,7 +19291,7 @@ SELECT NULLIF(value, '(none)') ... boolean - 多范围的上界是无限的么? + 多范围是否没有上界?(上界为Infinity时返回假。) upper_inf('{(,)}'::datemultirange) @@ -18671,7 +19319,7 @@ SELECT NULLIF(value, '(none)') ... - multirange (function) + multirange(函数) multirange ( anyrange ) anymultirange @@ -18689,14 +19337,13 @@ SELECT NULLIF(value, '(none)') ... unnest - for multirange + 用于多范围 unnest ( anymultirange ) setof anyrange - 扩展多范围为一组范围。 - 范围按存储顺序读出(升序)。 + 将多范围按升序展开为一组范围。 unnest('{[1,2), [3,4)}'::int4multirange) @@ -18712,7 +19359,7 @@ SELECT NULLIF(value, '(none)') ... - lower_incupper_inclower_inf、 和 upper_inf 函数对空范围(empty range)或多范围都返回假(false)。 + lower_incupper_inclower_infupper_inf 函数对空范围或空多范围都返回假。 @@ -18726,17 +19373,22 @@ SELECT NULLIF(value, '(none)') ... - 聚合函数从一个输入值的集合计算出一个单一值。 - 内置的通用聚合函数在中列出,而统计性聚合是在中列出。 + 聚合函数从一个输入值的集合计算出一个单一结果。 + 内置的通用聚合函数在中列出,而统计聚合函数在中列出。 内置的组内有序集聚合函数在中列出,而内置的组内假想集聚合在中列出。 与聚合函数紧密相关的分组操作在中列出。 - 中会解释针对聚合函数的特殊语法考虑。额外的介绍信息请参考。 + 中会解释针对聚合函数的特殊语法注意事项。更多入门信息请参考 支持部分模式的聚合函数能够参与各种优化,例如并行聚合。 + + 虽然下面所有聚合函数都接受可选的ORDER BY子句 + (详见),但这里只在输出受排序影响的聚合函数签名中列出了该子句。 + + 通用聚合函数 @@ -18758,35 +19410,49 @@ SELECT NULLIF(value, '(none)') ... + + + + any_value + + any_value ( anyelement ) + 与输入类型相同 + + + 从非空输入值中返回任意一个值。 + + + + array_agg - array_agg ( anynonarray ) + array_agg ( anynonarray ORDER BY input_sort_columns ) anyarray 将所有输入值,包括空值,收集到一个数组中。 - No + - array_agg ( anyarray ) + array_agg ( anyarray ORDER BY input_sort_columns ) anyarray - 将所有输入数组连接到一个更高维度的数组中。(输入必须都具有相同的维度,并且不能为空的(empty)或空值(null)。) + 将所有输入数组连接成维数增加一维的数组。(所有输入的维数必须相同,且不能是空数组或空值(NULL)。) - No + - average + 平均值 avg @@ -18821,7 +19487,7 @@ SELECT NULLIF(value, '(none)') ... 计算所有非空输入值的平均值(算术平均值)。 - Yes + @@ -18845,9 +19511,9 @@ SELECT NULLIF(value, '(none)') ... bit - 计算所有非空输入值的逐位AND。 + 计算所有非空输入值的按位与。 - Yes + @@ -18871,9 +19537,9 @@ SELECT NULLIF(value, '(none)') ... bit - 计算所有非空输入值的逐位OR。 + 计算所有非空输入值的按位或。 - Yes + @@ -18900,7 +19566,7 @@ SELECT NULLIF(value, '(none)') ... 计算所有非空输入值的按位异或。 可用作一组无序的值集合的校验和。 - Yes + @@ -18914,7 +19580,7 @@ SELECT NULLIF(value, '(none)') ... 如果全部非空输入值都为真则返回真,否则返回假。 - Yes + @@ -18928,7 +19594,7 @@ SELECT NULLIF(value, '(none)') ... 如果任何非空输入值为真则返回真,否则返回假。 - Yes + @@ -18940,81 +19606,226 @@ SELECT NULLIF(value, '(none)') ... bigint - 计算输入行的数量。 + 计算输入行的数量。 + + + + + + + count ( "any" ) + bigint + + + 计算输入值不为空的输入行的数量。 + + + + + + + + every + + every ( boolean ) + boolean + + + 这是标准 SQL 中与bool_and等价的函数。 + + + + + + + + json_agg + + json_agg ( anyelement ORDER BY input_sort_columns ) + json + + + + jsonb_agg + + jsonb_agg ( anyelement ORDER BY input_sort_columns ) + jsonb + + + 收集所有输入值,包括空值,到一个JSON数组。根据to_jsonto_jsonb将值转换为JSON。 + + + + + + + + json_agg_strict + + json_agg_strict ( anyelement ) + json + + + + jsonb_agg_strict + + jsonb_agg_strict ( anyelement ) + jsonb + + + 将所有非空输入值收集到一个JSON数组中,跳过空值。根据to_jsonto_jsonb将值转换为JSON。 + + + + + + + json_arrayagg + json_arrayagg ( + value_expression + ORDER BY sort_expression + { NULL | ABSENT } ON NULL + RETURNING data_type FORMAT JSON ENCODING UTF8 ) + + + 行为与json_array相同,只是它作为一个聚合函数,因此只接受一个 + value_expression参数。 + 如果指定了ABSENT ON NULL,则会省略所有 NULL 值。 + 如果指定了ORDER BY,元素将按该顺序出现在数组中,而不是按输入顺序。 + + + SELECT json_arrayagg(v) FROM (VALUES(2),(1)) t(v) + [2, 1] + + + + + + + json_objectagg + json_objectagg ( + { key_expression { VALUE | ':' } value_expression } + { NULL | ABSENT } ON NULL + { WITH | WITHOUT } UNIQUE KEYS + RETURNING data_type FORMAT JSON ENCODING UTF8 ) + + + 行为与json_object相同,只是它作为一个聚合函数,因此只接受一个 + key_expression参数和一个 + value_expression参数。 + + + SELECT json_objectagg(k:v) FROM (VALUES ('a'::text,current_date),('b',current_date + 1)) AS t(k,v) + { "a" : "2022-05-10", "b" : "2022-05-11" } + + + + + + + + json_object_agg + + json_object_agg ( key + "any", value + "any" + ORDER BY input_sort_columns ) + json + + + + jsonb_object_agg + + jsonb_object_agg ( key + "any", value + "any" + ORDER BY input_sort_columns ) + jsonb + + + 将所有键/值对收集到一个JSON对象中。键参数强制转换为文本;值参数按照to_jsonto_jsonb进行转换。 + 值可以为空,但键不能(为空)。 - Yes + - count ( "any" ) - bigint + + json_object_agg_strict + + json_object_agg_strict ( + key "any", + value "any" ) + json - - 计算输入值不为空的输入行的数量。 - - Yes - - - - + - every + jsonb_object_agg_strict - every ( boolean ) - boolean + jsonb_object_agg_strict ( + key "any", + value "any" ) + jsonb - 这是对应bool_and的SQL标准的等效物。 + 将所有键/值对收集到一个JSON对象中。键参数强制转换为文本;值参数按照to_jsonto_jsonb进行转换。 + key不能为空。如果value为空,则跳过该条目。 - Yes + - json_agg + json_object_agg_unique - json_agg ( anyelement ) + json_object_agg_unique ( + key "any", + value "any" ) json - jsonb_agg + jsonb_object_agg_unique - jsonb_agg ( anyelement ) + jsonb_object_agg_unique ( + key "any", + value "any" ) jsonb - 收集所有输入值,包括空值,到一个JSON数组。根据to_jsonto_jsonb将值转换为JSON。 + 将所有键/值对收集到一个JSON对象中。键参数强制转换为文本;值参数按照to_jsonto_jsonb进行转换。 + 值可以为空,但键不能为空。如果存在重复键,则会抛出错误。 - No + - json_object_agg + json_object_agg_unique_strict - json_object_agg ( key - "any", value - "any" ) + json_object_agg_unique_strict ( + key "any", + value "any" ) json - jsonb_object_agg + jsonb_object_agg_unique_strict - jsonb_object_agg ( key - "any", value - "any" ) + jsonb_object_agg_unique_strict ( + key "any", + value "any" ) jsonb - 将所有键/值对收集到一个JSON对象中。关键参数强制转换为文本;值参数按照to_jsonto_jsonb进行转换。 - 值可以为空,但键不能(为空)。 + 将所有键/值对收集到一个JSON对象中。键参数强制转换为文本;值参数按照to_jsonto_jsonb进行转换。 + key不能为空。如果value为空,则跳过该条目。 + 如果存在重复键,则会抛出错误。 - No + @@ -19022,15 +19833,13 @@ SELECT NULLIF(value, '(none)') ... 最大值 - max ( see text ) - same as input type + max ( 见说明 ) + 与输入类型相同 计算非空输入值的最大值。适用于任何数字、字符串、日期/时间或枚举类型, - 以及inetinterval、 - moneyoidpg_lsn、 - tidxid8, - 以及这些类型的数组。 + 以及byteainetintervalmoneyoidpg_lsntidxid8, + 以及包含可排序数据类型的数组和复合类型。 @@ -19040,15 +19849,13 @@ SELECT NULLIF(value, '(none)') ... 最小值 - min ( see text ) - same as input type + min ( 见说明 ) + 与输入类型相同 计算非空输入值的最小值。适用于任何数字、字符串、日期/时间或枚举类型, - 以及inetinterval、 - moneyoidpg_lsn、 - tidxid8, - 以及这些类型的数组。 + 以及byteainetintervalmoneyoidpg_lsntidxid8, + 以及包含可排序数据类型的数组和复合类型。 @@ -19070,7 +19877,7 @@ SELECT NULLIF(value, '(none)') ... 计算非空输入值的并集。 - No + @@ -19090,7 +19897,7 @@ SELECT NULLIF(value, '(none)') ... 计算非空输入值的交集。 - No + @@ -19104,13 +19911,14 @@ SELECT NULLIF(value, '(none)') ... string_agg ( value - bytea, delimiter bytea ) + bytea, delimiter bytea + ORDER BY input_sort_columns ) bytea - 将非 null 输入值连接成一个字符串。第一个值之后的每个值前面都会放置相应的delimiter(如果它不为 null)。 + 将非 NULL 输入值连接成一个字符串。在第一个值之后,每个值前面都会放置相应的delimiter(如果它不为 NULL)。 - No + @@ -19152,7 +19960,7 @@ SELECT NULLIF(value, '(none)') ... 计算非空输入值的总和。 - Yes + @@ -19160,35 +19968,28 @@ SELECT NULLIF(value, '(none)') ... xmlagg - xmlagg ( xml ) + xmlagg ( xml ORDER BY input_sort_columns ) xml - 连接非空的XML输入值(参见)。 + 连接非空的 XML 输入值(参见)。 - No +
- 应该注意的是,除了count之外,这些函数在没有选择行时返回空值。 - 特别地,行数的sum返回空(null),而不是预期的零,array_agg在没有输入行时返回空(null)而不是空数组。 - coalesce函数可以在必要时用零或空数组代替空(null)。 + 需要注意,除了count之外,这些函数在没有选中任何行时都会返回空值。特别地,sum在没有输入行时返回空值,而不是预期中的零;array_agg在没有输入行时返回空值,而不是空数组。必要时,可以用coalesce函数把空值替换成零或空数组。 - 聚合函数 array_agg,json_agg, jsonb_agg,json_object_agg, jsonb_object_agg, - string_agg,和 xmlagg,以及类似的用户定义的聚合函数,根据输入值的顺序产生富有意义的不同的结果值。 - 默认情况下,这种排序是不指定的,但可以通过在聚合调用中写入ORDER BY子句来控制,如所示。 - 或者,从排序的子查询提供输入值通常也可以。例如: - + 聚合函数array_aggjson_aggjsonb_aggjson_agg_strictjsonb_agg_strictjson_object_aggjsonb_object_aggjson_object_agg_strictjsonb_object_agg_strictjson_object_agg_uniquejsonb_object_agg_uniquejson_object_agg_unique_strictjsonb_object_agg_unique_strictstring_aggxmlagg,以及类似的用户定义聚合函数,其结果值会随输入值的顺序发生实质性变化。默认情况下,输入顺序未指定,但可以在聚合调用中写入ORDER BY子句来控制,如所示。也可以用已排序的子查询提供输入值,这通常也能奏效。例如: - - 注意,如果外部查询级别包含其他处理,例如关联,则此方法可能会失败,因为这可能导致子查询的输出在计算聚合之前重新排序。 + 需要注意,如果外层查询包含连接等额外处理,这种方法可能失效,因为子查询的输出可能在计算聚合之前被重新排序。 @@ -19202,31 +20003,24 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; - 布尔聚合 bool_andbool_or 对应于标准SQL聚合 everyanysome. - PostgreSQL 支持 every, 但不支持 anysome, 因为标准语法中存在模糊性: - + 布尔聚合bool_andbool_or对应于标准 SQL 聚合everyanysome。 + PostgreSQL支持every,但不支持anysome,因为标准语法中存在歧义: SELECT b1 = ANY((SELECT b2 FROM t2 ...)) FROM t1 ...; - - 这里ANY可以被认为是引入子查询,或者是聚合函数,如果子查询返回一行布尔值。因此,不能为这些聚合提供标准名称。 +此处的ANY既可以被视为引入一个子查询,也可以在该子查询返回一行布尔值时被视为聚合函数。因此,不能将标准名称用于这些聚合。 - 习惯使用其他SQL数据库管理系统的用户可能会对count聚合应用于整个表时的性能感到失望。一个类似下面的查询: - + 习惯于其他 SQL 数据库管理系统的用户,可能会对count聚合用于整个表时的性能感到失望。如下查询: SELECT count(*) FROM sometable; - - 将需要与表大小成比例的工作:PostgreSQL将需要扫描整个表或包含表中所有行的索引。 +所需的工作量与表大小成正比:PostgreSQL需要扫描整个表,或者完整扫描一个包含表中所有行的索引。 - 显示了统计分析中常用的聚合函数。 - (这些被分离出来仅仅是为了避免使更常用的聚合列表混乱。) - 显示为接受numeric_type的函数可用于所有类型smallint, integer,bigint, numeric, real, 和 double precision。 - 在描述中提及N时,它意味着所有输入表达式都非空的输入行数。在所有情况下,如果计算没有意义,则返回null,例如当N为0时。 + 列出了统计分析中常用的聚合函数。(将它们单独列出,只是为了避免更常用的聚合函数列表过于杂乱。)标为接受numeric_type的函数适用于smallintintegerbigintnumericrealdouble precision这些类型。描述中提到的N表示所有输入表达式都非空的输入行数。无论哪种情况,如果计算没有意义,例如N为 0,就返回 null。 @@ -19261,7 +20055,7 @@ SELECT count(*) FROM sometable; - correlation + 相关性 corr @@ -19272,14 +20066,14 @@ SELECT count(*) FROM sometable; 计算相关系数。 - Yes + - covariance - population + 协方差 + 总体 covar_pop @@ -19290,14 +20084,14 @@ SELECT count(*) FROM sometable; 计算总体协方差。 - Yes + - covariance - sample + 协方差 + 样本 covar_samp @@ -19308,7 +20102,7 @@ SELECT count(*) FROM sometable; 计算样本协方差。 - Yes + @@ -19320,9 +20114,9 @@ SELECT count(*) FROM sometable; double precision
- 计算自变量的平均值,sum(X)/N. + 计算自变量的平均值,即sum(X)/N
- Yes +
@@ -19334,9 +20128,9 @@ SELECT count(*) FROM sometable; double precision
- 计算因变量的平均值,sum(Y)/N. + 计算因变量的平均值,即sum(Y)/N - Yes + @@ -19350,13 +20144,13 @@ SELECT count(*) FROM sometable; 计算两个输入都非空的行数。 - Yes + - regression intercept + 回归截距 regr_intercept @@ -19365,9 +20159,9 @@ SELECT count(*) FROM sometable; double precision - 计算由(XY)对决定的最小二乘拟合的线性方程的Y-截距。 + 计算由(XY)数值对确定的最小二乘拟合线性方程的 y 轴截距。 - Yes + @@ -19381,13 +20175,13 @@ SELECT count(*) FROM sometable; 计算相关系数的平方。 - Yes + - regression slope + 回归斜率 regr_slope @@ -19396,9 +20190,9 @@ SELECT count(*) FROM sometable; double precision - 计算由(X, Y)对决定的最小二乘拟合的线性方程的斜率。 + 计算由(XY)数值对确定的最小二乘拟合线性方程的斜率。 - Yes + @@ -19410,10 +20204,9 @@ SELECT count(*) FROM sometable; double precision
- 计算自变量的平方和 - sum(X^2) - sum(X)^2/N. + 计算自变量的平方和,即sum(X^2) - sum(X)^2/N - Yes + @@ -19425,10 +20218,9 @@ SELECT count(*) FROM sometable; double precision
- 计算独立变量乘以因变量的sum of products, - sum(X*Y) - sum(X) * sum(Y)/N. + 计算自变量与因变量的乘积和,即sum(X*Y) - sum(X) * sum(Y)/N - Yes + @@ -19440,69 +20232,62 @@ SELECT count(*) FROM sometable; double precision
- 计算因变量的平方和, - sum(Y^2) - sum(Y)^2/N. + 计算因变量的平方和,即sum(Y^2) - sum(Y)^2/N - Yes + - standard deviation + 标准差 stddev stddev ( numeric_type ) - double precision - for real or double precision, - otherwise numeric + 对于realdouble precision输入,返回double precision;否则返回numeric - 这是stddev_samp的一个历史别称。 + 这是stddev_samp的一个历史别名。 - Yes + - standard deviation - population + 标准差 + 总体 stddev_pop stddev_pop ( numeric_type ) - double precision - for real or double precision, - otherwise numeric + 对于realdouble precision输入,返回double precision;否则返回numeric 计算输入值的总体标准差。 - Yes + - standard deviation - sample + 标准差 + 样本 stddev_samp stddev_samp ( numeric_type ) - double precision - for real or double precision, - otherwise numeric + 对于realdouble precision输入,返回double precision;否则返回numeric 计算输入值的样本标准差。 - Yes + @@ -19511,54 +20296,48 @@ SELECT count(*) FROM sometable; variance variance ( numeric_type ) - double precision - for real or double precision, - otherwise numeric + 对于realdouble precision输入,返回double precision;否则返回numeric
- 这是 var_samp 的一个历史别称。 + 这是 var_samp 的一个历史别名。 - Yes + - variance - population + 方差 + 总体 var_pop var_pop ( numeric_type ) - double precision - for real or double precision, - otherwise numeric + 对于realdouble precision输入,返回double precision;否则返回numeric - 计算输入值的总体方差(总体标准差的平方)。 + 计算输入值的总体方差(总体标准差的平方)。 - Yes + - variance - sample + 方差 + 样本 var_samp var_samp ( numeric_type ) - double precision - for real or double precision, - otherwise numeric + 对于realdouble precision输入,返回double precision;否则返回numeric - 计算输入值的样本方差(样本标准差的平方)。 + 计算输入值的样本方差(样本标准差的平方)。 - Yes + @@ -19569,11 +20348,11 @@ SELECT count(*) FROM sometable; 这些函数有时被称为逆分布函数。 它们的聚合输入通过ORDER BY引入,还可以接受未聚合的直接参数,但后者只计算一次。 所有这些函数在其聚合输入中都忽略空(null)值。 - 对于使用fraction参数的函数,分数值必须在 0 到 1 之间;否则会报错。但是,null 的 fraction 值只会产生一个 null 结果。 + 对于使用fraction参数的函数,比例值必须在 0 到 1 之间;否则会报错。但是,null 的 fraction 值只会产生一个 null 结果。
- ordered-set aggregate + 有序集聚合 内置 @@ -19605,16 +20384,16 @@ SELECT count(*) FROM sometable; - mode - statistical + 众数 + 统计 mode () WITHIN GROUP ( ORDER BY anyelement ) anyelement - 计算mode,即聚合参数最频繁的值(如果有多个相同频繁的值,第一个可以任意选择)。聚合参数必须是可排序类型。 + 计算众数,即聚合参数中出现次数最多的值(若多个值的出现次数相同且最多,则任意选择其中第一个)。聚合参数必须是可排序类型。 - No + @@ -19632,9 +20411,9 @@ SELECT count(*) FROM sometable; 计算连续百分位点,该值对应于聚合参数值有序集合中的指定fraction。 - 如果需要,这将在相邻的输入项之间插入。 + 必要时会在相邻输入项之间进行插值。 - No + @@ -19649,7 +20428,7 @@ SELECT count(*) FROM sometable; 计算多个连续百分位点。结果是一个与fractions参数具有相同维度的数组,其中每个非 null 元素都被替换为对应百分位点的值(必要时会进行插值)。 - No + @@ -19665,7 +20444,7 @@ SELECT count(*) FROM sometable; 计算离散百分位数,即聚合参数值的有序集合中的第一个值,该值在排序中的位置等于或超过指定的fraction。 聚合参数必须是可排序类型。 - No + @@ -19678,14 +20457,14 @@ SELECT count(*) FROM sometable; 结果是一个与fractions参数具有相同维数的数组,每个非空元素都被对应于该百分位数的输入值替换。 聚合参数必须是可排序类型。 - No + - hypothetical-set aggregate + 假想集聚合 内置 @@ -19721,52 +20500,52 @@ SELECT count(*) FROM sometable; rank - hypothetical + 假设行 rank ( args ) WITHIN GROUP ( ORDER BY sorted_args ) bigint - 计算假设行的排名,包括间隔,就是说在它的同等行组中第一行的行号。 + 计算假设行的排名,允许空缺;即该行所属同等行组中第一行的行号。 - No + dense_rank - hypothetical + 假设行 dense_rank ( args ) WITHIN GROUP ( ORDER BY sorted_args ) bigint - 计算假设行的排名,没有间隔;这个功能有效地计数同等行组。 + 计算假设行的排名,没有空缺;此函数实际上对同等行组进行计数。 - No + percent_rank - hypothetical + 假设行 percent_rank ( args ) WITHIN GROUP ( ORDER BY sorted_args ) double precision - 计算假设行的相关排行,也就是(rank - 1) / (total rows - 1)。取值范围为 0 到 1(含)。 + 计算假设行的相对排名,即(rank - 1)/(总行数 - 1)。取值范围为 0 到 1(含)。 - No + cume_dist - hypothetical + 假设行 cume_dist ( args ) WITHIN GROUP ( ORDER BY sorted_args ) double precision @@ -19774,7 +20553,7 @@ SELECT count(*) FROM sometable; 计算累积分布,也就是(位于假设行之前或与假设行同等的行数)/(总行数)。取值范围为 1/N 到 1。 - No + @@ -19807,8 +20586,7 @@ SELECT count(*) FROM sometable; integer - 返回一个位掩码以指示哪个GROUP BY表达式没有包含在当前分组集中。 - 比特位被分配给最右边的参数对应于最低有效位;如果对应的表达式包含在生成当前结果行的分组集的分组条件中,则每个位为0,如果不包含则为1。 + 返回一个位掩码,指示哪些GROUP BY表达式未包含在当前分组集中。分配比特位时,最右侧参数对应最低有效位;如果相应表达式包含在生成当前结果行的分组集的分组条件中,该位为 0,否则为 1。 @@ -19816,9 +20594,7 @@ SELECT count(*) FROM sometable; - 所示的分组操作与分组集(参见)共同使用,以区分结果行。 - GROUPING函数的参数实际上并不求值,但它们必须与相关查询级别的GROUP BY子句中给出的表达式完全匹配。例如: - + 在中列出的分组操作与分组集配合使用(参见),以区分结果行。传给GROUPING函数的参数不会实际求值,但它们必须与相关查询层级的GROUP BY子句中的表达式完全匹配。例如: => SELECT * FROM items_sold; make | model | sales -------+-------+------- @@ -19839,9 +20615,7 @@ SELECT count(*) FROM sometable; Bar | | 1 | 20 | | 3 | 50 (7 rows) - - 在这里,前四行中的grouping0表明这些已经正常分组,在两个分组列上。 - 值1表示model没有在倒数两行中分组,值3表示无论是make还是model都没有在最后一行中分组(因此,这是所有输入行的聚合)。 +这里,前四行的grouping值为0,表明这些行按两个分组列正常分组。值1表明model未用于倒数第二、第三行的分组,值3则表明最后一行既未按make分组,也未按model分组(因此该行聚合了全部输入行)。 @@ -19865,7 +20639,7 @@ SELECT count(*) FROM sometable; - 除了这些函数之外,任何内置的或用户定义的普通聚合(例如非有序集或假想集聚合)都可以作为窗口函数使用;关于内置聚合的列表,参见。 + 除了这些函数之外,任何内置的或用户定义的普通聚合(即不属于有序集或假想集聚合)都可以作为窗口函数使用;关于内置聚合的列表,参见。 聚合函数只有在调用后带有OVER子句时才作为窗口函数;否则,它们就是普通聚合,并为整个结果集返回一行。 @@ -19896,7 +20670,7 @@ SELECT count(*) FROM sometable; bigint - 返回其分区内的当前行数,从1开始计数。 + 返回当前行在其分区内的编号,从 1 开始计数。 @@ -19909,7 +20683,7 @@ SELECT count(*) FROM sometable; bigint - 返回当前行的排名,包含间隔;即同等行组中第一行的row_number。 + 返回当前行的排名,允许空缺;即同等行组中第一行的row_number @@ -19922,7 +20696,7 @@ SELECT count(*) FROM sometable; bigint - 返回当前行的排名,不包括间隔;这个功能有效地计数同等行组。 + 返回当前行的排名,没有空缺;此函数实际上对同等行组进行计数。 @@ -19961,7 +20735,7 @@ SELECT count(*) FROM sometable; integer - 返回一个从1到参数值的整数,并将分区划分为尽可能相等的值。 + 返回从 1 到参数值的整数,将分区尽可能均等地划分。 @@ -19976,9 +20750,7 @@ SELECT count(*) FROM sometable; anycompatible - 返回分区中在当前行之前offset行的value;如果没有这样的行,则返回default(必须与value相兼容的类型)。 - offsetdefault都是针对当前行求值的。 - 如果省略,offset默认为1,defaultNULL。 + 返回在分区内当前行之前offset行处计算的value;如果没有这样的行,则返回default(其类型必须与value兼容)。offsetdefault都针对当前行求值。如果省略,offset默认为 1,default默认为NULL @@ -19993,10 +20765,7 @@ SELECT count(*) FROM sometable; anycompatible - 返回分区中在当前行之后offset行的value; - 如果没有这样的行,则返回default(必须与value兼容的类型)。 - offsetdefault都是针对当前行求值的。 - 如果省略,offset默认为1,defaultNULL。 + 返回在分区内当前行之后offset行处计算的value;如果没有这样的行,则返回default(其类型必须与value兼容)。offsetdefault都针对当前行求值。如果省略,offset默认为 1,default默认为NULL @@ -20051,14 +20820,14 @@ SELECT count(*) FROM sometable; 注意first_valuelast_valuenth_value只考虑窗口帧内的行,它默认情况下包含从分区的开始行直到当前行的最后一个同等行。 这对last_value可能不会给出有用的结果,有时对nth_value也一样。 - 你可以通过向OVER子句增加一个合适的帧声明(RANGEGROUPS)来重定义帧。 + 你可以通过向OVER子句增加一个合适的帧声明(RANGEROWSGROUPS)来重定义帧。 关于帧声明的更多信息请参考 当一个聚合函数被用作窗口函数时,它将在当前行的窗口帧内的行上聚合。 - 一个使用ORDER BY和默认窗口帧定义的聚合产生一种运行时求和类型的行为,这可能是或者不是想要的结果。 - 为了获取在整个分区上的聚合,忽略ORDER BY或者使用ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING。 + 一个使用ORDER BY和默认窗口帧定义的聚合产生一种累计求和类型的行为,这可能是或者不是想要的结果。 + 为了获取在整个分区上的聚合,省略ORDER BY或者使用ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING。 其它窗口帧声明可以用来获得其它的效果。 @@ -20067,7 +20836,7 @@ SELECT count(*) FROM sometable; SQL 标准为leadlagfirst_valuelast_valuenth_value定义了一个RESPECT NULLSIGNORE NULLS选项。 这在PostgreSQL中没有实现:行为总是与标准的默认相同,即RESPECT NULLS。 - 同样,标准中用于nth_valueFROM FIRSTFROM LAST选项没有实现: 只有支持默认的FROM FIRST行为(你可以通过反转ORDER BY的排序达到FROM LAST的结果)。 + 同样,标准中用于nth_valueFROM FIRSTFROM LAST选项没有实现: 只支持默认的FROM FIRST行为(你可以通过反转ORDER BY的排序达到FROM LAST的结果)。 @@ -20174,11 +20943,11 @@ MERGE INTO products p - subquery + 子查询 - 本节描述PostgreSQL中可用的SQL兼容的子查询表达式。所有本节中成文的表达式都返回布尔值(真/假)结果。 + 本节描述PostgreSQL中可用的SQL兼容的子查询表达式。本节介绍的所有表达式形式都返回布尔值(真/假)结果。 @@ -20193,7 +20962,7 @@ EXISTS (subquery) - 子查询可以引用来自周围的查询的变量,这些变量在该子查询的任何一次计算中都起常量的作用。 + 子查询可以引用外层查询的变量,这些变量在该子查询的任何一次计算中都起常量的作用。 @@ -20205,7 +20974,7 @@ EXISTS (subquery) - 下面这个简单的示例类似在col2上的一次内联接,但是它为每个 tab1的行生成最多一个输出,即使存在多个匹配tab2的行也如此∶ + 下面这个简单的示例类似在col2上的一次内连接,但是它为每个 tab1的行最多生成一行输出,即使存在多个匹配tab2的行也如此: SELECT col1 FROM tab1 @@ -20222,15 +20991,15 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 右手边是一个圆括弧括起来的子查询, 它必须正好只返回一个列。左手边表达式将被计算并与子查询结果逐行进行比较。 如果找到任何等于子查询行的情况,那么IN的结果就是。 如果没有找到相等行,那么结果是(包括子查询没有返回任何行的情况)。 + 右手边是一个圆括号括起来的子查询,它必须恰好返回一列。左手边表达式会被求值,并与子查询结果逐行比较。如果找到任意相等的子查询行,那么IN的结果就是。如果没有找到相等行,那么结果就是(包括子查询不返回任何行的情况)。 - 请注意如果左手边表达式得到空值,或者没有相等的右手边值, 并且至少有一个右手边行得到空值,那么IN结构的结果将是空值,而不是假。这个行为是遵照 SQL 处理空值的一般规则的。 + 请注意,如果左侧表达式得到空值,或者右侧没有相等的值且至少有一行得到空值,则IN结构的结果将是空值,而不是假。这符合 SQL 对空值布尔组合的一般规则。 - 和EXISTS一样,假设子查询将被完成运行完全是不明智的。 + 和EXISTS一样,假定子查询一定会完整运行并不明智。 @@ -20238,7 +21007,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 这种形式的IN的左手边是一个行构造器, 如中所述。 右手边是一个圆括弧子查询,它必须返回和左手边返回的行中表达式所构成的完全一样多的列。 左手边表达式将被计算并与子查询结果逐行进行比较。如果找到任意相等的子查询行,则IN的结果为。如果没有找到相等行, 那么结果为(包括子查询不返回行的情况)。 + 这种形式的IN左手边是一个行构造器,如中所述。右手边是一个圆括号括起来的子查询,它必须返回与左手边行中表达式数量完全相同的列数。左手边表达式会被求值,并与子查询结果逐行比较。如果找到任意相等的子查询行,则IN的结果为。如果没有找到相等行,那么结果为(包括子查询不返回任何行的情况)。 @@ -20254,15 +21023,15 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 右手边是一个用圆括弧包围的子查询,它必须返回正好一个列。左手边表达式将被计算并与子查询结果逐行进行比较。 如果只找到不相等的子查询行(包括子查询不返回行的情况),那么NOT IN的结果是。 如果找到任何相等行,则结果为。 + 右手边是一个圆括号括起来的子查询,它必须恰好返回一列。左手边表达式会被求值,并与子查询结果逐行比较。如果只找到不相等的子查询行(包括子查询不返回任何行的情况),那么NOT IN的结果是。如果找到任何相等行,则结果为 - 请注意如果左手边表达式得到空值,或者没有相等的右手边值, 并且至少有一个右手边行得到空值,那么NOT IN结构的结果将是空值,而不是真。这个行为是遵照 SQL 处理空值的一般规则的。 + 请注意,如果左侧表达式得到空值,或者右侧没有相等的值且至少有一行得到空值,则NOT IN结构的结果将是空值,而不是真。这符合 SQL 对空值布尔组合的一般规则。 - 和EXISTS一样,假设子查询将被完成运行完全是不明智的。 + 和EXISTS一样,假定子查询一定会完整运行并不明智。 @@ -20270,7 +21039,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 这种形式的NOT IN的左手边是一个行构造器, 如中所述。 右手边是一个圆括弧子查询,它必须返回和左手边返回的行中表达式所构成的完全一样多的列。 左手边表达式将被计算并与子查询结果逐行进行比较。如果找到不等于子查询行的行,则NOT IN的结果为。如果找到相等行, 那么结果为(包括子查询不返回行的情况)。 + 这种形式的NOT IN左侧是一个行构造器,如中所述。右侧是一个用圆括号括起来的子查询,必须返回与左侧行中表达式数量完全相同的列数。对左侧表达式求值后,将其按行与子查询结果的每一行比较。如果只找到不相等的子查询行(包括子查询不返回任何行的情况),则NOT IN的结果为。如果找到任何相等行,则结果为 @@ -20288,7 +21057,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 这种形式的右侧是一个用括号括起来的子查询,它必须恰好返回一列。左侧表达式会被求值,并使用给定的 operator 与子查询结果的每一行进行比较。如果得到任何真值结果,那么ANY的结果就是。如果没有找到真值结果,那么结果是(包括子查询没有返回任何行的情况)。 + 这种形式的右侧是一个用括号括起来的子查询,它必须恰好返回一列。左侧表达式会被求值,并使用给定的 operator 与子查询结果的每一行进行比较。该操作符必须产生布尔结果。如果得到任何真值结果,那么ANY的结果就是。如果没有找到真值结果,那么结果是(包括子查询没有返回任何行的情况)。 @@ -20296,11 +21065,11 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 请注意如果没有任何成功并且至少有一个右手边行为该操作符结果生成空值, 那么ANY结构的结果将是空值,而不是假。 这个行为是遵照 SQL 处理空值布尔组合的一般规则制定的。 + 请注意,如果没有任何比较返回真,并且至少有一个右侧行的操作符结果为空值,则ANY结构的结果将是空值,而不是假。这符合 SQL 对空值布尔组合的一般规则。 - 和EXISTS一样,假设子查询将被完成运行完全是不明智的。 + 和EXISTS一样,假定子查询一定会完整运行并不明智。 @@ -20309,7 +21078,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 这种形式的左侧是一个行构造器,如所述。右侧是一个用括号括起来的子查询,它必须返回与左侧行中表达式数量完全相同的列数。左侧表达式会被求值,并使用给定的operator与子查询结果的每一行逐行比较。如果比较对任何子查询行返回真,则ANY的结果为。如果比较对每一个子查询行都返回假,则结果为(包括子查询不返回行的情况)。如果比较对任何行都不返回真,并且至少有一次比较返回 NULL,则结果为 NULL。 + 这种形式的ANY左侧是一个行构造器,如所述。右侧是一个用括号括起来的子查询,它必须返回与左侧行中表达式数量完全相同的列数。左侧表达式会被求值,并使用给定的operator与子查询结果的每一行逐行比较。如果比较对任何子查询行返回真,则ANY的结果为。如果比较对每一个子查询行都返回假,则结果为(包括子查询不返回行的情况)。如果比较对任何行都不返回真,并且至少有一次比较返回 NULL,则结果为 NULL。 @@ -20325,7 +21094,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 这种形式的 ALL 右侧是一个用括号括起来的子查询,它必须只返回一列。左侧表达式会被求值,并使用给定的 operator 与子查询结果的每一行进行比较。该操作符必须产生布尔结果。如果所有行都得到真(包括子查询没有返回任何行的情况),ALL 的结果就是。如果发现任何假值结果,结果就是。如果比较对任何行都不返回假,并且至少有一次比较返回 NULL,则结果为 NULL。 + 右侧是一个用圆括号括起来的子查询,必须恰好返回一列。左侧表达式会被求值,并使用给定的operator与子查询结果的每一行进行比较。该操作符必须产生布尔结果。如果所有行都得到真(包括子查询不返回任何行的情况),则ALL的结果为。如果得到任何假值结果,则结果为。如果与任何子查询行的比较都不返回假,并且至少有一次比较返回 NULL,则结果为 NULL。 @@ -20333,7 +21102,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 和EXISTS一样,假设子查询将被完成运行完全是不明智的。 + 和EXISTS一样,假定子查询一定会完整运行并不明智。 @@ -20363,7 +21132,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 左手边是一个行构造器,如所述。 右手边是一个圆括弧括起来的子查询,该查询必须返回和左手边行中表达式数目完全一样的列。 另外,该子查询不能返回超过一行的数量(如果它返回零行,那么结果就是空值)。 左手边被计算并逐行与右手边的子查询结果行比较。 + 左侧是一个行构造器,如所述。右侧是一个用圆括号括起来的子查询,必须返回与左侧行中表达式数量完全相同的列数。此外,该子查询不能返回超过一行;如果它返回零行,则结果为空值。对左侧求值后,将所得的行与子查询返回的唯一一行进行比较。 @@ -20402,12 +21171,12 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 逐行比较 + 行比较 比较 - 逐行 + 复合类型 @@ -20424,7 +21193,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 本节描述几个特殊的结构,用于在值的组之间进行多重比较。这些形式语法上和前面一节的子查询形式相关,但是不涉及子查询。 这种形式涉及的数组子表达式是PostgreSQL的扩展; 其它的是SQL兼容的。所有本节记录的表达式形式都返回布尔(Boolean)结果(真/假)。 + 本节描述几个特殊的结构,用于在值的组之间进行多重比较。这些形式语法上和前面一节的子查询形式相关,但是不涉及子查询。 涉及数组子表达式的形式是PostgreSQL的扩展; 其余形式是SQL兼容的。本节介绍的所有表达式形式都返回布尔(Boolean)结果(真/假)。 @@ -20435,14 +21204,12 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 右侧是一个用括号括起来的表达式列表。如果左侧表达式的结果等于右侧任何一个表达式的结果,则结果为true。 - 这是一个简写表示法,如下所示: - + 右侧是一个用圆括号括起来的表达式列表。如果左侧表达式的结果等于右侧任一表达式的结果,则结果为。这等价于以下写法: expression = value1 -或 +OR expression = value2 -或 +OR ... @@ -20460,9 +21227,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 右侧是一个用括号括起来的表达式列表。如果左侧表达式的结果与所有右侧表达式都不相等,则结果为true。 - 这是一个简写表示法,用于 - + 右侧是一个用圆括号括起来的表达式列表。如果左侧表达式的结果与右侧所有表达式的结果都不相等,则结果为。这等价于以下写法: expression <> value1 AND @@ -20486,7 +21251,7 @@ AND - <literal>ANY</literal>/<literal>SOME</literal> (array) + <literal>ANY</literal>/<literal>SOME</literal>(数组) expression operator ANY (array expression) @@ -20508,7 +21273,7 @@ AND - <literal>ALL</literal> (array) + <literal>ALL</literal>(数组) expression operator ALL (array expression) @@ -20532,20 +21297,7 @@ AND - 每一边都是一个行构造器, - 如在中描述的那样。 - 这两个行构造器必须具有相同数量的字段。 - 给定的operator应用于每一对 - 对应的字段。(由于字段可能是不同类型的,这意味着每对可能选择不同的具体操作符。) - 所有选定的操作符必须是某个B-树操作符类的成员,或者是B-树操作符类的=成员的否定形式, - 这意味着只有当operator是 - =、 - <>、 - <、 - <=、 - >或 - >=时才可能进行行构造器比较, - 或者具有类似于这些操作符的语义。 + 两侧都是行构造器,如所述。两个行构造器必须具有相同数量的字段。给定的operator应用于每一对对应字段。(由于字段可能具有不同的类型,因此可能为各对字段选择不同的具体操作符。)所选操作符必须是某个 B-树操作符类的成员,或者是 B-树操作符类中=成员的否定操作符。这意味着只有当operator=<><<=>>=,或具有与这些操作符类似的语义时,才可以进行行构造器比较。 @@ -20556,12 +21308,7 @@ AND 对于<<=>>=这几种情况,会从左到右比较各行元素,一旦找到一对不相等或含有 null 的元素就立即停止。如果这对元素中的任意一个为 null,那么行比较的结果就是未知(null);否则,这对元素的比较结果决定整个行比较的结果。例如,ROW(1,2,NULL) < ROW(1,3,0)的结果为真,而不是 null,因为第三对元素并不会被考虑。 - - - 在PostgreSQL 8.2 之前,<<=>>=这几种情况并不是按照 SQL 规范处理的。像ROW(a,b) < ROW(c,d)这样的比较会被实现为a < c AND b < d,而正确行为应当等价于a < c OR (a = c AND b < d)。 - - row_constructor IS DISTINCT FROM row_constructor @@ -20590,21 +21337,21 @@ AND - SQL 规范要求在结果依赖于比较两个 NULL 值或者一个 NULL 与一个非 NULL 时逐行比较返回 NULL。 + SQL 规范要求在结果依赖于比较两个 NULL 值或者一个 NULL 与一个非 NULL 时行比较返回 NULL。 PostgreSQL只有在比较两个行构造器(如)的结果或者比较一个行构造器与一个子查询的输出时才这样做(如中所述)。 - 在其他比较两个复合类型值的环境中,两个 NULL 域值被认为相等,并且一个 NULL 被认为大于一个非 NULL。 + 在其他比较两个复合类型值的环境中,两个 NULL 字段值被认为相等,并且一个 NULL 被认为大于一个非 NULL。 为了得到复合类型的一致的排序和索引行为,这样做是必要的。 - 每一边都会被计算并且它们会被逐行比较。当operator是 + 对两侧分别求值后,按行进行比较。当operator=<><<=>或者 - >=时或者具有与这些类似的语义时,允许复合类型的比较(更准确地说,如果一个操作符是一个 B-树操作符类的成员,或者是一个 B-树操作符类的=成员的否定词,它就可以是一个行比较操作符)。 - 上述操作符的行为与用于行构造器(见)的IS [ NOT ] DISTINCT FROM相同。 + >=时或者具有与这些类似的语义时,允许复合类型的比较(更准确地说,如果一个操作符是一个 B-树操作符类的成员,或者是一个 B-树操作符类的=成员的否定操作符,它就可以是一个行比较操作符)。 + 上述操作符的默认行为与用于行构造器(见)的IS [ NOT ] DISTINCT FROM相同。 @@ -20615,9 +21362,9 @@ AND *<=*>以及 *>=。 - 这些操作符比较两行的内部二进制表达。即使两行用相等操作符的比较为真,两行也可能具有不同的二进制表达。 - 行在这些比较操作符之下的排序是决定性的,其他倒没什么意义。 - 这些操作符在内部被用于物化视图并且可能对其他如复制和B-树复制(参见 )之类的特殊功能有用,但是它们并不打算用在书写查询这类普通用途中。 + 这些操作符比较两行的内部二进制表示。即使两行用相等操作符的比较为真,两行也可能具有不同的二进制表示。 + 使用这些比较操作符得到的行排序是确定的,但除此之外没有其他意义。 + 这些操作符在内部被用于物化视图并且可能对其他如复制和 B-树去重(参见 )之类的特殊功能有用,但是它们并不打算用在书写查询这类普通用途中。 @@ -20632,13 +21379,13 @@ AND - 本节描述那些可能返回多于一行的函数。目前这个类中被使用最广泛的是级数生成函数, 如所述。其他更特殊的集合返回函数在本手册的其他地方描述。 - 组合多集合返回函数的方法可见。 + 本节描述那些可能返回多于一行的函数。目前这个类中被使用最广泛的是序列生成函数, 如所述。其他更特殊的集合返回函数在本手册的其他地方描述。 + 组合多个集合返回函数的方法可见 - 级数生成函数 + 序列生成函数 @@ -20694,9 +21441,7 @@ AND
- 当step为正时,如果start大于stop则返回零行。 - 相反,当step为负时,如果start小于stop则返回零行。 - 如果任何输入为NULL也会返回零行。step为零是一个错误。下面是一些示例: + 当step为正数时,如果start大于stop,则返回零行。反之,当step为负数时,如果start小于stop,则返回零行。如果任一输入为NULL,也返回零行。如果step为零,则会报错。下面是一些示例: SELECT * FROM generate_series(2,4); generate_series @@ -20727,7 +21472,7 @@ SELECT generate_series(1.1, 4, 1.3); 3.7 (3 rows) --- this example relies on the date-plus-integer operator: +-- 此示例使用日期加整数的操作符: SELECT current_date + s.a AS dates FROM generate_series(0,14,7) AS s(a); dates ------------ @@ -20751,7 +21496,7 @@ SELECT * FROM generate_series('2008-03-01 00:00'::timestamp, 2008-03-04 08:00:00 (9 rows) --- 此示例假定 TimeZone 设置为 UTC;注意 DST 转换: +-- 此示例假定 TimeZone 设为 UTC;请注意夏令时(DST)切换: SELECT * FROM generate_series('2001-10-22 00:00 -04:00'::timestamptz, '2001-11-01 00:00 -05:00'::timestamptz, '1 day'::interval, 'America/New_York'); @@ -20799,7 +21544,7 @@ SELECT * FROM generate_series('2001-10-22 00:00 -04:00'::timestamptz, setof integer - 生成一个包含给定数组第dim维度的有效下标的序列。 + 生成一个包含给定数组第dim维的有效下标的序列。 @@ -20809,7 +21554,7 @@ SELECT * FROM generate_series('2001-10-22 00:00 -04:00'::timestamptz, setof integer
- 生成一个包含给定数组第dim维度的有效下标的序列。当reverse为真时,以相反的顺序返回序列。 + 生成一个包含给定数组第dim维的有效下标的序列。当reverse为真时,以相反的顺序返回序列。 @@ -20818,9 +21563,9 @@ SELECT * FROM generate_series('2001-10-22 00:00 -04:00'::timestamptz, generate_subscripts是一个快捷函数,它为给定数组的指定维度生成一组合法的下标。 - 对于不具有请求维度的数组返回零行,对于任何输入为NULL数组也返回零行。下面是一些示例: + 如果数组不具有所请求的维度,或者任一输入为NULL,则返回零行。下面是一些示例: --- basic usage: +-- 基本用法: SELECT generate_subscripts('{NULL,1,NULL,2}'::int[], 1) AS s; s --- @@ -20830,8 +21575,8 @@ SELECT generate_subscripts('{NULL,1,NULL,2}'::int[], 1) AS s; 4 (4 rows) --- presenting an array, the subscript and the subscripted --- value requires a subquery: +-- 展示数组、下标和下标对应的值 +-- 需要使用子查询: SELECT * FROM arrays; a -------------------- @@ -20850,7 +21595,7 @@ FROM (SELECT generate_subscripts(a, 1) AS s, a FROM arrays) foo; {100,200,300} | 3 | 300 (5 rows) --- unnest a 2D array: +-- 展开二维数组: CREATE OR REPLACE FUNCTION unnest2(anyarray) RETURNS SETOF anyelement AS $$ select $1[i][j] @@ -20870,15 +21615,13 @@ SELECT * FROM unnest2(ARRAY[[1,2],[3,4]]); - ordinality + 序号 - 当FROM子句中的函数以WITH ORDINALITY作为后缀时,将在函数的输出列上附加一个bigint列,该列从1开始,函数输出的每一行加1。 - 这在 unnest()等集合返回函数的情况下最有用。 - + 当FROM子句中的函数后面加上WITH ORDINALITY时,一个bigint列会追加到函数的输出列中,其值从 1 开始,对函数输出的每一行递增 1。这种方式对集合返回函数尤其有用,例如unnest() --- set returning function WITH ORDINALITY: +-- 集合返回函数与 WITH ORDINALITY: SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); ls | n -----------------+---- @@ -20911,11 +21654,15 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); 系统信息函数和操作符 + + 本节描述的函数用于获取有关PostgreSQL安装的各种信息。 + + 会话信息函数 - 展示了多个可以抽取会话和系统信息的函数。 + 列出了多个用于提取会话和系统信息的函数。 @@ -20956,7 +21703,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); name - 返回当前数据库的名称。(在SQL标准中数据库被称为catalogs,因此current_catalog是该标准的拼写方式。) + 返回当前数据库的名称。(SQL 标准将数据库称为目录(catalogs),因此current_catalog是标准中的写法。) @@ -20969,7 +21716,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); text - 返回当前所执行查询的文本,由客户端提交的(可能包含一个以上的语句)。 + 返回客户端提交的当前正在执行的查询文本(可能包含多条语句)。 @@ -20992,8 +21739,8 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); current_schema - schema - current + 模式 + 当前 current_schema name @@ -21014,16 +21761,14 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); current_schemas - search path - current + 搜索路径 + 当前 current_schemas ( include_implicit boolean ) name[]
- 返回当前在有效搜索路径中的所有模式的名称的数组,以优先级顺序。 - (当前 设置中与已存在的、可搜索模式不相符的项将被省略。) - 如果布尔参数为true,则类似pg_catalog的隐式搜索的系统模式将包含在结果中。 + 返回当前有效搜索路径中所有模式名称的数组,按优先级排序。(当前设置中不对应于已存在且可搜索的模式的项会被省略。)如果布尔参数为true,结果还会包含pg_catalog等隐式搜索的系统模式。 @@ -21033,8 +21778,8 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); current_user - user - current + 用户 + 当前 current_user name @@ -21053,7 +21798,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); inet
- 返回当前客户端的IP地址,如果当前连接是通过Unix-域套接字则返回NULL + 返回当前客户端的 IP 地址;如果当前连接通过 Unix 域套接字建立,则返回NULL @@ -21066,7 +21811,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); integer
- 返回当前客户端的IP端口号,如果当前连接是通过Unix-域套接字则返回NULL。 + 返回当前客户端的IP端口号,如果当前连接是通过Unix 域套接字则返回NULL @@ -21079,7 +21824,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); inet
- 返回服务器接受当前连接的IP地址,如果当前连接是通过Unix-域套接字则返回NULL。 + 返回服务器接受当前连接的IP地址,如果当前连接是通过Unix 域套接字则返回NULL @@ -21092,7 +21837,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); integer
- 返回服务器接受当前连接的IP端口号,如果当前连接是通过Unix-域套接字则返回NULL。 + 返回服务器接受当前连接的IP端口号,如果当前连接是通过Unix 域套接字则返回NULL @@ -21118,12 +21863,10 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); integer[] - 返回阻止服务器进程的会话的进程ID数组,该进程ID与指定的进程ID一起获取锁定,如果没有这样的服务器进程或者没有被阻塞,则返回一个空数组。 + 返回一个数组,包含阻止指定进程 ID 对应的服务器进程获取锁的会话进程 ID;如果不存在这样的服务器进程,或该进程未被阻塞,则返回空数组。 - 如果一个服务器进程持有一个与被阻塞进程的锁请求冲突的锁(硬阻塞),或者正在等待一个与被阻塞进程的锁请求冲突并且在等待队列中位于其前面的锁(软阻塞),那么这个服务器进程就会阻塞另一个服务器进程。 - 当使用并行查询时结果总是列出客户端可见的进程ID(即pg_backend_pid的结果),即使实际的锁是由子工作进程持有或等待的。 - 因此,结果中可能存在重复的pid。还要注意当准备好的事务持有冲突锁时,它将用零进程ID表示。 + 一个服务器进程会在以下情况下阻塞另一个进程:它持有与被阻塞进程请求的锁冲突的锁(硬阻塞);或者它正在等待一个会与被阻塞进程请求的锁冲突的锁,并且在等待队列中位于被阻塞进程之前(软阻塞)。使用并行查询时,即使实际持锁或等待锁的是子工作进程,结果也始终列出客户端可见的进程 ID(即pg_backend_pid的结果)。因此,结果中可能出现重复的 PID。另外,如果持有冲突锁的是一个预备事务,结果中会用进程 ID 0 表示它。 频繁调用这个函数可能会对数据库性能产生一些影响,因为它需要在短时间内独占访问锁管理器的共享状态。 @@ -21139,8 +21882,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); timestamp with time zone - 返回服务器配置文件最后加载的时间。如果当前会话当时是活跃的,那么这将是会话本身重新读取配置文件的时间(因此在不同的会话中读取会稍有不同)。 - 否则,就是postmaster进程重新读取配置文件的时间。 + 返回服务器配置文件最近一次加载的时间。如果当时当前会话已经存在,则返回该会话自身重新读取配置文件的时间(因此不同会话中的返回时间会略有不同)。否则,返回 postmaster 进程重新读取配置文件的时间。 @@ -21150,16 +21892,16 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); pg_current_logfile - Logging - pg_current_logfile函数 + 日志记录 + pg_current_logfile 函数 current_logfiles - 和pg_current_logfile函数 + 和pg_current_logfile 函数 - Logging - current_logfiles文件和pg_current_logfile函数 + 日志记录 + current_logfiles 文件和pg_current_logfile 函数 pg_current_logfile ( text ) text @@ -21175,7 +21917,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); 结果反映current_logfiles文件的内容。 - 默认情况下,此函数仅限于超级用户以及具有pg_monitor角色权限的角色,但可以向其他用户授予 EXECUTE 权限以运行该函数。 + 默认情况下,此函数仅限超级用户和具有pg_monitor角色权限的角色使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -21269,7 +22011,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); double precision - 返回当前被等待处理的通知所占用的异步通知队列最大尺寸的分数(0–1)。更多信息请参见。 + 返回待处理通知当前占用的空间占异步通知队列最大容量的比例(0–1)。更多信息请参见 @@ -21295,11 +22037,11 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); integer[] - 返回一个进程ID数组,该进程ID是阻塞服务器进程获取安全快照的会话的进程ID数组,如果没有这样的服务器进程或者没有阻塞,则返回一个空数组。 + 返回一个数组,包含阻止指定进程 ID 对应的服务器进程获取安全快照的会话进程 ID;如果不存在这样的服务器进程,或该进程未被阻塞,则返回空数组。 运行SERIALIZABLE事务的会话会阻止SERIALIZABLE READ ONLY DEFERRABLE事务获取快照,直到后者确定可以安全地避免获取谓词锁。 - 关于可串行化和可延迟事务的更多信息,请参见。 + 关于可序列化和可延迟事务的更多信息,请参见 频繁调用这个函数可能会对数据库性能产生一些影响,因为它需要在短时间内访问谓词锁管理器的共享状态。 @@ -21315,7 +22057,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); integer - 返回当前嵌套层次的PostgreSQL触发器(如果没有调用则为 0,直接或间接,从一个触发器内部开始)。 + 返回PostgreSQL触发器的当前嵌套层级(如果不是从触发器内部直接或间接调用,则为 0)。 @@ -21328,7 +22070,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); name - 返回会话用户名. + 返回会话用户名。 @@ -21358,20 +22100,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); - - - - version - - version () - text - - - 返回描述PostgreSQL服务器的版本的字符串。 - 你还可以从 中获得此信息,或者对于机器可读的版本,使用。 - 软件开发人员可以使用server_version_num(从8.2起可用)或,而不是解析文本版本。 - - + @@ -21379,17 +22108,12 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); - current_catalogcurrent_rolecurrent_schemacurrent_usersession_useruserSQL里有特殊的语法地位: 它们被调用时结尾不要跟着圆括号。 - 在 PostgreSQL 中,圆括号可以有选择性地被用于current_schema,但是不能和其他的一起用。 + current_catalogcurrent_rolecurrent_schemacurrent_usersession_useruserSQL中具有特殊语法:调用时不得在后面加圆括号。在 PostgreSQL 中,current_schema可以选择加圆括号,其他函数则不可以。 - session_user通常是发起当前数据库连接的用户,不过超级用户可以用修改这个设置。 - current_user是用于权限检查的用户标识。通常, 它总是等于会话用户,但是可以被改变。 - 它也会在函数执行的过程中随着属性SECURITY DEFINER的改变而改变。 - 在 Unix 的说法里,那么会话用户是真实用户,而当前用户是有效用户。 - current_role以及usercurrent_user的同义词(SQL标准在current_rolecurrent_user之间做了区分,但PostgreSQL不区分,因为它把用户和角色统一成了一种实体)。 + session_user通常是发起当前数据库连接的用户,但超级用户可以用修改此设置。current_user是用于权限检查的用户标识,通常等于会话用户,但可以用更改。在执行具有SECURITY DEFINER属性的函数期间,它也会改变。用 Unix 的术语来说,会话用户是真实用户,当前用户是有效用户current_roleusercurrent_user的同义词。(SQL 标准区分current_rolecurrent_user,但PostgreSQL不区分,因为它将用户和角色统一为同一种实体。)
@@ -21399,18 +22123,12 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); 访问权限查询函数 - privilege - querying + 权限 + 查询 - 列出那些允许编程查询对象访问权限的函数。参阅获取更多有关权限的信息。 - 在这些函数中,可以通过名称或OID (pg_authid.oid)指定被查询权限的用户,或者如果名称被指定为public,则检查PUBLIC伪角色的权限。 - 同样,user参数可以完全省略,在这种情况下,假设为current_user。被查询的对象也可以通过名称或OID来指定。 - 通过名称指定时,可以包含相关的模式名称。感兴趣的访问权限由一个文本字符串指定,它必须计算为对象类型的一个适当的权限关键字(例如,SELECT)。 - 还可以将 WITH GRANT OPTION添加到权限类型中,以测试该权限是否由授予选项持有。 - 同样,可以用逗号分隔列出多个权限类型,在这种情况下,如果所列出的权限中有任何一个被持有,结果将为真。 - (权限字符串的大小写不重要,权限名之间允许有额外的空格,但在权限名中不允许。)一些示例: + 列出了允许以编程方式查询对象访问权限的函数。(关于权限的更多信息,请参见。)在这些函数中,可以通过名称或 OID(pg_authid.oid)指定要查询权限的用户;如果名称为public,则检查 PUBLIC 伪角色的权限。也可以完全省略user参数,此时使用current_user。要查询的对象也可以通过名称或 OID 指定。通过名称指定时,如适用,可以包含模式名。所需访问权限由文本字符串指定,其值必须为适用于该对象类型的权限关键字之一(例如SELECT)。还可以在权限类型后附加WITH GRANT OPTION,以检查是否拥有该权限及其授予选项。也可以用逗号分隔列出多个权限类型;只要拥有列出的任一权限,结果就为真。(权限字符串不区分大小写,权限名之间允许有额外的空白,但权限名内部不允许。)例如: SELECT has_table_privilege('myschema.mytable', 'select'); SELECT has_table_privilege('joe', 'mytable', 'INSERT, SELECT WITH GRANT OPTION'); @@ -21447,9 +22165,7 @@ SELECT has_table_privilege('joe', 'mytable', 'INSERT, SELECT WITH GRANT OPTION') boolean - 用户是否对表的任何列有权限? - 如果对整个表持有权限,或者对至少一个列有列级的权限授予,则会成功。 - 允许的权限类型为SELECT, INSERT,UPDATE, 和 REFERENCES + 用户是否对表的至少一列具有权限?如果拥有整个表的权限,或至少一列获得了该权限的列级授权,则返回真。允许的权限类型为SELECTINSERTUPDATEREFERENCES @@ -21500,7 +22216,7 @@ SELECT has_table_privilege('joe', 'mytable', 'INSERT, SELECT WITH GRANT OPTION') boolean - 用户是否拥有外部数据包装的权限?唯一允许的权限类型是USAGE。 + 用户是否具有外部数据包装器权限?唯一允许的权限类型为USAGE @@ -21604,7 +22320,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); boolean - 用户是否有顺序权限?允许的权限类型有USAGE, SELECT, 和UPDATE。 + 用户是否具有序列权限?允许的权限类型为USAGESELECTUPDATE @@ -21685,11 +22401,11 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); boolean - 用户对角色有权限吗?允许的权限类型有MEMBERUSAGESET。 + 用户是否具有角色权限?允许的权限类型为MEMBERUSAGESETMEMBER表示对该角色的直接或间接成员资格,而不考虑由此授予的具体权限。 USAGE表示该角色的权限是否无需执行SET ROLE即可立即使用,而SET表示是否可以使用SET ROLE命令切换到该角色。 任一权限类型后面都可以附加WITH ADMIN OPTIONWITH GRANT OPTION,用于测试是否持有 ADMIN 权限(这六种写法测试的都是同一件事)。 - 此函数不允许特殊情况下将user设置为public,因为PUBLIC伪角色永远不能成为真实角色的成员。 + 此函数不允许将user设置为public这一特殊情况,因为 PUBLIC 伪角色永远不能成为实际角色的成员。 @@ -21703,7 +22419,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); boolean - 在当前用户和当前环境的上下文之中,指定表的行级安全是活动的吗? + 在当前用户和当前环境的上下文中,指定表的行级安全性是否生效? @@ -21711,8 +22427,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); - 显示了aclitem类型的可用操作符,它是访问权限的目录表示。 - 有关如何读取访问权限值的信息,请参阅 。 + 列出了aclitem类型可用的操作符;该类型是访问权限在系统目录中的表示形式。有关如何解读访问权限值的信息,请参见 @@ -21745,8 +22460,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); boolean - aclitem相等吗?(注意,aclitem类型缺少比较操作符的通常集合;它只有相等。 - 反而言之,aclitem数组只能进行相等比较。) + 两个aclitem是否相等?(注意,aclitem类型没有通常的整套比较操作符,而只支持相等比较。因此,aclitem数组也只能进行相等比较。) 'calvin=r*w/hobbes'::aclitem = 'calvin=r*w*/hobbes'::aclitem @@ -21763,7 +22477,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); boolean - 数组是否包含指定的权限?(如果有一个数组条目与aclitem的被授权人和授予人相匹配,并且至少具有权限的指定集,则此选项为真。) + 数组是否包含指定的权限?(如果数组中存在一个条目,其被授权者和授权者与该aclitem相同,且至少包含指定的全部权限,则返回真。) '{calvin=r*w/hobbes,hobbes=r*w*/postgres}'::aclitem[] @> 'calvin=r*/hobbes'::aclitem @@ -21775,7 +22489,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute');
- 显示了一些额外的函数来管理aclitem类型。 + 列出了一些用于管理aclitem类型的其他函数。 @@ -21807,23 +22521,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); aclitem[] - 构造一个aclitem数组,保存属于具有OID ownerId的角色的对象类型type的默认访问权限。 - 这表示当对象的ACL条目为空时将假定的访问权限。(默认访问权限在中描述。) - type参数必须是以下之一: - 'c'表示COLUMN, - 'r'表示TABLE和类似表的对象, - 's'表示SEQUENCE, - 'd'表示DATABASE, - 'f'表示FUNCTIONPROCEDURE, - 'l'表示LANGUAGE, - 'L'表示LARGE OBJECT, - 'n'表示SCHEMA, - 'p'表示PARAMETER, - 't'表示TABLESPACE, - 'F'表示FOREIGN DATA WRAPPER, - 'S'表示FOREIGN SERVER, - 或 - 'T'表示TYPEDOMAIN。 + 构造一个aclitem数组,保存类型为type、属于 OID 为ownerId的角色的对象的默认访问权限。当对象的ACL条目为空值时,会采用这些访问权限。(默认访问权限见。)type参数必须为以下值之一:'c' 表示COLUMN,'r' 表示TABLE和类似表的对象,'s' 表示SEQUENCE,'d' 表示DATABASE,'f' 表示FUNCTIONPROCEDURE,'l' 表示LANGUAGE,'L' 表示LARGE OBJECT,'n' 表示SCHEMA,'p' 表示PARAMETER,'t' 表示TABLESPACE,'F' 表示FOREIGN DATA WRAPPER,'S' 表示FOREIGN SERVER,'T' 表示TYPEDOMAIN @@ -21840,9 +22538,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); is_grantableboolean ) - 以行集的形式返回aclitem数组。如果受让人是伪角色PUBLIC,则在grantee列中用0表示。 - 每个被授予的权限都表示为SELECT, INSERT等。 - 注意,每个权限被分割成单独的一行,因此在privilege_type列中只出现一个关键字。 + 以行集的形式返回aclitem数组。如果被授权者是伪角色 PUBLIC,则在grantee列中用零表示。每项授予的权限表示为SELECTINSERT等(完整列表见)。注意,每项权限都会拆成单独的一行,因此privilege_type列中只会出现一个关键字。 @@ -21859,7 +22555,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); aclitem - 使用给定的属性构造 aclitem 。 + 使用给定的属性构造aclitemprivileges是以逗号分隔的权限名列表,例如SELECTINSERT等,列出的所有权限都会设置在结果中。(权限字符串不区分大小写,权限名之间允许有额外的空白,但权限名内部不允许。) @@ -21873,14 +22569,9 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); 模式可见性查询函数 - 展示了决定是否一个特定对象在当前模式搜索路径中可见的函数。 - 例如,如果一个表所在的模式在当前搜索路径中并且在它之前没有出现过相同的名字,这个表就被说是可见的。 - 这等价于在语句中表可以被用名称引用但不加显式的模式限定。因此,要列出所有可见表的名字: - + 列出了判断某个特定对象是否可见的函数,其判断依据是当前模式搜索路径。例如,如果表所在的模式位于搜索路径中,并且在搜索路径的更前面没有同名表,就称该表可见。这等价于说,可以只通过表名引用该表,而不必显式地用模式限定。因此,要列出所有可见表的名称: SELECT relname FROM pg_class WHERE pg_table_is_visible(oid); - - 对于函数和操作符,如果路径前面没有相同名称和参数数据类型的对象,那么搜索路径中的对象就是可见的。 - 对于操作符类和操作符族,要考虑名称和关联的索引访问方法。 +对于函数和操作符,只要搜索路径中更靠前的位置没有对象具有与被检查对象相同的名称和参数数据类型,就称被检查对象可见。对于操作符类和操作符族,会同时考虑名称及关联的索引访问方法。 @@ -22019,7 +22710,7 @@ SELECT relname FROM pg_class WHERE pg_table_is_visible(oid); boolean - 文本搜索配置在搜索路径可见吗? + 全文检索配置是否在搜索路径中可见? @@ -22032,7 +22723,7 @@ SELECT relname FROM pg_class WHERE pg_table_is_visible(oid); boolean - 文本搜索字典在搜索路径可见吗? + 全文检索词典是否在搜索路径中可见? @@ -22045,7 +22736,7 @@ SELECT relname FROM pg_class WHERE pg_table_is_visible(oid); boolean - 文本搜索解析器在搜索路径中可见吗? + 全文检索解析器是否在搜索路径中可见? @@ -22058,7 +22749,7 @@ SELECT relname FROM pg_class WHERE pg_table_is_visible(oid); boolean - 文本搜索模板在搜索路径可见吗? + 全文检索模板是否在搜索路径中可见? @@ -22079,11 +22770,10 @@ SELECT relname FROM pg_class WHERE pg_table_is_visible(oid);
- 所有这些函数都要求用对象 OID 来标识将被检查的对象。如果你想用名称来测试一个对象,使用 OID 别名类型(regclassregtyperegprocedureregoperatorregconfigregdictionary)将会很方便。例如: - + 所有这些函数都需要用对象 OID 标识要检查的对象。如果想按名称测试对象,使用 OID 别名类型会很方便(regclassregtype, + regprocedureregoperatorregconfig,或regdictionary),例如: SELECT pg_type_is_visible('myschema.widget'::regtype); - - 注意以这种方式测试一个非模式限定的类型名没什么意义 — 如果该名称完全能被识别,它必须是可见的。 +注意,用这种方式测试不带模式限定的类型名并没有太大意义:只要该名称能够被识别,它就必然可见。 @@ -22115,7 +22805,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); - + format_type @@ -22127,6 +22817,26 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); + + + + pg_basetype + + pg_basetype ( regtype ) + regtype + + + 返回由类型 OID 标识的域的基础类型 OID。如果参数是非域类型的 OID,则原样返回该参数。如果参数不是有效的类型 OID,则返回 NULL。如果存在域依赖链,则递归查找,直到找到基础类型。 + + + 假设执行了CREATE DOMAIN mytext AS text: + + + pg_basetype('mytext'::regtype) + text + + + @@ -22173,7 +22883,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); 返回一组记录,描述存在于PostgreSQL系统目录中的外键关系。 fktable 列包含引用目录的名称,fkcols列包含引用列的名称。 类似地,pktable列包含被引用目录的名称,而pkcols列包含被引用列的名称。 - 如果is_array为真,则最后一个引用列是一个数组,其每个元素都应该与引用目录中的某个条目匹配。 + 如果is_array为真,则最后一个引用列是一个数组,其每个元素都应该与被引用目录中的某个条目匹配。 如果is_opt为真,则允许引用列包含零而不是有效引用。 @@ -22187,7 +22897,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 重构为了约束的创建命令。(这是一个反编译的重构,而不是命令的原始文本。) + 重建约束的创建命令。(这是反编译重建的结果,并非命令的原始文本。) @@ -22200,8 +22910,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 反编译存储在系统目录中的表达式的内部形式,例如列的默认值。 - 如果表达式可能包含变量,则指定它们所指向的关系的OID作为第二个参数;如果没有预期的变量,传递0就可以了。 + 反编译存储在系统目录中的表达式的内部形式,例如列的默认值。如果表达式可能包含 Var 节点,请将它们所引用的关系的 OID 指定为第二个参数;如果预计不含 Var 节点,传入零即可。 @@ -22214,8 +22923,8 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 重构为了函数或过程的创建命令。(这是一个反编译的重构,而不是命令的原始文本。) - 结果是一个完整的CREATE OR REPLACE FUNCTIONCREATE OR REPLACE PROCEDURE语句。 + 重建函数或过程的创建命令。(这是反编译重建的结果,并非命令的原始文本。) + 结果是一条完整的CREATE OR REPLACE FUNCTIONCREATE OR REPLACE PROCEDURE语句。 @@ -22228,7 +22937,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 重新构造函数或过程的参数列表,以其在 CREATE FUNCTION里面需要出现的形式(包括默认值)。 + 重建函数或过程的参数列表,采用其在CREATE FUNCTION中应有的形式(包括默认值)。 @@ -22241,7 +22950,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 重新构造标识函数或过程所需的参数列表,以其应出现在ALTER FUNCTION等命令中的形式。这个表单省略默认值。 + 重建标识函数或过程所需的参数列表,采用其在ALTER FUNCTION等命令中应有的形式。这种形式省略默认值。 @@ -22254,7 +22963,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 重构函数的RETURNS子句,以其需要出现在CREATE FUNCTION中的形式。对于过程,返回NULL。 + 重建函数的RETURNS子句,采用其在CREATE FUNCTION中应有的形式。对于过程,返回NULL @@ -22267,7 +22976,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 重构针对索引的创建命令。(这是一个反编译的重构,而不是命令的原始文本。)如果提供了column而且不为零,则只重构该列的定义。 + 重建索引的创建命令。(这是反编译重建的结果,并非命令的原始文本。)如果提供了column而且不为零,则只重建该列的定义。 @@ -22285,11 +22994,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); baredesc text ) - 返回一组描述服务器识别的SQL关键字的记录。word列包含关键字。 - catcode列包含一个类别代码:U表示无保留关键字,C表示可以是列名的关键字,T表示可以是类型或函数名的关键字,或者R表示完全保留关键字。 - 如果关键字可以在SELECT列表中用作bare列标签,则barelabel列包含true,或者false,如果它只能在AS之后使用。 - catdesc列包含可能本地化字符串,描述关键字的类别。 - baredesc列包含可能本地化的字符串,描述关键字的列标签状态。 + 返回描述服务器所识别 SQL 关键字的一组记录。word列包含关键字。catcode列包含类别代码:U表示非保留关键字,C表示可用作列名的关键字,T表示可用作类型名或函数名的关键字,R表示完全保留的关键字。如果关键字可以在SELECT列表中用作列标签,barelabel列为true;如果只能在AS之后使用,则为falsecatdesc列包含描述关键字类别的字符串,该字符串可能已被本地化。baredesc列包含描述关键字列标签状态的字符串,该字符串可能已被本地化。 @@ -22301,8 +23006,20 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 重构分区约束的定义。 - (这是反编译得到的重构结果,而不是命令的原始文本。) + 重建分区约束的定义。(这是反编译重建的结果,并非命令的原始文本。) + + + + + + + pg_get_partkeydef + + pg_get_partkeydef ( table oid ) + text + + + 重建分区表的分区键定义,采用其在CREATE TABLEPARTITION BY子句中的形式。(这是反编译重建的结果,并非命令的原始文本。) @@ -22315,7 +23032,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 重构针对规则的创建命令。(这是一个反编译的重构,而不是命令的原始文本。) + 重建规则的创建命令。(这是反编译重建的结果,并非命令的原始文本。) @@ -22330,15 +23047,15 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); 返回与列相关联的序列名称,如果没有序列与该列相关联则返回NULL。 如果列是标识列,则关联序列是在内部为该列创建的序列。 - 对于使用一种串行类型(serial, smallserial, bigserial)创建的列,它是为该串行列定义创建的序列。 + 对于使用一种 serial 类型(serial, smallserial, bigserial)创建的列,它是为该 serial 列定义创建的序列。 在后一种情况下,可以使用ALTER SEQUENCE OWNED BY修改或删除关联。 - (这个函数可能应该被称为pg_get_owned_sequence;它的当前名称反映了它在历史上曾与串行类型的列一起使用。) + (这个函数可能应该被称为pg_get_owned_sequence;它的当前名称反映了它在历史上曾与 serial 类型的列一起使用。) 第一个参数是具有可选模式的表名,第二个参数是列名。 由于第一个参数可能包含模式名和表名,因此按照通常的SQL规则解析它,这意味着默认情况下它是小写的。 第二个参数只是一个列名,按照字面来处理,因此保留了它的大小写。结果经过了适当的格式化,可以传递给序列函数(参见)。 - 典型的用法是读取序列的当前值以获取标识或串行列,示例如下: + 典型用法是读取标识列或 serial 列所用序列的当前值,例如: SELECT currval(pg_get_serial_sequence('sometable', 'id')); @@ -22354,7 +23071,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); text - 重构针对扩展统计对象的创建命令。(这是一个反编译的重构,而不是命令的原始文本。) + 重建扩展统计对象的创建命令。(这是反编译重建的结果,并非命令的原始文本。) @@ -22367,7 +23084,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); text - 重构针对触发器的创建命令。(这是一个反编译的重构,而不是命令的原始文本。) + 重建触发器的创建命令。(这是反编译重建的结果,并非命令的原始文本。) @@ -22393,7 +23110,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); text - 重构针对视图或物化视图的SELECT命令。(这是一个反编译的重构,而不是命令的原始文本。) + 重建定义视图或物化视图的SELECT命令。(这是反编译重建的结果,并非命令的原始文本。) @@ -22403,8 +23120,8 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); text - 重构针对视图或物化视图的底层SELECT命令。(这是一个反编译的重构,而不是命令的原始文本。) - 在这种形式的函数中,总是启用美观打印,并对长行进行换行,以尽量使它们小于指定的列数。 + 重建定义视图或物化视图的SELECT命令。(这是反编译重建的结果,并非命令的原始文本。) + 这种形式始终启用美化输出,并将长行折行,尽量使每行长度小于指定列数。 @@ -22414,7 +23131,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); text - 根据视图的文本名称而不是它的OID,重构针对视图或物化视图的底层SELECT命令。(这是弃用;请使用OID变体。) + 根据视图的文本名称而不是其 OID,重建定义视图或物化视图的SELECT命令。(此形式已弃用;请使用 OID 变体。) @@ -22427,7 +23144,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); boolean - 测试一个索引列是否具有命名属性。列出了常用索引列属性。 + 测试一个索引列是否具有指定名称的属性。列出了常用索引列属性。 (注意,扩展访问方法可以为其索引定义额外的属性名。) 如果属性名未知或不适用于特定对象,或者OID或列号不能识别有效的对象,则返回NULL @@ -22442,7 +23159,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); boolean - 测试一个索引是否具有命名属性。列出了常用的索引属性。 + 测试一个索引是否具有指定名称的属性。列出了常用的索引属性。 (注意,扩展访问方法可以为其索引定义额外的属性名。) 如果属性名未知或不适用于特定对象,或者OID不能识别有效的对象,则返回NULL @@ -22457,7 +23174,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); boolean - 测试索引访问方法是否具有命名属性。访问方法属性如所示。 + 测试索引访问方法是否具有指定名称的属性。访问方法属性如所示。 如果属性名未知或不适用于特定对象,或者OID不能识别有效的对象,则返回NULL @@ -22486,9 +23203,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); text[] - 返回与给定GUC相关联的标志数组,如果不存在则返回NULL。 - 如果GUC存在但没有要显示的标志,则结果为空数组。 - 仅公开列出在中最有用的标志。 + 返回与给定 GUC 关联的标志数组;如果该 GUC 不存在,则返回NULL。如果 GUC 存在但没有要显示的标志,则结果为空数组。此函数仅公开中列出的最有用的标志。 @@ -22501,9 +23216,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); setof oid - 返回具有存储在指定表空间中的对象的数据库的OIDs集。 - 如果这个函数返回了任何行,那么表空间就不是空的,且不能被删除。 - 要识别填充表空间的特定对象,需要连接到由pg_tablespace_databases标识的数据库,并查询它们的pg_class目录。 + 返回在指定表空间中存储了对象的数据库 OID 集合。如果此函数返回任何行,则说明该表空间不为空,不能删除。要查看存放在该表空间中的具体对象,需要连接到pg_tablespace_databases标识的数据库,并查询它们的pg_class系统目录。 @@ -22529,23 +23242,11 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); regtype - 返回传递值给它的数据类型的OID。这对于故障排除或动态构造SQL查询很有帮助。 - 函数声明为返回regtype,它是一个OID别名类型(see ); - 这意味着,为了比较,它与OID相同,但显示为类型名。 + 返回所传入值的数据类型的 OID。这有助于排查问题或动态构造 SQL 查询。函数声明的返回类型是regtype,它是一种 OID 别名类型(参见);这意味着它在比较时与 OID 相同,但显示为类型名。 - 例如: - -SELECT pg_typeof(33); - pg_typeof ------------ - integer - -SELECT typlen FROM pg_type WHERE oid = pg_typeof(33); - typlen --------- - 4 - + pg_typeof(33) + integer @@ -22558,22 +23259,17 @@ SELECT typlen FROM pg_type WHERE oid = pg_typeof(33); text - 返回传递值给它的排序规则的名称。如果需要,该值会被引号括起来,并使用模式限定。 - 如果没有为参数表达式派生排序规则,则返回NULL。如果参数不是可排序数据类型,则会引发错误。 + 返回传入值的排序规则名称。必要时会为返回的名称加上引号和模式限定。 + 如果无法为参数表达式推导出排序规则,则返回NULL。 + 如果参数不属于支持排序规则的数据类型,则报错。 - 例如: - -SELECT collation for (description) FROM pg_description LIMIT 1; - pg_collation_for ------------------- - "default" - -SELECT collation for ('foo' COLLATE "de_DE"); - pg_collation_for ------------------- - "de_DE" - + collation for ('foo'::text) + "default" + + + collation for ('foo' COLLATE "de_DE") + "de_DE" @@ -22587,7 +23283,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); 将文本关系名转换为它的OID。通过将字符串类型转换为regclass可以得到类似的结果(参见); - 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。 @@ -22600,8 +23296,8 @@ SELECT collation for ('foo' COLLATE "de_DE"); regcollation - 将文本排序规则名称转换为它的OID。通过将字符串类型转换为regcollation(参见)可以得到类似的结果; - 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 将文本排序规则名称转换为它的OID。通过将字符串类型转换为regcollation(参见)可以得到类似的结果; + 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。 @@ -22614,8 +23310,8 @@ SELECT collation for ('foo' COLLATE "de_DE"); regnamespace - 将文本模式名转换为它的OID。通过将字符串转换为regnamespace类型(参见)可以得到类似的结果; - 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 将文本模式名转换为它的OID。通过将字符串转换为regnamespace类型(参见)可以得到类似的结果; + 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。 @@ -22628,8 +23324,8 @@ SELECT collation for ('foo' COLLATE "de_DE"); regoper - 将文本操作符名称转换为它的OID。通过将字符串类型转换为regoper(参见)可以得到类似的结果; - 但是,如果找不到名称或名称有多义性,该函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 将文本操作符名称转换为它的OID。通过将字符串类型转换为regoper(参见)可以得到类似的结果; + 但是,如果找不到名称或名称有多义性,该函数将返回NULL而不会抛出错误。 @@ -22642,8 +23338,8 @@ SELECT collation for ('foo' COLLATE "de_DE"); regoperator - 将文本操作符名称(带有参数类型)转换为其OID。通过将字符串转换为regoperator类型(参见节)可以得到类似的结果; - 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 将文本操作符名称(带有参数类型)转换为其OID。通过将字符串转换为regoperator类型(参见节)可以得到类似的结果; + 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。 @@ -22656,8 +23352,8 @@ SELECT collation for ('foo' COLLATE "de_DE"); regproc - 将文本函数或过程名转换为其OID。通过将字符串转换为regproc类型(参见)可以得到类似的结果; - 但是,如果找不到名称或名称有多义性,该函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 将文本函数或过程名转换为其OID。通过将字符串转换为regproc类型(参见)可以得到类似的结果; + 但是,如果找不到名称或名称有多义性,该函数将返回NULL而不会抛出错误。 @@ -22671,7 +23367,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); 将文本函数或过程名(带有参数类型)转换为其OID。通过将字符串类型转换为regprocedure可以得到类似的结果(参见); - 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。 @@ -22685,12 +23381,12 @@ SELECT collation for ('foo' COLLATE "de_DE"); 将文本角色名转换为它的OID。通过将字符串类型转换为regrole可以得到类似的结果(参见); - 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。 - + to_regtype @@ -22698,8 +23394,26 @@ SELECT collation for ('foo' COLLATE "de_DE"); regtype - 将文本类型名转换为它的OID。通过将字符串类型转换为regtype可以得到类似的结果(参见); - 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 解析文本字符串,从中提取可能的类型名,并将该名称转换为类型 OID。字符串中的语法错误会导致报错;但如果字符串是语法有效的类型名,只是在系统目录中找不到该类型,结果就是 NULL。将字符串转换为 regtype 类型也能得到类似的结果(参见 ),区别在于类型转换会在找不到名称时报错。 + + + + + + to_regtypemod + + to_regtypemod ( text ) + integer + + + 解析文本字符串,从中提取可能的类型名称,并转换其类型修饰符(如果有)。字符串中的语法错误会引发错误;但如果字符串是语法有效的类型名称,只是在系统目录中找不到,则结果为NULL。如果没有类型修饰符,则结果为-1。 + + + to_regtypemod可以与结合,为生成适当的输入,从而将表示类型名称的字符串转换为规范形式。 + + + format_type(to_regtype('varchar(32)'), to_regtypemod('varchar(32)')) + character varying(32) @@ -22707,10 +23421,10 @@ SELECT collation for ('foo' COLLATE "de_DE"); - 大多数重构(反编译)数据库对象的函数都有一个可选的 pretty标志,如果为true,结果将被pretty-printed。 - 美观打印会抑制不必要的圆括号,并为易读性增加空格。 - 美观打印的格式可读性更好,但是默认格式更有可能被PostgreSQL的未来版本以同样的方式解释; - 因此,避免为转储目的使用美观打印的输出。为pretty参数传递false会产生与省略参数相同的结果。 + 大多数重建(反编译)数据库对象的函数都有一个可选的pretty标志;若为true,则对结果进行美化输出。 + 美化输出会省略不必要的圆括号,并增加空白以提高可读性。 + 美化后的格式更易读,但默认格式更有可能被PostgreSQL的未来版本以同样的方式解释,因此用于转储时应避免美化输出。 + 为pretty参数传入false与省略该参数的结果相同。 @@ -22755,19 +23469,20 @@ SELECT collation for ('foo' COLLATE "de_DE"); distance_orderable - 列能否通过一个distance操作符(例如ORDER BY col <-> constant)有序地扫描? + + 能否按距离操作符的结果有序地扫描该列,例如ORDER BY col <-> constant returnable - 列值是否可以通过一次只用索引扫描返回? + 列值是否可以通过一次仅索引扫描返回? search_array - 列是否天然支持col = ANY(array)搜索? + 列是否原生支持col = ANY(array)搜索? @@ -22782,7 +23497,7 @@ SELECT collation for ('foo' COLLATE "de_DE");
- 索引性质 + 索引属性 @@ -22819,7 +23534,7 @@ SELECT collation for ('foo' COLLATE "de_DE");
- 索引访问方法性质 + 索引访问方法属性 @@ -22872,15 +23587,20 @@ SELECT collation for ('foo' COLLATE "de_DE"); EXPLAIN - 带有此标志的参数包含在EXPLAIN (SETTINGS)命令中。 + 带有此标志的参数会在EXPLAIN (SETTINGS)命令的输出中显示。 NO_SHOW_ALL - 具有此标志的参数将被排除在SHOW ALL命令之外。 + 带有此标志的参数不会在SHOW ALL命令的输出中显示。 + NO_RESET + 带有此标志的参数不支持RESET命令。 + + + NO_RESET_ALL 具有此标志的参数将被排除在RESET ALL命令之外。 @@ -22904,16 +23624,15 @@ SELECT collation for ('foo' COLLATE "de_DE"); - 对象信息和定位函数 + 对象信息和寻址函数 - 列出了与数据库对象 - 标识和定位有关的函数。 + 列出了与数据库对象标识和寻址有关的函数。
- 对象信息和定位函数 + 对象信息和寻址函数 @@ -22929,6 +23648,19 @@ SELECT collation for ('foo' COLLATE "de_DE"); + + + + pg_get_acl + + pg_get_acl ( classid oid, objid oid, objsubid integer ) + aclitem[] + + + 返回由系统目录 OID、对象 OID 和子对象 ID 指定的数据库对象的ACL。对于未定义的对象,此函数返回NULL值。 + + + @@ -22938,9 +23670,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); text - 返回由目录OID、对象OID和子对象ID(例如表中的列号)标识的数据库对象的文本描述;当引用整个对象时,子对象ID为0)。 - 这个描述是人类可读的,并且可以根据服务器配置进行翻译。这对于决定pg_depend目录中引用的对象的标识特别有用。 - 此函数对于未定义的对象返回NULL值 + 返回数据库对象的文本描述,对象由系统目录 OID、对象 OID 和子对象 ID 指定(例如表中的列号;引用整个对象时,子对象 ID 为零)。该描述供人阅读,并可能根据服务器配置被翻译。这对于确定pg_depend系统目录中所引用对象的标识尤其有用。对于未定义的对象,此函数返回NULL @@ -22957,13 +23687,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); identitytext ) - 返回包含足够信息的行以唯一标识由目录OID、对象OID和子对象ID指定的数据库对象。 - 这些信息是为了机器可读的,永远不会被翻译。 - type标识数据库对象的类型; - schema是对象所属的模式名,NULL表示不属于模式的对象类型; - name是对象的名称,如果有必要,用引号括起来,如果名称(随着模式名称,如果相关)足以唯一地标识对象,否则为NULL; - identity是完整的对象标识,其精确格式依赖于对象类型,格式中的每个名称都是模式限定的,并在必要时用引号括起来。 - 未定义的对象由NULL值标识。 + 返回一行,其中包含足以唯一标识数据库对象的信息,该对象由系统目录 OID、对象 OID 和子对象 ID 指定。这些信息供机器读取,永远不会被翻译。type标识数据库对象的类型;schema是对象所属的模式名,对于不属于模式的对象类型则为NULL;如果对象名(以及适用时的模式名)足以唯一标识该对象,name就是对象名,并在必要时加引号,否则为NULLidentity是完整的对象标识,其具体格式取决于对象类型,格式中的每个名称都会根据需要加上模式限定和引号。未定义的对象以NULL值标识。 @@ -22979,10 +23703,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); object_argstext[] ) - 返回包含足够信息的行以唯一标识由目录OID、对象OID和子对象ID指定的数据库对象。 - 返回的信息独立于当前服务器,也就是说,它可以用于标识另一个服务器中具有相同名称的对象。 - type标识数据库对象的类型;object_namesobject_args是文本数组,它们一起构成对对象的引用。 - 这三个值可以传递给pg_get_object_address以获得对象的内部地址。 + 返回一行,其中包含足以唯一标识数据库对象的信息,该对象由系统目录 OID、对象 OID 和子对象 ID 指定。返回的信息与当前服务器无关,也就是说,它也能用于标识另一台服务器上名称相同的对象。type标识数据库对象的类型;object_namesobject_args是文本数组,共同构成对该对象的引用。将这三个值传给pg_get_object_address可以获得对象的内部地址。 @@ -22998,18 +23719,37 @@ SELECT collation for ('foo' COLLATE "de_DE"); objsubidinteger ) - 返回包含足够信息的行以唯一标识由类型代码、对象名称和参数数组指定的数据库对象。 - 返回的值将在系统目录中使用,例如pg_depend; - 它们可以传递给其他系统函数,比如 pg_describe_objectpg_identify_object。 - classid是包含该对象的系统目录的OID;objid是对象本身的OID, objsubid是子对象的ID,如果没有则为零。 - 这个函数是pg_identify_object_as_address的反向函数。 - 未定义的对象以NULL值标识。 + 返回一行,其中包含足以唯一标识数据库对象的信息,该对象由类型代码、对象名称数组和参数数组指定。返回的值就是pg_depend等系统目录中使用的值;它们可以传给pg_describe_objectpg_identify_object等其他系统函数。classid是包含该对象的系统目录的 OID;objid是对象自身的 OID;objsubid是子对象 ID,没有子对象时为零。此函数执行pg_identify_object_as_address的逆操作。未定义的对象以NULL值标识。
+ + pg_get_acl可用于检索和检查与数据库对象关联的权限,而无需查看特定目录。 + 例如,若要检索当前数据库中对象上已授予的全部权限: + +postgres=# SELECT + (pg_identify_object(s.classid,s.objid,s.objsubid)).*, + pg_catalog.pg_get_acl(s.classid,s.objid,s.objsubid) AS acl +FROM pg_catalog.pg_shdepend AS s +JOIN pg_catalog.pg_database AS d + ON d.datname = current_database() AND + d.oid = s.dbid +JOIN pg_catalog.pg_authid AS a + ON a.oid = s.refobjid AND + s.refclassid = 'pg_authid'::regclass +WHERE s.deptype = 'a'; +-[ RECORD 1 ]----------------------------------------- +type | table +schema | public +name | testtab +identity | public.testtab +acl | {postgres=arwdDxtm/postgres,foo=r/postgres} + + + @@ -23022,7 +23762,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); - 中展示的函数抽取注释,注释是由命令在以前存储的。如果对指定参数找不到注释,则返回空值。 + 中的函数用于提取此前通过命令存储的注释。如果找不到与指定参数对应的注释,则返回空值。 @@ -23052,7 +23792,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); text - 返回表列的注释,该注释由该表的OID和列号指定。(obj_description不能用于表的列,因为列没有自己的oid。) + 返回表列的注释,列由所属表的 OID 和列号指定。(obj_description不能用于表列,因为列没有自身的 OID。) @@ -23065,8 +23805,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); text - 返回OID指定的数据库对象的注释和包含该对象的系统目录的名称。 - 例如,obj_description(123456, 'pg_class')将检索OID为123456的表的注释。 + 返回数据库对象的注释,对象由其 OID 和所在系统目录的名称指定。例如,obj_description(123456, 'pg_class')会获取 OID 为 123456 的表的注释。 @@ -23076,8 +23815,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); text - 返回仅由其OID指定的数据库对象的注释。 - 这个已被弃用(deprecated)因为无法保证oid在不同的系统目录中是唯一的;因此,可能会返回错误的注释。 + 返回仅由其 OID 指定的数据库对象的注释。此形式已弃用,因为无法保证 OID 在不同系统目录之间唯一,因而可能返回错误的注释。 @@ -23090,9 +23828,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); text - 返回共享数据库对象的注释,该对象由其OID和包含的系统编目的名称指定。 - 这与obj_description类似,只是它用于检索共享对象(也就是数据库、角色和表空间)上的注释。 - 有些系统编目对每个集簇中的所有数据库都是全局的,其中对象的描述也全局存储。 + 返回共享数据库对象的注释,对象由其 OID 和所在系统目录的名称指定。此函数与obj_description类似,但用于获取共享对象(即数据库、角色和表空间)的注释。有些系统目录由数据库集簇中的所有数据库全局共享,其中对象的描述也全局存储。 @@ -23228,6 +23964,32 @@ SELECT collation for ('foo' COLLATE "de_DE"); + + + + age + + age ( xid ) + integer + + + 返回给定事务 ID 与当前事务计数器之间的事务数。 + + + + + + + mxid_age + + mxid_age ( xid ) + integer + + + 返回给定多事务 ID 与当前多事务计数器之间的多事务 ID 数。 + + + @@ -23237,7 +23999,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); xid8 - 返回当前事务的ID。如果当前事务还没有一个ID(因为它还没有执行任何数据库更新),它将分配一个新的事务。 + 返回当前事务的ID。如果当前事务还没有一个ID(因为它还没有执行任何数据库更新),它将分配一个新的事务 ID;详见。如果在子事务中执行,它将返回顶层事务的ID;详见 @@ -23250,8 +24012,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); xid8 - 返回当前事务的ID,如果还没有分配ID则返回NULL。 - (如果事务可能是只读的,最好使用这种变体,以避免不必要地消耗XID。) + 返回当前事务的 ID;如果尚未分配 ID,则返回NULL。(如果事务本来可能是只读的,最好使用此变体,以免不必要地消耗 XID。)如果在子事务中执行,则返回顶层事务 ID。 @@ -23264,10 +24025,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); text - 报告最近的事务的提交状态。如果事务为最近的,系统会保留事务的提交状态,则结果是 in progresscommittedaborted。 - 如果该事务的时间足够久,并且系统中没有对该事务的引用,而且提交状态信息已经被丢弃,则结果为NULL。 - 应用可以使用此函数,例如,确定在进行COMMIT时,应用程序和数据库服务器断开连接后,它们的事务是已提交还是中止。 - 注意,准备好的事务报告为in progress的事务;如果应用需要确定一个事务ID是否属于一个准备好的事务,则必须检查pg_prepared_xacts。 + 报告近期事务的提交状态。只要事务足够新,系统仍保留其提交状态,结果就为in progresscommittedaborted。如果事务已足够旧,系统中不再有对它的引用,且提交状态信息已被丢弃,则返回NULL。例如,在COMMIT进行过程中应用与数据库服务器断开连接时,应用可以用此函数判断事务是提交了还是中止了。注意,预备事务被报告为in progress;如果需要确定某个事务 ID 是否为预备事务,应用必须检查pg_prepared_xacts @@ -23280,7 +24038,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); pg_snapshot - 返回当前snapshot,显示哪些事务 ID正在进行中的数据结构。 + 返回当前快照,即显示哪些事务 ID 正在进行中的数据结构。快照中只包含顶层事务 ID,不显示子事务 ID;详见 @@ -23332,8 +24090,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); boolean - 根据此快照,给定的事务ID是否可见(visible)(也就是说,它是否在快照拍摄之前完成)? - 注意,这个函数不会给出子事务ID的正确答案。 + 根据此快照,给定的事务 ID 是否可见(即该事务是否在生成快照之前完成)?注意,此函数无法为子事务 ID(subxid)给出正确结果;详见 @@ -23357,7 +24114,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); 内部事务 ID 类型xid是 32 位宽,每 40 亿个事务就会回卷一次(wrap around)。 - 但是,中所示的函数使用的是 64 位类型xid8,它在一次安装的生命周期内不会回卷,必要时可以通过强制转换将其转换为xid。 + 但是,中所示的函数(agemxid_agepg_get_multixact_members除外)使用的是 64 位类型xid8,它在一次安装的生命周期内不会回卷,必要时可以通过类型转换将其转换为xid;详见。 数据类型pg_snapshot存储特定时刻事务ID可见性的信息。 其组成如所描述。pg_snapshot的文本表示形式是xmin:xmax:xip_list。 例如10:20:10,14,15表示xmin=10, xmax=20, xip_list=10, 14, 15。 @@ -23380,21 +24137,22 @@ SELECT collation for ('foo' COLLATE "de_DE"); xmin - 仍然处于活动状态的最低事务ID。所有小于xmin的事务 ID要么提交且可见,要么回滚并死亡。 + 仍然处于活动状态的最小事务 ID。所有小于xmin的事务 ID 要么已经提交且可见,要么已经回滚而失效。 xmax - 比最高完成的事务ID还高出一个值。所有大于或等于xmax的事务 ID到快照时还没有完成,因此不可见。 + 已完成事务中的最大事务 ID 加一。所有大于或等于xmax的事务 ID 在生成快照时尚未完成,因此不可见。 xip_list - 快照时正在进行的事务。一个事务ID为xmin <= X < xmax且不在快照时已经完成的列表中,因此根据其提交状态,该事务ID要么是可见的,要么是死的。此列表不包括子事务的事务 ID。 + 生成快照时正在进行的事务。满足xmin <= X < + xmax且不在此列表中的事务 ID 在生成快照时已经完成,因此根据其提交状态,要么可见,要么失效。此列表不包含子事务的事务 ID(subxid)。 @@ -23539,8 +24297,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); 已提交事务信息函数 - 中的函数提供了关于过去的事务何时被提交的信息。 - 它们只在启用配置选项时提供有用的数据,并且只针对在启用该选项后提交的事务。 + 中的函数提供过去事务的提交时间信息。只有启用配置选项后,这些函数才会提供有用的数据,并且只针对启用该选项之后提交的事务。提交时间戳信息会在 vacuum 过程中定期清理。
@@ -23585,7 +24342,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); roidentoid) - 返回事务的提交时间戳和复制起源。 + 返回事务的提交时间戳和复制源。 @@ -23601,7 +24358,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); roidentoid ) - 返回最近提交的事务的事务ID、提交时间戳和复制源头。 + 返回最近提交事务的事务 ID、提交时间戳和复制源。 @@ -23615,9 +24372,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); 控制数据函数 - 中所展示的函数能打印initdb期间初始化的信息,例如目录版本。 - 它们也能显示有关预写式日志和检查点处理的信息。这些信息是集簇范围内的,不与任何特定的一个数据库相关。 - 这些函数提供大致相同的信息,对于同一种来源,就像应用。 + 中的函数显示在initdb期间初始化的信息,例如系统目录版本。它们也显示有关预写式日志和检查点处理的信息。这些信息适用于整个数据库集簇,而非某个特定数据库。这些函数与应用程序从相同来源提供大部分相同的信息。
@@ -23647,7 +24402,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); record - 返回有关当前检查点状态的信息, 如 所展示。 + 返回有关当前检查点状态的信息, 如 所展示。 @@ -23686,7 +24441,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); record - 返回有关恢复状态的信息,如 所展示。 + 返回有关恢复状态的信息,如 所展示。 @@ -23908,6 +24663,10 @@ SELECT collation for ('foo' COLLATE "de_DE"); integer + + default_char_signedness + boolean +
@@ -23980,6 +24739,8 @@ SELECT collation for ('foo' COLLATE "de_DE"); + + @@ -24095,7 +24856,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); WAL 记录修改过。每一行中,如果is_limit_block 为 true,则表示以下两种情况之一:(a) 该关系分支在相关 WAL 记录范围内 被截断到relblocknumber给出的长度;或者 (b) 该关系分支在 - 相关 WAL 记录范围内被创建或删除;在这些情况下, + 相关 WAL 记录范围内被创建或删除;在创建或删除的情况下, relblocknumber将为零。 @@ -24167,9 +24928,9 @@ SELECT collation for ('foo' COLLATE "de_DE"); - configuration - of the server - functions + 配置 + 服务器 + 函数 @@ -24206,7 +24967,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); text - 返回设置的setting_name的当前值。 + 返回设置setting_name的当前值。 如果没有这样的设置,current_setting将抛出一个错误,除非missing_ok被提供并且为true(在此情况下返回NULL)。 这个函数对应于SQL命令 @@ -24228,9 +24989,10 @@ SELECT collation for ('foo' COLLATE "de_DE"); text - 将参数setting_name设置为new_value,并返回该值。 - 如果is_localtrue,新值将仅在当前事务期间应用。 - 如果您希望新值应用于当前会话的其余部分,请使用false代替。这个函数对应于SQL命令。 + 将参数setting_name设置为new_value,并返回该值。如果is_localtrue,新值仅在当前事务期间生效。如果希望新值在当前会话的剩余时间内生效,则使用false。此函数对应 SQL 命令。 + + + set_config接受将 NULL 作为new_value的值,但由于配置值不能为 null,这会被解释为将该设置重置为默认值的请求。 set_config('log_statement_stats', 'off', false) @@ -24253,7 +25015,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); - 在中展示的函数向其它服务器进程发送控制信号。默认情况下这些函数只能被超级用户使用,但是如果需要,可以利用GRANT把访问权限授予给其他用户。 + 在中展示的函数向其它服务器进程发送控制信号。默认情况下这些函数只能被超级用户使用,但是如果需要,可以利用GRANT把访问权限授予给其他用户(注明的例外除外)。 @@ -24289,6 +25051,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); 取消具有指定进程ID的后端进程的会话的当前查询。如果调用角色是被取消的后端进程所属角色的成员, 或者调用角色具有pg_signal_backend的权限,则也允许执行此操作,但只有超级用户可以取消超级用户后端进程。 + 例外情况是,具有pg_signal_autovacuum_worker角色权限的角色可以取消 autovacuum 工作进程,而这些进程原本被视为超级用户后端。 @@ -24301,11 +25064,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); boolean - 请求记录具有指定进程ID的后端的内存上下文。此函数可以将请求发送到后端和辅助进程,但不包括记录器。这些内存上下文将以 - LOG消息级别记录。它们将根据设置的日志配置出现在服务器日志中 - (有关更多信息,请参见), - 但无论如何都不会发送给客户端 - ()。 + 请求记录具有指定进程 ID 的后端进程的内存上下文。此函数可以向除日志记录进程以外的后端进程和辅助进程发送请求。这些内存上下文将以LOG消息级别记录,并根据日志配置出现在服务器日志中(详见);无论如何设置,都不会发送给客户端。 @@ -24352,9 +25111,10 @@ SELECT collation for ('foo' COLLATE "de_DE"); 终止具有指定进程ID的后端进程的会话。如果调用角色是正在终止的后端的角色的成员,或者调用角色具有pg_signal_backend的权限,则也允许执行此操作,但只有超级用户才能终止超级用户后端。 + 例外情况是,具有pg_signal_autovacuum_worker角色权限的角色可以终止 autovacuum 工作进程,而这些进程原本被视为超级用户后端。 - 如果未指定或超时timeout为零,则此函数无论进程是否实际终止,都将返回true,仅表示信号发送成功。如果指定了timeout(以毫秒为单位)且大于零,则函数将等待直到进程实际终止或直到给定时间已过。如果进程被终止,函数将返回true。在超时时,会发出警告并返回false。 + 如果未指定timeout或其值为零,则此函数无论进程是否实际终止,都将返回true,仅表示信号发送成功。如果指定了timeout(以毫秒为单位)且大于零,则函数将等待直到进程实际终止或直到给定时间已过。如果进程被终止,函数将返回true。在超时时,会发出警告并返回false @@ -24380,16 +25140,16 @@ postgres=# SELECT pg_log_backend_memory_contexts(pg_backend_pid()); LOG: logging memory contexts of PID 10377 STATEMENT: SELECT pg_log_backend_memory_contexts(pg_backend_pid()); -LOG: level: 0; TopMemoryContext: 80800 total in 6 blocks; 14432 free (5 chunks); 66368 used -LOG: level: 1; pgstat TabStatusArray lookup hash table: 8192 total in 1 blocks; 1408 free (0 chunks); 6784 used -LOG: level: 1; TopTransactionContext: 8192 total in 1 blocks; 7720 free (1 chunks); 472 used -LOG: level: 1; RowDescriptionContext: 8192 total in 1 blocks; 6880 free (0 chunks); 1312 used -LOG: level: 1; MessageContext: 16384 total in 2 blocks; 5152 free (0 chunks); 11232 used -LOG: level: 1; Operator class cache: 8192 total in 1 blocks; 512 free (0 chunks); 7680 used -LOG: level: 1; smgr relation table: 16384 total in 2 blocks; 4544 free (3 chunks); 11840 used -LOG: level: 1; TransactionAbortContext: 32768 total in 1 blocks; 32504 free (0 chunks); 264 used +LOG: level: 1; TopMemoryContext: 80800 total in 6 blocks; 14432 free (5 chunks); 66368 used +LOG: level: 2; pgstat TabStatusArray lookup hash table: 8192 total in 1 blocks; 1408 free (0 chunks); 6784 used +LOG: level: 2; TopTransactionContext: 8192 total in 1 blocks; 7720 free (1 chunks); 472 used +LOG: level: 2; RowDescriptionContext: 8192 total in 1 blocks; 6880 free (0 chunks); 1312 used +LOG: level: 2; MessageContext: 16384 total in 2 blocks; 5152 free (0 chunks); 11232 used +LOG: level: 2; Operator class cache: 8192 total in 1 blocks; 512 free (0 chunks); 7680 used +LOG: level: 2; smgr relation table: 16384 total in 2 blocks; 4544 free (3 chunks); 11840 used +LOG: level: 2; TransactionAbortContext: 32768 total in 1 blocks; 32504 free (0 chunks); 264 used ... -LOG: level: 1; ErrorContext: 8192 total in 1 blocks; 7928 free (3 chunks); 264 used +LOG: level: 2; ErrorContext: 8192 total in 1 blocks; 7928 free (3 chunks); 264 used LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 used 如果在同一父级下有超过100个子上下文,则将记录前100个子上下文,并附上其余上下文的摘要。 @@ -24403,7 +25163,7 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 备份控制函数 - backup + 备份 @@ -24443,13 +25203,9 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 pg_lsn - 在预写式日志中创建一个命名标记记录,稍后可以将其用作恢复目标,并返回相应的预写日志位置。 - 然后可以将给定的名称与 一起使用,以指定进行恢复的点。 - 要避免创建多个名称相同的恢复点,因为恢复将在第一个名称与恢复目标匹配的恢复点停止。 + 在预写式日志中创建一条命名标记记录,供以后用作恢复目标,并返回相应的预写式日志位置。随后可以在中使用给定名称,指定恢复到哪一点。应避免创建多个同名恢复点,因为恢复会在第一个名称匹配恢复目标的恢复点停止。 - - 默认情况下,该函数仅限超级用户使用,但可以授权给其他用户执行该函数。 - + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -24461,7 +25217,7 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 pg_lsn - 返回当前预写式日志刷新位置(参见下面的说明)。 + 返回当前预写式日志刷盘位置(参见下文说明)。 @@ -24474,7 +25230,7 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 pg_lsn - 返回当前预式日志插入位置(参见下面的说明)。 + 返回当前预写式日志插入位置(参见下文说明)。 @@ -24487,7 +25243,7 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 pg_lsn - 返回当前预写式日志写位置(参见下面的说明)。 + 返回当前预写式日志写入位置(参见下文说明)。 @@ -24503,15 +25259,9 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 pg_lsn - 准备服务器开始在线备份。唯一必需的参数是备份的任意用户定义标签。 - (通常这将是备份转储文件存储的名称。) - 如果将可选的第二个参数指定为true, - 它将尽快执行pg_backup_start。这将强制立即进行检查点, - 这将导致I/O操作的激增,从而减慢任何同时执行的查询。 + 准备服务器开始在线备份。唯一必需的参数是用户任意指定的备份标签。(通常是备份转储文件将要保存的名称。)如果可选的第二个参数为true,则尽快执行pg_backup_start。这会强制立即执行检查点,使 I/O 操作量陡增,并降低并发执行的查询的速度。 - - 默认情况下,此函数仅限于超级用户,但可以授予其他用户执行权限以运行该函数。 - + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -24528,31 +25278,18 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 spcmapfile text ) - 完成在线备份。函数的结果中返回备份标签文件和表空间映射文件的期望内容,并必须写入备份区域的文件中。 - 这些文件不得写入实时数据目录(这样做将导致PostgreSQL在崩溃时无法重新启动)。 + 结束在线备份。备份标签文件和表空间映射文件所需的内容作为函数结果的一部分返回,必须将其写入备份区域中的文件。切勿将这些文件写入正在使用的数据目录(否则发生崩溃后 PostgreSQL 将无法重新启动)。 - 有一个类型为boolean的可选参数。 - 如果为false,则在备份完成后立即返回,而无需等待WAL进行归档。 - 此行为仅适用于独立监视WAL归档的备份软件。否则,可能会缺少使备份一致所需的WAL,使备份无效。 - 默认情况下或当此参数为true时,pg_backup_stop将在启用归档时等待WAL进行归档。 - (在备库上,这意味着仅当archive_mode = always时才会等待。 - 如果主库上的写入活动较低,则可能有必要在主库上运行pg_switch_wal以触发立即段切换。) + 有一个boolean类型的可选参数。如果为 false,该函数会在备份完成后立即返回,不等待 WAL 归档。这种行为只适用于自行监控 WAL 归档的备份软件;否则,可能缺少使备份保持一致所需的 WAL,导致备份无法使用。默认情况下或该参数为 true 时,若已启用归档,pg_backup_stop会等待 WAL 归档。(在备库上,这意味着只有archive_mode = always时才会等待。如果主库的写入活动很少,可以在主库上运行pg_switch_wal,触发立即切换日志段。) - 在主库上执行时,此函数还会在预写式日志归档区域中创建一个备份历史文件。 - 历史文件包括给定给pg_backup_start的标签、备份的起始和结束预写式日志位置,以及备份的起始和结束时间。 - 在记录结束位置后,当前的预写式日志插入点会自动前进到下一个预写式日志文件,以便立即归档结束的预写式日志文件以完成备份。 + 在主库上执行时,该函数还会在预写式日志归档区域创建备份历史文件。历史文件包括传给pg_backup_start的标签、备份的起止预写式日志位置以及备份的起止时间。记录结束位置后,当前预写式日志插入点会自动推进到下一个预写式日志文件,使包含结束位置的预写式日志文件可以立即归档,从而完成备份。 - 函数的结果是一个记录。 - lsn列保存备份的结束预写式日志位置(可以忽略)。 - 第二列返回备份标签文件的内容,第三列返回表空间映射文件的内容。 - 这些必须作为备份的一部分存储,并作为恢复过程的一部分。 + 该函数的结果是一条记录。lsn列保存备份结束时的预写式日志位置(同样可以忽略)。第二列返回备份标签文件的内容,第三列返回表空间映射文件的内容。这些内容必须作为备份的一部分保存,恢复时需要用到它们。 - - 默认情况下,此函数仅限于超级用户,但可以授予其他用户EXECUTE权限来运行该函数。 - + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -24564,13 +25301,9 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 pg_lsn - 强制服务器切换到一个新的预写式日志文件,这允许对当前文件进行归档(假设你正在使用连续归档)。 - 其结果是在刚刚完成的预写式日志文件中结束预写式日志位置加1。 - 如果自从上次预写式日志切换以来没有提前写日志活动,pg_switch_wal将不做任何操作,并返回当前正在使用的提前写日志文件的起始位置。 + 强制服务器切换到新的预写式日志文件,使当前文件可以归档(假设正在使用连续归档)。返回值是刚完成的预写式日志文件中的结束预写式日志位置加 1。如果自上次切换预写式日志以来没有发生任何预写式日志活动,pg_switch_wal不执行任何操作,并返回当前使用的预写式日志文件的起始位置。 - - 默认情况下该函数仅限超级用户使用,但可以授权其他用户执行该函数。 - + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -24582,7 +25315,7 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 text - 将预写式日志位置转换为保持该位置的WAL文件的名称。 + 将预写式日志位置转换为包含该位置的 WAL 文件的名称。 @@ -24601,6 +25334,21 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 + + + + pg_split_walfile_name + + pg_split_walfile_name ( file_name text ) + record + ( segment_number numeric, + timeline_id bigint ) + + + 从 WAL 文件名中提取序列号和时间线 ID。 + + + @@ -24610,34 +25358,38 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 numeric - 计算两个预写式日志位置之间的字节(lsn1 - lsn2)差异。 - 这可以与pg_stat_replication中所示的一些函数一起使用,以获得复制延迟。 + 计算两个预写式日志位置之间的字节差(lsn1 - lsn2)。可以将它与pg_stat_replication中的某些函数配合使用,以获取复制延迟。 - - pg_current_wal_lsn 显示当前预写式日志写位置,与上述函数所用的格式相同。 - 类似地,pg_current_wal_insert_lsn显示当前预写式日志插入位置,pg_current_wal_flush_lsn显示当前预写式日志刷新位置。 - 插入位置是预写式日志在任何时刻的逻辑(logical) 结束,而写位置是已经从服务器内部缓冲区实际写入的内容的结束,而刷新位置是已知的要写入持久化存储的最后一个位置。 - 写位置是可以从服务器外部检查的最后位置,如果你对归档部分完成的预写式日志文件感兴趣,那么它通常就是你想要的位置。 - 插入和刷新位置主要用于服务器调试目的。这些都是只读操作,不需要超级用户权限。 - + pg_current_wal_lsn 显示当前预写式日志写入位置,格式与上述函数相同。类似地,pg_current_wal_insert_lsn 显示当前预写式日志插入位置,pg_current_wal_flush_lsn 显示当前预写式日志刷盘位置。插入位置是预写式日志在任意时刻的逻辑末尾;写入位置是实际从服务器内部缓冲区写出的内容的末尾;刷盘位置则是已知已经写入持久存储的最后位置。写入位置是能从服务器外部检查到的内容的末尾,如果要归档尚未写满的预写式日志文件,通常需要这个位置。插入位置和刷盘位置主要用于服务器调试。这些都是只读操作,不需要超级用户权限。 - - 您可以使用pg_walfile_name_offsetpg_lsn值中提取相应的预写式日志文件名和字节偏移量。例如: - + 可以使用pg_walfile_name_offset从一个pg_lsn值中提取相应的预写式日志文件名和字节偏移量。例如: postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); file_name | file_offset --------------------------+------------- 00000001000000000000000D | 4039624 (1 row) +类似地,pg_walfile_name仅提取预写式日志文件名。 + + + pg_split_walfile_name可用于根据文件偏移量和 WAL 文件名计算 + LSN,例如: + +postgres=# \set file_name '000000010000000100C000AB' +postgres=# \set offset 256 +postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset AS lsn + FROM pg_split_walfile_name(:'file_name') pd, + pg_show_all_settings() ps + WHERE ps.name = 'wal_segment_size'; + lsn +--------------- + C001/AB000100 +(1 row) - 类似地,pg_walfile_name仅提取预写式日志文件名。 - 当给定的预写式日志位置恰好位于预写式日志文件边界时,这两个函数都会返回前一个预写式日志文件的名称。 - 这通常是管理预写式日志归档行为的期望行为,因为前一个文件是当前需要归档的最后一个文件。
@@ -24691,9 +25443,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); pg_lsn - 返回已接收并通过流复制同步到磁盘的最后一个预写式日志位置。 - 当流复制正在进行时这将单调地增加。如果恢复已经完成,那么在恢复期间,接收到的最后一条WAL记录的位置将保持静态,并同步到磁盘。 - 如果流复制已禁用,或者尚未启动,函数将返回NULL。 + 返回流复制最近接收并同步到磁盘的预写式日志位置。在流复制进行期间,该值单调增加。如果恢复已完成,该值将保持为恢复期间最后接收并同步到磁盘的 WAL 记录的位置。如果禁用了流复制,或者流复制尚未开始,此函数返回 NULL @@ -24706,8 +25456,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); pg_lsn - 返回恢复期间重新播放的最后一个预写式日志位置。如果恢复仍在进行中这将会单调地增加。 - 如果恢复已经完成,那么恢复期间应用的最后WAL记录的位置将保持静态。当服务器正常启动且没有恢复时,函数返回NULL。 + 返回恢复期间最近重放的预写式日志位置。如果恢复仍在进行,该值单调增加。如果恢复已完成,该值将保持为该次恢复期间最后应用的 WAL 记录的位置。如果服务器未经恢复而正常启动,此函数返回 NULL @@ -24720,10 +25469,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); timestamp with time zone - 返回恢复期间重放的最后一个事务的时间戳。这是在主库上为该事务生成提交或中止 WAL记录的时间。 - 如果在恢复期间没有重放任何事务,该函数将返回NULL。否则,如果恢复仍在进行中,这将单调地增加。 - 如果恢复已经完成,那么在恢复期间应用最后一个事务时,这将会保持静态。 - 当服务器正常启动且没有恢复时,函数返回NULL。 + 返回恢复期间最近重放事务的时间戳,即该事务的提交或中止 WAL 记录在主库上生成的时间。如果恢复期间尚未重放任何事务,此函数返回 NULL。否则,如果恢复仍在进行,该值单调增加。如果恢复已完成,该值将保持为该次恢复期间最后应用的事务的时间戳。如果服务器未经恢复而正常启动,此函数返回 NULL @@ -24747,7 +25493,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); - 控制恢复进度的功能如 所示。这些函数只能在恢复过程中执行。 + 列出的函数用于控制恢复进度。这些函数只能在恢复期间执行。 @@ -24777,7 +25523,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); boolean - 如果请求了恢复暂停了则返回真。 + 如果已请求暂停恢复,则返回真。 @@ -24791,7 +25537,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); 返回恢复暂停状态。 - 如果没有请求pause,返回值是not paused,如果请求暂停但恢复还没有暂停,返回值是pause requested,如果恢复实际已经暂停,返回值是paused。 + 如果没有请求暂停,返回值是not paused,如果请求暂停但恢复还没有暂停,返回值是pause requested,如果恢复实际已经暂停,返回值是paused @@ -24805,11 +25551,11 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); 将备库提升为主库状态。 - 当wait设置为true(默认值)时,函数将等待直到升级完成或wait_seconds秒数已过,如果升级成功则返回true,否则返回false。 - 如果wait设置为false,则该函数在向postmaster发送SIGUSR1信号以触发升级后立即返回true。 + 当wait设置为true(默认值)时,函数将等待直到提升完成或wait_seconds秒数已过,如果提升成功则返回true,否则返回false。 + 如果wait设置为false,则该函数在向postmaster发送SIGUSR1信号以触发提升后立即返回true - 默认情况下这个函数仅限超级用户使用,但可以授权给其他用户执行该函数。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -24830,7 +25576,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); 如果热备是激活的,所有新查询将看到相同的一致的数据库快照,并且在恢复继续之前不会生成进一步的查询冲突。 - 默认情况下该函数仅限超级用户使用,但可以授权其他用户执行该函数。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -24846,7 +25592,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); 如果暂停了,则重新启动恢复。 - 默认情况下该函数仅限超级用户使用,但可以授权其他用户执行该函数。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -24854,8 +25600,8 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn);
- pg_wal_replay_pausepg_wal_replay_resume不能在提升(promotion)进行时执行。 - 如果在恢复暂停时触发了提升(promotion),则暂停状态结束,升级继续进行。 + pg_wal_replay_pausepg_wal_replay_resume不能在提升进行时执行。 + 如果在恢复暂停时触发了提升,则暂停状态结束,提升继续进行。 @@ -24874,7 +25620,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); - 为了解决这个问题,PostgreSQL允许一个事务导出它正在使用的快照。只要导出的事务仍然保持打开,其他事务可以导入它的快照,并且因此可以保证它们可以看到和第一个事务看到的完全一样的数据库视图。但是注意这些事务中的任何一个对数据库所作的更改对其他事务仍然保持不可见,和未提交事务所作的修改一样。因此这些事务是针对以前存在的数据同步,而对由它们自己所作的更改则采取正常的动作。 + 为了解决这个问题,PostgreSQL允许一个事务导出它正在使用的快照。只要导出快照的事务仍然保持打开,其他事务可以导入它的快照,并且因此可以保证它们可以看到和第一个事务看到的完全一样的数据库视图。但是注意这些事务中的任何一个对数据库所作的更改对其他事务仍然保持不可见,和未提交事务所作的修改一样。因此这些事务是针对以前存在的数据同步,而对由它们自己所作的更改则采取正常的动作。 @@ -24914,7 +25660,19 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); 如果需要的话,一个事务可以导出多个快照。 请注意,这样做仅在READ COMMITTED事务中有用,因为在REPEATABLE READ和更高的隔离级别中,事务在它们的生命周期中使用相同的快照。 - 一旦事务导出了快照,它就不能用 进行准备。 + 一旦事务导出了快照,它就不能用 进行预备。 + + + + + + pg_log_standby_snapshot + + pg_log_standby_snapshot () + pg_lsn + + + 为进行中的事务拍摄快照并将其写入 WAL,无须等待后台写入器或检查点进程记录快照。这对备用服务器上的逻辑解码很有用,因为创建逻辑复制槽必须等待此类记录在备用服务器上重放。 @@ -24930,7 +25688,6 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); 中展示的函数用于控制以及与复制特性交互。 有关底层特性的信息请见以及。 - 复制原点函数的使用仅限于超级用户。 默认只允许超级用户使用复制源的函数,但可以通过GRANT命令允许其他用户使用。 复制槽的函数只限于超级用户和拥有REPLICATION权限的用户。 @@ -24976,12 +25733,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); lsn pg_lsn ) - 创建一个新的名为slot_name的物理复制槽。 - 第二个参数是可选的,当它为true时,立即为这个物理槽指定要被保留的LSN。 - 否则该LSN会被保留在来自一个流复制客户端的第一个连接上。 - 来自一个物理槽的更改只能通过流复制协议进行流式传输 — 见。 - 当可选的第三参数temporary被设置为真时,指定那个槽不会被持久地存储在磁盘上并且仅对当前会话的使用有意义。 - 临时槽也会在发生任何错误时被释放。这个函数对应于复制协议命令CREATE_REPLICATION_SLOT ... PHYSICAL。 + 创建名为 slot_name 的新物理复制槽。可选的第二个参数为 true 时,指定立即为此复制槽保留 LSN;否则在流复制客户端首次连接时保留 LSN。从物理槽流式传输更改只能使用流复制协议 — 参见。可选的第三个参数 temporary 为真时,指定该槽不永久存储到磁盘,且仅供当前会话使用。发生任何错误时,临时槽也会被释放。此函数对应复制协议命令 CREATE_REPLICATION_SLOT ... PHYSICAL @@ -24994,9 +25746,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); void - 丢弃名为slot_name的物理或逻辑复制槽。 - 和复制协议命令DROP_REPLICATION_SLOT相同。对于逻辑槽, - 在连接到在其中创建该槽的同一个数据库时,必须调用这个函数。 + 删除名为slot_name的物理或逻辑复制槽。与复制协议命令DROP_REPLICATION_SLOT相同。 @@ -25011,7 +25761,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); lsn pg_lsn ) - 创建一个名为slot_name的新逻辑(解码)复制插槽,使用输出插件plugin。可选的第三个参数temporary,当设置为true时,指定插槽不应永久存储到磁盘,仅供当前会话使用。临时插槽也会在任何错误发生时释放。可选的第四个参数twophase,当设置为true时,指定为此插槽启用已准备事务的解码。可选的第五个参数failover,当设置为true时,指定启用此插槽同步到备库,以便在故障切换后可以恢复逻辑复制。调用此函数的效果与复制协议命令CREATE_REPLICATION_SLOT ... LOGICAL相同。 + 创建一个名为slot_name的新逻辑(解码)复制槽,使用输出插件plugin。可选的第三个参数temporary,当设置为真时,指定槽不应永久存储到磁盘,仅供当前会话使用。临时槽也会在任何错误发生时释放。可选的第四个参数twophase,当设置为真时,指定为此槽启用预备事务的解码。可选的第五个参数failover,当设置为真时,指定启用此槽同步到备库,以便在故障切换后可以恢复逻辑复制。调用此函数的效果与复制协议命令CREATE_REPLICATION_SLOT ... LOGICAL相同。 @@ -25027,8 +25777,9 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); 将一个名为src_slot_name的现有物理复制槽复制到一个名为dst_slot_name的物理复制槽。 - 被复制的物理槽开始从与源槽相同的LSN开始保留WAL。temporary是可选的。 + 复制后的物理槽从与源槽相同的LSN开始保留WAL。temporary是可选的。 如果省略了temporary,则使用与源槽相同的值。 + 不能复制已失效的槽。 @@ -25043,9 +25794,11 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); lsn pg_lsn ) - 复制一个名为src_slot_name的现有逻辑复制槽到一个名为dst_slot_name的逻辑复制槽,选择性的改变输出插件和持久性。 + 复制一个名为src_slot_name的现有逻辑复制槽到一个名为dst_slot_name的逻辑复制槽,可选地更改输出插件和持久性。 被复制的逻辑槽从与源逻辑槽相同的LSN开始。temporaryplugin都是可选的。 如果它们被省略了,使用与源逻辑槽相同的值。 + 源逻辑槽的failover选项不会被复制,而是默认设为false。这是为了避免故障切换到正在同步该槽的备库后无法继续逻辑复制的风险。 + 不能复制已失效的槽。 @@ -25061,16 +25814,12 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); data text ) - 返回槽slot_name中的改变,从最后一次使用更改的点开始。 - 如果upto_lsnupto_nchanges为 NULL,逻辑解码将一直继续到 WAL 的末尾。 - 如果upto_lsn为非 NULL,解码将只包括那些在指定 LSN 之前提交的事务。 - 如果upto_nchanges为非 NULL,解码将在其产生的行数超过指定值后停止。 - 不过要注意,被返回的实际行数可能更大,因为对这个限制的检查只会在增加了解码每个新的提交事务产生的行之后进行。 + 返回槽 slot_name 中自上次消费更改的位置起的更改。如果 upto_lsnupto_nchanges 都为 NULL,逻辑解码会持续到 WAL 末尾。如果 upto_lsn 非 NULL,解码仅包含在指定 LSN 之前提交的事务。如果 upto_nchanges 非 NULL,解码产生的行数超过指定值时就会停止。不过,实际返回行数可能更大,因为只有在添加完对每个新事务提交进行解码所产生的行后,才会检查此限制。如果指定的槽是逻辑故障切换槽,则只有在synchronized_standby_slots中指定的所有物理槽都确认已接收 WAL 后,该函数才会返回。 - + pg_logical_slot_peek_changes @@ -25120,7 +25869,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); - + pg_replication_slot_advance @@ -25130,9 +25879,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); end_lsn pg_lsn ) - 将复制槽的当前确认的位置提前到名为slot_name的复制槽的当前确认位置。 - 该槽不会向后移动,也不会移动到当前插入位置之外。返回该槽的名称和它被推进到的真实位置。 - 如果有任何进展,则在下一个检查点中写出更新后的槽位置信息。所以如果发生崩溃,该槽位可能会返回到之前的位置。 + 推进名为 slot_name 的复制槽当前已确认的位置。该槽不会后退,也不会越过当前插入位置。返回槽名及其实际推进到的位置。如果发生了推进,更新后的槽位置信息会在下一个检查点写出。因此,发生崩溃时,槽可能回到更早的位置。如果指定的槽是逻辑故障切换槽,则只有在 synchronized_standby_slots 中指定的所有物理槽都确认已接收 WAL 后,该函数才会返回。 @@ -25146,6 +25893,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); 用给定的外部名称创建一个复制源,并且返回分配给它的内部 ID。 + 该名称长度不得超过 512 字节。 @@ -25184,8 +25932,8 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); void - 将当前会话标记为从给定的原点回放,从而允许跟踪回放进度。 - 只能在当前没有选择原点时使用。使用pg_replication_origin_session_reset 命令来撤销。 + 将当前会话标记为从给定的复制源重放,从而允许跟踪重放进度。 + 只能在当前没有选择复制源时使用。使用pg_replication_origin_session_reset来撤销。 @@ -25224,7 +25972,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); pg_lsn - 返回当前会话中选择的复制源的重放位置。参数flush决定对应的本地事务是否被确保已经刷入磁盘。 + 返回当前会话中选择的复制源的重放位置。参数flush决定是否保证对应的本地事务已刷盘。 @@ -25278,7 +26026,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); pg_lsn - 返回给定复制元的重放位置。参数flush决定对应的本地事务是否被确保已经刷入磁盘。 + 返回给定复制源的重放位置。参数flush决定是否保证对应的本地事务已刷盘。 @@ -25287,19 +26035,15 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); pg_logical_emit_message - pg_logical_emit_message ( transactional boolean, prefix text, content text ) + pg_logical_emit_message ( transactional boolean, prefix text, content text , flush boolean DEFAULT false ) pg_lsn - pg_logical_emit_message ( transactional boolean, prefix text, content bytea ) + pg_logical_emit_message ( transactional boolean, prefix text, content bytea , flush boolean DEFAULT false ) pg_lsn - 发出逻辑解码消息。这可以用于通过WAL将通用消息传递给逻辑解码插件。 - transactional参数指定消息是否应该是当前事务的一部分, - 还是应该立即写入并在逻辑解码器读取记录时立即解码。 - prefix参数是一个文本前缀,逻辑解码插件可以使用它轻松识别对它们有趣的消息。 - content参数是消息的内容,可以以文本或二进制形式给出。 + 发出逻辑解码消息。这可用于通过 WAL 向逻辑解码插件传递通用消息。transactional 参数指定消息是作为当前事务的一部分,还是立即写入并在逻辑解码器读到该记录时立即解码。prefix 参数是一个文本前缀,便于逻辑解码插件识别其关注的消息。content 参数是消息内容,可以文本或二进制形式给出。 flush 参数(默认为 false)控制是否立即将消息对应的 WAL 记录刷盘。transactional 为真时,flush 不起作用,因为消息的 WAL 记录会与其事务一起刷盘。 @@ -25388,6 +26132,19 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); + + + + pg_column_toast_chunk_id + + pg_column_toast_chunk_id ( "any" ) + oid + + + 显示磁盘上经过TOAST处理的值的chunk_id。如果该值未经过TOAST处理或不在磁盘上,则返回NULL。有关TOAST的更多信息,请参见。 + + + @@ -25428,13 +26185,13 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); bigint - 计算指定关系的一个fork所使用的磁盘空间。 - (注意在大多数情况下,使用更高级的函数 pg_total_relation_sizepg_table_size更方便,它们将所有分叉(forks)的大小相加。) - 使用一个参数,这将返回关系的主数据分叉的大小。第二个参数可以用来指定要检查哪个分叉: + 计算指定关系的一个分支所使用的磁盘空间。 + (注意在大多数情况下,使用更高级的函数 pg_total_relation_sizepg_table_size更方便,它们将所有分支的大小相加。) + 使用一个参数,这将返回关系的主数据分支的大小。第二个参数可以用来指定要检查哪个分支: - main返回关系的主数据分叉的大小。 + main返回关系的主数据分支的大小。 @@ -25449,7 +26206,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); - init 返回初始化分叉的大小,如果有的话,与关系相关。 + init 返回与该关系关联的初始化分支(如有)的大小。 @@ -25465,7 +26222,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); bigint - 将人可阅读的格式的大小(由pg_size_pretty返回)转换为字节。 + 将人类可读格式的大小(由pg_size_pretty返回)转换为字节。有效的单位为bytesBkBMBGBTBPB @@ -25496,7 +26253,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); bigint - 计算指定表所使用的磁盘空间,不包括索引(但包括它的TOAST表,如果有的话,空闲空间映射,以及可见性映射)。 + 计算指定表所使用的磁盘空间,不包括索引(但包括其 TOAST 表(如有)、空闲空间映射和可见性映射)。 @@ -25530,7 +26287,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); 计算指定表所使用的总磁盘空间,包括所有索引和TOAST数据。 - 结果等价pg_table_size + pg_indexes_size。 + 结果等价于pg_table_size + pg_indexes_size @@ -25538,11 +26295,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); - 上述操作表和索引的函数接受一个regclass参数,它是该表或索引在pg_class系统目录中的 OID。 - 你不必手工去查找该 OID,因为regclass数据类型的输入转换器会为你代劳。 - 只写包围在单引号内的表名,这样它看起来像一个文字常量。 - 为了与普通SQL名称的处理相兼容,该字符串将被转换为小写形式,除非其中在表名周围包含双引号。 - 详见。 + 上述操作表和索引的函数接受一个regclass参数,即该表或索引在pg_class系统目录中的 OID。不必手工查找该 OID,因为regclass数据类型的输入转换器会代为查找。详见 @@ -25576,7 +26329,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); oid - 返回当前分配给指定关系的filenode数字。文件节点是用于该关系的文件名称的基本组件(更多信息请参阅 )。 + 返回当前分配给指定关系的文件结点编号。文件结点是用于该关系的文件名称的基本组件(更多信息请参阅 )。 对于大多数关系,其结果与pg_class.relfilenode相同,但对于某些系统目录,relfilenode为0,并且必须使用这个函数来获得正确的值。 如果传递的是一个没有存储的关系,例如一个视图,那么函数将返回NULL。 @@ -25591,7 +26344,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); text - 返回关系的完整文件路径名称(相对于数据库集簇的数据目录,即关系的PGDATA)。 + 返回关系的完整文件路径名称(相对于数据库集簇的数据目录,即PGDATA)。 @@ -25604,8 +26357,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); regclass - 返回一个给定表空间OID和存储它的文件节点的关系的OID。这本质上是pg_relation_filepath的反向映射。 - 对于数据库默认表空间中的关系,表空间可以指定为0。如果当前数据库中没有与给定值相关联的关系,则返回 NULL。 + 根据关系所在表空间的 OID 和文件结点返回该关系的 OID。这本质上是pg_relation_filepath的反向映射。对于数据库默认表空间中的关系,表空间可以指定为 0。如果当前数据库中没有与给定值关联的关系,或者该关系是临时关系,则返回NULL @@ -25672,13 +26424,13 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); integer - 基于在操作系统中找到的所有区域环境(locales),加入排序规则到系统目录pg_collation中。 - 这是 initdb 会用到的,更多细节请参考。 - 如果后来在操作系统上安装了额外的区域环境,可以再次运行这个函数加入新区域环境的排序规则。 - 匹配pg_collation中现有条目的区域环境将被跳过(但是这个函数不会移除以在操作系统中不再存在的区域环境为基础的排序规则对象)。 - schema参数通常是pg_catalog,但这并非强制要求,排序规则也可以安装到其他模式中。 - 该函数返回其创建的新排序规则对象的数量。 - 此函数仅限超级用户使用。 + 根据操作系统中找到的所有区域设置,向系统目录pg_collation添加排序规则。 + initdb使用的就是此函数;更多信息见。 + 如果以后在操作系统中安装了其他区域设置,可以再次运行此函数,为新区域设置添加排序规则。 + 与pg_collation中现有条目匹配的区域设置会被跳过。 + (但此函数不会删除基于操作系统中已不存在的区域设置的排序规则对象。) + schema参数通常为pg_catalog,但并非必须如此;也可以将排序规则安装到其他模式中。 + 函数返回新建的排序规则对象数量。此函数仅限超级用户使用。 @@ -25721,7 +26473,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); boolean - 更新表级统计信息。通常这些统计信息由自动收集或作为的一部分更新,因此不必调用此函数。但它在恢复后很有用,可以在尚未运行ANALYZE时帮助优化器选择更好的计划。 + 更新表级统计信息。通常这些统计信息会自动收集或作为的一部分更新,因此不必调用此函数。但它在恢复后很有用,可以在尚未运行ANALYZE时帮助优化器选择更好的计划。 被跟踪的统计信息可能因版本而异,所以参数以argnameargvalue对的形式传递: @@ -25746,7 +26498,7 @@ SELECT pg_restore_relation_stats( 参数schemanamerelname是必需的,用于指定表。其他参数是与pg_class中某些列对应的统计信息的名称和值。当前支持的关系统计信息包括:integer类型的relpagesreal类型的reltuplesinteger类型的relallvisible以及integer类型的relallfrozen - 此外,此函数还接受integer类型的参数名version,指定统计信息来源的服务器版本。这有助于从旧版本的PostgreSQL移植统计信息。 + 此外,此函数还接受名为versioninteger类型参数,用于指定统计信息来源的服务器版本。这预计有助于从旧版本的PostgreSQL移植统计信息。 次要错误会以WARNING报告并被忽略,其余统计信息仍将被恢复。如果所有指定的统计信息都成功恢复,则返回true,否则返回false。 @@ -25785,7 +26537,7 @@ SELECT pg_restore_relation_stats( boolean - 创建或更新列级统计信息。通常这些统计信息由自动收集或作为的一部分更新,因此不必调用此函数。但它在恢复后很有用,可以在尚未运行ANALYZE时帮助优化器选择更好的计划。 + 创建或更新列级统计信息。通常这些统计信息会自动收集或作为的一部分更新,因此不必调用此函数。但它在恢复后很有用,可以在尚未运行ANALYZE时帮助优化器选择更好的计划。 被跟踪的统计信息可能因版本而异,所以参数以argnameargvalue对的形式传递: @@ -25812,7 +26564,7 @@ SELECT pg_restore_attribute_stats( 必需的参数包括:text类型的schemanamerelname,用于指定表;text类型的attnamesmallint类型的attnum,用于指定列;以及inherited,指定统计信息是否包含来自子表的值。其他参数是与pg_stats中的列对应的统计信息的名称和值。 - 此外,此函数还接受integer类型的参数名version,指定统计信息来源的服务器版本。这有助于从旧版本的PostgreSQL移植统计信息。 + 此外,此函数还接受名为versioninteger类型参数,用于指定统计信息来源的服务器版本。这预计有助于从旧版本的PostgreSQL移植统计信息。 次要错误会以WARNING报告并被忽略,其余统计信息仍将被恢复。如果所有指定的统计信息都成功恢复,则返回true,否则返回false。 @@ -25920,7 +26672,7 @@ SELECT pg_restore_attribute_stats( - 例如,要检查分区表measurement中包含的数据的总大小,可以使用以下查询: + 例如,要检查分区表measurement中包含的数据的总大小,可以使用以下查询: SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size FROM pg_partition_tree('measurement'); @@ -25935,7 +26687,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size 显示了索引维护任务可以使用的函数。 - (注意,这些维护任务通常由自动清理(autovacuum)自动完成;只有在特殊情况下才需要使用这些函数。) + (注意,这些维护任务通常由 autovacuum 自动完成;只有在特殊情况下才需要使用这些函数。) 这些函数在恢复过程中无法执行。这些函数的使用局限于超级用户和给定索引的所有者。 @@ -25966,7 +26718,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size integer - 扫描指定的BRIN索引以查找基表中当前尚未生成索引摘要的页面范围; + 扫描指定的BRIN索引以查找基表中当前尚未生成索引摘要的页面范围; 对于任何这样的范围,它都通过扫描这些表页来创建一个新的摘要索引元组。 返回插入到索引中的新页面范围摘要的数量。 @@ -25982,7 +26734,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size 对覆盖给定块的页面范围执行摘要(如果尚未摘要)。 - 这类似于brin_summarize_new_values,只是它只处理覆盖给定表块数的页范围。 + 这类似于brin_summarize_new_values,区别在于它只处理包含给定表块编号的页面范围。 @@ -26008,9 +26760,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size bigint - 清理指定GIN索引的pending列表,通过移除里面的条目,以大批的方式,到主要的GIN数据结构。 - 返回从挂起列表中删除的页数。如果参数是使用禁用fastupdate选项构建的GIN索引,则不会发生清理,结果为零,因为索引没有挂起的列表。 - 关于挂起列表和fastupdate选项的详细信息,请参见。 + 将指定 GIN 索引的待处理列表中的条目批量移入主 GIN 数据结构,从而清理该列表。返回从待处理列表中移除的页数。如果参数是禁用fastupdate选项构建的 GIN 索引,则不会进行清理,结果为零,因为该索引没有待处理列表。有关待处理列表和fastupdate选项的详细信息,参见 @@ -26025,21 +26775,20 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size 中展示的函数提供了对数据库服务器所在机器上的文件的本地访问。 - 只能访问数据库集簇目录以及log_directory中的文件,除非用户是超级用户或者被授予了角色pg_read_server_files。 + 只能访问数据库集簇目录以及log_directory中的文件,除非用户是超级用户或者被授予了角色pg_read_server_files。 使用相对路径访问集簇目录里面的文件,以及匹配 log_directory配置设置的路径访问日志文件。 - 注意在pg_read_file()或者相关函数上,向用户授予EXECUTE权限, - 以允许他们有能力读取服务器上该数据库服务器进程能读取的任何文件;这些函数会绕过所有的数据库内权限检查。 - 这意味着,例如,具有这种访问的用户能够读取pg_authid表中存储着认证信息的内容,也能读取数据库中的任何表数据。 - 因此,授予对这些函数的访问应该要很仔细地考虑。 + 注意,向用户授予pg_read_file()或相关函数的 EXECUTE 权限,会使其能够读取服务器上数据库服务器进程能读取的任何文件;这些函数会绕过数据库内部的所有权限检查。例如,具有这种访问权限的用户能够读取存储认证信息的pg_authid表的内容,以及数据库中的任何表数据。因此,授予这些函数的访问权限时应仔细考虑。 - 这些函数中的一些函数有可选的missing_ok参数,可以指定当文件或目录不存在时的行为。 - 如果为true,函数返回NULL或着空结果集,根据适合情况。 - 如果为false,会产生一个错误。默认为false。 + 授予这些函数的权限时,请注意:表中列出可选参数的条目,大多由多个参数列表不同的实际函数实现。若要使用其中某个函数,就必须单独授予该函数的权限。psql\df命令可以帮助检查实际的函数签名。 + + + + 这些函数中的一些函数接受可选的missing_ok参数,用于指定文件或目录不存在时的行为。如果为true,函数会视情况返回NULL或空结果集。如果为false,则会报错。(除文件未找到之外的失败情况,在任何情况下都会报错。)默认为false @@ -26069,12 +26818,12 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size setof text - 返回指定目录中所有文件(和目录以及其他指定文件)的名称。 - include_dot_dirs参数标示在结果集中是否包括...;默认为不包括它们。 - 要包括它们在missing_oktrue时能够有用,以从不存在的目录中辨别一个空目录。 + 返回指定目录中所有文件的名称(包括目录及其他特殊文件)。 + include_dot_dirs参数指示结果集中是否包含...;默认不包含它们。 + 在missing_oktrue时,包含它们有助于区分不存在的目录和空目录。 - 这个函数默认限制为超级用户,但是其他用户可以被授予EXECUTE以运行此函数。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -26093,7 +26842,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size 返回服务器日志目录中每个普通文件的名称、大小和最后修改时间(mtime)。以点开头的文件名、目录和其他特殊文件将被排除。 - 默认情况下,此函数仅限于超级用户和具有pg_monitor角色权限的角色,但其他用户可以被授予EXECUTE权限来运行该函数。 + 默认情况下,此函数仅限超级用户和具有pg_monitor角色权限的角色使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -26113,8 +26862,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size 以点开头的文件名、目录和其他特殊文件将被排除。 - 默认情况下,此函数仅限于超级用户和具有pg_monitor角色权限的角色, - 但其他用户可以被授予EXECUTE权限来运行该函数。 + 默认情况下,此函数仅限超级用户和具有pg_monitor角色权限的角色使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -26134,7 +26882,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size 以点开头的文件名、目录和其他特殊文件将被排除。 - 默认情况下,此函数仅限于超级用户和pg_monitor角色的成员,但其他用户可以被授予EXECUTE权限来运行该函数。 + 默认情况下,此函数仅限超级用户和pg_monitor角色的成员使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -26154,7 +26902,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size 以点开头的文件名、目录和其他特殊文件将被排除。 - 默认情况下,此函数仅限于超级用户和pg_monitor角色的成员,但其他用户可以被授予EXECUTE权限来运行该函数。 + 默认情况下,此函数仅限超级用户和pg_monitor角色的成员使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -26174,7 +26922,26 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size 其中slot_name是作为函数输入提供的复制槽的名称。以点开头的文件名、目录和其他特殊文件将被排除。 - 默认情况下,此函数仅限于超级用户和pg_monitor角色的成员,但其他用户可以被授予EXECUTE权限来运行该函数。 + 默认情况下,此函数仅限超级用户和pg_monitor角色的成员使用,但可以向其他用户授予EXECUTE权限以运行它。 + + + + + + + pg_ls_summariesdir + + pg_ls_summariesdir () + setof record + ( name text, + size bigint, + modification timestamp with time zone ) + + + 返回服务器 WAL 摘要目录(pg_wal/summaries)中每个普通文件的名称、大小和最后修改时间(mtime)。排除名称以点开头的文件、目录及其他特殊文件。 + + + 默认情况下,此函数仅限超级用户和pg_monitor角色的成员使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -26190,11 +26957,11 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size modificationtimestamp with time zone ) - 返回服务器的WAL归档状态目录(pg_wal/archive_status)中的每个普通文件的名称、大小、和最后修改时间(mtime)。 - 文件名以一个点(dot)开始,目录和其他指定的文件不包括。 + 返回服务器 WAL 归档状态目录(pg_wal/archive_status)中每个普通文件的名称、大小和最后修改时间(mtime)。 + 以点号开头的文件名、目录以及其他特殊文件都不会包含在结果中。 - 这个函数默认限制在超级用户和pg_monitor角色的成员,但是其他用户可以被授予EXECUTE以运行此函数。 + 默认情况下,此函数仅限超级用户和pg_monitor角色的成员使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -26211,12 +26978,12 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size modificationtimestamp with time zone ) - 返回针对指定tablespace的临时文件目录中的每个普通文件的名称、大小、和最后修改时间(mtime)。 - 如果tablespace没有提供,pg_default 表空间为被检验的。 - 文件名以一个点(dot)开始,目录和其他指定的文件不包括。 + 返回针对指定tablespace的临时文件目录中每个普通文件的名称、大小和最后修改时间(mtime)。 + 如果未提供tablespace,则检查pg_default表空间。 + 以点号开头的文件名、目录以及其他特殊文件都不会包含在结果中。 - 这个函数默认限制在超级用户和pg_monitor角色的成员,但是其他用户可以被授予EXECUTE以运行此函数。 + 默认情况下,此函数仅限超级用户和pg_monitor角色的成员使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -26225,16 +26992,16 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size pg_read_file - pg_read_file ( filenametext, offset bigint, length bigint , missing_ok boolean ) + pg_read_file ( filenametext, offset bigint, length bigint , missing_ok boolean ) text - 返回一个文本文件的全部或部分,开始于给定的字节offset,在最大的length字节返回(如果文件的结尾先达到了则减少)。 - 如果offset为负,他于文件的结尾有关。如果offsetlength 被省略,整个文件被返回。 - 从文件中读的字节在服务器的编码中解释为字符串;如果它们在哪些编码中不是有效的则抛出错误。 + 返回一个文本文件的全部或部分,从给定的字节offset开始,最多返回length字节(如果先到达文件末尾,则返回更少)。 + 如果offset为负,则它相对于文件末尾计算。如果省略offsetlength,则返回整个文件。 + 从文件中读取的字节会按数据库编码解释为字符串;如果它们在该编码下无效,则会抛出错误。 - 这个函数默认限制在超级用户,但是其他用户可以被授予EXECUTE以运行此函数。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -26243,18 +27010,18 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size pg_read_binary_file - pg_read_binary_file ( filenametext, offset bigint, length bigint , missing_ok boolean ) + pg_read_binary_file ( filenametext, offset bigint, length bigint , missing_ok boolean ) bytea - 返回文件的全部或部分。这个函数与pg_read_file 是完全相同的,除了它可以读任意的二进制数据,返回结果为bytea而不是text; - 因此,没有编码检查会被执行。 + 返回文件的全部或部分。该函数与pg_read_file完全相同,只是它可以读取任意二进制数据,并返回bytea而不是text; + 因此不会执行编码检查。 - 这个函数默认限制在超级用户,但是其他用户可以被授予EXECUTE以运行此函数。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 - 与 convert_from函数组合,这个函数能被用于以指定的编码读文本文件并转换到数据库的编码: + 与convert_from函数配合使用时,该函数可用于按指定编码读取文本文件,并将其转换为数据库编码: SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); @@ -26276,10 +27043,10 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); isdir boolean ) - 返回一个记录,包含文件的大小、最后访问时间戳、最后修改时间戳,最后文件状态变更时间戳(仅在UNIX平台)、文件建立时间戳(仅Windows),和一个标志旗如果它是一个目录。 + 返回一个记录,包含文件大小、最后访问时间戳、最后修改时间戳、最后文件状态变更时间戳(仅限 Unix 平台)、文件创建时间戳(仅限 Windows)以及一个指示其是否为目录的标志。 - 这个函数默认限制在超级用户,但是其他用户可以被授予EXECUTE以运行此函数。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -26299,11 +27066,11 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); - 所有这些函数都打算用于锁定应用程序定义的资源,可以通过一个64位键值或两个32位键值来标识(注意这两个键空间不能重叠)。 - 如果另一个会话已经在相同的资源标识符上持有一个冲突的锁,函数将等待直到资源变成可用,或者返回一个false结果,合适于函数的。 - 锁可以是共享或排他的:共享锁不会与同一资源上的其他共享锁发生冲突,只会与排他锁发生冲突。 - 锁可以在会话级(这样它们被保持直到释放或会话结束)或在事务级(这样它们被保持直到当前事务结束;没有手动释放的供应)。 - 多个会话级锁请求堆栈,因此如果同一个资源标识符被锁定三次,那么必须有三个解锁请求来释放资源,在会话结束之前。 + 这些函数用于锁定应用程序定义的资源;资源可用一个 64 位键值或两个 32 位键值标识(这两个键空间互不重叠)。 + 如果另一个会话已对同一资源标识符持有冲突锁,函数会根据自身的行为等待资源可用,或返回false。 + 锁可以是共享的或排他的:共享锁不会与同一资源上的其他共享锁冲突,只会与排他锁冲突。 + 锁可以在会话级获取(一直保持到释放或会话结束),也可以在事务级获取(一直保持到当前事务结束,不能手动释放)。 + 多次会话级锁请求会累加,因此,如果同一资源标识符被锁定三次,就必须请求解锁三次,才能在会话结束前释放该资源。
@@ -26454,8 +27221,8 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); boolean - 获取一个排他的会话级咨询锁,如果适用。 - 这将立即获得锁并返回true,或者如果不能立即获取锁则立即返回 false而无需等待。 + 尝试获取一个排他的会话级咨询锁。 + 如果能立即获取到锁,就返回true;否则立即返回false,而不等待。 @@ -26472,8 +27239,8 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); boolean - 获取一个共享的会话级咨询锁,如果适用。 - 这将立即获得锁并返回true,或者如果不能立即获取锁则立即返回 false而无需等待。 + 尝试获取一个共享的会话级咨询锁。 + 如果能立即获取到锁,就返回true;否则立即返回false,而不等待。 @@ -26490,8 +27257,8 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); boolean - 获取一个排他的事务级咨询锁,如果适用。 - 这将立即获得锁并返回true,或者如果不能立即获取锁则立即返回 false而无需等待。 + 尝试获取一个排他的事务级咨询锁。 + 如果能立即获取到锁,就返回true;否则立即返回false,而不等待。 @@ -26508,8 +27275,8 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); boolean - 获取一个共享的事务级咨询锁,如果适用。 - 这将立即获得锁并返回true,或者如果不能立即获取锁则立即返回 false而无需等待。 + 尝试获取一个共享的事务级咨询锁。 + 如果能立即获取到锁,就返回true;否则立即返回false,而不等待。 @@ -26564,7 +27331,7 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); trigger - 阻止不做事的更新操作。详见下文。 + 抑制不改变数据的更新操作。详见下文。 CREATE TRIGGER ... suppress_redundant_updates_trigger() @@ -26580,8 +27347,7 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); trigger - 自动从相关的纯文本文档列更新tsvector列。 - 要使用的文本搜索配置是以名称指定为触发器参数。详情请参见。 + 根据关联的纯文本文档列自动更新tsvector列。所用的全文检索配置以名称形式指定为触发器参数。详见 CREATE TRIGGER ... tsvector_update_trigger(tsvcol, 'pg_catalog.swedish', title, body) @@ -26597,8 +27363,7 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); trigger - 自动从相关的纯文本文档列更新tsvector列。 - 要使用的文本搜索配置取自表的regconfig列。详情请参见。 + 根据关联的纯文本文档列自动更新tsvector列。所用的全文检索配置取自表的regconfig列。详见 CREATE TRIGGER ... tsvector_update_trigger_column(tsvcol, tsconfigcol, title, body) @@ -26615,23 +27380,15 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); - 理想的情况下,你应该避免运行实际上并没有改变记录中数据的更新。 - 冗余更新会花费大量不必要的时间,尤其是如果有大量索引要改变, 并将最终不得不清理被死亡行占用的空间。 - 但是,在客户端代码中检测这种情况并不总是容易的,甚至不可能做到。 而写表达式来检测它们容易产生错误。 - 作为替代,使用suppress_redundant_updates_trigger可以跳过不改变数据的更新。 但是,你需要小心使用它。 - 触发器需要很短但不能忽略的时间来处理每条记录,所以如果受更新影响的大多数记录确实变化了,此触发器的使用将使更新比平均水平运行得更慢。 + 理想情况下,应避免执行实际上不会改变记录中数据的更新。冗余更新会耗费大量不必要的时间,尤其是在需要修改许多索引时;它们还会使死行占用空间,最终需要通过清理回收。但是,在客户端代码中检测这种情况并不总是容易,甚至可能无法做到,而编写用于检测的表达式也容易出错。另一种办法是使用suppress_redundant_updates_trigger,跳过不改变数据的更新。但使用时应当谨慎。此触发器处理每条记录的耗时虽小,却不可忽略,因此如果更新涉及的大多数记录确实会改变,使用此触发器反而会增加更新的平均耗时。 - suppress_redundant_updates_trigger函数可以像这样添加到表中: - + 该suppress_redundant_updates_trigger函数可以按如下方式添加到表中: CREATE TRIGGER z_min_update BEFORE UPDATE ON tablename FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); - - 在大多数情况下,你需要为每一行最后触发这个触发器,这样它就不会覆盖可能希望更改该行的其他触发器。 - 请记住,触发器是按照名称顺序触发的,你将为此选择一个触发器名称,该名称位于表中可能存在的任何其他触发器的名称之后。 - (因此在示例中使用了z前缀。) +大多数情况下,需要让该触发器对每一行最后触发,以免覆盖其他可能修改该行的触发器的效果。由于触发器按名称顺序触发,应选择一个排序位于表上其他所有触发器名称之后的名称。(这就是示例中使用z前缀的原因。) @@ -26640,7 +27397,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); 事件触发器函数 - PostgreSQL提供了这些助手函数来从事件触发器检索信息。 + PostgreSQL提供了这些辅助函数来从事件触发器检索信息。 @@ -26662,7 +27419,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); 当在一个ddl_command_end事件触发器的函数中调用时,pg_event_trigger_ddl_commands返回被每一个用户动作执行的DDL命令的列表。 如果在其他任何环境中调用这个函数,会发生错误。 - pg_event_trigger_ddl_commands为每一个被执行的基本命令返回一行,某些只有一个单一 SQL 句子的命令可能会返回多于一行。 + pg_event_trigger_ddl_commands为每一个被执行的基本命令返回一行,某些由单条 SQL 语句构成的命令可能会返回多于一行。 这个函数返回下面的列: @@ -26679,7 +27436,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); classid oid - 对象所属的目录的 OID + 对象所属系统目录的 OID objid @@ -26689,7 +27446,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); objsubid integer - 对象的子-id(例如列的属性号) + 子对象 ID(例如列的属性编号) command_tag @@ -26705,16 +27462,14 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); schema_name text - 该对象所属的模式的名称(如果有),如果没有则为NULL。 - 没有引号。 + 对象所属模式的名称(若有);否则为NULL。不加引号。 object_identity text - 对象标识的文本表现形式,用模式限定。如果必要,出现在 - 该标识中的每一个标识符都会被引用。 + 对象标识的文本表示形式,带模式限定。标识中包含的每个标识符在必要时都会加引号。 @@ -26726,8 +27481,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); command pg_ddl_command - 以内部格式表达的该命令的一个完整表现形式。这不能被直接输出, - 但是可以把它传递给其他函数来得到有关于该命令不同部分的信息。 + 命令的完整内部表示,不能直接输出,但可以将其传给其他函数以获取关于该命令的不同信息。 @@ -26749,8 +27503,8 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); - pg_event_trigger_dropped_objects返回被调用sql_drop事件的命令删除的所有对象的列表。 - 如果调用在任何其他上下文中,会引发一个错误。这个函数返回以下列: + 在命令的sql_drop事件中调用pg_event_trigger_dropped_objects时,它返回该命令删除的所有对象的列表。 + 如果调用在任何其他上下文中,会引发一个错误。这个函数返回以下列: @@ -26766,7 +27520,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); classid oid - 对象所属的目录的 OID + 对象原先所属系统目录的 OID objid @@ -26776,7 +27530,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); objsubid integer - 子对象ID(如列的属性号) + 子对象 ID(例如列的属性编号) original @@ -26787,7 +27541,7 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); normal boolean - 指示在依赖图中有一个普通依赖关系指向该对象的标志 + 如果依赖图中存在指向该对象的普通依赖关系,则为真。 @@ -26806,29 +27560,28 @@ FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); schema_name text - 对象所属模式的名称(如果存在);否则为NULL。不应用引用。 + 对象原先所属模式的名称(若有);否则为NULL。不加引号。 object_name text - 如果模式和名称的组合能被用于对象的一个唯一标识符,则是对象的名称;否则是NULL。不应用引用,并且名称不是模式限定的。 + 如果模式和名称的组合可用作该对象的唯一标识符,则为对象名称;否则为NULL。不加引号,并且该名称永远不带模式限定。 object_identity text - 对象身份的文本表现,模式限定的。每一个以及所有身份中出现的标识符在必要时加引号。 + 对象标识的文本表示形式,带模式限定。标识中包含的每个标识符在必要时都会加引号。 address_names text[] - 一个数组,它可以和object_typeaddress_args, - 一起通过pg_get_object_address函数在一台包含有同类相同名称对象的远程服务器上重建该对象地址。 + 一个数组,可与object_typeaddress_args一起,通过pg_get_object_address函数在包含同类同名对象的远程服务器上重建该对象地址。 @@ -26927,7 +27680,7 @@ CREATE EVENT TRIGGER test_event_trigger_for_drops
- 这些函数可以在事件触发器中使用,就像这样: + 这些函数可以在事件触发器中使用,就像这样: CREATE FUNCTION test_event_trigger_table_rewrite_oid() RETURNS event_trigger @@ -26953,12 +27706,12 @@ CREATE EVENT TRIGGER test_table_rewrite_oid 统计信息函数 - function - statistics + 函数 + 统计信息 - PostgreSQL提供了一个函数来检查使用CREATE STATISTICS命令定义的复杂统计。 + PostgreSQL提供了一个函数来检查使用CREATE STATISTICS命令定义的复杂统计信息。 @@ -26974,7 +27727,7 @@ CREATE EVENT TRIGGER test_table_rewrite_oid - pg_mcv_list_items返回一组记录,描述存储在多列MCV列表中的所有项目。它返回以下列: + pg_mcv_list_items返回一组记录,描述存储在多列MCV列表中的所有项目。它返回以下列: @@ -27010,7 +27763,7 @@ CREATE EVENT TRIGGER test_table_rewrite_oid base_frequency double precision - MCV项目的基本频率 + MCV项目的基础频率 @@ -27018,7 +27771,7 @@ CREATE EVENT TRIGGER test_table_rewrite_oid - pg_mcv_list_items函数可以这样使用: + pg_mcv_list_items函数可以这样使用: SELECT m.* FROM pg_statistic_ext join pg_statistic_ext_data on (oid = stxoid), diff --git a/zh/18/generate-targets-meson.pl b/zh/18/generate-targets-meson.pl index d127429c..fbef1dfd 100644 --- a/zh/18/generate-targets-meson.pl +++ b/zh/18/generate-targets-meson.pl @@ -4,10 +4,21 @@ # Copyright (c) 2000-2025, PostgreSQL Global Development Group use strict; +use utf8; +binmode STDOUT, ':encoding(UTF-8)'; use warnings FATAL => 'all'; + +my %titles = ( + 'Code' => '代码构建目标', + 'Developer' => '开发目标', + 'Documentation' => '文档构建目标', + 'Installation' => '安装目标', + 'Other' => '其他目标', +); + my $targets_meson_file = $ARGV[0]; -open my $targets_meson, '<', $targets_meson_file or die; +open my $targets_meson, '<:encoding(UTF-8)', $targets_meson_file or die; print "\n"; @@ -24,7 +35,7 @@ print qq( - $targets Targets + $titles{$targets} ); diff --git a/zh/18/gin.sgml b/zh/18/gin.sgml index 4ef19c51..249e1d37 100644 --- a/zh/18/gin.sgml +++ b/zh/18/gin.sgml @@ -53,7 +53,7 @@ 内置操作符类 - PostgreSQL 核心发布包含 + PostgreSQL 核心发行版包含 所示的 GIN 操作符类。 (在 中描述的一些可选模块还提供额外的 GIN 操作符类。) @@ -152,7 +152,7 @@ 给定一个要建立索引的项,返回一个用 palloc 分配的键数组。返回键的数量必须存入 *nkeys。如果任一键可以为 null,还要另外 palloc 一个包含 *nkeysbool 字段的数组,将其地址存入 - *nullFlags,并按需设置这些空值标志。如果所有键都非空, + *nullFlags,并按需设置这些空值标志。如果所有键都不是 null, *nullFlags 可以保持为 NULL(其初始值)。 如果该项不包含任何键,则返回值可以为 NULL @@ -172,7 +172,7 @@ query 的数据类型,以及应采用何种方法提取键值。返回键的数量必须存入 *nkeys。如果任一键可以为 null,还要另外 palloc 一个包含 *nkeysbool 字段的数组,将其地址存入 - *nullFlags,并按需设置这些空值标志。如果所有键都非空, + *nullFlags,并按需设置这些空值标志。如果所有键都不是 null, *nullFlags 可以保持为 NULL(其初始值)。 如果 query 不包含任何键,则返回值可以为 NULL @@ -185,7 +185,7 @@ 被设置为 GIN_SEARCH_MODE_INCLUDE_EMPTY,则除至少包含一个匹配键的项之外, 完全不含任何键的项也会被视为候选匹配。(例如,该模式对于实现是子集操作符很有用。) 若 *searchMode 被设置为 GIN_SEARCH_MODE_ALL, - 则索引中所有非空项都会被视为候选匹配,无论它们是否匹配任一返回键。 + 则索引中所有非 null 项都会被视为候选匹配,无论它们是否匹配任一返回键。 (该模式比前两种选择慢得多,因为它基本上需要扫描整个索引;但为了正确处理某些边界情况, 可能有此必要。在大多数情况下都需要此模式的操作符,大概并不适合作为 GIN 操作符类的候选。)用于设置该模式的符号定义在 @@ -218,7 +218,7 @@ 操作符类还必须提供一个函数,用于检查被索引项是否匹配查询。它有两种形式:布尔型 consistent 函数,以及三值型 triConsistent 函数。 triConsistent 覆盖了两者的功能,因此仅提供 triConsistent - 就已经足够。不过,如果布尔变体的计算明显更便宜,那么同时提供两者会更有利。 + 就已经足够。不过,如果布尔变体的计算代价明显更低,那么同时提供两者可能更有利。 若只提供布尔变体,则一些依赖于在取回所有键之前先排除索引项的优化将被禁用。 @@ -233,10 +233,10 @@ 该函数无法直接访问被索引项的值,因为 GIN 并不显式存储项。 它所能利用的是这样一种信息:从查询中提取出的哪些键值出现在给定的被索引项中。 check 数组长度为 nkeys,这与先前针对该 - query 数据由 extractQuery 返回的键数量相同。 + query datum 由 extractQuery 返回的键数量相同。 如果被索引项包含相应查询键,则 check 数组中的对应元素为 true; 也就是说,如果 check[i] == true,则 extractQuery - 结果数组中的第 i 个键存在于该被索引项中。传入原始 query 数据值, + 结果数组中的第 i 个键存在于该被索引项中。传入原始 query datum, 是为了让 consistent 方法在需要时可以查看它;同样也会传入先前由 extractQuery 返回的 queryKeys[]nullFlags[] 数组。extra_data 则是 @@ -274,7 +274,7 @@ 而 GIN_MAYBE 表示该键是否存在尚不确定。存在 GIN_MAYBE 值时,只有当无论索引项是否包含对应查询键,该项都确定匹配时,函数才应返回 GIN_TRUE。同样,只有当无论是否包含 GIN_MAYBE 键, - 该项都确定不匹配时,函数才必须返回 GIN_FALSE。如果结果依赖于 + 该项都确定不匹配时,函数才能返回 GIN_FALSE。如果结果依赖于 GIN_MAYBE 条目,也就是说,无法根据已知的查询键确认或否定匹配, 则函数必须返回 GIN_MAYBE。 @@ -306,7 +306,7 @@ 或者,如果操作符类没有提供 compare 方法,GIN 将查找该索引键数据类型的默认 B-树操作符类,并使用其比较函数。建议在仅面向单一数据类型的 - GIN 操作符类中显式指定比较函数,因为查找 B-树操作符类会消耗少量周期。 + GIN 操作符类中显式指定比较函数,因为查找 B-树操作符类会消耗少量处理器周期。 不过,多态 GIN 操作符类(例如 array_ops)通常无法指定单一比较函数。 @@ -374,8 +374,8 @@ 在内部,一个 GIN 索引包含一个基于键构建的 B-树索引,其中每个键都是一个或多个被索引项中的某个元素 - (例如数组成员),而叶子页中的每个元组要么包含一个指向堆指针 B-树的指针(posting tree), - 要么在列表足够小、能够连同键值一起放入单个索引元组时,直接包含一个简单的堆指针列表(posting list)。 + (例如数组成员),而叶子页中的每个元组要么包含一个指向堆指针 B-树的指针(倒排树), + 要么在列表足够小、能够连同键值一起放入单个索引元组时,直接包含一个简单的堆指针列表(倒排列表)。 展示了 GIN 索引的这些组成部分。 @@ -422,7 +422,7 @@ - 如果一致的响应时间比更新速度更重要,可以通过关闭 GIN 索引的 + 如果稳定的响应时间比更新速度更重要,可以通过关闭 GIN 索引的 fastupdate 存储参数来禁用待处理列表机制。详见 @@ -461,7 +461,7 @@ 当为 GIN 启用 fastupdate 时 (详见 ),这种代价会比未启用时小一些。 - 但对于非常大的更新,最好仍然是删除并重建索引。 + 但对于非常大的更新,删除并重建索引仍然可能是最佳选择。 @@ -529,7 +529,7 @@ GIN 假定可索引操作符是严格的。这意味着,当项值为 null 时, 根本不会对其调用 extractValue(而是自动创建一个占位符索引项); 当查询值为 null 时,也不会调用 extractQuery(而是认为该查询不可满足)。 - 不过要注意,非空组合项或查询值内部包含的 null 键值仍然受支持。 + 不过要注意,非 null 的组合项或查询值内部包含的 null 键值仍然受支持。 @@ -537,7 +537,7 @@ 示例 - PostgreSQL 核心发布包含前面在 + PostgreSQL 核心发行版包含前面在 中展示过的 GIN 操作符类。 下列 contrib 模块也包含 GIN 操作符类: diff --git a/zh/18/gist.sgml b/zh/18/gist.sgml index 8f9abd9e..4f805fe8 100644 --- a/zh/18/gist.sgml +++ b/zh/18/gist.sgml @@ -4,7 +4,7 @@ GiST 索引 - index + 索引 GiST @@ -211,7 +211,7 @@ CREATE INDEX ON my_table USING GIST (my_inet_column inet_ops); - 这种可扩展性不应与其他标准搜索树在可处理数据方面的可扩展性相混淆。例如,PostgreSQL支持可扩展的 B-树和哈希索引。这意味着你可以用PostgreSQL在任意数据类型上构建 B-树或哈希索引。但 B-树只支持范围谓词(<=>),而哈希索引只支持等值查询。 + 这种可扩展性不应与其他标准搜索树在可处理数据方面的可扩展性相混淆。例如,PostgreSQL支持可扩展的 B-树和 hash 索引。这意味着你可以用PostgreSQL在任意数据类型上构建 B-树或 hash 索引。但 B-树只支持范围谓词(<=>),而 hash 索引只支持等值查询。 @@ -262,15 +262,14 @@ my_consistent(PG_FUNCTION_ARGS) bool retval; /* - * determine return value as a function of strategy, key and query. + * 根据 strategy、key 和 query 确定返回值。 * - * Use GIST_LEAF(entry) to know where you're called in the index tree, - * which comes handy when supporting the = operator for example (you could - * check for non empty union() in non-leaf nodes and equality in leaf - * nodes). + * 使用 GIST_LEAF(entry) 判断当前调用位于索引树的哪个位置。 + * 例如,支持 = 操作符时这很有用(可以在非叶节点检查 + * union() 是否非空,在叶节点检查是否相等)。 */ - *recheck = true; /* or false if check is exact */ + *recheck = true; /* 如果检查是精确的,则为 false */ PG_RETURN_BOOL(retval); } @@ -386,10 +385,10 @@ my_compress(PG_FUNCTION_ARGS) if (entry->leafkey) { - /* replace entry->key with a compressed version */ + /* 将 entry->key 替换为压缩后的形式 */ compressed_data_type *compressed_data = palloc(sizeof(compressed_data_type)); - /* fill *compressed_data from entry->key ... */ + /* 根据 entry->key 填充 *compressed_data ... */ retval = palloc(sizeof(GISTENTRY)); gistentryinit(*retval, PointerGetDatum(compressed_data), @@ -397,7 +396,7 @@ my_compress(PG_FUNCTION_ARGS) } else { - /* typically we needn't do anything with non-leaf entries */ + /* 通常无需对非叶项做任何处理 */ retval = entry; } @@ -460,7 +459,7 @@ my_decompress(PG_FUNCTION_ARGS) CREATE OR REPLACE FUNCTION my_penalty(internal, internal, internal) RETURNS internal AS 'MODULE_PATHNAME' -LANGUAGE C STRICT; -- in some cases penalty functions need not be strict +LANGUAGE C STRICT; -- 某些情况下 penalty 函数不必是严格函数 而 C 模块中的对应代码则可以遵循如下框架: @@ -482,7 +481,7 @@ my_penalty(PG_FUNCTION_ARGS) } - 出于历史原因,penalty函数并不是直接返回一个float结果;相反,它必须把该值存储到第三个参数指示的位置。返回值本身会被忽略,不过通常会返回该参数的地址。 + 出于历史原因,penalty函数并不是直接返回一个float结果;相反,它必须把该值存储到第三个参数指示的位置。返回值本身会被忽略,不过通常会返回该参数所指向的地址。 @@ -543,7 +542,7 @@ my_picksplit(PG_FUNCTION_ARGS) unionL = NULL; unionR = NULL; - /* Initialize the raw entry vector. */ + /* 初始化原始项向量。 */ raw_entryvec = (GISTENTRY **) malloc(entryvec->n * sizeof(void *)); for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) raw_entryvec[i] = &(entryvec->vector[i]); @@ -556,9 +555,9 @@ my_picksplit(PG_FUNCTION_ARGS) Assert(tmp_union != NULL); /* - * Choose where to put the index entries and update unionL and unionR - * accordingly. Append the entries to either v->spl_left or - * v->spl_right, and care about the counters. + * 选择索引项的存放位置,并相应更新 unionL 和 unionR。 + * 将项追加到 v->spl_left 或 v->spl_right, + * 同时更新计数器。 */ if (my_choice_is_left(unionL, curl, unionR, curr)) @@ -575,7 +574,7 @@ my_picksplit(PG_FUNCTION_ARGS) else { /* - * Same on the right + * 对右侧执行相同操作 */ } } @@ -629,7 +628,7 @@ my_same(PG_FUNCTION_ARGS) } - 出于历史原因,same函数并不是直接返回一个布尔结果;相反,它必须把该标志存储到第三个参数指示的位置。返回值本身会被忽略,不过通常会返回该参数的地址。 + 出于历史原因,same函数并不是直接返回一个布尔结果;相反,它必须把该标志存储到第三个参数指示的位置。返回值本身会被忽略,不过通常会返回该参数所指向的地址。 @@ -668,7 +667,7 @@ my_distance(PG_FUNCTION_ARGS) double retval; /* - * determine return value as a function of strategy, key and query. + * 根据 strategy、key 和 query 确定返回值。 */ PG_RETURN_FLOAT8(retval); @@ -679,11 +678,11 @@ my_distance(PG_FUNCTION_ARGS) - 在确定距离时允许有一定近似,只要结果永不大于该项的实际距离即可。因此,例如在几何应用中,到外包盒的距离通常就足够了。对于内部树节点,返回的距离不能大于其任一子节点的距离。如果返回的距离不精确,函数必须将*recheck设为 true。(对内部树节点则不必这样做;对它们总是假定计算结果不精确。)在这种情况下,执行器会在从堆中取出元组后计算准确距离,并在必要时重新排序这些元组。 + 在确定距离时允许有一定近似,只要结果永不大于该项的实际距离即可。因此,例如在几何应用中,到包围盒的距离通常就足够了。对于内部树节点,返回的距离不能大于其任一子节点的距离。如果返回的距离不精确,函数必须将*recheck设为 true。(对内部树节点则不必这样做;对它们总是假定计算结果不精确。)在这种情况下,执行器会在从堆中取出元组后计算准确距离,并在必要时重新排序这些元组。 - 如果距离函数对任何叶节点都返回*recheck = true,原始排序操作符的返回类型必须是float8float4,且距离函数的结果值必须能与原始排序操作符的结果进行比较,因为执行器会同时使用距离函数结果和重新计算得到的排序操作符结果进行排序。否则,距离函数的结果值可以是任意有限的float8值,只要这些结果值的相对顺序与排序操作符返回的顺序一致即可。(无穷大和负无穷在内部用于处理空值等情况,因此不建议distance函数返回这些值。) + 如果距离函数对任意一个叶节点返回*recheck = true,原始排序操作符的返回类型必须是float8float4,且距离函数的结果值必须能与原始排序操作符的结果进行比较,因为执行器会同时使用距离函数结果和重新计算得到的排序操作符结果进行排序。否则,距离函数的结果值可以是任意有限的float8值,只要这些结果值的相对顺序与排序操作符返回的顺序一致即可。(无穷大和负无穷在内部用于处理空值等情况,因此不建议distance函数返回这些值。) @@ -727,10 +726,10 @@ my_fetch(PG_FUNCTION_ARGS) fetched_data = palloc(sizeof(fetched_data_type)); /* - * Convert 'fetched_data' into the a Datum of the original datatype. + * 将 'fetched_data' 转换为原始数据类型的 Datum。 */ - /* fill *retval from fetched_data. */ + /* 根据 fetched_data 填充 *retval。 */ gistentryinit(*retval, PointerGetDatum(converted_datum), entry->rel, entry->page, entry->offset, FALSE); @@ -781,26 +780,26 @@ typedef enum MyEnumType typedef struct { - int32 vl_len_; /* varlena header (do not touch directly!) */ - int int_param; /* integer parameter */ - double real_param; /* real parameter */ - MyEnumType enum_param; /* enum parameter */ - int str_param; /* string parameter */ + int32 vl_len_; /* varlena 首部(不要直接操作!) */ + int int_param; /* 整数参数 */ + double real_param; /* 实数参数 */ + MyEnumType enum_param; /* 枚举参数 */ + int str_param; /* 字符串参数 */ } MyOptionsStruct; -/* String representation of enum values */ +/* 枚举值的字符串表示 */ static relopt_enum_elt_def myEnumValues[] = { {"on", MY_ENUM_ON}, {"off", MY_ENUM_OFF}, {"auto", MY_ENUM_AUTO}, - {(const char *) NULL} /* list terminator */ + {(const char *) NULL} /* 列表终止项 */ }; static char *str_param_default = "default"; /* - * Sample validator: checks that string is not longer than 8 bytes. + * 验证器示例:检查字符串长度不超过 8 字节。 */ static void validate_my_string_relopt(const char *value) @@ -812,7 +811,7 @@ validate_my_string_relopt(const char *value) } /* - * Sample filler: switches characters to lower case. + * 填充函数示例:将字符转换为小写。 */ static Size fill_my_string_relopt(const char *value, void *ptr) @@ -865,10 +864,9 @@ my_compress(PG_FUNCTION_ARGS) char *str_param = str_param_default; /* - * Normally, when opclass contains 'options' method, then options are always - * passed to support functions. However, if you add 'options' method to - * existing opclass, previously defined indexes have no options, so the - * check is required. + * 通常,操作符类包含 'options' 方法时,总会把选项传给支持函数。 + * 但是,如果把 'options' 方法添加到已有操作符类中, + * 先前定义的索引没有选项,因此需要进行检查。 */ if (PG_HAS_OPCLASS_OPTIONS()) { @@ -880,7 +878,7 @@ my_compress(PG_FUNCTION_ARGS) str_param = GET_STRING_RELOPTION(options, str_param); } - /* the rest implementation of support function */ + /* 支持函数的其余实现 */ } @@ -924,7 +922,7 @@ PG_FUNCTION_INFO_V1(my_sortsupport); static int my_fastcmp(Datum x, Datum y, SortSupport ssup) { - /* establish order between x and y by computing some sorting value z */ + /* 通过计算某个排序值 z 来确定 x 和 y 的顺序 */ int z1 = ComputeSpatialCode(x); int z2 = ComputeSpatialCode(y); @@ -949,7 +947,7 @@ my_sortsupport(PG_FUNCTION_ARGS) translate_cmptype - 给定一个来自src/include/access/cmptype.hCompareType值,返回该操作符类用于匹配功能的策略号。如果该操作符类没有匹配策略,函数应返回InvalidStrategy。 + 给定一个来自src/include/access/cmptype.hCompareType值,返回该操作符类中具有相应功能的策略号。如果该操作符类没有匹配策略,函数应返回InvalidStrategy @@ -1003,7 +1001,7 @@ my_translate_cmptype(PG_FUNCTION_ARGS) - PostgreSQL提供了一个翻译函数:gist_translate_cmptype_common,用于使用RT*StrategyNumber常量的操作符类。btree_gist扩展又定义了第二个翻译函数gist_translate_cmptype_btree,用于使用BT*StrategyNumber常量的操作符类。 + PostgreSQL提供了一个转换函数:gist_translate_cmptype_common,用于使用RT*StrategyNumber常量的操作符类。btree_gist扩展又定义了第二个转换函数gist_translate_cmptype_btree,用于使用BT*StrategyNumber常量的操作符类。 @@ -1022,7 +1020,7 @@ my_translate_cmptype(PG_FUNCTION_ARGS) GiST 索引构建方法 - 构建 GiST 索引最简单的方法就是把所有项逐个插入。这对于大型索引往往很慢,因为如果索引元组分散在整个索引中,而索引又大到无法放入缓存,就需要大量随机 I/O。PostgreSQL支持两种用于 GiST 索引初始构建的替代方法:sortedbuffered模式。 + 构建 GiST 索引最简单的方法就是把所有项逐个插入。这对于大型索引往往很慢,因为如果索引元组分散在整个索引中,而索引又大到无法放入缓存,就需要大量随机 I/O。PostgreSQL支持两种用于 GiST 索引初始构建的替代方法:排序缓冲模式。 @@ -1068,7 +1066,7 @@ my_translate_cmptype(PG_FUNCTION_ARGS) hstore - 用于存储 (key, value) 对的模块 + 用于存储(键,值)对的模块 diff --git a/zh/18/glossary.sgml b/zh/18/glossary.sgml index bd5493b1..3fabf27d 100644 --- a/zh/18/glossary.sgml +++ b/zh/18/glossary.sgml @@ -382,7 +382,7 @@ 客户端(进程) - 任何进程,可能是远程的,通过连接到某个 + 任何进程,可能是远程的,通过连接到某个 实例来建立 会话, 以与一个数据库交互。 @@ -830,7 +830,7 @@ 一台通过网络与其他计算机通信的计算机。这个术语有时被用作 服务器的同义词。 - 它也用来指客户端进程运行所在的计算机。 + 它也用来指客户端进程运行所在的计算机。 @@ -914,7 +914,7 @@ 实例处理 DBMS 的所有关键特性: 对文件和共享内存的读写访问、保证 ACID 属性、 - 与客户端进程的连接、 + 与客户端进程连接、 权限验证、崩溃恢复、复制等。 @@ -1010,7 +1010,7 @@ - 逻辑复制集簇 + 逻辑复制集群 一组发布者实例和订阅者实例,其中发布者实例把变更复制到订阅者实例。 @@ -1164,7 +1164,7 @@ - 当它用于指代查询中的 + 当它用于指代查询中的 窗口函数时, 分区是一种用户定义的准则,用来标识 查询结果集中哪些相邻的 diff --git a/zh/18/hash.sgml b/zh/18/hash.sgml index 49f4fdf6..0a5f55de 100644 --- a/zh/18/hash.sgml +++ b/zh/18/hash.sgml @@ -1,11 +1,11 @@ -哈希索引 +Hash 索引 索引 - 哈希 + Hash @@ -13,51 +13,51 @@ PostgreSQL - 提供了持久化的磁盘哈希索引实现,并且完全支持崩溃恢复。任何数据类型都可以使用哈希索引,包括那些没有明确定义线性顺序的数据类型。哈希索引只存储被索引数据的哈希值,因此对被索引数据列的大小没有限制。 + 提供了持久化的磁盘 hash 索引实现,并且完全支持崩溃恢复。任何数据类型都可以使用 hash 索引,包括那些没有明确定义线性顺序的数据类型。Hash 索引只存储被索引数据的 hash 值,因此对被索引数据列的大小没有限制。 - 哈希索引仅支持单列索引,也不支持唯一性检查。 + Hash 索引仅支持单列索引,也不支持唯一性检查。 - 哈希索引仅支持=操作符,因此指定范围操作的 WHERE 子句无法利用哈希索引。 + Hash 索引仅支持=操作符,因此指定范围操作的 WHERE 子句无法利用 hash 索引。 - 每个哈希索引元组只存储 4 字节的哈希值,而不存储实际的列值。因此,在为 UUID、URL 等较长的数据项建立索引时,哈希索引可能比 B-树小得多。由于没有列值,所有哈希索引扫描也都是有损的。哈希索引可以参与位图索引扫描和反向扫描。 + 每个 hash 索引元组只存储 4 字节的 hash 值,而不存储实际的列值。因此,在为 UUID、URL 等较长的数据项建立索引时,hash 索引可能比 B-树小得多。由于没有列值,所有 hash 索引扫描也都是有损的。Hash 索引可以参与位图索引扫描和反向扫描。 - 哈希索引最适合于在较大表上执行等值扫描、且以 SELECT 和 UPDATE 为主的工作负载。在 B-树索引中,搜索必须沿树向下直到找到叶页。在拥有数百万行的表中,这种向下遍历会增加访问数据的时间。在哈希索引中,与叶页对应的页称为桶页。相比之下,哈希索引允许直接访问桶页,因此可能减少大表中的索引访问时间。这种“逻辑 I/O”的减少,在索引/数据大于 shared_buffers/RAM 时会更加明显。 + Hash 索引最适合于在较大表上执行等值扫描、且以 SELECT 和 UPDATE 为主的工作负载。在 B-树索引中,搜索必须沿树向下直到找到叶页。在拥有数百万行的表中,这种向下遍历会增加访问数据的时间。在 hash 索引中,与叶页对应的页称为桶页。相比之下,hash 索引允许直接访问桶页,因此可能减少大表中的索引访问时间。这种“逻辑 I/O”的减少,在索引/数据大于 shared_buffers/RAM 时会更加明显。 - 哈希索引在设计上能够应对哈希值分布不均的情况。如果哈希值分布均匀,那么直接访问桶页的效果很好。当插入导致桶页填满时,额外的溢出页就会链接到该特定桶页上,从而在局部扩展用于存放匹配该哈希值的索引元组的空间。查询期间扫描某个哈希桶时,需要遍历其全部溢出页。因此,对于某些数据,不平衡的哈希索引在所需块访问次数方面实际上可能比 B-树更差。 + Hash 索引在设计上能够应对 hash 值分布不均的情况。如果 hash 值分布均匀,那么直接访问桶页的效果很好。当插入导致桶页填满时,额外的溢出页就会链接到该特定桶页上,从而在局部扩展用于存放匹配该 hash 值的索引元组的空间。查询期间扫描某个 hash 桶时,需要遍历其全部溢出页。因此,对于某些数据,不平衡的 hash 索引在所需块访问次数方面实际上可能比 B-树更差。 - 由于会出现这些溢出情况,可以说哈希索引最适合用于唯一值、近乎唯一值,或者每个哈希桶中行数较少的数据。 + 由于会出现这些溢出情况,可以说 hash 索引最适合用于唯一值、近乎唯一值,或者每个 hash 桶中行数较少的数据。 避免问题的一种可能办法,是使用部分索引条件把高度非唯一的值排除在索引之外,但这在很多情况下可能并不适用。 - 与 B-树一样,哈希索引也会执行简单的索引元组删除。这是一种延迟维护操作,用于删除那些已知可以安全删除的索引元组(即其项标识符的 LP_DEAD 位已经被设置的那些元组)。如果插入操作发现页上没有可用空间,我们会尝试通过移除死索引元组来避免创建新的溢出页。如果该页当时已被钉住,就无法执行移除。死索引指针也会在 VACUUM 期间被删除。 + 与 B-树一样,hash 索引也会执行简单的索引元组删除。这是一种延迟维护操作,用于删除那些已知可以安全删除的索引元组(即其项标识符的 LP_DEAD 位已经被设置的那些元组)。如果插入操作发现页上没有可用空间,我们会尝试通过移除死索引元组来避免创建新的溢出页。如果该页当时已被钉住,就无法执行移除。死索引指针也会在 VACUUM 期间被删除。 - 如果可能,VACUUM 还会尝试将索引元组压缩到尽可能少的溢出页上,以最小化溢出链。 + 如果可能,VACUUM 还会尝试将索引元组集中存放在尽可能少的溢出页上,以最小化溢出链。 如果某个溢出页变为空页,该溢出页就可以被回收并在其他桶中重用,不过我们从不将它们返还给操作系统。 - 目前除了使用 REINDEX 重建哈希索引之外,还没有缩小哈希索引的方法。 + 目前除了使用 REINDEX 重建 hash 索引之外,还没有缩小 hash 索引的方法。 同样也没有减少桶数量的方法。 - 随着被索引行数的增长,哈希索引可能会扩展桶页数量。哈希键到桶号的映射经过选择,使得索引能够增量扩展。当需要向索引中添加一个新桶时,恰好只需要“拆分”一个现有桶,并根据更新后的键到桶号映射,将其中一部分元组转移到新桶。 + 随着被索引行数的增长,Hash 索引可能会扩展桶页数量。hash 键到桶号的映射经过选择,使得索引能够增量扩展。当需要向索引中添加一个新桶时,恰好只需要“拆分”一个现有桶,并根据更新后的键到桶号映射,将其中一部分元组转移到新桶。 - 这种扩展是在前台进行的,因此可能会增加用户插入操作的执行时间。因此,哈希索引可能不适合行数快速增长的表。 + 这种扩展是在前台进行的,因此可能会增加用户插入操作的执行时间。因此,hash 索引可能不适合行数快速增长的表。 @@ -66,7 +66,7 @@ 实现 - 哈希索引中有四种页:元页(第零页),其中包含静态分配的控制信息;主桶页;溢出页;以及位图页,后者用于跟踪已被释放且可供重用的溢出页。在寻址时,位图页被视为溢出页的一个子集。 + hash 索引中有四种页:元页(第零页),其中包含静态分配的控制信息;主桶页;溢出页;以及位图页,后者用于跟踪已被释放且可供重用的溢出页。在寻址时,位图页被视为溢出页的一个子集。 @@ -74,15 +74,15 @@ - 主桶页和溢出页是独立分配的,因为任何一个给定索引相对于其桶数,可能需要更多或更少的溢出页。哈希代码使用了一组颇有意思的寻址规则,以支持可变数量的溢出页,同时又不必在主桶页创建后再移动它们。 + 主桶页和溢出页是独立分配的,因为任何一个给定索引相对于其桶数,可能需要更多或更少的溢出页。hash 实现代码使用了一组颇有意思的寻址规则,以支持可变数量的溢出页,同时又不必在主桶页创建后再移动它们。 - 被索引表中的每一行,都由哈希索引中的单个索引元组表示。哈希索引元组存储在桶页中,如果存在溢出页,也会存储在溢出页中。为了加快搜索速度,我们将任一索引页中的索引项按哈希码排序,从而可以在索引页内使用二分查找。但请注意,并不假定同一桶中不同索引页之间的哈希码具有任何相对顺序。 + 被索引表中的每一行,都由 hash 索引中的单个索引元组表示。Hash 索引元组存储在桶页中,如果存在溢出页,也会存储在溢出页中。为了加快搜索速度,我们将任一索引页中的索引项按 hash 码排序,从而可以在索引页内使用二分查找。但请注意,并不假定同一桶中不同索引页之间的 hash 码具有任何相对顺序。 - 用于扩展哈希索引的桶拆分算法过于复杂,这里不再展开说明;但在src/backend/access/hash/README中有更详细的描述。该拆分算法具备崩溃安全性,如果未能成功完成,可以重新启动。 + 用于扩展 hash 索引的桶拆分算法过于复杂,这里不再展开说明;但在src/backend/access/hash/README中有更详细的描述。该拆分算法具备崩溃安全性,如果未能成功完成,可以重新启动。 diff --git a/zh/18/high-availability.sgml b/zh/18/high-availability.sgml index 3e9eec14..a293f9a6 100644 --- a/zh/18/high-availability.sgml +++ b/zh/18/high-availability.sgml @@ -19,7 +19,7 @@ - 某些方案通过只允许一台服务器修改数据来处理同步。能够修改数据的服务器称为读/写、主库(master)主库(primary)服务器。跟踪主库变更的服务器称为备库。只能在被提升为主库之后才能连接的备库称为温备,而能够接受连接并提供只读查询的备库称为热备。 + 某些方案通过只允许一台服务器修改数据来处理同步。能够修改数据的服务器称为读/写、主库(master)主库(primary)服务器。跟踪主库变更的服务器称为备库(standby)备库(secondary)。只能在被提升为主库之后才能连接的备库称为温备,而能够接受连接并提供只读查询的备库称为热备 @@ -102,7 +102,7 @@ protocol to make nodes agree on a serializable transactional order. - 基于触发器的主库-备库复制 + 基于触发器的主备复制 @@ -238,7 +238,7 @@ protocol to make nodes agree on a serializable transactional order. - 主库无额外负载 + 主库无额外开销 @@ -354,7 +354,7 @@ protocol to make nodes agree on a serializable transactional order. - 连续归档可用于创建一种高可用性(HA)集簇配置,其中有一个或多个备库随时准备在主库失效时接管操作。这种能力通常称为温备日志传送。 + 持续归档可用于创建一种高可用性(HA)集簇配置,其中有一个或多个备库随时准备在主库失效时接管操作。这种能力通常称为温备日志传送 @@ -528,7 +528,7 @@ archive_cleanup_command = 'pg_archivecleanup /path/to/archive %r' 认证 - 正确设置复制访问权限非常重要,因为从 WAL 流中很容易提取出需要权限才能访问的信息,因此必须确保只有受信任的用户才能读取它。备库必须以具有 REPLICATION 权限的账户或超级用户身份向主库认证。建议专门创建一个具有 REPLICATIONLOGIN 权限的用户账户用于复制。虽然 REPLICATION 权限的权限很高,但它并不允许用户修改主系统上的任何数据,而 SUPERUSER 权限则允许。 + 正确设置复制访问权限非常重要,因为从 WAL 流中很容易提取出需要权限才能访问的信息,因此必须确保只有受信任的用户才能读取它。备库必须以具有 REPLICATION 权限的账户或超级用户身份向主库认证。建议专门创建一个具有 REPLICATIONLOGIN 权限的用户账户用于复制。虽然 REPLICATION 权限很高,但它并不允许用户修改主系统上的任何数据,而 SUPERUSER 权限则允许。 @@ -559,7 +559,7 @@ primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass' 流复制的一个重要健康指标,是主库上已经生成但尚未在备库上应用的 WAL 记录量。你可以通过比较主库上的当前 WAL 写入位置和备库收到的最后一个 WAL 位置来计算这种滞后。这些位置分别可以用主库上的 pg_current_wal_lsn 和备库上的 pg_last_wal_receive_lsn 取得(详见 )。备库上的最后一个 WAL 接收位置也会显示在 WAL 接收进程的进程状态中,即通过 ps 命令显示的状态(详见 )。 - 你可以通过 pg_stat_replication 视图取得 WAL 发送进程列表。pg_current_wal_lsn 与该视图的 sent_lsn 字段之间存在较大差异,可能表示主库负载很重;而 sent_lsn 与备库上的 pg_last_wal_receive_lsn 之间存在较大差异,则可能表示网络延迟,或者备库负载很重。 + 你可以通过 pg_stat_replication 视图取得 WAL 发送进程列表。pg_current_wal_lsn 与该视图的 sent_lsn 字段之间存在较大差异,可能表示主库负载很重;而 sent_lsn 与备库上的 pg_last_wal_receive_lsn 之间存在差异,则可能表示网络延迟,或者备库负载很重。 在热备上,WAL 接收进程的状态可以通过 @@ -575,13 +575,13 @@ primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass' 流复制 - 复制槽提供了一种自动化方法,以确保主库在所有备库都收到 WAL 段之前不会删除它们,并且即使备库处于断开状态,主库也不会删除可能导致恢复冲突的行。 + 复制槽提供了一种自动化方法,以确保主库在所有备库都收到 WAL 段之前不会删除它们,并且即使备库处于断开状态,主库也不会删除那些一旦删除就可能导致恢复冲突的行。 如果不使用复制槽,也可以通过阻止旧的 WAL 段被移除,或者通过把这些段保存到归档中。这些方法的一个缺点是,它们通常会保留多于实际所需数量的 WAL 段,而复制槽只会保留已知确实需要的段数。 - 类似地,如果不配合复制槽单独使用 ,它虽然能防止相关的行被清理而避免因清理产生的问题,但在备库未连接的那段时间内并不能提供保护。 + 类似地,如果不配合复制槽单独使用 ,它虽然能防止相关的行被清理移除,但在备库未连接的那段时间内并不能提供保护。 @@ -685,7 +685,7 @@ primary_slot_name = 'node_a_slot' - 只读事务和事务回滚不需要等待备库的回应。子事务提交也不需要等待备库响应,只有顶层提交才需要等待。数据装载或索引构建等长时间运行的动作,不会一直等到最终提交消息。所有两阶段提交操作都需要等待提交,包括 prepare 和 commit。 + 只读事务和事务回滚不需要等待备库的回应。子事务提交也不需要等待备库响应,只有顶层提交才需要等待。数据装载或索引构建等长时间运行的动作,直到最终提交时才会等待。所有两阶段提交操作都需要等待提交,包括准备和提交两个阶段。 @@ -700,7 +700,7 @@ primary_slot_name = 'node_a_slot' - 当提交记录已经在主库上写入磁盘之后,WAL 记录就会被发送到备库。每当新的一批 WAL 数据被写入磁盘时,备库就会发送回复消息,除非备库上的wal_receiver_status_interval被设置为零。如果synchronous_commit被设置为remote_apply,那么备库会在提交记录被重放时发送回复消息,从而使该事务变得可见。如果根据主库上的synchronous_standby_names设置,该备库被选为同步备库,那么它发出的回复会与其他同步备库的回复一起,用于决定何时释放那些正在等待确认提交记录已被收到的事务。这些参数允许管理员指定哪些备库应作为同步备库。注意,同步复制的配置主要在主库上进行。被命名的备库必须直接连接到主库;主库并不知道使用级联复制的下游备库。 + 当提交记录已经在主库上写入磁盘之后,WAL 记录就会被发送到备库。每当新的一批 WAL 数据被写入磁盘时,备库就会发送回复消息,除非备库上的wal_receiver_status_interval被设置为零。如果synchronous_commit被设置为remote_apply,那么备库会在提交记录被重放、该事务变得可见时发送回复消息。如果根据主库上的synchronous_standby_names设置,该备库被选为同步备库,那么它发出的回复会与其他同步备库的回复一起,用于决定何时释放那些正在等待确认提交记录已被收到的事务。这些参数允许管理员指定哪些备库应作为同步备库。注意,同步复制的配置主要在主库上进行。被命名的备库必须直接连接到主库;主库并不知道使用级联复制的下游备库。 @@ -712,7 +712,7 @@ primary_slot_name = 'node_a_slot' - 如果请求快速关闭,用户将停止等待。不过,与使用异步复制时一样,在所有尚未解决的 WAL 记录传输到当前已连接的备库之前,服务器不会完全关闭。 + 如果请求快速关闭,用户将停止等待。不过,与使用异步复制时一样,在所有尚未传送的 WAL 记录传输到当前已连接的备库之前,服务器不会完全关闭。 @@ -734,14 +734,14 @@ synchronous_standby_names = 'FIRST 2 (s1, s2, s3)' 在这个例子中,如果四台备库s1s2s3s4都在运行,则s1s2会被选为同步备库,因为它们的名字在备库名称列表中出现得更早。s3是潜在的同步备库,当s1s2中的任意一台失效时,它就会接替其角色。由于s4的名称不在列表中,因此它是异步备库。 - ANY方法指定基于法定人数的同步复制,使事务提交等待,直到它们的 WAL 记录被复制到列表中所要求数量的同步备库中的至少这么多台。 + ANY方法指定基于法定人数的同步复制,使事务提交等待,直到它们的 WAL 记录被复制到列表中至少所要求数量的同步备库。 基于法定人数的多同步备库的synchronous_standby_names示例如下: synchronous_standby_names = 'ANY 2 (s1, s2, s3)' - 在这个例子中,如果四台备库s1s2s3s4都在运行,事务提交将等待来自s1s2s3中的任意两台备库的回复。由于s4的名字不在列表中,因此它是异步备库。 + 在这个例子中,如果四台备库s1s2s3s4都在运行,事务提交将等待来自s1s2s3中的至少任意两台备库的回复。由于s4的名字不在列表中,因此它是异步备库。 备库的同步状态可以通过pg_stat_replication视图查看。 @@ -764,7 +764,7 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' - 通过在应用级别(在主库上)指定同步复制选项,我们可以只对最重要的变更提供同步复制,而不会拖慢整体工作负载。应用级别选项是让高性能应用获得同步复制收益的一种重要而实用的工具。 + 通过在应用级别(在主库上)指定同步复制选项,我们可以只对最重要的变更提供同步复制,而不会拖慢大部分工作负载。应用级别选项是让高性能应用获得同步复制收益的一种重要而实用的工具。 @@ -797,7 +797,7 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' - 如果主库在提交正等待确认时重启,这些等待中的事务会在主库恢复后被标记为已完全提交。无法确定在主库崩溃时,所有备库是否已经收到全部尚未处理的 WAL 数据。因此,某些事务可能不会在备库上显示为已提交,即使它们在主库上显示为已提交。我们所提供的保证是:只有在确认 WAL 数据已经被所有同步备库安全接收之后,应用才会收到事务成功提交的显式确认。 + 如果主库在提交正等待确认时重启,这些等待中的事务会在主库恢复后被标记为已完全提交。无法确定在主库崩溃时,所有备库是否已经收到全部待传送的 WAL 数据。因此,某些事务可能不会在备库上显示为已提交,即使它们在主库上显示为已提交。我们所提供的保证是:只有在确认 WAL 数据已经被所有同步备库安全接收之后,应用才会收到事务成功提交的显式确认。 @@ -857,7 +857,7 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' - 一旦故障切换到备库,系统中就只剩下一台服务器在运行。这被称为退化状态。原来的备库现在成为主库,而原来的主库已经停机,并且可能持续停机。要恢复到正常运行状态,就必须重新创建一台备库:要么在原主库恢复后在其上重建,要么在第三台可能是全新的服务器上重建。在大型集簇上,可以使用工具来加快这一过程。一旦完成,就可以认为主库和备库已经交换了角色。有些人会选择使用第三台服务器,在新的备库重建完成之前为新的主库提供备份,但显然这会让系统配置和操作流程更加复杂。 + 一旦故障切换到备库,系统中就只剩下一台服务器在运行。这被称为退化状态。原来的备库现在成为主库,而原来的主库已经停机,并且可能持续停机。要恢复到正常运行状态,就必须重新创建一台备库:要么在原主库恢复后在其上重建,要么在第三台可能是全新的服务器上重建。在大型集簇上,可以使用工具来加快这一过程。一旦完成,就可以认为主库和备库已经交换了角色。有些人会选择使用第三台服务器,在新的备库重建完成之前为新的主库提供后备支持,但显然这会让系统配置和操作流程更加复杂。 @@ -920,7 +920,7 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' - 事务管理命令: + 事务管理命令: @@ -934,7 +934,7 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' - EXCEPTION块或其他内部子事务 + EXCEPTION块和其他内部子事务 @@ -974,7 +974,7 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' 数据操纵语言(DML):INSERTUPDATEDELETEMERGECOPY FROM、 - TRUNCATE。请注意,恢复期间不存在任何允许执行触发器的动作。这个限制甚至适用于临时表,因为不分配事务 ID 就无法读取或写入表行,而这在热备环境中目前是不可能的。 + TRUNCATE。请注意,恢复期间不存在任何允许执行触发器的动作。这个限制甚至适用于临时表,因为不分配事务 ID 就无法读取或写入表行,而目前热备环境中无法分配事务 ID。 @@ -1009,13 +1009,13 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' - BEGIN READ WRITE, + BEGIN READ WRITESTART TRANSACTION READ WRITE - SET TRANSACTION READ WRITE, + SET TRANSACTION READ WRITESET SESSION CHARACTERISTICS AS TRANSACTION READ WRITE @@ -1031,7 +1031,7 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' 两阶段提交命令:PREPARE TRANSACTIONCOMMIT PREPAREDROLLBACK PREPARED, - 因为即使是只读事务,在 prepare 阶段(两阶段提交的第一阶段)也需要写入 WAL。 + 因为即使是只读事务,在准备阶段(两阶段提交的第一阶段)也需要写入 WAL。 @@ -1117,24 +1117,22 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' - 一旦max_standby_archive_delaymax_standby_streaming_delay指定的延迟被超越,冲突查询将被取消。这通常仅导致一个取消错误,尽管在重放一个DROP DATABASE的情况下整个冲突会话都将被中断。另外,如果冲突发生在一个被空闲事务持有的锁上,该冲突会话会被中断(这种行为可能在未来被改变)。 + 一旦max_standby_archive_delaymax_standby_streaming_delay指定的延迟被超越,冲突查询将被取消。这通常仅导致一个取消错误,尽管在重放一个DROP DATABASE的情况下整个冲突会话都将被终止。另外,如果冲突发生在一个被空闲事务持有的锁上,该冲突会话会被终止(这种行为可能在未来被改变)。 - - 被取消的查询可能会立即被重试(当然是在开始一个新的事务后)。因为查询取消依赖于 WAL 记录被重放的本质,如果一个被取消的查询被再次执行,它可能会很好地成功完成。 - + 被取消的查询可以立即重试(当然,要先开始一个新事务)。由于查询取消取决于正在重放的 WAL 记录的性质,被取消的查询再次执行时完全可能成功。 - 记住延迟参数是从 WAL 数据被备库收到后流逝的时间。因此,留给备库上任何一个查询的宽限期从不会超过延迟参数,并且如果备库已经由于等待之前的查询完成而落后或者因为过重的更新负载而无法跟上主库,宽限期可能会更少。 + 请记住,延迟参数要与备库收到 WAL 数据之后经过的时间进行比较。因此,留给备库上任何一个查询的宽限期从不会超过延迟参数,并且如果备库已经由于等待之前的查询完成而落后或者因为过重的更新负载而无法跟上主库,宽限期可能会更少。 - 备库查询与 WAL 重放发生冲突的最常见原因是过早清理。正常情况下,当没有事务需要看到旧行版本时,PostgreSQL允许清理这些旧行版本,以保证按照 MVCC 规则得到正确的数据可见性。不过,这条规则只能应用于在主库上执行的事务。因此,主库上的清理有可能移除某个备库事务仍然可见的行版本。 + 备库查询与 WAL 重放发生冲突的最常见原因是过早清理。正常情况下,当不再有事务需要看到旧行版本来保证符合 MVCC 规则的数据可见性时,PostgreSQL允许清理这些旧行版本。不过,这条规则只能应用于在主库上执行的事务。因此,主库上的清理有可能移除某个备库事务仍然可见的行版本。 行版本清理并不是与备库查询发生冲突的唯一潜在原因。所有仅索引扫描(包括在备库上运行的那些)都必须使用一个MVCC快照,它与可见性映射一致。因此,每当VACUUM在可见性映射中把某个页面标记为全可见,而该页面中包含一行或多行对所有备库查询都不可见的数据时,就必须产生冲突。所以,即使针对一个没有更新或删除任何需要清理行的表执行VACUUM,也可能导致冲突。 + linkend="vacuum-for-visibility-map">在可见性映射中把某个页面标记为全可见,而该页面中包含并非对所有备库查询都可见的一行或多行数据时,就必须产生冲突。所以,即使针对一个没有需要清理的已更新或已删除行的表执行VACUUM,也可能导致冲突。 @@ -1237,7 +1235,7 @@ HINT: You can then restart the server after making the necessary configuration - 主库上写出的事务状态 "hint bits" 不会被 WAL 记录,因此备库上的数据很可能会再次写出这些提示位。这样一来,即使所有用户都是只读的,备库仍然会执行磁盘写操作;不过数据值本身并不会发生变化。用户仍然会写出大型排序临时文件,并重新生成 relcache 信息文件,因此在热备模式下,数据库没有任何部分是真正只读的。还要注意,使用dblink模块写入远程数据库,以及借助 PL 函数执行其他数据库外部操作,依然是可能的,即使该事务在本地是只读的。 + 主库上写出的事务状态“提示位” 不会被 WAL 记录,因此备库上的数据很可能会再次写出这些提示位。这样一来,即使所有用户都是只读的,备库仍然会执行磁盘写操作;不过数据值本身并不会发生变化。用户仍然会写出大型排序临时文件,并重新生成 relcache 信息文件,因此在热备模式下,数据库没有任何部分是真正只读的。还要注意,使用dblink模块写入远程数据库,以及借助 PL 函数执行其他数据库外部操作,依然是可能的,即使该事务在本地是只读的。 @@ -1246,7 +1244,7 @@ HINT: You can then restart the server after making the necessary configuration - 数据定义语言:例如 CREATE INDEX + 数据定义语言(DDL):例如 CREATE INDEX diff --git a/zh/18/images/fixup-svg.xsl b/zh/18/images/fixup-svg.xsl index d6c46b36..cf7169bb 100644 --- a/zh/18/images/fixup-svg.xsl +++ b/zh/18/images/fixup-svg.xsl @@ -32,6 +32,11 @@ Fix stroke="transparent" attribute, which is invalid SVG. none + + + 'Alibaba PuHuiTi 3.0',serif + + diff --git a/zh/18/images/gin.gv b/zh/18/images/gin.gv index 097e9102..b8e26542 100644 --- a/zh/18/images/gin.gv +++ b/zh/18/images/gin.gv @@ -1,11 +1,12 @@ digraph "gin" { layout=dot; - node [label="", shape=box, style=filled, fillcolor=gray, width=1.4]; + fontname="Alibaba PuHuiTi 3.0"; + node [fontname="Alibaba PuHuiTi 3.0", label="", shape=box, style=filled, fillcolor=gray, width=1.4]; - m1 [label="meta page"]; + m1 [label="元页"]; subgraph cluster01 { - label="entry tree"; + label="键项树"; subgraph egroup1 { rank=same; e1; @@ -27,13 +28,13 @@ digraph "gin" { e4 -> e8; e4 -> e9; - e6 [fillcolor=green, label="posting list"]; - e8 [fillcolor=green, label="posting list"]; - e9 [fillcolor=green, label="posting list"]; + e6 [fillcolor=green, label="倒排列表"]; + e8 [fillcolor=green, label="倒排列表"]; + e9 [fillcolor=green, label="倒排列表"]; } subgraph cluster02 { - label="posting tree"; + label="倒排树"; subgraph pgroup1 { rank=same; p1; @@ -45,22 +46,22 @@ digraph "gin" { p1 -> p2; p1 -> p3; - p2 [fillcolor=green, label="heap ptr"]; - p3 [fillcolor=green, label="heap ptr"]; + p2 [fillcolor=green, label="堆指针"]; + p3 [fillcolor=green, label="堆指针"]; } subgraph cluster03 { - label="posting tree"; + label="倒排树"; subgraph pgroup3 { rank=same; p4; } - p4 [fillcolor=green, label="heap ptr"]; + p4 [fillcolor=green, label="堆指针"]; } subgraph cluster04 { - label="posting tree"; + label="倒排树"; subgraph pgroup4 { rank=same; p5; @@ -72,12 +73,12 @@ digraph "gin" { p5 -> p6; p5 -> p7; - p6 [fillcolor=green, label="heap ptr"]; - p7 [fillcolor=green, label="heap ptr"]; + p6 [fillcolor=green, label="堆指针"]; + p7 [fillcolor=green, label="堆指针"]; } subgraph cluster05 { - label="pending list"; + label="待处理列表"; node [style=filled, fillcolor=red]; n1 -> n2 -> n3 -> n4; } diff --git a/zh/18/images/gin.svg b/zh/18/images/gin.svg index 04fe85ba..79cf14a9 100644 --- a/zh/18/images/gin.svg +++ b/zh/18/images/gin.svg @@ -9,33 +9,33 @@ cluster01 -entry tree +键项树 cluster02 -posting tree +倒排树 cluster03 -posting tree +倒排树 cluster04 -posting tree +倒排树 cluster05 -pending list +待处理列表 m1 -meta page +元页 @@ -113,7 +113,7 @@ e6 -posting list +倒排列表 @@ -142,7 +142,7 @@ e8 -posting list +倒排列表 @@ -154,7 +154,7 @@ e9 -posting list +倒排列表 @@ -195,7 +195,7 @@ p4 -heap ptr +堆指针 @@ -224,7 +224,7 @@ p2 -heap ptr +堆指针 @@ -236,7 +236,7 @@ p3 -heap ptr +堆指针 @@ -254,7 +254,7 @@ p6 -heap ptr +堆指针 @@ -266,7 +266,7 @@ p7 -heap ptr +堆指针 diff --git a/zh/18/indexam.sgml b/zh/18/indexam.sgml index 9444743f..d2150755 100644 --- a/zh/18/indexam.sgml +++ b/zh/18/indexam.sgml @@ -21,7 +21,7 @@ - 索引本质上是从一些数据键值到行版本(元组)在索引父表中的元组标识符TID)的映射。一个 TID 由块号以及该块中的项号组成(见 元组标识符(TIDs)的映射。一个 TID 由块号以及该块中的项号组成(见 )。这些信息足以从表中取出某个特定的行版本。索引并不直接知道在 MVCC 之下同一逻辑行可能会存在多个现存版本;对索引来说,每个元组都是一个独立对象,需要它自己的索引条目。因此,对一行的更新总会为该行创建全新的索引条目,即使键值并未改变也是如此。(HOT 元组是这一说法的例外;但索引同样不直接处理它们。)当死元组自身被回收时(通过清理),它们对应的索引条目也会被回收。 @@ -44,89 +44,89 @@ typedef struct IndexAmRoutine NodeTag type; /* - * Total number of strategies (operators) by which we can traverse/search - * this AM. Zero if AM does not have a fixed set of strategy assignments. + * 可用于遍历或搜索此 AM 的策略(操作符)总数。 + * 如果 AM 没有固定的一组策略分配,则为零。 */ uint16 amstrategies; - /* total number of support functions that this AM uses */ + /* 此 AM 使用的支持函数总数 */ uint16 amsupport; - /* opclass options support function number or 0 */ + /* 操作符类选项支持函数编号,或为 0 */ uint16 amoptsprocnum; - /* does AM support ORDER BY indexed column's value? */ + /* AM 是否支持按被索引列的值进行 ORDER BY? */ bool amcanorder; - /* does AM support ORDER BY result of an operator on indexed column? */ + /* AM 是否支持按被索引列上操作符的结果进行 ORDER BY? */ bool amcanorderbyop; - /* does AM support hashing using API consistent with the hash AM? */ + /* AM 是否支持使用与 hash AM 一致的 API 进行哈希? */ bool amcanhash; - /* do operators within an opfamily have consistent equality semantics? */ + /* 操作符族内的操作符是否具有一致的相等语义? */ bool amconsistentequality; - /* do operators within an opfamily have consistent ordering semantics? */ + /* 操作符族内的操作符是否具有一致的排序语义? */ bool amconsistentordering; - /* does AM support backward scanning? */ + /* AM 是否支持反向扫描? */ bool amcanbackward; - /* does AM support UNIQUE indexes? */ + /* AM 是否支持 UNIQUE 索引? */ bool amcanunique; - /* does AM support multi-column indexes? */ + /* AM 是否支持多列索引? */ bool amcanmulticol; - /* does AM require scans to have a constraint on the first index column? */ + /* AM 是否要求扫描必须约束第一个索引列? */ bool amoptionalkey; - /* does AM handle ScalarArrayOpExpr quals? */ + /* AM 是否处理 ScalarArrayOpExpr 限定条件? */ bool amsearcharray; - /* does AM handle IS NULL/IS NOT NULL quals? */ + /* AM 是否处理 IS NULL/IS NOT NULL 限定条件? */ bool amsearchnulls; - /* can index storage data type differ from column data type? */ + /* 索引存储数据类型是否可以不同于列数据类型? */ bool amstorage; - /* can an index of this type be clustered on? */ + /* 是否可以按此类型的索引进行聚簇? */ bool amclusterable; - /* does AM handle predicate locks? */ + /* AM 是否处理谓词锁? */ bool ampredlocks; - /* does AM support parallel scan? */ + /* AM 是否支持并行扫描? */ bool amcanparallel; - /* does AM support parallel build? */ + /* AM 是否支持并行构建? */ bool amcanbuildparallel; - /* does AM support columns included with clause INCLUDE? */ + /* AM 是否支持由 INCLUDE 子句包含的列? */ bool amcaninclude; - /* does AM use maintenance_work_mem? */ + /* AM 是否使用 maintenance_work_mem? */ bool amusemaintenanceworkmem; - /* does AM summarize tuples, with at least all tuples in the block - * summarized in one summary */ + /* AM 是否对元组进行摘要,且一个摘要至少涵盖 + * 块中的所有元组? */ bool amsummarizing; - /* OR of parallel vacuum flags */ + /* 并行清理标志的 OR 组合 */ uint8 amparallelvacuumoptions; - /* type of data stored in index, or InvalidOid if variable */ + /* 索引中存储的数据类型;如果可变,则为 InvalidOid */ Oid amkeytype; - /* interface functions */ + /* 接口函数 */ ambuild_function ambuild; ambuildempty_function ambuildempty; aminsert_function aminsert; - aminsertcleanup_function aminsertcleanup; /* can be NULL */ + aminsertcleanup_function aminsertcleanup; /* 可以为 NULL */ ambulkdelete_function ambulkdelete; amvacuumcleanup_function amvacuumcleanup; - amcanreturn_function amcanreturn; /* can be NULL */ + amcanreturn_function amcanreturn; /* 可以为 NULL */ amcostestimate_function amcostestimate; - amgettreeheight_function amgettreeheight; /* can be NULL */ + amgettreeheight_function amgettreeheight; /* 可以为 NULL */ amoptions_function amoptions; - amproperty_function amproperty; /* can be NULL */ - ambuildphasename_function ambuildphasename; /* can be NULL */ + amproperty_function amproperty; /* 可以为 NULL */ + ambuildphasename_function ambuildphasename; /* 可以为 NULL */ amvalidate_function amvalidate; - amadjustmembers_function amadjustmembers; /* can be NULL */ + amadjustmembers_function amadjustmembers; /* 可以为 NULL */ ambeginscan_function ambeginscan; amrescan_function amrescan; - amgettuple_function amgettuple; /* can be NULL */ - amgetbitmap_function amgetbitmap; /* can be NULL */ + amgettuple_function amgettuple; /* 可以为 NULL */ + amgetbitmap_function amgetbitmap; /* 可以为 NULL */ amendscan_function amendscan; - ammarkpos_function ammarkpos; /* can be NULL */ - amrestrpos_function amrestrpos; /* can be NULL */ + ammarkpos_function ammarkpos; /* 可以为 NULL */ + amrestrpos_function amrestrpos; /* 可以为 NULL */ - /* interface functions to support parallel index scans */ - amestimateparallelscan_function amestimateparallelscan; /* can be NULL */ - aminitparallelscan_function aminitparallelscan; /* can be NULL */ - amparallelrescan_function amparallelrescan; /* can be NULL */ + /* 支持并行索引扫描的接口函数 */ + amestimateparallelscan_function amestimateparallelscan; /* 可以为 NULL */ + aminitparallelscan_function aminitparallelscan; /* 可以为 NULL */ + amparallelrescan_function amparallelrescan; /* 可以为 NULL */ - /* interface functions to support planning */ - amtranslate_strategy_function amtranslatestrategy; /* can be NULL */ - amtranslate_cmptype_function amtranslatecmptype; /* can be NULL */ + /* 支持规划的接口函数 */ + amtranslate_strategy_function amtranslatestrategy; /* 可以为 NULL */ + amtranslate_cmptype_function amtranslatecmptype; /* 可以为 NULL */ } IndexAmRoutine; @@ -148,7 +148,7 @@ typedef struct IndexAmRoutine - amsummarizing 标志指示该访问方法是否会对被索引元组做摘要,并且摘要粒度至少达到每个块一个摘要。不指向单个元组,而是指向块范围(例如 BRIN)的访问方法,可能允许继续使用 HOT 优化。这不适用于索引谓词中引用的属性,对这类属性的更新总会禁用 HOT。 + amsummarizing 标志指示该访问方法是否会对被索引元组做摘要,并且摘要粒度至少为一个块。不指向单个元组,而是指向块范围(例如 BRIN)的访问方法,可能允许继续使用 HOT 优化。这不适用于索引谓词中引用的属性,对这类属性的更新总会禁用 HOT @@ -215,7 +215,7 @@ void aminsertcleanup (Relation indexRelation, IndexInfo *indexInfo); - 清理由 indexInfo->ii_AmCache 在连续插入之间维护的状态。如果这些数据需要额外的清理步骤(例如释放已钉住的缓冲区),而仅释放内存还不够,那么这个函数就很有用。 + 清理在 indexInfo->ii_AmCache 中跨连续插入维护的状态。如果这些数据需要额外的清理步骤(例如释放已钉住的缓冲区),而仅释放内存还不够,那么这个函数就很有用。 @@ -226,7 +226,7 @@ ambulkdelete (IndexVacuumInfo *info, IndexBulkDeleteCallback callback, void *callback_state); - 从索引中删除元组。这是一个批量删除操作,通常应通过扫描整个索引并检查每个条目是否应被删除来实现。必须调用传入的 callback 函数,其调用形式为 callback(TID, callback_state) returns bool,以确定由其引用 TID 标识的某个索引条目是否应删除。该函数必须返回 NULL,或者返回一个通过 palloc 分配的结构体,其中包含此次删除操作影响的统计信息。如果不需要向 amvacuumcleanup 传递信息,返回 NULL 也是可以的。 + 从索引中删除元组。这是一个批量删除操作,旨在通过扫描整个索引并检查每个条目是否应被删除来实现。必须调用传入的 callback 函数,其调用形式为 callback(TID, callback_state) returns bool,以确定由其引用 TID 标识的某个索引条目是否应删除。该函数必须返回 NULL,或者返回一个通过 palloc 分配的结构体,其中包含此次删除操作影响的统计信息。如果不需要向 amvacuumcleanup 传递信息,返回 NULL 也是可以的。 @@ -251,8 +251,7 @@ amvacuumcleanup (IndexVacuumInfo *info, bool amcanreturn (Relation indexRelation, int attno); - 检查索引是否能够在给定列上支持 仅索引扫描,做法是返回该列原始的被索引值。属性编号从 1 开始,也就是说第一列的 attno 为 1。若支持则返回真,否则返回假。如果支持包含列,这个函数应始终对包含列返回真,因为不能取回的包含列几乎没有意义。如果访问方法根本不支持仅索引扫描,那么它的 IndexAmRoutine 结构体中的 amcanreturn 字段可以设为 NULL。 + 检查索引能否通过返回给定列原始的被索引值,在该列上支持 仅索引扫描。属性编号从 1 开始,也就是说第一列的 attno 为 1。若支持则返回真,否则返回假。如果支持包含列,这个函数应始终对包含列返回真,因为不能取回的包含列几乎没有意义。如果访问方法根本不支持仅索引扫描,那么它的 IndexAmRoutine 结构体中的 amcanreturn 字段可以设为 NULL。 @@ -267,7 +266,7 @@ amcostestimate (PlannerInfo *root, double *indexCorrelation, double *indexPages); - 估计一次索引扫描的开销。该函数将在后面的 中详细讨论。 + 估计一次索引扫描的代价。该函数将在后面的 中详细讨论。 @@ -275,7 +274,7 @@ amcostestimate (PlannerInfo *root, int amgettreeheight (Relation rel); - 计算树形索引的高度。这一信息会通过 path->indexinfo->tree_height 提供给 amcostestimate 函数,可用于支持开销估计。其结果不会在其他地方使用,因此这个函数实际上也可以用来计算索引上任何一种适合装入整数、且开销估计函数可能想知道的数据。如果计算代价较高,把结果缓存到 RelationData.rd_amcache 中可能会有用。 + 计算树形索引的高度。这一信息会通过 path->indexinfo->tree_height 提供给 amcostestimate 函数,可用于支持代价估算。其结果不会在其他地方使用,因此这个函数实际上也可以用来计算索引上任何一种适合装入整数、且代价估算函数可能想知道的数据。如果计算代价较高,把结果缓存到 RelationData.rd_amcache 中可能会有用。 @@ -284,7 +283,7 @@ bytea * amoptions (ArrayType *reloptions, bool validate); - 解析并验证索引的 reloptions 数组。只有当该索引存在非空的 reloptions 数组时才会调用此函数。reloptions 是一个 text 数组,其中的条目形如 name=value。该函数应构造一个 bytea 值,并将其复制到索引 relcache 条目的 rd_options 字段中。这个 bytea 值中的数据内容由访问方法自行定义;大多数标准访问方法使用结构体 StdRdOptions。当 validate 为真时,若存在未识别选项或无效取值,函数应报告合适的错误消息;当 validate 为假时,无效条目应被静默忽略。(当装载已存储在 pg_catalog 中的选项时,validate 为假;此时只有在访问方法改变了选项规则时才可能发现无效条目,而忽略过时条目是合适的。)如果希望采用默认行为,返回 NULL 也是可以的。 + 解析并验证索引的 reloptions 数组。只有当该索引存在非 NULL 的 reloptions 数组时才会调用此函数。reloptions 是一个 text 数组,其中的条目形如 name=value。该函数应构造一个 bytea 值,并将其复制到索引 relcache 条目的 rd_options 字段中。这个 bytea 值中的数据内容由访问方法自行定义;大多数标准访问方法使用结构体 StdRdOptions。当 validate 为真时,若存在未识别选项或无效取值,函数应报告合适的错误消息;当 validate 为假时,无效条目应被静默忽略。(当装载已存储在 pg_catalog 中的选项时,validate 为假;此时只有在访问方法改变了选项规则时才可能发现无效条目,而忽略过时条目是合适的。)如果希望采用默认行为,返回 NULL 也是可以的。 @@ -298,7 +297,7 @@ amproperty (Oid index_oid, int attno, - 支持排序操作符的访问方法应当实现 AMPROP_DISTANCE_ORDERABLE 属性测试,因为核心代码不知道如何完成该测试,只会返回 NULL。若实现成本低于打开索引并调用 amcanreturn(这正是核心代码的默认行为),那么实现 AMPROP_RETURNABLE 测试也可能是有利的。对于其他所有标准属性,默认行为应当已经足够。 + 支持排序操作符的访问方法应当实现 AMPROP_DISTANCE_ORDERABLE 属性测试,因为核心代码不知道如何完成该测试,只会返回 NULL。若完成该测试的代价低于打开索引并调用 amcanreturn(这正是核心代码的默认行为),那么实现 AMPROP_RETURNABLE 测试也可能是有利的。对于其他所有标准属性,默认行为应当已经足够。 @@ -360,11 +359,11 @@ bool amgettuple (IndexScanDesc scan, ScanDirection direction); - 在给定扫描中取出下一个元组,并按给定方向移动(在索引中向前或向后)。若成功取得元组则返回真;若不再有匹配元组则返回假。在返回真时,元组的 TID 会存入 scan 结构体中。请注意,成功仅表示索引中存在一个匹配扫描键的条目,并不表示该元组一定仍然存在于堆中,或者一定能通过调用者的快照测试。成功时,amgettuple 还必须把 scan->xs_recheck 设为真或假。假表示可以确定该索引条目匹配扫描键;真表示这一点并不确定,因此在取到堆元组后必须根据扫描键所代表的条件重新检查它。这一机制支持有损索引操作符。请注意,重检只会扩展到扫描条件;部分索引谓词(如果有)永远不会由 amgettuple 的调用者重新检查。 + 在给定扫描中取出下一个元组,并按给定方向移动(在索引中向前或向后)。若成功取得元组则返回真;若不再有匹配元组则返回假。在返回真时,元组的 TID 会存入 scan 结构体中。请注意,成功仅表示索引中存在一个匹配扫描键的条目,并不表示该元组一定仍然存在于堆中,或者一定能通过调用者的快照测试。成功时,amgettuple 还必须把 scan->xs_recheck 设为真或假。假表示可以确定该索引条目匹配扫描键;真表示这一点并不确定,因此在取到堆元组后必须根据扫描键所代表的条件重新检查它。这一机制支持有损索引操作符。请注意,重检只针对扫描条件;部分索引谓词(如果有)永远不会由 amgettuple 的调用者重新检查。 - 如果索引支持 仅索引扫描(即其任一列上 amcanreturn 返回真),那么成功时 AM 还必须检查 scan->xs_want_itup;若其为真,就必须返回该索引条目的原始被索引数据。对于 amcanreturn 返回假的列,可以把其值作为 NULL 返回。数据可以通过以下两种形式之一返回:一种是把 IndexTuple 指针存入 scan->xs_itup,其元组描述符为 scan->xs_itupdesc;另一种是把 HeapTuple 指针存入 scan->xs_hitup,其元组描述符为 scan->xs_hitupdesc。(当重建出的数据可能装不进 IndexTuple 时,应使用后一种格式。)无论采用哪种形式,指针所引用数据的管理责任都在访问方法一侧。对这份数据的有效性必须至少保持到该扫描下一次调用 amgettupleamrescanamendscan 为止。 + 如果索引支持 仅索引扫描(即其至少一列上 amcanreturn 返回真),那么成功时 AM 还必须检查 scan->xs_want_itup;若其为真,就必须返回该索引条目的原始被索引数据。对于 amcanreturn 返回假的列,可以把其值作为 NULL 返回。数据可以通过以下两种形式之一返回:一种是把 IndexTuple 指针存入 scan->xs_itup,其元组描述符为 scan->xs_itupdesc;另一种是把 HeapTuple 指针存入 scan->xs_hitup,其元组描述符为 scan->xs_hitupdesc。(当重建出的数据可能装不进 IndexTuple 时,应使用后一种格式。)无论采用哪种形式,指针所引用数据的管理责任都在访问方法一侧。这份数据必须至少保持有效,直到该扫描下一次调用 amgettupleamrescanamendscan @@ -377,7 +376,7 @@ int64 amgetbitmap (IndexScanDesc scan, TIDBitmap *tbm); - 取出给定扫描中的所有元组,并将其加入调用者提供的 TIDBitmap 中(也就是把这组元组 ID 与位图中已有的集合做 OR)。返回值是取得的元组数量(这可能只是近似计数,例如某些 AM 不会检测重复项)。在把元组 ID 插入位图时,amgetbitmap 可以指出某些具体的元组 ID 需要重新检查扫描条件。这类似于 amgettuplexs_recheck 输出参数。注意:在当前实现中,对这一特性的支持与位图自身的有损存储支持混在一起,因此调用者会对可重检元组同时重新检查扫描条件和部分索引谓词(如果有)。不过,这并不一定永远如此。amgetbitmapamgettuple 不能在同一次索引扫描中同时使用;使用 amgetbitmap 时还有其他限制,详见 。 + 取出给定扫描中的所有元组,并将其加入调用者提供的 TIDBitmap 中(也就是把这组元组 ID 与位图中已有的集合做 OR)。返回值是取得的元组数量(这可能只是近似计数,例如某些 AM 不会检测重复项)。在把元组 ID 插入位图时,amgetbitmap 可以指出某些具体的元组 ID 需要重新检查扫描条件。这类似于 amgettuplexs_recheck 输出参数。注意:在当前实现中,对这一特性的支持与位图自身的有损存储支持混在一起,因此调用者会对需要重检的元组同时重新检查扫描条件和部分索引谓词(如果有)。不过,这并不一定永远如此。amgetbitmapamgettuple 不能在同一次索引扫描中同时使用;使用 amgetbitmap 时还有其他限制,详见 @@ -389,7 +388,7 @@ amgetbitmap (IndexScanDesc scan, void amendscan (IndexScanDesc scan); - 结束一次扫描并释放资源。scan 结构体本身不应被释放,但访问方法内部获取的任何锁或 pin,以及由 ambeginscan 和其他扫描相关函数分配的其他内存,都必须被释放。 + 结束一次扫描并释放资源。scan 结构体本身不应被释放,但必须释放访问方法内部获取的所有锁、解除所有钉住状态,并释放由 ambeginscan 和其他扫描相关函数分配的其他内存。 @@ -524,7 +523,7 @@ amtranslatecmptype (CompareType cmptype, Oid opfamily, Oid opcintype); - 除了使用 amgettuple 外,索引扫描也可以使用 amgetbitmap,在一次调用中取出所有元组。与 amgettuple 相比,这通常明显更高效,因为它可以避免访问方法内部的反复加锁和解锁。原则上,amgetbitmap 应具有与重复调用 amgettuple 相同的效果,但为了简化实现,我们施加了若干限制。首先,amgetbitmap 一次性返回全部元组,因此不支持标记或恢复扫描位置。其次,元组是通过一个位图返回的,没有特定顺序,这也是为什么 amgetbitmap 不带 direction 参数的原因。(这种扫描也永远不会提供排序操作符。)此外,使用 amgetbitmap 时也没有仅索引扫描的支持,因为没有办法返回索引元组的内容。最后,amgetbitmap 不保证对返回的元组做任何锁定,其影响见 。 + 除了使用 amgettuple 外,索引扫描也可以使用 amgetbitmap,在一次调用中取出所有元组。与 amgettuple 相比,这可能明显更高效,因为它可以避免访问方法内部的反复加锁和解锁。原则上,amgetbitmap 应具有与重复调用 amgettuple 相同的效果,但为了简化实现,我们施加了若干限制。首先,amgetbitmap 一次性返回全部元组,因此不支持标记或恢复扫描位置。其次,元组是通过一个位图返回的,没有特定顺序,这也是为什么 amgetbitmap 不带 direction 参数的原因。(这种扫描也永远不会提供排序操作符。)此外,使用 amgetbitmap 时也没有仅索引扫描的支持,因为没有办法返回索引元组的内容。最后,amgetbitmap 不保证对返回的元组做任何锁定,其影响见 @@ -541,7 +540,7 @@ amtranslatecmptype (CompareType cmptype, Oid opfamily, Oid opcintype); - 构建一种支持并发更新的索引类型,通常需要对所需行为进行大量而细致的分析。对于 B-树和哈希索引类型,可以阅读 src/backend/access/nbtree/READMEsrc/backend/access/hash/README 中涉及的设计决策。 + 构建一种支持并发更新的索引类型,通常需要对所需行为进行大量而细致的分析。对于 B-树和 hash 索引类型,可以阅读 src/backend/access/nbtree/READMEsrc/backend/access/hash/README 中涉及的设计决策。 @@ -560,12 +559,12 @@ amtranslatecmptype (CompareType cmptype, Oid opfamily, Oid opcintype); - 索引扫描必须在保存 amgettuple 最近一次返回条目的索引页面上维护一个 pin,而 ambulkdelete 不能从被其他后端钉住的页面中删除条目。下面会解释为什么需要这条规则。 + 索引扫描必须在保存 amgettuple 最近一次返回条目的索引页面上保持钉住状态,而 ambulkdelete 不能从被其他后端钉住的页面中删除条目。下面会解释为什么需要这条规则。 - 如果没有第三条规则,索引读取者就有可能在某个索引条目被 VACUUM 删除之前先看到它,然后在对应的堆条目已被 VACUUM 删除之后才到达那里。如果读取者到达时,该项号仍未被重新使用,就不会造成严重问题,因为空项槽位会被 heap_fetch() 忽略。但如果第三个后端已经把这个项槽位重新用作别的东西呢?在使用 MVCC 兼容快照时不会有问题,因为该槽位的新占用者一定太新,无法通过快照测试。然而,对于非 MVCC 兼容的快照(例如 SnapshotAny),就可能错误地接受并返回一行实际上并不匹配扫描键的数据。我们可以要求在所有情况下都对堆行重新检查扫描键,以防范这种情形,但那样代价太高。于是,我们改为把索引页面上的 pin 作为一种代理,表示读取者可能仍处于从索引条目前往匹配堆条目的飞行中。让 ambulkdelete 在这种 pin 上阻塞,能够保证 VACUUM 不会在读取者处理完之前删除对应的堆条目。这种方案运行时开销很小,只有在真正发生冲突的少数情况下才会增加阻塞开销。 + 如果没有第三条规则,索引读取者就有可能在某个索引条目被 VACUUM 删除之前先看到它,然后在对应的堆条目已被 VACUUM 删除之后才到达那里。如果读取者到达时,该项号仍未被重新使用,就不会造成严重问题,因为空项槽位会被 heap_fetch() 忽略。但如果第三个后端已经把这个项槽位重新用作别的东西呢?在使用 MVCC 兼容快照时不会有问题,因为该槽位的新占用者一定太新,无法通过快照测试。然而,对于非 MVCC 兼容的快照(例如 SnapshotAny),就可能错误地接受并返回一行实际上并不匹配扫描键的数据。我们可以要求在所有情况下都对堆行重新检查扫描键,以防范这种情形,但那样代价太高。于是,我们改为把索引页面的钉住状态作为一种代理,表示读取者从索引条目到匹配堆条目的访问过程可能仍在进行中。让 ambulkdelete 因这种钉住状态而阻塞,能够保证 VACUUM 不会在读取者处理完之前删除对应的堆条目。这种方案运行时开销很小,只有在真正发生冲突的少数情况下才会增加阻塞开销。 @@ -573,7 +572,7 @@ amtranslatecmptype (CompareType cmptype, Oid opfamily, Oid opcintype); - 在 amgetbitmap 索引扫描中,访问方法不会在任何返回的元组上保留索引 pin。因此,只有把这种扫描与 MVCC 兼容的快照一起使用才是安全的。 + 在 amgetbitmap 索引扫描中,访问方法不会为任何返回的元组保持索引页面的钉住状态。因此,只有把这种扫描与 MVCC 兼容的快照一起使用才是安全的。 @@ -612,7 +611,7 @@ amtranslatecmptype (CompareType cmptype, Oid opfamily, Oid opcintype); - 此外,在按照上述规则报告唯一性违背之前,访问方法必须立即重新检查正在插入那一行的存活性。如果它已经是提交后死亡的状态,就不应报告违背。(这种情况不会出现在插入由当前事务刚创建的行这一普通场景中,但在 CREATE UNIQUE INDEX CONCURRENTLY 期间却可能发生。) + 此外,就在按照上述规则报告唯一性违背之前,访问方法必须重新检查正在插入那一行的存活性。如果它已经是提交后死亡的状态,就不应报告违背。(这种情况不会出现在插入由当前事务刚创建的行这一普通场景中,但在 CREATE UNIQUE INDEX CONCURRENTLY 期间却可能发生。) @@ -620,7 +619,7 @@ amtranslatecmptype (CompareType cmptype, Oid opfamily, Oid opcintype); - 如果唯一约束是可延迟的,情况会更复杂:我们需要能够为新行插入一个索引条目,但把任何唯一性违背错误延迟到语句结束时甚至更晚才报告。为了避免对索引进行不必要的重复搜索,索引访问方法应在初始插入期间执行一次初步唯一性检查。如果这表明确实不存在冲突的存活元组,那么事情就结束了。否则,我们会安排在真正强制约束时再做一次重检。若在重检时,插入的元组与另外某个具有相同键值的元组都仍然存活,就必须报告错误。(注意,就此用途而言,存活实际上是指索引条目 HOT 链中的任一元组是存活的。)为实现这一点,传给 aminsert 函数的 checkUnique 参数会取以下值之一: + 如果唯一约束是可延迟的,情况会更复杂:我们需要能够为新行插入一个索引条目,但把任何唯一性违背错误延迟到语句结束时甚至更晚才报告。为了避免对索引进行不必要的重复搜索,索引访问方法应在初始插入期间执行一次初步唯一性检查。如果这表明确实不存在冲突的存活元组,那么事情就结束了。否则,我们会安排在真正强制约束时再做一次重检。若在重检时,插入的元组与另外某个具有相同键值的元组都仍然存活,就必须报告错误。(注意,就此用途而言,存活实际上是指索引条目 HOT 链中至少有一个元组是存活的。)为实现这一点,传给 aminsert 函数的 checkUnique 参数会取以下值之一: @@ -657,10 +656,10 @@ amtranslatecmptype (CompareType cmptype, Oid opfamily, Oid opcintype); - 索引开销估计函数 + 索引代价估算函数 - amcostestimate 函数会收到描述某种可能索引扫描方式的信息,其中包括已经确定可用于该索引的 WHERE 子句和 ORDER BY 子句列表。它必须返回访问该索引的开销估计,以及 WHERE 子句的选择率(也就是在索引扫描期间将从父表中检索出的行所占比例)。对于简单情况,开销估计器几乎所有工作都可以通过调用优化器中的标准例程来完成;之所以提供 amcostestimate 函数,是为了让索引访问方法能够提供与索引类型有关的专门知识,以便在可能时改进标准估计。 + amcostestimate 函数会收到描述某种可能索引扫描方式的信息,其中包括已经确定可用于该索引的 WHERE 子句和 ORDER BY 子句列表。它必须返回访问该索引的代价估算,以及 WHERE 子句选择率的估计值(也就是在索引扫描期间将从父表中检索出的行所占比例)。对于简单情况,代价估算器几乎所有工作都可以通过调用优化器中的标准例程来完成;之所以提供 amcostestimate 函数,是为了让索引访问方法能够提供与索引类型有关的专门知识,以便在可能时改进标准估计。 @@ -694,7 +693,7 @@ amcostestimate (PlannerInfo *root, path - 当前正在考虑的索引访问路径。除开销和选择率字段外,其余字段都有效。 + 当前正在考虑的索引访问路径。除代价和选择率字段外,其余字段都有效。 @@ -703,7 +702,7 @@ amcostestimate (PlannerInfo *root, loop_count - 在开销估计中应计入的索引扫描重复次数。当考虑在嵌套循环连接内部使用参数化扫描时,这个参数通常会大于 1。请注意,开销估计仍应只针对一次扫描;更大的 loop_count 只表示可以适当考虑多次扫描之间的一些缓存效应。 + 在代价估算中应计入的索引扫描重复次数。当考虑在嵌套循环连接内部使用参数化扫描时,这个参数通常会大于 1。请注意,代价估算仍应只针对一次扫描;更大的 loop_count 只表示可以适当考虑多次扫描之间的一些缓存效应。 @@ -718,7 +717,7 @@ amcostestimate (PlannerInfo *root, *indexStartupCost - 设为索引启动处理的开销。 + 设为索引启动处理的代价。 @@ -727,7 +726,7 @@ amcostestimate (PlannerInfo *root, *indexTotalCost - 设为索引处理的总开销。 + 设为索引处理的总代价。 @@ -762,19 +761,19 @@ amcostestimate (PlannerInfo *root, - 请注意,开销估计函数必须用 C 编写,而不能用 SQL 或任何可用的过程语言,因为它们必须访问规划器/优化器的内部数据结构。 + 请注意,代价估算函数必须用 C 编写,而不能用 SQL 或任何可用的过程语言,因为它们必须访问规划器/优化器的内部数据结构。 - 索引访问开销应使用 src/backend/optimizer/path/costsize.c 所采用的参数来计算:顺序磁盘块读取的开销为 seq_page_cost,非顺序读取的开销为 random_page_cost,处理一条索引行的开销通常应取为 cpu_index_tuple_cost。此外,在索引处理期间调用的任何比较操作符(特别是对 indexquals 本身的求值)都应计入适当倍数的 cpu_operator_cost。 + 索引访问代价应使用 src/backend/optimizer/path/costsize.c 所采用的参数来计算:顺序磁盘块读取的代价为 seq_page_cost,非顺序读取的代价为 random_page_cost,处理一条索引行的代价通常应取为 cpu_index_tuple_cost。此外,在索引处理期间调用的任何比较操作符(特别是对 indexquals 本身的求值)都应计入适当倍数的 cpu_operator_cost - 访问开销应包括与扫描索引本身有关的全部磁盘和 CPU 开销,但包括取出或处理由索引标识出的父表行的开销。 + 访问代价应包括与扫描索引本身有关的全部磁盘和 CPU 代价,但包括取出或处理由索引标识出的父表行的代价。 - 启动开销是整个扫描总开销中必须在开始取第一行之前先付出的那一部分。对大多数索引来说,这可以视为零;但启动开销较高的索引类型可能希望把它设为非零。 + 启动代价是整个扫描总代价中必须在开始取第一行之前先付出的那一部分。对大多数索引来说,这可以视为零;但启动代价较高的索引类型可能希望把它设为非零。 @@ -782,7 +781,7 @@ amcostestimate (PlannerInfo *root, - indexCorrelation 应设为索引顺序与表顺序之间的相关性(范围从 -1.0 到 1.0)。该值用于调整从父表取行开销的估计。 + indexCorrelation 应设为索引顺序与表顺序之间的相关性(范围从 -1.0 到 1.0)。该值用于调整从父表取行代价的估计。 @@ -794,9 +793,9 @@ amcostestimate (PlannerInfo *root, - 开销估计 + 代价估算 - 一个典型的开销估计器会按如下步骤进行: + 一个典型的代价估算器会按如下步骤进行: @@ -825,14 +824,14 @@ amcostestimate (PlannerInfo *root, - 计算索引访问开销。一个通用估计器可能会这样做: + 计算索引访问代价。一个通用估计器可能会这样做: /* - * Our generic assumption is that the index pages will be read - * sequentially, so they cost seq_page_cost each, not random_page_cost. - * Also, we charge for evaluation of the indexquals at each index row. - * All the costs are assumed to be paid incrementally during the scan. + * 通用假设是索引页面将按顺序读取, + * 因此每页代价为 seq_page_cost,而非 random_page_cost。 + * 此外,还要计入在每个索引行上对 indexquals 求值的代价。 + * 假定所有代价都在扫描过程中逐步付出。 */ cost_qual_eval(&index_qual_cost, path->indexquals, root); *indexStartupCost = index_qual_cost.startup; @@ -852,7 +851,7 @@ cost_qual_eval(&index_qual_cost, path->indexquals, root); - 开销估计器函数的示例可在 src/backend/utils/adt/selfuncs.c 中找到。 + 代价估算器函数的示例可在 src/backend/utils/adt/selfuncs.c 中找到。 diff --git a/zh/18/indices.sgml b/zh/18/indices.sgml index 84fbb8ac..a5782c8a 100644 --- a/zh/18/indices.sgml +++ b/zh/18/indices.sgml @@ -31,7 +31,7 @@ SELECT content FROM test1 WHERE id = constant; - 大多数非小说类书籍也采用了类似的方法:读者经常查找的术语和概念会被收集到书末按字母顺序排列的索引中。感兴趣的读者可以相对快速地浏览索引并翻到相应页面,而不必通读整本书才能找到自己感兴趣的内容。正如作者需要预判读者可能查找哪些条目一样,数据库程序员也需要预见哪些索引会有用。 + 大多数非虚构类书籍也采用了类似的方法:读者经常查找的术语和概念会被收集到书末按字母顺序排列的索引中。感兴趣的读者可以相对快速地浏览索引并翻到相应页面,而不必通读整本书才能找到自己感兴趣的内容。正如作者需要预判读者可能查找哪些条目一样,数据库程序员也需要预见哪些索引会有用。 @@ -71,7 +71,7 @@ CREATE INDEX test1_id_index ON test1 (id); comparison-value operator indexed-column - 那么如果原始operator有一个可交换操作符,并且该操作符属于该索引的操作符类,就可以把它翻转成可索引的形式。 + 那么如果原始operator有一个交换子操作符,并且该操作符属于该索引的操作符类,就可以把它翻转成可索引的形式。 @@ -100,12 +100,12 @@ CREATE INDEX name ON table B-树 - index + 索引 B-树 B-树 - index + 索引 @@ -133,12 +133,12 @@ CREATE INDEX name ON table Hash - index + 索引 hash hash - index + 索引 @@ -154,12 +154,12 @@ CREATE INDEX name ON table GiST - index + 索引 GiST GiST - index + 索引 @@ -178,7 +178,7 @@ CREATE INDEX name ON table SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10; ]]> - 这会找出距离给定目标点最近的十个地点。是否能做到这一点,同样取决于所使用的具体操作符类。在中,可以按这种方式使用的操作符列在Ordering Operators这一列中。 + 这会找出距离给定目标点最近的十个地点。是否能做到这一点,同样取决于所使用的具体操作符类。在中,可以按这种方式使用的操作符列在排序操作符这一列中。 @@ -186,12 +186,12 @@ SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10; SP-GiST - index + 索引 SP-GiST SP-GiST - index + 索引 @@ -205,7 +205,7 @@ SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10; - 与 GiST 一样,SP-GiST 支持最近邻搜索。对于支持距离排序的 SP-GiST 操作符类,相应操作符列在Ordering Operators列中。 + 与 GiST 一样,SP-GiST 支持最近邻搜索。对于支持距离排序的 SP-GiST 操作符类,相应操作符列在排序操作符列中。 @@ -213,12 +213,12 @@ SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10; GIN - index + 索引 GIN GIN - index + 索引 @@ -240,12 +240,12 @@ SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10; BRIN - index + 索引 BRIN BRIN - index + 索引 @@ -265,8 +265,8 @@ SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10; 多列索引 - index - multicolumn + 索引 + 多列 @@ -293,7 +293,7 @@ CREATE INDEX test2_mm_idx ON test2 (major, minor); - 多列 B-树索引可以用于涉及索引任意列子集的查询条件,但当对前导(最左)列存在约束时,索引效率最高。精确的规则是:对前导列的等值约束,再加上第一个没有等值约束列上的任意不等约束,总会被用来限制被扫描的索引范围。这些列右侧列上的约束会在索引中进行检查,因此总能减少访问表本体的次数,但不一定会减少必须扫描的索引范围。如果 B-树索引扫描能够有效应用跳过扫描优化,那么它在通过反复的索引搜索遍历索引时,会利用每一列约束。这可能减少需要读取的索引部分,即便一个或多个列(位于查询谓词中最低有效索引列之前)缺少常规的等值约束。跳过扫描的工作方式是内部生成一个动态的等值约束,使其匹配索引列中的每个可能值(不过这只适用于某个列缺少来自查询谓词的等值约束,且生成的约束能够与查询谓词中较后列的约束联合使用时)。 + 多列 B-树索引可以用于涉及索引任意列子集的查询条件,但当对前导(最左)列存在约束时,索引效率最高。精确的规则是:对前导列的等值约束,再加上第一个没有等值约束列上的任意不等约束,总会被用来限制被扫描的索引范围。这些列右侧列上的约束会在索引中进行检查,因此总能减少访问表本体的次数,但不一定会减少必须扫描的索引范围。如果 B-树索引扫描能够有效应用跳过扫描优化,那么它在通过反复的索引搜索遍历索引时,会利用每一列约束。这可能减少需要读取的索引部分,即便一个或多个列(位于查询谓词所涉及的最右侧索引列之前)缺少常规的等值约束。跳过扫描的工作方式是内部生成一个动态的等值约束,使其匹配索引列中的每个可能值(不过这只适用于某个列缺少来自查询谓词的等值约束,且生成的约束能够与查询谓词中较后列的约束联合使用时)。 @@ -309,11 +309,11 @@ CREATE INDEX test2_mm_idx ON test2 (major, minor); - 多列 GIN 索引可以用于涉及索引任意列子集的查询条件。与 B-树或 GiST 不同,无论查询条件使用的是哪一列索引列,GIN 的索引搜索效果都一样。 + 多列 GIN 索引可以用于涉及索引任意列子集的查询条件。与 B-树或 GiST 不同,无论查询条件使用的是哪些索引列,GIN 的索引搜索效果都一样。 - 多列 BRIN 索引可以用于涉及索引任意列子集的查询条件。和 GIN 一样、不同于 B-树或 GiST,无论查询条件使用的是哪一列索引列,索引搜索效果都一样。在单个表上使用多个 BRIN 索引,而不是使用一个多列 BRIN 索引的唯一理由,是需要不同的pages_per_range存储参数。 + 多列 BRIN 索引可以用于涉及索引任意列子集的查询条件。和 GIN 一样、不同于 B-树或 GiST,无论查询条件使用的是哪些索引列,索引搜索效果都一样。在单个表上使用多个 BRIN 索引,而不是使用一个多列 BRIN 索引的唯一理由,是需要不同的pages_per_range存储参数。 @@ -330,8 +330,8 @@ CREATE INDEX test2_mm_idx ON test2 (major, minor); 索引和<literal>ORDER BY</literal> - index - and ORDER BY + 索引 + ORDER BY @@ -339,7 +339,7 @@ CREATE INDEX test2_mm_idx ON test2 (major, minor); - 规划器在满足ORDER BY要求时,会考虑两种方案:扫描一个与该要求匹配的可用索引,或者按物理顺序扫描表再显式排序。对于需要扫描表中很大一部分内容的查询,显式排序通常会比使用索引更快,因为它遵循顺序访问模式,需要的磁盘 I/O 更少。只有在只需取出少量行时,索引才更有价值。一个重要的特例是ORDER BYLIMIT n组合使用:显式排序必须处理所有数据才能找出最前面的n行,而如果有一个与ORDER BY匹配的索引,就可以直接取回前n行,而完全不必扫描剩余数据。 + 规划器在满足ORDER BY要求时,会考虑两种方案:扫描一个与该要求匹配的可用索引,或者按物理顺序扫描表再显式排序。对于需要扫描表中很大一部分内容的查询,显式排序通常会比使用索引更快,因为它遵循顺序访问模式,需要的磁盘 I/O 更少。只需取出少量行时,索引更有价值。一个重要的特例是ORDER BYLIMIT n组合使用:显式排序必须处理所有数据才能找出最前面的n行,而如果有一个与ORDER BY匹配的索引,就可以直接取回前n行,而完全不必扫描剩余数据。 @@ -369,12 +369,12 @@ CREATE INDEX test3_desc_index ON test3 (id DESC NULLS LAST); 组合多个索引 - index - combining multiple indexes + 索引 + 组合多个索引 - bitmap scan + 位图扫描 @@ -391,7 +391,7 @@ CREATE INDEX test3_desc_index ON test3 (id DESC NULLS LAST); - 除了最简单的应用之外,通常会有多种可能有用的索引组合,数据库开发者必须权衡决定提供哪些索引。有时多列索引最好,但有时创建独立索引并依赖索引组合功能会更合适。例如,如果你的工作负载包含一组查询:有时只涉及列x,有时只涉及列y,有时同时涉及两列,那么你可以选择分别在xy上创建两个独立索引,并依赖索引组合来处理同时使用两列的查询。你也可以创建一个(x, y)上的多列索引。对于同时涉及两列的查询,这个索引通常会比索引组合更高效,但正如中所讨论的,它对于只涉及y的查询就没那么有用了。具体能有多大用处,取决于 B-树索引跳过扫描优化的效果;如果x的非重复值不超过几百个,跳过扫描会让针对特定y值的搜索仍然具有相当不错的效率。再加上一个(x, y)上的多列索引和一个单独的y索引,也可能工作得相当好。对于只涉及x的查询,多列索引也可以使用,但它会比单独的x索引更大,因此更慢。最后一种选择是同时创建这三个索引,但这大概只有在该表被搜索的频率远高于被更新的频率,并且三类查询都很常见时才合理。如果其中一种查询远没有另外两种常见,那么你大概只需创建最适合常见查询类型的两个索引即可。 + 除了最简单的应用之外,通常会有多种可能有用的索引组合,数据库开发者必须权衡决定提供哪些索引。有时多列索引最好,但有时创建独立索引并依赖索引组合功能会更合适。例如,如果你的工作负载包含一组查询:有时只涉及列x,有时只涉及列y,有时同时涉及两列,那么你可以选择分别在xy上创建两个独立索引,并依赖索引组合来处理同时使用两列的查询。你也可以创建一个(x, y)上的多列索引。对于同时涉及两列的查询,这个索引通常会比索引组合更高效,但正如中所讨论的,它对于只涉及y的查询就没那么有用了。具体能有多大用处,取决于 B-树索引跳过扫描优化的效果;如果x的非重复值不超过几百个,跳过扫描会让针对特定y值的搜索仍然具有相当不错的效率。将一个(x, y)上的多列索引和一个单独的y索引组合使用,也可能工作得相当好。对于只涉及x的查询,多列索引也可以使用,但它会比单独的x索引更大,因此更慢。最后一种选择是同时创建这三个索引,但这大概只有在该表被搜索的频率远高于被更新的频率,并且三类查询都很常见时才合理。如果其中一种查询远没有另外两种常见,那么你大概只需创建最适合常见查询类型的两个索引即可。 @@ -401,8 +401,8 @@ CREATE INDEX test3_desc_index ON test3 (id DESC NULLS LAST); 唯一索引 - index - unique + 索引 + 唯一 @@ -433,8 +433,8 @@ CREATE UNIQUE INDEX name ON table表达式索引 - index - on expressions + 索引 + 基于表达式 @@ -481,8 +481,8 @@ CREATE INDEX people_names ON people ((first_name || ' ' || last_name)); 部分索引 - index - partial + 索引 + 部分 @@ -490,7 +490,7 @@ CREATE INDEX people_names ON people ((first_name || ' ' || last_name)); - 使用部分索引的一个主要原因是避免索引常见值。由于搜索常见值的查询(即占全部表行百分之几以上的值)反正也不会使用索引,因此完全没有必要把这些行保留在索引里。这会减小索引尺寸,从而加快那些确实会使用该索引的查询。它也会加快很多表更新操作,因为索引并不需要在所有情况下都更新。展示了这种思路的一种可能应用。 + 使用部分索引的一个主要原因是避免索引常见值。由于搜索常见值(即占全部表行百分之几以上的值)的查询反正也不会使用索引,因此完全没有必要把这些行保留在索引里。这会减小索引尺寸,从而加快那些确实会使用该索引的查询。它也会加快很多表更新操作,因为索引并不需要在所有情况下都更新。展示了这种思路的一种可能应用。 @@ -578,7 +578,7 @@ SELECT * FROM orders WHERE order_nr = 3501; - 也说明了:索引列和谓词中使用的列不必一致。PostgreSQL支持带任意谓词的部分索引,只要其中只涉及正在建立索引的那张表的列。不过要记住,谓词必须与那些希望从该索引受益的查询中使用的条件相匹配。更准确地说,只有当系统能够识别出查询的WHERE条件在数学上蕴含该索引的谓词时,部分索引才能用于该查询。PostgreSQL并没有一个复杂的定理证明器,来识别那些写法不同但数学上等价的表达式。(不仅构建这样一个通用定理证明器极其困难,而且它很可能也会慢到失去实际用途。)系统可以识别简单的不等式蕴含,例如x < 1蕴含x < 2;否则,谓词条件必须与查询WHERE条件的某一部分完全匹配,否则索引不会被识别为可用。匹配发生在查询规划阶段,而不是运行时。因此,参数化查询子句无法与部分索引配合工作。例如,一个带参数的预备查询可能写成x < ?,而对于参数的所有可能取值,它都不可能蕴含x < 2。 + 也说明了:索引列和谓词中使用的列不必一致。PostgreSQL支持带任意谓词的部分索引,只要其中只涉及正在建立索引的那张表的列。不过要记住,谓词必须与那些希望从该索引受益的查询中使用的条件相匹配。更准确地说,只有当系统能够识别出查询的WHERE条件在数学上蕴含该索引的谓词时,部分索引才能用于该查询。PostgreSQL并没有一个复杂的定理证明器,来识别那些写法不同但数学上等价的表达式。(不仅构建这样一个通用定理证明器极其困难,而且它很可能也会慢到失去实际用途。)系统可以识别简单的不等式蕴含,例如x < 1蕴含x < 2;否则,谓词条件必须与查询WHERE条件的某一部分完全匹配,否则索引不会被识别为可用。匹配发生在查询规划阶段,而不是运行时。因此,参数化查询子句无法与部分索引配合工作。例如,一个带参数的预备查询可能写成x < ?,而它无法保证在参数的所有可能取值下都蕴含x < 2 @@ -590,7 +590,7 @@ SELECT * FROM orders WHERE order_nr = 3501; 建立一个部分唯一索引 - 假设我们有一张描述测试结果的表。我们希望确保对于给定的subjecttarget组合,只有一条成功记录,但可以有任意多条失败记录。实现方法之一如下: + 假设我们有一张描述测试结果的表。我们希望确保对于给定的测试对象和目标组合,只有一条成功记录,但可以有任意多条失败记录。实现方法之一如下: CREATE TABLE tests ( subject text, @@ -671,7 +671,7 @@ CREATE INDEX mytable_cat_data ON mytable (category, data); - PostgreSQL中的所有索引都是二级索引,也就是说,每个索引都与表的主数据区分开存储(在PostgreSQL术语中,这个主数据区称为表的)。这意味着,在普通索引扫描中,每次取回一行都需要同时从索引和堆中取数据。此外,尽管满足某个可索引WHERE条件的索引项通常在索引中彼此接近,但它们引用的表行却可能分布在堆中的任何位置。因此,索引扫描的堆访问部分会涉及大量对堆的随机访问,这可能很慢,尤其是在传统旋转介质上。(正如中所述,位图扫描试图通过按排序顺序进行堆访问来缓解这项成本,但那也只能缓解到一定程度。) + PostgreSQL中的所有索引都是二级索引,也就是说,每个索引都与表的主数据区分开存储(在PostgreSQL术语中,这个主数据区称为表的)。这意味着,在普通索引扫描中,每次取回一行都需要同时从索引和堆中取数据。此外,尽管满足某个可索引WHERE条件的索引项通常在索引中彼此接近,但它们引用的表行却可能分布在堆中的任何位置。因此,索引扫描的堆访问部分会涉及大量对堆的随机访问,这可能很慢,尤其是在传统旋转介质上。(正如中所述,位图扫描试图通过按排序顺序进行堆访问来缓解这项代价,但那也只能缓解到一定程度。) @@ -686,7 +686,7 @@ CREATE INDEX mytable_cat_data ON mytable (category, data); - 查询只能引用存储在索引中的列。例如,给定一个表,它有列xyz,而索引建立在xy上,那么下面这些查询可以使用仅索引扫描: + 查询只能引用存储在索引中的列。例如,假设某个表的xy列上有一个索引,且该表还有一列z,那么下面这些查询可以使用仅索引扫描: SELECT x, y FROM tab WHERE x = 'key'; SELECT x FROM tab WHERE x = 'key' AND y < 42; @@ -713,7 +713,7 @@ SELECT x FROM tab WHERE x = 'key' AND z < 42; INCLUDE - in index definitions + 在索引定义中 为了有效利用仅索引扫描特性,你可以选择创建一个覆盖索引,也就是专门设计来包含某一类高频查询所需列的索引。由于查询通常需要取回的列不止是用于搜索的那些列,PostgreSQL允许你创建一种索引,其中某些列只是负载,而不是搜索键的一部分。这是通过添加一个INCLUDE子句列出这些额外列来实现的。例如,如果你经常运行如下查询: @@ -735,7 +735,7 @@ CREATE UNIQUE INDEX tab_x_y ON tab(x) INCLUDE (y); - 向索引中添加非键负载列时,明智的做法是保持保守,尤其是宽列。如果某个索引元组超过该索引类型允许的最大尺寸,数据插入就会失败。无论如何,非键列都会复制索引对应表中的数据并让索引膨胀,因此可能拖慢搜索。另外请记住,除非表变化足够缓慢,以至于仅索引扫描很可能无需访问堆,否则把负载列包含在索引中并没有太大意义。如果反正必须访问堆元组,那么顺便从那里取出该列的值也不会增加额外成本。其他限制包括:当前不支持把表达式作为包含列;并且当前只有 B-树、GiST 和 SP-GiST 索引支持包含列。 + 向索引中添加非键负载列时,明智的做法是保持保守,尤其是宽列。如果某个索引元组超过该索引类型允许的最大尺寸,数据插入就会失败。无论如何,非键列都会复制索引对应表中的数据并让索引膨胀,因此可能拖慢搜索。另外请记住,除非表变化足够缓慢,以至于仅索引扫描很可能无需访问堆,否则把负载列包含在索引中并没有太大意义。如果反正必须访问堆元组,那么顺便从那里取出该列的值也不会增加额外代价。其他限制包括:当前不支持把表达式作为包含列;并且当前只有 B-树、GiST 和 SP-GiST 索引支持包含列。 @@ -781,11 +781,11 @@ SELECT target FROM tests WHERE subject = 'some-subject' AND success; 操作符类和操作符族 - operator class + 操作符类 - operator family + 操作符族 @@ -903,8 +903,8 @@ CREATE INDEX test1c_content_y_index ON test1c (content COLLATE "y"); 检查索引使用情况 - index - examining usage + 索引 + 检查使用情况 diff --git a/zh/18/information_schema.sgml b/zh/18/information_schema.sgml index a8e671c1..0b783605 100644 --- a/zh/18/information_schema.sgml +++ b/zh/18/information_schema.sgml @@ -388,7 +388,7 @@ collation_catalog sql_identifier - 包含此属性排序规则的数据库名(总是当前数据库),如果默认或者该属性的数据类型不可排序则为空 + 包含该属性排序规则的数据库名称(总是当前数据库);如果使用默认排序规则,或该属性的数据类型不支持排序规则,则为 null。 @@ -397,7 +397,7 @@ collation_schema sql_identifier - 包含此属性排序规则的模式名,如果默认或者该属性的数据类型不可排序则为空 + 包含该属性排序规则的模式名称;如果使用默认排序规则,或该属性的数据类型不支持排序规则,则为 null。 @@ -406,7 +406,7 @@ collation_name sql_identifier - 该属性排序规则的名称,如果默认或者该属性的数据类型不可排序则为空 + 该属性排序规则的名称;如果使用默认排序规则,或该属性的数据类型不支持排序规则,则为 null。 @@ -1626,7 +1626,7 @@ collation_catalog sql_identifier - 包含此属性排序规则的数据库名(总是当前数据库),如果默认或者该属性的数据类型不可排序则为空 + 包含该列排序规则的数据库名称(总是当前数据库);如果使用默认排序规则,或该列的数据类型不支持排序规则,则为 null。 @@ -1635,7 +1635,7 @@ collation_schema sql_identifier - 该列的包含排序规则的模式名,如果默认或者该列的数据类型不可排序则为空 + 包含该列排序规则的模式名称;如果使用默认排序规则,或该列的数据类型不支持排序规则,则为 null。 @@ -1644,7 +1644,7 @@ collation_name sql_identifier - 该列的排序规则的名称,如果默认或者该列的数据类型不可排序则为空 + 该列排序规则的名称;如果使用默认排序规则,或该列的数据类型不支持排序规则,则为 null。 @@ -2385,7 +2385,7 @@ collation_catalog sql_identifier - 包含此域排序规则的数据库名(总是当前数据库),如果默认或者该域的数据类型不可排序则为空 + 包含该域排序规则的数据库名称(总是当前数据库);如果使用默认排序规则,或该域的数据类型不支持排序规则,则为 null。 @@ -2394,7 +2394,7 @@ collation_schema sql_identifier - 包含此域排序规则的模式名,如果默认或者该域的数据类型不可排序则为空 + 包含该域排序规则的模式名称;如果使用默认排序规则,或该域的数据类型不支持排序规则,则为 null。 @@ -2403,7 +2403,7 @@ collation_name sql_identifier - 该域排序规则的名称,如果默认或者该域的数据类型不可排序则为空 + 该域排序规则的名称;如果使用默认排序规则,或该域的数据类型不支持排序规则,则为 null。 @@ -2558,7 +2558,7 @@ <literal>element_types</literal> - 视图element_types包含数组元素的数据类型描述符。当一个表列、复合类型属性、域、函数参数或函数返回值被定义为一种数组类型,相应的信息模式视图只在列data_type中包含ARRAY。要获得该数组元素类型的信息,你可以连接该相应的视图和这个视图。例如,要显示一个表的列及其数据类型和数组元素类型,你可以: + 视图element_types包含数组元素的数据类型描述符。当一个表列、复合类型属性、域、函数参数或函数返回值被定义为一种数组类型时,相应的信息模式视图只在列data_type中包含ARRAY。要获得该数组元素类型的信息,你可以连接该相应的视图和这个视图。例如,要显示一个表的列及其数据类型和数组元素类型(如果适用),你可以: SELECT c.column_name, c.data_type, e.data_type AS element_type FROM information_schema.columns c LEFT JOIN information_schema.element_types e @@ -2689,7 +2689,7 @@ ORDER BY c.ordinal_position; collation_catalog sql_identifier - 包含元素类型排序规则的数据库名称(总是当前数据库), 如果默认或该元素的数据类型是不可排序的则为空 + 包含该元素类型排序规则的数据库名称(总是当前数据库);如果使用默认排序规则,或该元素类型不支持排序规则,则为 null。 @@ -2698,7 +2698,7 @@ ORDER BY c.ordinal_position; collation_schema sql_identifier - 包含元素类型排序规则的模式名称, 如果默认或该元素的数据类型是不可排序的则为空 + 包含该元素类型排序规则的模式名称;如果使用默认排序规则,或该元素类型不支持排序规则,则为 null。 @@ -2707,7 +2707,7 @@ ORDER BY c.ordinal_position; collation_name sql_identifier - 元素类型的排序规则名, 如果默认或该元素的数据类型是不可排序的则为空 + 该元素类型排序规则的名称;如果使用默认排序规则,或该元素类型不支持排序规则,则为 null。 @@ -7145,7 +7145,7 @@ ORDER BY c.ordinal_position; - SQL 了解两种用户定义类型:结构类型(在PostgreSQL中也称为复合类型)以及 distinct type(PostgreSQL 尚未实现)。为兼顾将来,请使用列user_defined_type_category来区分它们。其他用户定义类型,如基类型和枚举(两者都是PostgreSQL的扩展),不会在这里显示。域的相关信息见。 + SQL 中有两种用户定义类型:结构类型(在PostgreSQL中也称为复合类型)以及独立类型(distinct type,PostgreSQL 尚未实现)。为兼顾将来,请使用列user_defined_type_category来区分它们。其他用户定义类型,如基础类型和枚举(两者都是PostgreSQL的扩展),不会在这里显示。域的相关信息见 @@ -7877,7 +7877,7 @@ ORDER BY c.ordinal_position; check_optioncharacter_data - CASCADEDLOCAL 如果视图上有CHECK OPTION 定义,如果没有则为NONE。 + CASCADEDLOCAL 如果视图上有CHECK OPTION 定义,如果没有则为NONE diff --git a/zh/18/installation.sgml b/zh/18/installation.sgml index 18965a65..5c3567d8 100644 --- a/zh/18/installation.sgml +++ b/zh/18/installation.sgml @@ -4,7 +4,7 @@ 从源代码安装 - installation + 安装 @@ -362,7 +362,7 @@ 使用 Autoconf 和 Make 进行构建和安装 - 简短版本 + 简要说明 @@ -379,7 +379,7 @@ su - postgres /usr/local/pgsql/bin/createdb test /usr/local/pgsql/bin/psql test - 较长版本见本其余部分。 + 详细说明见本的其余部分。 @@ -607,7 +607,7 @@ build-postgresql: <filename>configure</filename> 选项 - 配置选项 + configure 选项 @@ -1031,7 +1031,7 @@ build-postgresql: ,使用 OSSP UUID library + url="http://www.ossp.org/pkg/lib/uuid/">OSSP UUID 库 @@ -1094,13 +1094,7 @@ build-postgresql: 这一特性要求 libxml2 2.6.23 或更高版本。 - - 为了检测所需的编译器和链接器选项,如果系统已安装 - pkg-config 且知道 libxml2,PostgreSQL - 会查询 pkg-config。否则,如果找得到由 libxml2 - 安装的 xml2-config 程序,就会使用它。 - 优先使用 pkg-config,因为它能更好地处理多架构安装。 - + 为检测所需的编译器和链接器选项,PostgreSQL 会查询 pkg-config,前提是已安装该程序且其中有 libxml2 的信息。否则,如果找到 libxml2 安装的 xml2-config 程序,就会使用它。优先使用 pkg-config,因为它能更好地处理多架构安装。 如果 libxml2 安装在不常见的位置,你可以设置与 @@ -1142,7 +1136,7 @@ build-postgresql: - 反功能 + 禁用特性 本节描述的选项允许禁用某些默认会构建的 @@ -1287,8 +1281,7 @@ build-postgresql: - 不在 PostgreSQL 的可执行文件中标记, - 使其在运行时到安装的库目录中搜索共享库(见 )。 + 不在 PostgreSQL 的可执行文件中添加指示其到安装的库目录中搜索共享库的标记(见 )。 在大多数平台上,这种标记使用库目录的绝对路径,因此如果你之后移动安装位置, 它就没有帮助了。不过这样一来,你就需要通过其他方式让可执行文件找到共享库。 通常这要求配置操作系统的动态链接器搜索该库目录;更多细节见 @@ -1305,7 +1298,7 @@ build-postgresql: 杂项 - 调整默认端口号 相当常见, + 使用 调整默认端口号相当常见, 尤其是在测试性构建中。本节中的其他选项只推荐给高级用户。 @@ -1340,10 +1333,10 @@ build-postgresql: - 设置 segment size,单位为 GB。 + 设置 段大小,单位为 GB。 大表会被分成多个操作系统文件,每个文件的大小等于段大小。 这可以避免很多平台上的文件大小限制问题。默认段大小 1GB 在所有支持的平台上 - 都是安全的。如果你的操作系统支持 largefile + 都是安全的。如果你的操作系统支持 大文件 (如今大多数都支持),你可以使用更大的段大小。 这有助于减少处理超大表时消耗的文件描述符数量。 但请注意不要选择超出你的平台和打算使用的文件系统所支持的值。 @@ -1359,7 +1352,7 @@ build-postgresql: - 设置 block size,单位为 KB。 + 设置 块大小,单位为 KB。 这是表内部存储和 I/O 的单位。默认值 8KB 适合大多数场景, 但在特殊情况下,其他取值也可能有用。 该值必须是 1 到 32(KB)之间的 2 的幂。 @@ -1373,7 +1366,7 @@ build-postgresql: - 设置 WAL block size,单位为 KB。 + 设置 WAL 块大小,单位为 KB。 这是 WAL 日志内部存储和 I/O 的单位。默认值 8KB 适合大多数场景, 但在特殊情况下,其他取值也可能有用。 该值必须是 1 到 64(KB)之间的 2 的幂。 @@ -1423,11 +1416,11 @@ build-postgresql: - 在服务器中启用 assertion 检查,用于测试许多 - 不应该发生的条件。这对代码开发非常有价值,但这些测试会显著拖慢 + 在服务器中启用 断言 检查,用于测试许多 + 不可能发生的条件。这对代码开发非常有价值,但这些测试可能会显著拖慢 服务器速度。此外,启用这些测试并不一定会增强服务器稳定性! 断言检查并未按严重程度分类,因此即使某个 bug 相对无害,只要触发了断言失败, - 仍可能导致服务器重启。该选项不建议用于生产环境,但如果你在做开发工作 + 仍会导致服务器重启。该选项不建议用于生产环境,但如果你在做开发工作 或运行测试版,就应当启用它。 @@ -1472,7 +1465,7 @@ build-postgresql: 如果使用 GCC,所有程序和库都会被编译成可进行性能分析的形式。 - 后端退出时,会创建一个子目录,其中包含带有 profile 数据的 + 后端退出时,会创建一个子目录,其中包含带有性能分析数据的 gmon.out 文件。 该选项只适用于 GCC,并且仅在开发工作中使用。 @@ -1548,7 +1541,7 @@ build-postgresql: <filename>configure</filename> 环境变量 - configure environment variables + configure 环境变量 @@ -1615,7 +1608,7 @@ build-postgresql: 在使用 --with-llvm 编译时, - 用于处理源代码以内联的 clang 程序路径 + 用于处理源代码以进行内联的 clang 程序路径 @@ -1819,7 +1812,7 @@ build-postgresql: 使用 Meson 构建和安装 - 简短版本 + 简要说明 @@ -1837,7 +1830,7 @@ su - postgres /usr/local/pgsql/bin/createdb test /usr/local/pgsql/bin/psql test - 较长版本见本其余部分。 + 详细说明见本的其余部分。 @@ -2387,7 +2380,7 @@ ninja install ,使用 OSSP UUID library + url="http://www.ossp.org/pkg/lib/uuid/">OSSP UUID 库 @@ -2475,7 +2468,7 @@ ninja install - 反功能 + 禁用特性 @@ -2531,7 +2524,7 @@ ninja install 设置这个选项,可以覆盖所有 auto 特性的取值 (也就是那些在找到所需软件时会自动启用的特性)。 - 当你想一次性禁用或启用所有 optional 特性, + 当你想一次性禁用或启用所有 可选 特性, 而不必逐个手工设置时,这会很有用。 该参数的默认值是 auto。 @@ -2647,9 +2640,8 @@ ninja install - 该选项默认值是 true。如果设为 false,则不会在 - PostgreSQL 的可执行文件中标记, - 使其在运行时到安装的库目录中搜索共享库(见 )。 + 该选项默认值是 true。如果设为 false,则不在 + PostgreSQL 的可执行文件中添加指示其到安装的库目录中搜索共享库的标记(见 )。 在大多数平台上,这种标记使用库目录的绝对路径,因此如果你之后移动安装位置, 它就没有帮助了。不过这样一来,你就需要通过其他方式让可执行文件找到共享库。 通常这要求配置操作系统的动态链接器搜索该库目录;更多细节见 @@ -2750,10 +2742,10 @@ ninja install - 设置 segment size,单位为 GB。 + 设置 段大小,单位为 GB。 大表会被分成多个操作系统文件,每个文件的大小等于段大小。 这可以避免很多平台上的文件大小限制问题。默认段大小 1GB 在所有支持的平台上 - 都是安全的。如果你的操作系统支持 largefile + 都是安全的。如果你的操作系统支持 大文件 (如今大多数都支持),你可以使用更大的段大小。 这有助于减少处理超大表时消耗的文件描述符数量。 但请注意不要选择超出你的平台和打算使用的文件系统所支持的值。 @@ -2767,7 +2759,7 @@ ninja install - 设置 block size,单位为 KB。 + 设置 块大小,单位为 KB。 这是表内部存储和 I/O 的单位。默认值 8KB 适合大多数场景, 但在特殊情况下,其他取值也可能有用。 该值必须是 1 到 32(KB)之间的 2 的幂。 @@ -2779,7 +2771,7 @@ ninja install - 设置 WAL block size,单位为 KB。 + 设置 WAL 块大小,单位为 KB。 这是 WAL 日志内部存储和 I/O 的单位。默认值 8KB 适合大多数场景, 但在特殊情况下,其他取值也可能有用。 该值必须是 1 到 64(KB)之间的 2 的幂。 @@ -2865,11 +2857,11 @@ ninja install - 在服务器中启用 assertion 检查,用于测试许多 - 不应该发生的条件。这对代码开发非常有价值,但这些测试会显著拖慢 + 在服务器中启用 断言 检查,用于测试许多 + 不可能发生的条件。这对代码开发非常有价值,但这些测试会显著拖慢 服务器速度。此外,启用这些测试并不一定会增强服务器稳定性! 断言检查并未按严重程度分类,因此即使某个 bug 相对无害,只要触发了断言失败, - 仍可能导致服务器重启。该选项不建议用于生产环境,但如果你在做开发工作 + 仍会导致服务器重启。该选项不建议用于生产环境,但如果你在做开发工作 或运行测试版,就应当启用它。 @@ -2890,10 +2882,10 @@ ninja install - 启用额外测试套件;这些测试默认不会运行,因为它们不适合在多用户系统上运行、 + 启用额外测试套件;这些测试默认不会运行,因为它们在多用户系统上运行不安全、 需要特殊软件,或者资源消耗较大。该参数是以空白分隔的测试名称列表。 详见 。如果在运行测试时设置了 - PG_TEST_EXTRA 环境变量,那么它会覆盖这个构建时选项。 + PG_TEST_EXTRA 环境变量,那么它会覆盖这个配置阶段的选项。 @@ -3202,14 +3194,14 @@ export MANPATH 不支持 adduser 命令;请使用 Windows 中相应的 - 用户管理应用。除此之外,跳过这一步即可。 + 用户管理应用。也可以跳过这一步。 不支持 su 命令;请在 Windows 上使用 ssh 来模拟 su。 - 除此之外,跳过这一步即可。 + 也可以跳过这一步。 @@ -3240,16 +3232,11 @@ export MANPATH - - 并行回归测试(make check)可能会因为 - listen() backlog 队列溢出而产生伪造的回归测试失败, - 进而导致连接拒绝错误或挂起。你可以像下面这样使用 make 变量 - MAX_CONNECTIONS 来限制连接数: + 并行回归测试(make check)可能因 listen() 的待处理连接队列溢出而误报回归测试失败;队列溢出会导致连接被拒绝的错误或挂起。可以使用 make 变量 MAX_CONNECTIONS 限制连接数,方法如下: make MAX_CONNECTIONS=5 check - (在某些系统上,同时连接数大致最多可达到 10 个。) - +(在某些系统上,并发连接数最高可达约 10 个。) @@ -3322,7 +3309,7 @@ xcrun --show-sdk-path macOS 的 - System Integrity Protection(SIP)特性会破坏 + 系统完整性保护(SIP)特性会破坏 make check,因为它会阻止把所需的 DYLD_LIBRARY_PATH 设置传递给被测试的可执行文件。 你可以通过在 make check 之前先执行 @@ -3388,7 +3375,7 @@ xcrun --show-sdk-path 你可以从 下载 Sun Studio。许多 GNU 工具已经集成到 Solaris 10 中, - 或者包含在 Solaris companion CD 中。如果你需要适用于较旧 Solaris 版本的 + 或者包含在 Solaris 配套光盘中。如果你需要适用于较旧 Solaris 版本的 软件包,可以到 查找这些工具。 如果你更想要源码,请看 。 @@ -3396,10 +3383,10 @@ xcrun --show-sdk-path - configure 抱怨测试程序失败 + configure 报告测试程序失败 - 如果 configure 抱怨某个测试程序失败, + 如果 configure 报告某个测试程序失败, 这多半是因为运行时链接器找不到某些库,通常是 libz、libreadline, 或其他非标准库如 libssl。要把它指向正确位置,请在 configure 命令行中设置环境变量 LDFLAGS, diff --git a/zh/18/libpq.sgml b/zh/18/libpq.sgml index e5ee8c57..6772cb49 100644 --- a/zh/18/libpq.sgml +++ b/zh/18/libpq.sgml @@ -41,7 +41,7 @@ - 如果不可信用户能够访问一个没有采用模式的安全使用方式的数据库,那么每个会话开始时都应从search_path中移除公开可写的模式。可以把参数关键词options设置为-csearch_path=。也可以在连接后发出PQexec(conn, "SELECT pg_catalog.set_config('search_path', '', false)")。这种考虑并非专门针对libpq;它适用于每一种可执行任意 SQL 命令的接口。 + 如果不受信任的用户能够访问一个没有采用模式的安全使用方式的数据库,那么每个会话开始时都应从search_path中移除公开可写的模式。可以把参数关键词options设置为-csearch_path=。也可以在连接后发出PQexec(conn, "SELECT pg_catalog.set_config('search_path', '', false)")。这种考虑并非专门针对libpq;它适用于每一种可执行任意 SQL 命令的接口。 @@ -180,7 +180,7 @@ PGconn *PQsetdb(char *pghost, PQconnectStartParamsPQconnectStartParams PQconnectStartPQconnectStart - PQconnectPollPQconnectPoll + PQconnectPollPQconnectPoll nonblocking connection @@ -214,7 +214,7 @@ PostgresPollingStatusType PQconnectPoll(PGconn *conn); - hostaddrhost参数必须被合适地使用,以防止做DNS查询。详见中这些参数的文档。 + 必须正确使用 hostaddr 参数,以避免执行 DNS 查询。详细信息请参见中该参数的说明。 @@ -289,11 +289,12 @@ PostgresPollingStatusType PQconnectPoll(PGconn *conn); - - CONNECTION_SETENV + + + CONNECTION_GSS_STARTUP - 协商环境驱动的参数设置。 + 协商 GSS 加密。 @@ -307,6 +308,15 @@ PostgresPollingStatusType PQconnectPoll(PGconn *conn); + + CONNECTION_CHECK_STANDBY + + + 检查连接的服务器是否处于备用模式。 + + + + CONNECTION_CONSUME @@ -347,6 +357,38 @@ switch(PQstatus(conn)) + + PQsocketPollPQsocketPoll + + + 非阻塞连接 + 轮询通过取得的连接底层套接字描述符。此函数主要用于逐步执行文档中描述的连接过程。 + +typedef int64_t pg_usec_time_t; + +int PQsocketPoll(int sock, int forRead, int forWrite, + pg_usec_time_t end_time); + + + + + 此函数对文件描述符进行轮询,并可选择设置超时。如果forRead非零,则在套接字可读时结束。如果forWrite非零,则在套接字可写时结束。 + + + + 超时由end_time指定,它表示停止等待的时刻,以自 Unix 纪元以来的微秒数表示(即time_t乘以一百万)。如果end_time-1,则无限等待。如果 end_time0(或任何早于当前时刻的时间),则立即超时(不阻塞)。将所需的微秒数加到的结果上,即可方便地计算超时值。注意,底层系统调用的精度可能低于微秒,因此实际延迟可能不精确。 + + + + 如果满足指定条件,函数返回大于0的值;如果发生超时,返回0;如果发生错误,返回-1。可以通过检查errno(3)的值获取错误信息。如果forReadforWrite都为零,函数会立即返回超时指示。 + + + + PQsocketPoll根据平台使用poll(2)select(2)实现。更多信息请参见poll(2)中的POLLINPOLLOUT,或select(2)中的readfdswritefds。 + + + + PQconndefaultsPQconndefaults @@ -779,7 +821,7 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname 参数关键词 - 目前被识别的参数关键字包括: + 目前被识别的参数关键字包括: @@ -951,9 +993,7 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname 服务器必须请求 MD5 哈希密码认证。 - - 对 MD5 加密密码的支持已被废弃,并将在未来的PostgreSQL版本中移除。关于迁移到其他密码类型的细节,请参见。 - + 对 MD5 加密密码的支持已弃用,并将在PostgreSQL的未来版本中移除。迁移到其他密码类型的详细信息见 @@ -1057,7 +1097,7 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname - 指定连接开始时发送到服务器的命令行选项。例如,将其设置为-c geqo=off会把会话的geqo参数值设为off。 + 指定连接开始时发送到服务器的命令行选项。例如,将其设置为-c geqo=off--geqo=off会把会话的geqo参数值设为off。 此字符串中的空格被视为分隔命令行参数,除非用反斜杠(\)转义;写\\表示字面上的反斜杠。 有关可用选项的详细讨论,请参阅 @@ -1515,12 +1555,20 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname sslrootcert - - 这个参数指定一个包含SSL证书颁发机构(CA)证书的文件名。 - 如果文件存在,服务器的证书将被验证是否由这些机构之一签名。 - 默认值是~/.postgresql/root.crt。 + 此参数指定包含 SSL 证书颁发机构(CA)证书的文件名。如果文件存在,则会验证服务器证书是否由这些机构之一签名。默认值为~/.postgresql/root.crt + + 也可以指定特殊值system,此时会加载 SSL 实现提供的受信任 CA 根证书。这些根证书的确切位置因 SSL 实现和平台而异。对于OpenSSL,还可以通过SSL_CERT_DIRSSL_CERT_FILE环境变量进一步修改这些位置。 + + + + 使用sslrootcert=system时,默认的sslmode会改为verify-full,任何较弱的设置都会引发错误。在大多数情况下,任何人都很容易为其控制的主机名获取受系统信任的证书,因此verify-ca及所有更弱的模式都无法发挥作用。 + + + 特殊值system优先于同名的本地证书文件。如果遇到这种情况,请改用其他路径,例如sslrootcert=./system。 + + @@ -1624,7 +1672,7 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname 这个参数指定该连接允许的最低协议版本。默认情况下,允许使用 libpq所支持的任何 PostgreSQL协议版本, - 目前即3.0。如果服务器至少不支持这一协议版本, + 目前即3.0。如果服务器不支持此协议版本或更高版本, 则连接将被关闭。 @@ -1646,7 +1694,7 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname 但如果连接字符串指定了依赖更高协议版本的特性,则会使用 libpq支持的最新版本。如果服务器不支持客户端请求的协议版本, 连接会自动降级为服务器支持的较低次版本协议。连接尝试完成后, - 你可以使用PQfullProtocolVersion()来确定 + 你可以使用来确定 最终协商得到的确切协议版本。 @@ -1703,7 +1751,7 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname scram_client_key - 以 Base64 编码的 SCRAM client key。外部数据包装器或类似中间件可以利用它启用透传式 SCRAM 认证。一个实现示例见。普通用户或客户端应用不应直接指定它。 + 以 Base64 编码的 SCRAM 客户端密钥。外部数据包装器或类似中间件可以利用它启用透传式 SCRAM 认证。一个实现示例见。普通用户或客户端应用不应直接指定它。 @@ -1712,7 +1760,7 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname scram_server_key - 以 Base64 编码的 SCRAM server key。外部数据包装器或类似中间件可以利用它启用透传式 SCRAM 认证。一个实现示例见。普通用户或客户端应用不应直接指定它。 + 以 Base64 编码的 SCRAM 服务器密钥。外部数据包装器或类似中间件可以利用它启用透传式 SCRAM 认证。一个实现示例见。普通用户或客户端应用不应直接指定它。 @@ -1955,7 +2003,7 @@ char *PQpass(const PGconn *conn); 将返回连接参数中指定的密码,如果连接参数中没有密码并且能从密码文件中得到密码,则它将返回得到的密码。 - 在后一种情况中,如果连接参数中指定了多个主机,在连接被建立之前都不能依赖的结果。连接的状态可以用函数检查。 + 在后一种情况中,如果连接参数中指定了多个主机,在连接被建立之前都不能依赖的结果。连接的状态可以用函数检查。 @@ -2109,46 +2157,61 @@ PGTransactionStatusType PQtransactionStatus(const PGconn *conn); - 查找服务器的一个当前参数设置。 + 查找服务器某个参数的当前设置。 const char *PQparameterStatus(const PGconn *conn, const char *paramName); - 某一参数值会被服务器在连接开始或值改变时自动报告。可以被用来询问这些设置。它为已知的参数返回当前值,为未知的参数返回NULL。 + 服务器会在连接启动时,以及某些参数值发生变化时,自动报告这些参数值。可用于查询这些设置。如果已知该参数,则返回其当前值;如果未知,则返回NULL。 + + + + 当前版本报告的参数包括: + + application_name + client_encoding + DateStyle + default_transaction_read_only + in_hot_standby + integer_datetimes + IntervalStyle + is_superuser + scram_iterations + search_path + server_encoding + server_version + session_authorization + standard_conforming_strings + TimeZone + + (14 之前的版本不报告 default_transaction_read_onlyin_hot_standby;16 之前的版本不报告 scram_iterations;18 之前的版本不报告 search_path。) + 注意,server_versionserver_encodinginteger_datetimes 在启动后不能改变。 - 自当前发布开始会被报告的参数包括 - server_version、 - server_encoding、 - client_encoding、 - application_name、 - default_transaction_read_only, - in_hot_standby, - is_superuser、 - session_authorization、 - DateStyle、 - IntervalStyle、 - TimeZone、 - integer_datetimes以及 - standard_conforming_strings。 - (server_encodingTimeZone以及integer_datetimes在 8.0 以前的发布中不被报告; - standard_conforming_strings在 8.1 以前的发布中不被报告; - IntervalStyle在 8.4 以前的发布中不被报告; - application_name在 9.0 以前的发布中不被报告; - default_transaction_read_onlyin_hot_standby 在14以前的发布中不被报告) - 注意 server_version、 - server_encoding以及 - integer_datetimes在启动之后无法改变。 + 如果服务器未报告standard_conforming_strings的值,应用程序可以假定其为off,即反斜杠在字符串字面量中被视为转义字符。此外,服务器报告此参数也表明它接受转义字符串语法(E'...')。 - 如果没有为standard_conforming_strings报告值,应用能假设它是off,也就是说反斜线会被视为字符串中的转义。还有,这个参数的存在可以被作为转义字符串语法(E'...')被接受的指示。 + 返回的指针虽然被声明为const,但实际上指向与PGconn结构体关联的可变存储。不能假定该指针在执行其他查询后仍然有效。 + + + + PQfullProtocolVersionPQfullProtocolVersion + + - 尽管被返回的指针被声明成const,它事实上指向与PGconn结构体相关的可变存储。假定该指针在存储之间保持有效是不明智的。 + 查询正在使用的前端/后端协议。 + +int PQfullProtocolVersion(const PGconn *conn); + + 应用程序可以使用此函数确定是否支持某些功能。结果由服务器的协议主版本号乘以 10000,再加上次版本号组成。例如,版本 3.2 返回 30002,版本 4.0 返回 40000。如果连接无效,则返回零。PostgreSQL服务器 7.4 及更高版本支持 3.0 协议。 + + + 连接启动完成后,协议版本不会改变,但在连接重置期间,理论上可能改变。 @@ -2158,13 +2221,11 @@ const char *PQparameterStatus(const PGconn *conn, const char *paramName); - 询问所使用的 前端/后端协议。 + 查询前端/后端协议的主版本号。 int PQprotocolVersion(const PGconn *conn); - 应用可能希望用这个函数来确定某些特性是否被支持。当前,可能值是3(3.0 协议)或零(连接损坏)。 - 协议版本在连接启动完成后将不会改变,但是理论上在连接重置期间是可以改变的。 - 3.0 协议被PostgreSQL 7.4 或以后的服务器版本所支持。 + 与 不同,此函数仅返回正在使用的协议主版本号,但从 7.4 起的更多 libpq 版本均支持它。目前可能的值为 3(协议 3.0)或零(连接异常)。在 14.0 之前的版本中,libpq 还可能返回 2(协议 2.0)。 @@ -2283,6 +2344,22 @@ int PQconnectionUsedPassword(const PGconn *conn); + + + PQconnectionUsedGSSAPIPQconnectionUsedGSSAPI + + + 如果连接的认证方法使用了 GSSAPI,则返回真(1);否则返回假(0)。 + +int PQconnectionUsedGSSAPI(const PGconn *conn); + + + + + 此函数可用于检测连接是否使用 GSSAPI 进行了认证。 + + + @@ -2367,6 +2444,14 @@ const char *PQsslAttribute(const PGconn *conn, const char *attribute_name); + + alpn + + + TLS 应用层协议协商(ALPN)扩展选定的应用协议。libpq 唯一支持的协议是 postgresql,因此该属性主要用于检查服务器是否支持 ALPN。如果未使用 ALPN,则为空字符串。 + + + @@ -2383,13 +2468,16 @@ const char *PQsslAttribute(const PGconn *conn, const char *attribute_name); PQsslAttributeNamesPQsslAttributeNames - - 返回可用的SSL属性名称数组。 - 数组以NULL指针结尾。 + 返回可用于 PQsslAttribute() 的 SSL 属性名称数组。数组以 NULL 指针结尾。 const char * const * PQsslAttributeNames(const PGconn *conn); + + + + + 如果 conn 为 NULL,则返回默认 SSL 库可用的属性;如果 libpq 编译时未启用任何 SSL 支持,则返回空列表。如果 conn 不为 NULL,则返回该连接所用 SSL 库可用的属性;如果连接未加密,则返回空列表。 @@ -2569,7 +2657,7 @@ PGresult *PQexecParams(PGconn *conn, paramTypes[] - 通过 OID 指定要赋予给参数符号的数据类型。如果paramTypesNULL或者该数组中任何特定元素为零,服务器会用对待未知类型文字串的方式为参数符号推测一种数据类型。 + 通过 OID 指定要赋予给参数符号的数据类型。如果paramTypesNULL或者该数组中任何特定元素为零,服务器会用对待未指定类型的字符串字面量的方式为参数符号推测一种数据类型。 @@ -2663,10 +2751,10 @@ PGresult *PQprepare(PGconn *conn, 该函数从query串创建一个名为stmtName的预备语句,该串必须包含一个单一 SQL 命令。 stmtName可以是""来创建一个未命名语句,在这种情况下任何已存在未命名语句将被自动替换。 - 如果语句名称已经在当前会话中被定义,则是一种错误。如果使用了任何参数,它们在查询中以$1$2等引用。 + 否则,如果语句名称已经在当前会话中被定义,则是一种错误。如果使用了任何参数,它们在查询中以$1$2等引用。 nParams是参数的个数,其类型在数组paramTypes[]中被预先指定(当nParams为零时,该数组指针可以是NULL)。 paramTypes[]通过 OID 指定要赋予给参数符号的数据类型。 - 如果paramTypesNULL或者该数组中任何特定元素为零,服务器会用对待未知类型文字串的方式为参数符号推测一种数据类型。 + 如果paramTypesNULL或者该数组中任何特定元素为零,服务器会用对待未指定类型的字符串字面量的方式为参数符号推测一种数据类型。 还有,查询能够使用编号高于nParams的参数符号,它们的数据类型也会被自动推测(找出推测出的数据类型的方法见)。 @@ -2679,7 +2767,6 @@ PGresult *PQprepare(PGconn *conn, 用于的预备语句也能通过执行 SQL 语句来创建。 - 还有,尽管没有libpq函数来删除一个预备语句,SQL 语句可被用于此目的。 @@ -2927,13 +3014,21 @@ ExecStatusType PQresultStatus(const PGresult *res); - + + PGRES_TUPLES_CHUNK + + + PGresult包含当前命令返回的若干结果元组。此状态仅在为查询选择了分块模式时出现(参见)。元组数不会超过传递给的上限。 + + + + + PGRES_PIPELINE_SYNC - PGresult表示管道模式中的同步点,由请求。 - 此状态仅在选择管道模式时发生。 - + PGresult 表示管道模式中的同步点,由 请求。此状态仅在已选择管道模式时出现。 + @@ -3076,7 +3171,7 @@ char *PQresultErrorField(const PGresult *res, int fieldcode); PG_DIAG_MESSAGE_DETAIL - 细节:一个可选的次级错误消息,它携带了关于问题的等多细节。可能有多行。 + 细节:一个可选的次级错误消息,它携带了关于问题的更多细节。可能有多行。 @@ -3094,7 +3189,7 @@ char *PQresultErrorField(const PGresult *res, int fieldcode); PG_DIAG_STATEMENT_POSITION - 包含一个十进制整数的字符串,它表示一个错误游标位置,该位置是原始语句字符串的索引。第一个字符的索引是 1,位置以字符计算而不是以及字节计算。 + 包含一个十进制整数的字符串,它表示一个错误游标位置,该位置是原始语句字符串的索引。第一个字符的索引是 1,位置以字符计算而不是以字节计算。 @@ -3888,8 +3983,8 @@ unsigned char *PQescapeByteaConn(PGconn *conn, - 当某些字节值被用作一个SQL语句中的bytea文字的一部分时,它们必须被转义。 - 转义使用十六进制编码或反斜线转义的字节。详见。 + 当某些字节值被用作一个SQL语句中的bytea字面量的一部分时,它们必须被转义。 + 使用十六进制编码或反斜杠转义来转义这些字节。详见 @@ -3939,7 +4034,8 @@ unsigned char *PQescapeBytea(const unsigned char *from, - 将二进制数据的一个字符串表示转换成二进制数据 — 它是的逆向函数。当检索文本格式的bytea数据时,需要这个函数,但检索二进制个事时则不需要它。 + 将二进制数据的字符串表示转换为二进制数据,这是的逆操作。 + 以文本格式取得bytea数据时需要此操作;以二进制格式取得时则不需要。 unsigned char *PQunescapeBytea(const unsigned char *from, size_t *to_length); @@ -3947,14 +4043,15 @@ unsigned char *PQunescapeBytea(const unsigned char *from, size_t *to_length); - from参数指向一个字符串,例如被应用到一个bytea列上所返回的。 - 把这个串表示转换成它的二进制表示。 - 它返回一个指向用malloc()分配的缓冲区的指针,在错误时返回NULL,并且把缓冲区的尺寸放在to_length中。 - 当结果不再需要时,它必须使用释放。 + from参数指向一个字符串,例如对bytea列调用时返回的字符串。 + 将这个字符串表示转换为二进制表示。 + 它返回指向通过malloc()分配的缓冲区的指针,出错时返回NULL,并将缓冲区大小存入to_length。 + 不再需要结果时,必须使用释放它。 - 这种转换并不完全是PQescapeBytea的逆函数,因为当从PQgetvalue接收到字符串时,我们并不能期待它被转义。特别地这意味着不需要考虑字符串引用,并且因此也不需要一个参数。 + 此转换并不完全是的逆操作,因为从收到的字符串并非经过转义的形式。 + 具体而言,这意味着无需考虑字符串引号,因此也不需要PGconn参数。 @@ -4003,26 +4100,17 @@ unsigned char *PQunescapeBytea(const unsigned char *from, size_t *to_length); - - 不喜欢这些限制的应用程序可以使用构建自的底层函数: - 。 - 还有 - , - , - , - , - , - 以及 - , - 它们可以与配合使用,分别复制 - , - , - , - , - , - 和 - - 的功能。 + 如果应用程序不希望受到这些限制,可以改用构成的底层函数:。此外,还有, + , + , + , + , + ,以及,它们可以与配合使用,分别实现以下函数的功能:, + , + , + , + , + ,以及 @@ -4197,15 +4285,16 @@ int PQsendClosePortal(PGconn *conn, const char *portalName); - 等待来自先前的、 + 等待先前的 、 - 或 - - 调用的下一个结果,并返回它。 - 当命令完成且不会再有更多结果时,将返回空指针。 + 、 + 、 + 、 + 或 + 调用产生的下一个结果,并返回该结果。当命令执行完毕且不再有其他结果时,返回空指针。 PGresult *PQgetResult(PGconn *conn); @@ -4309,7 +4398,7 @@ int PQisBusy(PGconn *conn); 一个使用/的客户端也可以尝试取消一个正在被服务器处理的命令,见。 - 但是,不管的返回值是什么,应用都必须继续使用进行正常的结果读取序列。一次成功的取消只会导致命令比不取消时更快终止。 + 但是,不管的返回值是什么,应用都必须继续使用进行正常的结果读取序列。一次成功的取消只会导致命令比不取消时更快终止。 @@ -4473,68 +4562,42 @@ int PQflush(PGconn *conn); - 发出查询 - 进入管道模式后,应用程序使用或其姊妹函数来分派请求。 - 这些请求在客户端排队,直到刷新到服务器端;当使用建立管道中的同步点时,或者调用时,会发生这种情况。 - 函数在管道模式下也可以工作。 - 结果处理如下所述。 + 进入管道模式后,应用程序使用 或其处理预备查询的对应函数 发送请求。这些请求在客户端排队,直到发送到服务器;使用 在管道中建立同步点,或调用 时会发送它们。函数 、&zwsp;、&zwsp;、&zwsp; 也可用于管道模式。结果处理方式见下文。 - 服务器执行语句,并返回结果,按客户端发送它们的顺序。 - 服务器将立即开始执行管道中的命令,不等待管道的结束。 - 注意,结果被缓冲在服务器端;当使用PQpipelineSync建立同步点时,或者PQsendFlushRequest被调用时,服务器会刷新该缓冲区。 - 如果任何语句遇到错误,服务器将中止当前事务,并且不执行队列中的任何后续命令,直到下一个同步点;对于每一个这样的命令都会产生一个PGRES_PIPELINE_ABORTED结果。 - (即使管道中的命令将回滚事务,依然如此。) - 查询处理在同步点之后恢复。 + 服务器按客户端发送的顺序执行语句并返回结果。服务器会立即开始执行管道中的命令,无需等待管道结束。结果会缓存在服务器端;使用 PQpipelineSyncPQsendPipelineSync 建立同步点,或调用 PQsendFlushRequest 时,服务器会发送该缓冲区中的数据。如果任何语句发生错误,服务器会中止当前事务,并停止执行队列中的后续命令,直到下一个同步点;每条被跳过的命令都会产生一个 PGRES_PIPELINE_ABORTED 结果。(即使管道中的命令会回滚事务,也仍然如此。)到达同步点后,查询处理恢复。 - 一个操作依赖于前一个操作的结果是没问题的; - 例如,一个查询可以定义一个同一管道中的下一个查询将用到的表。 - 类似地,应用可以创建一个命名的预备语句,并在同一管道中与后续语句一起执行它。 + 一个操作可以依赖先前操作的结果;例如,一个查询可以定义一张表,供同一管道中的下一个查询使用。类似地,应用程序可以创建命名的预备语句,并通过同一管道中后续的语句执行它。 - 处理结果 - 为了在管道中处理一个查询的结果,应用重复调用PQgetResult并处理每个结果,直到PQgetResult返回空。 - 可以再次使用PQgetResult检索管道中下一个查询的结果,并且循环重复 - 应用像通常一样处理单个语句结果。 - 当管道中所有查询的结果都返回时,PQgetResult返回一个结果,其包含状态值PGRES_PIPELINE_SYNC。 + 要处理管道中一个查询的结果,应用程序应重复调用 PQgetResult 并处理每个结果,直到 PQgetResult 返回空指针。然后再次调用 PQgetResult 获取管道中下一个查询的结果,重复这一过程。应用程序按通常方式处理各条语句的结果。当管道中所有查询的结果都已返回时,PQgetResult 会返回一个包含状态值 PGRES_PIPELINE_SYNC 的结果。 - 客户端可以选择延迟结果处理,直到完整的管道被发送,或者与管道中发送的更多的查询交错在一起;参见。 + 客户端可以等到整条管道发送完毕后再处理结果,也可以在继续发送管道中的查询时交错处理结果;参见 - 要进入单行模式,在使用PQgetResult检索结果之前调用PQsetSingleRowMode。 - 此模式选择仅对当前处理的查询有效。 - 有关使用PQsetSingleRowMode的更多信息,请参阅。 + PQgetResult 的行为与普通异步处理相同,只是返回结果可能具有新的 PGresult 类型 PGRES_PIPELINE_SYNCPGRES_PIPELINE_ABORTED。对于每次 PQpipelineSyncPQsendPipelineSync 调用,都会在管道中的对应位置恰好报告一次 PGRES_PIPELINE_SYNC。对于第一个错误及其后的所有结果,会用 PGRES_PIPELINE_ABORTED 代替正常查询结果,直到下一个 PGRES_PIPELINE_SYNC;参见 - PQgetResult行为与普通异步处理相同,除了它可能包含新的PGresult类型PGRES_PIPELINE_SYNCPGRES_PIPELINE_ABORTED。 - 对于每个在管道中相应的点的PQpipelineSyncPGRES_PIPELINE_SYNC确定报告一次。 - PGRES_PIPELINE_ABORTED在第一个错误和所有后续结果的正常查询结果中发出,直到下一个PGRES_PIPELINE_SYNC;参见。 + PQisBusyPQconsumeInput 等函数在处理管道结果时照常工作。特别地,在管道处理过程中调用 PQisBusy 时,如果到目前为止已发出查询的所有结果均已被消费,则返回 0。 - PQisBusyPQconsumeInput、等正常操作,在处理管道结果时。 - 特别是,在管道中间调用PQisBusy 时,如果到目前为止发出的所有查询的结果都已被消耗,则返回0。 - - - - libpq不向应用提供有关当前正在处理的查询的任何信息(除了PQgetResult返回空,以表示我们开始返回下一个查询的结果)。 - 应用必须保持跟踪它发送查询的顺序,以将它们与相应的结果相关联。 - 应用通常会为此使用状态机或FIFO队列。 + libpq 不向应用程序提供当前正在处理哪个查询的信息(除了 PQgetResult 返回空指针,表示开始返回下一个查询的结果)。应用程序必须跟踪查询的发送顺序,以便将查询与对应结果关联起来。应用程序通常会使用状态机或 FIFO 队列实现这一点。 @@ -4581,7 +4644,7 @@ int PQflush(PGconn *conn); 客户端应用通常应该维护一个尚未分派的工作队列和一个已分派但尚未处理结果的工作队列。 当套接字是可写时,它将可以分派更多的工作。 当套接字是可读时,它将读取结果并处理它们,将它们匹配到相应结果队列中的下一个条目。 - 基于可用内存,来自套接字的结果将被经常读取:这里不需要等到管道结束才读取结果。 + 基于可用内存,来自套接字的结果将被经常读取:这里不需要等到管道结束才读取结果。 管道将范围涵盖到工作的逻辑单元,通常(但不是必然)每个管道一个事务。 在管道之间,不需要退出管道模式再重新进入管道模式,也不需要等待一个管道结束后再发送下一个。 @@ -4612,7 +4675,7 @@ PGpipelineStatus PQpipelineStatus(const PGconn *conn); - PQpipelineStatus 可以返回下列值中的一个: + PQpipelineStatus 可以返回下列值中的一个: @@ -4756,8 +4819,8 @@ int PQsendFlushRequest(PGconn *conn); - 当PQpipelineSync被调用的结果,或者在非管道模式下的任何请求时,服务器自动刷新它的输出缓冲区;这个函数用于使得服务器在不建立同步点的情况下以管道模式刷新其输出缓冲区。 - 请注意,请求不是自身能自动刷新到服务器;如果需要时使用PQflush。 + 当PQpipelineSync被调用的结果,或者在非管道模式下的任何请求时,服务器自动刷新它的输出缓冲区;这个函数用于使得服务器在不建立同步点的情况下以管道模式刷新其输出缓冲区。 + 请注意,请求不是自身能自动刷新到服务器;如果需要时使用PQflush @@ -4777,7 +4840,7 @@ int PQsendFlushRequest(PGconn *conn); 当服务器比较远,即网络延迟(ping time)高的时候,管道模式最有用,以及在许多小操作正在快速连续执行的时候。 当每个查询的执行时间是客户端/服务器往返时间的许多倍时,使用管道命令的优势通常会更少。 - 不用管道模式,在往返时间为300毫秒的服务器上运行一个100条语句的操作,仅网络延迟就需要30秒;使用管道,等待来自服务器的结果可能只消耗仅仅0.3秒。 + 不用管道模式,在往返时间为300毫秒的服务器上运行一个100条语句的操作,仅网络延迟就需要30秒;使用管道,等待来自服务器的结果可能只消耗仅仅0.3秒。 @@ -4788,7 +4851,7 @@ int PQsendFlushRequest(PGconn *conn); 当来自一个操作的信息需要客户端产生下一个操作时,管道模式是没有用的。 在这种情况下,客户机将不得不引入一个同步点,并等待完整的客户端/服务器往返以获取它需要的结果。 但是,通常可以调整客户端设计以交换服务器端所需的信息。 - 读-修改-写循环是非常好的选择;例如: + 读-修改-写循环是非常好的选择;例如: BEGIN; SELECT x FROM mytable WHERE id = 42 FOR UPDATE; @@ -4797,7 +4860,7 @@ SELECT x FROM mytable WHERE id = 42 FOR UPDATE; UPDATE mytable SET x = 3 WHERE id = 42; COMMIT; - 可以更有效地开展以下工作: + 可以更有效地开展以下工作: UPDATE mytable SET x = x + 1 WHERE id = 42; @@ -4814,12 +4877,12 @@ UPDATE mytable SET x = x + 1 WHERE id = 42; libpq - single-row mode + 单行模式 libpq - chunked mode + 分块模式 @@ -5199,22 +5262,23 @@ void PQfreeCancel(PGcancel *cancel); - 请求服务器放弃当前命令的处理。 + 的一个已弃用且不安全的变体,但可以在信号处理程序中安全调用。 int PQcancel(PGcancel *cancel, char *errbuf, int errbufsize); + - 返回值为 1 表示取消请求成功发送,为 0 表示未成功发送。如果未成功发送,errbuf将填充解释性错误消息。errbuf必须是大小为errbufsize的字符数组(推荐大小为 256 字节)。 + 仅因向后兼容而保留,应改用 唯一的优势在于:当 errbuf 是信号处理程序中的局部变量时,可以在信号处理程序中安全调用它。不过,通常认为这一优势不足以抵消该函数的安全问题。 - 取消请求成功分派并不保证一定会产生效果。如果取消成功,当前命令会提前终止并返回错误结果;如果取消失败(例如服务器已经处理完该命令),则不会有任何可见结果。 + 对于 而言,PGcancel 对象是只读的,因此也可以从与操作 PGconn 对象的线程不同的线程中调用它。 - 如果errbuf是信号处理程序中的局部变量,则可以安全地从信号处理程序中调用。对于而言,PGcancel对象是只读的,因此也可以从与操作PGconn对象的线程不同的线程中调用。 + 的返回值为 1 表示取消请求成功发送,为 0 表示未成功发送。如果未成功发送,errbuf 将填充解释性错误消息。errbuf 必须是大小为 errbufsize 的字符数组(推荐大小为 256 字节)。 @@ -5226,14 +5290,19 @@ int PQcancel(PGcancel *cancel, char *errbuf, int errbufsize); - 的一个已废弃变体。 + 的一个已弃用且不安全的变体。 int PQrequestCancel(PGconn *conn); + - 请求服务器放弃当前命令的处理。它直接作用于PGconn对象,失败时会把错误消息存储到PGconn对象中(可通过获取)。虽然功能相同,但这种方法在多线程程序或信号处理程序中并不安全,因为它可能覆盖PGconn中的错误消息,从而破坏当前连接上正在进行的操作。 + 仅因向后兼容而保留,应改用 。与 相比,使用 没有任何优势。 + + + + 请求服务器放弃当前命令的处理。它直接作用于 PGconn 对象,失败时会把错误消息存储到 PGconn 对象中(可通过 获取)。虽然功能相同,但这种方法在多线程程序或信号处理程序中并不安全,因为它可能覆盖 PGconn 中的错误消息,从而破坏当前连接上正在进行的操作。 @@ -5296,7 +5365,7 @@ typedef struct - 要传递NULL参数到函数,将参数结构体的len字段设置为-1;isintu 字段就不相关了。 + 要传递NULL参数到函数,将参数结构体的len字段设置为-1isintu 字段就不相关了。 @@ -5553,7 +5622,7 @@ int PQgetCopyData(PGconn *conn, 当async为真时(非零),将不会阻塞等待输入; 如果COPY仍在处理过程中并且没有可用的完整行,那么它将返回零 (在这种情况下等待读准备好,然后在再次调用之前,调用)。 - 当async为假(零)时,PQgetCopyData将阻塞,直到数据可用或者操作完成。 + 当async为假(零)时,将阻塞,直到数据可用或者操作完成。 @@ -5853,7 +5922,7 @@ void PQtrace(PGconn *conn, FILE *stream); - 每行包括:一个可选的时间戳,一个方向指示器(F表示从客户端到服务器的消息或B表示从服务器到客户端的消息),消息长度、消息类型、和消息内容。 + 每行包括:一个可选的时间戳,一个方向指示器(F表示从客户端到服务器的消息或B表示从服务器到客户端的消息),消息长度、消息类型、和消息内容。 非消息内容字段(时间戳、方向、长度和消息类型)由一个制表符分隔。 消息内容用空格分隔。 协议字符串用双引号括起来,而用作数据值的字符串用单引号括起来。 @@ -6027,7 +6096,7 @@ PGresult *PQchangePassword(PGconn *conn, const char *user, const char *passwd); char *PQencryptPassword(const char *passwd, const char *user); - 的一个较老的已经被废弃的版本。其差别是不要求一个连接对象,并且总是用md5作为加密算法。 + 的旧版本,现已弃用。其差别是不需要连接对象,并且总是用md5作为加密算法。 @@ -6047,11 +6116,12 @@ PGresult *PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status); 这是libpq内部用于分配并初始化一个空PGresult对象的函数。 - 如果不能分配内存,那么这个函数返回NULL。 - 它也是可以对外使用的,因为一些应用认为它可以用于产生结果对象(特别是带有错误状态的对象)本身。 - 如果conn非空,并且status表示一个错误,那么指定连接的当前错误消息会被复制到PGresult中。 - 如果conn非空,那么连接中的任何已注册事件过程也会被复制到PGresult中(它们不会获得PGEVT_RESULTCREATE调用,但会看到)。 - 注意在该对象上最终应该调用,正如对libpq本身返回的PGresult对象所作的那样。 + 如果无法分配内存,此函数返回NULL。 + 将它导出供外部调用,是因为一些应用需要自行生成结果对象,特别是带有错误状态的对象。 + 如果conn非空,并且status表示错误,指定连接的当前错误消息会被复制到PGresult中。 + 此外,如果conn非空,连接中注册的所有事件过程也会被复制到PGresult中。 + (这些过程不会收到PGEVT_RESULTCREATE调用,但可参见。) + 注意,最终应对该对象调用,就像处理libpq自身返回的PGresult一样。 @@ -6231,6 +6301,23 @@ int PQlibVersion(void); + + PQgetCurrentTimeUSecPQgetCurrentTimeUSec + + + + 获取当前时间,以自 Unix 纪元以来的微秒数表示(即time_t乘以一百万)。 + +pg_usec_time_t PQgetCurrentTimeUSec(void); + + + + + 此函数主要用于计算供使用的超时值。 + + + + @@ -6411,8 +6498,8 @@ typedef struct - 结果创建事件是响应任何生成结果的查询执行函数而触发的,包括 - 。此事件只会在结果成功创建后触发。 + 任何生成结果的查询执行函数都会触发结果创建事件,其中包括。 + 只有成功创建结果后才会触发该事件。 typedef struct @@ -6422,11 +6509,9 @@ typedef struct } PGEventResultCreate; - 当接收到PGEVT_RESULTCREATE事件时, - 应将evtInfo指针转换为 - PGEventResultCreate *。 - conn是用于生成结果的连接。 - 这是初始化需要与结果关联的任何instanceData的理想位置。 + 收到PGEVT_RESULTCREATE事件时,应将evtInfo指针转换为PGEventResultCreate *。 + 其中,conn是用于生成结果的连接。 + 这是初始化需要与结果关联的instanceData的理想位置。 如果事件过程失败(返回零),那么该事件过程将在结果的剩余生命周期内被忽略; 也就是说,它将不会接收到针对此结果或从中复制的结果的 PGEVT_RESULTCOPYPGEVT_RESULTDESTROY事件。 @@ -6796,6 +6881,15 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough) + + + + PGSSLNEGOTIATION + + PGSSLNEGOTIATION的行为与连接参数相同。 + + + @@ -6864,6 +6958,15 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough) + + + + PGREQUIREAUTH + + PGREQUIREAUTH的行为与连接参数相同。 + + + @@ -6976,6 +7079,15 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough) + + + + PGSSLCERTMODE + + PGSSLCERTMODE的行为与连接参数相同。 + + + @@ -7086,6 +7198,15 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough) + + + + PGGSSDELEGATION + + PGGSSDELEGATION的行为与连接参数相同。 + + + @@ -7125,6 +7246,33 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough) 下面的环境变量可用来为每一个PostgreSQL会话指定默认行为(为每一个用户或每一个数据库设置默认行为的方法还可见命令)。 + + + + PGLOADBALANCEHOSTS + + PGLOADBALANCEHOSTS的行为与连接参数相同。 + + + + + + + PGMINPROTOCOLVERSION + + PGMINPROTOCOLVERSION的行为与连接参数相同。 + + + + + + + PGMAXPROTOCOLVERSION + + PGMAXPROTOCOLVERSION的行为与连接参数相同。 + + + @@ -7195,20 +7343,15 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough) - 用户的主目录中的文件.pgpass可以包含密码, - 如果连接需要密码(且未指定其他密码)。在Microsoft Windows中, - 该文件的名称为%APPDATA%\postgresql\pgpass.conf - (其中%APPDATA%指用户配置文件中的应用数据子目录)。 - 或者,可以使用连接参数 - 或环境变量PGPASSFILE指定要使用的密码文件。 - + 用户主目录中的.pgpass文件可保存密码,供连接需要密码且尚未通过其他方式指定密码时使用。在 Unix 系统上,该目录可由HOME环境变量指定;如果未定义该变量,则使用有效用户的主目录。在 Microsoft Windows 上,文件名为%APPDATA%\postgresql\pgpass.conf(其中%APPDATA%指用户配置文件中的应用数据子目录)。也可以通过连接参数或环境变量PGPASSFILE指定要使用的密码文件。 + 这个文件应该包含下列格式的行: hostname:port:database:username:password - (你可以向该文件增加一个提醒:把上面的行复制到该文件并且在前面加上#)。前四个域的每一个都可以是文字值或者匹配任何东西的*。第一个匹配当前连接参数的行中的密码域将被使用(因此,在使用通配符时把更特殊的项放在前面)。如果一个条目需要包含:或者\,用\对该字符转义。如果指定了host连接参数,主机名字段会被匹配到host,否则如果指定了hostaddr参数则匹配到hostaddr,如果两者都没有给出,则会搜索主机名localhost。当连接是一个Unix域套接字连接并且host参数匹配libpq的默认套接字目录路径时,也会搜索主机名localhost。在一台备库上,值为replication的数据库字段匹配连接到主库的流复制连接。否则数据库字段的用途有限,因为用户对同一个集簇中的所有数据库都有相同的密码。 + (你可以向该文件增加一个提醒:把上面的行复制到该文件并且在前面加上#)。前四个字段的每一个都可以是字面值或者匹配任何东西的*。第一个匹配当前连接参数的行中的密码字段将被使用(因此,在使用通配符时把更特殊的项放在前面)。如果一个条目需要包含:或者\,用\对该字符转义。如果指定了host连接参数,主机名字段会被匹配到host,否则如果指定了hostaddr参数则匹配到hostaddr,如果两者都没有给出,则会搜索主机名localhost。当连接是一个Unix域套接字连接并且host参数匹配libpq的默认套接字目录路径时,也会搜索主机名localhost。在一台备库上,值为replication的数据库字段匹配连接到主库的流复制连接。否则数据库字段的用途有限,因为用户对同一个集簇中的所有数据库都有相同的密码。 @@ -7637,16 +7780,14 @@ ldap://ldap.acme.com/cn=dbserver,cn=hosts?pgconnectinfo?base?(objectclass=*) - SSL 库初始化 - 如果您的应用程序初始化libssl和/或libcrypto库,并且libpq - 构建时带有SSL支持,您应该调用告诉libpq - libssl和/或libcrypto库已被您的应用程序初始化,以便 - libpq不会再初始化这些库。 - 但是,当使用OpenSSL版本1.1.0或更高版本时,重复初始化不再成问题。 - + 需要兼容旧版 PostgreSQL、使用 OpenSSL 1.0.2 或更早版本的应用程序,需要在使用 SSL 库之前初始化它。自行初始化 libssl 和/或 libcrypto 库的应用程序应调用 ,告知 libpq 这些库已由应用程序初始化,使 libpq 不再初始化它们。不过,使用 OpenSSL 1.1.0 或更高版本时无需这样做,因为重复初始化已不再造成问题。 + + + 有关这些函数的用法,请参阅目标 PostgreSQL 版本的文档。 + @@ -7655,44 +7796,35 @@ ldap://ldap.acme.com/cn=dbserver,cn=hosts?pgconnectinfo?base?(objectclass=*) - 允许应用选择要初始化哪个安全性库。 + 允许应用程序选择要初始化的安全库。 void PQinitOpenSSL(int do_ssl, int do_crypto); - - - 当do_ssl是非零时,libpq将在第一次打开数据库连接前初始化OpenSSL库。 - 当do_crypto是非零时,libcrypto库将被初始化。 - 默认情况下(如果没有调用),两个库都会被初始化。 - 当 SSL 支持没有被编译时,这个函数也存在但是什么也不做。 - 如果你的应用使用并且初始化OpenSSL或者它的底层libcrypto库,你必须在第一次打开数据库连接前以合适的非零参数调用这个函数。 - 同时要确保在打开一个数据库连接前已经完成了初始化。 + 此函数已弃用,仅为向后兼容而保留,不执行任何操作。 PQinitSSLPQinitSSL - - 允许应用选择要初始化哪个安全性库。 + 允许应用程序选择要初始化的安全库。 void PQinitSSL(int do_ssl); + - 这个函数等效于PQinitOpenSSL(do_ssl, do_ssl)。 - 这对于要么初始化OpenSSL以及libcrypto要么都不初始化的应用足够用了。 + 此函数等价于 PQinitOpenSSL(do_ssl, do_ssl)。此函数已弃用,仅为向后兼容而保留,不执行任何操作。 - PostgreSQL 8.0 就存在了, - 而直到PostgreSQL 8.4 才被加入,因此可能对那些需要与旧版本libpq一起工作的应用来说更合适。 + 为向后兼容而保留,但从 PostgreSQL 18 起已不再需要。PostgreSQL 8.0 起就已存在,而 是在 PostgreSQL 8.4 中加入的,因此对于需要兼容旧版本 libpq 的应用程序, 可能更合适。 @@ -7921,8 +8053,8 @@ typedef struct PGoauthBearerRequest 在线程化程序中的行为 - threads - with libpq + 线程 + 用于 libpq diff --git a/zh/18/logical-replication.sgml b/zh/18/logical-replication.sgml index e2e1bbdc..154ae7c5 100644 --- a/zh/18/logical-replication.sgml +++ b/zh/18/logical-replication.sgml @@ -230,7 +230,7 @@ 如前所述,每个(活动)订阅都从远端(发布侧)的一个复制槽接收变更。 - 额外的表同步槽通常是临时的,由系统内部创建用于执行初始表同步,在不再需要时 + 额外的表同步槽通常只会短暂存在,由系统内部创建用于执行初始表同步,在不再需要时 自动删除。这些表同步槽的名称是自动生成的: pg_%u_sync_%u_%llu (参数分别为:订阅 oid、 @@ -422,7 +422,7 @@ 注意在常规复制阶段会使用相应的 publish 操作。 这意味着发布 pub2pub3a 不会复制 - INSERT。另外,发布 pub3b 只会复制与其 + INSERT。另外,发布 pub3b 只会复制与 pub3b 的 行过滤器匹配的数据。现在订阅端数据如下: /* sub # */ SELECT * FROM t1; @@ -617,7 +617,7 @@ HINT: To initiate replication, you must manually create the replication slot, e - 要确认某个订阅对应的备库确实已做好故障切换准备,请按下列步骤验证该订阅需要的 + 要确认备库确实已为某个订阅端做好故障切换准备,请按下列步骤验证该订阅端需要的 所有逻辑复制槽都已同步到备库: @@ -686,7 +686,7 @@ HINT: To initiate replication, you must manually create the replication slot, e 上述步骤中的前两步针对的是 PostgreSQL 订阅端。 - 建议在每次故障切换后,都在将由目标备库服务的各个订阅节点上执行这两步,以获得完整的复制槽 + 建议在每个将于故障切换后由指定备库提供服务的订阅端节点上执行这两步,以获得完整的复制槽 列表,然后在第 3 步中统一验证故障切换就绪状态。 非 PostgreSQL 订阅端则可使用其自身方法识别各自订阅使用的复制槽。 @@ -1757,7 +1757,7 @@ DETAIL: detailed_explanation. 解决方法可以是修改订阅端上的数据或权限,使其不再与传入变更冲突;也可以跳过与 - 现有数据冲突的事务。当冲突导致错误时,复制不会继续,逻辑复制工作者会向订阅端 + 现有数据冲突的事务。当冲突导致错误时,复制不会继续,逻辑复制工作进程会向订阅端 的服务器日志输出如下消息: ERROR: conflict detected on relation "public.test": conflict=insert_exists @@ -1769,8 +1769,8 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER (在上述示例中分别是 LSN 0/14C0378 和复制源 pg_16395)。 可以使用 ALTER SUBSCRIPTION ... SKIP - 并提供 finish LSN(即 LSN 0/14C0378)来跳过产生冲突的事务。这个 finish LSN - 可以是该事务在发布端提交或准备完成时的 LSN。或者,也可以调用 + 并提供 完成 LSN(即 LSN 0/14C0378)来跳过产生冲突的事务。这个 完成 LSN + 可以是该事务在发布端提交或预备时的 LSN。或者,也可以调用 pg_replication_origin_advance() 函数来跳过该事务。 在使用此函数之前,需要暂时禁用订阅,可以使用 @@ -1779,7 +1779,7 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER disable_on_error 选项。然后,可以使用 pg_replication_origin_advance() 函数, 传入 node_name(即 pg_16395) - 以及 finish LSN 的下一个 LSN(即 0/14C0379)。当前各复制源的位置可以在 + 以及 完成 LSN 的下一个 LSN(即 0/14C0379)。当前各复制源的位置可以在 pg_replication_origin_status 系统视图中查看。 请注意,跳过整个事务也会跳过那些本来可能不违反任何约束的变更,这很容易导致 @@ -1794,10 +1794,10 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER streaming - 模式为 parallel 时,失败事务的 finish LSN 可能不会被记录。 + 模式为 parallel 时,失败事务的 完成 LSN 可能不会被记录。 这种情况下,可能需要把 streaming 模式改为 on 或 - off,并再次触发相同的冲突,以便将失败事务的 finish LSN - 写入服务器日志。关于 finish LSN 的用法,请参见 + off,并再次触发相同的冲突,以便将失败事务的 完成 LSN + 写入服务器日志。关于 完成 LSN 的用法,请参见 ALTER SUBSCRIPTION ... SKIP @@ -1815,9 +1815,9 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER 数据库模式和 DDL 命令不会被复制。初始模式可以手工使用 pg_dump --schema-only 复制。之后的模式更改需要手工保持同步。 (不过请注意,两端的模式其实不需要绝对一致。)当活动数据库中的模式定义发生变化时, - 逻辑复制仍然具有一定鲁棒性:如果发布端修改了模式,而复制数据开始到达订阅端时 + 逻辑复制仍然能够稳健运行:如果发布端修改了模式,而复制数据开始到达订阅端时 与表模式不匹配,复制就会报错,直到模式被更新。在很多情况下,可以通过先在订阅端 - 应用增量式的模式变更来避免间歇性错误。 + 应用仅添加内容的模式变更来避免间歇性错误。 @@ -1873,7 +1873,7 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER 对已发布表使用 REPLICA IDENTITY FULL 时,需要注意:如果表中包含某些数据类型的属性(例如 point 或 box),而这些类型 - 没有 B-tree 或 Hash 的默认操作符类,那么 UPDATE 和 + 没有 B-树 或 Hash 的默认操作符类,那么 UPDATEDELETE 操作就无法在订阅端应用。不过,可以通过确保该表具有 主键或已定义复制标识来规避这一限制。 @@ -1915,9 +1915,9 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER 初始快照 对现有订阅表中的初始数据,会取快照并由一种特殊应用进程的并行实例来复制。 - 这些特殊的应用进程是为每张待同步表启动的专用表同步工作者。每个表同步进程 + 这些特殊的应用进程是为每张待同步表启动的专用表同步工作进程。每个表同步进程 都会创建自己的复制槽,并复制现有数据。复制一完成,该表内容就会对其他后端可见。 - 现有数据复制完成后,工作者会进入同步模式,通过标准逻辑复制流式发送在初始数据 + 现有数据复制完成后,工作进程会进入同步模式,通过标准逻辑复制流式发送在初始数据 复制期间发生的任何变更,使该表与主应用进程达到同步状态。在这一同步阶段, 变更会按照它们在发布端发生的顺序被应用和提交。同步完成后,该表的复制控制权 会交还给主应用进程,之后复制将照常继续。 @@ -1931,8 +1931,8 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER - 如果表同步工作者在复制期间失败,应用工作者会检测到这一失败,并重新启动表同步 - 工作者以继续同步过程。这种行为确保了瞬时错误不会永久破坏复制配置。另见 + 如果表同步工作进程在复制期间失败,应用工作进程会检测到这一失败,并重新启动表同步 + 工作进程以继续同步过程。这种行为确保了瞬时错误不会永久破坏复制配置。另见 wal_retrieve_retry_interval @@ -1952,14 +1952,14 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER 与订阅相关的监控信息可在 pg_stat_subscription - 中查看。这个视图为每个订阅工作者包含一行。一个订阅根据其状态,可能有零个或多个 - 活跃的订阅工作者。 + 中查看。这个视图为每个订阅工作进程包含一行。一个订阅根据其状态,可能有零个或多个 + 活跃的订阅工作进程。 通常,一个已启用的订阅会有一个应用进程在运行。被禁用的订阅或已崩溃的订阅在这个 视图中将没有任何行。如果某张表的初始数据同步正在进行,则还会有针对这些正在同步 - 的表的额外工作者。并且,如果使用 + 的表的额外工作进程。并且,如果使用 streaming 并以并行方式应用事务,则还可能出现额外的并行应用工作进程。 @@ -2038,14 +2038,14 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER - 在订阅端,订阅所有者的权限会在每个事务应用时重新检查。如果某个工作者正在应用 + 在订阅端,订阅所有者的权限会在每个事务应用时重新检查。如果某个工作进程正在应用 事务时,订阅的所有权被并发事务更改,那么当前事务的应用仍会继续使用旧所有者的 权限。 - 配置参数 + 配置设置 逻辑复制需要设置若干配置选项。这些选项只在复制的一侧生效。 @@ -2094,7 +2094,7 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER max_logical_replication_workers - 必须至少设置为订阅数量(用于主应用工作进程),再加上用于表同步工作进程 + 必须至少设置为订阅数量(用于领导者应用工作进程),再加上用于表同步工作进程 和并行应用工作进程的预留量。 @@ -2224,8 +2224,8 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER - 旧订阅端中所有订阅表应处于 i(initialize) - 或 r(ready)状态。 + 旧订阅端中所有订阅表应处于 i(初始化) + 或 r(就绪)状态。 可通过检查 pg_subscription_rel.srsubstate 验证。 diff --git a/zh/18/logicaldecoding.sgml b/zh/18/logicaldecoding.sgml index a6cc353f..b62e246f 100644 --- a/zh/18/logicaldecoding.sgml +++ b/zh/18/logicaldecoding.sgml @@ -357,7 +357,7 @@ postgres=# select * from pg_logical_slot_get_changes('regression_slot', NULL, NU 中列出的槽,向逻辑订阅者发送更改时仍然会有一定延迟。使用 synchronized_standby_slots 时,主库在与 synchronized_standby_slots 中指定的物理复制槽相关联 - 的备库确认已接收到截至主库最新刷写位置的 WAL 之前,不会完全关闭。 + 的备库确认已接收到截至主库最新刷盘位置的 WAL 之前,不会完全关闭。 diff --git a/zh/18/maintenance.sgml b/zh/18/maintenance.sgml index 4479ecc8..cf5227de 100644 --- a/zh/18/maintenance.sgml +++ b/zh/18/maintenance.sgml @@ -383,11 +383,11 @@ 如果一个表正在积累全部可见但尚未全部冻结的页面,普通清理可能会选择扫描这些本可跳过的页面, 以尝试冻结它们。这样可以减少下一次激进扫描必须扫描的页面数。这类页面称为 - 积极扫描页。通过增大 ,可以调整积极扫描, - 使其尝试冻结更多全部可见页面。即使积极扫描已将全部可见但未全部冻结页面的数量降到最低, - 大多数表仍然需要周期性地进行激进扫描。不过,任何成功被积极冻结的页面在激进扫描时都可以跳过, - 因此积极冻结可以尽量减小激进扫描的开销。 + 急切扫描页。通过增大 ,可以调整急切扫描, + 使其尝试冻结更多全部可见页面。即使急切扫描已将全部可见但未全部冻结页面的数量降到最低, + 大多数表仍然需要周期性地进行激进扫描。不过,任何成功被急切冻结的页面在激进扫描时都可以跳过, + 因此急切冻结可以尽量减小激进扫描的开销。 @@ -403,7 +403,7 @@ 一个表在不被清理的情况下所能维持的最长时间,是最后一次激进扫描时的 vacuum_freeze_min_age 值从 20 亿事务中扣除后的结果。 如果超过这个时间仍不清理,就可能导致数据丢失。为了确保不会发生这种情况, - 任何可能包含未冻结行且其 XID 早于配置参数 所指定年龄的表,都会触发自动清理。 (即使自动清理已被禁用,也会如此。) @@ -492,11 +492,10 @@ SELECT datname, age(datfrozenxid) FROM pg_database; 虽然 VACUUM 主要扫描自上次清理以来被修改过的页面, - 但它也可能为了冻结它们而积极扫描某些全部可见但未全部冻结的页面; + 但它也可能为了冻结它们而急切扫描某些全部可见但未全部冻结的页面; 不过,只有当表中每一个可能包含未冻结 XID 的页面都被扫描时, relfrozenxid 才会被推进。当 - relfrozenxid 比 - vacuum_freeze_table_age 旧、使用了 VACUUM 的 + relfrozenxid的年龄超过vacuum_freeze_table_age个事务、使用了 VACUUMFREEZE 选项,或者所有尚未全部冻结的页面碰巧都需要清理以移除死行版本时, 就会发生这种情况。当 VACUUM 扫描了表中每个尚未全部冻结的页面时, 它应把 age(relfrozenxid) 设为略高于所用 @@ -595,22 +594,22 @@ HINT: Execute a database-wide VACUUM in that database. 多事务(multitransaction,MultiXact) ID 用于支持多个事务对行加锁。由于元组头中用于存储锁信息的空间有限, 当有多个事务同时锁定一行时,这些信息会被编码为一个多事务 ID, - 简称 multixact ID。某个特定 multixact ID 包含哪些事务 ID 的信息, + 简称 multixact ID。某个特定 多事务 ID 包含哪些事务 ID 的信息, 会单独存放在 pg_multixact 子目录中,而元组头的 - xmax 字段中只出现 multixact ID。和事务 ID 一样, - multixact ID 也是以 32 位计数器及其对应存储实现的,因此同样需要仔细处理老化管理、 - 存储清理和回卷问题。还有一个单独的存储区域保存每个 multixact 的成员列表, + xmax 字段中只出现 多事务 ID。和事务 ID 一样, + 多事务 ID 也是以 32 位计数器及其对应存储实现的,因此同样需要仔细处理老化管理、 + 存储清理和回卷问题。还有一个单独的存储区域保存每个 多事务 的成员列表, 它也使用 32 位计数器,因此同样必须被管理。 中介绍的系统函数 pg_get_multixact_members() - 可用于检查与某个 multixact ID 关联的事务 ID。 + 可用于检查与某个 多事务 ID 关联的事务 ID。 每当 VACUUM 扫描表的任何部分时,它都会把遇到的、早于 - 的任何 multixact ID 替换为另一个值,该值可能是零值、单个事务 ID,或者更新的 multixact ID。 + 的任何 多事务 ID 替换为另一个值,该值可能是零值、单个事务 ID,或者更新的 多事务 ID。 对于每个表,pg_class.relminmxid - 保存该表任何元组中仍可能出现的最老 multixact ID。如果这个值早于 + 保存该表任何元组中仍可能出现的最老 多事务 ID。如果这个值早于 ,就会强制执行一次激进扫描。 正如上一节所述,激进扫描意味着只有那些已知为全部冻结的页面才会被跳过。 可以对 pg_class.relminmxid @@ -620,14 +619,14 @@ HINT: Execute a database-wide VACUUM in that database. 无论出于何种原因而发生,激进的 VACUUM保证 能够推进表的 relminmxid。最终,随着所有数据库中的所有表都被扫描, - 并推进其最老的 multixact 值,较老 multixact 的磁盘存储就可以被移除。 + 并推进其最老的 多事务 值,较老 多事务 的磁盘存储就可以被移除。 - 作为一项安全措施,对于 multixact 年龄大于 的任何表,都会进行一次激进扫描。 - 此外,如果 multixact 成员占用的存储超过大约 10GB,则会更频繁地对所有表进行激进扫描, - 从 multixact 年龄最老的表开始。即便自动清理名义上被禁用,这两类激进扫描也都会发生。 + 此外,如果 多事务 成员占用的存储超过大约 10GB,则会更频繁地对所有表进行激进扫描, + 从 多事务 年龄最老的表开始。即便自动清理名义上被禁用,这两类激进扫描也都会发生。 成员存储区域在到达回卷之前最多可增长到大约 20GB。 @@ -644,11 +643,11 @@ HINT: Execute a database-wide VACUUM in that database. - 如果没有可能出现在 multixact 中,那么正在运行的事务和预备事务都可以忽略。 + 如果没有可能出现在 多事务 中,那么正在运行的事务和预备事务都可以忽略。 - 与事务 ID 回卷不同,复制槽不会直接阻止 multixact 清理。 - 因此,删除陈旧的复制槽通常与解决 multixact ID 回卷问题无关。 + 与事务 ID 回卷不同,复制槽不会直接阻止 多事务 清理。 + 因此,删除陈旧的复制槽通常与解决 多事务 ID 回卷问题无关。 MXID 信息不会直接出现在诸如 pg_stat_activity 这样的系统视图中; @@ -704,7 +703,7 @@ HINT: Execute a database-wide VACUUM in that database. - 对于 relfrozenxid 值早于 + 对于 relfrozenxid值的年龄超过 个事务的表,总是会执行清理 (这也适用于那些通过存储参数修改了冻结最大年龄的表,见下文)。 否则,如果自上次 VACUUM 以来已经失效的元组数超过了 @@ -743,7 +742,7 @@ vacuum insert threshold = vacuum base insert threshold + vacuum insert scale fac 因为这会让元组在更早的清理中被冻结。过时元组数和插入元组数取自累积统计系统; 这是一个由每次 UPDATEDELETEINSERT 操作更新的最终一致计数。如果该表的 - relfrozenxid 值早于 + relfrozenxid值的年龄超过 vacuum_freeze_table_age 个事务,就会执行一次激进扫描, 以冻结旧元组并推进 relfrozenxid @@ -944,7 +943,7 @@ pg_ctl start | rotatelogs /var/log/pgsql_log 86400 不过,在很多系统上,syslog 并不十分可靠, 尤其是在日志消息很大时;它可能恰恰在你最需要消息的时候截断或丢弃它们。 此外,在 Linux 上, - syslog 会把每条消息都刷新到磁盘,导致性能较差。 + syslog 会把每条消息都刷盘,导致性能较差。 (你可以在 syslog 配置文件的文件名开头使用一个 - 来禁用同步。) diff --git a/zh/18/monitoring.sgml b/zh/18/monitoring.sgml index c38bc88c..fc12a802 100644 --- a/zh/18/monitoring.sgml +++ b/zh/18/monitoring.sgml @@ -87,15 +87,15 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - 累计统计系统 + 累积统计系统 - statistics + 统计信息 PostgreSQL累积统计系统支持收集和报告有关服务器活动的信息。 - 目前,对表和索引的访问以磁盘块和单个行的术语进行计数。每个表中的总行数, + 目前,对表和索引的访问分别以磁盘块和单行计数。每个表中的总行数, 以及每个表的清理和分析操作的信息也被计数。如果启用,对用户定义函数的调用 和每个函数中花费的总时间也会被计数。 @@ -107,7 +107,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - 统计收集配置 + 统计信息收集配置 由于收集统计信息会增加查询执行的开销,因此可以配置系统是否收集信息。这由通常在postgresql.conf中设置的配置参数控制(有关设置配置参数的详细信息,请参阅)。 @@ -160,11 +160,11 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - 另一个重要的观点是,当服务器进程被要求显示任何累积的统计信息时,在默认配置中,访问的值会被缓存直到当前事务结束。因此,只要您继续当前事务,统计信息将显示静态信息。类似地,当在事务中首次请求任何当前会话的查询信息时,会收集关于所有会话当前查询的信息,并且相同的信息将在整个事务中显示。这是一个特性,而不是一个错误,因为它允许您在统计信息上执行多个查询并将结果相关联,而不必担心数字在您眼前发生变化。 + 另一个重要的观点是,当服务器进程被要求显示任何累积的统计信息时,在默认配置中,访问的值会被缓存直到当前事务结束。因此,只要你继续当前事务,统计信息将显示静态信息。类似地,当在事务中首次请求这类当前查询信息时,会收集关于所有会话当前查询的信息,并且相同的信息将在整个事务中显示。这是一个特性,而不是一个错误,因为它允许你在统计信息上执行多个查询并将结果相关联,而不必担心数字在你眼前发生变化。 - 在交互式分析统计信息或使用昂贵的查询时,访问各个统计信息之间的时间差可能导致缓存统计信息中出现显著的偏差。为了最小化偏差,可以将stats_fetch_consistency设置为snapshot,但这会增加用于缓存不需要的统计数据的内存使用量。相反,如果已知统计信息只被访问一次,那么缓存访问的统计信息是不必要的,可以通过将stats_fetch_consistency设置为none来避免。 + 在交互式分析统计信息或使用开销较大的查询时,访问各个统计信息之间的时间差可能导致缓存统计信息中出现显著的偏差。为了最小化偏差,可以将stats_fetch_consistency设置为snapshot,但这会增加用于缓存不需要的统计数据的内存使用量。相反,如果已知统计信息只被访问一次,那么缓存访问的统计信息是不必要的,可以通过将stats_fetch_consistency设置为none来避免。 - 您可以调用pg_stat_clear_snapshot()来丢弃当前事务的统计快照或缓存的值(如果有)。下一次使用统计信息时(在快照模式下),将会创建一个新的快照,或者(在缓存模式下)将访问的统计信息缓存起来。 + 你可以调用pg_stat_clear_snapshot()来丢弃当前事务的统计快照或缓存的值(如果有)。下一次使用统计信息时(在快照模式下),将会创建一个新的快照,或者(在缓存模式下)将访问的统计信息缓存起来。 @@ -176,11 +176,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 相反,它们在事务期间持续更新。 - - 动态统计视图中显示的一些信息在中受到安全限制。 - 普通用户只能查看关于他们自己会话的所有信息(属于他们是成员的角色的会话)。在关于其他会话的行中,许多列将为空。 - 但是,请注意,所有用户都可以看到会话的存在以及其一般属性,如会话用户和数据库。超级用户和具有内置角色pg_read_all_stats权限的角色(另请参阅)可以查看所有会话的所有信息。 - + 所列动态统计视图中的一些信息受到安全限制。普通用户只能查看其自身会话的全部信息(包括属于其所加入角色的会话)。对于其他会话的行,许多列将为空值。不过,会话的存在及其一般属性(例如会话用户和数据库)对所有用户都可见。超级用户和具有内置角色pg_read_all_stats权限的角色可以查看所有会话的全部信息。
@@ -215,7 +211,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser pg_stat_wal_receiverpg_stat_wal_receiver - 只有一行,显示有关 WAL 接收进程从其连接服务器接收到的统计信息。有关详细信息,请参阅pg_stat_wal_receiver。 + 只有一行,显示 WAL 接收进程从其所连接服务器接收数据的统计信息。有关详细信息,请参阅pg_stat_wal_receiver @@ -305,42 +301,57 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - + pg_stat_bgwriterpg_stat_bgwriter 只有一行,显示有关后台写入器活动的信息。有关详细信息,请参阅pg_stat_bgwriter - + pg_stat_checkpointerpg_stat_checkpointer 只有一行,显示有关检查点进程活动的信息。有关详细信息,请参阅pg_stat_checkpointer - + + pg_stat_databasepg_stat_database + 每个数据库一行,显示数据库范围的统计信息。有关详细信息,请参阅pg_stat_database。 + + + + + pg_stat_database_conflictspg_stat_database_conflicts + 每个数据库一行,显示数据库范围内因备库上的恢复冲突而导致查询被取消的统计信息。有关详细信息,请参阅pg_stat_database_conflicts + + + pg_stat_iopg_stat_io 对于每种后端类型、上下文和目标对象的组合各有一行,包含集簇范围的 I/O 统计信息。有关详细信息,请参阅pg_stat_io - - pg_stat_walpg_stat_wal - 只有一行,显示有关 WAL 活动的统计信息。有关详细信息,请参阅pg_stat_wal。 - + + pg_stat_replication_slotspg_stat_replication_slots + 每个复制槽一行,显示有关复制槽使用情况的统计信息。有关详细信息,请参阅pg_stat_replication_slots - - pg_stat_databasepg_stat_database - 每个数据库一行,显示数据库范围的统计信息。有关详细信息,请参阅pg_stat_database。 - + + pg_stat_slrupg_stat_slru + 每个 SLRU 一行,显示操作统计信息。有关详细信息,请参阅pg_stat_slru - - pg_stat_database_conflictspg_stat_database_conflicts - 每个数据库一行,显示数据库范围内因备库上的恢复冲突而导致查询被取消的统计信息。有关详细信息,请参阅pg_stat_database_conflicts + + pg_stat_subscription_statspg_stat_subscription_stats + 每个订阅一行,显示有关错误和冲突的统计信息。有关详细信息,请参阅pg_stat_subscription_stats - + + pg_stat_walpg_stat_wal + 只有一行,显示有关 WAL 活动的统计信息。有关详细信息,请参阅pg_stat_wal。 + + + + pg_stat_all_tablespg_stat_all_tables 当前数据库中每个表一行,显示有关访问指定表的统计信息。详见 @@ -348,116 +359,101 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - + pg_stat_sys_tablespg_stat_sys_tables pg_stat_all_tables一样,但只显示系统表。 - + pg_stat_user_tablespg_stat_user_tables pg_stat_all_tables一样,但只显示用户表。 - + pg_stat_xact_all_tablespg_stat_xact_all_tables - pg_stat_all_tables相似,但计数动作只在当前事务内发生(还没有被包括在pg_stat_all_tables和相关视图中)。用于生存和死亡行数量的列以及清理和分析动作在此视图中不出现。 + pg_stat_all_tables 相似,但只统计当前事务中截至目前执行的操作(这些操作尚计入 pg_stat_all_tables 及相关视图)。此视图不包含存活行和死行数量以及清理、分析操作的列。 - + pg_stat_xact_sys_tablespg_stat_xact_sys_tables pg_stat_xact_all_tables一样,但只显示系统表。 - + pg_stat_xact_user_tablespg_stat_xact_user_tables pg_stat_xact_all_tables一样,但只显示用户表。 - + pg_stat_all_indexespg_stat_all_indexes 当前数据库中的每个索引一行,显示有关访问该特定索引的统计信息。有关详细信息,请参阅pg_stat_all_indexes - + pg_stat_sys_indexespg_stat_sys_indexes pg_stat_all_indexes一样,但只显示系统表上的索引。 - + pg_stat_user_indexespg_stat_user_indexes pg_stat_all_indexes一样,但只显示用户表上的索引。 - + + pg_stat_user_functionspg_stat_user_functions + 每个被跟踪的函数一行,显示有关该函数执行的统计信息。有关详细信息,请参阅pg_stat_user_functions + + + + pg_stat_xact_user_functionspg_stat_xact_user_functions + pg_stat_user_functions相似,但是只统计在当前事务期间的调用(还没有被包括在pg_stat_user_functions中)。 + + + pg_statio_all_tablespg_statio_all_tables 当前数据库中的每个表一行,显示有关访问该特定表的 I/O 统计信息。有关详细信息,请参阅pg_statio_all_tables - + pg_statio_sys_tablespg_statio_sys_tables pg_statio_all_tables一样,但只显示系统表。 - + pg_statio_user_tablespg_statio_user_tables pg_statio_all_tables一样,但只显示用户表。 - + pg_statio_all_indexespg_statio_all_indexes 当前数据库中的每个索引一行,显示有关访问该特定索引的 I/O 统计信息。有关详细信息,请参阅pg_statio_all_indexes - + pg_statio_sys_indexespg_statio_sys_indexes pg_statio_all_indexes一样,但只显示系统表上的索引。 - + pg_statio_user_indexespg_statio_user_indexes pg_statio_all_indexes一样,但只显示用户表上的索引。 - + pg_statio_all_sequencespg_statio_all_sequences 当前数据库中的每个序列一行,显示有关访问该特定序列的 I/O 统计信息。有关详细信息,请参阅pg_statio_all_sequences - + pg_statio_sys_sequencespg_statio_sys_sequences pg_statio_all_sequences一样,但只显示系统序列(目前没有定义系统序列,因此这个视图总是为空)。 - + pg_statio_user_sequencespg_statio_user_sequences pg_statio_all_sequences一样,但只显示用户序列。 - - pg_stat_user_functionspg_stat_user_functions - 每个被跟踪的函数一行,显示有关该函数执行的统计信息。有关详细信息,请参阅pg_stat_user_functions - - - - pg_stat_xact_user_functionspg_stat_xact_user_functions - pg_stat_user_functions相似,但是只统计在当前事务期间的调用(还没有被包括在pg_stat_user_functions中)。 - - - - pg_stat_slrupg_stat_slru - 每个 SLRU 一行,显示操作统计信息。有关详细信息,请参阅pg_stat_slru - - - - pg_stat_replication_slotspg_stat_replication_slots - 每个复制槽一行,显示有关复制槽使用情况的统计信息。有关详细信息,请参阅pg_stat_replication_slots - - - - pg_stat_subscription_statspg_stat_subscription_stats - 每个订阅一行,显示有关错误和冲突的统计信息。有关详细信息,请参阅pg_stat_subscription_stats - -
@@ -533,7 +529,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser leader_pid integer
- 如果该进程是并行查询工作进程,则为并行组领导者的进程 ID;如果该进程是并行应用工作进程,则为领导应用工作进程的进程 ID。NULL 表示该进程是并行组领导者或领导应用工作进程,或者不参与任何并行操作。 + 如果该进程是并行查询工作进程,则为并行组领导者的进程 ID;如果该进程是并行应用工作进程,则为领导者应用工作进程的进程 ID。NULL 表示该进程是并行组领导者或领导者应用工作进程,或者不参与任何并行操作。 @@ -569,7 +565,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser client_addr inet
- 连接到这个后端的客户端的 IP 地址。如果这个字段为空,它表示客户端通过服务器机器上的一个 Unix 套接字连接或者这是一个内部进程,如自动清理。 + 连接到这个后端的客户端的 IP 地址。如果这个字段为空值,它表示客户端通过服务器机器上的一个 Unix 套接字连接或者这是一个内部进程,如自动清理。 @@ -588,7 +584,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser client_port integer
- 客户端用于与此后端通信的TCP端口号,如果使用Unix套接字,则为-1。如果该字段为空,它表示这是一个内部服务器进程。 + 客户端用于与此后端通信的TCP端口号,如果使用Unix套接字,则为-1。如果该字段为空值,它表示这是一个内部服务器进程。 @@ -606,8 +602,8 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser xact_start timestamp with time zone
- 这个进程的当前事务被启动的时间,如果没有活动事务则为空。 - 如果当前查询是它的第一个事务,这一列等于query_start列。 + 这个进程的当前事务被启动的时间,如果没有活动事务则为空值。 + 如果当前查询是其事务中的第一个查询,这一列等于query_start列。 @@ -634,7 +630,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser wait_event_type text - 后端正在等待的事件类型(如果有);否则为NULL。请参阅。 + 后端正在等待的事件类型(如果有);否则为空值。请参阅 @@ -643,7 +639,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser wait_event text - 如果此后端当前正在等待,则返回等待事件名称,否则为NULL。请参阅。 + 如果此后端当前正在等待,则返回等待事件名称,否则为空值。请参阅 @@ -651,44 +647,29 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser state text - - 这个后端的当前总体状态。可能的值为: - + 该后端当前的总体状态。可能的值为: - starting: 后端正处于初始启动阶段。客户端认证在此阶段执行。 + starting: 后端正处于初始启动阶段。客户端认证在此阶段执行。 - - active: 后端正在执行一个查询。 - + active:后端正在执行一个查询。 - - idle: 后端正在等待一个新的客户端命令。 - + idle:后端正在等待新的客户端命令。 - - idle in transaction: 后端在一个事务中,但是当前没有正在执行一个查询。 - + idle in transaction:后端处于事务中,但当前没有执行查询。 - - idle in transaction (aborted): 这个状态与 - idle in transaction相似,除了在该事务中的一个语句导致了一个错误。 - + idle in transaction (aborted):该状态与idle in transaction类似,但事务中的某个语句导致了错误。 - - fastpath function call: 后端正在执行一个 fast-path 函数。 - + fastpath function call:后端正在执行一个快速路径函数。 - - disabled: 如果在这个后端中被禁用,则报告这个状态。 - + disabled:如果在此后端中禁用了,就会报告此状态。 @@ -698,9 +679,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser backend_xid xid - - 这个后端的顶层事务 ID,如果存在。 - + 这个后端的顶层事务 ID(如果存在);请参阅 @@ -708,7 +687,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser backend_xmin xid - 当前后端的xmin范围。 + 当前后端的xmin视界。 @@ -720,7 +699,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 这个后端的最近查询的标识符。 如果stateactive,这个字段显示当前正在执行的查询的标识符。 在所有其他状态,它显示执行的最后一个查询的标识符。 - 默认不计算查询标识符,因此该字段将为空,除非启用参数或配置了计算查询标识符的第三方模块。 + 默认不计算查询标识符,因此该字段将为空值,除非启用参数或配置了计算查询标识符的第三方模块。 @@ -738,19 +717,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser backend_type text - - 当前后端的类型。可能的类型为 - autovacuum launcher, autovacuum worker, - logical replication launcher, - logical replication worker, - parallel worker, background writer, - client backend, checkpointer, - archiver, standalone backend, - startup, walreceiver, - walsender, walwriter 以及 - walsummarizer。 - 此外,由扩展注册的后台工作进程还可能有额外的类型。 - + 当前后端的类型。可能的类型为autovacuum launcherautovacuum workerlogical replication launcherlogical replication workerparallel workerbackground writerclient backendcheckpointerarchiverstandalone backendstartupwalreceiverwalsenderwalwriterwalsummarizer。此外,由扩展注册的后台工作进程还可能有额外的类型。 @@ -759,7 +726,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - wait_eventstate列彼此独立。如果某个后端处于active状态,它既可能正在等待某个事件,也可能没有等待。如果状态为activewait_event非空,就意味着某个查询正在执行,但在系统中的某处被阻塞了。为将报告开销保持在较低水平,系统不会尝试为某个后端同步活动数据的不同方面。因此,视图各列之间可能暂时存在不一致。 + wait_eventstate列彼此独立。如果某个后端处于active状态,它可能正在等待(waiting)某个事件,也可能没有等待。如果状态为activewait_event非空,就意味着某个查询正在执行,但在系统中的某处被阻塞了。为将报告开销保持在较低水平,系统不会尝试为某个后端同步活动数据的不同方面。因此,视图各列之间可能暂时存在不一致。 @@ -786,10 +753,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser BufferPin - 服务器进程正在等待对数据缓冲的独占访问。 - 如果另一个进程持有一个打开的游标,该游标最后一次从相关缓冲区读取数据,则缓冲区销等待可能是漫长的。 - 参见。 - + 服务器进程正在等待独占访问一个数据缓冲区。如果另一个进程持有尚未关闭的游标,且该游标最近读取的数据来自此缓冲区,缓冲区钉住等待就可能持续较长时间。参见 @@ -812,7 +776,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser IO - 服务器进程正在等待一个I/O操作完成。wait_event将识别特定的等待点;参见。 + 服务器进程正在等待一个 I/O 操作完成。wait_event将识别特定的等待点;参见 @@ -824,17 +788,14 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser Lock - 服务器进程正在等待一个重量级锁。重量级锁,也称为锁管理器锁或简单锁,主要保护表等SQL可见对象。 + 服务器进程正在等待一个重量级锁。重量级锁,也称为锁管理器锁或简称为锁,主要保护表等SQL可见对象。 然而,它们也用于确保某些内部操作的互斥,例如关系扩展。wait_event将识别等待的锁的类型;参见 LWLock - 服务器进程正在等待一个轻量级锁。大多数这样的锁保护共享内存中的特定数据结构。 - wait_event将包含标识轻量级锁用途的名称。 - (有些锁有特定的名称;其他锁是一组锁的一部分,每个锁具有类似的目的。)参见。 - + 服务器进程正在等待一个轻量级锁。大多数这样的锁保护共享内存中的某个特定数据结构。wait_event将包含标识该轻量级锁用途的名称。(有些锁具有专门的名称,另一些锁属于一组用途相似的锁。)参见 @@ -866,17 +827,17 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - AutoVacuumMain - 在自动清理启动过程的主循环中等待。 + AutovacuumMain + 在自动清理启动进程的主循环中等待。 - BgWriterHibernate - 在后台写入器中等待,休眠状态。 + BgwriterHibernate + 在后台写入器进程中休眠等待。 - BgWriterMain + BgwriterMain 在后台写入器主循环中等待。 @@ -885,6 +846,16 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 在检查点进程的主循环中等待。 + + CheckpointerShutdown + 等待检查点进程终止。 + + + + IoWorkerMain + 在 I/O 工作进程的主循环中等待。 + + LogicalApplyMain 在逻辑复制应用进程的主循环中等待。 @@ -895,19 +866,34 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 在逻辑复制启动器进程的主循环中等待。 + + LogicalParallelApplyMain + 在逻辑复制并行应用进程的主循环中等待。 + + RecoveryWalStream - 流恢复期间,在启动进程主循环等待WAL到达。 + 在流恢复期间,在启动进程的主循环中等待 WAL 到达。 + + + + ReplicationSlotsyncMain + 在复制槽同步工作进程的主循环中等待。 + + + + ReplicationSlotsyncShutdown + 等待复制槽同步工作进程关闭。 - SysLoggerMain + SysloggerMain 在 syslogger 进程的主循环中等待。 WalReceiverMain - 在WAL 接收进程的主循环中等待。 + 在 WAL 接收进程的主循环中等待。 @@ -915,9 +901,14 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 在 WAL 发送进程的主循环中等待。 + + WalSummarizerWal + 在 WAL 汇总进程中等待生成更多 WAL。 + + WalWriterMain - 在WAL写入进程的主循环中等待。 + 在 WAL 写入进程的主循环中等待。 @@ -939,7 +930,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser BufferPin - 等待获得缓冲区上的独占销。 + 等待获得缓冲区上的独占钉住。 @@ -970,28 +961,33 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - GSSOpenServer + GssOpenServer 在建立GSSAPI会话时等待从客户端读取数据。 - LibPQWalReceiverConnect - 在WAL 接收进程等待与远程服务器建立连接。 + LibpqwalreceiverConnect + 在 WAL 接收进程中等待与远程服务器建立连接。 - LibPQWalReceiverReceive - 在WAL 接收进程中等待从远程服务器接收数据。 + LibpqwalreceiverReceive + 在 WAL 接收进程中等待从远程服务器接收数据。 - SSLOpenServer + SslOpenServer 在尝试连接时等待SSL。 - WalSenderWaitForWAL - 在 WAL 发送进程中等待 WAL 被刷新。 + WaitForStandbyConfirmation + 等待物理备库接收 WAL 并将其刷盘。 + + + + WalSenderWaitForWal + 在 WAL 发送进程中等待 WAL 刷盘。 @@ -1039,33 +1035,48 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - BaseBackupRead + AioIoCompletion + 等待另一个进程完成 I/O。 + + + + AioIoUringExecution + 等待通过 io_uring 执行 I/O。 + + + + AioIoUringSubmit + 等待通过 io_uring 提交 I/O。 + + + + BasebackupRead 等待基础备份从文件中读取。 - BaseBackupSync - 等待由基础备份写入的数据达到持久存储。 + BasebackupSync + 等待基础备份写入的数据同步到持久存储。 - BaseBackupWrite + BasebackupWrite 等待基础备份写入文件。 - BufFileRead + BuffileRead 等待从缓冲文件中读取。 - BufFileWrite - 等待对缓冲文件的写入。 + BuffileTruncate + 等待一个缓冲文件被截断。 - BufFileTruncate - 等待一个缓冲文件被截断。 + BuffileWrite + 等待对缓冲文件的写入。 @@ -1075,12 +1086,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser ControlFileSync - 等待pg_control文件到达持久存储。 + 等待 pg_control 文件同步到持久存储。 ControlFileSyncUpdate - 等待更新pg_control文件以达到持久存储。 + 等待对 pg_control 文件的更新同步到持久存储。 @@ -1090,22 +1101,22 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser ControlFileWriteUpdate - 等待写入更新pg_control文件。 + 等待写入以更新 pg_control 文件。 - CopyFileRead - 在文件复制操作期间等待读取。 + CopyFileCopy + 等待文件复制操作。 - CopyFileWrite - 在文件拷贝操作期间等待写入。 + CopyFileRead + 在文件复制操作期间等待读取。 - DSMFillZeroWrite - 等待用零填充动态共享内存备份(backing)文件。 + CopyFileWrite + 在文件复制操作期间等待写入。 @@ -1115,12 +1126,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser DataFileFlush - 等待关系数据文件达到持久存储。 + 等待关系数据文件同步到持久存储。 DataFileImmediateSync - 等待关系数据文件到持久存储的立即同步。 + 等待关系数据文件立即同步到持久存储。 @@ -1135,7 +1146,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser DataFileSync - 等待对关系数据文件的更改达到持久存储。 + 等待对关系数据文件的更改同步到持久存储。 @@ -1149,17 +1160,27 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - LockFileAddToDataDirRead + DsmAllocate + 等待分配动态共享内存段。 + + + + DsmFillZeroWrite + 等待用零填充动态共享内存的后备文件。 + + + + LockFileAddtodatadirRead 在向数据目录锁文件中添加一行时等待读取。 - LockFileAddToDataDirSync - 等待数据到达持久存储,同时向数据目录锁文件添加一行。 + LockFileAddtodatadirSync + 在向数据目录锁文件中添加一行时,等待数据同步到持久存储。 - LockFileAddToDataDirWrite + LockFileAddtodatadirWrite 在向数据目录锁文件中添加一行时等待写操作。 @@ -1170,7 +1191,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser LockFileCreateSync - 在创建数据目录锁文件时等待数据到达持久存储。 + 在创建数据目录锁文件时,等待数据同步到持久存储。 @@ -1179,18 +1200,18 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - LockFileReCheckDataDirRead + LockFileRecheckdatadirRead 在重新检查数据目录锁文件期间等待读取。 LogicalRewriteCheckpointSync - 等待逻辑重写映射到在检查点到达持久存储。 + 在检查点期间等待逻辑重写映射同步到持久存储。 LogicalRewriteMappingSync - 在逻辑重写期间等待映射数据到达持久存储 + 在逻辑重写期间等待映射数据同步到持久存储。 @@ -1200,12 +1221,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser LogicalRewriteSync - 等待逻辑重写映射到达持久存储。 + 等待逻辑重写映射同步到持久存储。 LogicalRewriteTruncate - 等待在逻辑重写期间截断映射数据。 + 在逻辑重写期间等待截断映射数据。 @@ -1219,8 +1240,8 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - RelationMapSync - 等待关系映射文件到达持久存储。 + RelationMapReplace + 等待关系映射文件的替换结果同步到持久存储。 @@ -1230,17 +1251,17 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser ReorderBufferRead - 在重新排序缓冲区管理期间等待读取。 + 在重排序缓冲区管理期间等待读取。 ReorderBufferWrite - 在重新排序缓冲区管理期间等待写操作。 + 在重排序缓冲区管理期间等待写入。 ReorderLogicalMappingRead - 在重新排序缓冲区管理期间等待读取逻辑映射。 + 在重排序缓冲区管理期间等待读取逻辑映射。 @@ -1250,12 +1271,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser ReplicationSlotRestoreSync - 等待复制槽控制文件到达持久存储,同时将其恢复到内存中。 + 在将复制槽控制文件恢复到内存期间,等待该文件同步到持久存储。 ReplicationSlotSync - 等待复制槽控制文件到达持久存储。 + 等待复制槽控制文件同步到持久存储。 @@ -1264,43 +1285,43 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - SLRUFlushSync - 在检查点或数据库关闭期间等待SLRU数据到达持久存储。 + SlruFlushSync + 在检查点或数据库关闭期间,等待 SLRU 数据同步到持久存储。 - SLRURead + SlruRead 等待读取SLRU页面。 - SLRUSync - 在写页面后等待SLRU数据到达持久存储。 + SlruSync + 在页面写入后等待 SLRU 数据同步到持久存储。 - SLRUWrite + SlruWrite 等待SLRU页面的写入。 SnapbuildRead - 等待读取序列化的历史目录快照。 + 等待读取序列化的历史系统目录快照。 SnapbuildSync - 等待序列化历史目录快照到达持久存储。 + 等待序列化的历史系统目录快照同步到持久存储。 SnapbuildWrite - 等待串行历史目录快照的写入。 + 等待写入序列化的历史系统目录快照。 TimelineHistoryFileSync - 等待通过流复制接收的时间线历史文件到达持久存储。 + 等待通过流复制接收的时间线历史文件同步到持久存储。 @@ -1315,7 +1336,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser TimelineHistorySync - 等待新创建的时间线历史文件到达持久存储。 + 等待新创建的时间线历史文件同步到持久存储。 @@ -1330,7 +1351,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser TwophaseFileSync - 等待两阶段状态文件到达持久存储。 + 等待两阶段状态文件同步到持久存储。 @@ -1340,7 +1361,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser VersionFileSync - 等待版本文件达到持久存储,同时创建数据库。 + 在创建数据库时,等待版本文件同步到持久存储。 @@ -1349,63 +1370,73 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - WALBootstrapSync - 在引导过程中等待WAL达到持久存储。 + WalsenderTimelineHistoryRead + 在 WAL 发送进程执行时间线命令期间,等待从时间线历史文件读取。 + + + + WalBootstrapSync + 在引导过程中等待 WAL 同步到持久存储。 - WALBootstrapWrite + WalBootstrapWrite 在引导过程中等待WAL页面的写入。 - WALCopyRead + WalCopyRead 通过复制一个已有WAL段来创建一个新的WAL段时等待读取。 - WALCopySync - 等待通过复制一个已有WAL段到持久存储来创建一个新的WAL段。 + WalCopySync + 等待通过复制现有 WAL 段创建的新 WAL 段同步到持久存储。 - WALCopyWrite + WalCopyWrite 通过复制一个已有WAL段来创建一个新的WAL段时等待写入。 - WALInitSync - 等待一个新初始化的WAL文件到持久存储。 + WalInitSync + 等待新初始化的 WAL 文件同步到持久存储。 - WALInitWrite + WalInitWrite 在初始化一个新的WAL文件时等待写入。 - WALRead + WalRead 等待WAL文件的读取。 - WALSenderTimelineHistoryRead - 在walsender时间线命令期间等待从时间线历史文件读取。 + WalSummaryRead + 等待从 WAL 汇总文件读取。 - WALSync - 等待WAL文件到达持久存储。 + WalSummaryWrite + 等待写入 WAL 汇总文件。 - WALSyncMethodAssign - 等待数据到达持久存储,同时分配一个新的WAL同步方法。 + WalSync + 等待 WAL 文件同步到持久存储。 - WALWrite - 等待写入WAL文件。 + WalSyncMethodAssign + 在设置新的 WAL 同步方法时,等待数据同步到持久存储。 + + + + WalWrite + 等待写入 WAL 文件。 @@ -1451,23 +1482,33 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - BgWorkerShutdown + BgworkerShutdown 等待后台工作进程关闭。 - BgWorkerStartup + BgworkerStartup 等待后台工作进程启动。 BtreePage - 正等待继续并行B-树扫描所需的页号变得可用。 + 等待继续并行 B-树扫描所需的页号变得可用。 - BufferIO - 等待缓冲I/O结束。 + BufferIo + 等待缓冲区 I/O 完成。 + + + + CheckpointDelayComplete + 等待阻碍检查点完成的后端。 + + + + CheckpointDelayStart + 等待阻碍检查点开始的后端。 @@ -1482,82 +1523,92 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser ExecuteGather - 在执行Gather 计划节点时,等待子进程的活动。 + 在执行 Gather 计划节点时,等待子进程的活动。 HashBatchAllocate - 等待一个选定的并行哈希参与者分配哈希表。 + 等待选出的 Parallel Hash 参与者分配哈希表。 HashBatchElect - 等待选择一个并行哈希参与者来分配哈希表。 + 等待选出负责分配哈希表的 Parallel Hash 参与者。 HashBatchLoad - 等待其他并行哈希参与者完成哈希表的加载。 + 等待其他 Parallel Hash 参与者完成哈希表的加载。 HashBuildAllocate - 等待一个选定的并行哈希参与者分配初始哈希表。 + 等待选出的 Parallel Hash 参与者分配初始哈希表。 HashBuildElect - 等待选择一个并行哈希参与者来分配初始哈希表。 + 等待选出负责分配初始哈希表的 Parallel Hash 参与者。 HashBuildHashInner - 等待其他并行哈希参与者完成内部关系的散列。 + 等待其他 Parallel Hash 参与者完成对内层关系的哈希处理。 HashBuildHashOuter - 等待其他Parallel 哈希参与者完成对外部关系的分区。 - - - - HashGrowBatchesAllocate - 等待选定的并行哈希参与者分配更多批处理。 + 等待其他 Parallel Hash 参与者完成对外层关系的分区。 HashGrowBatchesDecide - 等待选择一个并行哈希参与者来决定未来的批处理增长。 + 等待选出负责决定后续批次增长的 Parallel Hash 参与者。 HashGrowBatchesElect - 等待选择一个Parallel 哈希参与者来分配更多批处理。 + 等待选出负责分配更多批次的 Parallel Hash 参与者。 HashGrowBatchesFinish - 等待当选的平行散列参与者决定未来的批量增长。 + 等待选出的 Parallel Hash 参与者决定后续的批次增长。 - HashGrowBatchesRepartition - 等待一个选定的并行哈希参与者决定未来的批处理增长。 + HashGrowBatchesReallocate + 等待选出的 Parallel Hash 参与者分配更多批次。 - HashGrowBucketsAllocate - 等待选定的并行哈希参与者完成更多bucket的分配。 + HashGrowBatchesRepartition + 等待其他 Parallel Hash 参与者完成重新分区。 HashGrowBucketsElect - 等待选择一个并行哈希参与者来分配更多的buckets。 + 等待选出负责分配更多桶的 Parallel Hash 参与者。 + + + + HashGrowBucketsReallocate + 等待选出的 Parallel Hash 参与者完成更多桶的分配。 HashGrowBucketsReinsert - 等待其他Parallel 哈希参与者完成将元组插入到新buckets中。 + 等待其他 Parallel Hash 参与者完成向新桶插入元组。 + + + + LogicalApplySendData + 等待逻辑复制领导者应用进程向并行应用进程发送数据。 + + + + LogicalParallelApplyStateChange + 等待逻辑复制并行应用进程改变状态。 @@ -1590,24 +1641,29 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 等待将字节发送到共享消息队列。 + + MultixactCreation + 等待多事务创建完成。 + + ParallelBitmapScan - 等待并行位图扫描被初始化。 + 等待并行位图扫描完成初始化。 ParallelCreateIndexScan - 等待并行CREATE INDEX 工作进程完成堆扫描。 + 等待并行 CREATE INDEX 工作进程完成堆扫描。 ParallelFinish - 等待并行工作人员完成计算。 + 等待并行工作进程完成计算。 - ProcArrayGroupUpdate - 等待组领导在并行操作结束时清除事务ID。 + ProcarrayGroupUpdate + 等待组领导者在事务结束时清除事务 ID。 @@ -1622,12 +1678,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser RecoveryConflictSnapshot - 等待vacuum清理的恢复冲突解决。 + 等待解决清理操作引发的恢复冲突。 RecoveryConflictTablespace - 等待恢复冲突解决删除表空间。 + 等待解决删除表空间引发的恢复冲突。 @@ -1662,7 +1718,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser SyncRep - 在同步复制期间等待远程服务器的确认。 + 在同步复制期间等待来自远程服务器的确认。 @@ -1670,14 +1726,24 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 等待WAL 接收进程退出。 + + WalReceiverUpstreamCatchup + 等待上游服务器的 WAL 刷盘位置追上请求的起始点。 + + WalReceiverWaitStart 等待启动进程为流复制发送初始数据。 + + WalSummaryReady + 等待生成新的 WAL 汇总。 + + XactGroupUpdate - 等待分组组长在并行操作结束时更新事务状态。 + 等待组领导者在事务结束时更新事务状态。 @@ -1699,7 +1765,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser advisory - 等待获得一个建议用户锁。 + 等待获取用户咨询锁。 + + + + applytransaction + 等待获取逻辑复制订阅者正在应用的远程事务上的锁。 @@ -1709,8 +1780,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser frozenid - 等待升级 pg_database.datfrozenxid - 和 pg_database.datminmxid. + 等待更新 pg_database.datfrozenxidpg_database.datminmxid @@ -1725,12 +1795,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser relation - 等待获得一个关系的锁。 + 等待获取关系上的锁。 spectoken - 等待获取推测的插入锁。 + 等待获取推测插入锁。 @@ -1750,7 +1820,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser virtualxid - 等待获取虚拟事务ID锁。 + 等待获取虚拟事务 ID 锁;参见 @@ -1772,7 +1842,17 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser AddinShmemInit - 等待管理共享内存中的扩展空间分配。 + 等待管理扩展在共享内存中的空间分配。 + + + + AioUringCompletion + 等待另一个进程通过 io_uring 完成 I/O。 + + + + AioWorkerSubmissionQueue + 等待访问 AIO 工作进程的提交队列。 @@ -1787,7 +1867,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser AutovacuumSchedule - 等待确保选择为自动清理的表仍然需要清理。 + 等待确认选中进行自动清理的表是否仍需清理。 @@ -1817,7 +1897,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser CommitTs - 等待读取或更新事务提交时间戳的最后一个值集。 + 等待读取或更新最近设置的事务提交时间戳值。 @@ -1835,11 +1915,31 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 等待读取或更新pg_control文件或创建一个新的WAL文件。 + + DSMRegistry + 等待读取或更新动态共享内存注册表。 + + + + DSMRegistryDSA + 等待访问动态共享内存注册表的动态共享内存分配器。 + + + + DSMRegistryHash + 等待访问动态共享内存注册表的共享哈希表。 + + DynamicSharedMemoryControl 等待读取或更新动态共享内存分配信息。 + + InjectionPoint + 等待读取或更新注入点相关信息。 + + LockFastPath 等待读取或更新进程的快速路径锁信息。 @@ -1847,42 +1947,52 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser LockManager - 等待读取或更新关于heavyweight锁。 + 等待读取或更新有关重量级锁的信息。 + + + + LogicalRepLauncherDSA + 等待访问逻辑复制启动进程的动态共享内存分配器。 + + + + LogicalRepLauncherHash + 等待访问逻辑复制启动进程的共享哈希表。 LogicalRepWorker - 等待读取或更新逻辑复制工作器的状态。 + 等待读取或更新逻辑复制工作进程的状态。 MultiXactGen - 等待读取或更新共享的multixact状态。 + 等待读取或更新共享的多事务状态。 MultiXactMemberBuffer - 在multixact成员SLRU缓冲区上等待I/O。 + 等待多事务成员 SLRU 缓冲区上的 I/O。 MultiXactMemberSLRU - 等待访问multixact成员SLRU缓存。 + 等待访问多事务成员 SLRU 缓存。 MultiXactOffsetBuffer - 在multixact 偏移 SLRU缓冲区上等待I/O。 + 等待多事务偏移量 SLRU 缓冲区上的 I/O。 MultiXactOffsetSLRU - 等待访问multixact 偏移 SLRU缓存。 + 等待访问多事务偏移量 SLRU 缓存。 MultiXactTruncation - 等待读取或截断multixact信息。 + 等待读取或截断多事务信息。 @@ -1897,7 +2007,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser NotifyQueueTail - 等待NOTIFY消息存储上的更新限制。 + 等待更新 NOTIFY 消息存储的限制。 @@ -1911,18 +2021,18 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - OldSnapshotTimeMap - 等待读取或更新旧的快照控制信息。 + ParallelAppend + 在 Parallel Append 计划执行期间等待选择下一个子计划。 - ParallelAppend - 在并行附加计划执行期间等待选择下一个子计划。 + ParallelBtreeScan + 在并行 B-树扫描计划执行期间等待同步工作进程。 ParallelHashJoin - 在并行哈希连接计划执行期间等待同步工作器。 + 在 Parallel Hash Join 计划执行期间等待同步工作进程。 @@ -1930,6 +2040,11 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 等待并行查询动态共享内存分配。 + + ParallelVacuumDSA + 等待为并行清理分配动态共享内存。 + + PerSessionDSA 等待并行查询动态共享内存分配。 @@ -1937,12 +2052,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser PerSessionRecordType - 等待访问有关复合类型的并行查询信息。 + 等待访问并行查询中有关复合类型的信息。 PerSessionRecordTypmod - 等待访问有关标识匿名记录类型的类型修饰符的并行查询信息。 + 等待访问并行查询中用于标识匿名记录类型的类型修饰符信息。 @@ -1950,6 +2065,21 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 在并行查询期间等待访问当前可串行化事务持有的谓词锁列表。 + + PgStatsData + 等待访问共享内存中的统计数据。 + + + + PgStatsDSA + 等待访问统计信息的动态共享内存分配器。 + + + + PgStatsHash + 等待访问统计信息的共享内存哈希表。 + + PredicateLockManager 等待访问可串行化事务使用的谓词锁信息。 @@ -1957,7 +2087,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser ProcArray - 等待访问每个进程共享的数据结构(通常情况,是获取快照或报告会话的事务ID)。 + 等待访问各进程的共享数据结构(通常是为了获取快照或报告会话的事务 ID)。 @@ -2000,6 +2130,11 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 在可串行化事务冲突的SLRU缓冲区上等待I/O。 + + SerialControl + 等待读取或更新共享的 pg_serial 状态。 + + SerializableFinishedList 等待访问已完成的可串行化事务列表。 @@ -2010,21 +2145,6 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 等待访问可串行化事务持有的谓词锁列表。 - - PgStatsDSA - 等待统计动态共享内存分配器访问 - - - - PgStatsHash - 等待统计共享内存哈希表访问 - - - - PgStatsData - 等待共享内存统计数据访问 - - SerializableXactHash 等待读取或更新关于可串行化事务的信息。 @@ -2052,12 +2172,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser SInvalRead - 等待从共享目录失效队列中检索消息。 + 等待从共享系统目录失效队列中取出消息。 SInvalWrite - 等待向共享编目失效队列添加消息。 + 等待向共享系统目录失效队列添加消息。 @@ -2087,7 +2207,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser TwoPhaseState - 等待读取或更新已准备事务的状态。 + 等待读取或更新预备事务的状态。 + + + + WaitEventCustom + 等待读取或更新自定义等待事件信息。 @@ -2100,6 +2225,11 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 等待将WAL数据插入内存缓冲区。 + + WALSummarizer + 等待读取或更新 WAL 汇总状态。 + + WALWrite 等待WAL缓冲区写入磁盘。 @@ -2107,7 +2237,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser WrapLimitsVacuum - 等待更新事务 ID和multixact消费的限制。 + 等待更新事务 ID 和多事务消耗量的限制。 @@ -2133,13 +2263,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - - - 扩展可以将ExtensionInjectionPointLWLock 类型添加到所示的列表中。 - 在某些情况下,扩展分配的 LWLock 名称无法在所有服务器进程中使用;因此,LWLock 等待事件可能只会被报告为extension,而不是扩展分配的名称。 - - @@ -2157,12 +2281,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser BaseBackupThrottle - 当有限流活动时在基础备份期间等待。 + 在基础备份期间因限流而等待。 CheckpointWriteDelay - 在执行检查点时写入之间的等待时间。 + 在执行检查点时,在各次写入之间等待。 @@ -2182,24 +2306,34 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser RegisterSyncRequest - 在发送同步请求到检查点程序时等待,因为请求队列已满。 + 向检查点进程发送同步请求时,因请求队列已满而等待。 + + + + SpinDelay + 在获取有竞争的自旋锁时等待。 VacuumDelay - 在一个基于代价的清理延迟点。 + 在基于代价的清理延迟点等待。 VacuumTruncate 等待获取独占锁以截断被清理的表末尾的空页面。 + + + WalSummarizerError + 在 WAL 汇总进程出错后等待。 +
- 这里是一个查看等待事件的示例: + 以下示例展示如何查看等待事件: SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event is NOT NULL; @@ -2223,6 +2357,14 @@ description | Waiting for a newly initialized WAL file to reach durable storage + + + + 扩展可以将ExtensionInjectionPointLWLock 事件添加到所示的列表中。 + 在某些情况下,扩展分配的 LWLock 名称无法在所有服务器进程中使用;它可能只会被报告为extension,而不是扩展分配的名称。 + + + @@ -2297,7 +2439,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage 连接到这个 WAL 发送进程的客户端的 IP 地址。 - 如果这个域为空,它表示该客户端通过服务器机器上的一个Unix 套接字连接。 + 如果这个字段为空值,它表示该客户端通过服务器机器上的一个Unix 套接字连接。
@@ -2348,27 +2490,27 @@ description | Waiting for a newly initialized WAL file to reach durable storage - startup: 此 WAL 发送进程正在启动。 + startup: 此 WAL 发送进程正在启动。 - catchup: 与此 WAL 发送进程连接的备库正在赶上主库。 + catchup: 与此 WAL 发送进程连接的备库正在赶上主库。 - streaming: 在其连接的备库赶上主库之后,此 WAL 发送进程正在流式传输更改。 + streaming: 在其连接的备库赶上主库之后,此 WAL 发送进程正在流式传输更改。 - backup: 此 WAL 发送进程正在发送一个备份。 + backup: 此 WAL 发送进程正在发送一个备份。 - stopping: 此 WAL 发送进程正在停止。 + stopping: 此 WAL 发送进程正在停止。 @@ -2415,30 +2557,21 @@ description | Waiting for a newly initialized WAL file to reach durable storage write_lag interval - - 从本地刷写最近的 WAL,到收到该备库已写入该 WAL(但尚未刷盘或应用)的通知之间经过的时间。 - 如果该服务器被配置为同步备库,可用此值衡量在提交时 synchronous_commit 级别 remote_write 所导致的延迟。 - + 从在本地将最近的 WAL 刷盘,到收到该备库已写入该 WAL(但尚未刷盘或应用)的通知之间经过的时间。如果该服务器被配置为同步备库,可用此值衡量在提交时synchronous_commit级别remote_write所导致的延迟。
flush_lag interval - - 从本地刷写最近的 WAL,到收到该备库已写入并刷写该 WAL(但尚未应用)的通知之间经过的时间。 - 如果该服务器被配置为同步备库,可用此值衡量在提交时 synchronous_commit 级别 on 所导致的延迟。 - + 从在本地将最近的 WAL 刷盘,到收到该备库已写入该 WAL 并将其刷盘(但尚未应用)的通知之间经过的时间。如果该服务器被配置为同步备库,可用此值衡量在提交时synchronous_commit级别on所导致的延迟。 replay_lag interval - - 从本地刷写最近的 WAL,到收到该备库已写入、刷写并应用该 WAL 的通知之间经过的时间。 - 如果该服务器被配置为同步备库,可用此值衡量在提交时 synchronous_commit 级别 remote_apply 所导致的延迟。 - + 从在本地将最近的 WAL 刷盘,到收到该备库已写入该 WAL、将其刷盘并应用的通知之间经过的时间。如果该服务器被配置为同步备库,可用此值衡量在提交时synchronous_commit级别remote_apply所导致的延迟。 @@ -2460,22 +2593,22 @@ description | Waiting for a newly initialized WAL file to reach durable storage - async: 该备库是异步的。 + async: 该备库是异步的。 - potential: 该备库当前是异步的,但在当前同步备库失效时可能变为同步的。 + potential: 该备库当前是异步的,但在当前某个同步备库失效时可能变为同步的。 - sync: 该备库是同步的。 + sync: 该备库是同步的。 - quorum: 该备库被作为法定人数同步复制候选备库。 + quorum: 该备库被作为法定人数同步复制候选备库。 @@ -2484,7 +2617,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - reply_time 带时区的时间戳 + reply_time timestamp with time zone 从备库收到的最后一条回复消息的发送时间 @@ -2495,17 +2628,17 @@ description | Waiting for a newly initialized WAL file to reach durable storage - pg_stat_replication视图中报告的滞后时间,是最近的 WAL 被写入、刷写和重放,以及发送端获知这些操作完成所花费时间的度量。如果远程服务器被配置为同步备库,这些时间表示各个同步提交级别带来或可能带来的提交延迟。对于异步备库,replay_lag列是最近事务对查询变得可见所需延迟时间的近似值。如果备库已经完全追上发送服务器且没有新的 WAL 活动,系统会在短时间内继续显示最近测得的滞后时间,随后显示为 NULL。 + pg_stat_replication视图中报告的滞后时间,是最近的 WAL 被写入、刷盘和重放,以及发送端获知这些操作完成所花费时间的度量。如果远程服务器被配置为同步备库,这些时间表示各个同步提交级别带来或可能带来的提交延迟。对于异步备库,replay_lag列是最近事务对查询变得可见所需延迟时间的近似值。如果备库已经完全追上发送服务器且没有新的 WAL 活动,系统会在短时间内继续显示最近测得的滞后时间,随后显示为 空值。 - 对于物理复制,滞后时间会自动测量。逻辑解码插件可以选择发出跟踪消息;如果没有这样做,跟踪机制会将滞后显示为 NULL。 + 对于物理复制,滞后时间会自动测量。逻辑解码插件可以选择发出跟踪消息;如果没有这样做,跟踪机制会将滞后显示为 空值。 - 报告出的滞后时间并不是根据当前重放速率预测该备库还需多久才能追上发送服务器。在持续生成新 WAL 时,那样的系统可能会显示相近的时间;但当发送端空闲时,就会显示不同的值。特别是当备库已经完全追上时,pg_stat_replication显示的是写入、刷写和重放最近报告的 WAL 位置所花费的时间,而不是某些用户可能预期的零。这样做符合为最近写事务测量同步提交和事务可见性延迟的目的。为减少用户因预期另一种滞后模型而产生的混淆,在一个已完全重放且处于空闲状态的系统上,lag 列会在较短时间后恢复为 NULL。监控系统应自行决定将这种情况表示为缺失数据、零,还是继续显示最近一次已知值。 + 报告出的滞后时间并不是根据当前重放速率预测该备库还需多久才能追上发送服务器。在持续生成新 WAL 时,那样的系统可能会显示相近的时间;但当发送端空闲时,就会显示不同的值。特别是当备库已经完全追上时,pg_stat_replication显示的是写入、刷盘和重放最近报告的 WAL 位置所花费的时间,而不是某些用户可能预期的零。这样做符合为最近写事务测量同步提交和事务可见性延迟的目的。为减少用户因预期另一种滞后模型而产生的混淆,在一个已完全重放且处于空闲状态的系统上,滞后列会在较短时间后恢复为 空值。监控系统应自行决定将这种情况表示为缺失数据、零,还是继续显示最近一次已知值。 @@ -2544,19 +2677,14 @@ description | Waiting for a newly initialized WAL file to reach durable storage slot_name text - - 唯一的,复制槽的集簇范围标识符 - + 复制槽在整个集簇范围内的唯一标识符 spill_txns bigint - - 当逻辑解码在解码来自WAL的更改时所使用的内存超过logical_decoding_work_mem,溢出到磁盘的事务数。 - 顶级事务和子事务的计数器都是递增的。 - + 当逻辑解码从 WAL 解码更改时所使用的内存超过logical_decoding_work_mem后,溢出到磁盘的事务数。顶层事务和子事务都会使此计数器递增。 @@ -2564,7 +2692,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage spill_count bigint - 在为该槽位解码来自WAL的更改时,事务溢出到磁盘的次数。 + 在为该槽解码来自WAL的更改时,事务溢出到磁盘的次数。 此计数器在每次事务被溢出时递增,并且同一事务可能被溢出多次。 @@ -2573,20 +2701,14 @@ description | Waiting for a newly initialized WAL file to reach durable storage spill_bytes bigint - - 在对来自WAL的更改执行解码时,已解码的事务数据溢出到磁盘的数量。 - 这个和其他溢出计数器可用于测量逻辑解码期间发生的I/O,并且允许调优logical_decoding_work_mem。 - + 为此槽从 WAL 解码更改时,溢出到磁盘的已解码事务数据量。此计数器及其他溢出计数器可用于衡量逻辑解码期间发生的 I/O,并用于调优logical_decoding_work_mem stream_txns bigint - - 在逻辑解码在解码来自该槽位的WAL更改的时候,所使用的内存超过logical_decoding_work_mem之后,流式传输到解码输出插件的正在进行的事务数。 - 流式传输仅对顶级事务有效(子事务不能独立进行流式传输),因此子事务的计数器不会增加。 - + 当逻辑解码为此槽从 WAL 解码更改时所使用的内存超过logical_decoding_work_mem后,流式传输到解码输出插件的进行中事务数。流式传输仅适用于顶层事务(子事务不能单独进行流式传输),因此子事务不会使此计数器递增。 @@ -2594,7 +2716,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage stream_countbigint - 在为该槽位解码来自WAL的更改时,将正在进行的事务流式传输到解码输出插件的次数。 + 在为该槽解码来自WAL的更改时,将进行中事务流式传输到解码输出插件的次数。 此计数器在每次事务流式传输时递增,并且同一事务可能被流式传输多次。 @@ -2604,8 +2726,8 @@ description | Waiting for a newly initialized WAL file to reach durable storage stream_bytesbigint - 在为该槽位解码来自WAL的更改时,为将正在进行的事务流式传输到解码输出插件而解码的事务数据的数量。 - 这个和针对此槽位的其他流式传输计数器可用于调优logical_decoding_work_mem。 + 在为该槽解码来自WAL的更改时,为将进行中事务流式传输到解码输出插件而解码的事务数据量。 + 这个和针对此槽的其他流式传输计数器可用于调优logical_decoding_work_mem
@@ -2616,7 +2738,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage 针对此槽的,发送到解码输出插件的已解码事务数。 - 这只计算顶级事务,对子事务不会增加。 + 这只计算顶层事务,对子事务不会增加。 注意,这包括流式传输和/或溢出的事务。
@@ -2626,7 +2748,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage total_bytesbigint - 在对此槽位的WAL进行解码时,为将事务发送到解码输出插件而解码的事务数据量。 + 在为此槽从 WAL 解码更改时,为将事务发送到解码输出插件而解码的事务数据量。 注意这包括流式传输和/或溢出的数据。 @@ -2636,9 +2758,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage stats_reset timestamp with time zone - - 这些统计最后重置的时间 - + 这些统计信息上次被重置的时间
@@ -2653,9 +2773,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage pg_stat_wal_receiver - - pg_stat_wal_receiver事务只包含一行,它显示了从 WAL 接收进程所连接的服务器得到的有关该接收进程的统计信息。 - + pg_stat_wal_receiver视图只包含一行,显示 WAL 接收进程从其所连接服务器接收数据的统计信息。 @@ -2680,7 +2798,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage pidinteger - WAL 接收进程的进程ID + WAL 接收进程的进程 ID @@ -2689,7 +2807,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage statustext - WAL接收进程的活动状态 + WAL 接收进程的活动状态 @@ -2698,7 +2816,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage receive_start_lsnpg_lsn - WAL 接收进程启动时使用的第一个写前日志位置 + WAL 接收进程启动时使用的第一个预写式日志位置 @@ -2707,7 +2825,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage receive_start_tliinteger - WAL 接收进程启动时使用的第一个时间线数字 + WAL 接收进程启动时使用的第一个时间线编号 @@ -2716,7 +2834,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage written_lsnpg_lsn - 已经接收并写入磁盘的最后一个预写式日志位置,但没有刷入。这不能用于数据完整性检查。 + 已经接收并写入磁盘的最后一个预写式日志位置,但尚未刷盘。此字段不应用于数据完整性检查。 @@ -2725,7 +2843,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage flushed_lsnpg_lsn - 已经接收并刷入到磁盘的最后一个预写式日志位置,该字段的初始值是启动WAL 接收进程时使用的第一个日志位置 + 已经接收并刷入到磁盘的最后一个预写式日志位置,该字段的初始值是启动 WAL 接收进程时使用的第一个日志位置 @@ -2734,7 +2852,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage received_tliinteger - 接收并刷入到磁盘的最后一个预写式日志位置的时间线数字,该字段的初始值为启动WAL 接收进程时使用的第一个日志位置的时间线数字 + 接收并刷入到磁盘的最后一个预写式日志位置的时间线编号,该字段的初始值为启动 WAL 接收进程时使用的第一个日志位置的时间线编号 @@ -2779,7 +2897,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage slot_nametext - 这个WAL 接收进程使用的复制槽的名称 + 这个 WAL 接收进程使用的复制槽的名称 @@ -2788,8 +2906,8 @@ description | Waiting for a newly initialized WAL file to reach durable storage sender_hosttext - 这个WAL 接收进程连接到的PostgreSQL实例的主机。 - 这可以是主机名、IP地址,或者目录路径,如果连接是通过Unix套接字进行的。(路径的情况可以区分,因为它总是以/开头的绝对路径。) + 这个 WAL 接收进程连接到的PostgreSQL实例的主机。 + 这可以是主机名、IP地址,或者目录路径,如果连接是通过Unix套接字进行的。(路径的情况可以区分,因为它总是以/开头的绝对路径。) @@ -2798,7 +2916,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage sender_portinteger - 这个WAL 接收进程连接的PostgreSQL实例的端口号。 + 这个 WAL 接收进程连接的PostgreSQL实例的端口号。 @@ -2807,7 +2925,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage conninfotext - 这个WAL 接收进程使用的连接字符串,对安全敏感的字段进行了模糊处理。 + 这个 WAL 接收进程使用的连接字符串,对安全敏感的字段进行了模糊处理。 @@ -2853,9 +2971,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage stats_reset timestamp with time zone - - 这些统计数据上次重置的时间 - + 这些统计信息上次被重置的时间 @@ -2930,9 +3046,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage wal_distance int - - 预取器向前查看多少字节 - + 预取器向前查看的字节数 @@ -2941,9 +3055,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage block_distance int - - 预取器正在查看多少个块之前 - + 预取器向前查看的块数 @@ -2952,9 +3064,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage io_depth int - - 已启动但尚未完成的预取数量 - + 已启动但尚未确认完成的预取数量 @@ -2997,7 +3107,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + subname name @@ -3006,7 +3116,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + worker_type text @@ -3015,7 +3125,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + pid integer @@ -3024,59 +3134,69 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + + + leader_pid integer + + + 如果此进程是并行应用工作进程,则为领导者应用工作进程的进程 ID;如果此进程是领导者应用工作进程或表同步工作进程,则为 NULL + + + + relid oid - 该工作进程正在同步的关系的 OID;主应用工作进程则为 NULL + 该工作进程正在同步的关系的 OID;对于领导者应用工作进程和并行应用工作进程,则为空值 - + received_lsn pg_lsn - 接收到的最后一个预写式日志位置,该字段的初始值为0 + 接收到的最后一个预写式日志位置,该字段的初始值为 0;对于并行应用工作进程,则为 NULL - + last_msg_send_time timestamp with time zone - 从源 WAL 发送进程收到的最后一条消息的发送时间 + 从源 WAL 发送进程收到的最后一条消息的发送时间;对于并行应用工作进程,则为 NULL - + last_msg_receipt_time timestamp with time zone - 从源 WAL 发送进程收到的最后一条消息的接收时间 + 从源 WAL 发送进程收到的最后一条消息的接收时间;对于并行应用工作进程,则为 NULL - + latest_end_lsn pg_lsn - 向源 WAL 发送进程报告的最后一个预写式日志位置 + 向源 WAL 发送进程报告的最后一个预写式日志位置;对于并行应用工作进程,则为 NULL - + latest_end_time timestamp with time zone - 向 WAL 发送进程报告最后一个预写式日志位置的时间 + 向源 WAL 发送进程报告最后一个预写式日志位置的时间;对于并行应用工作进程,则为 NULL +
@@ -3135,7 +3255,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage apply_error_count bigint - 应用更改时发生错误的次数 + 应用更改时发生错误的次数。请注意,导致应用错误的任何冲突都会同时计入 apply_error_count 和对应的冲突计数(例如 confl_*)。
@@ -3215,9 +3335,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage stats_reset timestamp with time zone - - 这些统计数据最后一次重置的时间 - + 这些统计信息上次被重置的时间
@@ -3278,7 +3396,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage version text - 使用SSL的版本,如果此连接上没有使用SSL则为NULL + 使用SSL的版本,如果此连接上没有使用SSL则为空值
@@ -3287,7 +3405,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage cipher text - 正在使用的SSL密码的名称,如果此连接上没有使用SSL则为NULL + 正在使用的SSL 密码套件的名称,如果此连接上没有使用SSL则为空值
@@ -3296,7 +3414,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage bits integer - 使用的加密算法中的位数,如果此连接上没有使用SSL则为NULL + 使用的加密算法中的位数,如果此连接上没有使用SSL则为空值
@@ -3305,8 +3423,8 @@ description | Waiting for a newly initialized WAL file to reach durable storage client_dn text - 区别名称(DN,Distinguished Name)字段与使用的客户端证书,如果没有提供客户端证书或在此连接上没有使用SSL,则为NULL。 - 如果DN字段长于NAMEDATALEN(标准构建中为64个字符),则该字段将被截断。 + 所用客户端证书中的区别名称(DN,Distinguished Name)字段,如果没有提供客户端证书或在此连接上没有使用SSL,则为空值。 + 如果DN字段长于NAMEDATALEN(标准构建中为64个字符),则该字段将被截断。
@@ -3315,8 +3433,8 @@ description | Waiting for a newly initialized WAL file to reach durable storage client_serial numeric - 客户端证书的序列号,如果没有提供客户端证书或在此连接上没有使用SSL,则为NULL。 - 证书序列号和证书颁发者的组合唯一标识一个证书(除非颁发者错误地重用序列号)。 + 客户端证书的序列号,如果没有提供客户端证书或在此连接上没有使用SSL,则为空值。 + 证书序列号和证书颁发者的组合唯一标识一个证书(除非颁发者错误地重用序列号)。
@@ -3325,7 +3443,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage issuer_dn text - 客户端证书颁发者的区别名称(DN,Distinguished Name),如果没有提供客户端证书或在此连接上没有使用SSL,则为NULL。该字段像client_dn一样被截断。 + 客户端证书颁发者的区别名称(DN,Distinguished Name),如果没有提供客户端证书或在此连接上没有使用SSL,则为空值。该字段像client_dn一样被截断。
@@ -3343,7 +3461,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage pg_stat_gssapi视图将包含每一个后端一个行,显示该连接上的GSSAPI使用情况。 - 它可以加入到pg_stat_activitypg_stat_replication上的pid列,获取更多关于连接的详细信息。 + 可以通过pid列将它与pg_stat_activitypg_stat_replication连接,获取更多关于连接的详细信息。 @@ -3387,8 +3505,8 @@ description | Waiting for a newly initialized WAL file to reach durable storage principaltext - 用于验证此连接的主体,如果未使用GSSAPI对此连接进行认证,则为NULL。 - 如果主体长度超过NAMEDATALEN(标准构建中为64个字符),则该字段被截断。 + 用于认证此连接的主体,如果未使用GSSAPI对此连接进行认证,则为空值。 + 如果主体长度超过NAMEDATALEN(标准构建中为64个字符),则该字段被截断。 @@ -3502,9 +3620,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage stats_reset timestamp with time zone - - 这些统计数据最后一次重置的时间 - + 这些统计信息上次被重置的时间 @@ -3554,7 +3670,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage backend_typetext - 后端类型(例如后台工作进程、autovacuum 工作进程)。有关 backend_type 的更多信息,请参阅pg_stat_activity。某些 backend_type 不会累计 I/O 操作统计信息,因此不会出现在该视图中。 + 后端类型(例如后台工作进程、自动清理工作进程)。有关 backend_type 的更多信息,请参阅pg_stat_activity。某些 backend_type 不会累积 I/O 操作统计信息,因此不会出现在该视图中。 @@ -3566,7 +3682,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage I/O 操作的目标对象。可能的值有: - + @@ -3584,6 +3700,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage + @@ -3608,7 +3725,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - vacuum:对永久关系执行 vacuum 和 analyze 时,在共享缓冲区之外执行的 I/O 操作。临时表 vacuum 与其他临时表 I/O 操作共用同一本地缓冲池,因此会在 contextnormal 时跟踪。 + vacuum:对永久关系执行清理和分析 时,在共享缓冲区之外执行的 I/O 操作。临时表清理 与其他临时表 I/O 操作共用同一本地缓冲池,因此会在 contextnormal 时跟踪。 @@ -3809,9 +3926,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage stats_reset timestamp with time zone - - 这些统计信息上次被重置的时间。 - + 这些统计信息上次被重置的时间。 @@ -3823,7 +3938,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - 此外,某些 I/O 操作永远不会由某些后端类型执行,或者永远不会针对某些 I/O 对象和/或在某些 I/O 上下文中执行。这些单元格会是 NULL。例如,临时表不会执行 fsync,因此当 objecttemp relation 时,fsyncs 将为 NULL。又如,后台写入器不会执行读取,因此当 backend_typebackground writer 时,reads 将为 NULL。 + 此外,某些 I/O 操作永远不会由某些后端类型执行,或者永远不会针对某些 I/O 对象和/或在某些 I/O 上下文中执行。这些单元格会是空值。例如,临时表不会执行 fsync,因此当 objecttemp relation 时,fsyncs 将为空值。又如,后台写入器不会执行读取,因此当 backend_typebackground writer 时,reads 将为空值。 @@ -3840,7 +3955,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - 客户端后端依赖检查点进程确保数据持久化到永久存储。客户端后端出现大量 fsyncs 可能表明共享缓冲区或检查点进程配置不当。有关配置检查点进程的更多信息,请参阅。 + 客户端后端依赖检查点进程确保数据持久化到永久存储。client backend出现大量 fsyncs 可能表明共享缓冲区或检查点进程配置不当。有关配置检查点进程的更多信息,请参阅 @@ -3916,9 +4031,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage stats_reset timestamp with time zone - - 这些统计信息上次被重置的时间 - + 这些统计信息上次被重置的时间 @@ -4046,9 +4159,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage stats_reset timestamp with time zone - - 这些统计信息上次被重置的时间 - + 这些统计信息上次被重置的时间 @@ -4112,7 +4223,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage wal_bytes numeric - 生成的WAL总数,以字节计 + 生成的 WAL 总量,以字节计 @@ -4121,56 +4232,23 @@ description | Waiting for a newly initialized WAL file to reach durable storage wal_buffers_full bigint - 因为缓冲区已满,WAL数据被写入磁盘的次数 + 因为 WAL 缓冲区已满,WAL 数据被写入磁盘的次数 - - - wal_write bigint - - - 通过XLogWrite请求,WAL缓冲区被写入到磁盘的次数。 - 有关内部WAL函数XLogWrite的更多信息,请参见。 - - - - - wal_sync bigint - - - 通过issue_xlog_fsync 请求将WAL文件同步到磁盘的次数(如果onfdatasync, fsyncfsync_writethrough,否则为零)。 - 有关内部WAL函数issue_xlog_fsync的更多信息,参见。 - - - - - wal_write_time double precision - - - 通过XLogWrite请求将WAL缓冲区写入磁盘所消耗的总时间,以毫秒计(如果是启用的,否则为零)。 - 这包括当wal_sync_methodopen_datasyncopen_sync时的同步时间。 - - - - - wal_sync_time double precision - - - 通过issue_xlog_fsync请求将WAL文件同步到磁盘所消耗的总时间,以毫秒计(如果 track_wal_io_timing 被启用,fsync is on, 和 wal_sync_methodfdatasync, fsyncfsync_writethrough, 否则为零). - - + + + + stats_reset timestamp with time zone - - 这些统计数据最后一次重置的时间 - + 这些统计信息上次被重置的时间 @@ -4216,7 +4294,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + datname name @@ -4225,17 +4303,17 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + numbackends integer 当前连接到此数据库的后端数,对于共享对象则为NULL。 - 这是该视图中唯一返回反映当前状态的值的列;所有其他列返回自上次重置以来累积的值。 + 这是该视图中唯一返回反映当前状态的值的列;所有其他列返回自上次重置以来累积的值。 - + xact_commit bigint @@ -4244,7 +4322,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + xact_rollback bigint @@ -4253,7 +4331,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + blks_read bigint @@ -4262,7 +4340,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + blks_hit bigint @@ -4271,7 +4349,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + tup_returned bigint @@ -4280,7 +4358,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + tup_fetched bigint @@ -4289,7 +4367,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + tup_inserted bigint @@ -4298,7 +4376,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + tup_updated bigint @@ -4307,7 +4385,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + tup_deleted bigint @@ -4316,7 +4394,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + conflicts bigint @@ -4325,7 +4403,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + temp_files bigint @@ -4334,7 +4412,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + temp_bytes bigint @@ -4343,7 +4421,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + deadlocks bigint @@ -4352,7 +4430,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + checksum_failures bigint @@ -4361,7 +4439,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + checksum_last_failure timestamp with time zone @@ -4370,7 +4448,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + blk_read_time double precision @@ -4379,7 +4457,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + blk_write_time double precision @@ -4388,25 +4466,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - - - parallel_workers_to_launch bigint - - - 计划由该数据库上的查询启动的并行工作进程数 - - - - - - parallel_workers_launched bigint - - - 由该数据库上的查询启动的并行工作进程数 - - - - + session_time double precision @@ -4415,7 +4475,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + active_time double precision @@ -4424,7 +4484,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + idle_in_transaction_time double precision @@ -4433,7 +4493,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + sessions bigint @@ -4442,7 +4502,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + sessions_abandoned bigint @@ -4451,7 +4511,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + sessions_fatal bigint @@ -4460,7 +4520,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + sessions_killed bigint @@ -4469,7 +4529,25 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + + + parallel_workers_to_launch bigint + + + 计划由该数据库上的查询启动的并行工作进程数 + + + + + + parallel_workers_launched bigint + + + 由该数据库上的查询启动的并行工作进程数 + + + + stats_reset timestamp with time zone @@ -4477,6 +4555,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage 这些统计数据最后一次重置的时间 +
@@ -4563,7 +4642,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage confl_bufferpin bigint - 此数据库中由于固定缓冲区而被取消的查询数 + 此数据库中由于缓冲区被钉住而被取消的查询数
@@ -4670,7 +4749,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage seq_tup_read bigint - 连续扫描获取的实时行数 + 顺序扫描获取的存活行数
@@ -4697,7 +4776,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage idx_tup_fetch bigint - 索引扫描获取的实时行数 + 索引扫描获取的存活行数
@@ -4714,9 +4793,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage n_tup_upd bigint - - 更新的行数(包括HOT更新的行) - + 更新的总行数。(包括计入n_tup_hot_updn_tup_newpage_upd的行更新,以及其余非HOT更新。)
@@ -4732,9 +4809,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage n_tup_hot_upd bigint - - HOT更新的行数(即,不需要单独的索引更新) - + 进行HOT 更新的行数。这些更新不需要在索引中存储后继版本。 @@ -4742,7 +4817,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage n_tup_newpage_upd bigint - 更新的行数,其中后继版本转到新的堆页,留下一个原始版本,其t_ctid字段指向不同的堆页。这些始终是非 HOT 更新。 + 更新的行数,其中后继版本转到的堆页,留下一个原始版本,其t_ctid字段指向不同的堆页。这些始终是非 HOT 更新。 @@ -4777,9 +4852,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage n_ins_since_vacuum bigint - - 自上次清理此表以来插入的行的估计数量 - + 自上次清理此表以来插入的行的估计数量(不计VACUUM FULL
@@ -4787,7 +4860,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage last_vacuum timestamp with time zone - 最后一次手动清理这个表(不包括VACUUM FULL) + 最后一次手动清理这个表的时间(不包括VACUUM FULL @@ -4805,7 +4878,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage last_analyze timestamp with time zone - 上一次手动分析这个表 + 上一次手动分析这个表的时间
@@ -4814,7 +4887,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage last_autoanalyze timestamp with time zone - 自动清理守护进程最后一次分析这个表 + 自动清理守护进程最后一次分析这个表的时间
@@ -4823,7 +4896,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage vacuum_count bigint - 这个表被手动清理的次数(VACUUM FULL不计数) + 这个表被手动清理的次数(VACUUM FULL不计数)
@@ -4859,7 +4932,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage total_vacuum_time double precision - 手动 VACUUM 此表所花费的总时间,以毫秒计(不包括 VACUUM FULL)。(这包括由于基于成本的延迟而睡眠的时间。) + 手动清理此表所花费的总时间,以毫秒计(不包括 VACUUM FULL)。(这包括由于基于代价的延迟而睡眠的时间。)
@@ -4868,7 +4941,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage total_autovacuum_time double precision - 自动清理守护进程对该表执行 VACUUM 所花费的总时间,以毫秒计。(这包括由于基于成本的延迟而睡眠的时间。) + 自动清理守护进程清理该表 所花费的总时间,以毫秒计。(这包括由于基于代价的延迟而睡眠的时间。)
@@ -4877,7 +4950,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage total_analyze_time double precision - 手动分析该表所花费的总时间,以毫秒计。(这包括由于基于成本的延迟而睡眠的时间。) + 手动分析该表所花费的总时间,以毫秒计。(这包括由于基于代价的延迟而睡眠的时间。)
@@ -4886,7 +4959,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage total_autoanalyze_time double precision - 自动清理守护进程分析该表所花费的总时间,以毫秒计。(这包括由于基于成本的延迟而睡眠的时间。) + 自动清理守护进程分析该表所花费的总时间,以毫秒计。(这包括由于基于代价的延迟而睡眠的时间。)
@@ -5001,7 +5074,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage idx_tup_fetch bigint - 使用此索引进行简单索引扫描获取的活动表行数 + 使用此索引进行简单索引扫描获取的存活表行数
@@ -5009,16 +5082,25 @@ description | Waiting for a newly initialized WAL file to reach durable storage - 索引可以被简单索引扫描、位图索引扫描以及优化器使用。在一次位图扫描中,多个索引的输出可以被通过 AND 或 OR 规则组合,因此当使用一次位图扫描时难以将取得的个体堆行与特定的索引关联起来。因此,一次位图扫描会增加它使用的索引的pg_stat_all_indexes.idx_tup_read计数,并且为每个表增加pg_stat_all_tables.idx_tup_fetch计数,但是它不影响pg_stat_all_indexes.idx_tup_fetch。如果所提供的常量值不在优化器统计信息记录的范围之内,优化器也会访问索引来检查,因为优化器统计信息可能已经“不新鲜”了。 + 索引可以被简单索引扫描、位图索引扫描以及优化器使用。在一次位图扫描中,多个索引的输出可以被通过 AND 或 OR 规则组合,因此当使用一次位图扫描时难以将取得的个体堆行与特定的索引关联起来。因此,一次位图扫描会增加它使用的索引的pg_stat_all_indexes.idx_tup_read计数,并且为该表增加pg_stat_all_tables.idx_tup_fetch计数,但是它不影响pg_stat_all_indexes.idx_tup_fetch。如果所提供的常量值不在优化器统计信息记录的范围之内,优化器也会访问索引来检查,因为优化器统计信息可能已经过时。 - 即使不用位图扫描,idx_tup_readidx_tup_fetch计数也可能不同,因为idx_tup_read统计从该索引取得的索引项而idx_tup_fetch统计从表取得的活着的行。如果使用该索引取得了任何死亡行或还未提交的行,或者如果通过一次只用索引扫描的方式避免了任何堆获取,后者将较小。 + 即使不用位图扫描,idx_tup_readidx_tup_fetch计数也可能不同,因为idx_tup_read统计从该索引取得的索引项而idx_tup_fetch统计从表取得的存活行。如果使用该索引取得了任何死亡行或还未提交的行,或者如果通过一次仅索引扫描的方式避免了任何堆获取,后者将较小。 + + 索引扫描在一次执行中有时会进行多次索引搜索。每次索引搜索都会递增pg_stat_all_indexes.idx_scan,因此索引扫描计数可能显著超过索引扫描执行器节点的总执行次数。 + 使用某些SQL构造来搜索与列表或数组中的多个标量值之一匹配的行时,可能出现这种情况(参见)。使用column_name = value1 OR column_name = value2 ...构造的查询也可能如此,但前提是优化器将该构造转换为等价的多值数组表示。同样,当 B-树索引扫描使用跳跃扫描优化时,每次将扫描位置移至下一个可能包含匹配元组的索引叶子页,都会进行一次索引搜索(参见)。 + + + + EXPLAIN ANALYZE会输出每个索引扫描节点执行的索引搜索总次数。有关展示其工作方式的示例,请参见 + + @@ -5118,7 +5200,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage toast_blks_read bigint - 从这个表的TOAST表中读取的磁盘块的数量(如果有的话) + 从这个表的TOAST表中读取的磁盘块的数量(如果有的话) @@ -5127,7 +5209,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage toast_blks_hit bigint - 这个表的TOAST表中的缓冲区命中数(如果有的话) + 这个表的TOAST表中的缓冲区命中数(如果有的话) @@ -5136,7 +5218,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage tidx_blks_read bigint - 从这个表的TOAST表索引中读取的磁盘块的数量(如果有的话) + 从这个表的TOAST表索引中读取的磁盘块的数量(如果有的话) @@ -5145,7 +5227,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage tidx_blks_hit bigint - 这个表的TOAST表索引中的缓冲区命中数(如果有的话) + 这个表的TOAST表索引中的缓冲区命中数(如果有的话) @@ -5431,10 +5513,9 @@ description | Waiting for a newly initialized WAL file to reach durable storage pg_stat_slru - - PostgreSQL通过SLRU(simple least-recently-used,简单的最近-最少-使用)缓存访问某些磁盘上的信息。 - pg_stat_slru视图将为每个被跟踪的SLRU缓存包含一行,显示关于访问缓存页面的统计信息。 - + PostgreSQL通过SLRU简单最近最少使用)缓存访问某些磁盘上的信息。pg_stat_slru视图将为每个被跟踪的 SLRU 缓存包含一行,显示关于访问缓存页面的统计信息。 + + 对于核心服务器中的每个SLRU缓存,都有一个以_buffers为后缀的配置参数来控制其大小。 @@ -5477,7 +5558,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage blks_hitbigint - 已经在SLRU中的磁盘块被发现的次数,因此不需要读取(这只包括SLRU中的命中,而不是操作系统的文件系统缓存) + 已经在SLRU中的磁盘块被发现的次数,因此不需要读取(这只包括SLRU中的命中,而不是操作系统的文件系统缓存) @@ -5513,7 +5594,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage flushesbigint - 此SLRU的脏数据刷新数 + 此SLRU的脏数据刷盘次数 @@ -5522,7 +5603,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage truncatesbigint - 这个SLRU的截断数 + 这个SLRU的截断次数 @@ -5530,9 +5611,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage stats_reset timestamp with time zone - - 这些统计数据最后一次重置的时间 - + 这些统计信息上次被重置的时间 @@ -5552,7 +5631,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - 与累积统计系统相关的其他功能在中列出。 + 与累积统计系统相关的其他函数在中列出。
@@ -5596,7 +5675,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage 返回指定进程 ID 的后端的 I/O 统计信息。输出字段与 pg_stat_io 视图中的字段完全相同。 - 该函数不会返回检查点进程、后台写入器、启动进程和 自动清理启动器的 I/O 统计信息,因为这些统计信息已经在 pg_stat_io 视图中可见,而且每种都只有一个。 + 该函数不返回检查点进程、后台写入器、启动进程和自动清理启动器的 I/O 统计信息,因为这些统计信息已显示在 pg_stat_io 视图中,而且每种进程都只有一个。 @@ -5639,7 +5718,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage timestamp with time zone - 返回当前统计快照的时间戳,如果没有统计快照则返回NULL。如果在事务中第一次访问累积统计信息时将快照设置为stats_fetch_consistencysnapshot。 + 返回当前统计快照的时间戳;如果尚未获取统计快照,则返回 NULL。如果 stats_fetch_consistency 设置为 snapshot,则会在事务中第一次访问累积统计信息时获取快照。 @@ -5695,9 +5774,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage 将当前数据库的所有统计计数器重置为零。 - - 默认情况下该函数仅限于超级用户,但是其他用户可以被授予EXECUTE来运行此函数。 - + 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 @@ -5705,51 +5782,67 @@ description | Waiting for a newly initialized WAL file to reach durable storage pg_stat_reset_shared - pg_stat_reset_shared ( text ) + pg_stat_reset_shared ( [ target text DEFAULT NULL ] ) void - 根据参数将一些集簇范围的统计计数器重置为零。参数可以是bgwriter, - 用于重置在pg_stat_bgwriter视图中显示的所有计数器, - archiver,用于重置在pg_stat_archiver视图中显示的所有计数器, - wal,用于重置在pg_stat_wal视图中显示的所有计数器, - 或recovery_prefetch,用于重置在pg_stat_recovery_prefetch视图中显示的所有计数器。 + 根据参数将一些集簇范围的统计计数器重置为零。target 可以是: + + + archiver:重置 pg_stat_archiver 视图中显示的所有计数器。 + + + bgwriter:重置 pg_stat_bgwriter 视图中显示的所有计数器。 + + + checkpointer:重置 pg_stat_checkpointer 视图中显示的所有计数器。 + + + io:重置 pg_stat_io 视图中显示的所有计数器。 + + + recovery_prefetch:重置 pg_stat_recovery_prefetch 视图中显示的所有计数器。 + + + slru:重置 pg_stat_slru 视图中显示的所有计数器。 + + + wal:重置 pg_stat_wal 视图中显示的所有计数器。 + + + NULL 或未指定:重置上述所有视图中的所有计数器。 + + - - 默认情况下,此函数仅限超级用户使用,但可以授予其他用户EXECUTE权限来运行该函数。 - + 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 - pg_stat_reset_backend_stats + pg_stat_reset_single_table_counters - pg_stat_reset_backend_stats ( integer ) + pg_stat_reset_single_table_counters ( oid ) void - 将指定进程 ID 的单个后端进程的统计信息重置为零。 + 将单个表或索引的统计信息重置为零;该对象可以位于当前数据库中,也可以由集簇中的所有数据库共享。 - - 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 - + 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 - pg_stat_reset_single_table_counters + pg_stat_reset_backend_stats - pg_stat_reset_single_table_counters ( oid ) + pg_stat_reset_backend_stats ( integer ) void - 重置当前数据库中的单个表或索引的统计信息,或者在集簇中跨所有数据库共享的统计信息为零。 + 将指定进程 ID 的单个后端进程的统计信息重置为零。 - - 默认情况下,此函数仅限超级用户使用,但可以授予其他用户EXECUTE权限来运行该函数。 - + 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 @@ -5763,9 +5856,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage 将当前数据库中单个函数的统计信息重置为零。 - - 默认情况下该函数仅限于超级用户,但是其他用户可以被授予EXECUTE来运行此函数。 - + 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 @@ -5773,19 +5864,13 @@ description | Waiting for a newly initialized WAL file to reach durable storage pg_stat_reset_slru - pg_stat_reset_slru ( text ) + pg_stat_reset_slru ( [ target text DEFAULT NULL ] ) void - 将单个SLRU缓存或集簇中所有SLRU的统计信息重置为零。 - 如果该参数为NULL,则所有SLRU缓存的pg_stat_slru视图中显示的计数器将被重置。 - 参数可以是CommitTsMultiXactMemberMultiXactOffsetNotify、 - SerialSubtrans、 或Xact中的一个,以便只重置该条目的计数器。 - 如果参数是other(或实际上,任何无法识别的名称),那么所有其他SLRU缓存的计数器,如扩展定义的缓存,将被重置。 + 将单个 SLRU 缓存或集簇中所有 SLRU 的统计信息重置为零。如果 targetNULL 或未指定,则重置 pg_stat_slru 视图中所有 SLRU 缓存的全部计数器。参数可以为 commit_timestamp、&zwsp;multixact_member、&zwsp;multixact_offset、&zwsp;notify、&zwsp;serializable、&zwsp;subtransactiontransaction 中的一个,以便只重置对应条目的计数器。如果参数为 other(实际上,任何无法识别的名称都可以),则重置其他所有 SLRU 缓存的计数器,例如扩展定义的缓存。 - - 默认情况下该函数仅限于超级用户,但是其他用户可以被授予EXECUTE来运行此函数。 - + 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 @@ -5800,9 +5885,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage 重置由参数定义的复制槽的统计信息。 如果参数为NULL,则重置所有复制槽的统计信息。 - - 该函数默认仅限于超级用户,但可以授予其他用户EXECUTE权限来运行该函数。 - + 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 @@ -5817,9 +5900,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage 重置pg_stat_subscription_stats视图中显示的单个订阅的统计信息为零。 如果参数是NULL,则重置所有订阅的统计信息。 - - 默认情况下,此函数仅限超级用户使用,但其他用户可以被授予EXECUTE权限来运行该函数。 - + 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 @@ -5835,17 +5916,18 @@ description | Waiting for a newly initialized WAL file to reach durable storage - pg_stat_get_activitypg_stat_activity视图的底层函数, - 它返回一个行集合,其中包含有关每个后端进程所有可用的信息。有时只获得该信息的一个子集可能会更方便。 - 在那些情况中,可以使用一组更老的针对每个后端的统计访问函数,这些显示在中。 - 这些访问函数使用一个后端 ID 号,范围从 1 到当前活动后端数目。 - 函数pg_stat_get_backend_idset提供了一种方便的方法为每个活动后端产生一行来调用这些函数。 - 例如,要显示PID以及所有后端当前的查询: + pg_stat_get_activitypg_stat_activity 视图的底层函数, + 返回一组记录,其中包含有关每个后端进程的全部可用信息。有时只获取其中一部分信息会更方便。 + 在这种情况下,可以使用另一组针对每个后端的统计信息访问函数,见 。 + 这些访问函数使用会话的后端 ID 号,它是一个值较小的非负整数(>= 0),与任何并发会话的后端 ID 都不同, + 但会话退出后,其 ID 可立即被重新使用。后端 ID 的用途之一是标识会话的临时模式(如果有)。 + 函数 pg_stat_get_backend_idset 提供了一种便捷的方法,可列出所有活动后端的 ID 号来调用这些函数。 + 例如,要显示所有后端的 PID 和当前查询: -SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - pg_stat_get_backend_activity(s.backendid) AS query - FROM (SELECT pg_stat_get_backend_idset() AS backendid) AS s; +SELECT pg_stat_get_backend_pid(backendid) AS pid, + pg_stat_get_backend_activity(backendid) AS query +FROM pg_stat_get_backend_idset() AS backendid; @@ -5867,19 +5949,6 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - - - - pg_stat_get_backend_idset - - pg_stat_get_backend_idset () - setof integer - - - 返回当前活动后端ID号的集合(从1到活动后端数)。 - - - @@ -5899,7 +5968,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, pg_stat_get_backend_activity_start pg_stat_get_backend_activity_start ( integer ) - 有时区的时间戳 + timestamp with time zone 返回后端最近一次查询开始的时间。 @@ -5945,6 +6014,19 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, + + + + pg_stat_get_backend_idset + + pg_stat_get_backend_idset () + setof integer + + + 返回当前活动后端 ID 号的集合。 + + + @@ -5964,11 +6046,9 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, pg_stat_get_backend_start pg_stat_get_backend_start ( integer ) - 有时区的时间戳 + timestamp with time zone - - 返回该进程开始的时间。 - + 返回该进程开始的时间。 @@ -6000,28 +6080,28 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - pg_stat_get_backend_wait_event_type + pg_stat_get_backend_wait_event - pg_stat_get_backend_wait_event_type ( integer ) + pg_stat_get_backend_wait_event ( integer ) text - 如果后端当前正在等待,则返回等待事件类型名称,否则返回NULL。 - 请参阅。 + 如果后端当前正在等待,则返回等待事件名称,否则为空值。 + 请参阅 - pg_stat_get_backend_wait_event + pg_stat_get_backend_wait_event_type - pg_stat_get_backend_wait_event ( integer ) + pg_stat_get_backend_wait_event_type ( integer ) text - 如果后端当前正在等待,则返回等待事件名称,否则为NULL。 - 请参阅。 + 如果后端当前正在等待,则返回等待事件类型名称,否则返回空值。 + 请参阅 @@ -6031,7 +6111,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, pg_stat_get_backend_xact_start pg_stat_get_backend_xact_start ( integer ) - 有时区的时间戳 + timestamp with time zone 返回后端当前事务开始的时间。 @@ -6049,23 +6129,23 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, 查看锁 - lock - monitoring + + 监控 - 监控数据库活动的另外一个有用的工具是pg_locks系统表。这样就允许数据库管理员查看在锁管理器里面未解决的锁的信息。例如,这个功能可以被用于: + 监控数据库活动的另外一个有用的工具是pg_locks系统表。这样就允许数据库管理员查看锁管理器中当前存在的锁的信息。例如,这个功能可以被用于: - 查看当前所有未解决的锁、在一个特定数据库中的关系上所有的锁、在一个特定关系上所有的锁,或者由一个特定PostgreSQL会话持有的所有的锁。 + 查看当前存在的所有锁、在一个特定数据库中的关系上所有的锁、在一个特定关系上所有的锁,或者由一个特定PostgreSQL会话持有的所有的锁。 - 判断当前数据库中带有最多未授予锁的关系(它很可能是数据库客户端的竞争源)。 + 判断当前数据库中带有最多未授予锁的关系(它可能是数据库客户端之间的竞争来源)。 @@ -6232,7 +6312,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, delay_time double precision - 因基于成本的延迟而睡眠的总时间(参见),以毫秒计(如果启用了 ,否则为零)。 + 因基于代价的延迟而睡眠的总时间(参见),以毫秒计(如果启用了 ,否则为零)。 @@ -6264,14 +6344,14 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, acquiring sample rows - 该命令当前正在扫描relid给出的表以获得样例行。 + 该命令当前正在扫描relid给出的表以获得样本行。 acquiring inherited sample rows - 该命令当前正在扫描子表以获得样例行。列child_tables_total,child_tables_done, + 该命令当前正在扫描子表以获得样本行。列child_tables_totalchild_tables_done、 和current_child_table_relid包含此阶段的进度信息。 @@ -6279,14 +6359,14 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, computing statistics - 该命令从表扫描期间获得的样例行计算统计信息。 + 该命令从表扫描期间获得的样本行计算统计信息。 computing extended statistics - 该命令从表扫描期间获得的样例行计算扩展统计信息。 + 该命令从表扫描期间获得的样本行计算扩展统计信息。 @@ -6302,29 +6382,25 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - - 注意当在分区表上运行ANALYZE时,它的所有分区也会被递归分析。 - 在这种情况下,首先报告父表的ANALYZE进度,收集它的继承统计信息,然后是每个分区的(继承统计信息)。 - + 请注意,当在分区表上运行ANALYZE且未指定ONLY关键字时,其所有分区也会被递归分析。在这种情况下,会先报告父表的ANALYZE进度,并收集其继承统计信息,随后再报告每个分区的进度。 - + - CREATE INDEX 进度报告 + CLUSTER 进度报告 - pg_stat_progress_create_index + pg_stat_progress_cluster - 每当运行CREATE INDEXREINDEX时,pg_stat_progress_create_index视图将包含当前正在创建索引的每个后端的一行。 - 下面的表描述了将要报告的信息,并提供了关于如何解释它的信息。 + 每当CLUSTERVACUUM FULL运行时,pg_stat_progress_cluster视图将为每个当前正在运行这两种命令之一的后端包含一行。下面的表格描述了将被报告的信息,并提供了关于如何解释这些信息的信息。 -
+
- <structname>pg_stat_progress_create_index</structname> 视图 + <structname>pg_stat_progress_cluster</structname> 视图 @@ -6372,229 +6448,313 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, relidoid - 正在创建索引的表的OID。 + 正在聚簇的表的OID。 - index_relid oid + command text - 正在创建或重建索引的OID。在非并发 CREATE INDEX的时候,此为 0。 + 正在运行的命令。CLUSTERVACUUM FULL - command text + phase text - 在运行的命令: CREATE INDEX,CREATE INDEX CONCURRENTLY, - REINDEX, 或 REINDEX CONCURRENTLY. + 当前处理阶段。参见 - phase text + cluster_index_relid oid - 索引创建的当前处理阶段。 参见 。 + 如果正在使用索引对表进行扫描,这就是正在使用的索引的OID;否则为0。 - lockers_total bigint + heap_tuples_scanned bigint - 在适用的情况下,需要等待的储物柜总数 + 扫描的堆元组数。 + 该计数器仅在阶段为seq scanning heapindex scanning heap + 或 writing new heap 时才会递增。 - lockers_done bigint + heap_tuples_written bigint - 已经等待的储物柜数量。 + 写入的堆元组的数量。这个计数器只有在阶段为seq scanning heapindex scanning heap + 或 writing new heap时才会递增。 - current_locker_pid bigint + heap_blks_total bigint - 目前正在等待的储物柜的进程ID。 + 表中的堆块总数。 这个数字以seq scanning heap开始时的数量为准。 - blocks_total bigint + heap_blks_scanned bigint - 本阶段要处理的区块总数。 + 扫描的堆块数量。该计数器仅在阶段为seq scanning heap时才会递增。 - blocks_done bigint + index_rebuild_count bigint - 当前阶段已经处理的区块数量。 + 已重建的索引数。该计数器仅在rebuilding index阶段时才会递增。 + + +
+ + + + CLUSTER 和 VACUUM FULL 阶段 + + + + + + + 阶段 + 描述 + + + + + + + initializing + + 命令正在准备开始扫描堆。这个阶段预计会非常短暂。 + + + + + seq scanning heap + + 该命令目前采用顺序扫描的方式对表进行扫描。 + + + + + index scanning heap + + CLUSTER目前正在使用索引扫描表。 + + + + + sorting tuples + + CLUSTER目前正在对元组进行排序。 + + + + + writing new heap + + CLUSTER目前正在写入新的堆。 + + + + + swapping relation files + + 目前,该命令正在将新建立的文件调换到位。 + + + + + rebuilding index + + 该命令目前正在重建一个索引。 + + + + + performing final cleanup + + 该命令正在执行最后的清理工作。 当此阶段完成后,CLUSTERVACUUM FULL将结束。 + + + + +
+
+ + + + COPY 进度报告 + + + pg_stat_progress_copy + + + + 当COPY正在运行时,pg_stat_progress_copy视图会为每个当前正在执行COPY命令的后端包含一行。下表描述了会报告哪些信息,以及应如何解释这些信息。 + + + + + <structname>pg_stat_progress_copy</structname> 视图 + + - tuples_total bigint + 列类型 - 当前阶段要处理的元组总数。 + 描述 + + + - tuples_done bigint + pid integer - 在当前阶段已经处理的元组数量。 + 后端的进程ID。 - partitions_total bigint + datid oid - 在分区表上创建索引时,该列被设置为要在其上创建索引的分区总数。 - 在REINDEX期间,此字段为0。 + 后端连接到的数据库的OID。 - partitions_done bigint + datname name - 当在分区表上创建索引时,该列被设置为在其上建立索引的分区数。 - 在REINDEX期间,此字段为0。 + 后端连接到的数据库的名称。 - - -
- - - - CREATE INDEX 的阶段 - - - - - - - 阶段 - 描述 - - - - 初始化 - - CREATE INDEXREINDEX正在准备创建索引。 这个阶段预计会非常短暂。 - - - - - 构建前等待读写器 - - CREATE INDEX CONCURRENTLYREINDEX CONCURRENTLY正在等待有可能看到表的写锁的事务完成。 当不在并发模式时,这个阶段会被跳过。lockers_totallockers_donecurrent_locker_pid 列包含了这个阶段的进度信息。 - - - - - 新建索引 - - 索引是由访问方法专用代码建立的。 在这一阶段,支持进度报告的访问方法填写自己的进度数据,子阶段在这一栏中表示。 通常情况下,blocks_totalblocks_done将包含进度数据,也可能包含tuples_totaltuples_done。 - + + relid oid + + + 执行COPY命令的表的OID。 + 如果从SELECT查询中复制,它被设置为0。 + - 在验证前等待读写器 - - CREATE INDEX CONCURRENTLYREINDEX CONCURRENTLY正在等待有可能写入表的事务完成写锁的事务。当不在并发模式时,这个阶段会被跳过。lockers_totallockers_donecurrent_locker_pid 列包含了这个阶段的进度信息。 - + + command text + + + 正在运行的命令: COPY FROMCOPY TO。 + - 索引验证:扫描索引 - - CREATE INDEX CONCURRENTLY正在扫描索引,搜索需要验证的元组。如果不是并发模式,则会跳过此阶段。列 blocks_total(设为索引总大小)和 blocks_done 包含该阶段的进度信息。 - + + type text + + 读取或写入数据的 I/O 类型:FILEPROGRAMPIPE(用于COPY FROM STDINCOPY TO STDOUT),或CALLBACK(例如在逻辑复制的初始表同步期间使用)。 - 索引验证:排序元组 - - CREATE INDEX CONCURRENTLY正在对索引扫描阶段的输出进行排序。 - + + bytes_processed bigint + + + 已经被COPY命令处理的字节数。 + - 索引验证:扫描表 - - CREATE INDEX CONCURRENTLY正在扫描表,以验证前两个阶段收集的索引元组。如果不是并发模式,则会跳过此阶段。blocks_total 列(设为表总大小)和 blocks_done 列包含该阶段的进度信息。 - + + bytes_total bigint + + + COPY FROM命令的源文件大小,以字节计。 + 如果不可用则设置为0。 + - 等待旧照 - - CREATE INDEX CONCURRENTLYREINDEX CONCURRENTLY正在等待可能看到表的事务释放快照。 当不处于并发模式时,这个阶段会被跳过。 lockers_totallockers_donecurrent_locker_pid 列包含了这个阶段的进度信息。 - + + tuples_processed bigint + + + 已经被COPY命令处理的元组数。 + - 标记 dead之前等待readers - - REINDEX CONCURRENTLY等待表上有读锁的事务完成后,再将旧索引标记为死索引。当不在并发模式时,这个阶段被跳过。lockers_totallockers_donecurrent_locker_pid 列包含了这个阶段的进度信息。 - + + tuples_excluded bigint + + + 没有处理的元组数,因为它们被COPY命令的WHERE子句所排除。 + - 在 dropping之前等待readers - - REINDEX CONCURRENTLY等待表上有读锁的事务完成后,再丢弃旧索引。当不在并发模式时,这个阶段被跳过。列 lockers_totallockers_donecurrent_locker_pid包含了这个阶段的进度信息。 - + + tuples_skipped bigint + + + 因包含格式错误的数据而被跳过的元组数。只有当 ON_ERROR 选项指定的值不是 stop 时,此计数器才会递增。 +
-
- + - VACUUM 进度报告 + CREATE INDEX 进度报告 - pg_stat_progress_vacuum + pg_stat_progress_create_index - 只要VACUUM正在运行,pg_stat_progress_vacuum视图就会为每个当前正在清理的后端(包括自动清理工作进程)包含一行。下表描述了将报告的信息,并说明如何解释这些信息。VACUUM FULL命令的进度通过pg_stat_progress_cluster报告,因为VACUUM FULLCLUSTER都会重写表,而常规的VACUUM只会原地修改表。参见。 + 每当运行CREATE INDEXREINDEX时,pg_stat_progress_create_index视图将包含当前正在创建索引的每个后端的一行。 + 下面的表描述了将要报告的信息,并提供了关于如何解释它的信息。 - +
- <structname>pg_stat_progress_vacuum</structname> 视图 + <structname>pg_stat_progress_create_index</structname> 视图 @@ -6614,9 +6774,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, pid integer - - 后端的进程ID。 - + 正在创建索引的后端的进程 ID。 @@ -6642,204 +6800,217 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, relid oid - 被vacuum的表的OID。 + 正在创建索引的表的OID。 - phase text + index_relid oid - vacuum的当前处理阶段。参见 。 + 正在创建或重建索引的OID。在非并发 CREATE INDEX的时候,此为 0。 - heap_blks_total bigint + command text - 该表中堆块的总数。这个数字在扫描开始时报告,之后增加的块将不会(并且不需要)被这个VACUUM访问。 + 具体命令类型: CREATE INDEXCREATE INDEX CONCURRENTLY、 + REINDEXREINDEX CONCURRENTLY - heap_blks_scanned bigint + phase text - 被扫描的堆块数量。由于visibility map被用来优化扫描,一些块将被跳过而不做检查, - 被跳过的块会被包括在这个总数中,因此当清理完成时这个数字最终将会等于heap_blks_total。 - 仅当处于扫描堆阶段时这个计数器才会前进。 + 索引创建的当前处理阶段。 参见 - heap_blks_vacuumed bigint + lockers_total bigint - - 被清理的堆块数量。除非表没有索引,这个计数器仅在处于清理堆阶段时才会前进。 - 不包含死亡元组的块会被跳过,因此这个计数器可能有时会向前跳跃一个比较大的增量。 - + 在适用的情况下,需要等待的持锁进程总数。 - index_vacuum_count bigint + lockers_done bigint - - 已完成的索引清理周期数。 - + 已完成等待的持锁进程数量。 - max_dead_tuple_bytes bigint + current_locker_pid bigint - - 在需要执行索引清理周期之前可存储的死亡元组数据量,取决于。 - + 当前正在等待的持锁进程的进程 ID。 - dead_tuple_bytes bigint + blocks_total bigint - 自上一个索引清理周期以来收集到的死亡元组数据量。 + 本阶段要处理的块总数。 - num_dead_item_ids bigint + blocks_done bigint - 自上一个索引清理周期以来收集到的死项标识符数量。 + 当前阶段已经处理的块数量。 - indexes_total bigint + tuples_total bigint - 将要执行 vacuum 或清理的索引总数。该数字会在 vacuuming indexescleaning up indexes 阶段开始时报告。 + 当前阶段要处理的元组总数。 - indexes_processed bigint + tuples_done bigint - 已处理的索引数量。该计数器只会在 vacuuming indexescleaning up indexes 阶段推进。 + 在当前阶段已经处理的元组数量。 - delay_time double precision + partitions_total bigint - - 因基于成本的延迟而睡眠的总时间(参见),以毫秒计(如果启用了 ,否则为零)。这包括任何相关并行工作进程的睡眠时间;不过,并行工作进程最多每秒才会上报一次自己的睡眠时间,因此该值可能略有滞后。 - + 要创建或附加索引的分区总数,包括直接分区和间接分区。在REINDEX期间,或索引未分区时,此值为0 + + + + + partitions_done bigint + + 已创建或附加索引的分区数量,包括直接分区和间接分区。在REINDEX期间,或索引未分区时,此值为0
- +
- VACUUM的阶段 + CREATE INDEX 阶段 - + 阶段 描述 + - + + initializing + + CREATE INDEXREINDEX正在准备创建索引。 这个阶段预计会非常短暂。 + + - - 初始化 - - VACUUM正在准备开始扫描堆。这个阶段应该很简短。 - - + + waiting for writers before build + + CREATE INDEX CONCURRENTLYREINDEX CONCURRENTLY正在等待持有写锁且可能看到该表的事务结束。 当不在并发模式时,这个阶段会被跳过。lockers_totallockers_donecurrent_locker_pid 列包含了这个阶段的进度信息。 + + - - 扫描堆 - - VACUUM正在扫描堆。如果需要,它将会对每个页面进行修建以及碎片整理,并且可能会执行冻结动作。heap_blks_scanned列可以用来监控扫描的进度。 - - + + building index + + 索引是由访问方法专用代码建立的。 在这一阶段,支持进度报告的访问方法填写自己的进度数据,子阶段在这一栏中表示。 通常情况下,blocks_totalblocks_done将包含进度数据,tuples_totaltuples_done也可能包含进度数据。 + + - - 清理索引 - - VACUUM当前正在清理索引。 - 如果一个表拥有索引,那么每次清理时这个阶段会在堆扫描完成后至少发生一次。 - 如果不足以存放找到的死亡元组(或者, 在autovacuum情况下,如果设置了) ,则每次清理时会多次清理索引。 - - + + waiting for writers before validation + + CREATE INDEX CONCURRENTLYREINDEX CONCURRENTLY正在等待持有写锁且可能写入该表的事务结束。当不在并发模式时,这个阶段会被跳过。lockers_totallockers_donecurrent_locker_pid 列包含了这个阶段的进度信息。 + + - - 清理堆 - - VACUUM当前正在清理堆。清理堆与扫描堆不是同一个概念,清理堆发生在每一次清理索引的实例之后。如果heap_blks_scanned小于heap_blks_total,系统将在这个阶段完成之后回去扫描堆;否则,系统将在这个阶段完成后开始清理索引。 - - + + index validation: scanning index + + CREATE INDEX CONCURRENTLY正在扫描索引,搜索需要验证的元组。如果不是并发模式,则会跳过此阶段。列 blocks_total(设为索引总大小)和 blocks_done 包含该阶段的进度信息。 + + - - 清除索引 - - VACUUM当前正在清除索引。这个阶段发生在堆被完全扫描并且对堆和索引的所有清理都已经完成以后。 - - + + index validation: sorting tuples + + CREATE INDEX CONCURRENTLY正在对索引扫描阶段的输出进行排序。 + + - - 截断堆 - - VACUUM正在截断堆,以便把关系尾部的空页面返还给操作系统。这个阶段发生在清除完索引之后。 - - + + index validation: scanning table + + CREATE INDEX CONCURRENTLY正在扫描表,以验证前两个阶段收集的索引元组。如果不是并发模式,则会跳过此阶段。blocks_total 列(设为表总大小)和 blocks_done 列包含该阶段的进度信息。 + + + + + waiting for old snapshots + + CREATE INDEX CONCURRENTLYREINDEX CONCURRENTLY正在等待可能看到表的事务释放快照。 当不处于并发模式时,这个阶段会被跳过。 lockers_totallockers_donecurrent_locker_pid 列包含了这个阶段的进度信息。 + + + + + waiting for readers before marking dead + + REINDEX CONCURRENTLY等待表上有读锁的事务完成后,再将旧索引标记为死索引。当不在并发模式时,这个阶段被跳过。lockers_totallockers_donecurrent_locker_pid 列包含了这个阶段的进度信息。 + + - - 执行最终清理 - - VACUUM正在执行最终清理。在此阶段,VACUUM将清理空闲空间映射, - 更新pg_class中的统计信息,并向累积统计系统报告统计信息。当此阶段完成时, - VACUUM将结束。 - - - + + waiting for readers before dropping + + REINDEX CONCURRENTLY等待表上有读锁的事务完成后,再丢弃旧索引。当不在并发模式时,这个阶段被跳过。列 lockers_totallockers_donecurrent_locker_pid包含了这个阶段的进度信息。 + + +
- + - CLUSTER 进度报告 + VACUUM 进度报告 - pg_stat_progress_cluster + pg_stat_progress_vacuum - 每当CLUSTERVACUUM FULL运行时,pg_stat_progress_cluster视图将包含当前正在运行的每一个后台的记录。下面的表格描述了将被报告的信息,并提供了关于如何解释这些信息的信息。 + 只要VACUUM正在运行,pg_stat_progress_vacuum视图就会为每个当前正在清理的后端(包括自动清理工作进程)包含一行。下表描述了将报告的信息,并说明如何解释这些信息。VACUUM FULL命令的进度通过pg_stat_progress_cluster报告,因为VACUUM FULLCLUSTER都会重写表,而常规的VACUUM只会原地修改表。参见 - +
- <structname>pg_stat_progress_cluster</structname> 视图 + <structname>pg_stat_progress_vacuum</structname> 视图 @@ -6887,91 +7058,118 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, relidoid - 被集群的表的OID。 + 正在清理的表的OID。 - command text + phase text - 正在运行的命令。CLUSTERVACUUM FULL。 + 清理的当前处理阶段。参见 - phase text + heap_blks_total bigint - 当前处理阶段。参见。 + 该表中堆块的总数。这个数字以扫描开始时的数量为准,之后增加的块将不会(并且不需要)被这个VACUUM访问。 - cluster_index_relid oid + heap_blks_scanned bigint - 如果正在使用索引对表进行扫描,这就是正在使用的索引的OID;否则为0。 + 被扫描的堆块数量。由于可见性映射被用来优化扫描,一些块将被跳过而不做检查, + 被跳过的块会被包括在这个总数中,因此当清理完成时这个数字最终将会等于heap_blks_total。 + 仅当处于scanning heap阶段时这个计数器才会前进。 - heap_tuples_scanned bigint + heap_blks_vacuumed bigint - 扫描的堆元组数。 - 该计数器仅在阶段为seq scanning heapindex scanning heap - 或 writing new heap 时才会递增。 + 被清理的堆块数量。除非表没有索引,这个计数器仅在处于vacuuming heap阶段时才会前进。 + 不包含死亡元组的块会被跳过,因此这个计数器可能有时会向前跳跃一个比较大的增量。 - heap_tuples_written bigint + index_vacuum_count bigint - 写入的堆元组的数量。这个计数器只有在阶段为seq scanning heap,index scanning heap - 或 writing new heap时才会前进。 + 已完成的索引清理周期数。 - heap_blks_total bigint + max_dead_tuple_bytes bigint - 表中的堆块总数。 这个数字是在seq scanning heap的开始时报告的。 + 在需要执行索引清理周期之前可存储的死亡元组数据量,取决于 - heap_blks_scanned bigint + dead_tuple_bytes bigint - 扫描的堆块数量。该计数器仅在阶段为seq scanning heap时才会递增。 + 自上一个索引清理周期以来收集到的死亡元组数据量。 - index_rebuild_count bigint + num_dead_item_ids bigint + + + 自上一个索引清理周期以来收集到的死项标识符数量。 + + + + + + indexes_total bigint + + + 将要执行清理或收尾清理的索引总数。该数字会在 vacuuming indexescleaning up indexes 阶段开始时报告。 + + + + + + indexes_processed bigint + + + 已处理的索引数量。该计数器只会在 vacuuming indexescleaning up indexes 阶段推进。 + + + + + + delay_time double precision - 已重建的索引数。该计数器仅在重建索引阶段时才会递增。 + 因基于代价的延迟而睡眠的总时间(参见),以毫秒计(如果启用了 ,否则为零)。这包括任何相关并行工作进程的睡眠时间;不过,并行工作进程最多每秒才会上报一次自己的睡眠时间,因此该值可能略有滞后。
- +
- CLUSTER 和 VACUUM FULL 阶段 + VACUUM 阶段 @@ -6986,63 +7184,57 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - 初始化 - - 该命令准备开始扫描堆栈。 这个阶段预计会非常短暂。 - - - - - seq扫描堆 + initializing - 该命令目前采用顺序扫描的方式对表进行扫描。 + VACUUM正在准备开始扫描堆。这个阶段应该很简短。 - 索引扫描堆 + scanning heap - CLUSTER目前正在使用索引扫描表。 + VACUUM正在扫描堆。如果需要,它将会对每个页面进行剪枝以及碎片整理,并且可能会执行冻结动作。heap_blks_scanned列可以用来监控扫描的进度。 - 元组排序 - - CLUSTER目前正在对元组进行排序。 - + vacuuming indexes + VACUUM当前正在清理索引。如果表有索引,每次清理都会在堆扫描完成后至少执行一次此阶段。如果(或者,对于自动清理,已设置的)不足以存储找到的死亡元组数量,则每次清理可能多次执行此阶段。 - 新写入堆 + vacuuming heap - CLUSTER目前正在编写新的堆。 + VACUUM当前正在清理堆。清理堆与扫描堆不是同一个概念,清理堆发生在每次索引清理之后。如果heap_blks_scanned小于heap_blks_total,系统将在这个阶段完成之后回去扫描堆;否则,系统将在这个阶段完成后开始索引收尾清理。 - 交换关系文件 + cleaning up indexes - 目前,该命令正在将新建立的文件调换到位。 + VACUUM当前正在进行索引收尾清理。这个阶段发生在堆被完全扫描并且对堆和索引的所有清理都已经完成以后。 - 重建索引 + truncating heap - 该命令目前正在重建一个索引。 + VACUUM正在截断堆,以便把关系尾部的空页面返还给操作系统。这个阶段发生在索引收尾清理完成之后。 - 清理 + performing final cleanup - 该命令正在执行最后的清理工作。 当此阶段完成后,CLUSTERVACUUM FULL将结束。 + VACUUM正在执行最终清理。在此阶段,VACUUM将清理空闲空间映射, + 更新pg_class中的统计信息,并向累积统计系统报告统计信息。当此阶段完成时, + VACUUM将结束。
+
@@ -7103,7 +7295,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, 将被流式传输的数据总量。该值在streaming database files阶段开始时进行估算并报告。 注意,这只是一个近似值,因为数据库可能会在streaming database files阶段期间发生变化,而 WAL 日志也可能在稍后的备份阶段被包含进来。 一旦流式传输的数据量超过了估计的总大小,该值始终与backup_streamed相同。 - 如果在pg_basebackup中禁用估算(也就是说,指定了--no-estimate-size选项),这为NULL。 + 如果在pg_basebackup中禁用估算(也就是说,指定了--no-estimate-size选项),这为NULL。 @@ -7160,7 +7352,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - 等待检查点完成 + waiting for checkpoint to finish WAL 发送进程当前正在执行pg_backup_start以准备进行基础备份,并等待备份起始检查点完成。 @@ -7181,7 +7373,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - 等待wal归档完成 + waiting for wal archiving to finish WAL发送进程当前正在执行pg_backup_stop以完成备份, 并等待基础备份所需的所有 WAL 文件成功归档。 @@ -7204,141 +7396,6 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - - - COPY 进度报告 - - - pg_stat_progress_copy - - - - 当COPY正在运行时,pg_stat_progress_copy视图会为每个当前正在执行COPY命令的后端包含一行。下表描述了会报告哪些信息,以及应如何解释这些信息。 - - - - - <structname>pg_stat_progress_copy</structname> 视图 - - - - - - 列类型 - - - 描述 - - - - - - - - - pid integer - - - 后端的进程ID。 - - - - - - datid oid - - - 后端连接到的数据库的OID。 - - - - - - datname name - - - 后端连接到的数据库的名称。 - - - - - - relid oid - - - 执行COPY命令的表的OID。 - 如果从SELECT查询中复制,它被设置为0。 - - - - - - command text - - - 正在运行的命令: COPY FROM, 或 COPY TO。 - - - - - - type text - - - 数据被读取或写入的io类型:FILE, PROGRAM, PIPE (对于COPY FROM STDINCOPY TO STDOUT),或 CALLBACK(例如在逻辑复制中初始表同步期间使用)。 - - - - - - bytes_processed bigint - - - 已经被COPY命令处理的字节数。 - - - - - - bytes_total bigint - - - COPY FROM命令的源文件大小,以字节计。 - 如果不可用则设置为0。 - - - - - - tuples_processed bigint - - - 已经被COPY命令处理的元组数。 - - - - - - tuples_excluded bigint - - - 没有处理的元组数,因为它们被COPY命令的WHERE子句所排除。 - - - - - - tuples_skipped bigint - - - 因包含格式错误的数据而被跳过的元组数。只有当 ON_ERROR 选项指定的值不是 stop 时,此计数器才会递增。 - - - - -
-
- @@ -7364,7 +7421,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - 动态追踪的编译 + 为动态追踪编译 默认情况下,探针是不可用的,因此你将需要显式地告诉配置脚本让探针在PostgreSQL中可用。要包括 DTrace 支持,在配置时指定。更多信息请见。 @@ -7376,7 +7433,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, 内置探针 - 如所示,源代码中提供了一些标准探针。显式了在探针中使用的类型。当然,可以增加更多探针来增强PostgreSQL的可观测性。 + 如所示,源代码中提供了一些标准探针。显示了在探针中使用的类型。当然,可以增加更多探针来增强PostgreSQL的可观测性。 @@ -7412,13 +7469,13 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, transaction-abort (LocalTransactionId) - 当一个事务失败完成时触发的探针。arg0 是事务 ID。 + 当一个事务失败结束时触发的探针。arg0 是事务 ID。 query-start (const char *) - 当一个查询的处理被开始时触发的探针。arg0 是查询字符串。 + 当一个查询的处理开始时触发的探针。arg0 是查询字符串。 @@ -7430,7 +7487,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, query-parse-start (const char *) - 当一个查询的解析被开始时触发的探针。arg0 是查询字符串。 + 当一个查询的解析开始时触发的探针。arg0 是查询字符串。 @@ -7442,7 +7499,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, query-rewrite-start (const char *) - 当一个查询的重写被开始时触发的探针。arg0 是查询字符串。 + 当一个查询的重写开始时触发的探针。arg0 是查询字符串。 @@ -7454,7 +7511,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, query-plan-start () - 当一个查询的规划被开始时触发的探针。 + 当一个查询的规划开始时触发的探针。 @@ -7466,7 +7523,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, query-execute-start () - 当一个查询的执行被开始时触发的探针。 + 当一个查询的执行开始时触发的探针。 @@ -7484,19 +7541,19 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, checkpoint-start (int) - 当一个检查点被开始时触发的探针。arg0 传递位标志来区分不同的检查点类型,例如关闭(shutdown)、立即(immediate)或强制(force)。 + 当一个检查点开始时触发的探针。arg0 传递位标志来区分不同的检查点类型,例如关闭(shutdown)、立即(immediate)或强制(force)。 checkpoint-done (int, int, int, int, int) - 当一个检查点完成时触发的探针(检查点处理过程中序列中列出的下一个触发的探针)。arg0 是要写的缓冲区数量。arg1 是缓冲区的总数。arg2、arg3 和 arg4 分别包含了增加、删除和循环回收的 WAL 文件的数量。 + 当一个检查点完成时触发的探针(下面列出的探针会在检查点处理过程中依次触发)。arg0 是已写入的缓冲区数量。arg1 是缓冲区的总数。arg2、arg3 和 arg4 分别包含了增加、删除和循环回收的 WAL 文件的数量。 clog-checkpoint-start (bool) - 当一个检查点的 CLOG 部分被开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 + 当一个检查点的 CLOG 部分开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 @@ -7508,7 +7565,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, subtrans-checkpoint-start (bool) - 当一个检查点的 SUBTRANS 部分被开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 + 当一个检查点的 SUBTRANS 部分开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 @@ -7520,7 +7577,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, multixact-checkpoint-start (bool) - 当一个检查点的 MultiXact 部分被开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 + 当一个检查点的 MultiXact 部分开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 @@ -7532,7 +7589,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, buffer-checkpoint-start (int) - 当一个检查点的写缓冲区部分被开始时触发的探针。arg0 传递位标志来区分不同的检查点类型,例如关闭(shutdown)、立即(immediate)或强制(force)。 + 当一个检查点的写缓冲区部分开始时触发的探针。arg0 传递位标志来区分不同的检查点类型,例如关闭(shutdown)、立即(immediate)或强制(force)。 @@ -7568,7 +7625,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, twophase-checkpoint-start () - 当一个检查点的两阶段部分被开始时触发的探针。 + 当一个检查点的两阶段部分开始时触发的探针。 @@ -7577,22 +7634,54 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, 当一个检查点的两阶段部分完成时触发的探针。 + + buffer-extend-start + (ForkNumber, BlockNumber, Oid, Oid, Oid, int, unsigned int) + 当关系扩展开始时触发的探针。 + arg0 包含要扩展的分支。arg1、arg2 和 arg3 包含用于标识该关系的 + 表空间、数据库和关系 OID。对于本地缓冲区,arg4 是创建临时关系的后端 ID; + 对于共享缓冲区,则为 INVALID_PROC_NUMBER(-1)。 + arg5 是调用者希望扩展的块数。 + + + + buffer-extend-done + (ForkNumber, BlockNumber, Oid, Oid, Oid, int, unsigned int, BlockNumber) + 当关系扩展完成时触发的探针。 + arg0 包含要扩展的分支。arg1、arg2 和 arg3 包含用于标识该关系的 + 表空间、数据库和关系 OID。对于本地缓冲区,arg4 是创建临时关系的后端 ID; + 对于共享缓冲区,则为 INVALID_PROC_NUMBER(-1)。 + arg5 是关系实际扩展的块数;由于资源限制,该值可能小于 + buffer-extend-start中的数量。arg6 包含第一个新块的 + BlockNumber。 + + buffer-read-start - (ForkNumber, BlockNumber, Oid, Oid, Oid, int, bool) - 当一次缓冲区读被开始时触发的探针。arg0 和 arg1 包含该页的分叉号和块号(如果这是一次关系扩展请求,arg1 为 -1)。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是 InvalidBackendId(-1)。arg6 为真表示一次关系扩展请求,为假表示正常读。 + (ForkNumber, BlockNumber, Oid, Oid, Oid, int) + 当缓冲区读取开始时触发的探针。 + arg0 和 arg1 包含该页的分支号和块号。 + arg2、arg3 和 arg4 包含用于标识该关系的表空间、数据库和关系 OID。 + 对于本地缓冲区,arg5 是创建临时关系的后端 ID;对于共享缓冲区, + 则为 INVALID_PROC_NUMBER(-1)。 + buffer-read-done - (ForkNumber, BlockNumber, Oid, Oid, Oid, int, bool, bool) - 当一次缓冲区读完成时触发的探针。arg0 和 arg1 包含该页的分叉号和块号(如果这是一次关系扩展请求,arg1 现在包含新增加块的块号)。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是 InvalidBackendId(-1)。arg6 为真表示一次关系扩展请求,为假表示正常读。arg7 为真表示在池中找到该缓冲区,为假表示没有找到。 + (ForkNumber, BlockNumber, Oid, Oid, Oid, int, bool) + 当缓冲区读取完成时触发的探针。 + arg0 和 arg1 包含该页的分支号和块号。 + arg2、arg3 和 arg4 包含用于标识该关系的表空间、数据库和关系 OID。 + 对于本地缓冲区,arg5 是创建临时关系的后端 ID;对于共享缓冲区, + 则为 INVALID_PROC_NUMBER(-1)。 + 如果在缓冲池中找到了该缓冲区,arg6 为真;否则为假。 buffer-flush-start (ForkNumber, BlockNumber, Oid, Oid, Oid) - 在发出对一个共享缓冲区的任意写请求之前触发的探针。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。 + 在发出对一个共享缓冲区的任意写请求之前触发的探针。arg0 和 arg1 包含该页的分支号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。 @@ -7601,17 +7690,9 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, 当一个写请求完成时触发的探针(注意这只反映传递数据给内核的时间,它通常并没有实际地被写入到磁盘)。参数和buffer-flush-start的相同。 - - buffer-write-dirty-start - (ForkNumber, BlockNumber, Oid, Oid, Oid) - 当一个服务器进程开始写一个脏缓冲区时触发的探针(如果这经常发生,表示太小,或需要调整后台写入器的控制参数)。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。 - - - buffer-write-dirty-done - (ForkNumber, BlockNumber, Oid, Oid, Oid) - 当一次脏缓冲区写完成时触发的探针。参数与buffer-write-dirty-start相同。 - + + wal-buffer-write-dirty-start @@ -7622,13 +7703,13 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, wal-buffer-write-dirty-done () - 当一次脏 WAL 缓冲区完成时触发的探针。 + 当一次脏 WAL 缓冲区写入完成时触发的探针。 wal-insert (unsigned char, unsigned char) - 当一个 WAL 记录被插入时触发的探针。arg0 是该记录的资源管理者(rmid)。arg1 包含 info 标志。 + 当一个 WAL 记录被插入时触发的探针。arg0 是该记录的资源管理器(rmid)。arg1 包含 info 标志。 @@ -7640,31 +7721,31 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, smgr-md-read-start (ForkNumber, BlockNumber, Oid, Oid, Oid, int) - 当开始从一个关系读取一块时触发的探针。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。 + 当开始从一个关系读取一块时触发的探针。arg0 和 arg1 包含该页的分支号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是INVALID_PROC_NUMBER(-1)。 smgr-md-read-done (ForkNumber, BlockNumber, Oid, Oid, Oid, int, int, int) - 当一次块读取完成时触发的探针。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。arg6 是实际读取的字节数,而 arg7 是请求读取的字节数(如果两者不同就意味着麻烦)。 + 当一次块读取完成时触发的探针。arg0 和 arg1 包含该页的分支号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是INVALID_PROC_NUMBER(-1)。arg6 是实际读取的字节数,而 arg7 是请求读取的字节数(如果两者不同,则表示发生了短读)。 smgr-md-write-start (ForkNumber, BlockNumber, Oid, Oid, Oid, int) - 当开始向一个关系中写入一个块时触发的探针。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。 + 当开始向一个关系中写入一个块时触发的探针。arg0 和 arg1 包含该页的分支号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是INVALID_PROC_NUMBER(-1)。 smgr-md-write-done (ForkNumber, BlockNumber, Oid, Oid, Oid, int, int, int) - 当一个块写操作完成时触发的探针。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3和arg4 包含表空间、数据库和关系 OID来标识该关系。对于一个本地缓冲区,arg5 是创建临时关系的后端 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。arg6 是实际写的字节数,而 arg7 是要求写的字节数(如果这两者不同,则意味着麻烦)。 + 当一个块写操作完成时触发的探针。arg0 和 arg1 包含该页的分支号和块号。arg2、arg3和arg4 包含表空间、数据库和关系 OID来标识该关系。对于一个本地缓冲区,arg5 是创建临时关系的后端 ID;对于一个共享缓冲区,arg5 是INVALID_PROC_NUMBER(-1)。arg6 是实际写的字节数,而 arg7 是要求写的字节数(如果这两者不同,则表示发生了短写)。 sort-start (int, bool, int, int, bool, int) - 当一次排序操作开始时触发的探针。arg0 指示是堆排序、索引排序或数据排序。arg1 为真表示强制唯一值。arg2 是键列数。arg3 是允许使用的工作内存大小(以千字节计)。如果要求随机访问排序结果,则 arg4 为真。arg5 为 0 时表示串行,为 1 时表示并行工作进程,为 2 时表示并行领导者。 + 当一次排序操作开始时触发的探针。arg0 指示是堆排序、索引排序或 datum 排序。arg1 为真表示强制唯一值。arg2 是键列数。arg3 是允许使用的工作内存大小(以千字节计)。如果要求随机访问排序结果,则 arg4 为真。arg5 为 0 时表示串行,为 1 时表示并行工作进程,为 2 时表示并行领导者。 @@ -7678,7 +7759,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, (char *, LWLockMode) 当成功获得一个 LWLock 时触发的探针。 arg0 是该 LWLock 所在的切片(Tranche)。 - arg1 所请求的锁模式,是排他或共享。 + arg1 是所请求的锁模式,是排他或共享。 @@ -7693,34 +7774,34 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, (char *, LWLockMode) 当一个 LWLock不是当即可用并且一个服务器进程因此开始等待该锁变为可用时触发的探针。 arg0 是该 LWLock 所在的切片(Tranche)。 - arg1 请求的锁模式,是排他或共享。 + arg1 是所请求的锁模式,是排他或共享。 lwlock-wait-done (char *, LWLockMode) 当一个进程从对一个 LWLock 的等待中被释放时(它实际还没有得到该锁)时触发的探针。arg0 是该 LWLock 所在的切片(Tranche)。 - arg1 所请求的锁模式,是排他或共享。 + arg1 是所请求的锁模式,是排他或共享。 lwlock-condacquire (char *, LWLockMode) 当调用者指定无需等待而成功获得一个 LWLock 时触发的探针。arg0 是该 LWLock 所在的切片(Tranche)。 - arg1 所请求的锁模式,是排他或共享。 + arg1 是所请求的锁模式,是排他或共享。 lwlock-condacquire-fail (char *, LWLockMode) 当调用者指定无需等待而没有成功获得一个 LWLock 时触发的探针。arg0 是该 LWLock 所在的切片(Tranche)。 - arg1 所请求的锁模式,是排他或共享。 + arg1 是所请求的锁模式,是排他或共享。 lock-wait-start (unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, LOCKMODE) - 当一个重量级锁(lmgr锁)的请求由于锁不可用开始等待时触发的探针。arg0 到 arg3 是标识被锁定对象的标签域。arg4 指示被锁对象的类型。arg5 表示被请求的锁类型。 + 当一个重量级锁(lmgr锁)的请求由于锁不可用开始等待时触发的探针。arg0 到 arg3 是标识被锁定对象的标签字段。arg4 指示被锁对象的类型。arg5 表示被请求的锁类型。 @@ -7741,7 +7822,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid,
- 定义用在探针参数中的类型 + 探针参数中使用的已定义类型 @@ -7835,7 +7916,7 @@ Total time (ns) 2312105013 - 你应该记住,DTrace 脚本需要细心地编写和调试,否则被收集的追踪信息可能会毫无意义。在大部分发现问题的情况中,它就是发生问题的部件,而不是底层系统。当讨论使用动态追踪发现的信息时,一定要附上使用的脚本以便其也被检查和讨论。 + 你应该记住,DTrace 脚本需要细心地编写和调试,否则被收集的追踪信息可能会毫无意义。在大多数发现问题的情况下,出错的是插桩,而不是底层系统。当讨论使用动态追踪发现的信息时,一定要附上使用的脚本以便其也被检查和讨论。 @@ -7851,7 +7932,7 @@ Total time (ns) 2312105013 - 决定探针名称以及探针可用的数据 + 决定探针名称以及要通过探针提供的数据 @@ -7865,7 +7946,7 @@ Total time (ns) 2312105013 - 如果pg_trace.h还不存在于包含该探针点的模块中,包括它,并且在源代码中期望的位置插入TRACE_POSTGRESQL探针宏 + 如果pg_trace.h尚未被包含该探针点的模块引用,则将它包含进来,并且在源代码中期望的位置插入TRACE_POSTGRESQL探针宏 @@ -7901,14 +7982,14 @@ Total time (ns) 2312105013 probe transaction__start(LocalTransactionId); - 注意探针名字中双下划线的使用。在一个使用探针的 DTrace 脚本中,双下划线需要被替换为一个连字符,因此 ,对用户而言transaction-start是文档名。 + 注意探针名字中双下划线的使用。在一个使用探针的 DTrace 脚本中,双下划线需要被替换为一个连字符,因此,文档中应向用户说明的名称是transaction-start - 在编译时,transaction__start被转换成一个宏调用TRACE_POSTGRESQL_TRANSACTION_START(注意这里是单下划线),可以通过包括头文件pg_trace.h获得。将宏调用加入到源代码中的合适位置。在这种情况下,看起来类似: + 在编译时,transaction__start被转换成一个名为TRACE_POSTGRESQL_TRANSACTION_START的宏(注意这里是单下划线),可以通过包含头文件pg_trace.h获得。将宏调用加入到源代码中的合适位置。在这种情况下,看起来类似: TRACE_POSTGRESQL_TRANSACTION_START(vxid.localTransactionId); @@ -7945,7 +8026,7 @@ TRACE_POSTGRESQL_TRANSACTION_START(vxid.localTransactionId); - 在大多数平台上,如果用编译了PostgreSQL,无论何时当控制经过一个追踪宏时,都会评估该宏的参数,即使没有进行追踪也会这样做。通常不需要担心你是否只在报告一些局部变量的值。但是要注意不要将开销大的函数调用放入参数中。如果你需要这样做,考虑通过检查追踪是否真的被启用来保护该宏: + 在大多数平台上,如果用编译了PostgreSQL,无论何时当控制经过一个追踪宏时,都会对该宏的参数求值,即使没有进行追踪也会这样做。如果只是报告少数局部变量的值,通常无需担心这一点。但是要注意不要将开销大的函数调用放入参数中。如果你需要这样做,考虑通过检查追踪是否真的被启用来保护该宏: if (TRACE_POSTGRESQL_TRANSACTION_START_ENABLED()) @@ -7986,7 +8067,7 @@ if (TRACE_POSTGRESQL_TRANSACTION_START_ENABLED()) - 在最近执行过 VACUUMANALYZE 的数据库上使用 psql,你可以发出查询来查看任意表的磁盘使用情况: + 在最近进行过清理或分析 的数据库上使用 psql,你可以发出查询来查看任意表的磁盘使用情况: SELECT pg_relation_filepath(oid), relpages FROM pg_class WHERE relname = 'customer'; diff --git a/zh/18/mvcc.sgml b/zh/18/mvcc.sgml index 44bc1d14..0de66ba0 100644 --- a/zh/18/mvcc.sgml +++ b/zh/18/mvcc.sgml @@ -4,7 +4,7 @@ 并发控制 - concurrency + 并发 @@ -15,7 +15,7 @@ 介绍 - Multiversion Concurrency Control + 多版本并发控制 @@ -23,7 +23,7 @@ - Serializable Snapshot Isolation + 可串行化快照隔离 @@ -50,7 +50,7 @@ 事务隔离 - transaction isolation + 事务隔离 @@ -68,7 +68,7 @@ 脏读 - dirty read + 脏读 @@ -80,7 +80,7 @@ 不可重复读 - nonrepeatable read + 不可重复读 @@ -92,7 +92,7 @@ 幻读 - phantom read + 幻读 @@ -104,7 +104,7 @@ 串行化异常 - serialization anomaly + 串行化异常 @@ -117,7 +117,7 @@ - transaction isolation level + 事务隔离级别 SQL 标准以及 PostgreSQL 实现的事务隔离级别见 @@ -244,12 +244,12 @@ 读已提交隔离级别 - transaction isolation level - read committed + 事务隔离级别 + 读已提交 - read committed + 读已提交 @@ -334,7 +334,7 @@ COMMIT; 在读已提交模式下,更复杂的用法可能产生不理想的结果。例如,考虑一个 - DELETE 命令,它所处理的数据会被另一个命令同时加入和移出其筛选条件。 + DELETE 命令,另一个命令正在修改数据,使某些行开始满足其筛选条件、另一些行不再满足。 假设 website 是一个有两行的表,其中 website.hits 分别等于 910: @@ -342,7 +342,7 @@ COMMIT; BEGIN; UPDATE website SET hits = hits + 1; --- run from another session: DELETE FROM website WHERE hits = 10; +-- 从另一个会话运行: DELETE FROM website WHERE hits = 10; COMMIT; @@ -370,12 +370,12 @@ COMMIT; 可重复读隔离级别 - transaction isolation level - repeatable read + 事务隔离级别 + 可重复读 - repeatable read + 可重复读 @@ -428,9 +428,7 @@ ERROR: could not serialize access due to concurrent update 可重复读模式提供了严格的保证,即每个事务都看到数据库的一个完全稳定的视图。 不过,这个视图并不一定总能与同一级别并发事务的某种串行(一次一个)执行保持一致。 - 例如,即使该级别上的只读事务可能看到一条控制记录被更新,表明某个批处理已经完成, - 但它并不一定能看到作为该批处理逻辑组成部分的某条明细记录, - 因为它读到的是控制记录的较早版本。如果不仔细使用显式锁来阻塞冲突事务, + 例如,即使是该级别的只读事务,也可能看到一条表明某批次已完成的控制记录,却看不到逻辑上属于该批次的某条明细记录,因为创建该明细记录的事务读取了控制记录的较早版本。如果不仔细使用显式锁来阻塞冲突事务, 试图依靠运行在这一隔离级别的事务来强制业务规则,往往无法正确工作。 @@ -438,7 +436,7 @@ ERROR: could not serialize access due to concurrent update 可重复读隔离级别是通过一种技术实现的,这种技术在学术数据库文献中以及某些其他数据库产品中被称为 快照隔离。与使用会降低并发性的传统加锁技术的系统相比, 其行为和性能可能会表现出差异。有些其他系统甚至把可重复读和快照隔离作为两个行为不同的独立隔离级别提供。 - 用来区分这两种技术的允许现象,直到 SQL 标准制定之后才被数据库研究人员正式定义,因此超出了本手册的范围。 + 用来区分这两种技术的允许现象,直到 SQL 标准制定之后才被数据库研究人员正式定义,并且超出了本手册的范围。 完整讨论请参阅 @@ -454,20 +452,20 @@ ERROR: could not serialize access due to concurrent update 可串行化隔离级别 - transaction isolation level - serializable + 事务隔离级别 + 可串行化 - serializable + 可串行化 - predicate locking + 谓词锁 - serialization anomaly + 串行化异常 @@ -480,48 +478,30 @@ ERROR: could not serialize access due to concurrent update 一旦检测到可能导致串行化异常的条件,就会触发串行化失败 - - 例如,考虑一张表 mytab,其初始内容为: - + 例如,考虑表mytab,它最初包含以下内容: class | value -------+------- 1 | 10 1 | 20 2 | 100 2 | 200 - - 假设可串行化事务 A 计算: - +假设可串行化事务 A 执行以下计算: SELECT SUM(value) FROM mytab WHERE class = 1; - - 然后将结果(30)作为一条新行的 value 插入,并把 - class 设为 2。与此同时,可串行化事务 B 计算: - +然后将结果(30)作为新行的value插入,且该行满足class = 2。与此同时,可串行化事务 B 执行以下计算: SELECT SUM(value) FROM mytab WHERE class = 2; - - 并得到结果 300,再把它插入为一条新行,其 - class1。然后两个事务都尝试提交。 - 如果任一事务是在可重复读隔离级别下运行,则二者都可以提交; - 但由于不存在与该结果一致的串行执行顺序,使用可串行化事务时将允许其中一个事务提交, - 并按如下消息回滚另一个事务: - - +得到结果 300,并将它插入一个新行,该行满足class = 1。然后两个事务都尝试提交。如果任一事务运行在可重复读隔离级别,两个事务都可以提交;但由于不存在与该结果一致的串行执行顺序,使用可串行化事务时,只会允许一个事务提交,另一个则会被回滚,并收到以下消息: ERROR: could not serialize access due to read/write dependencies among transactions - - - 这是因为,如果 A 先于 B 执行,B 算出的和将是 330 而不是 300; - 反过来,另一种顺序也会使 A 算出不同的和。 - +这是因为,如果 A 在 B 之前执行,B 算出的总和应该是 330,而不是 300;同样,按另一种顺序执行,A 算出的总和也会不同。 当依赖可串行化事务来防止异常时,重要的是:从永久用户表读取的任何数据,在读取它的事务成功提交之前, - 都不应视为有效。即使对于只读事务也是如此;唯一的例外是可推迟只读事务中读取的数据, + 都不应视为有效。即使对于只读事务也是如此;唯一的例外是可延迟只读事务中读取的数据, 它一经读出就可视为有效,因为这种事务会等到能够获取一个保证不存在此类问题的快照后才开始读取数据。 在所有其他情况下,应用不能依赖后来被中止事务中读到的结果;相反,应重试事务直到成功。 - 为了保证真正的可串行化,PostgreSQL 使用了谓词锁, + 为了保证真正的可串行性,PostgreSQL 使用了谓词锁, 也就是说,系统会保留一些锁,以便判断某个写操作如果先发生,是否会影响并发事务先前读取的结果。 在 PostgreSQL 中,这些锁不会造成任何阻塞,因此会参与形成死锁。 它们用于识别并标记并发可串行化事务之间的依赖关系,而这些依赖在某些组合下可能导致串行化异常。 @@ -543,7 +523,7 @@ ERROR: could not serialize access due to read/write dependencies among transact - 持续使用可串行化事务可以简化开发。任何一组成功提交的并发可串行化事务,都保证与把它们一次一个运行的效果相同;这意味着,如果你能够证明某个事务在单独运行时会做正确的事,那么即使不了解其他事务会做什么,也可以相信它在任何可串行化事务的混合执行中也会做正确的事,否则它就不会成功提交。重要的是,采用这种技术的环境应当有一套通用机制来处理串行化失败(其 SQLSTATE 值总是 40001),因为很难准确预测究竟哪些事务会对读/写依赖关系有贡献,并因此需要被回滚来防止串行化异常。监视读/写依赖关系会带来开销,被串行化失败中止的事务重新启动也会带来开销;但在把这些开销与显式锁以及 SELECT FOR UPDATESELECT FOR SHARE 所涉及的成本和阻塞进行权衡之后,可串行化事务在某些环境中仍然是性能最佳的选择。 + 统一采用可串行化事务可以简化开发。任何一组成功提交的并发可串行化事务,都保证与把它们一次一个运行的效果相同;这意味着,如果你能够证明某个事务在单独运行时会做正确的事,那么即使不了解其他事务会做什么,也可以相信它在任何可串行化事务的混合执行中也会做正确的事,否则它就不会成功提交。重要的是,采用这种技术的环境应当有一套通用机制来处理串行化失败(其 SQLSTATE 值总是 40001),因为很难准确预测究竟哪些事务会对读/写依赖关系有贡献,并因此需要被回滚来防止串行化异常。监视读/写依赖关系会带来开销,被串行化失败中止的事务重新启动也会带来开销;但在把这些开销与显式锁以及 SELECT FOR UPDATESELECT FOR SHARE 所涉及的成本和阻塞进行权衡之后,可串行化事务在某些环境中仍然是性能最佳的选择。 @@ -587,7 +567,7 @@ ERROR: could not serialize access due to read/write dependencies among transact - 当系统因谓词锁表内存不足而被迫把多个页级谓词锁合并为单个关系级谓词锁时,串行化失败的比例可能会上升。你可以通过增加 来避免这种情况。 + 当系统因谓词锁表内存不足而被迫把多个页级谓词锁合并为单个关系级谓词锁时,串行化失败的比例可能会上升。你可以通过增加 和/或 来避免这种情况。 @@ -611,7 +591,7 @@ ERROR: could not serialize access due to read/write dependencies among transact 显式锁定 - lock + @@ -715,7 +695,7 @@ ERROR: could not serialize access due to read/write dependencies among transact CREATE STATISTICSCOMMENT ONREINDEX CONCURRENTLY, 以及某些 ALTER INDEX - 和 ALTER TABLE 变体会获取这种锁 + 和 ALTER TABLE 变体获取这种锁 (有关详细信息,请参阅这些命令的文档)。 @@ -980,7 +960,7 @@ ERROR: could not serialize access due to read/write dependencies among transact - 行为与 FOR SHARE 类似,不过锁更弱:SELECT FOR UPDATE 会被阻塞,但 SELECT FOR NO KEY UPDATE 不会。键共享锁会阻塞其他事务执行会修改键值的 DELETEUPDATE,但不会阻塞其他 UPDATE,也不会阻止 SELECT FOR NO KEY UPDATESELECT FOR SHARESELECT FOR KEY SHARE。 + 行为与 FOR SHARE 类似,不过锁更弱:SELECT FOR UPDATE 会被阻塞,但 SELECT FOR NO KEY UPDATE 不会。键共享锁会阻塞其他事务执行 DELETE 或任何会修改键值的 UPDATE,但不会阻塞其他 UPDATE,也不会阻止 SELECT FOR NO KEY UPDATESELECT FOR SHARESELECT FOR KEY SHARE @@ -1058,7 +1038,7 @@ ERROR: could not serialize access due to read/write dependencies among transact 死锁 - deadlock + 死锁 @@ -1101,12 +1081,12 @@ UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 22222; 咨询锁 - advisory lock + 咨询锁 - lock - advisory + + 咨询 @@ -1138,12 +1118,12 @@ UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 22222; 在某些使用咨询锁的方法中,特别是涉及显式排序和 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(id) FROM foo WHERE id = 12345; -- 可以 +SELECT pg_advisory_lock(id) FROM foo WHERE id > 12345 LIMIT 100; -- 危险! SELECT pg_advisory_lock(q.id) FROM ( SELECT id FROM foo WHERE id > 12345 LIMIT 100 -) q; -- ok +) q; -- 可以 在上面的查询中,第二种形式是危险的,因为不能保证在执行加锁函数之前先应用 LIMIT。 这可能导致获取了一些应用并未预期的锁,因此应用也不会去释放它们(直到会话结束)。 @@ -1161,12 +1141,12 @@ SELECT pg_advisory_lock(q.id) FROM 应用级别的数据一致性检查 - 在读已提交事务下,想要通过业务规则强制数据一致性非常困难,因为数据视图会随每条语句而变化, + 用读已提交事务强制执行有关数据完整性的业务规则非常困难,因为数据视图会随每条语句而变化, 而且一旦发生写冲突,即使是单条语句也未必局限于该语句自己的快照。 - 虽然可重复读事务在整个执行期间都具有稳定的数据视图,但在使用 MVCC 快照进行数据一致性检查时,还存在一个微妙问题,即所谓的读/写冲突。如果一个事务写入数据,而并发事务试图读取相同的数据(无论是在写入之前还是之后),它都看不到另一个事务的工作。于是,读取者看起来就像是先执行的一方,而不管究竟是谁先启动,也不管谁先提交。如果事情只停留在这一步,就没有问题;但如果读取者还写入了数据,而这些数据又被另一个并发事务读取,那么现在就会有一个事务看起来像是在前面提到的任一事务之前执行。如果看起来最后执行的事务实际上最先提交,就很容易在事务执行顺序图中形成一个环。一旦出现这样的环,不借助额外机制,一致性检查就无法正确工作。 + 虽然可重复读事务在整个执行期间都具有稳定的数据视图,但在使用 MVCC 快照进行数据一致性检查时,还存在一个微妙问题,即所谓的读/写冲突。如果一个事务写入数据,而并发事务试图读取相同的数据(无论是在写入之前还是之后),它都看不到另一个事务的工作。于是,读取者看起来就像是先执行的一方,而不管究竟是谁先启动,也不管谁先提交。如果事情只停留在这一步,就没有问题;但如果读取者还写入了数据,而这些数据又被另一个并发事务读取,那么现在就会有一个事务看起来像是在前面提到的任一事务之前执行。如果看起来最后执行的事务实际上最先提交,就很容易在事务执行顺序图中形成一个环。一旦出现这样的环,不借助额外机制,完整性检查就无法正确工作。 @@ -1183,7 +1163,7 @@ SELECT pg_advisory_lock(q.id) FROM - 使用这种技术时,如果应用软件通过某个框架运行,并由该框架自动重试因串行化错误而回滚的事务,就可以避免给应用程序员带来不必要的负担。把 default_transaction_isolation 设置为 serializable 可能是个好主意。通过在触发器中检查事务隔离级别来采取某些措施,以确保不会因为疏忽或为了绕过完整性检查而使用其他事务隔离级别,也是明智的。 + 使用这种技术时,如果应用软件通过某个框架运行,并由该框架自动重试因串行化失败而回滚的事务,就可以避免给应用程序员带来不必要的负担。把 default_transaction_isolation 设置为 serializable 可能是个好主意。通过在触发器中检查事务隔离级别来采取某些措施,以确保不会因为疏忽或为了绕过完整性检查而使用其他事务隔离级别,也是明智的。 @@ -1200,7 +1180,7 @@ SELECT pg_advisory_lock(q.id) FROM - 使用显式锁定强制一致性 + 使用显式阻塞锁强制一致性 当存在非可串行化写入时,要确保某一行当前仍然有效,并保护它不受并发更新影响, @@ -1223,7 +1203,7 @@ SELECT pg_advisory_lock(q.id) FROM 在非可串行化的 MVCC 环境下,全局有效性检查需要额外考虑。 - 例如,一个银行应用可能希望检查一个表中的所有收入总和等于另一个表中的所有支出总和, + 例如,一个银行应用可能希望检查一个表中的贷方金额总和等于另一个表中的借方金额总和, 而这两个表都在被活跃更新。在读已提交模式下,比较两个连续的 SELECT sum(...) 命令的结果并不可靠,因为第二个查询很可能会包含第一个查询没有统计到的事务提交结果。 在单个可重复读事务中完成这两次求和,只能准确反映在该可重复读事务开始之前已提交事务的效果 @@ -1251,10 +1231,10 @@ SELECT pg_advisory_lock(q.id) FROM 串行化失败处理 - serialization failure + 串行化失败 - retryable error + 可重试错误 @@ -1291,7 +1271,7 @@ SELECT pg_advisory_lock(q.id) FROM 重试事务并不保证重试后的事务一定能够完成;可能需要多次重试。 在争用非常激烈的情况下,完成一个事务可能需要尝试很多次。 - 如果涉及相互冲突的已准备事务,那么在已准备事务提交或回滚之前,可能根本无法取得进展。 + 如果涉及相互冲突的预备事务,那么在预备事务提交或回滚之前,可能根本无法取得进展。 @@ -1319,8 +1299,8 @@ SELECT pg_advisory_lock(q.id) FROM 锁定和索引 - index - locks + 索引 + @@ -1333,7 +1313,7 @@ SELECT pg_advisory_lock(q.id) FROM - 读写访问使用短期的页级共享/排他锁。每个索引行在被取出或插入之后,锁都会立即释放。这些索引类型在不存在死锁条件的前提下提供了最高的并发性。 + 读写访问使用短期的页级共享/排他锁。每个索引行在被取出或插入之后,锁都会立即释放。这些索引类型提供最高的并发性,并且不会产生死锁。 @@ -1355,7 +1335,7 @@ SELECT pg_advisory_lock(q.id) FROM - 读写访问使用短期的页级共享/排他锁。每个索引行在被取出或插入之后,锁都会立即释放。但要注意,插入一个 GIN 索引值通常会导致每行产生多个索引键插入,因此 GIN 可能为了插入单个值而做大量工作。 + 读写访问使用短期的页级共享/排他锁。每个索引行在被取出或插入之后,锁都会立即释放。但要注意,插入一个使用 GIN 索引的值通常会导致每行产生多个索引键插入,因此 GIN 可能为了插入单个值而做大量工作。 diff --git a/zh/18/oauth-validators.sgml b/zh/18/oauth-validators.sgml index f5b90e49..844616e9 100644 --- a/zh/18/oauth-validators.sgml +++ b/zh/18/oauth-validators.sgml @@ -92,7 +92,7 @@ 也可以通过部署架构的带外知识在没有显式作用域的情况下完成客户端授权, - 但这样会把用户排除在环路之外, + 但这样会让用户无法参与授权过程, 用户将无法发现部署错误,而此类错误也可能被静默利用。 如果不提示用户授予额外作用域, 则对数据库的访问必须被严格限制为仅允许受信任客户端 @@ -184,7 +184,7 @@ 模块必须保持可被信号中断, 这样服务器才能正确处理认证超时和来自 pg_ctl 的停机信号。 - 例如,套接字上的阻塞调用通常应替换为可无竞争地同时处理 + 例如,套接字上的阻塞调用通常应替换为能够在没有竞争条件的情况下同时处理 套接字事件与中断的代码(见 WaitLatchOrSocket()WaitEventSetWait() 等), 且长时间运行的循环应定期调用 @@ -208,10 +208,10 @@ 文档 - 验证器实现应记录针对每个终端用户向服务器报告的认证 ID 的内容和格式, + 验证器实现应在文档中说明针对每个终端用户向服务器报告的认证 ID 的内容和格式, 因为 DBA 可能需要据此构造 pg_ident 映射。 (例如,它是邮箱地址?组织 ID 号?还是 UUID?) - 还应记录该模块在 + 还应在文档中说明该模块在 delegate_ident_mapping=1 模式下是否可安全使用, 以及为此需要哪些额外配置。 @@ -230,7 +230,7 @@ 不过,OAuth 本身就是授权框架, 令牌也可能携带用户权限信息。 例如,令牌可能包含用户所属组织组的信息, - 或列出用户可承担的角色, + 或列出用户可使用的角色, 将这些信息复制到每台服务器的本地用户名映射中可能并不理想。 diff --git a/zh/18/oid2name.sgml b/zh/18/oid2name.sgml index 4b80f64a..40bb461a 100644 --- a/zh/18/oid2name.sgml +++ b/zh/18/oid2name.sgml @@ -8,7 +8,7 @@ oid2name 1 - Application + 应用程序 diff --git a/zh/18/pageinspect.sgml b/zh/18/pageinspect.sgml index 46b0b0c9..5a7090c6 100644 --- a/zh/18/pageinspect.sgml +++ b/zh/18/pageinspect.sgml @@ -370,20 +370,20 @@ test=# SELECT itemoffset, ctid, itemlen, nulls, vars, data, dead, htid, tids[0:2 13 | (16,8292) | 616 | f | f | 2f 00 00 00 00 00 00 00 | f | (4,17) | {"(4,17)","(4,21)"} (13 rows) - 这是一个 B-树叶页。所有指向表的元组恰好都是 posting list 元组(它们总共存储了 100 个 6 字节的 TID)。此外,在itemoffset 编号 1 处还有一个high key元组。这个示例中,ctid用于存储每个元组的编码信息,不过叶页元组通常会直接在ctid字段中存储一个堆 TID。tids是作为 posting list 存储的 TID 列表。 + 这是一个 B-树叶页。所有指向表的元组恰好都是倒排列表元组(每个都存储了 100 个 6 字节的 TID)。此外,在itemoffset 编号 1 处还有一个高键元组。这个示例中,ctid用于存储每个元组的编码信息,不过叶页元组通常会直接在ctid字段中存储一个堆 TID。tids是作为倒排列表存储的 TID 列表。 在内部页(此处未显示)中,ctid的块号部分是一个downlink(下行链接),也就是该索引中另一页的块号。ctid的偏移部分(第二个数字)存储着关于该元组的编码信息,例如实际存在的列数(后缀截断可能移除了不需要的后缀列)。被截断的列被视为具有minus infinity值。 - htid显示该元组的堆 TID,而不考虑底层元组表示形式。这个值可能与ctid相同,也可能是从 posting list 元组以及内部页元组所使用的替代表示中解码出来的。内部页中的元组通常会把实现层面的堆 TID 列截断掉,这会表现为htid值为 NULL。 + htid显示该元组的堆 TID,而不考虑底层元组表示形式。这个值可能与ctid相同,也可能是从倒排列表元组以及内部页元组所使用的替代表示中解码出来的。内部页中的元组通常会把实现层面的堆 TID 列截断掉,这会表现为htid值为 NULL。 - 请注意,任何非最右页(即btpo_next字段值非零的页面)的第一项都是该页的high key,这意味着它的data充当该页上所有项的上界,而它的ctid字段并不指向另一个块。另外,在内部页上,第一个真正的数据项(第一个不是high key的项)一定会把所有列都截断掉,因此其data字段中没有实际值。不过,这样的项在其ctid字段中确实有一个有效的下行链接。 + 请注意,任何非最右页(即btpo_next字段值非零的页面)的第一项都是该页的高键,这意味着它的data充当该页上所有项的上界,而它的ctid字段并不指向另一个块。另外,在内部页上,第一个真正的数据项(第一个不是高键的项)一定会把所有列都截断掉,因此其data字段中没有实际值。不过,这样的项在其ctid字段中确实有一个有效的下行链接。 - 关于 B-树索引结构的更多细节,参见。关于去重和 posting list 的更多细节,参见。关于去重和倒排列表的更多细节,参见 diff --git a/zh/18/parallel.sgml b/zh/18/parallel.sgml index 424f847e..8beb9974 100644 --- a/zh/18/parallel.sgml +++ b/zh/18/parallel.sgml @@ -222,7 +222,7 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%'; - Parallel Append + 并行追加 每当 PostgreSQL 需要将来自多个源的行合并成一个结果集时,它就会使用 AppendMergeAppend 计划节点。这种情况常见于实现 UNION ALL 或扫描分区表时。这样的节点和其他任何计划中的情形一样,也可以用于并行计划。不过,在并行计划中,规划器也可能改用 Parallel Append 节点。 @@ -300,7 +300,7 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%'; - 如果函数或聚合会写数据库、修改事务状态(而不是通过子事务进行错误恢复)、访问序列,或者对设置做持久更改,那么它们必须标记为 PARALLEL UNSAFE。类似地,如果函数访问临时表、客户端连接状态、游标、预备语句,或者系统无法在工作进程之间同步的各种后端本地状态,那么它必须标记为 PARALLEL RESTRICTED。例如,setseedrandom 就因为最后一个原因而属于并行受限。 + 如果函数或聚合会写数据库、修改事务状态(使用子事务进行错误恢复的情况除外)、访问序列,或者对设置做持久更改,那么它们必须标记为 PARALLEL UNSAFE。类似地,如果函数访问临时表、客户端连接状态、游标、预备语句,或者系统无法在工作进程之间同步的各种后端本地状态,那么它必须标记为 PARALLEL RESTRICTED。例如,setseedrandom 就因为最后一个原因而属于并行受限。 diff --git a/zh/18/perform.sgml b/zh/18/perform.sgml index 174ef662..9041ebfa 100644 --- a/zh/18/perform.sgml +++ b/zh/18/perform.sgml @@ -819,9 +819,9 @@ EXPLAIN ANALYZE SELECT * FROM tenk1 WHERE unique1 < 100 AND unique2 > 9000 of the planner - + - 单列统计信息 + <anchor id="zh18-auto-perform-sect2-1" xreflabel="单列统计信息"/>单列统计信息 如上一节所见,查询规划器需要估计查询将检索多少行,才能对查询计划做出良好选择。本节简要介绍系统用于这些估计的统计信息。 @@ -956,9 +956,9 @@ WHERE tablename = 'road'; 下面的小节介绍当前支持的扩展统计信息类型。 - + - 函数依赖 + <anchor id="zh18-auto-perform-sect3-1" xreflabel="函数依赖"/>函数依赖 最简单的一类扩展统计信息跟踪函数依赖,这是数据库范式定义中使用的概念。如果知道列a的值就足以确定列b的值,也就是说,不存在两行具有相同的a值却拥有不同的b值,那么就称列b函数依赖于列a。在完全规范化的数据库中,函数依赖应当只存在于主键和超键上。不过在实践中,很多数据集出于各种原因并未完全规范化,常见情形之一就是为了性能而有意进行反规范化。即使在完全规范化的数据库中,某些列之间也可能存在部分相关性,这可以表现为部分函数依赖。 @@ -994,9 +994,9 @@ SELECT stxname, stxkeys, stxddependencies 在为涉及函数依赖列的查询计算选择度时,规划器会使用依赖系数来调整针对条件的选择度估计,这样就不会产生低估。 - + - 函数依赖的限制 + <anchor id="zh18-auto-perform-sect4-1" xreflabel="函数依赖的限制"/>函数依赖的限制 当前只有在考虑简单等值条件(将列与常量值比较)和具有常量值的IN @@ -1022,9 +1022,9 @@ SELECT * FROM zipcodes WHERE city = 'San Francisco' AND zip = '90210'; - + - 多元可区分值计数 + <anchor id="zh18-auto-perform-sect3-2" xreflabel="多元可区分值计数"/>多元可区分值计数 单列统计信息存储每一列中可区分值的数量。在组合多个列(例如GROUP BY a, b)时,如果规划器只有单列统计数据,则对可区分值数量的估计常常会错误,导致选择不好的计划。 @@ -1057,9 +1057,9 @@ nd | {"1, 2": 33178, "1, 5": 33178, "2, 5": 27435, "1, 2, 5": 33178} - + - 多元 MCV 列表 + <anchor id="zh18-auto-perform-sect3-3" xreflabel="多元 MCV 列表"/>多元 MCV 列表 另一类按列存储的统计信息是高频值列表。这允许对单列做出非常准确的估计,但对于同时涉及多个列条件的查询,仍可能产生显著误差。 diff --git a/zh/18/pgcrypto.sgml b/zh/18/pgcrypto.sgml index 9fa02a53..efc9101c 100644 --- a/zh/18/pgcrypto.sgml +++ b/zh/18/pgcrypto.sgml @@ -254,17 +254,17 @@ gen_salt(type text [, iter_count integer ]) returns text - type参数指定哈希算法。 + type参数指定 hash 算法。 接受的类型有:desxdesmd5bfsha256cryptsha512crypt。 最后两种即 sha256cryptsha512crypt, - 是现代的、基于 SHA-2 的密码哈希。 + 是现代的、基于 SHA-2 的密码 hash。 iter_count参数允许用户为支持该参数的算法指定迭代次数。 - 次数越高,密码哈希所需时间越长,从而破解它所需时间也越长。 - 不过,如果次数过高,计算一个哈希可能需要数年时间 — 这显然不切实际。 + 次数越高,对密码进行 hash 所需的时间越长,从而破解它所需时间也越长。 + 不过,如果次数过高,计算一个 hash 可能需要数年时间 — 这显然不切实际。 若省略iter_count参数,则使用默认迭代次数。 允许的iter_count值取决于算法,如所示。 @@ -308,12 +308,12 @@ gen_salt(type text [, iter_count integer ]) returns text - 为了选择合适的迭代次数,可以考虑原始 DES crypt 在当时硬件上的设计速度是每秒 4 次哈希。 - 低于每秒 4 次哈希可能会影响可用性,而高于每秒 100 次哈希则很可能过快。 + 为了选择合适的迭代次数,可以考虑原始 DES crypt 在当时硬件上的设计速度是每秒 4 次 hash。 + 低于每秒 4 次 hash 可能会影响可用性,而高于每秒 100 次 hash 则很可能过快。 - 概述了不同哈希算法之间的相对速度差异。 + 概述了不同 hash 算法之间的相对速度差异。 该表展示了在 8 字符密码上尝试所有字符组合所需的时间,假定密码只包含小写字母, 或者包含大小写字母和数字。在crypt-bf条目中, 斜杠后的数字是gen_saltiter_count参数值。 @@ -322,17 +322,17 @@ gen_salt(type text [, iter_count integer ]) returns text sha256cryptsha512crypt而言, 默认的iter_count5000 对现代硬件来说被认为过低, - 但可以调高以生成更强的密码哈希。除此之外, + 但可以调高以生成更强的密码 hash。除此之外, sha256cryptsha512crypt都被认为是安全的。
- 哈希算法速度 + Hash 算法速度 算法 - 每秒哈希次数 + 每秒 hash 次数 针对[a-z] 针对[A-Za-z0-9] 相对于md5 hash的耗时倍数 diff --git a/zh/18/plhandler.sgml b/zh/18/plhandler.sgml index 38562e46..4048d572 100644 --- a/zh/18/plhandler.sgml +++ b/zh/18/plhandler.sgml @@ -17,11 +17,11 @@ - 调用处理器与其他函数一样被调用:它会接收一个指向 FunctionCallInfoBaseData struct 的指针,其中包含参数值以及被调用函数的相关信息;同时它还应返回一个 Datum 结果(如果希望返回 SQL 空值结果,还可以设置 isnull 字段,也就是 FunctionCallInfoBaseData 结构体中的该字段)。调用处理器与普通被调函数之间的区别在于,flinfo->fn_oid 字段在 FunctionCallInfoBaseData 结构体中保存的是实际要调用函数的 OID,而不是调用处理器本身的 OID。调用处理器必须使用这个字段来判定要执行哪个函数。另外,传入的参数列表是按照目标函数而不是调用处理器的声明来设置的。 + 调用处理器与其他函数一样被调用:它会接收一个指向 FunctionCallInfoBaseData struct 的指针,其中包含参数值以及被调用函数的相关信息;同时它还应返回一个 Datum 结果(如果希望返回 SQL 空值结果,还需要设置 isnull 字段,也就是 FunctionCallInfoBaseData 结构体中的该字段)。调用处理器与普通被调函数之间的区别在于,flinfo->fn_oid 字段在 FunctionCallInfoBaseData 结构体中保存的是实际要调用函数的 OID,而不是调用处理器本身的 OID。调用处理器必须使用这个字段来判定要执行哪个函数。另外,传入的参数列表是按照目标函数而不是调用处理器的声明来设置的。 - 调用处理器必须从系统目录 pg_proc 中取出该函数的条目,并分析被调用函数的参数类型和返回类型。该函数的 AS 子句可在其 CREATE FUNCTION 命令对应的 prosrc 列里找到,也就是 pg_proc 行中的该列。这里通常是一段过程语言源文本,但理论上也可以是其他内容,例如某个文件的路径名,或者任何能详细告诉调用处理器该做什么的信息。 + 调用处理器必须从系统目录 pg_proc 中取出该函数的条目,并分析被调用函数的参数类型和返回类型。该函数的 CREATE FUNCTION 命令中的 AS 子句内容,保存在 pg_proc 对应行的 prosrc 列中。这里通常是一段过程语言源文本,但理论上也可以是其他内容,例如某个文件的路径名,或者任何能详细告诉调用处理器该做什么的信息。 @@ -46,7 +46,7 @@ 验证器函数通常应遵循 参数:如果它被关闭,就应跳过任何开销高昂或依赖上下文的检查。如果该语言允许在编译时执行代码,验证器还必须抑制会诱发此类执行的检查。特别是,pg_dump 会关闭这个参数,这样它就可以装载过程语言函数,而不必担心函数体对其他数据库对象的副作用或依赖关系。(正因为有这一要求,调用处理器不应假设验证器已经完整检查了函数。提供验证器的目的,并不是让调用处理器省略检查,而是在 CREATE FUNCTION 命令中存在明显错误时立即通知用户。)虽然究竟检查哪些内容主要由验证器函数自行决定,但要注意,核心 CREATE FUNCTION 代码只会执行附加到函数上的 SET 子句,前提是 check_function_bodies 打开。因此,当 check_function_bodies 关闭时,那些结果可能受 GUC 参数影响的检查肯定都应跳过,以避免在恢复转储时出现虚假的失败。 + linkend="guc-check-function-bodies"/> 参数:如果它被关闭,就应跳过任何开销高昂或依赖上下文的检查。如果该语言允许在编译时执行代码,验证器还必须抑制会诱发此类执行的检查。特别是,pg_dump 会关闭这个参数,这样它就可以装载过程语言函数,而不必担心副作用或函数体对其他数据库对象的依赖关系。(正因为有这一要求,调用处理器不应假设验证器已经完整检查了函数。提供验证器的目的,并不是让调用处理器省略检查,而是在 CREATE FUNCTION 命令中存在明显错误时立即通知用户。)虽然究竟检查哪些内容主要由验证器函数自行决定,但要注意,只有在 check_function_bodies 打开时,核心 CREATE FUNCTION 代码才会执行函数附带的 SET 子句。因此,当 check_function_bodies 关闭时,那些结果可能受 GUC 参数影响的检查肯定都应跳过,以避免在恢复转储时出现虚假的失败。 diff --git a/zh/18/plperl.sgml b/zh/18/plperl.sgml index 7fc5b272..a7da7851 100644 --- a/zh/18/plperl.sgml +++ b/zh/18/plperl.sgml @@ -13,7 +13,7 @@ - PL/Perl 是一种可载入的过程语言,它允许使用 + PL/Perl 是一种可加载的过程语言,它允许使用 Perl 编程语言编写 PostgreSQL 函数和过程。 @@ -32,8 +32,7 @@ - 如果把该语言安装到 template1 中,之后创建的所有 - 数据库都会自动安装该语言。 + 如果把某种语言安装到template1中,之后创建的所有数据库都会自动安装该语言。 @@ -57,9 +56,9 @@ CREATE FUNCTION funcname (argument-types) RETURNS return-type --- function attributes can go here +-- 函数属性可以写在这里 AS $$ - # PL/Perl function body goes here + # PL/Perl 函数体写在这里 $$ LANGUAGE plperl; @@ -78,7 +77,7 @@ $$ LANGUAGE plperl; DO $$ - # PL/Perl code + # PL/Perl 代码 $$ LANGUAGE plperl; @@ -136,15 +135,14 @@ $$ LANGUAGE plperl; 如果一个 SQL 空值空值in PL/Perl被传给一个函数,在 - Perl 中该参数值将呈现为undefined。上述函数定义对于 - 空输入的行为并不理想(实际上,它会把它们当作零)。我们可以在函数 + sortas="PL/Perl">在 PL/Perl 中被传给一个函数,在 + Perl 中该参数值将呈现为未定义。上述函数定义对于 + 空值输入的行为并不理想(实际上,它会把它们当作零)。我们可以在函数 定义中添加 STRICT,让 PostgreSQL 采取更合理的做法:如果传入空值, - 函数将根本不会被调用,而是自动返回空结果。另一种方式是在函数体中 + 函数将根本不会被调用,而是自动返回空值结果。另一种方式是在函数体中 检查未定义输入。例如,假设我们希望在 - perl_max 的两个参数中一个为空、另一个非空时, - 返回非空参数而不是空值: + perl_max 的两个参数中一个为空值、另一个非空值时,返回非空值参数而不是空值: CREATE FUNCTION perl_max (integer, integer) RETURNS integer AS $$ @@ -186,7 +184,7 @@ $$ LANGUAGE plperl; bool_plperl 扩展提供了合适的转换。要使用它, 请先安装该扩展: -CREATE EXTENSION bool_plperl; -- or bool_plperlu for PL/PerlU +CREATE EXTENSION bool_plperl; -- 对于 PL/PerlU,则使用 bool_plperlu 然后对接收或返回 bool 的 PL/Perl 函数使用 TRANSFORM 函数属性,例如: @@ -199,7 +197,7 @@ AS $$ $$ LANGUAGE plperl; 应用该转换后,Perl 会将 bool 参数视为 - 1 或空值,从而能正确表示真或假。如果函数结果类型为 + 1 或空字符串,从而能正确表示真或假。如果函数结果类型为 bool,则其真或假取决于 Perl 是否会将返回值求值为真。 对函数内部执行的 SPI 查询,其布尔查询参数和结果也会进行类似的转换 ()。 @@ -232,12 +230,12 @@ CREATE OR REPLACE FUNCTION concat_array_elements(text[]) RETURNS TEXT AS $$ my $result = ""; return undef if (!defined $arg); - # as an array reference + # 作为数组引用 for (@$arg) { $result .= $_; } - # also works as a string + # 也可以作为字符串使用 $result .= $arg; return $result; @@ -248,7 +246,8 @@ SELECT concat_array_elements(ARRAY['PL','/','Perl']); - 多维数组会以所有 Perl 程序员都熟悉的方式,表示为对低维数组引用的引用。 + 多维数组按 Perl 程序员熟悉的方式表示为指向较低维数组的引用, + 而这些数组的元素又是引用。 @@ -357,11 +356,11 @@ SELECT * FROM perl_set(); 如果希望在代码中使用 strict 编译指示,可以有几种 选择。对于临时的全局用法,可以 SET - plperl.use_strict 为 true。这会影响后续编译的 + plperl.use_strict 为真。这会影响后续编译的 PL/Perl 函数,但不会影响当前会话中已经编译的 函数。对于永久的全局用法,可以在 postgresql.conf 文件中将 - plperl.use_strict 设为 true。 + plperl.use_strict 设为真。 @@ -417,7 +416,7 @@ use strict; spi_exec_query(query [, limit]) spi_exec_query - in PL/Perl + 在 PL/Perl 中 @@ -503,7 +502,7 @@ SELECT * FROM test_munge(); spi_query(command) spi_query - in PL/Perl + 在 PL/Perl 中 @@ -511,7 +510,7 @@ SELECT * FROM test_munge(); spi_fetchrow(cursor) spi_fetchrow - in PL/Perl + 在 PL/Perl 中 @@ -519,7 +518,7 @@ SELECT * FROM test_munge(); spi_cursor_close(cursor) spi_cursor_close - in PL/Perl + 在 PL/Perl 中 @@ -539,7 +538,7 @@ CREATE OR REPLACE FUNCTION lotsa_md5 (INTEGER) RETURNS SETOF foo_type AS $$ my $file = '/usr/share/dict/words'; my $t = localtime; elog(NOTICE, "opening file $file at $t" ); - open my $fh, '<', $file # ooh, it's a file access! + open my $fh, '<', $file # 注意,这里访问了文件! or elog(ERROR, "cannot open $file for reading: $!"); my @words = <$fh>; close $fh; @@ -579,7 +578,7 @@ SELECT * from lotsa_md5(500); spi_prepare(command, argument types) spi_prepare - in PL/Perl + 在 PL/Perl 中 @@ -587,7 +586,7 @@ SELECT * from lotsa_md5(500); spi_query_prepared(plan, arguments) spi_query_prepared - in PL/Perl + 在 PL/Perl 中 @@ -595,7 +594,7 @@ SELECT * from lotsa_md5(500); spi_exec_prepared(plan [, attributes], arguments) spi_exec_prepared - in PL/Perl + 在 PL/Perl 中 @@ -603,7 +602,7 @@ SELECT * from lotsa_md5(500); spi_freeplan(plan) spi_freeplan - in PL/Perl + 在 PL/Perl 中 @@ -612,7 +611,7 @@ SELECT * from lotsa_md5(500); spi_preparespi_query_preparedspi_exec_preparedspi_freeplan - 提供相同的功能,但用于预处理查询。spi_prepare + 提供相同的功能,但用于预备查询。spi_prepare 接受一个带编号参数占位符($1、$2 等)的查询字符串,以及参数类型的 字符串列表: @@ -631,7 +630,7 @@ $plan = spi_prepare('SELECT * FROM test WHERE id > $1 AND name = $2', - 预处理查询的优点在于,一个准备好的计划可以用于多次查询执行。当计划 + 预备查询的优点在于,一个准备好的计划可以用于多次查询执行。当计划 不再需要时,可以用 spi_freeplan 将其释放: CREATE OR REPLACE FUNCTION init() RETURNS VOID AS $$ @@ -708,7 +707,7 @@ SELECT release_hosts_query(); spi_commit() spi_commit - in PL/Perl + 在 PL/Perl 中 @@ -716,7 +715,7 @@ SELECT release_hosts_query(); spi_rollback() spi_rollback - in PL/Perl + 在 PL/Perl 中 @@ -756,7 +755,7 @@ CALL transaction_test1(); - PL/Perl 中的工具函数 + PL/Perl 中的辅助函数 @@ -765,7 +764,7 @@ CALL transaction_test1(); elog(level, msg) elog - in PL/Perl + 在 PL/Perl 中 @@ -791,7 +790,7 @@ CALL transaction_test1(); quote_literal(string) quote_literal - in PL/Perl + 在 PL/Perl 中 @@ -812,7 +811,7 @@ CALL transaction_test1(); quote_nullable(string) quote_nullable - in PL/Perl + 在 PL/Perl 中 @@ -831,7 +830,7 @@ CALL transaction_test1(); quote_ident(string) quote_ident - in PL/Perl + 在 PL/Perl 中 @@ -850,7 +849,7 @@ CALL transaction_test1(); decode_bytea(string) decode_bytea - in PL/Perl + 在 PL/Perl 中 @@ -868,7 +867,7 @@ CALL transaction_test1(); encode_bytea(string) encode_bytea - in PL/Perl + 在 PL/Perl 中 @@ -885,7 +884,7 @@ CALL transaction_test1(); encode_array_literal(array) encode_array_literal - in PL/Perl + 在 PL/Perl 中 @@ -908,7 +907,7 @@ CALL transaction_test1(); encode_typed_literal(value, typename) encode_typed_literal - in PL/Perl + 在 PL/Perl 中 @@ -926,7 +925,7 @@ CALL transaction_test1(); encode_array_constructor(array) encode_array_constructor - in PL/Perl + 在 PL/Perl 中 @@ -947,7 +946,7 @@ CALL transaction_test1(); looks_like_number(string) looks_like_number - in PL/Perl + 在 PL/Perl 中 @@ -967,7 +966,7 @@ CALL transaction_test1(); is_array_ref(argument) is_array_ref - in PL/Perl + 在 PL/Perl 中 @@ -1025,9 +1024,9 @@ CREATE OR REPLACE FUNCTION myfuncs() RETURNS void AS $$ }; $$ LANGUAGE plperl; -SELECT myfuncs(); /* initializes the function */ +SELECT myfuncs(); /* 初始化函数 */ -/* Set up a function that uses the quote function */ +/* 创建一个使用加引号函数的函数 */ CREATE OR REPLACE FUNCTION use_quote(TEXT) RETURNS text AS $$ my $text_to_quote = shift; @@ -1042,11 +1041,9 @@ $$ LANGUAGE plperl; - 出于安全原因,PL/Perl 会为某个 SQL 角色调用的函数在该角色专用的独立 - Perl 解释器中执行。这可以防止一个用户意外或恶意地干扰另一个用户的 + 出于安全原因,PL/Perl 会在每个 SQL 角色各自独立的 Perl 解释器中执行该角色调用的函数。这可以防止一个用户意外或恶意地干扰另一个用户的 PL/Perl 函数行为。每个这样的解释器都有自己的 - %_SHARED 变量值和其他全局状态。因此,只有在两个 - PL/Perl 函数都由同一 SQL 角色执行时,它们才会共享 + %_SHARED 变量值和其他全局状态。因此,当且仅当两个 PL/Perl 函数都由同一 SQL 角色执行时,它们才会共享 %_SHARED 的值。在某些应用中,一个会话可能会在多个 SQL 角色下执行代码(通过 SECURITY DEFINER 函数、 使用 SET ROLE 等),这时可能需要显式采取措施, @@ -1059,29 +1056,29 @@ $$ LANGUAGE plperl; - 可信与不可信的 PL/Perl + 受信任与不受信任的 PL/Perl - trusted + 受信任的 PL/Perl 通常,PL/Perl 会被安装为一种名为 plperl 的 - 可信编程语言。在这种设置下,为了保持安全性,某些 Perl + 受信任的编程语言。在这种设置下,为了保持安全性,某些 Perl 操作会被禁用。一般来说,受限制的是那些与环境交互的操作,包括文件句柄 操作、requireuse (针对外部模块)。它无法像 C 函数那样访问数据库服务器进程的内部, - 也无法以服务器进程的权限获取操作系统级访问。因此,可以允许任何无权限 + 也无法以服务器进程的权限获取操作系统级访问。因此,可以允许任何无特权 的数据库用户使用这种语言。 - 可信 PL/Perl 依赖 Perl 的 Opcode 模块来维持安全性。 + 受信任的 PL/Perl 依赖 Perl 的 Opcode 模块来维持安全性。 Perl 的 文档 - 指出,该模块对于可信 PL/Perl 这一使用场景并不有效。若你的安全需求 + 指出,该模块对于受信任的 PL/Perl 这一使用场景并不有效。若你的安全需求 不能接受该警告中的不确定性,请考虑执行 REVOKE USAGE ON LANGUAGE plperl FROM PUBLIC @@ -1105,16 +1102,16 @@ $$ LANGUAGE plperl; 有时需要编写不受这些限制的 Perl 函数。例如,可能需要一个能发送邮件的 Perl 函数。为处理这类情况,也可以把 PL/Perl 安装成一种 - 不可信语言(通常称为 + 不受信任的语言(通常称为 PL/PerlUPL/PerlU)。 在这种情况下,完整的 Perl 语言都可用。安装该语言时,使用语言名 - plperlu 就会选择不可信的 PL/Perl 变体。 + plperlu 就会选择不受信任的 PL/Perl 变体。 PL/PerlU 函数的编写者必须注意,函数不能被 用于任何非预期用途,因为它能够执行以数据库管理员身份登录的用户所能 - 做的任何事情。请注意,数据库系统只允许数据库超级用户用不可信语言创建 + 做的任何事情。请注意,数据库系统只允许数据库超级用户用不受信任的语言创建 函数。 @@ -1249,7 +1246,7 @@ $$ LANGUAGE plperl; $_TD->{relname} - 触发该触发器的表名。该字段已废弃,并且可能会在未来版本中移除。 + 触发该触发器的表名。该字段已弃用,并且可能会在未来版本中移除。 请改用 $_TD->{table_name}。 @@ -1328,12 +1325,12 @@ CREATE TABLE test ( CREATE OR REPLACE FUNCTION valid_id() RETURNS trigger AS $$ if (($_TD->{new}{i} >= 100) || ($_TD->{new}{i} <= 0)) { - return "SKIP"; # skip INSERT/UPDATE command + return "SKIP"; # 跳过 INSERT/UPDATE 命令 } elsif ($_TD->{new}{v} ne "immortal") { $_TD->{new}{v} .= "(modified by trigger)"; - return "MODIFY"; # modify row and execute INSERT/UPDATE command + return "MODIFY"; # 修改行并执行 INSERT/UPDATE 命令 } else { - return; # execute INSERT/UPDATE command + return; # 执行 INSERT/UPDATE 命令 } $$ LANGUAGE plperl; @@ -1490,7 +1487,7 @@ DO 'elog(WARNING, join ", ", sort keys %INC)' LANGUAGE plperl; 也会发生。这是在 plperl.on_init 完成的任何初始化 之后进行的。执行这段代码时 SPI 函数不可用。 plperl.on_plperl_init 中的 Perl 代码是在对解释器 - 进行锁定之后执行的,因此只能执行可信操作。 + 进行锁定之后执行的,因此只能执行受信任的操作。 diff --git a/zh/18/plpgsql.sgml b/zh/18/plpgsql.sgml index 73d6dfb2..993a89fa 100644 --- a/zh/18/plpgsql.sgml +++ b/zh/18/plpgsql.sgml @@ -144,7 +144,7 @@ CREATE FUNCTION somefunc(integer, text) RETURNS integer AS 'function body text' LANGUAGE plpgsql; - 就 CREATE FUNCTION 而言,函数体目前只是一个字符串字面量。编写函数体时,通常最好使用美元引用(见 ),而不是普通的单引号语法。如果不使用美元引用,函数体中的任何单引号或反斜线都必须通过双写进行转义。本章几乎所有示例的函数体都使用了美元引用。 + 就 CREATE FUNCTION 而言,函数体只是一个字符串字面量。编写函数体时,通常最好使用美元引用(见 ),而不是普通的单引号语法。如果不使用美元引用,函数体中的任何单引号或反斜线都必须通过双写进行转义。本章几乎所有示例的函数体都使用了美元引用。 @@ -340,7 +340,7 @@ $$ LANGUAGE plpgsql; - 当 PL/pgSQL 函数声明了输出参数时,输出参数也会像普通输入参数一样获得 $n 名称和可选别名。输出参数本质上是一个初始值为 NULL 的变量,应在函数执行期间给它赋值。该参数的最终值就是返回值。例如,sales-tax 的示例也可以这样写: + 当 PL/pgSQL 函数声明了输出参数时,输出参数也会像普通输入参数一样获得 $n 名称和可选别名。输出参数本质上是一个初始值为 NULL 的变量,应在函数执行期间给它赋值。该参数的最终值就是返回值。例如,销售税的示例也可以这样写: CREATE FUNCTION sales_tax(subtotal real, OUT tax real) AS $$ @@ -465,7 +465,7 @@ $$ LANGUAGE plpgsql; SELECT add_three_values(1, 2, 4.7); - 可以正常工作,并会自动把整数输入提升为 numeric。如果使用 anyelement,则必须手工把这三个输入转换成同一类型。 + 可以正常工作,并会自动把整数输入提升为 numeric。如果使用 anyelement,则必须手工把这三个输入转换成同一类型。 @@ -516,7 +516,7 @@ user_id users.user_id%TYPE; user_ids users.user_id%TYPE[]; user_ids users.user_id%TYPE ARRAY[4]; -- 等价于上面一行 - 与声明数组表列时一样,写多个方括号还是写具体数组维度都无关紧要:PostgreSQL 会把同一元素类型的所有数组都视为同一种类型,而不考虑维度数。(见 。) + 与声明数组表列时一样,写多对方括号还是写具体数组维度都无关紧要:PostgreSQL 会把同一元素类型的所有数组都视为同一种类型,而不考虑维度数。(见 。) @@ -594,12 +594,12 @@ SELECT merge_fields(t.*) FROM table1 t WHERE ... ; <application>PL/pgSQL</application>变量的排序规则 - collation - in PL/pgSQL + 排序规则 + 在 PL/pgSQL 中 - 当 PL/pgSQL 函数具有一个或多个可排序数据类型参数时,每次函数调用都会根据分配给实际参数的排序规则确定出一个排序规则,如 所述。如果该排序规则能成功确定出来(即参数之间的隐式排序规则没有冲突),那么所有可排序参数都会被视为隐式带有该排序规则。这会影响函数中那些受排序规则影响的操作。例如,考虑 + 当 PL/pgSQL 函数具有一个或多个支持排序规则的数据类型参数时,每次函数调用都会根据分配给实际参数的排序规则确定出一个排序规则,如 所述。如果该排序规则能成功确定出来(即参数之间的隐式排序规则没有冲突),那么所有支持排序规则的参数都会被视为隐式带有该排序规则。这会影响函数中那些受排序规则影响的操作。例如,考虑 CREATE FUNCTION less_than(a text, b text) RETURNS boolean AS $$ @@ -616,7 +616,7 @@ SELECT less_than(text_field_1, text_field_2 COLLATE "C") FROM table1; - 此外,确定出的排序规则也会被视为任何可排序数据类型局部变量的排序规则。因此,即使把这个函数写成下面这样,其行为也不会有任何不同: + 此外,确定出的排序规则也会被视为任何支持排序规则的数据类型局部变量的排序规则。因此,即使把这个函数写成下面这样,其行为也不会有任何不同: CREATE FUNCTION less_than(a text, b text) RETURNS boolean AS $$ @@ -631,11 +631,11 @@ $$ LANGUAGE plpgsql; - 如果函数没有可排序数据类型的参数,或者无法为它们确定共同排序规则,那么参数和局部变量将使用其数据类型的默认排序规则(通常是数据库默认排序规则,但对于域类型变量也可能不同)。 + 如果函数没有支持排序规则的数据类型的参数,或者无法为它们确定共同排序规则,那么参数和局部变量将使用其数据类型的默认排序规则(通常是数据库默认排序规则,但对于域类型变量也可能不同)。 - 通过在可排序数据类型局部变量的声明中加入 COLLATE 选项,可以为其指定不同的排序规则,例如 + 通过在支持排序规则的数据类型局部变量的声明中加入 COLLATE 选项,可以为其指定不同的排序规则,例如 DECLARE @@ -666,7 +666,7 @@ $$ LANGUAGE plpgsql; 表达式 - PL/pgSQL语句中使用的所有表达式都会由服务器的主SQL执行器处理。例如,当你写下这样一条PL/pgSQL语句时: + PL/pgSQL 语句中使用的所有表达式都会由服务器的主 SQL 执行器处理。例如,当写下这样一条 PL/pgSQL 语句时: IF expression THEN ... @@ -674,7 +674,7 @@ IF expression THEN ... SELECT expression - 来计算该表达式。如中详细讨论的那样,在构造该SELECT命令时,PL/pgSQL变量名的每一次出现都会被替换成查询参数。这使得该SELECT的查询计划只需准备一次,然后就能在后续以不同变量值求值时重用。因此,表达式第一次被使用时,实际发生的事情本质上相当于执行了一条PREPARE命令。例如,如果已经声明了两个整数变量xy,并写下 + 来计算该表达式。如 中详细讨论的那样,在构造该 SELECT 命令时,PL/pgSQL 变量名的每一次出现都会被替换成查询参数。这使得该 SELECT 的查询计划只需准备一次,然后就能在后续以不同变量值求值时重用。因此,表达式第一次被使用时,实际发生的事情本质上相当于执行了一条 PREPARE 命令。例如,如果已经声明了两个整数变量 xy,并写下 IF x < y THEN ... @@ -682,7 +682,7 @@ IF x < y THEN ... PREPARE statement_name(integer, integer) AS SELECT $1 < $2; - 然后,在每次执行IF语句时,这条预备语句都会以当前PL/pgSQL变量值作为参数值被EXECUTE。通常这些细节对PL/pgSQL用户并不重要,但在诊断问题时了解它们会很有帮助。更多信息见。 + 然后,在每次执行 IF 语句时,这条预备语句都会以当前 PL/pgSQL 变量值作为参数值由 EXECUTE 执行。通常这些细节对 PL/pgSQL 用户并不重要,但在诊断问题时了解它们会很有帮助。更多信息见 @@ -699,7 +699,7 @@ PREPARE statement_name(integer, integer) AS SELECT $1 基本语句 - 在这一节和接下来的小节中,我们会描述PL/pgSQL能明确理解的所有语句类型。任何不被识别为这些语句类型之一的被假定为是一个 SQL 命令,并且会被发送给主数据库引擎执行,具体如中所述。 + 在这一节和接下来的小节中,我们会描述 PL/pgSQL 能明确理解的所有语句类型。任何不被识别为这些语句类型之一的语句都被视为 SQL 命令,并会被发送给主数据库引擎执行,具体如 中所述。 @@ -715,8 +715,7 @@ PREPARE statement_name(integer, integer) AS SELECT $1 SELECT命令被发送到主数据库引擎的方式计算。 该表达式必须得到一个单一值(如果该变量是一个行或记录变量, 它可能是一个行值)。该目标变量可以是一个简单变量( - 可以选择用一个块名限定)、一个行或记录变量的域或是一个简单 - 变量或域的数组的元素或者数组的切片。 + 可以选择用一个块名限定)、行或记录目标的字段,或者数组目标的元素或切片。 等号(=)可以被用来代替 PL/SQL-兼容的 := @@ -758,7 +757,7 @@ complex_array[n].realpart = 12.3; 如果命令返回行(例如 SELECT,或者带 RETURNINGINSERT/UPDATE/DELETE/MERGE),有两种方式处理。 - 当命令最多返回一行,或者你只关心第一行的输出时,像往常一样编写命令,但要添加一个INTO子句来捕获输出,如中所述。为了处理所有的输出行,把命令写成FOR循环的数据源,如 中所述。 + 当命令最多返回一行,或者只关心第一行的输出时,可照常编写该命令,但要添加一个 INTO 子句来捕获输出,如 中所述。要处理所有输出行,可将该命令写成 FOR 循环的数据源,如 中所述。 @@ -766,29 +765,29 @@ complex_array[n].realpart = 12.3; - PL/pgSQL变量值可以自动插入到可优化的SQL命令中,这些命令包括SELECTINSERTUPDATEDELETEMERGE以及某些包含其中之一的实用程序命令,比如EXPLAINCREATE TABLE ... AS SELECT。在这些命令中,命令文本中出现的任何PL/pgSQL变量名都会被查询参数替换,然后变量的当前值会在运行时作为参数值提供。这与前面描述的表达式处理完全相同;详情请参见。 + PL/pgSQL 变量值可以自动插入可优化的 SQL 命令中,这些命令包括 SELECTINSERTUPDATEDELETEMERGE 以及某些包含其中之一的工具命令,比如 EXPLAINCREATE TABLE ... AS SELECT。在这些命令中,命令文本中出现的任何 PL/pgSQL 变量名都会被查询参数替换,然后变量的当前值会在运行时作为参数值提供。这与前面描述的表达式处理完全相同;详情请参见 - 当以这种方式执行一个可优化的 SQL 命令时,如中讨论的,PL/pgSQL会为该命令缓存并重用执行计划。 + 当以这种方式执行一个可优化的 SQL 命令时,如中讨论的,PL/pgSQL可能会为该命令缓存并重用执行计划。 - 不可优化的SQL命令(也称为实用命令)不能够接受查询参数。 所以自动替换PL/pgSQL的变量在这类命令中不起作用。 要在从PL/pgSQL执行的实用程序命令中包含非常量文本,你必须将实用程序命令构建为一个字符串,然后EXECUTE它,如中所讨论的。 + 不可优化的 SQL 命令(也称为工具命令)不能接受查询参数。因此,自动替换 PL/pgSQL 变量在这类命令中不起作用。要在从 PL/pgSQL 执行的工具命令中包含非常量文本,必须将工具命令构建为一个字符串,然后用 EXECUTE 执行它,如 中所讨论的。 - EXECUTE也必须使用,如果你想以某种其他方式修改命令,而不是提供数据值,例如改变表名。 + 如果想通过其他方式修改命令,而不只是提供数据值,例如改变表名,也必须使用 EXECUTE - 有时候计算一个表达式或SELECT查询但抛弃其结果是有用的,例如调用一个有副作用但是没有有用的结果值的函数。在PL/pgSQL中要这样做,可使用PERFORM语句: + 有时需要计算一个表达式或 SELECT 查询但丢弃其结果,例如调用一个有副作用但没有有用结果值的函数。要在 PL/pgSQL 中这样做,可使用 PERFORM 语句: PERFORM query; - 这会执行query并且丢弃掉结果。以写一个SQL SELECT命令相同的方式写该query,并且将初始的关键词SELECT替换为PERFORM。对于WITH查询,使用PERFORM并且接着把该查询放在圆括号中(在这种情况中,该查询只能返回一行)。PL/pgSQL变量将被替换到该查询中,正如上面描述的查询,并且计划被以相同的方式被缓存。还有,如果该查询产生至少一行,特殊变量FOUND会被设置为真,而如果它不产生行则设置为假(见)。 + 这会执行 query 并丢弃结果。query 的写法与 SQL SELECT 命令相同,只需把开头的关键词 SELECT 替换为 PERFORM。对于 WITH 查询,使用 PERFORM 并将该查询放在圆括号中(在这种情况下,该查询只能返回一行)。PL/pgSQL 变量会像上文所述那样替换到查询中,计划也会以相同方式缓存。此外,如果该查询产生至少一行,特殊变量 FOUND 会被设置为真;如果不产生行,则设置为假(见 )。 @@ -812,12 +811,12 @@ PERFORM create_mv('cs_session_page_requests_mv', my_query); SELECT INTO - in PL/pgSQL + 在 PL/pgSQL 中 RETURNING INTO - in PL/pgSQL + 在 PL/pgSQL 中 @@ -842,7 +841,7 @@ MERGE ... RETURNING expressions INTO STRICT - 如果一个行变量或一个变量列表被用作目标,该命令的结果列必须完全匹配该结果的结构,包括数量和数据类型,否则会发生一个运行时错误。当一个记录变量是目标时,它会自动地把自身配置成命令的结果列组成的行类型。 + 如果一个行变量或一个变量列表被用作目标,该命令的结果列必须完全匹配该目标的结构,包括数量和数据类型,否则会发生一个运行时错误。当一个记录变量是目标时,它会自动地把自身配置成命令的结果列组成的行类型。 @@ -850,7 +849,7 @@ MERGE ... RETURNING expressions INTO STRICT - 如果STRICT没有在INTO子句中被指定,那么target将被设置为该命令返回的第一个行,或者在该命令不返回行时设置为空(注意除非使用了ORDER BY,否则第一行的界定并不清楚)。第一行之后的任何结果行都会被抛弃。你可以检查特殊的FOUND变量(见)来确定是否返回了一行: + 如果STRICT没有在INTO子句中被指定,那么target将被设置为该命令返回的第一个行,或者在该命令不返回行时设置为空值(注意除非使用了ORDER BY,否则第一行的界定并不清楚)。第一行之后的任何结果行都会被抛弃。你可以检查特殊的FOUND变量(见)来确定是否返回了一行: SELECT * INTO myrec FROM emp WHERE empname = myname; @@ -879,7 +878,7 @@ END; - 如果为函数启用了print_strict_params,那么当由于不满足STRICT要求而抛出错误时,错误消息的DETAIL部分将包含传给该命令的参数信息。你可以通过设置plpgsql.print_strict_params来修改所有函数的print_strict_params设置,不过只有此后重新编译的函数才会受影响。也可以通过编译器选项按函数启用它,例如: + 如果为函数启用了print_strict_params,那么当由于不满足STRICT要求而抛出错误时,错误消息的DETAIL部分将包含传给该命令的参数信息。你可以通过设置plpgsql.print_strict_params来修改所有函数的print_strict_params设置,不过该设置只会影响此后编译的函数。也可以通过编译器选项按函数启用它,例如: CREATE FUNCTION get_userid(username text) RETURNS int AS $$ @@ -915,33 +914,31 @@ CONTEXT: PL/pgSQL function get_userid(text) line 6 at SQL statement 执行动态命令 - 很多时候你将想要在PL/pgSQL函数中产生动态命令,也就是每次执行中会涉及到不同表或不同数据类型的命令。PL/pgSQL通常对于命令所做的缓存计划尝试(如中讨论)在这种情境下无法工作。要处理这一类问题,需要提供EXECUTE语句: + 很多时候你将想要在PL/pgSQL函数中产生动态命令,也就是每次执行中会涉及到不同表或不同数据类型的命令。PL/pgSQL通常对于命令所做的缓存计划尝试(如中讨论)在这种情境下无法工作。要处理这一类问题,提供了EXECUTE语句: EXECUTE command-string INTO STRICT target USING expression , ... ; - 其中command-string是一个能得到一个包含要被执行命令字符串(类型text)的表达式。可选的target是一个记录变量、一个行变量或者一个逗号分隔的简单变量以及记录/行域的列表,该命令的结果将存储在其中。可选的USING表达式提供要被插入到该命令中的值。 + 其中command-string是一个能得到一个包含要被执行命令字符串(类型text)的表达式。可选的target是一个记录变量、一个行变量或者一个逗号分隔的简单变量以及记录/行字段的列表,该命令的结果将存储在其中。可选的USING表达式提供要被插入到该命令中的值。 在计算得到的命令字符串中,不会做PL/pgSQL变量的替换。任何所需的变量值必须在命令字符串被构造时被插入其中,或者你可以使用下面描述的参数。 - - 还有,对于通过EXECUTE执行的命令不会有计划被缓存。该命令反而在每次运行时都会被做计划。因此,该命令字符串可以在执行不同表和列上动作的函数中被动态创建。 - + 此外,通过 EXECUTE 执行的命令不会缓存计划,而是在每次运行该语句时重新规划。因此,可以在函数中动态构造命令字符串,对不同的表和列执行操作。 - INTO子句指定一个返回行的 SQL 命令的结果应该被赋值到哪里。如果提供了一个行或变量列表,它必须完全匹配查询命令结果的结构(当一个记录变量被提供时,它会自动把它自己配置为匹配结果结构)。如果返回多个行,只有第一个行会被赋值给INTO变量。如果没有返回行,NULL 会被赋值给INTO变量。如果没有指定INTO变量,该查询结果会被抛弃。 + INTO子句指定一个返回行的 SQL 命令的结果应该被赋值到哪里。如果提供了一个行变量或变量列表,它必须完全匹配查询命令结果的结构(当一个记录变量被提供时,它会自动把它自己配置为匹配结果结构)。如果返回多个行,只有第一个行会被赋值给INTO变量。如果没有返回行,NULL 会被赋值给INTO变量。如果没有指定INTO子句,该查询结果会被抛弃。 - 如果给出了STRICT选项,除非该查询刚好产生一行,否则将会报告一个错误。 + 如果给出了STRICT选项,除非该命令刚好产生一行,否则将会报告一个错误。 - 命令字符串可以使用参数值,它们在命令中用$1$2等引用。这些符号引用在USING子句中提供的值。这种方法常常更适合于把数据值作为文本插入到命令字符串中:它避免了将该值转换为文本以及转换回来的运行时负荷,并且它更不容易被 SQL 注入攻击,因为不需要引用或转义。一个示例是: + 命令字符串可以使用参数值,它们在命令中用$1$2等引用。这些符号引用在USING子句中提供的值。这种方法通常比把数据值作为文本插入命令字符串更可取:它避免了将该值转换为文本以及转换回来的运行时负荷,并且它更不容易被 SQL 注入攻击,因为不需要引用或转义。一个示例是: EXECUTE 'SELECT count(*) FROM mytable WHERE inserted_by = $1 AND inserted <= $2' INTO c @@ -959,25 +956,25 @@ EXECUTE 'SELECT count(*) FROM ' USING checked_user, checked_date; 一种更干净的方法是使用format()的 - %I规范,插入自带引号的表名或者列名: + %I 格式说明符,插入表名或列名并自动为其加上引号: EXECUTE format('SELECT count(*) FROM %I ' 'WHERE inserted_by = $1 AND inserted <= $2', tabname) INTO c USING checked_user, checked_date; - (此示例依赖于隐式连接由换行符分隔的字符串文字的 SQL 规则) + (此示例依赖于隐式连接由换行符分隔的字符串字面量的 SQL 规则) 参数符号的另一个限制是它们仅适用于可优化的SQL命令 (SELECT, INSERT, UPDATE, DELETE, MERGE以及包含其中一个的某些命令)。 - 在其他语句类型(通称为实用程序语句)中,即使它们只是数据值,您也必须以文本方式插入值。 + 在其他语句类型(通称为工具语句)中,即使它们只是数据值,你也必须以文本方式插入值。 - 在上面第一个示例中,带有一个简单的常量命令字符串和一些USING参数的EXECUTE命令在功能上等效于直接用PL/pgSQL写的命令,并且允许自动发生PL/pgSQL变量替换。重要的不同之处在于,EXECUTE会在每一次执行时根据当前的参数值重新计划该命令,而PL/pgSQL则是创建一个通用计划并且将其缓存以便重用。在最佳计划强依赖于参数值的情况中,使用EXECUTE来明确地保证不会选择一个通用计划是很有帮助的。 + 在上面第一个示例中,带有一个简单的常量命令字符串和一些USING参数的EXECUTE命令在功能上等效于直接用PL/pgSQL写的命令,并且允许自动发生PL/pgSQL变量替换。重要的不同之处在于,EXECUTE会在每一次执行时根据当前的参数值重新计划该命令,而PL/pgSQL则可能创建一个通用计划并且将其缓存以便重用。在最佳计划强依赖于参数值的情况中,使用EXECUTE来明确地保证不会选择一个通用计划是很有帮助的。 @@ -985,10 +982,7 @@ EXECUTE format('SELECT count(*) FROM %I ' - - - PL/pgSQL中的EXECUTE语句与EXECUTE PostgreSQL服务器支持的 SQL 语句无关。服务器的EXECUTE语句不能直接在PL/pgSQL函数中使用(并且也没有必要)。 - + PL/pgSQLEXECUTE 语句与 PostgreSQL 服务器支持的 SQL EXECUTE 语句无关。服务器的 EXECUTE 语句不能直接用于 PL/pgSQL 函数中(也没有这个必要)。 @@ -1052,19 +1046,19 @@ EXECUTE 'UPDATE tbl SET ' || ' WHERE key = ' || quote_nullable(keyvalue); - 如果正在处理的参数值可能为空,那么通常应该用quote_nullable来代替quote_literal。 + 如果正在处理的参数值可能为空值,那么通常应该用quote_nullable来代替quote_literal - 通常,必须小心地确保查询中的空值不会递送意料之外的结果。例如如果keyvalue为空,下面的WHERE子句 + 通常,必须小心地确保查询中的空值不会产生意料之外的结果。例如如果keyvalue为空值,下面的WHERE子句 'WHERE key = ' || quote_nullable(keyvalue) - 永远不会成功,因为在=操作符中使用空操作数得到的结果总是为空。如果想让空和一个普通键值一样工作,你应该将上面的命令重写成 + 永远不会成功,因为在=操作符中使用空值操作数得到的结果总是空值。如果想让空值像普通键值一样工作,你应该将上面的命令重写成 'WHERE key IS NOT DISTINCT FROM ' || quote_nullable(keyvalue) - (目前,IS NOT DISTINCT FROM的处理效率不如=,因此只有在非常必要时才这样做。关于空和IS DISTINCT的详细信息请见)。 + (目前,IS NOT DISTINCT FROM的处理效率不如=,因此只有在非常必要时才这样做。关于空值和IS DISTINCT的详细信息请见)。 @@ -1077,7 +1071,7 @@ EXECUTE 'UPDATE tbl SET ' || '$$ WHERE key = ' || quote_literal(keyvalue); - 因为如果newvalue的内容碰巧含有$$,那么这段代码就会出问题。同样的缺点可能适用于你选择的任何其他美元符号引用定界符。因此,要想安全地引用事先不知道的文本,必须恰当地使用quote_literalquote_nullablequote_ident。 + 因为如果newvalue的内容碰巧含有$$,那么这段代码就会出问题。同样的问题也适用于你选择的任何其他美元符号引用定界符。因此,要想安全地引用事先不知道的文本,必须恰当地使用quote_literalquote_nullablequote_ident @@ -1116,7 +1110,7 @@ EXECUTE format('UPDATE tbl SET %I = $1 WHERE key = $2', colname) GET CURRENT DIAGNOSTICS variable { = | := } item , ... ; - 这条命令允许检索系统状态指示符。CURRENT是一个噪声词(另见中的GET STACKED DIAGNOSTICS)。每个item是一个关键字, 它标识一个要被赋予给指定变量的状态值(变量应具有正确的数据类型来接收状态值)。中展示了当前可用的状态项。冒号等号(:=)可以被用来取代 SQL 标准的=符号。例如: + 这条命令允许检索系统状态指示符。CURRENT是一个噪声词(另见中的GET STACKED DIAGNOSTICS)。每个item是一个关键字, 它标识一个要被赋予给指定variable的状态值(变量应具有正确的数据类型来接收状态值)。中展示了当前可用的状态项。冒号等号(:=)可以被用来取代 SQL 标准的=符号。例如: GET DIAGNOSTICS integer_var = ROW_COUNT; @@ -1161,13 +1155,13 @@ GET DIAGNOSTICS integer_var = ROW_COUNT; 第二种确定命令效果的方法是检查名为FOUND的特殊变量,类型为boolean。 - 在每次PL/pgSQL函数调用中,FOUND都是以 false 开头。 + 在每次PL/pgSQL函数调用中,FOUND的初始值都是 false。 它由以下类型的语句设置: - SELECT INTO语句在分配行时将FOUND设置为true, + SELECT INTO语句在为目标赋上一行值时将FOUND设置为true, 如果没有返回行则设置为false。 @@ -1199,7 +1193,7 @@ GET DIAGNOSTICS integer_var = ROW_COUNT; FORFOREACH语句在迭代一次或多次时将 FOUND设置为true,否则设置为false。 - 当循环退出时,FOUND被设置为这种方式; + 当循环退出时,FOUND会按上述方式设置; 在循环执行过程中,FOUND不会被循环语句修改, 尽管它可能会被循环体内的其他语句执行修改。 @@ -1295,7 +1289,7 @@ RETURN expression; - 如果函数返回的是标量类型,表达式结果会自动转换为函数的返回类型。但如果要返回一个组合(行)值,你必须写出一个恰好生成所需列集合的表达式。这可能需要显式类型转换。 + 如果函数返回的是标量类型,表达式结果会按照赋值部分的说明自动转换为函数的返回类型。但如果要返回一个复合(行)值,你必须写出一个恰好生成所需列集合的表达式。这可能需要显式类型转换。 @@ -1307,7 +1301,7 @@ RETURN expression; - 一个函数的返回值不能是未定义。如果控制到达了函数最顶层的块而没有碰到一个RETURN语句,那么会发生一个运行时错误。不过,这个限制不适用于带输出参数的函数以及返回void的函数。在这些情况中,如果顶层的块结束,将自动执行一个RETURN语句。 + 一个函数的返回值不能是未定义。如果控制到达了函数最顶层块的末尾而没有碰到一个RETURN语句,那么会发生一个运行时错误。不过,这个限制不适用于带输出参数的函数以及返回void的函数。在这些情况中,如果顶层的块结束,将自动执行一个RETURN语句。 @@ -1331,12 +1325,12 @@ RETURN (1, 2, 'three'::text); -- 必须把列类型转换成正确的类型 RETURN NEXT - in PL/pgSQL + 在 PL/pgSQL 中 RETURN QUERY - in PL/pgSQL + 在 PL/pgSQL 中 @@ -1346,7 +1340,7 @@ RETURN QUERY EXECUTE command-string < - 当 PL/pgSQL 函数被声明为返回 SETOF sometype 时,返回过程会略有不同。在这种情况下,要返回的各个项通过一系列 RETURN NEXTRETURN QUERY 命令指定,最后再用一个不带参数的 RETURN 命令表明函数已经执行完毕。RETURN NEXT 可用于标量和组合数据类型;对于组合结果类型,会返回完整的结果RETURN QUERY 会把查询执行结果追加到函数的结果集中。在同一个集合返回函数中,RETURN NEXTRETURN QUERY 可以自由混用,此时它们的结果会被串接起来。 + 当 PL/pgSQL 函数被声明为返回 SETOF sometype 时,返回过程会略有不同。在这种情况下,要返回的各个项通过一系列 RETURN NEXTRETURN QUERY 命令指定,最后再用一个不带参数的 RETURN 命令表明函数已经执行完毕。RETURN NEXT 可用于标量和复合数据类型;对于复合结果类型,会返回完整的结果RETURN QUERY 会把查询执行结果追加到函数的结果集中。在同一个集合返回函数中,RETURN NEXTRETURN QUERY 可以自由混用,此时它们的结果会被串接起来。 @@ -1511,7 +1505,7 @@ END IF; - IF-THEN语句是IF的最简单形式。 如果条件为真,在THENEND IF之间的语句将被执行。否则,将忽略它们。 + IF-THEN语句是IF的最简单形式。 如果条件为真,在THENEND IF之间的语句将被执行。否则,将忽略它们。 @@ -1594,7 +1588,7 @@ ELSIF number > 0 THEN ELSIF number < 0 THEN result := 'negative'; ELSE - -- 嗯,唯一的其他可能性是数字为空 + -- 嗯,唯一的其他可能性是 number 为 null result := 'NULL'; END IF; @@ -1690,9 +1684,7 @@ END CASE; - - 这种形式的CASEIF-THEN-ELSIF完全等价,唯一的区别是:如果省略了ELSE子句,CASE会报错,而不是简单地什么也不做。 - + 这种形式的CASEIF-THEN-ELSIF完全等价,唯一的区别是:如果执行到被省略的ELSE子句,就会报错,而不是简单地什么也不做。 @@ -1702,12 +1694,12 @@ END CASE; 简单循环 - loop + 循环 在 PL/pgSQL 中 - 使用LOOPEXITCONTINUEWHILEFORFOREACH语句,你可以安排PL/pgSQL重复一系列命令。 + 使用LOOPEXITCONTINUEWHILEFORFOREACH语句,你可以安排PL/pgSQL函数重复一系列命令。 @@ -1862,22 +1854,22 @@ END LOOP label ; - 这种形式的FOR会创建一个在一个整数范围上迭代的循环。变量name会自动定义为类型integer并且只在循环内存在(任何该变量名的现有定义在此循环内都将被忽略)。给出范围上下界的两个表达式在进入循环的时候计算一次。如果没有指定BY子句,迭代步长为 1,否则步长是BY中指定的值,该值也只在循环进入时计算一次。如果指定了REVERSE,那么在每次迭代后步长值会被减除而不是增加。 + 这种形式的FOR会创建一个在一个整数范围上迭代的循环。变量name会自动定义为类型integer并且只在循环内存在(任何该变量名的现有定义在此循环内都将被忽略)。给出范围上下界的两个表达式在进入循环的时候计算一次。如果没有指定BY子句,迭代步长为 1,否则步长是BY中指定的值,该值也只在循环进入时计算一次。如果指定了REVERSE,那么在每次迭代后会减去步长,而不是加上步长。 整数FOR循环的一些示例: FOR i IN 1..10 LOOP - -- 我在循环中将取值 1,2,3,4,5,6,7,8,9,10 + -- i 在循环中将取值 1,2,3,4,5,6,7,8,9,10 END LOOP; FOR i IN REVERSE 10..1 LOOP - -- 我在循环中将取值 10,9,8,7,6,5,4,3,2,1 + -- i 在循环中将取值 10,9,8,7,6,5,4,3,2,1 END LOOP; FOR i IN REVERSE 10..1 BY 2 LOOP - -- 我在循环中将取值 10,8,6,4,2 + -- i 在循环中将取值 10,8,6,4,2 END LOOP; @@ -1941,7 +1933,7 @@ $$ LANGUAGE plpgsql; - 在这类 FOR 语句中使用的 query,可以是任何向调用者返回行的 SQL 命令:最常见的是 SELECT,但也可以是带 RETURNING 子句的 INSERTUPDATEDELETEMERGE。某些实用程序命令,如 EXPLAIN,也可以用于此处。 + 在这类 FOR 语句中使用的 query,可以是任何向调用者返回行的 SQL 命令:最常见的是 SELECT,但也可以是带 RETURNING 子句的 INSERTUPDATEDELETEMERGE。某些工具命令,如 EXPLAIN,也可以用于此处。 @@ -1956,7 +1948,7 @@ FOR target IN EXECUTE text_expressionstatements END LOOP label ; - 这个示例类似前面的形式,只不过源查询被指定为一个字符串表达式,在每次进入FOR循环时都会计算它并且重新计划。这允许程序员在一个预先计划好了的命令的速度和一个动态命令的灵活性之间进行选择,就像一个纯EXECUTE语句那样。在使用EXECUTE时,可以通过USING将参数值插入到动态命令中。 + 这个示例类似前面的形式,只不过源查询被指定为一个字符串表达式,在每次进入FOR循环时都会计算它并且重新计划。这允许程序员在一个预先计划好了的命令的速度和一个动态命令的灵活性之间进行选择,就像一个纯EXECUTE语句那样。与EXECUTE一样,可以通过USING将参数值插入到动态命令中。 @@ -1969,7 +1961,7 @@ END LOOP label ; 遍历数组 - FOREACH循环很像FOR循环,但它不是遍历 SQL 查询返回的行,而是遍历数组值的元素。(一般来说,FOREACH用于遍历组合值表达式的组成部分;未来还可能加入遍历数组以外其他组合值的变体。)用于遍历数组的FOREACH语句如下: + FOREACH循环很像FOR循环,但它不是遍历 SQL 查询返回的行,而是遍历数组值的元素。(一般来说,FOREACH用于遍历复合值表达式的组成部分;未来还可能加入遍历数组以外其他复合值的变体。)用于遍历数组的FOREACH语句如下: <<label>> @@ -1997,7 +1989,7 @@ END; $$ LANGUAGE plpgsql; - 元素会按存储顺序访问,而不管数组有多少维。尽管target通常只是单个变量,但在遍历组合值(记录)数组时,它也可以是一个变量列表。在这种情况下,每个数组元素都会按组合值的连续列给这些变量赋值。 + 元素会按存储顺序访问,而不管数组有多少维。尽管target通常只是单个变量,但在遍历复合值(记录)数组时,它也可以是一个变量列表。在这种情况下,每个数组元素都会按复合值的连续列给这些变量赋值。 @@ -2030,8 +2022,8 @@ NOTICE: row = {10,11,12} 捕获错误 - exceptions - in PL/pgSQL + 异常 + 在 PL/pgSQL 中 @@ -2054,7 +2046,7 @@ END; - 如果没有发生错误,这种形式的块只是简单地执行所有statements, 并且接着控制转到END之后的下一个语句。但是如果在statements内发生了一个错误,则会放弃对statements的进一步处理,然后控制会转到EXCEPTION列表。系统会在列表中寻找匹配所发生错误的第一个condition。如果找到一个匹配,则执行对应的handler_statements,并且接着把控制转到END之后的下一个语句。如果没有找到匹配,该错误就会传播出去,就好像根本没有EXCEPTION一样:错误可以被一个带有EXCEPTION的闭合块捕捉,如果没有EXCEPTION则中止该函数的处理。 + 如果没有发生错误,这种形式的块只是简单地执行所有statements, 并且接着控制转到END之后的下一个语句。但是如果在statements内发生了一个错误,则会放弃对statements的进一步处理,然后控制会转到EXCEPTION列表。系统会在列表中寻找匹配所发生错误的第一个condition。如果找到一个匹配,则执行对应的handler_statements,并且接着把控制转到END之后的下一个语句。如果没有找到匹配,该错误就会传播出去,就好像根本没有EXCEPTION一样:错误可以被一个带有EXCEPTION的外围块捕捉,如果没有这样的块则中止该函数的处理。 @@ -2091,7 +2083,7 @@ END; - 进入和退出一个包含EXCEPTION子句的块要比不包含EXCEPTION的块开销大的多。因此,只在必要的时候使用EXCEPTION。 + 进入和退出一个包含EXCEPTION子句的块要比不包含该子句的块开销大得多。因此,只在必要的时候使用EXCEPTION @@ -2118,9 +2110,9 @@ BEGIN IF found THEN RETURN; END IF; - -- 不在这里,那么尝试插入该键 + -- 该键不存在,因此尝试插入 -- 如果其他某人并发地插入同一个键, - -- 我们可能得到一个唯一键失败 + -- 就可能发生违反唯一约束的错误 BEGIN INSERT INTO db(a,b) VALUES (key, data); RETURN; @@ -2159,7 +2151,7 @@ SELECT merge_db(1, 'dennis'); GET STACKED DIAGNOSTICS variable { = | := } item , ... ; - 每个item是一个关键词,它标识一个被赋予给指定变量(应该具有接收该值的正确数据类型)的状态值。中显示了当前可用的状态项。 + 每个item是一个关键词,它标识一个被赋予给指定variable(应该具有接收该值的正确数据类型)的状态值。中显示了当前可用的状态项。
@@ -2271,7 +2263,7 @@ END; 获得执行位置信息 - GET DIAGNOSTICS(之前在中描述)命令检索有关当前执行状态的信息(反之上文讨论的GET STACKED DIAGNOSTICS命令会把有关执行状态的信息报告成一个以前的错误)。它的PG_CONTEXT状态项可用于标识当前执行位置。状态项PG_CONTEXT将返回一个文本字符串,其中有描述该调用栈的多行文本。第一行会指向当前函数以及当前正在执行GET DIAGNOSTICS的命令。第二行及其后的行表示调用栈中更上层的调用函数。例如: + GET DIAGNOSTICS(之前在中描述)命令检索有关当前执行状态的信息(反之上文讨论的GET STACKED DIAGNOSTICS命令报告先前发生错误时的执行状态信息)。它的PG_CONTEXT状态项可用于标识当前执行位置。状态项PG_CONTEXT将返回一个文本字符串,其中包含一行或多行描述该调用栈的文本。第一行会指向当前函数以及当前正在执行的GET DIAGNOSTICS命令。第二行及其后的行表示调用栈中更上层的调用函数。例如: CREATE OR REPLACE FUNCTION outer_func() RETURNS integer AS $$ @@ -2315,7 +2307,7 @@ CONTEXT: PL/pgSQL function outer_func() line 3 at RETURN 游标 - cursor + 游标 在 PL/pgSQL 中 @@ -2347,7 +2339,7 @@ DECLARE - 当游标查询使用 FOR UPDATE/SHARE 时,不能使用 SCROLL 选项。此外,对于涉及易失函数的查询,最好使用 NO SCROLLSCROLL 的实现假定重新读取查询输出会得到一致的结果,而易失函数并不满足这一假设。 + 当游标查询使用 FOR UPDATE/SHARE 时,不能使用 SCROLL 选项。此外,对于涉及易失函数的查询,最好使用 NO SCROLLSCROLL 的实现假定重新读取查询输出会得到一致的结果,而易失函数可能无法满足这一假设。 @@ -2372,7 +2364,7 @@ DECLARE - 打开游标会创建一个称为 portal 的服务器内部数据结构,它保存游标查询的执行状态。portal 具有一个名称,在其存在期间该名称在会话内必须唯一。默认情况下,PL/pgSQL 会为其创建的每个 portal 分配唯一名称。不过,如果你给游标变量赋一个非空字符串值,该字符串会被用作 portal 名称。这个特性可用于中描述的用法。 + 打开游标会创建一个称为 portal 的服务器内部数据结构,它保存游标查询的执行状态。portal 具有一个名称,在其存在期间该名称在会话内必须唯一。默认情况下,PL/pgSQL 会为其创建的每个 portal 分配唯一名称。不过,如果你给游标变量赋一个非 NULL 的字符串值,该字符串会被用作 portal 名称。这个特性可用于中描述的用法。 @@ -2498,7 +2490,7 @@ FETCH direction { FROM | IN } RELATIVE countFORWARD或者 BACKWARD。 - 省略direction和指定NEXT是一样的。在使用count的形式中,count可以是任意的整数值表达式(与SQL命令FETCH不一样,FETCH仅允许整数常量)。除非游标被使用SCROLL选项声明或打开,否则要求反向移动的direction值很可能会失败。 + 省略direction和指定NEXT是一样的。在使用count的形式中,count可以是任意的整数值表达式(与SQL命令FETCH不一样,后者仅允许整数常量)。除非游标被使用SCROLL选项声明或打开,否则要求反向移动的direction值很可能会失败。 @@ -2586,13 +2578,13 @@ CLOSE curs1; - 游标使用的 portal 名称既可以由程序员指定,也可以自动生成。要指定 portal 名称,只需在打开refcursor变量之前给它赋一个字符串值。OPEN会把该refcursor变量的字符串值用作底层 portal 的名称。不过,如果refcursor变量为 null,OPEN就会自动生成一个与任何现有 portal 都不冲突的名称,并把它赋回给refcursor变量。 + 游标使用的 portal 名称既可以由程序员指定,也可以自动生成。要指定 portal 名称,只需在打开refcursor变量之前给它赋一个字符串值。OPEN会把该refcursor变量的字符串值用作底层 portal 的名称。不过,如果refcursor变量为 null(这是默认值),OPEN就会自动生成一个与任何现有 portal 都不冲突的名称,并把它赋回给refcursor变量。 - 在 PostgreSQL 16 之前,已绑定游标变量会被初始化为其自身名称,而不是保持为空,因此默认情况下底层 portal 名称与游标变量名相同。之所以改动,是因为该行为在不同函数里同名游标之间带来了过高的名称冲突风险。 + 在 PostgreSQL 16 之前,已绑定游标变量会被初始化为其自身名称,而不是保持为 NULL,因此默认情况下底层 portal 名称与游标变量名相同。之所以改动,是因为该行为在不同函数里同名游标之间带来了过高的名称冲突风险。 @@ -2726,7 +2718,7 @@ CALL transaction_test1(); 连锁的事务 - 在 PL/pgSQL + 在 PL/pgSQL 中 @@ -2739,7 +2731,7 @@ CALL transaction_test1(); - PL/pgSQL 不支持保存点(SAVEPOINT/ROLLBACK TO SAVEPOINT/RELEASE SAVEPOINT)。保存点的典型用法可以用带异常处理器的代码块替代(见)。在内部,实现为带异常处理器的代码块会形成一个子事务,这意味着在这类代码块内部不能结束事务。 + PL/pgSQL 不支持保存点(SAVEPOINT/ROLLBACK TO SAVEPOINT/RELEASE SAVEPOINT)。保存点的典型用法可以用带异常处理器的代码块替代(见)。带异常处理器的代码块在内部会形成一个子事务,这意味着在这类代码块内部不能结束事务。 @@ -2786,23 +2778,19 @@ CALL transaction_test2(); 在 PL/pgSQL 中 - - 使用RAISE语句报告消息以及抛出错误。 - - + 使用RAISE语句报告消息和抛出错误。 RAISE level 'format' , expression , ... USING option { = | := } expression , ... ; RAISE level condition_name USING option { = | := } expression , ... ; RAISE level SQLSTATE 'sqlstate' USING option { = | := } expression , ... ; RAISE level USING option { = | := } expression , ... ; RAISE ; - - - level选项指定了错误的严重性。允许的级别有DEBUGLOGINFONOTICE, WARNING以及EXCEPTION,默认级别是EXCEPTIONEXCEPTION会抛出一个错误(通常会中止当前事务)。其他级别仅仅是产生不同优先级的消息。不管一个特定优先级的消息是被报告给客户端、还是写到服务器日志、亦或是二者同时都做,这都由配置变量控制。详见。 - +其中,level选项指定错误的严重程度。允许的级别为DEBUG, + LOGINFO, + NOTICEWARNING以及EXCEPTION,其中EXCEPTION是默认值。EXCEPTION会抛出错误(通常会中止当前事务);其他级别只会生成不同优先级的消息。特定优先级的消息是报告给客户端、写入服务器日志,还是两者都做,由配置变量控制。更多信息见中的说明。 在第一种语法变体中,在level之后(如果有),写一个format字符串 - (必须是一个简单的字符串文字,而不是一个表达式)。格式字符串指定要报告的错误消息文本。 + (必须是一个简单的字符串字面量,而不是一个表达式)。格式字符串指定要报告的错误消息文本。 格式字符串后跟要插入到消息中的可选参数表达式。 在格式字符串中,%将被下一个可选参数的值的字符串表示替换。写 %%以发出一个字面上的%。 @@ -2845,7 +2833,7 @@ RAISE WARNING SQLSTATE '22012'; DETAIL - 提供一个错误的细节消息。 + 提供错误的详细信息。 @@ -2876,9 +2864,7 @@ RAISE WARNING SQLSTATE '22012'; - - 这个示例将用给定的错误消息和提示中止事务: - + 这个例子会中止事务,并给出指定的错误消息和提示: RAISE EXCEPTION 'Nonexistent ID --> %', user_id USING HINT = 'Please check your user ID'; @@ -2890,9 +2876,8 @@ RAISE EXCEPTION 'Nonexistent ID --> %', user_id RAISE 'Duplicate user ID: %', user_id USING ERRCODE = 'unique_violation'; RAISE 'Duplicate user ID: %', user_id USING ERRCODE = '23505'; - - + 另一种得到前面示例相同结果的方式是: RAISE unique_violation USING MESSAGE = 'Duplicate user ID: ' || user_id; @@ -2923,7 +2908,7 @@ RAISE unique_violation USING MESSAGE = 'Duplicate user ID: ' || user_id; - 当用 SQLSTATE 代码指定错误代码时,你并不受限于预定义错误代码,而是可以选择任何由五位数字和/或大写 ASCII 字母构成的错误代码,唯一不能使用的是 00000。我们建议尽量避免抛出以三个零结尾的错误代码,因为这些是类别代码,只能用于捕获整个类别。 + 当用 SQLSTATE 代码指定错误代码时,你并不受限于预定义错误代码,而是可以选择任何由五位数字和/或大写 ASCII 字母构成的错误代码,唯一不能使用的是 00000。我们建议尽量避免抛出以三个零结尾的错误代码,因为这些是类别代码,只能通过捕获整个类别来捕获这类错误。 @@ -2935,12 +2920,12 @@ RAISE unique_violation USING MESSAGE = 'Duplicate user ID: ' || user_id; ASSERT - in PL/pgSQL + 在 PL/pgSQL 中 - assertions - in PL/pgSQL + 断言 + 在 PL/pgSQL 中 @@ -2957,15 +2942,14 @@ ASSERT condition , condition是一个布尔 表达式,它被期望总是计算为真。如果确实如此, - ASSERT语句不会再做什么。但如果结果是假 - 或者空,那么将发生一个ASSERT_FAILURE异常(如果在计算 + ASSERT语句不会再做什么。但如果结果是假或者空值,那么将发生一个ASSERT_FAILURE异常(如果在计算 condition时发生错误, 它会被报告为一个普通错误)。 如果提供了可选的message, - 它是一个结果(如果非空)被用来替换默认错误消息文本 + 它是一个结果(如果不为 NULL)被用来替换默认错误消息文本 assertion failed的表达式(如果 condition失败)。 message表达式在 @@ -2998,7 +2982,7 @@ ASSERT condition , - PL/pgSQL可以被用来在数据更改或者数据库事件上定义触发器函数。触发器函数用CREATE FUNCTION命令创建,它被声明为一个没有参数并且返回类型为trigger(对于数据更改触发器)或者event_trigger(对于数据库事件触发器)的函数。名为PG_something的特殊局部变量将被自动创建用以描述触发该调用的条件。 + PL/pgSQL可以被用来在数据更改或者数据库事件上定义触发器函数。触发器函数用CREATE FUNCTION命令创建,它被声明为一个没有参数并且返回类型为trigger(对于数据更改触发器)或者event_trigger(对于数据库事件触发器)的函数。名为TG_something的特殊局部变量将被自动创建用以描述触发该调用的条件。 @@ -3009,10 +2993,7 @@ ASSERT condition , 数据更改触发器被声明为一个没有参数并且返回类型为trigger的函数。注意,如下所述,即便该函数准备接收一些在CREATE TRIGGER中指定的参数 — 这类参数通过TG_ARGV传递,也必须把它声明为没有参数。 - - 当一个PL/pgSQL函数当做触发器调用时,在顶层块会自动创建一些特殊变量。它们是: - - + 当一个PL/pgSQL函数作为触发器被调用时,会在顶层块中自动创建一些特殊变量。它们是: NEW record @@ -3132,11 +3113,11 @@ ASSERT condition , - INSTEAD OF触发器(总是行级触发器,并且可能只被用于视图)能够返回空来表示它们没有执行任何更新,并且对该行剩余的操作可以被跳过(即后续的触发器不会被引发,并且该行不会被计入外围INSERT/UPDATE/DELETE的行影响状态中)。否则一个非空值应该被返回用以表示该触发器执行了所请求的操作。对于INSERTUPDATE操作,返回值应该是NEW,触发器函数可能对它进行了修改来支持INSERT RETURNINGUPDATE RETURNING(这也将影响被传递给任何后续触发器的行值,或者被传递给带有ON CONFLICT DO UPDATEINSERT语句中一个特殊的EXCLUDED别名引用)。对于DELETE操作,返回值应该是OLD。 + INSTEAD OF触发器(总是行级触发器,并且只能用于视图)能够返回 null 来表示它们没有执行任何更新,并且对该行剩余的操作应被跳过(即后续的触发器不会被引发,并且该行不会被计入外围INSERT/UPDATE/DELETE的行影响状态中)。否则应该返回一个非 null 值用以表示该触发器执行了所请求的操作。对于INSERTUPDATE操作,返回值应该是NEW,触发器函数可能对它进行了修改来支持INSERT RETURNINGUPDATE RETURNING(这也将影响被传递给任何后续触发器的行值,或者被传递给带有ON CONFLICT DO UPDATEINSERT语句中一个特殊的EXCLUDED别名引用)。对于DELETE操作,返回值应该是OLD - 一个AFTER行级触发器或一个BEFOREAFTER语句级触发器的返回值总是会被忽略,它可能也是空。不过,任何这些类型的触发器可能仍会通过抛出一个错误来中止整个操作。 + 一个AFTER行级触发器或一个BEFOREAFTER语句级触发器的返回值总是会被忽略,因此也可以返回 null。不过,任何这些类型的触发器可能仍会通过抛出一个错误来中止整个操作。 @@ -3310,11 +3291,10 @@ INSTEAD OF INSERT OR UPDATE OR DELETE ON emp_view - - 一个 <application>PL/pgSQL</application> 用于维护汇总表的触发器函数 + 一个用于维护汇总表的 <application>PL/pgSQL</application> 触发器函数 - 这里详述的模式有一部分是基于 Ralph Kimball 所作的数据仓工具包中的Grocery Store示例。 + 这里详述的模式有一部分是基于 Ralph Kimball 所作的数据仓库工具包中的Grocery Store示例。 @@ -3457,7 +3437,7 @@ SELECT * FROM sales_summary_bytime; 使用过渡表审计 - 这个示例产生和相同的结果,但并未使用一个为每一行都触发的触发器,而是在把相关信息收集到一个过渡表中之后用了一个只为每个语句引发一次的触发器。当调用语句修改了很多行时,这种方法明显比行触发器方法快。注意我们必须为每一种事件建立一个单独的触发器声明,因为每种情况的REFERENCING子句必须不同。但是这并不能阻止我们使用单一的触发器函数(实际上,使用三个单独的函数会更好,因为可以避免在TG_OP上的运行时测试)。 + 这个示例产生和相同的结果,但并未使用一个为每一行都触发的触发器,而是在把相关信息收集到一个过渡表中之后用了一个只为每个语句引发一次的触发器。当调用语句修改了很多行时,这种方法可能显著快于行触发器方法。注意我们必须为每一种事件建立一个单独的触发器声明,因为每种情况的REFERENCING子句必须不同。但是这并不能阻止我们使用单一的触发器函数(实际上,使用三个单独的函数可能会更好,因为可以避免在TG_OP上的运行时测试)。 @@ -3519,10 +3499,7 @@ CREATE TRIGGER emp_audit_del PL/pgSQL可以被用来定义事件触发器。PostgreSQL要求一个可以作为事件触发器调用的函数必须被声明为没有参数并且返回类型为event_trigger - - 当一个PL/pgSQL函数被作为一个事件触发器调用,在顶层块中会自动创建一些特殊变量。它们是: - - + 当一个PL/pgSQL函数作为事件触发器被调用时,会在顶层块中自动创建一些特殊变量。它们是: TG_EVENT text @@ -3573,9 +3550,7 @@ CREATE EVENT TRIGGER snitch ON ddl_command_start EXECUTE FUNCTION snitch(); <application>PL/pgSQL</application> 内部机制 - - 这一节讨论了一些PL/pgSQL用户应该知道的一些重要的实现细节。 - + 本节讨论一些实现细节,了解这些细节对 PL/pgSQL 用户通常很重要。 @@ -3653,7 +3628,7 @@ CREATE FUNCTION stamp_user(id int, comment text) RETURNS void AS $$ END; $$ LANGUAGE plpgsql; - 在UPDATE命令中,curtimecomment以及id将引用该函数的变量和参数,不管users有没有这些名称的列。注意,我们不得不在WHERE子句中对users.id的引用加以限定,以便让它引用表列。但是我们不需要在UPDATE列表中把对comment的引用限定为一个目标,因为语法上那必须是users的一列。我们可以用下面的方式写一个相同的不依赖于variable_conflict设置的函数: + 在UPDATE命令中,curtimecomment以及id将引用该函数的变量和参数,不管users有没有这些名称的列。注意,我们不得不在WHERE子句中对users.id的引用加以限定,以便让它引用表列。但是我们不需要对UPDATE列表中作为目标的comment引用加以限定,因为语法上那必须是users的一列。我们可以用下面的方式写一个相同的不依赖于variable_conflict设置的函数: CREATE FUNCTION stamp_user(id int, comment text) RETURNS void AS $$ <<fn>> @@ -3672,7 +3647,7 @@ $$ LANGUAGE plpgsql; - 目前,变量替换只在 SELECTINSERTUPDATEDELETEMERGE 以及包含其中之一的命令中生效(例如 EXPLAINCREATE TABLE ... AS SELECT),因为主 SQL 引擎只允许在这些命令中使用查询参数。若要在其他语句类型(统称为实用语句)中使用非常量名称或值,就必须把该实用语句构造为字符串,再用 EXECUTE 执行。 + 目前,变量替换只在 SELECTINSERTUPDATEDELETEMERGE 以及包含其中之一的命令中生效(例如 EXPLAINCREATE TABLE ... AS SELECT),因为主 SQL 引擎只允许在这些命令中使用查询参数。若要在其他语句类型(统称为工具语句)中使用非常量名称或值,就必须把该工具语句构造为字符串,再用 EXECUTE 执行。 @@ -3694,7 +3669,7 @@ $$ LANGUAGE plpgsql; - PL/pgSQL(更准确地说,是 SPI 管理器)还会尝试缓存与某个预备语句相关的执行计划。如果没有使用缓存计划,那么每次执行该语句时都会生成新的执行计划,而当前参数值(也就是 PL/pgSQL 变量值)可用于优化所选计划。如果该语句没有参数,或者会被执行很多次,SPI 管理器就会考虑创建一个不依赖具体参数值的通用计划,并将其缓存起来供重复使用。通常只有在执行计划对其中引用的 PL/pgSQL 变量值不太敏感时,才会这样做。如果执行计划对参数值非常敏感,那么每次重新生成计划总体上反而更划算。关于预备语句的行为,详见 。 + PL/pgSQL(更准确地说,是 SPI 管理器)还可以尝试缓存与某个预备语句相关的执行计划。如果没有使用缓存计划,那么每次执行该语句时都会生成新的执行计划,而当前参数值(也就是 PL/pgSQL 变量值)可用于优化所选计划。如果该语句没有参数,或者会被执行很多次,SPI 管理器就会考虑创建一个不依赖具体参数值的通用计划,并将其缓存起来供重复使用。通常只有在执行计划对其中引用的 PL/pgSQL 变量值不太敏感时,才会这样做。如果执行计划对参数值非常敏感,那么每次重新生成计划总体上反而更划算。关于预备语句的行为,详见 @@ -3743,7 +3718,7 @@ $$ LANGUAGE plpgsql; - 在logfunc2中,PostgreSQL的主解析器不知道应该把'now'解释成什么类型,因此返回一个text类型的数据值,其中包含字符串now。在确定对本地变量curtime的赋值时,PL/pgSQL解释器通过调用用于该转换的textouttimestamp_in函数,把这个字符串转换为timestamp类型。因此,计算得到的时间戳会按程序员预期在每次执行时更新。虽然这恰好能得到预期结果,但效率并不高,因此使用now()函数仍然是更好的主意。 + 在logfunc2中,PostgreSQL的主解析器不知道应该把'now'解释成什么类型,因此返回一个text类型的数据值,其中包含字符串now。在随后给局部变量curtime赋值时,PL/pgSQL解释器通过调用用于该转换的textouttimestamp_in函数,把这个字符串转换为timestamp类型。因此,计算得到的时间戳会按程序员预期在每次执行时更新。虽然这恰好能得到预期结果,但效率并不高,因此使用now()函数仍然是更好的主意。 @@ -3772,7 +3747,7 @@ $$ LANGUAGE plpgsql; - 另一种开发PL/pgSQL的好方法,是使用有助于过程语言开发的 GUI 数据库访问工具。这类工具的一个例子是pgAdmin,当然也有其他工具。它们通常提供一些方便的特性,例如转义单引号,以及让重新创建和调试函数变得更容易。 + 另一种使用PL/pgSQL进行开发的好方法,是使用有助于过程语言开发的 GUI 数据库访问工具。这类工具的一个例子是pgAdmin,当然也有其他工具。它们通常提供一些方便的特性,例如转义单引号,以及让重新创建和调试函数变得更容易。 @@ -3780,7 +3755,7 @@ $$ LANGUAGE plpgsql; 引号的处理 - 一个PL/pgSQL函数的代码在一个CREATE FUNCTION中被指定为一个字符串。如果你用通常的方式把该字符串写在单引号中间,那么该函数体中的任何单引号都必须被双写;同样任何反斜线也必须被双写(假定使用了转义字符串语法)。双写引号最多有点冗长,并且在更复杂的情况中代码会变得完全无法理解,因为你很容易发现你需要半打或者更多相邻的引号。我们推荐你转而把函数体写成一个美元引用的字符串(见)。在美元引用方法中,你从不需要双写任何引号。但是要注意为你需要的每一层嵌套选择一个不同的美元引用定界符。例如,你可能把CREATE FUNCTION命令写成: + 一个PL/pgSQL函数的代码在一个CREATE FUNCTION中被指定为一个字符串字面量。如果你用通常的方式把该字符串写在单引号中间,那么该函数体中的任何单引号都必须被双写;同样任何反斜线也必须被双写(假定使用了转义字符串语法)。双写引号本身就很繁琐,并且在更复杂的情况中代码会变得完全无法理解,因为你很容易发现你需要半打或者更多相邻的引号。我们推荐你转而把函数体写成一个美元引用的字符串(见)。在美元引用方法中,你从不需要双写任何引号。但是要注意为你需要的每一层嵌套选择一个不同的美元引用定界符。例如,你可能把CREATE FUNCTION命令写成: CREATE OR REPLACE FUNCTION testfunc(integer) RETURNS integer AS $PROC$ .... @@ -3817,7 +3792,7 @@ CREATE FUNCTION foo() RETURNS integer AS ' - 用于函数体内的字符串,例如: + 用于函数体内的字符串字面量,例如: a_output := ''Blah''; SELECT * FROM users WHERE f_name=''foobar''; @@ -3827,7 +3802,7 @@ SELECT * FROM users WHERE f_name=''foobar''; a_output := 'Blah'; SELECT * FROM users WHERE f_name='foobar'; - 这恰好就是PL/pgSQL在两种情况中会看到的。 + 这恰好就是PL/pgSQL解析器在两种情况中会看到的。 @@ -3850,7 +3825,7 @@ a_output := a_output || '' AND name LIKE ''''foobar'''' AND xyz'' a_output := a_output || $$ AND name LIKE 'foobar' AND xyz$$ - 要小心在这周围的任何美元引用定界符不只是$$。 + 要小心在这周围的任何美元引用定界符都不能是$$ @@ -3883,7 +3858,7 @@ a_output := a_output || $$ AND name LIKE 'foobar'$$ - 当你想在一个字符串常量(占 8 个引号)中有两个单引号时并且这会挨着该字符串常量的末尾(另外 2 个)。如果你正在写一个产生其他函数的函数(如中),你将很可能只需要这种。例如: + 当字符串常量中需要两个单引号(这需要 8 个引号),而且它们紧邻该字符串常量的末尾(还需 2 个引号)时。通常只有在编写生成其他函数的函数时(如所示),才会需要这种写法。例如: a_output := a_output || '' if v_'' || referrer_keys.kind || '' like '''''''''' @@ -3925,9 +3900,7 @@ a_output := a_output || $$ if v_$$ || referrer_keys.kind || $$ like '$$ 因此建议你在一个单独的开发环境中进行测试。 - - 根据需要设置 plpgsql.extra_warningsplpgsql.extra_errors,适当情况下,在开发和/或测试环境中可以设置为 "all"。 - + 建议在开发和/或测试环境中,根据需要将 plpgsql.extra_warningsplpgsql.extra_errors 设置为 "all" 这些额外的检查通过配置变量plpgsql.extra_warnings来启用警告, @@ -4041,18 +4014,16 @@ HINT: Make sure the query returns the exact list of columns. - PL/pgSQL与 PL/SQL 在许多方面都非常类似。它是一种块结构的、命令式的语言并且所有变量必须先被声明。赋值、循环和条件则很类似。在从PL/SQLPL/pgSQL移植时必须记住一些事情: - - + PL/pgSQL在许多方面都与 PL/SQL 类似。它是一种具有块结构的命令式语言,所有变量都必须声明。赋值、循环和条件语句也都很相似。在从PL/SQL移植到PL/pgSQL时,应当记住以下主要差异: - 如果一个 SQL 命令中使用的名字可能是一个表的列名或者是对一个函数中变量的引用,那么PL/SQL会将它当作一个列名。默认情况下, PL/pgSQL会抛出名称模糊的错误, 你可以指定plpgsql.variable_conflict=use_column来改变这一行为以匹配PL/SQL。如中所述。通常最好是首先避免这种歧义,但如果不得不移植依赖于该行为的大量代码,那么设置variable_conflict将是最好的方案。 + 如果一个 SQL 命令中使用的名字可能是一个表的列名或者是对一个函数中变量的引用,那么PL/SQL会将它当作一个列名。默认情况下, PL/pgSQL会抛出名称有歧义的错误, 你可以指定plpgsql.variable_conflict=use_column来改变这一行为以匹配PL/SQL。如中所述。通常最好是首先避免这种歧义,但如果不得不移植依赖于该行为的大量代码,那么设置variable_conflict可能是最好的方案。 - 在PostgreSQL中,函数体必须写成字符串文本。因此你需要使用美元符引用或者转义函数体中的单引号(见)。 + 在PostgreSQL中,函数体必须写成字符串字面量。因此你需要使用美元符引用或者转义函数体中的单引号(见)。 @@ -4142,13 +4113,13 @@ show errors; - 在PostgreSQL中,函数体被认为是一个字符串,所以你需要使用引号或者美元符号包围它。这代替了Oracle 方法中的用于终止的/。 + 在PostgreSQL中,函数体被认为是一个字符串字面量,所以你需要使用引号或者美元引用定界符包围它。这代替了Oracle 方法中的用于终止的/ - 在PostgreSQL中没有show errors命令, 并且也不需要这个命令,因为错误是自动报告的。 + 在PostgreSQL中没有show errors命令, 并且也不需要这个命令,因为错误是自动报告的。 @@ -4180,9 +4151,7 @@ $$ LANGUAGE plpgsql; 从<application>PL/SQL</application>移植一个创建另一个函数的函数到<application>PL/pgSQL</application> - - 下面的过程从一个SELECT语句抓取行,并且为了效率而构建一个带有IF语句中结果的大型函数。 - + 下面的过程从 SELECT 语句读取行,并将结果写入 IF 语句,从而构造一个大型函数,以提高效率。 这是 Oracle 版本: @@ -4213,8 +4182,7 @@ show errors; - - 这里是PostgreSQL的版本: + 下面是这个函数的最终移植结果,目标数据库为PostgreSQL CREATE OR REPLACE PROCEDURE cs_update_referrer_type_proc() AS $func$ DECLARE @@ -4247,9 +4215,7 @@ BEGIN EXECUTE func_cmd; END; $func$ LANGUAGE plpgsql; - - 请注意,这里先单独构造了函数体,再通过 quote_literal 传入,以便把其中的引号正确双写。之所以需要这种技术,是因为我们无法安全地使用美元引用来定义新函数:我们并不确切知道会从 referrer_key.key_string 字段插入什么字符串。(这里假定 referrer_key.kind 始终可信地只会是 hostdomainurl,但 referrer_key.key_string 可能是任意内容,尤其可能包含美元符号。)实际上,这个函数比 Oracle 原版还有改进,因为当 referrer_key.key_stringreferrer_key.referrer_type 中包含引号时,它也不会生成无效代码。 - +注意,这里单独构造函数体,然后将其传给quote_literal,使其中的每个引号都变成两个。这种技术是必需的,因为不能安全地使用美元引用来定义新函数:我们无法确定会插入什么字符串,其来源是referrer_key.key_string字段。(这里假定referrer_key.kind可信,其值总是hostdomainurl,但是referrer_key.key_string可能是任何内容,尤其可能包含美元符号。)这个函数实际上改进了 Oracle 原版:当referrer_key.key_stringreferrer_key.referrer_type中包含引号时,它也不会生成有问题的代码。 @@ -4269,7 +4235,7 @@ $func$ LANGUAGE plpgsql; CREATE OR REPLACE PROCEDURE cs_parse_url( v_url IN VARCHAR2, - v_host OUT VARCHAR2, -- 这将被传回去 + v_host OUT VARCHAR2, -- 这个值将被返回 v_path OUT VARCHAR2, -- 这个也是 v_query OUT VARCHAR2) -- 还有这个 IS @@ -4312,9 +4278,9 @@ show errors; CREATE OR REPLACE FUNCTION cs_parse_url( v_url IN VARCHAR, - v_host OUT VARCHAR, -- 这将被传递回去 + v_host OUT VARCHAR, -- 这个值将被返回 v_path OUT VARCHAR, -- 这个也是 - v_query OUT VARCHAR) -- 以及这个 + v_query OUT VARCHAR) -- 还有这个 AS $$ DECLARE a_pos1 INTEGER; @@ -4357,7 +4323,7 @@ SELECT * FROM cs_parse_url('http://foobar.com/query.cgi?baz'); - 展示了如何移植一个使用了多种 Oracle 特性的过程。 + 展示了如何移植一个使用了多种 Oracle 专属特性的过程。 @@ -4397,7 +4363,7 @@ show errors - 这是我们如何将这个过程移植到PL/pgSQL: + 下面展示了如何将这个过程移植到PL/pgSQL CREATE OR REPLACE PROCEDURE cs_create_job(v_job_id integer) AS $$ @@ -4472,7 +4438,7 @@ EXCEPTION END; - 如果你正在移植一个以这种方式使用SAVEPOINTROLLBACK TO的 Oracle 过程,工作会比较简单:只要忽略SAVEPOINTROLLBACK TO即可。如果你的 Oracle 过程以不同方式使用SAVEPOINTROLLBACK TO,那就需要认真思考了。 + 如果你正在移植一个以这种方式使用SAVEPOINTROLLBACK TO的 Oracle 过程,工作会比较简单:只要省略SAVEPOINTROLLBACK TO即可。如果你的 Oracle 过程以不同方式使用SAVEPOINTROLLBACK TO,那就需要认真思考了。 @@ -4489,11 +4455,11 @@ END; 优化 <application>PL/pgSQL</application> 函数 - PostgreSQL提供了两种函数创建修饰符来优化执行:volatility(对于给定的相同参数,函数是否总是返回相同的结果)以及strictness (如果任何参数为空,函数是否返回空)。详见参考页。 + PostgreSQL提供了两种函数创建修饰符来优化执行:volatility(对于给定的相同参数,函数是否总是返回相同的结果)以及strictness (如果任何参数为空值,函数是否返回空值)。详见参考页。 - 在利用这些优化属性时,你的CREATE FUNCTION语句应该看起来像这样: + 在利用这些优化属性时,你的CREATE FUNCTION语句可能像这样: CREATE FUNCTION foo(...) RETURNS integer AS $$ diff --git a/zh/18/plpython.sgml b/zh/18/plpython.sgml index 25d33332..19a3c11b 100644 --- a/zh/18/plpython.sgml +++ b/zh/18/plpython.sgml @@ -45,7 +45,7 @@ CREATE FUNCTION funcname (argument-list) RETURNS return-type AS $$ - # PL/Python function body + # PL/Python 函数体 $$ LANGUAGE plpython3u; @@ -85,7 +85,7 @@ def __plpython_procedure_pymax_23456(): CREATE FUNCTION pystrip(x text) RETURNS text AS $$ - x = x.strip() # error + x = x.strip() # 错误 return x $$ LANGUAGE plpython3u; @@ -95,7 +95,7 @@ CREATE FUNCTION pystrip(x text) RETURNS text AS $$ global x - x = x.strip() # ok now + x = x.strip() # 现在可以正常工作 return x $$ LANGUAGE plpython3u; @@ -216,7 +216,7 @@ $$ LANGUAGE plpython3u; 如果把 SQL 空值空值在 PL/Python 中传给函数,参数值在 Python 中会显示为None。例如,中展示的pymax定义在处理空输入时就会返回错误结果。我们可以在函数定义中添加STRICT,让PostgreSQL做出更合理的处理:如果传入空值,函数根本不会被调用,而是自动返回空结果。另一种办法是在函数体中检查空输入: + sortas="PL/Python">在 PL/Python 中传给函数,参数值在 Python 中会显示为None。例如,中展示的pymax定义在处理空值输入时就会返回错误结果。我们可以在函数定义中添加STRICT,让PostgreSQL做出更合理的处理:如果传入空值,函数根本不会被调用,而是自动返回空值结果。另一种办法是在函数体中检查空值输入: CREATE FUNCTION pymax (a integer, b integer) @@ -329,21 +329,21 @@ CREATE TYPE named_value AS ( ); - 组合结果可以按以下形式返回: + 复合结果可以按以下形式返回: 序列类型(元组或列表,但不能是集合,因为集合不可通过索引访问) - 返回的序列对象必须包含与组合结果类型字段数相同的项。索引为 0 的项会赋给复合类型的第一个字段,索引为 1 的项赋给第二个字段,依此类推。例如: + 返回的序列对象必须包含与复合结果类型字段数相同的项。索引为 0 的项会赋给复合类型的第一个字段,索引为 1 的项赋给第二个字段,依此类推。例如: CREATE FUNCTION make_pair (name text, value integer) RETURNS named_value AS $$ return ( name, value ) - # or alternatively, as list: return [ name, value ] + # 也可以使用列表: return [ name, value ] $$ LANGUAGE plpython3u; @@ -391,7 +391,7 @@ AS $$ self.value = v return named_value(name, value) - # or simply + # 或者简写为 class nv: pass nv.name = name nv.value = value @@ -452,8 +452,8 @@ CREATE TYPE greeting AS ( CREATE FUNCTION greet (how text) RETURNS SETOF greeting AS $$ - # return tuple containing lists as composite types - # all other combinations work also + # 返回包含列表的元组,以列表表示复合类型 + # 其他组合方式也都可用 return ( [ how, "World" ], [ how, "PostgreSQL" ], [ how, "PL/Python" ] ) $$ LANGUAGE plpython3u; @@ -511,7 +511,7 @@ $$ LANGUAGE plpython3u; - 也支持带OUT参数的返回集函数(使用RETURNS SETOF record)。例如: + 也支持带OUT参数的集合返回函数(使用RETURNS SETOF record)。例如: CREATE FUNCTION multiout_simple_setof(n integer, OUT integer, OUT integer) RETURNS SETOF record AS $$ return [(1, 2)] * n @@ -546,7 +546,7 @@ SELECT * FROM multiout_simple_setof(3); DO $$ - # PL/Python code + # PL/Python 代码 $$ LANGUAGE plpython3u; @@ -795,7 +795,7 @@ CREATE FUNCTION usesavedplan() RETURNS trigger AS $$ else: plan = plpy.prepare("SELECT 1") SD["plan"] = plan - # rest of function + # 函数的其余部分 $$ LANGUAGE plpython3u; @@ -812,11 +812,11 @@ $$ LANGUAGE plpython3u; - 游标对象提供fetch方法,它接受一个整数参数并返回结果对象。每次调用fetch,返回对象都会包含下一批行,数量不会超过该参数值。一旦所有行都已取完,fetch就会开始返回空结果对象。游标对象还提供迭代器接口,每次产生一行,直到所有行为止。以这种方式获取的数据不会作为结果对象返回,而是以字典形式返回,每个字典对应一行结果。 + 游标对象提供fetch方法,它接受一个整数参数并返回结果对象。每次调用fetch,返回对象都会包含下一批行,数量不会超过该参数值。一旦所有行都已取完,fetch就会开始返回空结果对象。游标对象还提供迭代器接口,每次产生一行,直到取完所有行。以这种方式获取的数据不会作为结果对象返回,而是以字典形式返回,每个字典对应一行结果。 - 下面示例展示了如何处理大表中的数据: + 下面示例展示了处理大表中数据的两种方式: CREATE FUNCTION count_odd_iterator() RETURNS integer AS $$ odd = 0 @@ -842,7 +842,7 @@ $$ LANGUAGE plpython3u; CREATE FUNCTION count_odd_prepared() RETURNS integer AS $$ odd = 0 plan = plpy.prepare("select num from largetable where num % $1 <> 0", ["integer"]) -rows = list(plpy.cursor(plan, [2])) # or: = list(plan.cursor([2])) +rows = list(plpy.cursor(plan, [2])) # 或者:= list(plan.cursor([2])) return len(rows) $$ LANGUAGE plpython3u; @@ -995,7 +995,7 @@ CALL transaction_test1(); - 实用函数 + 辅助函数 plpy模块还提供以下函数: @@ -1049,7 +1049,7 @@ PL/Python function "raise_custom_exception" - 另一组实用函数是plpy.quote_literal(string)plpy.quote_nullable(string)以及plpy.quote_ident(string)。它们等价于中描述的内置引用函数。在构造临时查询时,这些函数很有用。中动态 SQL 的一个 PL/Python 等价写法如下: + 另一组辅助函数是plpy.quote_literal(string)plpy.quote_nullable(string)以及plpy.quote_ident(string)。它们等价于中描述的内置加引号函数。在构造临时查询时,这些函数很有用。中动态 SQL 的一个 PL/Python 等价写法如下: plpy.execute("UPDATE tbl SET %s = %s WHERE key = %s" % ( plpy.quote_ident(colname), diff --git a/zh/18/pltcl.sgml b/zh/18/pltcl.sgml index d4e0e94c..6da91aa5 100644 --- a/zh/18/pltcl.sgml +++ b/zh/18/pltcl.sgml @@ -13,7 +13,7 @@ - PL/Tcl 是一种适用于 PostgreSQL 数据库系统的可载入的过程语言,它允许使用 Tcl 语言 来编写 PostgreSQL 函数和过程。 + PL/Tcl 是一种适用于 PostgreSQL 数据库系统的可加载的过程语言,它允许使用 Tcl 语言 来编写 PostgreSQL 函数和过程。 @@ -54,7 +54,7 @@ CREATE FUNCTION funcname (argument-types) RETURNS return-type AS $$ - # PL/Tcl function body + # PL/Tcl 函数体 $$ LANGUAGE pltcl; @@ -75,11 +75,11 @@ CREATE FUNCTION tcl_max(integer, integer) RETURNS integer AS $$ $$ LANGUAGE pltcl STRICT; - 注意STRICT子句,它让我们不必考虑空输入值:如果传入的是空值,函数根本不会被调用,而是会自动返回空结果。 + 注意STRICT子句,它让我们不必考虑空值输入:如果传入的是空值,函数根本不会被调用,而是会自动返回空值结果。 - 在非严格函数中,如果某个参数的实际值为空,对应的$n变量会被设置为空串。要检测某个特定参数是否为空,可使用函数argisnull。例如,假设我们希望在tcl_max的两个参数中一个为空、一个非空时返回非空参数,而不是返回空值: + 在非严格函数中,如果某个参数的实际值为空值,对应的$n变量会被设置为空串。要检测某个特定参数是否为空值,可使用函数argisnull。例如,假设我们希望在tcl_max的两个参数中一个为空值、一个非空值时返回非空值参数,而不是返回空值: CREATE FUNCTION tcl_max(integer, integer) RETURNS integer AS $$ @@ -99,7 +99,7 @@ $$ LANGUAGE pltcl; - 复合类型参数会作为 Tcl 数组传递给函数。数组元素名就是该复合类型的属性名。如果传入行中的某个属性为 NULL,它就不会出现在数组中。下面是一个示例: + 复合类型参数会作为 Tcl 数组传递给函数。数组元素名就是该复合类型的属性名。如果传入行中的某个属性为空值,它就不会出现在数组中。下面是一个示例: CREATE TABLE employee ( @@ -185,7 +185,7 @@ $$ LANGUAGE pltcl; PL/Tcl 中的数据值 - 提供给 PL/Tcl 函数代码的参数值,只是将输入参数转换成文本形式(就像用SELECT语句将它们显示出来一样)。反过来,returnreturn_next命令会接受任何字符串,只要它是该函数声明结果类型或组合结果类型中指定列的可接受输入格式。 + 提供给 PL/Tcl 函数代码的参数值,只是将输入参数转换成文本形式(就像用SELECT语句将它们显示出来一样)。反过来,returnreturn_next命令会接受任何字符串,只要它是该函数声明结果类型或复合结果类型中指定列的可接受输入格式。 @@ -195,8 +195,8 @@ $$ LANGUAGE pltcl; PL/Tcl 中的全局数据 - global data - in PL/Tcl + 全局数据 + 在 PL/Tcl 中 @@ -234,7 +234,7 @@ $$ LANGUAGE pltcl; - 执行以字符串形式给出的 SQL 命令。命令出错时会引发错误。否则,spi_exec的返回值是该命令处理的行数(选出、插入、更新或删除的行),如果命令是实用程序语句则返回零。此外,如果命令是SELECT语句,则所选列的值会按下文所述放入 Tcl 变量中。 + 执行以字符串形式给出的 SQL 命令。命令出错时会引发错误。否则,spi_exec的返回值是该命令处理的行数(选出、插入、更新或删除的行),如果命令是工具语句则返回零。此外,如果命令是SELECT语句,则所选列的值会按下文所述放入 Tcl 变量中。 @@ -275,7 +275,7 @@ spi_exec -array C "SELECT * FROM pg_class" { - 如果查询结果中的某一列为空,则对应的目标变量会被unset,而不是被设值。 + 如果查询结果中的某一列为空值,则对应的目标变量会被unset,而不是被设值。 @@ -287,7 +287,7 @@ spi_exec -array C "SELECT * FROM pg_class" { 准备并保存一个查询计划以供后续执行。保存的计划会在当前会话的整个生命周期内保留。 准备查询 - 在PL/Tcl中 + 在 PL/Tcl 中 @@ -317,7 +317,7 @@ spi_exec -array C "SELECT * FROM pg_class" { 可选的-nulls值是由空格和'n'字符组成的字符串,用来告诉spi_execp哪些参数是空值。 - 如果给出,它的长度必须与value-list完全相同。如果未给出,则所有参数值都视为非空。 + 如果给出,它的长度必须与value-list完全相同。如果未给出,则所有参数值都视为非空值。 @@ -331,7 +331,7 @@ spi_exec -array C "SELECT * FROM pg_class" { CREATE FUNCTION t1_count(integer, integer) RETURNS integer AS $$ if {![ info exists GD(plan) ]} { - # prepare the saved plan on the first call + # 在首次调用时准备并保存计划 set GD(plan) [ spi_prepare \ "SELECT count(*) AS cnt FROM t1 WHERE num >= \$1 AND num <= \$2" \ [ list int4 int4 ] ] @@ -367,7 +367,7 @@ $$ LANGUAGE pltcl; 将给定字符串中的所有单引号和反斜杠字符都加倍。 - 这可用于安全地引用那些要插入到传给spi_execspi_prepare的 SQL 命令中的字符串。 + 这可用于安全地为那些要插入到传给spi_execspi_prepare的 SQL 命令中的字符串加引号。 例如,考虑如下 SQL 命令字符串: @@ -393,7 +393,7 @@ SELECT 'doesn''t' AS ret "SELECT '[ quote $val ]' AS ret" - spi_execp的一个优点是,你不必像这样对参数值做引用,因为这些参数永远不会作为 SQL 命令字符串的一部分被解析。 + spi_execp的一个优点是,你不必像这样给参数值加引号,因为这些参数永远不会作为 SQL 命令字符串的一部分被解析。 @@ -404,7 +404,7 @@ SELECT 'doesn''t' AS ret elog level msg elog - 在PL/Tcl中 + 在 PL/Tcl 中 @@ -436,8 +436,8 @@ SELECT 'doesn''t' AS ret PL/Tcl 中的触发器函数 - trigger - in PL/Tcl + 触发器 + 在 PL/Tcl 中 @@ -525,7 +525,7 @@ SELECT 'doesn''t' AS ret $NEW - 对于INSERTUPDATE动作,这是一个包含新表行值的关联数组;对于DELETE则为空。该数组以列名为索引。值为 NULL 的列不会出现在数组中。对于语句级触发器,不会设置这个变量。 + 对于INSERTUPDATE动作,这是一个包含新表行值的关联数组;对于DELETE则为空。该数组以列名为索引。值为空值的列不会出现在数组中。对于语句级触发器,不会设置这个变量。 @@ -534,7 +534,7 @@ SELECT 'doesn''t' AS ret $OLD - 对于UPDATEDELETE动作,这是一个包含旧表行值的关联数组;对于INSERT则为空。该数组以列名为索引。值为 NULL 的列不会出现在数组中。对于语句级触发器,不会设置这个变量。 + 对于UPDATEDELETE动作,这是一个包含旧表行值的关联数组;对于INSERT则为空。该数组以列名为索引。值为空值的列不会出现在数组中。对于语句级触发器,不会设置这个变量。 @@ -598,8 +598,8 @@ CREATE TRIGGER trig_mytab_modcount BEFORE INSERT OR UPDATE ON mytab PL/Tcl 中的事件触发器函数 - event trigger - in PL/Tcl + 事件触发器 + 在 PL/Tcl 中 @@ -615,7 +615,7 @@ CREATE TRIGGER trig_mytab_modcount BEFORE INSERT OR UPDATE ON mytab $TG_event - 触发器因其而被触发的事件名称。 + 该触发器所针对的事件名称。 @@ -624,7 +624,7 @@ CREATE TRIGGER trig_mytab_modcount BEFORE INSERT OR UPDATE ON mytab $TG_tag - 触发器因其而被触发的命令标签。 + 该触发器所针对的命令标签。 @@ -632,7 +632,7 @@ CREATE TRIGGER trig_mytab_modcount BEFORE INSERT OR UPDATE ON mytab - 事件触发器函数的返回值会被忽略。 + 触发器函数的返回值会被忽略。 @@ -653,8 +653,8 @@ CREATE EVENT TRIGGER tcl_a_snitch ON ddl_command_start EXECUTE FUNCTION tclsnitc PL/Tcl 中的错误处理 - exceptions - in PL/Tcl + 异常 + 在 PL/Tcl 中 @@ -682,9 +682,9 @@ if {[catch { spi_exec $sql_command }]} { if {[lindex $::errorCode 0] == "POSTGRES"} { array set errorArray $::errorCode if {$errorArray(condition) == "undefined_table"} { - # deal with missing table + # 处理表不存在的情况 } else { - # deal with some other type of SQL error + # 处理其他类型的 SQL 错误 } } } @@ -698,8 +698,8 @@ if {[catch { spi_exec $sql_command }]} { PL/Tcl 中的显式子事务 - subtransactions - in PL/Tcl + 子事务 + 在 PL/Tcl 中 @@ -797,7 +797,7 @@ CALL transaction_test1(); pltcl.start_proc (string) - pltcl.start_proc configuration parameter + pltcl.start_proc 配置参数 @@ -825,7 +825,7 @@ CALL transaction_test1(); pltclu.start_proc (string) - pltclu.start_proc configuration parameter + pltclu.start_proc 配置参数 diff --git a/zh/18/postgres-fdw.sgml b/zh/18/postgres-fdw.sgml index f3d0240a..7b22fbd4 100644 --- a/zh/18/postgres-fdw.sgml +++ b/zh/18/postgres-fdw.sgml @@ -38,7 +38,7 @@ - 对于每个需要被允许访问各外部服务器的数据库用户,使用 + 对于每个需要获准访问各个外部服务器的数据库用户,使用 创建用户映射。将要使用的 远程用户名和密码指定为用户映射的 userpassword 选项。 @@ -56,7 +56,7 @@ - 现在,只需从外部表执行 SELECT,即可访问其底层远程表中 + 现在,只需对外部表执行 SELECT,即可访问其底层远程表中 存储的数据。也可以使用 INSERTUPDATEDELETECOPYTRUNCATE 修改远程表。 @@ -120,8 +120,7 @@ application_name 可以出现在连接选项和 - 中的任一处,或同时出现在 - 二者中。 + 中的任一处,或同时出现在二者中。 如果两者都存在,postgres_fdw.application_name 会覆盖连接设置。与 libpq 不同, postgres_fdw 允许 application_name @@ -250,7 +249,7 @@ OPTIONS (ADD password_required 'false'); - fdw_startup_cost (floating point) + fdw_startup_cost (浮点数) 该选项可为外部服务器指定,是一个浮点值,会被加到该服务器上任何 @@ -261,7 +260,7 @@ OPTIONS (ADD password_required 'false'); - fdw_tuple_cost (floating point) + fdw_tuple_cost (浮点数) 该选项可为外部服务器指定,是一个浮点值,用作该服务器上外部表扫描的 @@ -339,7 +338,7 @@ OPTIONS (ADD password_required 'false'); 该选项是一个以逗号分隔的 PostgreSQL 扩展 名称列表,这些扩展必须在本地和远程服务器上都已安装且版本兼容。 - 属于列出扩展且为 immutable 的函数和操作符,将被视为可下推到远程服务器 + 属于列出扩展且不可变的函数和操作符,将被视为可下推到远程服务器 执行。该选项只能为外部服务器指定,不能按表指定。 @@ -381,7 +380,7 @@ OPTIONS (ADD password_required 'false'); - 该选项也适用于向外部表执行 COPY。在这种情况下, + 该选项也适用于向外部表复制数据。在这种情况下, postgres_fdw 实际一次复制的行数会以与插入场景 类似的方式确定,但由于 COPY 命令的实现限制, 最多只能为 1000 行。 @@ -573,8 +572,7 @@ OPTIONS (ADD password_required 'false'); COLLATE 选项。默认值为 true。 如果远程服务器的排序规则名称集合与本地服务器不同,则可能需要关闭此 选项;如果远程服务器运行在不同操作系统上,这种情况尤其可能发生。 - 不过,如果这样做,导入表列的排序规则极有可能与底层数据不匹配, - 从而导致查询行为异常。 + 不过,如果这样做,导入表列的排序规则就存在与底层数据不匹配的严重风险,从而导致查询行为异常。 @@ -669,7 +667,7 @@ OPTIONS (ADD password_required 'false'); 该选项控制 postgres_fdw 在连接到外部服务器时 是否使用 SCRAM 透传认证。该选项可为外部服务器或用户映射指定。 用户映射的设置会覆盖外部服务器的设置。使用 SCRAM 透传认证时, - postgres_fdw 使用 SCRAM 哈希后的凭据,而不是 + postgres_fdw 使用经 SCRAM Hash 处理的凭据,而不是 明文用户密码连接远程服务器。这样可以避免在 PostgreSQL 系统目录中 存储明文用户密码。 @@ -702,13 +700,13 @@ OPTIONS (ADD password_required 'false'); 运行 postgres_fdw 的服务器与远程服务器, 必须针对用于在 postgres_fdw 上认证到外部 - 服务器的该用户,拥有完全相同的 SCRAM secret(加密密码) + 服务器的该用户,拥有完全相同的 SCRAM 凭据(加密密码) (盐值和迭代次数都必须相同,而不仅仅是密码相同)。 因而,如果要建立到多个主机的 FDW 连接,例如用于分区外部表或分片, - 则所有主机都必须为相关用户保存完全相同的 SCRAM secret。 + 则所有主机都必须为相关用户保存完全相同的 SCRAM 凭据。 @@ -931,8 +929,7 @@ postgres=# SELECT postgres_fdw_disconnect_all(); - 请注意,postgres_fdw 当前不支持将远程事务预备为 - 两阶段提交。 + 请注意,postgres_fdw 当前不支持为两阶段提交预备远程事务。 @@ -943,9 +940,9 @@ postgres=# SELECT postgres_fdw_disconnect_all(); postgres_fdw 会尽力优化远程查询,以减少从外部 服务器传输的数据量。这是通过将查询的 WHERE 子句发送到 远程服务器执行,以及不获取当前查询不需要的表列来实现的。为降低查询被 - 错误执行的风险,除非 WHERE 子句仅使用内置数据类型、 - 操作符和函数,或属于外部服务器 extensions 选项列出的 - 扩展,否则不会将其发送到远程服务器。这类子句中的操作符和函数还必须是 + 错误执行的风险,只有当 WHERE 子句使用的所有数据类型、 + 操作符和函数都是内置的,或属于外部服务器 extensions + 选项列出的扩展时,才会将该子句发送到远程服务器。这类子句中的操作符和函数还必须是 IMMUTABLE。对于 UPDATEDELETE 查询,postgres_fdw 会在 查询中不存在无法发送到远程服务器的 WHERE 子句、没有 @@ -1095,7 +1092,7 @@ postgres=# SELECT postgres_fdw_disconnect_all(); postgres_fdw.application_name (string) - postgres_fdw.application_name configuration parameter + postgres_fdw.application_name 配置参数 @@ -1109,7 +1106,7 @@ postgres=# SELECT postgres_fdw_disconnect_all(); postgres_fdw.application_name 可以是任意长度的任意 字符串,甚至可以包含非 ASCII 字符。不过,当它被传递并作为外部服务器中 的 application_name 使用时,请注意它会被截断到少于 - NAMEDATALEN 个字符。所有不可打印 ASCII 字符都会被 + NAMEDATALEN 个字符。除可打印 ASCII 字符以外的所有字符都会被 替换为C 风格的十六进制转义。 有关细节见 。 @@ -1163,7 +1160,7 @@ postgres=# SELECT postgres_fdw_disconnect_all(); %% - 字面值 % + 字面字符 % diff --git a/zh/18/protocol.sgml b/zh/18/protocol.sgml index 6c471b60..4607effe 100644 --- a/zh/18/protocol.sgml +++ b/zh/18/protocol.sgml @@ -227,9 +227,7 @@ 前端现在必须发送一个 PasswordMessage,其中包含密码;该密码先与用户名一起经过 MD5 加密,再使用 AuthenticationMD5Password 消息中指定的 4 字节随机盐重新加密。如果密码正确,服务器响应 AuthenticationOk;否则响应 ErrorResponse。实际的 PasswordMessage 可以用 SQL 计算:concat('md5', md5(concat(md5(concat(password, username)), random-salt)))。(请记住 md5() 函数返回的是十六进制字符串。) - - 对 MD5 加密密码的支持已弃用,并将在未来版本 PostgreSQL 中移除。关于迁移到其他密码类型,请参阅 。 - + 对 MD5 加密密码的支持已弃用,并将在PostgreSQL的未来版本中移除。迁移到其他密码类型的详细信息见 @@ -832,7 +830,7 @@ SELCT 1/0; - 目前,系统会为以下参数发送 ParameterStatus: + 目前,会为一组固定的参数生成 ParameterStatus,参数如下: application_name client_encoding @@ -850,10 +848,8 @@ SELCT 1/0; standard_conforming_strings TimeZone - (default_transaction_read_onlyin_hot_standby 在 14 之前不报告; - scram_iterations 在 16 之前不报告; - search_path 在 18 之前不报告。) - 注意 server_versionserver_encodinginteger_datetimes 是启动后不可更改的伪参数。未来该集合可能变化,甚至可能变为可配置。因此,前端应忽略其不理解或不关心的 ParameterStatus。 + (14 之前的版本不报告 default_transaction_read_onlyin_hot_standby;16 之前的版本不报告 scram_iterations;18 之前的版本不报告 search_path。) + 注意,server_versionserver_encodinginteger_datetimes 是启动后不能改变的伪参数。这组参数将来可能变化,甚至可能变为可配置。因此,前端应直接忽略其不理解或不关心的参数的 ParameterStatus。 @@ -1368,7 +1364,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" CREATE_REPLICATION_SLOT slot_name [ TEMPORARY ] { PHYSICAL | LOGICAL output_plugin } [ ( option [, ...] ) ] - 创建复制槽 + CREATE_REPLICATION_SLOT @@ -1425,15 +1421,6 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - - FAILOVER [ boolean ] - - - 若为 true,则该复制槽会同步到备库,从而在故障切换后恢复逻辑复制。默认值为 false。 - - - - RESERVE_WAL [ boolean ] @@ -1450,13 +1437,14 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" SNAPSHOT { 'export' | 'use' | 'nothing' } - - 决定在逻辑复制槽初始化期间如何处理所创建的快照。'export' - 这是默认选项,将导出快照供其他会话使用。此选项不能在事务内使用。 - 'use'将为执行命令的当前事务使用快照。此选项必须在事务中使用, - 并且CREATE_REPLICATION_SLOT必须是在该事务中运行的第一个命令。 - 最后,'nothing'将像往常一样仅用于逻辑解码使用快照,但不会执行其他操作。 - + 决定如何处理初始化逻辑复制槽时创建的快照。默认选项 'export' 会导出快照供其他会话使用,此选项不能在事务内使用。'use' 会将快照用于执行该命令的当前事务;此选项必须在事务内使用,且 CREATE_REPLICATION_SLOT 必须是该事务中执行的第一条命令。最后,'nothing' 只会像平常一样将快照用于逻辑解码,不会对其执行其他操作。 + + + + + FAILOVER [ boolean ] + + 若为 true,则允许该复制槽同步到备库,以便在故障切换后恢复逻辑复制。默认值为 false。 @@ -1487,7 +1475,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" snapshot_name (text) - 该命令导出的快照标识符。该快照在此连接上执行下一条命令之前,或复制连接关闭之前有效。如果所创建的是物理复制槽,则为 null。 + 该命令导出的快照标识符。该快照在此连接上执行下一条命令之前,或复制连接关闭之前有效。如果所创建的是物理复制槽,则为空值。 @@ -1496,7 +1484,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" output_plugin (text) - 新建复制槽所使用的输出插件名称。如果所创建的是物理复制槽,则为 null。 + 新建复制槽所使用的输出插件名称。如果所创建的是物理复制槽,则为空值。 @@ -2050,7 +2038,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 指示服务器开始流式传输基本备份。 + 指示服务器开始流式传输基础备份。 在备份开始之前,系统将自动进入备份模式,并在备份完成后退出备份模式。 接受以下选项: @@ -2061,7 +2049,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" 设置备份的标签。如果未指定,则将使用base backup作为备份标签。 - 标签的引用规则与打开的标准SQL字符串相同。 + 标签的引号使用规则与打开的标准SQL字符串相同。 @@ -2101,11 +2089,11 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 如果设置为true,则请求生成进度报告所需的信息。这将在每个表空间的头部发送一个近似大小, + 如果设置为true,则请求生成进度报告所需的信息。这将在每个表空间的首部发送一个近似大小, 可用于计算流式传输的进度。这是通过在传输开始之前先枚举所有文件大小来计算的, 可能会对性能产生负面影响。特别是,在流式传输数据之前可能需要更长的时间。 由于备份期间数据库文件可能会发生变化,因此大小仅为近似值, - 在近似值和实际文件发送之间可能会增长或缩小。默认值为false。 + 在估算与实际发送文件之间的这段时间里可能会增长或缩小。默认值为false。 @@ -2115,7 +2103,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 设置在基本备份开始时执行的检查点类型。默认值为spread。 + 设置在基础备份开始时执行的检查点类型。默认值为spread @@ -2124,9 +2112,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" WAL [ boolean ] - - 如果设置为true,则在备份中包含必要的WAL段。这将包括在开始和停止备份之间的所有文件在基本目录tar文件的pg_wal目录中。默认值为false。 - + 如果设置为 true,则在备份中包含必要的 WAL 段。这会把开始备份到停止备份之间的所有文件放入基础目录 tar 文件内的pg_wal目录中。默认值为 false。 @@ -2214,7 +2200,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 如果为true,则在进行基本备份时验证校验和(如果已启用)。如果为false,则跳过此步骤。默认值为true。 + 如果为true,则在进行基础备份时验证校验和(如果已启用)。如果为false,则跳过此步骤。默认值为true。 @@ -2229,7 +2215,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" 除了可能包含的任何WAL文件。它还存储每个文件的大小、最后修改时间, 以及可选的校验和。 值为force-encode会强制对所有文件名进行十六进制编码; - 否则,仅对文件名为非UTF8八位序列的文件执行此类型的编码。 + 否则,仅对文件名为非 UTF8 字节序列的文件执行此类型的编码。 force-encode主要用于测试目的,以确保读取备份清单的客户端 能够处理这种情况。为了与之前的版本兼容,默认值为MANIFEST 'no' @@ -2271,14 +2257,14 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" 第二个普通结果集中的每个表空间都有一行。 - 这一行中的字段是: + 这一行中的字段是: spcoid (oid) - 表空间的OID,如果是基本目录则为null。 + 表空间的OID,如果是基础目录则为null。 @@ -2287,7 +2273,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" spclocation (text) - 表空间目录的完整路径,如果是基本目录则为null。 + 表空间目录的完整路径,如果是基础目录则为null。 @@ -2311,7 +2297,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - new archive (B) + 新归档 (B) @@ -2343,7 +2329,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 对于主数据目录,使用空字符串。对于其他表空间,使用从创建此归档的目录的完整路径。 + 对于主数据目录,使用空字符串。对于其他表空间,使用创建此归档所用目录的完整路径。 @@ -2353,7 +2339,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - manifest (B) + 清单 (B) @@ -2402,7 +2388,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - progress report (B) + 进度报告 (B) @@ -2460,13 +2446,11 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - - 不记录 WAL 的关系(Unlogged表),除了需要在恢复时重新创建(空的)不记录 WAL 的关系的init fork。 - + 不记录 WAL 的关系,但不包括恢复时重新创建(空的)不记录 WAL 的关系所需的初始化分支。 - pg_wal,包括子目录。如果备份包含WAL文件,则将包含pg_wal的合成版本,但它只包含备份工作所需的文件,而不包含其余内容。 + pg_wal,包括子目录。如果备份包含WAL文件,则将包含pg_wal的合成版本,但它只包含使备份可用所需的文件,而不包含其余内容。 @@ -2479,7 +2463,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 除了常规文件和目录之外的文件,如符号链接(除了上述列出的目录之外的符号链接)以及特殊设备和操作系统文件,将被跳过。(pg_tblspc中的符号链接将被保留。) + 除了普通文件和目录之外的文件,如符号链接(除了上述列出的目录之外的符号链接)以及特殊设备和操作系统文件,将被跳过。(pg_tblspc中的符号链接将被保留。) @@ -2512,7 +2496,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 逻辑复制参数 + 逻辑流复制参数 使用 START_REPLICATION 命令时,pgoutput 接受以下选项: @@ -2527,13 +2511,13 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" 协议版本。目前支持的版本有 1234。必须指定一个有效版本。 - 版本2仅支持服务器版本14及以上,并允许流式传输大型进行中的事务。 + 版本 2 仅在服务器版本 14 及以上受支持,允许流式传输正在进行的大型事务。 - 版本3仅支持服务器版本15及以上,并允许流式传输两阶段提交。 + 版本 3 仅在服务器版本 15 及以上受支持,允许流式传输两阶段提交。 - 版本4仅支持服务器版本 16 及以上,并允许对大型进行中事务的流进行并行应用。 + 版本 4 仅在服务器版本 16 及以上受支持,允许并行应用正在进行的大型事务的流。 @@ -2544,8 +2528,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 用于订阅(接收更改)的发布名称的逗号分隔列表。各个发布名称按标准对象名处理,可按需加引号。 - 至少需要一个发布名称。 + 要订阅(接收变更)的发布名称列表,以逗号分隔。各个发布名称按标准对象名处理,可按需加引号。至少需要一个发布名称。 @@ -2556,7 +2539,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 使用二进制传输模式的布尔选项。二进制模式比文本模式更快,但略微不够稳健。 + 使用二进制传输模式的布尔选项。二进制模式比文本模式更快,但稳健性略差。 @@ -2567,7 +2550,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 一个布尔选项,用于启用发送由 pg_logical_emit_message 写入的消息。 + 布尔选项,用于启用发送由 pg_logical_emit_message 写入的消息。 @@ -2607,9 +2590,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - - 在上述命令中,若参数类型为 boolean,可省略 value 部分;省略等同于指定 TRUE。 - + @@ -3456,58 +3437,48 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - CancelRequest (F) - Int32 - - 消息内容的长度(以字节为单位),包括其自身。 + 消息内容的长度,以字节为单位,包括此长度字段本身。 - Int32(80877102) - - 取消请求代码。该值被选择为在最高的16位中包含1234,在最低的16位中包含5678。 - (为避免混淆,此代码不得与任何协议版本号相同。) + 取消请求代码。此值的最高 16 位为 1234,最低 16 位为 5678。(为避免混淆,此代码不能与任何协议版本号相同。) - Int32 - - 目标后端的进程ID。 + 目标后端的进程 ID。 - - Int32 + Byten - - 目标后端的 secret key。该字段长度由消息总长度决定并延伸至消息末尾,最大长度为 256 字节。 + 目标后端的密钥。此字段延伸至消息末尾,其范围由长度字段确定。密钥最长为 256 字节。 - 在协议 3.2 之前,secret key 固定为 4 字节。 - + 在协议版本 3.2 之前,密钥始终为 4 字节长。 + @@ -5587,7 +5558,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 严重性: 字段内容为ERROR, FATAL, 或 + 严重性: 字段内容为ERROR, FATAL, 或 PANIC (在错误消息中), 或 WARNING, NOTICE, DEBUG, INFO, 或 LOG (在通知消息中), @@ -5601,7 +5572,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 严重性:字段内容为ERRORFATAL或 + 严重性:字段内容为ERRORFATALPANIC(在错误消息中),或WARNINGNOTICEDEBUGINFOLOG(在通知消息中)。 这与S字段相同,只是内容不会被本地化。仅在由PostgreSQL版本9.6 @@ -5625,7 +5596,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 消息: 主要的人类可读错误消息。 + 消息: 主要的人类可读错误消息。 这应该准确但简洁(通常一行)。 总是存在。 @@ -5647,7 +5618,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 提示: 关于问题应该怎么做的一个可选建议。 + 提示: 关于问题应该怎么做的一个可选建议。 这意在与细节不同,它提供建议(可能不合适)而不是硬性事实。 可能会跨越多行。 @@ -5681,7 +5652,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 内部查询: 一个失败的内部生成命令的文本。 + 内部查询: 一个失败的内部生成命令的文本。 例如,这可能是由PL/pgSQL函数发出的SQL查询。 @@ -5714,7 +5685,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 表名: 如果错误与特定表相关联,则为表的名称。(有关表模式名称的名称,请参考模式名称字段。) + 表名: 如果错误与特定表相关联,则为表的名称。(有关表模式名称的名称,请参考模式名称字段。) @@ -5724,7 +5695,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 列名: 如果错误与特定表列相关联,则为列的名称。(请参考模式和表名字段以识别表。) + 列名: 如果错误与特定表列相关联,则为列的名称。(请参考模式和表名字段以识别表。) @@ -5734,7 +5705,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 数据类型名称: 如果错误与特定数据类型相关联,则为数据类型的名称。 + 数据类型名称: 如果错误与特定数据类型相关联,则为数据类型的名称。 (有关数据类型模式的名称,请参阅模式名称字段。) @@ -5745,7 +5716,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 约束名称: 如果错误与特定约束相关联,则为约束的名称。请参考上面列出的字段,了解相关表或域。 + 约束名称: 如果错误与特定约束相关联,则为约束的名称。请参考上面列出的字段,了解相关表或域。 (为此,即使索引不是使用约束语法创建的,也将其视为约束。) @@ -5756,7 +5727,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 文件: 报告错误的源代码位置的文件名。 + 文件: 报告错误的源代码位置的文件名。 @@ -5894,7 +5865,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 标志; 逻辑解码消息是非事务性的时为0,是事务性的时为1。 + 标志; 逻辑解码消息是非事务性的时为0,是事务性的时为1。 @@ -5968,7 +5939,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 标志; 目前未使用。 + 标志; 目前未使用。 @@ -6666,7 +6637,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 标志; 目前未使用。 + 标志; 目前未使用。 @@ -6744,6 +6715,27 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" + + Int64 (XLogRecPtr) + + + 中止操作的 LSN,仅当 streaming 设置为 parallel 时出现。 + 此字段从协议版本 4 起可用。 + + + + + + Int64 (TimestampTz) + + + 事务的中止时间戳,仅当 streaming 设置为 parallel 时出现。 + 该值为自 PostgreSQL 纪元(2000-01-01)以来的微秒数。 + 此字段从协议版本 4 起可用。 + + + + @@ -6850,7 +6842,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 标志; 目前未使用。 + 标志; 目前未使用。 @@ -6935,7 +6927,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 标志; 目前未使用。 + 标志; 目前未使用。 @@ -7020,7 +7012,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 标志; 目前未使用。 + 标志; 目前未使用。 @@ -7116,7 +7108,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 标志; 目前未使用。 + 标志; 目前未使用。 @@ -7276,76 +7268,36 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 自协议2.0以来的变化总结 + 自协议 2.0 以来的变更总结 - 本节为那些试图将现有客户端库更新到协议3.0的开发人员提供了一个快速变更清单。 + 本节提供一份简要的变更清单,供准备将现有客户端库更新到协议 3.0 的开发者参考。 - - 初始启动数据包使用灵活的字符串列表格式,而不是固定格式。请注意,现在可以直接在启动数据包中指定运行时参数的会话默认值。 - (实际上,以前可以使用options字段来做到这一点,但考虑到options的有限宽度以及缺乏引用值中空格的任何方法,这并不是一种非常安全的技术。) - + 初始启动包采用灵活的字符串列表格式,取代了固定格式。注意,运行时参数的会话默认值现在可以直接在启动包中指定。(实际上,以前也能通过 options 字段实现,但由于 options 的宽度有限,且无法用引号保护值中的空白字符,这种方法并不稳妥。) - - 所有消息现在都在消息类型字节后面立即跟着长度计数(除了启动数据包,它们没有类型字节)。另外请注意,PasswordMessage现在有一个类型字节。 - + 现在,所有消息都在消息类型字节之后紧跟一个长度计数(启动包除外,它没有类型字节)。另请注意,PasswordMessage 现在也有类型字节。 - - ErrorResponse和NoticeResponse('E'和'N') - 消息现在包含多个字段,客户端代码可以从中组装出所需级别的错误消息。请注意, - 单个字段通常不会以换行符结尾,而在旧协议中发送的单个字符串总是以换行符结尾。 - + ErrorResponse 和 NoticeResponse('E' 和 'N')消息现在包含多个字段,客户端代码可以利用这些字段组合出所需详细程度的错误消息。注意,各字段通常不会以换行符结束,而旧协议发送的单个字符串总是以换行符结束。 - - ReadyForQuery('Z')消息包括事务状态指示器。 - + ReadyForQuery('Z')消息包含一个事务状态指示器。 - - 二进制行和数据行消息类型之间的区别已经消失;单个数据行消息类型用于以所有格式返回数据。 - 请注意,DataRow的布局已更改,以使其更容易解析。 - 此外,二进制值的表示已更改:它不再直接与服务器的内部表示形式绑定。 - + BinaryRow 与 DataRow 消息类型不再有区别;单一的 DataRow 消息类型用于返回所有格式的数据。注意,DataRow 的布局已经改变,使其更容易解析。另外,二进制值的表示方式也已改变,不再直接取决于服务器内部的表示方式。 - - 有一个新的扩展查询子协议,它增加了前端消息类型Parse、Bind、Execute、Describe、Close、Flush和Sync, - 以及后端消息类型ParseComplete、BindComplete、PortalSuspended、ParameterDescription、NoData和CloseComplete。 - 现有客户端不必关心这个子协议,但利用它可能会提高性能或功能。 - + 新增了扩展查询子协议,其中增加了前端消息类型 Parse、Bind、Execute、Describe、Close、Flush 和 Sync,以及后端消息类型 ParseComplete、BindComplete、PortalSuspended、ParameterDescription、NoData 和 CloseComplete。现有客户端不必关注这个子协议,但使用它可能有助于改善性能或功能。 - - COPY数据现在封装到CopyData和CopyDone消息中。在COPY期间有一种明确定义的错误恢复方式。 - 特殊的\.最后一行不再需要,并且在COPY OUT期间不发送。 - (在文本模式的COPY IN期间仍然被识别为终止符,但在CSV模式中不会被识别。文本模式中的这种行为已弃用,并且最终可能会被移除。)支持二进制COPY。 - CopyInResponse和CopyOutResponse消息包括指示列数和每列格式的字段。 - + COPY 数据现在封装在 CopyData 和 CopyDone 消息中。COPY 期间的错误恢复已有明确定义的方法。不再需要特殊的最后一行 \.COPY OUT 期间也不再发送它。(在文本模式的 COPY IN 期间仍会将它识别为终止符,但在 CSV 模式中不会。文本模式的这种行为已弃用,将来可能会被移除。)现已支持二进制 COPY。CopyInResponse 和 CopyOutResponse 消息包含了表示列数及各列格式的字段。 - - FunctionCall和FunctionCallResponse消息的布局已更改。 - FunctionCall现在可以支持将NULL参数传递给函数。它还可以处理以文本或二进制格式传递参数和检索结果。 - 不再需要考虑FunctionCall可能存在安全漏洞,因为它不提供对内部服务器数据表示的直接访问。 - + FunctionCall 和 FunctionCallResponse 消息的布局已经改变。FunctionCall 现在支持向函数传递 NULL 参数,也可以使用文本或二进制格式传递参数和取得结果。由于它不再提供对服务器内部数据表示的直接访问,因此也不再有理由将 FunctionCall 视为潜在的安全漏洞。 - - 后端在连接启动期间向客户端库发送ParameterStatus('S')消息,以传达其认为对客户端库有趣的所有参数。 - 随后,每当这些参数中任何一个的活动值发生变化时,都会发送ParameterStatus消息。 - + 在连接启动期间,后端会为其认为客户端库关注的所有参数发送 ParameterStatus('S')消息。之后,只要这些参数中任何一个的当前值发生变化,就会发送一条 ParameterStatus 消息。 - - RowDescription('T')消息携带了描述行的每列的新表OID和列号字段。它还显示了每列的格式代码。 - + RowDescription('T')消息针对所描述行中的每一列,增加了表 OID 和列编号字段,并显示各列的格式代码。 - - CursorResponse('P')消息不再由后端生成。 - + 后端不再生成 CursorResponse('P')消息。 - - NotificationResponse('A')消息有一个额外的字符串字段,可以携带一个有效负载字符串, - 从NOTIFY事件发送者传递过来。 - + NotificationResponse('A')消息增加了一个字符串字段,可以携带 NOTIFY 事件发送者传来的载荷字符串。 - - EmptyQueryResponse('I')消息曾包含一个空字符串参数;现已移除。 - + EmptyQueryResponse('I')消息以前包含一个空字符串参数,现在已将其移除。 diff --git a/zh/18/queries.sgml b/zh/18/queries.sgml index 49ad3b90..7a419d4c 100644 --- a/zh/18/queries.sgml +++ b/zh/18/queries.sgml @@ -512,7 +512,7 @@ FROM (VALUES ('anne', 'smith'), ('bob', 'jones'), ('joe', 'blow')) - 表函数是那些生成行集合的函数,这些行可以由基本数据类型(标量类型)组成,也可以由复合数据类型(表行)组成。它们在查询的FROM子句中用法类似于表、视图或子查询。表函数返回的列可以像表、视图或子查询的列一样,出现在SELECTJOINWHERE子句中。 + 表函数是那些生成行集合的函数,这些行可以由基础类型(标量类型)组成,也可以由复合数据类型(表行)组成。它们在查询的FROM子句中用法类似于表、视图或子查询。表函数返回的列可以像表、视图或子查询的列一样,出现在SELECTJOINWHERE子句中。 @@ -550,7 +550,7 @@ UNNEST( array_expression , ... - 如果没有提供列的别名,那么对于一个返回基数据类型的函数,列名也与该函数 + 如果没有提供列的别名,那么对于一个返回基础类型的函数,列名也与该函数 名相同。对于一个返回复合类型的函数,结果列会从该类型的属性得到名称。 diff --git a/zh/18/rangetypes.sgml b/zh/18/rangetypes.sgml index f60e0af7..68409fa3 100644 --- a/zh/18/rangetypes.sgml +++ b/zh/18/rangetypes.sgml @@ -209,7 +209,7 @@ SELECT '{[3,7), [8,9)}'::int4multirange; 构造范围和多范围 - 每种范围类型都有一个与范围类型同名的构造函数。使用构造函数通常比书写范围文字常量更方便,因为这样无需对界限值进行额外引用。构造函数接受两个或三个参数。两个参数的形式构造标准形式的范围(下界包含,上界排除),而三个参数的形式则按第三个参数指定的界限形式构造范围。第三个参数必须是下列字符串之一: + 每种范围类型都有一个与范围类型同名的构造函数。使用构造函数通常比书写范围字面量更方便,因为这样无需为界限值额外加引号。构造函数接受两个或三个参数。两个参数的形式构造标准形式的范围(下界包含,上界排除),而三个参数的形式则按第三个参数指定的界限形式构造范围。第三个参数必须是下列字符串之一: ()(][)或者 diff --git a/zh/18/ref/abort.sgml b/zh/18/ref/abort.sgml index 95835c70..caed1f42 100644 --- a/zh/18/ref/abort.sgml +++ b/zh/18/ref/abort.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ABORT 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/alter_aggregate.sgml b/zh/18/ref/alter_aggregate.sgml index 6e6d9e05..ce4e87f4 100644 --- a/zh/18/ref/alter_aggregate.sgml +++ b/zh/18/ref/alter_aggregate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER AGGREGATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/alter_collation.sgml b/zh/18/ref/alter_collation.sgml index 85fd5517..c8273dd3 100644 --- a/zh/18/ref/alter_collation.sgml +++ b/zh/18/ref/alter_collation.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER COLLATION 7 - SQL - Language Statements + SQL - 语言语句 @@ -102,7 +102,7 @@ ALTER COLLATION name SET SCHEMA new_sche 注解 - 创建排序规则对象时,该排序规则的提供者特定版本会记录在系统目录中。 + 创建排序规则对象时,会在系统目录中记录由提供程序确定的排序规则版本。 使用该排序规则时,会将当前版本与记录的版本进行比较;如果二者不匹 配,就会发出警告,例如: diff --git a/zh/18/ref/alter_conversion.sgml b/zh/18/ref/alter_conversion.sgml index d6c8e82c..613b3ec3 100644 --- a/zh/18/ref/alter_conversion.sgml +++ b/zh/18/ref/alter_conversion.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER CONVERSION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/alter_database.sgml b/zh/18/ref/alter_database.sgml index 41dcd0fe..3cd8b071 100644 --- a/zh/18/ref/alter_database.sgml +++ b/zh/18/ref/alter_database.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER DATABASE 7 - SQL - Language Statements + SQL - 语言语句 @@ -90,9 +90,7 @@ ALTER DATABASE name RESET ALL allowconn - - 如果为假,则没有人能连接到这个数据库。 - + 如果为 false,则任何人都不能连接到该数据库。 @@ -109,7 +107,7 @@ ALTER DATABASE name RESET ALL istemplate - 如果为真,则任何具有CREATEDB权限的用户都可以从这个数据库克隆。如果为假,则只有超级用户或者该数据库的拥有者可以克隆它。 + 如果为 true,则任何具有 CREATEDB 权限的用户都可以克隆该数据库;如果为 false,则只有超级用户或该数据库的拥有者可以克隆它。 diff --git a/zh/18/ref/alter_default_privileges.sgml b/zh/18/ref/alter_default_privileges.sgml index 2fca3f17..87446d98 100644 --- a/zh/18/ref/alter_default_privileges.sgml +++ b/zh/18/ref/alter_default_privileges.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER DEFAULT PRIVILEGES 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/alter_domain.sgml b/zh/18/ref/alter_domain.sgml index a0fe964c..95aaee6c 100644 --- a/zh/18/ref/alter_domain.sgml +++ b/zh/18/ref/alter_domain.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER DOMAIN 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/alter_event_trigger.sgml b/zh/18/ref/alter_event_trigger.sgml index 326f30e1..b9407346 100644 --- a/zh/18/ref/alter_event_trigger.sgml +++ b/zh/18/ref/alter_event_trigger.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER EVENT TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -58,7 +58,7 @@ ALTER EVENT TRIGGER name RENAME TO new_owner - 该事件触发器的新拥有者的用户名。 + 该事件触发器的新所有者的用户名。 @@ -94,7 +94,7 @@ ALTER EVENT TRIGGER name RENAME TO - 另见 + 参见 diff --git a/zh/18/ref/alter_extension.sgml b/zh/18/ref/alter_extension.sgml index 9471390f..3ceae003 100644 --- a/zh/18/ref/alter_extension.sgml +++ b/zh/18/ref/alter_extension.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER EXTENSION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/alter_foreign_data_wrapper.sgml b/zh/18/ref/alter_foreign_data_wrapper.sgml index 06bdb8be..52dbfc7e 100644 --- a/zh/18/ref/alter_foreign_data_wrapper.sgml +++ b/zh/18/ref/alter_foreign_data_wrapper.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER FOREIGN DATA WRAPPER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/alter_foreign_table.sgml b/zh/18/ref/alter_foreign_table.sgml index 14958ed9..287ffa90 100644 --- a/zh/18/ref/alter_foreign_table.sgml +++ b/zh/18/ref/alter_foreign_table.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER FOREIGN TABLE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/alter_function.sgml b/zh/18/ref/alter_function.sgml index 5de95078..5c9bc999 100644 --- a/zh/18/ref/alter_function.sgml +++ b/zh/18/ref/alter_function.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation ALTER FUNCTION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/alter_group.sgml b/zh/18/ref/alter_group.sgml index 6f8814dc..cf493632 100644 --- a/zh/18/ref/alter_group.sgml +++ b/zh/18/ref/alter_group.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER GROUP 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/alter_index.sgml b/zh/18/ref/alter_index.sgml index 06134114..978d61e1 100644 --- a/zh/18/ref/alter_index.sgml +++ b/zh/18/ref/alter_index.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER INDEX 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/alter_language.sgml b/zh/18/ref/alter_language.sgml index 7af98f20..000fe499 100644 --- a/zh/18/ref/alter_language.sgml +++ b/zh/18/ref/alter_language.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER LANGUAGE 7 - SQL - Language Statements + SQL - 语言语句 @@ -31,8 +31,8 @@ ALTER [ PROCEDURAL ] LANGUAGE name OWNER TO { ALTER LANGUAGE更改一种过程语言的定义。 - 目前唯一的功能是重命名该语言或为其指定新的拥有者。 - 要使用ALTER LANGUAGE,你必须是超级用户或者该语言的拥有者。 + 目前唯一的功能是重命名该语言或为其指定新的所有者。 + 要使用ALTER LANGUAGE,你必须是超级用户或者该语言的所有者。 @@ -62,7 +62,7 @@ ALTER [ PROCEDURAL ] LANGUAGE name OWNER TO { new_owner - 该语言的新拥有者 + 该语言的新所有者 diff --git a/zh/18/ref/alter_large_object.sgml b/zh/18/ref/alter_large_object.sgml index ad3f61f7..be30f848 100644 --- a/zh/18/ref/alter_large_object.sgml +++ b/zh/18/ref/alter_large_object.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER LARGE OBJECT 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/alter_materialized_view.sgml b/zh/18/ref/alter_materialized_view.sgml index 71ac3ade..2ef84a4c 100644 --- a/zh/18/ref/alter_materialized_view.sgml +++ b/zh/18/ref/alter_materialized_view.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER MATERIALIZED VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/alter_opclass.sgml b/zh/18/ref/alter_opclass.sgml index b1872b37..a2228963 100644 --- a/zh/18/ref/alter_opclass.sgml +++ b/zh/18/ref/alter_opclass.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER OPERATOR CLASS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/alter_operator.sgml b/zh/18/ref/alter_operator.sgml index 9537f8e9..0e908cac 100644 --- a/zh/18/ref/alter_operator.sgml +++ b/zh/18/ref/alter_operator.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER OPERATOR 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/alter_opfamily.sgml b/zh/18/ref/alter_opfamily.sgml index a0b755c2..de22efe2 100644 --- a/zh/18/ref/alter_opfamily.sgml +++ b/zh/18/ref/alter_opfamily.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER OPERATOR FAMILY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/alter_policy.sgml b/zh/18/ref/alter_policy.sgml index 30e5b6e0..e8f525cf 100644 --- a/zh/18/ref/alter_policy.sgml +++ b/zh/18/ref/alter_policy.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER POLICY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/alter_procedure.sgml b/zh/18/ref/alter_procedure.sgml index 22e333e4..2a38515b 100644 --- a/zh/18/ref/alter_procedure.sgml +++ b/zh/18/ref/alter_procedure.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER PROCEDURE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/alter_publication.sgml b/zh/18/ref/alter_publication.sgml index 12bfeb8e..8baeb298 100644 --- a/zh/18/ref/alter_publication.sgml +++ b/zh/18/ref/alter_publication.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER PUBLICATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/alter_role.sgml b/zh/18/ref/alter_role.sgml index 6c719424..0f2402d9 100644 --- a/zh/18/ref/alter_role.sgml +++ b/zh/18/ref/alter_role.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation ALTER ROLE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/alter_routine.sgml b/zh/18/ref/alter_routine.sgml index 4fc3e18d..79191e1e 100644 --- a/zh/18/ref/alter_routine.sgml +++ b/zh/18/ref/alter_routine.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER ROUTINE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/alter_rule.sgml b/zh/18/ref/alter_rule.sgml index 9449d787..9397274c 100644 --- a/zh/18/ref/alter_rule.sgml +++ b/zh/18/ref/alter_rule.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER RULE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/alter_schema.sgml b/zh/18/ref/alter_schema.sgml index 2baf518d..13df793e 100644 --- a/zh/18/ref/alter_schema.sgml +++ b/zh/18/ref/alter_schema.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER SCHEMA 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/alter_sequence.sgml b/zh/18/ref/alter_sequence.sgml index 05ba4edf..a1f6887d 100644 --- a/zh/18/ref/alter_sequence.sgml +++ b/zh/18/ref/alter_sequence.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER SEQUENCE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/alter_server.sgml b/zh/18/ref/alter_server.sgml index 5d870833..b3481a8a 100644 --- a/zh/18/ref/alter_server.sgml +++ b/zh/18/ref/alter_server.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER SERVER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/alter_statistics.sgml b/zh/18/ref/alter_statistics.sgml index 315ff6b7..561ca100 100644 --- a/zh/18/ref/alter_statistics.sgml +++ b/zh/18/ref/alter_statistics.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER STATISTICS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/alter_subscription.sgml b/zh/18/ref/alter_subscription.sgml index ae25db69..87daeccb 100644 --- a/zh/18/ref/alter_subscription.sgml +++ b/zh/18/ref/alter_subscription.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER SUBSCRIPTION 7 - SQL - Language Statements + SQL - 语言语句 @@ -269,9 +269,7 @@ ALTER SUBSCRIPTION name RENAME TO < 跳过应用远端事务的所有更改。如果传入数据违反任何约束,逻辑复制会停止,直到问题解决。 通过使用ALTER SUBSCRIPTION ... SKIP命令,逻辑复制工作进程会跳过 - 该事务中的所有数据修改操作。若订阅者上启用了 - two_phase, - 则此选项对因在订阅者上启用该参数而已经预备的事务没有作用。逻辑复制工作进程成功跳过该事务或完成一个事务后, + 该事务中的所有数据修改操作。此选项对因在订阅者上启用 two_phase 而已经预备的事务没有作用。逻辑复制工作进程成功跳过该事务或完成一个事务后, LSN(存储在pg_subscription.subskiplsn中) 会被清除。有关逻辑复制冲突的详细信息,请参见 。 diff --git a/zh/18/ref/alter_system.sgml b/zh/18/ref/alter_system.sgml index 22c645e6..1c9249b1 100644 --- a/zh/18/ref/alter_system.sgml +++ b/zh/18/ref/alter_system.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER SYSTEM 7 - SQL - Language Statements + SQL - 语言语句 @@ -85,8 +85,7 @@ ALTER SYSTEM RESET ALL - 对于某些接受列表的参数,带引号的值会生成带双引号的输出,以保留空 - 格和逗号;对于另一些参数,则必须在单引号字符串内部使用双引号才能 + 对于某些接受列表的参数,带引号的值会生成带双引号的输出,以保留空白和逗号;对于另一些参数,则必须在单引号字符串内部使用双引号才能 达到这种效果。 diff --git a/zh/18/ref/alter_table.sgml b/zh/18/ref/alter_table.sgml index 4798657b..2df03e17 100644 --- a/zh/18/ref/alter_table.sgml +++ b/zh/18/ref/alter_table.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TABLE 7 - SQL - Language Statements + SQL - 语言语句 @@ -1011,7 +1011,7 @@ WITH ( MODULUS numeric_literal, REM - 若要强制立即回收已删除列所占的空间,可以执行任何一种会导致整表重写的ALTER TABLE形式。这样会重新构造每一行,并用空值替换被删除的列。 + 若要强制立即回收已删除列所占的空间,可以执行任何一种会导致整表重写的ALTER TABLE形式。这样会重建每一行,并用空值替换被删除的列。 diff --git a/zh/18/ref/alter_tablespace.sgml b/zh/18/ref/alter_tablespace.sgml index f0297481..7369ec94 100644 --- a/zh/18/ref/alter_tablespace.sgml +++ b/zh/18/ref/alter_tablespace.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TABLESPACE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/alter_trigger.sgml b/zh/18/ref/alter_trigger.sgml index 9fc49c8b..874811aa 100644 --- a/zh/18/ref/alter_trigger.sgml +++ b/zh/18/ref/alter_trigger.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -127,7 +127,7 @@ ALTER TRIGGER emp_stamp ON emp DEPENDS ON EXTENSION emplib; - 另见 + 参见 diff --git a/zh/18/ref/alter_tsconfig.sgml b/zh/18/ref/alter_tsconfig.sgml index 7ae05dd5..891dce66 100644 --- a/zh/18/ref/alter_tsconfig.sgml +++ b/zh/18/ref/alter_tsconfig.sgml @@ -13,7 +13,7 @@ PostgreSQL documentation ALTER TEXT SEARCH CONFIGURATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/alter_tsdictionary.sgml b/zh/18/ref/alter_tsdictionary.sgml index 9679697e..163d788b 100644 --- a/zh/18/ref/alter_tsdictionary.sgml +++ b/zh/18/ref/alter_tsdictionary.sgml @@ -13,7 +13,7 @@ PostgreSQL documentation ALTER TEXT SEARCH DICTIONARY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/alter_tsparser.sgml b/zh/18/ref/alter_tsparser.sgml index 525064c9..0844cb0a 100644 --- a/zh/18/ref/alter_tsparser.sgml +++ b/zh/18/ref/alter_tsparser.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TEXT SEARCH PARSER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/alter_tstemplate.sgml b/zh/18/ref/alter_tstemplate.sgml index fa4157f9..a3eec599 100644 --- a/zh/18/ref/alter_tstemplate.sgml +++ b/zh/18/ref/alter_tstemplate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TEXT SEARCH TEMPLATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/alter_type.sgml b/zh/18/ref/alter_type.sgml index 58063799..6c1bc805 100644 --- a/zh/18/ref/alter_type.sgml +++ b/zh/18/ref/alter_type.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation ALTER TYPE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/alter_user.sgml b/zh/18/ref/alter_user.sgml index 362b5518..5a4f5dd4 100644 --- a/zh/18/ref/alter_user.sgml +++ b/zh/18/ref/alter_user.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER USER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/alter_user_mapping.sgml b/zh/18/ref/alter_user_mapping.sgml index 6bbeffc6..b1fc6606 100644 --- a/zh/18/ref/alter_user_mapping.sgml +++ b/zh/18/ref/alter_user_mapping.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER USER MAPPING 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/alter_view.sgml b/zh/18/ref/alter_view.sgml index 020f864b..63fcb79e 100644 --- a/zh/18/ref/alter_view.sgml +++ b/zh/18/ref/alter_view.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/analyze.sgml b/zh/18/ref/analyze.sgml index 1717fc7f..8a934dce 100644 --- a/zh/18/ref/analyze.sgml +++ b/zh/18/ref/analyze.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ANALYZE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/begin.sgml b/zh/18/ref/begin.sgml index 2343e66c..fc8fb312 100644 --- a/zh/18/ref/begin.sgml +++ b/zh/18/ref/begin.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation BEGIN 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/call.sgml b/zh/18/ref/call.sgml index 4a12245b..7dca6405 100644 --- a/zh/18/ref/call.sgml +++ b/zh/18/ref/call.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CALL 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/checkpoint.sgml b/zh/18/ref/checkpoint.sgml index 3cda7713..708982bf 100644 --- a/zh/18/ref/checkpoint.sgml +++ b/zh/18/ref/checkpoint.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CHECKPOINT 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/close.sgml b/zh/18/ref/close.sgml index 53c793c4..788e2c9a 100644 --- a/zh/18/ref/close.sgml +++ b/zh/18/ref/close.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation CLOSE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/cluster.sgml b/zh/18/ref/cluster.sgml index f22017f1..fb0c44b0 100644 --- a/zh/18/ref/cluster.sgml +++ b/zh/18/ref/cluster.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CLUSTER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/clusterdb.sgml b/zh/18/ref/clusterdb.sgml index fd83c9ba..ada12058 100644 --- a/zh/18/ref/clusterdb.sgml +++ b/zh/18/ref/clusterdb.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation clusterdb 1 - Application + 应用程序 diff --git a/zh/18/ref/comment.sgml b/zh/18/ref/comment.sgml index baa2f239..5148556c 100644 --- a/zh/18/ref/comment.sgml +++ b/zh/18/ref/comment.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation COMMENT 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/commit.sgml b/zh/18/ref/commit.sgml index 046c6d84..596d1550 100644 --- a/zh/18/ref/commit.sgml +++ b/zh/18/ref/commit.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation COMMIT 7 - SQL - Language Statements + SQL - 语言语句 @@ -39,7 +39,7 @@ COMMIT [ WORK | TRANSACTION ] [ AND [ NO ] CHAIN ] 参数 - chained transactions + 链式事务 diff --git a/zh/18/ref/commit_prepared.sgml b/zh/18/ref/commit_prepared.sgml index dcdba873..734b2833 100644 --- a/zh/18/ref/commit_prepared.sgml +++ b/zh/18/ref/commit_prepared.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation COMMIT PREPARED 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/copy.sgml b/zh/18/ref/copy.sgml index aef76bdf..eb1e883c 100644 --- a/zh/18/ref/copy.sgml +++ b/zh/18/ref/copy.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation COPY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/create_access_method.sgml b/zh/18/ref/create_access_method.sgml index d4cb6d2c..7f2d9d8e 100644 --- a/zh/18/ref/create_access_method.sgml +++ b/zh/18/ref/create_access_method.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE ACCESS METHOD 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/create_aggregate.sgml b/zh/18/ref/create_aggregate.sgml index 3b890824..252f9fab 100644 --- a/zh/18/ref/create_aggregate.sgml +++ b/zh/18/ref/create_aggregate.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation CREATE AGGREGATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/create_cast.sgml b/zh/18/ref/create_cast.sgml index 1e2c9275..94e78f9e 100644 --- a/zh/18/ref/create_cast.sgml +++ b/zh/18/ref/create_cast.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation CREATE CAST 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/create_collation.sgml b/zh/18/ref/create_collation.sgml index 6bb3f7ab..4177c026 100644 --- a/zh/18/ref/create_collation.sgml +++ b/zh/18/ref/create_collation.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE COLLATION 7 - SQL - Language Statements + SQL - 语言语句 @@ -130,7 +130,7 @@ CREATE COLLATION [ IF NOT EXISTS ] name FROM - 指定与该排序规则关联的区域设置服务所使用的提供者。可能的值是 + 指定与该排序规则关联的区域设置服务所使用的提供程序。可能的值是 builtinicuICU (如果服务器在构建时启用了 ICU 支持)或libc。 @@ -154,7 +154,7 @@ CREATE COLLATION [ IF NOT EXISTS ] name FROM - 非确定性排序规则仅受 ICU 提供者支持。 + 非确定性排序规则仅受 ICU 提供程序支持。 @@ -238,14 +238,14 @@ CREATE COLLATION french (locale = 'fr_FR.utf8'); - 使用 ICU 提供者并采用德语电话簿排序顺序创建一种排序规则: + 使用 ICU 提供程序并采用德语电话簿排序顺序创建一种排序规则: CREATE COLLATION german_phonebook (provider = icu, locale = 'de-u-co-phonebk'); - 使用 ICU 提供者、基于 ICU 根区域设置并带有自定义规则创建一种排序规 + 使用 ICU 提供程序、基于 ICU 根区域设置并带有自定义规则创建一种排序规 则: diff --git a/zh/18/ref/create_conversion.sgml b/zh/18/ref/create_conversion.sgml index da83218a..3fcb4447 100644 --- a/zh/18/ref/create_conversion.sgml +++ b/zh/18/ref/create_conversion.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE CONVERSION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/create_database.sgml b/zh/18/ref/create_database.sgml index 0aaa9268..f03ba746 100644 --- a/zh/18/ref/create_database.sgml +++ b/zh/18/ref/create_database.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE DATABASE 7 - SQL - Language Statements + SQL - 语言语句 @@ -359,7 +359,7 @@ CREATE DATABASE nameLC_CTYPE)兼容。如果区域设置为 C (或等价的 POSIX),则允许所有编码;但对于其他区域设置,只有一种编码能够正常工作。(不过,在 Windows 上,UTF-8 编码可与任何区域设置一起使用。) CREATE DATABASE 允许超级用户不考虑区域设置而指定 - SQL_ASCII 编码,但这种选择已被废弃;如果数据库中存储了与该区域设置不兼容编码的数据,字符串函数的行为可能会出错。 + SQL_ASCII 编码,但这种选择已弃用;如果数据库中存储了与该区域设置不兼容编码的数据,字符串函数的行为可能会出错。 @@ -409,7 +409,7 @@ CREATE DATABASE music TEMPLATE template0; 在这个示例中,如果指定的区域设置与 template1 中的不同, - 则必须使用 TEMPLATE template0 子句。(如果并不不同, + 则必须使用 TEMPLATE template0 子句。(如果相同, 那么显式指定区域设置就是多余的。) diff --git a/zh/18/ref/create_domain.sgml b/zh/18/ref/create_domain.sgml index 905dd30d..420bbf83 100644 --- a/zh/18/ref/create_domain.sgml +++ b/zh/18/ref/create_domain.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE DOMAIN 7 - SQL - Language Statements + SQL - 语言语句 @@ -86,7 +86,7 @@ CREATE DOMAIN name [ AS ] 该域的可选排序规则。如果未指定排序规则,则该域的排序规则行为与其 底层数据类型相同。如果指定了COLLATE,则底层 - 类型必须是一种可排序数据类型。 + 类型必须是一种支持排序规则的数据类型。 diff --git a/zh/18/ref/create_event_trigger.sgml b/zh/18/ref/create_event_trigger.sgml index 0d45c2be..32448118 100644 --- a/zh/18/ref/create_event_trigger.sgml +++ b/zh/18/ref/create_event_trigger.sgml @@ -13,7 +13,7 @@ PostgreSQL documentation CREATE EVENT TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -44,7 +44,7 @@ CREATE EVENT TRIGGER name CREATE EVENT TRIGGER创建一个新的事件触发器。 每当指定的事件发生,并且与该触发器关联的WHEN条件(如果有)得到 满足时,就会执行该触发器函数。有关事件触发器的一般性介绍,见 - 。创建事件触发器的用户将成为其拥有者。 + 。创建事件触发器的用户将成为其所有者。 @@ -83,8 +83,7 @@ CREATE EVENT TRIGGER name - 用于过滤事件的变量名称。这使得可以将触发器限定为只在支持该变量的部 - 分情形下触发。当前唯一支持的 + 用于过滤事件的变量名称。这样可以将触发器限定为只在原本支持的部分情形下触发。当前唯一支持的 filter_variableTAG @@ -194,7 +193,7 @@ CREATE EVENT TRIGGER abort_ddl ON ddl_command_start - 另见 + 参见 diff --git a/zh/18/ref/create_extension.sgml b/zh/18/ref/create_extension.sgml index 1503df25..b503bb90 100644 --- a/zh/18/ref/create_extension.sgml +++ b/zh/18/ref/create_extension.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE EXTENSION 7 - SQL - Language Statements + SQL - 语言语句 @@ -167,7 +167,7 @@ CREATE EXTENSION [ IF NOT EXISTS ] extension_name 会在之后执行编写粗心的扩展脚本时实施攻击,使该用户获得超级用户权限。 不过,只有当特洛伊木马对象在脚本执行期间位于 search_path 中时,它们才会构成危险;这意味着它们 - 位于扩展的安装目标模式中,或位于它所依赖的某个扩展所属的模式中。 + 位于扩展的安装目标模式中,或位于它所依赖的某个扩展的目标模式中。 因此,处理那些脚本尚未经过仔细审查的扩展时,一个经验法则是: 只把它们安装到从未向任何不受信任用户授予、而且今后也不会授予 CREATE 权限的模式中。它们所依赖的任何扩展也应如此。 diff --git a/zh/18/ref/create_foreign_data_wrapper.sgml b/zh/18/ref/create_foreign_data_wrapper.sgml index bfa097ef..0611709d 100644 --- a/zh/18/ref/create_foreign_data_wrapper.sgml +++ b/zh/18/ref/create_foreign_data_wrapper.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE FOREIGN DATA WRAPPER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/create_foreign_table.sgml b/zh/18/ref/create_foreign_table.sgml index ad1f4348..6f932eff 100644 --- a/zh/18/ref/create_foreign_table.sgml +++ b/zh/18/ref/create_foreign_table.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE FOREIGN TABLE 7 - SQL - Language Statements + SQL - 语言语句 @@ -143,9 +143,7 @@ WITH ( MODULUS numeric_literal, REM COLLATE collation - - COLLATE子句为该列(必须是一种可排序数据类型)指定一个排序规则。如果未指定,则使用该列数据类型的默认排序规则。 - + COLLATE子句为列指定排序规则(该列必须属于支持排序规则的数据类型)。如果未指定,则使用列数据类型的默认排序规则。 diff --git a/zh/18/ref/create_function.sgml b/zh/18/ref/create_function.sgml index b6447707..5b894c32 100644 --- a/zh/18/ref/create_function.sgml +++ b/zh/18/ref/create_function.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation CREATE FUNCTION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/create_group.sgml b/zh/18/ref/create_group.sgml index 06195a91..9a6538ed 100644 --- a/zh/18/ref/create_group.sgml +++ b/zh/18/ref/create_group.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE GROUP 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/create_index.sgml b/zh/18/ref/create_index.sgml index 1c525288..3db5aa58 100644 --- a/zh/18/ref/create_index.sgml +++ b/zh/18/ref/create_index.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation CREATE INDEX 7 - SQL - Language Statements + SQL - 语言语句 @@ -57,7 +57,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] PostgreSQL提供了索引方法 - B-树、哈希、GiST、SP-GiST、GIN 以及 BRIN。用户也可以定义自己的索引 + B-树、hash、GiST、SP-GiST、GIN 以及 BRIN。用户也可以定义自己的索引 方法,但这相当复杂。 @@ -123,7 +123,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] 对于临时表,CREATE INDEX始终是非并发的, - 因为没有其他会话可以访问它们,而且非并发创建索引的成本更低。 + 因为没有其他会话可以访问它们,而且非并发创建索引的代价更低。 @@ -376,7 +376,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - B-树、哈希、GiST 和 SP-GiST 索引方法都接受以下参数: + B-树、hash、GiST 和 SP-GiST 索引方法都接受以下参数: @@ -566,7 +566,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - 定义当在下一页范围检测到插入时,是否为前一页范围排队执行一次提要操作 + 定义当在下一页范围检测到插入时,是否为前一页范围排队执行一次范围摘要操作 (详见)。 默认值为off @@ -580,8 +580,8 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] 并发构建索引 - index - building concurrently + 索引 + 并发构建 diff --git a/zh/18/ref/create_language.sgml b/zh/18/ref/create_language.sgml index fca9e159..5d737764 100644 --- a/zh/18/ref/create_language.sgml +++ b/zh/18/ref/create_language.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE LANGUAGE 7 - SQL - Language Statements + SQL - 语言语句 @@ -96,7 +96,7 @@ CREATE [ OR REPLACE ] [ TRUSTED ] [ PROCEDURAL ] LANGUAGE 。 - + 对 MD5 加密密码的支持已弃用,并将在PostgreSQL的未来版本中移除。迁移到其他密码类型的详细信息见 diff --git a/zh/18/ref/create_rule.sgml b/zh/18/ref/create_rule.sgml index 6d1486c9..e8b37c6d 100644 --- a/zh/18/ref/create_rule.sgml +++ b/zh/18/ref/create_rule.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE RULE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/create_schema.sgml b/zh/18/ref/create_schema.sgml index 74944401..92074e50 100644 --- a/zh/18/ref/create_schema.sgml +++ b/zh/18/ref/create_schema.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE SCHEMA 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/create_sequence.sgml b/zh/18/ref/create_sequence.sgml index ffbf9797..c786a61f 100644 --- a/zh/18/ref/create_sequence.sgml +++ b/zh/18/ref/create_sequence.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation CREATE SEQUENCE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/create_server.sgml b/zh/18/ref/create_server.sgml index 586067b0..0cb4f9ed 100644 --- a/zh/18/ref/create_server.sgml +++ b/zh/18/ref/create_server.sgml @@ -13,7 +13,7 @@ PostgreSQL documentation CREATE SERVER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/create_statistics.sgml b/zh/18/ref/create_statistics.sgml index ecafe6c6..f007156a 100644 --- a/zh/18/ref/create_statistics.sgml +++ b/zh/18/ref/create_statistics.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE STATISTICS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/create_subscription.sgml b/zh/18/ref/create_subscription.sgml index 9311f13b..6368c150 100644 --- a/zh/18/ref/create_subscription.sgml +++ b/zh/18/ref/create_subscription.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE SUBSCRIPTION 7 - SQL - Language Statements + SQL - 语言语句 @@ -247,7 +247,7 @@ CREATE SUBSCRIPTION subscription_nameparallel,表示如果有可用的并行应用工作进程, 接收到的更改会直接通过其中之一应用。如果没有空闲的并行应用工作进程 可以处理流式事务,那么这些更改会写入临时文件,并在事务提交后再应用。 - 注意,如果并行应用工作进程中发生错误,远端事务的 finish LSN + 注意,如果并行应用工作进程中发生错误,远端事务的 完成 LSN 可能不会记录到服务器日志中。 diff --git a/zh/18/ref/create_table.sgml b/zh/18/ref/create_table.sgml index 1eb96450..bb468e6f 100644 --- a/zh/18/ref/create_table.sgml +++ b/zh/18/ref/create_table.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation CREATE TABLE 7 - SQL - Language Statements + SQL - 语言语句 @@ -59,7 +59,7 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI [ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ] [ TABLESPACE tablespace_name ] -where column_constraint is: +其中column_constraint为: [ CONSTRAINT constraint_name ] { NOT NULL [ NO INHERIT ] | @@ -74,7 +74,7 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI [ ON DELETE referential_action ] [ ON UPDATE referential_action ] } [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ] [ ENFORCED | NOT ENFORCED ] -and table_constraint is: +table_constraint为: [ CONSTRAINT constraint_name ] { CHECK ( expression ) [ NO INHERIT ] | @@ -87,28 +87,28 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI class="parameter">referential_action ] [ ON UPDATE referential_action ] } [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ] [ ENFORCED | NOT ENFORCED ] -and like_option is: +like_option为: { INCLUDING | EXCLUDING } { COMMENTS | COMPRESSION | CONSTRAINTS | DEFAULTS | GENERATED | IDENTITY | INDEXES | STATISTICS | STORAGE | ALL } -and partition_bound_spec is: +partition_bound_spec为: IN ( partition_bound_expr [, ...] ) | FROM ( { partition_bound_expr | MINVALUE | MAXVALUE } [, ...] ) TO ( { partition_bound_expr | MINVALUE | MAXVALUE } [, ...] ) | WITH ( MODULUS numeric_literal, REMAINDER numeric_literal ) -index_parameters in UNIQUE, PRIMARY KEY, and EXCLUDE constraints are: +UNIQUEPRIMARY KEYEXCLUDE约束中的index_parameters为: [ INCLUDE ( column_name [, ... ] ) ] [ WITH ( storage_parameter [= value] [, ... ] ) ] [ USING INDEX TABLESPACE tablespace_name ] -exclude_element in an EXCLUDE constraint is: +EXCLUDE约束中的exclude_element为: { column_name | ( expression ) } [ COLLATE collation ] [ opclass [ ( opclass_parameter = value [, ... ] ) ] ] [ ASC | DESC ] [ NULLS { FIRST | LAST } ] -referential_action in a FOREIGN KEY/REFERENCES constraint is: +FOREIGN KEY/REFERENCES 约束中的 referential_action 为: { NO ACTION | RESTRICT | CASCADE | SET NULL [ ( column_name [, ... ] ) ] | SET DEFAULT [ ( column_name [, ... ] ) ] } @@ -155,7 +155,7 @@ WITH ( MODULUS numeric_literal, REM - TEMPORARY or TEMP + TEMPORARYTEMP @@ -170,7 +170,7 @@ WITH ( MODULUS numeric_literal, REM - 可以在 TEMPORARYTEMP 前写 GLOBALLOCAL。这在当前的 PostgreSQL 中没有区别,而且已废弃;见下文 。 + 可以在 TEMPORARYTEMP 前写 GLOBALLOCAL。这在当前的 PostgreSQL 中没有区别,而且已弃用;见下文 @@ -222,7 +222,7 @@ WITH ( MODULUS numeric_literal, REM - 类型化表的列名和数据类型始终与其派生类型相同,因此不能再指定额外的列。但 CREATE TABLE 命令仍可为该表添加默认值和约束,并指定存储参数。 + 类型化表的列名和数据类型始终与其所基于的类型相同,因此不能再指定额外的列。但 CREATE TABLE 命令仍可为该表添加默认值和约束,并指定存储参数。 @@ -253,10 +253,7 @@ WITH ( MODULUS numeric_literal, REM COLLATE collation - - COLLATE 子句为该列(必须是一种可排序数据类型)赋予一个排序规则。 - 如果没有指定,将使用该列数据类型的默认排序规则。 - + COLLATE子句为列指定排序规则(该列必须属于支持排序规则的数据类型)。如果未指定,则使用列数据类型的默认排序规则。 @@ -265,7 +262,7 @@ WITH ( MODULUS numeric_literal, REM STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN | DEFAULT } TOAST - per-column storage settings + 逐列存储设置 @@ -424,13 +421,13 @@ WITH ( MODULUS numeric_literal, REM 还要注意,某些元素类型(如 timestamp)具有 - "infinity" 的概念,那只是另一种可存储的值。这不同于 + “无穷大” 的概念,那只是另一种可存储的值。这不同于 MINVALUEMAXVALUE,后两者并非可存储 的实际值,而只是表示值无界的方式。MAXVALUE 可以视为大于任何 - 其他值,包括 "infinity";MINVALUE 可以视为小于任何 - 其他值,包括 "minus infinity"。因此,范围 + 其他值,包括 “无穷大”;MINVALUE 可以视为小于任何 + 其他值,包括 “负无穷大”。因此,范围 FROM ('infinity') TO (MAXVALUE) 并不是空范围;它只允许存储 - 一个值 — "infinity"。 + 一个值 — “无穷大”。 @@ -548,7 +545,7 @@ WITH ( MODULUS numeric_literal, REM INCLUDING GENERATED - 会复制被复制列定义中的生成表达式以及 STORED/VIRTUAL 的选择。默认情况下,新列将是常规基表列。 + 会复制被复制列定义中的生成表达式以及 STORED/VIRTUAL 的选择。默认情况下,新列将是普通基础列。 @@ -661,7 +658,7 @@ WITH ( MODULUS numeric_literal, REM - 一个被标记为NO INHERIT的约束将不会传播到子表。 + 标记为 NO INHERIT 的约束不会传播到子表。 @@ -688,7 +685,7 @@ WITH ( MODULUS numeric_literal, REM - GENERATED ALWAYS AS ( generation_expr ) [ STORED | VIRTUAL ]generated column + GENERATED ALWAYS AS ( generation_expr ) [ STORED | VIRTUAL ]生成列 @@ -800,7 +797,7 @@ WITH ( MODULUS numeric_literal, REM 可选的 INCLUDE 子句会向该索引添加一个或多个仅作为 - payload 的列:对这些列不强制唯一性,而且该索引也不能据此 + 载荷 的列:对这些列不强制唯一性,而且该索引也不能据此 进行搜索。不过,它们可以通过仅索引扫描取回。注意,尽管约束不在包含列上 强制执行,它仍然依赖于这些列。因此,对这类列执行某些操作(例如 DROP COLUMN)可能导致约束和索引被级联删除。 @@ -847,7 +844,7 @@ WITH ( MODULUS numeric_literal, REM 可选的 INCLUDE 子句会向该索引添加一个或多个仅作为 - payload 的列:对这些列不强制唯一性,而且该索引也不能据此 + 载荷 的列:对这些列不强制唯一性,而且该索引也不能据此 进行搜索。不过,它们可以通过仅索引扫描取回。注意,尽管约束不在包含列上 强制执行,它仍然依赖于这些列。因此,对这类列执行某些操作(例如 DROP COLUMN)可能导致约束和索引被级联删除。 @@ -883,7 +880,7 @@ WITH ( MODULUS numeric_literal, REM 访问方法必须支持 amgettuple(见 );目前这意味着不能使用 GIN。 虽然允许,但在排他约束上使用 B-树或 hash 索引意义不大,因为它们做不到 - 比普通唯一约束更好的事情。因此,实践中访问方法几乎总会是 + 比普通唯一约束更好的事情。因此,实践中访问方法总是 GiSTSP-GiST @@ -943,7 +940,7 @@ WITH ( MODULUS numeric_literal, REM - 对于每一对引用列和被引用列,如果它们属于可排序数据类型,则两者的排序规 + 对于每一对引用列和被引用列,如果它们属于支持排序规则的数据类型,则两者的排序规 则要么都必须是确定性的,要么必须完全相同。这样可以确保两列对“相等”具 有一致的定义。 @@ -1046,10 +1043,7 @@ WITH ( MODULUS numeric_literal, REM - - 如果被引用列经常发生变化,那么最好在引用列上添加一个索引,以便更高效地 - 执行与该外键约束相关的引用动作。 - + 如果被引用列经常变化,可以考虑在引用列上添加索引,使与外键约束关联的引用操作能够更高效地执行。 @@ -1093,7 +1087,7 @@ WITH ( MODULUS numeric_literal, REM NOT ENFORCED - 当约束为 ENFORCED 时,数据库系统会在适当时机检查该约束(按需要在每条语句后或事务结束时),这是默认行为。若约束为 NOT ENFORCED,数据库系统将不再检查该约束,改由应用代码保证约束成立。对于不影响结果正确性的优化决策,数据库系统仍可能假定数据满足该约束。 + 当约束为 ENFORCED 时,数据库系统会在适当时机检查该约束(按需要在每条语句后或事务结束时),以确保约束成立。这是默认行为。若约束为 NOT ENFORCED,数据库系统将不再检查该约束,改由应用代码保证约束成立。对于不影响结果正确性的优化决策,数据库系统仍可能假定数据满足该约束。 @@ -1225,7 +1219,7 @@ WITH ( MODULUS numeric_literal, REM 存储参数 - storage parameters + 存储参数 @@ -1247,7 +1241,7 @@ WITH ( MODULUS numeric_literal, REM fillfactor (integer) - fillfactor storage parameter + fillfactor 存储参数 @@ -1269,7 +1263,7 @@ WITH ( MODULUS numeric_literal, REM toast_tuple_target (integer) - toast_tuple_target storage parameter + toast_tuple_target 存储参数 @@ -1277,7 +1271,7 @@ WITH ( MODULUS numeric_literal, REM toast_tuple_target 指定在尝试压缩和/或将长列值移入 TOAST 表之前所需的最小元组长度,同时也是一旦开始 TOAST 化后试图将长度 - 缩减到的目标长度。这会影响标记为 External(用于移动)、Main(用于压缩) + 缩减到其以下的目标长度。这会影响标记为 External(用于移动)、Main(用于压缩) 或 Extended(用于两者)的列,并且只适用于新元组。对现有行没有影响。默认 情况下,该参数被设置为至少允许每个块容纳 4 个元组,在默认块大小下即为 2040 字节。有效值介于 128 字节与(块大小减去页头)之间,默认上限为 @@ -1292,13 +1286,13 @@ WITH ( MODULUS numeric_literal, REM parallel_workers (integer) - parallel_workers storage parameter + parallel_workers 存储参数 - 该参数设置在对该表执行并行扫描时可用于辅助扫描的工作进程数量。若未设置, + 该参数设置在对该表执行并行扫描时用于辅助扫描的工作进程数量。若未设置, 系统会根据关系大小决定一个值。规划器或使用并行扫描的实用命令实际选择的 工作进程数量可能更少,例如可能受 设置所限。 @@ -1310,7 +1304,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_enabled, toast.autovacuum_enabled (boolean) - autovacuum_enabled storage parameter + autovacuum_enabled 存储参数 @@ -1333,7 +1327,7 @@ WITH ( MODULUS numeric_literal, REM vacuum_index_cleanup, toast.vacuum_index_cleanup (enum) - vacuum_index_cleanup storage parameter + vacuum_index_cleanup 存储参数 @@ -1357,7 +1351,7 @@ WITH ( MODULUS numeric_literal, REM vacuum_truncate, toast.vacuum_truncate (boolean) vacuum_truncate - storage parameter + 存储参数 @@ -1375,7 +1369,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_vacuum_threshold, toast.autovacuum_vacuum_threshold (integer) autovacuum_vacuum_threshold - storage parameter + 存储参数 @@ -1390,7 +1384,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_vacuum_max_threshold, toast.autovacuum_vacuum_max_threshold (integer) autovacuum_vacuum_max_threshold - storage parameter + 存储参数 @@ -1405,7 +1399,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_vacuum_scale_factor, toast.autovacuum_vacuum_scale_factor (floating point) autovacuum_vacuum_scale_factor - storage parameter + 存储参数 @@ -1421,7 +1415,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_vacuum_insert_threshold, toast.autovacuum_vacuum_insert_threshold (integer) autovacuum_vacuum_insert_threshold - storage parameter + 存储参数 @@ -1438,7 +1432,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_vacuum_insert_scale_factor, toast.autovacuum_vacuum_insert_scale_factor (floating point) autovacuum_vacuum_insert_scale_factor - storage parameter + 存储参数 @@ -1454,7 +1448,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_analyze_threshold (integer) autovacuum_analyze_threshold - storage parameter + 存储参数 @@ -1470,7 +1464,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_analyze_scale_factor (floating point) autovacuum_analyze_scale_factor - storage parameter + 存储参数 @@ -1486,7 +1480,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_vacuum_cost_delay, toast.autovacuum_vacuum_cost_delay (floating point) autovacuum_vacuum_cost_delay - storage parameter + 存储参数 @@ -1502,7 +1496,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_vacuum_cost_limit, toast.autovacuum_vacuum_cost_limit (integer) autovacuum_vacuum_cost_limit - storage parameter + 存储参数 @@ -1517,7 +1511,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_freeze_min_age, toast.autovacuum_freeze_min_age (integer) - autovacuum_freeze_min_age storage parameter + autovacuum_freeze_min_age 存储参数 @@ -1535,7 +1529,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_freeze_max_age, toast.autovacuum_freeze_max_age (integer) autovacuum_freeze_max_age - storage parameter + 存储参数 @@ -1552,7 +1546,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_freeze_table_age, toast.autovacuum_freeze_table_age (integer) - autovacuum_freeze_table_age storage parameter + autovacuum_freeze_table_age 存储参数 @@ -1567,7 +1561,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_multixact_freeze_min_age, toast.autovacuum_multixact_freeze_min_age (integer) - autovacuum_multixact_freeze_min_age storage parameter + autovacuum_multixact_freeze_min_age 存储参数 @@ -1586,7 +1580,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_multixact_freeze_max_age, toast.autovacuum_multixact_freeze_max_age (integer) autovacuum_multixact_freeze_max_age - storage parameter + 存储参数 @@ -1604,7 +1598,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_multixact_freeze_table_age, toast.autovacuum_multixact_freeze_table_age (integer) - autovacuum_multixact_freeze_table_age storage parameter + autovacuum_multixact_freeze_table_age 存储参数 @@ -1620,7 +1614,7 @@ WITH ( MODULUS numeric_literal, REM log_autovacuum_min_duration, toast.log_autovacuum_min_duration (integer) log_autovacuum_min_duration - storage parameter + 存储参数 @@ -1635,7 +1629,7 @@ WITH ( MODULUS numeric_literal, REM vacuum_max_eager_freeze_failure_rate, toast.vacuum_max_eager_freeze_failure_rate (floating point) vacuum_max_eager_freeze_failure_rate - storage parameter + 存储参数 @@ -1649,7 +1643,7 @@ WITH ( MODULUS numeric_literal, REM user_catalog_table (boolean) - user_catalog_table storage parameter + user_catalog_table 存储参数 @@ -1671,7 +1665,7 @@ WITH ( MODULUS numeric_literal, REM 注解 - PostgreSQL为每一个唯一约束和主键约束创建一个索引来强制唯一性。因此,没有必要显式地为主键列创建一个索引(详见)。 + PostgreSQL为每一个唯一约束和主键约束自动创建一个索引来强制唯一性。因此,没有必要显式地为主键列创建一个索引(详见)。 @@ -2101,9 +2095,9 @@ CREATE TABLE cities_partdef NULL 约束(实际上并不是约束)是 - PostgreSQL 对 SQL 标准的扩展;它也被其他一些数 - 据库系统采纳,以便兼容(以及与对称的 NOT NULL 约束保持一 - 致)。由于它本来就是任意列的默认值,所以它的存在只是噪声。 + PostgreSQL 对 SQL 标准的扩展;提供它是为了 + 与其他一些数据库系统兼容(以及与 NOT NULL 约束保持 + 对称)。由于它本来就是任意列的默认情况,所以它的存在只是噪声。 @@ -2133,12 +2127,12 @@ CREATE TABLE cities_partdef - 零列表 + 零列的表 PostgreSQL 允许创建没有列的表(例如 CREATE TABLE foo();)。这是对 SQL 标准的扩展,标准不允许 - 零列表。零列表本身并不十分有用,但若禁止它们,就会让 + 零列的表。零列的表本身并不十分有用,但若禁止它们,就会让 ALTER TABLE DROP COLUMN 出现奇怪的特殊情况,因此忽略这 一规范限制看起来更整洁。 @@ -2151,7 +2145,7 @@ CREATE TABLE cities_partdef PostgreSQL 允许一个表拥有多个标识列。 该标准指定一个表最多只能有一个标识列。 - 这主要是为了给模式更改或迁移提供更大的灵活性。 + 放宽这一限制主要是为了给模式更改或迁移提供更大的灵活性。 请注意,INSERT 命令仅支持一个适用于整个语句的覆盖子 句,因此对行为不同的多个标识列支持并不好。 @@ -2204,8 +2198,7 @@ CREATE TABLE cities_partdef 类型化表 - 类型化表实现了 SQL 标准的一个子集。按照标准,类型化表除了具有与底层组合 - 类型相对应的列之外,还应有一个额外的自引用列。 + 类型化表实现了 SQL 标准的一个子集。按照标准,类型化表除了具有与底层复合类型相对应的列之外,还应有一个额外的自引用列PostgreSQL 不显式支持自引用列。 diff --git a/zh/18/ref/create_table_as.sgml b/zh/18/ref/create_table_as.sgml index 7d80a1f0..03a60483 100644 --- a/zh/18/ref/create_table_as.sgml +++ b/zh/18/ref/create_table_as.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation CREATE TABLE AS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/create_tablespace.sgml b/zh/18/ref/create_tablespace.sgml index 32b0dbb1..88106ccd 100644 --- a/zh/18/ref/create_tablespace.sgml +++ b/zh/18/ref/create_tablespace.sgml @@ -13,7 +13,7 @@ PostgreSQL documentation CREATE TABLESPACE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/create_transform.sgml b/zh/18/ref/create_transform.sgml index 247e6a0f..ecea2c1e 100644 --- a/zh/18/ref/create_transform.sgml +++ b/zh/18/ref/create_transform.sgml @@ -13,7 +13,7 @@ PostgreSQL documentation CREATE TRANSFORM 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/create_trigger.sgml b/zh/18/ref/create_trigger.sgml index 236c79c4..9f177700 100644 --- a/zh/18/ref/create_trigger.sgml +++ b/zh/18/ref/create_trigger.sgml @@ -11,13 +11,13 @@ PostgreSQL documentation 过渡表 - ephemeral named relation + 临时命名关系 CREATE TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -70,7 +70,7 @@ CREATE [ OR REPLACE ] [ CONSTRAINT ] TRIGGER name UPDATEDELETE之前); 也可以在该操作完成之后引发(即在检查约束以及完成 INSERTUPDATE或 - DELETE之后);或者改为执行该操作 + DELETE之后);或者取代该操作执行 (用于视图上的插入、更新或删除)。如果触发器在事件之前引发,或者改为取代该事件执行, 则它可以跳过对当前行的操作,或者修改待插入的行 (仅适用于INSERTUPDATE操作)。 @@ -178,7 +178,7 @@ CREATE [ OR REPLACE ] [ CONSTRAINT ] TRIGGER name 调整其引发时机。约束触发器必须是普通表(不是外部表)上的 AFTER ROW 触发器。它们既可以在导致触发事件的语句结束时引发, 也可以在包含它的事务结束时引发;后一种情况称为延迟。 - 也可以使用SET CONSTRAINTS强制挂起的延迟触发立即引发。 + 也可以使用SET CONSTRAINTS强制尚待执行的延迟触发器立即引发。 约束触发器应当在其所实现的约束遭到违反时抛出异常。 @@ -394,7 +394,7 @@ UPDATE OF column_name1 [, column_name2CREATE TRIGGER的语法中,关键字 FUNCTIONPROCEDURE 是等价的, 但无论如何,被引用的对象都必须是函数而不是过程。 - 这里使用 PROCEDURE 关键字只是出于历史原因,并且已被废弃。 + 这里使用 PROCEDURE 关键字只是出于历史原因,并且已被弃用。 diff --git a/zh/18/ref/create_tsconfig.sgml b/zh/18/ref/create_tsconfig.sgml index 52c43127..52970b36 100644 --- a/zh/18/ref/create_tsconfig.sgml +++ b/zh/18/ref/create_tsconfig.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TEXT SEARCH CONFIGURATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/create_tsdictionary.sgml b/zh/18/ref/create_tsdictionary.sgml index 7a06b430..c45a7240 100644 --- a/zh/18/ref/create_tsdictionary.sgml +++ b/zh/18/ref/create_tsdictionary.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TEXT SEARCH DICTIONARY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/create_tsparser.sgml b/zh/18/ref/create_tsparser.sgml index d0c11ba5..358152ce 100644 --- a/zh/18/ref/create_tsparser.sgml +++ b/zh/18/ref/create_tsparser.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TEXT SEARCH PARSER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/create_tstemplate.sgml b/zh/18/ref/create_tstemplate.sgml index 947b18b9..702233e4 100644 --- a/zh/18/ref/create_tstemplate.sgml +++ b/zh/18/ref/create_tstemplate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TEXT SEARCH TEMPLATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/create_type.sgml b/zh/18/ref/create_type.sgml index 45a4d93a..879d0a86 100644 --- a/zh/18/ref/create_type.sgml +++ b/zh/18/ref/create_type.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation CREATE TYPE 7 - SQL - Language Statements + SQL - 语言语句 @@ -96,7 +96,7 @@ CREATE TYPE name 复合类型 - 第一种形式的CREATE TYPE创建复合类型。组合 + 第一种形式的CREATE TYPE创建复合类型。复合 类型由属性名和数据类型列表指定。如果某个属性的数据类型支持排序规 则,还可以指定该属性的排序规则。复合类型本质上与表的行类型相同, 但如果目的只是定义一种类型,使用CREATE TYPE @@ -322,7 +322,7 @@ CREATE TYPE name 数才知道,但仍有若干内部表示属性必须向 PostgreSQL声明。其中最重要的是 internallength。 - 基础数据类型可以是定长的,此时internallength为正整数;也可 以是变长的,此时将internallength设为 @@ -427,7 +427,7 @@ CREATE TYPE name collatable为真,则 该类型的列定义和表达式可以通过COLLATE子句携 带排序规则信息。是否实际使用这些排序规则信息取决于操作该类型的函 - 数实现;仅仅把类型标记为 collatable 并不会自动实现这一点。 + 数实现;仅仅把类型标记为支持排序规则并不会自动实现这一点。 @@ -876,7 +876,7 @@ CREATE TYPE float8_range AS RANGE (subtype = float8, subtype_diff = float8mi); - 这个示例创建基础数据类型box,然后在表定义中使用它: + 这个示例创建基础类型box,然后在表定义中使用它: CREATE TYPE box; diff --git a/zh/18/ref/create_user.sgml b/zh/18/ref/create_user.sgml index 218c51eb..9548a147 100644 --- a/zh/18/ref/create_user.sgml +++ b/zh/18/ref/create_user.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE USER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/create_user_mapping.sgml b/zh/18/ref/create_user_mapping.sgml index fe556318..1abe6abd 100644 --- a/zh/18/ref/create_user_mapping.sgml +++ b/zh/18/ref/create_user_mapping.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE USER MAPPING 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/create_view.sgml b/zh/18/ref/create_view.sgml index 80c6d1ab..292b1a4b 100644 --- a/zh/18/ref/create_view.sgml +++ b/zh/18/ref/create_view.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation CREATE VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/createdb.sgml b/zh/18/ref/createdb.sgml index 554d7377..0a70cb6a 100644 --- a/zh/18/ref/createdb.sgml +++ b/zh/18/ref/createdb.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation createdb 1 - Application + 应用程序 diff --git a/zh/18/ref/createuser.sgml b/zh/18/ref/createuser.sgml index 0451cadd..eba45357 100644 --- a/zh/18/ref/createuser.sgml +++ b/zh/18/ref/createuser.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation createuser 1 - Application + 应用程序 @@ -139,7 +139,7 @@ PostgreSQL documentation - (已废弃) + (已弃用) diff --git a/zh/18/ref/deallocate.sgml b/zh/18/ref/deallocate.sgml index 27b9da86..6dea341e 100644 --- a/zh/18/ref/deallocate.sgml +++ b/zh/18/ref/deallocate.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation DEALLOCATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/declare.sgml b/zh/18/ref/declare.sgml index ed389e4d..9276a0e3 100644 --- a/zh/18/ref/declare.sgml +++ b/zh/18/ref/declare.sgml @@ -22,7 +22,7 @@ PostgreSQL documentation DECLARE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/delete.sgml b/zh/18/ref/delete.sgml index 4a79783c..653e86a2 100644 --- a/zh/18/ref/delete.sgml +++ b/zh/18/ref/delete.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DELETE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/discard.sgml b/zh/18/ref/discard.sgml index 29d4ea8d..f6572252 100644 --- a/zh/18/ref/discard.sgml +++ b/zh/18/ref/discard.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DISCARD 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/do.sgml b/zh/18/ref/do.sgml index 2ea6566a..cdbf189e 100644 --- a/zh/18/ref/do.sgml +++ b/zh/18/ref/do.sgml @@ -15,7 +15,7 @@ PostgreSQL documentation DO 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/drop_access_method.sgml b/zh/18/ref/drop_access_method.sgml index 407ec4cd..646100e1 100644 --- a/zh/18/ref/drop_access_method.sgml +++ b/zh/18/ref/drop_access_method.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP ACCESS METHOD 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/drop_aggregate.sgml b/zh/18/ref/drop_aggregate.sgml index 1c8a1122..9fd7ea4b 100644 --- a/zh/18/ref/drop_aggregate.sgml +++ b/zh/18/ref/drop_aggregate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP AGGREGATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/drop_cast.sgml b/zh/18/ref/drop_cast.sgml index 73860e3c..5e330ae0 100644 --- a/zh/18/ref/drop_cast.sgml +++ b/zh/18/ref/drop_cast.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP CAST 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/drop_collation.sgml b/zh/18/ref/drop_collation.sgml index b90849fc..b10b3206 100644 --- a/zh/18/ref/drop_collation.sgml +++ b/zh/18/ref/drop_collation.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP COLLATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/drop_conversion.sgml b/zh/18/ref/drop_conversion.sgml index b63d1291..35009708 100644 --- a/zh/18/ref/drop_conversion.sgml +++ b/zh/18/ref/drop_conversion.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP CONVERSION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/drop_database.sgml b/zh/18/ref/drop_database.sgml index 9bbd949f..10817b69 100644 --- a/zh/18/ref/drop_database.sgml +++ b/zh/18/ref/drop_database.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP DATABASE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/drop_domain.sgml b/zh/18/ref/drop_domain.sgml index d43f95c6..b292b189 100644 --- a/zh/18/ref/drop_domain.sgml +++ b/zh/18/ref/drop_domain.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP DOMAIN 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/drop_event_trigger.sgml b/zh/18/ref/drop_event_trigger.sgml index 80020f78..f4f0053f 100644 --- a/zh/18/ref/drop_event_trigger.sgml +++ b/zh/18/ref/drop_event_trigger.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP EVENT TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -30,7 +30,7 @@ DROP EVENT TRIGGER [ IF EXISTS ] name DROP EVENT TRIGGER移除一个现有的事件触发器。 - 要执行此命令,当前用户必须是该事件触发器的拥有者。 + 要执行此命令,当前用户必须是该事件触发器的所有者。 @@ -99,7 +99,7 @@ DROP EVENT TRIGGER snitch; - 另见 + 参见 diff --git a/zh/18/ref/drop_extension.sgml b/zh/18/ref/drop_extension.sgml index 5eb04c04..ccccb0b1 100644 --- a/zh/18/ref/drop_extension.sgml +++ b/zh/18/ref/drop_extension.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP EXTENSION 7 - SQL - Language Statements + SQL - 语言语句 @@ -59,8 +59,8 @@ DROP EXTENSION [ IF EXISTS ] name [ name - 已安装扩展的名称。 - + 一个已安装扩展的名称。 + @@ -95,7 +95,7 @@ DROP EXTENSION [ IF EXISTS ] name [ DROP EXTENSION hstore; - 如果数据库中正在使用hstore的任何对象, + 如果数据库中使用了hstore的任何对象, 例如某些表具有hstore类型的列,则该命令会失败。 加上CASCADE选项可以强制一并移除这些依赖对象。 diff --git a/zh/18/ref/drop_foreign_data_wrapper.sgml b/zh/18/ref/drop_foreign_data_wrapper.sgml index 9902c875..6f781f31 100644 --- a/zh/18/ref/drop_foreign_data_wrapper.sgml +++ b/zh/18/ref/drop_foreign_data_wrapper.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP FOREIGN DATA WRAPPER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/drop_foreign_table.sgml b/zh/18/ref/drop_foreign_table.sgml index 0b4d0bbd..c420e4ba 100644 --- a/zh/18/ref/drop_foreign_table.sgml +++ b/zh/18/ref/drop_foreign_table.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP FOREIGN TABLE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/drop_function.sgml b/zh/18/ref/drop_function.sgml index 32e1de58..f80cc1d8 100644 --- a/zh/18/ref/drop_function.sgml +++ b/zh/18/ref/drop_function.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP FUNCTION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/drop_group.sgml b/zh/18/ref/drop_group.sgml index f43389ca..4ee8fc55 100644 --- a/zh/18/ref/drop_group.sgml +++ b/zh/18/ref/drop_group.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP GROUP 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/drop_index.sgml b/zh/18/ref/drop_index.sgml index b65b810b..d7f892d9 100644 --- a/zh/18/ref/drop_index.sgml +++ b/zh/18/ref/drop_index.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP INDEX 7 - SQL - Language Statements + SQL - 语言语句 @@ -57,7 +57,7 @@ DROP INDEX [ CONCURRENTLY ] [ IF EXISTS ] name 对于临时表,DROP INDEX始终是非并发的, - 因为没有其他会话可以访问它们,而且非并发删除索引的成本更低。 + 因为没有其他会话可以访问它们,而且非并发删除索引的代价更低。 @@ -66,7 +66,7 @@ DROP INDEX [ CONCURRENTLY ] [ IF EXISTS ] nameIF EXISTS - 如果该索引不存在,则不要抛出错误。这种情况下会发出一个提示。 + 如果该索引不存在,则不要抛出错误。这种情况下会发出一条提示。 diff --git a/zh/18/ref/drop_language.sgml b/zh/18/ref/drop_language.sgml index 9696f612..8fb4de3f 100644 --- a/zh/18/ref/drop_language.sgml +++ b/zh/18/ref/drop_language.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP LANGUAGE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/drop_materialized_view.sgml b/zh/18/ref/drop_materialized_view.sgml index f3682552..71ad4326 100644 --- a/zh/18/ref/drop_materialized_view.sgml +++ b/zh/18/ref/drop_materialized_view.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP MATERIALIZED VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/drop_opclass.sgml b/zh/18/ref/drop_opclass.sgml index c3dd2e74..9d67dc64 100644 --- a/zh/18/ref/drop_opclass.sgml +++ b/zh/18/ref/drop_opclass.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP OPERATOR CLASS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/drop_operator.sgml b/zh/18/ref/drop_operator.sgml index 3cfb069c..19e93d4e 100644 --- a/zh/18/ref/drop_operator.sgml +++ b/zh/18/ref/drop_operator.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP OPERATOR 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/drop_opfamily.sgml b/zh/18/ref/drop_opfamily.sgml index 8e7097f9..06223045 100644 --- a/zh/18/ref/drop_opfamily.sgml +++ b/zh/18/ref/drop_opfamily.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP OPERATOR FAMILY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/drop_owned.sgml b/zh/18/ref/drop_owned.sgml index 2bc659bf..3ec24e66 100644 --- a/zh/18/ref/drop_owned.sgml +++ b/zh/18/ref/drop_owned.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP OWNED 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/drop_policy.sgml b/zh/18/ref/drop_policy.sgml index ee64ffa0..a939a688 100644 --- a/zh/18/ref/drop_policy.sgml +++ b/zh/18/ref/drop_policy.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP POLICY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/drop_procedure.sgml b/zh/18/ref/drop_procedure.sgml index 178e6684..19708931 100644 --- a/zh/18/ref/drop_procedure.sgml +++ b/zh/18/ref/drop_procedure.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP PROCEDURE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/drop_publication.sgml b/zh/18/ref/drop_publication.sgml index 6bc4bf59..048c1756 100644 --- a/zh/18/ref/drop_publication.sgml +++ b/zh/18/ref/drop_publication.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP PUBLICATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/drop_role.sgml b/zh/18/ref/drop_role.sgml index 6f3dd022..9fbfa99e 100644 --- a/zh/18/ref/drop_role.sgml +++ b/zh/18/ref/drop_role.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP ROLE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/drop_routine.sgml b/zh/18/ref/drop_routine.sgml index 4f2be77f..db15d5d2 100644 --- a/zh/18/ref/drop_routine.sgml +++ b/zh/18/ref/drop_routine.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP ROUTINE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/drop_rule.sgml b/zh/18/ref/drop_rule.sgml index ddb561f4..2968d946 100644 --- a/zh/18/ref/drop_rule.sgml +++ b/zh/18/ref/drop_rule.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP RULE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/drop_schema.sgml b/zh/18/ref/drop_schema.sgml index 9f622df3..94843c9a 100644 --- a/zh/18/ref/drop_schema.sgml +++ b/zh/18/ref/drop_schema.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP SCHEMA 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/drop_sequence.sgml b/zh/18/ref/drop_sequence.sgml index 4ba78640..586d3038 100644 --- a/zh/18/ref/drop_sequence.sgml +++ b/zh/18/ref/drop_sequence.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP SEQUENCE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/drop_server.sgml b/zh/18/ref/drop_server.sgml index 0864a4c2..8bdacdc8 100644 --- a/zh/18/ref/drop_server.sgml +++ b/zh/18/ref/drop_server.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP SERVER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/drop_statistics.sgml b/zh/18/ref/drop_statistics.sgml index 3120dc06..4773bfa8 100644 --- a/zh/18/ref/drop_statistics.sgml +++ b/zh/18/ref/drop_statistics.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP STATISTICS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/drop_subscription.sgml b/zh/18/ref/drop_subscription.sgml index 67421595..c793c07f 100644 --- a/zh/18/ref/drop_subscription.sgml +++ b/zh/18/ref/drop_subscription.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP SUBSCRIPTION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/drop_table.sgml b/zh/18/ref/drop_table.sgml index a2634c54..bdfbabf4 100644 --- a/zh/18/ref/drop_table.sgml +++ b/zh/18/ref/drop_table.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TABLE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/drop_tablespace.sgml b/zh/18/ref/drop_tablespace.sgml index c8b09e59..a31fd70f 100644 --- a/zh/18/ref/drop_tablespace.sgml +++ b/zh/18/ref/drop_tablespace.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TABLESPACE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/drop_transform.sgml b/zh/18/ref/drop_transform.sgml index be84b60c..09a3c9c7 100644 --- a/zh/18/ref/drop_transform.sgml +++ b/zh/18/ref/drop_transform.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TRANSFORM 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/drop_trigger.sgml b/zh/18/ref/drop_trigger.sgml index 1f85cf41..160a5ebd 100644 --- a/zh/18/ref/drop_trigger.sgml +++ b/zh/18/ref/drop_trigger.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -30,7 +30,7 @@ DROP TRIGGER [ IF EXISTS ] name ON DROP TRIGGER移除一个现有触发器的定义。 - 要执行此命令,当前用户必须是定义该触发器的表的拥有者。 + 要执行此命令,当前用户必须是定义该触发器的表的所有者。 @@ -109,7 +109,7 @@ DROP TRIGGER if_dist_exists ON films; - 另见 + 参见 diff --git a/zh/18/ref/drop_tsconfig.sgml b/zh/18/ref/drop_tsconfig.sgml index 2a7cdc52..ea139802 100644 --- a/zh/18/ref/drop_tsconfig.sgml +++ b/zh/18/ref/drop_tsconfig.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TEXT SEARCH CONFIGURATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/drop_tsdictionary.sgml b/zh/18/ref/drop_tsdictionary.sgml index 1eb24189..316c5d00 100644 --- a/zh/18/ref/drop_tsdictionary.sgml +++ b/zh/18/ref/drop_tsdictionary.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TEXT SEARCH DICTIONARY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/drop_tsparser.sgml b/zh/18/ref/drop_tsparser.sgml index 0cfa7acd..a65f47be 100644 --- a/zh/18/ref/drop_tsparser.sgml +++ b/zh/18/ref/drop_tsparser.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TEXT SEARCH PARSER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/drop_tstemplate.sgml b/zh/18/ref/drop_tstemplate.sgml index 282231c5..fa1faab0 100644 --- a/zh/18/ref/drop_tstemplate.sgml +++ b/zh/18/ref/drop_tstemplate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TEXT SEARCH TEMPLATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/drop_type.sgml b/zh/18/ref/drop_type.sgml index dab5bfa0..2f139da5 100644 --- a/zh/18/ref/drop_type.sgml +++ b/zh/18/ref/drop_type.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TYPE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/drop_user.sgml b/zh/18/ref/drop_user.sgml index 00d1d5f4..2e61d6ef 100644 --- a/zh/18/ref/drop_user.sgml +++ b/zh/18/ref/drop_user.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP USER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/drop_user_mapping.sgml b/zh/18/ref/drop_user_mapping.sgml index 2a79a65b..d23b0a16 100644 --- a/zh/18/ref/drop_user_mapping.sgml +++ b/zh/18/ref/drop_user_mapping.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP USER MAPPING 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/drop_view.sgml b/zh/18/ref/drop_view.sgml index 4feb47e5..8f995245 100644 --- a/zh/18/ref/drop_view.sgml +++ b/zh/18/ref/drop_view.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/dropdb.sgml b/zh/18/ref/dropdb.sgml index 70ad776f..10f79ed2 100644 --- a/zh/18/ref/dropdb.sgml +++ b/zh/18/ref/dropdb.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation dropdb 1 - Application + 应用程序 diff --git a/zh/18/ref/dropuser.sgml b/zh/18/ref/dropuser.sgml index 55aa53fa..3cdd48c0 100644 --- a/zh/18/ref/dropuser.sgml +++ b/zh/18/ref/dropuser.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation dropuser 1 - Application + 应用程序 diff --git a/zh/18/ref/ecpg-ref.sgml b/zh/18/ref/ecpg-ref.sgml index 002b8ef1..506be589 100644 --- a/zh/18/ref/ecpg-ref.sgml +++ b/zh/18/ref/ecpg-ref.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ecpg 1 - Application + 应用程序 diff --git a/zh/18/ref/end.sgml b/zh/18/ref/end.sgml index d042a740..10947ab0 100644 --- a/zh/18/ref/end.sgml +++ b/zh/18/ref/end.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation END 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/execute.sgml b/zh/18/ref/execute.sgml index 2aed0669..5e7274ff 100644 --- a/zh/18/ref/execute.sgml +++ b/zh/18/ref/execute.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation EXECUTE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/explain.sgml b/zh/18/ref/explain.sgml index 5d6ad75a..bb06dcca 100644 --- a/zh/18/ref/explain.sgml +++ b/zh/18/ref/explain.sgml @@ -21,7 +21,7 @@ PostgreSQL documentation EXPLAIN 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/fetch.sgml b/zh/18/ref/fetch.sgml index 71c12406..9ab88c49 100644 --- a/zh/18/ref/fetch.sgml +++ b/zh/18/ref/fetch.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation FETCH 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/grant.sgml b/zh/18/ref/grant.sgml index 90d2b6aa..74073771 100644 --- a/zh/18/ref/grant.sgml +++ b/zh/18/ref/grant.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation GRANT 7 - SQL - Language Statements + SQL - 语言语句 @@ -102,7 +102,7 @@ GRANT role_name [, ...] TO role_specification ] -where role_specification can be: +其中role_specification可以是: [ GROUP ] role_name | PUBLIC diff --git a/zh/18/ref/import_foreign_schema.sgml b/zh/18/ref/import_foreign_schema.sgml index 6e912201..1957d60a 100644 --- a/zh/18/ref/import_foreign_schema.sgml +++ b/zh/18/ref/import_foreign_schema.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation IMPORT FOREIGN SCHEMA 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/initdb.sgml b/zh/18/ref/initdb.sgml index 28ee2e7d..6ac68117 100644 --- a/zh/18/ref/initdb.sgml +++ b/zh/18/ref/initdb.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation initdb 1 - Application + 应用程序 @@ -208,7 +208,7 @@ PostgreSQL documentation - 当使用 ICU 提供程序时,指定 ICU 区域设置 ID。区域设置支持见 + 当使用 ICU 提供程序时,指定 ICU 区域设置。区域设置支持见 diff --git a/zh/18/ref/insert.sgml b/zh/18/ref/insert.sgml index e3cc2c2e..025d9d82 100644 --- a/zh/18/ref/insert.sgml +++ b/zh/18/ref/insert.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation INSERT 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/listen.sgml b/zh/18/ref/listen.sgml index 0a7c6e23..421010d0 100644 --- a/zh/18/ref/listen.sgml +++ b/zh/18/ref/listen.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation LISTEN 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/load.sgml b/zh/18/ref/load.sgml index bb0adb7c..89bdb114 100644 --- a/zh/18/ref/load.sgml +++ b/zh/18/ref/load.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation LOAD 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/lock.sgml b/zh/18/ref/lock.sgml index bc45eec4..fce3ac96 100644 --- a/zh/18/ref/lock.sgml +++ b/zh/18/ref/lock.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation LOCK 7 - SQL - Language Statements + SQL - 语言语句 @@ -55,7 +55,7 @@ LOCK [ TABLE ] [ ONLY ] name [ * ] 因为SHARE锁模式与写入者获取的ROW EXCLUSIVE锁冲突, 而LOCK TABLE name IN SHARE MODE - 语句会一直等待,直到任何并发持有ROW EXCLUSIVE模式锁的事务提交或回滚。 + 语句会一直等待,直到所有并发持有ROW EXCLUSIVE模式锁的事务提交或回滚。 因此,一旦获得该锁,就不存在尚未提交的写入;而且在释放该锁之前,也不会有新的写入开始。 @@ -166,9 +166,7 @@ LOCK [ TABLE ] [ ONLY ] name [ * ] 这些模式名称通常应理解为:用户打算在被锁定的表中获取行级锁。 此外,ROW EXCLUSIVE模式本身也是一种可共享的表锁。 请记住,就LOCK TABLE而言,所有锁模式的语义完全相同, - 差别只在于哪些模式彼此冲突。关于如何获取真正的行级锁,请参阅 - 文档中的和 - 。 + 差别只在于哪些模式彼此冲突。关于如何获取真正的行级锁,请参阅 (后者位于文档中)。 diff --git a/zh/18/ref/merge.sgml b/zh/18/ref/merge.sgml index c57732bd..bb13669c 100644 --- a/zh/18/ref/merge.sgml +++ b/zh/18/ref/merge.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation MERGE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/move.sgml b/zh/18/ref/move.sgml index e90c1b88..961359c8 100644 --- a/zh/18/ref/move.sgml +++ b/zh/18/ref/move.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation MOVE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/notify.sgml b/zh/18/ref/notify.sgml index 502baccc..a9f72d29 100644 --- a/zh/18/ref/notify.sgml +++ b/zh/18/ref/notify.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation NOTIFY 7 - SQL - Language Statements + SQL - 语言语句 @@ -88,7 +88,7 @@ NOTIFY channel [ , 注解 - 系统中有一个队列,用来保存那些已经发送但尚未被所有监听会话处理的通知。如果这个队列被塞满,那么调用NOTIFY的事务会在提交时失败。该队列非常大(标准安装中为 8GB),几乎足以满足所有用例。不过,如果某个会话执行了LISTEN后又长时间停留在一个事务里,就无法进行清理。一旦队列占用超过一半,你就会在日志文件中看到警告,指出究竟是哪个会话阻碍了清理。在这种情况下,应确保该会话结束其当前事务,以便清理能够继续进行。 + 系统中有一个队列,用来保存那些已经发送但尚未被所有监听会话处理的通知。如果这个队列被塞满,那么调用NOTIFY的事务会在提交时失败。该队列非常大(标准安装中为 8GB),几乎足以满足所有用例。不过,如果某个会话执行了LISTEN后又长时间停留在一个事务里,就无法进行清理。一旦队列占用达到一半,你就会在日志文件中看到警告,指出究竟是哪个会话阻碍了清理。在这种情况下,应确保该会话结束其当前事务,以便清理能够继续进行。 函数pg_notification_queue_usage返回当前被待处理通知占用的队列比例。详见。 diff --git a/zh/18/ref/pg_amcheck.sgml b/zh/18/ref/pg_amcheck.sgml index 855c42dd..55a6e2b7 100644 --- a/zh/18/ref/pg_amcheck.sgml +++ b/zh/18/ref/pg_amcheck.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_amcheck 1 - Application + 应用程序 diff --git a/zh/18/ref/pg_basebackup.sgml b/zh/18/ref/pg_basebackup.sgml index 91155fa9..3c0c71a7 100644 --- a/zh/18/ref/pg_basebackup.sgml +++ b/zh/18/ref/pg_basebackup.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation pg_basebackup 1 - Application + 应用程序 @@ -80,7 +80,7 @@ PostgreSQL documentation - 备份所需的所有 WAL 记录都必须包含足够的全页写入, + 备份所需的所有 WAL 记录都必须包含足够的整页写入, 因此必须在主库上启用full_page_writes @@ -217,7 +217,7 @@ PostgreSQL documentation - 目前,此选项仅适用于 plain 输出格式;如果选择了 tar 格式,则会被忽略。 + 目前,此选项仅适用于 普通文件 输出格式;如果选择了 tar 格式,则会被忽略。 @@ -227,7 +227,7 @@ PostgreSQL documentation - 设置写入 WAL(预写式日志)文件的目录。默认情况下,WAL 文件会放在目标目录的pg_wal子目录中,但此选项可用于将其放在其他位置。waldir必须是绝对路径。与主目标目录一样,waldir不必事先存在,但如果存在则必须为空。只有当备份采用 plain 格式时,才能指定此选项。 + 设置写入 WAL(预写式日志)文件的目录。默认情况下,WAL 文件会放在目标目录的pg_wal子目录中,但此选项可用于将其放在其他位置。waldir必须是绝对路径。与主目标目录一样,waldir不必事先存在,但如果存在则必须为空。只有当备份采用 普通文件 格式时,才能指定此选项。 @@ -319,7 +319,7 @@ PostgreSQL documentation - 当 tar 格式配合gziplz4zstd使用时,所有 tar 文件名都会分别自动加上.gz.lz4.zst后缀。使用 plain 格式时,不能指定客户端压缩,但仍可以请求服务器端压缩。这样做时,服务器会先压缩备份再传输,而客户端会对其进行解压并提取。 + 当 tar 格式配合gziplz4zstd使用时,所有 tar 文件名都会分别自动加上.gz.lz4.zst后缀。使用 普通文件 格式时,不能指定客户端压缩,但仍可以请求服务器端压缩。这样做时,服务器会先压缩备份再传输,而客户端会对其进行解压并提取。 @@ -378,7 +378,7 @@ PostgreSQL documentation - 请注意,无论如何表空间目录都不会被清理。 + 请注意,无论是否使用此选项,表空间目录都不会被清理。 @@ -426,7 +426,7 @@ PostgreSQL documentation - 此选项只能与-X stream一起使用。它会使 WAL 流式传输使用指定的复制槽。如果此基础备份打算用作使用复制槽的流复制备库,那么该备库应使用与相同的复制槽名称。这样可以确保主库在基础备份结束与新备库开始流复制之间的这段时间内,不会移除任何必需的 WAL 数据。 + 此选项只能与-X stream一起使用。它会使 WAL 流式传输使用指定的复制槽。如果此基础备份打算用作使用复制槽的流复制备库,那么该备库应将同一个复制槽名称用作的值。这样可以确保主库在基础备份结束与新备库开始流复制之间的这段时间内,不会移除任何必需的 WAL 数据。 @@ -443,10 +443,10 @@ PostgreSQL documentation - 设置为fsync(默认)时,pg_basebackup会递归打开并同步备份目录中的所有文件。使用 plain 格式时,查找文件会跟随 WAL 目录和各已配置表空间的符号链接。 + 设置为fsync(默认)时,pg_basebackup会递归打开并同步备份目录中的所有文件。使用 普通文件 格式时,查找文件会跟随 WAL 目录和各已配置表空间的符号链接。 - 在 Linux 上,也可以使用syncfs,让操作系统同步包含备份目录的整个文件系统。使用 plain 格式时,pg_basebackup还会同步包含 WAL 文件和各表空间的文件系统。关于使用syncfs时需要注意的限制,见。 + 在 Linux 上,也可以使用syncfs,让操作系统同步包含备份目录的整个文件系统。使用 普通文件 格式时,pg_basebackup还会同步包含 WAL 文件和各表空间的文件系统。关于使用syncfs时需要注意的事项,见 使用时,此选项无效。 @@ -478,7 +478,7 @@ PostgreSQL documentation - 对于希望验证备份未被篡改的用户,使用 SHA 哈希函数可以为每个文件提供具有密码学安全性的摘要;而 CRC-32C 算法提供的校验和计算速度要快得多,虽然它很适合发现由于意外改动造成的错误,但并不能抵御恶意修改。请注意,要想对能够访问备份的攻击者形成防护,备份清单就需要安全地保存在其他地方,或者以其他方式确认自备份完成后未被修改。 + 对于希望验证备份未被篡改的用户,使用 SHA hash 函数可以为每个文件提供具有密码学安全性的摘要;而 CRC-32C 算法提供的校验和计算速度要快得多,虽然它很适合发现由于意外改动造成的错误,但并不能抵御恶意修改。请注意,要想对能够访问备份的攻击者形成防护,备份清单就需要安全地保存在其他地方,或者以其他方式确认自备份完成后未被修改。 @@ -686,7 +686,7 @@ PostgreSQL documentation - 注意 + 注解 在备份开始时,需要在源服务器上执行一次检查点。这可能需要一些时间(尤其是在未使用--checkpoint=fast选项时);在此期间,pg_basebackup看起来会处于空闲状态。 @@ -697,7 +697,7 @@ PostgreSQL documentation - 在 plain 格式中,除非使用了--tablespace-mapping选项,否则表空间会备份到其在源服务器上的相同路径。如果不使用此选项,那么当表空间正在使用时,就无法在与服务器相同的主机上执行 plain 格式的基础备份,因为备份将不得不写入与原始表空间相同的目录位置。 + 在 普通文件 格式中,除非使用了--tablespace-mapping选项,否则表空间会备份到其在源服务器上的相同路径。如果不使用此选项,那么当表空间正在使用时,就无法在与服务器相同的主机上执行 普通文件 格式的基础备份,因为备份将不得不写入与原始表空间相同的目录位置。 @@ -757,7 +757,7 @@ PostgreSQL documentation - 参见 + 另见 diff --git a/zh/18/ref/pg_checksums.sgml b/zh/18/ref/pg_checksums.sgml index bba74354..9ffb27fb 100644 --- a/zh/18/ref/pg_checksums.sgml +++ b/zh/18/ref/pg_checksums.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_checksums 1 - Application + 应用程序 diff --git a/zh/18/ref/pg_combinebackup.sgml b/zh/18/ref/pg_combinebackup.sgml index 5ae1aa14..c9ebcedf 100644 --- a/zh/18/ref/pg_combinebackup.sgml +++ b/zh/18/ref/pg_combinebackup.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_combinebackup 1 - Application + 应用程序 @@ -239,18 +239,18 @@ PostgreSQL documentation 当设置为fsync(这是默认值)时, pg_combinebackup会递归打开并同步备份目录中的所有文件。 - 使用 plain 格式时,搜索文件时会跟随 WAL 目录和每个已配置表空间的符号链接。 + 使用 普通文件 格式时,搜索文件时会跟随 WAL 目录和每个已配置表空间的符号链接。 在 Linux 上,也可以改用syncfs, 让操作系统同步包含备份目录的整个文件系统。 - 使用 plain 格式时,pg_combinebackup + 使用 普通文件 格式时,pg_combinebackup 还会同步包含 WAL 文件和各表空间的文件系统。 关于使用syncfs时需要注意的事项,请参见 - 当使用时,此选项无效。 + 使用时,此选项无效。 @@ -302,15 +302,11 @@ PostgreSQL documentation 环境 - 与多数PostgreSQL工具一样, - 本工具使用libpq支持的环境变量 - (参见)。 + 与大多数其他PostgreSQL工具一样,此工具也使用libpq支持的环境变量(见)。 - 环境变量PG_COLOR指定诊断消息是否使用颜色。 - 可选值为alwaysauto和 - never。 + 环境变量PG_COLOR指定是否在诊断消息中使用颜色。可能的值为alwaysautonever diff --git a/zh/18/ref/pg_config-ref.sgml b/zh/18/ref/pg_config-ref.sgml index 565638d9..b157f24c 100644 --- a/zh/18/ref/pg_config-ref.sgml +++ b/zh/18/ref/pg_config-ref.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation pg_config 1 - Application + 应用程序 diff --git a/zh/18/ref/pg_controldata.sgml b/zh/18/ref/pg_controldata.sgml index 818db6cc..5435edfa 100644 --- a/zh/18/ref/pg_controldata.sgml +++ b/zh/18/ref/pg_controldata.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_controldata 1 - Application + 应用程序 diff --git a/zh/18/ref/pg_createsubscriber.sgml b/zh/18/ref/pg_createsubscriber.sgml index 81487086..fdea72aa 100644 --- a/zh/18/ref/pg_createsubscriber.sgml +++ b/zh/18/ref/pg_createsubscriber.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_createsubscriber 1 - Application + 应用程序 @@ -170,7 +170,7 @@ PostgreSQL documentation - 等待恢复结束的最大秒数。设为 0 表示禁用。 + 等待恢复结束的最大秒数。设为 0 表示禁用超时限制。 默认值为 0。 @@ -313,7 +313,7 @@ PostgreSQL documentation - 注意 + 注解 前置条件 @@ -404,7 +404,7 @@ PostgreSQL documentation 若缺少必需 WAL 文件,复制可能失败。 - 为避免该问题,源服务器应将 + 为避免该问题,源服务器必须将 设置为-1, 以确保必需 WAL 文件不会被提前移除。 @@ -456,9 +456,9 @@ PostgreSQL documentation 它指定了恢复将推进到的预写式日志位置的 LSN()。 它还将promote指定为服务器在达到恢复目标后应执行的动作。 - 为了避免恢复过程中出现意外行为,还会添加其他恢复参数,例如在达到一致状态后就结束恢复 - (实际上 WAL 应继续应用到复制起始位置)以及因多个恢复目标而导致失败。 + 还会添加其他恢复参数,以避免恢复过程中出现意外行为, + 例如一达到一致状态就结束恢复(WAL 应继续应用到复制起始位置),或者因指定多个恢复目标而失败。 当服务器退出备库模式并接受读写事务时,该步骤结束。 如果设置了选项,而恢复在给定秒数内没有结束, pg_createsubscriber就会终止。 diff --git a/zh/18/ref/pg_ctl-ref.sgml b/zh/18/ref/pg_ctl-ref.sgml index 6085da56..801cbc55 100644 --- a/zh/18/ref/pg_ctl-ref.sgml +++ b/zh/18/ref/pg_ctl-ref.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation pg_ctl 1 - Application + 应用程序 diff --git a/zh/18/ref/pg_dump.sgml b/zh/18/ref/pg_dump.sgml index 5bf6314d..663b424b 100644 --- a/zh/18/ref/pg_dump.sgml +++ b/zh/18/ref/pg_dump.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_dump 1 - Application + 应用程序 diff --git a/zh/18/ref/pg_dumpall.sgml b/zh/18/ref/pg_dumpall.sgml index bdec2662..c10a1658 100644 --- a/zh/18/ref/pg_dumpall.sgml +++ b/zh/18/ref/pg_dumpall.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_dumpall 1 - Application + 应用程序 diff --git a/zh/18/ref/pg_isready.sgml b/zh/18/ref/pg_isready.sgml index 2e93dde1..a09f7745 100644 --- a/zh/18/ref/pg_isready.sgml +++ b/zh/18/ref/pg_isready.sgml @@ -13,7 +13,7 @@ PostgreSQL documentation pg_isready 1 - Application + 应用程序 diff --git a/zh/18/ref/pg_receivewal.sgml b/zh/18/ref/pg_receivewal.sgml index 3c9e580a..bf520c28 100644 --- a/zh/18/ref/pg_receivewal.sgml +++ b/zh/18/ref/pg_receivewal.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation pg_receivewal 1 - Application + 应用程序 diff --git a/zh/18/ref/pg_recvlogical.sgml b/zh/18/ref/pg_recvlogical.sgml index 993fc2a9..acd6439b 100644 --- a/zh/18/ref/pg_recvlogical.sgml +++ b/zh/18/ref/pg_recvlogical.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation pg_recvlogical 1 - Application + 应用程序 @@ -155,7 +155,7 @@ PostgreSQL documentation - 启用后会将该槽同步到备库。此选项只能与 一起指定。 + 允许将该槽同步到备库。此选项只能与 一起指定。 @@ -181,7 +181,7 @@ PostgreSQL documentation 指定pg_recvlogical应当以多高的频率发起fsync()调用, - 以确保输出文件被安全地刷入磁盘。 + 以确保输出文件安全刷盘。 diff --git a/zh/18/ref/pg_resetwal.sgml b/zh/18/ref/pg_resetwal.sgml index 9deadc8c..7dee0bce 100644 --- a/zh/18/ref/pg_resetwal.sgml +++ b/zh/18/ref/pg_resetwal.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_resetwal 1 - Application + 应用程序 diff --git a/zh/18/ref/pg_restore.sgml b/zh/18/ref/pg_restore.sgml index 7ae86b39..8cd4af1a 100644 --- a/zh/18/ref/pg_restore.sgml +++ b/zh/18/ref/pg_restore.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_restore 1 - Application + 应用程序 diff --git a/zh/18/ref/pg_rewind.sgml b/zh/18/ref/pg_rewind.sgml index 16ffc2e9..93617f49 100644 --- a/zh/18/ref/pg_rewind.sgml +++ b/zh/18/ref/pg_rewind.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation pg_rewind 1 - Application + 应用程序 diff --git a/zh/18/ref/pg_verifybackup.sgml b/zh/18/ref/pg_verifybackup.sgml index a2afbec0..8678a81e 100644 --- a/zh/18/ref/pg_verifybackup.sgml +++ b/zh/18/ref/pg_verifybackup.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_verifybackup 1 - Application + 应用程序 @@ -32,9 +32,9 @@ PostgreSQL documentation pg_verifybackup用于依据服务器在备份时生成的 backup_manifest,检查使用 pg_basebackup获取的数据库集簇备份的完整性。备份 - 既可以采用“plain”格式,也可以采用“tar”格式;其中也包括使用 + 既可以采用“普通文件”格式,也可以采用“tar”格式;其中也包括使用 pg_basebackup支持的任意算法压缩的 tar 格 - 式备份。不过,目前仅支持对 plain 格式备份执行WAL + 式备份。不过,目前仅支持对 普通文件 格式备份执行WAL 验证。因此,如果备份采用 tar 格式存储,应使用 -n, --no-parse-wal选项。 @@ -42,8 +42,7 @@ PostgreSQL documentation 需要注意,pg_verifybackup执行的验证并未、也 不可能涵盖运行中的服务器在尝试使用该备份时会执行的每一项检查。即使使 - 用了此工具,你仍应进行测试恢复,并确认生成的数据库按预期工作且包含正 - 确的数据。不过,pg_verifybackup能够检测出 + 用了此工具,你仍应进行测试恢复,并确认生成的数据库按预期工作且看起来包含正确的数据。不过,pg_verifybackup能够检测出 许多因存储问题或用户错误而常见的问题。 @@ -141,9 +140,7 @@ PostgreSQL documentation tar - 备份由 tar 文件组成,这些文件可以经过压缩。有效的备份包括名为 - base.tar的主数据目录、名为 - pg_wal.tar的 WAL 文件,以及每个表空间 + 备份由 tar 文件组成,这些文件可以经过压缩。有效的备份包括存放在 base.tar文件中的主数据目录、存放在 pg_wal.tar中的 WAL 文件,以及每个表空间 对应的单独 tar 文件,这些文件以该表空间的 OID 命名。如果备份 被压缩,则会在每个文件名末尾追加相应的压缩扩展名。 @@ -237,9 +234,9 @@ PostgreSQL documentation - 还提供下列其他选项: + 其他选项也可用: - + @@ -270,7 +267,7 @@ PostgreSQL documentation 示例 - 要在mydbserver上创建服务器的基础备份,并验证该备 + 要为位于mydbserver的服务器创建基础备份,并验证该备 份的完整性: $ pg_basebackup -h mydbserver -D /usr/local/pgsql/data @@ -279,7 +276,7 @@ PostgreSQL documentation - 要在mydbserver上创建服务器的基础备份,将备份清单 + 要为位于mydbserver的服务器创建基础备份,将备份清单 移到备份目录之外的位置,然后验证该备份: $ pg_basebackup -h mydbserver -D /usr/local/pgsql/backup1234 diff --git a/zh/18/ref/pg_waldump.sgml b/zh/18/ref/pg_waldump.sgml index a4433e63..baa4bb42 100644 --- a/zh/18/ref/pg_waldump.sgml +++ b/zh/18/ref/pg_waldump.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_waldump 1 - Application + 应用程序 diff --git a/zh/18/ref/pg_walsummary.sgml b/zh/18/ref/pg_walsummary.sgml index b3abba5e..bbc7cd38 100644 --- a/zh/18/ref/pg_walsummary.sgml +++ b/zh/18/ref/pg_walsummary.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_walsummary 1 - Application + 应用程序 @@ -41,11 +41,11 @@ PostgreSQL documentation WAL 汇总文件按表空间 OID、关系 OID 以及关系分支(fork)建立索引。 对于每个关系分支,它都存储该文件所汇总范围内被 WAL 修改的块列表。 - 它还可以存储一个limit block: + 它还可以存储一个界限块: 如果该关系分支在相关 WAL 范围内被创建或截断,则其值为 0; 否则,其值为该关系分支被截断后的最短长度。 如果该关系分支在相关 WAL 范围内未被创建、删除或截断, - 则 limit block 未定义,或者为无穷大,本工具不会打印它。 + 则 界限块 未定义,或者为无穷大,本工具不会打印它。 @@ -107,9 +107,7 @@ PostgreSQL documentation 环境 - 环境变量PG_COLOR用于指定是否在诊断消息中使用颜色。 - 可能的值为alwaysauto和 - never。 + 环境变量PG_COLOR指定是否在诊断消息中使用颜色。可能的值为alwaysautonever diff --git a/zh/18/ref/pgarchivecleanup.sgml b/zh/18/ref/pgarchivecleanup.sgml index 5c2c0a53..fd4da23e 100644 --- a/zh/18/ref/pgarchivecleanup.sgml +++ b/zh/18/ref/pgarchivecleanup.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_archivecleanup 1 - Application + 应用程序 diff --git a/zh/18/ref/pgbench.sgml b/zh/18/ref/pgbench.sgml index cbade471..e0fa9e55 100644 --- a/zh/18/ref/pgbench.sgml +++ b/zh/18/ref/pgbench.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation pgbench 1 - Application + 应用程序 @@ -1685,7 +1685,7 @@ SELECT 4 AS four \; SELECT 5 AS five \aset greatest ( number , ... ) - double 如果任何参数是双精度的,否则 integer + 若任一参数为 double,则为 double,否则为 integer 选择参数中的最大值。 @@ -1755,7 +1755,7 @@ SELECT 4 AS four \; SELECT 5 AS five \aset least ( number , ... ) - double 如果任何参数是双精度的,否则 integer + 若任一参数为 double,则为 double,否则为 integer 选择参数中的最小值。 @@ -2602,7 +2602,7 @@ PGOPTIONS='-c default_table_access_method=wuzza' 安全性 - 如果不可信用户能够访问尚未采用模式的安全使用方式的数据库,就不要在该数据库中运行pgbenchpgbench使用非限定名称,并且不会更改搜索路径。 + 如果不受信任的用户能够访问尚未采用模式的安全使用方式的数据库,就不要在该数据库中运行pgbenchpgbench使用非限定名称,并且不会更改搜索路径。 diff --git a/zh/18/ref/pgtestfsync.sgml b/zh/18/ref/pgtestfsync.sgml index 86e69b30..6055bccf 100644 --- a/zh/18/ref/pgtestfsync.sgml +++ b/zh/18/ref/pgtestfsync.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_test_fsync 1 - Application + 应用程序 diff --git a/zh/18/ref/pgtesttiming.sgml b/zh/18/ref/pgtesttiming.sgml index f652980f..dc7208fc 100644 --- a/zh/18/ref/pgtesttiming.sgml +++ b/zh/18/ref/pgtesttiming.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_test_timing 1 - Application + 应用程序 diff --git a/zh/18/ref/pgupgrade.sgml b/zh/18/ref/pgupgrade.sgml index 33017708..8771b30c 100644 --- a/zh/18/ref/pgupgrade.sgml +++ b/zh/18/ref/pgupgrade.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_upgrade 1 - Application + 应用程序 @@ -40,7 +40,7 @@ PostgreSQL documentation pg_upgrade(以前称为 pg_migrator)允许将存储在 PostgreSQL 数据文件中的数据升级到更新的 PostgreSQL主版本,而无需执行主版本升级通常所需的数据转储/恢复, - 例如从 12.14 升级到 13.10,或从 14.9 升级到 15.5。它不用于次版本升级, + 例如从 12.14 升级到 13.10,或从 14.9 升级到 15.5。次版本升级不需要使用它, 例如从 12.7 升级到 12.8 或从 14.1 升级到 14.5。 @@ -340,7 +340,7 @@ PostgreSQL documentation 这里不介绍升级 - 逻辑复制集簇 + 逻辑复制集群 的步骤;详见 diff --git a/zh/18/ref/postgres-ref.sgml b/zh/18/ref/postgres-ref.sgml index b62740d6..a2e9456b 100644 --- a/zh/18/ref/postgres-ref.sgml +++ b/zh/18/ref/postgres-ref.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation postgres 1 - Application + 应用程序 @@ -532,7 +532,7 @@ PostgreSQL documentation - 表明另一台服务器已经在运行的失败消息 + 表明另一个服务器已经在运行的失败消息 应仔细检查,例如可根据你的系统使用下面的命令: $ ps ax | grep postgres @@ -721,7 +721,7 @@ PostgreSQL documentation - 参见 + 另见 , diff --git a/zh/18/ref/prepare.sgml b/zh/18/ref/prepare.sgml index 6c456821..20228fb4 100644 --- a/zh/18/ref/prepare.sgml +++ b/zh/18/ref/prepare.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation PREPARE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/prepare_transaction.sgml b/zh/18/ref/prepare_transaction.sgml index 10d018b0..75776dab 100644 --- a/zh/18/ref/prepare_transaction.sgml +++ b/zh/18/ref/prepare_transaction.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation PREPARE TRANSACTION 7 - SQL - Language Statements + SQL - 语言语句 @@ -72,7 +72,7 @@ PREPARE TRANSACTION transaction_id - 当前不允许将执行过以下任一操作的事务置为预备状态:涉及临时表或会话临时命名空间的操作、创建任何WITH HOLD游标,或执行过LISTENUNLISTENNOTIFY。这些特性与当前会话绑定得过于紧密,因此在要进入预备状态的事务中没有意义。 + 当前不允许对执行过以下任一操作的事务执行PREPARE:涉及临时表或会话临时命名空间的操作、创建任何WITH HOLD游标,或执行过LISTENUNLISTENNOTIFY。这些特性与当前会话绑定得过于紧密,因此在要进入预备状态的事务中没有意义。 diff --git a/zh/18/ref/psql-ref.sgml b/zh/18/ref/psql-ref.sgml index f7651da7..083bf93b 100644 --- a/zh/18/ref/psql-ref.sgml +++ b/zh/18/ref/psql-ref.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation psql 1 - Application + 应用程序 @@ -534,7 +534,7 @@ testdb=> - 如果不可信用户能够访问尚未采用模式的安全使用方式的数据库,请在会话开始时从search_path中移除所有公众可写的 schema。可以在连接字符串中加入options=-csearch_path=,或者在执行其他 SQL 命令之前发出SELECT pg_catalog.set_config('search_path', '', false)。这种考虑并非psql特有;它适用于任何执行任意 SQL 命令的接口。 + 如果不受信任的用户能够访问尚未采用模式的安全使用方式的数据库,请在会话开始时从search_path中移除所有公众可写的模式。可以在连接字符串中加入options=-csearch_path=,或者在执行其他 SQL 命令之前发出SELECT pg_catalog.set_config('search_path', '', false)。这种考虑并非psql特有;它适用于任何执行任意 SQL 命令的接口。 @@ -587,7 +587,7 @@ testdb=> - 定义了以下元命令: + 定义了以下元命令: @@ -686,7 +686,7 @@ INSERT INTO tbls1 VALUES ($1, $2) \parse stmt1 - 示例: + 示例: => \c mydb myuser host.dom 6432 @@ -1658,11 +1658,7 @@ CREATE INDEX - 生成的查询按照返回的行的顺序执行,并在每行内从左到右执行,如果有多个列。NULL字段将被忽略。生成的查询文字 - 直接发送到服务器进行处理,因此它们不能是psql元命令,也不能包含psql - 变量引用。如果任何单个查询失败,剩余查询的执行将继续,除非设置了ON_ERROR_STOP。每个查询的执行 - 都受ECHO处理的影响。(通常在使用\gexec时,将ECHO设置为 - allqueries是明智的。)查询记录、单步模式、计时和其他查询执行功能也适用于每个生成的查询。 + 生成的查询按照返回行的顺序执行;如果有多列,则在每行内从左到右执行。NULL 字段会被忽略。生成的查询按原样发送到服务器进行处理,因此不能是psql元命令,也不能包含psql变量引用。如果某个查询失败,仍会继续执行其余查询,除非设置了ON_ERROR_STOP。每个查询的执行都受ECHO处理的影响。(通常,在使用\gexec时,适宜将ECHO设为allqueries。)查询日志、单步模式、计时及其他查询执行功能也适用于每个生成的查询。 如果当前查询缓冲区为空,则重新执行最近发送的查询。 @@ -1902,7 +1898,7 @@ SELECT - 将文件存储到一个PostgreSQL大对象中。可选地,它将给定的注释与对象关联起来。例如: + 将文件存储到一个PostgreSQL大对象中。可选地,它将给定的注释与对象关联起来。例如: foo=> \lo_import '/home/peter/pictures/photo.xcf' 'a picture of me' lo_import 152801 @@ -2048,7 +2044,7 @@ SELECT $1 \parse stmt1 - 可调整打印选项有: + 可调整打印选项有: border @@ -2148,7 +2144,7 @@ SELECT $1 \parse stmt1 允许使用唯一缩写。 - aligned格式是标准的、人类可读的、格式良好的文本输出;这是默认设置。 + aligned格式是标准的、适合人阅读且排版整齐的文本输出;这是默认格式。 unaligned格式将一行中的所有列写在一行上,由当前活动的字段分隔符分隔。这对于创建可能被其他程序读取的输出很有用,例如,制表符分隔或逗号分隔格式。然而,如果字段分隔符字符出现在列的值中,则不会被特殊处理;因此,CSV格式可能更适合这些目的。 @@ -3329,7 +3325,7 @@ bar <acronym>SQL</acronym> 中插入变量 - psql变量的一个关键特性是可以把它们替换(插入)到常规SQL语句中,也可以把它们作为元命令的参数。此外,psql还提供了功能来确保被用作 SQL 文字和标识符的变量值会被正确地引用。插入一个值而不需要加引用的语法是在变量名前面加上一个冒号(:)。例如, + psql变量的一个关键特性是可以把它们替换(插入)到常规SQL语句中,也可以把它们作为元命令的参数。此外,psql还提供了功能来确保被用作 SQL 字面量和标识符的变量值会被正确地加引号。插入一个值而不加引号的语法是在变量名前面加上一个冒号(:)。例如, testdb=> \set foo 'my_table' testdb=> SELECT * FROM :foo; diff --git a/zh/18/ref/reassign_owned.sgml b/zh/18/ref/reassign_owned.sgml index 824834b8..ba7d9f7b 100644 --- a/zh/18/ref/reassign_owned.sgml +++ b/zh/18/ref/reassign_owned.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation REASSIGN OWNED 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/refresh_materialized_view.sgml b/zh/18/ref/refresh_materialized_view.sgml index 2ccb7ac0..7d0fed7a 100644 --- a/zh/18/ref/refresh_materialized_view.sgml +++ b/zh/18/ref/refresh_materialized_view.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation REFRESH MATERIALIZED VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/reindex.sgml b/zh/18/ref/reindex.sgml index cbc30ec6..46b00870 100644 --- a/zh/18/ref/reindex.sgml +++ b/zh/18/ref/reindex.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation REINDEX 7 - SQL - Language Statements + SQL - 语言语句 @@ -304,7 +304,7 @@ REINDEX [ ( option [, ...] ) ] { DA 当对分区索引或分区表执行带TABLESPACE子句的 REINDEX时,只有叶分区的表空间引用会被更新。由于 - 分区索引本身不会更新,建议另外对相应的分区表单独执行 + 分区索引本身不会更新,建议另外对这些分区索引单独执行 ALTER TABLE ONLY,以便后续附加的任何新分区都继承 新表空间。如果命令失败,可能不会把所有索引都移动到新表空间。重新运行 该命令将重建所有叶分区,并把先前未处理的索引移动到新表空间。 @@ -322,8 +322,8 @@ REINDEX [ ( option [, ...] ) ] { DA 并发重建索引 - index - rebuilding concurrently + 索引 + 并发重建 diff --git a/zh/18/ref/reindexdb.sgml b/zh/18/ref/reindexdb.sgml index 20dc32bf..5fc8edd5 100644 --- a/zh/18/ref/reindexdb.sgml +++ b/zh/18/ref/reindexdb.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation reindexdb 1 - Application + 应用程序 diff --git a/zh/18/ref/release_savepoint.sgml b/zh/18/ref/release_savepoint.sgml index 59f96e68..ca94cc38 100644 --- a/zh/18/ref/release_savepoint.sgml +++ b/zh/18/ref/release_savepoint.sgml @@ -10,13 +10,13 @@ PostgreSQL documentation 保存点 - releasing + 释放 RELEASE SAVEPOINT 7 - SQL - Language Statements + SQL - 语言语句 @@ -99,7 +99,7 @@ BEGIN; SAVEPOINT sp2; INSERT INTO table1 VALUES (3); RELEASE SAVEPOINT sp2; - INSERT INTO table1 VALUES (4))); -- generates an error + INSERT INTO table1 VALUES (4))); -- 产生错误 在这个例子中,应用程序请求释放保存点sp2,值 3 是在其中插入的。 这样会把该插入操作的事务上下文改为sp1。 diff --git a/zh/18/ref/reset.sgml b/zh/18/ref/reset.sgml index e8aeae8c..5e249ff9 100644 --- a/zh/18/ref/reset.sgml +++ b/zh/18/ref/reset.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation RESET 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/revoke.sgml b/zh/18/ref/revoke.sgml index 8d7945a5..c2d7aee8 100644 --- a/zh/18/ref/revoke.sgml +++ b/zh/18/ref/revoke.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation REVOKE 7 - SQL - Language Statements + SQL - 语言语句 @@ -131,7 +131,7 @@ REVOKE [ { ADMIN | INHERIT | SET } OPTION FOR ] [ GRANTED BY role_specification ] [ CASCADE | RESTRICT ] -where role_specification can be: +其中role_specification可以是: [ GROUP ] role_name | PUBLIC diff --git a/zh/18/ref/rollback.sgml b/zh/18/ref/rollback.sgml index d1c8fdd2..1a91b03e 100644 --- a/zh/18/ref/rollback.sgml +++ b/zh/18/ref/rollback.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ROLLBACK 7 - SQL - Language Statements + SQL - 语言语句 @@ -37,7 +37,7 @@ ROLLBACK [ WORK | TRANSACTION ] [ AND [ NO ] CHAIN ] 参数 - chained transactions + 链式事务 diff --git a/zh/18/ref/rollback_prepared.sgml b/zh/18/ref/rollback_prepared.sgml index 7ffe1af8..7438d9cc 100644 --- a/zh/18/ref/rollback_prepared.sgml +++ b/zh/18/ref/rollback_prepared.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ROLLBACK PREPARED 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/rollback_to.sgml b/zh/18/ref/rollback_to.sgml index 843a612e..d5d8c0e0 100644 --- a/zh/18/ref/rollback_to.sgml +++ b/zh/18/ref/rollback_to.sgml @@ -10,13 +10,13 @@ PostgreSQL documentation 保存点 - rolling back + 回滚 ROLLBACK TO SAVEPOINT 7 - SQL - Language Statements + SQL - 语言语句 @@ -73,8 +73,8 @@ ROLLBACK [ WORK | TRANSACTION ] TO [ SAVEPOINT ] savepoint_name 就保存点而言,游标带有一些非事务性的行为。凡是在某个保存点内打开的游标, 在回滚该保存点时都会被关闭。如果先前打开的游标在某个随后又被回滚的保存点内受到了 - FETCHMOVE命令的影响,那么该游标会保留在这些命令使其指向的位置上 - (也就是说,由FETCHMOVE引起的游标移动不会被回滚)。 + FETCHMOVE命令的影响,那么该游标会保留在FETCH使其指向的位置上 + (也就是说,由FETCH引起的游标移动不会被回滚)。 关闭游标同样不会因回滚而撤销。不过,如果游标查询导致了其他副作用(例如该查询调用的 易变函数带来的副作用),且这些副作用发生在后来被回滚的保存点期间,那么它们 被回滚。如果某个游标的执行导致事务中止,该游标会进入不可执行状态, diff --git a/zh/18/ref/savepoint.sgml b/zh/18/ref/savepoint.sgml index fdca4151..5f9bea25 100644 --- a/zh/18/ref/savepoint.sgml +++ b/zh/18/ref/savepoint.sgml @@ -10,13 +10,13 @@ PostgreSQL documentation 保存点 - defining + 定义 SAVEPOINT 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/security_label.sgml b/zh/18/ref/security_label.sgml index fc969a4a..9c2b13d0 100644 --- a/zh/18/ref/security_label.sgml +++ b/zh/18/ref/security_label.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SECURITY LABEL 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/select.sgml b/zh/18/ref/select.sgml index 1b47aa6d..19abe844 100644 --- a/zh/18/ref/select.sgml +++ b/zh/18/ref/select.sgml @@ -21,7 +21,7 @@ PostgreSQL documentation SELECT 7 - SQL - Language Statements + SQL - 语言语句 @@ -1485,7 +1485,7 @@ SELECT * FROM (SELECT * FROM mytable FOR UPDATE) ss ORDER BY column1; REPEATABLE READSERIALIZABLE事务隔离级别下, - 这将导致序列化失败(带有SQLSTATE'40001'), + 这将导致串行化失败(SQLSTATE'40001'), 因此在这些隔离级别下不可能接收到无序的行。 diff --git a/zh/18/ref/select_into.sgml b/zh/18/ref/select_into.sgml index a05e57e8..12a48774 100644 --- a/zh/18/ref/select_into.sgml +++ b/zh/18/ref/select_into.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SELECT INTO 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/set.sgml b/zh/18/ref/set.sgml index ab67075e..9702d560 100644 --- a/zh/18/ref/set.sgml +++ b/zh/18/ref/set.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SET 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/set_constraints.sgml b/zh/18/ref/set_constraints.sgml index 53d0c7a0..e5588db7 100644 --- a/zh/18/ref/set_constraints.sgml +++ b/zh/18/ref/set_constraints.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SET CONSTRAINTS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/set_role.sgml b/zh/18/ref/set_role.sgml index ed65dec8..c32755be 100644 --- a/zh/18/ref/set_role.sgml +++ b/zh/18/ref/set_role.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SET ROLE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/set_session_auth.sgml b/zh/18/ref/set_session_auth.sgml index e520dd49..e7692edc 100644 --- a/zh/18/ref/set_session_auth.sgml +++ b/zh/18/ref/set_session_auth.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SET SESSION AUTHORIZATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/set_transaction.sgml b/zh/18/ref/set_transaction.sgml index ca7f3e50..8b3470a9 100644 --- a/zh/18/ref/set_transaction.sgml +++ b/zh/18/ref/set_transaction.sgml @@ -26,7 +26,7 @@ PostgreSQL documentation SET TRANSACTION 7 - SQL - Language Statements + SQL - 语言语句 @@ -66,7 +66,7 @@ SET SESSION CHARACTERISTICS AS TRANSACTION transa - 一个事务的隔离级别决定当其他事务并行运行时该事务能看见什么数据: + 一个事务的隔离级别决定当其他事务并发运行时该事务能看见什么数据: @@ -137,7 +137,7 @@ SET SESSION CHARACTERISTICS AS TRANSACTION transa 事务属性才会生效。当为一个事务同时选择这三个属性时,该事务在 首次获取其快照时可能会阻塞;在此之后,它便可以运行,而无需承担普通 SERIALIZABLE事务的常规开销,也不会有促成 - 序列化失败或因序列化失败而被取消的风险。这种模式非常适合长时间运行的 + 串行化失败或因串行化失败而被取消的风险。这种模式非常适合长时间运行的 报表或备份。 diff --git a/zh/18/ref/show.sgml b/zh/18/ref/show.sgml index 3b4be6bd..81bd6a80 100644 --- a/zh/18/ref/show.sgml +++ b/zh/18/ref/show.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SHOW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/start_transaction.sgml b/zh/18/ref/start_transaction.sgml index 57a74b2f..5026fa70 100644 --- a/zh/18/ref/start_transaction.sgml +++ b/zh/18/ref/start_transaction.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation START TRANSACTION 7 - SQL - Language Statements + SQL - 语言语句 @@ -64,15 +64,16 @@ START TRANSACTION [ transaction_mode - DEFERRABLE 这一 - transaction_mode 是 - PostgreSQL语言扩展。 + DEFERRABLE + transaction_mode + 是PostgreSQL的一种语言扩展。 SQL 标准要求在连续的transaction_modes之间有逗号, - 但出于历史原因PostgreSQL允许省略逗号。 + 但出于历史原因, + PostgreSQL允许省略逗号。 diff --git a/zh/18/ref/truncate.sgml b/zh/18/ref/truncate.sgml index aa2ce51c..ff1e0bc9 100644 --- a/zh/18/ref/truncate.sgml +++ b/zh/18/ref/truncate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation TRUNCATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/unlisten.sgml b/zh/18/ref/unlisten.sgml index 5e73e99e..6b52f1af 100644 --- a/zh/18/ref/unlisten.sgml +++ b/zh/18/ref/unlisten.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation UNLISTEN 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/ref/update.sgml b/zh/18/ref/update.sgml index a3c965df..4ace7c49 100644 --- a/zh/18/ref/update.sgml +++ b/zh/18/ref/update.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation UPDATE 7 - SQL - Language Statements + SQL - 语言语句 @@ -313,12 +313,12 @@ UPDATE count 在被移动的行上并发执行UPDATE或 - DELETE时,有可能收到序列化失败错误。假设会话 1 - 正在更新某个分区键,与此同时,一个对该行可见的并发会话 2 对该行 + DELETE时,有可能收到串行化失败错误。假设会话 1 + 正在对某个分区键执行UPDATE,与此同时,一个能够看到该行的并发会话 2 对该行 执行UPDATEDELETE操作。在 这种情况下,会话 2 的UPDATE或 - DELETE将检测到行移动,并引发序列化失败错误 - (其 SQLSTATE 代码始终为'40001')。如果发生 + DELETE将检测到行移动,并引发串行化失败错误 + (其 SQLSTATE 代码始终为'40001')。如果发生 这种情况,应用程序可能需要重试事务。在表未分区或没有发生行移动 的通常情况下,会话 2 会识别出新更新的那一行,并在这个新行版本上执行 UPDATE/DELETE。 diff --git a/zh/18/ref/vacuum.sgml b/zh/18/ref/vacuum.sgml index 06c73baa..35e793c4 100644 --- a/zh/18/ref/vacuum.sgml +++ b/zh/18/ref/vacuum.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation VACUUM 7 - SQL - Language Statements + SQL - 语言语句 @@ -75,7 +75,7 @@ VACUUM [ ( option [, ...] ) ] [ 并行清理。 - 如需禁用该功能,可以使用PARALLEL选项并将并行工作者数指定为零。 + 如需禁用该功能,可以使用PARALLEL选项并将并行工作进程数指定为零。 VACUUM FULL会把表的全部内容重写到一个没有额外空闲空间的新磁盘文件中, 从而让未使用的空间能够返还给操作系统。这种形式要慢得多,并且在处理每个表时都需要 ACCESS EXCLUSIVE锁。 @@ -374,7 +374,7 @@ VACUUM [ ( option [, ...] ) ] [ - 我们建议定期对所有数据库执行清理,以移除死行。PostgreSQL提供了一个autovacuum机制, + 我们建议定期对所有数据库执行清理,以移除死行。PostgreSQL提供了一个自动清理(autovacuum)机制, 可以自动执行常规清理维护。有关自动与手动清理的更多信息,参见 @@ -392,8 +392,8 @@ VACUUM [ ( option [, ...] ) ] [ VACUUM会显著增加 I/O 流量,这可能导致其他活动会话性能变差。 - 因此,有时建议使用基于代价的清理延迟特性。对于并行清理,每个工作者的睡眠时长 - 都与该工作者完成的工作量成比例。详见。 + 因此,有时建议使用基于代价的清理延迟特性。对于并行清理,每个工作进程的睡眠时长 + 都与该工作进程完成的工作量成比例。详见 @@ -409,7 +409,7 @@ VACUUM [ ( option [, ...] ) ] [ 示例 - 清理单个表onek,对其执行优化器分析,并打印详细的清理活动报告: + 清理单个表onek,对其进行分析以供优化器使用,并打印详细的清理活动报告: VACUUM (VERBOSE, ANALYZE) onek; diff --git a/zh/18/ref/vacuumdb.sgml b/zh/18/ref/vacuumdb.sgml index 4396e2e0..b41769e6 100644 --- a/zh/18/ref/vacuumdb.sgml +++ b/zh/18/ref/vacuumdb.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation vacuumdb 1 - Application + 应用程序 @@ -132,8 +132,8 @@ PostgreSQL documentation - 指定给定一次 缓冲区访问策略(Buffer Access Strategy) - 环形缓冲区大小,供 vacuumdb 调用使用。这个大小用于计算将作为该策略一部分被重用的共享缓冲区数量。参见 + 为一次给定的 vacuumdb 调用指定缓冲区访问策略(Buffer Access Strategy) + 环形缓冲区大小。这个大小用于计算将作为该策略一部分被重用的共享缓冲区数量。参见 @@ -187,7 +187,7 @@ PostgreSQL documentation - 积极地冻结元组。 + 激进地冻结元组。 @@ -225,12 +225,12 @@ PostgreSQL documentation - 仅对 multixact ID 年龄至少为 mxid_age - 的表执行清理或分析命令。此设置可用于优先处理表,以防止 multixact ID 回卷 + 仅对 多事务 ID 年龄至少为 mxid_age + 的表执行清理或分析命令。此设置可用于优先处理表,以防止 多事务 ID 回卷 (见 )。 - 就此选项而言,一个关系的 multixact ID 年龄,是其主关系及其关联的 + 就此选项而言,一个关系的 多事务 ID 年龄,是其主关系及其关联的 TOAST 表(如果存在)年龄中的较大者。由于 vacuumdb 发出的命令在必要时也会处理该关系的 TOAST 表,因此无需单独考虑它。 diff --git a/zh/18/ref/values.sgml b/zh/18/ref/values.sgml index e5b00372..8c6d7597 100644 --- a/zh/18/ref/values.sgml +++ b/zh/18/ref/values.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation VALUES 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/18/release-18.sgml b/zh/18/release-18.sgml index 86fa3493..a4f8985f 100644 --- a/zh/18/release-18.sgml +++ b/zh/18/release-18.sgml @@ -2175,14 +2175,14 @@ Branch: REL_14_STABLE [15fd7a3e2] 2026-07-28 10:56:39 +0200 --> - 在清理 GIN 索引 posting-tree 期间响应查询取消并遵守清理延迟 + 在清理 GIN 索引倒排树期间响应查询取消并遵守清理延迟 (Paul Kim、Alexander Korotkov) § - 常见值的 posting tree 可能很大,因此遗漏这项检查可能导致清理运行 + 常见值的倒排树可能很大,因此遗漏这项检查可能导致清理运行 很长时间后才注意到中断。 @@ -4345,7 +4345,7 @@ Branch: REL_15_STABLE [bab4f7fa5] 2026-05-05 10:32:42 +0900 Branch: REL_14_STABLE [172034f6e] 2026-05-05 10:34:07 +0900 --> - 在假定可排序类型上的等值条件意味着唯一性之前,检查是否存在非确定性排序规则 + 在假定支持排序规则的类型上的等值条件意味着唯一性之前,检查是否存在非确定性排序规则 (Richard Guo) § § @@ -6146,12 +6146,12 @@ Branch: master [889676a0d] 2026-01-16 14:53:50 +0900 Branch: REL_18_STABLE [f335457e8] 2026-01-16 14:53:32 +0900 --> - 修正属于非关系范围条目的行标记的不正确浏览, 如子序列( Dean Rasheed) + 修正属于非关系范围条目的行标记的不正确浏览, 如子序列( Dean Rasheed) § - 如果需要通过EvalPlanQual的重新检查来修改拟议的行更新,结果就会不正确,如果该行同时更新,情况也可能如此。 + 如果需要通过EvalPlanQual的重新检查来修改拟议的行更新,结果就会不正确,如果该行同时更新,情况也可能如此。 @@ -6196,12 +6196,12 @@ Branch: master [6dfce8420] 2025-12-05 20:10:33 -0500 Branch: REL_18_STABLE [18b349315] 2025-12-05 20:10:33 -0500 --> - 修正文本子字符串搜索, 用于非决定性的整理( Laurenz Albe) + 修正文本子字符串搜索, 用于非决定性的整理( Laurenz Albe) § - 在使用非决定性的整理时,我们未能发现在搜索字符串的末尾发生的匹配. + 在使用非决定性的整理时,我们未能发现在搜索字符串的末尾发生的匹配。 @@ -6238,7 +6238,7 @@ Branch: REL_18_STABLE [382ce9cb7] 2025-12-25 12:15:09 +0900 - 在构建ProjectSet计划节点时,计划员未能发现涉及分组表达式的子表达式已经由输入计划计算出来. 这导致了计划效率低下或错误,例如: 子计划目标列表中找不到的变量. + 在构建ProjectSet计划节点时,计划员未能发现涉及分组表达式的子表达式已经由输入计划计算出来。这导致了计划效率低下或错误,例如:子计划目标列表中找不到的变量 @@ -7377,7 +7377,7 @@ Branch: REL_18_STABLE [580b5c2f3] 2025-12-11 14:11:25 +0900 - 代码分配的内存是NUMA页面状态需要的两倍. + 代码分配的内存是NUMA页面状态需要的两倍。 @@ -7592,7 +7592,7 @@ Branch: REL_18_STABLE [ef6168baf] 2025-10-30 12:03:15 +0900 - 由于赛事条件,该案例在更新加盟共享散列表时无法可靠工作. + 由于在更新连接的共享哈希表时存在竞态条件,该情况无法可靠工作。 @@ -7608,7 +7608,7 @@ Branch: REL_18_STABLE [500f64636] 2025-11-05 18:15:02 +0900 - 这种错误可能导致错误选择最便宜的路径,或导致调试构建中的断言失败. + 这种错误可能导致错误选择最便宜的路径,或导致调试构建中的断言失败。 @@ -7624,7 +7624,7 @@ Branch: REL_18_STABLE [74197bdc8] 2025-10-28 10:11:35 +0100 - 这种疏忽导致了错误,比如: 没有返回仅用于索引扫描的数据。 。 。 案件不会出现任何核心指数类型,但有些扩展遇到了问题。 + 这种疏忽导致了错误,比如: 没有返回仅用于索引扫描的数据。 。 。 案件不会出现任何核心指数类型,但有些扩展遇到了问题。 @@ -7743,8 +7743,7 @@ Branch: master [5c0a20003] 2025-10-18 16:07:04 +1300 Branch: REL_18_STABLE [0b6a02f03] 2025-10-18 16:07:41 +1300 --> - 处理散列时修复罕见的崩溃 GROUPING - SETS queries (David Rowley) + 修复处理带哈希的 GROUPING SETS 查询时罕见的崩溃(David Rowley) § @@ -7761,7 +7760,7 @@ Branch: REL_18_STABLE [aa151022e] 2025-10-17 22:27:49 +0200 - Hash加入有时会使用比预期更多的内存,或者未能以高效的方式进行分割. + 哈希连接有时会使用比预期更多的内存,或者未能以高效的方式划分这些内存。 @@ -8323,7 +8322,7 @@ Branch: REL_13_STABLE [d20df9590] 2025-10-18 17:50:10 +0200 - 确保这些数据库对象的顺序一致,如对其他对象类型所做的那样。 + 确保这些数据库对象的顺序一致,如对其他对象类型所做的那样。 @@ -10769,7 +10768,7 @@ Author: Robert Haas - 添加函数 PQfullProtocolVersion() 以报告完整的(包括次要版本)协议版本号(Jacob Champion, Jelte Fennema-Nio) § + 添加函数 PQfullProtocolVersion() 以报告完整的(包括次要版本)协议版本号(Jacob Champion, Jelte Fennema-Nio) § diff --git a/zh/18/runtime.sgml b/zh/18/runtime.sgml index f10efd39..9e48148e 100644 --- a/zh/18/runtime.sgml +++ b/zh/18/runtime.sgml @@ -17,7 +17,7 @@ <productname>PostgreSQL</productname>用户账户 - postgres user + postgres 用户 @@ -47,7 +47,7 @@ - 在做任何事情之前,必须先在磁盘上初始化一个数据库存储区域。我们把它称为数据库集簇。(SQL 标准使用术语 catalog cluster。)数据库集簇是由一个正在运行的数据库服务器实例管理的一组数据库。初始化之后,数据库集簇中会包含一个名为postgres的数据库,作为供工具、用户和第三方应用使用的默认数据库。数据库服务器本身并不要求该postgres数据库存在,但许多外部工具程序都假定它存在。初始化期间,集簇中还会创建另外两个数据库,名为template1template0。顾名思义,它们会作为后续新建数据库的模板;不应将它们用于实际工作。(关于在集簇中创建新数据库的信息,见。) + 在做任何事情之前,必须先在磁盘上初始化一个数据库存储区域。我们把它称为数据库集簇。(SQL 标准使用术语目录集簇(catalog cluster)。)数据库集簇是由一个正在运行的数据库服务器实例管理的一组数据库。初始化之后,数据库集簇中会包含一个名为postgres的数据库,作为供工具、用户和第三方应用使用的默认数据库。数据库服务器本身并不要求该postgres数据库存在,但许多外部工具程序都假定它存在。初始化期间,集簇中还会创建另外两个数据库,名为template1template0。顾名思义,它们会作为后续新建数据库的模板;不应将它们用于实际工作。(关于在集簇中创建新数据库的信息,见。) @@ -112,9 +112,7 @@ postgres$ initdb -D /usr/local/pgsql/data 另外,指定,以避免使用默认的trust认证方式;或者在运行initdb之后、首次启动服务器之前修改生成的pg_hba.conf文件。(其他合理方法包括使用peer认证,或使用文件系统权限限制连接。更多信息见。) - - initdb还会为数据库集簇初始化默认区域设置locale。通常,它只是采用环境中的区域设置,并将其应用到新初始化的数据库。你也可以为数据库指定不同的区域设置;更多信息见。该数据库集簇内部使用的默认排序顺序由initdb设定。虽然你可以创建采用不同排序顺序的新数据库,但initdb创建的模板数据库所使用的排序顺序,若不删除并重建它们就无法更改。使用非CPOSIX区域设置还会带来性能影响,因此第一次就做出正确选择很重要。 - + initdb 还会初始化数据库集簇的默认区域设置区域设置。通常,它会直接采用环境中的区域设置,并将其应用于初始化的数据库。可以为数据库指定不同的区域设置;更多信息见 。特定数据库集簇中使用的默认排序顺序由 initdb 设置,虽然你可以使用不同的排序顺序创建新数据库,但 initdb 创建的模板数据库所使用的顺序,只有删除并重建这些数据库才能更改。使用 CPOSIX 以外的区域设置还会影响性能。因此,一开始就作出正确选择很重要。 initdb还会为数据库集簇设置默认字符集编码。通常应选择与区域设置相匹配的字符集编码。详见。 @@ -162,9 +160,7 @@ postgres$ initdb -D /usr/local/pgsql/data 对于在PostgreSQL中使用NFS,唯一硬性要求是文件系统必须使用hard选项挂载。使用hard选项时,如果出现网络问题,进程可能会无限期地挂起,因此这种配置需要配套谨慎的监控措施。soft选项会在网络问题出现时中断系统调用,但PostgreSQL不会重试以这种方式被中断的系统调用,因此任何此类中断都会导致报告 I/O 错误。 - - 没有必要使用sync挂载选项。async选项的行为已经足够,因为PostgreSQL会在适当的时候发出fsync调用来刷新写缓存。(这和它在本地文件系统上的工作方式类似。)但是,强烈建议在支持该选项的NFS服务器端系统上使用sync导出选项(主要是 Linux)。否则,NFS 客户端上的fsync或等效操作实际上并不能保证数据到达服务器上的持久存储,这可能导致类似于将参数设为关闭时那样的损坏。这些挂载和导出选项的默认值在不同厂商和版本间并不相同,因此无论如何都建议检查它们,并且最好显式指定,以避免歧义。 - + 没有必要使用 sync 挂载选项。async 选项的行为已经足够,因为 PostgreSQL 会在适当的时候发出 fsync 调用将写缓存刷盘。(这和它在本地文件系统上的工作方式类似。)但是,强烈建议在支持该选项的 NFS 服务器端系统上使用 sync 导出选项(主要是 Linux)。否则,NFS 客户端上的 fsync 或等效操作实际上并不能保证数据到达服务器上的持久存储,这可能导致类似于将参数 设为关闭时那样的损坏。这些挂载和导出选项的默认值在不同厂商和版本间并不相同,因此无论如何都建议检查它们,并且最好显式指定,以避免歧义。 在某些情况下,可以通过 NFS 或更底层的协议(例如 iSCSI)访问外部存储产品。在后一种情况下,存储会表现为块设备,可以在其上创建任意可用的文件系统。这种方式或许能让 DBA 不必应对 NFS 的某些特性,但当然,管理远程存储的复杂性会转移到其他层面。 @@ -215,7 +211,7 @@ pg_ctl start -l logfile - 通常,你会希望在计算机启动时就启动数据库服务器。booting启动服务器时自动启动脚本依赖于操作系统。PostgreSQLcontrib/start-scripts 目录中附带了一些示例脚本。安装这些脚本需要 root 权限。 + 通常,你会希望在计算机启动时就启动数据库服务器。引导期间启动服务器自动启动脚本依赖于操作系统。PostgreSQLcontrib/start-scripts 目录中附带了一些示例脚本。安装这些脚本需要 root 权限。 @@ -232,14 +228,14 @@ su postgres -c 'pg_ctl start -D /usr/local/pgsql/data -l serverlog' 对于FreeBSD,请查看PostgreSQL源码发布包中的contrib/start-scripts/freebsd文件。 - FreeBSDstart script + FreeBSD启动脚本 OpenBSD上,把以下内容加入/etc/rc.local: - OpenBSDstart script + OpenBSD启动脚本 if [ -x /usr/local/pgsql/bin/pg_ctl -a -x /usr/local/pgsql/bin/postgres ]; then su -l postgres -c '/usr/local/pgsql/bin/pg_ctl start -s -l /var/postgresql/log -D /usr/local/pgsql/data' @@ -252,7 +248,7 @@ fi Linux系统上,可以把 - Linuxstart script + Linux启动脚本 /usr/local/pgsql/bin/pg_ctl start -l logfile -D /usr/local/pgsql/data @@ -291,14 +287,14 @@ WantedBy=multi-user.target NetBSD上,可根据偏好使用FreeBSDLinux的启动脚本。 - NetBSDstart script + NetBSD启动脚本 Solaris上,创建一个名为/etc/init.d/postgresql的文件,其中包含以下内容: - Solarisstart script + Solaris启动脚本 su - postgres -c "/usr/local/pgsql/bin/pg_ctl start -l logfile -D /usr/local/pgsql/data" @@ -395,7 +391,7 @@ psql: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: No such 管理内核资源 - PostgreSQL有时会耗尽操作系统的各种资源限制,尤其是在同一系统上运行多个服务器副本,或在非常大型的安装环境中时更是如此。本节解释PostgreSQL使用的内核资源,以及你可以采取哪些步骤来解决与内核资源消耗相关的问题。 + PostgreSQL有时会达到操作系统的各种资源上限,尤其是在同一系统上运行多个服务器实例,或在非常大型的安装环境中时更是如此。本节解释PostgreSQL使用的内核资源,以及你可以采取哪些步骤来解决与内核资源消耗相关的问题。 @@ -419,7 +415,7 @@ psql: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: No such - System V IPC 功能通常受系统范围的分配限制约束。当PostgreSQL超出这些限制之一时,服务器会拒绝启动,并留下带有指导性的错误消息,说明问题所在以及应如何处理(另见)。相关内核参数在不同系统上的命名基本一致,给出了概览;不过,设置它们的方法却各不相同。下面给出一些平台上的建议。 + System V IPC 功能通常受系统范围的分配限制约束。当PostgreSQL超出这些限制之一时,服务器会拒绝启动,并应留下带有指导性的错误消息,说明问题所在以及应如何处理(另见)。相关内核参数在不同系统上的命名基本一致,给出了概览;不过,设置它们的方法却各不相同。下面给出一些平台上的建议。
@@ -444,7 +440,7 @@ psql: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: No such SHMMAX 共享内存段的最大尺寸(字节) - 至少 1kB,但是默认值通常要高一些 + 至少 1kB,但是默认值通常高得多 @@ -507,8 +503,8 @@ psql: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: No such
- PostgreSQL要求少量字节的 System V 共享内存(在 64 位平台上通常是 48 字节)用于每一个服务器拷贝。在大多数现代操作系统上,这个量很容易得到。 - 但是,如果你运行了很多个服务器副本,或者显式配置服务器以使用大量 System V 共享内存(参见 ), + PostgreSQL要求少量字节的 System V 共享内存(在 64 位平台上通常是 48 字节)用于每一个服务器实例。在大多数现代操作系统上,这个量很容易得到。 + 但是,如果你运行了很多个服务器实例,或者显式配置服务器以使用大量 System V 共享内存(参见 ), 可能需要增加SHMALL(系统范围内 System V 共享内存的总量)。注意在很多系统上SHMALL是以页面而不是字节来度量。 @@ -517,14 +513,14 @@ psql: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: No such
- 当使用 System V 信号量时,PostgreSQL会为每个允许连接()、每个允许自动清理工作进程()、每个允许 WAL 发送进程()、每个允许后台进程()等分配一个信号量,按 16 个一组。运行期计算参数会报告所需信号量数;可在启动服务器前用如下命令查看: + 当使用 System V 信号量时,PostgreSQL会为每个允许连接()、每个允许自动清理工作进程()、每个允许 WAL 发送进程()、每个允许后台进程()等分配一个信号量,按 16 个一组。运行期计算参数会报告所需信号量数;可在启动服务器前用如下postgres命令查看: $ postgres -D $PGDATA -C num_os_semaphores - 每组 16 个信号量还包含第 17 个信号量,用于存放magic number,以检测与其他应用信号量集合的冲突。系统最大信号量数由 SEMMNS 设定,因此至少应为 num_os_semaphores 加上每组 16 个所需信号量的一个附加量(见中的公式)。SEMMNI决定系统中同一时刻可存在的信号量集合数上限,因此至少应为 ceil(num_os_semaphores / 16)。降低允许连接数是对通常带有误导措辞设备上没有剩余空间(来自semget)这类失败的临时缓解手段。 + 每组 16 个信号量还包含第 17 个信号量,用于存放魔数,以检测与其他应用信号量集合的冲突。系统最大信号量数由 SEMMNS 设定,因此至少应为 num_os_semaphores 加上每组 16 个所需信号量的一个附加量(见中的公式)。SEMMNI决定系统中同一时刻可存在的信号量集合数上限,因此至少应为 ceil(num_os_semaphores / 16)。降低允许连接数是对通常带有误导措辞No space left on device(来自semget)这类失败的临时缓解手段。 @@ -532,7 +528,7 @@ $ postgres -D $PGDATA -C num_os_semaphores - 与semaphore undo有关的其他各种设置,如SEMMNUSEMUME,不会影响PostgreSQL。 + 与信号量撤销有关的其他各种设置,如SEMMNUSEMUME,不会影响PostgreSQL @@ -630,7 +626,7 @@ $ postgres -D $PGDATA -C num_os_semaphores - 共享内存大小设置可以通过sysctl界面更改。例如,允许 16 GB: + 共享内存大小设置可以通过sysctl接口更改。例如,允许 16 GB: $ sysctl -w kernel.shmmax=17179869184 $ sysctl -w kernel.shmall=4194304 @@ -668,9 +664,7 @@ kern.sysv.shmall=1024 SHMMAX 只能设置为 4096 的倍数。 - - 在这个平台上,SHMALL以 4kB 的页面度量。 - + 在这个平台上,SHMALL 以 4 kB 的页为单位。 SHMMNI 之外,其他设置都可以使用 sysctl 动态更改。不过,最好还是通过/etc/sysctl.conf设置你希望使用的值,这样重启后仍能保留。 @@ -685,7 +679,7 @@ kern.sysv.shmall=1024 - 默认的共享内存和信号量设置对于大多数 PostgreSQL 应用通常已经足够。Solaris 现在将SHMMAX的默认值设为系统 RAM 的四分之一。要进一步调整这一设置,可使用与postgres用户关联的项目设置。例如,以root运行下列命令: + 默认的共享内存和信号量设置对于大多数 PostgreSQL 应用通常已经足够。Solaris 将SHMMAX的默认值设为系统 RAM 的四分之一。要进一步调整这一设置,可使用与postgres用户关联的项目设置。例如,以root运行下列命令: projadd -c "PostgreSQL DB User" -K "project.max-shm-memory=(privileged,8GB,deny)" -U postgres -G postgres user.postgres @@ -740,7 +734,7 @@ WARNING: could not remove shared memory segment "/PostgreSQL.1450751626": No su - 用户注销可能会作为维护作业的一部分发生,也可能在管理员以postgres用户或类似名称登录时手工触发,因此通常很难彻底防止。 + 用户注销可能会作为维护作业的一部分发生,也可能在管理员以postgres用户登录或执行类似操作时手工触发,因此通常很难彻底防止。 @@ -821,7 +815,7 @@ default:\ Linux 内存过量分配 - memory overcommit + 内存过量分配 @@ -829,7 +823,7 @@ default:\ - overcommit + 过量分配 @@ -849,7 +843,7 @@ Out of Memory: Killed process 12345 (postgres). - 如果导致系统耗尽内存的正是PostgreSQL自身,那么你可以通过调整配置来避免该问题。在某些情况下,调低与内存相关的配置参数会有帮助,尤其是shared_bufferswork_memhash_mem_multiplier。在其他情况下,允许数据库服务器接受过多连接也可能导致这一问题。很多时候,更好的做法是减小max_connections,并转而使用外部连接池软件。 + 如果导致系统耗尽内存的正是PostgreSQL自身,那么你可以通过调整配置来避免该问题。在某些情况下,调低与内存相关的配置参数会有帮助,尤其是shared_bufferswork_memhash_mem_multiplier。在其他情况下,允许数据库服务器接受过多连接也可能导致这一问题。很多时候,更好的做法可能是减小max_connections,并转而使用外部连接池软件。 @@ -861,17 +855,25 @@ sysctl -w vm.overcommit_memory=2 - 另一种方法可在修改或不修改 vm.overcommit_memory 的情况下使用:把 PostgreSQL 主进程的 OOM score adjustment 值设为 -1000,从而保证它不会成为 OOM 杀手的目标。最简单的做法是在 PostgreSQL 启动脚本中、调用 postgres 之前执行以下命令: + 另一种方法可在修改或不修改 vm.overcommit_memory 的情况下使用: + 把 postmaster 进程专属的OOM 评分调整值设为 -1000, + 从而保证它不会成为 OOM 杀手的目标。最简单的做法是在 PostgreSQL + 启动脚本中、调用 postgres 之前执行: echo -1000 > /proc/self/oom_score_adj - 请注意,这个操作必须以 root 身份完成,否则不会生效。因此,最容易放置该操作的位置是由 root 拥有的启动脚本。如果这样做,你还应该在调用 postgres 之前,在启动脚本中设置这些环境变量: + 请注意,这个操作必须以 root 身份完成,否则不会生效;因此,由 root 拥有的启动脚本是最容易执行该操作的位置。 + 如果这样做,还应在调用 postgres 之前,在启动脚本中设置以下环境变量: export PG_OOM_ADJUST_FILE=/proc/self/oom_score_adj export PG_OOM_ADJUST_VALUE=0 - 这些设置会使 postgres 子进程以默认值零的 OOM score adjustment 运行,因此 OOM 杀手在需要时仍可将它们作为目标。如果你希望子进程使用其他 OOM score adjustment 值,也可以为 PG_OOM_ADJUST_VALUE 指定其他数值(也可省略,此时默认为零)。如果不设置 PG_OOM_ADJUST_FILE,子进程就会和主进程使用相同的 OOM score adjustment,这并不明智,因为这样做的目的正是为了确保主进程拥有优先保护设置。 - + 这些设置会使 postmaster 子进程以常规的 OOM 评分调整值零运行,以便 OOM 杀手在需要时仍可将它们作为目标。 + 如果希望子进程以其他 OOM 评分调整值运行,也可以为 PG_OOM_ADJUST_VALUE 指定其他值。 + (也可以省略 PG_OOM_ADJUST_VALUE,此时默认为零。) + 如果不设置 PG_OOM_ADJUST_FILE,子进程就会和 postmaster 使用相同的 OOM 评分调整值, + 这并不明智,因为这样做的目的正是确保 postmaster 获得优先保护。 +
@@ -911,8 +913,9 @@ $ cat /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages - 你可能还需要授予数据库服务器的操作系统用户使用大页的权限,例如通过sysctl设置vm.hugetlb_shm_group,以及/或者授予其使用ulimit -l锁定内存的权限。 - + 可能还需要通过 sysctl 设置 vm.hugetlb_shm_group, + 授予数据库服务器的操作系统用户使用大页的权限,以及/或者通过 ulimit -l 授予其锁定内存的权限。 + PostgreSQL对大页的默认行为是:只要可能就使用它们,采用系统默认的大页大小;如果失败,则回退到普通页面。要强制使用大页,可以在postgresql.conf中将设为on。请注意,在这种设置下,如果没有足够的大页可用,PostgreSQL将无法启动。 @@ -934,7 +937,7 @@ $ cat /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages - 有几种关闭数据库服务器的方法。在后台,它们都简化为向主管 postgres 进程发送信号。 + 有几种关闭数据库服务器的方法。这些方法在内部都是向主管 postgres 进程发送信号。 @@ -976,7 +979,7 @@ $ cat /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepagesSIGQUIT并等待它们终止。 如果有任何进程在 5 秒内未终止,它们将被发送SIGKILL。 一旦所有子进程退出,主管服务器进程将立即退出,而不进行正常的数据库关闭处理。 - 这会导致下次启动时通过回放 WAL 日志执行恢复。仅建议在紧急情况下使用。 + 这会导致下次启动时通过重放 WAL 日志执行恢复。仅建议在紧急情况下使用。 @@ -992,10 +995,7 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` - - 最好不要使用SIGKILL关闭服务器。这样做将会阻止服务器释放共享内存和信号量。 - 此外,使用SIGKILL杀掉postgres进程时,postgres不会有机会将信号传播到它的子进程,所以可能也必须手工杀掉单个的子进程。 - + 最好不要使用 SIGKILL 关闭服务器。这样做会阻止服务器释放共享内存和信号量。此外,SIGKILL 会终止 postgres 进程,使其没有机会将信号转发给子进程,因此可能还需要手动逐个终止子进程。 @@ -1008,12 +1008,12 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`升级 PostgreSQL 集簇 - upgrading + 升级 - version - compatibility + 版本 + 兼容性 @@ -1033,7 +1033,7 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` - 新的主版本通常还会引入一些用户可见的不兼容变化,因此应用程序可能也需要做出修改。所有用户可见的变化都列在发行说明()中;请特别留意标为Migration的小节。虽然你可以从一个主版本直接升级到另一个主版本,而不必逐个升级中间版本,但仍应阅读所有中间版本的主版本发行说明。 + 新的主版本通常还会引入一些用户可见的不兼容变化,因此应用程序可能也需要做出修改。所有用户可见的变化都列在发行说明()中;请特别留意标为迁移(Migration)的小节。虽然你可以从一个主版本直接升级到另一个主版本,而不必逐个升级中间版本,但仍应阅读所有中间版本的主版本发行说明。 @@ -1092,7 +1092,7 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` - 这涉及以后端函数 API 为代表的变更,该 API 使用 C 语言编写。这类变更会影响那些深入引用服务器内部后端函数的代码。 + 这涉及使用 C 语言编写的后端函数 API 的变更。这类变更会影响那些深入引用服务器内部后端函数的代码。 @@ -1104,7 +1104,7 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`通过pg_dumpall升级数据 - 一种升级方法是从某个主版本的PostgreSQL导出数据,再在另一个版本中恢复。要这样做,必须使用逻辑备份工具,例如pg_dumpall;文件系统级备份方法不起作用。(系统中有相应检查,会阻止你在不兼容版本的PostgreSQL上使用某个数据目录,因此即便误用错误版本的服务器去启动某个数据目录,通常也不会造成太大损害。) + 一种升级方法是从某个主版本的PostgreSQL转储数据,再在另一个版本中恢复。要这样做,必须使用逻辑备份工具,例如pg_dumpall;文件系统级备份方法不起作用。(系统中有相应检查,会阻止你在不兼容版本的PostgreSQL上使用某个数据目录,因此即便误用错误版本的服务器去启动某个数据目录,通常也不会造成太大损害。) @@ -1119,13 +1119,13 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` - 如果是在制作备份,请确认数据库此时没有正在进行更新。这不会影响备份的一致性,但那些变更当然不会包含在备份中。必要时,可修改/usr/local/pgsql/data/pg_hba.conf中的访问权限(或采用等效方法),禁止除你之外的其他人访问数据库。有关访问控制的更多信息见。 + 如果是在制作备份,请确认数据库此时没有正在进行更新。更新操作不会影响备份的完整性,但那些变更当然不会包含在备份中。必要时,可修改/usr/local/pgsql/data/pg_hba.conf(或等效文件)中的访问权限,禁止除你之外的其他人访问数据库。有关访问控制的更多信息见 pg_dumpall - use during upgrade + 在升级期间使用 要备份整个数据库安装,请输入: @@ -1146,7 +1146,7 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` pg_ctl stop - 在那些会自动启动PostgreSQL的系统上,可能已经有某个启动脚本能完成同样的工作。例如,在Red Hat Linux系统上,也许下面这条命令就可以: + 在那些会在开机时自动启动PostgreSQL的系统上,可能已经有某个启动脚本能完成同样的工作。例如,在Red Hat Linux系统上,也许下面这条命令就可以: /etc/rc.d/init.d/postgresql stop @@ -1201,12 +1201,9 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` - - 最后,使用新的psql从备份恢复数据: - + 最后,使用以下命令从备份恢复数据: /usr/local/pgsql/bin/psql -d postgres -f outputfile - - 这里务必使用新的psql。 +这里应使用新版 psql @@ -1237,7 +1234,7 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 通过复制升级数据 - 也可以使用逻辑复制方法,创建一个运行较新版本PostgreSQL的备库。之所以可行,是因为逻辑复制支持不同主版本PostgreSQL之间进行复制。该备库可以与旧服务器部署在同一台机器上,也可以部署在不同机器上。一旦它与主库(运行旧版本PostgreSQL)同步,就可以切换主备角色,让备库提升为主库,并关闭旧的数据库实例。这种切换通常只会带来几秒钟的停机时间。 + 也可以使用逻辑复制方法,创建一个运行较新版本PostgreSQL的备库。之所以可行,是因为逻辑复制支持不同主版本PostgreSQL之间进行复制。该备库可以与旧服务器部署在同一台机器上,也可以部署在不同机器上。一旦它与主库(运行旧版本PostgreSQL)同步,就可以切换主备角色,让备库提升为主库,并关闭旧的数据库实例。这种切换使升级只需几秒钟的停机时间。 @@ -1271,17 +1268,14 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 - 要防止 SSL 欺骗,服务器必须配置为仅接受 hostssl 连接(),并且具备 SSL 密钥和证书文件()。TCP 客户端必须使用 sslmode=verify-caverify-full 连接,并安装适当的根证书文件()。另外,也可使用 SSL 实现定义的系统 CA 池(system CA pool),即设置 sslrootcert=system;出于安全考虑,此时会强制使用 sslmode=verify-full,因为获得由公共 CA 签发的证书通常并不困难。 + 要通过 SSL 防止服务器欺骗,服务器必须配置为仅接受 hostssl 连接(),并且具备 SSL 密钥和证书文件()。TCP 客户端必须使用 sslmode=verify-caverify-full 连接,并安装适当的根证书文件()。另外,也可使用 SSL 实现定义的系统 CA 池,即设置 sslrootcert=system;出于安全考虑,此时会强制使用 sslmode=verify-full,因为获得由公共 CA 签发的证书通常并不困难。 在网络上使用 scram-sha-256 密码认证时,为防止服务器欺骗,应确保通过 SSL 连接服务器,并使用上一段描述的任一防欺骗方法。此外,libpq 中的 SCRAM 实现无法保护整个认证交换过程,但使用连接参数 channel_binding=require 可对服务器欺骗提供一定缓解。攻击者若用伪造服务器拦截 SCRAM 交换,可能通过离线分析推导出客户端哈希密码。 - - 要防止 GSSAPI 欺骗,必须将服务器配置为仅接受hostgssenc连接 () 并对它们使用gss认证。 - TCP 客户端则必须使用 gssencmode=require 发起连接。 - + 要通过 GSSAPI 防止服务器欺骗,服务器必须配置为仅接受 hostgssenc 连接(),并对这些连接使用 gss 认证。TCP 客户端必须使用 gssencmode=require 连接。
@@ -1293,7 +1287,7 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 - PostgreSQL提供了多个层次的加密,并在防止数据因数据库服务器被盗、不可靠的管理员或不安全网络等原因而泄露方面提供了很高的灵活性。对于医疗记录、金融交易等敏感数据,加密也可能是合规要求的一部分。 + PostgreSQL提供了多个层次的加密,并在防止数据因数据库服务器被盗、不诚实的管理员或不安全网络等原因而泄露方面提供了很高的灵活性。为了保护医疗记录、金融交易等敏感数据,也可能需要使用加密。 @@ -1308,9 +1302,7 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 - - 对 MD5 加密密码的支持已弃用,并将在未来版本的 PostgreSQL 中移除。迁移到其他密码类型的细节见 。 - + 对 MD5 加密密码的支持已弃用,并将在PostgreSQL的未来版本中移除。迁移到其他密码类型的详细信息见 @@ -1433,7 +1425,7 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 - 如果私钥受密码保护,服务器会提示输入该密码,并在输入之前不会启动。默认情况下,使用密码会禁用无需重启服务器即可更改 SSL 配置的能力,不过参见。此外,在 Windows 上完全无法使用带密码保护的私钥。 + 如果私钥受口令保护,服务器会提示输入该口令,并在输入之前不会启动。默认情况下,使用口令会禁用无需重启服务器即可更改 SSL 配置的能力,不过参见。此外,在 Windows 上完全无法使用带口令保护的私钥。 @@ -1460,7 +1452,7 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 - 使用NULL-SHANULL-MD5密码套件,可以在几乎没有加密开销的情况下完成认证。不过,中间人仍然能够读取并转发客户端与服务器之间的通信。此外,与认证的开销相比,加密开销本身通常很小。基于这些原因,不建议使用 NULL 密码套件。 + 使用NULL-SHANULL-MD5密码套件,可以在没有加密开销的情况下完成认证。不过,中间人仍然能够读取并转发客户端与服务器之间的通信。此外,与认证的开销相比,加密开销本身很小。基于这些原因,不建议使用 NULL 密码套件。
@@ -1693,9 +1685,7 @@ psql -h localhost -p 63333 postgres 对数据库服务器来说,它看到的是来自主机foo.com上用户joelocalhost绑定地址的连接,并将应用为该用户到该绑定地址所配置的认证方式。请注意,服务器不会认为这是 SSL 加密连接,因为实际上SSH服务器与PostgreSQL服务器之间并没有加密。不过这通常不会带来额外安全风险,因为两者位于同一台机器上。 - - 要让这条隧道建立成功,你必须能够像建立终端会话那样,通过sshjoe@foo.com身份连接。 - + 要让这条隧道建立成功,你必须有权通过 sshjoe@foo.com 身份连接,就像尝试使用 ssh 创建终端会话一样。 你也可以把端口转发设成这样: diff --git a/zh/18/spgist.sgml b/zh/18/spgist.sgml index 35430a86..ea4d1790 100644 --- a/zh/18/spgist.sgml +++ b/zh/18/spgist.sgml @@ -4,7 +4,7 @@ SP-GiST 索引 - index + 索引 SP-GiST @@ -12,7 +12,7 @@ 简介 - SP-GiST 是 space-partitioned GiST + SP-GiST 是空间分区 GiST 的缩写。SP-GiST 支持分区搜索树,这使得开发多种不同的 非平衡数据结构成为可能,例如四叉树、k-d 树以及基数树(trie)。这些结构 的共同特征是,它们会反复将搜索空间划分为不必等大的分区。与这种划分规则良 @@ -49,7 +49,7 @@ 内置操作符类 - 核心 PostgreSQL 发行版包含了 + PostgreSQL 核心发行版包含了 SP-GiST 操作符类,如 所示。 @@ -232,11 +232,11 @@ - SP-GiST 核心代码会处理空项。虽然 - SP-GiST 索引确实会为被索引列中的空值存储项,但这一 - 点对索引操作符类代码是隐藏的:不会有空的索引项或搜索条件传递给操作符类 - 方法。(这里假定 SP-GiST 操作符是严格的,因此对空 - 值不可能成功。)因此,这里不再进一步讨论空值。 + SP-GiST 核心代码负责处理值为 null 的索引项。虽然 + SP-GiST 索引会为被索引列中的 null 值存储索引项, + 但索引操作符类代码看不到这些项:值为 null 的索引项或搜索条件绝不会传给 + 操作符类方法。(这里假定 SP-GiST 操作符是严格的, + 因此对 null 值不可能返回真。)所以这里不再讨论 null 值。 @@ -286,8 +286,8 @@ typedef struct spgConfigOut Oid prefixType; /* 内部元组前缀的数据类型 */ Oid labelType; /* 内部元组结点标签的数据类型 */ Oid leafType; /* 叶子元组值的数据类型 */ - bool canReturnData; /* 操作符类能重构原始数据 */ - bool longValuesOK; /* 操作符类能处理值 > 1 页 */ + bool canReturnData; /* 操作符类能重建原始数据 */ + bool longValuesOK; /* 操作符类能处理大小 > 1 页的值 */ } spgConfigOut; @@ -314,7 +314,7 @@ typedef struct spgConfigOut 类型与操作符类的输入类型相同,这也是最常见的情况。)出于向后兼容的原 因,config 方法也可以将 leafType 设为其他值,并且该值将被使用; - 但这已被废弃,因为这样会导致目录中对索引内容的标识不正确。此外,也允 + 但这已被弃用,因为这样会导致目录中对索引内容的标识不正确。此外,也允 许不初始化 leafType(即保持为零);这会 被解释为使用从 opckeytype 派生的索引存 储类型。 @@ -354,7 +354,7 @@ typedef struct spgChooseIn int level; /* 当前层级(从零开始计) */ /* 来自当前内部元组的数据 */ - bool allTheSame; /* 元组被标记为 all-the-same? */ + bool allTheSame; /* 元组被标记为全部相同? */ bool hasPrefix; /* 元组有前缀? */ Datum prefixDatum; /* 如果有,前缀值 */ int nNodes; /* 内部元组中的结点数 */ @@ -594,14 +594,14 @@ typedef struct spgInnerConsistentIn int nkeys; /* scankeys 数组的长度 */ int norderbys; /* orderbys 数组的长度 */ - Datum reconstructedValue; /* 在父元组处重构的值 */ + Datum reconstructedValue; /* 在父元组处重建的值 */ void *traversalValue; /* 操作符类特定的遍历值 */ MemoryContext traversalMemoryContext; /* 将新的遍历值放在这里 */ int level; /* 当前层级(从零开始计) */ bool returnData; /* 必须返回原始数据? */ /* 来自当前内部元组的数据 */ - bool allTheSame; /* 元组被标记为 all-the-same? */ + bool allTheSame; /* 元组被标记为全部相同? */ bool hasPrefix; /* 元组有前缀? */ Datum prefixDatum; /* 如果有,前缀值 */ int nNodes; /* 内部元组中的结点数 */ @@ -613,7 +613,7 @@ typedef struct spgInnerConsistentOut int nNodes; /* 需要访问的子结点数 */ int *nodeNumbers; /* 它们在结点数组中的索引 */ int *levelAdds; /* 对每个结点层级增加这么多 */ - Datum *reconstructedValues; /* 关联的重构值 */ + Datum *reconstructedValues; /* 关联的重建值 */ void **traversalValues; /* 操作符类特定的遍历值 */ double **distances; /* 关联距离 */ } spgInnerConsistentOut; @@ -624,7 +624,7 @@ typedef struct spgInnerConsistentOut 用 AND 组合 — 只有满足全部条件的索引项才是我们关心的。(注 意, nkeys = 0 表示所有索引项都满足该查 - 询。)通常 consistent 函数只关心每个数组元素的 + 询。)通常一致性检查函数只关心每个数组元素的 sk_strategysk_argument 字段,它们分别给出可索引操 作符和比较值。特别地,无需检查 sk_flags @@ -641,9 +641,8 @@ typedef struct spgInnerConsistentOut 遍历值(见下文)的内存上下文。level 是 当前内部元组的层级,根层为零。如果本查询需要重建数据,则 returnDatatrue; - 只有在 config 函数声明了 - canReturnData 时才会如此。若当前内部元组 - 被标记为 all-the-same,则 + 只有在 config 函数将 canReturnData 设为真时才会如此。若当前内部元组 + 被标记为 全部相同,则 allTheSame 为真;在这种情况下,所有结点 都具有相同的标签(如果有),因此要么全部匹配该查询,要么全部不匹配 (参见 )。若当前内部元组包 @@ -663,8 +662,7 @@ typedef struct spgInnerConsistentOut 非必然如此,所以这里使用数组。)如果需要值重建,则将 reconstructedValues 设为一个数组,其中包 含为每个待访问子结点重建的值;否则,将 - reconstructedValues 保持为 NULL。重构 - 值假定具有 spgConfigOut.leafType + reconstructedValues 保持为 NULL。重建的值假定具有 spgConfigOut.leafType 类型。(不过,由于核心系统除了可能复制它们以外不会对其做任何处理,只 要它们具有与 leafType 相同的 typlentypbyval 属性就足 @@ -713,7 +711,7 @@ typedef struct spgLeafConsistentIn int nkeys; /* scankeys 数组的长度 */ int norderbys; /* orderbys 数组的长度 */ - Datum reconstructedValue; /* 在父元组处重构的值 */ + Datum reconstructedValue; /* 在父元组处重建的值 */ void *traversalValue; /* 操作符类特定的遍历值 */ int level; /* 当前层级(从零开始计) */ bool returnData; /* 必须返回原始数据? */ @@ -723,7 +721,7 @@ typedef struct spgLeafConsistentIn typedef struct spgLeafConsistentOut { - Datum leafValue; /* 重构出的原始数据(如果有) */ + Datum leafValue; /* 重建出的原始数据(如果有) */ bool recheck; /* 如果必须重新检查操作符则设为真 */ bool recheckDistances; /* 如果必须重新检查距离则设为真 */ double *distances; /* 关联距离 */ @@ -734,7 +732,7 @@ typedef struct spgLeafConsistentOut scankeys 数组描述索引搜索条件。这些条件 用 AND 组合在一起 — 只有满足全部条件的索引项才满足该查询。(注 意 nkeys = 0 表示所有索引项都满足该查 - 询。)通常 consistent 函数只关心每个数组元素的 + 询。)通常一致性检查函数只关心每个数组元素的 sk_strategysk_argument 字段,它们分别给出可索引操 作符和比较值。特别地,无需检查 sk_flags @@ -750,8 +748,7 @@ typedef struct spgLeafConsistentOut NULL。level 是当前叶子元组的层级,根层为 零。如果本查询需要重建数据,则 returnDatatrue; - 只有在 config 函数声明了 - canReturnData 时才会如此。 + 只有在 config 函数将 canReturnData 设为真时才会如此。 leafDatum 是当前叶子元组中存储的、类型为 spgConfigOut.leafType 的键值。 @@ -844,7 +841,7 @@ LANGUAGE C STRICT; - 如果被索引列属于可应用排序规则的数据类型,则索引排序规则会通过标准的 + 如果被索引列属于支持排序规则的数据类型,则索引排序规则会通过标准的 PG_GET_COLLATION() 机制传递给所有支持方法。 @@ -922,7 +919,7 @@ LANGUAGE C STRICT; - <quote>All-the-Same</quote> 内部元组 + <quote>全部相同</quote>的内部元组 picksplit 无法把提供的叶子值划分为至少两个结点 diff --git a/zh/18/spi.sgml b/zh/18/spi.sgml index b4b8b0e2..22aec302 100644 --- a/zh/18/spi.sgml +++ b/zh/18/spi.sgml @@ -76,7 +76,7 @@ int SPI_connect_ext(int options) SPI_connect 会为某次 C 函数调用打开到 SPI 管理器 的连接。如果要通过 SPI 执行命令,就必须调用此函数。不过,有些 SPI - 实用函数可以在未连接的 C 函数中调用。 + 辅助函数可以在未连接的 C 函数中调用。 @@ -291,16 +291,16 @@ SPI_execute("INSERT INTO foo SELECT * FROM bar RETURNING *", false, 5); typedef struct SPITupleTable { - /* Public members */ - TupleDesc tupdesc; /* tuple descriptor */ - HeapTuple *vals; /* array of tuples */ - uint64 numvals; /* number of valid tuples */ - - /* Private members, not intended for external callers */ - uint64 alloced; /* allocated length of vals array */ - MemoryContext tuptabcxt; /* memory context of result table */ - slist_node next; /* link for internal bookkeeping */ - SubTransactionId subid; /* subxact in which tuptable was created */ + /* 公共成员 */ + TupleDesc tupdesc; /* 元组描述符 */ + HeapTuple *vals; /* 元组数组 */ + uint64 numvals; /* 有效元组数 */ + + /* 私有成员,不供外部调用者使用 */ + uint64 alloced; /* vals 数组的已分配长度 */ + MemoryContext tuptabcxt; /* 结果表的内存上下文 */ + slist_node next; /* 用于内部管理的链接 */ + SubTransactionId subid; /* 创建 tuptable 的子事务 */ } SPITupleTable; SPI 调用者可以使用 tupdesc、 @@ -471,7 +471,7 @@ typedef struct SPITupleTable - 发生错误时,则返回下列负值之一: + 出错时,返回以下负值之一: @@ -521,7 +521,7 @@ typedef struct SPITupleTable SPI_ERROR_UNCONNECTED - 从未连接的 C 函数中调用 + 如果从一个未连接的 C 函数中调用 @@ -534,9 +534,9 @@ typedef struct SPITupleTable 所有 SPI 查询执行函数都会设置 SPI_processed 和 - SPI_tuptable(只设置指针,而不会复制结构体内容)。如果 + SPI_tuptable(只设置指针,而不更改结构体内容)。如果 需要在后续调用之后继续访问 SPI_execute 或其他查询 - 执行函数的结果表,请把这两个全局变量保存到本地 C 函数变量中。 + 执行函数的结果表,请把这两个全局变量保存到 C 函数的局部变量中。 @@ -581,7 +581,7 @@ int SPI_exec(const char * command, long count< const char * command - 包含要执行命令的字符串 + 包含待执行命令的字符串 @@ -590,7 +590,7 @@ int SPI_exec(const char * command, long count< long count - 要返回的最大行数,或者用0表示没有限制 + 要返回的最大行数,或者用 0 表示不限制 @@ -821,7 +821,7 @@ int SPI_execute_with_args(const char *command, SPI_execute_plan 达到类似效果。不过,使用本函数 时,查询计划总会针对所提供的具体参数值进行定制。对于一次性查询执行,应 优先选择本函数。如果同一条命令要用许多不同参数重复执行,则两种方式孰快 - 取决于重新计划的代价与定制计划收益之间的权衡。 + 取决于重新规划的代价与定制计划收益之间的权衡。 @@ -876,9 +876,9 @@ int SPI_execute_with_args(const char *command, 如果 nullsNULL,则 - SPI_execute_with_args 会假定没有参数为 NULL。 - 否则,如果对应参数值非 NULL,则 nulls 数组中 - 的对应项应为 ' ';如果对应参数值为 NULL,则 + SPI_execute_with_args 会假定没有参数为空值。 + 否则,如果对应参数值非空值,则 nulls 数组中 + 的对应项应为 ' ';如果对应参数值为空值,则 对应项应为 'n'。(后一种情况下,对应 values 项中的实际值无关紧要。)注意, nulls 不是文本字符串,而只是一个数组,因此不 @@ -932,7 +932,7 @@ int SPI_execute_with_args(const char *command, SPI_prepare - 准备一个语句,但不执行它 + 准备一个语句,但暂不执行 @@ -1011,8 +1011,7 @@ SPIPlanPtr SPI_prepare(const char * command, int 返回值 - SPI_prepare 返回一个指向非空 SPIPlan - 的指针,它是表示预备语句的不透明结构体。发生错误时会返回 + SPI_prepare 返回一个非空指针,指向表示预备语句的不透明结构体 SPIPlan。发生错误时会返回 NULL,并将 SPI_result 设为 SPI_execute 所使用的那些错误码之一;但如果 commandNULL,或者 @@ -1031,17 +1030,16 @@ SPIPlanPtr SPI_prepare(const char * command, int SPI_execute_plan 在最初几次使用时会根据提供的参数 值生成定制计划。当同一个预备语句被使用足够多次之后, SPI_execute_plan 会构建一个通用计划;如果它的代价 - 没有比定制计划高出太多,就会开始改用通用计划,而不是每次都重新计划。如 + 没有比定制计划高出太多,就会开始改用通用计划,而不是每次都重新规划。如 果这种默认行为不合适,可以把 CURSOR_OPT_GENERIC_PLANCURSOR_OPT_CUSTOM_PLAN 标志传给 SPI_prepare_cursor,分别强制使用通用计划或定制计划。 - 尽管预备语句的主要目的在于避免重复进行解析分析和计划,但只要语句中使用 + 尽管预备语句的主要目的在于避免重复进行解析分析和规划,但只要语句中使用 的数据库对象自上次使用该预备语句以来发生了定义性(DDL)变更, - PostgreSQL 就会在再次使用前强制重新分析并重 - 新计划该语句。此外,如果 的值在两次 + PostgreSQL 就会在再次使用前强制重新分析并重新规划该语句。此外,如果 的值在两次 使用之间发生变化,该语句也会基于新的 search_path 重 新解析。(后一种行为是从 PostgreSQL 9.3 开 始引入的。)有关预备语句行为的更多信息,请参见 @@ -1101,7 +1099,7 @@ SPIPlanPtr SPI_prepare_cursor(const char * command, int < - 此函数现已废弃,推荐改用 SPI_prepare_extended。 + 此函数现已弃用,推荐改用 SPI_prepare_extended @@ -1131,7 +1129,7 @@ SPIPlanPtr SPI_prepare_cursor(const char * command, int < Oid * argtypes - 指向数组的指针,该数组包含参数数据类型的 + 一个数组指针,它指向的数组包含参数的数据类型的 OID @@ -1200,7 +1198,7 @@ SPIPlanPtr SPI_prepare_extended(const char * command, SPI_prepare_extended 为指定命令创建并返回一个预备语 句,但并不执行该命令。它相当于 SPI_prepare,并额外 - 允许调用者指定选项,以控制外部参数引用的解析,以及查询解析和计划的其他 + 允许调用者指定选项,以控制外部参数引用的解析,以及查询解析和规划的其他 方面。 @@ -1240,7 +1238,7 @@ SPIPlanPtr SPI_prepare_extended(const char * command, ParserSetupHook parserSetup - 语法分析器钩子设置函数 + 解析器钩子设置函数 @@ -1318,7 +1316,7 @@ SPIPlanPtr SPI_prepare_params(const char * command, - 此函数现已废弃,推荐改用 SPI_prepare_extended。 + 此函数现已弃用,推荐改用 SPI_prepare_extended @@ -1339,7 +1337,7 @@ SPIPlanPtr SPI_prepare_params(const char * command, ParserSetupHook parserSetup - 语法分析器钩子设置函数 + 解析器钩子设置函数 @@ -1554,8 +1552,8 @@ bool SPI_is_cursor_plan(SPIPlanPtr plan) 返回值 - 如果 plan 能产生游标,则返回 - true;如果不能,则返回 false,并将 + 返回 truefalse,表示 + plan 能否产生游标,同时将 SPI_result 设为零。如果无法确定答案(例如 planNULL 或无效,或者在 未连接到 SPI 时调用),则会将 SPI_result 设为合适 @@ -1627,15 +1625,14 @@ int SPI_execute_plan(SPIPlanPtr plan, Datum * - 如果nullsNULL, - 那么SPI_execute_plan会假设没有参数 - 为空值。否则,如果对应的参数值为非空, - nulls - 数组的每一个项都应该是' ';如果对应参数值为空, - nulls数组的项应为'n'(在后 - 面的情况中,对应的values项中的值没有 - 关系)。注意nulls不是一个文本字符串, - 它只是一个数组:它不需要一个'\0'终止符。 + 如果 nullsNULL,则 + SPI_execute_plan 会假定没有参数为空值。 + 否则,如果对应参数值非空值,则 nulls 数组中 + 的对应项应为 ' ';如果对应参数值为空值,则 + 对应项应为 'n'。(后一种情况下,对应 + values 项中的实际值无关紧要。)注意, + nulls 不是文本字符串,而只是一个数组,因此不 + 需要 '\0' 终止符。 @@ -1708,7 +1705,7 @@ int SPI_execute_plan(SPIPlanPtr plan, Datum * SPI_execute_plan_extended - 执行一个由SPI_prepare准备的语句 + 执行由 SPI_prepare 准备好的语句 @@ -1793,8 +1790,9 @@ int SPI_execute_plan_extended(SPIPlanPtr plan, bool allow_nonatomic - true 允许以非原子方式执行 CALL 与 DO 语句 - (但除非向 SPI_connect_ext 传入了 + true 允许以非原子方式执行 CALL + 和 DO 语句(但除非向 + SPI_connect_ext 传入了 SPI_OPT_NONATOMIC 标志,否则该字段会被忽略) @@ -1814,7 +1812,7 @@ int SPI_execute_plan_extended(SPIPlanPtr plan, uint64 tcount - 要返回的最大行数,或者用0表示没有限制 + 要返回的最大行数,或者用 0 表示不限制 @@ -1899,7 +1897,7 @@ int SPI_execute_plan_with_paramlist(SPIPlanPtr plan, - 此函数现已废弃,推荐改用 SPI_execute_plan_extended。 + 此函数现已弃用,推荐改用 SPI_execute_plan_extended @@ -1936,7 +1934,7 @@ int SPI_execute_plan_with_paramlist(SPIPlanPtr plan, long count - 要返回的最大行数,或者用0表示没有限制 + 要返回的最大行数,或者用 0 表示不限制 @@ -2020,15 +2018,14 @@ int SPI_execp(SPIPlanPtr plan, Datum * values< - 如果nullsNULL, - 那么SPI_execp会假设没有参数 - 为空值。否则,如果对应的参数值为非空, - nulls - 数组的每一个项都应该是' ';如果对应参数值为空, - nulls数组的项应为'n'(在后 - 面的情况中,对应的values项中的值没有 - 关系)。注意nulls不是一个文本字符串, - 它只是一个数组:它不需要一个'\0'终止符。 + 如果 nullsNULL,则 + SPI_execp 会假定没有参数为空值。 + 否则,如果对应参数值非空值,则 nulls 数组中 + 的对应项应为 ' ';如果对应参数值为空值,则 + 对应项应为 'n'。(后一种情况下,对应 + values 项中的实际值无关紧要。)注意, + nulls 不是文本字符串,而只是一个数组,因此不 + 需要 '\0' 终止符。 @@ -2037,7 +2034,7 @@ int SPI_execp(SPIPlanPtr plan, Datum * values< long count - 要返回的最大行数,或者用0表示没有限制 + 要返回的最大行数,或者用 0 表示不限制 @@ -2145,15 +2142,14 @@ Portal SPI_cursor_open(const char * name, SPIPlanPtr - 如果nullsNULL, - 那么SPI_cursor_open会假设没有参数 - 为空值。否则,如果对应的参数值为非空, - nulls - 数组的每一个项都应该是' ';如果对应参数值为空, - nulls数组的项应为'n'(在后 - 面的情况中,对应的values项中的值没有 - 关系)。注意nulls不是一个文本字符串, - 它只是一个数组:它不需要一个'\0'终止符。 + 如果 nullsNULL,则 + SPI_cursor_open 会假定没有参数为空值。 + 否则,如果对应参数值非空值,则 nulls 数组中 + 的对应项应为 ' ';如果对应参数值为空值,则 + 对应项应为 'n'。(后一种情况下,对应 + values 项中的实际值无关紧要。)注意, + nulls 不是文本字符串,而只是一个数组,因此不 + 需要 '\0' 终止符。 @@ -2214,11 +2210,10 @@ Portal SPI_cursor_open_with_args(const char *name, - 对于一次性的查询执行,这个函数应该比 - SPI_prepare_cursor加上其后的 - SPI_cursor_open更好。如果相同的命令 - 要被用很多不同的参数执行,哪种方法更快就要取决于重做计划的 - 代价与定制计划带来的好处之间谁更有利。 + 对于一次性查询执行,应优先使用此函数,而不是先调用 + SPI_prepare_cursor 再调用 + SPI_cursor_open。如果同一条命令要用许多不同参数执行, + 哪种方法更快取决于重新规划的代价与定制计划收益之间的权衡。 @@ -2227,7 +2222,7 @@ Portal SPI_cursor_open_with_args(const char *name, - 此函数现已废弃,推荐改用 SPI_cursor_parse_open, + 此函数现已弃用,推荐改用 SPI_cursor_parse_open, 它提供了等价的功能,并使用更现代的查询参数处理 API。 @@ -2267,8 +2262,8 @@ Portal SPI_cursor_open_with_args(const char *name, Oid * argtypes - 一个长度为nargs的数组, - 包含参数的数据类型的OID + 一个长度为 nargs 的数组,包含参数数据类型的 + OID @@ -2277,8 +2272,7 @@ Portal SPI_cursor_open_with_args(const char *name, Datum * values - 一个长度为nargs的数组, - 包含实际的参数值 + 一个长度为 nargs 的数组,包含实际参数值 @@ -2287,20 +2281,19 @@ Portal SPI_cursor_open_with_args(const char *name, const char * nulls - 一个长度为nargs的数组, - 描述哪些参数为空值 + 一个长度为 nargs 的数组,用于描述哪些参数为 + 空值 - 如果nullsNULL, - 那么SPI_cursor_open_with_args会假设没有参数 - 为空值。否则,如果对应的参数值为非空, - nulls - 数组的每一个项都应该是' ';如果对应参数值为空, - nulls数组的项应为'n'(在后 - 面的情况中,对应的values项中的值没有 - 关系)。注意nulls不是一个文本字符串, - 它只是一个数组:它不需要一个'\0'终止符。 + 如果 nullsNULL,则 + SPI_cursor_open_with_args 会假定没有参数为空值。 + 否则,如果对应参数值非空值,则 nulls 数组中 + 的对应项应为 ' ';如果对应参数值为空值,则 + 对应项应为 'n'。(后一种情况下,对应 + values 项中的实际值无关紧要。)注意, + nulls 不是文本字符串,而只是一个数组,因此不 + 需要 '\0' 终止符。 @@ -2437,7 +2430,7 @@ Portal SPI_cursor_open_with_paramlist(const char *name, SPI_cursor_parse_open - 使用查询字符串和参数设置游标 + 使用查询字符串和参数建立游标 @@ -2463,7 +2456,7 @@ Portal SPI_cursor_parse_open(const char *name, 对于一次性查询执行,推荐优先使用此函数,而不是 SPI_prepare_cursorSPI_cursor_open_with_paramlist 的组合。如果同一条命 - 令要用很多不同参数执行,两种方法孰快则取决于重新计划的代价与定制计划带 + 令要用很多不同参数执行,两种方法孰快则取决于重新规划的代价与定制计划带 来的收益之间的权衡。 @@ -2700,7 +2693,7 @@ void SPI_cursor_fetch(Portal portal, bool forw 如果该游标的计划不是用CURSOR_OPT_SCROLL - 选项创建的,向后获取会失败。 + 选项创建的,向后获取可能失败。 @@ -2774,7 +2767,7 @@ void SPI_cursor_move(Portal portal, bool forwa 如果该游标的计划不是用CURSOR_OPT_SCROLL - 选项创建的,向后移动会失败。 + 选项创建的,向后移动可能失败。 @@ -2870,8 +2863,7 @@ void SPI_scroll_cursor_fetch(Portal portal, FetchDirectio 如果该游标的计划不是用CURSOR_OPT_SCROLL - 选项创建的,除FETCH_FORWARD之外的方向值会 - 失败。 + 选项创建的,除FETCH_FORWARD之外的方向值可能失败。 @@ -2968,8 +2960,7 @@ void SPI_scroll_cursor_move(Portal portal, FetchDirection 如果该游标的计划不是用CURSOR_OPT_SCROLL - 选项创建的,除FETCH_FORWARD之外的方向值会 - 失败。 + 选项创建的,除FETCH_FORWARD之外的方向值可能失败。 @@ -3191,8 +3182,8 @@ SPIPlanPtr SPI_saveplan(SPIPlanPtr plan) SPI_register_relation - ephemeral named relation - registering with SPI + 临时命名关系 + 向 SPI 注册 @@ -3216,7 +3207,7 @@ int SPI_register_relation(EphemeralNamedRelation enr) SPI_register_relation 使一个带有相关信息的临时命名关 - 系对通过当前 SPI 连接计划和执行的查询可用。 + 系对通过当前 SPI 连接规划和执行的查询可用。 @@ -3254,7 +3245,7 @@ int SPI_register_relation(EphemeralNamedRelation enr) - 在出错时,会返回下列负值之一: + 出错时,返回以下负值之一: @@ -3296,8 +3287,8 @@ int SPI_register_relation(EphemeralNamedRelation enr) SPI_unregister_relation - ephemeral named relation - unregistering from SPI + 临时命名关系 + 从 SPI 注销 @@ -3344,7 +3335,7 @@ int SPI_unregister_relation(const char * name) 返回值 - 如果该命令的执行成功,则会返回下列(非负)值: + 如果该命令的执行成功,则将返回下列(非负)值: @@ -3359,7 +3350,7 @@ int SPI_unregister_relation(const char * name) - 出现错误时,会返回下列负值之一: + 出错时,返回以下负值之一: @@ -3399,13 +3390,13 @@ int SPI_unregister_relation(const char * name) SPI_register_trigger_data - ephemeral named relation - registering with SPI + 临时命名关系 + 向 SPI 注册 - transition tables - implementation in PLs + 过渡表 + 在 PL 中实现 @@ -3429,8 +3420,8 @@ int SPI_register_trigger_data(TriggerData *tdata) SPI_register_trigger_data 使触发器捕获的所有临时关系 - 都能在通过当前 SPI 连接计划和执行的查询中使用。目前,这指的是通过 - REFERENCING OLD/NEW TABLE AS ... 子句定义、并由 + 都能在通过当前 SPI 连接规划和执行的查询中使用。目前,这指的是由带有 + REFERENCING OLD/NEW TABLE AS ... 子句的 AFTER 触发器捕获的过渡表。PL 触发器处理函数应在建 立 SPI 连接后调用此函数。 @@ -3456,7 +3447,7 @@ int SPI_register_trigger_data(TriggerData *tdata) 返回值 - 如果命令的执行成功,则会返回下列(非负)值: + 如果该命令的执行成功,则将返回下列(非负)值: @@ -3471,7 +3462,7 @@ int SPI_register_trigger_data(TriggerData *tdata) - 出现错误时,会返回下列负值之一: + 出错时,返回以下负值之一: @@ -3728,7 +3719,7 @@ char * SPI_getvalue(HeapTuple row, TupleDesc r 返回值 - 列值;如果该列为 NULL、colnumber 超出范围 + 列值;如果该列为空值、colnumber 超出范围 (SPI_result 被设置为 SPI_ERROR_NOATTRIBUTE)或者没有输出函数 可用(SPI_result 被设置为 @@ -3820,8 +3811,8 @@ Datum SPI_getbinval(HeapTuple row, TupleDesc r 返回值 - 返回该列的二进制值。如果该列为 NULL,则 - isnull 指向的变量会被设为 true,否则设为 false。 + 返回该列的二进制值。如果该列为空值,则 + isnull 指向的变量会被设为真,否则设为假。 @@ -3857,7 +3848,7 @@ char * SPI_gettype(TupleDesc rowdesc, int coln SPI_gettype返回该指定列的数据类型名称 - 的拷贝(当你不再需要该拷贝后,可以使用pfree + 的副本(当你不再需要该副本后,可以使用pfree 释放它)。 @@ -3989,7 +3980,7 @@ char * SPI_getrelname(Relation rel) SPI_getrelname返回该指定关系的名称 - 的拷贝(当你不再需要该拷贝后,可以使用pfree + 的副本(当你不再需要该副本后,可以使用pfree 释放它)。 @@ -4082,7 +4073,7 @@ char * SPI_getnspname(Relation rel) SPI_result_code_string - 将结果代码表示为字符串 + 返回错误码的字符串表示 @@ -4096,7 +4087,7 @@ const char * SPI_result_code_string(int code); SPI_result_code_string 返回各种 SPI 函数返回的,或 - 存放在 SPI_result 中的结果代码的字符串表示。 + 存放在 SPI_result 中的结果码的字符串表示。 @@ -4108,7 +4099,7 @@ const char * SPI_result_code_string(int code); int code - 结果代码 + 结果码 @@ -4119,7 +4110,7 @@ const char * SPI_result_code_string(int code); 返回值 - 结果代码的字符串表示。 + 结果码的字符串表示。 @@ -4131,8 +4122,8 @@ const char * SPI_result_code_string(int code); - memory context - in SPI + 内存上下文 + 在 SPI 中 PostgreSQL内存上下文 中分配内存。内存上下文为管理那些在许多不同位置创建、且生命周期各不相同 @@ -4157,7 +4148,7 @@ const char * SPI_result_code_string(int code); 办法是用 SPI_palloc 为返回对象分配内存。 SPI_palloc上层执行器上下文中分配 内存,也就是调用 SPI_connect 时的当前内存上下文; - 这正是从 C 函数返回值最合适的上下文。本节介绍的其他几个实用函数同样会返 + 这正是从 C 函数返回值最合适的上下文。本节介绍的其他几个辅助函数同样会返 回在上层执行器上下文中创建的对象。 @@ -4165,7 +4156,7 @@ const char * SPI_result_code_string(int code); 调用 SPI_connect 时,会把该 C 函数的私有上下文 (由 SPI_connect 创建)设为当前上下文。所有通过 pallocrepalloc 或 SPI - 实用函数分配的内存(本节另有说明的除外)都位于这个上下文中。当 C 函数通 + 辅助函数分配的内存(本节另有说明的除外)都位于这个上下文中。当 C 函数通 过 SPI_finish 与 SPI 管理器断开连接时,当前上下文 会恢复为上层执行器上下文,而在该 C 函数内存上下文中分配的所有内存都会被 释放,之后就不能再使用。 @@ -4360,7 +4351,7 @@ void SPI_pfree(void * pointer) SPI_copytuple - 在上层执行器上下文中创建一行的拷贝 + 在上层执行器上下文中创建一行的副本 @@ -4393,7 +4384,7 @@ HeapTuple SPI_copytuple(HeapTuple row) HeapTuple row - 要拷贝的行 + 要复制的行 @@ -4404,7 +4395,7 @@ HeapTuple SPI_copytuple(HeapTuple row) 返回值 - 拷贝后的行;出错时返回 NULL + 复制后的行;出错时返回 NULL (错误指示见 SPI_result @@ -4460,7 +4451,7 @@ HeapTupleHeader SPI_returntuple(HeapTuple row, TupleDesc HeapTuple row - 要拷贝的行 + 要复制的行 @@ -4469,7 +4460,7 @@ HeapTupleHeader SPI_returntuple(HeapTuple row, TupleDesc TupleDesc rowdesc - 行描述符(若要获得最佳缓存效果,大多数情况下应每次都传入同一个描述符) + 行描述符(若要获得最佳缓存效果,每次都传入同一个描述符) @@ -4480,7 +4471,7 @@ HeapTupleHeader SPI_returntuple(HeapTuple row, TupleDesc 返回值 - 指向拷贝后行的 HeapTupleHeader;出错时返回 + 指向复制后行的 HeapTupleHeader;出错时返回 NULL(错误指示见 SPI_result @@ -4582,13 +4573,14 @@ HeapTuple SPI_modifytuple(Relation rel, HeapTuple - 如果nullsNULL,那么 - SPI_modifytuple假定没有新值为空值。否则, - 如果对应的新值为非空,nulls数组的每一项都应 - 该是' ',而如果对应的新值为空值则为'n'(在 - 后一种情况中,对应的values项中的新值无关紧 - 要)。注意nulls不是一个文本字符串,只是一个 - 数组:它不需要一个'\0'终止符。 + 如果 nullsNULL,则 + SPI_modifytuple 会假定没有新值为空值。 + 否则,如果对应新值非空值,则 nulls 数组中 + 的对应项应为 ' ';如果对应新值为空值,则 + 对应项应为 'n'。(后一种情况下,对应 + values 项中的实际值无关紧要。)注意, + nulls 不是文本字符串,而只是一个数组,因此不 + 需要 '\0' 终止符。 @@ -4667,7 +4659,7 @@ void SPI_freetuple(HeapTuple row) SPI_freetuple释放之前在上层执行器上下文中 - 分配的一个行。 + 分配的一行。 @@ -4965,7 +4957,7 @@ void SPI_start_transaction(void) - 数据改变的可见性 + 数据更改的可见性 下列规则决定了使用 SPI 的函数(以及其他任何 C 函数)中数据更改的可见 diff --git a/zh/18/stylesheet-speedup-common.xsl b/zh/18/stylesheet-speedup-common.xsl index e3fb582a..403f350c 100644 --- a/zh/18/stylesheet-speedup-common.xsl +++ b/zh/18/stylesheet-speedup-common.xsl @@ -95,6 +95,6 @@ -en +zh_cn diff --git a/zh/18/syntax.sgml b/zh/18/syntax.sgml index b60a341f..683643e4 100644 --- a/zh/18/syntax.sgml +++ b/zh/18/syntax.sgml @@ -21,7 +21,7 @@ 词法结构 - token + 词元 @@ -29,7 +29,7 @@ - 一个词元可以是关键词标识符带引号的标识符文字值(或常量),或者特殊字符符号。词元通常由空白(空格、制表符、换行)分隔,但如果不存在歧义,则不必如此(一般只有特殊字符与其他类型的词元相邻时才会这样)。 + 一个词元可以是关键词标识符带引号的标识符字面量(或常量),或者特殊字符符号。词元通常由空白(空格、制表符、换行)分隔,但如果不存在歧义,则不必如此(一般只有特殊字符与其他类型的词元相邻时才会这样)。 @@ -58,18 +58,18 @@ INSERT INTO MY_TABLE VALUES (3, 'hi there'); 标识符和关键词 - identifier - syntax of + 标识符 + 语法 - name - syntax of + 名称 + 语法 - key word - syntax of + 关键词 + 语法 @@ -83,7 +83,7 @@ INSERT INTO MY_TABLE VALUES (3, 'hi there'); - identifierlength + 标识符长度 系统对标识符最多只使用 NAMEDATALEN-1 个字节;在命令中可以写更长的名称,但它们会被截断。默认情况下, NAMEDATALEN 为 64,因此标识符的最大长度是 63 字节。如果这个限制有问题,可以通过修改 src/include/pg_config_manual.h 中的 NAMEDATALEN 常量来提高。 @@ -91,8 +91,8 @@ INSERT INTO MY_TABLE VALUES (3, 'hi there'); - case sensitivity - of SQL commands + 大小写敏感性 + SQL 命令 关键词和未加引号的标识符不区分大小写。因此: @@ -110,8 +110,8 @@ UPDATE my_table SET a = 5; - quotation marks - and identifiers + 引号 + 与标识符 还有第二类标识符:定界标识符带引号的标识符。它通过把任意字符序列括在双引号中形成(")。 定界标识符始终是标识符,绝不会是关键词。因此,"select" 可以用来引用名为 select 的列或表,而不加引号的 select 会被视为关键词,因此在期望表名或列名的位置使用时会导致解析错误。这个示例可以用带引号的标识符写成: @@ -133,7 +133,7 @@ UPDATE "my_table" SET "a" = 5; Unicode 转义 - in identifiers + 在标识符中 @@ -177,7 +177,7 @@ U&"d!0061t!+000061" UESCAPE '!' 常量 - constant + 常量 @@ -188,19 +188,15 @@ U&"d!0061t!+000061" UESCAPE '!' 字符串常量 - character string - constant + 字符串 + 常量 - - - quotation marks + + 引号 转义 - SQL 中的字符串常量是由单引号括起的任意字符序列,例如 - 'This is a string'。要在字符串常量中包含单引号字符,请写两个相邻的单引号,例如 - 'Dianne''s horse'。注意,这与双引号字符("不同 - + SQL 中的字符串常量是由单引号(')括起的任意字符序列,例如 'This is a string'。要在字符串常量中包含单引号字符,请写两个相邻的单引号,例如 'Dianne''s horse'。注意,这不同于双引号字符(")。 两个只由空白及至少一个新行分隔的字符串常量会被连接在一起,并且将作为一个写在一起的字符串常量来对待。例如: @@ -304,7 +300,7 @@ SELECT 'foo' 'bar'; - 如果配置参数off,那么PostgreSQL对常规字符串常量和转义字符串常量中的反斜线转义都识别。不过,从PostgreSQL 9.1 开始,该参数的默认值为on,意味着只在转义字符串常量中识别反斜线转义。这种行为更兼容标准,但是可能打断依赖于历史行为(反斜线转义总是会被识别)的应用。作为一种变通,你可以设置该参数为off,但是最好迁移到符合新的行为。如果你需要使用一个反斜线转义来表示一个特殊字符,为该字符串常量写上一个E。 + 如果配置参数off,那么PostgreSQL对常规字符串常量和转义字符串常量中的反斜线转义都识别。不过,从PostgreSQL 9.1 开始,该参数的默认值为on,意味着只在转义字符串常量中识别反斜线转义。这种行为更兼容标准,但是可能使依赖历史行为(始终识别反斜线转义)的应用无法正常工作。作为一种变通,你可以设置该参数为off,但最好修改应用,不再使用反斜线转义。如果你需要使用一个反斜线转义来表示一个特殊字符,为该字符串常量写上一个E @@ -322,7 +318,7 @@ SELECT 'foo' 'bar'; Unicode 转义 - in string constants + 在字符串常量中 @@ -368,7 +364,7 @@ U&'d!0061t!+000061' UESCAPE '!' 美元引用的字符串常量 - dollar quoting + 美元引用 @@ -411,8 +407,8 @@ $function$ 位串常量 - bit string - constant + 位串 + 常量 @@ -432,8 +428,8 @@ $function$ 数字常量 - number - constant + 数字 + 常量 @@ -510,12 +506,12 @@ $function$ - 为数字常量最初指定的数据类型,只是类型解析算法的起点。在大多数情况下,常量会根据上下文被自动强制转换成最合适的类型。必要时,你可以通过类型转换强制把一个数值解释为特定的数据类型。type cast + 为数字常量最初指定的数据类型,只是类型解析算法的起点。在大多数情况下,常量会根据上下文被自动强制转换成最合适的类型。必要时,你可以通过类型转换强制把一个数值解释为特定的数据类型。类型转换 例如,可以通过下面的写法强制把一个数值当作类型 realfloat4)处理: -REAL '1.23' -- string style -1.23::REAL -- PostgreSQL (historical) style +REAL '1.23' -- 字符串形式 +1.23::REAL -- PostgreSQL(历史)形式 这些实际上只是下面将要讨论的一般类型转换记法的特例。 @@ -526,8 +522,8 @@ REAL '1.23' -- string style 其他类型的常量 - data type - constant + 数据类型 + 常量 @@ -553,7 +549,7 @@ CAST ( 'string' AS type ) - 如中所述,::CAST() 以及函数调用语法也可以用来指定任意表达式的运行时类型转换。为避免语法歧义,type 'string' 语法只能用来指定简单字面常量的类型。该语法的另一个限制是不能用于数组类型;要指定数组常量的类型,请使用 ::CAST()。 + 如中所述,::CAST() 以及函数调用语法也可以用来指定任意表达式的运行时类型转换。为避免语法歧义,type 'string' 语法只能用来指定简单字面常量的类型。type 'string' 语法的另一个限制是不能用于数组类型;要指定数组常量的类型,请使用 ::CAST() @@ -566,8 +562,8 @@ CAST ( 'string' AS type ) 操作符 - operator - syntax + 操作符 + 语法 @@ -617,7 +613,7 @@ CAST ( 'string' AS type ) - 圆括号(())具有它们通常的含义,用来分组表达式并且强制优先。在某些情况中,圆括号被要求作为一个特定 SQL 命令的固定语法的一部分。 + 圆括号(())具有它们通常的含义,用来对表达式分组并确定运算优先级。在某些情况中,圆括号被要求作为一个特定 SQL 命令的固定语法的一部分。 @@ -635,7 +631,7 @@ CAST ( 'string' AS type ) - 分号(;)结束一个 SQL 命令。它不能出现在一个命令中间的任何位置,除了在一个字符串常量中或者一个被引用的标识符中。 + 分号(;)结束一个 SQL 命令。它不能出现在一个命令中间的任何位置,除了在一个字符串常量中或者一个带引号的标识符中。 @@ -647,7 +643,7 @@ CAST ( 'string' AS type ) - 星号(*)在某些上下文中用来表示表行或组合值的所有字段。当它被用作聚合函数的参数时,还有一种特殊含义,即该聚合不需要任何显式参数。 + 星号(*)在某些上下文中用来表示表行或复合值的所有字段。当它被用作聚合函数的参数时,还有一种特殊含义,即该聚合不需要任何显式参数。 @@ -665,22 +661,22 @@ CAST ( 'string' AS type ) 注释 - comment - in SQL + 注释 + 在 SQL 中 注释是一串以双连字符开始并延伸到行尾的字符,例如: --- This is a standard SQL comment +-- 这是一条标准 SQL 注释 另外,也可以使用 C 风格注释块: -/* multiline comment - * with nesting: /* nested block comment */ +/* 多行注释 + * 包含嵌套:/* 嵌套块注释 */ */ 这里该注释开始于/*并且延伸到匹配出现的*/。这些注释块可按照 SQL 标准中指定的方式嵌套,但和 C 中不同。这样我们可以注释掉一大段可能包含注释块的代码。 @@ -695,8 +691,8 @@ CAST ( 'string' AS type ) 操作符优先级 - operator - precedence + 操作符 + 优先级 @@ -740,7 +736,7 @@ CAST ( 'string' AS type ) + - - 一元加、一元减 + 一元正号、一元负号 @@ -758,13 +754,13 @@ CAST ( 'string' AS type ) ^ - 指数 + 求幂 * / % - 乘、除、模 + 乘、除、取模 @@ -776,7 +772,7 @@ CAST ( 'string' AS type ) (任意其他操作符) - 所有其他本地以及用户定义的操作符 + 所有其他内置以及用户定义的操作符 @@ -833,18 +829,7 @@ SELECT 3 OPERATOR(pg_catalog.+) 4; - - 版本 9.5 之前的PostgreSQL使用的操作符优先级 - 规则略有不同。特别是,<=>= - 和<>习惯于被当作普通操作符,IS - 测试习惯于具有较高的优先级。并且在一些认为NOT比 - BETWEEN优先级高的情况下,NOT BETWEEN - 和相关的结构的行为不一致。为了更好地兼容 SQL 标准并且减少对 - 逻辑上等价的结构不一致的处理,这些规则也得到了修改。在大部分情况下, - 这些变化不会导致行为上的变化,或者可能会产生no such operator - 错误,但可以通过增加圆括号解决。不过在一些极端情况中,查询可能在 - 没有被报告解析错误的情况下发生行为的改变。 - + PostgreSQL 9.5 之前的版本使用的操作符优先级规则略有不同。特别是,<=>=<> 过去被当作普通操作符;IS 测试过去具有较高的优先级;而 NOT BETWEEN 和相关结构的处理不一致,在某些情况下被认为具有 NOT 而不是 BETWEEN 的优先级。为了更好地符合 SQL 标准,并减少对逻辑等价结构的不一致处理造成的困惑,这些规则得到了修改。在大部分情况下,这些变化不会导致行为变化,或者可能会产生 no such operator 错误,但可以通过增加圆括号解决。不过在一些极端情况下,查询可能在没有报告任何解析错误的情况下改变行为。
@@ -1537,7 +1522,7 @@ SELECT * FROM tbl WHERE a COLLATE "C" > 'foo'; SELECT * FROM tbl WHERE (a > 'foo') COLLATE "C"; - 因为它尝试把一个排序规则应用到>操作符的结果,而它的数据类型是非可排序数据类型boolean。 + 因为它尝试把一个排序规则应用到>操作符的结果,而它的数据类型是不支持排序规则的数据类型boolean。 diff --git a/zh/18/system-views.sgml b/zh/18/system-views.sgml index 84e8160d..9bb67669 100644 --- a/zh/18/system-views.sgml +++ b/zh/18/system-views.sgml @@ -1299,7 +1299,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; address text - 主机名或IP地址,或者allsamehostsamenet之一,对于本地连接为空 + 主机名或IP地址,或者allsamehostsamenet之一,对于本地连接为 NULL @@ -1308,7 +1308,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; netmask text - IP地址掩码,如果不适用则为空 + IP地址掩码,如果不适用则为 NULL @@ -1526,7 +1526,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; (参考 pg_tablespace.spcname) - 包含索引的表空间名(如果是数据库的默认值则为空) + 包含索引的表空间名(如果是数据库的默认值则为 NULL) @@ -1535,7 +1535,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; indexdef text - 索引定义(重构出的 命令) + 索引定义(重建出的 命令) @@ -1569,8 +1569,8 @@ AND c1.path[c2.level] = c2.path[c2.level]; 以及一般的数据库对象(由类OID和对象OID标识, 与pg_descriptionpg_depend中的方式相同)。 - 此外,扩展关系的权限被表示为一个单独的可锁定对象,以及更新 - pg_database.datfrozenxid 的更新权限。 + 此外,扩展关系的权利被表示为单独的可锁定对象,更新 + pg_database.datfrozenxid的权利也是如此。 此外,还可以对具有用户定义含义的数字施加咨询锁。 @@ -1617,7 +1617,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; (参考 pg_database.oid) - 锁目标存在的数据库的OID,如果目标是一个共享对象则为0,如果目标是一个事务ID则为空 + 锁目标存在的数据库的OID,如果目标是一个共享对象则为0,如果目标是一个事务ID则为 NULL @@ -1627,7 +1627,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; (参考 pg_class.oid) - 作为锁目标的关系的OID,如果目标不是一个关系或者只是关系的一部分则此列为空 + 作为锁目标的关系的OID,如果目标既不是关系,也不是关系的一部分则此列为 NULL @@ -1636,7 +1636,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; page int4 - 作为锁目标的页在关系中的页号,如果目标不是一个关系页或元组则此列为空 + 作为锁目标的页在关系中的页号,如果目标不是一个关系页或元组则此列为 NULL @@ -1645,7 +1645,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; tuple int2 - 作为锁目标的元组在页中的元组号,如果目标不是一个元组则此列为空 + 作为锁目标的元组在页中的元组号,如果目标不是一个元组则此列为 NULL @@ -1654,7 +1654,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; virtualxid text - 锁定目标事务的虚拟 ID,如果目标不是虚拟事务 ID,则为空;见 + 锁定目标事务的虚拟 ID,如果目标不是虚拟事务 ID,则为 NULL;见 @@ -1664,7 +1664,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; transactionid xid - 锁定目标事务的标识,如果目标不是事务 ID,则为空; + 锁定目标事务的标识,如果目标不是事务 ID,则为 NULL; @@ -1674,7 +1674,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; (参考 pg_class.oid) - 包含锁目标的系统目录的OID,如果目标不是一个普通数据库对象则此列为空 + 包含锁目标的系统目录的OID,如果目标不是一个普通数据库对象则此列为 NULL @@ -1684,7 +1684,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; (参考任意 OID 列) - 锁目标在它的系统目录中的OID,如果目标不是一个普通数据库对象则为空 + 锁目标在它的系统目录中的OID,如果目标不是一个普通数据库对象则为 NULL @@ -1693,7 +1693,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; objsubid int2 - 锁的目标列号(classidobjid指表本身),如果目标是某种其他普通数据库对象则此列为0,如果目标不是一个普通数据库对象则此列为空 + 锁的目标列号(classidobjid指表本身),如果目标是某种其他普通数据库对象则此列为0,如果目标不是一个普通数据库对象则此列为 NULL @@ -1711,7 +1711,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; pid int4 - 保持这个锁或者正在等待这个锁的服务器进程的PID,如果此锁被一个预备事务所持有则此列为空 + 保持这个锁或者正在等待这个锁的服务器进程的PID,如果此锁被一个预备事务所持有则此列为 NULL @@ -1747,8 +1747,8 @@ AND c1.path[c2.level] = c2.path[c2.level]; waitstart timestamptz - 服务器进程开始等待该锁的时间;如果锁已被授予则为空。 - 注意,在开始等待之后,即使grantedfalse,该值在极短时间内也可能仍为空。 + 服务器进程开始等待该锁的时间;如果锁已被授予则为 NULL。 + 注意,在开始等待之后,即使grantedfalse,该值在极短时间内也可能仍为 NULL。 @@ -1780,8 +1780,8 @@ AND c1.path[c2.level] = c2.path[c2.level]; 咨询锁可以在由单个 bigint 值或两个整数值组成的键上获取。 - 一个bigint键在classid列中显示其高阶半部分, - 在objid列中显示其低阶半部分,并且objsubid等于1。 + 一个bigint键在classid列中显示其高位半部分, + 在objid列中显示其低位半部分,并且objsubid等于1。 可以使用表达式(classid::bigint << 32) | objid::bigint重新组装原始bigint值。 整数键在classid列中显示第一个键,在objid列中显示第二个键, 并且 objsubid 等于 2。键的实际含义由用户自行决定。咨询锁在每个数据库内都是本地的, @@ -1830,15 +1830,15 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx pg_locks视图显示来自常规锁管理器和谓词锁管理器的数据,这两个是独立的系统; - 此外,常规锁管理器将其锁分为常规锁和fast-path锁。 + 此外,常规锁管理器将其锁分为常规锁和快速路径锁。 不能保证这些数据完全一致。 当查询该视图时, - fast-path 锁的数据(具有fastpath = true) + 快速路径锁的数据(具有fastpath = true) 从每个后端逐个收集,而不会冻结整个锁管理器的状态,因此在收集信息时可能会发生锁的获取或释放。 但请注意,这些锁已知不会与当前放置的任何其他锁发生冲突。 - 在查询所有后端的 fast-path 锁后,剩余的常规锁管理器将作为一个单元被锁定,并且所有剩余锁的一致快照将作为一个原子操作收集。 + 在查询所有后端的快速路径锁后,剩余的常规锁管理器将作为一个单元被锁定,并且所有剩余锁的一致快照将作为一个原子操作收集。 解锁常规锁管理器后,谓词锁管理器类似地被锁定,并且所有谓词锁将作为一个原子操作收集。 - 因此,除了 fast-path 锁外,每个锁管理器将提供一致的结果集,但由于我们不同时锁定两个锁管理器,因此在询问常规锁管理器后和在询问谓词锁管理器前,可能会发生锁的获取或释放。 + 因此,除了快速路径锁外,每个锁管理器将提供一致的结果集,但由于我们不同时锁定两个锁管理器,因此在询问常规锁管理器后和在询问谓词锁管理器前,可能会发生锁的获取或释放。 @@ -1914,7 +1914,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx (参考 pg_tablespace.spcname) - 包含物化视图的表空间名(如使用数据库默认表空间则为空) + 包含物化视图的表空间名(如使用数据库默认表空间则为 NULL) @@ -1941,7 +1941,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx definition text - 物化视图的定义(一个重构的查询) + 物化视图的定义(一个重建的查询) @@ -2132,7 +2132,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx 该预备语句返回列的类型,以 regtype 数组形式表示。该数组中某个元素对应的 OID 可以通过将 - regtype 值转换为 oid 获得。如果预备语句不提供结果(例如 DML 语句),则该字段为空。 + regtype 值转换为 oid 获得。如果预备语句不提供结果(例如 DML 语句),则该字段为 NULL。 @@ -2547,7 +2547,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx confirmed_flush_lsn pg_lsn - 逻辑槽消费者已确认接收到数据的地址(LSN)。在此 LSN 之前提交的事务所对应的数据将不再可用。物理槽为 NULL。 + 逻辑槽消费者已确认接收的数据所到达的地址(LSN)。在此 LSN 之前提交的事务所对应的数据将不再可用。物理槽为 NULL @@ -2610,7 +2610,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx inactive_since timestamptz - 槽变为不活动的时间。如果该槽当前正在被流式传输,则为 NULL。如果该槽变为无效,该值将不再更新。对于从主库同步而来的备库逻辑槽(其 synced 字段为 true),inactive_since 表示槽同步(参见 )最近一次停止的时间。如果该槽始终保持同步,则为 NULL。这有助于跟踪备库上的槽同步何时被中断。 + 槽变为不活动的时间。如果当前正在从该槽流式传输数据,则为 NULL。如果该槽变为无效,该值将不再更新。对于从主库同步而来的备库逻辑槽(其 synced 字段为 true),inactive_since 表示槽同步(参见 )最近一次停止的时间。如果该槽始终保持同步,则为 NULL。这有助于跟踪备库上的槽同步何时被中断。 @@ -2642,7 +2642,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - wal_level_insufficient 表示主库没有足够的 来执行逻辑解码。该值只会设置在逻辑槽上。 + wal_level_insufficient 表示主库的 不足以支持逻辑解码。该值只会设置在逻辑槽上。 @@ -2686,7 +2686,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx 视图pg_roles提供数据库角色的信息。它本质上是 - pg_authid 的公开可读视图,并将密码字段清空。 + pg_authid 的公开可读视图,并隐藏密码字段。 @@ -2772,7 +2772,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx rolconnlimitint4 - 对于可以登录的角色,本列设置该角色可以同时发起最大连接数。-1表示无限制。 + 对于可以登录的角色,本列设置该角色能够建立的最大并发连接数。-1 表示无限制。 @@ -2790,7 +2790,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx rolvaliduntiltimestamptz - 密码过期时间(只用于密码认证),如果永不过期则为空 + 密码过期时间(仅用于密码认证);不设过期时间时为 NULL @@ -2888,7 +2888,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx definitiontext - 规则定义(创建命令的重构) + 规则定义(重建的创建命令) @@ -2974,7 +2974,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx (参考 pg_namespace.oid) - 如果适用,为此对象的命名空间 OID;否则为空。 + 如果适用,为此对象的命名空间 OID;否则为 NULL。 @@ -3281,7 +3281,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx min_valtext - 参数的最小允许值(对非数值参数为空) + 参数的最小允许值(对非数值参数为 NULL) @@ -3290,7 +3290,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx max_valtext - 参数的最大允许值(对非数值参数为空) + 参数的最大允许值(对非数值参数为 NULL) @@ -3299,7 +3299,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx enumvalstext[] - 枚举参数的允许值(对非枚举参数为空) + 枚举参数的允许值(对非枚举参数为 NULL) @@ -3487,7 +3487,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx 这个名称源于该表不应向公众开放读取,因为它包含密码。 pg_user - 是 pg_shadow 的公开可读视图,并将密码字段清空。 + 是 pg_shadow 的公开可读视图,并隐藏密码字段。
@@ -3826,7 +3826,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx null_fracfloat4 - 列项中为空的比例 + 列项中为 NULL 的比例 @@ -3854,7 +3854,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx most_common_valsanyarray - 列中高频值的一个列表(如果没有任何一个值看起来比其他值更常用,此列为空) + 列中高频值的一个列表(如果没有任何一个值看起来比其他值更常用,此列为 NULL) @@ -3863,7 +3863,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx most_common_freqsfloat4[] - 高频值的频率列表,即每一个高频值的出现次数除以总行数(如果most_common_vals为空,则此列为空) + 高频值的频率列表,即每一个高频值的出现次数除以总行数(如果most_common_vals为 NULL,则此列为 NULL) @@ -3872,7 +3872,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx histogram_boundsanyarray - 将列值划分成大小接近的组的值列表。如果存在most_common_vals,其中的值会被直方图计算所忽略(如果列类型没有一个<操作符或者most_common_vals等于整个值集合,则此列为空) + 将列值划分成大小接近的组的值列表。如果存在most_common_vals,其中的值会被直方图计算所忽略(如果列类型没有一个<操作符或者most_common_vals等于整个值集合,则此列为 NULL) @@ -3881,7 +3881,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx correlationfloat4 - 物理行顺序和列值逻辑顺序之间的统计关联。其范围从-1到+1。当值接近-1或+1时,在列上的一个索引扫描被认为比值接近0时的代价更低,因为这种情况减少了对磁盘的随机访问(如果列数据类型不具有一个<操作符,则此列为空) + 物理行顺序和列值逻辑顺序之间的统计关联。其范围从-1到+1。当值接近-1或+1时,在列上的一个索引扫描被认为比值接近0时的代价更低,因为这种情况减少了对磁盘的随机访问(如果列数据类型不具有一个<操作符,则此列为 NULL) @@ -3890,7 +3890,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx most_common_elemsanyarray - 在列值中,最经常出现的非空元素列表(对标量类型为空) + 在列值中,最经常出现的非空元素列表(对标量类型为 NULL) @@ -3900,7 +3900,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx 最常用元素值的频度列表,即含有至少一个给定值实例的行的分数。 - 在每个元素的频度之后有二至三个附加值,它们是每个元素频度的最小和最大值,以及可选的空元素的频度(如果most_common_elems为空,则此列为空) + 在每个元素的频度之后有二至三个附加值,它们是每个元素频度的最小和最大值,以及可选的空元素的频度(如果most_common_elems为 NULL,则此列为 NULL) @@ -3909,7 +3909,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx elem_count_histogramfloat4[] - 在列值中可区分非空元素值计数的一个直方图,后面跟随可区分非空元素的平均数(对于标量类型为空) + 在列值中可区分非空元素值计数的一个直方图,后面跟随可区分非空元素的平均数(对于标量类型为 NULL) @@ -3918,7 +3918,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx range_length_histogramanyarray - 范围类型列中非空且非 NULL 的范围值长度直方图。(对非范围类型为空。) + 范围类型列中非空且非 NULL 的范围值长度直方图。(非范围类型为 null。) 该直方图使用范围函数 subtype_diff 计算,而不考虑范围边界是否包含端点。 @@ -3930,7 +3930,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx range_empty_frac float4 - 列项中值为空范围的比例。(对非范围类型为空。) + 列项中值为空范围的比例。(非范围类型为 null。) @@ -3939,10 +3939,10 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx range_bounds_histogramanyarray - 非空且非 NULL 的范围值下界和上界的直方图。(对非范围类型为空。) + 非空且非 NULL 的范围值下界和上界的直方图。(非范围类型为 null。) - 这两个直方图表示为单个数组列,其中下半部分表示下界的直方图,上半部分表示上界的直方图。 + 这两个直方图表示为一个范围数组,其中各范围的下界表示下界直方图,上界表示上界直方图。 @@ -4108,7 +4108,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx most_common_valstext[] - 列中值的最常见组合的列表(如果没有组合看上去比其它的更常见,则为空。) + 列中值的最常见组合的列表(如果没有组合看上去比其它的更常见,则为 NULL。) @@ -4117,7 +4117,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx most_common_val_nullsbool[] - 值最常见组合的NULL标志的列表(当most_common_vals是空值时,为空。) + 值最常见组合的NULL标志的列表(当most_common_vals为 NULL 时,为 NULL。) @@ -4126,7 +4126,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx most_common_freqsfloat8[] - 最常见组合的频率的列表,即每个出现的数量除以行的总数(当most_common_vals是空值时,为空) + 最常见组合的频率的列表,即每个出现的数量除以行的总数(当most_common_vals为 NULL 时,为 NULL) @@ -4135,7 +4135,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx most_common_base_freqsfloat8[] - 最常见组合的基本频率的列表,即每个值频率的乘积。(当most_common_vals是空值时,为空。) + 最常见组合的基本频率的列表,即每个值频率的乘积。(当most_common_vals为 NULL 时,为 NULL。) @@ -4260,7 +4260,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx null_fracfloat4 - 表达式条目为空的比例 + 表达式条目为 NULL 的比例 @@ -4288,7 +4288,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx most_common_valsanyarray - 表达式中高频值的列表(如果没有值看起来比任何其他值更常见则为空) + 表达式中高频值的列表(如果没有值看起来比任何其他值更常见则为 NULL) @@ -4297,7 +4297,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx most_common_freqsfloat4[] - 高频值的频率列表,即每一个高频值的出现次数除以总行数(如果most_common_vals为空,则此列为空) + 高频值的频率列表,即每一个高频值的出现次数除以总行数(如果most_common_vals为 NULL,则此列为 NULL) @@ -4306,7 +4306,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx histogram_boundsanyarray - 将表达式的值划分成大小接近的组的值列表。如果存在most_common_vals,其中的值会被直方图计算所忽略(如果表达式的数据类型没有一个<操作符或者most_common_vals等于整个值集合,则此列为空) + 将表达式的值划分成大小接近的组的值列表。如果存在most_common_vals,其中的值会被直方图计算所忽略(如果表达式的数据类型没有一个<操作符或者most_common_vals等于整个值集合,则此列为 NULL) @@ -4315,7 +4315,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx correlationfloat4 - 物理行顺序和表达式值逻辑顺序之间的统计关联。其范围从-1到+1。当值接近-1或+1时,在表达式上的一个索引扫描被认为比值接近0时的代价更低,因为这种情况减少了对磁盘的随机访问(如果表达式的数据类型不具有一个<操作符,则此列为空) + 物理行顺序和表达式值逻辑顺序之间的统计关联。其范围从-1到+1。当值接近-1或+1时,在表达式上的一个索引扫描被认为比值接近0时的代价更低,因为这种情况减少了对磁盘的随机访问(如果表达式的数据类型不具有一个<操作符,则此列为 NULL) @@ -4324,7 +4324,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx most_common_elemsanyarray - 与表达式的值一起最常出现的非空元素值的列表。(标量类型时为空) + 与表达式的值一起最常出现的非空元素值的列表。(标量类型时为 NULL) @@ -4334,7 +4334,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx 最常用元素值的频度列表,即含有至少一个给定值实例的行的分数。 - 在每个元素的频度之后有二至三个附加值,它们是每个元素频度的最小和最大值,以及可选的空元素的频度(如果most_common_elems为空,则此列为空) + 在每个元素的频度之后有二至三个附加值,它们是每个元素频度的最小和最大值,以及可选的空元素的频度(如果most_common_elems为 NULL,则此列为 NULL) @@ -4343,7 +4343,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx elem_count_histogramfloat4[] - 表达式值的不同非空元素值的计数的直方图,后面跟着不同非空元素的平均数量。(标量类型时为空) + 表达式值的不同非空元素值的计数的直方图,后面跟着不同非空元素的平均数量。(标量类型时为 NULL) @@ -4420,7 +4420,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx (参考 pg_tablespace.spcname) - 包含该表的表空间名称(如果使用数据库的默认表空间,此列为空) + 包含该表的表空间名称(如果使用数据库的默认表空间,此列为 NULL) @@ -4617,7 +4617,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx 视图pg_user提供数据库用户的信息。它本质上是 - pg_shadow 的公开可读视图,并将密码字段清空。 + pg_shadow 的公开可读视图,并隐藏密码字段。
@@ -4895,7 +4895,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx definitiontext - 视图定义(一个重构的查询) + 视图定义(一个重建的查询) diff --git a/zh/18/targets-meson.txt b/zh/18/targets-meson.txt index d0021a5e..0fcabe3f 100644 --- a/zh/18/targets-meson.txt +++ b/zh/18/targets-meson.txt @@ -7,37 +7,37 @@ # remaining lines are target separated by whitespace from their description # Code Targets: - all Build everything other than documentation - backend Build backend and related modules - bin Build frontend binaries - contrib Build contrib modules - pl Build procedural languages + all 构建文档以外的所有内容 + backend 构建后端及相关模块 + bin 构建前端二进制程序 + contrib 构建 contrib 模块 + pl 构建过程语言 Developer Targets: - reformat-dat-files Rewrite catalog data files into standard format - expand-dat-files Expand all data files to include defaults - update-unicode Update unicode data to new version + reformat-dat-files 将系统目录数据文件改写为标准格式 + expand-dat-files 展开所有数据文件以包含默认值 + update-unicode 将 Unicode 数据更新到新版本 Documentation Targets: - html Build documentation in multi-page HTML format - man Build documentation in man page format - docs Build documentation in multi-page HTML and man page format - doc/src/sgml/postgres-A4.pdf Build documentation in PDF format, with A4 pages - doc/src/sgml/postgres-US.pdf Build documentation in PDF format, with US letter pages - doc/src/sgml/postgres.html Build documentation in single-page HTML format - alldocs Build documentation in all supported formats + html 构建多页 HTML 格式的文档 + man 构建手册页格式的文档 + docs 构建多页 HTML 和手册页格式的文档 + doc/src/sgml/postgres-A4.pdf 构建 A4 页面大小的 PDF 格式文档 + doc/src/sgml/postgres-US.pdf 构建 US letter 页面大小的 PDF 格式文档 + doc/src/sgml/postgres.html 构建单页 HTML 格式的文档 + alldocs 构建所有支持格式的文档 Installation Targets: - install Install postgres, excluding documentation - install-docs Install documentation in multi-page HTML and man page formats - install-html Install documentation in multi-page HTML format - install-man Install documentation in man page format - install-quiet Like "install", but installed files are not displayed - install-world Install postgres, including multi-page HTML and man page documentation - uninstall Remove installed files + install 安装 postgres,不包括文档 + install-docs 安装多页 HTML 和手册页格式的文档 + install-html 安装多页 HTML 格式的文档 + install-man 安装手册页格式的文档 + install-quiet 与“install”相同,但不显示安装的文件 + install-world 安装 postgres,包括多页 HTML 和手册页格式的文档 + uninstall 删除已安装的文件 Other Targets: - clean Remove all build products - test Run all enabled tests (including contrib) - world Build everything, including documentation - help List important targets + clean 删除所有构建产物 + test 运行所有已启用的测试(包括 contrib) + world 构建所有内容,包括文档 + help 列出重要的目标 diff --git a/zh/18/textsearch.sgml b/zh/18/textsearch.sgml index dd40b2ea..17771cbf 100644 --- a/zh/18/textsearch.sgml +++ b/zh/18/textsearch.sgml @@ -2099,7 +2099,7 @@ ALTER TEXT SEARCH CONFIGURATION russian 分类词典示例 - 考虑简单的天文词库 thesaurus_astro,其中包含一些天文单词组合: + 考虑简单的天文词库 thesaurus_astro,其中包含一些天文单词组合: supernovae stars : sn @@ -2534,7 +2534,7 @@ ts_debug( config re - 以下是一个简单的示例: + 以下是一个简单的示例: SELECT * FROM ts_debug('english', 'a fat cat sat on a mat - it ate a fat rats'); diff --git a/zh/18/trigger.sgml b/zh/18/trigger.sgml index d830948f..e4f6aa01 100644 --- a/zh/18/trigger.sgml +++ b/zh/18/trigger.sgml @@ -4,7 +4,7 @@ 触发器 - trigger + 触发器 @@ -125,7 +125,7 @@ - 在执行 MERGE 命令时,对于该命令动作中指定的事件,无论该动作最终是否实际执行,语句级 + 在执行 MERGE 命令时,对于 MERGE 命令的动作中指定的事件,无论该动作最终是否实际执行,语句级 BEFOREAFTER 触发器都会触发。这与更新零行的 UPDATE 语句相同:尽管没有行被更新,语句级触发器仍会触发。只有在某行确实被更新、插入或删除时,行级触发器才会触发。因此,完全可能出现这样的情况:某类动作的语句级触发器已经触发,而同类动作的行级触发器却一个也没有触发。 @@ -169,8 +169,7 @@ 生成列还有一些额外注意事项。 - generated columnin - triggers + 生成列在触发器中 存储型生成列会在 BEFORE 触发器之后、AFTER 触发器之前计算。因此,可以在 AFTER 触发器中检查生成值。在 BEFORE 触发器中,OLD 行如预期那样包含旧的 @@ -181,7 +180,7 @@ - 如果在同一关系上的同一事件为其定义了多个触发器,它们会按触发器名称的字母顺序触发。对于 BEFOREINSTEAD OF + 如果为同一关系上的同一事件定义了多个触发器,它们会按触发器名称的字母顺序触发。对于 BEFOREINSTEAD OF 触发器,每个触发器返回的、可能已经被修改过的行都会成为下一个触发器的输入。如果任何一个 BEFOREINSTEAD OF 触发器返回 NULL,则会放弃对该行执行该操作,并且后续触发器(针对该行)都不会再触发。 @@ -191,7 +190,7 @@ 条件,不过这个特性对它们用处不大。)在 BEFORE 触发器中, WHEN 条件就在函数即将执行或本会执行之前求值,因此使用 WHEN 与在触发器函数开头测试同样的条件并无实质差别。不过,在 - AFTER 触发器中,WHEN 条件会在行更改发生后立即求值,并决定是否要在语句末尾将一个事件排入队列以触发该触发器。因此,当 AFTER 触发器的 WHEN + AFTER 触发器中,WHEN 条件会在行更改发生后立即求值,并决定是否要将一个事件排入队列,以便在语句末尾触发该触发器。因此,当 AFTER 触发器的 WHEN 条件不返回真时,就不必排队该事件,也不必在语句末尾重新取出该行。如果触发器只需要针对少数几行触发,这会让修改大量行的语句显著加快。 INSTEAD OF 触发器不支持 WHEN 条件。 @@ -217,8 +216,8 @@ - trigger - arguments for trigger functions + 触发器 + 触发器函数的参数 在定义触发器时,可以为它指定参数。在触发器定义中包含参数,是为了让需求相似的不同触发器能够调用同一个函数。举例来说,可以有一个通用触发器函数,它接受两个列名作为参数,把当前用户写入其中一个列,把当前时间戳写入另一个列。只要编写得当,这个触发器函数就应独立于它所作用的具体表。因此,同一个函数可用于任何具有适当列的表上的 INSERT 事件,例如自动跟踪某个事务表中记录的创建。如果把它定义成 UPDATE 触发器,还可以用来跟踪最近更新事件。 @@ -301,13 +300,13 @@ 用 C 编写触发器函数 - trigger - in C + 触发器 + 在 C 中 - transition tables - referencing from C trigger + 过渡表 + 从 C 触发器中引用 @@ -319,7 +318,7 @@ - 当函数由触发器管理器调用时,不会向它传递任何普通参数,但会传递一个指向 TriggerData 结构体的 context 指针。C 函数可以通过执行下列宏来检查自己是否由触发器管理器调用: + 当函数由触发器管理器调用时,不会向它传递任何普通参数,但会传递一个指向 TriggerData 结构体的 上下文 指针。C 函数可以通过执行下列宏来检查自己是否由触发器管理器调用: CALLED_AS_TRIGGER(fcinfo) @@ -378,7 +377,7 @@ typedef struct TriggerData TRIGGER_FIRED_BEFORE(tg_event) - 如果触发器在操作之前触发,则返回 true。 + 如果触发器在操作之前触发,则返回真。 @@ -387,7 +386,7 @@ typedef struct TriggerData TRIGGER_FIRED_AFTER(tg_event) - 如果触发器在操作之后触发,则返回 true。 + 如果触发器在操作之后触发,则返回真。 @@ -396,7 +395,7 @@ typedef struct TriggerData TRIGGER_FIRED_INSTEAD(tg_event) - 如果触发器是取代该操作而触发,则返回 true。 + 如果触发器是取代该操作而触发,则返回真。 @@ -405,7 +404,7 @@ typedef struct TriggerData TRIGGER_FIRED_FOR_ROW(tg_event) - 如果触发器是因行级事件触发,则返回 true。 + 如果触发器是因行级事件触发,则返回真。 @@ -414,7 +413,7 @@ typedef struct TriggerData TRIGGER_FIRED_FOR_STATEMENT(tg_event) - 如果触发器是因语句级事件触发,则返回 true。 + 如果触发器是因语句级事件触发,则返回真。 @@ -423,7 +422,7 @@ typedef struct TriggerData TRIGGER_FIRED_BY_INSERT(tg_event) - 如果触发器是由 INSERT 命令触发,则返回 true。 + 如果触发器是由 INSERT 命令触发,则返回真。 @@ -432,7 +431,7 @@ typedef struct TriggerData TRIGGER_FIRED_BY_UPDATE(tg_event) - 如果触发器是由 UPDATE 命令触发,则返回 true。 + 如果触发器是由 UPDATE 命令触发,则返回真。 @@ -441,7 +440,7 @@ typedef struct TriggerData TRIGGER_FIRED_BY_DELETE(tg_event) - 如果触发器是由 DELETE 命令触发,则返回 true。 + 如果触发器是由 DELETE 命令触发,则返回真。 @@ -450,7 +449,7 @@ typedef struct TriggerData TRIGGER_FIRED_BY_TRUNCATE(tg_event) - 如果触发器是由 TRUNCATE 命令触发,则返回 true。 + 如果触发器是由 TRUNCATE 命令触发,则返回真。 @@ -609,16 +608,16 @@ typedef struct Trigger - 一个完整的触发器实例 + 一个完整的触发器示例 这里给出一个非常简单的、用 C 编写的触发器函数示例。(用过程语言编写的触发器示例可见各过程语言的文档。) - 如果某条命令试图向列 x 中插入空值,函数 - trigf 就会报告表 ttest - 中的行数,并跳过实际操作。(这样,这个触发器就起到了非空约束的作用,但不会中止事务。) + 函数 trigf 会报告表 ttest 中的行数, + 并在命令试图向列 x 中插入空值时跳过实际操作。 + (这样,这个触发器就起到了非空约束的作用,但不会中止事务。) diff --git a/zh/18/typeconv.sgml b/zh/18/typeconv.sgml index 15e7c27c..984ee0cf 100644 --- a/zh/18/typeconv.sgml +++ b/zh/18/typeconv.sgml @@ -30,7 +30,7 @@ -PostgreSQL扫描器/解析器将词法元素分成五个基本类别:整数、非整数数字、字符串、标识符和关键字。大多数非数值类型的常量会先被归类为字符串。SQL语言定义允许用字符串指定类型名,而PostgreSQL可以利用这一机制让解析器从一开始就沿着正确的路径处理。例如,查询: +PostgreSQL扫描器/解析器将词法元素分成五个基本类别:整数、非整数数字、字符串、标识符和关键字。大多数非数值类型的常量会先被归类为字符串。SQL语言定义允许给字符串指定类型名,而PostgreSQL可以利用这一机制让解析器从一开始就沿着正确的路径处理。例如,查询: SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; @@ -41,7 +41,7 @@ SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; (1 row) -包含两个文字常量,它们的类型分别是textpoint。如果没有为某个字符串文字指定类型,那么它最初会被赋予占位类型unknown,并在后文所述的后续阶段解析。 +包含两个字面量,它们的类型分别是textpoint。如果没有为某个字符串字面量指定类型,那么它最初会被赋予占位类型unknown,并在后文所述的后续阶段解析。 @@ -166,11 +166,11 @@ SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; -检查是否存在一个恰好接受输入参数类型的操作符。如果存在(在被考虑的操作符集合中至多只有一个精确匹配),就使用它。若通过限定名调用(这种情况并不常见)某个允许不可信用户创建对象的模式中的操作符,而又缺少精确匹配,就会带来安全隐患 +检查是否存在一个恰好接受输入参数类型的操作符。如果存在(在被考虑的操作符集合中至多只有一个精确匹配),就使用它。若通过限定名调用(这种情况并不常见)某个允许不受信任的用户创建对象的模式中的操作符,而又缺少精确匹配,就会带来安全隐患 - 对于未带模式限定的名称,不会出现这种隐患,因为包含允许不可信用户创建对象的模式的搜索路径不是一种模式的安全使用方式。 + 对于未带模式限定的名称,不会出现这种隐患,因为包含允许不受信任的用户创建对象的模式的搜索路径不是一种模式的安全使用方式。 。在这种情况下,应通过对参数进行类型转换来强制获得精确匹配。 @@ -186,7 +186,7 @@ SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; -如果二元操作符调用的一个参数是unknown类型,而另一个是域类型,则接着检查是否存在两边都恰好接受该域基类型的操作符;如果有,就使用它。 +如果二元操作符调用的一个参数是unknown类型,而另一个是域类型,则接着检查是否存在两边都恰好接受该域基础类型的操作符;如果有,就使用它。 @@ -201,13 +201,13 @@ SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; -丢弃那些输入类型不匹配,且也无法通过隐式类型转换实现匹配的候选操作符。为此,假定unknown文字可以转换为任何类型。如果只剩一个候选操作符,就使用它;否则继续下一步。 +丢弃那些输入类型不匹配,且也无法通过隐式类型转换实现匹配的候选操作符。为此,假定unknown字面量可以转换为任何类型。如果只剩一个候选操作符,就使用它;否则继续下一步。 -如果任何输入参数是域类型,则在后续所有步骤中都把它当作该域的基类型。这样可以确保在解决操作符歧义时,域的行为与其基类型一致。 +如果任何输入参数是域类型,则在后续所有步骤中都把它当作该域的基础类型。这样可以确保在解决操作符歧义时,域的行为与其基础类型一致。 @@ -219,13 +219,13 @@ SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; -遍历所有候选操作符,保留那些在需要类型转换的最多位置上接受首选类型(属于输入数据类型的类型分类)的候选项。如果没有候选项接受首选类型,则保留全部候选项。如果只剩一个候选操作符,就使用它;否则继续下一步。 +遍历所有候选操作符,在需要类型转换的位置上,保留接受首选类型(属于输入数据类型的类型分类)的位置数最多的候选项。如果没有候选项接受首选类型,则保留全部候选项。如果只剩一个候选操作符,就使用它;否则继续下一步。 -如果有任何输入参数是unknown,就检查剩余候选操作符在这些参数位置上接受哪些类型分类。在每个位置上,如果有任何候选项接受string分类,就选择该分类。(这种偏向字符串的做法是合适的,因为unknown类型的文字看起来像字符串。)否则,如果所有剩余候选项都接受同一种类型分类,就选择该分类;否则失败,因为在缺少更多线索的情况下无法推断出正确选择。然后丢弃不接受所选类型分类的候选项。此外,如果有任何候选项接受该分类中的首选类型,就丢弃在该参数上接受非首选类型的候选项。如果没有候选项通过这些测试,则保留全部候选项。如果只剩一个候选操作符,就使用它;否则继续下一步。 +如果有任何输入参数是unknown,就检查剩余候选操作符在这些参数位置上接受哪些类型分类。在每个位置上,如果有任何候选项接受string分类,就选择该分类。(这种偏向字符串的做法是合适的,因为unknown类型的字面量看起来像字符串。)否则,如果所有剩余候选项都接受同一种类型分类,就选择该分类;否则失败,因为在缺少更多线索的情况下无法推断出正确选择。然后丢弃不接受所选类型分类的候选项。此外,如果有任何候选项接受该分类中的首选类型,就丢弃在该参数上接受非首选类型的候选项。如果没有候选项通过这些测试,则保留全部候选项。如果只剩一个候选操作符,就使用它;否则继续下一步。 @@ -273,7 +273,7 @@ SELECT |/ CAST(40 AS double precision) AS "square root of 40"; -一个只有一个未指定参数的例子: +一个参数未指定类型的例子: SELECT text 'abc' || 'def' AS "text and unknown"; @@ -301,7 +301,7 @@ SELECT 'abc' || 'def' AS "unspecified"; -这里对使用哪种类型没有初始提示,因为查询中没有指定任何类型。因此,解析器会查找所有候选操作符,并发现既有接受字符串分类输入的候选项,也有接受位串分类输入的候选项。由于在可用时优先选择字符串分类,所以会选中该分类,再使用字符串的首选类型text作为解析这些unknown类型文字的具体类型。 +这里对使用哪种类型没有初始提示,因为查询中没有指定任何类型。因此,解析器会查找所有候选操作符,并发现既有接受字符串分类输入的候选项,也有接受位串分类输入的候选项。由于在可用时优先选择字符串分类,所以会选中该分类,再使用字符串的首选类型text作为解析这些unknown类型字面量的具体类型。 @@ -318,7 +318,7 @@ SELECT @ '-4.5' AS "abs"; 4.5 (1 row) -这里,系统在应用所选操作符之前,已经把unknown类型文字隐式解析为float8。我们可以验证使用的确实是float8,而不是其他类型: +这里,系统在应用所选操作符之前,已经把unknown类型字面量隐式解析为float8。我们可以验证使用的确实是float8,而不是其他类型: SELECT @ '-4.5e500' AS "abs"; @@ -352,7 +352,7 @@ SELECT ~ CAST('20' AS int8) AS "negation"; 数组包含操作符类型解析 -下面是另一个解析一边已知、一边未知输入的操作符的例子: +下面是另一个解析带有一个已知类型输入和一个未知类型输入的操作符的例子: SELECT array[1,2] <@ '{1,2,3}' as "is subset"; @@ -361,7 +361,7 @@ SELECT array[1,2] <@ '{1,2,3}' as "is subset"; t (1 row) -PostgreSQL操作符目录中为中缀操作符<@定义了多个条目,但左侧能够接受整数数组的只有两种:数组包含(anyarray <@ anyarray)和范围包含(anyelement <@ anyrange)。由于这些多态伪类型(见)都不被视为首选类型,解析器无法据此消除歧义。不过,告诉它可以假定unknown类型文字与另一输入具有相同类型,也就是整数数组。这样两个操作符中只有一个能够匹配,因此会选择数组包含。(如果选中范围包含,就会报错,因为该字符串的格式并不是合法的范围文字。) +PostgreSQL操作符目录中为中缀操作符<@定义了多个条目,但左侧能够接受整数数组的只有两种:数组包含(anyarray <@ anyarray)和范围包含(anyelement <@ anyrange)。由于这些多态伪类型(见)都不被视为首选类型,解析器无法据此消除歧义。不过,要求它假定unknown类型字面量与另一输入具有相同类型,也就是整数数组。这样两个操作符中只有一个能够匹配,因此会选择数组包含。(如果选中范围包含,就会报错,因为该字符串的格式并不是合法的范围字面量。) @@ -370,7 +370,7 @@ SELECT array[1,2] <@ '{1,2,3}' as "is subset"; 域类型上的自定义操作符 -用户有时会尝试声明只适用于某个域类型的操作符。这是可行的,但远没有看上去那样有用,因为操作符解析规则被设计成优先选择作用于域基类型的操作符。考虑下面的例子: +用户有时会尝试声明只适用于某个域类型的操作符。这是可行的,但远没有看上去那样有用,因为操作符解析规则被设计成优先选择作用于域基础类型的操作符。考虑下面的例子: CREATE DOMAIN mytext AS text CHECK(...); CREATE FUNCTION mytext_eq_text (mytext, text) RETURNS boolean AS ...; @@ -379,11 +379,11 @@ CREATE TABLE mytable (val mytext); SELECT * FROM mytable WHERE val = 'foo'; -这个查询不会使用自定义操作符。解析器首先会检查是否存在mytext = mytext操作符(),但并不存在;然后它会考虑该域的基类型text,并检查是否存在text = text操作符(),而这是存在的;于是它会把unknown类型的文字解析为text,并使用text = text操作符。要让自定义操作符被使用,唯一的方法是显式地对该文字做类型转换: +这个查询不会使用自定义操作符。解析器首先会检查是否存在mytext = mytext操作符(),但并不存在;然后它会考虑该域的基础类型text,并检查是否存在text = text操作符(),而这是存在的;于是它会把unknown类型的字面量解析为text,并使用text = text操作符。要让自定义操作符被使用,唯一的方法是显式地对该字面量做类型转换: SELECT * FROM mytable WHERE val = text 'foo'; -这样就会根据精确匹配规则立即找到mytext = text操作符。如果解析过程进入最佳匹配规则,它们会主动排斥作用于域类型的操作符。如果不是这样,这类操作符会导致过多的操作符歧义失败,因为类型转换规则总是把域视为可以转换到其基类型或从其基类型转换而来,因此域操作符会在所有与基类型上同名操作符相同的场景中都被视为可用。 +这样就会根据精确匹配规则立即找到mytext = text操作符。如果解析过程进入最佳匹配规则,它们会主动排斥作用于域类型的操作符。如果不是这样,这类操作符会导致过多的操作符歧义失败,因为类型转换规则总是把域视为可以转换到其基础类型或从其基础类型转换而来,因此域操作符会在所有与基础类型上同名操作符相同的场景中都被视为可用。 @@ -422,27 +422,27 @@ SELECT * FROM mytable WHERE val = text 'foo'; -如果函数声明了一个VARIADIC数组参数,而调用时没有使用VARIADIC关键字,则把该函数视为其数组参数按需要被其元素类型的一个或多个出现所替换,以匹配该调用。扩展之后,该函数的有效参数类型可能与某个非VARIADIC函数完全相同。在这种情况下,使用搜索路径中较早出现的函数;如果两个函数位于同一模式,则优先选择非VARIADIC函数。 +如果函数声明了一个VARIADIC数组参数,而调用时没有使用VARIADIC关键字,则把数组参数视为一个或多个其元素类型的参数,个数按匹配该调用的需要确定。扩展之后,该函数的有效参数类型可能与某个非VARIADIC函数完全相同。在这种情况下,使用搜索路径中较早出现的函数;如果两个函数位于同一模式,则优先选择非VARIADIC函数。 -通过限定名调用某个允许不可信用户创建对象的模式中找到的可变参数函数时,会带来安全隐患 +通过限定名调用某个允许不受信任的用户创建对象的模式中找到的可变参数函数时,会带来安全隐患 - 对于未带模式限定的名称,不会出现这种隐患,因为包含允许不可信用户创建对象的模式的搜索路径不是一种模式的安全使用方式。 + 对于未带模式限定的名称,不会出现这种隐患,因为包含允许不受信任的用户创建对象的模式的搜索路径不是一种模式的安全使用方式。 - 。恶意用户可以借此劫持调用,并以你的身份执行任意 SQL 函数。改为使用带有VARIADIC关键字的调用可以绕过这一隐患。对于填充VARIADIC "any"参数的调用,往往没有包含VARIADIC关键字的等价写法。要安全地发出这类调用,该函数所在模式必须只允许可信用户创建对象。 + 。恶意用户可以借此劫持调用,并以你的身份执行任意 SQL 函数。改为使用带有VARIADIC关键字的调用可以绕过这一隐患。对于填充VARIADIC "any"参数的调用,往往没有包含VARIADIC关键字的等价写法。要安全地发出这类调用,该函数所在模式必须只允许受信任的用户创建对象。 -带有参数默认值的函数,被认为可以匹配任何省略了零个或多个可默认参数位置的调用。如果不止一个这样的函数能匹配某个调用,则使用搜索路径中最早出现的那一个。如果同一模式中存在两个或更多这样的函数,并且它们在未使用默认值的参数位置上的参数类型相同(如果它们具有不同的可默认参数集合,这种情况是可能的),系统就无法判断该偏好哪一个;如果找不到更好的匹配,就会报有歧义的函数调用错误。 +带有参数默认值的函数,被认为可以匹配任何省略了零个或多个可使用默认值的参数位置的调用。如果不止一个这样的函数能匹配某个调用,则使用搜索路径中最早出现的那一个。如果同一模式中存在两个或更多这样的函数,并且它们在未使用默认值的参数位置上的参数类型相同(如果它们具有不同的带有默认值的参数集合,这种情况是可能的),系统就无法判断该偏好哪一个;如果找不到更好的匹配,就会报有歧义的函数调用错误。 -通过限定名调用某个允许不可信用户创建对象的模式中的任意函数时,会带来可用性隐患。恶意用户可以用现有函数的名字创建一个新函数,复制该函数的参数,并附加带有默认值的新参数。这样就会阻止对原始函数的新调用。为避免这种隐患,应把函数放在只允许可信用户创建对象的模式中。 +通过限定名调用某个允许不受信任的用户创建对象的模式中的任意函数时,会带来可用性隐患。恶意用户可以用现有函数的名字创建一个新函数,复制该函数的参数,并附加带有默认值的新参数。这样就会阻止对原始函数的新调用。为避免这种隐患,应把函数放在只允许受信任的用户创建对象的模式中。 @@ -451,14 +451,14 @@ SELECT * FROM mytable WHERE val = text 'foo'; -检查是否存在一个恰好接受输入参数类型的函数。如果存在(在被考虑的函数集合中至多只有一个精确匹配),就使用它。若通过限定名调用某个允许不可信用户创建对象的模式中的函数,而又缺少精确匹配,就会带来安全隐患。在这种情况下,应通过对参数进行类型转换来强制获得精确匹配。(涉及unknown的情况在这一步永远找不到匹配。) +检查是否存在一个恰好接受输入参数类型的函数。如果存在(在被考虑的函数集合中至多只有一个精确匹配),就使用它。若通过限定名调用某个允许不受信任的用户创建对象的模式中的函数,而又缺少精确匹配,就会带来安全隐患。在这种情况下,应通过对参数进行类型转换来强制获得精确匹配。(涉及unknown的情况在这一步永远找不到匹配。) -如果没有找到精确匹配,就检查该函数调用是否看起来像一种特殊的类型转换请求。这种情况发生在:函数调用只有一个参数,且函数名与某个数据类型的(内部)名称相同。此外,函数参数必须是unknown类型文字,或者是一种能够进行二进制强制转换到该命名数据类型的类型,或者是一种可以通过应用其 I/O 函数转换为该命名数据类型的类型(也就是说,该转换要么转到某种标准字符串类型,要么从某种标准字符串类型转来)。满足这些条件时,该函数调用会被当作一种CAST形式。 +如果没有找到精确匹配,就检查该函数调用是否看起来像一种特殊的类型转换请求。这种情况发生在:函数调用只有一个参数,且函数名与某个数据类型的(内部)名称相同。此外,函数参数必须是unknown类型字面量,或者是一种可以二进制强制转换为该命名数据类型的类型,或者是一种可以通过应用其 I/O 函数转换为该命名数据类型的类型(也就是说,该转换要么转到某种标准字符串类型,要么从某种标准字符串类型转来)。满足这些条件时,该函数调用会被当作一种CAST形式。 之所以有这一步,是为了在不存在实际类型转换函数的情况下仍支持函数风格的类型转换写法。如果存在类型转换函数,按惯例它会以其输出类型命名,因此无需为此设置特殊情况。更多说明见。 @@ -475,13 +475,13 @@ SELECT * FROM mytable WHERE val = text 'foo'; -丢弃那些输入类型不匹配,且也无法通过隐式类型转换实现匹配的候选函数。为此,假定unknown文字可以转换为任何类型。如果只剩一个候选函数,就使用它;否则继续下一步。 +丢弃那些输入类型不匹配,且也无法通过隐式类型转换实现匹配的候选函数。为此,假定unknown字面量可以转换为任何类型。如果只剩一个候选函数,就使用它;否则继续下一步。 -如果任何输入参数是域类型,则在后续所有步骤中都把它当作该域的基类型。这样可以确保在解决函数歧义时,域的行为与其基类型一致。 +如果任何输入参数是域类型,则在后续所有步骤中都把它当作该域的基础类型。这样可以确保在解决函数歧义时,域的行为与其基础类型一致。 @@ -493,13 +493,13 @@ SELECT * FROM mytable WHERE val = text 'foo'; -遍历所有候选函数,保留那些在需要类型转换的最多位置上接受首选类型(属于输入数据类型的类型分类)的候选项。如果没有候选项接受首选类型,则保留全部候选项。如果只剩一个候选函数,就使用它;否则继续下一步。 +遍历所有候选函数,在需要类型转换的位置上,保留接受首选类型(属于输入数据类型的类型分类)的位置数最多的候选项。如果没有候选项接受首选类型,则保留全部候选项。如果只剩一个候选函数,就使用它;否则继续下一步。 -如果有任何输入参数是unknown,就检查剩余候选函数在这些参数位置上接受哪些类型分类。在每个位置上,如果有任何候选项接受string分类,就选择该分类。(这种偏向字符串的做法是合适的,因为unknown类型的文字看起来像字符串。)否则,如果所有剩余候选项都接受同一种类型分类,就选择该分类;否则失败,因为在缺少更多线索的情况下无法推断出正确选择。然后丢弃不接受所选类型分类的候选项。此外,如果有任何候选项接受该分类中的首选类型,就丢弃在该参数上接受非首选类型的候选项。如果没有候选项通过这些测试,则保留全部候选项。如果只剩一个候选函数,就使用它;否则继续下一步。 +如果有任何输入参数是unknown,就检查剩余候选函数在这些参数位置上接受哪些类型分类。在每个位置上,如果有任何候选项接受string分类,就选择该分类。(这种偏向字符串的做法是合适的,因为unknown类型的字面量看起来像字符串。)否则,如果所有剩余候选项都接受同一种类型分类,就选择该分类;否则失败,因为在缺少更多线索的情况下无法推断出正确选择。然后丢弃不接受所选类型分类的候选项。此外,如果有任何候选项接受该分类中的首选类型,就丢弃在该参数上接受非首选类型的候选项。如果没有候选项通过这些测试,则保留全部候选项。如果只剩一个候选函数,就使用它;否则继续下一步。 @@ -680,7 +680,7 @@ SELECT substr(CAST (1234 AS text), 3); -否则,尝试把表达式转换为目标类型。如果这两种类型之间在pg_cast目录中登记了赋值类型转换(见),就可以这样做。另一种情况是,如果表达式是unknown类型文字,则会把文字字符串的内容送入目标类型的输入转换例程。 +否则,尝试把表达式转换为目标类型。如果这两种类型之间在pg_cast目录中登记了赋值类型转换(见),就可以这样做。另一种情况是,如果表达式是unknown类型字面量,则会把字符串字面量的内容送入目标类型的输入转换例程。 @@ -713,7 +713,7 @@ SELECT v, octet_length(v) FROM vv; -这里实际发生的是,两个unknown类型文字默认都被解析为text,从而使||操作符被解析为text的连接操作。然后,操作符得到的text结果被转换为bpcharblank-padded char,即character数据类型的内部名称),以匹配目标列类型。(由于从textbpchar的转换是二进制可强制转换的,这一步不会插入任何真实的函数调用。)最后,系统目录中找到尺寸调整函数bpchar(bpchar, integer, boolean),并把它应用到操作符结果以及存储列长度上。这个特定于类型的函数会执行所需的长度检查并补齐填充空格。 +这里实际发生的是,两个unknown类型字面量默认都被解析为text,从而使||操作符被解析为text的连接操作。然后,操作符得到的text结果被转换为bpchar用空格填充的字符,blank-padded char,即character数据类型的内部名称),以匹配目标列类型。(由于从textbpchar的转换是二进制可强制转换的,这一步不会插入任何真实的函数调用。)最后,系统从系统目录中找到尺寸调整函数bpchar(bpchar, integer, boolean),并把它应用到操作符结果以及存储列长度上。这个特定于类型的函数会执行所需的长度检查并补齐填充空格。 @@ -770,10 +770,10 @@ SQL 的UNION结构必须让可能不同的类型彼此匹配 -如果任何输入是域类型,则在后续所有步骤中都把它当作该域的基类型。 +如果任何输入是域类型,则在后续所有步骤中都把它当作该域的基础类型。 - 这在某种程度上类似于操作符和函数对域输入的处理方式;只要用户确保所有输入都隐式或显式地正好属于该域类型,这种行为就能让域类型在UNION或类似结构中得以保留。否则,就会使用该域的基类型。 + 这在某种程度上类似于操作符和函数对域输入的处理方式;只要用户确保所有输入都隐式或显式地正好属于该域类型,这种行为就能让域类型在UNION或类似结构中得以保留。否则,就会使用该域的基础类型。 @@ -832,7 +832,7 @@ SELECT text 'a' AS "text" UNION SELECT 'b'; b (2 rows) -这里,unknown类型文字'b'会被解析为text类型。 +这里,unknown类型字面量'b'会被解析为text类型。 @@ -850,7 +850,7 @@ SELECT 1.2 AS "numeric" UNION SELECT 1; 1.2 (2 rows) -文字常量1.2的类型是numeric,而integer1可以隐式转换为numeric,因此使用该类型。 +字面量1.2的类型是numeric,而integer1可以隐式转换为numeric,因此使用该类型。 @@ -905,17 +905,17 @@ ERROR: UNION types text and integer cannot be matched -前面各节给出的规则会为 SQL 查询中的所有表达式分配非unknown的数据类型,唯一的例外是作为SELECT命令简单输出列出现的未指定类型文字常量。例如,在 +前面各节给出的规则会为 SQL 查询中的所有表达式分配非unknown的数据类型,唯一的例外是作为SELECT命令简单输出列出现的未指定类型字面量。例如,在 SELECT 'Hello World'; -中,没有任何信息能够表明这个字符串文字应该视为哪种类型。在这种情况下,PostgreSQL会退回到把该文字解析为text类型。 +中,没有任何信息能够表明这个字符串字面量应该视为哪种类型。在这种情况下,PostgreSQL会退回到把该字面量解析为text类型。 -当SELECTUNION(或INTERSECTEXCEPT)结构的一端,或者出现在INSERT ... SELECT中时,这条规则不适用,因为前面各节给出的规则具有更高优先级。在前一种情况下,未指定类型文字的类型可以从UNION的另一侧取得;在后一种情况下,则从目标列取得。 +当SELECTUNION(或INTERSECTEXCEPT)结构的一端,或者出现在INSERT ... SELECT中时,这条规则不适用,因为前面各节给出的规则具有更高优先级。在前一种情况下,未指定类型字面量的类型可以从UNION的另一侧取得;在后一种情况下,则从目标列取得。 @@ -925,7 +925,7 @@ SELECT 'Hello World'; - 在PostgreSQL 10 之前,这条规则并不存在,SELECT输出列表中的未指定类型文字会被保留为unknown类型。这会带来各种不良后果,因此后来做了修改。 + 在PostgreSQL 10 之前,这条规则并不存在,SELECT输出列表中的未指定类型字面量会被保留为unknown类型。这会带来各种不良后果,因此后来做了修改。 diff --git a/zh/18/user-manag.sgml b/zh/18/user-manag.sgml index 8aca4397..c3bc2a7b 100644 --- a/zh/18/user-manag.sgml +++ b/zh/18/user-manag.sgml @@ -312,12 +312,12 @@ ALTER TABLE bobs_table OWNER TO alice; - 一旦有价值的对象都已转移给新拥有者,被删除角色所拥有的其余对象即可使用DROP OWNED命令删除。同样,由于该命令不能访问其他数据库中的对象,因此必须在包含该角色所拥有对象的每个数据库中运行它。另外,DROP + 一旦有价值的对象都已转移给新拥有者,待删除角色所拥有的其余对象即可使用DROP OWNED命令删除。同样,由于该命令不能访问其他数据库中的对象,因此必须在包含该角色所拥有对象的每个数据库中运行它。另外,DROP OWNED不会删除整个数据库或表空间,因此如果该角色拥有任何尚未转移给新拥有者的数据库或表空间,就必须手工删除它们。 - DROP OWNED还会负责移除授予目标角色、但不属于它自身对象的任何权限。由于REASSIGN OWNED不会处理这类对象,所以通常需要同时运行REASSIGN OWNEDDROP OWNED(按这个顺序!),才能完整移除待删除角色的依赖关系。 + DROP OWNED还会负责移除目标角色在其他角色所拥有的对象上获授的所有权限。由于REASSIGN OWNED不会处理这类对象,所以通常需要同时运行REASSIGN OWNEDDROP OWNED(按这个顺序!),才能完整移除待删除角色的依赖关系。 @@ -356,7 +356,7 @@ GRANT pg_signal_backend TO admin_user; - 授予这些角色时应当谨慎,确保它们只在需要时使用,并理解这些角色会授予对敏感信息的访问。 + 授予这些角色时应当谨慎,确保它们只在需要时使用,并理解这些角色会授予对需要特权才能访问的信息的访问。 @@ -421,7 +421,7 @@ GRANT pg_signal_backend TO admin_user; pg_read_all_settings允许读取所有配置变量,即使是那些通常仅对超级用户可见的变量。 - pg_read_all_stats允许读取所有 pg_stat_* 视图,并使用各种与统计信息相关的扩展,即使是那些通常仅对超级用户可见的扩展。 + pg_read_all_stats允许读取所有 pg_stat_* 视图,并使用各种与统计信息相关的扩展,包括通常仅对超级用户可见的内容。 pg_stat_scan_tables允许执行可能在表上持有ACCESS SHARE锁并持续较长时间的监控函数(例如pgrowlocks(text),见扩展)。 @@ -448,7 +448,7 @@ GRANT pg_signal_backend TO admin_user; pg_execute_server_program - 这些角色旨在允许管理员创建受信任但非超级用户的角色,使其能够以数据库运行所用操作系统用户的身份访问文件并在数据库服务器上运行程序。它们在直接访问文件时会绕过所有数据库级权限检查,并且可被用来获得超级用户级别的访问能力。因此,向用户授予这些角色时必须极其谨慎。 + 这些角色旨在让管理员能够使受信任但非超级用户的角色能够以数据库运行所用操作系统用户的身份访问文件并在数据库服务器上运行程序。它们在直接访问文件时会绕过所有数据库级权限检查,并且可被用来获得超级用户级别的访问能力。因此,向用户授予这些角色时必须极其谨慎。 pg_read_server_files允许使用COPY和其他文件访问函数,从服务器上数据库可访问的任何位置读取文件。 @@ -497,7 +497,7 @@ GRANT pg_signal_backend TO admin_user; 函数安全性 - 函数、触发器和行级安全策略允许用户把代码插入后端服务器,而其他用户可能会无意中执行这些代码。因此,这些机制使用户能够相对容易地对其他用户实施特洛伊木马攻击。最强的保护方式是严格控制谁能定义对象。如果这不可行,则应编写只引用拥有者可信对象的查询,并从search_path中移除任何允许不受信任用户创建对象的模式。 + 函数、触发器和行级安全策略允许用户把代码插入后端服务器,而其他用户可能会无意中执行这些代码。因此,这些机制使用户能够相对容易地对其他用户实施特洛伊木马攻击。最强的保护方式是严格控制谁能定义对象。如果这不可行,则应编写只引用拥有者可信的对象的查询,并从search_path中移除任何允许不受信任用户创建对象的模式。 diff --git a/zh/18/vacuumlo.sgml b/zh/18/vacuumlo.sgml index 9e80b19f..cc2c04f5 100644 --- a/zh/18/vacuumlo.sgml +++ b/zh/18/vacuumlo.sgml @@ -8,7 +8,7 @@ vacuumlo 1 - Application + 应用程序 diff --git a/zh/18/wal.sgml b/zh/18/wal.sgml index f704e004..e509efaf 100644 --- a/zh/18/wal.sgml +++ b/zh/18/wal.sgml @@ -390,9 +390,9 @@ 检查点检查点 是事务序列中的一些点,在这些点上可以保证堆和索引数据文件已经用检查点之前写入 - 的全部信息进行了更新。执行检查点时,所有脏数据页都会刷写到磁盘,并向 WAL - 文件写入一条特殊的检查点记录。(更改记录此前已经刷入 WAL - 文件。)如果发生崩溃,崩溃恢复过程会查看最新的检查点记录,以确定应该从 WAL + 的全部信息进行了更新。执行检查点时,所有脏数据页都会刷盘,并向 WAL + 文件写入一条特殊的检查点记录。(更改记录此前已写入 WAL + 文件并刷盘。)如果发生崩溃,崩溃恢复过程会查看最新的检查点记录,以确定应该从 WAL 的哪个位置(称为重做记录)开始执行 REDO。该点之前对数据文件所做的任何更改 都保证已经在磁盘上。因此,检查点之后,位于包含重做记录的段之前的 WAL 段不再需要, 可以被回收或删除。(若正在执行 WAL 归档,则这些 WAL 段必 @@ -420,7 +420,7 @@ 减小 checkpoint_timeout 和/或 max_wal_size 会让检查点更频繁地发生。这样可以加快崩溃后 - 恢复,因为需要重做的工作更少。不过,这必须与更频繁刷写脏数据页所增加的成本 + 恢复,因为需要重做的工作更少。不过,这必须与更频繁地将脏数据页刷盘所增加的成本 权衡。如果设置了 (默认就是如此), 还要考虑另一个因素。为了保证数据页一致性,每个检查点之后对某个数据页的首次 修改,都会导致把整页内容写入日志。在这种情况下,更短的检查点间隔会增加输出到 @@ -447,7 +447,7 @@ I/O 速率,使检查点在给定比例的 checkpoint_timeout 秒数 经过时完成,或者在 max_wal_size 即将超出之前完成,以较早 者为准。使用默认值 0.9 时,可以预期 PostgreSQL - 会在下一次计划检查点开始前稍早完成每个检查点(大约在检查点间隔的 90% 时)。 + 会在下一次计划检查点开始前稍早完成每个检查点(耗时约为上一次检查点持续时间的 90%)。 这样能尽可能摊平 I/O,从而使检查点 I/O 负载在整个检查点间隔内保持稳定。这样 做的缺点是,延长检查点会影响恢复时间,因为需要保留更多 WAL 段以备恢复时 使用。关心恢复耗时的用户,可能希望减小 @@ -463,7 +463,7 @@ 在 Linux 和 POSIX 平台上, - 允许在检查点写出的操作系统页面达到可配置的字节数后,强制把它们刷到磁盘。 + 允许在检查点写出的操作系统页面达到可配置的字节数后,强制将它们刷盘。 否则,这些页面可能会停留在操作系统页缓存中,从而在检查点末尾发出 fsync 时引发停顿。这个设置通常有助于降低事务延迟,但也可能 对性能产生不利影响,尤其是在工作负载大于 @@ -501,7 +501,7 @@ 在归档恢复或备库模式下,服务器会周期性地执行 重启点重启点, - 其行为类似于正常运行时的检查点:服务器会强制把自身状态写盘,更新 + 其行为类似于正常运行时的检查点:服务器会强制将其所有状态刷盘,更新 pg_control 文件,以表明已经处理过的 WAL 数据无需再次 扫描,然后回收 pg_wal 目录中的旧 WAL 段文件。重启点的 执行频率不会高于主库上的检查点,因为重启点只能在检查点记录处执行。重启点既 @@ -544,7 +544,7 @@ 快。更糟的是,写 WAL 缓冲区还可能迫使系统创建新的 WAL 段, 这会花费更多时间。正常情况下,WAL 缓冲区应由 XLogFlush 请求负责写出并刷盘; - 该请求大多发生在事务提交时,以确保事务记录被刷入持久存储。在 WAL 输出量很高 + 该请求大多发生在事务提交时,以确保事务记录已刷盘至持久存储。在 WAL 输出量很高 的系统上,XLogFlush 请求可能不够频繁,无法避免 XLogInsertRecord 自己去执行写出。在这种系统上,应增加 WAL 缓冲区的数量,具体做法是修改参数 @@ -557,7 +557,7 @@ 参数 定义了组提交的领导者进程在 XLogFlush 内部获取锁之后会睡眠多少微秒,在此期间,组提 交的追随者会排队跟在领导者后面。这一延迟允许其他服务器进程把自己的提交记录添 - 加到 WAL 缓冲区中,以便它们都能由领导者最终执行的同步操作一并刷出。如果没有 + 加到 WAL 缓冲区中,以便它们都能由领导者最终执行的同步操作一并刷盘。如果没有 启用 ,或者当前处于活跃事务中的其他会话少于 个,就不会发生睡眠;这样可以避免在其他 会话不太可能很快提交时还去睡眠。请注意,在某些平台上,休眠请求的分辨率是 @@ -586,8 +586,7 @@ commit_delay 设为 0(默认值)时,仍然可能出现一种组 - 提交,但每个组只会包含那些恰好在前一次刷盘操作(若有)进行期间,到达“需要刷 - 出其提交记录”这一点的会话。客户端数量更高时,往往会出现一种 + 提交,但每个组只会包含那些恰好在前一次刷盘操作(若有)进行期间,到达“需要将其提交记录刷盘”这一点的会话。客户端数量更高时,往往会出现一种 gangway effect,以至于即使 commit_delay 为 0,组提交的效果也会变得很显著,因此显式设置 commit_delay 的帮助反而会变小。只有在以下两种条件同时 @@ -600,9 +599,9 @@ 参数 决定 PostgreSQL 将如何请求内核把 - WAL 更新强制刷到磁盘。就可靠性而言,所有选项应当都是相同 + WAL 更新强制刷盘。就可靠性而言,所有选项应当都是相同 的;例外是 fsync_writethrough,它有时能够在其他选项做不 - 到时强制刷新磁盘缓存。不过,具体哪个选项速度最快则高度依赖平台。可以使用 + 到时强制将磁盘缓存中的数据刷盘。不过,具体哪个选项速度最快则高度依赖平台。可以使用 程序测试不同选项的速度。请注意,如果 fsync 已被关闭,那么这个参数就没有意义。 diff --git a/zh/18/xaggr.sgml b/zh/18/xaggr.sgml index b46b119e..d7ef45aa 100644 --- a/zh/18/xaggr.sgml +++ b/zh/18/xaggr.sgml @@ -43,11 +43,11 @@ SELECT sum(a) FROM test_complex; - 如果没有非空输入值,上述sum定义将返回零(即初始状态值)。也许我们更希望在这种情况下返回空值 — SQL 标准要求sum这样做。实现这一点只需省略initcond短语,使初始状态值为空。通常这意味着sfunc需要检查输入的状态值是否为空。但对于sum以及maxmin这类其他简单聚合,只需把第一个非空输入值放入状态变量,然后从第二个非空输入值开始应用转移函数即可。如果初始状态值为空,并且转移函数被标记为strict(即不会对空输入调用),PostgreSQL会自动这样做。 + 如果没有非空输入值,上述sum定义将返回零(即初始状态值)。也许我们更希望在这种情况下返回空值 — SQL 标准要求sum这样做。实现这一点只需省略initcond短语,使初始状态值为空值。通常这意味着sfunc需要检查输入的状态值是否为空值。但对于sum以及maxmin这类其他简单聚合,只需把第一个非空输入值放入状态变量,然后从第二个非空输入值开始应用转移函数即可。如果初始状态值为空值,并且转移函数被标记为strict(即不会对空值输入调用),PostgreSQL会自动这样做。 - strict转移函数的另一项默认行为是,只要遇到空输入值,就会保留先前的状态值不变。因此,空值会被忽略。如果你需要对空输入采用其他行为,就不要把转移函数声明为 strict,而应在函数代码中自行检测空输入并完成所需处理。 + strict转移函数的另一项默认行为是,只要遇到空值输入,就会保留先前的状态值不变。因此,空值会被忽略。如果你需要对空值输入采用其他行为,就不要把转移函数声明为 strict,而应在函数代码中自行检测空值输入并完成所需处理。 @@ -72,7 +72,7 @@ CREATE AGGREGATE avg (float8) - SQL 中的聚合函数调用允许使用DISTINCTORDER BY选项,以控制哪些行会传递给聚合的转移函数,以及传递顺序。这些选项是在后台实现的,并不是聚合支持函数需要关心的事情。 + SQL 中的聚合函数调用允许使用DISTINCTORDER BY选项,以控制哪些行会传递给聚合的转移函数,以及传递顺序。这些选项由系统在内部实现,并不是聚合支持函数需要关心的事情。 @@ -292,7 +292,7 @@ SELECT percentile_disc(0.5) WITHIN GROUP (ORDER BY income) FROM households; - 与普通聚合不同,有序集聚合的输入行排序不是在幕后完成的,而是由聚合的支持函数负责。典型的实现方法是在聚合的状态值中保存一个tuplesort对象的引用,把输入行送入该对象,然后在最终函数中完成排序并读出数据。这样的设计使最终函数可以执行特殊操作,例如向待排序数据中注入额外的假想行。普通聚合通常可以使用由PL/pgSQL或其他 PL 语言编写的支持函数来实现,但有序集聚合通常必须用 C 编写,因为它们的状态值无法定义为任何 SQL 数据类型。(在上面的示例中,注意状态值被声明为internal类型,这很典型。)另外,由于最终函数执行了排序,之后就不可能再通过再次执行转移函数来继续加入输入行。这意味着最终函数不是READ_ONLY;在CREATE AGGREGATE中,必须将其声明为READ_WRITE,或者如果额外的最终函数调用能够利用已经排好序的状态,则声明为SHAREABLE。 + 与普通聚合不同,有序集聚合的输入行排序不是由系统在内部完成的,而是由聚合的支持函数负责。典型的实现方法是在聚合的状态值中保存一个tuplesort对象的引用,把输入行送入该对象,然后在最终函数中完成排序并读出数据。这样的设计使最终函数可以执行特殊操作,例如向待排序数据中注入额外的假想行。普通聚合通常可以使用由PL/pgSQL或其他 PL 语言编写的支持函数来实现,但有序集聚合通常必须用 C 编写,因为它们的状态值无法定义为任何 SQL 数据类型。(在上面的示例中,注意状态值被声明为internal类型,这很典型。)另外,由于最终函数执行了排序,之后就不可能再通过再次执行转移函数来继续加入输入行。这意味着最终函数不是READ_ONLY;在CREATE AGGREGATE中,必须将其声明为READ_WRITE,或者如果额外的最终函数调用能够利用已经排好序的状态,则声明为SHAREABLE @@ -366,7 +366,7 @@ if (AggCheckCallContext(fcinfo, NULL)) - AggCheckCallContext的第二个参数可用于取得保存聚合状态值的内存上下文。这对于希望把扩展对象(见)用作状态值的转移函数很有用。第一次调用时,转移函数应返回一个扩展对象,其内存上下文是聚合状态上下文的子上下文;之后的调用则持续返回同一个扩展对象。示例见array_append()。(array_append()并不是任何内置聚合的转移函数,但它的写法保证了在用作自定义聚合的转移函数时也能高效工作。) + AggCheckCallContext的第二个参数可用于取得保存聚合状态值的内存上下文。这对于希望把展开对象(见)用作状态值的转移函数很有用。第一次调用时,转移函数应返回一个展开对象,其内存上下文是聚合状态上下文的子上下文;之后的调用则持续返回同一个展开对象。示例见array_append()。(array_append()并不是任何内置聚合的转移函数,但它的写法保证了在用作自定义聚合的转移函数时也能高效工作。) diff --git a/zh/18/xfunc.sgml b/zh/18/xfunc.sgml index f197856f..f6c24bfd 100644 --- a/zh/18/xfunc.sgml +++ b/zh/18/xfunc.sgml @@ -4,8 +4,8 @@ 用户定义的函数 - function - user-defined + 函数 + 用户定义的 @@ -36,15 +36,15 @@ - 每一类函数可以采用基本类型、复合类型或者它们的组合作为参数。此外,每一类函数可以返回一个基本类型或一个复合类型。函数也能被定义成返回基本类型或复合类型值的集合。 + 每一类函数可以采用基础类型、复合类型或者它们的组合作为参数。此外,每一类函数可以返回一个基础类型或一个复合类型。函数也能被定义成返回基础类型或复合类型值的集合。 - 很多类函数可以接受或者返回特定的伪类型(例如,多态类型),但是可用的功能会变化。详情可以参考每一种函数的描述。 + 很多类函数可以接受或者返回特定的伪类型(例如,多态类型),但是可用的功能因函数类别而异。详情可以参考每一种函数的描述。 - 定义SQL函数最容易,因此我们将从讨论SQL函数开始。大部分SQL函数的概念也能用到其他类型的函数上。 + 定义SQL函数最容易,因此我们将从讨论它们开始。大部分SQL函数的概念也能用到其他类型的函数上。 @@ -57,8 +57,8 @@ 用户定义的过程 - procedure - user-defined + 过程 + 用户定义的 @@ -101,7 +101,7 @@ - 函数和过程一起构成了例程routine。 + 函数和过程统称为例程例程。 有ALTER ROUTINEDROP ROUTINE这样的命令可以操作函数和过程而不需要知道它们是哪一种。 不过,要注意没有CREATE ROUTINE命令。 @@ -113,7 +113,7 @@ 函数 用户定义的 - in SQL + 在 SQL 中 @@ -139,7 +139,7 @@ DELETEMERGE),以及其他 SQL 命令。(在 SQL 函数中不能使用事务控制命令,例如 COMMITSAVEPOINT,也不能使用某些 - 实用命令,例如 VACUUM。)不过,最后一条命令必须是 + 工具命令,例如 VACUUM。)不过,最后一条命令必须是 SELECT,或者带有 RETURNING 子句,并返回与函数声明返回类型相符的结果。或者,如果你想定义一个执行动作 但没有有用返回值的 SQL 函数,也可以把它定义为返回 void。 @@ -171,7 +171,7 @@ CREATE PROCEDURE clean_emp() AS ' CALL clean_emp(); - 在像这样的简单情况中,函数与过程返回void的差异主要是风格上面的。 + 在像这样的简单情况中,返回void的函数与过程之间的差异主要是风格上面的。 不过,过程还提供了函数所没有的额外能力,例如事务控制。 此外,过程是 SQL 标准的一部分,而返回void则是 PostgreSQL 扩展。 @@ -226,10 +226,10 @@ INSERT INTO $1 VALUES (42); - 基本类型上的<acronym>SQL</acronym>函数 + 基础类型上的<acronym>SQL</acronym>函数 - 最简单的 SQL 函数没有参数,只是返回一个基本类型,例如 + 最简单的 SQL 函数没有参数,只是返回一个基础类型,例如 integer @@ -255,7 +255,7 @@ SELECT one(); - 定义接受基本类型参数的 SQL 函数也几乎同样容易: + 定义接受基础类型参数的 SQL 函数也几乎同样容易: CREATE FUNCTION add_em(x integer, y integer) RETURNS integer AS $$ @@ -393,17 +393,17 @@ SELECT name, double_salary(emp.*) AS dream 注意这里用 $1.salary 语法来选取参数行值中的一个字段。 还要注意,调用时的 SELECT 命令使用 - table_name.* 将表的当前整行取作一个组合值。该表行也可以仅用表名来引用: + table_name.* 将表的当前整行取作一个复合值。该表行也可以仅用表名来引用: SELECT name, double_salary(emp) AS dream FROM emp WHERE emp.cubicle ~= point '(2,1)'; - 但这种用法已被废弃,因为它很容易让人混淆(关于表行组合值这两种记法的更多细节,见)。 + 但这种用法已被弃用,因为它很容易让人混淆(关于表行复合值这两种记法的更多细节,见)。 - 有时候即时构造一个组合参数会很方便。这可以用ROW构造器完成。 + 有时候即时构造一个复合参数值会很方便。这可以用ROW构造器完成。 例如,我们可以调整被传递给函数的数据: SELECT name, double_salary(ROW(name, salary*1.1, age, cubicle)) AS dream @@ -432,7 +432,7 @@ $$ LANGUAGE SQL; - 查询中的选择列表顺序必须与列在复合类型中出现的顺序完全相同。(正如我们上面所做的那样,命名列与系统无关。) + 查询中的选择列表顺序必须与列在复合类型中出现的顺序完全相同。(系统不考虑像上面这样指定的列名。) @@ -444,7 +444,7 @@ ERROR: return type mismatch in function declared to return emp DETAIL: Final statement returns text instead of point at column 4. - 与基本类型的情况一样,系统不会自动插入显式转换,只会插入隐式或赋值转换。 + 与基础类型的情况一样,系统不会自动插入显式转换,只会插入隐式或赋值转换。 @@ -461,7 +461,7 @@ $$ LANGUAGE SQL; 这里我们写了一个只返回单列、且该列具有正确复合类型的 SELECT。 在这种场景下,这样写并不见得更好,但在某些情况下会很方便 - — 例如,需要通过调用另一个返回目标组合值的函数来计算结果时。 + — 例如,需要通过调用另一个返回目标复合值的函数来计算结果时。 还有一种情况是,如果我们要编写的函数返回的是基于复合类型的域,而不是普通复合类型, 那么就必须写成返回单列的形式,因为没有办法让整行结果发生所需的强制转换。 @@ -526,7 +526,7 @@ SELECT name(new_emp()); - 另一种使用函数返回复合类型的方法是将结果传递给另一个接受正确行类型作为输入的函数: + 另一种使用函数返回复合类型的方法是将结果传递给另一个接受正确行类型作为输入的函数: CREATE FUNCTION getname(emp) RETURNS text AS $$ @@ -614,7 +614,7 @@ DROP FUNCTION sum_n_product (int, int); <acronym>SQL</acronym>有输出参数的过程 - procedures + 过程 输出参数 @@ -636,7 +636,7 @@ $$ LANGUAGE SQL; CALL tp1(17, 100.0, NULL); 如果你写的是其他内容,它必须是一个能够像输入参数那样被隐式强制转换成该参数声明类型的表达式。 - 注意,无论如何这样的表达式不会被评估。 + 不过要注意,这样的表达式不会被求值。 @@ -648,12 +648,12 @@ CALL tp1(17, 100.0, NULL); 带有可变数量参数的<acronym>SQL</acronym>函数 - function - variadic + 函数 + 可变参数 - variadic function + 可变参数函数 @@ -684,27 +684,27 @@ SELECT mleast(ARRAY[10, -1, 5, 4.4]); -- doesn't work - 有时候,能够把一个已经构造好的数组传给 variadic 函数会很有用,尤其是当一个 variadic 函数想把它的数组参数再传给另一个函数时。此外,在允许不受信任用户创建对象的模式中调用 variadic 函数时,这是唯一安全的方式,见。你可以在调用中指定VARIADIC来做到这一点: + 有时候,能够把一个已经构造好的数组传给可变参数函数会很有用,尤其是当一个可变参数函数想把它的数组参数再传给另一个函数时。此外,在允许不受信任用户创建对象的模式中调用可变参数函数时,这是唯一安全的方式,见。你可以在调用中指定VARIADIC来做到这一点: SELECT mleast(VARIADIC ARRAY[10, -1, 5, 4.4]); - 这样会阻止函数的 variadic 参数按其元素类型展开,从而让数组实参能够按常规方式匹配。VARIADIC 只能附加在函数调用的最后一个实参上。 + 这样会阻止函数的可变参数按其元素类型展开,从而让数组实参能够按常规方式匹配。VARIADIC 只能附加在函数调用的最后一个实参上。 - 在调用中指定VARIADIC也是向 variadic 函数传递空数组的唯一方式,例如: + 在调用中指定VARIADIC也是向可变参数函数传递空数组的唯一方式,例如: SELECT mleast(VARIADIC ARRAY[]::numeric[]); - 仅仅写成SELECT mleast()是行不通的,因为 variadic 参数必须匹配至少一个实参。(如果你希望允许这种调用,可以再定义一个同名且不带参数的函数mleast。) + 仅仅写成SELECT mleast()是行不通的,因为可变参数必须匹配至少一个实参。(如果你希望允许这种调用,可以再定义一个同名且不带参数的函数mleast。) - 从 variadic 参数派生出的数组元素参数会被视为没有自己的名字。这意味着除非你指定了 VARIADIC,否则不能使用命名参数来调用 variadic 函数()。例如,下面的调用是可行的: + 从可变参数派生出的数组元素参数会被视为没有自己的名字。这意味着除非你指定了 VARIADIC,否则不能使用命名参数来调用可变参数函数()。例如,下面的调用是可行的: SELECT mleast(VARIADIC arr => ARRAY[10, -1, 5, 4.4]); @@ -723,7 +723,7 @@ SELECT mleast(arr => ARRAY[10, -1, 5, 4.4]); 带有参数默认值的<acronym>SQL</acronym>函数 - function + 函数 参数的默认值 @@ -732,7 +732,7 @@ SELECT mleast(arr => ARRAY[10, -1, 5, 4.4]); 没有给出足够多的实参,就会插入默认值来弥补缺失的实参。由于参数只 能从实参列表的尾部开始被省略,在一个有默认值的参数之后的所有参数 都不得不也具有默认值(尽管使用命名参数记法可以允许放松这种限制, - 这种限制仍然会被强制以便位置参数记法能工作)。不管你是否使用它,这种能力都要求在某些用户不信任其他用户的数据中调用函数时做一些预防措施,见。 + 这种限制仍然会被强制以便位置参数记法能工作)。不管你是否使用它,这种能力都要求在某些用户不信任其他用户的数据库中调用函数时做一些预防措施,见 @@ -775,13 +775,13 @@ ERROR: function foo() does not exist 所有的 SQL 函数都可以被用在查询的FROM子句中,但是 - 对于返回复合类型的函数特别有用。如果函数被定义为返回一种基本类型, + 对于返回复合类型的函数特别有用。如果函数被定义为返回一种基础类型, 该表函数会产生一个单列表。如果该函数被定义为返回一种复合类型,该 表函数会为该复合类型的每一个属性产生一列。 - 以下是一个示例: + 以下是一个示例: CREATE TABLE foo (fooid int, foosubid int, fooname text); @@ -814,8 +814,8 @@ SELECT *, upper(fooname) FROM getfoo(1) AS t1; 返回集合的<acronym>SQL</acronym>函数 - function - with SETOF + 函数 + 使用 SETOF @@ -948,7 +948,7 @@ SELECT x, generate_series(1,5) AS g FROM tab; SELECT x, g FROM tab, LATERAL generate_series(1,5) AS g; - 这会是完全一样的,除了在这个特别的示例中,规划器会选择把g放在嵌套循环连接的外侧,因为gtab没有实际的横向依赖。那会导致一种不同的输出行顺序。选择列表中的集合返回函数总是会被计算,就好像它们在FROM子句剩余部分的嵌套循环连接的内侧一样,因此在考虑来自FROM子句的下一行之前,这些函数会运行到完成。 + 这会是完全一样的,除了在这个特别的示例中,规划器可以选择把g放在嵌套循环连接的外侧,因为gtab没有实际的横向依赖。那会导致一种不同的输出行顺序。选择列表中的集合返回函数总是会被计算,就好像它们在FROM子句剩余部分的嵌套循环连接的内侧一样,因此在考虑来自FROM子句的下一行之前,这些函数会运行到完成。 @@ -968,7 +968,7 @@ SELECT srf1(srf2(x), srf3(y)), srf4(srf5(z)) FROM tab; SELECT x, CASE WHEN x > 0 THEN generate_series(1, 5) ELSE 0 END FROM tab; - 看起来这个语句应该产生满足x > 0的输入行的五次重复,以及不满足的行的一次重复。但实际上,由于在CASE表达时被计算前,generate_series(1, 5)会被运行在一个隐式的LATERAL FROM项中,它会为每个输入行产生五次重复。为了减少混乱,这类情况会产生一个解析时错误。 + 看起来这个语句应该产生满足x > 0的输入行的五次重复,以及不满足的行的一次重复。但实际上,由于在CASE表达式被计算前,generate_series(1, 5)会被运行在一个隐式的LATERAL FROM项中,它会为每个输入行产生五次重复。为了减少混乱,这类情况会产生一个解析时错误。 @@ -984,11 +984,11 @@ SELECT x, CASE WHEN x > 0 THEN generate_series(1, 5) ELSE 0 END FROM tab; 在 PostgreSQL 10 之前,除非多个集合返回函数始终产生相同数量的行,否则把它们放在同一个选择列表中的行为并不合理。 否则,得到的输出行数会是这些集合返回函数各自产生行数的最小公倍数。 此外,嵌套的集合返回函数也不像上文所描述的那样工作;相反,一个集合返回函数至多只能有一个集合返回参数, - 并且每一层嵌套都会独立运行。再加上过去还允许条件执行(即在 CASE 等结构内部使用集合返回函数), + 并且每一组嵌套的集合返回函数都会独立运行。再加上过去还允许条件执行(即在 CASE 等结构内部使用集合返回函数), 事情就更加复杂了。 如果你要编写需要在旧版 PostgreSQL 上运行的查询,建议使用 LATERAL 语法, 因为这样在不同版本之间能够得到一致的结果。 - 如果你的查询依赖于集合返回函数的条件执行,可以把条件判断移动到自定义集合返回函数内部来修复。例如, + 如果你的查询依赖于集合返回函数的条件执行,或许可以把条件判断移动到自定义集合返回函数内部来修复。例如, SELECT x, CASE WHEN y > 0 THEN generate_series(1, z) ELSE 5 END FROM tab; @@ -1006,7 +1006,7 @@ END$$ LANGUAGE plpgsql; SELECT x, case_generate_series(y > 0, 1, z, 5) FROM tab; - 这种写法在所有版本的 PostgreSQL 中都能正常工作。 + 这种写法在所有版本的 PostgreSQL 中的行为都相同。 @@ -1015,7 +1015,7 @@ SELECT x, case_generate_series(y > 0, 1, z, 5) FROM tab; 返回<literal>TABLE</literal>的<acronym>SQL</acronym>函数 - function + 函数 RETURNS TABLE @@ -1064,10 +1064,9 @@ SELECT make_array(1, 2) AS intarray, make_array('a'::text, 'b') AS textarray; 注意类型转换'a'::text的使用是为了指定该参数的类型 - 是text。如果该参数只是一个字符串这就是必须的,因为 + 是text。如果该参数只是一个字符串字面量,这就是必须的,因为 否则它会被当作unknown类型,并且 - unknown的数组也不是一种合法的类型。如果没有改类型 - 类型转换,将得到这样的错误: + unknown的数组也不是一种合法的类型。如果没有该类型转换,将得到这样的错误: ERROR: could not determine polymorphic type because input has type unknown @@ -1138,7 +1137,7 @@ SELECT * FROM dup(22); - 多态也可以用于 variadic 函数。例如: + 多态也可以用于可变参数函数。例如: CREATE FUNCTION anyleast (VARIADIC anyarray) RETURNS anyelement AS $$ SELECT min($1[i]) FROM generate_subscripts($1, 1) g(i); @@ -1173,14 +1172,14 @@ SELECT concat_values('|', 1, 4, 2); 带有排序规则的<acronym>SQL</acronym>函数 - collation - in SQL functions + 排序规则 + 在 SQL 函数中 - 当一个 SQL 函数有一个或多个可设定排序规则的数据类型参数时,会按 - 中的说明,为每次函数调用确定一个排序规则。 - 如果能够成功确定(也就是说,参数之间不存在隐式排序规则冲突),那么所有可设定排序规则的参数都会被视为隐式带有该排序规则。 + 当一个 SQL 函数有一个或多个支持排序规则的数据类型参数时,会按 + 中的说明,根据分配给实参的排序规则,为每次函数调用确定一个排序规则。 + 如果能够成功确定(也就是说,参数之间不存在隐式排序规则冲突),那么所有支持排序规则的参数都会被视为隐式带有该排序规则。 这会影响函数中对排序规则敏感的操作的行为。例如,使用上文的 anyleast 函数时, SELECT anyleast('abc'::text, 'ABC'); @@ -1200,7 +1199,7 @@ CREATE FUNCTION anyleast (VARIADIC anyarray) RETURNS anyelement AS $$ SELECT min($1[i] COLLATE "en_US") FROM generate_subscripts($1, 1) g(i); $$ LANGUAGE SQL; - 但请注意,如果把它用于不可设定排序规则的数据类型,就会抛出错误。 + 但请注意,如果把它用于不支持排序规则的数据类型,就会抛出错误。 @@ -1209,7 +1208,7 @@ $$ LANGUAGE SQL; - 这种可设定排序规则参数的行为,可以看作是仅适用于文本数据类型的一种受限多态形式。 + 这种支持排序规则的参数的行为,可以看作是仅适用于文本数据类型的一种受限多态形式。 @@ -1218,13 +1217,13 @@ $$ LANGUAGE SQL; 函数重载 - overloading - functions + 重载 + 函数 可以用同样的 SQL 名称定义多于一个函数,只要它们的参数不同即可。 - 换句话说,函数名可以被重载。不管你是否使用它,这种能力都要求在某些用户不信任其他用户的数据中调用函数时做一些预防措施,见。当一个查询 + 换句话说,函数名可以被重载。不管你是否使用它,这种能力都要求在某些用户不信任其他用户的数据库中调用函数时采取安全预防措施,见。当一个查询 被执行时,服务器将从数据类型和所提供的参数个数来决定要调用哪个 函数。重载也可用来模拟具有可变参数个数(最大个数有限)的函数。 @@ -1251,10 +1250,10 @@ CREATE FUNCTION test(smallint, double precision) RETURNS ... - 另一类可能的冲突发生在 variadic 函数和非 variadic 函数之间。例如,可以同时创建 + 另一类可能的冲突发生在可变参数函数和非可变参数函数之间。例如,可以同时创建 foo(numeric)foo(VARIADIC numeric[])。 这时,对于只提供一个 numeric 参数的调用(例如 foo(10.1)),就不清楚该匹配哪个函数。 - 规则是:优先使用在搜索路径中出现较早的那个函数;如果两者位于同一模式中,则优先使用非 variadic 函数。 + 规则是:优先使用在搜索路径中出现较早的那个函数;如果两者位于同一模式中,则优先使用非可变参数函数。 @@ -1281,8 +1280,8 @@ CREATE FUNCTION test(int, int) RETURNS int 函数易变性分类 - volatility - functions + 易变性 + 函数 VOLATILE @@ -1304,7 +1303,7 @@ CREATE FUNCTION test(int, int) RETURNS int 一个VOLATILE函数可以做任何事情,包括修改数据库。在 使用相同的参数连续调用时,它能返回不同的结果。优化器不会对这类函 - 数的行为做任何假定。对于在每一行都需要 volatile 函数值的查询,函数都会被重新求值。 + 数的行为做任何假定。使用易变函数的查询会在需要该函数值的每一行上重新对它求值。 @@ -1352,8 +1351,7 @@ CREATE FUNCTION test(int, int) RETURNS int 在考虑先规划然后立即执行的简单交互式查询时,在STABLEIMMUTABLE分类间的区别相对较小:一个函数是在规划时只 执行一次还是在查询执行开始期间只执行一次没有太大关系。但是如果计划 - 被保存下来然后在后面被重用,区别就大了。如果在不允许过早把一个函数 - 变成规划期间的一个常数时把它标记为IMMUTABLE,会导致 + 被保存下来然后在后面被重用,区别就大了。如果把一个实际上并非不可变的函数标记为IMMUTABLE,就可能在规划期间过早将它折叠成常量,导致 在后续重用该计划时继续使用陈旧的值。在使用预备语句,或使用会缓存执行计划的函数语言(如 PL/pgSQL)时,这会带来严重问题。 @@ -1421,7 +1419,7 @@ CREATE FUNCTION test(int, int) RETURNS int 内部函数 - functioninternal + 函数内部 内部函数由 C 编写并且已经被静态链接到PostgreSQL @@ -1459,9 +1457,9 @@ CREATE FUNCTION square_root(double precision) RETURNS double precision C 语言函数 - function - user-defined - in C + 函数 + 用户定义的 + 在 C 中 @@ -1485,17 +1483,17 @@ CREATE FUNCTION square_root(double precision) RETURNS double precision - 在一个会话中第一次调用一个特定可载入对象文件中的用户定义函数时, - 动态载入器会把那个对象文件载入到内存以便该函数被调用。因此用户 + 在一个会话中第一次调用一个特定可载入目标文件中的用户定义函数时, + 动态载入器会把那个目标文件载入到内存以便该函数被调用。因此用户 定义的 C 函数的CREATE FUNCTION必须 - 为该函数指定两块信息:可载入对象文件的名称,以及要在该对象文件中 + 为该函数指定两块信息:可载入目标文件的名称,以及要在该目标文件中 调用的特定函数的 C 名称(链接符号)。如果没有显式指定 C 名称,则 它被假定为和 SQL 函数名相同。 下面的算法被用来基于CREATE FUNCTION - 命令中给定的名称来定位共享对象文件: + 命令中给定的名称来定位共享目标文件: @@ -1554,20 +1552,20 @@ CREATE FUNCTION square_root(double precision) RETURNS double precision PostgreSQL不会自动编译 C 函数。在 - 从CREATE FUNCTION命令中引用对象文件 + 从CREATE FUNCTION命令中引用目标文件 之前,它必须先被编译好。更多信息请见 - magic block + 魔数块 PG_MODULE_MAGIC - 为确保动态装载的对象文件不会被加载到不兼容的服务器中,PostgreSQL 会检查该文件是否包含内容正确的magic block。这样服务器就能检测出明显的不兼容情况,例如代码是针对另一个 PostgreSQL 主版本编译的。要加入 magic block,请在模块某一个(且只能一个)源文件中,在包含头文件 fmgr.h 之后写入: + 为确保动态装载的目标文件不会被加载到不兼容的服务器中,PostgreSQL 会检查该文件是否包含内容正确的魔数块。这样服务器就能检测出明显的不兼容情况,例如代码是针对另一个 PostgreSQL 主版本编译的。要加入魔数块,请在模块某一个(且只能一个)源文件中,在包含头文件 fmgr.h 之后写入: PG_MODULE_MAGIC; @@ -1592,9 +1590,9 @@ PG_MODULE_MAGIC_EXT( - 在第一次使用之后,动态载入对象文件会保留在内存中。在同一个会话中, + 在第一次使用之后,动态载入目标文件会保留在内存中。在同一个会话中, 后续对该文件中函数的调用只需付出一次很小的符号表查找开销。如果需要 - 强制重新载入一个对象文件(例如在重新编译之后),就需要开启一个新的会话。 + 强制重新载入一个目标文件(例如在重新编译之后),就需要开启一个新的会话。 @@ -1613,7 +1611,7 @@ PG_MODULE_MAGIC_EXT( - C 语言函数中的基本类型 + C 语言函数中的基础类型 数据类型 @@ -1622,16 +1620,16 @@ PG_MODULE_MAGIC_EXT( 要了解如何编写 C 语言函数,你需要了解 - PostgreSQL如何在内部表达基本数据类型 + PostgreSQL如何在内部表达基础类型 以及如何与函数传递它们。在内部, - PostgreSQL把基本类型视为一块内存数据块。 + PostgreSQL把基础类型视为一块内存数据块。 你为该类型定义的用户自定义函数,决定了 PostgreSQL 如何操作它。 也就是说,PostgreSQL 只负责把数据存到磁盘、再从磁盘取回, 而数据的输入、处理和输出则依赖你定义的这些函数。 - 基本类型可以有三种内部格式之一: + 基础类型可以有三种内部格式之一: @@ -1696,10 +1694,9 @@ typedef struct 最后,所有变长类型必须也以引用的方式传递。所有变长类型必须用一个 - 正好 4 字节的不透明长度域开始,该域会由SET_VARSIZE - 设置,绝不要直接设置该域!所有要被存储在该类型中的数据必须在内存 - 中接着该长度域的后面存储。长度域包含该结构体的总长度,也就是包括长 - 度域本身的尺寸。 + 正好 4 字节的不透明长度字段开始,该字段会由SET_VARSIZE + 设置,绝不要直接设置该字段!所有要被存储在该类型中的数据必须在内存 + 中接着该长度字段的后面存储。长度字段包含该结构体的总长度,也就是包括长度字段本身的尺寸。 @@ -1749,16 +1746,16 @@ memcpy(destination->data, buffer, 40); VARHDRSZsizeof(int32)一样, - 但是用宏VARHDRSZ来引用变长类型的载荷的 + 但是用宏VARHDRSZ来引用变长类型的额外开销的 尺寸被认为是比较好的风格。还有,必须 - 使用SET_VARSIZE宏来设置长度域,而不是用 + 使用SET_VARSIZE宏来设置长度字段,而不是用 简单的赋值来设置。 展示了 PostgreSQL 中许多内置 SQL 数据类型所对应的 C 类型。 - Defined In列给出了需要包含的头文件,以获取类型定义。 + 定义文件列给出了需要包含的头文件,以获取类型定义。 (实际的定义可能位于所列文件包含的其他文件中。建议用户坚持使用已定义的接口。) 请注意,在服务器代码的任何源文件中,都应该始终首先包含postgres.h, 因为它声明了很多你反正都会用到的内容,而且先包含其他头文件可能会带来可移植性问题。 @@ -1934,8 +1931,7 @@ memcpy(destination->data, buffer, 40);
- 现在我们已经复习了基本类型所有可能的结构,现在可以展示一些 - 真实函数的示例了。 + 了解了基础类型所有可能的结构后,就可以看一些实际函数示例。 @@ -1943,7 +1939,7 @@ memcpy(destination->data, buffer, 40); 版本 1 的调用约定 - 版本-1 的调用规范依赖于宏来降低传参数和结果的复杂度。版本-1 函数的 + 版本-1 的调用约定依赖于宏来降低传参数和结果的复杂度。版本-1 函数的 C 声明总是: Datum funcname(PG_FUNCTION_ARGS) @@ -1955,11 +1951,11 @@ PG_FUNCTION_INFO_V1(funcname); 必须出现在同一个源文件中(按惯例会正好写在该函数本身之前)。 这种宏调用不是internal语言函数所需要的,因为 PostgreSQL会假定所有内部函数都使用 - 版本-1 规范。不过,对于动态载入函数是必需的。 + 版本-1 调用约定。不过,对于动态载入函数是必需的。 - 在版本-1 函数中,每一个实参都使用对应于该参数数据类型的PG_GETARG_xxx()宏取得。(在非严格的函数中,需要使用PG_ARGISNULL()对参数是否为空提前做检查;见下文。)结果要用对应于返回类型的PG_RETURN_xxx()宏返回。PG_GETARG_xxx()的参数是要取得的函数参数的编号,从零开始计。PG_RETURN_xxx()的参数是实际要返回的值。 + 在版本-1 函数中,每一个实参都使用对应于该参数数据类型的PG_GETARG_xxx()宏取得。(在非严格的函数中,需要使用PG_ARGISNULL()对参数是否为空值提前做检查;见下文。)结果要用对应于返回类型的PG_RETURN_xxx()宏返回。PG_GETARG_xxx()的参数是要取得的函数参数的编号,从零开始计。PG_RETURN_xxx()的参数是实际要返回的值。 @@ -2142,11 +2138,11 @@ CREATE FUNCTION t_starts_with(text, text) RETURNS boolean - 注意我们已经把函数指定为strict,这意味着如果有任何输入值为空,系统应该自动假定得到空结果。通过这种做法,我们避免在函数代码中检查空值输入。如果不这样做,我们必须使用PG_ARGISNULL()明确地检查空值输入。 + 注意我们已经把函数指定为strict,这意味着如果有任何输入值为空值,系统应该自动假定结果为空值。通过这种做法,我们避免在函数代码中检查空值输入。如果不这样做,我们必须使用PG_ARGISNULL()明确地检查空值输入。 - 宏PG_ARGISNULL(n)允许一个函数测试是否每一个输入为空(当然,只需要在没有声明为strict的函数中这样做)。和PG_GETARG_xxx()宏一样,输入参数也是从零开始计数。注意应该在验证了一个参数不是空之后才执行PG_GETARG_xxx()。要返回一个空结果,应执行PG_RETURN_NULL(),它对严格的以及非严格的函数都有用。 + 宏PG_ARGISNULL(n)允许一个函数测试是否每一个输入为空值(当然,只需要在没有声明为strict的函数中这样做)。和PG_GETARG_xxx()宏一样,输入参数也是从零开始计数。注意应该在验证了一个参数不是空值之后才执行PG_GETARG_xxx()。要返回空值结果,应执行PG_RETURN_NULL(),它对严格的以及非严格的函数都有用。 @@ -2154,11 +2150,11 @@ CREATE FUNCTION t_starts_with(text, text) RETURNS boolean - 在版本-1接口中提供的其他选项是PG_GETARG_xxx()宏的两个变种。其中的第一种是PG_GETARG_xxx_COPY(),它确保返回的指定参数的拷贝可以被安全地写入(通常的宏有时会返回一个指向表中物理存储的值,它不能被写入。使用PG_GETARG_xxx_COPY()宏可以保证得到一个可写的结果)。第二种变种PG_GETARG_xxx_SLICE()宏有三个参数。第一个是函数参数的编号(如上文)。第二个和第三个是要被返回的段的偏移量和长度。偏移量从零开始计算,而负值的长度则表示要求返回该值的剩余部分。当大型值的存储类型为external时,这些宏提供了访问这些大型值的更有效的方法(列的存储类型可以使用ALTER TABLE tablename ALTER COLUMN colname SET STORAGE storagetype来指定。storagetypeplainexternalextended或者main)。 + 在版本-1接口中提供的其他选项是PG_GETARG_xxx()宏的两个变种。其中的第一种是PG_GETARG_xxx_COPY(),它确保返回的指定参数的拷贝可以被安全地写入(通常的宏有时会返回一个指向表中物理存储值的指针,不能写入该值。使用PG_GETARG_xxx_COPY()宏可以保证得到一个可写的结果)。第二种变种PG_GETARG_xxx_SLICE()宏有三个参数。第一个是函数参数的编号(如上文)。第二个和第三个是要被返回的段的偏移量和长度。偏移量从零开始计算,而负值的长度则表示要求返回该值的剩余部分。当大型值的存储类型为external时,这些宏提供了访问这些大型值的部分内容的更有效方法(列的存储类型可以使用ALTER TABLE tablename ALTER COLUMN colname SET STORAGE storagetype来指定。storagetypeplainexternalextended或者main)。 - 最后,版本-1 的函数调用规范可以返回集合结果()、实现触发器函数()和过程语言调用处理器()。更多细节 + 最后,版本-1 的函数调用约定可以返回集合结果()、实现触发器函数()和过程语言调用处理器()。更多细节 可见源代码发布中的src/backend/utils/fmgr/README @@ -2169,10 +2165,10 @@ CREATE FUNCTION t_starts_with(text, text) RETURNS boolean 在开始更高级的话题之前,我们应该讨论一下用于 PostgreSQL C 语言函数的编码规则。 - 虽然可以把不是 C 编写的函数载入到 - PostgreSQL中,这通常是很困难的, + 虽然有可能把不是 C 编写的函数载入到 + PostgreSQL中,但即使能够做到,通常也很困难, 因为其他语言(例如 C++、FORTRAN 或者 Pascal)通常不会遵循和 C - 相同的调用规范。也就是说,其他语言不会以同样的方式在函数之间传递 + 相同的调用约定。也就是说,其他语言不会以同样的方式在函数之间传递 参数以及返回值。由于这个原因,我们会假定你的 C 语言函数确实是用 C 编写的。 @@ -2184,7 +2180,7 @@ CREATE FUNCTION t_starts_with(text, text) RETURNS boolean 使用 pg_config - --includedir-serverpg_configwith user-defined C functions + --includedir-serverpg_config用于用户定义的 C 函数 查出 PostgreSQL 服务器头文件在你的系统上(或你的用户将要运行的系统上)安装于何处。 @@ -2197,7 +2193,7 @@ CREATE FUNCTION t_starts_with(text, text) RETURNS boolean - 记得按照中的说明,为你的共享库定义一个magic block。 + 记得按照中的说明,为你的共享库定义一个魔数块 @@ -2223,7 +2219,7 @@ CREATE FUNCTION t_starts_with(text, text) RETURNS boolean - 对象文件中定义的符号名不能彼此冲突,也不能与 + 目标文件中定义的符号名不能彼此冲突,也不能与 PostgreSQL 服务器可执行文件中定义的符号冲突。如果你收到这类错误消息,就必须重命名相关函数或变量。 @@ -2306,7 +2302,7 @@ CREATE FUNCTION t_starts_with(text, text) RETURNS boolean - 但请注意,服务器中有很多部分并不是作为公开可消费的 API 来设计和维护的(而且在大多数情况下,其真实边界也并不清晰)。如果这些部分出现紧急需求,对它们的修改自然会比对那些边界清楚且广泛使用的接口做修改时,更少考虑扩展代码的兼容性。 + 但请注意,服务器中有很多部分并不是作为可公开使用的 API 来设计和维护的(而且在大多数情况下,其真实边界也并不清晰)。如果这些部分出现紧急需求,对它们的修改自然会比对那些边界清楚且广泛使用的接口做修改时,更少考虑扩展代码的兼容性。 @@ -2322,10 +2318,10 @@ CREATE FUNCTION t_starts_with(text, text) RETURNS boolean 复合类型没有像 C 结构体那样的固定布局。复合类型的实例可能包含 - 空值域。此外,继承层次中的复合类型可能具有和同一继承层次中 - 其他成员不同的域。因此, + 空值字段。此外,继承层次中的复合类型可能具有和同一继承层次中 + 其他成员不同的字段。因此, PostgreSQL提供了函数接口 - 来访问 C 的复合类型的域。 + 以便从 C 访问复合类型的字段。 @@ -2337,7 +2333,7 @@ SELECT name, c_overpaid(emp, 1500) AS overpaid WHERE name = 'Bill' OR name = 'Sam'; - 如果使用版本-1的调用规范,我们可以定义 + 如果使用版本-1的调用约定,我们可以定义 c_overpaid为: 也有GetAttributeByNum函数,它可以用目标属性 - 的属性号而不是属性名来选择目标属性。 + 的列号而不是属性名来选择目标属性。 @@ -2396,14 +2392,14 @@ CREATE FUNCTION c_overpaid(emp, integer) RETURNS boolean 要从 C 语言函数中返回一行或一个复合类型值,可以使用一套特殊的 API, - 它通过一组宏和函数隐藏了构造组合数据类型时的大部分复杂性。要使用这套 API,源文件中必须包含: + 它通过一组宏和函数隐藏了构造复合数据类型时的大部分复杂性。要使用这套 API,源文件中必须包含: #include "funcapi.h" - 构造组合数据值(下文简称元组)有两种方式: + 构造复合数据值(下文简称元组)有两种方式: 一种是从 Datum 值数组构造,另一种是从 C 字符串数组构造,这些字符串会传给该元组各列数据类型的输入转换函数。 无论采用哪种方式,首先都需要获取或构造描述该元组结构的 TupleDesc。 处理 Datum 时,需要把 TupleDesc 传给 BlessTupleDesc,然后为每一行调用 heap_form_tuple。 @@ -2412,13 +2408,13 @@ CREATE FUNCTION c_overpaid(emp, integer) RETURNS boolean - 有一些辅助函数可以用来设置所需的 TupleDesc。在大多数返回组合值的函数中,推荐的做法是调用: + 有一些辅助函数可以用来设置所需的 TupleDesc。在大多数返回复合值的函数中,推荐的做法是调用: TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc) - 传入与调用函数本身相同的 fcinfo 结构体(这当然要求使用版本 1 调用约定)。 + 传入调用函数本身收到的同一个 fcinfo 结构体(这当然要求使用版本 1 调用约定)。 resultTypeId 可以指定为 NULL,也可以指定为一个本地变量的地址,用于接收函数结果类型的 OID。 resultTupleDesc 应当是一个本地 TupleDesc 变量的地址。 检查返回结果是否为 TYPEFUNC_COMPOSITE;如果是,resultTupleDesc 就会被填入所需的 TupleDesc。 @@ -2437,7 +2433,7 @@ TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, get_call_result_type有一个兄弟 get_expr_result_type,它被用来解析被表示为一棵表达式 - 树的函数调用的输出类型。在尝试确定来自函数外部的结果类型时可以用它。 + 树的函数调用的输出类型。在尝试从函数自身外部确定结果类型时可以用它。 也有一个get_func_result_type,当只有函数的 OID 可用时 可以用它。不过这些函数无法处理被声明为返回record的 函数,并且get_func_result_type无法解析多态类型,因此你 @@ -2446,22 +2442,22 @@ TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, - 更早、现在已被废弃的获取TupleDesc的函数有: + 更早、现在已被弃用的获取TupleDesc的函数有: TupleDesc RelationNameGetTupleDesc(const char *relname) - 它可以为一个提到的关系的行类型得到TupleDesc, + 它可以为一个指定名称的关系的行类型得到TupleDesc, 还有: TupleDesc TypeGetTupleDesc(Oid typeoid, List *colaliases) 可以基于一个类型 OID 得到TupleDesc。这可以被用来 - 为一种基础或者复合类型获得TupleDesc。不过,对于 + 为一种基本或者复合类型获得TupleDesc。不过,对于 返回record的函数它不起作用,并且它无法解析多态类型。 - 一旦有了一个TupleDesc,如果计划处理 Datum可以调用: + 一旦有了一个TupleDesc,如果计划处理 Datum,可以调用: TupleDesc BlessTupleDesc(TupleDesc tupdesc) @@ -2471,7 +2467,7 @@ AttInMetadata *TupleDescGetAttInMetadata(TupleDesc tupdesc) 如果正在编写一个返回集合的函数,你可以把这些函数的结果保存在 FuncCallContext结构体中 — 分别使用 - tuple_desc或者attinmeta域。 + tuple_desc或者attinmeta字段。 @@ -2491,8 +2487,7 @@ HeapTuple BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values) values是一个 C 字符串数组,每一个元素是返回行 的一个属性。每一个 C 字符串应该是该属性数据类型的输入函数所期望 的格式。为了对一个属性返回空值,values数组中对 - 应的指针应该被设置为NULL。对于你返回的每一行都将 - 再次调用这个函数。 + 应的指针应该被设置为NULL。对于你返回的每一行都需要再次调用这个函数。 @@ -2527,13 +2522,13 @@ HeapTupleGetDatum(HeapTuple tuple) 使用 ValuePerCall 模式时,重要的是要记住查询不能保证运行完成; 也就是说,由于诸如LIMIT之类的选项, - 执行程序可能会在获取所有行之前停止调用 set-returning 函数。 + 执行器可能会在获取所有行之前停止调用集合返回函数。 这意味着在最后一次调用中执行清理活动是不安全的,因为这可能永远不会发生。 对于需要访问外部资源(例如文件描述符)的函数,建议使用 Materialize 模式。 - 本节的其余部分记录了一组使用 ValuePerCall 模式的 SRF 常用(尽管不是必须使用)的帮助程序宏。 + 本节的其余部分记录了一组使用 ValuePerCall 模式的 SRF 常用(尽管不是必须使用)的辅助宏。 有关 Materialize 模式的其他详细信息可以在src/backend/utils/fmgr/README中找到。 此外,PostgreSQL源代码分发中的contrib 模块包含许多使用 ValuePerCall 和 Materialize 模式的 SRF 示例。 @@ -2542,7 +2537,7 @@ HeapTupleGetDatum(HeapTuple tuple) 要使用此处描述的 ValuePerCall 支持宏,请包含funcapi.h。 这些宏与结构体FuncCallContext一起使用,该结构体包含需要跨调用保存的状态。 - 在调用 SRF 中,fcinfo->flinfo->fn_extra用于在调用之间保存 + 在使用这些宏的 SRF 中,fcinfo->flinfo->fn_extra用于在调用之间保存 指向FuncCallContext的指针。 宏在第一次使用时自动填充该字段,并期望在后续使用中找到相同的指针。 @@ -2575,7 +2570,7 @@ typedef struct FuncCallContext /* * 可选:指向包含属性类型输入元数据的结构的指针 * - * attinmeta 被用在返回元组(即组合数据类型)时,在返回基本数据类型 + * attinmeta 被用在返回元组(即复合数据类型)时,在返回基础类型 * 时不会使用。只有想用BuildTupleFromCStrings()创建返回元组时才需要它。 */ AttInMetadata *attinmeta; @@ -2592,7 +2587,7 @@ typedef struct FuncCallContext /* * 可选:指向包含元组描述的结构的指针 * - * tuple_desc 被用在返回元组(即组合数据类型)时,并且只有在用 + * tuple_desc 被用在返回元组(即复合数据类型)时,并且只有在用 * heap_form_tuple() 而不是 BuildTupleFromCStrings() 构建元组时才需要它。 * 注意这里存储的 TupleDesc 指针通常已经被先运行过 BlessTupleDesc()。 */ @@ -2696,7 +2691,7 @@ my_set_returning_function(PG_FUNCTION_ARGS) else { /* 这里已经完成了项的返回,所以只报告事实。 */ - /* (不要将清理代码放在这里的。) */ + /* (不要将清理代码放在这里。) */ SRF_RETURN_DONE(funcctx); } } @@ -2776,7 +2771,7 @@ retcomposite(PG_FUNCTION_ARGS) /* 构建一个元组 */ tuple = BuildTupleFromCStrings(attinmeta, values); - /* 将元组转换为数据 */ + /* 将元组转换为 datum */ result = HeapTupleGetDatum(tuple); /* 清理(这实际上并不是必要的) */ @@ -2832,10 +2827,10 @@ CREATE OR REPLACE FUNCTION retcomposite(IN integer, IN integer, fcinfo->flinfo访问。参数argnum则是从零 开始计。get_call_result_type也可被用作 get_fn_expr_rettype的一种替代品。还有 - get_fn_expr_variadic,它可以被用来找出 variadic 参数 + get_fn_expr_variadic,它可以被用来找出可变参数 是否已经被合并到了一个数组中。这主要用于 VARIADIC "any"函数,因为对于接收普通数组类型的 - variadic 函数来说总是会发生这类合并。 + 可变参数函数来说总是会发生这类合并。 @@ -2903,7 +2898,7 @@ CREATE FUNCTION make_array(anyelement) RETURNS anyarray 它与 anyelement 类似,但不会要求不同的 "any" 参数必须是同一种类型,也不会帮助确定函数的结果类型。 C 语言函数还可以把最后一个参数声明为 VARIADIC "any"。 这可以匹配一个或多个任意类型的实参(不必是同一种类型)。 - 这些参数不会像普通 variadic 函数那样被收集成一个数组,而是会单独传给函数。 + 这些参数不会像普通可变参数函数那样被收集成一个数组,而是会单独传给函数。 使用这种特性时,必须结合 PG_NARGS() 宏以及前面介绍的方法来确定实参的个数和类型。 此外,这种函数的用户也可能希望在函数调用中使用 VARIADIC 关键字,以便让函数把数组元素当作独立参数处理。 如果希望支持这种行为,函数本身就必须在使用 get_fn_expr_variadic 检测到实参被标记为 VARIADIC 后自行实现它。 @@ -3272,9 +3267,9 @@ extern PgStat_Kind pgstat_register_kind(PgStat_Kind kind,
- 如果从 C++ 代码调用后端函数,确定 C++ 调用栈值包含传统 C 风格 + 如果从 C++ 代码调用后端函数,确定 C++ 调用栈只包含传统 C 风格 的数据结构(POD)。这是必要的,因为后端错误会 - 产生远距离的longjmp(),它无法正确的退回具有非 + 产生远距离的longjmp(),它无法正确地展开具有非 POD 对象的 C++ 调用栈。 @@ -3293,8 +3288,8 @@ extern PgStat_Kind pgstat_register_kind(PgStat_Kind kind, 函数优化信息 - optimization information - for functions + 优化信息 + 用于函数 @@ -3330,7 +3325,7 @@ supportfn(internal) returns internal - 对于返回 boolean 的目标函数,估计使用该函数的 WHERE 子句会筛选出多少行通常很有用。这可以通过实现 SupportRequestSelectivity 请求类型的支持函数来完成。 + 对于返回 boolean 的目标函数,估计使用该函数的 WHERE 子句筛选出的行所占的比例通常很有用。这可以通过实现 SupportRequestSelectivity 请求类型的支持函数来完成。 diff --git a/zh/18/xindex.sgml b/zh/18/xindex.sgml index 425c94d8..112b38c4 100644 --- a/zh/18/xindex.sgml +++ b/zh/18/xindex.sgml @@ -4,8 +4,8 @@ 索引扩展接口 - index - for user-defined data type + 索引 + 用于用户定义的数据类型 @@ -27,7 +27,7 @@ - 索引方法的例程并不直接知道它将处理哪些数据类型。相反,一个操作符类operator class标识了索引方法在处理特定数据类型时需要使用的那组操作。之所以称为操作符类,是因为它指定的一项内容就是可与索引一起使用的 WHERE 子句操作符集合(也就是能被转换成索引扫描条件的操作符)。操作符类还可以指定索引方法内部操作所需的一些支持函数,但这些函数并不直接对应任何可与索引一起使用的 WHERE 子句操作符。 + 索引方法的例程并不直接知道它将处理哪些数据类型。相反,一个操作符类操作符类标识了索引方法在处理特定数据类型时需要使用的那组操作。之所以称为操作符类,是因为它指定的一项内容就是可与索引一起使用的 WHERE 子句操作符集合(也就是能被转换成索引扫描条件的操作符)。操作符类还可以指定索引方法内部操作所需的一些支持函数,但这些函数并不直接对应任何可与索引一起使用的 WHERE 子句操作符。 @@ -355,7 +355,7 @@ - 返回可由 C 调用的 skip 支持函数地址(可选) + 返回可由 C 调用的跳跃支持函数地址(可选) 6 @@ -385,7 +385,7 @@ - 给定一个 64 位 salt,计算一个键的 64 位哈希值;如果 salt 为 0,结果的低 32 位必须与函数 1 计算出的值一致(可选) + 给定一个 64 位盐值,计算一个键的 64 位哈希值;如果盐值为 0,结果的低 32 位必须与函数 1 计算出的值一致(可选) 2 @@ -558,7 +558,7 @@ compare - 比较两个键,并返回一个小于零、等于零或大于零的整数,以表示第一个键是小于、等于还是大于第二个键 + 比较两个键,并返回一个小于零、等于零或大于零的整数,用以表示第一个键是小于、等于还是大于第二个键 1 @@ -732,7 +732,7 @@ CREATE OPERATOR < ( restrict = scalarltsel, join = scalarltjoinsel ); - 指定正确的交换子和求反器操作符很重要,同样也要指定合适的限制选择度函数和连接选择度函数,否则优化器将无法有效地利用索引。 + 指定正确的交换子和求反器操作符很重要,同样也要指定合适的限制选择率函数和连接选择率函数,否则优化器将无法有效地利用索引。 @@ -811,7 +811,7 @@ CREATE OPERATOR CLASS complex_abs_ops - 为了满足这些需求,PostgreSQL使用操作符族operator family这一概念。一个操作符族包含一个或多个操作符类,还可以包含属于整个族、但不属于族中任何单一类的可索引操作符及其相应的支持函数。我们称这样的操作符和函数在该族中是松散的,而不是绑定在某个特定类中。通常,每个操作符类只包含单一数据类型的操作符,而跨数据类型操作符则作为操作符族中的松散成员存在。 + 为了满足这些需求,PostgreSQL使用操作符族操作符族这一概念。一个操作符族包含一个或多个操作符类,还可以包含属于整个族、但不属于族中任何单一类的可索引操作符及其相应的支持函数。我们称这样的操作符和函数在该族中是松散的,而不是绑定在某个特定类中。通常,每个操作符类只包含单一数据类型的操作符,而跨数据类型操作符则作为操作符族中的松散成员存在。 @@ -931,7 +931,7 @@ ALTER OPERATOR FAMILY integer_ops USING btree ADD - 要构建一个多数据类型的哈希操作符族,必须为该族支持的每一种数据类型创建相互兼容的哈希支持函数。这里的兼容性是指:对任意两个被该族中的等值操作符视为相等的值,这些函数都保证返回相同的哈希码,即使这两个值属于不同类型也是如此。当这些类型具有不同的物理表示时,这通常难以实现,但在某些情况下可以做到。此外,将该操作符族中一种数据类型的值通过隐式或二进制强制转换转换成该族中另一种数据类型时,不应改变所计算出的哈希值。注意,每种数据类型只有一个支持函数,而不是每个等值操作符一个。建议让操作符族保持完整,也就是说,对每一种数据类型组合都提供一个等值操作符。每个操作符类只应包含其数据类型对应的非跨数据类型等值操作符和支持函数。 + 要构建一个多数据类型的哈希操作符族,必须为该族支持的每一种数据类型创建相互兼容的哈希支持函数。这里的兼容性是指:对任意两个被该族中的等值操作符视为相等的值,这些函数都保证返回相同的哈希码,即使这两个值属于不同类型也是如此。当这些类型具有不同的物理表示时,这通常难以实现,但在某些情况下可以做到。此外,将该操作符族中一种数据类型的值通过隐式或二进制强制转换转为该族中另一种数据类型时,不得改变所计算出的哈希值。注意,每种数据类型只有一个支持函数,而不是每个等值操作符一个。建议让操作符族保持完整,也就是说,对每一种数据类型组合都提供一个等值操作符。每个操作符类只应包含其数据类型对应的非跨数据类型等值操作符和支持函数。 @@ -944,7 +944,7 @@ ALTER OPERATOR FAMILY integer_ops USING btree ADD - 在 PostgreSQL 8.3 之前,并没有操作符族这一概念,因此任何打算与索引一起使用的跨数据类型操作符都必须直接绑定到该索引的操作符类中。虽然这种做法仍然有效,但已经废弃,因为它会使索引的依赖关系过于宽泛,而且当两种数据类型都在同一操作符族中拥有操作符时,规划器能更有效地处理跨数据类型比较。 + 在 PostgreSQL 8.3 之前,并没有操作符族这一概念,因此任何打算与索引一起使用的跨数据类型操作符都必须直接绑定到该索引的操作符类中。虽然这种做法仍然有效,但已被弃用,因为它会使索引的依赖关系过于宽泛,而且当两种数据类型都在同一操作符族中拥有操作符时,规划器能更有效地处理跨数据类型比较。 @@ -953,7 +953,7 @@ ALTER OPERATOR FAMILY integer_ops USING btree ADD 系统对操作符类的依赖 - ordering operator + 排序操作符 @@ -961,7 +961,7 @@ ALTER OPERATOR FAMILY integer_ops USING btree ADD - 特别地,ORDER BYDISTINCT等 SQL 特性要求对值的比较和排序。为了在用户定义的数据类型上实现这些特性,PostgreSQL会为数据类型查找默认 B-树操作符类。这个操作符类的equals成员定义了用于GROUP BYDISTINCT的值的等值概念,而该操作符类施加的排序顺序定义了默认的ORDER BY顺序。 + 特别地,ORDER BYDISTINCT等 SQL 特性要求对值的比较和排序。为了在用户定义的数据类型上实现这些特性,PostgreSQL会为数据类型查找默认 B-树操作符类。这个操作符类的相等成员定义了用于GROUP BYDISTINCT的值的等值概念,而该操作符类施加的排序顺序定义了默认的ORDER BY顺序。 @@ -987,11 +987,11 @@ SELECT * FROM mytable ORDER BY somecol USING ~<~; - 用户定义类型的数组比较也依赖于该类型默认 B-树操作符类所定义的语义。如果没有默认 B-树操作符类,但有默认的哈希操作符类,则支持数组相等比较,但不支持顺序比较。 + 用户定义类型的数组比较也依赖于该类型默认 B-树操作符类所定义的语义。如果没有默认 B-树操作符类,但有默认的哈希操作符类,则支持数组相等比较,但不支持排序比较。 - 另一种需要更多数据类型相关知识的 SQL 特性,是窗口函数中的 RANGE offset PRECEDING/FOLLOWING 框架选项(见)。对于下面这样的查询 + 另一种需要更多数据类型相关知识的 SQL 特性,是窗口函数中的 RANGE offset PRECEDING/FOLLOWING 帧选项(见)。对于下面这样的查询 SELECT sum(x) OVER (ORDER BY x RANGE BETWEEN 5 PRECEDING AND 10 FOLLOWING) FROM mytable; @@ -1026,7 +1026,7 @@ SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10; - 搜索操作符必须返回布尔结果,而排序操作符通常返回其他类型的结果,例如表示距离的浮点数或数值。这种类型通常不同于被索引的数据类型。为了避免对不同数据类型行为作硬编码假设,在定义排序操作符时,必须指定一个 B-树操作符族,用来说明结果数据类型的排序顺序。正如上一节所述,B-树操作符族定义了 PostgreSQL 的顺序概念,因此这是一种自然的表示方式。由于点的 <-> 操作符返回 float8,因此可以在创建操作符类时这样指定它: + 搜索操作符必须返回布尔结果,而排序操作符通常返回其他类型的结果,例如用于表示距离的 float 或 numeric。这种类型通常不同于被索引的数据类型。为了避免对不同数据类型行为作硬编码假设,在定义排序操作符时,必须指定一个 B-树操作符族,用来说明结果数据类型的排序顺序。正如上一节所述,B-树操作符族定义了 PostgreSQL 的顺序概念,因此这是一种自然的表示方式。由于点的 <-> 操作符返回 float8,因此可以在创建操作符类时这样指定它: (point, point) FOR ORDER BY float_ops ]]> @@ -1039,7 +1039,7 @@ OPERATOR 15 <-> (point, point) FOR ORDER BY float_ops 操作符类的特殊特性 - 还有两个操作符类的特殊特性我们尚未讨论,主要是因为它们对最常用的索引方法并不太有用。 + 还有两个操作符类的特殊特性我们尚未讨论,主要是因为它们对最常用的索引方法没有用处。 @@ -1060,7 +1060,7 @@ CREATE OPERATOR CLASS polygon_ops STORAGE box; - 目前,只有 GiST、SP-GiST、GIN 和 BRIN 索引方法支持与列数据类型不同的 STORAGE 类型。GiST 的 compressdecompress 支持例程在使用 STORAGE 时必须处理数据类型转换。SP-GiST 同样需要 compress 支持函数在存储类型不同时完成转换;如果某个 SP-GiST 操作符类还支持取回数据,那么反向转换必须由 consistent 函数处理。在 GIN 中,STORAGE 类型标识key值的类型,它通常不同于被索引列的类型 — 例如,整数数组列上的某个操作符类,其键值可能只是整数。GIN 的 extractValueextractQuery 支持例程负责从被索引值中提取键。BRIN 与 GIN 类似:STORAGE 类型标识被存储的摘要值类型,而操作符类的支持过程负责正确解释这些摘要值。 + 目前,只有 GiST、SP-GiST、GIN 和 BRIN 索引方法支持与列数据类型不同的 STORAGE 类型。GiST 的 compressdecompress 支持例程在使用 STORAGE 时必须处理数据类型转换。SP-GiST 同样需要 compress 支持函数在存储类型不同时完成转换;如果某个 SP-GiST 操作符类还支持取回数据,那么反向转换必须由 consistent 函数处理。在 GIN 中,STORAGE 类型标识值的类型,它通常不同于被索引列的类型 — 例如,整数数组列上的某个操作符类,其键值可能只是整数。GIN 的 extractValueextractQuery 支持例程负责从被索引值中提取键。BRIN 与 GIN 类似:STORAGE 类型标识被存储的摘要值类型,而操作符类的支持函数负责正确解释这些摘要值。 diff --git a/zh/18/xml2.sgml b/zh/18/xml2.sgml index 1324ffd4..f3f40587 100644 --- a/zh/18/xml2.sgml +++ b/zh/18/xml2.sgml @@ -90,7 +90,7 @@ 对文档执行该查询,并将结果包在 XML 标签中。如果结果包含多个值,输出将类似于: <toptag> -<itemtag>Value 1 which could be an XML fragment</itemtag> +<itemtag>Value 1(可以是 XML 片段)</itemtag> <itemtag>Value 2....</itemtag> </toptag> @@ -173,7 +173,7 @@ xpath_table(text key, text document, text relation, text xpaths, text criteria) key - key 字段的名称 — 这只是一个作为输出表第一列使用的字段,也就是说,它用于标识每个输出行来自哪条记录(关于多个值,见下文注释) + 字段的名称 — 这只是一个作为输出表第一列使用的字段,也就是说,它用于标识每个输出行来自哪条记录(关于多个值,见下文注释) @@ -238,7 +238,7 @@ xpath_table('article_id', 'date_entered > ''2003-01-01'' ') AS t(article_id integer, author text, page_count integer, title text); - AS 子句定义了输出表中各列的名称和类型。第一列是 key 字段,其余各列对应 XPath 查询。如果 XPath 查询多于结果列,多出的查询将被忽略。如果结果列多于 XPath 查询,多出的列将为 NULL。 + AS 子句定义了输出表中各列的名称和类型。第一列是 字段,其余各列对应 XPath 查询。如果 XPath 查询多于结果列,多出的查询将被忽略。如果结果列多于 XPath 查询,多出的列将为 NULL。 @@ -267,7 +267,7 @@ WHERE t.author_id = p.person_id; - 在某些情况下,用户会知道某个 XPath 查询只会返回单个结果(例如唯一文档标识符)— 如果它与返回多个结果的 XPath 查询一起使用,这个单值结果只会出现在结果的第一行。解决办法是把 key 字段作为与一个更简单的 XPath 查询结果进行连接的条件之一。例如: + 在某些情况下,用户会知道某个 XPath 查询只会返回单个结果(例如唯一文档标识符)— 如果它与返回多个结果的 XPath 查询一起使用,这个单值结果只会出现在结果的第一行。解决办法是把键字段作为与一个更简单的 XPath 查询结果进行连接的条件之一。例如: CREATE TABLE test ( diff --git a/zh/18/xoper.sgml b/zh/18/xoper.sgml index b9968985..3e471267 100644 --- a/zh/18/xoper.sgml +++ b/zh/18/xoper.sgml @@ -164,10 +164,10 @@ SELECT (a + b) AS c FROM test_complex; <literal>RESTRICT</literal> - 如果给出 RESTRICT 子句,它指定该操作符的限制选择度估 + 如果给出 RESTRICT 子句,它指定该操作符的限制选择率估 算函数。(注意,这里是函数名,而不是操作符名。) RESTRICT 子句只对返回 boolean 的二元操 - 作符有意义。限制选择度估算器的作用,是针对当前操作符和某个特定常量值, + 作符有意义。限制选择率估算器的作用,是针对当前操作符和某个特定常量值, 猜测一张表中有多少比例的行会满足如下形式的 WHERE 子句条件: @@ -179,9 +179,9 @@ column OP constant - 编写新的限制选择度估算函数远远超出了本章的范围,不过幸运的是,对于你自 + 编写新的限制选择率估算函数远远超出了本章的范围,不过幸运的是,对于你自 己的很多操作符,通常都可以直接使用系统提供的某个标准估算器。标准的限制 - 选择度估算器如下: + 选择率估算器如下: eqsel 用于 = neqsel 用于 <> @@ -193,7 +193,7 @@ column OP constant - 对于选择度非常高或非常低的操作符,即使它们实际上并不是真正的相等或不等 + 对于选择率非常高或非常低的操作符,即使它们实际上并不是真正的相等或不等 比较,你也常常可以勉强使用 eqselneqsel。例如,几何类型中的近似相等操作符就使用 eqsel,其依据是它们通常只会匹配表中很小一部分项。 @@ -212,7 +212,7 @@ column OP constant - 另一个有用的内置选择度估算函数是 matchingsel。只要 + 另一个有用的内置选择率估算函数是 matchingsel。只要 已为输入数据类型收集了标准的 MCV 和/或直方图统计信息,它几乎就适用于任 何二元操作符。它的默认估计值被设定为 eqsel 所用默认 估计值的两倍,因此最适合那些比相等比较稍微宽松一些的比较操作符。(或者 @@ -222,7 +222,7 @@ column OP constant src/backend/utils/adt/geo_selfuncs.c 中,还为几 - 何操作符提供了其他选择度估算函数:areasel、 + 何操作符提供了其他选择率估算函数:areaselpositionselcontsel。截至 目前,这些函数都还只是桩实现,但你也许仍会想使用它们(或者更好的是,改 进它们)。 @@ -233,9 +233,9 @@ column OP constant <literal>JOIN</literal> - 如果给出 JOIN 子句,它指定该操作符的连接选择度估算函 + 如果给出 JOIN 子句,它指定该操作符的连接选择率估算函 数。(注意,这里是函数名,而不是操作符名。)JOIN 子 - 句只对返回 boolean 的二元操作符有意义。连接选择度估算器的 + 句只对返回 boolean 的二元操作符有意义。连接选择率估算器的 作用,是针对当前操作符,猜测两张表中有多少比例的行对会满足如下形式的 WHERE 子句条件: @@ -246,7 +246,7 @@ table1.column1 OP table2.column2 - 与前面一样,本章不会尝试解释如何编写连接选择度估算函数,而只是建议你在 + 与前面一样,本章不会尝试解释如何编写连接选择率估算函数,而只是建议你在 适用时使用某个标准估算器: eqjoinsel 用于 = @@ -305,7 +305,7 @@ table1.column1 OP table2.column2 一个可参与哈希连接的操作符,必须拥有一个交换子(如果两侧操作数数据类型 - 相同,则可以是它自身;如果不同,则应是相关的相等操作符),并且该交换子 + 相同,则为它自身;如果不同,则应是相关的相等操作符),并且该交换子 也必须出现在同一个操作符族中。否则,在使用该操作符时可能会发生规划器错 误。另外,对于支持多种数据类型的哈希操作符族,最好(虽然并非严格必需) 为每一种数据类型组合都提供相等操作符;这样可以获得更好的优化效果。 @@ -342,7 +342,7 @@ table1.column1 OP table2.column2 - 归并连接的基本思想,是先把左表和右表分别排序,然后并行扫描它们。因此, + 归并连接的基本思想,是先把左表和右表分别排序,然后同步扫描它们。因此, 两种数据类型都必须能够被完全排序,而连接操作符必须只能在那对值位于排序 次序中同一位置时才成功。实际效果上,这意味着连接操作符 必须表现得像相等比较一样。不过,只要两种不同的数据类型在逻辑上兼容,也 @@ -362,7 +362,7 @@ table1.column1 OP table2.column2 一个可参与归并连接的操作符,必须拥有一个交换子(如果两侧操作数数据类型 - 相同,则可以是它自身;如果不同,则应是相关的相等操作符),并且该交换子 + 相同,则为它自身;如果不同,则应是相关的相等操作符),并且该交换子 也必须出现在同一个操作符族中。否则,在使用该操作符时可能会发生规划器错 误。另外,对于支持多种数据类型的 btree 操作符族,最 好(虽然并非严格必需)为每一种数据类型组合都提供相等操作符;这样可以获 diff --git a/zh/18/xplang.sgml b/zh/18/xplang.sgml index 9075d7b6..0590ea2d 100644 --- a/zh/18/xplang.sgml +++ b/zh/18/xplang.sgml @@ -183,7 +183,7 @@ CREATE TRUSTED LANGUAGE plperl 在默认的PostgreSQL安装中, PL/pgSQL语言的调用处理器会被构建并安装到 - library目录中;此外, + 目录中;此外, PL/pgSQL语言本身也安装在所有数据库中。如 果在构建时配置了Tcl支持,那么 PL/TclPL/TclU diff --git a/zh/18/xtypes.sgml b/zh/18/xtypes.sgml index 3d1b66d1..b66c4aa1 100644 --- a/zh/18/xtypes.sgml +++ b/zh/18/xtypes.sgml @@ -218,7 +218,7 @@ CREATE TYPE complex ( 如果数据类型的内部表示是可变长度的,则这种内部表示必须遵循可变长度数 据的标准布局:前四个字节必须是一个从不直接访问的char[4] 字段(惯例上命名为vl_len_)。必须使用 - SET_VARSIZE()宏在该字段中存储该值的总大小(包括 + SET_VARSIZE()宏在该字段中存储该 datum 的总大小(包括 长度字段本身),并使用VARSIZE()取回它。(这些宏 之所以存在,是因为长度字段可能会随平台不同而采用编码形式。) @@ -260,7 +260,7 @@ CREATE TYPE complex ( PG_DETOAST_DATUM_PACKED(通常通过定义 GETARG_DATATYPE_PP宏来隐藏),并使用 VARSIZE_ANY_EXHDRVARDATA_ANY - 宏访问一个可能采用打包形式的值。再次注意,即使数据类型定义指定了 + 宏访问一个可能采用打包形式的 datum。再次注意,即使数据类型定义指定了 对齐方式,这些宏返回的数据也不是对齐的。如果对齐很重要,就必须使用常 规的PG_DETOAST_DATUM接口。 @@ -271,8 +271,7 @@ CREATE TYPE complex ( 较旧的代码常把vl_len_声明为 int32字段,而不是char[4]字段。只要结构体定 义中还有其他至少按int32对齐的字段,这样做是可以的。但 - 在处理可能未对齐的值时使用这种结构体定义就很危险;编译器可能据此假定该 - 值实际上是对齐的,从而在对齐要求严格的体系结构上导致核心转储。 + 在处理可能未对齐的 datum 时使用这种结构体定义就很危险;编译器可能据此假定该 datum 实际上是对齐的,从而在对齐要求严格的体系结构上导致核心转储。 diff --git a/zh/19/amcheck.sgml b/zh/19/amcheck.sgml index e8872eac..d2ef0ed3 100644 --- a/zh/19/amcheck.sgml +++ b/zh/19/amcheck.sgml @@ -361,7 +361,7 @@ SET client_min_messages = DEBUG1; 这也包括因操作系统排序规则的比较规则发生变化而引起的问题。 - 像text这类可排序类型的数据值之间的比较必须是不可变的 + 像text这类支持排序规则的类型的 datum 之间的比较必须是不可变的 (正如用于 B-树索引扫描的所有比较都必须不可变一样), 这就意味着操作系统排序规则绝不能发生变化。 虽然这种情况比较少见,但操作系统排序规则的更新确实可能导致此类问题。 diff --git a/zh/19/backup-manifest.sgml b/zh/19/backup-manifest.sgml index 5d61e7ff..3eec4b46 100644 --- a/zh/19/backup-manifest.sgml +++ b/zh/19/backup-manifest.sgml @@ -4,7 +4,7 @@ 备份清单格式 - Backup Manifest + 备份清单 @@ -180,7 +180,7 @@ Start-LSN - 为了使用该备份,必须在指定时间线上从这个 LSN 开始回放。该 LSN 按 + 为了使用该备份,必须在指定时间线上从这个 LSN 开始重放。该 LSN 按 PostgreSQL 通常使用的格式存储;也就是说, 它是一个字符串,由两段十六进制字符串构成,每段长度在 1 到 8 之间,并 以斜杠分隔。 @@ -192,7 +192,7 @@ End-LSN - 使用该备份时,指定时间线上的回放可结束于此 LSN,而这也是允许的最早 + 使用该备份时,指定时间线上的重放可结束于此 LSN,而这也是允许的最早 LSN。其存储格式与 Start-LSN 相同。 diff --git a/zh/19/backup.sgml b/zh/19/backup.sgml index a0eae7fd..a110e972 100644 --- a/zh/19/backup.sgml +++ b/zh/19/backup.sgml @@ -3,7 +3,7 @@ 备份和恢复 - backup + 备份 与任何保存重要数据的系统一样,PostgreSQL数据库也应定期备份。虽然其过程基本简单,但清楚理解其底层技术和前提假设非常重要。 @@ -74,7 +74,7 @@ psql -X dbname < psql -X --set ON_ERROR_STOP=on dbname < dumpfile - 无论如何,你最终只会得到一个部分恢复的数据库。另一种做法是指定将整个转储作为单个事务恢复,这样恢复要么全部完成,要么全部回滚。可以通过把命令行选项传给psql来启用这种模式。使用这种模式时要注意,即便是一个很小的错误,也可能回滚一个已经运行了许多小时的恢复过程。不过,这仍可能比在部分恢复后手工清理一个复杂数据库更可取。 + 无论采用上述哪种方式,你最终只会得到一个部分恢复的数据库。另一种做法是指定将整个转储作为单个事务恢复,这样恢复要么全部完成,要么全部回滚。可以通过把命令行选项传给psql来启用这种模式。使用这种模式时要注意,即便是一个很小的错误,也可能回滚一个已经运行了许多小时的恢复过程。不过,这仍可能比在部分恢复后手工清理一个复杂数据库更可取。 @@ -194,7 +194,7 @@ pg_restore -d dbname - 对于非常大的数据库,你可能需要把split与前两种方法之一结合使用。 + 对于非常大的数据库,你可能需要把split与另外两种方法之一结合使用。 @@ -250,7 +250,7 @@ tar -cf backup.tar /usr/local/pgsql/data - 如果无法获得同时的快照,一种选择是将数据库服务器关闭足够长的时间,以建立所有冻结快照。另一种选择是执行持续归档基础备份(),因为这种备份不受备份期间文件系统变化的影响。这要求只在备份过程中启用持续归档;恢复则使用持续归档恢复()。 + 如果无法获得同时的快照,一种选择是将数据库服务器关闭足够长的时间,以建立所有冻结快照。另一种选择是执行持续归档基础备份(),因为这种备份不受备份期间文件系统变化的影响。这种方法只需在备份期间启用持续归档;恢复则使用持续归档恢复()。 @@ -266,11 +266,11 @@ tar -cf backup.tar /usr/local/pgsql/data 持续归档和时间点恢复(PITR) - continuous archiving + 持续归档 - point-in-time recovery + 时间点恢复 @@ -310,7 +310,7 @@ tar -cf backup.tar /usr/local/pgsql/data - 和普通文件系统备份技术一样,这种方法只能支持整个数据库集簇的恢复,而不支持其中某个子集的恢复。此外,它需要大量归档存储:基础备份可能很庞大,繁忙系统也会产生大量必须归档的 WAL 流量。尽管如此,在很多需要高可靠性的场景中,它仍是首选的备份技术。 + 和普通文件系统备份技术一样,这种方法只能支持整个数据库集簇的恢复,而不支持其中某个子集的恢复。此外,它需要大量归档存储:基础备份可能很庞大,繁忙系统也会产生许多兆字节的、必须归档的 WAL 流量。尽管如此,在很多需要高可靠性的场景中,它仍是首选的备份技术。 @@ -329,7 +329,7 @@ tar -cf backup.tar /usr/local/pgsql/data - 要启用 WAL 归档,请将配置参数设置为replica或更高,将设置为on,并在配置参数中指定要使用的 shell 命令,或者在配置参数中指定要使用的库。实际上,这些设置通常都会放在postgresql.conf文件中。 + 要启用 WAL 归档,请将配置参数设置为replica或更高,将设置为on,并在配置参数中指定要使用的 shell 命令,或者在配置参数中指定要使用的库。在实际使用中,这些设置总是放在postgresql.conf文件中。 @@ -345,20 +345,16 @@ test ! -f /mnt/server/archivedir/00000001000000A900000065 && cp pg_wal/0 对每个新的待归档文件都会生成一条类似的命令。 - - 归档命令会以运行PostgreSQL服务器的同一操作系统用户身份执行。由于这一系列被归档的 WAL 文件实际上包含了数据库中的几乎全部内容,因此你应确保归档数据不会被他人窥探;例如,把它归档到一个不向组或所有用户开放读权限的目录中。 - + 归档命令将以运行 PostgreSQL 服务器的同一用户身份执行。由于归档的一系列 WAL 文件实际上包含数据库中的全部内容,应确保归档数据不会被他人窥视;例如,将其归档到不允许所属组或其他用户读取的目录。 - - 重要的是,归档命令只有在成功时才返回零退出状态。收到零结果后,PostgreSQL会认为该文件已经成功归档,并会将其删除或回收。相反,非零状态会告诉PostgreSQL该文件尚未归档;系统会周期性重试,直到成功为止。 - + 归档命令必须当且仅当成功时才返回退出状态零。收到零状态后,PostgreSQL 会认为该文件已成功归档,并将其删除或回收。非零状态则告诉 PostgreSQL 该文件尚未归档;它会定期重试,直到成功。 另一种归档方式是把自定义归档模块用作archive_library。由于这类模块是用C编写的,创建自己的模块可能比编写 shell 命令需要更多工作。不过,归档模块可能比通过 shell 归档更高效,而且可以访问许多有用的服务器资源。有关归档模块的更多信息,见 - 当归档命令被信号终止(用于服务器关闭流程的SIGTERM除外),或者 shell 因退出状态大于 125 的错误(例如命令未找到)而失败,或者归档函数发出ERRORFATAL时,归档器进程会中止,并由 postmaster 重新启动。在这种情况下,失败不会记录到中。 + 当归档命令被信号终止(用于服务器关闭流程的SIGTERM除外),或者因 shell 报错(例如命令未找到)而以大于 125 的状态退出,或者归档函数发出ERRORFATAL时,归档器进程会中止,并由 postmaster 重新启动。在这种情况下,失败不会记录到中。 @@ -366,7 +362,7 @@ test ! -f /mnt/server/archivedir/00000001000000A900000065 && cp pg_wal/0 - 在少数情况下,PostgreSQL可能会尝试重新归档一个此前已经归档过的 WAL 文件。例如,如果系统在服务器把归档成功持久记录下来之前崩溃,服务器在重启后会再次尝试归档该文件(前提是归档仍然启用)。当归档命令或归档库遇到一个已存在的文件时,如果该文件与待归档 WAL 文件内容完全相同,且先前归档的文件已经完全持久化到存储,则前者应分别返回零状态或true。如果已存在文件的内容与正在归档的 WAL 文件不同,则归档命令或归档库必须分别返回非零状态或false。 + 在少数情况下,PostgreSQL可能会尝试重新归档一个此前已经归档过的 WAL 文件。例如,如果系统在服务器把归档成功持久记录下来之前崩溃,服务器在重启后会再次尝试归档该文件(前提是归档仍然启用)。当归档命令或归档库遇到一个已存在的文件时,如果该文件与待归档 WAL 文件内容完全相同,且先前归档的文件已经完全持久化到存储,则归档命令或归档库应分别返回零状态或true。如果已存在文件的内容与正在归档的 WAL 文件不同,则归档命令或归档库必须分别返回非零状态或false @@ -390,7 +386,7 @@ test ! -f /mnt/server/archivedir/00000001000000A900000065 && cp pg_wal/0 - 归档命令或归档函数只会在完整的 WAL 段上被调用。因此,如果服务器产生的 WAL 流量很小(或者存在低谷期),事务完成到其被安全写入归档存储之间可能会有很长延迟。为了限制未归档数据可能有多旧,你可以设置,强制服务器至少隔这么长时间切换到一个新的 WAL 段文件。注意,由强制切换而提前归档的文件长度仍与装满的文件相同。因此,把archive_timeout设得很短并不明智,这会使归档存储膨胀。archive_timeout设为大约 1 分钟通常是合理的。 + 归档命令或归档函数只会针对已完成的 WAL 段调用。因此,如果服务器产生的 WAL 流量很小(或者存在低谷期),事务完成到其被安全写入归档存储之间可能会有很长延迟。为了限制未归档数据可能有多旧,你可以设置,使服务器强制切换到新 WAL 段文件的间隔不超过这个值。注意,由强制切换而提前归档的文件长度仍与装满的文件相同。因此,把archive_timeout设得很短并不明智,这会使归档存储膨胀。archive_timeout设为大约 1 分钟通常是合理的。 @@ -438,7 +434,7 @@ test ! -f /mnt/server/archivedir/00000001000000A900000065 && cp pg_wal/0 - 恢复增量备份时,不仅需要增量备份本身,还必须具有所有更早的备份,以便提供增量备份中省略的那些块。关于这项要求的更多信息见。请注意,当集簇的校验和状态发生变化时,使用pg_combinebackup会受到限制;参见pg_combinebackup limitations。 + 恢复增量备份时,不仅需要增量备份本身,还必须具有提供增量备份中省略的块所需的所有较早备份。关于这项要求的更多信息见。请注意,当集簇的校验和状态发生变化时,使用pg_combinebackup会受到限制;参见pg_combinebackup 的限制。 @@ -446,7 +442,7 @@ test ! -f /mnt/server/archivedir/00000001000000A900000065 && cp pg_wal/0 - 增量备份通常只对相对较大的数据库有意义,因为其中相当一部分数据不变,或者变化缓慢。对于小数据库,忽略增量备份的存在而直接进行完整备份会更简单,也更容易管理。对于所有数据都被频繁修改的大数据库,增量备份也不会比完整备份小多少。 + 增量备份通常只对相当一部分数据不变或变化缓慢的较大数据库有意义。对于小数据库,忽略增量备份的存在而直接进行完整备份会更简单,也更容易管理。对于所有数据都被频繁修改的大数据库,增量备份也不会比完整备份小多少。 @@ -610,7 +606,7 @@ SELECT * FROM pg_backup_stop(wait_for_archive => true); - 这一切的关键在于设置一个恢复配置,描述你希望如何恢复,以及恢复应运行到什么位置。其中绝对必须指定的一项是restore_command,它告诉PostgreSQL如何检索已归档的 WAL 文件段。像archive_command一样,它也是一个 shell 命令字符串。它可以包含%f,会被替换为所需 WAL 文件的名称;也可以包含%p,会被替换为复制该 WAL 文件时要使用的路径名。(该路径名相对于当前工作目录,也就是集簇的数据目录。)如果需要在命令中嵌入实际的%字符,请写成%%。最简单而有用的命令类似如下: + 这一切的关键在于设置一个恢复配置,描述你希望如何恢复,以及恢复应运行到什么位置。其中绝对必须指定的一项是restore_command,它告诉PostgreSQL如何检索已归档的 WAL 段文件。像archive_command一样,它也是一个 shell 命令字符串。它可以包含%f,会被替换为所需 WAL 文件的名称;也可以包含%p,会被替换为复制该 WAL 文件时要使用的路径名。(该路径名相对于当前工作目录,也就是集簇的数据目录。)如果需要在命令中嵌入实际的%字符,请写成%%。最简单而有用的命令类似如下: restore_command = 'cp "/mnt/server/archivedir/%f" "%p"' @@ -618,11 +614,11 @@ restore_command = 'cp "/mnt/server/archivedir/%f" "%p"' - 重要的是,该命令在失败时必须返回非零退出状态。系统调用该命令来请求归档中不存在的文件;遇到这种情况时,它就应返回非零值。这不是一种错误情况。例外是,如果该命令被信号终止(用于数据库服务器关闭的SIGTERM除外),或者因 shell 错误(如命令未找到)而失败,那么恢复将中止,服务器也不会启动。 + 重要的是,该命令在失败时必须返回非零退出状态。系统调用该命令来请求归档中不存在的文件;遇到这种情况时,它必须返回非零值。这不是一种错误情况。例外是,如果该命令被信号终止(用于数据库服务器关闭的SIGTERM除外),或者因 shell 错误(如命令未找到)而失败,那么恢复将中止,服务器也不会启动。 - 被请求的文件并不全都是 WAL 段文件;你还应预期会收到对带有.history后缀文件的请求。另外请注意,%p路径的基本文件名会与%f不同;不要指望它们可以互换使用。 + 被请求的文件并不全都是 WAL 段文件;你还应预期会收到对带有.history后缀文件的请求。另外请注意,%p路径的文件名部分会与%f不同;不要指望它们可以互换使用。 @@ -630,16 +626,16 @@ restore_command = 'cp "/mnt/server/archivedir/%f" "%p"' - 通常,恢复会处理完所有可用的 WAL 段,从而把数据库恢复到当前时间点(或者在可用 WAL 段所允许的情况下尽可能接近当前时间点)。因此,一次正常恢复通常会以一条file not found消息结束,具体错误文本取决于你选择的restore_command。在恢复开始时,你也可能看到一条针对类似00000001.history文件的错误消息。这同样是正常的,在简单恢复场景中并不表示有问题;相关讨论见。 + 通常,恢复会处理完所有可用的 WAL 段,从而把数据库恢复到当前时间点(或者在可用 WAL 段所允许的情况下尽可能接近当前时间点)。因此,一次正常恢复会以一条file not found消息结束,具体错误文本取决于你选择的restore_command。在恢复开始时,你也可能看到一条针对类似00000001.history文件的错误消息。这同样是正常的,在简单恢复场景中并不表示有问题;相关讨论见 - 如果你希望恢复到过去的某个时间点(例如恢复到那位初级 DBA 删掉你的主事务表之前),只需指定所需的停止点即可。这个停止点也称为恢复目标,可以通过日期/时间、命名恢复点或者某个特定事务 ID 完成时刻来指定。在目前的实现下,只有日期/时间和命名恢复点这两种方式真正比较实用,因为没有工具能够帮助你足够准确地识别应使用哪个事务 ID。 + 如果你希望恢复到过去的某个时间点(例如恢复到那位初级 DBA 删掉你的主事务表之前),只需指定所需的停止点即可。这个停止点也称为恢复目标,可以通过日期/时间、命名恢复点或者某个特定事务 ID 完成时刻来指定。在撰写本文时,只有日期/时间和命名恢复点这两种方式真正比较实用,因为没有工具能够帮助你足够准确地识别应使用哪个事务 ID。 - 停止点必须晚于基础备份的结束时间,也就是pg_backup_stop的结束时间。你不能用某次基础备份恢复到该备份仍在进行中的时间点。(若要恢复到这样的时间点,必须回到更早的一次基础备份,再从那里向前滚动。) + 停止点必须晚于基础备份的结束时间,也就是pg_backup_stop的结束时间。你不能用某次基础备份恢复到该备份仍在进行中的时间点。(若要恢复到这样的时间点,必须回到更早的一次基础备份,再从那里向前重放日志。) @@ -653,12 +649,10 @@ restore_command = 'cp "/mnt/server/archivedir/%f" "%p"' 时间线 - timelines + 时间线 - - 把数据库恢复到过去某个时间点的能力,会带来一些复杂性,颇有点像关于时间旅行和平行宇宙的科幻小说。例如,在数据库的原始历史中,假设你在星期二晚上 5:15 删掉了一张关键表,但直到星期三中午才意识到自己的错误。于是你拿出备份,把系统恢复到星期二晚上 5:14,并重新上线运行。在数据库宇宙的这条历史中,你从未删掉那张表。但如果你后来发现这并不是个好主意,并且想回到原始历史中的星期三上午某个时间点,就办不到了,因为在数据库重新上线运行期间,它可能已经覆盖了某些 WAL 段文件,而这些文件本来能把你带回到现在想回去的那个时刻。因此,为了避免这种情况,你需要把时间点恢复之后生成的那一串 WAL 记录,与数据库原始历史中生成的那些 WAL 记录区分开来。 - + 能够将数据库恢复到过去某个时间点,也会带来一些类似科幻故事中时间旅行和平行宇宙的复杂情况。例如,假设在数据库原来的历史中,你在周二下午 5:15 删除了一张重要的表,直到周三中午才发现错误。你从容地取出备份,将数据库恢复到周二下午 5:14,然后重新投入运行。在数据库宇宙的这段历史中,你从未删除过那张表。但假设你后来发现这样做不太合适,希望回到原来历史中的周三上午某个时刻。如果数据库恢复运行后覆盖了通往该时刻所需的某些 WAL 段文件,就无法回去了。因此,为了避免这种情况,需要区分时间点恢复后产生的一系列 WAL 记录与数据库原来历史中产生的记录。 为了解决这个问题,PostgreSQL引入了时间线的概念。每当一次归档恢复完成时,系统都会创建一条新的时间线,用来标识此次恢复之后生成的 WAL 记录序列。时间线 ID 是 WAL 段文件名的一部分,因此新的时间线不会覆盖先前时间线产生的 WAL 数据。例如,在 WAL 文件名0000000100001234000055CD中,开头的00000001就是十六进制表示的时间线 ID。(注意,在服务器日志消息等其他场合,时间线 ID 通常以十进制打印。) @@ -672,9 +666,7 @@ restore_command = 'cp "/mnt/server/archivedir/%f" "%p"' 每当创建一条新的时间线时,PostgreSQL都会创建一个时间线历史文件,记录它是从哪条时间线、在何时分叉出来的。当从包含多条时间线的归档中恢复时,这些历史文件对于系统选取正确的 WAL 段文件是必需的。因此,它们会像 WAL 段文件一样被归档到 WAL 归档区域。历史文件只是很小的文本文件,因此长期保存它们既便宜也合适(而段文件通常很大)。如果你愿意,还可以在历史文件中加入注释,记录创建这条时间线的方式和原因。当你因实验而积累出一批错综复杂的时间线时,这类注释会特别有价值。 - - 恢复的默认行为是恢复到归档中找到的最新时间线。如果你希望恢复到执行基础备份时的当前时间线,或者恢复到某个指定的子时间线(也就是说,你想回到某个本身就是在一次恢复尝试之后才产生的状态),就需要指定current,或者在中指定目标时间线 ID。你不能恢复到那些在基础备份之前就已经分叉出去的时间线。 - + 默认的恢复行为是恢复到归档中找到的最新时间线。如果希望恢复到制作基础备份时的当前时间线,或者某条特定的子时间线(即希望返回到一次恢复尝试之后产生的某个状态),需要在 中指定 current 或目标时间线 ID。不能恢复到在基础备份之前就已分支出去的时间线。 @@ -685,14 +677,14 @@ restore_command = 'cp "/mnt/server/archivedir/%f" "%p"' - 单机热备份 + 独立热备份 - 可以利用PostgreSQL的备份设施生成单机热备份。这些备份不能用于时间点恢复,但它们的制作和恢复通常都比pg_dump转储快得多。(它们也比pg_dump转储大得多,因此在某些情况下速度优势可能会被抵消。) + 可以利用PostgreSQL的备份设施生成独立热备份。这些备份不能用于时间点恢复,但它们的制作和恢复通常都比pg_dump转储快得多。(它们也比pg_dump转储大得多,因此在某些情况下速度优势可能会被抵消。) - 和基础备份一样,生成单机热备份最简单的方法是使用工具。如果在调用它时包含-X参数,使用该备份所需的全部预写式日志都会自动包含在备份中,恢复该备份时也不需要额外动作。 + 和基础备份一样,生成独立热备份最简单的方法是使用工具。如果在调用它时包含-X参数,使用该备份所需的全部预写式日志都会自动包含在备份中,恢复该备份时也不需要额外动作。 @@ -723,7 +715,7 @@ archive_command = 'local_backup_script.sh "%p" "%f"' - 脚本中可能需要解决的需求示例包括: + 可以在脚本中处理的需求示例包括: @@ -732,7 +724,7 @@ archive_command = 'local_backup_script.sh "%p" "%f"' - 把 WAL 文件成批处理,使其每三个小时传输一次,而不是每生成一个就传一次 + 把 WAL 文件成批处理,使其每三个小时传输一次,而不是每次只传输一个 diff --git a/zh/19/brin.sgml b/zh/19/brin.sgml index cc6cc7b1..deeaac0f 100644 --- a/zh/19/brin.sgml +++ b/zh/19/brin.sgml @@ -4,7 +4,7 @@ BRIN 索引 - index + 索引 BRIN @@ -25,8 +25,7 @@ - 如果索引中存储的摘要信息与查询条件相一致BRIN - 索引就可以通过常规位图索引扫描来满足查询,并返回每个范围内所有页上的全部元组。 + BRIN 索引可以通过常规位图索引扫描来满足查询;对于每个范围,如果索引中存储的摘要信息与查询条件相一致,就会返回该范围内所有页上的全部元组。 查询执行器负责重新检查这些元组,并丢弃不匹配查询条件的元组 — 换句话说,这些索引是有损的。 由于 BRIN 索引非常小,与顺序扫描相比,扫描索引只会带来很小的额外开销, 但可以避免扫描那些已知不包含匹配元组的大块表数据。 @@ -85,7 +84,7 @@ 当启用自动摘要时,一旦检测到向下一个块范围第一页的第一项执行了插入, - 就会向 autovacuum 发送请求,要求对该块范围执行定向摘要。 + 就会向 autovacuum 发送请求,要求对前一个块范围执行定向摘要。 该请求会在同一数据库中的某个 autovacuum 工作进程下一次结束运行时得到处理。 如果请求队列已满,该请求就不会被记录,并会向服务器日志发送一条消息: @@ -790,13 +789,13 @@ LOG: request for BRIN range summarization for index "brin_wi_idx" page 128 was typedef struct BrinOpcInfo { - /* Number of columns stored in an index column of this opclass */ + /* 此操作符类在一个索引列中存储的列数 */ uint16 oi_nstored; - /* Opaque pointer for the opclass' private use */ + /* 供操作符类私有使用的不透明指针 */ void *oi_opaque; - /* Type cache entries of the stored columns */ + /* 所存储列的类型缓存条目 */ TypeCacheEntry *oi_typcache[FLEXIBLE_ARRAY_MEMBER]; } BrinOpcInfo; @@ -1012,62 +1011,62 @@ typedef struct BrinOpcInfo 操作符策略 1 - left-of 操作符 + 位于左侧的操作符 操作符策略 4 操作符策略 2 - does-not-extend-to-the-right-of 操作符 + 不延伸到右侧的操作符 操作符策略 5 操作符策略 3 - overlaps 操作符 + 重叠操作符 操作符策略 4 - does-not-extend-to-the-left-of 操作符 + 不延伸到左侧的操作符 操作符策略 1 操作符策略 5 - right-of 操作符 + 位于右侧的操作符 操作符策略 2 - 操作符策略 6, 18 - same-as-or-equal-to 操作符 + 操作符策略 6、18 + 相同或等于操作符 操作符策略 7 - 操作符策略 7, 16, 24, 25 - contains-or-equal-to 操作符 + 操作符策略 7、16、24、25 + 包含或等于操作符 - 操作符策略 8, 26, 27 - is-contained-by-or-equal-to 操作符 + 操作符策略 8、26、27 + 被包含或等于操作符 操作符策略 3 操作符策略 9 - does-not-extend-above 操作符 + 不延伸到上方的操作符 操作符策略 11 操作符策略 10 - is-below 操作符 + 位于下方的操作符 操作符策略 12 操作符策略 11 - is-above 操作符 + 位于上方的操作符 操作符策略 9 操作符策略 12 - does-not-extend-below 操作符 + 不延伸到下方的操作符 操作符策略 10 @@ -1113,12 +1112,12 @@ typedef struct BrinOpcInfo 要为仅实现等值操作符且支持哈希的数据类型编写操作符类,可以按 - 所示,将 bloom 支持过程与相应操作符一起使用。 - 所有操作符类成员(过程和操作符)都是必需的。 + 所示,将 bloom 支持函数与相应操作符一起使用。 + 所有操作符类成员(函数和操作符)都是必需的。 - bloom 操作符类的过程和支持编号 + bloom 操作符类的函数和支持编号 @@ -1128,28 +1127,28 @@ typedef struct BrinOpcInfo - 支持过程 1 + 支持函数 1 内部函数brin_bloom_opcinfo() - 支持过程 2 + 支持函数 2 内部函数brin_bloom_add_value() - 支持过程 3 + 支持函数 3 内部函数brin_bloom_consistent() - 支持过程 4 + 支持函数 4 内部函数brin_bloom_union() - 支持过程 5 + 支持函数 5 内部函数brin_bloom_options() - 支持过程 11 - 计算元素哈希值的函数 + 支持函数 11 + 计算元素 hash 值的函数 操作符策略 1 @@ -1160,20 +1159,20 @@ typedef struct BrinOpcInfo
- 支持过程编号 1 至 10 保留给 BRIN 内部函数,因此 SQL 层函数从编号 11 开始。 + 支持函数编号 1 至 10 保留给 BRIN 内部函数,因此 SQL 层函数从编号 11 开始。 支持函数 11 是构建索引所需的主要函数。 - 它应接受一个与操作符类数据类型相同的参数,并返回该值的哈希值。 + 它应接受一个与操作符类数据类型相同的参数,并返回该值的 hash 值。 minmax-multi 操作符类也面向实现全序集的数据类型,可以看作 minmax 操作符类的简单扩展。 minmax 操作符类把每个块范围中的值摘要为单个连续区间,而 minmax-multi 则允许将其摘要为多个较小区间,以改进对离群值的处理。 - 可以按 所示,将 minmax-multi 支持过程与相应操作符一起使用。 - 所有操作符类成员(过程和操作符)都是必需的。 + 可以按 所示,将 minmax-multi 支持函数与相应操作符一起使用。 + 所有操作符类成员(函数和操作符)都是必需的。 - minmax-multi 操作符类的过程和支持编号 + minmax-multi 操作符类的函数和支持编号 @@ -1183,27 +1182,27 @@ typedef struct BrinOpcInfo - 支持过程 1 + 支持函数 1 内部函数brin_minmax_multi_opcinfo() - 支持过程 2 + 支持函数 2 内部函数brin_minmax_multi_add_value() - 支持过程 3 + 支持函数 3 内部函数brin_minmax_multi_consistent() - 支持过程 4 + 支持函数 4 内部函数brin_minmax_multi_union() - 支持过程 5 + 支持函数 5 内部函数brin_minmax_multi_options() - 支持过程 11 + 支持函数 11 计算两个值之间距离(范围长度)的函数 diff --git a/zh/19/btree.sgml b/zh/19/btree.sgml index 4f6b9006..845b6433 100644 --- a/zh/19/btree.sgml +++ b/zh/19/btree.sgml @@ -4,7 +4,7 @@ B-树索引 - index + 索引 B-树 @@ -18,10 +18,10 @@ - 由于每个 B-树 操作符类都会为其数据类型施加一种排序顺序,B-树 + 由于每个 B-树操作符类都会为其数据类型施加一种排序顺序,B-树 操作符类(更准确地说,是操作符族)已经成为 PostgreSQL 用来统一表示和理解排序语义的方式。因此,它们具备了一些超出单纯支持 - B-树 索引所需范围的特性,系统中某些与 btree AM + B-树索引所需范围的特性,系统中某些与 B-树 AM 相距甚远的部分也会利用它们。 @@ -55,7 +55,7 @@ - = 操作符必须是一种等价关系;也就是说,对于该数据类型的所有非空值 + = 操作符必须是一种等价关系;也就是说,对于该数据类型的所有非 null 值 ABC: @@ -93,7 +93,7 @@ - < 操作符必须是一种强排序关系;也就是说,对于所有非空值 + < 操作符必须是一种强排序关系;也就是说,对于所有非 null 值 ABC: @@ -123,7 +123,7 @@ - 此外,该顺序还是全序的;也就是说,对于所有非空值 + 此外,该顺序还是全序的;也就是说,对于所有非 null 值 AB: @@ -177,18 +177,18 @@ B-树支持函数 - 如所示,btree 定义了一个必需和五个可选的支持函数。六个用户定义的方法如下: + 如所示,B-树定义了一个必需和五个可选的支持函数。六个用户定义的方法如下: order - 对于 B-树 操作符族为其提供比较操作符的每一种数据类型组合,都必须提供一个比较支持函数。该函数在 + 对于 B-树操作符族为其提供比较操作符的每一种数据类型组合,都必须提供一个比较支持函数。该函数在 pg_amproc 中注册,支持函数编号为 1,并且 amproclefttype/amprocrighttype 要等于该比较的左右数据类型(也就是与匹配操作符在 - pg_amop 中注册时相同的数据类型)。比较函数必须接受两个非空值 + pg_amop 中注册时相同的数据类型)。比较函数必须接受两个非 null 值 AB,并返回一个 int32 值,其值为 < 0、 @@ -197,12 +197,12 @@ < BA = BA - > B。不允许返回空值:该数据类型的所有值都必须可比较。示例见 + > B。不允许返回 null:该数据类型的所有值都必须可比较。示例见 src/backend/access/nbtree/nbtcompare.c - 如果参与比较的值属于可排序数据类型,则会通过标准的 + 如果参与比较的值属于支持排序规则的数据类型,则会通过标准的 PG_GET_COLLATION() 机制,把适当的排序规则 OID 传递给比较支持函数。 @@ -223,11 +223,11 @@ in_range - in_range support functions + in_range 支持函数 - support functions + 支持函数 in_range @@ -266,7 +266,7 @@ returns bool - in_range 函数的核心语义取决于这两个 Boolean + in_range 函数的核心语义取决于这两个布尔 标志参数。它应当先对 baseoffset 做加法或减法,再把 val 与结果比较,具体如下: @@ -383,7 +383,7 @@ returns bool - 如果被排序的类型(type1)属于可排序数据类型,则会通过标准的 + 如果被排序的类型(type1)属于支持排序规则的数据类型,则会通过标准的 PG_GET_COLLATION() 机制,把适当的排序规则 OID 传递给 in_range 函数。 @@ -408,12 +408,7 @@ returns bool equalimage(opcintype oid) returns bool - 返回值是关于某个操作符类及其排序规则的静态信息。返回 - true 表示:该操作符类的 - order 函数被保证只有在返回 - 0arguments are equal)时,其 - AB - 参数才是可以互换而不损失任何语义信息的。如果未注册 + 返回值是关于某个操作符类及其排序规则的静态信息。返回 true 表示可以保证:该操作符类的 order 函数只有在其 AB 参数也能够互换而不损失任何语义信息时,才会返回 0参数相等)。如果未注册 equalimage 函数,或其返回 false,就表示不能假定该条件成立。 @@ -421,7 +416,7 @@ equalimage(opcintype oid) returns bool opcintype 参数是该操作符类所索引数据类型的 pg_type.oid。这只是为了方便在不同操作符类之间复用同一个底层 equalimage 函数。如果 - opcintype 是可排序数据类型,则会通过标准的 + opcintype 是支持排序规则的数据类型,则会通过标准的 PG_GET_COLLATION() 机制,把适当的排序规则 OID 传递给 equalimage 函数。 @@ -453,7 +448,7 @@ equalimage(opcintype oid) returns bool 发行版中包含的操作符类遵循的惯例是:注册一个现成的通用 equalimage 函数。大多数操作符类注册 btequalimage(),这表示去重在无条件下都是安全的。像 - text 这样可排序数据类型的操作符类会注册 + text 这样支持排序规则的数据类型的操作符类会注册 btvarstrequalimage(),这表示在确定性排序规则下去重是安全的。第三方扩展的最佳实践则是注册它们自己的自定义函数,以保留控制权。 @@ -493,19 +488,19 @@ options(relopts local_relopts *) returns skipsupport - 可选地,B-树 操作符族可以提供skip 支持函数,注册为支持函数编号 + 可选地,B-树操作符族可以提供跳过支持函数,注册为支持函数编号 6。这些函数为 B-树 代码提供了一种按键空间顺序遍历某个操作符类底层输入类型所能表示的全部可能值的方法。当核心代码应用跳过扫描优化时,就会用到它。相关 API 定义在 src/include/utils/skipsupport.h 中。 - 没有提供 skip 支持函数的操作符类,仍然可以使用跳过扫描。核心代码仍可采用其后备策略,尽管对于某些离散类型来说,这种策略可能并非最优。对于连续类型上的操作符类,提供 - skip 支持函数通常没有意义(甚至可能不可行)。 + 没有提供跳过支持函数的操作符类,仍然可以使用跳过扫描。核心代码仍可采用其后备策略,尽管对于某些离散类型来说,这种策略可能并非最优。对于连续类型上的操作符类,提供 + 跳过支持函数通常没有意义(甚至可能不可行)。 操作符族注册跨类型的 skipsupport - 函数并不合理,尝试这样做会导致错误。因为要确定下一个可被索引的值,必须通过递增一个从索引元组复制出来的值来完成。所生成的值都必须属于同一种底层数据类型(也就是被跳过的索引列的 opclass 输入类型)。 + 函数并不合理,尝试这样做会导致错误。因为要确定下一个可被索引的值,必须通过递增一个从索引元组复制出来的值来完成。所生成的值都必须属于同一种底层数据类型(也就是被跳过的索引列的操作符类输入类型)。 @@ -547,7 +542,7 @@ options(relopts local_relopts *) returns B-树索引会通过执行自底向上索引删除轮次,增量地删除这类版本频繁更替产生的索引元组。每一轮删除都是因预期中的版本频繁更替页拆分而触发的。这只会发生在那些没有被 - UPDATE 语句逻辑修改的索引上,否则过时版本就会集中积累在某些特定页面中。通常可以避免页拆分,不过也可能出现某些实现层面的启发式规则甚至一个垃圾索引元组都识别不出来、删不掉的情况(这时就要靠页拆分或一次去重轮次来解决新元组放不进叶页的问题)。任何一次索引扫描在单个逻辑行上必须穿越的最坏版本数,是影响整个系统响应能力和吞吐量的重要因素。一次自底向上索引删除轮次会基于涉及逻辑行与版本的定性区别,针对单个叶页中疑似垃圾的元组。这与自动清理工作进程执行的自顶向下索引清理不同,后者是在超出某些定量的表级阈值时触发的(见)。 + UPDATE 语句逻辑修改的索引上;如果不执行这类删除,过时版本就会集中积累在某些特定页面中。通常可以避免页拆分,不过也可能出现某些实现层面的启发式规则甚至一个垃圾索引元组都识别不出来、删不掉的情况(这时就要靠页拆分或一次去重轮次来解决新元组放不进叶页的问题)。任何一次索引扫描在单个逻辑行上必须穿越的最坏版本数,是影响整个系统响应能力和吞吐量的重要因素。一次自底向上索引删除轮次会基于涉及逻辑行与版本的定性区别,针对单个叶页中疑似垃圾的元组。这与自动清理工作进程执行的自顶向下索引清理不同,后者是在超出某些定量的表级阈值时触发的(见)。 @@ -587,7 +582,7 @@ options(relopts local_relopts *) returns 去重通过周期性地把一组组重复元组合并起来,为每一组形成一个 - posting list 元组。在这种表示中,列键值只出现一次,后面跟着一个排好序的 + 倒排列表 元组。在这种表示中,列键值只出现一次,后面跟着一个排好序的 TID 数组,指向表中的各行。这能显著减小那些每个值(或每一种不同列值组合)平均会出现多次的索引的存储大小。查询延迟可能显著降低,整体查询吞吐量也可能显著提升,例行索引清理的开销同样可能显著减少。 @@ -601,14 +596,14 @@ options(relopts local_relopts *) returns 去重过程是惰性发生的:当插入一个放不进现有叶页的新项时,只有在索引元组删除也无法为该新项释放足够空间的情况下,才会进行去重(通常只会短暂考虑删除,然后就跳过)。与 - GIN 的 posting list 元组不同,B-树的 posting list - 元组不需要在每次插入新的重复项时都扩展;它们只是叶页原始逻辑内容的一种替代物理表示。这种设计优先考虑混合读写工作负载下的一致性能。大多数客户端应用至少都能从去重中获得适度的性能收益。去重默认启用。 + GIN 的倒排列表元组不同,B-树的倒排列表 + 元组不需要在每次插入新的重复项时都扩展;它们只是叶页原始逻辑内容的一种替代物理表示。这种设计优先考虑混合读写工作负载下的稳定性能。大多数客户端应用至少都能从去重中获得适度的性能收益。去重默认启用。 CREATE INDEXREINDEX - 都会应用去重来创建 posting list - 元组,只是两者采用的策略略有不同。对于从表中取出的已排序输入中遇到的每一组普通重复元组,都会在被加入当前待写入叶页之前先合并成一个 - posting list 元组。每个 posting list 元组都会尽量容纳更多的 + 都会应用去重来创建倒排列表 + 元组,不过它们采用的策略与上述过程略有不同。对于从表中取出的已排序输入中遇到的每一组普通重复元组,都会在被加入当前待写入叶页之前先合并成一个 + 倒排列表元组。每个倒排列表元组都会尽量容纳更多的 TID。叶页按通常方式写出,不需要额外独立的去重过程。由于 CREATE INDEXREINDEX 都是一次性的批处理操作,这种策略非常适合它们。 @@ -617,14 +612,14 @@ options(relopts local_relopts *) returns 如果某个写密集型工作负载由于索引中的重复值很少甚至没有,而无法从去重中获益,那么它会承担很小且固定的性能损耗(除非显式禁用去重)。 deduplicate_items 存储参数可用于在单个索引内禁用去重。而只读工作负载绝不会因此遭受性能损失,因为读取 - posting list 元组至少与读取标准元组表示一样高效。禁用去重通常并没有帮助。 + 倒排列表元组至少与读取标准元组表示一样高效。禁用去重通常并没有帮助。 有时唯一索引(以及唯一约束)也可以使用去重。这允许叶页临时吸收因版本频繁更替产生的额外重复项。唯一索引中的去重能够增强自底向上索引删除,特别是在长事务持有阻塞垃圾回收的快照时。其目标是为自底向上索引删除策略再次发挥作用争取时间。把页拆分推迟到某个单独的长事务自然结束之后,可能使一次自底向上删除轮次在较早一次失败的地方获得成功。 - 系统会应用一种特殊的启发式规则,来判定唯一索引中是否应当执行一次去重轮次。它往往可以直接跳到拆分叶页,从而避免把周期浪费在无益的去重过程中而造成性能损耗。如果你担心去重的开销,可以考虑有选择地设置 + 系统会应用一种特殊的启发式规则,来判定唯一索引中是否应当执行一次去重轮次。它往往可以直接跳到拆分叶页,从而避免把处理器周期浪费在无益的去重过程中而造成性能损耗。如果你担心去重的开销,可以考虑有选择地设置 deduplicate_items = off。在唯一索引中保持去重启用,坏处很小。 @@ -648,7 +643,7 @@ options(relopts local_relopts *) returns numeric 不能使用去重。必须保留相等的 datum - 之间的小数位数。 + 之间的显示小数位数。 diff --git a/zh/19/catalogs.sgml b/zh/19/catalogs.sgml index b2e9a46a..f5bce9be 100644 --- a/zh/19/catalogs.sgml +++ b/zh/19/catalogs.sgml @@ -703,7 +703,7 @@ t = 表(包括物化视图), - i = 索引. + i = 索引。 @@ -956,7 +956,7 @@
- amproclefttypeamprocrighttype列的通常解释是它们标识了一个特定支持过程所支持的操作符的左右输入类型。对于某些访问方法它们和支持过程本身的输入数据类型相匹配,而对其他的则不会匹配。对于一个索引有一个默认支持过程的概念,这些支持过程的amproclefttypeamprocrighttype都等于索引操作符类的opcintype。 + amproclefttypeamprocrighttype列的通常解释是它们标识了一个特定支持函数所支持的操作符的左右输入类型。对于某些访问方法它们和支持函数本身的输入数据类型相匹配,而对其他的则不会匹配。对于一个索引有一个默认支持函数的概念,这些支持函数的amproclefttypeamprocrighttype都等于索引操作符类的opcintype @@ -1117,7 +1117,7 @@
atttypmod记录了在表创建时提供的类型相关数据(例如一个varchar列的最大长度)。 - 它会被传递给类型相关的输入函数和长度强制函数。对于那些不需要atttypmod的类型,这个值通常总是为-1。 + 它会被传递给类型相关的输入函数和长度强制转换函数。对于那些不需要atttypmod的类型,这个值通常为 -1。 @@ -1195,8 +1195,7 @@ atthasmissing bool
- 该列在行中完全缺失时会用到这个列的值,如果在行创建之后增加一个有非易失DEFAULT值的列,就会发生这种情况。 - 实际使用的值被存放在attmissingval列中。 + 此列有一个值,供该列在数据行中完全缺失时使用;在数据行创建之后添加带有非易失 DEFAULT 值的列时,就会出现这种情况。实际使用的值存储在 attmissingval 列中。 @@ -1226,7 +1225,7 @@ attisdropped bool - 该列被删除且不再有效。一个删除的列仍然物理存在于表中,但是会被分析器忽略并因此无法通过SQL访问。 + 该列被删除且不再有效。一个删除的列仍然物理存在于表中,但是会被解析器忽略并因此无法通过SQL访问。 @@ -1254,7 +1253,7 @@ (引用 pg_collation.oid - 该列被定义的排序规则,如果该列不是一个可排序数据类型则为0。 + 该列定义的排序规则;如果该列的数据类型不支持排序规则,则为零。 @@ -1277,7 +1276,7 @@ attacl aclitem[] - 列级访问权限, 如果此列上已有特别授予的权限 + 列级访问权限,如果此列上已有特别授予的权限 @@ -1305,7 +1304,7 @@ 这个列中是一个含有一个元素的数组,其中的值被用于该列在行中完全缺失时,如果在行创建之后增加一个有非易失DEFAULT值的列,就会发生这种情况。 - 只有当atthasmissing为真时才使用这个值。如果没有值则该列为空。 + 只有当atthasmissing为真时才使用这个值。如果没有值则该列为空值。 @@ -1313,9 +1312,7 @@ - 在一个被删除的列的pg_attribute的项中,atttypid被重置为0,但attlen以及其他从pg_type拷贝的域仍然有效。 - 这种安排用于处理一种情况,即被删除列的数据类型后来被删除,并且因此不再有相应的pg_type行。 - attlen和其他域可以被用来解释表的一行的内容。 + 在被删除列的 pg_attribute 条目中,atttypid 被重置为零,但 attlen 以及其他从 pg_type 复制的字段仍然有效。这种安排用于应对被删除列的数据类型后来也被删除、因而不再有相应 pg_type 行的情况。attlen 和其他字段可用于解释表中一行的内容。 @@ -1444,7 +1441,7 @@ rolconnlimit int4 - 对于可以登录的角色,本列设置该角色可以同时发起最大连接数。-1表示无限制。 + 对于可以登录的角色,本列设置该角色能够建立的最大并发连接数。-1 表示无限制。 @@ -1453,7 +1450,7 @@ rolpassword text - 加密后的密码;如果未设置则为空。其格式取决于所使用的加密方式。 + 加密后的密码;如果未设置则为空值。其格式取决于所使用的加密方式。 @@ -1462,7 +1459,7 @@ rolvaliduntil timestamptz - 密码过期时间(只用于密码鉴定),如果永不过期则为空 + 密码过期时间(仅用于密码认证);不设过期时间时为空值 @@ -1470,13 +1467,11 @@ - 对于一个MD5加密的密码,rolpassword列将由字符串md5后面跟上一个32字符的十六进制MD5哈希值构成。MD5哈希值将是该用户的密码串接上它们的用户名。例如,如果用户joe的密码是xyzzy,则PostgreSQL将存储xyzzyjoe的md5哈希。 + 对于一个MD5加密的密码,rolpassword列将由字符串md5后面跟上一个32字符的十六进制MD5哈希值构成。MD5 哈希值通过在用户密码后拼接用户名再计算得到。例如,如果用户joe的密码是xyzzy,则PostgreSQL将存储xyzzyjoe的md5哈希。 - - 对 MD5 加密密码的支持已被弃用,并将在未来的 PostgreSQL 发布中移除。关于迁移到其他密码类型的详细信息,请参见。 - + 对 MD5 加密密码的支持已弃用,并将在PostgreSQL的未来版本中移除。迁移到其他密码类型的详细信息见 @@ -1607,7 +1602,7 @@ SCRAM-SHA-256$<iteration count>:&l - 需要注意的是,pg_cast并不表示系统知道如何执行的所有类型转换,它只包括那些不能从某些通用规则推导出的转换。例如,一个域及其基类型之间的转换并未显式地在pg_cast中展示。另一个重要的例外是自动的基于 I/O 的类型转换,它们通过数据类型自己的 I/O 函数来转换成(或者转换自)text或其他字符串类型,这些转换也没有显式地在pg_cast中表示。 + 需要注意的是,pg_cast并不表示系统知道如何执行的所有类型转换,它只包括那些不能从某些通用规则推导出的转换。例如,一个域及其基础类型之间的转换并未显式地在pg_cast中展示。另一个重要的例外是自动的基于 I/O 的类型转换,它们通过数据类型自己的 I/O 函数来转换成(或者转换自)text或其他字符串类型,这些转换也没有显式地在pg_cast中表示。 @@ -1712,7 +1707,7 @@ SCRAM-SHA-256$<iteration count>:&l - 目录pg_class描述了具有列或与表类似的其他对象。这包括索引(但请参见pg_index)、序列(但请参见pg_sequence)、视图、物化视图、复合类型和TOAST表;请参见relkind。 + 目录pg_class描述了表以及其他具有列或在其他方面与表类似的对象。这包括索引(但请参见pg_index)、序列(但请参见pg_sequence)、视图、物化视图、复合类型和TOAST表;请参见relkind。 在下面,当我们指的是所有这些类型的对象时,我们称之为关系(relations)。并非所有pg_class的列对所有关系类型都有意义。 @@ -1764,9 +1759,7 @@ SCRAM-SHA-256$<iteration count>:&l reltype oid (引用 pg_type.oid) - - 该关系可能对应的表行类型的数据类型 OID;对索引为 0,而序列和 TOAST 表没有pg_type项 - + 与此表的行类型对应的数据类型的 OID(如有);索引、序列和 TOAST 表没有pg_type项,此值为零 @@ -1901,7 +1894,7 @@ SCRAM-SHA-256$<iteration count>:&l relpersistence char - p = 永久表/序列, u = 不记录 WAL 的表/序列, + p = 永久表/序列,u = 不记录 WAL 的表/序列, t = 临时表/序列 @@ -1919,9 +1912,9 @@ SCRAM-SHA-256$<iteration count>:&l m = 物化视图, c = 复合类型, f = 外部表, - g = 属性图, p = 分区表, - I = 分区索引 + I = 分区索引, + g = 属性图 @@ -1997,7 +1990,7 @@ SCRAM-SHA-256$<iteration count>:&l relispopulated bool - 如果表已被填充则为真(对于所有关系该列都为真,但对于某些物化视图却不是) + 如果关系已被填充则为真(对于所有关系该列都为真,但对于某些物化视图却不是) @@ -2039,7 +2032,7 @@ SCRAM-SHA-256$<iteration count>:&l relfrozenxid xid - 在此之前的所有事务ID在表中已经被替换为一个永久的(冻结的) 事务ID。 + 在此之前的所有事务ID在表中已经被替换为一个永久的(冻结的)事务ID。 这用于跟踪表是否需要被清理,以便阻止事务ID回卷或者允许pg_xact被收缩。 如果该关系不是一个表则为0(InvalidTransactionId)。 @@ -2050,7 +2043,7 @@ SCRAM-SHA-256$<iteration count>:&l relminmxid xid - 在此之前的多事务ID在表中已经被替换为一个事务ID。这被用于跟踪表是否需要被清理,以阻止 + 在此之前的所有多事务ID在表中已经被替换为一个事务ID。这被用于跟踪表是否需要被清理,以阻止 多事务ID回卷或者允许pg_multixact被收缩。如果关系不是一个表则 为0(InvalidMultiXactId)。 @@ -2079,7 +2072,7 @@ SCRAM-SHA-256$<iteration count>:&l relpartbound pg_node_tree - 如果表示一个分区(见relispartition),则为分区边界的内部表示 + 如果表是一个分区(见relispartition),则为分区边界的内部表示 @@ -2087,9 +2080,9 @@ SCRAM-SHA-256$<iteration count>:&l
- pg_class中的一些逻辑标志被以一种懒惰的方式维护:在正确状态时它们被保证为真,但是当条件不再为真时它们并不会被立刻重置为假。 + pg_class中的一些布尔标志采用延迟维护:当条件成立时,保证它们为真;但当条件不再成立时,可能不会立即将它们重置为假。 例如,relhasindexCREATE INDEX设置,但它从不会被DROP INDEX清除。 - 作为替代,VACUUM会在找到无索引表后清除其relhasindex。 + 作为替代,VACUUM会在找到无索引表后清除其relhasindex。 这种安排避免了竞争条件并且提高了并发性。 @@ -2163,9 +2156,10 @@ SCRAM-SHA-256$<iteration count>:&l collprovider char - 排序规则提供者:d = 数据库默认值, + 排序规则提供程序:d = 数据库默认值, b = builtin,c = libc, - i = icu + i = icu + @@ -2191,7 +2185,7 @@ SCRAM-SHA-256$<iteration count>:&l collcollate text - 此排序规则对象的 LC_COLLATE。如果提供者不是 libc,则 collcollate 为 + 此排序规则对象的 LC_COLLATE。如果提供程序不是 libc,则 collcollateNULL,改用 colllocale @@ -2201,7 +2195,7 @@ SCRAM-SHA-256$<iteration count>:&l collctype text - 此排序规则对象的 LC_CTYPE。如果提供者不是 libc,则 collctype 为 + 此排序规则对象的 LC_CTYPE。如果提供程序不是 libc,则 collctypeNULL,改用 colllocale @@ -2211,7 +2205,7 @@ SCRAM-SHA-256$<iteration count>:&l colllocale text - 此排序规则对象的提供者区域设置名称。如果提供者是 libc, + 此排序规则对象的提供程序区域设置名称。如果提供程序是 libc, 则 colllocaleNULL; 改用 collcollatecollctype。 @@ -2232,7 +2226,7 @@ SCRAM-SHA-256$<iteration count>:&l collversion text - 排序规则的提供者相关的版本。这是在排序规则创建时记录下来的,并且在使用排序规则时会被检查以检测可能导致数据损坏的排序规则定义的改变。 + 提供程序特有的排序规则版本。它会在创建排序规则时记录下来,并在使用时接受检查,以检测可能导致数据损坏的排序规则定义更改。 @@ -2578,9 +2572,9 @@ SCRAM-SHA-256$<iteration count>:&l - 在一个排他约束的情况中, conkey只对约束元素是单一列引用时有用。 - 对于其他情况,conkey为0且必须查阅相关索引来发现被约束的表达式。 - (对于索引,conkey因此和pg_index.indkey具有相同的内容)。 + 对于排他约束,conkey仅对作为简单列引用的约束元素有用。 + 对于其他情况,conkey中会出现一个 0,必须查阅关联索引来确定被约束的表达式。 + (因此,conkey与该索引的 pg_index.indkey具有相同的内容。) @@ -2774,8 +2768,9 @@ SCRAM-SHA-256$<iteration count>:&l datlocprovider char - 此数据库的区域设置提供者:b = 内置, - c = libc,i = icu + 此数据库的区域设置提供程序:b = builtin, + c = libc,i = icu + @@ -2874,7 +2869,7 @@ SCRAM-SHA-256$<iteration count>:&l datlocale text - 此数据库的提供者区域设置名称。如果提供者是 libc, + 此数据库的提供程序区域设置名称。如果提供程序是 libc, 则 datlocaleNULL; 改用 datcollatedatctype。 @@ -2895,7 +2890,7 @@ SCRAM-SHA-256$<iteration count>:&l datcollversion text - 该排序规则的提供者特定版本。它会在创建数据库时记录下来,并在使用时接受检查,以检测可能导致数据损坏的排序规则定义更改。 + 提供程序特有的排序规则版本。它会在创建数据库时记录下来,并在使用时接受检查,以检测可能导致数据损坏的排序规则定义更改。 @@ -3987,7 +3982,7 @@ SCRAM-SHA-256$<iteration count>:&l indisunique bool - 如为真, 这是唯一索引 + 如为真, 这是唯一索引 @@ -3996,8 +3991,8 @@ SCRAM-SHA-256$<iteration count>:&l indnullsnotdistinct bool - 该值只用于唯一索引。如果为 false,则该唯一索引会将 null 值视为非重复值(因此索引中可以包含多个 null 值,这是 PostgreSQL 的默认行为)。 - 如果为 true,则会将 null 值视为相等(因此索引中只能包含一个 null 值)。 + 该值只用于唯一索引。如果为 false,则该唯一索引会将 null 值视为彼此不同(因此索引的某一列中可以包含多个 null 值,这是 PostgreSQL 的默认行为)。 + 如果为 true,则会将 null 值视为相等(因此索引的某一列中只能包含一个 null 值)。 @@ -4105,7 +4100,7 @@ SCRAM-SHA-256$<iteration count>:&l (引用 pg_collation.oid - 对于索引键(indnkeyatts值)中的每一列,这包含要用于该索引的排序规则的OID,如果该列不是一种可排序数据类型则为零。 + 对于索引键(indnkeyatts值)中的每一列,这包含要用于该索引的排序规则的OID,如果该列的数据类型不支持排序规则则为零。 @@ -5177,7 +5172,7 @@ SCRAM-SHA-256$<iteration count>:&l (引用 pg_collation.oid - 对于分区键中的每一个列,这个域包含要用于分区的排序规则的OID,如果该列不是一种可排序数据类型则为零。 + 对于分区键中的每一个列,这个域包含要用于分区的排序规则的OID,如果该列的数据类型不支持排序规则则为零。 @@ -6089,7 +6084,7 @@ SCRAM-SHA-256$<iteration count>:&l (引用 pg_collation.oid - 该属性定义的排序规则;如果该属性不是可排序数据类型,则为零。(无论该属性在图中的不同元素和标签中被定义多少次,这一排序规则都必须保持固定。) + 该属性定义的排序规则;如果该属性的数据类型不支持排序规则,则为零。(无论该属性在图中的不同元素和标签中被定义多少次,这一排序规则都必须保持固定。) @@ -6527,7 +6522,11 @@ SCRAM-SHA-256$<iteration count>:&l - rngsubopc (加上rngcollation,如果元素类型是可排序的)决定了被该范围类型所使用的排序顺序。rngcanonical用于离散类型的元素类型。rngsubdiff是可选的,但是提供它可以提高范围类型上的GiST索引性能。 + rngsubopc(如果元素类型支持排序规则,则还包括 + rngcollation)决定范围类型所用的排序顺序。 + rngcanonical用于元素类型为离散类型的情况。 + rngsubdiff是可选的,但应当提供它, + 以提高范围类型上的 GiST 索引性能。 @@ -7215,8 +7214,8 @@ SCRAM-SHA-256$<iteration count>:&l 通常,每个已分析的表列都有一个条目,其中stainherit = false。 - 如果表具有继承子项或分区,则还会创建第二个条目,其中stainherit = true。 - 此行表示继承树上列的统计信息,即您可以通过SELECT column FROM table*看到的数据的统计信息, + 如果表具有继承子表或分区,则还会创建第二个条目,其中stainherit = true。 + 此行表示继承树上列的统计信息,即你可以通过SELECT column FROM table*看到的数据的统计信息, 而stainherit = false行表示SELECT column FROM ONLY table的结果。 @@ -7225,7 +7224,7 @@ SCRAM-SHA-256$<iteration count>:&l - 因为不同类型的统计信息适用于不同类型的数据, pg_statistic 被设计成不太在意自己存储的是什么类型的统计。 只有极为常用的统计信息(比如NULL的含量)才在pg_statistic里给予专用的字段。 其它所有东西都存储在槽位中,而槽位是一组相关的列, 它们的内容用槽位中的一个列里的代码表示。 更详细的信息请参阅 src/include/catalog/pg_statistic.h。 + 由于不同种类的数据可能适合不同种类的统计信息,pg_statistic 在设计上尽量不对所存储的统计信息种类作出假定。只有极为通用的统计信息(例如空值情况)才在 pg_statistic 中有专用的列。其余统计信息都存储在槽位中。每个槽位都是一组相关的列,其内容由其中一列的代码编号来标识。更多信息见 src/include/catalog/pg_statistic.h @@ -7281,7 +7280,7 @@ SCRAM-SHA-256$<iteration count>:&l stanullfrac float4 - 列的项为空的比例 + 列中空值所占的比例 @@ -7299,8 +7298,8 @@ SCRAM-SHA-256$<iteration count>:&l stadistinct float4 - 列中非空唯一值的数目。一个大于零的值是唯一值的真正数目。 - 一个小于零的值是表中行数的乘数的负值;例如,对于一个 80% 的值为非空且每个非空值平均出现两次的列,可以表示为stadistinct = -0.4。一个0值表示唯一值的数目未知。 + 列中不同非空数据值的数量。一个大于零的值是不同值的真正数目。 + 一个小于零的值是表中行数的乘数的负值;例如,对于一个约 80% 的值为非空且每个非空值平均出现两次的列,可以表示为stadistinct = -0.4。一个0值表示不同值的数目未知。 @@ -7331,8 +7330,8 @@ SCRAM-SHA-256$<iteration count>:&l (引用 pg_collation.oid - 用于导出存储在第N槽位中的统计信息的排序规则。 - 例如,可应用排序规则列的直方图槽会显示定义数据排序顺序的排序规则。对于不可应用排序规则的数据,则为零。 + 用于生成存储在第N槽位中的统计信息的排序规则。 + 例如,支持排序规则的列的直方图槽会显示定义数据排序顺序的排序规则。对于不支持排序规则的数据,则为零。 @@ -7341,7 +7340,7 @@ SCRAM-SHA-256$<iteration count>:&l stanumbersN float4[] - 第N槽位的类型的数值类型统计, 如果该槽位不涉及数值类型则为NULL + 第N槽位中相应种类的数值统计信息;如果该槽位种类不涉及数值,则为 NULL @@ -7351,7 +7350,7 @@ SCRAM-SHA-256$<iteration count>:&l N槽位的类型的列值,如果该槽位类型不存储任何数据值则为 NULL。 - 每个数组的元素值实际上都是指定列的数据类型或者是一个相关类型(如数组元素类型), 因此,除了把这些列的类型定义成anyarray之外别无他法。 + 每个数组的元素值实际上都是指定列的数据类型或者是一个相关类型(如数组元素类型), 因此,无法把这些列的类型定义得比anyarray更具体。 @@ -7478,7 +7477,7 @@ SCRAM-SHA-256$<iteration count>:&l 统计信息对象属性中那些不是简单列引用的表达式树,以 nodeToString() 表示。 这是一个列表,每个表达式占一个元素。 - 如果所有统计信息对象属性都是简单引用,则为空。 + 如果所有统计信息对象属性都是简单引用,则为空值。 @@ -7487,8 +7486,8 @@ SCRAM-SHA-256$<iteration count>:&l - pg_statistic_ext条目在CREATE STATISTICS期间完全填充,但是随后不计算实际的统计值。 - 后来ANALYZE命令计算所需的值,并在pg_statistic_ext_data目录中填充条目。 + pg_statistic_ext条目在CREATE STATISTICS期间完全填充,但此时不会计算实际的统计值。 + 后续的ANALYZE命令计算所需的值,并在pg_statistic_ext_data目录中填充条目。 @@ -7505,14 +7504,7 @@ SCRAM-SHA-256$<iteration count>:&l - 通常,每个已分析的统计对象都有一个条目,其中stxdinherit = - false。如果表具有继承子项或分区,还会创建第二个条目,其中 - stxdinherit = true。此行表示继承树上的统计对象,即, - 您将看到的数据的统计信息 - SELECT * FROM table*, - 而stxdinherit = false行 - 表示 - SELECT * FROM ONLY table的结果。 + 通常,每个已分析的统计信息对象都有一个 stxdinherit = false 的条目。如果表有继承子表或分区,还会创建第二个 stxdinherit = true 的条目。后者表示该统计信息对象在整个继承树上的统计信息,即通过 SELECT * FROM table* 看到的数据的统计信息;而 stxdinherit = false 的行表示 SELECT * FROM ONLY table 的结果。 @@ -7582,7 +7574,7 @@ SCRAM-SHA-256$<iteration count>:&l stxdmcv pg_mcv_list - MCV(最频值)列表统计信息,序列化为pg_mcv_list类型 + MCV(高频值)列表统计信息,序列化为pg_mcv_list类型 @@ -7591,7 +7583,7 @@ SCRAM-SHA-256$<iteration count>:&l stxdexpr pg_statistic[] - 每个表达式的统计信息,序列化为pg_statistic类型的数组 + 每个表达式的统计信息,序列化为pg_statistic类型的数组。 @@ -7658,7 +7650,7 @@ SCRAM-SHA-256$<iteration count>:&l subskiplsn pg_lsn - 事务的完成 LSN,其更改将被跳过,如果是有效 LSN;否则0/0000000。 + 若为有效 LSN,则表示要跳过其更改的事务的完成 LSN;否则为 0/0000000 @@ -7706,7 +7698,7 @@ SCRAM-SHA-256$<iteration count>:&l 控制如何处理进行中事务的流式传输: f = 不允许对进行中事务进行流式传输, - t = 将进行中事务的更改溢写到磁盘,并在事务在发布者端提交且被订阅者接收后立即应用, + t = 将进行中事务的更改溢写到磁盘,并在事务在发布者端提交且被订阅者接收后一次性应用, p = 如果可用,则直接使用并行应用工作进程应用更改(如果没有工作进程,则与 t 相同) @@ -8254,7 +8246,7 @@ SCRAM-SHA-256$<iteration count>:&l tgdeferrable bool - 如果约束触发器可推迟则为真 + 如果约束触发器可延迟则为真 @@ -8263,7 +8255,7 @@ SCRAM-SHA-256$<iteration count>:&l tginitdeferred bool - 如果约束触发器初始可推迟则为真 + 如果约束触发器初始处于延迟状态则为真 @@ -8799,7 +8791,7 @@ SCRAM-SHA-256$<iteration count>:&l 目录pg_type存储有关数据类型的信息。 - 基类型和枚举类型(标量类型)使用CREATE TYPE创建,而域使用CREATE DOMAIN创建。 + 基础类型和枚举类型(标量类型)使用CREATE TYPE创建,而域使用CREATE DOMAIN创建。 数据库中的每一个表都会有一个自动创建的复合类型,用于表示表的行结构。 也可以使用CREATE TYPE AS创建复合类型。 @@ -8885,7 +8877,7 @@ SCRAM-SHA-256$<iteration count>:&l typtype可以是: - b表示一个基类型, + b表示一个基础类型, c表示一个复合类型(例如一个表的行类型), d表示一个域, e表示一个枚举类型, @@ -9091,7 +9083,7 @@ SCRAM-SHA-256$<iteration count>:&l - e (外部的): 值可以存储在一个次要 TOAST 关系中 (如果有一个关系, 参见pg_class.reltoastrelid). + e (外部的): 值可以存储在一个次要 TOAST 关系中 (如果有一个关系, 参见pg_class.reltoastrelid). @@ -9134,7 +9126,7 @@ SCRAM-SHA-256$<iteration count>:&l typtypmod int4 - 域使用typtypmod来记录被应用于它们基类型的typmod(如果基类型不使用typmod,则为-1)。如果此类型不是一个域则为-1。 + 域使用typtypmod来记录被应用于它们基础类型的typmod(如果基础类型不使用typmod,则为-1)。如果此类型不是一个域则为-1。 @@ -9154,8 +9146,8 @@ SCRAM-SHA-256$<iteration count>:&l typcollation指定此类型的排序规则。如果类型不支持排序规则,此列为零。 - 支持排序规则的基类型在这里会有一个非零值,典型值为DEFAULT_COLLATION_OID。 - 基于可应用排序规则类型的域,如果为其指定了排序规则 OID,则它的排序规则 OID 可以不同于其基类型。 + 支持排序规则的基础类型在这里会有一个非零值,典型值为DEFAULT_COLLATION_OID。 + 基于支持排序规则的类型的域,如果为其指定了排序规则 OID,则它的排序规则 OID 可以不同于其基础类型的排序规则 OID。 diff --git a/zh/19/charset.sgml b/zh/19/charset.sgml index 70d87d51..eeb75848 100644 --- a/zh/19/charset.sgml +++ b/zh/19/charset.sgml @@ -29,7 +29,7 @@ 区域设置支持 - locale + 区域设置 区域设置支持是指应用程序在字母表、排序、数字格式等 @@ -197,7 +197,7 @@ initdb --locale=sv_SE 以及 POSIX 风格正则表达式);区域设置既会影响大小写不敏感匹配,也会 影响字符类正则表达式中的字符分类 LIKE与区域设置 - regular expressions与区域设置 + 正则表达式与区域设置 @@ -565,10 +565,10 @@ SELECT 'N-45' < 'N-123' COLLATE mycollation5 AS result; 概念 - 从概念上讲,每个可排序数据类型的表达式都有一个排序规则。(内置的可排序 - 数据类型包括textvarcharchar。 - 用户定义的基本类型也可以标记为可排序,当然,建立在可排序数据类型之上的 - 也是可排序的。) + 从概念上讲,每个支持排序规则的数据类型的表达式都有一个排序规则。 + (内置的支持排序规则的数据类型包括textvarcharchar。 + 用户定义的基础类型也可以标记为支持排序规则,当然,建立在支持排序规则的数据类型之上的 + 也支持排序规则。) 如果表达式是列引用,则该表达式的排序规则就是该列定义的排序规则。如果表 达式是常量,则其排序规则就是该常量数据类型的默认排序规则。更复杂表达式 的排序规则则按下文所述,从其输入表达式的排序规则推导出来。 @@ -593,7 +593,7 @@ SELECT 'N-45' < 'N-123' COLLATE mycollation5 AS result; 对于函数或操作符调用,通过检查参数排序规则推导出的排序规则,会在运行时 - 用于执行指定操作。如果该函数或操作符调用的结果属于可排序数据类型,那么 + 用于执行指定操作。如果该函数或操作符调用的结果属于支持排序规则的数据类型,那么 在解析时它也会被用作该函数或操作符表达式的已定义排序规则,以便在外围表 达式需要知道其排序规则时使用。 @@ -675,7 +675,7 @@ SELECT a || b FROM test1; - 如果函数或操作符返回的是可排序数据类型,那么分配给该函数或操作符组合输 + 如果函数或操作符返回的是支持排序规则的数据类型,那么分配给该函数或操作符组合输 入表达式的排序规则,也被认为适用于其结果。因此,在 SELECT * FROM test1 ORDER BY a || 'foo'; @@ -721,8 +721,7 @@ SELECT * FROM test1 ORDER BY a || b COLLATE "fr_FR"; - 由icu提供的排序规则对象,对应于 ICU 库提供的具名整 - 理器。ICU 不支持将collatectype分开设 + 由icu提供的排序规则对象,对应于 ICU 库提供的具名排序器。ICU 不支持将collatectype分开设 置,因此二者总是相同的。此外,ICU 排序规则与编码无关,因此在一个数据库 中,某个给定名称的 ICU 排序规则始终只有一个。 diff --git a/zh/19/client-auth.sgml b/zh/19/client-auth.sgml index e2bdc677..7e1eeb5f 100644 --- a/zh/19/client-auth.sgml +++ b/zh/19/client-auth.sgml @@ -48,6 +48,21 @@ 请参见配置参数 。 + + 在启动时以及主服务器进程收到 SIGHUPSIGHUP 信号时,pg_hba.conf 文件会被读取。 + 如果你在运行中的系统上编辑了该文件,就需要通知 postmaster(使用 pg_ctl reload、调用 SQL 函数 pg_reload_conf(),或者使用 kill -HUP)重新读取该文件。 + + + + + 前面的说明不适用于 Microsoft Windows:在Windows上,pg_hba.conf文件中的任何更改会立即被应用到后续的新连接上。 + + + + + 系统视图pg_hba_file_rules 有助于预先测试对 pg_hba.conf 文件的修改,也可以在加载该文件没有产生预期效果时用于诊断问题。视图中 error 字段非空的行表示文件对应行存在问题。 + + pg_hba.conf 文件的一般格式是一组记录,每行一条。 空白行会被忽略,# 注释字符后面的任何文本也会被忽略。 @@ -67,7 +82,7 @@ - 一条记录可以有多种格式: + 一条记录可以有多种格式: local database user auth-method auth-options @@ -239,7 +254,7 @@ include_dir directory IP地址范围使用标准的数字表示法来指定起始地址,然后是斜杠(/)和一个CIDR掩码长度。 掩码长度表示客户端IP地址必须匹配的高位比特数。给定IP地址中右侧的比特应为零。 - IP地址、/和CIDR掩码长度之间不得有任何空格。 + IP地址、/和CIDR掩码长度之间不得有任何空白。 @@ -253,8 +268,7 @@ include_dir directory 以IPv4格式给出的条目将仅匹配IPv4连接,以IPv6格式给出的条目将仅匹配IPv6连接, - 即使所代表的地址在IPv4-in-IPv6范围内。请注意,如果系统的C库不支持IPv6地址, - 以IPv6格式给出的条目将被拒绝。 + 即使所代表的地址在IPv4-in-IPv6范围内。 @@ -276,12 +290,12 @@ include_dir directory 以点(.)开头的主机名规范匹配实际主机名的后缀。 因此,.example.com将匹配foo.example.com - (但不仅仅是example.com)。 + (但不匹配单独的example.com)。 当在pg_hba.conf中指定主机名时,应确保名称解析相对快速。 - 最好设置一个本地名称解析缓存,如nscd。 + 设置一个本地名称解析缓存可能会有帮助,如nscd。 此外,还可能希望启用配置参数log_hostname,以便在日志中看到客户端的主机名而不是 IP 地址。 @@ -293,7 +307,7 @@ include_dir directory 用户有时会想知道为什么主机名以这种看似复杂的方式处理,包括两次名称解析,其中包括对客户端IP地址的反向查找。 - 如果客户端的反向DNS条目未设置或生成了一些不良的主机名,则使用该功能会变得复杂。 + 如果客户端的反向DNS条目未设置或返回了不符合预期的主机名,则使用该功能会变得复杂。 这主要是为了效率:这样,连接尝试最多需要两次解析器查找,一次反向查找和一次正向查找。 如果某个地址存在解析器问题,那就只会成为该客户端的问题。 一个假设的替代实现只进行正向查找的情况下,在每次连接尝试期间都必须解析pg_hba.conf中提到的每个主机名。 @@ -308,7 +322,7 @@ include_dir directory 请注意,这种行为与其他流行的基于主机名的访问控制实现一致,例如 - Apache HTTP服务器和TCP包装器。 + Apache HTTP 服务器和 TCP Wrappers。 @@ -320,7 +334,7 @@ include_dir directory - 这两个字段可以用作IP地址/掩码长度 + 这两个字段可以用作IP-address/mask-length 表示法的替代方案。而不是指定掩码长度,实际掩码在一个单独的列中指定。 例如,255.0.0.0表示IPv4的CIDR掩码长度为8, 而255.255.255.255表示CIDR掩码长度为32。 @@ -379,9 +393,7 @@ include_dir directory 执行 SCRAM-SHA-256 或 MD5 认证以校验用户密码。详见 - - 对 MD5 加密密码的支持已被弃用,并将在未来版本的 PostgreSQL 中移除。关于迁移到其他密码类型的细节,请参阅 。 - + 对 MD5 加密密码的支持已弃用,并将在PostgreSQL的未来版本中移除。迁移到其他密码类型的详细信息见 @@ -504,11 +516,7 @@ include_dir directory auth-options - - - 在auth-method字段之后,可以是形如name=value的字段, - 用于指定认证方法的选项。关于哪些选项适用于哪些认证方法的详细信息见下文。 - + auth-method 字段之后,可以有一个或多个形如 name=value 的字段,用于指定认证方法的选项。下文会详细说明各认证方法有哪些可用选项。 除了下面列出的特定于方法的选项外,还有一个方法无关的认证选项 clientcert, @@ -521,7 +529,7 @@ include_dir directory - 对于任何使用客户端证书认证的记录(即使用 cert 认证方法的记录,或使用 clientcert 选项的记录),都可以通过 clientname 选项指定要匹配客户端证书凭据中的哪一部分。此选项有两个可选值。如果指定 clientname=CN,这也是默认值,则用户名将与证书的 Common Name (CN) 匹配。如果改为指定 clientname=DN,则用户名将与证书的完整 Distinguished Name (DN) 匹配。此选项通常最好与用户名映射配合使用。比较时使用的是 RFC 2253 格式的 DN。要查看以这种格式表示的客户端证书 DN,请执行 + 对于任何使用客户端证书认证的记录(即使用 cert 认证方法的记录,或使用 clientcert 选项的记录),都可以通过 clientname 选项指定要匹配客户端证书凭据中的哪一部分。此选项有两个可选值。如果指定 clientname=CN,这也是默认值,则用户名将与证书的 Common Name (CN) 匹配。如果改为指定 clientname=DN,则用户名将与证书的完整 Distinguished Name (DN) 匹配。此选项可能更适合与用户名映射配合使用。比较时使用的是 RFC 2253 格式的 DN。要查看以这种格式表示的客户端证书 DN,请执行 openssl x509 -in myclient.crt -noout -subject -nameopt RFC2253 | sed "s/^subject=//" @@ -563,25 +571,7 @@ openssl x509 -in myclient.crt -noout -subject -nameopt RFC2253 | sed "s/^subject 由 @ 构造引用的文件会被读取为名称列表,其中的名称可以用空白或逗号分隔。注释仍然用 # 引入,与 pg_hba.conf 中相同,并且允许嵌套的 @ 构造。除非 @ 后面的文件名是绝对路径,否则它会被视为相对于引用它的文件所在目录。 - - 因为每一次连接尝试都会顺序地检查pg_hba.conf记录,所以这些记录的顺序是非常关键的。通常,靠前的记录有比较严的连接匹配参数和比较弱的认证方法,而靠后的记录有比较松的匹配参数和比较强的认证方法。 例如,我们希望对本地 TCP/IP 连接使用trust认证,而对远程 TCP/IP 连接要求密码。在这种情况下为来自于 127.0.0.1 的连接指定trust认证的记录将出现在为一个更宽范围的客户端 IP 地址指定密码认证的记录前面。 - - - - 在启动以及主服务器进程收到SIGHUPSIGHUP信号时,pg_hba.conf文件会被读取。 - 如果你在活动的系统上编辑了该文件,你将需要通知 postmaster(使用pg_ctl reload,调用SQL函数pg_reload_conf(),或使用kill -HUP)使其重新读取该文件。 - - - - - - 前面的说明在Microsoft Windows上不为真:在Windows上,pg_hba.conf文件中的任何更改会立即被应用到后续的新连接上。 - - - - - 系统视图pg_hba_file_rules 有助于预先测试对 pg_hba.conf 文件的修改,也可以在加载该文件没有产生预期效果时用于诊断问题。视图中 error 字段非空的行表示文件对应行存在问题。 - + 由于每次连接尝试都会按顺序检查 pg_hba.conf 记录,因此记录的顺序很重要。通常,靠前的记录使用较严格的连接匹配条件和较弱的认证方法,靠后的记录使用较宽松的匹配条件和较强的认证方法。例如,可能希望对本地 TCP/IP 连接使用 trust 认证,而要求远程 TCP/IP 连接提供密码。此时,为来自 127.0.0.1 的连接指定 trust 认证的记录,应放在为更大范围的允许客户端 IP 地址指定密码认证的记录之前。 @@ -590,9 +580,7 @@ openssl x509 -in myclient.crt -noout -subject -nameopt RFC2253 | sed "s/^subject - - 中展示了pg_hba.conf项的一些示例。不同认证方法的详情请见下一节。 - + 展示了一些 pg_hba.conf 条目示例。有关不同认证方法的详细信息,参见下一节。 @@ -600,8 +588,8 @@ openssl x509 -in myclient.crt -noout -subject -nameopt RFC2253 | sed "s/^subject # 允许本地系统上的任何用户 -# 通过 Unix 域套接字以任意 -# 数据库用户名连接到任意数据库(本地连接的默认值)。 +# 通过 Unix 域套接字(本地连接的默认方式)以任意 +# 数据库用户名连接到任意数据库。 # # TYPE DATABASE USER ADDRESS METHOD local all all trust @@ -646,7 +634,7 @@ host postgres all 192.168.93.0/24 ident # TYPE DATABASE USER ADDRESS METHOD host postgres all 192.168.12.10/32 scram-sha-256 -# 如果用户的密码被正确提供,允许 example.com 中主机上 +# 如果用户的密码被正确提供,允许 example.com 域中主机上 # 的任意用户连接到任意数据库。 # # 为大部分用户要求SCRAM认证,但是用户'mike'是个例外, @@ -657,7 +645,7 @@ host all mike .example.com md5 host all all .example.com scram-sha-256 # 如果没有前面的 "host" 行,这三行 -# 将拒绝所有来自 192.168.54.1的连接(因为那些项将首先被匹配), +# 将拒绝所有来自 192.168.54.1的连接(因为该条目将首先被匹配), # 但是允许来自互联网其他任何地方的 # GSSAPI 加密连接。零掩码表示不会考虑主机 IP 地址中的任何位, # 因此它会匹配任意主机。未加密的 GSSAPI 连接 @@ -672,7 +660,7 @@ host all all 192.168.12.10/32 gss # 允许来自 192.168.x.x 主机的用户连接到任意数据库,如果它们能够 # 通过 ident 检查。例如,假设 ident说用户是 "bryanh" 并且他要求以 # PostgreSQL 用户 "guest1" 连接,如果在 pg_ident.conf 有一个映射 -# "omicron" 的选项说 "bryanh" 被允许以 "guest1" 连接,则该连接将被允许。 +# "omicron" 的条目表明 "bryanh" 被允许以 "guest1" 连接,则该连接将被允许。 # # TYPE DATABASE USER ADDRESS METHOD host all all 192.168.0.0/16 ident map=omicron @@ -729,6 +717,18 @@ local db1,db2,@demodbs all scram-sha-256 与 pg_hba.conf 一样,此文件中的各行也可以是 include 指令,并遵循相同的规则。 + + 在启动时以及主服务器进程收到 SIGHUPSIGHUP 信号时,pg_ident.conf 文件会被读取。 + 如果你在运行中的系统上编辑了该文件,就需要通知 postmaster(使用 pg_ctl reload、调用 SQL 函数 pg_reload_conf(),或者使用 kill -HUP)重新读取该文件。 + + + + 系统视图 + pg_ident_file_mappings + 可以帮助预先测试对pg_ident.conf文件的更改,或者在加载文件后未产生预期效果时诊断问题。 + 视图中具有非空error字段的行表示文件相应行中存在问题。 + + 对于给定的一个操作系统用户可以对应多少个数据库用户,没有任何限制,反之亦然。因此,映射中的条目应理解为该操作系统用户被允许以该数据库用户身份连接,而不是意味着两者等价。只要存在任何一条映射项把外部认证系统获得的用户名与用户请求连接时使用的数据库用户名配对起来,该连接就会被允许。值 all 还可以用作 database-username,表示只要 system-username 匹配,该用户就被允许以任意现有数据库用户身份登录。若给 all 加上引号,则它会失去该特殊含义。 @@ -757,18 +757,6 @@ mymap /^(.*)@otherdomain\.com$ guest - - 在启动时以及主服务器进程收到 SIGHUPSIGHUP 信号时,pg_ident.conf 文件会被读取。 - 如果你在运行中的系统上编辑了该文件,就需要通知 postmaster(使用 pg_ctl reload、调用 SQL 函数 pg_reload_conf(),或者使用 kill -HUP)重新读取该文件。 - - - - 系统视图 - pg_ident_file_mappings - 可以帮助预先测试对pg_ident.conf文件的更改,或者在加载文件后未产生预期效果时诊断问题。 - 视图中具有非空error字段的行表示文件相应行中存在问题。 - - 展示了一个可与 中的 pg_hba.conf 文件配合使用的 pg_ident.conf 文件。在这个示例中,任何登录到 192.168 网络中某台机器上的用户,如果其操作系统用户名不是 bryanhannrobert,都不会被授予访问权限。Unix 用户 robert 只有在尝试以 PostgreSQL 用户 bob 身份连接时才被允许访问,而不能以 robert 或其他身份连接。ann 只能以 ann 身份连接。用户 bryanh 则可以以 bryanhguest1 身份连接。 @@ -862,7 +850,7 @@ omicron bryanh guest1 - Peer 认证通常适用于本地连接,不过在某些情况下,信任认证也可能已经足够。 + 通常建议对本地连接使用 Peer 认证,不过在某些情况下,信任认证也可能已经足够。 密码认证是远程连接最容易采用的选择。 其余所有选项都需要某种外部安全基础设施(通常是认证服务器,或用于签发 SSL 证书的证书颁发机构),或者属于平台特定功能。 @@ -881,16 +869,14 @@ omicron bryanh guest1 - trust认证对于单用户工作站的本地连接是非常合适和方便的。通常它本身适用于一台多用户机器。不过,只要你利用文件系统权限限制了对服务器的 Unix 域套接字文件的访问,即使在多用户机器上,你也可以使用trust。 要做这些限制,你可以设置中描述的unix_socket_permissions配置参数(可能还有unix_socket_group)。 或者你可以设置unix_socket_directories配置参数来把 Unix 域套接字文件放在一个经过恰当限制的目录中。 + trust认证对于单用户工作站的本地连接是非常合适和方便的。通常它本身适用于一台多用户机器。不过,只要你利用文件系统权限限制了对服务器的 Unix 域套接字文件的访问,即使在多用户机器上,你也可能可以使用trust。 要做这些限制,你可以设置中描述的unix_socket_permissions配置参数(可能还有unix_socket_group)。 或者你可以设置unix_socket_directories配置参数来把 Unix 域套接字文件放在一个经过恰当限制的目录中。 设置文件系统权限只能有助于 Unix 套接字连接。本地 TCP/IP 连接不会被文件系统权限限制。因此,如果你想利用文件系统权限来控制本地安全,那么从pg_hba.conf中移除host ... 127.0.0.1 ...行,或者把它改为一个非trust认证方法。 - - 如果通过指定trustpg_hba.conf行让你信任每一个被允许连接到服务器的机器上的用户,trust认证只适合 TCP/IP 连接。为任何不是来自localhost(127.0.0.1)的 TCP/IP 连接使用trust很少是合理的。 - + 只有当你信任由 pg_hba.conf 中指定 trust 的行所允许连接的每台机器上的每个用户时,trust 认证才适合用于 TCP/IP 连接。对来自 localhost(127.0.0.1)以外的任何 TCP/IP 连接使用 trust,通常都不合理。 @@ -935,17 +921,13 @@ omicron bryanh guest1 md5 - - 方法md5使用一种自定义的安全性较低的挑战-响应机制。它能防止密码嗅探并且防止密码在服务器上以明文存储,但是无法保护攻击者想办法从服务器上窃取了密码哈希的情况。此外,现在认为MD5哈希算法对于确定攻击已经不再安全。 - + 方法md5使用一种自定义的、安全性较低的挑战-响应机制。它能防止密码嗅探,并避免在服务器上以明文存储密码;但如果攻击者设法从服务器上窃取了密码哈希,它就无法提供保护。此外,如今已不再认为 MD5 哈希算法能抵御有决心的攻击者。 为了简化从md5方法到较新的SCRAM方法的转变,如果在pg_hba.conf中指定了md5但是用户在服务器上的密码是为SCRAM(见下文)加密的,则将自动选择基于SCRAM的认证。 - - 对 MD5 加密密码的支持已被弃用,并将在未来版本的 PostgreSQL 中移除。关于迁移到其他密码类型的细节,请参阅下文。 - + 对 MD5 加密密码的支持已弃用,并将在PostgreSQL的未来版本中移除。迁移到其他密码类型的详细信息见下文。 @@ -970,7 +952,7 @@ omicron bryanh guest1 - 要把现有安装从 md5 升级到 scram-sha-256,需要先确保所有正在使用的客户端库都足够新并支持 SCRAM,然后在 postgresql.conf 中设置 password_encryption = 'scram-sha-256',要求所有用户重新设置密码,并将 pg_hba.conf 中的认证方法说明改为 scram-sha-256。 + 要把现有安装从 md5 升级到 scram-sha-256,需要先确保所有正在使用的客户端库都足够新并支持 SCRAM,然后在 postgresql.conf 中设置 password_encryption = 'scram-sha-256',要求所有用户重新设置密码,并将 pg_hba.conf 中的认证方法设置改为 scram-sha-256 @@ -1034,7 +1016,7 @@ omicron bryanh guest1 keytab 文件用 Kerberos 软件生成;详见 Kerberos 文档。 - 下面展示了用 MIT 兼容的 Kerberos 5 实现的kadmin来做这个的示例: + 下面的示例展示了如何使用 MIT Kerberos 的 kadmin 工具生成该文件: kadmin% addprinc -randkey postgres/server.my.domain.org kadmin% ktadd -k krb5.keytab postgres/server.my.domain.org @@ -1124,7 +1106,7 @@ omicron bryanh guest1 如果设为 1,则会在 include_realm 选项中使用域的 SAM 兼容名称(也称为 NetBIOS 名称)。这是默认值。如果设为 0,则会使用 Kerberos 用户主体名中的真实 realm 名称。 - 不要禁用这个选项,除非你的服务器运行在一个域账号(这包括一个域成员系统上的虚拟服务账号)下并且所有通过 SSPI 认证的所有客户端也在使用域账号,否则认证将会失败。 + 不要禁用这个选项,除非你的服务器运行在一个域账号(这包括一个域成员系统上的虚拟服务账号)下并且所有通过 SSPI 认证的客户端也在使用域账号,否则认证将会失败。 @@ -1189,7 +1171,7 @@ omicron bryanh guest1 map - 允许在系统用户和数据库用户名称之间进行映射。详细信息请参见。 + 允许在系统用户名和数据库用户名之间进行映射。详见 @@ -1212,7 +1194,7 @@ omicron bryanh guest1
RFC 1413 - 标识协议的本意不是作为一种认证或访问控制协议。 + 标识协议的本意不是作为一种授权或访问控制协议。
@@ -1241,7 +1223,7 @@ omicron bryanh guest1 map - 允许在系统用户和数据库用户名称之间进行映射。详细信息请参见。 + 允许在系统用户名和数据库用户名之间进行映射。详见 @@ -1297,8 +1279,7 @@ omicron bryanh guest1 ldapscheme - 设置为ldaps以使用LDAPS。这是一种非标准的使用LDAP - 进行SSL加密的方式,受一些LDAP服务器实现支持。另请参阅ldaptls + 设置为ldaps以使用LDAPS。这是一种非标准的通过 SSL 使用 LDAP 的方式,受一些LDAP服务器实现支持。另请参阅ldaptls 选项作为替代。 @@ -1386,21 +1367,23 @@ omicron bryanh guest1 +
+ + + 以下选项提供了另一种写法,可以用更紧凑、标准的形式表示上述部分 LDAP 选项: ldapurl 一个RFC 4516 - LDAP URL。这是以更紧凑和标准形式编写其他LDAP选项的替代方式。格式为 + LDAP URL。格式为 ldap[s]://host[:port]/basedn[?[attribute][?[scope][?[filter]]]] scope必须是baseonesub中的一个,通常是最后一个。(默认为base,在此应用中通常无用。)attribute可以指定单个属性,此时将用作ldapsearchattribute的值。如果attribute为空,则filter可用作ldapsearchfilter的值。 - - URL方案ldaps选择了通过SSL进行LDAP连接的LDAPS方法,相当于使用ldapscheme=ldaps。要使用StartTLS操作进行加密LDAP连接,请使用正常的URL方案ldap并另外指定ldaptls选项。 - + URL 方案 ldaps 会选择 LDAPS 方法,通过 SSL 建立 LDAP 连接,等同于使用 ldapscheme=ldaps。要通过 StartTLS 操作使用加密的 LDAP 连接,请使用普通的 URL 方案 ldap,并在 ldapurl 之外指定 ldaptls 选项。 对于非匿名绑定,必须将ldapbinddnldapbindpasswd指定为单独的选项。 @@ -1411,8 +1394,7 @@ ldap[s]://host[:port]/ - - + 将简单绑定选项与搜索+绑定选项混用是错误的。若要在简单绑定模式下使用 ldapurl,该 URL 中不能包含 basedn 或查询元素。 @@ -1703,7 +1685,7 @@ host ... ldap ldapbasedn="dc=example,dc=net" scope - 一个以空格分隔的 OAuth scope 列表,服务器需要借此既能授权客户端,又能认证用户。合适的取值由授权服务器以及所使用的 OAuth 验证模块决定(关于验证器的更多信息,见 )。此参数为必需项。 + 一个以空格分隔的 OAuth 作用域(scope)列表,服务器需要借此既能授权客户端,又能认证用户。合适的取值由授权服务器以及所使用的 OAuth 验证模块决定(关于验证器的更多信息,见 )。此参数为必需项。 diff --git a/zh/19/config.sgml b/zh/19/config.sgml index 4583e13a..0b147c74 100644 --- a/zh/19/config.sgml +++ b/zh/19/config.sgml @@ -53,7 +53,7 @@ 字符串: 通常值被包括在单引号内,值内部的任何单引号都需要被双写。不过,如果值是一个简单数字或者 标识符,引号通常可以被省略。 - (与 SQL 关键字匹配的值需要在某些上下文中引用。) + (与 SQL 关键字匹配的值在某些上下文中需要加引号。) @@ -72,7 +72,7 @@ 带单位的数字: 一些数字参数具有隐含单位,因为它们描述的是内存或时间量。单位可能是字节、千字节、块 - (通常为 8 千字节)、毫秒、秒或分钟。这类设置若给出不带修饰的数字值,就会使用该设置的默认单位, + (通常为 8 千字节)、毫秒、秒或分钟。这类设置若给出不带单位的数字值,就会使用该设置的默认单位, 可以通过 pg_settings.unit 了解该默认单位。为了方便, 也可以显式指定单位,例如把时间值写成 '120 ms',系统会将其转换为该参数的实际单位。 注意,要使用这一特性,值必须写成字符串(带引号)。单位名称区分大小写,并且数字值与单位之间可以有空白。 @@ -154,7 +154,12 @@ shared_buffers = 128MB 除了 postgresql.conf 之外,PostgreSQL - 还使用另外三个手工编辑的配置文件,它们控制客户端认证(其使用在中讨论)以及 SSL 主机配置。默认情况下,所有四个配置文件都存放在数据库集簇的数据目录中。本节描述的参数允许配置文件放在别的地方(这么做可以简化管理,特别是如果配置文件被独立放置,可以很容易保证它得到恰当的备份)。 + 数据目录还包含文件 + postgresql.auto.confpostgresql.auto.conf, + 它与 postgresql.conf 采用相同的格式,但设计为自动编辑而非手工编辑。 + 这个文件保存了通过ALTER SYSTEM命令提供的设置。 + 每当读取 postgresql.conf 时,也会读取该文件,并以同样的方式使其中设置生效。 + postgresql.auto.conf 中的设置会覆盖 postgresql.conf 中的设置。 @@ -187,14 +192,14 @@ shared_buffers = 128MB - ALTER DATABASE命令允许针对一个数据库覆盖其全局设置。 + ALTER DATABASE命令允许针对各个数据库覆盖全局设置。 - ALTER ROLE命令允许用用户指定的值来覆盖全局设置和数据库设置。 + ALTER ROLE命令允许用针对特定用户设置的值来覆盖全局设置和数据库设置。 @@ -269,7 +274,7 @@ UPDATE pg_settings SET setting = reset_val WHERE name = 'configuration_parameter 通过 Shell 影响参数 - 除了在数据库或者角色层面上设置全局默认值或者进行覆盖,你还可以通过 shell 工具把设置 + 除了设置全局默认值或在数据库、角色级别覆盖默认值之外,你还可以通过 shell 工具把设置 传递给PostgreSQL。服务器和libpq 客户端库都能通过 shell 接受参数值。 @@ -278,8 +283,7 @@ UPDATE pg_settings SET setting = reset_val WHERE name = 'configuration_parameter - 在服务器启动期间,可以通过命令行参数把参数设置传递给 - postgres命令。例如: + 在服务器启动期间,可以通过 命令行参数或其等效形式 ,把参数设置传递给 postgres 命令。例如: postgres -c log_connections=all --log-destination='syslog' @@ -294,7 +298,7 @@ postgres -c log_connections=all --log-destination='syslog' 当通过libpq启动一个客户端会话时,可以使用PGOPTIONS 环境变量指定参数设置。这种方式建立的设置构成了会话生存期间的默认值,但是不会影响 其他的会话。由于历史原因,PGOPTIONS的格式和启动 - postgres命令时用到的相似,特别是标志必须被指定。 + postgres命令时用到的相似,具体来说,必须指定 ,或在参数名称前加上 --。 例如: env PGOPTIONS="-c geqo=off --statement-timeout=5min" psql @@ -341,7 +345,7 @@ include 'filename' 还有一个 include_if_exists 指令,其行为与 include 相同, 但在被引用文件不存在或无法读取时有所不同。普通的 include 会将其视为错误, - 而 include_if_exists 只会记录一条消息并继续处理引用配置文件。 + 而 include_if_exists 只会记录一条消息并继续处理引用它的配置文件。 @@ -352,21 +356,21 @@ include 'filename' postgresql.conf 文件也可以包含 include_dir 指令, 用来指定一个应被包含的配置文件目录。其用法如下: - include_dir 'directory' - - 非绝对目录名会被解释为相对于引用配置文件所在目录的路径。在指定目录中, +include_dir 'directory' + + 非绝对目录名会被解释为相对于引用它的配置文件所在目录的路径。在指定目录中, 只有名称以 .conf 结尾的非目录文件才会被包含。以 . 开头的文件名也会被忽略,以避免在某些平台上误处理隐藏文件。包含目录中的多个文件会按文件名顺序处理 (依据 C 区域规则排序,即数字在字母之前,大写字母在小写字母之前)。 - 包括文件或目录可以被用来在逻辑上分隔数据库配置的各个部分,而不是用一个很大的postgresql.conf文件。 + 包含文件或目录可以用来在逻辑上分隔数据库配置的各个部分,而不是用一个很大的postgresql.conf文件。 考虑一个有两台数据库服务器的公司,每一个都有不同的内存量。 - 很可能配置的元素都会被共享,例如用于日志的参数。但是两者关于内存的参数将会不同。 + 两者很可能会共享部分配置,例如日志设置。但是两者关于内存的参数将会不同。 并且还可能会有服务器相关的自定义。 一种管理这类情况的方法是将你的站点的自定义配置修改分成三个文件。 - 你可以把下面的内容加入到你的postgresql.conf文件末尾来包括它们: + 你可以把下面的内容加入到你的postgresql.conf文件末尾来包含它们: include 'shared.conf' include 'memory.conf' @@ -427,7 +431,7 @@ include_dir 'conf.d' - 指定用于数据存储的目录。这个选项只能在服务器启动时设置。 + 指定用于数据存储的目录。这个参数只能在服务器启动时设置。 @@ -478,16 +482,14 @@ include_dir 'conf.d' - hosts_file (string) hosts_file配置参数 - - 指定用于基于主机的 SSL 配置的配置文件(通常叫pg_hosts.conf)。这个参数只能在服务器启动时设置。另见。 + 指定基于主机的 SSL 配置文件(通常称为 pg_hosts.conf)。此参数只能在服务器启动时设置。另请参见 @@ -502,7 +504,7 @@ include_dir 'conf.d' - 指定可被服务器创建的用于管理程序的额外进程 ID(PID)文件。这个参数只能在服务器启动的时候设置。 + 指定服务器应创建的额外进程 ID(PID)文件的名称,供服务器管理程序使用。这个参数只能在服务器启动的时候设置。 @@ -513,15 +515,15 @@ include_dir 'conf.d' - 如果你想把配置文件放在别的地方而不是数据目录中,那么postgres 命令行选项或者环境变量PGDATA必须指向包含配置文件的目录,并且postgresql.conf中(或者命令行上)的data_directory参数必须显示数据目录实际存放的地方。请注意,data_directory将覆盖PGDATA指定的数据目录位置,但是不覆盖配置文件的位置。 + 如果你想把配置文件放在别的地方而不是数据目录中,那么postgres 命令行选项或者环境变量PGDATA必须指向包含配置文件的目录,并且postgresql.conf中(或者命令行上)的data_directory参数必须设置为数据目录的实际位置。请注意,data_directory将覆盖PGDATA指定的数据目录位置,但是不覆盖配置文件的位置。 - 如果你愿意,可以使用选项config_filehba_fileident_file和/或hosts_file单独指定配置文件名称和位置。config_file只能在postgres命令行上指定,但是其他文件可以在主配置文件中设置。如果所有四个参数外加data_directory被显式地设置,则不必指定PGDATA。 + 如果你愿意,可以使用选项config_filehba_fileident_file和/或hosts_file单独指定配置文件名称和位置。config_file只能在postgres命令行上指定,但是其他参数可以在主配置文件中设置。如果所有四个参数外加data_directory被显式地设置,则不必指定PGDATA - 在设置任何这些参数时,相对路径将被解释为相对于postgres启动路径的路径。 + 在设置任何这些参数时,相对路径将被解释为相对于启动 postgres 时所在目录的路径。 @@ -545,7 +547,7 @@ include_dir 'conf.d' - 指定服务器用于监听来自客户端应用程序的连接的TCP/IP地址(指服务器网卡IP地址)。 + 指定服务器用于监听来自客户端应用程序的连接的TCP/IP地址。 该值采用逗号分隔的主机名和/或数字IP地址的形式。特殊条目*对应于所有可用的IP接口。 条目0.0.0.0允许监听所有IPv4地址,::允许监听所有IPv6地址。 如果列表为空,则服务器不会在任何IP接口上监听,此时只能使用Unix域套接字进行连接。 @@ -568,11 +570,11 @@ include_dir 'conf.d' - - - 服务器监听的 TCP 端口;默认是 5432 。请注意服务器会同一个端口号监听所有的 IP 地址。这个参数只能在服务器启动时设置。 - - + + 服务器监听的 TCP 端口,默认是 5432。请注意,服务器监听的所有 IP 地址都使用同一个端口号。 + 此参数只能在服务器启动时设置。 + + @@ -595,7 +597,8 @@ include_dir 'conf.d' - 运行备库时,必须将此参数设置为大于或等于主库上的值。否则,备库上将不允许查询。 + 当运行一个备库时,你必须设置这个参数等于或大于主库上的参数。 + 否则,备库上将不允许查询。 @@ -608,20 +611,10 @@ include_dir 'conf.d' - 确定为拥有 - pg_use_reserved_connections - 角色的连接保留多少个连接。当空闲连接槽的数量大于 - , - 但小于或等于superuser_reserved_connections与 - reserved_connections之和时,新连接将只接受超级用户以及拥有 - pg_use_reserved_connections权限的角色。如果可用连接槽的数量等于或少于 - superuser_reserved_connections,则新连接只接受超级用户。 + 确定为具有 pg_use_reserved_connections 角色权限的角色保留多少个连接。当空闲连接槽的数量大于 ,但小于或等于 superuser_reserved_connectionsreserved_connections 之和时,新连接将只接受超级用户以及具有 pg_use_reserved_connections 角色权限的角色。如果可用连接槽的数量小于或等于 superuser_reserved_connections,则新连接只接受超级用户。 - 默认值为零连接。该值必须小于 - max_connections减去 - superuser_reserved_connections。 - 此参数只能在服务器启动时设置。 + 默认值为零个连接。该值必须小于 max_connections 减去 superuser_reserved_connections。此参数只能在服务器启动时设置。 @@ -639,7 +632,7 @@ include_dir 'conf.d' 决定为 PostgreSQL 超级用户连接保留多少个连接。 - 同时活跃的连接数最多始终只能达到 。当活跃并发连接数达到 + 同时活跃的连接数最多始终只能达到 。当活跃并发连接数至少达到 max_connections 减去 superuser_reserved_connections 时, 新连接将只接受超级用户。由该参数保留的连接槽是在 保留的连接槽耗尽之后,用于紧急情况的最后储备。 @@ -717,31 +710,23 @@ include_dir 'conf.d' - - 设置 Unix 域套接字的访问权限。Unix 域套接字使用普通的 Unix 文件系统权限集。这个参数值应该是数字的形式,也就是系统调用chmodumask接受的 形式(如果使用自定义的八进制格式,数字必须以一个0(零)开头)。 + 设置 Unix 域套接字的访问权限。Unix 域套接字使用通常的 Unix 文件系统权限集。参数值应是以 chmodumask 系统调用所接受格式指定的数字权限模式。(要使用惯用的八进制格式,数字必须以 0(零)开头。) - - 默认的权限是0777,意思是任何人都可以连接。合理的候选是0770(只有用户和同组的人可以访问, 又见unix_socket_group)和0700(只有用户自己可以访问)(请注意,对于 Unix 域套接字,只有写权限有麻烦,因此没有对读取和执行权限的设置和收回)。 + 默认权限是 0777,表示任何人都可以连接。合理的其他取值包括 0770(仅属主和所属组,另见 unix_socket_group)和 0700(仅属主)。(注意,对 Unix 域套接字而言,只有写权限起作用,因此设置或撤销读权限和执行权限没有意义。) - - 这个访问控制机制与中的用户认证没有关系。 + 此访问控制机制独立于 中描述的机制。 - - 这个参数只能在服务器启动时设置。 + 此参数只能在服务器启动时设置。 - - 这个参数与完全忽略套接字权限的系统无关,尤其是自版本10以上的Solaris。 - 在那些系统上,可以通过把unix_socket_directories指向一个把搜索权限 - 限制给指定用户的目录来实现相似的效果。 + 此参数对完全忽略套接字权限的系统无效,尤其是 Solaris(截至 Solaris 10)。在这些系统上,可以将 unix_socket_directories 指向一个仅向目标用户授予搜索权限的目录,以达到类似效果。 - - 抽象命名空间中的套接字没有文件权限,所以这种情况下这个设置也会被忽略。 + 抽象命名空间中的套接字没有文件权限,因此这种情况下也会忽略此设置。 @@ -754,10 +739,8 @@ include_dir 'conf.d' - - 通过Bonjour广告服务器的存在。默认值是关闭。 - 这个参数只能在服务器启动时设置。 + 启用通过 Bonjour 通告服务器存在的功能。默认值为关闭。此参数只能在服务器启动时设置。 @@ -770,11 +753,11 @@ include_dir 'conf.d' - - - 指定Bonjour服务名称。空字符串''(默认值)表示使用计算机名。 如果编译时没有打开Bonjour支持那么将忽略这个参数。这个参数只能在服务器启动时设置。 - - + + 指定 Bonjour 服务名。空字符串 ''(默认值)表示使用计算机名。 + 如果编译时未启用 Bonjour 支持,则此参数会被忽略。此参数只能在服务器启动时设置。 + + @@ -867,109 +850,23 @@ include_dir 'conf.d' - - 在运行查询时,设置检查客户端是否保持连接的可选检查的时间间隔。 - 这个检查通过轮询套接字来执行,并且在内核报告该连接关闭时,允许长时间运行的查询可以尽快中止。 + 设置查询执行期间可选的客户端连接检查的时间间隔,用于检查客户端是否仍然连接。检查通过轮询套接字执行;如果内核报告连接已经关闭,就可以更早中止长时间运行的查询。 - - 这个选项依赖于Linux、macOS、illumos和BSD家族操作系统暴露的内核事件, - 目前在其他系统上不可用。 + 此选项依赖 Linux、macOS、illumos 和 BSD 系列操作系统提供的内核事件,目前在其他系统上不可用。 - - 如果指定的值没有单位,则以毫秒为单位。 - 默认值为0,代表禁用连接检查。 - 没有连接检查,服务器将只在与套接字的下一次交互时检测连接的丢失,当它等待、接收或发送数据时。 + 如果指定值时没有单位,则以毫秒计。默认值为 0,表示禁用连接检查。如果不进行连接检查,服务器只有在下一次与套接字交互(等待、接收或发送数据)时,才会检测到连接丢失。 - - 为了让内核本身能够在包括网络故障在内的所有场景中,在已知的时间范围内可靠地检测丢失的TCP连接,它可能还需要调整操作系统的TCP保持连接设置, - 或者PostgreSQL, 设置。 + 要让内核本身在包括网络故障在内的所有场景中,能够在确定的时间范围内可靠地检测到 TCP 连接丢失,可能还需要调整操作系统的 TCP keepalive 设置,或 PostgreSQL 设置。 - - file_copy_method (enum) - - file_copy_method配置参数 - - - - - 指定用于复制文件的方法。可能的值包括 COPY(默认)和 - CLONE(如果操作系统支持)。 - - - 此参数会影响: - - - - - CREATE DATABASE ... STRATEGY=FILE_COPY - - - - - ALTER DATABASE ... SET TABLESPACE ... - - - - - CLONE 使用 copy_file_range()(Linux、FreeBSD) - 或 copyfile(macOS)系统调用,让内核有机会共享磁盘块, - 或把工作下推到某些文件系统的较低层。 - - - - - file_extend_method (enum) - - file_extend_method配置参数 - - - - - 指定在诸如COPY这类批量操作期间扩展数据文件时所使用的方法。 - 默认会根据操作系统选择第一个可用选项: - - - - posix_fallocate(Unix)使用标准 POSIX 接口分配磁盘空间,但某些系统缺少该接口。 - 如果接口存在但底层文件系统不支持,本选项会静默回退到write_zeros。 - 已知当前版本的 BTRFS 在使用该选项时会禁用压缩。 - 在提供该函数的系统上,这是默认值。 - - - - - write_zeros通过写出零字节块来扩展文件。 - 在不提供posix_fallocate函数的系统上,这是默认值。 - - - - 当数据文件扩展的块数不超过 8 个时,总是使用write_zeros方法。 - - - - - max_notify_queue_pages (integer) - - max_notify_queue_pages配置参数 - - - - - 指定 / 队列可分配页面的最大数量。 - 默认值是 1048576。对于 8 KB 页面,这允许最多消耗 8 GB 的磁盘空间。 - 此参数只能在服务器启动时设置。 - - - @@ -1020,10 +917,7 @@ include_dir 'conf.d' 详情参见 - - 对 MD5 加密密码的支持已被弃用,并将在未来的 PostgreSQL 版本中移除。 - 关于迁移到其他密码类型的细节,请参见 。 - + 对 MD5 加密密码的支持已弃用,并将在PostgreSQL的未来版本中移除。迁移到其他密码类型的详细信息见 @@ -1092,7 +986,7 @@ include_dir 'conf.d' 设置服务器的Kerberos密钥文件的位置。 - 默认为FILE:/usr/local/pgsql/etc/krb5.keytab(其中目录部分是在构建时由sysconfdir指定的;用pg_config --sysconfdir来决定)。 + 默认为FILE:/usr/local/pgsql/etc/krb5.keytab(其中目录部分是在构建时由sysconfdir指定的;可用pg_config --sysconfdir来确定该目录)。 如果这个参数被设为空字符串,它将被忽略,并且系统依赖的默认值被应用。 这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 详情请参考。 @@ -1123,10 +1017,7 @@ include_dir 'conf.d' - 设置是否应接受来自客户端的 GSSAPI 代理。默认值为off, - 这表示不会接受客户端的凭据。将其改为on会使服务器接受 - 客户端代理给它的凭据。此参数只能在postgresql.conf文件 - 或服务器命令行中设置。 + 设置是否接受客户端的 GSSAPI 委派。默认值为 off,表示不会接受客户端的凭证。将其改为 on 会使服务器接受客户端委派给它的凭证。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 @@ -1156,14 +1047,10 @@ include_dir 'conf.d' - SSL - 查看以获取有关设置SSL的更多信息。 - 用TLS协议控制传输加密的配置参数被命名为ssl,出于历史原因, - 尽管对SSL协议的支持已被弃用。 - 在这种情况下,SSLTLS可互换使用。 + 关于 SSL 的设置,参见 。虽然对 SSL 协议的支持已被弃用,但由于历史原因,用于控制 TLS 协议传输加密的配置参数仍以 ssl 命名。在此语境中,SSLTLS 这两个术语可互换使用。 @@ -1247,13 +1134,13 @@ include_dir 'conf.d' 这个目录需要用OpenSSL 命令 openssl rehashc_rehash来准备。 - 详情参阅相应文档 + 详情参阅相应文档。 - 当使用此设置时,在连接时会按需加载指定目录下的CRLs。 - 新的CRLs可以添加到该目录中,并可以立即使用。 - 这与不同,那个会导致文件中的CRL在服务器启动时间或重新加载配置时加载。 + 当使用此设置时,在连接时会按需加载指定目录下的CRL。 + 新的CRL可以添加到该目录中,并可以立即使用。 + 这与不同,那个会导致文件中的CRL在服务器启动时或重新加载配置时加载。 两个设置可以一起使用。 @@ -1357,7 +1244,7 @@ include_dir 'conf.d' - 可用的密码组细节可能会随着OpenSSL 版本变化。 + 可用的密码套件细节可能会随着OpenSSL 版本变化。 可使用命令 openssl ciphers -v 'HIGH:MEDIUM:+3DES:!aNULL'来查看当前安装的OpenSSL版本的实际细节。 注意这个列表是根据服务器密钥类型在运行时过滤过的。 @@ -1372,15 +1259,11 @@ include_dir 'conf.d' - - 指定是否使用服务器的 SSL 密码首选项,而不是用客户端的。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 - 默认值是 on。 + 指定是否使用服务器的 SSL 密码套件优先顺序,而非客户端的优先顺序。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。默认值为 on - - 老的PostgreSQL版本没有这个设置并且总是使用客户端的首选项。这个设置主要用于与那些版本 - 的向后兼容性。使用服务器的首选项通常会更好,因为服务器更可能会被合适地配置。 + PostgreSQL 9.4 之前的版本没有此设置,始终采用客户端的优先顺序。此设置主要用于与这些旧版本保持向后兼容。采用服务器的优先顺序通常更好,因为服务器更可能得到适当配置。 @@ -1412,7 +1295,7 @@ include_dir 'conf.d' prime256v1 (NIST P-256)、 secp384r1 (NIST P-384)、 secp521r1 (NIST P-521)。 - openssl ecparam -list_curves 命令可以显示可用曲线的完整列表, + openssl ecparam -list_curves 命令可以显示可用组的不完整列表, 但并非所有曲线都可用于 TLS,而且许多受支持的组名和别名并未列出。 @@ -1431,19 +1314,14 @@ include_dir 'conf.d' - - 设置要使用的最小SSL/TLS协议版本。当前的可用版本包括: TLSv1, TLSv1.1, TLSv1.2, TLSv1.3. - 旧版本的 OpenSSL 库不支持所有值;如果选择了不支持的设置将会引发错误。 - TLS 1.0之前的协议版本,也就是SSL 版本 2 and 3,总是禁用的。 + 设置要使用的最低 SSL/TLS 协议版本。当前有效值为:TLSv1TLSv1.1TLSv1.2TLSv1.3。较旧版本的 OpenSSL 库不支持所有值;如果选择了不支持的设置,就会报错。TLS 1.0 之前的协议版本,即 SSL 2 和 3,始终被禁用。 - - 默认为TLSv1.2, 在本文撰写时的行业最佳实践。 + 默认值为 TLSv1.2,符合本文撰写时的行业最佳实践。 - - 这个参数只能在postgresql.conf文件中或通过服务器命令行进行设置。 + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 @@ -1456,15 +1334,11 @@ include_dir 'conf.d' - - 设定要使用的最大SSL/TLS协议版本。 - 有效的版本为 , 添加一个空字符串,允许任何协议版本。 - 默认为允许任何版本。设置最大协议版本主要用于测试,或者某个组件在与较新的协议配合工作时出现了问题。 + 设置要使用的最高 SSL/TLS 协议版本。有效值与 相同,此外还可设为空字符串,表示允许任意协议版本。默认允许任意版本。设置最高协议版本主要用于测试,或处理某些组件无法正常配合更新协议工作的问题。 - - 这个参数只能在postgresql.conf文件中或通过服务器命令行进行设置。 + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 @@ -1477,13 +1351,11 @@ include_dir 'conf.d' - - 指定含有用于SSL密码的所谓临时DH家族的Diffie-Hellman参数的文件名。默认值为空,这种情况下将使用内置的默认DH参数。使用自定义的DH参数可以降低攻击者破解众所周知的内置DH参数的风险。可以用命令openssl dhparam -out dhparams.pem 2048创建自己的DH参数文件。 + 指定包含 Diffie-Hellman 参数的文件名,这些参数用于所谓临时 DH 系列的 SSL 密码套件。默认值为空,此时使用编译时内置的默认 DH 参数。如果攻击者破解了众所周知的内置 DH 参数,使用自定义 DH 参数可以降低由此带来的风险。可以用命令 openssl dhparam -out dhparams.pem 2048 创建自己的 DH 参数文件。 - - 这个参数只能在postgresql.conf文件中或通过服务器命令行进行设置。 + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 @@ -1496,21 +1368,17 @@ include_dir 'conf.d' - - 设置当需要一个密码(例如一个私钥)来解密SSL文件时会调用的一个外部命令。默认情况下,这个参数为空,表示使用内置的提示机制。 + 设置获取用于解密私钥等 SSL 文件的口令时要调用的外部命令。默认值为空,表示使用内置的提示机制。 - - 该命令必须将密码打印到标准输出并且以代码0退出。在该参数值中,%p被替换为一个提示字符串(要得到文字%,应该写成%%)。注意该提示字符串将可能含有空格,因此要确保加上适当的引号。如果输出的末尾有单一的新行,它会被剥离掉。 + 该命令必须将口令输出到标准输出,并以退出码 0 结束。参数值中的 %p 会被替换为提示字符串。(要表示字面值 %,应写成 %%。)提示字符串可能包含空白,因此务必正确加引号。如果输出末尾有一个换行符,会将其去掉。 - - 该命令实际上并不一定要提示用户输入一个密码。它可以从文件中读取密码、从钥匙链得到密码等等。确保选中的机制足够安全是用户的责任。 + 该命令不一定要提示用户输入口令,也可以从文件读取口令、从钥匙链获取口令等。用户应自行确保所选机制足够安全。 - - 这个参数只能在postgresql.conf文件中或通过服务器命令行进行设置。 + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 @@ -1523,20 +1391,14 @@ include_dir 'conf.d' - - 这个参数决定在配置重载期间如果一个密钥文件需要密码时,是否也调用ssl_passphrase_command设置的密码命令。 - 如果这个参数为off(默认),那么在重载期间将忽略ssl_passphrase_command,如果在此期间需要密码则SSL配置将不会被重载。 - 对于要求一个TTY(当服务器正在运行时可能是不可用的)来进行提示的命令,这种设置是合适的。 - 例如,如果密码是从一个文件中得到的,将这个参数设置为on可能是合适的。 + 此参数决定:配置重载期间,如果密钥文件需要口令,是否也调用 ssl_passphrase_command 设置的口令命令。如果此参数为 off(默认值),则重载时会忽略 ssl_passphrase_command,如果需要口令,就不会重载 SSL 配置。此设置适合需要通过 TTY 提示用户的命令,因为服务器运行期间可能无法使用 TTY。例如,如果从文件中获取口令,则适合将此参数设为 on。 - 在Windows上运行时,必须将该参数设为on, - 因为该平台采用不同的进程模型,所有连接都会触发配置重载。 + 在 Windows 上运行时,必须将此参数设为 on,因为该平台的进程模型不同,每个连接都会执行配置重载。 - - 这个参数只能在postgresql.conf文件中或通过服务器命令行进行设置。 + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 @@ -1577,22 +1439,15 @@ include_dir 'conf.d' - - 设置数据库服务器将使用的共享内存缓冲区量。默认通常是 128 兆字节(128MB),但是如果你的内核设置不支持(在initdb时决定),那么可以会更少。 - 这个设置必须至少为 128 千字节。不过为了更好的性能,通常会使用明显高于最小值的设置。 - 如果指定值时没有单位,则以块为单位,即BLCKSZ字节,通常为8kB.(BLCKSZ 的非默认值改变最小值。) - 此参数只能在服务器启动时设置。 + 设置数据库服务器用于共享内存缓冲区的内存量。默认值通常为 128 兆字节(128MB),但如果内核设置不支持,则可能更小(在 initdb 期间确定)。此设置必须至少为 128 千字节。不过,要获得良好性能,通常需要远高于该最小值的设置。如果指定值时没有单位,则以块为单位,即 BLCKSZ 字节,通常为 8kB。(BLCKSZ 的非默认值会改变该最小值。)此参数只能在服务器启动时设置。 - - 如果有一个专用的 1GB 或更多内存的数据库服务器,一个合理的shared_buffers开始值是系统内存的 25%。即使更大的shared_buffers有效,也会造成一些工作负载, 但因为PostgreSQL同样依赖操作系统的高速缓冲区,将shared_buffers设置为超过 40% 的RAM不太可能比一个小点值工作得更好。为了能把对写大量新的或改变的数据的处理分布在一个较长的时间段内,shared_buffers更大的设置通常要求对max_wal_size也做相应增加。 + 如果专用数据库服务器具有 1GB 或更多内存,shared_buffers 的合理初始值是系统内存的 25%。对于某些工作负载,将 shared_buffers 设得更大也有效,但由于 PostgreSQL 同时依赖操作系统缓存,将超过 40% 的内存分配给 shared_buffers 不太可能比更小的值效果更好。将 shared_buffers 设得更大时,通常还需要相应增加 max_wal_size,以便将大量新数据或已修改数据的写入过程分散到更长的时间内。 - - 如果系统内存小于 1GB,一个较小的 RAM 百分数是合适的,这样可以为操作系统留下足够的空间。 + 对于内存少于 1GB 的系统,适合使用更小的内存比例,以便为操作系统留出足够空间。 - @@ -1606,7 +1461,7 @@ include_dir 'conf.d' - 控制是否为主共享内存区域请求巨型页。有效值是try(默认)、on以及off。该参数只能在服务器启动时设置。如果huge_pages被设置为try,则服务器将尝试请求巨型页,但是如果失败会退回到默认的方式。如果为on,请求巨型页失败将使得服务器无法启动。如果为off,则不会请求巨型页。 + 控制是否为主共享内存区域请求巨型页。有效值是try(默认)、on以及off。该参数只能在服务器启动时设置。如果huge_pages被设置为try,则服务器将尝试请求巨型页,但是如果失败会退回到默认的方式。如果为on,请求巨型页失败将使得服务器无法启动。如果为off,则不会请求巨型页。实际是否使用巨型页由服务器变量 表示。 @@ -1615,19 +1470,19 @@ include_dir 'conf.d' - 巨型页面的使用会导致更小的页面表以及花费在内存管理上的 CPU 时间更少,从而提高性能。更多有关Linux上使用巨型页面的细节请见。 + 巨型页的使用会导致更小的页表以及花费在内存管理上的 CPU 时间更少,从而提高性能。更多有关Linux上使用巨型页的细节请见 巨型页在Windows上被称为大页面。 要使用大页面,需要为运行PostgreSQL的Windows用户账号分配在内存中锁定页面的用户权限。 可以使用Windows的组策略工具(gpedit.msc)来分配用户权限在内存中锁定页面。 - 为了在命令窗口以单进程(而不是Windows服务)的方式启动数据库服务器,命令窗口必须以管理员身份运行或者禁用用户访问控制(UAC)。 + 为了在命令窗口以独立进程(而不是Windows服务)的方式启动数据库服务器,命令窗口必须以管理员身份运行或者禁用用户访问控制(UAC)。 当UAC被启用时,普通的命令窗口会在启动时收回用户权限在内存中锁定页面 - 注意这种设置仅影响主共享内存区域。Linux、FreeBSD以及Illumos之类的操作系统也能为普通内存分配自动使用巨型页(也被称为超级页或者页面),而不需要来自PostgreSQL的显式请求。在Linux上,这被称为transparent huge pagestransparent huge pages(THP,透明巨型页)。已知这种特性对某些Linux版本上的某些用户会导致PostgreSQL的性能退化,因此当前并不鼓励使用它(与huge_pages的显式使用不同)。 + 注意这种设置仅影响主共享内存区域。Linux、FreeBSD以及Illumos之类的操作系统也能为普通内存分配自动使用巨型页(也被称为超级页或者页面),而不需要来自PostgreSQL的显式请求。在Linux上,这被称为transparent huge pages透明巨型页(THP,透明巨型页)。已知这种特性对某些Linux版本上的某些用户会导致PostgreSQL的性能退化,因此当前并不鼓励使用它(与huge_pages的显式使用不同)。 @@ -1640,24 +1495,14 @@ include_dir 'conf.d' - - 控制巨型页的大小,当他们通过时。 - 默认为零 (0)。 - 当设置为0时,将使用系统默认的巨型页大小。 - 这个参数只能在服务器启动时设置。 + 控制通过 启用巨型页时所使用的页大小。默认值为零(0)。设置为 0 时,使用系统默认的巨型页大小。此参数只能在服务器启动时设置。 - - 一些现代64位服务器体系结构上常用的有效页尺寸包括: - 2MB1GB (Intel and AMD), - 16MB16GB (IBM POWER), - 还有 64kB, 2MB,32MB1GB (ARM). - 关于使用和支持的更多信息,参见。 + 现代 64 位服务器体系结构上常见的页大小包括:2MB1GB(Intel 和 AMD),16MB16GB(IBM POWER),以及 64kB2MB32MB1GB(ARM)。关于使用和支持的更多信息,参见 - - 非默认设置当前仅在Linux上支持。 + 目前只有 Linux 支持非默认设置。 @@ -1670,16 +1515,11 @@ include_dir 'conf.d' - - 为每个数据库会话设置用于临时缓冲区的最大内存.这些是仅用于访问临时表的会话本地缓冲。 - 如果指定值时没有单位,则以块为单位,即BLCKSZ字节,通常为8kB。 - 默认为8兆字节 (8MB)。(如果BLCKSZ不是8kB,则默认值按比例缩放。) - 这个设置可以在独立的会话内部被改变,但是只有在会话第一次使用临时表之前才能改变; 在会话中随后企图改变该值是无效的。 + 设置每个数据库会话用于临时缓冲区的最大内存量。这些是会话本地的缓冲区,仅用于访问临时表。如果指定值时没有单位,则以块为单位,即 BLCKSZ 字节,通常为 8kB。默认值为 8 兆字节(8MB)。(如果 BLCKSZ 不是 8kB,则默认值按比例变化。)可以在单个会话内更改此设置,但必须在该会话首次使用临时表之前更改;此后尝试更改该值,对该会话不会产生影响。 - - 一个会话将按照temp_buffers给出的限制根据需要分配临时缓冲区。如果在一个并不需要大量临时缓冲区的会话里设置一个大的数值, 其开销只是一个缓冲区描述符,或者说temp_buffers每增加一则增加大概 64 字节。不过,如果一个缓冲区被实际使用,那么它就会额外消耗 8192 字节(或者BLCKSZ字节)。 + 会话会按需分配临时缓冲区,上限为 temp_buffers。对于实际不需要很多临时缓冲区的会话,将此参数设得较大时,开销仅为 temp_buffers 每增加一就多分配一个缓冲区描述符,约为 64 字节。不过,如果实际使用了某个缓冲区,还会为它额外消耗 8192 字节(一般而言为 BLCKSZ 字节)。 @@ -1692,17 +1532,14 @@ include_dir 'conf.d' - - 设置可以同时处于prepared状态的事务的最大数目(见)。把这个参数设置 为零(这是默认设置)将禁用预备事务特性。这个参数只能在服务器启动时设置。 + 设置可同时处于预备状态的事务的最大数量(见 )。将此参数设为零(默认值)会禁用预备事务功能。此参数只能在服务器启动时设置。 - - 如果你不打算使用预备事务,可以把这个参数设置为零来防止意外创建预备事务。如果你正在使用预备事务,你将希望把max_prepared_transactions至少设置为一样大,因此每一个会话可以有一个预备事务待处理。 + 如果不打算使用预备事务,应将此参数设为零,以防意外创建预备事务。如果使用预备事务,通常应将 max_prepared_transactions 设为不小于 的值,以便每个会话都能有一个待处理的预备事务。 - - 运行备库时,必须将此参数设置为大于或等于主库上的值。否则,备库上将不允许查询。 + 运行备库时,必须将此参数设为与主库相同或更大的值。否则,备库上将不允许执行查询。 @@ -1715,24 +1552,11 @@ include_dir 'conf.d' - - 设置查询操作(如排序或哈希表)在写入临时磁盘文件之前可使用的基本最大内存量。 - 如果未指定单位,则将其视为千字节。默认值为四兆字节(4MB)。 - 请注意,复杂查询可能同时执行多个排序和哈希操作, - 每个操作通常允许在开始将数据写入临时文件之前使用此值指定的内存量。 - 此外,可能有多个正在运行的会话同时执行此类操作。 - 因此,使用的总内存量可能是work_mem值的多倍; - 在选择值时必须牢记这一事实。排序操作用于ORDER BYDISTINCT和合并连接。 - 哈希表用于哈希连接、基于哈希的聚合、记忆节点和IN子查询的基于哈希的处理。 + 设置查询操作(如排序或哈希表)在写入临时磁盘文件之前可使用的基础最大内存量。如果未指定单位,则以千字节为单位。默认值为 4 兆字节(4MB)。请注意,复杂查询可能同时执行多个排序和哈希操作,每个操作在开始向临时文件写入数据之前,通常都可以使用此值指定的内存量。此外,多个正在运行的会话也可能并发执行此类操作。因此,使用的总内存量可能是 work_mem 值的数倍;选择此值时必须考虑这一点。排序操作用于 ORDER BYDISTINCT 和归并连接。哈希表用于哈希连接、基于哈希的聚合、Memoize 节点以及基于哈希的 IN 子查询处理。 - - 基于哈希的操作通常比等效的基于排序的操作更加敏感于内存可用性。 - 哈希表的内存限制是通过将work_mem乘以 - hash_mem_multiplier来计算的。这使得 - 基于哈希的操作可以使用超过通常的work_mem基本 - 量的内存。 + 与等效的排序操作相比,基于哈希的操作通常对可用内存更敏感。哈希表的内存上限由 work_mem 乘以 hash_mem_multiplier 计算得到。因此,基于哈希的操作可以使用超过通常的 work_mem 基础量的内存。 @@ -1745,17 +1569,11 @@ include_dir 'conf.d' - - 用于计算哈希操作可以使用的最大内存量。最终限制由将work_mem乘以hash_mem_multiplier确定。 - 默认值为2.0,这使得基于哈希的操作使用通常work_mem基础量的两倍。 + 用于计算基于哈希的操作可以使用的最大内存量。最终上限由 work_mem 乘以 hash_mem_multiplier 确定。默认值为 2.0,使基于哈希的操作可以使用通常的 work_mem 基础量的两倍。 - - 考虑在查询操作频繁溢出的环境中增加hash_mem_multiplier, - 特别是当简单增加work_mem导致内存压力时(内存压力通常表现为间歇性的内存不足错误)。 - 默认设置为2.0通常在混合工作负载中有效。在已将work_mem增加到40MB或更高的环境中, - 可以考虑将设置调高至2.0-8.0或更高。 + 如果查询操作经常溢写磁盘,可以考虑增加 hash_mem_multiplier,尤其是在单纯增加 work_mem 会导致内存压力的情况下(内存压力通常表现为间歇性的内存不足错误)。对于混合工作负载,默认值 2.0 通常有效。如果 work_mem 已增加到 40MB 或更高,则将该值进一步设为 2.0 - 8.0 或更高可能有效。 @@ -1768,19 +1586,11 @@ include_dir 'conf.d' - - 指定维护操作(如 VACUUMCREATE INDEX 和 - ALTER TABLE ADD FOREIGN KEY)可使用的最大内存量。 - 如果指定值时未带单位,则按千字节解释。默认值为 64 兆字节(64MB)。 - 由于数据库会话一次只能执行一个这样的操作,而一个安装通常也不会有很多此类操作并发运行, - 因此把该值设置得明显大于 work_mem 通常是安全的。更大的设置可能改善清理和恢复数据库转储的性能。 + 指定维护操作(如 VACUUMCREATE INDEXALTER TABLE ADD FOREIGN KEY)可使用的最大内存量。如果未指定单位,则以千字节为单位。默认值为 64 兆字节(64MB)。由于一个数据库会话一次只能执行一个此类操作,而一个数据库系统通常也不会并发运行很多此类操作,因此可以安全地将该值设得远大于 work_mem。更大的设置可能改善清理和恢复数据库转储的性能。 - - 注意当自动清理运行时,可能会分配最多达这个内存的倍,因此要小心不要把该默认值设置得太高。 - 通过独立地设置可能会对控制这种情况 - 有所帮助。 + 注意,自动清理运行时,最多可能分配此内存量的 倍,因此不要将默认值设得过高。单独设置 可能有助于控制这一点。 @@ -1793,15 +1603,10 @@ include_dir 'conf.d' - - 指定每个自动清理工作者进程能使用的最大内存量。 - 如果指定值时没有单位,则以千字节为单位。 - 其默认值为 -1,表示转而使用 的值。 - 当运行在其他上下文环境中时,这个设置对VACUUM的行为没有影响。 - 这个参数只能在postgresql.conf中或者服务器命令行上设置。 + 指定每个自动清理工作进程可使用的最大内存量。如果未指定单位,则以千字节为单位。默认值为 -1,表示改用 的值。该设置不影响其他上下文中运行的 VACUUM 的行为。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 - + @@ -1812,13 +1617,7 @@ include_dir 'conf.d' - VACUUMANALYZE命令使用的缓冲区访问策略大小。 - 设置为0将允许操作使用任意数量的shared_buffers。 - 否则,有效范围是 128KB 到 16GB。如果指定的大小超过shared_buffers的 1/8, - 将被静默限制到该值。默认值为 2MB。如果未指定单位,则视为千字节。 - 此参数可随时设置,并且可通过为 - 传递选项来覆盖。较高的设置可以让 - VACUUMANALYZE运行得更快,但设置过大可能会将过多有用页面从共享缓冲区逐出。 + 指定 VACUUMANALYZE 命令使用的缓冲区访问策略的大小。设为 0 时,允许操作使用任意数量的 shared_buffers 缓冲区。否则,有效大小范围为 128 kB16 GB。如果指定的大小超过 shared_buffers 大小的 1/8,则会在不提示的情况下限制为该值。默认值为 2MB。如果未指定单位,则以千字节为单位。此参数可以随时设置。在执行 时,可以通过 选项覆盖此设置。较大的设置可能使 VACUUMANALYZE 运行得更快,但设置过大可能会将过多其他有用页面逐出共享缓冲区。 @@ -1831,13 +1630,10 @@ include_dir 'conf.d' - - 指定逻辑解码要使用的最大内存量,在将某些解码的更改写入本地磁盘之前。 - 这将限制逻辑流复制连接使用的内存量。它默认为 64 兆字节(64MB)。 - 由于每个复制连接仅使用此大小的单个缓冲区,并且安装通常不会同时具有多个此类连接(受 max_wal_senders 的限制),因此将此值设置得明显高于 work_mem是安全的,从而减少写入磁盘的解码更改数量。 + 指定逻辑解码在将部分已解码的更改写入本地磁盘之前可使用的最大内存量。它限制了流式逻辑复制连接使用的内存量。默认值为 64 兆字节(64MB)。由于每个复制连接仅使用一个此大小的缓冲区,而一个数据库系统通常不会同时有很多此类连接(受 max_wal_senders 限制),因此可以安全地将该值设得远高于 work_mem,以减少写入磁盘的已解码更改数量。 - + @@ -1850,7 +1646,7 @@ include_dir 'conf.d' 指定用于缓存pg_commit_ts内容的内存量 (参见)。如果未指定单位,则视为块, - 即BLCKSZ字节,通常为 8KB。默认值为0, + 即BLCKSZ字节,通常为 8kB。默认值为0, 这会请求shared_buffers/512,最多 1024 个块、最少 16 个块。 此参数只能在服务器启动时设置。 @@ -1867,7 +1663,7 @@ include_dir 'conf.d' 指定用于缓存pg_multixact/members内容的共享内存量 (参见)。如果未指定单位,则视为块, - 即BLCKSZ字节,通常为 8KB。默认值为 32。此参数只能在服务器启动时设置。 + 即BLCKSZ字节,通常为 8kB。默认值为 32。此参数只能在服务器启动时设置。 @@ -1882,7 +1678,7 @@ include_dir 'conf.d' 指定用于缓存pg_multixact/offsets内容的共享内存量 (参见)。如果未指定单位,则视为块, - 即BLCKSZ字节,通常为 8KB。默认值为 16。此参数只能在服务器启动时设置。 + 即BLCKSZ字节,通常为 8kB。默认值为 16。此参数只能在服务器启动时设置。 @@ -1897,7 +1693,7 @@ include_dir 'conf.d' 指定用于缓存pg_notify内容的共享内存量 (参见)。如果未指定单位,则视为块, - 即BLCKSZ字节,通常为 8KB。默认值为 16。此参数只能在服务器启动时设置。 + 即BLCKSZ字节,通常为 8kB。默认值为 16。此参数只能在服务器启动时设置。 @@ -1912,7 +1708,7 @@ include_dir 'conf.d' 指定用于缓存pg_serial内容的共享内存量 (参见)。如果未指定单位,则视为块, - 即BLCKSZ字节,通常为 8KB。默认值为 32。此参数只能在服务器启动时设置。 + 即BLCKSZ字节,通常为 8kB。默认值为 32。此参数只能在服务器启动时设置。 @@ -1927,7 +1723,7 @@ include_dir 'conf.d' 指定用于缓存pg_subtrans内容的共享内存量 (参见)。如果未指定单位,则视为块, - 即BLCKSZ字节,通常为 8KB。默认值为0, + 即BLCKSZ字节,通常为 8kB。默认值为0, 这会请求shared_buffers/512,最多 1024 个块、最少 16 个块。 此参数只能在服务器启动时设置。 @@ -1944,7 +1740,7 @@ include_dir 'conf.d' 指定用于缓存pg_xact内容的共享内存量 (参见)。如果未指定单位,则视为块, - 即BLCKSZ字节,通常为 8KB。默认值为0, + 即BLCKSZ字节,通常为 8kB。默认值为0, 这会请求shared_buffers/512,最多 1024 个块、最少 16 个块。 此参数只能在服务器启动时设置。 @@ -1962,8 +1758,8 @@ include_dir 'conf.d' 指定服务器执行栈的最大安全深度。此参数的理想设置是由内核强制执行的实际栈大小限制 - (如由ulimit -s或本地等效设置),减去大约一兆字节的安全边界。 - 需要安全边界是因为服务器中并非每个例程都检查栈深度,而只在关键的潜在递归例程中检查。 + (如由ulimit -s或本地等效设置),减去大约一兆字节的安全余量。 + 需要安全余量是因为服务器中并非每个例程都检查栈深度,而只在关键的潜在递归例程中检查。 如果未指定单位,则将其视为千字节。默认设置为两兆字节(2MB), 这是保守且不太可能引起崩溃的小值。但是,这可能太小,无法执行复杂函数。 只有超级用户和具有适当SET权限的用户才能更改此设置。 @@ -1983,12 +1779,8 @@ include_dir 'conf.d' - - 指定服务器应用于主共享内存区域的共享内存实现,包括 PostgreSQL 的共享缓冲区和其他共享数据。 - 可能的值为 mmap (对使用 mmap 分配的匿名共享内存),sysv (通过 shmget 分配的系统V 共享内存),和windows (Windows共享内存)。 - 并非在所有平台上都支持全部值;第一个被支持的选项是该平台的默认选项。 - sysv 选项不是任何平台的默认选项,通常不建议使用,因为它通常需要非默认的内核设置来允许大量的地址分配(参见 )。 + 指定服务器用于主共享内存区域的共享内存实现,该区域存放 PostgreSQL 的共享缓冲区及其他共享数据。可选值为 mmap(使用 mmap 分配的匿名共享内存)、sysv(通过 shmget 分配的 System V 共享内存)和 windows(Windows 共享内存)。并非所有平台都支持所有值;第一个受支持的选项是该平台的默认值。sysv 不是任何平台的默认选项,通常不建议使用,因为它一般需要更改内核的默认设置才能分配大量内存(见 )。此参数只能在服务器启动时设置。 @@ -2001,16 +1793,8 @@ include_dir 'conf.d' - - 指定服务器应该使用的动态共享内存实现。可能的值包括posix(使用shm_open分配的POSIX共享内存), - sysv(通过shmget分配的System V共享内存), - windows(用于Windows共享内存), - 和mmap(使用存储在数据目录中的内存映射文件模拟共享内存)。 - 并非所有平台都支持所有值;通常第一个支持的选项是该平台的默认值。 - 通常不建议使用mmap选项,因为操作系统可能会反复将修改的页面写回磁盘,增加系统I/O负载; - 但在调试时,当pg_dynshmem目录存储在RAM磁盘上,或者其他共享内存设施不可用时,可能会有用。 - 该参数只能在服务器启动时设置。 + 指定服务器应使用的动态共享内存实现。可选值为 posix(使用 shm_open 分配的 POSIX 共享内存)、sysv(通过 shmget 分配的 System V 共享内存)、windows(Windows 共享内存)、mmap(使用存放在数据目录中的内存映射文件模拟共享内存)。并非所有平台都支持所有值;第一个受支持的选项通常是该平台的默认值。mmap 不是任何平台的默认选项,通常不建议使用,因为操作系统可能会反复将修改过的页面写回磁盘,增加系统 I/O 负载;不过,在调试、将 pg_dynshmem 目录存放在 RAM 磁盘上,或其他共享内存设施不可用时,它可能有用。此参数只能在服务器启动时设置。 @@ -2023,13 +1807,8 @@ include_dir 'conf.d' - - 指定在服务器启动时将要分配给并行查询使用的内存容量。 - 当此内存区域不够用或被并发查询耗尽时,新的并行查询尝试使用dynamic_shared_memory_type配置的方法从操作系统临时分配额外的共享内存,由于内存管理开销该方法可能慢一些。 - 在启动时由min_dynamic_shared_memory分配的内存受到操作系统上所支持的huge_pages设置的影响,并且在自动管理的操作系统上更可能从较大的页面中受益。 - 默认值是0(无)。 - 该参数只能在服务器启动时设置。 + 指定服务器启动时为并行查询分配的内存量。当此内存区域不足或被并发查询耗尽时,新的并行查询会尝试使用 dynamic_shared_memory_type 配置的方法,临时向操作系统分配额外的共享内存;由于内存管理开销,这可能较慢。在支持 huge_pages 设置的操作系统上,启动时通过 min_dynamic_shared_memory 分配的内存会受到该设置的影响;在自动管理巨型页的操作系统上,这些内存也可能更容易受益于较大的页。默认值为 0(不分配)。此参数只能在服务器启动时设置。 @@ -2050,165 +1829,123 @@ include_dir 'conf.d' - - 指定进程可以用于临时文件(如排序和哈希临时文件)或保留游标的存储文件的最大磁盘空间。 - 尝试超过此限制的事务将被取消。 - 如果未指定单位,则将其视为千字节。 - -1(默认值)表示没有限制。 - 只有超级用户和具有适当SET权限的用户才能更改此设置。 + 指定一个进程可用于临时文件的最大磁盘空间,例如排序和哈希临时文件,或保留游标的存储文件。尝试超过此限制的事务将被取消。如果未指定单位,则以千字节为单位。-1(默认值)表示没有限制。只有超级用户和具有适当 SET 权限的用户才能更改此设置。 - - 这个设置约束着一个给定PostgreSQL进程在任何瞬间所使用的所有临时文件的总空间。应该注意的是,与在查询执行中在幕后使用的临时文件相反,显式临时表所用的磁盘空间被这个设置所限制。 + 此设置限制单个 PostgreSQL 进程在任意时刻使用的所有临时文件的总空间。需要注意,显式临时表所用的磁盘空间计入该上限;计入的是查询执行过程中内部使用的临时文件。 - - - - - - 内核资源使用 - - - - - max_files_per_process (integer) + + file_copy_method (enum) - max_files_per_process配置参数 + file_copy_method配置参数 - - 设置每个服务器子进程允许同时打开的最大文件数。已经在 postmaster 中打开的文件不计入此限制。默认值是一千个文件。 + 指定用于复制文件的方法。可能的值包括 COPY(默认)和 + CLONE(如果操作系统支持)。 + + + 此参数会影响: + + + + CREATE DATABASE ... STRATEGY=FILE_COPY + + + + + ALTER DATABASE ... SET TABLESPACE ... + + + - 如果内核强制实施了安全的每进程上限,你通常不必担心这个设置。但在某些平台上 - (尤其是大多数 BSD 系统),如果许多进程都尝试打开大量文件,内核可能允许单个进程打开的文件数 - 远超系统在整体上真正能够支持的数量。如果你看到打开的文件过多之类的失败, - 可以尝试减小这个设置。这个参数只能在服务器启动时设置。 + CLONE 使用 copy_file_range()(Linux、FreeBSD) + 或 copyfile(macOS)系统调用,使内核有机会在某些文件系统上共享磁盘块, + 或将工作交由更低层处理。 - - - - - - 基于代价的清理延迟 - - - 在命令的执行过程中,系统维持着一个内部计数器来跟踪各种被执行的I/O操作的估算开销。当累计的代价达到一个限制(由vacuum_cost_limit指定),执行这些操作的进程将按照vacuum_cost_delay所指定的休眠一小段时间。然后它将重置计数器并继续执行。 - - - 这个特性的出发点是允许管理员降低这些命令对并发的数据库活动产生的I/O影响。在很多情况下,VACUUMANALYZE等维护命令能否快速完成并不重要,而非常重要的是这些命令不会对系统执行其他数据库操作的能力产生显著的影响。基于代价的清理延迟提供了一种方式让管理员能够保证这一点。 - - - - 对于手动发出的VACUUM命令,该特性默认被禁用。要启用它,只要把vacuum_cost_delay变量设为一个非零值。 - - - - - - vacuum_cost_delay (floating point) - - vacuum_cost_delay配置参数 - - - - - - 当超出开销限制时进程将要休眠的时间量。如果指定值时没有单位,则以毫秒为单位。 - 其默认值为0,这将禁用基于代价的清理延迟特性。正值将启用基于代价的清理。 - - - - 在使用基于代价的清理时,vacuum_cost_delay的合适值通常很小,也许是小于1毫秒。 - 虽然vacuum_cost_delay可以被设置为毫秒级别的值,但是在较老的平台上可能无法准确地测量这种延迟。 - 在这样的平台上,增加 VACUUM的节流资源消耗在1ms以上,需要改变其他的清理开销参数。 - 尽管如此,你应该保持 vacuum_cost_delay 在平台能持续测量的情况下尽可能小;大延迟没有帮助。 - - - - - - - vacuum_cost_page_hit (integer) - - vacuum_cost_page_hit配置参数 - - - - - - 清理一个在共享缓存中找到的缓冲区的估计代价。它表示锁住缓冲池、查找共享哈希表和扫描页内容的代价。默认值为1。 - - - - - - - vacuum_cost_page_miss (integer) - - vacuum_cost_page_miss配置参数 - - - - - - 清理一个必须从磁盘上读取的缓冲区的代价。 - 它表示锁住缓冲池、查找共享哈希表、从磁盘读取需要的块以及扫描其内容的代价。 - 默认值为2。 - - - - - - - vacuum_cost_page_dirty (integer) - - vacuum_cost_page_dirty配置参数 - - - + + file_extend_method (enum) + + file_extend_method配置参数 + + + + + 指定在诸如COPY这类批量操作期间扩展数据文件时所使用的方法。 + 默认会根据操作系统选择第一个可用选项: + + + + posix_fallocate(Unix)使用标准 POSIX 接口分配磁盘空间,但某些系统缺少该接口。 + 如果接口存在但底层文件系统不支持,本选项会静默回退到write_zeros。 + 已知当前版本的 BTRFS 在使用该选项时会禁用压缩。 + 在提供该函数的系统上,这是默认值。 + + + + + write_zeros通过写入全零数据块来扩展文件。 + 在不提供posix_fallocate函数的系统上,这是默认值。 + + + + 当数据文件扩展的块数不超过 8 个时,总是使用write_zeros方法。 + + + - - 当清理修改一个之前干净的块时需要花费的估计代价。它表示再次把脏块刷出到磁盘所需要的额外I/O。默认值为20。 - - - + + max_notify_queue_pages (integer) + + max_notify_queue_pages配置参数 + + + + + 指定 / 队列可分配页面的最大数量。 + 默认值是 1048576。对于 8 KB 页面,这允许最多消耗 8 GB 的磁盘空间。 + 此参数只能在服务器启动时设置。 + + + - + + - vacuum_cost_limit (integer) - - vacuum_cost_limit配置参数 - - - + - - 将导致清理进程休眠的累计代价。默认值为200。 - - - - + 内核资源使用 - + + - - 有些操作会保持关键性的锁,这样可以尽快完成。基于代价的清理延迟在这类操作期间不会发生。因此有可能代价会累计至大大超过指定的限制。为了防止在这种情况下的无意义的长时间延迟,实际延迟的计算方式是vacuum_cost_delay * - accumulated_balance / - vacuum_cost_limit,且最大值是vacuum_cost_delay * 4。 - - + max_files_per_process (integer) + + max_files_per_process配置参数 + + + + + 设置每个服务器子进程允许同时打开的最大文件数量。postmaster 中已经打开的文件不计入此上限。默认值为一千个文件。 + + + 如果内核强制实施了安全的每进程上限,就不必担心此设置。但在某些平台上(尤其是大多数 BSD 系统),内核允许单个进程打开的文件数量很大,如果很多进程都尝试打开这么多文件,就会远超系统实际能够支持的总量。如果遇到 Too many open files(打开的文件过多)错误,可尝试减小此设置。此参数只能在服务器启动时设置。 + + + + + 计时 @@ -2263,14 +2000,14 @@ include_dir 'conf.d' - 后台写入器 - 有一个独立的服务器进程,叫做后台写入器,它的功能就是发出写(新的或修改过的)共享缓冲区的命令。 - 当干净的共享缓存数量出现不足时,后台写入器写入一些脏缓存到文件系统,并标记为干净。 - 不过,后台写入器确实会增加 I/O 的总负荷,因为虽然在每个检查点间隔中一个重复弄脏的页面可能只会写出一次,但在同一个间隔中后台写入器可能会把它写出好几次。 - 在这一小节讨论的参数可以被用于调节本地需求的行为。 + 有一个独立的服务器进程,称为后台写入器,负责写出(新的或修改过的)共享缓冲区。 + 当干净的共享缓冲区数量似乎不足时,后台写入器会将一些脏缓冲区写入文件系统,并将其标记为干净。 + 这可以降低处理用户查询的服务器进程找不到干净缓冲区、因而不得不自行写出脏缓冲区的可能性。 + 不过,后台写入器确实会使总体 I/O 负载有所增加:反复变脏的页面原本可能在每个检查点间隔中只写出一次, + 而后台写入器可能在同一间隔内随着它变脏而多次写出。本节参数可用于根据实际需求调整此行为。 @@ -2282,13 +2019,10 @@ include_dir 'conf.d' - - - 指定后台写入器活动轮次之间的延迟。在每个轮次中,写入器都会为一定数量的脏缓冲区发出写操作(可以用下面的参数控制)。 - 然后它就休眠 bgwriter_delay的时长, 然后重复动作。当缓冲池中没有脏缓冲区时,不管 bgwriter_delay,它都会进入更长的休眠。如果指定值时没有单位,则以毫秒为单位。默认值是 200 毫秒(200ms)。 - 注意在许多系统上,休眠延迟的有效解析度是 10 毫秒;因此,为bgwriter_delay设置一个 不是 10 的倍数的值与把它设置为下一个更高的 10 的倍数是一样的效果。这个选项只能在服务器命令行上或者在postgresql.conf文件中设置。 - - + + 指定后台写入器各轮活动之间的延迟。每一轮中,写入器会对一定数量的脏缓冲区发出写操作(由下面的参数控制),然后休眠 bgwriter_delay 指定的时长,再重复此过程。不过,当缓冲池中没有脏缓冲区时,它会进入更长的休眠,而不受 bgwriter_delay 限制。如果未指定单位,则以毫秒为单位。默认值为 200 毫秒(200ms)。注意,在某些系统上,休眠延迟的有效分辨率为 10 毫秒;将 bgwriter_delay 设为不是 10 的倍数的值,可能与将它设为下一个更大的 10 的倍数效果相同。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 + + @@ -2299,11 +2033,10 @@ include_dir 'conf.d' - - - 在每个轮次中,不超过这么多个缓冲区将被后台写入器写出。把这个参数设置为零可禁用后台写出(注意被一个独立、专用辅助进程管理的检查点不受影响)。默认值是 100 个缓冲区。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 - - + + 后台写入器每轮写出的缓冲区数量不会超过此值。设为零会禁用后台写入。(由另一个独立的专用辅助进程管理的检查点不受影响。)默认值为 100 个缓冲区。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 + + @@ -2314,11 +2047,10 @@ include_dir 'conf.d' - - - 每一轮次要写的脏缓冲区的数目基于最近几个轮次中服务器进程需要的新缓冲区的数目。 最近所需的平均值乘以bgwriter_lru_multiplier可以估算下一轮次中将会需要的缓冲区数目。脏缓冲区将被写出直到有很多干净可重用的缓冲区(然而,每一轮次中写出的缓冲区数不超过bgwriter_lru_maxpages)。 因此,设置为 1.0 表示一种刚刚好的策略,这种策略会写出正好符合预测值的数目的缓冲区。 更大大的值可以为需求高峰提供某种缓冲,而更小的值则需要服务进程来处理一些写出操作。默认值是 2.0。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 - - + + 每轮写出的脏缓冲区数量取决于最近几轮服务器进程所需的新缓冲区数量。将近期平均需求乘以 bgwriter_lru_multiplier,即可估算下一轮所需的缓冲区数量。写入器会写出脏缓冲区,直到可用的干净且可重用缓冲区达到这一数量。(不过,每轮写出的缓冲区数量不会超过 bgwriter_lru_maxpages。)因此,设为 1.0 表示采用恰好及时策略,写出的缓冲区数量恰好等于预测需求量。更大的值可为需求突增留出余量,而更小的值则有意将部分写操作留给服务器进程执行。默认值为 2.0。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 + + @@ -2329,24 +2061,22 @@ include_dir 'conf.d' - - - 只要后台写入的数据超过这个数量,尝试强制 OS 把这些写发送到底层存储上。这样做将限制内核页缓存中脏数据的量,降低了在检查点末尾发出一个 fsync 时或者 OS 在后台大批量写回数据时卡住的可能性。 - 那常常会导致大幅度压缩的事务延迟,但是也有一些情况(特别是负载超过但小于 OS 页面高速缓存)的性能会降低。这种设置可能会在某些平台上没有效果。 - 如果指定值时没有单位,则以块为单位,即为BLCKSZ 字节,通常为8kB.合法的范围在0(禁用受控写回)和2MB之间。Linux 上的默认值是512kB,其他平台上是0(如果BLCKSZ不是8kB,则默认值和最大值会按比例缩放至这个值)。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 - - + + 每当后台写入器写出的数据超过此数量时,就尝试强制操作系统将这些写操作发往底层存储。这样可以限制内核页缓存中的脏数据量,降低在检查点结束时调用 fsync,或操作系统在后台以较大批次写回数据时发生停顿的可能性。通常,这能大幅降低事务延迟,但在某些情况下性能可能下降,尤其是工作负载大于 而小于操作系统页缓存时。此设置在某些平台上可能没有效果。如果未指定单位,则以块为单位,即 BLCKSZ 字节,通常为 8kB。有效范围为 0(禁用强制写回)至 2MB。Linux 上的默认值为 512kB,其他平台为 0。(如果 BLCKSZ 不是 8kB,默认值和最大值将按比例变化。)此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 + + - 较小的bgwriter_lru_maxpagesbgwriter_lru_multiplier可以降低由后台写入器造成的额外 I/O 开销。但更可能的是,服务器进程将必须自己发出写入操作,这会延迟交互式查询。 + 较小的 bgwriter_lru_maxpagesbgwriter_lru_multiplier 可以降低后台写入器造成的额外 I/O 负载, + 但也会增加服务器进程必须自行发出写操作的可能性,从而延迟交互式查询。 - 异步行为 + I/O @@ -2357,18 +2087,10 @@ include_dir 'conf.d' - - - 当单个后端写入数据的量超过这个数量时,尝试强制操作系统发送这些写入到底层存储。 - 这样做将限制内核的页面缓存中的脏数据量,降低在检查点末尾发出fsync时暂停的可能性,或者当操作系统在后台大批量的写回数据时。 - 通常的结果会大大减少事务延迟,但也有一些情况,特别是当工作负载大于,但小于操作系统的页面缓存时,性能可能会下降。 - 此设置在某些平台上可能无效。 - 如果指定此值时没有单位,则将其作为块,即BLCKSZ字节,通常为8kB。 - 有效范围在0,禁止强制回写,和2MB之间。 - 默认值是0,即没有强制回写。 - (如果BLCKSZ不是8kB,则最大值按其比例缩放。) - - + + 每当单个后端写出的数据超过此数量时,就尝试强制操作系统将这些写操作发往底层存储。这样可以限制内核页缓存中的脏数据量,降低在检查点结束时调用 fsync,或操作系统在后台以较大批次写回数据时发生停顿的可能性。通常,这能大幅降低事务延迟,但在某些情况下性能可能下降,尤其是工作负载大于 而小于操作系统页缓存时。此设置在某些平台上可能没有效果。如果未指定单位,则以块为单位,即 BLCKSZ 字节,通常为 8kB。有效范围为 0(禁用强制写回)至 2MB。默认值为 0,即不强制写回。(如果 BLCKSZ 不是 8kB,最大值将按比例变化。) + + @@ -2379,23 +2101,19 @@ include_dir 'conf.d' - - - 设置PostgreSQL预期可以同时执行的并发存储 I/O 操作数量。提高该值会增加任何单个PostgreSQL会话尝试并行发起的 I/O 操作数。允许的范围是11000,或者0表示禁用异步 I/O 请求。默认值是16。 - - - - 较高的值对高延迟存储和高 IOPS 设备影响最大,否则查询会经历明显的 I/O 停顿。不必要地设置过高,可能会增加系统中所有查询的 I/O 延迟。 - - - - 在支持预取建议的系统上,effective_io_concurrency还控制预取距离。 - - - - 对于位于特定表空间中的表,可以通过设置同名的表空间参数覆盖该值(见)。 - - + + 设置 PostgreSQL 预期可以同时执行的并发存储 I/O 操作数量。提高此值会增加单个 PostgreSQL 会话尝试并行发起的 I/O 操作数量。允许的范围为 11000,或设为 0 以禁用异步 I/O 请求。默认值为 16。 + + + 较高的值对以下存储影响最大:查询原本会出现明显 I/O 停顿的高延迟存储,以及高 IOPS 设备。不必要地设得过高,可能会增加系统中所有查询的 I/O 延迟。 + + + 在支持预取建议的系统上,effective_io_concurrency 还控制预取距离。 + + + 对于位于特定表空间中的表,可以通过设置同名的表空间参数覆盖此值(见 )。 + + @@ -2406,15 +2124,13 @@ include_dir 'conf.d' - - - 与effective_io_concurrency相似,但用于支持许多客户端会话完成的维护工作。 - - - 默认值是16。对于位于特定表空间中的表,可以通过设置同名的表空间参数覆盖该值(见)。 - - + 与 effective_io_concurrency 类似,但用于为多个客户端会话执行的维护工作。 + + + 默认值为 16。对于位于特定表空间中的表,可以通过设置同名的表空间参数覆盖此值(见 )。 + + @@ -2593,19 +2309,16 @@ include_dir 'conf.d' - - - 设置系统能够支持的后台进程的最大数量。这个参数只能在服务器启动时设置。默认值为 8。 - - - - 运行备库时,必须将此参数设置为大于或等于主库上的值。否则,备库上将不允许查询。 + + 设置集簇能够支持的后台进程的最大数量。此参数只能在服务器启动时设置。默认值为 8。 - - - 在更改这个值时,考虑也对以及进行调整。 - - + + 运行备库时,必须将此参数设为与主库相同或更大的值。否则,备库上将不允许执行查询。 + + + 更改此值时,也应考虑调整 、&zwsp;、&zwsp;、&zwsp;。 + + @@ -2616,19 +2329,16 @@ include_dir 'conf.d' - - - 设置单个Gather或者Gather Merge节点能够开始的工作者的最大数量。并行工作者会从建立的进程池中取得,数量由限制。注意所要求的工作者数量在运行时可能实际无法被满足。如果这种事情发生,该计划将会以比预期更少的工作者运行,这可能会不太高效。默认值是2。把这个值设置为0将会禁用并行查询执行。 - - - - 注意并行查询可能消耗比非并行查询更多的资源,因为每一个工作者进程时一个完全独立的进程,它对系统产生的影响大致和一个额外的用户会话相同。在为这个设置选择值时,以及配置其他控制资源利用的设置(例如)时,应该把这个因素考虑在内。work_mem之类的资源限制会被独立地应用于每一个工作者,这意味着所有进程的总资源利用可能会比单个进程时高得多。例如,一个使用 4 个工作者的并行查询使用的 CPU 时间、内存、I/O 带宽可能是不使用工作者时的 5 倍之多。 - - - - 并行查询的更多信息请见。 - - + + 设置单个 GatherGather Merge 节点能够启动的工作进程的最大数量。并行工作进程取自 建立的进程池,并受到 的限制。注意,运行时实际可用的工作进程可能不足请求的数量。此时,计划会使用少于预期的工作进程运行,效率可能较低。默认值为 2。设为 0 会禁用并行查询执行。 + + + 注意,并行查询消耗的资源可能远多于非并行查询,因为每个工作进程都是完全独立的进程,对系统的影响大致相当于额外增加一个用户会话。选择此设置的值,以及配置其他控制资源使用的设置(如 )时,都应考虑这一点。work_mem 等资源限制分别应用于每个工作进程,因此所有进程的总资源用量可能远高于单个进程通常的用量。例如,使用 4 个工作进程的并行查询,其 CPU 时间、内存、I/O 带宽等用量可能达到完全不使用工作进程的查询的 5 倍。 + + + 并行查询的更多信息参见 。 + + @@ -2639,18 +2349,13 @@ include_dir 'conf.d' - - - 设置单一工具性命令能够启动的并行工作者的最大数目。 - 当前,支持使用并行工作者的工具性命令是CREATE INDEX,并且只有在构建B-树索引时才能并行,并且 VACUUM 没有 FULL选项。 - 并行工作者从由创建的进程池中取出,数量由控制。 - 注意实际在运行时所请求数量的工作者可能不可用。如果发生这种情况,工具性操作将使用比预期数量少的工作者运行。默认值为2。将这个值设置为0可以禁用工具性命令对并行工作者的使用。 - - - - 注意并行工具性命令不应该消耗比同等数量非并行操作更多的内存。这种策略与并行查询不同,并行查询的资源限制通常是应用在每个工作者进程上。并行工具性命令把资源限制maintenance_work_mem当作对整个工具性命令的限制,而不管其中用到了多少个并行工作者进程。不过,并行工具性命令实际上可能仍会消耗更多的CPU资源和I/O带宽。 - - + + 设置单个工具命令能够启动的并行工作进程的最大数量。目前,支持使用并行工作进程的工具命令包括:构建 B-树、GIN 或 BRIN索引时的 CREATE INDEX,以及不带 FULL 选项的 VACUUM。并行工作进程取自 建立的进程池,并受到 的限制。注意,运行时实际可用的工作进程可能不足请求的数量。此时,工具操作会使用少于预期的工作进程运行。默认值为 2。设为 0 会禁止工具命令使用并行工作进程。 + + + 注意,并行工具命令的内存消耗不应明显高于等效的非并行操作。这与并行查询的策略不同,后者的资源限制通常分别应用于每个工作进程。并行工具命令将 maintenance_work_mem 视为整个工具命令的资源上限,而不论使用多少个并行工作进程。不过,并行工具命令仍可能消耗多得多的 CPU 资源和 I/O 带宽。 + + @@ -2661,17 +2366,14 @@ include_dir 'conf.d' - - - 设置系统为并行操作所支持的工作者的最大数量。默认值为8。 - 在增加或者减小这个值时,也要考虑对以及进行调整。 - 此外,要注意将这个值设置得大于将不会产生效果,因为并行工作者进程都是从所建立的工作者进程池中取出来的。 - - + + 设置集簇能够为并行操作提供的工作进程的最大数量。默认值为 8。增大或减小此值时,也应考虑调整 。此外,将此值设得大于 没有效果,因为并行工作进程取自该设置建立的工作进程池。 + + - + parallel_leader_participation (boolean) @@ -2679,17 +2381,12 @@ include_dir 'conf.d' - - - 允许 leader 进程在GatherGather Merge节点下参与执行查询计划,而不是仅仅等待 worker 进程。 - 默认值是on。 - 将其设置为off可以降低 worker 因 leader 读取元组速度不够快而被阻塞的可能性, - 但在生成第一条元组之前,leader 进程将需要等待 worker 进程启动。 - leader 对性能的帮助或拖累程度取决于计划类型、worker 数量以及查询持续时间。 - - + + 允许领导者进程执行 GatherGather Merge 节点下的查询计划,而不是等待工作进程。默认值为 on。将此值设置为 off,可以降低工作进程因领导者读取元组不够快而被阻塞的可能性,但在产生第一批元组之前,领导者进程必须等待工作进程启动。领导者对性能的帮助或妨碍程度取决于计划类型、工作进程数量和查询持续时间。 + + - + @@ -2720,7 +2417,7 @@ include_dir 'conf.d' - minimal级别生成最少的WAL日志量。它不记录在创建或重写事务中对永久关系的行信息。 + minimal级别生成最少的WAL日志量。对于在当前事务中创建或重写的永久关系,不记录其行信息。 这可以使操作速度更快(参见)。触发此优化的操作包括: ALTER ... SET TABLESPACE @@ -2731,15 +2428,15 @@ include_dir 'conf.d' REINDEX TRUNCATE - 然而,最小的WAL不包含足够的信息用于时点恢复,因此必须使用replica或更高级别来启用持续归档 + 然而,minimal 级别的 WAL 不包含足够的信息用于时间点恢复,因此必须使用replica或更高级别来启用持续归档 ()和流式二进制复制。 实际上,如果max_wal_senders不为零,服务器甚至不会以此模式启动。 - 请注意,将wal_level更改为minimal会使先前的基本备份无法用于时点恢复和备库。 + 请注意,将wal_level更改为minimal会使先前的基础备份无法用于时间点恢复和备库。 logical级别上,记录与replica相同的信息,以及从WAL中提取逻辑变更集所需的信息。 - 使用logical级别会增加WAL的容量,特别是如果许多表被配置为REPLICA IDENTITY FULL, + 使用logical级别会增加 WAL 的数量,特别是如果许多表被配置为REPLICA IDENTITY FULL, 并且执行了许多UPDATEDELETE语句。 @@ -2771,16 +2468,15 @@ include_dir 'conf.d' - 能安全关闭fsync的环境的示例包括从一个备份文件中初始加载一个新数据库集簇、使用一个数据库集簇来在数据库被删掉并重建之后处理一批数据,或者一个被经常重建并却不用于失效备援的只读数据库克隆。单独的高质量硬件不足以成为关闭fsync的理由。 + 可以安全关闭fsync的情形包括:从备份文件初始装载一个新数据库集簇;用数据库集簇处理一批数据,处理后就丢弃并重建该数据库;或者使用经常重建且不用于故障切换的只读数据库克隆。仅有高质量硬件不足以成为关闭fsync的理由。 - 当把fsync从关闭改成打开时,为了可靠的恢复,需要强制在内核中的所有被修改的缓冲区进入持久化存储。这可以在多个时机来完成: - 在集簇被关闭时或在fsync因为运行initdb --sync-only而打开时、运行sync时、卸载文件系统时或者重启服务器时。 + 为确保将fsync从关闭改为打开后能够可靠恢复,必须将内核中所有已修改的缓冲区强制写入持久存储。可以在集簇已关闭或fsync已开启时,通过运行initdb --sync-only、运行sync、卸载文件系统或重启服务器来完成。 - 在很多情况下,为不重要的事务关闭可以提供很多关闭fsync的潜在性能收益,并不会有的同时, 关闭fsync可以提供很多潜在的性能优势,而不会有伴随着的数据损坏风险。 + 在很多情况下,为非关键事务关闭,可以获得关闭fsync所带来的大部分潜在性能收益,同时避免伴随的数据损坏风险。 @@ -2799,44 +2495,32 @@ include_dir 'conf.d' - 指定数据库服务器返回success指示给客户端之前,必须要完成多少WAL处理。 - 合法的值为remote_apply, on(默认值), remote_write,local, 和 off。 + 指定数据库服务器向客户端返回成功指示之前,必须完成多少 WAL 处理。有效值为remote_applyon(默认值)、remote_writelocaloff - 如果synchronous_standby_names为空,则唯一有意义的设置为onoff ; - remote_applyremote_writelocal都提供与on相同的本地同步级别。 - 所有非off模式的本地行为都是等待WAL的本地刷新到磁盘。 - 在 off模式,无需等待,因此在向客户端报告成功和以后保证事务安全防止服务器崩溃之间可能会出现延迟。 - 当设置为off时,在向客户端报告成功和真正保证事务不会被服务器崩溃威胁之间会有延迟(最大的延迟是的三倍)。 - 不同于,将这个参数设置为off不会产生数据库不一致性的风险:一个操作系统或数据库崩溃可能会造成一些最近据说已提交的事务丢失,但数据库状态是一致的,就像这些事务已经被干净地中止。 - 因此,当性能比完全确保事务的持久性更重要时,关闭synchronous_commit可以作为一个有效的代替手段。更多讨论见。 + 如果synchronous_standby_names为空,只有onoff两种设置有意义;remote_applyremote_writelocal提供的本地同步级别都与on相同。所有非off模式在本地都会等待 WAL 刷写到磁盘。在off模式下则无需等待,因此,向客户端报告成功后,可能还要经过一段时间,才能保证事务不会因服务器崩溃而丢失。(最大延迟为的三倍。)与不同,将此参数设为off不会带来数据库不一致的风险:操作系统或数据库崩溃可能会使一些最近报告已提交的事务丢失,但数据库状态会与这些事务已正常中止时完全相同。因此,当性能比完全确保事务持久性更重要时,关闭synchronous_commit可以是一种有用的替代方案。更多讨论见 - 如果为非空,synchronous_commit也控制是否事务提交将等待它们的 WAL 记录在备库上被处理。 + 如果非空,synchronous_commit还控制事务提交是否等待备库处理其 WAL 记录。 - 当设置为 remote_apply 时,提交将等待,直到来自当前同步备库的答复显示他们已收到事务的提交记录并应用了它,以便它变得对备库上的查询可见,并写入备库上的持久存储。 - 这将导致比以前的设置更大的提交延迟,因为它等待 WAL 重放(replay)。 - 当设置为on时,提交将等待,直到来自于当前同步的备库的回复显示它们已经收到了事务的提交记录并将其刷入了磁盘。 - 这保证事务将不会被丢失,除非主库和所有同步备库都遭受到了数据库存储损坏的问题。 - 当这个参数被设置为remote_write时,提交将等待,直到来自当前的同步备库的回复指示它们已经收到了该事务的提交记录并且已经把该记录写到它们的文件系统,这种设置保证数据得以保存,在PostgreSQL的备库实例崩溃时,但是不能保证备库遭受操作系统级别崩溃时数据能被保持,因为数据不一定必须要在备库上达到持久存储。 - 设置local会导致提交等待本地刷写到磁盘,而不是复制。在使用同步复制时这通常是不可取的,但是为了完整性提供了这个选项。 + 设为remote_apply时,提交会等待当前同步备库回复,确认已收到并应用该事务的提交记录,使其对备库上的查询可见,并且已将其写入备库的持久存储。由于需要等待 WAL 重放,这会比之前的设置产生大得多的提交延迟。设为on时,提交会等待当前同步备库回复,确认已收到事务的提交记录,并已将其刷写到持久存储。这能保证事务不会丢失,除非主库和所有同步备库的数据库存储都损坏。设为remote_write时,提交会等待当前同步备库回复,确认已收到事务的提交记录,并已将其写入各自的文件系统。此设置能保证备库上的PostgreSQL实例崩溃时数据不丢失,但不能保证备库发生操作系统级别崩溃时数据不丢失,因为数据未必已写入备库的持久存储。设为local时,提交会等待本地刷盘,但不等待复制。使用同步复制时通常不希望采用这种设置,提供它是为了使选项完整。 - 这个参数可以随时被修改;任何一个事务的行为由其提交时生效的设置决定。因此,可以同步提交一些事务,同时异步提交其他事务。例如,当默认是相反时,实现一个单一多语句事务的异步提交,在事务中发出SET LOCAL synchronous_commit TO OFF。 + 此参数可以随时更改;每个事务的行为由提交时生效的设置决定。因此,让一些事务同步提交、另一些事务异步提交是可行且有用的。例如,当默认设置要求同步提交时,可以在一个包含多条语句的事务中执行SET LOCAL synchronous_commit TO OFF,使该事务异步提交。 - 概括了 synchronous_commit 设置的能力. + 汇总了synchronous_commit各种设置具备的能力。 - synchronous_commit Modes + synchronous_commit 模式 @@ -2846,10 +2530,10 @@ include_dir 'conf.d' - synchronous_commit setting - local durable commit - PG 崩溃备库持久提交 - OS 崩溃备库持久提交 + synchronous_commit 设置 + 本地提交持久性 + PG 崩溃后备库提交持久性 + OS 崩溃后备库提交持久性 备库查询一致性 @@ -2913,7 +2597,7 @@ include_dir 'conf.d' - 用来向强制 WAL 更新到磁盘的方法。如果fsync是关闭的,那么这个设置就不相关,因为 WAL 文件更新将根本不会被强制。可能的值是: + 用于将 WAL 更新强制写入磁盘的方法。如果fsync关闭,此设置就没有作用,因为 WAL 文件更新根本不会被强制写入磁盘。可选值为: @@ -2937,7 +2621,7 @@ include_dir 'conf.d' - fsync_writethrough(在每次提交时调用fsync(),强制任何磁盘写高速缓存的直通写) + fsync_writethrough(在每次提交时调用fsync(),强制穿透任何磁盘写缓存) @@ -2949,10 +2633,9 @@ include_dir 'conf.d' - open_* 选项也可以使用O_DIRECT(如果可用)。 不是在所有平台上都能使用所有这些选择。 - 默认值是列表中第一个被平台支持的那个, 不过fdatasync是 Linux和FreeBSD中的默认值。 - 默认值不一定是最理想的;有可能需要修改这个设置或系统配置的其他方面来创建一个崩溃-安全的配置,或达到最佳性能。 + 默认值是列表中第一个被平台支持的那个, 不过fdatasync是 Linux 和 FreeBSD 中的默认值。 + 默认值不一定最合适;可能需要更改此设置或系统配置的其他方面,以确保崩溃时的数据安全或达到最佳性能。 这些方面在中讨论。 这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 @@ -2969,11 +2652,11 @@ include_dir 'conf.d' - 当这个参数为打开时,PostgreSQL服务器在一个检查点之后的页面的第一次修改期间将每个页面的全部内容写到 WAL 中。这么做是因为在操作系统崩溃期间正在处理的一次页写入可能只有部分完成,从而导致在一个磁盘页面中混合有新旧数据。在崩溃后的恢复期间,通常存储在 WAL 中的行级改变数据不足以完全恢复这样一个页面。存储整页镜像可以保证页面被正确存储,但代价是增加了必须被写入 WAL 的数据量(因为 WAL 重放总是从一个检查点开始,所以在检查点后每个页面的第一次改变时这样做就够了。因此,一种减小全页面写开销的方法是增加检查点间隔参数值)。 + 启用此参数时,PostgreSQL服务器会在检查点之后首次修改每个磁盘页面时,将该页面的全部内容写入 WAL。这样做是因为,操作系统崩溃时正在进行的页面写入可能只完成了一部分,导致磁盘页面混有新旧数据。通常存储在 WAL 中的行级变更数据不足以在崩溃恢复时完整还原这样的页面。保存整页镜像能保证正确恢复页面,但会增加必须写入 WAL 的数据量。(由于 WAL 重放总是从检查点开始,只需在检查点之后首次修改每个页面时这样做。因此,减少整页写入开销的一种方法是增大检查点间隔参数。) - 把这个参数关闭会加快正常操作,但是在系统失败后可能导致不可恢复的数据损坏,或者静默的数据损坏。其风险类似于关闭fsync, 但是风险较小。并且只有在可关闭fsync的情况下才应该关闭它。 + 关闭此参数可以加快正常操作,但系统故障后可能出现不可恢复的数据损坏或静默数据损坏。风险与关闭fsync类似,虽然较小,但也只有在该参数建议的相同情形下才应关闭此参数。 @@ -2996,7 +2679,7 @@ include_dir 'conf.d' - 当这个参数为on时,PostgreSQL服务器一个检查点之后页面被第一次修改期间把该磁盘页面的整个内容都写入 WAL,即使对所谓的提示位做非关键修改也会这样做。 + 当这个参数为on时,PostgreSQL服务器在检查点之后首次修改页面时把该磁盘页面的整个内容都写入 WAL,即使对所谓的提示位做非关键修改也会这样做。 @@ -3021,9 +2704,8 @@ include_dir 'conf.d' 此参数启用使用指定的压缩方法对WAL进行压缩。 - 启用后,PostgreSQL服务器在 - 打开时或在基本备份期间, - 压缩写入WAL的整页镜像。 + 启用后,PostgreSQL服务器会压缩写入 WAL 的整页镜像,例如 + 在启用时、基础备份期间等。 在WAL重放期间,将对压缩的页镜像进行解压缩。 支持的方法有pglzlz4(如果PostgreSQL @@ -3036,8 +2718,7 @@ include_dir 'conf.d' - 启用压缩可以减少WAL卷的大小,而不会增加不可恢复的数据损坏的风险, - 但会增加在WAL记录期间进行压缩时的额外CPU消耗,以及在WAL重放期间进行解压缩时的成本。 + 启用压缩可以减少 WAL 数据量,而且不会增加不可恢复的数据损坏风险;代价是在记录 WAL 时压缩、重放 WAL 时解压会额外消耗一些 CPU。 @@ -3052,10 +2733,10 @@ include_dir 'conf.d' - 如果设置为on(默认值),此选项会导致新的 WAL 文件被零填充。 - 在某些文件系统上,这可确保在我们需要写入 WAL 记录之前分配空间。 - 但是,Copy-On-Write(COW)文件系统可能不会从此技术中受益,因此可以选择跳过不必要的工作。 - 如果设置为off,则在创建文件时仅写入最终字节,以便其具有预期大小。 + 如果设置为on(默认值),此选项会导致新的 WAL 文件被零填充。 + 在某些文件系统上,这可确保在我们需要写入 WAL 记录之前分配空间。 + 但是,写时复制(COW)文件系统可能不会从此技术中受益,因此可以选择跳过不必要的工作。 + 如果设置为off,则在创建文件时只写入最后一个字节,以便其具有预期大小。 @@ -3070,8 +2751,8 @@ include_dir 'conf.d' - 如果设置为 on (默认值),此选项通过重命名来回收 WAL 文件,从而避免创建新文件。 - 在 COW 文件系统上,创建新文件系统可能更快,因此提供了禁用此行为的选项。 + 如果设置为 on (默认值),此选项通过重命名来回收 WAL 文件,从而避免创建新文件。 + 在 COW 文件系统上,创建新文件可能更快,因此提供了禁用此行为的选项。 @@ -3086,12 +2767,12 @@ include_dir 'conf.d' - 用于还未写入磁盘的 WAL 数据的共享内存量。默认值 -1 选择等于的 1/32 的尺寸(大约3%),但是不小于64kB也不大于 WAL 段的尺寸(通常为16MB)。如果自动的选择太大或太小可以手工设置该值,但是任何小于32kB的正值都将被当作32kB。 + 用于还未写入磁盘的 WAL 数据的共享内存量。默认值 -1 选择等于的 1/32 的尺寸(大约3%),但是不小于64kB也不大于 WAL 段的尺寸(通常为16MB)。如果自动的选择太大或太小可以手工设置该值,但是任何小于32kB的正值都将被当作32kB。 如果指定值时没有单位,则以WAL块作为单位,即为 XLOG_BLCKSZ 字节,通常为8kB。这个参数只能在服务器启动时设置。 - 在每次事务提交时,WAL 缓冲区的内容被写出到磁盘,因此极大的值不可能提供显著的收益。不过,把这个值设置为几个兆字节可以在一个繁忙的服务器(其中很多客户端会在同一时间提交)上提高写性能。由默认设置 -1 选择的自动调节将在大部分情况下得到合理的结果。 + 在每次事务提交时,WAL 缓冲区的内容被写出到磁盘,因此极大的值不太可能带来显著收益。不过,把这个值设置为至少几个兆字节可以在一个繁忙的服务器(其中很多客户端会在同一时间提交)上提高写性能。由默认设置 -1 选择的自动调节将在大部分情况下得到合理的结果。 @@ -3109,9 +2790,9 @@ include_dir 'conf.d' 指定 WAL 写入器刷写 WAL 的频繁程度,以时间为单位。 在刷写WAL之后,写入器将根据wal_writer_delay所给出的时间长度进行睡眠,除非被一个异步提交的事务提前唤醒。 - 如果最近的刷写发生在 wal_writer_delay 之前,并且小于 wal_writer_flush_after WAL的值产生之后,那么WAL只会被写入操作系统,而不会被刷写到磁盘。 + 如果距上次刷盘的时间小于wal_writer_delay,并且自那以后产生的 WAL 数据量小于wal_writer_flush_after,则只将 WAL 写入操作系统,而不刷写到磁盘。 如果指定值时没有单位,则以毫秒作为单位。 - 默认值是 200 毫秒(200ms)。注意在很多系统上,有效的睡眠延迟粒度是 10 毫秒,把wal_writer_delay设置为一个不是 10 的倍数的值,其效果和把它设置为大于该值的下一个 10 的倍数产生的效果相同。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 + 默认值是 200 毫秒(200ms)。注意在某些系统上,有效的睡眠延迟粒度是 10 毫秒,把wal_writer_delay设置为一个不是 10 的倍数的值,其效果可能与将其设置为下一个更大的 10 的倍数相同。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 @@ -3126,8 +2807,8 @@ include_dir 'conf.d' - 指定 WAL 写入器刷写 WAL 的频繁程度,以卷为单位。 - 如果最近的刷写发生在 wal_writer_delay 之前,并且小于 wal_writer_flush_after WAL的值产生之后,那么WAL只会被写入操作系统,而不会被刷写到磁盘。 + 指定 WAL 写入器刷写 WAL 的频繁程度,按数据量衡量。 + 如果距上次刷盘的时间小于wal_writer_delay,并且自那以后产生的 WAL 数据量小于wal_writer_flush_after,则只将 WAL 写入操作系统,而不刷写到磁盘。 如果wal_writer_flush_after被设置为0,则WAL数据总是会被立即刷写。 如果指定值时没有单位,则以WAL块作为单位,即为XLOG_BLCKSZ字节,通常为8kB。 默认是1MB。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 @@ -3145,10 +2826,7 @@ include_dir 'conf.d' - 当wal_levelminimal,并且在创建或重写永久关系之后提交事务时,此设置将确定如何保留新数据。 - 如果数据小于此设置,将其写入 WAL 日志;否则,使用受影响文件的 fsync。 - 根据存储的属性,如果此类提交减慢了并发事务,提高或降低此值可能会有所帮助。 - 如果指定此值时没有单位,则视为千字节。默认为两兆字节(2MB)。 + 当wal_levelminimal,且事务在创建或重写永久关系后提交时,此设置决定如何持久保存新数据。如果数据量小于此设置,就将其写入 WAL;否则,对受影响的文件执行 fsync。如果这类提交拖慢了并发事务,根据存储的特性,增大或减小此值可能有所帮助。未指定单位时以千字节为单位。默认值为两兆字节(2MB)。 @@ -3163,20 +2841,20 @@ include_dir 'conf.d' - 设置commit_delay会在执行WAL刷新之前添加时间延迟。 + 设置commit_delay会在发起 WAL 刷盘之前添加时间延迟。 如果系统负载足够高,使得在给定时间间隔内有更多事务准备提交, - 这可以通过允许更多事务通过单个WAL刷新来提高组提交吞吐量。 - 然而,这也会增加延迟,最多为每个WAL刷新的commit_delay。 - 因为如果没有其他事务准备提交,延迟就是浪费的,所以只有在至少有 - commit_siblings其他事务活动时才会执行延迟, - 当要启动刷新时,如果fsync被禁用,则不会执行延迟。 + 这可以通过允许更多事务通过一次 WAL 刷盘来提高组提交吞吐量。 + 不过,每次 WAL 刷盘的延迟也会因此增加,最多增加commit_delay。 + 如果没有其他事务准备提交,等待就没有意义,因此仅当即将发起刷盘时至少还有 + commit_siblings个其他活动事务,才会等待。 + 此外,如果禁用了fsync,也不会等待。 如果未指定单位,则将其视为微秒。 默认commit_delay为零(无延迟)。 只有超级用户和具有适当SET权限的用户才能更改此设置。 - 在PostgreSQL的 9.3 发布之前,commit_delay的行为不同并且效果更差:它只影响提交,而不是所有 WAL 刷写,并且即使在 WAL 刷写马上就要完成时也会等待一整个配置的延迟。从PostgreSQL 9.3 中开始,第一个准备好刷写的进程会等待配置的间隔,而后续的进程只等到领先者完成刷写操作。 + 在PostgreSQL的 9.3 发布之前,commit_delay的行为不同并且效果更差:它只影响提交,而不是所有 WAL 刷写,并且即使 WAL 刷盘更早完成,也会等待整个配置的延迟时间。从PostgreSQL 9.3 开始,第一个准备好刷写的进程会等待配置的间隔,而后续的进程只等到领先者完成刷写操作。 @@ -3191,7 +2869,7 @@ include_dir 'conf.d' - 在执行commit_delay延迟时,要求的并发活动事务的最小数目。大一些的值会导致在延迟间隔期间更可能有至少另外一个事务准备好提交。默认值是五个事务。 + 执行commit_delay延迟前要求的并发活动事务的最小数目。大一些的值会导致在延迟间隔期间更可能有至少另外一个事务准备好提交。默认值是五个事务。 @@ -3214,7 +2892,7 @@ include_dir 'conf.d' 自动 WAL 检查点之间的最长时间。如果指定值时没有单位,则以秒为单位。 - 合理的范围在 30 秒到 1 天之间。默认是 5 分钟(5min)。增加这个参数的值会增加崩溃恢复所需的时间。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 + 合理的范围在 30 秒到 1 天之间。默认是 5 分钟(5min)。增加这个参数的值可能会增加崩溃恢复所需的时间。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 @@ -3229,11 +2907,11 @@ include_dir 'conf.d' - 指定检查点完成的目标,作为检查点之间总时间的一部分。 - 默认是 0.9,这将把检查点分布在几乎所有可用的时间间隔上,提供公平一致的I/O负载,同时也为检查点完成开销留下了一些时间。 - 减少此参数是不被推荐的,因为这会导致检查点完成得更快。 - 这个造成处于在检查点和下一个计划检查点之间较少IO之后的检查点会有更高的IO比例。 - 这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 + 指定检查点完成所用时间的目标值,以检查点之间总时间的比例表示。 + 默认值为 0.9,这会把检查点工作分散到几乎整个可用间隔内,使 I/O 负载较为平稳, + 同时为检查点完成时的额外工作留出一些时间。不建议减小此参数,因为这样会让检查点更快完成, + 导致检查点期间的 I/O 速率更高,而在检查点完成后到下一个计划检查点开始前的一段时间内 I/O 较少。 + 此参数只能在postgresql.conf文件中或服务器命令行上设置。 @@ -3250,7 +2928,7 @@ include_dir 'conf.d' 当执行检查点时写入的数据量超过此数量时,就尝试强制 OS 把这些写发送到底层存储。 这样做将会限制内核页面高速缓存中的脏数据数量,降低在检查点末尾发出fsync或者 OS 在后台大批量写回数据时被卡住的可能性。 - 那常常会导致大幅度压缩的事务延迟,但是也有一些情况(特别是负载超过但小于 OS 页面高速缓存)的性能会降低。 + 这通常能显著降低事务延迟,但是也有一些情况(特别是负载超过但小于 OS 页面高速缓存)的性能会降低。 这种设置可能会在某些平台上没有效果。 如果指定值时没有单位,则以块为单位,即为BLCKSZ 字节,通常为8kB。 合法的范围在0(禁用强制写回)和2MB之间。Linux 上的默认值是256kB,其他平台上是0(如果BLCKSZ不是8kB,则默认值和最大值会按比例缩放到它)。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 @@ -3367,6 +3045,7 @@ include_dir 'conf.d' 这个参数只能在postgresql.conf文件或服务器命令行中设置。 除非在服务器启动时启用了archive_mode并且archive_library设置为空字符串,否则将被忽略。 + 如果archive_commandarchive_library都被设置,则会报错。 如果archive_command是空字符串(默认值),而archive_mode已启用(并且archive_library设置为空字符串), WAL归档将暂时被禁用,但服务器将继续积累WAL段文件,期望很快会提供命令。 将archive_command设置为一个什么都不做但返回true的命令,例如/bin/true(Windows上为REM), @@ -3386,6 +3065,7 @@ include_dir 'conf.d' 用于归档已完成的WAL文件段的库。如果设置为空字符串(默认值),则通过shell进行归档,并使用。 + 如果archive_commandarchive_library都被设置,则会报错。 否则,指定的共享库用于归档。当此参数更改时,postmaster会重新启动WAL归档进程。有关更多信息,请参见 @@ -3405,7 +3085,7 @@ include_dir 'conf.d' - 仅在完成的WAL段中调用。 + 只针对已完成的 WAL 段调用。 因此,如果您的服务器生成的WAL流量较少(或者在这样做时有间歇期),在事务完成和安全记录到归档存储之间可能会有很长的延迟。 为了限制未归档数据的年龄,您可以将archive_timeout设置为强制服务器定期切换到新的WAL段文件。 当此参数大于零时,只要自上次段文件切换以来经过了这段时间,并且存在任何数据库活动,包括单个检查点(如果没有数据库活动,则跳过检查点),服务器将切换到新的段文件。 @@ -3445,13 +3125,9 @@ include_dir 'conf.d' - 是否在恢复期间尝试预取在WAL中引用但尚未在缓冲池中的块。有效值为 - offon和 - try(默认值)。设置 - try仅在操作系统提供 - posix_fadvise函数时才启用 - 预取,该函数目前用于实现预取。请注意,一些操作系统提供该 - 函数,但它不起作用。 + 是否在恢复期间尝试预取 WAL 中引用但尚未在缓冲池中的块。 + 有效值为offontry(默认值)。 + try设置仅在操作系统支持发出预读建议时启用预取。 @@ -3486,8 +3162,8 @@ include_dir 'conf.d' 归档恢复 - configuration - of recovery + 配置 + 恢复 一个备库 @@ -3496,7 +3172,7 @@ include_dir 'conf.d' - Recovery 涵盖使用服务器作为备库或用于执行目标恢复。 + 恢复 涵盖使用服务器作为备库或用于执行目标恢复。 通常情况,备库模式用于提供高可用性和/或读可扩展性,而目标恢复用于从数据丢失中恢复。 @@ -3565,7 +3241,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows 这个信息可以被用来把归档截断为支持从当前恢复重启所需的最小值。 对于单一备库配置,模块常常被用在archive_cleanup_command中,例如: archive_cleanup_command = 'pg_archivecleanup /mnt/server/archivedir "%r"' - 但是注意,如果多个备库正在从同一个归档目录中恢复,你将需要保证只有当任意服务器都不再需要 WAL 文件时才会删除它们。 + 但是注意,如果多个备库正在从同一个归档目录中恢复,你将需要保证只有当所有服务器都不再需要这些 WAL 文件时才会删除它们。 archive_cleanup_command通常被用于一种温备配置(见)中。 要在该命令中嵌入一个真正的%字符,需要写成%% @@ -3618,7 +3294,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows 默认情况下,恢复将会一直恢复到 WAL 日志的末尾。下面的参数可以被用来指定一个更早的停止点。 在recovery_targetrecovery_target_lsnrecovery_target_namerecovery_target_timerecovery_target_xid中, - 最多只能使用一个,如果在配置文件中使用了多个,将会产生一个错误。这个参数只能在服务器启动时设置。 + 最多只能使用一个,如果在配置文件中使用了多个,将会产生一个错误。这些参数只能在服务器启动时设置。 @@ -3651,7 +3327,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows - 这个参数指定(pg_create_restore_point()所创建)的已命名的恢复点,恢复将进入该恢复点。 + 这个参数指定(pg_create_restore_point()所创建)的已命名的恢复点,恢复将进行到该恢复点。 @@ -3666,7 +3342,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows - 此参数指定恢复将执行的时间戳。精确的停止点还受到得影响。 + 此参数指定恢复要进行到的时间戳。精确的停止点还受到的影响。 @@ -3686,7 +3362,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows - 这个参数指定恢复将进入的事务 ID。记住虽然事务 ID 是在事务开始时顺序分配的,但是事务可能以不同的数字顺序完成。 + 这个参数指定恢复要进行到的事务 ID。记住虽然事务 ID 是在事务开始时顺序分配的,但是事务可能以不同的数字顺序完成。 那些在指定事务之前(也可以包括该事务)提交的事务将被恢复。精确的停止点也受到的影响。 @@ -3710,7 +3386,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows - 此参数指定恢复将继续进行的预写日志位置的LSN。精确的停靠点也受 的影响。 + 此参数指定恢复要进行到的预写日志位置的 LSN。精确的停止点也受 的影响。 使用系统数据类型pg_lsn解析此参数。 @@ -3735,7 +3411,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows 指定我们是否仅在指定的恢复目标之后停止(on),或者仅在恢复目标之前停止(off)。 适用于或者被指定的情况。 - 这个设置分别控制事务是否有准确的目标WAL位置(LSN)、提交时间或事务ID将被包括在该恢复中。默认值为on。 + 这个设置控制恢复是否包含 WAL 位置(LSN)、提交时间或事务 ID 分别恰好等于目标值的事务。默认值为on @@ -3752,7 +3428,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows 指定恢复到一个特定的时间线中。该值可以是数字时间线 ID 或特殊值。 - 值current沿着与执行基本备份时相同的时间线恢复。 + 值current沿着与执行基础备份时相同的时间线恢复。 值latest将恢复到归档中能找到的最新时间线,这在备库中很有用。 latest是默认值。 @@ -3788,14 +3464,14 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows - 使用pause设置的目的是:如果这个恢复目标就是恢复最想要的位置,就允许对数据库执行查询。 + 使用pause设置的目的是允许对数据库执行查询,以检查这个恢复目标是否为最合适的恢复位置。 暂停的状态可以使用pg_wal_replay_resume()(见)继续,这会让恢复终结。 如果这个恢复目标不是想要的停止点,那么关闭服务器,将恢复目标设置改为一个稍后的目标并且重启以继续恢复。 要让实例在想要的重放点那里准备好,shutdown设置可以派上用场。 - 该实例将仍能重放更多 WAL 记录(并且事实上将不得不重放从下一次它被启动后最后一个检查点以来的 WAL 记录)。 + 该实例将仍能重放更多 WAL 记录(并且事实上,下次启动时必须重新回放自上一个检查点以来的 WAL 记录)。 @@ -3806,7 +3482,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows 如果没有设置恢复目标,这个设置没有效果。 如果没有启用pause设置的动作将和shutdown一样。 - 如果在升级期间达到恢复目标,pause 的设置将与 promote的行为相同。 + 如果在备库提升期间达到恢复目标,pause 的设置将与 promote的行为相同。 @@ -3821,9 +3497,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows WAL 汇总 - - 这些设置控制 WAL 汇总,这是执行所需的一项功能。 - + 这些设置控制 WAL 汇总。执行增量备份前必须启用这项功能。 @@ -3839,12 +3513,10 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows 默认值为off - 如果wal_level被设置为minimal,则无法以 - summarize_wal=on启动服务器。如果在服务器启动后将 - summarize_wal设置为on而 - wal_levelminimal,则汇总器会运行,但会拒绝为使用 - wal_level=minimal生成的任何 WAL 创建汇总文件。 - + 如果wal_level设为minimal,则不能以summarize_wal=on启动服务器。 + 如果在服务器启动后配置summarize_wal=on,而此时wal_level=minimal, + 汇总器会运行,但会拒绝为使用wal_level=minimal生成的任何 WAL 创建汇总文件。 + @@ -3883,6 +3555,10 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows 对于物理复制,服务器将可以是主库或备库。主库能发送数据,而备库总是被复制数据的接收者。当使用级联复制(见)时,备库也可以是发送者,同时也是接收者。这些参数主要用于发送服务器和备库,尽管某些只在主库上有意义。如果有必要,设置可以在集簇中变化而不出问题。 + + 对于逻辑复制发布者(执行CREATE PUBLICATION的服务器)向订阅者(执行CREATE SUBSCRIPTION的服务器)复制数据。服务器也可以同时是发布者和订阅者。注意,下文各节将发布者称为“发送者”。有关逻辑复制配置设置的更多详细信息,请参见。 + + 发送服务器 @@ -3902,10 +3578,12 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows - 指定来自备库或流式基础备份客户端的并发连接的最大数量(即同时运行 WAL 发送进程的最大数)。 - 默认值是10。值0意味着禁用复制。 - 突然的流式传输客户端断开连接可能留下一个孤立连接槽(知道达到超时),因此这个参数应该设置得略高于最大客户端连接数,这样断开连接的客户端可以立刻重新连接。 - 这个参数只能在服务器启动时被设置。此外,wal_level必须设置为replica或更高级别以允许来自备库的连接。 + 指定来自备库或流式基础备份客户端的最大并发连接数(即同时运行的 WAL 发送进程的最大数量)。 + 默认值为 10。值 0 表示禁用复制。 + 流式客户端突然断开连接后,可能会留下一个孤立连接槽,直到超时才释放。 + 因此,此参数应设置得略高于预期的最大客户端数,使断开连接的客户端能够立即重新连接。 + 此参数只能在服务器启动时设置。此外,wal_level 必须设置为 + replica 或更高级别,才允许来自备库的连接。 @@ -4005,16 +3683,19 @@ HINT: If it is safe for all REPLICATION users to use this library as an output - 指定在备库需要为流复制获取日志段文件的情况下,pg_wal目录下所能保留的过去日志文件段的最小尺寸。 - 如果一个连接到发送服务器的备库落后了超过wal_keep_size兆字节,发送服务器可以移除一个备库仍然需要的 WAL 段,在这种情况下复制连接将被中断。 - 最终结果是下行连接也将最终失败(不过,如果在使用 WAL 归档,备库可以通过从归档获取段来恢复)。 + 指定在 pg_wal 目录中保留的旧 WAL 文件的最小总量, + 以便备库需要时获取这些文件进行流复制。如果连接到发送服务器的备库落后超过 + wal_keep_size 兆字节,发送服务器可能会移除备库仍需要的 WAL 段, + 从而导致复制连接终止。下游连接最终也会因此失败。 + (不过,如果使用了 WAL 归档,备库可以通过从归档获取该段来恢复。) - 只设置pg_wal中保留的文件段的最小尺寸;系统可能需要为 WAL 归档或从一个检查点恢复保留更多段。 - 如果wal_keep_size为零(默认值), 更多的空间来 存放WAL归档或从一个检查点恢复。 - 如果wal_keep_segments是零(缺省), 系统不会为备库目的保留任何多余的段,因此备库可用的旧 WAL 段的数量是一个上个检查点位置和 WAL 归档状态的函数。 - 如果此值被指定时没有单位,则视为兆字节。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 + 此设置只规定 pg_wal 中保留的段的最小总量;系统可能需要为 WAL 归档 + 或从检查点恢复而保留更多段。如果 wal_keep_size 为零(默认值), + 系统不会为备库额外保留任何段,因此备库可用的旧 WAL 段数取决于前一个检查点的位置 + 和 WAL 归档的状态。如果指定值时没有单位,则按兆字节计算。 + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 @@ -4028,14 +3709,18 @@ HINT: If it is safe for all REPLICATION users to use this library as an output - - 指定在检查点时,replication slots(复制槽)允许在pg_wal目录中保留的WAL文件的最大大小。 - 如果max_slot_wal_keep_size为-1(默认值),复制槽可以保留无限量的WAL文件。否则,如果复制槽的restart_lsn落后于当前LSN超过给定大小, - 使用该槽的备机可能由于所需的WAL文件被删除而无法继续复制。您可以在pg_replication_slots中查看复制槽的WAL可用性。 - 如果未指定单位,则此值将被视为兆字节。此参数只能在postgresql.conf文件或服务器命令行中设置。 - - - + + 指定检查点时复制槽允许在 + pg_wal 目录中保留的 WAL 文件最大总量。 + 如果 max_slot_wal_keep_size 为 -1(默认值),复制槽可以保留无限量的 WAL 文件。 + 否则,如果复制槽的 restart_lsn 落后当前 LSN 超过给定大小,使用该槽的备库可能会 + 因为所需 WAL 文件被移除而无法继续复制。可以在 + pg_replication_slots 中查看复制槽的 WAL 可用情况。 + 如果指定值时没有单位,则按兆字节计算。此参数只能在 + postgresql.conf 文件中或服务器命令行上设置。 + + + idle_replication_slot_timeout (integer) @@ -4074,14 +3759,14 @@ HINT: If it is safe for all REPLICATION users to use this library as an output - 中断那些停止活动超过这个时间量的复制连接。这对发送服务器检测一个费用服务器崩溃或网络中断有用。 - 如果指定值时没有单位,则以毫秒为单位。默认值是 60 秒。值0将禁用超时机制。 + 终止非活动时间超过此值的复制连接。这有助于发送服务器检测备库崩溃或网络中断。 + 如果指定值时没有单位,则按毫秒计算。默认值为 60 秒。值零禁用超时机制。 - 对于跨越多个地理位置分布的集簇,每个位置使用不同的值可以为集簇管理带来更大的灵活性。 - 对于具有低延迟网络连接的备库,较小的值有助于更快的故障检测; - 对于位于远端位置的具有高延迟网络连接的备库,较大的值有助于更好地判断备库的健康状况。 + 对于跨多个地理位置分布的集簇,在各位置使用不同的值可以提高集簇管理的灵活性。 + 对于网络延迟较低的备库,较小的值有助于更快地检测故障; + 对于地处远端、网络延迟较高的备库,较大的值有助于更准确地判断其健康状况。 @@ -4147,7 +3832,10 @@ HINT: If it is safe for all REPLICATION users to use this library as an output 主库 - 这些参数可以在发送复制数据给一个或多个备库的主库上设置。注意除了这些参数之外,在主库上必须设置合适的,并且也启用可选的 WAL 归档(见)。这些参数值与备库无关,尽管你可能希望为了准备好一个备库转变成主库来设置这些参数。 + 这些参数可以在向一个或多个备库发送复制数据的主库上设置。 + 除这些参数外,还必须在主库上适当设置 , + 也可以选择启用 WAL 归档(见 )。 + 这些参数在备库上的取值不影响备库运行,不过也可以预先设置,以备将来提升为主库。 @@ -4163,15 +3851,17 @@ HINT: If it is safe for all REPLICATION users to use this library as an output 所述,这个参数指定一个支持同步复制的备库的列表。 - 可能会有一个或者多个活动的同步备库,在这些备库确认收到它们的数据之后,等待提交的事务将被允许继续下去。 - 同步备库是那些名字出现在这个列表前面,并且当前已连接并且正在实时流式传输数据(如pg_stat_replication视图中streaming的状态所示)的服务器。 + 将有一个或多个活动的同步备库,在这些备库确认收到它们的数据之后,等待提交的事务将被允许继续下去。 + 同步备库是那些名字出现在这个列表中,并且当前已连接并且正在实时流式传输数据(如pg_stat_replication视图中streaming的状态所示)的服务器。 指定多于一台同步备库可以得到非常高的可用性并且能防止数据丢失。 用于这一目的的备库的名称是其application_name设置,它在备库的连接信息中设置。 - 在物理复制备库的情况下,这应该被设置在primary_conninfo设置中,如果设置了,默认是的设置,否则为 walreceiver。 - 对于逻辑复制,可以在订阅的连接信息中设置。对于其他复制流消费者,请参考其文档。 + 对于物理复制备库,应在 primary_conninfo 设置中指定。 + 若已设置 ,则默认使用其值;否则默认值为 walreceiver。 + 对于逻辑复制,可以在订阅的连接信息中设置,默认值为订阅名称。 + 对于其他复制流消费者,请参考其文档。 @@ -4181,15 +3871,17 @@ HINT: If it is safe for all REPLICATION users to use this library as an output ANY num_sync ( standby_name [, ...] ) standby_name [, ...] - 其中num_sync是事务需要等待其回复的同步备库的数量,standby_name是一个备库的名称。FIRST以及ANY指定从所列服务器中选取同步备库的方法。 + 其中num_sync是事务需要等待其回复的同步备库的数量,standby_name是一个备库的名称。 + num_sync 必须是大于零的整数。 + FIRST以及ANY指定从所列服务器中选取同步备库的方法。 - 关键词FIRST加上num_sync指定一种基于优先的同步复制,并且会让事务提交等待,直到它们的WAL记录被复制到基于优先级选择的num_sync台同步备库上为止。例如,设置FIRST 3 (s1, s2, s3, s4)将导致每次提交都等待来自三台较高优先级的备库的答复,这三台备库将从备库s1s2s3以及s4中选出。在该列表中出现较早的备库将被给予较高的优先级,并且将被考虑为同步备库。列表中出现的其他备库表示潜在的同步备库。如果当前的任何同步备库因为某种原因断开连接,它将立刻被下一个最高优先级的备库替代。关键词FIRST是可选的。 + 关键词FIRST加上num_sync指定一种基于优先级的同步复制,并且会让事务提交等待,直到它们的WAL记录被复制到基于优先级选择的num_sync台同步备库上为止。例如,设置FIRST 3 (s1, s2, s3, s4)将导致每次提交都等待来自三台较高优先级的备库的答复,这三台备库将从备库s1s2s3以及s4中选出。在该列表中出现较早的备库将被给予较高的优先级,并且将被考虑为同步备库。列表中出现的其他备库表示潜在的同步备库。如果当前的任何同步备库因为某种原因断开连接,它将立刻被下一个最高优先级的备库替代。关键词FIRST是可选的。 - 关键词ANY加上num_sync指定一种基于规定数量的同步复制,并且会让事务提交等待,直到它们的WAL记录被复制到所列出备库中的至少num_sync台上为止。例如,设置ANY 3 (s1, s2, s3, s4)将导致每次提交会在收到s1s2s3以及s4中任意三台备库的回答后立刻继续下去。 + 关键词ANY加上num_sync指定一种基于法定人数的同步复制,并且会让事务提交等待,直到它们的WAL记录被复制到所列出备库中的至少num_sync台上为止。例如,设置ANY 3 (s1, s2, s3, s4)将导致每次提交会在收到s1s2s3以及s4中任意三台备库的回答后立刻继续下去。 @@ -4215,7 +3907,7 @@ ANY num_sync ( 参数设置为localoff。 + 如果这里没有指定同步备库名称,那么不启用同步复制并且事务提交将不会等待复制。这是默认的配置。即便当同步复制被启用时,个体事务也可以被配置为不等待复制,做法是将参数设置为localoff @@ -4232,16 +3924,16 @@ ANY num_sync ( pg_replication_slot_advance、 + pg_logical_slot_get_changes和 + pg_logical_slot_peek_changes + 将阻塞,直到synchronized_standby_slots中列出的所有物理槽都确认接收到了 WAL。 synchronized_standby_slots中物理复制槽对应的备库必须配置 @@ -4353,9 +4045,7 @@ ANY num_sync ( num_sync ( num_sync ( )。 - 默认为"关闭"。 此参数只能在postgresql.conf文件或服务器命令行中设置。 - 如果在 WAL 接收进程运行时更改此参数,则该进程将发出关机的信号,并预期使用新设置重新启动。 - + 指定在未使用配置要使用的永久复制槽时,WAL 接收进程是否应在远程实例上创建临时复制槽。默认值为 off。此参数只能在postgresql.conf文件中或服务器命令行上设置。如果在 WAL 接收进程运行时更改此参数,则会向该进程发送信号使其关闭,并预期它使用新设置重新启动。 @@ -4411,9 +4095,9 @@ ANY num_sync ( pg_stat_replication视图看到。 - 备库将报告它已经写入的上一个预写式日志位置、它已经刷到磁盘的上一个位置以及它已经应用的最后一个位置。 + 备库将报告最后写入的预写日志位置、最后刷盘的位置以及最后应用的位置。 这个参数的值是报告之间的最大时间量。 - 每次写入或刷出位置改变时会发送状态更新,或者按这个参数的指定的频度发送,如果设置为非零值。 + 每次写入或刷盘位置改变时会发送状态更新,或者按这个参数的指定的频度发送,如果设置为非零值。 在其他情况下发送更新时忽略此参数;例如,当现有的WAL处理完成或当synchronous_commit设置为remote_apply时。 因此,应用位置可能比真实位置略微滞后。 如果指定值时没有单位,则以秒为单位。 @@ -4433,7 +4117,7 @@ ANY num_sync ( num_sync ( + + recovery_min_apply_delay (integer) recovery_min_apply_delay 配置参数 - - 默认情况下,备库会尽快恢复来自于发送服务器的 WAL 记录。有一份数据的延时拷贝是有用的,它能提供机会纠正数据丢失错误。 - 这个参数允许你将恢复延迟一段指定的时间量。 - 例如,如果你设置这个参数为5min,对于一个事务提交,只有当备库上的系统时钟超过主库报告的提交时间至少 5分钟时,备库才会重放该事务。 - 如果指定值时没有单位,则以毫秒为单位。默认为0,不增加延迟。 + 默认情况下,备库会尽快恢复来自发送服务器的 WAL 记录。保留一份延迟的数据副本可能很有用,因为它提供了纠正数据丢失错误的机会。此参数允许将恢复延迟指定的时间。例如,将此参数设置为 5min 时,只有当备库系统时间比主库报告的提交时间至少晚五分钟,备库才会重放各事务的提交。如果没有指定单位,则以毫秒计。默认值为零,不增加延迟。 - - 有可能服务器之间的复制延迟会超过这个参数的值,在这种情况下则不会增加延迟。 - 注意延迟是根据主库上写 WAL 的时间戳以及备库上的当前时间来计算。 - 由于网络延迟或者级联复制配置导致的传输延迟可能会显著地减少实际等待时间。 - 如果主库和备库上的系统时钟不同步,这会导致恢复比预期的更早应用记录。 - 但这不是一个主要问题,因为这个参数有用的设置比服务器之间的典型事件偏差要大得多。 + 服务器之间的复制延迟可能超过此参数的值,这种情况下不会增加延迟。注意,延迟根据主库写入的 WAL 时间戳与备库当前时间之差计算。网络延迟或级联复制配置导致的传输延迟,可能显著缩短实际等待时间。如果主库和备库的系统时钟不同步,恢复时可能比预期更早应用记录;但这通常不是主要问题,因为此参数的实用取值远大于服务器间常见的时间偏差。 - - 只有在事务提交的 WAL 记录上才会发生延迟。其他记录还是会被尽可能快地重放,这不会成为问题,因为 MVCC 可见性规则确保了在对应的提交记录被应用之前它们的效果不会被看到。 + 延迟仅发生在事务提交的 WAL 记录上。其他记录会尽快重放;这不会造成问题,因为 MVCC 可见性规则确保在对应提交记录被应用之前,它们的效果不会可见。 - - 一旦恢复中的数据库已经达到一致状态,延迟就会产生,直到备库被提升或者触发。在那之后,备库将会结束恢复并且不再等待。 + 恢复中的数据库达到一致状态后开始延迟,直到备库被提升或触发。此后,备库会结束恢复,不再等待。 - - WAL记录必须保留在备库上,直到准备好应用。因此,较长的延迟将导致WAL文件的积累增加,增加备库的pg_wal目录的磁盘空间需求。 + WAL 记录必须保留在备库上,直到可以应用它们。因此,更长的延迟会导致更多 WAL 文件积压,增加备库 pg_wal 目录所需的磁盘空间。 - - 这个参数的目的是和物理流复制部署一起使用,但是,如果指定了该参数,除了崩溃恢复之外所有的情况下都会遵守它。 - 使用这个特性也会让hot_standby_feedback被延迟,这可能导致主库的膨胀,两者一起使用时要小心。 - + 此参数旨在用于流式物理复制部署;不过,只要指定了此参数,它就会在除崩溃恢复以外的所有情况下生效。使用此功能也会延迟 hot_standby_feedback,可能导致主库膨胀;同时使用两者时应谨慎。 - 当synchronous_commit被设置为remote_apply时,同步复制会受到这个设置的影响,每一个COMMIT都需要等待被应用。 + 当 synchronous_commit 设置为 remote_apply 时,同步复制会受到此设置影响;每个 COMMIT 都必须等待提交被应用。 - - - 这个参数只能在postgresql.conf文件中或通过服务器命令行进行设置。 - - - + + + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 + + + - + sync_replication_slots (boolean) sync_replication_slots配置参数 @@ -4558,53 +4226,8 @@ ANY num_sync ( - createrole_self_grant (string) - - createrole_self_grant配置参数 - - - - - 如果一个拥有CREATEROLE但不拥有SUPERUSER权限的用户创建了角色,并且此选项被设置为非空值,则新创建的角色将以指定选项授予创建者。 - 该值必须是setinherit或它们的逗号分隔列表。默认值为空字符串,这会禁用此功能。 - - - 此选项的目的是允许非超级用户的CREATEROLE用户自动继承或自动获得对新创建角色执行SET ROLE的能力。 - 由于CREATEROLE用户始终会隐式获得其所创建角色的ADMIN OPTION,因此该用户总是可以通过执行GRANT语句达到相同效果,但自动授予在可用性上更方便。 - 超级用户会自动继承每个角色的权限,并且始终可以切换到任何角色;此设置可用于为CREATEROLE用户提供类似行为。 - - - - - event_triggers (boolean) - - event_triggers配置参数 - - - - - 允许临时禁用事件触发器的执行,以便对有故障的事件触发器进行故障排查和修复。 - 将其设置为false会禁用所有事件触发器;设置为true则允许所有事件触发器触发,这也是默认值。 - 只有超级用户和具有适当SET权限的用户才能更改此设置。 - - - - - restrict_nonsystem_relation_kind (string) - - restrict_nonsystem_relation_kind配置参数 - - - - - 设置禁止访问非系统关系的关系类型。该值采用关系类型的逗号分隔列表形式。 - 目前支持的关系类型是viewforeign-table。 - - - @@ -4614,11 +4237,7 @@ ANY num_sync ( @@ -4634,7 +4253,7 @@ ANY num_sync ( ),从而实际上限制了服务器上可以创建多少逻辑复制订阅。 将其设置为低于当前正在跟踪的复制源数量(体现在pg_replication_origin_status中)会阻止服务器启动。 默认值为 10。该参数只能在服务器启动时设置。 - max_active_replication_origins至少必须设置为订阅者上要添加的订阅数量,再加上一些用于表同步的预留。 + max_active_replication_origins至少必须设置为订阅者上要添加的订阅数量,再加上一些用于表同步的预留。 @@ -4649,16 +4268,15 @@ ANY num_sync ( num_sync ( num_sync ( num_sync ( + + enable_bitmapscan (boolean) - 位图扫描 + 位图扫描 - enable_bitmapscan配置参数 + enable_bitmapscan 配置参数 - - 允许或禁止查询规划器使用位图扫描计划类型。默认值是on。 + 启用或禁用查询规划器对位图扫描计划类型的使用。默认值为 on - - + + - + enable_distinct_reordering (boolean) enable_distinct_reordering配置参数 @@ -4797,22 +4413,22 @@ ANY num_sync ( + + enable_gathermerge (boolean) - enable_gathermerge配置参数 + enable_gathermerge 配置参数 - - 启用或者禁用查询规划器对收集归并计划类型的使用。默认值是on。 + 启用或禁用查询规划器对收集归并计划类型的使用。默认值为 on - - + + - + enable_group_by_reordering (boolean) enable_group_by_reordering配置参数 @@ -4827,89 +4443,90 @@ ANY num_sync ( + + enable_hashagg (boolean) - enable_hashagg配置参数 + enable_hashagg 配置参数 - - 允许或禁用查询规划器使用哈希聚合计划类型。默认值是on。 + 启用或禁用查询规划器对哈希聚合计划类型的使用。默认值为 on - + + enable_hashjoin (boolean) - enable_hashjoin配置参数 + enable_hashjoin 配置参数 - - 允许或禁止查询规划器使用哈希连接计划类型。默认值是on。 + 启用或禁用查询规划器对哈希连接计划类型的使用。默认值为 on - + + enable_incremental_sort (boolean) enable_incremental_sort 配置参数 - - 启用或禁用查询规划器对增量排序步骤的使用。默认为on。 + 启用或禁用查询规划器对增量排序步骤的使用。默认值为 on - + + + + enable_indexscan (boolean) - 索引扫描 + 索引扫描 - enable_indexscan配置参数 + enable_indexscan 配置参数 - - 允许或禁止查询规划器使用索引扫描计划类型。默认值是on。 + 启用或禁用查询规划器对索引扫描和仅索引扫描计划类型的使用。默认值为 on。另请参见 - enable_indexonlyscan (boolean) - enable_indexonlyscan配置参数 + enable_indexonlyscan 配置参数 - - 允许或禁止查询规划器使用只用索引扫描计划类型(见)。默认值是on。 + 启用或禁用查询规划器对仅索引扫描计划类型的使用(参见 )。默认值为 on。还必须启用 ,查询规划器才会考虑仅索引扫描。 - + + enable_material (boolean) - enable_material配置参数 + enable_material 配置参数 @@ -4920,8 +4537,9 @@ ANY num_sync ( + + enable_memoize (boolean) enable_memoize 配置参数 @@ -4938,26 +4556,27 @@ ANY num_sync ( + + enable_mergejoin (boolean) - enable_mergejoin配置参数 + enable_mergejoin 配置参数 - - 允许或禁止查询规划器使用归并连接计划类型。默认值是on。 + 启用或禁用查询规划器对归并连接计划类型的使用。默认值为 on - + + enable_nestloop (boolean) - enable_nestloop配置参数 + enable_nestloop 配置参数 @@ -4983,17 +4602,17 @@ ANY num_sync ( + + enable_parallel_hash (boolean) - enable_parallel_hash配置参数 + enable_parallel_hash 配置参数 - - 允许或禁止查询规划器对并行哈希使用哈希连接计划类型。如果哈希连接计划也没有启用,这个参数没有效果。默认值是on。 + 启用或禁用查询规划器对使用并行哈希的哈希连接计划类型的使用。如果没有同时启用哈希连接计划,此参数不起作用。默认值为 on @@ -5013,41 +4632,37 @@ ANY num_sync ( + + + + enable_partitionwise_join (boolean) - enable_partitionwise_join配置参数 + enable_partitionwise_join 配置参数 - - 允许或者禁止查询规划器使用面向分区的连接,这使得分区表之间的连接以连接匹配的分区的方式来执行。 - 面向分区的连接当前只适用于连接条件包括所有分区键的情况,连接条件必须是相同的数据类型并且子分区集合要1对1匹配。 - 由于面向分区的连接规划在规划期间会使用可观的CPU时间和内存,所以默认值为off。 + 启用或禁用查询规划器对分区连接的使用,使分区表之间的连接可以通过连接相匹配的分区来完成。分区连接目前仅适用于连接条件包含所有分区键的情况;这些分区键必须具有相同的数据类型,并且子分区集合必须一一匹配。启用此设置后,最终计划中内存用量受 work_mem 限制的节点数量可能随所扫描分区的数量线性增加。这可能大幅增加查询执行期间的总内存消耗。查询规划在内存和 CPU 方面的开销也会显著增加。默认值为 off - enable_partitionwise_aggregate (boolean) - enable_partitionwise_aggregate配置参数 + enable_partitionwise_aggregate 配置参数 - - 启用或禁用查询规划器使用分区分组或聚合的功能,该功能允许在分区表上分别对每个分区执行分组或聚合操作。 - 如果GROUP BY子句不包括分区键,那么只能在每个分区的基础上执行部分聚合,并且必须在稍后进行最终化处理。 - 由于分区分组或聚合在规划期间可能会使用更多的CPU时间和内存,因此默认情况下为off。 + 启用或禁用查询规划器对分区分组或聚合的使用,使分区表上的分组或聚合可以在各个分区上分别执行。如果 GROUP BY 子句不包含分区键,则只能在各分区上执行部分聚合,随后还必须进行最终处理。启用此设置后,最终计划中内存用量受 work_mem 限制的节点数量可能随所扫描分区的数量线性增加。这可能大幅增加查询执行期间的总内存消耗。查询规划在内存和 CPU 方面的开销也会显著增加。默认值为 off - - + + - + enable_presorted_aggregate (boolean) enable_presorted_aggregate配置参数 @@ -5545,7 +5160,7 @@ ANY num_sync ( 包括在普通日志项中。只有可打印 ASCII 字符能被使用在application_name之中。其他字符将被替换为问号(?)。 + application_name可以是任意小于NAMEDATALEN个字符(标准编译中是 64 个字符)的字符串。应用通常在连接服务器时设置此值。该名称将被显示在pg_stat_activity视图中并被包括在 CSV 日志项中。它也会被通过包括在普通日志项中。只有可打印 ASCII 字符能被使用在application_name之中。其他字符将被替换为C 风格的十六进制转义序列。 @@ -6556,7 +6171,7 @@ local0.* /var/log/postgresql 出于向后兼容性考虑,onofftruefalseyesno10仍然受支持。 - 正向值等价于指定receiptauthentication和 + 表示启用的值等价于指定receiptauthenticationauthorization选项。 @@ -6568,7 +6183,7 @@ local0.* /var/log/postgresql - 某些客户端程序(例如psql)在要求密码时会尝试连接两次,因此重复的收到连接消息并不一定表示一个错误。 + 某些客户端程序(例如psql)在判断是否需要密码时会尝试连接两次,因此重复的收到连接消息并不一定表示一个错误。 @@ -6717,6 +6332,11 @@ local0.* /var/log/postgresql 远程主机名或 IP 地址 + + %L + 本地地址(客户端所连接的服务器 IP 地址) + + %b @@ -6786,13 +6406,13 @@ local0.* /var/log/postgresql %v - 虚拟事务 ID (backendID/localXID) + 虚拟事务 ID (procNumber/localXID);参见 %x - 事务 ID (如果未分配则为 0) + 事务 ID (如果未分配则为 0);参见 @@ -6811,7 +6431,7 @@ local0.* /var/log/postgresql %% - 纯文字 % + 字面字符 % @@ -6845,7 +6465,7 @@ FROM pg_stat_activity; - Syslog产生自己的时间戳和进程 ID 信息,因此如果你记录到syslog你可能不希望包括哪些转义。 + Syslog产生自己的时间戳和进程 ID 信息,因此如果你记录到syslog你可能不希望包括那些转义。 @@ -6886,6 +6506,21 @@ log_line_prefix = '%m [%p] %q%u@%d/%a ' + + log_lock_failures (boolean) + + log_lock_failures配置参数 + + + + + 控制当获取锁失败时是否生成详细日志消息。这有助于分析锁失败的原因。 + 目前,仅支持由于SELECT NOWAIT导致的锁失败。 + 默认值为off。只有超级用户和具有适当SET权限的用户才能更改此设置。 + + + + log_recovery_conflict_waits (boolean) @@ -6907,21 +6542,6 @@ log_line_prefix = '%m [%p] %q%u@%d/%a ' - - log_lock_failures (boolean) - - log_lock_failures配置参数 - - - - - 控制当获取锁失败时是否生成详细日志消息。这有助于分析锁失败的原因。 - 目前,仅支持由于SELECT NOWAIT导致的锁失败。 - 默认值为off。只有超级用户和具有适当SET权限的用户才能更改此设置。 - - - - log_parameter_max_length (integer) @@ -7395,12 +7015,12 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 为不同目的设置标识这个数据库集簇(实例)的名称。此集簇名称出现在该集簇中所有服务器进程的进程标题中。 - 此外,它还是备库连接的默认应用名称。(参见 .) + 设置一个用于各种目的、标识此数据库集簇(实例)的名称。集簇名称会出现在此集簇所有服务器进程的进程标题中。 + 此外,它还是备库连接的默认应用名称(参见)。 - 这个名称可以是任何长度不超过NAMEDATALEN个字符(在标准编译中是 64字符)的任何字符串。只有可打印的 ASCII 字符能被用在cluster_name值中。其他字符将被替换为问号(?)。如果这个参数被设置为空字符串''(也是默认值),将不会显示名称。这个参数只能在服务器启动时设置。 + 这个名称可以是任何长度少于NAMEDATALEN个字符(在标准编译中是 64字符)的任何字符串。只有可打印的 ASCII 字符能被用在cluster_name值中。其他字符将被替换为C 风格的十六进制转义序列。如果这个参数被设置为空字符串''(也是默认值),将不会显示名称。这个参数只能在服务器启动时设置。 @@ -7502,41 +7122,39 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 启用基于成本的清理延迟计时(参见)。 - 默认情况下该参数关闭,因为它需要反复查询操作系统当前时间,在某些平台上可能带来显著开销。 - 你可以使用pg_test_timing来衡量系统上的计时开销。 - 基于成本的清理延迟计时信息会显示在pg_stat_progress_vacuum、 - pg_stat_progress_analyze中, - 也会显示在带有VERBOSE选项的VACUUMANALYZE输出中, - 并且当设置了时,autovacuum 还会为自动清理和自动分析记录这些信息。 - 只有超级用户和具有适当SET权限的用户才能更改此设置。 + 启用基于代价的清理延迟计时(参见)。 + 默认情况下该参数关闭,因为它需要反复查询操作系统当前时间,在某些平台上可能带来显著开销。 + 你可以使用 工具来衡量系统上的计时开销。 + 基于代价的清理延迟计时信息会显示在pg_stat_progress_vacuum、 + pg_stat_progress_analyze中, + 也会显示在带有VERBOSE选项的输出中, + 并且当设置了时,autovacuum 还会为自动清理和自动分析记录这些信息。 + 只有超级用户和具有适当SET权限的用户才能更改此设置。 - track_io_timing (boolean) - track_io_timing配置参数 + track_io_timing 配置参数 - - 启用数据库I/O调用的计时。 默认情况下,此参数处于关闭状态,因为它将重复查询操作系统的当前时间,这可能会在某些平台上造成显著的开销。 您可以使用工具来测量系统上计时的开销。 - I/O计时信息显示在 - pg_stat_database、 - - pg_stat_io(当object - 不是wal时)、 - pg_stat_get_backend_io()函数的输出中(当 - object不是wal时)、使用 - BUFFERS选项时的输出中、 - 使用VERBOSE选项时的输出中、 - autovacuum 执行自动清理和自动分析时(当设置了),以及中。 - 只有超级用户和具有适当SET权限的用户才能更改此设置。 + 启用数据库 I/O 等待的计时。此参数默认关闭,因为计时需要反复向操作系统查询 + 当前时间,在某些平台上可能会产生显著开销。可以使用 工具 + 测量本系统上的计时开销。I/O 计时信息会显示在 + pg_stat_database 中、 + pg_stat_io 中(当 object 不是 wal 时)、 + pg_stat_get_backend_io() 函数的输出中 + (当 object 不是 wal 时)、 + 使用 BUFFERS 选项的 输出中、 + 使用 VERBOSE 选项的 输出中, + autovacuum 也会在执行自动清理和自动分析时输出这些信息 + (需设置 ), + 同样提供这些信息。只有超级用户和具有适当 + SET 权限的用户可以更改此设置。 @@ -7551,18 +7169,8 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 启用WAL I/O调用的定时。此参数默认关闭,因为它将重复查询操作系统的当前时间, - 这可能会在某些平台上造成显著的开销。 - 您可以使用pg_test_timing工具来 - 测量系统上定时的开销。 - I/O定时信息显示在 - pg_stat_io中(针对 - object wal),以及 - - pg_stat_get_backend_io()函数的输出中(针对 - object wal)。 - 只有超级用户和具有适当SET权限的用户才能更改此设置。 - + 启用 WAL I/O 等待的计时。此参数默认关闭,因为它会反复向操作系统查询当前时间,可能在某些平台上产生显著开销。可以使用 pg_test_timing 工具测量系统上的计时开销。I/O 计时信息显示在 pg_stat_ioobjectwal 的行,以及 pg_stat_get_backend_io() 函数输出中 objectwal 的行。只有超级用户和具有适当 SET 权限的用户才能更改此设置。 + @@ -7657,7 +7265,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 确认只有一个查询标识符被计算和显示,如果一个查询标识符已经被计算,扩展计算标识符将抛出一个错误。 + 为确保只有一个查询标识符被计算和显示,计算查询标识符的扩展在查询标识符已被计算时应当抛出一个错误。 @@ -7706,19 +7314,19 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - Vacuuming + 清理 - 自动清理 + 清理 配置参数 - 这些参数控制 vacuuming 的行为。有关 vacuum 的目的和职责的更多信息,请参阅。 + 这些参数控制清理的行为。有关清理的目的和职责的更多信息,请参阅 - 自动 Vacuuming + 自动清理 这些设置控制autovacuum特性的行为。详情请参考 @@ -7745,7 +7353,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 注意即使该参数被禁用,系统也会在需要防止事务ID回卷时发起清理进程。详情请见。 + 注意即使该参数被禁用,系统也会在需要防止事务ID回卷时发起自动清理进程。详情请见 @@ -7777,7 +7385,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 指定能同时运行的自动清理进程(除了自动清理启动器之外)的最大数量。默认值为3。该参数只能在服务器启动时设置。 + 指定能同时运行的自动清理进程(除了自动清理启动器之外)的最大数量。默认值为3。该参数只能在postgresql.conf文件或服务器命令行中设置。 请注意,如果该值被设置得高于,将不会产生任何效果,因为 autovacuum 工作进程是从该设置建立的槽位池中获取的。 @@ -7795,29 +7403,13 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 指定自动清理在任意给定数据库上运行的最小延迟。在每一轮中后台进程检查数据库并根据需要为数据库中的表发出VACUUMANALYZE命令。 + 指定自动清理在任意给定数据库上各次运行之间的最小间隔。在每一轮中后台进程检查数据库并根据需要为数据库中的表发出VACUUMANALYZE命令。 如果指定值时没有单位,则以秒为单位。默认值为1分钟(1min)。该参数只能在postgresql.conf文件或在服务器命令行上设置。 - - autovacuum_vacuum_max_threshold (integer) - - autovacuum_vacuum_max_threshold配置参数 - - - - - 指定在任意一个表上触发VACUUM所需更新或删除元组数的最大值,也就是对 - autovacuum_vacuum_threshold和 - autovacuum_vacuum_scale_factor计算结果所施加的上限。 - 默认值为 100,000,000 个元组。如果指定为-1,autovacuum 将不会对触发 - VACUUM所需的更新或删除元组数强制施加最大值。 - 该参数只能在postgresql.conf文件中或服务器命令行上设置;但可以通过更改表存储参数覆盖单个表的该设置。 - - - + @@ -7848,7 +7440,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; 指定在任何一个表中触发 VACUUM所需要插入的元组数。默认值为 1000 个元组。 如果指定了 -1,则autovacuum不会根据插入数量在任何表上触发 VACUUM操作。 - 此参数只能在postgresql.conf文件或服务器命令行中设置;但可以通过更改表存储参数来覆盖单个表的设置。 + 此参数只能在postgresql.conf文件或服务器命令行中设置;但可以通过更改表存储参数来覆盖单个表的设置。 @@ -7880,7 +7472,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 指定一个表尺寸的分数,在决定是否触发VACUUM时将它加到autovacuum_vacuum_threshold上。默认值为0.2(表尺寸的20%)。该参数只能在postgresql.conf文件或在服务器命令中设置。但是对个别表可以通过修改表存储参数来覆盖该设置。 + 指定一个表尺寸的分数,在决定是否触发VACUUM时将它加到autovacuum_vacuum_threshold上。默认值为0.2(表尺寸的20%)。该参数只能在postgresql.conf文件或在服务器命令中设置。但是对个别表可以通过修改表存储参数来覆盖该设置。 @@ -7896,8 +7488,9 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 指定一个要添加到autovacuum_vacuum_insert_threshold 中的表的大小的比例,在决定是否触发VACUUM时。 - 默认值为 0.2(表大小的 20%)。此参数只能在postgresql.conf文件或服务器命令行中设置;但可以通过更改表存储参数来覆盖单个表的设置。 + 指定表中未冻结页面的比例,在决定是否触发VACUUM时,将由该比例计算出的数量加到 + autovacuum_vacuum_insert_threshold上。默认值为0.2(表中未冻结页面的 20%)。 + 该参数只能在postgresql.conf文件或服务器命令行中设置;但可以通过更改表存储参数为单个表覆盖该设置。 @@ -7913,11 +7506,29 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 指定一个表尺寸的分数,在决定是否触发ANALYZE时将它加到autovacuum_analyze_threshold上。默认值为0.1(表尺寸的10%)。该参数只能在postgresql.conf文件或在服务器命令中设置。但是对个别表可以通过修改表存储参数来覆盖该设置。 + 指定一个表尺寸的分数,在决定是否触发ANALYZE时将它加到autovacuum_analyze_threshold上。默认值为0.1(表尺寸的10%)。该参数只能在postgresql.conf文件或在服务器命令中设置。但是对个别表可以通过修改表存储参数来覆盖该设置。 + + autovacuum_vacuum_max_threshold (integer) + + autovacuum_vacuum_max_threshold配置参数 + + + + + 指定在任意一个表上触发VACUUM所需更新或删除元组数的最大值,也就是对 + autovacuum_vacuum_threshold和 + autovacuum_vacuum_scale_factor计算结果所施加的上限。 + 默认值为 100,000,000 个元组。如果指定为-1,autovacuum 将不会对触发 + VACUUM所需的更新或删除元组数强制施加最大值。 + 该参数只能在postgresql.conf文件中或服务器命令行上设置;但可以通过更改表存储参数覆盖单个表的该设置。 + + + + autovacuum_freeze_max_age (integer) @@ -7986,7 +7597,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 指定用于自动VACUUM操作中的代价限制值。如果指定-1(默认值),则使用值。注意该值被按比例地分配到运行中的自动清理工作者上(如果有多个),因此每一个工作者的限制值之和不会超过这个变量中的值。该参数只能在postgresql.conf文件或在服务器命令中设置。但是对个别表可以通过修改表存储参数来覆盖该设置。 + 指定用于自动VACUUM操作中的代价限制值。如果指定-1(默认值),则使用值。注意该值被按比例地分配到运行中的自动清理工作进程上(如果有多个),因此每一个工作进程的限制值之和不会超过这个变量中的值。该参数只能在postgresql.conf文件或在服务器命令中设置。但是对个别表可以通过修改表存储参数来覆盖该设置。 @@ -8034,7 +7645,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 指定自动清理在确定优先级时所用评分中,清理 阈值分量的缩放因子。默认值为1.0。该参数只能在postgresql.conf文件中或服务器命令行上设置。更多信息见。 + 指定自动清理在确定优先级时所用评分中,清理阈值分量的缩放因子。默认值为1.0。该参数只能在postgresql.conf文件中或服务器命令行上设置。更多信息见 @@ -8050,7 +7661,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 指定自动清理在确定优先级时所用评分中,插入清理 阈值分量的缩放因子。默认值为1.0。该参数只能在postgresql.conf文件中或服务器命令行上设置。更多信息见。 + 指定自动清理在确定优先级时所用评分中,插入清理阈值分量的缩放因子。默认值为1.0。该参数只能在postgresql.conf文件中或服务器命令行上设置。更多信息见 @@ -8066,7 +7677,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 指定自动清理在确定优先级时所用评分中,分析 阈值分量的缩放因子。默认值为1.0。该参数只能在postgresql.conf文件中或服务器命令行上设置。更多信息见。 + 指定自动清理在确定优先级时所用评分中,分析阈值分量的缩放因子。默认值为1.0。该参数只能在postgresql.conf文件中或服务器命令行上设置。更多信息见 @@ -8082,7 +7693,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 设置单个自动清理工作进程在处理索引时可使用的并行工作进程最大数量。此限制只适用于索引清理(index vacuuming)和索引收尾清理(index cleanup)阶段(有关自动清理各阶段的细节,请参见)。实际可用的并行工作进程数量还会进一步受到的限制。它相当于每个自动清理工作进程上的VACUUM命令PARALLEL选项。将该值设为 0 会在自动清理期间禁用并行 清理。默认值为0。 + 设置单个自动清理工作进程在处理索引时可使用的并行工作进程最大数量。此限制只适用于索引清理(index vacuuming)和索引收尾清理(index cleanup)阶段(有关自动清理各阶段的细节,请参见)。实际可用的并行工作进程数量还会进一步受到的限制。它相当于每个自动清理工作进程上的VACUUM命令PARALLEL选项。将该值设为 0 会在自动清理期间禁用并行清理。默认值为0。 @@ -8090,6 +7701,108 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; + + 基于代价的清理延迟 + + + 执行 命令期间,系统维护一个内部计数器,记录已执行的各种 I/O 操作的估算代价。 + 当累计代价达到上限(由 vacuum_cost_limit 指定)时,执行该操作的进程会休眠一小段时间,时长由 vacuum_cost_delay 指定。 + 随后重置计数器并继续执行。 + + + + 此功能让管理员能够降低这些命令对并发数据库活动的 I/O 影响。在许多情况下,VACUUMANALYZE 等维护命令是否快速完成并不重要, + 但避免它们显著干扰系统执行其他数据库操作的能力通常很重要。基于代价的清理延迟为管理员提供了实现这一点的方法。 + + + + 对于手动执行的 VACUUM 命令,此功能默认禁用。要启用它,将 vacuum_cost_delay 变量设为非零值。 + + + + + + vacuum_cost_delay (floating point) + + vacuum_cost_delay配置参数 + + + + + 超过代价上限后,进程将休眠的时长。如果未指定单位,则以毫秒为单位。默认值为 0,表示禁用基于代价的清理延迟功能。正值会启用基于代价的清理。 + + + 使用基于代价的清理时,vacuum_cost_delay 的合适值通常很小,可能不到 1 毫秒。虽然 vacuum_cost_delay 可以设为以毫秒为单位的小数值,但较旧的平台可能无法准确计量这种延迟。在这些平台上,若要让 VACUUM 的资源用量超过延迟设为 1ms 时的水平,需要调整其他清理代价参数。尽管如此,仍应将 vacuum_cost_delay 设为平台能够稳定计量的尽可能小的值;较大的延迟没有帮助。 + + + + + + + vacuum_cost_page_hit (integer) + + vacuum_cost_page_hit配置参数 + + + + + 清理在共享缓冲区缓存中找到的缓冲区时所计入的估算代价。它表示锁定缓冲池、查找共享哈希表和扫描页内容的代价。默认值为 1。 + + + + + + + vacuum_cost_page_miss (integer) + + vacuum_cost_page_miss配置参数 + + + + + 清理必须从磁盘读取的缓冲区时所计入的估算代价。它表示锁定缓冲池、查找共享哈希表、从磁盘读取所需数据块并扫描其内容所需的工作量。默认值为 2。 + + + + + + + vacuum_cost_page_dirty (integer) + + vacuum_cost_page_dirty配置参数 + + + + + 清理操作修改原本干净的数据块时所计入的估算代价。它表示再次将脏块刷盘所需的额外 I/O。默认值为 20。 + + + + + + + vacuum_cost_limit (integer) + + vacuum_cost_limit配置参数 + + + + + 会使清理进程休眠 vacuum_cost_delay 指定时长的累计代价。默认值为 200。 + + + + + + + + 某些操作持有关键的锁,因此应尽快完成。这些操作期间不会发生基于代价的清理延迟,所以累计代价可能远超指定上限。 + 为避免此时出现无益的长时间延迟,实际延迟按 vacuum_cost_delay * accumulated_balance / vacuum_cost_limit 计算, + 但最大不超过 vacuum_cost_delay * 4。 + + + + 默认行为 @@ -8114,10 +7827,14 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 冻结 (Freezing) + 冻结 - 这些设置控制旧行版本的冻结。更多信息请参阅。 + 为了在事务 ID 回卷后仍保持正确性,PostgreSQL会将足够旧的行标记为已冻结。 + 这些行对所有事务都可见;其他事务不必检查插入这些行的 XID 就能确定其可见性。 + VACUUM负责将行标记为已冻结。以下设置控制VACUUM的冻结行为, + 应根据系统的 XID 消耗速率以及主要工作负载的数据访问模式进行调整。 + 有关事务 ID 回卷和这些参数的调优,详见 @@ -8129,7 +7846,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 当表的pg_class.relfrozenxid字段达到该设置指定的年龄时,VACUUM会执行激进扫描。激进扫描与常规VACUUM不同,它会访问每一个可能包含未冻结 XID 或 MXID 的页面,而不仅仅是那些可能包含死元组的页面。默认值是 1.5 亿个事务。尽管用户可以将该值设置为 0 到 20 亿之间的任意值,VACUUM会悄悄将有效值调整为的 95%,从而在触发防回卷 autovacuum 之前仍有机会执行一次常规手工VACUUM。更多信息请参见。 + 当表的pg_class.relfrozenxid字段达到该设置指定的年龄时,VACUUM会执行激进扫描。激进扫描与常规VACUUM不同,它会访问每一个可能包含未冻结 XID 或 MXID 的页面,而不仅仅是那些可能包含死元组的页面。默认值是 1.5 亿个事务。尽管用户可以将该值设置为 0 到 20 亿之间的任意值,VACUUM会悄悄将有效值限制为不超过的 95%,从而在触发防回卷 autovacuum 之前仍有机会执行一次常规手工VACUUM。更多信息请参见 @@ -8142,7 +7859,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 指定VACUUM在扫描表时用来决定是否冻结行版本的切断年龄(以事务计)。默认值是 5000 万个事务。尽管用户可以将该值设置为 0 到 10 亿之间的任意值,VACUUM会悄悄将有效值调整为的一半,这样强制 autovacuum 之间就不会间隔过短。更多信息请参见。 + 指定VACUUM用来决定是否触发对含有较旧 XID 的页面进行冻结的截止年龄(以事务计)。默认值是 5000 万个事务。尽管用户可以将该值设置为 0 到 10 亿之间的任意值,VACUUM会悄悄将有效值限制为不超过的一半,这样强制 autovacuum 之间就不会间隔过短。更多信息请参见 @@ -8158,7 +7875,10 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; 指定表的pg_class.relfrozenxid字段在VACUUM采取特别措施以避免系统范围事务 ID 回卷失败之前所允许达到的最大年龄(以事务计)。这是VACUUM的最后防线。失效保护通常会在防止事务 ID 回卷的 autovacuum 已经运行了一段时间后触发,但也有可能在任何VACUUM期间触发。 - 当失效保护被触发时,将不再应用任何有效的基于成本的延迟,并且会跳过进一步的非关键维护任务(例如索引 vacuum)。 + 当失效保护被触发时,将不再应用任何有效的基于代价的延迟,并且会跳过进一步的非关键维护任务(例如索引清理),而且任何正在使用的 + 缓冲区访问策略 + 都会被禁用,使 VACUUM 可以自由使用全部 + 共享缓冲区 默认值为 16 亿个事务。尽管用户可以将该值设置为 0 到 21 亿之间的任意值,VACUUM会悄悄将有效值调整为不低于的 105%。 @@ -8174,7 +7894,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 当表的pg_class.relminmxid字段达到该设置指定的年龄时,VACUUM会执行激进扫描。激进扫描与常规VACUUM不同,它会访问每一个可能包含未冻结 XID 或 MXID 的页面,而不是只扫描那些可能包含死元组的页面。默认值是 1.5 亿个 multixact。尽管用户可以将该值设置为 0 到 20 亿之间的任意值,VACUUM会悄悄将有效值调整为的 95%,从而在触发防回卷 autovacuum 之前仍有机会执行一次常规手工VACUUM。更多信息请参见。 + 当表的pg_class.relminmxid字段达到该设置指定的年龄时,VACUUM会执行激进扫描。激进扫描与常规VACUUM不同,它会访问每一个可能包含未冻结 XID 或 MXID 的页面,而不是只扫描那些可能包含死元组的页面。默认值是 1.5 亿个多事务。尽管用户可以将该值设置为 0 到 20 亿之间的任意值,VACUUM会悄悄将有效值限制为不超过的 95%,从而在触发防回卷 autovacuum 之前仍有机会执行一次常规手工VACUUM。更多信息请参见 @@ -8187,29 +7907,31 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 指定VACUUM在扫描表时用来决定是否将 multixact ID 替换为较新的事务 ID 或 multixact ID 的切断年龄(以 multixact 计)。默认值是 5000 万个 multixact。尽管用户可以将该值设置为 0 到 10 亿之间的任意值,VACUUM会悄悄将有效值调整为的一半,这样强制 autovacuum 之间就不会间隔过短。更多信息请参见。 + 指定VACUUM用来决定是否触发对含有较旧多事务 ID 的页面进行冻结的截止年龄(以多事务计)。默认值是 500 万个多事务。尽管用户可以将该值设置为 0 到 10 亿之间的任意值,VACUUM会悄悄将有效值限制为不超过的一半,这样强制 autovacuum 之间就不会间隔过短。更多信息请参见 + + - vacuum_multixact_failsafe_age (integer) - - vacuum_multixact_failsafe_age配置参数 - - - + vacuum_multixact_failsafe_age (integer) + + vacuum_multixact_failsafe_age 配置参数 + + + - 指定表的pg_class.relminmxid字段在VACUUM采取特别措施以避免系统范围 multixact ID 回卷失败之前所允许达到的最大年龄(以 multixact 计)。这是VACUUM的最后防线。失效保护通常会在防止事务 ID 回卷的 autovacuum 已经运行了一段时间后触发,但也有可能在任何VACUUM期间触发。 + 指定表的 pg_class.relminmxid 字段在 VACUUM 采取特别措施避免系统范围的多事务 ID 回卷故障之前,所能达到的最大年龄(以多事务计)。这是 VACUUM 的最后手段。失效保护通常会在防止事务 ID 回卷的自动清理已经运行一段时间后触发,但也可能在任何 VACUUM 期间触发。 - 当失效保护被触发时,将不再应用任何有效的基于成本的延迟,并且会跳过进一步的非关键维护任务(例如索引 vacuum)。 + 触发失效保护后,任何正在生效的基于代价的延迟都将不再应用,后续非必要的维护任务(例如索引清理)也会被跳过。 - 默认值为 16 亿个 multixact。尽管用户可以将该值设置为 0 到 21 亿之间的任意值,VACUUM会悄悄将有效值调整为不低于的 105%。 + 默认值为 16 亿个多事务。虽然用户可以将此值设置为 0 到 21 亿之间的任意值,VACUUM 仍会将实际生效值自动调整为不低于 的 105%。 - + vacuum_max_eager_freeze_failure_rate (floating point) @@ -8219,10 +7941,10 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 指定VACUUM在积极扫描模式下可以扫描但未能在可见性映射中设置为 all-frozen 的页面数量占整个关系总页面数的比例,超过该比例后就会禁用积极扫描。值0表示完全禁用积极扫描。默认值为0.03(3%)。 + 指定VACUUM在急切扫描模式下可以扫描但未能在可见性映射中设置为 all-frozen 的页面数量占整个关系总页面数的比例,超过该比例后就会禁用急切扫描。值0表示完全禁用急切扫描。默认值为0.03(3%)。 - 请注意,当积极扫描启用时,只有冻结失败才会计入上限,成功的冻结不会计入。成功冻结的页面在内部会被限制为关系中所有 all-visible 但未 all-frozen 页面数的 20%。对成功冻结页面设置上限有助于将成本分摊到多次常规 vacuum 中,并限制在下次积极 vacuum 之前页面再次被修改时积极冻结可能带来的浪费。 + 请注意,当急切扫描启用时,只有冻结失败才会计入上限,成功的冻结不会计入。成功冻结的页面在内部会被限制为关系中所有 all-visible 但未 all-frozen 页面数的 20%。对成功冻结页面设置上限有助于将成本分摊到多次常规清理 中,并限制在下次激进清理 之前页面再次被修改时急切冻结可能带来的浪费。 这个参数只能在postgresql.conf文件中或服务器命令行上设置; @@ -8276,7 +7998,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; search_path配置参数 - pathfor schemas + 路径用于模式 @@ -8369,7 +8091,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; default_tablespace配置参数 - tablespacedefault + 表空间默认 @@ -8474,7 +8196,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; default_transaction_isolation (enum) - transaction isolation level + 事务隔离级别 设置默认值 @@ -8497,7 +8219,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; default_transaction_read_only (boolean) - read-only transaction + 只读事务 设置默认值 @@ -8520,7 +8242,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; default_transaction_deferrable (boolean) - deferrable transaction + 可延迟事务 设置默认值 @@ -8547,7 +8269,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; transaction_isolation (enum) - transaction isolation level + 事务隔离级别 transaction_isolation配置参数 @@ -8567,7 +8289,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; transaction_read_only (boolean) - read-only transaction + 只读事务 transaction_read_only 配置参数 @@ -8587,7 +8309,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; transaction_deferrable (boolean) - deferrable transaction + 可延迟事务 transaction_deferrable 配置参数 @@ -8731,7 +8453,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; 此选项可以用于确保空闲会话不会在不合理的时间内持有锁。 - 即使没有持有重要的锁的时候,打开的事务也会防止清理最近死亡的可能只对这个事务可见的元组;所以长时间保持空闲会导致表膨胀。 + 即使没有持有重要的锁的时候,打开的事务也会防止清理最近死亡的可能只对这个事务可见的元组;所以长时间保持空闲会导致表膨胀。 详见 @@ -8807,7 +8529,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; SET XML OPTION - XML option + XML 选项 @@ -8845,6 +8567,54 @@ SET XML OPTION { DOCUMENT | CONTENT }; + + createrole_self_grant (string) + + createrole_self_grant配置参数 + + + + + 如果一个拥有CREATEROLE但不拥有SUPERUSER权限的用户创建了角色,并且此选项被设置为非空值,则新创建的角色将以指定选项授予创建者。 + 该值必须是setinherit或它们的逗号分隔列表。默认值为空字符串,这会禁用此功能。 + + + 此选项的目的是允许非超级用户的CREATEROLE用户自动继承或自动获得对新创建角色执行SET ROLE的能力。 + 由于CREATEROLE用户始终会隐式获得其所创建角色的ADMIN OPTION,因此该用户总是可以通过执行GRANT语句达到相同效果,但自动授予在可用性上更方便。 + 超级用户会自动继承每个角色的权限,并且始终可以切换到任何角色;此设置可让CREATEROLE用户对其创建的用户获得类似的行为。 + + + + + + event_triggers (boolean) + + event_triggers配置参数 + + + + + 允许临时禁用事件触发器的执行,以便对有故障的事件触发器进行故障排查和修复。 + 将其设置为false会禁用所有事件触发器;设置为true则允许所有事件触发器触发,这也是默认值。 + 只有超级用户和具有适当SET权限的用户才能更改此设置。 + + + + + + restrict_nonsystem_relation_kind (string) + + restrict_nonsystem_relation_kind配置参数 + + + + + 设置禁止访问非系统关系的关系类型。该值采用关系类型的逗号分隔列表形式。 + 目前支持的关系类型是viewforeign-table。 + + + + @@ -8893,7 +8663,7 @@ SET XML OPTION { DOCUMENT | CONTENT }; TimeZone配置参数 - time zone + 时区 @@ -8909,7 +8679,7 @@ SET XML OPTION { DOCUMENT | CONTENT }; timezone_abbreviations配置参数 - time zone names + 时区名称 @@ -8923,11 +8693,11 @@ SET XML OPTION { DOCUMENT | CONTENT }; extra_float_digits (integer) - significant digits + 有效数字 - floating-point - display + 浮点数 + 显示 extra_float_digits配置参数 @@ -8955,7 +8725,7 @@ SET XML OPTION { DOCUMENT | CONTENT }; - 此参数的含义,以及其默认值,在 PostgreSQL 12 中发生了变化; + 此参数的含义,以及其默认值,在 PostgreSQL 12 中发生了变化; 参见 以便进一步讨论。 @@ -8968,7 +8738,7 @@ SET XML OPTION { DOCUMENT | CONTENT }; client_encoding配置参数 - character set + 字符集 @@ -9328,8 +9098,12 @@ extension_control_path = 'C:\tools\postgresql;H:\my_project\share;$system' 推荐在postgresql.conf中设置该参数。 - 请注意,如果你设置该参数以便从非标准位置加载扩展,那么通常还需要把设置为相应的位置。 - + 请注意,如果设置此参数以便从非标准位置加载扩展,通常还需要将设置为相应的位置,例如: + +extension_control_path = '/usr/local/share/postgresql:$system' +dynamic_library_path = '/usr/local/lib/postgresql:$libdir' + + @@ -9362,12 +9136,12 @@ extension_control_path = 'C:\tools\postgresql;H:\my_project\share;$system' deadlock_timeout (integer) - deadlock + 死锁 期间超时 - timeout - deadlock + 超时 + 死锁 deadlock_timeout配置参数 @@ -9402,7 +9176,7 @@ extension_control_path = 'C:\tools\postgresql;H:\my_project\share;$system' - 共享锁表为每个服务器进程或预备事务预留可容纳max_locks_per_transaction 个对象(例如表)的空间;因此,在任何时刻可被锁住的不同对象数都不能超过总容量。这个参数限制每个事务使用的对象锁的平均数量;只要所有事务的锁能放入锁表中,单个事务就可以锁住更多对象。这是能被锁住的行数,那个值是没有限制的。默认值 128 已经被历史证明是足够的,但是如果你有需要在一个事务中使用很多不同表的查询(例如查询一个有很多子表的父表),你可能需要提高这个值。这个参数只能在服务器启动时设置。 + 共享锁表为每个服务器进程或预备事务预留可容纳max_locks_per_transaction 个对象(例如表)的空间;因此,在任何时刻可被锁住的不同对象数都不能超过总容量。这个参数限制每个事务使用的对象锁的平均数量;只要所有事务的锁能放入锁表中,单个事务就可以锁住更多对象。这是能被锁住的行数,那个值是没有限制的。默认值 128 已经被历史证明是足够的,但是如果你有需要在一个事务中使用很多不同表的查询(例如查询一个有很多子表的父表),你可能需要提高这个值。这个参数只能在服务器启动时设置。 @@ -9421,9 +9195,7 @@ extension_control_path = 'C:\tools\postgresql;H:\my_project\share;$system' - 共享谓词锁表跟踪在max_pred_locks_per_transaction * ( + ) 个对象(如表)上的锁。因此,在任何一个时刻,只有不超过这么多个可区分对象能够被锁住。这个参数控制为每个事务分配的对象锁的平均数量。个体事务可以锁住更多对象,数量可以和锁表中能容纳的所有事务的锁一样多。这是能被锁住的行数,那个值是没有限制的。默认值 64 已经在测试中被证明通常是足够的,但是如果你有需要在一个可串行化事务中使用很多不同表的查询(例如查询一个有很多子表的父表),你可能需要提高这个值。这个参数只能在服务器启动时设置。 + 共享谓词锁表为每个服务器进程或预备事务预留可容纳max_pred_locks_per_transaction 个对象(例如表)的空间;因此,在任何时刻可被锁住的不同对象数都不能超过总容量。这个参数限制每个事务使用的对象锁的平均数量;只要所有事务的锁能放入锁表中,单个事务就可以锁住更多对象。这是能被锁住的行数,那个值是没有限制的。默认值 64 已经被历史证明是足够的,但是如果你有会在单个可串行化事务中访问许多不同表的客户端,则可能需要提高这个值。这个参数只能在服务器启动时设置。 @@ -9493,7 +9265,7 @@ extension_control_path = 'C:\tools\postgresql;H:\my_project\share;$system' backslash_quote (enum) - stringsbackslash quotes + 字符串反斜线引号 backslash_quote配置参数 @@ -9551,7 +9323,7 @@ extension_control_path = 'C:\tools\postgresql;H:\my_project\share;$system' standard_conforming_strings (boolean) - stringsstandard conforming + 字符串标准符合 standard_conforming_strings配置参数 @@ -9994,7 +9766,7 @@ extension_control_path = 'C:\tools\postgresql;H:\my_project\share;$system' server_encoding配置参数 - character set + 字符集 diff --git a/zh/19/datatype.sgml b/zh/19/datatype.sgml index 8543cccb..b0d3f18f 100644 --- a/zh/19/datatype.sgml +++ b/zh/19/datatype.sgml @@ -354,19 +354,19 @@ smallint 2字节 小范围整数 - -32768 to +32767 + -32768 到 +32767 integer 4字节 整数的典型选择 - -2147483648 to +2147483647 + -2147483648 到 +2147483647 bigint 8字节 大范围整数 - -9223372036854775808 to +9223372036854775807 + -9223372036854775808 到 +9223372036854775807 @@ -866,9 +866,8 @@ FROM generate_series(-3.5, 3.5, 1) AS x; - 本节描述的是 PostgreSQL 特有的创建 - 自动递增列的方法。另一种方法是使用 SQL 标准的标识列特性, - 参见 。 + 本节介绍 PostgreSQL 特有的自动递增列创建方法。 + 另一种方法是使用 SQL 标准的标识列特性,参见 @@ -947,7 +946,7 @@ ALTER SEQUENCE tablename_money 类型以固定的小数精度存储货币金额; 参见 。小数精度由数据库的 设置决定。表中显示的范围假定 - 有两位小数。输入支持多种格式,包括整数和浮点文字,以及典型的 + 有两位小数。输入支持多种格式,包括整数字面量和浮点数字面量,以及典型的 货币格式,例如 '$1,000.00'。输出通常也采用 后一种形式,但会受到区域设置影响。 @@ -1373,7 +1372,7 @@ SELECT '\xDEADBEEF'::bytea;
- <type>bytea</type>文字转义字节 + <type>bytea</type>字面量中需要转义的字节 @@ -2637,7 +2636,7 @@ SELECT '2 years 15 months 100 weeks 99 hours 123456789 milliseconds'::interval; 3 years 3 mons 700 days 133:17:36.789 - 这里,周被理解为 7 days,而较小和较大的时间单位 + 这里,周按7 天计算并单独保留,而较小和较大的时间单位 则被合并并规范化了。 @@ -4076,17 +4075,16 @@ decode('HqPWTLxATMOEu2sR7jHlwg==', 'base64')::uuid xml 数据类型可用于存储 XML 数据。与把 XML 数据存储在 - text 字段中相比,它的优势在于会检查输入值是否格式 - 良好,并且提供了可执行类型安全操作的支持函数;见 - 。使用该数据类型要求安装时启用 + text 字段中相比,它的优势在于会检查输入值的良构性,并且提供了可执行类型安全操作的支持函数;见 + 。使用该数据类型要求构建时使用 configure --with-libxml - xml 类型既可以存储符合 XML 标准定义的格式良好的 + xml 类型既可以存储 XML 标准所定义的良构 文档,也可以存储 内容 片段;后者是参照 XQuery 和 XPath 数据模型中更宽松的 - document node + 文档节点 概念来定义的。粗略地说,这意味着内容片段可以拥有多个顶层元素或字符 节点。表达式 xmlvalue IS DOCUMENT @@ -4255,7 +4253,7 @@ SET xmloption TO { DOCUMENT | CONTENT }; - 是一种用户定义的数据类型,它基于另一种底层类型。根据需要,它可以有约束来限制其有效值为底层类型所允许值的一个子集。如果没有约束,它的行为就和底层类型一样 — 例如,任何适用于底层类型的操作符或函数都对该域类型有效。底层类型可以是任何内置或者用户定义的基础类型、枚举类型、数组类型、复合类型、范围类型或者另一个域。 + 是一种用户定义的数据类型,它基于另一种底层类型。根据需要,它可以有约束来限制其有效值为底层类型所允许值的一个子集。除此之外,它的行为与底层类型相同 — 例如,任何适用于底层类型的操作符或函数都对该域类型有效。底层类型可以是任何内置或者用户定义的基础类型、枚举类型、数组类型、复合类型、范围类型或者另一个域。 diff --git a/zh/19/dblink.sgml b/zh/19/dblink.sgml index 4409736f..aa940dca 100644 --- a/zh/19/dblink.sgml +++ b/zh/19/dblink.sgml @@ -65,8 +65,8 @@ -dblink_connect(text connstr) 返回 text -dblink_connect(text connname, text connstr) 返回 text +dblink_connect(text connstr) returns text +dblink_connect(text connname, text connstr) returns text @@ -128,7 +128,7 @@ dblink_connect(text connname, text connstr) 返回 text 注解 - 如果不可信用户能够访问一个尚未采用模式的安全使用方式的数据库,则应在每个会话开始时从 + 如果不受信任的用户能够访问一个尚未采用模式的安全使用方式的数据库,则应在每个会话开始时从 search_path 中移除公共可写模式。例如,可以把 options=-csearch_path= 加到 connstr 中。这个注意事项并非 dblink 所特有;它适用于每一种执行任意 SQL 命令的接口。 @@ -139,7 +139,7 @@ dblink_connect(text connname, text connstr) 返回 text use_scram_passthrough,用于控制 dblink 是否在连接远程数据库时使用 SCRAM 透传认证。 该选项可为外部服务器或用户映射指定。用户映射的设置会覆盖外部服务器的设置。 - 使用 SCRAM 透传认证时,dblink 会使用 SCRAM 哈希后的凭据,而不是明文用户密码来连接远程服务器。 + 使用 SCRAM 透传认证时,dblink 会使用经 SCRAM Hash 处理的凭据,而不是明文用户密码来连接远程服务器。 这样可以避免在 PostgreSQL 系统目录中存储明文用户密码。关于更多细节和限制,请参见 postgres_fdw 中对应的 use_scram_passthrough @@ -174,10 +174,10 @@ SELECT dblink_connect('myconn', 'dbname=postgres options=-csearch_path='); OK (1 row) --- FOREIGN DATA WRAPPER functionality --- Note: local connections that don't use SCRAM pass-through require password --- authentication for this to work properly. Otherwise, you will receive --- the following error from dblink_connect(): +-- FOREIGN DATA WRAPPER 功能 +-- 注意:要使本例正常工作,不使用 SCRAM 透传的本地连接必须要求密码认证。 +-- 否则,dblink_connect() 将报告 +-- 以下错误: -- ERROR: password is required -- DETAIL: Non-superuser cannot connect if the server does not request a password. -- HINT: Target server's authentication method must be changed. @@ -240,8 +240,8 @@ DROP SERVER fdtest; -dblink_connect_u(text connstr) 返回 text -dblink_connect_u(text connname, text connstr) 返回 text +dblink_connect_u(text connstr) returns text +dblink_connect_u(text connname, text connstr) returns text @@ -261,7 +261,7 @@ dblink_connect_u(text connname, text connstr) 返回 text 因此,dblink_connect_u() 在初始安装时会撤销 PUBLIC 的全部权限,从而除了超级用户之外无法调用它。 在某些情况下,可能适合向被认为可信的特定用户授予 - EXECUTE 权限,但必须谨慎操作。还建议服务器用户的任何 + dblink_connect_u()EXECUTE 权限,但必须谨慎操作。还建议服务器用户的任何 ~/.pgpass 文件不要包含指定通配主机名的记录。 @@ -288,8 +288,8 @@ dblink_connect_u(text connname, text connstr) 返回 text -dblink_disconnect() 返回 text -dblink_disconnect(text connname) 返回 text +dblink_disconnect() returns text +dblink_disconnect(text connname) returns text @@ -361,9 +361,9 @@ SELECT dblink_disconnect('myconn'); -dblink(text connname, text sql [, bool fail_on_error]) 返回 setof record -dblink(text connstr, text sql [, bool fail_on_error]) 返回 setof record -dblink(text sql [, bool fail_on_error]) 返回 setof record +dblink(text connname, text sql [, bool fail_on_error]) returns setof record +dblink(text connstr, text sql [, bool fail_on_error]) returns setof record +dblink(text sql [, bool fail_on_error]) returns setof record @@ -440,7 +440,7 @@ SELECT * WHERE proname LIKE 'bytea%'; - FROM 子句中的 alias 部分必须指定该函数将返回的列名和类型。(在别名中指定列名实际上是标准 SQL 语法,但指定列类型则是 + FROM 子句中的 别名 部分必须指定该函数将返回的列名和类型。(在别名中指定列名实际上是标准 SQL 语法,但指定列类型则是 PostgreSQL 的扩展。)这样系统才能在尝试执行该函数之前,就知道 * 应展开成什么,以及 WHERE 子句中的 proname 指的是什么。运行时,如果远程数据库返回的实际查询结果与 @@ -560,9 +560,9 @@ SELECT * FROM dblink('myconn', 'SELECT proname, prosrc FROM pg_proc') -dblink_exec(text connname, text sql [, bool fail_on_error]) 返回 text -dblink_exec(text connstr, text sql [, bool fail_on_error]) 返回 text -dblink_exec(text sql [, bool fail_on_error]) 返回 text +dblink_exec(text connname, text sql [, bool fail_on_error]) returns text +dblink_exec(text connstr, text sql [, bool fail_on_error]) returns text +dblink_exec(text sql [, bool fail_on_error]) returns text @@ -640,7 +640,7 @@ SELECT dblink_connect('dbname=dblink_test_standby'); OK (1 row) -SELECT dblink_exec('INSERT INTO foo VALUES (21, ''z'', ''{"a0","b0","c0"}'');'); +SELECT dblink_exec('insert into foo values(21, ''z'', ''{"a0","b0","c0"}'');'); dblink_exec ----------------- INSERT 943366 1 @@ -652,13 +652,13 @@ SELECT dblink_connect('myconn', 'dbname=regression'); OK (1 row) -SELECT dblink_exec('myconn', 'INSERT INTO foo VALUES (21, ''z'', ''{"a0","b0","c0"}'');'); +SELECT dblink_exec('myconn', 'insert into foo values(21, ''z'', ''{"a0","b0","c0"}'');'); dblink_exec ------------------ INSERT 6432584 1 (1 row) -SELECT dblink_exec('myconn', 'INSERT INTO pg_class VALUES (''foo'')',false); +SELECT dblink_exec('myconn', 'insert into pg_class values (''foo'')',false); NOTICE: sql error DETAIL: ERROR: null value in column "relnamespace" violates not-null constraint @@ -687,8 +687,8 @@ DETAIL: ERROR: null value in column "relnamespace" violates not-null constrain -dblink_open(text cursorname, text sql [, bool fail_on_error]) 返回 text -dblink_open(text connname, text cursorname, text sql [, bool fail_on_error]) 返回 text +dblink_open(text cursorname, text sql [, bool fail_on_error]) returns text +dblink_open(text connname, text cursorname, text sql [, bool fail_on_error]) returns text @@ -801,8 +801,8 @@ SELECT dblink_open('foo', 'SELECT proname, prosrc FROM pg_proc'); -dblink_fetch(text cursorname, int howmany [, bool fail_on_error]) 返回 setof record -dblink_fetch(text connname, text cursorname, int howmany [, bool fail_on_error]) 返回 setof record +dblink_fetch(text cursorname, int howmany [, bool fail_on_error]) returns setof record +dblink_fetch(text connname, text cursorname, int howmany [, bool fail_on_error]) returns setof record @@ -944,8 +944,8 @@ SELECT * FROM dblink_fetch('foo', 5) AS (funcname name, source text); -dblink_close(text cursorname [, bool fail_on_error]) 返回 text -dblink_close(text connname, text cursorname [, bool fail_on_error]) 返回 text +dblink_close(text cursorname [, bool fail_on_error]) returns text +dblink_close(text connname, text cursorname [, bool fail_on_error]) returns text @@ -1050,7 +1050,7 @@ SELECT dblink_close('foo'); -dblink_get_connections() 返回 text[] +dblink_get_connections() returns text[] @@ -1066,7 +1066,7 @@ dblink_get_connections() 返回 text[] 返回值 - 返回一个包含连接名称的 text 数组;如果没有,则返回 NULL。 + 返回包含连接名称的文本数组;如果没有连接,则返回 NULL。 @@ -1095,7 +1095,7 @@ SELECT dblink_get_connections(); -dblink_error_message(text connname) 返回 text +dblink_error_message(text connname) returns text @@ -1166,7 +1166,7 @@ SELECT dblink_error_message('dtest1'); -dblink_send_query(text connname, text sql) 返回 int +dblink_send_query(text connname, text sql) returns int @@ -1241,7 +1241,7 @@ SELECT dblink_send_query('dtest1', 'SELECT * FROM foo WHERE f1 < 3'); -dblink_is_busy(text connname) 返回 int +dblink_is_busy(text connname) returns int @@ -1303,8 +1303,8 @@ SELECT dblink_is_busy('dtest1'); -dblink_get_notify() 返回 setof (notify_name text, be_pid int, extra text) -dblink_get_notify(text connname) 返回 setof (notify_name text, be_pid int, extra text) +dblink_get_notify() returns setof (notify_name text, be_pid int, extra text) +dblink_get_notify(text connname) returns setof (notify_name text, be_pid int, extra text) @@ -1383,7 +1383,7 @@ SELECT * FROM dblink_get_notify(); -dblink_get_result(text connname [, bool fail_on_error]) 返回 setof record +dblink_get_result(text connname [, bool fail_on_error]) returns setof record @@ -1529,7 +1529,7 @@ contrib_regression=# SELECT * FROM dblink_get_result('dtest1') AS t1(f1 int, f2 -dblink_cancel_query(text connname) 返回 text +dblink_cancel_query(text connname) returns text @@ -1592,7 +1592,7 @@ SELECT dblink_cancel_query('dtest1'); -dblink_get_pkey(text relname) 返回 setof dblink_pkey_results +dblink_get_pkey(text relname) returns setof dblink_pkey_results @@ -1681,7 +1681,7 @@ dblink_build_sql_insert(text relname, int2vector primary_key_attnums, integer num_primary_key_atts, text[] src_pk_att_vals_array, - text[] tgt_pk_att_vals_array) 返回 text + text[] tgt_pk_att_vals_array) returns text @@ -1750,7 +1750,7 @@ dblink_build_sql_insert(text relname, 返回值 - 以 text 形式返回所请求的 SQL 语句。 + 以文本形式返回所请求的 SQL 语句。 @@ -1797,7 +1797,7 @@ SELECT dblink_build_sql_insert('foo', '1 2', 2, '{"1", "a"}', '{"1", "b''a"}'); dblink_build_sql_delete(text relname, int2vector primary_key_attnums, integer num_primary_key_atts, - text[] tgt_pk_att_vals_array) 返回 text + text[] tgt_pk_att_vals_array) returns text @@ -1857,7 +1857,7 @@ dblink_build_sql_delete(text relname, 返回值 - 以 text 形式返回所请求的 SQL 语句。 + 以文本形式返回所请求的 SQL 语句。 @@ -1905,7 +1905,7 @@ dblink_build_sql_update(text relname, int2vector primary_key_attnums, integer num_primary_key_atts, text[] src_pk_att_vals_array, - text[] tgt_pk_att_vals_array) 返回 text + text[] tgt_pk_att_vals_array) returns text @@ -1975,7 +1975,7 @@ dblink_build_sql_update(text relname, 返回值 - 以 text 形式返回所请求的 SQL 语句。 + 以文本形式返回所请求的 SQL 语句。 diff --git a/zh/19/ddl.sgml b/zh/19/ddl.sgml index 1f33a6b5..30f101fc 100644 --- a/zh/19/ddl.sgml +++ b/zh/19/ddl.sgml @@ -319,7 +319,7 @@ CREATE TABLE people ( - 类似地,对于分区表,如果在CREATE TABLE ... PARTITION OF中编写子列定义时未写任何GENERATED子句,则会自动从父列复制该子句。ALTER TABLE ... ATTACH PARTITION要求父列和子列在生成状态上已经匹配,但不要求它们的生成表达式相同。 + 类似地,对于分区表,如果在CREATE TABLE ... PARTITION OF中编写子列定义时未写任何GENERATED子句,则会自动从父列复制该GENERATED子句。ALTER TABLE ... ATTACH PARTITION要求父列和子列在生成状态上已经匹配,但不要求它们的生成表达式相同。 @@ -3718,8 +3718,8 @@ CREATE TABLE measurement_y2008m02 PARTITION OF measurement 作为一种替代方案,有时更方便的是在分区结构之外创建新表,并稍后将其附加为分区。这允许在新数据出现在分区表中之前加载、检查和转换新数据。 - 此外,ATTACH PARTITION操作只需要在分区表上持有SHARE UPDATE EXCLUSIVE锁,而不像CREATE TABLE ... PARTITION OF那样需要ACCESS EXCLUSIVE锁,因此对分区表上的并发操作更友好。 - CREATE TABLE ... LIKE选项有助于避免繁琐地重复父表定义: + 此外,ALTER TABLE ... ATTACH PARTITION操作只需要在分区表上持有SHARE UPDATE EXCLUSIVE锁,而不像CREATE TABLE ... PARTITION OF那样需要ACCESS EXCLUSIVE锁,因此对分区表上的并发操作更友好。 + CREATE TABLE ... LIKE选项有助于避免繁琐地重复父表定义: CREATE TABLE measurement_y2008m02 @@ -3927,7 +3927,16 @@ ALTER TABLE measurement SPLIT PARTITION measurement_y2006q1 INTO - 创建表,所有的表都将从它继承。这个表将不包含数据。不要在这个表上定义任何检查约束,除非想让它们应用到所有的子表上。同样,在这个表上定义索引或者唯一约束也没有意义。对于我们的示例来说,根表是最初定义的measurement表。 + 创建表,所有的表都将从它继承。这个表将不包含数据。不要在这个表上定义任何检查约束,除非想让它们应用到所有的子表上。同样,在这个表上定义索引或者唯一约束也没有意义。对于我们的示例来说,根表是最初定义的measurement表: + + +CREATE TABLE measurement ( + city_id int not null, + logdate date not null, + peaktemp int, + unitsales int +); + @@ -4536,7 +4545,7 @@ DROP TABLE products CASCADE; - 对于一个将其主体定义为字符串文字的用户定义函数或过程,PostgreSQL会跟踪与函数的外部可见属性相关的依赖关系,例如其参数和结果类型,但不会跟踪只有通过检查函数主体才能知道的依赖关系。例如,考虑以下情况: + 对于一个将其主体定义为字符串字面量的用户定义函数或过程,PostgreSQL会跟踪与函数的外部可见属性相关的依赖关系,例如其参数和结果类型,但不会跟踪只有通过检查函数主体才能知道的依赖关系。例如,考虑以下情况: CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', diff --git a/zh/19/dfunc.sgml b/zh/19/dfunc.sgml index 2070d7f6..0f456690 100644 --- a/zh/19/dfunc.sgml +++ b/zh/19/dfunc.sgml @@ -46,7 +46,7 @@ FreeBSD - FreeBSDshared library + FreeBSD共享库 @@ -65,7 +65,7 @@ cc -shared -o foo.so foo.o Linux - Linuxshared library + Linux共享库 @@ -82,7 +82,7 @@ cc -shared -o foo.so foo.o macOS - macOSshared library + macOS共享库 @@ -98,7 +98,7 @@ cc -bundle -flat_namespace -undefined suppress -o foo.so foo.o NetBSD - NetBSDshared library + NetBSD共享库 @@ -116,7 +116,7 @@ gcc -shared -o foo.so foo.o OpenBSD - OpenBSDshared library + OpenBSD共享库 @@ -133,7 +133,7 @@ ld -Bshareable -o foo.so foo.o Solaris - Solarisshared library + Solaris共享库 diff --git a/zh/19/docguide.sgml b/zh/19/docguide.sgml index c0e8df51..1dacec9b 100644 --- a/zh/19/docguide.sgml +++ b/zh/19/docguide.sgml @@ -306,7 +306,7 @@ checking for dbtoepub... dbtoepub - 对于 U.S. letter 格式: + 对于美国信纸格式: doc/src/sgml$ make postgres-US.pdf @@ -320,7 +320,7 @@ checking for dbtoepub... dbtoepub 因此,在某些系统上,构建会因内存相关错误而失败。这通常可以通过在配置文件 ~/.foprc中配置 Java 堆设置来解决,例如: -# FOP binary distribution +# FOP 二进制发行版 FOP_OPTS='-Xmx1500m' # Debian JAVA_ARGS='-Xmx1500m' diff --git a/zh/19/ecpg.sgml b/zh/19/ecpg.sgml index 29d91590..8725ee33 100644 --- a/zh/19/ecpg.sgml +++ b/zh/19/ecpg.sgml @@ -1139,7 +1139,7 @@ oid=313780, datname=testdb, size=8183012 - 结构体主变量将列尽数吸收成结构体的域。额外的列可以被分配给其他主变量。例如,上面的程序也可以使用结构体外部的size变量重新构造: + 结构体主变量吸收的列数与结构体的字段数相同。额外的列可以被分配给其他主变量。例如,上面的程序也可以使用结构体外部的size变量改写: EXEC SQL BEGIN DECLARE SECTION; typedef struct @@ -1440,7 +1440,7 @@ while (1) 用户定义的基础类型 - ECPG 并不直接支持新的用户定义的基本类型。你可以使用外部字符串表示以及类型char[]VARCHAR[]的主变量,并且这种方案事实上对很多类型都是合适和足够的。 + ECPG 并不直接支持新的用户定义的基础类型。你可以使用外部字符串表示以及类型char[]VARCHAR[]的主变量,并且这种方案事实上对很多类型都是合适和足够的。 @@ -4743,7 +4743,7 @@ EXEC SQL INCLUDE "filename"; 当前目录 /usr/local/include - PostgreSQL 的包括目录,在编译时定义(例如/usr/local/pgsql/include + PostgreSQL 的头文件目录,在编译时定义(例如/usr/local/pgsql/include /usr/include @@ -4870,7 +4870,7 @@ EXEC SQL UPDATE Tbl SET col = MYNUMBER; - 此示例将完全编译三个SET TIMEZONE命令之一: + 此示例将完全编译三个SET TIMEZONE命令之一: EXEC SQL ifdef TZVAR; EXEC SQL SET TIMEZONE TO TZVAR; @@ -5498,7 +5498,7 @@ DATABASE connection_target 使用 user_name/passworduser_name IDENTIFIED BY password或者 - user_name USING password之一,这个参数也能指定用户名和密码. + user_name USING password之一,这个参数也能指定用户名和密码。 @@ -6078,9 +6078,7 @@ EXECUTE IMMEDIATE string - 如果你使用文字字符串,请注意任何你可能希望在SQL语句中包括的双引号必须写为八进制转义(\042) ,而不是通常的C惯语\"。 - 这是因为字符串在EXEC SQL段里面,所以ECPG 语法分析器根据SQL规则而不是C规则来解析它。 - 任何内嵌的反斜杠后续将按照C规格处理;但是\"会造成直接语法错误,因为它被视为文字的终结。 + 如果使用字符串字面量,请注意,要在 SQL 语句中包含的双引号必须写为八进制转义(\042),而不是通常的 C 写法\"。这是因为字符串位于EXEC SQL段中,ECPG 词法分析器会按照 SQL 规则而非 C 规则解析它。内嵌的反斜杠随后会按照 C 规则处理;但\"会被视为字面量的结束,因此会立即引起语法错误。 @@ -6413,9 +6411,7 @@ PREPARE prepared_name FROM - 如果你使用文字字符串,请注意任何你可能希望在SQL语句中包括的双引号必须写为八进制转义(\042) ,而不是通常的C惯语\"。 - 这是因为字符串在EXEC SQL段里面,所以ECPG 语法分析器根据SQL规则而不是C规则来解析它。 - 任何内嵌的反斜杠后续将按照C规格处理;但是\"会造成直接语法错误,因为它被视为文字的终结。 + 如果使用字符串字面量,请注意,要在 SQL 语句中包含的双引号必须写为八进制转义(\042),而不是通常的 C 写法\"。这是因为字符串位于EXEC SQL段中,ECPG 词法分析器会按照 SQL 规则而非 C 规则解析它。内嵌的反斜杠随后会按照 C 规则处理;但\"会被视为字面量的结束,因此会立即引起语法错误。 @@ -7672,19 +7668,19 @@ int rjulmdy(date d, short mdy[3]); rdefmtdate - 使用格式掩码将字符字符串转换为日期类型的值。 + 使用格式掩码将字符串转换为日期类型的值。 int rdefmtdate(date *d, char *fmt, char *str); 该函数接收一个指向应该保存操作结果的日期值的指针(d), 用于解析日期的格式掩码(fmt)和包含日期文本表示的C char*字符串 (str)。文本表示应与格式掩码匹配。但是,你不需要将字符串 - 与格式掩码进行一一映射。该函数仅分析顺序顺序,并查找表示年份位置的文字 + 与格式掩码进行一一映射。该函数只分析先后顺序,并查找表示年份位置的字面文本 yyyyyy,表示月份位置的mm 和表示日期位置的dd - 该函数返回以下值: + 该函数返回以下值: diff --git a/zh/19/event-trigger.sgml b/zh/19/event-trigger.sgml index 58e1fa5b..4100d3d8 100644 --- a/zh/19/event-trigger.sgml +++ b/zh/19/event-trigger.sgml @@ -20,7 +20,7 @@ - 事件触发器行为概览 + 事件触发器行为概述 只要与事件触发器关联的事件在其定义所在数据库中发生,事件触发器就会被触发。 @@ -210,7 +210,7 @@ CALLED_AS_EVENT_TRIGGER(fcinfo) ((fcinfo)->context != NULL && IsA((fcinfo)->context, EventTriggerData)) - 如果该宏返回 true,那么就可以安全地将 fcinfo->context + 如果该宏返回真,那么就可以安全地将 fcinfo->context 转换为 EventTriggerData * 类型,并使用它所指向的 EventTriggerData 结构体。该函数 不得修改 EventTriggerData @@ -281,7 +281,7 @@ typedef struct EventTriggerData 事件触发器函数必须返回一个 NULL 指针 (不是 SQL 空值,也就是不要将 - isNull 设为 true)。 + isNull 设为真)。 diff --git a/zh/19/extend.sgml b/zh/19/extend.sgml index 32ac897b..a11f45d0 100644 --- a/zh/19/extend.sgml +++ b/zh/19/extend.sgml @@ -59,7 +59,7 @@ 类型、函数、访问方法等的信息。这些表可以由用户修改,而 PostgreSQL 又是基于这些表来运行的,这意味着 PostgreSQL 可以由用户扩展。相比之下,传统数据库 - 系统通常只能通过修改源代码中的硬编码过程,或加载由 + 系统只能通过修改源代码中的硬编码过程,或加载由 DBMS 供应商专门编写的模块来扩展。 @@ -92,7 +92,7 @@ 数据类型 - 组合 + 复合 @@ -517,7 +517,7 @@ RETURNS anycompatible AS ... 哪些 SQL 对象种类可以成为扩展成员,见 ALTER EXTENSION 的说明。特别是,数据库集簇范围内的对象,如数据库、角色和表空间,不能 - 成为扩展成员,因为扩展只在单个数据库内可见。(尽管扩展脚本并不禁止创 + 成为扩展成员,因为扩展只在单个数据库内可见。(尽管并不禁止扩展脚本创 建这类对象,但如果这样做,它们不会作为扩展的一部分受到跟踪。)还要注意, 虽然表可以成为扩展成员,但其附属对象(如索引)并不直接被视为扩展成员。 另一个重要点是,模式可以属于扩展,但反过来不成立:扩展本身只有一个非 @@ -672,21 +672,7 @@ RETURNS anycompatible AS ... trusted (boolean) - - 如果该参数被设为 true(默认并非如此),则允许某些 - 非超级用户安装 superuser 设为 - true 的扩展。具体来说,任何在当前数据库上具有 - CREATE 权限的用户都被允许安装。当执行 - CREATE EXTENSION 的用户不是超级用户,但因该参数 - 而被允许安装时,安装或更新脚本会以引导超级用户的身份运行,而不是以 - 调用用户的身份运行。如果 superuser 为 - false,这个参数就没有意义。一般来说,对于可能让 - 用户访问原本只有超级用户才能使用的能力(如文件系统访问)的扩展,不 - 应把它设为 true。此外,把一个扩展标记为 - trusted,还需要付出大量额外努力来确保安装和更 - 新脚本写得足够安全;见 - 。 - + 如果将此参数设为 true(不是默认值),则允许某些非超级用户安装 superuser 设为 true 的扩展。具体而言,当前数据库上具有 CREATE 权限的任何人都可以安装。当执行 CREATE EXTENSION 的用户不是超级用户,但凭借此参数获准安装时,安装或更新脚本会以引导超级用户的身份运行,而不是调用用户的身份。如果 superuserfalse,则此参数不起作用。通常,对于可能允许访问原本仅限超级用户使用的能力(例如文件系统访问)的扩展,不应将此参数设为真。此外,将扩展标记为受信任的,需要投入大量额外工作来安全地编写其安装和更新脚本;参见 @@ -747,8 +733,8 @@ RETURNS anycompatible AS ... 如果扩展脚本中包含字符串 @extowner@,该字符串会被 替换为调用 CREATE EXTENSION 或 - ALTER EXTENSION 的用户名称(会作适当引用)。通常, - 这个特性被标记为 trusted 的扩展用来把选定对象的 + ALTER EXTENSION 的用户名称(会适当加上引号)。通常, + 这个特性被标记为受信任的扩展用来把选定对象的 所有权赋给调用用户, 而不是赋给引导超级用户。(不过这样做时应当谨慎。例如,把一个 C 语言 函数的所有权赋给非超级用户,会为该用户创建一条权限提升路径。) @@ -973,7 +959,7 @@ SELECT pg_catalog.pg_extension_config_dump('my_config', 'WHERE NOT standard_entr 在有合适更新脚本可用的前提下, - ALTER EXTENSION UPDATE 命令可以把已安装的扩展更新 + ALTER EXTENSION UPDATE 命令会把已安装的扩展更新 到指定的新版本。更新脚本运行在 CREATE EXTENSION 为安装脚本提供的同一环境中:尤其 是,search_path 的设置方式完全相同,而且脚本创建的 @@ -999,7 +985,7 @@ SELECT pg_catalog.pg_extension_config_dump('my_config', 'WHERE NOT standard_entr 例如,它并不知道 1.1 是否跟在 1.0 之后。它只是匹配可用的版本名,并选择需要应用 更新脚本最少的那条路径。(实际上,版本名可以是任何不包含 - --,且不以前导或尾随 - 结尾的字 + --,且不以 - 开头或结尾的字 符串。) @@ -1072,19 +1058,9 @@ SELECT * FROM pg_extension_update_paths('extension_name - - 将 superuser 属性设为 true 的 - 扩展,还必须考虑其安装脚本和更新脚本中操作所带来的安全风险。恶意用户并不难创建出特洛伊木 - 马对象,从而在后续粗心编写的扩展脚本执行时造成破坏,并借此获得超级用 - 户权限。 - + superuser 属性设为真的扩展,还必须考虑其安装和更新脚本所执行操作的安全风险。恶意用户可以创建木马对象,破坏以后对编写不慎的扩展脚本的执行,从而获得超级用户权限;这并非特别困难。 - - 如果一个扩展被标记为 trusted,那么安装用户可以自己 - 选择安装模式,而该用户可能会有意使用不安全的模式,希望借此获得超级用 - 户权限。因此,从安全角度看,trusted 扩展暴露程度 - 极高,必须仔细审查其所有脚本命令,确保不存在任何可被利用之处。 - + 如果扩展被标记为 trusted,那么安装用户可以选择其安装模式,而该用户可能故意使用不安全的模式,试图获得超级用户权限。因此,从安全角度看,受信任的扩展面临的风险极高,必须仔细检查其全部脚本命令,确保无法被攻破。 关于如何安全地编写函数,建议见下面的 @@ -1132,7 +1108,7 @@ SELECT * FROM pg_extension_update_paths('extension_namemyschema.myfunc(bigint),那么像 myschema.myfunc(42) 这样的调用,就可能被恶意函数 myschema.myfunc(integer) 截获。要注意函数和操作符 - 参数的数据类型必须与声明的实参类型精确匹配,必要时请使用显式类型转 + 所传参数的数据类型必须与声明的参数类型精确匹配,必要时请使用显式类型转 换。 @@ -1181,7 +1157,7 @@ SELECT * FROM pg_extension_update_paths('extension_name扩展示例 - 下面给出一个纯 SQL 扩展的完整示例:一个双元素组合 + 下面给出一个纯 SQL 扩展的完整示例:一个双元素复合 类型,它可以在两个槽位中存储任意类型的值,这两个槽位名为 kv。非文本值会自动强制转换为文本后 再存储。 @@ -1262,7 +1238,7 @@ include $(PGXS) 如果你打算分发自己的 PostgreSQL 扩展模块, - 那么为它们搭建一个可移植的构建系统会相当困难。因此, + 那么为它们搭建一个可移植的构建系统可能相当困难。因此, PostgreSQL 安装提供了一套称为 PGXS 的扩展构建基础设施,使简单的扩展模块可以针对 已安装好的服务器直接构建。PGXS 主要面向包含 C 代码 @@ -1313,7 +1289,7 @@ include $(PGXS) MODULE_big - 要从多个源文件构建的共享库(在 OBJS 中列出对象 + 要从多个源文件构建的共享库(在 OBJS 中列出目标 文件) @@ -1323,7 +1299,7 @@ include $(PGXS) PROGRAM - 要构建的可执行程序(在 OBJS 中列出对象文件) + 要构建的可执行程序(在 OBJS 中列出目标文件) @@ -1678,7 +1654,7 @@ make VPATH=/path/to/extension/source/tree install 正在运行的 PostgreSQL 服务器。列在 REGRESS 中的脚本文件必须位于扩展目录下名为 sql/ 的子目录中。这些文件必须具有 - .sql 扩展名,而该扩展名不应出现在 makefile 的 + .sql 扩展名,而该扩展名不能出现在 makefile 的 REGRESS 列表中。对于每个测试,还应在名为 expected/ 的子目录中有一个包含期望输出的文件,其主 干名相同,扩展名为 .out。 @@ -1697,7 +1673,7 @@ make VPATH=/path/to/extension/source/tree install 必须有一个正在运行的 PostgreSQL 服务器。列 在 ISOLATION 中的脚本文件必须位于扩展目录下名为 specs/ 的子目录中。这些文件必须具有 - .spec 扩展名,而该扩展名不应出现在 makefile 的 + .spec 扩展名,而该扩展名不能出现在 makefile 的 ISOLATION 列表中。对于每个测试,还应在名为 expected/ 的子目录中有一个包含期望输出的文件,其主 干名相同,扩展名为 .out。 diff --git a/zh/19/fdwhandler.sgml b/zh/19/fdwhandler.sgml index 2eeed62d..62c3c8dc 100644 --- a/zh/19/fdwhandler.sgml +++ b/zh/19/fdwhandler.sgml @@ -753,7 +753,7 @@ RecheckForeignScan(ForeignScanState *node, - <command>EXPLAIN</command>的FDW例程 + <command>EXPLAIN</command> 的 FDW 例程 @@ -803,7 +803,7 @@ ExplainDirectModify(ForeignScanState *node, - <command>ANALYZE</command>的FDW例程 + <command>ANALYZE</command> 的 FDW 例程 diff --git a/zh/19/features.sgml b/zh/19/features.sgml index 6e7ab388..9f9148c4 100644 --- a/zh/19/features.sgml +++ b/zh/19/features.sgml @@ -408,7 +408,7 @@ SELECT XMLQUERY('$a is $b' PASSING BY VALUE x AS a, < DOCUMENTCONTENT形式的值。 一个 XQuery/XPath 表达式的上下文项必须是单个 XML 节点或原子值, 但 XPath 1.0 又进一步限制它只能是 XML 节点,并且没有允许CONTENT的节点类型。 - 归根结底,格式良好的DOCUMENT是 + 归根结底,良构的DOCUMENTPostgreSQL能够作为 XPath 上下文项提供的唯一 XML 值形式。 diff --git a/zh/19/func/func-admin.sgml b/zh/19/func/func-admin.sgml index 7bcf2c89..4c8fa0ac 100644 --- a/zh/19/func/func-admin.sgml +++ b/zh/19/func/func-admin.sgml @@ -19,9 +19,9 @@ - configuration - of the server - functions + 配置 + 服务器 + 函数 @@ -58,7 +58,7 @@ text - 返回设置的setting_name的当前值。 + 返回设置setting_name的当前值。 如果没有这样的设置,current_setting将抛出一个错误,除非missing_ok被提供并且为true(在此情况下返回NULL)。 这个函数对应于SQL命令 @@ -80,9 +80,10 @@ text - 将参数setting_name设置为new_value,并返回该值。 - 如果is_localtrue,新值将仅在当前事务期间应用。 - 如果您希望新值应用于当前会话的其余部分,请使用false代替。这个函数对应于SQL命令。 + 将参数setting_name设置为new_value,并返回该值。如果is_localtrue,新值仅在当前事务期间生效。如果希望新值在当前会话的剩余时间内生效,则使用false。此函数对应 SQL 命令。 + + + set_config接受将 NULL 作为new_value的值,但由于配置值不能为 null,这会被解释为将该设置重置为默认值的请求。 set_config('log_statement_stats', 'off', false) @@ -105,7 +106,7 @@ - 在中展示的函数向其它服务器进程发送控制信号。默认情况下这些函数只能被超级用户使用,但是如果需要,可以利用GRANT把访问权限授予给其他用户。 + 在中展示的函数向其它服务器进程发送控制信号。默认情况下这些函数只能被超级用户使用,但是如果需要,可以利用GRANT把访问权限授予给其他用户(注明的例外除外)。 @@ -141,6 +142,7 @@ 取消具有指定进程ID的后端进程的会话的当前查询。如果调用角色是被取消的后端进程所属角色的成员, 或者调用角色具有pg_signal_backend的权限,则也允许执行此操作,但只有超级用户可以取消超级用户后端进程。 + 例外情况是,具有pg_signal_autovacuum_worker角色权限的角色可以取消 autovacuum 工作进程,而这些进程原本被视为超级用户后端。 @@ -153,11 +155,7 @@ boolean - 请求记录具有指定进程ID的后端的内存上下文。此函数可以将请求发送到后端和辅助进程,但不包括记录器。这些内存上下文将以 - LOG消息级别记录。它们将根据设置的日志配置出现在服务器日志中 - (有关更多信息,请参见), - 但无论如何都不会发送给客户端 - ()。 + 请求记录具有指定进程 ID 的后端进程的内存上下文。此函数可以向除日志记录进程以外的后端进程和辅助进程发送请求。这些内存上下文将以LOG消息级别记录,并根据日志配置出现在服务器日志中(详见);无论如何设置,都不会发送给客户端。 @@ -204,9 +202,10 @@ 终止具有指定进程ID的后端进程的会话。如果调用角色是正在终止的后端的角色的成员,或者调用角色具有pg_signal_backend的权限,则也允许执行此操作,但只有超级用户才能终止超级用户后端。 + 例外情况是,具有pg_signal_autovacuum_worker角色权限的角色可以终止 autovacuum 工作进程,而这些进程原本被视为超级用户后端。 - 如果未指定或超时timeout为零,则此函数无论进程是否实际终止,都将返回true,仅表示信号发送成功。如果指定了timeout(以毫秒为单位)且大于零,则函数将等待直到进程实际终止或直到给定时间已过。如果进程被终止,函数将返回true。在超时时,会发出警告并返回false。 + 如果未指定timeout或其值为零,则此函数无论进程是否实际终止,都将返回true,仅表示信号发送成功。如果指定了timeout(以毫秒为单位)且大于零,则函数将等待直到进程实际终止或直到给定时间已过。如果进程被终止,函数将返回true。在超时时,会发出警告并返回false @@ -232,16 +231,16 @@ postgres=# SELECT pg_log_backend_memory_contexts(pg_backend_pid()); LOG: logging memory contexts of PID 10377 STATEMENT: SELECT pg_log_backend_memory_contexts(pg_backend_pid()); -LOG: level: 0; TopMemoryContext: 80800 total in 6 blocks; 14432 free (5 chunks); 66368 used -LOG: level: 1; pgstat TabStatusArray lookup hash table: 8192 total in 1 blocks; 1408 free (0 chunks); 6784 used -LOG: level: 1; TopTransactionContext: 8192 total in 1 blocks; 7720 free (1 chunks); 472 used -LOG: level: 1; RowDescriptionContext: 8192 total in 1 blocks; 6880 free (0 chunks); 1312 used -LOG: level: 1; MessageContext: 16384 total in 2 blocks; 5152 free (0 chunks); 11232 used -LOG: level: 1; Operator class cache: 8192 total in 1 blocks; 512 free (0 chunks); 7680 used -LOG: level: 1; smgr relation table: 16384 total in 2 blocks; 4544 free (3 chunks); 11840 used -LOG: level: 1; TransactionAbortContext: 32768 total in 1 blocks; 32504 free (0 chunks); 264 used +LOG: level: 1; TopMemoryContext: 80800 total in 6 blocks; 14432 free (5 chunks); 66368 used +LOG: level: 2; pgstat TabStatusArray lookup hash table: 8192 total in 1 blocks; 1408 free (0 chunks); 6784 used +LOG: level: 2; TopTransactionContext: 8192 total in 1 blocks; 7720 free (1 chunks); 472 used +LOG: level: 2; RowDescriptionContext: 8192 total in 1 blocks; 6880 free (0 chunks); 1312 used +LOG: level: 2; MessageContext: 16384 total in 2 blocks; 5152 free (0 chunks); 11232 used +LOG: level: 2; Operator class cache: 8192 total in 1 blocks; 512 free (0 chunks); 7680 used +LOG: level: 2; smgr relation table: 16384 total in 2 blocks; 4544 free (3 chunks); 11840 used +LOG: level: 2; TransactionAbortContext: 32768 total in 1 blocks; 32504 free (0 chunks); 264 used ... -LOG: level: 1; ErrorContext: 8192 total in 1 blocks; 7928 free (3 chunks); 264 used +LOG: level: 2; ErrorContext: 8192 total in 1 blocks; 7928 free (3 chunks); 264 used LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 used 如果在同一父级下有超过100个子上下文,则将记录前100个子上下文,并附上其余上下文的摘要。 @@ -255,7 +254,7 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 备份控制函数 - backup + 备份 @@ -295,13 +294,9 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 pg_lsn - 在预写式日志中创建一个命名标记记录,稍后可以将其用作恢复目标,并返回相应的预写日志位置。 - 然后可以将给定的名称与 一起使用,以指定进行恢复的点。 - 要避免创建多个名称相同的恢复点,因为恢复将在第一个名称与恢复目标匹配的恢复点停止。 + 在预写式日志中创建一条命名标记记录,供以后用作恢复目标,并返回相应的预写式日志位置。随后可以在中使用给定名称,指定恢复到哪一点。应避免创建多个同名恢复点,因为恢复会在第一个名称匹配恢复目标的恢复点停止。 - - 默认情况下,该函数仅限超级用户使用,但可以授权给其他用户执行该函数。 - + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -313,7 +308,7 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 pg_lsn - 返回当前预写式日志刷新位置(参见下面的说明)。 + 返回当前预写式日志刷盘位置(参见下文说明)。 @@ -326,7 +321,7 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 pg_lsn - 返回当前预式日志插入位置(参见下面的说明)。 + 返回当前预写式日志插入位置(参见下文说明)。 @@ -339,7 +334,7 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 pg_lsn - 返回当前预写式日志写位置(参见下面的说明)。 + 返回当前预写式日志写入位置(参见下文说明)。 @@ -355,15 +350,9 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 pg_lsn - 准备服务器开始在线备份。唯一必需的参数是备份的任意用户定义标签。 - (通常这将是备份转储文件存储的名称。) - 如果将可选的第二个参数指定为true, - 它将尽快执行pg_backup_start。这将强制快速检查点, - 这将导致I/O操作的激增,从而减慢任何同时执行的查询。 + 准备服务器开始在线备份。唯一必需的参数是用户任意指定的备份标签。(通常是备份转储文件将要保存的名称。)如果可选的第二个参数为true,则尽快执行pg_backup_start。这会强制执行快速检查点,使 I/O 操作量陡增,并降低并发执行的查询的速度。 - - 默认情况下,此函数仅限于超级用户,但可以授予其他用户执行权限以运行该函数。 - + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -380,31 +369,18 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 spcmapfile text ) - 完成在线备份。函数的结果中返回备份标签文件和表空间映射文件的期望内容,并必须写入备份区域的文件中。 - 这些文件不得写入实时数据目录(这样做将导致PostgreSQL在崩溃时无法重新启动)。 + 结束在线备份。备份标签文件和表空间映射文件所需的内容作为函数结果的一部分返回,必须将其写入备份区域中的文件。切勿将这些文件写入正在使用的数据目录(否则发生崩溃后 PostgreSQL 将无法重新启动)。 - 有一个类型为boolean的可选参数。 - 如果为false,则在备份完成后立即返回,而无需等待WAL进行归档。 - 此行为仅适用于独立监视WAL归档的备份软件。否则,可能会缺少使备份一致所需的WAL,使备份无效。 - 默认情况下或当此参数为true时,pg_backup_stop将在启用归档时等待WAL进行归档。 - (在备库上,这意味着仅当archive_mode = always时才会等待。 - 如果主库上的写入活动较低,则可能有必要在主库上运行pg_switch_wal以触发立即段切换。) + 有一个boolean类型的可选参数。如果为 false,该函数会在备份完成后立即返回,不等待 WAL 归档。这种行为只适用于自行监控 WAL 归档的备份软件;否则,可能缺少使备份保持一致所需的 WAL,导致备份无法使用。默认情况下或该参数为 true 时,若已启用归档,pg_backup_stop会等待 WAL 归档。(在备库上,这意味着只有archive_mode = always时才会等待。如果主库的写入活动很少,可以在主库上运行pg_switch_wal,触发立即切换日志段。) - 在主库上执行时,此函数还会在预写式日志归档区域中创建一个备份历史文件。 - 历史文件包括给定给pg_backup_start的标签、备份的起始和结束预写式日志位置,以及备份的起始和结束时间。 - 在记录结束位置后,当前的预写式日志插入点会自动前进到下一个预写式日志文件,以便立即归档结束的预写式日志文件以完成备份。 + 在主库上执行时,该函数还会在预写式日志归档区域创建备份历史文件。历史文件包括传给pg_backup_start的标签、备份的起止预写式日志位置以及备份的起止时间。记录结束位置后,当前预写式日志插入点会自动推进到下一个预写式日志文件,使包含结束位置的预写式日志文件可以立即归档,从而完成备份。 - 函数的结果是一个记录。 - lsn列保存备份的结束预写式日志位置(可以忽略)。 - 第二列返回备份标签文件的内容,第三列返回表空间映射文件的内容。 - 这些必须作为备份的一部分存储,并作为恢复过程的一部分。 + 该函数的结果是一条记录。lsn列保存备份结束时的预写式日志位置(同样可以忽略)。第二列返回备份标签文件的内容,第三列返回表空间映射文件的内容。这些内容必须作为备份的一部分保存,恢复时需要用到它们。 - - 默认情况下,此函数仅限于超级用户,但可以授予其他用户EXECUTE权限来运行该函数。 - + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -416,13 +392,9 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 pg_lsn - 强制服务器切换到一个新的预写式日志文件,这允许对当前文件进行归档(假设你正在使用连续归档)。 - 其结果是在刚刚完成的预写式日志文件中结束预写式日志位置加1。 - 如果自从上次预写式日志切换以来没有提前写日志活动,pg_switch_wal将不做任何操作,并返回当前正在使用的提前写日志文件的起始位置。 + 强制服务器切换到新的预写式日志文件,使当前文件可以归档(假设正在使用连续归档)。返回值是刚完成的预写式日志文件中的结束预写式日志位置加 1。如果自上次切换预写式日志以来没有发生任何预写式日志活动,pg_switch_wal不执行任何操作,并返回当前使用的预写式日志文件的起始位置。 - - 默认情况下该函数仅限超级用户使用,但可以授权其他用户执行该函数。 - + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -434,7 +406,7 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 text - 将预写式日志位置转换为保持该位置的WAL文件的名称。 + 将预写式日志位置转换为包含该位置的 WAL 文件的名称。 @@ -477,35 +449,22 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 numeric - 计算两个预写式日志位置之间的字节(lsn1 - lsn2)差异。 - 这可以与pg_stat_replication中所示的一些函数一起使用,以获得复制延迟。 + 计算两个预写式日志位置之间的字节差(lsn1 - lsn2)。可以将它与pg_stat_replication中的某些函数配合使用,以获取复制延迟。
- - pg_current_wal_lsn 显示当前预写式日志写位置,与上述函数所用的格式相同。 - 类似地,pg_current_wal_insert_lsn显示当前预写式日志插入位置,pg_current_wal_flush_lsn显示当前预写式日志刷新位置。 - 插入位置是预写式日志在任何时刻的逻辑(logical) 结束,而写位置是已经从服务器内部缓冲区实际写入的内容的结束,而刷新位置是已知的要写入持久化存储的最后一个位置。 - 写位置是可以从服务器外部检查的最后位置,如果你对归档部分完成的预写式日志文件感兴趣,那么它通常就是你想要的位置。 - 插入和刷新位置主要用于服务器调试目的。这些都是只读操作,不需要超级用户权限。 - + pg_current_wal_lsn 显示当前预写式日志写入位置,格式与上述函数相同。类似地,pg_current_wal_insert_lsn 显示当前预写式日志插入位置,pg_current_wal_flush_lsn 显示当前预写式日志刷盘位置。插入位置是预写式日志在任意时刻的逻辑末尾;写入位置是实际从服务器内部缓冲区写出的内容的末尾;刷盘位置则是已知已经写入持久存储的最后位置。写入位置是能从服务器外部检查到的内容的末尾,如果要归档尚未写满的预写式日志文件,通常需要这个位置。插入位置和刷盘位置主要用于服务器调试。这些都是只读操作,不需要超级用户权限。 - - 您可以使用pg_walfile_name_offsetpg_lsn值中提取相应的预写式日志文件名和字节偏移量。例如: - + 可以使用pg_walfile_name_offset从一个pg_lsn值中提取相应的预写式日志文件名和字节偏移量。例如: postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); file_name | file_offset --------------------------+------------- 00000001000000000000000D | 4039624 (1 row) - - 类似地,pg_walfile_name仅提取预写式日志文件名。 - 当给定的预写式日志位置恰好位于预写式日志文件边界时,这两个函数都会返回前一个预写式日志文件的名称。 - 这通常是管理预写式日志归档行为的期望行为,因为前一个文件是当前需要归档的最后一个文件。 - +类似地,pg_walfile_name仅提取预写式日志文件名。 pg_split_walfile_name可用于根据文件偏移量和 WAL 文件名计算 @@ -575,9 +534,7 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset pg_lsn - 返回已接收并通过流复制同步到磁盘的最后一个预写式日志位置。 - 当流复制正在进行时这将单调地增加。如果恢复已经完成,那么在恢复期间,接收到的最后一条WAL记录的位置将保持静态,并同步到磁盘。 - 如果流复制已禁用,或者尚未启动,函数将返回NULL。 + 返回流复制最近接收并同步到磁盘的预写式日志位置。在流复制进行期间,该值单调增加。如果恢复已完成,该值将保持为恢复期间最后接收并同步到磁盘的 WAL 记录的位置。如果禁用了流复制,或者流复制尚未开始,此函数返回 NULL @@ -590,8 +547,7 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset pg_lsn
- 返回恢复期间重新播放的最后一个预写式日志位置。如果恢复仍在进行中这将会单调地增加。 - 如果恢复已经完成,那么恢复期间应用的最后WAL记录的位置将保持静态。当服务器正常启动且没有恢复时,函数返回NULL。 + 返回恢复期间最近重放的预写式日志位置。如果恢复仍在进行,该值单调增加。如果恢复已完成,该值将保持为该次恢复期间最后应用的 WAL 记录的位置。如果服务器未经恢复而正常启动,此函数返回 NULL @@ -604,10 +560,7 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset timestamp with time zone - 返回恢复期间重放的最后一个事务的时间戳。这是在主库上为该事务生成提交或中止 WAL记录的时间。 - 如果在恢复期间没有重放任何事务,该函数将返回NULL。否则,如果恢复仍在进行中,这将单调地增加。 - 如果恢复已经完成,那么在恢复期间应用最后一个事务时,这将会保持静态。 - 当服务器正常启动且没有恢复时,函数返回NULL。 + 返回恢复期间最近重放事务的时间戳,即该事务的提交或中止 WAL 记录在主库上生成的时间。如果恢复期间尚未重放任何事务,此函数返回 NULL。否则,如果恢复仍在进行,该值单调增加。如果恢复已完成,该值将保持为该次恢复期间最后应用的事务的时间戳。如果服务器未经恢复而正常启动,此函数返回 NULL @@ -631,7 +584,7 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset - 控制恢复进度的功能如 所示。这些函数只能在恢复过程中执行。 + 列出的函数用于控制恢复进度。这些函数只能在恢复期间执行。 @@ -661,7 +614,7 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset boolean - 如果请求了恢复暂停了则返回真。 + 如果已请求暂停恢复,则返回真。 @@ -675,7 +628,7 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset 返回恢复暂停状态。 - 如果没有请求pause,返回值是not paused,如果请求暂停但恢复还没有暂停,返回值是pause requested,如果恢复实际已经暂停,返回值是paused。 + 如果没有请求暂停,返回值是not paused,如果请求暂停但恢复还没有暂停,返回值是pause requested,如果恢复实际已经暂停,返回值是paused @@ -689,11 +642,11 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset 将备库提升为主库状态。 - 当wait设置为true(默认值)时,函数将等待直到升级完成或wait_seconds秒数已过,如果升级成功则返回true,否则返回false。 - 如果wait设置为false,则该函数在向postmaster发送SIGUSR1信号以触发升级后立即返回true。 + 当wait设置为true(默认值)时,函数将等待直到提升完成或wait_seconds秒数已过,如果提升成功则返回true,否则返回false。 + 如果wait设置为false,则该函数在向postmaster发送SIGUSR1信号以触发提升后立即返回true - 默认情况下这个函数仅限超级用户使用,但可以授权给其他用户执行该函数。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -714,7 +667,7 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset 如果热备是激活的,所有新查询将看到相同的一致的数据库快照,并且在恢复继续之前不会生成进一步的查询冲突。 - 默认情况下该函数仅限超级用户使用,但可以授权其他用户执行该函数。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -730,7 +683,7 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset 如果暂停了,则重新启动恢复。 - 默认情况下该函数仅限超级用户使用,但可以授权其他用户执行该函数。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -738,8 +691,8 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset
- pg_wal_replay_pausepg_wal_replay_resume不能在提升(promotion)进行时执行。 - 如果在恢复暂停时触发了提升(promotion),则暂停状态结束,升级继续进行。 + pg_wal_replay_pausepg_wal_replay_resume不能在提升进行时执行。 + 如果在恢复暂停时触发了提升,则暂停状态结束,提升继续进行。 @@ -758,7 +711,7 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset - 为了解决这个问题,PostgreSQL允许一个事务导出它正在使用的快照。只要导出的事务仍然保持打开,其他事务可以导入它的快照,并且因此可以保证它们可以看到和第一个事务看到的完全一样的数据库视图。但是注意这些事务中的任何一个对数据库所作的更改对其他事务仍然保持不可见,和未提交事务所作的修改一样。因此这些事务是针对以前存在的数据同步,而对由它们自己所作的更改则采取正常的动作。 + 为了解决这个问题,PostgreSQL允许一个事务导出它正在使用的快照。只要导出快照的事务仍然保持打开,其他事务可以导入它的快照,并且因此可以保证它们可以看到和第一个事务看到的完全一样的数据库视图。但是注意这些事务中的任何一个对数据库所作的更改对其他事务仍然保持不可见,和未提交事务所作的修改一样。因此这些事务是针对以前存在的数据同步,而对由它们自己所作的更改则采取正常的动作。 @@ -798,7 +751,19 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset 如果需要的话,一个事务可以导出多个快照。 请注意,这样做仅在READ COMMITTED事务中有用,因为在REPEATABLE READ和更高的隔离级别中,事务在它们的生命周期中使用相同的快照。 - 一旦事务导出了快照,它就不能用 进行准备。 + 一旦事务导出了快照,它就不能用 进行预备。 + + + + + + pg_log_standby_snapshot + + pg_log_standby_snapshot () + pg_lsn + + + 为进行中的事务拍摄快照并将其写入 WAL,无须等待后台写入器或检查点进程记录快照。这对备用服务器上的逻辑解码很有用,因为创建逻辑复制槽必须等待此类记录在备用服务器上重放。 @@ -814,7 +779,6 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset 中展示的函数用于控制以及与复制特性交互。 有关底层特性的信息请见以及。 - 复制原点函数的使用仅限于超级用户。 默认只允许超级用户使用复制源的函数,但可以通过GRANT命令允许其他用户使用。 复制槽的函数只限于超级用户和拥有REPLICATION权限的用户。 @@ -860,13 +824,7 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset lsn pg_lsn ) - 创建一个新的名为slot_name的物理复制槽。 - 槽名称不能是pg_conflict_detection,因为它保留给冲突检测槽。 - 第二个参数是可选的,当它为true时,立即为这个物理槽指定要被保留的LSN。 - 否则该LSN会被保留在来自一个流复制客户端的第一个连接上。 - 来自一个物理槽的更改只能通过流复制协议进行流式传输 — 见。 - 当可选的第三参数temporary被设置为真时,指定那个槽不会被持久地存储在磁盘上并且仅对当前会话的使用有意义。 - 临时槽也会在发生任何错误时被释放。这个函数对应于复制协议命令CREATE_REPLICATION_SLOT ... PHYSICAL。 + 创建名为 slot_name 的新物理复制槽。槽名称不能是pg_conflict_detection,因为它保留给冲突检测槽。可选的第二个参数为 true 时,指定立即为此复制槽保留 LSN;否则在流复制客户端首次连接时保留 LSN。从物理槽流式传输更改只能使用流复制协议 — 参见。可选的第三个参数 temporary 为真时,指定该槽不永久存储到磁盘,且仅供当前会话使用。发生任何错误时,临时槽也会被释放。此函数对应复制协议命令 CREATE_REPLICATION_SLOT ... PHYSICAL @@ -879,9 +837,7 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset void - 丢弃名为slot_name的物理或逻辑复制槽。 - 和复制协议命令DROP_REPLICATION_SLOT相同。对于逻辑槽, - 在连接到在其中创建该槽的同一个数据库时,必须调用这个函数。 + 删除名为slot_name的物理或逻辑复制槽。与复制协议命令DROP_REPLICATION_SLOT相同。 @@ -896,8 +852,8 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset lsn pg_lsn ) - 创建一个名为slot_name的新逻辑(解码)复制插槽,使用输出插件plugin。槽名称不能是pg_conflict_detection,因为它保留给冲突检测槽。 - 可选的第三个参数temporary,当设置为true时,指定插槽不应永久存储到磁盘,仅供当前会话使用。临时插槽也会在任何错误发生时释放。可选的第四个参数twophase,当设置为true时,指定为此插槽启用已准备事务的解码。可选的第五个参数failover,当设置为true时,指定启用此插槽同步到备库,以便在故障切换后可以恢复逻辑复制。调用此函数的效果与复制协议命令CREATE_REPLICATION_SLOT ... LOGICAL相同。 + 创建一个名为slot_name的新逻辑(解码)复制槽,使用输出插件plugin。槽名称不能是pg_conflict_detection,因为它保留给冲突检测槽。 + 可选的第三个参数temporary,当设置为真时,指定槽不应永久存储到磁盘,仅供当前会话使用。临时槽也会在任何错误发生时释放。可选的第四个参数twophase,当设置为真时,指定为此槽启用预备事务的解码。可选的第五个参数failover,当设置为真时,指定启用此槽同步到备库,以便在故障切换后可以恢复逻辑复制。调用此函数的效果与复制协议命令CREATE_REPLICATION_SLOT ... LOGICAL相同。 @@ -914,8 +870,9 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset 将一个名为src_slot_name的现有物理复制槽复制到一个名为dst_slot_name的物理复制槽。 新槽名称不能是pg_conflict_detection,因为它保留给冲突检测。 - 被复制的物理槽开始从与源槽相同的LSN开始保留WAL。temporary是可选的。 + 复制后的物理槽从与源槽相同的LSN开始保留WAL。temporary是可选的。 如果省略了temporary,则使用与源槽相同的值。 + 不能复制已失效的槽。 @@ -930,10 +887,12 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset lsn pg_lsn ) - 复制一个名为src_slot_name的现有逻辑复制槽到一个名为dst_slot_name的逻辑复制槽,选择性的改变输出插件和持久性。 + 复制一个名为src_slot_name的现有逻辑复制槽到一个名为dst_slot_name的逻辑复制槽,可选地更改输出插件和持久性。 新槽名称不能是pg_conflict_detection,因为该名称保留用于冲突检测。 被复制的逻辑槽从与源逻辑槽相同的LSN开始。temporaryplugin都是可选的。 如果它们被省略了,使用与源逻辑槽相同的值。 + 源逻辑槽的failover选项不会被复制,而是默认设为false。这是为了避免故障切换到正在同步该槽的备库后无法继续逻辑复制的风险。 + 不能复制已失效的槽。 @@ -949,11 +908,7 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset data text ) - 返回槽slot_name中的改变,从最后一次使用更改的点开始。 - 如果upto_lsnupto_nchanges为 NULL,逻辑解码将一直继续到 WAL 的末尾。 - 如果upto_lsn为非 NULL,解码将只包括那些在指定 LSN 之前提交的事务。 - 如果upto_nchanges为非 NULL,解码将在其产生的行数超过指定值后停止。 - 不过要注意,被返回的实际行数可能更大,因为对这个限制的检查只会在增加了解码每个新的提交事务产生的行之后进行。 + 返回槽 slot_name 中自上次消费更改的位置起的更改。如果 upto_lsnupto_nchanges 都为 NULL,逻辑解码会持续到 WAL 末尾。如果 upto_lsn 非 NULL,解码仅包含在指定 LSN 之前提交的事务。如果 upto_nchanges 非 NULL,解码产生的行数超过指定值时就会停止。不过,实际返回行数可能更大,因为只有在添加完对每个新事务提交进行解码所产生的行后,才会检查此限制。如果指定的槽是逻辑故障切换槽,则只有在synchronized_standby_slots中指定的所有物理槽都确认已接收 WAL 后,该函数才会返回。 @@ -1018,9 +973,7 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset end_lsn pg_lsn ) - 将复制槽的当前确认的位置提前到名为slot_name的复制槽的当前确认位置。 - 该槽不会向后移动,也不会移动到当前插入位置之外。返回该槽的名称和它被推进到的真实位置。 - 如果有任何进展,则在下一个检查点中写出更新后的槽位置信息。所以如果发生崩溃,该槽位可能会返回到之前的位置。如果指定的槽是逻辑故障切换槽,则在synchronized_standby_slots中指定的所有物理槽都确认已接收 WAL 之前,该函数不会返回。 + 推进名为 slot_name 的复制槽当前已确认的位置。该槽不会后退,也不会越过当前插入位置。返回槽名及其实际推进到的位置。如果发生了推进,更新后的槽位置信息会在下一个检查点写出。因此,发生崩溃时,槽可能回到更早的位置。如果指定的槽是逻辑故障切换槽,则只有在 synchronized_standby_slots 中指定的所有物理槽都确认已接收 WAL 后,该函数才会返回。 @@ -1125,7 +1078,7 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset pg_lsn - 返回当前会话中选择的复制源的重放位置。参数flush决定对应的本地事务是否被确保已经刷入磁盘。 + 返回当前会话中选择的复制源的重放位置。参数flush决定是否保证对应的本地事务已刷盘。 @@ -1179,7 +1132,7 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset pg_lsn - 返回给定复制元的重放位置。参数flush决定对应的本地事务是否被确保已经刷入磁盘。 + 返回给定复制源的重放位置。参数flush决定是否保证对应的本地事务已刷盘。 @@ -1188,19 +1141,15 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset pg_logical_emit_message - pg_logical_emit_message ( transactional boolean, prefix text, content text ) + pg_logical_emit_message ( transactional boolean, prefix text, content text , flush boolean DEFAULT false ) pg_lsn - pg_logical_emit_message ( transactional boolean, prefix text, content bytea ) + pg_logical_emit_message ( transactional boolean, prefix text, content bytea , flush boolean DEFAULT false ) pg_lsn - 发出逻辑解码消息。这可以用于通过WAL将通用消息传递给逻辑解码插件。 - transactional参数指定消息是否应该是当前事务的一部分, - 还是应该立即写入并在逻辑解码器读取记录时立即解码。 - prefix参数是一个文本前缀,逻辑解码插件可以使用它轻松识别对它们有趣的消息。 - content参数是消息的内容,可以以文本或二进制形式给出。 + 发出逻辑解码消息。这可用于通过 WAL 向逻辑解码插件传递通用消息。transactional 参数指定消息是作为当前事务的一部分,还是立即写入并在逻辑解码器读到该记录时立即解码。prefix 参数是一个文本前缀,便于逻辑解码插件识别其关注的消息。content 参数是消息内容,可以文本或二进制形式给出。 flush 参数(默认为 false)控制是否立即将消息对应的 WAL 记录刷盘。transactional 为真时,flush 不起作用,因为消息的 WAL 记录会与其事务一起刷盘。 @@ -1298,10 +1247,7 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset oid - 显示磁盘上已 TOAST 化值的chunk_id。 - 如果该值已被去 TOAST 化或未存储在磁盘上,则返回 - NULL。有关 TOAST 的更多信息,请参阅 - 。 + 显示磁盘上经过TOAST处理的值的chunk_id。如果该值未经过TOAST处理或不在磁盘上,则返回NULL。有关TOAST的更多信息,请参见 @@ -1345,13 +1291,13 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset bigint - 计算指定关系的一个fork所使用的磁盘空间。 - (注意在大多数情况下,使用更高级的函数 pg_total_relation_sizepg_table_size更方便,它们将所有分叉(forks)的大小相加。) - 使用一个参数,这将返回关系的主数据分叉的大小。第二个参数可以用来指定要检查哪个分叉: + 计算指定关系的一个分支所使用的磁盘空间。 + (注意在大多数情况下,使用更高级的函数 pg_total_relation_sizepg_table_size更方便,它们将所有分支的大小相加。) + 使用一个参数,这将返回关系的主数据分支的大小。第二个参数可以用来指定要检查哪个分支: - main返回关系的主数据分叉的大小。 + main返回关系的主数据分支的大小。 @@ -1366,7 +1312,7 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset - init 返回初始化分叉的大小,如果有的话,与关系相关。 + init 返回与该关系关联的初始化分支(如有)的大小。 @@ -1382,7 +1328,7 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset bigint - 将人可阅读的格式的大小(由pg_size_pretty返回)转换为字节。 + 将人类可读格式的大小(由pg_size_pretty返回)转换为字节。有效的单位为bytesBkBMBGBTBPB @@ -1413,7 +1359,7 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset bigint - 计算指定表所使用的磁盘空间,不包括索引(但包括它的TOAST表,如果有的话,空闲空间映射,以及可见性映射)。 + 计算指定表所使用的磁盘空间,不包括索引(但包括其 TOAST 表(如有)、空闲空间映射和可见性映射)。 @@ -1447,7 +1393,7 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset 计算指定表所使用的总磁盘空间,包括所有索引和TOAST数据。 - 结果等价pg_table_size + pg_indexes_size。 + 结果等价于pg_table_size + pg_indexes_size @@ -1455,11 +1401,7 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset - 上述操作表和索引的函数接受一个regclass参数,它是该表或索引在pg_class系统目录中的 OID。 - 你不必手工去查找该 OID,因为regclass数据类型的输入转换器会为你代劳。 - 只写包围在单引号内的表名,这样它看起来像一个文字常量。 - 为了与普通SQL名称的处理相兼容,该字符串将被转换为小写形式,除非其中在表名周围包含双引号。 - 详见。 + 上述操作表和索引的函数接受一个regclass参数,即该表或索引在pg_class系统目录中的 OID。不必手工查找该 OID,因为regclass数据类型的输入转换器会代为查找。详见 @@ -1493,7 +1435,7 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset oid - 返回当前分配给指定关系的filenode数字。文件节点是用于该关系的文件名称的基本组件(更多信息请参阅 )。 + 返回当前分配给指定关系的文件结点编号。文件结点是用于该关系的文件名称的基本组件(更多信息请参阅 )。 对于大多数关系,其结果与pg_class.relfilenode相同,但对于某些系统目录,relfilenode为0,并且必须使用这个函数来获得正确的值。 如果传递的是一个没有存储的关系,例如一个视图,那么函数将返回NULL。 @@ -1508,7 +1450,7 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset text - 返回关系的完整文件路径名称(相对于数据库集簇的数据目录,即关系的PGDATA)。 + 返回关系的完整文件路径名称(相对于数据库集簇的数据目录,即PGDATA)。 @@ -1521,8 +1463,7 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset regclass - 返回一个给定表空间OID和存储它的文件节点的关系的OID。这本质上是pg_relation_filepath的反向映射。 - 对于数据库默认表空间中的关系,表空间可以指定为0。如果当前数据库中没有与给定值相关联的关系,则返回 NULL。 + 根据关系所在表空间的 OID 和文件结点返回该关系的 OID。这本质上是pg_relation_filepath的反向映射。对于数据库默认表空间中的关系,表空间可以指定为 0。如果当前数据库中没有与给定值关联的关系,或者该关系是临时关系,则返回NULL @@ -1589,13 +1530,13 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset integer - 基于在操作系统中找到的所有区域环境(locales),加入排序规则到系统目录pg_collation中。 - 这是 initdb 会用到的,更多细节请参考。 - 如果后来在操作系统上安装了额外的区域环境,可以再次运行这个函数加入新区域环境的排序规则。 - 匹配pg_collation中现有条目的区域环境将被跳过(但是这个函数不会移除以在操作系统中不再存在的区域环境为基础的排序规则对象)。 - schema参数通常是pg_catalog,但这并非强制要求,排序规则也可以安装到其他模式中。 - 该函数返回其创建的新排序规则对象的数量。 - 此函数仅限超级用户使用。 + 根据操作系统中找到的所有区域设置,向系统目录pg_collation添加排序规则。 + initdb使用的就是此函数;更多信息见。 + 如果以后在操作系统中安装了其他区域设置,可以再次运行此函数,为新区域设置添加排序规则。 + 与pg_collation中现有条目匹配的区域设置会被跳过。 + (但此函数不会删除基于操作系统中已不存在的区域设置的排序规则对象。) + schema参数通常为pg_catalog,但并非必须如此;也可以将排序规则安装到其他模式中。 + 函数返回新建的排序规则对象数量。此函数仅限超级用户使用。 @@ -1638,7 +1579,7 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset boolean - 更新表级统计信息。通常这些统计信息由自动收集或作为的一部分更新,因此不必调用此函数。但它在恢复后很有用,可以在尚未运行ANALYZE时帮助优化器选择更好的计划。 + 更新表级统计信息。通常这些统计信息会自动收集或作为的一部分更新,因此不必调用此函数。但它在恢复后很有用,可以在尚未运行ANALYZE时帮助优化器选择更好的计划。 被跟踪的统计信息可能因版本而异,所以参数以argnameargvalue对的形式传递: @@ -1663,7 +1604,7 @@ SELECT pg_restore_relation_stats( 参数schemanamerelname是必需的,用于指定表。其他参数是与pg_class中某些列对应的统计信息的名称和值。当前支持的关系统计信息包括:integer类型的relpagesreal类型的reltuplesinteger类型的relallvisible以及integer类型的relallfrozen - 此外,此函数还接受integer类型的参数名version,指定统计信息来源的服务器版本。这有助于从旧版本的PostgreSQL移植统计信息。 + 此外,此函数还接受名为versioninteger类型参数,用于指定统计信息来源的服务器版本。这预计有助于从旧版本的PostgreSQL移植统计信息。 次要错误会以WARNING报告并被忽略,其余统计信息仍将被恢复。如果所有指定的统计信息都成功恢复,则返回true,否则返回false。 @@ -1702,7 +1643,7 @@ SELECT pg_restore_relation_stats( boolean - 创建或更新列级统计信息。通常这些统计信息由自动收集或作为的一部分更新,因此不必调用此函数。但它在恢复后很有用,可以在尚未运行ANALYZE时帮助优化器选择更好的计划。 + 创建或更新列级统计信息。通常这些统计信息会自动收集或作为的一部分更新,因此不必调用此函数。但它在恢复后很有用,可以在尚未运行ANALYZE时帮助优化器选择更好的计划。 被跟踪的统计信息可能因版本而异,所以参数以argnameargvalue对的形式传递: @@ -1729,7 +1670,7 @@ SELECT pg_restore_attribute_stats( 必需的参数包括:text类型的schemanamerelname,用于指定表;text类型的attnamesmallint类型的attnum,用于指定列;以及inherited,指定统计信息是否包含来自子表的值。其他参数是与pg_stats中的列对应的统计信息的名称和值。 - 此外,此函数还接受integer类型的参数名version,指定统计信息来源的服务器版本。这有助于从旧版本的PostgreSQL移植统计信息。 + 此外,此函数还接受名为versioninteger类型参数,用于指定统计信息来源的服务器版本。这预计有助于从旧版本的PostgreSQL移植统计信息。 次要错误会以WARNING报告并被忽略,其余统计信息仍将被恢复。如果所有指定的统计信息都成功恢复,则返回true,否则返回false。 @@ -1838,8 +1779,7 @@ SELECT pg_restore_extended_stats( 由pg_stats_ext_exprs中每个统计列对应的 JSON 元素组成。 - 此外,此函数还接受类型为integer的参数名version,用于指定统计信息来源的服务器版本。 - 这有望帮助从较旧版本的PostgreSQL迁移统计信息。 + 此外,此函数还接受名为versioninteger类型参数,用于指定统计信息来源的服务器版本。这预计有助于从旧版本的PostgreSQL移植统计信息。 次要错误会以WARNING报告并忽略,而剩余统计信息仍会被恢复。 @@ -1950,7 +1890,7 @@ SELECT pg_restore_extended_stats( - 例如,要检查分区表measurement中包含的数据的总大小,可以使用以下查询: + 例如,要检查分区表measurement中包含的数据的总大小,可以使用以下查询: SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size FROM pg_partition_tree('measurement'); @@ -1965,7 +1905,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size 显示了索引维护任务可以使用的函数。 - (注意,这些维护任务通常由自动清理(autovacuum)自动完成;只有在特殊情况下才需要使用这些函数。) + (注意,这些维护任务通常由 autovacuum 自动完成;只有在特殊情况下才需要使用这些函数。) 这些函数在恢复过程中无法执行。这些函数的使用局限于超级用户和给定索引的所有者。 @@ -1996,7 +1936,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size integer - 扫描指定的BRIN索引以查找基表中当前尚未生成索引摘要的页面范围; + 扫描指定的BRIN索引以查找基表中当前尚未生成索引摘要的页面范围; 对于任何这样的范围,它都通过扫描这些表页来创建一个新的摘要索引元组。 返回插入到索引中的新页面范围摘要的数量。 @@ -2012,7 +1952,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size 对覆盖给定块的页面范围执行摘要(如果尚未摘要)。 - 这类似于brin_summarize_new_values,只是它只处理覆盖给定表块数的页范围。 + 这类似于brin_summarize_new_values,区别在于它只处理包含给定表块编号的页面范围。 @@ -2038,9 +1978,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size bigint - 清理指定GIN索引的pending列表,通过移除里面的条目,以大批的方式,到主要的GIN数据结构。 - 返回从挂起列表中删除的页数。如果参数是使用禁用fastupdate选项构建的GIN索引,则不会发生清理,结果为零,因为索引没有挂起的列表。 - 关于挂起列表和fastupdate选项的详细信息,请参见。 + 将指定 GIN 索引的待处理列表中的条目批量移入主 GIN 数据结构,从而清理该列表。返回从待处理列表中移除的页数。如果参数是禁用fastupdate选项构建的 GIN 索引,则不会进行清理,结果为零,因为该索引没有待处理列表。有关待处理列表和fastupdate选项的详细信息,参见 @@ -2055,21 +1993,20 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size 中展示的函数提供了对数据库服务器所在机器上的文件的本地访问。 - 只能访问数据库集簇目录以及log_directory中的文件,除非用户是超级用户或者被授予了角色pg_read_server_files。 + 只能访问数据库集簇目录以及log_directory中的文件,除非用户是超级用户或者被授予了角色pg_read_server_files。 使用相对路径访问集簇目录里面的文件,以及匹配 log_directory配置设置的路径访问日志文件。 - 注意在pg_read_file()或者相关函数上,向用户授予EXECUTE权限, - 以允许他们有能力读取服务器上该数据库服务器进程能读取的任何文件;这些函数会绕过所有的数据库内权限检查。 - 这意味着,例如,具有这种访问的用户能够读取pg_authid表中存储着认证信息的内容,也能读取数据库中的任何表数据。 - 因此,授予对这些函数的访问应该要很仔细地考虑。 + 注意,向用户授予pg_read_file()或相关函数的 EXECUTE 权限,会使其能够读取服务器上数据库服务器进程能读取的任何文件;这些函数会绕过数据库内部的所有权限检查。例如,具有这种访问权限的用户能够读取存储认证信息的pg_authid表的内容,以及数据库中的任何表数据。因此,授予这些函数的访问权限时应仔细考虑。 - 这些函数中的一些函数有可选的missing_ok参数,可以指定当文件或目录不存在时的行为。 - 如果为true,函数返回NULL或着空结果集,根据适合情况。 - 如果为false,会产生一个错误。默认为false。 + 授予这些函数的权限时,请注意:表中列出可选参数的条目,大多由多个参数列表不同的实际函数实现。若要使用其中某个函数,就必须单独授予该函数的权限。psql\df命令可以帮助检查实际的函数签名。 + + + + 这些函数中的一些函数接受可选的missing_ok参数,用于指定文件或目录不存在时的行为。如果为true,函数会视情况返回NULL或空结果集。如果为false,则会报错。(除文件未找到之外的失败情况,在任何情况下都会报错。)默认为false @@ -2099,12 +2036,12 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size setof text - 返回指定目录中所有文件(和目录以及其他指定文件)的名称。 - include_dot_dirs参数标示在结果集中是否包括...;默认为不包括它们。 - 要包括它们在missing_oktrue时能够有用,以从不存在的目录中辨别一个空目录。 + 返回指定目录中所有文件的名称(包括目录及其他特殊文件)。 + include_dot_dirs参数指示结果集中是否包含...;默认不包含它们。 + 在missing_oktrue时,包含它们有助于区分不存在的目录和空目录。 - 这个函数默认限制为超级用户,但是其他用户可以被授予EXECUTE以运行此函数。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -2123,7 +2060,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size 返回服务器日志目录中每个普通文件的名称、大小和最后修改时间(mtime)。以点开头的文件名、目录和其他特殊文件将被排除。 - 默认情况下,此函数仅限于超级用户和具有pg_monitor角色权限的角色,但其他用户可以被授予EXECUTE权限来运行该函数。 + 默认情况下,此函数仅限超级用户和具有pg_monitor角色权限的角色使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -2143,8 +2080,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size 以点开头的文件名、目录和其他特殊文件将被排除。 - 默认情况下,此函数仅限于超级用户和具有pg_monitor角色权限的角色, - 但其他用户可以被授予EXECUTE权限来运行该函数。 + 默认情况下,此函数仅限超级用户和具有pg_monitor角色权限的角色使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -2164,7 +2100,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size 以点开头的文件名、目录和其他特殊文件将被排除。 - 默认情况下,此函数仅限于超级用户和pg_monitor角色的成员,但其他用户可以被授予EXECUTE权限来运行该函数。 + 默认情况下,此函数仅限超级用户和pg_monitor角色的成员使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -2184,7 +2120,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size 以点开头的文件名、目录和其他特殊文件将被排除。 - 默认情况下,此函数仅限于超级用户和pg_monitor角色的成员,但其他用户可以被授予EXECUTE权限来运行该函数。 + 默认情况下,此函数仅限超级用户和pg_monitor角色的成员使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -2204,7 +2140,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size 其中slot_name是作为函数输入提供的复制槽的名称。以点开头的文件名、目录和其他特殊文件将被排除。 - 默认情况下,此函数仅限于超级用户和pg_monitor角色的成员,但其他用户可以被授予EXECUTE权限来运行该函数。 + 默认情况下,此函数仅限超级用户和pg_monitor角色的成员使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -2220,11 +2156,10 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size modificationtimestamp with time zone ) - 返回服务器的 WAL 摘要目录(pg_wal/summaries)中每个普通文件的名称、大小和最后修改时间(mtime)。 - 以点开头的文件名、目录和其他特殊文件将被排除。 + 返回服务器 WAL 摘要目录(pg_wal/summaries)中每个普通文件的名称、大小和最后修改时间(mtime)。排除名称以点开头的文件、目录及其他特殊文件。 - 默认情况下,此函数仅限于超级用户和pg_monitor角色的成员,但其他用户可以被授予EXECUTE权限来运行该函数。 + 默认情况下,此函数仅限超级用户和pg_monitor角色的成员使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -2240,11 +2175,11 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size modificationtimestamp with time zone ) - 返回服务器的WAL归档状态目录(pg_wal/archive_status)中的每个普通文件的名称、大小、和最后修改时间(mtime)。 - 文件名以一个点(dot)开始,目录和其他指定的文件不包括。 + 返回服务器 WAL 归档状态目录(pg_wal/archive_status)中每个普通文件的名称、大小和最后修改时间(mtime)。 + 以点号开头的文件名、目录以及其他特殊文件都不会包含在结果中。 - 这个函数默认限制在超级用户和pg_monitor角色的成员,但是其他用户可以被授予EXECUTE以运行此函数。 + 默认情况下,此函数仅限超级用户和pg_monitor角色的成员使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -2261,12 +2196,12 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size modificationtimestamp with time zone ) - 返回针对指定tablespace的临时文件目录中的每个普通文件的名称、大小、和最后修改时间(mtime)。 - 如果tablespace没有提供,pg_default 表空间为被检验的。 - 文件名以一个点(dot)开始,目录和其他指定的文件不包括。 + 返回针对指定tablespace的临时文件目录中每个普通文件的名称、大小和最后修改时间(mtime)。 + 如果未提供tablespace,则检查pg_default表空间。 + 以点号开头的文件名、目录以及其他特殊文件都不会包含在结果中。 - 这个函数默认限制在超级用户和pg_monitor角色的成员,但是其他用户可以被授予EXECUTE以运行此函数。 + 默认情况下,此函数仅限超级用户和pg_monitor角色的成员使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -2275,16 +2210,16 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size pg_read_file - pg_read_file ( filenametext, offset bigint, length bigint , missing_ok boolean ) + pg_read_file ( filenametext, offset bigint, length bigint , missing_ok boolean ) text - 返回一个文本文件的全部或部分,开始于给定的字节offset,在最大的length字节返回(如果文件的结尾先达到了则减少)。 - 如果offset为负,他于文件的结尾有关。如果offsetlength 被省略,整个文件被返回。 - 从文件中读的字节在服务器的编码中解释为字符串;如果它们在哪些编码中不是有效的则抛出错误。 + 返回一个文本文件的全部或部分,从给定的字节offset开始,最多返回length字节(如果先到达文件末尾,则返回更少)。 + 如果offset为负,则它相对于文件末尾计算。如果省略offsetlength,则返回整个文件。 + 从文件中读取的字节会按数据库编码解释为字符串;如果它们在该编码下无效,则会抛出错误。 - 这个函数默认限制在超级用户,但是其他用户可以被授予EXECUTE以运行此函数。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -2293,18 +2228,18 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size pg_read_binary_file - pg_read_binary_file ( filenametext, offset bigint, length bigint , missing_ok boolean ) + pg_read_binary_file ( filenametext, offset bigint, length bigint , missing_ok boolean ) bytea - 返回文件的全部或部分。这个函数与pg_read_file 是完全相同的,除了它可以读任意的二进制数据,返回结果为bytea而不是text; - 因此,没有编码检查会被执行。 + 返回文件的全部或部分。该函数与pg_read_file完全相同,只是它可以读取任意二进制数据,并返回bytea而不是text; + 因此不会执行编码检查。 - 这个函数默认限制在超级用户,但是其他用户可以被授予EXECUTE以运行此函数。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 - 与 convert_from函数组合,这个函数能被用于以指定的编码读文本文件并转换到数据库的编码: + 与convert_from函数配合使用时,该函数可用于按指定编码读取文本文件,并将其转换为数据库编码: SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); @@ -2326,10 +2261,10 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); isdir boolean ) - 返回一个记录,包含文件的大小、最后访问时间戳、最后修改时间戳,最后文件状态变更时间戳(仅在UNIX平台)、文件建立时间戳(仅Windows),和一个标志旗如果它是一个目录。 + 返回一个记录,包含文件大小、最后访问时间戳、最后修改时间戳、最后文件状态变更时间戳(仅限 Unix 平台)、文件创建时间戳(仅限 Windows)以及一个指示其是否为目录的标志。 - 这个函数默认限制在超级用户,但是其他用户可以被授予EXECUTE以运行此函数。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -2349,11 +2284,11 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); - 所有这些函数都打算用于锁定应用程序定义的资源,可以通过一个64位键值或两个32位键值来标识(注意这两个键空间不能重叠)。 - 如果另一个会话已经在相同的资源标识符上持有一个冲突的锁,函数将等待直到资源变成可用,或者返回一个false结果,合适于函数的。 - 锁可以是共享或排他的:共享锁不会与同一资源上的其他共享锁发生冲突,只会与排他锁发生冲突。 - 锁可以在会话级(这样它们被保持直到释放或会话结束)或在事务级(这样它们被保持直到当前事务结束;没有手动释放的供应)。 - 多个会话级锁请求堆栈,因此如果同一个资源标识符被锁定三次,那么必须有三个解锁请求来释放资源,在会话结束之前。 + 这些函数用于锁定应用程序定义的资源;资源可用一个 64 位键值或两个 32 位键值标识(这两个键空间互不重叠)。 + 如果另一个会话已对同一资源标识符持有冲突锁,函数会根据自身的行为等待资源可用,或返回false。 + 锁可以是共享的或排他的:共享锁不会与同一资源上的其他共享锁冲突,只会与排他锁冲突。 + 锁可以在会话级获取(一直保持到释放或会话结束),也可以在事务级获取(一直保持到当前事务结束,不能手动释放)。 + 多次会话级锁请求会累加,因此,如果同一资源标识符被锁定三次,就必须请求解锁三次,才能在会话结束前释放该资源。
@@ -2504,8 +2439,8 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); boolean - 获取一个排他的会话级咨询锁,如果适用。 - 这将立即获得锁并返回true,或者如果不能立即获取锁则立即返回 false而无需等待。 + 尝试获取一个排他的会话级咨询锁。 + 如果能立即获取到锁,就返回true;否则立即返回false,而不等待。 @@ -2522,8 +2457,8 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); boolean - 获取一个共享的会话级咨询锁,如果适用。 - 这将立即获得锁并返回true,或者如果不能立即获取锁则立即返回 false而无需等待。 + 尝试获取一个共享的会话级咨询锁。 + 如果能立即获取到锁,就返回true;否则立即返回false,而不等待。 @@ -2540,8 +2475,8 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); boolean - 获取一个排他的事务级咨询锁,如果适用。 - 这将立即获得锁并返回true,或者如果不能立即获取锁则立即返回 false而无需等待。 + 尝试获取一个排他的事务级咨询锁。 + 如果能立即获取到锁,就返回true;否则立即返回false,而不等待。 @@ -2558,8 +2493,8 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); boolean - 获取一个共享的事务级咨询锁,如果适用。 - 这将立即获得锁并返回true,或者如果不能立即获取锁则立即返回 false而无需等待。 + 尝试获取一个共享的事务级咨询锁。 + 如果能立即获取到锁,就返回true;否则立即返回false,而不等待。 diff --git a/zh/19/func/func-aggregate.sgml b/zh/19/func/func-aggregate.sgml index 886ed857..c4d6a5b6 100644 --- a/zh/19/func/func-aggregate.sgml +++ b/zh/19/func/func-aggregate.sgml @@ -8,11 +8,11 @@ - 聚合函数从一个输入值的集合计算出一个单一值。 - 内置的通用聚合函数在中列出,而统计性聚合是在中列出。 + 聚合函数从一个输入值的集合计算出一个单一结果。 + 内置的通用聚合函数在中列出,而统计聚合函数在中列出。 内置的组内有序集聚合函数在中列出,而内置的组内假想集聚合在中列出。 与聚合函数紧密相关的分组操作在中列出。 - 中会解释针对聚合函数的特殊语法考虑。额外的介绍信息请参考。 + 中会解释针对聚合函数的特殊语法注意事项。更多入门信息请参考 @@ -20,8 +20,8 @@ - 尽管下面所有聚合函数都接受一个可选的ORDER BY子句(如所述), - 但该子句只添加到了输出会受到排序影响的那些聚合函数上。 + 虽然下面所有聚合函数都接受可选的ORDER BY子句 + (详见),但这里只在输出受排序影响的聚合函数签名中列出了该子句。
@@ -51,12 +51,12 @@ any_valueany_value ( anyelement ) - same as input type + 与输入类型相同 从非空输入值中返回任意一个值。 - Yes + @@ -70,7 +70,7 @@ 将所有输入值,包括空值,收集到一个数组中。 - No + @@ -79,15 +79,15 @@ anyarray - 将所有输入数组连接到一个更高维度的数组中。(输入必须都具有相同的维度,并且不能为空的(empty)或空值(null)。) + 将所有输入数组连接成维数增加一维的数组。(所有输入的维数必须相同,且不能是空数组或空值(NULL)。) - No + - average + 平均值 avg @@ -122,7 +122,7 @@ 计算所有非空输入值的平均值(算术平均值)。 - Yes + @@ -146,9 +146,9 @@ bit - 计算所有非空输入值的逐位AND。 + 计算所有非空输入值的按位与。 - Yes + @@ -172,9 +172,9 @@ bit - 计算所有非空输入值的逐位OR。 + 计算所有非空输入值的按位或。 - Yes + @@ -201,7 +201,7 @@ 计算所有非空输入值的按位异或。 可用作一组无序的值集合的校验和。 - Yes + @@ -215,7 +215,7 @@ 如果全部非空输入值都为真则返回真,否则返回假。 - Yes + @@ -229,7 +229,7 @@ 如果任何非空输入值为真则返回真,否则返回假。 - Yes + @@ -243,7 +243,7 @@ 计算输入行的数量。 - Yes + @@ -254,7 +254,7 @@ 计算输入值不为空的输入行的数量。 - Yes + @@ -266,9 +266,9 @@ boolean - 这是对应bool_and的SQL标准的等效物。 + 这是标准 SQL 中与bool_and等价的函数。 - Yes + @@ -289,7 +289,7 @@ 收集所有输入值,包括空值,到一个JSON数组。根据to_jsonto_jsonb将值转换为JSON。 - No + @@ -308,9 +308,9 @@ jsonb - 收集所有输入值,跳过空值,到一个JSON数组。根据to_jsonto_jsonb将值转换为JSON。 + 将所有非空输入值收集到一个JSON数组中,跳过空值。根据to_jsonto_jsonb将值转换为JSON。 - No + @@ -325,14 +325,14 @@ 行为与json_array相同,只是它作为一个聚合函数,因此只接受一个 value_expression参数。 - 如果指定了ABSENT ON NULL,则会省略任何NULL值。 + 如果指定了ABSENT ON NULL,则会省略所有 NULL 值。 如果指定了ORDER BY,元素将按该顺序出现在数组中,而不是按输入顺序。 SELECT json_arrayagg(v) FROM (VALUES(2),(1)) t(v) [2, 1] - No + @@ -345,15 +345,15 @@ RETURNING data_type FORMAT JSON ENCODING UTF8 ) - 行为与json_object相同,只是它作为一个聚合函数,因此只接受一个 + 行为与json_object相同,只是它作为一个聚合函数,因此只接受一个 key_expression参数和一个 value_expression参数。 - + SELECT json_objectagg(k:v) FROM (VALUES ('a'::text,current_date),('b',current_date + 1)) AS t(k,v) { "a" : "2022-05-10", "b" : "2022-05-11" } - No + @@ -378,10 +378,10 @@ jsonb - 将所有键/值对收集到一个JSON对象中。关键参数强制转换为文本;值参数按照to_jsonto_jsonb进行转换。 + 将所有键/值对收集到一个JSON对象中。键参数强制转换为文本;值参数按照to_jsonto_jsonb进行转换。 值可以为空,但键不能(为空)。 - No + @@ -430,10 +430,10 @@ jsonb - 将所有键/值对收集到一个JSON对象中。关键参数强制转换为文本;值参数按照to_jsonto_jsonb进行转换。 + 将所有键/值对收集到一个JSON对象中。键参数强制转换为文本;值参数按照to_jsonto_jsonb进行转换。 值可以为空,但键不能为空。如果存在重复键,则会抛出错误。 - No + @@ -468,8 +468,8 @@ 最大值 - max ( see text ) - same as input type + max ( 见说明 ) + 与输入类型相同 计算非空输入值的最大值。适用于任何数字、字符串、日期/时间或枚举类型, @@ -486,8 +486,8 @@ 最小值 - min ( see text ) - same as input type + min ( 见说明 ) + 与输入类型相同 计算非空输入值的最小值。适用于任何数字、字符串、日期/时间或枚举类型, @@ -516,7 +516,7 @@ 计算非空输入值的并集。 - No + @@ -536,7 +536,7 @@ 计算非空输入值的交集。 - No + @@ -555,9 +555,9 @@ bytea - 将非 null 输入值连接成一个字符串。第一个值之后的每个值前面都会放置相应的delimiter(如果它不为 null)。 + 将非 NULL 输入值连接成一个字符串。在第一个值之后,每个值前面都会放置相应的delimiter(如果它不为 NULL)。 - No + @@ -599,7 +599,7 @@ 计算非空输入值的总和。 - Yes + @@ -611,37 +611,24 @@ xml - 连接非空的XML输入值(参见)。 + 连接非空的 XML 输入值(参见)。 - No +
- 应该注意的是,除了count之外,这些函数在没有选择行时返回空值。 - 特别地,行数的sum返回空(null),而不是预期的零,array_agg在没有输入行时返回空(null)而不是空数组。 - coalesce函数可以在必要时用零或空数组代替空(null)。 + 需要注意,除了count之外,这些函数在没有选中任何行时都会返回空值。特别地,sum在没有输入行时返回空值,而不是预期中的零;array_agg在没有输入行时返回空值,而不是空数组。必要时,可以用coalesce函数把空值替换成零或空数组。 - 聚合函数 array_agg,json_agg, jsonb_agg,json_object_agg, jsonb_object_agg, - json_agg_strict, jsonb_agg_strict, - json_object_agg_strict, jsonb_object_agg_strict, - json_object_agg_unique, jsonb_object_agg_unique, - json_object_agg_unique_strict, - jsonb_object_agg_unique_strict, - string_agg, - 和 xmlagg,以及类似的用户定义的聚合函数,根据输入值的顺序产生富有意义的不同的结果值。 - 默认情况下,这种排序是不指定的,但可以通过在聚合调用中写入ORDER BY子句来控制,如所示。 - 或者,从排序的子查询提供输入值通常也可以。例如: - + 聚合函数array_aggjson_aggjsonb_aggjson_agg_strictjsonb_agg_strictjson_object_aggjsonb_object_aggjson_object_agg_strictjsonb_object_agg_strictjson_object_agg_uniquejsonb_object_agg_uniquejson_object_agg_unique_strictjsonb_object_agg_unique_strictstring_aggxmlagg,以及类似的用户定义聚合函数,其结果值会随输入值的顺序发生实质性变化。默认情况下,输入顺序未指定,但可以在聚合调用中写入ORDER BY子句来控制,如所示。也可以用已排序的子查询提供输入值,这通常也能奏效。例如: - - 注意,如果外部查询级别包含其他处理,例如关联,则此方法可能会失败,因为这可能导致子查询的输出在计算聚合之前重新排序。 + 需要注意,如果外层查询包含连接等额外处理,这种方法可能失效,因为子查询的输出可能在计算聚合之前被重新排序。 @@ -655,31 +642,24 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; - 布尔聚合 bool_andbool_or 对应于标准SQL聚合 everyanysome. - PostgreSQL 支持 every, 但不支持 anysome, 因为标准语法中存在模糊性: - + 布尔聚合bool_andbool_or对应于标准 SQL 聚合everyanysome。 + PostgreSQL支持every,但不支持anysome,因为标准语法中存在歧义: SELECT b1 = ANY((SELECT b2 FROM t2 ...)) FROM t1 ...; - - 这里ANY可以被认为是引入子查询,或者是聚合函数,如果子查询返回一行布尔值。因此,不能为这些聚合提供标准名称。 +此处的ANY既可以被视为引入一个子查询,也可以在该子查询返回一行布尔值时被视为聚合函数。因此,不能将标准名称用于这些聚合。 - 习惯使用其他SQL数据库管理系统的用户可能会对count聚合应用于整个表时的性能感到失望。一个类似下面的查询: - + 习惯于其他 SQL 数据库管理系统的用户,可能会对count聚合用于整个表时的性能感到失望。如下查询: SELECT count(*) FROM sometable; - - 将需要与表大小成比例的工作:PostgreSQL将需要扫描整个表或包含表中所有行的索引。 +所需的工作量与表大小成正比:PostgreSQL需要扫描整个表,或者完整扫描一个包含表中所有行的索引。 - 显示了统计分析中常用的聚合函数。 - (这些被分离出来仅仅是为了避免使更常用的聚合列表混乱。) - 显示为接受numeric_type的函数可用于所有类型smallint, integer,bigint, numeric, real, 和 double precision。 - 在描述中提及N时,它意味着所有输入表达式都非空的输入行数。在所有情况下,如果计算没有意义,则返回null,例如当N为0时。 + 列出了统计分析中常用的聚合函数。(将它们单独列出,只是为了避免更常用的聚合函数列表过于杂乱。)标为接受numeric_type的函数适用于smallintintegerbigintnumericrealdouble precision这些类型。描述中提到的N表示所有输入表达式都非空的输入行数。无论哪种情况,如果计算没有意义,例如N为 0,就返回 null。 @@ -714,7 +694,7 @@ SELECT count(*) FROM sometable; - correlation + 相关性 corr @@ -725,14 +705,14 @@ SELECT count(*) FROM sometable; 计算相关系数。 - Yes + - covariance - population + 协方差 + 总体 covar_pop @@ -743,14 +723,14 @@ SELECT count(*) FROM sometable; 计算总体协方差。 - Yes + - covariance - sample + 协方差 + 样本 covar_samp @@ -761,7 +741,7 @@ SELECT count(*) FROM sometable; 计算样本协方差。 - Yes + @@ -773,9 +753,9 @@ SELECT count(*) FROM sometable; double precision - 计算自变量的平均值,sum(X)/N. + 计算自变量的平均值,即sum(X)/N - Yes + @@ -787,9 +767,9 @@ SELECT count(*) FROM sometable; double precision - 计算因变量的平均值,sum(Y)/N. + 计算因变量的平均值,即sum(Y)/N - Yes + @@ -803,13 +783,13 @@ SELECT count(*) FROM sometable; 计算两个输入都非空的行数。 - Yes + - regression intercept + 回归截距 regr_intercept @@ -818,9 +798,9 @@ SELECT count(*) FROM sometable; double precision - 计算由(XY)对决定的最小二乘拟合的线性方程的Y-截距。 + 计算由(XY)数值对确定的最小二乘拟合线性方程的 y 轴截距。 - Yes + @@ -834,13 +814,13 @@ SELECT count(*) FROM sometable; 计算相关系数的平方。 - Yes + - regression slope + 回归斜率 regr_slope @@ -849,9 +829,9 @@ SELECT count(*) FROM sometable; double precision - 计算由(X, Y)对决定的最小二乘拟合的线性方程的斜率。 + 计算由(XY)数值对确定的最小二乘拟合线性方程的斜率。 - Yes + @@ -863,10 +843,9 @@ SELECT count(*) FROM sometable; double precision - 计算自变量的平方和 - sum(X^2) - sum(X)^2/N. + 计算自变量的平方和,即sum(X^2) - sum(X)^2/N - Yes + @@ -878,10 +857,9 @@ SELECT count(*) FROM sometable; double precision - 计算独立变量乘以因变量的sum of products, - sum(X*Y) - sum(X) * sum(Y)/N. + 计算自变量与因变量的乘积和,即sum(X*Y) - sum(X) * sum(Y)/N - Yes + @@ -893,69 +871,62 @@ SELECT count(*) FROM sometable; double precision - 计算因变量的平方和, - sum(Y^2) - sum(Y)^2/N. + 计算因变量的平方和,即sum(Y^2) - sum(Y)^2/N - Yes + - standard deviation + 标准差 stddev stddev ( numeric_type ) - double precision - for real or double precision, - otherwise numeric + 对于realdouble precision输入,返回double precision;否则返回numeric - 这是stddev_samp的一个历史别称。 + 这是stddev_samp的一个历史别名。 - Yes + - standard deviation - population + 标准差 + 总体 stddev_pop stddev_pop ( numeric_type ) - double precision - for real or double precision, - otherwise numeric + 对于realdouble precision输入,返回double precision;否则返回numeric 计算输入值的总体标准差。 - Yes + - standard deviation - sample + 标准差 + 样本 stddev_samp stddev_samp ( numeric_type ) - double precision - for real or double precision, - otherwise numeric + 对于realdouble precision输入,返回double precision;否则返回numeric 计算输入值的样本标准差。 - Yes + @@ -964,54 +935,48 @@ SELECT count(*) FROM sometable; variance variance ( numeric_type ) - double precision - for real or double precision, - otherwise numeric + 对于realdouble precision输入,返回double precision;否则返回numeric - 这是 var_samp 的一个历史别称。 + 这是 var_samp 的一个历史别名。 - Yes + - variance - population + 方差 + 总体 var_pop var_pop ( numeric_type ) - double precision - for real or double precision, - otherwise numeric + 对于realdouble precision输入,返回double precision;否则返回numeric - 计算输入值的总体方差(总体标准差的平方)。 + 计算输入值的总体方差(总体标准差的平方)。 - Yes + - variance - sample + 方差 + 样本 var_samp var_samp ( numeric_type ) - double precision - for real or double precision, - otherwise numeric + 对于realdouble precision输入,返回double precision;否则返回numeric - 计算输入值的样本方差(样本标准差的平方)。 + 计算输入值的样本方差(样本标准差的平方)。 - Yes + @@ -1022,11 +987,11 @@ SELECT count(*) FROM sometable; 这些函数有时被称为逆分布函数。 它们的聚合输入通过ORDER BY引入,还可以接受未聚合的直接参数,但后者只计算一次。 所有这些函数在其聚合输入中都忽略空(null)值。 - 对于使用fraction参数的函数,分数值必须在 0 到 1 之间;否则会报错。但是,null 的 fraction 值只会产生一个 null 结果。 + 对于使用fraction参数的函数,比例值必须在 0 到 1 之间;否则会报错。但是,null 的 fraction 值只会产生一个 null 结果。 - ordered-set aggregate + 有序集聚合 内置 @@ -1058,16 +1023,16 @@ SELECT count(*) FROM sometable; - mode - statistical + 众数 + 统计 mode () WITHIN GROUP ( ORDER BY anyelement ) anyelement - 计算mode,即聚合参数最频繁的值(如果有多个相同频繁的值,第一个可以任意选择)。聚合参数必须是可排序类型。 + 计算众数,即聚合参数中出现次数最多的值(若多个值的出现次数相同且最多,则任意选择其中第一个)。聚合参数必须是可排序类型。 - No + @@ -1085,9 +1050,9 @@ SELECT count(*) FROM sometable; 计算连续百分位点,该值对应于聚合参数值有序集合中的指定fraction。 - 如果需要,这将在相邻的输入项之间插入。 + 必要时会在相邻输入项之间进行插值。 - No + @@ -1102,7 +1067,7 @@ SELECT count(*) FROM sometable; 计算多个连续百分位点。结果是一个与fractions参数具有相同维度的数组,其中每个非 null 元素都被替换为对应百分位点的值(必要时会进行插值)。 - No + @@ -1118,7 +1083,7 @@ SELECT count(*) FROM sometable; 计算离散百分位数,即聚合参数值的有序集合中的第一个值,该值在排序中的位置等于或超过指定的fraction。 聚合参数必须是可排序类型。 - No + @@ -1131,14 +1096,14 @@ SELECT count(*) FROM sometable; 结果是一个与fractions参数具有相同维数的数组,每个非空元素都被对应于该百分位数的输入值替换。 聚合参数必须是可排序类型。 - No + - hypothetical-set aggregate + 假想集聚合 内置 @@ -1174,52 +1139,52 @@ SELECT count(*) FROM sometable; rank - hypothetical + 假设行 rank ( args ) WITHIN GROUP ( ORDER BY sorted_args ) bigint - 计算假设行的排名,包括间隔,就是说在它的同等行组中第一行的行号。 + 计算假设行的排名,允许空缺;即该行所属同等行组中第一行的行号。 - No + dense_rank - hypothetical + 假设行 dense_rank ( args ) WITHIN GROUP ( ORDER BY sorted_args ) bigint - 计算假设行的排名,没有间隔;这个功能有效地计数同等行组。 + 计算假设行的排名,没有空缺;此函数实际上对同等行组进行计数。 - No + percent_rank - hypothetical + 假设行 percent_rank ( args ) WITHIN GROUP ( ORDER BY sorted_args ) double precision - 计算假设行的相关排行,也就是(rank - 1) / (total rows - 1)。取值范围为 0 到 1(含)。 + 计算假设行的相对排名,即(rank - 1)/(总行数 - 1)。取值范围为 0 到 1(含)。 - No + cume_dist - hypothetical + 假设行 cume_dist ( args ) WITHIN GROUP ( ORDER BY sorted_args ) double precision @@ -1227,7 +1192,7 @@ SELECT count(*) FROM sometable; 计算累积分布,也就是(位于假设行之前或与假设行同等的行数)/(总行数)。取值范围为 1/N 到 1。 - No + @@ -1260,8 +1225,7 @@ SELECT count(*) FROM sometable; integer - 返回一个位掩码以指示哪个GROUP BY表达式没有包含在当前分组集中。 - 比特位被分配给最右边的参数对应于最低有效位;如果对应的表达式包含在生成当前结果行的分组集的分组条件中,则每个位为0,如果不包含则为1。 + 返回一个位掩码,指示哪些GROUP BY表达式未包含在当前分组集中。分配比特位时,最右侧参数对应最低有效位;如果相应表达式包含在生成当前结果行的分组集的分组条件中,该位为 0,否则为 1。 @@ -1269,9 +1233,7 @@ SELECT count(*) FROM sometable; - 所示的分组操作与分组集(参见)共同使用,以区分结果行。 - GROUPING函数的参数实际上并不求值,但它们必须与相关查询级别的GROUP BY子句中给出的表达式完全匹配。例如: - + 在中列出的分组操作与分组集配合使用(参见),以区分结果行。传给GROUPING函数的参数不会实际求值,但它们必须与相关查询层级的GROUP BY子句中的表达式完全匹配。例如: => SELECT * FROM items_sold; make | model | sales -------+-------+------- @@ -1292,9 +1254,7 @@ SELECT count(*) FROM sometable; Bar | | 1 | 20 | | 3 | 50 (7 rows) - - 在这里,前四行中的grouping0表明这些已经正常分组,在两个分组列上。 - 值1表示model没有在倒数两行中分组,值3表示无论是make还是model都没有在最后一行中分组(因此,这是所有输入行的聚合)。 +这里,前四行的grouping值为0,表明这些行按两个分组列正常分组。值1表明model未用于倒数第二、第三行的分组,值3则表明最后一行既未按make分组,也未按model分组(因此该行聚合了全部输入行)。 diff --git a/zh/19/func/func-array.sgml b/zh/19/func/func-array.sgml index b32b17c3..b3954e35 100644 --- a/zh/19/func/func-array.sgml +++ b/zh/19/func/func-array.sgml @@ -5,9 +5,9 @@ 显示了可以用于数组类型的专用的操作符。 除此之外,中所示的常用比较操作符也适用于数组。 - 比较操作符逐个元素的比较数组内容,使用默认的元素数据类型的B-树比较函数,并根据第一个差值进行排序。 + 比较操作符逐个元素比较数组内容,使用元素数据类型的默认 B-树比较函数,并根据第一个差异进行排序。 多维数组的元素按照行序进行访问(最后的下标变化最快)。 - 如果两个数组的内容相同但维数不等,那么维度信息中的第一个不同将决定排序顺序。 + 如果两个数组的内容相同但维度信息不同,那么维度信息中的第一个不同将决定排序顺序。 @@ -38,7 +38,7 @@ 第一个数组是否包含第二个数组,也就是说,出现在第二个数组中的每个元素是否等于第一个数组中的某个元素? - (重复值不需要特殊处理,因此ARRAY[1]ARRAY[1,1]被认为包含对方。) + (重复元素不作特殊处理,因此ARRAY[1]ARRAY[1,1]被认为包含对方。) ARRAY[1,4,3] @> ARRAY[3,1,3] @@ -80,8 +80,7 @@ anycompatiblearray - 连接两个数组。连接空(null)或空数组是一个无操作(no-op);否则,数组必须具有相同的维度数(如第一个示例所示),或者维度数相差一个(如第二个示例所示)。 - 如果数组不是完全相同的元素类型,它们将被强制转换成一个共同的类型(参见)。 + 连接两个数组。连接 null 或空数组不会产生任何效果;否则,数组必须具有相同的维数(如第一个示例所示),或维数相差一维(如第二个示例所示)。如果数组的元素类型不同,则会将它们强制转换为同一个类型(参见)。 ARRAY[1,2,3] || ARRAY[4,5,6,7] @@ -113,7 +112,7 @@ anycompatiblearray - 将元素连接到数组的末尾(数组必须为空或一维的[one-dimensional])。 + 将元素连接到数组的末尾(数组必须为空或一维)。 ARRAY[4,5,6] || 7 @@ -125,7 +124,7 @@
- 参阅获取有关数组操作符行为的更多细节。有关哪些操作符支持被索引的操作,请参阅。 + 参阅获取有关数组操作符行为的更多细节。有关哪些操作符支持索引操作,请参阅 @@ -214,8 +213,7 @@ anyarray - 返回一个包含给定值的拷贝的数组,其维数与第二个参数指定的长度相同。 - 可选的第三个参数提供每个维度的下界值(默认为全部为 1)。 + 返回用给定值的副本填充的数组,各维的长度由第二个参数指定。可选的第三个参数提供各维的下界值(默认均为1)。 array_fill(11, ARRAY[2,3]) @@ -296,7 +294,7 @@ integer - 返回阵列中第二个参数中第一次发生的下标,如果它不存在,则返回NULL。 + 返回第二个参数在数组中首次出现的下标;若不存在,则返回NULL。 如果给出了第三个参数,则搜索从该下标开始。数组必须是一维的。比较是使用IS NOT DISTINCT FROM语义进行的,所以可以搜索NULL @@ -314,9 +312,9 @@ integer[] - 返回作为第一个参数的数组中第二个参数所有出现的下标的数组。 + 返回第二个参数在第一个参数所给数组中所有出现位置的下标数组。 数组必须是一维的。使用IS NOT DISTINCT FROM语义完成比较,所以可以搜索NULL。 - 只有当数组为NULL时才返回NULL;如果在数组中没有找到该值,则返回空数组。 + 只有当数组为NULL时才返回NULL;如果在数组中没有找到该值,则返回空数组。 array_positions(ARRAY['A','A','B','A'], 'A') @@ -443,7 +441,7 @@ anyarray - 对数组的第一维进行排序。排序顺序由数组元素类型的默认排序规则决定;不过,如果元素类型支持排序规则,也可以通过给array参数添加COLLATE子句来指定要使用的排序规则。 + 对数组的第一维进行排序。排序顺序由数组元素类型的默认排序顺序决定;不过,如果元素类型支持排序规则,也可以通过给array参数添加COLLATE子句来指定要使用的排序规则。 如果descending为 true,则按降序排序,否则按升序排序。省略时默认按升序排序。如果nulls_first为 true,则空值出现在非空值之前,否则空值出现在非空值之后。省略时,nulls_first取与descending相同的值。 @@ -516,7 +514,7 @@ anyarray - 通过删除最后的n元素来裁剪数组。 + 通过删除最后的n个元素来裁剪数组。 如果数组是多维的,则只裁剪第一个维度。 @@ -565,7 +563,7 @@ 将多个数组(可能是不同的数据类型)展开到一组行中。 如果数组的长度不完全相同,那么较短的数组将用NULL填充。 - 这种形式只在查询的FROM子句中允许;参见。 + 这种形式只允许出现在查询的 FROM 子句中;参见 SELECT * FROM unnest(ARRAY[1, 2], ARRAY['foo', 'bar', 'baz']) AS x(a, b) diff --git a/zh/19/func/func-binarystring.sgml b/zh/19/func/func-binarystring.sgml index 92535b34..3a533e47 100644 --- a/zh/19/func/func-binarystring.sgml +++ b/zh/19/func/func-binarystring.sgml @@ -3,17 +3,17 @@ 二进制串函数和操作符 - binary data - functions + 二进制数据 + 函数 - 本节描述那些检查和操作二进制字符串的函数和操作符,这是类型bytea的值。 + 本节描述用于检查和操作二进制字符串(即bytea类型的值)的函数和操作符。 其中许多函数在用途和语法上都与上一节中描述的文本字符串函数等效。 - SQL定义了一些使用关键字而不是逗号来分割参数的串函数。详情请见PostgreSQL也提供了这些函数使用常规函数调用语法的版本(参阅)。 + SQL定义了一些使用关键字而不是逗号来分隔参数的字符串函数。详情请见PostgreSQL也提供了这些函数使用常规函数调用语法的版本(参阅)。 @@ -40,14 +40,14 @@ - binary string - concatenation + 二进制串 + 串接 bytea || bytea bytea - 连接两个二进制字符串。 + 串接两个二进制字符串。 '\x123456'::bytea || '\x789a00bcde'::bytea @@ -72,6 +72,42 @@ + + + + btrim + + btrim ( bytes bytea, + bytesremoved bytea ) + bytea + + + 从bytes的开头和结尾移除仅由bytesremoved中字节组成的最长字符串。 + + + btrim('\x1234567890'::bytea, '\x9012'::bytea) + \x345678 + + + + + + + ltrim + + ltrim ( bytes bytea, + bytesremoved bytea ) + bytea + + + 从bytes的开头移除仅由bytesremoved中字节组成的最长字符串。 + + + ltrim('\x1234567890'::bytea, '\x9012'::bytea) + \x34567890 + + + @@ -98,8 +134,7 @@ bytea - 将bytes的子字符串替换为newsubstring,该子字符串从start字节开始,并以count字节扩展。 - 如果忽略了count,则默认为newsubstring的长度。 + 用newsubstring替换bytes中从第start个字节开始、长度为count个字节的子字符串。如果省略count,则默认为newsubstring的长度。 overlay('\x1234567890'::bytea PLACING '\002\003'::bytea FROM 2 FOR 3) @@ -116,7 +151,7 @@ integer - 返回bytes中指定的substring的第一个起始索引,如果不存在,则为零。 + 返回substringbytes中首次出现的位置;如果不存在则返回零。 position('\x5678'::bytea IN '\x1234567890'::bytea) @@ -124,6 +159,24 @@ + + + + rtrim + + rtrim ( bytes bytea, + bytesremoved bytea ) + bytea + + + 从bytes的结尾移除仅由bytesremoved中字节组成的最长字符串。 + + + rtrim('\x1234567890'::bytea, '\x9012'::bytea) + \x12345678 + + + @@ -133,8 +186,7 @@ bytea - 提取bytesstart字节开始的子字符串,如果指定了,并且在count字节之后停止,如果指定了的话。 - 至少提供startcount中的一个。 + 提取bytes的子字符串:若指定了起始位置,则从第start个字节开始;若指定了长度,则在提取count个字节后停止。startcount至少需要指定一个。 substring('\x1234567890'::bytea FROM 3 FOR 2) @@ -153,7 +205,7 @@ bytea - 删除bytesremoved中只包含字节的最长字符串,从bytes的开始、结束,或两端(BOTH 为默认的)。 + 从bytes的开头、结尾或两端(默认为BOTH)移除仅由bytesremoved中字节组成的最长字符串。 trim('\x9012'::bytea from '\x1234567890'::bytea) @@ -169,7 +221,7 @@ bytea - 这是trim()的非标准语法。 + 这是一个非标准的trim()语法。 trim(both from '\x1234567890'::bytea, '\x9012'::bytea) @@ -181,7 +233,7 @@
- 还有一些二进制串处理函数可以使用,在列出。 其中有一些是在内部使用,用于实现列出的 SQL 标准串函数。 + 还有一些二进制串处理函数可以使用,在列出。 其中有一些是在内部使用,用于实现列出的 SQL 标准串函数。 @@ -218,7 +270,7 @@ bigint - 返回二进制字符串中设置的位数(也被认为popcount)。 + 返回二进制字符串中被置位的位数(也称为popcount)。 bit_count('\x1234567890'::bytea) @@ -260,23 +312,7 @@ - - - - btrim - - btrim ( bytes bytea, - bytesremoved bytea ) - bytea - - - 从bytes的开始和结束处删除只包含bytesremoved中出现的字节的最长字符串 - - - btrim('\x1234567890'::bytea, '\x9012'::bytea) - \x345678 - - + @@ -288,7 +324,7 @@ integer - 从二进制字符串中提取 n'th 位。 + 从二进制字符串中提取 编号为 n 的 位。 get_bit('\x1234567890'::bytea, 30) @@ -306,7 +342,7 @@ integer - 从二进制字符串中提取 n'th 字节。 + 从二进制字符串中提取 编号为 n 的 字节。 get_byte('\x1234567890'::bytea, 4) @@ -320,13 +356,13 @@ length - binary string - length + 二进制串 + 长度 - length - 二进制字符串 - binary strings, length + 长度 + 二进制串 + 二进制串,长度 length ( bytea ) integer @@ -355,23 +391,7 @@ - - - - ltrim - - ltrim ( bytes bytea, - bytesremoved bytea ) - bytea - - - 从bytes开头移除出现在bytesremoved中的只包含字节的最长字符串。 - - - ltrim('\x1234567890'::bytea, '\x9012'::bytea) - \x34567890 - - + @@ -390,23 +410,24 @@ + + - - - rtrim - - rtrim ( bytes bytea, - bytesremoved bytea ) - bytea - - - 从bytes结尾移除出现在bytesremoved中的只包含字节的最长字符串。 - - - rtrim('\x1234567890'::bytea, '\x9012'::bytea) - \x12345678 - - + + + reverse + + reverse ( bytea ) + bytea + + + 反转二进制字符串中字节的顺序。 + + + reverse('\xabcd'::bytea) + \xcdab + + @@ -419,7 +440,7 @@ bytea - 设置二进制字符串中的n'th位为newvalue。 + 设置二进制字符串中的编号为 n 的位为newvalue set_bit('\x1234567890'::bytea, 30, 0) @@ -438,7 +459,7 @@ bytea - 设置二进制字符串中的 n'th 字节到 newvalue。 + 设置二进制字符串中的 编号为 n 的 字节到 newvalue set_byte('\x1234567890'::bytea, 4, 64) @@ -493,7 +514,7 @@ sha384('abc'::bytea) - \xcb00753f45a35e8bb5a03d699ac65007&zwsp;272c32ab0ed1631a8b605a43ff5bed&zwsp;8086072ba1e7cc2358baeca134c825a7 + \xcb00753f45a35e8bb5a03d699ac65007&zwsp;272c32ab0eded1631a8b605a43ff5bed&zwsp;8086072ba1e7cc2358baeca134c825a7 @@ -510,7 +531,7 @@ sha512('abc'::bytea) - \xddaf35a193617abacc417349ae204131&zwsp;12e6fa4e89a97ea20a9ee64b55d39a&zwsp;2192992a274fc1a836ba3c23a3feebbd&zwsp;454d4423643ce80e2a9ac94fa54ca49f + \xddaf35a193617abacc417349ae204131&zwsp;12e6fa4e89a97ea20a9eeee64b55d39a&zwsp;2192992a274fc1a836ba3c23a3feebbd&zwsp;454d4423643ce80e2a9ac94fa54ca49f @@ -523,8 +544,7 @@ bytea - 从start字节开始提取bytes的子字符串,并扩展为count字节,如果这是指定的。 - (与 substring(bytesstartcount) 相同.) + 提取bytes中从第start个字节开始的子字符串;若指定了长度,则提取count个字节。(与substring(bytes from start for count)相同。) substr('\x1234567890'::bytea, 3, 2) @@ -536,7 +556,7 @@
- 函数get_byteset_byte把一个二进制串中的一个字节计数为字节 0。 + 函数get_byteset_byte把二进制串中的第一个字节编号为字节 0。 函数get_bitset_bit在每一个字节中从右边起计数位; 例如位 0 是第一个字节的最低有效位,而位 15 是第二个字节的最高有效位。 @@ -544,16 +564,16 @@ 由于历史原因,函数md5返回的是一个十六进制编码的text值,而SHA-2函数返回类型bytea。 可以使用函数encodedecode在两者之间转换。 - 例如encode(sha256('abc'),'hex')可以得到一个十六进制编码的文本表示,或者decode(md5('abc'), 'hex')得到一个bytea 值。 + 例如encode(sha256('abc'), 'hex')可以得到一个十六进制编码的文本表示,或者decode(md5('abc'), 'hex')得到一个bytea 值。 - character string + 字符串 转换为二进制字符串 - binary string + 二进制串 转换为字符串 用于在不同字符集(编码)之间转换字符串的函数,以及用于以文本形式表示任意二进制数据的函数,在中显示。 @@ -562,7 +582,7 @@ - 文本/字符串转换函数 + 文本/二进制串转换函数 @@ -672,7 +692,7 @@ bytea - 从文本表示中解码二进制数据;支持的format值与encode相同。 + 从文本表示中解码二进制数据;支持的format值与encode相同。 decode('MTIzAAE=', 'base64') @@ -721,9 +741,9 @@ base64格式是RFC 2045第6.8节中描述的。根据RFC,编码行在76个字符处换行。 - 然而,与MIME CRLF换行符不同,结尾只使用换行符。 + 然而,与MIME CRLF换行符不同,行尾只使用一个换行符。 decode函数会忽略回车、换行、空格和制表符。 - 否则,当decode提供无效的base64数据时,包括尾部填充不正确时,会引发错误。 + 否则,当向decode传入无效的 base64 数据时,包括尾部填充不正确时,会引发错误。 @@ -750,8 +770,8 @@ - escape格式将零字节和高位设置的字节转换为八进制转义序列 - (\nnn),并将反斜杠加倍。 + escape格式将零字节和最高位被置位的字节转换为八进制转义序列 + (\nnn),并将反斜杠双写。 其他字节值会直接表示。如果反斜杠后面不是第二个反斜杠或三个八进制数字,则decode函数会引发错误; 它会接受其他字节值不变。 @@ -766,10 +786,10 @@ hex格式将每4位数据表示为一个十六进制数字,0f, - 先写入每个字节的高阶数字。 encode函数以小写输出a-f十六进制数字。 + 先写入每个字节的高位数字。 encode函数以小写输出a-f十六进制数字。 因为数据的最小单位是8位,所以encode总是返回偶数个字符。 decode函数接受a-f字符的大小写。 - 当decode提供无效的十六进制数据时,包括提供奇数个字符时,会引发错误。 + 当向decode传入无效的十六进制数据时,包括提供奇数个字符时,会引发错误。 @@ -777,8 +797,9 @@ - 另外,也可以在整数值和bytea之间进行类型转换。将整数转换为bytea时,会生成 2、4 或 8 个字节,具体取决于整数类型的宽度。 - 结果是该整数的二进制补码表示,最高有效字节在前。一些示例如下: + 此外,还可以在整数值与bytea类型之间进行类型转换。 + 将整数转换为bytea会产生 2、4 或 8 个字节,具体取决于整数类型的宽度。 + 结果是该整数的补码表示,最高有效字节在前。以下是一些示例: 1234::smallint::bytea \x04d2 cast(1234 AS bytea) \x000004d2 @@ -786,7 +807,7 @@ cast(-1234 AS bytea) \xfffffb2e '\x8000'::bytea::smallint -32768 '\x8000'::bytea::integer 32768 - 将bytea转换为整数时,如果bytea的长度超过该整数类型的宽度,就会引发错误。 + 将bytea转换为整数时,如果bytea的长度超过整数类型的宽度,则会引发错误。 diff --git a/zh/19/func/func-bitstring.sgml b/zh/19/func/func-bitstring.sgml index a780c6a3..d5d66f50 100644 --- a/zh/19/func/func-bitstring.sgml +++ b/zh/19/func/func-bitstring.sgml @@ -3,14 +3,14 @@ 位串函数和操作符 - bit strings - functions + 位串 + 函数 本节描述用于检查和操作位串的函数和操作符,也就是操作类型为bitbit varying的值的函数和操作符。 - (虽然这些表中只提到了bit类型,但bit varying类型的值可以互换使用。) - 位字符串支持中显示的常用比较操作符,就像中显示的操作符。 + (虽然这些表中只提到了bit类型,但bit varying类型的值可以互换使用。) + 位串支持中显示的常用比较操作符,以及中显示的操作符。
@@ -40,7 +40,7 @@ bit - 连接 + 串接 B'10001' || B'011' @@ -96,7 +96,7 @@ bit - 按位求反 + 按位非 ~ B'10001' @@ -136,12 +136,12 @@
- 一些可用于二进制字符串的函数也可用于位字符串,如中所示。 + 一些可用于二进制字符串的函数也可用于位串,如中所示。 - 位字符串函数 + 位串函数 @@ -169,7 +169,7 @@ bigint - 返回位字符串中设置的位数(也被视为popcount)。 + 返回位串中被置位的位数(也称为popcount)。 bit_count(B'10111') @@ -186,7 +186,7 @@ integer - 返回位字符串中的位数。 + 返回位串中的位数。 bit_length(B'10111') @@ -200,14 +200,14 @@ length - bit string - length + 位串 + 长度 length ( bit ) integer - 返回位字符串中的位数。 + 返回位串中的位数。 length(B'10111') @@ -224,7 +224,7 @@ integer - 返回位字符串中的字节数。 + 返回位串中的字节数。 octet_length(B'1011111011') @@ -241,8 +241,7 @@ bit - 替换从start位开始的bits的子字符串,并将newsubstring扩展count位。 - 如果count被省略,默认为newsubstring的长度。 + 用newsubstring替换bits中从第start位开始、长度为count位的子串。如果省略count,则默认为newsubstring的长度。 overlay(B'01010101010101010' PLACING B'11111' FROM 2 FOR 3) @@ -259,7 +258,7 @@ integer - 按返回指定substring的第一个起始索引,以bits为单位,如果不存在则返回0。 + 返回substringbits中首次出现的位置;如果不存在则返回零。 position(B'010' IN B'000001101011') @@ -276,8 +275,7 @@ bit - 如果指定了起始位,则提取从start位开始的bits的子字符串,如果指定了计数位,则在count位之后停止。 - startcount至少提供一个。 + 提取bits的子串:若指定了起始位置,则从第start位开始;若指定了长度,则在提取count位后停止。startcount至少需要指定一个。 substring(B'110010111111' FROM 3 FOR 2) @@ -295,7 +293,7 @@ integer - 从位字符串中提取第n位;第一个(最左)位为第0位。 + 从位串中提取编号为n的位;第一位(最左侧的位)编号为位 0。 get_bit(B'101010101010101010', 6) @@ -314,7 +312,7 @@ bit - 将位字符串中的第n位设置为newvalue;第一个(最左)位是第0位。 + 将位串中编号为n的位设置为newvalue;第一位(最左侧的位)编号为位 0。 set_bit(B'101010101010101010', 6, 0) @@ -325,16 +323,10 @@
- - 另外,我们可以在整数和bit之间来回转换。 - 将一个整数转换为bit(n)会复制最右边的n位。 - 将一个整数转换为比整数本身更宽的位字符串宽度将在左边进行符号扩展。一些示例: - + 此外,还可以在整数值与bit类型之间进行类型转换。将整数转换为bit(n)会复制最右侧的n位。将整数转换为宽度超过该整数自身位宽的位串时,会在左侧进行符号扩展。下面是一些示例: 44::bit(10) 0000101100 44::bit(3) 100 cast(-44 AS bit(12)) 111111010100 '1110'::bit(4)::integer 14 - - 请注意,如果只是转换为bit,意思是转换成bit(1),因此只会转换整数的最低有效位。 - +注意,仅转换为bit意味着转换为bit(1),因此只会得到该整数的最低有效位。 diff --git a/zh/19/func/func-comparison.sgml b/zh/19/func/func-comparison.sgml index 51edcd1f..5e4397b9 100644 --- a/zh/19/func/func-comparison.sgml +++ b/zh/19/func/func-comparison.sgml @@ -3,8 +3,8 @@ 比较函数和操作符 - comparison - operators + 比较 + 操作符 @@ -87,14 +87,14 @@ - <> 表示 not equal 的标准的SQL符号。 - != 是一个别名, 在解析的早期阶段被转换为 <> 。 - 因此, 它不可能实现 !=<> 操作符以做不同的事情。 + <>不等于 的标准 SQL 符号。 + != 是一个别名,在解析的早期阶段就会被转换为 <>。 + 因此,不可能让 !=<> 操作符执行不同的操作。 - 这些比较操作符适用于所有具有自然排序的内置数据类型,包括数字、字符串和日期/时间类型。 + 这些比较操作符适用于所有具有自然排序的内置数据类型,包括数值、字符串和日期/时间类型。 此外,如果其组成数据类型具有可比性,则也可以比较数组、复合类型和范围。 @@ -140,7 +140,7 @@ boolean - 之间(包括范围端点)。 + 位于两者之间(包括范围端点)。 2 BETWEEN 1 AND 3 @@ -200,7 +200,7 @@ boolean - 不相等, 将空(null)视为可比值。 + 不相等,将 null 视为可比值。 1 IS DISTINCT FROM NULL @@ -218,7 +218,7 @@ boolean - 相等, 将空(null)视为可比值。 + 相等,将 null 视为可比值。 1 IS NOT DISTINCT FROM NULL @@ -236,7 +236,7 @@ boolean - 测试值是否为空。 + 测试值是否为 null。 1.5 IS NULL @@ -250,7 +250,7 @@ boolean - 测试值是否不为空。 + 测试值是否不为 null。 'null' IS NOT NULL @@ -264,7 +264,7 @@ boolean - 测试值是否为空(非标准语法)。 + 测试值是否为 null(非标准语法)。 @@ -274,7 +274,7 @@ boolean
- 测试值是否不为空(非标准语法)。 + 测试值是否不为 null(非标准语法)。 @@ -395,30 +395,22 @@ BETWEEN SYMMETRIC - - BETWEEN谓词可以简化范围测试: - + BETWEEN谓词可以简化范围测试: a BETWEEN x AND y - - 等效于 - +等价于 a >= x AND a <= y - - 注意BETWEEN认为终点值是包含在范围内的。 - BETWEEN SYMMETRIC 就像BETWEEN,除了没有要求AND的左边的参数小于或等于右边的参数。 - 如果不是的话,这两个参数将自动交换,因此总是隐含一个非空范围。 -
+注意,BETWEEN将两个端点值都视为包含在范围内。BETWEEN SYMMETRIC类似于BETWEEN,但不要求AND左侧的参数小于或等于右侧的参数。如果不是这样,这两个参数会自动交换,以确保表示的范围始终非空。
- BETWEEN的各种变量都是以普通比较操作符的方式实现的,因此适用于任何可以比较的数据类型。 + BETWEEN的各种变体都是以普通比较操作符的方式实现的,因此适用于任何可以比较的数据类型。 - 在BETWEEN语法中使用AND会与使用AND作为逻辑操作符产生歧义。 - 为了解决这个问题,只允许有限的一组表达类型作为BETWEEN子句的第二个参数。 - 如果您需要在BETWEEN中写一个更复杂的子表达式,在子表达式两边写上圆括号。 + 在BETWEEN语法中使用AND,会与将AND用作逻辑操作符产生歧义。 + 为了解决这个问题,只允许有限的一组表达式类型作为BETWEEN子句的第二个参数。 + 如果你需要在BETWEEN中写一个更复杂的子表达式,请在该子表达式两边加上圆括号。 @@ -429,12 +421,12 @@ IS NOT DISTINCT FROM - 当有一个输入为空时,普通的比较操作符会得到空(表示未知),而不是真或假。例如,7 = NULL得到空,7 <> NULL也一样。如果这种行为不合适,可以使用IS NOT DISTINCT FROM谓词: + 当任一输入为 null 时,普通的比较操作符会得到 null(表示未知),而不是真或假。例如,7 = NULL得到 null,7 <> NULL也一样。如果这种行为不合适,可以使用IS NOT DISTINCT FROM谓词: a IS DISTINCT FROM b a IS NOT DISTINCT FROM b - 对于非空输入,IS DISTINCT FROM<>操作符一样。不过,如果两个输入都为空,它会返回假。而如果只有一个输入为空,它会返回真。类似地,IS NOT DISTINCT FROM对于非空输入的行为与=相同,但是当两个输入都为空时它返回真,并且当只有一个输入为空时返回假。因此,这些谓词实际上把空值当作一种普通数据值,而不是未知。 + 对于非 null 输入,IS DISTINCT FROM<>操作符一样。不过,如果两个输入都为 null,它会返回假。而如果只有一个输入为 null,它会返回真。类似地,IS NOT DISTINCT FROM对于非 null 输入的行为与=相同,但是当两个输入都为 null 时它返回真,并且当只有一个输入为 null 时返回假。因此,这些谓词实际上把 null 当作一种普通数据值,而不是未知 @@ -450,17 +442,17 @@ NOTNULL - 要检查一个值是否为空,使用下面的谓词: + 要检查一个值是否为 null,使用下面的谓词: expression IS NULL expression IS NOT NULL - 或者等效,但并不标准的谓词: + 或者等效但非标准的谓词: expression ISNULL expression NOTNULL - null valuecomparing + 空值比较 @@ -470,7 +462,7 @@ - 有些应用可能要求表达式expression = NULLexpression得出空值时返回真。我们强烈建议这样的应用修改成遵循 SQL 标准。但是,如果这样修改不可能完成,那么我们可以使用配置变量。如果打开它,PostgreSQL将把x = NULL子句转换成x IS NULL。 + 有些应用可能期望表达式expression = NULLexpression求值为 null 时返回真。我们强烈建议此类应用修改为遵循 SQL 标准。但是,如果无法这样修改,那么可以使用配置变量。如果将其打开,PostgreSQL会把x = NULL子句转换成x IS NULL @@ -480,11 +472,11 @@ SELECT ROW(1,2.5,'this is a test') = ROW(1, 3, 'not the same'); -SELECT ROW(table.*) IS NULL FROM table; -- detect all-null rows +SELECT ROW(table.*) IS NULL FROM table; -- 检测所有字段均为 null 的行 -SELECT ROW(table.*) IS NOT NULL FROM table; -- detect all-non-null rows +SELECT ROW(table.*) IS NOT NULL FROM table; -- 检测所有字段均非 null 的行 -SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in rows +SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- 检测至少有一个 null 字段的行 在某些情况下,写成row IS DISTINCT FROM NULL或者row IS NOT DISTINCT FROM NULL可能更合适,因为它们只会检查整个行值是否为 null,而不会再对行字段做额外测试。 @@ -518,7 +510,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in boolean_expression IS UNKNOWN boolean_expression IS NOT UNKNOWN - 这些谓词将总是返回真或假,从来不返回空值,即使操作数是空也如此。空值输入被当做逻辑值未知。 请注意实际上IS UNKNOWNIS NOT UNKNOWN分别与IS NULLIS NOT NULL相同, 只是输入表达式必须是布尔类型。 + 这些谓词总是返回真或假,从不返回空值,即使操作数为 null 也是如此。null 输入被当作逻辑值未知。请注意,IS UNKNOWNIS NOT UNKNOWN实际上分别等同于IS NULLIS NOT NULL,只是输入表达式必须是布尔类型。 @@ -575,7 +567,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in integer - 返回非空参数的数量。 + 返回非 null 参数的数量。 num_nonnulls(1, NULL, 2) @@ -592,7 +584,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in integer - 返回空参数的数量。 + 返回 null 参数的数量。 num_nulls(1, NULL, 2) diff --git a/zh/19/func/func-comparisons.sgml b/zh/19/func/func-comparisons.sgml index 3c4b2a32..394b8d1b 100644 --- a/zh/19/func/func-comparisons.sgml +++ b/zh/19/func/func-comparisons.sgml @@ -28,12 +28,12 @@ - 逐行比较 + 行比较 比较 - 逐行 + 复合类型 @@ -50,7 +50,7 @@ - 本节描述几个特殊的结构,用于在值的组之间进行多重比较。这些形式语法上和前面一节的子查询形式相关,但是不涉及子查询。 这种形式涉及的数组子表达式是PostgreSQL的扩展; 其它的是SQL兼容的。所有本节记录的表达式形式都返回布尔(Boolean)结果(真/假)。 + 本节描述几个特殊的结构,用于在值的组之间进行多重比较。这些形式语法上和前面一节的子查询形式相关,但是不涉及子查询。 涉及数组子表达式的形式是PostgreSQL的扩展; 其余形式是SQL兼容的。本节介绍的所有表达式形式都返回布尔(Boolean)结果(真/假)。 @@ -61,14 +61,12 @@ - 右侧是一个用括号括起来的表达式列表。如果左侧表达式的结果等于右侧任何一个表达式的结果,则结果为true。 - 这是一个简写表示法,如下所示: - + 右侧是一个用圆括号括起来的表达式列表。如果左侧表达式的结果等于右侧任一表达式的结果,则结果为。这等价于以下写法: expression = value1 -或 +OR expression = value2 -或 +OR ... @@ -86,9 +84,7 @@ - 右侧是一个用括号括起来的表达式列表。如果左侧表达式的结果与所有右侧表达式都不相等,则结果为true。 - 这是一个简写表示法,用于 - + 右侧是一个用圆括号括起来的表达式列表。如果左侧表达式的结果与右侧所有表达式的结果都不相等,则结果为。这等价于以下写法: expression <> value1 AND @@ -112,7 +108,7 @@ AND - <literal>ANY</literal>/<literal>SOME</literal> (array) + <literal>ANY</literal>/<literal>SOME</literal>(数组) expression operator ANY (array expression) @@ -134,7 +130,7 @@ AND - <literal>ALL</literal> (array) + <literal>ALL</literal>(数组) expression operator ALL (array expression) @@ -158,20 +154,7 @@ AND - 每一边都是一个行构造器, - 如在中描述的那样。 - 这两个行构造器必须具有相同数量的字段。 - 给定的operator应用于每一对 - 对应的字段。(由于字段可能是不同类型的,这意味着每对可能选择不同的具体操作符。) - 所有选定的操作符必须是某个B-树操作符类的成员,或者是B-树操作符类的=成员的否定形式, - 这意味着只有当operator是 - =、 - <>、 - <、 - <=、 - >或 - >=时才可能进行行构造器比较, - 或者具有类似于这些操作符的语义。 + 两侧都是行构造器,如所述。两个行构造器必须具有相同数量的字段。给定的operator应用于每一对对应字段。(由于字段可能具有不同的类型,因此可能为各对字段选择不同的具体操作符。)所选操作符必须是某个 B-树操作符类的成员,或者是 B-树操作符类中=成员的否定操作符。这意味着只有当operator=<><<=>>=,或具有与这些操作符类似的语义时,才可以进行行构造器比较。 @@ -182,12 +165,7 @@ AND 对于<<=>>=这几种情况,会从左到右比较各行元素,一旦找到一对不相等或含有 null 的元素就立即停止。如果这对元素中的任意一个为 null,那么行比较的结果就是未知(null);否则,这对元素的比较结果决定整个行比较的结果。例如,ROW(1,2,NULL) < ROW(1,3,0)的结果为真,而不是 null,因为第三对元素并不会被考虑。 - - - 在PostgreSQL 8.2 之前,<<=>>=这几种情况并不是按照 SQL 规范处理的。像ROW(a,b) < ROW(c,d)这样的比较会被实现为a < c AND b < d,而正确行为应当等价于a < c OR (a = c AND b < d)。 - - row_constructor IS DISTINCT FROM row_constructor @@ -216,21 +194,21 @@ AND - SQL 规范要求在结果依赖于比较两个 NULL 值或者一个 NULL 与一个非 NULL 时逐行比较返回 NULL。 + SQL 规范要求在结果依赖于比较两个 NULL 值或者一个 NULL 与一个非 NULL 时行比较返回 NULL。 PostgreSQL只有在比较两个行构造器(如)的结果或者比较一个行构造器与一个子查询的输出时才这样做(如中所述)。 - 在其他比较两个复合类型值的环境中,两个 NULL 域值被认为相等,并且一个 NULL 被认为大于一个非 NULL。 + 在其他比较两个复合类型值的环境中,两个 NULL 字段值被认为相等,并且一个 NULL 被认为大于一个非 NULL。 为了得到复合类型的一致的排序和索引行为,这样做是必要的。 - 每一边都会被计算并且它们会被逐行比较。当operator是 + 对两侧分别求值后,按行进行比较。当operator=<><<=>或者 - >=时或者具有与这些类似的语义时,允许复合类型的比较(更准确地说,如果一个操作符是一个 B-树操作符类的成员,或者是一个 B-树操作符类的=成员的否定词,它就可以是一个行比较操作符)。 - 上述操作符的行为与用于行构造器(见)的IS [ NOT ] DISTINCT FROM相同。 + >=时或者具有与这些类似的语义时,允许复合类型的比较(更准确地说,如果一个操作符是一个 B-树操作符类的成员,或者是一个 B-树操作符类的=成员的否定操作符,它就可以是一个行比较操作符)。 + 上述操作符的默认行为与用于行构造器(见)的IS [ NOT ] DISTINCT FROM相同。 @@ -241,9 +219,9 @@ AND *<=*>以及 *>=。 - 这些操作符比较两行的内部二进制表达。即使两行用相等操作符的比较为真,两行也可能具有不同的二进制表达。 - 行在这些比较操作符之下的排序是决定性的,其他倒没什么意义。 - 这些操作符在内部被用于物化视图并且可能对其他如复制和B-树复制(参见 )之类的特殊功能有用,但是它们并不打算用在书写查询这类普通用途中。 + 这些操作符比较两行的内部二进制表示。即使两行用相等操作符的比较为真,两行也可能具有不同的二进制表示。 + 使用这些比较操作符得到的行排序是确定的,但除此之外没有其他意义。 + 这些操作符在内部被用于物化视图并且可能对其他如复制和 B-树去重(参见 )之类的特殊功能有用,但是它们并不打算用在书写查询这类普通用途中。 diff --git a/zh/19/func/func-conditional.sgml b/zh/19/func/func-conditional.sgml index 9a3b5d48..25764d89 100644 --- a/zh/19/func/func-conditional.sgml +++ b/zh/19/func/func-conditional.sgml @@ -41,7 +41,7 @@ CASE WHEN condition THEN result - CASE子句可以用于任何表达式可以出现的地方。每一个condition是一个返回boolean结果的表达式。如果结果为真,那么CASE表达式的结果就是符合条件的result,并且剩下的CASE表达式不会被处理。如果条件的结果不为真,那么以相同方式搜寻任何随后的WHEN子句。如果没有WHEN condition为真,那么CASE表达式的值就是在ELSE子句里的result。如果省略了ELSE子句而且没有条件为真,结果为空。 + CASE子句可以用于任何表达式可以出现的地方。每一个condition是一个返回boolean结果的表达式。如果结果为真,那么CASE表达式的结果就是紧随该条件后的result,并且剩下的CASE表达式不会被处理。如果条件的结果不为真,那么以相同方式搜寻任何随后的WHEN子句。如果没有WHEN condition为真,那么CASE表达式的值就是在ELSE子句里的result。如果省略了ELSE子句而且没有条件为真,结果为 null。 @@ -86,7 +86,7 @@ CASE expression END - 第一个expression会被计算,然后与所有在WHEN子句中的每一个value对比,直到找到一个相等的。如果没有找到匹配的,则返回在ELSE子句中的result(或者控制)。 这类似于 C 里的switch语句。 + 第一个expression会被计算,然后与所有在WHEN子句中的每一个value对比,直到找到一个相等的。如果没有找到匹配的,则返回在ELSE子句中的result(或者 null 值)。 这类似于 C 里的switch语句。 @@ -117,11 +117,7 @@ SELECT ... WHERE CASE WHEN x <> 0 THEN y/x > 1.5 ELSE false END; - 如中所述,在有几种情况中一个表达式的子表达式 - 会被计算多次,因此CASE只计算必要的表达式这 - 一原则并非不可打破。例如一个常量子表达式1/0通常将会在规划时导致一次 - 除零错误,即便它位于一个执行时永远也不会进入的CASE分支时也是 - 如此。 + 如所述,在多种情况下,表达式中的子表达式会在不同阶段求值,因此CASE只计算必要的子表达式这一原则并非绝对成立。例如,常量子表达式1/0通常会在规划时导致除零错误,即便它位于一个运行时永远不会进入的CASE分支中也是如此。 @@ -146,19 +142,19 @@ SELECT ... WHERE CASE WHEN x <> 0 THEN y/x > 1.5 ELSE false END; - COALESCE函数返回它的第一个非空参数的值。当且仅当所有参数都为空时才会返回空。它常用于在为显示目的检索数据时用缺省值替换空值。例如: + COALESCE函数返回参数中第一个不为 null 的值。只有所有参数都为 null 时,才返回 null。它常用于在检索数据以供显示时,用默认值替换 null 值。例如: SELECT COALESCE(description, short_description, '(none)') ... - 如果description不为空,这将会返回它的值,否则如果short_description非空则返回short_description的值,如果前两个都为空则返回(none)。 + 此表达式返回description,前提是它不为 null,否则返回short_description,前提是它不为 null,否则返回(none) - 所有参数都必须转换为一个公共数据类型,它将是结果的类型 (详情参见 )。 + 所有参数都必须能转换为同一个数据类型,它将是结果的类型(详情参见)。 - 和CASE表达式一样,COALESCE将不会 计算无助于判断结果的参数;也就是说,在第一个非空参数右边的参数不会被计算。这个 SQL 标准函数提供了类似于NVLIFNULL的能力,它们被用在某些其他数据库系统中。 + 和CASE表达式一样,COALESCE只计算确定结果所需的参数;也就是说,在第一个不为 null 的参数右边的参数不会被计算。这个 SQL 标准函数提供了类似于NVLIFNULL的能力,它们被用在某些其他数据库系统中。 @@ -174,12 +170,12 @@ SELECT COALESCE(description, short_description, '(none)') ... - 当value1value2相等时,NULLIF返回一个空值。 + 当value1value2相等时,NULLIF返回 null。 否则它返回value1。 这些可以用于执行前文给出的COALESCE示例的逆操作: SELECT NULLIF(value, '(none)') ... - 在这个示例中,如果value(none),将返回空值,否则返回value的值。 + 在这个示例中,如果value(none),将返回 null,否则返回value的值。 @@ -214,11 +210,11 @@ SELECT NULLIF(value, '(none)') ... - GREATESTLEAST函数从一个任意的数字表达式列表里选取最大或者最小的数值。 这些表达式必须都可以转换成一个普通的数据类型,它将会是结果类型 (参阅获取细节)。列表中的 NULL 数值将被忽略。只有所有表达式的结果都是 NULL 的时候,结果才会是 NULL。 + GREATESTLEAST函数从由任意数量的表达式组成的列表中选取最大值或最小值。这些表达式都必须能转换为同一个数据类型,该类型将作为结果类型(详情参见)。 - 请注意GREATESTLEAST都不是 SQL 标准,但却是很常见的扩展。某些其他数据库让它们在任何参数为 NULL 时返回 NULL,而不是在所有参数都为 NULL 时才返回 NULL。 + 参数列表中的 NULL 值会被忽略。只有所有表达式的求值结果都为 NULL 时,结果才为 NULL。(这与 SQL 标准不同。按照标准,只要有任意参数为 NULL,返回值就为 NULL。一些其他数据库采用这种行为。) diff --git a/zh/19/func/func-datetime.sgml b/zh/19/func/func-datetime.sgml index 4b31f909..e65d6c71 100644 --- a/zh/19/func/func-datetime.sgml +++ b/zh/19/func/func-datetime.sgml @@ -1,9 +1,9 @@ - 时间/日期函数和操作符 + 日期/时间函数和操作符 - 展示了可用于处理日期/时间值的函数,其细节在随后的小节中描述。演示了基本算术操作符 (+*等)的行为。 而与格式化相关的函数,可以参考。你应该很熟悉中的日期/时间数据类型的背景知识。 + 展示了可用于处理日期/时间值的函数,其细节在随后的小节中描述。演示了基本算术操作符 (+*等)的行为。 而与格式化相关的函数,可以参考。你应当熟悉中的日期/时间数据类型的背景知识。 @@ -89,7 +89,7 @@ interval - 添加时间间隔 + 将两个时间间隔相加 interval '1 day' + interval '1 hour' @@ -131,7 +131,7 @@ interval - 取否一个时间间隔 + 对时间间隔取负 - interval '23 hours' @@ -145,7 +145,7 @@ integer - 减去日期,生成经过的天数 + 将两个日期相减,得到相隔的天数 date '2001-10-01' - date '2001-09-28' @@ -187,7 +187,7 @@ interval - 减去时间 + 将两个时间相减 time '05:00' - time '03:00' @@ -229,7 +229,7 @@ interval - 减去时间间隔 + 将两个时间间隔相减 interval '1 day' - interval '1 hour' @@ -243,12 +243,12 @@ interval - 减去时间戳(将24小时间隔转换为天数,类似于justify_hours() - 时间戳 '2001-09-29 03:00' - 时间戳 '2001-07-27 12:00' - 63 天 15:00:00 + timestamp '2001-09-29 03:00' - timestamp '2001-07-27 12:00' + 63 days 15:00:00 @@ -258,7 +258,7 @@ interval - 将时间间隔乘以数量 + 将时间间隔乘以一个标量 interval '1 second' * 900 @@ -280,7 +280,7 @@ interval - 用时间间隔除以数量 + 将时间间隔除以一个标量 interval '1 hour' / 1.5 @@ -321,7 +321,7 @@ interval - 减去参数,生成一个使用年和月,而不是只用日的符号化的结果 + 将两个参数相减,生成一个使用年和月,而不是只用日的符号化的结果 age(timestamp '2001-04-10', timestamp '1957-06-13') @@ -335,7 +335,7 @@ interval - 从 current_date 减去参数(在午夜) + 从current_date(午夜时刻)减去参数 age(timestamp '1957-06-13') @@ -386,7 +386,7 @@ time with time zone - 一天中的当前时间;参见 + 一天中的当前时刻;参见 current_time @@ -400,7 +400,7 @@ time with time zone - 一天中的当前时间;有限精度;参见 + 一天中的当前时刻,精度受限;参见 current_time(2) @@ -417,7 +417,7 @@ timestamp with time zone - 当前日期和时间 (当前事务的开始);参见 + 当前日期和时间(当前事务开始时);参见 current_timestamp @@ -431,7 +431,7 @@ timestamp with time zone - 当前日期和时间 (当前事务的开始);有限精度;参见 + 当前日期和时间(当前事务开始时),精度受限;参见 current_timestamp(0) @@ -479,7 +479,7 @@ double precision - 获取时间戳字段 (等同于 extract);参见 + 获取时间戳子字段 (等同于 extract);参见 date_part('hour', timestamp '2001-02-16 20:38:40') @@ -603,7 +603,7 @@ boolean - 测试有限日期(不是+/-无限) + 测试日期是否有限(不是正负无穷) isfinite(date '2001-02-16') @@ -617,7 +617,7 @@ boolean - 测试有限时间戳(不是+/-无限) + 测试时间戳是否有限(不是正负无穷) isfinite(timestamp 'infinity') @@ -631,7 +631,7 @@ boolean - 测试有限时间间隔 (当前总是为真) + 测试时间间隔是否有限(不是正负无穷) isfinite(interval '4 hours') @@ -684,7 +684,7 @@ interval - 使用 justify_daysjustify_hours调整时间间隔; 通过额外的符号调整 + 使用 justify_daysjustify_hours调整时间间隔,并额外调整符号 justify_interval(interval '1 mon -1 hour') @@ -701,7 +701,7 @@ time - 一天中当前时间;参见 + 一天中的当前时刻;参见 localtime @@ -715,7 +715,7 @@ time - 一天中的当前时间,有限精度;参见 + 一天中的当前时刻,精度受限;参见 localtime(0) @@ -732,7 +732,7 @@ timestamp - 当前日期和时间(当前事务的开始);参见 + 当前日期和时间(当前事务开始时);参见 localtimestamp @@ -746,7 +746,7 @@ timestamp - 当前日期和时间(当前事务的开始);有限精度;参见 + 当前日期和时间(当前事务开始时),精度受限;参见 localtimestamp(2) @@ -874,7 +874,7 @@ timestamp with time zone - 当前日期和时间(当前事务的开始);参见 + 当前日期和时间(当前事务开始时);参见 now() @@ -923,7 +923,7 @@ timestamp with time zone - 当前日期和时间(当前语句的开始);参见 + 当前日期和时间(当前语句开始时);参见 statement_timestamp() @@ -958,7 +958,7 @@ timestamp with time zone - 当前日期和时间(当前事务的开始);参见 + 当前日期和时间(当前事务开始时);参见 transaction_timestamp() @@ -975,7 +975,7 @@ timestamp with time zone - 将Unix纪元转换为带时区的时间戳(从1970-01-01 00:00:00+00开始的秒) + 将 Unix 纪元时间(自 1970-01-01 00:00:00+00 起的秒数)转换为带时区的时间戳 to_timestamp(1284352323) @@ -995,7 +995,7 @@ (start1, end1) OVERLAPS (start2, end2) (start1, length1) OVERLAPS (start2, length2) - 这个表达式在两个时间域(用它们的端点定义)重叠的时候得到真,当它们不重叠时得到假。端点可以用一对日期、时间或者时间戳来指定;或者是用一个后面跟着一个间隔的日期、时间或时间戳来指定。当一对值被提供时,起点或终点都可以被写在前面,OVERLAPS会自动地把较早的值作为起点。每一个时间段被认为是表示半开的间隔start <= time < end,除非startend相等,这种情况下它表示单个时间实例。例如这表示两个只有一个共同端点的时间段不重叠。 + 这个表达式在两个时间段(用它们的端点定义)重叠的时候得到真,当它们不重叠时得到假。端点可以用一对日期、时间或者时间戳来指定;或者是用一个后面跟着一个间隔的日期、时间或时间戳来指定。当一对值被提供时,起点或终点都可以被写在前面,OVERLAPS会自动地把较早的值作为起点。每一个时间段被认为是表示半开区间start <= time < end,除非startend相等,这种情况下它表示单个时刻。例如这表示两个只有一个共同端点的时间段不重叠。 @@ -1014,16 +1014,19 @@ SELECT (DATE '2001-10-30', DATE '2001-10-30') OVERLAPS - 当把一个interval值添加到timestamp with time zone上(或从中减去)时,天这一部分会按照指定的天数增减该timestamp with time zone的日期,同时保持一天中的时间不变。 - 对于跨越夏令时变更的情况(当会话时区被设置为能够识别 DST 的时区时),这意味着interval '1 day'并不一定等于interval '24 hours'。 - 例如,当会话的时区设置为America/Denver时: + 当把一个interval值加到timestamptimestamp with time zone值上(或从中减去一个interval值)时,会依次处理interval值的月、日和微秒字段。 + 首先,非零的月字段会按指定月数增减时间戳的日期,同时保持其在月份中的日不变;如果该日超出了新月份的月末,则使用该月的最后一天。(例如,3 月 31 日加 1 个月得到 4 月 30 日,加 2 个月则得到 5 月 31 日。) + 然后,日字段会按指定天数增减时间戳的日期。在这两个步骤中,一天中的本地时刻保持不变。最后,如果微秒字段不为零,则直接加上或减去该值。 + 在识别夏令时的时区中对timestamp with time zone值进行运算时,这意味着加上或减去(例如)interval '1 day'与加上或减去interval '24 + hours'的结果不一定相同。 + 例如,当会话时区设为America/Denver时: SELECT timestamp with time zone '2005-04-02 12:00:00-07' + interval '1 day'; 结果:2005-04-03 12:00:00-06 SELECT timestamp with time zone '2005-04-02 12:00:00-07' + interval '24 hours'; 结果:2005-04-03 13:00:00-06 - - 发生这种情况是因为在America/Denver时区,夏令时在2005-04-03 02:00:00发生切换,导致跳过了一个小时。 + + 发生这种情况是因为在2005-04-03 02:00:00America/Denver时区切换了夏令时,跳过了一个小时。 @@ -1031,15 +1034,9 @@ SELECT timestamp with time zone '2005-04-02 12:00:00-07' + interval '24 hours'; - 日期和时间戳的减法也可能会很复杂。执行减法的一种概念上很简单的方法是,使用 - EXTRACT(EPOCH FROM ...)把每个值都转换成秒数,然后执行减法, - 这样会得到两个值之间的数。这种方法将会适应每个月中天数、 - 时区改变和夏令时调整。使用-操作符的日期或时间 - 戳减法会返回值之间的天数(24小时)以及时/分/秒,也会做同样的调整。 - age函数会返回年、月、日以及时/分/秒,执行按域的减法,然后对 - 负值域进行调整。下面的查询展示了这些方法的不同。示例中的结果由 - timezone = 'US/Eastern'产生,这使得两个使用的日期之间存在着夏令 - 时的变化: + 日期和时间戳的减法也可能很复杂。一种概念上简单的方法是,先用EXTRACT(EPOCH FROM ...)将各值转换为秒数,然后将结果相减;这样得到的是两个值之间的数。这种方法会针对每个月的天数、时区变化和夏令时变化进行调整。 + 用-操作符将日期或时间戳值相减,会返回两个值之间的天数(每一天为 24 小时)和时/分/秒,也会作相同的调整。age函数返回年、月、日和时/分/秒,它会逐字段相减,然后调整负值字段。 + 以下查询显示了这些方法的差异。示例结果在timezone = 'US/Eastern'设置下产生;所用的两个日期之间发生了夏令时切换: @@ -1091,7 +1088,7 @@ EXTRACT(field FROM source) - 这个世纪;对于interval值,年份字段除以100 + 世纪;对于interval值,年份字段除以100 @@ -1114,7 +1111,7 @@ SELECT EXTRACT(CENTURY FROM INTERVAL '2001 years'); - 月份的日期(1–31);对于interval值,表示天数 + 一个月中的第几天(1–31);对于interval值,表示天数 @@ -1167,7 +1164,7 @@ SELECT EXTRACT(DOW FROM TIMESTAMP '2001-02-16 20:38:40'); - 一年中的日子(1-365/366) + 一年中的第几天(1–365/366) @@ -1182,7 +1179,7 @@ SELECT EXTRACT(DOY FROM TIMESTAMP '2001-02-16 20:38:40'); - 对于timestamp with time zone值,自1970-01-01 00:00:00 UTC以来的秒数(负值表示该时间戳之前的时间); + 对于timestamp with time zone值,自1970-01-01 00:00:00 UTC以来的秒数(早于该时刻的时间戳对应负值); 对于datetimestamp值,自1970-01-01 00:00:00以来的名义秒数,不考虑时区或夏令时规则; 对于interval值,间隔中的总秒数 @@ -1206,8 +1203,8 @@ SELECT to_timestamp(982384720.12); - 注意,将to_timestamp应用于从datetimestamp值中提取的时代可能会产生误导性的结果: - 结果将有效地假定原始值是以UTC时间给出的,这可能并非事实。 + 注意,将to_timestamp应用于从datetimestamp值中提取的 epoch 值可能会产生误导性的结果: + 结果实际上会假定原始值是以UTC时间给出的,这可能并非事实。
@@ -1263,8 +1260,7 @@ SELECT EXTRACT(ISOYEAR FROM DATE '2006-01-02'); - 每个ISO 8601周编号年从包含1月4日的星期一开始,因此在一月初或十二月底,ISO年可能与格里高利年不同。 - 有关更多信息,请参见week字段。 + 每个 ISO 8601 周编号年都从包含 1 月 4 日的那一周的星期一开始,因此在 1 月初或 12 月末,ISO 年可能与格里高利年不同。更多信息请参见 week 字段。 @@ -1307,7 +1303,7 @@ SELECT EXTRACT(MICROSECONDS FROM TIME '17:12:28.5'); - 千年; 对于interval值,年份字段除以1000 + 千年; 对于interval值,年份字段除以1000 @@ -1318,7 +1314,7 @@ SELECT EXTRACT(MILLENNIUM FROM INTERVAL '2001 years'); - 20世纪的年份在第二个千年。第三个千年从2001年1月1日开始。 + 1900 年代的年份属于第二个千年。第三个千年始于 2001 年 1 月 1 日。 @@ -1328,7 +1324,7 @@ SELECT EXTRACT(MILLENNIUM FROM INTERVAL '2001 years'); - 第二个字段,包括小数部分,乘以1000。请注意,这包括完整的秒数。 + 秒字段,包括小数部分,乘以1000。请注意,这包括完整的秒数。 @@ -1358,7 +1354,7 @@ SELECT EXTRACT(MINUTE FROM TIMESTAMP '2001-02-16 20:38:40'); - 月份在一年中的编号(1-12);对于interval值,月份模12的余数(0-11) + 月份在一年中的编号(1–12);对于interval值,月份模12的余数(0–11) @@ -1377,12 +1373,14 @@ SELECT EXTRACT(MONTH FROM INTERVAL '2 years 13 months'); - 日期所在的年份季度(1-4) + 日期所在的年份季度(1–4);对于interval值,为月份字段除以 3 加 1 SELECT EXTRACT(QUARTER FROM TIMESTAMP '2001-02-16 20:38:40'); 结果:1 +SELECT EXTRACT(QUARTER FROM INTERVAL '1 year 6 months'); +结果:3 @@ -1419,7 +1417,7 @@ SELECT EXTRACT(SECOND FROM TIME '17:12:28.5'); - 时间区偏移的小时组件 + 时区偏移的小时部分 @@ -1429,7 +1427,7 @@ SELECT EXTRACT(SECOND FROM TIME '17:12:28.5'); - 时间区偏移的分钟组件 + 时区偏移的分钟部分 @@ -1439,21 +1437,22 @@ SELECT EXTRACT(SECOND FROM TIME '17:12:28.5'); - 一年中ISO 8601周编号周的数量。根据定义,ISO周从周一开始, - 一年的第一周包含该年的1月4日。换句话说,一年的第一个星期四在该年的第1周。 + 一年中按ISO 8601 周编号体系计算的周序号。根据定义,ISO 周从周一开始,一年的第一周包含该年的 1 月 4 日。换句话说,一年的第一个星期四在该年的第 1 周。 + + + + 在 ISO 周编号体系中,1 月初的日期可能属于前一年的第 52 周或第 53 周,而 12 月末的日期可能属于下一年的第一周。例如,2005-01-01属于 2004 年的第 53 周,2006-01-01属于 2005 年的第 52 周,而2012-12-31属于 2013 年的第一周。建议将isoyear字段与week一起使用,以获得一致的结果。 - 在ISO周编号系统中,早年1月的日期可能属于前一年的第52周或第53周,而 - 晚年12月的日期可能属于下一年的第一周。例如,2005-01-01 - 属于2004年的第53周,2006-01-01 属于2005年的第52周, - 而2012-12-31 属于2013年的第一周。建议同时使用 - isoyear 字段和week以获得一致的结果。 + 对于interval值,week 字段就是整天数除以 7 的结果。 SELECT EXTRACT(WEEK FROM TIMESTAMP '2001-02-16 20:38:40'); 结果:7 +SELECT EXTRACT(WEEK FROM INTERVAL '13 days 24 hours'); +结果:1 @@ -1463,7 +1462,7 @@ SELECT EXTRACT(WEEK FROM TIMESTAMP '2001-02-16 20:38:40'); - 年份字段。请记住,没有0 AD,所以要小心地从AD年中减去BC年。 + 年份字段。请记住,没有0 AD,所以把BC年份从AD年份中减去时需要小心。 @@ -1490,7 +1489,8 @@ SELECT EXTRACT(MINUTES FROM INTERVAL '80 minutes'); - 当输入值为 +/-Infinity 时,extract对于单调增的域(epochjulianyearisoyeardecadecentury以及millennium)返回 +/-Infinity。对于其他域返回 NULL。PostgreSQL 9.6 之前的版本对所有输入无穷的情况都返回零。 + 当输入值为 +/-Infinity 时,extract对单调递增的字段返回 +/-Infinity(对于timestamp输入,这些字段为epochjulianyearisoyeardecadecenturymillennium;对于interval输入,这些字段为epochhourdayyeardecadecenturymillennium)。 + 对于其他字段,返回 NULL。PostgreSQL 9.6 之前的版本对所有无穷输入都返回零。 @@ -1499,15 +1499,12 @@ SELECT EXTRACT(MINUTES FROM INTERVAL '80 minutes'); - 在传统的Ingres上建模的date_part函数等价于SQL标准函数extract: + date_part函数仿照传统的Ingres实现,后者对应SQL标准的extract函数: date_part('field', source) - 请注意这里的field参数必须是一个串值,而不是一个名字。 - 有效的date_part域名 和extract相同。 - 由于历史原因,date_part函数返回double precision类型的值。 - 这可能导致在某些使用中损失精度。 - 建议使用extract替代。 + 注意,此处的field参数必须是字符串值,而不能是名称。date_part的有效字段名与extract相同。 + 由于历史原因,date_part函数返回double precision类型的值,可能在某些用途中损失精度。建议改用extract @@ -1534,11 +1531,12 @@ SELECT date_part('hour', INTERVAL '4 hours 3 minutes'); date_trunc(field, source [, time_zone ]) - source是类型timestampinterval的值表达式(类型datetime的值都分别被自动转换成timestamp, timestamp with time zone,或者interval)。field选择对输入值选用什么样的精度进行截断。返回的值是timestamp, timestamp with time zone,类型或者所有小于选定的 精度的域都设置为零(或者一,对于日期和月份)的interval。 + sourcetimestamptimestamp with time zoneinterval类型的值表达式。(datetime类型的值会分别自动转换为timestampinterval。) + field选择输入值的截断精度。返回值同样为timestamptimestamp with time zoneinterval类型,其中低于所选精度的所有字段都设为零(日和月则设为一)。 - field的有效值是∶ + field的有效值是: microseconds milliseconds @@ -1557,7 +1555,7 @@ date_trunc(field, source [ - 当输入值的类型为timestamp with time zone时。截断是针对特定时区进行的。 例如,截断为day,产生的值是 是该区域的午夜。 默认情况下,截断是在以下方面进行的 到当前的设置,但在当前的 可以提供可选的time_zone参数。以指定不同的时区。 可以指定时区名称 中描述的任何一种方式。 + 当输入值为timestamp with time zone类型时,截断会以特定时区为准;例如,截断到day会得到该时区的午夜。默认情况下,截断以当前的设置为准,但可以通过可选的time_zone参数指定其他时区。时区名称可以用中描述的任意方式指定。 @@ -1599,11 +1597,11 @@ date_bin(stride, source, < sourcetimestamptimestamp with time zone类型的值表达式。 (类型date的值会自动转换为timestamp。) strideinterval类型的值表达式。 - 返回值同样是timestamptimestamp with time zone类型,并且它标记着放置source的bin的开始。 + 返回值同样是timestamptimestamp with time zone类型,并且它表示source所在分箱的起点。 - 示例: + 示例: SELECT date_bin('15 minutes', TIMESTAMP '2020-02-11 15:44:17', TIMESTAMP '2001-01-01'); 结果: 2020-02-11 15:30:00 @@ -1625,8 +1623,8 @@ SELECT date_bin('15 minutes', TIMESTAMP '2020-02-11 15:44:17', TIMESTAMP '2001-0 <literal>AT TIME ZONE</literal> 和 <literal>AT LOCAL</literal> - time zone - conversion + 时区 + 转换 @@ -1638,7 +1636,7 @@ SELECT date_bin('15 minutes', TIMESTAMP '2020-02-11 15:44:17', TIMESTAMP '2001-0 - AT TIME ZONE 操作符可在带时区和不带时区的时间戳之间进行转换,也可将 time with time zone 值转换到不同的时区。 展示了它的各种变体。 + AT TIME ZONE 操作符可将不带时区的时间戳转换为时区的时间戳或反向转换,也可将 time with time zone 值转换到不同的时区。 展示了它的各种变体。 @@ -1685,7 +1683,7 @@ SELECT date_bin('15 minutes', TIMESTAMP '2020-02-11 15:44:17', TIMESTAMP '2001-0 将给定的不带时区时间戳转换为带时区时间戳,所用时区为会话的 TimeZone 值。 - timestamp '2001-02-16 20:38:40' AT LOCAL + timestamp '2001-02-16 20:38:40' at local 2001-02-17 03:38:40+00 @@ -1713,7 +1711,7 @@ SELECT date_bin('15 minutes', TIMESTAMP '2020-02-11 15:44:17', TIMESTAMP '2001-0 将给定的带时区时间戳转换为无时区时间戳,所用时区为会话的 TimeZone 值。 - timestamp with time zone '2001-02-16 20:38:40-05' AT LOCAL + timestamp with time zone '2001-02-16 20:38:40-05' at local 2001-02-16 18:38:40 @@ -1738,13 +1736,13 @@ SELECT date_bin('15 minutes', TIMESTAMP '2020-02-11 15:44:17', TIMESTAMP '2001-0 time with time zone - 将给定的带时区时间转换到新的时区,所用时区为会话的 TimeZone 值。由于没有提供日期,这会使用会话 TimeZone 当前生效的 UTC 偏移量。 + 将给定的带时区时间转换到新的时区。由于没有提供日期,这会使用会话 TimeZone 值当前生效的 UTC 偏移量。 假定会话的 TimeZone 设为 UTC - time with time zone '05:34:17-05' AT LOCAL + time with time zone '05:34:17-05' at local 10:34:17+00 @@ -1774,33 +1772,38 @@ SELECT TIMESTAMP '2001-02-16 20:38:40' AT TIME ZONE 'Asia/Tokyo' AT TIME ZONE 'A SELECT TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40-05' AT LOCAL; 结果:2001-02-16 17:38:40 SELECT TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40-05' AT TIME ZONE '+05'; -结果:2001-02-17 06:38:40 +结果:2001-02-16 20:38:40 SELECT TIME WITH TIME ZONE '20:38:40-05' AT LOCAL; -结果:17:38:40-08 +结果:17:38:40 第一个示例为缺少时区的值添加时区,并使用当前的 TimeZone 设置显示该值。 - 第二个示例将带时区的时间戳值转换到指定时区,并返回无时区的值。 - 这允许存储和显示与当前 TimeZone 设置不同的值。第三个示例将东京时间转换为芝加哥时间。第四个示例展示了 AT LOCAL 的用法。第五个示例使用数值型 UTC 偏移量作为时区。最后一个示例展示了 time with time zone 值转换为会话本地时区的结果。 + 第二个示例将带时区的时间戳值转换到指定时区,并返回不带时区的值。 + 这样就可以存储和显示与当前 TimeZone 设置不同的值。 + 第三个示例将东京时间转换为芝加哥时间。 + 第四个示例将带时区的时间戳值转换到当前 TimeZone 设置指定的时区,并返回不带时区的值。 + 第五个示例说明,POSIX 风格的时区说明中的正负号与 ISO-8601 日期时间字面量中的正负号含义相反,有关信息请参见 - 函数timezone(zone, timestamp)等效于 SQL 兼容的结构timestamp AT TIME ZONE zone。 + 第六个示例需要注意。由于输入值不包含日期,转换使用会话的当前日期。 + 因此,根据查看本示例时处于一年中的哪个时段,这个静态示例可能显示错误的结果,因为 + 'America/Los_Angeles' 实行夏令时。 - 结构 timestamp AT LOCAL 等效于 timestamp AT TIME ZONE local。 + 函数timezone(zone, timestamp)等效于符合 SQL 标准的结构timestamp AT TIME ZONE zone - 函数timezone(zone, timestamp with time zone)等效于 SQL 兼容的结构timestamp with time zone AT TIME ZONE zone。 + 函数timezone(zone, time)等效于符合 SQL 标准的结构time AT TIME ZONE zone - 结构 timestamp with time zone AT LOCAL 等效于 timestamp with time zone AT TIME ZONE local。 + 函数timezone(timestamp)等效于符合 SQL 标准的结构timestamp AT LOCAL - 函数timezone(zone, time with time zone)等效于 SQL 兼容的结构time with time zone AT TIME ZONE zone。结构 time with time zone AT LOCAL 等效于 time with time zone AT TIME ZONE local。 + 函数timezone(time)等效于符合 SQL 标准的结构time AT LOCAL @@ -1809,13 +1812,13 @@ SELECT TIME WITH TIME ZONE '20:38:40-05' AT LOCAL; 当前日期/时间 - date - current + 日期 + 当前 - time - current + 时间 + 当前 @@ -1834,15 +1837,15 @@ LOCALTIMESTAMP(precision) - CURRENT_TIMECURRENT_TIMESTAMP传递带有时区的值;LOCALTIMELOCALTIMESTAMP传递的值不带时区。 + CURRENT_TIMECURRENT_TIMESTAMP返回带时区的值;LOCALTIMELOCALTIMESTAMP返回不带时区的值。 - CURRENT_TIMECURRENT_TIMESTAMPLOCALTIMELOCALTIMESTAMP可以有选择地接受一个精度参数,该精度会使结果的秒字段圆整到指定的小数位数。如果没有精度参数,结果将给出可用的全部精度。 + CURRENT_TIMECURRENT_TIMESTAMPLOCALTIMELOCALTIMESTAMP可以有选择地接受一个精度参数,该精度会使结果的秒字段舍入到指定的小数位数。如果没有精度参数,结果将给出可用的全部精度。 - 一些示例: + 一些示例: SELECT CURRENT_TIME; 结果: 14:39:53.662522-05 @@ -1864,7 +1867,7 @@ SELECT LOCALTIMESTAMP; - 许多其它数据库系统可能会更频繁地推进这些值。 + 其他数据库系统可能会更频繁地推进这些值。 @@ -1881,11 +1884,11 @@ now() - transaction_timestamp()等价于CURRENT_TIMESTAMP,但是其命名清楚地反映了它的返回值。statement_timestamp()返回当前语句的开始时刻(更准确的说是收到 客户端最后一条命令的时间)。statement_timestamp()transaction_timestamp()在一个事务的第一条命令期间返回值相同,但是在随后的命令中却不一定相同。 clock_timestamp()返回真正的当前时间,因此它的值甚至在同一条 SQL 命令中都会变化。timeofday()是一个有历史原因的PostgreSQL函数。和clock_timestamp()相似,timeofday()也返回真实的当前时间,但是它的结果是一个格式化的text串,而不是timestamp with time zone值。now()PostgreSQL的一个传统,等效于transaction_timestamp()。 + transaction_timestamp()等价于CURRENT_TIMESTAMP,但是其命名清楚地反映了它的返回值。statement_timestamp()返回当前语句的开始时刻(更准确地说,是接收到客户端最近一条命令消息的时间)。statement_timestamp()transaction_timestamp()在一个事务的第一条语句期间返回值相同,但是在随后的语句中却不一定相同。 clock_timestamp()返回真正的当前时间,因此它的值甚至在同一条 SQL 语句中都会变化。timeofday()是一个有历史原因的PostgreSQL函数。和clock_timestamp()相似,它也返回真实的当前时间,但是它的结果是一个格式化的text串,而不是timestamp with time zone值。now()PostgreSQL中与transaction_timestamp()等价的传统函数。 - 所有日期/时间类型还接受特殊的文字值now,用于指定当前的日期和时间(重申,被解释为当前事务的开始时刻)。 因此,下面三个都返回相同的结果: + 所有日期/时间数据类型也都接受特殊字面值now来指定当前日期和时间(同样解释为事务开始时间)。因此,下面三种写法都返回相同的结果: SELECT CURRENT_TIMESTAMP; SELECT now(); @@ -1897,7 +1900,7 @@ SELECT TIMESTAMP 'now'; -- 但请参阅下面的提示 当指定以后要计算的值时,不要使用第三种形式,例如在表列的DEFAULT子句中。 - 系统将在分析这个常量的时候把now转换为一个timestamp, 这样需要默认值时就会得到创建表的时间!而前两种形式要到实际使用缺省值的时候才被计算, 因为它们是函数调用。因此它们可以给出每次插入行的时刻。 + 系统将在分析这个常量的时候把now转换为一个timestamp, 这样需要默认值时就会得到创建表的时间!而前两种形式要到实际使用默认值的时候才被计算, 因为它们是函数调用。因此它们可以给出每次插入行的时刻。 (参见 。) @@ -1920,24 +1923,24 @@ SELECT TIMESTAMP 'now'; -- 但请参阅下面的提示 - sleep + 休眠 - delay + 延迟 - 下面的这些函数可以用于让服务器进程延时执行: + 以下函数可用于延迟服务器进程的执行: pg_sleep ( double precision ) pg_sleep_for ( interval ) pg_sleep_until ( timestamp with time zone ) - pg_sleep使当前会话的进程休眠,直到过去给定的秒数。可以指定几分之一秒的延迟。 - pg_sleep_for是一个方便的函数,允许将睡眠时间指定为时间间隔。 - pg_sleep_until是一个方便的函数,用于需要特定的唤醒时间。例如: + pg_sleep使当前会话的进程休眠,直到经过指定的秒数。可以指定带小数部分的秒数作为延迟时间。 + pg_sleep_for是一个便捷函数,允许以interval指定休眠时间。 + pg_sleep_until是在需要指定唤醒时间时使用的便捷函数。例如: SELECT pg_sleep(1.5); diff --git a/zh/19/func/func-enum.sgml b/zh/19/func/func-enum.sgml index 0b82baa2..171c99f8 100644 --- a/zh/19/func/func-enum.sgml +++ b/zh/19/func/func-enum.sgml @@ -3,7 +3,7 @@ 枚举支持函数 - 对于枚举类型(在中描述), 有一些函数允许更清洁的编码,而不需要为一个枚举类型硬写特定的值。它们被列在中。本例假定一个枚举类型被创建为: + 对于枚举类型(见),有些函数可以避免硬编码枚举类型中的特定值,使程序更简洁。这些函数列在中。以下示例假定枚举类型按如下方式创建: CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple'); @@ -89,8 +89,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple anyarray - 以一个数组返回在给定两个枚举值之间的范围。值必须来自相同的枚举类型。 - 如果第一个参数为空,其结果将从枚举类型的第一个值开始。如果第二参数为空,其结果将以枚举类型的最后一个值结束。 + 以有序数组返回两个给定枚举值之间的范围。两个值必须来自同一枚举类型。如果第一个参数为 null,结果从该枚举类型的第一个值开始;如果第二个参数为 null,结果以该枚举类型的最后一个值结束。 enum_range('orange'::rainbow, 'green'::rainbow) @@ -110,7 +109,6 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple
- 请注意,除了双参数形式的enum_range外, 这些函数忽略传递给它们的具体值,它们只关心声明的数据类型。 - 空值或类型的一个特定值可以通过,并得到相同的结果。这些函数更多地被用于一个表列或函数参数,而不是一个硬写的类型名,如示例中所使用。 + 请注意,除了enum_range的双参数形式外,这些函数都忽略传入的具体值,只关心其声明的数据类型。传入 null 或该类型的某个具体值,结果都相同。通常会将这些函数用于表列或函数参数,而不是像示例那样使用硬编码的类型名。 diff --git a/zh/19/func/func-event-triggers.sgml b/zh/19/func/func-event-triggers.sgml index 6b4f641d..cb257885 100644 --- a/zh/19/func/func-event-triggers.sgml +++ b/zh/19/func/func-event-triggers.sgml @@ -3,7 +3,7 @@ 事件触发器函数 - PostgreSQL提供了这些助手函数来从事件触发器检索信息。 + PostgreSQL提供了这些辅助函数来从事件触发器检索信息。 @@ -25,7 +25,7 @@ 当在一个ddl_command_end事件触发器的函数中调用时,pg_event_trigger_ddl_commands返回被每一个用户动作执行的DDL命令的列表。 如果在其他任何环境中调用这个函数,会发生错误。 - pg_event_trigger_ddl_commands为每一个被执行的基本命令返回一行,某些只有一个单一 SQL 句子的命令可能会返回多于一行。 + pg_event_trigger_ddl_commands为每一个被执行的基本命令返回一行,某些由单条 SQL 语句构成的命令可能会返回多于一行。 这个函数返回下面的列: @@ -42,7 +42,7 @@ classid oid - 对象所属的目录的 OID + 对象所属系统目录的 OID objid @@ -52,7 +52,7 @@ objsubid integer - 对象的子-id(例如列的属性号) + 子对象 ID(例如列的属性编号) command_tag @@ -68,16 +68,14 @@ schema_name text - 该对象所属的模式的名称(如果有),如果没有则为NULL。 - 没有引号。 + 对象所属模式的名称(若有);否则为NULL。不加引号。 object_identity text - 对象标识的文本表现形式,用模式限定。如果必要,出现在 - 该标识中的每一个标识符都会被引用。 + 对象标识的文本表示形式,带模式限定。标识中包含的每个标识符在必要时都会加引号。 @@ -89,8 +87,7 @@ command pg_ddl_command - 以内部格式表达的该命令的一个完整表现形式。这不能被直接输出, - 但是可以把它传递给其他函数来得到有关于该命令不同部分的信息。 + 命令的完整内部表示,不能直接输出,但可以将其传给其他函数以获取关于该命令的不同信息。 @@ -112,8 +109,8 @@ - pg_event_trigger_dropped_objects返回被调用sql_drop事件的命令删除的所有对象的列表。 - 如果调用在任何其他上下文中,会引发一个错误。这个函数返回以下列: + 在命令的sql_drop事件中调用pg_event_trigger_dropped_objects时,它返回该命令删除的所有对象的列表。 + 如果调用在任何其他上下文中,会引发一个错误。这个函数返回以下列: @@ -129,7 +126,7 @@ classid oid - 对象所属的目录的 OID + 对象原先所属系统目录的 OID objid @@ -139,7 +136,7 @@ objsubid integer - 子对象ID(如列的属性号) + 子对象 ID(例如列的属性编号) original @@ -150,7 +147,7 @@ normal boolean - 指示在依赖图中有一个普通依赖关系指向该对象的标志 + 如果依赖图中存在指向该对象的普通依赖关系,则为真。 @@ -169,29 +166,28 @@ schema_name text - 对象所属模式的名称(如果存在);否则为NULL。不应用引用。 + 对象原先所属模式的名称(若有);否则为NULL。不加引号。 object_name text - 如果模式和名称的组合能被用于对象的一个唯一标识符,则是对象的名称;否则是NULL。不应用引用,并且名称不是模式限定的。 + 如果模式和名称的组合可用作该对象的唯一标识符,则为对象名称;否则为NULL。不加引号,并且该名称永远不带模式限定。 object_identity text - 对象身份的文本表现,模式限定的。每一个以及所有身份中出现的标识符在必要时加引号。 + 对象标识的文本表示形式,带模式限定。标识中包含的每个标识符在必要时都会加引号。 address_names text[] - 一个数组,它可以和object_typeaddress_args, - 一起通过pg_get_object_address函数在一台包含有同类相同名称对象的远程服务器上重建该对象地址。 + 一个数组,可与object_typeaddress_args一起,通过pg_get_object_address函数在包含同类同名对象的远程服务器上重建该对象地址。 @@ -290,7 +286,7 @@ CREATE EVENT TRIGGER test_event_trigger_for_drops - 这些函数可以在事件触发器中使用,就像这样: + 这些函数可以在事件触发器中使用,就像这样: CREATE FUNCTION test_event_trigger_table_rewrite_oid() RETURNS event_trigger diff --git a/zh/19/func/func-formatting.sgml b/zh/19/func/func-formatting.sgml index 8a470166..3de67a22 100644 --- a/zh/19/func/func-formatting.sgml +++ b/zh/19/func/func-formatting.sgml @@ -3,11 +3,11 @@ 数据类型格式化函数 - formatting + 格式化 - PostgreSQL格式化函数提供一套强大的工具用于把各种数据类型 (日期/时间、整数、浮点、数字) 转换成格式化的字符串以及反过来从格式化的字符串转换成 指定的数据类型。列出了这些函数。这些函数都遵循一个公共的调用规范: 第一个参数是待格式化的值,而第二个是一个定义输出或输入格式的模板。 + PostgreSQL格式化函数提供一套强大的工具用于把各种数据类型 (日期/时间、整数、浮点数、数值) 转换成格式化的字符串以及反过来从格式化的字符串转换成 指定的数据类型。列出了这些函数。这些函数都遵循一个公共的调用规范: 第一个参数是待格式化的值,而第二个是一个定义输出或输入格式的模板。 @@ -58,7 +58,7 @@ text - 根据给定的格式将间隔转换为字符串。 + 根据给定的格式将时间间隔转换为字符串。 to_char(interval '15h 2m 12s', 'HH24:MI:SS') @@ -114,7 +114,7 @@ numeric - 根据给定的格式将字符串转换为数字。 + 根据给定的格式将字符串转换为数值。 to_number('12,454.8-', '99G999D9S') @@ -155,7 +155,7 @@ - 展示了可以用于格式化日期和时间值的模版。 + 展示了可以用于格式化日期和时间值的模板模式。
@@ -240,24 +240,24 @@ SSSS, SSSSS - 午夜后的秒 (0–86399) + 自午夜起的秒数 (0–86399) AM, am, - PM or pm - 正午指示器(不带句号) + PMpm + 上午/下午标记(不带句点) A.M., a.m., - P.M. or p.m. - 正午指示器(带句号) + P.M.p.m. + 上午/下午标记(带句点) Y,YYY - 带逗号的年(4 位或者更多位) with comma + 带逗号的年(4 位或者更多位) @@ -314,17 +314,17 @@ MONTH - 全大写形式的月名(空格补齐到 9 字符) + 大写的月份全称(空格补齐到 9 字符) Month - 全首字母大写形式的月名(空格补齐到 9 字符) + 首字母大写的月份全称(空格补齐到 9 字符) month - 全小写形式的月名(空格补齐到 9 字符) + 小写的月份全称(空格补齐到 9 字符) @@ -349,72 +349,72 @@ DAY - 全大写形式的日名(空格补齐到 9 字符) + 大写的星期全称(空格补齐到 9 字符) Day - 全首字母大写形式的日名(空格补齐到 9 字符) + 首字母大写的星期全称(空格补齐到 9 字符) day - 全小写形式的日名(空格补齐到 9 字符) + 小写的星期全称(空格补齐到 9 字符) DY - 简写的大写形式的日名(英语 3 字符,本地化长度可变) + 大写的星期简称(英语 3 字符,本地化长度可变) Dy - 简写的首字母大写形式的日名(英语 3 字符,本地化长度可变) + 首字母大写的星期简称(英语 3 字符,本地化长度可变) dy - 简写的小写形式的日名(英语 3 字符,本地化长度可变) + 小写的星期简称(英语 3 字符,本地化长度可变) DDD - 一年中的日(001–366) + 年内日序数(001–366) IDDD - ISO 8601 周编号方式的年中的日 (001–371; 年的第 1 日时第一个 ISO 周的周一) + ISO 8601 周编号方式的年中的日 (001–371; 年的第 1 日是第一个 ISO 周的周一) DD - 月中的日 (01–31) + 月内日序数 (01–31) D - 周中的日,周日 (1) 到周六 (7) + 星期几,周日 (1) 到周六 (7) ID - 周中的 ISO 8601 日,周一 (1) 到周日 (7) + ISO 8601 星期几,周一 (1) 到周日 (7) W - 月中的周 (1–5) (第一周从该月的第一天开始) + 月内周序数 (1–5) (第一周从该月的第一天开始) WW - 年中的周数 (1–53) (第一周从该年的第一天开始) + 年中的周编号 (1–53) (第一周从该年的第一天开始) IW - ISO 8601 周编号方式的年中的周数 (01–53; 新的一年的第一个周四在第一周) + ISO 8601 周编号方式的年中的周编号 (01–53; 新的一年的第一个周四在第一周) @@ -444,12 +444,12 @@ TZ - 大写形式的时区缩写(仅在to_char中支持) + 大写形式的时区缩写 tz - 小写形式的时区缩写(仅在to_char中支持) + 小写形式的时区缩写 @@ -472,17 +472,17 @@
- 修饰语可以被应用于模板模式来修改它们的行为。例如,FMMonth就是带着FM修饰语的Month模式。展示了可用于日期/时间格式化的修饰语模式。 + 修饰符可以被应用于模板模式来修改它们的行为。例如,FMMonth就是带着FM修饰符的Month模式。展示了可用于日期/时间格式化的修饰符模式。 - 用于日期/时间格式化的模板模式修饰语 + 用于日期/时间格式化的模板模式修饰符 - 修饰语 + 修饰符 描述 示例 @@ -490,37 +490,37 @@ - FM prefix + FM 前缀 填充模式(抑制前导零和填充的空格) FMMonth - TH suffix + TH 后缀 大写形式的序数后缀 - DDTH, e.g., 12TH + DDTH,例如, 12TH - th suffix + th 后缀 小写形式的序数后缀 - DDth, e.g., 12th + DDth,例如, 12th - FX prefix - 固定的格式化全局选项(见使用须知) + FX 前缀 + 固定格式全局选项(见使用须知) FX Month DD Day - TM prefix - 翻译模式(基于使用本地化的日和月名) + TM 前缀 + 翻译模式(基于使用本地化的星期名和月份名) TMMonth - SP suffix + SP 后缀 拼写模式(未实现) DDSP @@ -537,8 +537,8 @@ FM抑制了在模式输出中添加前导零和尾随空格的行为,这些前导零和尾随空格 本来会被添加以使输出成为固定宽度。在PostgreSQL中, - FM仅修改下一个规范,而在Oracle中FM影响所有后续 - 规范,并且重复的FM修饰符切换填充模式的开启和关闭。 + FM仅修改下一个格式说明,而在Oracle中FM影响所有后续 + 格式说明,并且重复的FM修饰符切换填充模式的开启和关闭。 @@ -596,10 +596,10 @@ 一个TZH模板模式可以匹配有符号数。 - 没有FX选项,减号可能会有歧义,并且可能被解释为分隔符。 - 此歧义解决如下:如果模板字符串中TZH之前的分隔符数量少于输入字符串中减号之前的分隔符数量, - 则减号被解释为TZH的一部分。 - 否则,减号被视为值之间的分隔符。 + 没有FX选项,负号可能会有歧义,并且可能被解释为分隔符。 + 此歧义解决如下:如果模板字符串中TZH之前的分隔符数量少于输入字符串中负号之前的分隔符数量, + 则负号被解释为TZH的一部分。 + 否则,负号被视为值之间的分隔符。 例如,to_timestamp('2000 -10', 'YYYY TZH')匹配 -10TZH,但 to_timestamp('2000 -10', 'YYYY  TZH') @@ -610,12 +610,7 @@ - 普通文本允许在to_char模板中,并且将被直接输出。您可以将子字符串放在双引号中, - 以强制将其解释为文字文本,即使它包含模板模式。例如,在'"Hello Year "YYYY'中, - YYYY将被年份数据替换,但Year中的单个Y不会被替换。 - 在to_dateto_numberto_timestamp中, - 文本和双引号字符串会导致跳过字符串中包含的字符数;例如"XX"跳过两个输入字符 - (无论它们是否为XX)。 + 普通文本可以出现在to_char模板中,并会按字面输出。可以用双引号括起子串,使其即使包含模式关键字也强制按字面文本解释。例如,在'"Hello Year "YYYY'中,YYYY会被年份数据替换,但Year中单独的Y不会被替换。在to_dateto_numberto_timestamp中,字面文本和双引号字符串会跳过与该字符串所含字符数相同数量的输入字符;例如,"XX"跳过两个输入字符(无论它们是否为XX)。 @@ -634,7 +629,7 @@ 如果您想在输出中使用双引号,必须在其前面加上反斜杠,例如'\"YYYY Month\"' - 反斜杠在双引号之外不起特殊作用。在双引号字符串内部,反斜杠会使下一个字符被直接解释,无论是什么(但除非下一个字符是双引号或另一个反斜杠,否则没有特殊效果)。 + 反斜杠在双引号之外不起特殊作用。在双引号字符串内部,反斜杠会使下一个字符被按字面解释,无论是什么(但除非下一个字符是双引号或另一个反斜杠,否则没有特殊效果)。 @@ -697,14 +692,14 @@ - 年份、周数和星期几:例如to_date('2006-42-4', 'IYYY-IW-ID') + 年份、周编号和星期几:例如to_date('2006-42-4', 'IYYY-IW-ID') 返回日期2006-10-19。 如果省略星期几,则假定为1(星期一)。 - 年份和年内天数:例如to_date('2006-291', 'IYYY-IDDD')也返回2006-10-19。 + 年份和年内日序数:例如to_date('2006-291', 'IYYY-IDDD')也返回2006-10-19 @@ -712,14 +707,14 @@ 尝试使用ISO 8601周编号字段和公历日期字段的混合输入日期是荒谬的,并将导致错误。 - 在ISO 8601周编号年的背景下,月份日期的概念没有意义。 + 在ISO 8601周编号年的背景下,月份月内日序数的概念没有意义。 在公历年的背景下,ISO周没有意义。 - 当to_date拒绝混合使用公历和ISO周编号日期字段时, - to_char不会,因为输出格式规范如YYYY-MM-DD (IYYY-IDDD)可能很有用。 + 虽然to_date会拒绝混合使用公历和ISO周编号日期字段, + 但to_char不会,因为输出格式规范如YYYY-MM-DD (IYYY-IDDD)可能很有用。 但要避免编写类似IYYY-MM-DD的内容;那会在年初附近产生令人惊讶的结果。 (有关更多信息,请参见。) @@ -738,7 +733,7 @@ 这是一个更复杂的示例: to_timestamp('15:12:02.020.001230', 'HH24:MI:SS.MS.US') - 是15小时,12分钟和2秒 + 20毫秒 + 1230微秒 = 2.021230秒。 + 为15小时12分钟,秒数为2秒 + 20毫秒 + 1230微秒 = 2.021230秒。 @@ -746,7 +741,7 @@ to_char(..., 'ID')的星期几编号与extract(isodow FROM ...)函数匹配, - 但to_char(..., 'D')的不匹配extract(dow FROM ...)的星期编号。 + 但to_char(..., 'D')的不匹配extract(dow FROM ...)的星期几编号。 @@ -763,12 +758,12 @@ - 展示了可以用于格式化数字值的模版模式。 + 展示了可以用于格式化数值的模板模式。
- 用于数字格式化的模板模式 + 用于数值格式化的模板模式 @@ -783,21 +778,21 @@ 9 - 数位(如果无意义可以被删除) + 数位(非有效位可以被省略) 0 - 数位(即便没有意义也不会被删除) + 数位(即便是非有效位也不会被省略) - . (period) + .(句点) 小数点 - , (comma) + ,(逗号) 分组(千)分隔符 @@ -808,22 +803,22 @@ S - 带符号的数字(使用区域) + 紧贴数值的正负号(使用区域设置) L - 货币符号(使用区域) + 货币符号(使用区域设置) D - 小数点(使用区域) + 小数点(使用区域设置) G - 分组分隔符(使用区域) + 分组分隔符(使用区域设置) @@ -842,12 +837,12 @@ - RN - 罗马数字(输入在 1 和 3999 之间) + RNrn + 罗马数字(数值在 1 和 3999 之间) - TH or th + THth 序数后缀 @@ -865,7 +860,7 @@
- 数字格式化的使用注意事项: + 数值格式化的使用注意事项: @@ -881,14 +876,14 @@ - 如果格式提供的小数位数少于被格式化的数字,则to_char()将会将数字四舍五入到指定的小数位数。 + 如果格式指定的小数位数少于被格式化数值的小数位数,to_char()会将该数值舍入到指定的小数位数。 - 模式字符SLDG表示当前区域设置定义的符号、货币符号、小数点和千位分隔符字符 + 模式字符SLDG表示当前区域设置定义的正负号、货币符号、小数点和千位分隔符字符 (参见)。模式字符句点和逗号表示这些确切字符,具有小数点和千位分隔符的含义,不受区域设置影响。 @@ -897,15 +892,14 @@ - 如果在to_char()的模式中没有明确指定符号,将为符号保留一列,并将其锚定到(出现在)数字的左侧。 - 如果S出现在一些9的左侧,它也将锚定到数字。 + 如果to_char()的模式中没有明确指定正负号的位置,就会为正负号保留一列,并使其紧贴数值(紧靠数值左侧)。如果S紧邻若干个9的左侧,它同样会紧贴数值。 - 使用SGPLMI格式化的符号不与数字绑定; + 使用SGPLMI格式化的正负号不紧贴数值; 例如,to_char(-12, 'MI9999')会产生'-  12', 但to_char(-12, 'S9999')会产生'  -12'。 (Oracle实现不允许在9之前使用MI,而是要求9MI之前。) @@ -932,7 +926,7 @@ to_number函数中,如果使用非数据模板模式,如LTH, - 则会跳过相应数量的输入字符,无论它们是否与模板模式匹配,除非它们是数据字符(即数字、符号、小数点或逗号)。 + 则会跳过相应数量的输入字符,无论它们是否与模板模式匹配,除非它们是数据字符(即数字、正负号、小数点或逗号)。 例如,TH会跳过两个非数据字符。 @@ -943,7 +937,8 @@ Vto_char一起, 将输入值乘以10^n, 其中n是跟在V后面的数字位数。 - Vto_number一起以类似的方式除法。 + Vto_number一起以类似的方式进行除法。 + V可以视为输入或输出字符串中隐含小数点位置的标记。 to_charto_number不支持与小数点结合使用的V (例如,不允许使用99.9V99)。 @@ -955,21 +950,27 @@ EEEE(科学计数法)不能与任何其他格式模式或修饰符结合使用,除了数字和小数点模式之外,必须位于格式字符串的末尾(例如,9.99EEEE是一个有效模式)。
+ + + + 在to_number()中,RN模式将标准形式的罗马数字转换为数值。输入不区分大小写,因此RNrn等效。RN不能与其他格式化模式或修饰符组合使用,唯一的例外是FM;该修饰符只适用于to_char(),在to_number()中会被忽略。 + + - 某些修饰语可以被应用到任何模板来改变其行为。例如,FM99.99是带有FM修饰语的99.99模式。中展示了用于数字格式化模式修饰语。 + 某些修饰符可以被应用到任何模板来改变其行为。例如,FM99.99是带有FM修饰符的99.99模式。中展示了用于数值格式化的模式修饰符。 - 用于数字格式化的模板模式修饰语 + 用于数值格式化的模板模式修饰符 - 修饰语 + 修饰符 描述 示例 @@ -977,19 +978,19 @@ - FM prefix - 填充模式(抑制拖尾零和填充的空白) + FM 前缀 + 填充模式(抑制尾随零和填充的空白) FM99.99 - TH suffix + TH 后缀 大写序数后缀 999TH - th suffix + th 后缀 小写序数后缀 999th @@ -1022,6 +1023,13 @@ 'Tuesday, 6  05:39:18' + to_char(current_timestamp AT TIME ZONE + 'UTC', 'YYYY-MM-DD"T"HH24:MI:SS"Z"') + '2022-12-06T05:39:18Z', + ISO 8601 扩展格式 + + + to_char(-0.1, '99.99') '  -.10' diff --git a/zh/19/func/func-geometry.sgml b/zh/19/func/func-geometry.sgml index c4b85319..c8263764 100644 --- a/zh/19/func/func-geometry.sgml +++ b/zh/19/func/func-geometry.sgml @@ -5,7 +5,7 @@ 几何类型pointboxlseglinepath、 - polygoncircle有一大堆本地支持函数和操作符,如中所示。 + polygoncircle有大量内置支持函数和操作符,如中所示。
@@ -50,7 +50,7 @@ path - 连接两个打开的路径(如果其中一个路径是关闭的,则返回NULL)。 + 连接两个开放路径(如果任一路径是封闭的,则返回NULL)。 path '[(0,0),(1,1)]' + path '[(2,2),(3,3),(4,4)]' @@ -79,12 +79,12 @@ geometric_type - 将第一个参数的每个点乘上第二个point(将点视为由实部和虚部表示的复数,并执行标准的复数乘法)。 + 将第一个参数的每个点乘上第二个point(将点视为由实部和虚部表示的复数,并执行标准的复数乘法)。 如果将第二个point解释为向量,这等价于将对象的大小和到原点的距离按向量的长度缩放,并以向量与x轴的夹角绕原点逆时针旋转。 - 适用于point, box,Rotating 用这些操作符“旋转”一个盒子,只会移动它的角点:这个盒子仍然被认为有平行于轴的边。 - 因此,盒子的大小并没有像真正的旋转那样得到保留。 - path, circle.。 + 适用于pointbox用这些操作符旋转一个矩形框,只会移动它的角点:这个矩形框仍然被认为有平行于轴的边。 + 因此,矩形框的大小并没有像真正的旋转那样得到保留。 + pathcircle path '((0,0),(1,0),(1,1))' * point '(3.0,0)' @@ -103,7 +103,7 @@ 将第一个参数的每个点除以第二个point(将点视为由实部和虚部表示的复数,并执行标准的复数除法)。 - 如果将第二个point解释为向量,这等价于将物体的大小和到原点的距离按向量的长度向下缩放,并以向量与x轴的夹角围绕原点顺时针旋转。 + 如果将第二个point解释为向量,这等价于将对象的大小和到原点的距离按向量长度的倒数缩放,并以向量与x轴的夹角围绕原点顺时针旋转。 适用于 point, box, path,circle @@ -180,7 +180,7 @@ box - 计算两个方框的交集,如果没有则为NULL。 + 计算两个矩形框的交集,如果没有则为NULL。 box '(2,2),(-1,-1)' # box '(1,1),(-2,-2)' @@ -194,7 +194,7 @@ point - 计算第一个对象上距离第二个对象最近的点。 + 计算第二个对象上距离第一个对象最近的点。 可用于以下类型的配对: (point, box), (point, lseg), @@ -216,7 +216,7 @@ 计算对象之间的距离。 - 对于所有七种几何类型,所有point与另一种几何类型的组合, + 适用于所有七种几何类型,所有point与另一种几何类型的组合, 以及以下这些额外的类型对: (box, lseg), (lseg, line), @@ -256,7 +256,7 @@ boolean - 第一个对象包含在第二个对象之中还是在第二个对象之上? 适用于这些类型对: + 第一个对象是否位于第二个对象内部或其上? 适用于这些类型对: (point, box), (point, lseg), (point, line), @@ -356,7 +356,7 @@ boolean - 第一个对象是否确定位于第二个对象下面? + 第一个对象是否严格位于第二个对象下面? 适用于 point, box, polygon, circle @@ -371,7 +371,7 @@ boolean - 第一个对象是否确定位于第二个对象上面? + 第一个对象是否严格位于第二个对象上面? 适用于 point, box, polygon, circle. @@ -444,7 +444,7 @@ boolean - 这些对象是否相交? 适用于这些类型对: + 这些对象是否相交? 适用于这些类型对: (box, box), (lseg, box), (lseg, lseg), @@ -469,7 +469,7 @@ boolean - 线是水平的? + 线是否水平? ?- lseg '[(-1,0),(1,0)]' @@ -501,7 +501,7 @@ boolean - 线是纵向的? + 线是否竖直? ?| lseg '[(-1,0),(1,0)]' @@ -533,7 +533,7 @@ boolean - 线是垂直的? + 两条线是否互相垂直? lseg '[(0,0),(0,1)]' ?-| lseg '[(0,0),(1,0)]' @@ -551,7 +551,7 @@ boolean - 线是平行的? + 两条线是否平行? lseg '[(-1,0),(1,0)]' ?|| lseg '[(-1,2),(1,2)]' @@ -580,16 +580,16 @@ - 请注意same as操作符(~=),表示pointboxpolygoncircle类型的一般相等概念。 - 这些类型中的某些还有一个=操作符,但是=只比较相同的面积。 - 其它的标量比较操作符 (<=等等),在这些类型可用的地方,同样比较区域。 + 注意,相同操作符~=表示pointboxpolygoncircle类型通常意义上的相等。 + 某些几何类型还有=操作符,但=仅比较面积是否相等。 + 对于提供其他标量比较操作符(<=等)的类型,这些操作符同样比较面积。 - 在PostgreSQL14之前, 该点严格低于/高于比较操作符 point <<| pointpoint |>> point 分别被称为 <^>^。 + 在PostgreSQL14之前, 用于判断点是否严格位于另一点下方/上方的比较操作符 point <<| pointpoint |>> point 分别被称为 <^>^。 这些名字仍然可以使用,但是已被弃用并且最终将被移除。 @@ -886,7 +886,7 @@ box - 计算内接于圆的方框。 + 计算内接于圆的矩形框。 box(circle '<(0,0),2>') @@ -945,7 +945,7 @@ box - 计算两个方框的边界框。 + 计算两个矩形框的边界框。 bound_box(box '(1,1),(0,0)', box '(4,4),(3,3)') @@ -962,7 +962,7 @@ circle - 计算包围方框的最小圆。 + 计算包围矩形框的最小圆。 circle(box '(1,1),(0,0)') @@ -1055,7 +1055,7 @@ path - 将多边形转换为具有点的相同列表的封闭路径。 + 将多边形转换为具有相同点列表的封闭路径。 path(polygon '((0,0),(1,1),(2,0))') @@ -1163,7 +1163,7 @@ polygon(circle '<(0,0),2>') - (-2,0,)&zwsp; (-1.73205080758774,0.9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999998999998989898989676868686887898999999999998989898989898999978987878787808070876888788989898989898989898989898989898989898989898968686868688768686887878989896868686889899999999999990000890000899900000000890000890000890000000000000000 + ((-2,0),&zwsp;(-1.7320508075688774,0.9999999999999999),&zwsp;(-1.0000000000000002,1.7320508075688772),&zwsp;(-1.2246063538223773e-16,2),&zwsp;(0.9999999999999996,1.7320508075688774),&zwsp;(1.732050807568877,1.0000000000000007),&zwsp;(2,2.4492127076447545e-16),&zwsp;(1.7320508075688776,-0.9999999999999994),&zwsp;(1.0000000000000009,-1.7320508075688767),&zwsp;(3.673819061467132e-16,-2),&zwsp;(-0.9999999999999987,-1.732050807568878),&zwsp;(-1.7320508075688767,-1.0000000000000009)) @@ -1177,7 +1177,7 @@ polygon(4, circle '<(3,0),1>') - ((2,0,)&zwsp; (3,1,)&zwsp; (4,1.2246063538223773e-16), &zwsp; (3,-1)). + ((2,0),&zwsp;(3,1),&zwsp;(4,1.2246063538223773e-16),&zwsp;(3,-1)) @@ -1187,7 +1187,7 @@ polygon - 将封闭路径转换为具有点的相同列表的多边形。 + 将封闭路径转换为具有相同点列表的多边形。 polygon(path '((0,0),(1,1),(2,0))') @@ -1200,7 +1200,7 @@
- 我们可以把一个point的两个组成数字当作具有索引 0 和 1 的数组访问。例如,如果t.p是一个point列,那么SELECT p[0] FROM t检索 X 坐标而 UPDATE t SET p[1] = ...改变 Y 坐标。同样,box或者lseg类型的值可以当作两个point值的数组值看待。 + 可以把一个point当作下标为 0 和 1 的数组,访问它的两个数值分量。例如,如果t.p是一个point列,那么SELECT p[0] FROM t检索 X 坐标而 UPDATE t SET p[1] = ...改变 Y 坐标。同样,box或者lseg类型的值可以当作两个point值组成的数组看待。 diff --git a/zh/19/func/func-info.sgml b/zh/19/func/func-info.sgml index 906f743f..348ce8db 100644 --- a/zh/19/func/func-info.sgml +++ b/zh/19/func/func-info.sgml @@ -2,11 +2,15 @@ 系统信息函数和操作符 + + 本节描述的函数用于获取有关PostgreSQL安装的各种信息。 + + 会话信息函数 - 展示了多个可以抽取会话和系统信息的函数。 + 列出了多个用于提取会话和系统信息的函数。 @@ -47,7 +51,7 @@ name - 返回当前数据库的名称。(在SQL标准中数据库被称为catalogs,因此current_catalog是该标准的拼写方式。) + 返回当前数据库的名称。(SQL 标准将数据库称为目录(catalogs),因此current_catalog是标准中的写法。) @@ -60,7 +64,7 @@ text - 返回当前所执行查询的文本,由客户端提交的(可能包含一个以上的语句)。 + 返回客户端提交的当前正在执行的查询文本(可能包含多条语句)。 @@ -83,8 +87,8 @@ current_schema - schema - current + 模式 + 当前 current_schema name @@ -105,16 +109,14 @@ current_schemas - search path - current + 搜索路径 + 当前 current_schemas ( include_implicit boolean ) name[] - 返回当前在有效搜索路径中的所有模式的名称的数组,以优先级顺序。 - (当前 设置中与已存在的、可搜索模式不相符的项将被省略。) - 如果布尔参数为true,则类似pg_catalog的隐式搜索的系统模式将包含在结果中。 + 返回当前有效搜索路径中所有模式名称的数组,按优先级排序。(当前设置中不对应于已存在且可搜索的模式的项会被省略。)如果布尔参数为true,结果还会包含pg_catalog等隐式搜索的系统模式。 @@ -124,8 +126,8 @@ current_user - user - current + 用户 + 当前 current_user name @@ -144,7 +146,7 @@ inet - 返回当前客户端的IP地址,如果当前连接是通过Unix-域套接字则返回NULL + 返回当前客户端的 IP 地址;如果当前连接通过 Unix 域套接字建立,则返回NULL @@ -157,7 +159,7 @@ integer - 返回当前客户端的IP端口号,如果当前连接是通过Unix-域套接字则返回NULL。 + 返回当前客户端的IP端口号,如果当前连接是通过Unix 域套接字则返回NULL @@ -170,7 +172,7 @@ inet - 返回服务器接受当前连接的IP地址,如果当前连接是通过Unix-域套接字则返回NULL。 + 返回服务器接受当前连接的IP地址,如果当前连接是通过Unix 域套接字则返回NULL @@ -183,7 +185,7 @@ integer - 返回服务器接受当前连接的IP端口号,如果当前连接是通过Unix-域套接字则返回NULL。 + 返回服务器接受当前连接的IP端口号,如果当前连接是通过Unix 域套接字则返回NULL @@ -209,12 +211,10 @@ integer[] - 返回阻止服务器进程的会话的进程ID数组,该进程ID与指定的进程ID一起获取锁定,如果没有这样的服务器进程或者没有被阻塞,则返回一个空数组。 + 返回一个数组,包含阻止指定进程 ID 对应的服务器进程获取锁的会话进程 ID;如果不存在这样的服务器进程,或该进程未被阻塞,则返回空数组。 - 如果一个服务器进程持有一个与被阻塞进程的锁请求冲突的锁(硬阻塞),或者正在等待一个与被阻塞进程的锁请求冲突并且在等待队列中位于其前面的锁(软阻塞),那么这个服务器进程就会阻塞另一个服务器进程。 - 当使用并行查询时结果总是列出客户端可见的进程ID(即pg_backend_pid的结果),即使实际的锁是由子工作进程持有或等待的。 - 因此,结果中可能存在重复的pid。还要注意当准备好的事务持有冲突锁时,它将用零进程ID表示。 + 一个服务器进程会在以下情况下阻塞另一个进程:它持有与被阻塞进程请求的锁冲突的锁(硬阻塞);或者它正在等待一个会与被阻塞进程请求的锁冲突的锁,并且在等待队列中位于被阻塞进程之前(软阻塞)。使用并行查询时,即使实际持锁或等待锁的是子工作进程,结果也始终列出客户端可见的进程 ID(即pg_backend_pid的结果)。因此,结果中可能出现重复的 PID。另外,如果持有冲突锁的是一个预备事务,结果中会用进程 ID 0 表示它。 频繁调用这个函数可能会对数据库性能产生一些影响,因为它需要在短时间内独占访问锁管理器的共享状态。 @@ -230,8 +230,7 @@ timestamp with time zone - 返回服务器配置文件最后加载的时间。如果当前会话当时是活跃的,那么这将是会话本身重新读取配置文件的时间(因此在不同的会话中读取会稍有不同)。 - 否则,就是postmaster进程重新读取配置文件的时间。 + 返回服务器配置文件最近一次加载的时间。如果当时当前会话已经存在,则返回该会话自身重新读取配置文件的时间(因此不同会话中的返回时间会略有不同)。否则,返回 postmaster 进程重新读取配置文件的时间。 @@ -241,16 +240,16 @@ pg_current_logfile - Logging - pg_current_logfile函数 + 日志记录 + pg_current_logfile 函数 current_logfiles - 和pg_current_logfile函数 + 和pg_current_logfile 函数 - Logging - current_logfiles文件和pg_current_logfile函数 + 日志记录 + current_logfiles 文件和pg_current_logfile 函数 pg_current_logfile ( text ) text @@ -266,7 +265,7 @@ 结果反映current_logfiles文件的内容。 - 默认情况下,此函数仅限于超级用户以及具有pg_monitor角色权限的角色,但可以向其他用户授予 EXECUTE 权限以运行该函数。 + 默认情况下,此函数仅限超级用户和具有pg_monitor角色权限的角色使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -360,7 +359,7 @@ double precision - 返回当前被等待处理的通知所占用的异步通知队列最大尺寸的分数(0–1)。更多信息请参见。 + 返回待处理通知当前占用的空间占异步通知队列最大容量的比例(0–1)。更多信息请参见 @@ -386,11 +385,11 @@ integer[] - 返回一个进程ID数组,该进程ID是阻塞服务器进程获取安全快照的会话的进程ID数组,如果没有这样的服务器进程或者没有阻塞,则返回一个空数组。 + 返回一个数组,包含阻止指定进程 ID 对应的服务器进程获取安全快照的会话进程 ID;如果不存在这样的服务器进程,或该进程未被阻塞,则返回空数组。 运行SERIALIZABLE事务的会话会阻止SERIALIZABLE READ ONLY DEFERRABLE事务获取快照,直到后者确定可以安全地避免获取谓词锁。 - 关于可串行化和可延迟事务的更多信息,请参见。 + 关于可序列化和可延迟事务的更多信息,请参见 频繁调用这个函数可能会对数据库性能产生一些影响,因为它需要在短时间内访问谓词锁管理器的共享状态。 @@ -406,7 +405,7 @@ integer - 返回当前嵌套层次的PostgreSQL触发器(如果没有调用则为 0,直接或间接,从一个触发器内部开始)。 + 返回PostgreSQL触发器的当前嵌套层级(如果不是从触发器内部直接或间接调用,则为 0)。 @@ -419,7 +418,7 @@ name - 返回会话用户名. + 返回会话用户名。 @@ -449,20 +448,7 @@ - - - - version - - version () - text - - - 返回描述PostgreSQL服务器的版本的字符串。 - 你还可以从 中获得此信息,或者对于机器可读的版本,使用。 - 软件开发人员可以使用server_version_num(从8.2起可用)或,而不是解析文本版本。 - - + @@ -470,17 +456,12 @@ - current_catalogcurrent_rolecurrent_schemacurrent_usersession_useruserSQL里有特殊的语法地位: 它们被调用时结尾不要跟着圆括号。 - 在 PostgreSQL 中,圆括号可以有选择性地被用于current_schema,但是不能和其他的一起用。 + current_catalogcurrent_rolecurrent_schemacurrent_usersession_useruserSQL中具有特殊语法:调用时不得在后面加圆括号。在 PostgreSQL 中,current_schema可以选择加圆括号,其他函数则不可以。 - session_user通常是发起当前数据库连接的用户,不过超级用户可以用修改这个设置。 - current_user是用于权限检查的用户标识。通常, 它总是等于会话用户,但是可以被改变。 - 它也会在函数执行的过程中随着属性SECURITY DEFINER的改变而改变。 - 在 Unix 的说法里,那么会话用户是真实用户,而当前用户是有效用户。 - current_role以及usercurrent_user的同义词(SQL标准在current_rolecurrent_user之间做了区分,但PostgreSQL不区分,因为它把用户和角色统一成了一种实体)。 + session_user通常是发起当前数据库连接的用户,但超级用户可以用修改此设置。current_user是用于权限检查的用户标识,通常等于会话用户,但可以用更改。在执行具有SECURITY DEFINER属性的函数期间,它也会改变。用 Unix 的术语来说,会话用户是真实用户,当前用户是有效用户current_roleusercurrent_user的同义词。(SQL 标准区分current_rolecurrent_user,但PostgreSQL不区分,因为它将用户和角色统一为同一种实体。) @@ -490,18 +471,12 @@ 访问权限查询函数 - privilege - querying + 权限 + 查询 - 列出那些允许编程查询对象访问权限的函数。参阅获取更多有关权限的信息。 - 在这些函数中,可以通过名称或OID (pg_authid.oid)指定被查询权限的用户,或者如果名称被指定为public,则检查PUBLIC伪角色的权限。 - 同样,user参数可以完全省略,在这种情况下,假设为current_user。被查询的对象也可以通过名称或OID来指定。 - 通过名称指定时,可以包含相关的模式名称。感兴趣的访问权限由一个文本字符串指定,它必须计算为对象类型的一个适当的权限关键字(例如,SELECT)。 - 还可以将 WITH GRANT OPTION添加到权限类型中,以测试该权限是否由授予选项持有。 - 同样,可以用逗号分隔列出多个权限类型,在这种情况下,如果所列出的权限中有任何一个被持有,结果将为真。 - (权限字符串的大小写不重要,权限名之间允许有额外的空格,但在权限名中不允许。)一些示例: + 列出了允许以编程方式查询对象访问权限的函数。(关于权限的更多信息,请参见。)在这些函数中,可以通过名称或 OID(pg_authid.oid)指定要查询权限的用户;如果名称为public,则检查 PUBLIC 伪角色的权限。也可以完全省略user参数,此时使用current_user。要查询的对象也可以通过名称或 OID 指定。通过名称指定时,如适用,可以包含模式名。所需访问权限由文本字符串指定,其值必须为适用于该对象类型的权限关键字之一(例如SELECT)。还可以在权限类型后附加WITH GRANT OPTION,以检查是否拥有该权限及其授予选项。也可以用逗号分隔列出多个权限类型;只要拥有列出的任一权限,结果就为真。(权限字符串不区分大小写,权限名之间允许有额外的空白,但权限名内部不允许。)例如: SELECT has_table_privilege('myschema.mytable', 'select'); SELECT has_table_privilege('joe', 'mytable', 'INSERT, SELECT WITH GRANT OPTION'); @@ -538,9 +513,7 @@ SELECT has_table_privilege('joe', 'mytable', 'INSERT, SELECT WITH GRANT OPTION') boolean - 用户是否对表的任何列有权限? - 如果对整个表持有权限,或者对至少一个列有列级的权限授予,则会成功。 - 允许的权限类型为SELECT, INSERT,UPDATE, 和 REFERENCES + 用户是否对表的至少一列具有权限?如果拥有整个表的权限,或至少一列获得了该权限的列级授权,则返回真。允许的权限类型为SELECTINSERTUPDATEREFERENCES @@ -591,7 +564,7 @@ SELECT has_table_privilege('joe', 'mytable', 'INSERT, SELECT WITH GRANT OPTION') boolean - 用户是否拥有外部数据包装的权限?唯一允许的权限类型是USAGE。 + 用户是否具有外部数据包装器权限?唯一允许的权限类型为USAGE @@ -695,7 +668,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); boolean - 用户是否有顺序权限?允许的权限类型有USAGE, SELECT, 和UPDATE。 + 用户是否具有序列权限?允许的权限类型为USAGESELECTUPDATE @@ -776,11 +749,11 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); boolean - 用户对角色有权限吗?允许的权限类型有MEMBERUSAGESET。 + 用户是否具有角色权限?允许的权限类型为MEMBERUSAGESETMEMBER表示对该角色的直接或间接成员资格,而不考虑由此授予的具体权限。 USAGE表示该角色的权限是否无需执行SET ROLE即可立即使用,而SET表示是否可以使用SET ROLE命令切换到该角色。 任一权限类型后面都可以附加WITH ADMIN OPTIONWITH GRANT OPTION,用于测试是否持有 ADMIN 权限(这六种写法测试的都是同一件事)。 - 此函数不允许特殊情况下将user设置为public,因为PUBLIC伪角色永远不能成为真实角色的成员。 + 此函数不允许将user设置为public这一特殊情况,因为 PUBLIC 伪角色永远不能成为实际角色的成员。 @@ -794,7 +767,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); boolean - 在当前用户和当前环境的上下文之中,指定表的行级安全是活动的吗? + 在当前用户和当前环境的上下文中,指定表的行级安全性是否生效? @@ -802,8 +775,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); - 显示了aclitem类型的可用操作符,它是访问权限的目录表示。 - 有关如何读取访问权限值的信息,请参阅 。 + 列出了aclitem类型可用的操作符;该类型是访问权限在系统目录中的表示形式。有关如何解读访问权限值的信息,请参见 @@ -836,8 +808,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); boolean - aclitem相等吗?(注意,aclitem类型缺少比较操作符的通常集合;它只有相等。 - 反而言之,aclitem数组只能进行相等比较。) + 两个aclitem是否相等?(注意,aclitem类型没有通常的整套比较操作符,而只支持相等比较。因此,aclitem数组也只能进行相等比较。) 'calvin=r*w/hobbes'::aclitem = 'calvin=r*w*/hobbes'::aclitem @@ -854,7 +825,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); boolean - 数组是否包含指定的权限?(如果有一个数组条目与aclitem的被授权人和授予人相匹配,并且至少具有权限的指定集,则此选项为真。) + 数组是否包含指定的权限?(如果数组中存在一个条目,其被授权者和授权者与该aclitem相同,且至少包含指定的全部权限,则返回真。) '{calvin=r*w/hobbes,hobbes=r*w*/postgres}'::aclitem[] @> 'calvin=r*/hobbes'::aclitem @@ -866,7 +837,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute');
- 显示了一些额外的函数来管理aclitem类型。 + 列出了一些用于管理aclitem类型的其他函数。 @@ -898,23 +869,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); aclitem[] - 构造一个aclitem数组,保存属于具有OID ownerId的角色的对象类型type的默认访问权限。 - 这表示当对象的ACL条目为空时将假定的访问权限。(默认访问权限在中描述。) - type参数必须是以下之一: - 'c'表示COLUMN, - 'r'表示TABLE和类似表的对象, - 's'表示SEQUENCE, - 'd'表示DATABASE, - 'f'表示FUNCTIONPROCEDURE, - 'l'表示LANGUAGE, - 'L'表示LARGE OBJECT, - 'n'表示SCHEMA, - 'p'表示PARAMETER, - 't'表示TABLESPACE, - 'F'表示FOREIGN DATA WRAPPER, - 'S'表示FOREIGN SERVER, - 或 - 'T'表示TYPEDOMAIN。 + 构造一个aclitem数组,保存类型为type、属于 OID 为ownerId的角色的对象的默认访问权限。当对象的ACL条目为空值时,会采用这些访问权限。(默认访问权限见。)type参数必须为以下值之一:'c' 表示COLUMN,'r' 表示TABLE和类似表的对象,'s' 表示SEQUENCE,'d' 表示DATABASE,'f' 表示FUNCTIONPROCEDURE,'l' 表示LANGUAGE,'L' 表示LARGE OBJECT,'n' 表示SCHEMA,'p' 表示PARAMETER,'t' 表示TABLESPACE,'F' 表示FOREIGN DATA WRAPPER,'S' 表示FOREIGN SERVER,'T' 表示TYPEDOMAIN @@ -931,9 +886,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); is_grantableboolean ) - 以行集的形式返回aclitem数组。如果受让人是伪角色PUBLIC,则在grantee列中用0表示。 - 每个被授予的权限都表示为SELECT, INSERT等。 - 注意,每个权限被分割成单独的一行,因此在privilege_type列中只出现一个关键字。 + 以行集的形式返回aclitem数组。如果被授权者是伪角色 PUBLIC,则在grantee列中用零表示。每项授予的权限表示为SELECTINSERT等(完整列表见)。注意,每项权限都会拆成单独的一行,因此privilege_type列中只会出现一个关键字。 @@ -950,7 +903,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); aclitem - 使用给定的属性构造 aclitem 。 + 使用给定的属性构造aclitemprivileges是以逗号分隔的权限名列表,例如SELECTINSERT等,列出的所有权限都会设置在结果中。(权限字符串不区分大小写,权限名之间允许有额外的空白,但权限名内部不允许。) @@ -964,14 +917,9 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); 模式可见性查询函数 - 展示了决定是否一个特定对象在当前模式搜索路径中可见的函数。 - 例如,如果一个表所在的模式在当前搜索路径中并且在它之前没有出现过相同的名字,这个表就被说是可见的。 - 这等价于在语句中表可以被用名称引用但不加显式的模式限定。因此,要列出所有可见表的名字: - + 列出了判断某个特定对象是否可见的函数,其判断依据是当前模式搜索路径。例如,如果表所在的模式位于搜索路径中,并且在搜索路径的更前面没有同名表,就称该表可见。这等价于说,可以只通过表名引用该表,而不必显式地用模式限定。因此,要列出所有可见表的名称: SELECT relname FROM pg_class WHERE pg_table_is_visible(oid); - - 对于函数和操作符,如果路径前面没有相同名称和参数数据类型的对象,那么搜索路径中的对象就是可见的。 - 对于操作符类和操作符族,要考虑名称和关联的索引访问方法。 +对于函数和操作符,只要搜索路径中更靠前的位置没有对象具有与被检查对象相同的名称和参数数据类型,就称被检查对象可见。对于操作符类和操作符族,会同时考虑名称及关联的索引访问方法。 @@ -1110,7 +1058,7 @@ SELECT relname FROM pg_class WHERE pg_table_is_visible(oid); boolean - 文本搜索配置在搜索路径可见吗? + 全文检索配置是否在搜索路径中可见? @@ -1123,7 +1071,7 @@ SELECT relname FROM pg_class WHERE pg_table_is_visible(oid); boolean - 文本搜索字典在搜索路径可见吗? + 全文检索词典是否在搜索路径中可见? @@ -1136,7 +1084,7 @@ SELECT relname FROM pg_class WHERE pg_table_is_visible(oid); boolean - 文本搜索解析器在搜索路径中可见吗? + 全文检索解析器是否在搜索路径中可见? @@ -1149,7 +1097,7 @@ SELECT relname FROM pg_class WHERE pg_table_is_visible(oid); boolean - 文本搜索模板在搜索路径可见吗? + 全文检索模板是否在搜索路径中可见? @@ -1170,11 +1118,10 @@ SELECT relname FROM pg_class WHERE pg_table_is_visible(oid);
- 所有这些函数都要求用对象 OID 来标识将被检查的对象。如果你想用名称来测试一个对象,使用 OID 别名类型(regclassregtyperegprocedureregoperatorregconfigregdictionary)将会很方便。例如: - + 所有这些函数都需要用对象 OID 标识要检查的对象。如果想按名称测试对象,使用 OID 别名类型会很方便(regclassregtype, + regprocedureregoperatorregconfig,或regdictionary),例如: SELECT pg_type_is_visible('myschema.widget'::regtype); - - 注意以这种方式测试一个非模式限定的类型名没什么意义 — 如果该名称完全能被识别,它必须是可见的。 +注意,用这种方式测试不带模式限定的类型名并没有太大意义:只要该名称能够被识别,它就必然可见。 @@ -1227,10 +1174,10 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); regtype - 返回由类型 OID 标识的域的基类型的 OID。如果参数是非域类型的 OID,则原样返回该参数。如果参数不是有效的类型 OID,则返回 NULL。如果存在一条域依赖链,则会递归直到找到基类型。 + 返回由类型 OID 标识的域的基础类型 OID。如果参数是非域类型的 OID,则原样返回该参数。如果参数不是有效的类型 OID,则返回 NULL。如果存在域依赖链,则递归查找,直到找到基础类型。 - 假定 CREATE DOMAIN mytext AS text: + 假设执行了CREATE DOMAIN mytext AS text pg_basetype('mytext'::regtype) @@ -1284,7 +1231,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); 返回一组记录,描述存在于PostgreSQL系统目录中的外键关系。 fktable 列包含引用目录的名称,fkcols列包含引用列的名称。 类似地,pktable列包含被引用目录的名称,而pkcols列包含被引用列的名称。 - 如果is_array为真,则最后一个引用列是一个数组,其每个元素都应该与引用目录中的某个条目匹配。 + 如果is_array为真,则最后一个引用列是一个数组,其每个元素都应该与被引用目录中的某个条目匹配。 如果is_opt为真,则允许引用列包含零而不是有效引用。 @@ -1298,7 +1245,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 重构为了约束的创建命令。(这是一个反编译的重构,而不是命令的原始文本。) + 重建约束的创建命令。(这是反编译重建的结果,并非命令的原始文本。) @@ -1311,8 +1258,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 反编译存储在系统目录中的表达式的内部形式,例如列的默认值。 - 如果表达式可能包含变量,则指定它们所指向的关系的OID作为第二个参数;如果没有预期的变量,传递0就可以了。 + 反编译存储在系统目录中的表达式的内部形式,例如列的默认值。如果表达式可能包含 Var 节点,请将它们所引用的关系的 OID 指定为第二个参数;如果预计不含 Var 节点,传入零即可。 @@ -1325,8 +1271,8 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 重构为了函数或过程的创建命令。(这是一个反编译的重构,而不是命令的原始文本。) - 结果是一个完整的CREATE OR REPLACE FUNCTIONCREATE OR REPLACE PROCEDURE语句。 + 重建函数或过程的创建命令。(这是反编译重建的结果,并非命令的原始文本。) + 结果是一条完整的CREATE OR REPLACE FUNCTIONCREATE OR REPLACE PROCEDURE语句。 @@ -1339,7 +1285,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 重新构造函数或过程的参数列表,以其在 CREATE FUNCTION里面需要出现的形式(包括默认值)。 + 重建函数或过程的参数列表,采用其在CREATE FUNCTION中应有的形式(包括默认值)。 @@ -1352,7 +1298,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 重新构造标识函数或过程所需的参数列表,以其应出现在ALTER FUNCTION等命令中的形式。这个表单省略默认值。 + 重建标识函数或过程所需的参数列表,采用其在ALTER FUNCTION等命令中应有的形式。这种形式省略默认值。 @@ -1365,7 +1311,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 重构函数的RETURNS子句,以其需要出现在CREATE FUNCTION中的形式。对于过程,返回NULL。 + 重建函数的RETURNS子句,采用其在CREATE FUNCTION中应有的形式。对于过程,返回NULL @@ -1378,7 +1324,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 重构针对索引的创建命令。(这是一个反编译的重构,而不是命令的原始文本。)如果提供了column而且不为零,则只重构该列的定义。 + 重建索引的创建命令。(这是反编译重建的结果,并非命令的原始文本。)如果提供了column而且不为零,则只重建该列的定义。 @@ -1396,11 +1342,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); baredesc text ) - 返回一组描述服务器识别的SQL关键字的记录。word列包含关键字。 - catcode列包含一个类别代码:U表示无保留关键字,C表示可以是列名的关键字,T表示可以是类型或函数名的关键字,或者R表示完全保留关键字。 - 如果关键字可以在SELECT列表中用作bare列标签,则barelabel列包含true,或者false,如果它只能在AS之后使用。 - catdesc列包含可能本地化字符串,描述关键字的类别。 - baredesc列包含可能本地化的字符串,描述关键字的列标签状态。 + 返回描述服务器所识别 SQL 关键字的一组记录。word列包含关键字。catcode列包含类别代码:U表示非保留关键字,C表示可用作列名的关键字,T表示可用作类型名或函数名的关键字,R表示完全保留的关键字。如果关键字可以在SELECT列表中用作列标签,barelabel列为true;如果只能在AS之后使用,则为falsecatdesc列包含描述关键字类别的字符串,该字符串可能已被本地化。baredesc列包含描述关键字列标签状态的字符串,该字符串可能已被本地化。 @@ -1412,8 +1354,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 重构分区约束的定义。 - (这是反编译得到的重构结果,而不是命令的原始文本。) + 重建分区约束的定义。(这是反编译重建的结果,并非命令的原始文本。) @@ -1426,7 +1367,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 重构分区表分区键的定义,以其在 PARTITION BY 子句中的形式出现。(这是一个反编译的重构,而不是命令的原始文本。) + 重建分区表的分区键定义,采用其在CREATE TABLEPARTITION BY子句中的形式。(这是反编译重建的结果,并非命令的原始文本。) @@ -1439,7 +1380,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 重构属性图的创建命令。(这是一个反编译的重构,而不是命令的原始文本。) + 重建属性图的创建命令。(这是反编译重建的结果,并非命令的原始文本。) @@ -1452,7 +1393,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 重构针对规则的创建命令。(这是一个反编译的重构,而不是命令的原始文本。) + 重建规则的创建命令。(这是反编译重建的结果,并非命令的原始文本。) @@ -1467,15 +1408,15 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); 返回与列相关联的序列名称,如果没有序列与该列相关联则返回NULL。 如果列是标识列,则关联序列是在内部为该列创建的序列。 - 对于使用一种串行类型(serial, smallserial, bigserial)创建的列,它是为该串行列定义创建的序列。 + 对于使用一种 serial 类型(serial, smallserial, bigserial)创建的列,它是为该 serial 列定义创建的序列。 在后一种情况下,可以使用ALTER SEQUENCE OWNED BY修改或删除关联。 - (这个函数可能应该被称为pg_get_owned_sequence;它的当前名称反映了它在历史上曾与串行类型的列一起使用。) + (这个函数可能应该被称为pg_get_owned_sequence;它的当前名称反映了它在历史上曾与 serial 类型的列一起使用。) 第一个参数是具有可选模式的表名,第二个参数是列名。 由于第一个参数可能包含模式名和表名,因此按照通常的SQL规则解析它,这意味着默认情况下它是小写的。 第二个参数只是一个列名,按照字面来处理,因此保留了它的大小写。结果经过了适当的格式化,可以传递给序列函数(参见)。 - 典型的用法是读取序列的当前值以获取标识或串行列,示例如下: + 典型用法是读取标识列或 serial 列所用序列的当前值,例如: SELECT currval(pg_get_serial_sequence('sometable', 'id')); @@ -1491,7 +1432,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); text - 重构针对扩展统计对象的创建命令。(这是一个反编译的重构,而不是命令的原始文本。) + 重建扩展统计对象的创建命令。(这是反编译重建的结果,并非命令的原始文本。) @@ -1504,7 +1445,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); text - 重构针对触发器的创建命令。(这是一个反编译的重构,而不是命令的原始文本。) + 重建触发器的创建命令。(这是反编译重建的结果,并非命令的原始文本。) @@ -1530,7 +1471,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); text - 重构针对视图或物化视图的SELECT命令。(这是一个反编译的重构,而不是命令的原始文本。) + 重建定义视图或物化视图的SELECT命令。(这是反编译重建的结果,并非命令的原始文本。) @@ -1540,8 +1481,8 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); text - 重构针对视图或物化视图的底层SELECT命令。(这是一个反编译的重构,而不是命令的原始文本。) - 在这种形式的函数中,总是启用美观打印,并对长行进行换行,以尽量使它们小于指定的列数。 + 重建定义视图或物化视图的SELECT命令。(这是反编译重建的结果,并非命令的原始文本。) + 这种形式始终启用美化输出,并将长行折行,尽量使每行长度小于指定列数。 @@ -1551,7 +1492,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); text - 根据视图的文本名称而不是它的OID,重构针对视图或物化视图的底层SELECT命令。(这是弃用;请使用OID变体。) + 根据视图的文本名称而不是其 OID,重建定义视图或物化视图的SELECT命令。(此形式已弃用;请使用 OID 变体。) @@ -1564,7 +1505,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); boolean - 测试一个索引列是否具有命名属性。列出了常用索引列属性。 + 测试一个索引列是否具有指定名称的属性。列出了常用索引列属性。 (注意,扩展访问方法可以为其索引定义额外的属性名。) 如果属性名未知或不适用于特定对象,或者OID或列号不能识别有效的对象,则返回NULL @@ -1579,7 +1520,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); boolean - 测试一个索引是否具有命名属性。列出了常用的索引属性。 + 测试一个索引是否具有指定名称的属性。列出了常用的索引属性。 (注意,扩展访问方法可以为其索引定义额外的属性名。) 如果属性名未知或不适用于特定对象,或者OID不能识别有效的对象,则返回NULL @@ -1594,7 +1535,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); boolean - 测试索引访问方法是否具有命名属性。访问方法属性如所示。 + 测试索引访问方法是否具有指定名称的属性。访问方法属性如所示。 如果属性名未知或不适用于特定对象,或者OID不能识别有效的对象,则返回NULL @@ -1623,9 +1564,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); text[] - 返回与给定GUC相关联的标志数组,如果不存在则返回NULL。 - 如果GUC存在但没有要显示的标志,则结果为空数组。 - 仅公开列出在中最有用的标志。 + 返回与给定 GUC 关联的标志数组;如果该 GUC 不存在,则返回NULL。如果 GUC 存在但没有要显示的标志,则结果为空数组。此函数仅公开中列出的最有用的标志。 @@ -1638,9 +1577,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); setof oid - 返回具有存储在指定表空间中的对象的数据库的OIDs集。 - 如果这个函数返回了任何行,那么表空间就不是空的,且不能被删除。 - 要识别填充表空间的特定对象,需要连接到由pg_tablespace_databases标识的数据库,并查询它们的pg_class目录。 + 返回在指定表空间中存储了对象的数据库 OID 集合。如果此函数返回任何行,则说明该表空间不为空,不能删除。要查看存放在该表空间中的具体对象,需要连接到pg_tablespace_databases标识的数据库,并查询它们的pg_class系统目录。 @@ -1666,7 +1603,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); regtype - 返回传递给它的值的数据类型的 OID。这对于故障排除或动态构造 SQL 查询很有帮助。该函数声明为返回regtype,它是一个 OID 别名类型(参见);这意味着,为了比较,它与 OID 相同,但显示为类型名。 + 返回所传入值的数据类型的 OID。这有助于排查问题或动态构造 SQL 查询。函数声明的返回类型是regtype,它是一种 OID 别名类型(参见);这意味着它在比较时与 OID 相同,但显示为类型名。 pg_typeof(33) @@ -1683,7 +1620,9 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); text - 返回传递给它的值的排序规则名称。必要时会对该值加引号并加上模式限定。如果参数表达式没有派生出排序规则,则返回NULL。如果参数不是可排序数据类型,则会引发错误。 + 返回传入值的排序规则名称。必要时会为返回的名称加上引号和模式限定。 + 如果无法为参数表达式推导出排序规则,则返回NULL。 + 如果参数不属于支持排序规则的数据类型,则报错。 COLLATION FOR ('foo'::text) @@ -1705,7 +1644,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); 将文本关系名转换为它的OID。通过将字符串类型转换为regclass可以得到类似的结果(参见); - 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。 @@ -1732,8 +1671,8 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); regcollation - 将文本排序规则名称转换为它的OID。通过将字符串类型转换为regcollation(参见)可以得到类似的结果; - 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 将文本排序规则名称转换为它的OID。通过将字符串类型转换为regcollation(参见)可以得到类似的结果; + 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。 @@ -1746,8 +1685,8 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); regnamespace - 将文本模式名转换为它的OID。通过将字符串转换为regnamespace类型(参见)可以得到类似的结果; - 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 将文本模式名转换为它的OID。通过将字符串转换为regnamespace类型(参见)可以得到类似的结果; + 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。 @@ -1760,8 +1699,8 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); regoper - 将文本操作符名称转换为它的OID。通过将字符串类型转换为regoper(参见)可以得到类似的结果; - 但是,如果找不到名称或名称有多义性,该函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 将文本操作符名称转换为它的OID。通过将字符串类型转换为regoper(参见)可以得到类似的结果; + 但是,如果找不到名称或名称有多义性,该函数将返回NULL而不会抛出错误。 @@ -1774,8 +1713,8 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); regoperator - 将文本操作符名称(带有参数类型)转换为其OID。通过将字符串转换为regoperator类型(参见节)可以得到类似的结果; - 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 将文本操作符名称(带有参数类型)转换为其OID。通过将字符串转换为regoperator类型(参见节)可以得到类似的结果; + 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。 @@ -1788,8 +1727,8 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); regproc - 将文本函数或过程名转换为其OID。通过将字符串转换为regproc类型(参见)可以得到类似的结果; - 但是,如果找不到名称或名称有多义性,该函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 将文本函数或过程名转换为其OID。通过将字符串转换为regproc类型(参见)可以得到类似的结果; + 但是,如果找不到名称或名称有多义性,该函数将返回NULL而不会抛出错误。 @@ -1803,7 +1742,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); 将文本函数或过程名(带有参数类型)转换为其OID。通过将字符串类型转换为regprocedure可以得到类似的结果(参见); - 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。 @@ -1817,7 +1756,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); 将文本角色名转换为它的OID。通过将字符串类型转换为regrole可以得到类似的结果(参见); - 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。 @@ -1830,8 +1769,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); regtype - 将文本类型名转换为它的OID。通过将字符串类型转换为regtype可以得到类似的结果(参见); - 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 解析文本字符串,从中提取可能的类型名,并将该名称转换为类型 OID。字符串中的语法错误会导致报错;但如果字符串是语法有效的类型名,只是在系统目录中找不到该类型,结果就是 NULL。将字符串转换为 regtype 类型也能得到类似的结果(参见 ),区别在于类型转换会在找不到名称时报错。 @@ -1844,12 +1782,10 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); integer - 解析文本字符串,从中提取可能的类型名,并转换其类型修饰符(如果存在)。 - 字符串中的语法错误将导致报错;但如果字符串是语法有效的类型名,只是恰好未在目录中找到,则结果为NULL。 - 如果不存在类型修饰符,则结果为-1。 + 解析文本字符串,从中提取可能的类型名称,并转换其类型修饰符(如果有)。字符串中的语法错误会引发错误;但如果字符串是语法有效的类型名称,只是在系统目录中找不到,则结果为NULL。如果没有类型修饰符,则结果为-1 - to_regtypemod可与结合,为生成合适的输入,从而对表示类型名的字符串进行规范化。 + to_regtypemod可以与结合,为生成适当的输入,从而将表示类型名称的字符串转换为规范形式。 format_type(to_regtype('varchar(32)'), to_regtypemod('varchar(32)')) @@ -1861,10 +1797,10 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); - 大多数重构(反编译)数据库对象的函数都有一个可选的 pretty标志,如果为true,结果将被pretty-printed。 - 美观打印会抑制不必要的圆括号,并为易读性增加空格。 - 美观打印的格式可读性更好,但是默认格式更有可能被PostgreSQL的未来版本以同样的方式解释; - 因此,避免为转储目的使用美观打印的输出。为pretty参数传递false会产生与省略参数相同的结果。 + 大多数重建(反编译)数据库对象的函数都有一个可选的pretty标志;若为true,则对结果进行美化输出。 + 美化输出会省略不必要的圆括号,并增加空白以提高可读性。 + 美化后的格式更易读,但默认格式更有可能被PostgreSQL的未来版本以同样的方式解释,因此用于转储时应避免美化输出。 + 为pretty参数传入false与省略该参数的结果相同。 @@ -1909,19 +1845,20 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); distance_orderable - 列能否通过一个distance操作符(例如ORDER BY col <-> constant)有序地扫描? + + 能否按距离操作符的结果有序地扫描该列,例如ORDER BY col <-> constant returnable - 列值是否可以通过一次只用索引扫描返回? + 列值是否可以通过一次仅索引扫描返回? search_array - 列是否天然支持col = ANY(array)搜索? + 列是否原生支持col = ANY(array)搜索? @@ -1936,7 +1873,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id'));
- 索引性质 + 索引属性 @@ -1973,7 +1910,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id'));
- 索引访问方法性质 + 索引访问方法属性 @@ -2026,18 +1963,18 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); EXPLAIN - 带有此标志的参数包含在EXPLAIN (SETTINGS)命令中。 + 带有此标志的参数会在EXPLAIN (SETTINGS)命令的输出中显示。 NO_SHOW_ALL - 具有此标志的参数将被排除在SHOW ALL命令之外。 + 带有此标志的参数不会在SHOW ALL命令的输出中显示。 - NO_RESET - 具有此标志的参数不支持RESET命令。 - + NO_RESET + 带有此标志的参数不支持RESET命令。 + NO_RESET_ALL @@ -2063,16 +2000,15 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); - 对象信息和定位函数 + 对象信息和寻址函数 - 列出了与数据库对象 - 标识和定位有关的函数。 + 列出了与数据库对象标识和寻址有关的函数。
- 对象信息和定位函数 + 对象信息和寻址函数 @@ -2097,8 +2033,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); aclitem[] - 返回由目录 OID、对象 OID 和子对象 ID 指定的数据库对象的ACL。 - 对于未定义的对象,此函数返回NULL值。 + 返回由系统目录 OID、对象 OID 和子对象 ID 指定的数据库对象的ACL。对于未定义的对象,此函数返回NULL值。 @@ -2111,9 +2046,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); text - 返回由目录OID、对象OID和子对象ID(例如表中的列号)标识的数据库对象的文本描述;当引用整个对象时,子对象ID为0)。 - 这个描述是人类可读的,并且可以根据服务器配置进行翻译。这对于决定pg_depend目录中引用的对象的标识特别有用。 - 此函数对于未定义的对象返回NULL值 + 返回数据库对象的文本描述,对象由系统目录 OID、对象 OID 和子对象 ID 指定(例如表中的列号;引用整个对象时,子对象 ID 为零)。该描述供人阅读,并可能根据服务器配置被翻译。这对于确定pg_depend系统目录中所引用对象的标识尤其有用。对于未定义的对象,此函数返回NULL @@ -2130,13 +2063,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); identitytext ) - 返回包含足够信息的行以唯一标识由目录OID、对象OID和子对象ID指定的数据库对象。 - 这些信息是为了机器可读的,永远不会被翻译。 - type标识数据库对象的类型; - schema是对象所属的模式名,NULL表示不属于模式的对象类型; - name是对象的名称,如果有必要,用引号括起来,如果名称(随着模式名称,如果相关)足以唯一地标识对象,否则为NULL; - identity是完整的对象标识,其精确格式依赖于对象类型,格式中的每个名称都是模式限定的,并在必要时用引号括起来。 - 未定义的对象由NULL值标识。 + 返回一行,其中包含足以唯一标识数据库对象的信息,该对象由系统目录 OID、对象 OID 和子对象 ID 指定。这些信息供机器读取,永远不会被翻译。type标识数据库对象的类型;schema是对象所属的模式名,对于不属于模式的对象类型则为NULL;如果对象名(以及适用时的模式名)足以唯一标识该对象,name就是对象名,并在必要时加引号,否则为NULLidentity是完整的对象标识,其具体格式取决于对象类型,格式中的每个名称都会根据需要加上模式限定和引号。未定义的对象以NULL值标识。 @@ -2152,10 +2079,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); object_argstext[] ) - 返回包含足够信息的行以唯一标识由目录OID、对象OID和子对象ID指定的数据库对象。 - 返回的信息独立于当前服务器,也就是说,它可以用于标识另一个服务器中具有相同名称的对象。 - type标识数据库对象的类型;object_namesobject_args是文本数组,它们一起构成对对象的引用。 - 这三个值可以传递给pg_get_object_address以获得对象的内部地址。 + 返回一行,其中包含足以唯一标识数据库对象的信息,该对象由系统目录 OID、对象 OID 和子对象 ID 指定。返回的信息与当前服务器无关,也就是说,它也能用于标识另一台服务器上名称相同的对象。type标识数据库对象的类型;object_namesobject_args是文本数组,共同构成对该对象的引用。将这三个值传给pg_get_object_address可以获得对象的内部地址。 @@ -2171,12 +2095,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); objsubidinteger ) - 返回包含足够信息的行以唯一标识由类型代码、对象名称和参数数组指定的数据库对象。 - 返回的值将在系统目录中使用,例如pg_depend; - 它们可以传递给其他系统函数,比如 pg_describe_objectpg_identify_object。 - classid是包含该对象的系统目录的OID;objid是对象本身的OID, objsubid是子对象的ID,如果没有则为零。 - 这个函数是pg_identify_object_as_address的反向函数。 - 未定义的对象以NULL值标识。 + 返回一行,其中包含足以唯一标识数据库对象的信息,该对象由类型代码、对象名称数组和参数数组指定。返回的值就是pg_depend等系统目录中使用的值;它们可以传给pg_describe_objectpg_identify_object等其他系统函数。classid是包含该对象的系统目录的 OID;objid是对象自身的 OID;objsubid是子对象 ID,没有子对象时为零。此函数执行pg_identify_object_as_address的逆操作。未定义的对象以NULL值标识。 @@ -2219,7 +2138,7 @@ acl | {postgres=arwdDxtm/postgres,foo=r/postgres} - 中展示的函数抽取注释,注释是由命令在以前存储的。如果对指定参数找不到注释,则返回空值。 + 中的函数用于提取此前通过命令存储的注释。如果找不到与指定参数对应的注释,则返回空值。
@@ -2249,7 +2168,7 @@ acl | {postgres=arwdDxtm/postgres,foo=r/postgres} text - 返回表列的注释,该注释由该表的OID和列号指定。(obj_description不能用于表的列,因为列没有自己的oid。) + 返回表列的注释,列由所属表的 OID 和列号指定。(obj_description不能用于表列,因为列没有自身的 OID。) @@ -2262,8 +2181,7 @@ acl | {postgres=arwdDxtm/postgres,foo=r/postgres} text - 返回OID指定的数据库对象的注释和包含该对象的系统目录的名称。 - 例如,obj_description(123456, 'pg_class')将检索OID为123456的表的注释。 + 返回数据库对象的注释,对象由其 OID 和所在系统目录的名称指定。例如,obj_description(123456, 'pg_class')会获取 OID 为 123456 的表的注释。 @@ -2273,8 +2191,7 @@ acl | {postgres=arwdDxtm/postgres,foo=r/postgres} text - 返回仅由其OID指定的数据库对象的注释。 - 这个已被弃用(deprecated)因为无法保证oid在不同的系统目录中是唯一的;因此,可能会返回错误的注释。 + 返回仅由其 OID 指定的数据库对象的注释。此形式已弃用,因为无法保证 OID 在不同系统目录之间唯一,因而可能返回错误的注释。 @@ -2287,9 +2204,7 @@ acl | {postgres=arwdDxtm/postgres,foo=r/postgres} text - 返回共享数据库对象的注释,该对象由其OID和包含的系统编目的名称指定。 - 这与obj_description类似,只是它用于检索共享对象(也就是数据库、角色和表空间)上的注释。 - 有些系统编目对每个集簇中的所有数据库都是全局的,其中对象的描述也全局存储。 + 返回共享数据库对象的注释,对象由其 OID 和所在系统目录的名称指定。此函数与obj_description类似,但用于获取共享对象(即数据库、角色和表空间)的注释。有些系统目录由数据库集簇中的所有数据库全局共享,其中对象的描述也全局存储。 @@ -2425,6 +2340,32 @@ acl | {postgres=arwdDxtm/postgres,foo=r/postgres} + + + + age + + age ( xid ) + integer + + + 返回给定事务 ID 与当前事务计数器之间的事务数。 + + + + + + + mxid_age + + mxid_age ( xid ) + integer + + + 返回给定多事务 ID 与当前多事务计数器之间的多事务 ID 数。 + + + @@ -2434,7 +2375,7 @@ acl | {postgres=arwdDxtm/postgres,foo=r/postgres} xid8 - 返回当前事务的ID。如果当前事务还没有一个ID(因为它还没有执行任何数据库更新),它将分配一个新的事务。 + 返回当前事务的ID。如果当前事务还没有一个ID(因为它还没有执行任何数据库更新),它将分配一个新的事务 ID;详见。如果在子事务中执行,它将返回顶层事务的ID;详见 @@ -2447,8 +2388,7 @@ acl | {postgres=arwdDxtm/postgres,foo=r/postgres} xid8 - 返回当前事务的ID,如果还没有分配ID则返回NULL。 - (如果事务可能是只读的,最好使用这种变体,以避免不必要地消耗XID。) + 返回当前事务的 ID;如果尚未分配 ID,则返回NULL。(如果事务本来可能是只读的,最好使用此变体,以免不必要地消耗 XID。)如果在子事务中执行,则返回顶层事务 ID。 @@ -2461,10 +2401,7 @@ acl | {postgres=arwdDxtm/postgres,foo=r/postgres} text - 报告最近的事务的提交状态。如果事务为最近的,系统会保留事务的提交状态,则结果是 in progresscommittedaborted。 - 如果该事务的时间足够久,并且系统中没有对该事务的引用,而且提交状态信息已经被丢弃,则结果为NULL。 - 应用可以使用此函数,例如,确定在进行COMMIT时,应用程序和数据库服务器断开连接后,它们的事务是已提交还是中止。 - 注意,准备好的事务报告为in progress的事务;如果应用需要确定一个事务ID是否属于一个准备好的事务,则必须检查pg_prepared_xacts。 + 报告近期事务的提交状态。只要事务足够新,系统仍保留其提交状态,结果就为in progresscommittedaborted。如果事务已足够旧,系统中不再有对它的引用,且提交状态信息已被丢弃,则返回NULL。例如,在COMMIT进行过程中应用与数据库服务器断开连接时,应用可以用此函数判断事务是提交了还是中止了。注意,预备事务被报告为in progress;如果需要确定某个事务 ID 是否为预备事务,应用必须检查pg_prepared_xacts @@ -2477,7 +2414,7 @@ acl | {postgres=arwdDxtm/postgres,foo=r/postgres} pg_snapshot - 返回当前snapshot,显示哪些事务 ID正在进行中的数据结构。 + 返回当前快照,即显示哪些事务 ID 正在进行中的数据结构。快照中只包含顶层事务 ID,不显示子事务 ID;详见 @@ -2529,8 +2466,7 @@ acl | {postgres=arwdDxtm/postgres,foo=r/postgres} boolean - 根据此快照,给定的事务ID是否可见(visible)(也就是说,它是否在快照拍摄之前完成)? - 注意,这个函数不会给出子事务ID的正确答案。 + 根据此快照,给定的事务 ID 是否可见(即该事务是否在生成快照之前完成)?注意,此函数无法为子事务 ID(subxid)给出正确结果;详见 @@ -2578,7 +2514,7 @@ acl | {postgres=arwdDxtm/postgres,foo=r/postgres} 内部事务 ID 类型xid是 32 位宽,每 40 亿个事务就会回卷一次(wrap around)。 - 但是,中所示的函数中,除了agemxid_agepg_get_multixact_memberspg_get_multixact_stats之外,使用的是 64 位类型xid8,它在一次安装的生命周期内不会回卷,必要时可以通过强制转换将其转换为xid;详见。 + 但是,中所示的函数中,除了agemxid_agepg_get_multixact_memberspg_get_multixact_stats之外,使用的是 64 位类型xid8,它在一次安装的生命周期内不会回卷,必要时可以通过类型转换将其转换为xid;详见。 数据类型pg_snapshot存储特定时刻事务ID可见性的信息。 其组成如所描述。pg_snapshot的文本表示形式是xmin:xmax:xip_list。 例如10:20:10,14,15表示xmin=10, xmax=20, xip_list=10, 14, 15。 @@ -2601,21 +2537,22 @@ acl | {postgres=arwdDxtm/postgres,foo=r/postgres} xmin - 仍然处于活动状态的最低事务ID。所有小于xmin的事务 ID要么提交且可见,要么回滚并死亡。 + 仍然处于活动状态的最小事务 ID。所有小于xmin的事务 ID 要么已经提交且可见,要么已经回滚而失效。 xmax - 比最高完成的事务ID还高出一个值。所有大于或等于xmax的事务 ID到快照时还没有完成,因此不可见。 + 已完成事务中的最大事务 ID 加一。所有大于或等于xmax的事务 ID 在生成快照时尚未完成,因此不可见。 xip_list - 快照时正在进行的事务。一个事务ID为xmin <= X < xmax且不在快照时已经完成的列表中,因此根据其提交状态,该事务ID要么是可见的,要么是死的。此列表不包括子事务的事务 ID。 + 生成快照时正在进行的事务。满足xmin <= X < + xmax且不在此列表中的事务 ID 在生成快照时已经完成,因此根据其提交状态,要么可见,要么失效。此列表不包含子事务的事务 ID(subxid)。 @@ -2760,8 +2697,7 @@ acl | {postgres=arwdDxtm/postgres,foo=r/postgres} 已提交事务信息函数 - 中的函数提供了关于过去的事务何时被提交的信息。 - 它们只在启用配置选项时提供有用的数据,并且只针对在启用该选项后提交的事务。 + 中的函数提供过去事务的提交时间信息。只有启用配置选项后,这些函数才会提供有用的数据,并且只针对启用该选项之后提交的事务。提交时间戳信息会在 vacuum 过程中定期清理。
@@ -2806,7 +2742,7 @@ acl | {postgres=arwdDxtm/postgres,foo=r/postgres} roidentoid) - 返回事务的提交时间戳和复制起源。 + 返回事务的提交时间戳和复制源。 @@ -2822,7 +2758,7 @@ acl | {postgres=arwdDxtm/postgres,foo=r/postgres} roidentoid ) - 返回最近提交的事务的事务ID、提交时间戳和复制源头。 + 返回最近提交事务的事务 ID、提交时间戳和复制源。 @@ -2836,9 +2772,7 @@ acl | {postgres=arwdDxtm/postgres,foo=r/postgres} 控制数据函数 - 中所展示的函数能打印initdb期间初始化的信息,例如目录版本。 - 它们也能显示有关预写式日志和检查点处理的信息。这些信息是集簇范围内的,不与任何特定的一个数据库相关。 - 这些函数提供大致相同的信息,对于同一种来源,就像应用。 + 中的函数显示在initdb期间初始化的信息,例如系统目录版本。它们也显示有关预写式日志和检查点处理的信息。这些信息适用于整个数据库集簇,而非某个特定数据库。这些函数与应用程序从相同来源提供大部分相同的信息。
@@ -2868,7 +2802,7 @@ acl | {postgres=arwdDxtm/postgres,foo=r/postgres} record - 返回有关当前检查点状态的信息, 如 所展示。 + 返回有关当前检查点状态的信息, 如 所展示。 @@ -2907,7 +2841,7 @@ acl | {postgres=arwdDxtm/postgres,foo=r/postgres} record - 返回有关恢复状态的信息,如 所展示。 + 返回有关恢复状态的信息,如 所展示。 @@ -3211,6 +3145,8 @@ acl | {postgres=arwdDxtm/postgres,foo=r/postgres} + + @@ -3326,7 +3262,7 @@ acl | {postgres=arwdDxtm/postgres,foo=r/postgres} WAL 记录修改过。每一行中,如果is_limit_block 为 true,则表示以下两种情况之一:(a) 该关系分支在相关 WAL 记录范围内 被截断到relblocknumber给出的长度;或者 (b) 该关系分支在 - 相关 WAL 记录范围内被创建或删除;在这些情况下, + 相关 WAL 记录范围内被创建或删除;在创建或删除的情况下, relblocknumber将为零。 @@ -3379,7 +3315,7 @@ acl | {postgres=arwdDxtm/postgres,foo=r/postgres} 获取对象 DDL 函数 - 中显示的函数会重构各种全局数据库对象的 DDL 语句。每个函数返回一组文本行,每行一条 SQL 语句。(这是一个反编译重构,而不是命令的原始文本。) + 中显示的函数会重建各种全局数据库对象的 DDL 语句。每个函数返回一组文本行,每行一条 SQL 语句。(这是反编译重建的结果,并非命令的原始文本。)
@@ -3413,10 +3349,10 @@ acl | {postgres=arwdDxtm/postgres,foo=r/postgres} setof text - 重构指定数据库的CREATE + 重建指定数据库的CREATE DATABASE语句,随后返回用于连接数上限、模板状态和配置设置的 ALTER DATABASE语句。 - 每条语句作为单独一行返回。当pretty为 true 时,对输出进行美观打印。 + 每条语句作为单独一行返回。当pretty为 true 时,启用美化输出。 当owner为 false 时,省略OWNER子句。 当tablespace为 false 时,省略TABLESPACE子句。 @@ -3435,10 +3371,10 @@ acl | {postgres=arwdDxtm/postgres,foo=r/postgres} setof text - 重构给定角色的CREATE ROLE + 重建给定角色的CREATE ROLE 语句以及任何ALTER ROLE ... SET 语句。每条语句作为单独一行返回。密码信息绝不会包含在输出中。 - 当pretty为 true 时,对输出进行美观打印。 + 当pretty为 true 时,启用美化输出。 当memberships为 false 时,省略用于角色成员关系的 GRANT语句。 @@ -3466,10 +3402,10 @@ acl | {postgres=arwdDxtm/postgres,foo=r/postgres} setof text - 重构指定表空间(按 OID 或名称指定)的CREATE + 重建指定表空间(按 OID 或名称指定)的CREATE TABLESPACE语句。如果该表空间设置了选项,还会返回一条 ALTER TABLESPACE ... SET语句。 - 每条语句作为单独一行返回。当pretty为 true 时,对输出进行美观打印。 + 每条语句作为单独一行返回。当pretty为 true 时,启用美化输出。 当owner为 false 时,省略OWNER子句。 diff --git a/zh/19/func/func-json.sgml b/zh/19/func/func-json.sgml index 9c876be2..09a0489e 100644 --- a/zh/19/func/func-json.sgml +++ b/zh/19/func/func-json.sgml @@ -6,9 +6,13 @@ JSON函数和操作符 + + SQL/JSON + 函数和表达式 + - 本节描述: + 本节描述: @@ -18,12 +22,12 @@ - SQL/JSON路径语言 + SQL/JSON 路径语言 - SQL/JSON查询函数 + SQL/JSON 查询函数 @@ -31,13 +35,13 @@ 为了在 SQL 环境中为 JSON 数据类型提供原生支持,PostgreSQL 实现了 - SQL/JSON 数据模型。该模型由一系列项组成。每个项可以保存 SQL 标量值, - 以及额外的 SQL/JSON 空值,还可以保存使用 JSON 数组和对象的复合数据结构。该模型是 JSON 规范 - RFC 7159 中隐含数据模型的正式化。 + SQL/JSON 数据模型。该模型由项序列组成。每个项可以保存 SQL 标量值, + 以及额外的 SQL/JSON null 值,还可以保存使用 JSON 数组和对象的复合数据结构。该模型是 JSON 规范 + RFC 7159 中隐含数据模型的形式化表示。 - SQL/JSON 允许你在常规 SQL 数据旁边处理 JSON 数据,并提供事务支持,包括: + SQL/JSON 允许你将 JSON 数据与常规 SQL 数据一同处理,并提供事务支持,包括: @@ -69,16 +73,13 @@ 处理和创建 JSON 数据 - 显示了可用于 JSON 数据类型的操作符(参见 - )。 - 此外, 中列出的常规比较操作符也可用于 - jsonb,但不适用于 json。比较操作符遵循 - 中概述的 B-树操作排序规则。 - 另请参阅 ,了解聚合函数 json_agg - 如何将记录值聚合为 JSON,聚合函数 json_object_agg 如何将值对聚合为 - JSON 对象,以及它们对应的 jsonb 函数 jsonb_agg 和 - jsonb_object_agg。 - + 显示了可用于 JSON 数据类型的操作符(参见)。 + 此外,中给出的常规比较操作符也可用于jsonb,但不适用于json。 + 比较操作符遵循 B-树操作的排序规则,详见。 + 另请参阅,了解聚合函数json_agg如何将记录值聚合为 JSON, + 以及聚合函数json_object_agg如何将值对聚合为 JSON 对象,还有它们对应的jsonb函数, + jsonb_aggjsonb_object_agg。 +
@@ -219,14 +220,13 @@ - 如果JSON输入没有匹配请求的正确结构,字段/元素/路径提取操作符返回NULL,而不是失败;例如,如果不存在这样的键或数组元素。 + 如果 JSON 输入没有匹配请求的正确结构,字段/元素/路径提取操作符会返回 NULL,而不是失败;例如,如果不存在这样的键或数组元素。 - 还有一些操作符仅适用于jsonb,如表所示。 - 第描述了如何使用这些操作符来有效地搜索索引的jsonb数据。 - + 还有一些操作符仅适用于jsonb,如所示。介绍了如何使用这些操作符有效地搜索已建立索引的jsonb数据。 +
@@ -301,7 +301,7 @@ boolean - 文本数组中的字符串是否作为顶级键或数组元素存在? + 文本数组中的任一字符串是否作为顶级键或数组元素存在? '{"a":1, "b":2, "c":3}'::jsonb ?| array['b', 'd'] @@ -333,7 +333,7 @@ 连接两个数组将生成一个包含每个输入的所有元素的数组。 连接两个对象将生成一个包含它们键的并集的对象,当存在重复的键时取第二个对象的值。 所有其他情况都通过将非数组输入转换为单元素数组来处理,然后按照两个数组的方式进行处理。 - 不递归操作:只有顶级数组或对象结构被合并。 + 不递归操作:只有顶级数组或对象结构会被合并。 '["a", "b"]'::jsonb || '["a", "d"]'::jsonb @@ -352,7 +352,7 @@ [{"a": "b"}, 42] - 要将一个数组作为单个条目附加到另一个数组中,请将其包装在另一个数组附加层中,例如: + 要将一个数组作为单个元素追加到另一个数组中,请先在它外面再包装一层数组,例如: '[1, 2]'::jsonb || jsonb_build_array('[3, 4]'::jsonb) @@ -426,7 +426,7 @@ boolean - JSON路径是否为指定的JSON值返回任何项? + JSON 路径是否为指定的 JSON 值返回任何项?(这只适用于 SQL 标准 JSON 路径表达式,不适用于谓词检查表达式,因为后者总是返回一个值。) '{"a":[1,2,3,4,5]}'::jsonb @? '$.a[*] ? (@ > 2)' @@ -440,7 +440,7 @@ boolean - 返回指定JSON值的JSON路径谓词检查的结果。只考虑结果的第一项。如果结果不是布尔值,则返回NULL。 + 返回对指定 JSON 值进行 JSON 路径谓词检查的结果。(这只适用于谓词检查表达式,不适用于 SQL 标准 JSON 路径表达式,因为如果路径结果不是单个布尔值,就会返回NULL。) '{"a":[1,2,3,4,5]}'::jsonb @@ '$.a[*] > 2' @@ -454,15 +454,13 @@ - jsonpath操作符@?@@抑制以下错误:缺少对象字段或数组元素,意外的JSON项目类型,日期时间和数字错误。 - 还可以告诉以下描述的与jsonpath相关的函数来抑制这些类型的错误。 - 在搜索不同结构的JSON文档集合时,此行为可能会有所帮助。 + jsonpath操作符@?@@会抑制以下错误:缺少对象字段或数组元素、JSON 项类型不符合预期,以及日期时间和数值错误。下文介绍的jsonpath相关函数也可以设置为抑制这些类型的错误。在搜索结构各异的 JSON 文档集合时,这一行为可能很有用。 - 显示可用于构造jsonjsonb值的函数。 - + 列出了可用于构造jsonjsonb值的函数。表中的某些函数具有RETURNING子句,用于指定返回的数据类型。该类型必须是jsonjsonbbytea、字符串类型(textcharvarchar),或者可以转换为json的类型。默认返回json类型。 +
@@ -501,14 +499,14 @@ jsonb - 将任何SQL值转换为jsonjsonb。数组和组合递归地转换为数组和对象(多维数组在JSON中变成数组的数组)。 - 否则,如果存在从SQL数据类型到json的类型转换,则类型转换函数将用于执行转换; + 将任何SQL值转换为jsonjsonb。数组和复合值递归地转换为数组和对象(多维数组在JSON中变成数组的数组)。 + 否则,如果存在从SQL数据类型到json的类型转换,则类型转换函数将用于执行转换; - 例如,扩展有一个从hstorejson的转换,这样通过json创建函数转换的hstore值将被表示为json对象,而不是原始字符串值 + 例如,扩展有一个从hstorejson的类型转换,因此通过 JSON 创建函数转换的hstore值将表示为 JSON 对象,而不是基本的字符串值。 - 否则,将生成一个标量json值。对于除数字、布尔值或空值之外的任何标量,将使用文本表示,并根据需要进行转义,使其成为有效的JSON字符串值。 + 否则,将生成一个标量 JSON 值。对于除数字、布尔值或空值之外的任何标量,将使用文本表示,并根据需要进行转义,使其成为有效的JSON字符串值。 to_json('Fred said "Hi."'::text) @@ -516,7 +514,7 @@ to_jsonb(row(42, 'Fred said "Hi."'::text)) - {"f1":42,"f2":"Fred said \"Hi.\""} + {"f1": 42, "f2": "Fred said \"Hi.\""} @@ -539,9 +537,11 @@ json_array @@ -556,12 +556,8 @@ RETURNING data_type FORMAT JSON ENCODING UTF8 ) - 根据一系列 value_expression 参数或 - query_expression 的结果构造 JSON 数组;后者 必须是只返回一列的 SELECT 查询。 - 如果指定 ABSENT ON NULL,则忽略 NULL 值。 - 使用 query_expression时始终如此。如果查询未返回任何行, - 则返回空 JSON 数组。 - + 从一系列value_expression参数或query_expression的结果构造 JSON 数组;后者必须是返回单列的 SELECT 查询。如果指定了ABSENT ON NULL,则忽略 NULL 值。使用query_expression时始终如此。如果查询不返回任何行,则返回空 JSON 数组。 + json_array(1,true,json '{"a":null}') [1, true, {"a":null}] @@ -581,7 +577,7 @@ json - 将SQL组合值转换为JSON对象。该行为与to_json相同,只是如果可选boolean参数为真,换行符将在顶级元素之间添加。 + 将SQL 复合值转换为JSON对象。该行为与to_json相同,只是如果可选boolean参数为真,换行符将在顶级元素之间添加。 row_to_json(row(1,'foo')) @@ -630,7 +626,7 @@ 根据可变参数列表构建一个JSON对象。按照惯例,参数列表由交替的键和值组成。 - 关键参数强制转换为文本;值参数按照to_jsonto_jsonb进行转换。 + 键参数会被强制转换为文本;值参数则按照to_jsonto_jsonb进行转换。 json_build_object('foo', 1, 2, row(3,'bar')) @@ -649,16 +645,8 @@ RETURNING data_type FORMAT JSON ENCODING UTF8 ) - 构造由所有给定键/值对组成的 JSON 对象,或者在没有给出任何键/值对时构造空对象。 - key_expression 是定义 JSON 键的标量表达式,它会被转换为 - text 类型。它不能为 NULL,也不能属于具有到 - json 类型强制转换的类型。如果指定了 WITH UNIQUE KEYS, - 则 key_expression 不能重复。任何使 - value_expression 求值为 NULL 的键值对, - 如果指定了 ABSENT ON NULL,就会从输出中省略;如果指定了 - NULL ON NULL 或省略了该子句,则会把该键及其值 NULL - 包含在输出中。 - + 根据给定的所有键值对构造 JSON 对象;如果没有给出键值对,则构造空对象。key_expression是定义JSON键的标量表达式,会被转换为text类型。它不能为NULL,其类型也不能具有到json的类型转换。如果指定了WITH UNIQUE KEYS,则key_expression不能重复。如果指定了ABSENT ON NULL,则value_expression求值为NULL的键值对会从输出中省略;如果指定了NULL ON NULL或省略了该子句,则保留该键,并将其值设为NULL。 + json_object('code' VALUE 'P123', 'title': 'Jaws') {"code" : "P123", "title" : "Jaws"} @@ -681,8 +669,7 @@ jsonb - 从文本数组构建JSON对象。该数组必须有两个维度,一个维度的成员数为偶数,在这种情况下,它们被视为交替的键/值对; - 另一个维度的成员数为二维,每个内部数组恰好有两个元素,它们被视为键/值对。所有值都转换为JSON字符串。 + 从文本数组构造 JSON 对象。该数组必须是一维且包含偶数个成员,此时将成员按交替的键/值对处理;或者是二维数组,且每个内部数组恰好有两个元素,将这两个元素作为一个键/值对。所有值都转换为 JSON 字符串。 json_object('{a, 1, b, "def", c, 3.5}') @@ -703,7 +690,7 @@ jsonb - 这种形式的json_object从单独的文本数组中成对地获取键和值。否则,它与单参数形式相同。 + 这种形式的json_object从单独的文本数组中成对地获取键和值。除此之外,它与单参数形式相同。 json_object('{a,b}', '{1,2}') @@ -714,7 +701,7 @@ - json constructor + json 构造器 json ( expression FORMAT JSON ENCODING UTF8 @@ -722,11 +709,8 @@ json - 将按 UTF8 编码的 textbytea 字符串形式指定的给定表达式转换为 JSON - 值。如果 expression 为 NULL,则返回 SQL null 值。 - 如果指定了 WITH UNIQUE,则 expression - 不能包含任何重复的对象键。 - + 将给定的textbytea字符串表达式(采用 UTF8 编码)转换为 JSON 值。如果expression为 NULL,则返回SQL空值。如果指定了WITH UNIQUE,则expression不能包含重复的对象键。 + json('{"a":123, "b":[true,"foo"], "a":"bar"}') {"a":123, "b":[true,"foo"], "a":"bar"} @@ -740,9 +724,7 @@ json_scalar ( expression ) - 将给定的 SQL 标量值转换为 JSON 标量值。如果输入为 NULL,则返回 SQL null。 - 如果输入为数字或布尔值,则返回对应的 JSON 数字或布尔值。对于其他任何值, - 返回 JSON 字符串。 + 将给定的 SQL 标量值转换为 JSON 标量值。如果输入为 NULL,则返回SQL空值。如果输入是数字或布尔值,则返回相应的 JSON 数字或布尔值。对于其他值,则返回 JSON 字符串。 json_scalar(123.45) @@ -761,10 +743,7 @@ RETURNING data_type FORMAT JSON ENCODING UTF8 ) - 将 SQL/JSON 表达式转换为字符或二进制字符串。expression - 可以是任何 JSON 类型、任何字符字符串类型,或者是 UTF8 编码的 bytea。 - 在 RETURNING 中使用的返回类型可以是任何字符字符串类型或 bytea。 - 默认值是 text。 + 将 SQL/JSON 表达式转换为字符或二进制字符串。expression可以是任意 JSON 类型、任意字符串类型,或采用 UTF8 编码的bytea RETURNING中使用的返回类型可以是任意字符串类型或bytea,默认为text json_serialize('{ "a" : 1 } ' RETURNING bytea) @@ -776,8 +755,7 @@
- 详细说明了用于测试 JSON 的 SQL/JSON - 功能。 + 详细介绍了用于测试 JSON 的 SQL/JSON 功能。 @@ -1127,48 +1105,48 @@ array w/o UK? | t anyelement - 将顶级 JSON 对象展开为具有 base 参数复合类型的行。JSON 对象将被扫描,查找名称与输出行类型列名匹配的字段,并将其值插入到输出行的对应列中。 - (不对应任何输出列名的字段将被忽略。)在典型用法中,base 的值仅为 NULL,这意味着任何不匹配对象字段的输出列都会被填充为 null。 - 但是,如果base不为NULL,那么它包含的值将用于不匹配的列。 + 将顶级 JSON 对象展开为一个行,其复合类型与base参数相同。系统会扫描该 JSON 对象,查找名称与输出行类型列名匹配的字段,并将其值插入输出中的对应列。 + (不对应任何输出列名的字段会被忽略。)在典型用法中,base的值就是NULL,这意味着凡是不匹配对象字段的输出列都会被填充为空值。 + 但是,如果base不是NULL,那么其中包含的值将用于那些不匹配的列。 - 要将JSON值转换为输出列的SQL类型,需要按次序应用以下规则: + 要将 JSON 值转换为输出列的 SQL 类型,需要依次应用以下规则: - 在所有情况下,JSON空值都会转换为SQL空值。 + 在所有情况下,JSON 空值都会转换为 SQL 空值。 - 如果输出列的类型是jsonjsonb,则会精确地重制JSON值。 + 如果输出列的类型是jsonjsonb,则 JSON 值会被原样保留。 - 如果输出列是复合(行)类型,且JSON值是JSON对象,则该对象的字段将转换为输出行类型的列,通过这些规则的递归应用程序。 + 如果输出列是复合(行)类型,且 JSON 值是 JSON 对象,则该对象的字段会通过递归应用这些规则,被转换为输出行类型的各列。 - 同样,如果输出列是数组类型,而JSON值是JSON数组,则通过这些规则的递归应用程序将JSON数组的元素转换为输出数组的元素。 + 同样,如果输出列是数组类型,而 JSON 值是 JSON 数组,则会通过递归应用这些规则,把 JSON 数组的元素转换为输出数组的元素。 - 否则,如果JSON值是字符串,则将字符串的内容提供给输入转换函数,用以确定列的数据类型。 + 否则,如果 JSON 值是字符串,则会把该字符串的内容送入该列数据类型的输入转换函数。 - 否则,JSON值的普通文本表示将被提供给输入转换函数,以确定列的数据类型。 + 否则,JSON 值的普通文本表示会被送入该列数据类型的输入转换函数。 - 虽然下面的示例使用一个常量JSON值,典型的用法是在查询的FROM子句中从另一个表侧面地引用jsonjsonb列。 - 在FROM子句中编写json_populate_record是一种很好的实践,因为提取的所有列都可以使用,而不需要重复的函数调用。 + 虽然下面的示例使用的是常量 JSON 值,但典型用法是在查询的FROM子句中,以横向方式引用另一个表中的jsonjsonb列。 + 把json_populate_record写在FROM子句中是一种良好实践,因为这样抽取出的所有列都可以直接使用,而不需要重复调用函数。 CREATE TYPE subrowtype AS (d int, e text); @@ -1195,9 +1173,7 @@ array w/o UK? | t boolean - 用于测试jsonb_populate_record。如果对于给定的输入 JSON 对象, - jsonb_populate_record调用能够无错误完成,即输入有效,则返回 - true;否则返回false。 + 用于测试jsonb_populate_record的函数。对于给定的输入 JSON 对象,如果jsonb_populate_record能够无错误地完成,即该输入有效,则返回true;否则返回false CREATE TYPE jsb_char2 AS (a char(2)); @@ -1253,8 +1229,7 @@ ERROR: value too long for type character(2) setof anyelement - 将对象的顶级 JSON 数组展开为一组具有 base 参数复合类型的行。 - 对于json[b]_populate_record,将如上所述处理JSON数组的每个元素。 + 将由对象组成的顶级 JSON 数组展开为一组行,其复合类型与base参数相同。JSON 数组中的每个元素都按照上文对json[b]_populate_record的说明进行处理。 CREATE TYPE twoints AS (a int, b int); @@ -1323,8 +1298,8 @@ ERROR: value too long for type character(2) 将顶级JSON对象数组展开为一组由AS子句定义的复合类型的行。 - (与所有返回record的函数一样,调用查询必须使用AS子句显式定义记录的结构。) - 对于json[b]_populate_record,将如上所述处理JSON数组的每个元素。 + (与所有返回record的函数一样,调用查询必须使用AS子句显式定义记录的结构。) + JSON 数组中的每个元素都按照上文对json[b]_populate_record的说明进行处理。 SELECT * FROM json_to_recordset('[{"a":1,"b":"foo"}, {"a":"2","c":"bar"}]') AS x(a int, b text) @@ -1350,7 +1325,7 @@ ERROR: value too long for type character(2) 返回target,将path指定的项替换为new_value, 如果create_if_missing为真(此为默认值)并且path指定的项不存在,则添加new_value。 路径中的所有前面步骤都必须存在,否则将不加改变地返回target。 - 与面向路径操作符一样,负整数出现在JSON数组末尾的path计数中。 + 与面向路径的操作符一样,path中的负整数从 JSON 数组末尾计数。 如果最后一个路径步骤是超出范围的数组索引,并且create_if_missing为真,那么如果索引为负,新值将添加到数组的开头,如果索引为正,则添加到数组的结尾。 @@ -1397,8 +1372,8 @@ ERROR: value too long for type character(2) 如果path指派的项是一个数组元素,如果 insert_after为假(此为默认值),则new_value将被插入到该项之前,如果 insert_after为真则在该项之后。 如果由path指派的项是一个对象字段,则只在对象不包含该键时才插入 new_value。 路径中的所有前面步骤都必须存在,否则将不加改变地返回target。 - 与面向路径操作符一样,负整数出现在JSON数组末尾的 path计数中。 - 如果最后一个路径步骤是超出范围的数组下标,则如果下标为负,则将新值添加到数组的开头;如果下标为正,则将新值添加到数组的结尾。 + 与面向路径的操作符一样,path中的负整数从 JSON 数组末尾计数。 + 如果最后一个路径步骤是超出范围的数组下标,那么当下标为负时,新值会被添加到数组开头;当下标为正时,新值会被添加到数组末尾。 jsonb_insert('{"a": [0,1,2]}', '{a, 1}', '"new_value"') @@ -1447,7 +1422,7 @@ ERROR: value too long for type character(2) boolean - 检查 JSON 路径是否为指定的 JSON 值返回任何项。(这只对 SQL 标准 JSON 路径表达式有用,而不适用于布尔谓词检查表达式,因为后者总是返回一个值。)如果指定了vars参数,则它必须是一个 JSON 对象,并且它的字段提供要替换到jsonpath表达式中的具名值。 + 检查 JSON 路径是否为指定的 JSON 值返回任何项。(这只对 SQL 标准 JSON 路径表达式有用,而不适用于谓词检查表达式,因为后者总是返回一个值。)如果指定了vars参数,则它必须是一个 JSON 对象,并且它的字段提供要替换到jsonpath表达式中的具名值。 如果指定了silent参数并为true,函数会抑制与@?@@操作符相同的错误。 @@ -1465,7 +1440,7 @@ ERROR: value too long for type character(2) boolean - 返回指定 JSON 值的 JSON 路径谓词检查的 SQL 布尔结果。(这只对布尔谓词检查表达式有用,而不适用于 SQL 标准 JSON 路径表达式,因为如果路径结果不是单个布尔值,它就会失败或返回NULL。)可选的varssilent参数的作用与jsonb_path_exists相同。 + 返回指定 JSON 值的 JSON 路径谓词检查的 SQL 布尔结果。(这只对谓词检查表达式有用,而不适用于 SQL 标准 JSON 路径表达式,因为如果路径结果不是单个布尔值,它将失败或返回NULL。)可选的varssilent参数的作用与jsonb_path_exists相同。 jsonb_path_match('{"a":[1,2,3,4,5]}', 'exists($.a[*] ? (@ >= $min && @ <= $max))', '{"min":2, "max":4}') @@ -1482,7 +1457,7 @@ ERROR: value too long for type character(2) setof jsonb - 为指定的 JSON 值返回由 JSON 路径返回的所有 JSON 项。对于 SQL 标准 JSON 路径表达式,它返回从target中选出的 JSON 值。对于布尔谓词检查表达式,它返回谓词检查的结果:truefalsenull。可选的varssilent参数的作用与jsonb_path_exists相同。 + 为指定的 JSON 值返回由 JSON 路径返回的所有 JSON 项。对于 SQL 标准 JSON 路径表达式,它返回从target中选出的 JSON 值。对于谓词检查表达式,它返回谓词检查的结果:truefalsenull。可选的varssilent参数的作用与jsonb_path_exists相同。 SELECT * FROM jsonb_path_query('{"a":[1,2,3,4,5]}', '$.a[*] ? (@ >= $min && @ <= $max)', '{"min":2, "max":4}') @@ -1506,7 +1481,7 @@ ERROR: value too long for type character(2) jsonb - 以JSON数组的形式返回由JSON路径为指定的JSON值返回的所有JSON项。可选的varssilent参数的作用与jsonb_path_exists相同。 + 以JSON数组的形式返回由JSON路径为指定的JSON值返回的所有JSON项。参数与jsonb_path_query相同。 jsonb_path_query_array('{"a":[1,2,3,4,5]}', '$.a[*] ? (@ >= $min && @ <= $max)', '{"min":2, "max":4}') @@ -1524,7 +1499,7 @@ ERROR: value too long for type character(2) 为指定的JSON值返回由JSON路径返回的第一个JSON项。如果没有结果则返回NULL。 - 可选的varssilent参数的作用与 jsonb_path_exists相同。 + 参数与jsonb_path_query相同。 jsonb_path_query_first('{"a":[1,2,3,4,5]}', '$.a[*] ? (@ >= $min && @ <= $max)', '{"min":2, "max":4}') @@ -1588,7 +1563,7 @@ ERROR: value too long for type character(2) text - 将给定的JSON值转换为精美打印的,缩进的文本。 + 将给定的 JSON 值转换为经过美化并带有缩进的文本。 jsonb_pretty('[{"f1":1,"f2":null}, 2]') @@ -1621,8 +1596,8 @@ ERROR: value too long for type character(2) text - 以文本字符串形式返回顶级JSON值的类型。可能的类型有object, array,string, number,boolean, 和 null。 - (null的结果不应该与SQL NULL 混淆;参见示例。) + 以文本字符串形式返回顶级JSON值的类型。可能的类型有objectarraystringnumberbooleannull。 + (null 的结果不应与 SQL NULL 混淆;参见示例。) json_typeof('-123.4') @@ -1651,14 +1626,15 @@ ERROR: value too long for type character(2) - SQL/JSON路径表达式指定了要从JSON数据中检索的项目,类似于SQL访问XML时使用的XPath表达式。 + SQL/JSON路径表达式指定了要从JSON数据中检索的项,类似于访问 XML 内容时使用的 XPath 表达式。 在PostgreSQL中,路径表达式作为jsonpath数据类型实现,可以使用中描述的任何元素。 JSON 查询函数和操作符会将给定的路径表达式传递给路径引擎进行求值。 如果表达式与被查询的JSON数据匹配,则返回相应的JSON项或项集。 - 路径表达式是用SQL/JSON路径语言编写的,也可以包括算术表达式和函数。 + 如果没有匹配项,则根据所用函数返回NULLfalse或抛出错误。 + 路径表达式是用SQL/JSON路径语言编写的,也可以包括算术表达式和函数。 @@ -1667,15 +1643,13 @@ ERROR: value too long for type character(2) - 要引用正在查询的JSON值(context item项),在路径表达式中使用$变量。 - 它后面可以跟着一个或多个accessor operators,这些操作符在JSON结构中逐级向下检索上下文项的子项。 - 后面的每个操作符处理前一个求值步骤的结果。 - + 要引用正在查询的 JSON 值(上下文项),请在路径表达式中使用$变量。路径的第一个元素必须始终是$。它后面可以跟一个或多个访问操作符,沿 JSON 结构逐层向下获取上下文项的子项。每个访问操作符都处理上一步求值的结果,为每个输入项产生零个、一个或多个输出项。 + - 例如,假设你有一些你想要解析的来自GPS跟踪器的JSON数据,例如: + 例如,假设你有一些来自 GPS 跟踪器、想要解析的 JSON 数据,如下所示: -{ +SELECT '{ "track": { "segments": [ { @@ -1690,12 +1664,13 @@ ERROR: value too long for type character(2) } ] } -} +}' AS json \gset - + (可以将上述示例复制粘贴到psql中,为后续示例做好准备。此后,psql会将:'json'展开为一个包含该 JSON 值、且已正确加上引号的字符串常量。) + - 为了检索可用的轨迹段,你需要使用.key访问操作符来向下浏览周边的JSON对象: + 要获取可用的轨迹段,需要使用.key访问操作符,逐层访问外围的 JSON 对象: => SELECT jsonb_path_query(:'json', '$.track.segments'); jsonb_path_query @@ -1705,7 +1680,7 @@ ERROR: value too long for type character(2) - 要检索数组的内容,通常使用[*]操作符。例如,下面的路径将返回所有可用轨迹段的位置坐标: + 要检索数组的内容,通常使用[*]操作符。例如,下面的路径将返回所有可用轨迹段的位置坐标: => SELECT jsonb_path_query(:'json', '$.track.segments[*].location'); jsonb_path_query @@ -1728,7 +1703,7 @@ ERROR: value too long for type character(2) 每个路径求值步骤的结果可以由中列出的一个或多个jsonpath操作符和方法来处理。 - 每个方法名之前必须有一个点。例如,你可以得到一个数组的大小: + 每个方法名之前必须有一个点。例如,你可以得到一个数组的大小: => SELECT jsonb_path_query(:'json', '$.track.segments.size()'); jsonb_path_query @@ -1739,19 +1714,17 @@ ERROR: value too long for type character(2) - 在定义路径时,还可以使用一个或多个与SQL中的WHERE子句类似的filter expressions。 - 过滤器表达式以问号开头,并在圆括号中提供条件: - - + 路径还可以包含过滤表达式,其作用类似于 SQL 中的WHERE子句。过滤表达式以问号开头,并在圆括号中提供条件: + ? (condition) - - + + - 过滤表达式必须在它们应该应用的路径求值步骤之后写入。该步骤的结果将被筛选,以只包括满足所提供条件的那些项。 + 过滤表达式必须在它们应该应用的路径求值步骤之后指定。该步骤的结果会经过过滤,只保留满足给定条件的项。 SQL/JSON定义了三值逻辑,因此条件可以是 true, false,或 unknownunknown值发挥与SQL NULL相同的角色,可以使用IS UNKNOWN谓词进行测试。 - 进一步的路径求值步骤只使用筛选器表达式返回true的那些项。 + 进一步的路径求值步骤只使用过滤表达式返回true的那些项。 @@ -1760,7 +1733,7 @@ ERROR: value too long for type character(2) - 例如,假设你想要检索所有高于130的心率值。你可以使用下面的表达式来实现这一点: + 例如,假设你想要检索所有高于130的心率值。你可以使用下面的表达式来实现这一点: => SELECT jsonb_path_query(:'json', '$.track.segments[*].HR ? (@ > 130)'); jsonb_path_query @@ -1770,7 +1743,7 @@ ERROR: value too long for type character(2) - 为了获得具有这些值的片段的开始时间,必须在返回开始时间之前过滤掉不相关的片段,所以过滤表达式应用于上一步,条件中使用的路径不同: + 为了获得具有这些值的轨迹段的开始时间,必须先过滤掉不相关的轨迹段,再返回开始时间。因此,过滤表达式应用于上一步,条件中使用的路径也不同: => SELECT jsonb_path_query(:'json', '$.track.segments[*] ? (@.HR > 130)."start time"'); jsonb_path_query @@ -1780,7 +1753,7 @@ ERROR: value too long for type character(2) - 如果需要,可以按顺序使用几个过滤器表达式。例如,下面的表达式选择所有包含有相关坐标和高心率值的位置的段的开始时间: + 如有需要,可以依次使用多个过滤表达式。例如,下面的表达式选择位置坐标符合要求且心率较高的所有轨迹段的开始时间: => SELECT jsonb_path_query(:'json', '$.track.segments[*] ? (@.location[1] < 13.4) ? (@.HR > 130)."start time"'); jsonb_path_query @@ -1790,7 +1763,7 @@ ERROR: value too long for type character(2) - 也允许在不同嵌套层级中使用过滤器表达式。下面的示例首先根据位置筛选所有的片段,然后返回这些片段的高心率值,如果适用的话: + 也可以在不同嵌套层级使用过滤表达式。下面的示例先按位置筛选所有轨迹段,再返回这些轨迹段中的高心率值(如果存在): => SELECT jsonb_path_query(:'json', '$.track.segments[*] ? (@.location[1] < 13.4).HR ? (@ > 130)'); jsonb_path_query @@ -1800,15 +1773,14 @@ ERROR: value too long for type character(2) - 你也可以在彼此之间嵌套过滤器表达式: + 还可以将过滤表达式相互嵌套。如果轨迹包含任何具有高心率值的轨迹段,下面的示例返回轨迹的大小,否则返回空序列: => SELECT jsonb_path_query(:'json', '$.track ? (exists(@.segments[*] ? (@.HR > 130))).segments.size()'); jsonb_path_query ------------------ 2 - 如果包含任何具有高心率值的片段,则该表达式返回轨迹的大小,否则返回空序列。 - + 与 SQL 标准的偏差 @@ -1857,46 +1829,41 @@ ERROR: value too long for type character(2) 当查询JSON数据时,路径表达式可能与实际的JSON数据结构不匹配。 - 试图访问不存在的对象成员或数组元素会导致结构错误。SQL/JSON路径表达式有两种处理结构错误的模式: + 试图访问不存在的对象成员或数组元素会导致结构错误。SQL/JSON路径表达式有两种处理结构错误的模式: - 不严格的(lax)(默认)—路径引擎隐式地将查询的数据适配到指定的路径。任何剩余的结构错误都将被抑制并转换为空SQL/JSON序列。 - + 宽松模式(lax,默认)—路径引擎隐式地将被查询的数据适配到指定路径。凡是无法按下文所述方式修复的结构错误都会被抑制,产生的结果是不匹配。 + - - 严格的(strict) —如果发生了结构错误,则会引发错误。 - + 严格模式(strict)— 如果发生结构错误,就会引发错误。 - 如果JSON数据不符合期望的模式,不严格的(lax)模式有助于匹配JSON文档结构和路径表达式。 - 如果操作不匹配特定操作的要求,可以自动将其包装为SQL/JSON数组,也可以在执行该操作之前将其元素转换为SQL/JSON序列来解包装。 - 此外,比较操作符会自动以lax模式打开它们的操作数,因此你可以开包即用的就能比较SQL/JSON数组。 - 大小为1的数组被认为等于它的唯一元素。只有在以下情况下才不会自动展开: + 如果 JSON 数据不符合预期模式,宽松模式有助于使 JSON 文档结构与路径表达式相匹配。如果操作数不满足某个操作的要求,可以在执行该操作之前自动将其包装为 SQL/JSON 数组,或通过将其元素转换为 SQL/JSON 序列来解包。此外,在宽松模式下,比较操作符会自动解包其操作数,因此可以直接比较 SQL/JSON 数组。大小为 1 的数组被视为等于其唯一元素。以下情况不会自动解包: - 路径表达式包含type()size()方法,它们分别返回数组中的元素类型和数量。 + 路径表达式包含type()size()方法,它们分别返回类型和数组中的元素数量。 - 查询的JSON数据包含嵌套的数组。在本例中,只有最外层的数组被打开,而所有内部数组保持不变。 - 因此,隐式展开在每个路径求值步骤中只能向下进行一级。 + 查询的JSON数据包含嵌套的数组。在本例中,只有最外层的数组被解包,而所有内部数组保持不变。 + 因此,隐式解包在每个路径求值步骤中只能向下进行一级。 - 例如,查询上面列出的GPS数据时,使用不严格的(lax)模式就无需关注片段存储在数组中这一细节: + 例如,查询上面列出的GPS数据时,使用宽松模式就无需关注轨迹段存储在数组中这一细节: => SELECT jsonb_path_query(:'json', 'lax $.track.segments.location'); jsonb_path_query @@ -1907,11 +1874,12 @@ ERROR: value too long for type character(2) - 在严格的(strict)模式中,指定的路径必须与查询的JSON文档的结构完全匹配才能返回SQL/JSON项,因此使用该路径表达式会导致错误。 - + 在严格模式下,指定的路径必须与查询的JSON文档的结构完全匹配,因此使用该路径表达式会导致错误。 + => SELECT jsonb_path_query(:'json', 'strict $.track.segments.location'); ERROR: jsonpath member accessor can only be applied to an object -要得到与不严格的(lax)模式相同的结果,你必须显式地打开segments数组: + + 要得到与宽松模式相同的结果,你必须显式地解包segments数组: => SELECT jsonb_path_query(:'json', 'strict $.track.segments[*].location'); jsonb_path_query @@ -1922,8 +1890,8 @@ ERROR: jsonpath member accessor can only be applied to an object - .**访问器在使用lax模式时可能导致令人惊讶的结果。 - 例如,下面的查询选择每个HR值两次: + .**访问器在宽松模式下可能产生意外结果。 + 例如,下面的查询选择每个HR值两次: => SELECT jsonb_path_query(:'json', 'lax $.**.HR'); jsonb_path_query @@ -1933,10 +1901,10 @@ ERROR: jsonpath member accessor can only be applied to an object 73 135 - 发生这个,是因为.**访问器会全部选择segments数组和它的每个元素。 - 而当使用lax模式时,.HR访问器会自动打开数组。 + 这是因为.**访问器既选择segments数组,又选择它的每个元素。 + 而在宽松模式下,.HR访问器会自动解包数组。 为了避免意外的结果,我们建议仅在严格模式下使用.**访问器。 - 下面的查询选择每个HR值仅一次: + 下面的查询选择每个HR值仅一次: => SELECT jsonb_path_query(:'json', 'strict $.**.HR'); jsonb_path_query @@ -1947,7 +1915,7 @@ ERROR: jsonpath member accessor can only be applied to an object - 数组的自动展开也可能产生意外结果。下面的示例选择所有 location 数组: + 数组解包也可能产生意外结果。请看下面这个选取所有location数组的示例: => SELECT jsonb_path_query(:'json', 'lax $.track.segments[*].location'); jsonb_path_query @@ -1956,7 +1924,7 @@ ERROR: jsonpath member accessor can only be applied to an object [47.706, 13.2635] (2 rows) - 结果如预期一样返回完整数组。但应用过滤表达式会使数组自动展开,以便逐项求值,只返回与表达式匹配的项: + 它会如预期那样返回完整数组。但应用过滤表达式时,数组会被解包,以便对每个元素求值,最终只返回匹配该表达式的元素: => SELECT jsonb_path_query(:'json', 'lax $.track.segments[*].location ?(@[*] > 15)'); jsonb_path_query @@ -1965,7 +1933,7 @@ ERROR: jsonpath member accessor can only be applied to an object 47.706 (2 rows) - 尽管路径表达式选择的是完整数组,结果仍然如此。使用严格模式可以重新得到完整数组: + 尽管路径表达式选取的是完整数组,结果仍然如此。使用严格模式可以恢复选取数组的行为: => SELECT jsonb_path_query(:'json', 'strict $.track.segments[*].location ?(@[*] > 15)'); jsonb_path_query @@ -1983,8 +1951,7 @@ ERROR: jsonpath member accessor can only be applied to an object SQL/JSON 路径操作符和方法 - 显示了jsonpath中可用的操作符和方法。 - 请注意,虽然一元操作符和方法可以应用于由前一个路径步骤产生的多个值,二元操作符(加法等)只能应用于单个值。 + 列出了jsonpath中可用的操作符和方法。请注意,一元操作符和方法可以应用于前一个路径步骤产生的多个值,而二元操作符(加法等)只能应用于单个值。在宽松模式下,对数组应用方法时,会对数组中的每个值执行该方法。例外是.type().size(),它们作用于数组本身。
@@ -2056,7 +2023,7 @@ ERROR: jsonpath member accessor can only be applied to an object number - 否定;与减法不同,它可以迭代多个值 + 取负;与减法不同,可以遍历多个值。 jsonb_path_query_array('{"x": [2,3,4]}', '- $.x') @@ -2098,7 +2065,7 @@ ERROR: jsonpath member accessor can only be applied to an object number - 模数 (余数) + 取模(余数) jsonb_path_query('[32]', '$[0] % 10') @@ -2134,6 +2101,38 @@ ERROR: jsonpath member accessor can only be applied to an object + + + value . boolean() + boolean + + + 将 JSON 布尔值、数字或字符串转换为布尔值。 + + + jsonb_path_query_array('[1, "yes", false]', '$[*].boolean()') + [true, true, false] + + + + + + value . string() + string + + + 将 JSON 布尔值、数字、字符串或日期时间转换为字符串值。 + + + jsonb_path_query_array('[1.23, "xyz", false]', '$[*].string()') + ["1.23", "xyz", "false"] + + + jsonb_path_query('"2023-08-15 12:34:56"', '$.timestamp().string()') + "2023-08-15T12:34:56" + + + value . double() @@ -2190,11 +2189,67 @@ ERROR: jsonpath member accessor can only be applied to an object + + + value . bigint() + bigint + + + 将 JSON 数字或字符串转换为大整数值。 + + + jsonb_path_query('{"len": "9876543219"}', '$.len.bigint()') + 9876543219 + + + + + + value . decimal( [ precision [ , scale ] ] ) + decimal + + + 将 JSON 数字或字符串转换为经过舍入的十进制数值(precisionscale必须为整数值)。 + + + jsonb_path_query('1234.5678', '$.decimal(6, 2)') + 1234.57 + + + + + + value . integer() + integer + + + 将 JSON 数字或字符串转换为整数值。 + + + jsonb_path_query('{"len": "12345"}', '$.len.integer()') + 12345 + + + + + + value . number() + numeric + + + 将 JSON 数字或字符串转换为数值。 + + + jsonb_path_query('{"len": "123.45"}', '$.len.number()') + 123.45 + + + string . datetime() datetime_type - (see note) + (见注) 从字符串转换过来的日期/时间值 @@ -2209,7 +2264,7 @@ ERROR: jsonpath member accessor can only be applied to an object string . datetime(template) datetime_type - (see note) + (见注) 使用指定的to_timestamp模板从字符串转换过来的日期/时间值 @@ -2220,6 +2275,146 @@ ERROR: jsonpath member accessor can only be applied to an object + + + string . date() + date + + + 将字符串转换为日期值。 + + + jsonb_path_query('"2023-08-15"', '$.date()') + "2023-08-15" + + + + + + string . time() + time without time zone + + + 将字符串转换为不带时区的时间值。 + + + jsonb_path_query('"12:34:56"', '$.time()') + "12:34:56" + + + + + + string . time(precision) + time without time zone + + + 将字符串转换为不带时区的时间值,并将秒的小数部分调整到给定精度。 + + + jsonb_path_query('"12:34:56.789"', '$.time(2)') + "12:34:56.79" + + + + + + string . time_tz() + time with time zone + + + 将字符串转换为带时区的时间值。 + + + jsonb_path_query('"12:34:56 +05:30"', '$.time_tz()') + "12:34:56+05:30" + + + + + + string . time_tz(precision) + time with time zone + + + 将字符串转换为带时区的时间值,并将秒的小数部分调整到给定精度。 + + + jsonb_path_query('"12:34:56.789 +05:30"', '$.time_tz(2)') + "12:34:56.79+05:30" + + + + + + string . timestamp() + timestamp without time zone + + + 将字符串转换为不带时区的时间戳值。 + + + jsonb_path_query('"2023-08-15 12:34:56"', '$.timestamp()') + "2023-08-15T12:34:56" + + + + + + string . timestamp(precision) + timestamp without time zone + + + 将字符串转换为不带时区的时间戳值,并将秒的小数部分调整到给定精度。 + + + jsonb_path_query('"2023-08-15 12:34:56.789"', '$.timestamp(2)') + "2023-08-15T12:34:56.79" + + + + + + string . timestamp_tz() + timestamp with time zone + + + 将字符串转换为带时区的时间戳值。 + + + jsonb_path_query('"2023-08-15 12:34:56 +05:30"', '$.timestamp_tz()') + "2023-08-15T12:34:56+05:30" + + + + + + string . timestamp_tz(precision) + timestamp with time zone + + + 将字符串转换为带时区的时间戳值,并将秒的小数部分调整到给定精度。 + + + jsonb_path_query('"2023-08-15 12:34:56.789 +05:30"', '$.timestamp_tz(2)') + "2023-08-15T12:34:56.79+05:30" + + + + + + object . keyvalue() + array + + + 对象的键值对,表示为包含三个字段的对象数组:"key""value",和"id";"id"是键值对所归属对象的唯一标识符 + + + jsonb_path_query_array('{"x": "20", "y": 32}', '$.keyvalue()') + [{"id": 0, "key": "x", "value": "20"}, {"id": 0, "key": "y", "value": 32}] + + + string . lower() @@ -2347,20 +2542,6 @@ ERROR: jsonpath member accessor can only be applied to an object "trim" - - - - object . keyvalue() - array - - - 对象的键值对,表示为包含三个字段的对象数组:"key""value",和"id";"id"是键值对所归属对象的唯一标识符 - - - jsonb_path_query_array('{"x": "20", "y": 32}', '$.keyvalue()') - [{"id": 0, "key": "x", "value": "20"}, {"id": 0, "key": "y", "value": 32}] - -
@@ -2374,7 +2555,7 @@ ERROR: jsonpath member accessor can only be applied to an object datetime()方法依次尝试将其输入字符串与date, timetz, time,timestamptz, 和 timestamp的ISO格式进行匹配。 - 它在第一个匹配格式时停止,并发出相应的数据类型。 + 它在第一个匹配格式时停止,并返回相应数据类型的值。 @@ -2382,26 +2563,26 @@ ERROR: jsonpath member accessor can only be applied to an object - datetime()datetime(template)方法使用与to_timestamp SQL函数相同的解析规则(see ),但有三个例外。 + datetime()datetime(template)方法使用与to_timestamp SQL函数相同的解析规则(参见),但有三个例外。 首先,这些方法不允许不匹配的模板模式。 - 其次,模板字符串中只允许以下分隔符:减号、句点、solidus(斜杠)、逗号、撇号、分号、冒号和空格。 + 其次,模板字符串中只允许以下分隔符:减号、句点、斜杠、逗号、撇号、分号、冒号和空格。 第三,模板字符串中的分隔符必须与输入字符串完全匹配。 - 如果需要比较不同的日期/时间类型,则应用隐式转换。 + 如果需要比较不同的日期/时间类型,则应用隐式类型转换。 date值可以转换为timestamptimestamptz, timestamp可以转换为timestamptz, time可以转换为timetz。 - 但是,除了第一个转换外,其他所有转换都依赖于当前设置,因此只能在时区感知的jsonpath函数中执行。 + 但是,除了第一个转换外,其他所有转换都依赖于当前设置,因此只能在时区感知的jsonpath函数中执行。类似地,其他将字符串转换为日期/时间类型的日期/时间相关方法也会进行这种转换,这可能涉及当前的设置。因此,这些转换同样只能在时区感知的jsonpath函数中执行。 - 显示了适用的过滤器表达式元素。 + 显示了可用的过滤表达式元素。 - <type>jsonpath</type> 过滤器表达式元素 + <type>jsonpath</type> 过滤表达式元素 @@ -2550,7 +2731,7 @@ ERROR: jsonpath member accessor can only be applied to an object value - JSON常数null(注意,与SQL不同,与null比较可以正常工作) + JSON 常量null(注意,与SQL不同,与null比较可以正常工作) jsonb_path_query('[{"name": "Mary", "job": null}, {"name": "Michael", "job": "driver"}]', '$[*] ? (@.job == null) .name') @@ -2620,7 +2801,7 @@ ERROR: jsonpath member accessor can only be applied to an object boolean - 测试第一个操作数是否与第二个操作数给出的正则表达式匹配,可选使用由一串flag字符描述的修改(参见)。 + 测试第一个操作数是否与第二个操作数给出的正则表达式匹配;可以用一串flag标志字符调整匹配行为(参见)。 jsonb_path_query_array('["abc", "abd", "aBdC", "abdacb", "babc"]', '$[*] ? (@ like_regex "^ab.*c")') @@ -2676,31 +2857,28 @@ ERROR: jsonpath member accessor can only be applied to an object LIKE_REGEX - in SQL/JSON + 用于 SQL/JSON - - SQL/JSON路径表达式允许通过like_regex过滤器将文本匹配为正则表达式。 - 例如,下面的SQL/JSON路径查询将不区分大小写地匹配以英语元音开头的数组中的所有字符串: - + SQL/JSON 路径表达式允许使用like_regex过滤器,将文本与正则表达式进行匹配。例如,以下 SQL/JSON 路径查询会以不区分大小写的方式,匹配数组中所有以英语元音字母开头的字符串: $[*] ? (@ like_regex "^[aeiou]" flag "i") - 可选的flag字符串可以包括一个或多个字符i用于不区分大小写的匹配,m允许^$在换行时匹配,s允许.匹配换行符,q引用整个模式(将行为简化为一个简单的子字符串匹配)。 + 可选的flag字符串可以包括一个或多个字符i用于不区分大小写的匹配,m允许^$在换行时匹配,s允许.匹配换行符,q将整个模式按字面量处理(将行为简化为一个简单的子字符串匹配)。 SQL/JSON标准借用了来自LIKE_REGEX操作符的正则表达式定义,其使用了XQuery标准。 PostgreSQL目前不支持LIKE_REGEX操作符。因此,like_regex过滤器是使用中描述的POSIX正则表达式引擎来实现的。 - 这导致了与标准SQL/JSON行为的各种细微差异,这在中进行了分类。 - 但是请注意,这里描述的标志字母不兼容并不适用于SQL/JSON,因为它将XQuery标志字母翻译为符合POSIX引擎的预期。 + 这导致了与标准SQL/JSON行为的各种细微差异,这些差异列在中。 + 但是请注意,这里描述的标志字母不兼容并不适用于SQL/JSON,因为 SQL/JSON 会将 XQuery 标志字母转换为 POSIX 引擎所预期的形式。 - 请记住,like_regex的模式参数是一个JSON路径字符串文字,根据给出的规则编写。 - 这特别意味着在正则表达式中要使用的任何反斜杠都必须加倍。例如,匹配只包含数字的根文档的字符串值: + 请记住,like_regex的模式参数是一个JSON 路径字符串字面量,根据给出的规则编写。 + 这特别意味着在正则表达式中要使用的任何反斜杠都必须加倍。例如,匹配根文档中仅包含数字的字符串值: $.* ? (@ like_regex "^\\d+$") @@ -3020,18 +3198,18 @@ DETAIL: Missing "]" after array dimensions. 列。这些列可以通过一个看起来与顶层 COLUMNS 子句类似的 COLUMNS 子句来指定。由 NESTED COLUMNS 构造的行称为子行,它们会与父 - COLUMNS 子句中指定的列所构造的行联接, + COLUMNS 子句中指定的列所构造的行连接, 从而得到最终视图中的行。子列自身也可以包含 NESTED PATH 说明,因此可以提取位于任意嵌套层级中的数据。 在同一层级上由多个 NESTED PATH 生成的列彼此视为 - 兄弟,它们在与父行联接后的行通过 + 兄弟,它们在与父行连接后的行通过 UNION 进行组合。 - 由 JSON_TABLE 生成的行会与生成它们的行进行横向联接, + 由 JSON_TABLE 生成的行会与生成它们的行进行横向连接, 因此你无需显式地将构造出来的视图与保存 JSON - 数据的原始表进行联接。 + 数据的原始表进行连接。 @@ -3169,9 +3347,8 @@ JSON_TABLE ( 该值对应于将 PATH 表达式应用到行模式后是否产生任何值。 - 指定的 type 应当具有从 - boolean 类型进行强制转换的能力。 - + 应当存在从boolean到指定type的类型转换。 + 你还可以选择使用 ON ERROR 来指定: 当 JSON 路径求值期间发生错误,或者将 SQL/JSON 值强制转换为指定类型时发生错误时, @@ -3235,7 +3412,7 @@ JSON_TABLE ( 可选的 json_path_name 用作所提供的 path_expression 的标识符。 - 该名称必须唯一,并且不能与列名相同。 + 该名称必须唯一,并且不得与列名相同。 @@ -3343,7 +3520,7 @@ SELECT jt.* FROM 下面是在上述查询基础上的修改版本,用来展示如何使用 NESTED PATH 填充 title 和 director - 列,并说明它们如何与父列 id 和 kind 联接: + 列,并说明它们如何与父列 id 和 kind 连接: SELECT jt.* FROM diff --git a/zh/19/func/func-logical.sgml b/zh/19/func/func-logical.sgml index 527a4ece..d157c6e3 100644 --- a/zh/19/func/func-logical.sgml +++ b/zh/19/func/func-logical.sgml @@ -3,20 +3,17 @@ 逻辑操作符 - operator - logical + 操作符 + 逻辑 - Boolean - operators - operators, logical + 布尔 + 操作符 + 操作符,逻辑 - - 常用的逻辑操作符有: - - + 可以使用以下常见逻辑操作符: AND(操作符) @@ -29,15 +26,15 @@ - conjunction + 合取 - disjunction + 析取 - negation + 否定 @@ -46,9 +43,7 @@ NOT boolean boolean - SQL使用三值的逻辑系统,包括真、假和nullnull表示未知。观察下面的真值表: - - + SQL使用由真、假和null构成的三值逻辑系统,其中null表示未知。请看下面的真值表: diff --git a/zh/19/func/func-matching.sgml b/zh/19/func/func-matching.sgml index 43afb02c..613b6a81 100644 --- a/zh/19/func/func-matching.sgml +++ b/zh/19/func/func-matching.sgml @@ -3,11 +3,11 @@ 模式匹配 - pattern matching + 模式匹配 - PostgreSQL提供了三种独立的实现模式匹配的方法:SQL LIKE操作符、更近一些的SIMILAR TO操作符(SQL:1999 里添加进来的)和POSIX-风格的正则表达式。除了这些基本的这个串匹配这个模式吗?操作符外,还有一些函数可用于提取或替换匹配子串并在匹配位置分离一个串。 + PostgreSQL提供了三种独立的模式匹配方法:传统的SQL LIKE操作符、较新的SIMILAR TO操作符(在 SQL:1999 中加入),以及POSIX风格的正则表达式。除了用于判断这个字符串是否匹配这个模式?的基本操作符外,还提供了提取或替换匹配子字符串、在匹配位置分割字符串的函数。 @@ -20,25 +20,20 @@ - 虽然大部分的正则表达式搜索都能被很快地执行,但是正则表达式仍可能被 - 人为地弄成需要任意长的时间和任意量的内存进行处理。要当心从不怀好意 - 的来源接受正则表达式搜索模式。如果必须这样做,建议加上语句超时限制。 + 虽然大多数正则表达式搜索都能很快完成,但特意构造的正则表达式可能需要任意长的处理时间和任意多的内存。接受来自恶意来源的正则表达式搜索模式时应当谨慎。如果必须这样做,建议设置语句超时。 - 使用SIMILAR TO模式的搜索具有同样的安全性危险, - 因为SIMILAR TO提供了很多和 - POSIX-风格正则表达式相同的能力。 + 使用SIMILAR TO模式进行搜索具有同样的安全风险,因为SIMILAR TO提供了许多与POSIX风格正则表达式相同的能力。 - LIKE搜索比其他两种选项简单得多,因此在使用 - 不怀好意的模式来源时要更安全些。 + LIKE搜索比另外两种方法简单得多,因此,当模式可能来自恶意来源时,使用它更安全。 - SIMILAR TOPOSIX-风格正则表达式不支持非确定性排序规则。如果需要的话,可以使用LIKE或在表达式中应用不同的排序规则来绕过这个限制。 + SIMILAR TOPOSIX 风格的正则表达式不支持非确定性排序规则。如有需要,可以使用 LIKE,或对表达式应用不同的排序规则来绕过这一限制。 @@ -58,7 +53,11 @@ - 如果pattern不包含百分号或者下划线,那么该模式只代表它本身的串;这时候LIKE的行为就象等号操作符。在pattern里的下划线 (_)代表(匹配)任何单个字符; 而一个百分号(%)匹配任何零或更多个字符的序列。 + 如果pattern不包含百分号或下划线,那么该模式只表示它 + 本身的字符串;在这种情况下,LIKE的行为就像等号操作符。 + pattern中的下划线(_)代表 + (匹配)任意单个字符;百分号(%)匹配任意由零个或多个 + 字符组成的序列。 @@ -72,17 +71,35 @@ - LIKE模式匹配总是覆盖整个串。因此,要匹配在串内任何位置的序列,该模式必须以百分号开头和结尾。 + LIKE 模式匹配支持非确定性排序规则(参见 ),例如不区分大小写的排序规则,或忽略标点符号的排序规则。因此,使用不区分大小写的排序规则时,可以得到: + +'AbC' LIKE 'abc' COLLATE case_insensitive true +'AbC' LIKE 'a%' COLLATE case_insensitive true + +对于忽略某些字符,或更一般地将不同长度的字符串视为相等的排序规则,语义会稍显复杂。考虑以下示例: + +'.foo.' LIKE 'foo' COLLATE ign_punct true +'.foo.' LIKE 'f_o' COLLATE ign_punct true +'.foo.' LIKE '_oo' COLLATE ign_punct false + +匹配时会把模式划分为通配符序列和非通配符字符串(通配符为 _%)。例如,模式 f_o 被划分为 f, _, o,模式 _oo 被划分为 _, oo。如果输入字符串能以某种方式划分,使通配符分别匹配一个字符或任意数量的字符,且非通配符片段在所用排序规则下相等,则输入字符串与模式匹配。例如,'.foo.' LIKE 'f_o' COLLATE ign_punct 为真,因为可以把 .foo. 划分为 .f, o, o.;此时 '.f' = 'f' COLLATE ign_punct'o' 匹配通配符 _,且 'o.' = 'o' COLLATE ign_punct。但 '.foo.' LIKE '_oo' COLLATE ign_punct 为假,因为无法将 .foo. 划分为首个字符匹配任意字符、而剩余字符串与 oo 比较相等的形式。(注意,单字符通配符始终恰好匹配一个字符,与排序规则无关。因此,在此示例中,_ 会匹配 .,但输入字符串的其余部分无法匹配模式的其余部分。) - 要匹配文本的下划线或者百分号,而不是匹配其它字符, 在pattern里相应的字符必须 前导转义字符。缺省的转义字符是反斜线,但是你可以用ESCAPE子句指定一个不同的转义字符。 要匹配转义字符本身,写两个转义字符。 + LIKE模式匹配总是覆盖整个字符串。因此,如果想要匹配字符串内 + 任意位置上的一个序列,该模式就必须以百分号开头并以百分号结尾。 + + + + 要匹配字面量下划线或百分号而不是把它们当作通配符, + pattern中相应的字符前面必须带有转义字符。 + 默认的转义字符是反斜线,但也可以使用ESCAPE子句选择其他 + 转义字符。要匹配转义字符本身,请写两个转义字符。 - 请注意反斜线在串文本里已经有特殊含义了,所以如果你写一个 包含反斜线的模式常量,那你就要在 SQL 语句里写两个反斜线。 因此,写一个匹配单个反斜线的模式实际上要在语句里写四个反斜线。 你可以通过用 ESCAPE 选择一个不同的转义字符 来避免这样;这样反斜线就不再是 LIKE 的特殊字符了。 但仍然是字符文本分析器的特殊字符,所以你还是需要两个反斜线。) - 我们也可以通过写ESCAPE ''的方式不选择转义字符,这样可以有效地禁用转义机制,但是没有办法关闭下划线和百分号在模式中的特殊含义。 + 也可以通过写 ESCAPE '' 来选择不使用转义字符。这会禁用转义机制,从而无法关闭模式中下划线和百分号的特殊含义。 @@ -91,7 +108,7 @@ - 关键字ILIKE可以用于替换LIKE,它令该匹配根据活动区域成为大小写无关。(但这不支持非确定性排序规则。)这个不属于SQL标准而是一个PostgreSQL扩展。 + 可以用关键字 ILIKE 代替 LIKE,使匹配根据当前区域设置忽略大小写。(但它不支持非确定性排序规则。)这不属于 SQL 标准,而是 PostgreSQL 的扩展。 @@ -102,14 +119,11 @@ - 短语LIKEILIKENOT LIKE,和 NOT ILIKEPostgreSQL语法中通常被视为操作符; - 例如,它们可以用于expression operator的任何(subquery)构造,尽管这里不能包含ESCAPE子句。 - 在某些晦涩难懂的情况下,可能需要用底层操作符名称替代。 + 在 PostgreSQL 语法中,LIKEILIKENOT LIKENOT ILIKE 通常被当作操作符;例如,它们可以用于 expression operator ANY (subquery) 构造,但其中不能包含 ESCAPE 子句。在某些不常见的情况下,可能需要改用底层操作符名称。 - 另请参阅以^@开头的操作符和相应的starts_with()函数, - 在需要简单匹配字符串开头的情况下非常有用。 + 另请参见用于匹配字符串开头的操作符 ^@ 和相应的 starts_with() 函数,它们适用于只需匹配字符串开头的情况。 @@ -118,8 +132,8 @@ <function>SIMILAR TO</function>正则表达式 - regular expression - + 正则表达式 + @@ -136,13 +150,11 @@ - SIMILAR TO操作符根据自己的模式是否匹配给定串而返回真或者假。 - 它和LIKE非常类似,只不过它使用 SQL 标准定义的正则表达式理解模式。 - SQL 正则表达式是在LIKE标记和普通的(POSIX)正则表达式标记的奇怪的杂交。 + SIMILAR TO操作符根据其模式是否匹配给定字符串返回真或假。它与LIKE非常相似,但使用 SQL 标准定义的正则表达式来解释模式。SQL 正则表达式是LIKE表示法与普通(POSIX)正则表达式表示法的一种奇特结合。 - 类似LIKESIMILAR TO操作符只有在它的模式匹配整个串的时候才能成功;这一点和普通的 正则表达式的行为不同,在普通的正则表达式里,模式匹配串的任意部分。 和LIKE类似的地方还有,SIMILAR TO使用_%作为分别代表任意单个字符和任意串的通配符(这些可以比得上 POSIX 正则表达式里的..*)。 + 与LIKE类似,SIMILAR TO操作符只有在其模式匹配整个字符串时才算成功;这一点不同于普通正则表达式,后者可以匹配字符串的任意部分。与LIKE相同,SIMILAR TO也使用_%作为通配符,分别匹配任意单个字符和任意字符串(分别类似于 POSIX 正则表达式中的..*)。 @@ -210,8 +222,7 @@ - 另一个非标准扩展是,在转义字符后面跟着一个字母或数字提供了对为POSIX正则表达式定义的转义序列的访问;参见下面的 - ,和 。 + 另一个非标准扩展是在转义字符后跟一个字母或数字,以使用 POSIX 正则表达式定义的转义序列;参见下文的 @@ -227,19 +238,19 @@ - 带有三个参数的substring函数可以提取匹配SQL正则表达式模式的子字符串。 该函数可以按照标准SQL99语法编写。 + 带有三个参数的substring函数可以提取匹配 SQL 正则表达式模式的子字符串。该函数可以按照标准 SQL 语法书写: substring(string SIMILAR pattern ESCAPE escape-character) - 或使用现在废除的 SQL:1999 语法: + 也可以使用现已过时的 SQL:1999 语法: substring(string FROM pattern FOR escape-character) - 或作为一个普通的三参数函数: + 或写成普通的三参数函数: substring(string, pattern, escape-character) - 与SIMILAR TO一样,指定的模式必须与整个数据字符串匹配,否则函数失败并返回空值。 为了表示匹配的数据子字符串的模式中,模式中应该包含两个转义字符的出现,并在后面加上一个双引号(")。 匹配成功后,将返回与这些分隔符之间的模式部分匹配的文本。 + 与SIMILAR TO一样,指定的模式必须匹配整个数据字符串,否则函数失败并返回空值。为了指明要提取的子字符串所对应的模式部分,模式中应包含两个分隔符,每个分隔符都由转义字符后跟双引号(")组成。匹配成功时,返回与这两个分隔符之间的模式部分匹配的文本。 @@ -247,7 +258,7 @@ substring(string, pattern, - 作为对SQL标准的扩展,PostgreSQL只允许有一个转义双引号分隔符,在这种情况下,第三个正则表达式被视为空;或者没有分隔符,在这种情况下,第一个和第三个正则表达式被视为空。 + 作为对SQL标准的扩展,PostgreSQL允许仅有一个转义双引号分隔符,在这种情况下,第三个正则表达式被视为空;或者没有分隔符,在这种情况下,第一个和第三个正则表达式被视为空。 @@ -264,8 +275,8 @@ substring('foobar' SIMILAR '#"o_b#"%' ESCAPE '#') NULLPOSIX正则表达式 - regular expression - pattern matching + 正则表达式 + 模式匹配 @@ -300,7 +311,7 @@ substring('foobar' SIMILAR '#"o_b#"%' ESCAPE '#') NULLboolean - 字符串匹配正则表达式,大小写敏感 + 字符串匹配正则表达式,区分大小写 'thomas' ~ 't.*ma' @@ -314,7 +325,7 @@ substring('foobar' SIMILAR '#"o_b#"%' ESCAPE '#') NULLboolean - 字符串匹配正则表达式,大小写不敏感 + 字符串匹配正则表达式,不区分大小写 'thomas' ~* 'T.*ma' @@ -328,7 +339,7 @@ substring('foobar' SIMILAR '#"o_b#"%' ESCAPE '#') NULLboolean - 字符串不匹配正则表达式,大小写敏感 + 字符串不匹配正则表达式,区分大小写 'thomas' !~ 't.*max' @@ -342,7 +353,7 @@ substring('foobar' SIMILAR '#"o_b#"%' ESCAPE '#') NULLboolean - 字符串不匹配正则表达式,大小写不敏感 + 字符串不匹配正则表达式,不区分大小写 'thomas' !~* 'T.*ma' @@ -354,11 +365,11 @@ substring('foobar' SIMILAR '#"o_b#"%' ESCAPE '#') NULL - POSIX正则表达式提供了比LIKESIMILAR TO操作符更强大的含义。许多 Unix 工具,例如grep -Esedawk使用一种与我们这里描述的类似的模式匹配语言。 + POSIX正则表达式提供了比LIKESIMILAR TO操作符更强大的模式匹配方式。许多 Unix 工具,例如grep -Esedawk,都使用与这里描述的模式匹配语言相似的语言。 - 正则表达式是一个字符序列,它是定义一个串集合 (一个正则集)的缩写。 如果一个串是正则表达式描述的正则集中的一员时, 我们就说这个串匹配该正则表达式。 和LIKE一样,模式字符准确地匹配串字符, 除非在正则表达式语言里有特殊字符 — 不过正则表达式用的 特殊字符和LIKE用的不同。 和LIKE模式不一样的是,正则表达式允许匹配串里的任何位置,除非该正则表达式显式地挂接在串的开头或者结尾。 + 正则表达式是一个字符序列,是定义一组字符串(一个正则集)的简写。如果字符串属于正则表达式描述的正则集,就称该字符串匹配此正则表达式。与LIKE一样,模式中的字符精确匹配字符串中的字符,除非该模式字符在正则表达式语言中有特殊含义 — 但正则表达式使用的特殊字符与LIKE不同。与LIKE模式不同,正则表达式可以匹配字符串中的任意位置,除非显式将其锚定到字符串开头或末尾。 @@ -398,8 +409,8 @@ substring('foobar' SIMILAR '#"o_b#"%' ESCAPE '#') NULLstring from pattern) text substring(string, pattern) text - (使用from的语法符合 SQL 标准,但 PostgreSQL 也允许使用逗号。)如果没有匹配它返回空值,否则就是匹配模式的文本中的第一部分。 - 但是如果该模式包含任何圆括号,那么将返回匹配第一对子表达式(对应第一个左圆括号的) 的文本。 + (使用from的语法符合 SQL 标准,但PostgreSQL也允许使用逗号。)如果没有匹配它返回空值,否则返回文本中首次匹配模式的那部分内容。 + 但是如果该模式包含任何圆括号,那么将返回匹配第一个圆括号子表达式(左圆括号最先出现的那个)的文本。 如果你想在表达式里使用圆括号而又不想导致这个例外,那么你可以在整个表达式外边放上一对圆括号。 如果你需要在想抽取的子表达式前有圆括号,参阅中描述的非捕获性圆括号。 @@ -436,7 +447,7 @@ regexp_count(string, pattern - 一些示例: + 一些示例: regexp_count('ABCABCAXYaxy', 'A.') 3 regexp_count('ABCABCAXYaxy', 'A.', 1, 'i') 4 @@ -453,7 +464,7 @@ regexp_count('ABCABCAXYaxy', 'A.', 1, 'i') 4 - regexp_instr函数返回字符串中第N个匹配项的起始或结束位置,如果没有这样的匹配项则返回零。 + regexp_instr函数返回 POSIX 正则表达式模式在字符串中第N个匹配项的起始或结束位置,如果没有这样的匹配项则返回零。 它的语法为: regexp_instr(string, pattern , start , N , endoption , flags , subexpr ) integer @@ -463,17 +474,17 @@ regexp_instr(string, patternendoption参数或将其指定为0,则函数返回匹配项的第一个字符的位置。否则,endoption 必须为1,函数返回匹配项后面字符的位置。 flags参数是一个可选的文本字符串,包含零个或多个单字母标志,可以改变函数的行为。支持的标志在中描述。 - 对于包含括号子表达式的模式,subexpr是一个整数,表示感兴趣的子表达式:结果标识与该子表达式匹配的子字符串的位置。 - 子表达式按其前导括号的顺序编号。 - 当省略或将subexpr指定为零时,结果标识整个匹配的位置,而不考虑括号子表达式。 + 对于包含圆括号子表达式的模式,subexpr是一个整数,表示感兴趣的子表达式:结果标识与该子表达式匹配的子字符串的位置。 + 子表达式按其左圆括号的顺序编号。 + 当省略或将subexpr指定为零时,结果标识整个匹配的位置,而不考虑圆括号子表达式。 - 一些示例: + 一些示例: regexp_instr('number of your street, town zip, FR', '[^,]+', 1, 2) 23 -regexp_instr('ABCDEFGHI', '(c..)(...)', 1, 1, 0, 'i', 2) +regexp_instr(string=>'ABCDEFGHI', pattern=>'(c..)(...)', start=>1, "N"=>1, endoption=>0, flags=>'i', subexpr=>2) 6 @@ -501,7 +512,7 @@ regexp_like(string, pattern - 一些示例: + 一些示例: regexp_like('Hello World', 'world') false regexp_like('Hello World', 'world', 'i') true @@ -518,20 +529,20 @@ regexp_like('Hello World', 'world', 'i') true - regexp_match函数返回一个文本数组,其中包含与POSIX正则表达式模式对字符串的第一个匹配的子字符串。它的语法为 + regexp_match函数返回一个文本数组,包含字符串首次匹配 POSIX 正则表达式模式时匹配的子字符串。它的语法为 : regexp_match(string, pattern , flags ) text[] 如果没有匹配,结果为NULL。 - 如果找到匹配,并且pattern不包含括号子表达式,则结果是包含与整个模式匹配的子字符串的单元素文本数组。 - 如果找到匹配,并且pattern包含括号子表达式,则结果是一个文本数组,其中第n个元素是匹配 - pattern的第n个括号子表达式的子字符串(不包括非捕获括号;详情见)。 + 如果找到匹配,并且pattern不包含圆括号子表达式,则结果是包含与整个模式匹配的子字符串的单元素文本数组。 + 如果找到匹配,并且pattern包含圆括号子表达式,则结果是一个文本数组,其中第n个元素是匹配 + pattern的第n个圆括号子表达式的子字符串(不包括非捕获括号;详情见)。 flags参数是一个可选的文本字符串,其中包含零个或多个单个字母标志,用于更改函数的行为。支持的标志在中描述。 - 一些示例: + 一些示例: SELECT regexp_match('foobarbequebaz', 'bar.*que'); regexp_match @@ -550,10 +561,10 @@ SELECT regexp_match('foobarbequebaz', '(bar)(beque)'); - 在通常情况下,当您只想要整个匹配的子字符串或NULL表示没有匹配时, + 在通常情况下,当你只想要整个匹配的子字符串或NULL表示没有匹配时, 最好的解决方案是使用regexp_substr()。 然而,在PostgreSQL版本15及以上版本中才存在 - regexp_substr()。在旧版本中工作时,您可以提取 + regexp_substr()。在旧版本中工作时,你可以提取 regexp_match()结果的第一个元素,例如: SELECT (regexp_match('foobarbequebaz', 'bar.*que'))[1]; @@ -609,11 +620,11 @@ SELECT regexp_matches('foobarbequebazilbarfbonk', '(b[^b]+)(b[^b]+)', 'g'); - 在大部分情况下,regexp_matches()应该与g标志一起使用,因为如果只是想要第一个匹配,使用regexp_match()会更加简单高效。不过,regexp_match()仅存在于PostgreSQL版本10以及更高的版本中。当在较老的版本中使用时,一种常用的技巧是把regexp_matches()调用放在子选择中,例如: + 在大部分情况下,regexp_matches()应该与g标志一起使用,因为如果只是想要第一个匹配,使用regexp_match()会更加简单高效。不过,regexp_match()仅存在于PostgreSQL版本10以及更高的版本中。当在较老的版本中使用时,一种常用的技巧是把regexp_matches()调用放在子查询中,例如: SELECT col1, (SELECT regexp_matches(col2, '(bar)(beque)')) FROM tab; - 如果有一个匹配,则这个语句会产生一个文本数组,否则返回NULL,这和regexp_match()的做法一样。如果没有子选择,这个查询对于没有匹配的表行根本不会产生输出,显然那不是想要的行为。 + 如果有一个匹配,则这个语句会产生一个文本数组,否则返回NULL,这和regexp_match()的做法一样。如果没有子查询,这个查询对于没有匹配的表行根本不会产生输出,这通常不是预期行为。 @@ -627,32 +638,16 @@ SELECT col1, (SELECT regexp_matches(col2, '(bar)(beque)')) FROM tab; - regexp_replace函数提供了对匹配POSIX正则表达式模式的子字符串进行替换的功能。 - 它的语法为 - : + regexp_replace函数将匹配 POSIX 正则表达式模式的子字符串替换为新文本。它的语法为: regexp_replace(string, pattern, replacement , flags ) text regexp_replace(string, pattern, replacement, start , N , flags ) text - 如果pattern没有匹配到string字符串, - 则返回未更改的string字符串。如果有匹配,则返回带有 - replacement字符串替换匹配子字符串的string字符串。 - replacement字符串可以包含\n, - 其中n为1至9,表示应插入与模式的第n个括号子表达式匹配的源子字符串, - 也可以包含\&表示应插入与整个模式匹配的子字符串。 - 如果需要在替换文本中放置一个字面上的反斜杠,则写\\。 - 在string中搜索pattern, - 通常从字符串的开头开始,但如果提供了start参数,则从该字符索引开始。 - 默认情况下,只替换模式的第一个匹配项。 - 如果指定了N且大于零,则替换模式的第N个匹配项。 - 如果给出了g标志,或者指定了N且为零,则在start位置或之后的所有匹配项 - 都将被替换。 (当指定了N时,g标志将被忽略。) - flags参数是一个可选的文本字符串,包含零个或多个单字母标志,用于更改函数的行为。 - 支持的标志(尽管不包括g)在中描述。 +如果没有匹配pattern的内容,则原样返回源字符串string。如果有匹配,则返回将匹配的子字符串替换为replacement后的stringreplacement字符串可以包含\n,其中n为 1 至 9,表示插入与模式中第n个圆括号子表达式匹配的源子字符串;也可以包含\&,表示插入与整个模式匹配的子字符串。要在替换文本中放入字面的反斜线,应写成\\。在string中搜索pattern时,通常从字符串开头开始;如果提供了start参数,则从该字符索引开始。默认只替换模式的第一个匹配项。如果指定了N且其值大于零,则替换模式的第N个匹配项。如果给出g标志,或指定了N且其值为零,则替换start位置及其后的所有匹配项。(指定N时,g标志会被忽略。)flags参数是可选的文本字符串,可包含零个或多个单字母标志,用于改变函数行为。支持的标志(不包括g)在中介绍。 - 一些示例: + 一些示例: regexp_replace('foobarbaz', 'b..', 'X') fooXbaz @@ -662,7 +657,7 @@ regexp_replace('foobarbaz', 'b(..)', 'X\1Y', 'g') fooXarYXazY regexp_replace('A PostgreSQL function', 'a|e|i|o|u', 'X', 1, 0, 'i') X PXstgrXSQL fXnctXXn -regexp_replace('A PostgreSQL function', 'a|e|i|o|u', 'X', 1, 3, 'i') +regexp_replace(string=>'A PostgreSQL function', pattern=>'a|e|i|o|u', replacement=>'X', start=>1, "N"=>3, flags=>'i') A PostgrXSQL function @@ -677,10 +672,10 @@ regexp_replace('A PostgreSQL function', 'a|e|i|o|u', 'X', 1, 3, 'i') - regexp_split_to_table把一个 POSIX 正则表达式模式当作一个定界符来分离一个串。它的语法形式是: + regexp_split_to_table把一个 POSIX 正则表达式模式当作一个定界符来分割字符串。它的语法形式是: regexp_split_to_table(string, pattern , flags ) setof text -如果没有与pattern的匹配,该函数返回string。如果有至少有一个匹配,对每一个匹配它都返回从上一个匹配的末尾(或者串的开头)到这次匹配开头之间的文本。当没有更多匹配时,它返回从上一次匹配的末尾到串末尾之间的文本。flags参数是一个可选的文本串,它包含零个或更多单字母标志,这些标识可以改变该函数的行为。regexp_split_to_table能支持的标志在中描述。 +如果没有与pattern的匹配,该函数返回string。如果至少有一个匹配,对每一个匹配它都返回从上一个匹配的末尾(或者串的开头)到这次匹配开头之间的文本。当没有更多匹配时,它返回从上一次匹配的末尾到串末尾之间的文本。flags参数是一个可选的文本串,它包含零个或更多单字母标志,这些标志可以改变该函数的行为。regexp_split_to_table能支持的标志在中描述。 @@ -725,8 +720,8 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; 正如最后一个示例所示,regexp_split_to_table会忽略出现在字符串开头或结尾 - 或紧跟在前一个匹配项之后的零长度匹配。这与其他regexp函数实现的 - 严格的regexp匹配定义相矛盾,但在实践中通常是最方便的行为。 + 或紧跟在前一个匹配项之后的零长度匹配。这与其他正则表达式函数实现的 + 严格的正则表达式匹配定义相矛盾,但在实践中通常是最方便的行为。 其他软件系统如Perl使用类似的定义。 @@ -780,17 +775,17 @@ regexp_substr(string, patternN,则返回模式的第N次匹配, 否则返回第一次匹配。参数flags是一个可选文本字符串, 包含零个或多个单字母标志,可以改变函数的行为。支持的标志在中描述。 - 对于包含括号子表达式的模式,subexpr是一个整数, + 对于包含圆括号子表达式的模式,subexpr是一个整数, 表示感兴趣的子表达式:结果是与该子表达式匹配的子字符串。 - 子表达式按其前导括号的顺序编号。 - 当省略或为零时,subexpr的结果是整个匹配,而不考虑括号子表达式。 + 子表达式按其左圆括号的顺序编号。 + 当subexpr省略或为零时,结果是整个匹配,而不考虑圆括号子表达式。 - 一些示例: + 一些示例: regexp_substr('number of your street, town zip, FR', '[^,]+', 1, 2) - 城镇 邮编 + town zip regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) FGH @@ -804,7 +799,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - POSIX正则表达式细节 + POSIX 正则表达式细节 PostgreSQL的正则表达式是使用 Henry Spencer 写的一个包来实现的。下面的正则表达式的大部分描述都是从他的手册页中逐字拷贝过来的。 @@ -831,7 +826,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 一个量化原子是一个原子, 后面可能跟着一个量词。没有量词的时候,它匹配一个原子, 有量词的时候,它可以匹配若干个原子。一个原子可以是在里面显示的任何可能。 可能的量词和它们的含义在里显示。 + 一个量化原子是一个原子,后面可以跟一个量词。没有量词时,匹配一次原子所匹配的内容;有量词时,按量词指定的次数匹配原子所匹配的内容。原子可以是列出的任何一种形式。可用量词及其含义见 @@ -857,12 +852,12 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) (re) - (其中re是任何正则表达式) 匹配一个对re的匹配,匹配将为可能的报告被记下 + (其中re是任意正则表达式)匹配re所匹配的内容,并记录该匹配,以备输出结果 (?:re) - 同上,但是匹配不会为了报告而被记下 (一个非捕获圆括号集) (只对 ARE) + 同上,但不记录匹配结果(非捕获圆括号;仅适用于 ARE) @@ -877,17 +872,17 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) \k - (其中k是一个非字母数字字符) 匹配一个被当作普通字符看待的特定字符, 例如,\\匹配一个反斜线字符 + (其中k既不是字母也不是数字)把该字符视为普通字符并匹配它,例如,\\匹配反斜线字符 \c - 其中c是一个字母数字 (可能跟着其它字符),它是一个转义, 参阅(仅对 ARE; 在 ERE 和 BRE 中,它匹配c + 其中c是字母或数字(后面可能还有其他字符),这是一个转义,参见(仅适用于 ARE;在 ERE 和 BRE 中,它匹配c { - 如果后面跟着一个字符,而不是数字, 那么就匹配左花括弧{;如果跟着一个数字, 那么它是range的开始(见下文) + 如果后面跟着非数字字符,则匹配左花括号{;如果后面跟着数字,则是bound的开头(见下文) @@ -991,7 +986,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 非贪婪的量词(只在 ARE 中可用)匹配对应的正常 (贪婪)模式,区别是它寻找最少的匹配,而不是最多的匹配。详见。 + 非贪婪量词(仅适用于 ARE)与对应的普通(贪婪)量词匹配相同的可能内容,但优先选择最少的匹配次数,而不是最多的匹配次数。详见 @@ -1020,39 +1015,39 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) ^ - 串开头的匹配 + 在字符串开头匹配 $ - 串末尾的匹配 + 在字符串末尾匹配 (?=re) - 在某个位置上,如果从该位置开始的子串能够匹配re,则匹配正向先行断言(仅对 ARE) + 正向先行断言在这样的位置匹配:存在从该位置开始且匹配re的子字符串(仅适用于 ARE) (?!re) - 在某个位置上,如果从该位置开始的子串不能匹配re,则匹配负向先行断言(仅对 ARE) + 负向先行断言在这样的位置匹配:不存在任何从该位置开始且匹配re的子字符串(仅适用于 ARE) (?<=re) - 在某个位置上,如果以该位置结束的某个子串能够匹配re,则匹配正向后行断言(仅对 ARE) + 正向后行断言在这样的位置匹配:存在以该位置结束且匹配re的子字符串(仅适用于 ARE) (?<!re) - 在某个位置上,如果以该位置结束的任何子串都不能匹配re,则匹配负向后行断言(仅对 ARE) + 负向后行断言在这样的位置匹配:不存在任何以该位置结束且匹配re的子字符串(仅适用于 ARE)
- Lookahead 和 lookbehind 约束不能包含反向引用 (参阅),并且其中的所有圆括号 都被认为是非捕获的。 + 先行和后行约束不能包含反向引用(参见),其中的所有圆括号都视为非捕获圆括号。 @@ -1061,11 +1056,11 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) 方括号表达式 - 方括号表达式是一个包围在[]中的字符列表。它通常匹配列表中的任意单个字符(但见下文)。 如果列表以^开头,它匹配任意单个在该列表参与部分中的字符。如果该列表中两个字符用-隔开, 那它就是那两个字符(包括在内)之间的所有字符范围的缩写,例如,在ASCII[0-9]匹配任何十进制数字。两个范围共享一个端点是非法的,例如,a-c-e。范围与字符集关系密切, 可移植的程序应该避免依靠它们。 + 方括号表达式是用[]括起来的字符列表。通常,它匹配列表中的任意单个字符(但请参见下文)。如果列表以^开头,则匹配任意在列表剩余部分中的单个字符。如果列表中的两个字符用-分隔,则表示排序序列中这两个字符之间的完整字符范围(包含两个端点);例如,ASCII中的[0-9]匹配任意十进制数字。两个范围共享一个端点是不合法的,例如a-c-e。范围高度依赖排序序列,因此可移植程序应避免依赖它们。 - 想在列表中包含文本],可以让它做列表的首字符(如果使用了^,需要放在其后)。 想在列表中包含文本-,可以让它做列表的首字符或者尾字符,或者一个范围的第二个端点。 想在列表中把文本-当做范围的起点, 把它用[..]包围起来,这样它就成为一个排序元素(见下文)。 除了这些字符本身、一些用[的组合(见下段)以及转义(只在 ARE 中有效)以外,所有其它特殊字符 在方括号表达式里都失去它们的特殊含义。特别是,在 ERE 和 BRE 规则下\不是特殊的, 但在 ARE 里,它是特殊的(引入一个转义)。 + 想在列表中包含字面字符],可以让它做列表的首字符(如果使用了^,需要放在其后)。 想在列表中包含字面字符-,可以让它做列表的首字符或者尾字符,或者一个范围的第二个端点。 想在列表中把字面字符-当做范围的起点, 把它用[..]包围起来,这样它就成为一个排序元素(见下文)。 除了这些字符本身、一些用[的组合(见下段)以及转义(只在 ARE 中有效)以外,所有其它特殊字符 在方括号表达式里都失去它们的特殊含义。特别是,在 ERE 和 BRE 规则下\不是特殊的, 但在 ARE 里,它是特殊的(引入一个转义)。 @@ -1080,30 +1075,11 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 在方括号表达式里,包围在[==]里的排序元素是一个等价类, 代表等效于那一个的所有排序元素的字符序列,包括它本身(如果没有其它等效排序元素,那么就好象封装定界符是[..])。例如,如果o^是一个等价类的成员,那么[[=o=]][[=^=]][o^]都是同义的。一个等价类不能是一个范围的端点。 + 在方括号表达式里,包围在[==]里的排序元素是一个等价类, 代表等效于那一个的所有排序元素的字符序列,包括它本身(如果没有其它等效排序元素,那么就好像封装定界符是[..])。例如,如果o^是一个等价类的成员,那么[[=o=]][[=^=]][o^]都是同义的。一个等价类不能是一个范围的端点。 - 在方括号表达式里,在[::]里面封装的字符类的名字代表属于该类的所有字符的列表。 - 字符类不能作为范围的端点使用。 - POSIX标准定义了这些字符类的名称: - alnum (字符和数字), - alpha (字符), - blank (空格和制表符tab), - cntrl (控制符), - digit (数位数), - graph (空格除外可打印字符), - lower (小写字母), - print (包含空格可打印字符), - punct (标点符号), - space (空白), - upper (大写字母), - 和 xdigit (十六进制数). - 对于7位ASCII字符集中的字符来说,这些标准字符类的行为在不同平台上一般是一致的。 - 一个给定的非 ASCII 字符是否被认为属于这些类别中的一个,取决于正则表达式函数或操作符所使用的排序规则(见),或者在默认情况下取决于数据库的LC_CTYPE locale 设置(见)。 - 非ASCII字符的分类在不同的平台上会有不同的分类,即使是在类似命名的locale中也是如此。 - (但C locale从不认为任何非ASCII字符属于上述任何一类)。 - 除了这些标准字符类之外,PostgreSQL定义了word字符类,等同于alnum加上下划线(_), 以及ascii字符类,它完全包含7位ASCII字符集。 + 在方括号表达式中,用[::]括起来的字符类名称表示属于该类的所有字符。字符类不能作为范围的端点。POSIX标准定义了以下字符类名称:alnum(字母和数字)、alpha(字母)、blank(空格和制表符)、cntrl(控制字符)、digit(数字)、graph(空格以外的可打印字符)、lower(小写字母)、print(包括空格的可打印字符)、punct(标点符号)、space(任意空白字符)、upper(大写字母)和xdigit(十六进制数字)。对于 7 位 ASCII 字符集中的字符,这些标准字符类在各平台上的行为通常一致。给定的非 ASCII 字符是否属于其中某个类,取决于正则表达式函数或操作符使用的排序规则(参见),默认则取决于数据库的LC_CTYPE区域设置(参见)。即使区域设置名称相似,非 ASCII 字符的分类也可能因平台而异。(但C区域设置不会将任何非 ASCII 字符归入这些类。)除了这些标准字符类,PostgreSQL还定义了word字符类,即alnum加上下划线(_),以及恰好包含 7 位 ASCII 字符集的ascii字符类。 @@ -1120,11 +1096,11 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) 正则表达式转义 - 转义是以\开头,后面跟着一个字母数字字符的特殊序列。 转义有好几种变体:字符输入转义、字符类简写转义、约束转义以及反向引用。在 ARE 里, 如果一个\后面跟着一个字母数字,但是并未组成一个合法的转义, 那么它是非法的。在 ERE 中没有转义:在方括号表达式之外,一个后面跟着字母数字字符的\只是表示该字符是一个普通的字符,而且在一个方括号表达式里,\是一个普通的字符(后者实际上在 ERE 和 ARE 不兼容)。 + 转义是以\开头,后面跟着一个字母或数字字符的特殊序列。 转义有好几种变体:字符输入转义、字符类简写转义、约束转义以及反向引用。在 ARE 里, 如果一个\后面跟着一个字母或数字,但是并未组成一个合法的转义, 那么它是非法的。在 ERE 中没有转义:在方括号表达式之外,一个后面跟着字母或数字字符的\只是表示该字符是一个普通的字符,而且在一个方括号表达式里,\是一个普通的字符(后者是 ERE 与 ARE 之间唯一的实际不兼容之处)。 - 字符输入转义用于便于我们在 RE 中声明那些不可打印的或其他习惯的字符。它们显示在中。 + 字符输入转义便于在 RE 中指定不可打印或其他不便输入的字符,见 @@ -1132,13 +1108,13 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 约束转义是一个约束,如果满足特定的条件,它匹配该空串。它们显示在中。 + 约束转义是以转义形式书写的约束,在满足特定条件时匹配空字符串,见 - 反向引用\n)匹配数字\n指定的被前面的圆括号子表达式匹配的同一个串 (参阅)。 + 反向引用\n)匹配前面编号为n的圆括号子表达式所匹配的同一字符串 (参阅)。 例如, ([bc])\1匹配bb或者cc, 但是不匹配bc或者cb。 - RE 中子表达式必须完全在反向引用前面。子表达式以它们的先导圆括号的顺序编号。 + RE 中子表达式必须完全在反向引用前面。子表达式以它们的左圆括号的顺序编号。 非捕获圆括号并不定义子表达式。 反向引用仅考虑被引用的子表达式匹配的字符串字符,而不考虑其中包含的任何约束。 例如,(^\d)\1 将匹配 22。 @@ -1183,7 +1159,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) \e - 排序序列名为ESC的字符,如果无法做到该字符为八进制值 033 + 排序序列名称为ESC的字符;若不存在这样的字符,则使用八进制值为033的字符 @@ -1193,7 +1169,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) \n - 新行,和 C 中一样 + 换行符,与 C 中相同 @@ -1319,7 +1295,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 类-缩写转义也适用于括号表达式,尽管上面显示的定义在该上下文中在语法上并不完全有效。 + 字符类简写转义也适用于括号表达式,尽管上面显示的定义在该上下文中在语法上并不完全有效。 例如,[a-c\d] 等同于 [a-c[:digit:]] @@ -1362,7 +1338,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) \Y - 只在一个词的不是开头或末尾的点上匹配 + 只在不属于单词开头或末尾的位置匹配 @@ -1374,7 +1350,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 一个词被定义成在上面[[:<:]][[:>:]]中的声明。在方括号表达式里,约束转义是非法的。 + 单词的定义与上文[[:<:]][[:>:]]的说明相同。方括号表达式中不允许使用约束转义。 @@ -1396,12 +1372,12 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) \m - (其中m是一个非零位)一个到第m个子表达式的反向引用 + (其中m是一个非零数字)一个到第m个子表达式的反向引用 \mnn - (其中m是一个非零位,并且nn是一些更多的位,并且十六进制值mnn不超过目前能看到的封闭捕获圆括号的数目)一个到第mnn个子表达式的反向引用 + (其中m是一个非零数字,并且nn是后续的若干数字,并且十进制值mnn不大于此前已出现的捕获右圆括号数)一个到第mnn个子表达式的反向引用 @@ -1410,7 +1386,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 在八进制字符输入转义和反向引用之间有一个历史继承的歧义存在,这个歧义是 通过下面的启发式规则解决的,像上面描述地那样。前导零总是表示这是一个八进制转义。 而单个非零数字,如果没有跟着任何其它位,那么总是被认为反向引用。 一个多位的非零开头的序列也被认为是反向引用,只要它出现在合适的子表达式后面 (也就是说,在反向引用的合法范围中的数),否则就被认为是一个八进制。 + 八进制字符输入转义与反向引用之间存在固有歧义,按上文提到的启发式规则解决:前导零始终表示八进制转义。单个非零数字,如果后面没有其他数字,始终视为反向引用。不以零开头的多位数字序列,如果前面已有相应的子表达式(即该数字在反向引用的合法范围内),则视为反向引用,否则视为八进制转义。 @@ -1424,11 +1400,11 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 如果一个 RE 以***:开头,那么剩下的 RE 都被当作 ARE(这在PostgreSQL中通常是无效的,因为 RE 被假定为 ARE,但是如果 ERE 或 BRE 模式通过flags参数被指定为一个正则表达式函数时,它确实能产生效果)。如果一个 RE 以***=开头, 那么剩下的 RE 被当作一个文本串,所有的字符都被认为是一个普通字符。 + RE 可以以两种特殊的引导前缀之一开头。如果 RE 以***:开头,余下部分就被视为 ARE。(这在PostgreSQL中通常没有影响,因为 RE 默认被视为 ARE;但如果通过正则表达式函数的flags参数指定了 ERE 或 BRE 模式,它就会产生影响。)如果 RE 以***=开头,余下部分就作为按字面解释的字符串处理,所有字符都视为普通字符。 - 一个 ARE 可以以嵌入选项开头:一个序列(?xyz)(这里的xyz是一个或多个字母字符)声明影响剩余 RE 的选项。 这些选项覆盖任何前面判断的选项 — 特别地,它们可以覆盖一个正则表达式操作符隐含的大小写敏感的行为,或者覆盖flags参数中的正则表达式函数。可用的选项字母在中显示。注意这些同样的选项字母也被用在正则表达式函数的flags参数中。 + 一个 ARE 可以以嵌入选项开头:一个序列(?xyz)(这里的xyz是一个或多个字母字符)声明影响剩余 RE 的选项。 这些选项覆盖任何先前确定的选项 — 特别地,它们可以覆盖一个正则表达式操作符隐含的大小写敏感的行为,或者覆盖正则表达式函数的flags参数所指定的选项。可用的选项字母在中显示。注意这些同样的选项字母也被用在正则表达式函数的flags参数中。
@@ -1475,32 +1451,32 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) n - 新行敏感的匹配(见 + 换行敏感的匹配(见 p - 部分新行敏感的匹配(见 + 部分换行敏感的匹配(见 q - RE的剩余部分是一个文字(quoted)串,全部是普通字符 + RE 的剩余部分按字面(加引号)解释,所有字符都视为普通字符 s - 非新行敏感的匹配(默认) + 非换行敏感的匹配(默认) t - 紧语法(默认,见下文) + 紧凑语法(默认;见下文) w - 逆部分新行敏感(怪异)的匹配(见 + 逆部分换行敏感(怪异)的匹配(见 @@ -1512,16 +1488,16 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2)
- 嵌入选项在)终止序列时发生作用。它们只在 ARE 的开始处起作用 (在任何可能存在的***:控制器后面)。 + 嵌入选项从结束该序列的)处开始生效。它们只能出现在 ARE 的开头(如果存在***:引导前缀,则位于该前缀之后)。 - 除了通常的()RE 语法(这种情况下所有字符都有效), 还有一种扩展语法,可以通过声明嵌入的x选项获得。在扩展语法里,RE 中的空白字符被忽略,就像那些在#和其后的新行(或 RE 的末尾)之间的字符一样。这样就允许我们给一个复杂的 RE 分段和注释。不过这个基本规则有三种例外: + 除了通常的紧凑 RE 语法(其中所有字符都有意义)之外,还有一种扩展语法,可以通过指定嵌入的x选项来使用。在扩展语法中,RE 中的空白字符会被忽略,同样被忽略的还有#与其后的换行符(或 RE 末尾)之间的所有字符。这使得复杂的 RE 可以分段并添加注释。此基本规则有三个例外: - 空白字符或前置了\#将被保留 + 空白字符或 # 的前面若有 \,该字符就会被保留。 @@ -1536,14 +1512,14 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 为了这个目的,空白是空格、制表符、新行以及任何属于 whitespace 字符类的字符。 + 在这里,空白字符包括空格、制表符、换行符,以及属于space字符类的任何字符。 - 最后,在 ARE 里,方括号表达式外面,序列(?#ttt)(其中ttt是任意不包含一个))的文本)是一个注释, 它被完全忽略。同样,这样的东西是不允许出现在多字符符号的字符中间的,例如 (?:。这种注释更像是一种历史产物而不是一种有用的设施,并且它们的使用已经被废弃;请使用扩展语法来替代。 + 最后,在 ARE 里,方括号表达式外面,序列(?#ttt)(其中ttt是任意不包含一个)的文本)是一个注释, 它被完全忽略。同样,这样的东西是不允许出现在多字符符号的字符中间的,例如 (?:。这种注释更像是一种历史产物而不是一种有用的设施,并且它们的使用已经被废弃;请使用扩展语法来替代。
- 如果声明了一个初始的***=控制器,那么所有这些元语法扩展都不能使用,因为这样表示把用户输入当作一个文字串而不是 RE 对待。 + 如果指定了开头的***=引导前缀,那么这些元语法扩展都不能使用,因为这表示把用户输入作为按字面解释的字符串,而非 RE 处理。 @@ -1560,7 +1536,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 大多数原子以及所有约束,都没有贪婪属性(因为它们毕竟无法匹配个数变化的文本)。 + 大多数原子以及所有约束,都没有贪婪属性(因为它们毕竟无法匹配长度不定的文本)。 @@ -1612,7 +1588,7 @@ SELECT SUBSTRING('XY1234Z', 'Y*?([0-9]{1,3})');
- 简而言之,如果一个 RE 同时包含贪婪和非贪婪的子表达式,那么总的匹配长度要么是尽可能长,要么是尽可能短,这取决于给整个 RE 赋予的属性。给子表达式赋予的属性只影响在这个匹配里,各个子表达式之间相互允许吃掉的多少。 + 简而言之,如果一个 RE 同时包含贪婪和非贪婪的子表达式,那么总的匹配长度要么是尽可能长,要么是尽可能短,这取决于给整个 RE 赋予的属性。给子表达式赋予的属性只影响在这个匹配里,各个子表达式相对于其他子表达式能吃掉多少内容。 @@ -1646,23 +1622,23 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 如果声明了大小写无关的匹配,那么效果就好像所有大小写区别在字母表中消失了。如果在多个情况中一个字母以一个普通字符的形式出现在方括号表达式外面,那么它实际上被转换成 一个包含大小写的方括号表达式,也就是说,x 变成 [xX]。 如果它出现在一个方括号表达式里面,那么它的所有大小写的同族都被加入 方括号表达式中,也就是说,x变成[xX]。当它出现在一个方括号表达式内时,它的所有大小写副本都被加入到方括号表达式中,例如, [x]会变成[xX],而[^x]会变成[^xX]。 + 如果指定不区分大小写的匹配,其效果近似于字母表中的所有大小写差别都消失了。当存在大小写形式的字母作为普通字符出现在方括号表达式之外时,实际上会转换为包含其大小写形式的方括号表达式,例如x变成[xX]。当它出现在方括号表达式内部时,其所有大小写形式都会加入该表达式,例如[x]变成[xX][^x]变成[^xX] 如果指定了换行敏感的匹配,.和使用^的方括号表达式 将永远不会匹配换行字符(这样,匹配就不会跨越行,除非 RE 显式地包含了换行)并且^$除了分别匹配串开头和结尾之外,还将分别匹配换行后面和前面的空串。 但是 ARE 转义\A\Z仍然匹配串的开头和结尾。 - 此外,字符类缩写符\D\W将匹配换行,而无论这种模式如何。 + 此外,字符类简写\D\W将匹配换行,而无论这种模式如何。 (在PostgreSQL 14之前,它们在换行敏感模式下不匹配换行。 写入[^[:digit:]][^[:word:]]以获取旧的行为。) - 如果指定了部分新行敏感的匹配,那么它影响.和方括号表达式, 这个时候和新行敏感的匹配一样,但是不影响^$。 + 如果指定了部分换行敏感的匹配,那么它影响.和方括号表达式, 这个时候和换行敏感的匹配一样,但是不影响^$ - 如果指定了逆新行敏感匹配,那么它影响^$,其作用和在新行敏感的匹配里一样,但是不影响.和方括号表达式。这个并不是很有用,只是为了满足对称性而提供的。 + 如果指定了逆部分换行敏感匹配,那么它影响^$,其作用和在换行敏感的匹配里一样,但是不影响.和方括号表达式。这个并不是很有用,只是为了满足对称性而提供的。 @@ -1675,11 +1651,11 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}');
- ARE 实际上和 POSIX ERE 不兼容的唯一的特性是在方括号表达式里\并不失去它特殊的含义。所有其它 ARE 特性都使用在 POSIX ERE 里面是非法或者是未定义、未声明效果的语法;指示器的***就是在 POSIX 的 BRE 和 ERE 之外的语法。 + ARE 与 POSIX ERE 实际不兼容的唯一特性是:\在方括号表达式中不会失去特殊含义。其他所有 ARE 特性所使用的语法,在 POSIX ERE 中都是非法的,或其效果未定义或未指定;引导前缀的***语法同样不属于 POSIX 的 BRE 或 ERE 语法。 - 许多 ARE 扩展都是从 Perl 那里借来的(但是有些被做了修改来清理它们),以及一些 Perl 里没有出现的扩展。要注意的不兼容性包括\b\B、对结尾的新行缺乏特别的处理、对那些被新行敏感匹配的东西附加的补齐方括号表达式、在 lookahead/lookbehind 约束里对圆括号和反向引用的限制以及最长/最短 匹配(而不是第一匹配)的语义。 + 许多 ARE 扩展借鉴自 Perl,但其中一些经过了整理和修改,也未实现少数 Perl 扩展。需要注意的不兼容之处包括\b\B、不对末尾换行符作特殊处理、取反的方括号表达式也受换行敏感匹配影响、先行和后行约束中对圆括号及反向引用的限制,以及采用最长或最短匹配而非首次匹配的语义。 @@ -1688,7 +1664,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 基本正则表达式 - BREs 在几个方面和 ERE 不太一样。在 BRE 中,|+?都是普通字符并且没有与它们功能等价的东西。范围的定界符是\{\}, 因为 {}本身是普通字符。嵌套的子表达式的圆括号是\(\),因为()自身是普通字符。除非在 RE 开头或者是圆括号子表达式开头,^都是一个普通字符。 除非在 RE 结尾或者是圆括号子表达式的结尾,$是一个普通字符。如果*出现在 RE 开头或者是圆括号封装的子表达式开头 (前面可能有^),那么它是个普通字符。最后,可以用单数字的反向引用,\<\>分别是[[:<:]][[:>:]]的同义词;在 BRE 中没有其它可用的转义。 + BRE 在几个方面和 ERE 不太一样。在 BRE 中,|+?都是普通字符并且没有与它们功能等价的东西。范围的定界符是\{\},而{}本身是普通字符。嵌套的子表达式的圆括号是\(\),而()自身是普通字符。除非在 RE 开头或者是圆括号子表达式开头,^都是一个普通字符。 除非在 RE 结尾或者是圆括号子表达式的结尾,$是一个普通字符。如果*出现在 RE 开头或者是圆括号封装的子表达式开头 (前面可能有^),那么它是个普通字符。最后,可以用单数字的反向引用,\<\>分别是[[:<:]][[:>:]]的同义词;在 BRE 中没有其它可用的转义。 @@ -1744,7 +1720,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); SQL标准 - PostgreSQL + PostgreSQL @@ -1801,16 +1777,13 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 使用\p{UnicodeProperty}或其反义\P{UnicodeProperty}来定义XQuery字符类元素是不被支持的。 + 使用\p{UnicodeProperty}或其取反形式\P{UnicodeProperty}来定义XQuery字符类元素是不被支持的。 - POSIX解释字符类,如\w - (参见) - 根据当前区域设置(你可以通过将COLLATE子句附加到操作符或函数上来控制)。 - XQuery通过参考Unicode字符属性来指定这些类别,因此只有遵循Unicode规则的区域设置才能获得等效行为。 + POSIX 根据当前区域设置解释\w等字符类(参见);你可以通过为操作符或函数附加COLLATE子句来控制该区域设置。XQuery 根据 Unicode 字符属性定义这些类,因此只有使用遵循 Unicode 规则的区域设置时,才能得到等效行为。 @@ -1823,10 +1796,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 在描述的字符输入转义中 - 中, - XQuery仅支持\n\r, - 和\t。 + 在描述的字符输入转义中,XQuery 仅支持 \n\r\t @@ -1838,7 +1808,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - XQuery没有前瞻或后顾约束,也没有在中描述的任何约束转义。 + XQuery没有先行或后行约束,也没有在中描述的任何约束转义。 @@ -1858,7 +1828,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); XQuery的s(允许点匹配换行符) 和m(允许^ - 和$匹配换行符)标志提供 + 和$在换行处匹配)标志提供 与POSIX的npw标志相同的行为,但它们 匹配POSIX的sm标志的行为。 diff --git a/zh/19/func/func-math.sgml b/zh/19/func/func-math.sgml index c8aabab5..a58305b4 100644 --- a/zh/19/func/func-math.sgml +++ b/zh/19/func/func-math.sgml @@ -3,12 +3,12 @@ 数学函数和操作符 - PostgreSQL为很多类型提供了数学操作符。对于那些没有标准数学表达的类型(如日期/时间类型),我们将在后续小节中描述实际的行为。 + PostgreSQL为很多类型提供了数学操作符。对于那些没有标准数学惯例的类型(如日期/时间类型),我们将在后续小节中描述实际的行为。 - 显示了可用于标准数字类型的数学操作符。 - 除非另有说明, 显示为可接受 numeric_type 的操作符对所有的 smallintintegerbigintnumericrealdouble precision类型都可用。 + 显示了可用于标准数值类型的数学操作符。 + 除非另有说明, 显示为可接受 numeric_type 的操作符对所有的 smallintintegerbigintnumericrealdouble precision类型都可用。 显示为可接受 integral_type 的操作符对 smallintintegerbigint类型是可用的。 除了特别说明之处,操作符的每种形式都返回与其参数相同的数据类型。 涉及多个参数数据类型的调用, 例如 integer + numeric,可通过使用这些列表中稍后出现的类型来解析。 @@ -56,7 +56,7 @@ numeric_type - 一元加(无操作) + 一元正号(不执行操作) + 3.5 @@ -84,7 +84,7 @@ numeric_type - 否定 + 取负 - (-4) @@ -112,7 +112,7 @@ numeric_type - 除(对于整型,除法将结果截断为零) + 除法(对于整数类型,除法将结果向零截断) 5.0 / 2 @@ -152,14 +152,14 @@ double precision - 指数 + 求幂 2 ^ 3 8 - 不像典型的数学实践,多次使用 ^ 将会默认从左到右关联: + 与通常的数学惯例不同,多次使用^时默认从左到右结合: 2 ^ 3 ^ 3 @@ -219,7 +219,7 @@ integral_type - 按位与(AND) + 按位与 91 & 15 @@ -233,7 +233,7 @@ integral_type - 按位或(OR) + 按位或 32 | 3 @@ -247,7 +247,7 @@ integral_type - 按位异或(exclusive OR) + 按位异或 17 # 5 @@ -261,7 +261,7 @@ integral_type - 按位求反(NOT) + 按位非 ~1 @@ -304,9 +304,9 @@ 显示了可用的数学函数。 许多这样的函数以多种具有不同的参数类型的形式提供。 - 除非注明,任何给定形式的函数都返回与其参数相同的数据类型;跨类型情况的解决方法与上述对操作符的解释相同。 - 使用double precision数据的函数大多是在主机系统的C库上实现的; - 因此,边界情况下的准确性和行为会因主机系统的区别而不同。 + 除非注明,任何给定形式的函数都返回与其参数相同的数据类型;跨类型情况的解决方法与上述对操作符的解释相同。 + 使用double precision数据的函数大多是在主机系统的C库上实现的; + 因此,精度和边界情况下的行为可能因主机系统而异。 @@ -437,7 +437,7 @@ numeric - y/x 的整数商(截断为零位) + y/x 的整数商(向零截断) div(9, 4) @@ -445,27 +445,6 @@ - - - - exp - - exp ( numeric ) - numeric - - - exp ( double precision ) - double precision - - - 指数 (e 的给定次方) - - - exp(1.0) - 2.7182818284590452 - - - @@ -500,6 +479,27 @@ + + + + exp + + exp ( numeric ) + numeric + + + exp ( double precision ) + double precision + + + 指数函数(e的给定次幂) + + + exp(1.0) + 2.7182818284590452 + + + @@ -701,7 +701,7 @@ integer - 精确表示所提供值所需的最小刻度(小数位数) + 精确表示给定值所需的最少小数位数 min_scale(8.4100) @@ -798,7 +798,7 @@ double precision - 四舍五入到最近的整数。 + 舍入到最接近的整数。 对于numeric,遇到恰好位于中点的情况时按远离零的方向舍入。 对于double precision,中点取舍规则取决于平台,但舍入到最接近的偶数是最常见的规则。 @@ -835,7 +835,7 @@ integer - 参数的刻度(小数点后的位数) + 参数的小数位数(小数部分的十进制位数) scale(8.4100) @@ -894,7 +894,7 @@ numeric - 通过删除尾数部分的零来降低值的刻度(小数位数) + 通过移除尾随零来减少值的小数位数 trim_scale(8.4100) @@ -915,7 +915,7 @@ double precision - 截断整数 (向零靠近) + 向零截断为整数 trunc(42.8) @@ -933,7 +933,7 @@ numeric - 截断 vs 位小数位置的数字 + 将v截断到s位小数 trunc(42.4382, 2) @@ -1026,6 +1026,35 @@ + + + + random + + random ( min integer, max integer ) + integer + + + random ( min bigint, max bigint ) + bigint + + + random ( min numeric, max numeric ) + numeric + + + 返回范围min <= x <= max内的随机值。对于numeric类型,结果的小数位数与minmax中小数位数较多者相同。 + + + random(1, 10) + 7 + + + random(-0.499, 0.499) + 0.347 + + + @@ -1038,8 +1067,7 @@ double precision - 返回具有给定参数的正态分布中的一个随机值;mean默认为 0.0, - stddev默认为 1.0 + 从具有给定参数的正态分布中返回一个随机值;mean默认为 0.0,stddev默认为 1.0。 random_normal(0.0, 1.0) @@ -1067,7 +1095,7 @@
- 在中列出的random()random_normal()函数使用同一个确定性伪随机数生成器。 + 在中列出的random()random_normal()函数使用确定性伪随机数生成器。 它速度快,但不适用于加密应用;请参阅模块以获取更安全的替代方案。 如果调用setseed(),则当前会话中后续对这些函数的调用结果序列可以通过使用相同参数重新发出setseed()来重复。 在同一会话中没有任何先前的setseed()调用时,首次调用这些函数中的任何一个都会从平台相关的随机位源获取种子。 @@ -1380,7 +1408,7 @@ - 另一种使用以角度度量的角的方法是使用早前展示的单位转换函数radians()degrees()。不过,使用基于角度的三角函数更好,因为这类方法能避免sind(30)等特殊情况下的舍入偏差。 + 另一种使用以角度度量的角的方法是使用早前展示的单位转换函数radians()degrees()。不过,使用基于角度的三角函数更好,因为这类方法能避免sind(30)等特殊情况下的舍入误差。 @@ -1453,7 +1481,7 @@ double precision - 双曲切线 + 双曲正切 tanh(1) @@ -1504,7 +1532,7 @@ double precision - 反双曲切线 + 反双曲正切 atanh(0.5) diff --git a/zh/19/func/func-net.sgml b/zh/19/func/func-net.sgml index 3b586187..2684c44e 100644 --- a/zh/19/func/func-net.sgml +++ b/zh/19/func/func-net.sgml @@ -9,8 +9,8 @@ 任何cidr 值都可以隐式地转换到inet;因此,下面在inet上操作的操作符和函数也可以在cidr值上工作。 - (对于inetcidr有单独的函数,这是因为这两种情况的行为应该是不同的。) - 此外,它允许将inet值转换为cidr。 + (如果inetcidr各有单独的函数,是因为这两种情况下的行为应当不同。) + 此外,也允许将inet值转换为cidr。 当这样做的时候,子网掩码右边的任何位都被静默地置零,以创建一个有效的cidr值。 @@ -41,8 +41,8 @@ boolean - 子网是否严格包含在子网中?这个操作符和后续的四个操作符测试子网包含情况。 - 它们只考虑两个地址的网络部分(忽略网络掩码右侧的任何位),并确定一个网络与另一个网络相同或者是相同的子网。 + 子网是否严格包含在另一个子网中?这个操作符和后续四个操作符测试子网包含关系。 + 它们只考虑两个地址的网络部分(忽略网络掩码右侧的所有位),并判断一个网络是否与另一个网络相同,或是另一个网络的子网。 inet '192.168.1.5' << inet '192.168.1/24' @@ -64,7 +64,7 @@ boolean - 子网是否包含或等于子网? + 子网是否被包含于或等于子网? inet '192.168.1/24' <<= inet '192.168.1/24' @@ -124,7 +124,7 @@ inet - 计算位 NOT. + 计算按位非。 ~ inet '192.168.1.6' @@ -138,7 +138,7 @@ inet - 计算位 AND. + 计算按位与。 inet '192.168.1.6' & inet '0.0.0.255' @@ -152,7 +152,7 @@ inet - 计算位 OR. + 计算按位或。 inet '192.168.1.6' | inet '0.0.0.255' @@ -253,9 +253,8 @@ text - 创建缩写的文本显示格式。 - (结果与inet输出函数产生的结果相同;只有在与显式转换为text的结果相比时它才算是缩写形式, - 由于历史原因,它永远不会抑制子网掩码部分。) + 创建文本形式的缩写显示格式。 + (结果与inet输出函数产生的结果相同;只有与显式类型转换为text的结果相比时,才称为缩写形式。由于历史原因,后一种转换从不省略网络掩码部分。) abbrev(inet '10.1.0.0/32') @@ -269,7 +268,7 @@ text - 创建缩写的文本显示格式。(缩写包括在子网掩码的右侧删除所有零字节;更多的示例请见 。) + 创建文本形式的缩写显示格式。(缩写形式会省略网络掩码右侧值为零的字节;更多示例见。) abbrev(cidr '10.1.0.0/16') @@ -388,7 +387,7 @@ integer - 以比特位返回子网掩码长度。 + 返回子网掩码长度,以位为单位。 masklen(inet '192.168.1.5/24') @@ -490,7 +489,7 @@ MAC地址类型, macaddrmacaddr8,支持中所示的常用比较操作符以及中所示的特殊函数。 - 此外,它们支持位元逻辑操作符~, &| (NOT, AND 和 OR),就像上面对IP地址所示的那样。 + 此外,它们支持按位逻辑操作符~&|(非、与和或),就像上面对IP地址所示的那样。 @@ -554,7 +553,7 @@ macaddr8 - 将地址的第7位设置为1,创建所谓的modified EUI-64,用于包含在IPv6地址中。 + 将地址的第 7 位设置为 1,生成所谓的修订 EUI-64 格式,以便用于 IPv6 地址。 macaddr8_set7bit(macaddr8 '00:34:56:ab:cd:ef') diff --git a/zh/19/func/func-range.sgml b/zh/19/func/func-range.sgml index e8646dde..1381d571 100644 --- a/zh/19/func/func-range.sgml +++ b/zh/19/func/func-range.sgml @@ -126,7 +126,7 @@ boolean - 第一个范围是否严格符合第二个(范围)? + 第一个范围是否严格地在第二个(范围)的右边? int8range(50,60) >> int8range(20,30) @@ -210,7 +210,7 @@ anyrange - 计算范围的差异。第二个范围必须不能包含在第一个(范围)中,以使差异不是一个单一的范围。 + 计算范围的差集。第二个范围不能被包含在第一个范围中而导致差集无法表示为单个范围。 int8range(5,15) - int8range(10,20) @@ -304,7 +304,7 @@ boolean - 第一个多范围是否被第二个所包括? + 第一个多范围是否被第二个所包含? '{[2,4)}'::int4multirange <@ '{[1,7)}'::int4multirange @@ -318,7 +318,7 @@ boolean - 多范围是否被范围所包括。 + 多范围是否被范围所包含? '{[2,4)}'::int4multirange <@ int4range(1,7) @@ -332,7 +332,7 @@ boolean - 范围是否被多范围所包括? + 范围是否被多范围所包含? int4range(2,4) <@ '{[1,7)}'::int4multirange @@ -430,7 +430,7 @@ boolean - 范围是否完全的在多范围左边? + 范围是否完全在多范围左边? int8range(1,10) << '{[100,110)}'::int8multirange @@ -472,7 +472,7 @@ boolean - 范围是否完全在多范围右边。 + 范围是否完全在多范围右边? int8range(50,60) >> '{[20,30)}'::int8multirange @@ -640,7 +640,7 @@ anymultirange - 计算多范围的差异。 + 计算多范围的差集。 '{[5,20)}'::int8multirange - '{[10,15)}'::int8multirange @@ -652,21 +652,21 @@
- 当涉及一个空范围或多范围时,左部/右部/相邻操作符总是返回假;即一个空范围被认为不在任何其他范围前面或者后面。 + 涉及空范围或空多范围时,左侧、右侧和相邻操作符总是返回假;也就是说,空范围不被视为位于任何其他范围之前或之后。 - 在其他地方,空范围和多范围被视为添加标识:与空值的任何交集都是它自己。 - 任何减去空值的都是它自己。 - 空的多范围与空的范围具有完全相同的点。 + 在其他运算中,空范围和空多范围被视为加法单位元:任何值与空值求并集,结果仍是该值本身。 + 任何值减去空值,结果也仍是该值本身。 + 空多范围与空范围具有完全相同的点。 每个范围都包含空范围。 每个多范围包含任意多个空范围。 - 范围交集和差异操作符将失败,如果结果范围需要包含两个不相交的子范围,因为这样的范围无法表示。 - 还有用于求交集和差集的单独操作符,它们接受多范围参数并返回多范围,即使参数彼此不相交也不会失败。 - 因此,如果需要对可能不相交的范围进行交集或差异操作,你可以通过首先将范围转换为多范围来避免错误。 + 如果结果范围需要包含两个不相交的子范围,范围并集和差集操作符会失败,因为这样的范围无法表示。 + 另有接受多范围参数并返回多范围的并集和差集操作符,即使参数彼此不相交,也不会失败。 + 因此,如果需要对可能不相交的范围求并集或差集,可以先将范围转换为多范围来避免错误。 @@ -704,7 +704,7 @@ anyelement - 提取范围的下界(如果范围为空或下界为无限,则为NULL)。 + 提取范围的下界(如果范围为空或没有下界,则返回NULL)。 lower(numrange(1.1,2.2)) @@ -721,7 +721,7 @@ anyelement - 提取范围的上限(如果范围为空或上限为无限,则为NULL)。 + 提取范围的上界(如果范围为空或没有上界,则返回NULL)。 upper(numrange(1.1,2.2)) @@ -789,7 +789,7 @@ boolean - 范围的下界是无限的吗? + 范围是否没有下界?(下界为-Infinity时返回假。) lower_inf('(,)'::daterange) @@ -806,7 +806,7 @@ boolean - 范围的上界是无限的吗? + 范围是否没有上界?(上界为Infinity时返回假。) upper_inf('(,)'::daterange) @@ -884,7 +884,7 @@ anyelement - 提取多范围的下界 (NULL 如果多范围为空或下界为无穷的)。 + 提取多范围的下界(如果多范围为空或没有下界,则返回NULL)。 lower('{[1.1,2.2)}'::nummultirange) @@ -901,7 +901,7 @@ anyelement - 提取多范围的上界 (NULL 如果多范围为空或上界为无穷的)。 + 提取多范围的上界(如果多范围为空或没有上界,则返回NULL)。 upper('{[1.1,2.2)}'::nummultirange) @@ -935,7 +935,7 @@ boolean - 多范围的下界是否包括? + 多范围的下界是否包含在内? lower_inc('{[1.1,2.2)}'::nummultirange) @@ -952,7 +952,7 @@ boolean - 多范围的上界是否包括? + 多范围的上界是否包含在内? upper_inc('{[1.1,2.2)}'::nummultirange) @@ -969,7 +969,7 @@ boolean - 多范围的下界是无限的么? + 多范围是否没有下界?(下界为-Infinity时返回假。) lower_inf('{(,)}'::datemultirange) @@ -986,7 +986,7 @@ boolean - 多范围的上界是无限的么? + 多范围是否没有上界?(上界为Infinity时返回假。) upper_inf('{(,)}'::datemultirange) @@ -1014,7 +1014,7 @@ - multirange (function) + multirange(函数) multirange ( anyrange ) anymultirange @@ -1032,14 +1032,13 @@ unnest - for multirange + 用于多范围 unnest ( anymultirange ) setof anyrange - 扩展多范围为一组范围。 - 范围按存储顺序读出(升序)。 + 将多范围按升序展开为一组范围。 unnest('{[1,2), [3,4)}'::int4multirange) @@ -1072,6 +1071,6 @@ - lower_incupper_inclower_inf、 和 upper_inf 函数对空范围(empty range)或多范围都返回假(false)。 + lower_incupper_inclower_infupper_inf 函数对空范围或空多范围都返回假。 diff --git a/zh/19/func/func-sequence.sgml b/zh/19/func/func-sequence.sgml index 8352af4d..9c88d44f 100644 --- a/zh/19/func/func-sequence.sgml +++ b/zh/19/func/func-sequence.sgml @@ -3,11 +3,11 @@ 序列操作函数 - sequence + 序列 - 本节描述对序列对象进行操作的函数,也称为序列生成器或简称序列。 + 本节描述用于操作序列对象(也称为序列生成器,或简称序列)的函数。 序列对象是使用创建的特殊单行表。 序列对象通常用于为表中的行生成惟一标识符。在中列出的序列函数,提供了简单的、多用户安全方法,用于从序列对象中获取连续的序列值。 @@ -39,12 +39,12 @@ bigint - 将序列对象推进到下一个值并返回该值。这是自动完成的:即使多个会话并发地执行nextval,每个会话也会安全地接收到不同的序列值。 - 如果序列对象是用默认形参创建的,则连续的nextval调用将返回以1开始的连续值。 + 将序列对象推进到下一个值并返回该值。这个操作是原子的:即使多个会话并发地执行nextval,每个会话也会安全地接收到不同的序列值。 + 如果序列对象是用默认参数创建的,则连续的nextval调用将返回以1开始的连续值。 其他行为可以通过在命令中使用适当的参数获得。 - 这个函数需要USAGEUPDATE权限在序列上。 + 这个函数需要序列上的USAGEUPDATE权限。 @@ -57,16 +57,16 @@ bigint - 设置序列对象的当前值,以及可选的它的is_called标志。 + 设置序列对象的当前值,并可选地设置其is_called标志。 双参数形式将序列的last_value字段设置为指定的值,并将其is_called字段设置为true,意味着下一个nextval将在返回值之前推进序列。 currval将报告的值也设置为指定的值。在三参数形式中,is_called可以设置为truefalsetrue与双参数形式具有相同的效果。 - 如果设置为false,下一个nextval将返回指定的值,序列推进从下面的nextval开始。 - 而且,currval报告的值在这种情况下不会改变。例如, + 如果设置为false,下一个nextval将返回指定的值,序列推进从再下一次调用nextval开始。 + 而且,currval报告的值在这种情况下不会改变。例如: -SELECT setval('myseq', 42); Next nextval will return 43 +SELECT setval('myseq', 42); 下一次 nextval 将返回 43 SELECT setval('myseq', 42, true); 同上 -SELECT setval('myseq', 42, false); Next nextval will return 42 +SELECT setval('myseq', 42, false); 下一次 nextval 将返回 42 setval返回的结果就是它的第二个参数的值。 @@ -84,8 +84,7 @@ SELECT setval('myseq', 42, false); Next nextvalbigint
- 返回nextval在当前会话中为该序列最近获取的值。(如果在这个会话中没有为这个序列调用nextval会报告错误。) - 因为它返回的是一个会话本地值,所以它给出了一个可预测的答案,即自当前会话以来,其他会话是否执行了nextval。 + 返回当前会话中最近一次针对该序列调用nextval所获得的值。(如果当前会话从未针对该序列调用过nextval,则会报错。)由于返回的是会话局部值,无论其他会话是否在当前会话调用之后执行过nextval,结果都是可预测的。 这个函数需要序列上的USAGESELECT权限。 @@ -162,8 +161,6 @@ SELECT setval('myseq', 42, false); Next nextval - 序列函数所要操作的序列由regclass参数指定,该参数只是pg_class系统目录中序列的OID。 - 你不必手工查找OID,不过,因为regclass数据类型的输入转换器将为您完成这项工作。 - 详见 + 序列函数所要操作的序列由regclass参数指定,该参数就是序列在pg_class系统目录中的 OID。不过,不必手动查找 OID,因为regclass数据类型的输入转换器会完成这项工作。详见 diff --git a/zh/19/func/func-srf.sgml b/zh/19/func/func-srf.sgml index fa113ebd..f51b14b9 100644 --- a/zh/19/func/func-srf.sgml +++ b/zh/19/func/func-srf.sgml @@ -8,13 +8,13 @@ - 本节描述那些可能返回多于一行的函数。目前这个类中被使用最广泛的是级数生成函数, 如所述。其他更特殊的集合返回函数在本手册的其他地方描述。 - 组合多集合返回函数的方法可见。 + 本节描述那些可能返回多于一行的函数。目前这个类中被使用最广泛的是序列生成函数, 如所述。其他更特殊的集合返回函数在本手册的其他地方描述。 + 组合多个集合返回函数的方法可见 - 级数生成函数 + 序列生成函数 @@ -70,9 +70,7 @@
- 当step为正时,如果start大于stop则返回零行。 - 相反,当step为负时,如果start小于stop则返回零行。 - 如果任何输入为NULL也会返回零行。step为零是一个错误。下面是一些示例: + 当step为正数时,如果start大于stop,则返回零行。反之,当step为负数时,如果start小于stop,则返回零行。如果任一输入为NULL,也返回零行。如果step为零,则会报错。下面是一些示例: SELECT * FROM generate_series(2,4); generate_series @@ -103,7 +101,7 @@ SELECT generate_series(1.1, 4, 1.3); 3.7 (3 rows) --- this example relies on the date-plus-integer operator: +-- 此示例使用日期加整数的操作符: SELECT current_date + s.a AS dates FROM generate_series(0,14,7) AS s(a); dates ------------ @@ -127,7 +125,7 @@ SELECT * FROM generate_series('2008-03-01 00:00'::timestamp, 2008-03-04 08:00:00 (9 rows) --- 此示例假定 TimeZone 设置为 UTC;注意 DST 转换: +-- 此示例假定 TimeZone 设为 UTC;请注意夏令时(DST)切换: SELECT * FROM generate_series('2001-10-22 00:00 -04:00'::timestamptz, '2001-11-01 00:00 -05:00'::timestamptz, '1 day'::interval, 'America/New_York'); @@ -175,7 +173,7 @@ SELECT * FROM generate_series('2001-10-22 00:00 -04:00'::timestamptz, setof integer - 生成一个包含给定数组第dim维度的有效下标的序列。 + 生成一个包含给定数组第dim维的有效下标的序列。 @@ -185,7 +183,7 @@ SELECT * FROM generate_series('2001-10-22 00:00 -04:00'::timestamptz, setof integer
- 生成一个包含给定数组第dim维度的有效下标的序列。当reverse为真时,以相反的顺序返回序列。 + 生成一个包含给定数组第dim维的有效下标的序列。当reverse为真时,以相反的顺序返回序列。 @@ -194,9 +192,9 @@ SELECT * FROM generate_series('2001-10-22 00:00 -04:00'::timestamptz, generate_subscripts是一个快捷函数,它为给定数组的指定维度生成一组合法的下标。 - 对于不具有请求维度的数组返回零行,对于任何输入为NULL数组也返回零行。下面是一些示例: + 如果数组不具有所请求的维度,或者任一输入为NULL,则返回零行。下面是一些示例: --- basic usage: +-- 基本用法: SELECT generate_subscripts('{NULL,1,NULL,2}'::int[], 1) AS s; s --- @@ -206,8 +204,8 @@ SELECT generate_subscripts('{NULL,1,NULL,2}'::int[], 1) AS s; 4 (4 rows) --- presenting an array, the subscript and the subscripted --- value requires a subquery: +-- 展示数组、下标和下标对应的值 +-- 需要使用子查询: SELECT * FROM arrays; a -------------------- @@ -226,7 +224,7 @@ FROM (SELECT generate_subscripts(a, 1) AS s, a FROM arrays) foo; {100,200,300} | 3 | 300 (5 rows) --- unnest a 2D array: +-- 展开二维数组: CREATE OR REPLACE FUNCTION unnest2(anyarray) RETURNS SETOF anyelement AS $$ SELECT $1[i][j] @@ -246,15 +244,13 @@ SELECT * FROM unnest2(ARRAY[[1,2],[3,4]]); - ordinality + 序号 - 当FROM子句中的函数以WITH ORDINALITY作为后缀时,将在函数的输出列上附加一个bigint列,该列从1开始,函数输出的每一行加1。 - 这在 unnest()等集合返回函数的情况下最有用。 - + 当FROM子句中的函数后面加上WITH ORDINALITY时,一个bigint列会追加到函数的输出列中,其值从 1 开始,对函数输出的每一行递增 1。这种方式对集合返回函数尤其有用,例如unnest() --- set returning function WITH ORDINALITY: +-- 集合返回函数与 WITH ORDINALITY: SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); ls | n -----------------+---- diff --git a/zh/19/func/func-statistics.sgml b/zh/19/func/func-statistics.sgml index e32d8020..c7c56a48 100644 --- a/zh/19/func/func-statistics.sgml +++ b/zh/19/func/func-statistics.sgml @@ -3,12 +3,12 @@ 统计信息函数 - function - statistics + 函数 + 统计信息 - PostgreSQL提供了一个函数来检查使用CREATE STATISTICS命令定义的复杂统计。 + PostgreSQL提供了一个函数来检查使用CREATE STATISTICS命令定义的复杂统计信息。 @@ -24,7 +24,7 @@ - pg_mcv_list_items返回一组记录,描述存储在多列MCV列表中的所有项目。它返回以下列: + pg_mcv_list_items返回一组记录,描述存储在多列MCV列表中的所有项目。它返回以下列: @@ -60,7 +60,7 @@ base_frequency double precision - MCV项目的基本频率 + MCV项目的基础频率 @@ -68,7 +68,7 @@ - pg_mcv_list_items函数可以这样使用: + pg_mcv_list_items函数可以这样使用: SELECT m.* FROM pg_statistic_ext join pg_statistic_ext_data on (oid = stxoid), diff --git a/zh/19/func/func-string.sgml b/zh/19/func/func-string.sgml index e5e80bd7..4e1821b3 100644 --- a/zh/19/func/func-string.sgml +++ b/zh/19/func/func-string.sgml @@ -7,7 +7,7 @@ 这里的字符串包括charactercharacter varyingtext类型的值。 除非另有说明,这些函数和操作符都声明为接受并返回text类型。 它们也可互换地接受character varying参数。 - 在应用函数或操作符之前,character类型的值会先转换为text,因此会去除其尾随空格。 + 在应用函数或操作符之前,character类型的值会先转换为text,因此会去除 character 值的尾随空格。 @@ -18,7 +18,7 @@ 字符串串接操作符(||)将接受非字符串输入,只要至少一个输入是一种字符串类型,如所示。 - 对于其他情况,向text插入一个显式强制,可用于接受非字符串输入。 + 对于其他情况,可以添加到text的显式强制转换,以接受非字符串输入。 @@ -46,14 +46,14 @@ - character string - concatenation + 字符串 + 串接 text || text text - 连接两个字符串。 + 串接两个字符串。 'Post' || 'greSQL' @@ -71,8 +71,8 @@ text - 将非字符串输入转换为文本,然后将两个字符串串联在一起。 - (非字符串输入不能为数组类型,因为这将在||操作符的数组中造成歧义。如果你想连接一个数组的文本相等的,请显式地将其转换为text 。) + 将非字符串输入转换为文本,然后将两个字符串串接起来。 + (非字符串输入不能是数组类型,因为那样会与数组的||操作符产生歧义。如果要串接数组的文本表示,请显式地将其转换为text。) 'Value: ' || 42 @@ -83,17 +83,35 @@ - normalized + btrim + + btrim ( string text + , characters text ) + text + + + 从string的开头和结尾移除仅由characters中字符(默认为空格)组成的最长字符串。 + + + btrim('xyxtrimyyx', 'xyz') + trim + + + + + + + 规范化 - Unicode normalization + Unicode 规范化 text IS NOT form NORMALIZED boolean - 检查字符串是否在指定的 Unicode 规范化表单中。 - 可选的form关键词指定表单:NFC (默认的), NFD, NFKC, 或 NFKD。 + 检查字符串是否处于指定的 Unicode 规范化形式中。 + 可选的form关键字指定形式:NFC(默认)、NFDNFKCNFKD。 只有在服务器编码为UTF8时,才能使用此表达式。 请注意,使用这个表达式检查规范化通常比规范化可能已经规范化的字符串要快。 @@ -126,13 +144,13 @@ char_length - character string - length + 字符串 + 长度 - length + 长度 字符串 - character string, length + 字符串,长度 char_length ( text ) integer @@ -162,7 +180,7 @@ text - 根据数据库的语言环境规则,将字符串转换为全部小写。 + 根据数据库的区域设置规则,将字符串转换为全部小写。 lower('TOM') @@ -170,22 +188,57 @@ + + + + lpad + + lpad ( string text, + length integer + , fill text ) + text + + + 在string前面添加字符fill(默认为空格),将其填充到长度length。如果string已经长于length,则从右侧截断。 + + + lpad('hi', 5, 'xy') + xyxhi + + + + + + + ltrim + + ltrim ( string text + , characters text ) + text + + + 从string的开头移除仅由characters中字符(默认为空格)组成的最长字符串。 + + + ltrim('zzzytest', 'xyz') + test + + + normalize - Unicode normalization + Unicode 规范化 normalize ( text , form ) text - 将字符串转换为指定的Unicode规范化形式。 - 可选的form关键字指定了如下形式:NFC (the default),NFDNFKC,或NFKD。 - 该函数只能在服务器编码为UTF8时使用。 + 将字符串转换为指定的 Unicode 规范化形式。可选的 form 关键字指定如下形式:NFC(默认值)、NFDNFKCNFKD。该函数只能在服务器编码为 UTF8 时使用。 normalize(U&'\0061\0308bc', NFC) @@ -236,8 +289,7 @@ text - 替换stringstart字符开始的子串,并用newsubstring扩展到count字符。 - 如果省略了count,则默认为newsubstring的长度。 + 用newsubstring替换string中从第start个字符开始、长度为count个字符的子字符串。如果省略count,则默认为newsubstring的长度。 overlay('Txxxxas' PLACING 'hom' FROM 2 FOR 4) @@ -254,7 +306,7 @@ integer - 返回string中指定的substring的第一个起始索引,如果不存在则返回零,。 + 返回substringstring中首次出现的位置;如果不存在则返回零。 position('om' IN 'Thomas') @@ -262,6 +314,43 @@ + + + + rpad + + rpad ( string text, + length integer + , fill text ) + text + + + 在string后面追加字符fill(默认为空格),将其填充到长度length。如果string已经长于length,则截断它。 + + + rpad('hi', 5, 'xy') + hixyx + + + + + + + rtrim + + rtrim ( string text + , characters text ) + text + + + 从string的结尾移除仅由characters中字符(默认为空格)组成的最长字符串。 + + + rtrim('testxxzx', 'xyz') + test + + + @@ -271,9 +360,7 @@ text - 如果已指定,提取stringstart字符开始的子串, - 并且在count字符后停止。如果已指定的话。 - 提供至少一个startcount中的至少一个。 + 提取string的子字符串:若指定了起始位置,则从第start个字符开始;若指定了长度,则在提取count个字符后停止。startcount至少需要指定一个。 substring('Thomas' FROM 2 FOR 3) @@ -295,7 +382,7 @@ text - 提取匹配POSIX正则表达式的第一个子字符串; 参见 。 + 提取匹配 POSIX 正则表达式的第一个子字符串;参见 substring('Thomas' FROM '...$') @@ -313,8 +400,8 @@ text - 提取匹配 SQL 正则表达式的第一个字串;参见 。 - 第一种形式自从SQL:2003被指定,第二种形式仅在SQL:1999中,并应认为是废弃的。 + 提取匹配 SQL 正则表达式的第一个子字符串;参见 。 + 第一种形式自 SQL:2003 起由标准规定;第二种形式只出现在 SQL:1999 中,应视为已过时。 substring('Thomas' SIMILAR '%#"o_a#"_' ESCAPE '#') @@ -366,8 +453,7 @@ boolean - 如果字符串中的所有字符都已分配 Unicode 代码点,则返回true;否则返回false。 - 此函数只能在服务器编码为UTF8时使用。 + 如果字符串中的所有字符都是已分配的 Unicode 码点,则返回true;否则返回false。此函数只能在服务器编码为UTF8时使用。 @@ -380,7 +466,7 @@ text - 根据数据库的定位规则,将字符串转换为所有大写。 + 根据数据库的区域设置规则,将字符串转换为全部大写。 upper('tom') @@ -447,7 +533,7 @@ integer - 返回参数的第一个字符的数字代码。在UTF8编码中,返回该字符的Unicode代码点。 + 返回参数的第一个字符的数字代码。在UTF8编码中,返回该字符的Unicode 码点。 在其他多字节编码中,该参数必须是一个ASCII字符。 @@ -456,23 +542,7 @@ - - - - btrim - - btrim ( string text - , characters text ) - text - - - 从string的开头或结尾删除最长的只包含characters(默认是一个空格)的字符串 - - - btrim('xyxtrimyyx', 'xyz') - trim - - + @@ -483,7 +553,7 @@ text - 返回给定代码的字符。在UTF8编码中该参数被视作一个Unicode代码点。 + 返回给定代码的字符。在UTF8编码中该参数被视作一个Unicode 码点。 在其他多字节编码中该参数必须指定一个ASCII字符。 chr(0) 字符不被允许,因为文本数据类型不能存储这种字符。 @@ -499,11 +569,11 @@ concat concat ( val1 "any" - [, val2 "any" [, ...] ] ) + , val2 "any" , ... ) text - 连接所有参数的文本表示。空参数被忽略。 + 串接所有参数的文本表示。NULL 参数被忽略。 concat('abcde', 2, NULL, 22) @@ -518,11 +588,11 @@ concat_ws ( sep text, val1 "any" - [, val2 "any" [, ...] ] ) + , val2 "any" , ... ) text - 用分隔符连接除第一个参数外的所有参数。第一个参数用作分隔符字符串,不应为NULL。其他NULL参数将被忽略。 + 用分隔符串接除第一个参数外的所有参数。第一个参数用作分隔符字符串,不应为NULL。其他NULL参数将被忽略。 concat_ws(',', 'abcde', 2, NULL, 22) @@ -536,7 +606,7 @@ format format ( formatstr text - [, formatarg "any" [, ...] ] ) + , formatarg "any" , ... ) text @@ -558,7 +628,7 @@ text - 将每个单词的第一个字母转换为大写(如果该字母是双字母,且区域设置为ICUbuiltin PG_UNICODE_FAST,则转换为标题大小写),其余字母转换为小写。使用libcbuiltin区域设置提供者时,单词是由非字母数字字符分隔的字母数字字符序列;使用 ICU 区域设置提供者时,单词按ICU 的 u_strToTitle 函数划分。 + 将每个单词的第一个字母转换为大写(如果该字母是二合字母,且区域设置为ICUbuiltin PG_UNICODE_FAST,则转换为标题大小写),其余字母转换为小写。使用libcbuiltin区域设置提供者时,单词是由非字母数字字符分隔的字母数字字符序列;使用 ICU 区域设置提供者时,单词按ICU 的 u_strToTitle 函数划分。 这个函数主要用于方便显示。由于区域设置提供者之间以及不同 ICU 版本之间存在差异,不应依赖具体的转换结果。如果需要特定的单词边界规则,建议编写自定义函数。 @@ -578,20 +648,19 @@ text - 根据排序规则对输入字符串执行大小写折叠。大小写折叠类似于大小写转换,但大小写折叠的目的是促进字符串的不区分大小写匹配,而大小写转换的目的是转换为特定的大小写形式。 - 此函数只能在服务器编码为UTF8时使用。 + 根据排序规则对输入字符串执行大小写折叠。大小写折叠与大小写转换类似,但其目的是方便字符串的不区分大小写匹配,而大小写转换的目的是将字符串转换为特定的大小写形式。此函数只能在服务器编码为UTF8时使用。 - 通常,大小写折叠只是转换为小写,但取决于排序规则,可能存在例外。例如,某些字符有两种以上的小写变体,或者会折叠为大写。 + 通常,大小写折叠只是将字符转换为小写,但不同排序规则可能存在例外。例如,某些字符具有两种以上的小写变体,或者会折叠为大写。 - 大小写折叠可能改变字符串长度。例如,在PG_UNICODE_FAST排序规则中,ß(U+00DF)会折叠为ss。 + 大小写折叠可能改变字符串的长度。例如,在PG_UNICODE_FAST排序规则中,ß(U+00DF)会折叠为ss - casefold可用于 Unicode 默认不区分大小写匹配。它并不总是保留输入字符串的规范化形式(参见)。 + casefold可用于 Unicode 默认无大小写匹配。它并不总能保留输入字符串的规范化形式(参见)。 - libc提供者不支持大小写折叠,因此casefold完全相同。 + libc提供者不支持大小写折叠,因此casefold相同。 @@ -605,7 +674,7 @@ text
- 以字符串返回第一个 n 字符,或在 n 为负时, 返回最后 |n| 个字符之外的全部字符。 + 返回字符串最左侧的 n 个字符;如果 n 为负,则返回除最后 |n| 个字符之外的全部字符。 left('abcde', 2) @@ -630,43 +699,9 @@ - - - - lpad - - lpad ( string text, - length integer - , fill text ) - text - - - 将string扩展为长度length,通过前置字符fill(默认空格)。 - 如果string已经超过length那么它将被截断(在右侧)。 - - - lpad('hi', 5, 'xy') - xyxhi - - - - - - ltrim - - ltrim ( string text - , characters text ) - text - - - 从string开始删除包含characters(默认空格)中仅包含字符的最长字符串。 - - - ltrim('zzzytest', 'xyz') - test - - + + @@ -691,14 +726,14 @@ parse_ident parse_ident ( qualified_identifier text - [, strict_mode boolean DEFAULT true ] ) + , strict_mode boolean DEFAULT true ) text[] - 将qualified_identifier拆分为一个标识符数组,删除单个标识符的任何引用。 + 将qualified_identifier拆分为一个标识符数组,去除各个标识符的引号。 默认情况下,最后一个标识符之后的额外字符被视为错误;但是,如果第二个参数为false,则忽略这些额外的字符。 (这种行为对于解析类似函数的对象的名称有作用。) - 请注意,此函数不会截断超长标识符。如果你想截断,你可以把结果给到name[]。 + 请注意,此函数不会截断超长标识符。如果你想截断,你可以将结果转换为name[] parse_ident('"SomeSchema".someTable') @@ -732,9 +767,7 @@ text - 返回适合引用的给定字符串,作为SQL语句字符串中的标识符。 - 只有在必要的情况下才添加引号(例如,如果字符串包含非标识符字符或将被大小写折叠)。 - 嵌入的引号被适当地加双引号。参见。 + 为给定字符串添加适当的引号并返回,使其可用作SQL语句字符串中的标识符。仅在必要时(即字符串包含不能用于标识符的字符,或会发生大小写折叠时)添加引号。内嵌的引号会被适当地双写。另见 quote_ident('Foo bar') @@ -751,9 +784,7 @@ text - 返回在SQL语句字符串中适当引用的给定字符串,用作字符串文字使用。 - 嵌入式单引号和反斜线适当的翻倍(转双引号或双斜线)。 - 请注意,quote_literal在参数为 null 时返回 null;如果这个参数可能为空,quote_nullable通常更合适。另请参阅。 + 为给定字符串添加适当的引号并返回,使其可用作SQL语句字符串中的字符串字面量。内嵌的单引号和反斜杠会被适当地双写。注意,quote_literal在输入为 null 时返回 null;如果参数可能为 null,quote_nullable通常更合适。另见 quote_literal(E'O\'Reilly') @@ -767,8 +798,7 @@ text - 将给定的值转换为文本,然后将其作为字面量引用。 - 内嵌的单引号和反斜杠被适当地翻倍。 + 将给定值转换为文本,然后作为字面量加引号。内嵌的单引号和反斜杠会被适当地双写。 quote_literal(42.5) @@ -785,8 +815,7 @@ text - 返回在SQL语句字符串中适当引用的给定字符串文字;或者,如果参数为null,则返回NULL。 - 内嵌的单引号和反斜杠被适当地翻倍。参见。 + 为给定字符串添加适当的引号并返回,使其可用作SQL语句字符串中的字符串字面量;如果参数为 null,则返回NULL。内嵌的单引号和反斜杠会被适当地双写。另见 quote_nullable(NULL) @@ -800,8 +829,7 @@ text - 将给定值转换为文本,然后将其作为字面量引用;或者,如果参数为null,则返回NULL。 - 内嵌的单引号和反斜杠被适当地翻倍。 + 将给定值转换为文本,然后作为字面量加引号;如果参数为 null,则返回NULL。内嵌的单引号和反斜杠会被适当地双写。 quote_nullable(42.5) @@ -815,9 +843,9 @@ regexp_count regexp_count ( string text, pattern text - [, start integer - [, flags text ] ] ) - integer + , start integer + , flags text ) + integer 返回 POSIX 正则表达式patternstring中匹配的次数;参见。 @@ -834,15 +862,15 @@ regexp_instr regexp_instr ( string text, pattern text - [, start integer - [, N integer - [, endoption integer - [, flags text - [, subexpr integer ] ] ] ] ] ) - integer + , start integer + , N integer + , endoption integer + , flags text + , subexpr integer ) + integer - 返回string中第N个匹配项的POSIX正则表达式pattern出现的位置,如果没有这样的匹配项,则返回零;参见。 + 返回 POSIX 正则表达式patternstring中第N次匹配的位置;如果没有这样的匹配,则返回零。参见 regexp_instr('ABCDEF', 'c(.)(..)', 1, 1, 0, 'i') @@ -860,8 +888,8 @@ regexp_like regexp_like ( string text, pattern text - [, flags text ] ) - boolean + , flags text ) + boolean 检查 POSIX 正则表达式pattern是否在string中出现;参见。 @@ -877,11 +905,11 @@ regexp_match - regexp_match ( string text, pattern text [, flags text ] ) - text[] + regexp_match ( string text, pattern text , flags text ) + text[] - 返回第一个匹配的POSIX正则表达式patternstring中的子字符串;参见。 + 返回 POSIX 正则表达式patternstring的第一次匹配中的子字符串;参见 regexp_match('foobarbequebaz', '(bar)(beque)') @@ -894,12 +922,11 @@ regexp_matches - regexp_matches ( string text, pattern text [, flags text ] ) - setof text[] + regexp_matches ( string text, pattern text , flags text ) + setof text[] - 返回第一个匹配的 POSIX 正则表达式patternstring中的子字符串,或者如果使用了g标志,则返回所有匹配的子字符串; - 参见。 + 返回 POSIX 正则表达式patternstring的第一次匹配中的子字符串;如果使用g标志,则返回所有匹配中的子字符串。参见 regexp_matches('foobarbequebaz', 'ba.', 'g') @@ -917,8 +944,7 @@ regexp_replace regexp_replace ( string text, pattern text, replacement text - [, start integer ] - [, flags text ] ) + , flags text ) text @@ -933,17 +959,21 @@ regexp_replace ( string text, pattern text, replacement text, - start integer, - N integer - [, flags text ] ) + start integer + , N integer + , flags text ) text - 替换字符串中第N个与 POSIX 正则表达式pattern匹配的子字符串,如果N为零,则替换所有匹配项;参见。 + 替换第N个与 POSIX 正则表达式pattern匹配的子字符串;如果N为零,则替换所有这样的匹配。搜索从string的第start个字符开始。如果省略N,则默认为 1。参见 regexp_replace('Thomas', '.', 'X', 3, 2) ThoXas + + + regexp_replace(string=>'hello world', pattern=>'l', replacement=>'XX', start=>1, "N"=>2) + helXXo world @@ -952,8 +982,8 @@ regexp_split_to_array - regexp_split_to_array ( string text, pattern text [, flags text ] ) - text[] + regexp_split_to_array ( string text, pattern text , flags text ) + text[] 使用POSIX正则表达式作为分隔符拆分string,生成一个结果的数组; 参见 。 @@ -969,8 +999,8 @@ regexp_split_to_table - regexp_split_to_table ( string text, pattern text [, flags text ] ) - setof text + regexp_split_to_table ( string text, pattern text , flags text ) + setof text 使用POSIX正则表达式作为分隔符拆分string,生成一组结果;参见 。 @@ -991,15 +1021,14 @@ regexp_substr regexp_substr ( string text, pattern text - [, start integer - [, N integer - [, flags text - [, subexpr integer ] ] ] ] ) + , start integer + , N integer + , flags text + , subexpr integer ) text - 返回string中与第N个出现的POSIX正则表达式pattern匹配的子字符串, - 如果没有这样的匹配,则返回NULL;参见。 + 返回string中 POSIX 正则表达式pattern的第N次匹配对应的子字符串;如果没有这样的匹配,则返回NULL。参见 regexp_substr('ABCDEF', 'c(.)(..)', 1, 1, 'i') @@ -1039,7 +1068,7 @@ text - 将string 中当前的子串from替换为子串to。 + 将string中所有出现的子字符串from替换为子字符串to replace('abcdefabcdef', 'cd', 'XX') @@ -1074,7 +1103,7 @@ text - 返回字符串中的最后n个字符,或者在n>为负时,返回除了前面的|n|字符之外的所有字符。 + 返回字符串中的最后n个字符;如果n为负数,则返回除前 |n| 个字符之外的全部字符。 right('abcde', 2) @@ -1082,43 +1111,9 @@ - - - - rpad - - rpad ( string text, - length integer - , fill text ) - text - - - 扩展 string 到长度 length,通过追加fill 字符(默认为空格). - 如果string 已经比 length 长,则截断它。 - - - rpad('hi', 5, 'xy') - hixyx - - - - - - rtrim - - rtrim ( string text - , characters text ) - text - - - 从string末尾删除包含characters(默认为空格)中仅包含字符的最长字符串。 - - - rtrim('testxxzx', 'xyz') - test - - + + @@ -1131,7 +1126,7 @@ text - 在delimiter出现时拆分string,并且返回第n个字段(从一计数),或者当n为负数时,返回|n|'th-from-last 字段。 + 在出现delimiter时拆分string,并返回第n个字段(从一开始计数);如果n为负数,则返回倒数第 |n| 个字段。 split_part('abc~@~def~@~ghi', '~@~', 2) @@ -1215,8 +1210,7 @@ integer - 返回在string中指定的substring的第一个起始索引,如果不存在则为零。 - (与(substringstring中的)位置相同,但是请注意反转的参数顺序) + 返回substringstring中首次出现的位置;如果不存在则返回零。(与position(substring in string)相同,但请注意参数顺序相反。) strpos('high', 'ig') @@ -1233,8 +1227,7 @@ text - 提取stringstart字符开始的子字符串,并扩展count字符,如果指定了的话。 - (与 子字符串(stringstart 开始计数 count)相同。) + 提取string中从第start个字符开始的子字符串;若指定了长度,则提取count个字符。(与substring(string from start for count)相同。) substr('alphabet', 3) @@ -1265,10 +1258,7 @@ text - 将string从另一个编码中转换为ASCII,该编码可按名称或编号标识。 - 如果encoding被省略,则假定数据库编码(这在实践中是唯一有用的案例)。转换主要包括降音。 - 转换仅支持来自 LATIN1LATIN2LATIN9、 和 WIN1250 的编码. - (其他请参见 模块, 更灵活的解决方案。) + 将string从其他编码转换为ASCII,源编码可以用名称或编号指定。如果省略encoding,则使用数据库编码(实际上,这也是唯一有用的情况)。转换主要是去除重音符号。只支持从LATIN1LATIN2LATIN9WIN1250编码转换。(另一种更灵活的解决方案参见模块。) to_ascii('Karél') @@ -1314,11 +1304,15 @@ text - 将数字转换为其相应的十六进制表示形式。 + 将数字转换为等价的十六进制补码表示。 to_hex(2147483647) 7fffffff + + + to_hex(-1234) + fffffb2e @@ -1359,7 +1353,7 @@
string中与from集合中匹配的每个字符替换为to集合中相应的字符。 - 如果from长于tofrom中出现的额外字符被删除。 + 如果from长于to,输入中出现的from中的额外字符会被删除。 translate('12345', '143', 'ax') @@ -1376,18 +1370,18 @@ text - 计算参数中的转义Unicode字符。 + 解析参数中转义的 Unicode 字符。 Unicode字符可以被指定为\XXXX (4个十六进制数字),\+XXXXXX(6个十六进制数字),\uXXXX(4个十六进制数字),或\UXXXXXXXX (8个十六进制数字)。 要指定反斜杠,请写入两个反斜杠。 - 所有其他字符都是按字面意义的。 + 所有其他字符均按字面解释。 - 如果服务器编码不是UTF-8,由这些转义序列之一标识的Unicode编码点将被转换为实际的服务器编码;如果不可能,则会报告错误。 + 如果服务器编码不是 UTF-8,由这些转义序列之一标识的 Unicode 码点将被转换为实际的服务器编码;如果无法转换,则会报告错误。 - 这个函数提供了一个(非标准的)替代到Unicode转义的字符串常量(参见)。 + 此函数提供了带 Unicode 转义的字符串常量的另一种(非标准)写法(参见)。 @@ -1405,12 +1399,12 @@ - concatconcat_wsformat函数是可变的,因此可以把要串接或格式化的值作为一个标记了VARIADIC关键字的数组进行传递(见)。 - 数组的元素被当作函数的独立普通参数一样处理。如果可变数组参数为 NULL,concatconcat_ws返回 NULL,但format把 NULL 当作一个零元素数组。 + concatconcat_wsformat是可变参数函数,因此可以把要串接或格式化的值作为一个标记了VARIADIC关键字的数组进行传递(见)。 + 数组的元素被当作函数的独立普通参数一样处理。如果可变参数数组为 NULL,concatconcat_ws返回 NULL,但format把 NULL 当作一个零元素数组。 - 还可以参阅中的string_agg,以及中的字符串和bytea类型之间转换的功能。 + 还可以参阅中的聚合函数string_agg,以及中的字符串和bytea类型之间转换的函数。 @@ -1426,24 +1420,24 @@ -format(formatstr text [, formatarg "any" [, ...] ]) +format(formatstr text , formatarg "any" , ... ) - formatstr是一个格式字符串,它指定了结果应该如何被格式化。格式字符串中的文本被直接复制到结果中,除了使用格式说明符的地方。格式说明符在字符串中扮演着占位符的角色,它定义后续的函数参数如何被格式化及插入到结果中。每一个formatarg参数会被根据其数据类型的常规输出规则转换为文本,并接着根据格式说明符被格式化和插入到结果字符串中。 + formatstr是指定结果格式的字符串。格式字符串中的文本会直接复制到结果中,但格式说明符所在的位置除外。格式说明符充当字符串中的占位符,定义如何格式化后续函数参数并将其插入结果。每个formatarg参数都按照其数据类型通常的输出规则转换为文本,再根据格式说明符进行格式化并插入结果字符串。 - 格式说明符由一个%字符开始并且有这样的形式 + 格式说明符以%字符开头,格式如下: %[position][flags][width]type - 其中的各组件域是: + 其中各组成字段为: position(可选) - 一个形式为n$的字符串,其中n是要打印的参数的索引。索引 1 表示formatstr之后的第一个参数。如果position被忽略,默认会使用序列中的下一个参数。 + 一个形式为n$的字符串,其中n是要打印的参数的索引。索引 1 表示formatstr之后的第一个参数。如果position被省略,默认会使用序列中的下一个参数。 @@ -1451,9 +1445,7 @@ flags(可选) - - 控制格式说明符的输出如何被格式化的附加选项。当前唯一支持的标志是一个负号(-),它将导致格式说明符的输出会被左对齐(left-justified)。除非width域也被指定,否者这个域不会产生任何效果。 - + 用于控制格式说明符输出格式的附加选项。目前唯一支持的标志是减号(-),它使格式说明符的输出左对齐。只有同时指定了width字段时,它才有效。 @@ -1465,8 +1457,8 @@ - 如果宽度来自于一个函数参数,则参数在被格式说明符的值使用之前就被消耗掉了。如果宽度参数是负值,结果会在长度为abs(width)的域中被左对齐(如果-标志被指定)。 - + 如果宽度来自一个函数参数,会先使用该宽度参数,再使用作为格式说明符值的参数。如果宽度参数为负数,结果会在长度为abs(width)的字段中左对齐(如同指定了-标志)。 +
@@ -1483,12 +1475,12 @@
- I将参数值视作 SQL 标识符,并在必要时用双写引号包围它。如果参数为空,将会是一个错误(等效于quote_ident)。 + I将参数值视作 SQL 标识符,并在必要时用双引号包围它。如果参数为 null,则会报错(等效于quote_ident)。 - L将参数值引用为 SQL 文字。一个空值将被显示为不带引号的字符串NULL(等效于quote_nullable)。 + L将参数值作为 SQL 字面量加引号。null 值显示为不带引号的字符串NULL(等效于quote_nullable)。 @@ -1499,13 +1491,10 @@
- 除了以上所述的格式说明符之外,要输出一个文字形式的%字符,可以使用特殊序列%%。 + 除了以上所述的格式说明符之外,要输出一个字面形式的%字符,可以使用特殊序列%% - - 下面有一些基本的格式转换的示例: - - + 下面是一些基本格式转换的示例: SELECT format('Hello %s', 'World'); 结果:Hello World @@ -1516,14 +1505,11 @@ SELECT format('INSERT INTO %I VALUES(%L)', 'Foo bar', E'O\'Reilly'); 结果:INSERT INTO "Foo bar" VALUES('O''Reilly') SELECT format('INSERT INTO %I VALUES(%L)', 'locations', 'C:\Program Files'); -结果:INSERT INTO locations VALUES(E'C:\\Program Files') +结果:INSERT INTO locations VALUES('C:\Program Files') - - 下面是使用width域和-标志的示例: - - + 下面是使用width字段和-标志的示例: SELECT format('|%10s|', 'foo'); 结果:| foo| @@ -1544,10 +1530,7 @@ SELECT format('|%-*s|', -10, 'foo'); - - 这些示例展示了position域的示例: - - + 这些示例展示了如何使用position字段: SELECT format('Testing %3$s, %2$s, %1$s', 'one', 'two', 'three'); 结果:Testing three, two, one @@ -1559,10 +1542,8 @@ SELECT format('|%1$*2$s|', 'foo', 10, 'bar'); - - 不同于标准的 C 函数sprintfPostgreSQLformat函数允许将带有或者不带有position域的格式说明符被混在同一个格式字符串中。一个不带有position域的格式说明符总是使用最后一个被消耗的参数的下一个参数。另外,format函数不要求所有函数参数都被用在格式字符串中。例如: - - + 不同于标准 C 函数sprintf, + PostgreSQLformat函数允许在同一个格式字符串中,混合使用带有或不带有position字段的格式说明符。不带position字段的格式说明符,总是使用最后一个已使用参数之后的下一个参数。此外,format函数不要求格式字符串使用全部函数参数。例如: SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); 结果:Testing three, two, three diff --git a/zh/19/func/func-subquery.sgml b/zh/19/func/func-subquery.sgml index 72ef4a18..38fd273e 100644 --- a/zh/19/func/func-subquery.sgml +++ b/zh/19/func/func-subquery.sgml @@ -27,11 +27,11 @@ - subquery + 子查询 - 本节描述PostgreSQL中可用的SQL兼容的子查询表达式。所有本节中成文的表达式都返回布尔值(真/假)结果。 + 本节描述PostgreSQL中可用的SQL兼容的子查询表达式。本节介绍的所有表达式形式都返回布尔值(真/假)结果。 @@ -46,7 +46,7 @@ EXISTS (subquery) - 子查询可以引用来自周围的查询的变量,这些变量在该子查询的任何一次计算中都起常量的作用。 + 子查询可以引用外层查询的变量,这些变量在该子查询的任何一次计算中都起常量的作用。 @@ -59,7 +59,7 @@ EXISTS (subquery) - 下面这个简单的示例类似在col2上的一次内联接,但是它为每个 tab1的行生成最多一个输出,即使存在多个匹配tab2的行也如此∶ + 下面这个简单的示例类似在col2上的一次内连接,但是它为每个 tab1的行最多生成一行输出,即使存在多个匹配tab2的行也如此: SELECT col1 FROM tab1 @@ -76,15 +76,15 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 右手边是一个圆括弧括起来的子查询, 它必须正好只返回一个列。左手边表达式将被计算并与子查询结果逐行进行比较。 如果找到任何等于子查询行的情况,那么IN的结果就是。 如果没有找到相等行,那么结果是(包括子查询没有返回任何行的情况)。 + 右手边是一个圆括号括起来的子查询,它必须恰好返回一列。左手边表达式会被求值,并与子查询结果逐行比较。如果找到任意相等的子查询行,那么IN的结果就是。如果没有找到相等行,那么结果就是(包括子查询不返回任何行的情况)。 - 请注意如果左手边表达式得到空值,或者没有相等的右手边值, 并且至少有一个右手边行得到空值,那么IN结构的结果将是空值,而不是假。这个行为是遵照 SQL 处理空值的一般规则的。 + 请注意,如果左侧表达式得到空值,或者右侧没有相等的值且至少有一行得到空值,则IN结构的结果将是空值,而不是假。这符合 SQL 对空值布尔组合的一般规则。 - 和EXISTS一样,假设子查询将被完成运行完全是不明智的。 + 和EXISTS一样,假定子查询一定会完整运行并不明智。 @@ -92,7 +92,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 这种形式的IN的左手边是一个行构造器, 如中所述。 右手边是一个圆括弧子查询,它必须返回和左手边返回的行中表达式所构成的完全一样多的列。 左手边表达式将被计算并与子查询结果逐行进行比较。如果找到任意相等的子查询行,则IN的结果为。如果没有找到相等行, 那么结果为(包括子查询不返回行的情况)。 + 这种形式的IN左手边是一个行构造器,如中所述。右手边是一个圆括号括起来的子查询,它必须返回与左手边行中表达式数量完全相同的列数。左手边表达式会被求值,并与子查询结果逐行比较。如果找到任意相等的子查询行,则IN的结果为。如果没有找到相等行,那么结果为(包括子查询不返回任何行的情况)。 @@ -108,15 +108,15 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 右手边是一个用圆括弧包围的子查询,它必须返回正好一个列。左手边表达式将被计算并与子查询结果逐行进行比较。 如果只找到不相等的子查询行(包括子查询不返回行的情况),那么NOT IN的结果是。 如果找到任何相等行,则结果为。 + 右手边是一个圆括号括起来的子查询,它必须恰好返回一列。左手边表达式会被求值,并与子查询结果逐行比较。如果只找到不相等的子查询行(包括子查询不返回任何行的情况),那么NOT IN的结果是。如果找到任何相等行,则结果为 - 请注意如果左手边表达式得到空值,或者没有相等的右手边值, 并且至少有一个右手边行得到空值,那么NOT IN结构的结果将是空值,而不是真。这个行为是遵照 SQL 处理空值的一般规则的。 + 请注意,如果左侧表达式得到空值,或者右侧没有相等的值且至少有一行得到空值,则NOT IN结构的结果将是空值,而不是真。这符合 SQL 对空值布尔组合的一般规则。 - 和EXISTS一样,假设子查询将被完成运行完全是不明智的。 + 和EXISTS一样,假定子查询一定会完整运行并不明智。 @@ -124,7 +124,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 这种形式的NOT IN的左手边是一个行构造器, 如中所述。 右手边是一个圆括弧子查询,它必须返回和左手边返回的行中表达式所构成的完全一样多的列。 左手边表达式将被计算并与子查询结果逐行进行比较。如果找到不等于子查询行的行,则NOT IN的结果为。如果找到相等行, 那么结果为(包括子查询不返回行的情况)。 + 这种形式的NOT IN左侧是一个行构造器,如中所述。右侧是一个用圆括号括起来的子查询,必须返回与左侧行中表达式数量完全相同的列数。对左侧表达式求值后,将其按行与子查询结果的每一行比较。如果只找到不相等的子查询行(包括子查询不返回任何行的情况),则NOT IN的结果为。如果找到任何相等行,则结果为 @@ -142,7 +142,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 这种形式的右侧是一个用括号括起来的子查询,它必须恰好返回一列。左侧表达式会被求值,并使用给定的 operator 与子查询结果的每一行进行比较。如果得到任何真值结果,那么ANY的结果就是。如果没有找到真值结果,那么结果是(包括子查询没有返回任何行的情况)。 + 这种形式的右侧是一个用括号括起来的子查询,它必须恰好返回一列。左侧表达式会被求值,并使用给定的 operator 与子查询结果的每一行进行比较。该操作符必须产生布尔结果。如果得到任何真值结果,那么ANY的结果就是。如果没有找到真值结果,那么结果是(包括子查询没有返回任何行的情况)。 @@ -150,11 +150,11 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 请注意如果没有任何成功并且至少有一个右手边行为该操作符结果生成空值, 那么ANY结构的结果将是空值,而不是假。 这个行为是遵照 SQL 处理空值布尔组合的一般规则制定的。 + 请注意,如果没有任何比较返回真,并且至少有一个右侧行的操作符结果为空值,则ANY结构的结果将是空值,而不是假。这符合 SQL 对空值布尔组合的一般规则。 - 和EXISTS一样,假设子查询将被完成运行完全是不明智的。 + 和EXISTS一样,假定子查询一定会完整运行并不明智。 @@ -163,7 +163,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 这种形式的左侧是一个行构造器,如所述。右侧是一个用括号括起来的子查询,它必须返回与左侧行中表达式数量完全相同的列数。左侧表达式会被求值,并使用给定的operator与子查询结果的每一行逐行比较。如果比较对任何子查询行返回真,则ANY的结果为。如果比较对每一个子查询行都返回假,则结果为(包括子查询不返回行的情况)。如果比较对任何行都不返回真,并且至少有一次比较返回 NULL,则结果为 NULL。 + 这种形式的ANY左侧是一个行构造器,如所述。右侧是一个用括号括起来的子查询,它必须返回与左侧行中表达式数量完全相同的列数。左侧表达式会被求值,并使用给定的operator与子查询结果的每一行逐行比较。如果比较对任何子查询行返回真,则ANY的结果为。如果比较对每一个子查询行都返回假,则结果为(包括子查询不返回行的情况)。如果比较对任何行都不返回真,并且至少有一次比较返回 NULL,则结果为 NULL。 @@ -179,7 +179,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 这种形式的 ALL 右侧是一个用括号括起来的子查询,它必须只返回一列。左侧表达式会被求值,并使用给定的 operator 与子查询结果的每一行进行比较。该操作符必须产生布尔结果。如果所有行都得到真(包括子查询没有返回任何行的情况),ALL 的结果就是。如果发现任何假值结果,结果就是。如果比较对任何行都不返回假,并且至少有一次比较返回 NULL,则结果为 NULL。 + 右侧是一个用圆括号括起来的子查询,必须恰好返回一列。左侧表达式会被求值,并使用给定的operator与子查询结果的每一行进行比较。该操作符必须产生布尔结果。如果所有行都得到真(包括子查询不返回任何行的情况),则ALL的结果为。如果得到任何假值结果,则结果为。如果与任何子查询行的比较都不返回假,并且至少有一次比较返回 NULL,则结果为 NULL。 @@ -187,7 +187,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 和EXISTS一样,假设子查询将被完成运行完全是不明智的。 + 和EXISTS一样,假定子查询一定会完整运行并不明智。 @@ -217,7 +217,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 左手边是一个行构造器,如所述。 右手边是一个圆括弧括起来的子查询,该查询必须返回和左手边行中表达式数目完全一样的列。 另外,该子查询不能返回超过一行的数量(如果它返回零行,那么结果就是空值)。 左手边被计算并逐行与右手边的子查询结果行比较。 + 左侧是一个行构造器,如所述。右侧是一个用圆括号括起来的子查询,必须返回与左侧行中表达式数量完全相同的列数。此外,该子查询不能返回超过一行;如果它返回零行,则结果为空值。对左侧求值后,将所得的行与子查询返回的唯一一行进行比较。 diff --git a/zh/19/func/func-textsearch.sgml b/zh/19/func/func-textsearch.sgml index ba8bcb87..56953a63 100644 --- a/zh/19/func/func-textsearch.sgml +++ b/zh/19/func/func-textsearch.sgml @@ -3,7 +3,7 @@ 文本搜索函数和操作符 - 全文搜索 + 全文检索 函数和操作符 @@ -16,7 +16,7 @@ 以及 - 总结了为全文搜索提供的函数和操作符。PostgreSQL的文本搜索功能的详细解释可参考。 + 总结了为全文检索提供的函数和操作符。PostgreSQL的文本搜索功能的详细解释可参考 @@ -78,11 +78,11 @@ tsvector - 连接两个tsvector。如果两个输入都包含词素位置,则相应地调整第二个输入的位置。 + 连接两个tsvector。如果两个输入都包含词位位置,则相应地调整第二个输入的位置。 'a:1 b:2'::tsvector || 'c:1 d:2 b:3'::tsvector - 'a':1'b':2,5'c':3'd':4 + 'a':1 'b':2,5 'c':3 'd':4 @@ -120,7 +120,7 @@ tsquery - 否定tsquery,生成一个与输入查询不匹配的匹配文档的查询。 + 对tsquery取反,生成匹配那些不满足输入查询的文档的查询。 !! 'cat'::tsquery @@ -134,7 +134,7 @@ tsquery - 构造一个短语查询,如果两个输入查询在连续的词素上匹配,该查询将进行匹配。 + 构造一个短语查询;当两个输入查询分别匹配相邻的词位时,该查询匹配。 to_tsquery('fat') <-> to_tsquery('rat') @@ -148,7 +148,7 @@ boolean - 第一个tsquery包含了第二个吗?(这只考虑出现在一个查询中的所有词素是否出现在另一个查询中,忽略了组合操作符。) + 第一个tsquery包含了第二个吗?(这只考虑出现在一个查询中的所有词位是否出现在另一个查询中,忽略了组合操作符。) 'cat'::tsquery @> 'cat & rat'::tsquery @@ -162,7 +162,7 @@ boolean - 第一个tsquery包含在第二个中吗?(这只考虑出现在一个查询中的所有词素是否出现在另一个查询中,而忽略了组合操作符。) + 第一个tsquery包含在第二个中吗?(这只考虑出现在一个查询中的所有词位是否出现在另一个查询中,而忽略了组合操作符。) 'cat'::tsquery <@ 'cat & rat'::tsquery @@ -179,7 +179,7 @@ 除了这些专用操作符之外, 中所示的常用比较操作符也适用于tsvectortsquery类型。 - 它们对于文本搜索不是很有用,但是允许使用。例如,建在这些类型列上的唯一索引。 + 这些操作符对文本搜索用处不大,但可以用于其他用途,例如在这些类型的列上建立唯一索引。
@@ -213,7 +213,7 @@ 将文本字符串数组转换为tsvector。 - 给定的字符串被直接用作词元,不经过进一步处理。数组元素不得为空字符串 + 给定的字符串被直接用作词位,不经过进一步处理。数组元素不得为空字符串 或NULL @@ -284,8 +284,7 @@ tsquery - 将文本转换为tsquery,根据指定的或默认配置对单词进行标准化。 - 字符串中的任何标点符号都会被忽略(它不决定查询操作符)。结果查询匹配文本中包含所有非停止词的文档。 + 将文本转换为tsquery,根据指定的或默认配置对单词进行正规化。字符串中的任何标点符号都会被忽略(它们不决定查询操作符)。生成的查询匹配包含文本中所有非停用词的文档。 plainto_tsquery('english', 'The Fat Rats') @@ -304,8 +303,8 @@ tsquery - 将文本转换为tsquery,根据指定的或默认配置对单词进行标准化。 - 字符串中的任何标点符号都会被忽略(它不决定查询操作符)。结果查询匹配包含文本中所有非停止词的短语。 + 将文本转换为tsquery,根据指定的或默认配置对单词进行正规化。 + 字符串中的任何标点符号都会被忽略(它不决定查询操作符)。结果查询匹配包含文本中所有非停用词的短语。 phraseto_tsquery('english', 'The Fat Rats') @@ -328,8 +327,7 @@ tsquery - 将文本转换为tsquery,根据指定的或默认配置对单词进行标准化。引用的单词序列被转换为短语测试。 - or一词被理解为产生OR操作符,而破折号产生NOT操作符;其他标点符号被忽略。这类似于一些常见的网络搜索工具的行为。 + 将文本转换为tsquery,根据指定的或默认配置对单词进行正规化。带引号的单词序列被转换为短语测试。or一词产生 OR 操作符,短横线产生 NOT 操作符;其他标点符号会被忽略。这类似于一些常见网络搜索工具的行为。 websearch_to_tsquery('english', '"fat rat" or cat dog') @@ -375,14 +373,13 @@ setweight - 为特定词元设置权重 + 为特定词位设置权重 setweight ( vector tsvector, weight "char", lexemes text[] ) tsvector - 为vector中列出的lexemes赋予指定的weight。 - lexemes中的字符串被视为词元,不经过进一步处理。不匹配vector中任何词元的字符串将被忽略。 + 为vector中列在lexemes内的元素赋予指定的weightlexemes中的字符串按原样用作词位,不经过进一步处理。不匹配vector中任何词位的字符串将被忽略。 setweight('fat:2,4 cat:3 rat:5,6B'::tsvector, 'A', '{cat,rat}') @@ -418,7 +415,7 @@ tsquery - 将文本转换为tsquery,根据指定的或默认配置对单词进行标准化。单词必须由有效的tsquery操作符组合。 + 将文本转换为tsquery,根据指定的或默认配置对单词进行正规化。单词必须由有效的tsquery操作符组合。 to_tsquery('english', 'The & Fat & Rats') @@ -437,7 +434,7 @@ tsvector - 将文本转换为tsvector,根据指定的或默认配置对单词进行标准化。结果中包含位置信息。 + 将文本转换为tsvector,根据指定的或默认配置对单词进行正规化。结果中包含位置信息。 to_tsvector('english', 'The Fat Rats') @@ -459,9 +456,7 @@ tsvector - 将JSON文档中的每个字符串值转换为tsvector,根据指定的或默认配置对单词进行标准化。 - 然后将结果按文档顺序连接起来以产生输出。位置信息就像在每对字符串值之间存在一个停止词一样生成。 - (注意,当输入为jsonb时,JSON对象的字段的document order取决于实现;请观察这些示例中的差异。) + 将 JSON 文档中的每个字符串值转换为tsvector,根据指定的或默认配置对单词进行正规化。然后将结果按文档顺序连接起来以产生输出。生成位置信息时,视为每对字符串值之间存在一个停用词。(注意,当输入为jsonb时,JSON 对象字段的文档顺序取决于具体实现;请注意这些示例中的差异。) to_tsvector('english', '{"aa": "The Fat Rats", "b": "dog"}'::json) @@ -495,15 +490,15 @@ tsvector - 选择filter请求的JSON文档中的每个项,并将每个项转换为tsvector,根据指定的或默认配置对单词进行标准化。 - 然后将结果按文档顺序连接起来以产生输出。位置信息就像在每对选定的项目之间存在一个停止词一样生成。 - (注意,当输入为jsonb时,JSON对象字段的document order取决于实现。) - filter必须是一个jsonb数组,其中包含0个或多个关键字: + 选择filter请求的JSON文档中的每个项,并将每个项转换为tsvector,根据指定的或默认配置对单词进行正规化。 + 然后将结果按文档顺序连接起来以产生输出。位置信息就像在每对选定的项目之间存在一个停用词一样生成。 + (注意,当输入为jsonb时,JSON对象字段的文档顺序取决于实现。) + filter必须是一个jsonb数组,其中包含0个或多个关键字: "string"(包括所有字符串值), "numeric"(包括所有数值), "boolean"(包括所有布尔值), "key"(包括所有键),或 - "all"(包括以上所有关键字)。 + "all"(包括以上所有内容)。 作为一种特殊情况,该filter也可以是这些关键字之一的简单JSON值。 @@ -525,8 +520,8 @@ tsvector - 从vector中删除给定的lexeme的任何出现。 - lexeme字符串被视为原样的词元,不经过进一步处理。 + 从vector中删除给定的lexeme的所有出现。 + lexeme字符串被视为原样的词位,不经过进一步处理。 ts_delete('fat:2,4 cat:3 rat:5A'::tsvector, 'fat') @@ -540,9 +535,7 @@ tsvector - 从vector中删除lexemes中的任何出现。 - lexemes中的字符串被视为词元,不经过进一步处理。 - 不匹配vector中任何词元的字符串将被忽略。 + 从vector中删除lexemes所列词位的所有出现。lexemes中的字符串按原样用作词位,不经过进一步处理。不匹配vector中任何词位的字符串将被忽略。 ts_delete('fat:2,4 cat:3 rat:5A'::tsvector, ARRAY['fat','rat']) @@ -580,9 +573,7 @@ text - 以缩写形式显示documentquery的匹配项,该匹配项必须是原始文本,而不是tsvector。 - 在匹配查询之前,文档中的单词将根据指定的或默认的配置进行规范化。 - 中讨论了该函数的使用,还描述了可用的options。 + 以缩略形式显示querydocument中的匹配项;后者必须是原始文本,不能是tsvector。在匹配查询之前,文档中的单词将根据指定的或默认配置进行正规化。中讨论了该函数的使用,还描述了可用的options ts_headline('The fat cat ate the rat.', 'cat') @@ -608,8 +599,7 @@ text - 以缩写形式显示匹配JSONdocument中字符串值中的query。 - 更多细节请参阅 。 + 以缩略形式显示query在 JSON document字符串值中的匹配项。更多细节请参见 ts_headline('{"cat":"raining cats and dogs"}'::jsonb, 'cat') @@ -687,8 +677,7 @@ tsquery - 根据目标替换部分query,并替换通过执行SELECT命令获得的查询。 - 详情参见。 + 根据执行SELECT命令得到的目标和替换项,替换query中的相应部分。详情参见 SELECT ts_rewrite('a & b'::tsquery, 'SELECT t,s FROM aliases') @@ -719,7 +708,7 @@ tsquery - 构造一个短语查询,用于搜索query1query2的匹配项,这些匹配项恰好出现在distance词位之间。 + 构造一个短语查询,用于搜索query1query2的匹配项,其匹配位置恰好相距distance个词位。 tsquery_phrase(to_tsquery('fat'), to_tsquery('cat'), 10) @@ -748,7 +737,7 @@ unnest - for tsvector + 用于 tsvector unnest ( tsvector ) setof record @@ -778,7 +767,7 @@ - 所有接受一个可选的regconfig参数的文本搜索函数在该参数被忽略时,使用由指定的配置。 + 所有接受一个可选的regconfig参数的文本搜索函数在省略该参数时,会使用由指定的配置。 @@ -825,7 +814,7 @@ lexemes text[] ) - 根据指定的或默认的文本搜索配置从document中提取和标准化标记,并返回关于每个标记是如何处理的信息。 + 根据指定的或默认的文本搜索配置从document中提取和正规化词元,并返回关于每个词元是如何处理的信息。 详情参见 @@ -843,8 +832,7 @@ text[] - 如果字典知道输入标记,则返回替换词位数组;如果字典知道标记,但它是停止词,则返回空数组;如果它不是已知词,则返回NULL。 - 详情参见。 + 如果词典识别输入词元,则返回由替换词位组成的数组;如果词典识别该词元,但它是停用词,则返回空数组;如果词典无法识别该词元,则返回NULL。详情参见 ts_lexize('english_stem', 'stars') @@ -864,7 +852,7 @@ token text ) - 使用命名的解析器从document中提取标记。详情参见。 + 使用指定名称的解析器从document中提取词元。详情参见 ts_parse('default', 'foo - bar') @@ -881,7 +869,7 @@ token text ) - 使用 OID 指定的解析器从document中提取标记。 + 使用 OID 指定的解析器从document中提取词元。 详情参见 @@ -902,7 +890,7 @@ description text ) - 返回一个表,该表描述命名解析器可以识别的每种类型的标记。详情参见。 + 返回一个表,该表描述指定名称的解析器可以识别的每种类型的词元。详情参见 ts_token_type('default') @@ -919,7 +907,7 @@ description text ) - 返回一个表,该表描述 OID 指定的解析器可以识别的每种标记类型。详情参见。 + 返回一个表,该表描述 OID 指定的解析器可以识别的每种词元类型。详情参见 ts_token_type(3722) @@ -940,7 +928,7 @@ nentry integer ) - 执行sqlquery,该查询必须返回单个tsvector列,并返回数据中每个不同词元的统计信息。 + 执行sqlquery,该查询必须返回单个tsvector列,并返回数据中每个不同词位的统计信息。 详情参见 diff --git a/zh/19/func/func-trigger.sgml b/zh/19/func/func-trigger.sgml index 880b45aa..d4ed0d0b 100644 --- a/zh/19/func/func-trigger.sgml +++ b/zh/19/func/func-trigger.sgml @@ -42,7 +42,7 @@ trigger - 阻止不做事的更新操作。详见下文。 + 抑制不改变数据的更新操作。详见下文。 CREATE TRIGGER ... suppress_redundant_updates_trigger() @@ -58,8 +58,7 @@ trigger - 自动从相关的纯文本文档列更新tsvector列。 - 要使用的文本搜索配置是以名称指定为触发器参数。详情请参见。 + 根据关联的纯文本文档列自动更新tsvector列。所用的全文检索配置以名称形式指定为触发器参数。详见 CREATE TRIGGER ... tsvector_update_trigger(tsvcol, 'pg_catalog.swedish', title, body) @@ -75,8 +74,7 @@ trigger - 自动从相关的纯文本文档列更新tsvector列。 - 要使用的文本搜索配置取自表的regconfig列。详情请参见。 + 根据关联的纯文本文档列自动更新tsvector列。所用的全文检索配置取自表的regconfig列。详见 CREATE TRIGGER ... tsvector_update_trigger_column(tsvcol, tsconfigcol, title, body) @@ -93,23 +91,15 @@ - 理想的情况下,你应该避免运行实际上并没有改变记录中数据的更新。 - 冗余更新会花费大量不必要的时间,尤其是如果有大量索引要改变, 并将最终不得不清理被死亡行占用的空间。 - 但是,在客户端代码中检测这种情况并不总是容易的,甚至不可能做到。 而写表达式来检测它们容易产生错误。 - 作为替代,使用suppress_redundant_updates_trigger可以跳过不改变数据的更新。 但是,你需要小心使用它。 - 触发器需要很短但不能忽略的时间来处理每条记录,所以如果受更新影响的大多数记录确实变化了,此触发器的使用将使更新比平均水平运行得更慢。 + 理想情况下,应避免执行实际上不会改变记录中数据的更新。冗余更新会耗费大量不必要的时间,尤其是在需要修改许多索引时;它们还会使死行占用空间,最终需要通过清理回收。但是,在客户端代码中检测这种情况并不总是容易,甚至可能无法做到,而编写用于检测的表达式也容易出错。另一种办法是使用suppress_redundant_updates_trigger,跳过不改变数据的更新。但使用时应当谨慎。此触发器处理每条记录的耗时虽小,却不可忽略,因此如果更新涉及的大多数记录确实会改变,使用此触发器反而会增加更新的平均耗时。 - suppress_redundant_updates_trigger函数可以像这样添加到表中: - + 该suppress_redundant_updates_trigger函数可以按如下方式添加到表中: CREATE TRIGGER z_min_update BEFORE UPDATE ON tablename FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); - - 在大多数情况下,你需要为每一行最后触发这个触发器,这样它就不会覆盖可能希望更改该行的其他触发器。 - 请记住,触发器是按照名称顺序触发的,你将为此选择一个触发器名称,该名称位于表中可能存在的任何其他触发器的名称之后。 - (因此在示例中使用了z前缀。) +大多数情况下,需要让该触发器对每一行最后触发,以免覆盖其他可能修改该行的触发器的效果。由于触发器按名称顺序触发,应选择一个排序位于表上其他所有触发器名称之后的名称。(这就是示例中使用z前缀的原因。) diff --git a/zh/19/func/func-uuid.sgml b/zh/19/func/func-uuid.sgml index 5dd69b3e..0ec7d5c2 100644 --- a/zh/19/func/func-uuid.sgml +++ b/zh/19/func/func-uuid.sgml @@ -174,8 +174,7 @@
- PostgreSQL也为 UUID 提供了 - 中展示的常用比较操作符。 + PostgreSQL也为 UUID 提供了中展示的常用比较操作符。 关于PostgreSQLuuid数据类型的细节,请参见 diff --git a/zh/19/func/func-window.sgml b/zh/19/func/func-window.sgml index d0d73ebb..c55d42c9 100644 --- a/zh/19/func/func-window.sgml +++ b/zh/19/func/func-window.sgml @@ -17,7 +17,7 @@ - 除了这些函数之外,任何内置的或用户定义的普通聚合(例如非有序集或假想集聚合)都可以作为窗口函数使用;关于内置聚合的列表,参见。 + 除了这些函数之外,任何内置的或用户定义的普通聚合(即不属于有序集或假想集聚合)都可以作为窗口函数使用;关于内置聚合的列表,参见。 聚合函数只有在调用后带有OVER子句时才作为窗口函数;否则,它们就是普通聚合,并为整个结果集返回一行。 @@ -48,7 +48,7 @@ bigint
- 返回其分区内的当前行数,从1开始计数。 + 返回当前行在其分区内的编号,从 1 开始计数。 @@ -61,7 +61,7 @@ bigint
- 返回当前行的排名,包含间隔;即同等行组中第一行的row_number。 + 返回当前行的排名,允许空缺;即同等行组中第一行的row_number @@ -74,7 +74,7 @@ bigint
- 返回当前行的排名,不包括间隔;这个功能有效地计数同等行组。 + 返回当前行的排名,没有空缺;此函数实际上对同等行组进行计数。 @@ -113,7 +113,7 @@ integer
- 返回一个从1到参数值的整数,并将分区划分为尽可能相等的值。 + 返回从 1 到参数值的整数,将分区尽可能均等地划分。 @@ -128,9 +128,7 @@ anycompatible
- 返回分区中在当前行之前offset行的value;如果没有这样的行,则返回default(必须与value相兼容的类型)。 - offsetdefault都是针对当前行求值的。 - 如果省略,offset默认为1,defaultNULL。 + 返回在分区内当前行之前offset行处计算的value;如果没有这样的行,则返回default(其类型必须与value兼容)。offsetdefault都针对当前行求值。如果省略,offset默认为 1,default默认为NULL @@ -145,10 +143,7 @@ anycompatible
- 返回分区中在当前行之后offset行的value; - 如果没有这样的行,则返回default(必须与value兼容的类型)。 - offsetdefault都是针对当前行求值的。 - 如果省略,offset默认为1,defaultNULL。 + 返回在分区内当前行之后offset行处计算的value;如果没有这样的行,则返回default(其类型必须与value兼容)。offsetdefault都针对当前行求值。如果省略,offset默认为 1,default默认为NULL @@ -203,14 +198,14 @@ 注意first_valuelast_valuenth_value只考虑窗口帧内的行,它默认情况下包含从分区的开始行直到当前行的最后一个同等行。 这对last_value可能不会给出有用的结果,有时对nth_value也一样。 - 你可以通过向OVER子句增加一个合适的帧声明(RANGEGROUPS)来重定义帧。 + 你可以通过向OVER子句增加一个合适的帧声明(RANGEROWSGROUPS)来重定义帧。 关于帧声明的更多信息请参考 当一个聚合函数被用作窗口函数时,它将在当前行的窗口帧内的行上聚合。 - 一个使用ORDER BY和默认窗口帧定义的聚合产生一种运行时求和类型的行为,这可能是或者不是想要的结果。 - 为了获取在整个分区上的聚合,忽略ORDER BY或者使用ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING。 + 一个使用ORDER BY和默认窗口帧定义的聚合产生一种累计求和类型的行为,这可能是或者不是想要的结果。 + 为了获取在整个分区上的聚合,省略ORDER BY或者使用ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING。 其它窗口帧声明可以用来获得其它的效果。 diff --git a/zh/19/func/func-xml.sgml b/zh/19/func/func-xml.sgml index b2f675fe..28e7e31f 100644 --- a/zh/19/func/func-xml.sgml +++ b/zh/19/func/func-xml.sgml @@ -458,7 +458,7 @@ SELECT xmlexists('//town[text() = ''Toronto'']' PASSING BY VALUE 'T
- 示例: + 示例: - 示例: + 示例: test', ARRAY[ARRAY['my', 'http://example.com']]); @@ -575,7 +575,7 @@ SELECT xpath('//mydefns:b/text()', 'test - 示例: + 示例: test', ARRAY[ARRAY['my', 'http://example.com']]); @@ -627,8 +627,8 @@ SELECT xpath_exists('/my:a/text()', 'test - document_expression提供了上下文。row_expression的项。 - 它必须是一个格式良好的XML文档;不接受片段/森林。BY REFBY VALUE子句 如上文所讨论的那样,被接受但被忽略了,正如在中所讨论的。 + document_expressionrow_expression提供上下文项。 + 它必须是一个良构的 XML 文档;不接受内容片段或森林。BY REFBY VALUE子句会被接受,但会被忽略,如中所述。 @@ -677,7 +677,7 @@ SELECT xpath_exists('/my:a/text()', 'test - 一个XML元素的字符串值是字符串值的协整,按文档的顺序。该元素中包含的所有文本节点及其子节点。字符串 元素的值是一个没有下级文本节点的元素的值是一个 空字符串(不是NULL)。任何xsi:nil属性都会被忽略。请注意,两个非文本之间的text()节点只用空格,而两个非文本 元素,并且保留了text()上的前导白格。节点不被扁平化。XPath 1.0中的string函数可以参考XPath 1.0中的 定义其他XML节点类型和非XML值的字符串值的规则。 + 一个 XML 元素的字符串值,是该元素及其所有后代中包含的文本节点按文档顺序拼接而成的字符串。没有后代文本节点的元素,其字符串值为空字符串(不是 NULL)。所有 xsi:nil 属性都会被忽略。注意,两个非文本元素之间仅含空白的 text() 节点会被保留,text() 节点的前导空白也不会被折叠。其他 XML 节点类型及非 XML 值的字符串值定义规则,可参考 XPath 1.0 的 string 函数。 @@ -697,7 +697,7 @@ SELECT xpath_exists('/my:a/text()', 'test - 示例: + 示例: - 下面的示例展示了多个text()节点的连接,列名作为XPath过滤器的使用,以及对空格、XML注释和处理指令的处理: + 下面的示例展示了多个text()节点的连接,列名作为XPath过滤器的使用,以及对空格、XML注释和处理指令的处理: Code Targets", + "chinese": "代码构建目标" + }, + { + "english": "Developer Targets", + "chinese": "开发目标" + }, + { + "english": "Documentation Targets", + "chinese": "文档构建目标" + }, + { + "english": "Installation Targets", + "chinese": "安装目标" + }, + { + "english": "Other Targets", + "chinese": "其他目标" + }, + { + "english": "Build everything other than documentation", + "chinese": "构建文档以外的所有内容" + }, + { + "english": "Build backend and related modules", + "chinese": "构建后端及相关模块" + }, + { + "english": "Build frontend binaries", + "chinese": "构建前端二进制程序" + }, + { + "english": "Build contrib modules", + "chinese": "构建 contrib 模块" + }, + { + "english": "Build procedural languages", + "chinese": "构建过程语言" + }, + { + "english": "Rewrite catalog data files into standard format", + "chinese": "将系统目录数据文件改写为标准格式" + }, + { + "english": "Expand all data files to include defaults", + "chinese": "展开所有数据文件以包含默认值" + }, { "english": "Update Unicode data to new version", "chinese": "将 Unicode 数据更新到新版本" @@ -54,6 +102,78 @@ { "english": "Check that all headers compile as C++", "chinese": "检查所有头文件能否作为 C++ 编译" + }, + { + "english": "Build documentation in multi-page HTML format", + "chinese": "构建多页 HTML 格式的文档" + }, + { + "english": "Build documentation in man page format", + "chinese": "构建手册页格式的文档" + }, + { + "english": "Build documentation in multi-page HTML and man page format", + "chinese": "构建多页 HTML 和手册页格式的文档" + }, + { + "english": "Build documentation in PDF format, with A4 pages", + "chinese": "构建 A4 页面大小的 PDF 格式文档" + }, + { + "english": "Build documentation in PDF format, with US letter pages", + "chinese": "构建 US letter 页面大小的 PDF 格式文档" + }, + { + "english": "Build documentation in single-page HTML format", + "chinese": "构建单页 HTML 格式的文档" + }, + { + "english": "Build documentation in all supported formats", + "chinese": "构建所有支持格式的文档" + }, + { + "english": "Install postgres, excluding documentation", + "chinese": "安装 postgres,不包括文档" + }, + { + "english": "Install documentation in multi-page HTML and man page formats", + "chinese": "安装多页 HTML 和手册页格式的文档" + }, + { + "english": "Install documentation in multi-page HTML format", + "chinese": "安装多页 HTML 格式的文档" + }, + { + "english": "Install documentation in man page format", + "chinese": "安装手册页格式的文档" + }, + { + "english": "Like \"install\", but installed files are not displayed", + "chinese": "与“install”相同,但不显示安装的文件" + }, + { + "english": "Install postgres, including multi-page HTML and man page documentation", + "chinese": "安装 postgres,包括多页 HTML 和手册页格式的文档" + }, + { + "english": "Remove installed files", + "chinese": "删除已安装的文件" + }, + { + "english": "Remove all build products", + "chinese": "删除所有构建产物" + }, + { + "english": "Run all enabled tests (including contrib)", + "chinese": "运行所有已启用的测试(包括 contrib)" + }, + { + "english": "Build everything, including documentation", + "chinese": "构建所有内容,包括文档" + }, + { + "english": "List important targets", + "chinese": "列出重要的目标" } ] } diff --git a/zh/19/gin.sgml b/zh/19/gin.sgml index d96ea757..1b83d342 100644 --- a/zh/19/gin.sgml +++ b/zh/19/gin.sgml @@ -53,7 +53,7 @@ 内置操作符类 - PostgreSQL 核心发布包含 + PostgreSQL 核心发行版包含 所示的 GIN 操作符类。 (在 中描述的一些可选模块还提供额外的 GIN 操作符类。) @@ -152,7 +152,7 @@ 给定一个要建立索引的项,返回一个用 palloc 分配的键数组。返回键的数量必须存入 *nkeys。如果任一键可以为 null,还要另外 palloc 一个包含 *nkeysbool 字段的数组,将其地址存入 - *nullFlags,并按需设置这些空值标志。如果所有键都非空, + *nullFlags,并按需设置这些空值标志。如果所有键都不是 null, *nullFlags 可以保持为 NULL(其初始值)。 如果该项不包含任何键,则返回值可以为 NULL @@ -172,7 +172,7 @@ query 的数据类型,以及应采用何种方法提取键值。返回键的数量必须存入 *nkeys。如果任一键可以为 null,还要另外 palloc 一个包含 *nkeysbool 字段的数组,将其地址存入 - *nullFlags,并按需设置这些空值标志。如果所有键都非空, + *nullFlags,并按需设置这些空值标志。如果所有键都不是 null, *nullFlags 可以保持为 NULL(其初始值)。 如果 query 不包含任何键,则返回值可以为 NULL @@ -185,7 +185,7 @@ 被设置为 GIN_SEARCH_MODE_INCLUDE_EMPTY,则除至少包含一个匹配键的项之外, 完全不含任何键的项也会被视为候选匹配。(例如,该模式对于实现是子集操作符很有用。) 若 *searchMode 被设置为 GIN_SEARCH_MODE_ALL, - 则索引中所有非空项都会被视为候选匹配,无论它们是否匹配任一返回键。 + 则索引中所有非 null 项都会被视为候选匹配,无论它们是否匹配任一返回键。 (该模式比前两种选择慢得多,因为它基本上需要扫描整个索引;但为了正确处理某些边界情况, 可能有此必要。在大多数情况下都需要此模式的操作符,大概并不适合作为 GIN 操作符类的候选。)用于设置该模式的符号定义在 @@ -218,7 +218,7 @@ 操作符类还必须提供一个函数,用于检查被索引项是否匹配查询。它有两种形式:布尔型 consistent 函数,以及三值型 triConsistent 函数。 triConsistent 覆盖了两者的功能,因此仅提供 triConsistent - 就已经足够。不过,如果布尔变体的计算明显更便宜,那么同时提供两者会更有利。 + 就已经足够。不过,如果布尔变体的计算代价明显更低,那么同时提供两者可能更有利。 若只提供布尔变体,则一些依赖于在取回所有键之前先排除索引项的优化将被禁用。 @@ -233,10 +233,10 @@ 该函数无法直接访问被索引项的值,因为 GIN 并不显式存储项。 它所能利用的是这样一种信息:从查询中提取出的哪些键值出现在给定的被索引项中。 check 数组长度为 nkeys,这与先前针对该 - query 数据由 extractQuery 返回的键数量相同。 + query datum 由 extractQuery 返回的键数量相同。 如果被索引项包含相应查询键,则 check 数组中的对应元素为 true; 也就是说,如果 check[i] == true,则 extractQuery - 结果数组中的第 i 个键存在于该被索引项中。传入原始 query 数据值, + 结果数组中的第 i 个键存在于该被索引项中。传入原始 query datum, 是为了让 consistent 方法在需要时可以查看它;同样也会传入先前由 extractQuery 返回的 queryKeys[]nullFlags[] 数组。extra_data 则是 @@ -274,7 +274,7 @@ 而 GIN_MAYBE 表示该键是否存在尚不确定。存在 GIN_MAYBE 值时,只有当无论索引项是否包含对应查询键,该项都确定匹配时,函数才应返回 GIN_TRUE。同样,只有当无论是否包含 GIN_MAYBE 键, - 该项都确定不匹配时,函数才必须返回 GIN_FALSE。如果结果依赖于 + 该项都确定不匹配时,函数才能返回 GIN_FALSE。如果结果依赖于 GIN_MAYBE 条目,也就是说,无法根据已知的查询键确认或否定匹配, 则函数必须返回 GIN_MAYBE @@ -306,7 +306,7 @@ 或者,如果操作符类没有提供 compare 方法,GIN 将查找该索引键数据类型的默认 B-树操作符类,并使用其比较函数。建议在仅面向单一数据类型的 - GIN 操作符类中显式指定比较函数,因为查找 B-树操作符类会消耗少量周期。 + GIN 操作符类中显式指定比较函数,因为查找 B-树操作符类会消耗少量处理器周期。 不过,多态 GIN 操作符类(例如 array_ops)通常无法指定单一比较函数。 @@ -376,8 +376,8 @@ 在内部,一个 GIN 索引包含一个基于键构建的 B-树索引,其中每个键都是一个或多个被索引项中的某个元素 - (例如数组成员),而叶子页中的每个元组要么包含一个指向堆指针 B-树的指针(posting tree), - 要么在列表足够小、能够连同键值一起放入单个索引元组时,直接包含一个简单的堆指针列表(posting list)。 + (例如数组成员),而叶子页中的每个元组要么包含一个指向堆指针 B-树的指针(倒排树), + 要么在列表足够小、能够连同键值一起放入单个索引元组时,直接包含一个简单的堆指针列表(倒排列表)。 展示了 GIN 索引的这些组成部分。 @@ -424,7 +424,7 @@ - 如果一致的响应时间比更新速度更重要,可以通过关闭 GIN 索引的 + 如果稳定的响应时间比更新速度更重要,可以通过关闭 GIN 索引的 fastupdate 存储参数来禁用待处理列表机制。详见 @@ -463,7 +463,7 @@ 当为 GIN 启用 fastupdate 时 (详见 ),这种代价会比未启用时小一些。 - 但对于非常大的更新,最好仍然是删除并重建索引。 + 但对于非常大的更新,删除并重建索引仍然可能是最佳选择。
@@ -531,7 +531,7 @@ GIN 假定可索引操作符是严格的。这意味着,当项值为 null 时, 根本不会对其调用 extractValue(而是自动创建一个占位符索引项); 当查询值为 null 时,也不会调用 extractQuery(而是认为该查询不可满足)。 - 不过要注意,非空组合项或查询值内部包含的 null 键值仍然受支持。 + 不过要注意,非 null 的组合项或查询值内部包含的 null 键值仍然受支持。 @@ -539,7 +539,7 @@ 示例 - PostgreSQL 核心发布包含前面在 + PostgreSQL 核心发行版包含前面在 中展示过的 GIN 操作符类。 下列 contrib 模块也包含 GIN 操作符类: diff --git a/zh/19/gist.sgml b/zh/19/gist.sgml index 2ba40641..47d1dfd1 100644 --- a/zh/19/gist.sgml +++ b/zh/19/gist.sgml @@ -4,7 +4,7 @@ GiST 索引 - index + 索引 GiST @@ -211,7 +211,7 @@ CREATE INDEX ON my_table USING GIST (my_inet_column inet_ops); - 这种可扩展性不应与其他标准搜索树在可处理数据方面的可扩展性相混淆。例如,PostgreSQL支持可扩展的 B-树和哈希索引。这意味着你可以用PostgreSQL在任意数据类型上构建 B-树或哈希索引。但 B-树只支持范围谓词(<=>),而哈希索引只支持等值查询。 + 这种可扩展性不应与其他标准搜索树在可处理数据方面的可扩展性相混淆。例如,PostgreSQL支持可扩展的 B-树和 hash 索引。这意味着你可以用PostgreSQL在任意数据类型上构建 B-树或 hash 索引。但 B-树只支持范围谓词(<=>),而 hash 索引只支持等值查询。 @@ -264,15 +264,14 @@ my_consistent(PG_FUNCTION_ARGS) bool retval; /* - * determine return value as a function of strategy, key and query. + * 根据 strategy、key 和 query 确定返回值。 * - * Use GIST_LEAF(entry) to know where you're called in the index tree, - * which comes handy when supporting the = operator for example (you could - * check for non empty union() in non-leaf nodes and equality in leaf - * nodes). + * 使用 GIST_LEAF(entry) 判断当前调用位于索引树的哪个位置。 + * 例如,支持 = 操作符时这很有用(可以在非叶节点检查 + * union() 是否非空,在叶节点检查是否相等)。 */ - *recheck = true; /* or false if check is exact */ + *recheck = true; /* 如果检查是精确的,则为 false */ PG_RETURN_BOOL(retval); } @@ -366,7 +365,7 @@ my_union(PG_FUNCTION_ARGS) - 如果被索引的数据类型与存储在索引中的数据类型不同,可以使用CREATE OPERATOR CLASS命令的STORAGE选项来定义索引中存储的数据类型。不过要注意,STORAGE数据类型只用于定义索引项的物理属性(它们的typlentypbyvaltypalign属性)。索引 数据值 中实际存放什么,由compressdecompress方法控制,只要存放的数据满足这些属性即可。只要叶子键与更高层索引页上的键都满足STORAGE数据类型,compress就可以为叶子键和其他键生成不同表示形式。 + 如果被索引的数据类型与存储在索引中的数据类型不同,可以使用CREATE OPERATOR CLASS命令的STORAGE选项来定义索引中存储的数据类型。不过要注意,STORAGE数据类型只用于定义索引项的物理属性(它们的typlentypbyvaltypalign属性)。索引 datum 中实际存放什么,由compressdecompress方法控制,只要存放的 datum 满足这些属性即可。只要叶子键与更高层索引页上的键都满足STORAGE数据类型,compress就可以为叶子键和其他键生成不同表示形式。 @@ -392,10 +391,10 @@ my_compress(PG_FUNCTION_ARGS) if (entry->leafkey) { - /* replace entry->key with a compressed version */ + /* 将 entry->key 替换为压缩后的形式 */ compressed_data_type *compressed_data = palloc_object(compressed_data_type); - /* fill *compressed_data from entry->key ... */ + /* 根据 entry->key 填充 *compressed_data ... */ retval = palloc_object(GISTENTRY); gistentryinit(*retval, PointerGetDatum(compressed_data), @@ -403,7 +402,7 @@ my_compress(PG_FUNCTION_ARGS) } else { - /* typically we needn't do anything with non-leaf entries */ + /* 通常无需对非叶项做任何处理 */ retval = entry; } @@ -466,7 +465,7 @@ my_decompress(PG_FUNCTION_ARGS) CREATE OR REPLACE FUNCTION my_penalty(internal, internal, internal) RETURNS internal AS 'MODULE_PATHNAME' -LANGUAGE C STRICT; -- in some cases penalty functions need not be strict +LANGUAGE C STRICT; -- 某些情况下 penalty 函数不必是严格函数 而 C 模块中的对应代码则可以遵循如下框架: @@ -488,7 +487,7 @@ my_penalty(PG_FUNCTION_ARGS) } - 出于历史原因,penalty函数并不是直接返回一个float结果;相反,它必须把该值存储到第三个参数指示的位置。返回值本身会被忽略,不过通常会返回该参数的地址。 + 出于历史原因,penalty函数并不是直接返回一个float结果;相反,它必须把该值存储到第三个参数指示的位置。返回值本身会被忽略,不过通常会返回该参数所指向的地址。 @@ -549,7 +548,7 @@ my_picksplit(PG_FUNCTION_ARGS) unionL = NULL; unionR = NULL; - /* Initialize the raw entry vector. */ + /* 初始化原始项向量。 */ raw_entryvec = (GISTENTRY **) malloc(entryvec->n * sizeof(void *)); for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) raw_entryvec[i] = &(entryvec->vector[i]); @@ -562,9 +561,9 @@ my_picksplit(PG_FUNCTION_ARGS) Assert(tmp_union != NULL); /* - * Choose where to put the index entries and update unionL and unionR - * accordingly. Append the entries to either v->spl_left or - * v->spl_right, and care about the counters. + * 选择索引项的存放位置,并相应更新 unionL 和 unionR。 + * 将项追加到 v->spl_left 或 v->spl_right, + * 同时更新计数器。 */ if (my_choice_is_left(unionL, curl, unionR, curr)) @@ -581,7 +580,7 @@ my_picksplit(PG_FUNCTION_ARGS) else { /* - * Same on the right + * 对右侧执行相同操作 */ } } @@ -635,7 +634,7 @@ my_same(PG_FUNCTION_ARGS) } - 出于历史原因,same函数并不是直接返回一个布尔结果;相反,它必须把该标志存储到第三个参数指示的位置。返回值本身会被忽略,不过通常会返回该参数的地址。 + 出于历史原因,same函数并不是直接返回一个布尔结果;相反,它必须把该标志存储到第三个参数指示的位置。返回值本身会被忽略,不过通常会返回该参数所指向的地址。
@@ -676,7 +675,7 @@ my_distance(PG_FUNCTION_ARGS) double retval; /* - * determine return value as a function of strategy, key and query. + * 根据 strategy、key 和 query 确定返回值。 */ PG_RETURN_FLOAT8(retval); @@ -687,11 +686,11 @@ my_distance(PG_FUNCTION_ARGS) - 在确定距离时允许有一定近似,只要结果永不大于该项的实际距离即可。因此,例如在几何应用中,到外包盒的距离通常就足够了。对于内部树节点,返回的距离不能大于其任一子节点的距离。如果返回的距离不精确,函数必须将*recheck设为 true。(对内部树节点则不必这样做;对它们总是假定计算结果不精确。)在这种情况下,执行器会在从堆中取出元组后计算准确距离,并在必要时重新排序这些元组。 + 在确定距离时允许有一定近似,只要结果永不大于该项的实际距离即可。因此,例如在几何应用中,到包围盒的距离通常就足够了。对于内部树节点,返回的距离不能大于其任一子节点的距离。如果返回的距离不精确,函数必须将*recheck设为 true。(对内部树节点则不必这样做;对它们总是假定计算结果不精确。)在这种情况下,执行器会在从堆中取出元组后计算准确距离,并在必要时重新排序这些元组。 - 如果距离函数对任何叶节点都返回*recheck = true,原始排序操作符的返回类型必须是float8float4,且距离函数的结果值必须能与原始排序操作符的结果进行比较,因为执行器会同时使用距离函数结果和重新计算得到的排序操作符结果进行排序。否则,距离函数的结果值可以是任意有限的float8值,只要这些结果值的相对顺序与排序操作符返回的顺序一致即可。(无穷大和负无穷在内部用于处理空值等情况,因此不建议distance函数返回这些值。) + 如果距离函数对任意一个叶节点返回*recheck = true,原始排序操作符的返回类型必须是float8float4,且距离函数的结果值必须能与原始排序操作符的结果进行比较,因为执行器会同时使用距离函数结果和重新计算得到的排序操作符结果进行排序。否则,距离函数的结果值可以是任意有限的float8值,只要这些结果值的相对顺序与排序操作符返回的顺序一致即可。(无穷大和负无穷在内部用于处理空值等情况,因此不建议distance函数返回这些值。) @@ -735,10 +734,10 @@ my_fetch(PG_FUNCTION_ARGS) fetched_data = palloc_object(fetched_data_type); /* - * Convert 'fetched_data' into the a Datum of the original datatype. + * 将 'fetched_data' 转换为原始数据类型的 Datum。 */ - /* fill *retval from fetched_data. */ + /* 根据 fetched_data 填充 *retval。 */ gistentryinit(*retval, PointerGetDatum(converted_datum), entry->rel, entry->page, entry->offset, FALSE); @@ -789,26 +788,26 @@ typedef enum MyEnumType typedef struct { - int32 vl_len_; /* varlena header (do not touch directly!) */ - int int_param; /* integer parameter */ - double real_param; /* real parameter */ - MyEnumType enum_param; /* enum parameter */ - int str_param; /* string parameter */ + int32 vl_len_; /* varlena 首部(不要直接操作!) */ + int int_param; /* 整数参数 */ + double real_param; /* 实数参数 */ + MyEnumType enum_param; /* 枚举参数 */ + int str_param; /* 字符串参数 */ } MyOptionsStruct; -/* String representation of enum values */ +/* 枚举值的字符串表示 */ static relopt_enum_elt_def myEnumValues[] = { {"on", MY_ENUM_ON}, {"off", MY_ENUM_OFF}, {"auto", MY_ENUM_AUTO}, - {(const char *) NULL} /* list terminator */ + {(const char *) NULL} /* 列表终止项 */ }; static char *str_param_default = "default"; /* - * Sample validator: checks that string is not longer than 8 bytes. + * 验证器示例:检查字符串长度不超过 8 字节。 */ static void validate_my_string_relopt(const char *value) @@ -820,7 +819,7 @@ validate_my_string_relopt(const char *value) } /* - * Sample filler: switches characters to lower case. + * 填充函数示例:将字符转换为小写。 */ static Size fill_my_string_relopt(const char *value, void *ptr) @@ -873,10 +872,9 @@ my_compress(PG_FUNCTION_ARGS) char *str_param = str_param_default; /* - * Normally, when opclass contains 'options' method, then options are always - * passed to support functions. However, if you add 'options' method to - * existing opclass, previously defined indexes have no options, so the - * check is required. + * 通常,操作符类包含 'options' 方法时,总会把选项传给支持函数。 + * 但是,如果把 'options' 方法添加到已有操作符类中, + * 先前定义的索引没有选项,因此需要进行检查。 */ if (PG_HAS_OPCLASS_OPTIONS()) { @@ -888,7 +886,7 @@ my_compress(PG_FUNCTION_ARGS) str_param = GET_STRING_RELOPTION(options, str_param); } - /* the rest implementation of support function */ + /* 支持函数的其余实现 */ } @@ -932,7 +930,7 @@ PG_FUNCTION_INFO_V1(my_sortsupport); static int my_fastcmp(Datum x, Datum y, SortSupport ssup) { - /* establish order between x and y by computing some sorting value z */ + /* 通过计算某个排序值 z 来确定 x 和 y 的顺序 */ int z1 = ComputeSpatialCode(x); int z2 = ComputeSpatialCode(y); @@ -957,7 +955,7 @@ my_sortsupport(PG_FUNCTION_ARGS) translate_cmptype - 给定一个来自src/include/access/cmptype.hCompareType值,返回该操作符类用于匹配功能的策略号。如果该操作符类没有匹配策略,函数应返回InvalidStrategy。 + 给定一个来自src/include/access/cmptype.hCompareType值,返回该操作符类中具有相应功能的策略号。如果该操作符类没有匹配策略,函数应返回InvalidStrategy @@ -1011,7 +1009,7 @@ my_translate_cmptype(PG_FUNCTION_ARGS) - PostgreSQL提供了一个翻译函数:gist_translate_cmptype_common,用于使用RT*StrategyNumber常量的操作符类。btree_gist扩展又定义了第二个翻译函数gist_translate_cmptype_btree,用于使用BT*StrategyNumber常量的操作符类。 + PostgreSQL提供了一个转换函数:gist_translate_cmptype_common,用于使用RT*StrategyNumber常量的操作符类。btree_gist扩展又定义了第二个转换函数gist_translate_cmptype_btree,用于使用BT*StrategyNumber常量的操作符类。 @@ -1030,7 +1028,7 @@ my_translate_cmptype(PG_FUNCTION_ARGS) GiST 索引构建方法 - 构建 GiST 索引最简单的方法就是把所有项逐个插入。这对于大型索引往往很慢,因为如果索引元组分散在整个索引中,而索引又大到无法放入缓存,就需要大量随机 I/O。PostgreSQL支持两种用于 GiST 索引初始构建的替代方法:sortedbuffered模式。 + 构建 GiST 索引最简单的方法就是把所有项逐个插入。这对于大型索引往往很慢,因为如果索引元组分散在整个索引中,而索引又大到无法放入缓存,就需要大量随机 I/O。PostgreSQL支持两种用于 GiST 索引初始构建的替代方法:排序缓冲模式。 @@ -1076,7 +1074,7 @@ my_translate_cmptype(PG_FUNCTION_ARGS) hstore - 用于存储 (key, value) 对的模块 + 用于存储(键,值)对的模块 diff --git a/zh/19/glossary.sgml b/zh/19/glossary.sgml index 935bb0be..646ccbbb 100644 --- a/zh/19/glossary.sgml +++ b/zh/19/glossary.sgml @@ -396,7 +396,7 @@ 客户端(进程) - 任何进程,可能是远程的,通过连接到某个 + 任何进程,可能是远程的,通过连接到某个 实例来建立 会话, 以与一个数据库交互。 @@ -870,7 +870,7 @@ 一台通过网络与其他计算机通信的计算机。这个术语有时被用作 服务器的同义词。 - 它也用来指客户端进程运行所在的计算机。 + 它也用来指客户端进程运行所在的计算机。 @@ -954,7 +954,7 @@ 实例处理 DBMS 的所有关键特性: 对文件和共享内存的读写访问、保证 ACID 属性、 - 与客户端进程的连接、 + 与客户端进程连接、 权限验证、崩溃恢复、复制等。 @@ -1050,7 +1050,7 @@ - 逻辑复制集簇 + 逻辑复制集群 一组发布者实例和订阅者实例,其中发布者实例把变更复制到订阅者实例。 @@ -1204,7 +1204,7 @@ - 当它用于指代查询中的 + 当它用于指代查询中的 窗口函数时, 分区是一种用户定义的准则,用来标识 查询结果集中哪些相邻的 diff --git a/zh/19/hash.sgml b/zh/19/hash.sgml index 49f4fdf6..0a5f55de 100644 --- a/zh/19/hash.sgml +++ b/zh/19/hash.sgml @@ -1,11 +1,11 @@ -哈希索引 +Hash 索引 索引 - 哈希 + Hash @@ -13,51 +13,51 @@ PostgreSQL - 提供了持久化的磁盘哈希索引实现,并且完全支持崩溃恢复。任何数据类型都可以使用哈希索引,包括那些没有明确定义线性顺序的数据类型。哈希索引只存储被索引数据的哈希值,因此对被索引数据列的大小没有限制。 + 提供了持久化的磁盘 hash 索引实现,并且完全支持崩溃恢复。任何数据类型都可以使用 hash 索引,包括那些没有明确定义线性顺序的数据类型。Hash 索引只存储被索引数据的 hash 值,因此对被索引数据列的大小没有限制。 - 哈希索引仅支持单列索引,也不支持唯一性检查。 + Hash 索引仅支持单列索引,也不支持唯一性检查。 - 哈希索引仅支持=操作符,因此指定范围操作的 WHERE 子句无法利用哈希索引。 + Hash 索引仅支持=操作符,因此指定范围操作的 WHERE 子句无法利用 hash 索引。 - 每个哈希索引元组只存储 4 字节的哈希值,而不存储实际的列值。因此,在为 UUID、URL 等较长的数据项建立索引时,哈希索引可能比 B-树小得多。由于没有列值,所有哈希索引扫描也都是有损的。哈希索引可以参与位图索引扫描和反向扫描。 + 每个 hash 索引元组只存储 4 字节的 hash 值,而不存储实际的列值。因此,在为 UUID、URL 等较长的数据项建立索引时,hash 索引可能比 B-树小得多。由于没有列值,所有 hash 索引扫描也都是有损的。Hash 索引可以参与位图索引扫描和反向扫描。 - 哈希索引最适合于在较大表上执行等值扫描、且以 SELECT 和 UPDATE 为主的工作负载。在 B-树索引中,搜索必须沿树向下直到找到叶页。在拥有数百万行的表中,这种向下遍历会增加访问数据的时间。在哈希索引中,与叶页对应的页称为桶页。相比之下,哈希索引允许直接访问桶页,因此可能减少大表中的索引访问时间。这种“逻辑 I/O”的减少,在索引/数据大于 shared_buffers/RAM 时会更加明显。 + Hash 索引最适合于在较大表上执行等值扫描、且以 SELECT 和 UPDATE 为主的工作负载。在 B-树索引中,搜索必须沿树向下直到找到叶页。在拥有数百万行的表中,这种向下遍历会增加访问数据的时间。在 hash 索引中,与叶页对应的页称为桶页。相比之下,hash 索引允许直接访问桶页,因此可能减少大表中的索引访问时间。这种“逻辑 I/O”的减少,在索引/数据大于 shared_buffers/RAM 时会更加明显。 - 哈希索引在设计上能够应对哈希值分布不均的情况。如果哈希值分布均匀,那么直接访问桶页的效果很好。当插入导致桶页填满时,额外的溢出页就会链接到该特定桶页上,从而在局部扩展用于存放匹配该哈希值的索引元组的空间。查询期间扫描某个哈希桶时,需要遍历其全部溢出页。因此,对于某些数据,不平衡的哈希索引在所需块访问次数方面实际上可能比 B-树更差。 + Hash 索引在设计上能够应对 hash 值分布不均的情况。如果 hash 值分布均匀,那么直接访问桶页的效果很好。当插入导致桶页填满时,额外的溢出页就会链接到该特定桶页上,从而在局部扩展用于存放匹配该 hash 值的索引元组的空间。查询期间扫描某个 hash 桶时,需要遍历其全部溢出页。因此,对于某些数据,不平衡的 hash 索引在所需块访问次数方面实际上可能比 B-树更差。 - 由于会出现这些溢出情况,可以说哈希索引最适合用于唯一值、近乎唯一值,或者每个哈希桶中行数较少的数据。 + 由于会出现这些溢出情况,可以说 hash 索引最适合用于唯一值、近乎唯一值,或者每个 hash 桶中行数较少的数据。 避免问题的一种可能办法,是使用部分索引条件把高度非唯一的值排除在索引之外,但这在很多情况下可能并不适用。 - 与 B-树一样,哈希索引也会执行简单的索引元组删除。这是一种延迟维护操作,用于删除那些已知可以安全删除的索引元组(即其项标识符的 LP_DEAD 位已经被设置的那些元组)。如果插入操作发现页上没有可用空间,我们会尝试通过移除死索引元组来避免创建新的溢出页。如果该页当时已被钉住,就无法执行移除。死索引指针也会在 VACUUM 期间被删除。 + 与 B-树一样,hash 索引也会执行简单的索引元组删除。这是一种延迟维护操作,用于删除那些已知可以安全删除的索引元组(即其项标识符的 LP_DEAD 位已经被设置的那些元组)。如果插入操作发现页上没有可用空间,我们会尝试通过移除死索引元组来避免创建新的溢出页。如果该页当时已被钉住,就无法执行移除。死索引指针也会在 VACUUM 期间被删除。 - 如果可能,VACUUM 还会尝试将索引元组压缩到尽可能少的溢出页上,以最小化溢出链。 + 如果可能,VACUUM 还会尝试将索引元组集中存放在尽可能少的溢出页上,以最小化溢出链。 如果某个溢出页变为空页,该溢出页就可以被回收并在其他桶中重用,不过我们从不将它们返还给操作系统。 - 目前除了使用 REINDEX 重建哈希索引之外,还没有缩小哈希索引的方法。 + 目前除了使用 REINDEX 重建 hash 索引之外,还没有缩小 hash 索引的方法。 同样也没有减少桶数量的方法。 - 随着被索引行数的增长,哈希索引可能会扩展桶页数量。哈希键到桶号的映射经过选择,使得索引能够增量扩展。当需要向索引中添加一个新桶时,恰好只需要“拆分”一个现有桶,并根据更新后的键到桶号映射,将其中一部分元组转移到新桶。 + 随着被索引行数的增长,Hash 索引可能会扩展桶页数量。hash 键到桶号的映射经过选择,使得索引能够增量扩展。当需要向索引中添加一个新桶时,恰好只需要“拆分”一个现有桶,并根据更新后的键到桶号映射,将其中一部分元组转移到新桶。 - 这种扩展是在前台进行的,因此可能会增加用户插入操作的执行时间。因此,哈希索引可能不适合行数快速增长的表。 + 这种扩展是在前台进行的,因此可能会增加用户插入操作的执行时间。因此,hash 索引可能不适合行数快速增长的表。 @@ -66,7 +66,7 @@ 实现 - 哈希索引中有四种页:元页(第零页),其中包含静态分配的控制信息;主桶页;溢出页;以及位图页,后者用于跟踪已被释放且可供重用的溢出页。在寻址时,位图页被视为溢出页的一个子集。 + hash 索引中有四种页:元页(第零页),其中包含静态分配的控制信息;主桶页;溢出页;以及位图页,后者用于跟踪已被释放且可供重用的溢出页。在寻址时,位图页被视为溢出页的一个子集。 @@ -74,15 +74,15 @@ - 主桶页和溢出页是独立分配的,因为任何一个给定索引相对于其桶数,可能需要更多或更少的溢出页。哈希代码使用了一组颇有意思的寻址规则,以支持可变数量的溢出页,同时又不必在主桶页创建后再移动它们。 + 主桶页和溢出页是独立分配的,因为任何一个给定索引相对于其桶数,可能需要更多或更少的溢出页。hash 实现代码使用了一组颇有意思的寻址规则,以支持可变数量的溢出页,同时又不必在主桶页创建后再移动它们。 - 被索引表中的每一行,都由哈希索引中的单个索引元组表示。哈希索引元组存储在桶页中,如果存在溢出页,也会存储在溢出页中。为了加快搜索速度,我们将任一索引页中的索引项按哈希码排序,从而可以在索引页内使用二分查找。但请注意,并不假定同一桶中不同索引页之间的哈希码具有任何相对顺序。 + 被索引表中的每一行,都由 hash 索引中的单个索引元组表示。Hash 索引元组存储在桶页中,如果存在溢出页,也会存储在溢出页中。为了加快搜索速度,我们将任一索引页中的索引项按 hash 码排序,从而可以在索引页内使用二分查找。但请注意,并不假定同一桶中不同索引页之间的 hash 码具有任何相对顺序。 - 用于扩展哈希索引的桶拆分算法过于复杂,这里不再展开说明;但在src/backend/access/hash/README中有更详细的描述。该拆分算法具备崩溃安全性,如果未能成功完成,可以重新启动。 + 用于扩展 hash 索引的桶拆分算法过于复杂,这里不再展开说明;但在src/backend/access/hash/README中有更详细的描述。该拆分算法具备崩溃安全性,如果未能成功完成,可以重新启动。 diff --git a/zh/19/high-availability.sgml b/zh/19/high-availability.sgml index c515a6f2..fa3dd113 100644 --- a/zh/19/high-availability.sgml +++ b/zh/19/high-availability.sgml @@ -19,7 +19,7 @@ - 某些方案通过只允许一台服务器修改数据来处理同步。能够修改数据的服务器称为读/写、主库(master)主库(primary)服务器。跟踪主库变更的服务器称为备库。只能在被提升为主库之后才能连接的备库称为温备,而能够接受连接并提供只读查询的备库称为热备。 + 某些方案通过只允许一台服务器修改数据来处理同步。能够修改数据的服务器称为读/写、主库(master)主库(primary)服务器。跟踪主库变更的服务器称为备库(standby)备库(secondary)。只能在被提升为主库之后才能连接的备库称为温备,而能够接受连接并提供只读查询的备库称为热备 @@ -102,7 +102,7 @@ protocol to make nodes agree on a serializable transactional order. - 基于触发器的主库-备库复制 + 基于触发器的主备复制 @@ -238,7 +238,7 @@ protocol to make nodes agree on a serializable transactional order. - 主库无额外负载 + 主库无额外开销 @@ -354,7 +354,7 @@ protocol to make nodes agree on a serializable transactional order. - 连续归档可用于创建一种高可用性(HA)集簇配置,其中有一个或多个备库随时准备在主库失效时接管操作。这种能力通常称为温备日志传送。 + 持续归档可用于创建一种高可用性(HA)集簇配置,其中有一个或多个备库随时准备在主库失效时接管操作。这种能力通常称为温备日志传送 @@ -534,7 +534,7 @@ archive_cleanup_command = 'pg_archivecleanup /path/to/archive "%r"' 认证 - 正确设置复制访问权限非常重要,因为从 WAL 流中很容易提取出需要权限才能访问的信息,因此必须确保只有受信任的用户才能读取它。备库必须以具有 REPLICATION 权限的账户或超级用户身份向主库认证。建议专门创建一个具有 REPLICATIONLOGIN 权限的用户账户用于复制。虽然 REPLICATION 权限的权限很高,但它并不允许用户修改主系统上的任何数据,而 SUPERUSER 权限则允许。 + 正确设置复制访问权限非常重要,因为从 WAL 流中很容易提取出需要权限才能访问的信息,因此必须确保只有受信任的用户才能读取它。备库必须以具有 REPLICATION 权限的账户或超级用户身份向主库认证。建议专门创建一个具有 REPLICATIONLOGIN 权限的用户账户用于复制。虽然 REPLICATION 权限很高,但它并不允许用户修改主系统上的任何数据,而 SUPERUSER 权限则允许。 @@ -565,7 +565,7 @@ primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass' 流复制的一个重要健康指标,是主库上已经生成但尚未在备库上应用的 WAL 记录量。你可以通过比较主库上的当前 WAL 写入位置和备库收到的最后一个 WAL 位置来计算这种滞后。这些位置分别可以用主库上的 pg_current_wal_lsn 和备库上的 pg_last_wal_receive_lsn 取得(详见 )。备库上的最后一个 WAL 接收位置也会显示在 WAL 接收进程的进程状态中,即通过 ps 命令显示的状态(详见 )。 - 你可以通过 pg_stat_replication 视图取得 WAL 发送进程列表。pg_current_wal_lsn 与该视图的 sent_lsn 字段之间存在较大差异,可能表示主库负载很重;而 sent_lsn 与备库上的 pg_last_wal_receive_lsn 之间存在较大差异,则可能表示网络延迟,或者备库负载很重。 + 你可以通过 pg_stat_replication 视图取得 WAL 发送进程列表。pg_current_wal_lsn 与该视图的 sent_lsn 字段之间存在较大差异,可能表示主库负载很重;而 sent_lsn 与备库上的 pg_last_wal_receive_lsn 之间存在差异,则可能表示网络延迟,或者备库负载很重。 在热备上,WAL 接收进程的状态可以通过 @@ -583,13 +583,13 @@ primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass' 流复制 - 复制槽提供了一种自动化方法,以确保主库不会删除 WAL 段,直到所有备库/订阅者都已经接收了它们,无论是物理接收还是逻辑接收;并且即使备库断开连接,主库也不会删除可能在物理副本上导致恢复冲突的行。 + 复制槽提供了一种自动化方法,以确保主库不会删除 WAL 段,直到所有备库/订阅者都已经接收了它们,无论是物理接收还是逻辑接收;并且即使备库断开连接,主库也不会删除那些一旦删除就可能在物理副本上导致恢复冲突的行。 如果不使用复制槽,也可以通过阻止旧的 WAL 段被移除,或者通过把这些段保存到归档中。这些方法的一个缺点是,它们通常会保留多于实际所需数量的 WAL 段,而复制槽只会保留已知确实需要的段数。 - 类似地,如果不配合物理复制槽单独使用 ,它虽然能防止相关的行被清理而避免因清理产生的问题,但在物理复制备库未连接的那段时间内并不能提供保护。 + 类似地,如果不配合物理复制槽单独使用 ,它虽然能防止相关的行被清理移除,但在物理复制备库未连接的那段时间内并不能提供保护。 @@ -693,7 +693,7 @@ primary_slot_name = 'node_a_slot' - 只读事务和事务回滚不需要等待备库的回应。子事务提交也不需要等待备库响应,只有顶层提交才需要等待。数据装载或索引构建等长时间运行的动作,不会一直等到最终提交消息。所有两阶段提交操作都需要等待提交,包括 prepare 和 commit。 + 只读事务和事务回滚不需要等待备库的回应。子事务提交也不需要等待备库响应,只有顶层提交才需要等待。数据装载或索引构建等长时间运行的动作,直到最终提交时才会等待。所有两阶段提交操作都需要等待提交,包括准备和提交两个阶段。 @@ -708,7 +708,7 @@ primary_slot_name = 'node_a_slot' - 当提交记录已经在主库上写入磁盘之后,WAL 记录就会被发送到备库。每当新的一批 WAL 数据被写入磁盘时,备库就会发送回复消息,除非备库上的wal_receiver_status_interval被设置为零。如果synchronous_commit被设置为remote_apply,那么备库会在提交记录被重放时发送回复消息,从而使该事务变得可见。如果根据主库上的synchronous_standby_names设置,该备库被选为同步备库,那么它发出的回复会与其他同步备库的回复一起,用于决定何时释放那些正在等待确认提交记录已被收到的事务。这些参数允许管理员指定哪些备库应作为同步备库。注意,同步复制的配置主要在主库上进行。被命名的备库必须直接连接到主库;主库并不知道使用级联复制的下游备库。 + 当提交记录已经在主库上写入磁盘之后,WAL 记录就会被发送到备库。每当新的一批 WAL 数据被写入磁盘时,备库就会发送回复消息,除非备库上的wal_receiver_status_interval被设置为零。如果synchronous_commit被设置为remote_apply,那么备库会在提交记录被重放、该事务变得可见时发送回复消息。如果根据主库上的synchronous_standby_names设置,该备库被选为同步备库,那么它发出的回复会与其他同步备库的回复一起,用于决定何时释放那些正在等待确认提交记录已被收到的事务。这些参数允许管理员指定哪些备库应作为同步备库。注意,同步复制的配置主要在主库上进行。被命名的备库必须直接连接到主库;主库并不知道使用级联复制的下游备库。 @@ -742,14 +742,14 @@ synchronous_standby_names = 'FIRST 2 (s1, s2, s3)' 在这个例子中,如果四台备库s1s2s3s4都在运行,则s1s2会被选为同步备库,因为它们的名字在备库名称列表中出现得更早。s3是潜在的同步备库,当s1s2中的任意一台失效时,它就会接替其角色。由于s4的名称不在列表中,因此它是异步备库。 - ANY方法指定基于法定人数的同步复制,使事务提交等待,直到它们的 WAL 记录被复制到列表中所要求数量的同步备库中的至少这么多台。 + ANY方法指定基于法定人数的同步复制,使事务提交等待,直到它们的 WAL 记录被复制到列表中至少所要求数量的同步备库。 基于法定人数的多同步备库的synchronous_standby_names示例如下: synchronous_standby_names = 'ANY 2 (s1, s2, s3)' - 在这个例子中,如果四台备库s1s2s3s4都在运行,事务提交将等待来自s1s2s3中的任意两台备库的回复。由于s4的名字不在列表中,因此它是异步备库。 + 在这个例子中,如果四台备库s1s2s3s4都在运行,事务提交将等待来自s1s2s3中的至少任意两台备库的回复。由于s4的名字不在列表中,因此它是异步备库。 备库的同步状态可以通过pg_stat_replication视图查看。 @@ -772,7 +772,7 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' - 通过在应用级别(在主库上)指定同步复制选项,我们可以只对最重要的变更提供同步复制,而不会拖慢整体工作负载。应用级别选项是让高性能应用获得同步复制收益的一种重要而实用的工具。 + 通过在应用级别(在主库上)指定同步复制选项,我们可以只对最重要的变更提供同步复制,而不会拖慢大部分工作负载。应用级别选项是让高性能应用获得同步复制收益的一种重要而实用的工具。 @@ -805,7 +805,7 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' - 如果主库在提交正等待确认时重启,这些等待中的事务会在主库恢复后被标记为已完全提交。无法确定在主库崩溃时,所有备库是否已经收到全部尚未处理的 WAL 数据。因此,某些事务可能不会在备库上显示为已提交,即使它们在主库上显示为已提交。我们所提供的保证是:只有在确认 WAL 数据已经被所有同步备库安全接收之后,应用才会收到事务成功提交的显式确认。 + 如果主库在提交正等待确认时重启,这些等待中的事务会在主库恢复后被标记为已完全提交。无法确定在主库崩溃时,所有备库是否已经收到全部待传送的 WAL 数据。因此,某些事务可能不会在备库上显示为已提交,即使它们在主库上显示为已提交。我们所提供的保证是:只有在确认 WAL 数据已经被所有同步备库安全接收之后,应用才会收到事务成功提交的显式确认。 @@ -901,7 +901,7 @@ postgres=# WAIT FOR LSN '0/306EE20'; - 一旦故障切换到备库,系统中就只剩下一台服务器在运行。这被称为退化状态。原来的备库现在成为主库,而原来的主库已经停机,并且可能持续停机。要恢复到正常运行状态,就必须重新创建一台备库:要么在原主库恢复后在其上重建,要么在第三台可能是全新的服务器上重建。在大型集簇上,可以使用工具来加快这一过程。一旦完成,就可以认为主库和备库已经交换了角色。有些人会选择使用第三台服务器,在新的备库重建完成之前为新的主库提供备份,但显然这会让系统配置和操作流程更加复杂。 + 一旦故障切换到备库,系统中就只剩下一台服务器在运行。这被称为退化状态。原来的备库现在成为主库,而原来的主库已经停机,并且可能持续停机。要恢复到正常运行状态,就必须重新创建一台备库:要么在原主库恢复后在其上重建,要么在第三台可能是全新的服务器上重建。在大型集簇上,可以使用工具来加快这一过程。一旦完成,就可以认为主库和备库已经交换了角色。有些人会选择使用第三台服务器,在新的备库重建完成之前为新的主库提供后备支持,但显然这会让系统配置和操作流程更加复杂。 @@ -964,7 +964,7 @@ postgres=# WAIT FOR LSN '0/306EE20'; - 事务管理命令: + 事务管理命令: @@ -978,7 +978,7 @@ postgres=# WAIT FOR LSN '0/306EE20'; - EXCEPTION块或其他内部子事务 + EXCEPTION块和其他内部子事务 @@ -1018,7 +1018,7 @@ postgres=# WAIT FOR LSN '0/306EE20'; 数据操纵语言(DML):INSERTUPDATEDELETEMERGECOPY FROM、 - TRUNCATE。请注意,恢复期间不存在任何允许执行触发器的动作。这个限制甚至适用于临时表,因为不分配事务 ID 就无法读取或写入表行,而这在热备环境中目前是不可能的。 + TRUNCATE。请注意,恢复期间不存在任何允许执行触发器的动作。这个限制甚至适用于临时表,因为不分配事务 ID 就无法读取或写入表行,而目前热备环境中无法分配事务 ID。 @@ -1053,13 +1053,13 @@ postgres=# WAIT FOR LSN '0/306EE20'; - BEGIN READ WRITE, + BEGIN READ WRITESTART TRANSACTION READ WRITE - SET TRANSACTION READ WRITE, + SET TRANSACTION READ WRITESET SESSION CHARACTERISTICS AS TRANSACTION READ WRITE @@ -1075,7 +1075,7 @@ postgres=# WAIT FOR LSN '0/306EE20'; 两阶段提交命令:PREPARE TRANSACTIONCOMMIT PREPAREDROLLBACK PREPARED, - 因为即使是只读事务,在 prepare 阶段(两阶段提交的第一阶段)也需要写入 WAL。 + 因为即使是只读事务,在准备阶段(两阶段提交的第一阶段)也需要写入 WAL。 @@ -1163,24 +1163,22 @@ postgres=# WAIT FOR LSN '0/306EE20'; - 一旦max_standby_archive_delaymax_standby_streaming_delay指定的延迟被超越,冲突查询将被取消。这通常仅导致一个取消错误,尽管在重放一个DROP DATABASE的情况下整个冲突会话都将被中断。另外,如果冲突发生在一个被空闲事务持有的锁上,该冲突会话会被中断(这种行为可能在未来被改变)。 + 一旦max_standby_archive_delaymax_standby_streaming_delay指定的延迟被超越,冲突查询将被取消。这通常仅导致一个取消错误,尽管在重放一个DROP DATABASE的情况下整个冲突会话都将被终止。另外,如果冲突发生在一个被空闲事务持有的锁上,该冲突会话会被终止(这种行为可能在未来被改变)。 - - 被取消的查询可能会立即被重试(当然是在开始一个新的事务后)。因为查询取消依赖于 WAL 记录被重放的本质,如果一个被取消的查询被再次执行,它可能会很好地成功完成。 - + 被取消的查询可以立即重试(当然,要先开始一个新事务)。由于查询取消取决于正在重放的 WAL 记录的性质,被取消的查询再次执行时完全可能成功。 - 记住延迟参数是从 WAL 数据被备库收到后流逝的时间。因此,留给备库上任何一个查询的宽限期从不会超过延迟参数,并且如果备库已经由于等待之前的查询完成而落后或者因为过重的更新负载而无法跟上主库,宽限期可能会更少。 + 请记住,延迟参数要与备库收到 WAL 数据之后经过的时间进行比较。因此,留给备库上任何一个查询的宽限期从不会超过延迟参数,并且如果备库已经由于等待之前的查询完成而落后或者因为过重的更新负载而无法跟上主库,宽限期可能会更少。 - 备库查询与 WAL 重放发生冲突的最常见原因是过早清理。正常情况下,当没有事务需要看到旧行版本时,PostgreSQL允许清理这些旧行版本,以保证按照 MVCC 规则得到正确的数据可见性。不过,这条规则只能应用于在主库上执行的事务。因此,主库上的清理有可能移除某个备库事务仍然可见的行版本。 + 备库查询与 WAL 重放发生冲突的最常见原因是过早清理。正常情况下,当不再有事务需要看到旧行版本来保证符合 MVCC 规则的数据可见性时,PostgreSQL允许清理这些旧行版本。不过,这条规则只能应用于在主库上执行的事务。因此,主库上的清理有可能移除某个备库事务仍然可见的行版本。 行版本清理并不是与备库查询发生冲突的唯一潜在原因。所有仅索引扫描(包括在备库上运行的那些)都必须使用一个MVCC快照,它与可见性映射一致。因此,每当VACUUM在可见性映射中把某个页面标记为全可见,而该页面中包含一行或多行对所有备库查询都不可见的数据时,就必须产生冲突。所以,即使针对一个没有更新或删除任何需要清理行的表执行VACUUM,也可能导致冲突。 + linkend="vacuum-for-visibility-map">在可见性映射中把某个页面标记为全可见,而该页面中包含并非对所有备库查询都可见的一行或多行数据时,就必须产生冲突。所以,即使针对一个没有需要清理的已更新或已删除行的表执行VACUUM,也可能导致冲突。 @@ -1283,7 +1281,7 @@ HINT: You can then restart the server after making the necessary configuration - 主库上写出的事务状态 "hint bits" 不会被 WAL 记录,因此备库上的数据很可能会再次写出这些提示位。这样一来,即使所有用户都是只读的,备库仍然会执行磁盘写操作;不过数据值本身并不会发生变化。用户仍然会写出大型排序临时文件,并重新生成 relcache 信息文件,因此在热备模式下,数据库没有任何部分是真正只读的。还要注意,使用dblink模块写入远程数据库,以及借助 PL 函数执行其他数据库外部操作,依然是可能的,即使该事务在本地是只读的。 + 主库上写出的事务状态“提示位” 不会被 WAL 记录,因此备库上的数据很可能会再次写出这些提示位。这样一来,即使所有用户都是只读的,备库仍然会执行磁盘写操作;不过数据值本身并不会发生变化。用户仍然会写出大型排序临时文件,并重新生成 relcache 信息文件,因此在热备模式下,数据库没有任何部分是真正只读的。还要注意,使用dblink模块写入远程数据库,以及借助 PL 函数执行其他数据库外部操作,依然是可能的,即使该事务在本地是只读的。 @@ -1292,7 +1290,7 @@ HINT: You can then restart the server after making the necessary configuration - 数据定义语言:例如 CREATE INDEX + 数据定义语言(DDL):例如 CREATE INDEX diff --git a/zh/19/images/fixup-svg.xsl b/zh/19/images/fixup-svg.xsl index d6c46b36..cf7169bb 100644 --- a/zh/19/images/fixup-svg.xsl +++ b/zh/19/images/fixup-svg.xsl @@ -32,6 +32,11 @@ Fix stroke="transparent" attribute, which is invalid SVG. none + + + 'Alibaba PuHuiTi 3.0',serif + + diff --git a/zh/19/images/gin.gv b/zh/19/images/gin.gv index 097e9102..b8e26542 100644 --- a/zh/19/images/gin.gv +++ b/zh/19/images/gin.gv @@ -1,11 +1,12 @@ digraph "gin" { layout=dot; - node [label="", shape=box, style=filled, fillcolor=gray, width=1.4]; + fontname="Alibaba PuHuiTi 3.0"; + node [fontname="Alibaba PuHuiTi 3.0", label="", shape=box, style=filled, fillcolor=gray, width=1.4]; - m1 [label="meta page"]; + m1 [label="元页"]; subgraph cluster01 { - label="entry tree"; + label="键项树"; subgraph egroup1 { rank=same; e1; @@ -27,13 +28,13 @@ digraph "gin" { e4 -> e8; e4 -> e9; - e6 [fillcolor=green, label="posting list"]; - e8 [fillcolor=green, label="posting list"]; - e9 [fillcolor=green, label="posting list"]; + e6 [fillcolor=green, label="倒排列表"]; + e8 [fillcolor=green, label="倒排列表"]; + e9 [fillcolor=green, label="倒排列表"]; } subgraph cluster02 { - label="posting tree"; + label="倒排树"; subgraph pgroup1 { rank=same; p1; @@ -45,22 +46,22 @@ digraph "gin" { p1 -> p2; p1 -> p3; - p2 [fillcolor=green, label="heap ptr"]; - p3 [fillcolor=green, label="heap ptr"]; + p2 [fillcolor=green, label="堆指针"]; + p3 [fillcolor=green, label="堆指针"]; } subgraph cluster03 { - label="posting tree"; + label="倒排树"; subgraph pgroup3 { rank=same; p4; } - p4 [fillcolor=green, label="heap ptr"]; + p4 [fillcolor=green, label="堆指针"]; } subgraph cluster04 { - label="posting tree"; + label="倒排树"; subgraph pgroup4 { rank=same; p5; @@ -72,12 +73,12 @@ digraph "gin" { p5 -> p6; p5 -> p7; - p6 [fillcolor=green, label="heap ptr"]; - p7 [fillcolor=green, label="heap ptr"]; + p6 [fillcolor=green, label="堆指针"]; + p7 [fillcolor=green, label="堆指针"]; } subgraph cluster05 { - label="pending list"; + label="待处理列表"; node [style=filled, fillcolor=red]; n1 -> n2 -> n3 -> n4; } diff --git a/zh/19/images/gin.svg b/zh/19/images/gin.svg index 04fe85ba..79cf14a9 100644 --- a/zh/19/images/gin.svg +++ b/zh/19/images/gin.svg @@ -9,33 +9,33 @@ cluster01 -entry tree +键项树 cluster02 -posting tree +倒排树 cluster03 -posting tree +倒排树 cluster04 -posting tree +倒排树 cluster05 -pending list +待处理列表 m1 -meta page +元页 @@ -113,7 +113,7 @@ e6 -posting list +倒排列表 @@ -142,7 +142,7 @@ e8 -posting list +倒排列表 @@ -154,7 +154,7 @@ e9 -posting list +倒排列表 @@ -195,7 +195,7 @@ p4 -heap ptr +堆指针 @@ -224,7 +224,7 @@ p2 -heap ptr +堆指针 @@ -236,7 +236,7 @@ p3 -heap ptr +堆指针 @@ -254,7 +254,7 @@ p6 -heap ptr +堆指针 @@ -266,7 +266,7 @@ p7 -heap ptr +堆指针 diff --git a/zh/19/images/temporal-isolation.svg b/zh/19/images/temporal-isolation.svg index 9bde2fc9..690b3e29 100644 --- a/zh/19/images/temporal-isolation.svg +++ b/zh/19/images/temporal-isolation.svg @@ -32,16 +32,16 @@ - 会话 1 + 会话 1 UPDATE; - 等待…… + 等待…… BEGIN; BEGIN; - 会话 2 + 会话 2 UPDATE; COMMIT; COMMIT; - ……继续 - 重新检查 + ……继续 + 重新检查 diff --git a/zh/19/indexam.sgml b/zh/19/indexam.sgml index fbadeb80..41e661ed 100644 --- a/zh/19/indexam.sgml +++ b/zh/19/indexam.sgml @@ -21,7 +21,7 @@ - 索引本质上是从一些数据键值到行版本(元组)在索引父表中的元组标识符TID)的映射。一个 TID 由块号以及该块中的项号组成(见 元组标识符(TIDs)的映射。一个 TID 由块号以及该块中的项号组成(见 )。这些信息足以从表中取出某个特定的行版本。索引并不直接知道在 MVCC 之下同一逻辑行可能会存在多个现存版本;对索引来说,每个元组都是一个独立对象,需要它自己的索引条目。因此,对一行的更新总会为该行创建全新的索引条目,即使键值并未改变也是如此。(HOT 元组是这一说法的例外;但索引同样不直接处理它们。)当死元组自身被回收时(通过清理),它们对应的索引条目也会被回收。 @@ -44,89 +44,89 @@ typedef struct IndexAmRoutine NodeTag type; /* - * Total number of strategies (operators) by which we can traverse/search - * this AM. Zero if AM does not have a fixed set of strategy assignments. + * 可用于遍历或搜索此 AM 的策略(操作符)总数。 + * 如果 AM 没有固定的一组策略分配,则为零。 */ uint16 amstrategies; - /* total number of support functions that this AM uses */ + /* 此 AM 使用的支持函数总数 */ uint16 amsupport; - /* opclass options support function number or 0 */ + /* 操作符类选项支持函数编号,或为 0 */ uint16 amoptsprocnum; - /* does AM support ORDER BY indexed column's value? */ + /* AM 是否支持按被索引列的值进行 ORDER BY? */ bool amcanorder; - /* does AM support ORDER BY result of an operator on indexed column? */ + /* AM 是否支持按被索引列上操作符的结果进行 ORDER BY? */ bool amcanorderbyop; - /* does AM support hashing using API consistent with the hash AM? */ + /* AM 是否支持使用与 hash AM 一致的 API 进行哈希? */ bool amcanhash; - /* do operators within an opfamily have consistent equality semantics? */ + /* 操作符族内的操作符是否具有一致的相等语义? */ bool amconsistentequality; - /* do operators within an opfamily have consistent ordering semantics? */ + /* 操作符族内的操作符是否具有一致的排序语义? */ bool amconsistentordering; - /* does AM support backward scanning? */ + /* AM 是否支持反向扫描? */ bool amcanbackward; - /* does AM support UNIQUE indexes? */ + /* AM 是否支持 UNIQUE 索引? */ bool amcanunique; - /* does AM support multi-column indexes? */ + /* AM 是否支持多列索引? */ bool amcanmulticol; - /* does AM require scans to have a constraint on the first index column? */ + /* AM 是否要求扫描必须约束第一个索引列? */ bool amoptionalkey; - /* does AM handle ScalarArrayOpExpr quals? */ + /* AM 是否处理 ScalarArrayOpExpr 限定条件? */ bool amsearcharray; - /* does AM handle IS NULL/IS NOT NULL quals? */ + /* AM 是否处理 IS NULL/IS NOT NULL 限定条件? */ bool amsearchnulls; - /* can index storage data type differ from column data type? */ + /* 索引存储数据类型是否可以不同于列数据类型? */ bool amstorage; - /* can an index of this type be clustered on? */ + /* 是否可以按此类型的索引进行聚簇? */ bool amclusterable; - /* does AM handle predicate locks? */ + /* AM 是否处理谓词锁? */ bool ampredlocks; - /* does AM support parallel scan? */ + /* AM 是否支持并行扫描? */ bool amcanparallel; - /* does AM support parallel build? */ + /* AM 是否支持并行构建? */ bool amcanbuildparallel; - /* does AM support columns included with clause INCLUDE? */ + /* AM 是否支持由 INCLUDE 子句包含的列? */ bool amcaninclude; - /* does AM use maintenance_work_mem? */ + /* AM 是否使用 maintenance_work_mem? */ bool amusemaintenanceworkmem; - /* does AM summarize tuples, with at least all tuples in the block - * summarized in one summary */ + /* AM 是否对元组进行摘要,且一个摘要至少涵盖 + * 块中的所有元组? */ bool amsummarizing; - /* OR of parallel vacuum flags */ + /* 并行清理标志的 OR 组合 */ uint8 amparallelvacuumoptions; - /* type of data stored in index, or InvalidOid if variable */ + /* 索引中存储的数据类型;如果可变,则为 InvalidOid */ Oid amkeytype; - /* interface functions */ + /* 接口函数 */ ambuild_function ambuild; ambuildempty_function ambuildempty; aminsert_function aminsert; - aminsertcleanup_function aminsertcleanup; /* can be NULL */ + aminsertcleanup_function aminsertcleanup; /* 可以为 NULL */ ambulkdelete_function ambulkdelete; amvacuumcleanup_function amvacuumcleanup; - amcanreturn_function amcanreturn; /* can be NULL */ + amcanreturn_function amcanreturn; /* 可以为 NULL */ amcostestimate_function amcostestimate; - amgettreeheight_function amgettreeheight; /* can be NULL */ + amgettreeheight_function amgettreeheight; /* 可以为 NULL */ amoptions_function amoptions; - amproperty_function amproperty; /* can be NULL */ - ambuildphasename_function ambuildphasename; /* can be NULL */ + amproperty_function amproperty; /* 可以为 NULL */ + ambuildphasename_function ambuildphasename; /* 可以为 NULL */ amvalidate_function amvalidate; - amadjustmembers_function amadjustmembers; /* can be NULL */ + amadjustmembers_function amadjustmembers; /* 可以为 NULL */ ambeginscan_function ambeginscan; amrescan_function amrescan; - amgettuple_function amgettuple; /* can be NULL */ - amgetbitmap_function amgetbitmap; /* can be NULL */ + amgettuple_function amgettuple; /* 可以为 NULL */ + amgetbitmap_function amgetbitmap; /* 可以为 NULL */ amendscan_function amendscan; - ammarkpos_function ammarkpos; /* can be NULL */ - amrestrpos_function amrestrpos; /* can be NULL */ + ammarkpos_function ammarkpos; /* 可以为 NULL */ + amrestrpos_function amrestrpos; /* 可以为 NULL */ - /* interface functions to support parallel index scans */ - amestimateparallelscan_function amestimateparallelscan; /* can be NULL */ - aminitparallelscan_function aminitparallelscan; /* can be NULL */ - amparallelrescan_function amparallelrescan; /* can be NULL */ + /* 支持并行索引扫描的接口函数 */ + amestimateparallelscan_function amestimateparallelscan; /* 可以为 NULL */ + aminitparallelscan_function aminitparallelscan; /* 可以为 NULL */ + amparallelrescan_function amparallelrescan; /* 可以为 NULL */ - /* interface functions to support planning */ - amtranslate_strategy_function amtranslatestrategy; /* can be NULL */ - amtranslate_cmptype_function amtranslatecmptype; /* can be NULL */ + /* 支持规划的接口函数 */ + amtranslate_strategy_function amtranslatestrategy; /* 可以为 NULL */ + amtranslate_cmptype_function amtranslatecmptype; /* 可以为 NULL */ } IndexAmRoutine; @@ -148,7 +148,7 @@ typedef struct IndexAmRoutine - amsummarizing 标志指示该访问方法是否会对被索引元组做摘要,并且摘要粒度至少达到每个块一个摘要。不指向单个元组,而是指向块范围(例如 BRIN)的访问方法,可能允许继续使用 HOT 优化。这不适用于索引谓词中引用的属性,对这类属性的更新总会禁用 HOT。 + amsummarizing 标志指示该访问方法是否会对被索引元组做摘要,并且摘要粒度至少为一个块。不指向单个元组,而是指向块范围(例如 BRIN)的访问方法,可能允许继续使用 HOT 优化。这不适用于索引谓词中引用的属性,对这类属性的更新总会禁用 HOT @@ -215,7 +215,7 @@ void aminsertcleanup (Relation indexRelation, IndexInfo *indexInfo); - 清理由 indexInfo->ii_AmCache 在连续插入之间维护的状态。如果这些数据需要额外的清理步骤(例如释放已钉住的缓冲区),而仅释放内存还不够,那么这个函数就很有用。 + 清理在 indexInfo->ii_AmCache 中跨连续插入维护的状态。如果这些数据需要额外的清理步骤(例如释放已钉住的缓冲区),而仅释放内存还不够,那么这个函数就很有用。 @@ -226,7 +226,7 @@ ambulkdelete (IndexVacuumInfo *info, IndexBulkDeleteCallback callback, void *callback_state); - 从索引中删除元组。这是一个批量删除操作,通常应通过扫描整个索引并检查每个条目是否应被删除来实现。必须调用传入的 callback 函数,其调用形式为 callback(TID, callback_state) returns bool,以确定由其引用 TID 标识的某个索引条目是否应删除。该函数必须返回 NULL,或者返回一个通过 palloc 分配的结构体,其中包含此次删除操作影响的统计信息。如果不需要向 amvacuumcleanup 传递信息,返回 NULL 也是可以的。 + 从索引中删除元组。这是一个批量删除操作,旨在通过扫描整个索引并检查每个条目是否应被删除来实现。必须调用传入的 callback 函数,其调用形式为 callback(TID, callback_state) returns bool,以确定由其引用 TID 标识的某个索引条目是否应删除。该函数必须返回 NULL,或者返回一个通过 palloc 分配的结构体,其中包含此次删除操作影响的统计信息。如果不需要向 amvacuumcleanup 传递信息,返回 NULL 也是可以的。 @@ -251,8 +251,7 @@ amvacuumcleanup (IndexVacuumInfo *info, bool amcanreturn (Relation indexRelation, int attno); - 检查索引是否能够在给定列上支持 仅索引扫描,做法是返回该列原始的被索引值。属性编号从 1 开始,也就是说第一列的 attno 为 1。若支持则返回真,否则返回假。如果支持包含列,这个函数应始终对包含列返回真,因为不能取回的包含列几乎没有意义。如果访问方法根本不支持仅索引扫描,那么它的 IndexAmRoutine 结构体中的 amcanreturn 字段可以设为 NULL。 + 检查索引能否通过返回给定列原始的被索引值,在该列上支持 仅索引扫描。属性编号从 1 开始,也就是说第一列的 attno 为 1。若支持则返回真,否则返回假。如果支持包含列,这个函数应始终对包含列返回真,因为不能取回的包含列几乎没有意义。如果访问方法根本不支持仅索引扫描,那么它的 IndexAmRoutine 结构体中的 amcanreturn 字段可以设为 NULL。 @@ -267,7 +266,7 @@ amcostestimate (PlannerInfo *root, double *indexCorrelation, double *indexPages); - 估计一次索引扫描的开销。该函数将在后面的 中详细讨论。 + 估计一次索引扫描的代价。该函数将在后面的 中详细讨论。 @@ -275,7 +274,7 @@ amcostestimate (PlannerInfo *root, int amgettreeheight (Relation rel); - 计算树形索引的高度。这一信息会通过 path->indexinfo->tree_height 提供给 amcostestimate 函数,可用于支持开销估计。其结果不会在其他地方使用,因此这个函数实际上也可以用来计算索引上任何一种适合装入整数、且开销估计函数可能想知道的数据。如果计算代价较高,把结果缓存到 RelationData.rd_amcache 中可能会有用。 + 计算树形索引的高度。这一信息会通过 path->indexinfo->tree_height 提供给 amcostestimate 函数,可用于支持代价估算。其结果不会在其他地方使用,因此这个函数实际上也可以用来计算索引上任何一种适合装入整数、且代价估算函数可能想知道的数据。如果计算代价较高,把结果缓存到 RelationData.rd_amcache 中可能会有用。 @@ -284,7 +283,7 @@ bytea * amoptions (ArrayType *reloptions, bool validate); - 解析并验证索引的 reloptions 数组。只有当该索引存在非空的 reloptions 数组时才会调用此函数。reloptions 是一个 text 数组,其中的条目形如 name=value。该函数应构造一个 bytea 值,并将其复制到索引 relcache 条目的 rd_options 字段中。这个 bytea 值中的数据内容由访问方法自行定义;大多数标准访问方法使用结构体 StdRdOptions。当 validate 为真时,若存在未识别选项或无效取值,函数应报告合适的错误消息;当 validate 为假时,无效条目应被静默忽略。(当装载已存储在 pg_catalog 中的选项时,validate 为假;此时只有在访问方法改变了选项规则时才可能发现无效条目,而忽略过时条目是合适的。)如果希望采用默认行为,返回 NULL 也是可以的。 + 解析并验证索引的 reloptions 数组。只有当该索引存在非 NULL 的 reloptions 数组时才会调用此函数。reloptions 是一个 text 数组,其中的条目形如 name=value。该函数应构造一个 bytea 值,并将其复制到索引 relcache 条目的 rd_options 字段中。这个 bytea 值中的数据内容由访问方法自行定义;大多数标准访问方法使用结构体 StdRdOptions。当 validate 为真时,若存在未识别选项或无效取值,函数应报告合适的错误消息;当 validate 为假时,无效条目应被静默忽略。(当装载已存储在 pg_catalog 中的选项时,validate 为假;此时只有在访问方法改变了选项规则时才可能发现无效条目,而忽略过时条目是合适的。)如果希望采用默认行为,返回 NULL 也是可以的。 @@ -298,7 +297,7 @@ amproperty (Oid index_oid, int attno, - 支持排序操作符的访问方法应当实现 AMPROP_DISTANCE_ORDERABLE 属性测试,因为核心代码不知道如何完成该测试,只会返回 NULL。若实现成本低于打开索引并调用 amcanreturn(这正是核心代码的默认行为),那么实现 AMPROP_RETURNABLE 测试也可能是有利的。对于其他所有标准属性,默认行为应当已经足够。 + 支持排序操作符的访问方法应当实现 AMPROP_DISTANCE_ORDERABLE 属性测试,因为核心代码不知道如何完成该测试,只会返回 NULL。若完成该测试的代价低于打开索引并调用 amcanreturn(这正是核心代码的默认行为),那么实现 AMPROP_RETURNABLE 测试也可能是有利的。对于其他所有标准属性,默认行为应当已经足够。 @@ -360,11 +359,11 @@ bool amgettuple (IndexScanDesc scan, ScanDirection direction); - 在给定扫描中取出下一个元组,并按给定方向移动(在索引中向前或向后)。若成功取得元组则返回真;若不再有匹配元组则返回假。在返回真时,元组的 TID 会存入 scan 结构体中。请注意,成功仅表示索引中存在一个匹配扫描键的条目,并不表示该元组一定仍然存在于堆中,或者一定能通过调用者的快照测试。成功时,amgettuple 还必须把 scan->xs_recheck 设为真或假。假表示可以确定该索引条目匹配扫描键;真表示这一点并不确定,因此在取到堆元组后必须根据扫描键所代表的条件重新检查它。这一机制支持有损索引操作符。请注意,重检只会扩展到扫描条件;部分索引谓词(如果有)永远不会由 amgettuple 的调用者重新检查。 + 在给定扫描中取出下一个元组,并按给定方向移动(在索引中向前或向后)。若成功取得元组则返回真;若不再有匹配元组则返回假。在返回真时,元组的 TID 会存入 scan 结构体中。请注意,成功仅表示索引中存在一个匹配扫描键的条目,并不表示该元组一定仍然存在于堆中,或者一定能通过调用者的快照测试。成功时,amgettuple 还必须把 scan->xs_recheck 设为真或假。假表示可以确定该索引条目匹配扫描键;真表示这一点并不确定,因此在取到堆元组后必须根据扫描键所代表的条件重新检查它。这一机制支持有损索引操作符。请注意,重检只针对扫描条件;部分索引谓词(如果有)永远不会由 amgettuple 的调用者重新检查。 - 如果索引支持 仅索引扫描(即其任一列上 amcanreturn 返回真),那么成功时 AM 还必须检查 scan->xs_want_itup;若其为真,就必须返回该索引条目的原始被索引数据。对于 amcanreturn 返回假的列,可以把其值作为 NULL 返回。数据可以通过以下两种形式之一返回:一种是把 IndexTuple 指针存入 scan->xs_itup,其元组描述符为 scan->xs_itupdesc;另一种是把 HeapTuple 指针存入 scan->xs_hitup,其元组描述符为 scan->xs_hitupdesc。(当重建出的数据可能装不进 IndexTuple 时,应使用后一种格式。)无论采用哪种形式,指针所引用数据的管理责任都在访问方法一侧。对这份数据的有效性必须至少保持到该扫描下一次调用 amgettupleamrescanamendscan 为止。 + 如果索引支持 仅索引扫描(即其至少一列上 amcanreturn 返回真),那么成功时 AM 还必须检查 scan->xs_want_itup;若其为真,就必须返回该索引条目的原始被索引数据。对于 amcanreturn 返回假的列,可以把其值作为 NULL 返回。数据可以通过以下两种形式之一返回:一种是把 IndexTuple 指针存入 scan->xs_itup,其元组描述符为 scan->xs_itupdesc;另一种是把 HeapTuple 指针存入 scan->xs_hitup,其元组描述符为 scan->xs_hitupdesc。(当重建出的数据可能装不进 IndexTuple 时,应使用后一种格式。)无论采用哪种形式,指针所引用数据的管理责任都在访问方法一侧。这份数据必须至少保持有效,直到该扫描下一次调用 amgettupleamrescanamendscan @@ -377,7 +376,7 @@ int64 amgetbitmap (IndexScanDesc scan, TIDBitmap *tbm); - 取出给定扫描中的所有元组,并将其加入调用者提供的 TIDBitmap 中(也就是把这组元组 ID 与位图中已有的集合做 OR)。返回值是取得的元组数量(这可能只是近似计数,例如某些 AM 不会检测重复项)。在把元组 ID 插入位图时,amgetbitmap 可以指出某些具体的元组 ID 需要重新检查扫描条件。这类似于 amgettuplexs_recheck 输出参数。注意:在当前实现中,对这一特性的支持与位图自身的有损存储支持混在一起,因此调用者会对可重检元组同时重新检查扫描条件和部分索引谓词(如果有)。不过,这并不一定永远如此。amgetbitmapamgettuple 不能在同一次索引扫描中同时使用;使用 amgetbitmap 时还有其他限制,详见 。 + 取出给定扫描中的所有元组,并将其加入调用者提供的 TIDBitmap 中(也就是把这组元组 ID 与位图中已有的集合做 OR)。返回值是取得的元组数量(这可能只是近似计数,例如某些 AM 不会检测重复项)。在把元组 ID 插入位图时,amgetbitmap 可以指出某些具体的元组 ID 需要重新检查扫描条件。这类似于 amgettuplexs_recheck 输出参数。注意:在当前实现中,对这一特性的支持与位图自身的有损存储支持混在一起,因此调用者会对需要重检的元组同时重新检查扫描条件和部分索引谓词(如果有)。不过,这并不一定永远如此。amgetbitmapamgettuple 不能在同一次索引扫描中同时使用;使用 amgetbitmap 时还有其他限制,详见 @@ -389,7 +388,7 @@ amgetbitmap (IndexScanDesc scan, void amendscan (IndexScanDesc scan); - 结束一次扫描并释放资源。scan 结构体本身不应被释放,但访问方法内部获取的任何锁或 pin,以及由 ambeginscan 和其他扫描相关函数分配的其他内存,都必须被释放。 + 结束一次扫描并释放资源。scan 结构体本身不应被释放,但必须释放访问方法内部获取的所有锁、解除所有钉住状态,并释放由 ambeginscan 和其他扫描相关函数分配的其他内存。 @@ -524,7 +523,7 @@ amtranslatecmptype (CompareType cmptype, Oid opfamily, Oid opcintype); - 除了使用 amgettuple 外,索引扫描也可以使用 amgetbitmap,在一次调用中取出所有元组。与 amgettuple 相比,这通常明显更高效,因为它可以避免访问方法内部的反复加锁和解锁。原则上,amgetbitmap 应具有与重复调用 amgettuple 相同的效果,但为了简化实现,我们施加了若干限制。首先,amgetbitmap 一次性返回全部元组,因此不支持标记或恢复扫描位置。其次,元组是通过一个位图返回的,没有特定顺序,这也是为什么 amgetbitmap 不带 direction 参数的原因。(这种扫描也永远不会提供排序操作符。)此外,使用 amgetbitmap 时也没有仅索引扫描的支持,因为没有办法返回索引元组的内容。最后,amgetbitmap 不保证对返回的元组做任何锁定,其影响见 。 + 除了使用 amgettuple 外,索引扫描也可以使用 amgetbitmap,在一次调用中取出所有元组。与 amgettuple 相比,这可能明显更高效,因为它可以避免访问方法内部的反复加锁和解锁。原则上,amgetbitmap 应具有与重复调用 amgettuple 相同的效果,但为了简化实现,我们施加了若干限制。首先,amgetbitmap 一次性返回全部元组,因此不支持标记或恢复扫描位置。其次,元组是通过一个位图返回的,没有特定顺序,这也是为什么 amgetbitmap 不带 direction 参数的原因。(这种扫描也永远不会提供排序操作符。)此外,使用 amgetbitmap 时也没有仅索引扫描的支持,因为没有办法返回索引元组的内容。最后,amgetbitmap 不保证对返回的元组做任何锁定,其影响见 @@ -541,7 +540,7 @@ amtranslatecmptype (CompareType cmptype, Oid opfamily, Oid opcintype); - 构建一种支持并发更新的索引类型,通常需要对所需行为进行大量而细致的分析。对于 B-树和哈希索引类型,可以阅读 src/backend/access/nbtree/READMEsrc/backend/access/hash/README 中涉及的设计决策。 + 构建一种支持并发更新的索引类型,通常需要对所需行为进行大量而细致的分析。对于 B-树和 hash 索引类型,可以阅读 src/backend/access/nbtree/READMEsrc/backend/access/hash/README 中涉及的设计决策。 @@ -560,12 +559,12 @@ amtranslatecmptype (CompareType cmptype, Oid opfamily, Oid opcintype); - 索引扫描必须在保存 amgettuple 最近一次返回条目的索引页面上维护一个 pin,而 ambulkdelete 不能从被其他后端钉住的页面中删除条目。下面会解释为什么需要这条规则。 + 索引扫描必须在保存 amgettuple 最近一次返回条目的索引页面上保持钉住状态,而 ambulkdelete 不能从被其他后端钉住的页面中删除条目。下面会解释为什么需要这条规则。 - 如果没有第三条规则,索引读取者就有可能在某个索引条目被 VACUUM 删除之前先看到它,然后在对应的堆条目已被 VACUUM 删除之后才到达那里。如果读取者到达时,该项号仍未被重新使用,就不会造成严重问题,因为空项槽位会被 heap_fetch() 忽略。但如果第三个后端已经把这个项槽位重新用作别的东西呢?在使用 MVCC 兼容快照时不会有问题,因为该槽位的新占用者一定太新,无法通过快照测试。然而,对于非 MVCC 兼容的快照(例如 SnapshotAny),就可能错误地接受并返回一行实际上并不匹配扫描键的数据。我们可以要求在所有情况下都对堆行重新检查扫描键,以防范这种情形,但那样代价太高。于是,我们改为把索引页面上的 pin 作为一种代理,表示读取者可能仍处于从索引条目前往匹配堆条目的飞行中。让 ambulkdelete 在这种 pin 上阻塞,能够保证 VACUUM 不会在读取者处理完之前删除对应的堆条目。这种方案运行时开销很小,只有在真正发生冲突的少数情况下才会增加阻塞开销。 + 如果没有第三条规则,索引读取者就有可能在某个索引条目被 VACUUM 删除之前先看到它,然后在对应的堆条目已被 VACUUM 删除之后才到达那里。如果读取者到达时,该项号仍未被重新使用,就不会造成严重问题,因为空项槽位会被 heap_fetch() 忽略。但如果第三个后端已经把这个项槽位重新用作别的东西呢?在使用 MVCC 兼容快照时不会有问题,因为该槽位的新占用者一定太新,无法通过快照测试。然而,对于非 MVCC 兼容的快照(例如 SnapshotAny),就可能错误地接受并返回一行实际上并不匹配扫描键的数据。我们可以要求在所有情况下都对堆行重新检查扫描键,以防范这种情形,但那样代价太高。于是,我们改为把索引页面的钉住状态作为一种代理,表示读取者从索引条目到匹配堆条目的访问过程可能仍在进行中。让 ambulkdelete 因这种钉住状态而阻塞,能够保证 VACUUM 不会在读取者处理完之前删除对应的堆条目。这种方案运行时开销很小,只有在真正发生冲突的少数情况下才会增加阻塞开销。 @@ -573,7 +572,7 @@ amtranslatecmptype (CompareType cmptype, Oid opfamily, Oid opcintype); - 在 amgetbitmap 索引扫描中,访问方法不会在任何返回的元组上保留索引 pin。因此,只有把这种扫描与 MVCC 兼容的快照一起使用才是安全的。 + 在 amgetbitmap 索引扫描中,访问方法不会为任何返回的元组保持索引页面的钉住状态。因此,只有把这种扫描与 MVCC 兼容的快照一起使用才是安全的。 @@ -612,7 +611,7 @@ amtranslatecmptype (CompareType cmptype, Oid opfamily, Oid opcintype); - 此外,在按照上述规则报告唯一性违背之前,访问方法必须立即重新检查正在插入那一行的存活性。如果它已经是提交后死亡的状态,就不应报告违背。(这种情况不会出现在插入由当前事务刚创建的行这一普通场景中,但在 CREATE UNIQUE INDEX CONCURRENTLY 期间却可能发生。) + 此外,就在按照上述规则报告唯一性违背之前,访问方法必须重新检查正在插入那一行的存活性。如果它已经是提交后死亡的状态,就不应报告违背。(这种情况不会出现在插入由当前事务刚创建的行这一普通场景中,但在 CREATE UNIQUE INDEX CONCURRENTLY 期间却可能发生。) @@ -620,7 +619,7 @@ amtranslatecmptype (CompareType cmptype, Oid opfamily, Oid opcintype); - 如果唯一约束是可延迟的,情况会更复杂:我们需要能够为新行插入一个索引条目,但把任何唯一性违背错误延迟到语句结束时甚至更晚才报告。为了避免对索引进行不必要的重复搜索,索引访问方法应在初始插入期间执行一次初步唯一性检查。如果这表明确实不存在冲突的存活元组,那么事情就结束了。否则,我们会安排在真正强制约束时再做一次重检。若在重检时,插入的元组与另外某个具有相同键值的元组都仍然存活,就必须报告错误。(注意,就此用途而言,存活实际上是指索引条目 HOT 链中的任一元组是存活的。)为实现这一点,传给 aminsert 函数的 checkUnique 参数会取以下值之一: + 如果唯一约束是可延迟的,情况会更复杂:我们需要能够为新行插入一个索引条目,但把任何唯一性违背错误延迟到语句结束时甚至更晚才报告。为了避免对索引进行不必要的重复搜索,索引访问方法应在初始插入期间执行一次初步唯一性检查。如果这表明确实不存在冲突的存活元组,那么事情就结束了。否则,我们会安排在真正强制约束时再做一次重检。若在重检时,插入的元组与另外某个具有相同键值的元组都仍然存活,就必须报告错误。(注意,就此用途而言,存活实际上是指索引条目 HOT 链中至少有一个元组是存活的。)为实现这一点,传给 aminsert 函数的 checkUnique 参数会取以下值之一: @@ -657,10 +656,10 @@ amtranslatecmptype (CompareType cmptype, Oid opfamily, Oid opcintype); - 索引开销估计函数 + 索引代价估算函数 - amcostestimate 函数会收到描述某种可能索引扫描方式的信息,其中包括已经确定可用于该索引的 WHERE 子句和 ORDER BY 子句列表。它必须返回访问该索引的开销估计,以及 WHERE 子句的选择率(也就是在索引扫描期间将从父表中检索出的行所占比例)。对于简单情况,开销估计器几乎所有工作都可以通过调用优化器中的标准例程来完成;之所以提供 amcostestimate 函数,是为了让索引访问方法能够提供与索引类型有关的专门知识,以便在可能时改进标准估计。 + amcostestimate 函数会收到描述某种可能索引扫描方式的信息,其中包括已经确定可用于该索引的 WHERE 子句和 ORDER BY 子句列表。它必须返回访问该索引的代价估算,以及 WHERE 子句选择率的估计值(也就是在索引扫描期间将从父表中检索出的行所占比例)。对于简单情况,代价估算器几乎所有工作都可以通过调用优化器中的标准例程来完成;之所以提供 amcostestimate 函数,是为了让索引访问方法能够提供与索引类型有关的专门知识,以便在可能时改进标准估计。 @@ -694,7 +693,7 @@ amcostestimate (PlannerInfo *root, path - 当前正在考虑的索引访问路径。除开销和选择率字段外,其余字段都有效。 + 当前正在考虑的索引访问路径。除代价和选择率字段外,其余字段都有效。 @@ -703,7 +702,7 @@ amcostestimate (PlannerInfo *root, loop_count - 在开销估计中应计入的索引扫描重复次数。当考虑在嵌套循环连接内部使用参数化扫描时,这个参数通常会大于 1。请注意,开销估计仍应只针对一次扫描;更大的 loop_count 只表示可以适当考虑多次扫描之间的一些缓存效应。 + 在代价估算中应计入的索引扫描重复次数。当考虑在嵌套循环连接内部使用参数化扫描时,这个参数通常会大于 1。请注意,代价估算仍应只针对一次扫描;更大的 loop_count 只表示可以适当考虑多次扫描之间的一些缓存效应。 @@ -718,7 +717,7 @@ amcostestimate (PlannerInfo *root, *indexStartupCost - 设为索引启动处理的开销。 + 设为索引启动处理的代价。 @@ -727,7 +726,7 @@ amcostestimate (PlannerInfo *root, *indexTotalCost - 设为索引处理的总开销。 + 设为索引处理的总代价。 @@ -762,19 +761,19 @@ amcostestimate (PlannerInfo *root, - 请注意,开销估计函数必须用 C 编写,而不能用 SQL 或任何可用的过程语言,因为它们必须访问规划器/优化器的内部数据结构。 + 请注意,代价估算函数必须用 C 编写,而不能用 SQL 或任何可用的过程语言,因为它们必须访问规划器/优化器的内部数据结构。 - 索引访问开销应使用 src/backend/optimizer/path/costsize.c 所采用的参数来计算:顺序磁盘块读取的开销为 seq_page_cost,非顺序读取的开销为 random_page_cost,处理一条索引行的开销通常应取为 cpu_index_tuple_cost。此外,在索引处理期间调用的任何比较操作符(特别是对 indexquals 本身的求值)都应计入适当倍数的 cpu_operator_cost。 + 索引访问代价应使用 src/backend/optimizer/path/costsize.c 所采用的参数来计算:顺序磁盘块读取的代价为 seq_page_cost,非顺序读取的代价为 random_page_cost,处理一条索引行的代价通常应取为 cpu_index_tuple_cost。此外,在索引处理期间调用的任何比较操作符(特别是对 indexquals 本身的求值)都应计入适当倍数的 cpu_operator_cost - 访问开销应包括与扫描索引本身有关的全部磁盘和 CPU 开销,但包括取出或处理由索引标识出的父表行的开销。 + 访问代价应包括与扫描索引本身有关的全部磁盘和 CPU 代价,但包括取出或处理由索引标识出的父表行的代价。 - 启动开销是整个扫描总开销中必须在开始取第一行之前先付出的那一部分。对大多数索引来说,这可以视为零;但启动开销较高的索引类型可能希望把它设为非零。 + 启动代价是整个扫描总代价中必须在开始取第一行之前先付出的那一部分。对大多数索引来说,这可以视为零;但启动代价较高的索引类型可能希望把它设为非零。 @@ -782,7 +781,7 @@ amcostestimate (PlannerInfo *root, - indexCorrelation 应设为索引顺序与表顺序之间的相关性(范围从 -1.0 到 1.0)。该值用于调整从父表取行开销的估计。 + indexCorrelation 应设为索引顺序与表顺序之间的相关性(范围从 -1.0 到 1.0)。该值用于调整从父表取行代价的估计。 @@ -794,9 +793,9 @@ amcostestimate (PlannerInfo *root, - 开销估计 + 代价估算 - 一个典型的开销估计器会按如下步骤进行: + 一个典型的代价估算器会按如下步骤进行: @@ -825,14 +824,14 @@ amcostestimate (PlannerInfo *root, - 计算索引访问开销。一个通用估计器可能会这样做: + 计算索引访问代价。一个通用估计器可能会这样做: /* - * Our generic assumption is that the index pages will be read - * sequentially, so they cost seq_page_cost each, not random_page_cost. - * Also, we charge for evaluation of the indexquals at each index row. - * All the costs are assumed to be paid incrementally during the scan. + * 通用假设是索引页面将按顺序读取, + * 因此每页代价为 seq_page_cost,而非 random_page_cost。 + * 此外,还要计入在每个索引行上对 indexquals 求值的代价。 + * 假定所有代价都在扫描过程中逐步付出。 */ cost_qual_eval(&index_qual_cost, path->indexquals, root); *indexStartupCost = index_qual_cost.startup; @@ -852,7 +851,7 @@ cost_qual_eval(&index_qual_cost, path->indexquals, root); - 开销估计器函数的示例可在 src/backend/utils/adt/selfuncs.c 中找到。 + 代价估算器函数的示例可在 src/backend/utils/adt/selfuncs.c 中找到。 diff --git a/zh/19/indices.sgml b/zh/19/indices.sgml index 62a36f25..ad4c56a7 100644 --- a/zh/19/indices.sgml +++ b/zh/19/indices.sgml @@ -31,7 +31,7 @@ SELECT content FROM test1 WHERE id = constant; - 大多数非小说类书籍也采用了类似的方法:读者经常查找的术语和概念会被收集到书末按字母顺序排列的索引中。感兴趣的读者可以相对快速地浏览索引并翻到相应页面,而不必通读整本书才能找到自己感兴趣的内容。正如作者需要预判读者可能查找哪些条目一样,数据库程序员也需要预见哪些索引会有用。 + 大多数非虚构类书籍也采用了类似的方法:读者经常查找的术语和概念会被收集到书末按字母顺序排列的索引中。感兴趣的读者可以相对快速地浏览索引并翻到相应页面,而不必通读整本书才能找到自己感兴趣的内容。正如作者需要预判读者可能查找哪些条目一样,数据库程序员也需要预见哪些索引会有用。 @@ -71,7 +71,7 @@ CREATE INDEX test1_id_index ON test1 (id); comparison-value operator indexed-column - 那么如果原始operator有一个可交换操作符,并且该操作符属于该索引的操作符类,就可以把它翻转成可索引的形式。 + 那么如果原始operator有一个交换子操作符,并且该操作符属于该索引的操作符类,就可以把它翻转成可索引的形式。 @@ -100,12 +100,12 @@ CREATE INDEX name ON table B-树 - index + 索引 B-树 B-树 - index + 索引 @@ -133,12 +133,12 @@ CREATE INDEX name ON table Hash - index + 索引 hash hash - index + 索引 @@ -154,12 +154,12 @@ CREATE INDEX name ON table GiST - index + 索引 GiST GiST - index + 索引 @@ -178,7 +178,7 @@ CREATE INDEX name ON table SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10; ]]> - 这会找出距离给定目标点最近的十个地点。是否能做到这一点,同样取决于所使用的具体操作符类。在中,可以按这种方式使用的操作符列在Ordering Operators这一列中。 + 这会找出距离给定目标点最近的十个地点。是否能做到这一点,同样取决于所使用的具体操作符类。在中,可以按这种方式使用的操作符列在排序操作符这一列中。 @@ -186,12 +186,12 @@ SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10; SP-GiST - index + 索引 SP-GiST SP-GiST - index + 索引 @@ -205,7 +205,7 @@ SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10; - 与 GiST 一样,SP-GiST 支持最近邻搜索。对于支持距离排序的 SP-GiST 操作符类,相应操作符列在Ordering Operators列中。 + 与 GiST 一样,SP-GiST 支持最近邻搜索。对于支持距离排序的 SP-GiST 操作符类,相应操作符列在排序操作符列中。 @@ -213,12 +213,12 @@ SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10; GIN - index + 索引 GIN GIN - index + 索引 @@ -240,12 +240,12 @@ SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10; BRIN - index + 索引 BRIN BRIN - index + 索引 @@ -265,8 +265,8 @@ SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10; 多列索引 - index - multicolumn + 索引 + 多列 @@ -293,7 +293,7 @@ CREATE INDEX test2_mm_idx ON test2 (major, minor); - 多列 B-树索引可以用于涉及索引任意列子集的查询条件,但当对前导(最左)列存在约束时,索引效率最高。精确的规则是:对前导列的等值约束,再加上第一个没有等值约束列上的任意不等约束,总会被用来限制被扫描的索引范围。这些列右侧列上的约束会在索引中进行检查,因此总能减少访问表本体的次数,但不一定会减少必须扫描的索引范围。如果 B-树索引扫描能够有效应用跳过扫描优化,那么它在通过反复的索引搜索遍历索引时,会利用每一列约束。这可能减少需要读取的索引部分,即便一个或多个列(位于查询谓词中最低有效索引列之前)缺少常规的等值约束。跳过扫描的工作方式是内部生成一个动态的等值约束,使其匹配索引列中的每个可能值(不过这只适用于某个列缺少来自查询谓词的等值约束,且生成的约束能够与查询谓词中较后列的约束联合使用时)。 + 多列 B-树索引可以用于涉及索引任意列子集的查询条件,但当对前导(最左)列存在约束时,索引效率最高。精确的规则是:对前导列的等值约束,再加上第一个没有等值约束列上的任意不等约束,总会被用来限制被扫描的索引范围。这些列右侧列上的约束会在索引中进行检查,因此总能减少访问表本体的次数,但不一定会减少必须扫描的索引范围。如果 B-树索引扫描能够有效应用跳过扫描优化,那么它在通过反复的索引搜索遍历索引时,会利用每一列约束。这可能减少需要读取的索引部分,即便一个或多个列(位于查询谓词所涉及的最右侧索引列之前)缺少常规的等值约束。跳过扫描的工作方式是内部生成一个动态的等值约束,使其匹配索引列中的每个可能值(不过这只适用于某个列缺少来自查询谓词的等值约束,且生成的约束能够与查询谓词中较后列的约束联合使用时)。 @@ -309,11 +309,11 @@ CREATE INDEX test2_mm_idx ON test2 (major, minor); - 多列 GIN 索引可以用于涉及索引任意列子集的查询条件。与 B-树或 GiST 不同,无论查询条件使用的是哪一列索引列,GIN 的索引搜索效果都一样。 + 多列 GIN 索引可以用于涉及索引任意列子集的查询条件。与 B-树或 GiST 不同,无论查询条件使用的是哪些索引列,GIN 的索引搜索效果都一样。 - 多列 BRIN 索引可以用于涉及索引任意列子集的查询条件。和 GIN 一样、不同于 B-树或 GiST,无论查询条件使用的是哪一列索引列,索引搜索效果都一样。在单个表上使用多个 BRIN 索引,而不是使用一个多列 BRIN 索引的唯一理由,是需要不同的pages_per_range存储参数。 + 多列 BRIN 索引可以用于涉及索引任意列子集的查询条件。和 GIN 一样、不同于 B-树或 GiST,无论查询条件使用的是哪些索引列,索引搜索效果都一样。在单个表上使用多个 BRIN 索引,而不是使用一个多列 BRIN 索引的唯一理由,是需要不同的pages_per_range存储参数。 @@ -330,8 +330,8 @@ CREATE INDEX test2_mm_idx ON test2 (major, minor); 索引和<literal>ORDER BY</literal> - index - and ORDER BY + 索引 + ORDER BY @@ -339,7 +339,7 @@ CREATE INDEX test2_mm_idx ON test2 (major, minor); - 规划器在满足ORDER BY要求时,会考虑两种方案:扫描一个与该要求匹配的可用索引,或者按物理顺序扫描表再显式排序。对于需要扫描表中很大一部分内容的查询,显式排序通常会比使用索引更快,因为它遵循顺序访问模式,需要的磁盘 I/O 更少。只有在只需取出少量行时,索引才更有价值。一个重要的特例是ORDER BYLIMIT n组合使用:显式排序必须处理所有数据才能找出最前面的n行,而如果有一个与ORDER BY匹配的索引,就可以直接取回前n行,而完全不必扫描剩余数据。 + 规划器在满足ORDER BY要求时,会考虑两种方案:扫描一个与该要求匹配的可用索引,或者按物理顺序扫描表再显式排序。对于需要扫描表中很大一部分内容的查询,显式排序通常会比使用索引更快,因为它遵循顺序访问模式,需要的磁盘 I/O 更少。只需取出少量行时,索引更有价值。一个重要的特例是ORDER BYLIMIT n组合使用:显式排序必须处理所有数据才能找出最前面的n行,而如果有一个与ORDER BY匹配的索引,就可以直接取回前n行,而完全不必扫描剩余数据。 @@ -369,12 +369,12 @@ CREATE INDEX test3_desc_index ON test3 (id DESC NULLS LAST); 组合多个索引 - index - combining multiple indexes + 索引 + 组合多个索引 - bitmap scan + 位图扫描 @@ -391,7 +391,7 @@ CREATE INDEX test3_desc_index ON test3 (id DESC NULLS LAST); - 除了最简单的应用之外,通常会有多种可能有用的索引组合,数据库开发者必须权衡决定提供哪些索引。有时多列索引最好,但有时创建独立索引并依赖索引组合功能会更合适。例如,如果你的工作负载包含一组查询:有时只涉及列x,有时只涉及列y,有时同时涉及两列,那么你可以选择分别在xy上创建两个独立索引,并依赖索引组合来处理同时使用两列的查询。你也可以创建一个(x, y)上的多列索引。对于同时涉及两列的查询,这个索引通常会比索引组合更高效,但正如中所讨论的,它对于只涉及y的查询就没那么有用了。具体能有多大用处,取决于 B-树索引跳过扫描优化的效果;如果x的非重复值不超过几百个,跳过扫描会让针对特定y值的搜索仍然具有相当不错的效率。再加上一个(x, y)上的多列索引和一个单独的y索引,也可能工作得相当好。对于只涉及x的查询,多列索引也可以使用,但它会比单独的x索引更大,因此更慢。最后一种选择是同时创建这三个索引,但这大概只有在该表被搜索的频率远高于被更新的频率,并且三类查询都很常见时才合理。如果其中一种查询远没有另外两种常见,那么你大概只需创建最适合常见查询类型的两个索引即可。 + 除了最简单的应用之外,通常会有多种可能有用的索引组合,数据库开发者必须权衡决定提供哪些索引。有时多列索引最好,但有时创建独立索引并依赖索引组合功能会更合适。例如,如果你的工作负载包含一组查询:有时只涉及列x,有时只涉及列y,有时同时涉及两列,那么你可以选择分别在xy上创建两个独立索引,并依赖索引组合来处理同时使用两列的查询。你也可以创建一个(x, y)上的多列索引。对于同时涉及两列的查询,这个索引通常会比索引组合更高效,但正如中所讨论的,它对于只涉及y的查询就没那么有用了。具体能有多大用处,取决于 B-树索引跳过扫描优化的效果;如果x的非重复值不超过几百个,跳过扫描会让针对特定y值的搜索仍然具有相当不错的效率。将一个(x, y)上的多列索引和一个单独的y索引组合使用,也可能工作得相当好。对于只涉及x的查询,多列索引也可以使用,但它会比单独的x索引更大,因此更慢。最后一种选择是同时创建这三个索引,但这大概只有在该表被搜索的频率远高于被更新的频率,并且三类查询都很常见时才合理。如果其中一种查询远没有另外两种常见,那么你大概只需创建最适合常见查询类型的两个索引即可。 @@ -401,8 +401,8 @@ CREATE INDEX test3_desc_index ON test3 (id DESC NULLS LAST); 唯一索引 - index - unique + 索引 + 唯一 @@ -433,8 +433,8 @@ CREATE UNIQUE INDEX name ON table表达式索引 - index - on expressions + 索引 + 基于表达式 @@ -481,8 +481,8 @@ CREATE INDEX people_names ON people ((first_name || ' ' || last_name)); 部分索引 - index - partial + 索引 + 部分 @@ -490,7 +490,7 @@ CREATE INDEX people_names ON people ((first_name || ' ' || last_name)); - 使用部分索引的一个主要原因是避免索引常见值。由于搜索常见值的查询(即占全部表行百分之几以上的值)反正也不会使用索引,因此完全没有必要把这些行保留在索引里。这会减小索引尺寸,从而加快那些确实会使用该索引的查询。它也会加快很多表更新操作,因为索引并不需要在所有情况下都更新。展示了这种思路的一种可能应用。 + 使用部分索引的一个主要原因是避免索引常见值。由于搜索常见值(即占全部表行百分之几以上的值)的查询反正也不会使用索引,因此完全没有必要把这些行保留在索引里。这会减小索引尺寸,从而加快那些确实会使用该索引的查询。它也会加快很多表更新操作,因为索引并不需要在所有情况下都更新。展示了这种思路的一种可能应用。 @@ -578,7 +578,7 @@ SELECT * FROM orders WHERE order_nr = 3501; - 也说明了:索引列和谓词中使用的列不必一致。PostgreSQL支持带任意谓词的部分索引,只要其中只涉及正在建立索引的那张表的列。不过要记住,谓词必须与那些希望从该索引受益的查询中使用的条件相匹配。更准确地说,只有当系统能够识别出查询的WHERE条件在数学上蕴含该索引的谓词时,部分索引才能用于该查询。PostgreSQL并没有一个复杂的定理证明器,来识别那些写法不同但数学上等价的表达式。(不仅构建这样一个通用定理证明器极其困难,而且它很可能也会慢到失去实际用途。)系统可以识别简单的不等式蕴含,例如x < 1蕴含x < 2;否则,谓词条件必须与查询WHERE条件的某一部分完全匹配,否则索引不会被识别为可用。匹配发生在查询规划阶段,而不是运行时。因此,参数化查询子句无法与部分索引配合工作。例如,一个带参数的预备查询可能写成x < ?,而对于参数的所有可能取值,它都不可能蕴含x < 2。 + 也说明了:索引列和谓词中使用的列不必一致。PostgreSQL支持带任意谓词的部分索引,只要其中只涉及正在建立索引的那张表的列。不过要记住,谓词必须与那些希望从该索引受益的查询中使用的条件相匹配。更准确地说,只有当系统能够识别出查询的WHERE条件在数学上蕴含该索引的谓词时,部分索引才能用于该查询。PostgreSQL并没有一个复杂的定理证明器,来识别那些写法不同但数学上等价的表达式。(不仅构建这样一个通用定理证明器极其困难,而且它很可能也会慢到失去实际用途。)系统可以识别简单的不等式蕴含,例如x < 1蕴含x < 2;否则,谓词条件必须与查询WHERE条件的某一部分完全匹配,否则索引不会被识别为可用。匹配发生在查询规划阶段,而不是运行时。因此,参数化查询子句无法与部分索引配合工作。例如,一个带参数的预备查询可能写成x < ?,而它无法保证在参数的所有可能取值下都蕴含x < 2 @@ -590,7 +590,7 @@ SELECT * FROM orders WHERE order_nr = 3501; 建立一个部分唯一索引 - 假设我们有一张描述测试结果的表。我们希望确保对于给定的subjecttarget组合,只有一条成功记录,但可以有任意多条失败记录。实现方法之一如下: + 假设我们有一张描述测试结果的表。我们希望确保对于给定的测试对象和目标组合,只有一条成功记录,但可以有任意多条失败记录。实现方法之一如下: CREATE TABLE tests ( subject text, @@ -671,7 +671,7 @@ CREATE INDEX mytable_cat_data ON mytable (category, data); - PostgreSQL中的所有索引都是二级索引,也就是说,每个索引都与表的主数据区分开存储(在PostgreSQL术语中,这个主数据区称为表的)。这意味着,在普通索引扫描中,每次取回一行都需要同时从索引和堆中取数据。此外,尽管满足某个可索引WHERE条件的索引项通常在索引中彼此接近,但它们引用的表行却可能分布在堆中的任何位置。因此,索引扫描的堆访问部分会涉及大量对堆的随机访问,这可能很慢,尤其是在传统旋转介质上。(正如中所述,位图扫描试图通过按排序顺序进行堆访问来缓解这项成本,但那也只能缓解到一定程度。) + PostgreSQL中的所有索引都是二级索引,也就是说,每个索引都与表的主数据区分开存储(在PostgreSQL术语中,这个主数据区称为表的)。这意味着,在普通索引扫描中,每次取回一行都需要同时从索引和堆中取数据。此外,尽管满足某个可索引WHERE条件的索引项通常在索引中彼此接近,但它们引用的表行却可能分布在堆中的任何位置。因此,索引扫描的堆访问部分会涉及大量对堆的随机访问,这可能很慢,尤其是在传统旋转介质上。(正如中所述,位图扫描试图通过按排序顺序进行堆访问来缓解这项代价,但那也只能缓解到一定程度。) @@ -686,7 +686,7 @@ CREATE INDEX mytable_cat_data ON mytable (category, data); - 查询只能引用存储在索引中的列。例如,给定一个表,它有列xyz,而索引建立在xy上,那么下面这些查询可以使用仅索引扫描: + 查询只能引用存储在索引中的列。例如,假设某个表的xy列上有一个索引,且该表还有一列z,那么下面这些查询可以使用仅索引扫描: SELECT x, y FROM tab WHERE x = 'key'; SELECT x FROM tab WHERE x = 'key' AND y < 42; @@ -713,17 +713,17 @@ SELECT x FROM tab WHERE x = 'key' AND z < 42; INCLUDE - in index definitions + 在索引定义中 为了有效利用仅索引扫描特性,你可以选择创建一个覆盖索引,也就是专门设计来包含某一类高频查询所需列的索引。由于查询通常需要取回的列不止是用于搜索的那些列,PostgreSQL允许你创建一种索引,其中某些列只是负载,而不是搜索键的一部分。这是通过添加一个INCLUDE子句列出这些额外列来实现的。例如,如果你经常运行如下查询: SELECT y FROM tab WHERE x = 'key'; - 传统上,为了加速这类查询,通常会只在x上创建一个索引。但如果将索引定义为: + 传统上,为了加速这类查询,通常会只在x上创建一个索引。但如果将索引定义为: CREATE INDEX tab_x_y ON tab(x) INCLUDE (y); - 那么这些查询就可以以仅索引扫描的方式完成,因为y可以直接从索引中取得,而不必访问堆。 + 那么这些查询就可以以仅索引扫描的方式完成,因为y可以直接从索引中取得,而不必访问堆。 @@ -735,7 +735,7 @@ CREATE UNIQUE INDEX tab_x_y ON tab(x) INCLUDE (y); - 向索引中添加非键负载列时,明智的做法是保持保守,尤其是宽列。如果某个索引元组超过该索引类型允许的最大尺寸,数据插入就会失败。无论如何,非键列都会复制索引对应表中的数据并让索引膨胀,因此可能拖慢搜索。另外请记住,除非表变化足够缓慢,以至于仅索引扫描很可能无需访问堆,否则把负载列包含在索引中并没有太大意义。如果反正必须访问堆元组,那么顺便从那里取出该列的值也不会增加额外成本。其他限制包括:当前不支持把表达式作为包含列;并且当前只有 B-树、GiST 和 SP-GiST 索引支持包含列。 + 向索引中添加非键负载列时,明智的做法是保持保守,尤其是宽列。如果某个索引元组超过该索引类型允许的最大尺寸,数据插入就会失败。无论如何,非键列都会复制索引对应表中的数据并让索引膨胀,因此可能拖慢搜索。另外请记住,除非表变化足够缓慢,以至于仅索引扫描很可能无需访问堆,否则把负载列包含在索引中并没有太大意义。如果反正必须访问堆元组,那么顺便从那里取出该列的值也不会增加额外代价。其他限制包括:当前不支持把表达式作为包含列;并且当前只有 B-树、GiST 和 SP-GiST 索引支持包含列。 @@ -781,11 +781,11 @@ SELECT target FROM tests WHERE subject = 'some-subject' AND success; 操作符类和操作符族 - operator class + 操作符类 - operator family + 操作符族 @@ -903,8 +903,8 @@ CREATE INDEX test1c_content_y_index ON test1c (content COLLATE "y"); 检查索引使用情况 - index - examining usage + 索引 + 检查使用情况 diff --git a/zh/19/information_schema.sgml b/zh/19/information_schema.sgml index 152dd54d..b37925f5 100644 --- a/zh/19/information_schema.sgml +++ b/zh/19/information_schema.sgml @@ -388,7 +388,7 @@ collation_catalog sql_identifier - 包含此属性排序规则的数据库名(总是当前数据库),如果默认或者该属性的数据类型不可排序则为空 + 包含该属性排序规则的数据库名称(总是当前数据库);如果使用默认排序规则,或该属性的数据类型不支持排序规则,则为 null。 @@ -397,7 +397,7 @@ collation_schema sql_identifier - 包含此属性排序规则的模式名,如果默认或者该属性的数据类型不可排序则为空 + 包含该属性排序规则的模式名称;如果使用默认排序规则,或该属性的数据类型不支持排序规则,则为 null。 @@ -406,7 +406,7 @@ collation_name sql_identifier - 该属性排序规则的名称,如果默认或者该属性的数据类型不可排序则为空 + 该属性排序规则的名称;如果使用默认排序规则,或该属性的数据类型不支持排序规则,则为 null。 @@ -1626,7 +1626,7 @@ collation_catalog sql_identifier - 包含此属性排序规则的数据库名(总是当前数据库),如果默认或者该属性的数据类型不可排序则为空 + 包含该列排序规则的数据库名称(总是当前数据库);如果使用默认排序规则,或该列的数据类型不支持排序规则,则为 null。 @@ -1635,7 +1635,7 @@ collation_schema sql_identifier - 该列的包含排序规则的模式名,如果默认或者该列的数据类型不可排序则为空 + 包含该列排序规则的模式名称;如果使用默认排序规则,或该列的数据类型不支持排序规则,则为 null。 @@ -1644,7 +1644,7 @@ collation_name sql_identifier - 该列的排序规则的名称,如果默认或者该列的数据类型不可排序则为空 + 该列排序规则的名称;如果使用默认排序规则,或该列的数据类型不支持排序规则,则为 null。 @@ -2385,7 +2385,7 @@ collation_catalog sql_identifier - 包含此域排序规则的数据库名(总是当前数据库),如果默认或者该域的数据类型不可排序则为空 + 包含该域排序规则的数据库名称(总是当前数据库);如果使用默认排序规则,或该域的数据类型不支持排序规则,则为 null。 @@ -2394,7 +2394,7 @@ collation_schema sql_identifier - 包含此域排序规则的模式名,如果默认或者该域的数据类型不可排序则为空 + 包含该域排序规则的模式名称;如果使用默认排序规则,或该域的数据类型不支持排序规则,则为 null。 @@ -2403,7 +2403,7 @@ collation_name sql_identifier - 该域排序规则的名称,如果默认或者该域的数据类型不可排序则为空 + 该域排序规则的名称;如果使用默认排序规则,或该域的数据类型不支持排序规则,则为 null。 @@ -2558,7 +2558,7 @@ <literal>element_types</literal> - 视图element_types包含数组元素的数据类型描述符。当一个表列、复合类型属性、域、函数参数或函数返回值被定义为一种数组类型,相应的信息模式视图只在列data_type中包含ARRAY。要获得该数组元素类型的信息,你可以连接该相应的视图和这个视图。例如,要显示一个表的列及其数据类型和数组元素类型,你可以: + 视图element_types包含数组元素的数据类型描述符。当一个表列、复合类型属性、域、函数参数或函数返回值被定义为一种数组类型时,相应的信息模式视图只在列data_type中包含ARRAY。要获得该数组元素类型的信息,你可以连接该相应的视图和这个视图。例如,要显示一个表的列及其数据类型和数组元素类型(如果适用),你可以: SELECT c.column_name, c.data_type, e.data_type AS element_type FROM information_schema.columns c LEFT JOIN information_schema.element_types e @@ -2689,7 +2689,7 @@ ORDER BY c.ordinal_position; collation_catalog sql_identifier - 包含元素类型排序规则的数据库名称(总是当前数据库), 如果默认或该元素的数据类型是不可排序的则为空 + 包含该元素类型排序规则的数据库名称(总是当前数据库);如果使用默认排序规则,或该元素类型不支持排序规则,则为 null。 @@ -2698,7 +2698,7 @@ ORDER BY c.ordinal_position; collation_schema sql_identifier - 包含元素类型排序规则的模式名称, 如果默认或该元素的数据类型是不可排序的则为空 + 包含该元素类型排序规则的模式名称;如果使用默认排序规则,或该元素类型不支持排序规则,则为 null。 @@ -2707,7 +2707,7 @@ ORDER BY c.ordinal_position; collation_name sql_identifier - 元素类型的排序规则名, 如果默认或该元素的数据类型是不可排序的则为空 + 该元素类型排序规则的名称;如果使用默认排序规则,或该元素类型不支持排序规则,则为 null。 @@ -4434,7 +4434,7 @@ ORDER BY c.ordinal_position; collation_catalog sql_identifier - 包含该属性排序规则的数据库名称(始终是当前数据库),如果是默认值或该属性的数据类型不可排序,则为空。 + 包含该属性排序规则的数据库名称(总是当前数据库);如果使用默认排序规则,或该属性的数据类型不支持排序规则,则为 null。 @@ -4443,7 +4443,7 @@ ORDER BY c.ordinal_position; collation_schema sql_identifier - 包含该属性排序规则的模式名称,如果是默认值或该属性的数据类型不可排序,则为空。 + 包含该属性排序规则的模式名称;如果使用默认排序规则,或该属性的数据类型不支持排序规则,则为 null。 @@ -4452,7 +4452,7 @@ ORDER BY c.ordinal_position; collation_name sql_identifier - 该属性排序规则的名称,如果是默认值或该属性的数据类型不可排序,则为空。 + 该属性排序规则的名称;如果使用默认排序规则,或该属性的数据类型不支持排序规则,则为 null。 @@ -8142,7 +8142,7 @@ ORDER BY c.ordinal_position; - SQL 了解两种用户定义类型:结构类型(在PostgreSQL中也称为复合类型)以及 distinct type(PostgreSQL 尚未实现)。为兼顾将来,请使用列user_defined_type_category来区分它们。其他用户定义类型,如基类型和枚举(两者都是PostgreSQL的扩展),不会在这里显示。域的相关信息见。 + SQL 中有两种用户定义类型:结构类型(在PostgreSQL中也称为复合类型)以及独立类型(distinct type,PostgreSQL 尚未实现)。为兼顾将来,请使用列user_defined_type_category来区分它们。其他用户定义类型,如基础类型和枚举(两者都是PostgreSQL的扩展),不会在这里显示。域的相关信息见 @@ -8874,7 +8874,7 @@ ORDER BY c.ordinal_position; check_optioncharacter_data - CASCADEDLOCAL 如果视图上有CHECK OPTION 定义,如果没有则为NONE。 + CASCADEDLOCAL 如果视图上有CHECK OPTION 定义,如果没有则为NONE diff --git a/zh/19/installation.sgml b/zh/19/installation.sgml index 7287ee9a..d825316c 100644 --- a/zh/19/installation.sgml +++ b/zh/19/installation.sgml @@ -4,7 +4,7 @@ 从源代码安装 - installation + 安装 @@ -362,7 +362,7 @@ 使用 Autoconf 和 Make 进行构建和安装 - 简短版本 + 简要说明 @@ -379,7 +379,7 @@ su - postgres /usr/local/pgsql/bin/createdb test /usr/local/pgsql/bin/psql test - 较长版本见本其余部分。 + 详细说明见本的其余部分。 @@ -607,7 +607,7 @@ build-postgresql: <filename>configure</filename> 选项 - 配置选项 + configure 选项 @@ -1031,7 +1031,7 @@ build-postgresql: ,使用 OSSP UUID library + url="http://www.ossp.org/pkg/lib/uuid/">OSSP UUID 库 @@ -1094,13 +1094,7 @@ build-postgresql: 这一特性要求 libxml2 2.6.23 或更高版本。 - - 为了检测所需的编译器和链接器选项,如果系统已安装 - pkg-config 且知道 libxml2,PostgreSQL - 会查询 pkg-config。否则,如果找得到由 libxml2 - 安装的 xml2-config 程序,就会使用它。 - 优先使用 pkg-config,因为它能更好地处理多架构安装。 - + 为检测所需的编译器和链接器选项,PostgreSQL 会查询 pkg-config,前提是已安装该程序且其中有 libxml2 的信息。否则,如果找到 libxml2 安装的 xml2-config 程序,就会使用它。优先使用 pkg-config,因为它能更好地处理多架构安装。 如果 libxml2 安装在不常见的位置,你可以设置与 @@ -1142,7 +1136,7 @@ build-postgresql: - 反功能 + 禁用特性 本节描述的选项允许禁用某些默认会构建的 @@ -1287,8 +1281,7 @@ build-postgresql: - 不在 PostgreSQL 的可执行文件中标记, - 使其在运行时到安装的库目录中搜索共享库(见 )。 + 不在 PostgreSQL 的可执行文件中添加指示其到安装的库目录中搜索共享库的标记(见 )。 在大多数平台上,这种标记使用库目录的绝对路径,因此如果你之后移动安装位置, 它就没有帮助了。不过这样一来,你就需要通过其他方式让可执行文件找到共享库。 通常这要求配置操作系统的动态链接器搜索该库目录;更多细节见 @@ -1305,7 +1298,7 @@ build-postgresql: 杂项 - 调整默认端口号 相当常见, + 使用 调整默认端口号相当常见, 尤其是在测试性构建中。本节中的其他选项只推荐给高级用户。 @@ -1340,10 +1333,10 @@ build-postgresql: - 设置 segment size,单位为 GB。 + 设置 段大小,单位为 GB。 大表会被分成多个操作系统文件,每个文件的大小等于段大小。 这可以避免很多平台上的文件大小限制问题。默认段大小 1GB 在所有支持的平台上 - 都是安全的。如果你的操作系统支持 largefile + 都是安全的。如果你的操作系统支持 大文件 (如今大多数都支持),你可以使用更大的段大小。 这有助于减少处理超大表时消耗的文件描述符数量。 但请注意不要选择超出你的平台和打算使用的文件系统所支持的值。 @@ -1359,7 +1352,7 @@ build-postgresql: - 设置 block size,单位为 KB。 + 设置 块大小,单位为 KB。 这是表内部存储和 I/O 的单位。默认值 8KB 适合大多数场景, 但在特殊情况下,其他取值也可能有用。 该值必须是 1 到 32(KB)之间的 2 的幂。 @@ -1373,7 +1366,7 @@ build-postgresql: - 设置 WAL block size,单位为 KB。 + 设置 WAL 块大小,单位为 KB。 这是 WAL 日志内部存储和 I/O 的单位。默认值 8KB 适合大多数场景, 但在特殊情况下,其他取值也可能有用。 该值必须是 1 到 64(KB)之间的 2 的幂。 @@ -1423,11 +1416,11 @@ build-postgresql: - 在服务器中启用 assertion 检查,用于测试许多 - 不应该发生的条件。这对代码开发非常有价值,但这些测试会显著拖慢 + 在服务器中启用 断言 检查,用于测试许多 + 不可能发生的条件。这对代码开发非常有价值,但这些测试可能会显著拖慢 服务器速度。此外,启用这些测试并不一定会增强服务器稳定性! 断言检查并未按严重程度分类,因此即使某个 bug 相对无害,只要触发了断言失败, - 仍可能导致服务器重启。该选项不建议用于生产环境,但如果你在做开发工作 + 仍会导致服务器重启。该选项不建议用于生产环境,但如果你在做开发工作 或运行测试版,就应当启用它。 @@ -1472,7 +1465,7 @@ build-postgresql: 如果使用 GCC,所有程序和库都会被编译成可进行性能分析的形式。 - 后端退出时,会创建一个子目录,其中包含带有 profile 数据的 + 后端退出时,会创建一个子目录,其中包含带有性能分析数据的 gmon.out 文件。 该选项只适用于 GCC,并且仅在开发工作中使用。 @@ -1544,7 +1537,7 @@ build-postgresql: <filename>configure</filename> 环境变量 - configure environment variables + configure 环境变量 @@ -1611,7 +1604,7 @@ build-postgresql: 在使用 --with-llvm 编译时, - 用于处理源代码以内联的 clang 程序路径 + 用于处理源代码以进行内联的 clang 程序路径 @@ -1815,7 +1808,7 @@ build-postgresql: 使用 Meson 构建和安装 - 简短版本 + 简要说明 @@ -1833,7 +1826,7 @@ su - postgres /usr/local/pgsql/bin/createdb test /usr/local/pgsql/bin/psql test - 较长版本见本其余部分。 + 详细说明见本的其余部分。 @@ -2383,7 +2376,7 @@ ninja install ,使用 OSSP UUID library + url="http://www.ossp.org/pkg/lib/uuid/">OSSP UUID 库 @@ -2471,7 +2464,7 @@ ninja install - 反功能 + 禁用特性 @@ -2527,7 +2520,7 @@ ninja install 设置这个选项,可以覆盖所有 auto 特性的取值 (也就是那些在找到所需软件时会自动启用的特性)。 - 当你想一次性禁用或启用所有 optional 特性, + 当你想一次性禁用或启用所有 可选 特性, 而不必逐个手工设置时,这会很有用。 该参数的默认值是 auto。 @@ -2653,9 +2646,8 @@ ninja install - 该选项默认值是 true。如果设为 false,则不会在 - PostgreSQL 的可执行文件中标记, - 使其在运行时到安装的库目录中搜索共享库(见 )。 + 该选项默认值是 true。如果设为 false,则不在 + PostgreSQL 的可执行文件中添加指示其到安装的库目录中搜索共享库的标记(见 )。 在大多数平台上,这种标记使用库目录的绝对路径,因此如果你之后移动安装位置, 它就没有帮助了。不过这样一来,你就需要通过其他方式让可执行文件找到共享库。 通常这要求配置操作系统的动态链接器搜索该库目录;更多细节见 @@ -2756,10 +2748,10 @@ ninja install - 设置 segment size,单位为 GB。 + 设置 段大小,单位为 GB。 大表会被分成多个操作系统文件,每个文件的大小等于段大小。 这可以避免很多平台上的文件大小限制问题。默认段大小 1GB 在所有支持的平台上 - 都是安全的。如果你的操作系统支持 largefile + 都是安全的。如果你的操作系统支持 大文件 (如今大多数都支持),你可以使用更大的段大小。 这有助于减少处理超大表时消耗的文件描述符数量。 但请注意不要选择超出你的平台和打算使用的文件系统所支持的值。 @@ -2773,7 +2765,7 @@ ninja install - 设置 block size,单位为 KB。 + 设置 块大小,单位为 KB。 这是表内部存储和 I/O 的单位。默认值 8KB 适合大多数场景, 但在特殊情况下,其他取值也可能有用。 该值必须是 1 到 32(KB)之间的 2 的幂。 @@ -2785,7 +2777,7 @@ ninja install - 设置 WAL block size,单位为 KB。 + 设置 WAL 块大小,单位为 KB。 这是 WAL 日志内部存储和 I/O 的单位。默认值 8KB 适合大多数场景, 但在特殊情况下,其他取值也可能有用。 该值必须是 1 到 64(KB)之间的 2 的幂。 @@ -2871,11 +2863,11 @@ ninja install - 在服务器中启用 assertion 检查,用于测试许多 - 不应该发生的条件。这对代码开发非常有价值,但这些测试会显著拖慢 + 在服务器中启用 断言 检查,用于测试许多 + 不可能发生的条件。这对代码开发非常有价值,但这些测试会显著拖慢 服务器速度。此外,启用这些测试并不一定会增强服务器稳定性! 断言检查并未按严重程度分类,因此即使某个 bug 相对无害,只要触发了断言失败, - 仍可能导致服务器重启。该选项不建议用于生产环境,但如果你在做开发工作 + 仍会导致服务器重启。该选项不建议用于生产环境,但如果你在做开发工作 或运行测试版,就应当启用它。 @@ -2896,10 +2888,10 @@ ninja install - 启用额外测试套件;这些测试默认不会运行,因为它们不适合在多用户系统上运行、 + 启用额外测试套件;这些测试默认不会运行,因为它们在多用户系统上运行不安全、 需要特殊软件,或者资源消耗较大。该参数是以空白分隔的测试名称列表。 详见 。如果在运行测试时设置了 - PG_TEST_EXTRA 环境变量,那么它会覆盖这个构建时选项。 + PG_TEST_EXTRA 环境变量,那么它会覆盖这个配置阶段的选项。 @@ -3175,7 +3167,7 @@ export MANPATH 此外,也请参阅 中关于如何解释回归测试结果的说明。 - + 这里未列出的平台,目前没有已知的平台特定安装问题。 @@ -3199,7 +3191,7 @@ export MANPATH export OBJECT_MODE=64 meson setup ... - 如果不这样做,通常会看到 ar 报告文件具有错误的对象文件模式。 + 如果不这样做,通常会看到 ar 报告文件具有错误的目标文件模式。 @@ -3237,14 +3229,14 @@ meson setup ... 不支持 adduser 命令;请使用 Windows 中相应的 - 用户管理应用。除此之外,跳过这一步即可。 + 用户管理应用。也可以跳过这一步。 不支持 su 命令;请在 Windows 上使用 ssh 来模拟 su。 - 除此之外,跳过这一步即可。 + 也可以跳过这一步。 @@ -3275,16 +3267,11 @@ meson setup ... - - 并行回归测试(make check)可能会因为 - listen() backlog 队列溢出而产生伪造的回归测试失败, - 进而导致连接拒绝错误或挂起。你可以像下面这样使用 make 变量 - MAX_CONNECTIONS 来限制连接数: + 并行回归测试(make check)可能因 listen() 的待处理连接队列溢出而误报回归测试失败;队列溢出会导致连接被拒绝的错误或挂起。可以使用 make 变量 MAX_CONNECTIONS 限制连接数,方法如下: make MAX_CONNECTIONS=5 check - (在某些系统上,同时连接数大致最多可达到 10 个。) - +(在某些系统上,并发连接数最高可达约 10 个。) @@ -3357,7 +3344,7 @@ xcrun --show-sdk-path macOS 的 - System Integrity Protection(SIP)特性会破坏 + 系统完整性保护(SIP)特性会破坏 make check,因为它会阻止把所需的 DYLD_LIBRARY_PATH 设置传递给被测试的可执行文件。 你可以通过在 make check 之前先执行 @@ -3421,10 +3408,10 @@ xcrun --show-sdk-path - configure 抱怨测试程序失败 + configure 报告测试程序失败 - 如果 configure 抱怨某个测试程序失败, + 如果 configure 报告某个测试程序失败, 这多半是因为运行时链接器找不到某些库,通常是 libz、libreadline, 或其他非标准库如 libssl。要把它指向正确位置,请在 configure 命令行中设置环境变量 LDFLAGS, diff --git a/zh/19/libpq.sgml b/zh/19/libpq.sgml index b813e4a9..85568605 100644 --- a/zh/19/libpq.sgml +++ b/zh/19/libpq.sgml @@ -41,7 +41,7 @@ - 如果不可信用户能够访问一个没有采用模式的安全使用方式的数据库,那么每个会话开始时都应从search_path中移除公开可写的模式。可以把参数关键词options设置为-csearch_path=。也可以在连接后发出PQexec(conn, "SELECT pg_catalog.set_config('search_path', '', false)")。这种考虑并非专门针对libpq;它适用于每一种可执行任意 SQL 命令的接口。 + 如果不受信任的用户能够访问一个没有采用模式的安全使用方式的数据库,那么每个会话开始时都应从search_path中移除公开可写的模式。可以把参数关键词options设置为-csearch_path=。也可以在连接后发出PQexec(conn, "SELECT pg_catalog.set_config('search_path', '', false)")。这种考虑并非专门针对libpq;它适用于每一种可执行任意 SQL 命令的接口。 @@ -214,7 +214,7 @@ PostgresPollingStatusType PQconnectPoll(PGconn *conn); - hostaddrhost参数必须被合适地使用,以防止做DNS查询。详见中这些参数的文档。 + 必须正确使用 hostaddr 参数,以避免执行 DNS 查询。详细信息请参见中该参数的说明。 @@ -298,14 +298,6 @@ PostgresPollingStatusType PQconnectPoll(PGconn *conn); - - CONNECTION_SETENV - - - 协商环境驱动的参数设置。 - - - CONNECTION_CHECK_WRITABLE @@ -320,7 +312,7 @@ PostgresPollingStatusType PQconnectPoll(PGconn *conn); CONNECTION_CHECK_STANDBY - 检查连接的是否为备库模式下的服务器。 + 检查连接的服务器是否处于备用模式。 @@ -369,9 +361,8 @@ switch(PQstatus(conn)) PQsocketPollPQsocketPoll - nonblocking connection - 轮询通过取得的连接底层套接字描述符。 - 该函数的主要用途是迭代文档中所述的连接序列。 + 非阻塞连接 + 轮询通过取得的连接底层套接字描述符。此函数主要用于逐步执行文档中描述的连接过程。 typedef int64_t pg_usec_time_t; @@ -381,24 +372,19 @@ int PQsocketPoll(int sock, int forRead, int forWrite, - 此函数对文件描述符执行轮询,并可选地设置超时。 - 如果forRead非零,则当套接字准备好读取时函数终止。如果forWrite非零,则当套接字准备好写入时函数终止。 + 此函数对文件描述符进行轮询,并可选择设置超时。如果forRead非零,则在套接字可读时结束。如果forWrite非零,则在套接字可写时结束。 - 超时由end_time指定,它是以 Unix 纪元以来的微秒数(即time_t乘以 100 万)表示的停止等待时间。 - 如果end_time-1,则超时时间为无限。如果end_time0(或任何早于当前的时间),则立即超时(不阻塞)。 - 可以把所需微秒数加到的结果上,以方便地计算超时值。请注意,底层系统调用的精度可能低于微秒,因此实际延迟可能不精确。 + 超时由end_time指定,它表示停止等待的时刻,以自 Unix 纪元以来的微秒数表示(即time_t乘以一百万)。如果end_time-1,则无限等待。如果 end_time0(或任何早于当前时刻的时间),则立即超时(不阻塞)。将所需的微秒数加到的结果上,即可方便地计算超时值。注意,底层系统调用的精度可能低于微秒,因此实际延迟可能不精确。 - 如果满足指定条件,函数返回大于0的值;如果发生超时,则返回0;如果发生错误,则返回-1。 - 可以通过检查errno(3)的值来获取错误。如果forReadforWrite均为零,函数会立即返回超时指示。 + 如果满足指定条件,函数返回大于0的值;如果发生超时,返回0;如果发生错误,返回-1。可以通过检查errno(3)的值获取错误信息。如果forReadforWrite都为零,函数会立即返回超时指示。 - PQsocketPoll会根据平台使用poll(2)select(2)实现。 - 更多信息请参见poll(2)中的POLLINPOLLOUT,或select(2)中的readfdswritefds。 + PQsocketPoll根据平台使用poll(2)select(2)实现。更多信息请参见poll(2)中的POLLINPOLLOUT,或select(2)中的readfdswritefds @@ -835,7 +821,7 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname 参数关键词 - 目前被识别的参数关键字包括: + 目前被识别的参数关键字包括: @@ -1007,9 +993,7 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname 服务器必须请求 MD5 哈希密码认证。 - - 对 MD5 加密密码的支持已被废弃,并将在未来的PostgreSQL版本中移除。关于迁移到其他密码类型的细节,请参见。 - + 对 MD5 加密密码的支持已弃用,并将在PostgreSQL的未来版本中移除。迁移到其他密码类型的详细信息见 @@ -1113,7 +1097,7 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname - 指定连接开始时发送到服务器的命令行选项。例如,将其设置为-c geqo=off会把会话的geqo参数值设为off。 + 指定连接开始时发送到服务器的命令行选项。例如,将其设置为-c geqo=off--geqo=off会把会话的geqo参数值设为off。 此字符串中的空格被视为分隔命令行参数,除非用反斜杠(\)转义;写\\表示字面上的反斜杠。 有关可用选项的详细讨论,请参阅 @@ -1571,12 +1555,20 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname sslrootcert - - 这个参数指定一个包含SSL证书颁发机构(CA)证书的文件名。 - 如果文件存在,服务器的证书将被验证是否由这些机构之一签名。 - 默认值是~/.postgresql/root.crt。 + 此参数指定包含 SSL 证书颁发机构(CA)证书的文件名。如果文件存在,则会验证服务器证书是否由这些机构之一签名。默认值为~/.postgresql/root.crt。 + + + 也可以指定特殊值system,此时会加载 SSL 实现提供的受信任 CA 根证书。这些根证书的确切位置因 SSL 实现和平台而异。对于OpenSSL,还可以通过SSL_CERT_DIRSSL_CERT_FILE环境变量进一步修改这些位置。 + + + + 使用sslrootcert=system时,默认的sslmode会改为verify-full,任何较弱的设置都会引发错误。在大多数情况下,任何人都很容易为其控制的主机名获取受系统信任的证书,因此verify-ca及所有更弱的模式都无法发挥作用。 + + + 特殊值system优先于同名的本地证书文件。如果遇到这种情况,请改用其他路径,例如sslrootcert=./system + @@ -1680,7 +1672,7 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname 这个参数指定该连接允许的最低协议版本。默认情况下,允许使用 libpq所支持的任何 PostgreSQL协议版本, - 目前即3.0。如果服务器至少不支持这一协议版本, + 目前即3.0。如果服务器不支持此协议版本或更高版本, 则连接将被关闭。 @@ -1716,7 +1708,7 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname 但如果连接字符串指定了依赖更高协议版本的特性,则会使用 libpq支持的最新版本。如果服务器不支持客户端请求的协议版本, 连接会自动降级为服务器支持的较低次版本协议。连接尝试完成后, - 你可以使用PQfullProtocolVersion()来确定 + 你可以使用来确定 最终协商得到的确切协议版本。 @@ -1773,7 +1765,7 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname scram_client_key - 以 Base64 编码的 SCRAM client key。外部数据包装器或类似中间件可以利用它启用透传式 SCRAM 认证。一个实现示例见。普通用户或客户端应用不应直接指定它。 + 以 Base64 编码的 SCRAM 客户端密钥。外部数据包装器或类似中间件可以利用它启用透传式 SCRAM 认证。一个实现示例见。普通用户或客户端应用不应直接指定它。 @@ -1782,7 +1774,7 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname scram_server_key - 以 Base64 编码的 SCRAM server key。外部数据包装器或类似中间件可以利用它启用透传式 SCRAM 认证。一个实现示例见。普通用户或客户端应用不应直接指定它。 + 以 Base64 编码的 SCRAM 服务器密钥。外部数据包装器或类似中间件可以利用它启用透传式 SCRAM 认证。一个实现示例见。普通用户或客户端应用不应直接指定它。 @@ -2050,7 +2042,7 @@ char *PQpass(const PGconn *conn); 将返回连接参数中指定的密码,如果连接参数中没有密码并且能从密码文件中得到密码,则它将返回得到的密码。 - 在后一种情况中,如果连接参数中指定了多个主机,在连接被建立之前都不能依赖的结果。连接的状态可以用函数检查。 + 在后一种情况中,如果连接参数中指定了多个主机,在连接被建立之前都不能依赖的结果。连接的状态可以用函数检查。 @@ -2204,13 +2196,13 @@ PGTransactionStatusType PQtransactionStatus(const PGconn *conn); - 查找服务器的一个当前参数设置。 + 查找服务器某个参数的当前设置。 const char *PQparameterStatus(const PGconn *conn, const char *paramName); - 某一参数值会被服务器在连接开始或值改变时自动报告。可以被用来询问这些设置。它为已知的参数返回当前值,为未知的参数返回NULL。 + 服务器会在连接启动时,以及某些参数值发生变化时,自动报告这些参数值。可用于查询这些设置。如果已知该参数,则返回其当前值;如果未知,则返回NULL @@ -2232,16 +2224,12 @@ const char *PQparameterStatus(const PGconn *conn, const char *paramName); standard_conforming_strings TimeZone - (default_transaction_read_onlyin_hot_standby在 14 以前的版本中不被报告;scram_iterations在 16 以前的版本中不被报告;search_path在 18 以前的版本中不被报告。) - 注意 server_version 和 - server_encoding在启动之后无法改变。 - 此外,从 9.5 及更高版本开始,integer_datetimes总是 - on,而从 19 及更高版本开始, - standard_conforming_strings总是on。 + (14 之前的版本不报告 default_transaction_read_onlyin_hot_standby;16 之前的版本不报告 scram_iterations;18 之前的版本不报告 search_path。) + 注意,server_versionserver_encoding 在启动后不能改变。此外,integer_datetimes 在 9.5 及以后的版本中始终为 onstandard_conforming_strings 在 19 及以后的版本中始终为 on - 尽管被返回的指针被声明成const,它事实上指向与PGconn结构体相关的可变存储。假定该指针在存储之间保持有效是不明智的。 + 返回的指针虽然被声明为const,但实际上指向与PGconn结构体关联的可变存储。不能假定该指针在执行其他查询后仍然有效。 @@ -2255,12 +2243,10 @@ const char *PQparameterStatus(const PGconn *conn, const char *paramName); int PQfullProtocolVersion(const PGconn *conn); - 应用可能希望使用此函数确定是否支持某些特性。结果由服务器的主版本号乘以 10000,再加上次版本号而得。 - 例如,版本 3.2 返回 30002,版本 4.0 返回 40000。如果连接已损坏,则返回零。 - PostgreSQL 7.4 及以上服务器版本支持 3.0 协议。 + 应用程序可以使用此函数确定是否支持某些功能。结果由服务器的协议主版本号乘以 10000,再加上次版本号组成。例如,版本 3.2 返回 30002,版本 4.0 返回 40000。如果连接无效,则返回零。PostgreSQL服务器 7.4 及更高版本支持 3.0 协议。 - 连接启动完成后,协议版本不会改变,但理论上它可能在连接重置期间改变。 + 连接启动完成后,协议版本不会改变,但在连接重置期间,理论上可能改变。 @@ -2270,14 +2256,11 @@ int PQfullProtocolVersion(const PGconn *conn); - 查询正在使用的前端/后端协议主版本。 + 查询前端/后端协议的主版本号。 int PQprotocolVersion(const PGconn *conn); - 与 不同,此函数只返回正在使用的 - 协议主版本,但它得到更广泛的 libpq 版本支持,最早可追溯到 7.4 版。 - 当前可能的值为 3(3.0 协议)或零(连接损坏)。在 14.0 版之前, - libpq 还可能返回 2(2.0 协议)。 + 与 不同,此函数仅返回正在使用的协议主版本号,但从 7.4 起的更多 libpq 版本均支持它。目前可能的值为 3(协议 3.0)或零(连接异常)。在 14.0 之前的版本中,libpq 还可能返回 2(协议 2.0)。 @@ -2401,15 +2384,14 @@ int PQconnectionUsedPassword(const PGconn *conn); PQconnectionUsedGSSAPIPQconnectionUsedGSSAPI - 如果连接认证方法使用了 GSSAPI,则返回真(1)。否则返回假(0)。 - + 如果连接的认证方法使用了 GSSAPI,则返回真(1);否则返回假(0)。 int PQconnectionUsedGSSAPI(const PGconn *conn); - 可使用此函数检测连接是否通过 GSSAPI 进行了认证。 + 此函数可用于检测连接是否使用 GSSAPI 进行了认证。 @@ -2497,6 +2479,14 @@ const char *PQsslAttribute(const PGconn *conn, const char *attribute_name); + + alpn + + + TLS 应用层协议协商(ALPN)扩展选定的应用协议。libpq 唯一支持的协议是 postgresql,因此该属性主要用于检查服务器是否支持 ALPN。如果未使用 ALPN,则为空字符串。 + + + @@ -2513,13 +2503,16 @@ const char *PQsslAttribute(const PGconn *conn, const char *attribute_name); PQsslAttributeNamesPQsslAttributeNames - - 返回可供PQsslAttribute()使用的 SSL 属性名称数组。 - 数组以NULL指针结尾。 + 返回可用于 PQsslAttribute() 的 SSL 属性名称数组。数组以 NULL 指针结尾。 const char * const * PQsslAttributeNames(const PGconn *conn); + + + + + 如果 conn 为 NULL,则返回默认 SSL 库可用的属性;如果 libpq 编译时未启用任何 SSL 支持,则返回空列表。如果 conn 不为 NULL,则返回该连接所用 SSL 库可用的属性;如果连接未加密,则返回空列表。 @@ -2699,7 +2692,7 @@ PGresult *PQexecParams(PGconn *conn, paramTypes[] - 通过 OID 指定要赋予给参数符号的数据类型。如果paramTypesNULL或者该数组中任何特定元素为零,服务器会用对待未知类型文字串的方式为参数符号推测一种数据类型。 + 通过 OID 指定要赋予给参数符号的数据类型。如果paramTypesNULL或者该数组中任何特定元素为零,服务器会用对待未指定类型的字符串字面量的方式为参数符号推测一种数据类型。 @@ -2793,10 +2786,10 @@ PGresult *PQprepare(PGconn *conn, 该函数从query串创建一个名为stmtName的预备语句,该串必须包含一个单一 SQL 命令。 stmtName可以是""来创建一个未命名语句,在这种情况下任何已存在未命名语句将被自动替换。 - 如果语句名称已经在当前会话中被定义,则是一种错误。如果使用了任何参数,它们在查询中以$1$2等引用。 + 否则,如果语句名称已经在当前会话中被定义,则是一种错误。如果使用了任何参数,它们在查询中以$1$2等引用。 nParams是参数的个数,其类型在数组paramTypes[]中被预先指定(当nParams为零时,该数组指针可以是NULL)。 paramTypes[]通过 OID 指定要赋予给参数符号的数据类型。 - 如果paramTypesNULL或者该数组中任何特定元素为零,服务器会用对待未知类型文字串的方式为参数符号推测一种数据类型。 + 如果paramTypesNULL或者该数组中任何特定元素为零,服务器会用对待未指定类型的字符串字面量的方式为参数符号推测一种数据类型。 还有,查询能够使用编号高于nParams的参数符号,它们的数据类型也会被自动推测(找出推测出的数据类型的方法见)。 @@ -2809,7 +2802,6 @@ PGresult *PQprepare(PGconn *conn, 用于的预备语句也能通过执行 SQL 语句来创建。 - 还有,尽管没有libpq函数来删除一个预备语句,SQL 语句可被用于此目的。 @@ -3061,10 +3053,8 @@ ExecStatusType PQresultStatus(const PGresult *res); PGRES_TUPLES_CHUNK - PGresult包含当前命令返回的多个结果元组。 - 这个状态只在查询选择了分块模式时发生(见)。 - 元组数不会超过传递给的限制。 - + PGresult包含当前命令返回的若干结果元组。此状态仅在为查询选择了分块模式时出现(参见)。元组数不会超过传递给的上限。 + @@ -3072,9 +3062,8 @@ ExecStatusType PQresultStatus(const PGresult *res); PGRES_PIPELINE_SYNC - PGresult表示管道模式中的同步点,由请求。 - 此状态仅在选择管道模式时发生。 - + PGresult 表示管道模式中的同步点,由 请求。此状态仅在已选择管道模式时出现。 + @@ -3217,7 +3206,7 @@ char *PQresultErrorField(const PGresult *res, int fieldcode); PG_DIAG_MESSAGE_DETAIL - 细节:一个可选的次级错误消息,它携带了关于问题的等多细节。可能有多行。 + 细节:一个可选的次级错误消息,它携带了关于问题的更多细节。可能有多行。 @@ -3235,7 +3224,7 @@ char *PQresultErrorField(const PGresult *res, int fieldcode); PG_DIAG_STATEMENT_POSITION - 包含一个十进制整数的字符串,它表示一个错误游标位置,该位置是原始语句字符串的索引。第一个字符的索引是 1,位置以字符计算而不是以及字节计算。 + 包含一个十进制整数的字符串,它表示一个错误游标位置,该位置是原始语句字符串的索引。第一个字符的索引是 1,位置以字符计算而不是以字节计算。 @@ -4029,8 +4018,8 @@ unsigned char *PQescapeByteaConn(PGconn *conn, - 当某些字节值被用作一个SQL语句中的bytea文字的一部分时,它们必须被转义。 - 转义使用十六进制编码或反斜线转义的字节。详见。 + 当某些字节值被用作一个SQL语句中的bytea字面量的一部分时,它们必须被转义。 + 使用十六进制编码或反斜杠转义来转义这些字节。详见 @@ -4080,7 +4069,8 @@ unsigned char *PQescapeBytea(const unsigned char *from, - 将二进制数据的一个字符串表示转换成二进制数据 — 它是的逆向函数。当检索文本格式的bytea数据时,需要这个函数,但检索二进制个事时则不需要它。 + 将二进制数据的字符串表示转换为二进制数据,这是的逆操作。 + 以文本格式取得bytea数据时需要此操作;以二进制格式取得时则不需要。 unsigned char *PQunescapeBytea(const unsigned char *from, size_t *to_length); @@ -4088,14 +4078,15 @@ unsigned char *PQunescapeBytea(const unsigned char *from, size_t *to_length); - from参数指向一个字符串,例如被应用到一个bytea列上所返回的。 - 把这个串表示转换成它的二进制表示。 - 它返回一个指向用malloc()分配的缓冲区的指针,在错误时返回NULL,并且把缓冲区的尺寸放在to_length中。 - 当结果不再需要时,它必须使用释放。 + from参数指向一个字符串,例如对bytea列调用时返回的字符串。 + 将这个字符串表示转换为二进制表示。 + 它返回指向通过malloc()分配的缓冲区的指针,出错时返回NULL,并将缓冲区大小存入to_length。 + 不再需要结果时,必须使用释放它。 - 这种转换并不完全是PQescapeBytea的逆函数,因为当从PQgetvalue接收到字符串时,我们并不能期待它被转义。特别地这意味着不需要考虑字符串引用,并且因此也不需要一个参数。 + 此转换并不完全是的逆操作,因为从收到的字符串并非经过转义的形式。 + 具体而言,这意味着无需考虑字符串引号,因此也不需要PGconn参数。 @@ -4144,26 +4135,17 @@ unsigned char *PQunescapeBytea(const unsigned char *from, size_t *to_length); - - 不喜欢这些限制的应用程序可以使用构建自的底层函数: - 。 - 还有 - , - , - , - , - , - 以及 - , - 它们可以与配合使用,分别复制 - , - , - , - , - , - 和 - - 的功能。 + 如果应用程序不希望受到这些限制,可以改用构成的底层函数:。此外,还有, + , + , + , + , + ,以及,它们可以与配合使用,分别实现以下函数的功能:, + , + , + , + , + ,以及 @@ -4338,15 +4320,16 @@ int PQsendClosePortal(PGconn *conn, const char *portalName); - 等待来自先前的、 + 等待先前的 、 - 或 - - 调用的下一个结果,并返回它。 - 当命令完成且不会再有更多结果时,将返回空指针。 + 、 + 、 + 、 + 或 + 调用产生的下一个结果,并返回该结果。当命令执行完毕且不再有其他结果时,返回空指针。 PGresult *PQgetResult(PGconn *conn); @@ -4450,7 +4433,7 @@ int PQisBusy(PGconn *conn); 一个使用/的客户端也可以尝试取消一个正在被服务器处理的命令,见。 - 但是,不管的返回值是什么,应用都必须继续使用进行正常的结果读取序列。一次成功的取消只会导致命令比不取消时更快终止。 + 但是,不管的返回值是什么,应用都必须继续使用进行正常的结果读取序列。一次成功的取消只会导致命令比不取消时更快终止。 @@ -4614,68 +4597,42 @@ int PQflush(PGconn *conn); - 发出查询 - 进入管道模式后,应用程序使用或其姊妹函数来分派请求。 - 这些请求在客户端排队,直到刷新到服务器端;当使用建立管道中的同步点时,或者调用时,会发生这种情况。 - 函数在管道模式下也可以工作。 - 结果处理如下所述。 + 进入管道模式后,应用程序使用 或其处理预备查询的对应函数 发送请求。这些请求在客户端排队,直到发送到服务器;使用 在管道中建立同步点,或调用 时会发送它们。函数 、&zwsp;、&zwsp;、&zwsp; 也可用于管道模式。结果处理方式见下文。 - 服务器执行语句,并返回结果,按客户端发送它们的顺序。 - 服务器将立即开始执行管道中的命令,不等待管道的结束。 - 注意,结果被缓冲在服务器端;当使用PQpipelineSync建立同步点时,或者PQsendFlushRequest被调用时,服务器会刷新该缓冲区。 - 如果任何语句遇到错误,服务器将中止当前事务,并且不执行队列中的任何后续命令,直到下一个同步点;对于每一个这样的命令都会产生一个PGRES_PIPELINE_ABORTED结果。 - (即使管道中的命令将回滚事务,依然如此。) - 查询处理在同步点之后恢复。 + 服务器按客户端发送的顺序执行语句并返回结果。服务器会立即开始执行管道中的命令,无需等待管道结束。结果会缓存在服务器端;使用 PQpipelineSyncPQsendPipelineSync 建立同步点,或调用 PQsendFlushRequest 时,服务器会发送该缓冲区中的数据。如果任何语句发生错误,服务器会中止当前事务,并停止执行队列中的后续命令,直到下一个同步点;每条被跳过的命令都会产生一个 PGRES_PIPELINE_ABORTED 结果。(即使管道中的命令会回滚事务,也仍然如此。)到达同步点后,查询处理恢复。 - 一个操作依赖于前一个操作的结果是没问题的; - 例如,一个查询可以定义一个同一管道中的下一个查询将用到的表。 - 类似地,应用可以创建一个命名的预备语句,并在同一管道中与后续语句一起执行它。 + 一个操作可以依赖先前操作的结果;例如,一个查询可以定义一张表,供同一管道中的下一个查询使用。类似地,应用程序可以创建命名的预备语句,并通过同一管道中后续的语句执行它。 - 处理结果 - 为了在管道中处理一个查询的结果,应用重复调用PQgetResult并处理每个结果,直到PQgetResult返回空。 - 可以再次使用PQgetResult检索管道中下一个查询的结果,并且循环重复 - 应用像通常一样处理单个语句结果。 - 当管道中所有查询的结果都返回时,PQgetResult返回一个结果,其包含状态值PGRES_PIPELINE_SYNC。 + 要处理管道中一个查询的结果,应用程序应重复调用 PQgetResult 并处理每个结果,直到 PQgetResult 返回空指针。然后再次调用 PQgetResult 获取管道中下一个查询的结果,重复这一过程。应用程序按通常方式处理各条语句的结果。当管道中所有查询的结果都已返回时,PQgetResult 会返回一个包含状态值 PGRES_PIPELINE_SYNC 的结果。 - 客户端可以选择延迟结果处理,直到完整的管道被发送,或者与管道中发送的更多的查询交错在一起;参见。 + 客户端可以等到整条管道发送完毕后再处理结果,也可以在继续发送管道中的查询时交错处理结果;参见 - 要进入单行模式,在使用PQgetResult检索结果之前调用PQsetSingleRowMode。 - 此模式选择仅对当前处理的查询有效。 - 有关使用PQsetSingleRowMode的更多信息,请参阅。 + PQgetResult 的行为与普通异步处理相同,只是返回结果可能具有新的 PGresult 类型 PGRES_PIPELINE_SYNCPGRES_PIPELINE_ABORTED。对于每次 PQpipelineSyncPQsendPipelineSync 调用,都会在管道中的对应位置恰好报告一次 PGRES_PIPELINE_SYNC。对于第一个错误及其后的所有结果,会用 PGRES_PIPELINE_ABORTED 代替正常查询结果,直到下一个 PGRES_PIPELINE_SYNC;参见 - PQgetResult行为与普通异步处理相同,除了它可能包含新的PGresult类型PGRES_PIPELINE_SYNCPGRES_PIPELINE_ABORTED。 - 对于每个在管道中相应的点的PQpipelineSyncPGRES_PIPELINE_SYNC确定报告一次。 - PGRES_PIPELINE_ABORTED在第一个错误和所有后续结果的正常查询结果中发出,直到下一个PGRES_PIPELINE_SYNC;参见。 + PQisBusyPQconsumeInput 等函数在处理管道结果时照常工作。特别地,在管道处理过程中调用 PQisBusy 时,如果到目前为止已发出查询的所有结果均已被消费,则返回 0。 - PQisBusyPQconsumeInput、等正常操作,在处理管道结果时。 - 特别是,在管道中间调用PQisBusy 时,如果到目前为止发出的所有查询的结果都已被消耗,则返回0。 - - - - libpq不向应用提供有关当前正在处理的查询的任何信息(除了PQgetResult返回空,以表示我们开始返回下一个查询的结果)。 - 应用必须保持跟踪它发送查询的顺序,以将它们与相应的结果相关联。 - 应用通常会为此使用状态机或FIFO队列。 + libpq 不向应用程序提供当前正在处理哪个查询的信息(除了 PQgetResult 返回空指针,表示开始返回下一个查询的结果)。应用程序必须跟踪查询的发送顺序,以便将查询与对应结果关联起来。应用程序通常会使用状态机或 FIFO 队列实现这一点。 @@ -4722,7 +4679,7 @@ int PQflush(PGconn *conn); 客户端应用通常应该维护一个尚未分派的工作队列和一个已分派但尚未处理结果的工作队列。 当套接字是可写时,它将可以分派更多的工作。 当套接字是可读时,它将读取结果并处理它们,将它们匹配到相应结果队列中的下一个条目。 - 基于可用内存,来自套接字的结果将被经常读取:这里不需要等到管道结束才读取结果。 + 基于可用内存,来自套接字的结果将被经常读取:这里不需要等到管道结束才读取结果。 管道将范围涵盖到工作的逻辑单元,通常(但不是必然)每个管道一个事务。 在管道之间,不需要退出管道模式再重新进入管道模式,也不需要等待一个管道结束后再发送下一个。 @@ -4753,7 +4710,7 @@ PGpipelineStatus PQpipelineStatus(const PGconn *conn); - PQpipelineStatus 可以返回下列值中的一个: + PQpipelineStatus 可以返回下列值中的一个: @@ -4897,8 +4854,8 @@ int PQsendFlushRequest(PGconn *conn); - 当PQpipelineSync被调用的结果,或者在非管道模式下的任何请求时,服务器自动刷新它的输出缓冲区;这个函数用于使得服务器在不建立同步点的情况下以管道模式刷新其输出缓冲区。 - 请注意,请求不是自身能自动刷新到服务器;如果需要时使用PQflush。 + 当PQpipelineSync被调用的结果,或者在非管道模式下的任何请求时,服务器自动刷新它的输出缓冲区;这个函数用于使得服务器在不建立同步点的情况下以管道模式刷新其输出缓冲区。 + 请注意,请求不是自身能自动刷新到服务器;如果需要时使用PQflush @@ -4918,7 +4875,7 @@ int PQsendFlushRequest(PGconn *conn); 当服务器比较远,即网络延迟(ping time)高的时候,管道模式最有用,以及在许多小操作正在快速连续执行的时候。 当每个查询的执行时间是客户端/服务器往返时间的许多倍时,使用管道命令的优势通常会更少。 - 不用管道模式,在往返时间为300毫秒的服务器上运行一个100条语句的操作,仅网络延迟就需要30秒;使用管道,等待来自服务器的结果可能只消耗仅仅0.3秒。 + 不用管道模式,在往返时间为300毫秒的服务器上运行一个100条语句的操作,仅网络延迟就需要30秒;使用管道,等待来自服务器的结果可能只消耗仅仅0.3秒。 @@ -4929,7 +4886,7 @@ int PQsendFlushRequest(PGconn *conn); 当来自一个操作的信息需要客户端产生下一个操作时,管道模式是没有用的。 在这种情况下,客户机将不得不引入一个同步点,并等待完整的客户端/服务器往返以获取它需要的结果。 但是,通常可以调整客户端设计以交换服务器端所需的信息。 - 读-修改-写循环是非常好的选择;例如: + 读-修改-写循环是非常好的选择;例如: BEGIN; SELECT x FROM mytable WHERE id = 42 FOR UPDATE; @@ -4938,7 +4895,7 @@ SELECT x FROM mytable WHERE id = 42 FOR UPDATE; UPDATE mytable SET x = 3 WHERE id = 42; COMMIT; - 可以更有效地开展以下工作: + 可以更有效地开展以下工作: UPDATE mytable SET x = x + 1 WHERE id = 42; @@ -4955,12 +4912,12 @@ UPDATE mytable SET x = x + 1 WHERE id = 42; libpq - single-row mode + 单行模式 libpq - chunked mode + 分块模式 @@ -5340,22 +5297,23 @@ void PQfreeCancel(PGcancel *cancel); - 请求服务器放弃当前命令的处理。 + 的一个已弃用且不安全的变体,但可以在信号处理程序中安全调用。 int PQcancel(PGcancel *cancel, char *errbuf, int errbufsize); + - 返回值为 1 表示取消请求成功发送,为 0 表示未成功发送。如果未成功发送,errbuf将填充解释性错误消息。errbuf必须是大小为errbufsize的字符数组(推荐大小为 256 字节)。 + 仅因向后兼容而保留,应改用 唯一的优势在于:当 errbuf 是信号处理程序中的局部变量时,可以在信号处理程序中安全调用它。不过,通常认为这一优势不足以抵消该函数的安全问题。 - 取消请求成功分派并不保证一定会产生效果。如果取消成功,当前命令会提前终止并返回错误结果;如果取消失败(例如服务器已经处理完该命令),则不会有任何可见结果。 + 对于 而言,PGcancel 对象是只读的,因此也可以从与操作 PGconn 对象的线程不同的线程中调用它。 - 如果errbuf是信号处理程序中的局部变量,则可以安全地从信号处理程序中调用。对于而言,PGcancel对象是只读的,因此也可以从与操作PGconn对象的线程不同的线程中调用。 + 的返回值为 1 表示取消请求成功发送,为 0 表示未成功发送。如果未成功发送,errbuf 将填充解释性错误消息。errbuf 必须是大小为 errbufsize 的字符数组(推荐大小为 256 字节)。 @@ -5367,14 +5325,19 @@ int PQcancel(PGcancel *cancel, char *errbuf, int errbufsize); - 的一个已废弃变体。 + 的一个已弃用且不安全的变体。 int PQrequestCancel(PGconn *conn); + - 请求服务器放弃当前命令的处理。它直接作用于PGconn对象,失败时会把错误消息存储到PGconn对象中(可通过获取)。虽然功能相同,但这种方法在多线程程序或信号处理程序中并不安全,因为它可能覆盖PGconn中的错误消息,从而破坏当前连接上正在进行的操作。 + 仅因向后兼容而保留,应改用 。与 相比,使用 没有任何优势。 + + + + 请求服务器放弃当前命令的处理。它直接作用于 PGconn 对象,失败时会把错误消息存储到 PGconn 对象中(可通过 获取)。虽然功能相同,但这种方法在多线程程序或信号处理程序中并不安全,因为它可能覆盖 PGconn 中的错误消息,从而破坏当前连接上正在进行的操作。 @@ -5437,7 +5400,7 @@ typedef struct - 要传递NULL参数到函数,将参数结构体的len字段设置为-1;isintu 字段就不相关了。 + 要传递NULL参数到函数,将参数结构体的len字段设置为-1isintu 字段就不相关了。 @@ -5694,7 +5657,7 @@ int PQgetCopyData(PGconn *conn, 当async为真时(非零),将不会阻塞等待输入; 如果COPY仍在处理过程中并且没有可用的完整行,那么它将返回零 (在这种情况下等待读准备好,然后在再次调用之前,调用)。 - 当async为假(零)时,PQgetCopyData将阻塞,直到数据可用或者操作完成。 + 当async为假(零)时,将阻塞,直到数据可用或者操作完成。 @@ -5994,7 +5957,7 @@ void PQtrace(PGconn *conn, FILE *stream); - 每行包括:一个可选的时间戳,一个方向指示器(F表示从客户端到服务器的消息或B表示从服务器到客户端的消息),消息长度、消息类型、和消息内容。 + 每行包括:一个可选的时间戳,一个方向指示器(F表示从客户端到服务器的消息或B表示从服务器到客户端的消息),消息长度、消息类型、和消息内容。 非消息内容字段(时间戳、方向、长度和消息类型)由一个制表符分隔。 消息内容用空格分隔。 协议字符串用双引号括起来,而用作数据值的字符串用单引号括起来。 @@ -6168,7 +6131,7 @@ PGresult *PQchangePassword(PGconn *conn, const char *user, const char *passwd); char *PQencryptPassword(const char *passwd, const char *user); - 的一个较老的已经被废弃的版本。其差别是不要求一个连接对象,并且总是用md5作为加密算法。 + 的旧版本,现已弃用。其差别是不需要连接对象,并且总是用md5作为加密算法。 @@ -6188,11 +6151,12 @@ PGresult *PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status); 这是libpq内部用于分配并初始化一个空PGresult对象的函数。 - 如果不能分配内存,那么这个函数返回NULL。 - 它也是可以对外使用的,因为一些应用认为它可以用于产生结果对象(特别是带有错误状态的对象)本身。 - 如果conn非空,并且status表示一个错误,那么指定连接的当前错误消息会被复制到PGresult中。 - 如果conn非空,那么连接中的任何已注册事件过程也会被复制到PGresult中(它们不会获得PGEVT_RESULTCREATE调用,但会看到)。 - 注意在该对象上最终应该调用,正如对libpq本身返回的PGresult对象所作的那样。 + 如果无法分配内存,此函数返回NULL。 + 将它导出供外部调用,是因为一些应用需要自行生成结果对象,特别是带有错误状态的对象。 + 如果conn非空,并且status表示错误,指定连接的当前错误消息会被复制到PGresult中。 + 此外,如果conn非空,连接中注册的所有事件过程也会被复制到PGresult中。 + (这些过程不会收到PGEVT_RESULTCREATE调用,但可参见。) + 注意,最终应对该对象调用,就像处理libpq自身返回的PGresult一样。 @@ -6377,15 +6341,15 @@ int PQlibVersion(void); - 获取当前时间,表示为 Unix 纪元以来的微秒数(即time_t乘以 100 万)。 + 获取当前时间,以自 Unix 纪元以来的微秒数表示(即time_t乘以一百万)。 pg_usec_time_t PQgetCurrentTimeUSec(void); - + - 该函数主要用于计算传递给的超时值。 - + 此函数主要用于计算供使用的超时值。 + @@ -6569,8 +6533,8 @@ typedef struct - 结果创建事件是响应任何生成结果的查询执行函数而触发的,包括 - 。此事件只会在结果成功创建后触发。 + 任何生成结果的查询执行函数都会触发结果创建事件,其中包括。 + 只有成功创建结果后才会触发该事件。 typedef struct @@ -6580,11 +6544,9 @@ typedef struct } PGEventResultCreate; - 当接收到PGEVT_RESULTCREATE事件时, - 应将evtInfo指针转换为 - PGEventResultCreate *。 - conn是用于生成结果的连接。 - 这是初始化需要与结果关联的任何instanceData的理想位置。 + 收到PGEVT_RESULTCREATE事件时,应将evtInfo指针转换为PGEventResultCreate *。 + 其中,conn是用于生成结果的连接。 + 这是初始化需要与结果关联的instanceData的理想位置。 如果事件过程失败(返回零),那么该事件过程将在结果的剩余生命周期内被忽略; 也就是说,它将不会接收到针对此结果或从中复制的结果的 PGEVT_RESULTCOPYPGEVT_RESULTDESTROY事件。 @@ -6954,6 +6916,15 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough) + + + + PGSSLNEGOTIATION + + PGSSLNEGOTIATION的行为与连接参数相同。 + + + @@ -7022,6 +6993,15 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough) + + + + PGREQUIREAUTH + + PGREQUIREAUTH的行为与连接参数相同。 + + + @@ -7133,6 +7113,15 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough) + + + + PGSSLCERTMODE + + PGSSLCERTMODE的行为与连接参数相同。 + + + @@ -7243,6 +7232,15 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough) + + + + PGGSSDELEGATION + + PGGSSDELEGATION的行为与连接参数相同。 + + + @@ -7281,8 +7279,7 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough) PGLOADBALANCEHOSTS - PGLOADBALANCEHOSTS的行为与连接参数相同。 + PGLOADBALANCEHOSTS的行为与连接参数相同。 @@ -7291,8 +7288,7 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough) PGMINPROTOCOLVERSION - PGMINPROTOCOLVERSION的行为与连接参数相同。 + PGMINPROTOCOLVERSION的行为与连接参数相同。 @@ -7301,8 +7297,7 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough) PGMAXPROTOCOLVERSION - PGMAXPROTOCOLVERSION的行为与连接参数相同。 + PGMAXPROTOCOLVERSION的行为与连接参数相同。 @@ -7392,20 +7387,15 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough) - 用户的主目录中的文件.pgpass可以包含密码, - 如果连接需要密码(且未指定其他密码)。在Microsoft Windows中, - 该文件的名称为%APPDATA%\postgresql\pgpass.conf - (其中%APPDATA%指用户配置文件中的应用数据子目录)。 - 或者,可以使用连接参数 - 或环境变量PGPASSFILE指定要使用的密码文件。 - + 用户主目录中的.pgpass文件可保存密码,供连接需要密码且尚未通过其他方式指定密码时使用。在 Unix 系统上,该目录可由HOME环境变量指定;如果未定义该变量,则使用有效用户的主目录。在 Microsoft Windows 上,文件名为%APPDATA%\postgresql\pgpass.conf(其中%APPDATA%指用户配置文件中的应用数据子目录)。也可以通过连接参数或环境变量PGPASSFILE指定要使用的密码文件。 + 这个文件应该包含下列格式的行: hostname:port:database:username:password - (你可以向该文件增加一个提醒:把上面的行复制到该文件并且在前面加上#)。前四个域的每一个都可以是文字值或者匹配任何东西的*。第一个匹配当前连接参数的行中的密码域将被使用(因此,在使用通配符时把更特殊的项放在前面)。如果一个条目需要包含:或者\,用\对该字符转义。如果指定了host连接参数,主机名字段会被匹配到host,否则如果指定了hostaddr参数则匹配到hostaddr,如果两者都没有给出,则会搜索主机名localhost。当连接是一个Unix域套接字连接并且host参数匹配libpq的默认套接字目录路径时,也会搜索主机名localhost。在一台备库上,值为replication的数据库字段匹配连接到主库的流复制连接。否则数据库字段的用途有限,因为用户对同一个集簇中的所有数据库都有相同的密码。 + (你可以向该文件增加一个提醒:把上面的行复制到该文件并且在前面加上#)。前四个字段的每一个都可以是字面值或者匹配任何东西的*。第一个匹配当前连接参数的行中的密码字段将被使用(因此,在使用通配符时把更特殊的项放在前面)。如果一个条目需要包含:或者\,用\对该字符转义。如果指定了host连接参数,主机名字段会被匹配到host,否则如果指定了hostaddr参数则匹配到hostaddr,如果两者都没有给出,则会搜索主机名localhost。当连接是一个Unix域套接字连接并且host参数匹配libpq的默认套接字目录路径时,也会搜索主机名localhost。在一台备库上,值为replication的数据库字段匹配连接到主库的流复制连接。否则数据库字段的用途有限,因为用户对同一个集簇中的所有数据库都有相同的密码。 @@ -7835,16 +7825,14 @@ ldap://ldap.acme.com/cn=dbserver,cn=hosts?pgconnectinfo?base?(objectclass=*) - SSL 库初始化 - 如果您的应用程序初始化libssl和/或libcrypto库,并且libpq - 构建时带有SSL支持,您应该调用告诉libpq - libssl和/或libcrypto库已被您的应用程序初始化,以便 - libpq不会再初始化这些库。 - 但是,当使用OpenSSL版本1.1.0或更高版本时,重复初始化不再成问题。 - + 需要兼容旧版 PostgreSQL、使用 OpenSSL 1.0.2 或更早版本的应用程序,需要在使用 SSL 库之前初始化它。自行初始化 libssl 和/或 libcrypto 库的应用程序应调用 ,告知 libpq 这些库已由应用程序初始化,使 libpq 不再初始化它们。不过,使用 OpenSSL 1.1.0 或更高版本时无需这样做,因为重复初始化已不再造成问题。 + + + 有关这些函数的用法,请参阅目标 PostgreSQL 版本的文档。 + @@ -7853,44 +7841,35 @@ ldap://ldap.acme.com/cn=dbserver,cn=hosts?pgconnectinfo?base?(objectclass=*) - 允许应用选择要初始化哪个安全性库。 + 允许应用程序选择要初始化的安全库。 void PQinitOpenSSL(int do_ssl, int do_crypto); - - - 当do_ssl是非零时,libpq将在第一次打开数据库连接前初始化OpenSSL库。 - 当do_crypto是非零时,libcrypto库将被初始化。 - 默认情况下(如果没有调用),两个库都会被初始化。 - 当 SSL 支持没有被编译时,这个函数也存在但是什么也不做。 - 如果你的应用使用并且初始化OpenSSL或者它的底层libcrypto库,你必须在第一次打开数据库连接前以合适的非零参数调用这个函数。 - 同时要确保在打开一个数据库连接前已经完成了初始化。 + 此函数已弃用,仅为向后兼容而保留,不执行任何操作。 PQinitSSLPQinitSSL - - 允许应用选择要初始化哪个安全性库。 + 允许应用程序选择要初始化的安全库。 void PQinitSSL(int do_ssl); + - 这个函数等效于PQinitOpenSSL(do_ssl, do_ssl)。 - 这对于要么初始化OpenSSL以及libcrypto要么都不初始化的应用足够用了。 + 此函数等价于 PQinitOpenSSL(do_ssl, do_ssl)。此函数已弃用,仅为向后兼容而保留,不执行任何操作。 - PostgreSQL 8.0 就存在了, - 而直到PostgreSQL 8.4 才被加入,因此可能对那些需要与旧版本libpq一起工作的应用来说更合适。 + 为向后兼容而保留,但从 PostgreSQL 18 起已不再需要。PostgreSQL 8.0 起就已存在,而 是在 PostgreSQL 8.4 中加入的,因此对于需要兼容旧版本 libpq 的应用程序, 可能更合适。 @@ -8247,8 +8226,8 @@ PGOAUTHDEBUG=UNSAFE:http,call-count 危险选项与安全选项 在线程化程序中的行为 - threads - with libpq + 线程 + 用于 libpq diff --git a/zh/19/localize-generated.py b/zh/19/localize-generated.py index cc0f61a7..b41c3198 100644 --- a/zh/19/localize-generated.py +++ b/zh/19/localize-generated.py @@ -1,9 +1,9 @@ #!/usr/bin/env python3 -"""Apply only PG18.6-to-PG19 changed generated descriptions after regeneration. +"""Apply reviewed Chinese translations after regenerating the pinned PG19 input. Keep upstream generators and inputs intact. Each input/output is hash-bound; -unchanged descriptions retain the inherited generated English. The map is -reviewed source; generated SGML stays in the isolated build workspace. +the map is the maintained translation source. Generated SGML stays in the +isolated build workspace. """ import hashlib import json diff --git a/zh/19/logical-replication.sgml b/zh/19/logical-replication.sgml index 8acb74e3..930cbefb 100644 --- a/zh/19/logical-replication.sgml +++ b/zh/19/logical-replication.sgml @@ -235,7 +235,7 @@ 如前所述,每个(活动)订阅都使用远端(发布侧)的一个逻辑复制槽。 - 额外的表同步槽通常是临时的,由系统内部创建用于执行初始表同步,在不再需要时 + 额外的表同步槽通常只会短暂存在,由系统内部创建用于执行初始表同步,在不再需要时 自动删除。这些表同步槽的名称是自动生成的: pg_%u_sync_%u_%llu (参数分别为:订阅 oid、 @@ -293,7 +293,7 @@ 示例:建立逻辑复制 - 在发布端创建一个表 t1,供下面的示例使用。 + 在发布端创建一些测试表。 /* pub # */ CREATE TABLE t1(a int, b text, PRIMARY KEY(a)); /* pub # */ CREATE TABLE t2(c int, d text, PRIMARY KEY(c)); @@ -427,7 +427,7 @@ 注意在常规复制阶段会使用相应的 publish 操作。 这意味着发布 pub2pub3a 不会复制 - INSERT。另外,发布 pub3b 只会复制与其 + INSERT。另外,发布 pub3b 只会复制与 pub3b 的 行过滤器匹配的数据。现在订阅端数据如下: /* sub # */ SELECT * FROM t1; @@ -622,7 +622,7 @@ HINT: To initiate replication, you must manually create the replication slot, e - 要确认某个订阅对应的备库确实已做好故障切换准备,请按下列步骤验证该订阅需要的 + 要确认备库确实已为某个订阅端做好故障切换准备,请按下列步骤验证该订阅端需要的 所有逻辑复制槽都已同步到备库: @@ -691,7 +691,7 @@ HINT: To initiate replication, you must manually create the replication slot, e 上述步骤中的前两步针对的是 PostgreSQL 订阅端。 - 建议在每次故障切换后,都在将由目标备库服务的各个订阅节点上执行这两步,以获得完整的复制槽 + 建议在每个将于故障切换后由指定备库提供服务的订阅端节点上执行这两步,以获得完整的复制槽 列表,然后在第 3 步中统一验证故障切换就绪状态。 非 PostgreSQL 订阅端则可使用其自身方法识别各自订阅使用的复制槽。 @@ -1584,7 +1584,7 @@ Included in publications: 序列同步工作进程,并在序列同步完成后退出。 - 启动序列同步工作进程的数量受 + 能否启动序列同步工作进程受 max_sync_workers_per_subscription 配置项限制。 @@ -1786,10 +1786,10 @@ Included in publications: 冲突 - 逻辑复制的行为与普通 DML 类似:即使订阅端节点上的数据已在本地被修改, - 传入的变更仍会更新它。如果传入数据违反任何约束,复制就会停止,这被称为 + 逻辑复制的行为在一点上类似于普通 DML 操作:即使订阅节点上的数据已在本地被修改, + 传入的变更仍会更新它。如果传入数据违反了任何约束,复制就会停止,这种情况称为 冲突。在复制 UPDATE 或 - DELETE 操作时,找不到目标数据也会被视为 + DELETE 操作时,找不到目标数据也被视为 冲突,但不会报错,这类操作会被直接跳过。 @@ -1803,10 +1803,10 @@ Included in publications: insert_exists - 插入某行时违反了一个 NOT DEFERRABLE 唯一约束。请注意, - 若要在日志中记录冲突键的来源和提交时间戳详情,订阅端应启用 + 插入某行时违反了一个 NOT DEFERRABLE 唯一约束。 + 请注意,若要在日志中记录冲突键的来源和提交时间戳详情,订阅端应启用 track_commit_timestamp。 - 这种情况下,直到手工解决冲突前都会持续报错。 + 这种情况下,系统会持续报错,直到手工解决该冲突。 @@ -1814,7 +1814,7 @@ Included in publications: update_origin_differs - 更新一行,而该行此前已被另一复制源修改。请注意,只有在订阅端启用了 + 更新一行,而该行此前已被另一来源修改。请注意,只有在订阅端启用了 track_commit_timestamp 时才能检测到这种冲突。目前,无论本地行的来源是什么,更新都会照常应用。 @@ -1824,10 +1824,10 @@ Included in publications: update_exists - 某行更新后的值违反了一个 NOT DEFERRABLE 唯一约束。请注意, - 若要在日志中记录冲突键的来源和提交时间戳详情,订阅端应启用 + 某行更新后的值违反了一个 NOT DEFERRABLE 唯一约束。 + 请注意,若要在日志中记录冲突键的来源和提交时间戳详情,订阅端应启用 track_commit_timestamp。 - 这种情况下,直到手工解决冲突前都会持续报错。另请注意,在更新分区表时, + 这种情况下,系统会持续报错,直到手工解决该冲突。另请注意,在更新分区表时, 如果更新后的行值满足了另一个分区的约束,导致该行被插入到新分区中,而新行又 违反了一个 NOT DEFERRABLE 唯一约束,则可能出现 insert_exists 冲突。 @@ -1860,7 +1860,7 @@ Included in publications: delete_origin_differs - 删除一行,而该行此前已被另一复制源修改。请注意,只有在订阅端启用了 + 删除一行,而该行此前已被另一来源修改。请注意,只有在订阅端启用了 track_commit_timestamp 时才能检测到这种冲突。目前,无论本地行的来源是什么,删除都会照常应用。 @@ -1878,10 +1878,10 @@ Included in publications: multiple_unique_conflicts - 插入或更新某行时违反了多个 NOT DEFERRABLE 唯一约束。请注意, - 若要在日志中记录冲突键的来源和提交时间戳详情,请确保订阅端启用了 + 插入或更新某行时违反了多个 NOT DEFERRABLE 唯一约束。 + 请注意,若要在日志中记录冲突键的来源和提交时间戳详情,请确保订阅端启用了 track_commit_timestamp。 - 这种情况下,直到手工解决冲突前都会持续报错。 + 这种情况下,系统会持续报错,直到手工解决该冲突。 @@ -2012,7 +2012,7 @@ DETAIL: detailed_explanation[: 解决方法可以是修改订阅端上的数据或权限,使其不再与传入变更冲突;也可以跳过与 - 现有数据冲突的事务。当冲突导致错误时,复制不会继续,逻辑复制工作者会向订阅端 + 现有数据冲突的事务。当冲突导致错误时,复制不会继续,逻辑复制工作进程会向订阅端 的服务器日志输出如下消息: ERROR: conflict detected on relation "public.test": conflict=insert_exists @@ -2024,8 +2024,8 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER (在上述示例中分别是 LSN 0/014C0378 和复制源 pg_16395)。 可以使用 ALTER SUBSCRIPTION ... SKIP - 并提供 finish LSN(即 LSN 0/014C0378)来跳过产生冲突的事务。这个 finish LSN - 可以是该事务在发布端提交或准备完成时的 LSN。或者,也可以调用 + 并提供 完成 LSN(即 LSN 0/014C0378)来跳过产生冲突的事务。这个 完成 LSN + 可以是该事务在发布端提交或预备时的 LSN。或者,也可以调用 pg_replication_origin_advance() 函数来跳过该事务。 在使用此函数之前,需要暂时禁用订阅,可以使用 @@ -2034,7 +2034,7 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER disable_on_error 选项。然后,可以使用 pg_replication_origin_advance() 函数, 传入 node_name(即 pg_16395) - 以及 finish LSN 的下一个 LSN(即 0/014C0379)。当前各复制源的位置可以在 + 以及 完成 LSN 的下一个 LSN(即 0/014C0379)。当前各复制源的位置可以在 pg_replication_origin_status 系统视图中查看。 请注意,跳过整个事务也会跳过那些本来可能不违反任何约束的变更,这很容易导致 @@ -2049,10 +2049,10 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER streaming - 模式为 parallel 时,失败事务的 finish LSN 可能不会被记录。 + 模式为 parallel 时,失败事务的 完成 LSN 可能不会被记录。 这种情况下,可能需要把 streaming 模式改为 on 或 - off,并再次触发相同的冲突,以便将失败事务的 finish LSN - 写入服务器日志。关于 finish LSN 的用法,请参见 + off,并再次触发相同的冲突,以便将失败事务的 完成 LSN + 写入服务器日志。关于 完成 LSN 的用法,请参见 ALTER SUBSCRIPTION ... SKIP @@ -2070,9 +2070,9 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER 数据库模式和 DDL 命令不会被复制。初始模式可以手工使用 pg_dump --schema-only 复制。之后的模式更改需要手工保持同步。 (不过请注意,两端的模式其实不需要绝对一致。)当活动数据库中的模式定义发生变化时, - 逻辑复制仍然具有一定鲁棒性:如果发布端修改了模式,而复制数据开始到达订阅端时 + 逻辑复制仍然能够稳健运行:如果发布端修改了模式,而复制数据开始到达订阅端时 与表模式不匹配,复制就会报错,直到模式被更新。在很多情况下,可以通过先在订阅端 - 应用增量式的模式变更来避免间歇性错误。 + 应用仅添加内容的模式变更来避免间歇性错误。 @@ -2137,7 +2137,7 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER 对已发布表使用 REPLICA IDENTITY FULL 时,需要注意:如果表中包含某些数据类型的属性(例如 point 或 box),而这些类型 - 没有 B-tree 或 Hash 的默认操作符类,那么 UPDATE 和 + 没有 B-树 或 Hash 的默认操作符类,那么 UPDATEDELETE 操作就无法在订阅端应用。不过,可以通过确保该表具有 主键或已定义复制标识来规避这一限制。 @@ -2178,10 +2178,10 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER 初始快照 - 现有已订阅表中的初始数据会被快照化,并由特殊类型的应用进程并行复制。 - 这些特殊的应用进程是为每张待同步表启动的专用表同步工作者。每个表同步进程 + 对现有订阅表中的初始数据,会取快照并由一种特殊应用进程的并行实例来复制。 + 这些特殊的应用进程是为每张待同步表启动的专用表同步工作进程。每个表同步进程 都会创建自己的复制槽,并复制现有数据。复制一完成,该表内容就会对其他后端可见。 - 现有数据复制完成后,工作者会进入同步模式,通过标准逻辑复制流式发送在初始数据 + 现有数据复制完成后,工作进程会进入同步模式,通过标准逻辑复制流式发送在初始数据 复制期间发生的任何变更,使该表与主应用进程达到同步状态。在这一同步阶段, 变更会按照它们在发布端发生的顺序被应用和提交。同步完成后,该表的复制控制权 会交还给主应用进程,之后复制将照常继续。 @@ -2195,8 +2195,8 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER - 如果表同步工作者在复制期间失败,应用工作者会检测到这一失败,并重新启动表同步 - 工作者以继续同步过程。这种行为确保了瞬时错误不会永久破坏复制配置。另见 + 如果表同步工作进程在复制期间失败,应用工作进程会检测到这一失败,并重新启动表同步 + 工作进程以继续同步过程。这种行为确保了瞬时错误不会永久破坏复制配置。另见 wal_retrieve_retry_interval @@ -2216,14 +2216,14 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER 与订阅相关的监控信息可在 pg_stat_subscription - 中查看。这个视图为每个订阅工作者包含一行。一个订阅根据其状态,可能有零个或多个 - 活跃的订阅工作者。 + 中查看。这个视图为每个订阅工作进程包含一行。一个订阅根据其状态,可能有零个或多个 + 活跃的订阅工作进程。 通常,一个已启用的订阅会有一个应用进程在运行。被禁用的订阅或已崩溃的订阅在这个 视图中将没有任何行。如果某张表的初始数据同步正在进行,则还会有针对这些正在同步 - 的表的额外工作者。并且,如果使用 + 的表的额外工作进程。并且,如果使用 streaming 并以并行方式应用事务,则还可能出现额外的并行应用工作进程。 @@ -2311,14 +2311,14 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER - 在订阅端,订阅所有者的权限会在每个事务应用时重新检查。如果某个工作者正在应用 + 在订阅端,订阅所有者的权限会在每个事务应用时重新检查。如果某个工作进程正在应用 事务时,订阅的所有权被并发事务更改,那么当前事务的应用仍会继续使用旧所有者的 权限。 - 配置参数 + 配置设置 逻辑复制需要设置若干配置选项。这些选项只在复制的一侧生效。 @@ -2374,7 +2374,7 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER max_logical_replication_workers - 必须至少设置为订阅数量(用于主应用工作进程),再加上并行应用工作进程、 + 必须至少设置为订阅数量(用于领导者应用工作进程),再加上并行应用工作进程、 表同步工作进程和序列同步工作进程的预留。 @@ -2389,7 +2389,7 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER max_sync_workers_per_subscription - 控制订阅初始化或新增表时,可以并行同步多少张表。序列同步还需要一个额外工作者。 + 控制订阅初始化或新增表时,可以并行同步多少张表。序列同步还需要一个额外工作进程。 @@ -2511,8 +2511,8 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER - 旧订阅端中所有订阅表应处于 i(initialize)或 - r(ready)状态。可通过检查 + 旧订阅端中所有订阅表应处于 i(初始化)或 + r(就绪)状态。可通过检查 pg_subscription_rel.srsubstate 验证。 @@ -2534,8 +2534,8 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER - 如果存在启用了 retain_dead_tuples 的订阅,新集簇中保留复制槽 - pg_conflict_detection 不能存在。此外,新集簇上的 + 如果存在启用了 retain_dead_tuples 的订阅,新集簇中不能存在保留的复制槽 + pg_conflict_detection。此外,新集簇上的 wal_level 必须设置为 replicalogical diff --git a/zh/19/logicaldecoding.sgml b/zh/19/logicaldecoding.sgml index 082b70a4..62d42e32 100644 --- a/zh/19/logicaldecoding.sgml +++ b/zh/19/logicaldecoding.sgml @@ -269,7 +269,7 @@ postgres=# SELECT * from pg_logical_slot_get_changes('regression_slot', NULL, NU 需要各个进程之间的同步,因此可保证系统范围内的一致性。反之,如果 wal_level 设为 replica,并且最后 一个逻辑复制槽被删除或失效,则逻辑解码会自动停用。请注意,这种停用可能 - 需要一些时间,因为它是由 检查点 进程异步完成的。 + 需要一些时间,因为它是由检查点进程异步完成的。 @@ -392,7 +392,7 @@ postgres=# SELECT * from pg_logical_slot_get_changes('regression_slot', NULL, NU 中列出的槽,向逻辑订阅者发送更改时仍然会有一定延迟。使用 synchronized_standby_slots 时,主库在与 synchronized_standby_slots 中指定的物理复制槽相关联 - 的备库确认已接收到截至主库最新刷写位置的 WAL 之前,不会完全关闭。 + 的备库确认已接收到截至主库最新刷盘位置的 WAL 之前,不会完全关闭。 @@ -574,8 +574,7 @@ DETAIL: Synchronization could lead to data loss, because the remote slot needs 版本 2 在服务器版本 14 及以上受支持;当 - streaming 设置为 on 以流式传 - 输大型进行中事务时,必须使用该版本。 + streaming 设置为 on 以流式传输大型进行中事务时,必须使用该版本。 版本 3 在服务器版本 15 及以上受支持;当启用 @@ -593,9 +592,7 @@ DETAIL: Synchronization could lead to data loss, because the remote slot needs publication_names (string) - 一个以逗号分隔的 发布 名称列表,用于订阅。各个 - 发布 名称按标准对象名处理,并可在需要时按同样方式加引号。 - 至少需要一个 发布 名称。 + 要订阅的发布名称列表,以逗号分隔。各个发布名称按标准对象名处理,可按需加引号。至少需要一个发布名称。 @@ -625,13 +622,11 @@ DETAIL: Synchronization could lead to data loss, because the remote slot needs streaming (enum) - 启用对进行中事务的流式传输。有效值为 off(默 - 认)、onparallel。 + 启用对进行中事务的流式传输。有效值为 off(默认)、onparallel 当设置为 off 时, - pgoutput 会先完整解码一个事务,再将其整体发 - 送。该模式适用于任何协议版本。 + pgoutput 会先完整解码一个事务,再将其整体发送。该模式适用于任何协议版本。 当设置为 on 时, @@ -640,8 +635,7 @@ DETAIL: Synchronization could lead to data loss, because the remote slot needs 当设置为 parallel 时, - pgoutput 会流式传输大型进行中事务,并在某些消 - 息中额外发送信息,以支持并行处理。这要求协议版本为 4 或更高。 + pgoutput 会流式传输大型进行中事务,并在某些消息中额外发送信息,以支持并行处理。这要求协议版本为 4 或更高。 diff --git a/zh/19/maintenance.sgml b/zh/19/maintenance.sgml index 71363b21..6c0cbab5 100644 --- a/zh/19/maintenance.sgml +++ b/zh/19/maintenance.sgml @@ -383,11 +383,11 @@ 如果一个表正在积累全部可见但尚未全部冻结的页面,普通清理可能会选择扫描这些本可跳过的页面, 以尝试冻结它们。这样可以减少下一次激进扫描必须扫描的页面数。这类页面称为 - 积极扫描页。通过增大 ,可以调整积极扫描, - 使其尝试冻结更多全部可见页面。即使积极扫描已将全部可见但未全部冻结页面的数量降到最低, - 大多数表仍然需要周期性地进行激进扫描。不过,任何成功被积极冻结的页面在激进扫描时都可以跳过, - 因此积极冻结可以尽量减小激进扫描的开销。 + 急切扫描页。通过增大 ,可以调整急切扫描, + 使其尝试冻结更多全部可见页面。即使急切扫描已将全部可见但未全部冻结页面的数量降到最低, + 大多数表仍然需要周期性地进行激进扫描。不过,任何成功被急切冻结的页面在激进扫描时都可以跳过, + 因此急切冻结可以尽量减小激进扫描的开销。 @@ -403,7 +403,7 @@ 一个表在不被清理的情况下所能维持的最长时间,是最后一次激进扫描时的 vacuum_freeze_min_age 值从 20 亿事务中扣除后的结果。 如果超过这个时间仍不清理,就可能导致数据丢失。为了确保不会发生这种情况, - 任何可能包含未冻结行且其 XID 早于配置参数 所指定年龄的表,都会触发自动清理。 (即使自动清理已被禁用,也会如此。) @@ -492,11 +492,10 @@ SELECT datname, age(datfrozenxid) FROM pg_database; 虽然 VACUUM 主要扫描自上次清理以来被修改过的页面, - 但它也可能为了冻结它们而积极扫描某些全部可见但未全部冻结的页面; + 但它也可能为了冻结它们而急切扫描某些全部可见但未全部冻结的页面; 不过,只有当表中每一个可能包含未冻结 XID 的页面都被扫描时, relfrozenxid 才会被推进。当 - relfrozenxid 比 - vacuum_freeze_table_age 旧、使用了 VACUUM 的 + relfrozenxid的年龄超过vacuum_freeze_table_age个事务、使用了 VACUUMFREEZE 选项,或者所有尚未全部冻结的页面碰巧都需要清理以移除死行版本时, 就会发生这种情况。当 VACUUM 扫描了表中每个尚未全部冻结的页面时, 它应把 age(relfrozenxid) 设为略高于所用 @@ -596,22 +595,22 @@ HINT: Execute a database-wide VACUUM in that database. 多事务(multitransaction,MultiXact) ID 用于支持多个事务对行加锁。由于元组头中用于存储锁信息的空间有限, 当有多个事务同时锁定一行时,这些信息会被编码为一个多事务 ID, - 简称 multixact ID。某个特定 multixact ID 包含哪些事务 ID 的信息, + 简称 multixact ID。某个特定 多事务 ID 包含哪些事务 ID 的信息, 会单独存放在 pg_multixact 子目录中,而元组头的 - xmax 字段中只出现 multixact ID。和事务 ID 一样, - multixact ID 也是以 32 位计数器及其对应存储实现的,因此同样需要仔细处理老化管理、 - 存储清理和回卷问题。还有一个单独的存储区域保存每个 multixact 的成员列表, + xmax 字段中只出现 多事务 ID。和事务 ID 一样, + 多事务 ID 也是以 32 位计数器及其对应存储实现的,因此同样需要仔细处理老化管理、 + 存储清理和回卷问题。还有一个单独的存储区域保存每个 多事务 的成员列表, 它也使用 32 位计数器,因此同样必须被管理。 中介绍的系统函数 pg_get_multixact_members() - 可用于检查与某个 multixact ID 关联的事务 ID。 + 可用于检查与某个 多事务 ID 关联的事务 ID。 每当 VACUUM 扫描表的任何部分时,它都会把遇到的、早于 - 的任何 multixact ID 替换为另一个值,该值可能是零值、单个事务 ID,或者更新的 multixact ID。 + 的任何 多事务 ID 替换为另一个值,该值可能是零值、单个事务 ID,或者更新的 多事务 ID。 对于每个表,pg_class.relminmxid - 保存该表任何元组中仍可能出现的最老 multixact ID。如果这个值早于 + 保存该表任何元组中仍可能出现的最老 多事务 ID。如果这个值早于 ,就会强制执行一次激进扫描。 正如上一节所述,激进扫描意味着只有那些已知为全部冻结的页面才会被跳过。 可以对 pg_class.relminmxid @@ -621,15 +620,15 @@ HINT: Execute a database-wide VACUUM in that database. 无论出于何种原因而发生,激进的 VACUUM保证 能够推进表的 relminmxid。最终,随着所有数据库中的所有表都被扫描, - 并推进其最老的 multixact 值,较老 multixact 的磁盘存储就可以被移除。 + 并推进其最老的 多事务 值,较老 多事务 的磁盘存储就可以被移除。 - 作为一项安全措施,对于 多事务 年龄大于 的任何表,都会进行一次激进清理扫描。 - 此外,如果创建的 多事务 成员条目数量超过大约 20 亿个 + 此外,如果创建的多事务成员条目数量超过大约 20 亿个 (在 pg_multixact/members 目录中占用大约 10GB), - 就会更频繁地对所有表进行激进清理扫描,从 多事务 年龄最老的表开始。 + 就会更频繁地对所有表进行激进清理扫描,从多事务年龄最老的表开始。 即使自动清理名义上被禁用,这两类激进扫描也都会发生。 当条目数量达到大约 40 亿个 (在 pg_multixact/members 目录中占用大约 20GB)时, @@ -648,7 +647,7 @@ HINT: Execute a database-wide VACUUM in that database. 311740299 | 2785241176 | 13926205880 | 2 | 13 GB (1 row) - 该输出显示一个 多事务 活动明显的系统:大约 3.12 亿个 多事务 ID, + 该输出显示一个多事务活动明显的系统:大约 3.12 亿个 多事务 ID, 以及大约 28 亿个成员条目,占用 13 GB 存储空间。 如果 num_mxids 激增,可能表示多个会话正在运行带有外键检查的 UPDATE 语句、并发的 SELECT FOR SHARE @@ -670,11 +669,11 @@ HINT: Execute a database-wide VACUUM in that database. - 如果没有可能出现在 multixact 中,那么正在运行的事务和预备事务都可以忽略。 + 如果没有可能出现在 多事务 中,那么正在运行的事务和预备事务都可以忽略。 - 与事务 ID 回卷不同,复制槽不会直接阻止 multixact 清理。 - 因此,删除陈旧的复制槽通常与解决 multixact ID 回卷问题无关。 + 与事务 ID 回卷不同,复制槽不会直接阻止 多事务 清理。 + 因此,删除陈旧的复制槽通常与解决 多事务 ID 回卷问题无关。 MXID 信息不会直接出现在诸如 pg_stat_activity 这样的系统视图中; @@ -731,7 +730,7 @@ HINT: Execute a database-wide VACUUM in that database. - 对于 relfrozenxid 值早于 + 对于 relfrozenxid值的年龄超过 个事务的表,总是会执行清理 (这也适用于那些通过存储参数修改了冻结最大年龄的表,见下文)。 否则,如果自上次 VACUUM 以来已经失效的元组数超过了 @@ -770,7 +769,7 @@ vacuum insert threshold = vacuum base insert threshold + vacuum insert scale fac 因为这会让元组在更早的清理中被冻结。过时元组数和插入元组数取自累积统计系统; 这是一个由每次 UPDATEDELETEINSERT 操作更新的最终一致计数。如果该表的 - relfrozenxid 值早于 + relfrozenxid值的年龄超过 vacuum_freeze_table_age 个事务,就会执行一次激进扫描, 以冻结旧元组并推进 relfrozenxid @@ -837,15 +836,15 @@ analyze threshold = analyze base threshold + analyze scale factor * number of tu 自动清理分两步决定处理对象:首先选择一个数据库,然后选择该数据库中的表。 - 自动清理启动器进程会优先处理有事务 ID 或 多事务 ID 回卷风险的数据库, + 自动清理启动器进程会优先处理有事务 ID 或多事务 ID 回卷风险的数据库, 否则就选择最久未被处理的数据库。作为例外,它会跳过自上次统计信息重置以来没有连接 或没有活动的数据库,除非它们有回卷风险。 - 在数据库内部,自动清理工作进程会构建一个需要 清理 或 分析 的表列表, + 在数据库内部,自动清理工作进程会构建一个需要清理或分析的表列表, 并使用一个评分系统对其排序。它通过取若干分量评分中的最大值来为每个表打分, - 这些分量反映了对 清理 或 分析 重要的各种标准。各分量如下: + 这些分量反映了对清理或分析重要的各种标准。各分量如下: @@ -866,10 +865,10 @@ analyze threshold = analyze base threshold + analyze scale factor * number of tu 多事务 ID 分量衡量表的 pg_class.relminmxid - 字段按 多事务 数计算的年龄,并与 + 字段按多事务数计算的年龄,并与 比较。此外, 一旦年龄超过 , - 或者已创建的 多事务 成员条目数量超过大约 20 亿条 + 或者已创建的多事务成员条目数量超过大约 20 亿条 (见 ), 该分量会大幅增加。该分量的最终值可通过 调整。注意, @@ -926,12 +925,12 @@ analyze threshold = analyze base threshold + analyze scale factor * number of tu - 并行 清理 + 并行清理 VACUUM 可以使用后台工作进程并行执行索引清理(index vacuuming)和索引收尾清理(index cleanup)阶段 - (各个 清理 阶段的细节请参见 )。 - 并行度由该关系上支持并行 清理 的索引数量决定。对于手工 VACUUM, + (各个清理阶段的细节请参见 )。 + 并行度由该关系上支持并行清理的索引数量决定。对于手工 VACUUM, 如果指定了PARALLEL 选项,则受该选项限制;此外还会进一步受 限制。对于自动清理, 这受表的 限制(如果指定), @@ -942,8 +941,8 @@ analyze threshold = analyze base threshold + analyze scale factor * number of tu 只有当索引大小大于 时, - 它才能参与并行 清理。每个索引只能使用一个工作进程。因此,只有当表中至少有 - 2 个索引时,才会启动并行工作进程。清理 的工作进程会在每个阶段开始前启动, + 它才能参与并行清理。每个索引只能使用一个工作进程。因此,只有当表中至少有 + 2 个索引时,才会启动并行工作进程。清理的工作进程会在每个阶段开始前启动, 并在阶段结束时退出。这些行为在未来版本中可能会改变。 @@ -1090,7 +1089,7 @@ pg_ctl start | rotatelogs /var/log/pgsql_log 86400 不过,在很多系统上,syslog 并不十分可靠, 尤其是在日志消息很大时;它可能恰恰在你最需要消息的时候截断或丢弃它们。 此外,在 Linux 上, - syslog 会把每条消息都刷新到磁盘,导致性能较差。 + syslog 会把每条消息都刷盘,导致性能较差。 (你可以在 syslog 配置文件的文件名开头使用一个 - 来禁用同步。) diff --git a/zh/19/monitoring.sgml b/zh/19/monitoring.sgml index 7ed73721..e6bed225 100644 --- a/zh/19/monitoring.sgml +++ b/zh/19/monitoring.sgml @@ -87,15 +87,15 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - 累计统计系统 + 累积统计系统 - statistics + 统计信息 PostgreSQL累积统计系统支持收集和报告有关服务器活动的信息。 - 目前,对表和索引的访问以磁盘块和单个行的术语进行计数。每个表中的总行数, + 目前,对表和索引的访问分别以磁盘块和单行计数。每个表中的总行数, 以及每个表的清理和分析操作的信息也被计数。如果启用,对用户定义函数的调用 和每个函数中花费的总时间也会被计数。 @@ -107,7 +107,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - 统计收集配置 + 统计信息收集配置 由于收集统计信息会增加查询执行的开销,因此可以配置系统是否收集信息。这由通常在postgresql.conf中设置的配置参数控制(有关设置配置参数的详细信息,请参阅)。 @@ -160,11 +160,11 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - 另一个重要的观点是,当服务器进程被要求显示任何累积的统计信息时,在默认配置中,访问的值会被缓存直到当前事务结束。因此,只要您继续当前事务,统计信息将显示静态信息。类似地,当在事务中首次请求任何当前会话的查询信息时,会收集关于所有会话当前查询的信息,并且相同的信息将在整个事务中显示。这是一个特性,而不是一个错误,因为它允许您在统计信息上执行多个查询并将结果相关联,而不必担心数字在您眼前发生变化。 + 另一个重要的观点是,当服务器进程被要求显示任何累积的统计信息时,在默认配置中,访问的值会被缓存直到当前事务结束。因此,只要你继续当前事务,统计信息将显示静态信息。类似地,当在事务中首次请求这类当前查询信息时,会收集关于所有会话当前查询的信息,并且相同的信息将在整个事务中显示。这是一个特性,而不是一个错误,因为它允许你在统计信息上执行多个查询并将结果相关联,而不必担心数字在你眼前发生变化。 - 在交互式分析统计信息或使用昂贵的查询时,访问各个统计信息之间的时间差可能导致缓存统计信息中出现显著的偏差。为了最小化偏差,可以将stats_fetch_consistency设置为snapshot,但这会增加用于缓存不需要的统计数据的内存使用量。相反,如果已知统计信息只被访问一次,那么缓存访问的统计信息是不必要的,可以通过将stats_fetch_consistency设置为none来避免。 + 在交互式分析统计信息或使用开销较大的查询时,访问各个统计信息之间的时间差可能导致缓存统计信息中出现显著的偏差。为了最小化偏差,可以将stats_fetch_consistency设置为snapshot,但这会增加用于缓存不需要的统计数据的内存使用量。相反,如果已知统计信息只被访问一次,那么缓存访问的统计信息是不必要的,可以通过将stats_fetch_consistency设置为none来避免。 - 您可以调用pg_stat_clear_snapshot()来丢弃当前事务的统计快照或缓存的值(如果有)。下一次使用统计信息时(在快照模式下),将会创建一个新的快照,或者(在缓存模式下)将访问的统计信息缓存起来。 + 你可以调用pg_stat_clear_snapshot()来丢弃当前事务的统计快照或缓存的值(如果有)。下一次使用统计信息时(在快照模式下),将会创建一个新的快照,或者(在缓存模式下)将访问的统计信息缓存起来。 @@ -176,11 +176,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 相反,它们在事务期间持续更新。 - - 动态统计视图中显示的一些信息在中受到安全限制。 - 普通用户只能查看关于他们自己会话的所有信息(属于他们是成员的角色的会话)。在关于其他会话的行中,许多列将为空。 - 但是,请注意,所有用户都可以看到会话的存在以及其一般属性,如会话用户和数据库。超级用户和具有内置角色pg_read_all_stats权限的角色(另请参阅)可以查看所有会话的所有信息。 - + 所列动态统计视图中的一些信息受到安全限制。普通用户只能查看其自身会话的全部信息(包括属于其所加入角色的会话)。对于其他会话的行,许多列将为空值。不过,会话的存在及其一般属性(例如会话用户和数据库)对所有用户都可见。超级用户和具有内置角色pg_read_all_stats权限的角色可以查看所有会话的全部信息。
@@ -215,7 +211,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser pg_stat_wal_receiverpg_stat_wal_receiver - 只有一行,显示有关 WAL 接收进程从其连接服务器接收到的统计信息。有关详细信息,请参阅pg_stat_wal_receiver。 + 只有一行,显示 WAL 接收进程从其所连接服务器接收数据的统计信息。有关详细信息,请参阅pg_stat_wal_receiver @@ -325,48 +321,63 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - + pg_stat_bgwriterpg_stat_bgwriter 只有一行,显示有关后台写入器活动的信息。有关详细信息,请参阅pg_stat_bgwriter - + pg_stat_checkpointerpg_stat_checkpointer 只有一行,显示有关检查点进程活动的信息。有关详细信息,请参阅pg_stat_checkpointer - + + pg_stat_databasepg_stat_database + 每个数据库一行,显示数据库范围的统计信息。有关详细信息,请参阅pg_stat_database。 + + + + + pg_stat_database_conflictspg_stat_database_conflicts + 每个数据库一行,显示数据库范围内因备库上的恢复冲突而导致查询被取消的统计信息。有关详细信息,请参阅pg_stat_database_conflicts + + + pg_stat_iopg_stat_io 对于每种后端类型、上下文和目标对象的组合各有一行,包含集簇范围的 I/O 统计信息。有关详细信息,请参阅pg_stat_io - + pg_stat_lockpg_stat_lock 每种锁类型一行,显示集簇范围的锁统计信息。有关详细信息,请参阅pg_stat_lock - - pg_stat_walpg_stat_wal - 只有一行,显示有关 WAL 活动的统计信息。有关详细信息,请参阅pg_stat_wal。 - + + pg_stat_replication_slotspg_stat_replication_slots + 每个复制槽一行,显示有关复制槽使用情况的统计信息。有关详细信息,请参阅pg_stat_replication_slots - - pg_stat_databasepg_stat_database - 每个数据库一行,显示数据库范围的统计信息。有关详细信息,请参阅pg_stat_database。 - + + pg_stat_slrupg_stat_slru + 每个 SLRU 一行,显示操作统计信息。有关详细信息,请参阅pg_stat_slru - - pg_stat_database_conflictspg_stat_database_conflicts - 每个数据库一行,显示数据库范围内因备库上的恢复冲突而导致查询被取消的统计信息。有关详细信息,请参阅pg_stat_database_conflicts + + pg_stat_subscription_statspg_stat_subscription_stats + 每个订阅一行,显示有关错误和冲突的统计信息。有关详细信息,请参阅pg_stat_subscription_stats - + + pg_stat_walpg_stat_wal + 只有一行,显示有关 WAL 活动的统计信息。有关详细信息,请参阅pg_stat_wal。 + + + + pg_stat_all_tablespg_stat_all_tables 当前数据库中每个表一行,显示有关访问指定表的统计信息。详见 @@ -374,121 +385,106 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - + pg_stat_sys_tablespg_stat_sys_tables pg_stat_all_tables一样,但只显示系统表。 - + pg_stat_user_tablespg_stat_user_tables pg_stat_all_tables一样,但只显示用户表。 - + pg_stat_xact_all_tablespg_stat_xact_all_tables - pg_stat_all_tables相似,但计数动作只在当前事务内发生(还没有被包括在pg_stat_all_tables和相关视图中)。用于生存和死亡行数量的列以及清理和分析动作在此视图中不出现。 + pg_stat_all_tables 相似,但只统计当前事务中截至目前执行的操作(这些操作尚计入 pg_stat_all_tables 及相关视图)。此视图不包含存活行和死行数量以及清理、分析操作的列。 - + pg_stat_xact_sys_tablespg_stat_xact_sys_tables pg_stat_xact_all_tables一样,但只显示系统表。 - + pg_stat_xact_user_tablespg_stat_xact_user_tables pg_stat_xact_all_tables一样,但只显示用户表。 - + pg_stat_autovacuum_scorespg_stat_autovacuum_scores 当前数据库中的每个表一行,显示该表当前的自动清理评分。有关详细信息,请参阅pg_stat_autovacuum_scores - + pg_stat_all_indexespg_stat_all_indexes 当前数据库中的每个索引一行,显示有关访问该特定索引的统计信息。有关详细信息,请参阅pg_stat_all_indexes - + pg_stat_sys_indexespg_stat_sys_indexes pg_stat_all_indexes一样,但只显示系统表上的索引。 - + pg_stat_user_indexespg_stat_user_indexes pg_stat_all_indexes一样,但只显示用户表上的索引。 - + + pg_stat_user_functionspg_stat_user_functions + 每个被跟踪的函数一行,显示有关该函数执行的统计信息。有关详细信息,请参阅pg_stat_user_functions + + + + pg_stat_xact_user_functionspg_stat_xact_user_functions + pg_stat_user_functions相似,但是只统计在当前事务期间的调用(还没有被包括在pg_stat_user_functions中)。 + + + pg_statio_all_tablespg_statio_all_tables 当前数据库中的每个表一行,显示有关访问该特定表的 I/O 统计信息。有关详细信息,请参阅pg_statio_all_tables - + pg_statio_sys_tablespg_statio_sys_tables pg_statio_all_tables一样,但只显示系统表。 - + pg_statio_user_tablespg_statio_user_tables pg_statio_all_tables一样,但只显示用户表。 - + pg_statio_all_indexespg_statio_all_indexes 当前数据库中的每个索引一行,显示有关访问该特定索引的 I/O 统计信息。有关详细信息,请参阅pg_statio_all_indexes - + pg_statio_sys_indexespg_statio_sys_indexes pg_statio_all_indexes一样,但只显示系统表上的索引。 - + pg_statio_user_indexespg_statio_user_indexes pg_statio_all_indexes一样,但只显示用户表上的索引。 - + pg_statio_all_sequencespg_statio_all_sequences 当前数据库中的每个序列一行,显示有关访问该特定序列的 I/O 统计信息。有关详细信息,请参阅pg_statio_all_sequences - + pg_statio_sys_sequencespg_statio_sys_sequences pg_statio_all_sequences一样,但只显示系统序列(目前没有定义系统序列,因此这个视图总是为空)。 - + pg_statio_user_sequencespg_statio_user_sequences pg_statio_all_sequences一样,但只显示用户序列。 - - pg_stat_user_functionspg_stat_user_functions - 每个被跟踪的函数一行,显示有关该函数执行的统计信息。有关详细信息,请参阅pg_stat_user_functions - - - - pg_stat_xact_user_functionspg_stat_xact_user_functions - pg_stat_user_functions相似,但是只统计在当前事务期间的调用(还没有被包括在pg_stat_user_functions中)。 - - - - pg_stat_slrupg_stat_slru - 每个 SLRU 一行,显示操作统计信息。有关详细信息,请参阅pg_stat_slru - - - - pg_stat_replication_slotspg_stat_replication_slots - 每个复制槽一行,显示有关复制槽使用情况的统计信息。有关详细信息,请参阅pg_stat_replication_slots - - - - pg_stat_subscription_statspg_stat_subscription_stats - 每个订阅一行,显示有关错误和冲突的统计信息。有关详细信息,请参阅pg_stat_subscription_stats - -
@@ -564,7 +560,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser leader_pid integer
- 如果该进程是并行查询工作进程,则为并行组领导者的进程 ID;如果该进程是并行应用工作进程,则为领导应用工作进程的进程 ID。NULL 表示该进程是并行组领导者或领导应用工作进程,或者不参与任何并行操作。 + 如果该进程是并行查询工作进程,则为并行组领导者的进程 ID;如果该进程是并行应用工作进程,则为领导者应用工作进程的进程 ID。NULL 表示该进程是并行组领导者或领导者应用工作进程,或者不参与任何并行操作。 @@ -600,7 +596,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser client_addr inet - 连接到这个后端的客户端的 IP 地址。如果这个字段为空,它表示客户端通过服务器机器上的一个 Unix 套接字连接或者这是一个内部进程,如自动清理。 + 连接到这个后端的客户端的 IP 地址。如果这个字段为空值,它表示客户端通过服务器机器上的一个 Unix 套接字连接或者这是一个内部进程,如自动清理。 @@ -619,7 +615,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser client_port integer - 客户端用于与此后端通信的TCP端口号,如果使用Unix套接字,则为-1。如果该字段为空,它表示这是一个内部服务器进程。 + 客户端用于与此后端通信的TCP端口号,如果使用Unix套接字,则为-1。如果该字段为空值,它表示这是一个内部服务器进程。 @@ -637,8 +633,8 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser xact_start timestamp with time zone - 这个进程的当前事务被启动的时间,如果没有活动事务则为空。 - 如果当前查询是它的第一个事务,这一列等于query_start列。 + 这个进程的当前事务被启动的时间,如果没有活动事务则为空值。 + 如果当前查询是其事务中的第一个查询,这一列等于query_start列。 @@ -665,7 +661,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser wait_event_type text - 后端正在等待的事件类型(如果有);否则为NULL。请参阅。 + 后端正在等待的事件类型(如果有);否则为空值。请参阅 @@ -674,7 +670,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser wait_event text - 如果此后端当前正在等待,则返回等待事件名称,否则为NULL。请参阅。 + 如果此后端当前正在等待,则返回等待事件名称,否则为空值。请参阅 @@ -682,44 +678,29 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser state text - - 这个后端的当前总体状态。可能的值为: - + 该后端当前的总体状态。可能的值为: - starting: 后端正处于初始启动阶段。客户端认证在此阶段执行。 + starting: 后端正处于初始启动阶段。客户端认证在此阶段执行。 - - active: 后端正在执行一个查询。 - + active:后端正在执行一个查询。 - - idle: 后端正在等待一个新的客户端命令。 - + idle:后端正在等待新的客户端命令。 - - idle in transaction: 后端在一个事务中,但是当前没有正在执行一个查询。 - + idle in transaction:后端处于事务中,但当前没有执行查询。 - - idle in transaction (aborted): 这个状态与 - idle in transaction相似,除了在该事务中的一个语句导致了一个错误。 - + idle in transaction (aborted):该状态与idle in transaction类似,但事务中的某个语句导致了错误。 - - fastpath function call: 后端正在执行一个 fast-path 函数。 - + fastpath function call:后端正在执行一个快速路径函数。 - - disabled: 如果在这个后端中被禁用,则报告这个状态。 - + disabled:如果在此后端中禁用了,就会报告此状态。 @@ -729,9 +710,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser backend_xid xid - - 这个后端的顶层事务 ID,如果存在。 - + 这个后端的顶层事务 ID(如果存在);请参阅 @@ -739,7 +718,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser backend_xmin xid - 当前后端的xmin范围。 + 当前后端的xmin视界。 @@ -751,7 +730,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 这个后端的最近查询的标识符。 如果stateactive,这个字段显示当前正在执行的查询的标识符。 在所有其他状态,它显示执行的最后一个查询的标识符。 - 默认不计算查询标识符,因此该字段将为空,除非启用参数或配置了计算查询标识符的第三方模块。 + 默认不计算查询标识符,因此该字段将为空值,除非启用参数或配置了计算查询标识符的第三方模块。 @@ -769,19 +748,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser backend_type text - - 当前后端的类型。可能的类型为 - autovacuum launcher, autovacuum worker, - logical replication launcher, - logical replication worker, - parallel worker, background writer, - client backend, checkpointer, - archiver, standalone backend, - startup, walreceiver, - walsender, walwriter 以及 - walsummarizer。 - 此外,由扩展注册的后台工作进程还可能有额外的类型。 - + 当前后端的类型。可能的类型为autovacuum launcherautovacuum workerlogical replication launcherlogical replication workerparallel workerbackground writerclient backendcheckpointerarchiverstandalone backendstartupwalreceiverwalsenderwalwriterwalsummarizer。此外,由扩展注册的后台工作进程还可能有额外的类型。 @@ -790,7 +757,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - wait_eventstate列彼此独立。如果某个后端处于active状态,它既可能正在等待某个事件,也可能没有等待。如果状态为activewait_event非空,就意味着某个查询正在执行,但在系统中的某处被阻塞了。为将报告开销保持在较低水平,系统不会尝试为某个后端同步活动数据的不同方面。因此,视图各列之间可能暂时存在不一致。 + wait_eventstate列彼此独立。如果某个后端处于active状态,它可能正在等待(waiting)某个事件,也可能没有等待。如果状态为activewait_event非空,就意味着某个查询正在执行,但在系统中的某处被阻塞了。为将报告开销保持在较低水平,系统不会尝试为某个后端同步活动数据的不同方面。因此,视图各列之间可能暂时存在不一致。 @@ -842,7 +809,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser IO - 服务器进程正在等待一个I/O操作完成。wait_event将识别特定的等待点;参见。 + 服务器进程正在等待一个 I/O 操作完成。wait_event将识别特定的等待点;参见 @@ -854,17 +821,14 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser Lock - 服务器进程正在等待一个重量级锁。重量级锁,也称为锁管理器锁或简单锁,主要保护表等SQL可见对象。 + 服务器进程正在等待一个重量级锁。重量级锁,也称为锁管理器锁或简称为锁,主要保护表等SQL可见对象。 然而,它们也用于确保某些内部操作的互斥,例如关系扩展。wait_event将识别等待的锁的类型;参见 LWLock - 服务器进程正在等待一个轻量级锁。大多数这样的锁保护共享内存中的特定数据结构。 - wait_event将包含标识轻量级锁用途的名称。 - (有些锁有特定的名称;其他锁是一组锁的一部分,每个锁具有类似的目的。)参见。 - + 服务器进程正在等待一个轻量级锁。大多数这样的锁保护共享内存中的某个特定数据结构。wait_event将包含标识该轻量级锁用途的名称。(有些锁具有专门的名称,另一些锁属于一组用途相似的锁。)参见 @@ -896,17 +860,17 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - AutoVacuumMain - 在自动清理启动过程的主循环中等待。 + AutovacuumMain + 在自动清理启动进程的主循环中等待。 - BgWriterHibernate - 在后台写入器中等待,休眠状态。 + BgwriterHibernate + 在后台写入器进程中休眠等待。 - BgWriterMain + BgwriterMain 在后台写入器主循环中等待。 @@ -915,6 +879,16 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 在检查点进程的主循环中等待。 + + CheckpointerShutdown + 等待检查点进程终止。 + + + + IoWorkerMain + 在 I/O 工作进程的主循环中等待。 + + LogicalApplyMain 在逻辑复制应用进程的主循环中等待。 @@ -926,22 +900,33 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - RecoveryWalStream - 流恢复期间,在启动进程主循环等待WAL到达。 + LogicalParallelApplyMain + 在逻辑复制并行应用进程的主循环中等待。 - SysLoggerMain - 在 syslogger 进程的主循环中等待。 + RecoveryWalStream + 在流恢复期间,在启动进程的主循环中等待 WAL 到达。 ReplicationSlotsyncMain 在复制槽同步的主循环中等待。 - + + + ReplicationSlotsyncShutdown + 等待复制槽同步工作进程关闭。 + + + + SysloggerMain + 在 syslogger 进程的主循环中等待。 + + + WalReceiverMain - 在WAL 接收进程的主循环中等待。 + 在 WAL 接收进程的主循环中等待。 @@ -949,9 +934,14 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 在 WAL 发送进程的主循环中等待。 + + WalSummarizerWal + 在 WAL 汇总进程中等待生成更多 WAL。 + + WalWriterMain - 在WAL写入进程的主循环中等待。 + 在 WAL 写入进程的主循环中等待。 @@ -974,17 +964,20 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser BufferCleanup - 等待获取缓冲区上的排他 pin。如果另一个进程持有一个尚未关闭的游标,且该游标最近一次读取的数据来自这个缓冲区,缓冲区 pin 等待可能会持续较长时间。 + 等待获得缓冲区上的独占钉住。如果另一个进程持有尚未关闭的游标,且该游标最近一次读取的数据来自该缓冲区,缓冲区钉住等待可能会持续较长时间。 - + + BufferExclusive 等待获取缓冲区上的排他锁。 - + + BufferShared 等待获取缓冲区上的共享锁。 - + + BufferShareExclusive 等待获取缓冲区上的共享排他锁。 @@ -1017,28 +1010,33 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - GSSOpenServer + GssOpenServer 在建立GSSAPI会话时等待从客户端读取数据。 - LibPQWalReceiverConnect - 在WAL 接收进程等待与远程服务器建立连接。 + LibpqwalreceiverConnect + 在 WAL 接收进程中等待与远程服务器建立连接。 - LibPQWalReceiverReceive - 在WAL 接收进程中等待从远程服务器接收数据。 + LibpqwalreceiverReceive + 在 WAL 接收进程中等待从远程服务器接收数据。 - SSLOpenServer + SslOpenServer 在尝试连接时等待SSL。 - WalSenderWaitForWAL - 在 WAL 发送进程中等待 WAL 被刷新。 + WaitForStandbyConfirmation + 等待物理备库接收 WAL 并将其刷盘。 + + + + WalSenderWaitForWal + 在 WAL 发送进程中等待 WAL 刷盘。 @@ -1086,33 +1084,48 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - BaseBackupRead + AioIoCompletion + 等待另一个进程完成 I/O。 + + + + AioIoUringExecution + 等待通过 io_uring 执行 I/O。 + + + + AioIoUringSubmit + 等待通过 io_uring 提交 I/O。 + + + + BasebackupRead 等待基础备份从文件中读取。 - BaseBackupSync - 等待由基础备份写入的数据达到持久存储。 + BasebackupSync + 等待基础备份写入的数据同步到持久存储。 - BaseBackupWrite + BasebackupWrite 等待基础备份写入文件。 - BufFileRead + BuffileRead 等待从缓冲文件中读取。 - BufFileWrite - 等待对缓冲文件的写入。 + BuffileTruncate + 等待一个缓冲文件被截断。 - BufFileTruncate - 等待一个缓冲文件被截断。 + BuffileWrite + 等待对缓冲文件的写入。 @@ -1122,12 +1135,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser ControlFileSync - 等待pg_control文件到达持久存储。 + 等待 pg_control 文件同步到持久存储。 ControlFileSyncUpdate - 等待更新pg_control文件以达到持久存储。 + 等待对 pg_control 文件的更新同步到持久存储。 @@ -1137,45 +1150,47 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser ControlFileWriteUpdate - 等待写入更新pg_control文件。 + 等待写入以更新 pg_control 文件。 - CopyFileRead - 在文件复制操作期间等待读取。 + CopyFileCopy + 等待文件复制操作。 - CopyFileWrite - 在文件拷贝操作期间等待写入。 + CopyFileRead + 在文件复制操作期间等待读取。 - DSMFillZeroWrite - 等待用零填充动态共享内存备份(backing)文件。 + CopyFileWrite + 在文件复制操作期间等待写入。 CopyFromRead 在 COPY FROM 期间等待从管道、文件或程序读取数据。 - + + CopyToWrite 在 COPY TO 期间等待向管道、文件或程序写入数据。 - + + DataFileExtend 等待关系数据文件被扩展。 DataFileFlush - 等待关系数据文件达到持久存储。 + 等待关系数据文件同步到持久存储。 DataFileImmediateSync - 等待关系数据文件到持久存储的立即同步。 + 等待关系数据文件立即同步到持久存储。 @@ -1190,7 +1205,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser DataFileSync - 等待对关系数据文件的更改达到持久存储。 + 等待对关系数据文件的更改同步到持久存储。 @@ -1204,17 +1219,27 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - LockFileAddToDataDirRead + DsmAllocate + 等待分配动态共享内存段。 + + + + DsmFillZeroWrite + 等待用零填充动态共享内存的后备文件。 + + + + LockFileAddtodatadirRead 在向数据目录锁文件中添加一行时等待读取。 - LockFileAddToDataDirSync - 等待数据到达持久存储,同时向数据目录锁文件添加一行。 + LockFileAddtodatadirSync + 在向数据目录锁文件中添加一行时,等待数据同步到持久存储。 - LockFileAddToDataDirWrite + LockFileAddtodatadirWrite 在向数据目录锁文件中添加一行时等待写操作。 @@ -1225,7 +1250,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser LockFileCreateSync - 在创建数据目录锁文件时等待数据到达持久存储。 + 在创建数据目录锁文件时,等待数据同步到持久存储。 @@ -1234,18 +1259,18 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - LockFileReCheckDataDirRead + LockFileRecheckdatadirRead 在重新检查数据目录锁文件期间等待读取。 LogicalRewriteCheckpointSync - 等待逻辑重写映射到在检查点到达持久存储。 + 在检查点期间等待逻辑重写映射同步到持久存储。 LogicalRewriteMappingSync - 在逻辑重写期间等待映射数据到达持久存储 + 在逻辑重写期间等待映射数据同步到持久存储。 @@ -1255,12 +1280,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser LogicalRewriteSync - 等待逻辑重写映射到达持久存储。 + 等待逻辑重写映射同步到持久存储。 LogicalRewriteTruncate - 等待在逻辑重写期间截断映射数据。 + 在逻辑重写期间等待截断映射数据。 @@ -1274,8 +1299,8 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - RelationMapSync - 等待关系映射文件到达持久存储。 + RelationMapReplace + 等待关系映射文件的替换结果同步到持久存储。 @@ -1285,17 +1310,17 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser ReorderBufferRead - 在重新排序缓冲区管理期间等待读取。 + 在重排序缓冲区管理期间等待读取。 ReorderBufferWrite - 在重新排序缓冲区管理期间等待写操作。 + 在重排序缓冲区管理期间等待写入。 ReorderLogicalMappingRead - 在重新排序缓冲区管理期间等待读取逻辑映射。 + 在重排序缓冲区管理期间等待读取逻辑映射。 @@ -1305,12 +1330,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser ReplicationSlotRestoreSync - 等待复制槽控制文件到达持久存储,同时将其恢复到内存中。 + 在将复制槽控制文件恢复到内存期间,等待该文件同步到持久存储。 ReplicationSlotSync - 等待复制槽控制文件到达持久存储。 + 等待复制槽控制文件同步到持久存储。 @@ -1319,43 +1344,43 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - SLRUFlushSync - 在检查点或数据库关闭期间等待SLRU数据到达持久存储。 + SlruFlushSync + 在检查点或数据库关闭期间,等待 SLRU 数据同步到持久存储。 - SLRURead + SlruRead 等待读取SLRU页面。 - SLRUSync - 在写页面后等待SLRU数据到达持久存储。 + SlruSync + 在页面写入后等待 SLRU 数据同步到持久存储。 - SLRUWrite + SlruWrite 等待SLRU页面的写入。 SnapbuildRead - 等待读取序列化的历史目录快照。 + 等待读取序列化的历史系统目录快照。 SnapbuildSync - 等待序列化历史目录快照到达持久存储。 + 等待序列化的历史系统目录快照同步到持久存储。 SnapbuildWrite - 等待串行历史目录快照的写入。 + 等待写入序列化的历史系统目录快照。 TimelineHistoryFileSync - 等待通过流复制接收的时间线历史文件到达持久存储。 + 等待通过流复制接收的时间线历史文件同步到持久存储。 @@ -1370,7 +1395,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser TimelineHistorySync - 等待新创建的时间线历史文件到达持久存储。 + 等待新创建的时间线历史文件同步到持久存储。 @@ -1385,7 +1410,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser TwophaseFileSync - 等待两阶段状态文件到达持久存储。 + 等待两阶段状态文件同步到持久存储。 @@ -1395,7 +1420,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser VersionFileSync - 等待版本文件达到持久存储,同时创建数据库。 + 在创建数据库时,等待版本文件同步到持久存储。 @@ -1404,63 +1429,73 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - WALBootstrapSync - 在引导过程中等待WAL达到持久存储。 + WalsenderTimelineHistoryRead + 在 WAL 发送进程执行时间线命令期间,等待从时间线历史文件读取。 + + + + WalBootstrapSync + 在引导过程中等待 WAL 同步到持久存储。 - WALBootstrapWrite + WalBootstrapWrite 在引导过程中等待WAL页面的写入。 - WALCopyRead + WalCopyRead 通过复制一个已有WAL段来创建一个新的WAL段时等待读取。 - WALCopySync - 等待通过复制一个已有WAL段到持久存储来创建一个新的WAL段。 + WalCopySync + 等待通过复制现有 WAL 段创建的新 WAL 段同步到持久存储。 - WALCopyWrite + WalCopyWrite 通过复制一个已有WAL段来创建一个新的WAL段时等待写入。 - WALInitSync - 等待一个新初始化的WAL文件到持久存储。 + WalInitSync + 等待新初始化的 WAL 文件同步到持久存储。 - WALInitWrite + WalInitWrite 在初始化一个新的WAL文件时等待写入。 - WALRead + WalRead 等待WAL文件的读取。 - WALSenderTimelineHistoryRead - 在walsender时间线命令期间等待从时间线历史文件读取。 + WalSummaryRead + 等待从 WAL 汇总文件读取。 - WALSync - 等待WAL文件到达持久存储。 + WalSummaryWrite + 等待写入 WAL 汇总文件。 - WALSyncMethodAssign - 等待数据到达持久存储,同时分配一个新的WAL同步方法。 + WalSync + 等待 WAL 文件同步到持久存储。 - WALWrite - 等待写入WAL文件。 + WalSyncMethodAssign + 在设置新的 WAL 同步方法时,等待数据同步到持久存储。 + + + + WalWrite + 等待写入 WAL 文件。 @@ -1506,23 +1541,33 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - BgWorkerShutdown + BgworkerShutdown 等待后台工作进程关闭。 - BgWorkerStartup + BgworkerStartup 等待后台工作进程启动。 BtreePage - 正等待继续并行B-树扫描所需的页号变得可用。 + 等待继续并行 B-树扫描所需的页号变得可用。 + + + + BufferIo + 等待缓冲区 I/O 完成。 + + + + CheckpointDelayComplete + 等待阻碍检查点完成的后端。 - BufferIO - 等待缓冲I/O结束。 + CheckpointDelayStart + 等待阻碍检查点开始的后端。 @@ -1539,88 +1584,100 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser ChecksumEnableStartcondition 等待开始启用数据校验和。 - + + ChecksumEnableTemptableWait 等待临时表被删除,以便启用数据校验和。 - + + ExecuteGather - 在执行Gather 计划节点时,等待子进程的活动。 + 在执行 Gather 计划节点时,等待子进程的活动。 HashBatchAllocate - 等待一个选定的并行哈希参与者分配哈希表。 + 等待选出的 Parallel Hash 参与者分配哈希表。 HashBatchElect - 等待选择一个并行哈希参与者来分配哈希表。 + 等待选出负责分配哈希表的 Parallel Hash 参与者。 HashBatchLoad - 等待其他并行哈希参与者完成哈希表的加载。 + 等待其他 Parallel Hash 参与者完成哈希表的加载。 HashBuildAllocate - 等待一个选定的并行哈希参与者分配初始哈希表。 + 等待选出的 Parallel Hash 参与者分配初始哈希表。 HashBuildElect - 等待选择一个并行哈希参与者来分配初始哈希表。 + 等待选出负责分配初始哈希表的 Parallel Hash 参与者。 HashBuildHashInner - 等待其他并行哈希参与者完成内部关系的散列。 + 等待其他 Parallel Hash 参与者完成对内层关系的哈希处理。 HashBuildHashOuter - 等待其他Parallel 哈希参与者完成对外部关系的分区。 - - - - HashGrowBatchesAllocate - 等待选定的并行哈希参与者分配更多批处理。 + 等待其他 Parallel Hash 参与者完成对外层关系的分区。 HashGrowBatchesDecide - 等待选择一个并行哈希参与者来决定未来的批处理增长。 + 等待选出负责决定后续批次增长的 Parallel Hash 参与者。 HashGrowBatchesElect - 等待选择一个Parallel 哈希参与者来分配更多批处理。 + 等待选出负责分配更多批次的 Parallel Hash 参与者。 HashGrowBatchesFinish - 等待当选的平行散列参与者决定未来的批量增长。 + 等待选出的 Parallel Hash 参与者决定后续的批次增长。 - HashGrowBatchesRepartition - 等待一个选定的并行哈希参与者决定未来的批处理增长。 + HashGrowBatchesReallocate + 等待选出的 Parallel Hash 参与者分配更多批次。 - HashGrowBucketsAllocate - 等待选定的并行哈希参与者完成更多bucket的分配。 + HashGrowBatchesRepartition + 等待其他 Parallel Hash 参与者完成重新分区。 HashGrowBucketsElect - 等待选择一个并行哈希参与者来分配更多的buckets。 + 等待选出负责分配更多桶的 Parallel Hash 参与者。 + + + + HashGrowBucketsReallocate + 等待选出的 Parallel Hash 参与者完成更多桶的分配。 HashGrowBucketsReinsert - 等待其他Parallel 哈希参与者完成将元组插入到新buckets中。 + 等待其他 Parallel Hash 参与者完成向新桶插入元组。 + + + + LogicalApplySendData + 等待逻辑复制领导者应用进程向并行应用进程发送数据。 + + + + LogicalParallelApplyStateChange + 等待逻辑复制并行应用进程改变状态。 @@ -1653,24 +1710,29 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 等待将字节发送到共享消息队列。 + + MultixactCreation + 等待多事务创建完成。 + + ParallelBitmapScan - 等待并行位图扫描被初始化。 + 等待并行位图扫描完成初始化。 ParallelCreateIndexScan - 等待并行CREATE INDEX 工作进程完成堆扫描。 + 等待并行 CREATE INDEX 工作进程完成堆扫描。 ParallelFinish - 等待并行工作人员完成计算。 + 等待并行工作进程完成计算。 - ProcArrayGroupUpdate - 等待组领导在并行操作结束时清除事务ID。 + ProcarrayGroupUpdate + 等待组领导者在事务结束时清除事务 ID。 @@ -1685,12 +1747,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser RecoveryConflictSnapshot - 等待vacuum清理的恢复冲突解决。 + 等待解决清理操作引发的恢复冲突。 RecoveryConflictTablespace - 等待恢复冲突解决删除表空间。 + 等待解决删除表空间引发的恢复冲突。 @@ -1707,7 +1769,8 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser RepackWorkerExport 等待解码工作进程导出新的输出文件。 - + + ReplicationOriginDrop 等待复制源变为非活动状态,以便可以删除它。 @@ -1729,34 +1792,47 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser SyncRep - 在同步复制期间等待远程服务器的确认。 + 在同步复制期间等待来自远程服务器的确认。 WaitForWalFlush - 等待主服务器或备用服务器上的 WAL 刷盘达到目标 LSN。 + 等待主库或备库上的 WAL 刷盘达到目标 LSN。 - + + WaitForWalReplay - 等待备用服务器上的 WAL 重放达到目标 LSN。 + 等待备库上的 WAL 重放达到目标 LSN。 - + + WaitForWalWrite - 等待备用服务器上的 WAL 写入达到目标 LSN。 + 等待备库上的 WAL 写入达到目标 LSN。 - + + WalReceiverExit 等待WAL 接收进程退出。 + + WalReceiverUpstreamCatchup + 等待上游服务器的 WAL 刷盘位置追上请求的起始点。 + + WalReceiverWaitStart 等待启动进程为流复制发送初始数据。 + + WalSummaryReady + 等待生成新的 WAL 汇总。 + + XactGroupUpdate - 等待分组组长在并行操作结束时更新事务状态。 + 等待组领导者在事务结束时更新事务状态。 @@ -1778,7 +1854,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser advisory - 等待获得一个建议用户锁。 + 等待获取用户咨询锁。 + + + + applytransaction + 等待获取逻辑复制订阅者正在应用的远程事务上的锁。 @@ -1788,8 +1869,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser frozenid - 等待升级 pg_database.datfrozenxid - 和 pg_database.datminmxid. + 等待更新 pg_database.datfrozenxidpg_database.datminmxid @@ -1804,12 +1884,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser relation - 等待获得一个关系的锁。 + 等待获取关系上的锁。 spectoken - 等待获取推测的插入锁。 + 等待获取推测插入锁。 @@ -1829,7 +1909,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser virtualxid - 等待获取虚拟事务ID锁。 + 等待获取虚拟事务 ID 锁;参见 @@ -1851,14 +1931,25 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser AddinShmemInit - 等待管理共享内存中的扩展空间分配。 + 等待管理扩展在共享内存中的空间分配。 + + + + AioUringCompletion + 等待另一个进程通过 io_uring 完成 I/O。 AioWorkerControl 等待更新 AIO 工作进程信息。 - + + + AioWorkerSubmissionQueue + 等待访问 AIO 工作进程的提交队列。 + + + AutoFile 等待更新postgresql.auto.conf文件。 @@ -1870,7 +1961,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser AutovacuumSchedule - 等待确保选择为自动清理的表仍然需要清理。 + 等待确认选中进行自动清理的表是否仍需清理。 @@ -1883,8 +1974,6 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 等待读取或更新B-树索引的清理相关信息。 - - BufferMapping 等待将数据块与缓冲池中的缓冲区关联。 @@ -1897,7 +1986,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser CommitTs - 等待读取或更新事务提交时间戳的最后一个值集。 + 等待读取或更新最近设置的事务提交时间戳值。 @@ -1919,58 +2008,90 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser DataChecksumsWorker 等待数据校验和工作进程。 - - DynamicSharedMemoryControl - 等待读取或更新动态共享内存分配信息。 - - LockFastPath - 等待读取或更新进程的快速路径锁信息。 + DSMRegistry + 等待读取或更新动态共享内存注册表。 - LockManager - 等待读取或更新关于heavyweight锁。 + DSMRegistryDSA + 等待访问动态共享内存注册表的动态共享内存分配器。 - LogicalDecodingControl - 等待读取或更新逻辑解码状态信息。 - - - LogicalRepWorker - 等待读取或更新逻辑复制工作器的状态。 + DSMRegistryHash + 等待访问动态共享内存注册表的共享哈希表。 - MultiXactGen - 等待读取或更新共享的multixact状态。 + DynamicSharedMemoryControl + 等待读取或更新动态共享内存分配信息。 + + + + InjectionPoint + 等待读取或更新注入点相关信息。 + + + + LockFastPath + 等待读取或更新进程的快速路径锁信息。 + + + + LockManager + 等待读取或更新有关重量级锁的信息。 + + + + LogicalDecodingControl + 等待读取或更新逻辑解码状态信息。 + + + + LogicalRepLauncherDSA + 等待访问逻辑复制启动进程的动态共享内存分配器。 + + + + LogicalRepLauncherHash + 等待访问逻辑复制启动进程的共享哈希表。 + + + + LogicalRepWorker + 等待读取或更新逻辑复制工作进程的状态。 + + + + MultiXactGen + 等待读取或更新共享的多事务状态。 MultiXactMemberBuffer - 在multixact成员SLRU缓冲区上等待I/O。 + 等待多事务成员 SLRU 缓冲区上的 I/O。 MultiXactMemberSLRU - 等待访问multixact成员SLRU缓存。 + 等待访问多事务成员 SLRU 缓存。 MultiXactOffsetBuffer - 在multixact 偏移 SLRU缓冲区上等待I/O。 + 等待多事务偏移量 SLRU 缓冲区上的 I/O。 MultiXactOffsetSLRU - 等待访问multixact 偏移 SLRU缓存。 + 等待访问多事务偏移量 SLRU 缓存。 MultiXactTruncation - 等待读取或截断multixact信息。 + 等待读取或截断多事务信息。 @@ -1982,14 +2103,15 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser NotifyChannelHash 等待访问 NOTIFY 通道哈希表。 - + + NotifyQueue 等待读取或更新NOTIFY 消息。 NotifyQueueTail - 等待NOTIFY消息存储上的更新限制。 + 等待更新 NOTIFY 消息存储的限制。 @@ -2003,18 +2125,18 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - OldSnapshotTimeMap - 等待读取或更新旧的快照控制信息。 + ParallelAppend + 在 Parallel Append 计划执行期间等待选择下一个子计划。 - ParallelAppend - 在并行附加计划执行期间等待选择下一个子计划。 + ParallelBtreeScan + 在并行 B-树扫描计划执行期间等待同步工作进程。 ParallelHashJoin - 在并行哈希连接计划执行期间等待同步工作器。 + 在 Parallel Hash Join 计划执行期间等待同步工作进程。 @@ -2022,6 +2144,11 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 等待并行查询动态共享内存分配。 + + ParallelVacuumDSA + 等待为并行清理分配动态共享内存。 + + PerSessionDSA 等待并行查询动态共享内存分配。 @@ -2029,12 +2156,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser PerSessionRecordType - 等待访问有关复合类型的并行查询信息。 + 等待访问并行查询中有关复合类型的信息。 PerSessionRecordTypmod - 等待访问有关标识匿名记录类型的类型修饰符的并行查询信息。 + 等待访问并行查询中用于标识匿名记录类型的类型修饰符信息。 @@ -2042,6 +2169,21 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 在并行查询期间等待访问当前可串行化事务持有的谓词锁列表。 + + PgStatsData + 等待访问共享内存中的统计数据。 + + + + PgStatsDSA + 等待访问统计信息的动态共享内存分配器。 + + + + PgStatsHash + 等待访问统计信息的共享内存哈希表。 + + PredicateLockManager 等待访问可串行化事务使用的谓词锁信息。 @@ -2049,7 +2191,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser ProcArray - 等待访问每个进程共享的数据结构(通常情况,是获取快照或报告会话的事务ID)。 + 等待访问各进程的共享数据结构(通常是为了获取快照或报告会话的事务 ID)。 @@ -2092,6 +2234,11 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 在可串行化事务冲突的SLRU缓冲区上等待I/O。 + + SerialControl + 等待读取或更新共享的 pg_serial 状态。 + + SerializableFinishedList 等待访问已完成的可串行化事务列表。 @@ -2102,21 +2249,6 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 等待访问可串行化事务持有的谓词锁列表。 - - PgStatsDSA - 等待统计动态共享内存分配器访问 - - - - PgStatsHash - 等待统计共享内存哈希表访问 - - - - PgStatsData - 等待共享内存统计数据访问 - - SerializableXactHash 等待读取或更新关于可串行化事务的信息。 @@ -2144,12 +2276,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser SInvalRead - 等待从共享目录失效队列中检索消息。 + 等待从共享系统目录失效队列中取出消息。 SInvalWrite - 等待向共享编目失效队列添加消息。 + 等待向共享系统目录失效队列添加消息。 @@ -2179,14 +2311,20 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser TwoPhaseState - 等待读取或更新已准备事务的状态。 + 等待读取或更新预备事务的状态。 + + + + WaitEventCustom + 等待读取或更新自定义等待事件信息。 WaitLSN 等待读取或更新共享的 LSN 等待状态。 - + + WALBufMapping 等待在WAL缓冲区中替换一个页面。 @@ -2196,6 +2334,11 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 等待将WAL数据插入内存缓冲区。 + + WALSummarizer + 等待读取或更新 WAL 汇总状态。 + + WALWrite 等待WAL缓冲区写入磁盘。 @@ -2203,7 +2346,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser WrapLimitsVacuum - 等待更新事务 ID和multixact消费的限制。 + 等待更新事务 ID 和多事务消耗量的限制。 @@ -2229,13 +2372,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - - - 扩展可以将ExtensionInjectionPointLWLock 事件添加到所示的列表中。 - 在某些情况下,扩展分配的 LWLock 名称无法在所有服务器进程中使用;因此,LWLock 等待事件可能只会被报告为extension,而不是扩展分配的名称。 - - @@ -2253,19 +2390,20 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser BaseBackupThrottle - 当有限流活动时在基础备份期间等待。 + 在基础备份期间因限流而等待。 CheckpointWriteDelay - 在执行检查点时写入之间的等待时间。 + 在执行检查点时,在各次写入之间等待。 CommitDelay 等待 WAL 刷盘前的提交延迟。 - + + PgSleep 由于调用pg_sleep或同类函数而等待。 @@ -2282,24 +2420,34 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser RegisterSyncRequest - 在发送同步请求到检查点程序时等待,因为请求队列已满。 + 向检查点进程发送同步请求时,因请求队列已满而等待。 + + + + SpinDelay + 在获取有竞争的自旋锁时等待。 VacuumDelay - 在一个基于代价的清理延迟点。 + 在基于代价的清理延迟点等待。 VacuumTruncate 等待获取独占锁以截断被清理的表末尾的空页面。 + + + WalSummarizerError + 在 WAL 汇总进程出错后等待。 +
- 这里是一个查看等待事件的示例: + 以下示例展示如何查看等待事件: SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event IS NOT NULL; @@ -2323,6 +2471,14 @@ description | Waiting for a newly initialized WAL file to reach durable storage + + + + 扩展可以将ExtensionInjectionPointLWLock 事件添加到所示的列表中。 + 在某些情况下,扩展分配的 LWLock 名称无法在所有服务器进程中使用;它可能只会被报告为extension,而不是扩展分配的名称。 + + + @@ -2397,7 +2553,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage 连接到这个 WAL 发送进程的客户端的 IP 地址。 - 如果这个域为空,它表示该客户端通过服务器机器上的一个Unix 套接字连接。 + 如果这个字段为空值,它表示该客户端通过服务器机器上的一个Unix 套接字连接。
@@ -2437,7 +2593,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage 由报告的该备库的xmin视界。 如果使用了复制槽(此时备库的 xmin 显示在 pg_replication_slots 中),或禁用了 - hot_standby_feedback ,则此字段为 空。 + hot_standby_feedback,则此字段为空值。
@@ -2451,27 +2607,27 @@ description | Waiting for a newly initialized WAL file to reach durable storage - startup: 此 WAL 发送进程正在启动。 + startup: 此 WAL 发送进程正在启动。 - catchup: 与此 WAL 发送进程连接的备库正在赶上主库。 + catchup: 与此 WAL 发送进程连接的备库正在赶上主库。 - streaming: 在其连接的备库赶上主库之后,此 WAL 发送进程正在流式传输更改。 + streaming: 在其连接的备库赶上主库之后,此 WAL 发送进程正在流式传输更改。 - backup: 此 WAL 发送进程正在发送一个备份。 + backup: 此 WAL 发送进程正在发送一个备份。 - stopping: 此 WAL 发送进程正在停止。 + stopping: 此 WAL 发送进程正在停止。 @@ -2518,30 +2674,21 @@ description | Waiting for a newly initialized WAL file to reach durable storage write_lag interval - - 从本地刷写最近的 WAL,到收到该备库已写入该 WAL(但尚未刷盘或应用)的通知之间经过的时间。 - 如果该服务器被配置为同步备库,可用此值衡量在提交时 synchronous_commit 级别 remote_write 所导致的延迟。 - + 从在本地将最近的 WAL 刷盘,到收到该备库已写入该 WAL(但尚未刷盘或应用)的通知之间经过的时间。如果该服务器被配置为同步备库,可用此值衡量在提交时synchronous_commit级别remote_write所导致的延迟。
flush_lag interval - - 从本地刷写最近的 WAL,到收到该备库已写入并刷写该 WAL(但尚未应用)的通知之间经过的时间。 - 如果该服务器被配置为同步备库,可用此值衡量在提交时 synchronous_commit 级别 on 所导致的延迟。 - + 从在本地将最近的 WAL 刷盘,到收到该备库已写入该 WAL 并将其刷盘(但尚未应用)的通知之间经过的时间。如果该服务器被配置为同步备库,可用此值衡量在提交时synchronous_commit级别on所导致的延迟。 replay_lag interval - - 从本地刷写最近的 WAL,到收到该备库已写入、刷写并应用该 WAL 的通知之间经过的时间。 - 如果该服务器被配置为同步备库,可用此值衡量在提交时 synchronous_commit 级别 remote_apply 所导致的延迟。 - + 从在本地将最近的 WAL 刷盘,到收到该备库已写入该 WAL、将其刷盘并应用的通知之间经过的时间。如果该服务器被配置为同步备库,可用此值衡量在提交时synchronous_commit级别remote_apply所导致的延迟。 @@ -2563,22 +2710,22 @@ description | Waiting for a newly initialized WAL file to reach durable storage - async: 该备库是异步的。 + async: 该备库是异步的。 - potential: 该备库当前是异步的,但在当前同步备库失效时可能变为同步的。 + potential: 该备库当前是异步的,但在当前某个同步备库失效时可能变为同步的。 - sync: 该备库是同步的。 + sync: 该备库是同步的。 - quorum: 该备库被作为法定人数同步复制候选备库。 + quorum: 该备库被作为法定人数同步复制候选备库。 @@ -2587,7 +2734,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - reply_time 带时区的时间戳 + reply_time timestamp with time zone 从备库收到的最后一条回复消息的发送时间 @@ -2598,17 +2745,17 @@ description | Waiting for a newly initialized WAL file to reach durable storage - pg_stat_replication视图中报告的滞后时间,是最近的 WAL 被写入、刷写和重放,以及发送端获知这些操作完成所花费时间的度量。如果远程服务器被配置为同步备库,这些时间表示各个同步提交级别带来或可能带来的提交延迟。对于异步备库,replay_lag列是最近事务对查询变得可见所需延迟时间的近似值。如果备库已经完全追上发送服务器且没有新的 WAL 活动,系统会在短时间内继续显示最近测得的滞后时间,随后显示为 NULL。 + pg_stat_replication视图中报告的滞后时间,是最近的 WAL 被写入、刷盘和重放,以及发送端获知这些操作完成所花费时间的度量。如果远程服务器被配置为同步备库,这些时间表示各个同步提交级别带来或可能带来的提交延迟。对于异步备库,replay_lag列是最近事务对查询变得可见所需延迟时间的近似值。如果备库已经完全追上发送服务器且没有新的 WAL 活动,系统会在短时间内继续显示最近测得的滞后时间,随后显示为 空值。 - 对于物理复制,滞后时间会自动测量。逻辑解码插件可以选择发出跟踪消息;如果没有这样做,跟踪机制会将滞后显示为 NULL。 + 对于物理复制,滞后时间会自动测量。逻辑解码插件可以选择发出跟踪消息;如果没有这样做,跟踪机制会将滞后显示为 空值。 - 报告出的滞后时间并不是根据当前重放速率预测该备库还需多久才能追上发送服务器。在持续生成新 WAL 时,那样的系统可能会显示相近的时间;但当发送端空闲时,就会显示不同的值。特别是当备库已经完全追上时,pg_stat_replication显示的是写入、刷写和重放最近报告的 WAL 位置所花费的时间,而不是某些用户可能预期的零。这样做符合为最近写事务测量同步提交和事务可见性延迟的目的。为减少用户因预期另一种滞后模型而产生的混淆,在一个已完全重放且处于空闲状态的系统上,lag 列会在较短时间后恢复为 NULL。监控系统应自行决定将这种情况表示为缺失数据、零,还是继续显示最近一次已知值。 + 报告出的滞后时间并不是根据当前重放速率预测该备库还需多久才能追上发送服务器。在持续生成新 WAL 时,那样的系统可能会显示相近的时间;但当发送端空闲时,就会显示不同的值。特别是当备库已经完全追上时,pg_stat_replication显示的是写入、刷盘和重放最近报告的 WAL 位置所花费的时间,而不是某些用户可能预期的零。这样做符合为最近写事务测量同步提交和事务可见性延迟的目的。为减少用户因预期另一种滞后模型而产生的混淆,在一个已完全重放且处于空闲状态的系统上,滞后列会在较短时间后恢复为 空值。监控系统应自行决定将这种情况表示为缺失数据、零,还是继续显示最近一次已知值。 @@ -2647,19 +2794,14 @@ description | Waiting for a newly initialized WAL file to reach durable storage slot_name text - - 唯一的,复制槽的集簇范围标识符 - + 复制槽在整个集簇范围内的唯一标识符 spill_txns bigint - - 当逻辑解码在解码来自WAL的更改时所使用的内存超过logical_decoding_work_mem,溢出到磁盘的事务数。 - 顶级事务和子事务的计数器都是递增的。 - + 当逻辑解码从 WAL 解码更改时所使用的内存超过logical_decoding_work_mem后,溢出到磁盘的事务数。顶层事务和子事务都会使此计数器递增。 @@ -2667,7 +2809,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage spill_count bigint - 在为该槽位解码来自WAL的更改时,事务溢出到磁盘的次数。 + 在为该槽解码来自WAL的更改时,事务溢出到磁盘的次数。 此计数器在每次事务被溢出时递增,并且同一事务可能被溢出多次。 @@ -2676,20 +2818,14 @@ description | Waiting for a newly initialized WAL file to reach durable storage spill_bytes bigint - - 在对来自WAL的更改执行解码时,已解码的事务数据溢出到磁盘的数量。 - 这个和其他溢出计数器可用于测量逻辑解码期间发生的I/O,并且允许调优logical_decoding_work_mem。 - + 为此槽从 WAL 解码更改时,溢出到磁盘的已解码事务数据量。此计数器及其他溢出计数器可用于衡量逻辑解码期间发生的 I/O,并用于调优logical_decoding_work_mem stream_txns bigint - - 在逻辑解码在解码来自该槽位的WAL更改的时候,所使用的内存超过logical_decoding_work_mem之后,流式传输到解码输出插件的正在进行的事务数。 - 流式传输仅对顶级事务有效(子事务不能独立进行流式传输),因此子事务的计数器不会增加。 - + 当逻辑解码为此槽从 WAL 解码更改时所使用的内存超过logical_decoding_work_mem后,流式传输到解码输出插件的进行中事务数。流式传输仅适用于顶层事务(子事务不能单独进行流式传输),因此子事务不会使此计数器递增。 @@ -2697,7 +2833,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage stream_countbigint - 在为该槽位解码来自WAL的更改时,将正在进行的事务流式传输到解码输出插件的次数。 + 在为该槽解码来自WAL的更改时,将进行中事务流式传输到解码输出插件的次数。 此计数器在每次事务流式传输时递增,并且同一事务可能被流式传输多次。 @@ -2707,8 +2843,8 @@ description | Waiting for a newly initialized WAL file to reach durable storage stream_bytesbigint - 在为该槽位解码来自WAL的更改时,为将正在进行的事务流式传输到解码输出插件而解码的事务数据的数量。 - 这个和针对此槽位的其他流式传输计数器可用于调优logical_decoding_work_mem。 + 在为该槽解码来自WAL的更改时,为将进行中事务流式传输到解码输出插件而解码的事务数据量。 + 这个和针对此槽的其他流式传输计数器可用于调优logical_decoding_work_mem
@@ -2729,7 +2865,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage 针对此槽的,发送到解码输出插件的已解码事务数。 - 这只计算顶级事务,对子事务不会增加。 + 这只计算顶层事务,对子事务不会增加。 注意,这包括流式传输和/或溢出的事务。
@@ -2739,7 +2875,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage total_bytesbigint - 在对此槽位的WAL进行解码时,为将事务发送到解码输出插件而解码的事务数据量。 + 在为此槽从 WAL 解码更改时,为将事务发送到解码输出插件而解码的事务数据量。 注意这包括流式传输和/或溢出的数据。 @@ -2769,9 +2905,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage stats_reset timestamp with time zone - - 这些统计最后重置的时间 - + 这些统计信息上次被重置的时间
@@ -2786,9 +2920,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage pg_stat_wal_receiver - - pg_stat_wal_receiver事务只包含一行,它显示了从 WAL 接收进程所连接的服务器得到的有关该接收进程的统计信息。 - + pg_stat_wal_receiver视图只包含一行,显示 WAL 接收进程从其所连接服务器接收数据的统计信息。 @@ -2813,7 +2945,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage pidinteger - WAL 接收进程的进程ID + WAL 接收进程的进程 ID @@ -2863,7 +2995,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage receive_start_lsnpg_lsn - WAL 接收进程启动时使用的第一个写前日志位置 + WAL 接收进程启动时使用的第一个预写式日志位置 @@ -2872,7 +3004,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage receive_start_tliinteger - WAL 接收进程启动时使用的第一个时间线数字 + WAL 接收进程启动时使用的第一个时间线编号 @@ -2881,7 +3013,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage written_lsnpg_lsn - 已经接收并写入磁盘的最后一个预写式日志位置,但没有刷入。这不能用于数据完整性检查。 + 已经接收并写入磁盘的最后一个预写式日志位置,但尚未刷盘。此字段不应用于数据完整性检查。 @@ -2890,7 +3022,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage flushed_lsnpg_lsn - 已经接收并刷入到磁盘的最后一个预写式日志位置,该字段的初始值是启动WAL 接收进程时使用的第一个日志位置 + 已经接收并刷入到磁盘的最后一个预写式日志位置,该字段的初始值是启动 WAL 接收进程时使用的第一个日志位置 @@ -2899,7 +3031,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage received_tliinteger - 接收并刷入到磁盘的最后一个预写式日志位置的时间线数字,该字段的初始值为启动WAL 接收进程时使用的第一个日志位置的时间线数字 + 接收并刷入到磁盘的最后一个预写式日志位置的时间线编号,该字段的初始值为启动 WAL 接收进程时使用的第一个日志位置的时间线编号 @@ -2944,7 +3076,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage slot_nametext - 这个WAL 接收进程使用的复制槽的名称 + 这个 WAL 接收进程使用的复制槽的名称 @@ -2953,8 +3085,8 @@ description | Waiting for a newly initialized WAL file to reach durable storage sender_hosttext - 这个WAL 接收进程连接到的PostgreSQL实例的主机。 - 这可以是主机名、IP地址,或者目录路径,如果连接是通过Unix套接字进行的。(路径的情况可以区分,因为它总是以/开头的绝对路径。) + 这个 WAL 接收进程连接到的PostgreSQL实例的主机。 + 这可以是主机名、IP地址,或者目录路径,如果连接是通过Unix套接字进行的。(路径的情况可以区分,因为它总是以/开头的绝对路径。) @@ -2963,7 +3095,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage sender_portinteger - 这个WAL 接收进程连接的PostgreSQL实例的端口号。 + 这个 WAL 接收进程连接的PostgreSQL实例的端口号。 @@ -2972,7 +3104,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage conninfotext - 这个WAL 接收进程使用的连接字符串,对安全敏感的字段进行了模糊处理。 + 这个 WAL 接收进程使用的连接字符串,对安全敏感的字段进行了模糊处理。 @@ -3058,8 +3190,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage replay_end_tliinteger - 当前正在重放的 WAL 记录所在的时间线。当没有正在主动重放的记录时, - 等于last_replayed_tli。 + 当前正在重放的 WAL 记录所在的时间线。如果当前没有正在重放的记录,则等于last_replayed_tli @@ -3078,7 +3209,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage 启动进程观察到重放已经追上从流复制接收的最新 WAL 块的时间。 - 用于恢复冲突计时和重放/应用延迟诊断。如果尚未接收到流式 WAL,或无法获得该时间,则为 NULL。 + 用于恢复冲突计时和重放/应用延迟诊断。如果尚未接收到流式 WAL,或无法获得该时间,则为空值。 @@ -3092,17 +3223,17 @@ description | Waiting for a newly initialized WAL file to reach durable storage - not paused: 恢复正在正常进行。 + not paused: 恢复正在正常进行。 - pause requested: 已经请求暂停,但恢复尚未真正暂停。 + pause requested: 已经请求暂停,但恢复尚未真正暂停。 - paused: 恢复已暂停。 + paused: 恢复已暂停。 @@ -3151,9 +3282,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage stats_reset timestamp with time zone - - 这些统计数据上次重置的时间 - + 这些统计信息上次被重置的时间 @@ -3228,9 +3357,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage wal_distance int - - 预取器向前查看多少字节 - + 预取器向前查看的字节数 @@ -3239,9 +3366,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage block_distance int - - 预取器正在查看多少个块之前 - + 预取器向前查看的块数 @@ -3250,9 +3375,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage io_depth int - - 已启动但尚未完成的预取数量 - + 已启动但尚未确认完成的预取数量 @@ -3295,7 +3418,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + subname name @@ -3304,7 +3427,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + worker_type text @@ -3313,7 +3436,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + pid integer @@ -3322,68 +3445,69 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + leader_pid integer - 如果此进程是并行应用工作进程,则为主应用工作进程的进程 ID;如果此进程是主应用工作进程、表同步工作进程或序列同步工作进程,则为 NULL + 如果此进程是并行应用工作进程,则为领导者应用工作进程的进程 ID;如果此进程是领导者应用工作进程、表同步工作进程或序列同步工作进程,则为 NULL - + relid oid - 该工作进程正在同步的关系的 OID;主应用工作进程、并行应用工作进程和序列同步工作进程则为 NULL + 该工作进程正在同步的关系的 OID;对于领导者应用工作进程、并行应用工作进程和序列同步工作进程,则为空值 - + received_lsn pg_lsn - 接收到的最后一个预写式日志位置,该字段的初始值为 0;并行应用工作进程和序列同步工作进程则为 NULL + 接收到的最后一个预写式日志位置,该字段的初始值为 0;对于并行应用工作进程和序列同步工作进程,则为 NULL - + last_msg_send_time timestamp with time zone - 从源 WAL 发送进程收到的最后一条消息的发送时间;并行应用工作进程和序列同步工作进程则为 NULL + 从源 WAL 发送进程收到的最后一条消息的发送时间;对于并行应用工作进程和序列同步工作进程,则为 NULL - + last_msg_receipt_time timestamp with time zone - 从源 WAL 发送进程收到的最后一条消息的接收时间;并行应用工作进程和序列同步工作进程则为 NULL + 从源 WAL 发送进程收到的最后一条消息的接收时间;对于并行应用工作进程和序列同步工作进程,则为 NULL - + latest_end_lsn pg_lsn - 向源 WAL 发送进程报告的最后一个预写式日志位置;并行应用工作进程和序列同步工作进程则为 NULL + 向源 WAL 发送进程报告的最后一个预写式日志位置;对于并行应用工作进程和序列同步工作进程,则为 NULL - + latest_end_time timestamp with time zone - 向源 WAL 发送进程报告最后一个预写式日志位置的时间;并行应用工作进程和序列同步工作进程则为 NULL + 向源 WAL 发送进程报告最后一个预写式日志位置的时间;对于并行应用工作进程和序列同步工作进程,则为 NULL +
@@ -3442,7 +3566,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage apply_error_count bigint - 应用更改时发生错误的次数 + 应用更改时发生错误的次数。请注意,导致应用错误的任何冲突都会同时计入 apply_error_count 和对应的冲突计数(例如 confl_*)。
@@ -3540,9 +3664,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage stats_reset timestamp with time zone - - 这些统计数据最后一次重置的时间 - + 这些统计信息上次被重置的时间
@@ -3603,7 +3725,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage version text - 使用SSL的版本,如果此连接上没有使用SSL则为NULL + 使用SSL的版本,如果此连接上没有使用SSL则为空值
@@ -3612,7 +3734,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage cipher text - 正在使用的SSL密码的名称,如果此连接上没有使用SSL则为NULL + 正在使用的SSL 密码套件的名称,如果此连接上没有使用SSL则为空值
@@ -3621,7 +3743,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage bits integer - 使用的加密算法中的位数,如果此连接上没有使用SSL则为NULL + 使用的加密算法中的位数,如果此连接上没有使用SSL则为空值
@@ -3630,8 +3752,8 @@ description | Waiting for a newly initialized WAL file to reach durable storage client_dn text - 区别名称(DN,Distinguished Name)字段与使用的客户端证书,如果没有提供客户端证书或在此连接上没有使用SSL,则为NULL。 - 如果DN字段长于NAMEDATALEN(标准构建中为64个字符),则该字段将被截断。 + 所用客户端证书中的区别名称(DN,Distinguished Name)字段,如果没有提供客户端证书或在此连接上没有使用SSL,则为空值。 + 如果DN字段长于NAMEDATALEN(标准构建中为64个字符),则该字段将被截断。
@@ -3640,8 +3762,8 @@ description | Waiting for a newly initialized WAL file to reach durable storage client_serial numeric - 客户端证书的序列号,如果没有提供客户端证书或在此连接上没有使用SSL,则为NULL。 - 证书序列号和证书颁发者的组合唯一标识一个证书(除非颁发者错误地重用序列号)。 + 客户端证书的序列号,如果没有提供客户端证书或在此连接上没有使用SSL,则为空值。 + 证书序列号和证书颁发者的组合唯一标识一个证书(除非颁发者错误地重用序列号)。
@@ -3650,7 +3772,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage issuer_dn text - 客户端证书颁发者的区别名称(DN,Distinguished Name),如果没有提供客户端证书或在此连接上没有使用SSL,则为NULL。该字段像client_dn一样被截断。 + 客户端证书颁发者的区别名称(DN,Distinguished Name),如果没有提供客户端证书或在此连接上没有使用SSL,则为空值。该字段像client_dn一样被截断。
@@ -3668,7 +3790,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage pg_stat_gssapi视图将包含每一个后端一个行,显示该连接上的GSSAPI使用情况。 - 它可以加入到pg_stat_activitypg_stat_replication上的pid列,获取更多关于连接的详细信息。 + 可以通过pid列将它与pg_stat_activitypg_stat_replication连接,获取更多关于连接的详细信息。 @@ -3712,8 +3834,8 @@ description | Waiting for a newly initialized WAL file to reach durable storage principaltext - 用于验证此连接的主体,如果未使用GSSAPI对此连接进行认证,则为NULL。 - 如果主体长度超过NAMEDATALEN(标准构建中为64个字符),则该字段被截断。 + 用于认证此连接的主体,如果未使用GSSAPI对此连接进行认证,则为空值。 + 如果主体长度超过NAMEDATALEN(标准构建中为64个字符),则该字段被截断。 @@ -3827,9 +3949,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage stats_reset timestamp with time zone - - 这些统计数据最后一次重置的时间 - + 这些统计信息上次被重置的时间 @@ -3879,7 +3999,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage backend_typetext - 后端类型(例如后台工作进程、autovacuum 工作进程)。有关 backend_type 的更多信息,请参阅pg_stat_activity。某些 backend_type 不会累计 I/O 操作统计信息,因此不会出现在该视图中。 + 后端类型(例如后台工作进程、自动清理工作进程)。有关 backend_type 的更多信息,请参阅pg_stat_activity。某些 backend_type 不会累积 I/O 操作统计信息,因此不会出现在该视图中。 @@ -3891,7 +4011,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage I/O 操作的目标对象。可能的值有: - + @@ -3909,6 +4029,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage + @@ -3933,7 +4054,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - vacuum:对永久关系执行 vacuum 和 analyze 时,在共享缓冲区之外执行的 I/O 操作。临时表 vacuum 与其他临时表 I/O 操作共用同一本地缓冲池,因此会在 contextnormal 时跟踪。 + vacuum:对永久关系执行清理和分析 时,在共享缓冲区之外执行的 I/O 操作。临时表清理 与其他临时表 I/O 操作共用同一本地缓冲池,因此会在 contextnormal 时跟踪。 @@ -4135,9 +4256,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage stats_reset timestamp with time zone - - 这些统计信息上次被重置的时间。 - + 这些统计信息上次被重置的时间。 @@ -4149,7 +4268,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - 此外,某些 I/O 操作永远不会由某些后端类型执行,或者永远不会针对某些 I/O 对象和/或在某些 I/O 上下文中执行。这些单元格会是 NULL。例如,临时表不会执行 fsync,因此当 objecttemp relation 时,fsyncs 将为 NULL。又如,后台写入器不会执行读取,因此当 backend_typebackground writer 时,reads 将为 NULL。 + 此外,某些 I/O 操作永远不会由某些后端类型执行,或者永远不会针对某些 I/O 对象和/或在某些 I/O 上下文中执行。这些单元格会是空值。例如,临时表不会执行 fsync,因此当 objecttemp relation 时,fsyncs 将为空值。又如,后台写入器不会执行读取,因此当 backend_typebackground writer 时,reads 将为空值。 @@ -4166,7 +4285,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - 客户端后端依赖检查点进程确保数据持久化到永久存储。客户端后端出现大量 fsyncs 可能表明共享缓冲区或检查点进程配置不当。有关配置检查点进程的更多信息,请参阅。 + 客户端后端依赖检查点进程确保数据持久化到永久存储。client backend出现大量 fsyncs 可能表明共享缓冲区或检查点进程配置不当。有关配置检查点进程的更多信息,请参阅 @@ -4229,7 +4348,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage waits bigint - 由于冲突锁而必须等待的这种锁类型的次数。只有在等待超过 后成功获得锁时才会递增。 + 此类型的锁因与其他锁冲突而必须等待的次数。只有在等待超过 后成功获得锁时才会递增。 @@ -4261,9 +4380,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage stats_reset timestamp with time zone - - 这些统计信息最后一次重置的时间。 - + 这些统计信息上次被重置的时间。 @@ -4328,9 +4445,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage stats_reset timestamp with time zone - - 这些统计信息上次被重置的时间 - + 这些统计信息上次被重置的时间 @@ -4458,9 +4573,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage stats_reset timestamp with time zone - - 这些统计信息上次被重置的时间 - + 这些统计信息上次被重置的时间 @@ -4519,79 +4632,48 @@ description | Waiting for a newly initialized WAL file to reach durable storage - - - wal_fpi_bytes numeric - - - WAL 整页镜像的总字节数 - - + wal_bytes numeric - 生成的WAL总数,以字节计 + 生成的 WAL 总量,以字节计 - wal_buffers_full bigint + wal_fpi_bytes numeric - 因为缓冲区已满,WAL数据被写入磁盘的次数 + WAL 整页镜像的总字节数 - wal_write bigint + wal_buffers_full bigint - 通过XLogWrite请求,WAL缓冲区被写入到磁盘的次数。 - 有关内部WAL函数XLogWrite的更多信息,请参见。 + 因为 WAL 缓冲区已满,WAL 数据被写入磁盘的次数 - - - wal_sync bigint - - - 通过issue_xlog_fsync 请求将WAL文件同步到磁盘的次数(如果onfdatasync, fsyncfsync_writethrough,否则为零)。 - 有关内部WAL函数issue_xlog_fsync的更多信息,参见。 - - - - - wal_write_time double precision - - - 通过XLogWrite请求将WAL缓冲区写入磁盘所消耗的总时间,以毫秒计(如果是启用的,否则为零)。 - 这包括当wal_sync_methodopen_datasyncopen_sync时的同步时间。 - - - - - wal_sync_time double precision - - - 通过issue_xlog_fsync请求将WAL文件同步到磁盘所消耗的总时间,以毫秒计(如果 track_wal_io_timing 被启用,fsync is on, 和 wal_sync_methodfdatasync, fsyncfsync_writethrough, 否则为零). - - + + + + + stats_reset timestamp with time zone - - 这些统计数据最后一次重置的时间 - + 这些统计信息上次被重置的时间 @@ -4637,7 +4719,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + datname name @@ -4646,17 +4728,17 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + numbackends integer 当前连接到此数据库的后端数,对于共享对象则为NULL。 - 这是该视图中唯一返回反映当前状态的值的列;所有其他列返回自上次重置以来累积的值。 + 这是该视图中唯一返回反映当前状态的值的列;所有其他列返回自上次重置以来累积的值。 - + xact_commit bigint @@ -4665,7 +4747,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + xact_rollback bigint @@ -4674,7 +4756,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + blks_read bigint @@ -4683,7 +4765,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + blks_hit bigint @@ -4692,7 +4774,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + tup_returned bigint @@ -4701,7 +4783,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + tup_fetched bigint @@ -4710,7 +4792,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + tup_inserted bigint @@ -4719,7 +4801,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + tup_updated bigint @@ -4728,7 +4810,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + tup_deleted bigint @@ -4737,7 +4819,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + conflicts bigint @@ -4746,7 +4828,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + temp_files bigint @@ -4755,7 +4837,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + temp_bytes bigint @@ -4764,7 +4846,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + deadlocks bigint @@ -4773,7 +4855,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + checksum_failures bigint @@ -4782,7 +4864,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + checksum_last_failure timestamp with time zone @@ -4791,7 +4873,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + blk_read_time double precision @@ -4800,7 +4882,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + blk_write_time double precision @@ -4809,25 +4891,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - - - parallel_workers_to_launch bigint - - - 计划由该数据库上的查询启动的并行工作进程数 - - - - - - parallel_workers_launched bigint - - - 由该数据库上的查询启动的并行工作进程数 - - - - + session_time double precision @@ -4836,7 +4900,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + active_time double precision @@ -4845,7 +4909,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + idle_in_transaction_time double precision @@ -4854,7 +4918,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + sessions bigint @@ -4863,7 +4927,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + sessions_abandoned bigint @@ -4872,7 +4936,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + sessions_fatal bigint @@ -4881,7 +4945,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + sessions_killed bigint @@ -4890,7 +4954,25 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + + + parallel_workers_to_launch bigint + + + 计划由该数据库上的查询启动的并行工作进程数 + + + + + + parallel_workers_launched bigint + + + 由该数据库上的查询启动的并行工作进程数 + + + + stats_reset timestamp with time zone @@ -4898,6 +4980,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage 这些统计数据最后一次重置的时间 +
@@ -4984,7 +5067,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage confl_bufferpin bigint - 此数据库中由于固定缓冲区而被取消的查询数 + 此数据库中由于缓冲区被钉住而被取消的查询数
@@ -5005,8 +5088,17 @@ description | Waiting for a newly initialized WAL file to reach durable storage 此数据库中因旧快照或主库上的 太低而被取消的逻辑槽使用次数
- - + + + + stats_reset timestamp with time zone + + + 这些统计信息上次被重置的时间 + + + + @@ -5091,7 +5183,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage seq_tup_read bigint - 连续扫描获取的实时行数 + 顺序扫描获取的存活行数
@@ -5118,7 +5210,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage idx_tup_fetch bigint - 索引扫描获取的实时行数 + 索引扫描获取的存活行数
@@ -5135,9 +5227,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage n_tup_upd bigint - - 更新的行数(包括HOT更新的行) - + 更新的总行数。(包括计入n_tup_hot_updn_tup_newpage_upd的行更新,以及其余非HOT更新。)
@@ -5153,9 +5243,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage n_tup_hot_upd bigint - - HOT更新的行数(即,不需要单独的索引更新) - + 进行HOT 更新的行数。这些更新不需要在索引中存储后继版本。 @@ -5163,7 +5251,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage n_tup_newpage_upd bigint - 更新的行数,其中后继版本转到新的堆页,留下一个原始版本,其t_ctid字段指向不同的堆页。这些始终是非 HOT 更新。 + 更新的行数,其中后继版本转到的堆页,留下一个原始版本,其t_ctid字段指向不同的堆页。这些始终是非 HOT 更新。 @@ -5198,9 +5286,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage n_ins_since_vacuum bigint - - 自上次清理此表以来插入的行的估计数量 - + 自上次清理此表以来插入的行的估计数量(不计VACUUM FULL
@@ -5208,7 +5294,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage last_vacuum timestamp with time zone - 最后一次手动清理这个表(不包括VACUUM FULL) + 最后一次手动清理这个表的时间(不包括VACUUM FULL @@ -5226,7 +5312,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage last_analyze timestamp with time zone - 上一次手动分析这个表 + 上一次手动分析这个表的时间
@@ -5235,7 +5321,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage last_autoanalyze timestamp with time zone - 自动清理守护进程最后一次分析这个表 + 自动清理守护进程最后一次分析这个表的时间
@@ -5244,7 +5330,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage vacuum_count bigint - 这个表被手动清理的次数(VACUUM FULL不计数) + 这个表被手动清理的次数(VACUUM FULL不计数)
@@ -5280,7 +5366,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage total_vacuum_time double precision - 手动 VACUUM 此表所花费的总时间,以毫秒计(不包括 VACUUM FULL)。(这包括由于基于成本的延迟而睡眠的时间。) + 手动清理此表所花费的总时间,以毫秒计(不包括 VACUUM FULL)。(这包括由于基于代价的延迟而睡眠的时间。)
@@ -5289,7 +5375,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage total_autovacuum_time double precision - 自动清理守护进程对该表执行 VACUUM 所花费的总时间,以毫秒计。(这包括由于基于成本的延迟而睡眠的时间。) + 自动清理守护进程清理该表 所花费的总时间,以毫秒计。(这包括由于基于代价的延迟而睡眠的时间。)
@@ -5298,7 +5384,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage total_analyze_time double precision - 手动分析该表所花费的总时间,以毫秒计。(这包括由于基于成本的延迟而睡眠的时间。) + 手动分析该表所花费的总时间,以毫秒计。(这包括由于基于代价的延迟而睡眠的时间。)
@@ -5307,7 +5393,16 @@ description | Waiting for a newly initialized WAL file to reach durable storage total_autoanalyze_time double precision - 自动清理守护进程分析该表所花费的总时间,以毫秒计。(这包括由于基于成本的延迟而睡眠的时间。) + 自动清理守护进程分析该表所花费的总时间,以毫秒计。(这包括由于基于代价的延迟而睡眠的时间。) + +
+ + + + stats_reset timestamp with time zone + + + 这些统计信息上次被重置的时间 @@ -5564,7 +5659,16 @@ description | Waiting for a newly initialized WAL file to reach durable storage idx_tup_fetch bigint - 使用此索引进行简单索引扫描获取的活动表行数 + 使用此索引进行简单索引扫描获取的存活表行数 + +
+ + + + stats_reset timestamp with time zone + + + 这些统计信息上次被重置的时间 @@ -5572,16 +5676,25 @@ description | Waiting for a newly initialized WAL file to reach durable storage - 索引可以被简单索引扫描、位图索引扫描以及优化器使用。在一次位图扫描中,多个索引的输出可以被通过 AND 或 OR 规则组合,因此当使用一次位图扫描时难以将取得的个体堆行与特定的索引关联起来。因此,一次位图扫描会增加它使用的索引的pg_stat_all_indexes.idx_tup_read计数,并且为每个表增加pg_stat_all_tables.idx_tup_fetch计数,但是它不影响pg_stat_all_indexes.idx_tup_fetch。如果所提供的常量值不在优化器统计信息记录的范围之内,优化器也会访问索引来检查,因为优化器统计信息可能已经“不新鲜”了。 + 索引可以被简单索引扫描、位图索引扫描以及优化器使用。在一次位图扫描中,多个索引的输出可以被通过 AND 或 OR 规则组合,因此当使用一次位图扫描时难以将取得的个体堆行与特定的索引关联起来。因此,一次位图扫描会增加它使用的索引的pg_stat_all_indexes.idx_tup_read计数,并且为该表增加pg_stat_all_tables.idx_tup_fetch计数,但是它不影响pg_stat_all_indexes.idx_tup_fetch。如果所提供的常量值不在优化器统计信息记录的范围之内,优化器也会访问索引来检查,因为优化器统计信息可能已经过时。 - 即使不用位图扫描,idx_tup_readidx_tup_fetch计数也可能不同,因为idx_tup_read统计从该索引取得的索引项而idx_tup_fetch统计从表取得的活着的行。如果使用该索引取得了任何死亡行或还未提交的行,或者如果通过一次只用索引扫描的方式避免了任何堆获取,后者将较小。 + 即使不用位图扫描,idx_tup_readidx_tup_fetch计数也可能不同,因为idx_tup_read统计从该索引取得的索引项而idx_tup_fetch统计从表取得的存活行。如果使用该索引取得了任何死亡行或还未提交的行,或者如果通过一次仅索引扫描的方式避免了任何堆获取,后者将较小。 + + 索引扫描在一次执行中有时会进行多次索引搜索。每次索引搜索都会递增pg_stat_all_indexes.idx_scan,因此索引扫描计数可能显著超过索引扫描执行器节点的总执行次数。 + 使用某些SQL构造来搜索与列表或数组中的多个标量值之一匹配的行时,可能出现这种情况(参见)。使用column_name = value1 OR column_name = value2 ...构造的查询也可能如此,但前提是优化器将该构造转换为等价的多值数组表示。同样,当 B-树索引扫描使用跳跃扫描优化时,每次将扫描位置移至下一个可能包含匹配元组的索引叶子页,都会进行一次索引搜索(参见)。 + + + + EXPLAIN ANALYZE会输出每个索引扫描节点执行的索引搜索总次数。有关展示其工作方式的示例,请参见 + + @@ -5681,7 +5794,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage toast_blks_read bigint - 从这个表的TOAST表中读取的磁盘块的数量(如果有的话) + 从这个表的TOAST表中读取的磁盘块的数量(如果有的话)
@@ -5690,7 +5803,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage toast_blks_hit bigint - 这个表的TOAST表中的缓冲区命中数(如果有的话) + 这个表的TOAST表中的缓冲区命中数(如果有的话)
@@ -5699,7 +5812,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage tidx_blks_read bigint - 从这个表的TOAST表索引中读取的磁盘块的数量(如果有的话) + 从这个表的TOAST表索引中读取的磁盘块的数量(如果有的话)
@@ -5708,9 +5821,16 @@ description | Waiting for a newly initialized WAL file to reach durable storage tidx_blks_hit bigint - 这个表的TOAST表索引中的缓冲区命中数(如果有的话) + 这个表的TOAST表索引中的缓冲区命中数(如果有的话)
+ + + + stats_reset timestamp with time zone + + 这些统计信息上次被重置的时间 + @@ -5809,6 +5929,13 @@ description | Waiting for a newly initialized WAL file to reach durable storage 此索引中的缓冲区命中数
+ + + + stats_reset timestamp with time zone + + 这些统计信息上次被重置的时间 + @@ -5888,6 +6015,13 @@ description | Waiting for a newly initialized WAL file to reach durable storage 在此序列中的缓冲区命中数 + + + + stats_reset timestamp with time zone + + 这些统计信息上次被重置的时间 + @@ -5982,9 +6116,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage stats_reset timestamp with time zone - - 这些统计数据最后一次重置的时间 - + 这些统计信息上次被重置的时间 @@ -6003,10 +6135,9 @@ description | Waiting for a newly initialized WAL file to reach durable storage pg_stat_slru - - PostgreSQL通过SLRU(simple least-recently-used,简单的最近-最少-使用)缓存访问某些磁盘上的信息。 - pg_stat_slru视图将为每个被跟踪的SLRU缓存包含一行,显示关于访问缓存页面的统计信息。 - + PostgreSQL通过SLRU简单最近最少使用)缓存访问某些磁盘上的信息。pg_stat_slru视图将为每个被跟踪的 SLRU 缓存包含一行,显示关于访问缓存页面的统计信息。 + + 对于核心服务器中的每个SLRU缓存,都有一个以_buffers为后缀的配置参数来控制其大小。 @@ -6049,7 +6180,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage blks_hitbigint - 已经在SLRU中的磁盘块被发现的次数,因此不需要读取(这只包括SLRU中的命中,而不是操作系统的文件系统缓存) + 已经在SLRU中的磁盘块被发现的次数,因此不需要读取(这只包括SLRU中的命中,而不是操作系统的文件系统缓存) @@ -6085,7 +6216,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage flushesbigint - 此SLRU的脏数据刷新数 + 此SLRU的脏数据刷盘次数 @@ -6094,7 +6225,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage truncatesbigint - 这个SLRU的截断数 + 这个SLRU的截断次数 @@ -6102,9 +6233,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage stats_reset timestamp with time zone - - 这些统计数据最后一次重置的时间 - + 这些统计信息上次被重置的时间 @@ -6124,7 +6253,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - 与累积统计系统相关的其他功能在中列出。 + 与累积统计系统相关的其他函数在中列出。
@@ -6168,7 +6297,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage 返回指定进程 ID 的后端的 I/O 统计信息。输出字段与 pg_stat_io 视图中的字段完全相同。 - 该函数不会返回检查点进程、后台写入器、启动进程和 自动清理启动器的 I/O 统计信息,因为这些统计信息已经在 pg_stat_io 视图中可见,而且每种都只有一个。 + 该函数不返回检查点进程、后台写入器、启动进程和自动清理启动器的 I/O 统计信息,因为这些统计信息已显示在 pg_stat_io 视图中,而且每种进程都只有一个。 @@ -6211,7 +6340,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage timestamp with time zone - 返回当前统计快照的时间戳,如果没有统计快照则返回NULL。如果在事务中第一次访问累积统计信息时将快照设置为stats_fetch_consistencysnapshot。 + 返回当前统计快照的时间戳;如果尚未获取统计快照,则返回 NULL。如果 stats_fetch_consistency 设置为 snapshot,则会在事务中第一次访问累积统计信息时获取快照。 @@ -6267,9 +6396,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage 将当前数据库的所有统计计数器重置为零。 - - 默认情况下该函数仅限于超级用户,但是其他用户可以被授予EXECUTE来运行此函数。 - + 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 @@ -6283,88 +6410,64 @@ description | Waiting for a newly initialized WAL file to reach durable storage 根据参数将一些集簇范围的统计计数器重置为零。target 可以是: - - - archiver:重置 pg_stat_archiver 视图中的所有计数器。 - - - - - bgwriter:重置 pg_stat_bgwriter 视图中的所有计数器。 - - - - - checkpointer:重置 pg_stat_checkpointer 视图中的所有计数器。 - - - - - io:重置 pg_stat_io 视图中的所有计数器。 - - - - - lock:重置 pg_stat_lock 视图中的所有计数器。 - - - - - recovery_prefetch:重置 pg_stat_recovery_prefetch 视图中的所有计数器。 - - - - - slru:重置 pg_stat_slru 视图中的所有计数器。 - - - - - wal:重置 pg_stat_wal 视图中的所有计数器。 - - - - - NULL 或未指定:重置上面列出的所有视图中的所有计数器。 - - + + archiver:重置 pg_stat_archiver 视图中显示的所有计数器。 + + + bgwriter:重置 pg_stat_bgwriter 视图中显示的所有计数器。 + + + checkpointer:重置 pg_stat_checkpointer 视图中显示的所有计数器。 + + + io:重置 pg_stat_io 视图中显示的所有计数器。 + + + lock:重置 pg_stat_lock 视图中显示的所有计数器。 + + + recovery_prefetch:重置 pg_stat_recovery_prefetch 视图中显示的所有计数器。 + + + slru:重置 pg_stat_slru 视图中显示的所有计数器。 + + + wal:重置 pg_stat_wal 视图中显示的所有计数器。 + + + NULL 或未指定:重置上述所有视图中的所有计数器。 + - - 默认情况下,此函数仅限超级用户使用,但可以授予其他用户EXECUTE权限来运行该函数。 - + 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 - + - pg_stat_reset_backend_stats + pg_stat_reset_single_table_counters - pg_stat_reset_backend_stats ( integer ) + pg_stat_reset_single_table_counters ( oid ) void - 将指定进程 ID 的单个后端进程的统计信息重置为零。 + 将单个表或索引的统计信息重置为零;该对象可以位于当前数据库中,也可以由集簇中的所有数据库共享。它也可以重置当前数据库中单个序列或物化视图的统计信息。 - - 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 - + 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 - + - pg_stat_reset_single_table_counters + pg_stat_reset_backend_stats - pg_stat_reset_single_table_counters ( oid ) + pg_stat_reset_backend_stats ( integer ) void - 将当前数据库中的单个表或索引,或集簇中所有数据库共享的单个表或索引的统计信息重置为零。它还会重置当前数据库中单个序列或物化视图的统计信息。 + 将指定进程 ID 的单个后端进程的统计信息重置为零。 - - 默认情况下,此函数仅限超级用户使用,但可以授予其他用户EXECUTE权限来运行该函数。 - + 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 @@ -6378,9 +6481,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage 将当前数据库中单个函数的统计信息重置为零。 - - 默认情况下该函数仅限于超级用户,但是其他用户可以被授予EXECUTE来运行此函数。 - + 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 @@ -6388,19 +6489,13 @@ description | Waiting for a newly initialized WAL file to reach durable storage pg_stat_reset_slru - pg_stat_reset_slru ( text ) + pg_stat_reset_slru ( [ target text DEFAULT NULL ] ) void - 将单个SLRU缓存或集簇中所有SLRU的统计信息重置为零。 - 如果该参数为NULL,则所有SLRU缓存的pg_stat_slru视图中显示的计数器将被重置。 - 参数可以是CommitTsMultiXactMemberMultiXactOffsetNotify、 - SerialSubtrans、 或Xact中的一个,以便只重置该条目的计数器。 - 如果参数是other(或实际上,任何无法识别的名称),那么所有其他SLRU缓存的计数器,如扩展定义的缓存,将被重置。 + 将单个 SLRU 缓存或集簇中所有 SLRU 的统计信息重置为零。如果 targetNULL 或未指定,则重置 pg_stat_slru 视图中所有 SLRU 缓存的全部计数器。参数可以为 commit_timestamp、&zwsp;multixact_member、&zwsp;multixact_offset、&zwsp;notify、&zwsp;serializable、&zwsp;subtransactiontransaction 中的一个,以便只重置对应条目的计数器。如果参数为 other(实际上,任何无法识别的名称都可以),则重置其他所有 SLRU 缓存的计数器,例如扩展定义的缓存。 - - 默认情况下该函数仅限于超级用户,但是其他用户可以被授予EXECUTE来运行此函数。 - + 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 @@ -6415,9 +6510,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage 重置由参数定义的复制槽的统计信息。 如果参数为NULL,则重置所有复制槽的统计信息。 - - 该函数默认仅限于超级用户,但可以授予其他用户EXECUTE权限来运行该函数。 - + 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 @@ -6432,9 +6525,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage 重置pg_stat_subscription_stats视图中显示的单个订阅的统计信息为零。 如果参数是NULL,则重置所有订阅的统计信息。 - - 默认情况下,此函数仅限超级用户使用,但其他用户可以被授予EXECUTE权限来运行该函数。 - + 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 @@ -6450,17 +6541,18 @@ description | Waiting for a newly initialized WAL file to reach durable storage - pg_stat_get_activitypg_stat_activity视图的底层函数, - 它返回一个行集合,其中包含有关每个后端进程所有可用的信息。有时只获得该信息的一个子集可能会更方便。 - 在那些情况中,可以使用一组更老的针对每个后端的统计访问函数,这些显示在中。 - 这些访问函数使用一个后端 ID 号,范围从 1 到当前活动后端数目。 - 函数pg_stat_get_backend_idset提供了一种方便的方法为每个活动后端产生一行来调用这些函数。 - 例如,要显示PID以及所有后端当前的查询: + pg_stat_get_activitypg_stat_activity 视图的底层函数, + 返回一组记录,其中包含有关每个后端进程的全部可用信息。有时只获取其中一部分信息会更方便。 + 在这种情况下,可以使用另一组针对每个后端的统计信息访问函数,见 。 + 这些访问函数使用会话的后端 ID 号,它是一个值较小的非负整数(>= 0),与任何并发会话的后端 ID 都不同, + 但会话退出后,其 ID 可立即被重新使用。后端 ID 的用途之一是标识会话的临时模式(如果有)。 + 函数 pg_stat_get_backend_idset 提供了一种便捷的方法,可列出所有活动后端的 ID 号来调用这些函数。 + 例如,要显示所有后端的 PID 和当前查询: -SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - pg_stat_get_backend_activity(s.backendid) AS query - FROM (SELECT pg_stat_get_backend_idset() AS backendid) AS s; +SELECT pg_stat_get_backend_pid(backendid) AS pid, + pg_stat_get_backend_activity(backendid) AS query +FROM pg_stat_get_backend_idset() AS backendid; @@ -6482,19 +6574,6 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - - - - pg_stat_get_backend_idset - - pg_stat_get_backend_idset () - setof integer - - - 返回当前活动后端ID号的集合(从1到活动后端数)。 - - - @@ -6514,7 +6593,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, pg_stat_get_backend_activity_start pg_stat_get_backend_activity_start ( integer ) - 有时区的时间戳 + timestamp with time zone 返回后端最近一次查询开始的时间。 @@ -6560,6 +6639,19 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, + + + + pg_stat_get_backend_idset + + pg_stat_get_backend_idset () + setof integer + + + 返回当前活动后端 ID 号的集合。 + + + @@ -6579,11 +6671,9 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, pg_stat_get_backend_start pg_stat_get_backend_start ( integer ) - 有时区的时间戳 + timestamp with time zone - - 返回该进程开始的时间。 - + 返回该进程开始的时间。 @@ -6615,28 +6705,28 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - pg_stat_get_backend_wait_event_type + pg_stat_get_backend_wait_event - pg_stat_get_backend_wait_event_type ( integer ) + pg_stat_get_backend_wait_event ( integer ) text - 如果后端当前正在等待,则返回等待事件类型名称,否则返回NULL。 - 请参阅。 + 如果后端当前正在等待,则返回等待事件名称,否则为空值。 + 请参阅 - pg_stat_get_backend_wait_event + pg_stat_get_backend_wait_event_type - pg_stat_get_backend_wait_event ( integer ) + pg_stat_get_backend_wait_event_type ( integer ) text - 如果后端当前正在等待,则返回等待事件名称,否则为NULL。 - 请参阅。 + 如果后端当前正在等待,则返回等待事件类型名称,否则返回空值。 + 请参阅 @@ -6646,7 +6736,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, pg_stat_get_backend_xact_start pg_stat_get_backend_xact_start ( integer ) - 有时区的时间戳 + timestamp with time zone 返回后端当前事务开始的时间。 @@ -6664,23 +6754,23 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, 查看锁 - lock - monitoring + + 监控 - 监控数据库活动的另外一个有用的工具是pg_locks系统表。这样就允许数据库管理员查看在锁管理器里面未解决的锁的信息。例如,这个功能可以被用于: + 监控数据库活动的另外一个有用的工具是pg_locks系统表。这样就允许数据库管理员查看锁管理器中当前存在的锁的信息。例如,这个功能可以被用于: - 查看当前所有未解决的锁、在一个特定数据库中的关系上所有的锁、在一个特定关系上所有的锁,或者由一个特定PostgreSQL会话持有的所有的锁。 + 查看当前存在的所有锁、在一个特定数据库中的关系上所有的锁、在一个特定关系上所有的锁,或者由一个特定PostgreSQL会话持有的所有的锁。 - 判断当前数据库中带有最多未授予锁的关系(它很可能是数据库客户端的竞争源)。 + 判断当前数据库中带有最多未授予锁的关系(它可能是数据库客户端之间的竞争来源)。 @@ -6847,7 +6937,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, delay_time double precision - 因基于成本的延迟而睡眠的总时间(参见),以毫秒计(如果启用了 ,否则为零)。 + 因基于代价的延迟而睡眠的总时间(参见),以毫秒计(如果启用了 ,否则为零)。 @@ -6900,14 +6990,14 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, acquiring sample rows - 该命令当前正在扫描relid给出的表以获得样例行。 + 该命令当前正在扫描relid给出的表以获得样本行。 acquiring inherited sample rows - 该命令当前正在扫描子表以获得样例行。列child_tables_total,child_tables_done, + 该命令当前正在扫描子表以获得样本行。列child_tables_totalchild_tables_done、 和current_child_table_relid包含此阶段的进度信息。 @@ -6915,14 +7005,14 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, computing statistics - 该命令从表扫描期间获得的样例行计算统计信息。 + 该命令从表扫描期间获得的样本行计算统计信息。 computing extended statistics - 该命令从表扫描期间获得的样例行计算扩展统计信息。 + 该命令从表扫描期间获得的样本行计算扩展统计信息。 @@ -6938,29 +7028,25 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - - 注意当在分区表上运行ANALYZE时,它的所有分区也会被递归分析。 - 在这种情况下,首先报告父表的ANALYZE进度,收集它的继承统计信息,然后是每个分区的(继承统计信息)。 - + 请注意,当在分区表上运行ANALYZE且未指定ONLY关键字时,其所有分区也会被递归分析。在这种情况下,会先报告父表的ANALYZE进度,并收集其继承统计信息,随后再报告每个分区的进度。 - + - CREATE INDEX 进度报告 + CLUSTER 进度报告 - pg_stat_progress_create_index + pg_stat_progress_cluster - 每当运行CREATE INDEXREINDEX时,pg_stat_progress_create_index视图将包含当前正在创建索引的每个后端的一行。 - 下面的表描述了将要报告的信息,并提供了关于如何解释它的信息。 + 每当REPACKCLUSTERVACUUM FULL运行时,为向后兼容而保留的pg_stat_progress_cluster视图将为每个当前正在运行这些命令之一的后端包含一行。下面的表格描述了将被报告的信息,并提供了关于如何解释这些信息的信息。 -
+
- <structname>pg_stat_progress_create_index</structname> 视图 + <structname>pg_stat_progress_cluster</structname> 视图 @@ -7008,16 +7094,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, relidoid - 正在创建索引的表的OID。 - - - - - - index_relid oid - - - 正在创建或重建索引的OID。在非并发 CREATE INDEX的时候,此为 0。 + 正在聚簇的表的OID。 @@ -7026,8 +7103,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, commandtext - 在运行的命令: CREATE INDEX,CREATE INDEX CONCURRENTLY, - REINDEX, 或 REINDEX CONCURRENTLY. + 正在运行的命令。CLUSTERVACUUM FULL。由于此视图仅为向后兼容而存在,它会将任何REPACK命令映射为这两种命令之一。 @@ -7036,176 +7112,527 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, phasetext - 索引创建的当前处理阶段。 参见 。 - - - - - - lockers_total bigint - - - 在适用的情况下,需要等待的储物柜总数 - - - - - - lockers_done bigint - - - 已经等待的储物柜数量。 - - - - - - current_locker_pid bigint - - - 目前正在等待的储物柜的进程ID。 + 当前处理阶段。参见 - blocks_total bigint + cluster_index_relid oid - 本阶段要处理的区块总数。 + 如果正在使用索引对表进行扫描,这就是正在使用的索引的OID;否则为0。 - blocks_done bigint + heap_tuples_scanned bigint - 当前阶段已经处理的区块数量。 + 扫描的堆元组数。 + 该计数器仅在阶段为seq scanning heapindex scanning heap + 或 writing new heap 时才会递增。 - tuples_total bigint + heap_tuples_written bigint - 当前阶段要处理的元组总数。 + 写入的堆元组的数量。这个计数器只有在阶段为seq scanning heapindex scanning heap + 或 writing new heap时才会递增。 - tuples_done bigint + heap_blks_total bigint - 在当前阶段已经处理的元组数量。 + 表中的堆块总数。 这个数字以seq scanning heap开始时的数量为准。 - partitions_total bigint + heap_blks_scanned bigint - 在分区表上创建索引时,该列被设置为要在其上创建索引的分区总数。 - 在REINDEX期间,此字段为0。 + 扫描的堆块数量。该计数器仅在阶段为seq scanning heap时才会递增。 - partitions_done bigint + index_rebuild_count bigint - 当在分区表上创建索引时,该列被设置为在其上建立索引的分区数。 - 在REINDEX期间,此字段为0。 + 已重建的索引数。该计数器仅在rebuilding index阶段时才会递增。
- +
- CREATE INDEX 的阶段 + CLUSTER 和 VACUUM FULL 阶段 - + 阶段 描述 - - - 初始化 - - CREATE INDEXREINDEX正在准备创建索引。 这个阶段预计会非常短暂。 - + + + + initializing + + 命令正在准备开始扫描堆。这个阶段预计会非常短暂。 + + + + + seq scanning heap + + 该命令目前采用顺序扫描的方式对表进行扫描。 + + + + + index scanning heap + + CLUSTER目前正在使用索引扫描表。 + + + + + sorting tuples + + CLUSTER目前正在对元组进行排序。 + + + + + writing new heap + + CLUSTER目前正在写入新的堆。 + + + + + swapping relation files + + 目前,该命令正在将新建立的文件调换到位。 + + + + + rebuilding index + + 该命令目前正在重建一个索引。 + + + + + performing final cleanup + + 该命令正在执行最后的清理工作。 当此阶段完成后,CLUSTERVACUUM FULL将结束。 + + + + +
+ + + + + COPY 进度报告 + + + pg_stat_progress_copy + + + + 当COPY正在运行时,pg_stat_progress_copy视图会为每个当前正在执行COPY命令的后端包含一行。下表描述了会报告哪些信息,以及应如何解释这些信息。 + + + + + <structname>pg_stat_progress_copy</structname> 视图 + + + + + + 列类型 + + + 描述 + + + + + + + + + pid integer + + + 后端的进程ID。 + + + + + + datid oid + + + 后端连接到的数据库的OID。 + + + + + + datname name + + + 后端连接到的数据库的名称。 + + + + + + relid oid + + + 执行COPY命令的表的OID。 + 如果从SELECT查询中复制,它被设置为0。 + + + + + + command text + + + 正在运行的命令: COPY FROMCOPY TO。 + + + + + + type text + + 读取或写入数据的 I/O 类型:FILEPROGRAMPIPE(用于COPY FROM STDINCOPY TO STDOUT),或CALLBACK(例如在逻辑复制的初始表同步期间使用)。 + + + + + bytes_processed bigint + + + 已经被COPY命令处理的字节数。 + + + + + + bytes_total bigint + + + COPY FROM命令的源文件大小,以字节计。 + 如果不可用则设置为0。 + + + + + + tuples_processed bigint + + + 已经被COPY命令处理的元组数。 + + + + + + tuples_excluded bigint + + + 没有处理的元组数,因为它们被COPY命令的WHERE子句所排除。 + + + + + + tuples_skipped bigint + + + 因包含格式错误的数据而被跳过的元组数。只有当 ON_ERROR 指定为 ignore 时,此计数器才会递增。 + + + + +
+ +
+ + + + CREATE INDEX 进度报告 + + + pg_stat_progress_create_index + + + + 每当运行CREATE INDEXREINDEX时,pg_stat_progress_create_index视图将包含当前正在创建索引的每个后端的一行。 + 下面的表描述了将要报告的信息,并提供了关于如何解释它的信息。 + + + + + <structname>pg_stat_progress_create_index</structname> 视图 + + + + + + 列类型 + + + 描述 + + + + + + + + + pid integer + + 正在创建索引的后端的进程 ID。 + + + + + datid oid + + + 后端连接到的数据库的OID。 + + + + + + datname name + + + 后端连接到的数据库的名称。 + + + + + + relid oid + + + 正在创建索引的表的OID。 + + + + + + index_relid oid + + + 正在创建或重建索引的OID。在非并发 CREATE INDEX的时候,此为 0。 + + + + + + command text + + + 具体命令类型: CREATE INDEXCREATE INDEX CONCURRENTLY、 + REINDEXREINDEX CONCURRENTLY。 + + + + + + phase text + + + 索引创建的当前处理阶段。 参见 。 + + + + + + lockers_total bigint + + 在适用的情况下,需要等待的持锁进程总数。 + + + + + lockers_done bigint + + 已完成等待的持锁进程数量。 + + + + + current_locker_pid bigint + + 当前正在等待的持锁进程的进程 ID。 + + + + + blocks_total bigint + + + 本阶段要处理的块总数。 + + + + + + blocks_done bigint + + + 当前阶段已经处理的块数量。 + + + + + + tuples_total bigint + + + 当前阶段要处理的元组总数。 + + + + + + tuples_done bigint + + + 在当前阶段已经处理的元组数量。 + + + + + + partitions_total bigint + + 要创建或附加索引的分区总数,包括直接分区和间接分区。在REINDEX期间,或索引未分区时,此值为0 + + + + + partitions_done bigint + + 已创建或附加索引的分区数量,包括直接分区和间接分区。在REINDEX期间,或索引未分区时,此值为0 + + + +
+ + + + CREATE INDEX 阶段 + + + + + + + 阶段 + 描述 + + + + + + initializing + + CREATE INDEXREINDEX正在准备创建索引。 这个阶段预计会非常短暂。 + - 构建前等待读写器 + waiting for writers before build - CREATE INDEX CONCURRENTLYREINDEX CONCURRENTLY正在等待有可能看到表的写锁的事务完成。 当不在并发模式时,这个阶段会被跳过。lockers_totallockers_donecurrent_locker_pid 列包含了这个阶段的进度信息。 + CREATE INDEX CONCURRENTLYREINDEX CONCURRENTLY正在等待持有写锁且可能看到该表的事务结束。 当不在并发模式时,这个阶段会被跳过。lockers_totallockers_donecurrent_locker_pid 列包含了这个阶段的进度信息。 - 新建索引 + building index - 索引是由访问方法专用代码建立的。 在这一阶段,支持进度报告的访问方法填写自己的进度数据,子阶段在这一栏中表示。 通常情况下,blocks_totalblocks_done将包含进度数据,也可能包含tuples_totaltuples_done。 + 索引是由访问方法专用代码建立的。 在这一阶段,支持进度报告的访问方法填写自己的进度数据,子阶段在这一栏中表示。 通常情况下,blocks_totalblocks_done将包含进度数据,tuples_totaltuples_done也可能包含进度数据。 - 在验证前等待读写器 + waiting for writers before validation - CREATE INDEX CONCURRENTLYREINDEX CONCURRENTLY正在等待有可能写入表的事务完成写锁的事务。当不在并发模式时,这个阶段会被跳过。lockers_totallockers_donecurrent_locker_pid 列包含了这个阶段的进度信息。 + CREATE INDEX CONCURRENTLYREINDEX CONCURRENTLY正在等待持有写锁且可能写入该表的事务结束。当不在并发模式时,这个阶段会被跳过。lockers_totallockers_donecurrent_locker_pid 列包含了这个阶段的进度信息。 - 索引验证:扫描索引 + index validation: scanning index CREATE INDEX CONCURRENTLY正在扫描索引,搜索需要验证的元组。如果不是并发模式,则会跳过此阶段。列 blocks_total(设为索引总大小)和 blocks_done 包含该阶段的进度信息。 - 索引验证:排序元组 + index validation: sorting tuples CREATE INDEX CONCURRENTLY正在对索引扫描阶段的输出进行排序。 - 索引验证:扫描表 + index validation: scanning table CREATE INDEX CONCURRENTLY正在扫描表,以验证前两个阶段收集的索引元组。如果不是并发模式,则会跳过此阶段。blocks_total 列(设为表总大小)和 blocks_done 列包含该阶段的进度信息。 - 等待旧照 + waiting for old snapshots CREATE INDEX CONCURRENTLYREINDEX CONCURRENTLY正在等待可能看到表的事务释放快照。 当不处于并发模式时,这个阶段会被跳过。 lockers_totallockers_donecurrent_locker_pid 列包含了这个阶段的进度信息。 - 标记 dead之前等待readers + waiting for readers before marking dead REINDEX CONCURRENTLY等待表上有读锁的事务完成后,再将旧索引标记为死索引。当不在并发模式时,这个阶段被跳过。lockers_totallockers_donecurrent_locker_pid 列包含了这个阶段的进度信息。 - 在 dropping之前等待readers + waiting for readers before dropping REINDEX CONCURRENTLY等待表上有读锁的事务完成后,再丢弃旧索引。当不在并发模式时,这个阶段被跳过。列 lockers_totallockers_donecurrent_locker_pid包含了这个阶段的进度信息。 @@ -7246,7 +7673,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, pid integer - 后端的进程 ID。 + 后端的进程ID。 @@ -7254,7 +7681,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, datid oid - 后端连接到的数据库的 OID。 + 后端连接到的数据库的OID。 @@ -7294,7 +7721,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, repack_index_relid oid - 如果正使用索引扫描表,这里就是所用索引的 OID;否则为零。 + 如果正在使用索引对表进行扫描,这就是正在使用的索引的OID;否则为0。 @@ -7302,7 +7729,9 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, heap_tuples_scanned bigint - 扫描的堆元组数。该计数器仅在 seq scanning heapindex scanning heapwriting new heap 阶段递增。 + 扫描的堆元组数。 + 该计数器仅在阶段为seq scanning heapindex scanning heap + 或 writing new heap 时才会递增。 @@ -7334,7 +7763,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, heap_blks_total bigint - 表中的堆块总数。这个数字在 seq scanning heap 开始时报告。 + 表中的堆块总数。 这个数字以seq scanning heap开始时的数量为准。 @@ -7342,7 +7771,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, heap_blks_scanned bigint - 已扫描的堆块数。该计数器仅在 seq scanning heap 阶段递增。 + 扫描的堆块数量。该计数器仅在阶段为seq scanning heap时才会递增。 @@ -7350,7 +7779,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, index_rebuild_count bigint - 已重建的索引数。该计数器仅在 rebuilding index 阶段递增。 + 已重建的索引数。该计数器仅在rebuilding index阶段时才会递增。 @@ -7378,8 +7807,8 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, seq scanning heap - 命令正在使用顺序扫描扫描表。 - + 该命令目前采用顺序扫描的方式对表进行扫描。 + index scanning heap @@ -7408,14 +7837,14 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, swapping relation files - 命令正在把新构建的文件交换到位。 - + 目前,该命令正在将新建立的文件调换到位。 + rebuilding index - 命令正在重建一个索引。 - + 该命令目前正在重建一个索引。 + performing final cleanup @@ -7479,400 +7908,182 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - datname name - - - 后端连接到的数据库的名称。 - - - - - - relid oid - - - 被vacuum的表的OID。 - - - - - - phase text - - - vacuum的当前处理阶段。参见 。 - - - - - - heap_blks_total bigint - - - 该表中堆块的总数。这个数字在扫描开始时报告,之后增加的块将不会(并且不需要)被这个VACUUM访问。 - - - - - - heap_blks_scanned bigint - - - 被扫描的堆块数量。由于visibility map被用来优化扫描,一些块将被跳过而不做检查, - 被跳过的块会被包括在这个总数中,因此当清理完成时这个数字最终将会等于heap_blks_total。 - 仅当处于扫描堆阶段时这个计数器才会前进。 - - - - - - heap_blks_vacuumed bigint - - - 被清理的堆块数量。除非表没有索引,这个计数器仅在处于清理堆阶段时才会前进。 - 不包含死亡元组的块会被跳过,因此这个计数器可能有时会向前跳跃一个比较大的增量。 - - - - - - index_vacuum_count bigint - - - 已完成的索引清理周期数。 - - - - - - max_dead_tuple_bytes bigint - - - 在需要执行索引清理周期之前可存储的死亡元组数据量,取决于。 - - - - - - dead_tuple_bytes bigint - - - 自上一个索引清理周期以来收集到的死亡元组数据量。 - - - - - - num_dead_item_ids bigint - - - 自上一个索引清理周期以来收集到的死项标识符数量。 - - - - - - indexes_total bigint - - - 将要执行 vacuum 或清理的索引总数。该数字会在 vacuuming indexescleaning up indexes 阶段开始时报告。 - - - - - - indexes_processed bigint - - - 已处理的索引数量。该计数器只会在 vacuuming indexescleaning up indexes 阶段推进。 - - - - - - delay_time double precision - - - 因基于成本的延迟而睡眠的总时间(参见),以毫秒计(如果启用了 ,否则为零)。这包括任何相关并行工作进程的睡眠时间;不过,并行工作进程最多每秒才会上报一次自己的睡眠时间,因此该值可能略有滞后。 - - - - - - mode text - - - 当前 VACUUM 操作所处的模式。有关每种模式的详细信息请参见 。可能的值有: - - - - normal:执行标准 清理,既不需要以 激进 模式运行,也不处于 失效保护 模式。 - - - - - aggressive:执行 激进清理,必须扫描所有未标记为 全部冻结 的页面。 决定何时需要 激进清理。 - - - - - failsafe:清理 已进入 失效保护 模式,只执行避免事务 ID 或 多事务 ID 回卷失败所需的最少工作。 决定何时进入 失效保护 模式。清理 可能一开始就处于该模式,或者运行过程中切换到该模式;mode 列的值在操作期间可能从其他模式变为 failsafe。 - - - - - - - - - started_by text - - - 说明当前 VACUUM 操作是由什么触发的。可能的值有: - - - - manual:由显式的 VACUUM 命令启动。 - - - - - autovacuum:由自动清理工作进程启动。自动清理工作进程执行的 清理 可能会因锁冲突而被中断。 - - - - - autovacuum_wraparound:由自动清理工作进程为防止事务 ID 或 多事务 ID 回卷而启动。用于回卷保护的 清理 不会因锁冲突而中断。 - - - - - - - -
- - - - VACUUM的阶段 - - - - - - - 阶段 - 描述 - - - - - - - 初始化 - - VACUUM正在准备开始扫描堆。这个阶段应该很简短。 - - - - - 扫描堆 - - VACUUM正在扫描堆。如果需要,它将会对每个页面进行修建以及碎片整理,并且可能会执行冻结动作。heap_blks_scanned列可以用来监控扫描的进度。 - - - - - 清理索引 - - VACUUM当前正在清理索引。 - 如果一个表拥有索引,那么每次清理时这个阶段会在堆扫描完成后至少发生一次。 - 如果不足以存放找到的死亡元组(或者, 在autovacuum情况下,如果设置了) ,则每次清理时会多次清理索引。 - - - - - 清理堆 - - VACUUM当前正在清理堆。清理堆与扫描堆不是同一个概念,清理堆发生在每一次清理索引的实例之后。如果heap_blks_scanned小于heap_blks_total,系统将在这个阶段完成之后回去扫描堆;否则,系统将在这个阶段完成后开始清理索引。 - - - - - 清除索引 - - VACUUM当前正在清除索引。这个阶段发生在堆被完全扫描并且对堆和索引的所有清理都已经完成以后。 - - - - - 截断堆 - - VACUUM正在截断堆,以便把关系尾部的空页面返还给操作系统。这个阶段发生在清除完索引之后。 - - - - - 执行最终清理 - - VACUUM正在执行最终清理。在此阶段,VACUUM将清理空闲空间映射, - 更新pg_class中的统计信息,并向累积统计系统报告统计信息。当此阶段完成时, - VACUUM将结束。 - - - - -
- -
- - - - CLUSTER 进度报告 - - - pg_stat_progress_cluster - - - - 每当REPACKCLUSTERVACUUM FULL运行时,为向后兼容而保留的pg_stat_progress_cluster视图将为每个当前正在运行这些命令之一的后端包含一行。下面的表格描述了将被报告的信息,并提供了关于如何解释这些信息的信息。 - - - - - <structname>pg_stat_progress_cluster</structname> 视图 - - - - - - 列类型 + datname name - 描述 + 后端连接到的数据库的名称。 - - + + + relid oid + + + 正在清理的表的OID。 + + - pid integer + phase text - 后端的进程ID。 + 清理的当前处理阶段。参见 - datid oid + heap_blks_total bigint - 后端连接到的数据库的OID。 + 该表中堆块的总数。这个数字以扫描开始时的数量为准,之后增加的块将不会(并且不需要)被这个VACUUM访问。 - datname name + heap_blks_scanned bigint - 后端连接到的数据库的名称。 + 被扫描的堆块数量。由于可见性映射被用来优化扫描,一些块将被跳过而不做检查, + 被跳过的块会被包括在这个总数中,因此当清理完成时这个数字最终将会等于heap_blks_total。 + 仅当处于scanning heap阶段时这个计数器才会前进。 - relid oid + heap_blks_vacuumed bigint - 被集群的表的OID。 + 被清理的堆块数量。除非表没有索引,这个计数器仅在处于vacuuming heap阶段时才会前进。 + 不包含死亡元组的块会被跳过,因此这个计数器可能有时会向前跳跃一个比较大的增量。 - command text + index_vacuum_count bigint - 正在运行的命令。CLUSTERVACUUM FULL。由于此视图仅为向后兼容而存在,它会将任何REPACK命令映射为这两种命令之一。 + 已完成的索引清理周期数。 - phase text + max_dead_tuple_bytes bigint - 当前处理阶段。参见。 + 在需要执行索引清理周期之前可存储的死亡元组数据量,取决于 - cluster_index_relid oid + dead_tuple_bytes bigint - 如果正在使用索引对表进行扫描,这就是正在使用的索引的OID;否则为0。 + 自上一个索引清理周期以来收集到的死亡元组数据量。 - heap_tuples_scanned bigint + num_dead_item_ids bigint - 扫描的堆元组数。 - 该计数器仅在阶段为seq scanning heapindex scanning heap - 或 writing new heap 时才会递增。 + 自上一个索引清理周期以来收集到的死项标识符数量。 - heap_tuples_written bigint + indexes_total bigint - 写入的堆元组的数量。这个计数器只有在阶段为seq scanning heap,index scanning heap - 或 writing new heap时才会前进。 + 将要执行清理或收尾清理的索引总数。该数字会在 vacuuming indexescleaning up indexes 阶段开始时报告。 - heap_blks_total bigint + indexes_processed bigint - 表中的堆块总数。 这个数字是在seq scanning heap的开始时报告的。 + 已处理的索引数量。该计数器只会在 vacuuming indexescleaning up indexes 阶段推进。 - heap_blks_scanned bigint + delay_time double precision - 扫描的堆块数量。该计数器仅在阶段为seq scanning heap时才会递增。 + 因基于代价的延迟而睡眠的总时间(参见),以毫秒计(如果启用了 ,否则为零)。这包括任何相关并行工作进程的睡眠时间;不过,并行工作进程最多每秒才会上报一次自己的睡眠时间,因此该值可能略有滞后。 - index_rebuild_count bigint + mode text + + + 当前 VACUUM 操作所处的模式。有关每种模式的详细信息请参见 。可能的值有: + + + + normal:执行标准清理,既不需要以激进模式运行,也不处于失效保护模式。 + + + + + aggressive:执行激进清理,必须扫描所有未标记为全部冻结的页面。 决定何时需要激进清理。 + + + + + failsafe:清理已进入失效保护模式,只执行避免事务 ID 或多事务 ID 回卷失败所需的最少工作。 决定何时进入失效保护模式。清理可能一开始就处于该模式,或者运行过程中切换到该模式;mode 列的值在操作期间可能从其他模式变为 failsafe。 + + + + + + + + + started_by text - 已重建的索引数。该计数器仅在重建索引阶段时才会递增。 + 说明当前 VACUUM 操作是由什么触发的。可能的值有: + + + + manual:由显式的 VACUUM 命令启动。 + + + + + autovacuum:由自动清理工作进程启动。自动清理工作进程执行的清理可能会因锁冲突而被中断。 + + + + + autovacuum_wraparound:由自动清理工作进程为防止事务 ID 或多事务 ID 回卷而启动。用于回卷保护的清理不会因锁冲突而中断。 + + +
- +
- CLUSTER 和 VACUUM FULL 阶段 + VACUUM 阶段 @@ -7887,63 +8098,57 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - 初始化 + initializing - 该命令准备开始扫描堆栈。 这个阶段预计会非常短暂。 - - - - - seq扫描堆 - - 该命令目前采用顺序扫描的方式对表进行扫描。 + VACUUM正在准备开始扫描堆。这个阶段应该很简短。 - 索引扫描堆 + scanning heap - CLUSTER目前正在使用索引扫描表。 + VACUUM正在扫描堆。如果需要,它将会对每个页面进行剪枝以及碎片整理,并且可能会执行冻结动作。heap_blks_scanned列可以用来监控扫描的进度。 - 元组排序 - - CLUSTER目前正在对元组进行排序。 - + vacuuming indexes + VACUUM当前正在清理索引。如果表有索引,每次清理都会在堆扫描完成后至少执行一次此阶段。如果(或者,对于自动清理,已设置的)不足以存储找到的死亡元组数量,则每次清理可能多次执行此阶段。 - 新写入堆 + vacuuming heap - CLUSTER目前正在编写新的堆。 + VACUUM当前正在清理堆。清理堆与扫描堆不是同一个概念,清理堆发生在每次索引清理之后。如果heap_blks_scanned小于heap_blks_total,系统将在这个阶段完成之后回去扫描堆;否则,系统将在这个阶段完成后开始索引收尾清理。 - 交换关系文件 + cleaning up indexes - 目前,该命令正在将新建立的文件调换到位。 + VACUUM当前正在进行索引收尾清理。这个阶段发生在堆被完全扫描并且对堆和索引的所有清理都已经完成以后。 - 重建索引 + truncating heap - 该命令目前正在重建一个索引。 + VACUUM正在截断堆,以便把关系尾部的空页面返还给操作系统。这个阶段发生在索引收尾清理完成之后。 - 清理 + performing final cleanup - 该命令正在执行最后的清理工作。 当此阶段完成后,CLUSTERVACUUM FULL将结束。 + VACUUM正在执行最终清理。在此阶段,VACUUM将清理空闲空间映射, + 更新pg_class中的统计信息,并向累积统计系统报告统计信息。当此阶段完成时, + VACUUM将结束。
+
@@ -8004,7 +8209,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, 将被流式传输的数据总量。该值在streaming database files阶段开始时进行估算并报告。 注意,这只是一个近似值,因为数据库可能会在streaming database files阶段期间发生变化,而 WAL 日志也可能在稍后的备份阶段被包含进来。 一旦流式传输的数据量超过了估计的总大小,该值始终与backup_streamed相同。 - 如果在pg_basebackup中禁用估算(也就是说,指定了--no-estimate-size选项),这为NULL。 + 如果在pg_basebackup中禁用估算(也就是说,指定了--no-estimate-size选项),这为NULL。 @@ -8070,7 +8275,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - 等待检查点完成 + waiting for checkpoint to finish WAL 发送进程当前正在执行pg_backup_start以准备进行基础备份,并等待备份起始检查点完成。 @@ -8091,7 +8296,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - 等待wal归档完成 + waiting for wal archiving to finish WAL发送进程当前正在执行pg_backup_stop以完成备份, 并等待基础备份所需的所有 WAL 文件成功归档。 @@ -8114,142 +8319,6 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - - - COPY 进度报告 - - - pg_stat_progress_copy - - - - 当COPY正在运行时,pg_stat_progress_copy视图会为每个当前正在执行COPY命令的后端包含一行。下表描述了会报告哪些信息,以及应如何解释这些信息。 - - - - - <structname>pg_stat_progress_copy</structname> 视图 - - - - - - 列类型 - - - 描述 - - - - - - - - - pid integer - - - 后端的进程ID。 - - - - - - datid oid - - - 后端连接到的数据库的OID。 - - - - - - datname name - - - 后端连接到的数据库的名称。 - - - - - - relid oid - - - 执行COPY命令的表的OID。 - 如果从SELECT查询中复制,它被设置为0。 - - - - - - command text - - - 正在运行的命令: COPY FROM, 或 COPY TO。 - - - - - - type text - - - 数据被读取或写入的io类型:FILE, PROGRAM, PIPE (对于COPY FROM STDINCOPY TO STDOUT),或 CALLBACK(例如在逻辑复制中初始表同步期间使用)。 - - - - - - bytes_processed bigint - - - 已经被COPY命令处理的字节数。 - - - - - - bytes_total bigint - - - COPY FROM命令的源文件大小,以字节计。 - 如果不可用则设置为0。 - - - - - - tuples_processed bigint - - - 已经被COPY命令处理的元组数。 - - - - - - tuples_excluded bigint - - - 没有处理的元组数,因为它们被COPY命令的WHERE子句所排除。 - - - - - - tuples_skipped bigint - - - 因包含格式错误的数据而被跳过的元组数。只有当 ON_ERROR 指定为 ignore 时,此计数器才会递增。 - - - - -
- -
- 数据校验和进度报告 @@ -8329,7 +8398,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, databases_total bigint - 将要处理的数据库总数。只有在启用数据校验和时,启动器进程才会设置这个值; + 将要处理的数据库总数。启用数据校验和时,只有启动器进程的这个值会被设置; 否则该值为 NULL @@ -8341,7 +8410,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, databases_done bigint - 已处理的数据库数量。只有在启用数据校验和时,启动器进程才会设置这个值; + 已处理的数据库数量。启用数据校验和时,只有启动器进程的这个值会被设置; 否则该值为 NULL @@ -8466,7 +8535,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - 动态追踪的编译 + 为动态追踪编译 默认情况下,探针是不可用的,因此你将需要显式地告诉配置脚本让探针在PostgreSQL中可用。要包括 DTrace 支持,在配置时指定。更多信息请见。 @@ -8478,7 +8547,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, 内置探针 - 如所示,源代码中提供了一些标准探针。显式了在探针中使用的类型。当然,可以增加更多探针来增强PostgreSQL的可观测性。 + 如所示,源代码中提供了一些标准探针。显示了在探针中使用的类型。当然,可以增加更多探针来增强PostgreSQL的可观测性。 @@ -8514,13 +8583,13 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, transaction-abort (LocalTransactionId) - 当一个事务失败完成时触发的探针。arg0 是事务 ID。 + 当一个事务失败结束时触发的探针。arg0 是事务 ID。 query-start (const char *) - 当一个查询的处理被开始时触发的探针。arg0 是查询字符串。 + 当一个查询的处理开始时触发的探针。arg0 是查询字符串。 @@ -8532,7 +8601,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, query-parse-start (const char *) - 当一个查询的解析被开始时触发的探针。arg0 是查询字符串。 + 当一个查询的解析开始时触发的探针。arg0 是查询字符串。 @@ -8544,7 +8613,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, query-rewrite-start (const char *) - 当一个查询的重写被开始时触发的探针。arg0 是查询字符串。 + 当一个查询的重写开始时触发的探针。arg0 是查询字符串。 @@ -8556,7 +8625,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, query-plan-start () - 当一个查询的规划被开始时触发的探针。 + 当一个查询的规划开始时触发的探针。 @@ -8568,7 +8637,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, query-execute-start () - 当一个查询的执行被开始时触发的探针。 + 当一个查询的执行开始时触发的探针。 @@ -8586,19 +8655,19 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, checkpoint-start (int) - 当一个检查点被开始时触发的探针。arg0 传递位标志来区分不同的检查点类型,例如关闭(shutdown)、立即(immediate)或强制(force)。 + 当一个检查点开始时触发的探针。arg0 传递位标志来区分不同的检查点类型,例如关闭(shutdown)、立即(immediate)或强制(force)。 checkpoint-done (int, int, int, int, int) - 当一个检查点完成时触发的探针(检查点处理过程中序列中列出的下一个触发的探针)。arg0 是要写的缓冲区数量。arg1 是缓冲区的总数。arg2、arg3 和 arg4 分别包含了增加、删除和循环回收的 WAL 文件的数量。 + 当一个检查点完成时触发的探针(下面列出的探针会在检查点处理过程中依次触发)。arg0 是已写入的缓冲区数量。arg1 是缓冲区的总数。arg2、arg3 和 arg4 分别包含了增加、删除和循环回收的 WAL 文件的数量。 clog-checkpoint-start (bool) - 当一个检查点的 CLOG 部分被开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 + 当一个检查点的 CLOG 部分开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 @@ -8610,7 +8679,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, subtrans-checkpoint-start (bool) - 当一个检查点的 SUBTRANS 部分被开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 + 当一个检查点的 SUBTRANS 部分开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 @@ -8622,7 +8691,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, multixact-checkpoint-start (bool) - 当一个检查点的 MultiXact 部分被开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 + 当一个检查点的 MultiXact 部分开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 @@ -8634,7 +8703,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, buffer-checkpoint-start (int) - 当一个检查点的写缓冲区部分被开始时触发的探针。arg0 传递位标志来区分不同的检查点类型,例如关闭(shutdown)、立即(immediate)或强制(force)。 + 当一个检查点的写缓冲区部分开始时触发的探针。arg0 传递位标志来区分不同的检查点类型,例如关闭(shutdown)、立即(immediate)或强制(force)。 @@ -8670,7 +8739,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, twophase-checkpoint-start () - 当一个检查点的两阶段部分被开始时触发的探针。 + 当一个检查点的两阶段部分开始时触发的探针。 @@ -8683,7 +8752,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, buffer-extend-start (ForkNumber, BlockNumber, Oid, Oid, Oid, int, unsigned int) 当关系扩展开始时触发的探针。 - arg0 包含要扩展的分叉。arg1、arg2 和 arg3 包含用于标识该关系的 + arg0 包含要扩展的分支。arg1、arg2 和 arg3 包含用于标识该关系的 表空间、数据库和关系 OID。对于本地缓冲区,arg4 是创建临时关系的后端 ID; 对于共享缓冲区,则为 INVALID_PROC_NUMBER(-1)。 arg5 是调用者希望扩展的块数。 @@ -8693,7 +8762,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, buffer-extend-done (ForkNumber, BlockNumber, Oid, Oid, Oid, int, unsigned int, BlockNumber) 当关系扩展完成时触发的探针。 - arg0 包含要扩展的分叉。arg1、arg2 和 arg3 包含用于标识该关系的 + arg0 包含要扩展的分支。arg1、arg2 和 arg3 包含用于标识该关系的 表空间、数据库和关系 OID。对于本地缓冲区,arg4 是创建临时关系的后端 ID; 对于共享缓冲区,则为 INVALID_PROC_NUMBER(-1)。 arg5 是关系实际扩展的块数;由于资源限制,该值可能小于 @@ -8705,7 +8774,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, buffer-read-start (ForkNumber, BlockNumber, Oid, Oid, Oid, int) 当缓冲区读取开始时触发的探针。 - arg0 和 arg1 包含该页的分叉号和块号。 + arg0 和 arg1 包含该页的分支号和块号。 arg2、arg3 和 arg4 包含用于标识该关系的表空间、数据库和关系 OID。 对于本地缓冲区,arg5 是创建临时关系的后端 ID;对于共享缓冲区, 则为 INVALID_PROC_NUMBER(-1)。 @@ -8716,7 +8785,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, buffer-read-done (ForkNumber, BlockNumber, Oid, Oid, Oid, int, bool) 当缓冲区读取完成时触发的探针。 - arg0 和 arg1 包含该页的分叉号和块号。 + arg0 和 arg1 包含该页的分支号和块号。 arg2、arg3 和 arg4 包含用于标识该关系的表空间、数据库和关系 OID。 对于本地缓冲区,arg5 是创建临时关系的后端 ID;对于共享缓冲区, 则为 INVALID_PROC_NUMBER(-1)。 @@ -8726,7 +8795,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, buffer-flush-start (ForkNumber, BlockNumber, Oid, Oid, Oid) - 在发出对一个共享缓冲区的任意写请求之前触发的探针。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。 + 在发出对一个共享缓冲区的任意写请求之前触发的探针。arg0 和 arg1 包含该页的分支号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。 @@ -8735,17 +8804,9 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, 当一个写请求完成时触发的探针(注意这只反映传递数据给内核的时间,它通常并没有实际地被写入到磁盘)。参数和buffer-flush-start的相同。 - - buffer-write-dirty-start - (ForkNumber, BlockNumber, Oid, Oid, Oid) - 当一个服务器进程开始写一个脏缓冲区时触发的探针(如果这经常发生,表示太小,或需要调整后台写入器的控制参数)。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。 - - - buffer-write-dirty-done - (ForkNumber, BlockNumber, Oid, Oid, Oid) - 当一次脏缓冲区写完成时触发的探针。参数与buffer-write-dirty-start相同。 - + + wal-buffer-write-dirty-start @@ -8756,13 +8817,13 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, wal-buffer-write-dirty-done () - 当一次脏 WAL 缓冲区完成时触发的探针。 + 当一次脏 WAL 缓冲区写入完成时触发的探针。 wal-insert (unsigned char, unsigned char) - 当一个 WAL 记录被插入时触发的探针。arg0 是该记录的资源管理者(rmid)。arg1 包含 info 标志。 + 当一个 WAL 记录被插入时触发的探针。arg0 是该记录的资源管理器(rmid)。arg1 包含 info 标志。 @@ -8774,31 +8835,31 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, smgr-md-read-start (ForkNumber, BlockNumber, Oid, Oid, Oid, int) - 当开始从一个关系读取一块时触发的探针。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是INVALID_PROC_NUMBER(-1)。 + 当开始从一个关系读取一块时触发的探针。arg0 和 arg1 包含该页的分支号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是INVALID_PROC_NUMBER(-1)。 smgr-md-read-done (ForkNumber, BlockNumber, Oid, Oid, Oid, int, int, int) - 当一次块读取完成时触发的探针。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是INVALID_PROC_NUMBER(-1)。arg6 是实际读取的字节数,而 arg7 是请求读取的字节数(如果两者不同就意味着麻烦)。 + 当一次块读取完成时触发的探针。arg0 和 arg1 包含该页的分支号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是INVALID_PROC_NUMBER(-1)。arg6 是实际读取的字节数,而 arg7 是请求读取的字节数(如果两者不同,则表示发生了短读)。 smgr-md-write-start (ForkNumber, BlockNumber, Oid, Oid, Oid, int) - 当开始向一个关系中写入一个块时触发的探针。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是INVALID_PROC_NUMBER(-1)。 + 当开始向一个关系中写入一个块时触发的探针。arg0 和 arg1 包含该页的分支号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是INVALID_PROC_NUMBER(-1)。 smgr-md-write-done (ForkNumber, BlockNumber, Oid, Oid, Oid, int, int, int) - 当一个块写操作完成时触发的探针。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3和arg4 包含表空间、数据库和关系 OID来标识该关系。对于一个本地缓冲区,arg5 是创建临时关系的后端 ID;对于一个共享缓冲区,arg5 是INVALID_PROC_NUMBER(-1)。arg6 是实际写的字节数,而 arg7 是要求写的字节数(如果这两者不同,则意味着麻烦)。 + 当一个块写操作完成时触发的探针。arg0 和 arg1 包含该页的分支号和块号。arg2、arg3和arg4 包含表空间、数据库和关系 OID来标识该关系。对于一个本地缓冲区,arg5 是创建临时关系的后端 ID;对于一个共享缓冲区,arg5 是INVALID_PROC_NUMBER(-1)。arg6 是实际写的字节数,而 arg7 是要求写的字节数(如果这两者不同,则表示发生了短写)。 sort-start (int, bool, int, int, bool, int) - 当一次排序操作开始时触发的探针。arg0 指示是堆排序、索引排序或数据排序。arg1 为真表示强制唯一值。arg2 是键列数。arg3 是允许使用的工作内存大小(以千字节计)。如果要求随机访问排序结果,则 arg4 为真。arg5 为 0 时表示串行,为 1 时表示并行工作进程,为 2 时表示并行领导者。 + 当一次排序操作开始时触发的探针。arg0 指示是堆排序、索引排序或 datum 排序。arg1 为真表示强制唯一值。arg2 是键列数。arg3 是允许使用的工作内存大小(以千字节计)。如果要求随机访问排序结果,则 arg4 为真。arg5 为 0 时表示串行,为 1 时表示并行工作进程,为 2 时表示并行领导者。 @@ -8812,7 +8873,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, (char *, LWLockMode) 当成功获得一个 LWLock 时触发的探针。 arg0 是该 LWLock 所在的切片(Tranche)。 - arg1 所请求的锁模式,是排他或共享。 + arg1 是所请求的锁模式,是排他或共享。 @@ -8827,34 +8888,34 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, (char *, LWLockMode) 当一个 LWLock不是当即可用并且一个服务器进程因此开始等待该锁变为可用时触发的探针。 arg0 是该 LWLock 所在的切片(Tranche)。 - arg1 请求的锁模式,是排他或共享。 + arg1 是所请求的锁模式,是排他或共享。 lwlock-wait-done (char *, LWLockMode) 当一个进程从对一个 LWLock 的等待中被释放时(它实际还没有得到该锁)时触发的探针。arg0 是该 LWLock 所在的切片(Tranche)。 - arg1 所请求的锁模式,是排他或共享。 + arg1 是所请求的锁模式,是排他或共享。 lwlock-condacquire (char *, LWLockMode) 当调用者指定无需等待而成功获得一个 LWLock 时触发的探针。arg0 是该 LWLock 所在的切片(Tranche)。 - arg1 所请求的锁模式,是排他或共享。 + arg1 是所请求的锁模式,是排他或共享。 lwlock-condacquire-fail (char *, LWLockMode) 当调用者指定无需等待而没有成功获得一个 LWLock 时触发的探针。arg0 是该 LWLock 所在的切片(Tranche)。 - arg1 所请求的锁模式,是排他或共享。 + arg1 是所请求的锁模式,是排他或共享。 lock-wait-start (unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, LOCKMODE) - 当一个重量级锁(lmgr锁)的请求由于锁不可用开始等待时触发的探针。arg0 到 arg3 是标识被锁定对象的标签域。arg4 指示被锁对象的类型。arg5 表示被请求的锁类型。 + 当一个重量级锁(lmgr锁)的请求由于锁不可用开始等待时触发的探针。arg0 到 arg3 是标识被锁定对象的标签字段。arg4 指示被锁对象的类型。arg5 表示被请求的锁类型。 @@ -8875,7 +8936,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid,
- 定义用在探针参数中的类型 + 探针参数中使用的已定义类型 @@ -8969,7 +9030,7 @@ Total time (ns) 2312105013 - 你应该记住,DTrace 脚本需要细心地编写和调试,否则被收集的追踪信息可能会毫无意义。在大部分发现问题的情况中,它就是发生问题的部件,而不是底层系统。当讨论使用动态追踪发现的信息时,一定要附上使用的脚本以便其也被检查和讨论。 + 你应该记住,DTrace 脚本需要细心地编写和调试,否则被收集的追踪信息可能会毫无意义。在大多数发现问题的情况下,出错的是插桩,而不是底层系统。当讨论使用动态追踪发现的信息时,一定要附上使用的脚本以便其也被检查和讨论。 @@ -8985,7 +9046,7 @@ Total time (ns) 2312105013 - 决定探针名称以及探针可用的数据 + 决定探针名称以及要通过探针提供的数据 @@ -8999,7 +9060,7 @@ Total time (ns) 2312105013 - 如果pg_trace.h还不存在于包含该探针点的模块中,包括它,并且在源代码中期望的位置插入TRACE_POSTGRESQL探针宏 + 如果pg_trace.h尚未被包含该探针点的模块引用,则将它包含进来,并且在源代码中期望的位置插入TRACE_POSTGRESQL探针宏 @@ -9035,14 +9096,14 @@ Total time (ns) 2312105013 probe transaction__start(LocalTransactionId); - 注意探针名字中双下划线的使用。在一个使用探针的 DTrace 脚本中,双下划线需要被替换为一个连字符,因此 ,对用户而言transaction-start是文档名。 + 注意探针名字中双下划线的使用。在一个使用探针的 DTrace 脚本中,双下划线需要被替换为一个连字符,因此,文档中应向用户说明的名称是transaction-start - 在编译时,transaction__start被转换成一个宏调用TRACE_POSTGRESQL_TRANSACTION_START(注意这里是单下划线),可以通过包括头文件pg_trace.h获得。将宏调用加入到源代码中的合适位置。在这种情况下,看起来类似: + 在编译时,transaction__start被转换成一个名为TRACE_POSTGRESQL_TRANSACTION_START的宏(注意这里是单下划线),可以通过包含头文件pg_trace.h获得。将宏调用加入到源代码中的合适位置。在这种情况下,看起来类似: TRACE_POSTGRESQL_TRANSACTION_START(vxid.localTransactionId); @@ -9079,7 +9140,7 @@ TRACE_POSTGRESQL_TRANSACTION_START(vxid.localTransactionId); - 在大多数平台上,如果用编译了PostgreSQL,无论何时当控制经过一个追踪宏时,都会评估该宏的参数,即使没有进行追踪也会这样做。通常不需要担心你是否只在报告一些局部变量的值。但是要注意不要将开销大的函数调用放入参数中。如果你需要这样做,考虑通过检查追踪是否真的被启用来保护该宏: + 在大多数平台上,如果用编译了PostgreSQL,无论何时当控制经过一个追踪宏时,都会对该宏的参数求值,即使没有进行追踪也会这样做。如果只是报告少数局部变量的值,通常无需担心这一点。但是要注意不要将开销大的函数调用放入参数中。如果你需要这样做,考虑通过检查追踪是否真的被启用来保护该宏: if (TRACE_POSTGRESQL_TRANSACTION_START_ENABLED()) @@ -9120,7 +9181,7 @@ if (TRACE_POSTGRESQL_TRANSACTION_START_ENABLED()) - 在最近执行过 VACUUMANALYZE 的数据库上使用 psql,你可以发出查询来查看任意表的磁盘使用情况: + 在最近进行过清理或分析 的数据库上使用 psql,你可以发出查询来查看任意表的磁盘使用情况: SELECT pg_relation_filepath(oid), relpages FROM pg_class WHERE relname = 'customer'; diff --git a/zh/19/mvcc.sgml b/zh/19/mvcc.sgml index 7f83abaa..ccd9ea3e 100644 --- a/zh/19/mvcc.sgml +++ b/zh/19/mvcc.sgml @@ -4,7 +4,7 @@ 并发控制 - concurrency + 并发 @@ -15,7 +15,7 @@ 介绍 - Multiversion Concurrency Control + 多版本并发控制 @@ -23,7 +23,7 @@ - Serializable Snapshot Isolation + 可串行化快照隔离 @@ -50,7 +50,7 @@ 事务隔离 - transaction isolation + 事务隔离 @@ -68,7 +68,7 @@ 脏读 - dirty read + 脏读 @@ -80,7 +80,7 @@ 不可重复读 - nonrepeatable read + 不可重复读 @@ -92,7 +92,7 @@ 幻读 - phantom read + 幻读 @@ -104,7 +104,7 @@ 串行化异常 - serialization anomaly + 串行化异常 @@ -117,7 +117,7 @@ - transaction isolation level + 事务隔离级别 SQL 标准以及 PostgreSQL 实现的事务隔离级别见 @@ -244,12 +244,12 @@ 读已提交隔离级别 - transaction isolation level - read committed + 事务隔离级别 + 读已提交 - read committed + 读已提交 @@ -341,7 +341,7 @@ COMMIT; 在读已提交模式下,更复杂的用法可能产生不理想的结果。例如,考虑一个 - DELETE 命令,它所处理的数据会被另一个命令同时加入和移出其筛选条件。 + DELETE 命令,另一个命令正在修改数据,使某些行开始满足其筛选条件、另一些行不再满足。 假设 website 是一个有两行的表,其中 website.hits 分别等于 910: @@ -349,7 +349,7 @@ COMMIT; BEGIN; UPDATE website SET hits = hits + 1; --- run from another session: DELETE FROM website WHERE hits = 10; +-- 从另一个会话运行: DELETE FROM website WHERE hits = 10; COMMIT; @@ -377,12 +377,12 @@ COMMIT; 可重复读隔离级别 - transaction isolation level - repeatable read + 事务隔离级别 + 可重复读 - repeatable read + 可重复读 @@ -435,9 +435,7 @@ ERROR: could not serialize access due to concurrent update 可重复读模式提供了严格的保证,即每个事务都看到数据库的一个完全稳定的视图。 不过,这个视图并不一定总能与同一级别并发事务的某种串行(一次一个)执行保持一致。 - 例如,即使该级别上的只读事务可能看到一条控制记录被更新,表明某个批处理已经完成, - 但它并不一定能看到作为该批处理逻辑组成部分的某条明细记录, - 因为它读到的是控制记录的较早版本。如果不仔细使用显式锁来阻塞冲突事务, + 例如,即使是该级别的只读事务,也可能看到一条表明某批次已完成的控制记录,却看不到逻辑上属于该批次的某条明细记录,因为创建该明细记录的事务读取了控制记录的较早版本。如果不仔细使用显式锁来阻塞冲突事务, 试图依靠运行在这一隔离级别的事务来强制业务规则,往往无法正确工作。 @@ -445,7 +443,7 @@ ERROR: could not serialize access due to concurrent update 可重复读隔离级别是通过一种技术实现的,这种技术在学术数据库文献中以及某些其他数据库产品中被称为 快照隔离。与使用会降低并发性的传统加锁技术的系统相比, 其行为和性能可能会表现出差异。有些其他系统甚至把可重复读和快照隔离作为两个行为不同的独立隔离级别提供。 - 用来区分这两种技术的允许现象,直到 SQL 标准制定之后才被数据库研究人员正式定义,因此超出了本手册的范围。 + 用来区分这两种技术的允许现象,直到 SQL 标准制定之后才被数据库研究人员正式定义,并且超出了本手册的范围。 完整讨论请参阅 @@ -461,20 +459,20 @@ ERROR: could not serialize access due to concurrent update 可串行化隔离级别 - transaction isolation level - serializable + 事务隔离级别 + 可串行化 - serializable + 可串行化 - predicate locking + 谓词锁 - serialization anomaly + 串行化异常 @@ -487,48 +485,30 @@ ERROR: could not serialize access due to concurrent update 一旦检测到可能导致串行化异常的条件,就会触发串行化失败 - - 例如,考虑一张表 mytab,其初始内容为: - + 例如,考虑表mytab,它最初包含以下内容: class | value -------+------- 1 | 10 1 | 20 2 | 100 2 | 200 - - 假设可串行化事务 A 计算: - +假设可串行化事务 A 执行以下计算: SELECT SUM(value) FROM mytab WHERE class = 1; - - 然后将结果(30)作为一条新行的 value 插入,并把 - class 设为 2。与此同时,可串行化事务 B 计算: - +然后将结果(30)作为新行的value插入,且该行满足class = 2。与此同时,可串行化事务 B 执行以下计算: SELECT SUM(value) FROM mytab WHERE class = 2; - - 并得到结果 300,再把它插入为一条新行,其 - class1。然后两个事务都尝试提交。 - 如果任一事务是在可重复读隔离级别下运行,则二者都可以提交; - 但由于不存在与该结果一致的串行执行顺序,使用可串行化事务时将允许其中一个事务提交, - 并按如下消息回滚另一个事务: - - +得到结果 300,并将它插入一个新行,该行满足class = 1。然后两个事务都尝试提交。如果任一事务运行在可重复读隔离级别,两个事务都可以提交;但由于不存在与该结果一致的串行执行顺序,使用可串行化事务时,只会允许一个事务提交,另一个则会被回滚,并收到以下消息: ERROR: could not serialize access due to read/write dependencies among transactions - - - 这是因为,如果 A 先于 B 执行,B 算出的和将是 330 而不是 300; - 反过来,另一种顺序也会使 A 算出不同的和。 - +这是因为,如果 A 在 B 之前执行,B 算出的总和应该是 330,而不是 300;同样,按另一种顺序执行,A 算出的总和也会不同。 当依赖可串行化事务来防止异常时,重要的是:从永久用户表读取的任何数据,在读取它的事务成功提交之前, - 都不应视为有效。即使对于只读事务也是如此;唯一的例外是可推迟只读事务中读取的数据, + 都不应视为有效。即使对于只读事务也是如此;唯一的例外是可延迟只读事务中读取的数据, 它一经读出就可视为有效,因为这种事务会等到能够获取一个保证不存在此类问题的快照后才开始读取数据。 在所有其他情况下,应用不能依赖后来被中止事务中读到的结果;相反,应重试事务直到成功。 - 为了保证真正的可串行化,PostgreSQL 使用了谓词锁, + 为了保证真正的可串行性,PostgreSQL 使用了谓词锁, 也就是说,系统会保留一些锁,以便判断某个写操作如果先发生,是否会影响并发事务先前读取的结果。 在 PostgreSQL 中,这些锁不会造成任何阻塞,因此会参与形成死锁。 它们用于识别并标记并发可串行化事务之间的依赖关系,而这些依赖在某些组合下可能导致串行化异常。 @@ -550,7 +530,7 @@ ERROR: could not serialize access due to read/write dependencies among transact - 持续使用可串行化事务可以简化开发。任何一组成功提交的并发可串行化事务,都保证与把它们一次一个运行的效果相同;这意味着,如果你能够证明某个事务在单独运行时会做正确的事,那么即使不了解其他事务会做什么,也可以相信它在任何可串行化事务的混合执行中也会做正确的事,否则它就不会成功提交。重要的是,采用这种技术的环境应当有一套通用机制来处理串行化失败(其 SQLSTATE 值总是 40001),因为很难准确预测究竟哪些事务会对读/写依赖关系有贡献,并因此需要被回滚来防止串行化异常。监视读/写依赖关系会带来开销,被串行化失败中止的事务重新启动也会带来开销;但在把这些开销与显式锁以及 SELECT FOR UPDATESELECT FOR SHARE 所涉及的成本和阻塞进行权衡之后,可串行化事务在某些环境中仍然是性能最佳的选择。 + 统一采用可串行化事务可以简化开发。任何一组成功提交的并发可串行化事务,都保证与把它们一次一个运行的效果相同;这意味着,如果你能够证明某个事务在单独运行时会做正确的事,那么即使不了解其他事务会做什么,也可以相信它在任何可串行化事务的混合执行中也会做正确的事,否则它就不会成功提交。重要的是,采用这种技术的环境应当有一套通用机制来处理串行化失败(其 SQLSTATE 值总是 40001),因为很难准确预测究竟哪些事务会对读/写依赖关系有贡献,并因此需要被回滚来防止串行化异常。监视读/写依赖关系会带来开销,被串行化失败中止的事务重新启动也会带来开销;但在把这些开销与显式锁以及 SELECT FOR UPDATESELECT FOR SHARE 所涉及的成本和阻塞进行权衡之后,可串行化事务在某些环境中仍然是性能最佳的选择。 @@ -594,7 +574,7 @@ ERROR: could not serialize access due to read/write dependencies among transact - 当系统因谓词锁表内存不足而被迫把多个页级谓词锁合并为单个关系级谓词锁时,串行化失败的比例可能会上升。你可以通过增加 来避免这种情况。 + 当系统因谓词锁表内存不足而被迫把多个页级谓词锁合并为单个关系级谓词锁时,串行化失败的比例可能会上升。你可以通过增加 和/或 来避免这种情况。 @@ -618,7 +598,7 @@ ERROR: could not serialize access due to read/write dependencies among transact 显式锁定 - lock + @@ -722,7 +702,7 @@ ERROR: could not serialize access due to read/write dependencies among transact CREATE STATISTICSCOMMENT ONREINDEX CONCURRENTLY, 以及某些 ALTER INDEX - 和 ALTER TABLE 变体会获取这种锁 + 和 ALTER TABLE 变体获取这种锁 (有关详细信息,请参阅这些命令的文档)。 @@ -987,7 +967,7 @@ ERROR: could not serialize access due to read/write dependencies among transact - 行为与 FOR SHARE 类似,不过锁更弱:SELECT FOR UPDATE 会被阻塞,但 SELECT FOR NO KEY UPDATE 不会。键共享锁会阻塞其他事务执行会修改键值的 DELETEUPDATE,但不会阻塞其他 UPDATE,也不会阻止 SELECT FOR NO KEY UPDATESELECT FOR SHARESELECT FOR KEY SHARE。 + 行为与 FOR SHARE 类似,不过锁更弱:SELECT FOR UPDATE 会被阻塞,但 SELECT FOR NO KEY UPDATE 不会。键共享锁会阻塞其他事务执行 DELETE 或任何会修改键值的 UPDATE,但不会阻塞其他 UPDATE,也不会阻止 SELECT FOR NO KEY UPDATESELECT FOR SHARESELECT FOR KEY SHARE @@ -1065,7 +1045,7 @@ ERROR: could not serialize access due to read/write dependencies among transact 死锁 - deadlock + 死锁 @@ -1108,12 +1088,12 @@ UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 22222; 咨询锁 - advisory lock + 咨询锁 - lock - advisory + + 咨询 @@ -1145,12 +1125,12 @@ UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 22222; 在某些使用咨询锁的方法中,特别是涉及显式排序和 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(id) FROM foo WHERE id = 12345; -- 可以 +SELECT pg_advisory_lock(id) FROM foo WHERE id > 12345 LIMIT 100; -- 危险! SELECT pg_advisory_lock(q.id) FROM ( SELECT id FROM foo WHERE id > 12345 LIMIT 100 -) q; -- ok +) q; -- 可以 在上面的查询中,第二种形式是危险的,因为不能保证在执行加锁函数之前先应用 LIMIT。 这可能导致获取了一些应用并未预期的锁,因此应用也不会去释放它们(直到会话结束)。 @@ -1168,12 +1148,12 @@ SELECT pg_advisory_lock(q.id) FROM 应用级别的数据一致性检查 - 在读已提交事务下,想要通过业务规则强制数据一致性非常困难,因为数据视图会随每条语句而变化, + 用读已提交事务强制执行有关数据完整性的业务规则非常困难,因为数据视图会随每条语句而变化, 而且一旦发生写冲突,即使是单条语句也未必局限于该语句自己的快照。 - 虽然可重复读事务在整个执行期间都具有稳定的数据视图,但在使用 MVCC 快照进行数据一致性检查时,还存在一个微妙问题,即所谓的读/写冲突。如果一个事务写入数据,而并发事务试图读取相同的数据(无论是在写入之前还是之后),它都看不到另一个事务的工作。于是,读取者看起来就像是先执行的一方,而不管究竟是谁先启动,也不管谁先提交。如果事情只停留在这一步,就没有问题;但如果读取者还写入了数据,而这些数据又被另一个并发事务读取,那么现在就会有一个事务看起来像是在前面提到的任一事务之前执行。如果看起来最后执行的事务实际上最先提交,就很容易在事务执行顺序图中形成一个环。一旦出现这样的环,不借助额外机制,一致性检查就无法正确工作。 + 虽然可重复读事务在整个执行期间都具有稳定的数据视图,但在使用 MVCC 快照进行数据一致性检查时,还存在一个微妙问题,即所谓的读/写冲突。如果一个事务写入数据,而并发事务试图读取相同的数据(无论是在写入之前还是之后),它都看不到另一个事务的工作。于是,读取者看起来就像是先执行的一方,而不管究竟是谁先启动,也不管谁先提交。如果事情只停留在这一步,就没有问题;但如果读取者还写入了数据,而这些数据又被另一个并发事务读取,那么现在就会有一个事务看起来像是在前面提到的任一事务之前执行。如果看起来最后执行的事务实际上最先提交,就很容易在事务执行顺序图中形成一个环。一旦出现这样的环,不借助额外机制,完整性检查就无法正确工作。 @@ -1190,7 +1170,7 @@ SELECT pg_advisory_lock(q.id) FROM - 使用这种技术时,如果应用软件通过某个框架运行,并由该框架自动重试因串行化错误而回滚的事务,就可以避免给应用程序员带来不必要的负担。把 default_transaction_isolation 设置为 serializable 可能是个好主意。通过在触发器中检查事务隔离级别来采取某些措施,以确保不会因为疏忽或为了绕过完整性检查而使用其他事务隔离级别,也是明智的。 + 使用这种技术时,如果应用软件通过某个框架运行,并由该框架自动重试因串行化失败而回滚的事务,就可以避免给应用程序员带来不必要的负担。把 default_transaction_isolation 设置为 serializable 可能是个好主意。通过在触发器中检查事务隔离级别来采取某些措施,以确保不会因为疏忽或为了绕过完整性检查而使用其他事务隔离级别,也是明智的。 @@ -1207,7 +1187,7 @@ SELECT pg_advisory_lock(q.id) FROM - 使用显式锁定强制一致性 + 使用显式阻塞锁强制一致性 当存在非可串行化写入时,要确保某一行当前仍然有效,并保护它不受并发更新影响, @@ -1230,7 +1210,7 @@ SELECT pg_advisory_lock(q.id) FROM 在非可串行化的 MVCC 环境下,全局有效性检查需要额外考虑。 - 例如,一个银行应用可能希望检查一个表中的所有收入总和等于另一个表中的所有支出总和, + 例如,一个银行应用可能希望检查一个表中的贷方金额总和等于另一个表中的借方金额总和, 而这两个表都在被活跃更新。在读已提交模式下,比较两个连续的 SELECT sum(...) 命令的结果并不可靠,因为第二个查询很可能会包含第一个查询没有统计到的事务提交结果。 在单个可重复读事务中完成这两次求和,只能准确反映在该可重复读事务开始之前已提交事务的效果 @@ -1258,10 +1238,10 @@ SELECT pg_advisory_lock(q.id) FROM 串行化失败处理 - serialization failure + 串行化失败 - retryable error + 可重试错误 @@ -1298,7 +1278,7 @@ SELECT pg_advisory_lock(q.id) FROM 重试事务并不保证重试后的事务一定能够完成;可能需要多次重试。 在争用非常激烈的情况下,完成一个事务可能需要尝试很多次。 - 如果涉及相互冲突的已准备事务,那么在已准备事务提交或回滚之前,可能根本无法取得进展。 + 如果涉及相互冲突的预备事务,那么在预备事务提交或回滚之前,可能根本无法取得进展。 @@ -1331,8 +1311,8 @@ SELECT pg_advisory_lock(q.id) FROM 锁定和索引 - index - locks + 索引 + @@ -1345,7 +1325,7 @@ SELECT pg_advisory_lock(q.id) FROM - 读写访问使用短期的页级共享/排他锁。每个索引行在被取出或插入之后,锁都会立即释放。这些索引类型在不存在死锁条件的前提下提供了最高的并发性。 + 读写访问使用短期的页级共享/排他锁。每个索引行在被取出或插入之后,锁都会立即释放。这些索引类型提供最高的并发性,并且不会产生死锁。 @@ -1367,7 +1347,7 @@ SELECT pg_advisory_lock(q.id) FROM - 读写访问使用短期的页级共享/排他锁。每个索引行在被取出或插入之后,锁都会立即释放。但要注意,插入一个 GIN 索引值通常会导致每行产生多个索引键插入,因此 GIN 可能为了插入单个值而做大量工作。 + 读写访问使用短期的页级共享/排他锁。每个索引行在被取出或插入之后,锁都会立即释放。但要注意,插入一个使用 GIN 索引的值通常会导致每行产生多个索引键插入,因此 GIN 可能为了插入单个值而做大量工作。 diff --git a/zh/19/oauth-validators.sgml b/zh/19/oauth-validators.sgml index 5d21fa44..09fecf9d 100644 --- a/zh/19/oauth-validators.sgml +++ b/zh/19/oauth-validators.sgml @@ -92,7 +92,7 @@ 也可以通过部署架构的带外知识在没有显式作用域的情况下完成客户端授权, - 但这样会把用户排除在环路之外, + 但这样会让用户无法参与授权过程, 用户将无法发现部署错误,而此类错误也可能被静默利用。 如果不提示用户授予额外作用域, 则对数据库的访问必须被严格限制为仅允许受信任客户端 @@ -192,7 +192,7 @@ 模块必须保持可被信号中断, 这样服务器才能正确处理认证超时和来自 pg_ctl 的停机信号。 - 例如,套接字上的阻塞调用通常应替换为可无竞争地同时处理 + 例如,套接字上的阻塞调用通常应替换为能够在没有竞争条件的情况下同时处理 套接字事件与中断的代码(见 WaitLatchOrSocket()WaitEventSetWait() 等), 且长时间运行的循环应定期调用 @@ -216,16 +216,16 @@ 文档 - 验证器实现应记录针对每个终端用户向服务器报告的认证 ID 的内容和格式, + 验证器实现应在文档中说明针对每个终端用户向服务器报告的认证 ID 的内容和格式, 因为 DBA 可能需要据此构造 pg_ident 映射。 (例如,它是邮箱地址?组织 ID 号?还是 UUID?) - 还应记录该模块在 + 还应在文档中说明该模块在 delegate_ident_mapping=1 模式下是否可安全使用, 以及为此需要哪些额外配置。 如果实现提供了自定义 HBA 选项, - 这些选项的名称和语法也应当记录。 + 也应在文档中说明这些选项的名称和语法。 @@ -242,7 +242,7 @@ 不过,OAuth 本身就是授权框架, 令牌也可能携带用户权限信息。 例如,令牌可能包含用户所属组织组的信息, - 或列出用户可承担的角色, + 或列出用户可使用的角色, 将这些信息复制到每台服务器的本地用户名映射中可能并不理想。 @@ -377,7 +377,7 @@ typedef struct ValidatorModuleResult 在验证错误或内部错误这两种失败情况下,模块都可以在 result->error_detail 中保存一段供用户阅读的失败原因。 这会作为认证失败的 DETAIL 条目打印到服务器日志中(不会发送给客户端)。 - error_detail 指向的内存可以是 palloc + error_detail 指向的内存可以是 palloc 分配的,也可以是静态存储期内存。成功时会忽略 error_detail @@ -421,8 +421,8 @@ typedef void (*ValidatorShutdownCB) (ValidatorModuleState *state); PostgreSQL 19 开始,验证器实现可以定义供 pg_hba.conf 内使用的自定义选项。这些选项会 - 以 - validator.option 的形式提供给用户。 + 以 validator.option 的形式 + 提供给用户。 注册和获取自定义选项的 API 如下所述。 @@ -505,7 +505,7 @@ const char *GetOAuthHBAOption(const ValidatorModuleState *state, - 服务器在重新载入配置时无法检查选项名和值。pg_hba.conf 中任何未注册的选项都会导致连接失败。因此,每个模块都有责任按需记录并验证选项值的语法。 + 服务器在重新载入配置时无法检查选项名和值。pg_hba.conf 中任何未注册的选项都会导致连接失败。因此,每个模块都有责任按需在文档中说明并验证选项值的语法。 如果模块在 validate_cb 期间发现无效的选项值,建议通过将 @@ -586,10 +586,10 @@ validate_token(const ValidatorModuleState *state, 当同时使用多个验证器时,它们各自注册的选项列表彼此独立: -在 postgresql.conf中: +在 postgresql.conf 中: oauth_validator_libraries = 'example_org, my_validator' -在 pg_hba.conf中: +在 pg_hba.conf 中: # TYPE DATABASE USER ADDRESS METHOD hostssl postgres admin 0.0.0.0/0 oauth issuer=https://admin.example.com \ scope="pg-admin openid email" \ diff --git a/zh/19/oid2name.sgml b/zh/19/oid2name.sgml index 24e82560..eb8ff4a3 100644 --- a/zh/19/oid2name.sgml +++ b/zh/19/oid2name.sgml @@ -8,7 +8,7 @@ oid2name 1 - Application + 应用程序 diff --git a/zh/19/pageinspect.sgml b/zh/19/pageinspect.sgml index 2574679e..1e9e9419 100644 --- a/zh/19/pageinspect.sgml +++ b/zh/19/pageinspect.sgml @@ -370,20 +370,20 @@ test=# SELECT itemoffset, ctid, itemlen, nulls, vars, data, dead, htid, tids[0:2 13 | (16,8292) | 616 | f | f | 2f 00 00 00 00 00 00 00 | f | (4,17) | {"(4,17)","(4,21)"} (13 rows) - 这是一个 B-树叶页。所有指向表的元组恰好都是 posting list 元组(它们总共存储了 100 个 6 字节的 TID)。此外,在itemoffset 编号 1 处还有一个high key元组。这个示例中,ctid用于存储每个元组的编码信息,不过叶页元组通常会直接在ctid字段中存储一个堆 TID。tids是作为 posting list 存储的 TID 列表。 + 这是一个 B-树叶页。所有指向表的元组恰好都是倒排列表元组(每个都存储了 100 个 6 字节的 TID)。此外,在itemoffset 编号 1 处还有一个高键元组。这个示例中,ctid用于存储每个元组的编码信息,不过叶页元组通常会直接在ctid字段中存储一个堆 TID。tids是作为倒排列表存储的 TID 列表。 在内部页(此处未显示)中,ctid的块号部分是一个downlink(下行链接),也就是该索引中另一页的块号。ctid的偏移部分(第二个数字)存储着关于该元组的编码信息,例如实际存在的列数(后缀截断可能移除了不需要的后缀列)。被截断的列被视为具有minus infinity值。 - htid显示该元组的堆 TID,而不考虑底层元组表示形式。这个值可能与ctid相同,也可能是从 posting list 元组以及内部页元组所使用的替代表示中解码出来的。内部页中的元组通常会把实现层面的堆 TID 列截断掉,这会表现为htid值为 NULL。 + htid显示该元组的堆 TID,而不考虑底层元组表示形式。这个值可能与ctid相同,也可能是从倒排列表元组以及内部页元组所使用的替代表示中解码出来的。内部页中的元组通常会把实现层面的堆 TID 列截断掉,这会表现为htid值为 NULL。 - 请注意,任何非最右页(即btpo_next字段值非零的页面)的第一项都是该页的high key,这意味着它的data充当该页上所有项的上界,而它的ctid字段并不指向另一个块。另外,在内部页上,第一个真正的数据项(第一个不是high key的项)一定会把所有列都截断掉,因此其data字段中没有实际值。不过,这样的项在其ctid字段中确实有一个有效的下行链接。 + 请注意,任何非最右页(即btpo_next字段值非零的页面)的第一项都是该页的高键,这意味着它的data充当该页上所有项的上界,而它的ctid字段并不指向另一个块。另外,在内部页上,第一个真正的数据项(第一个不是高键的项)一定会把所有列都截断掉,因此其data字段中没有实际值。不过,这样的项在其ctid字段中确实有一个有效的下行链接。 - 关于 B-树索引结构的更多细节,参见。关于去重和 posting list 的更多细节,参见。关于去重和倒排列表的更多细节,参见 diff --git a/zh/19/parallel.sgml b/zh/19/parallel.sgml index d6f7fc7c..71ca3952 100644 --- a/zh/19/parallel.sgml +++ b/zh/19/parallel.sgml @@ -227,7 +227,7 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%'; - Parallel Append + 并行追加 每当 PostgreSQL 需要将来自多个源的行合并成一个结果集时,它就会使用 AppendMergeAppend 计划节点。这种情况常见于实现 UNION ALL 或扫描分区表时。这样的节点和其他任何计划中的情形一样,也可以用于并行计划。不过,在并行计划中,规划器也可能改用 Parallel Append 节点。 @@ -305,7 +305,7 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%'; - 如果函数或聚合会写数据库、修改事务状态(而不是通过子事务进行错误恢复)、访问序列,或者对设置做持久更改,那么它们必须标记为 PARALLEL UNSAFE。类似地,如果函数访问临时表、客户端连接状态、游标、预备语句,或者系统无法在工作进程之间同步的各种后端本地状态,那么它必须标记为 PARALLEL RESTRICTED。例如,setseedrandom 就因为最后一个原因而属于并行受限。 + 如果函数或聚合会写数据库、修改事务状态(使用子事务进行错误恢复的情况除外)、访问序列,或者对设置做持久更改,那么它们必须标记为 PARALLEL UNSAFE。类似地,如果函数访问临时表、客户端连接状态、游标、预备语句,或者系统无法在工作进程之间同步的各种后端本地状态,那么它必须标记为 PARALLEL RESTRICTED。例如,setseedrandom 就因为最后一个原因而属于并行受限。 diff --git a/zh/19/pgcrypto.sgml b/zh/19/pgcrypto.sgml index 146f27f9..98a12e76 100644 --- a/zh/19/pgcrypto.sgml +++ b/zh/19/pgcrypto.sgml @@ -254,17 +254,17 @@ gen_salt(type text [, iter_count integer ]) returns text - type参数指定哈希算法。 + type参数指定 hash 算法。 接受的类型有:desxdesmd5bfsha256cryptsha512crypt。 最后两种即 sha256cryptsha512crypt, - 是现代的、基于 SHA-2 的密码哈希。 + 是现代的、基于 SHA-2 的密码 hash。 iter_count参数允许用户为支持该参数的算法指定迭代次数。 - 次数越高,密码哈希所需时间越长,从而破解它所需时间也越长。 - 不过,如果次数过高,计算一个哈希可能需要数年时间 — 这显然不切实际。 + 次数越高,对密码进行 hash 所需的时间越长,从而破解它所需时间也越长。 + 不过,如果次数过高,计算一个 hash 可能需要数年时间 — 这显然不切实际。 若省略iter_count参数,则使用默认迭代次数。 允许的iter_count值取决于算法,如所示。 @@ -308,12 +308,12 @@ gen_salt(type text [, iter_count integer ]) returns text - 为了选择合适的迭代次数,可以考虑原始 DES crypt 在当时硬件上的设计速度是每秒 4 次哈希。 - 低于每秒 4 次哈希可能会影响可用性,而高于每秒 100 次哈希则很可能过快。 + 为了选择合适的迭代次数,可以考虑原始 DES crypt 在当时硬件上的设计速度是每秒 4 次 hash。 + 低于每秒 4 次 hash 可能会影响可用性,而高于每秒 100 次 hash 则很可能过快。 - 概述了不同哈希算法之间的相对速度差异。 + 概述了不同 hash 算法之间的相对速度差异。 该表展示了在 8 字符密码上尝试所有字符组合所需的时间,假定密码只包含小写字母, 或者包含大小写字母和数字。在crypt-bf条目中, 斜杠后的数字是gen_saltiter_count参数值。 @@ -322,17 +322,17 @@ gen_salt(type text [, iter_count integer ]) returns text sha256cryptsha512crypt而言, 默认的iter_count5000 对现代硬件来说被认为过低, - 但可以调高以生成更强的密码哈希。除此之外, + 但可以调高以生成更强的密码 hash。除此之外, sha256cryptsha512crypt都被认为是安全的。
- 哈希算法速度 + Hash 算法速度 算法 - 每秒哈希次数 + 每秒 hash 次数 针对[a-z] 针对[A-Za-z0-9] 相对于md5 hash的耗时倍数 diff --git a/zh/19/pgplanadvice.sgml b/zh/19/pgplanadvice.sgml index a4a99cc2..09656ace 100644 --- a/zh/19/pgplanadvice.sgml +++ b/zh/19/pgplanadvice.sgml @@ -1,7 +1,7 @@ - pg_plan_advice —— 帮助规划器获得正确的计划 + pg_plan_advice — 帮助规划器获得正确的计划 pg_plan_advice diff --git a/zh/19/pgstashadvice.sgml b/zh/19/pgstashadvice.sgml index 08d4f7e1..86326e01 100644 --- a/zh/19/pgstashadvice.sgml +++ b/zh/19/pgstashadvice.sgml @@ -1,7 +1,7 @@ - pg_stash_advice —— 存储并自动应用计划建议 + pg_stash_advice — 存储并自动应用计划建议 pg_stash_advice diff --git a/zh/19/plhandler.sgml b/zh/19/plhandler.sgml index 38562e46..4048d572 100644 --- a/zh/19/plhandler.sgml +++ b/zh/19/plhandler.sgml @@ -17,11 +17,11 @@ - 调用处理器与其他函数一样被调用:它会接收一个指向 FunctionCallInfoBaseData struct 的指针,其中包含参数值以及被调用函数的相关信息;同时它还应返回一个 Datum 结果(如果希望返回 SQL 空值结果,还可以设置 isnull 字段,也就是 FunctionCallInfoBaseData 结构体中的该字段)。调用处理器与普通被调函数之间的区别在于,flinfo->fn_oid 字段在 FunctionCallInfoBaseData 结构体中保存的是实际要调用函数的 OID,而不是调用处理器本身的 OID。调用处理器必须使用这个字段来判定要执行哪个函数。另外,传入的参数列表是按照目标函数而不是调用处理器的声明来设置的。 + 调用处理器与其他函数一样被调用:它会接收一个指向 FunctionCallInfoBaseData struct 的指针,其中包含参数值以及被调用函数的相关信息;同时它还应返回一个 Datum 结果(如果希望返回 SQL 空值结果,还需要设置 isnull 字段,也就是 FunctionCallInfoBaseData 结构体中的该字段)。调用处理器与普通被调函数之间的区别在于,flinfo->fn_oid 字段在 FunctionCallInfoBaseData 结构体中保存的是实际要调用函数的 OID,而不是调用处理器本身的 OID。调用处理器必须使用这个字段来判定要执行哪个函数。另外,传入的参数列表是按照目标函数而不是调用处理器的声明来设置的。 - 调用处理器必须从系统目录 pg_proc 中取出该函数的条目,并分析被调用函数的参数类型和返回类型。该函数的 AS 子句可在其 CREATE FUNCTION 命令对应的 prosrc 列里找到,也就是 pg_proc 行中的该列。这里通常是一段过程语言源文本,但理论上也可以是其他内容,例如某个文件的路径名,或者任何能详细告诉调用处理器该做什么的信息。 + 调用处理器必须从系统目录 pg_proc 中取出该函数的条目,并分析被调用函数的参数类型和返回类型。该函数的 CREATE FUNCTION 命令中的 AS 子句内容,保存在 pg_proc 对应行的 prosrc 列中。这里通常是一段过程语言源文本,但理论上也可以是其他内容,例如某个文件的路径名,或者任何能详细告诉调用处理器该做什么的信息。 @@ -46,7 +46,7 @@ 验证器函数通常应遵循 参数:如果它被关闭,就应跳过任何开销高昂或依赖上下文的检查。如果该语言允许在编译时执行代码,验证器还必须抑制会诱发此类执行的检查。特别是,pg_dump 会关闭这个参数,这样它就可以装载过程语言函数,而不必担心函数体对其他数据库对象的副作用或依赖关系。(正因为有这一要求,调用处理器不应假设验证器已经完整检查了函数。提供验证器的目的,并不是让调用处理器省略检查,而是在 CREATE FUNCTION 命令中存在明显错误时立即通知用户。)虽然究竟检查哪些内容主要由验证器函数自行决定,但要注意,核心 CREATE FUNCTION 代码只会执行附加到函数上的 SET 子句,前提是 check_function_bodies 打开。因此,当 check_function_bodies 关闭时,那些结果可能受 GUC 参数影响的检查肯定都应跳过,以避免在恢复转储时出现虚假的失败。 + linkend="guc-check-function-bodies"/> 参数:如果它被关闭,就应跳过任何开销高昂或依赖上下文的检查。如果该语言允许在编译时执行代码,验证器还必须抑制会诱发此类执行的检查。特别是,pg_dump 会关闭这个参数,这样它就可以装载过程语言函数,而不必担心副作用或函数体对其他数据库对象的依赖关系。(正因为有这一要求,调用处理器不应假设验证器已经完整检查了函数。提供验证器的目的,并不是让调用处理器省略检查,而是在 CREATE FUNCTION 命令中存在明显错误时立即通知用户。)虽然究竟检查哪些内容主要由验证器函数自行决定,但要注意,只有在 check_function_bodies 打开时,核心 CREATE FUNCTION 代码才会执行函数附带的 SET 子句。因此,当 check_function_bodies 关闭时,那些结果可能受 GUC 参数影响的检查肯定都应跳过,以避免在恢复转储时出现虚假的失败。 diff --git a/zh/19/plperl.sgml b/zh/19/plperl.sgml index 48f1908f..f8d4b4ef 100644 --- a/zh/19/plperl.sgml +++ b/zh/19/plperl.sgml @@ -13,7 +13,7 @@ - PL/Perl 是一种可载入的过程语言,它允许使用 + PL/Perl 是一种可加载的过程语言,它允许使用 Perl 编程语言编写 PostgreSQL 函数和过程。 @@ -32,8 +32,7 @@ - 如果把该语言安装到 template1 中,之后创建的所有 - 数据库都会自动安装该语言。 + 如果把某种语言安装到template1中,之后创建的所有数据库都会自动安装该语言。 @@ -57,9 +56,9 @@ CREATE FUNCTION funcname (argument-types) RETURNS return-type --- function attributes can go here +-- 函数属性可以写在这里 AS $$ - # PL/Perl function body goes here + # PL/Perl 函数体写在这里 $$ LANGUAGE plperl; @@ -78,7 +77,7 @@ $$ LANGUAGE plperl; DO $$ - # PL/Perl code + # PL/Perl 代码 $$ LANGUAGE plperl; @@ -136,15 +135,14 @@ $$ LANGUAGE plperl; 如果一个 SQL 空值空值in PL/Perl被传给一个函数,在 - Perl 中该参数值将呈现为undefined。上述函数定义对于 - 空输入的行为并不理想(实际上,它会把它们当作零)。我们可以在函数 + sortas="PL/Perl">在 PL/Perl 中被传给一个函数,在 + Perl 中该参数值将呈现为未定义。上述函数定义对于 + 空值输入的行为并不理想(实际上,它会把它们当作零)。我们可以在函数 定义中添加 STRICT,让 PostgreSQL 采取更合理的做法:如果传入空值, - 函数将根本不会被调用,而是自动返回空结果。另一种方式是在函数体中 + 函数将根本不会被调用,而是自动返回空值结果。另一种方式是在函数体中 检查未定义输入。例如,假设我们希望在 - perl_max 的两个参数中一个为空、另一个非空时, - 返回非空参数而不是空值: + perl_max 的两个参数中一个为空值、另一个非空值时,返回非空值参数而不是空值: CREATE FUNCTION perl_max (integer, integer) RETURNS integer AS $$ @@ -186,7 +184,7 @@ $$ LANGUAGE plperl; bool_plperl 扩展提供了合适的转换。要使用它, 请先安装该扩展: -CREATE EXTENSION bool_plperl; -- or bool_plperlu for PL/PerlU +CREATE EXTENSION bool_plperl; -- 对于 PL/PerlU,则使用 bool_plperlu 然后对接收或返回 bool 的 PL/Perl 函数使用 TRANSFORM 函数属性,例如: @@ -199,7 +197,7 @@ AS $$ $$ LANGUAGE plperl; 应用该转换后,Perl 会将 bool 参数视为 - 1 或空值,从而能正确表示真或假。如果函数结果类型为 + 1 或空字符串,从而能正确表示真或假。如果函数结果类型为 bool,则其真或假取决于 Perl 是否会将返回值求值为真。 对函数内部执行的 SPI 查询,其布尔查询参数和结果也会进行类似的转换 ()。 @@ -232,12 +230,12 @@ CREATE OR REPLACE FUNCTION concat_array_elements(text[]) RETURNS TEXT AS $$ my $result = ""; return undef if (!defined $arg); - # as an array reference + # 作为数组引用 for (@$arg) { $result .= $_; } - # also works as a string + # 也可以作为字符串使用 $result .= $arg; return $result; @@ -248,7 +246,8 @@ SELECT concat_array_elements(ARRAY['PL','/','Perl']); - 多维数组会以所有 Perl 程序员都熟悉的方式,表示为对低维数组引用的引用。 + 多维数组按 Perl 程序员熟悉的方式表示为指向较低维数组的引用, + 而这些数组的元素又是引用。 @@ -357,11 +356,11 @@ SELECT * FROM perl_set(); 如果希望在代码中使用 strict 编译指示,可以有几种 选择。对于临时的全局用法,可以 SET - plperl.use_strict 为 true。这会影响后续编译的 + plperl.use_strict 为真。这会影响后续编译的 PL/Perl 函数,但不会影响当前会话中已经编译的 函数。对于永久的全局用法,可以在 postgresql.conf 文件中将 - plperl.use_strict 设为 true。 + plperl.use_strict 设为真。 @@ -417,7 +416,7 @@ use strict; spi_exec_query(query [, limit]) spi_exec_query - in PL/Perl + 在 PL/Perl 中 @@ -503,7 +502,7 @@ SELECT * FROM test_munge(); spi_query(command) spi_query - in PL/Perl + 在 PL/Perl 中 @@ -511,7 +510,7 @@ SELECT * FROM test_munge(); spi_fetchrow(cursor) spi_fetchrow - in PL/Perl + 在 PL/Perl 中 @@ -519,7 +518,7 @@ SELECT * FROM test_munge(); spi_cursor_close(cursor) spi_cursor_close - in PL/Perl + 在 PL/Perl 中 @@ -539,7 +538,7 @@ CREATE OR REPLACE FUNCTION lotsa_md5 (INTEGER) RETURNS SETOF foo_type AS $$ my $file = '/usr/share/dict/words'; my $t = localtime; elog(NOTICE, "opening file $file at $t" ); - open my $fh, '<', $file # ooh, it's a file access! + open my $fh, '<', $file # 注意,这里访问了文件! or elog(ERROR, "cannot open $file for reading: $!"); my @words = <$fh>; close $fh; @@ -579,7 +578,7 @@ SELECT * FROM lotsa_md5(500); spi_prepare(command, argument types) spi_prepare - in PL/Perl + 在 PL/Perl 中 @@ -587,7 +586,7 @@ SELECT * FROM lotsa_md5(500); spi_query_prepared(plan, arguments) spi_query_prepared - in PL/Perl + 在 PL/Perl 中 @@ -595,7 +594,7 @@ SELECT * FROM lotsa_md5(500); spi_exec_prepared(plan [, attributes], arguments) spi_exec_prepared - in PL/Perl + 在 PL/Perl 中 @@ -603,7 +602,7 @@ SELECT * FROM lotsa_md5(500); spi_freeplan(plan) spi_freeplan - in PL/Perl + 在 PL/Perl 中 @@ -612,7 +611,7 @@ SELECT * FROM lotsa_md5(500); spi_preparespi_query_preparedspi_exec_preparedspi_freeplan - 提供相同的功能,但用于预处理查询。spi_prepare + 提供相同的功能,但用于预备查询。spi_prepare 接受一个带编号参数占位符($1、$2 等)的查询字符串,以及参数类型的 字符串列表: @@ -631,7 +630,7 @@ $plan = spi_prepare('SELECT * FROM test WHERE id > $1 AND name = $2', - 预处理查询的优点在于,一个准备好的计划可以用于多次查询执行。当计划 + 预备查询的优点在于,一个准备好的计划可以用于多次查询执行。当计划 不再需要时,可以用 spi_freeplan 将其释放: CREATE OR REPLACE FUNCTION init() RETURNS VOID AS $$ @@ -708,7 +707,7 @@ SELECT release_hosts_query(); spi_commit() spi_commit - in PL/Perl + 在 PL/Perl 中 @@ -716,7 +715,7 @@ SELECT release_hosts_query(); spi_rollback() spi_rollback - in PL/Perl + 在 PL/Perl 中 @@ -756,7 +755,7 @@ CALL transaction_test1(); - PL/Perl 中的工具函数 + PL/Perl 中的辅助函数 @@ -765,7 +764,7 @@ CALL transaction_test1(); elog(level, msg) elog - in PL/Perl + 在 PL/Perl 中 @@ -791,7 +790,7 @@ CALL transaction_test1(); quote_literal(string) quote_literal - in PL/Perl + 在 PL/Perl 中 @@ -812,7 +811,7 @@ CALL transaction_test1(); quote_nullable(string) quote_nullable - in PL/Perl + 在 PL/Perl 中 @@ -831,7 +830,7 @@ CALL transaction_test1(); quote_ident(string) quote_ident - in PL/Perl + 在 PL/Perl 中 @@ -850,7 +849,7 @@ CALL transaction_test1(); decode_bytea(string) decode_bytea - in PL/Perl + 在 PL/Perl 中 @@ -868,7 +867,7 @@ CALL transaction_test1(); encode_bytea(string) encode_bytea - in PL/Perl + 在 PL/Perl 中 @@ -885,7 +884,7 @@ CALL transaction_test1(); encode_array_literal(array) encode_array_literal - in PL/Perl + 在 PL/Perl 中 @@ -908,7 +907,7 @@ CALL transaction_test1(); encode_typed_literal(value, typename) encode_typed_literal - in PL/Perl + 在 PL/Perl 中 @@ -926,7 +925,7 @@ CALL transaction_test1(); encode_array_constructor(array) encode_array_constructor - in PL/Perl + 在 PL/Perl 中 @@ -947,7 +946,7 @@ CALL transaction_test1(); looks_like_number(string) looks_like_number - in PL/Perl + 在 PL/Perl 中 @@ -967,7 +966,7 @@ CALL transaction_test1(); is_array_ref(argument) is_array_ref - in PL/Perl + 在 PL/Perl 中 @@ -1025,9 +1024,9 @@ CREATE OR REPLACE FUNCTION myfuncs() RETURNS void AS $$ }; $$ LANGUAGE plperl; -SELECT myfuncs(); /* initializes the function */ +SELECT myfuncs(); /* 初始化函数 */ -/* Set up a function that uses the quote function */ +/* 创建一个使用加引号函数的函数 */ CREATE OR REPLACE FUNCTION use_quote(TEXT) RETURNS text AS $$ my $text_to_quote = shift; @@ -1042,11 +1041,9 @@ $$ LANGUAGE plperl; - 出于安全原因,PL/Perl 会为某个 SQL 角色调用的函数在该角色专用的独立 - Perl 解释器中执行。这可以防止一个用户意外或恶意地干扰另一个用户的 + 出于安全原因,PL/Perl 会在每个 SQL 角色各自独立的 Perl 解释器中执行该角色调用的函数。这可以防止一个用户意外或恶意地干扰另一个用户的 PL/Perl 函数行为。每个这样的解释器都有自己的 - %_SHARED 变量值和其他全局状态。因此,只有在两个 - PL/Perl 函数都由同一 SQL 角色执行时,它们才会共享 + %_SHARED 变量值和其他全局状态。因此,当且仅当两个 PL/Perl 函数都由同一 SQL 角色执行时,它们才会共享 %_SHARED 的值。在某些应用中,一个会话可能会在多个 SQL 角色下执行代码(通过 SECURITY DEFINER 函数、 使用 SET ROLE 等),这时可能需要显式采取措施, @@ -1059,29 +1056,29 @@ $$ LANGUAGE plperl; - 可信与不可信的 PL/Perl + 受信任与不受信任的 PL/Perl - trusted + 受信任的 PL/Perl 通常,PL/Perl 会被安装为一种名为 plperl 的 - 可信编程语言。在这种设置下,为了保持安全性,某些 Perl + 受信任的编程语言。在这种设置下,为了保持安全性,某些 Perl 操作会被禁用。一般来说,受限制的是那些与环境交互的操作,包括文件句柄 操作、requireuse (针对外部模块)。它无法像 C 函数那样访问数据库服务器进程的内部, - 也无法以服务器进程的权限获取操作系统级访问。因此,可以允许任何无权限 + 也无法以服务器进程的权限获取操作系统级访问。因此,可以允许任何无特权 的数据库用户使用这种语言。 - 可信 PL/Perl 依赖 Perl 的 Opcode 模块来维持安全性。 + 受信任的 PL/Perl 依赖 Perl 的 Opcode 模块来维持安全性。 Perl 的 文档 - 指出,该模块对于可信 PL/Perl 这一使用场景并不有效。若你的安全需求 + 指出,该模块对于受信任的 PL/Perl 这一使用场景并不有效。若你的安全需求 不能接受该警告中的不确定性,请考虑执行 REVOKE USAGE ON LANGUAGE plperl FROM PUBLIC @@ -1105,16 +1102,16 @@ $$ LANGUAGE plperl; 有时需要编写不受这些限制的 Perl 函数。例如,可能需要一个能发送邮件的 Perl 函数。为处理这类情况,也可以把 PL/Perl 安装成一种 - 不可信语言(通常称为 + 不受信任的语言(通常称为 PL/PerlUPL/PerlU)。 在这种情况下,完整的 Perl 语言都可用。安装该语言时,使用语言名 - plperlu 就会选择不可信的 PL/Perl 变体。 + plperlu 就会选择不受信任的 PL/Perl 变体。 PL/PerlU 函数的编写者必须注意,函数不能被 用于任何非预期用途,因为它能够执行以数据库管理员身份登录的用户所能 - 做的任何事情。请注意,数据库系统只允许数据库超级用户用不可信语言创建 + 做的任何事情。请注意,数据库系统只允许数据库超级用户用不受信任的语言创建 函数。 @@ -1249,7 +1246,7 @@ $$ LANGUAGE plperl; $_TD->{relname} - 触发该触发器的表名。该字段已废弃,并且可能会在未来版本中移除。 + 触发该触发器的表名。该字段已弃用,并且可能会在未来版本中移除。 请改用 $_TD->{table_name}。 @@ -1328,12 +1325,12 @@ CREATE TABLE test ( CREATE OR REPLACE FUNCTION valid_id() RETURNS trigger AS $$ if (($_TD->{new}{i} >= 100) || ($_TD->{new}{i} <= 0)) { - return "SKIP"; # skip INSERT/UPDATE command + return "SKIP"; # 跳过 INSERT/UPDATE 命令 } elsif ($_TD->{new}{v} ne "immortal") { $_TD->{new}{v} .= "(modified by trigger)"; - return "MODIFY"; # modify row and execute INSERT/UPDATE command + return "MODIFY"; # 修改行并执行 INSERT/UPDATE 命令 } else { - return; # execute INSERT/UPDATE command + return; # 执行 INSERT/UPDATE 命令 } $$ LANGUAGE plperl; @@ -1490,7 +1487,7 @@ DO 'elog(WARNING, join ", ", sort keys %INC)' LANGUAGE plperl; 也会发生。这是在 plperl.on_init 完成的任何初始化 之后进行的。执行这段代码时 SPI 函数不可用。 plperl.on_plperl_init 中的 Perl 代码是在对解释器 - 进行锁定之后执行的,因此只能执行可信操作。 + 进行锁定之后执行的,因此只能执行受信任的操作。 diff --git a/zh/19/plpgsql.sgml b/zh/19/plpgsql.sgml index 59ffe06f..166a2616 100644 --- a/zh/19/plpgsql.sgml +++ b/zh/19/plpgsql.sgml @@ -144,7 +144,7 @@ CREATE FUNCTION somefunc(integer, text) RETURNS integer AS 'function body text' LANGUAGE plpgsql; - 就 CREATE FUNCTION 而言,函数体目前只是一个字符串字面量。编写函数体时,通常最好使用美元引用(见 ),而不是普通的单引号语法。如果不使用美元引用,函数体中的任何单引号或反斜线都必须通过双写进行转义。本章几乎所有示例的函数体都使用了美元引用。 + 就 CREATE FUNCTION 而言,函数体只是一个字符串字面量。编写函数体时,通常最好使用美元引用(见 ),而不是普通的单引号语法。如果不使用美元引用,函数体中的任何单引号或反斜线都必须通过双写进行转义。本章几乎所有示例的函数体都使用了美元引用。 @@ -340,7 +340,7 @@ $$ LANGUAGE plpgsql; - 当 PL/pgSQL 函数声明了输出参数时,输出参数也会像普通输入参数一样获得 $n 名称和可选别名。输出参数本质上是一个初始值为 NULL 的变量,应在函数执行期间给它赋值。该参数的最终值就是返回值。例如,sales-tax 的示例也可以这样写: + 当 PL/pgSQL 函数声明了输出参数时,输出参数也会像普通输入参数一样获得 $n 名称和可选别名。输出参数本质上是一个初始值为 NULL 的变量,应在函数执行期间给它赋值。该参数的最终值就是返回值。例如,销售税的示例也可以这样写: CREATE FUNCTION sales_tax(subtotal real, OUT tax real) AS $$ @@ -465,7 +465,7 @@ $$ LANGUAGE plpgsql; SELECT add_three_values(1, 2, 4.7); - 可以正常工作,并会自动把整数输入提升为 numeric。如果使用 anyelement,则必须手工把这三个输入转换成同一类型。 + 可以正常工作,并会自动把整数输入提升为 numeric。如果使用 anyelement,则必须手工把这三个输入转换成同一类型。 @@ -516,7 +516,7 @@ user_id users.user_id%TYPE; user_ids users.user_id%TYPE[]; user_ids users.user_id%TYPE ARRAY[4]; -- 等价于上面一行 - 与声明数组表列时一样,写多个方括号还是写具体数组维度都无关紧要:PostgreSQL 会把同一元素类型的所有数组都视为同一种类型,而不考虑维度数。(见 。) + 与声明数组表列时一样,写多对方括号还是写具体数组维度都无关紧要:PostgreSQL 会把同一元素类型的所有数组都视为同一种类型,而不考虑维度数。(见 。) @@ -594,12 +594,12 @@ SELECT merge_fields(t.*) FROM table1 t WHERE ... ; <application>PL/pgSQL</application>变量的排序规则 - collation - in PL/pgSQL + 排序规则 + 在 PL/pgSQL 中 - 当 PL/pgSQL 函数具有一个或多个可排序数据类型参数时,每次函数调用都会根据分配给实际参数的排序规则确定出一个排序规则,如 所述。如果该排序规则能成功确定出来(即参数之间的隐式排序规则没有冲突),那么所有可排序参数都会被视为隐式带有该排序规则。这会影响函数中那些受排序规则影响的操作。例如,考虑 + 当 PL/pgSQL 函数具有一个或多个支持排序规则的数据类型参数时,每次函数调用都会根据分配给实际参数的排序规则确定出一个排序规则,如 所述。如果该排序规则能成功确定出来(即参数之间的隐式排序规则没有冲突),那么所有支持排序规则的参数都会被视为隐式带有该排序规则。这会影响函数中那些受排序规则影响的操作。例如,考虑 CREATE FUNCTION less_than(a text, b text) RETURNS boolean AS $$ @@ -616,7 +616,7 @@ SELECT less_than(text_field_1, text_field_2 COLLATE "C") FROM table1; - 此外,确定出的排序规则也会被视为任何可排序数据类型局部变量的排序规则。因此,即使把这个函数写成下面这样,其行为也不会有任何不同: + 此外,确定出的排序规则也会被视为任何支持排序规则的数据类型局部变量的排序规则。因此,即使把这个函数写成下面这样,其行为也不会有任何不同: CREATE FUNCTION less_than(a text, b text) RETURNS boolean AS $$ @@ -631,11 +631,11 @@ $$ LANGUAGE plpgsql; - 如果函数没有可排序数据类型的参数,或者无法为它们确定共同排序规则,那么参数和局部变量将使用其数据类型的默认排序规则(通常是数据库默认排序规则,但对于域类型变量也可能不同)。 + 如果函数没有支持排序规则的数据类型的参数,或者无法为它们确定共同排序规则,那么参数和局部变量将使用其数据类型的默认排序规则(通常是数据库默认排序规则,但对于域类型变量也可能不同)。 - 通过在可排序数据类型局部变量的声明中加入 COLLATE 选项,可以为其指定不同的排序规则,例如 + 通过在支持排序规则的数据类型局部变量的声明中加入 COLLATE 选项,可以为其指定不同的排序规则,例如 DECLARE @@ -666,7 +666,7 @@ $$ LANGUAGE plpgsql; 表达式 - PL/pgSQL语句中使用的所有表达式都会由服务器的主SQL执行器处理。例如,当你写下这样一条PL/pgSQL语句时: + PL/pgSQL 语句中使用的所有表达式都会由服务器的主 SQL 执行器处理。例如,当写下这样一条 PL/pgSQL 语句时: IF expression THEN ... @@ -674,7 +674,7 @@ IF expression THEN ... SELECT expression - 来计算该表达式。如中详细讨论的那样,在构造该SELECT命令时,PL/pgSQL变量名的每一次出现都会被替换成查询参数。这使得该SELECT的查询计划只需准备一次,然后就能在后续以不同变量值求值时重用。因此,表达式第一次被使用时,实际发生的事情本质上相当于执行了一条PREPARE命令。例如,如果已经声明了两个整数变量xy,并写下 + 来计算该表达式。如 中详细讨论的那样,在构造该 SELECT 命令时,PL/pgSQL 变量名的每一次出现都会被替换成查询参数。这使得该 SELECT 的查询计划只需准备一次,然后就能在后续以不同变量值求值时重用。因此,表达式第一次被使用时,实际发生的事情本质上相当于执行了一条 PREPARE 命令。例如,如果已经声明了两个整数变量 xy,并写下 IF x < y THEN ... @@ -682,7 +682,7 @@ IF x < y THEN ... PREPARE statement_name(integer, integer) AS SELECT $1 < $2; - 然后,在每次执行IF语句时,这条预备语句都会以当前PL/pgSQL变量值作为参数值被EXECUTE。通常这些细节对PL/pgSQL用户并不重要,但在诊断问题时了解它们会很有帮助。更多信息见。 + 然后,在每次执行 IF 语句时,这条预备语句都会以当前 PL/pgSQL 变量值作为参数值由 EXECUTE 执行。通常这些细节对 PL/pgSQL 用户并不重要,但在诊断问题时了解它们会很有帮助。更多信息见 @@ -699,7 +699,7 @@ PREPARE statement_name(integer, integer) AS SELECT $1 基本语句 - 在这一节和接下来的小节中,我们会描述PL/pgSQL能明确理解的所有语句类型。任何不被识别为这些语句类型之一的被假定为是一个 SQL 命令,并且会被发送给主数据库引擎执行,具体如中所述。 + 在这一节和接下来的小节中,我们会描述 PL/pgSQL 能明确理解的所有语句类型。任何不被识别为这些语句类型之一的语句都被视为 SQL 命令,并会被发送给主数据库引擎执行,具体如 中所述。 @@ -715,8 +715,7 @@ PREPARE statement_name(integer, integer) AS SELECT $1 SELECT命令被发送到主数据库引擎的方式计算。 该表达式必须得到一个单一值(如果该变量是一个行或记录变量, 它可能是一个行值)。该目标变量可以是一个简单变量( - 可以选择用一个块名限定)、一个行或记录变量的域或是一个简单 - 变量或域的数组的元素或者数组的切片。 + 可以选择用一个块名限定)、行或记录目标的字段,或者数组目标的元素或切片。 等号(=)可以被用来代替 PL/SQL-兼容的 := @@ -758,7 +757,7 @@ INSERT INTO mytable VALUES (1,'one'), (2,'two'); 如果命令返回行(例如 SELECT,或者带 RETURNINGINSERT/UPDATE/DELETE/MERGE),有两种方式处理。 - 当命令最多返回一行,或者你只关心第一行的输出时,像往常一样编写命令,但要添加一个INTO子句来捕获输出,如中所述。为了处理所有的输出行,把命令写成FOR循环的数据源,如 中所述。 + 当命令最多返回一行,或者只关心第一行的输出时,可照常编写该命令,但要添加一个 INTO 子句来捕获输出,如 中所述。要处理所有输出行,可将该命令写成 FOR 循环的数据源,如 中所述。 @@ -766,29 +765,29 @@ INSERT INTO mytable VALUES (1,'one'), (2,'two'); - PL/pgSQL变量值可以自动插入到可优化的SQL命令中,这些命令包括SELECTINSERTUPDATEDELETEMERGE以及某些包含其中之一的实用程序命令,比如EXPLAINCREATE TABLE ... AS SELECT。在这些命令中,命令文本中出现的任何PL/pgSQL变量名都会被查询参数替换,然后变量的当前值会在运行时作为参数值提供。这与前面描述的表达式处理完全相同;详情请参见。 + PL/pgSQL 变量值可以自动插入可优化的 SQL 命令中,这些命令包括 SELECTINSERTUPDATEDELETEMERGE 以及某些包含其中之一的工具命令,比如 EXPLAINCREATE TABLE ... AS SELECT。在这些命令中,命令文本中出现的任何 PL/pgSQL 变量名都会被查询参数替换,然后变量的当前值会在运行时作为参数值提供。这与前面描述的表达式处理完全相同;详情请参见 - 当以这种方式执行一个可优化的 SQL 命令时,如中讨论的,PL/pgSQL会为该命令缓存并重用执行计划。 + 当以这种方式执行一个可优化的 SQL 命令时,如中讨论的,PL/pgSQL可能会为该命令缓存并重用执行计划。 - 不可优化的SQL命令(也称为实用命令)不能够接受查询参数。 所以自动替换PL/pgSQL的变量在这类命令中不起作用。 要在从PL/pgSQL执行的实用程序命令中包含非常量文本,你必须将实用程序命令构建为一个字符串,然后EXECUTE它,如中所讨论的。 + 不可优化的 SQL 命令(也称为工具命令)不能接受查询参数。因此,自动替换 PL/pgSQL 变量在这类命令中不起作用。要在从 PL/pgSQL 执行的工具命令中包含非常量文本,必须将工具命令构建为一个字符串,然后用 EXECUTE 执行它,如 中所讨论的。 - EXECUTE也必须使用,如果你想以某种其他方式修改命令,而不是提供数据值,例如改变表名。 + 如果想通过其他方式修改命令,而不只是提供数据值,例如改变表名,也必须使用 EXECUTE - 有时候计算一个表达式或SELECT查询但抛弃其结果是有用的,例如调用一个有副作用但是没有有用的结果值的函数。在PL/pgSQL中要这样做,可使用PERFORM语句: + 有时需要计算一个表达式或 SELECT 查询但丢弃其结果,例如调用一个有副作用但没有有用结果值的函数。要在 PL/pgSQL 中这样做,可使用 PERFORM 语句: PERFORM query; - 这会执行query并且丢弃掉结果。以写一个SQL SELECT命令相同的方式写该query,并且将初始的关键词SELECT替换为PERFORM。对于WITH查询,使用PERFORM并且接着把该查询放在圆括号中(在这种情况中,该查询只能返回一行)。PL/pgSQL变量将被替换到该查询中,正如上面描述的查询,并且计划被以相同的方式被缓存。还有,如果该查询产生至少一行,特殊变量FOUND会被设置为真,而如果它不产生行则设置为假(见)。 + 这会执行 query 并丢弃结果。query 的写法与 SQL SELECT 命令相同,只需把开头的关键词 SELECT 替换为 PERFORM。对于 WITH 查询,使用 PERFORM 并将该查询放在圆括号中(在这种情况下,该查询只能返回一行)。PL/pgSQL 变量会像上文所述那样替换到查询中,计划也会以相同方式缓存。此外,如果该查询产生至少一行,特殊变量 FOUND 会被设置为真;如果不产生行,则设置为假(见 )。 @@ -812,12 +811,12 @@ PERFORM create_mv('cs_session_page_requests_mv', my_query); SELECT INTO - in PL/pgSQL + 在 PL/pgSQL 中 RETURNING INTO - in PL/pgSQL + 在 PL/pgSQL 中 @@ -842,7 +841,7 @@ MERGE ... RETURNING expressions INTO STRICT - 如果一个行变量或一个变量列表被用作目标,该命令的结果列必须完全匹配该结果的结构,包括数量和数据类型,否则会发生一个运行时错误。当一个记录变量是目标时,它会自动地把自身配置成命令的结果列组成的行类型。 + 如果一个行变量或一个变量列表被用作目标,该命令的结果列必须完全匹配该目标的结构,包括数量和数据类型,否则会发生一个运行时错误。当一个记录变量是目标时,它会自动地把自身配置成命令的结果列组成的行类型。 @@ -850,7 +849,7 @@ MERGE ... RETURNING expressions INTO STRICT - 如果STRICT没有在INTO子句中被指定,那么target将被设置为该命令返回的第一个行,或者在该命令不返回行时设置为空(注意除非使用了ORDER BY,否则第一行的界定并不清楚)。第一行之后的任何结果行都会被抛弃。你可以检查特殊的FOUND变量(见)来确定是否返回了一行: + 如果STRICT没有在INTO子句中被指定,那么target将被设置为该命令返回的第一个行,或者在该命令不返回行时设置为空值(注意除非使用了ORDER BY,否则第一行的界定并不清楚)。第一行之后的任何结果行都会被抛弃。你可以检查特殊的FOUND变量(见)来确定是否返回了一行: SELECT * INTO myrec FROM emp WHERE empname = myname; @@ -879,7 +878,7 @@ END; - 如果为函数启用了print_strict_params,那么当由于不满足STRICT要求而抛出错误时,错误消息的DETAIL部分将包含传给该命令的参数信息。你可以通过设置plpgsql.print_strict_params来修改所有函数的print_strict_params设置,不过只有此后重新编译的函数才会受影响。也可以通过编译器选项按函数启用它,例如: + 如果为函数启用了print_strict_params,那么当由于不满足STRICT要求而抛出错误时,错误消息的DETAIL部分将包含传给该命令的参数信息。你可以通过设置plpgsql.print_strict_params来修改所有函数的print_strict_params设置,不过该设置只会影响此后编译的函数。也可以通过编译器选项按函数启用它,例如: CREATE FUNCTION get_userid(username text) RETURNS int AS $$ @@ -915,33 +914,31 @@ CONTEXT: PL/pgSQL function get_userid(text) line 6 at SQL statement 执行动态命令 - 很多时候你将想要在PL/pgSQL函数中产生动态命令,也就是每次执行中会涉及到不同表或不同数据类型的命令。PL/pgSQL通常对于命令所做的缓存计划尝试(如中讨论)在这种情境下无法工作。要处理这一类问题,需要提供EXECUTE语句: + 很多时候你将想要在PL/pgSQL函数中产生动态命令,也就是每次执行中会涉及到不同表或不同数据类型的命令。PL/pgSQL通常对于命令所做的缓存计划尝试(如中讨论)在这种情境下无法工作。要处理这一类问题,提供了EXECUTE语句: EXECUTE command-string INTO STRICT target USING expression , ... ; - 其中command-string是一个能得到一个包含要被执行命令字符串(类型text)的表达式。可选的target是一个记录变量、一个行变量或者一个逗号分隔的简单变量以及记录/行域的列表,该命令的结果将存储在其中。可选的USING表达式提供要被插入到该命令中的值。 + 其中command-string是一个能得到一个包含要被执行命令字符串(类型text)的表达式。可选的target是一个记录变量、一个行变量或者一个逗号分隔的简单变量以及记录/行字段的列表,该命令的结果将存储在其中。可选的USING表达式提供要被插入到该命令中的值。 在计算得到的命令字符串中,不会做PL/pgSQL变量的替换。任何所需的变量值必须在命令字符串被构造时被插入其中,或者你可以使用下面描述的参数。 - - 还有,对于通过EXECUTE执行的命令不会有计划被缓存。该命令反而在每次运行时都会被做计划。因此,该命令字符串可以在执行不同表和列上动作的函数中被动态创建。 - + 此外,通过 EXECUTE 执行的命令不会缓存计划,而是在每次运行该语句时重新规划。因此,可以在函数中动态构造命令字符串,对不同的表和列执行操作。 - INTO子句指定一个返回行的 SQL 命令的结果应该被赋值到哪里。如果提供了一个行或变量列表,它必须完全匹配查询命令结果的结构(当一个记录变量被提供时,它会自动把它自己配置为匹配结果结构)。如果返回多个行,只有第一个行会被赋值给INTO变量。如果没有返回行,NULL 会被赋值给INTO变量。如果没有指定INTO变量,该查询结果会被抛弃。 + INTO子句指定一个返回行的 SQL 命令的结果应该被赋值到哪里。如果提供了一个行变量或变量列表,它必须完全匹配查询命令结果的结构(当一个记录变量被提供时,它会自动把它自己配置为匹配结果结构)。如果返回多个行,只有第一个行会被赋值给INTO变量。如果没有返回行,NULL 会被赋值给INTO变量。如果没有指定INTO子句,该查询结果会被抛弃。 - 如果给出了STRICT选项,除非该查询刚好产生一行,否则将会报告一个错误。 + 如果给出了STRICT选项,除非该命令刚好产生一行,否则将会报告一个错误。 - 命令字符串可以使用参数值,它们在命令中用$1$2等引用。这些符号引用在USING子句中提供的值。这种方法常常更适合于把数据值作为文本插入到命令字符串中:它避免了将该值转换为文本以及转换回来的运行时负荷,并且它更不容易被 SQL 注入攻击,因为不需要引用或转义。一个示例是: + 命令字符串可以使用参数值,它们在命令中用$1$2等引用。这些符号引用在USING子句中提供的值。这种方法通常比把数据值作为文本插入命令字符串更可取:它避免了将该值转换为文本以及转换回来的运行时负荷,并且它更不容易被 SQL 注入攻击,因为不需要引用或转义。一个示例是: EXECUTE 'SELECT count(*) FROM mytable WHERE inserted_by = $1 AND inserted <= $2' INTO c @@ -959,25 +956,25 @@ EXECUTE 'SELECT count(*) FROM ' USING checked_user, checked_date; 一种更干净的方法是使用format()的 - %I规范,插入自带引号的表名或者列名: + %I 格式说明符,插入表名或列名并自动为其加上引号: EXECUTE format('SELECT count(*) FROM %I ' 'WHERE inserted_by = $1 AND inserted <= $2', tabname) INTO c USING checked_user, checked_date; - (此示例依赖于隐式连接由换行符分隔的字符串文字的 SQL 规则) + (此示例依赖于隐式连接由换行符分隔的字符串字面量的 SQL 规则) 参数符号的另一个限制是它们仅适用于可优化的SQL命令 (SELECT, INSERT, UPDATE, DELETE, MERGE以及包含其中一个的某些命令)。 - 在其他语句类型(通称为实用程序语句)中,即使它们只是数据值,您也必须以文本方式插入值。 + 在其他语句类型(通称为工具语句)中,即使它们只是数据值,你也必须以文本方式插入值。 - 在上面第一个示例中,带有一个简单的常量命令字符串和一些USING参数的EXECUTE命令在功能上等效于直接用PL/pgSQL写的命令,并且允许自动发生PL/pgSQL变量替换。重要的不同之处在于,EXECUTE会在每一次执行时根据当前的参数值重新计划该命令,而PL/pgSQL则是创建一个通用计划并且将其缓存以便重用。在最佳计划强依赖于参数值的情况中,使用EXECUTE来明确地保证不会选择一个通用计划是很有帮助的。 + 在上面第一个示例中,带有一个简单的常量命令字符串和一些USING参数的EXECUTE命令在功能上等效于直接用PL/pgSQL写的命令,并且允许自动发生PL/pgSQL变量替换。重要的不同之处在于,EXECUTE会在每一次执行时根据当前的参数值重新计划该命令,而PL/pgSQL则可能创建一个通用计划并且将其缓存以便重用。在最佳计划强依赖于参数值的情况中,使用EXECUTE来明确地保证不会选择一个通用计划是很有帮助的。 @@ -985,10 +982,7 @@ EXECUTE format('SELECT count(*) FROM %I ' - - - PL/pgSQL中的EXECUTE语句与EXECUTE PostgreSQL服务器支持的 SQL 语句无关。服务器的EXECUTE语句不能直接在PL/pgSQL函数中使用(并且也没有必要)。 - + PL/pgSQLEXECUTE 语句与 PostgreSQL 服务器支持的 SQL EXECUTE 语句无关。服务器的 EXECUTE 语句不能直接用于 PL/pgSQL 函数中(也没有这个必要)。 @@ -1052,19 +1046,19 @@ EXECUTE 'UPDATE tbl SET ' || ' WHERE key = ' || quote_nullable(keyvalue); - 如果正在处理的参数值可能为空,那么通常应该用quote_nullable来代替quote_literal。 + 如果正在处理的参数值可能为空值,那么通常应该用quote_nullable来代替quote_literal - 通常,必须小心地确保查询中的空值不会递送意料之外的结果。例如如果keyvalue为空,下面的WHERE子句 + 通常,必须小心地确保查询中的空值不会产生意料之外的结果。例如如果keyvalue为空值,下面的WHERE子句 'WHERE key = ' || quote_nullable(keyvalue) - 永远不会成功,因为在=操作符中使用空操作数得到的结果总是为空。如果想让空和一个普通键值一样工作,你应该将上面的命令重写成 + 永远不会成功,因为在=操作符中使用空值操作数得到的结果总是空值。如果想让空值像普通键值一样工作,你应该将上面的命令重写成 'WHERE key IS NOT DISTINCT FROM ' || quote_nullable(keyvalue) - (目前,IS NOT DISTINCT FROM的处理效率不如=,因此只有在非常必要时才这样做。关于空和IS DISTINCT的详细信息请见)。 + (目前,IS NOT DISTINCT FROM的处理效率不如=,因此只有在非常必要时才这样做。关于空值和IS DISTINCT的详细信息请见)。 @@ -1077,7 +1071,7 @@ EXECUTE 'UPDATE tbl SET ' || '$$ WHERE key = ' || quote_literal(keyvalue); - 因为如果newvalue的内容碰巧含有$$,那么这段代码就会出问题。同样的缺点可能适用于你选择的任何其他美元符号引用定界符。因此,要想安全地引用事先不知道的文本,必须恰当地使用quote_literalquote_nullablequote_ident。 + 因为如果newvalue的内容碰巧含有$$,那么这段代码就会出问题。同样的问题也适用于你选择的任何其他美元符号引用定界符。因此,要想安全地引用事先不知道的文本,必须恰当地使用quote_literalquote_nullablequote_ident @@ -1116,7 +1110,7 @@ EXECUTE format('UPDATE tbl SET %I = $1 WHERE key = $2', colname) GET CURRENT DIAGNOSTICS variable { = | := } item , ... ; - 这条命令允许检索系统状态指示符。CURRENT是一个噪声词(另见中的GET STACKED DIAGNOSTICS)。每个item是一个关键字, 它标识一个要被赋予给指定变量的状态值(变量应具有正确的数据类型来接收状态值)。中展示了当前可用的状态项。冒号等号(:=)可以被用来取代 SQL 标准的=符号。例如: + 这条命令允许检索系统状态指示符。CURRENT是一个噪声词(另见中的GET STACKED DIAGNOSTICS)。每个item是一个关键字, 它标识一个要被赋予给指定variable的状态值(变量应具有正确的数据类型来接收状态值)。中展示了当前可用的状态项。冒号等号(:=)可以被用来取代 SQL 标准的=符号。例如: GET DIAGNOSTICS integer_var = ROW_COUNT; @@ -1161,13 +1155,13 @@ GET DIAGNOSTICS integer_var = ROW_COUNT; 第二种确定命令效果的方法是检查名为FOUND的特殊变量,类型为boolean。 - 在每次PL/pgSQL函数调用中,FOUND都是以 false 开头。 + 在每次PL/pgSQL函数调用中,FOUND的初始值都是 false。 它由以下类型的语句设置: - SELECT INTO语句在分配行时将FOUND设置为true, + SELECT INTO语句在为目标赋上一行值时将FOUND设置为true, 如果没有返回行则设置为false。 @@ -1199,7 +1193,7 @@ GET DIAGNOSTICS integer_var = ROW_COUNT; FORFOREACH语句在迭代一次或多次时将 FOUND设置为true,否则设置为false。 - 当循环退出时,FOUND被设置为这种方式; + 当循环退出时,FOUND会按上述方式设置; 在循环执行过程中,FOUND不会被循环语句修改, 尽管它可能会被循环体内的其他语句执行修改。 @@ -1295,7 +1289,7 @@ RETURN expression; - 如果函数返回的是标量类型,表达式结果会自动转换为函数的返回类型。但如果要返回一个组合(行)值,你必须写出一个恰好生成所需列集合的表达式。这可能需要显式类型转换。 + 如果函数返回的是标量类型,表达式结果会按照赋值部分的说明自动转换为函数的返回类型。但如果要返回一个复合(行)值,你必须写出一个恰好生成所需列集合的表达式。这可能需要显式类型转换。 @@ -1307,7 +1301,7 @@ RETURN expression; - 一个函数的返回值不能是未定义。如果控制到达了函数最顶层的块而没有碰到一个RETURN语句,那么会发生一个运行时错误。不过,这个限制不适用于带输出参数的函数以及返回void的函数。在这些情况中,如果顶层的块结束,将自动执行一个RETURN语句。 + 一个函数的返回值不能是未定义。如果控制到达了函数最顶层块的末尾而没有碰到一个RETURN语句,那么会发生一个运行时错误。不过,这个限制不适用于带输出参数的函数以及返回void的函数。在这些情况中,如果顶层的块结束,将自动执行一个RETURN语句。 @@ -1331,12 +1325,12 @@ RETURN (1, 2, 'three'::text); -- 必须把列类型转换成正确的类型 RETURN NEXT - in PL/pgSQL + 在 PL/pgSQL 中 RETURN QUERY - in PL/pgSQL + 在 PL/pgSQL 中 @@ -1346,7 +1340,7 @@ RETURN QUERY EXECUTE command-string < - 当 PL/pgSQL 函数被声明为返回 SETOF sometype 时,返回过程会略有不同。在这种情况下,要返回的各个项通过一系列 RETURN NEXTRETURN QUERY 命令指定,最后再用一个不带参数的 RETURN 命令表明函数已经执行完毕。RETURN NEXT 可用于标量和组合数据类型;对于组合结果类型,会返回完整的结果RETURN QUERY 会把查询执行结果追加到函数的结果集中。在同一个集合返回函数中,RETURN NEXTRETURN QUERY 可以自由混用,此时它们的结果会被串接起来。 + 当 PL/pgSQL 函数被声明为返回 SETOF sometype 时,返回过程会略有不同。在这种情况下,要返回的各个项通过一系列 RETURN NEXTRETURN QUERY 命令指定,最后再用一个不带参数的 RETURN 命令表明函数已经执行完毕。RETURN NEXT 可用于标量和复合数据类型;对于复合结果类型,会返回完整的结果RETURN QUERY 会把查询执行结果追加到函数的结果集中。在同一个集合返回函数中,RETURN NEXTRETURN QUERY 可以自由混用,此时它们的结果会被串接起来。 @@ -1511,7 +1505,7 @@ END IF; - IF-THEN语句是IF的最简单形式。 如果条件为真,在THENEND IF之间的语句将被执行。否则,将忽略它们。 + IF-THEN语句是IF的最简单形式。 如果条件为真,在THENEND IF之间的语句将被执行。否则,将忽略它们。 @@ -1594,7 +1588,7 @@ ELSIF number > 0 THEN ELSIF number < 0 THEN result := 'negative'; ELSE - -- 嗯,唯一的其他可能性是数字为空 + -- 嗯,唯一的其他可能性是 number 为 null result := 'NULL'; END IF; @@ -1690,9 +1684,7 @@ END CASE; - - 这种形式的CASEIF-THEN-ELSIF完全等价,唯一的区别是:如果省略了ELSE子句,CASE会报错,而不是简单地什么也不做。 - + 这种形式的CASEIF-THEN-ELSIF完全等价,唯一的区别是:如果执行到被省略的ELSE子句,就会报错,而不是简单地什么也不做。 @@ -1702,12 +1694,12 @@ END CASE; 简单循环 - loop + 循环 在 PL/pgSQL 中 - 使用LOOPEXITCONTINUEWHILEFORFOREACH语句,你可以安排PL/pgSQL重复一系列命令。 + 使用LOOPEXITCONTINUEWHILEFORFOREACH语句,你可以安排PL/pgSQL函数重复一系列命令。 @@ -1862,22 +1854,22 @@ END LOOP label ; - 这种形式的FOR会创建一个在一个整数范围上迭代的循环。变量name会自动定义为类型integer并且只在循环内存在(任何该变量名的现有定义在此循环内都将被忽略)。给出范围上下界的两个表达式在进入循环的时候计算一次。如果没有指定BY子句,迭代步长为 1,否则步长是BY中指定的值,该值也只在循环进入时计算一次。如果指定了REVERSE,那么在每次迭代后步长值会被减除而不是增加。 + 这种形式的FOR会创建一个在一个整数范围上迭代的循环。变量name会自动定义为类型integer并且只在循环内存在(任何该变量名的现有定义在此循环内都将被忽略)。给出范围上下界的两个表达式在进入循环的时候计算一次。如果没有指定BY子句,迭代步长为 1,否则步长是BY中指定的值,该值也只在循环进入时计算一次。如果指定了REVERSE,那么在每次迭代后会减去步长,而不是加上步长。 整数FOR循环的一些示例: FOR i IN 1..10 LOOP - -- 我在循环中将取值 1,2,3,4,5,6,7,8,9,10 + -- i 在循环中将取值 1,2,3,4,5,6,7,8,9,10 END LOOP; FOR i IN REVERSE 10..1 LOOP - -- 我在循环中将取值 10,9,8,7,6,5,4,3,2,1 + -- i 在循环中将取值 10,9,8,7,6,5,4,3,2,1 END LOOP; FOR i IN REVERSE 10..1 BY 2 LOOP - -- 我在循环中将取值 10,8,6,4,2 + -- i 在循环中将取值 10,8,6,4,2 END LOOP; @@ -1941,7 +1933,7 @@ $$ LANGUAGE plpgsql; - 在这类 FOR 语句中使用的 query,可以是任何向调用者返回行的 SQL 命令:最常见的是 SELECT,但也可以是带 RETURNING 子句的 INSERTUPDATEDELETEMERGE。某些实用程序命令,如 EXPLAIN,也可以用于此处。 + 在这类 FOR 语句中使用的 query,可以是任何向调用者返回行的 SQL 命令:最常见的是 SELECT,但也可以是带 RETURNING 子句的 INSERTUPDATEDELETEMERGE。某些工具命令,如 EXPLAIN,也可以用于此处。 @@ -1956,7 +1948,7 @@ FOR target IN EXECUTE text_expressionstatements END LOOP label ; - 这个示例类似前面的形式,只不过源查询被指定为一个字符串表达式,在每次进入FOR循环时都会计算它并且重新计划。这允许程序员在一个预先计划好了的命令的速度和一个动态命令的灵活性之间进行选择,就像一个纯EXECUTE语句那样。在使用EXECUTE时,可以通过USING将参数值插入到动态命令中。 + 这个示例类似前面的形式,只不过源查询被指定为一个字符串表达式,在每次进入FOR循环时都会计算它并且重新计划。这允许程序员在一个预先计划好了的命令的速度和一个动态命令的灵活性之间进行选择,就像一个纯EXECUTE语句那样。与EXECUTE一样,可以通过USING将参数值插入到动态命令中。 @@ -1969,7 +1961,7 @@ END LOOP label ; 遍历数组 - FOREACH循环很像FOR循环,但它不是遍历 SQL 查询返回的行,而是遍历数组值的元素。(一般来说,FOREACH用于遍历组合值表达式的组成部分;未来还可能加入遍历数组以外其他组合值的变体。)用于遍历数组的FOREACH语句如下: + FOREACH循环很像FOR循环,但它不是遍历 SQL 查询返回的行,而是遍历数组值的元素。(一般来说,FOREACH用于遍历复合值表达式的组成部分;未来还可能加入遍历数组以外其他复合值的变体。)用于遍历数组的FOREACH语句如下: <<label>> @@ -1997,7 +1989,7 @@ END; $$ LANGUAGE plpgsql; - 元素会按存储顺序访问,而不管数组有多少维。尽管target通常只是单个变量,但在遍历组合值(记录)数组时,它也可以是一个变量列表。在这种情况下,每个数组元素都会按组合值的连续列给这些变量赋值。 + 元素会按存储顺序访问,而不管数组有多少维。尽管target通常只是单个变量,但在遍历复合值(记录)数组时,它也可以是一个变量列表。在这种情况下,每个数组元素都会按复合值的连续列给这些变量赋值。 @@ -2030,8 +2022,8 @@ NOTICE: row = {10,11,12} 捕获错误 - exceptions - in PL/pgSQL + 异常 + 在 PL/pgSQL 中 @@ -2054,7 +2046,7 @@ END; - 如果没有发生错误,这种形式的块只是简单地执行所有statements, 并且接着控制转到END之后的下一个语句。但是如果在statements内发生了一个错误,则会放弃对statements的进一步处理,然后控制会转到EXCEPTION列表。系统会在列表中寻找匹配所发生错误的第一个condition。如果找到一个匹配,则执行对应的handler_statements,并且接着把控制转到END之后的下一个语句。如果没有找到匹配,该错误就会传播出去,就好像根本没有EXCEPTION一样:错误可以被一个带有EXCEPTION的闭合块捕捉,如果没有EXCEPTION则中止该函数的处理。 + 如果没有发生错误,这种形式的块只是简单地执行所有statements, 并且接着控制转到END之后的下一个语句。但是如果在statements内发生了一个错误,则会放弃对statements的进一步处理,然后控制会转到EXCEPTION列表。系统会在列表中寻找匹配所发生错误的第一个condition。如果找到一个匹配,则执行对应的handler_statements,并且接着把控制转到END之后的下一个语句。如果没有找到匹配,该错误就会传播出去,就好像根本没有EXCEPTION一样:错误可以被一个带有EXCEPTION的外围块捕捉,如果没有这样的块则中止该函数的处理。 @@ -2091,7 +2083,7 @@ END; - 进入和退出一个包含EXCEPTION子句的块要比不包含EXCEPTION的块开销大的多。因此,只在必要的时候使用EXCEPTION。 + 进入和退出一个包含EXCEPTION子句的块要比不包含该子句的块开销大得多。因此,只在必要的时候使用EXCEPTION @@ -2118,9 +2110,9 @@ BEGIN IF found THEN RETURN; END IF; - -- 不在这里,那么尝试插入该键 + -- 该键不存在,因此尝试插入 -- 如果其他某人并发地插入同一个键, - -- 我们可能得到一个唯一键失败 + -- 就可能发生违反唯一约束的错误 BEGIN INSERT INTO db(a,b) VALUES (key, data); RETURN; @@ -2159,7 +2151,7 @@ SELECT merge_db(1, 'dennis'); GET STACKED DIAGNOSTICS variable { = | := } item , ... ; - 每个item是一个关键词,它标识一个被赋予给指定变量(应该具有接收该值的正确数据类型)的状态值。中显示了当前可用的状态项。 + 每个item是一个关键词,它标识一个被赋予给指定variable(应该具有接收该值的正确数据类型)的状态值。中显示了当前可用的状态项。
@@ -2271,7 +2263,7 @@ END; 获得执行位置信息 - GET DIAGNOSTICS(之前在中描述)命令检索有关当前执行状态的信息(反之上文讨论的GET STACKED DIAGNOSTICS命令会把有关执行状态的信息报告成一个以前的错误)。它的PG_CONTEXT状态项可用于标识当前执行位置。状态项PG_CONTEXT将返回一个文本字符串,其中有描述该调用栈的多行文本。第一行会指向当前函数以及当前正在执行GET DIAGNOSTICS的命令。第二行及其后的行表示调用栈中更上层的调用函数。例如: + GET DIAGNOSTICS(之前在中描述)命令检索有关当前执行状态的信息(反之上文讨论的GET STACKED DIAGNOSTICS命令报告先前发生错误时的执行状态信息)。它的PG_CONTEXT状态项可用于标识当前执行位置。状态项PG_CONTEXT将返回一个文本字符串,其中包含一行或多行描述该调用栈的文本。第一行会指向当前函数以及当前正在执行的GET DIAGNOSTICS命令。第二行及其后的行表示调用栈中更上层的调用函数。例如: CREATE OR REPLACE FUNCTION outer_func() RETURNS integer AS $$ @@ -2315,7 +2307,7 @@ CONTEXT: PL/pgSQL function outer_func() line 3 at RETURN 游标 - cursor + 游标 在 PL/pgSQL 中 @@ -2347,7 +2339,7 @@ DECLARE - 当游标查询使用 FOR UPDATE/SHARE 时,不能使用 SCROLL 选项。此外,对于涉及易失函数的查询,最好使用 NO SCROLLSCROLL 的实现假定重新读取查询输出会得到一致的结果,而易失函数并不满足这一假设。 + 当游标查询使用 FOR UPDATE/SHARE 时,不能使用 SCROLL 选项。此外,对于涉及易失函数的查询,最好使用 NO SCROLLSCROLL 的实现假定重新读取查询输出会得到一致的结果,而易失函数可能无法满足这一假设。 @@ -2372,7 +2364,7 @@ DECLARE - 打开游标会创建一个称为 portal 的服务器内部数据结构,它保存游标查询的执行状态。portal 具有一个名称,在其存在期间该名称在会话内必须唯一。默认情况下,PL/pgSQL 会为其创建的每个 portal 分配唯一名称。不过,如果你给游标变量赋一个非空字符串值,该字符串会被用作 portal 名称。这个特性可用于中描述的用法。 + 打开游标会创建一个称为 portal 的服务器内部数据结构,它保存游标查询的执行状态。portal 具有一个名称,在其存在期间该名称在会话内必须唯一。默认情况下,PL/pgSQL 会为其创建的每个 portal 分配唯一名称。不过,如果你给游标变量赋一个非 NULL 的字符串值,该字符串会被用作 portal 名称。这个特性可用于中描述的用法。 @@ -2498,7 +2490,7 @@ FETCH direction { FROM | IN } RELATIVE countFORWARD或者 BACKWARD。 - 省略direction和指定NEXT是一样的。在使用count的形式中,count可以是任意的整数值表达式(与SQL命令FETCH不一样,FETCH仅允许整数常量)。除非游标被使用SCROLL选项声明或打开,否则要求反向移动的direction值很可能会失败。 + 省略direction和指定NEXT是一样的。在使用count的形式中,count可以是任意的整数值表达式(与SQL命令FETCH不一样,后者仅允许整数常量)。除非游标被使用SCROLL选项声明或打开,否则要求反向移动的direction值很可能会失败。 @@ -2586,13 +2578,13 @@ CLOSE curs1; - 游标使用的 portal 名称既可以由程序员指定,也可以自动生成。要指定 portal 名称,只需在打开refcursor变量之前给它赋一个字符串值。OPEN会把该refcursor变量的字符串值用作底层 portal 的名称。不过,如果refcursor变量为 null,OPEN就会自动生成一个与任何现有 portal 都不冲突的名称,并把它赋回给refcursor变量。 + 游标使用的 portal 名称既可以由程序员指定,也可以自动生成。要指定 portal 名称,只需在打开refcursor变量之前给它赋一个字符串值。OPEN会把该refcursor变量的字符串值用作底层 portal 的名称。不过,如果refcursor变量为 null(这是默认值),OPEN就会自动生成一个与任何现有 portal 都不冲突的名称,并把它赋回给refcursor变量。 - 在 PostgreSQL 16 之前,已绑定游标变量会被初始化为其自身名称,而不是保持为空,因此默认情况下底层 portal 名称与游标变量名相同。之所以改动,是因为该行为在不同函数里同名游标之间带来了过高的名称冲突风险。 + 在 PostgreSQL 16 之前,已绑定游标变量会被初始化为其自身名称,而不是保持为 NULL,因此默认情况下底层 portal 名称与游标变量名相同。之所以改动,是因为该行为在不同函数里同名游标之间带来了过高的名称冲突风险。 @@ -2726,7 +2718,7 @@ CALL transaction_test1(); 连锁的事务 - 在 PL/pgSQL + 在 PL/pgSQL 中 @@ -2739,7 +2731,7 @@ CALL transaction_test1(); - PL/pgSQL 不支持保存点(SAVEPOINT/ROLLBACK TO SAVEPOINT/RELEASE SAVEPOINT)。保存点的典型用法可以用带异常处理器的代码块替代(见)。在内部,实现为带异常处理器的代码块会形成一个子事务,这意味着在这类代码块内部不能结束事务。 + PL/pgSQL 不支持保存点(SAVEPOINT/ROLLBACK TO SAVEPOINT/RELEASE SAVEPOINT)。保存点的典型用法可以用带异常处理器的代码块替代(见)。带异常处理器的代码块在内部会形成一个子事务,这意味着在这类代码块内部不能结束事务。 @@ -2786,23 +2778,19 @@ CALL transaction_test2(); 在 PL/pgSQL 中 - - 使用RAISE语句报告消息以及抛出错误。 - - + 使用RAISE语句报告消息和抛出错误。 RAISE level 'format' , expression , ... USING option { = | := } expression , ... ; RAISE level condition_name USING option { = | := } expression , ... ; RAISE level SQLSTATE 'sqlstate' USING option { = | := } expression , ... ; RAISE level USING option { = | := } expression , ... ; RAISE ; - - - level选项指定了错误的严重性。允许的级别有DEBUGLOGINFONOTICE, WARNING以及EXCEPTION,默认级别是EXCEPTIONEXCEPTION会抛出一个错误(通常会中止当前事务)。其他级别仅仅是产生不同优先级的消息。不管一个特定优先级的消息是被报告给客户端、还是写到服务器日志、亦或是二者同时都做,这都由配置变量控制。详见。 - +其中,level选项指定错误的严重程度。允许的级别为DEBUG, + LOGINFO, + NOTICEWARNING以及EXCEPTION,其中EXCEPTION是默认值。EXCEPTION会抛出错误(通常会中止当前事务);其他级别只会生成不同优先级的消息。特定优先级的消息是报告给客户端、写入服务器日志,还是两者都做,由配置变量控制。更多信息见中的说明。 在第一种语法变体中,在level之后(如果有),写一个format字符串 - (必须是一个简单的字符串文字,而不是一个表达式)。格式字符串指定要报告的错误消息文本。 + (必须是一个简单的字符串字面量,而不是一个表达式)。格式字符串指定要报告的错误消息文本。 格式字符串后跟要插入到消息中的可选参数表达式。 在格式字符串中,%将被下一个可选参数的值的字符串表示替换。写 %%以发出一个字面上的%。 @@ -2845,7 +2833,7 @@ RAISE WARNING SQLSTATE '22012'; DETAIL - 提供一个错误的细节消息。 + 提供错误的详细信息。 @@ -2876,9 +2864,7 @@ RAISE WARNING SQLSTATE '22012'; - - 这个示例将用给定的错误消息和提示中止事务: - + 这个例子会中止事务,并给出指定的错误消息和提示: RAISE EXCEPTION 'Nonexistent ID --> %', user_id USING HINT = 'Please check your user ID'; @@ -2890,9 +2876,8 @@ RAISE EXCEPTION 'Nonexistent ID --> %', user_id RAISE 'Duplicate user ID: %', user_id USING ERRCODE = 'unique_violation'; RAISE 'Duplicate user ID: %', user_id USING ERRCODE = '23505'; - - + 另一种得到前面示例相同结果的方式是: RAISE unique_violation USING MESSAGE = 'Duplicate user ID: ' || user_id; @@ -2923,7 +2908,7 @@ RAISE unique_violation USING MESSAGE = 'Duplicate user ID: ' || user_id; - 当用 SQLSTATE 代码指定错误代码时,你并不受限于预定义错误代码,而是可以选择任何由五位数字和/或大写 ASCII 字母构成的错误代码,唯一不能使用的是 00000。我们建议尽量避免抛出以三个零结尾的错误代码,因为这些是类别代码,只能用于捕获整个类别。 + 当用 SQLSTATE 代码指定错误代码时,你并不受限于预定义错误代码,而是可以选择任何由五位数字和/或大写 ASCII 字母构成的错误代码,唯一不能使用的是 00000。我们建议尽量避免抛出以三个零结尾的错误代码,因为这些是类别代码,只能通过捕获整个类别来捕获这类错误。 @@ -2935,12 +2920,12 @@ RAISE unique_violation USING MESSAGE = 'Duplicate user ID: ' || user_id; ASSERT - in PL/pgSQL + 在 PL/pgSQL 中 - assertions - in PL/pgSQL + 断言 + 在 PL/pgSQL 中 @@ -2957,15 +2942,14 @@ ASSERT condition , condition是一个布尔 表达式,它被期望总是计算为真。如果确实如此, - ASSERT语句不会再做什么。但如果结果是假 - 或者空,那么将发生一个ASSERT_FAILURE异常(如果在计算 + ASSERT语句不会再做什么。但如果结果是假或者空值,那么将发生一个ASSERT_FAILURE异常(如果在计算 condition时发生错误, 它会被报告为一个普通错误)。 如果提供了可选的message, - 它是一个结果(如果非空)被用来替换默认错误消息文本 + 它是一个结果(如果不为 NULL)被用来替换默认错误消息文本 assertion failed的表达式(如果 condition失败)。 message表达式在 @@ -2998,7 +2982,7 @@ ASSERT condition , - PL/pgSQL可以被用来在数据更改或者数据库事件上定义触发器函数。触发器函数用CREATE FUNCTION命令创建,它被声明为一个没有参数并且返回类型为trigger(对于数据更改触发器)或者event_trigger(对于数据库事件触发器)的函数。名为PG_something的特殊局部变量将被自动创建用以描述触发该调用的条件。 + PL/pgSQL可以被用来在数据更改或者数据库事件上定义触发器函数。触发器函数用CREATE FUNCTION命令创建,它被声明为一个没有参数并且返回类型为trigger(对于数据更改触发器)或者event_trigger(对于数据库事件触发器)的函数。名为TG_something的特殊局部变量将被自动创建用以描述触发该调用的条件。 @@ -3009,10 +2993,7 @@ ASSERT condition , 数据更改触发器被声明为一个没有参数并且返回类型为trigger的函数。注意,如下所述,即便该函数准备接收一些在CREATE TRIGGER中指定的参数 — 这类参数通过TG_ARGV传递,也必须把它声明为没有参数。 - - 当一个PL/pgSQL函数当做触发器调用时,在顶层块会自动创建一些特殊变量。它们是: - - + 当一个PL/pgSQL函数作为触发器被调用时,会在顶层块中自动创建一些特殊变量。它们是: NEW record @@ -3132,11 +3113,11 @@ ASSERT condition , - INSTEAD OF触发器(总是行级触发器,并且可能只被用于视图)能够返回空来表示它们没有执行任何更新,并且对该行剩余的操作可以被跳过(即后续的触发器不会被引发,并且该行不会被计入外围INSERT/UPDATE/DELETE的行影响状态中)。否则一个非空值应该被返回用以表示该触发器执行了所请求的操作。对于INSERTUPDATE操作,返回值应该是NEW,触发器函数可能对它进行了修改来支持INSERT RETURNINGUPDATE RETURNING(这也将影响被传递给任何后续触发器的行值,或者被传递给带有ON CONFLICT DO UPDATEINSERT语句中一个特殊的EXCLUDED别名引用)。对于DELETE操作,返回值应该是OLD。 + INSTEAD OF触发器(总是行级触发器,并且只能用于视图)能够返回 null 来表示它们没有执行任何更新,并且对该行剩余的操作应被跳过(即后续的触发器不会被引发,并且该行不会被计入外围INSERT/UPDATE/DELETE的行影响状态中)。否则应该返回一个非 null 值用以表示该触发器执行了所请求的操作。对于INSERTUPDATE操作,返回值应该是NEW,触发器函数可能对它进行了修改来支持INSERT RETURNINGUPDATE RETURNING(这也将影响被传递给任何后续触发器的行值,或者被传递给带有ON CONFLICT DO UPDATEINSERT语句中一个特殊的EXCLUDED别名引用)。对于DELETE操作,返回值应该是OLD - 一个AFTER行级触发器或一个BEFOREAFTER语句级触发器的返回值总是会被忽略,它可能也是空。不过,任何这些类型的触发器可能仍会通过抛出一个错误来中止整个操作。 + 一个AFTER行级触发器或一个BEFOREAFTER语句级触发器的返回值总是会被忽略,因此也可以返回 null。不过,任何这些类型的触发器可能仍会通过抛出一个错误来中止整个操作。 @@ -3310,11 +3291,10 @@ INSTEAD OF INSERT OR UPDATE OR DELETE ON emp_view - - 一个 <application>PL/pgSQL</application> 用于维护汇总表的触发器函数 + 一个用于维护汇总表的 <application>PL/pgSQL</application> 触发器函数 - 这里详述的模式有一部分是基于 Ralph Kimball 所作的数据仓工具包中的Grocery Store示例。 + 这里详述的模式有一部分是基于 Ralph Kimball 所作的数据仓库工具包中的Grocery Store示例。 @@ -3457,7 +3437,7 @@ SELECT * FROM sales_summary_bytime; 使用过渡表审计 - 这个示例产生和相同的结果,但并未使用一个为每一行都触发的触发器,而是在把相关信息收集到一个过渡表中之后用了一个只为每个语句引发一次的触发器。当调用语句修改了很多行时,这种方法明显比行触发器方法快。注意我们必须为每一种事件建立一个单独的触发器声明,因为每种情况的REFERENCING子句必须不同。但是这并不能阻止我们使用单一的触发器函数(实际上,使用三个单独的函数会更好,因为可以避免在TG_OP上的运行时测试)。 + 这个示例产生和相同的结果,但并未使用一个为每一行都触发的触发器,而是在把相关信息收集到一个过渡表中之后用了一个只为每个语句引发一次的触发器。当调用语句修改了很多行时,这种方法可能显著快于行触发器方法。注意我们必须为每一种事件建立一个单独的触发器声明,因为每种情况的REFERENCING子句必须不同。但是这并不能阻止我们使用单一的触发器函数(实际上,使用三个单独的函数可能会更好,因为可以避免在TG_OP上的运行时测试)。 @@ -3519,10 +3499,7 @@ CREATE TRIGGER emp_audit_del PL/pgSQL可以被用来定义事件触发器。PostgreSQL要求一个可以作为事件触发器调用的函数必须被声明为没有参数并且返回类型为event_trigger - - 当一个PL/pgSQL函数被作为一个事件触发器调用,在顶层块中会自动创建一些特殊变量。它们是: - - + 当一个PL/pgSQL函数作为事件触发器被调用时,会在顶层块中自动创建一些特殊变量。它们是: TG_EVENT text @@ -3573,9 +3550,7 @@ CREATE EVENT TRIGGER snitch ON ddl_command_start EXECUTE FUNCTION snitch(); <application>PL/pgSQL</application> 内部机制 - - 这一节讨论了一些PL/pgSQL用户应该知道的一些重要的实现细节。 - + 本节讨论一些实现细节,了解这些细节对 PL/pgSQL 用户通常很重要。 @@ -3653,7 +3628,7 @@ CREATE FUNCTION stamp_user(id int, comment text) RETURNS void AS $$ END; $$ LANGUAGE plpgsql; - 在UPDATE命令中,curtimecomment以及id将引用该函数的变量和参数,不管users有没有这些名称的列。注意,我们不得不在WHERE子句中对users.id的引用加以限定,以便让它引用表列。但是我们不需要在UPDATE列表中把对comment的引用限定为一个目标,因为语法上那必须是users的一列。我们可以用下面的方式写一个相同的不依赖于variable_conflict设置的函数: + 在UPDATE命令中,curtimecomment以及id将引用该函数的变量和参数,不管users有没有这些名称的列。注意,我们不得不在WHERE子句中对users.id的引用加以限定,以便让它引用表列。但是我们不需要对UPDATE列表中作为目标的comment引用加以限定,因为语法上那必须是users的一列。我们可以用下面的方式写一个相同的不依赖于variable_conflict设置的函数: CREATE FUNCTION stamp_user(id int, comment text) RETURNS void AS $$ <<fn>> @@ -3672,7 +3647,7 @@ $$ LANGUAGE plpgsql; - 目前,变量替换只在 SELECTINSERTUPDATEDELETEMERGE 以及包含其中之一的命令中生效(例如 EXPLAINCREATE TABLE ... AS SELECT),因为主 SQL 引擎只允许在这些命令中使用查询参数。若要在其他语句类型(统称为实用语句)中使用非常量名称或值,就必须把该实用语句构造为字符串,再用 EXECUTE 执行。 + 目前,变量替换只在 SELECTINSERTUPDATEDELETEMERGE 以及包含其中之一的命令中生效(例如 EXPLAINCREATE TABLE ... AS SELECT),因为主 SQL 引擎只允许在这些命令中使用查询参数。若要在其他语句类型(统称为工具语句)中使用非常量名称或值,就必须把该工具语句构造为字符串,再用 EXECUTE 执行。 @@ -3694,7 +3669,7 @@ $$ LANGUAGE plpgsql; - PL/pgSQL(更准确地说,是 SPI 管理器)还会尝试缓存与某个预备语句相关的执行计划。如果没有使用缓存计划,那么每次执行该语句时都会生成新的执行计划,而当前参数值(也就是 PL/pgSQL 变量值)可用于优化所选计划。如果该语句没有参数,或者会被执行很多次,SPI 管理器就会考虑创建一个不依赖具体参数值的通用计划,并将其缓存起来供重复使用。通常只有在执行计划对其中引用的 PL/pgSQL 变量值不太敏感时,才会这样做。如果执行计划对参数值非常敏感,那么每次重新生成计划总体上反而更划算。关于预备语句的行为,详见 。 + PL/pgSQL(更准确地说,是 SPI 管理器)还可以尝试缓存与某个预备语句相关的执行计划。如果没有使用缓存计划,那么每次执行该语句时都会生成新的执行计划,而当前参数值(也就是 PL/pgSQL 变量值)可用于优化所选计划。如果该语句没有参数,或者会被执行很多次,SPI 管理器就会考虑创建一个不依赖具体参数值的通用计划,并将其缓存起来供重复使用。通常只有在执行计划对其中引用的 PL/pgSQL 变量值不太敏感时,才会这样做。如果执行计划对参数值非常敏感,那么每次重新生成计划总体上反而更划算。关于预备语句的行为,详见 @@ -3743,7 +3718,7 @@ $$ LANGUAGE plpgsql; - 在logfunc2中,PostgreSQL的主解析器不知道应该把'now'解释成什么类型,因此返回一个text类型的数据值,其中包含字符串now。在确定对本地变量curtime的赋值时,PL/pgSQL解释器通过调用用于该转换的textouttimestamp_in函数,把这个字符串转换为timestamp类型。因此,计算得到的时间戳会按程序员预期在每次执行时更新。虽然这恰好能得到预期结果,但效率并不高,因此使用now()函数仍然是更好的主意。 + 在logfunc2中,PostgreSQL的主解析器不知道应该把'now'解释成什么类型,因此返回一个text类型的数据值,其中包含字符串now。在随后给局部变量curtime赋值时,PL/pgSQL解释器通过调用用于该转换的textouttimestamp_in函数,把这个字符串转换为timestamp类型。因此,计算得到的时间戳会按程序员预期在每次执行时更新。虽然这恰好能得到预期结果,但效率并不高,因此使用now()函数仍然是更好的主意。 @@ -3772,7 +3747,7 @@ $$ LANGUAGE plpgsql; - 另一种开发PL/pgSQL的好方法,是使用有助于过程语言开发的 GUI 数据库访问工具。这类工具的一个例子是pgAdmin,当然也有其他工具。它们通常提供一些方便的特性,例如转义单引号,以及让重新创建和调试函数变得更容易。 + 另一种使用PL/pgSQL进行开发的好方法,是使用有助于过程语言开发的 GUI 数据库访问工具。这类工具的一个例子是pgAdmin,当然也有其他工具。它们通常提供一些方便的特性,例如转义单引号,以及让重新创建和调试函数变得更容易。 @@ -3780,7 +3755,7 @@ $$ LANGUAGE plpgsql; 引号的处理 - 一个PL/pgSQL函数的代码在一个CREATE FUNCTION中被指定为一个字符串。如果你用通常的方式把该字符串写在单引号中间,那么该函数体中的任何单引号都必须被双写;同样任何反斜线也必须被双写(假定使用了转义字符串语法)。双写引号最多有点冗长,并且在更复杂的情况中代码会变得完全无法理解,因为你很容易发现你需要半打或者更多相邻的引号。我们推荐你转而把函数体写成一个美元引用的字符串(见)。在美元引用方法中,你从不需要双写任何引号。但是要注意为你需要的每一层嵌套选择一个不同的美元引用定界符。例如,你可能把CREATE FUNCTION命令写成: + 一个PL/pgSQL函数的代码在一个CREATE FUNCTION中被指定为一个字符串字面量。如果你用通常的方式把该字符串写在单引号中间,那么该函数体中的任何单引号都必须被双写;同样任何反斜线也必须被双写(假定使用了转义字符串语法)。双写引号本身就很繁琐,并且在更复杂的情况中代码会变得完全无法理解,因为你很容易发现你需要半打或者更多相邻的引号。我们推荐你转而把函数体写成一个美元引用的字符串(见)。在美元引用方法中,你从不需要双写任何引号。但是要注意为你需要的每一层嵌套选择一个不同的美元引用定界符。例如,你可能把CREATE FUNCTION命令写成: CREATE OR REPLACE FUNCTION testfunc(integer) RETURNS integer AS $PROC$ .... @@ -3817,7 +3792,7 @@ CREATE FUNCTION foo() RETURNS integer AS ' - 用于函数体内的字符串,例如: + 用于函数体内的字符串字面量,例如: a_output := ''Blah''; SELECT * FROM users WHERE f_name=''foobar''; @@ -3827,7 +3802,7 @@ SELECT * FROM users WHERE f_name=''foobar''; a_output := 'Blah'; SELECT * FROM users WHERE f_name='foobar'; - 这恰好就是PL/pgSQL在两种情况中会看到的。 + 这恰好就是PL/pgSQL解析器在两种情况中会看到的。 @@ -3850,7 +3825,7 @@ a_output := a_output || '' AND name LIKE ''''foobar'''' AND xyz'' a_output := a_output || $$ AND name LIKE 'foobar' AND xyz$$ - 要小心在这周围的任何美元引用定界符不只是$$。 + 要小心在这周围的任何美元引用定界符都不能是$$ @@ -3883,7 +3858,7 @@ a_output := a_output || $$ AND name LIKE 'foobar'$$ - 当你想在一个字符串常量(占 8 个引号)中有两个单引号时并且这会挨着该字符串常量的末尾(另外 2 个)。如果你正在写一个产生其他函数的函数(如中),你将很可能只需要这种。例如: + 当字符串常量中需要两个单引号(这需要 8 个引号),而且它们紧邻该字符串常量的末尾(还需 2 个引号)时。通常只有在编写生成其他函数的函数时(如所示),才会需要这种写法。例如: a_output := a_output || '' IF v_'' || referrer_keys.kind || '' LIKE '''''''''' @@ -3925,9 +3900,7 @@ a_output := a_output || $$ IF v_$$ || referrer_keys.kind || $$ LIKE '$$ 因此建议你在一个单独的开发环境中进行测试。 - - 根据需要设置 plpgsql.extra_warningsplpgsql.extra_errors,适当情况下,在开发和/或测试环境中可以设置为 "all"。 - + 建议在开发和/或测试环境中,根据需要将 plpgsql.extra_warningsplpgsql.extra_errors 设置为 "all" 这些额外的检查通过配置变量plpgsql.extra_warnings来启用警告, @@ -4041,18 +4014,16 @@ HINT: Make sure the query returns the exact list of columns. - PL/pgSQL与 PL/SQL 在许多方面都非常类似。它是一种块结构的、命令式的语言并且所有变量必须先被声明。赋值、循环和条件则很类似。在从PL/SQLPL/pgSQL移植时必须记住一些事情: - - + PL/pgSQL在许多方面都与 PL/SQL 类似。它是一种具有块结构的命令式语言,所有变量都必须声明。赋值、循环和条件语句也都很相似。在从PL/SQL移植到PL/pgSQL时,应当记住以下主要差异: - 如果一个 SQL 命令中使用的名字可能是一个表的列名或者是对一个函数中变量的引用,那么PL/SQL会将它当作一个列名。默认情况下, PL/pgSQL会抛出名称模糊的错误, 你可以指定plpgsql.variable_conflict=use_column来改变这一行为以匹配PL/SQL。如中所述。通常最好是首先避免这种歧义,但如果不得不移植依赖于该行为的大量代码,那么设置variable_conflict将是最好的方案。 + 如果一个 SQL 命令中使用的名字可能是一个表的列名或者是对一个函数中变量的引用,那么PL/SQL会将它当作一个列名。默认情况下, PL/pgSQL会抛出名称有歧义的错误, 你可以指定plpgsql.variable_conflict=use_column来改变这一行为以匹配PL/SQL。如中所述。通常最好是首先避免这种歧义,但如果不得不移植依赖于该行为的大量代码,那么设置variable_conflict可能是最好的方案。 - 在PostgreSQL中,函数体必须写成字符串文本。因此你需要使用美元符引用或者转义函数体中的单引号(见)。 + 在PostgreSQL中,函数体必须写成字符串字面量。因此你需要使用美元符引用或者转义函数体中的单引号(见)。 @@ -4142,13 +4113,13 @@ show errors; - 在PostgreSQL中,函数体被认为是一个字符串,所以你需要使用引号或者美元符号包围它。这代替了Oracle 方法中的用于终止的/。 + 在PostgreSQL中,函数体被认为是一个字符串字面量,所以你需要使用引号或者美元引用定界符包围它。这代替了Oracle 方法中的用于终止的/ - 在PostgreSQL中没有show errors命令, 并且也不需要这个命令,因为错误是自动报告的。 + 在PostgreSQL中没有show errors命令, 并且也不需要这个命令,因为错误是自动报告的。 @@ -4180,9 +4151,7 @@ $$ LANGUAGE plpgsql; 从<application>PL/SQL</application>移植一个创建另一个函数的函数到<application>PL/pgSQL</application> - - 下面的过程从一个SELECT语句抓取行,并且为了效率而构建一个带有IF语句中结果的大型函数。 - + 下面的过程从 SELECT 语句读取行,并将结果写入 IF 语句,从而构造一个大型函数,以提高效率。 这是 Oracle 版本: @@ -4213,8 +4182,7 @@ show errors; - - 这里是PostgreSQL的版本: + 下面是这个函数的最终移植结果,目标数据库为PostgreSQL CREATE OR REPLACE PROCEDURE cs_update_referrer_type_proc() AS $func$ DECLARE @@ -4247,9 +4215,7 @@ BEGIN EXECUTE func_cmd; END; $func$ LANGUAGE plpgsql; - - 请注意,这里先单独构造了函数体,再通过 quote_literal 传入,以便把其中的引号正确双写。之所以需要这种技术,是因为我们无法安全地使用美元引用来定义新函数:我们并不确切知道会从 referrer_key.key_string 字段插入什么字符串。(这里假定 referrer_key.kind 始终可信地只会是 hostdomainurl,但 referrer_key.key_string 可能是任意内容,尤其可能包含美元符号。)实际上,这个函数比 Oracle 原版还有改进,因为当 referrer_key.key_stringreferrer_key.referrer_type 中包含引号时,它也不会生成无效代码。 - +注意,这里单独构造函数体,然后将其传给quote_literal,使其中的每个引号都变成两个。这种技术是必需的,因为不能安全地使用美元引用来定义新函数:我们无法确定会插入什么字符串,其来源是referrer_key.key_string字段。(这里假定referrer_key.kind可信,其值总是hostdomainurl,但是referrer_key.key_string可能是任何内容,尤其可能包含美元符号。)这个函数实际上改进了 Oracle 原版:当referrer_key.key_stringreferrer_key.referrer_type中包含引号时,它也不会生成有问题的代码。 @@ -4269,7 +4235,7 @@ $func$ LANGUAGE plpgsql; CREATE OR REPLACE PROCEDURE cs_parse_url( v_url IN VARCHAR2, - v_host OUT VARCHAR2, -- 这将被传回去 + v_host OUT VARCHAR2, -- 这个值将被返回 v_path OUT VARCHAR2, -- 这个也是 v_query OUT VARCHAR2) -- 还有这个 IS @@ -4312,9 +4278,9 @@ show errors; CREATE OR REPLACE FUNCTION cs_parse_url( v_url IN VARCHAR, - v_host OUT VARCHAR, -- 这将被传递回去 + v_host OUT VARCHAR, -- 这个值将被返回 v_path OUT VARCHAR, -- 这个也是 - v_query OUT VARCHAR) -- 以及这个 + v_query OUT VARCHAR) -- 还有这个 AS $$ DECLARE a_pos1 INTEGER; @@ -4357,7 +4323,7 @@ SELECT * FROM cs_parse_url('http://foobar.com/query.cgi?baz'); - 展示了如何移植一个使用了多种 Oracle 特性的过程。 + 展示了如何移植一个使用了多种 Oracle 专属特性的过程。 @@ -4397,7 +4363,7 @@ show errors - 这是我们如何将这个过程移植到PL/pgSQL: + 下面展示了如何将这个过程移植到PL/pgSQL CREATE OR REPLACE PROCEDURE cs_create_job(v_job_id integer) AS $$ @@ -4472,7 +4438,7 @@ EXCEPTION END; - 如果你正在移植一个以这种方式使用SAVEPOINTROLLBACK TO的 Oracle 过程,工作会比较简单:只要忽略SAVEPOINTROLLBACK TO即可。如果你的 Oracle 过程以不同方式使用SAVEPOINTROLLBACK TO,那就需要认真思考了。 + 如果你正在移植一个以这种方式使用SAVEPOINTROLLBACK TO的 Oracle 过程,工作会比较简单:只要省略SAVEPOINTROLLBACK TO即可。如果你的 Oracle 过程以不同方式使用SAVEPOINTROLLBACK TO,那就需要认真思考了。 @@ -4489,11 +4455,11 @@ END; 优化 <application>PL/pgSQL</application> 函数 - PostgreSQL提供了两种函数创建修饰符来优化执行:volatility(对于给定的相同参数,函数是否总是返回相同的结果)以及strictness (如果任何参数为空,函数是否返回空)。详见参考页。 + PostgreSQL提供了两种函数创建修饰符来优化执行:volatility(对于给定的相同参数,函数是否总是返回相同的结果)以及strictness (如果任何参数为空值,函数是否返回空值)。详见参考页。 - 在利用这些优化属性时,你的CREATE FUNCTION语句应该看起来像这样: + 在利用这些优化属性时,你的CREATE FUNCTION语句可能像这样: CREATE FUNCTION foo(...) RETURNS integer AS $$ diff --git a/zh/19/plpython.sgml b/zh/19/plpython.sgml index 299b1bfb..faf153b9 100644 --- a/zh/19/plpython.sgml +++ b/zh/19/plpython.sgml @@ -45,7 +45,7 @@ CREATE FUNCTION funcname (argument-list) RETURNS return-type AS $$ - # PL/Python function body + # PL/Python 函数体 $$ LANGUAGE plpython3u; @@ -85,7 +85,7 @@ def __plpython_procedure_pymax_23456(): CREATE FUNCTION pystrip(x text) RETURNS text AS $$ - x = x.strip() # error + x = x.strip() # 错误 return x $$ LANGUAGE plpython3u; @@ -95,7 +95,7 @@ CREATE FUNCTION pystrip(x text) RETURNS text AS $$ global x - x = x.strip() # ok now + x = x.strip() # 现在可以正常工作 return x $$ LANGUAGE plpython3u; @@ -216,7 +216,7 @@ $$ LANGUAGE plpython3u; 如果把 SQL 空值空值在 PL/Python 中传给函数,参数值在 Python 中会显示为None。例如,中展示的pymax定义在处理空输入时就会返回错误结果。我们可以在函数定义中添加STRICT,让PostgreSQL做出更合理的处理:如果传入空值,函数根本不会被调用,而是自动返回空结果。另一种办法是在函数体中检查空输入: + sortas="PL/Python">在 PL/Python 中传给函数,参数值在 Python 中会显示为None。例如,中展示的pymax定义在处理空值输入时就会返回错误结果。我们可以在函数定义中添加STRICT,让PostgreSQL做出更合理的处理:如果传入空值,函数根本不会被调用,而是自动返回空值结果。另一种办法是在函数体中检查空值输入: CREATE FUNCTION pymax (a integer, b integer) @@ -329,21 +329,21 @@ CREATE TYPE named_value AS ( ); - 组合结果可以按以下形式返回: + 复合结果可以按以下形式返回: 序列类型(元组或列表,但不能是集合,因为集合不可通过索引访问) - 返回的序列对象必须包含与组合结果类型字段数相同的项。索引为 0 的项会赋给复合类型的第一个字段,索引为 1 的项赋给第二个字段,依此类推。例如: + 返回的序列对象必须包含与复合结果类型字段数相同的项。索引为 0 的项会赋给复合类型的第一个字段,索引为 1 的项赋给第二个字段,依此类推。例如: CREATE FUNCTION make_pair (name text, value integer) RETURNS named_value AS $$ return ( name, value ) - # or alternatively, as list: return [ name, value ] + # 也可以使用列表: return [ name, value ] $$ LANGUAGE plpython3u; @@ -391,7 +391,7 @@ AS $$ self.value = v return named_value(name, value) - # or simply + # 或者简写为 class nv: pass nv.name = name nv.value = value @@ -452,8 +452,8 @@ CREATE TYPE greeting AS ( CREATE FUNCTION greet (how text) RETURNS SETOF greeting AS $$ - # return tuple containing lists as composite types - # all other combinations work also + # 返回包含列表的元组,以列表表示复合类型 + # 其他组合方式也都可用 return ( [ how, "World" ], [ how, "PostgreSQL" ], [ how, "PL/Python" ] ) $$ LANGUAGE plpython3u; @@ -511,7 +511,7 @@ $$ LANGUAGE plpython3u; - 也支持带OUT参数的返回集函数(使用RETURNS SETOF record)。例如: + 也支持带OUT参数的集合返回函数(使用RETURNS SETOF record)。例如: CREATE FUNCTION multiout_simple_setof(n integer, OUT integer, OUT integer) RETURNS SETOF record AS $$ return [(1, 2)] * n @@ -546,7 +546,7 @@ SELECT * FROM multiout_simple_setof(3); DO $$ - # PL/Python code + # PL/Python 代码 $$ LANGUAGE plpython3u; @@ -664,7 +664,7 @@ $$ LANGUAGE plpython3u; 事件触发器 - in PL/Python + 在 PL/Python 中 @@ -859,7 +859,7 @@ CREATE FUNCTION usesavedplan() RETURNS trigger AS $$ else: plan = plpy.prepare("SELECT 1") SD["plan"] = plan - # rest of function + # 函数的其余部分 $$ LANGUAGE plpython3u; @@ -876,11 +876,11 @@ $$ LANGUAGE plpython3u; - 游标对象提供fetch方法,它接受一个整数参数并返回结果对象。每次调用fetch,返回对象都会包含下一批行,数量不会超过该参数值。一旦所有行都已取完,fetch就会开始返回空结果对象。游标对象还提供迭代器接口,每次产生一行,直到所有行为止。以这种方式获取的数据不会作为结果对象返回,而是以字典形式返回,每个字典对应一行结果。 + 游标对象提供fetch方法,它接受一个整数参数并返回结果对象。每次调用fetch,返回对象都会包含下一批行,数量不会超过该参数值。一旦所有行都已取完,fetch就会开始返回空结果对象。游标对象还提供迭代器接口,每次产生一行,直到取完所有行。以这种方式获取的数据不会作为结果对象返回,而是以字典形式返回,每个字典对应一行结果。 - 下面示例展示了如何处理大表中的数据: + 下面示例展示了处理大表中数据的两种方式: CREATE FUNCTION count_odd_iterator() RETURNS integer AS $$ odd = 0 @@ -906,7 +906,7 @@ $$ LANGUAGE plpython3u; CREATE FUNCTION count_odd_prepared() RETURNS integer AS $$ odd = 0 plan = plpy.prepare("SELECT num FROM largetable WHERE num % $1 <> 0", ["integer"]) -rows = list(plpy.cursor(plan, [2])) # or: = list(plan.cursor([2])) +rows = list(plpy.cursor(plan, [2])) # 或者:= list(plan.cursor([2])) return len(rows) $$ LANGUAGE plpython3u; @@ -1059,7 +1059,7 @@ CALL transaction_test1(); - 实用函数 + 辅助函数 plpy模块还提供以下函数: @@ -1113,7 +1113,7 @@ PL/Python function "raise_custom_exception" - 另一组实用函数是plpy.quote_literal(string)plpy.quote_nullable(string)以及plpy.quote_ident(string)。它们等价于中描述的内置引用函数。在构造临时查询时,这些函数很有用。中动态 SQL 的一个 PL/Python 等价写法如下: + 另一组辅助函数是plpy.quote_literal(string)plpy.quote_nullable(string)以及plpy.quote_ident(string)。它们等价于中描述的内置加引号函数。在构造临时查询时,这些函数很有用。中动态 SQL 的一个 PL/Python 等价写法如下: plpy.execute("UPDATE tbl SET %s = %s WHERE key = %s" % ( plpy.quote_ident(colname), diff --git a/zh/19/pltcl.sgml b/zh/19/pltcl.sgml index 9c78fe04..06178f8f 100644 --- a/zh/19/pltcl.sgml +++ b/zh/19/pltcl.sgml @@ -13,7 +13,7 @@ - PL/Tcl 是一种适用于 PostgreSQL 数据库系统的可载入的过程语言,它允许使用 Tcl 语言 来编写 PostgreSQL 函数和过程。 + PL/Tcl 是一种适用于 PostgreSQL 数据库系统的可加载的过程语言,它允许使用 Tcl 语言 来编写 PostgreSQL 函数和过程。 @@ -54,7 +54,7 @@ CREATE FUNCTION funcname (argument-types) RETURNS return-type AS $$ - # PL/Tcl function body + # PL/Tcl 函数体 $$ LANGUAGE pltcl; @@ -75,11 +75,11 @@ CREATE FUNCTION tcl_max(integer, integer) RETURNS integer AS $$ $$ LANGUAGE pltcl STRICT; - 注意STRICT子句,它让我们不必考虑空输入值:如果传入的是空值,函数根本不会被调用,而是会自动返回空结果。 + 注意STRICT子句,它让我们不必考虑空值输入:如果传入的是空值,函数根本不会被调用,而是会自动返回空值结果。 - 在非严格函数中,如果某个参数的实际值为空,对应的$n变量会被设置为空串。要检测某个特定参数是否为空,可使用函数argisnull。例如,假设我们希望在tcl_max的两个参数中一个为空、一个非空时返回非空参数,而不是返回空值: + 在非严格函数中,如果某个参数的实际值为空值,对应的$n变量会被设置为空串。要检测某个特定参数是否为空值,可使用函数argisnull。例如,假设我们希望在tcl_max的两个参数中一个为空值、一个非空值时返回非空值参数,而不是返回空值: CREATE FUNCTION tcl_max(integer, integer) RETURNS integer AS $$ @@ -99,7 +99,7 @@ $$ LANGUAGE pltcl; - 复合类型参数会作为 Tcl 数组传递给函数。数组元素名就是该复合类型的属性名。如果传入行中的某个属性为 NULL,它就不会出现在数组中。下面是一个示例: + 复合类型参数会作为 Tcl 数组传递给函数。数组元素名就是该复合类型的属性名。如果传入行中的某个属性为空值,它就不会出现在数组中。下面是一个示例: CREATE TABLE employee ( @@ -185,7 +185,7 @@ $$ LANGUAGE pltcl; PL/Tcl 中的数据值 - 提供给 PL/Tcl 函数代码的参数值,只是将输入参数转换成文本形式(就像用SELECT语句将它们显示出来一样)。反过来,returnreturn_next命令会接受任何字符串,只要它是该函数声明结果类型或组合结果类型中指定列的可接受输入格式。 + 提供给 PL/Tcl 函数代码的参数值,只是将输入参数转换成文本形式(就像用SELECT语句将它们显示出来一样)。反过来,returnreturn_next命令会接受任何字符串,只要它是该函数声明结果类型或复合结果类型中指定列的可接受输入格式。 @@ -195,8 +195,8 @@ $$ LANGUAGE pltcl; PL/Tcl 中的全局数据 - global data - in PL/Tcl + 全局数据 + 在 PL/Tcl 中 @@ -234,7 +234,7 @@ $$ LANGUAGE pltcl; - 执行以字符串形式给出的 SQL 命令。命令出错时会引发错误。否则,spi_exec的返回值是该命令处理的行数(选出、插入、更新或删除的行),如果命令是实用程序语句则返回零。此外,如果命令是SELECT语句,则所选列的值会按下文所述放入 Tcl 变量中。 + 执行以字符串形式给出的 SQL 命令。命令出错时会引发错误。否则,spi_exec的返回值是该命令处理的行数(选出、插入、更新或删除的行),如果命令是工具语句则返回零。此外,如果命令是SELECT语句,则所选列的值会按下文所述放入 Tcl 变量中。 @@ -275,7 +275,7 @@ spi_exec -array C "SELECT * FROM pg_class" { - 如果查询结果中的某一列为空,则对应的目标变量会被unset,而不是被设值。 + 如果查询结果中的某一列为空值,则对应的目标变量会被unset,而不是被设值。 @@ -287,7 +287,7 @@ spi_exec -array C "SELECT * FROM pg_class" { 准备并保存一个查询计划以供后续执行。保存的计划会在当前会话的整个生命周期内保留。 准备查询 - 在PL/Tcl中 + 在 PL/Tcl 中 @@ -317,7 +317,7 @@ spi_exec -array C "SELECT * FROM pg_class" { 可选的-nulls值是由空格和'n'字符组成的字符串,用来告诉spi_execp哪些参数是空值。 - 如果给出,它的长度必须与value-list完全相同。如果未给出,则所有参数值都视为非空。 + 如果给出,它的长度必须与value-list完全相同。如果未给出,则所有参数值都视为非空值。 @@ -331,7 +331,7 @@ spi_exec -array C "SELECT * FROM pg_class" { CREATE FUNCTION t1_count(integer, integer) RETURNS integer AS $$ if {![ info exists GD(plan) ]} { - # prepare the saved plan on the first call + # 在首次调用时准备并保存计划 set GD(plan) [ spi_prepare \ "SELECT count(*) AS cnt FROM t1 WHERE num >= \$1 AND num <= \$2" \ [ list int4 int4 ] ] @@ -367,7 +367,7 @@ $$ LANGUAGE pltcl; 将给定字符串中的所有单引号和反斜杠字符都加倍。 - 这可用于安全地引用那些要插入到传给spi_execspi_prepare的 SQL 命令中的字符串。 + 这可用于安全地为那些要插入到传给spi_execspi_prepare的 SQL 命令中的字符串加引号。 例如,考虑如下 SQL 命令字符串: @@ -393,7 +393,7 @@ SELECT 'doesn''t' AS ret "SELECT '[ quote $val ]' AS ret" - spi_execp的一个优点是,你不必像这样对参数值做引用,因为这些参数永远不会作为 SQL 命令字符串的一部分被解析。 + spi_execp的一个优点是,你不必像这样给参数值加引号,因为这些参数永远不会作为 SQL 命令字符串的一部分被解析。 @@ -404,7 +404,7 @@ SELECT 'doesn''t' AS ret elog level msg elog - 在PL/Tcl中 + 在 PL/Tcl 中 @@ -436,8 +436,8 @@ SELECT 'doesn''t' AS ret PL/Tcl 中的触发器函数 - trigger - in PL/Tcl + 触发器 + 在 PL/Tcl 中 @@ -525,7 +525,7 @@ SELECT 'doesn''t' AS ret $NEW - 对于INSERTUPDATE动作,这是一个包含新表行值的关联数组;对于DELETE则为空。该数组以列名为索引。值为 NULL 的列不会出现在数组中。对于语句级触发器,不会设置这个变量。 + 对于INSERTUPDATE动作,这是一个包含新表行值的关联数组;对于DELETE则为空。该数组以列名为索引。值为空值的列不会出现在数组中。对于语句级触发器,不会设置这个变量。 @@ -534,7 +534,7 @@ SELECT 'doesn''t' AS ret $OLD - 对于UPDATEDELETE动作,这是一个包含旧表行值的关联数组;对于INSERT则为空。该数组以列名为索引。值为 NULL 的列不会出现在数组中。对于语句级触发器,不会设置这个变量。 + 对于UPDATEDELETE动作,这是一个包含旧表行值的关联数组;对于INSERT则为空。该数组以列名为索引。值为空值的列不会出现在数组中。对于语句级触发器,不会设置这个变量。 @@ -598,8 +598,8 @@ CREATE TRIGGER trig_mytab_modcount BEFORE INSERT OR UPDATE ON mytab PL/Tcl 中的事件触发器函数 - event trigger - in PL/Tcl + 事件触发器 + 在 PL/Tcl 中 @@ -615,7 +615,7 @@ CREATE TRIGGER trig_mytab_modcount BEFORE INSERT OR UPDATE ON mytab $TG_event - 触发器因其而被触发的事件名称。 + 该触发器所针对的事件名称。 @@ -624,7 +624,7 @@ CREATE TRIGGER trig_mytab_modcount BEFORE INSERT OR UPDATE ON mytab $TG_tag - 触发器因其而被触发的命令标签。 + 该触发器所针对的命令标签。 @@ -632,7 +632,7 @@ CREATE TRIGGER trig_mytab_modcount BEFORE INSERT OR UPDATE ON mytab - 事件触发器函数的返回值会被忽略。 + 触发器函数的返回值会被忽略。 @@ -653,8 +653,8 @@ CREATE EVENT TRIGGER tcl_a_snitch ON ddl_command_start EXECUTE FUNCTION tclsnitc PL/Tcl 中的错误处理 - exceptions - in PL/Tcl + 异常 + 在 PL/Tcl 中 @@ -682,9 +682,9 @@ if {[catch { spi_exec $sql_command }]} { if {[lindex $::errorCode 0] == "POSTGRES"} { array set errorArray $::errorCode if {$errorArray(condition) == "undefined_table"} { - # deal with missing table + # 处理表不存在的情况 } else { - # deal with some other type of SQL error + # 处理其他类型的 SQL 错误 } } } @@ -698,8 +698,8 @@ if {[catch { spi_exec $sql_command }]} { PL/Tcl 中的显式子事务 - subtransactions - in PL/Tcl + 子事务 + 在 PL/Tcl 中 @@ -797,7 +797,7 @@ CALL transaction_test1(); pltcl.start_proc (string) - pltcl.start_proc configuration parameter + pltcl.start_proc 配置参数 @@ -825,7 +825,7 @@ CALL transaction_test1(); pltclu.start_proc (string) - pltclu.start_proc configuration parameter + pltclu.start_proc 配置参数 diff --git a/zh/19/postgres-fdw.sgml b/zh/19/postgres-fdw.sgml index 1e5749d8..c5def843 100644 --- a/zh/19/postgres-fdw.sgml +++ b/zh/19/postgres-fdw.sgml @@ -38,7 +38,7 @@ - 对于每个需要被允许访问各外部服务器的数据库用户,使用 + 对于每个需要获准访问各个外部服务器的数据库用户,使用 创建用户映射。将要使用的 远程用户名和密码指定为用户映射的 userpassword 选项。 @@ -56,7 +56,7 @@ - 现在,只需从外部表执行 SELECT,即可访问其底层远程表中 + 现在,只需对外部表执行 SELECT,即可访问其底层远程表中 存储的数据。也可以使用 INSERTUPDATEDELETECOPYTRUNCATE 修改远程表。 @@ -120,8 +120,7 @@ application_name 可以出现在连接选项和 - 中的任一处,或同时出现在 - 二者中。 + 中的任一处,或同时出现在二者中。 如果两者都存在,postgres_fdw.application_name 会覆盖连接设置。与 libpq 不同, postgres_fdw 允许 application_name @@ -250,7 +249,7 @@ OPTIONS (ADD password_required 'false'); - fdw_startup_cost (floating point) + fdw_startup_cost (浮点数) 该选项可为外部服务器指定,是一个浮点值,会被加到该服务器上任何 @@ -261,7 +260,7 @@ OPTIONS (ADD password_required 'false'); - fdw_tuple_cost (floating point) + fdw_tuple_cost (浮点数) 该选项可为外部服务器指定,是一个浮点值,用作该服务器上外部表扫描的 @@ -362,7 +361,7 @@ OPTIONS (ADD password_required 'false'); 该选项是一个以逗号分隔的 PostgreSQL 扩展 名称列表,这些扩展必须在本地和远程服务器上都已安装且版本兼容。 - 属于列出扩展且为 immutable 的函数和操作符,将被视为可下推到远程服务器 + 属于列出扩展且不可变的函数和操作符,将被视为可下推到远程服务器 执行。该选项只能为外部服务器指定,不能按表指定。 @@ -404,7 +403,7 @@ OPTIONS (ADD password_required 'false'); - 该选项也适用于向外部表执行 COPY。在这种情况下, + 该选项也适用于向外部表复制数据。在这种情况下, postgres_fdw 实际一次复制的行数会以与插入场景 类似的方式确定,但由于 COPY 命令的实现限制, 最多只能为 1000 行。 @@ -596,8 +595,7 @@ OPTIONS (ADD password_required 'false'); COLLATE 选项。默认值为 true。 如果远程服务器的排序规则名称集合与本地服务器不同,则可能需要关闭此 选项;如果远程服务器运行在不同操作系统上,这种情况尤其可能发生。 - 不过,如果这样做,导入表列的排序规则极有可能与底层数据不匹配, - 从而导致查询行为异常。 + 不过,如果这样做,导入表列的排序规则就存在与底层数据不匹配的严重风险,从而导致查询行为异常。 @@ -692,7 +690,7 @@ OPTIONS (ADD password_required 'false'); 该选项控制 postgres_fdw 在连接到外部服务器时 是否使用 SCRAM 透传认证。该选项可为外部服务器或用户映射指定。 用户映射的设置会覆盖外部服务器的设置。使用 SCRAM 透传认证时, - postgres_fdw 使用 SCRAM 哈希后的凭据,而不是 + postgres_fdw 使用经 SCRAM Hash 处理的凭据,而不是 明文用户密码连接远程服务器。这样可以避免在 PostgreSQL 系统目录中 存储明文用户密码。 @@ -725,13 +723,13 @@ OPTIONS (ADD password_required 'false'); 运行 postgres_fdw 的服务器与远程服务器, 必须针对用于在 postgres_fdw 上认证到外部 - 服务器的该用户,拥有完全相同的 SCRAM secret(加密密码) + 服务器的该用户,拥有完全相同的 SCRAM 凭据(加密密码) (盐值和迭代次数都必须相同,而不仅仅是密码相同)。 因而,如果要建立到多个主机的 FDW 连接,例如用于分区外部表或分片, - 则所有主机都必须为相关用户保存完全相同的 SCRAM secret。 + 则所有主机都必须为相关用户保存完全相同的 SCRAM 凭据。 @@ -937,6 +935,31 @@ postgres=# SELECT postgres_fdw_disconnect_all(); + + 订阅管理 + + + postgres_fdw 使用与中描述相同的选项来支持订阅连接。 + + + + 例如,假设远程服务器 foreign-host 上有一个发布 + testpub: + +CREATE SERVER subscription_server FOREIGN DATA WRAPPER postgres_fdw OPTIONS (host 'foreign-host', dbname 'foreign_db'); +CREATE USER MAPPING FOR local_user SERVER subscription_server OPTIONS (user 'foreign_user', password 'password'); +CREATE SUBSCRIPTION my_subscription SERVER subscription_server PUBLICATION testpub; + + + + + 要创建订阅,用户必须是角色的成员,并且对该服务器 + 具有 USAGE 权限。 + + + 事务管理 @@ -975,8 +998,7 @@ postgres=# SELECT postgres_fdw_disconnect_all(); - 请注意,postgres_fdw 当前不支持将远程事务预备为 - 两阶段提交。 + 请注意,postgres_fdw 当前不支持为两阶段提交预备远程事务。 @@ -987,9 +1009,9 @@ postgres=# SELECT postgres_fdw_disconnect_all(); postgres_fdw 会尽力优化远程查询,以减少从外部 服务器传输的数据量。这是通过将查询的 WHERE 子句发送到 远程服务器执行,以及不获取当前查询不需要的表列来实现的。为降低查询被 - 错误执行的风险,除非 WHERE 子句仅使用内置数据类型、 - 操作符和函数,或属于外部服务器 extensions 选项列出的 - 扩展,否则不会将其发送到远程服务器。这类子句中的操作符和函数还必须是 + 错误执行的风险,只有当 WHERE 子句使用的所有数据类型、 + 操作符和函数都是内置的,或属于外部服务器 extensions + 选项列出的扩展时,才会将该子句发送到远程服务器。这类子句中的操作符和函数还必须是 IMMUTABLE。对于 UPDATEDELETE 查询,postgres_fdw 会在 查询中不存在无法发送到远程服务器的 WHERE 子句、没有 @@ -1093,30 +1115,7 @@ postgres=# SELECT postgres_fdw_disconnect_all(); - - 订阅管理 - - - postgres_fdw 使用与中描述相同的选项来支持订阅连接。 - - - - 例如,假设远程服务器 foreign-host 上有一个发布 - testpub: - -CREATE SERVER subscription_server FOREIGN DATA WRAPPER postgres_fdw OPTIONS (host 'foreign-host', dbname 'foreign_db'); -CREATE USER MAPPING FOR local_user SERVER subscription_server OPTIONS (user 'foreign_user', password 'password'); -CREATE SUBSCRIPTION my_subscription SERVER subscription_server PUBLICATION testpub; - - - - 要创建订阅,用户必须是角色的成员,并且对该服务器 - 具有 USAGE 权限。 - - 等待事件 @@ -1164,7 +1163,7 @@ CREATE SUBSCRIPTION my_subscription SERVER subscription_server PUBLICATION testp postgres_fdw.application_name (string) - postgres_fdw.application_name configuration parameter + postgres_fdw.application_name 配置参数 @@ -1178,7 +1177,7 @@ CREATE SUBSCRIPTION my_subscription SERVER subscription_server PUBLICATION testp postgres_fdw.application_name 可以是任意长度的任意 字符串,甚至可以包含非 ASCII 字符。不过,当它被传递并作为外部服务器中 的 application_name 使用时,请注意它会被截断到少于 - NAMEDATALEN 个字符。所有不可打印 ASCII 字符都会被 + NAMEDATALEN 个字符。除可打印 ASCII 字符以外的所有字符都会被 替换为C 风格的十六进制转义。 有关细节见 。 @@ -1232,7 +1231,7 @@ CREATE SUBSCRIPTION my_subscription SERVER subscription_server PUBLICATION testp %% - 字面值 % + 字面字符 % diff --git a/zh/19/protocol.sgml b/zh/19/protocol.sgml index e71aedd2..cbccec3e 100644 --- a/zh/19/protocol.sgml +++ b/zh/19/protocol.sgml @@ -317,9 +317,7 @@ 前端现在必须发送一个 PasswordMessage,其中包含密码;该密码先与用户名一起经过 MD5 加密,再使用 AuthenticationMD5Password 消息中指定的 4 字节随机盐重新加密。如果密码正确,服务器响应 AuthenticationOk;否则响应 ErrorResponse。实际的 PasswordMessage 可以用 SQL 计算:concat('md5', md5(concat(md5(concat(password, username)), random-salt)))。(请记住 md5() 函数返回的是十六进制字符串。) - - 对 MD5 加密密码的支持已弃用,并将在未来版本 PostgreSQL 中移除。关于迁移到其他密码类型,请参阅 。 - + 对 MD5 加密密码的支持已弃用,并将在PostgreSQL的未来版本中移除。迁移到其他密码类型的详细信息见 @@ -922,7 +920,7 @@ SELCT 1/0; - 目前,系统会为以下参数发送 ParameterStatus: + 目前,会为一组固定的参数生成 ParameterStatus,参数如下: application_name client_encoding @@ -940,10 +938,8 @@ SELCT 1/0; standard_conforming_strings TimeZone - (default_transaction_read_onlyin_hot_standby 在 14 之前不报告; - scram_iterations 在 16 之前不报告; - search_path 在 18 之前不报告。) - 注意 server_versionserver_encodinginteger_datetimes 是启动后不可更改的伪参数。未来该集合可能变化,甚至可能变为可配置。因此,前端应忽略其不理解或不关心的 ParameterStatus。 + (14 之前的版本不报告 default_transaction_read_onlyin_hot_standby;16 之前的版本不报告 scram_iterations;18 之前的版本不报告 search_path。) + 注意,server_versionserver_encodinginteger_datetimes 是启动后不能改变的伪参数。这组参数将来可能变化,甚至可能变为可配置。因此,前端应直接忽略其不理解或不关心的参数的 ParameterStatus。 @@ -1458,7 +1454,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" CREATE_REPLICATION_SLOT slot_name [ TEMPORARY ] { PHYSICAL | LOGICAL output_plugin } [ ( option [, ...] ) ] - 创建复制槽 + CREATE_REPLICATION_SLOT @@ -1516,15 +1512,6 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - - FAILOVER [ boolean ] - - - 若为 true,则该复制槽会同步到备库,从而在故障切换后恢复逻辑复制。默认值为 false。 - - - - RESERVE_WAL [ boolean ] @@ -1541,13 +1528,14 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" SNAPSHOT { 'export' | 'use' | 'nothing' } - - 决定在逻辑复制槽初始化期间如何处理所创建的快照。'export' - 这是默认选项,将导出快照供其他会话使用。此选项不能在事务内使用。 - 'use'将为执行命令的当前事务使用快照。此选项必须在事务中使用, - 并且CREATE_REPLICATION_SLOT必须是在该事务中运行的第一个命令。 - 最后,'nothing'将像往常一样仅用于逻辑解码使用快照,但不会执行其他操作。 - + 决定如何处理初始化逻辑复制槽时创建的快照。默认选项 'export' 会导出快照供其他会话使用,此选项不能在事务内使用。'use' 会将快照用于执行该命令的当前事务;此选项必须在事务内使用,且 CREATE_REPLICATION_SLOT 必须是该事务中执行的第一条命令。最后,'nothing' 只会像平常一样将快照用于逻辑解码,不会对其执行其他操作。 + + + + + FAILOVER [ boolean ] + + 若为 true,则允许该复制槽同步到备库,以便在故障切换后恢复逻辑复制。默认值为 false。 @@ -1578,7 +1566,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" snapshot_name (text) - 该命令导出的快照标识符。该快照在此连接上执行下一条命令之前,或复制连接关闭之前有效。如果所创建的是物理复制槽,则为 null。 + 该命令导出的快照标识符。该快照在此连接上执行下一条命令之前,或复制连接关闭之前有效。如果所创建的是物理复制槽,则为空值。 @@ -1587,7 +1575,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" output_plugin (text) - 新建复制槽所使用的输出插件名称。如果所创建的是物理复制槽,则为 null。 + 新建复制槽所使用的输出插件名称。如果所创建的是物理复制槽,则为空值。 @@ -2229,7 +2217,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 指示服务器开始流式传输基本备份。 + 指示服务器开始流式传输基础备份。 在备份开始之前,系统将自动进入备份模式,并在备份完成后退出备份模式。 接受以下选项: @@ -2240,7 +2228,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" 设置备份的标签。如果未指定,则将使用base backup作为备份标签。 - 标签的引用规则与标准SQL字符串相同。 + 标签的引号使用规则与标准SQL字符串相同。 @@ -2280,11 +2268,11 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 如果设置为true,则请求生成进度报告所需的信息。这将在每个表空间的头部发送一个近似大小, + 如果设置为true,则请求生成进度报告所需的信息。这将在每个表空间的首部发送一个近似大小, 可用于计算流式传输的进度。这是通过在传输开始之前先枚举所有文件大小来计算的, 可能会对性能产生负面影响。特别是,在流式传输数据之前可能需要更长的时间。 由于备份期间数据库文件可能会发生变化,因此大小仅为近似值, - 在近似值和实际文件发送之间可能会增长或缩小。默认值为false。 + 在估算与实际发送文件之间的这段时间里可能会增长或缩小。默认值为false。 @@ -2294,7 +2282,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 设置在基本备份开始时执行的检查点类型。默认值为spread。 + 设置在基础备份开始时执行的检查点类型。默认值为spread @@ -2303,9 +2291,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" WAL [ boolean ] - - 如果设置为true,则在备份中包含必要的WAL段。这将包括在开始和停止备份之间的所有文件在基本目录tar文件的pg_wal目录中。默认值为false。 - + 如果设置为 true,则在备份中包含必要的 WAL 段。这会把开始备份到停止备份之间的所有文件放入基础目录 tar 文件内的pg_wal目录中。默认值为 false。 @@ -2393,7 +2379,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 如果为true,则在进行基本备份时验证校验和(如果已启用)。如果为false,则跳过此步骤。默认值为true。 + 如果为true,则在进行基础备份时验证校验和(如果已启用)。如果为false,则跳过此步骤。默认值为true。 @@ -2408,7 +2394,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" 除了可能包含的任何WAL文件。它还存储每个文件的大小、最后修改时间, 以及可选的校验和。 值为force-encode会强制对所有文件名进行十六进制编码; - 否则,仅对文件名为非UTF8八位序列的文件执行此类型的编码。 + 否则,仅对文件名为非 UTF8 字节序列的文件执行此类型的编码。 force-encode主要用于测试目的,以确保读取备份清单的客户端 能够处理这种情况。为了与之前的版本兼容,默认值为MANIFEST 'no' @@ -2450,14 +2436,14 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" 第二个普通结果集中的每个表空间都有一行。 - 这一行中的字段是: + 这一行中的字段是: spcoid (oid) - 表空间的OID,如果是基本目录则为null。 + 表空间的OID,如果是基础目录则为null。 @@ -2466,7 +2452,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" spclocation (text) - 表空间目录的完整路径,如果是基本目录则为null。 + 表空间目录的完整路径,如果是基础目录则为null。 @@ -2490,7 +2476,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - new archive (B) + 新归档 (B) @@ -2522,7 +2508,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 对于主数据目录,使用空字符串。对于其他表空间,使用从创建此归档的目录的完整路径。 + 对于主数据目录,使用空字符串。对于其他表空间,使用创建此归档所用目录的完整路径。 @@ -2532,7 +2518,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - manifest (B) + 清单 (B) @@ -2581,7 +2567,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - progress report (B) + 进度报告 (B) @@ -2639,13 +2625,11 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - - 不记录 WAL 的关系(Unlogged表),除了需要在恢复时重新创建(空的)不记录 WAL 的关系的init fork。 - + 不记录 WAL 的关系,但不包括恢复时重新创建(空的)不记录 WAL 的关系所需的初始化分支。 - pg_wal,包括子目录。如果备份包含WAL文件,则将包含pg_wal的合成版本,但它只包含备份工作所需的文件,而不包含其余内容。 + pg_wal,包括子目录。如果备份包含WAL文件,则将包含pg_wal的合成版本,但它只包含使备份可用所需的文件,而不包含其余内容。 @@ -2658,7 +2642,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 除了常规文件和目录之外的文件,如符号链接(除了上述列出的目录之外的符号链接)以及特殊设备和操作系统文件,将被跳过。(pg_tblspc中的符号链接将被保留。) + 除了普通文件和目录之外的文件,如符号链接(除了上述列出的目录之外的符号链接)以及特殊设备和操作系统文件,将被跳过。(pg_tblspc中的符号链接将被保留。) @@ -2688,14 +2672,12 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 逻辑复制参数 + 逻辑流复制参数 START_REPLICATION命令可以向指定复制槽关联的逻辑解码输出插件传递选项。标准(pgoutput)插件接受的选项见 - - 在上述命令中,若参数类型为 boolean,可省略 value 部分;省略等同于指定 TRUE。 - + @@ -3542,58 +3524,48 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - CancelRequest (F) - Int32 - - 消息内容的长度(以字节为单位),包括其自身。 + 消息内容的长度,以字节为单位,包括此长度字段本身。 - Int32(80877102) - - 取消请求代码。该值被选择为在最高的16位中包含1234,在最低的16位中包含5678。 - (为避免混淆,此代码不得与任何协议版本号相同。) + 取消请求代码。此值的最高 16 位为 1234,最低 16 位为 5678。(为避免混淆,此代码不能与任何协议版本号相同。) - Int32 - - 目标后端的进程ID。 + 目标后端的进程 ID。 - - Int32 + Byten - - 目标后端的 secret key。该字段长度由消息总长度决定并延伸至消息末尾,最大长度为 256 字节。 + 目标后端的密钥。此字段延伸至消息末尾,其范围由长度字段确定。密钥最长为 256 字节。 - 在协议 3.2 之前,secret key 固定为 4 字节。 - + 在协议版本 3.2 之前,密钥始终为 4 字节长。 + @@ -5674,7 +5646,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 严重性: 字段内容为ERROR, FATAL, 或 + 严重性: 字段内容为ERROR, FATAL, 或 PANIC (在错误消息中), 或 WARNING, NOTICE, DEBUG, INFO, 或 LOG (在通知消息中), @@ -5688,7 +5660,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 严重性:字段内容为ERRORFATAL或 + 严重性:字段内容为ERRORFATALPANIC(在错误消息中),或WARNINGNOTICEDEBUGINFOLOG(在通知消息中)。 这与S字段相同,只是内容不会被本地化。仅在由PostgreSQL版本9.6 @@ -5712,7 +5684,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 消息: 主要的人类可读错误消息。 + 消息: 主要的人类可读错误消息。 这应该准确但简洁(通常一行)。 总是存在。 @@ -5734,7 +5706,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 提示: 关于问题应该怎么做的一个可选建议。 + 提示: 关于问题应该怎么做的一个可选建议。 这意在与细节不同,它提供建议(可能不合适)而不是硬性事实。 可能会跨越多行。 @@ -5768,7 +5740,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 内部查询: 一个失败的内部生成命令的文本。 + 内部查询: 一个失败的内部生成命令的文本。 例如,这可能是由PL/pgSQL函数发出的SQL查询。 @@ -5801,7 +5773,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 表名: 如果错误与特定表相关联,则为表的名称。(有关表模式名称的名称,请参考模式名称字段。) + 表名: 如果错误与特定表相关联,则为表的名称。(有关表模式名称的名称,请参考模式名称字段。) @@ -5811,7 +5783,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 列名: 如果错误与特定表列相关联,则为列的名称。(请参考模式和表名字段以识别表。) + 列名: 如果错误与特定表列相关联,则为列的名称。(请参考模式和表名字段以识别表。) @@ -5821,7 +5793,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 数据类型名称: 如果错误与特定数据类型相关联,则为数据类型的名称。 + 数据类型名称: 如果错误与特定数据类型相关联,则为数据类型的名称。 (有关数据类型模式的名称,请参阅模式名称字段。) @@ -5832,7 +5804,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 约束名称: 如果错误与特定约束相关联,则为约束的名称。请参考上面列出的字段,了解相关表或域。 + 约束名称: 如果错误与特定约束相关联,则为约束的名称。请参考上面列出的字段,了解相关表或域。 (为此,即使索引不是使用约束语法创建的,也将其视为约束。) @@ -5843,7 +5815,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 文件: 报告错误的源代码位置的文件名。 + 文件: 报告错误的源代码位置的文件名。 @@ -5981,7 +5953,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 标志; 逻辑解码消息是非事务性的时为0,是事务性的时为1。 + 标志; 逻辑解码消息是非事务性的时为0,是事务性的时为1。 @@ -6055,7 +6027,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 标志; 目前未使用。 + 标志; 目前未使用。 @@ -6753,7 +6725,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 标志; 目前未使用。 + 标志; 目前未使用。 @@ -6831,6 +6803,27 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" + + Int64 (XLogRecPtr) + + + 中止操作的 LSN,仅当 streaming 设置为 parallel 时出现。 + 此字段从协议版本 4 起可用。 + + + + + + Int64 (TimestampTz) + + + 事务的中止时间戳,仅当 streaming 设置为 parallel 时出现。 + 该值为自 PostgreSQL 纪元(2000-01-01)以来的微秒数。 + 此字段从协议版本 4 起可用。 + + + + @@ -6937,7 +6930,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 标志; 目前未使用。 + 标志; 目前未使用。 @@ -7022,7 +7015,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 标志; 目前未使用。 + 标志; 目前未使用。 @@ -7107,7 +7100,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 标志; 目前未使用。 + 标志; 目前未使用。 @@ -7203,7 +7196,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 标志; 目前未使用。 + 标志; 目前未使用。 @@ -7363,76 +7356,36 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 自协议2.0以来的变化总结 + 自协议 2.0 以来的变更总结 - 本节为那些试图将现有客户端库更新到协议3.0的开发人员提供了一个快速变更清单。 + 本节提供一份简要的变更清单,供准备将现有客户端库更新到协议 3.0 的开发者参考。 - - 初始启动数据包使用灵活的字符串列表格式,而不是固定格式。请注意,现在可以直接在启动数据包中指定运行时参数的会话默认值。 - (实际上,以前可以使用options字段来做到这一点,但考虑到options的有限宽度以及缺乏引用值中空格的任何方法,这并不是一种非常安全的技术。) - + 初始启动包采用灵活的字符串列表格式,取代了固定格式。注意,运行时参数的会话默认值现在可以直接在启动包中指定。(实际上,以前也能通过 options 字段实现,但由于 options 的宽度有限,且无法用引号保护值中的空白字符,这种方法并不稳妥。) - - 所有消息现在都在消息类型字节后面立即跟着长度计数(除了启动数据包,它们没有类型字节)。另外请注意,PasswordMessage现在有一个类型字节。 - + 现在,所有消息都在消息类型字节之后紧跟一个长度计数(启动包除外,它没有类型字节)。另请注意,PasswordMessage 现在也有类型字节。 - - ErrorResponse和NoticeResponse('E'和'N') - 消息现在包含多个字段,客户端代码可以从中组装出所需级别的错误消息。请注意, - 单个字段通常不会以换行符结尾,而在旧协议中发送的单个字符串总是以换行符结尾。 - + ErrorResponse 和 NoticeResponse('E' 和 'N')消息现在包含多个字段,客户端代码可以利用这些字段组合出所需详细程度的错误消息。注意,各字段通常不会以换行符结束,而旧协议发送的单个字符串总是以换行符结束。 - - ReadyForQuery('Z')消息包括事务状态指示器。 - + ReadyForQuery('Z')消息包含一个事务状态指示器。 - - 二进制行和数据行消息类型之间的区别已经消失;单个数据行消息类型用于以所有格式返回数据。 - 请注意,DataRow的布局已更改,以使其更容易解析。 - 此外,二进制值的表示已更改:它不再直接与服务器的内部表示形式绑定。 - + BinaryRow 与 DataRow 消息类型不再有区别;单一的 DataRow 消息类型用于返回所有格式的数据。注意,DataRow 的布局已经改变,使其更容易解析。另外,二进制值的表示方式也已改变,不再直接取决于服务器内部的表示方式。 - - 有一个新的扩展查询子协议,它增加了前端消息类型Parse、Bind、Execute、Describe、Close、Flush和Sync, - 以及后端消息类型ParseComplete、BindComplete、PortalSuspended、ParameterDescription、NoData和CloseComplete。 - 现有客户端不必关心这个子协议,但利用它可能会提高性能或功能。 - + 新增了扩展查询子协议,其中增加了前端消息类型 Parse、Bind、Execute、Describe、Close、Flush 和 Sync,以及后端消息类型 ParseComplete、BindComplete、PortalSuspended、ParameterDescription、NoData 和 CloseComplete。现有客户端不必关注这个子协议,但使用它可能有助于改善性能或功能。 - - COPY数据现在封装到CopyData和CopyDone消息中。在COPY期间有一种明确定义的错误恢复方式。 - 特殊的\.最后一行不再需要,并且在COPY OUT期间不发送。 - (在文本模式的COPY IN期间仍然被识别为终止符,但在CSV模式中不会被识别。文本模式中的这种行为已弃用,并且最终可能会被移除。)支持二进制COPY。 - CopyInResponse和CopyOutResponse消息包括指示列数和每列格式的字段。 - + COPY 数据现在封装在 CopyData 和 CopyDone 消息中。COPY 期间的错误恢复已有明确定义的方法。不再需要特殊的最后一行 \.COPY OUT 期间也不再发送它。(在文本模式的 COPY IN 期间仍会将它识别为终止符,但在 CSV 模式中不会。文本模式的这种行为已弃用,将来可能会被移除。)现已支持二进制 COPY。CopyInResponse 和 CopyOutResponse 消息包含了表示列数及各列格式的字段。 - - FunctionCall和FunctionCallResponse消息的布局已更改。 - FunctionCall现在可以支持将NULL参数传递给函数。它还可以处理以文本或二进制格式传递参数和检索结果。 - 不再需要考虑FunctionCall可能存在安全漏洞,因为它不提供对内部服务器数据表示的直接访问。 - + FunctionCall 和 FunctionCallResponse 消息的布局已经改变。FunctionCall 现在支持向函数传递 NULL 参数,也可以使用文本或二进制格式传递参数和取得结果。由于它不再提供对服务器内部数据表示的直接访问,因此也不再有理由将 FunctionCall 视为潜在的安全漏洞。 - - 后端在连接启动期间向客户端库发送ParameterStatus('S')消息,以传达其认为对客户端库有趣的所有参数。 - 随后,每当这些参数中任何一个的活动值发生变化时,都会发送ParameterStatus消息。 - + 在连接启动期间,后端会为其认为客户端库关注的所有参数发送 ParameterStatus('S')消息。之后,只要这些参数中任何一个的当前值发生变化,就会发送一条 ParameterStatus 消息。 - - RowDescription('T')消息携带了描述行的每列的新表OID和列号字段。它还显示了每列的格式代码。 - + RowDescription('T')消息针对所描述行中的每一列,增加了表 OID 和列编号字段,并显示各列的格式代码。 - - CursorResponse('P')消息不再由后端生成。 - + 后端不再生成 CursorResponse('P')消息。 - - NotificationResponse('A')消息有一个额外的字符串字段,可以携带一个有效负载字符串, - 从NOTIFY事件发送者传递过来。 - + NotificationResponse('A')消息增加了一个字符串字段,可以携带 NOTIFY 事件发送者传来的载荷字符串。 - - EmptyQueryResponse('I')消息曾包含一个空字符串参数;现已移除。 - + EmptyQueryResponse('I')消息以前包含一个空字符串参数,现在已将其移除。 diff --git a/zh/19/queries.sgml b/zh/19/queries.sgml index 1a85e845..867028f8 100644 --- a/zh/19/queries.sgml +++ b/zh/19/queries.sgml @@ -515,7 +515,7 @@ FROM (VALUES ('anne', 'smith'), ('bob', 'jones'), ('joe', 'blow')) - 表函数是那些生成行集合的函数,这些行可以由基本数据类型(标量类型)组成,也可以由复合数据类型(表行)组成。它们在查询的FROM子句中用法类似于表、视图或子查询。表函数返回的列可以像表、视图或子查询的列一样,出现在SELECTJOINWHERE子句中。 + 表函数是那些生成行集合的函数,这些行可以由基础类型(标量类型)组成,也可以由复合数据类型(表行)组成。它们在查询的FROM子句中用法类似于表、视图或子查询。表函数返回的列可以像表、视图或子查询的列一样,出现在SELECTJOINWHERE子句中。 @@ -553,7 +553,7 @@ UNNEST( array_expression , ... - 如果没有提供列的别名,那么对于一个返回基数据类型的函数,列名也与该函数 + 如果没有提供列的别名,那么对于一个返回基础类型的函数,列名也与该函数 名相同。对于一个返回复合类型的函数,结果列会从该类型的属性得到名称。 diff --git a/zh/19/rangetypes.sgml b/zh/19/rangetypes.sgml index f60e0af7..68409fa3 100644 --- a/zh/19/rangetypes.sgml +++ b/zh/19/rangetypes.sgml @@ -209,7 +209,7 @@ SELECT '{[3,7), [8,9)}'::int4multirange; 构造范围和多范围 - 每种范围类型都有一个与范围类型同名的构造函数。使用构造函数通常比书写范围文字常量更方便,因为这样无需对界限值进行额外引用。构造函数接受两个或三个参数。两个参数的形式构造标准形式的范围(下界包含,上界排除),而三个参数的形式则按第三个参数指定的界限形式构造范围。第三个参数必须是下列字符串之一: + 每种范围类型都有一个与范围类型同名的构造函数。使用构造函数通常比书写范围字面量更方便,因为这样无需为界限值额外加引号。构造函数接受两个或三个参数。两个参数的形式构造标准形式的范围(下界包含,上界排除),而三个参数的形式则按第三个参数指定的界限形式构造范围。第三个参数必须是下列字符串之一: ()(][)或者 diff --git a/zh/19/ref/abort.sgml b/zh/19/ref/abort.sgml index 2cfe088c..43c10475 100644 --- a/zh/19/ref/abort.sgml +++ b/zh/19/ref/abort.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ABORT 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/alter_aggregate.sgml b/zh/19/ref/alter_aggregate.sgml index 6e6d9e05..ce4e87f4 100644 --- a/zh/19/ref/alter_aggregate.sgml +++ b/zh/19/ref/alter_aggregate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER AGGREGATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/alter_collation.sgml b/zh/19/ref/alter_collation.sgml index 85fd5517..c8273dd3 100644 --- a/zh/19/ref/alter_collation.sgml +++ b/zh/19/ref/alter_collation.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER COLLATION 7 - SQL - Language Statements + SQL - 语言语句 @@ -102,7 +102,7 @@ ALTER COLLATION name SET SCHEMA new_sche 注解 - 创建排序规则对象时,该排序规则的提供者特定版本会记录在系统目录中。 + 创建排序规则对象时,会在系统目录中记录由提供程序确定的排序规则版本。 使用该排序规则时,会将当前版本与记录的版本进行比较;如果二者不匹 配,就会发出警告,例如: diff --git a/zh/19/ref/alter_conversion.sgml b/zh/19/ref/alter_conversion.sgml index d6c8e82c..613b3ec3 100644 --- a/zh/19/ref/alter_conversion.sgml +++ b/zh/19/ref/alter_conversion.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER CONVERSION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/alter_database.sgml b/zh/19/ref/alter_database.sgml index b83f72ce..0fe4d0c7 100644 --- a/zh/19/ref/alter_database.sgml +++ b/zh/19/ref/alter_database.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER DATABASE 7 - SQL - Language Statements + SQL - 语言语句 @@ -90,9 +90,7 @@ ALTER DATABASE name RESET ALL allowconn - - 如果为假,则没有人能连接到这个数据库。 - + 如果为 false,则任何人都不能连接到该数据库。 @@ -109,7 +107,7 @@ ALTER DATABASE name RESET ALL istemplate - 如果为真,则任何具有CREATEDB权限的用户都可以从这个数据库克隆。如果为假,则只有超级用户或者该数据库的拥有者可以克隆它。 + 如果为 true,则任何具有 CREATEDB 权限的用户都可以克隆该数据库;如果为 false,则只有超级用户或该数据库的拥有者可以克隆它。 diff --git a/zh/19/ref/alter_default_privileges.sgml b/zh/19/ref/alter_default_privileges.sgml index 2fca3f17..87446d98 100644 --- a/zh/19/ref/alter_default_privileges.sgml +++ b/zh/19/ref/alter_default_privileges.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER DEFAULT PRIVILEGES 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/alter_domain.sgml b/zh/19/ref/alter_domain.sgml index 92d5ffa8..c62ed311 100644 --- a/zh/19/ref/alter_domain.sgml +++ b/zh/19/ref/alter_domain.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER DOMAIN 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/alter_event_trigger.sgml b/zh/19/ref/alter_event_trigger.sgml index 326f30e1..b9407346 100644 --- a/zh/19/ref/alter_event_trigger.sgml +++ b/zh/19/ref/alter_event_trigger.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER EVENT TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -58,7 +58,7 @@ ALTER EVENT TRIGGER name RENAME TO new_owner - 该事件触发器的新拥有者的用户名。 + 该事件触发器的新所有者的用户名。 @@ -94,7 +94,7 @@ ALTER EVENT TRIGGER name RENAME TO - 另见 + 参见 diff --git a/zh/19/ref/alter_extension.sgml b/zh/19/ref/alter_extension.sgml index df4dec5d..7b45aa24 100644 --- a/zh/19/ref/alter_extension.sgml +++ b/zh/19/ref/alter_extension.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER EXTENSION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/alter_foreign_data_wrapper.sgml b/zh/19/ref/alter_foreign_data_wrapper.sgml index e212621b..46c8d850 100644 --- a/zh/19/ref/alter_foreign_data_wrapper.sgml +++ b/zh/19/ref/alter_foreign_data_wrapper.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER FOREIGN DATA WRAPPER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/alter_foreign_table.sgml b/zh/19/ref/alter_foreign_table.sgml index 717ebb1c..e3d4b556 100644 --- a/zh/19/ref/alter_foreign_table.sgml +++ b/zh/19/ref/alter_foreign_table.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER FOREIGN TABLE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/alter_function.sgml b/zh/19/ref/alter_function.sgml index 5de95078..5c9bc999 100644 --- a/zh/19/ref/alter_function.sgml +++ b/zh/19/ref/alter_function.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation ALTER FUNCTION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/alter_group.sgml b/zh/19/ref/alter_group.sgml index 09b41201..4e66434d 100644 --- a/zh/19/ref/alter_group.sgml +++ b/zh/19/ref/alter_group.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER GROUP 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/alter_index.sgml b/zh/19/ref/alter_index.sgml index 58fd2783..58d12d63 100644 --- a/zh/19/ref/alter_index.sgml +++ b/zh/19/ref/alter_index.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER INDEX 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/alter_language.sgml b/zh/19/ref/alter_language.sgml index 81506e75..aca1352c 100644 --- a/zh/19/ref/alter_language.sgml +++ b/zh/19/ref/alter_language.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER LANGUAGE 7 - SQL - Language Statements + SQL - 语言语句 @@ -31,8 +31,8 @@ ALTER [ PROCEDURAL ] LANGUAGE name OWNER TO { ALTER LANGUAGE更改一种过程语言的定义。 - 目前唯一的功能是重命名该语言或为其指定新的拥有者。 - 要使用ALTER LANGUAGE,你必须是超级用户或者该语言的拥有者。 + 目前唯一的功能是重命名该语言或为其指定新的所有者。 + 要使用ALTER LANGUAGE,你必须是超级用户或者该语言的所有者。 @@ -62,7 +62,7 @@ ALTER [ PROCEDURAL ] LANGUAGE name OWNER TO { new_owner - 该语言的新拥有者 + 该语言的新所有者 diff --git a/zh/19/ref/alter_large_object.sgml b/zh/19/ref/alter_large_object.sgml index 65731c89..74b865e1 100644 --- a/zh/19/ref/alter_large_object.sgml +++ b/zh/19/ref/alter_large_object.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER LARGE OBJECT 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/alter_materialized_view.sgml b/zh/19/ref/alter_materialized_view.sgml index 71ac3ade..2ef84a4c 100644 --- a/zh/19/ref/alter_materialized_view.sgml +++ b/zh/19/ref/alter_materialized_view.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER MATERIALIZED VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/alter_opclass.sgml b/zh/19/ref/alter_opclass.sgml index b1872b37..a2228963 100644 --- a/zh/19/ref/alter_opclass.sgml +++ b/zh/19/ref/alter_opclass.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER OPERATOR CLASS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/alter_operator.sgml b/zh/19/ref/alter_operator.sgml index 9537f8e9..0e908cac 100644 --- a/zh/19/ref/alter_operator.sgml +++ b/zh/19/ref/alter_operator.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER OPERATOR 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/alter_opfamily.sgml b/zh/19/ref/alter_opfamily.sgml index a0b755c2..de22efe2 100644 --- a/zh/19/ref/alter_opfamily.sgml +++ b/zh/19/ref/alter_opfamily.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER OPERATOR FAMILY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/alter_policy.sgml b/zh/19/ref/alter_policy.sgml index 30e5b6e0..e8f525cf 100644 --- a/zh/19/ref/alter_policy.sgml +++ b/zh/19/ref/alter_policy.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER POLICY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/alter_procedure.sgml b/zh/19/ref/alter_procedure.sgml index 22e333e4..2a38515b 100644 --- a/zh/19/ref/alter_procedure.sgml +++ b/zh/19/ref/alter_procedure.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER PROCEDURE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/alter_property_graph.sgml b/zh/19/ref/alter_property_graph.sgml index 2c7dc3b1..3d47559a 100644 --- a/zh/19/ref/alter_property_graph.sgml +++ b/zh/19/ref/alter_property_graph.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER PROPERTY GRAPH 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/alter_publication.sgml b/zh/19/ref/alter_publication.sgml index 5acfe65b..c552bf30 100644 --- a/zh/19/ref/alter_publication.sgml +++ b/zh/19/ref/alter_publication.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER PUBLICATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/alter_role.sgml b/zh/19/ref/alter_role.sgml index 6c719424..0f2402d9 100644 --- a/zh/19/ref/alter_role.sgml +++ b/zh/19/ref/alter_role.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation ALTER ROLE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/alter_routine.sgml b/zh/19/ref/alter_routine.sgml index 4fc3e18d..79191e1e 100644 --- a/zh/19/ref/alter_routine.sgml +++ b/zh/19/ref/alter_routine.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER ROUTINE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/alter_rule.sgml b/zh/19/ref/alter_rule.sgml index 9449d787..9397274c 100644 --- a/zh/19/ref/alter_rule.sgml +++ b/zh/19/ref/alter_rule.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER RULE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/alter_schema.sgml b/zh/19/ref/alter_schema.sgml index 9ff1f8bf..3bc22fe0 100644 --- a/zh/19/ref/alter_schema.sgml +++ b/zh/19/ref/alter_schema.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER SCHEMA 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/alter_sequence.sgml b/zh/19/ref/alter_sequence.sgml index e6ea56a5..5879f122 100644 --- a/zh/19/ref/alter_sequence.sgml +++ b/zh/19/ref/alter_sequence.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER SEQUENCE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/alter_server.sgml b/zh/19/ref/alter_server.sgml index 34a9998e..54ace2a3 100644 --- a/zh/19/ref/alter_server.sgml +++ b/zh/19/ref/alter_server.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER SERVER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/alter_statistics.sgml b/zh/19/ref/alter_statistics.sgml index e561b8a9..f5efa247 100644 --- a/zh/19/ref/alter_statistics.sgml +++ b/zh/19/ref/alter_statistics.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER STATISTICS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/alter_subscription.sgml b/zh/19/ref/alter_subscription.sgml index 0db2b4c6..da9b8187 100644 --- a/zh/19/ref/alter_subscription.sgml +++ b/zh/19/ref/alter_subscription.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER SUBSCRIPTION 7 - SQL - Language Statements + SQL - 语言语句 @@ -333,9 +333,7 @@ ALTER SUBSCRIPTION name RENAME TO < 跳过应用远端事务的所有更改。如果传入数据违反任何约束,逻辑复制会停止,直到问题解决。 通过使用ALTER SUBSCRIPTION ... SKIP命令,逻辑复制工作进程会跳过 - 该事务中的所有数据修改操作。若订阅者上启用了 - two_phase, - 则此选项对因在订阅者上启用该参数而已经预备的事务没有作用。逻辑复制工作进程成功跳过该事务或完成一个事务后, + 该事务中的所有数据修改操作。此选项对因在订阅者上启用 two_phase 而已经预备的事务没有作用。逻辑复制工作进程成功跳过该事务或完成一个事务后, LSN(存储在pg_subscription.subskiplsn中) 会被清除。有关逻辑复制冲突的详细信息,请参见 。 @@ -346,7 +344,7 @@ ALTER SUBSCRIPTION name RENAME TO < 支持的选项有: - + lsn (pg_lsn) diff --git a/zh/19/ref/alter_system.sgml b/zh/19/ref/alter_system.sgml index 829bb8ba..ccf33b0b 100644 --- a/zh/19/ref/alter_system.sgml +++ b/zh/19/ref/alter_system.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER SYSTEM 7 - SQL - Language Statements + SQL - 语言语句 @@ -87,8 +87,7 @@ ALTER SYSTEM RESET ALL - 对于某些接受列表的参数,带引号的值会生成带双引号的输出,以保留空 - 格和逗号;对于另一些参数,则必须在单引号字符串内部使用双引号才能 + 对于某些接受列表的参数,带引号的值会生成带双引号的输出,以保留空白和逗号;对于另一些参数,则必须在单引号字符串内部使用双引号才能 达到这种效果。 diff --git a/zh/19/ref/alter_table.sgml b/zh/19/ref/alter_table.sgml index c742950f..d7a23b95 100644 --- a/zh/19/ref/alter_table.sgml +++ b/zh/19/ref/alter_table.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TABLE 7 - SQL - Language Statements + SQL - 语言语句 @@ -1214,7 +1214,7 @@ WITH ( MODULUS numeric_literal, REM - 若要强制立即回收已删除列所占的空间,可以执行任何一种会导致整表重写的ALTER TABLE形式。这样会重新构造每一行,并用空值替换被删除的列。 + 若要强制立即回收已删除列所占的空间,可以执行任何一种会导致整表重写的ALTER TABLE形式。这样会重建每一行,并用空值替换被删除的列。 diff --git a/zh/19/ref/alter_tablespace.sgml b/zh/19/ref/alter_tablespace.sgml index f0297481..7369ec94 100644 --- a/zh/19/ref/alter_tablespace.sgml +++ b/zh/19/ref/alter_tablespace.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TABLESPACE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/alter_trigger.sgml b/zh/19/ref/alter_trigger.sgml index 9fc49c8b..874811aa 100644 --- a/zh/19/ref/alter_trigger.sgml +++ b/zh/19/ref/alter_trigger.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -127,7 +127,7 @@ ALTER TRIGGER emp_stamp ON emp DEPENDS ON EXTENSION emplib; - 另见 + 参见 diff --git a/zh/19/ref/alter_tsconfig.sgml b/zh/19/ref/alter_tsconfig.sgml index 7ae05dd5..891dce66 100644 --- a/zh/19/ref/alter_tsconfig.sgml +++ b/zh/19/ref/alter_tsconfig.sgml @@ -13,7 +13,7 @@ PostgreSQL documentation ALTER TEXT SEARCH CONFIGURATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/alter_tsdictionary.sgml b/zh/19/ref/alter_tsdictionary.sgml index 9679697e..163d788b 100644 --- a/zh/19/ref/alter_tsdictionary.sgml +++ b/zh/19/ref/alter_tsdictionary.sgml @@ -13,7 +13,7 @@ PostgreSQL documentation ALTER TEXT SEARCH DICTIONARY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/alter_tsparser.sgml b/zh/19/ref/alter_tsparser.sgml index 461e545e..6efd5c5b 100644 --- a/zh/19/ref/alter_tsparser.sgml +++ b/zh/19/ref/alter_tsparser.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TEXT SEARCH PARSER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/alter_tstemplate.sgml b/zh/19/ref/alter_tstemplate.sgml index 87a85ff3..af25c5b4 100644 --- a/zh/19/ref/alter_tstemplate.sgml +++ b/zh/19/ref/alter_tstemplate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TEXT SEARCH TEMPLATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/alter_type.sgml b/zh/19/ref/alter_type.sgml index 58063799..6c1bc805 100644 --- a/zh/19/ref/alter_type.sgml +++ b/zh/19/ref/alter_type.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation ALTER TYPE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/alter_user.sgml b/zh/19/ref/alter_user.sgml index 362b5518..5a4f5dd4 100644 --- a/zh/19/ref/alter_user.sgml +++ b/zh/19/ref/alter_user.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER USER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/alter_user_mapping.sgml b/zh/19/ref/alter_user_mapping.sgml index 6bbeffc6..b1fc6606 100644 --- a/zh/19/ref/alter_user_mapping.sgml +++ b/zh/19/ref/alter_user_mapping.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER USER MAPPING 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/alter_view.sgml b/zh/19/ref/alter_view.sgml index 020f864b..63fcb79e 100644 --- a/zh/19/ref/alter_view.sgml +++ b/zh/19/ref/alter_view.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/analyze.sgml b/zh/19/ref/analyze.sgml index 1717fc7f..8a934dce 100644 --- a/zh/19/ref/analyze.sgml +++ b/zh/19/ref/analyze.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ANALYZE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/begin.sgml b/zh/19/ref/begin.sgml index 1842ec9c..8040dc3a 100644 --- a/zh/19/ref/begin.sgml +++ b/zh/19/ref/begin.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation BEGIN 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/call.sgml b/zh/19/ref/call.sgml index 68bb5a3b..1996368e 100644 --- a/zh/19/ref/call.sgml +++ b/zh/19/ref/call.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CALL 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/checkpoint.sgml b/zh/19/ref/checkpoint.sgml index 569d9305..46153ee3 100644 --- a/zh/19/ref/checkpoint.sgml +++ b/zh/19/ref/checkpoint.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CHECKPOINT 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/close.sgml b/zh/19/ref/close.sgml index 76c0c817..7b006ea5 100644 --- a/zh/19/ref/close.sgml +++ b/zh/19/ref/close.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation CLOSE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/cluster.sgml b/zh/19/ref/cluster.sgml index 308ec80f..a579246d 100644 --- a/zh/19/ref/cluster.sgml +++ b/zh/19/ref/cluster.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CLUSTER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/clusterdb.sgml b/zh/19/ref/clusterdb.sgml index fd83c9ba..ada12058 100644 --- a/zh/19/ref/clusterdb.sgml +++ b/zh/19/ref/clusterdb.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation clusterdb 1 - Application + 应用程序 diff --git a/zh/19/ref/comment.sgml b/zh/19/ref/comment.sgml index 4d0b1904..fb032ed3 100644 --- a/zh/19/ref/comment.sgml +++ b/zh/19/ref/comment.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation COMMENT 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/commit.sgml b/zh/19/ref/commit.sgml index 5acbd72d..559cf99a 100644 --- a/zh/19/ref/commit.sgml +++ b/zh/19/ref/commit.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation COMMIT 7 - SQL - Language Statements + SQL - 语言语句 @@ -54,7 +54,7 @@ COMMIT [ WORK | TRANSACTION ] [ AND [ NO ] CHAIN ] 参数 - chained transactions + 链式事务 diff --git a/zh/19/ref/commit_prepared.sgml b/zh/19/ref/commit_prepared.sgml index 5a629346..53103cc2 100644 --- a/zh/19/ref/commit_prepared.sgml +++ b/zh/19/ref/commit_prepared.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation COMMIT PREPARED 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/copy.sgml b/zh/19/ref/copy.sgml index 2b4fbf68..9abc2a27 100644 --- a/zh/19/ref/copy.sgml +++ b/zh/19/ref/copy.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation COPY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/create_access_method.sgml b/zh/19/ref/create_access_method.sgml index d4cb6d2c..7f2d9d8e 100644 --- a/zh/19/ref/create_access_method.sgml +++ b/zh/19/ref/create_access_method.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE ACCESS METHOD 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/create_aggregate.sgml b/zh/19/ref/create_aggregate.sgml index 0a203329..9093d440 100644 --- a/zh/19/ref/create_aggregate.sgml +++ b/zh/19/ref/create_aggregate.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation CREATE AGGREGATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/create_cast.sgml b/zh/19/ref/create_cast.sgml index 1e2c9275..94e78f9e 100644 --- a/zh/19/ref/create_cast.sgml +++ b/zh/19/ref/create_cast.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation CREATE CAST 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/create_collation.sgml b/zh/19/ref/create_collation.sgml index 6bb3f7ab..4177c026 100644 --- a/zh/19/ref/create_collation.sgml +++ b/zh/19/ref/create_collation.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE COLLATION 7 - SQL - Language Statements + SQL - 语言语句 @@ -130,7 +130,7 @@ CREATE COLLATION [ IF NOT EXISTS ] name FROM - 指定与该排序规则关联的区域设置服务所使用的提供者。可能的值是 + 指定与该排序规则关联的区域设置服务所使用的提供程序。可能的值是 builtinicuICU (如果服务器在构建时启用了 ICU 支持)或libc。 @@ -154,7 +154,7 @@ CREATE COLLATION [ IF NOT EXISTS ] name FROM - 非确定性排序规则仅受 ICU 提供者支持。 + 非确定性排序规则仅受 ICU 提供程序支持。 @@ -238,14 +238,14 @@ CREATE COLLATION french (locale = 'fr_FR.utf8'); - 使用 ICU 提供者并采用德语电话簿排序顺序创建一种排序规则: + 使用 ICU 提供程序并采用德语电话簿排序顺序创建一种排序规则: CREATE COLLATION german_phonebook (provider = icu, locale = 'de-u-co-phonebk'); - 使用 ICU 提供者、基于 ICU 根区域设置并带有自定义规则创建一种排序规 + 使用 ICU 提供程序、基于 ICU 根区域设置并带有自定义规则创建一种排序规 则: diff --git a/zh/19/ref/create_conversion.sgml b/zh/19/ref/create_conversion.sgml index da83218a..3fcb4447 100644 --- a/zh/19/ref/create_conversion.sgml +++ b/zh/19/ref/create_conversion.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE CONVERSION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/create_database.sgml b/zh/19/ref/create_database.sgml index 18b484a6..57352426 100644 --- a/zh/19/ref/create_database.sgml +++ b/zh/19/ref/create_database.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE DATABASE 7 - SQL - Language Statements + SQL - 语言语句 @@ -178,7 +178,7 @@ CREATE DATABASE name 如果 是 - libc,它还会设置新数据库中使用的默认字符分类, + libc,它会设置新数据库中使用的默认字符分类, 从而覆盖 的设置。 @@ -360,7 +360,7 @@ CREATE DATABASE nameLC_CTYPE)兼容。如果区域设置为 C (或等价的 POSIX),则允许所有编码;但对于其他区域设置,只有一种编码能够正常工作。(不过,在 Windows 上,UTF-8 编码可与任何区域设置一起使用。) CREATE DATABASE 允许超级用户不考虑区域设置而指定 - SQL_ASCII 编码,但这种选择已被废弃;如果数据库中存储了与该区域设置不兼容编码的数据,字符串函数的行为可能会出错。 + SQL_ASCII 编码,但这种选择已弃用;如果数据库中存储了与该区域设置不兼容编码的数据,字符串函数的行为可能会出错。 @@ -410,7 +410,7 @@ CREATE DATABASE music TEMPLATE template0; 在这个示例中,如果指定的区域设置与 template1 中的不同, - 则必须使用 TEMPLATE template0 子句。(如果并不不同, + 则必须使用 TEMPLATE template0 子句。(如果相同, 那么显式指定区域设置就是多余的。) diff --git a/zh/19/ref/create_domain.sgml b/zh/19/ref/create_domain.sgml index 905dd30d..420bbf83 100644 --- a/zh/19/ref/create_domain.sgml +++ b/zh/19/ref/create_domain.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE DOMAIN 7 - SQL - Language Statements + SQL - 语言语句 @@ -86,7 +86,7 @@ CREATE DOMAIN name [ AS ] 该域的可选排序规则。如果未指定排序规则,则该域的排序规则行为与其 底层数据类型相同。如果指定了COLLATE,则底层 - 类型必须是一种可排序数据类型。 + 类型必须是一种支持排序规则的数据类型。 diff --git a/zh/19/ref/create_event_trigger.sgml b/zh/19/ref/create_event_trigger.sgml index 0d45c2be..32448118 100644 --- a/zh/19/ref/create_event_trigger.sgml +++ b/zh/19/ref/create_event_trigger.sgml @@ -13,7 +13,7 @@ PostgreSQL documentation CREATE EVENT TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -44,7 +44,7 @@ CREATE EVENT TRIGGER name CREATE EVENT TRIGGER创建一个新的事件触发器。 每当指定的事件发生,并且与该触发器关联的WHEN条件(如果有)得到 满足时,就会执行该触发器函数。有关事件触发器的一般性介绍,见 - 。创建事件触发器的用户将成为其拥有者。 + 。创建事件触发器的用户将成为其所有者。 @@ -83,8 +83,7 @@ CREATE EVENT TRIGGER name - 用于过滤事件的变量名称。这使得可以将触发器限定为只在支持该变量的部 - 分情形下触发。当前唯一支持的 + 用于过滤事件的变量名称。这样可以将触发器限定为只在原本支持的部分情形下触发。当前唯一支持的 filter_variableTAG @@ -194,7 +193,7 @@ CREATE EVENT TRIGGER abort_ddl ON ddl_command_start - 另见 + 参见 diff --git a/zh/19/ref/create_extension.sgml b/zh/19/ref/create_extension.sgml index 45a8d23c..ee93ce8f 100644 --- a/zh/19/ref/create_extension.sgml +++ b/zh/19/ref/create_extension.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE EXTENSION 7 - SQL - Language Statements + SQL - 语言语句 @@ -167,7 +167,7 @@ CREATE EXTENSION [ IF NOT EXISTS ] extension_name 会在之后执行编写粗心的扩展脚本时实施攻击,使该用户获得超级用户权限。 不过,只有当特洛伊木马对象在脚本执行期间位于 search_path 中时,它们才会构成危险;这意味着它们 - 位于扩展的安装目标模式中,或位于它所依赖的某个扩展所属的模式中。 + 位于扩展的安装目标模式中,或位于它所依赖的某个扩展的目标模式中。 因此,处理那些脚本尚未经过仔细审查的扩展时,一个经验法则是: 只把它们安装到从未向任何不受信任用户授予、而且今后也不会授予 CREATE 权限的模式中。它们所依赖的任何扩展也应如此。 diff --git a/zh/19/ref/create_foreign_data_wrapper.sgml b/zh/19/ref/create_foreign_data_wrapper.sgml index d5e9468b..fa3329a5 100644 --- a/zh/19/ref/create_foreign_data_wrapper.sgml +++ b/zh/19/ref/create_foreign_data_wrapper.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE FOREIGN DATA WRAPPER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/create_foreign_table.sgml b/zh/19/ref/create_foreign_table.sgml index ac7a7465..faab5522 100644 --- a/zh/19/ref/create_foreign_table.sgml +++ b/zh/19/ref/create_foreign_table.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE FOREIGN TABLE 7 - SQL - Language Statements + SQL - 语言语句 @@ -143,9 +143,7 @@ WITH ( MODULUS numeric_literal, REM COLLATE collation - - COLLATE子句为该列(必须是一种可排序数据类型)指定一个排序规则。如果未指定,则使用该列数据类型的默认排序规则。 - + COLLATE子句为列指定排序规则(该列必须属于支持排序规则的数据类型)。如果未指定,则使用列数据类型的默认排序规则。 diff --git a/zh/19/ref/create_function.sgml b/zh/19/ref/create_function.sgml index 0dc1198a..d74df096 100644 --- a/zh/19/ref/create_function.sgml +++ b/zh/19/ref/create_function.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation CREATE FUNCTION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/create_group.sgml b/zh/19/ref/create_group.sgml index 92d125e8..40345c02 100644 --- a/zh/19/ref/create_group.sgml +++ b/zh/19/ref/create_group.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE GROUP 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/create_index.sgml b/zh/19/ref/create_index.sgml index d09e0c68..f18c655b 100644 --- a/zh/19/ref/create_index.sgml +++ b/zh/19/ref/create_index.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation CREATE INDEX 7 - SQL - Language Statements + SQL - 语言语句 @@ -57,7 +57,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] PostgreSQL提供了索引方法 - B-树、哈希、GiST、SP-GiST、GIN 以及 BRIN。用户也可以定义自己的索引 + B-树、hash、GiST、SP-GiST、GIN 以及 BRIN。用户也可以定义自己的索引 方法,但这相当复杂。 @@ -123,7 +123,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] 对于临时表,CREATE INDEX始终是非并发的, - 因为没有其他会话可以访问它们,而且非并发创建索引的成本更低。 + 因为没有其他会话可以访问它们,而且非并发创建索引的代价更低。 @@ -376,7 +376,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - B-树、哈希、GiST 和 SP-GiST 索引方法都接受以下参数: + B-树、hash、GiST 和 SP-GiST 索引方法都接受以下参数: @@ -566,7 +566,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - 定义当在下一页范围检测到插入时,是否为前一页范围排队执行一次提要操作 + 定义当在下一页范围检测到插入时,是否为前一页范围排队执行一次范围摘要操作 (详见)。 默认值为off @@ -580,8 +580,8 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] 并发构建索引 - index - building concurrently + 索引 + 并发构建 diff --git a/zh/19/ref/create_language.sgml b/zh/19/ref/create_language.sgml index fca9e159..5d737764 100644 --- a/zh/19/ref/create_language.sgml +++ b/zh/19/ref/create_language.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE LANGUAGE 7 - SQL - Language Statements + SQL - 语言语句 @@ -96,7 +96,7 @@ CREATE [ OR REPLACE ] [ TRUSTED ] [ PROCEDURAL ] LANGUAGE 。 - + 对 MD5 加密密码的支持已弃用,并将在PostgreSQL的未来版本中移除。迁移到其他密码类型的详细信息见 diff --git a/zh/19/ref/create_rule.sgml b/zh/19/ref/create_rule.sgml index 6d1486c9..e8b37c6d 100644 --- a/zh/19/ref/create_rule.sgml +++ b/zh/19/ref/create_rule.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE RULE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/create_schema.sgml b/zh/19/ref/create_schema.sgml index b33167b3..212af43c 100644 --- a/zh/19/ref/create_schema.sgml +++ b/zh/19/ref/create_schema.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE SCHEMA 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/create_sequence.sgml b/zh/19/ref/create_sequence.sgml index 05b08166..881284df 100644 --- a/zh/19/ref/create_sequence.sgml +++ b/zh/19/ref/create_sequence.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation CREATE SEQUENCE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/create_server.sgml b/zh/19/ref/create_server.sgml index 5308089d..e1048bca 100644 --- a/zh/19/ref/create_server.sgml +++ b/zh/19/ref/create_server.sgml @@ -13,7 +13,7 @@ PostgreSQL documentation CREATE SERVER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/create_statistics.sgml b/zh/19/ref/create_statistics.sgml index 4b2fabc1..98a31ad8 100644 --- a/zh/19/ref/create_statistics.sgml +++ b/zh/19/ref/create_statistics.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE STATISTICS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/create_subscription.sgml b/zh/19/ref/create_subscription.sgml index 21935e95..67935066 100644 --- a/zh/19/ref/create_subscription.sgml +++ b/zh/19/ref/create_subscription.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE SUBSCRIPTION 7 - SQL - Language Statements + SQL - 语言语句 @@ -264,7 +264,7 @@ CREATE SUBSCRIPTION subscription_nameparallel,表示如果有可用的并行应用工作进程, 接收到的更改会直接通过其中之一应用。如果没有空闲的并行应用工作进程 可以处理流式事务,那么这些更改会写入临时文件,并在事务提交后再应用。 - 注意,如果并行应用工作进程中发生错误,远端事务的 finish LSN + 注意,如果并行应用工作进程中发生错误,远端事务的 完成 LSN 可能不会记录到服务器日志中。此参数对序列没有影响。 diff --git a/zh/19/ref/create_table.sgml b/zh/19/ref/create_table.sgml index 864f6561..fc21f92f 100644 --- a/zh/19/ref/create_table.sgml +++ b/zh/19/ref/create_table.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation CREATE TABLE 7 - SQL - Language Statements + SQL - 语言语句 @@ -86,7 +86,7 @@ COMPRESSION compression_method [ ON DELETE referential_action ] [ ON UPDATE referential_action ] } [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ] [ ENFORCED | NOT ENFORCED ] -and table_constraint is: +table_constraint为: [ CONSTRAINT constraint_name ] { CHECK ( expression ) [ NO INHERIT ] | @@ -99,11 +99,11 @@ COMPRESSION compression_method class="parameter">referential_action ] [ ON UPDATE referential_action ] } [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ] [ ENFORCED | NOT ENFORCED ] -and like_option is: +like_option为: { INCLUDING | EXCLUDING } { COMMENTS | COMPRESSION | CONSTRAINTS | DEFAULTS | GENERATED | IDENTITY | INDEXES | STATISTICS | STORAGE | ALL } -and partition_bound_spec is: +partition_bound_spec为: IN ( partition_bound_expr [, ...] ) | FROM ( { partition_bound_expr | MINVALUE | MAXVALUE } [, ...] ) @@ -171,7 +171,7 @@ WITH ( MODULUS numeric_literal, REM - TEMPORARY or TEMP + TEMPORARYTEMP @@ -186,7 +186,7 @@ WITH ( MODULUS numeric_literal, REM - 可以在 TEMPORARYTEMP 前写 GLOBALLOCAL。这在当前的 PostgreSQL 中没有区别,而且已废弃;见下文 。 + 可以在 TEMPORARYTEMP 前写 GLOBALLOCAL。这在当前的 PostgreSQL 中没有区别,而且已弃用;见下文 @@ -238,7 +238,7 @@ WITH ( MODULUS numeric_literal, REM - 类型化表的列名和数据类型始终与其派生类型相同,因此不能再指定额外的列。但 CREATE TABLE 命令仍可为该表添加默认值和约束,并指定存储参数。 + 类型化表的列名和数据类型始终与其所基于的类型相同,因此不能再指定额外的列。但 CREATE TABLE 命令仍可为该表添加默认值和约束,并指定存储参数。 @@ -269,10 +269,7 @@ WITH ( MODULUS numeric_literal, REM COLLATE collation - - COLLATE 子句为该列(必须是一种可排序数据类型)赋予一个排序规则。 - 如果没有指定,将使用该列数据类型的默认排序规则。 - + COLLATE子句为列指定排序规则(该列必须属于支持排序规则的数据类型)。如果未指定,则使用列数据类型的默认排序规则。 @@ -281,7 +278,7 @@ WITH ( MODULUS numeric_literal, REM STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN | DEFAULT } TOAST - per-column storage settings + 逐列存储设置 @@ -440,13 +437,13 @@ WITH ( MODULUS numeric_literal, REM 还要注意,某些元素类型(如 timestamp)具有 - "infinity" 的概念,那只是另一种可存储的值。这不同于 + “无穷大” 的概念,那只是另一种可存储的值。这不同于 MINVALUEMAXVALUE,后两者并非可存储 的实际值,而只是表示值无界的方式。MAXVALUE 可以视为大于任何 - 其他值,包括 "infinity";MINVALUE 可以视为小于任何 - 其他值,包括 "minus infinity"。因此,范围 + 其他值,包括 “无穷大”;MINVALUE 可以视为小于任何 + 其他值,包括 “负无穷大”。因此,范围 FROM ('infinity') TO (MAXVALUE) 并不是空范围;它只允许存储 - 一个值 — "infinity"。 + 一个值 — “无穷大”。 @@ -527,7 +524,7 @@ WITH ( MODULUS numeric_literal, REM INCLUDING COMMENTS - 复制的列、检查约束、非空约束、索引和扩展统计信息的注释也会被复制。默认行为是不复制注释,因此新表中的对应对象都没有注释。 + 复制的列、检查约束、非空约束、索引和扩展统计信息的注释也会被复制。默认行为是不复制注释,因此新表中对应的对象没有注释。 @@ -564,7 +561,7 @@ WITH ( MODULUS numeric_literal, REM INCLUDING GENERATED - 会复制被复制列定义中的生成表达式以及 STORED/VIRTUAL 的选择。默认情况下,新列将是常规基表列。 + 会复制被复制列定义中的生成表达式以及 STORED/VIRTUAL 的选择。默认情况下,新列将是普通基础列。 @@ -677,7 +674,7 @@ WITH ( MODULUS numeric_literal, REM - 一个被标记为NO INHERIT的约束将不会传播到子表。 + 标记为 NO INHERIT 的约束不会传播到子表。 @@ -704,7 +701,7 @@ WITH ( MODULUS numeric_literal, REM - GENERATED ALWAYS AS ( generation_expr ) [ STORED | VIRTUAL ]generated column + GENERATED ALWAYS AS ( generation_expr ) [ STORED | VIRTUAL ]生成列 @@ -816,7 +813,7 @@ WITH ( MODULUS numeric_literal, REM 可选的 INCLUDE 子句会向该索引添加一个或多个仅作为 - payload 的列:对这些列不强制唯一性,而且该索引也不能据此 + 载荷 的列:对这些列不强制唯一性,而且该索引也不能据此 进行搜索。不过,它们可以通过仅索引扫描取回。注意,尽管约束不在包含列上 强制执行,它仍然依赖于这些列。因此,对这类列执行某些操作(例如 DROP COLUMN)可能导致约束和索引被级联删除。 @@ -863,7 +860,7 @@ WITH ( MODULUS numeric_literal, REM 可选的 INCLUDE 子句会向该索引添加一个或多个仅作为 - payload 的列:对这些列不强制唯一性,而且该索引也不能据此 + 载荷 的列:对这些列不强制唯一性,而且该索引也不能据此 进行搜索。不过,它们可以通过仅索引扫描取回。注意,尽管约束不在包含列上 强制执行,它仍然依赖于这些列。因此,对这类列执行某些操作(例如 DROP COLUMN)可能导致约束和索引被级联删除。 @@ -899,7 +896,7 @@ WITH ( MODULUS numeric_literal, REM 访问方法必须支持 amgettuple(见 );目前这意味着不能使用 GIN。 虽然允许,但在排他约束上使用 B-树或 hash 索引意义不大,因为它们做不到 - 比普通唯一约束更好的事情。因此,实践中访问方法几乎总会是 + 比普通唯一约束更好的事情。因此,实践中访问方法总是 GiSTSP-GiST @@ -959,7 +956,7 @@ WITH ( MODULUS numeric_literal, REM - 对于每一对引用列和被引用列,如果它们属于可排序数据类型,则两者的排序规 + 对于每一对引用列和被引用列,如果它们属于支持排序规则的数据类型,则两者的排序规 则要么都必须是确定性的,要么必须完全相同。这样可以确保两列对“相等”具 有一致的定义。 @@ -1062,10 +1059,7 @@ WITH ( MODULUS numeric_literal, REM - - 如果被引用列经常发生变化,那么最好在引用列上添加一个索引,以便更高效地 - 执行与该外键约束相关的引用动作。 - + 如果被引用列经常变化,可以考虑在引用列上添加索引,使与外键约束关联的引用操作能够更高效地执行。 @@ -1109,7 +1103,7 @@ WITH ( MODULUS numeric_literal, REM NOT ENFORCED - 当约束为 ENFORCED 时,数据库系统会在适当时机检查该约束(按需要在每条语句后或事务结束时),这是默认行为。若约束为 NOT ENFORCED,数据库系统将不再检查该约束,改由应用代码保证约束成立。对于不影响结果正确性的优化决策,数据库系统仍可能假定数据满足该约束。 + 当约束为 ENFORCED 时,数据库系统会在适当时机检查该约束(按需要在每条语句后或事务结束时),以确保约束成立。这是默认行为。若约束为 NOT ENFORCED,数据库系统将不再检查该约束,改由应用代码保证约束成立。对于不影响结果正确性的优化决策,数据库系统仍可能假定数据满足该约束。 @@ -1241,7 +1235,7 @@ WITH ( MODULUS numeric_literal, REM 存储参数 - storage parameters + 存储参数 @@ -1263,7 +1257,7 @@ WITH ( MODULUS numeric_literal, REM fillfactor (integer) - fillfactor storage parameter + fillfactor 存储参数 @@ -1285,7 +1279,7 @@ WITH ( MODULUS numeric_literal, REM toast_tuple_target (integer) - toast_tuple_target storage parameter + toast_tuple_target 存储参数 @@ -1293,7 +1287,7 @@ WITH ( MODULUS numeric_literal, REM toast_tuple_target 指定在尝试压缩和/或将长列值移入 TOAST 表之前所需的最小元组长度,同时也是一旦开始 TOAST 化后试图将长度 - 缩减到的目标长度。这会影响标记为 External(用于移动)、Main(用于压缩) + 缩减到其以下的目标长度。这会影响标记为 External(用于移动)、Main(用于压缩) 或 Extended(用于两者)的列,并且只适用于新元组。对现有行没有影响。默认 情况下,该参数被设置为至少允许每个块容纳 4 个元组,在默认块大小下即为 2040 字节。有效值介于 128 字节与(块大小减去页头)之间,默认上限为 @@ -1308,13 +1302,13 @@ WITH ( MODULUS numeric_literal, REM parallel_workers (integer) - parallel_workers storage parameter + parallel_workers 存储参数 - 该参数设置在对该表执行并行扫描时可用于辅助扫描的工作进程数量。若未设置, + 该参数设置在对该表执行并行扫描时用于辅助扫描的工作进程数量。若未设置, 系统会根据关系大小决定一个值。规划器或使用并行扫描的实用命令实际选择的 工作进程数量可能更少,例如可能受 设置所限。 @@ -1326,7 +1320,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_enabled, toast.autovacuum_enabled (boolean) - autovacuum_enabled storage parameter + autovacuum_enabled 存储参数 @@ -1349,7 +1343,7 @@ WITH ( MODULUS numeric_literal, REM vacuum_index_cleanup, toast.vacuum_index_cleanup (enum) - vacuum_index_cleanup storage parameter + vacuum_index_cleanup 存储参数 @@ -1373,7 +1367,7 @@ WITH ( MODULUS numeric_literal, REM vacuum_truncate, toast.vacuum_truncate (boolean) vacuum_truncate - storage parameter + 存储参数 @@ -1404,7 +1398,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_vacuum_threshold, toast.autovacuum_vacuum_threshold (integer) autovacuum_vacuum_threshold - storage parameter + 存储参数 @@ -1419,7 +1413,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_vacuum_max_threshold, toast.autovacuum_vacuum_max_threshold (integer) autovacuum_vacuum_max_threshold - storage parameter + 存储参数 @@ -1434,7 +1428,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_vacuum_scale_factor, toast.autovacuum_vacuum_scale_factor (floating point) autovacuum_vacuum_scale_factor - storage parameter + 存储参数 @@ -1450,7 +1444,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_vacuum_insert_threshold, toast.autovacuum_vacuum_insert_threshold (integer) autovacuum_vacuum_insert_threshold - storage parameter + 存储参数 @@ -1467,7 +1461,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_vacuum_insert_scale_factor, toast.autovacuum_vacuum_insert_scale_factor (floating point) autovacuum_vacuum_insert_scale_factor - storage parameter + 存储参数 @@ -1483,7 +1477,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_analyze_threshold (integer) autovacuum_analyze_threshold - storage parameter + 存储参数 @@ -1499,7 +1493,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_analyze_scale_factor (floating point) autovacuum_analyze_scale_factor - storage parameter + 存储参数 @@ -1515,7 +1509,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_vacuum_cost_delay, toast.autovacuum_vacuum_cost_delay (floating point) autovacuum_vacuum_cost_delay - storage parameter + 存储参数 @@ -1531,7 +1525,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_vacuum_cost_limit, toast.autovacuum_vacuum_cost_limit (integer) autovacuum_vacuum_cost_limit - storage parameter + 存储参数 @@ -1546,7 +1540,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_freeze_min_age, toast.autovacuum_freeze_min_age (integer) - autovacuum_freeze_min_age storage parameter + autovacuum_freeze_min_age 存储参数 @@ -1564,7 +1558,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_freeze_max_age, toast.autovacuum_freeze_max_age (integer) autovacuum_freeze_max_age - storage parameter + 存储参数 @@ -1581,7 +1575,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_freeze_table_age, toast.autovacuum_freeze_table_age (integer) - autovacuum_freeze_table_age storage parameter + autovacuum_freeze_table_age 存储参数 @@ -1596,7 +1590,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_multixact_freeze_min_age, toast.autovacuum_multixact_freeze_min_age (integer) - autovacuum_multixact_freeze_min_age storage parameter + autovacuum_multixact_freeze_min_age 存储参数 @@ -1615,7 +1609,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_multixact_freeze_max_age, toast.autovacuum_multixact_freeze_max_age (integer) autovacuum_multixact_freeze_max_age - storage parameter + 存储参数 @@ -1633,7 +1627,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_multixact_freeze_table_age, toast.autovacuum_multixact_freeze_table_age (integer) - autovacuum_multixact_freeze_table_age storage parameter + autovacuum_multixact_freeze_table_age 存储参数 @@ -1649,7 +1643,7 @@ WITH ( MODULUS numeric_literal, REM log_autovacuum_min_duration, toast.log_autovacuum_min_duration (integer) log_autovacuum_min_duration - storage parameter + 存储参数 @@ -1664,7 +1658,7 @@ WITH ( MODULUS numeric_literal, REM log_autoanalyze_min_duration (integer) log_autoanalyze_min_duration - storage parameter + 存储参数 @@ -1678,7 +1672,7 @@ WITH ( MODULUS numeric_literal, REM vacuum_max_eager_freeze_failure_rate, toast.vacuum_max_eager_freeze_failure_rate (floating point) vacuum_max_eager_freeze_failure_rate - storage parameter + 存储参数 @@ -1692,7 +1686,7 @@ WITH ( MODULUS numeric_literal, REM user_catalog_table (boolean) - user_catalog_table storage parameter + user_catalog_table 存储参数 @@ -1714,7 +1708,7 @@ WITH ( MODULUS numeric_literal, REM 注解 - PostgreSQL为每一个唯一约束和主键约束创建一个索引来强制唯一性。因此,没有必要显式地为主键列创建一个索引(详见)。 + PostgreSQL为每一个唯一约束和主键约束自动创建一个索引来强制唯一性。因此,没有必要显式地为主键列创建一个索引(详见)。 @@ -2144,9 +2138,9 @@ CREATE TABLE cities_partdef NULL 约束(实际上并不是约束)是 - PostgreSQL 对 SQL 标准的扩展;它也被其他一些数 - 据库系统采纳,以便兼容(以及与对称的 NOT NULL 约束保持一 - 致)。由于它本来就是任意列的默认值,所以它的存在只是噪声。 + PostgreSQL 对 SQL 标准的扩展;提供它是为了 + 与其他一些数据库系统兼容(以及与 NOT NULL 约束保持 + 对称)。由于它本来就是任意列的默认情况,所以它的存在只是噪声。 @@ -2176,12 +2170,12 @@ CREATE TABLE cities_partdef - 零列表 + 零列的表 PostgreSQL 允许创建没有列的表(例如 CREATE TABLE foo();)。这是对 SQL 标准的扩展,标准不允许 - 零列表。零列表本身并不十分有用,但若禁止它们,就会让 + 零列的表。零列的表本身并不十分有用,但若禁止它们,就会让 ALTER TABLE DROP COLUMN 出现奇怪的特殊情况,因此忽略这 一规范限制看起来更整洁。 @@ -2194,7 +2188,7 @@ CREATE TABLE cities_partdef PostgreSQL 允许一个表拥有多个标识列。 该标准指定一个表最多只能有一个标识列。 - 这主要是为了给模式更改或迁移提供更大的灵活性。 + 放宽这一限制主要是为了给模式更改或迁移提供更大的灵活性。 请注意,INSERT 命令仅支持一个适用于整个语句的覆盖子 句,因此对行为不同的多个标识列支持并不好。 @@ -2247,8 +2241,7 @@ CREATE TABLE cities_partdef 类型化表 - 类型化表实现了 SQL 标准的一个子集。按照标准,类型化表除了具有与底层组合 - 类型相对应的列之外,还应有一个额外的自引用列。 + 类型化表实现了 SQL 标准的一个子集。按照标准,类型化表除了具有与底层复合类型相对应的列之外,还应有一个额外的自引用列PostgreSQL 不显式支持自引用列。 diff --git a/zh/19/ref/create_table_as.sgml b/zh/19/ref/create_table_as.sgml index c4380b1d..74ed70c0 100644 --- a/zh/19/ref/create_table_as.sgml +++ b/zh/19/ref/create_table_as.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation CREATE TABLE AS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/create_tablespace.sgml b/zh/19/ref/create_tablespace.sgml index 32b0dbb1..88106ccd 100644 --- a/zh/19/ref/create_tablespace.sgml +++ b/zh/19/ref/create_tablespace.sgml @@ -13,7 +13,7 @@ PostgreSQL documentation CREATE TABLESPACE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/create_transform.sgml b/zh/19/ref/create_transform.sgml index 247e6a0f..ecea2c1e 100644 --- a/zh/19/ref/create_transform.sgml +++ b/zh/19/ref/create_transform.sgml @@ -13,7 +13,7 @@ PostgreSQL documentation CREATE TRANSFORM 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/create_trigger.sgml b/zh/19/ref/create_trigger.sgml index 1fe80f9a..c4f28a46 100644 --- a/zh/19/ref/create_trigger.sgml +++ b/zh/19/ref/create_trigger.sgml @@ -11,13 +11,13 @@ PostgreSQL documentation 过渡表 - ephemeral named relation + 临时命名关系 CREATE TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -70,7 +70,7 @@ CREATE [ OR REPLACE ] [ CONSTRAINT ] TRIGGER name UPDATEDELETE之前); 也可以在该操作完成之后引发(即在检查约束以及完成 INSERTUPDATE或 - DELETE之后);或者改为执行该操作 + DELETE之后);或者取代该操作执行 (用于视图上的插入、更新或删除)。如果触发器在事件之前引发,或者改为取代该事件执行, 则它可以跳过对当前行的操作,或者修改待插入的行 (仅适用于INSERTUPDATE操作)。 @@ -178,7 +178,7 @@ CREATE [ OR REPLACE ] [ CONSTRAINT ] TRIGGER name 调整其引发时机。约束触发器必须是普通表(不是外部表)上的 AFTER ROW 触发器。它们既可以在导致触发事件的语句结束时引发, 也可以在包含它的事务结束时引发;后一种情况称为延迟。 - 也可以使用SET CONSTRAINTS强制挂起的延迟触发立即引发。 + 也可以使用SET CONSTRAINTS强制尚待执行的延迟触发器立即引发。 约束触发器应当在其所实现的约束遭到违反时抛出异常。 @@ -403,7 +403,7 @@ UPDATE OF column_name1 [, column_name2CREATE TRIGGER的语法中,关键字 FUNCTIONPROCEDURE 是等价的, 但无论如何,被引用的对象都必须是函数而不是过程。 - 这里使用 PROCEDURE 关键字只是出于历史原因,并且已被废弃。 + 这里使用 PROCEDURE 关键字只是出于历史原因,并且已被弃用。 diff --git a/zh/19/ref/create_tsconfig.sgml b/zh/19/ref/create_tsconfig.sgml index 52c43127..52970b36 100644 --- a/zh/19/ref/create_tsconfig.sgml +++ b/zh/19/ref/create_tsconfig.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TEXT SEARCH CONFIGURATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/create_tsdictionary.sgml b/zh/19/ref/create_tsdictionary.sgml index 7a06b430..c45a7240 100644 --- a/zh/19/ref/create_tsdictionary.sgml +++ b/zh/19/ref/create_tsdictionary.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TEXT SEARCH DICTIONARY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/create_tsparser.sgml b/zh/19/ref/create_tsparser.sgml index d0c11ba5..358152ce 100644 --- a/zh/19/ref/create_tsparser.sgml +++ b/zh/19/ref/create_tsparser.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TEXT SEARCH PARSER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/create_tstemplate.sgml b/zh/19/ref/create_tstemplate.sgml index 947b18b9..702233e4 100644 --- a/zh/19/ref/create_tstemplate.sgml +++ b/zh/19/ref/create_tstemplate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TEXT SEARCH TEMPLATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/create_type.sgml b/zh/19/ref/create_type.sgml index 45a4d93a..879d0a86 100644 --- a/zh/19/ref/create_type.sgml +++ b/zh/19/ref/create_type.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation CREATE TYPE 7 - SQL - Language Statements + SQL - 语言语句 @@ -96,7 +96,7 @@ CREATE TYPE name 复合类型 - 第一种形式的CREATE TYPE创建复合类型。组合 + 第一种形式的CREATE TYPE创建复合类型。复合 类型由属性名和数据类型列表指定。如果某个属性的数据类型支持排序规 则,还可以指定该属性的排序规则。复合类型本质上与表的行类型相同, 但如果目的只是定义一种类型,使用CREATE TYPE @@ -322,7 +322,7 @@ CREATE TYPE name 数才知道,但仍有若干内部表示属性必须向 PostgreSQL声明。其中最重要的是 internallength。 - 基础数据类型可以是定长的,此时internallength为正整数;也可 以是变长的,此时将internallength设为 @@ -427,7 +427,7 @@ CREATE TYPE name collatable为真,则 该类型的列定义和表达式可以通过COLLATE子句携 带排序规则信息。是否实际使用这些排序规则信息取决于操作该类型的函 - 数实现;仅仅把类型标记为 collatable 并不会自动实现这一点。 + 数实现;仅仅把类型标记为支持排序规则并不会自动实现这一点。 @@ -876,7 +876,7 @@ CREATE TYPE float8_range AS RANGE (subtype = float8, subtype_diff = float8mi); - 这个示例创建基础数据类型box,然后在表定义中使用它: + 这个示例创建基础类型box,然后在表定义中使用它: CREATE TYPE box; diff --git a/zh/19/ref/create_user.sgml b/zh/19/ref/create_user.sgml index fe0be7fc..b5eb5a87 100644 --- a/zh/19/ref/create_user.sgml +++ b/zh/19/ref/create_user.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE USER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/create_user_mapping.sgml b/zh/19/ref/create_user_mapping.sgml index fe556318..1abe6abd 100644 --- a/zh/19/ref/create_user_mapping.sgml +++ b/zh/19/ref/create_user_mapping.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE USER MAPPING 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/create_view.sgml b/zh/19/ref/create_view.sgml index 7caa727c..c80a12ca 100644 --- a/zh/19/ref/create_view.sgml +++ b/zh/19/ref/create_view.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation CREATE VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/createdb.sgml b/zh/19/ref/createdb.sgml index 410df34e..c02b1f47 100644 --- a/zh/19/ref/createdb.sgml +++ b/zh/19/ref/createdb.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation createdb 1 - Application + 应用程序 diff --git a/zh/19/ref/createuser.sgml b/zh/19/ref/createuser.sgml index 0451cadd..eba45357 100644 --- a/zh/19/ref/createuser.sgml +++ b/zh/19/ref/createuser.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation createuser 1 - Application + 应用程序 @@ -139,7 +139,7 @@ PostgreSQL documentation - (已废弃) + (已弃用) diff --git a/zh/19/ref/deallocate.sgml b/zh/19/ref/deallocate.sgml index 18bdb229..056a2010 100644 --- a/zh/19/ref/deallocate.sgml +++ b/zh/19/ref/deallocate.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation DEALLOCATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/declare.sgml b/zh/19/ref/declare.sgml index ed389e4d..9276a0e3 100644 --- a/zh/19/ref/declare.sgml +++ b/zh/19/ref/declare.sgml @@ -22,7 +22,7 @@ PostgreSQL documentation DECLARE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/delete.sgml b/zh/19/ref/delete.sgml index e92d5cd2..70981a8e 100644 --- a/zh/19/ref/delete.sgml +++ b/zh/19/ref/delete.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DELETE 7 - SQL - Language Statements + SQL - 语言语句 @@ -157,9 +157,8 @@ DELETE FROM [ ONLY ] table_name [ * start_time - 在时态删除中要更改的最早时间(含)。这必须是与 - range_column_name中的 - 范围基类型匹配的值。这里的NULL值表示删除的起点没有下界(与范围类型一样)。 + 时态删除中要更改的最早时间(含)。这必须是与 + range_column_name所对应范围的基础类型匹配的值。此处的 NULL 值表示删除的起点没有下界(与范围类型一样)。 @@ -168,9 +167,8 @@ DELETE FROM [ ONLY ] table_name [ * end_time - 在时态删除中要更改的最晚时间(不含)。这必须是与 - range_column_name中的 - 范围基类型匹配的值。这里的NULL值表示删除的终点没有上界(与范围类型一样)。 + 时态删除中要更改的最晚时间(不含)。这必须是与 + range_column_name所对应范围的基础类型匹配的值。此处的 NULL 值表示删除的终点没有上界(与范围类型一样)。 diff --git a/zh/19/ref/discard.sgml b/zh/19/ref/discard.sgml index 61abf5a5..5763d317 100644 --- a/zh/19/ref/discard.sgml +++ b/zh/19/ref/discard.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DISCARD 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/do.sgml b/zh/19/ref/do.sgml index b8c2447d..700b5046 100644 --- a/zh/19/ref/do.sgml +++ b/zh/19/ref/do.sgml @@ -15,7 +15,7 @@ PostgreSQL documentation DO 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/drop_access_method.sgml b/zh/19/ref/drop_access_method.sgml index 4a5d09ac..af8ef5bb 100644 --- a/zh/19/ref/drop_access_method.sgml +++ b/zh/19/ref/drop_access_method.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP ACCESS METHOD 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/drop_aggregate.sgml b/zh/19/ref/drop_aggregate.sgml index 77b9763f..97920191 100644 --- a/zh/19/ref/drop_aggregate.sgml +++ b/zh/19/ref/drop_aggregate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP AGGREGATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/drop_cast.sgml b/zh/19/ref/drop_cast.sgml index a7728e2a..dbdd3eef 100644 --- a/zh/19/ref/drop_cast.sgml +++ b/zh/19/ref/drop_cast.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP CAST 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/drop_collation.sgml b/zh/19/ref/drop_collation.sgml index 8dbd7e0c..a1002c5f 100644 --- a/zh/19/ref/drop_collation.sgml +++ b/zh/19/ref/drop_collation.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP COLLATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/drop_conversion.sgml b/zh/19/ref/drop_conversion.sgml index eded9fb9..aa436fbb 100644 --- a/zh/19/ref/drop_conversion.sgml +++ b/zh/19/ref/drop_conversion.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP CONVERSION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/drop_database.sgml b/zh/19/ref/drop_database.sgml index 6bd8086a..5dfe4375 100644 --- a/zh/19/ref/drop_database.sgml +++ b/zh/19/ref/drop_database.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP DATABASE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/drop_domain.sgml b/zh/19/ref/drop_domain.sgml index 5a2d7f2b..31b479a7 100644 --- a/zh/19/ref/drop_domain.sgml +++ b/zh/19/ref/drop_domain.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP DOMAIN 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/drop_event_trigger.sgml b/zh/19/ref/drop_event_trigger.sgml index 74dfad18..5e1ef2c5 100644 --- a/zh/19/ref/drop_event_trigger.sgml +++ b/zh/19/ref/drop_event_trigger.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP EVENT TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -30,7 +30,7 @@ DROP EVENT TRIGGER [ IF EXISTS ] name DROP EVENT TRIGGER移除一个现有的事件触发器。 - 要执行此命令,当前用户必须是该事件触发器的拥有者。 + 要执行此命令,当前用户必须是该事件触发器的所有者。 @@ -99,7 +99,7 @@ DROP EVENT TRIGGER snitch; - 另见 + 参见 diff --git a/zh/19/ref/drop_extension.sgml b/zh/19/ref/drop_extension.sgml index 67f0c30a..6ac9bbef 100644 --- a/zh/19/ref/drop_extension.sgml +++ b/zh/19/ref/drop_extension.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP EXTENSION 7 - SQL - Language Statements + SQL - 语言语句 @@ -59,8 +59,8 @@ DROP EXTENSION [ IF EXISTS ] name [ name - 已安装扩展的名称。 - + 一个已安装扩展的名称。 + @@ -95,7 +95,7 @@ DROP EXTENSION [ IF EXISTS ] name [ DROP EXTENSION hstore; - 如果数据库中正在使用hstore的任何对象, + 如果数据库中使用了hstore的任何对象, 例如某些表具有hstore类型的列,则该命令会失败。 加上CASCADE选项可以强制一并移除这些依赖对象。 diff --git a/zh/19/ref/drop_foreign_data_wrapper.sgml b/zh/19/ref/drop_foreign_data_wrapper.sgml index fda40192..2f53e037 100644 --- a/zh/19/ref/drop_foreign_data_wrapper.sgml +++ b/zh/19/ref/drop_foreign_data_wrapper.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP FOREIGN DATA WRAPPER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/drop_foreign_table.sgml b/zh/19/ref/drop_foreign_table.sgml index 0c8b77b3..a6552df0 100644 --- a/zh/19/ref/drop_foreign_table.sgml +++ b/zh/19/ref/drop_foreign_table.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP FOREIGN TABLE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/drop_function.sgml b/zh/19/ref/drop_function.sgml index b5cc2fd5..91df6bcf 100644 --- a/zh/19/ref/drop_function.sgml +++ b/zh/19/ref/drop_function.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP FUNCTION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/drop_group.sgml b/zh/19/ref/drop_group.sgml index f43389ca..4ee8fc55 100644 --- a/zh/19/ref/drop_group.sgml +++ b/zh/19/ref/drop_group.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP GROUP 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/drop_index.sgml b/zh/19/ref/drop_index.sgml index 1cd21c84..6dcf3c93 100644 --- a/zh/19/ref/drop_index.sgml +++ b/zh/19/ref/drop_index.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP INDEX 7 - SQL - Language Statements + SQL - 语言语句 @@ -57,7 +57,7 @@ DROP INDEX [ CONCURRENTLY ] [ IF EXISTS ] name 对于临时表,DROP INDEX始终是非并发的, - 因为没有其他会话可以访问它们,而且非并发删除索引的成本更低。 + 因为没有其他会话可以访问它们,而且非并发删除索引的代价更低。 @@ -66,7 +66,7 @@ DROP INDEX [ CONCURRENTLY ] [ IF EXISTS ] nameIF EXISTS - 如果该索引不存在,则不要抛出错误。这种情况下会发出一个提示。 + 如果该索引不存在,则不要抛出错误。这种情况下会发出一条提示。 diff --git a/zh/19/ref/drop_language.sgml b/zh/19/ref/drop_language.sgml index 9d551ab7..3069f936 100644 --- a/zh/19/ref/drop_language.sgml +++ b/zh/19/ref/drop_language.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP LANGUAGE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/drop_materialized_view.sgml b/zh/19/ref/drop_materialized_view.sgml index 44df7484..75276556 100644 --- a/zh/19/ref/drop_materialized_view.sgml +++ b/zh/19/ref/drop_materialized_view.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP MATERIALIZED VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/drop_opclass.sgml b/zh/19/ref/drop_opclass.sgml index 0255c3ee..ad861933 100644 --- a/zh/19/ref/drop_opclass.sgml +++ b/zh/19/ref/drop_opclass.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP OPERATOR CLASS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/drop_operator.sgml b/zh/19/ref/drop_operator.sgml index f82c10de..fb279be4 100644 --- a/zh/19/ref/drop_operator.sgml +++ b/zh/19/ref/drop_operator.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP OPERATOR 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/drop_opfamily.sgml b/zh/19/ref/drop_opfamily.sgml index 3baf3659..72f459f2 100644 --- a/zh/19/ref/drop_opfamily.sgml +++ b/zh/19/ref/drop_opfamily.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP OPERATOR FAMILY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/drop_owned.sgml b/zh/19/ref/drop_owned.sgml index cd5fc183..28ffd5de 100644 --- a/zh/19/ref/drop_owned.sgml +++ b/zh/19/ref/drop_owned.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP OWNED 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/drop_policy.sgml b/zh/19/ref/drop_policy.sgml index a7977ed1..8abec1b5 100644 --- a/zh/19/ref/drop_policy.sgml +++ b/zh/19/ref/drop_policy.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP POLICY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/drop_procedure.sgml b/zh/19/ref/drop_procedure.sgml index 62bfed69..d2504beb 100644 --- a/zh/19/ref/drop_procedure.sgml +++ b/zh/19/ref/drop_procedure.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP PROCEDURE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/drop_property_graph.sgml b/zh/19/ref/drop_property_graph.sgml index ad2bc298..7980bc9d 100644 --- a/zh/19/ref/drop_property_graph.sgml +++ b/zh/19/ref/drop_property_graph.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP PROPERTY GRAPH 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/drop_publication.sgml b/zh/19/ref/drop_publication.sgml index c0512c1c..95763bdb 100644 --- a/zh/19/ref/drop_publication.sgml +++ b/zh/19/ref/drop_publication.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP PUBLICATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/drop_role.sgml b/zh/19/ref/drop_role.sgml index 79eeedb9..0405c0d0 100644 --- a/zh/19/ref/drop_role.sgml +++ b/zh/19/ref/drop_role.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP ROLE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/drop_routine.sgml b/zh/19/ref/drop_routine.sgml index 4f2be77f..db15d5d2 100644 --- a/zh/19/ref/drop_routine.sgml +++ b/zh/19/ref/drop_routine.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP ROUTINE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/drop_rule.sgml b/zh/19/ref/drop_rule.sgml index 3fe97817..e775659c 100644 --- a/zh/19/ref/drop_rule.sgml +++ b/zh/19/ref/drop_rule.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP RULE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/drop_schema.sgml b/zh/19/ref/drop_schema.sgml index 7542159b..48c1cc60 100644 --- a/zh/19/ref/drop_schema.sgml +++ b/zh/19/ref/drop_schema.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP SCHEMA 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/drop_sequence.sgml b/zh/19/ref/drop_sequence.sgml index 4cb78e40..f50822ee 100644 --- a/zh/19/ref/drop_sequence.sgml +++ b/zh/19/ref/drop_sequence.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP SEQUENCE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/drop_server.sgml b/zh/19/ref/drop_server.sgml index ccedb62b..fe768d68 100644 --- a/zh/19/ref/drop_server.sgml +++ b/zh/19/ref/drop_server.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP SERVER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/drop_statistics.sgml b/zh/19/ref/drop_statistics.sgml index 42c7dd99..c3285b6d 100644 --- a/zh/19/ref/drop_statistics.sgml +++ b/zh/19/ref/drop_statistics.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP STATISTICS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/drop_subscription.sgml b/zh/19/ref/drop_subscription.sgml index dec6abb9..6574c345 100644 --- a/zh/19/ref/drop_subscription.sgml +++ b/zh/19/ref/drop_subscription.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP SUBSCRIPTION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/drop_table.sgml b/zh/19/ref/drop_table.sgml index ea3f869f..cc8c507c 100644 --- a/zh/19/ref/drop_table.sgml +++ b/zh/19/ref/drop_table.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TABLE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/drop_tablespace.sgml b/zh/19/ref/drop_tablespace.sgml index b075422e..3ed64693 100644 --- a/zh/19/ref/drop_tablespace.sgml +++ b/zh/19/ref/drop_tablespace.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TABLESPACE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/drop_transform.sgml b/zh/19/ref/drop_transform.sgml index 04145cf9..32f7d6db 100644 --- a/zh/19/ref/drop_transform.sgml +++ b/zh/19/ref/drop_transform.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TRANSFORM 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/drop_trigger.sgml b/zh/19/ref/drop_trigger.sgml index abc17538..240782df 100644 --- a/zh/19/ref/drop_trigger.sgml +++ b/zh/19/ref/drop_trigger.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -30,7 +30,7 @@ DROP TRIGGER [ IF EXISTS ] name ON DROP TRIGGER移除一个现有触发器的定义。 - 要执行此命令,当前用户必须是定义该触发器的表的拥有者。 + 要执行此命令,当前用户必须是定义该触发器的表的所有者。 @@ -109,7 +109,7 @@ DROP TRIGGER if_dist_exists ON films; - 另见 + 参见 diff --git a/zh/19/ref/drop_tsconfig.sgml b/zh/19/ref/drop_tsconfig.sgml index eee3e895..bf58e675 100644 --- a/zh/19/ref/drop_tsconfig.sgml +++ b/zh/19/ref/drop_tsconfig.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TEXT SEARCH CONFIGURATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/drop_tsdictionary.sgml b/zh/19/ref/drop_tsdictionary.sgml index 14bcf3cb..ff4362e2 100644 --- a/zh/19/ref/drop_tsdictionary.sgml +++ b/zh/19/ref/drop_tsdictionary.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TEXT SEARCH DICTIONARY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/drop_tsparser.sgml b/zh/19/ref/drop_tsparser.sgml index 630893a0..592ce807 100644 --- a/zh/19/ref/drop_tsparser.sgml +++ b/zh/19/ref/drop_tsparser.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TEXT SEARCH PARSER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/drop_tstemplate.sgml b/zh/19/ref/drop_tstemplate.sgml index dcbec6ef..1d05b98c 100644 --- a/zh/19/ref/drop_tstemplate.sgml +++ b/zh/19/ref/drop_tstemplate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TEXT SEARCH TEMPLATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/drop_type.sgml b/zh/19/ref/drop_type.sgml index e6d25ffb..0699eb0f 100644 --- a/zh/19/ref/drop_type.sgml +++ b/zh/19/ref/drop_type.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TYPE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/drop_user.sgml b/zh/19/ref/drop_user.sgml index 00d1d5f4..2e61d6ef 100644 --- a/zh/19/ref/drop_user.sgml +++ b/zh/19/ref/drop_user.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP USER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/drop_user_mapping.sgml b/zh/19/ref/drop_user_mapping.sgml index 775ebb59..a0d4be08 100644 --- a/zh/19/ref/drop_user_mapping.sgml +++ b/zh/19/ref/drop_user_mapping.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP USER MAPPING 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/drop_view.sgml b/zh/19/ref/drop_view.sgml index 3af915af..b85a66dc 100644 --- a/zh/19/ref/drop_view.sgml +++ b/zh/19/ref/drop_view.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/dropdb.sgml b/zh/19/ref/dropdb.sgml index f8a773f8..99de88e3 100644 --- a/zh/19/ref/dropdb.sgml +++ b/zh/19/ref/dropdb.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation dropdb 1 - Application + 应用程序 diff --git a/zh/19/ref/dropuser.sgml b/zh/19/ref/dropuser.sgml index 31bfb3d7..3f7468b3 100644 --- a/zh/19/ref/dropuser.sgml +++ b/zh/19/ref/dropuser.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation dropuser 1 - Application + 应用程序 diff --git a/zh/19/ref/ecpg-ref.sgml b/zh/19/ref/ecpg-ref.sgml index 002b8ef1..506be589 100644 --- a/zh/19/ref/ecpg-ref.sgml +++ b/zh/19/ref/ecpg-ref.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ecpg 1 - Application + 应用程序 diff --git a/zh/19/ref/end.sgml b/zh/19/ref/end.sgml index 3765c7b5..b70192fc 100644 --- a/zh/19/ref/end.sgml +++ b/zh/19/ref/end.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation END 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/execute.sgml b/zh/19/ref/execute.sgml index 59a59eb4..796a77ee 100644 --- a/zh/19/ref/execute.sgml +++ b/zh/19/ref/execute.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation EXECUTE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/explain.sgml b/zh/19/ref/explain.sgml index 95cf965d..1cb55503 100644 --- a/zh/19/ref/explain.sgml +++ b/zh/19/ref/explain.sgml @@ -21,7 +21,7 @@ PostgreSQL documentation EXPLAIN 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/fetch.sgml b/zh/19/ref/fetch.sgml index 71c12406..9ab88c49 100644 --- a/zh/19/ref/fetch.sgml +++ b/zh/19/ref/fetch.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation FETCH 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/grant.sgml b/zh/19/ref/grant.sgml index 9f0d8e8c..73fdab4e 100644 --- a/zh/19/ref/grant.sgml +++ b/zh/19/ref/grant.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation GRANT 7 - SQL - Language Statements + SQL - 语言语句 @@ -107,7 +107,7 @@ GRANT role_name [, ...] TO role_specification ] -where role_specification can be: +其中role_specification可以是: [ GROUP ] role_name | PUBLIC diff --git a/zh/19/ref/import_foreign_schema.sgml b/zh/19/ref/import_foreign_schema.sgml index 4fee82c8..4964a0d8 100644 --- a/zh/19/ref/import_foreign_schema.sgml +++ b/zh/19/ref/import_foreign_schema.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation IMPORT FOREIGN SCHEMA 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/initdb.sgml b/zh/19/ref/initdb.sgml index b2c8f502..efa40aa9 100644 --- a/zh/19/ref/initdb.sgml +++ b/zh/19/ref/initdb.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation initdb 1 - Application + 应用程序 @@ -208,7 +208,7 @@ PostgreSQL documentation - 当使用 ICU 提供程序时,指定 ICU 区域设置 ID。区域设置支持见 + 当使用 ICU 提供程序时,指定 ICU 区域设置。区域设置支持见 diff --git a/zh/19/ref/insert.sgml b/zh/19/ref/insert.sgml index 5aa626b5..159feffa 100644 --- a/zh/19/ref/insert.sgml +++ b/zh/19/ref/insert.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation INSERT 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/listen.sgml b/zh/19/ref/listen.sgml index cbf4b4dd..0c62a7c8 100644 --- a/zh/19/ref/listen.sgml +++ b/zh/19/ref/listen.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation LISTEN 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/load.sgml b/zh/19/ref/load.sgml index bb0adb7c..89bdb114 100644 --- a/zh/19/ref/load.sgml +++ b/zh/19/ref/load.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation LOAD 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/lock.sgml b/zh/19/ref/lock.sgml index bc45eec4..fce3ac96 100644 --- a/zh/19/ref/lock.sgml +++ b/zh/19/ref/lock.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation LOCK 7 - SQL - Language Statements + SQL - 语言语句 @@ -55,7 +55,7 @@ LOCK [ TABLE ] [ ONLY ] name [ * ] 因为SHARE锁模式与写入者获取的ROW EXCLUSIVE锁冲突, 而LOCK TABLE name IN SHARE MODE - 语句会一直等待,直到任何并发持有ROW EXCLUSIVE模式锁的事务提交或回滚。 + 语句会一直等待,直到所有并发持有ROW EXCLUSIVE模式锁的事务提交或回滚。 因此,一旦获得该锁,就不存在尚未提交的写入;而且在释放该锁之前,也不会有新的写入开始。 @@ -166,9 +166,7 @@ LOCK [ TABLE ] [ ONLY ] name [ * ] 这些模式名称通常应理解为:用户打算在被锁定的表中获取行级锁。 此外,ROW EXCLUSIVE模式本身也是一种可共享的表锁。 请记住,就LOCK TABLE而言,所有锁模式的语义完全相同, - 差别只在于哪些模式彼此冲突。关于如何获取真正的行级锁,请参阅 - 文档中的和 - 。 + 差别只在于哪些模式彼此冲突。关于如何获取真正的行级锁,请参阅 (后者位于文档中)。 diff --git a/zh/19/ref/merge.sgml b/zh/19/ref/merge.sgml index 4c108efd..bd32bf3b 100644 --- a/zh/19/ref/merge.sgml +++ b/zh/19/ref/merge.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation MERGE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/move.sgml b/zh/19/ref/move.sgml index e90c1b88..961359c8 100644 --- a/zh/19/ref/move.sgml +++ b/zh/19/ref/move.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation MOVE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/notify.sgml b/zh/19/ref/notify.sgml index f43e8ce1..1f68ddfc 100644 --- a/zh/19/ref/notify.sgml +++ b/zh/19/ref/notify.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation NOTIFY 7 - SQL - Language Statements + SQL - 语言语句 @@ -88,7 +88,7 @@ NOTIFY channel [ , 注解 - 系统中有一个队列,用来保存那些已经发送但尚未被所有监听会话处理的通知。如果这个队列被塞满,那么调用NOTIFY的事务会在提交时失败。该队列非常大(标准安装中为 8GB),几乎足以满足所有用例。不过,如果某个会话执行了LISTEN后又长时间停留在一个事务里,就无法进行清理。一旦队列占用超过一半,你就会在日志文件中看到警告,指出究竟是哪个会话阻碍了清理。在这种情况下,应确保该会话结束其当前事务,以便清理能够继续进行。 + 系统中有一个队列,用来保存那些已经发送但尚未被所有监听会话处理的通知。如果这个队列被塞满,那么调用NOTIFY的事务会在提交时失败。该队列非常大(标准安装中为 8GB),几乎足以满足所有用例。不过,如果某个会话执行了LISTEN后又长时间停留在一个事务里,就无法进行清理。一旦队列占用达到一半,你就会在日志文件中看到警告,指出究竟是哪个会话阻碍了清理。在这种情况下,应确保该会话结束其当前事务,以便清理能够继续进行。 函数pg_notification_queue_usage返回当前被待处理通知占用的队列比例。详见。 diff --git a/zh/19/ref/pg_amcheck.sgml b/zh/19/ref/pg_amcheck.sgml index 855c42dd..55a6e2b7 100644 --- a/zh/19/ref/pg_amcheck.sgml +++ b/zh/19/ref/pg_amcheck.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_amcheck 1 - Application + 应用程序 diff --git a/zh/19/ref/pg_basebackup.sgml b/zh/19/ref/pg_basebackup.sgml index 28e9ac27..1b4c050a 100644 --- a/zh/19/ref/pg_basebackup.sgml +++ b/zh/19/ref/pg_basebackup.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation pg_basebackup 1 - Application + 应用程序 @@ -80,7 +80,7 @@ PostgreSQL documentation - 备份所需的所有 WAL 记录都必须包含足够的全页写入, + 备份所需的所有 WAL 记录都必须包含足够的整页写入, 因此必须在主库上启用full_page_writes @@ -217,7 +217,7 @@ PostgreSQL documentation - 目前,此选项仅适用于 plain 输出格式;如果选择了 tar 格式,则会被忽略。 + 目前,此选项仅适用于 普通文件 输出格式;如果选择了 tar 格式,则会被忽略。 @@ -227,7 +227,7 @@ PostgreSQL documentation - 设置写入 WAL(预写式日志)文件的目录。默认情况下,WAL 文件会放在目标目录的pg_wal子目录中,但此选项可用于将其放在其他位置。waldir必须是绝对路径。与主目标目录一样,waldir不必事先存在,但如果存在则必须为空。只有当备份采用 plain 格式时,才能指定此选项。 + 设置写入 WAL(预写式日志)文件的目录。默认情况下,WAL 文件会放在目标目录的pg_wal子目录中,但此选项可用于将其放在其他位置。waldir必须是绝对路径。与主目标目录一样,waldir不必事先存在,但如果存在则必须为空。只有当备份采用 普通文件 格式时,才能指定此选项。 @@ -319,7 +319,7 @@ PostgreSQL documentation - 当 tar 格式配合gziplz4zstd使用时,所有 tar 文件名都会分别自动加上.gz.lz4.zst后缀。使用 plain 格式时,不能指定客户端压缩,但仍可以请求服务器端压缩。这样做时,服务器会先压缩备份再传输,而客户端会对其进行解压并提取。 + 当 tar 格式配合gziplz4zstd使用时,所有 tar 文件名都会分别自动加上.gz.lz4.zst后缀。使用 普通文件 格式时,不能指定客户端压缩,但仍可以请求服务器端压缩。这样做时,服务器会先压缩备份再传输,而客户端会对其进行解压并提取。 @@ -379,7 +379,7 @@ PostgreSQL documentation - 请注意,无论如何表空间目录都不会被清理。 + 请注意,无论是否使用此选项,表空间目录都不会被清理。 @@ -427,7 +427,7 @@ PostgreSQL documentation - 此选项只能与-X stream一起使用。它会使 WAL 流式传输使用指定的复制槽。如果此基础备份打算用作使用复制槽的流复制备库,那么该备库应使用与相同的复制槽名称。这样可以确保主库在基础备份结束与新备库开始流复制之间的这段时间内,不会移除任何必需的 WAL 数据。 + 此选项只能与-X stream一起使用。它会使 WAL 流式传输使用指定的复制槽。如果此基础备份打算用作使用复制槽的流复制备库,那么该备库应将同一个复制槽名称用作的值。这样可以确保主库在基础备份结束与新备库开始流复制之间的这段时间内,不会移除任何必需的 WAL 数据。 @@ -444,10 +444,10 @@ PostgreSQL documentation - 设置为fsync(默认)时,pg_basebackup会递归打开并同步备份目录中的所有文件。使用 plain 格式时,查找文件会跟随 WAL 目录和各已配置表空间的符号链接。 + 设置为fsync(默认)时,pg_basebackup会递归打开并同步备份目录中的所有文件。使用 普通文件 格式时,查找文件会跟随 WAL 目录和各已配置表空间的符号链接。 - 在 Linux 上,也可以使用syncfs,让操作系统同步包含备份目录的整个文件系统。使用 plain 格式时,pg_basebackup还会同步包含 WAL 文件和各表空间的文件系统。关于使用syncfs时需要注意的限制,见。 + 在 Linux 上,也可以使用syncfs,让操作系统同步包含备份目录的整个文件系统。使用 普通文件 格式时,pg_basebackup还会同步包含 WAL 文件和各表空间的文件系统。关于使用syncfs时需要注意的事项,见 使用时,此选项无效。 @@ -479,7 +479,7 @@ PostgreSQL documentation - 对于希望验证备份未被篡改的用户,使用 SHA 哈希函数可以为每个文件提供具有密码学安全性的摘要;而 CRC-32C 算法提供的校验和计算速度要快得多,虽然它很适合发现由于意外改动造成的错误,但并不能抵御恶意修改。请注意,要想对能够访问备份的攻击者形成防护,备份清单就需要安全地保存在其他地方,或者以其他方式确认自备份完成后未被修改。 + 对于希望验证备份未被篡改的用户,使用 SHA hash 函数可以为每个文件提供具有密码学安全性的摘要;而 CRC-32C 算法提供的校验和计算速度要快得多,虽然它很适合发现由于意外改动造成的错误,但并不能抵御恶意修改。请注意,要想对能够访问备份的攻击者形成防护,备份清单就需要安全地保存在其他地方,或者以其他方式确认自备份完成后未被修改。 @@ -687,7 +687,7 @@ PostgreSQL documentation - 注意 + 注解 在备份开始时,需要在源服务器上执行一次检查点。这可能需要一些时间(尤其是在未使用--checkpoint=fast选项时);在此期间,pg_basebackup看起来会处于空闲状态。 @@ -698,7 +698,7 @@ PostgreSQL documentation - 在 plain 格式中,除非使用了--tablespace-mapping选项,否则表空间会备份到其在源服务器上的相同路径。如果不使用此选项,那么当表空间正在使用时,就无法在与服务器相同的主机上执行 plain 格式的基础备份,因为备份将不得不写入与原始表空间相同的目录位置。 + 在 普通文件 格式中,除非使用了--tablespace-mapping选项,否则表空间会备份到其在源服务器上的相同路径。如果不使用此选项,那么当表空间正在使用时,就无法在与服务器相同的主机上执行 普通文件 格式的基础备份,因为备份将不得不写入与原始表空间相同的目录位置。 @@ -758,7 +758,7 @@ PostgreSQL documentation - 参见 + 另见 diff --git a/zh/19/ref/pg_checksums.sgml b/zh/19/ref/pg_checksums.sgml index 6b2a30fe..4bf3455f 100644 --- a/zh/19/ref/pg_checksums.sgml +++ b/zh/19/ref/pg_checksums.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_checksums 1 - Application + 应用程序 diff --git a/zh/19/ref/pg_combinebackup.sgml b/zh/19/ref/pg_combinebackup.sgml index 5ae1aa14..c9ebcedf 100644 --- a/zh/19/ref/pg_combinebackup.sgml +++ b/zh/19/ref/pg_combinebackup.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_combinebackup 1 - Application + 应用程序 @@ -239,18 +239,18 @@ PostgreSQL documentation 当设置为fsync(这是默认值)时, pg_combinebackup会递归打开并同步备份目录中的所有文件。 - 使用 plain 格式时,搜索文件时会跟随 WAL 目录和每个已配置表空间的符号链接。 + 使用 普通文件 格式时,搜索文件时会跟随 WAL 目录和每个已配置表空间的符号链接。 在 Linux 上,也可以改用syncfs, 让操作系统同步包含备份目录的整个文件系统。 - 使用 plain 格式时,pg_combinebackup + 使用 普通文件 格式时,pg_combinebackup 还会同步包含 WAL 文件和各表空间的文件系统。 关于使用syncfs时需要注意的事项,请参见 - 当使用时,此选项无效。 + 使用时,此选项无效。 @@ -302,15 +302,11 @@ PostgreSQL documentation 环境 - 与多数PostgreSQL工具一样, - 本工具使用libpq支持的环境变量 - (参见)。 + 与大多数其他PostgreSQL工具一样,此工具也使用libpq支持的环境变量(见)。 - 环境变量PG_COLOR指定诊断消息是否使用颜色。 - 可选值为alwaysauto和 - never。 + 环境变量PG_COLOR指定是否在诊断消息中使用颜色。可能的值为alwaysautonever diff --git a/zh/19/ref/pg_config-ref.sgml b/zh/19/ref/pg_config-ref.sgml index 565638d9..b157f24c 100644 --- a/zh/19/ref/pg_config-ref.sgml +++ b/zh/19/ref/pg_config-ref.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation pg_config 1 - Application + 应用程序 diff --git a/zh/19/ref/pg_controldata.sgml b/zh/19/ref/pg_controldata.sgml index f52e7980..ece80b04 100644 --- a/zh/19/ref/pg_controldata.sgml +++ b/zh/19/ref/pg_controldata.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_controldata 1 - Application + 应用程序 diff --git a/zh/19/ref/pg_createsubscriber.sgml b/zh/19/ref/pg_createsubscriber.sgml index ede4fdc5..406f1b73 100644 --- a/zh/19/ref/pg_createsubscriber.sgml +++ b/zh/19/ref/pg_createsubscriber.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_createsubscriber 1 - Application + 应用程序 @@ -201,7 +201,7 @@ PostgreSQL documentation - 等待恢复结束的最大秒数。设为 0 表示禁用。 + 等待恢复结束的最大秒数。设为 0 表示禁用超时限制。 默认值为 0。 @@ -350,7 +350,7 @@ PostgreSQL documentation - 注意 + 注解 前置条件 @@ -442,7 +442,7 @@ PostgreSQL documentation 若缺少必需 WAL 文件,复制可能失败。 - 为避免该问题,源服务器应将 + 为避免该问题,源服务器必须将 设置为-1, 以确保必需 WAL 文件不会被提前移除。 @@ -493,12 +493,13 @@ PostgreSQL documentation 将恢复参数写入目标数据目录中的独立配置文件 pg_createsubscriber.conf,该文件通过目标数据目录中的 postgresql.auto.conf 里的 include_if_exists - 引入,然后重启目标服务器。它指定了恢复将推进到的预写式日志位置的 LSN()。 - 它还将promote指定为服务器在达到恢复目标 后应执行的动作。 - 为了避免恢复过程中出现意外行为,还会添加其他恢复参数,例如在达到一致状态后就结束恢复 - (实际上 WAL 应继续应用到复制起始位置)以及因多个恢复目标而导致失败。 + 它还将promote指定为服务器在达到恢复目标后应执行的动作。 + 还会添加其他恢复参数,以避免恢复过程中出现意外行为, + 例如一达到一致状态就结束恢复(WAL 应继续应用到复制起始位置),或者因指定多个恢复目标而失败。 当服务器退出备库模式并接受读写事务时,该步骤结束。 如果设置了选项,而恢复在给定秒数内没有结束, pg_createsubscriber就会终止。 diff --git a/zh/19/ref/pg_ctl-ref.sgml b/zh/19/ref/pg_ctl-ref.sgml index 6085da56..801cbc55 100644 --- a/zh/19/ref/pg_ctl-ref.sgml +++ b/zh/19/ref/pg_ctl-ref.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation pg_ctl 1 - Application + 应用程序 diff --git a/zh/19/ref/pg_dump.sgml b/zh/19/ref/pg_dump.sgml index bc1d3f5a..b0587c6f 100644 --- a/zh/19/ref/pg_dump.sgml +++ b/zh/19/ref/pg_dump.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_dump 1 - Application + 应用程序 diff --git a/zh/19/ref/pg_dumpall.sgml b/zh/19/ref/pg_dumpall.sgml index 41476567..7a457c0d 100644 --- a/zh/19/ref/pg_dumpall.sgml +++ b/zh/19/ref/pg_dumpall.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_dumpall 1 - Application + 应用程序 diff --git a/zh/19/ref/pg_isready.sgml b/zh/19/ref/pg_isready.sgml index 2e93dde1..a09f7745 100644 --- a/zh/19/ref/pg_isready.sgml +++ b/zh/19/ref/pg_isready.sgml @@ -13,7 +13,7 @@ PostgreSQL documentation pg_isready 1 - Application + 应用程序 diff --git a/zh/19/ref/pg_receivewal.sgml b/zh/19/ref/pg_receivewal.sgml index 3c9e580a..bf520c28 100644 --- a/zh/19/ref/pg_receivewal.sgml +++ b/zh/19/ref/pg_receivewal.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation pg_receivewal 1 - Application + 应用程序 diff --git a/zh/19/ref/pg_recvlogical.sgml b/zh/19/ref/pg_recvlogical.sgml index 0fcc322f..b1fd09ae 100644 --- a/zh/19/ref/pg_recvlogical.sgml +++ b/zh/19/ref/pg_recvlogical.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation pg_recvlogical 1 - Application + 应用程序 @@ -155,7 +155,7 @@ PostgreSQL documentation - 启用后会将该槽同步到备库。此选项只能与 一起指定。 + 允许将该槽同步到备库。此选项只能与 一起指定。 @@ -181,7 +181,7 @@ PostgreSQL documentation 指定pg_recvlogical应当以多高的频率发起fsync()调用, - 以确保输出文件被安全地刷入磁盘。默认值为 10 秒。 + 以确保输出文件安全刷盘。默认值为 10 秒。 diff --git a/zh/19/ref/pg_resetwal.sgml b/zh/19/ref/pg_resetwal.sgml index c91fc159..e66029f0 100644 --- a/zh/19/ref/pg_resetwal.sgml +++ b/zh/19/ref/pg_resetwal.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_resetwal 1 - Application + 应用程序 diff --git a/zh/19/ref/pg_restore.sgml b/zh/19/ref/pg_restore.sgml index 00084b61..6ceac514 100644 --- a/zh/19/ref/pg_restore.sgml +++ b/zh/19/ref/pg_restore.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_restore 1 - Application + 应用程序 diff --git a/zh/19/ref/pg_rewind.sgml b/zh/19/ref/pg_rewind.sgml index 9df82094..6c1119f8 100644 --- a/zh/19/ref/pg_rewind.sgml +++ b/zh/19/ref/pg_rewind.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation pg_rewind 1 - Application + 应用程序 diff --git a/zh/19/ref/pg_verifybackup.sgml b/zh/19/ref/pg_verifybackup.sgml index 68ca0ec6..8cb2f638 100644 --- a/zh/19/ref/pg_verifybackup.sgml +++ b/zh/19/ref/pg_verifybackup.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_verifybackup 1 - Application + 应用程序 @@ -32,7 +32,7 @@ PostgreSQL documentation pg_verifybackup用于依据服务器在备份时生成的 backup_manifest,检查使用 pg_basebackup获取的数据库集簇备份的完整性。备份 - 既可以采用“plain”格式,也可以采用“tar”格式;其中也包括使用 + 既可以采用“普通文件”格式,也可以采用“tar”格式;其中也包括使用 pg_basebackup支持的任意算法压缩的 tar 格 式备份。 @@ -40,8 +40,7 @@ PostgreSQL documentation 需要注意,pg_verifybackup执行的验证并未、也 不可能涵盖运行中的服务器在尝试使用该备份时会执行的每一项检查。即使使 - 用了此工具,你仍应进行测试恢复,并确认生成的数据库按预期工作且包含正 - 确的数据。不过,pg_verifybackup能够检测出 + 用了此工具,你仍应进行测试恢复,并确认生成的数据库按预期工作且看起来包含正确的数据。不过,pg_verifybackup能够检测出 许多因存储问题或用户错误而常见的问题。 @@ -139,9 +138,7 @@ PostgreSQL documentation tar - 备份由 tar 文件组成,这些文件可以经过压缩。有效的备份包括名为 - base.tar的主数据目录、名为 - pg_wal.tar的 WAL 文件,以及每个表空间 + 备份由 tar 文件组成,这些文件可以经过压缩。有效的备份包括存放在 base.tar文件中的主数据目录、存放在 pg_wal.tar中的 WAL 文件,以及每个表空间 对应的单独 tar 文件,这些文件以该表空间的 OID 命名。如果备份 被压缩,则会在每个文件名末尾追加相应的压缩扩展名。 @@ -236,9 +233,9 @@ PostgreSQL documentation - 还提供下列其他选项: + 其他选项也可用: - + @@ -269,7 +266,7 @@ PostgreSQL documentation 示例 - 要在mydbserver上创建服务器的基础备份,并验证该备 + 要为位于mydbserver的服务器创建基础备份,并验证该备 份的完整性: $ pg_basebackup -h mydbserver -D /usr/local/pgsql/data @@ -278,7 +275,7 @@ PostgreSQL documentation - 要在mydbserver上创建服务器的基础备份,将备份清单 + 要为位于mydbserver的服务器创建基础备份,将备份清单 移到备份目录之外的位置,然后验证该备份: $ pg_basebackup -h mydbserver -D /usr/local/pgsql/backup1234 diff --git a/zh/19/ref/pg_waldump.sgml b/zh/19/ref/pg_waldump.sgml index f0d8c983..bd273f47 100644 --- a/zh/19/ref/pg_waldump.sgml +++ b/zh/19/ref/pg_waldump.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_waldump 1 - Application + 应用程序 diff --git a/zh/19/ref/pg_walsummary.sgml b/zh/19/ref/pg_walsummary.sgml index ff2e68da..3cc08b5e 100644 --- a/zh/19/ref/pg_walsummary.sgml +++ b/zh/19/ref/pg_walsummary.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_walsummary 1 - Application + 应用程序 @@ -31,7 +31,7 @@ PostgreSQL documentation 描述 pg_walsummary用于打印 WAL 汇总文件的内容。 - 这些二进制文件位于数据目录的pg_wal/summaries子目录中, + 这些二进制文件位于数据目录下的pg_wal/summaries子目录中, 可使用本工具将其转换为文本。 通常并无此必要,因为 WAL 汇总文件主要是为了支持 增量备份而存在的, @@ -41,11 +41,11 @@ PostgreSQL documentation WAL 汇总文件按表空间 OID、关系 OID 以及关系分支(fork)建立索引。 对于每个关系分支,它都存储该文件所汇总范围内被 WAL 修改的块列表。 - 它还可以存储一个limit block: + 它还可以存储一个界限块: 如果该关系分支在相关 WAL 范围内被创建或截断,则其值为 0; 否则,其值为该关系分支被截断后的最短长度。 如果该关系分支在相关 WAL 范围内未被创建、删除或截断, - 则 limit block 未定义,或者为无穷大,本工具不会打印它。 + 则 界限块 未定义,或者为无穷大,本工具不会打印它。 @@ -117,9 +117,7 @@ PostgreSQL documentation 环境 - 环境变量PG_COLOR用于指定是否在诊断消息中使用颜色。 - 可能的值为alwaysauto和 - never。 + 环境变量PG_COLOR指定是否在诊断消息中使用颜色。可能的值为alwaysautonever diff --git a/zh/19/ref/pgarchivecleanup.sgml b/zh/19/ref/pgarchivecleanup.sgml index efb1cea4..67eec297 100644 --- a/zh/19/ref/pgarchivecleanup.sgml +++ b/zh/19/ref/pgarchivecleanup.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_archivecleanup 1 - Application + 应用程序 diff --git a/zh/19/ref/pgbench.sgml b/zh/19/ref/pgbench.sgml index 6a0c16e5..3fc38e07 100644 --- a/zh/19/ref/pgbench.sgml +++ b/zh/19/ref/pgbench.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation pgbench 1 - Application + 应用程序 @@ -1701,7 +1701,7 @@ SELECT 4 AS four \; SELECT 5 AS five \aset greatest ( number , ... ) - double 如果任何参数是双精度的,否则 integer + 若任一参数为 double,则为 double,否则为 integer 选择参数中的最大值。 @@ -1771,7 +1771,7 @@ SELECT 4 AS four \; SELECT 5 AS five \aset least ( number , ... ) - double 如果任何参数是双精度的,否则 integer + 若任一参数为 double,则为 double,否则为 integer 选择参数中的最小值。 @@ -2629,7 +2629,7 @@ PGOPTIONS='-c default_table_access_method=wuzza' 安全性 - 如果不可信用户能够访问尚未采用模式的安全使用方式的数据库,就不要在该数据库中运行pgbenchpgbench使用非限定名称,并且不会更改搜索路径。 + 如果不受信任的用户能够访问尚未采用模式的安全使用方式的数据库,就不要在该数据库中运行pgbenchpgbench使用非限定名称,并且不会更改搜索路径。 diff --git a/zh/19/ref/pgtestfsync.sgml b/zh/19/ref/pgtestfsync.sgml index 86e69b30..6055bccf 100644 --- a/zh/19/ref/pgtestfsync.sgml +++ b/zh/19/ref/pgtestfsync.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_test_fsync 1 - Application + 应用程序 diff --git a/zh/19/ref/pgtesttiming.sgml b/zh/19/ref/pgtesttiming.sgml index a0141898..e6240d3b 100644 --- a/zh/19/ref/pgtesttiming.sgml +++ b/zh/19/ref/pgtesttiming.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_test_timing 1 - Application + 应用程序 diff --git a/zh/19/ref/pgupgrade.sgml b/zh/19/ref/pgupgrade.sgml index 474b6982..6cd18304 100644 --- a/zh/19/ref/pgupgrade.sgml +++ b/zh/19/ref/pgupgrade.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_upgrade 1 - Application + 应用程序 @@ -40,7 +40,7 @@ PostgreSQL documentation pg_upgrade(以前称为 pg_migrator)允许将存储在 PostgreSQL 数据文件中的数据升级到更新的 PostgreSQL主版本,而无需执行主版本升级通常所需的数据转储/恢复, - 例如从 12.14 升级到 13.10,或从 14.9 升级到 15.5。它不用于次版本升级, + 例如从 12.14 升级到 13.10,或从 14.9 升级到 15.5。次版本升级不需要使用它, 例如从 12.7 升级到 12.8 或从 14.1 升级到 14.5。 @@ -340,7 +340,7 @@ PostgreSQL documentation 这里不介绍升级 - 逻辑复制集簇 + 逻辑复制集群 的步骤;详见 diff --git a/zh/19/ref/postgres-ref.sgml b/zh/19/ref/postgres-ref.sgml index cadfc5ba..8d200e74 100644 --- a/zh/19/ref/postgres-ref.sgml +++ b/zh/19/ref/postgres-ref.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation postgres 1 - Application + 应用程序 @@ -532,7 +532,7 @@ PostgreSQL documentation - 表明另一台服务器已经在运行的失败消息 + 表明另一个服务器已经在运行的失败消息 应仔细检查,例如可根据你的系统使用下面的命令: $ ps ax | grep postgres @@ -721,7 +721,7 @@ PostgreSQL documentation - 参见 + 另见 , diff --git a/zh/19/ref/prepare.sgml b/zh/19/ref/prepare.sgml index 6c456821..20228fb4 100644 --- a/zh/19/ref/prepare.sgml +++ b/zh/19/ref/prepare.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation PREPARE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/prepare_transaction.sgml b/zh/19/ref/prepare_transaction.sgml index 2e875038..bccc8861 100644 --- a/zh/19/ref/prepare_transaction.sgml +++ b/zh/19/ref/prepare_transaction.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation PREPARE TRANSACTION 7 - SQL - Language Statements + SQL - 语言语句 @@ -72,7 +72,7 @@ PREPARE TRANSACTION transaction_id - 当前不允许将执行过以下任一操作的事务置为预备状态:涉及临时表或会话临时命名空间的操作、创建任何WITH HOLD游标,或执行过LISTENUNLISTENNOTIFY。这些特性与当前会话绑定得过于紧密,因此在要进入预备状态的事务中没有意义。 + 当前不允许对执行过以下任一操作的事务执行PREPARE:涉及临时表或会话临时命名空间的操作、创建任何WITH HOLD游标,或执行过LISTENUNLISTENNOTIFY。这些特性与当前会话绑定得过于紧密,因此在要进入预备状态的事务中没有意义。 diff --git a/zh/19/ref/psql-ref.sgml b/zh/19/ref/psql-ref.sgml index 9ce54280..552af7fb 100644 --- a/zh/19/ref/psql-ref.sgml +++ b/zh/19/ref/psql-ref.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation psql 1 - Application + 应用程序 @@ -534,7 +534,7 @@ testdb=> - 如果不可信用户能够访问尚未采用模式的安全使用方式的数据库,请在会话开始时从search_path中移除所有公众可写的 schema。可以在连接字符串中加入options=-csearch_path=,或者在执行其他 SQL 命令之前发出SELECT pg_catalog.set_config('search_path', '', false)。这种考虑并非psql特有;它适用于任何执行任意 SQL 命令的接口。 + 如果不受信任的用户能够访问尚未采用模式的安全使用方式的数据库,请在会话开始时从search_path中移除所有公众可写的模式。可以在连接字符串中加入options=-csearch_path=,或者在执行其他 SQL 命令之前发出SELECT pg_catalog.set_config('search_path', '', false)。这种考虑并非psql特有;它适用于任何执行任意 SQL 命令的接口。 @@ -587,7 +587,7 @@ testdb=> - 定义了以下元命令: + 定义了以下元命令: @@ -686,7 +686,7 @@ INSERT INTO tbls1 VALUES ($1, $2) \parse stmt1 - 示例: + 示例: => \c mydb myuser host.dom 6432 @@ -1659,11 +1659,7 @@ CREATE INDEX - 生成的查询按照返回的行的顺序执行,并在每行内从左到右执行,如果有多个列。NULL字段将被忽略。生成的查询文字 - 直接发送到服务器进行处理,因此它们不能是psql元命令,也不能包含psql - 变量引用。如果任何单个查询失败,剩余查询的执行将继续,除非设置了ON_ERROR_STOP。每个查询的执行 - 都受ECHO处理的影响。(通常在使用\gexec时,将ECHO设置为 - allqueries是明智的。)查询记录、单步模式、计时和其他查询执行功能也适用于每个生成的查询。 + 生成的查询按照返回行的顺序执行;如果有多列,则在每行内从左到右执行。NULL 字段会被忽略。生成的查询按原样发送到服务器进行处理,因此不能是psql元命令,也不能包含psql变量引用。如果某个查询失败,仍会继续执行其余查询,除非设置了ON_ERROR_STOP。每个查询的执行都受ECHO处理的影响。(通常,在使用\gexec时,适宜将ECHO设为allqueries。)查询日志、单步模式、计时及其他查询执行功能也适用于每个生成的查询。 如果当前查询缓冲区为空,则重新执行最近发送的查询。 @@ -1903,7 +1899,7 @@ SELECT - 将文件存储到一个PostgreSQL大对象中。可选地,它将给定的注释与对象关联起来。例如: + 将文件存储到一个PostgreSQL大对象中。可选地,它将给定的注释与对象关联起来。例如: foo=> \lo_import '/home/peter/pictures/photo.xcf' 'a picture of me' lo_import 152801 @@ -2049,7 +2045,7 @@ SELECT $1 \parse stmt1 - 可调整打印选项有: + 可调整打印选项有: border @@ -2167,7 +2163,7 @@ SELECT $1 \parse stmt1 允许使用唯一缩写。 - aligned格式是标准的、人类可读的、格式良好的文本输出;这是默认设置。 + aligned格式是标准的、适合人阅读且排版整齐的文本输出;这是默认格式。 unaligned格式将一行中的所有列写在一行上,由当前活动的字段分隔符分隔。这对于创建可能被其他程序读取的输出很有用,例如,制表符分隔或逗号分隔格式。然而,如果字段分隔符字符出现在列的值中,则不会被特殊处理;因此,CSV格式可能更适合这些目的。 @@ -3357,7 +3353,7 @@ bar <acronym>SQL</acronym> 中插入变量 - psql变量的一个关键特性是可以把它们替换(插入)到常规SQL语句中,也可以把它们作为元命令的参数。此外,psql还提供了功能来确保被用作 SQL 文字和标识符的变量值会被正确地引用。插入一个值而不需要加引用的语法是在变量名前面加上一个冒号(:)。例如, + psql变量的一个关键特性是可以把它们替换(插入)到常规SQL语句中,也可以把它们作为元命令的参数。此外,psql还提供了功能来确保被用作 SQL 字面量和标识符的变量值会被正确地加引号。插入一个值而不加引号的语法是在变量名前面加上一个冒号(:)。例如, testdb=> \set foo 'my_table' testdb=> SELECT * FROM :foo; diff --git a/zh/19/ref/reassign_owned.sgml b/zh/19/ref/reassign_owned.sgml index cad7631c..0d000d23 100644 --- a/zh/19/ref/reassign_owned.sgml +++ b/zh/19/ref/reassign_owned.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation REASSIGN OWNED 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/refresh_materialized_view.sgml b/zh/19/ref/refresh_materialized_view.sgml index 2ccb7ac0..7d0fed7a 100644 --- a/zh/19/ref/refresh_materialized_view.sgml +++ b/zh/19/ref/refresh_materialized_view.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation REFRESH MATERIALIZED VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/reindex.sgml b/zh/19/ref/reindex.sgml index 5f43ac70..e64fd049 100644 --- a/zh/19/ref/reindex.sgml +++ b/zh/19/ref/reindex.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation REINDEX 7 - SQL - Language Statements + SQL - 语言语句 @@ -304,7 +304,7 @@ REINDEX [ ( option [, ...] ) ] { DA 当对分区索引或分区表执行带TABLESPACE子句的 REINDEX时,只有叶分区的表空间引用会被更新。由于 - 分区索引本身不会更新,建议另外对相应的分区表单独执行 + 分区索引本身不会更新,建议另外对这些分区索引单独执行 ALTER TABLE ONLY,以便后续附加的任何新分区都继承 新表空间。如果命令失败,可能不会把所有索引都移动到新表空间。重新运行 该命令将重建所有叶分区,并把先前未处理的索引移动到新表空间。 @@ -322,8 +322,8 @@ REINDEX [ ( option [, ...] ) ] { DA 并发重建索引 - index - rebuilding concurrently + 索引 + 并发重建 diff --git a/zh/19/ref/reindexdb.sgml b/zh/19/ref/reindexdb.sgml index fd1f2c08..09b3ccd6 100644 --- a/zh/19/ref/reindexdb.sgml +++ b/zh/19/ref/reindexdb.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation reindexdb 1 - Application + 应用程序 diff --git a/zh/19/ref/release_savepoint.sgml b/zh/19/ref/release_savepoint.sgml index caf2c89d..757d5462 100644 --- a/zh/19/ref/release_savepoint.sgml +++ b/zh/19/ref/release_savepoint.sgml @@ -10,13 +10,13 @@ PostgreSQL documentation 保存点 - releasing + 释放 RELEASE SAVEPOINT 7 - SQL - Language Statements + SQL - 语言语句 @@ -99,7 +99,7 @@ BEGIN; SAVEPOINT sp2; INSERT INTO table1 VALUES (3); RELEASE SAVEPOINT sp2; - INSERT INTO table1 VALUES (4))); -- generates an error + INSERT INTO table1 VALUES (4))); -- 产生错误 在这个例子中,应用程序请求释放保存点sp2,值 3 是在其中插入的。 这样会把该插入操作的事务上下文改为sp1。 diff --git a/zh/19/ref/repack.sgml b/zh/19/ref/repack.sgml index 753f2327..6aafed4e 100644 --- a/zh/19/ref/repack.sgml +++ b/zh/19/ref/repack.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation REPACK 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/reset.sgml b/zh/19/ref/reset.sgml index 5582e84a..ca7ec278 100644 --- a/zh/19/ref/reset.sgml +++ b/zh/19/ref/reset.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation RESET 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/revoke.sgml b/zh/19/ref/revoke.sgml index 2d8e291c..d5eb2f7f 100644 --- a/zh/19/ref/revoke.sgml +++ b/zh/19/ref/revoke.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation REVOKE 7 - SQL - Language Statements + SQL - 语言语句 @@ -138,7 +138,7 @@ REVOKE [ { ADMIN | INHERIT | SET } OPTION FOR ] [ GRANTED BY role_specification ] [ CASCADE | RESTRICT ] -where role_specification can be: +其中role_specification可以是: [ GROUP ] role_name | PUBLIC diff --git a/zh/19/ref/rollback.sgml b/zh/19/ref/rollback.sgml index d1c8fdd2..1a91b03e 100644 --- a/zh/19/ref/rollback.sgml +++ b/zh/19/ref/rollback.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ROLLBACK 7 - SQL - Language Statements + SQL - 语言语句 @@ -37,7 +37,7 @@ ROLLBACK [ WORK | TRANSACTION ] [ AND [ NO ] CHAIN ] 参数 - chained transactions + 链式事务 diff --git a/zh/19/ref/rollback_prepared.sgml b/zh/19/ref/rollback_prepared.sgml index a0905ae0..7161663c 100644 --- a/zh/19/ref/rollback_prepared.sgml +++ b/zh/19/ref/rollback_prepared.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ROLLBACK PREPARED 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/rollback_to.sgml b/zh/19/ref/rollback_to.sgml index 843a612e..d5d8c0e0 100644 --- a/zh/19/ref/rollback_to.sgml +++ b/zh/19/ref/rollback_to.sgml @@ -10,13 +10,13 @@ PostgreSQL documentation 保存点 - rolling back + 回滚 ROLLBACK TO SAVEPOINT 7 - SQL - Language Statements + SQL - 语言语句 @@ -73,8 +73,8 @@ ROLLBACK [ WORK | TRANSACTION ] TO [ SAVEPOINT ] savepoint_name 就保存点而言,游标带有一些非事务性的行为。凡是在某个保存点内打开的游标, 在回滚该保存点时都会被关闭。如果先前打开的游标在某个随后又被回滚的保存点内受到了 - FETCHMOVE命令的影响,那么该游标会保留在这些命令使其指向的位置上 - (也就是说,由FETCHMOVE引起的游标移动不会被回滚)。 + FETCHMOVE命令的影响,那么该游标会保留在FETCH使其指向的位置上 + (也就是说,由FETCH引起的游标移动不会被回滚)。 关闭游标同样不会因回滚而撤销。不过,如果游标查询导致了其他副作用(例如该查询调用的 易变函数带来的副作用),且这些副作用发生在后来被回滚的保存点期间,那么它们 被回滚。如果某个游标的执行导致事务中止,该游标会进入不可执行状态, diff --git a/zh/19/ref/savepoint.sgml b/zh/19/ref/savepoint.sgml index 75705358..9fbe0152 100644 --- a/zh/19/ref/savepoint.sgml +++ b/zh/19/ref/savepoint.sgml @@ -10,13 +10,13 @@ PostgreSQL documentation 保存点 - defining + 定义 SAVEPOINT 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/security_label.sgml b/zh/19/ref/security_label.sgml index 40cea977..caea4591 100644 --- a/zh/19/ref/security_label.sgml +++ b/zh/19/ref/security_label.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SECURITY LABEL 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/select.sgml b/zh/19/ref/select.sgml index f92cf9a3..1fcb5d92 100644 --- a/zh/19/ref/select.sgml +++ b/zh/19/ref/select.sgml @@ -21,7 +21,7 @@ PostgreSQL documentation SELECT 7 - SQL - Language Statements + SQL - 语言语句 @@ -1506,7 +1506,7 @@ SELECT * FROM (SELECT * FROM mytable FOR UPDATE) ss ORDER BY column1; REPEATABLE READSERIALIZABLE事务隔离级别下, - 这将导致序列化失败(带有SQLSTATE'40001'), + 这将导致串行化失败(SQLSTATE'40001'), 因此在这些隔离级别下不可能接收到无序的行。 diff --git a/zh/19/ref/select_into.sgml b/zh/19/ref/select_into.sgml index cb933f09..7bf13eab 100644 --- a/zh/19/ref/select_into.sgml +++ b/zh/19/ref/select_into.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SELECT INTO 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/set.sgml b/zh/19/ref/set.sgml index 157e0242..66c1335b 100644 --- a/zh/19/ref/set.sgml +++ b/zh/19/ref/set.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SET 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/set_constraints.sgml b/zh/19/ref/set_constraints.sgml index 53d0c7a0..e5588db7 100644 --- a/zh/19/ref/set_constraints.sgml +++ b/zh/19/ref/set_constraints.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SET CONSTRAINTS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/set_role.sgml b/zh/19/ref/set_role.sgml index ed65dec8..c32755be 100644 --- a/zh/19/ref/set_role.sgml +++ b/zh/19/ref/set_role.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SET ROLE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/set_session_auth.sgml b/zh/19/ref/set_session_auth.sgml index e520dd49..e7692edc 100644 --- a/zh/19/ref/set_session_auth.sgml +++ b/zh/19/ref/set_session_auth.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SET SESSION AUTHORIZATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/set_transaction.sgml b/zh/19/ref/set_transaction.sgml index d43f24cc..7b76611f 100644 --- a/zh/19/ref/set_transaction.sgml +++ b/zh/19/ref/set_transaction.sgml @@ -26,7 +26,7 @@ PostgreSQL documentation SET TRANSACTION 7 - SQL - Language Statements + SQL - 语言语句 @@ -66,7 +66,7 @@ SET SESSION CHARACTERISTICS AS TRANSACTION transa - 一个事务的隔离级别决定当其他事务并行运行时该事务能看见什么数据: + 一个事务的隔离级别决定当其他事务并发运行时该事务能看见什么数据: @@ -137,7 +137,7 @@ SET SESSION CHARACTERISTICS AS TRANSACTION transa 事务属性才会生效。当为一个事务同时选择这三个属性时,该事务在 首次获取其快照时可能会阻塞;在此之后,它便可以运行,而无需承担普通 SERIALIZABLE事务的常规开销,也不会有促成 - 序列化失败或因序列化失败而被取消的风险。这种模式非常适合长时间运行的 + 串行化失败或因串行化失败而被取消的风险。这种模式非常适合长时间运行的 报表或备份。 diff --git a/zh/19/ref/show.sgml b/zh/19/ref/show.sgml index 3b4be6bd..81bd6a80 100644 --- a/zh/19/ref/show.sgml +++ b/zh/19/ref/show.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SHOW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/start_transaction.sgml b/zh/19/ref/start_transaction.sgml index 57a74b2f..5026fa70 100644 --- a/zh/19/ref/start_transaction.sgml +++ b/zh/19/ref/start_transaction.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation START TRANSACTION 7 - SQL - Language Statements + SQL - 语言语句 @@ -64,15 +64,16 @@ START TRANSACTION [ transaction_mode - DEFERRABLE 这一 - transaction_mode 是 - PostgreSQL语言扩展。 + DEFERRABLE + transaction_mode + 是PostgreSQL的一种语言扩展。 SQL 标准要求在连续的transaction_modes之间有逗号, - 但出于历史原因PostgreSQL允许省略逗号。 + 但出于历史原因, + PostgreSQL允许省略逗号。 diff --git a/zh/19/ref/truncate.sgml b/zh/19/ref/truncate.sgml index 19dcc221..35cd8db0 100644 --- a/zh/19/ref/truncate.sgml +++ b/zh/19/ref/truncate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation TRUNCATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/unlisten.sgml b/zh/19/ref/unlisten.sgml index a6ad5794..28132d63 100644 --- a/zh/19/ref/unlisten.sgml +++ b/zh/19/ref/unlisten.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation UNLISTEN 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/update.sgml b/zh/19/ref/update.sgml index dd6a5794..c5d35e12 100644 --- a/zh/19/ref/update.sgml +++ b/zh/19/ref/update.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation UPDATE 7 - SQL - Language Statements + SQL - 语言语句 @@ -165,7 +165,7 @@ UPDATE [ ONLY ] table_name [ * ] 时态更新中要更改的最早时间(含)。这必须是与 range_column_name所对应范围的基础类型匹配的值。 - 此处的NULL值表示更新的起点没有下界(与范围类型一样)。 + 此处的 NULL 值表示更新的起点没有下界(与范围类型一样)。 @@ -176,7 +176,7 @@ UPDATE [ ONLY ] table_name [ * ] 时态更新中要更改的最晚时间(不含)。这必须是与 range_column_name所对应范围的基础类型匹配的值。 - 此处的NULL值表示更新的终点没有上界(与范围类型一样)。 + 此处的 NULL 值表示更新的终点没有上界(与范围类型一样)。 @@ -386,12 +386,12 @@ UPDATE count 在被移动的行上并发执行UPDATE或 - DELETE时,有可能收到序列化失败错误。假设会话 1 - 正在更新某个分区键,与此同时,一个对该行可见的并发会话 2 对该行 + DELETE时,有可能收到串行化失败错误。假设会话 1 + 正在对某个分区键执行UPDATE,与此同时,一个能够看到该行的并发会话 2 对该行 执行UPDATEDELETE操作。在 这种情况下,会话 2 的UPDATE或 - DELETE将检测到行移动,并引发序列化失败错误 - (其 SQLSTATE 代码始终为'40001')。如果发生 + DELETE将检测到行移动,并引发串行化失败错误 + (其 SQLSTATE 代码始终为'40001')。如果发生 这种情况,应用程序可能需要重试事务。在表未分区或没有发生行移动 的通常情况下,会话 2 会识别出新更新的那一行,并在这个新行版本上执行 UPDATE/DELETE。 diff --git a/zh/19/ref/vacuum.sgml b/zh/19/ref/vacuum.sgml index 5c378ccb..247423d8 100644 --- a/zh/19/ref/vacuum.sgml +++ b/zh/19/ref/vacuum.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation VACUUM 7 - SQL - Language Statements + SQL - 语言语句 @@ -76,7 +76,7 @@ VACUUM [ ( option [, ...] ) ] [ 。 - 如需禁用该功能,可以使用PARALLEL选项并将并行工作者数指定为零。 + 如需禁用该功能,可以使用PARALLEL选项并将并行工作进程数指定为零。 VACUUM FULL会把表的全部内容重写到一个没有额外空闲空间的新磁盘文件中, 从而让未使用的空间能够返还给操作系统。这种形式要慢得多,并且在处理每个表时都需要 ACCESS EXCLUSIVE锁。 @@ -214,7 +214,7 @@ VACUUM [ ( option [, ...] ) ] [ PARALLEL - 指定可用于的最大并行工作者数, + 指定可用于的最大并行工作进程数, 其数量还会进一步受到的限制。 此选项不能与FULL选项一起使用。 @@ -370,7 +370,7 @@ VACUUM [ ( option [, ...] ) ] [ - 我们建议定期对所有数据库执行清理,以移除死行。PostgreSQL提供了一个autovacuum机制, + 我们建议定期对所有数据库执行清理,以移除死行。PostgreSQL提供了一个自动清理(autovacuum)机制, 可以自动执行常规清理维护。有关自动与手动清理的更多信息,参见 @@ -388,8 +388,8 @@ VACUUM [ ( option [, ...] ) ] [ VACUUM会显著增加 I/O 流量,这可能导致其他活动会话性能变差。 - 因此,有时建议使用基于代价的清理延迟特性。对于并行清理,每个工作者的睡眠时长 - 都与该工作者完成的工作量成比例。详见。 + 因此,有时建议使用基于代价的清理延迟特性。对于并行清理,每个工作进程的睡眠时长 + 都与该工作进程完成的工作量成比例。详见 @@ -405,7 +405,7 @@ VACUUM [ ( option [, ...] ) ] [ 示例 - 清理单个表onek,对其执行优化器分析,并打印详细的清理活动报告: + 清理单个表onek,对其进行分析以供优化器使用,并打印详细的清理活动报告: VACUUM (VERBOSE, ANALYZE) onek; diff --git a/zh/19/ref/vacuumdb.sgml b/zh/19/ref/vacuumdb.sgml index 5874c3c6..08ed85aa 100644 --- a/zh/19/ref/vacuumdb.sgml +++ b/zh/19/ref/vacuumdb.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation vacuumdb 1 - Application + 应用程序 @@ -132,8 +132,8 @@ PostgreSQL documentation - 指定给定一次 缓冲区访问策略(Buffer Access Strategy) - 环形缓冲区大小,供 vacuumdb 调用使用。这个大小用于计算将作为该策略一部分被重用的共享缓冲区数量。参见 + 为一次给定的 vacuumdb 调用指定缓冲区访问策略(Buffer Access Strategy) + 环形缓冲区大小。这个大小用于计算将作为该策略一部分被重用的共享缓冲区数量。参见 @@ -196,7 +196,7 @@ PostgreSQL documentation - 积极地冻结元组。 + 激进地冻结元组。 @@ -234,12 +234,12 @@ PostgreSQL documentation - 仅对 multixact ID 年龄至少为 mxid_age - 的表执行清理或分析命令。此设置可用于优先处理表,以防止 multixact ID 回卷 + 仅对 多事务 ID 年龄至少为 mxid_age + 的表执行清理或分析命令。此设置可用于优先处理表,以防止 多事务 ID 回卷 (见 )。 - 就此选项而言,一个关系的 multixact ID 年龄,是其主关系及其关联的 + 就此选项而言,一个关系的 多事务 ID 年龄,是其主关系及其关联的 TOAST 表(如果存在)年龄中的较大者。由于 vacuumdb 发出的命令在必要时也会处理该关系的 TOAST 表,因此无需单独考虑它。 diff --git a/zh/19/ref/values.sgml b/zh/19/ref/values.sgml index e5b00372..8c6d7597 100644 --- a/zh/19/ref/values.sgml +++ b/zh/19/ref/values.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation VALUES 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/ref/wait_for.sgml b/zh/19/ref/wait_for.sgml index 6c495c8b..8ef41f26 100644 --- a/zh/19/ref/wait_for.sgml +++ b/zh/19/ref/wait_for.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation WAIT FOR 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/19/release-19.sgml b/zh/19/release-19.sgml index c6f4ead5..c7c43be5 100644 --- a/zh/19/release-19.sgml +++ b/zh/19/release-19.sgml @@ -1995,7 +1995,7 @@ Author: Peter Eisentraut 2025-11-05 [e4d8a2af0] doc: Add section for temporal tables --> -新增关于 temporal tables 的文档章节(Paul A. Jungwirth)§ +新增关于 时态表 的文档章节(Paul A. Jungwirth)§ -en +zh_cn diff --git a/zh/19/syntax.sgml b/zh/19/syntax.sgml index 80f94424..2d0e2c55 100644 --- a/zh/19/syntax.sgml +++ b/zh/19/syntax.sgml @@ -21,7 +21,7 @@ 词法结构 - token + 词元 @@ -29,7 +29,7 @@ - 一个词元可以是关键词标识符带引号的标识符文字值(或常量),或者特殊字符符号。词元通常由空白(空格、制表符、换行)分隔,但如果不存在歧义,则不必如此(一般只有特殊字符与其他类型的词元相邻时才会这样)。 + 一个词元可以是关键词标识符带引号的标识符字面量(或常量),或者特殊字符符号。词元通常由空白(空格、制表符、换行)分隔,但如果不存在歧义,则不必如此(一般只有特殊字符与其他类型的词元相邻时才会这样)。 @@ -58,18 +58,18 @@ INSERT INTO MY_TABLE VALUES (3, 'hi there'); 标识符和关键词 - identifier - syntax of + 标识符 + 语法 - name - syntax of + 名称 + 语法 - key word - syntax of + 关键词 + 语法 @@ -83,7 +83,7 @@ INSERT INTO MY_TABLE VALUES (3, 'hi there'); - identifierlength + 标识符长度 系统对标识符最多只使用 NAMEDATALEN-1 个字节;在命令中可以写更长的名称,但它们会被截断。默认情况下, NAMEDATALEN 为 64,因此标识符的最大长度是 63 字节。如果这个限制有问题,可以通过修改 src/include/pg_config_manual.h 中的 NAMEDATALEN 常量来提高。 @@ -91,8 +91,8 @@ INSERT INTO MY_TABLE VALUES (3, 'hi there'); - case sensitivity - of SQL commands + 大小写敏感性 + SQL 命令 关键词和未加引号的标识符不区分大小写。因此: @@ -110,8 +110,8 @@ UPDATE my_table SET a = 5; - quotation marks - and identifiers + 引号 + 与标识符 还有第二类标识符:定界标识符带引号的标识符。它通过把任意字符序列括在双引号中形成(")。 定界标识符始终是标识符,绝不会是关键词。因此,"select" 可以用来引用名为 select 的列或表,而不加引号的 select 会被视为关键词,因此在期望表名或列名的位置使用时会导致解析错误。这个示例可以用带引号的标识符写成: @@ -133,7 +133,7 @@ UPDATE "my_table" SET "a" = 5; Unicode 转义 - in identifiers + 在标识符中 @@ -177,7 +177,7 @@ U&"d!0061t!+000061" UESCAPE '!' 常量 - constant + 常量 @@ -188,19 +188,15 @@ U&"d!0061t!+000061" UESCAPE '!' 字符串常量 - character string - constant + 字符串 + 常量 - - - quotation marks + + 引号 转义 - SQL 中的字符串常量是由单引号括起的任意字符序列,例如 - 'This is a string'。要在字符串常量中包含单引号字符,请写两个相邻的单引号,例如 - 'Dianne''s horse'。注意,这与双引号字符("不同 - + SQL 中的字符串常量是由单引号(')括起的任意字符序列,例如 'This is a string'。要在字符串常量中包含单引号字符,请写两个相邻的单引号,例如 'Dianne''s horse'。注意,这不同于双引号字符(")。 两个只由空白及至少一个新行分隔的字符串常量会被连接在一起,并且将作为一个写在一起的字符串常量来对待。例如: @@ -312,7 +308,7 @@ SELECT 'foo' 'bar'; Unicode 转义 - in string constants + 在字符串常量中 @@ -354,7 +350,7 @@ U&'d!0061t!+000061' UESCAPE '!' 美元引用的字符串常量 - dollar quoting + 美元引用 @@ -397,8 +393,8 @@ $function$ 位串常量 - bit string - constant + 位串 + 常量 @@ -418,8 +414,8 @@ $function$ 数字常量 - number - constant + 数字 + 常量 @@ -496,12 +492,12 @@ $function$ - 为数字常量最初指定的数据类型,只是类型解析算法的起点。在大多数情况下,常量会根据上下文被自动强制转换成最合适的类型。必要时,你可以通过类型转换强制把一个数值解释为特定的数据类型。type cast + 为数字常量最初指定的数据类型,只是类型解析算法的起点。在大多数情况下,常量会根据上下文被自动强制转换成最合适的类型。必要时,你可以通过类型转换强制把一个数值解释为特定的数据类型。类型转换 例如,可以通过下面的写法强制把一个数值当作类型 realfloat4)处理: -REAL '1.23' -- string style -1.23::REAL -- PostgreSQL (historical) style +REAL '1.23' -- 字符串形式 +1.23::REAL -- PostgreSQL(历史)形式 这些实际上只是下面将要讨论的一般类型转换记法的特例。 @@ -512,8 +508,8 @@ REAL '1.23' -- string style 其他类型的常量 - data type - constant + 数据类型 + 常量 @@ -539,7 +535,7 @@ CAST ( 'string' AS type ) - 如中所述,::CAST() 以及函数调用语法也可以用来指定任意表达式的运行时类型转换。为避免语法歧义,type 'string' 语法只能用来指定简单字面常量的类型。该语法的另一个限制是不能用于数组类型;要指定数组常量的类型,请使用 ::CAST()。 + 如中所述,::CAST() 以及函数调用语法也可以用来指定任意表达式的运行时类型转换。为避免语法歧义,type 'string' 语法只能用来指定简单字面常量的类型。type 'string' 语法的另一个限制是不能用于数组类型;要指定数组常量的类型,请使用 ::CAST() @@ -552,8 +548,8 @@ CAST ( 'string' AS type ) 操作符 - operator - syntax + 操作符 + 语法 @@ -603,7 +599,7 @@ CAST ( 'string' AS type ) - 圆括号(())具有它们通常的含义,用来分组表达式并且强制优先。在某些情况中,圆括号被要求作为一个特定 SQL 命令的固定语法的一部分。 + 圆括号(())具有它们通常的含义,用来对表达式分组并确定运算优先级。在某些情况中,圆括号被要求作为一个特定 SQL 命令的固定语法的一部分。 @@ -621,7 +617,7 @@ CAST ( 'string' AS type ) - 分号(;)结束一个 SQL 命令。它不能出现在一个命令中间的任何位置,除了在一个字符串常量中或者一个被引用的标识符中。 + 分号(;)结束一个 SQL 命令。它不能出现在一个命令中间的任何位置,除了在一个字符串常量中或者一个带引号的标识符中。 @@ -633,7 +629,7 @@ CAST ( 'string' AS type ) - 星号(*)在某些上下文中用来表示表行或组合值的所有字段。当它被用作聚合函数的参数时,还有一种特殊含义,即该聚合不需要任何显式参数。 + 星号(*)在某些上下文中用来表示表行或复合值的所有字段。当它被用作聚合函数的参数时,还有一种特殊含义,即该聚合不需要任何显式参数。 @@ -651,22 +647,22 @@ CAST ( 'string' AS type ) 注释 - comment - in SQL + 注释 + 在 SQL 中 注释是一串以双连字符开始并延伸到行尾的字符,例如: --- This is a standard SQL comment +-- 这是一条标准 SQL 注释 另外,也可以使用 C 风格注释块: -/* multiline comment - * with nesting: /* nested block comment */ +/* 多行注释 + * 包含嵌套:/* 嵌套块注释 */ */ 这里该注释开始于/*并且延伸到匹配出现的*/。这些注释块可按照 SQL 标准中指定的方式嵌套,但和 C 中不同。这样我们可以注释掉一大段可能包含注释块的代码。 @@ -681,8 +677,8 @@ CAST ( 'string' AS type ) 操作符优先级 - operator - precedence + 操作符 + 优先级 @@ -726,7 +722,7 @@ CAST ( 'string' AS type ) + - - 一元加、一元减 + 一元正号、一元负号 @@ -744,13 +740,13 @@ CAST ( 'string' AS type ) ^ - 指数 + 求幂 * / % - 乘、除、模 + 乘、除、取模 @@ -762,7 +758,7 @@ CAST ( 'string' AS type ) (任意其他操作符) - 所有其他本地以及用户定义的操作符 + 所有其他内置以及用户定义的操作符 @@ -819,18 +815,7 @@ SELECT 3 OPERATOR(pg_catalog.+) 4; - - 版本 9.5 之前的PostgreSQL使用的操作符优先级 - 规则略有不同。特别是,<=>= - 和<>习惯于被当作普通操作符,IS - 测试习惯于具有较高的优先级。并且在一些认为NOT比 - BETWEEN优先级高的情况下,NOT BETWEEN - 和相关的结构的行为不一致。为了更好地兼容 SQL 标准并且减少对 - 逻辑上等价的结构不一致的处理,这些规则也得到了修改。在大部分情况下, - 这些变化不会导致行为上的变化,或者可能会产生no such operator - 错误,但可以通过增加圆括号解决。不过在一些极端情况中,查询可能在 - 没有被报告解析错误的情况下发生行为的改变。 - + PostgreSQL 9.5 之前的版本使用的操作符优先级规则略有不同。特别是,<=>=<> 过去被当作普通操作符;IS 测试过去具有较高的优先级;而 NOT BETWEEN 和相关结构的处理不一致,在某些情况下被认为具有 NOT 而不是 BETWEEN 的优先级。为了更好地符合 SQL 标准,并减少对逻辑等价结构的不一致处理造成的困惑,这些规则得到了修改。在大部分情况下,这些变化不会导致行为变化,或者可能会产生 no such operator 错误,但可以通过增加圆括号解决。不过在一些极端情况下,查询可能在没有报告任何解析错误的情况下改变行为。 @@ -1523,7 +1508,7 @@ SELECT * FROM tbl WHERE a COLLATE "C" > 'foo'; SELECT * FROM tbl WHERE (a > 'foo') COLLATE "C"; - 因为它尝试把一个排序规则应用到>操作符的结果,而它的数据类型是非可排序数据类型boolean。 + 因为它尝试把一个排序规则应用到>操作符的结果,而它的数据类型是不支持排序规则的数据类型boolean diff --git a/zh/19/system-views.sgml b/zh/19/system-views.sgml index 8d59e327..16cf9686 100644 --- a/zh/19/system-views.sgml +++ b/zh/19/system-views.sgml @@ -50,11 +50,6 @@ 正在使用的异步 I/O 句柄 - - pg_dsm_registry_allocations - DSM 注册表跟踪的共享内存分配 - - pg_available_extensions 可用的扩展 @@ -80,6 +75,11 @@ 打开的游标 + + pg_dsm_registry_allocations + DSM 注册表跟踪的共享内存分配 + + pg_file_settings 配置文件内容摘要 @@ -131,13 +131,13 @@ - pg_publication_tables - 发布及其关联表的信息 + pg_publication_sequences + 发布及其关联序列的信息 - pg_publication_sequences - 发布及其关联序列的信息 + pg_publication_tables + 发布及其关联表的信息 @@ -1394,7 +1394,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; address text - 主机名或IP地址,或者allsamehostsamenet之一,对于本地连接为空 + 主机名或IP地址,或者allsamehostsamenet之一,对于本地连接为 NULL @@ -1403,7 +1403,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; netmask text - IP地址掩码,如果不适用则为空 + IP地址掩码,如果不适用则为 NULL @@ -1621,7 +1621,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; (参考 pg_tablespace.spcname) - 包含索引的表空间名(如果是数据库的默认值则为空) + 包含索引的表空间名(如果是数据库的默认值则为 NULL) @@ -1630,7 +1630,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; indexdef text - 索引定义(重构出的 命令) + 索引定义(重建出的 命令) @@ -1664,8 +1664,8 @@ AND c1.path[c2.level] = c2.path[c2.level]; 以及一般的数据库对象(由类OID和对象OID标识, 与pg_descriptionpg_depend中的方式相同)。 - 此外,扩展关系的权限被表示为一个单独的可锁定对象,以及更新 - pg_database.datfrozenxid 的更新权限。 + 此外,扩展关系的权利被表示为单独的可锁定对象,更新 + pg_database.datfrozenxid的权利也是如此。 此外,还可以对具有用户定义含义的数字施加咨询锁 @@ -1712,7 +1712,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; (参考 pg_database.oid) - 锁目标存在的数据库的OID,如果目标是一个共享对象则为0,如果目标是一个事务ID则为空 + 锁目标存在的数据库的OID,如果目标是一个共享对象则为0,如果目标是一个事务ID则为 NULL @@ -1722,7 +1722,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; (参考 pg_class.oid) - 作为锁目标的关系的OID,如果目标不是一个关系或者只是关系的一部分则此列为空 + 作为锁目标的关系的OID,如果目标既不是关系,也不是关系的一部分则此列为 NULL @@ -1731,7 +1731,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; page int4 - 作为锁目标的页在关系中的页号,如果目标不是一个关系页或元组则此列为空 + 作为锁目标的页在关系中的页号,如果目标不是一个关系页或元组则此列为 NULL @@ -1740,7 +1740,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; tuple int2 - 作为锁目标的元组在页中的元组号,如果目标不是一个元组则此列为空 + 作为锁目标的元组在页中的元组号,如果目标不是一个元组则此列为 NULL @@ -1749,7 +1749,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; virtualxid text - 锁定目标事务的虚拟 ID,如果目标不是虚拟事务 ID,则为空;见 + 锁定目标事务的虚拟 ID,如果目标不是虚拟事务 ID,则为 NULL;见 @@ -1759,7 +1759,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; transactionid xid - 锁定目标事务的标识,如果目标不是事务 ID,则为空; + 锁定目标事务的标识,如果目标不是事务 ID,则为 NULL; @@ -1769,7 +1769,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; (参考 pg_class.oid) - 包含锁目标的系统目录的OID,如果目标不是一个普通数据库对象则此列为空 + 包含锁目标的系统目录的OID,如果目标不是一个普通数据库对象则此列为 NULL @@ -1779,7 +1779,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; (参考任意 OID 列) - 锁目标在它的系统目录中的OID,如果目标不是一个普通数据库对象则为空 + 锁目标在它的系统目录中的OID,如果目标不是一个普通数据库对象则为 NULL @@ -1788,7 +1788,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; objsubid int2 - 锁的目标列号(classidobjid指表本身),如果目标是某种其他普通数据库对象则此列为0,如果目标不是一个普通数据库对象则此列为空 + 锁的目标列号(classidobjid指表本身),如果目标是某种其他普通数据库对象则此列为0,如果目标不是一个普通数据库对象则此列为 NULL @@ -1806,7 +1806,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; pid int4 - 保持这个锁或者正在等待这个锁的服务器进程的PID,如果此锁被一个预备事务所持有则此列为空 + 保持这个锁或者正在等待这个锁的服务器进程的PID,如果此锁被一个预备事务所持有则此列为 NULL @@ -1842,8 +1842,8 @@ AND c1.path[c2.level] = c2.path[c2.level]; waitstart timestamptz - 服务器进程开始等待该锁的时间;如果锁已被授予则为空。 - 注意,在开始等待之后,即使grantedfalse,该值在极短时间内也可能仍为空。 + 服务器进程开始等待该锁的时间;如果锁已被授予则为 NULL。 + 注意,在开始等待之后,即使grantedfalse,该值在极短时间内也可能仍为 NULL。 @@ -1875,8 +1875,8 @@ AND c1.path[c2.level] = c2.path[c2.level]; 咨询锁可以在由单个 bigint 值或两个整数值组成的键上获取。 - 一个bigint键在classid列中显示其高阶半部分, - 在objid列中显示其低阶半部分,并且objsubid等于1。 + 一个bigint键在classid列中显示其高位半部分, + 在objid列中显示其低位半部分,并且objsubid等于1。 可以使用表达式(classid::bigint << 32) | objid::bigint重新组装原始bigint值。 整数键在classid列中显示第一个键,在objid列中显示第二个键, 并且 objsubid 等于 2。键的实际含义由用户自行决定。咨询锁在每个数据库内都是本地的, @@ -1925,15 +1925,15 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx pg_locks视图显示来自常规锁管理器和谓词锁管理器的数据,这两个是独立的系统; - 此外,常规锁管理器将其锁分为常规锁和fast-path锁。 + 此外,常规锁管理器将其锁分为常规锁和快速路径锁。 不能保证这些数据完全一致。 当查询该视图时, - fast-path 锁的数据(具有fastpath = true) + 快速路径锁的数据(具有fastpath = true) 从每个后端逐个收集,而不会冻结整个锁管理器的状态,因此在收集信息时可能会发生锁的获取或释放。 但请注意,这些锁已知不会与当前放置的任何其他锁发生冲突。 - 在查询所有后端的 fast-path 锁后,剩余的常规锁管理器将作为一个单元被锁定,并且所有剩余锁的一致快照将作为一个原子操作收集。 + 在查询所有后端的快速路径锁后,剩余的常规锁管理器将作为一个单元被锁定,并且所有剩余锁的一致快照将作为一个原子操作收集。 解锁常规锁管理器后,谓词锁管理器类似地被锁定,并且所有谓词锁将作为一个原子操作收集。 - 因此,除了 fast-path 锁外,每个锁管理器将提供一致的结果集,但由于我们不同时锁定两个锁管理器,因此在询问常规锁管理器后和在询问谓词锁管理器前,可能会发生锁的获取或释放。 + 因此,除了快速路径锁外,每个锁管理器将提供一致的结果集,但由于我们不同时锁定两个锁管理器,因此在询问常规锁管理器后和在询问谓词锁管理器前,可能会发生锁的获取或释放。 @@ -2009,7 +2009,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx (参考 pg_tablespace.spcname) - 包含物化视图的表空间名(如使用数据库默认表空间则为空) + 包含物化视图的表空间名(如使用数据库默认表空间则为 NULL) @@ -2036,7 +2036,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx definition text - 物化视图的定义(一个重构的查询) + 物化视图的定义(一个重建的查询) @@ -2227,7 +2227,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx 该预备语句返回列的类型,以 regtype 数组形式表示。该数组中某个元素对应的 OID 可以通过将 - regtype 值转换为 oid 获得。如果预备语句不提供结果(例如 DML 语句),则该字段为空。 + regtype 值转换为 oid 获得。如果预备语句不提供结果(例如 DML 语句),则该字段为 NULL。 @@ -2702,7 +2702,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx confirmed_flush_lsn pg_lsn - 逻辑槽消费者已确认接收到数据的地址(LSN)。在此 LSN 之前提交的事务所对应的数据将不再可用。物理槽为 NULL。 + 逻辑槽消费者已确认接收的数据所到达的地址(LSN)。在此 LSN 之前提交的事务所对应的数据将不再可用。物理槽为 NULL @@ -2765,7 +2765,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx inactive_since timestamptz - 槽变为不活动的时间。如果该槽当前正在被流式传输,则为 NULL。如果该槽变为无效,该值将不再更新。对于从主库同步而来的备库逻辑槽(其 synced 字段为 true),inactive_since 表示槽同步(参见 )最近一次停止的时间。如果该槽始终保持同步,则为 NULL。这有助于跟踪备库上的槽同步何时被中断。 + 槽变为不活动的时间。如果当前正在从该槽流式传输数据,则为 NULL。如果该槽变为无效,该值将不再更新。对于从主库同步而来的备库逻辑槽(其 synced 字段为 true),inactive_since 表示槽同步(参见 )最近一次停止的时间。如果该槽始终保持同步,则为 NULL。这有助于跟踪备库上的槽同步何时被中断。 @@ -2827,7 +2827,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - + slotsync_skip_reasontext @@ -2841,7 +2841,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - wal_not_flushed表示备库尚未刷出与故障转移槽保留位置对应的 WAL。 + wal_not_flushed表示备库尚未将与故障切换槽保留位置对应的 WAL 刷盘。 @@ -2872,7 +2872,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx 视图pg_roles提供数据库角色的信息。它本质上是 - pg_authid 的公开可读视图,并将密码字段清空。 + pg_authid 的公开可读视图,并隐藏密码字段。
@@ -2958,7 +2958,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx rolconnlimitint4 - 对于可以登录的角色,本列设置该角色可以同时发起最大连接数。-1表示无限制。 + 对于可以登录的角色,本列设置该角色能够建立的最大并发连接数。-1 表示无限制。 @@ -2976,7 +2976,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx rolvaliduntiltimestamptz - 密码过期时间(只用于密码认证),如果永不过期则为空 + 密码过期时间(仅用于密码认证);不设过期时间时为 NULL @@ -3074,7 +3074,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx definitiontext - 规则定义(创建命令的重构) + 规则定义(重建的创建命令) @@ -3160,7 +3160,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx (参考 pg_namespace.oid) - 如果适用,为此对象的命名空间 OID;否则为空。 + 如果适用,为此对象的命名空间 OID;否则为 NULL。 @@ -3467,7 +3467,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx min_valtext - 参数的最小允许值(对非数值参数为空) + 参数的最小允许值(对非数值参数为 NULL) @@ -3476,7 +3476,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx max_valtext - 参数的最大允许值(对非数值参数为空) + 参数的最大允许值(对非数值参数为 NULL) @@ -3485,7 +3485,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx enumvalstext[] - 枚举参数的允许值(对非枚举参数为空) + 枚举参数的允许值(对非枚举参数为 NULL) @@ -3673,7 +3673,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx 这个名称源于该表不应向公众开放读取,因为它包含密码。 pg_user - 是 pg_shadow 的公开可读视图,并将密码字段清空。 + 是 pg_shadow 的公开可读视图,并隐藏密码字段。
@@ -4032,7 +4032,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx null_fracfloat4 - 列项中为空的比例 + 列项中为 NULL 的比例 @@ -4060,7 +4060,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx most_common_valsanyarray - 列中高频值的一个列表(如果没有任何一个值看起来比其他值更常用,此列为空) + 列中高频值的一个列表(如果没有任何一个值看起来比其他值更常用,此列为 NULL) @@ -4069,7 +4069,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx most_common_freqsfloat4[] - 高频值的频率列表,即每一个高频值的出现次数除以总行数(如果most_common_vals为空,则此列为空) + 高频值的频率列表,即每一个高频值的出现次数除以总行数(如果most_common_vals为 NULL,则此列为 NULL) @@ -4078,7 +4078,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx histogram_boundsanyarray - 将列值划分成大小接近的组的值列表。如果存在most_common_vals,其中的值会被直方图计算所忽略(如果列类型没有一个<操作符或者most_common_vals等于整个值集合,则此列为空) + 将列值划分成大小接近的组的值列表。如果存在most_common_vals,其中的值会被直方图计算所忽略(如果列类型没有一个<操作符或者most_common_vals等于整个值集合,则此列为 NULL) @@ -4087,7 +4087,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx correlationfloat4 - 物理行顺序和列值逻辑顺序之间的统计关联。其范围从-1到+1。当值接近-1或+1时,在列上的一个索引扫描被认为比值接近0时的代价更低,因为这种情况减少了对磁盘的随机访问(如果列数据类型不具有一个<操作符,则此列为空) + 物理行顺序和列值逻辑顺序之间的统计关联。其范围从-1到+1。当值接近-1或+1时,在列上的一个索引扫描被认为比值接近0时的代价更低,因为这种情况减少了对磁盘的随机访问(如果列数据类型不具有一个<操作符,则此列为 NULL) @@ -4096,7 +4096,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx most_common_elemsanyarray - 在列值中,最经常出现的非空元素列表(对标量类型为空) + 在列值中,最经常出现的非空元素列表(对标量类型为 NULL) @@ -4106,7 +4106,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx 最常用元素值的频度列表,即含有至少一个给定值实例的行的分数。 - 在每个元素的频度之后有二至三个附加值,它们是每个元素频度的最小和最大值,以及可选的空元素的频度(如果most_common_elems为空,则此列为空) + 在每个元素的频度之后有二至三个附加值,它们是每个元素频度的最小和最大值,以及可选的空元素的频度(如果most_common_elems为 NULL,则此列为 NULL) @@ -4115,7 +4115,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx elem_count_histogramfloat4[] - 在列值中可区分非空元素值计数的一个直方图,后面跟随可区分非空元素的平均数(对于标量类型为空) + 在列值中可区分非空元素值计数的一个直方图,后面跟随可区分非空元素的平均数(对于标量类型为 NULL) @@ -4124,7 +4124,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx range_length_histogramanyarray - 范围类型列中非空且非 NULL 的范围值长度直方图。(对非范围类型为空。) + 范围类型列中非空且非 NULL 的范围值长度直方图。(非范围类型为 null。) 该直方图使用范围函数 subtype_diff 计算,而不考虑范围边界是否包含端点。 @@ -4136,7 +4136,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx range_empty_frac float4 - 列项中值为空范围的比例。(对非范围类型为空。) + 列项中值为空范围的比例。(非范围类型为 null。) @@ -4145,10 +4145,10 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx range_bounds_histogramanyarray - 非空且非 NULL 的范围值下界和上界的直方图。(对非范围类型为空。) + 非空且非 NULL 的范围值下界和上界的直方图。(非范围类型为 null。) - 这两个直方图表示为单个数组列,其中下半部分表示下界的直方图,上半部分表示上界的直方图。 + 这两个直方图表示为一个范围数组,其中各范围的下界表示下界直方图,上界表示上界直方图。 @@ -4334,7 +4334,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx most_common_valstext[] - 列中值的最常见组合的列表(如果没有组合看上去比其它的更常见,则为空。) + 列中值的最常见组合的列表(如果没有组合看上去比其它的更常见,则为 NULL。) @@ -4343,7 +4343,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx most_common_val_nullsbool[] - 值最常见组合的NULL标志的列表(当most_common_vals是空值时,为空。) + 值最常见组合的NULL标志的列表(当most_common_vals为 NULL 时,为 NULL。) @@ -4352,7 +4352,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx most_common_freqsfloat8[] - 最常见组合的频率的列表,即每个出现的数量除以行的总数(当most_common_vals是空值时,为空) + 最常见组合的频率的列表,即每个出现的数量除以行的总数(当most_common_vals为 NULL 时,为 NULL) @@ -4361,7 +4361,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx most_common_base_freqsfloat8[] - 最常见组合的基本频率的列表,即每个值频率的乘积。(当most_common_vals是空值时,为空。) + 最常见组合的基本频率的列表,即每个值频率的乘积。(当most_common_vals为 NULL 时,为 NULL。) @@ -4507,7 +4507,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx null_fracfloat4 - 表达式条目为空的比例 + 表达式条目为 NULL 的比例 @@ -4535,7 +4535,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx most_common_valsanyarray - 表达式中高频值的列表(如果没有值看起来比任何其他值更常见则为空) + 表达式中高频值的列表(如果没有值看起来比任何其他值更常见则为 NULL) @@ -4544,7 +4544,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx most_common_freqsfloat4[] - 高频值的频率列表,即每一个高频值的出现次数除以总行数(如果most_common_vals为空,则此列为空) + 高频值的频率列表,即每一个高频值的出现次数除以总行数(如果most_common_vals为 NULL,则此列为 NULL) @@ -4553,7 +4553,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx histogram_boundsanyarray - 将表达式的值划分成大小接近的组的值列表。如果存在most_common_vals,其中的值会被直方图计算所忽略(如果表达式的数据类型没有一个<操作符或者most_common_vals等于整个值集合,则此列为空) + 将表达式的值划分成大小接近的组的值列表。如果存在most_common_vals,其中的值会被直方图计算所忽略(如果表达式的数据类型没有一个<操作符或者most_common_vals等于整个值集合,则此列为 NULL) @@ -4562,7 +4562,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx correlationfloat4 - 物理行顺序和表达式值逻辑顺序之间的统计关联。其范围从-1到+1。当值接近-1或+1时,在表达式上的一个索引扫描被认为比值接近0时的代价更低,因为这种情况减少了对磁盘的随机访问(如果表达式的数据类型不具有一个<操作符,则此列为空) + 物理行顺序和表达式值逻辑顺序之间的统计关联。其范围从-1到+1。当值接近-1或+1时,在表达式上的一个索引扫描被认为比值接近0时的代价更低,因为这种情况减少了对磁盘的随机访问(如果表达式的数据类型不具有一个<操作符,则此列为 NULL) @@ -4571,7 +4571,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx most_common_elemsanyarray - 与表达式的值一起最常出现的非空元素值的列表。(标量类型时为空) + 与表达式的值一起最常出现的非空元素值的列表。(标量类型时为 NULL) @@ -4581,7 +4581,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx 最常用元素值的频度列表,即含有至少一个给定值实例的行的分数。 - 在每个元素的频度之后有二至三个附加值,它们是每个元素频度的最小和最大值,以及可选的空元素的频度(如果most_common_elems为空,则此列为空) + 在每个元素的频度之后有二至三个附加值,它们是每个元素频度的最小和最大值,以及可选的空元素的频度(如果most_common_elems为 NULL,则此列为 NULL) @@ -4590,7 +4590,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx elem_count_histogramfloat4[] - 表达式值的不同非空元素值的计数的直方图,后面跟着不同非空元素的平均数量。(标量类型时为空) + 表达式值的不同非空元素值的计数的直方图,后面跟着不同非空元素的平均数量。(标量类型时为 NULL) @@ -4620,7 +4620,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx range_bounds_histogramanyarray - 非空且非 NULL 的范围值下界和上界的直方图。(对非范围类型为空。) + 非空且非 NULL 的范围值下界和上界的直方图。(对非范围类型为 NULL。) 这两个直方图表示为单个范围数组,其中下界表示下界直方图,上界表示上界直方图。 @@ -4700,7 +4700,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx (参考 pg_tablespace.spcname) - 包含该表的表空间名称(如果使用数据库的默认表空间,此列为空) + 包含该表的表空间名称(如果使用数据库的默认表空间,此列为 NULL) @@ -4897,7 +4897,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx 视图pg_user提供数据库用户的信息。它本质上是 - pg_shadow 的公开可读视图,并将密码字段清空。 + pg_shadow 的公开可读视图,并隐藏密码字段。
@@ -5175,7 +5175,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx definitiontext - 视图定义(一个重构的查询) + 视图定义(一个重建的查询) diff --git a/zh/19/textsearch.sgml b/zh/19/textsearch.sgml index f764eb52..d887dfc0 100644 --- a/zh/19/textsearch.sgml +++ b/zh/19/textsearch.sgml @@ -2099,7 +2099,7 @@ ALTER TEXT SEARCH CONFIGURATION russian 分类词典示例 - 考虑简单的天文词库 thesaurus_astro,其中包含一些天文单词组合: + 考虑简单的天文词库 thesaurus_astro,其中包含一些天文单词组合: supernovae stars : sn @@ -2581,7 +2581,7 @@ ts_debug( config re - 以下是一个简单的示例: + 以下是一个简单的示例: SELECT * FROM ts_debug('english', 'a fat cat sat on a mat - it ate a fat rats'); diff --git a/zh/19/trigger.sgml b/zh/19/trigger.sgml index 542519fa..8aea568b 100644 --- a/zh/19/trigger.sgml +++ b/zh/19/trigger.sgml @@ -4,7 +4,7 @@ 触发器 - trigger + 触发器 @@ -125,10 +125,15 @@ - 在执行 MERGE 命令时,对于该命令动作中指定的事件,无论该动作最终是否实际执行,语句级 + 在执行 MERGE 命令时,对于 MERGE 命令的动作中指定的事件,无论该动作最终是否实际执行,语句级 BEFOREAFTER 触发器都会触发。这与更新零行的 UPDATE 语句相同:尽管没有行被更新,语句级触发器仍会触发。只有在某行确实被更新、插入或删除时,行级触发器才会触发。因此,完全可能出现这样的情况:某类动作的语句级触发器已经触发,而同类动作的行级触发器却一个也没有触发。 + + 如果 UPDATEDELETE 使用 + FOR PORTION OF,从而插入新行以保留被修改记录中剩余的未命中部分,那么会对每个插入的行触发 INSERT 触发器。每行都是单独插入的,因此它们会触发各自的语句触发器,并且它们各自都有自己的过渡表。(BEFORE DELETE/UPDATE 触发器先触发,然后是 BEFORE INSERT,再然后是 AFTER INSERT,最后是 AFTER DELETE/UPDATE。) + + 由每语句触发器调用的触发器函数应始终返回 NULL。由每行触发器调用的触发器函数则可以根据需要向调用它的执行器返回一个表行(即类型 HeapTuple 的值)。在操作之前触发的行级触发器可以作出如下选择: @@ -169,8 +174,7 @@ 生成列还有一些额外注意事项。 - generated columnin - triggers + 生成列在触发器中 存储型生成列会在 BEFORE 触发器之后、AFTER 触发器之前计算。因此,可以在 AFTER 触发器中检查生成值。在 BEFORE 触发器中,OLD 行如预期那样包含旧的 @@ -181,7 +185,7 @@ - 如果在同一关系上的同一事件为其定义了多个触发器,它们会按触发器名称的字母顺序触发。对于 BEFOREINSTEAD OF + 如果为同一关系上的同一事件定义了多个触发器,它们会按触发器名称的字母顺序触发。对于 BEFOREINSTEAD OF 触发器,每个触发器返回的、可能已经被修改过的行都会成为下一个触发器的输入。如果任何一个 BEFOREINSTEAD OF 触发器返回 NULL,则会放弃对该行执行该操作,并且后续触发器(针对该行)都不会再触发。 @@ -191,7 +195,7 @@ 条件,不过这个特性对它们用处不大。)在 BEFORE 触发器中, WHEN 条件就在函数即将执行或本会执行之前求值,因此使用 WHEN 与在触发器函数开头测试同样的条件并无实质差别。不过,在 - AFTER 触发器中,WHEN 条件会在行更改发生后立即求值,并决定是否要在语句末尾将一个事件排入队列以触发该触发器。因此,当 AFTER 触发器的 WHEN + AFTER 触发器中,WHEN 条件会在行更改发生后立即求值,并决定是否要将一个事件排入队列,以便在语句末尾触发该触发器。因此,当 AFTER 触发器的 WHEN 条件不返回真时,就不必排队该事件,也不必在语句末尾重新取出该行。如果触发器只需要针对少数几行触发,这会让修改大量行的语句显著加快。 INSTEAD OF 触发器不支持 WHEN 条件。 @@ -208,11 +212,6 @@ 如果触发器函数执行 SQL 命令,那么这些命令可能会再次触发触发器。这就是所谓的级联触发器。对级联层数没有直接限制。级联还有可能导致同一个触发器被递归调用;例如,一个 INSERT 触发器可能执行一条向同一个表再插入一行的命令,从而导致该 INSERT 触发器再次触发。因此,在这种场景下,避免无限递归是触发器编写者自己的责任。 - - 如果 UPDATEDELETE 使用 - FOR PORTION OF,从而插入新行以保留被修改记录中剩余的未命中部分,那么会对每个插入的行触发 INSERT 触发器。每行都是单独插入的,因此它们会触发各自的语句触发器,并且它们各自都有自己的过渡表。(BEFORE DELETE/UPDATE 触发器先触发,然后是 BEFORE INSERT,再然后是 AFTER INSERT,最后是 AFTER DELETE/UPDATE。) - - 若外键约束指定了引用动作(即级联更新或级联删除),这些动作会通过在引用表上执行 普通 SQL UPDATEDELETE 命令完成。 @@ -222,8 +221,8 @@ - trigger - arguments for trigger functions + 触发器 + 触发器函数的参数 在定义触发器时,可以为它指定参数。在触发器定义中包含参数,是为了让需求相似的不同触发器能够调用同一个函数。举例来说,可以有一个通用触发器函数,它接受两个列名作为参数,把当前用户写入其中一个列,把当前时间戳写入另一个列。只要编写得当,这个触发器函数就应独立于它所作用的具体表。因此,同一个函数可用于任何具有适当列的表上的 INSERT 事件,例如自动跟踪某个事务表中记录的创建。如果把它定义成 UPDATE 触发器,还可以用来跟踪最近更新事件。 @@ -306,13 +305,13 @@ 用 C 编写触发器函数 - trigger - in C + 触发器 + 在 C 中 - transition tables - referencing from C trigger + 过渡表 + 从 C 触发器中引用 @@ -324,7 +323,7 @@ - 当函数由触发器管理器调用时,不会向它传递任何普通参数,但会传递一个指向 TriggerData 结构体的 context 指针。C 函数可以通过执行下列宏来检查自己是否由触发器管理器调用: + 当函数由触发器管理器调用时,不会向它传递任何普通参数,但会传递一个指向 TriggerData 结构体的 上下文 指针。C 函数可以通过执行下列宏来检查自己是否由触发器管理器调用: CALLED_AS_TRIGGER(fcinfo) @@ -383,7 +382,7 @@ typedef struct TriggerData TRIGGER_FIRED_BEFORE(tg_event) - 如果触发器在操作之前触发,则返回 true。 + 如果触发器在操作之前触发,则返回真。 @@ -392,7 +391,7 @@ typedef struct TriggerData TRIGGER_FIRED_AFTER(tg_event) - 如果触发器在操作之后触发,则返回 true。 + 如果触发器在操作之后触发,则返回真。 @@ -401,7 +400,7 @@ typedef struct TriggerData TRIGGER_FIRED_INSTEAD(tg_event) - 如果触发器是取代该操作而触发,则返回 true。 + 如果触发器是取代该操作而触发,则返回真。 @@ -410,7 +409,7 @@ typedef struct TriggerData TRIGGER_FIRED_FOR_ROW(tg_event) - 如果触发器是因行级事件触发,则返回 true。 + 如果触发器是因行级事件触发,则返回真。 @@ -419,7 +418,7 @@ typedef struct TriggerData TRIGGER_FIRED_FOR_STATEMENT(tg_event) - 如果触发器是因语句级事件触发,则返回 true。 + 如果触发器是因语句级事件触发,则返回真。 @@ -428,7 +427,7 @@ typedef struct TriggerData TRIGGER_FIRED_BY_INSERT(tg_event) - 如果触发器是由 INSERT 命令触发,则返回 true。 + 如果触发器是由 INSERT 命令触发,则返回真。 @@ -437,7 +436,7 @@ typedef struct TriggerData TRIGGER_FIRED_BY_UPDATE(tg_event) - 如果触发器是由 UPDATE 命令触发,则返回 true。 + 如果触发器是由 UPDATE 命令触发,则返回真。 @@ -446,7 +445,7 @@ typedef struct TriggerData TRIGGER_FIRED_BY_DELETE(tg_event) - 如果触发器是由 DELETE 命令触发,则返回 true。 + 如果触发器是由 DELETE 命令触发,则返回真。 @@ -455,7 +454,7 @@ typedef struct TriggerData TRIGGER_FIRED_BY_TRUNCATE(tg_event) - 如果触发器是由 TRUNCATE 命令触发,则返回 true。 + 如果触发器是由 TRUNCATE 命令触发,则返回真。 @@ -614,16 +613,16 @@ typedef struct Trigger - 一个完整的触发器实例 + 一个完整的触发器示例 这里给出一个非常简单的、用 C 编写的触发器函数示例。(用过程语言编写的触发器示例可见各过程语言的文档。) - 如果某条命令试图向列 x 中插入空值,函数 - trigf 就会报告表 ttest - 中的行数,并跳过实际操作。(这样,这个触发器就起到了非空约束的作用,但不会中止事务。) + 函数 trigf 会报告表 ttest 中的行数, + 并在命令试图向列 x 中插入空值时跳过实际操作。 + (这样,这个触发器就起到了非空约束的作用,但不会中止事务。) diff --git a/zh/19/typeconv.sgml b/zh/19/typeconv.sgml index dd5b0f4e..761439b8 100644 --- a/zh/19/typeconv.sgml +++ b/zh/19/typeconv.sgml @@ -30,7 +30,7 @@ -PostgreSQL扫描器/解析器将词法元素分成五个基本类别:整数、非整数数字、字符串、标识符和关键字。大多数非数值类型的常量会先被归类为字符串。SQL语言定义允许用字符串指定类型名,而PostgreSQL可以利用这一机制让解析器从一开始就沿着正确的路径处理。例如,查询: +PostgreSQL扫描器/解析器将词法元素分成五个基本类别:整数、非整数数字、字符串、标识符和关键字。大多数非数值类型的常量会先被归类为字符串。SQL语言定义允许给字符串指定类型名,而PostgreSQL可以利用这一机制让解析器从一开始就沿着正确的路径处理。例如,查询: SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; @@ -41,7 +41,7 @@ SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; (1 row) -包含两个文字常量,它们的类型分别是textpoint。如果没有为某个字符串文字指定类型,那么它最初会被赋予占位类型unknown,并在后文所述的后续阶段解析。 +包含两个字面量,它们的类型分别是textpoint。如果没有为某个字符串字面量指定类型,那么它最初会被赋予占位类型unknown,并在后文所述的后续阶段解析。 @@ -166,11 +166,11 @@ SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; -检查是否存在一个恰好接受输入参数类型的操作符。如果存在(在被考虑的操作符集合中至多只有一个精确匹配),就使用它。若通过限定名调用(这种情况并不常见)某个允许不可信用户创建对象的模式中的操作符,而又缺少精确匹配,就会带来安全隐患 +检查是否存在一个恰好接受输入参数类型的操作符。如果存在(在被考虑的操作符集合中至多只有一个精确匹配),就使用它。若通过限定名调用(这种情况并不常见)某个允许不受信任的用户创建对象的模式中的操作符,而又缺少精确匹配,就会带来安全隐患 - 对于未带模式限定的名称,不会出现这种隐患,因为包含允许不可信用户创建对象的模式的搜索路径不是一种模式的安全使用方式。 + 对于未带模式限定的名称,不会出现这种隐患,因为包含允许不受信任的用户创建对象的模式的搜索路径不是一种模式的安全使用方式。 。在这种情况下,应通过对参数进行类型转换来强制获得精确匹配。 @@ -186,7 +186,7 @@ SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; -如果二元操作符调用的一个参数是unknown类型,而另一个是域类型,则接着检查是否存在两边都恰好接受该域基类型的操作符;如果有,就使用它。 +如果二元操作符调用的一个参数是unknown类型,而另一个是域类型,则接着检查是否存在两边都恰好接受该域基础类型的操作符;如果有,就使用它。 @@ -201,13 +201,13 @@ SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; -丢弃那些输入类型不匹配,且也无法通过隐式类型转换实现匹配的候选操作符。为此,假定unknown文字可以转换为任何类型。如果只剩一个候选操作符,就使用它;否则继续下一步。 +丢弃那些输入类型不匹配,且也无法通过隐式类型转换实现匹配的候选操作符。为此,假定unknown字面量可以转换为任何类型。如果只剩一个候选操作符,就使用它;否则继续下一步。 -如果任何输入参数是域类型,则在后续所有步骤中都把它当作该域的基类型。这样可以确保在解决操作符歧义时,域的行为与其基类型一致。 +如果任何输入参数是域类型,则在后续所有步骤中都把它当作该域的基础类型。这样可以确保在解决操作符歧义时,域的行为与其基础类型一致。 @@ -219,13 +219,13 @@ SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; -遍历所有候选操作符,保留那些在需要类型转换的最多位置上接受首选类型(属于输入数据类型的类型分类)的候选项。如果没有候选项接受首选类型,则保留全部候选项。如果只剩一个候选操作符,就使用它;否则继续下一步。 +遍历所有候选操作符,在需要类型转换的位置上,保留接受首选类型(属于输入数据类型的类型分类)的位置数最多的候选项。如果没有候选项接受首选类型,则保留全部候选项。如果只剩一个候选操作符,就使用它;否则继续下一步。 -如果有任何输入参数是unknown,就检查剩余候选操作符在这些参数位置上接受哪些类型分类。在每个位置上,如果有任何候选项接受string分类,就选择该分类。(这种偏向字符串的做法是合适的,因为unknown类型的文字看起来像字符串。)否则,如果所有剩余候选项都接受同一种类型分类,就选择该分类;否则失败,因为在缺少更多线索的情况下无法推断出正确选择。然后丢弃不接受所选类型分类的候选项。此外,如果有任何候选项接受该分类中的首选类型,就丢弃在该参数上接受非首选类型的候选项。如果没有候选项通过这些测试,则保留全部候选项。如果只剩一个候选操作符,就使用它;否则继续下一步。 +如果有任何输入参数是unknown,就检查剩余候选操作符在这些参数位置上接受哪些类型分类。在每个位置上,如果有任何候选项接受string分类,就选择该分类。(这种偏向字符串的做法是合适的,因为unknown类型的字面量看起来像字符串。)否则,如果所有剩余候选项都接受同一种类型分类,就选择该分类;否则失败,因为在缺少更多线索的情况下无法推断出正确选择。然后丢弃不接受所选类型分类的候选项。此外,如果有任何候选项接受该分类中的首选类型,就丢弃在该参数上接受非首选类型的候选项。如果没有候选项通过这些测试,则保留全部候选项。如果只剩一个候选操作符,就使用它;否则继续下一步。 @@ -273,7 +273,7 @@ SELECT |/ CAST(40 AS double precision) AS "square root of 40"; -一个只有一个未指定参数的例子: +一个参数未指定类型的例子: SELECT text 'abc' || 'def' AS "text and unknown"; @@ -301,7 +301,7 @@ SELECT 'abc' || 'def' AS "unspecified"; -这里对使用哪种类型没有初始提示,因为查询中没有指定任何类型。因此,解析器会查找所有候选操作符,并发现既有接受字符串分类输入的候选项,也有接受位串分类输入的候选项。由于在可用时优先选择字符串分类,所以会选中该分类,再使用字符串的首选类型text作为解析这些unknown类型文字的具体类型。 +这里对使用哪种类型没有初始提示,因为查询中没有指定任何类型。因此,解析器会查找所有候选操作符,并发现既有接受字符串分类输入的候选项,也有接受位串分类输入的候选项。由于在可用时优先选择字符串分类,所以会选中该分类,再使用字符串的首选类型text作为解析这些unknown类型字面量的具体类型。 @@ -318,7 +318,7 @@ SELECT @ '-4.5' AS "abs"; 4.5 (1 row) -这里,系统在应用所选操作符之前,已经把unknown类型文字隐式解析为float8。我们可以验证使用的确实是float8,而不是其他类型: +这里,系统在应用所选操作符之前,已经把unknown类型字面量隐式解析为float8。我们可以验证使用的确实是float8,而不是其他类型: SELECT @ '-4.5e500' AS "abs"; @@ -352,7 +352,7 @@ SELECT ~ CAST('20' AS int8) AS "negation"; 数组包含操作符类型解析 -下面是另一个解析一边已知、一边未知输入的操作符的例子: +下面是另一个解析带有一个已知类型输入和一个未知类型输入的操作符的例子: SELECT ARRAY[1, 2] <@ '{1,2,3}' AS "is subset"; @@ -361,7 +361,7 @@ SELECT ARRAY[1, 2] <@ '{1,2,3}' AS "is subset"; t (1 row) -PostgreSQL操作符目录中为中缀操作符<@定义了多个条目,但左侧能够接受整数数组的只有两种:数组包含(anyarray <@ anyarray)和范围包含(anyelement <@ anyrange)。由于这些多态伪类型(见)都不被视为首选类型,解析器无法据此消除歧义。不过,告诉它可以假定unknown类型文字与另一输入具有相同类型,也就是整数数组。这样两个操作符中只有一个能够匹配,因此会选择数组包含。(如果选中范围包含,就会报错,因为该字符串的格式并不是合法的范围文字。) +PostgreSQL操作符目录中为中缀操作符<@定义了多个条目,但左侧能够接受整数数组的只有两种:数组包含(anyarray <@ anyarray)和范围包含(anyelement <@ anyrange)。由于这些多态伪类型(见)都不被视为首选类型,解析器无法据此消除歧义。不过,要求它假定unknown类型字面量与另一输入具有相同类型,也就是整数数组。这样两个操作符中只有一个能够匹配,因此会选择数组包含。(如果选中范围包含,就会报错,因为该字符串的格式并不是合法的范围字面量。) @@ -370,7 +370,7 @@ SELECT ARRAY[1, 2] <@ '{1,2,3}' AS "is subset"; 域类型上的自定义操作符 -用户有时会尝试声明只适用于某个域类型的操作符。这是可行的,但远没有看上去那样有用,因为操作符解析规则被设计成优先选择作用于域基类型的操作符。考虑下面的例子: +用户有时会尝试声明只适用于某个域类型的操作符。这是可行的,但远没有看上去那样有用,因为操作符解析规则被设计成优先选择作用于域基础类型的操作符。考虑下面的例子: CREATE DOMAIN mytext AS text CHECK(...); CREATE FUNCTION mytext_eq_text (mytext, text) RETURNS boolean AS ...; @@ -379,11 +379,11 @@ CREATE TABLE mytable (val mytext); SELECT * FROM mytable WHERE val = 'foo'; -这个查询不会使用自定义操作符。解析器首先会检查是否存在mytext = mytext操作符(),但并不存在;然后它会考虑该域的基类型text,并检查是否存在text = text操作符(),而这是存在的;于是它会把unknown类型的文字解析为text,并使用text = text操作符。要让自定义操作符被使用,唯一的方法是显式地对该文字做类型转换: +这个查询不会使用自定义操作符。解析器首先会检查是否存在mytext = mytext操作符(),但并不存在;然后它会考虑该域的基础类型text,并检查是否存在text = text操作符(),而这是存在的;于是它会把unknown类型的字面量解析为text,并使用text = text操作符。要让自定义操作符被使用,唯一的方法是显式地对该字面量做类型转换: SELECT * FROM mytable WHERE val = text 'foo'; -这样就会根据精确匹配规则立即找到mytext = text操作符。如果解析过程进入最佳匹配规则,它们会主动排斥作用于域类型的操作符。如果不是这样,这类操作符会导致过多的操作符歧义失败,因为类型转换规则总是把域视为可以转换到其基类型或从其基类型转换而来,因此域操作符会在所有与基类型上同名操作符相同的场景中都被视为可用。 +这样就会根据精确匹配规则立即找到mytext = text操作符。如果解析过程进入最佳匹配规则,它们会主动排斥作用于域类型的操作符。如果不是这样,这类操作符会导致过多的操作符歧义失败,因为类型转换规则总是把域视为可以转换到其基础类型或从其基础类型转换而来,因此域操作符会在所有与基础类型上同名操作符相同的场景中都被视为可用。 @@ -422,27 +422,27 @@ SELECT * FROM mytable WHERE val = text 'foo'; -如果函数声明了一个VARIADIC数组参数,而调用时没有使用VARIADIC关键字,则把该函数视为其数组参数按需要被其元素类型的一个或多个出现所替换,以匹配该调用。扩展之后,该函数的有效参数类型可能与某个非VARIADIC函数完全相同。在这种情况下,使用搜索路径中较早出现的函数;如果两个函数位于同一模式,则优先选择非VARIADIC函数。 +如果函数声明了一个VARIADIC数组参数,而调用时没有使用VARIADIC关键字,则把数组参数视为一个或多个其元素类型的参数,个数按匹配该调用的需要确定。扩展之后,该函数的有效参数类型可能与某个非VARIADIC函数完全相同。在这种情况下,使用搜索路径中较早出现的函数;如果两个函数位于同一模式,则优先选择非VARIADIC函数。 -通过限定名调用某个允许不可信用户创建对象的模式中找到的可变参数函数时,会带来安全隐患 +通过限定名调用某个允许不受信任的用户创建对象的模式中找到的可变参数函数时,会带来安全隐患 - 对于未带模式限定的名称,不会出现这种隐患,因为包含允许不可信用户创建对象的模式的搜索路径不是一种模式的安全使用方式。 + 对于未带模式限定的名称,不会出现这种隐患,因为包含允许不受信任的用户创建对象的模式的搜索路径不是一种模式的安全使用方式。 - 。恶意用户可以借此劫持调用,并以你的身份执行任意 SQL 函数。改为使用带有VARIADIC关键字的调用可以绕过这一隐患。对于填充VARIADIC "any"参数的调用,往往没有包含VARIADIC关键字的等价写法。要安全地发出这类调用,该函数所在模式必须只允许可信用户创建对象。 + 。恶意用户可以借此劫持调用,并以你的身份执行任意 SQL 函数。改为使用带有VARIADIC关键字的调用可以绕过这一隐患。对于填充VARIADIC "any"参数的调用,往往没有包含VARIADIC关键字的等价写法。要安全地发出这类调用,该函数所在模式必须只允许受信任的用户创建对象。 -带有参数默认值的函数,被认为可以匹配任何省略了零个或多个可默认参数位置的调用。如果不止一个这样的函数能匹配某个调用,则使用搜索路径中最早出现的那一个。如果同一模式中存在两个或更多这样的函数,并且它们在未使用默认值的参数位置上的参数类型相同(如果它们具有不同的可默认参数集合,这种情况是可能的),系统就无法判断该偏好哪一个;如果找不到更好的匹配,就会报有歧义的函数调用错误。 +带有参数默认值的函数,被认为可以匹配任何省略了零个或多个可使用默认值的参数位置的调用。如果不止一个这样的函数能匹配某个调用,则使用搜索路径中最早出现的那一个。如果同一模式中存在两个或更多这样的函数,并且它们在未使用默认值的参数位置上的参数类型相同(如果它们具有不同的带有默认值的参数集合,这种情况是可能的),系统就无法判断该偏好哪一个;如果找不到更好的匹配,就会报有歧义的函数调用错误。 -通过限定名调用某个允许不可信用户创建对象的模式中的任意函数时,会带来可用性隐患。恶意用户可以用现有函数的名字创建一个新函数,复制该函数的参数,并附加带有默认值的新参数。这样就会阻止对原始函数的新调用。为避免这种隐患,应把函数放在只允许可信用户创建对象的模式中。 +通过限定名调用某个允许不受信任的用户创建对象的模式中的任意函数时,会带来可用性隐患。恶意用户可以用现有函数的名字创建一个新函数,复制该函数的参数,并附加带有默认值的新参数。这样就会阻止对原始函数的新调用。为避免这种隐患,应把函数放在只允许受信任的用户创建对象的模式中。 @@ -451,14 +451,14 @@ SELECT * FROM mytable WHERE val = text 'foo'; -检查是否存在一个恰好接受输入参数类型的函数。如果存在(在被考虑的函数集合中至多只有一个精确匹配),就使用它。若通过限定名调用某个允许不可信用户创建对象的模式中的函数,而又缺少精确匹配,就会带来安全隐患。在这种情况下,应通过对参数进行类型转换来强制获得精确匹配。(涉及unknown的情况在这一步永远找不到匹配。) +检查是否存在一个恰好接受输入参数类型的函数。如果存在(在被考虑的函数集合中至多只有一个精确匹配),就使用它。若通过限定名调用某个允许不受信任的用户创建对象的模式中的函数,而又缺少精确匹配,就会带来安全隐患。在这种情况下,应通过对参数进行类型转换来强制获得精确匹配。(涉及unknown的情况在这一步永远找不到匹配。) -如果没有找到精确匹配,就检查该函数调用是否看起来像一种特殊的类型转换请求。这种情况发生在:函数调用只有一个参数,且函数名与某个数据类型的(内部)名称相同。此外,函数参数必须是unknown类型文字,或者是一种能够进行二进制强制转换到该命名数据类型的类型,或者是一种可以通过应用其 I/O 函数转换为该命名数据类型的类型(也就是说,该转换要么转到某种标准字符串类型,要么从某种标准字符串类型转来)。满足这些条件时,该函数调用会被当作一种CAST形式。 +如果没有找到精确匹配,就检查该函数调用是否看起来像一种特殊的类型转换请求。这种情况发生在:函数调用只有一个参数,且函数名与某个数据类型的(内部)名称相同。此外,函数参数必须是unknown类型字面量,或者是一种可以二进制强制转换为该命名数据类型的类型,或者是一种可以通过应用其 I/O 函数转换为该命名数据类型的类型(也就是说,该转换要么转到某种标准字符串类型,要么从某种标准字符串类型转来)。满足这些条件时,该函数调用会被当作一种CAST形式。 之所以有这一步,是为了在不存在实际类型转换函数的情况下仍支持函数风格的类型转换写法。如果存在类型转换函数,按惯例它会以其输出类型命名,因此无需为此设置特殊情况。更多说明见。 @@ -475,13 +475,13 @@ SELECT * FROM mytable WHERE val = text 'foo'; -丢弃那些输入类型不匹配,且也无法通过隐式类型转换实现匹配的候选函数。为此,假定unknown文字可以转换为任何类型。如果只剩一个候选函数,就使用它;否则继续下一步。 +丢弃那些输入类型不匹配,且也无法通过隐式类型转换实现匹配的候选函数。为此,假定unknown字面量可以转换为任何类型。如果只剩一个候选函数,就使用它;否则继续下一步。 -如果任何输入参数是域类型,则在后续所有步骤中都把它当作该域的基类型。这样可以确保在解决函数歧义时,域的行为与其基类型一致。 +如果任何输入参数是域类型,则在后续所有步骤中都把它当作该域的基础类型。这样可以确保在解决函数歧义时,域的行为与其基础类型一致。 @@ -493,13 +493,13 @@ SELECT * FROM mytable WHERE val = text 'foo'; -遍历所有候选函数,保留那些在需要类型转换的最多位置上接受首选类型(属于输入数据类型的类型分类)的候选项。如果没有候选项接受首选类型,则保留全部候选项。如果只剩一个候选函数,就使用它;否则继续下一步。 +遍历所有候选函数,在需要类型转换的位置上,保留接受首选类型(属于输入数据类型的类型分类)的位置数最多的候选项。如果没有候选项接受首选类型,则保留全部候选项。如果只剩一个候选函数,就使用它;否则继续下一步。 -如果有任何输入参数是unknown,就检查剩余候选函数在这些参数位置上接受哪些类型分类。在每个位置上,如果有任何候选项接受string分类,就选择该分类。(这种偏向字符串的做法是合适的,因为unknown类型的文字看起来像字符串。)否则,如果所有剩余候选项都接受同一种类型分类,就选择该分类;否则失败,因为在缺少更多线索的情况下无法推断出正确选择。然后丢弃不接受所选类型分类的候选项。此外,如果有任何候选项接受该分类中的首选类型,就丢弃在该参数上接受非首选类型的候选项。如果没有候选项通过这些测试,则保留全部候选项。如果只剩一个候选函数,就使用它;否则继续下一步。 +如果有任何输入参数是unknown,就检查剩余候选函数在这些参数位置上接受哪些类型分类。在每个位置上,如果有任何候选项接受string分类,就选择该分类。(这种偏向字符串的做法是合适的,因为unknown类型的字面量看起来像字符串。)否则,如果所有剩余候选项都接受同一种类型分类,就选择该分类;否则失败,因为在缺少更多线索的情况下无法推断出正确选择。然后丢弃不接受所选类型分类的候选项。此外,如果有任何候选项接受该分类中的首选类型,就丢弃在该参数上接受非首选类型的候选项。如果没有候选项通过这些测试,则保留全部候选项。如果只剩一个候选函数,就使用它;否则继续下一步。 @@ -680,7 +680,7 @@ SELECT substr(CAST (1234 AS text), 3); -否则,尝试把表达式转换为目标类型。如果这两种类型之间在pg_cast目录中登记了赋值类型转换(见),就可以这样做。另一种情况是,如果表达式是unknown类型文字,则会把文字字符串的内容送入目标类型的输入转换例程。 +否则,尝试把表达式转换为目标类型。如果这两种类型之间在pg_cast目录中登记了赋值类型转换(见),就可以这样做。另一种情况是,如果表达式是unknown类型字面量,则会把字符串字面量的内容送入目标类型的输入转换例程。 @@ -713,7 +713,7 @@ SELECT v, octet_length(v) FROM vv; -这里实际发生的是,两个unknown类型文字默认都被解析为text,从而使||操作符被解析为text的连接操作。然后,操作符得到的text结果被转换为bpcharblank-padded char,即character数据类型的内部名称),以匹配目标列类型。(由于从textbpchar的转换是二进制可强制转换的,这一步不会插入任何真实的函数调用。)最后,系统目录中找到尺寸调整函数bpchar(bpchar, integer, boolean),并把它应用到操作符结果以及存储列长度上。这个特定于类型的函数会执行所需的长度检查并补齐填充空格。 +这里实际发生的是,两个unknown类型字面量默认都被解析为text,从而使||操作符被解析为text的连接操作。然后,操作符得到的text结果被转换为bpchar用空格填充的字符,blank-padded char,即character数据类型的内部名称),以匹配目标列类型。(由于从textbpchar的转换是二进制可强制转换的,这一步不会插入任何真实的函数调用。)最后,系统从系统目录中找到尺寸调整函数bpchar(bpchar, integer, boolean),并把它应用到操作符结果以及存储列长度上。这个特定于类型的函数会执行所需的长度检查并补齐填充空格。 @@ -770,10 +770,10 @@ SQL 的UNION结构必须让可能不同的类型彼此匹配 -如果任何输入是域类型,则在后续所有步骤中都把它当作该域的基类型。 +如果任何输入是域类型,则在后续所有步骤中都把它当作该域的基础类型。 - 这在某种程度上类似于操作符和函数对域输入的处理方式;只要用户确保所有输入都隐式或显式地正好属于该域类型,这种行为就能让域类型在UNION或类似结构中得以保留。否则,就会使用该域的基类型。 + 这在某种程度上类似于操作符和函数对域输入的处理方式;只要用户确保所有输入都隐式或显式地正好属于该域类型,这种行为就能让域类型在UNION或类似结构中得以保留。否则,就会使用该域的基础类型。 @@ -832,7 +832,7 @@ SELECT text 'a' AS "text" UNION SELECT 'b'; b (2 rows) -这里,unknown类型文字'b'会被解析为text类型。 +这里,unknown类型字面量'b'会被解析为text类型。 @@ -850,7 +850,7 @@ SELECT 1.2 AS "numeric" UNION SELECT 1; 1.2 (2 rows) -文字常量1.2的类型是numeric,而integer1可以隐式转换为numeric,因此使用该类型。 +字面量1.2的类型是numeric,而integer1可以隐式转换为numeric,因此使用该类型。 @@ -905,17 +905,17 @@ ERROR: UNION types text and integer cannot be matched -前面各节给出的规则会为 SQL 查询中的所有表达式分配非unknown的数据类型,唯一的例外是作为SELECT命令简单输出列出现的未指定类型文字常量。例如,在 +前面各节给出的规则会为 SQL 查询中的所有表达式分配非unknown的数据类型,唯一的例外是作为SELECT命令简单输出列出现的未指定类型字面量。例如,在 SELECT 'Hello World'; -中,没有任何信息能够表明这个字符串文字应该视为哪种类型。在这种情况下,PostgreSQL会退回到把该文字解析为text类型。 +中,没有任何信息能够表明这个字符串字面量应该视为哪种类型。在这种情况下,PostgreSQL会退回到把该字面量解析为text类型。 -当SELECTUNION(或INTERSECTEXCEPT)结构的一端,或者出现在INSERT ... SELECT中时,这条规则不适用,因为前面各节给出的规则具有更高优先级。在前一种情况下,未指定类型文字的类型可以从UNION的另一侧取得;在后一种情况下,则从目标列取得。 +当SELECTUNION(或INTERSECTEXCEPT)结构的一端,或者出现在INSERT ... SELECT中时,这条规则不适用,因为前面各节给出的规则具有更高优先级。在前一种情况下,未指定类型字面量的类型可以从UNION的另一侧取得;在后一种情况下,则从目标列取得。 @@ -925,7 +925,7 @@ SELECT 'Hello World'; - 在PostgreSQL 10 之前,这条规则并不存在,SELECT输出列表中的未指定类型文字会被保留为unknown类型。这会带来各种不良后果,因此后来做了修改。 + 在PostgreSQL 10 之前,这条规则并不存在,SELECT输出列表中的未指定类型字面量会被保留为unknown类型。这会带来各种不良后果,因此后来做了修改。 diff --git a/zh/19/user-manag.sgml b/zh/19/user-manag.sgml index 52011ada..122c7f28 100644 --- a/zh/19/user-manag.sgml +++ b/zh/19/user-manag.sgml @@ -312,12 +312,12 @@ ALTER TABLE bobs_table OWNER TO alice; - 一旦有价值的对象都已转移给新拥有者,被删除角色所拥有的其余对象即可使用DROP OWNED命令删除。同样,由于该命令不能访问其他数据库中的对象,因此必须在包含该角色所拥有对象的每个数据库中运行它。另外,DROP + 一旦有价值的对象都已转移给新拥有者,待删除角色所拥有的其余对象即可使用DROP OWNED命令删除。同样,由于该命令不能访问其他数据库中的对象,因此必须在包含该角色所拥有对象的每个数据库中运行它。另外,DROP OWNED不会删除整个数据库或表空间,因此如果该角色拥有任何尚未转移给新拥有者的数据库或表空间,就必须手工删除它们。 - DROP OWNED还会负责移除授予目标角色、但不属于它自身对象的任何权限。由于REASSIGN OWNED不会处理这类对象,所以通常需要同时运行REASSIGN OWNEDDROP OWNED(按这个顺序!),才能完整移除待删除角色的依赖关系。 + DROP OWNED还会负责移除目标角色在其他角色所拥有的对象上获授的所有权限。由于REASSIGN OWNED不会处理这类对象,所以通常需要同时运行REASSIGN OWNEDDROP OWNED(按这个顺序!),才能完整移除待删除角色的依赖关系。 @@ -356,7 +356,7 @@ GRANT pg_signal_backend TO admin_user; - 授予这些角色时应当谨慎,确保它们只在需要时使用,并理解这些角色会授予对敏感信息的访问。 + 授予这些角色时应当谨慎,确保它们只在需要时使用,并理解这些角色会授予对需要特权才能访问的信息的访问。 @@ -422,7 +422,7 @@ GRANT pg_signal_backend TO admin_user; pg_read_all_settings允许读取所有配置变量,即使是那些通常仅对超级用户可见的变量。 - pg_read_all_stats允许读取所有 pg_stat_* 视图,并使用各种与统计信息相关的扩展,即使是那些通常仅对超级用户可见的扩展。 + pg_read_all_stats允许读取所有 pg_stat_* 视图,并使用各种与统计信息相关的扩展,包括通常仅对超级用户可见的内容。 pg_stat_scan_tables允许执行可能在表上持有ACCESS SHARE锁并持续较长时间的监控函数(例如pgrowlocks(text),见扩展)。 @@ -449,7 +449,7 @@ GRANT pg_signal_backend TO admin_user; pg_execute_server_program - 这些角色旨在允许管理员创建受信任但非超级用户的角色,使其能够以数据库运行所用操作系统用户的身份访问文件并在数据库服务器上运行程序。它们在直接访问文件时会绕过所有数据库级权限检查,并且可被用来获得超级用户级别的访问能力。因此,向用户授予这些角色时必须极其谨慎。 + 这些角色旨在让管理员能够使受信任但非超级用户的角色能够以数据库运行所用操作系统用户的身份访问文件并在数据库服务器上运行程序。它们在直接访问文件时会绕过所有数据库级权限检查,并且可被用来获得超级用户级别的访问能力。因此,向用户授予这些角色时必须极其谨慎。 pg_read_server_files允许使用COPY和其他文件访问函数,从服务器上数据库可访问的任何位置读取文件。 @@ -498,7 +498,7 @@ GRANT pg_signal_backend TO admin_user; 函数安全性 - 函数、触发器和行级安全策略允许用户把代码插入后端服务器,而其他用户可能会无意中执行这些代码。因此,这些机制使用户能够相对容易地对其他用户实施特洛伊木马攻击。最强的保护方式是严格控制谁能定义对象。如果这不可行,则应编写只引用拥有者可信对象的查询,并从search_path中移除任何允许不受信任用户创建对象的模式。 + 函数、触发器和行级安全策略允许用户把代码插入后端服务器,而其他用户可能会无意中执行这些代码。因此,这些机制使用户能够相对容易地对其他用户实施特洛伊木马攻击。最强的保护方式是严格控制谁能定义对象。如果这不可行,则应编写只引用拥有者可信的对象的查询,并从search_path中移除任何允许不受信任用户创建对象的模式。 diff --git a/zh/19/vacuumlo.sgml b/zh/19/vacuumlo.sgml index 9e80b19f..cc2c04f5 100644 --- a/zh/19/vacuumlo.sgml +++ b/zh/19/vacuumlo.sgml @@ -8,7 +8,7 @@ vacuumlo 1 - Application + 应用程序 diff --git a/zh/19/wal.sgml b/zh/19/wal.sgml index e94880a9..62c83458 100644 --- a/zh/19/wal.sgml +++ b/zh/19/wal.sgml @@ -488,9 +488,9 @@ 检查点检查点 是事务序列中的一些点,在这些点上可以保证堆和索引数据文件已经用检查点之前写入 - 的全部信息进行了更新。执行检查点时,所有脏数据页都会刷写到磁盘,并向 WAL - 文件写入一条特殊的检查点记录。(更改记录此前已经刷入 WAL - 文件。)如果发生崩溃,崩溃恢复过程会查看最新的检查点记录,以确定应该从 WAL + 的全部信息进行了更新。执行检查点时,所有脏数据页都会刷盘,并向 WAL + 文件写入一条特殊的检查点记录。(更改记录此前已写入 WAL + 文件并刷盘。)如果发生崩溃,崩溃恢复过程会查看最新的检查点记录,以确定应该从 WAL 的哪个位置(称为重做记录)开始执行 REDO。该点之前对数据文件所做的任何更改 都保证已经在磁盘上。因此,检查点之后,位于包含重做记录的段之前的 WAL 段不再需要, 可以被回收或删除。(若正在执行 WAL 归档,则这些 WAL 段必 @@ -518,7 +518,7 @@ 减小 checkpoint_timeout 和/或 max_wal_size 会让检查点更频繁地发生。这样可以加快崩溃后 - 恢复,因为需要重做的工作更少。不过,这必须与更频繁刷写脏数据页所增加的成本 + 恢复,因为需要重做的工作更少。不过,这必须与更频繁地将脏数据页刷盘所增加的成本 权衡。如果设置了 (默认就是如此), 还要考虑另一个因素。为了保证数据页一致性,每个检查点之后对某个数据页的首次 修改,都会导致把整页内容写入日志。在这种情况下,更短的检查点间隔会增加输出到 @@ -545,7 +545,7 @@ I/O 速率,使检查点在给定比例的 checkpoint_timeout 秒数 经过时完成,或者在 max_wal_size 即将超出之前完成,以较早 者为准。使用默认值 0.9 时,可以预期 PostgreSQL - 会在下一次计划检查点开始前稍早完成每个检查点(大约在检查点间隔的 90% 时)。 + 会在下一次计划检查点开始前稍早完成每个检查点(耗时约为上一次检查点持续时间的 90%)。 这样能尽可能摊平 I/O,从而使检查点 I/O 负载在整个检查点间隔内保持稳定。这样 做的缺点是,延长检查点会影响恢复时间,因为需要保留更多 WAL 段以备恢复时 使用。关心恢复耗时的用户,可能希望减小 @@ -561,7 +561,7 @@ 在 Linux 和 POSIX 平台上, - 允许在检查点写出的操作系统页面达到可配置的字节数后,强制把它们刷到磁盘。 + 允许在检查点写出的操作系统页面达到可配置的字节数后,强制将它们刷盘。 否则,这些页面可能会停留在操作系统页缓存中,从而在检查点末尾发出 fsync 时引发停顿。这个设置通常有助于降低事务延迟,但也可能 对性能产生不利影响,尤其是在工作负载大于 @@ -599,7 +599,7 @@ 在归档恢复或备库模式下,服务器会周期性地执行 重启点重启点, - 其行为类似于正常运行时的检查点:服务器会强制把自身状态写盘,更新 + 其行为类似于正常运行时的检查点:服务器会强制将其所有状态刷盘,更新 pg_control 文件,以表明已经处理过的 WAL 数据无需再次 扫描,然后回收 pg_wal 目录中的旧 WAL 段文件。重启点的 执行频率不会高于主库上的检查点,因为重启点只能在检查点记录处执行。重启点既 @@ -642,7 +642,7 @@ 快。更糟的是,写 WAL 缓冲区还可能迫使系统创建新的 WAL 段, 这会花费更多时间。正常情况下,WAL 缓冲区应由 XLogFlush 请求负责写出并刷盘; - 该请求大多发生在事务提交时,以确保事务记录被刷入持久存储。在 WAL 输出量很高 + 该请求大多发生在事务提交时,以确保事务记录已刷盘至持久存储。在 WAL 输出量很高 的系统上,XLogFlush 请求可能不够频繁,无法避免 XLogInsertRecord 自己去执行写出。在这种系统上,应增加 WAL 缓冲区的数量,具体做法是修改参数 @@ -655,7 +655,7 @@ 参数 定义了组提交的领导者进程在 XLogFlush 内部获取锁之后会睡眠多少微秒,在此期间,组提 交的追随者会排队跟在领导者后面。这一延迟允许其他服务器进程把自己的提交记录添 - 加到 WAL 缓冲区中,以便它们都能由领导者最终执行的同步操作一并刷出。如果没有 + 加到 WAL 缓冲区中,以便它们都能由领导者最终执行的同步操作一并刷盘。如果没有 启用 ,或者当前处于活跃事务中的其他会话少于 个,就不会发生睡眠;这样可以避免在其他 会话不太可能很快提交时还去睡眠。请注意,在某些平台上,休眠请求的分辨率是 @@ -684,8 +684,7 @@ commit_delay 设为 0(默认值)时,仍然可能出现一种组 - 提交,但每个组只会包含那些恰好在前一次刷盘操作(若有)进行期间,到达“需要刷 - 出其提交记录”这一点的会话。客户端数量更高时,往往会出现一种 + 提交,但每个组只会包含那些恰好在前一次刷盘操作(若有)进行期间,到达“需要将其提交记录刷盘”这一点的会话。客户端数量更高时,往往会出现一种 gangway effect,以至于即使 commit_delay 为 0,组提交的效果也会变得很显著,因此显式设置 commit_delay 的帮助反而会变小。只有在以下两种条件同时 @@ -698,9 +697,9 @@ 参数 决定 PostgreSQL 将如何请求内核把 - WAL 更新强制刷到磁盘。就可靠性而言,所有选项应当都是相同 + WAL 更新强制刷盘。就可靠性而言,所有选项应当都是相同 的;例外是 fsync_writethrough,它有时能够在其他选项做不 - 到时强制刷新磁盘缓存。不过,具体哪个选项速度最快则高度依赖平台。可以使用 + 到时强制将磁盘缓存中的数据刷盘。不过,具体哪个选项速度最快则高度依赖平台。可以使用 程序测试不同选项的速度。请注意,如果 fsync 已被关闭,那么这个参数就没有意义。 diff --git a/zh/19/xaggr.sgml b/zh/19/xaggr.sgml index b46b119e..d7ef45aa 100644 --- a/zh/19/xaggr.sgml +++ b/zh/19/xaggr.sgml @@ -43,11 +43,11 @@ SELECT sum(a) FROM test_complex; - 如果没有非空输入值,上述sum定义将返回零(即初始状态值)。也许我们更希望在这种情况下返回空值 — SQL 标准要求sum这样做。实现这一点只需省略initcond短语,使初始状态值为空。通常这意味着sfunc需要检查输入的状态值是否为空。但对于sum以及maxmin这类其他简单聚合,只需把第一个非空输入值放入状态变量,然后从第二个非空输入值开始应用转移函数即可。如果初始状态值为空,并且转移函数被标记为strict(即不会对空输入调用),PostgreSQL会自动这样做。 + 如果没有非空输入值,上述sum定义将返回零(即初始状态值)。也许我们更希望在这种情况下返回空值 — SQL 标准要求sum这样做。实现这一点只需省略initcond短语,使初始状态值为空值。通常这意味着sfunc需要检查输入的状态值是否为空值。但对于sum以及maxmin这类其他简单聚合,只需把第一个非空输入值放入状态变量,然后从第二个非空输入值开始应用转移函数即可。如果初始状态值为空值,并且转移函数被标记为strict(即不会对空值输入调用),PostgreSQL会自动这样做。 - strict转移函数的另一项默认行为是,只要遇到空输入值,就会保留先前的状态值不变。因此,空值会被忽略。如果你需要对空输入采用其他行为,就不要把转移函数声明为 strict,而应在函数代码中自行检测空输入并完成所需处理。 + strict转移函数的另一项默认行为是,只要遇到空值输入,就会保留先前的状态值不变。因此,空值会被忽略。如果你需要对空值输入采用其他行为,就不要把转移函数声明为 strict,而应在函数代码中自行检测空值输入并完成所需处理。 @@ -72,7 +72,7 @@ CREATE AGGREGATE avg (float8) - SQL 中的聚合函数调用允许使用DISTINCTORDER BY选项,以控制哪些行会传递给聚合的转移函数,以及传递顺序。这些选项是在后台实现的,并不是聚合支持函数需要关心的事情。 + SQL 中的聚合函数调用允许使用DISTINCTORDER BY选项,以控制哪些行会传递给聚合的转移函数,以及传递顺序。这些选项由系统在内部实现,并不是聚合支持函数需要关心的事情。 @@ -292,7 +292,7 @@ SELECT percentile_disc(0.5) WITHIN GROUP (ORDER BY income) FROM households; - 与普通聚合不同,有序集聚合的输入行排序不是在幕后完成的,而是由聚合的支持函数负责。典型的实现方法是在聚合的状态值中保存一个tuplesort对象的引用,把输入行送入该对象,然后在最终函数中完成排序并读出数据。这样的设计使最终函数可以执行特殊操作,例如向待排序数据中注入额外的假想行。普通聚合通常可以使用由PL/pgSQL或其他 PL 语言编写的支持函数来实现,但有序集聚合通常必须用 C 编写,因为它们的状态值无法定义为任何 SQL 数据类型。(在上面的示例中,注意状态值被声明为internal类型,这很典型。)另外,由于最终函数执行了排序,之后就不可能再通过再次执行转移函数来继续加入输入行。这意味着最终函数不是READ_ONLY;在CREATE AGGREGATE中,必须将其声明为READ_WRITE,或者如果额外的最终函数调用能够利用已经排好序的状态,则声明为SHAREABLE。 + 与普通聚合不同,有序集聚合的输入行排序不是由系统在内部完成的,而是由聚合的支持函数负责。典型的实现方法是在聚合的状态值中保存一个tuplesort对象的引用,把输入行送入该对象,然后在最终函数中完成排序并读出数据。这样的设计使最终函数可以执行特殊操作,例如向待排序数据中注入额外的假想行。普通聚合通常可以使用由PL/pgSQL或其他 PL 语言编写的支持函数来实现,但有序集聚合通常必须用 C 编写,因为它们的状态值无法定义为任何 SQL 数据类型。(在上面的示例中,注意状态值被声明为internal类型,这很典型。)另外,由于最终函数执行了排序,之后就不可能再通过再次执行转移函数来继续加入输入行。这意味着最终函数不是READ_ONLY;在CREATE AGGREGATE中,必须将其声明为READ_WRITE,或者如果额外的最终函数调用能够利用已经排好序的状态,则声明为SHAREABLE @@ -366,7 +366,7 @@ if (AggCheckCallContext(fcinfo, NULL)) - AggCheckCallContext的第二个参数可用于取得保存聚合状态值的内存上下文。这对于希望把扩展对象(见)用作状态值的转移函数很有用。第一次调用时,转移函数应返回一个扩展对象,其内存上下文是聚合状态上下文的子上下文;之后的调用则持续返回同一个扩展对象。示例见array_append()。(array_append()并不是任何内置聚合的转移函数,但它的写法保证了在用作自定义聚合的转移函数时也能高效工作。) + AggCheckCallContext的第二个参数可用于取得保存聚合状态值的内存上下文。这对于希望把展开对象(见)用作状态值的转移函数很有用。第一次调用时,转移函数应返回一个展开对象,其内存上下文是聚合状态上下文的子上下文;之后的调用则持续返回同一个展开对象。示例见array_append()。(array_append()并不是任何内置聚合的转移函数,但它的写法保证了在用作自定义聚合的转移函数时也能高效工作。) diff --git a/zh/19/xfunc.sgml b/zh/19/xfunc.sgml index e081ce71..b1eb2921 100644 --- a/zh/19/xfunc.sgml +++ b/zh/19/xfunc.sgml @@ -4,8 +4,8 @@ 用户定义的函数 - function - user-defined + 函数 + 用户定义的 @@ -36,15 +36,15 @@ - 每一类函数可以采用基本类型、复合类型或者它们的组合作为参数。此外,每一类函数可以返回一个基本类型或一个复合类型。函数也能被定义成返回基本类型或复合类型值的集合。 + 每一类函数可以采用基础类型、复合类型或者它们的组合作为参数。此外,每一类函数可以返回一个基础类型或一个复合类型。函数也能被定义成返回基础类型或复合类型值的集合。 - 很多类函数可以接受或者返回特定的伪类型(例如,多态类型),但是可用的功能会变化。详情可以参考每一种函数的描述。 + 很多类函数可以接受或者返回特定的伪类型(例如,多态类型),但是可用的功能因函数类别而异。详情可以参考每一种函数的描述。 - 定义SQL函数最容易,因此我们将从讨论SQL函数开始。大部分SQL函数的概念也能用到其他类型的函数上。 + 定义SQL函数最容易,因此我们将从讨论它们开始。大部分SQL函数的概念也能用到其他类型的函数上。 @@ -57,8 +57,8 @@ 用户定义的过程 - procedure - user-defined + 过程 + 用户定义的 @@ -101,7 +101,7 @@ - 函数和过程一起构成了例程routine。 + 函数和过程统称为例程例程。 有ALTER ROUTINEDROP ROUTINE这样的命令可以操作函数和过程而不需要知道它们是哪一种。 不过,要注意没有CREATE ROUTINE命令。 @@ -113,7 +113,7 @@ 函数 用户定义的 - in SQL + 在 SQL 中 @@ -139,7 +139,7 @@ DELETEMERGE),以及其他 SQL 命令。(在 SQL 函数中不能使用事务控制命令,例如 COMMITSAVEPOINT,也不能使用某些 - 实用命令,例如 VACUUM。)不过,最后一条命令必须是 + 工具命令,例如 VACUUM。)不过,最后一条命令必须是 SELECT,或者带有 RETURNING 子句,并返回与函数声明返回类型相符的结果。或者,如果你想定义一个执行动作 但没有有用返回值的 SQL 函数,也可以把它定义为返回 void。 @@ -171,7 +171,7 @@ CREATE PROCEDURE clean_emp() AS ' CALL clean_emp(); - 在像这样的简单情况中,函数与过程返回void的差异主要是风格上面的。 + 在像这样的简单情况中,返回void的函数与过程之间的差异主要是风格上面的。 不过,过程还提供了函数所没有的额外能力,例如事务控制。 此外,过程是 SQL 标准的一部分,而返回void则是 PostgreSQL 扩展。 @@ -226,10 +226,10 @@ INSERT INTO $1 VALUES (42); - 基本类型上的<acronym>SQL</acronym>函数 + 基础类型上的<acronym>SQL</acronym>函数 - 最简单的 SQL 函数没有参数,只是返回一个基本类型,例如 + 最简单的 SQL 函数没有参数,只是返回一个基础类型,例如 integer @@ -255,7 +255,7 @@ SELECT one(); - 定义接受基本类型参数的 SQL 函数也几乎同样容易: + 定义接受基础类型参数的 SQL 函数也几乎同样容易: CREATE FUNCTION add_em(x integer, y integer) RETURNS integer AS $$ @@ -393,17 +393,17 @@ SELECT name, double_salary(emp.*) AS dream 注意这里用 $1.salary 语法来选取参数行值中的一个字段。 还要注意,调用时的 SELECT 命令使用 - table_name.* 将表的当前整行取作一个组合值。该表行也可以仅用表名来引用: + table_name.* 将表的当前整行取作一个复合值。该表行也可以仅用表名来引用: SELECT name, double_salary(emp) AS dream FROM emp WHERE emp.cubicle ~= point '(2,1)'; - 但这种用法已被废弃,因为它很容易让人混淆(关于表行组合值这两种记法的更多细节,见)。 + 但这种用法已被弃用,因为它很容易让人混淆(关于表行复合值这两种记法的更多细节,见)。 - 有时候即时构造一个组合参数会很方便。这可以用ROW构造器完成。 + 有时候即时构造一个复合参数值会很方便。这可以用ROW构造器完成。 例如,我们可以调整被传递给函数的数据: SELECT name, double_salary(ROW(name, salary*1.1, age, cubicle)) AS dream @@ -432,7 +432,7 @@ $$ LANGUAGE SQL; - 查询中的选择列表顺序必须与列在复合类型中出现的顺序完全相同。(正如我们上面所做的那样,命名列与系统无关。) + 查询中的选择列表顺序必须与列在复合类型中出现的顺序完全相同。(系统不考虑像上面这样指定的列名。) @@ -444,7 +444,7 @@ ERROR: return type mismatch in function declared to return emp DETAIL: Final statement returns text instead of point at column 4. - 与基本类型的情况一样,系统不会自动插入显式转换,只会插入隐式或赋值转换。 + 与基础类型的情况一样,系统不会自动插入显式转换,只会插入隐式或赋值转换。 @@ -461,7 +461,7 @@ $$ LANGUAGE SQL; 这里我们写了一个只返回单列、且该列具有正确复合类型的 SELECT。 在这种场景下,这样写并不见得更好,但在某些情况下会很方便 - — 例如,需要通过调用另一个返回目标组合值的函数来计算结果时。 + — 例如,需要通过调用另一个返回目标复合值的函数来计算结果时。 还有一种情况是,如果我们要编写的函数返回的是基于复合类型的域,而不是普通复合类型, 那么就必须写成返回单列的形式,因为没有办法让整行结果发生所需的强制转换。 @@ -526,7 +526,7 @@ SELECT name(new_emp()); - 另一种使用函数返回复合类型的方法是将结果传递给另一个接受正确行类型作为输入的函数: + 另一种使用函数返回复合类型的方法是将结果传递给另一个接受正确行类型作为输入的函数: CREATE FUNCTION getname(emp) RETURNS text AS $$ @@ -614,7 +614,7 @@ DROP FUNCTION sum_n_product (int, int); <acronym>SQL</acronym>有输出参数的过程 - procedures + 过程 输出参数 @@ -636,7 +636,7 @@ $$ LANGUAGE SQL; CALL tp1(17, 100.0, NULL); 如果你写的是其他内容,它必须是一个能够像输入参数那样被隐式强制转换成该参数声明类型的表达式。 - 注意,无论如何这样的表达式不会被评估。 + 不过要注意,这样的表达式不会被求值。 @@ -648,12 +648,12 @@ CALL tp1(17, 100.0, NULL); 带有可变数量参数的<acronym>SQL</acronym>函数 - function - variadic + 函数 + 可变参数 - variadic function + 可变参数函数 @@ -684,27 +684,27 @@ SELECT mleast(ARRAY[10, -1, 5, 4.4]); -- doesn't work - 有时候,能够把一个已经构造好的数组传给 variadic 函数会很有用,尤其是当一个 variadic 函数想把它的数组参数再传给另一个函数时。此外,在允许不受信任用户创建对象的模式中调用 variadic 函数时,这是唯一安全的方式,见。你可以在调用中指定VARIADIC来做到这一点: + 有时候,能够把一个已经构造好的数组传给可变参数函数会很有用,尤其是当一个可变参数函数想把它的数组参数再传给另一个函数时。此外,在允许不受信任用户创建对象的模式中调用可变参数函数时,这是唯一安全的方式,见。你可以在调用中指定VARIADIC来做到这一点: SELECT mleast(VARIADIC ARRAY[10, -1, 5, 4.4]); - 这样会阻止函数的 variadic 参数按其元素类型展开,从而让数组实参能够按常规方式匹配。VARIADIC 只能附加在函数调用的最后一个实参上。 + 这样会阻止函数的可变参数按其元素类型展开,从而让数组实参能够按常规方式匹配。VARIADIC 只能附加在函数调用的最后一个实参上。 - 在调用中指定VARIADIC也是向 variadic 函数传递空数组的唯一方式,例如: + 在调用中指定VARIADIC也是向可变参数函数传递空数组的唯一方式,例如: SELECT mleast(VARIADIC ARRAY[]::numeric[]); - 仅仅写成SELECT mleast()是行不通的,因为 variadic 参数必须匹配至少一个实参。(如果你希望允许这种调用,可以再定义一个同名且不带参数的函数mleast。) + 仅仅写成SELECT mleast()是行不通的,因为可变参数必须匹配至少一个实参。(如果你希望允许这种调用,可以再定义一个同名且不带参数的函数mleast。) - 从 variadic 参数派生出的数组元素参数会被视为没有自己的名字。这意味着除非你指定了 VARIADIC,否则不能使用命名参数来调用 variadic 函数()。例如,下面的调用是可行的: + 从可变参数派生出的数组元素参数会被视为没有自己的名字。这意味着除非你指定了 VARIADIC,否则不能使用命名参数来调用可变参数函数()。例如,下面的调用是可行的: SELECT mleast(VARIADIC arr => ARRAY[10, -1, 5, 4.4]); @@ -723,7 +723,7 @@ SELECT mleast(arr => ARRAY[10, -1, 5, 4.4]); 带有参数默认值的<acronym>SQL</acronym>函数 - function + 函数 参数的默认值 @@ -732,7 +732,7 @@ SELECT mleast(arr => ARRAY[10, -1, 5, 4.4]); 没有给出足够多的实参,就会插入默认值来弥补缺失的实参。由于参数只 能从实参列表的尾部开始被省略,在一个有默认值的参数之后的所有参数 都不得不也具有默认值(尽管使用命名参数记法可以允许放松这种限制, - 这种限制仍然会被强制以便位置参数记法能工作)。不管你是否使用它,这种能力都要求在某些用户不信任其他用户的数据中调用函数时做一些预防措施,见。 + 这种限制仍然会被强制以便位置参数记法能工作)。不管你是否使用它,这种能力都要求在某些用户不信任其他用户的数据库中调用函数时做一些预防措施,见 @@ -775,13 +775,13 @@ ERROR: function foo() does not exist 所有的 SQL 函数都可以被用在查询的FROM子句中,但是 - 对于返回复合类型的函数特别有用。如果函数被定义为返回一种基本类型, + 对于返回复合类型的函数特别有用。如果函数被定义为返回一种基础类型, 该表函数会产生一个单列表。如果该函数被定义为返回一种复合类型,该 表函数会为该复合类型的每一个属性产生一列。 - 以下是一个示例: + 以下是一个示例: CREATE TABLE foo (fooid int, foosubid int, fooname text); @@ -814,8 +814,8 @@ SELECT *, upper(fooname) FROM getfoo(1) AS t1; 返回集合的<acronym>SQL</acronym>函数 - function - with SETOF + 函数 + 使用 SETOF @@ -948,7 +948,7 @@ SELECT x, generate_series(1,5) AS g FROM tab; SELECT x, g FROM tab, LATERAL generate_series(1,5) AS g; - 这会是完全一样的,除了在这个特别的示例中,规划器会选择把g放在嵌套循环连接的外侧,因为gtab没有实际的横向依赖。那会导致一种不同的输出行顺序。选择列表中的集合返回函数总是会被计算,就好像它们在FROM子句剩余部分的嵌套循环连接的内侧一样,因此在考虑来自FROM子句的下一行之前,这些函数会运行到完成。 + 这会是完全一样的,除了在这个特别的示例中,规划器可以选择把g放在嵌套循环连接的外侧,因为gtab没有实际的横向依赖。那会导致一种不同的输出行顺序。选择列表中的集合返回函数总是会被计算,就好像它们在FROM子句剩余部分的嵌套循环连接的内侧一样,因此在考虑来自FROM子句的下一行之前,这些函数会运行到完成。 @@ -968,7 +968,7 @@ SELECT srf1(srf2(x), srf3(y)), srf4(srf5(z)) FROM tab; SELECT x, CASE WHEN x > 0 THEN generate_series(1, 5) ELSE 0 END FROM tab; - 看起来这个语句应该产生满足x > 0的输入行的五次重复,以及不满足的行的一次重复。但实际上,由于在CASE表达时被计算前,generate_series(1, 5)会被运行在一个隐式的LATERAL FROM项中,它会为每个输入行产生五次重复。为了减少混乱,这类情况会产生一个解析时错误。 + 看起来这个语句应该产生满足x > 0的输入行的五次重复,以及不满足的行的一次重复。但实际上,由于在CASE表达式被计算前,generate_series(1, 5)会被运行在一个隐式的LATERAL FROM项中,它会为每个输入行产生五次重复。为了减少混乱,这类情况会产生一个解析时错误。 @@ -984,11 +984,11 @@ SELECT x, CASE WHEN x > 0 THEN generate_series(1, 5) ELSE 0 END FROM tab; 在 PostgreSQL 10 之前,除非多个集合返回函数始终产生相同数量的行,否则把它们放在同一个选择列表中的行为并不合理。 否则,得到的输出行数会是这些集合返回函数各自产生行数的最小公倍数。 此外,嵌套的集合返回函数也不像上文所描述的那样工作;相反,一个集合返回函数至多只能有一个集合返回参数, - 并且每一层嵌套都会独立运行。再加上过去还允许条件执行(即在 CASE 等结构内部使用集合返回函数), + 并且每一组嵌套的集合返回函数都会独立运行。再加上过去还允许条件执行(即在 CASE 等结构内部使用集合返回函数), 事情就更加复杂了。 如果你要编写需要在旧版 PostgreSQL 上运行的查询,建议使用 LATERAL 语法, 因为这样在不同版本之间能够得到一致的结果。 - 如果你的查询依赖于集合返回函数的条件执行,可以把条件判断移动到自定义集合返回函数内部来修复。例如, + 如果你的查询依赖于集合返回函数的条件执行,或许可以把条件判断移动到自定义集合返回函数内部来修复。例如, SELECT x, CASE WHEN y > 0 THEN generate_series(1, z) ELSE 5 END FROM tab; @@ -1006,7 +1006,7 @@ END$$ LANGUAGE plpgsql; SELECT x, case_generate_series(y > 0, 1, z, 5) FROM tab; - 这种写法在所有版本的 PostgreSQL 中都能正常工作。 + 这种写法在所有版本的 PostgreSQL 中的行为都相同。 @@ -1015,7 +1015,7 @@ SELECT x, case_generate_series(y > 0, 1, z, 5) FROM tab; 返回<literal>TABLE</literal>的<acronym>SQL</acronym>函数 - function + 函数 RETURNS TABLE @@ -1064,10 +1064,9 @@ SELECT make_array(1, 2) AS intarray, make_array('a'::text, 'b') AS textarray; 注意类型转换'a'::text的使用是为了指定该参数的类型 - 是text。如果该参数只是一个字符串这就是必须的,因为 + 是text。如果该参数只是一个字符串字面量,这就是必须的,因为 否则它会被当作unknown类型,并且 - unknown的数组也不是一种合法的类型。如果没有改类型 - 类型转换,将得到这样的错误: + unknown的数组也不是一种合法的类型。如果没有该类型转换,将得到这样的错误: ERROR: could not determine polymorphic type because input has type unknown @@ -1138,7 +1137,7 @@ SELECT * FROM dup(22); - 多态也可以用于 variadic 函数。例如: + 多态也可以用于可变参数函数。例如: CREATE FUNCTION anyleast (VARIADIC anyarray) RETURNS anyelement AS $$ SELECT min($1[i]) FROM generate_subscripts($1, 1) g(i); @@ -1173,14 +1172,14 @@ SELECT concat_values('|', 1, 4, 2); 带有排序规则的<acronym>SQL</acronym>函数 - collation - in SQL functions + 排序规则 + 在 SQL 函数中 - 当一个 SQL 函数有一个或多个可设定排序规则的数据类型参数时,会按 - 中的说明,为每次函数调用确定一个排序规则。 - 如果能够成功确定(也就是说,参数之间不存在隐式排序规则冲突),那么所有可设定排序规则的参数都会被视为隐式带有该排序规则。 + 当一个 SQL 函数有一个或多个支持排序规则的数据类型参数时,会按 + 中的说明,根据分配给实参的排序规则,为每次函数调用确定一个排序规则。 + 如果能够成功确定(也就是说,参数之间不存在隐式排序规则冲突),那么所有支持排序规则的参数都会被视为隐式带有该排序规则。 这会影响函数中对排序规则敏感的操作的行为。例如,使用上文的 anyleast 函数时, SELECT anyleast('abc'::text, 'ABC'); @@ -1200,7 +1199,7 @@ CREATE FUNCTION anyleast (VARIADIC anyarray) RETURNS anyelement AS $$ SELECT min($1[i] COLLATE "en_US") FROM generate_subscripts($1, 1) g(i); $$ LANGUAGE SQL; - 但请注意,如果把它用于不可设定排序规则的数据类型,就会抛出错误。 + 但请注意,如果把它用于不支持排序规则的数据类型,就会抛出错误。 @@ -1209,7 +1208,7 @@ $$ LANGUAGE SQL; - 这种可设定排序规则参数的行为,可以看作是仅适用于文本数据类型的一种受限多态形式。 + 这种支持排序规则的参数的行为,可以看作是仅适用于文本数据类型的一种受限多态形式。 @@ -1218,13 +1217,13 @@ $$ LANGUAGE SQL; 函数重载 - overloading - functions + 重载 + 函数 可以用同样的 SQL 名称定义多于一个函数,只要它们的参数不同即可。 - 换句话说,函数名可以被重载。不管你是否使用它,这种能力都要求在某些用户不信任其他用户的数据中调用函数时做一些预防措施,见。当一个查询 + 换句话说,函数名可以被重载。不管你是否使用它,这种能力都要求在某些用户不信任其他用户的数据库中调用函数时采取安全预防措施,见。当一个查询 被执行时,服务器将从数据类型和所提供的参数个数来决定要调用哪个 函数。重载也可用来模拟具有可变参数个数(最大个数有限)的函数。 @@ -1251,10 +1250,10 @@ CREATE FUNCTION test(smallint, double precision) RETURNS ... - 另一类可能的冲突发生在 variadic 函数和非 variadic 函数之间。例如,可以同时创建 + 另一类可能的冲突发生在可变参数函数和非可变参数函数之间。例如,可以同时创建 foo(numeric)foo(VARIADIC numeric[])。 这时,对于只提供一个 numeric 参数的调用(例如 foo(10.1)),就不清楚该匹配哪个函数。 - 规则是:优先使用在搜索路径中出现较早的那个函数;如果两者位于同一模式中,则优先使用非 variadic 函数。 + 规则是:优先使用在搜索路径中出现较早的那个函数;如果两者位于同一模式中,则优先使用非可变参数函数。 @@ -1281,8 +1280,8 @@ CREATE FUNCTION test(int, int) RETURNS int 函数易变性分类 - volatility - functions + 易变性 + 函数 VOLATILE @@ -1304,7 +1303,7 @@ CREATE FUNCTION test(int, int) RETURNS int 一个VOLATILE函数可以做任何事情,包括修改数据库。在 使用相同的参数连续调用时,它能返回不同的结果。优化器不会对这类函 - 数的行为做任何假定。对于在每一行都需要 volatile 函数值的查询,函数都会被重新求值。 + 数的行为做任何假定。使用易变函数的查询会在需要该函数值的每一行上重新对它求值。 @@ -1352,8 +1351,7 @@ CREATE FUNCTION test(int, int) RETURNS int 在考虑先规划然后立即执行的简单交互式查询时,在STABLEIMMUTABLE分类间的区别相对较小:一个函数是在规划时只 执行一次还是在查询执行开始期间只执行一次没有太大关系。但是如果计划 - 被保存下来然后在后面被重用,区别就大了。如果在不允许过早把一个函数 - 变成规划期间的一个常数时把它标记为IMMUTABLE,会导致 + 被保存下来然后在后面被重用,区别就大了。如果把一个实际上并非不可变的函数标记为IMMUTABLE,就可能在规划期间过早将它折叠成常量,导致 在后续重用该计划时继续使用陈旧的值。在使用预备语句,或使用会缓存执行计划的函数语言(如 PL/pgSQL)时,这会带来严重问题。 @@ -1421,7 +1419,7 @@ CREATE FUNCTION test(int, int) RETURNS int 内部函数 - functioninternal + 函数内部 内部函数由 C 编写并且已经被静态链接到PostgreSQL @@ -1459,9 +1457,9 @@ CREATE FUNCTION square_root(double precision) RETURNS double precision C 语言函数 - function - user-defined - in C + 函数 + 用户定义的 + 在 C 中 @@ -1485,17 +1483,17 @@ CREATE FUNCTION square_root(double precision) RETURNS double precision - 在一个会话中第一次调用一个特定可载入对象文件中的用户定义函数时, - 动态载入器会把那个对象文件载入到内存以便该函数被调用。因此用户 + 在一个会话中第一次调用一个特定可载入目标文件中的用户定义函数时, + 动态载入器会把那个目标文件载入到内存以便该函数被调用。因此用户 定义的 C 函数的CREATE FUNCTION必须 - 为该函数指定两块信息:可载入对象文件的名称,以及要在该对象文件中 + 为该函数指定两块信息:可载入目标文件的名称,以及要在该目标文件中 调用的特定函数的 C 名称(链接符号)。如果没有显式指定 C 名称,则 它被假定为和 SQL 函数名相同。 下面的算法被用来基于CREATE FUNCTION - 命令中给定的名称来定位共享对象文件: + 命令中给定的名称来定位共享目标文件: @@ -1554,20 +1552,20 @@ CREATE FUNCTION square_root(double precision) RETURNS double precision PostgreSQL不会自动编译 C 函数。在 - 从CREATE FUNCTION命令中引用对象文件 + 从CREATE FUNCTION命令中引用目标文件 之前,它必须先被编译好。更多信息请见 - magic block + 魔数块 PG_MODULE_MAGIC - 为确保动态装载的对象文件不会被加载到不兼容的服务器中,PostgreSQL 会检查该文件是否包含内容正确的magic block。这样服务器就能检测出明显的不兼容情况,例如代码是针对另一个 PostgreSQL 主版本编译的。要加入 magic block,请在模块某一个(且只能一个)源文件中,在包含头文件 fmgr.h 之后写入: + 为确保动态装载的目标文件不会被加载到不兼容的服务器中,PostgreSQL 会检查该文件是否包含内容正确的魔数块。这样服务器就能检测出明显的不兼容情况,例如代码是针对另一个 PostgreSQL 主版本编译的。要加入魔数块,请在模块某一个(且只能一个)源文件中,在包含头文件 fmgr.h 之后写入: PG_MODULE_MAGIC; @@ -1592,9 +1590,9 @@ PG_MODULE_MAGIC_EXT( - 在第一次使用之后,动态载入对象文件会保留在内存中。在同一个会话中, + 在第一次使用之后,动态载入目标文件会保留在内存中。在同一个会话中, 后续对该文件中函数的调用只需付出一次很小的符号表查找开销。如果需要 - 强制重新载入一个对象文件(例如在重新编译之后),就需要开启一个新的会话。 + 强制重新载入一个目标文件(例如在重新编译之后),就需要开启一个新的会话。 @@ -1613,7 +1611,7 @@ PG_MODULE_MAGIC_EXT( - C 语言函数中的基本类型 + C 语言函数中的基础类型 数据类型 @@ -1622,16 +1620,16 @@ PG_MODULE_MAGIC_EXT( 要了解如何编写 C 语言函数,你需要了解 - PostgreSQL如何在内部表达基本数据类型 + PostgreSQL如何在内部表达基础类型 以及如何与函数传递它们。在内部, - PostgreSQL把基本类型视为一块内存数据块。 + PostgreSQL把基础类型视为一块内存数据块。 你为该类型定义的用户自定义函数,决定了 PostgreSQL 如何操作它。 也就是说,PostgreSQL 只负责把数据存到磁盘、再从磁盘取回, 而数据的输入、处理和输出则依赖你定义的这些函数。 - 基本类型可以有三种内部格式之一: + 基础类型可以有三种内部格式之一: @@ -1695,10 +1693,9 @@ typedef struct 最后,所有变长类型必须也以引用的方式传递。所有变长类型必须用一个 - 正好 4 字节的不透明长度域开始,该域会由SET_VARSIZE - 设置,绝不要直接设置该域!所有要被存储在该类型中的数据必须在内存 - 中接着该长度域的后面存储。长度域包含该结构体的总长度,也就是包括长 - 度域本身的尺寸。 + 正好 4 字节的不透明长度字段开始,该字段会由SET_VARSIZE + 设置,绝不要直接设置该字段!所有要被存储在该类型中的数据必须在内存 + 中接着该长度字段的后面存储。长度字段包含该结构体的总长度,也就是包括长度字段本身的尺寸。 @@ -1748,16 +1745,16 @@ memcpy(destination->data, buffer, 40); VARHDRSZsizeof(int32)一样, - 但是用宏VARHDRSZ来引用变长类型的载荷的 + 但是用宏VARHDRSZ来引用变长类型的额外开销的 尺寸被认为是比较好的风格。还有,必须 - 使用SET_VARSIZE函数来设置长度域,而不是用 + 使用SET_VARSIZE函数来设置长度字段,而不是用 简单的赋值来设置。 展示了 PostgreSQL 中许多内置 SQL 数据类型所对应的 C 类型。 - Defined In列给出了需要包含的头文件,以获取类型定义。 + 定义文件列给出了需要包含的头文件,以获取类型定义。 (实际的定义可能位于所列文件包含的其他文件中。建议用户坚持使用已定义的接口。) 请注意,在服务器代码的任何源文件中,都应该始终首先包含postgres.h, 因为它声明了很多你反正都会用到的内容,而且先包含其他头文件可能会带来可移植性问题。 @@ -1933,8 +1930,7 @@ memcpy(destination->data, buffer, 40);
- 现在我们已经复习了基本类型所有可能的结构,现在可以展示一些 - 真实函数的示例了。 + 了解了基础类型所有可能的结构后,就可以看一些实际函数示例。
@@ -1942,7 +1938,7 @@ memcpy(destination->data, buffer, 40); 版本 1 的调用约定 - 版本-1 的调用规范依赖于宏来降低传参数和结果的复杂度。版本-1 函数的 + 版本-1 的调用约定依赖于宏来降低传参数和结果的复杂度。版本-1 函数的 C 声明总是: Datum funcname(PG_FUNCTION_ARGS) @@ -1954,11 +1950,11 @@ PG_FUNCTION_INFO_V1(funcname); 必须出现在同一个源文件中(按惯例会正好写在该函数本身之前)。 这种宏调用不是internal语言函数所需要的,因为 PostgreSQL会假定所有内部函数都使用 - 版本-1 规范。不过,对于动态载入函数是必需的。 + 版本-1 调用约定。不过,对于动态载入函数是必需的。 - 在版本-1 函数中,每一个实参都使用对应于该参数数据类型的PG_GETARG_xxx()宏取得。(在非严格的函数中,需要使用PG_ARGISNULL()对参数是否为空提前做检查;见下文。)结果要用对应于返回类型的PG_RETURN_xxx()宏返回。PG_GETARG_xxx()的参数是要取得的函数参数的编号,从零开始计。PG_RETURN_xxx()的参数是实际要返回的值。 + 在版本-1 函数中,每一个实参都使用对应于该参数数据类型的PG_GETARG_xxx()宏取得。(在非严格的函数中,需要使用PG_ARGISNULL()对参数是否为空值提前做检查;见下文。)结果要用对应于返回类型的PG_RETURN_xxx()宏返回。PG_GETARG_xxx()的参数是要取得的函数参数的编号,从零开始计。PG_RETURN_xxx()的参数是实际要返回的值。 @@ -2141,11 +2137,11 @@ CREATE FUNCTION t_starts_with(text, text) RETURNS boolean - 注意我们已经把函数指定为strict,这意味着如果有任何输入值为空,系统应该自动假定得到空结果。通过这种做法,我们避免在函数代码中检查空值输入。如果不这样做,我们必须使用PG_ARGISNULL()明确地检查空值输入。 + 注意我们已经把函数指定为strict,这意味着如果有任何输入值为空值,系统应该自动假定结果为空值。通过这种做法,我们避免在函数代码中检查空值输入。如果不这样做,我们必须使用PG_ARGISNULL()明确地检查空值输入。 - 宏PG_ARGISNULL(n)允许一个函数测试是否每一个输入为空(当然,只需要在没有声明为strict的函数中这样做)。和PG_GETARG_xxx()宏一样,输入参数也是从零开始计数。注意应该在验证了一个参数不是空之后才执行PG_GETARG_xxx()。要返回一个空结果,应执行PG_RETURN_NULL(),它对严格的以及非严格的函数都有用。 + 宏PG_ARGISNULL(n)允许一个函数测试是否每一个输入为空值(当然,只需要在没有声明为strict的函数中这样做)。和PG_GETARG_xxx()宏一样,输入参数也是从零开始计数。注意应该在验证了一个参数不是空值之后才执行PG_GETARG_xxx()。要返回空值结果,应执行PG_RETURN_NULL(),它对严格的以及非严格的函数都有用。 @@ -2153,11 +2149,11 @@ CREATE FUNCTION t_starts_with(text, text) RETURNS boolean - 在版本-1接口中提供的其他选项是PG_GETARG_xxx()宏的两个变种。其中的第一种是PG_GETARG_xxx_COPY(),它确保返回的指定参数的拷贝可以被安全地写入(通常的宏有时会返回一个指向表中物理存储的值,它不能被写入。使用PG_GETARG_xxx_COPY()宏可以保证得到一个可写的结果)。第二种变种PG_GETARG_xxx_SLICE()宏有三个参数。第一个是函数参数的编号(如上文)。第二个和第三个是要被返回的段的偏移量和长度。偏移量从零开始计算,而负值的长度则表示要求返回该值的剩余部分。当大型值的存储类型为external时,这些宏提供了访问这些大型值的更有效的方法(列的存储类型可以使用ALTER TABLE tablename ALTER COLUMN colname SET STORAGE storagetype来指定。storagetypeplainexternalextended或者main)。 + 在版本-1接口中提供的其他选项是PG_GETARG_xxx()宏的两个变种。其中的第一种是PG_GETARG_xxx_COPY(),它确保返回的指定参数的拷贝可以被安全地写入(通常的宏有时会返回一个指向表中物理存储值的指针,不能写入该值。使用PG_GETARG_xxx_COPY()宏可以保证得到一个可写的结果)。第二种变种PG_GETARG_xxx_SLICE()宏有三个参数。第一个是函数参数的编号(如上文)。第二个和第三个是要被返回的段的偏移量和长度。偏移量从零开始计算,而负值的长度则表示要求返回该值的剩余部分。当大型值的存储类型为external时,这些宏提供了访问这些大型值的部分内容的更有效方法(列的存储类型可以使用ALTER TABLE tablename ALTER COLUMN colname SET STORAGE storagetype来指定。storagetypeplainexternalextended或者main)。 - 最后,版本-1 的函数调用规范可以返回集合结果()、实现触发器函数()和过程语言调用处理器()。更多细节 + 最后,版本-1 的函数调用约定可以返回集合结果()、实现触发器函数()和过程语言调用处理器()。更多细节 可见源代码发布中的src/backend/utils/fmgr/README
@@ -2168,10 +2164,10 @@ CREATE FUNCTION t_starts_with(text, text) RETURNS boolean 在开始更高级的话题之前,我们应该讨论一下用于 PostgreSQL C 语言函数的编码规则。 - 虽然可以把不是 C 编写的函数载入到 - PostgreSQL中,这通常是很困难的, + 虽然有可能把不是 C 编写的函数载入到 + PostgreSQL中,但即使能够做到,通常也很困难, 因为其他语言(例如 C++、FORTRAN 或者 Pascal)通常不会遵循和 C - 相同的调用规范。也就是说,其他语言不会以同样的方式在函数之间传递 + 相同的调用约定。也就是说,其他语言不会以同样的方式在函数之间传递 参数以及返回值。由于这个原因,我们会假定你的 C 语言函数确实是用 C 编写的。 @@ -2183,7 +2179,7 @@ CREATE FUNCTION t_starts_with(text, text) RETURNS boolean 使用 pg_config - --includedir-serverpg_configwith user-defined C functions + --includedir-serverpg_config用于用户定义的 C 函数 查出 PostgreSQL 服务器头文件在你的系统上(或你的用户将要运行的系统上)安装于何处。 @@ -2196,7 +2192,7 @@ CREATE FUNCTION t_starts_with(text, text) RETURNS boolean - 记得按照中的说明,为你的共享库定义一个magic block。 + 记得按照中的说明,为你的共享库定义一个魔数块 @@ -2222,7 +2218,7 @@ CREATE FUNCTION t_starts_with(text, text) RETURNS boolean - 对象文件中定义的符号名不能彼此冲突,也不能与 + 目标文件中定义的符号名不能彼此冲突,也不能与 PostgreSQL 服务器可执行文件中定义的符号冲突。如果你收到这类错误消息,就必须重命名相关函数或变量。 @@ -2305,7 +2301,7 @@ CREATE FUNCTION t_starts_with(text, text) RETURNS boolean - 但请注意,服务器中有很多部分并不是作为公开可消费的 API 来设计和维护的(而且在大多数情况下,其真实边界也并不清晰)。如果这些部分出现紧急需求,对它们的修改自然会比对那些边界清楚且广泛使用的接口做修改时,更少考虑扩展代码的兼容性。 + 但请注意,服务器中有很多部分并不是作为可公开使用的 API 来设计和维护的(而且在大多数情况下,其真实边界也并不清晰)。如果这些部分出现紧急需求,对它们的修改自然会比对那些边界清楚且广泛使用的接口做修改时,更少考虑扩展代码的兼容性。 @@ -2321,10 +2317,10 @@ CREATE FUNCTION t_starts_with(text, text) RETURNS boolean 复合类型没有像 C 结构体那样的固定布局。复合类型的实例可能包含 - 空值域。此外,继承层次中的复合类型可能具有和同一继承层次中 - 其他成员不同的域。因此, + 空值字段。此外,继承层次中的复合类型可能具有和同一继承层次中 + 其他成员不同的字段。因此, PostgreSQL提供了函数接口 - 来访问 C 的复合类型的域。 + 以便从 C 访问复合类型的字段。 @@ -2336,7 +2332,7 @@ SELECT name, c_overpaid(emp, 1500) AS overpaid WHERE name = 'Bill' OR name = 'Sam'; - 如果使用版本-1的调用规范,我们可以定义 + 如果使用版本-1的调用约定,我们可以定义 c_overpaid为: 也有GetAttributeByNum函数,它可以用目标属性 - 的属性号而不是属性名来选择目标属性。 + 的列号而不是属性名来选择目标属性。 @@ -2395,14 +2391,14 @@ CREATE FUNCTION c_overpaid(emp, integer) RETURNS boolean 要从 C 语言函数中返回一行或一个复合类型值,可以使用一套特殊的 API, - 它通过一组宏和函数隐藏了构造组合数据类型时的大部分复杂性。要使用这套 API,源文件中必须包含: + 它通过一组宏和函数隐藏了构造复合数据类型时的大部分复杂性。要使用这套 API,源文件中必须包含: #include "funcapi.h" - 构造组合数据值(下文简称元组)有两种方式: + 构造复合数据值(下文简称元组)有两种方式: 一种是从 Datum 值数组构造,另一种是从 C 字符串数组构造,这些字符串会传给该元组各列数据类型的输入转换函数。 无论采用哪种方式,首先都需要获取或构造描述该元组结构的 TupleDesc。 处理 Datum 时,需要把 TupleDesc 传给 BlessTupleDesc,然后为每一行调用 heap_form_tuple。 @@ -2411,13 +2407,13 @@ CREATE FUNCTION c_overpaid(emp, integer) RETURNS boolean - 有一些辅助函数可以用来设置所需的 TupleDesc。在大多数返回组合值的函数中,推荐的做法是调用: + 有一些辅助函数可以用来设置所需的 TupleDesc。在大多数返回复合值的函数中,推荐的做法是调用: TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc) - 传入与调用函数本身相同的 fcinfo 结构体(这当然要求使用版本 1 调用约定)。 + 传入调用函数本身收到的同一个 fcinfo 结构体(这当然要求使用版本 1 调用约定)。 resultTypeId 可以指定为 NULL,也可以指定为一个本地变量的地址,用于接收函数结果类型的 OID。 resultTupleDesc 应当是一个本地 TupleDesc 变量的地址。 检查返回结果是否为 TYPEFUNC_COMPOSITE;如果是,resultTupleDesc 就会被填入所需的 TupleDesc。 @@ -2436,7 +2432,7 @@ TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, get_call_result_type有一个兄弟 get_expr_result_type,它被用来解析被表示为一棵表达式 - 树的函数调用的输出类型。在尝试确定来自函数外部的结果类型时可以用它。 + 树的函数调用的输出类型。在尝试从函数自身外部确定结果类型时可以用它。 也有一个get_func_result_type,当只有函数的 OID 可用时 可以用它。不过这些函数无法处理被声明为返回record的 函数,并且get_func_result_type无法解析多态类型,因此你 @@ -2445,22 +2441,22 @@ TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, - 更早、现在已被废弃的获取TupleDesc的函数有: + 更早、现在已被弃用的获取TupleDesc的函数有: TupleDesc RelationNameGetTupleDesc(const char *relname) - 它可以为一个提到的关系的行类型得到TupleDesc, + 它可以为一个指定名称的关系的行类型得到TupleDesc, 还有: TupleDesc TypeGetTupleDesc(Oid typeoid, List *colaliases) 可以基于一个类型 OID 得到TupleDesc。这可以被用来 - 为一种基础或者复合类型获得TupleDesc。不过,对于 + 为一种基本或者复合类型获得TupleDesc。不过,对于 返回record的函数它不起作用,并且它无法解析多态类型。 - 一旦有了一个TupleDesc,如果计划处理 Datum可以调用: + 一旦有了一个TupleDesc,如果计划处理 Datum,可以调用: TupleDesc BlessTupleDesc(TupleDesc tupdesc) @@ -2470,7 +2466,7 @@ AttInMetadata *TupleDescGetAttInMetadata(TupleDesc tupdesc) 如果正在编写一个返回集合的函数,你可以把这些函数的结果保存在 FuncCallContext结构体中 — 分别使用 - tuple_desc或者attinmeta域。 + tuple_desc或者attinmeta字段。 @@ -2490,8 +2486,7 @@ HeapTuple BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values) values是一个 C 字符串数组,每一个元素是返回行 的一个属性。每一个 C 字符串应该是该属性数据类型的输入函数所期望 的格式。为了对一个属性返回空值,values数组中对 - 应的指针应该被设置为NULL。对于你返回的每一行都将 - 再次调用这个函数。 + 应的指针应该被设置为NULL。对于你返回的每一行都需要再次调用这个函数。 @@ -2526,13 +2521,13 @@ HeapTupleGetDatum(HeapTuple tuple) 使用 ValuePerCall 模式时,重要的是要记住查询不能保证运行完成; 也就是说,由于诸如LIMIT之类的选项, - 执行程序可能会在获取所有行之前停止调用 set-returning 函数。 + 执行器可能会在获取所有行之前停止调用集合返回函数。 这意味着在最后一次调用中执行清理活动是不安全的,因为这可能永远不会发生。 对于需要访问外部资源(例如文件描述符)的函数,建议使用 Materialize 模式。 - 本节的其余部分记录了一组使用 ValuePerCall 模式的 SRF 常用(尽管不是必须使用)的帮助程序宏。 + 本节的其余部分记录了一组使用 ValuePerCall 模式的 SRF 常用(尽管不是必须使用)的辅助宏。 有关 Materialize 模式的其他详细信息可以在src/backend/utils/fmgr/README中找到。 此外,PostgreSQL源代码分发中的contrib 模块包含许多使用 ValuePerCall 和 Materialize 模式的 SRF 示例。 @@ -2541,7 +2536,7 @@ HeapTupleGetDatum(HeapTuple tuple) 要使用此处描述的 ValuePerCall 支持宏,请包含funcapi.h。 这些宏与结构体FuncCallContext一起使用,该结构体包含需要跨调用保存的状态。 - 在调用 SRF 中,fcinfo->flinfo->fn_extra用于在调用之间保存 + 在使用这些宏的 SRF 中,fcinfo->flinfo->fn_extra用于在调用之间保存 指向FuncCallContext的指针。 宏在第一次使用时自动填充该字段,并期望在后续使用中找到相同的指针。 @@ -2574,7 +2569,7 @@ typedef struct FuncCallContext /* * 可选:指向包含属性类型输入元数据的结构的指针 * - * attinmeta 被用在返回元组(即组合数据类型)时,在返回基本数据类型 + * attinmeta 被用在返回元组(即复合数据类型)时,在返回基础类型 * 时不会使用。只有想用BuildTupleFromCStrings()创建返回元组时才需要它。 */ AttInMetadata *attinmeta; @@ -2591,7 +2586,7 @@ typedef struct FuncCallContext /* * 可选:指向包含元组描述的结构的指针 * - * tuple_desc 被用在返回元组(即组合数据类型)时,并且只有在用 + * tuple_desc 被用在返回元组(即复合数据类型)时,并且只有在用 * heap_form_tuple() 而不是 BuildTupleFromCStrings() 构建元组时才需要它。 * 注意这里存储的 TupleDesc 指针通常已经被先运行过 BlessTupleDesc()。 */ @@ -2695,7 +2690,7 @@ my_set_returning_function(PG_FUNCTION_ARGS) else { /* 这里已经完成了项的返回,所以只报告事实。 */ - /* (不要将清理代码放在这里的。) */ + /* (不要将清理代码放在这里。) */ SRF_RETURN_DONE(funcctx); } } @@ -2775,7 +2770,7 @@ retcomposite(PG_FUNCTION_ARGS) /* 构建一个元组 */ tuple = BuildTupleFromCStrings(attinmeta, values); - /* 将元组转换为数据 */ + /* 将元组转换为 datum */ result = HeapTupleGetDatum(tuple); /* 清理(这实际上并不是必要的) */ @@ -2831,10 +2826,10 @@ CREATE OR REPLACE FUNCTION retcomposite(IN integer, IN integer, fcinfo->flinfo访问。参数argnum则是从零 开始计。get_call_result_type也可被用作 get_fn_expr_rettype的一种替代品。还有 - get_fn_expr_variadic,它可以被用来找出 variadic 参数 + get_fn_expr_variadic,它可以被用来找出可变参数 是否已经被合并到了一个数组中。这主要用于 VARIADIC "any"函数,因为对于接收普通数组类型的 - variadic 函数来说总是会发生这类合并。 + 可变参数函数来说总是会发生这类合并。 @@ -2902,7 +2897,7 @@ CREATE FUNCTION make_array(anyelement) RETURNS anyarray 它与 anyelement 类似,但不会要求不同的 "any" 参数必须是同一种类型,也不会帮助确定函数的结果类型。 C 语言函数还可以把最后一个参数声明为 VARIADIC "any"。 这可以匹配一个或多个任意类型的实参(不必是同一种类型)。 - 这些参数不会像普通 variadic 函数那样被收集成一个数组,而是会单独传给函数。 + 这些参数不会像普通可变参数函数那样被收集成一个数组,而是会单独传给函数。 使用这种特性时,必须结合 PG_NARGS() 宏以及前面介绍的方法来确定实参的个数和类型。 此外,这种函数的用户也可能希望在函数调用中使用 VARIADIC 关键字,以便让函数把数组元素当作独立参数处理。 如果希望支持这种行为,函数本身就必须在使用 get_fn_expr_variadic 检测到实参被标记为 VARIADIC 后自行实现它。 @@ -3309,9 +3304,9 @@ extern PgStat_Kind pgstat_register_kind(PgStat_Kind kind, - 如果从 C++ 代码调用后端函数,确定 C++ 调用栈值包含传统 C 风格 + 如果从 C++ 代码调用后端函数,确定 C++ 调用栈只包含传统 C 风格 的数据结构(POD)。这是必要的,因为后端错误会 - 产生远距离的longjmp(),它无法正确的退回具有非 + 产生远距离的longjmp(),它无法正确地展开具有非 POD 对象的 C++ 调用栈。 @@ -3330,8 +3325,8 @@ extern PgStat_Kind pgstat_register_kind(PgStat_Kind kind, 函数优化信息 - optimization information - for functions + 优化信息 + 用于函数 @@ -3371,7 +3366,7 @@ supportfn(internal) returns internal - 对于返回 boolean 的目标函数,估计使用该函数的 WHERE 子句会筛选出多少行通常很有用。这可以通过实现 SupportRequestSelectivity 请求类型的支持函数来完成。 + 对于返回 boolean 的目标函数,估计使用该函数的 WHERE 子句筛选出的行所占的比例通常很有用。这可以通过实现 SupportRequestSelectivity 请求类型的支持函数来完成。 diff --git a/zh/19/xindex.sgml b/zh/19/xindex.sgml index 425c94d8..112b38c4 100644 --- a/zh/19/xindex.sgml +++ b/zh/19/xindex.sgml @@ -4,8 +4,8 @@ 索引扩展接口 - index - for user-defined data type + 索引 + 用于用户定义的数据类型 @@ -27,7 +27,7 @@ - 索引方法的例程并不直接知道它将处理哪些数据类型。相反,一个操作符类operator class标识了索引方法在处理特定数据类型时需要使用的那组操作。之所以称为操作符类,是因为它指定的一项内容就是可与索引一起使用的 WHERE 子句操作符集合(也就是能被转换成索引扫描条件的操作符)。操作符类还可以指定索引方法内部操作所需的一些支持函数,但这些函数并不直接对应任何可与索引一起使用的 WHERE 子句操作符。 + 索引方法的例程并不直接知道它将处理哪些数据类型。相反,一个操作符类操作符类标识了索引方法在处理特定数据类型时需要使用的那组操作。之所以称为操作符类,是因为它指定的一项内容就是可与索引一起使用的 WHERE 子句操作符集合(也就是能被转换成索引扫描条件的操作符)。操作符类还可以指定索引方法内部操作所需的一些支持函数,但这些函数并不直接对应任何可与索引一起使用的 WHERE 子句操作符。 @@ -355,7 +355,7 @@ - 返回可由 C 调用的 skip 支持函数地址(可选) + 返回可由 C 调用的跳跃支持函数地址(可选) 6 @@ -385,7 +385,7 @@ - 给定一个 64 位 salt,计算一个键的 64 位哈希值;如果 salt 为 0,结果的低 32 位必须与函数 1 计算出的值一致(可选) + 给定一个 64 位盐值,计算一个键的 64 位哈希值;如果盐值为 0,结果的低 32 位必须与函数 1 计算出的值一致(可选) 2 @@ -558,7 +558,7 @@ compare - 比较两个键,并返回一个小于零、等于零或大于零的整数,以表示第一个键是小于、等于还是大于第二个键 + 比较两个键,并返回一个小于零、等于零或大于零的整数,用以表示第一个键是小于、等于还是大于第二个键 1 @@ -732,7 +732,7 @@ CREATE OPERATOR < ( restrict = scalarltsel, join = scalarltjoinsel ); - 指定正确的交换子和求反器操作符很重要,同样也要指定合适的限制选择度函数和连接选择度函数,否则优化器将无法有效地利用索引。 + 指定正确的交换子和求反器操作符很重要,同样也要指定合适的限制选择率函数和连接选择率函数,否则优化器将无法有效地利用索引。 @@ -811,7 +811,7 @@ CREATE OPERATOR CLASS complex_abs_ops - 为了满足这些需求,PostgreSQL使用操作符族operator family这一概念。一个操作符族包含一个或多个操作符类,还可以包含属于整个族、但不属于族中任何单一类的可索引操作符及其相应的支持函数。我们称这样的操作符和函数在该族中是松散的,而不是绑定在某个特定类中。通常,每个操作符类只包含单一数据类型的操作符,而跨数据类型操作符则作为操作符族中的松散成员存在。 + 为了满足这些需求,PostgreSQL使用操作符族操作符族这一概念。一个操作符族包含一个或多个操作符类,还可以包含属于整个族、但不属于族中任何单一类的可索引操作符及其相应的支持函数。我们称这样的操作符和函数在该族中是松散的,而不是绑定在某个特定类中。通常,每个操作符类只包含单一数据类型的操作符,而跨数据类型操作符则作为操作符族中的松散成员存在。 @@ -931,7 +931,7 @@ ALTER OPERATOR FAMILY integer_ops USING btree ADD - 要构建一个多数据类型的哈希操作符族,必须为该族支持的每一种数据类型创建相互兼容的哈希支持函数。这里的兼容性是指:对任意两个被该族中的等值操作符视为相等的值,这些函数都保证返回相同的哈希码,即使这两个值属于不同类型也是如此。当这些类型具有不同的物理表示时,这通常难以实现,但在某些情况下可以做到。此外,将该操作符族中一种数据类型的值通过隐式或二进制强制转换转换成该族中另一种数据类型时,不应改变所计算出的哈希值。注意,每种数据类型只有一个支持函数,而不是每个等值操作符一个。建议让操作符族保持完整,也就是说,对每一种数据类型组合都提供一个等值操作符。每个操作符类只应包含其数据类型对应的非跨数据类型等值操作符和支持函数。 + 要构建一个多数据类型的哈希操作符族,必须为该族支持的每一种数据类型创建相互兼容的哈希支持函数。这里的兼容性是指:对任意两个被该族中的等值操作符视为相等的值,这些函数都保证返回相同的哈希码,即使这两个值属于不同类型也是如此。当这些类型具有不同的物理表示时,这通常难以实现,但在某些情况下可以做到。此外,将该操作符族中一种数据类型的值通过隐式或二进制强制转换转为该族中另一种数据类型时,不得改变所计算出的哈希值。注意,每种数据类型只有一个支持函数,而不是每个等值操作符一个。建议让操作符族保持完整,也就是说,对每一种数据类型组合都提供一个等值操作符。每个操作符类只应包含其数据类型对应的非跨数据类型等值操作符和支持函数。 @@ -944,7 +944,7 @@ ALTER OPERATOR FAMILY integer_ops USING btree ADD - 在 PostgreSQL 8.3 之前,并没有操作符族这一概念,因此任何打算与索引一起使用的跨数据类型操作符都必须直接绑定到该索引的操作符类中。虽然这种做法仍然有效,但已经废弃,因为它会使索引的依赖关系过于宽泛,而且当两种数据类型都在同一操作符族中拥有操作符时,规划器能更有效地处理跨数据类型比较。 + 在 PostgreSQL 8.3 之前,并没有操作符族这一概念,因此任何打算与索引一起使用的跨数据类型操作符都必须直接绑定到该索引的操作符类中。虽然这种做法仍然有效,但已被弃用,因为它会使索引的依赖关系过于宽泛,而且当两种数据类型都在同一操作符族中拥有操作符时,规划器能更有效地处理跨数据类型比较。 @@ -953,7 +953,7 @@ ALTER OPERATOR FAMILY integer_ops USING btree ADD 系统对操作符类的依赖 - ordering operator + 排序操作符 @@ -961,7 +961,7 @@ ALTER OPERATOR FAMILY integer_ops USING btree ADD - 特别地,ORDER BYDISTINCT等 SQL 特性要求对值的比较和排序。为了在用户定义的数据类型上实现这些特性,PostgreSQL会为数据类型查找默认 B-树操作符类。这个操作符类的equals成员定义了用于GROUP BYDISTINCT的值的等值概念,而该操作符类施加的排序顺序定义了默认的ORDER BY顺序。 + 特别地,ORDER BYDISTINCT等 SQL 特性要求对值的比较和排序。为了在用户定义的数据类型上实现这些特性,PostgreSQL会为数据类型查找默认 B-树操作符类。这个操作符类的相等成员定义了用于GROUP BYDISTINCT的值的等值概念,而该操作符类施加的排序顺序定义了默认的ORDER BY顺序。 @@ -987,11 +987,11 @@ SELECT * FROM mytable ORDER BY somecol USING ~<~; - 用户定义类型的数组比较也依赖于该类型默认 B-树操作符类所定义的语义。如果没有默认 B-树操作符类,但有默认的哈希操作符类,则支持数组相等比较,但不支持顺序比较。 + 用户定义类型的数组比较也依赖于该类型默认 B-树操作符类所定义的语义。如果没有默认 B-树操作符类,但有默认的哈希操作符类,则支持数组相等比较,但不支持排序比较。 - 另一种需要更多数据类型相关知识的 SQL 特性,是窗口函数中的 RANGE offset PRECEDING/FOLLOWING 框架选项(见)。对于下面这样的查询 + 另一种需要更多数据类型相关知识的 SQL 特性,是窗口函数中的 RANGE offset PRECEDING/FOLLOWING 帧选项(见)。对于下面这样的查询 SELECT sum(x) OVER (ORDER BY x RANGE BETWEEN 5 PRECEDING AND 10 FOLLOWING) FROM mytable; @@ -1026,7 +1026,7 @@ SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10; - 搜索操作符必须返回布尔结果,而排序操作符通常返回其他类型的结果,例如表示距离的浮点数或数值。这种类型通常不同于被索引的数据类型。为了避免对不同数据类型行为作硬编码假设,在定义排序操作符时,必须指定一个 B-树操作符族,用来说明结果数据类型的排序顺序。正如上一节所述,B-树操作符族定义了 PostgreSQL 的顺序概念,因此这是一种自然的表示方式。由于点的 <-> 操作符返回 float8,因此可以在创建操作符类时这样指定它: + 搜索操作符必须返回布尔结果,而排序操作符通常返回其他类型的结果,例如用于表示距离的 float 或 numeric。这种类型通常不同于被索引的数据类型。为了避免对不同数据类型行为作硬编码假设,在定义排序操作符时,必须指定一个 B-树操作符族,用来说明结果数据类型的排序顺序。正如上一节所述,B-树操作符族定义了 PostgreSQL 的顺序概念,因此这是一种自然的表示方式。由于点的 <-> 操作符返回 float8,因此可以在创建操作符类时这样指定它: (point, point) FOR ORDER BY float_ops ]]> @@ -1039,7 +1039,7 @@ OPERATOR 15 <-> (point, point) FOR ORDER BY float_ops 操作符类的特殊特性 - 还有两个操作符类的特殊特性我们尚未讨论,主要是因为它们对最常用的索引方法并不太有用。 + 还有两个操作符类的特殊特性我们尚未讨论,主要是因为它们对最常用的索引方法没有用处。 @@ -1060,7 +1060,7 @@ CREATE OPERATOR CLASS polygon_ops STORAGE box; - 目前,只有 GiST、SP-GiST、GIN 和 BRIN 索引方法支持与列数据类型不同的 STORAGE 类型。GiST 的 compressdecompress 支持例程在使用 STORAGE 时必须处理数据类型转换。SP-GiST 同样需要 compress 支持函数在存储类型不同时完成转换;如果某个 SP-GiST 操作符类还支持取回数据,那么反向转换必须由 consistent 函数处理。在 GIN 中,STORAGE 类型标识key值的类型,它通常不同于被索引列的类型 — 例如,整数数组列上的某个操作符类,其键值可能只是整数。GIN 的 extractValueextractQuery 支持例程负责从被索引值中提取键。BRIN 与 GIN 类似:STORAGE 类型标识被存储的摘要值类型,而操作符类的支持过程负责正确解释这些摘要值。 + 目前,只有 GiST、SP-GiST、GIN 和 BRIN 索引方法支持与列数据类型不同的 STORAGE 类型。GiST 的 compressdecompress 支持例程在使用 STORAGE 时必须处理数据类型转换。SP-GiST 同样需要 compress 支持函数在存储类型不同时完成转换;如果某个 SP-GiST 操作符类还支持取回数据,那么反向转换必须由 consistent 函数处理。在 GIN 中,STORAGE 类型标识值的类型,它通常不同于被索引列的类型 — 例如,整数数组列上的某个操作符类,其键值可能只是整数。GIN 的 extractValueextractQuery 支持例程负责从被索引值中提取键。BRIN 与 GIN 类似:STORAGE 类型标识被存储的摘要值类型,而操作符类的支持函数负责正确解释这些摘要值。 diff --git a/zh/19/xml2.sgml b/zh/19/xml2.sgml index 1324ffd4..f3f40587 100644 --- a/zh/19/xml2.sgml +++ b/zh/19/xml2.sgml @@ -90,7 +90,7 @@ 对文档执行该查询,并将结果包在 XML 标签中。如果结果包含多个值,输出将类似于: <toptag> -<itemtag>Value 1 which could be an XML fragment</itemtag> +<itemtag>Value 1(可以是 XML 片段)</itemtag> <itemtag>Value 2....</itemtag> </toptag> @@ -173,7 +173,7 @@ xpath_table(text key, text document, text relation, text xpaths, text criteria) key - key 字段的名称 — 这只是一个作为输出表第一列使用的字段,也就是说,它用于标识每个输出行来自哪条记录(关于多个值,见下文注释) + 字段的名称 — 这只是一个作为输出表第一列使用的字段,也就是说,它用于标识每个输出行来自哪条记录(关于多个值,见下文注释) @@ -238,7 +238,7 @@ xpath_table('article_id', 'date_entered > ''2003-01-01'' ') AS t(article_id integer, author text, page_count integer, title text); - AS 子句定义了输出表中各列的名称和类型。第一列是 key 字段,其余各列对应 XPath 查询。如果 XPath 查询多于结果列,多出的查询将被忽略。如果结果列多于 XPath 查询,多出的列将为 NULL。 + AS 子句定义了输出表中各列的名称和类型。第一列是 字段,其余各列对应 XPath 查询。如果 XPath 查询多于结果列,多出的查询将被忽略。如果结果列多于 XPath 查询,多出的列将为 NULL。 @@ -267,7 +267,7 @@ WHERE t.author_id = p.person_id; - 在某些情况下,用户会知道某个 XPath 查询只会返回单个结果(例如唯一文档标识符)— 如果它与返回多个结果的 XPath 查询一起使用,这个单值结果只会出现在结果的第一行。解决办法是把 key 字段作为与一个更简单的 XPath 查询结果进行连接的条件之一。例如: + 在某些情况下,用户会知道某个 XPath 查询只会返回单个结果(例如唯一文档标识符)— 如果它与返回多个结果的 XPath 查询一起使用,这个单值结果只会出现在结果的第一行。解决办法是把键字段作为与一个更简单的 XPath 查询结果进行连接的条件之一。例如: CREATE TABLE test ( diff --git a/zh/19/xoper.sgml b/zh/19/xoper.sgml index a3b58216..3fe219da 100644 --- a/zh/19/xoper.sgml +++ b/zh/19/xoper.sgml @@ -164,10 +164,10 @@ SELECT (a + b) AS c FROM test_complex; <literal>RESTRICT</literal> - 如果给出 RESTRICT 子句,它指定该操作符的限制选择度估 + 如果给出 RESTRICT 子句,它指定该操作符的限制选择率估 算函数。(注意,这里是函数名,而不是操作符名。) RESTRICT 子句只对返回 boolean 的二元操 - 作符有意义。限制选择度估算器的作用,是针对当前操作符和某个特定常量值, + 作符有意义。限制选择率估算器的作用,是针对当前操作符和某个特定常量值, 猜测一张表中有多少比例的行会满足如下形式的 WHERE 子句条件: @@ -179,9 +179,9 @@ column OP constant - 编写新的限制选择度估算函数远远超出了本章的范围,不过幸运的是,对于你自 + 编写新的限制选择率估算函数远远超出了本章的范围,不过幸运的是,对于你自 己的很多操作符,通常都可以直接使用系统提供的某个标准估算器。标准的限制 - 选择度估算器如下: + 选择率估算器如下: eqsel 用于 = neqsel 用于 <> @@ -193,7 +193,7 @@ column OP constant - 对于选择度非常高或非常低的操作符,即使它们实际上并不是真正的相等或不等 + 对于选择率非常高或非常低的操作符,即使它们实际上并不是真正的相等或不等 比较,你也常常可以勉强使用 eqselneqsel。例如,几何类型中的近似相等操作符就使用 eqsel,其依据是它们通常只会匹配表中很小一部分项。 @@ -212,7 +212,7 @@ column OP constant - 另一个有用的内置选择度估算函数是 matchingsel。只要 + 另一个有用的内置选择率估算函数是 matchingsel。只要 已为输入数据类型收集了标准的 MCV 和/或直方图统计信息,它几乎就适用于任 何二元操作符。它的默认估计值被设定为 eqsel 所用默认 估计值的两倍,因此最适合那些比相等比较稍微宽松一些的比较操作符。(或者 @@ -222,7 +222,7 @@ column OP constant src/backend/utils/adt/geo_selfuncs.c 中,还为几 - 何操作符提供了其他选择度估算函数:areasel、 + 何操作符提供了其他选择率估算函数:areaselpositionselcontsel。截至 目前,这些函数都还只是桩实现,但你也许仍会想使用它们(或者更好的是,改 进它们)。 @@ -233,9 +233,9 @@ column OP constant <literal>JOIN</literal> - 如果给出 JOIN 子句,它指定该操作符的连接选择度估算函 + 如果给出 JOIN 子句,它指定该操作符的连接选择率估算函 数。(注意,这里是函数名,而不是操作符名。)JOIN 子 - 句只对返回 boolean 的二元操作符有意义。连接选择度估算器的 + 句只对返回 boolean 的二元操作符有意义。连接选择率估算器的 作用,是针对当前操作符,猜测两张表中有多少比例的行对会满足如下形式的 WHERE 子句条件: @@ -246,7 +246,7 @@ table1.column1 OP table2.column2 - 与前面一样,本章不会尝试解释如何编写连接选择度估算函数,而只是建议你在 + 与前面一样,本章不会尝试解释如何编写连接选择率估算函数,而只是建议你在 适用时使用某个标准估算器: eqjoinsel 用于 = @@ -305,7 +305,7 @@ table1.column1 OP table2.column2 一个可参与哈希连接的操作符,必须拥有一个交换子(如果两侧操作数数据类型 - 相同,则可以是它自身;如果不同,则应是相关的相等操作符),并且该交换子 + 相同,则为它自身;如果不同,则应是相关的相等操作符),并且该交换子 也必须出现在同一个操作符族中。否则,在使用该操作符时可能会发生规划器错 误。另外,对于支持多种数据类型的哈希操作符族,最好(虽然并非严格必需) 为每一种数据类型组合都提供相等操作符;这样可以获得更好的优化效果。 @@ -342,7 +342,7 @@ table1.column1 OP table2.column2 - 归并连接的基本思想,是先把左表和右表分别排序,然后并行扫描它们。因此, + 归并连接的基本思想,是先把左表和右表分别排序,然后同步扫描它们。因此, 两种数据类型都必须能够被完全排序,而连接操作符必须只能在那对值位于排序 次序中同一位置时才成功。实际效果上,这意味着连接操作符 必须表现得像相等比较一样。不过,只要两种不同的数据类型在逻辑上兼容,也 @@ -362,7 +362,7 @@ table1.column1 OP table2.column2 一个可参与归并连接的操作符,必须拥有一个交换子(如果两侧操作数数据类型 - 相同,则可以是它自身;如果不同,则应是相关的相等操作符),并且该交换子 + 相同,则为它自身;如果不同,则应是相关的相等操作符),并且该交换子 也必须出现在同一个操作符族中。否则,在使用该操作符时可能会发生规划器错 误。另外,对于支持多种数据类型的 btree 操作符族,最 好(虽然并非严格必需)为每一种数据类型组合都提供相等操作符;这样可以获 diff --git a/zh/19/xplang.sgml b/zh/19/xplang.sgml index 9075d7b6..0590ea2d 100644 --- a/zh/19/xplang.sgml +++ b/zh/19/xplang.sgml @@ -183,7 +183,7 @@ CREATE TRUSTED LANGUAGE plperl 在默认的PostgreSQL安装中, PL/pgSQL语言的调用处理器会被构建并安装到 - library目录中;此外, + 目录中;此外, PL/pgSQL语言本身也安装在所有数据库中。如 果在构建时配置了Tcl支持,那么 PL/TclPL/TclU diff --git a/zh/19/xtypes.sgml b/zh/19/xtypes.sgml index f5ee6199..7ffd6b18 100644 --- a/zh/19/xtypes.sgml +++ b/zh/19/xtypes.sgml @@ -218,7 +218,7 @@ CREATE TYPE complex ( 如果数据类型的内部表示是可变长度的,则这种内部表示必须遵循可变长度数 据的标准布局:前四个字节必须是一个从不直接访问的char[4] 字段(惯例上命名为vl_len_)。必须使用 - SET_VARSIZE()宏在该字段中存储该值的总大小(包括 + SET_VARSIZE()宏在该字段中存储该 datum 的总大小(包括 长度字段本身),并使用VARSIZE()取回它。(这些宏 之所以存在,是因为长度字段可能会随平台不同而采用编码形式。) @@ -260,7 +260,7 @@ CREATE TYPE complex ( PG_DETOAST_DATUM_PACKED(通常通过定义 GETARG_DATATYPE_PP宏来隐藏),并使用 VARSIZE_ANY_EXHDRVARDATA_ANY - 宏访问一个可能采用打包形式的值。再次注意,即使数据类型定义指定了 + 宏访问一个可能采用打包形式的 datum。再次注意,即使数据类型定义指定了 对齐方式,这些宏返回的数据也不是对齐的。如果对齐很重要,就必须使用常 规的PG_DETOAST_DATUM接口。 @@ -271,8 +271,7 @@ CREATE TYPE complex ( 较旧的代码常把vl_len_声明为 int32字段,而不是char[4]字段。只要结构体定 义中还有其他至少按int32对齐的字段,这样做是可以的。但 - 在处理可能未对齐的值时使用这种结构体定义就很危险;编译器可能据此假定该 - 值实际上是对齐的,从而在对齐要求严格的体系结构上导致核心转储。 + 在处理可能未对齐的 datum 时使用这种结构体定义就很危险;编译器可能据此假定该 datum 实际上是对齐的,从而在对齐要求严格的体系结构上导致核心转储。 diff --git a/zh/20/amcheck.sgml b/zh/20/amcheck.sgml index e8872eac..d2ef0ed3 100644 --- a/zh/20/amcheck.sgml +++ b/zh/20/amcheck.sgml @@ -361,7 +361,7 @@ SET client_min_messages = DEBUG1; 这也包括因操作系统排序规则的比较规则发生变化而引起的问题。 - 像text这类可排序类型的数据值之间的比较必须是不可变的 + 像text这类支持排序规则的类型的 datum 之间的比较必须是不可变的 (正如用于 B-树索引扫描的所有比较都必须不可变一样), 这就意味着操作系统排序规则绝不能发生变化。 虽然这种情况比较少见,但操作系统排序规则的更新确实可能导致此类问题。 diff --git a/zh/20/backup-manifest.sgml b/zh/20/backup-manifest.sgml index 5d61e7ff..3eec4b46 100644 --- a/zh/20/backup-manifest.sgml +++ b/zh/20/backup-manifest.sgml @@ -4,7 +4,7 @@ 备份清单格式 - Backup Manifest + 备份清单 @@ -180,7 +180,7 @@ Start-LSN - 为了使用该备份,必须在指定时间线上从这个 LSN 开始回放。该 LSN 按 + 为了使用该备份,必须在指定时间线上从这个 LSN 开始重放。该 LSN 按 PostgreSQL 通常使用的格式存储;也就是说, 它是一个字符串,由两段十六进制字符串构成,每段长度在 1 到 8 之间,并 以斜杠分隔。 @@ -192,7 +192,7 @@ End-LSN - 使用该备份时,指定时间线上的回放可结束于此 LSN,而这也是允许的最早 + 使用该备份时,指定时间线上的重放可结束于此 LSN,而这也是允许的最早 LSN。其存储格式与 Start-LSN 相同。 diff --git a/zh/20/backup.sgml b/zh/20/backup.sgml index a0eae7fd..a110e972 100644 --- a/zh/20/backup.sgml +++ b/zh/20/backup.sgml @@ -3,7 +3,7 @@ 备份和恢复 - backup + 备份 与任何保存重要数据的系统一样,PostgreSQL数据库也应定期备份。虽然其过程基本简单,但清楚理解其底层技术和前提假设非常重要。 @@ -74,7 +74,7 @@ psql -X dbname < psql -X --set ON_ERROR_STOP=on dbname < dumpfile - 无论如何,你最终只会得到一个部分恢复的数据库。另一种做法是指定将整个转储作为单个事务恢复,这样恢复要么全部完成,要么全部回滚。可以通过把命令行选项传给psql来启用这种模式。使用这种模式时要注意,即便是一个很小的错误,也可能回滚一个已经运行了许多小时的恢复过程。不过,这仍可能比在部分恢复后手工清理一个复杂数据库更可取。 + 无论采用上述哪种方式,你最终只会得到一个部分恢复的数据库。另一种做法是指定将整个转储作为单个事务恢复,这样恢复要么全部完成,要么全部回滚。可以通过把命令行选项传给psql来启用这种模式。使用这种模式时要注意,即便是一个很小的错误,也可能回滚一个已经运行了许多小时的恢复过程。不过,这仍可能比在部分恢复后手工清理一个复杂数据库更可取。 @@ -194,7 +194,7 @@ pg_restore -d dbname - 对于非常大的数据库,你可能需要把split与前两种方法之一结合使用。 + 对于非常大的数据库,你可能需要把split与另外两种方法之一结合使用。 @@ -250,7 +250,7 @@ tar -cf backup.tar /usr/local/pgsql/data - 如果无法获得同时的快照,一种选择是将数据库服务器关闭足够长的时间,以建立所有冻结快照。另一种选择是执行持续归档基础备份(),因为这种备份不受备份期间文件系统变化的影响。这要求只在备份过程中启用持续归档;恢复则使用持续归档恢复()。 + 如果无法获得同时的快照,一种选择是将数据库服务器关闭足够长的时间,以建立所有冻结快照。另一种选择是执行持续归档基础备份(),因为这种备份不受备份期间文件系统变化的影响。这种方法只需在备份期间启用持续归档;恢复则使用持续归档恢复()。 @@ -266,11 +266,11 @@ tar -cf backup.tar /usr/local/pgsql/data 持续归档和时间点恢复(PITR) - continuous archiving + 持续归档 - point-in-time recovery + 时间点恢复 @@ -310,7 +310,7 @@ tar -cf backup.tar /usr/local/pgsql/data - 和普通文件系统备份技术一样,这种方法只能支持整个数据库集簇的恢复,而不支持其中某个子集的恢复。此外,它需要大量归档存储:基础备份可能很庞大,繁忙系统也会产生大量必须归档的 WAL 流量。尽管如此,在很多需要高可靠性的场景中,它仍是首选的备份技术。 + 和普通文件系统备份技术一样,这种方法只能支持整个数据库集簇的恢复,而不支持其中某个子集的恢复。此外,它需要大量归档存储:基础备份可能很庞大,繁忙系统也会产生许多兆字节的、必须归档的 WAL 流量。尽管如此,在很多需要高可靠性的场景中,它仍是首选的备份技术。 @@ -329,7 +329,7 @@ tar -cf backup.tar /usr/local/pgsql/data - 要启用 WAL 归档,请将配置参数设置为replica或更高,将设置为on,并在配置参数中指定要使用的 shell 命令,或者在配置参数中指定要使用的库。实际上,这些设置通常都会放在postgresql.conf文件中。 + 要启用 WAL 归档,请将配置参数设置为replica或更高,将设置为on,并在配置参数中指定要使用的 shell 命令,或者在配置参数中指定要使用的库。在实际使用中,这些设置总是放在postgresql.conf文件中。 @@ -345,20 +345,16 @@ test ! -f /mnt/server/archivedir/00000001000000A900000065 && cp pg_wal/0 对每个新的待归档文件都会生成一条类似的命令。 - - 归档命令会以运行PostgreSQL服务器的同一操作系统用户身份执行。由于这一系列被归档的 WAL 文件实际上包含了数据库中的几乎全部内容,因此你应确保归档数据不会被他人窥探;例如,把它归档到一个不向组或所有用户开放读权限的目录中。 - + 归档命令将以运行 PostgreSQL 服务器的同一用户身份执行。由于归档的一系列 WAL 文件实际上包含数据库中的全部内容,应确保归档数据不会被他人窥视;例如,将其归档到不允许所属组或其他用户读取的目录。 - - 重要的是,归档命令只有在成功时才返回零退出状态。收到零结果后,PostgreSQL会认为该文件已经成功归档,并会将其删除或回收。相反,非零状态会告诉PostgreSQL该文件尚未归档;系统会周期性重试,直到成功为止。 - + 归档命令必须当且仅当成功时才返回退出状态零。收到零状态后,PostgreSQL 会认为该文件已成功归档,并将其删除或回收。非零状态则告诉 PostgreSQL 该文件尚未归档;它会定期重试,直到成功。 另一种归档方式是把自定义归档模块用作archive_library。由于这类模块是用C编写的,创建自己的模块可能比编写 shell 命令需要更多工作。不过,归档模块可能比通过 shell 归档更高效,而且可以访问许多有用的服务器资源。有关归档模块的更多信息,见 - 当归档命令被信号终止(用于服务器关闭流程的SIGTERM除外),或者 shell 因退出状态大于 125 的错误(例如命令未找到)而失败,或者归档函数发出ERRORFATAL时,归档器进程会中止,并由 postmaster 重新启动。在这种情况下,失败不会记录到中。 + 当归档命令被信号终止(用于服务器关闭流程的SIGTERM除外),或者因 shell 报错(例如命令未找到)而以大于 125 的状态退出,或者归档函数发出ERRORFATAL时,归档器进程会中止,并由 postmaster 重新启动。在这种情况下,失败不会记录到中。 @@ -366,7 +362,7 @@ test ! -f /mnt/server/archivedir/00000001000000A900000065 && cp pg_wal/0 - 在少数情况下,PostgreSQL可能会尝试重新归档一个此前已经归档过的 WAL 文件。例如,如果系统在服务器把归档成功持久记录下来之前崩溃,服务器在重启后会再次尝试归档该文件(前提是归档仍然启用)。当归档命令或归档库遇到一个已存在的文件时,如果该文件与待归档 WAL 文件内容完全相同,且先前归档的文件已经完全持久化到存储,则前者应分别返回零状态或true。如果已存在文件的内容与正在归档的 WAL 文件不同,则归档命令或归档库必须分别返回非零状态或false。 + 在少数情况下,PostgreSQL可能会尝试重新归档一个此前已经归档过的 WAL 文件。例如,如果系统在服务器把归档成功持久记录下来之前崩溃,服务器在重启后会再次尝试归档该文件(前提是归档仍然启用)。当归档命令或归档库遇到一个已存在的文件时,如果该文件与待归档 WAL 文件内容完全相同,且先前归档的文件已经完全持久化到存储,则归档命令或归档库应分别返回零状态或true。如果已存在文件的内容与正在归档的 WAL 文件不同,则归档命令或归档库必须分别返回非零状态或false @@ -390,7 +386,7 @@ test ! -f /mnt/server/archivedir/00000001000000A900000065 && cp pg_wal/0 - 归档命令或归档函数只会在完整的 WAL 段上被调用。因此,如果服务器产生的 WAL 流量很小(或者存在低谷期),事务完成到其被安全写入归档存储之间可能会有很长延迟。为了限制未归档数据可能有多旧,你可以设置,强制服务器至少隔这么长时间切换到一个新的 WAL 段文件。注意,由强制切换而提前归档的文件长度仍与装满的文件相同。因此,把archive_timeout设得很短并不明智,这会使归档存储膨胀。archive_timeout设为大约 1 分钟通常是合理的。 + 归档命令或归档函数只会针对已完成的 WAL 段调用。因此,如果服务器产生的 WAL 流量很小(或者存在低谷期),事务完成到其被安全写入归档存储之间可能会有很长延迟。为了限制未归档数据可能有多旧,你可以设置,使服务器强制切换到新 WAL 段文件的间隔不超过这个值。注意,由强制切换而提前归档的文件长度仍与装满的文件相同。因此,把archive_timeout设得很短并不明智,这会使归档存储膨胀。archive_timeout设为大约 1 分钟通常是合理的。 @@ -438,7 +434,7 @@ test ! -f /mnt/server/archivedir/00000001000000A900000065 && cp pg_wal/0 - 恢复增量备份时,不仅需要增量备份本身,还必须具有所有更早的备份,以便提供增量备份中省略的那些块。关于这项要求的更多信息见。请注意,当集簇的校验和状态发生变化时,使用pg_combinebackup会受到限制;参见pg_combinebackup limitations。 + 恢复增量备份时,不仅需要增量备份本身,还必须具有提供增量备份中省略的块所需的所有较早备份。关于这项要求的更多信息见。请注意,当集簇的校验和状态发生变化时,使用pg_combinebackup会受到限制;参见pg_combinebackup 的限制。 @@ -446,7 +442,7 @@ test ! -f /mnt/server/archivedir/00000001000000A900000065 && cp pg_wal/0 - 增量备份通常只对相对较大的数据库有意义,因为其中相当一部分数据不变,或者变化缓慢。对于小数据库,忽略增量备份的存在而直接进行完整备份会更简单,也更容易管理。对于所有数据都被频繁修改的大数据库,增量备份也不会比完整备份小多少。 + 增量备份通常只对相当一部分数据不变或变化缓慢的较大数据库有意义。对于小数据库,忽略增量备份的存在而直接进行完整备份会更简单,也更容易管理。对于所有数据都被频繁修改的大数据库,增量备份也不会比完整备份小多少。 @@ -610,7 +606,7 @@ SELECT * FROM pg_backup_stop(wait_for_archive => true); - 这一切的关键在于设置一个恢复配置,描述你希望如何恢复,以及恢复应运行到什么位置。其中绝对必须指定的一项是restore_command,它告诉PostgreSQL如何检索已归档的 WAL 文件段。像archive_command一样,它也是一个 shell 命令字符串。它可以包含%f,会被替换为所需 WAL 文件的名称;也可以包含%p,会被替换为复制该 WAL 文件时要使用的路径名。(该路径名相对于当前工作目录,也就是集簇的数据目录。)如果需要在命令中嵌入实际的%字符,请写成%%。最简单而有用的命令类似如下: + 这一切的关键在于设置一个恢复配置,描述你希望如何恢复,以及恢复应运行到什么位置。其中绝对必须指定的一项是restore_command,它告诉PostgreSQL如何检索已归档的 WAL 段文件。像archive_command一样,它也是一个 shell 命令字符串。它可以包含%f,会被替换为所需 WAL 文件的名称;也可以包含%p,会被替换为复制该 WAL 文件时要使用的路径名。(该路径名相对于当前工作目录,也就是集簇的数据目录。)如果需要在命令中嵌入实际的%字符,请写成%%。最简单而有用的命令类似如下: restore_command = 'cp "/mnt/server/archivedir/%f" "%p"' @@ -618,11 +614,11 @@ restore_command = 'cp "/mnt/server/archivedir/%f" "%p"' - 重要的是,该命令在失败时必须返回非零退出状态。系统调用该命令来请求归档中不存在的文件;遇到这种情况时,它就应返回非零值。这不是一种错误情况。例外是,如果该命令被信号终止(用于数据库服务器关闭的SIGTERM除外),或者因 shell 错误(如命令未找到)而失败,那么恢复将中止,服务器也不会启动。 + 重要的是,该命令在失败时必须返回非零退出状态。系统调用该命令来请求归档中不存在的文件;遇到这种情况时,它必须返回非零值。这不是一种错误情况。例外是,如果该命令被信号终止(用于数据库服务器关闭的SIGTERM除外),或者因 shell 错误(如命令未找到)而失败,那么恢复将中止,服务器也不会启动。 - 被请求的文件并不全都是 WAL 段文件;你还应预期会收到对带有.history后缀文件的请求。另外请注意,%p路径的基本文件名会与%f不同;不要指望它们可以互换使用。 + 被请求的文件并不全都是 WAL 段文件;你还应预期会收到对带有.history后缀文件的请求。另外请注意,%p路径的文件名部分会与%f不同;不要指望它们可以互换使用。 @@ -630,16 +626,16 @@ restore_command = 'cp "/mnt/server/archivedir/%f" "%p"' - 通常,恢复会处理完所有可用的 WAL 段,从而把数据库恢复到当前时间点(或者在可用 WAL 段所允许的情况下尽可能接近当前时间点)。因此,一次正常恢复通常会以一条file not found消息结束,具体错误文本取决于你选择的restore_command。在恢复开始时,你也可能看到一条针对类似00000001.history文件的错误消息。这同样是正常的,在简单恢复场景中并不表示有问题;相关讨论见。 + 通常,恢复会处理完所有可用的 WAL 段,从而把数据库恢复到当前时间点(或者在可用 WAL 段所允许的情况下尽可能接近当前时间点)。因此,一次正常恢复会以一条file not found消息结束,具体错误文本取决于你选择的restore_command。在恢复开始时,你也可能看到一条针对类似00000001.history文件的错误消息。这同样是正常的,在简单恢复场景中并不表示有问题;相关讨论见 - 如果你希望恢复到过去的某个时间点(例如恢复到那位初级 DBA 删掉你的主事务表之前),只需指定所需的停止点即可。这个停止点也称为恢复目标,可以通过日期/时间、命名恢复点或者某个特定事务 ID 完成时刻来指定。在目前的实现下,只有日期/时间和命名恢复点这两种方式真正比较实用,因为没有工具能够帮助你足够准确地识别应使用哪个事务 ID。 + 如果你希望恢复到过去的某个时间点(例如恢复到那位初级 DBA 删掉你的主事务表之前),只需指定所需的停止点即可。这个停止点也称为恢复目标,可以通过日期/时间、命名恢复点或者某个特定事务 ID 完成时刻来指定。在撰写本文时,只有日期/时间和命名恢复点这两种方式真正比较实用,因为没有工具能够帮助你足够准确地识别应使用哪个事务 ID。 - 停止点必须晚于基础备份的结束时间,也就是pg_backup_stop的结束时间。你不能用某次基础备份恢复到该备份仍在进行中的时间点。(若要恢复到这样的时间点,必须回到更早的一次基础备份,再从那里向前滚动。) + 停止点必须晚于基础备份的结束时间,也就是pg_backup_stop的结束时间。你不能用某次基础备份恢复到该备份仍在进行中的时间点。(若要恢复到这样的时间点,必须回到更早的一次基础备份,再从那里向前重放日志。) @@ -653,12 +649,10 @@ restore_command = 'cp "/mnt/server/archivedir/%f" "%p"' 时间线 - timelines + 时间线 - - 把数据库恢复到过去某个时间点的能力,会带来一些复杂性,颇有点像关于时间旅行和平行宇宙的科幻小说。例如,在数据库的原始历史中,假设你在星期二晚上 5:15 删掉了一张关键表,但直到星期三中午才意识到自己的错误。于是你拿出备份,把系统恢复到星期二晚上 5:14,并重新上线运行。在数据库宇宙的这条历史中,你从未删掉那张表。但如果你后来发现这并不是个好主意,并且想回到原始历史中的星期三上午某个时间点,就办不到了,因为在数据库重新上线运行期间,它可能已经覆盖了某些 WAL 段文件,而这些文件本来能把你带回到现在想回去的那个时刻。因此,为了避免这种情况,你需要把时间点恢复之后生成的那一串 WAL 记录,与数据库原始历史中生成的那些 WAL 记录区分开来。 - + 能够将数据库恢复到过去某个时间点,也会带来一些类似科幻故事中时间旅行和平行宇宙的复杂情况。例如,假设在数据库原来的历史中,你在周二下午 5:15 删除了一张重要的表,直到周三中午才发现错误。你从容地取出备份,将数据库恢复到周二下午 5:14,然后重新投入运行。在数据库宇宙的这段历史中,你从未删除过那张表。但假设你后来发现这样做不太合适,希望回到原来历史中的周三上午某个时刻。如果数据库恢复运行后覆盖了通往该时刻所需的某些 WAL 段文件,就无法回去了。因此,为了避免这种情况,需要区分时间点恢复后产生的一系列 WAL 记录与数据库原来历史中产生的记录。 为了解决这个问题,PostgreSQL引入了时间线的概念。每当一次归档恢复完成时,系统都会创建一条新的时间线,用来标识此次恢复之后生成的 WAL 记录序列。时间线 ID 是 WAL 段文件名的一部分,因此新的时间线不会覆盖先前时间线产生的 WAL 数据。例如,在 WAL 文件名0000000100001234000055CD中,开头的00000001就是十六进制表示的时间线 ID。(注意,在服务器日志消息等其他场合,时间线 ID 通常以十进制打印。) @@ -672,9 +666,7 @@ restore_command = 'cp "/mnt/server/archivedir/%f" "%p"' 每当创建一条新的时间线时,PostgreSQL都会创建一个时间线历史文件,记录它是从哪条时间线、在何时分叉出来的。当从包含多条时间线的归档中恢复时,这些历史文件对于系统选取正确的 WAL 段文件是必需的。因此,它们会像 WAL 段文件一样被归档到 WAL 归档区域。历史文件只是很小的文本文件,因此长期保存它们既便宜也合适(而段文件通常很大)。如果你愿意,还可以在历史文件中加入注释,记录创建这条时间线的方式和原因。当你因实验而积累出一批错综复杂的时间线时,这类注释会特别有价值。 - - 恢复的默认行为是恢复到归档中找到的最新时间线。如果你希望恢复到执行基础备份时的当前时间线,或者恢复到某个指定的子时间线(也就是说,你想回到某个本身就是在一次恢复尝试之后才产生的状态),就需要指定current,或者在中指定目标时间线 ID。你不能恢复到那些在基础备份之前就已经分叉出去的时间线。 - + 默认的恢复行为是恢复到归档中找到的最新时间线。如果希望恢复到制作基础备份时的当前时间线,或者某条特定的子时间线(即希望返回到一次恢复尝试之后产生的某个状态),需要在 中指定 current 或目标时间线 ID。不能恢复到在基础备份之前就已分支出去的时间线。 @@ -685,14 +677,14 @@ restore_command = 'cp "/mnt/server/archivedir/%f" "%p"' - 单机热备份 + 独立热备份 - 可以利用PostgreSQL的备份设施生成单机热备份。这些备份不能用于时间点恢复,但它们的制作和恢复通常都比pg_dump转储快得多。(它们也比pg_dump转储大得多,因此在某些情况下速度优势可能会被抵消。) + 可以利用PostgreSQL的备份设施生成独立热备份。这些备份不能用于时间点恢复,但它们的制作和恢复通常都比pg_dump转储快得多。(它们也比pg_dump转储大得多,因此在某些情况下速度优势可能会被抵消。) - 和基础备份一样,生成单机热备份最简单的方法是使用工具。如果在调用它时包含-X参数,使用该备份所需的全部预写式日志都会自动包含在备份中,恢复该备份时也不需要额外动作。 + 和基础备份一样,生成独立热备份最简单的方法是使用工具。如果在调用它时包含-X参数,使用该备份所需的全部预写式日志都会自动包含在备份中,恢复该备份时也不需要额外动作。 @@ -723,7 +715,7 @@ archive_command = 'local_backup_script.sh "%p" "%f"' - 脚本中可能需要解决的需求示例包括: + 可以在脚本中处理的需求示例包括: @@ -732,7 +724,7 @@ archive_command = 'local_backup_script.sh "%p" "%f"' - 把 WAL 文件成批处理,使其每三个小时传输一次,而不是每生成一个就传一次 + 把 WAL 文件成批处理,使其每三个小时传输一次,而不是每次只传输一个 diff --git a/zh/20/brin.sgml b/zh/20/brin.sgml index cc6cc7b1..deeaac0f 100644 --- a/zh/20/brin.sgml +++ b/zh/20/brin.sgml @@ -4,7 +4,7 @@ BRIN 索引 - index + 索引 BRIN @@ -25,8 +25,7 @@ - 如果索引中存储的摘要信息与查询条件相一致BRIN - 索引就可以通过常规位图索引扫描来满足查询,并返回每个范围内所有页上的全部元组。 + BRIN 索引可以通过常规位图索引扫描来满足查询;对于每个范围,如果索引中存储的摘要信息与查询条件相一致,就会返回该范围内所有页上的全部元组。 查询执行器负责重新检查这些元组,并丢弃不匹配查询条件的元组 — 换句话说,这些索引是有损的。 由于 BRIN 索引非常小,与顺序扫描相比,扫描索引只会带来很小的额外开销, 但可以避免扫描那些已知不包含匹配元组的大块表数据。 @@ -85,7 +84,7 @@ 当启用自动摘要时,一旦检测到向下一个块范围第一页的第一项执行了插入, - 就会向 autovacuum 发送请求,要求对该块范围执行定向摘要。 + 就会向 autovacuum 发送请求,要求对前一个块范围执行定向摘要。 该请求会在同一数据库中的某个 autovacuum 工作进程下一次结束运行时得到处理。 如果请求队列已满,该请求就不会被记录,并会向服务器日志发送一条消息: @@ -790,13 +789,13 @@ LOG: request for BRIN range summarization for index "brin_wi_idx" page 128 was typedef struct BrinOpcInfo { - /* Number of columns stored in an index column of this opclass */ + /* 此操作符类在一个索引列中存储的列数 */ uint16 oi_nstored; - /* Opaque pointer for the opclass' private use */ + /* 供操作符类私有使用的不透明指针 */ void *oi_opaque; - /* Type cache entries of the stored columns */ + /* 所存储列的类型缓存条目 */ TypeCacheEntry *oi_typcache[FLEXIBLE_ARRAY_MEMBER]; } BrinOpcInfo; @@ -1012,62 +1011,62 @@ typedef struct BrinOpcInfo 操作符策略 1 - left-of 操作符 + 位于左侧的操作符 操作符策略 4 操作符策略 2 - does-not-extend-to-the-right-of 操作符 + 不延伸到右侧的操作符 操作符策略 5 操作符策略 3 - overlaps 操作符 + 重叠操作符 操作符策略 4 - does-not-extend-to-the-left-of 操作符 + 不延伸到左侧的操作符 操作符策略 1 操作符策略 5 - right-of 操作符 + 位于右侧的操作符 操作符策略 2 - 操作符策略 6, 18 - same-as-or-equal-to 操作符 + 操作符策略 6、18 + 相同或等于操作符 操作符策略 7 - 操作符策略 7, 16, 24, 25 - contains-or-equal-to 操作符 + 操作符策略 7、16、24、25 + 包含或等于操作符 - 操作符策略 8, 26, 27 - is-contained-by-or-equal-to 操作符 + 操作符策略 8、26、27 + 被包含或等于操作符 操作符策略 3 操作符策略 9 - does-not-extend-above 操作符 + 不延伸到上方的操作符 操作符策略 11 操作符策略 10 - is-below 操作符 + 位于下方的操作符 操作符策略 12 操作符策略 11 - is-above 操作符 + 位于上方的操作符 操作符策略 9 操作符策略 12 - does-not-extend-below 操作符 + 不延伸到下方的操作符 操作符策略 10 @@ -1113,12 +1112,12 @@ typedef struct BrinOpcInfo 要为仅实现等值操作符且支持哈希的数据类型编写操作符类,可以按 - 所示,将 bloom 支持过程与相应操作符一起使用。 - 所有操作符类成员(过程和操作符)都是必需的。 + 所示,将 bloom 支持函数与相应操作符一起使用。 + 所有操作符类成员(函数和操作符)都是必需的。 - bloom 操作符类的过程和支持编号 + bloom 操作符类的函数和支持编号 @@ -1128,28 +1127,28 @@ typedef struct BrinOpcInfo - 支持过程 1 + 支持函数 1 内部函数brin_bloom_opcinfo() - 支持过程 2 + 支持函数 2 内部函数brin_bloom_add_value() - 支持过程 3 + 支持函数 3 内部函数brin_bloom_consistent() - 支持过程 4 + 支持函数 4 内部函数brin_bloom_union() - 支持过程 5 + 支持函数 5 内部函数brin_bloom_options() - 支持过程 11 - 计算元素哈希值的函数 + 支持函数 11 + 计算元素 hash 值的函数 操作符策略 1 @@ -1160,20 +1159,20 @@ typedef struct BrinOpcInfo
- 支持过程编号 1 至 10 保留给 BRIN 内部函数,因此 SQL 层函数从编号 11 开始。 + 支持函数编号 1 至 10 保留给 BRIN 内部函数,因此 SQL 层函数从编号 11 开始。 支持函数 11 是构建索引所需的主要函数。 - 它应接受一个与操作符类数据类型相同的参数,并返回该值的哈希值。 + 它应接受一个与操作符类数据类型相同的参数,并返回该值的 hash 值。 minmax-multi 操作符类也面向实现全序集的数据类型,可以看作 minmax 操作符类的简单扩展。 minmax 操作符类把每个块范围中的值摘要为单个连续区间,而 minmax-multi 则允许将其摘要为多个较小区间,以改进对离群值的处理。 - 可以按 所示,将 minmax-multi 支持过程与相应操作符一起使用。 - 所有操作符类成员(过程和操作符)都是必需的。 + 可以按 所示,将 minmax-multi 支持函数与相应操作符一起使用。 + 所有操作符类成员(函数和操作符)都是必需的。 - minmax-multi 操作符类的过程和支持编号 + minmax-multi 操作符类的函数和支持编号 @@ -1183,27 +1182,27 @@ typedef struct BrinOpcInfo - 支持过程 1 + 支持函数 1 内部函数brin_minmax_multi_opcinfo() - 支持过程 2 + 支持函数 2 内部函数brin_minmax_multi_add_value() - 支持过程 3 + 支持函数 3 内部函数brin_minmax_multi_consistent() - 支持过程 4 + 支持函数 4 内部函数brin_minmax_multi_union() - 支持过程 5 + 支持函数 5 内部函数brin_minmax_multi_options() - 支持过程 11 + 支持函数 11 计算两个值之间距离(范围长度)的函数 diff --git a/zh/20/btree.sgml b/zh/20/btree.sgml index 4f6b9006..845b6433 100644 --- a/zh/20/btree.sgml +++ b/zh/20/btree.sgml @@ -4,7 +4,7 @@ B-树索引 - index + 索引 B-树 @@ -18,10 +18,10 @@ - 由于每个 B-树 操作符类都会为其数据类型施加一种排序顺序,B-树 + 由于每个 B-树操作符类都会为其数据类型施加一种排序顺序,B-树 操作符类(更准确地说,是操作符族)已经成为 PostgreSQL 用来统一表示和理解排序语义的方式。因此,它们具备了一些超出单纯支持 - B-树 索引所需范围的特性,系统中某些与 btree AM + B-树索引所需范围的特性,系统中某些与 B-树 AM 相距甚远的部分也会利用它们。 @@ -55,7 +55,7 @@ - = 操作符必须是一种等价关系;也就是说,对于该数据类型的所有非空值 + = 操作符必须是一种等价关系;也就是说,对于该数据类型的所有非 null 值 ABC: @@ -93,7 +93,7 @@ - < 操作符必须是一种强排序关系;也就是说,对于所有非空值 + < 操作符必须是一种强排序关系;也就是说,对于所有非 null 值 ABC: @@ -123,7 +123,7 @@ - 此外,该顺序还是全序的;也就是说,对于所有非空值 + 此外,该顺序还是全序的;也就是说,对于所有非 null 值 AB: @@ -177,18 +177,18 @@ B-树支持函数 - 如所示,btree 定义了一个必需和五个可选的支持函数。六个用户定义的方法如下: + 如所示,B-树定义了一个必需和五个可选的支持函数。六个用户定义的方法如下: order - 对于 B-树 操作符族为其提供比较操作符的每一种数据类型组合,都必须提供一个比较支持函数。该函数在 + 对于 B-树操作符族为其提供比较操作符的每一种数据类型组合,都必须提供一个比较支持函数。该函数在 pg_amproc 中注册,支持函数编号为 1,并且 amproclefttype/amprocrighttype 要等于该比较的左右数据类型(也就是与匹配操作符在 - pg_amop 中注册时相同的数据类型)。比较函数必须接受两个非空值 + pg_amop 中注册时相同的数据类型)。比较函数必须接受两个非 null 值 AB,并返回一个 int32 值,其值为 < 0、 @@ -197,12 +197,12 @@ < BA = BA - > B。不允许返回空值:该数据类型的所有值都必须可比较。示例见 + > B。不允许返回 null:该数据类型的所有值都必须可比较。示例见 src/backend/access/nbtree/nbtcompare.c - 如果参与比较的值属于可排序数据类型,则会通过标准的 + 如果参与比较的值属于支持排序规则的数据类型,则会通过标准的 PG_GET_COLLATION() 机制,把适当的排序规则 OID 传递给比较支持函数。 @@ -223,11 +223,11 @@ in_range - in_range support functions + in_range 支持函数 - support functions + 支持函数 in_range @@ -266,7 +266,7 @@ returns bool - in_range 函数的核心语义取决于这两个 Boolean + in_range 函数的核心语义取决于这两个布尔 标志参数。它应当先对 baseoffset 做加法或减法,再把 val 与结果比较,具体如下: @@ -383,7 +383,7 @@ returns bool - 如果被排序的类型(type1)属于可排序数据类型,则会通过标准的 + 如果被排序的类型(type1)属于支持排序规则的数据类型,则会通过标准的 PG_GET_COLLATION() 机制,把适当的排序规则 OID 传递给 in_range 函数。 @@ -408,12 +408,7 @@ returns bool equalimage(opcintype oid) returns bool - 返回值是关于某个操作符类及其排序规则的静态信息。返回 - true 表示:该操作符类的 - order 函数被保证只有在返回 - 0arguments are equal)时,其 - AB - 参数才是可以互换而不损失任何语义信息的。如果未注册 + 返回值是关于某个操作符类及其排序规则的静态信息。返回 true 表示可以保证:该操作符类的 order 函数只有在其 AB 参数也能够互换而不损失任何语义信息时,才会返回 0参数相等)。如果未注册 equalimage 函数,或其返回 false,就表示不能假定该条件成立。 @@ -421,7 +416,7 @@ equalimage(opcintype oid) returns bool opcintype 参数是该操作符类所索引数据类型的 pg_type.oid。这只是为了方便在不同操作符类之间复用同一个底层 equalimage 函数。如果 - opcintype 是可排序数据类型,则会通过标准的 + opcintype 是支持排序规则的数据类型,则会通过标准的 PG_GET_COLLATION() 机制,把适当的排序规则 OID 传递给 equalimage 函数。 @@ -453,7 +448,7 @@ equalimage(opcintype oid) returns bool 发行版中包含的操作符类遵循的惯例是:注册一个现成的通用 equalimage 函数。大多数操作符类注册 btequalimage(),这表示去重在无条件下都是安全的。像 - text 这样可排序数据类型的操作符类会注册 + text 这样支持排序规则的数据类型的操作符类会注册 btvarstrequalimage(),这表示在确定性排序规则下去重是安全的。第三方扩展的最佳实践则是注册它们自己的自定义函数,以保留控制权。 @@ -493,19 +488,19 @@ options(relopts local_relopts *) returns skipsupport - 可选地,B-树 操作符族可以提供skip 支持函数,注册为支持函数编号 + 可选地,B-树操作符族可以提供跳过支持函数,注册为支持函数编号 6。这些函数为 B-树 代码提供了一种按键空间顺序遍历某个操作符类底层输入类型所能表示的全部可能值的方法。当核心代码应用跳过扫描优化时,就会用到它。相关 API 定义在 src/include/utils/skipsupport.h 中。 - 没有提供 skip 支持函数的操作符类,仍然可以使用跳过扫描。核心代码仍可采用其后备策略,尽管对于某些离散类型来说,这种策略可能并非最优。对于连续类型上的操作符类,提供 - skip 支持函数通常没有意义(甚至可能不可行)。 + 没有提供跳过支持函数的操作符类,仍然可以使用跳过扫描。核心代码仍可采用其后备策略,尽管对于某些离散类型来说,这种策略可能并非最优。对于连续类型上的操作符类,提供 + 跳过支持函数通常没有意义(甚至可能不可行)。 操作符族注册跨类型的 skipsupport - 函数并不合理,尝试这样做会导致错误。因为要确定下一个可被索引的值,必须通过递增一个从索引元组复制出来的值来完成。所生成的值都必须属于同一种底层数据类型(也就是被跳过的索引列的 opclass 输入类型)。 + 函数并不合理,尝试这样做会导致错误。因为要确定下一个可被索引的值,必须通过递增一个从索引元组复制出来的值来完成。所生成的值都必须属于同一种底层数据类型(也就是被跳过的索引列的操作符类输入类型)。 @@ -547,7 +542,7 @@ options(relopts local_relopts *) returns B-树索引会通过执行自底向上索引删除轮次,增量地删除这类版本频繁更替产生的索引元组。每一轮删除都是因预期中的版本频繁更替页拆分而触发的。这只会发生在那些没有被 - UPDATE 语句逻辑修改的索引上,否则过时版本就会集中积累在某些特定页面中。通常可以避免页拆分,不过也可能出现某些实现层面的启发式规则甚至一个垃圾索引元组都识别不出来、删不掉的情况(这时就要靠页拆分或一次去重轮次来解决新元组放不进叶页的问题)。任何一次索引扫描在单个逻辑行上必须穿越的最坏版本数,是影响整个系统响应能力和吞吐量的重要因素。一次自底向上索引删除轮次会基于涉及逻辑行与版本的定性区别,针对单个叶页中疑似垃圾的元组。这与自动清理工作进程执行的自顶向下索引清理不同,后者是在超出某些定量的表级阈值时触发的(见)。 + UPDATE 语句逻辑修改的索引上;如果不执行这类删除,过时版本就会集中积累在某些特定页面中。通常可以避免页拆分,不过也可能出现某些实现层面的启发式规则甚至一个垃圾索引元组都识别不出来、删不掉的情况(这时就要靠页拆分或一次去重轮次来解决新元组放不进叶页的问题)。任何一次索引扫描在单个逻辑行上必须穿越的最坏版本数,是影响整个系统响应能力和吞吐量的重要因素。一次自底向上索引删除轮次会基于涉及逻辑行与版本的定性区别,针对单个叶页中疑似垃圾的元组。这与自动清理工作进程执行的自顶向下索引清理不同,后者是在超出某些定量的表级阈值时触发的(见)。 @@ -587,7 +582,7 @@ options(relopts local_relopts *) returns 去重通过周期性地把一组组重复元组合并起来,为每一组形成一个 - posting list 元组。在这种表示中,列键值只出现一次,后面跟着一个排好序的 + 倒排列表 元组。在这种表示中,列键值只出现一次,后面跟着一个排好序的 TID 数组,指向表中的各行。这能显著减小那些每个值(或每一种不同列值组合)平均会出现多次的索引的存储大小。查询延迟可能显著降低,整体查询吞吐量也可能显著提升,例行索引清理的开销同样可能显著减少。 @@ -601,14 +596,14 @@ options(relopts local_relopts *) returns 去重过程是惰性发生的:当插入一个放不进现有叶页的新项时,只有在索引元组删除也无法为该新项释放足够空间的情况下,才会进行去重(通常只会短暂考虑删除,然后就跳过)。与 - GIN 的 posting list 元组不同,B-树的 posting list - 元组不需要在每次插入新的重复项时都扩展;它们只是叶页原始逻辑内容的一种替代物理表示。这种设计优先考虑混合读写工作负载下的一致性能。大多数客户端应用至少都能从去重中获得适度的性能收益。去重默认启用。 + GIN 的倒排列表元组不同,B-树的倒排列表 + 元组不需要在每次插入新的重复项时都扩展;它们只是叶页原始逻辑内容的一种替代物理表示。这种设计优先考虑混合读写工作负载下的稳定性能。大多数客户端应用至少都能从去重中获得适度的性能收益。去重默认启用。 CREATE INDEXREINDEX - 都会应用去重来创建 posting list - 元组,只是两者采用的策略略有不同。对于从表中取出的已排序输入中遇到的每一组普通重复元组,都会在被加入当前待写入叶页之前先合并成一个 - posting list 元组。每个 posting list 元组都会尽量容纳更多的 + 都会应用去重来创建倒排列表 + 元组,不过它们采用的策略与上述过程略有不同。对于从表中取出的已排序输入中遇到的每一组普通重复元组,都会在被加入当前待写入叶页之前先合并成一个 + 倒排列表元组。每个倒排列表元组都会尽量容纳更多的 TID。叶页按通常方式写出,不需要额外独立的去重过程。由于 CREATE INDEXREINDEX 都是一次性的批处理操作,这种策略非常适合它们。 @@ -617,14 +612,14 @@ options(relopts local_relopts *) returns 如果某个写密集型工作负载由于索引中的重复值很少甚至没有,而无法从去重中获益,那么它会承担很小且固定的性能损耗(除非显式禁用去重)。 deduplicate_items 存储参数可用于在单个索引内禁用去重。而只读工作负载绝不会因此遭受性能损失,因为读取 - posting list 元组至少与读取标准元组表示一样高效。禁用去重通常并没有帮助。 + 倒排列表元组至少与读取标准元组表示一样高效。禁用去重通常并没有帮助。 有时唯一索引(以及唯一约束)也可以使用去重。这允许叶页临时吸收因版本频繁更替产生的额外重复项。唯一索引中的去重能够增强自底向上索引删除,特别是在长事务持有阻塞垃圾回收的快照时。其目标是为自底向上索引删除策略再次发挥作用争取时间。把页拆分推迟到某个单独的长事务自然结束之后,可能使一次自底向上删除轮次在较早一次失败的地方获得成功。 - 系统会应用一种特殊的启发式规则,来判定唯一索引中是否应当执行一次去重轮次。它往往可以直接跳到拆分叶页,从而避免把周期浪费在无益的去重过程中而造成性能损耗。如果你担心去重的开销,可以考虑有选择地设置 + 系统会应用一种特殊的启发式规则,来判定唯一索引中是否应当执行一次去重轮次。它往往可以直接跳到拆分叶页,从而避免把处理器周期浪费在无益的去重过程中而造成性能损耗。如果你担心去重的开销,可以考虑有选择地设置 deduplicate_items = off。在唯一索引中保持去重启用,坏处很小。 @@ -648,7 +643,7 @@ options(relopts local_relopts *) returns numeric 不能使用去重。必须保留相等的 datum - 之间的小数位数。 + 之间的显示小数位数。 diff --git a/zh/20/catalogs.sgml b/zh/20/catalogs.sgml index ab019bdd..3388c164 100644 --- a/zh/20/catalogs.sgml +++ b/zh/20/catalogs.sgml @@ -678,7 +678,7 @@ t = 表(包括物化视图), - i = 索引. + i = 索引。 @@ -931,7 +931,7 @@
- amproclefttypeamprocrighttype列的通常解释是它们标识了一个特定支持过程所支持的操作符的左右输入类型。对于某些访问方法它们和支持过程本身的输入数据类型相匹配,而对其他的则不会匹配。对于一个索引有一个默认支持过程的概念,这些支持过程的amproclefttypeamprocrighttype都等于索引操作符类的opcintype。 + amproclefttypeamprocrighttype列的通常解释是它们标识了一个特定支持函数所支持的操作符的左右输入类型。对于某些访问方法它们和支持函数本身的输入数据类型相匹配,而对其他的则不会匹配。对于一个索引有一个默认支持函数的概念,这些支持函数的amproclefttypeamprocrighttype都等于索引操作符类的opcintype @@ -1092,7 +1092,7 @@
atttypmod记录了在表创建时提供的类型相关数据(例如一个varchar列的最大长度)。 - 它会被传递给类型相关的输入函数和长度强制函数。对于那些不需要atttypmod的类型,这个值通常总是为-1。 + 它会被传递给类型相关的输入函数和长度强制转换函数。对于那些不需要atttypmod的类型,这个值通常为 -1。 @@ -1170,8 +1170,7 @@ atthasmissing bool
- 该列在行中完全缺失时会用到这个列的值,如果在行创建之后增加一个有非易失DEFAULT值的列,就会发生这种情况。 - 实际使用的值被存放在attmissingval列中。 + 此列有一个值,供该列在数据行中完全缺失时使用;在数据行创建之后添加带有非易失 DEFAULT 值的列时,就会出现这种情况。实际使用的值存储在 attmissingval 列中。 @@ -1201,7 +1200,7 @@ attisdropped bool
- 该列被删除且不再有效。一个删除的列仍然物理存在于表中,但是会被分析器忽略并因此无法通过SQL访问。 + 该列被删除且不再有效。一个删除的列仍然物理存在于表中,但是会被解析器忽略并因此无法通过SQL访问。 @@ -1229,7 +1228,7 @@ (引用 pg_collation.oid
- 该列被定义的排序规则,如果该列不是一个可排序数据类型则为0。 + 该列定义的排序规则;如果该列的数据类型不支持排序规则,则为零。 @@ -1252,7 +1251,7 @@ attacl aclitem[]
- 列级访问权限, 如果此列上已有特别授予的权限 + 列级访问权限,如果此列上已有特别授予的权限 @@ -1280,7 +1279,7 @@
这个列中是一个含有一个元素的数组,其中的值被用于该列在行中完全缺失时,如果在行创建之后增加一个有非易失DEFAULT值的列,就会发生这种情况。 - 只有当atthasmissing为真时才使用这个值。如果没有值则该列为空。 + 只有当atthasmissing为真时才使用这个值。如果没有值则该列为空值。 @@ -1288,9 +1287,7 @@ - 在一个被删除的列的pg_attribute的项中,atttypid被重置为0,但attlen以及其他从pg_type拷贝的域仍然有效。 - 这种安排用于处理一种情况,即被删除列的数据类型后来被删除,并且因此不再有相应的pg_type行。 - attlen和其他域可以被用来解释表的一行的内容。 + 在被删除列的 pg_attribute 条目中,atttypid 被重置为零,但 attlen 以及其他从 pg_type 复制的字段仍然有效。这种安排用于应对被删除列的数据类型后来也被删除、因而不再有相应 pg_type 行的情况。attlen 和其他字段可用于解释表中一行的内容。 @@ -1419,7 +1416,7 @@ rolconnlimit int4
- 对于可以登录的角色,本列设置该角色可以同时发起最大连接数。-1表示无限制。 + 对于可以登录的角色,本列设置该角色能够建立的最大并发连接数。-1 表示无限制。 @@ -1428,7 +1425,7 @@ rolpassword text
- 加密后的密码;如果未设置则为空。其格式取决于所使用的加密方式。 + 加密后的密码;如果未设置则为空值。其格式取决于所使用的加密方式。 @@ -1437,7 +1434,7 @@ rolvaliduntil timestamptz
- 密码过期时间(只用于密码鉴定),如果永不过期则为空 + 密码过期时间(仅用于密码认证);不设过期时间时为空值 @@ -1445,13 +1442,11 @@ - 对于一个MD5加密的密码,rolpassword列将由字符串md5后面跟上一个32字符的十六进制MD5哈希值构成。MD5哈希值将是该用户的密码串接上它们的用户名。例如,如果用户joe的密码是xyzzy,则PostgreSQL将存储xyzzyjoe的md5哈希。 + 对于一个MD5加密的密码,rolpassword列将由字符串md5后面跟上一个32字符的十六进制MD5哈希值构成。MD5 哈希值通过在用户密码后拼接用户名再计算得到。例如,如果用户joe的密码是xyzzy,则PostgreSQL将存储xyzzyjoe的md5哈希。 - - 对 MD5 加密密码的支持已被弃用,并将在未来的 PostgreSQL 发布中移除。关于迁移到其他密码类型的详细信息,请参见。 - + 对 MD5 加密密码的支持已弃用,并将在PostgreSQL的未来版本中移除。迁移到其他密码类型的详细信息见 @@ -1582,7 +1577,7 @@ SCRAM-SHA-256$<iteration count>:&l - 需要注意的是,pg_cast并不表示系统知道如何执行的所有类型转换,它只包括那些不能从某些通用规则推导出的转换。例如,一个域及其基类型之间的转换并未显式地在pg_cast中展示。另一个重要的例外是自动的基于 I/O 的类型转换,它们通过数据类型自己的 I/O 函数来转换成(或者转换自)text或其他字符串类型,这些转换也没有显式地在pg_cast中表示。 + 需要注意的是,pg_cast并不表示系统知道如何执行的所有类型转换,它只包括那些不能从某些通用规则推导出的转换。例如,一个域及其基础类型之间的转换并未显式地在pg_cast中展示。另一个重要的例外是自动的基于 I/O 的类型转换,它们通过数据类型自己的 I/O 函数来转换成(或者转换自)text或其他字符串类型,这些转换也没有显式地在pg_cast中表示。 @@ -1687,7 +1682,7 @@ SCRAM-SHA-256$<iteration count>:&l - 目录pg_class描述了具有列或与表类似的其他对象。这包括索引(但请参见pg_index)、序列(但请参见pg_sequence)、视图、物化视图、复合类型和TOAST表;请参见relkind。 + 目录pg_class描述了表以及其他具有列或在其他方面与表类似的对象。这包括索引(但请参见pg_index)、序列(但请参见pg_sequence)、视图、物化视图、复合类型和TOAST表;请参见relkind。 在下面,当我们指的是所有这些类型的对象时,我们称之为关系(relations)。并非所有pg_class的列对所有关系类型都有意义。 @@ -1739,9 +1734,7 @@ SCRAM-SHA-256$<iteration count>:&l reltype oid (引用 pg_type.oid) - - 该关系可能对应的表行类型的数据类型 OID;对索引为 0,而序列和 TOAST 表没有pg_type项 - + 与此表的行类型对应的数据类型的 OID(如有);索引、序列和 TOAST 表没有pg_type项,此值为零 @@ -1888,7 +1881,7 @@ SCRAM-SHA-256$<iteration count>:&l relpersistence char - p = 永久表/序列, u = 不记录 WAL 的表/序列, + p = 永久表/序列,u = 不记录 WAL 的表/序列, t = 临时表/序列 @@ -1983,7 +1976,7 @@ SCRAM-SHA-256$<iteration count>:&l relispopulated bool - 如果表已被填充则为真(对于所有关系该列都为真,但对于某些物化视图却不是) + 如果关系已被填充则为真(对于所有关系该列都为真,但对于某些物化视图却不是) @@ -2025,7 +2018,7 @@ SCRAM-SHA-256$<iteration count>:&l relfrozenxid xid - 在此之前的所有事务ID在表中已经被替换为一个永久的(冻结的) 事务ID。 + 在此之前的所有事务ID在表中已经被替换为一个永久的(冻结的)事务ID。 这用于跟踪表是否需要被清理,以便阻止事务ID回卷或者允许pg_xact被收缩。 如果该关系不是一个表则为0(InvalidTransactionId)。 @@ -2036,7 +2029,7 @@ SCRAM-SHA-256$<iteration count>:&l relminmxid xid - 在此之前的多事务ID在表中已经被替换为一个事务ID。这被用于跟踪表是否需要被清理,以阻止 + 在此之前的所有多事务ID在表中已经被替换为一个事务ID。这被用于跟踪表是否需要被清理,以阻止 多事务ID回卷或者允许pg_multixact被收缩。如果关系不是一个表则 为0(InvalidMultiXactId)。 @@ -2065,7 +2058,7 @@ SCRAM-SHA-256$<iteration count>:&l relpartbound pg_node_tree - 如果表示一个分区(见relispartition),则为分区边界的内部表示 + 如果表是一个分区(见relispartition),则为分区边界的内部表示 @@ -2073,9 +2066,9 @@ SCRAM-SHA-256$<iteration count>:&l
- pg_class中的一些逻辑标志被以一种懒惰的方式维护:在正确状态时它们被保证为真,但是当条件不再为真时它们并不会被立刻重置为假。 + pg_class中的一些布尔标志采用延迟维护:当条件成立时,保证它们为真;但当条件不再成立时,可能不会立即将它们重置为假。 例如,relhasindexCREATE INDEX设置,但它从不会被DROP INDEX清除。 - 作为替代,VACUUM会在找到无索引表后清除其relhasindex。 + 作为替代,VACUUM会在找到无索引表后清除其relhasindex。 这种安排避免了竞争条件并且提高了并发性。 @@ -2149,9 +2142,10 @@ SCRAM-SHA-256$<iteration count>:&l collprovider char - 排序规则提供者:d = 数据库默认值, + 排序规则提供程序:d = 数据库默认值, b = builtin,c = libc, - i = icu + i = icu + @@ -2177,7 +2171,7 @@ SCRAM-SHA-256$<iteration count>:&l collcollate text - 此排序规则对象的 LC_COLLATE。如果提供者不是 libc,则 collcollate 为 + 此排序规则对象的 LC_COLLATE。如果提供程序不是 libc,则 collcollateNULL,改用 colllocale @@ -2187,7 +2181,7 @@ SCRAM-SHA-256$<iteration count>:&l collctype text - 此排序规则对象的 LC_CTYPE。如果提供者不是 libc,则 collctype 为 + 此排序规则对象的 LC_CTYPE。如果提供程序不是 libc,则 collctypeNULL,改用 colllocale @@ -2197,7 +2191,7 @@ SCRAM-SHA-256$<iteration count>:&l colllocale text - 此排序规则对象的提供者区域设置名称。如果提供者是 libc, + 此排序规则对象的提供程序区域设置名称。如果提供程序是 libc, 则 colllocaleNULL; 改用 collcollatecollctype。 @@ -2218,7 +2212,7 @@ SCRAM-SHA-256$<iteration count>:&l collversion text - 排序规则的提供者相关的版本。这是在排序规则创建时记录下来的,并且在使用排序规则时会被检查以检测可能导致数据损坏的排序规则定义的改变。 + 提供程序特有的排序规则版本。它会在创建排序规则时记录下来,并在使用时接受检查,以检测可能导致数据损坏的排序规则定义更改。 @@ -2564,9 +2558,9 @@ SCRAM-SHA-256$<iteration count>:&l - 在一个排他约束的情况中, conkey只对约束元素是单一列引用时有用。 - 对于其他情况,conkey为0且必须查阅相关索引来发现被约束的表达式。 - (对于索引,conkey因此和pg_index.indkey具有相同的内容)。 + 对于排他约束,conkey仅对作为简单列引用的约束元素有用。 + 对于其他情况,conkey中会出现一个 0,必须查阅关联索引来确定被约束的表达式。 + (因此,conkey与该索引的 pg_index.indkey具有相同的内容。) @@ -2760,8 +2754,9 @@ SCRAM-SHA-256$<iteration count>:&l datlocprovider char - 此数据库的区域设置提供者:b = builtin, - c = libc,i = icu + 此数据库的区域设置提供程序:b = builtin, + c = libc,i = icu + @@ -2860,7 +2855,7 @@ SCRAM-SHA-256$<iteration count>:&l datlocale text - 此数据库的提供者区域设置名称。如果提供者是 libc, + 此数据库的提供程序区域设置名称。如果提供程序是 libc, 则 datlocaleNULL; 改用 datcollatedatctype。 @@ -2881,7 +2876,7 @@ SCRAM-SHA-256$<iteration count>:&l datcollversion text - 该排序规则的提供者特定版本。它会在创建数据库时记录下来,并在使用时接受检查,以检测可能导致数据损坏的排序规则定义更改。 + 提供程序特有的排序规则版本。它会在创建数据库时记录下来,并在使用时接受检查,以检测可能导致数据损坏的排序规则定义更改。 @@ -3973,7 +3968,7 @@ SCRAM-SHA-256$<iteration count>:&l indisunique bool - 如为真, 这是唯一索引 + 如为真, 这是唯一索引 @@ -3982,8 +3977,8 @@ SCRAM-SHA-256$<iteration count>:&l indnullsnotdistinct bool - 该值只用于唯一索引。如果为 false,则该唯一索引会将 null 值视为非重复值(因此索引中可以包含多个 null 值,这是 PostgreSQL 的默认行为)。 - 如果为 true,则会将 null 值视为相等(因此索引中只能包含一个 null 值)。 + 该值只用于唯一索引。如果为 false,则该唯一索引会将 null 值视为彼此不同(因此索引的某一列中可以包含多个 null 值,这是 PostgreSQL 的默认行为)。 + 如果为 true,则会将 null 值视为相等(因此索引的某一列中只能包含一个 null 值)。 @@ -4091,7 +4086,7 @@ SCRAM-SHA-256$<iteration count>:&l (引用 pg_collation.oid - 对于索引键(indnkeyatts值)中的每一列,这包含要用于该索引的排序规则的OID,如果该列不是一种可排序数据类型则为零。 + 对于索引键(indnkeyatts值)中的每一列,这包含要用于该索引的排序规则的OID,如果该列的数据类型不支持排序规则则为零。 @@ -5163,7 +5158,7 @@ SCRAM-SHA-256$<iteration count>:&l (引用 pg_collation.oid - 对于分区键中的每一个列,这个域包含要用于分区的排序规则的OID,如果该列不是一种可排序数据类型则为零。 + 对于分区键中的每一个列,这个域包含要用于分区的排序规则的OID,如果该列的数据类型不支持排序规则则为零。 @@ -6074,7 +6069,11 @@ SCRAM-SHA-256$<iteration count>:&l - rngsubopc (加上rngcollation,如果元素类型是可排序的)决定了被该范围类型所使用的排序顺序。rngcanonical用于离散类型的元素类型。rngsubdiff是可选的,但是提供它可以提高范围类型上的GiST索引性能。 + rngsubopc(如果元素类型支持排序规则,则还包括 + rngcollation)决定范围类型所用的排序顺序。 + rngcanonical用于元素类型为离散类型的情况。 + rngsubdiff是可选的,但应当提供它, + 以提高范围类型上的 GiST 索引性能。 @@ -6762,8 +6761,8 @@ SCRAM-SHA-256$<iteration count>:&l 通常,每个已分析的表列都有一个条目,其中stainherit = false。 - 如果表具有继承子项或分区,则还会创建第二个条目,其中stainherit = true。 - 此行表示继承树上列的统计信息,即您可以通过SELECT column FROM table*看到的数据的统计信息, + 如果表具有继承子表或分区,则还会创建第二个条目,其中stainherit = true。 + 此行表示继承树上列的统计信息,即你可以通过SELECT column FROM table*看到的数据的统计信息, 而stainherit = false行表示SELECT column FROM ONLY table的结果。 @@ -6772,7 +6771,7 @@ SCRAM-SHA-256$<iteration count>:&l - 因为不同类型的统计信息适用于不同类型的数据, pg_statistic 被设计成不太在意自己存储的是什么类型的统计。 只有极为常用的统计信息(比如NULL的含量)才在pg_statistic里给予专用的字段。 其它所有东西都存储在槽位中,而槽位是一组相关的列, 它们的内容用槽位中的一个列里的代码表示。 更详细的信息请参阅 src/include/catalog/pg_statistic.h。 + 由于不同种类的数据可能适合不同种类的统计信息,pg_statistic 在设计上尽量不对所存储的统计信息种类作出假定。只有极为通用的统计信息(例如空值情况)才在 pg_statistic 中有专用的列。其余统计信息都存储在槽位中。每个槽位都是一组相关的列,其内容由其中一列的代码编号来标识。更多信息见 src/include/catalog/pg_statistic.h @@ -6828,7 +6827,7 @@ SCRAM-SHA-256$<iteration count>:&l stanullfrac float4 - 列的项为空的比例 + 列中空值所占的比例 @@ -6846,8 +6845,8 @@ SCRAM-SHA-256$<iteration count>:&l stadistinct float4 - 列中非空唯一值的数目。一个大于零的值是唯一值的真正数目。 - 一个小于零的值是表中行数的乘数的负值;例如,对于一个 80% 的值为非空且每个非空值平均出现两次的列,可以表示为stadistinct = -0.4。一个0值表示唯一值的数目未知。 + 列中不同非空数据值的数量。一个大于零的值是不同值的真正数目。 + 一个小于零的值是表中行数的乘数的负值;例如,对于一个约 80% 的值为非空且每个非空值平均出现两次的列,可以表示为stadistinct = -0.4。一个0值表示不同值的数目未知。 @@ -6878,8 +6877,8 @@ SCRAM-SHA-256$<iteration count>:&l (引用 pg_collation.oid - 用于导出存储在第N槽位中的统计信息的排序规则。 - 例如,可应用排序规则列的直方图槽会显示定义数据排序顺序的排序规则。对于不可应用排序规则的数据,则为零。 + 用于生成存储在第N槽位中的统计信息的排序规则。 + 例如,支持排序规则的列的直方图槽会显示定义数据排序顺序的排序规则。对于不支持排序规则的数据,则为零。 @@ -6888,7 +6887,7 @@ SCRAM-SHA-256$<iteration count>:&l stanumbersN float4[] - 第N槽位的类型的数值类型统计, 如果该槽位不涉及数值类型则为NULL + 第N槽位中相应种类的数值统计信息;如果该槽位种类不涉及数值,则为 NULL @@ -6898,7 +6897,7 @@ SCRAM-SHA-256$<iteration count>:&l N槽位的类型的列值,如果该槽位类型不存储任何数据值则为 NULL。 - 每个数组的元素值实际上都是指定列的数据类型或者是一个相关类型(如数组元素类型), 因此,除了把这些列的类型定义成anyarray之外别无他法。 + 每个数组的元素值实际上都是指定列的数据类型或者是一个相关类型(如数组元素类型), 因此,无法把这些列的类型定义得比anyarray更具体。 @@ -7025,7 +7024,7 @@ SCRAM-SHA-256$<iteration count>:&l 统计信息对象属性中那些不是简单列引用的表达式树,以 nodeToString() 表示。 这是一个列表,每个表达式占一个元素。 - 如果所有统计信息对象属性都是简单引用,则为空。 + 如果所有统计信息对象属性都是简单引用,则为空值。 @@ -7034,8 +7033,8 @@ SCRAM-SHA-256$<iteration count>:&l - pg_statistic_ext条目在CREATE STATISTICS期间完全填充,但是随后不计算实际的统计值。 - 后来ANALYZE命令计算所需的值,并在pg_statistic_ext_data目录中填充条目。 + pg_statistic_ext条目在CREATE STATISTICS期间完全填充,但此时不会计算实际的统计值。 + 后续的ANALYZE命令计算所需的值,并在pg_statistic_ext_data目录中填充条目。 @@ -7052,14 +7051,7 @@ SCRAM-SHA-256$<iteration count>:&l - 通常,每个已分析的统计对象都有一个条目,其中stxdinherit = - false。如果表具有继承子项或分区,还会创建第二个条目,其中 - stxdinherit = true。此行表示继承树上的统计对象,即, - 您将看到的数据的统计信息 - SELECT * FROM table*, - 而stxdinherit = false行 - 表示 - SELECT * FROM ONLY table的结果。 + 通常,每个已分析的统计信息对象都有一个 stxdinherit = false 的条目。如果表有继承子表或分区,还会创建第二个 stxdinherit = true 的条目。后者表示该统计信息对象在整个继承树上的统计信息,即通过 SELECT * FROM table* 看到的数据的统计信息;而 stxdinherit = false 的行表示 SELECT * FROM ONLY table 的结果。 @@ -7129,7 +7121,7 @@ SCRAM-SHA-256$<iteration count>:&l stxdmcv pg_mcv_list - MCV(最频值)列表统计信息,序列化为pg_mcv_list类型 + MCV(高频值)列表统计信息,序列化为pg_mcv_list类型 @@ -7138,7 +7130,7 @@ SCRAM-SHA-256$<iteration count>:&l stxdexpr pg_statistic[] - 每个表达式的统计信息,序列化为pg_statistic类型的数组 + 每个表达式的统计信息,序列化为pg_statistic类型的数组。 @@ -7205,7 +7197,7 @@ SCRAM-SHA-256$<iteration count>:&l subskiplsn pg_lsn - 事务的完成LSN,其更改将被跳过,如果是有效LSN;否则0/0000000。 + 若为有效 LSN,则表示要跳过其更改的事务的完成 LSN;否则为 0/0000000 @@ -7253,7 +7245,7 @@ SCRAM-SHA-256$<iteration count>:&l 控制如何处理进行中事务的流式传输: f = 不允许对进行中事务进行流式传输, - t = 将进行中事务的更改溢写到磁盘,并在事务在发布者端提交且被订阅者接收后立即应用, + t = 将进行中事务的更改溢写到磁盘,并在事务在发布者端提交且被订阅者接收后一次性应用, p = 如果可用,则直接使用并行应用工作进程应用更改(如果没有工作进程,则与 t 相同) @@ -7807,7 +7799,7 @@ SCRAM-SHA-256$<iteration count>:&l tgdeferrable bool - 如果约束触发器可推迟则为真 + 如果约束触发器可延迟则为真 @@ -7816,7 +7808,7 @@ SCRAM-SHA-256$<iteration count>:&l tginitdeferred bool - 如果约束触发器初始可推迟则为真 + 如果约束触发器初始处于延迟状态则为真 @@ -8352,7 +8344,7 @@ SCRAM-SHA-256$<iteration count>:&l 目录pg_type存储有关数据类型的信息。 - 基类型和枚举类型(标量类型)使用CREATE TYPE创建,而域使用CREATE DOMAIN创建。 + 基础类型和枚举类型(标量类型)使用CREATE TYPE创建,而域使用CREATE DOMAIN创建。 数据库中的每一个表都会有一个自动创建的复合类型,用于表示表的行结构。 也可以使用CREATE TYPE AS创建复合类型。 @@ -8438,7 +8430,7 @@ SCRAM-SHA-256$<iteration count>:&l typtype可以是: - b表示一个基类型, + b表示一个基础类型, c表示一个复合类型(例如一个表的行类型), d表示一个域, e表示一个枚举类型, @@ -8644,7 +8636,7 @@ SCRAM-SHA-256$<iteration count>:&l - e (外部的): 值可以存储在一个次要 TOAST 关系中 (如果有一个关系, 参见pg_class.reltoastrelid). + e (外部的): 值可以存储在一个次要 TOAST 关系中 (如果有一个关系, 参见pg_class.reltoastrelid). @@ -8687,7 +8679,7 @@ SCRAM-SHA-256$<iteration count>:&l typtypmod int4 - 域使用typtypmod来记录被应用于它们基类型的typmod(如果基类型不使用typmod,则为-1)。如果此类型不是一个域则为-1。 + 域使用typtypmod来记录被应用于它们基础类型的typmod(如果基础类型不使用typmod,则为-1)。如果此类型不是一个域则为-1。 @@ -8707,8 +8699,8 @@ SCRAM-SHA-256$<iteration count>:&l typcollation指定此类型的排序规则。如果类型不支持排序规则,此列为零。 - 支持排序规则的基类型在这里会有一个非零值,典型值为DEFAULT_COLLATION_OID。 - 基于可应用排序规则类型的域,如果为其指定了排序规则 OID,则它的排序规则 OID 可以不同于其基类型。 + 支持排序规则的基础类型在这里会有一个非零值,典型值为DEFAULT_COLLATION_OID。 + 基于支持排序规则的类型的域,如果为其指定了排序规则 OID,则它的排序规则 OID 可以不同于其基础类型的排序规则 OID。 diff --git a/zh/20/charset.sgml b/zh/20/charset.sgml index 578c42d0..605ce1d2 100644 --- a/zh/20/charset.sgml +++ b/zh/20/charset.sgml @@ -29,7 +29,7 @@ 区域设置支持 - locale + 区域设置 区域设置支持是指应用程序在字母表、排序、数字格式等 @@ -197,7 +197,7 @@ initdb --locale=sv_SE 以及 POSIX 风格正则表达式);区域设置既会影响大小写不敏感匹配,也会 影响字符类正则表达式中的字符分类 LIKE与区域设置 - regular expressions与区域设置 + 正则表达式与区域设置 @@ -565,10 +565,10 @@ SELECT 'N-45' < 'N-123' COLLATE mycollation5 AS result; 概念 - 从概念上讲,每个可排序数据类型的表达式都有一个排序规则。(内置的可排序 - 数据类型包括textvarcharchar。 - 用户定义的基本类型也可以标记为可排序,当然,建立在可排序数据类型之上的 - 也是可排序的。) + 从概念上讲,每个支持排序规则的数据类型的表达式都有一个排序规则。 + (内置的支持排序规则的数据类型包括textvarcharchar。 + 用户定义的基础类型也可以标记为支持排序规则,当然,建立在支持排序规则的数据类型之上的 + 也支持排序规则。) 如果表达式是列引用,则该表达式的排序规则就是该列定义的排序规则。如果表 达式是常量,则其排序规则就是该常量数据类型的默认排序规则。更复杂表达式 的排序规则则按下文所述,从其输入表达式的排序规则推导出来。 @@ -593,7 +593,7 @@ SELECT 'N-45' < 'N-123' COLLATE mycollation5 AS result; 对于函数或操作符调用,通过检查参数排序规则推导出的排序规则,会在运行时 - 用于执行指定操作。如果该函数或操作符调用的结果属于可排序数据类型,那么 + 用于执行指定操作。如果该函数或操作符调用的结果属于支持排序规则的数据类型,那么 在解析时它也会被用作该函数或操作符表达式的已定义排序规则,以便在外围表 达式需要知道其排序规则时使用。 @@ -675,7 +675,7 @@ SELECT a || b FROM test1; - 如果函数或操作符返回的是可排序数据类型,那么分配给该函数或操作符组合输 + 如果函数或操作符返回的是支持排序规则的数据类型,那么分配给该函数或操作符组合输 入表达式的排序规则,也被认为适用于其结果。因此,在 SELECT * FROM test1 ORDER BY a || 'foo'; @@ -721,8 +721,7 @@ SELECT * FROM test1 ORDER BY a || b COLLATE "fr_FR"; - 由icu提供的排序规则对象,对应于 ICU 库提供的具名整 - 理器。ICU 不支持将collatectype分开设 + 由icu提供的排序规则对象,对应于 ICU 库提供的具名排序器。ICU 不支持将collatectype分开设 置,因此二者总是相同的。此外,ICU 排序规则与编码无关,因此在一个数据库 中,某个给定名称的 ICU 排序规则始终只有一个。 diff --git a/zh/20/client-auth.sgml b/zh/20/client-auth.sgml index 8ca55469..ecf573bf 100644 --- a/zh/20/client-auth.sgml +++ b/zh/20/client-auth.sgml @@ -48,6 +48,21 @@ 请参见配置参数 。 + + 在启动时以及主服务器进程收到 SIGHUPSIGHUP 信号时,pg_hba.conf 文件会被读取。 + 如果你在运行中的系统上编辑了该文件,就需要通知 postmaster(使用 pg_ctl reload、调用 SQL 函数 pg_reload_conf(),或者使用 kill -HUP)重新读取该文件。 + + + + + 前面的说明不适用于 Microsoft Windows:在Windows上,pg_hba.conf文件中的任何更改会立即被应用到后续的新连接上。 + + + + + 系统视图pg_hba_file_rules 有助于预先测试对 pg_hba.conf 文件的修改,也可以在加载该文件没有产生预期效果时用于诊断问题。视图中 error 字段非空的行表示文件对应行存在问题。 + + pg_hba.conf 文件的一般格式是一组记录,每行一条。 空白行会被忽略,# 注释字符后面的任何文本也会被忽略。 @@ -67,7 +82,7 @@ - 一条记录可以有多种格式: + 一条记录可以有多种格式: local database user auth-method auth-options @@ -239,7 +254,7 @@ include_dir directory IP地址范围使用标准的数字表示法来指定起始地址,然后是斜杠(/)和一个CIDR掩码长度。 掩码长度表示客户端IP地址必须匹配的高位比特数。给定IP地址中右侧的比特应为零。 - IP地址、/和CIDR掩码长度之间不得有任何空格。 + IP地址、/和CIDR掩码长度之间不得有任何空白。 @@ -253,8 +268,7 @@ include_dir directory 以IPv4格式给出的条目将仅匹配IPv4连接,以IPv6格式给出的条目将仅匹配IPv6连接, - 即使所代表的地址在IPv4-in-IPv6范围内。请注意,如果系统的C库不支持IPv6地址, - 以IPv6格式给出的条目将被拒绝。 + 即使所代表的地址在IPv4-in-IPv6范围内。 @@ -276,12 +290,12 @@ include_dir directory 以点(.)开头的主机名规范匹配实际主机名的后缀。 因此,.example.com将匹配foo.example.com - (但不仅仅是example.com)。 + (但不匹配单独的example.com)。 当在pg_hba.conf中指定主机名时,应确保名称解析相对快速。 - 最好设置一个本地名称解析缓存,如nscd。 + 设置一个本地名称解析缓存可能会有帮助,如nscd。 此外,还可能希望启用配置参数log_hostname,以便在日志中看到客户端的主机名而不是 IP 地址。 @@ -293,7 +307,7 @@ include_dir directory 用户有时会想知道为什么主机名以这种看似复杂的方式处理,包括两次名称解析,其中包括对客户端IP地址的反向查找。 - 如果客户端的反向DNS条目未设置或生成了一些不良的主机名,则使用该功能会变得复杂。 + 如果客户端的反向DNS条目未设置或返回了不符合预期的主机名,则使用该功能会变得复杂。 这主要是为了效率:这样,连接尝试最多需要两次解析器查找,一次反向查找和一次正向查找。 如果某个地址存在解析器问题,那就只会成为该客户端的问题。 一个假设的替代实现只进行正向查找的情况下,在每次连接尝试期间都必须解析pg_hba.conf中提到的每个主机名。 @@ -308,7 +322,7 @@ include_dir directory 请注意,这种行为与其他流行的基于主机名的访问控制实现一致,例如 - Apache HTTP服务器和TCP包装器。 + Apache HTTP 服务器和 TCP Wrappers。 @@ -320,7 +334,7 @@ include_dir directory - 这两个字段可以用作IP地址/掩码长度 + 这两个字段可以用作IP-address/mask-length 表示法的替代方案。而不是指定掩码长度,实际掩码在一个单独的列中指定。 例如,255.0.0.0表示IPv4的CIDR掩码长度为8, 而255.255.255.255表示CIDR掩码长度为32。 @@ -379,9 +393,7 @@ include_dir directory 执行 SCRAM-SHA-256 或 MD5 认证以校验用户密码。详见 - - 对 MD5 加密密码的支持已被弃用,并将在未来版本的 PostgreSQL 中移除。关于迁移到其他密码类型的细节,请参阅 。 - + 对 MD5 加密密码的支持已弃用,并将在PostgreSQL的未来版本中移除。迁移到其他密码类型的详细信息见 @@ -505,11 +517,7 @@ include_dir directory auth-options - - - 在auth-method字段之后,可以是形如name=value的字段, - 用于指定认证方法的选项。关于哪些选项适用于哪些认证方法的详细信息见下文。 - + auth-method 字段之后,可以有一个或多个形如 name=value 的字段,用于指定认证方法的选项。下文会详细说明各认证方法有哪些可用选项。 除了下面列出的特定于方法的选项外,还有一个方法无关的认证选项 clientcert, @@ -522,7 +530,7 @@ include_dir directory - 对于任何使用客户端证书认证的记录(即使用 cert 认证方法的记录,或使用 clientcert 选项的记录),都可以通过 clientname 选项指定要匹配客户端证书凭据中的哪一部分。此选项有两个可选值。如果指定 clientname=CN,这也是默认值,则用户名将与证书的 Common Name (CN) 匹配。如果改为指定 clientname=DN,则用户名将与证书的完整 Distinguished Name (DN) 匹配。此选项通常最好与用户名映射配合使用。比较时使用的是 RFC 2253 格式的 DN。要查看以这种格式表示的客户端证书 DN,请执行 + 对于任何使用客户端证书认证的记录(即使用 cert 认证方法的记录,或使用 clientcert 选项的记录),都可以通过 clientname 选项指定要匹配客户端证书凭据中的哪一部分。此选项有两个可选值。如果指定 clientname=CN,这也是默认值,则用户名将与证书的 Common Name (CN) 匹配。如果改为指定 clientname=DN,则用户名将与证书的完整 Distinguished Name (DN) 匹配。此选项可能更适合与用户名映射配合使用。比较时使用的是 RFC 2253 格式的 DN。要查看以这种格式表示的客户端证书 DN,请执行 openssl x509 -in myclient.crt -noout -subject -nameopt RFC2253 | sed "s/^subject=//" @@ -564,25 +572,7 @@ openssl x509 -in myclient.crt -noout -subject -nameopt RFC2253 | sed "s/^subject 由 @ 构造引用的文件会被读取为名称列表,其中的名称可以用空白或逗号分隔。注释仍然用 # 引入,与 pg_hba.conf 中相同,并且允许嵌套的 @ 构造。除非 @ 后面的文件名是绝对路径,否则它会被视为相对于引用它的文件所在目录。 - - 因为每一次连接尝试都会顺序地检查pg_hba.conf记录,所以这些记录的顺序是非常关键的。通常,靠前的记录有比较严的连接匹配参数和比较弱的认证方法,而靠后的记录有比较松的匹配参数和比较强的认证方法。 例如,我们希望对本地 TCP/IP 连接使用trust认证,而对远程 TCP/IP 连接要求密码。在这种情况下为来自于 127.0.0.1 的连接指定trust认证的记录将出现在为一个更宽范围的客户端 IP 地址指定密码认证的记录前面。 - - - - 在启动以及主服务器进程收到SIGHUPSIGHUP信号时,pg_hba.conf文件会被读取。 - 如果你在活动的系统上编辑了该文件,你将需要通知 postmaster(使用pg_ctl reload,调用SQL函数pg_reload_conf(),或使用kill -HUP)使其重新读取该文件。 - - - - - - 前面的说明在Microsoft Windows上不为真:在Windows上,pg_hba.conf文件中的任何更改会立即被应用到后续的新连接上。 - - - - - 系统视图pg_hba_file_rules 有助于预先测试对 pg_hba.conf 文件的修改,也可以在加载该文件没有产生预期效果时用于诊断问题。视图中 error 字段非空的行表示文件对应行存在问题。 - + 由于每次连接尝试都会按顺序检查 pg_hba.conf 记录,因此记录的顺序很重要。通常,靠前的记录使用较严格的连接匹配条件和较弱的认证方法,靠后的记录使用较宽松的匹配条件和较强的认证方法。例如,可能希望对本地 TCP/IP 连接使用 trust 认证,而要求远程 TCP/IP 连接提供密码。此时,为来自 127.0.0.1 的连接指定 trust 认证的记录,应放在为更大范围的允许客户端 IP 地址指定密码认证的记录之前。 @@ -591,9 +581,7 @@ openssl x509 -in myclient.crt -noout -subject -nameopt RFC2253 | sed "s/^subject - - 中展示了pg_hba.conf项的一些示例。不同认证方法的详情请见下一节。 - + 展示了一些 pg_hba.conf 条目示例。有关不同认证方法的详细信息,参见下一节。 @@ -601,8 +589,8 @@ openssl x509 -in myclient.crt -noout -subject -nameopt RFC2253 | sed "s/^subject # 允许本地系统上的任何用户 -# 通过 Unix 域套接字以任意 -# 数据库用户名连接到任意数据库(本地连接的默认值)。 +# 通过 Unix 域套接字(本地连接的默认方式)以任意 +# 数据库用户名连接到任意数据库。 # # TYPE DATABASE USER ADDRESS METHOD local all all trust @@ -647,7 +635,7 @@ host postgres all 192.168.93.0/24 ident # TYPE DATABASE USER ADDRESS METHOD host postgres all 192.168.12.10/32 scram-sha-256 -# 如果用户的密码被正确提供,允许 example.com 中主机上 +# 如果用户的密码被正确提供,允许 example.com 域中主机上 # 的任意用户连接到任意数据库。 # # 为大部分用户要求SCRAM认证,但是用户'mike'是个例外, @@ -658,7 +646,7 @@ host all mike .example.com md5 host all all .example.com scram-sha-256 # 如果没有前面的 "host" 行,这三行 -# 将拒绝所有来自 192.168.54.1的连接(因为那些项将首先被匹配), +# 将拒绝所有来自 192.168.54.1的连接(因为该条目将首先被匹配), # 但是允许来自互联网其他任何地方的 # GSSAPI 加密连接。零掩码表示不会考虑主机 IP 地址中的任何位, # 因此它会匹配任意主机。未加密的 GSSAPI 连接 @@ -673,7 +661,7 @@ host all all 192.168.12.10/32 gss # 允许来自 192.168.x.x 主机的用户连接到任意数据库,如果它们能够 # 通过 ident 检查。例如,假设 ident说用户是 "bryanh" 并且他要求以 # PostgreSQL 用户 "guest1" 连接,如果在 pg_ident.conf 有一个映射 -# "omicron" 的选项说 "bryanh" 被允许以 "guest1" 连接,则该连接将被允许。 +# "omicron" 的条目表明 "bryanh" 被允许以 "guest1" 连接,则该连接将被允许。 # # TYPE DATABASE USER ADDRESS METHOD host all all 192.168.0.0/16 ident map=omicron @@ -730,6 +718,18 @@ local db1,db2,@demodbs all scram-sha-256 与 pg_hba.conf 一样,此文件中的各行也可以是 include 指令,并遵循相同的规则。 + + 在启动时以及主服务器进程收到 SIGHUPSIGHUP 信号时,pg_ident.conf 文件会被读取。 + 如果你在运行中的系统上编辑了该文件,就需要通知 postmaster(使用 pg_ctl reload、调用 SQL 函数 pg_reload_conf(),或者使用 kill -HUP)重新读取该文件。 + + + + 系统视图 + pg_ident_file_mappings + 可以帮助预先测试对pg_ident.conf文件的更改,或者在加载文件后未产生预期效果时诊断问题。 + 视图中具有非空error字段的行表示文件相应行中存在问题。 + + 对于给定的一个操作系统用户可以对应多少个数据库用户,没有任何限制,反之亦然。因此,映射中的条目应理解为该操作系统用户被允许以该数据库用户身份连接,而不是意味着两者等价。只要存在任何一条映射项把外部认证系统获得的用户名与用户请求连接时使用的数据库用户名配对起来,该连接就会被允许。值 all 还可以用作 database-username,表示只要 system-username 匹配,该用户就被允许以任意现有数据库用户身份登录。若给 all 加上引号,则它会失去该特殊含义。 @@ -758,18 +758,6 @@ mymap /^(.*)@otherdomain\.com$ guest - - 在启动时以及主服务器进程收到 SIGHUPSIGHUP 信号时,pg_ident.conf 文件会被读取。 - 如果你在运行中的系统上编辑了该文件,就需要通知 postmaster(使用 pg_ctl reload、调用 SQL 函数 pg_reload_conf(),或者使用 kill -HUP)重新读取该文件。 - - - - 系统视图 - pg_ident_file_mappings - 可以帮助预先测试对pg_ident.conf文件的更改,或者在加载文件后未产生预期效果时诊断问题。 - 视图中具有非空error字段的行表示文件相应行中存在问题。 - - 展示了一个可与 中的 pg_hba.conf 文件配合使用的 pg_ident.conf 文件。在这个示例中,任何登录到 192.168 网络中某台机器上的用户,如果其操作系统用户名不是 bryanhannrobert,都不会被授予访问权限。Unix 用户 robert 只有在尝试以 PostgreSQL 用户 bob 身份连接时才被允许访问,而不能以 robert 或其他身份连接。ann 只能以 ann 身份连接。用户 bryanh 则可以以 bryanhguest1 身份连接。 @@ -863,7 +851,7 @@ omicron bryanh guest1 - Peer 认证通常适用于本地连接,不过在某些情况下,信任认证也可能已经足够。 + 通常建议对本地连接使用 Peer 认证,不过在某些情况下,信任认证也可能已经足够。 密码认证是远程连接最容易采用的选择。 其余所有选项都需要某种外部安全基础设施(通常是认证服务器,或用于签发 SSL 证书的证书颁发机构),或者属于平台特定功能。 @@ -882,16 +870,14 @@ omicron bryanh guest1 - trust认证对于单用户工作站的本地连接是非常合适和方便的。通常它本身适用于一台多用户机器。不过,只要你利用文件系统权限限制了对服务器的 Unix 域套接字文件的访问,即使在多用户机器上,你也可以使用trust。 要做这些限制,你可以设置中描述的unix_socket_permissions配置参数(可能还有unix_socket_group)。 或者你可以设置unix_socket_directories配置参数来把 Unix 域套接字文件放在一个经过恰当限制的目录中。 + trust认证对于单用户工作站的本地连接是非常合适和方便的。通常它本身适用于一台多用户机器。不过,只要你利用文件系统权限限制了对服务器的 Unix 域套接字文件的访问,即使在多用户机器上,你也可能可以使用trust。 要做这些限制,你可以设置中描述的unix_socket_permissions配置参数(可能还有unix_socket_group)。 或者你可以设置unix_socket_directories配置参数来把 Unix 域套接字文件放在一个经过恰当限制的目录中。 设置文件系统权限只能有助于 Unix 套接字连接。本地 TCP/IP 连接不会被文件系统权限限制。因此,如果你想利用文件系统权限来控制本地安全,那么从pg_hba.conf中移除host ... 127.0.0.1 ...行,或者把它改为一个非trust认证方法。 - - 如果通过指定trustpg_hba.conf行让你信任每一个被允许连接到服务器的机器上的用户,trust认证只适合 TCP/IP 连接。为任何不是来自localhost(127.0.0.1)的 TCP/IP 连接使用trust很少是合理的。 - + 只有当你信任由 pg_hba.conf 中指定 trust 的行所允许连接的每台机器上的每个用户时,trust 认证才适合用于 TCP/IP 连接。对来自 localhost(127.0.0.1)以外的任何 TCP/IP 连接使用 trust,通常都不合理。 @@ -936,17 +922,13 @@ omicron bryanh guest1 md5 - - 方法md5使用一种自定义的安全性较低的挑战-响应机制。它能防止密码嗅探并且防止密码在服务器上以明文存储,但是无法保护攻击者想办法从服务器上窃取了密码哈希的情况。此外,现在认为MD5哈希算法对于确定攻击已经不再安全。 - + 方法md5使用一种自定义的、安全性较低的挑战-响应机制。它能防止密码嗅探,并避免在服务器上以明文存储密码;但如果攻击者设法从服务器上窃取了密码哈希,它就无法提供保护。此外,如今已不再认为 MD5 哈希算法能抵御有决心的攻击者。 为了简化从md5方法到较新的SCRAM方法的转变,如果在pg_hba.conf中指定了md5但是用户在服务器上的密码是为SCRAM(见下文)加密的,则将自动选择基于SCRAM的认证。 - - 对 MD5 加密密码的支持已被弃用,并将在未来版本的 PostgreSQL 中移除。关于迁移到其他密码类型的细节,请参阅下文。 - + 对 MD5 加密密码的支持已弃用,并将在PostgreSQL的未来版本中移除。迁移到其他密码类型的详细信息见下文。 @@ -971,7 +953,7 @@ omicron bryanh guest1 - 要把现有安装从 md5 升级到 scram-sha-256,需要先确保所有正在使用的客户端库都足够新并支持 SCRAM,然后在 postgresql.conf 中设置 password_encryption = 'scram-sha-256',要求所有用户重新设置密码,并将 pg_hba.conf 中的认证方法说明改为 scram-sha-256。 + 要把现有安装从 md5 升级到 scram-sha-256,需要先确保所有正在使用的客户端库都足够新并支持 SCRAM,然后在 postgresql.conf 中设置 password_encryption = 'scram-sha-256',要求所有用户重新设置密码,并将 pg_hba.conf 中的认证方法设置改为 scram-sha-256 @@ -1035,7 +1017,7 @@ omicron bryanh guest1 keytab 文件用 Kerberos 软件生成;详见 Kerberos 文档。 - 下面展示了用 MIT 兼容的 Kerberos 5 实现的kadmin来做这个的示例: + 下面的示例展示了如何使用 MIT Kerberos 的 kadmin 工具生成该文件: kadmin% addprinc -randkey postgres/server.my.domain.org kadmin% ktadd -k krb5.keytab postgres/server.my.domain.org @@ -1125,7 +1107,7 @@ omicron bryanh guest1 如果设为 1,则会在 include_realm 选项中使用域的 SAM 兼容名称(也称为 NetBIOS 名称)。这是默认值。如果设为 0,则会使用 Kerberos 用户主体名中的真实 realm 名称。 - 不要禁用这个选项,除非你的服务器运行在一个域账号(这包括一个域成员系统上的虚拟服务账号)下并且所有通过 SSPI 认证的所有客户端也在使用域账号,否则认证将会失败。 + 不要禁用这个选项,除非你的服务器运行在一个域账号(这包括一个域成员系统上的虚拟服务账号)下并且所有通过 SSPI 认证的客户端也在使用域账号,否则认证将会失败。 @@ -1190,7 +1172,7 @@ omicron bryanh guest1 map - 允许在系统用户和数据库用户名称之间进行映射。详细信息请参见。 + 允许在系统用户名和数据库用户名之间进行映射。详见 @@ -1213,7 +1195,7 @@ omicron bryanh guest1
RFC 1413 - 标识协议的本意不是作为一种认证或访问控制协议。 + 标识协议的本意不是作为一种授权或访问控制协议。
@@ -1242,7 +1224,7 @@ omicron bryanh guest1 map - 允许在系统用户和数据库用户名称之间进行映射。详细信息请参见。 + 允许在系统用户名和数据库用户名之间进行映射。详见 @@ -1298,8 +1280,7 @@ omicron bryanh guest1 ldapscheme - 设置为ldaps以使用LDAPS。这是一种非标准的使用LDAP - 进行SSL加密的方式,受一些LDAP服务器实现支持。另请参阅ldaptls + 设置为ldaps以使用LDAPS。这是一种非标准的通过 SSL 使用 LDAP 的方式,受一些LDAP服务器实现支持。另请参阅ldaptls 选项作为替代。 @@ -1387,21 +1368,23 @@ omicron bryanh guest1 + + + + 以下选项提供了另一种写法,可以用更紧凑、标准的形式表示上述部分 LDAP 选项: ldapurl 一个RFC 4516 - LDAP URL。这是以更紧凑和标准形式编写其他LDAP选项的替代方式。格式为 + LDAP URL。格式为 ldap[s]://host[:port]/basedn[?[attribute][?[scope][?[filter]]]] scope必须是baseonesub中的一个,通常是最后一个。(默认为base,在此应用中通常无用。)attribute可以指定单个属性,此时将用作ldapsearchattribute的值。如果attribute为空,则filter可用作ldapsearchfilter的值。 - - URL方案ldaps选择了通过SSL进行LDAP连接的LDAPS方法,相当于使用ldapscheme=ldaps。要使用StartTLS操作进行加密LDAP连接,请使用正常的URL方案ldap并另外指定ldaptls选项。 - + URL 方案 ldaps 会选择 LDAPS 方法,通过 SSL 建立 LDAP 连接,等同于使用 ldapscheme=ldaps。要通过 StartTLS 操作使用加密的 LDAP 连接,请使用普通的 URL 方案 ldap,并在 ldapurl 之外指定 ldaptls 选项。 对于非匿名绑定,必须将ldapbinddnldapbindpasswd指定为单独的选项。 @@ -1412,8 +1395,7 @@ ldap[s]://host[:port]/ - - + 将简单绑定选项与搜索+绑定选项混用是错误的。若要在简单绑定模式下使用 ldapurl,该 URL 中不能包含 basedn 或查询元素。 @@ -1706,7 +1688,7 @@ host ... ldap ldapbasedn="dc=example,dc=net" scope - 一个以空格分隔的 OAuth scope 列表,服务器需要借此既能授权客户端,又能认证用户。合适的取值由授权服务器以及所使用的 OAuth 验证模块决定(关于验证器的更多信息,见 )。此参数为必需项。 + 一个以空格分隔的 OAuth 作用域(scope)列表,服务器需要借此既能授权客户端,又能认证用户。合适的取值由授权服务器以及所使用的 OAuth 验证模块决定(关于验证器的更多信息,见 )。此参数为必需项。 diff --git a/zh/20/config.sgml b/zh/20/config.sgml index 79d3b603..96395028 100644 --- a/zh/20/config.sgml +++ b/zh/20/config.sgml @@ -53,7 +53,7 @@ 字符串: 通常值被包括在单引号内,值内部的任何单引号都需要被双写。不过,如果值是一个简单数字或者 标识符,引号通常可以被省略。 - (与 SQL 关键字匹配的值需要在某些上下文中引用。) + (与 SQL 关键字匹配的值在某些上下文中需要加引号。) @@ -72,7 +72,7 @@ 带单位的数字: 一些数字参数具有隐含单位,因为它们描述的是内存或时间量。单位可能是字节、千字节、块 - (通常为 8 千字节)、毫秒、秒或分钟。这类设置若给出不带修饰的数字值,就会使用该设置的默认单位, + (通常为 8 千字节)、毫秒、秒或分钟。这类设置若给出不带单位的数字值,就会使用该设置的默认单位, 可以通过 pg_settings.unit 了解该默认单位。为了方便, 也可以显式指定单位,例如把时间值写成 '120 ms',系统会将其转换为该参数的实际单位。 注意,要使用这一特性,值必须写成字符串(带引号)。单位名称区分大小写,并且数字值与单位之间可以有空白。 @@ -192,14 +192,14 @@ shared_buffers = 128MB - ALTER DATABASE命令允许针对一个数据库覆盖其全局设置。 + ALTER DATABASE命令允许针对各个数据库覆盖全局设置。 - ALTER ROLE命令允许用用户指定的值来覆盖全局设置和数据库设置。 + ALTER ROLE命令允许用针对特定用户设置的值来覆盖全局设置和数据库设置。 @@ -274,7 +274,7 @@ UPDATE pg_settings SET setting = reset_val WHERE name = 'configuration_parameter 通过 Shell 影响参数 - 除了在数据库或者角色层面上设置全局默认值或者进行覆盖,你还可以通过 shell 工具把设置 + 除了设置全局默认值或在数据库、角色级别覆盖默认值之外,你还可以通过 shell 工具把设置 传递给PostgreSQL。服务器和libpq 客户端库都能通过 shell 接受参数值。 @@ -283,8 +283,7 @@ UPDATE pg_settings SET setting = reset_val WHERE name = 'configuration_parameter - 在服务器启动期间,可以通过命令行参数把参数设置传递给 - postgres命令。例如: + 在服务器启动期间,可以通过 命令行参数或其等效形式 ,把参数设置传递给 postgres 命令。例如: postgres -c log_connections=all --log-destination='syslog' @@ -299,7 +298,7 @@ postgres -c log_connections=all --log-destination='syslog' 当通过libpq启动一个客户端会话时,可以使用PGOPTIONS 环境变量指定参数设置。这种方式建立的设置构成了会话生存期间的默认值,但是不会影响 其他的会话。由于历史原因,PGOPTIONS的格式和启动 - postgres命令时用到的相似,特别是标志必须被指定。 + postgres命令时用到的相似,具体来说,必须指定 ,或在参数名称前加上 --。 例如: env PGOPTIONS="-c geqo=off --statement-timeout=5min" psql @@ -346,7 +345,7 @@ include 'filename' 还有一个 include_if_exists 指令,其行为与 include 相同, 但在被引用文件不存在或无法读取时有所不同。普通的 include 会将其视为错误, - 而 include_if_exists 只会记录一条消息并继续处理引用配置文件。 + 而 include_if_exists 只会记录一条消息并继续处理引用它的配置文件。 @@ -357,21 +356,21 @@ include 'filename' postgresql.conf 文件也可以包含 include_dir 指令, 用来指定一个应被包含的配置文件目录。其用法如下: - include_dir 'directory' - - 非绝对目录名会被解释为相对于引用配置文件所在目录的路径。在指定目录中, +include_dir 'directory' + + 非绝对目录名会被解释为相对于引用它的配置文件所在目录的路径。在指定目录中, 只有名称以 .conf 结尾的非目录文件才会被包含。以 . 开头的文件名也会被忽略,以避免在某些平台上误处理隐藏文件。包含目录中的多个文件会按文件名顺序处理 (依据 C 区域规则排序,即数字在字母之前,大写字母在小写字母之前)。 - 包括文件或目录可以被用来在逻辑上分隔数据库配置的各个部分,而不是用一个很大的postgresql.conf文件。 + 包含文件或目录可以用来在逻辑上分隔数据库配置的各个部分,而不是用一个很大的postgresql.conf文件。 考虑一个有两台数据库服务器的公司,每一个都有不同的内存量。 - 很可能配置的元素都会被共享,例如用于日志的参数。但是两者关于内存的参数将会不同。 + 两者很可能会共享部分配置,例如日志设置。但是两者关于内存的参数将会不同。 并且还可能会有服务器相关的自定义。 一种管理这类情况的方法是将你的站点的自定义配置修改分成三个文件。 - 你可以把下面的内容加入到你的postgresql.conf文件末尾来包括它们: + 你可以把下面的内容加入到你的postgresql.conf文件末尾来包含它们: include 'shared.conf' include 'memory.conf' @@ -432,7 +431,7 @@ include_dir 'conf.d' - 指定用于数据存储的目录。这个选项只能在服务器启动时设置。 + 指定用于数据存储的目录。这个参数只能在服务器启动时设置。 @@ -483,16 +482,14 @@ include_dir 'conf.d' - hosts_file (string) hosts_file配置参数 - - 指定用于基于主机的 SSL 配置的配置文件(通常叫pg_hosts.conf)。这个参数只能在服务器启动时设置。另见。 + 指定基于主机的 SSL 配置文件(通常称为 pg_hosts.conf)。此参数只能在服务器启动时设置。另请参见 @@ -507,7 +504,7 @@ include_dir 'conf.d' - 指定可被服务器创建的用于管理程序的额外进程 ID(PID)文件。这个参数只能在服务器启动的时候设置。 + 指定服务器应创建的额外进程 ID(PID)文件的名称,供服务器管理程序使用。这个参数只能在服务器启动的时候设置。 @@ -518,15 +515,15 @@ include_dir 'conf.d' - 如果你想把配置文件放在别的地方而不是数据目录中,那么postgres 命令行选项或者环境变量PGDATA必须指向包含配置文件的目录,并且postgresql.conf中(或者命令行上)的data_directory参数必须显示数据目录实际存放的地方。请注意,data_directory将覆盖PGDATA指定的数据目录位置,但是不覆盖配置文件的位置。 + 如果你想把配置文件放在别的地方而不是数据目录中,那么postgres 命令行选项或者环境变量PGDATA必须指向包含配置文件的目录,并且postgresql.conf中(或者命令行上)的data_directory参数必须设置为数据目录的实际位置。请注意,data_directory将覆盖PGDATA指定的数据目录位置,但是不覆盖配置文件的位置。 - 如果你愿意,可以使用选项config_filehba_fileident_file和/或hosts_file单独指定配置文件名称和位置。config_file只能在postgres命令行上指定,但是其他文件可以在主配置文件中设置。如果所有四个参数外加data_directory被显式地设置,则不必指定PGDATA。 + 如果你愿意,可以使用选项config_filehba_fileident_file和/或hosts_file单独指定配置文件名称和位置。config_file只能在postgres命令行上指定,但是其他参数可以在主配置文件中设置。如果所有四个参数外加data_directory被显式地设置,则不必指定PGDATA - 在设置任何这些参数时,相对路径将被解释为相对于postgres启动路径的路径。 + 在设置任何这些参数时,相对路径将被解释为相对于启动 postgres 时所在目录的路径。 @@ -550,7 +547,7 @@ include_dir 'conf.d' - 指定服务器用于监听来自客户端应用程序的连接的TCP/IP地址(指服务器网卡IP地址)。 + 指定服务器用于监听来自客户端应用程序的连接的TCP/IP地址。 该值采用逗号分隔的主机名和/或数字IP地址的形式。特殊条目*对应于所有可用的IP接口。 条目0.0.0.0允许监听所有IPv4地址,::允许监听所有IPv6地址。 如果列表为空,则服务器不会在任何IP接口上监听,此时只能使用Unix域套接字进行连接。 @@ -573,11 +570,11 @@ include_dir 'conf.d' - - - 服务器监听的 TCP 端口;默认是 5432 。请注意服务器会同一个端口号监听所有的 IP 地址。这个参数只能在服务器启动时设置。 - - + + 服务器监听的 TCP 端口,默认是 5432。请注意,服务器监听的所有 IP 地址都使用同一个端口号。 + 此参数只能在服务器启动时设置。 + + @@ -600,7 +597,8 @@ include_dir 'conf.d' - 运行备库时,必须将此参数设置为大于或等于主库上的值。否则,备库上将不允许查询。 + 当运行一个备库时,你必须设置这个参数等于或大于主库上的参数。 + 否则,备库上将不允许查询。 @@ -613,20 +611,10 @@ include_dir 'conf.d' - 确定为拥有 - pg_use_reserved_connections - 角色的连接保留多少个连接。当空闲连接槽的数量大于 - , - 但小于或等于superuser_reserved_connections与 - reserved_connections之和时,新连接将只接受超级用户以及拥有 - pg_use_reserved_connections权限的角色。如果可用连接槽的数量等于或少于 - superuser_reserved_connections,则新连接只接受超级用户。 + 确定为具有 pg_use_reserved_connections 角色权限的角色保留多少个连接。当空闲连接槽的数量大于 ,但小于或等于 superuser_reserved_connectionsreserved_connections 之和时,新连接将只接受超级用户以及具有 pg_use_reserved_connections 角色权限的角色。如果可用连接槽的数量小于或等于 superuser_reserved_connections,则新连接只接受超级用户。 - 默认值为零连接。该值必须小于 - max_connections减去 - superuser_reserved_connections。 - 此参数只能在服务器启动时设置。 + 默认值为零个连接。该值必须小于 max_connections 减去 superuser_reserved_connections。此参数只能在服务器启动时设置。 @@ -644,7 +632,7 @@ include_dir 'conf.d' 决定为 PostgreSQL 超级用户连接保留多少个连接。 - 同时活跃的连接数最多始终只能达到 。当活跃并发连接数达到 + 同时活跃的连接数最多始终只能达到 。当活跃并发连接数至少达到 max_connections 减去 superuser_reserved_connections 时, 新连接将只接受超级用户。由该参数保留的连接槽是在 保留的连接槽耗尽之后,用于紧急情况的最后储备。 @@ -722,31 +710,23 @@ include_dir 'conf.d' - - 设置 Unix 域套接字的访问权限。Unix 域套接字使用普通的 Unix 文件系统权限集。这个参数值应该是数字的形式,也就是系统调用chmodumask接受的 形式(如果使用自定义的八进制格式,数字必须以一个0(零)开头)。 + 设置 Unix 域套接字的访问权限。Unix 域套接字使用通常的 Unix 文件系统权限集。参数值应是以 chmodumask 系统调用所接受格式指定的数字权限模式。(要使用惯用的八进制格式,数字必须以 0(零)开头。) - - 默认的权限是0777,意思是任何人都可以连接。合理的候选是0770(只有用户和同组的人可以访问, 又见unix_socket_group)和0700(只有用户自己可以访问)(请注意,对于 Unix 域套接字,只有写权限有麻烦,因此没有对读取和执行权限的设置和收回)。 + 默认权限是 0777,表示任何人都可以连接。合理的其他取值包括 0770(仅属主和所属组,另见 unix_socket_group)和 0700(仅属主)。(注意,对 Unix 域套接字而言,只有写权限起作用,因此设置或撤销读权限和执行权限没有意义。) - - 这个访问控制机制与中的用户认证没有关系。 + 此访问控制机制独立于 中描述的机制。 - - 这个参数只能在服务器启动时设置。 + 此参数只能在服务器启动时设置。 - - 这个参数与完全忽略套接字权限的系统无关,尤其是自版本10以上的Solaris。 - 在那些系统上,可以通过把unix_socket_directories指向一个把搜索权限 - 限制给指定用户的目录来实现相似的效果。 + 此参数对完全忽略套接字权限的系统无效,尤其是 Solaris(截至 Solaris 10)。在这些系统上,可以将 unix_socket_directories 指向一个仅向目标用户授予搜索权限的目录,以达到类似效果。 - - 抽象命名空间中的套接字没有文件权限,所以这种情况下这个设置也会被忽略。 + 抽象命名空间中的套接字没有文件权限,因此这种情况下也会忽略此设置。 @@ -759,10 +739,8 @@ include_dir 'conf.d' - - 通过Bonjour广告服务器的存在。默认值是关闭。 - 这个参数只能在服务器启动时设置。 + 启用通过 Bonjour 通告服务器存在的功能。默认值为关闭。此参数只能在服务器启动时设置。 @@ -775,11 +753,11 @@ include_dir 'conf.d' - - - 指定Bonjour服务名称。空字符串''(默认值)表示使用计算机名。 如果编译时没有打开Bonjour支持那么将忽略这个参数。这个参数只能在服务器启动时设置。 - - + + 指定 Bonjour 服务名。空字符串 ''(默认值)表示使用计算机名。 + 如果编译时未启用 Bonjour 支持,则此参数会被忽略。此参数只能在服务器启动时设置。 + + @@ -872,109 +850,23 @@ include_dir 'conf.d' - - 在运行查询时,设置检查客户端是否保持连接的可选检查的时间间隔。 - 这个检查通过轮询套接字来执行,并且在内核报告该连接关闭时,允许长时间运行的查询可以尽快中止。 + 设置查询执行期间可选的客户端连接检查的时间间隔,用于检查客户端是否仍然连接。检查通过轮询套接字执行;如果内核报告连接已经关闭,就可以更早中止长时间运行的查询。 - - 这个选项依赖于Linux、macOS、illumos和BSD家族操作系统暴露的内核事件, - 目前在其他系统上不可用。 + 此选项依赖 Linux、macOS、illumos 和 BSD 系列操作系统提供的内核事件,目前在其他系统上不可用。 - - 如果指定的值没有单位,则以毫秒为单位。 - 默认值为0,代表禁用连接检查。 - 没有连接检查,服务器将只在与套接字的下一次交互时检测连接的丢失,当它等待、接收或发送数据时。 + 如果指定值时没有单位,则以毫秒计。默认值为 0,表示禁用连接检查。如果不进行连接检查,服务器只有在下一次与套接字交互(等待、接收或发送数据)时,才会检测到连接丢失。 - - 为了让内核本身能够在包括网络故障在内的所有场景中,在已知的时间范围内可靠地检测丢失的TCP连接,它可能还需要调整操作系统的TCP保持连接设置, - 或者PostgreSQL, 设置。 + 要让内核本身在包括网络故障在内的所有场景中,能够在确定的时间范围内可靠地检测到 TCP 连接丢失,可能还需要调整操作系统的 TCP keepalive 设置,或 PostgreSQL 设置。 - - file_copy_method (enum) - - file_copy_method配置参数 - - - - - 指定用于复制文件的方法。可能的值包括 COPY(默认)和 - CLONE(如果操作系统支持)。 - - - 此参数会影响: - - - - - CREATE DATABASE ... STRATEGY=FILE_COPY - - - - - ALTER DATABASE ... SET TABLESPACE ... - - - - - CLONE 使用 copy_file_range()(Linux、FreeBSD) - 或 copyfile(macOS)系统调用,让内核有机会共享磁盘块, - 或把工作下推到某些文件系统的较低层。 - - - - - file_extend_method (enum) - - file_extend_method配置参数 - - - - - 指定在诸如COPY这类批量操作期间扩展数据文件时所使用的方法。 - 默认会根据操作系统选择第一个可用选项: - - - - posix_fallocate(Unix)使用标准 POSIX 接口分配磁盘空间,但某些系统缺少该接口。 - 如果接口存在但底层文件系统不支持,本选项会静默回退到write_zeros。 - 已知当前版本的 BTRFS 在使用该选项时会禁用压缩。 - 在提供该函数的系统上,这是默认值。 - - - - - write_zeros通过写出零字节块来扩展文件。 - 在不提供posix_fallocate函数的系统上,这是默认值。 - - - - 当数据文件扩展的块数不超过 8 个时,总是使用write_zeros方法。 - - - - - max_notify_queue_pages (integer) - - max_notify_queue_pages配置参数 - - - - - 指定 / 队列可分配页面的最大数量。 - 默认值是 1048576。对于 8 KB 页面,这允许最多消耗 8 GB 的磁盘空间。 - 此参数只能在服务器启动时设置。 - - - @@ -1025,10 +917,7 @@ include_dir 'conf.d' 详情参见 - - 对 MD5 加密密码的支持已被弃用,并将在未来的 PostgreSQL 版本中移除。 - 关于迁移到其他密码类型的细节,请参见 。 - + 对 MD5 加密密码的支持已弃用,并将在PostgreSQL的未来版本中移除。迁移到其他密码类型的详细信息见 @@ -1097,7 +986,7 @@ include_dir 'conf.d' 设置服务器的Kerberos密钥文件的位置。 - 默认为FILE:/usr/local/pgsql/etc/krb5.keytab(其中目录部分是在构建时由sysconfdir指定的;用pg_config --sysconfdir来决定)。 + 默认为FILE:/usr/local/pgsql/etc/krb5.keytab(其中目录部分是在构建时由sysconfdir指定的;可用pg_config --sysconfdir来确定该目录)。 如果这个参数被设为空字符串,它将被忽略,并且系统依赖的默认值被应用。 这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 详情请参考。 @@ -1128,10 +1017,7 @@ include_dir 'conf.d' - 设置是否应接受来自客户端的 GSSAPI 代理。默认值为off, - 这表示不会接受客户端的凭据。将其改为on会使服务器接受 - 客户端代理给它的凭据。此参数只能在postgresql.conf文件 - 或服务器命令行中设置。 + 设置是否接受客户端的 GSSAPI 委派。默认值为 off,表示不会接受客户端的凭证。将其改为 on 会使服务器接受客户端委派给它的凭证。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 @@ -1161,14 +1047,10 @@ include_dir 'conf.d' - SSL - 查看以获取有关设置SSL的更多信息。 - 用TLS协议控制传输加密的配置参数被命名为ssl,出于历史原因, - 尽管对SSL协议的支持已被弃用。 - 在这种情况下,SSLTLS可互换使用。 + 关于 SSL 的设置,参见 。虽然对 SSL 协议的支持已被弃用,但由于历史原因,用于控制 TLS 协议传输加密的配置参数仍以 ssl 命名。在此语境中,SSLTLS 这两个术语可互换使用。 @@ -1252,13 +1134,13 @@ include_dir 'conf.d' 这个目录需要用OpenSSL 命令 openssl rehashc_rehash来准备。 - 详情参阅相应文档 + 详情参阅相应文档。 - 当使用此设置时,在连接时会按需加载指定目录下的CRLs。 - 新的CRLs可以添加到该目录中,并可以立即使用。 - 这与不同,那个会导致文件中的CRL在服务器启动时间或重新加载配置时加载。 + 当使用此设置时,在连接时会按需加载指定目录下的CRL。 + 新的CRL可以添加到该目录中,并可以立即使用。 + 这与不同,那个会导致文件中的CRL在服务器启动时或重新加载配置时加载。 两个设置可以一起使用。 @@ -1362,7 +1244,7 @@ include_dir 'conf.d' - 可用的密码组细节可能会随着OpenSSL 版本变化。 + 可用的密码套件细节可能会随着OpenSSL 版本变化。 可使用命令 openssl ciphers -v 'HIGH:MEDIUM:+3DES:!aNULL'来查看当前安装的OpenSSL版本的实际细节。 注意这个列表是根据服务器密钥类型在运行时过滤过的。 @@ -1377,15 +1259,11 @@ include_dir 'conf.d' - - 指定是否使用服务器的 SSL 密码首选项,而不是用客户端的。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 - 默认值是 on。 + 指定是否使用服务器的 SSL 密码套件优先顺序,而非客户端的优先顺序。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。默认值为 on - - 老的PostgreSQL版本没有这个设置并且总是使用客户端的首选项。这个设置主要用于与那些版本 - 的向后兼容性。使用服务器的首选项通常会更好,因为服务器更可能会被合适地配置。 + PostgreSQL 9.4 之前的版本没有此设置,始终采用客户端的优先顺序。此设置主要用于与这些旧版本保持向后兼容。采用服务器的优先顺序通常更好,因为服务器更可能得到适当配置。 @@ -1417,7 +1295,7 @@ include_dir 'conf.d' prime256v1 (NIST P-256)、 secp384r1 (NIST P-384)、 secp521r1 (NIST P-521)。 - openssl ecparam -list_curves 命令可以显示可用曲线的完整列表, + openssl ecparam -list_curves 命令可以显示可用组的不完整列表, 但并非所有曲线都可用于 TLS,而且许多受支持的组名和别名并未列出。 @@ -1436,19 +1314,14 @@ include_dir 'conf.d' - - 设置要使用的最小SSL/TLS协议版本。当前的可用版本包括: TLSv1, TLSv1.1, TLSv1.2, TLSv1.3. - 旧版本的 OpenSSL 库不支持所有值;如果选择了不支持的设置将会引发错误。 - TLS 1.0之前的协议版本,也就是SSL 版本 2 and 3,总是禁用的。 + 设置要使用的最低 SSL/TLS 协议版本。当前有效值为:TLSv1TLSv1.1TLSv1.2TLSv1.3。较旧版本的 OpenSSL 库不支持所有值;如果选择了不支持的设置,就会报错。TLS 1.0 之前的协议版本,即 SSL 2 和 3,始终被禁用。 - - 默认为TLSv1.2, 在本文撰写时的行业最佳实践。 + 默认值为 TLSv1.2,符合本文撰写时的行业最佳实践。 - - 这个参数只能在postgresql.conf文件中或通过服务器命令行进行设置。 + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 @@ -1461,15 +1334,11 @@ include_dir 'conf.d' - - 设定要使用的最大SSL/TLS协议版本。 - 有效的版本为 , 添加一个空字符串,允许任何协议版本。 - 默认为允许任何版本。设置最大协议版本主要用于测试,或者某个组件在与较新的协议配合工作时出现了问题。 + 设置要使用的最高 SSL/TLS 协议版本。有效值与 相同,此外还可设为空字符串,表示允许任意协议版本。默认允许任意版本。设置最高协议版本主要用于测试,或处理某些组件无法正常配合更新协议工作的问题。 - - 这个参数只能在postgresql.conf文件中或通过服务器命令行进行设置。 + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 @@ -1482,13 +1351,11 @@ include_dir 'conf.d' - - 指定含有用于SSL密码的所谓临时DH家族的Diffie-Hellman参数的文件名。默认值为空,这种情况下将使用内置的默认DH参数。使用自定义的DH参数可以降低攻击者破解众所周知的内置DH参数的风险。可以用命令openssl dhparam -out dhparams.pem 2048创建自己的DH参数文件。 + 指定包含 Diffie-Hellman 参数的文件名,这些参数用于所谓临时 DH 系列的 SSL 密码套件。默认值为空,此时使用编译时内置的默认 DH 参数。如果攻击者破解了众所周知的内置 DH 参数,使用自定义 DH 参数可以降低由此带来的风险。可以用命令 openssl dhparam -out dhparams.pem 2048 创建自己的 DH 参数文件。 - - 这个参数只能在postgresql.conf文件中或通过服务器命令行进行设置。 + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 @@ -1501,21 +1368,17 @@ include_dir 'conf.d' - - 设置当需要一个密码(例如一个私钥)来解密SSL文件时会调用的一个外部命令。默认情况下,这个参数为空,表示使用内置的提示机制。 + 设置获取用于解密私钥等 SSL 文件的口令时要调用的外部命令。默认值为空,表示使用内置的提示机制。 - - 该命令必须将密码打印到标准输出并且以代码0退出。在该参数值中,%p被替换为一个提示字符串(要得到文字%,应该写成%%)。注意该提示字符串将可能含有空格,因此要确保加上适当的引号。如果输出的末尾有单一的新行,它会被剥离掉。 + 该命令必须将口令输出到标准输出,并以退出码 0 结束。参数值中的 %p 会被替换为提示字符串。(要表示字面值 %,应写成 %%。)提示字符串可能包含空白,因此务必正确加引号。如果输出末尾有一个换行符,会将其去掉。 - - 该命令实际上并不一定要提示用户输入一个密码。它可以从文件中读取密码、从钥匙链得到密码等等。确保选中的机制足够安全是用户的责任。 + 该命令不一定要提示用户输入口令,也可以从文件读取口令、从钥匙链获取口令等。用户应自行确保所选机制足够安全。 - - 这个参数只能在postgresql.conf文件中或通过服务器命令行进行设置。 + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 @@ -1528,20 +1391,14 @@ include_dir 'conf.d' - - 这个参数决定在配置重载期间如果一个密钥文件需要密码时,是否也调用ssl_passphrase_command设置的密码命令。 - 如果这个参数为off(默认),那么在重载期间将忽略ssl_passphrase_command,如果在此期间需要密码则SSL配置将不会被重载。 - 对于要求一个TTY(当服务器正在运行时可能是不可用的)来进行提示的命令,这种设置是合适的。 - 例如,如果密码是从一个文件中得到的,将这个参数设置为on可能是合适的。 + 此参数决定:配置重载期间,如果密钥文件需要口令,是否也调用 ssl_passphrase_command 设置的口令命令。如果此参数为 off(默认值),则重载时会忽略 ssl_passphrase_command,如果需要口令,就不会重载 SSL 配置。此设置适合需要通过 TTY 提示用户的命令,因为服务器运行期间可能无法使用 TTY。例如,如果从文件中获取口令,则适合将此参数设为 on。 - 在Windows上运行时,必须将该参数设为on, - 因为该平台采用不同的进程模型,所有连接都会触发配置重载。 + 在 Windows 上运行时,必须将此参数设为 on,因为该平台的进程模型不同,每个连接都会执行配置重载。 - - 这个参数只能在postgresql.conf文件中或通过服务器命令行进行设置。 + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 @@ -1582,22 +1439,15 @@ include_dir 'conf.d' - - 设置数据库服务器将使用的共享内存缓冲区量。默认通常是 128 兆字节(128MB),但是如果你的内核设置不支持(在initdb时决定),那么可以会更少。 - 这个设置必须至少为 128 千字节。不过为了更好的性能,通常会使用明显高于最小值的设置。 - 如果指定值时没有单位,则以块为单位,即BLCKSZ字节,通常为8kB.(BLCKSZ 的非默认值改变最小值。) - 此参数只能在服务器启动时设置。 + 设置数据库服务器用于共享内存缓冲区的内存量。默认值通常为 128 兆字节(128MB),但如果内核设置不支持,则可能更小(在 initdb 期间确定)。此设置必须至少为 128 千字节。不过,要获得良好性能,通常需要远高于该最小值的设置。如果指定值时没有单位,则以块为单位,即 BLCKSZ 字节,通常为 8kB。(BLCKSZ 的非默认值会改变该最小值。)此参数只能在服务器启动时设置。 - - 如果有一个专用的 1GB 或更多内存的数据库服务器,一个合理的shared_buffers开始值是系统内存的 25%。即使更大的shared_buffers有效,也会造成一些工作负载, 但因为PostgreSQL同样依赖操作系统的高速缓冲区,将shared_buffers设置为超过 40% 的RAM不太可能比一个小点值工作得更好。为了能把对写大量新的或改变的数据的处理分布在一个较长的时间段内,shared_buffers更大的设置通常要求对max_wal_size也做相应增加。 + 如果专用数据库服务器具有 1GB 或更多内存,shared_buffers 的合理初始值是系统内存的 25%。对于某些工作负载,将 shared_buffers 设得更大也有效,但由于 PostgreSQL 同时依赖操作系统缓存,将超过 40% 的内存分配给 shared_buffers 不太可能比更小的值效果更好。将 shared_buffers 设得更大时,通常还需要相应增加 max_wal_size,以便将大量新数据或已修改数据的写入过程分散到更长的时间内。 - - 如果系统内存小于 1GB,一个较小的 RAM 百分数是合适的,这样可以为操作系统留下足够的空间。 + 对于内存少于 1GB 的系统,适合使用更小的内存比例,以便为操作系统留出足够空间。 - @@ -1611,7 +1461,7 @@ include_dir 'conf.d' - 控制是否为主共享内存区域请求巨型页。有效值是try(默认)、on以及off。该参数只能在服务器启动时设置。如果huge_pages被设置为try,则服务器将尝试请求巨型页,但是如果失败会退回到默认的方式。如果为on,请求巨型页失败将使得服务器无法启动。如果为off,则不会请求巨型页。 + 控制是否为主共享内存区域请求巨型页。有效值是try(默认)、on以及off。该参数只能在服务器启动时设置。如果huge_pages被设置为try,则服务器将尝试请求巨型页,但是如果失败会退回到默认的方式。如果为on,请求巨型页失败将使得服务器无法启动。如果为off,则不会请求巨型页。实际是否使用巨型页由服务器变量 表示。 @@ -1620,19 +1470,19 @@ include_dir 'conf.d' - 巨型页面的使用会导致更小的页面表以及花费在内存管理上的 CPU 时间更少,从而提高性能。更多有关Linux上使用巨型页面的细节请见。 + 巨型页的使用会导致更小的页表以及花费在内存管理上的 CPU 时间更少,从而提高性能。更多有关Linux上使用巨型页的细节请见 巨型页在Windows上被称为大页面。 要使用大页面,需要为运行PostgreSQL的Windows用户账号分配在内存中锁定页面的用户权限。 可以使用Windows的组策略工具(gpedit.msc)来分配用户权限在内存中锁定页面。 - 为了在命令窗口以单进程(而不是Windows服务)的方式启动数据库服务器,命令窗口必须以管理员身份运行或者禁用用户访问控制(UAC)。 + 为了在命令窗口以独立进程(而不是Windows服务)的方式启动数据库服务器,命令窗口必须以管理员身份运行或者禁用用户访问控制(UAC)。 当UAC被启用时,普通的命令窗口会在启动时收回用户权限在内存中锁定页面 - 注意这种设置仅影响主共享内存区域。Linux、FreeBSD以及Illumos之类的操作系统也能为普通内存分配自动使用巨型页(也被称为超级页或者页面),而不需要来自PostgreSQL的显式请求。在Linux上,这被称为transparent huge pagestransparent huge pages(THP,透明巨型页)。已知这种特性对某些Linux版本上的某些用户会导致PostgreSQL的性能退化,因此当前并不鼓励使用它(与huge_pages的显式使用不同)。 + 注意这种设置仅影响主共享内存区域。Linux、FreeBSD以及Illumos之类的操作系统也能为普通内存分配自动使用巨型页(也被称为超级页或者页面),而不需要来自PostgreSQL的显式请求。在Linux上,这被称为transparent huge pages透明巨型页(THP,透明巨型页)。已知这种特性对某些Linux版本上的某些用户会导致PostgreSQL的性能退化,因此当前并不鼓励使用它(与huge_pages的显式使用不同)。 @@ -1645,24 +1495,14 @@ include_dir 'conf.d' - - 控制巨型页的大小,当他们通过时。 - 默认为零 (0)。 - 当设置为0时,将使用系统默认的巨型页大小。 - 这个参数只能在服务器启动时设置。 + 控制通过 启用巨型页时所使用的页大小。默认值为零(0)。设置为 0 时,使用系统默认的巨型页大小。此参数只能在服务器启动时设置。 - - 一些现代64位服务器体系结构上常用的有效页尺寸包括: - 2MB1GB (Intel and AMD), - 16MB16GB (IBM POWER), - 还有 64kB, 2MB,32MB1GB (ARM). - 关于使用和支持的更多信息,参见。 + 现代 64 位服务器体系结构上常见的页大小包括:2MB1GB(Intel 和 AMD),16MB16GB(IBM POWER),以及 64kB2MB32MB1GB(ARM)。关于使用和支持的更多信息,参见 - - 非默认设置当前仅在Linux上支持。 + 目前只有 Linux 支持非默认设置。 @@ -1675,16 +1515,11 @@ include_dir 'conf.d' - - 为每个数据库会话设置用于临时缓冲区的最大内存.这些是仅用于访问临时表的会话本地缓冲。 - 如果指定值时没有单位,则以块为单位,即BLCKSZ字节,通常为8kB。 - 默认为8兆字节 (8MB)。(如果BLCKSZ不是8kB,则默认值按比例缩放。) - 这个设置可以在独立的会话内部被改变,但是只有在会话第一次使用临时表之前才能改变; 在会话中随后企图改变该值是无效的。 + 设置每个数据库会话用于临时缓冲区的最大内存量。这些是会话本地的缓冲区,仅用于访问临时表。如果指定值时没有单位,则以块为单位,即 BLCKSZ 字节,通常为 8kB。默认值为 8 兆字节(8MB)。(如果 BLCKSZ 不是 8kB,则默认值按比例变化。)可以在单个会话内更改此设置,但必须在该会话首次使用临时表之前更改;此后尝试更改该值,对该会话不会产生影响。 - - 一个会话将按照temp_buffers给出的限制根据需要分配临时缓冲区。如果在一个并不需要大量临时缓冲区的会话里设置一个大的数值, 其开销只是一个缓冲区描述符,或者说temp_buffers每增加一则增加大概 64 字节。不过,如果一个缓冲区被实际使用,那么它就会额外消耗 8192 字节(或者BLCKSZ字节)。 + 会话会按需分配临时缓冲区,上限为 temp_buffers。对于实际不需要很多临时缓冲区的会话,将此参数设得较大时,开销仅为 temp_buffers 每增加一就多分配一个缓冲区描述符,约为 64 字节。不过,如果实际使用了某个缓冲区,还会为它额外消耗 8192 字节(一般而言为 BLCKSZ 字节)。 @@ -1697,17 +1532,14 @@ include_dir 'conf.d' - - 设置可以同时处于prepared状态的事务的最大数目(见)。把这个参数设置 为零(这是默认设置)将禁用预备事务特性。这个参数只能在服务器启动时设置。 + 设置可同时处于预备状态的事务的最大数量(见 )。将此参数设为零(默认值)会禁用预备事务功能。此参数只能在服务器启动时设置。 - - 如果你不打算使用预备事务,可以把这个参数设置为零来防止意外创建预备事务。如果你正在使用预备事务,你将希望把max_prepared_transactions至少设置为一样大,因此每一个会话可以有一个预备事务待处理。 + 如果不打算使用预备事务,应将此参数设为零,以防意外创建预备事务。如果使用预备事务,通常应将 max_prepared_transactions 设为不小于 的值,以便每个会话都能有一个待处理的预备事务。 - - 运行备库时,必须将此参数设置为大于或等于主库上的值。否则,备库上将不允许查询。 + 运行备库时,必须将此参数设为与主库相同或更大的值。否则,备库上将不允许执行查询。 @@ -1720,24 +1552,11 @@ include_dir 'conf.d' - - 设置查询操作(如排序或哈希表)在写入临时磁盘文件之前可使用的基本最大内存量。 - 如果未指定单位,则将其视为千字节。默认值为四兆字节(4MB)。 - 请注意,复杂查询可能同时执行多个排序和哈希操作, - 每个操作通常允许在开始将数据写入临时文件之前使用此值指定的内存量。 - 此外,可能有多个正在运行的会话同时执行此类操作。 - 因此,使用的总内存量可能是work_mem值的多倍; - 在选择值时必须牢记这一事实。排序操作用于ORDER BYDISTINCT和合并连接。 - 哈希表用于哈希连接、基于哈希的聚合、记忆节点和IN子查询的基于哈希的处理。 + 设置查询操作(如排序或哈希表)在写入临时磁盘文件之前可使用的基础最大内存量。如果未指定单位,则以千字节为单位。默认值为 4 兆字节(4MB)。请注意,复杂查询可能同时执行多个排序和哈希操作,每个操作在开始向临时文件写入数据之前,通常都可以使用此值指定的内存量。此外,多个正在运行的会话也可能并发执行此类操作。因此,使用的总内存量可能是 work_mem 值的数倍;选择此值时必须考虑这一点。排序操作用于 ORDER BYDISTINCT 和归并连接。哈希表用于哈希连接、基于哈希的聚合、Memoize 节点以及基于哈希的 IN 子查询处理。 - - 基于哈希的操作通常比等效的基于排序的操作更加敏感于内存可用性。 - 哈希表的内存限制是通过将work_mem乘以 - hash_mem_multiplier来计算的。这使得 - 基于哈希的操作可以使用超过通常的work_mem基本 - 量的内存。 + 与等效的排序操作相比,基于哈希的操作通常对可用内存更敏感。哈希表的内存上限由 work_mem 乘以 hash_mem_multiplier 计算得到。因此,基于哈希的操作可以使用超过通常的 work_mem 基础量的内存。 @@ -1750,17 +1569,11 @@ include_dir 'conf.d' - - 用于计算哈希操作可以使用的最大内存量。最终限制由将work_mem乘以hash_mem_multiplier确定。 - 默认值为2.0,这使得基于哈希的操作使用通常work_mem基础量的两倍。 + 用于计算基于哈希的操作可以使用的最大内存量。最终上限由 work_mem 乘以 hash_mem_multiplier 确定。默认值为 2.0,使基于哈希的操作可以使用通常的 work_mem 基础量的两倍。 - - 考虑在查询操作频繁溢出的环境中增加hash_mem_multiplier, - 特别是当简单增加work_mem导致内存压力时(内存压力通常表现为间歇性的内存不足错误)。 - 默认设置为2.0通常在混合工作负载中有效。在已将work_mem增加到40MB或更高的环境中, - 可以考虑将设置调高至2.0-8.0或更高。 + 如果查询操作经常溢写磁盘,可以考虑增加 hash_mem_multiplier,尤其是在单纯增加 work_mem 会导致内存压力的情况下(内存压力通常表现为间歇性的内存不足错误)。对于混合工作负载,默认值 2.0 通常有效。如果 work_mem 已增加到 40MB 或更高,则将该值进一步设为 2.0 - 8.0 或更高可能有效。 @@ -1773,19 +1586,11 @@ include_dir 'conf.d' - - 指定维护操作(如 VACUUMCREATE INDEX 和 - ALTER TABLE ADD FOREIGN KEY)可使用的最大内存量。 - 如果指定值时未带单位,则按千字节解释。默认值为 64 兆字节(64MB)。 - 由于数据库会话一次只能执行一个这样的操作,而一个安装通常也不会有很多此类操作并发运行, - 因此把该值设置得明显大于 work_mem 通常是安全的。更大的设置可能改善清理和恢复数据库转储的性能。 + 指定维护操作(如 VACUUMCREATE INDEXALTER TABLE ADD FOREIGN KEY)可使用的最大内存量。如果未指定单位,则以千字节为单位。默认值为 64 兆字节(64MB)。由于一个数据库会话一次只能执行一个此类操作,而一个数据库系统通常也不会并发运行很多此类操作,因此可以安全地将该值设得远大于 work_mem。更大的设置可能改善清理和恢复数据库转储的性能。 - - 注意当自动清理运行时,可能会分配最多达这个内存的倍,因此要小心不要把该默认值设置得太高。 - 通过独立地设置可能会对控制这种情况 - 有所帮助。 + 注意,自动清理运行时,最多可能分配此内存量的 倍,因此不要将默认值设得过高。单独设置 可能有助于控制这一点。 @@ -1798,15 +1603,10 @@ include_dir 'conf.d' - - 指定每个自动清理工作者进程能使用的最大内存量。 - 如果指定值时没有单位,则以千字节为单位。 - 其默认值为 -1,表示转而使用 的值。 - 当运行在其他上下文环境中时,这个设置对VACUUM的行为没有影响。 - 这个参数只能在postgresql.conf中或者服务器命令行上设置。 + 指定每个自动清理工作进程可使用的最大内存量。如果未指定单位,则以千字节为单位。默认值为 -1,表示改用 的值。该设置不影响其他上下文中运行的 VACUUM 的行为。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 - + @@ -1817,13 +1617,7 @@ include_dir 'conf.d' - VACUUMANALYZE命令使用的缓冲区访问策略大小。 - 设置为0将允许操作使用任意数量的shared_buffers。 - 否则,有效范围是 128KB 到 16GB。如果指定的大小超过shared_buffers的 1/8, - 将被静默限制到该值。默认值为 2MB。如果未指定单位,则视为千字节。 - 此参数可随时设置,并且可通过为 - 传递选项来覆盖。较高的设置可以让 - VACUUMANALYZE运行得更快,但设置过大可能会将过多有用页面从共享缓冲区逐出。 + 指定 VACUUMANALYZE 命令使用的缓冲区访问策略的大小。设为 0 时,允许操作使用任意数量的 shared_buffers 缓冲区。否则,有效大小范围为 128 kB16 GB。如果指定的大小超过 shared_buffers 大小的 1/8,则会在不提示的情况下限制为该值。默认值为 2MB。如果未指定单位,则以千字节为单位。此参数可以随时设置。在执行 时,可以通过 选项覆盖此设置。较大的设置可能使 VACUUMANALYZE 运行得更快,但设置过大可能会将过多其他有用页面逐出共享缓冲区。 @@ -1836,13 +1630,10 @@ include_dir 'conf.d' - - 指定逻辑解码要使用的最大内存量,在将某些解码的更改写入本地磁盘之前。 - 这将限制逻辑流复制连接使用的内存量。它默认为 64 兆字节(64MB)。 - 由于每个复制连接仅使用此大小的单个缓冲区,并且安装通常不会同时具有多个此类连接(受 max_wal_senders 的限制),因此将此值设置得明显高于 work_mem是安全的,从而减少写入磁盘的解码更改数量。 + 指定逻辑解码在将部分已解码的更改写入本地磁盘之前可使用的最大内存量。它限制了流式逻辑复制连接使用的内存量。默认值为 64 兆字节(64MB)。由于每个复制连接仅使用一个此大小的缓冲区,而一个数据库系统通常不会同时有很多此类连接(受 max_wal_senders 限制),因此可以安全地将该值设得远高于 work_mem,以减少写入磁盘的已解码更改数量。 - + @@ -1855,7 +1646,7 @@ include_dir 'conf.d' 指定用于缓存pg_commit_ts内容的内存量 (参见)。如果未指定单位,则视为块, - 即BLCKSZ字节,通常为 8KB。默认值为0, + 即BLCKSZ字节,通常为 8kB。默认值为0, 这会请求shared_buffers/512,最多 1024 个块、最少 16 个块。 此参数只能在服务器启动时设置。 @@ -1872,7 +1663,7 @@ include_dir 'conf.d' 指定用于缓存pg_multixact/members内容的共享内存量 (参见)。如果未指定单位,则视为块, - 即BLCKSZ字节,通常为 8KB。默认值为 32。此参数只能在服务器启动时设置。 + 即BLCKSZ字节,通常为 8kB。默认值为 32。此参数只能在服务器启动时设置。 @@ -1887,7 +1678,7 @@ include_dir 'conf.d' 指定用于缓存pg_multixact/offsets内容的共享内存量 (参见)。如果未指定单位,则视为块, - 即BLCKSZ字节,通常为 8KB。默认值为 16。此参数只能在服务器启动时设置。 + 即BLCKSZ字节,通常为 8kB。默认值为 16。此参数只能在服务器启动时设置。 @@ -1902,7 +1693,7 @@ include_dir 'conf.d' 指定用于缓存pg_notify内容的共享内存量 (参见)。如果未指定单位,则视为块, - 即BLCKSZ字节,通常为 8KB。默认值为 16。此参数只能在服务器启动时设置。 + 即BLCKSZ字节,通常为 8kB。默认值为 16。此参数只能在服务器启动时设置。 @@ -1917,7 +1708,7 @@ include_dir 'conf.d' 指定用于缓存pg_serial内容的共享内存量 (参见)。如果未指定单位,则视为块, - 即BLCKSZ字节,通常为 8KB。默认值为 32。此参数只能在服务器启动时设置。 + 即BLCKSZ字节,通常为 8kB。默认值为 32。此参数只能在服务器启动时设置。 @@ -1932,7 +1723,7 @@ include_dir 'conf.d' 指定用于缓存pg_subtrans内容的共享内存量 (参见)。如果未指定单位,则视为块, - 即BLCKSZ字节,通常为 8KB。默认值为0, + 即BLCKSZ字节,通常为 8kB。默认值为0, 这会请求shared_buffers/512,最多 1024 个块、最少 16 个块。 此参数只能在服务器启动时设置。 @@ -1949,7 +1740,7 @@ include_dir 'conf.d' 指定用于缓存pg_xact内容的共享内存量 (参见)。如果未指定单位,则视为块, - 即BLCKSZ字节,通常为 8KB。默认值为0, + 即BLCKSZ字节,通常为 8kB。默认值为0, 这会请求shared_buffers/512,最多 1024 个块、最少 16 个块。 此参数只能在服务器启动时设置。 @@ -1967,8 +1758,8 @@ include_dir 'conf.d' 指定服务器执行栈的最大安全深度。此参数的理想设置是由内核强制执行的实际栈大小限制 - (如由ulimit -s或本地等效设置),减去大约一兆字节的安全边界。 - 需要安全边界是因为服务器中并非每个例程都检查栈深度,而只在关键的潜在递归例程中检查。 + (如由ulimit -s或本地等效设置),减去大约一兆字节的安全余量。 + 需要安全余量是因为服务器中并非每个例程都检查栈深度,而只在关键的潜在递归例程中检查。 如果未指定单位,则将其视为千字节。默认设置为两兆字节(2MB), 这是保守且不太可能引起崩溃的小值。但是,这可能太小,无法执行复杂函数。 只有超级用户和具有适当SET权限的用户才能更改此设置。 @@ -1988,12 +1779,8 @@ include_dir 'conf.d' - - 指定服务器应用于主共享内存区域的共享内存实现,包括 PostgreSQL 的共享缓冲区和其他共享数据。 - 可能的值为 mmap (对使用 mmap 分配的匿名共享内存),sysv (通过 shmget 分配的系统V 共享内存),和windows (Windows共享内存)。 - 并非在所有平台上都支持全部值;第一个被支持的选项是该平台的默认选项。 - sysv 选项不是任何平台的默认选项,通常不建议使用,因为它通常需要非默认的内核设置来允许大量的地址分配(参见 )。 + 指定服务器用于主共享内存区域的共享内存实现,该区域存放 PostgreSQL 的共享缓冲区及其他共享数据。可选值为 mmap(使用 mmap 分配的匿名共享内存)、sysv(通过 shmget 分配的 System V 共享内存)和 windows(Windows 共享内存)。并非所有平台都支持所有值;第一个受支持的选项是该平台的默认值。sysv 不是任何平台的默认选项,通常不建议使用,因为它一般需要更改内核的默认设置才能分配大量内存(见 )。此参数只能在服务器启动时设置。 @@ -2006,16 +1793,8 @@ include_dir 'conf.d' - - 指定服务器应该使用的动态共享内存实现。可能的值包括posix(使用shm_open分配的POSIX共享内存), - sysv(通过shmget分配的System V共享内存), - windows(用于Windows共享内存), - 和mmap(使用存储在数据目录中的内存映射文件模拟共享内存)。 - 并非所有平台都支持所有值;通常第一个支持的选项是该平台的默认值。 - 通常不建议使用mmap选项,因为操作系统可能会反复将修改的页面写回磁盘,增加系统I/O负载; - 但在调试时,当pg_dynshmem目录存储在RAM磁盘上,或者其他共享内存设施不可用时,可能会有用。 - 该参数只能在服务器启动时设置。 + 指定服务器应使用的动态共享内存实现。可选值为 posix(使用 shm_open 分配的 POSIX 共享内存)、sysv(通过 shmget 分配的 System V 共享内存)、windows(Windows 共享内存)、mmap(使用存放在数据目录中的内存映射文件模拟共享内存)。并非所有平台都支持所有值;第一个受支持的选项通常是该平台的默认值。mmap 不是任何平台的默认选项,通常不建议使用,因为操作系统可能会反复将修改过的页面写回磁盘,增加系统 I/O 负载;不过,在调试、将 pg_dynshmem 目录存放在 RAM 磁盘上,或其他共享内存设施不可用时,它可能有用。此参数只能在服务器启动时设置。 @@ -2028,13 +1807,8 @@ include_dir 'conf.d' - - 指定在服务器启动时将要分配给并行查询使用的内存容量。 - 当此内存区域不够用或被并发查询耗尽时,新的并行查询尝试使用dynamic_shared_memory_type配置的方法从操作系统临时分配额外的共享内存,由于内存管理开销该方法可能慢一些。 - 在启动时由min_dynamic_shared_memory分配的内存受到操作系统上所支持的huge_pages设置的影响,并且在自动管理的操作系统上更可能从较大的页面中受益。 - 默认值是0(无)。 - 该参数只能在服务器启动时设置。 + 指定服务器启动时为并行查询分配的内存量。当此内存区域不足或被并发查询耗尽时,新的并行查询会尝试使用 dynamic_shared_memory_type 配置的方法,临时向操作系统分配额外的共享内存;由于内存管理开销,这可能较慢。在支持 huge_pages 设置的操作系统上,启动时通过 min_dynamic_shared_memory 分配的内存会受到该设置的影响;在自动管理巨型页的操作系统上,这些内存也可能更容易受益于较大的页。默认值为 0(不分配)。此参数只能在服务器启动时设置。 @@ -2055,165 +1829,123 @@ include_dir 'conf.d' - - 指定进程可以用于临时文件(如排序和哈希临时文件)或保留游标的存储文件的最大磁盘空间。 - 尝试超过此限制的事务将被取消。 - 如果未指定单位,则将其视为千字节。 - -1(默认值)表示没有限制。 - 只有超级用户和具有适当SET权限的用户才能更改此设置。 + 指定一个进程可用于临时文件的最大磁盘空间,例如排序和哈希临时文件,或保留游标的存储文件。尝试超过此限制的事务将被取消。如果未指定单位,则以千字节为单位。-1(默认值)表示没有限制。只有超级用户和具有适当 SET 权限的用户才能更改此设置。 - - 这个设置约束着一个给定PostgreSQL进程在任何瞬间所使用的所有临时文件的总空间。应该注意的是,与在查询执行中在幕后使用的临时文件相反,显式临时表所用的磁盘空间被这个设置所限制。 + 此设置限制单个 PostgreSQL 进程在任意时刻使用的所有临时文件的总空间。需要注意,显式临时表所用的磁盘空间计入该上限;计入的是查询执行过程中内部使用的临时文件。 - - - - - - 内核资源使用 - - - - - max_files_per_process (integer) + + file_copy_method (enum) - max_files_per_process配置参数 + file_copy_method配置参数 - - 设置每个服务器子进程允许同时打开的最大文件数。已经在 postmaster 中打开的文件不计入此限制。默认值是一千个文件。 + 指定用于复制文件的方法。可能的值包括 COPY(默认)和 + CLONE(如果操作系统支持)。 + + + 此参数会影响: + + + + CREATE DATABASE ... STRATEGY=FILE_COPY + + + + + ALTER DATABASE ... SET TABLESPACE ... + + + - 如果内核强制实施了安全的每进程上限,你通常不必担心这个设置。但在某些平台上 - (尤其是大多数 BSD 系统),如果许多进程都尝试打开大量文件,内核可能允许单个进程打开的文件数 - 远超系统在整体上真正能够支持的数量。如果你看到打开的文件过多之类的失败, - 可以尝试减小这个设置。这个参数只能在服务器启动时设置。 + CLONE 使用 copy_file_range()(Linux、FreeBSD) + 或 copyfile(macOS)系统调用,使内核有机会在某些文件系统上共享磁盘块, + 或将工作交由更低层处理。 - - - - - - 基于代价的清理延迟 - - 在命令的执行过程中,系统维持着一个内部计数器来跟踪各种被执行的I/O操作的估算开销。当累计的代价达到一个限制(由vacuum_cost_limit指定),执行这些操作的进程将按照vacuum_cost_delay所指定的休眠一小段时间。然后它将重置计数器并继续执行。 - - - - 这个特性的出发点是允许管理员降低这些命令对并发的数据库活动产生的I/O影响。在很多情况下,VACUUMANALYZE等维护命令能否快速完成并不重要,而非常重要的是这些命令不会对系统执行其他数据库操作的能力产生显著的影响。基于代价的清理延迟提供了一种方式让管理员能够保证这一点。 - - - - 对于手动发出的VACUUM命令,该特性默认被禁用。要启用它,只要把vacuum_cost_delay变量设为一个非零值。 - - - - - - vacuum_cost_delay (floating point) - - vacuum_cost_delay配置参数 - - - - - - 当超出开销限制时进程将要休眠的时间量。如果指定值时没有单位,则以毫秒为单位。 - 其默认值为0,这将禁用基于代价的清理延迟特性。正值将启用基于代价的清理。 - - - - 在使用基于代价的清理时,vacuum_cost_delay的合适值通常很小,也许是小于1毫秒。 - 虽然vacuum_cost_delay可以被设置为毫秒级别的值,但是在较老的平台上可能无法准确地测量这种延迟。 - 在这样的平台上,增加 VACUUM的节流资源消耗在1ms以上,需要改变其他的清理开销参数。 - 尽管如此,你应该保持 vacuum_cost_delay 在平台能持续测量的情况下尽可能小;大延迟没有帮助。 - - - - - - - vacuum_cost_page_hit (integer) - - vacuum_cost_page_hit配置参数 - - - - - - 清理一个在共享缓存中找到的缓冲区的估计代价。它表示锁住缓冲池、查找共享哈希表和扫描页内容的代价。默认值为1。 - - - - - - - vacuum_cost_page_miss (integer) - - vacuum_cost_page_miss配置参数 - - - - - - 清理一个必须从磁盘上读取的缓冲区的代价。 - 它表示锁住缓冲池、查找共享哈希表、从磁盘读取需要的块以及扫描其内容的代价。 - 默认值为2。 - - - - - - - vacuum_cost_page_dirty (integer) - - vacuum_cost_page_dirty配置参数 - - - + + file_extend_method (enum) + + file_extend_method配置参数 + + + + + 指定在诸如COPY这类批量操作期间扩展数据文件时所使用的方法。 + 默认会根据操作系统选择第一个可用选项: + + + + posix_fallocate(Unix)使用标准 POSIX 接口分配磁盘空间,但某些系统缺少该接口。 + 如果接口存在但底层文件系统不支持,本选项会静默回退到write_zeros。 + 已知当前版本的 BTRFS 在使用该选项时会禁用压缩。 + 在提供该函数的系统上,这是默认值。 + + + + + write_zeros通过写入全零数据块来扩展文件。 + 在不提供posix_fallocate函数的系统上,这是默认值。 + + + + 当数据文件扩展的块数不超过 8 个时,总是使用write_zeros方法。 + + + - - 当清理修改一个之前干净的块时需要花费的估计代价。它表示再次把脏块刷出到磁盘所需要的额外I/O。默认值为20。 - - - + + max_notify_queue_pages (integer) + + max_notify_queue_pages配置参数 + + + + + 指定 / 队列可分配页面的最大数量。 + 默认值是 1048576。对于 8 KB 页面,这允许最多消耗 8 GB 的磁盘空间。 + 此参数只能在服务器启动时设置。 + + + - + + - vacuum_cost_limit (integer) - - vacuum_cost_limit配置参数 - - - + - - 将导致清理进程休眠的累计代价。默认值为200。 - - - - + 内核资源使用 - + + - - 有些操作会保持关键性的锁,这样可以尽快完成。基于代价的清理延迟在这类操作期间不会发生。因此有可能代价会累计至大大超过指定的限制。为了防止在这种情况下的无意义的长时间延迟,实际延迟的计算方式是vacuum_cost_delay * - accumulated_balance / - vacuum_cost_limit,且最大值是vacuum_cost_delay * 4。 - - + max_files_per_process (integer) + + max_files_per_process配置参数 + + + + + 设置每个服务器子进程允许同时打开的最大文件数量。postmaster 中已经打开的文件不计入此上限。默认值为一千个文件。 + + + 如果内核强制实施了安全的每进程上限,就不必担心此设置。但在某些平台上(尤其是大多数 BSD 系统),内核允许单个进程打开的文件数量很大,如果很多进程都尝试打开这么多文件,就会远超系统实际能够支持的总量。如果遇到 Too many open files(打开的文件过多)错误,可尝试减小此设置。此参数只能在服务器启动时设置。 + + + + + 计时 @@ -2252,7 +1984,7 @@ include_dir 'conf.d' TSC TSC - 如果启用,名为 TSC 的时钟源会在测量时间间隔时使用专门的 CPU 指令;它的名字来自 x86-64 上的时间戳计数器(Time-Stamp Counter)。与读取操作系统时钟相比,这可以降低计时开销,并减少叠加在实际运行时间之上的测量误差,例如在 EXPLAIN ANALYZE 中。 + 如果启用,名为 TSC 的时钟源会在测量时间间隔时使用专门的 CPU 指令;它的名字来自 x86-64 上的 时间戳计数器(Time-Stamp Counter)。与读取操作系统时钟相比,这可以降低计时开销,并减少叠加在实际运行时间之上的测量误差,例如在 EXPLAIN ANALYZE 中。 RDTSC @@ -2268,14 +2000,14 @@ include_dir 'conf.d' - 后台写入器 - 有一个独立的服务器进程,叫做后台写入器,它的功能就是发出写(新的或修改过的)共享缓冲区的命令。 - 当干净的共享缓存数量出现不足时,后台写入器写入一些脏缓存到文件系统,并标记为干净。 - 不过,后台写入器确实会增加 I/O 的总负荷,因为虽然在每个检查点间隔中一个重复弄脏的页面可能只会写出一次,但在同一个间隔中后台写入器可能会把它写出好几次。 - 在这一小节讨论的参数可以被用于调节本地需求的行为。 + 有一个独立的服务器进程,称为后台写入器,负责写出(新的或修改过的)共享缓冲区。 + 当干净的共享缓冲区数量似乎不足时,后台写入器会将一些脏缓冲区写入文件系统,并将其标记为干净。 + 这可以降低处理用户查询的服务器进程找不到干净缓冲区、因而不得不自行写出脏缓冲区的可能性。 + 不过,后台写入器确实会使总体 I/O 负载有所增加:反复变脏的页面原本可能在每个检查点间隔中只写出一次, + 而后台写入器可能在同一间隔内随着它变脏而多次写出。本节参数可用于根据实际需求调整此行为。 @@ -2287,13 +2019,10 @@ include_dir 'conf.d' - - - 指定后台写入器活动轮次之间的延迟。在每个轮次中,写入器都会为一定数量的脏缓冲区发出写操作(可以用下面的参数控制)。 - 然后它就休眠 bgwriter_delay的时长, 然后重复动作。当缓冲池中没有脏缓冲区时,不管 bgwriter_delay,它都会进入更长的休眠。如果指定值时没有单位,则以毫秒为单位。默认值是 200 毫秒(200ms)。 - 注意在许多系统上,休眠延迟的有效解析度是 10 毫秒;因此,为bgwriter_delay设置一个 不是 10 的倍数的值与把它设置为下一个更高的 10 的倍数是一样的效果。这个选项只能在服务器命令行上或者在postgresql.conf文件中设置。 - - + + 指定后台写入器各轮活动之间的延迟。每一轮中,写入器会对一定数量的脏缓冲区发出写操作(由下面的参数控制),然后休眠 bgwriter_delay 指定的时长,再重复此过程。不过,当缓冲池中没有脏缓冲区时,它会进入更长的休眠,而不受 bgwriter_delay 限制。如果未指定单位,则以毫秒为单位。默认值为 200 毫秒(200ms)。注意,在某些系统上,休眠延迟的有效分辨率为 10 毫秒;将 bgwriter_delay 设为不是 10 的倍数的值,可能与将它设为下一个更大的 10 的倍数效果相同。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 + + @@ -2304,11 +2033,10 @@ include_dir 'conf.d' - - - 在每个轮次中,不超过这么多个缓冲区将被后台写入器写出。把这个参数设置为零可禁用后台写出(注意被一个独立、专用辅助进程管理的检查点不受影响)。默认值是 100 个缓冲区。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 - - + + 后台写入器每轮写出的缓冲区数量不会超过此值。设为零会禁用后台写入。(由另一个独立的专用辅助进程管理的检查点不受影响。)默认值为 100 个缓冲区。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 + + @@ -2319,11 +2047,10 @@ include_dir 'conf.d' - - - 每一轮次要写的脏缓冲区的数目基于最近几个轮次中服务器进程需要的新缓冲区的数目。 最近所需的平均值乘以bgwriter_lru_multiplier可以估算下一轮次中将会需要的缓冲区数目。脏缓冲区将被写出直到有很多干净可重用的缓冲区(然而,每一轮次中写出的缓冲区数不超过bgwriter_lru_maxpages)。 因此,设置为 1.0 表示一种刚刚好的策略,这种策略会写出正好符合预测值的数目的缓冲区。 更大大的值可以为需求高峰提供某种缓冲,而更小的值则需要服务进程来处理一些写出操作。默认值是 2.0。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 - - + + 每轮写出的脏缓冲区数量取决于最近几轮服务器进程所需的新缓冲区数量。将近期平均需求乘以 bgwriter_lru_multiplier,即可估算下一轮所需的缓冲区数量。写入器会写出脏缓冲区,直到可用的干净且可重用缓冲区达到这一数量。(不过,每轮写出的缓冲区数量不会超过 bgwriter_lru_maxpages。)因此,设为 1.0 表示采用恰好及时策略,写出的缓冲区数量恰好等于预测需求量。更大的值可为需求突增留出余量,而更小的值则有意将部分写操作留给服务器进程执行。默认值为 2.0。此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 + + @@ -2334,24 +2061,22 @@ include_dir 'conf.d' - - - 只要后台写入的数据超过这个数量,尝试强制 OS 把这些写发送到底层存储上。这样做将限制内核页缓存中脏数据的量,降低了在检查点末尾发出一个 fsync 时或者 OS 在后台大批量写回数据时卡住的可能性。 - 那常常会导致大幅度压缩的事务延迟,但是也有一些情况(特别是负载超过但小于 OS 页面高速缓存)的性能会降低。这种设置可能会在某些平台上没有效果。 - 如果指定值时没有单位,则以块为单位,即为BLCKSZ 字节,通常为8kB.合法的范围在0(禁用受控写回)和2MB之间。Linux 上的默认值是512kB,其他平台上是0(如果BLCKSZ不是8kB,则默认值和最大值会按比例缩放至这个值)。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 - - + + 每当后台写入器写出的数据超过此数量时,就尝试强制操作系统将这些写操作发往底层存储。这样可以限制内核页缓存中的脏数据量,降低在检查点结束时调用 fsync,或操作系统在后台以较大批次写回数据时发生停顿的可能性。通常,这能大幅降低事务延迟,但在某些情况下性能可能下降,尤其是工作负载大于 而小于操作系统页缓存时。此设置在某些平台上可能没有效果。如果未指定单位,则以块为单位,即 BLCKSZ 字节,通常为 8kB。有效范围为 0(禁用强制写回)至 2MB。Linux 上的默认值为 512kB,其他平台为 0。(如果 BLCKSZ 不是 8kB,默认值和最大值将按比例变化。)此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 + + - 较小的bgwriter_lru_maxpagesbgwriter_lru_multiplier可以降低由后台写入器造成的额外 I/O 开销。但更可能的是,服务器进程将必须自己发出写入操作,这会延迟交互式查询。 + 较小的 bgwriter_lru_maxpagesbgwriter_lru_multiplier 可以降低后台写入器造成的额外 I/O 负载, + 但也会增加服务器进程必须自行发出写操作的可能性,从而延迟交互式查询。 - 异步行为 + I/O @@ -2362,18 +2087,10 @@ include_dir 'conf.d' - - - 当单个后端写入数据的量超过这个数量时,尝试强制操作系统发送这些写入到底层存储。 - 这样做将限制内核的页面缓存中的脏数据量,降低在检查点末尾发出fsync时暂停的可能性,或者当操作系统在后台大批量的写回数据时。 - 通常的结果会大大减少事务延迟,但也有一些情况,特别是当工作负载大于,但小于操作系统的页面缓存时,性能可能会下降。 - 此设置在某些平台上可能无效。 - 如果指定此值时没有单位,则将其作为块,即BLCKSZ字节,通常为8kB。 - 有效范围在0,禁止强制回写,和2MB之间。 - 默认值是0,即没有强制回写。 - (如果BLCKSZ不是8kB,则最大值按其比例缩放。) - - + + 每当单个后端写出的数据超过此数量时,就尝试强制操作系统将这些写操作发往底层存储。这样可以限制内核页缓存中的脏数据量,降低在检查点结束时调用 fsync,或操作系统在后台以较大批次写回数据时发生停顿的可能性。通常,这能大幅降低事务延迟,但在某些情况下性能可能下降,尤其是工作负载大于 而小于操作系统页缓存时。此设置在某些平台上可能没有效果。如果未指定单位,则以块为单位,即 BLCKSZ 字节,通常为 8kB。有效范围为 0(禁用强制写回)至 2MB。默认值为 0,即不强制写回。(如果 BLCKSZ 不是 8kB,最大值将按比例变化。) + + @@ -2384,23 +2101,19 @@ include_dir 'conf.d' - - - 设置PostgreSQL预期可以同时执行的并发存储 I/O 操作数量。提高该值会增加任何单个PostgreSQL会话尝试并行发起的 I/O 操作数。允许的范围是11000,或者0表示禁用异步 I/O 请求。默认值是16。 - - - - 较高的值对高延迟存储和高 IOPS 设备影响最大,否则查询会经历明显的 I/O 停顿。不必要地设置过高,可能会增加系统中所有查询的 I/O 延迟。 - - - - 在支持预取建议的系统上,effective_io_concurrency还控制预取距离。 - - - - 对于位于特定表空间中的表,可以通过设置同名的表空间参数覆盖该值(见)。 - - + + 设置 PostgreSQL 预期可以同时执行的并发存储 I/O 操作数量。提高此值会增加单个 PostgreSQL 会话尝试并行发起的 I/O 操作数量。允许的范围为 11000,或设为 0 以禁用异步 I/O 请求。默认值为 16。 + + + 较高的值对以下存储影响最大:查询原本会出现明显 I/O 停顿的高延迟存储,以及高 IOPS 设备。不必要地设得过高,可能会增加系统中所有查询的 I/O 延迟。 + + + 在支持预取建议的系统上,effective_io_concurrency 还控制预取距离。 + + + 对于位于特定表空间中的表,可以通过设置同名的表空间参数覆盖此值(见 )。 + + @@ -2411,15 +2124,13 @@ include_dir 'conf.d' - - - 与effective_io_concurrency相似,但用于支持许多客户端会话完成的维护工作。 - - - 默认值是16。对于位于特定表空间中的表,可以通过设置同名的表空间参数覆盖该值(见)。 - - + 与 effective_io_concurrency 类似,但用于为多个客户端会话执行的维护工作。 + + + 默认值为 16。对于位于特定表空间中的表,可以通过设置同名的表空间参数覆盖此值(见 )。 + + @@ -2600,19 +2311,16 @@ include_dir 'conf.d' - - - 设置系统能够支持的后台进程的最大数量。这个参数只能在服务器启动时设置。默认值为 8。 - - - - 运行备库时,必须将此参数设置为大于或等于主库上的值。否则,备库上将不允许查询。 + + 设置集簇能够支持的后台进程的最大数量。此参数只能在服务器启动时设置。默认值为 8。 - - - 在更改这个值时,考虑也对 以及 进行调整。 - - + + 运行备库时,必须将此参数设为与主库相同或更大的值。否则,备库上将不允许执行查询。 + + + 更改此值时,也应考虑调整 、&zwsp;、&zwsp;、&zwsp;。 + + @@ -2623,19 +2331,16 @@ include_dir 'conf.d' - - - 设置单个Gather或者Gather Merge节点能够开始的工作者的最大数量。并行工作者会从建立的进程池中取得,数量由限制。注意所要求的工作者数量在运行时可能实际无法被满足。如果这种事情发生,该计划将会以比预期更少的工作者运行,这可能会不太高效。默认值是2。把这个值设置为0将会禁用并行查询执行。 - - - - 注意并行查询可能消耗比非并行查询更多的资源,因为每一个工作者进程时一个完全独立的进程,它对系统产生的影响大致和一个额外的用户会话相同。在为这个设置选择值时,以及配置其他控制资源利用的设置(例如)时,应该把这个因素考虑在内。work_mem之类的资源限制会被独立地应用于每一个工作者,这意味着所有进程的总资源利用可能会比单个进程时高得多。例如,一个使用 4 个工作者的并行查询使用的 CPU 时间、内存、I/O 带宽可能是不使用工作者时的 5 倍之多。 - - - - 并行查询的更多信息请见。 - - + + 设置单个 GatherGather Merge 节点能够启动的工作进程的最大数量。并行工作进程取自 建立的进程池,并受到 的限制。注意,运行时实际可用的工作进程可能不足请求的数量。此时,计划会使用少于预期的工作进程运行,效率可能较低。默认值为 2。设为 0 会禁用并行查询执行。 + + + 注意,并行查询消耗的资源可能远多于非并行查询,因为每个工作进程都是完全独立的进程,对系统的影响大致相当于额外增加一个用户会话。选择此设置的值,以及配置其他控制资源使用的设置(如 )时,都应考虑这一点。work_mem 等资源限制分别应用于每个工作进程,因此所有进程的总资源用量可能远高于单个进程通常的用量。例如,使用 4 个工作进程的并行查询,其 CPU 时间、内存、I/O 带宽等用量可能达到完全不使用工作进程的查询的 5 倍。 + + + 并行查询的更多信息参见 。 + + @@ -2646,18 +2351,13 @@ include_dir 'conf.d' - - - 设置单一工具性命令能够启动的并行工作者的最大数目。 - 当前,支持使用并行工作者的工具性命令是CREATE INDEX,并且只有在构建B-树索引时才能并行,并且 VACUUM 没有 FULL选项。 - 并行工作者从由创建的进程池中取出,数量由控制。 - 注意实际在运行时所请求数量的工作者可能不可用。如果发生这种情况,工具性操作将使用比预期数量少的工作者运行。默认值为2。将这个值设置为0可以禁用工具性命令对并行工作者的使用。 - - - - 注意并行工具性命令不应该消耗比同等数量非并行操作更多的内存。这种策略与并行查询不同,并行查询的资源限制通常是应用在每个工作者进程上。并行工具性命令把资源限制maintenance_work_mem当作对整个工具性命令的限制,而不管其中用到了多少个并行工作者进程。不过,并行工具性命令实际上可能仍会消耗更多的CPU资源和I/O带宽。 - - + + 设置单个工具命令能够启动的并行工作进程的最大数量。目前,支持使用并行工作进程的工具命令包括:构建 B-树、GIN 或 BRIN索引时的 CREATE INDEX,以及不带 FULL 选项的 VACUUM。并行工作进程取自 建立的进程池,并受到 的限制。注意,运行时实际可用的工作进程可能不足请求的数量。此时,工具操作会使用少于预期的工作进程运行。默认值为 2。设为 0 会禁止工具命令使用并行工作进程。 + + + 注意,并行工具命令的内存消耗不应明显高于等效的非并行操作。这与并行查询的策略不同,后者的资源限制通常分别应用于每个工作进程。并行工具命令将 maintenance_work_mem 视为整个工具命令的资源上限,而不论使用多少个并行工作进程。不过,并行工具命令仍可能消耗多得多的 CPU 资源和 I/O 带宽。 + + @@ -2668,17 +2368,14 @@ include_dir 'conf.d' - - - 设置系统为并行操作所支持的工作者的最大数量。默认值为8。 - 在增加或者减小这个值时,也要考虑对以及进行调整。 - 此外,要注意将这个值设置得大于将不会产生效果,因为并行工作者进程都是从所建立的工作者进程池中取出来的。 - - + + 设置集簇能够为并行操作提供的工作进程的最大数量。默认值为 8。增大或减小此值时,也应考虑调整 。此外,将此值设得大于 没有效果,因为并行工作进程取自该设置建立的工作进程池。 + + - + parallel_leader_participation (boolean) @@ -2686,17 +2383,12 @@ include_dir 'conf.d' - - - 允许 leader 进程在GatherGather Merge节点下参与执行查询计划,而不是仅仅等待 worker 进程。 - 默认值是on。 - 将其设置为off可以降低 worker 因 leader 读取元组速度不够快而被阻塞的可能性, - 但在生成第一条元组之前,leader 进程将需要等待 worker 进程启动。 - leader 对性能的帮助或拖累程度取决于计划类型、worker 数量以及查询持续时间。 - - + + 允许领导者进程执行 GatherGather Merge 节点下的查询计划,而不是等待工作进程。默认值为 on。将此值设置为 off,可以降低工作进程因领导者读取元组不够快而被阻塞的可能性,但在产生第一批元组之前,领导者进程必须等待工作进程启动。领导者对性能的帮助或妨碍程度取决于计划类型、工作进程数量和查询持续时间。 + + - + @@ -2727,7 +2419,7 @@ include_dir 'conf.d' - minimal级别生成最少的WAL日志量。它不记录在创建或重写事务中对永久关系的行信息。 + minimal级别生成最少的WAL日志量。对于在当前事务中创建或重写的永久关系,不记录其行信息。 这可以使操作速度更快(参见)。触发此优化的操作包括: ALTER ... SET TABLESPACE @@ -2738,15 +2430,15 @@ include_dir 'conf.d' REINDEX TRUNCATE - 然而,最小的WAL不包含足够的信息用于时点恢复,因此必须使用replica或更高级别来启用持续归档 + 然而,minimal 级别的 WAL 不包含足够的信息用于时间点恢复,因此必须使用replica或更高级别来启用持续归档 ()和流式二进制复制。 实际上,如果max_wal_senders不为零,服务器甚至不会以此模式启动。 - 请注意,将wal_level更改为minimal会使先前的基本备份无法用于时点恢复和备库。 + 请注意,将wal_level更改为minimal会使先前的基础备份无法用于时间点恢复和备库。 logical级别上,记录与replica相同的信息,以及从WAL中提取逻辑变更集所需的信息。 - 使用logical级别会增加WAL的容量,特别是如果许多表被配置为REPLICA IDENTITY FULL, + 使用logical级别会增加 WAL 的数量,特别是如果许多表被配置为REPLICA IDENTITY FULL, 并且执行了许多UPDATEDELETE语句。 @@ -2778,16 +2470,15 @@ include_dir 'conf.d' - 能安全关闭fsync的环境的示例包括从一个备份文件中初始加载一个新数据库集簇、使用一个数据库集簇来在数据库被删掉并重建之后处理一批数据,或者一个被经常重建并却不用于失效备援的只读数据库克隆。单独的高质量硬件不足以成为关闭fsync的理由。 + 可以安全关闭fsync的情形包括:从备份文件初始装载一个新数据库集簇;用数据库集簇处理一批数据,处理后就丢弃并重建该数据库;或者使用经常重建且不用于故障切换的只读数据库克隆。仅有高质量硬件不足以成为关闭fsync的理由。 - 当把fsync从关闭改成打开时,为了可靠的恢复,需要强制在内核中的所有被修改的缓冲区进入持久化存储。这可以在多个时机来完成: - 在集簇被关闭时或在fsync因为运行initdb --sync-only而打开时、运行sync时、卸载文件系统时或者重启服务器时。 + 为确保将fsync从关闭改为打开后能够可靠恢复,必须将内核中所有已修改的缓冲区强制写入持久存储。可以在集簇已关闭或fsync已开启时,通过运行initdb --sync-only、运行sync、卸载文件系统或重启服务器来完成。 - 在很多情况下,为不重要的事务关闭可以提供很多关闭fsync的潜在性能收益,并不会有的同时, 关闭fsync可以提供很多潜在的性能优势,而不会有伴随着的数据损坏风险。 + 在很多情况下,为非关键事务关闭,可以获得关闭fsync所带来的大部分潜在性能收益,同时避免伴随的数据损坏风险。 @@ -2806,44 +2497,32 @@ include_dir 'conf.d' - 指定数据库服务器返回success指示给客户端之前,必须要完成多少WAL处理。 - 合法的值为remote_apply, on(默认值), remote_write,local, 和 off。 + 指定数据库服务器向客户端返回成功指示之前,必须完成多少 WAL 处理。有效值为remote_applyon(默认值)、remote_writelocaloff - 如果synchronous_standby_names为空,则唯一有意义的设置为onoff ; - remote_applyremote_writelocal都提供与on相同的本地同步级别。 - 所有非off模式的本地行为都是等待WAL的本地刷新到磁盘。 - 在 off模式,无需等待,因此在向客户端报告成功和以后保证事务安全防止服务器崩溃之间可能会出现延迟。 - 当设置为off时,在向客户端报告成功和真正保证事务不会被服务器崩溃威胁之间会有延迟(最大的延迟是的三倍)。 - 不同于,将这个参数设置为off不会产生数据库不一致性的风险:一个操作系统或数据库崩溃可能会造成一些最近据说已提交的事务丢失,但数据库状态是一致的,就像这些事务已经被干净地中止。 - 因此,当性能比完全确保事务的持久性更重要时,关闭synchronous_commit可以作为一个有效的代替手段。更多讨论见。 + 如果synchronous_standby_names为空,只有onoff两种设置有意义;remote_applyremote_writelocal提供的本地同步级别都与on相同。所有非off模式在本地都会等待 WAL 刷写到磁盘。在off模式下则无需等待,因此,向客户端报告成功后,可能还要经过一段时间,才能保证事务不会因服务器崩溃而丢失。(最大延迟为的三倍。)与不同,将此参数设为off不会带来数据库不一致的风险:操作系统或数据库崩溃可能会使一些最近报告已提交的事务丢失,但数据库状态会与这些事务已正常中止时完全相同。因此,当性能比完全确保事务持久性更重要时,关闭synchronous_commit可以是一种有用的替代方案。更多讨论见 - 如果为非空,synchronous_commit也控制是否事务提交将等待它们的 WAL 记录在备库上被处理。 + 如果非空,synchronous_commit还控制事务提交是否等待备库处理其 WAL 记录。 - 当设置为 remote_apply 时,提交将等待,直到来自当前同步备库的答复显示他们已收到事务的提交记录并应用了它,以便它变得对备库上的查询可见,并写入备库上的持久存储。 - 这将导致比以前的设置更大的提交延迟,因为它等待 WAL 重放(replay)。 - 当设置为on时,提交将等待,直到来自于当前同步的备库的回复显示它们已经收到了事务的提交记录并将其刷入了磁盘。 - 这保证事务将不会被丢失,除非主库和所有同步备库都遭受到了数据库存储损坏的问题。 - 当这个参数被设置为remote_write时,提交将等待,直到来自当前的同步备库的回复指示它们已经收到了该事务的提交记录并且已经把该记录写到它们的文件系统,这种设置保证数据得以保存,在PostgreSQL的备库实例崩溃时,但是不能保证备库遭受操作系统级别崩溃时数据能被保持,因为数据不一定必须要在备库上达到持久存储。 - 设置local会导致提交等待本地刷写到磁盘,而不是复制。在使用同步复制时这通常是不可取的,但是为了完整性提供了这个选项。 + 设为remote_apply时,提交会等待当前同步备库回复,确认已收到并应用该事务的提交记录,使其对备库上的查询可见,并且已将其写入备库的持久存储。由于需要等待 WAL 重放,这会比之前的设置产生大得多的提交延迟。设为on时,提交会等待当前同步备库回复,确认已收到事务的提交记录,并已将其刷写到持久存储。这能保证事务不会丢失,除非主库和所有同步备库的数据库存储都损坏。设为remote_write时,提交会等待当前同步备库回复,确认已收到事务的提交记录,并已将其写入各自的文件系统。此设置能保证备库上的PostgreSQL实例崩溃时数据不丢失,但不能保证备库发生操作系统级别崩溃时数据不丢失,因为数据未必已写入备库的持久存储。设为local时,提交会等待本地刷盘,但不等待复制。使用同步复制时通常不希望采用这种设置,提供它是为了使选项完整。 - 这个参数可以随时被修改;任何一个事务的行为由其提交时生效的设置决定。因此,可以同步提交一些事务,同时异步提交其他事务。例如,当默认是相反时,实现一个单一多语句事务的异步提交,在事务中发出SET LOCAL synchronous_commit TO OFF。 + 此参数可以随时更改;每个事务的行为由提交时生效的设置决定。因此,让一些事务同步提交、另一些事务异步提交是可行且有用的。例如,当默认设置要求同步提交时,可以在一个包含多条语句的事务中执行SET LOCAL synchronous_commit TO OFF,使该事务异步提交。 - 概括了 synchronous_commit 设置的能力. + 汇总了synchronous_commit各种设置具备的能力。 - synchronous_commit Modes + synchronous_commit 模式 @@ -2853,10 +2532,10 @@ include_dir 'conf.d' - synchronous_commit setting - local durable commit - PG 崩溃备库持久提交 - OS 崩溃备库持久提交 + synchronous_commit 设置 + 本地提交持久性 + PG 崩溃后备库提交持久性 + OS 崩溃后备库提交持久性 备库查询一致性 @@ -2920,7 +2599,7 @@ include_dir 'conf.d' - 用来向强制 WAL 更新到磁盘的方法。如果fsync是关闭的,那么这个设置就不相关,因为 WAL 文件更新将根本不会被强制。可能的值是: + 用于将 WAL 更新强制写入磁盘的方法。如果fsync关闭,此设置就没有作用,因为 WAL 文件更新根本不会被强制写入磁盘。可选值为: @@ -2944,7 +2623,7 @@ include_dir 'conf.d' - fsync_writethrough(在每次提交时调用fsync(),强制任何磁盘写高速缓存的直通写) + fsync_writethrough(在每次提交时调用fsync(),强制穿透任何磁盘写缓存) @@ -2956,10 +2635,9 @@ include_dir 'conf.d' - open_* 选项也可以使用O_DIRECT(如果可用)。 不是在所有平台上都能使用所有这些选择。 - 默认值是列表中第一个被平台支持的那个, 不过fdatasync是 Linux和FreeBSD中的默认值。 - 默认值不一定是最理想的;有可能需要修改这个设置或系统配置的其他方面来创建一个崩溃-安全的配置,或达到最佳性能。 + 默认值是列表中第一个被平台支持的那个, 不过fdatasync是 Linux 和 FreeBSD 中的默认值。 + 默认值不一定最合适;可能需要更改此设置或系统配置的其他方面,以确保崩溃时的数据安全或达到最佳性能。 这些方面在中讨论。 这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 @@ -2976,11 +2654,11 @@ include_dir 'conf.d' - 当这个参数为打开时,PostgreSQL服务器在一个检查点之后的页面的第一次修改期间将每个页面的全部内容写到 WAL 中。这么做是因为在操作系统崩溃期间正在处理的一次页写入可能只有部分完成,从而导致在一个磁盘页面中混合有新旧数据。在崩溃后的恢复期间,通常存储在 WAL 中的行级改变数据不足以完全恢复这样一个页面。存储整页镜像可以保证页面被正确存储,但代价是增加了必须被写入 WAL 的数据量(因为 WAL 重放总是从一个检查点开始,所以在检查点后每个页面的第一次改变时这样做就够了。因此,一种减小全页面写开销的方法是增加检查点间隔参数值)。 + 启用此参数时,PostgreSQL服务器会在检查点之后首次修改每个磁盘页面时,将该页面的全部内容写入 WAL。这样做是因为,操作系统崩溃时正在进行的页面写入可能只完成了一部分,导致磁盘页面混有新旧数据。通常存储在 WAL 中的行级变更数据不足以在崩溃恢复时完整还原这样的页面。保存整页镜像能保证正确恢复页面,但会增加必须写入 WAL 的数据量。(由于 WAL 重放总是从检查点开始,只需在检查点之后首次修改每个页面时这样做。因此,减少整页写入开销的一种方法是增大检查点间隔参数。) - 把这个参数关闭会加快正常操作,但是在系统失败后可能导致不可恢复的数据损坏,或者静默的数据损坏。其风险类似于关闭fsync, 但是风险较小。并且只有在可关闭fsync的情况下才应该关闭它。 + 关闭此参数可以加快正常操作,但系统故障后可能出现不可恢复的数据损坏或静默数据损坏。风险与关闭fsync类似,虽然较小,但也只有在该参数建议的相同情形下才应关闭此参数。 @@ -3003,7 +2681,7 @@ include_dir 'conf.d' - 当这个参数为on时,PostgreSQL服务器一个检查点之后页面被第一次修改期间把该磁盘页面的整个内容都写入 WAL,即使对所谓的提示位做非关键修改也会这样做。 + 当这个参数为on时,PostgreSQL服务器在检查点之后首次修改页面时把该磁盘页面的整个内容都写入 WAL,即使对所谓的提示位做非关键修改也会这样做。 @@ -3028,9 +2706,8 @@ include_dir 'conf.d' 此参数启用使用指定的压缩方法对WAL进行压缩。 - 启用后,PostgreSQL服务器在 - 打开时或在基本备份期间, - 压缩写入WAL的整页镜像。 + 启用后,PostgreSQL服务器会压缩写入 WAL 的整页镜像,例如 + 在启用时、基础备份期间等。 在WAL重放期间,将对压缩的页镜像进行解压缩。 支持的方法有offonzstd(如果PostgreSQL @@ -3043,8 +2720,7 @@ include_dir 'conf.d' - 启用压缩可以减少WAL卷的大小,而不会增加不可恢复的数据损坏的风险, - 但会增加在WAL记录期间进行压缩时的额外CPU消耗,以及在WAL重放期间进行解压缩时的成本。 + 启用压缩可以减少 WAL 数据量,而且不会增加不可恢复的数据损坏风险;代价是在记录 WAL 时压缩、重放 WAL 时解压会额外消耗一些 CPU。 @@ -3059,10 +2735,10 @@ include_dir 'conf.d' - 如果设置为on(默认值),此选项会导致新的 WAL 文件被零填充。 - 在某些文件系统上,这可确保在我们需要写入 WAL 记录之前分配空间。 - 但是,Copy-On-Write(COW)文件系统可能不会从此技术中受益,因此可以选择跳过不必要的工作。 - 如果设置为off,则在创建文件时仅写入最终字节,以便其具有预期大小。 + 如果设置为on(默认值),此选项会导致新的 WAL 文件被零填充。 + 在某些文件系统上,这可确保在我们需要写入 WAL 记录之前分配空间。 + 但是,写时复制(COW)文件系统可能不会从此技术中受益,因此可以选择跳过不必要的工作。 + 如果设置为off,则在创建文件时只写入最后一个字节,以便其具有预期大小。 @@ -3077,8 +2753,8 @@ include_dir 'conf.d' - 如果设置为 on (默认值),此选项通过重命名来回收 WAL 文件,从而避免创建新文件。 - 在 COW 文件系统上,创建新文件系统可能更快,因此提供了禁用此行为的选项。 + 如果设置为 on (默认值),此选项通过重命名来回收 WAL 文件,从而避免创建新文件。 + 在 COW 文件系统上,创建新文件可能更快,因此提供了禁用此行为的选项。 @@ -3093,12 +2769,12 @@ include_dir 'conf.d' - 用于还未写入磁盘的 WAL 数据的共享内存量。默认值 -1 选择等于的 1/32 的尺寸(大约3%),但是不小于64kB也不大于 WAL 段的尺寸(通常为16MB)。如果自动的选择太大或太小可以手工设置该值,但是任何小于32kB的正值都将被当作32kB。 + 用于还未写入磁盘的 WAL 数据的共享内存量。默认值 -1 选择等于的 1/32 的尺寸(大约3%),但是不小于64kB也不大于 WAL 段的尺寸(通常为16MB)。如果自动的选择太大或太小可以手工设置该值,但是任何小于32kB的正值都将被当作32kB。 如果指定值时没有单位,则以WAL块作为单位,即为 XLOG_BLCKSZ 字节,通常为8kB。这个参数只能在服务器启动时设置。 - 在每次事务提交时,WAL 缓冲区的内容被写出到磁盘,因此极大的值不可能提供显著的收益。不过,把这个值设置为几个兆字节可以在一个繁忙的服务器(其中很多客户端会在同一时间提交)上提高写性能。由默认设置 -1 选择的自动调节将在大部分情况下得到合理的结果。 + 在每次事务提交时,WAL 缓冲区的内容被写出到磁盘,因此极大的值不太可能带来显著收益。不过,把这个值设置为至少几个兆字节可以在一个繁忙的服务器(其中很多客户端会在同一时间提交)上提高写性能。由默认设置 -1 选择的自动调节将在大部分情况下得到合理的结果。 @@ -3116,9 +2792,9 @@ include_dir 'conf.d' 指定 WAL 写入器刷写 WAL 的频繁程度,以时间为单位。 在刷写WAL之后,写入器将根据wal_writer_delay所给出的时间长度进行睡眠,除非被一个异步提交的事务提前唤醒。 - 如果最近的刷写发生在 wal_writer_delay 之前,并且小于 wal_writer_flush_after WAL的值产生之后,那么WAL只会被写入操作系统,而不会被刷写到磁盘。 + 如果距上次刷盘的时间小于wal_writer_delay,并且自那以后产生的 WAL 数据量小于wal_writer_flush_after,则只将 WAL 写入操作系统,而不刷写到磁盘。 如果指定值时没有单位,则以毫秒作为单位。 - 默认值是 200 毫秒(200ms)。注意在很多系统上,有效的睡眠延迟粒度是 10 毫秒,把wal_writer_delay设置为一个不是 10 的倍数的值,其效果和把它设置为大于该值的下一个 10 的倍数产生的效果相同。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 + 默认值是 200 毫秒(200ms)。注意在某些系统上,有效的睡眠延迟粒度是 10 毫秒,把wal_writer_delay设置为一个不是 10 的倍数的值,其效果可能与将其设置为下一个更大的 10 的倍数相同。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 @@ -3133,8 +2809,8 @@ include_dir 'conf.d' - 指定 WAL 写入器刷写 WAL 的频繁程度,以卷为单位。 - 如果最近的刷写发生在 wal_writer_delay 之前,并且小于 wal_writer_flush_after WAL的值产生之后,那么WAL只会被写入操作系统,而不会被刷写到磁盘。 + 指定 WAL 写入器刷写 WAL 的频繁程度,按数据量衡量。 + 如果距上次刷盘的时间小于wal_writer_delay,并且自那以后产生的 WAL 数据量小于wal_writer_flush_after,则只将 WAL 写入操作系统,而不刷写到磁盘。 如果wal_writer_flush_after被设置为0,则WAL数据总是会被立即刷写。 如果指定值时没有单位,则以WAL块作为单位,即为XLOG_BLCKSZ字节,通常为8kB。 默认是1MB。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 @@ -3152,10 +2828,7 @@ include_dir 'conf.d' - 当wal_levelminimal,并且在创建或重写永久关系之后提交事务时,此设置将确定如何保留新数据。 - 如果数据小于此设置,将其写入 WAL 日志;否则,使用受影响文件的 fsync。 - 根据存储的属性,如果此类提交减慢了并发事务,提高或降低此值可能会有所帮助。 - 如果指定此值时没有单位,则视为千字节。默认为两兆字节(2MB)。 + 当wal_levelminimal,且事务在创建或重写永久关系后提交时,此设置决定如何持久保存新数据。如果数据量小于此设置,就将其写入 WAL;否则,对受影响的文件执行 fsync。如果这类提交拖慢了并发事务,根据存储的特性,增大或减小此值可能有所帮助。未指定单位时以千字节为单位。默认值为两兆字节(2MB)。 @@ -3170,20 +2843,20 @@ include_dir 'conf.d' - 设置commit_delay会在执行WAL刷新之前添加时间延迟。 + 设置commit_delay会在发起 WAL 刷盘之前添加时间延迟。 如果系统负载足够高,使得在给定时间间隔内有更多事务准备提交, - 这可以通过允许更多事务通过单个WAL刷新来提高组提交吞吐量。 - 然而,这也会增加延迟,最多为每个WAL刷新的commit_delay。 - 因为如果没有其他事务准备提交,延迟就是浪费的,所以只有在至少有 - commit_siblings其他事务活动时才会执行延迟, - 当要启动刷新时,如果fsync被禁用,则不会执行延迟。 + 这可以通过允许更多事务通过一次 WAL 刷盘来提高组提交吞吐量。 + 不过,每次 WAL 刷盘的延迟也会因此增加,最多增加commit_delay。 + 如果没有其他事务准备提交,等待就没有意义,因此仅当即将发起刷盘时至少还有 + commit_siblings个其他活动事务,才会等待。 + 此外,如果禁用了fsync,也不会等待。 如果未指定单位,则将其视为微秒。 默认commit_delay为零(无延迟)。 只有超级用户和具有适当SET权限的用户才能更改此设置。 - 在PostgreSQL的 9.3 发布之前,commit_delay的行为不同并且效果更差:它只影响提交,而不是所有 WAL 刷写,并且即使在 WAL 刷写马上就要完成时也会等待一整个配置的延迟。从PostgreSQL 9.3 中开始,第一个准备好刷写的进程会等待配置的间隔,而后续的进程只等到领先者完成刷写操作。 + 在PostgreSQL的 9.3 发布之前,commit_delay的行为不同并且效果更差:它只影响提交,而不是所有 WAL 刷写,并且即使 WAL 刷盘更早完成,也会等待整个配置的延迟时间。从PostgreSQL 9.3 开始,第一个准备好刷写的进程会等待配置的间隔,而后续的进程只等到领先者完成刷写操作。 @@ -3198,7 +2871,7 @@ include_dir 'conf.d' - 在执行commit_delay延迟时,要求的并发活动事务的最小数目。大一些的值会导致在延迟间隔期间更可能有至少另外一个事务准备好提交。默认值是五个事务。 + 执行commit_delay延迟前要求的并发活动事务的最小数目。大一些的值会导致在延迟间隔期间更可能有至少另外一个事务准备好提交。默认值是五个事务。 @@ -3221,7 +2894,7 @@ include_dir 'conf.d' 自动 WAL 检查点之间的最长时间。如果指定值时没有单位,则以秒为单位。 - 合理的范围在 30 秒到 1 天之间。默认是 5 分钟(5min)。增加这个参数的值会增加崩溃恢复所需的时间。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 + 合理的范围在 30 秒到 1 天之间。默认是 5 分钟(5min)。增加这个参数的值可能会增加崩溃恢复所需的时间。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 @@ -3236,11 +2909,11 @@ include_dir 'conf.d' - 指定检查点完成的目标,作为检查点之间总时间的一部分。 - 默认是 0.9,这将把检查点分布在几乎所有可用的时间间隔上,提供公平一致的I/O负载,同时也为检查点完成开销留下了一些时间。 - 减少此参数是不被推荐的,因为这会导致检查点完成得更快。 - 这个造成处于在检查点和下一个计划检查点之间较少IO之后的检查点会有更高的IO比例。 - 这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 + 指定检查点完成所用时间的目标值,以检查点之间总时间的比例表示。 + 默认值为 0.9,这会把检查点工作分散到几乎整个可用间隔内,使 I/O 负载较为平稳, + 同时为检查点完成时的额外工作留出一些时间。不建议减小此参数,因为这样会让检查点更快完成, + 导致检查点期间的 I/O 速率更高,而在检查点完成后到下一个计划检查点开始前的一段时间内 I/O 较少。 + 此参数只能在postgresql.conf文件中或服务器命令行上设置。 @@ -3257,7 +2930,7 @@ include_dir 'conf.d' 当执行检查点时写入的数据量超过此数量时,就尝试强制 OS 把这些写发送到底层存储。 这样做将会限制内核页面高速缓存中的脏数据数量,降低在检查点末尾发出fsync或者 OS 在后台大批量写回数据时被卡住的可能性。 - 那常常会导致大幅度压缩的事务延迟,但是也有一些情况(特别是负载超过但小于 OS 页面高速缓存)的性能会降低。 + 这通常能显著降低事务延迟,但是也有一些情况(特别是负载超过但小于 OS 页面高速缓存)的性能会降低。 这种设置可能会在某些平台上没有效果。 如果指定值时没有单位,则以块为单位,即为BLCKSZ 字节,通常为8kB。 合法的范围在0(禁用强制写回)和2MB之间。Linux 上的默认值是256kB,其他平台上是0(如果BLCKSZ不是8kB,则默认值和最大值会按比例缩放到它)。这个参数只能在postgresql.conf文件中或者服务器命令行上设置。 @@ -3374,6 +3047,7 @@ include_dir 'conf.d' 这个参数只能在postgresql.conf文件或服务器命令行中设置。 除非在服务器启动时启用了archive_mode并且archive_library设置为空字符串,否则将被忽略。 + 如果archive_commandarchive_library都被设置,则会报错。 如果archive_command是空字符串(默认值),而archive_mode已启用(并且archive_library设置为空字符串), WAL归档将暂时被禁用,但服务器将继续积累WAL段文件,期望很快会提供命令。 将archive_command设置为一个什么都不做但返回true的命令,例如/bin/true(Windows上为REM), @@ -3393,6 +3067,7 @@ include_dir 'conf.d' 用于归档已完成的WAL文件段的库。如果设置为空字符串(默认值),则通过shell进行归档,并使用。 + 如果archive_commandarchive_library都被设置,则会报错。 否则,指定的共享库用于归档。当此参数更改时,postmaster会重新启动WAL归档进程。有关更多信息,请参见 @@ -3412,7 +3087,7 @@ include_dir 'conf.d' - 仅在完成的WAL段中调用。 + 只针对已完成的 WAL 段调用。 因此,如果您的服务器生成的WAL流量较少(或者在这样做时有间歇期),在事务完成和安全记录到归档存储之间可能会有很长的延迟。 为了限制未归档数据的年龄,您可以将archive_timeout设置为强制服务器定期切换到新的WAL段文件。 当此参数大于零时,只要自上次段文件切换以来经过了这段时间,并且存在任何数据库活动,包括单个检查点(如果没有数据库活动,则跳过检查点),服务器将切换到新的段文件。 @@ -3452,13 +3127,9 @@ include_dir 'conf.d' - 是否在恢复期间尝试预取在WAL中引用但尚未在缓冲池中的块。有效值为 - offon和 - try(默认值)。设置 - try仅在操作系统提供 - posix_fadvise函数时才启用 - 预取,该函数目前用于实现预取。请注意,一些操作系统提供该 - 函数,但它不起作用。 + 是否在恢复期间尝试预取 WAL 中引用但尚未在缓冲池中的块。 + 有效值为offontry(默认值)。 + try设置仅在操作系统支持发出预读建议时启用预取。 @@ -3493,8 +3164,8 @@ include_dir 'conf.d' 归档恢复 - configuration - of recovery + 配置 + 恢复 一个备库 @@ -3503,7 +3174,7 @@ include_dir 'conf.d' - Recovery 涵盖使用服务器作为备库或用于执行目标恢复。 + 恢复 涵盖使用服务器作为备库或用于执行目标恢复。 通常情况,备库模式用于提供高可用性和/或读可扩展性,而目标恢复用于从数据丢失中恢复。 @@ -3572,7 +3243,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows 这个信息可以被用来把归档截断为支持从当前恢复重启所需的最小值。 对于单一备库配置,模块常常被用在archive_cleanup_command中,例如: archive_cleanup_command = 'pg_archivecleanup /mnt/server/archivedir "%r"' - 但是注意,如果多个备库正在从同一个归档目录中恢复,你将需要保证只有当任意服务器都不再需要 WAL 文件时才会删除它们。 + 但是注意,如果多个备库正在从同一个归档目录中恢复,你将需要保证只有当所有服务器都不再需要这些 WAL 文件时才会删除它们。 archive_cleanup_command通常被用于一种温备配置(见)中。 要在该命令中嵌入一个真正的%字符,需要写成%% @@ -3625,7 +3296,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows 默认情况下,恢复将会一直恢复到 WAL 日志的末尾。下面的参数可以被用来指定一个更早的停止点。 在recovery_targetrecovery_target_lsnrecovery_target_namerecovery_target_timerecovery_target_xid中, - 最多只能使用一个,如果在配置文件中使用了多个,将会产生一个错误。这个参数只能在服务器启动时设置。 + 最多只能使用一个,如果在配置文件中使用了多个,将会产生一个错误。这些参数只能在服务器启动时设置。 @@ -3658,7 +3329,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows - 这个参数指定(pg_create_restore_point()所创建)的已命名的恢复点,恢复将进入该恢复点。 + 这个参数指定(pg_create_restore_point()所创建)的已命名的恢复点,恢复将进行到该恢复点。 @@ -3673,7 +3344,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows - 此参数指定恢复将执行的时间戳。精确的停止点还受到得影响。 + 此参数指定恢复要进行到的时间戳。精确的停止点还受到的影响。 @@ -3693,7 +3364,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows - 这个参数指定恢复将进入的事务 ID。记住虽然事务 ID 是在事务开始时顺序分配的,但是事务可能以不同的数字顺序完成。 + 这个参数指定恢复要进行到的事务 ID。记住虽然事务 ID 是在事务开始时顺序分配的,但是事务可能以不同的数字顺序完成。 那些在指定事务之前(也可以包括该事务)提交的事务将被恢复。精确的停止点也受到的影响。 该值可以指定为 32 位事务 ID,也可以指定为 64 位事务 ID(由纪元和 32 位 ID 组成),例如 pg_current_xact_id() 返回的值。提供 64 位事务 ID 时,仅使用其中的 32 位事务 ID 部分作为恢复目标。例如,4294968296(纪元 1)和 8589935592(纪元 2)都指向同一个 32 位事务 ID:1000。 @@ -3717,7 +3388,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows - 此参数指定恢复将继续进行的预写日志位置的LSN。精确的停靠点也受 的影响。 + 此参数指定恢复要进行到的预写日志位置的 LSN。精确的停止点也受 的影响。 使用系统数据类型pg_lsn解析此参数。 @@ -3742,7 +3413,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows 指定我们是否仅在指定的恢复目标之后停止(on),或者仅在恢复目标之前停止(off)。 适用于或者被指定的情况。 - 这个设置分别控制事务是否有准确的目标WAL位置(LSN)、提交时间或事务ID将被包括在该恢复中。默认值为on。 + 这个设置控制恢复是否包含 WAL 位置(LSN)、提交时间或事务 ID 分别恰好等于目标值的事务。默认值为on @@ -3759,7 +3430,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows 指定恢复到一个特定的时间线中。该值可以是数字时间线 ID 或特殊值。 - 值current沿着与执行基本备份时相同的时间线恢复。 + 值current沿着与执行基础备份时相同的时间线恢复。 值latest将恢复到归档中能找到的最新时间线,这在备库中很有用。 latest是默认值。 @@ -3795,14 +3466,14 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows - 使用pause设置的目的是:如果这个恢复目标就是恢复最想要的位置,就允许对数据库执行查询。 + 使用pause设置的目的是允许对数据库执行查询,以检查这个恢复目标是否为最合适的恢复位置。 暂停的状态可以使用pg_wal_replay_resume()(见)继续,这会让恢复终结。 如果这个恢复目标不是想要的停止点,那么关闭服务器,将恢复目标设置改为一个稍后的目标并且重启以继续恢复。 要让实例在想要的重放点那里准备好,shutdown设置可以派上用场。 - 该实例将仍能重放更多 WAL 记录(并且事实上将不得不重放从下一次它被启动后最后一个检查点以来的 WAL 记录)。 + 该实例将仍能重放更多 WAL 记录(并且事实上,下次启动时必须重新回放自上一个检查点以来的 WAL 记录)。 @@ -3813,7 +3484,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows 如果没有设置恢复目标,这个设置没有效果。 如果没有启用pause设置的动作将和shutdown一样。 - 如果在升级期间达到恢复目标,pause 的设置将与 promote的行为相同。 + 如果在备库提升期间达到恢复目标,pause 的设置将与 promote的行为相同。 @@ -3828,9 +3499,7 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows WAL 汇总 - - 这些设置控制 WAL 汇总,这是执行所需的一项功能。 - + 这些设置控制 WAL 汇总。执行增量备份前必须启用这项功能。 @@ -3846,12 +3515,10 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows 默认值为off - 如果wal_level被设置为minimal,则无法以 - summarize_wal=on启动服务器。如果在服务器启动后将 - summarize_wal设置为on而 - wal_levelminimal,则汇总器会运行,但会拒绝为使用 - wal_level=minimal生成的任何 WAL 创建汇总文件。 - + 如果wal_level设为minimal,则不能以summarize_wal=on启动服务器。 + 如果在服务器启动后配置summarize_wal=on,而此时wal_level=minimal, + 汇总器会运行,但会拒绝为使用wal_level=minimal生成的任何 WAL 创建汇总文件。 + @@ -3890,6 +3557,10 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows 对于物理复制,服务器将可以是主库或备库。主库能发送数据,而备库总是被复制数据的接收者。当使用级联复制(见)时,备库也可以是发送者,同时也是接收者。这些参数主要用于发送服务器和备库,尽管某些只在主库上有意义。如果有必要,设置可以在集簇中变化而不出问题。 + + 对于逻辑复制发布者(执行CREATE PUBLICATION的服务器)向订阅者(执行CREATE SUBSCRIPTION的服务器)复制数据。服务器也可以同时是发布者和订阅者。注意,下文各节将发布者称为“发送者”。有关逻辑复制配置设置的更多详细信息,请参见。 + + 发送服务器 @@ -3909,10 +3580,12 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows - 指定来自备库或流式基础备份客户端的并发连接的最大数量(即同时运行 WAL 发送进程的最大数)。 - 默认值是10。值0意味着禁用复制。 - 突然的流式传输客户端断开连接可能留下一个孤立连接槽(知道达到超时),因此这个参数应该设置得略高于最大客户端连接数,这样断开连接的客户端可以立刻重新连接。 - 这个参数只能在服务器启动时被设置。此外,wal_level必须设置为replica或更高级别以允许来自备库的连接。 + 指定来自备库或流式基础备份客户端的最大并发连接数(即同时运行的 WAL 发送进程的最大数量)。 + 默认值为 10。值 0 表示禁用复制。 + 流式客户端突然断开连接后,可能会留下一个孤立连接槽,直到超时才释放。 + 因此,此参数应设置得略高于预期的最大客户端数,使断开连接的客户端能够立即重新连接。 + 此参数只能在服务器启动时设置。此外,wal_level 必须设置为 + replica 或更高级别,才允许来自备库的连接。 @@ -4012,16 +3685,19 @@ HINT: If it is safe for all REPLICATION users to use this library as an output - 指定在备库需要为流复制获取日志段文件的情况下,pg_wal目录下所能保留的过去日志文件段的最小尺寸。 - 如果一个连接到发送服务器的备库落后了超过wal_keep_size兆字节,发送服务器可以移除一个备库仍然需要的 WAL 段,在这种情况下复制连接将被中断。 - 最终结果是下行连接也将最终失败(不过,如果在使用 WAL 归档,备库可以通过从归档获取段来恢复)。 + 指定在 pg_wal 目录中保留的旧 WAL 文件的最小总量, + 以便备库需要时获取这些文件进行流复制。如果连接到发送服务器的备库落后超过 + wal_keep_size 兆字节,发送服务器可能会移除备库仍需要的 WAL 段, + 从而导致复制连接终止。下游连接最终也会因此失败。 + (不过,如果使用了 WAL 归档,备库可以通过从归档获取该段来恢复。) - 只设置pg_wal中保留的文件段的最小尺寸;系统可能需要为 WAL 归档或从一个检查点恢复保留更多段。 - 如果wal_keep_size为零(默认值), 更多的空间来 存放WAL归档或从一个检查点恢复。 - 如果wal_keep_segments是零(缺省), 系统不会为备库目的保留任何多余的段,因此备库可用的旧 WAL 段的数量是一个上个检查点位置和 WAL 归档状态的函数。 - 如果此值被指定时没有单位,则视为兆字节。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。 + 此设置只规定 pg_wal 中保留的段的最小总量;系统可能需要为 WAL 归档 + 或从检查点恢复而保留更多段。如果 wal_keep_size 为零(默认值), + 系统不会为备库额外保留任何段,因此备库可用的旧 WAL 段数取决于前一个检查点的位置 + 和 WAL 归档的状态。如果指定值时没有单位,则按兆字节计算。 + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 @@ -4035,14 +3711,18 @@ HINT: If it is safe for all REPLICATION users to use this library as an output - - 指定在检查点时,replication slots(复制槽)允许在pg_wal目录中保留的WAL文件的最大大小。 - 如果max_slot_wal_keep_size为-1(默认值),复制槽可以保留无限量的WAL文件。否则,如果复制槽的restart_lsn落后于当前LSN超过给定大小, - 使用该槽的备机可能由于所需的WAL文件被删除而无法继续复制。您可以在pg_replication_slots中查看复制槽的WAL可用性。 - 如果未指定单位,则此值将被视为兆字节。此参数只能在postgresql.conf文件或服务器命令行中设置。 - - - + + 指定检查点时复制槽允许在 + pg_wal 目录中保留的 WAL 文件最大总量。 + 如果 max_slot_wal_keep_size 为 -1(默认值),复制槽可以保留无限量的 WAL 文件。 + 否则,如果复制槽的 restart_lsn 落后当前 LSN 超过给定大小,使用该槽的备库可能会 + 因为所需 WAL 文件被移除而无法继续复制。可以在 + pg_replication_slots 中查看复制槽的 WAL 可用情况。 + 如果指定值时没有单位,则按兆字节计算。此参数只能在 + postgresql.conf 文件中或服务器命令行上设置。 + + + idle_replication_slot_timeout (integer) @@ -4081,14 +3761,14 @@ HINT: If it is safe for all REPLICATION users to use this library as an output - 中断那些停止活动超过这个时间量的复制连接。这对发送服务器检测一个费用服务器崩溃或网络中断有用。 - 如果指定值时没有单位,则以毫秒为单位。默认值是 60 秒。值0将禁用超时机制。 + 终止非活动时间超过此值的复制连接。这有助于发送服务器检测备库崩溃或网络中断。 + 如果指定值时没有单位,则按毫秒计算。默认值为 60 秒。值零禁用超时机制。 - 对于跨越多个地理位置分布的集簇,每个位置使用不同的值可以为集簇管理带来更大的灵活性。 - 对于具有低延迟网络连接的备库,较小的值有助于更快的故障检测; - 对于位于远端位置的具有高延迟网络连接的备库,较大的值有助于更好地判断备库的健康状况。 + 对于跨多个地理位置分布的集簇,在各位置使用不同的值可以提高集簇管理的灵活性。 + 对于网络延迟较低的备库,较小的值有助于更快地检测故障; + 对于地处远端、网络延迟较高的备库,较大的值有助于更准确地判断其健康状况。 @@ -4154,7 +3834,10 @@ HINT: If it is safe for all REPLICATION users to use this library as an output 主库 - 这些参数可以在发送复制数据给一个或多个备库的主库上设置。注意除了这些参数之外,在主库上必须设置合适的,并且也启用可选的 WAL 归档(见)。这些参数值与备库无关,尽管你可能希望为了准备好一个备库转变成主库来设置这些参数。 + 这些参数可以在向一个或多个备库发送复制数据的主库上设置。 + 除这些参数外,还必须在主库上适当设置 , + 也可以选择启用 WAL 归档(见 )。 + 这些参数在备库上的取值不影响备库运行,不过也可以预先设置,以备将来提升为主库。 @@ -4170,15 +3853,17 @@ HINT: If it is safe for all REPLICATION users to use this library as an output 所述,这个参数指定一个支持同步复制的备库的列表。 - 可能会有一个或者多个活动的同步备库,在这些备库确认收到它们的数据之后,等待提交的事务将被允许继续下去。 - 同步备库是那些名字出现在这个列表前面,并且当前已连接并且正在实时流式传输数据(如pg_stat_replication视图中streaming的状态所示)的服务器。 + 将有一个或多个活动的同步备库,在这些备库确认收到它们的数据之后,等待提交的事务将被允许继续下去。 + 同步备库是那些名字出现在这个列表中,并且当前已连接并且正在实时流式传输数据(如pg_stat_replication视图中streaming的状态所示)的服务器。 指定多于一台同步备库可以得到非常高的可用性并且能防止数据丢失。 用于这一目的的备库的名称是其application_name设置,它在备库的连接信息中设置。 - 在物理复制备库的情况下,这应该被设置在primary_conninfo设置中,如果设置了,默认是的设置,否则为 walreceiver。 - 对于逻辑复制,可以在订阅的连接信息中设置。对于其他复制流消费者,请参考其文档。 + 对于物理复制备库,应在 primary_conninfo 设置中指定。 + 若已设置 ,则默认使用其值;否则默认值为 walreceiver。 + 对于逻辑复制,可以在订阅的连接信息中设置,默认值为订阅名称。 + 对于其他复制流消费者,请参考其文档。 @@ -4188,15 +3873,17 @@ HINT: If it is safe for all REPLICATION users to use this library as an output ANY num_sync ( standby_name [, ...] ) standby_name [, ...] - 其中num_sync是事务需要等待其回复的同步备库的数量,standby_name是一个备库的名称。FIRST以及ANY指定从所列服务器中选取同步备库的方法。 + 其中num_sync是事务需要等待其回复的同步备库的数量,standby_name是一个备库的名称。 + num_sync 必须是大于零的整数。 + FIRST以及ANY指定从所列服务器中选取同步备库的方法。 - 关键词FIRST加上num_sync指定一种基于优先的同步复制,并且会让事务提交等待,直到它们的WAL记录被复制到基于优先级选择的num_sync台同步备库上为止。例如,设置FIRST 3 (s1, s2, s3, s4)将导致每次提交都等待来自三台较高优先级的备库的答复,这三台备库将从备库s1s2s3以及s4中选出。在该列表中出现较早的备库将被给予较高的优先级,并且将被考虑为同步备库。列表中出现的其他备库表示潜在的同步备库。如果当前的任何同步备库因为某种原因断开连接,它将立刻被下一个最高优先级的备库替代。关键词FIRST是可选的。 + 关键词FIRST加上num_sync指定一种基于优先级的同步复制,并且会让事务提交等待,直到它们的WAL记录被复制到基于优先级选择的num_sync台同步备库上为止。例如,设置FIRST 3 (s1, s2, s3, s4)将导致每次提交都等待来自三台较高优先级的备库的答复,这三台备库将从备库s1s2s3以及s4中选出。在该列表中出现较早的备库将被给予较高的优先级,并且将被考虑为同步备库。列表中出现的其他备库表示潜在的同步备库。如果当前的任何同步备库因为某种原因断开连接,它将立刻被下一个最高优先级的备库替代。关键词FIRST是可选的。 - 关键词ANY加上num_sync指定一种基于规定数量的同步复制,并且会让事务提交等待,直到它们的WAL记录被复制到所列出备库中的至少num_sync台上为止。例如,设置ANY 3 (s1, s2, s3, s4)将导致每次提交会在收到s1s2s3以及s4中任意三台备库的回答后立刻继续下去。 + 关键词ANY加上num_sync指定一种基于法定人数的同步复制,并且会让事务提交等待,直到它们的WAL记录被复制到所列出备库中的至少num_sync台上为止。例如,设置ANY 3 (s1, s2, s3, s4)将导致每次提交会在收到s1s2s3以及s4中任意三台备库的回答后立刻继续下去。 @@ -4222,7 +3909,7 @@ ANY num_sync ( 参数设置为localoff。 + 如果这里没有指定同步备库名称,那么不启用同步复制并且事务提交将不会等待复制。这是默认的配置。即便当同步复制被启用时,个体事务也可以被配置为不等待复制,做法是将参数设置为localoff @@ -4239,16 +3926,16 @@ ANY num_sync ( pg_replication_slot_advance、 + pg_logical_slot_get_changes和 + pg_logical_slot_peek_changes + 将阻塞,直到synchronized_standby_slots中列出的所有物理槽都确认接收到了 WAL。 synchronized_standby_slots中物理复制槽对应的备库必须配置 @@ -4360,9 +4047,7 @@ ANY num_sync ( num_sync ( num_sync ( )。 - 默认为"关闭"。 此参数只能在postgresql.conf文件或服务器命令行中设置。 - 如果在 WAL 接收进程运行时更改此参数,则该进程将发出关机的信号,并预期使用新设置重新启动。 - + 指定在未使用配置要使用的永久复制槽时,WAL 接收进程是否应在远程实例上创建临时复制槽。默认值为 off。此参数只能在postgresql.conf文件中或服务器命令行上设置。如果在 WAL 接收进程运行时更改此参数,则会向该进程发送信号使其关闭,并预期它使用新设置重新启动。 @@ -4418,9 +4097,9 @@ ANY num_sync ( pg_stat_replication视图看到。 - 备库将报告它已经写入的上一个预写式日志位置、它已经刷到磁盘的上一个位置以及它已经应用的最后一个位置。 + 备库将报告最后写入的预写日志位置、最后刷盘的位置以及最后应用的位置。 这个参数的值是报告之间的最大时间量。 - 每次写入或刷出位置改变时会发送状态更新,或者按这个参数的指定的频度发送,如果设置为非零值。 + 每次写入或刷盘位置改变时会发送状态更新,或者按这个参数的指定的频度发送,如果设置为非零值。 在其他情况下发送更新时忽略此参数;例如,当现有的WAL处理完成或当synchronous_commit设置为remote_apply时。 因此,应用位置可能比真实位置略微滞后。 如果指定值时没有单位,则以秒为单位。 @@ -4440,7 +4119,7 @@ ANY num_sync ( num_sync ( + + recovery_min_apply_delay (integer) recovery_min_apply_delay 配置参数 - - 默认情况下,备库会尽快恢复来自于发送服务器的 WAL 记录。有一份数据的延时拷贝是有用的,它能提供机会纠正数据丢失错误。 - 这个参数允许你将恢复延迟一段指定的时间量。 - 例如,如果你设置这个参数为5min,对于一个事务提交,只有当备库上的系统时钟超过主库报告的提交时间至少 5分钟时,备库才会重放该事务。 - 如果指定值时没有单位,则以毫秒为单位。默认为0,不增加延迟。 + 默认情况下,备库会尽快恢复来自发送服务器的 WAL 记录。保留一份延迟的数据副本可能很有用,因为它提供了纠正数据丢失错误的机会。此参数允许将恢复延迟指定的时间。例如,将此参数设置为 5min 时,只有当备库系统时间比主库报告的提交时间至少晚五分钟,备库才会重放各事务的提交。如果没有指定单位,则以毫秒计。默认值为零,不增加延迟。 - - 有可能服务器之间的复制延迟会超过这个参数的值,在这种情况下则不会增加延迟。 - 注意延迟是根据主库上写 WAL 的时间戳以及备库上的当前时间来计算。 - 由于网络延迟或者级联复制配置导致的传输延迟可能会显著地减少实际等待时间。 - 如果主库和备库上的系统时钟不同步,这会导致恢复比预期的更早应用记录。 - 但这不是一个主要问题,因为这个参数有用的设置比服务器之间的典型事件偏差要大得多。 + 服务器之间的复制延迟可能超过此参数的值,这种情况下不会增加延迟。注意,延迟根据主库写入的 WAL 时间戳与备库当前时间之差计算。网络延迟或级联复制配置导致的传输延迟,可能显著缩短实际等待时间。如果主库和备库的系统时钟不同步,恢复时可能比预期更早应用记录;但这通常不是主要问题,因为此参数的实用取值远大于服务器间常见的时间偏差。 - - 只有在事务提交的 WAL 记录上才会发生延迟。其他记录还是会被尽可能快地重放,这不会成为问题,因为 MVCC 可见性规则确保了在对应的提交记录被应用之前它们的效果不会被看到。 + 延迟仅发生在事务提交的 WAL 记录上。其他记录会尽快重放;这不会造成问题,因为 MVCC 可见性规则确保在对应提交记录被应用之前,它们的效果不会可见。 - - 一旦恢复中的数据库已经达到一致状态,延迟就会产生,直到备库被提升或者触发。在那之后,备库将会结束恢复并且不再等待。 + 恢复中的数据库达到一致状态后开始延迟,直到备库被提升或触发。此后,备库会结束恢复,不再等待。 - - WAL记录必须保留在备库上,直到准备好应用。因此,较长的延迟将导致WAL文件的积累增加,增加备库的pg_wal目录的磁盘空间需求。 + WAL 记录必须保留在备库上,直到可以应用它们。因此,更长的延迟会导致更多 WAL 文件积压,增加备库 pg_wal 目录所需的磁盘空间。 - - 这个参数的目的是和物理流复制部署一起使用,但是,如果指定了该参数,除了崩溃恢复之外所有的情况下都会遵守它。 - 使用这个特性也会让hot_standby_feedback被延迟,这可能导致主库的膨胀,两者一起使用时要小心。 - + 此参数旨在用于流式物理复制部署;不过,只要指定了此参数,它就会在除崩溃恢复以外的所有情况下生效。使用此功能也会延迟 hot_standby_feedback,可能导致主库膨胀;同时使用两者时应谨慎。 - 当synchronous_commit被设置为remote_apply时,同步复制会受到这个设置的影响,每一个COMMIT都需要等待被应用。 + 当 synchronous_commit 设置为 remote_apply 时,同步复制会受到此设置影响;每个 COMMIT 都必须等待提交被应用。 - - - 这个参数只能在postgresql.conf文件中或通过服务器命令行进行设置。 - - - + + + 此参数只能在 postgresql.conf 文件中或服务器命令行上设置。 + + + - + sync_replication_slots (boolean) sync_replication_slots配置参数 @@ -4565,53 +4228,8 @@ ANY num_sync ( - createrole_self_grant (string) - - createrole_self_grant配置参数 - - - - - 如果一个拥有CREATEROLE但不拥有SUPERUSER权限的用户创建了角色,并且此选项被设置为非空值,则新创建的角色将以指定选项授予创建者。 - 该值必须是setinherit或它们的逗号分隔列表。默认值为空字符串,这会禁用此功能。 - - - 此选项的目的是允许非超级用户的CREATEROLE用户自动继承或自动获得对新创建角色执行SET ROLE的能力。 - 由于CREATEROLE用户始终会隐式获得其所创建角色的ADMIN OPTION,因此该用户总是可以通过执行GRANT语句达到相同效果,但自动授予在可用性上更方便。 - 超级用户会自动继承每个角色的权限,并且始终可以切换到任何角色;此设置可用于为CREATEROLE用户提供类似行为。 - - - - - event_triggers (boolean) - - event_triggers配置参数 - - - - - 允许临时禁用事件触发器的执行,以便对有故障的事件触发器进行故障排查和修复。 - 将其设置为false会禁用所有事件触发器;设置为true则允许所有事件触发器触发,这也是默认值。 - 只有超级用户和具有适当SET权限的用户才能更改此设置。 - - - - - restrict_nonsystem_relation_kind (string) - - restrict_nonsystem_relation_kind配置参数 - - - - - 设置禁止访问非系统关系的关系类型。该值采用关系类型的逗号分隔列表形式。 - 目前支持的关系类型是viewforeign-table。 - - - @@ -4621,11 +4239,7 @@ ANY num_sync ( @@ -4641,7 +4255,7 @@ ANY num_sync ( ),从而实际上限制了服务器上可以创建多少逻辑复制订阅。 将其设置为低于当前正在跟踪的复制源数量(体现在pg_replication_origin_status中)会阻止服务器启动。 默认值为 10。该参数只能在服务器启动时设置。 - max_active_replication_origins至少必须设置为订阅者上要添加的订阅数量,再加上一些用于表同步的预留。 + max_active_replication_origins至少必须设置为订阅者上要添加的订阅数量,再加上一些用于表同步的预留。 @@ -4656,16 +4270,15 @@ ANY num_sync ( num_sync ( num_sync ( num_sync ( + + enable_bitmapscan (boolean) - 位图扫描 + 位图扫描 - enable_bitmapscan配置参数 + enable_bitmapscan 配置参数 - - 允许或禁止查询规划器使用位图扫描计划类型。默认值是on。 + 启用或禁用查询规划器对位图扫描计划类型的使用。默认值为 on - - + + - + enable_distinct_reordering (boolean) enable_distinct_reordering配置参数 @@ -4803,22 +4415,22 @@ ANY num_sync ( + + enable_gathermerge (boolean) - enable_gathermerge配置参数 + enable_gathermerge 配置参数 - - 启用或者禁用查询规划器对收集归并计划类型的使用。默认值是on。 + 启用或禁用查询规划器对收集归并计划类型的使用。默认值为 on - - + + - + enable_group_by_reordering (boolean) enable_group_by_reordering配置参数 @@ -4846,89 +4458,90 @@ ANY num_sync ( + + enable_hashagg (boolean) - enable_hashagg配置参数 + enable_hashagg 配置参数 - - 允许或禁用查询规划器使用哈希聚合计划类型。默认值是on。 + 启用或禁用查询规划器对哈希聚合计划类型的使用。默认值为 on - + + enable_hashjoin (boolean) - enable_hashjoin配置参数 + enable_hashjoin 配置参数 - - 允许或禁止查询规划器使用哈希连接计划类型。默认值是on。 + 启用或禁用查询规划器对哈希连接计划类型的使用。默认值为 on - + + enable_incremental_sort (boolean) enable_incremental_sort 配置参数 - - 启用或禁用查询规划器对增量排序步骤的使用。默认为on。 + 启用或禁用查询规划器对增量排序步骤的使用。默认值为 on - + + + + enable_indexscan (boolean) - 索引扫描 + 索引扫描 - enable_indexscan配置参数 + enable_indexscan 配置参数 - - 允许或禁止查询规划器使用索引扫描计划类型。默认值是on。 + 启用或禁用查询规划器对索引扫描和仅索引扫描计划类型的使用。默认值为 on。另请参见 - enable_indexonlyscan (boolean) - enable_indexonlyscan配置参数 + enable_indexonlyscan 配置参数 - - 允许或禁止查询规划器使用只用索引扫描计划类型(见)。默认值是on。 + 启用或禁用查询规划器对仅索引扫描计划类型的使用(参见 )。默认值为 on。还必须启用 ,查询规划器才会考虑仅索引扫描。 - + + enable_material (boolean) - enable_material配置参数 + enable_material 配置参数 @@ -4939,8 +4552,9 @@ ANY num_sync ( + + enable_memoize (boolean) enable_memoize 配置参数 @@ -4957,26 +4571,27 @@ ANY num_sync ( + + enable_mergejoin (boolean) - enable_mergejoin配置参数 + enable_mergejoin 配置参数 - - 允许或禁止查询规划器使用归并连接计划类型。默认值是on。 + 启用或禁用查询规划器对归并连接计划类型的使用。默认值为 on - + + enable_nestloop (boolean) - enable_nestloop配置参数 + enable_nestloop 配置参数 @@ -5002,17 +4617,17 @@ ANY num_sync ( + + enable_parallel_hash (boolean) - enable_parallel_hash配置参数 + enable_parallel_hash 配置参数 - - 允许或禁止查询规划器对并行哈希使用哈希连接计划类型。如果哈希连接计划也没有启用,这个参数没有效果。默认值是on。 + 启用或禁用查询规划器对使用并行哈希的哈希连接计划类型的使用。如果没有同时启用哈希连接计划,此参数不起作用。默认值为 on @@ -5032,41 +4647,37 @@ ANY num_sync ( + + + + enable_partitionwise_join (boolean) - enable_partitionwise_join配置参数 + enable_partitionwise_join 配置参数 - - 允许或者禁止查询规划器使用面向分区的连接,这使得分区表之间的连接以连接匹配的分区的方式来执行。 - 面向分区的连接当前只适用于连接条件包括所有分区键的情况,连接条件必须是相同的数据类型并且子分区集合要1对1匹配。 - 由于面向分区的连接规划在规划期间会使用可观的CPU时间和内存,所以默认值为off。 + 启用或禁用查询规划器对分区连接的使用,使分区表之间的连接可以通过连接相匹配的分区来完成。分区连接目前仅适用于连接条件包含所有分区键的情况;这些分区键必须具有相同的数据类型,并且子分区集合必须一一匹配。启用此设置后,最终计划中内存用量受 work_mem 限制的节点数量可能随所扫描分区的数量线性增加。这可能大幅增加查询执行期间的总内存消耗。查询规划在内存和 CPU 方面的开销也会显著增加。默认值为 off - enable_partitionwise_aggregate (boolean) - enable_partitionwise_aggregate配置参数 + enable_partitionwise_aggregate 配置参数 - - 启用或禁用查询规划器使用分区分组或聚合的功能,该功能允许在分区表上分别对每个分区执行分组或聚合操作。 - 如果GROUP BY子句不包括分区键,那么只能在每个分区的基础上执行部分聚合,并且必须在稍后进行最终化处理。 - 由于分区分组或聚合在规划期间可能会使用更多的CPU时间和内存,因此默认情况下为off。 + 启用或禁用查询规划器对分区分组或聚合的使用,使分区表上的分组或聚合可以在各个分区上分别执行。如果 GROUP BY 子句不包含分区键,则只能在各分区上执行部分聚合,随后还必须进行最终处理。启用此设置后,最终计划中内存用量受 work_mem 限制的节点数量可能随所扫描分区的数量线性增加。这可能大幅增加查询执行期间的总内存消耗。查询规划在内存和 CPU 方面的开销也会显著增加。默认值为 off - - + + - + enable_presorted_aggregate (boolean) enable_presorted_aggregate配置参数 @@ -5564,7 +5175,7 @@ ANY num_sync ( 包括在普通日志项中。只有可打印 ASCII 字符能被使用在application_name之中。其他字符将被替换为问号(?)。 + application_name可以是任意小于NAMEDATALEN个字符(标准编译中是 64 个字符)的字符串。应用通常在连接服务器时设置此值。该名称将被显示在pg_stat_activity视图中并被包括在 CSV 日志项中。它也会被通过包括在普通日志项中。只有可打印 ASCII 字符能被使用在application_name之中。其他字符将被替换为C 风格的十六进制转义序列。 @@ -6571,7 +6182,7 @@ local0.* /var/log/postgresql 出于向后兼容性考虑,onofftruefalseyesno10仍然受支持。 - 正向值等价于指定receiptauthentication和 + 表示启用的值等价于指定receiptauthenticationauthorization选项。 @@ -6583,7 +6194,7 @@ local0.* /var/log/postgresql - 某些客户端程序(例如psql)在要求密码时会尝试连接两次,因此重复的收到连接消息并不一定表示一个错误。 + 某些客户端程序(例如psql)在判断是否需要密码时会尝试连接两次,因此重复的收到连接消息并不一定表示一个错误。 @@ -6732,6 +6343,11 @@ local0.* /var/log/postgresql 远程主机名或 IP 地址 + + %L + 本地地址(客户端所连接的服务器 IP 地址) + + %b @@ -6801,13 +6417,13 @@ local0.* /var/log/postgresql %v - 虚拟事务 ID (backendID/localXID) + 虚拟事务 ID (procNumber/localXID);参见 %x - 事务 ID (如果未分配则为 0) + 事务 ID (如果未分配则为 0);参见 @@ -6826,7 +6442,7 @@ local0.* /var/log/postgresql %% - 纯文字 % + 字面字符 % @@ -6860,7 +6476,7 @@ FROM pg_stat_activity; - Syslog产生自己的时间戳和进程 ID 信息,因此如果你记录到syslog你可能不希望包括哪些转义。 + Syslog产生自己的时间戳和进程 ID 信息,因此如果你记录到syslog你可能不希望包括那些转义。 @@ -6901,6 +6517,21 @@ log_line_prefix = '%m [%p] %q%u@%d/%a ' + + log_lock_failures (boolean) + + log_lock_failures配置参数 + + + + + 控制当获取锁失败时是否生成详细日志消息。这有助于分析锁失败的原因。 + 目前,仅支持由于SELECT NOWAIT导致的锁失败。 + 默认值为off。只有超级用户和具有适当SET权限的用户才能更改此设置。 + + + + log_recovery_conflict_waits (boolean) @@ -6922,21 +6553,6 @@ log_line_prefix = '%m [%p] %q%u@%d/%a ' - - log_lock_failures (boolean) - - log_lock_failures配置参数 - - - - - 控制当获取锁失败时是否生成详细日志消息。这有助于分析锁失败的原因。 - 目前,仅支持由于SELECT NOWAIT导致的锁失败。 - 默认值为off。只有超级用户和具有适当SET权限的用户才能更改此设置。 - - - - log_parameter_max_length (integer) @@ -7422,12 +7038,12 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 为不同目的设置标识这个数据库集簇(实例)的名称。此集簇名称出现在该集簇中所有服务器进程的进程标题中。 - 此外,它还是备库连接的默认应用名称。(参见 .) + 设置一个用于各种目的、标识此数据库集簇(实例)的名称。集簇名称会出现在此集簇所有服务器进程的进程标题中。 + 此外,它还是备库连接的默认应用名称(参见)。 - 这个名称可以是任何长度不超过NAMEDATALEN个字符(在标准编译中是 64字符)的任何字符串。只有可打印的 ASCII 字符能被用在cluster_name值中。其他字符将被替换为问号(?)。如果这个参数被设置为空字符串''(也是默认值),将不会显示名称。这个参数只能在服务器启动时设置。 + 这个名称可以是任何长度少于NAMEDATALEN个字符(在标准编译中是 64字符)的任何字符串。只有可打印的 ASCII 字符能被用在cluster_name值中。其他字符将被替换为C 风格的十六进制转义序列。如果这个参数被设置为空字符串''(也是默认值),将不会显示名称。这个参数只能在服务器启动时设置。 @@ -7529,32 +7145,39 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 启用基于成本的清理延迟计时(参见)。 - 默认情况下该参数关闭,因为它需要反复查询操作系统当前时间,在某些平台上可能带来显著开销。 - 你可以使用pg_test_timing来衡量系统上的计时开销。 - 基于成本的清理延迟计时信息会显示在pg_stat_progress_vacuum、 - pg_stat_progress_analyze中, - 也会显示在带有VERBOSE选项的VACUUMANALYZE输出中, - 并且当设置了时,autovacuum 还会为自动清理和自动分析记录这些信息。 - 只有超级用户和具有适当SET权限的用户才能更改此设置。 + 启用基于代价的清理延迟计时(参见)。 + 默认情况下该参数关闭,因为它需要反复查询操作系统当前时间,在某些平台上可能带来显著开销。 + 你可以使用 工具来衡量系统上的计时开销。 + 基于代价的清理延迟计时信息会显示在pg_stat_progress_vacuum、 + pg_stat_progress_analyze中, + 也会显示在带有VERBOSE选项的输出中, + 并且当设置了时,autovacuum 还会为自动清理和自动分析记录这些信息。 + 只有超级用户和具有适当SET权限的用户才能更改此设置。 - track_io_timing (boolean) - track_io_timing配置参数 + track_io_timing 配置参数 - - 启用数据库I/O调用的计时。 默认情况下,此参数处于关闭状态,因为它将重复查询操作系统的当前时间,这可能会在某些平台上造成显著的开销。 您可以使用工具来测量系统上计时的开销。 - I/O计时信息显示在 - pg_stat_database中,在的输出中,当使用BUFFERS选项时,在的输出中,当使用VERBOSE选项时,由autovacuum执行自动清理和自动分析时,当设置了时,以及由。 - 只有超级用户和具有适当SET权限的用户才能更改此设置。 + 启用数据库 I/O 等待的计时。此参数默认关闭,因为计时需要反复向操作系统查询 + 当前时间,在某些平台上可能会产生显著开销。可以使用 工具 + 测量本系统上的计时开销。I/O 计时信息会显示在 + pg_stat_database 中、 + pg_stat_io 中(当 object 不是 wal 时)、 + pg_stat_get_backend_io() 函数的输出中 + (当 object 不是 wal 时)、 + 使用 BUFFERS 选项的 输出中、 + 使用 VERBOSE 选项的 输出中, + autovacuum 也会在执行自动清理和自动分析时输出这些信息 + (需设置 ), + 同样提供这些信息。只有超级用户和具有适当 + SET 权限的用户可以更改此设置。 @@ -7569,14 +7192,8 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 启用WAL I/O调用的定时。此参数默认关闭,因为它将重复查询操作系统的当前时间, - 这可能会在某些平台上造成显著的开销。 - 您可以使用pg_test_timing工具来 - 测量系统上定时的开销。 - I/O定时信息显示在 - pg_stat_wal中。 - 只有超级用户和具有适当SET权限的用户才能更改此设置。 - + 启用 WAL I/O 等待的计时。此参数默认关闭,因为它会反复向操作系统查询当前时间,可能在某些平台上产生显著开销。可以使用 pg_test_timing 工具测量系统上的计时开销。I/O 计时信息显示在 pg_stat_ioobjectwal 的行,以及 pg_stat_get_backend_io() 函数输出中 objectwal 的行。只有超级用户和具有适当 SET 权限的用户才能更改此设置。 + @@ -7671,7 +7288,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 确认只有一个查询标识符被计算和显示,如果一个查询标识符已经被计算,扩展计算标识符将抛出一个错误。 + 为确保只有一个查询标识符被计算和显示,计算查询标识符的扩展在查询标识符已被计算时应当抛出一个错误。 @@ -7720,19 +7337,19 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - Vacuuming + 清理 - 自动清理 + 清理 配置参数 - 这些参数控制 vacuuming 的行为。有关 vacuum 的目的和职责的更多信息,请参阅。 + 这些参数控制清理的行为。有关清理的目的和职责的更多信息,请参阅 - 自动 Vacuuming + 自动清理 这些设置控制autovacuum特性的行为。详情请参考 @@ -7759,7 +7376,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 注意即使该参数被禁用,系统也会在需要防止事务ID回卷时发起清理进程。详情请见。 + 注意即使该参数被禁用,系统也会在需要防止事务ID回卷时发起自动清理进程。详情请见 @@ -7791,7 +7408,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 指定能同时运行的自动清理进程(除了自动清理启动器之外)的最大数量。默认值为3。该参数只能在服务器启动时设置。 + 指定能同时运行的自动清理进程(除了自动清理启动器之外)的最大数量。默认值为3。该参数只能在postgresql.conf文件或服务器命令行中设置。 请注意,如果该值被设置得高于,将不会产生任何效果,因为 autovacuum 工作进程是从该设置建立的槽位池中获取的。 @@ -7809,29 +7426,13 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 指定自动清理在任意给定数据库上运行的最小延迟。在每一轮中后台进程检查数据库并根据需要为数据库中的表发出VACUUMANALYZE命令。 + 指定自动清理在任意给定数据库上各次运行之间的最小间隔。在每一轮中后台进程检查数据库并根据需要为数据库中的表发出VACUUMANALYZE命令。 如果指定值时没有单位,则以秒为单位。默认值为1分钟(1min)。该参数只能在postgresql.conf文件或在服务器命令行上设置。 - - autovacuum_vacuum_max_threshold (integer) - - autovacuum_vacuum_max_threshold配置参数 - - - - - 指定在任意一个表上触发VACUUM所需更新或删除元组数的最大值,也就是对 - autovacuum_vacuum_threshold和 - autovacuum_vacuum_scale_factor计算结果所施加的上限。 - 默认值为 100,000,000 个元组。如果指定为-1,autovacuum 将不会对触发 - VACUUM所需的更新或删除元组数强制施加最大值。 - 该参数只能在postgresql.conf文件中或服务器命令行上设置;但可以通过更改表存储参数覆盖单个表的该设置。 - - - + @@ -7862,7 +7463,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; 指定在任何一个表中触发 VACUUM所需要插入的元组数。默认值为 1000 个元组。 如果指定了 -1,则autovacuum不会根据插入数量在任何表上触发 VACUUM操作。 - 此参数只能在postgresql.conf文件或服务器命令行中设置;但可以通过更改表存储参数来覆盖单个表的设置。 + 此参数只能在postgresql.conf文件或服务器命令行中设置;但可以通过更改表存储参数来覆盖单个表的设置。 @@ -7894,7 +7495,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 指定一个表尺寸的分数,在决定是否触发VACUUM时将它加到autovacuum_vacuum_threshold上。默认值为0.2(表尺寸的20%)。该参数只能在postgresql.conf文件或在服务器命令中设置。但是对个别表可以通过修改表存储参数来覆盖该设置。 + 指定一个表尺寸的分数,在决定是否触发VACUUM时将它加到autovacuum_vacuum_threshold上。默认值为0.2(表尺寸的20%)。该参数只能在postgresql.conf文件或在服务器命令中设置。但是对个别表可以通过修改表存储参数来覆盖该设置。 @@ -7910,8 +7511,9 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 指定一个要添加到autovacuum_vacuum_insert_threshold 中的表的大小的比例,在决定是否触发VACUUM时。 - 默认值为 0.2(表大小的 20%)。此参数只能在postgresql.conf文件或服务器命令行中设置;但可以通过更改表存储参数来覆盖单个表的设置。 + 指定表中未冻结页面的比例,在决定是否触发VACUUM时,将由该比例计算出的数量加到 + autovacuum_vacuum_insert_threshold上。默认值为0.2(表中未冻结页面的 20%)。 + 该参数只能在postgresql.conf文件或服务器命令行中设置;但可以通过更改表存储参数为单个表覆盖该设置。 @@ -7927,11 +7529,29 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 指定一个表尺寸的分数,在决定是否触发ANALYZE时将它加到autovacuum_analyze_threshold上。默认值为0.1(表尺寸的10%)。该参数只能在postgresql.conf文件或在服务器命令中设置。但是对个别表可以通过修改表存储参数来覆盖该设置。 + 指定一个表尺寸的分数,在决定是否触发ANALYZE时将它加到autovacuum_analyze_threshold上。默认值为0.1(表尺寸的10%)。该参数只能在postgresql.conf文件或在服务器命令中设置。但是对个别表可以通过修改表存储参数来覆盖该设置。 + + autovacuum_vacuum_max_threshold (integer) + + autovacuum_vacuum_max_threshold配置参数 + + + + + 指定在任意一个表上触发VACUUM所需更新或删除元组数的最大值,也就是对 + autovacuum_vacuum_threshold和 + autovacuum_vacuum_scale_factor计算结果所施加的上限。 + 默认值为 100,000,000 个元组。如果指定为-1,autovacuum 将不会对触发 + VACUUM所需的更新或删除元组数强制施加最大值。 + 该参数只能在postgresql.conf文件中或服务器命令行上设置;但可以通过更改表存储参数覆盖单个表的该设置。 + + + + autovacuum_freeze_max_age (integer) @@ -8000,7 +7620,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 指定用于自动VACUUM操作中的代价限制值。如果指定-1(默认值),则使用值。注意该值被按比例地分配到运行中的自动清理工作者上(如果有多个),因此每一个工作者的限制值之和不会超过这个变量中的值。该参数只能在postgresql.conf文件或在服务器命令中设置。但是对个别表可以通过修改表存储参数来覆盖该设置。 + 指定用于自动VACUUM操作中的代价限制值。如果指定-1(默认值),则使用值。注意该值被按比例地分配到运行中的自动清理工作进程上(如果有多个),因此每一个工作进程的限制值之和不会超过这个变量中的值。该参数只能在postgresql.conf文件或在服务器命令中设置。但是对个别表可以通过修改表存储参数来覆盖该设置。 @@ -8102,6 +7722,108 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; + + 基于代价的清理延迟 + + + 执行 命令期间,系统维护一个内部计数器,记录已执行的各种 I/O 操作的估算代价。 + 当累计代价达到上限(由 vacuum_cost_limit 指定)时,执行该操作的进程会休眠一小段时间,时长由 vacuum_cost_delay 指定。 + 随后重置计数器并继续执行。 + + + + 此功能让管理员能够降低这些命令对并发数据库活动的 I/O 影响。在许多情况下,VACUUMANALYZE 等维护命令是否快速完成并不重要, + 但避免它们显著干扰系统执行其他数据库操作的能力通常很重要。基于代价的清理延迟为管理员提供了实现这一点的方法。 + + + + 对于手动执行的 VACUUM 命令,此功能默认禁用。要启用它,将 vacuum_cost_delay 变量设为非零值。 + + + + + + vacuum_cost_delay (floating point) + + vacuum_cost_delay配置参数 + + + + + 超过代价上限后,进程将休眠的时长。如果未指定单位,则以毫秒为单位。默认值为 0,表示禁用基于代价的清理延迟功能。正值会启用基于代价的清理。 + + + 使用基于代价的清理时,vacuum_cost_delay 的合适值通常很小,可能不到 1 毫秒。虽然 vacuum_cost_delay 可以设为以毫秒为单位的小数值,但较旧的平台可能无法准确计量这种延迟。在这些平台上,若要让 VACUUM 的资源用量超过延迟设为 1ms 时的水平,需要调整其他清理代价参数。尽管如此,仍应将 vacuum_cost_delay 设为平台能够稳定计量的尽可能小的值;较大的延迟没有帮助。 + + + + + + + vacuum_cost_page_hit (integer) + + vacuum_cost_page_hit配置参数 + + + + + 清理在共享缓冲区缓存中找到的缓冲区时所计入的估算代价。它表示锁定缓冲池、查找共享哈希表和扫描页内容的代价。默认值为 1。 + + + + + + + vacuum_cost_page_miss (integer) + + vacuum_cost_page_miss配置参数 + + + + + 清理必须从磁盘读取的缓冲区时所计入的估算代价。它表示锁定缓冲池、查找共享哈希表、从磁盘读取所需数据块并扫描其内容所需的工作量。默认值为 2。 + + + + + + + vacuum_cost_page_dirty (integer) + + vacuum_cost_page_dirty配置参数 + + + + + 清理操作修改原本干净的数据块时所计入的估算代价。它表示再次将脏块刷盘所需的额外 I/O。默认值为 20。 + + + + + + + vacuum_cost_limit (integer) + + vacuum_cost_limit配置参数 + + + + + 会使清理进程休眠 vacuum_cost_delay 指定时长的累计代价。默认值为 200。 + + + + + + + + 某些操作持有关键的锁,因此应尽快完成。这些操作期间不会发生基于代价的清理延迟,所以累计代价可能远超指定上限。 + 为避免此时出现无益的长时间延迟,实际延迟按 vacuum_cost_delay * accumulated_balance / vacuum_cost_limit 计算, + 但最大不超过 vacuum_cost_delay * 4。 + + + + 默认行为 @@ -8126,10 +7848,14 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 冻结 (Freezing) + 冻结 - 这些设置控制旧行版本的冻结。更多信息请参阅。 + 为了在事务 ID 回卷后仍保持正确性,PostgreSQL会将足够旧的行标记为已冻结。 + 这些行对所有事务都可见;其他事务不必检查插入这些行的 XID 就能确定其可见性。 + VACUUM负责将行标记为已冻结。以下设置控制VACUUM的冻结行为, + 应根据系统的 XID 消耗速率以及主要工作负载的数据访问模式进行调整。 + 有关事务 ID 回卷和这些参数的调优,详见 @@ -8141,7 +7867,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 当表的pg_class.relfrozenxid字段达到该设置指定的年龄时,VACUUM会执行激进扫描。激进扫描与常规VACUUM不同,它会访问每一个可能包含未冻结 XID 或 MXID 的页面,而不仅仅是那些可能包含死元组的页面。默认值是 1.5 亿个事务。尽管用户可以将该值设置为 0 到 20 亿之间的任意值,VACUUM会悄悄将有效值调整为的 95%,从而在触发防回卷 autovacuum 之前仍有机会执行一次常规手工VACUUM。更多信息请参见。 + 当表的pg_class.relfrozenxid字段达到该设置指定的年龄时,VACUUM会执行激进扫描。激进扫描与常规VACUUM不同,它会访问每一个可能包含未冻结 XID 或 MXID 的页面,而不仅仅是那些可能包含死元组的页面。默认值是 1.5 亿个事务。尽管用户可以将该值设置为 0 到 20 亿之间的任意值,VACUUM会悄悄将有效值限制为不超过的 95%,从而在触发防回卷 autovacuum 之前仍有机会执行一次常规手工VACUUM。更多信息请参见 @@ -8154,7 +7880,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 指定VACUUM在扫描表时用来决定是否冻结行版本的切断年龄(以事务计)。默认值是 5000 万个事务。尽管用户可以将该值设置为 0 到 10 亿之间的任意值,VACUUM会悄悄将有效值调整为的一半,这样强制 autovacuum 之间就不会间隔过短。更多信息请参见。 + 指定VACUUM用来决定是否触发对含有较旧 XID 的页面进行冻结的截止年龄(以事务计)。默认值是 5000 万个事务。尽管用户可以将该值设置为 0 到 10 亿之间的任意值,VACUUM会悄悄将有效值限制为不超过的一半,这样强制 autovacuum 之间就不会间隔过短。更多信息请参见 @@ -8170,7 +7896,10 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; 指定表的pg_class.relfrozenxid字段在VACUUM采取特别措施以避免系统范围事务 ID 回卷失败之前所允许达到的最大年龄(以事务计)。这是VACUUM的最后防线。失效保护通常会在防止事务 ID 回卷的 autovacuum 已经运行了一段时间后触发,但也有可能在任何VACUUM期间触发。 - 当失效保护被触发时,将不再应用任何有效的基于成本的延迟,并且会跳过进一步的非关键维护任务(例如索引 vacuum)。 + 当失效保护被触发时,将不再应用任何有效的基于代价的延迟,并且会跳过进一步的非关键维护任务(例如索引清理),而且任何正在使用的 + 缓冲区访问策略 + 都会被禁用,使 VACUUM 可以自由使用全部 + 共享缓冲区 默认值为 16 亿个事务。尽管用户可以将该值设置为 0 到 21 亿之间的任意值,VACUUM会悄悄将有效值调整为不低于的 105%。 @@ -8186,7 +7915,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 当表的pg_class.relminmxid字段达到该设置指定的年龄时,VACUUM会执行激进扫描。激进扫描与常规VACUUM不同,它会访问每一个可能包含未冻结 XID 或 MXID 的页面,而不是只扫描那些可能包含死元组的页面。默认值是 1.5 亿个 multixact。尽管用户可以将该值设置为 0 到 20 亿之间的任意值,VACUUM会悄悄将有效值调整为的 95%,从而在触发防回卷 autovacuum 之前仍有机会执行一次常规手工VACUUM。更多信息请参见。 + 当表的pg_class.relminmxid字段达到该设置指定的年龄时,VACUUM会执行激进扫描。激进扫描与常规VACUUM不同,它会访问每一个可能包含未冻结 XID 或 MXID 的页面,而不是只扫描那些可能包含死元组的页面。默认值是 1.5 亿个多事务。尽管用户可以将该值设置为 0 到 20 亿之间的任意值,VACUUM会悄悄将有效值限制为不超过的 95%,从而在触发防回卷 autovacuum 之前仍有机会执行一次常规手工VACUUM。更多信息请参见 @@ -8199,29 +7928,31 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 指定VACUUM在扫描表时用来决定是否将 multixact ID 替换为较新的事务 ID 或 multixact ID 的切断年龄(以 multixact 计)。默认值是 5000 万个 multixact。尽管用户可以将该值设置为 0 到 10 亿之间的任意值,VACUUM会悄悄将有效值调整为的一半,这样强制 autovacuum 之间就不会间隔过短。更多信息请参见。 + 指定VACUUM用来决定是否触发对含有较旧多事务 ID 的页面进行冻结的截止年龄(以多事务计)。默认值是 500 万个多事务。尽管用户可以将该值设置为 0 到 10 亿之间的任意值,VACUUM会悄悄将有效值限制为不超过的一半,这样强制 autovacuum 之间就不会间隔过短。更多信息请参见 + + - vacuum_multixact_failsafe_age (integer) - - vacuum_multixact_failsafe_age配置参数 - - - + vacuum_multixact_failsafe_age (integer) + + vacuum_multixact_failsafe_age 配置参数 + + + - 指定表的pg_class.relminmxid字段在VACUUM采取特别措施以避免系统范围 multixact ID 回卷失败之前所允许达到的最大年龄(以 multixact 计)。这是VACUUM的最后防线。失效保护通常会在防止事务 ID 回卷的 autovacuum 已经运行了一段时间后触发,但也有可能在任何VACUUM期间触发。 + 指定表的 pg_class.relminmxid 字段在 VACUUM 采取特别措施避免系统范围的多事务 ID 回卷故障之前,所能达到的最大年龄(以多事务计)。这是 VACUUM 的最后手段。失效保护通常会在防止事务 ID 回卷的自动清理已经运行一段时间后触发,但也可能在任何 VACUUM 期间触发。 - 当失效保护被触发时,将不再应用任何有效的基于成本的延迟,并且会跳过进一步的非关键维护任务(例如索引 vacuum)。 + 触发失效保护后,任何正在生效的基于代价的延迟都将不再应用,后续非必要的维护任务(例如索引清理)也会被跳过。 - 默认值为 16 亿个 multixact。尽管用户可以将该值设置为 0 到 21 亿之间的任意值,VACUUM会悄悄将有效值调整为不低于的 105%。 + 默认值为 16 亿个多事务。虽然用户可以将此值设置为 0 到 21 亿之间的任意值,VACUUM 仍会将实际生效值自动调整为不低于 的 105%。 - + vacuum_max_eager_freeze_failure_rate (floating point) @@ -8231,10 +7962,10 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - 指定VACUUM在积极扫描模式下可以扫描但未能在可见性映射中设置为 all-frozen 的页面数量占整个关系总页面数的比例,超过该比例后就会禁用积极扫描。值0表示完全禁用积极扫描。默认值为0.03(3%)。 + 指定VACUUM在急切扫描模式下可以扫描但未能在可见性映射中设置为 all-frozen 的页面数量占整个关系总页面数的比例,超过该比例后就会禁用急切扫描。值0表示完全禁用急切扫描。默认值为0.03(3%)。 - 请注意,当积极扫描启用时,只有冻结失败才会计入上限,成功的冻结不会计入。成功冻结的页面在内部会被限制为关系中所有 all-visible 但未 all-frozen 页面数的 20%。对成功冻结页面设置上限有助于将成本分摊到多次常规 vacuum 中,并限制在下次积极 vacuum 之前页面再次被修改时积极冻结可能带来的浪费。 + 请注意,当急切扫描启用时,只有冻结失败才会计入上限,成功的冻结不会计入。成功冻结的页面在内部会被限制为关系中所有 all-visible 但未 all-frozen 页面数的 20%。对成功冻结页面设置上限有助于将成本分摊到多次常规清理 中,并限制在下次激进清理 之前页面再次被修改时急切冻结可能带来的浪费。 这个参数只能在postgresql.conf文件中或服务器命令行上设置; @@ -8288,7 +8019,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; search_path配置参数 - pathfor schemas + 路径用于模式 @@ -8381,7 +8112,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; default_tablespace配置参数 - tablespacedefault + 表空间默认 @@ -8486,7 +8217,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; default_transaction_isolation (enum) - transaction isolation level + 事务隔离级别 设置默认值 @@ -8509,7 +8240,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; default_transaction_read_only (boolean) - read-only transaction + 只读事务 设置默认值 @@ -8532,7 +8263,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; default_transaction_deferrable (boolean) - deferrable transaction + 可延迟事务 设置默认值 @@ -8559,7 +8290,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; transaction_isolation (enum) - transaction isolation level + 事务隔离级别 transaction_isolation配置参数 @@ -8579,7 +8310,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; transaction_read_only (boolean) - read-only transaction + 只读事务 transaction_read_only 配置参数 @@ -8599,7 +8330,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; transaction_deferrable (boolean) - deferrable transaction + 可延迟事务 transaction_deferrable 配置参数 @@ -8743,7 +8474,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; 此选项可以用于确保空闲会话不会在不合理的时间内持有锁。 - 即使没有持有重要的锁的时候,打开的事务也会防止清理最近死亡的可能只对这个事务可见的元组;所以长时间保持空闲会导致表膨胀。 + 即使没有持有重要的锁的时候,打开的事务也会防止清理最近死亡的可能只对这个事务可见的元组;所以长时间保持空闲会导致表膨胀。 详见 @@ -8819,7 +8550,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; SET XML OPTION - XML option + XML 选项 @@ -8857,6 +8588,54 @@ SET XML OPTION { DOCUMENT | CONTENT }; + + createrole_self_grant (string) + + createrole_self_grant配置参数 + + + + + 如果一个拥有CREATEROLE但不拥有SUPERUSER权限的用户创建了角色,并且此选项被设置为非空值,则新创建的角色将以指定选项授予创建者。 + 该值必须是setinherit或它们的逗号分隔列表。默认值为空字符串,这会禁用此功能。 + + + 此选项的目的是允许非超级用户的CREATEROLE用户自动继承或自动获得对新创建角色执行SET ROLE的能力。 + 由于CREATEROLE用户始终会隐式获得其所创建角色的ADMIN OPTION,因此该用户总是可以通过执行GRANT语句达到相同效果,但自动授予在可用性上更方便。 + 超级用户会自动继承每个角色的权限,并且始终可以切换到任何角色;此设置可让CREATEROLE用户对其创建的用户获得类似的行为。 + + + + + + event_triggers (boolean) + + event_triggers配置参数 + + + + + 允许临时禁用事件触发器的执行,以便对有故障的事件触发器进行故障排查和修复。 + 将其设置为false会禁用所有事件触发器;设置为true则允许所有事件触发器触发,这也是默认值。 + 只有超级用户和具有适当SET权限的用户才能更改此设置。 + + + + + + restrict_nonsystem_relation_kind (string) + + restrict_nonsystem_relation_kind配置参数 + + + + + 设置禁止访问非系统关系的关系类型。该值采用关系类型的逗号分隔列表形式。 + 目前支持的关系类型是viewforeign-table。 + + + + @@ -8905,7 +8684,7 @@ SET XML OPTION { DOCUMENT | CONTENT }; TimeZone配置参数 - time zone + 时区 @@ -8921,7 +8700,7 @@ SET XML OPTION { DOCUMENT | CONTENT }; timezone_abbreviations配置参数 - time zone names + 时区名称 @@ -8935,11 +8714,11 @@ SET XML OPTION { DOCUMENT | CONTENT }; extra_float_digits (integer) - significant digits + 有效数字 - floating-point - display + 浮点数 + 显示 extra_float_digits配置参数 @@ -8967,7 +8746,7 @@ SET XML OPTION { DOCUMENT | CONTENT }; - 此参数的含义,以及其默认值,在 PostgreSQL 12 中发生了变化; + 此参数的含义,以及其默认值,在 PostgreSQL 12 中发生了变化; 参见 以便进一步讨论。 @@ -8980,7 +8759,7 @@ SET XML OPTION { DOCUMENT | CONTENT }; client_encoding配置参数 - character set + 字符集 @@ -9340,8 +9119,12 @@ extension_control_path = 'C:\tools\postgresql;H:\my_project\share;$system' 推荐在postgresql.conf中设置该参数。 - 请注意,如果你设置该参数以便从非标准位置加载扩展,那么通常还需要把设置为相应的位置。 - + 请注意,如果设置此参数以便从非标准位置加载扩展,通常还需要将设置为相应的位置,例如: + +extension_control_path = '/usr/local/share/postgresql:$system' +dynamic_library_path = '/usr/local/lib/postgresql:$libdir' + + @@ -9374,12 +9157,12 @@ extension_control_path = 'C:\tools\postgresql;H:\my_project\share;$system' deadlock_timeout (integer) - deadlock + 死锁 期间超时 - timeout - deadlock + 超时 + 死锁 deadlock_timeout配置参数 @@ -9414,7 +9197,7 @@ extension_control_path = 'C:\tools\postgresql;H:\my_project\share;$system' - 共享锁表为每个服务器进程或预备事务预留可容纳max_locks_per_transaction 个对象(例如表)的空间;因此,在任何时刻可被锁住的不同对象数都不能超过总容量。这个参数限制每个事务使用的对象锁的平均数量;只要所有事务的锁能放入锁表中,单个事务就可以锁住更多对象。这是能被锁住的行数,那个值是没有限制的。默认值 128 已经被历史证明是足够的,但是如果你有需要在一个事务中使用很多不同表的查询(例如查询一个有很多子表的父表),你可能需要提高这个值。这个参数只能在服务器启动时设置。 + 共享锁表为每个服务器进程或预备事务预留可容纳max_locks_per_transaction 个对象(例如表)的空间;因此,在任何时刻可被锁住的不同对象数都不能超过总容量。这个参数限制每个事务使用的对象锁的平均数量;只要所有事务的锁能放入锁表中,单个事务就可以锁住更多对象。这是能被锁住的行数,那个值是没有限制的。默认值 128 已经被历史证明是足够的,但是如果你有需要在一个事务中使用很多不同表的查询(例如查询一个有很多子表的父表),你可能需要提高这个值。这个参数只能在服务器启动时设置。 此参数还决定每个后端可用于快速路径加锁的槽数量。 @@ -9439,9 +9222,7 @@ extension_control_path = 'C:\tools\postgresql;H:\my_project\share;$system' - 共享谓词锁表跟踪在max_pred_locks_per_transaction * ( + ) 个对象(如表)上的锁。因此,在任何一个时刻,只有不超过这么多个可区分对象能够被锁住。这个参数控制为每个事务分配的对象锁的平均数量。个体事务可以锁住更多对象,数量可以和锁表中能容纳的所有事务的锁一样多。这是能被锁住的行数,那个值是没有限制的。默认值 64 已经在测试中被证明通常是足够的,但是如果你有需要在一个可串行化事务中使用很多不同表的查询(例如查询一个有很多子表的父表),你可能需要提高这个值。这个参数只能在服务器启动时设置。 + 共享谓词锁表为每个服务器进程或预备事务预留可容纳max_pred_locks_per_transaction 个对象(例如表)的空间;因此,在任何时刻可被锁住的不同对象数都不能超过总容量。这个参数限制每个事务使用的对象锁的平均数量;只要所有事务的锁能放入锁表中,单个事务就可以锁住更多对象。这是能被锁住的行数,那个值是没有限制的。默认值 64 已经被历史证明是足够的,但是如果你有会在单个可串行化事务中访问许多不同表的客户端,则可能需要提高这个值。这个参数只能在服务器启动时设置。 @@ -9511,7 +9292,7 @@ extension_control_path = 'C:\tools\postgresql;H:\my_project\share;$system' backslash_quote (enum) - stringsbackslash quotes + 字符串反斜线引号 backslash_quote配置参数 @@ -9569,7 +9350,7 @@ extension_control_path = 'C:\tools\postgresql;H:\my_project\share;$system' standard_conforming_strings (boolean) - stringsstandard conforming + 字符串标准符合 standard_conforming_strings配置参数 @@ -10012,7 +9793,7 @@ extension_control_path = 'C:\tools\postgresql;H:\my_project\share;$system' server_encoding配置参数 - character set + 字符集 diff --git a/zh/20/datatype.sgml b/zh/20/datatype.sgml index 596c5b6d..6cfddb07 100644 --- a/zh/20/datatype.sgml +++ b/zh/20/datatype.sgml @@ -354,19 +354,19 @@ smallint 2字节 小范围整数 - -32768 to +32767 + -32768 到 +32767 integer 4字节 整数的典型选择 - -2147483648 to +2147483647 + -2147483648 到 +2147483647 bigint 8字节 大范围整数 - -9223372036854775808 to +9223372036854775807 + -9223372036854775808 到 +9223372036854775807 @@ -866,9 +866,8 @@ FROM generate_series(-3.5, 3.5, 1) AS x; - 本节描述的是 PostgreSQL 特有的创建 - 自动递增列的方法。另一种方法是使用 SQL 标准的标识列特性, - 参见 。 + 本节介绍 PostgreSQL 特有的自动递增列创建方法。 + 另一种方法是使用 SQL 标准的标识列特性,参见 @@ -947,7 +946,7 @@ ALTER SEQUENCE tablename_money 类型以固定的小数精度存储货币金额; 参见 。小数精度由数据库的 设置决定。表中显示的范围假定 - 有两位小数。输入支持多种格式,包括整数和浮点文字,以及典型的 + 有两位小数。输入支持多种格式,包括整数字面量和浮点数字面量,以及典型的 货币格式,例如 '$1,000.00'。输出通常也采用 后一种形式,但会受到区域设置影响。 @@ -1373,7 +1372,7 @@ SELECT '\xDEADBEEF'::bytea;
- <type>bytea</type>文字转义字节 + <type>bytea</type>字面量中需要转义的字节 @@ -2639,7 +2638,7 @@ SELECT '2 years 15 months 100 weeks 99 hours 123456789 milliseconds'::interval; 3 years 3 mons 700 days 133:17:36.789 - 这里,周被理解为 7 days,而较小和较大的时间单位 + 这里,周按7 天计算并单独保留,而较小和较大的时间单位 则被合并并规范化了。 @@ -4080,17 +4079,16 @@ decode('HqPWTLxATMOEu2sR7jHlwg==', 'base64')::uuid xml 数据类型可用于存储 XML 数据。与把 XML 数据存储在 - text 字段中相比,它的优势在于会检查输入值是否格式 - 良好,并且提供了可执行类型安全操作的支持函数;见 - 。使用该数据类型要求安装时启用 + text 字段中相比,它的优势在于会检查输入值的良构性,并且提供了可执行类型安全操作的支持函数;见 + 。使用该数据类型要求构建时使用 configure --with-libxml - xml 类型既可以存储符合 XML 标准定义的格式良好的 + xml 类型既可以存储 XML 标准所定义的良构 文档,也可以存储 内容 片段;后者是参照 XQuery 和 XPath 数据模型中更宽松的 - document node + 文档节点 概念来定义的。粗略地说,这意味着内容片段可以拥有多个顶层元素或字符 节点。表达式 xmlvalue IS DOCUMENT @@ -4259,7 +4257,7 @@ SET xmloption TO { DOCUMENT | CONTENT }; - 是一种用户定义的数据类型,它基于另一种底层类型。根据需要,它可以有约束来限制其有效值为底层类型所允许值的一个子集。如果没有约束,它的行为就和底层类型一样 — 例如,任何适用于底层类型的操作符或函数都对该域类型有效。底层类型可以是任何内置或者用户定义的基础类型、枚举类型、数组类型、复合类型、范围类型或者另一个域。 + 是一种用户定义的数据类型,它基于另一种底层类型。根据需要,它可以有约束来限制其有效值为底层类型所允许值的一个子集。除此之外,它的行为与底层类型相同 — 例如,任何适用于底层类型的操作符或函数都对该域类型有效。底层类型可以是任何内置或者用户定义的基础类型、枚举类型、数组类型、复合类型、范围类型或者另一个域。 diff --git a/zh/20/dblink.sgml b/zh/20/dblink.sgml index 695aeb8a..aa940dca 100644 --- a/zh/20/dblink.sgml +++ b/zh/20/dblink.sgml @@ -65,8 +65,8 @@ -dblink_connect(text connstr) 返回 text -dblink_connect(text connname, text connstr) 返回 text +dblink_connect(text connstr) returns text +dblink_connect(text connname, text connstr) returns text @@ -128,7 +128,7 @@ dblink_connect(text connname, text connstr) 返回 text 注解 - 如果不可信用户能够访问一个尚未采用模式的安全使用方式的数据库,则应在每个会话开始时从 + 如果不受信任的用户能够访问一个尚未采用模式的安全使用方式的数据库,则应在每个会话开始时从 search_path 中移除公共可写模式。例如,可以把 options=-csearch_path= 加到 connstr 中。这个注意事项并非 dblink 所特有;它适用于每一种执行任意 SQL 命令的接口。 @@ -139,7 +139,7 @@ dblink_connect(text connname, text connstr) 返回 text use_scram_passthrough,用于控制 dblink 是否在连接远程数据库时使用 SCRAM 透传认证。 该选项可为外部服务器或用户映射指定。用户映射的设置会覆盖外部服务器的设置。 - 使用 SCRAM 透传认证时,dblink 会使用 SCRAM 哈希后的凭据,而不是明文用户密码来连接远程服务器。 + 使用 SCRAM 透传认证时,dblink 会使用经 SCRAM Hash 处理的凭据,而不是明文用户密码来连接远程服务器。 这样可以避免在 PostgreSQL 系统目录中存储明文用户密码。关于更多细节和限制,请参见 postgres_fdw 中对应的 use_scram_passthrough @@ -174,10 +174,10 @@ SELECT dblink_connect('myconn', 'dbname=postgres options=-csearch_path='); OK (1 row) --- FOREIGN DATA WRAPPER functionality --- Note: local connections that don't use SCRAM pass-through require password --- authentication for this to work properly. Otherwise, you will receive --- the following error from dblink_connect(): +-- FOREIGN DATA WRAPPER 功能 +-- 注意:要使本例正常工作,不使用 SCRAM 透传的本地连接必须要求密码认证。 +-- 否则,dblink_connect() 将报告 +-- 以下错误: -- ERROR: password is required -- DETAIL: Non-superuser cannot connect if the server does not request a password. -- HINT: Target server's authentication method must be changed. @@ -240,8 +240,8 @@ DROP SERVER fdtest; -dblink_connect_u(text connstr) 返回 text -dblink_connect_u(text connname, text connstr) 返回 text +dblink_connect_u(text connstr) returns text +dblink_connect_u(text connname, text connstr) returns text @@ -261,7 +261,7 @@ dblink_connect_u(text connname, text connstr) 返回 text 因此,dblink_connect_u() 在初始安装时会撤销 PUBLIC 的全部权限,从而除了超级用户之外无法调用它。 在某些情况下,可能适合向被认为可信的特定用户授予 - EXECUTE 权限,但必须谨慎操作。还建议服务器用户的任何 + dblink_connect_u()EXECUTE 权限,但必须谨慎操作。还建议服务器用户的任何 ~/.pgpass 文件不要包含指定通配主机名的记录。 @@ -288,8 +288,8 @@ dblink_connect_u(text connname, text connstr) 返回 text -dblink_disconnect() 返回 text -dblink_disconnect(text connname) 返回 text +dblink_disconnect() returns text +dblink_disconnect(text connname) returns text @@ -361,9 +361,9 @@ SELECT dblink_disconnect('myconn'); -dblink(text connname, text sql [, bool fail_on_error]) 返回 setof record -dblink(text connstr, text sql [, bool fail_on_error]) 返回 setof record -dblink(text sql [, bool fail_on_error]) 返回 setof record +dblink(text connname, text sql [, bool fail_on_error]) returns setof record +dblink(text connstr, text sql [, bool fail_on_error]) returns setof record +dblink(text sql [, bool fail_on_error]) returns setof record @@ -440,7 +440,7 @@ SELECT * WHERE proname LIKE 'bytea%'; - FROM 子句中的 alias 部分必须指定该函数将返回的列名和类型。(在别名中指定列名实际上是标准 SQL 语法,但指定列类型则是 + FROM 子句中的 别名 部分必须指定该函数将返回的列名和类型。(在别名中指定列名实际上是标准 SQL 语法,但指定列类型则是 PostgreSQL 的扩展。)这样系统才能在尝试执行该函数之前,就知道 * 应展开成什么,以及 WHERE 子句中的 proname 指的是什么。运行时,如果远程数据库返回的实际查询结果与 @@ -560,9 +560,9 @@ SELECT * FROM dblink('myconn', 'SELECT proname, prosrc FROM pg_proc') -dblink_exec(text connname, text sql [, bool fail_on_error]) 返回 text -dblink_exec(text connstr, text sql [, bool fail_on_error]) 返回 text -dblink_exec(text sql [, bool fail_on_error]) 返回 text +dblink_exec(text connname, text sql [, bool fail_on_error]) returns text +dblink_exec(text connstr, text sql [, bool fail_on_error]) returns text +dblink_exec(text sql [, bool fail_on_error]) returns text @@ -687,8 +687,8 @@ DETAIL: ERROR: null value in column "relnamespace" violates not-null constrain -dblink_open(text cursorname, text sql [, bool fail_on_error]) 返回 text -dblink_open(text connname, text cursorname, text sql [, bool fail_on_error]) 返回 text +dblink_open(text cursorname, text sql [, bool fail_on_error]) returns text +dblink_open(text connname, text cursorname, text sql [, bool fail_on_error]) returns text @@ -801,8 +801,8 @@ SELECT dblink_open('foo', 'SELECT proname, prosrc FROM pg_proc'); -dblink_fetch(text cursorname, int howmany [, bool fail_on_error]) 返回 setof record -dblink_fetch(text connname, text cursorname, int howmany [, bool fail_on_error]) 返回 setof record +dblink_fetch(text cursorname, int howmany [, bool fail_on_error]) returns setof record +dblink_fetch(text connname, text cursorname, int howmany [, bool fail_on_error]) returns setof record @@ -944,8 +944,8 @@ SELECT * FROM dblink_fetch('foo', 5) AS (funcname name, source text); -dblink_close(text cursorname [, bool fail_on_error]) 返回 text -dblink_close(text connname, text cursorname [, bool fail_on_error]) 返回 text +dblink_close(text cursorname [, bool fail_on_error]) returns text +dblink_close(text connname, text cursorname [, bool fail_on_error]) returns text @@ -1050,7 +1050,7 @@ SELECT dblink_close('foo'); -dblink_get_connections() 返回 text[] +dblink_get_connections() returns text[] @@ -1066,7 +1066,7 @@ dblink_get_connections() 返回 text[] 返回值 - 返回一个包含连接名称的 text 数组;如果没有,则返回 NULL。 + 返回包含连接名称的文本数组;如果没有连接,则返回 NULL。 @@ -1095,7 +1095,7 @@ SELECT dblink_get_connections(); -dblink_error_message(text connname) 返回 text +dblink_error_message(text connname) returns text @@ -1166,7 +1166,7 @@ SELECT dblink_error_message('dtest1'); -dblink_send_query(text connname, text sql) 返回 int +dblink_send_query(text connname, text sql) returns int @@ -1241,7 +1241,7 @@ SELECT dblink_send_query('dtest1', 'SELECT * FROM foo WHERE f1 < 3'); -dblink_is_busy(text connname) 返回 int +dblink_is_busy(text connname) returns int @@ -1303,8 +1303,8 @@ SELECT dblink_is_busy('dtest1'); -dblink_get_notify() 返回 setof (notify_name text, be_pid int, extra text) -dblink_get_notify(text connname) 返回 setof (notify_name text, be_pid int, extra text) +dblink_get_notify() returns setof (notify_name text, be_pid int, extra text) +dblink_get_notify(text connname) returns setof (notify_name text, be_pid int, extra text) @@ -1383,7 +1383,7 @@ SELECT * FROM dblink_get_notify(); -dblink_get_result(text connname [, bool fail_on_error]) 返回 setof record +dblink_get_result(text connname [, bool fail_on_error]) returns setof record @@ -1529,7 +1529,7 @@ contrib_regression=# SELECT * FROM dblink_get_result('dtest1') AS t1(f1 int, f2 -dblink_cancel_query(text connname) 返回 text +dblink_cancel_query(text connname) returns text @@ -1592,7 +1592,7 @@ SELECT dblink_cancel_query('dtest1'); -dblink_get_pkey(text relname) 返回 setof dblink_pkey_results +dblink_get_pkey(text relname) returns setof dblink_pkey_results @@ -1681,7 +1681,7 @@ dblink_build_sql_insert(text relname, int2vector primary_key_attnums, integer num_primary_key_atts, text[] src_pk_att_vals_array, - text[] tgt_pk_att_vals_array) 返回 text + text[] tgt_pk_att_vals_array) returns text @@ -1750,7 +1750,7 @@ dblink_build_sql_insert(text relname, 返回值 - 以 text 形式返回所请求的 SQL 语句。 + 以文本形式返回所请求的 SQL 语句。 @@ -1797,7 +1797,7 @@ SELECT dblink_build_sql_insert('foo', '1 2', 2, '{"1", "a"}', '{"1", "b''a"}'); dblink_build_sql_delete(text relname, int2vector primary_key_attnums, integer num_primary_key_atts, - text[] tgt_pk_att_vals_array) 返回 text + text[] tgt_pk_att_vals_array) returns text @@ -1857,7 +1857,7 @@ dblink_build_sql_delete(text relname, 返回值 - 以 text 形式返回所请求的 SQL 语句。 + 以文本形式返回所请求的 SQL 语句。 @@ -1905,7 +1905,7 @@ dblink_build_sql_update(text relname, int2vector primary_key_attnums, integer num_primary_key_atts, text[] src_pk_att_vals_array, - text[] tgt_pk_att_vals_array) 返回 text + text[] tgt_pk_att_vals_array) returns text @@ -1975,7 +1975,7 @@ dblink_build_sql_update(text relname, 返回值 - 以 text 形式返回所请求的 SQL 语句。 + 以文本形式返回所请求的 SQL 语句。 diff --git a/zh/20/ddl.sgml b/zh/20/ddl.sgml index f3a9a39d..f4169d87 100644 --- a/zh/20/ddl.sgml +++ b/zh/20/ddl.sgml @@ -319,7 +319,7 @@ CREATE TABLE people ( - 类似地,对于分区表,如果在CREATE TABLE ... PARTITION OF中编写子列定义时未写任何GENERATED子句,则会自动从父列复制该子句。ALTER TABLE ... ATTACH PARTITION要求父列和子列在生成状态上已经匹配,但不要求它们的生成表达式相同。 + 类似地,对于分区表,如果在CREATE TABLE ... PARTITION OF中编写子列定义时未写任何GENERATED子句,则会自动从父列复制该GENERATED子句。ALTER TABLE ... ATTACH PARTITION要求父列和子列在生成状态上已经匹配,但不要求它们的生成表达式相同。 @@ -3521,8 +3521,8 @@ CREATE TABLE measurement_y2008m02 PARTITION OF measurement 作为一种替代方案,有时更方便的是在分区结构之外创建新表,并稍后将其附加为分区。这允许在新数据出现在分区表中之前加载、检查和转换新数据。 - 此外,ATTACH PARTITION操作只需要在分区表上持有SHARE UPDATE EXCLUSIVE锁,而不像CREATE TABLE ... PARTITION OF那样需要ACCESS EXCLUSIVE锁,因此对分区表上的并发操作更友好。 - CREATE TABLE ... LIKE选项有助于避免繁琐地重复父表定义: + 此外,ALTER TABLE ... ATTACH PARTITION操作只需要在分区表上持有SHARE UPDATE EXCLUSIVE锁,而不像CREATE TABLE ... PARTITION OF那样需要ACCESS EXCLUSIVE锁,因此对分区表上的并发操作更友好。 + CREATE TABLE ... LIKE选项有助于避免繁琐地重复父表定义: CREATE TABLE measurement_y2008m02 @@ -3704,7 +3704,16 @@ ALTER INDEX measurement_city_id_logdate_key - 创建表,所有的表都将从它继承。这个表将不包含数据。不要在这个表上定义任何检查约束,除非想让它们应用到所有的子表上。同样,在这个表上定义索引或者唯一约束也没有意义。对于我们的示例来说,根表是最初定义的measurement表。 + 创建表,所有的表都将从它继承。这个表将不包含数据。不要在这个表上定义任何检查约束,除非想让它们应用到所有的子表上。同样,在这个表上定义索引或者唯一约束也没有意义。对于我们的示例来说,根表是最初定义的measurement表: + + +CREATE TABLE measurement ( + city_id int not null, + logdate date not null, + peaktemp int, + unitsales int +); + @@ -4313,7 +4322,7 @@ DROP TABLE products CASCADE; - 对于一个将其主体定义为字符串文字的用户定义函数或过程,PostgreSQL会跟踪与函数的外部可见属性相关的依赖关系,例如其参数和结果类型,但不会跟踪只有通过检查函数主体才能知道的依赖关系。例如,考虑以下情况: + 对于一个将其主体定义为字符串字面量的用户定义函数或过程,PostgreSQL会跟踪与函数的外部可见属性相关的依赖关系,例如其参数和结果类型,但不会跟踪只有通过检查函数主体才能知道的依赖关系。例如,考虑以下情况: CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', diff --git a/zh/20/dfunc.sgml b/zh/20/dfunc.sgml index 2070d7f6..0f456690 100644 --- a/zh/20/dfunc.sgml +++ b/zh/20/dfunc.sgml @@ -46,7 +46,7 @@ FreeBSD - FreeBSDshared library + FreeBSD共享库 @@ -65,7 +65,7 @@ cc -shared -o foo.so foo.o Linux - Linuxshared library + Linux共享库 @@ -82,7 +82,7 @@ cc -shared -o foo.so foo.o macOS - macOSshared library + macOS共享库 @@ -98,7 +98,7 @@ cc -bundle -flat_namespace -undefined suppress -o foo.so foo.o NetBSD - NetBSDshared library + NetBSD共享库 @@ -116,7 +116,7 @@ gcc -shared -o foo.so foo.o OpenBSD - OpenBSDshared library + OpenBSD共享库 @@ -133,7 +133,7 @@ ld -Bshareable -o foo.so foo.o Solaris - Solarisshared library + Solaris共享库 diff --git a/zh/20/docguide.sgml b/zh/20/docguide.sgml index c0e8df51..1dacec9b 100644 --- a/zh/20/docguide.sgml +++ b/zh/20/docguide.sgml @@ -306,7 +306,7 @@ checking for dbtoepub... dbtoepub - 对于 U.S. letter 格式: + 对于美国信纸格式: doc/src/sgml$ make postgres-US.pdf @@ -320,7 +320,7 @@ checking for dbtoepub... dbtoepub 因此,在某些系统上,构建会因内存相关错误而失败。这通常可以通过在配置文件 ~/.foprc中配置 Java 堆设置来解决,例如: -# FOP binary distribution +# FOP 二进制发行版 FOP_OPTS='-Xmx1500m' # Debian JAVA_ARGS='-Xmx1500m' diff --git a/zh/20/ecpg.sgml b/zh/20/ecpg.sgml index bd5b3ca4..373254b5 100644 --- a/zh/20/ecpg.sgml +++ b/zh/20/ecpg.sgml @@ -1139,7 +1139,7 @@ oid=313780, datname=testdb, size=8183012 - 结构体主变量将列尽数吸收成结构体的域。额外的列可以被分配给其他主变量。例如,上面的程序也可以使用结构体外部的size变量重新构造: + 结构体主变量吸收的列数与结构体的字段数相同。额外的列可以被分配给其他主变量。例如,上面的程序也可以使用结构体外部的size变量改写: EXEC SQL BEGIN DECLARE SECTION; typedef struct @@ -1440,7 +1440,7 @@ while (1) 用户定义的基础类型 - ECPG 并不直接支持新的用户定义的基本类型。你可以使用外部字符串表示以及类型char[]VARCHAR[]的主变量,并且这种方案事实上对很多类型都是合适和足够的。 + ECPG 并不直接支持新的用户定义的基础类型。你可以使用外部字符串表示以及类型char[]VARCHAR[]的主变量,并且这种方案事实上对很多类型都是合适和足够的。 @@ -4743,7 +4743,7 @@ EXEC SQL INCLUDE "filename"; 当前目录 /usr/local/include - PostgreSQL 的包括目录,在编译时定义(例如/usr/local/pgsql/include + PostgreSQL 的头文件目录,在编译时定义(例如/usr/local/pgsql/include /usr/include @@ -4870,7 +4870,7 @@ EXEC SQL UPDATE Tbl SET col = MYNUMBER; - 此示例将完全编译三个SET TIMEZONE命令之一: + 此示例将完全编译三个SET TIMEZONE命令之一: EXEC SQL ifdef TZVAR; EXEC SQL SET TIMEZONE TO TZVAR; @@ -5498,7 +5498,7 @@ DATABASE connection_target 使用 user_name/passworduser_name IDENTIFIED BY password或者 - user_name USING password之一,这个参数也能指定用户名和密码. + user_name USING password之一,这个参数也能指定用户名和密码。 @@ -6078,9 +6078,7 @@ EXECUTE IMMEDIATE string - 如果你使用文字字符串,请注意任何你可能希望在SQL语句中包括的双引号必须写为八进制转义(\042) ,而不是通常的C惯语\"。 - 这是因为字符串在EXEC SQL段里面,所以ECPG 语法分析器根据SQL规则而不是C规则来解析它。 - 任何内嵌的反斜杠后续将按照C规格处理;但是\"会造成直接语法错误,因为它被视为文字的终结。 + 如果使用字符串字面量,请注意,要在 SQL 语句中包含的双引号必须写为八进制转义(\042),而不是通常的 C 写法\"。这是因为字符串位于EXEC SQL段中,ECPG 词法分析器会按照 SQL 规则而非 C 规则解析它。内嵌的反斜杠随后会按照 C 规则处理;但\"会被视为字面量的结束,因此会立即引起语法错误。 @@ -6413,9 +6411,7 @@ PREPARE prepared_name FROM - 如果你使用文字字符串,请注意任何你可能希望在SQL语句中包括的双引号必须写为八进制转义(\042) ,而不是通常的C惯语\"。 - 这是因为字符串在EXEC SQL段里面,所以ECPG 语法分析器根据SQL规则而不是C规则来解析它。 - 任何内嵌的反斜杠后续将按照C规格处理;但是\"会造成直接语法错误,因为它被视为文字的终结。 + 如果使用字符串字面量,请注意,要在 SQL 语句中包含的双引号必须写为八进制转义(\042),而不是通常的 C 写法\"。这是因为字符串位于EXEC SQL段中,ECPG 词法分析器会按照 SQL 规则而非 C 规则解析它。内嵌的反斜杠随后会按照 C 规则处理;但\"会被视为字面量的结束,因此会立即引起语法错误。 @@ -7672,19 +7668,19 @@ int rjulmdy(date d, short mdy[3]); rdefmtdate - 使用格式掩码将字符字符串转换为日期类型的值。 + 使用格式掩码将字符串转换为日期类型的值。 int rdefmtdate(date *d, char *fmt, char *str); 该函数接收一个指向应该保存操作结果的日期值的指针(d), 用于解析日期的格式掩码(fmt)和包含日期文本表示的C char*字符串 (str)。文本表示应与格式掩码匹配。但是,你不需要将字符串 - 与格式掩码进行一一映射。该函数仅分析顺序顺序,并查找表示年份位置的文字 + 与格式掩码进行一一映射。该函数只分析先后顺序,并查找表示年份位置的字面文本 yyyyyy,表示月份位置的mm 和表示日期位置的dd - 该函数返回以下值: + 该函数返回以下值: diff --git a/zh/20/event-trigger.sgml b/zh/20/event-trigger.sgml index 58e1fa5b..4100d3d8 100644 --- a/zh/20/event-trigger.sgml +++ b/zh/20/event-trigger.sgml @@ -20,7 +20,7 @@ - 事件触发器行为概览 + 事件触发器行为概述 只要与事件触发器关联的事件在其定义所在数据库中发生,事件触发器就会被触发。 @@ -210,7 +210,7 @@ CALLED_AS_EVENT_TRIGGER(fcinfo) ((fcinfo)->context != NULL && IsA((fcinfo)->context, EventTriggerData)) - 如果该宏返回 true,那么就可以安全地将 fcinfo->context + 如果该宏返回真,那么就可以安全地将 fcinfo->context 转换为 EventTriggerData * 类型,并使用它所指向的 EventTriggerData 结构体。该函数 不得修改 EventTriggerData @@ -281,7 +281,7 @@ typedef struct EventTriggerData 事件触发器函数必须返回一个 NULL 指针 (不是 SQL 空值,也就是不要将 - isNull 设为 true)。 + isNull 设为真)。 diff --git a/zh/20/extend.sgml b/zh/20/extend.sgml index 32ac897b..a11f45d0 100644 --- a/zh/20/extend.sgml +++ b/zh/20/extend.sgml @@ -59,7 +59,7 @@ 类型、函数、访问方法等的信息。这些表可以由用户修改,而 PostgreSQL 又是基于这些表来运行的,这意味着 PostgreSQL 可以由用户扩展。相比之下,传统数据库 - 系统通常只能通过修改源代码中的硬编码过程,或加载由 + 系统只能通过修改源代码中的硬编码过程,或加载由 DBMS 供应商专门编写的模块来扩展。 @@ -92,7 +92,7 @@ 数据类型 - 组合 + 复合 @@ -517,7 +517,7 @@ RETURNS anycompatible AS ... 哪些 SQL 对象种类可以成为扩展成员,见 ALTER EXTENSION 的说明。特别是,数据库集簇范围内的对象,如数据库、角色和表空间,不能 - 成为扩展成员,因为扩展只在单个数据库内可见。(尽管扩展脚本并不禁止创 + 成为扩展成员,因为扩展只在单个数据库内可见。(尽管并不禁止扩展脚本创 建这类对象,但如果这样做,它们不会作为扩展的一部分受到跟踪。)还要注意, 虽然表可以成为扩展成员,但其附属对象(如索引)并不直接被视为扩展成员。 另一个重要点是,模式可以属于扩展,但反过来不成立:扩展本身只有一个非 @@ -672,21 +672,7 @@ RETURNS anycompatible AS ... trusted (boolean) - - 如果该参数被设为 true(默认并非如此),则允许某些 - 非超级用户安装 superuser 设为 - true 的扩展。具体来说,任何在当前数据库上具有 - CREATE 权限的用户都被允许安装。当执行 - CREATE EXTENSION 的用户不是超级用户,但因该参数 - 而被允许安装时,安装或更新脚本会以引导超级用户的身份运行,而不是以 - 调用用户的身份运行。如果 superuser 为 - false,这个参数就没有意义。一般来说,对于可能让 - 用户访问原本只有超级用户才能使用的能力(如文件系统访问)的扩展,不 - 应把它设为 true。此外,把一个扩展标记为 - trusted,还需要付出大量额外努力来确保安装和更 - 新脚本写得足够安全;见 - 。 - + 如果将此参数设为 true(不是默认值),则允许某些非超级用户安装 superuser 设为 true 的扩展。具体而言,当前数据库上具有 CREATE 权限的任何人都可以安装。当执行 CREATE EXTENSION 的用户不是超级用户,但凭借此参数获准安装时,安装或更新脚本会以引导超级用户的身份运行,而不是调用用户的身份。如果 superuserfalse,则此参数不起作用。通常,对于可能允许访问原本仅限超级用户使用的能力(例如文件系统访问)的扩展,不应将此参数设为真。此外,将扩展标记为受信任的,需要投入大量额外工作来安全地编写其安装和更新脚本;参见 @@ -747,8 +733,8 @@ RETURNS anycompatible AS ... 如果扩展脚本中包含字符串 @extowner@,该字符串会被 替换为调用 CREATE EXTENSION 或 - ALTER EXTENSION 的用户名称(会作适当引用)。通常, - 这个特性被标记为 trusted 的扩展用来把选定对象的 + ALTER EXTENSION 的用户名称(会适当加上引号)。通常, + 这个特性被标记为受信任的扩展用来把选定对象的 所有权赋给调用用户, 而不是赋给引导超级用户。(不过这样做时应当谨慎。例如,把一个 C 语言 函数的所有权赋给非超级用户,会为该用户创建一条权限提升路径。) @@ -973,7 +959,7 @@ SELECT pg_catalog.pg_extension_config_dump('my_config', 'WHERE NOT standard_entr 在有合适更新脚本可用的前提下, - ALTER EXTENSION UPDATE 命令可以把已安装的扩展更新 + ALTER EXTENSION UPDATE 命令会把已安装的扩展更新 到指定的新版本。更新脚本运行在 CREATE EXTENSION 为安装脚本提供的同一环境中:尤其 是,search_path 的设置方式完全相同,而且脚本创建的 @@ -999,7 +985,7 @@ SELECT pg_catalog.pg_extension_config_dump('my_config', 'WHERE NOT standard_entr 例如,它并不知道 1.1 是否跟在 1.0 之后。它只是匹配可用的版本名,并选择需要应用 更新脚本最少的那条路径。(实际上,版本名可以是任何不包含 - --,且不以前导或尾随 - 结尾的字 + --,且不以 - 开头或结尾的字 符串。) @@ -1072,19 +1058,9 @@ SELECT * FROM pg_extension_update_paths('extension_name - - 将 superuser 属性设为 true 的 - 扩展,还必须考虑其安装脚本和更新脚本中操作所带来的安全风险。恶意用户并不难创建出特洛伊木 - 马对象,从而在后续粗心编写的扩展脚本执行时造成破坏,并借此获得超级用 - 户权限。 - + superuser 属性设为真的扩展,还必须考虑其安装和更新脚本所执行操作的安全风险。恶意用户可以创建木马对象,破坏以后对编写不慎的扩展脚本的执行,从而获得超级用户权限;这并非特别困难。 - - 如果一个扩展被标记为 trusted,那么安装用户可以自己 - 选择安装模式,而该用户可能会有意使用不安全的模式,希望借此获得超级用 - 户权限。因此,从安全角度看,trusted 扩展暴露程度 - 极高,必须仔细审查其所有脚本命令,确保不存在任何可被利用之处。 - + 如果扩展被标记为 trusted,那么安装用户可以选择其安装模式,而该用户可能故意使用不安全的模式,试图获得超级用户权限。因此,从安全角度看,受信任的扩展面临的风险极高,必须仔细检查其全部脚本命令,确保无法被攻破。 关于如何安全地编写函数,建议见下面的 @@ -1132,7 +1108,7 @@ SELECT * FROM pg_extension_update_paths('extension_namemyschema.myfunc(bigint),那么像 myschema.myfunc(42) 这样的调用,就可能被恶意函数 myschema.myfunc(integer) 截获。要注意函数和操作符 - 参数的数据类型必须与声明的实参类型精确匹配,必要时请使用显式类型转 + 所传参数的数据类型必须与声明的参数类型精确匹配,必要时请使用显式类型转 换。 @@ -1181,7 +1157,7 @@ SELECT * FROM pg_extension_update_paths('extension_name扩展示例 - 下面给出一个纯 SQL 扩展的完整示例:一个双元素组合 + 下面给出一个纯 SQL 扩展的完整示例:一个双元素复合 类型,它可以在两个槽位中存储任意类型的值,这两个槽位名为 kv。非文本值会自动强制转换为文本后 再存储。 @@ -1262,7 +1238,7 @@ include $(PGXS) 如果你打算分发自己的 PostgreSQL 扩展模块, - 那么为它们搭建一个可移植的构建系统会相当困难。因此, + 那么为它们搭建一个可移植的构建系统可能相当困难。因此, PostgreSQL 安装提供了一套称为 PGXS 的扩展构建基础设施,使简单的扩展模块可以针对 已安装好的服务器直接构建。PGXS 主要面向包含 C 代码 @@ -1313,7 +1289,7 @@ include $(PGXS) MODULE_big - 要从多个源文件构建的共享库(在 OBJS 中列出对象 + 要从多个源文件构建的共享库(在 OBJS 中列出目标 文件) @@ -1323,7 +1299,7 @@ include $(PGXS) PROGRAM - 要构建的可执行程序(在 OBJS 中列出对象文件) + 要构建的可执行程序(在 OBJS 中列出目标文件) @@ -1678,7 +1654,7 @@ make VPATH=/path/to/extension/source/tree install 正在运行的 PostgreSQL 服务器。列在 REGRESS 中的脚本文件必须位于扩展目录下名为 sql/ 的子目录中。这些文件必须具有 - .sql 扩展名,而该扩展名不应出现在 makefile 的 + .sql 扩展名,而该扩展名不能出现在 makefile 的 REGRESS 列表中。对于每个测试,还应在名为 expected/ 的子目录中有一个包含期望输出的文件,其主 干名相同,扩展名为 .out。 @@ -1697,7 +1673,7 @@ make VPATH=/path/to/extension/source/tree install 必须有一个正在运行的 PostgreSQL 服务器。列 在 ISOLATION 中的脚本文件必须位于扩展目录下名为 specs/ 的子目录中。这些文件必须具有 - .spec 扩展名,而该扩展名不应出现在 makefile 的 + .spec 扩展名,而该扩展名不能出现在 makefile 的 ISOLATION 列表中。对于每个测试,还应在名为 expected/ 的子目录中有一个包含期望输出的文件,其主 干名相同,扩展名为 .out。 diff --git a/zh/20/fdwhandler.sgml b/zh/20/fdwhandler.sgml index 64cd8836..8298857d 100644 --- a/zh/20/fdwhandler.sgml +++ b/zh/20/fdwhandler.sgml @@ -753,7 +753,7 @@ RecheckForeignScan(ForeignScanState *node, - <command>EXPLAIN</command>的FDW例程 + <command>EXPLAIN</command> 的 FDW 例程 @@ -803,7 +803,7 @@ ExplainDirectModify(ForeignScanState *node, - <command>ANALYZE</command>的FDW例程 + <command>ANALYZE</command> 的 FDW 例程 diff --git a/zh/20/features.sgml b/zh/20/features.sgml index f212af45..866569f6 100644 --- a/zh/20/features.sgml +++ b/zh/20/features.sgml @@ -408,7 +408,7 @@ SELECT XMLQUERY('$a is $b' PASSING BY VALUE x AS a, < DOCUMENTCONTENT形式的值。 一个 XQuery/XPath 表达式的上下文项必须是单个 XML 节点或原子值, 但 XPath 1.0 又进一步限制它只能是 XML 节点,并且没有允许CONTENT的节点类型。 - 归根结底,格式良好的DOCUMENT是 + 归根结底,良构的DOCUMENTPostgreSQL能够作为 XPath 上下文项提供的唯一 XML 值形式。 diff --git a/zh/20/func/func-admin.sgml b/zh/20/func/func-admin.sgml index 49524c44..3e99d55b 100644 --- a/zh/20/func/func-admin.sgml +++ b/zh/20/func/func-admin.sgml @@ -19,9 +19,9 @@ - configuration - of the server - functions + 配置 + 服务器 + 函数 @@ -58,7 +58,7 @@ text - 返回设置的setting_name的当前值。 + 返回设置setting_name的当前值。 如果没有这样的设置,current_setting将抛出一个错误,除非missing_ok被提供并且为true(在此情况下返回NULL)。 这个函数对应于SQL命令 @@ -80,9 +80,10 @@ text - 将参数setting_name设置为new_value,并返回该值。 - 如果is_localtrue,新值将仅在当前事务期间应用。 - 如果您希望新值应用于当前会话的其余部分,请使用false代替。这个函数对应于SQL命令。 + 将参数setting_name设置为new_value,并返回该值。如果is_localtrue,新值仅在当前事务期间生效。如果希望新值在当前会话的剩余时间内生效,则使用false。此函数对应 SQL 命令。 + + + set_config接受将 NULL 作为new_value的值,但由于配置值不能为 null,这会被解释为将该设置重置为默认值的请求。 set_config('log_statement_stats', 'off', false) @@ -105,7 +106,7 @@ - 在中展示的函数向其它服务器进程发送控制信号。默认情况下这些函数只能被超级用户使用,但是如果需要,可以利用GRANT把访问权限授予给其他用户。 + 在中展示的函数向其它服务器进程发送控制信号。默认情况下这些函数只能被超级用户使用,但是如果需要,可以利用GRANT把访问权限授予给其他用户(注明的例外除外)。 @@ -141,6 +142,7 @@ 取消具有指定进程ID的后端进程的会话的当前查询。如果调用角色是被取消的后端进程所属角色的成员, 或者调用角色具有pg_signal_backend的权限,则也允许执行此操作,但只有超级用户可以取消超级用户后端进程。 + 例外情况是,具有pg_signal_autovacuum_worker角色权限的角色可以取消 autovacuum 工作进程,而这些进程原本被视为超级用户后端。 @@ -153,11 +155,7 @@ boolean - 请求记录具有指定进程ID的后端的内存上下文。此函数可以将请求发送到后端和辅助进程,但不包括记录器。这些内存上下文将以 - LOG消息级别记录。它们将根据设置的日志配置出现在服务器日志中 - (有关更多信息,请参见), - 但无论如何都不会发送给客户端 - ()。 + 请求记录具有指定进程 ID 的后端进程的内存上下文。此函数可以向除日志记录进程以外的后端进程和辅助进程发送请求。这些内存上下文将以LOG消息级别记录,并根据日志配置出现在服务器日志中(详见);无论如何设置,都不会发送给客户端。 @@ -204,9 +202,10 @@ 终止具有指定进程ID的后端进程的会话。如果调用角色是正在终止的后端的角色的成员,或者调用角色具有pg_signal_backend的权限,则也允许执行此操作,但只有超级用户才能终止超级用户后端。 + 例外情况是,具有pg_signal_autovacuum_worker角色权限的角色可以终止 autovacuum 工作进程,而这些进程原本被视为超级用户后端。 - 如果未指定或超时timeout为零,则此函数无论进程是否实际终止,都将返回true,仅表示信号发送成功。如果指定了timeout(以毫秒为单位)且大于零,则函数将等待直到进程实际终止或直到给定时间已过。如果进程被终止,函数将返回true。在超时时,会发出警告并返回false。 + 如果未指定timeout或其值为零,则此函数无论进程是否实际终止,都将返回true,仅表示信号发送成功。如果指定了timeout(以毫秒为单位)且大于零,则函数将等待直到进程实际终止或直到给定时间已过。如果进程被终止,函数将返回true。在超时时,会发出警告并返回false @@ -232,16 +231,16 @@ postgres=# SELECT pg_log_backend_memory_contexts(pg_backend_pid()); LOG: logging memory contexts of PID 10377 STATEMENT: SELECT pg_log_backend_memory_contexts(pg_backend_pid()); -LOG: level: 0; TopMemoryContext: 80800 total in 6 blocks; 14432 free (5 chunks); 66368 used -LOG: level: 1; pgstat TabStatusArray lookup hash table: 8192 total in 1 blocks; 1408 free (0 chunks); 6784 used -LOG: level: 1; TopTransactionContext: 8192 total in 1 blocks; 7720 free (1 chunks); 472 used -LOG: level: 1; RowDescriptionContext: 8192 total in 1 blocks; 6880 free (0 chunks); 1312 used -LOG: level: 1; MessageContext: 16384 total in 2 blocks; 5152 free (0 chunks); 11232 used -LOG: level: 1; Operator class cache: 8192 total in 1 blocks; 512 free (0 chunks); 7680 used -LOG: level: 1; smgr relation table: 16384 total in 2 blocks; 4544 free (3 chunks); 11840 used -LOG: level: 1; TransactionAbortContext: 32768 total in 1 blocks; 32504 free (0 chunks); 264 used +LOG: level: 1; TopMemoryContext: 80800 total in 6 blocks; 14432 free (5 chunks); 66368 used +LOG: level: 2; pgstat TabStatusArray lookup hash table: 8192 total in 1 blocks; 1408 free (0 chunks); 6784 used +LOG: level: 2; TopTransactionContext: 8192 total in 1 blocks; 7720 free (1 chunks); 472 used +LOG: level: 2; RowDescriptionContext: 8192 total in 1 blocks; 6880 free (0 chunks); 1312 used +LOG: level: 2; MessageContext: 16384 total in 2 blocks; 5152 free (0 chunks); 11232 used +LOG: level: 2; Operator class cache: 8192 total in 1 blocks; 512 free (0 chunks); 7680 used +LOG: level: 2; smgr relation table: 16384 total in 2 blocks; 4544 free (3 chunks); 11840 used +LOG: level: 2; TransactionAbortContext: 32768 total in 1 blocks; 32504 free (0 chunks); 264 used ... -LOG: level: 1; ErrorContext: 8192 total in 1 blocks; 7928 free (3 chunks); 264 used +LOG: level: 2; ErrorContext: 8192 total in 1 blocks; 7928 free (3 chunks); 264 used LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 used 如果在同一父级下有超过100个子上下文,则将记录前100个子上下文,并附上其余上下文的摘要。 @@ -255,7 +254,7 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 备份控制函数 - backup + 备份 @@ -295,13 +294,9 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 pg_lsn - 在预写式日志中创建一个命名标记记录,稍后可以将其用作恢复目标,并返回相应的预写日志位置。 - 然后可以将给定的名称与 一起使用,以指定进行恢复的点。 - 要避免创建多个名称相同的恢复点,因为恢复将在第一个名称与恢复目标匹配的恢复点停止。 + 在预写式日志中创建一条命名标记记录,供以后用作恢复目标,并返回相应的预写式日志位置。随后可以在中使用给定名称,指定恢复到哪一点。应避免创建多个同名恢复点,因为恢复会在第一个名称匹配恢复目标的恢复点停止。 - - 默认情况下,该函数仅限超级用户使用,但可以授权给其他用户执行该函数。 - + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -313,7 +308,7 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 pg_lsn - 返回当前预写式日志刷新位置(参见下面的说明)。 + 返回当前预写式日志刷盘位置(参见下文说明)。 @@ -326,7 +321,7 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 pg_lsn - 返回当前预式日志插入位置(参见下面的说明)。 + 返回当前预写式日志插入位置(参见下文说明)。 @@ -339,7 +334,7 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 pg_lsn - 返回当前预写式日志写位置(参见下面的说明)。 + 返回当前预写式日志写入位置(参见下文说明)。 @@ -355,15 +350,9 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 pg_lsn - 准备服务器开始在线备份。唯一必需的参数是备份的任意用户定义标签。 - (通常这将是备份转储文件存储的名称。) - 如果将可选的第二个参数指定为true, - 它将尽快执行pg_backup_start。这将强制快速检查点, - 这将导致I/O操作的激增,从而减慢任何同时执行的查询。 + 准备服务器开始在线备份。唯一必需的参数是用户任意指定的备份标签。(通常是备份转储文件将要保存的名称。)如果可选的第二个参数为true,则尽快执行pg_backup_start。这会强制执行快速检查点,使 I/O 操作量陡增,并降低并发执行的查询的速度。 - - 默认情况下,此函数仅限于超级用户,但可以授予其他用户执行权限以运行该函数。 - + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -380,31 +369,18 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 spcmapfile text ) - 完成在线备份。函数的结果中返回备份标签文件和表空间映射文件的期望内容,并必须写入备份区域的文件中。 - 这些文件不得写入实时数据目录(这样做将导致PostgreSQL在崩溃时无法重新启动)。 + 结束在线备份。备份标签文件和表空间映射文件所需的内容作为函数结果的一部分返回,必须将其写入备份区域中的文件。切勿将这些文件写入正在使用的数据目录(否则发生崩溃后 PostgreSQL 将无法重新启动)。 - 有一个类型为boolean的可选参数。 - 如果为false,则在备份完成后立即返回,而无需等待WAL进行归档。 - 此行为仅适用于独立监视WAL归档的备份软件。否则,可能会缺少使备份一致所需的WAL,使备份无效。 - 默认情况下或当此参数为true时,pg_backup_stop将在启用归档时等待WAL进行归档。 - (在备库上,这意味着仅当archive_mode = always时才会等待。 - 如果主库上的写入活动较低,则可能有必要在主库上运行pg_switch_wal以触发立即段切换。) + 有一个boolean类型的可选参数。如果为 false,该函数会在备份完成后立即返回,不等待 WAL 归档。这种行为只适用于自行监控 WAL 归档的备份软件;否则,可能缺少使备份保持一致所需的 WAL,导致备份无法使用。默认情况下或该参数为 true 时,若已启用归档,pg_backup_stop会等待 WAL 归档。(在备库上,这意味着只有archive_mode = always时才会等待。如果主库的写入活动很少,可以在主库上运行pg_switch_wal,触发立即切换日志段。) - 在主库上执行时,此函数还会在预写式日志归档区域中创建一个备份历史文件。 - 历史文件包括给定给pg_backup_start的标签、备份的起始和结束预写式日志位置,以及备份的起始和结束时间。 - 在记录结束位置后,当前的预写式日志插入点会自动前进到下一个预写式日志文件,以便立即归档结束的预写式日志文件以完成备份。 + 在主库上执行时,该函数还会在预写式日志归档区域创建备份历史文件。历史文件包括传给pg_backup_start的标签、备份的起止预写式日志位置以及备份的起止时间。记录结束位置后,当前预写式日志插入点会自动推进到下一个预写式日志文件,使包含结束位置的预写式日志文件可以立即归档,从而完成备份。 - 函数的结果是一个记录。 - lsn列保存备份的结束预写式日志位置(可以忽略)。 - 第二列返回备份标签文件的内容,第三列返回表空间映射文件的内容。 - 这些必须作为备份的一部分存储,并作为恢复过程的一部分。 + 该函数的结果是一条记录。lsn列保存备份结束时的预写式日志位置(同样可以忽略)。第二列返回备份标签文件的内容,第三列返回表空间映射文件的内容。这些内容必须作为备份的一部分保存,恢复时需要用到它们。 - - 默认情况下,此函数仅限于超级用户,但可以授予其他用户EXECUTE权限来运行该函数。 - + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -416,13 +392,9 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 pg_lsn - 强制服务器切换到一个新的预写式日志文件,这允许对当前文件进行归档(假设你正在使用连续归档)。 - 其结果是在刚刚完成的预写式日志文件中结束预写式日志位置加1。 - 如果自从上次预写式日志切换以来没有提前写日志活动,pg_switch_wal将不做任何操作,并返回当前正在使用的提前写日志文件的起始位置。 + 强制服务器切换到新的预写式日志文件,使当前文件可以归档(假设正在使用连续归档)。返回值是刚完成的预写式日志文件中的结束预写式日志位置加 1。如果自上次切换预写式日志以来没有发生任何预写式日志活动,pg_switch_wal不执行任何操作,并返回当前使用的预写式日志文件的起始位置。 - - 默认情况下该函数仅限超级用户使用,但可以授权其他用户执行该函数。 - + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -434,7 +406,7 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 text - 将预写式日志位置转换为保持该位置的WAL文件的名称。 + 将预写式日志位置转换为包含该位置的 WAL 文件的名称。 @@ -453,6 +425,21 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 + + + + pg_split_walfile_name + + pg_split_walfile_name ( file_name text ) + record + ( segment_number numeric, + timeline_id bigint ) + + + 从 WAL 文件名中提取序列号和时间线 ID。 + + + @@ -462,34 +449,38 @@ LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 numeric - 计算两个预写式日志位置之间的字节(lsn1 - lsn2)差异。 - 这可以与pg_stat_replication中所示的一些函数一起使用,以获得复制延迟。 + 计算两个预写式日志位置之间的字节差(lsn1 - lsn2)。可以将它与pg_stat_replication中的某些函数配合使用,以获取复制延迟。
- - pg_current_wal_lsn 显示当前预写式日志写位置,与上述函数所用的格式相同。 - 类似地,pg_current_wal_insert_lsn显示当前预写式日志插入位置,pg_current_wal_flush_lsn显示当前预写式日志刷新位置。 - 插入位置是预写式日志在任何时刻的逻辑(logical) 结束,而写位置是已经从服务器内部缓冲区实际写入的内容的结束,而刷新位置是已知的要写入持久化存储的最后一个位置。 - 写位置是可以从服务器外部检查的最后位置,如果你对归档部分完成的预写式日志文件感兴趣,那么它通常就是你想要的位置。 - 插入和刷新位置主要用于服务器调试目的。这些都是只读操作,不需要超级用户权限。 - + pg_current_wal_lsn 显示当前预写式日志写入位置,格式与上述函数相同。类似地,pg_current_wal_insert_lsn 显示当前预写式日志插入位置,pg_current_wal_flush_lsn 显示当前预写式日志刷盘位置。插入位置是预写式日志在任意时刻的逻辑末尾;写入位置是实际从服务器内部缓冲区写出的内容的末尾;刷盘位置则是已知已经写入持久存储的最后位置。写入位置是能从服务器外部检查到的内容的末尾,如果要归档尚未写满的预写式日志文件,通常需要这个位置。插入位置和刷盘位置主要用于服务器调试。这些都是只读操作,不需要超级用户权限。 - - 您可以使用pg_walfile_name_offsetpg_lsn值中提取相应的预写式日志文件名和字节偏移量。例如: - + 可以使用pg_walfile_name_offset从一个pg_lsn值中提取相应的预写式日志文件名和字节偏移量。例如: postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); file_name | file_offset --------------------------+------------- 00000001000000000000000D | 4039624 (1 row) +类似地,pg_walfile_name仅提取预写式日志文件名。 + + + pg_split_walfile_name可用于根据文件偏移量和 WAL 文件名计算 + LSN,例如: + +postgres=# \set file_name '000000010000000100C000AB' +postgres=# \set offset 256 +postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset AS lsn + FROM pg_split_walfile_name(:'file_name') pd, + pg_show_all_settings() ps + WHERE ps.name = 'wal_segment_size'; + lsn +--------------- + C001/AB000100 +(1 row) - 类似地,pg_walfile_name仅提取预写式日志文件名。 - 当给定的预写式日志位置恰好位于预写式日志文件边界时,这两个函数都会返回前一个预写式日志文件的名称。 - 这通常是管理预写式日志归档行为的期望行为,因为前一个文件是当前需要归档的最后一个文件。 @@ -543,9 +534,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); pg_lsn - 返回已接收并通过流复制同步到磁盘的最后一个预写式日志位置。 - 当流复制正在进行时这将单调地增加。如果恢复已经完成,那么在恢复期间,接收到的最后一条WAL记录的位置将保持静态,并同步到磁盘。 - 如果流复制已禁用,或者尚未启动,函数将返回NULL。 + 返回流复制最近接收并同步到磁盘的预写式日志位置。在流复制进行期间,该值单调增加。如果恢复已完成,该值将保持为恢复期间最后接收并同步到磁盘的 WAL 记录的位置。如果禁用了流复制,或者流复制尚未开始,此函数返回 NULL @@ -558,8 +547,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); pg_lsn
- 返回恢复期间重新播放的最后一个预写式日志位置。如果恢复仍在进行中这将会单调地增加。 - 如果恢复已经完成,那么恢复期间应用的最后WAL记录的位置将保持静态。当服务器正常启动且没有恢复时,函数返回NULL。 + 返回恢复期间最近重放的预写式日志位置。如果恢复仍在进行,该值单调增加。如果恢复已完成,该值将保持为该次恢复期间最后应用的 WAL 记录的位置。如果服务器未经恢复而正常启动,此函数返回 NULL @@ -572,10 +560,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); timestamp with time zone - 返回恢复期间重放的最后一个事务的时间戳。这是在主库上为该事务生成提交或中止 WAL记录的时间。 - 如果在恢复期间没有重放任何事务,该函数将返回NULL。否则,如果恢复仍在进行中,这将单调地增加。 - 如果恢复已经完成,那么在恢复期间应用最后一个事务时,这将会保持静态。 - 当服务器正常启动且没有恢复时,函数返回NULL。 + 返回恢复期间最近重放事务的时间戳,即该事务的提交或中止 WAL 记录在主库上生成的时间。如果恢复期间尚未重放任何事务,此函数返回 NULL。否则,如果恢复仍在进行,该值单调增加。如果恢复已完成,该值将保持为该次恢复期间最后应用的事务的时间戳。如果服务器未经恢复而正常启动,此函数返回 NULL @@ -599,7 +584,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); - 控制恢复进度的功能如 所示。这些函数只能在恢复过程中执行。 + 列出的函数用于控制恢复进度。这些函数只能在恢复期间执行。 @@ -629,7 +614,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); boolean - 如果请求了恢复暂停了则返回真。 + 如果已请求暂停恢复,则返回真。 @@ -643,7 +628,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); 返回恢复暂停状态。 - 如果没有请求pause,返回值是not paused,如果请求暂停但恢复还没有暂停,返回值是pause requested,如果恢复实际已经暂停,返回值是paused。 + 如果没有请求暂停,返回值是not paused,如果请求暂停但恢复还没有暂停,返回值是pause requested,如果恢复实际已经暂停,返回值是paused @@ -657,11 +642,11 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); 将备库提升为主库状态。 - 当wait设置为true(默认值)时,函数将等待直到升级完成或wait_seconds秒数已过,如果升级成功则返回true,否则返回false。 - 如果wait设置为false,则该函数在向postmaster发送SIGUSR1信号以触发升级后立即返回true。 + 当wait设置为true(默认值)时,函数将等待直到提升完成或wait_seconds秒数已过,如果提升成功则返回true,否则返回false。 + 如果wait设置为false,则该函数在向postmaster发送SIGUSR1信号以触发提升后立即返回true - 默认情况下这个函数仅限超级用户使用,但可以授权给其他用户执行该函数。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -682,7 +667,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); 如果热备是激活的,所有新查询将看到相同的一致的数据库快照,并且在恢复继续之前不会生成进一步的查询冲突。 - 默认情况下该函数仅限超级用户使用,但可以授权其他用户执行该函数。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -698,7 +683,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); 如果暂停了,则重新启动恢复。 - 默认情况下该函数仅限超级用户使用,但可以授权其他用户执行该函数。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -706,8 +691,8 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn);
- pg_wal_replay_pausepg_wal_replay_resume不能在提升(promotion)进行时执行。 - 如果在恢复暂停时触发了提升(promotion),则暂停状态结束,升级继续进行。 + pg_wal_replay_pausepg_wal_replay_resume不能在提升进行时执行。 + 如果在恢复暂停时触发了提升,则暂停状态结束,提升继续进行。 @@ -726,7 +711,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); - 为了解决这个问题,PostgreSQL允许一个事务导出它正在使用的快照。只要导出的事务仍然保持打开,其他事务可以导入它的快照,并且因此可以保证它们可以看到和第一个事务看到的完全一样的数据库视图。但是注意这些事务中的任何一个对数据库所作的更改对其他事务仍然保持不可见,和未提交事务所作的修改一样。因此这些事务是针对以前存在的数据同步,而对由它们自己所作的更改则采取正常的动作。 + 为了解决这个问题,PostgreSQL允许一个事务导出它正在使用的快照。只要导出快照的事务仍然保持打开,其他事务可以导入它的快照,并且因此可以保证它们可以看到和第一个事务看到的完全一样的数据库视图。但是注意这些事务中的任何一个对数据库所作的更改对其他事务仍然保持不可见,和未提交事务所作的修改一样。因此这些事务是针对以前存在的数据同步,而对由它们自己所作的更改则采取正常的动作。 @@ -766,7 +751,19 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); 如果需要的话,一个事务可以导出多个快照。 请注意,这样做仅在READ COMMITTED事务中有用,因为在REPEATABLE READ和更高的隔离级别中,事务在它们的生命周期中使用相同的快照。 - 一旦事务导出了快照,它就不能用 进行准备。 + 一旦事务导出了快照,它就不能用 进行预备。 + + + + + + pg_log_standby_snapshot + + pg_log_standby_snapshot () + pg_lsn + + + 为进行中的事务拍摄快照并将其写入 WAL,无须等待后台写入器或检查点进程记录快照。这对备用服务器上的逻辑解码很有用,因为创建逻辑复制槽必须等待此类记录在备用服务器上重放。 @@ -782,7 +779,6 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); 中展示的函数用于控制以及与复制特性交互。 有关底层特性的信息请见以及。 - 复制原点函数的使用仅限于超级用户。 默认只允许超级用户使用复制源的函数,但可以通过GRANT命令允许其他用户使用。 复制槽的函数只限于超级用户和拥有REPLICATION权限的用户。 @@ -828,13 +824,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); lsn pg_lsn ) - 创建一个新的名为slot_name的物理复制槽。 - 槽名称不能是pg_conflict_detection,因为它保留给冲突检测槽。 - 第二个参数是可选的,当它为true时,立即为这个物理槽指定要被保留的LSN。 - 否则该LSN会被保留在来自一个流复制客户端的第一个连接上。 - 来自一个物理槽的更改只能通过流复制协议进行流式传输 — 见。 - 当可选的第三参数temporary被设置为真时,指定那个槽不会被持久地存储在磁盘上并且仅对当前会话的使用有意义。 - 临时槽也会在发生任何错误时被释放。这个函数对应于复制协议命令CREATE_REPLICATION_SLOT ... PHYSICAL。 + 创建名为 slot_name 的新物理复制槽。槽名称不能是pg_conflict_detection,因为它保留给冲突检测槽。可选的第二个参数为 true 时,指定立即为此复制槽保留 LSN;否则在流复制客户端首次连接时保留 LSN。从物理槽流式传输更改只能使用流复制协议 — 参见。可选的第三个参数 temporary 为真时,指定该槽不永久存储到磁盘,且仅供当前会话使用。发生任何错误时,临时槽也会被释放。此函数对应复制协议命令 CREATE_REPLICATION_SLOT ... PHYSICAL @@ -847,9 +837,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); void - 丢弃名为slot_name的物理或逻辑复制槽。 - 和复制协议命令DROP_REPLICATION_SLOT相同。对于逻辑槽, - 在连接到在其中创建该槽的同一个数据库时,必须调用这个函数。 + 删除名为slot_name的物理或逻辑复制槽。与复制协议命令DROP_REPLICATION_SLOT相同。 @@ -864,8 +852,8 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); lsn pg_lsn ) - 创建一个名为slot_name的新逻辑(解码)复制插槽,使用输出插件plugin。槽名称不能是pg_conflict_detection,因为它保留给冲突检测槽。 - 可选的第三个参数temporary,当设置为true时,指定插槽不应永久存储到磁盘,仅供当前会话使用。临时插槽也会在任何错误发生时释放。可选的第四个参数twophase,当设置为true时,指定为此插槽启用已准备事务的解码。可选的第五个参数failover,当设置为true时,指定启用此插槽同步到备库,以便在故障切换后可以恢复逻辑复制。调用此函数的效果与复制协议命令CREATE_REPLICATION_SLOT ... LOGICAL相同。 + 创建一个名为slot_name的新逻辑(解码)复制槽,使用输出插件plugin。槽名称不能是pg_conflict_detection,因为它保留给冲突检测槽。 + 可选的第三个参数temporary,当设置为真时,指定槽不应永久存储到磁盘,仅供当前会话使用。临时槽也会在任何错误发生时释放。可选的第四个参数twophase,当设置为真时,指定为此槽启用预备事务的解码。可选的第五个参数failover,当设置为真时,指定启用此槽同步到备库,以便在故障切换后可以恢复逻辑复制。调用此函数的效果与复制协议命令CREATE_REPLICATION_SLOT ... LOGICAL相同。 @@ -882,8 +870,9 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); 将一个名为src_slot_name的现有物理复制槽复制到一个名为dst_slot_name的物理复制槽。 新槽名称不能是pg_conflict_detection,因为它保留给冲突检测。 - 被复制的物理槽开始从与源槽相同的LSN开始保留WAL。temporary是可选的。 + 复制后的物理槽从与源槽相同的LSN开始保留WAL。temporary是可选的。 如果省略了temporary,则使用与源槽相同的值。 + 不能复制已失效的槽。 @@ -898,10 +887,12 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); lsn pg_lsn ) - 复制一个名为src_slot_name的现有逻辑复制槽到一个名为dst_slot_name的逻辑复制槽,选择性的改变输出插件和持久性。 + 复制一个名为src_slot_name的现有逻辑复制槽到一个名为dst_slot_name的逻辑复制槽,可选地更改输出插件和持久性。 新槽名称不能是pg_conflict_detection,因为该名称保留用于冲突检测。 被复制的逻辑槽从与源逻辑槽相同的LSN开始。temporaryplugin都是可选的。 如果它们被省略了,使用与源逻辑槽相同的值。 + 源逻辑槽的failover选项不会被复制,而是默认设为false。这是为了避免故障切换到正在同步该槽的备库后无法继续逻辑复制的风险。 + 不能复制已失效的槽。 @@ -917,11 +908,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); data text ) - 返回槽slot_name中的改变,从最后一次使用更改的点开始。 - 如果upto_lsnupto_nchanges为 NULL,逻辑解码将一直继续到 WAL 的末尾。 - 如果upto_lsn为非 NULL,解码将只包括那些在指定 LSN 之前提交的事务。 - 如果upto_nchanges为非 NULL,解码将在其产生的行数超过指定值后停止。 - 不过要注意,被返回的实际行数可能更大,因为对这个限制的检查只会在增加了解码每个新的提交事务产生的行之后进行。 + 返回槽 slot_name 中自上次消费更改的位置起的更改。如果 upto_lsnupto_nchanges 都为 NULL,逻辑解码会持续到 WAL 末尾。如果 upto_lsn 非 NULL,解码仅包含在指定 LSN 之前提交的事务。如果 upto_nchanges 非 NULL,解码产生的行数超过指定值时就会停止。不过,实际返回行数可能更大,因为只有在添加完对每个新事务提交进行解码所产生的行后,才会检查此限制。如果指定的槽是逻辑故障切换槽,则只有在synchronized_standby_slots中指定的所有物理槽都确认已接收 WAL 后,该函数才会返回。 @@ -986,9 +973,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); end_lsn pg_lsn ) - 将复制槽的当前确认的位置提前到名为slot_name的复制槽的当前确认位置。 - 该槽不会向后移动,也不会移动到当前插入位置之外。返回该槽的名称和它被推进到的真实位置。 - 如果有任何进展,则在下一个检查点中写出更新后的槽位置信息。所以如果发生崩溃,该槽位可能会返回到之前的位置。 + 推进名为 slot_name 的复制槽当前已确认的位置。该槽不会后退,也不会越过当前插入位置。返回槽名及其实际推进到的位置。如果发生了推进,更新后的槽位置信息会在下一个检查点写出。因此,发生崩溃时,槽可能回到更早的位置。如果指定的槽是逻辑故障切换槽,则只有在 synchronized_standby_slots 中指定的所有物理槽都确认已接收 WAL 后,该函数才会返回。 @@ -1002,6 +987,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); 用给定的外部名称创建一个复制源,并且返回分配给它的内部 ID。 + 该名称长度不得超过 512 字节。 @@ -1092,7 +1078,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); pg_lsn - 返回当前会话中选择的复制源的重放位置。参数flush决定对应的本地事务是否被确保已经刷入磁盘。 + 返回当前会话中选择的复制源的重放位置。参数flush决定是否保证对应的本地事务已刷盘。 @@ -1146,7 +1132,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); pg_lsn - 返回给定复制元的重放位置。参数flush决定对应的本地事务是否被确保已经刷入磁盘。 + 返回给定复制源的重放位置。参数flush决定是否保证对应的本地事务已刷盘。 @@ -1155,19 +1141,15 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); pg_logical_emit_message - pg_logical_emit_message ( transactional boolean, prefix text, content text ) + pg_logical_emit_message ( transactional boolean, prefix text, content text , flush boolean DEFAULT false ) pg_lsn - pg_logical_emit_message ( transactional boolean, prefix text, content bytea ) + pg_logical_emit_message ( transactional boolean, prefix text, content bytea , flush boolean DEFAULT false ) pg_lsn - 发出逻辑解码消息。这可以用于通过WAL将通用消息传递给逻辑解码插件。 - transactional参数指定消息是否应该是当前事务的一部分, - 还是应该立即写入并在逻辑解码器读取记录时立即解码。 - prefix参数是一个文本前缀,逻辑解码插件可以使用它轻松识别对它们有趣的消息。 - content参数是消息的内容,可以以文本或二进制形式给出。 + 发出逻辑解码消息。这可用于通过 WAL 向逻辑解码插件传递通用消息。transactional 参数指定消息是作为当前事务的一部分,还是立即写入并在逻辑解码器读到该记录时立即解码。prefix 参数是一个文本前缀,便于逻辑解码插件识别其关注的消息。content 参数是消息内容,可以文本或二进制形式给出。 flush 参数(默认为 false)控制是否立即将消息对应的 WAL 记录刷盘。transactional 为真时,flush 不起作用,因为消息的 WAL 记录会与其事务一起刷盘。 @@ -1256,6 +1238,19 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); + + + + pg_column_toast_chunk_id + + pg_column_toast_chunk_id ( "any" ) + oid + + + 显示磁盘上经过TOAST处理的值的chunk_id。如果该值未经过TOAST处理或不在磁盘上,则返回NULL。有关TOAST的更多信息,请参见。 + + + @@ -1296,13 +1291,13 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); bigint - 计算指定关系的一个fork所使用的磁盘空间。 - (注意在大多数情况下,使用更高级的函数 pg_total_relation_sizepg_table_size更方便,它们将所有分叉(forks)的大小相加。) - 使用一个参数,这将返回关系的主数据分叉的大小。第二个参数可以用来指定要检查哪个分叉: + 计算指定关系的一个分支所使用的磁盘空间。 + (注意在大多数情况下,使用更高级的函数 pg_total_relation_sizepg_table_size更方便,它们将所有分支的大小相加。) + 使用一个参数,这将返回关系的主数据分支的大小。第二个参数可以用来指定要检查哪个分支: - main返回关系的主数据分叉的大小。 + main返回关系的主数据分支的大小。 @@ -1317,7 +1312,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); - init 返回初始化分叉的大小,如果有的话,与关系相关。 + init 返回与该关系关联的初始化分支(如有)的大小。 @@ -1333,7 +1328,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); bigint - 将人可阅读的格式的大小(由pg_size_pretty返回)转换为字节。 + 将人类可读格式的大小(由pg_size_pretty返回)转换为字节。有效的单位为bytesBkBMBGBTBPB @@ -1364,7 +1359,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); bigint - 计算指定表所使用的磁盘空间,不包括索引(但包括它的TOAST表,如果有的话,空闲空间映射,以及可见性映射)。 + 计算指定表所使用的磁盘空间,不包括索引(但包括其 TOAST 表(如有)、空闲空间映射和可见性映射)。 @@ -1398,7 +1393,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); 计算指定表所使用的总磁盘空间,包括所有索引和TOAST数据。 - 结果等价pg_table_size + pg_indexes_size。 + 结果等价于pg_table_size + pg_indexes_size @@ -1406,11 +1401,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); - 上述操作表和索引的函数接受一个regclass参数,它是该表或索引在pg_class系统目录中的 OID。 - 你不必手工去查找该 OID,因为regclass数据类型的输入转换器会为你代劳。 - 只写包围在单引号内的表名,这样它看起来像一个文字常量。 - 为了与普通SQL名称的处理相兼容,该字符串将被转换为小写形式,除非其中在表名周围包含双引号。 - 详见。 + 上述操作表和索引的函数接受一个regclass参数,即该表或索引在pg_class系统目录中的 OID。不必手工查找该 OID,因为regclass数据类型的输入转换器会代为查找。详见 @@ -1444,7 +1435,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); oid - 返回当前分配给指定关系的filenode数字。文件节点是用于该关系的文件名称的基本组件(更多信息请参阅 )。 + 返回当前分配给指定关系的文件结点编号。文件结点是用于该关系的文件名称的基本组件(更多信息请参阅 )。 对于大多数关系,其结果与pg_class.relfilenode相同,但对于某些系统目录,relfilenode为0,并且必须使用这个函数来获得正确的值。 如果传递的是一个没有存储的关系,例如一个视图,那么函数将返回NULL。 @@ -1459,7 +1450,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); text - 返回关系的完整文件路径名称(相对于数据库集簇的数据目录,即关系的PGDATA)。 + 返回关系的完整文件路径名称(相对于数据库集簇的数据目录,即PGDATA)。 @@ -1472,8 +1463,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); regclass - 返回一个给定表空间OID和存储它的文件节点的关系的OID。这本质上是pg_relation_filepath的反向映射。 - 对于数据库默认表空间中的关系,表空间可以指定为0。如果当前数据库中没有与给定值相关联的关系,则返回 NULL。 + 根据关系所在表空间的 OID 和文件结点返回该关系的 OID。这本质上是pg_relation_filepath的反向映射。对于数据库默认表空间中的关系,表空间可以指定为 0。如果当前数据库中没有与给定值关联的关系,或者该关系是临时关系,则返回NULL @@ -1540,13 +1530,13 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); integer - 基于在操作系统中找到的所有区域环境(locales),加入排序规则到系统目录pg_collation中。 - 这是 initdb 会用到的,更多细节请参考。 - 如果后来在操作系统上安装了额外的区域环境,可以再次运行这个函数加入新区域环境的排序规则。 - 匹配pg_collation中现有条目的区域环境将被跳过(但是这个函数不会移除以在操作系统中不再存在的区域环境为基础的排序规则对象)。 - schema参数通常是pg_catalog,但这并非强制要求,排序规则也可以安装到其他模式中。 - 该函数返回其创建的新排序规则对象的数量。 - 此函数仅限超级用户使用。 + 根据操作系统中找到的所有区域设置,向系统目录pg_collation添加排序规则。 + initdb使用的就是此函数;更多信息见。 + 如果以后在操作系统中安装了其他区域设置,可以再次运行此函数,为新区域设置添加排序规则。 + 与pg_collation中现有条目匹配的区域设置会被跳过。 + (但此函数不会删除基于操作系统中已不存在的区域设置的排序规则对象。) + schema参数通常为pg_catalog,但并非必须如此;也可以将排序规则安装到其他模式中。 + 函数返回新建的排序规则对象数量。此函数仅限超级用户使用。 @@ -1589,7 +1579,7 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); boolean - 更新表级统计信息。通常这些统计信息由自动收集或作为的一部分更新,因此不必调用此函数。但它在恢复后很有用,可以在尚未运行ANALYZE时帮助优化器选择更好的计划。 + 更新表级统计信息。通常这些统计信息会自动收集或作为的一部分更新,因此不必调用此函数。但它在恢复后很有用,可以在尚未运行ANALYZE时帮助优化器选择更好的计划。 被跟踪的统计信息可能因版本而异,所以参数以argnameargvalue对的形式传递: @@ -1614,7 +1604,7 @@ SELECT pg_restore_relation_stats( 参数schemanamerelname是必需的,用于指定表。其他参数是与pg_class中某些列对应的统计信息的名称和值。当前支持的关系统计信息包括:integer类型的relpagesreal类型的reltuplesinteger类型的relallvisible以及integer类型的relallfrozen - 此外,此函数还接受integer类型的参数名version,指定统计信息来源的服务器版本。这有助于从旧版本的PostgreSQL移植统计信息。 + 此外,此函数还接受名为versioninteger类型参数,用于指定统计信息来源的服务器版本。这预计有助于从旧版本的PostgreSQL移植统计信息。 次要错误会以WARNING报告并被忽略,其余统计信息仍将被恢复。如果所有指定的统计信息都成功恢复,则返回true,否则返回false。 @@ -1653,7 +1643,7 @@ SELECT pg_restore_relation_stats( boolean - 创建或更新列级统计信息。通常这些统计信息由自动收集或作为的一部分更新,因此不必调用此函数。但它在恢复后很有用,可以在尚未运行ANALYZE时帮助优化器选择更好的计划。 + 创建或更新列级统计信息。通常这些统计信息会自动收集或作为的一部分更新,因此不必调用此函数。但它在恢复后很有用,可以在尚未运行ANALYZE时帮助优化器选择更好的计划。 被跟踪的统计信息可能因版本而异,所以参数以argnameargvalue对的形式传递: @@ -1680,7 +1670,7 @@ SELECT pg_restore_attribute_stats( 必需的参数包括:text类型的schemanamerelname,用于指定表;text类型的attnamesmallint类型的attnum,用于指定列;以及inherited,指定统计信息是否包含来自子表的值。其他参数是与pg_stats中的列对应的统计信息的名称和值。 - 此外,此函数还接受integer类型的参数名version,指定统计信息来源的服务器版本。这有助于从旧版本的PostgreSQL移植统计信息。 + 此外,此函数还接受名为versioninteger类型参数,用于指定统计信息来源的服务器版本。这预计有助于从旧版本的PostgreSQL移植统计信息。 次要错误会以WARNING报告并被忽略,其余统计信息仍将被恢复。如果所有指定的统计信息都成功恢复,则返回true,否则返回false。 @@ -1787,7 +1777,7 @@ SELECT pg_restore_extended_stats( 由pg_stats_ext_exprs中每个统计列对应的 JSON 元素组成。 - 此外,此函数还接受integer类型的参数名version,指定统计信息来源的服务器版本。这有助于从旧版本的PostgreSQL移植统计信息。 + 此外,此函数还接受名为versioninteger类型参数,用于指定统计信息来源的服务器版本。这预计有助于从旧版本的PostgreSQL移植统计信息。 次要错误会以WARNING报告并被忽略,其余统计信息仍将被恢复。如果所有指定的统计信息都成功恢复,则返回true,否则返回false。 @@ -1900,7 +1890,7 @@ SELECT pg_restore_extended_stats( - 例如,要检查分区表measurement中包含的数据的总大小,可以使用以下查询: + 例如,要检查分区表measurement中包含的数据的总大小,可以使用以下查询: SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size FROM pg_partition_tree('measurement'); @@ -1915,7 +1905,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size 显示了索引维护任务可以使用的函数。 - (注意,这些维护任务通常由自动清理(autovacuum)自动完成;只有在特殊情况下才需要使用这些函数。) + (注意,这些维护任务通常由 autovacuum 自动完成;只有在特殊情况下才需要使用这些函数。) 这些函数在恢复过程中无法执行。这些函数的使用局限于超级用户和给定索引的所有者。 @@ -1946,7 +1936,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size integer - 扫描指定的BRIN索引以查找基表中当前尚未生成索引摘要的页面范围; + 扫描指定的BRIN索引以查找基表中当前尚未生成索引摘要的页面范围; 对于任何这样的范围,它都通过扫描这些表页来创建一个新的摘要索引元组。 返回插入到索引中的新页面范围摘要的数量。 @@ -1962,7 +1952,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size 对覆盖给定块的页面范围执行摘要(如果尚未摘要)。 - 这类似于brin_summarize_new_values,只是它只处理覆盖给定表块数的页范围。 + 这类似于brin_summarize_new_values,区别在于它只处理包含给定表块编号的页面范围。 @@ -1988,9 +1978,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size bigint - 清理指定GIN索引的pending列表,通过移除里面的条目,以大批的方式,到主要的GIN数据结构。 - 返回从挂起列表中删除的页数。如果参数是使用禁用fastupdate选项构建的GIN索引,则不会发生清理,结果为零,因为索引没有挂起的列表。 - 关于挂起列表和fastupdate选项的详细信息,请参见。 + 将指定 GIN 索引的待处理列表中的条目批量移入主 GIN 数据结构,从而清理该列表。返回从待处理列表中移除的页数。如果参数是禁用fastupdate选项构建的 GIN 索引,则不会进行清理,结果为零,因为该索引没有待处理列表。有关待处理列表和fastupdate选项的详细信息,参见 @@ -2005,21 +1993,20 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size 中展示的函数提供了对数据库服务器所在机器上的文件的本地访问。 - 只能访问数据库集簇目录以及log_directory中的文件,除非用户是超级用户或者被授予了角色pg_read_server_files。 + 只能访问数据库集簇目录以及log_directory中的文件,除非用户是超级用户或者被授予了角色pg_read_server_files。 使用相对路径访问集簇目录里面的文件,以及匹配 log_directory配置设置的路径访问日志文件。 - 注意在pg_read_file()或者相关函数上,向用户授予EXECUTE权限, - 以允许他们有能力读取服务器上该数据库服务器进程能读取的任何文件;这些函数会绕过所有的数据库内权限检查。 - 这意味着,例如,具有这种访问的用户能够读取pg_authid表中存储着认证信息的内容,也能读取数据库中的任何表数据。 - 因此,授予对这些函数的访问应该要很仔细地考虑。 + 注意,向用户授予pg_read_file()或相关函数的 EXECUTE 权限,会使其能够读取服务器上数据库服务器进程能读取的任何文件;这些函数会绕过数据库内部的所有权限检查。例如,具有这种访问权限的用户能够读取存储认证信息的pg_authid表的内容,以及数据库中的任何表数据。因此,授予这些函数的访问权限时应仔细考虑。 + + + + 授予这些函数的权限时,请注意:表中列出可选参数的条目,大多由多个参数列表不同的实际函数实现。若要使用其中某个函数,就必须单独授予该函数的权限。psql\df命令可以帮助检查实际的函数签名。 - 这些函数中的一些函数有可选的missing_ok参数,可以指定当文件或目录不存在时的行为。 - 如果为true,函数返回NULL或着空结果集,根据适合情况。 - 如果为false,会产生一个错误。默认为false。 + 这些函数中的一些函数接受可选的missing_ok参数,用于指定文件或目录不存在时的行为。如果为true,函数会视情况返回NULL或空结果集。如果为false,则会报错。(除文件未找到之外的失败情况,在任何情况下都会报错。)默认为false @@ -2049,12 +2036,12 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size setof text - 返回指定目录中所有文件(和目录以及其他指定文件)的名称。 - include_dot_dirs参数标示在结果集中是否包括...;默认为不包括它们。 - 要包括它们在missing_oktrue时能够有用,以从不存在的目录中辨别一个空目录。 + 返回指定目录中所有文件的名称(包括目录及其他特殊文件)。 + include_dot_dirs参数指示结果集中是否包含...;默认不包含它们。 + 在missing_oktrue时,包含它们有助于区分不存在的目录和空目录。 - 这个函数默认限制为超级用户,但是其他用户可以被授予EXECUTE以运行此函数。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -2073,7 +2060,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size 返回服务器日志目录中每个普通文件的名称、大小和最后修改时间(mtime)。以点开头的文件名、目录和其他特殊文件将被排除。 - 默认情况下,此函数仅限于超级用户和具有pg_monitor角色权限的角色,但其他用户可以被授予EXECUTE权限来运行该函数。 + 默认情况下,此函数仅限超级用户和具有pg_monitor角色权限的角色使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -2093,8 +2080,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size 以点开头的文件名、目录和其他特殊文件将被排除。 - 默认情况下,此函数仅限于超级用户和具有pg_monitor角色权限的角色, - 但其他用户可以被授予EXECUTE权限来运行该函数。 + 默认情况下,此函数仅限超级用户和具有pg_monitor角色权限的角色使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -2114,7 +2100,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size 以点开头的文件名、目录和其他特殊文件将被排除。 - 默认情况下,此函数仅限于超级用户和pg_monitor角色的成员,但其他用户可以被授予EXECUTE权限来运行该函数。 + 默认情况下,此函数仅限超级用户和pg_monitor角色的成员使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -2134,7 +2120,7 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size 以点开头的文件名、目录和其他特殊文件将被排除。 - 默认情况下,此函数仅限于超级用户和pg_monitor角色的成员,但其他用户可以被授予EXECUTE权限来运行该函数。 + 默认情况下,此函数仅限超级用户和pg_monitor角色的成员使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -2154,7 +2140,26 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size 其中slot_name是作为函数输入提供的复制槽的名称。以点开头的文件名、目录和其他特殊文件将被排除。 - 默认情况下,此函数仅限于超级用户和pg_monitor角色的成员,但其他用户可以被授予EXECUTE权限来运行该函数。 + 默认情况下,此函数仅限超级用户和pg_monitor角色的成员使用,但可以向其他用户授予EXECUTE权限以运行它。 + + + + + + + pg_ls_summariesdir + + pg_ls_summariesdir () + setof record + ( name text, + size bigint, + modification timestamp with time zone ) + + + 返回服务器 WAL 摘要目录(pg_wal/summaries)中每个普通文件的名称、大小和最后修改时间(mtime)。排除名称以点开头的文件、目录及其他特殊文件。 + + + 默认情况下,此函数仅限超级用户和pg_monitor角色的成员使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -2170,11 +2175,11 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size modificationtimestamp with time zone ) - 返回服务器的WAL归档状态目录(pg_wal/archive_status)中的每个普通文件的名称、大小、和最后修改时间(mtime)。 - 文件名以一个点(dot)开始,目录和其他指定的文件不包括。 + 返回服务器 WAL 归档状态目录(pg_wal/archive_status)中每个普通文件的名称、大小和最后修改时间(mtime)。 + 以点号开头的文件名、目录以及其他特殊文件都不会包含在结果中。 - 这个函数默认限制在超级用户和pg_monitor角色的成员,但是其他用户可以被授予EXECUTE以运行此函数。 + 默认情况下,此函数仅限超级用户和pg_monitor角色的成员使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -2191,12 +2196,12 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size modificationtimestamp with time zone ) - 返回针对指定tablespace的临时文件目录中的每个普通文件的名称、大小、和最后修改时间(mtime)。 - 如果tablespace没有提供,pg_default 表空间为被检验的。 - 文件名以一个点(dot)开始,目录和其他指定的文件不包括。 + 返回针对指定tablespace的临时文件目录中每个普通文件的名称、大小和最后修改时间(mtime)。 + 如果未提供tablespace,则检查pg_default表空间。 + 以点号开头的文件名、目录以及其他特殊文件都不会包含在结果中。 - 这个函数默认限制在超级用户和pg_monitor角色的成员,但是其他用户可以被授予EXECUTE以运行此函数。 + 默认情况下,此函数仅限超级用户和pg_monitor角色的成员使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -2205,16 +2210,16 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size pg_read_file - pg_read_file ( filenametext, offset bigint, length bigint , missing_ok boolean ) + pg_read_file ( filenametext, offset bigint, length bigint , missing_ok boolean ) text - 返回一个文本文件的全部或部分,开始于给定的字节offset,在最大的length字节返回(如果文件的结尾先达到了则减少)。 - 如果offset为负,他于文件的结尾有关。如果offsetlength 被省略,整个文件被返回。 - 从文件中读的字节在服务器的编码中解释为字符串;如果它们在哪些编码中不是有效的则抛出错误。 + 返回一个文本文件的全部或部分,从给定的字节offset开始,最多返回length字节(如果先到达文件末尾,则返回更少)。 + 如果offset为负,则它相对于文件末尾计算。如果省略offsetlength,则返回整个文件。 + 从文件中读取的字节会按数据库编码解释为字符串;如果它们在该编码下无效,则会抛出错误。 - 这个函数默认限制在超级用户,但是其他用户可以被授予EXECUTE以运行此函数。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -2223,18 +2228,18 @@ SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size pg_read_binary_file - pg_read_binary_file ( filenametext, offset bigint, length bigint , missing_ok boolean ) + pg_read_binary_file ( filenametext, offset bigint, length bigint , missing_ok boolean ) bytea - 返回文件的全部或部分。这个函数与pg_read_file 是完全相同的,除了它可以读任意的二进制数据,返回结果为bytea而不是text; - 因此,没有编码检查会被执行。 + 返回文件的全部或部分。该函数与pg_read_file完全相同,只是它可以读取任意二进制数据,并返回bytea而不是text; + 因此不会执行编码检查。 - 这个函数默认限制在超级用户,但是其他用户可以被授予EXECUTE以运行此函数。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 - 与 convert_from函数组合,这个函数能被用于以指定的编码读文本文件并转换到数据库的编码: + 与convert_from函数配合使用时,该函数可用于按指定编码读取文本文件,并将其转换为数据库编码: SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); @@ -2256,10 +2261,10 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); isdir boolean ) - 返回一个记录,包含文件的大小、最后访问时间戳、最后修改时间戳,最后文件状态变更时间戳(仅在UNIX平台)、文件建立时间戳(仅Windows),和一个标志旗如果它是一个目录。 + 返回一个记录,包含文件大小、最后访问时间戳、最后修改时间戳、最后文件状态变更时间戳(仅限 Unix 平台)、文件创建时间戳(仅限 Windows)以及一个指示其是否为目录的标志。 - 这个函数默认限制在超级用户,但是其他用户可以被授予EXECUTE以运行此函数。 + 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -2279,11 +2284,11 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); - 所有这些函数都打算用于锁定应用程序定义的资源,可以通过一个64位键值或两个32位键值来标识(注意这两个键空间不能重叠)。 - 如果另一个会话已经在相同的资源标识符上持有一个冲突的锁,函数将等待直到资源变成可用,或者返回一个false结果,合适于函数的。 - 锁可以是共享或排他的:共享锁不会与同一资源上的其他共享锁发生冲突,只会与排他锁发生冲突。 - 锁可以在会话级(这样它们被保持直到释放或会话结束)或在事务级(这样它们被保持直到当前事务结束;没有手动释放的供应)。 - 多个会话级锁请求堆栈,因此如果同一个资源标识符被锁定三次,那么必须有三个解锁请求来释放资源,在会话结束之前。 + 这些函数用于锁定应用程序定义的资源;资源可用一个 64 位键值或两个 32 位键值标识(这两个键空间互不重叠)。 + 如果另一个会话已对同一资源标识符持有冲突锁,函数会根据自身的行为等待资源可用,或返回false。 + 锁可以是共享的或排他的:共享锁不会与同一资源上的其他共享锁冲突,只会与排他锁冲突。 + 锁可以在会话级获取(一直保持到释放或会话结束),也可以在事务级获取(一直保持到当前事务结束,不能手动释放)。 + 多次会话级锁请求会累加,因此,如果同一资源标识符被锁定三次,就必须请求解锁三次,才能在会话结束前释放该资源。
@@ -2434,8 +2439,8 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); boolean - 获取一个排他的会话级咨询锁,如果适用。 - 这将立即获得锁并返回true,或者如果不能立即获取锁则立即返回 false而无需等待。 + 尝试获取一个排他的会话级咨询锁。 + 如果能立即获取到锁,就返回true;否则立即返回false,而不等待。 @@ -2452,8 +2457,8 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); boolean - 获取一个共享的会话级咨询锁,如果适用。 - 这将立即获得锁并返回true,或者如果不能立即获取锁则立即返回 false而无需等待。 + 尝试获取一个共享的会话级咨询锁。 + 如果能立即获取到锁,就返回true;否则立即返回false,而不等待。 @@ -2470,8 +2475,8 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); boolean - 获取一个排他的事务级咨询锁,如果适用。 - 这将立即获得锁并返回true,或者如果不能立即获取锁则立即返回 false而无需等待。 + 尝试获取一个排他的事务级咨询锁。 + 如果能立即获取到锁,就返回true;否则立即返回false,而不等待。 @@ -2488,8 +2493,8 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); boolean - 获取一个共享的事务级咨询锁,如果适用。 - 这将立即获得锁并返回true,或者如果不能立即获取锁则立即返回 false而无需等待。 + 尝试获取一个共享的事务级咨询锁。 + 如果能立即获取到锁,就返回true;否则立即返回false,而不等待。 diff --git a/zh/20/func/func-aggregate.sgml b/zh/20/func/func-aggregate.sgml index 3a79ec4f..5393e47b 100644 --- a/zh/20/func/func-aggregate.sgml +++ b/zh/20/func/func-aggregate.sgml @@ -8,17 +8,22 @@ - 聚合函数从一个输入值的集合计算出一个单一值。 - 内置的通用聚合函数在中列出,而统计性聚合是在中列出。 + 聚合函数从一个输入值的集合计算出一个单一结果。 + 内置的通用聚合函数在中列出,而统计聚合函数在中列出。 内置的组内有序集聚合函数在中列出,而内置的组内假想集聚合在中列出。 与聚合函数紧密相关的分组操作在中列出。 - 中会解释针对聚合函数的特殊语法考虑。额外的介绍信息请参考。 + 中会解释针对聚合函数的特殊语法注意事项。更多入门信息请参考 支持部分模式的聚合函数能够参与各种优化,例如并行聚合。 + + 虽然下面所有聚合函数都接受可选的ORDER BY子句 + (详见),但这里只在输出受排序影响的聚合函数签名中列出了该子句。 + +
通用聚合函数 @@ -40,35 +45,49 @@ + + + + any_value + + any_value ( anyelement ) + 与输入类型相同 + + + 从非空输入值中返回任意一个值。 + + + + array_agg - array_agg ( anynonarray ) + array_agg ( anynonarray ORDER BY input_sort_columns ) anyarray 将所有输入值,包括空值,收集到一个数组中。 - No + - array_agg ( anyarray ) + array_agg ( anyarray ORDER BY input_sort_columns ) anyarray - 将所有输入数组连接到一个更高维度的数组中。(输入必须都具有相同的维度,并且不能为空的(empty)或空值(null)。) + 将所有输入数组连接成维数增加一维的数组。(所有输入的维数必须相同,且不能是空数组或空值(NULL)。) - No + - average + 平均值 avg @@ -103,7 +122,7 @@ 计算所有非空输入值的平均值(算术平均值)。 - Yes + @@ -127,9 +146,9 @@ bit - 计算所有非空输入值的逐位AND。 + 计算所有非空输入值的按位与。 - Yes + @@ -153,9 +172,9 @@ bit - 计算所有非空输入值的逐位OR。 + 计算所有非空输入值的按位或。 - Yes + @@ -182,7 +201,7 @@ 计算所有非空输入值的按位异或。 可用作一组无序的值集合的校验和。 - Yes + @@ -196,7 +215,7 @@ 如果全部非空输入值都为真则返回真,否则返回假。 - Yes + @@ -210,7 +229,7 @@ 如果任何非空输入值为真则返回真,否则返回假。 - Yes + @@ -224,7 +243,7 @@ 计算输入行的数量。 - Yes + @@ -235,7 +254,7 @@ 计算输入值不为空的输入行的数量。 - Yes + @@ -247,9 +266,9 @@ boolean - 这是对应bool_and的SQL标准的等效物。 + 这是标准 SQL 中与bool_and等价的函数。 - Yes + @@ -257,20 +276,84 @@ json_agg - json_agg ( anyelement ) + json_agg ( anyelement ORDER BY input_sort_columns ) json jsonb_agg - jsonb_agg ( anyelement ) + jsonb_agg ( anyelement ORDER BY input_sort_columns ) jsonb 收集所有输入值,包括空值,到一个JSON数组。根据to_jsonto_jsonb将值转换为JSON。 - No + + + + + + + json_agg_strict + + json_agg_strict ( anyelement ) + json + + + + jsonb_agg_strict + + jsonb_agg_strict ( anyelement ) + jsonb + + + 将所有非空输入值收集到一个JSON数组中,跳过空值。根据to_jsonto_jsonb将值转换为JSON。 + + + + + + + json_arrayagg + json_arrayagg ( + value_expression + ORDER BY sort_expression + { NULL | ABSENT } ON NULL + RETURNING data_type FORMAT JSON ENCODING UTF8 ) + + + 行为与json_array相同,只是它作为一个聚合函数,因此只接受一个 + value_expression参数。 + 如果指定了ABSENT ON NULL,则会省略所有 NULL 值。 + 如果指定了ORDER BY,元素将按该顺序出现在数组中,而不是按输入顺序。 + + + SELECT json_arrayagg(v) FROM (VALUES(2),(1)) t(v) + [2, 1] + + + + + + + json_objectagg + json_objectagg ( + { key_expression { VALUE | ':' } value_expression } + { NULL | ABSENT } ON NULL + { WITH | WITHOUT } UNIQUE KEYS + RETURNING data_type FORMAT JSON ENCODING UTF8 ) + + + 行为与json_object相同,只是它作为一个聚合函数,因此只接受一个 + key_expression参数和一个 + value_expression参数。 + + + SELECT json_objectagg(k:v) FROM (VALUES ('a'::text,current_date),('b',current_date + 1)) AS t(k,v) + { "a" : "2022-05-10", "b" : "2022-05-11" } + + @@ -280,7 +363,8 @@ json_object_agg ( key "any", value - "any" ) + "any" + ORDER BY input_sort_columns ) json @@ -289,14 +373,15 @@ jsonb_object_agg ( key "any", value - "any" ) + "any" + ORDER BY input_sort_columns ) jsonb - 将所有键/值对收集到一个JSON对象中。关键参数强制转换为文本;值参数按照to_jsonto_jsonb进行转换。 + 将所有键/值对收集到一个JSON对象中。键参数强制转换为文本;值参数按照to_jsonto_jsonb进行转换。 值可以为空,但键不能(为空)。 - No + @@ -325,6 +410,32 @@ + + + + json_object_agg_unique + + json_object_agg_unique ( + key "any", + value "any" ) + json + + + + jsonb_object_agg_unique + + jsonb_object_agg_unique ( + key "any", + value "any" ) + jsonb + + + 将所有键/值对收集到一个JSON对象中。键参数强制转换为文本;值参数按照to_jsonto_jsonb进行转换。 + 值可以为空,但键不能为空。如果存在重复键,则会抛出错误。 + + + + @@ -357,8 +468,8 @@ 最大值 - max ( see text ) - same as input type + max ( 见说明 ) + 与输入类型相同 计算非空输入值的最大值。适用于任何数字、字符串、日期/时间或枚举类型, @@ -375,8 +486,8 @@ 最小值 - min ( see text ) - same as input type + min ( 见说明 ) + 与输入类型相同 计算非空输入值的最小值。适用于任何数字、字符串、日期/时间或枚举类型, @@ -405,7 +516,7 @@ 计算非空输入值的并集。 - No + @@ -425,7 +536,7 @@ 计算非空输入值的交集。 - No + @@ -439,13 +550,14 @@ string_agg ( value - bytea, delimiter bytea ) + bytea, delimiter bytea + ORDER BY input_sort_columns ) bytea - 将非 null 输入值连接成一个字符串。第一个值之后的每个值前面都会放置相应的delimiter(如果它不为 null)。 + 将非 NULL 输入值连接成一个字符串。在第一个值之后,每个值前面都会放置相应的delimiter(如果它不为 NULL)。 - No + @@ -487,7 +599,7 @@ 计算非空输入值的总和。 - Yes + @@ -495,35 +607,28 @@ xmlagg - xmlagg ( xml ) + xmlagg ( xml ORDER BY input_sort_columns ) xml - 连接非空的XML输入值(参见)。 + 连接非空的 XML 输入值(参见)。 - No +
- 应该注意的是,除了count之外,这些函数在没有选择行时返回空值。 - 特别地,行数的sum返回空(null),而不是预期的零,array_agg在没有输入行时返回空(null)而不是空数组。 - coalesce函数可以在必要时用零或空数组代替空(null)。 + 需要注意,除了count之外,这些函数在没有选中任何行时都会返回空值。特别地,sum在没有输入行时返回空值,而不是预期中的零;array_agg在没有输入行时返回空值,而不是空数组。必要时,可以用coalesce函数把空值替换成零或空数组。 - 聚合函数 array_agg,json_agg, jsonb_agg,json_object_agg, jsonb_object_agg, - string_agg,和 xmlagg,以及类似的用户定义的聚合函数,根据输入值的顺序产生富有意义的不同的结果值。 - 默认情况下,这种排序是不指定的,但可以通过在聚合调用中写入ORDER BY子句来控制,如所示。 - 或者,从排序的子查询提供输入值通常也可以。例如: - + 聚合函数array_aggjson_aggjsonb_aggjson_agg_strictjsonb_agg_strictjson_object_aggjsonb_object_aggjson_object_agg_strictjsonb_object_agg_strictjson_object_agg_uniquejsonb_object_agg_uniquejson_object_agg_unique_strictjsonb_object_agg_unique_strictstring_aggxmlagg,以及类似的用户定义聚合函数,其结果值会随输入值的顺序发生实质性变化。默认情况下,输入顺序未指定,但可以在聚合调用中写入ORDER BY子句来控制,如所示。也可以用已排序的子查询提供输入值,这通常也能奏效。例如: - - 注意,如果外部查询级别包含其他处理,例如关联,则此方法可能会失败,因为这可能导致子查询的输出在计算聚合之前重新排序。 + 需要注意,如果外层查询包含连接等额外处理,这种方法可能失效,因为子查询的输出可能在计算聚合之前被重新排序。 @@ -537,31 +642,24 @@ SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab; - 布尔聚合 bool_andbool_or 对应于标准SQL聚合 everyanysome. - PostgreSQL 支持 every, 但不支持 anysome, 因为标准语法中存在模糊性: - + 布尔聚合bool_andbool_or对应于标准 SQL 聚合everyanysome。 + PostgreSQL支持every,但不支持anysome,因为标准语法中存在歧义: SELECT b1 = ANY((SELECT b2 FROM t2 ...)) FROM t1 ...; - - 这里ANY可以被认为是引入子查询,或者是聚合函数,如果子查询返回一行布尔值。因此,不能为这些聚合提供标准名称。 +此处的ANY既可以被视为引入一个子查询,也可以在该子查询返回一行布尔值时被视为聚合函数。因此,不能将标准名称用于这些聚合。 - 习惯使用其他SQL数据库管理系统的用户可能会对count聚合应用于整个表时的性能感到失望。一个类似下面的查询: - + 习惯于其他 SQL 数据库管理系统的用户,可能会对count聚合用于整个表时的性能感到失望。如下查询: SELECT count(*) FROM sometable; - - 将需要与表大小成比例的工作:PostgreSQL将需要扫描整个表或包含表中所有行的索引。 +所需的工作量与表大小成正比:PostgreSQL需要扫描整个表,或者完整扫描一个包含表中所有行的索引。 - 显示了统计分析中常用的聚合函数。 - (这些被分离出来仅仅是为了避免使更常用的聚合列表混乱。) - 显示为接受numeric_type的函数可用于所有类型smallint, integer,bigint, numeric, real, 和 double precision。 - 在描述中提及N时,它意味着所有输入表达式都非空的输入行数。在所有情况下,如果计算没有意义,则返回null,例如当N为0时。 + 列出了统计分析中常用的聚合函数。(将它们单独列出,只是为了避免更常用的聚合函数列表过于杂乱。)标为接受numeric_type的函数适用于smallintintegerbigintnumericrealdouble precision这些类型。描述中提到的N表示所有输入表达式都非空的输入行数。无论哪种情况,如果计算没有意义,例如N为 0,就返回 null。 @@ -596,7 +694,7 @@ SELECT count(*) FROM sometable; - correlation + 相关性 corr @@ -607,14 +705,14 @@ SELECT count(*) FROM sometable; 计算相关系数。 - Yes + - covariance - population + 协方差 + 总体 covar_pop @@ -625,14 +723,14 @@ SELECT count(*) FROM sometable; 计算总体协方差。 - Yes + - covariance - sample + 协方差 + 样本 covar_samp @@ -643,7 +741,7 @@ SELECT count(*) FROM sometable; 计算样本协方差。 - Yes + @@ -655,9 +753,9 @@ SELECT count(*) FROM sometable; double precision - 计算自变量的平均值,sum(X)/N. + 计算自变量的平均值,即sum(X)/N - Yes + @@ -669,9 +767,9 @@ SELECT count(*) FROM sometable; double precision - 计算因变量的平均值,sum(Y)/N. + 计算因变量的平均值,即sum(Y)/N - Yes + @@ -685,13 +783,13 @@ SELECT count(*) FROM sometable; 计算两个输入都非空的行数。 - Yes + - regression intercept + 回归截距 regr_intercept @@ -700,9 +798,9 @@ SELECT count(*) FROM sometable; double precision - 计算由(XY)对决定的最小二乘拟合的线性方程的Y-截距。 + 计算由(XY)数值对确定的最小二乘拟合线性方程的 y 轴截距。 - Yes + @@ -716,13 +814,13 @@ SELECT count(*) FROM sometable; 计算相关系数的平方。 - Yes + - regression slope + 回归斜率 regr_slope @@ -731,9 +829,9 @@ SELECT count(*) FROM sometable; double precision - 计算由(X, Y)对决定的最小二乘拟合的线性方程的斜率。 + 计算由(XY)数值对确定的最小二乘拟合线性方程的斜率。 - Yes + @@ -745,10 +843,9 @@ SELECT count(*) FROM sometable; double precision - 计算自变量的平方和 - sum(X^2) - sum(X)^2/N. + 计算自变量的平方和,即sum(X^2) - sum(X)^2/N - Yes + @@ -760,10 +857,9 @@ SELECT count(*) FROM sometable; double precision - 计算独立变量乘以因变量的sum of products, - sum(X*Y) - sum(X) * sum(Y)/N. + 计算自变量与因变量的乘积和,即sum(X*Y) - sum(X) * sum(Y)/N - Yes + @@ -775,69 +871,62 @@ SELECT count(*) FROM sometable; double precision - 计算因变量的平方和, - sum(Y^2) - sum(Y)^2/N. + 计算因变量的平方和,即sum(Y^2) - sum(Y)^2/N - Yes + - standard deviation + 标准差 stddev stddev ( numeric_type ) - double precision - for real or double precision, - otherwise numeric + 对于realdouble precision输入,返回double precision;否则返回numeric - 这是stddev_samp的一个历史别称。 + 这是stddev_samp的一个历史别名。 - Yes + - standard deviation - population + 标准差 + 总体 stddev_pop stddev_pop ( numeric_type ) - double precision - for real or double precision, - otherwise numeric + 对于realdouble precision输入,返回double precision;否则返回numeric 计算输入值的总体标准差。 - Yes + - standard deviation - sample + 标准差 + 样本 stddev_samp stddev_samp ( numeric_type ) - double precision - for real or double precision, - otherwise numeric + 对于realdouble precision输入,返回double precision;否则返回numeric 计算输入值的样本标准差。 - Yes + @@ -846,54 +935,48 @@ SELECT count(*) FROM sometable; variance variance ( numeric_type ) - double precision - for real or double precision, - otherwise numeric + 对于realdouble precision输入,返回double precision;否则返回numeric - 这是 var_samp 的一个历史别称。 + 这是 var_samp 的一个历史别名。 - Yes + - variance - population + 方差 + 总体 var_pop var_pop ( numeric_type ) - double precision - for real or double precision, - otherwise numeric + 对于realdouble precision输入,返回double precision;否则返回numeric - 计算输入值的总体方差(总体标准差的平方)。 + 计算输入值的总体方差(总体标准差的平方)。 - Yes + - variance - sample + 方差 + 样本 var_samp var_samp ( numeric_type ) - double precision - for real or double precision, - otherwise numeric + 对于realdouble precision输入,返回double precision;否则返回numeric - 计算输入值的样本方差(样本标准差的平方)。 + 计算输入值的样本方差(样本标准差的平方)。 - Yes + @@ -904,11 +987,11 @@ SELECT count(*) FROM sometable; 这些函数有时被称为逆分布函数。 它们的聚合输入通过ORDER BY引入,还可以接受未聚合的直接参数,但后者只计算一次。 所有这些函数在其聚合输入中都忽略空(null)值。 - 对于使用fraction参数的函数,分数值必须在 0 到 1 之间;否则会报错。但是,null 的 fraction 值只会产生一个 null 结果。 + 对于使用fraction参数的函数,比例值必须在 0 到 1 之间;否则会报错。但是,null 的 fraction 值只会产生一个 null 结果。 - ordered-set aggregate + 有序集聚合 内置 @@ -940,16 +1023,16 @@ SELECT count(*) FROM sometable; - mode - statistical + 众数 + 统计 mode () WITHIN GROUP ( ORDER BY anyelement ) anyelement - 计算mode,即聚合参数最频繁的值(如果有多个相同频繁的值,第一个可以任意选择)。聚合参数必须是可排序类型。 + 计算众数,即聚合参数中出现次数最多的值(若多个值的出现次数相同且最多,则任意选择其中第一个)。聚合参数必须是可排序类型。 - No + @@ -967,9 +1050,9 @@ SELECT count(*) FROM sometable; 计算连续百分位点,该值对应于聚合参数值有序集合中的指定fraction。 - 如果需要,这将在相邻的输入项之间插入。 + 必要时会在相邻输入项之间进行插值。 - No + @@ -984,7 +1067,7 @@ SELECT count(*) FROM sometable; 计算多个连续百分位点。结果是一个与fractions参数具有相同维度的数组,其中每个非 null 元素都被替换为对应百分位点的值(必要时会进行插值)。 - No + @@ -1000,7 +1083,7 @@ SELECT count(*) FROM sometable; 计算离散百分位数,即聚合参数值的有序集合中的第一个值,该值在排序中的位置等于或超过指定的fraction。 聚合参数必须是可排序类型。 - No + @@ -1013,14 +1096,14 @@ SELECT count(*) FROM sometable; 结果是一个与fractions参数具有相同维数的数组,每个非空元素都被对应于该百分位数的输入值替换。 聚合参数必须是可排序类型。 - No + - hypothetical-set aggregate + 假想集聚合 内置 @@ -1056,52 +1139,52 @@ SELECT count(*) FROM sometable; rank - hypothetical + 假设行 rank ( args ) WITHIN GROUP ( ORDER BY sorted_args ) bigint - 计算假设行的排名,包括间隔,就是说在它的同等行组中第一行的行号。 + 计算假设行的排名,允许空缺;即该行所属同等行组中第一行的行号。 - No + dense_rank - hypothetical + 假设行 dense_rank ( args ) WITHIN GROUP ( ORDER BY sorted_args ) bigint - 计算假设行的排名,没有间隔;这个功能有效地计数同等行组。 + 计算假设行的排名,没有空缺;此函数实际上对同等行组进行计数。 - No + percent_rank - hypothetical + 假设行 percent_rank ( args ) WITHIN GROUP ( ORDER BY sorted_args ) double precision - 计算假设行的相关排行,也就是(rank - 1) / (total rows - 1)。取值范围为 0 到 1(含)。 + 计算假设行的相对排名,即(rank - 1)/(总行数 - 1)。取值范围为 0 到 1(含)。 - No + cume_dist - hypothetical + 假设行 cume_dist ( args ) WITHIN GROUP ( ORDER BY sorted_args ) double precision @@ -1109,7 +1192,7 @@ SELECT count(*) FROM sometable; 计算累积分布,也就是(位于假设行之前或与假设行同等的行数)/(总行数)。取值范围为 1/N 到 1。 - No + @@ -1142,8 +1225,7 @@ SELECT count(*) FROM sometable; integer - 返回一个位掩码以指示哪个GROUP BY表达式没有包含在当前分组集中。 - 比特位被分配给最右边的参数对应于最低有效位;如果对应的表达式包含在生成当前结果行的分组集的分组条件中,则每个位为0,如果不包含则为1。 + 返回一个位掩码,指示哪些GROUP BY表达式未包含在当前分组集中。分配比特位时,最右侧参数对应最低有效位;如果相应表达式包含在生成当前结果行的分组集的分组条件中,该位为 0,否则为 1。 @@ -1151,9 +1233,7 @@ SELECT count(*) FROM sometable; - 所示的分组操作与分组集(参见)共同使用,以区分结果行。 - GROUPING函数的参数实际上并不求值,但它们必须与相关查询级别的GROUP BY子句中给出的表达式完全匹配。例如: - + 在中列出的分组操作与分组集配合使用(参见),以区分结果行。传给GROUPING函数的参数不会实际求值,但它们必须与相关查询层级的GROUP BY子句中的表达式完全匹配。例如: => SELECT * FROM items_sold; make | model | sales -------+-------+------- @@ -1174,9 +1254,7 @@ SELECT count(*) FROM sometable; Bar | | 1 | 20 | | 3 | 50 (7 rows) - - 在这里,前四行中的grouping0表明这些已经正常分组,在两个分组列上。 - 值1表示model没有在倒数两行中分组,值3表示无论是make还是model都没有在最后一行中分组(因此,这是所有输入行的聚合)。 +这里,前四行的grouping值为0,表明这些行按两个分组列正常分组。值1表明model未用于倒数第二、第三行的分组,值3则表明最后一行既未按make分组,也未按model分组(因此该行聚合了全部输入行)。 diff --git a/zh/20/func/func-array.sgml b/zh/20/func/func-array.sgml index b32b17c3..b3954e35 100644 --- a/zh/20/func/func-array.sgml +++ b/zh/20/func/func-array.sgml @@ -5,9 +5,9 @@ 显示了可以用于数组类型的专用的操作符。 除此之外,中所示的常用比较操作符也适用于数组。 - 比较操作符逐个元素的比较数组内容,使用默认的元素数据类型的B-树比较函数,并根据第一个差值进行排序。 + 比较操作符逐个元素比较数组内容,使用元素数据类型的默认 B-树比较函数,并根据第一个差异进行排序。 多维数组的元素按照行序进行访问(最后的下标变化最快)。 - 如果两个数组的内容相同但维数不等,那么维度信息中的第一个不同将决定排序顺序。 + 如果两个数组的内容相同但维度信息不同,那么维度信息中的第一个不同将决定排序顺序。 @@ -38,7 +38,7 @@ 第一个数组是否包含第二个数组,也就是说,出现在第二个数组中的每个元素是否等于第一个数组中的某个元素? - (重复值不需要特殊处理,因此ARRAY[1]ARRAY[1,1]被认为包含对方。) + (重复元素不作特殊处理,因此ARRAY[1]ARRAY[1,1]被认为包含对方。) ARRAY[1,4,3] @> ARRAY[3,1,3] @@ -80,8 +80,7 @@ anycompatiblearray - 连接两个数组。连接空(null)或空数组是一个无操作(no-op);否则,数组必须具有相同的维度数(如第一个示例所示),或者维度数相差一个(如第二个示例所示)。 - 如果数组不是完全相同的元素类型,它们将被强制转换成一个共同的类型(参见)。 + 连接两个数组。连接 null 或空数组不会产生任何效果;否则,数组必须具有相同的维数(如第一个示例所示),或维数相差一维(如第二个示例所示)。如果数组的元素类型不同,则会将它们强制转换为同一个类型(参见)。 ARRAY[1,2,3] || ARRAY[4,5,6,7] @@ -113,7 +112,7 @@ anycompatiblearray - 将元素连接到数组的末尾(数组必须为空或一维的[one-dimensional])。 + 将元素连接到数组的末尾(数组必须为空或一维)。 ARRAY[4,5,6] || 7 @@ -125,7 +124,7 @@
- 参阅获取有关数组操作符行为的更多细节。有关哪些操作符支持被索引的操作,请参阅。 + 参阅获取有关数组操作符行为的更多细节。有关哪些操作符支持索引操作,请参阅 @@ -214,8 +213,7 @@ anyarray - 返回一个包含给定值的拷贝的数组,其维数与第二个参数指定的长度相同。 - 可选的第三个参数提供每个维度的下界值(默认为全部为 1)。 + 返回用给定值的副本填充的数组,各维的长度由第二个参数指定。可选的第三个参数提供各维的下界值(默认均为1)。 array_fill(11, ARRAY[2,3]) @@ -296,7 +294,7 @@ integer - 返回阵列中第二个参数中第一次发生的下标,如果它不存在,则返回NULL。 + 返回第二个参数在数组中首次出现的下标;若不存在,则返回NULL。 如果给出了第三个参数,则搜索从该下标开始。数组必须是一维的。比较是使用IS NOT DISTINCT FROM语义进行的,所以可以搜索NULL @@ -314,9 +312,9 @@ integer[] - 返回作为第一个参数的数组中第二个参数所有出现的下标的数组。 + 返回第二个参数在第一个参数所给数组中所有出现位置的下标数组。 数组必须是一维的。使用IS NOT DISTINCT FROM语义完成比较,所以可以搜索NULL。 - 只有当数组为NULL时才返回NULL;如果在数组中没有找到该值,则返回空数组。 + 只有当数组为NULL时才返回NULL;如果在数组中没有找到该值,则返回空数组。 array_positions(ARRAY['A','A','B','A'], 'A') @@ -443,7 +441,7 @@ anyarray - 对数组的第一维进行排序。排序顺序由数组元素类型的默认排序规则决定;不过,如果元素类型支持排序规则,也可以通过给array参数添加COLLATE子句来指定要使用的排序规则。 + 对数组的第一维进行排序。排序顺序由数组元素类型的默认排序顺序决定;不过,如果元素类型支持排序规则,也可以通过给array参数添加COLLATE子句来指定要使用的排序规则。 如果descending为 true,则按降序排序,否则按升序排序。省略时默认按升序排序。如果nulls_first为 true,则空值出现在非空值之前,否则空值出现在非空值之后。省略时,nulls_first取与descending相同的值。 @@ -516,7 +514,7 @@ anyarray - 通过删除最后的n元素来裁剪数组。 + 通过删除最后的n个元素来裁剪数组。 如果数组是多维的,则只裁剪第一个维度。 @@ -565,7 +563,7 @@ 将多个数组(可能是不同的数据类型)展开到一组行中。 如果数组的长度不完全相同,那么较短的数组将用NULL填充。 - 这种形式只在查询的FROM子句中允许;参见。 + 这种形式只允许出现在查询的 FROM 子句中;参见 SELECT * FROM unnest(ARRAY[1, 2], ARRAY['foo', 'bar', 'baz']) AS x(a, b) diff --git a/zh/20/func/func-binarystring.sgml b/zh/20/func/func-binarystring.sgml index 22e1e1a3..ed7c4d6b 100644 --- a/zh/20/func/func-binarystring.sgml +++ b/zh/20/func/func-binarystring.sgml @@ -3,17 +3,17 @@ 二进制串函数和操作符 - binary data - functions + 二进制数据 + 函数 - 本节描述那些检查和操作二进制字符串的函数和操作符,这是类型bytea的值。 + 本节描述用于检查和操作二进制字符串(即bytea类型的值)的函数和操作符。 其中许多函数在用途和语法上都与上一节中描述的文本字符串函数等效。 - SQL定义了一些使用关键字而不是逗号来分割参数的串函数。详情请见PostgreSQL也提供了这些函数使用常规函数调用语法的版本(参阅)。 + SQL定义了一些使用关键字而不是逗号来分隔参数的字符串函数。详情请见PostgreSQL也提供了这些函数使用常规函数调用语法的版本(参阅)。 @@ -40,14 +40,14 @@ - binary string - concatenation + 二进制串 + 串接 bytea || bytea bytea - 连接两个二进制字符串。 + 串接两个二进制字符串。 '\x123456'::bytea || '\x789a00bcde'::bytea @@ -72,6 +72,42 @@ + + + + btrim + + btrim ( bytes bytea, + bytesremoved bytea ) + bytea + + + 从bytes的开头和结尾移除仅由bytesremoved中字节组成的最长字符串。 + + + btrim('\x1234567890'::bytea, '\x9012'::bytea) + \x345678 + + + + + + + ltrim + + ltrim ( bytes bytea, + bytesremoved bytea ) + bytea + + + 从bytes的开头移除仅由bytesremoved中字节组成的最长字符串。 + + + ltrim('\x1234567890'::bytea, '\x9012'::bytea) + \x34567890 + + + @@ -98,8 +134,7 @@ bytea - 将bytes的子字符串替换为newsubstring,该子字符串从start字节开始,并以count字节扩展。 - 如果忽略了count,则默认为newsubstring的长度。 + 用newsubstring替换bytes中从第start个字节开始、长度为count个字节的子字符串。如果省略count,则默认为newsubstring的长度。 overlay('\x1234567890'::bytea PLACING '\002\003'::bytea FROM 2 FOR 3) @@ -116,7 +151,7 @@ integer - 返回bytes中指定的substring的第一个起始索引,如果不存在,则为零。 + 返回substringbytes中首次出现的位置;如果不存在则返回零。 position('\x5678'::bytea IN '\x1234567890'::bytea) @@ -124,6 +159,24 @@ + + + + rtrim + + rtrim ( bytes bytea, + bytesremoved bytea ) + bytea + + + 从bytes的结尾移除仅由bytesremoved中字节组成的最长字符串。 + + + rtrim('\x1234567890'::bytea, '\x9012'::bytea) + \x12345678 + + + @@ -133,8 +186,7 @@ bytea - 提取bytesstart字节开始的子字符串,如果指定了,并且在count字节之后停止,如果指定了的话。 - 至少提供startcount中的一个。 + 提取bytes的子字符串:若指定了起始位置,则从第start个字节开始;若指定了长度,则在提取count个字节后停止。startcount至少需要指定一个。 substring('\x1234567890'::bytea FROM 3 FOR 2) @@ -153,7 +205,7 @@ bytea - 删除bytesremoved中只包含字节的最长字符串,从bytes的开始、结束,或两端(BOTH 为默认的)。 + 从bytes的开头、结尾或两端(默认为BOTH)移除仅由bytesremoved中字节组成的最长字符串。 trim('\x9012'::bytea from '\x1234567890'::bytea) @@ -169,7 +221,7 @@ bytea - 这是trim()的非标准语法。 + 这是一个非标准的trim()语法。 trim(both from '\x1234567890'::bytea, '\x9012'::bytea) @@ -181,7 +233,7 @@
- 还有一些二进制串处理函数可以使用,在列出。 其中有一些是在内部使用,用于实现列出的 SQL 标准串函数。 + 还有一些二进制串处理函数可以使用,在列出。 其中有一些是在内部使用,用于实现列出的 SQL 标准串函数。 @@ -218,7 +270,7 @@ bigint - 返回二进制字符串中设置的位数(也被认为popcount)。 + 返回二进制字符串中被置位的位数(也称为popcount)。 bit_count('\x1234567890'::bytea) @@ -226,23 +278,41 @@ + + - btrim + crc32 - btrim ( bytes bytea, - bytesremoved bytea ) - bytea + crc32 ( bytea ) + bigint - 从bytes的开始和结束处删除只包含bytesremoved中出现的字节的最长字符串 + 计算二进制字符串的 CRC-32 值。 - btrim('\x1234567890'::bytea, '\x9012'::bytea) - \x345678 - - + crc32('abc'::bytea) + 891568578 + + + + + + + crc32c + + crc32c ( bytea ) + bigint + + + 计算二进制字符串的 CRC-32C 值。 + + + crc32c('abc'::bytea) + 910901175 + + @@ -254,7 +324,7 @@ integer - 从二进制字符串中提取 n'th 位。 + 从二进制字符串中提取 编号为 n 的 位。 get_bit('\x1234567890'::bytea, 30) @@ -272,7 +342,7 @@ integer - 从二进制字符串中提取 n'th 字节。 + 从二进制字符串中提取 编号为 n 的 字节。 get_byte('\x1234567890'::bytea, 4) @@ -286,13 +356,13 @@ length - binary string - length + 二进制串 + 长度 - length - 二进制字符串 - binary strings, length + 长度 + 二进制串 + 二进制串,长度 length ( bytea ) integer @@ -321,23 +391,7 @@ - - - - ltrim - - ltrim ( bytes bytea, - bytesremoved bytea ) - bytea - - - 从bytes开头移除出现在bytesremoved中的只包含字节的最长字符串。 - - - ltrim('\x1234567890'::bytea, '\x9012'::bytea) - \x34567890 - - + @@ -356,23 +410,24 @@ + + - - - rtrim - - rtrim ( bytes bytea, - bytesremoved bytea ) - bytea - - - 从bytes结尾移除出现在bytesremoved中的只包含字节的最长字符串。 - - - rtrim('\x1234567890'::bytea, '\x9012'::bytea) - \x12345678 - - + + + reverse + + reverse ( bytea ) + bytea + + + 反转二进制字符串中字节的顺序。 + + + reverse('\xabcd'::bytea) + \xcdab + + @@ -385,7 +440,7 @@ bytea - 设置二进制字符串中的n'th位为newvalue。 + 设置二进制字符串中的编号为 n 的位为newvalue set_bit('\x1234567890'::bytea, 30, 0) @@ -404,7 +459,7 @@ bytea - 设置二进制字符串中的 n'th 字节到 newvalue。 + 设置二进制字符串中的 编号为 n 的 字节到 newvalue set_byte('\x1234567890'::bytea, 4, 64) @@ -459,7 +514,7 @@ sha384('abc'::bytea) - \xcb00753f45a35e8bb5a03d699ac65007&zwsp;272c32ab0ed1631a8b605a43ff5bed&zwsp;8086072ba1e7cc2358baeca134c825a7 + \xcb00753f45a35e8bb5a03d699ac65007&zwsp;272c32ab0eded1631a8b605a43ff5bed&zwsp;8086072ba1e7cc2358baeca134c825a7 @@ -476,7 +531,7 @@ sha512('abc'::bytea) - \xddaf35a193617abacc417349ae204131&zwsp;12e6fa4e89a97ea20a9ee64b55d39a&zwsp;2192992a274fc1a836ba3c23a3feebbd&zwsp;454d4423643ce80e2a9ac94fa54ca49f + \xddaf35a193617abacc417349ae204131&zwsp;12e6fa4e89a97ea20a9eeee64b55d39a&zwsp;2192992a274fc1a836ba3c23a3feebbd&zwsp;454d4423643ce80e2a9ac94fa54ca49f @@ -489,8 +544,7 @@ bytea - 从start字节开始提取bytes的子字符串,并扩展为count字节,如果这是指定的。 - (与 substring(bytesstartcount) 相同.) + 提取bytes中从第start个字节开始的子字符串;若指定了长度,则提取count个字节。(与substring(bytes from start for count)相同。) substr('\x1234567890'::bytea, 3, 2) @@ -502,7 +556,7 @@
- 函数get_byteset_byte把一个二进制串中的一个字节计数为字节 0。 + 函数get_byteset_byte把二进制串中的第一个字节编号为字节 0。 函数get_bitset_bit在每一个字节中从右边起计数位; 例如位 0 是第一个字节的最低有效位,而位 15 是第二个字节的最高有效位。 @@ -510,16 +564,16 @@ 由于历史原因,函数md5返回的是一个十六进制编码的text值,而SHA-2函数返回类型bytea。 可以使用函数encodedecode在两者之间转换。 - 例如encode(sha256('abc'),'hex')可以得到一个十六进制编码的文本表示,或者decode(md5('abc'), 'hex')得到一个bytea 值。 + 例如encode(sha256('abc'), 'hex')可以得到一个十六进制编码的文本表示,或者decode(md5('abc'), 'hex')得到一个bytea 值。 - character string + 字符串 转换为二进制字符串 - binary string + 二进制串 转换为字符串 用于在不同字符集(编码)之间转换字符串的函数,以及用于以文本形式表示任意二进制数据的函数,在中显示。 @@ -528,7 +582,7 @@ - 文本/字符串转换函数 + 文本/二进制串转换函数 @@ -638,7 +692,7 @@ bytea - 从文本表示中解码二进制数据;支持的format值与encode相同。 + 从文本表示中解码二进制数据;支持的format值与encode相同。 decode('MTIzAAE=', 'base64') @@ -687,9 +741,9 @@ base64格式是RFC 2045第6.8节中描述的。根据RFC,编码行在76个字符处换行。 - 然而,与MIME CRLF换行符不同,结尾只使用换行符。 + 然而,与MIME CRLF换行符不同,行尾只使用一个换行符。 decode函数会忽略回车、换行、空格和制表符。 - 否则,当decode提供无效的base64数据时,包括尾部填充不正确时,会引发错误。 + 否则,当向decode传入无效的 base64 数据时,包括尾部填充不正确时,会引发错误。 @@ -716,8 +770,8 @@ - escape格式将零字节和高位设置的字节转换为八进制转义序列 - (\nnn),并将反斜杠加倍。 + escape格式将零字节和最高位被置位的字节转换为八进制转义序列 + (\nnn),并将反斜杠双写。 其他字节值会直接表示。如果反斜杠后面不是第二个反斜杠或三个八进制数字,则decode函数会引发错误; 它会接受其他字节值不变。 @@ -732,10 +786,10 @@ hex格式将每4位数据表示为一个十六进制数字,0f, - 先写入每个字节的高阶数字。 encode函数以小写输出a-f十六进制数字。 + 先写入每个字节的高位数字。 encode函数以小写输出a-f十六进制数字。 因为数据的最小单位是8位,所以encode总是返回偶数个字符。 decode函数接受a-f字符的大小写。 - 当decode提供无效的十六进制数据时,包括提供奇数个字符时,会引发错误。 + 当向decode传入无效的十六进制数据时,包括提供奇数个字符时,会引发错误。 @@ -743,8 +797,9 @@ - 另外,也可以在整数值和bytea之间进行类型转换。将整数转换为bytea时,会生成 2、4 或 8 个字节,具体取决于整数类型的宽度。 - 结果是该整数的二进制补码表示,最高有效字节在前。一些示例如下: + 此外,还可以在整数值与bytea类型之间进行类型转换。 + 将整数转换为bytea会产生 2、4 或 8 个字节,具体取决于整数类型的宽度。 + 结果是该整数的补码表示,最高有效字节在前。以下是一些示例: 1234::smallint::bytea \x04d2 cast(1234 AS bytea) \x000004d2 @@ -752,7 +807,7 @@ cast(-1234 AS bytea) \xfffffb2e '\x8000'::bytea::smallint -32768 '\x8000'::bytea::integer 32768 - 将bytea转换为整数时,如果bytea的长度超过该整数类型的宽度,就会引发错误。 + 将bytea转换为整数时,如果bytea的长度超过整数类型的宽度,则会引发错误。 diff --git a/zh/20/func/func-bitstring.sgml b/zh/20/func/func-bitstring.sgml index a780c6a3..d5d66f50 100644 --- a/zh/20/func/func-bitstring.sgml +++ b/zh/20/func/func-bitstring.sgml @@ -3,14 +3,14 @@ 位串函数和操作符 - bit strings - functions + 位串 + 函数 本节描述用于检查和操作位串的函数和操作符,也就是操作类型为bitbit varying的值的函数和操作符。 - (虽然这些表中只提到了bit类型,但bit varying类型的值可以互换使用。) - 位字符串支持中显示的常用比较操作符,就像中显示的操作符。 + (虽然这些表中只提到了bit类型,但bit varying类型的值可以互换使用。) + 位串支持中显示的常用比较操作符,以及中显示的操作符。
@@ -40,7 +40,7 @@ bit - 连接 + 串接 B'10001' || B'011' @@ -96,7 +96,7 @@ bit - 按位求反 + 按位非 ~ B'10001' @@ -136,12 +136,12 @@
- 一些可用于二进制字符串的函数也可用于位字符串,如中所示。 + 一些可用于二进制字符串的函数也可用于位串,如中所示。 - 位字符串函数 + 位串函数 @@ -169,7 +169,7 @@ bigint - 返回位字符串中设置的位数(也被视为popcount)。 + 返回位串中被置位的位数(也称为popcount)。 bit_count(B'10111') @@ -186,7 +186,7 @@ integer - 返回位字符串中的位数。 + 返回位串中的位数。 bit_length(B'10111') @@ -200,14 +200,14 @@ length - bit string - length + 位串 + 长度 length ( bit ) integer - 返回位字符串中的位数。 + 返回位串中的位数。 length(B'10111') @@ -224,7 +224,7 @@ integer - 返回位字符串中的字节数。 + 返回位串中的字节数。 octet_length(B'1011111011') @@ -241,8 +241,7 @@ bit - 替换从start位开始的bits的子字符串,并将newsubstring扩展count位。 - 如果count被省略,默认为newsubstring的长度。 + 用newsubstring替换bits中从第start位开始、长度为count位的子串。如果省略count,则默认为newsubstring的长度。 overlay(B'01010101010101010' PLACING B'11111' FROM 2 FOR 3) @@ -259,7 +258,7 @@ integer - 按返回指定substring的第一个起始索引,以bits为单位,如果不存在则返回0。 + 返回substringbits中首次出现的位置;如果不存在则返回零。 position(B'010' IN B'000001101011') @@ -276,8 +275,7 @@ bit - 如果指定了起始位,则提取从start位开始的bits的子字符串,如果指定了计数位,则在count位之后停止。 - startcount至少提供一个。 + 提取bits的子串:若指定了起始位置,则从第start位开始;若指定了长度,则在提取count位后停止。startcount至少需要指定一个。 substring(B'110010111111' FROM 3 FOR 2) @@ -295,7 +293,7 @@ integer - 从位字符串中提取第n位;第一个(最左)位为第0位。 + 从位串中提取编号为n的位;第一位(最左侧的位)编号为位 0。 get_bit(B'101010101010101010', 6) @@ -314,7 +312,7 @@ bit - 将位字符串中的第n位设置为newvalue;第一个(最左)位是第0位。 + 将位串中编号为n的位设置为newvalue;第一位(最左侧的位)编号为位 0。 set_bit(B'101010101010101010', 6, 0) @@ -325,16 +323,10 @@
- - 另外,我们可以在整数和bit之间来回转换。 - 将一个整数转换为bit(n)会复制最右边的n位。 - 将一个整数转换为比整数本身更宽的位字符串宽度将在左边进行符号扩展。一些示例: - + 此外,还可以在整数值与bit类型之间进行类型转换。将整数转换为bit(n)会复制最右侧的n位。将整数转换为宽度超过该整数自身位宽的位串时,会在左侧进行符号扩展。下面是一些示例: 44::bit(10) 0000101100 44::bit(3) 100 cast(-44 AS bit(12)) 111111010100 '1110'::bit(4)::integer 14 - - 请注意,如果只是转换为bit,意思是转换成bit(1),因此只会转换整数的最低有效位。 - +注意,仅转换为bit意味着转换为bit(1),因此只会得到该整数的最低有效位。 diff --git a/zh/20/func/func-comparison.sgml b/zh/20/func/func-comparison.sgml index 254f6087..f33684a4 100644 --- a/zh/20/func/func-comparison.sgml +++ b/zh/20/func/func-comparison.sgml @@ -3,8 +3,8 @@ 比较函数和操作符 - comparison - operators + 比较 + 操作符 @@ -87,14 +87,14 @@ - <> 表示 not equal 的标准的SQL符号。 - != 是一个别名, 在解析的早期阶段被转换为 <> 。 - 因此, 它不可能实现 !=<> 操作符以做不同的事情。 + <>不等于 的标准 SQL 符号。 + != 是一个别名,在解析的早期阶段就会被转换为 <>。 + 因此,不可能让 !=<> 操作符执行不同的操作。 - 这些比较操作符适用于所有具有自然排序的内置数据类型,包括数字、字符串和日期/时间类型。 + 这些比较操作符适用于所有具有自然排序的内置数据类型,包括数值、字符串和日期/时间类型。 此外,如果其组成数据类型具有可比性,则也可以比较数组、复合类型和范围。 @@ -140,7 +140,7 @@ boolean - 之间(包括范围端点)。 + 位于两者之间(包括范围端点)。 2 BETWEEN 1 AND 3 @@ -200,7 +200,7 @@ boolean - 不相等, 将空(null)视为可比值。 + 不相等,将 null 视为可比值。 1 IS DISTINCT FROM NULL @@ -218,7 +218,7 @@ boolean - 相等, 将空(null)视为可比值。 + 相等,将 null 视为可比值。 1 IS NOT DISTINCT FROM NULL @@ -236,7 +236,7 @@ boolean - 测试值是否为空。 + 测试值是否为 null。 1.5 IS NULL @@ -250,7 +250,7 @@ boolean - 测试值是否不为空。 + 测试值是否不为 null。 'null' IS NOT NULL @@ -264,7 +264,7 @@ boolean - 测试值是否为空(非标准语法)。 + 测试值是否为 null(非标准语法)。 @@ -274,7 +274,7 @@ boolean
- 测试值是否不为空(非标准语法)。 + 测试值是否不为 null(非标准语法)。 @@ -395,30 +395,22 @@ BETWEEN SYMMETRIC - - BETWEEN谓词可以简化范围测试: - + BETWEEN谓词可以简化范围测试: a BETWEEN x AND y - - 等效于 - +等价于 a >= x AND a <= y - - 注意BETWEEN认为终点值是包含在范围内的。 - BETWEEN SYMMETRIC 就像BETWEEN,除了没有要求AND的左边的参数小于或等于右边的参数。 - 如果不是的话,这两个参数将自动交换,因此总是隐含一个非空范围。 -
+注意,BETWEEN将两个端点值都视为包含在范围内。BETWEEN SYMMETRIC类似于BETWEEN,但不要求AND左侧的参数小于或等于右侧的参数。如果不是这样,这两个参数会自动交换,以确保表示的范围始终非空。
- BETWEEN的各种变量都是以普通比较操作符的方式实现的,因此适用于任何可以比较的数据类型。 + BETWEEN的各种变体都是以普通比较操作符的方式实现的,因此适用于任何可以比较的数据类型。 - 在BETWEEN语法中使用AND会与使用AND作为逻辑操作符产生歧义。 - 为了解决这个问题,只允许有限的一组表达类型作为BETWEEN子句的第二个参数。 - 如果您需要在BETWEEN中写一个更复杂的子表达式,在子表达式两边写上圆括号。 + 在BETWEEN语法中使用AND,会与将AND用作逻辑操作符产生歧义。 + 为了解决这个问题,只允许有限的一组表达式类型作为BETWEEN子句的第二个参数。 + 如果你需要在BETWEEN中写一个更复杂的子表达式,请在该子表达式两边加上圆括号。 @@ -429,12 +421,12 @@ IS NOT DISTINCT FROM - 当有一个输入为空时,普通的比较操作符会得到空(表示未知),而不是真或假。例如,7 = NULL得到空,7 <> NULL也一样。如果这种行为不合适,可以使用IS NOT DISTINCT FROM谓词: + 当任一输入为 null 时,普通的比较操作符会得到 null(表示未知),而不是真或假。例如,7 = NULL得到 null,7 <> NULL也一样。如果这种行为不合适,可以使用IS NOT DISTINCT FROM谓词: a IS DISTINCT FROM b a IS NOT DISTINCT FROM b - 对于非空输入,IS DISTINCT FROM<>操作符一样。不过,如果两个输入都为空,它会返回假。而如果只有一个输入为空,它会返回真。类似地,IS NOT DISTINCT FROM对于非空输入的行为与=相同,但是当两个输入都为空时它返回真,并且当只有一个输入为空时返回假。因此,这些谓词实际上把空值当作一种普通数据值,而不是未知。 + 对于非 null 输入,IS DISTINCT FROM<>操作符一样。不过,如果两个输入都为 null,它会返回假。而如果只有一个输入为 null,它会返回真。类似地,IS NOT DISTINCT FROM对于非 null 输入的行为与=相同,但是当两个输入都为 null 时它返回真,并且当只有一个输入为 null 时返回假。因此,这些谓词实际上把 null 当作一种普通数据值,而不是未知 @@ -450,17 +442,17 @@ NOTNULL - 要检查一个值是否为空,使用下面的谓词: + 要检查一个值是否为 null,使用下面的谓词: expression IS NULL expression IS NOT NULL - 或者等效,但并不标准的谓词: + 或者等效但非标准的谓词: expression ISNULL expression NOTNULL - null valuecomparing + 空值比较 @@ -470,7 +462,7 @@ - 有些应用可能要求表达式expression = NULLexpression得出空值时返回真。我们强烈建议这样的应用修改成遵循 SQL 标准。但是,如果这样修改不可能完成,那么我们可以使用配置变量。如果打开它,PostgreSQL将把x = NULL子句转换成x IS NULL。 + 有些应用可能期望表达式expression = NULLexpression求值为 null 时返回真。我们强烈建议此类应用修改为遵循 SQL 标准。但是,如果无法这样修改,那么可以使用配置变量。如果将其打开,PostgreSQL会把x = NULL子句转换成x IS NULL @@ -480,11 +472,11 @@ SELECT ROW(1,2.5,'this is a test') = ROW(1, 3, 'not the same'); -SELECT ROW(table.*) IS NULL FROM table; -- detect all-null rows +SELECT ROW(table.*) IS NULL FROM table; -- 检测所有字段均为 null 的行 -SELECT ROW(table.*) IS NOT NULL FROM table; -- detect all-non-null rows +SELECT ROW(table.*) IS NOT NULL FROM table; -- 检测所有字段均非 null 的行 -SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in rows +SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- 检测至少有一个 null 字段的行 在某些情况下,写成row IS DISTINCT FROM NULL或者row IS NOT DISTINCT FROM NULL可能更合适,因为它们只会检查整个行值是否为 null,而不会再对行字段做额外测试。 @@ -518,7 +510,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in boolean_expression IS UNKNOWN boolean_expression IS NOT UNKNOWN - 这些谓词将总是返回真或假,从来不返回空值,即使操作数是空也如此。空值输入被当做逻辑值未知。 请注意实际上IS UNKNOWNIS NOT UNKNOWN分别与IS NULLIS NOT NULL相同, 只是输入表达式必须是布尔类型。 + 这些谓词总是返回真或假,从不返回空值,即使操作数为 null 也是如此。null 输入被当作逻辑值未知。请注意,IS UNKNOWNIS NOT UNKNOWN实际上分别等同于IS NULLIS NOT NULL,只是输入表达式必须是布尔类型。 @@ -576,7 +568,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in integer - 返回非空参数的数量。 + 返回非 null 参数的数量。 num_nonnulls(1, NULL, 2) @@ -593,7 +585,7 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in integer - 返回空参数的数量。 + 返回 null 参数的数量。 num_nulls(1, NULL, 2) diff --git a/zh/20/func/func-comparisons.sgml b/zh/20/func/func-comparisons.sgml index 3c4b2a32..394b8d1b 100644 --- a/zh/20/func/func-comparisons.sgml +++ b/zh/20/func/func-comparisons.sgml @@ -28,12 +28,12 @@ - 逐行比较 + 行比较 比较 - 逐行 + 复合类型 @@ -50,7 +50,7 @@ - 本节描述几个特殊的结构,用于在值的组之间进行多重比较。这些形式语法上和前面一节的子查询形式相关,但是不涉及子查询。 这种形式涉及的数组子表达式是PostgreSQL的扩展; 其它的是SQL兼容的。所有本节记录的表达式形式都返回布尔(Boolean)结果(真/假)。 + 本节描述几个特殊的结构,用于在值的组之间进行多重比较。这些形式语法上和前面一节的子查询形式相关,但是不涉及子查询。 涉及数组子表达式的形式是PostgreSQL的扩展; 其余形式是SQL兼容的。本节介绍的所有表达式形式都返回布尔(Boolean)结果(真/假)。 @@ -61,14 +61,12 @@ - 右侧是一个用括号括起来的表达式列表。如果左侧表达式的结果等于右侧任何一个表达式的结果,则结果为true。 - 这是一个简写表示法,如下所示: - + 右侧是一个用圆括号括起来的表达式列表。如果左侧表达式的结果等于右侧任一表达式的结果,则结果为。这等价于以下写法: expression = value1 -或 +OR expression = value2 -或 +OR ... @@ -86,9 +84,7 @@ - 右侧是一个用括号括起来的表达式列表。如果左侧表达式的结果与所有右侧表达式都不相等,则结果为true。 - 这是一个简写表示法,用于 - + 右侧是一个用圆括号括起来的表达式列表。如果左侧表达式的结果与右侧所有表达式的结果都不相等,则结果为。这等价于以下写法: expression <> value1 AND @@ -112,7 +108,7 @@ AND - <literal>ANY</literal>/<literal>SOME</literal> (array) + <literal>ANY</literal>/<literal>SOME</literal>(数组) expression operator ANY (array expression) @@ -134,7 +130,7 @@ AND - <literal>ALL</literal> (array) + <literal>ALL</literal>(数组) expression operator ALL (array expression) @@ -158,20 +154,7 @@ AND - 每一边都是一个行构造器, - 如在中描述的那样。 - 这两个行构造器必须具有相同数量的字段。 - 给定的operator应用于每一对 - 对应的字段。(由于字段可能是不同类型的,这意味着每对可能选择不同的具体操作符。) - 所有选定的操作符必须是某个B-树操作符类的成员,或者是B-树操作符类的=成员的否定形式, - 这意味着只有当operator是 - =、 - <>、 - <、 - <=、 - >或 - >=时才可能进行行构造器比较, - 或者具有类似于这些操作符的语义。 + 两侧都是行构造器,如所述。两个行构造器必须具有相同数量的字段。给定的operator应用于每一对对应字段。(由于字段可能具有不同的类型,因此可能为各对字段选择不同的具体操作符。)所选操作符必须是某个 B-树操作符类的成员,或者是 B-树操作符类中=成员的否定操作符。这意味着只有当operator=<><<=>>=,或具有与这些操作符类似的语义时,才可以进行行构造器比较。 @@ -182,12 +165,7 @@ AND 对于<<=>>=这几种情况,会从左到右比较各行元素,一旦找到一对不相等或含有 null 的元素就立即停止。如果这对元素中的任意一个为 null,那么行比较的结果就是未知(null);否则,这对元素的比较结果决定整个行比较的结果。例如,ROW(1,2,NULL) < ROW(1,3,0)的结果为真,而不是 null,因为第三对元素并不会被考虑。 - - - 在PostgreSQL 8.2 之前,<<=>>=这几种情况并不是按照 SQL 规范处理的。像ROW(a,b) < ROW(c,d)这样的比较会被实现为a < c AND b < d,而正确行为应当等价于a < c OR (a = c AND b < d)。 - - row_constructor IS DISTINCT FROM row_constructor @@ -216,21 +194,21 @@ AND - SQL 规范要求在结果依赖于比较两个 NULL 值或者一个 NULL 与一个非 NULL 时逐行比较返回 NULL。 + SQL 规范要求在结果依赖于比较两个 NULL 值或者一个 NULL 与一个非 NULL 时行比较返回 NULL。 PostgreSQL只有在比较两个行构造器(如)的结果或者比较一个行构造器与一个子查询的输出时才这样做(如中所述)。 - 在其他比较两个复合类型值的环境中,两个 NULL 域值被认为相等,并且一个 NULL 被认为大于一个非 NULL。 + 在其他比较两个复合类型值的环境中,两个 NULL 字段值被认为相等,并且一个 NULL 被认为大于一个非 NULL。 为了得到复合类型的一致的排序和索引行为,这样做是必要的。 - 每一边都会被计算并且它们会被逐行比较。当operator是 + 对两侧分别求值后,按行进行比较。当operator=<><<=>或者 - >=时或者具有与这些类似的语义时,允许复合类型的比较(更准确地说,如果一个操作符是一个 B-树操作符类的成员,或者是一个 B-树操作符类的=成员的否定词,它就可以是一个行比较操作符)。 - 上述操作符的行为与用于行构造器(见)的IS [ NOT ] DISTINCT FROM相同。 + >=时或者具有与这些类似的语义时,允许复合类型的比较(更准确地说,如果一个操作符是一个 B-树操作符类的成员,或者是一个 B-树操作符类的=成员的否定操作符,它就可以是一个行比较操作符)。 + 上述操作符的默认行为与用于行构造器(见)的IS [ NOT ] DISTINCT FROM相同。 @@ -241,9 +219,9 @@ AND *<=*>以及 *>=。 - 这些操作符比较两行的内部二进制表达。即使两行用相等操作符的比较为真,两行也可能具有不同的二进制表达。 - 行在这些比较操作符之下的排序是决定性的,其他倒没什么意义。 - 这些操作符在内部被用于物化视图并且可能对其他如复制和B-树复制(参见 )之类的特殊功能有用,但是它们并不打算用在书写查询这类普通用途中。 + 这些操作符比较两行的内部二进制表示。即使两行用相等操作符的比较为真,两行也可能具有不同的二进制表示。 + 使用这些比较操作符得到的行排序是确定的,但除此之外没有其他意义。 + 这些操作符在内部被用于物化视图并且可能对其他如复制和 B-树去重(参见 )之类的特殊功能有用,但是它们并不打算用在书写查询这类普通用途中。 diff --git a/zh/20/func/func-conditional.sgml b/zh/20/func/func-conditional.sgml index 7f002204..d1ee6946 100644 --- a/zh/20/func/func-conditional.sgml +++ b/zh/20/func/func-conditional.sgml @@ -41,7 +41,7 @@ CASE WHEN condition THEN result - CASE子句可以用于任何表达式可以出现的地方。每一个condition是一个返回boolean结果的表达式。如果结果为真,那么CASE表达式的结果就是符合条件的result,并且剩下的CASE表达式不会被处理。如果条件的结果不为真,那么以相同方式搜寻任何随后的WHEN子句。如果没有WHEN condition为真,那么CASE表达式的值就是在ELSE子句里的result。如果省略了ELSE子句而且没有条件为真,结果为空。 + CASE子句可以用于任何表达式可以出现的地方。每一个condition是一个返回boolean结果的表达式。如果结果为真,那么CASE表达式的结果就是紧随该条件后的result,并且剩下的CASE表达式不会被处理。如果条件的结果不为真,那么以相同方式搜寻任何随后的WHEN子句。如果没有WHEN condition为真,那么CASE表达式的值就是在ELSE子句里的result。如果省略了ELSE子句而且没有条件为真,结果为 null。 @@ -85,7 +85,7 @@ CASE expression END - 第一个expression会被计算,然后与所有在WHEN子句中的每一个value对比,直到找到一个相等的。如果没有找到匹配的,则返回在ELSE子句中的result(或者控制)。 这类似于 C 里的switch语句。 + 第一个expression会被计算,然后与所有在WHEN子句中的每一个value对比,直到找到一个相等的。如果没有找到匹配的,则返回在ELSE子句中的result(或者 null 值)。 这类似于 C 里的switch语句。 @@ -116,11 +116,7 @@ SELECT ... WHERE CASE WHEN x <> 0 THEN y/x > 1.5 ELSE false END; - 如中所述,在有几种情况中一个表达式的子表达式 - 会被计算多次,因此CASE只计算必要的表达式这 - 一原则并非不可打破。例如一个常量子表达式1/0通常将会在规划时导致一次 - 除零错误,即便它位于一个执行时永远也不会进入的CASE分支时也是 - 如此。 + 如所述,在多种情况下,表达式中的子表达式会在不同阶段求值,因此CASE只计算必要的子表达式这一原则并非绝对成立。例如,常量子表达式1/0通常会在规划时导致除零错误,即便它位于一个运行时永远不会进入的CASE分支中也是如此。 @@ -145,19 +141,19 @@ SELECT ... WHERE CASE WHEN x <> 0 THEN y/x > 1.5 ELSE false END; - COALESCE函数返回它的第一个非空参数的值。当且仅当所有参数都为空时才会返回空。它常用于在为显示目的检索数据时用缺省值替换空值。例如: + COALESCE函数返回参数中第一个不为 null 的值。只有所有参数都为 null 时,才返回 null。它常用于在检索数据以供显示时,用默认值替换 null 值。例如: SELECT COALESCE(description, short_description, '(none)') ... - 如果description不为空,这将会返回它的值,否则如果short_description非空则返回short_description的值,如果前两个都为空则返回(none)。 + 此表达式返回description,前提是它不为 null,否则返回short_description,前提是它不为 null,否则返回(none) - 所有参数都必须转换为一个公共数据类型,它将是结果的类型 (详情参见 )。 + 所有参数都必须能转换为同一个数据类型,它将是结果的类型(详情参见)。 - 和CASE表达式一样,COALESCE将不会 计算无助于判断结果的参数;也就是说,在第一个非空参数右边的参数不会被计算。这个 SQL 标准函数提供了类似于NVLIFNULL的能力,它们被用在某些其他数据库系统中。 + 和CASE表达式一样,COALESCE只计算确定结果所需的参数;也就是说,在第一个不为 null 的参数右边的参数不会被计算。这个 SQL 标准函数提供了类似于NVLIFNULL的能力,它们被用在某些其他数据库系统中。 @@ -173,12 +169,12 @@ SELECT COALESCE(description, short_description, '(none)') ... - 当value1value2相等时,NULLIF返回一个空值。 + 当value1value2相等时,NULLIF返回 null。 否则它返回value1。 这些可以用于执行前文给出的COALESCE示例的逆操作: SELECT NULLIF(value, '(none)') ... - 在这个示例中,如果value(none),将返回空值,否则返回value的值。 + 在这个示例中,如果value(none),将返回 null,否则返回value的值。 @@ -213,11 +209,11 @@ SELECT NULLIF(value, '(none)') ... - GREATESTLEAST函数从一个任意的数字表达式列表里选取最大或者最小的数值。 这些表达式必须都可以转换成一个普通的数据类型,它将会是结果类型 (参阅获取细节)。列表中的 NULL 数值将被忽略。只有所有表达式的结果都是 NULL 的时候,结果才会是 NULL。 + GREATESTLEAST函数从由任意数量的表达式组成的列表中选取最大值或最小值。这些表达式都必须能转换为同一个数据类型,该类型将作为结果类型(详情参见)。 - 请注意GREATESTLEAST都不是 SQL 标准,但却是很常见的扩展。某些其他数据库让它们在任何参数为 NULL 时返回 NULL,而不是在所有参数都为 NULL 时才返回 NULL。 + 参数列表中的 NULL 值会被忽略。只有所有表达式的求值结果都为 NULL 时,结果才为 NULL。(这与 SQL 标准不同。按照标准,只要有任意参数为 NULL,返回值就为 NULL。一些其他数据库采用这种行为。) diff --git a/zh/20/func/func-datetime.sgml b/zh/20/func/func-datetime.sgml index 610241fd..e65d6c71 100644 --- a/zh/20/func/func-datetime.sgml +++ b/zh/20/func/func-datetime.sgml @@ -1,9 +1,9 @@ - 时间/日期函数和操作符 + 日期/时间函数和操作符 - 展示了可用于处理日期/时间值的函数,其细节在随后的小节中描述。演示了基本算术操作符 (+*等)的行为。 而与格式化相关的函数,可以参考。你应该很熟悉中的日期/时间数据类型的背景知识。 + 展示了可用于处理日期/时间值的函数,其细节在随后的小节中描述。演示了基本算术操作符 (+*等)的行为。 而与格式化相关的函数,可以参考。你应当熟悉中的日期/时间数据类型的背景知识。 @@ -89,7 +89,7 @@ interval - 添加时间间隔 + 将两个时间间隔相加 interval '1 day' + interval '1 hour' @@ -131,7 +131,7 @@ interval - 取否一个时间间隔 + 对时间间隔取负 - interval '23 hours' @@ -145,7 +145,7 @@ integer - 减去日期,生成经过的天数 + 将两个日期相减,得到相隔的天数 date '2001-10-01' - date '2001-09-28' @@ -187,7 +187,7 @@ interval - 减去时间 + 将两个时间相减 time '05:00' - time '03:00' @@ -229,7 +229,7 @@ interval - 减去时间间隔 + 将两个时间间隔相减 interval '1 day' - interval '1 hour' @@ -243,12 +243,12 @@ interval - 减去时间戳(将24小时间隔转换为天数,类似于justify_hours() - 时间戳 '2001-09-29 03:00' - 时间戳 '2001-07-27 12:00' - 63 天 15:00:00 + timestamp '2001-09-29 03:00' - timestamp '2001-07-27 12:00' + 63 days 15:00:00 @@ -258,7 +258,7 @@ interval - 将时间间隔乘以数量 + 将时间间隔乘以一个标量 interval '1 second' * 900 @@ -280,7 +280,7 @@ interval - 用时间间隔除以数量 + 将时间间隔除以一个标量 interval '1 hour' / 1.5 @@ -321,7 +321,7 @@ interval - 减去参数,生成一个使用年和月,而不是只用日的符号化的结果 + 将两个参数相减,生成一个使用年和月,而不是只用日的符号化的结果 age(timestamp '2001-04-10', timestamp '1957-06-13') @@ -335,7 +335,7 @@ interval - 从 current_date 减去参数(在午夜) + 从current_date(午夜时刻)减去参数 age(timestamp '1957-06-13') @@ -386,7 +386,7 @@ time with time zone - 一天中的当前时间;参见 + 一天中的当前时刻;参见 current_time @@ -400,7 +400,7 @@ time with time zone - 一天中的当前时间;有限精度;参见 + 一天中的当前时刻,精度受限;参见 current_time(2) @@ -417,7 +417,7 @@ timestamp with time zone - 当前日期和时间 (当前事务的开始);参见 + 当前日期和时间(当前事务开始时);参见 current_timestamp @@ -431,7 +431,7 @@ timestamp with time zone - 当前日期和时间 (当前事务的开始);有限精度;参见 + 当前日期和时间(当前事务开始时),精度受限;参见 current_timestamp(0) @@ -479,7 +479,7 @@ double precision - 获取时间戳字段 (等同于 extract);参见 + 获取时间戳子字段 (等同于 extract);参见 date_part('hour', timestamp '2001-02-16 20:38:40') @@ -603,7 +603,7 @@ boolean - 测试有限日期(不是+/-无限) + 测试日期是否有限(不是正负无穷) isfinite(date '2001-02-16') @@ -617,7 +617,7 @@ boolean - 测试有限时间戳(不是+/-无限) + 测试时间戳是否有限(不是正负无穷) isfinite(timestamp 'infinity') @@ -631,7 +631,7 @@ boolean - 测试有限时间间隔 (当前总是为真) + 测试时间间隔是否有限(不是正负无穷) isfinite(interval '4 hours') @@ -684,7 +684,7 @@ interval - 使用 justify_daysjustify_hours调整时间间隔; 通过额外的符号调整 + 使用 justify_daysjustify_hours调整时间间隔,并额外调整符号 justify_interval(interval '1 mon -1 hour') @@ -701,7 +701,7 @@ time - 一天中当前时间;参见 + 一天中的当前时刻;参见 localtime @@ -715,7 +715,7 @@ time - 一天中的当前时间,有限精度;参见 + 一天中的当前时刻,精度受限;参见 localtime(0) @@ -732,7 +732,7 @@ timestamp - 当前日期和时间(当前事务的开始);参见 + 当前日期和时间(当前事务开始时);参见 localtimestamp @@ -746,7 +746,7 @@ timestamp - 当前日期和时间(当前事务的开始);有限精度;参见 + 当前日期和时间(当前事务开始时),精度受限;参见 localtimestamp(2) @@ -874,7 +874,7 @@ timestamp with time zone - 当前日期和时间(当前事务的开始);参见 + 当前日期和时间(当前事务开始时);参见 now() @@ -923,7 +923,7 @@ timestamp with time zone - 当前日期和时间(当前语句的开始);参见 + 当前日期和时间(当前语句开始时);参见 statement_timestamp() @@ -958,7 +958,7 @@ timestamp with time zone - 当前日期和时间(当前事务的开始);参见 + 当前日期和时间(当前事务开始时);参见 transaction_timestamp() @@ -975,7 +975,7 @@ timestamp with time zone - 将Unix纪元转换为带时区的时间戳(从1970-01-01 00:00:00+00开始的秒) + 将 Unix 纪元时间(自 1970-01-01 00:00:00+00 起的秒数)转换为带时区的时间戳 to_timestamp(1284352323) @@ -995,7 +995,7 @@ (start1, end1) OVERLAPS (start2, end2) (start1, length1) OVERLAPS (start2, length2) - 这个表达式在两个时间域(用它们的端点定义)重叠的时候得到真,当它们不重叠时得到假。端点可以用一对日期、时间或者时间戳来指定;或者是用一个后面跟着一个间隔的日期、时间或时间戳来指定。当一对值被提供时,起点或终点都可以被写在前面,OVERLAPS会自动地把较早的值作为起点。每一个时间段被认为是表示半开的间隔start <= time < end,除非startend相等,这种情况下它表示单个时间实例。例如这表示两个只有一个共同端点的时间段不重叠。 + 这个表达式在两个时间段(用它们的端点定义)重叠的时候得到真,当它们不重叠时得到假。端点可以用一对日期、时间或者时间戳来指定;或者是用一个后面跟着一个间隔的日期、时间或时间戳来指定。当一对值被提供时,起点或终点都可以被写在前面,OVERLAPS会自动地把较早的值作为起点。每一个时间段被认为是表示半开区间start <= time < end,除非startend相等,这种情况下它表示单个时刻。例如这表示两个只有一个共同端点的时间段不重叠。 @@ -1014,16 +1014,19 @@ SELECT (DATE '2001-10-30', DATE '2001-10-30') OVERLAPS - 当把一个interval值添加到timestamp with time zone上(或从中减去)时,天这一部分会按照指定的天数增减该timestamp with time zone的日期,同时保持一天中的时间不变。 - 对于跨越夏令时变更的情况(当会话时区被设置为能够识别 DST 的时区时),这意味着interval '1 day'并不一定等于interval '24 hours'。 - 例如,当会话的时区设置为America/Denver时: + 当把一个interval值加到timestamptimestamp with time zone值上(或从中减去一个interval值)时,会依次处理interval值的月、日和微秒字段。 + 首先,非零的月字段会按指定月数增减时间戳的日期,同时保持其在月份中的日不变;如果该日超出了新月份的月末,则使用该月的最后一天。(例如,3 月 31 日加 1 个月得到 4 月 30 日,加 2 个月则得到 5 月 31 日。) + 然后,日字段会按指定天数增减时间戳的日期。在这两个步骤中,一天中的本地时刻保持不变。最后,如果微秒字段不为零,则直接加上或减去该值。 + 在识别夏令时的时区中对timestamp with time zone值进行运算时,这意味着加上或减去(例如)interval '1 day'与加上或减去interval '24 + hours'的结果不一定相同。 + 例如,当会话时区设为America/Denver时: SELECT timestamp with time zone '2005-04-02 12:00:00-07' + interval '1 day'; 结果:2005-04-03 12:00:00-06 SELECT timestamp with time zone '2005-04-02 12:00:00-07' + interval '24 hours'; 结果:2005-04-03 13:00:00-06 - - 发生这种情况是因为在America/Denver时区,夏令时在2005-04-03 02:00:00发生切换,导致跳过了一个小时。 + + 发生这种情况是因为在2005-04-03 02:00:00America/Denver时区切换了夏令时,跳过了一个小时。 @@ -1031,15 +1034,9 @@ SELECT timestamp with time zone '2005-04-02 12:00:00-07' + interval '24 hours'; - 日期和时间戳的减法也可能会很复杂。执行减法的一种概念上很简单的方法是,使用 - EXTRACT(EPOCH FROM ...)把每个值都转换成秒数,然后执行减法, - 这样会得到两个值之间的数。这种方法将会适应每个月中天数、 - 时区改变和夏令时调整。使用-操作符的日期或时间 - 戳减法会返回值之间的天数(24小时)以及时/分/秒,也会做同样的调整。 - age函数会返回年、月、日以及时/分/秒,执行按域的减法,然后对 - 负值域进行调整。下面的查询展示了这些方法的不同。示例中的结果由 - timezone = 'US/Eastern'产生,这使得两个使用的日期之间存在着夏令 - 时的变化: + 日期和时间戳的减法也可能很复杂。一种概念上简单的方法是,先用EXTRACT(EPOCH FROM ...)将各值转换为秒数,然后将结果相减;这样得到的是两个值之间的数。这种方法会针对每个月的天数、时区变化和夏令时变化进行调整。 + 用-操作符将日期或时间戳值相减,会返回两个值之间的天数(每一天为 24 小时)和时/分/秒,也会作相同的调整。age函数返回年、月、日和时/分/秒,它会逐字段相减,然后调整负值字段。 + 以下查询显示了这些方法的差异。示例结果在timezone = 'US/Eastern'设置下产生;所用的两个日期之间发生了夏令时切换: @@ -1091,7 +1088,7 @@ EXTRACT(field FROM source) - 这个世纪;对于interval值,年份字段除以100 + 世纪;对于interval值,年份字段除以100 @@ -1114,7 +1111,7 @@ SELECT EXTRACT(CENTURY FROM INTERVAL '2001 years'); - 月份的日期(1–31);对于interval值,表示天数 + 一个月中的第几天(1–31);对于interval值,表示天数 @@ -1167,7 +1164,7 @@ SELECT EXTRACT(DOW FROM TIMESTAMP '2001-02-16 20:38:40'); - 一年中的日子(1-365/366) + 一年中的第几天(1–365/366) @@ -1182,7 +1179,7 @@ SELECT EXTRACT(DOY FROM TIMESTAMP '2001-02-16 20:38:40'); - 对于timestamp with time zone值,自1970-01-01 00:00:00 UTC以来的秒数(负值表示该时间戳之前的时间); + 对于timestamp with time zone值,自1970-01-01 00:00:00 UTC以来的秒数(早于该时刻的时间戳对应负值); 对于datetimestamp值,自1970-01-01 00:00:00以来的名义秒数,不考虑时区或夏令时规则; 对于interval值,间隔中的总秒数 @@ -1206,8 +1203,8 @@ SELECT to_timestamp(982384720.12); - 注意,将to_timestamp应用于从datetimestamp值中提取的时代可能会产生误导性的结果: - 结果将有效地假定原始值是以UTC时间给出的,这可能并非事实。 + 注意,将to_timestamp应用于从datetimestamp值中提取的 epoch 值可能会产生误导性的结果: + 结果实际上会假定原始值是以UTC时间给出的,这可能并非事实。
@@ -1263,8 +1260,7 @@ SELECT EXTRACT(ISOYEAR FROM DATE '2006-01-02'); - 每个ISO 8601周编号年从包含1月4日的星期一开始,因此在一月初或十二月底,ISO年可能与格里高利年不同。 - 有关更多信息,请参见week字段。 + 每个 ISO 8601 周编号年都从包含 1 月 4 日的那一周的星期一开始,因此在 1 月初或 12 月末,ISO 年可能与格里高利年不同。更多信息请参见 week 字段。 @@ -1307,7 +1303,7 @@ SELECT EXTRACT(MICROSECONDS FROM TIME '17:12:28.5'); - 千年; 对于interval值,年份字段除以1000 + 千年; 对于interval值,年份字段除以1000 @@ -1318,7 +1314,7 @@ SELECT EXTRACT(MILLENNIUM FROM INTERVAL '2001 years'); - 20世纪的年份在第二个千年。第三个千年从2001年1月1日开始。 + 1900 年代的年份属于第二个千年。第三个千年始于 2001 年 1 月 1 日。 @@ -1328,7 +1324,7 @@ SELECT EXTRACT(MILLENNIUM FROM INTERVAL '2001 years'); - 第二个字段,包括小数部分,乘以1000。请注意,这包括完整的秒数。 + 秒字段,包括小数部分,乘以1000。请注意,这包括完整的秒数。 @@ -1358,7 +1354,7 @@ SELECT EXTRACT(MINUTE FROM TIMESTAMP '2001-02-16 20:38:40'); - 月份在一年中的编号(1-12);对于interval值,月份模12的余数(0-11) + 月份在一年中的编号(1–12);对于interval值,月份模12的余数(0–11) @@ -1377,12 +1373,14 @@ SELECT EXTRACT(MONTH FROM INTERVAL '2 years 13 months'); - 日期所在的年份季度(1-4) + 日期所在的年份季度(1–4);对于interval值,为月份字段除以 3 加 1 SELECT EXTRACT(QUARTER FROM TIMESTAMP '2001-02-16 20:38:40'); 结果:1 +SELECT EXTRACT(QUARTER FROM INTERVAL '1 year 6 months'); +结果:3 @@ -1419,7 +1417,7 @@ SELECT EXTRACT(SECOND FROM TIME '17:12:28.5'); - 时间区偏移的小时组件 + 时区偏移的小时部分 @@ -1429,7 +1427,7 @@ SELECT EXTRACT(SECOND FROM TIME '17:12:28.5'); - 时间区偏移的分钟组件 + 时区偏移的分钟部分 @@ -1439,21 +1437,22 @@ SELECT EXTRACT(SECOND FROM TIME '17:12:28.5'); - 一年中ISO 8601周编号周的数量。根据定义,ISO周从周一开始, - 一年的第一周包含该年的1月4日。换句话说,一年的第一个星期四在该年的第1周。 + 一年中按ISO 8601 周编号体系计算的周序号。根据定义,ISO 周从周一开始,一年的第一周包含该年的 1 月 4 日。换句话说,一年的第一个星期四在该年的第 1 周。 + + + + 在 ISO 周编号体系中,1 月初的日期可能属于前一年的第 52 周或第 53 周,而 12 月末的日期可能属于下一年的第一周。例如,2005-01-01属于 2004 年的第 53 周,2006-01-01属于 2005 年的第 52 周,而2012-12-31属于 2013 年的第一周。建议将isoyear字段与week一起使用,以获得一致的结果。 - 在ISO周编号系统中,早年1月的日期可能属于前一年的第52周或第53周,而 - 晚年12月的日期可能属于下一年的第一周。例如,2005-01-01 - 属于2004年的第53周,2006-01-01 属于2005年的第52周, - 而2012-12-31 属于2013年的第一周。建议同时使用 - isoyear 字段和week以获得一致的结果。 + 对于interval值,week 字段就是整天数除以 7 的结果。 SELECT EXTRACT(WEEK FROM TIMESTAMP '2001-02-16 20:38:40'); 结果:7 +SELECT EXTRACT(WEEK FROM INTERVAL '13 days 24 hours'); +结果:1 @@ -1463,7 +1462,7 @@ SELECT EXTRACT(WEEK FROM TIMESTAMP '2001-02-16 20:38:40'); - 年份字段。请记住,没有0 AD,所以要小心地从AD年中减去BC年。 + 年份字段。请记住,没有0 AD,所以把BC年份从AD年份中减去时需要小心。 @@ -1490,7 +1489,8 @@ SELECT EXTRACT(MINUTES FROM INTERVAL '80 minutes'); - 当输入值为 +/-Infinity 时,extract对于单调增的域(epochjulianyearisoyeardecadecentury以及millennium)返回 +/-Infinity。对于其他域返回 NULL。PostgreSQL 9.6 之前的版本对所有输入无穷的情况都返回零。 + 当输入值为 +/-Infinity 时,extract对单调递增的字段返回 +/-Infinity(对于timestamp输入,这些字段为epochjulianyearisoyeardecadecenturymillennium;对于interval输入,这些字段为epochhourdayyeardecadecenturymillennium)。 + 对于其他字段,返回 NULL。PostgreSQL 9.6 之前的版本对所有无穷输入都返回零。 @@ -1499,15 +1499,12 @@ SELECT EXTRACT(MINUTES FROM INTERVAL '80 minutes'); - 在传统的Ingres上建模的date_part函数等价于SQL标准函数extract: + date_part函数仿照传统的Ingres实现,后者对应SQL标准的extract函数: date_part('field', source) - 请注意这里的field参数必须是一个串值,而不是一个名字。 - 有效的date_part域名 和extract相同。 - 由于历史原因,date_part函数返回double precision类型的值。 - 这可能导致在某些使用中损失精度。 - 建议使用extract替代。 + 注意,此处的field参数必须是字符串值,而不能是名称。date_part的有效字段名与extract相同。 + 由于历史原因,date_part函数返回double precision类型的值,可能在某些用途中损失精度。建议改用extract @@ -1534,11 +1531,12 @@ SELECT date_part('hour', INTERVAL '4 hours 3 minutes'); date_trunc(field, source [, time_zone ]) - source是类型timestampinterval的值表达式(类型datetime的值都分别被自动转换成timestamp, timestamp with time zone,或者interval)。field选择对输入值选用什么样的精度进行截断。返回的值是timestamp, timestamp with time zone,类型或者所有小于选定的 精度的域都设置为零(或者一,对于日期和月份)的interval。 + sourcetimestamptimestamp with time zoneinterval类型的值表达式。(datetime类型的值会分别自动转换为timestampinterval。) + field选择输入值的截断精度。返回值同样为timestamptimestamp with time zoneinterval类型,其中低于所选精度的所有字段都设为零(日和月则设为一)。 - field的有效值是∶ + field的有效值是: microseconds milliseconds @@ -1557,7 +1555,7 @@ date_trunc(field, source [ - 当输入值的类型为timestamp with time zone时。截断是针对特定时区进行的。 例如,截断为day,产生的值是 是该区域的午夜。 默认情况下,截断是在以下方面进行的 到当前的设置,但在当前的 可以提供可选的time_zone参数。以指定不同的时区。 可以指定时区名称 中描述的任何一种方式。 + 当输入值为timestamp with time zone类型时,截断会以特定时区为准;例如,截断到day会得到该时区的午夜。默认情况下,截断以当前的设置为准,但可以通过可选的time_zone参数指定其他时区。时区名称可以用中描述的任意方式指定。 @@ -1599,11 +1597,11 @@ date_bin(stride, source, < sourcetimestamptimestamp with time zone类型的值表达式。 (类型date的值会自动转换为timestamp。) strideinterval类型的值表达式。 - 返回值同样是timestamptimestamp with time zone类型,并且它标记着放置source的bin的开始。 + 返回值同样是timestamptimestamp with time zone类型,并且它表示source所在分箱的起点。 - 示例: + 示例: SELECT date_bin('15 minutes', TIMESTAMP '2020-02-11 15:44:17', TIMESTAMP '2001-01-01'); 结果: 2020-02-11 15:30:00 @@ -1625,8 +1623,8 @@ SELECT date_bin('15 minutes', TIMESTAMP '2020-02-11 15:44:17', TIMESTAMP '2001-0 <literal>AT TIME ZONE</literal> 和 <literal>AT LOCAL</literal> - time zone - conversion + 时区 + 转换 @@ -1638,7 +1636,7 @@ SELECT date_bin('15 minutes', TIMESTAMP '2020-02-11 15:44:17', TIMESTAMP '2001-0 - AT TIME ZONE 操作符可在带时区和不带时区的时间戳之间进行转换,也可将 time with time zone 值转换到不同的时区。 展示了它的各种变体。 + AT TIME ZONE 操作符可将不带时区的时间戳转换为时区的时间戳或反向转换,也可将 time with time zone 值转换到不同的时区。 展示了它的各种变体。 @@ -1738,7 +1736,7 @@ SELECT date_bin('15 minutes', TIMESTAMP '2020-02-11 15:44:17', TIMESTAMP '2001-0 time with time zone - 将给定的带时区时间转换到新的时区,所用时区为会话的 TimeZone 值。由于没有提供日期,这会使用会话 TimeZone 当前生效的 UTC 偏移量。 + 将给定的带时区时间转换到新的时区。由于没有提供日期,这会使用会话 TimeZone 值当前生效的 UTC 偏移量。 假定会话的 TimeZone 设为 UTC: @@ -1774,33 +1772,38 @@ SELECT TIMESTAMP '2001-02-16 20:38:40' AT TIME ZONE 'Asia/Tokyo' AT TIME ZONE 'A SELECT TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40-05' AT LOCAL; 结果:2001-02-16 17:38:40 SELECT TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40-05' AT TIME ZONE '+05'; -结果:2001-02-17 06:38:40 +结果:2001-02-16 20:38:40 SELECT TIME WITH TIME ZONE '20:38:40-05' AT LOCAL; -结果:17:38:40-08 +结果:17:38:40 第一个示例为缺少时区的值添加时区,并使用当前的 TimeZone 设置显示该值。 - 第二个示例将带时区的时间戳值转换到指定时区,并返回无时区的值。 - 这允许存储和显示与当前 TimeZone 设置不同的值。第三个示例将东京时间转换为芝加哥时间。第四个示例展示了 AT LOCAL 的用法。第五个示例使用数值型 UTC 偏移量作为时区。最后一个示例展示了 time with time zone 值转换为会话本地时区的结果。 + 第二个示例将带时区的时间戳值转换到指定时区,并返回不带时区的值。 + 这样就可以存储和显示与当前 TimeZone 设置不同的值。 + 第三个示例将东京时间转换为芝加哥时间。 + 第四个示例将带时区的时间戳值转换到当前 TimeZone 设置指定的时区,并返回不带时区的值。 + 第五个示例说明,POSIX 风格的时区说明中的正负号与 ISO-8601 日期时间字面量中的正负号含义相反,有关信息请参见 - 函数timezone(zone, timestamp)等效于 SQL 兼容的结构timestamp AT TIME ZONE zone。 + 第六个示例需要注意。由于输入值不包含日期,转换使用会话的当前日期。 + 因此,根据查看本示例时处于一年中的哪个时段,这个静态示例可能显示错误的结果,因为 + 'America/Los_Angeles' 实行夏令时。 - 结构 timestamp AT LOCAL 等效于 timestamp AT TIME ZONE local。 + 函数timezone(zone, timestamp)等效于符合 SQL 标准的结构timestamp AT TIME ZONE zone - 函数timezone(zone, timestamp with time zone)等效于 SQL 兼容的结构timestamp with time zone AT TIME ZONE zone。 + 函数timezone(zone, time)等效于符合 SQL 标准的结构time AT TIME ZONE zone - 结构 timestamp with time zone AT LOCAL 等效于 timestamp with time zone AT TIME ZONE local。 + 函数timezone(timestamp)等效于符合 SQL 标准的结构timestamp AT LOCAL - 函数timezone(zone, time with time zone)等效于 SQL 兼容的结构time with time zone AT TIME ZONE zone。结构 time with time zone AT LOCAL 等效于 time with time zone AT TIME ZONE local。 + 函数timezone(time)等效于符合 SQL 标准的结构time AT LOCAL @@ -1809,13 +1812,13 @@ SELECT TIME WITH TIME ZONE '20:38:40-05' AT LOCAL; 当前日期/时间 - date - current + 日期 + 当前 - time - current + 时间 + 当前 @@ -1834,15 +1837,15 @@ LOCALTIMESTAMP(precision) - CURRENT_TIMECURRENT_TIMESTAMP传递带有时区的值;LOCALTIMELOCALTIMESTAMP传递的值不带时区。 + CURRENT_TIMECURRENT_TIMESTAMP返回带时区的值;LOCALTIMELOCALTIMESTAMP返回不带时区的值。 - CURRENT_TIMECURRENT_TIMESTAMPLOCALTIMELOCALTIMESTAMP可以有选择地接受一个精度参数,该精度会使结果的秒字段圆整到指定的小数位数。如果没有精度参数,结果将给出可用的全部精度。 + CURRENT_TIMECURRENT_TIMESTAMPLOCALTIMELOCALTIMESTAMP可以有选择地接受一个精度参数,该精度会使结果的秒字段舍入到指定的小数位数。如果没有精度参数,结果将给出可用的全部精度。 - 一些示例: + 一些示例: SELECT CURRENT_TIME; 结果: 14:39:53.662522-05 @@ -1864,7 +1867,7 @@ SELECT LOCALTIMESTAMP; - 许多其它数据库系统可能会更频繁地推进这些值。 + 其他数据库系统可能会更频繁地推进这些值。 @@ -1881,11 +1884,11 @@ now() - transaction_timestamp()等价于CURRENT_TIMESTAMP,但是其命名清楚地反映了它的返回值。statement_timestamp()返回当前语句的开始时刻(更准确的说是收到 客户端最后一条命令的时间)。statement_timestamp()transaction_timestamp()在一个事务的第一条命令期间返回值相同,但是在随后的命令中却不一定相同。 clock_timestamp()返回真正的当前时间,因此它的值甚至在同一条 SQL 命令中都会变化。timeofday()是一个有历史原因的PostgreSQL函数。和clock_timestamp()相似,timeofday()也返回真实的当前时间,但是它的结果是一个格式化的text串,而不是timestamp with time zone值。now()PostgreSQL的一个传统,等效于transaction_timestamp()。 + transaction_timestamp()等价于CURRENT_TIMESTAMP,但是其命名清楚地反映了它的返回值。statement_timestamp()返回当前语句的开始时刻(更准确地说,是接收到客户端最近一条命令消息的时间)。statement_timestamp()transaction_timestamp()在一个事务的第一条语句期间返回值相同,但是在随后的语句中却不一定相同。 clock_timestamp()返回真正的当前时间,因此它的值甚至在同一条 SQL 语句中都会变化。timeofday()是一个有历史原因的PostgreSQL函数。和clock_timestamp()相似,它也返回真实的当前时间,但是它的结果是一个格式化的text串,而不是timestamp with time zone值。now()PostgreSQL中与transaction_timestamp()等价的传统函数。 - 所有日期/时间类型还接受特殊的文字值now,用于指定当前的日期和时间(重申,被解释为当前事务的开始时刻)。 因此,下面三个都返回相同的结果: + 所有日期/时间数据类型也都接受特殊字面值now来指定当前日期和时间(同样解释为事务开始时间)。因此,下面三种写法都返回相同的结果: SELECT CURRENT_TIMESTAMP; SELECT now(); @@ -1897,7 +1900,7 @@ SELECT TIMESTAMP 'now'; -- 但请参阅下面的提示 当指定以后要计算的值时,不要使用第三种形式,例如在表列的DEFAULT子句中。 - 系统将在分析这个常量的时候把now转换为一个timestamp, 这样需要默认值时就会得到创建表的时间!而前两种形式要到实际使用缺省值的时候才被计算, 因为它们是函数调用。因此它们可以给出每次插入行的时刻。 + 系统将在分析这个常量的时候把now转换为一个timestamp, 这样需要默认值时就会得到创建表的时间!而前两种形式要到实际使用默认值的时候才被计算, 因为它们是函数调用。因此它们可以给出每次插入行的时刻。 (参见 。) @@ -1920,24 +1923,24 @@ SELECT TIMESTAMP 'now'; -- 但请参阅下面的提示 - sleep + 休眠 - delay + 延迟 - 下面的这些函数可以用于让服务器进程延时执行: + 以下函数可用于延迟服务器进程的执行: pg_sleep ( double precision ) pg_sleep_for ( interval ) pg_sleep_until ( timestamp with time zone ) - pg_sleep使当前会话的进程休眠,直到过去给定的秒数。可以指定几分之一秒的延迟。 - pg_sleep_for是一个方便的函数,允许将睡眠时间指定为时间间隔。 - pg_sleep_until是一个方便的函数,用于需要特定的唤醒时间。例如: + pg_sleep使当前会话的进程休眠,直到经过指定的秒数。可以指定带小数部分的秒数作为延迟时间。 + pg_sleep_for是一个便捷函数,允许以interval指定休眠时间。 + pg_sleep_until是在需要指定唤醒时间时使用的便捷函数。例如: SELECT pg_sleep(1.5); diff --git a/zh/20/func/func-enum.sgml b/zh/20/func/func-enum.sgml index 0b82baa2..171c99f8 100644 --- a/zh/20/func/func-enum.sgml +++ b/zh/20/func/func-enum.sgml @@ -3,7 +3,7 @@ 枚举支持函数 - 对于枚举类型(在中描述), 有一些函数允许更清洁的编码,而不需要为一个枚举类型硬写特定的值。它们被列在中。本例假定一个枚举类型被创建为: + 对于枚举类型(见),有些函数可以避免硬编码枚举类型中的特定值,使程序更简洁。这些函数列在中。以下示例假定枚举类型按如下方式创建: CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple'); @@ -89,8 +89,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple anyarray - 以一个数组返回在给定两个枚举值之间的范围。值必须来自相同的枚举类型。 - 如果第一个参数为空,其结果将从枚举类型的第一个值开始。如果第二参数为空,其结果将以枚举类型的最后一个值结束。 + 以有序数组返回两个给定枚举值之间的范围。两个值必须来自同一枚举类型。如果第一个参数为 null,结果从该枚举类型的第一个值开始;如果第二个参数为 null,结果以该枚举类型的最后一个值结束。 enum_range('orange'::rainbow, 'green'::rainbow) @@ -110,7 +109,6 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple
- 请注意,除了双参数形式的enum_range外, 这些函数忽略传递给它们的具体值,它们只关心声明的数据类型。 - 空值或类型的一个特定值可以通过,并得到相同的结果。这些函数更多地被用于一个表列或函数参数,而不是一个硬写的类型名,如示例中所使用。 + 请注意,除了enum_range的双参数形式外,这些函数都忽略传入的具体值,只关心其声明的数据类型。传入 null 或该类型的某个具体值,结果都相同。通常会将这些函数用于表列或函数参数,而不是像示例那样使用硬编码的类型名。 diff --git a/zh/20/func/func-event-triggers.sgml b/zh/20/func/func-event-triggers.sgml index 6b4f641d..cb257885 100644 --- a/zh/20/func/func-event-triggers.sgml +++ b/zh/20/func/func-event-triggers.sgml @@ -3,7 +3,7 @@ 事件触发器函数 - PostgreSQL提供了这些助手函数来从事件触发器检索信息。 + PostgreSQL提供了这些辅助函数来从事件触发器检索信息。 @@ -25,7 +25,7 @@ 当在一个ddl_command_end事件触发器的函数中调用时,pg_event_trigger_ddl_commands返回被每一个用户动作执行的DDL命令的列表。 如果在其他任何环境中调用这个函数,会发生错误。 - pg_event_trigger_ddl_commands为每一个被执行的基本命令返回一行,某些只有一个单一 SQL 句子的命令可能会返回多于一行。 + pg_event_trigger_ddl_commands为每一个被执行的基本命令返回一行,某些由单条 SQL 语句构成的命令可能会返回多于一行。 这个函数返回下面的列: @@ -42,7 +42,7 @@ classid oid - 对象所属的目录的 OID + 对象所属系统目录的 OID objid @@ -52,7 +52,7 @@ objsubid integer - 对象的子-id(例如列的属性号) + 子对象 ID(例如列的属性编号) command_tag @@ -68,16 +68,14 @@ schema_name text - 该对象所属的模式的名称(如果有),如果没有则为NULL。 - 没有引号。 + 对象所属模式的名称(若有);否则为NULL。不加引号。 object_identity text - 对象标识的文本表现形式,用模式限定。如果必要,出现在 - 该标识中的每一个标识符都会被引用。 + 对象标识的文本表示形式,带模式限定。标识中包含的每个标识符在必要时都会加引号。 @@ -89,8 +87,7 @@ command pg_ddl_command - 以内部格式表达的该命令的一个完整表现形式。这不能被直接输出, - 但是可以把它传递给其他函数来得到有关于该命令不同部分的信息。 + 命令的完整内部表示,不能直接输出,但可以将其传给其他函数以获取关于该命令的不同信息。 @@ -112,8 +109,8 @@ - pg_event_trigger_dropped_objects返回被调用sql_drop事件的命令删除的所有对象的列表。 - 如果调用在任何其他上下文中,会引发一个错误。这个函数返回以下列: + 在命令的sql_drop事件中调用pg_event_trigger_dropped_objects时,它返回该命令删除的所有对象的列表。 + 如果调用在任何其他上下文中,会引发一个错误。这个函数返回以下列: @@ -129,7 +126,7 @@ classid oid - 对象所属的目录的 OID + 对象原先所属系统目录的 OID objid @@ -139,7 +136,7 @@ objsubid integer - 子对象ID(如列的属性号) + 子对象 ID(例如列的属性编号) original @@ -150,7 +147,7 @@ normal boolean - 指示在依赖图中有一个普通依赖关系指向该对象的标志 + 如果依赖图中存在指向该对象的普通依赖关系,则为真。 @@ -169,29 +166,28 @@ schema_name text - 对象所属模式的名称(如果存在);否则为NULL。不应用引用。 + 对象原先所属模式的名称(若有);否则为NULL。不加引号。 object_name text - 如果模式和名称的组合能被用于对象的一个唯一标识符,则是对象的名称;否则是NULL。不应用引用,并且名称不是模式限定的。 + 如果模式和名称的组合可用作该对象的唯一标识符,则为对象名称;否则为NULL。不加引号,并且该名称永远不带模式限定。 object_identity text - 对象身份的文本表现,模式限定的。每一个以及所有身份中出现的标识符在必要时加引号。 + 对象标识的文本表示形式,带模式限定。标识中包含的每个标识符在必要时都会加引号。 address_names text[] - 一个数组,它可以和object_typeaddress_args, - 一起通过pg_get_object_address函数在一台包含有同类相同名称对象的远程服务器上重建该对象地址。 + 一个数组,可与object_typeaddress_args一起,通过pg_get_object_address函数在包含同类同名对象的远程服务器上重建该对象地址。 @@ -290,7 +286,7 @@ CREATE EVENT TRIGGER test_event_trigger_for_drops - 这些函数可以在事件触发器中使用,就像这样: + 这些函数可以在事件触发器中使用,就像这样: CREATE FUNCTION test_event_trigger_table_rewrite_oid() RETURNS event_trigger diff --git a/zh/20/func/func-formatting.sgml b/zh/20/func/func-formatting.sgml index 1aa85d9a..deb87344 100644 --- a/zh/20/func/func-formatting.sgml +++ b/zh/20/func/func-formatting.sgml @@ -3,11 +3,11 @@ 数据类型格式化函数 - formatting + 格式化 - PostgreSQL格式化函数提供一套强大的工具用于把各种数据类型 (日期/时间、整数、浮点、数字) 转换成格式化的字符串以及反过来从格式化的字符串转换成 指定的数据类型。列出了这些函数。这些函数都遵循一个公共的调用规范: 第一个参数是待格式化的值,而第二个是一个定义输出或输入格式的模板。 + PostgreSQL格式化函数提供一套强大的工具用于把各种数据类型 (日期/时间、整数、浮点数、数值) 转换成格式化的字符串以及反过来从格式化的字符串转换成 指定的数据类型。列出了这些函数。这些函数都遵循一个公共的调用规范: 第一个参数是待格式化的值,而第二个是一个定义输出或输入格式的模板。 @@ -58,7 +58,7 @@ text - 根据给定的格式将间隔转换为字符串。 + 根据给定的格式将时间间隔转换为字符串。 to_char(interval '15h 2m 12s', 'HH24:MI:SS') @@ -114,7 +114,7 @@ numeric - 根据给定的格式将字符串转换为数字。 + 根据给定的格式将字符串转换为数值。 to_number('12,454.8-', '99G999D9S') @@ -155,7 +155,7 @@ - 展示了可以用于格式化日期和时间值的模版。 + 展示了可以用于格式化日期和时间值的模板模式。
@@ -242,24 +242,24 @@ SSSS, SSSSS - 午夜后的秒 (0–86399) + 自午夜起的秒数 (0–86399) AM, am, - PM or pm - 正午指示器(不带句号) + PMpm + 上午/下午标记(不带句点) A.M., a.m., - P.M. or p.m. - 正午指示器(带句号) + P.M.p.m. + 上午/下午标记(带句点) Y,YYY - 带逗号的年(4 位或者更多位) with comma + 带逗号的年(4 位或者更多位) @@ -316,17 +316,17 @@ MONTH - 全大写形式的月名(空格补齐到 9 字符) + 大写的月份全称(空格补齐到 9 字符) Month - 全首字母大写形式的月名(空格补齐到 9 字符) + 首字母大写的月份全称(空格补齐到 9 字符) month - 全小写形式的月名(空格补齐到 9 字符) + 小写的月份全称(空格补齐到 9 字符) @@ -351,72 +351,72 @@ DAY - 全大写形式的日名(空格补齐到 9 字符) + 大写的星期全称(空格补齐到 9 字符) Day - 全首字母大写形式的日名(空格补齐到 9 字符) + 首字母大写的星期全称(空格补齐到 9 字符) day - 全小写形式的日名(空格补齐到 9 字符) + 小写的星期全称(空格补齐到 9 字符) DY - 简写的大写形式的日名(英语 3 字符,本地化长度可变) + 大写的星期简称(英语 3 字符,本地化长度可变) Dy - 简写的首字母大写形式的日名(英语 3 字符,本地化长度可变) + 首字母大写的星期简称(英语 3 字符,本地化长度可变) dy - 简写的小写形式的日名(英语 3 字符,本地化长度可变) + 小写的星期简称(英语 3 字符,本地化长度可变) DDD - 一年中的日(001–366) + 年内日序数(001–366) IDDD - ISO 8601 周编号方式的年中的日 (001–371; 年的第 1 日时第一个 ISO 周的周一) + ISO 8601 周编号方式的年中的日 (001–371; 年的第 1 日是第一个 ISO 周的周一) DD - 月中的日 (01–31) + 月内日序数 (01–31) D - 周中的日,周日 (1) 到周六 (7) + 星期几,周日 (1) 到周六 (7) ID - 周中的 ISO 8601 日,周一 (1) 到周日 (7) + ISO 8601 星期几,周一 (1) 到周日 (7) W - 月中的周 (1–5) (第一周从该月的第一天开始) + 月内周序数 (1–5) (第一周从该月的第一天开始) WW - 年中的周数 (1–53) (第一周从该年的第一天开始) + 年中的周编号 (1–53) (第一周从该年的第一天开始) IW - ISO 8601 周编号方式的年中的周数 (01–53; 新的一年的第一个周四在第一周) + ISO 8601 周编号方式的年中的周编号 (01–53; 新的一年的第一个周四在第一周) @@ -446,12 +446,12 @@ TZ - 大写形式的时区缩写(仅在to_char中支持) + 大写形式的时区缩写 tz - 小写形式的时区缩写(仅在to_char中支持) + 小写形式的时区缩写 @@ -474,17 +474,17 @@
- 修饰语可以被应用于模板模式来修改它们的行为。例如,FMMonth就是带着FM修饰语的Month模式。展示了可用于日期/时间格式化的修饰语模式。 + 修饰符可以被应用于模板模式来修改它们的行为。例如,FMMonth就是带着FM修饰符的Month模式。展示了可用于日期/时间格式化的修饰符模式。 - 用于日期/时间格式化的模板模式修饰语 + 用于日期/时间格式化的模板模式修饰符 - 修饰语 + 修饰符 描述 示例 @@ -492,37 +492,37 @@ - FM prefix + FM 前缀 填充模式(抑制前导零和填充的空格) FMMonth - TH suffix + TH 后缀 大写形式的序数后缀 - DDTH, e.g., 12TH + DDTH,例如, 12TH - th suffix + th 后缀 小写形式的序数后缀 - DDth, e.g., 12th + DDth,例如, 12th - FX prefix - 固定的格式化全局选项(见使用须知) + FX 前缀 + 固定格式全局选项(见使用须知) FX Month DD Day - TM prefix - 翻译模式(基于使用本地化的日和月名) + TM 前缀 + 翻译模式(基于使用本地化的星期名和月份名) TMMonth - SP suffix + SP 后缀 拼写模式(未实现) DDSP @@ -539,8 +539,8 @@ FM抑制了在模式输出中添加前导零和尾随空格的行为,这些前导零和尾随空格 本来会被添加以使输出成为固定宽度。在PostgreSQL中, - FM仅修改下一个规范,而在Oracle中FM影响所有后续 - 规范,并且重复的FM修饰符切换填充模式的开启和关闭。 + FM仅修改下一个格式说明,而在Oracle中FM影响所有后续 + 格式说明,并且重复的FM修饰符切换填充模式的开启和关闭。 @@ -598,10 +598,10 @@ 一个TZH模板模式可以匹配有符号数。 - 没有FX选项,减号可能会有歧义,并且可能被解释为分隔符。 - 此歧义解决如下:如果模板字符串中TZH之前的分隔符数量少于输入字符串中减号之前的分隔符数量, - 则减号被解释为TZH的一部分。 - 否则,减号被视为值之间的分隔符。 + 没有FX选项,负号可能会有歧义,并且可能被解释为分隔符。 + 此歧义解决如下:如果模板字符串中TZH之前的分隔符数量少于输入字符串中负号之前的分隔符数量, + 则负号被解释为TZH的一部分。 + 否则,负号被视为值之间的分隔符。 例如,to_timestamp('2000 -10', 'YYYY TZH')匹配 -10TZH,但 to_timestamp('2000 -10', 'YYYY  TZH') @@ -612,12 +612,7 @@ - 普通文本允许在to_char模板中,并且将被直接输出。您可以将子字符串放在双引号中, - 以强制将其解释为文字文本,即使它包含模板模式。例如,在'"Hello Year "YYYY'中, - YYYY将被年份数据替换,但Year中的单个Y不会被替换。 - 在to_dateto_numberto_timestamp中, - 文本和双引号字符串会导致跳过字符串中包含的字符数;例如"XX"跳过两个输入字符 - (无论它们是否为XX)。 + 普通文本可以出现在to_char模板中,并会按字面输出。可以用双引号括起子串,使其即使包含模式关键字也强制按字面文本解释。例如,在'"Hello Year "YYYY'中,YYYY会被年份数据替换,但Year中单独的Y不会被替换。在to_dateto_numberto_timestamp中,字面文本和双引号字符串会跳过与该字符串所含字符数相同数量的输入字符;例如,"XX"跳过两个输入字符(无论它们是否为XX)。 @@ -636,7 +631,7 @@ 如果您想在输出中使用双引号,必须在其前面加上反斜杠,例如'\"YYYY Month\"' - 反斜杠在双引号之外不起特殊作用。在双引号字符串内部,反斜杠会使下一个字符被直接解释,无论是什么(但除非下一个字符是双引号或另一个反斜杠,否则没有特殊效果)。 + 反斜杠在双引号之外不起特殊作用。在双引号字符串内部,反斜杠会使下一个字符被按字面解释,无论是什么(但除非下一个字符是双引号或另一个反斜杠,否则没有特殊效果)。 @@ -699,14 +694,14 @@ - 年份、周数和星期几:例如to_date('2006-42-4', 'IYYY-IW-ID') + 年份、周编号和星期几:例如to_date('2006-42-4', 'IYYY-IW-ID') 返回日期2006-10-19。 如果省略星期几,则假定为1(星期一)。 - 年份和年内天数:例如to_date('2006-291', 'IYYY-IDDD')也返回2006-10-19。 + 年份和年内日序数:例如to_date('2006-291', 'IYYY-IDDD')也返回2006-10-19 @@ -714,14 +709,14 @@ 尝试使用ISO 8601周编号字段和公历日期字段的混合输入日期是荒谬的,并将导致错误。 - 在ISO 8601周编号年的背景下,月份日期的概念没有意义。 + 在ISO 8601周编号年的背景下,月份月内日序数的概念没有意义。 在公历年的背景下,ISO周没有意义。 - 当to_date拒绝混合使用公历和ISO周编号日期字段时, - to_char不会,因为输出格式规范如YYYY-MM-DD (IYYY-IDDD)可能很有用。 + 虽然to_date会拒绝混合使用公历和ISO周编号日期字段, + 但to_char不会,因为输出格式规范如YYYY-MM-DD (IYYY-IDDD)可能很有用。 但要避免编写类似IYYY-MM-DD的内容;那会在年初附近产生令人惊讶的结果。 (有关更多信息,请参见。) @@ -740,7 +735,7 @@ 这是一个更复杂的示例: to_timestamp('15:12:02.020.001230', 'HH24:MI:SS.MS.US') - 是15小时,12分钟和2秒 + 20毫秒 + 1230微秒 = 2.021230秒。 + 为15小时12分钟,秒数为2秒 + 20毫秒 + 1230微秒 = 2.021230秒。 @@ -748,7 +743,7 @@ to_char(..., 'ID')的星期几编号与extract(isodow FROM ...)函数匹配, - 但to_char(..., 'D')的不匹配extract(dow FROM ...)的星期编号。 + 但to_char(..., 'D')的不匹配extract(dow FROM ...)的星期几编号。 @@ -765,12 +760,12 @@ - 展示了可以用于格式化数字值的模版模式。 + 展示了可以用于格式化数值的模板模式。
- 用于数字格式化的模板模式 + 用于数值格式化的模板模式 @@ -787,21 +782,21 @@ 9 - 数位(如果无意义可以被删除) + 数位(非有效位可以被省略) 0 - 数位(即便没有意义也不会被删除) + 数位(即便是非有效位也不会被省略) - . (period) + .(句点) 小数点 - , (comma) + ,(逗号) 分组(千)分隔符 @@ -812,22 +807,22 @@ S - 带符号的数字(使用区域) + 紧贴数值的正负号(使用区域设置) L - 货币符号(使用区域) + 货币符号(使用区域设置) D - 小数点(使用区域) + 小数点(使用区域设置) G - 分组分隔符(使用区域) + 分组分隔符(使用区域设置) @@ -846,12 +841,12 @@ - RN - 罗马数字(输入在 1 和 3999 之间) + RNrn + 罗马数字(数值在 1 和 3999 之间) - TH or th + THth 序数后缀 @@ -869,7 +864,7 @@
- 数字格式化的使用注意事项: + 数值格式化的使用注意事项: @@ -885,14 +880,14 @@ - 如果格式提供的小数位数少于被格式化的数字,则to_char()将会将数字四舍五入到指定的小数位数。 + 如果格式指定的小数位数少于被格式化数值的小数位数,to_char()会将该数值舍入到指定的小数位数。 - 模式字符SLDG表示当前区域设置定义的符号、货币符号、小数点和千位分隔符字符 + 模式字符SLDG表示当前区域设置定义的正负号、货币符号、小数点和千位分隔符字符 (参见)。模式字符句点和逗号表示这些确切字符,具有小数点和千位分隔符的含义,不受区域设置影响。 @@ -901,15 +896,14 @@ - 如果在to_char()的模式中没有明确指定符号,将为符号保留一列,并将其锚定到(出现在)数字的左侧。 - 如果S出现在一些9的左侧,它也将锚定到数字。 + 如果to_char()的模式中没有明确指定正负号的位置,就会为正负号保留一列,并使其紧贴数值(紧靠数值左侧)。如果S紧邻若干个9的左侧,它同样会紧贴数值。 - 使用SGPLMI格式化的符号不与数字绑定; + 使用SGPLMI格式化的正负号不紧贴数值; 例如,to_char(-12, 'MI9999')会产生'-  12', 但to_char(-12, 'S9999')会产生'  -12'。 (Oracle实现不允许在9之前使用MI,而是要求9MI之前。) @@ -936,7 +930,7 @@ to_number函数中,如果使用非数据模板模式,如LTH, - 则会跳过相应数量的输入字符,无论它们是否与模板模式匹配,除非它们是数据字符(即数字、符号、小数点或逗号)。 + 则会跳过相应数量的输入字符,无论它们是否与模板模式匹配,除非它们是数据字符(即数字、正负号、小数点或逗号)。 例如,TH会跳过两个非数据字符。 @@ -947,7 +941,8 @@ Vto_char一起, 将输入值乘以10^n, 其中n是跟在V后面的数字位数。 - Vto_number一起以类似的方式除法。 + Vto_number一起以类似的方式进行除法。 + V可以视为输入或输出字符串中隐含小数点位置的标记。 to_charto_number不支持与小数点结合使用的V (例如,不允许使用99.9V99)。 @@ -959,21 +954,27 @@ EEEE(科学计数法)不能与任何其他格式模式或修饰符结合使用,除了数字和小数点模式之外,必须位于格式字符串的末尾(例如,9.99EEEE是一个有效模式)。
+ + + + 在to_number()中,RN模式将标准形式的罗马数字转换为数值。输入不区分大小写,因此RNrn等效。RN不能与其他格式化模式或修饰符组合使用,唯一的例外是FM;该修饰符只适用于to_char(),在to_number()中会被忽略。 + + - 某些修饰语可以被应用到任何模板来改变其行为。例如,FM99.99是带有FM修饰语的99.99模式。中展示了用于数字格式化模式修饰语。 + 某些修饰符可以被应用到任何模板来改变其行为。例如,FM99.99是带有FM修饰符的99.99模式。中展示了用于数值格式化的模式修饰符。 - 用于数字格式化的模板模式修饰语 + 用于数值格式化的模板模式修饰符 - 修饰语 + 修饰符 描述 示例 @@ -981,19 +982,19 @@ - FM prefix - 填充模式(抑制拖尾零和填充的空白) + FM 前缀 + 填充模式(抑制尾随零和填充的空白) FM99.99 - TH suffix + TH 后缀 大写序数后缀 999TH - th suffix + th 后缀 小写序数后缀 999th @@ -1026,6 +1027,13 @@ 'Tuesday, 6  05:39:18' + to_char(current_timestamp AT TIME ZONE + 'UTC', 'YYYY-MM-DD"T"HH24:MI:SS"Z"') + '2022-12-06T05:39:18Z', + ISO 8601 扩展格式 + + + to_char(-0.1, '99.99') '  -.10' diff --git a/zh/20/func/func-geometry.sgml b/zh/20/func/func-geometry.sgml index c4b85319..c8263764 100644 --- a/zh/20/func/func-geometry.sgml +++ b/zh/20/func/func-geometry.sgml @@ -5,7 +5,7 @@ 几何类型pointboxlseglinepath、 - polygoncircle有一大堆本地支持函数和操作符,如中所示。 + polygoncircle有大量内置支持函数和操作符,如中所示。
@@ -50,7 +50,7 @@ path - 连接两个打开的路径(如果其中一个路径是关闭的,则返回NULL)。 + 连接两个开放路径(如果任一路径是封闭的,则返回NULL)。 path '[(0,0),(1,1)]' + path '[(2,2),(3,3),(4,4)]' @@ -79,12 +79,12 @@ geometric_type - 将第一个参数的每个点乘上第二个point(将点视为由实部和虚部表示的复数,并执行标准的复数乘法)。 + 将第一个参数的每个点乘上第二个point(将点视为由实部和虚部表示的复数,并执行标准的复数乘法)。 如果将第二个point解释为向量,这等价于将对象的大小和到原点的距离按向量的长度缩放,并以向量与x轴的夹角绕原点逆时针旋转。 - 适用于point, box,Rotating 用这些操作符“旋转”一个盒子,只会移动它的角点:这个盒子仍然被认为有平行于轴的边。 - 因此,盒子的大小并没有像真正的旋转那样得到保留。 - path, circle.。 + 适用于pointbox用这些操作符旋转一个矩形框,只会移动它的角点:这个矩形框仍然被认为有平行于轴的边。 + 因此,矩形框的大小并没有像真正的旋转那样得到保留。 + pathcircle path '((0,0),(1,0),(1,1))' * point '(3.0,0)' @@ -103,7 +103,7 @@ 将第一个参数的每个点除以第二个point(将点视为由实部和虚部表示的复数,并执行标准的复数除法)。 - 如果将第二个point解释为向量,这等价于将物体的大小和到原点的距离按向量的长度向下缩放,并以向量与x轴的夹角围绕原点顺时针旋转。 + 如果将第二个point解释为向量,这等价于将对象的大小和到原点的距离按向量长度的倒数缩放,并以向量与x轴的夹角围绕原点顺时针旋转。 适用于 point, box, path,circle @@ -180,7 +180,7 @@ box - 计算两个方框的交集,如果没有则为NULL。 + 计算两个矩形框的交集,如果没有则为NULL。 box '(2,2),(-1,-1)' # box '(1,1),(-2,-2)' @@ -194,7 +194,7 @@ point - 计算第一个对象上距离第二个对象最近的点。 + 计算第二个对象上距离第一个对象最近的点。 可用于以下类型的配对: (point, box), (point, lseg), @@ -216,7 +216,7 @@ 计算对象之间的距离。 - 对于所有七种几何类型,所有point与另一种几何类型的组合, + 适用于所有七种几何类型,所有point与另一种几何类型的组合, 以及以下这些额外的类型对: (box, lseg), (lseg, line), @@ -256,7 +256,7 @@ boolean - 第一个对象包含在第二个对象之中还是在第二个对象之上? 适用于这些类型对: + 第一个对象是否位于第二个对象内部或其上? 适用于这些类型对: (point, box), (point, lseg), (point, line), @@ -356,7 +356,7 @@ boolean - 第一个对象是否确定位于第二个对象下面? + 第一个对象是否严格位于第二个对象下面? 适用于 point, box, polygon, circle @@ -371,7 +371,7 @@ boolean - 第一个对象是否确定位于第二个对象上面? + 第一个对象是否严格位于第二个对象上面? 适用于 point, box, polygon, circle. @@ -444,7 +444,7 @@ boolean - 这些对象是否相交? 适用于这些类型对: + 这些对象是否相交? 适用于这些类型对: (box, box), (lseg, box), (lseg, lseg), @@ -469,7 +469,7 @@ boolean - 线是水平的? + 线是否水平? ?- lseg '[(-1,0),(1,0)]' @@ -501,7 +501,7 @@ boolean - 线是纵向的? + 线是否竖直? ?| lseg '[(-1,0),(1,0)]' @@ -533,7 +533,7 @@ boolean - 线是垂直的? + 两条线是否互相垂直? lseg '[(0,0),(0,1)]' ?-| lseg '[(0,0),(1,0)]' @@ -551,7 +551,7 @@ boolean - 线是平行的? + 两条线是否平行? lseg '[(-1,0),(1,0)]' ?|| lseg '[(-1,2),(1,2)]' @@ -580,16 +580,16 @@ - 请注意same as操作符(~=),表示pointboxpolygoncircle类型的一般相等概念。 - 这些类型中的某些还有一个=操作符,但是=只比较相同的面积。 - 其它的标量比较操作符 (<=等等),在这些类型可用的地方,同样比较区域。 + 注意,相同操作符~=表示pointboxpolygoncircle类型通常意义上的相等。 + 某些几何类型还有=操作符,但=仅比较面积是否相等。 + 对于提供其他标量比较操作符(<=等)的类型,这些操作符同样比较面积。 - 在PostgreSQL14之前, 该点严格低于/高于比较操作符 point <<| pointpoint |>> point 分别被称为 <^>^。 + 在PostgreSQL14之前, 用于判断点是否严格位于另一点下方/上方的比较操作符 point <<| pointpoint |>> point 分别被称为 <^>^。 这些名字仍然可以使用,但是已被弃用并且最终将被移除。 @@ -886,7 +886,7 @@ box - 计算内接于圆的方框。 + 计算内接于圆的矩形框。 box(circle '<(0,0),2>') @@ -945,7 +945,7 @@ box - 计算两个方框的边界框。 + 计算两个矩形框的边界框。 bound_box(box '(1,1),(0,0)', box '(4,4),(3,3)') @@ -962,7 +962,7 @@ circle - 计算包围方框的最小圆。 + 计算包围矩形框的最小圆。 circle(box '(1,1),(0,0)') @@ -1055,7 +1055,7 @@ path - 将多边形转换为具有点的相同列表的封闭路径。 + 将多边形转换为具有相同点列表的封闭路径。 path(polygon '((0,0),(1,1),(2,0))') @@ -1163,7 +1163,7 @@ polygon(circle '<(0,0),2>') - (-2,0,)&zwsp; (-1.73205080758774,0.9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999998999998989898989676868686887898999999999998989898989898999978987878787808070876888788989898989898989898989898989898989898989898968686868688768686887878989896868686889899999999999990000890000899900000000890000890000890000000000000000 + ((-2,0),&zwsp;(-1.7320508075688774,0.9999999999999999),&zwsp;(-1.0000000000000002,1.7320508075688772),&zwsp;(-1.2246063538223773e-16,2),&zwsp;(0.9999999999999996,1.7320508075688774),&zwsp;(1.732050807568877,1.0000000000000007),&zwsp;(2,2.4492127076447545e-16),&zwsp;(1.7320508075688776,-0.9999999999999994),&zwsp;(1.0000000000000009,-1.7320508075688767),&zwsp;(3.673819061467132e-16,-2),&zwsp;(-0.9999999999999987,-1.732050807568878),&zwsp;(-1.7320508075688767,-1.0000000000000009)) @@ -1177,7 +1177,7 @@ polygon(4, circle '<(3,0),1>') - ((2,0,)&zwsp; (3,1,)&zwsp; (4,1.2246063538223773e-16), &zwsp; (3,-1)). + ((2,0),&zwsp;(3,1),&zwsp;(4,1.2246063538223773e-16),&zwsp;(3,-1)) @@ -1187,7 +1187,7 @@ polygon - 将封闭路径转换为具有点的相同列表的多边形。 + 将封闭路径转换为具有相同点列表的多边形。 polygon(path '((0,0),(1,1),(2,0))') @@ -1200,7 +1200,7 @@
- 我们可以把一个point的两个组成数字当作具有索引 0 和 1 的数组访问。例如,如果t.p是一个point列,那么SELECT p[0] FROM t检索 X 坐标而 UPDATE t SET p[1] = ...改变 Y 坐标。同样,box或者lseg类型的值可以当作两个point值的数组值看待。 + 可以把一个point当作下标为 0 和 1 的数组,访问它的两个数值分量。例如,如果t.p是一个point列,那么SELECT p[0] FROM t检索 X 坐标而 UPDATE t SET p[1] = ...改变 Y 坐标。同样,box或者lseg类型的值可以当作两个point值组成的数组看待。 diff --git a/zh/20/func/func-info.sgml b/zh/20/func/func-info.sgml index 5dd77789..3604c7f0 100644 --- a/zh/20/func/func-info.sgml +++ b/zh/20/func/func-info.sgml @@ -2,11 +2,15 @@ 系统信息函数和操作符 + + 本节描述的函数用于获取有关PostgreSQL安装的各种信息。 + + 会话信息函数 - 展示了多个可以抽取会话和系统信息的函数。 + 列出了多个用于提取会话和系统信息的函数。 @@ -47,7 +51,7 @@ name - 返回当前数据库的名称。(在SQL标准中数据库被称为catalogs,因此current_catalog是该标准的拼写方式。) + 返回当前数据库的名称。(SQL 标准将数据库称为目录(catalogs),因此current_catalog是标准中的写法。) @@ -60,7 +64,7 @@ text - 返回当前所执行查询的文本,由客户端提交的(可能包含一个以上的语句)。 + 返回客户端提交的当前正在执行的查询文本(可能包含多条语句)。 @@ -83,8 +87,8 @@ current_schema - schema - current + 模式 + 当前 current_schema name @@ -105,16 +109,14 @@ current_schemas - search path - current + 搜索路径 + 当前 current_schemas ( include_implicit boolean ) name[] - 返回当前在有效搜索路径中的所有模式的名称的数组,以优先级顺序。 - (当前 设置中与已存在的、可搜索模式不相符的项将被省略。) - 如果布尔参数为true,则类似pg_catalog的隐式搜索的系统模式将包含在结果中。 + 返回当前有效搜索路径中所有模式名称的数组,按优先级排序。(当前设置中不对应于已存在且可搜索的模式的项会被省略。)如果布尔参数为true,结果还会包含pg_catalog等隐式搜索的系统模式。 @@ -124,8 +126,8 @@ current_user - user - current + 用户 + 当前 current_user name @@ -144,7 +146,7 @@ inet - 返回当前客户端的IP地址,如果当前连接是通过Unix-域套接字则返回NULL + 返回当前客户端的 IP 地址;如果当前连接通过 Unix 域套接字建立,则返回NULL @@ -157,7 +159,7 @@ integer - 返回当前客户端的IP端口号,如果当前连接是通过Unix-域套接字则返回NULL。 + 返回当前客户端的IP端口号,如果当前连接是通过Unix 域套接字则返回NULL @@ -170,7 +172,7 @@ inet - 返回服务器接受当前连接的IP地址,如果当前连接是通过Unix-域套接字则返回NULL。 + 返回服务器接受当前连接的IP地址,如果当前连接是通过Unix 域套接字则返回NULL @@ -183,7 +185,7 @@ integer - 返回服务器接受当前连接的IP端口号,如果当前连接是通过Unix-域套接字则返回NULL。 + 返回服务器接受当前连接的IP端口号,如果当前连接是通过Unix 域套接字则返回NULL @@ -209,12 +211,10 @@ integer[] - 返回阻止服务器进程的会话的进程ID数组,该进程ID与指定的进程ID一起获取锁定,如果没有这样的服务器进程或者没有被阻塞,则返回一个空数组。 + 返回一个数组,包含阻止指定进程 ID 对应的服务器进程获取锁的会话进程 ID;如果不存在这样的服务器进程,或该进程未被阻塞,则返回空数组。 - 如果一个服务器进程持有一个与被阻塞进程的锁请求冲突的锁(硬阻塞),或者正在等待一个与被阻塞进程的锁请求冲突并且在等待队列中位于其前面的锁(软阻塞),那么这个服务器进程就会阻塞另一个服务器进程。 - 当使用并行查询时结果总是列出客户端可见的进程ID(即pg_backend_pid的结果),即使实际的锁是由子工作进程持有或等待的。 - 因此,结果中可能存在重复的pid。还要注意当准备好的事务持有冲突锁时,它将用零进程ID表示。 + 一个服务器进程会在以下情况下阻塞另一个进程:它持有与被阻塞进程请求的锁冲突的锁(硬阻塞);或者它正在等待一个会与被阻塞进程请求的锁冲突的锁,并且在等待队列中位于被阻塞进程之前(软阻塞)。使用并行查询时,即使实际持锁或等待锁的是子工作进程,结果也始终列出客户端可见的进程 ID(即pg_backend_pid的结果)。因此,结果中可能出现重复的 PID。另外,如果持有冲突锁的是一个预备事务,结果中会用进程 ID 0 表示它。 频繁调用这个函数可能会对数据库性能产生一些影响,因为它需要在短时间内独占访问锁管理器的共享状态。 @@ -230,8 +230,7 @@ timestamp with time zone - 返回服务器配置文件最后加载的时间。如果当前会话当时是活跃的,那么这将是会话本身重新读取配置文件的时间(因此在不同的会话中读取会稍有不同)。 - 否则,就是postmaster进程重新读取配置文件的时间。 + 返回服务器配置文件最近一次加载的时间。如果当时当前会话已经存在,则返回该会话自身重新读取配置文件的时间(因此不同会话中的返回时间会略有不同)。否则,返回 postmaster 进程重新读取配置文件的时间。 @@ -241,16 +240,16 @@ pg_current_logfile - Logging - pg_current_logfile函数 + 日志记录 + pg_current_logfile 函数 current_logfiles - 和pg_current_logfile函数 + 和pg_current_logfile 函数 - Logging - current_logfiles文件和pg_current_logfile函数 + 日志记录 + current_logfiles 文件和pg_current_logfile 函数 pg_current_logfile ( text ) text @@ -266,7 +265,7 @@ 结果反映current_logfiles文件的内容。 - 默认情况下,此函数仅限于超级用户以及具有pg_monitor角色权限的角色,但可以向其他用户授予 EXECUTE 权限以运行该函数。 + 默认情况下,此函数仅限超级用户和具有pg_monitor角色权限的角色使用,但可以向其他用户授予EXECUTE权限以运行它。 @@ -360,7 +359,7 @@ double precision - 返回当前被等待处理的通知所占用的异步通知队列最大尺寸的分数(0–1)。更多信息请参见。 + 返回待处理通知当前占用的空间占异步通知队列最大容量的比例(0–1)。更多信息请参见 @@ -386,11 +385,11 @@ integer[] - 返回一个进程ID数组,该进程ID是阻塞服务器进程获取安全快照的会话的进程ID数组,如果没有这样的服务器进程或者没有阻塞,则返回一个空数组。 + 返回一个数组,包含阻止指定进程 ID 对应的服务器进程获取安全快照的会话进程 ID;如果不存在这样的服务器进程,或该进程未被阻塞,则返回空数组。 运行SERIALIZABLE事务的会话会阻止SERIALIZABLE READ ONLY DEFERRABLE事务获取快照,直到后者确定可以安全地避免获取谓词锁。 - 关于可串行化和可延迟事务的更多信息,请参见。 + 关于可序列化和可延迟事务的更多信息,请参见 频繁调用这个函数可能会对数据库性能产生一些影响,因为它需要在短时间内访问谓词锁管理器的共享状态。 @@ -406,7 +405,7 @@ integer - 返回当前嵌套层次的PostgreSQL触发器(如果没有调用则为 0,直接或间接,从一个触发器内部开始)。 + 返回PostgreSQL触发器的当前嵌套层级(如果不是从触发器内部直接或间接调用,则为 0)。 @@ -419,7 +418,7 @@ name - 返回会话用户名. + 返回会话用户名。 @@ -449,20 +448,7 @@ - - - - version - - version () - text - - - 返回描述PostgreSQL服务器的版本的字符串。 - 你还可以从 中获得此信息,或者对于机器可读的版本,使用。 - 软件开发人员可以使用server_version_num(从8.2起可用)或,而不是解析文本版本。 - - + @@ -470,17 +456,12 @@ - current_catalogcurrent_rolecurrent_schemacurrent_usersession_useruserSQL里有特殊的语法地位: 它们被调用时结尾不要跟着圆括号。 - 在 PostgreSQL 中,圆括号可以有选择性地被用于current_schema,但是不能和其他的一起用。 + current_catalogcurrent_rolecurrent_schemacurrent_usersession_useruserSQL中具有特殊语法:调用时不得在后面加圆括号。在 PostgreSQL 中,current_schema可以选择加圆括号,其他函数则不可以。 - session_user通常是发起当前数据库连接的用户,不过超级用户可以用修改这个设置。 - current_user是用于权限检查的用户标识。通常, 它总是等于会话用户,但是可以被改变。 - 它也会在函数执行的过程中随着属性SECURITY DEFINER的改变而改变。 - 在 Unix 的说法里,那么会话用户是真实用户,而当前用户是有效用户。 - current_role以及usercurrent_user的同义词(SQL标准在current_rolecurrent_user之间做了区分,但PostgreSQL不区分,因为它把用户和角色统一成了一种实体)。 + session_user通常是发起当前数据库连接的用户,但超级用户可以用修改此设置。current_user是用于权限检查的用户标识,通常等于会话用户,但可以用更改。在执行具有SECURITY DEFINER属性的函数期间,它也会改变。用 Unix 的术语来说,会话用户是真实用户,当前用户是有效用户current_roleusercurrent_user的同义词。(SQL 标准区分current_rolecurrent_user,但PostgreSQL不区分,因为它将用户和角色统一为同一种实体。) @@ -490,18 +471,12 @@ 访问权限查询函数 - privilege - querying + 权限 + 查询 - 列出那些允许编程查询对象访问权限的函数。参阅获取更多有关权限的信息。 - 在这些函数中,可以通过名称或OID (pg_authid.oid)指定被查询权限的用户,或者如果名称被指定为public,则检查PUBLIC伪角色的权限。 - 同样,user参数可以完全省略,在这种情况下,假设为current_user。被查询的对象也可以通过名称或OID来指定。 - 通过名称指定时,可以包含相关的模式名称。感兴趣的访问权限由一个文本字符串指定,它必须计算为对象类型的一个适当的权限关键字(例如,SELECT)。 - 还可以将 WITH GRANT OPTION添加到权限类型中,以测试该权限是否由授予选项持有。 - 同样,可以用逗号分隔列出多个权限类型,在这种情况下,如果所列出的权限中有任何一个被持有,结果将为真。 - (权限字符串的大小写不重要,权限名之间允许有额外的空格,但在权限名中不允许。)一些示例: + 列出了允许以编程方式查询对象访问权限的函数。(关于权限的更多信息,请参见。)在这些函数中,可以通过名称或 OID(pg_authid.oid)指定要查询权限的用户;如果名称为public,则检查 PUBLIC 伪角色的权限。也可以完全省略user参数,此时使用current_user。要查询的对象也可以通过名称或 OID 指定。通过名称指定时,如适用,可以包含模式名。所需访问权限由文本字符串指定,其值必须为适用于该对象类型的权限关键字之一(例如SELECT)。还可以在权限类型后附加WITH GRANT OPTION,以检查是否拥有该权限及其授予选项。也可以用逗号分隔列出多个权限类型;只要拥有列出的任一权限,结果就为真。(权限字符串不区分大小写,权限名之间允许有额外的空白,但权限名内部不允许。)例如: SELECT has_table_privilege('myschema.mytable', 'select'); SELECT has_table_privilege('joe', 'mytable', 'INSERT, SELECT WITH GRANT OPTION'); @@ -538,9 +513,7 @@ SELECT has_table_privilege('joe', 'mytable', 'INSERT, SELECT WITH GRANT OPTION') boolean - 用户是否对表的任何列有权限? - 如果对整个表持有权限,或者对至少一个列有列级的权限授予,则会成功。 - 允许的权限类型为SELECT, INSERT,UPDATE, 和 REFERENCES + 用户是否对表的至少一列具有权限?如果拥有整个表的权限,或至少一列获得了该权限的列级授权,则返回真。允许的权限类型为SELECTINSERTUPDATEREFERENCES @@ -591,7 +564,7 @@ SELECT has_table_privilege('joe', 'mytable', 'INSERT, SELECT WITH GRANT OPTION') boolean - 用户是否拥有外部数据包装的权限?唯一允许的权限类型是USAGE。 + 用户是否具有外部数据包装器权限?唯一允许的权限类型为USAGE @@ -695,7 +668,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); boolean - 用户是否有顺序权限?允许的权限类型有USAGE, SELECT, 和UPDATE。 + 用户是否具有序列权限?允许的权限类型为USAGESELECTUPDATE @@ -776,11 +749,11 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); boolean - 用户对角色有权限吗?允许的权限类型有MEMBERUSAGESET。 + 用户是否具有角色权限?允许的权限类型为MEMBERUSAGESETMEMBER表示对该角色的直接或间接成员资格,而不考虑由此授予的具体权限。 USAGE表示该角色的权限是否无需执行SET ROLE即可立即使用,而SET表示是否可以使用SET ROLE命令切换到该角色。 任一权限类型后面都可以附加WITH ADMIN OPTIONWITH GRANT OPTION,用于测试是否持有 ADMIN 权限(这六种写法测试的都是同一件事)。 - 此函数不允许特殊情况下将user设置为public,因为PUBLIC伪角色永远不能成为真实角色的成员。 + 此函数不允许将user设置为public这一特殊情况,因为 PUBLIC 伪角色永远不能成为实际角色的成员。 @@ -794,7 +767,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); boolean - 在当前用户和当前环境的上下文之中,指定表的行级安全是活动的吗? + 在当前用户和当前环境的上下文中,指定表的行级安全性是否生效? @@ -802,8 +775,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); - 显示了aclitem类型的可用操作符,它是访问权限的目录表示。 - 有关如何读取访问权限值的信息,请参阅 。 + 列出了aclitem类型可用的操作符;该类型是访问权限在系统目录中的表示形式。有关如何解读访问权限值的信息,请参见 @@ -836,8 +808,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); boolean - aclitem相等吗?(注意,aclitem类型缺少比较操作符的通常集合;它只有相等。 - 反而言之,aclitem数组只能进行相等比较。) + 两个aclitem是否相等?(注意,aclitem类型没有通常的整套比较操作符,而只支持相等比较。因此,aclitem数组也只能进行相等比较。) 'calvin=r*w/hobbes'::aclitem = 'calvin=r*w*/hobbes'::aclitem @@ -854,7 +825,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); boolean - 数组是否包含指定的权限?(如果有一个数组条目与aclitem的被授权人和授予人相匹配,并且至少具有权限的指定集,则此选项为真。) + 数组是否包含指定的权限?(如果数组中存在一个条目,其被授权者和授权者与该aclitem相同,且至少包含指定的全部权限,则返回真。) '{calvin=r*w/hobbes,hobbes=r*w*/postgres}'::aclitem[] @> 'calvin=r*/hobbes'::aclitem @@ -866,7 +837,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute');
- 显示了一些额外的函数来管理aclitem类型。 + 列出了一些用于管理aclitem类型的其他函数。 @@ -898,23 +869,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); aclitem[] - 构造一个aclitem数组,保存属于具有OID ownerId的角色的对象类型type的默认访问权限。 - 这表示当对象的ACL条目为空时将假定的访问权限。(默认访问权限在中描述。) - type参数必须是以下之一: - 'c'表示COLUMN, - 'r'表示TABLE和类似表的对象, - 's'表示SEQUENCE, - 'd'表示DATABASE, - 'f'表示FUNCTIONPROCEDURE, - 'l'表示LANGUAGE, - 'L'表示LARGE OBJECT, - 'n'表示SCHEMA, - 'p'表示PARAMETER, - 't'表示TABLESPACE, - 'F'表示FOREIGN DATA WRAPPER, - 'S'表示FOREIGN SERVER, - 或 - 'T'表示TYPEDOMAIN。 + 构造一个aclitem数组,保存类型为type、属于 OID 为ownerId的角色的对象的默认访问权限。当对象的ACL条目为空值时,会采用这些访问权限。(默认访问权限见。)type参数必须为以下值之一:'c' 表示COLUMN,'r' 表示TABLE和类似表的对象,'s' 表示SEQUENCE,'d' 表示DATABASE,'f' 表示FUNCTIONPROCEDURE,'l' 表示LANGUAGE,'L' 表示LARGE OBJECT,'n' 表示SCHEMA,'p' 表示PARAMETER,'t' 表示TABLESPACE,'F' 表示FOREIGN DATA WRAPPER,'S' 表示FOREIGN SERVER,'T' 表示TYPEDOMAIN @@ -931,9 +886,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); is_grantableboolean ) - 以行集的形式返回aclitem数组。如果受让人是伪角色PUBLIC,则在grantee列中用0表示。 - 每个被授予的权限都表示为SELECT, INSERT等。 - 注意,每个权限被分割成单独的一行,因此在privilege_type列中只出现一个关键字。 + 以行集的形式返回aclitem数组。如果被授权者是伪角色 PUBLIC,则在grantee列中用零表示。每项授予的权限表示为SELECTINSERT等(完整列表见)。注意,每项权限都会拆成单独的一行,因此privilege_type列中只会出现一个关键字。 @@ -950,7 +903,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); aclitem - 使用给定的属性构造 aclitem 。 + 使用给定的属性构造aclitemprivileges是以逗号分隔的权限名列表,例如SELECTINSERT等,列出的所有权限都会设置在结果中。(权限字符串不区分大小写,权限名之间允许有额外的空白,但权限名内部不允许。) @@ -964,14 +917,9 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); 模式可见性查询函数 - 展示了决定是否一个特定对象在当前模式搜索路径中可见的函数。 - 例如,如果一个表所在的模式在当前搜索路径中并且在它之前没有出现过相同的名字,这个表就被说是可见的。 - 这等价于在语句中表可以被用名称引用但不加显式的模式限定。因此,要列出所有可见表的名字: - + 列出了判断某个特定对象是否可见的函数,其判断依据是当前模式搜索路径。例如,如果表所在的模式位于搜索路径中,并且在搜索路径的更前面没有同名表,就称该表可见。这等价于说,可以只通过表名引用该表,而不必显式地用模式限定。因此,要列出所有可见表的名称: SELECT relname FROM pg_class WHERE pg_table_is_visible(oid); - - 对于函数和操作符,如果路径前面没有相同名称和参数数据类型的对象,那么搜索路径中的对象就是可见的。 - 对于操作符类和操作符族,要考虑名称和关联的索引访问方法。 +对于函数和操作符,只要搜索路径中更靠前的位置没有对象具有与被检查对象相同的名称和参数数据类型,就称被检查对象可见。对于操作符类和操作符族,会同时考虑名称及关联的索引访问方法。 @@ -1110,7 +1058,7 @@ SELECT relname FROM pg_class WHERE pg_table_is_visible(oid); boolean - 文本搜索配置在搜索路径可见吗? + 全文检索配置是否在搜索路径中可见? @@ -1123,7 +1071,7 @@ SELECT relname FROM pg_class WHERE pg_table_is_visible(oid); boolean - 文本搜索字典在搜索路径可见吗? + 全文检索词典是否在搜索路径中可见? @@ -1136,7 +1084,7 @@ SELECT relname FROM pg_class WHERE pg_table_is_visible(oid); boolean - 文本搜索解析器在搜索路径中可见吗? + 全文检索解析器是否在搜索路径中可见? @@ -1149,7 +1097,7 @@ SELECT relname FROM pg_class WHERE pg_table_is_visible(oid); boolean - 文本搜索模板在搜索路径可见吗? + 全文检索模板是否在搜索路径中可见? @@ -1170,11 +1118,10 @@ SELECT relname FROM pg_class WHERE pg_table_is_visible(oid);
- 所有这些函数都要求用对象 OID 来标识将被检查的对象。如果你想用名称来测试一个对象,使用 OID 别名类型(regclassregtyperegprocedureregoperatorregconfigregdictionary)将会很方便。例如: - + 所有这些函数都需要用对象 OID 标识要检查的对象。如果想按名称测试对象,使用 OID 别名类型会很方便(regclassregtype, + regprocedureregoperatorregconfig,或regdictionary),例如: SELECT pg_type_is_visible('myschema.widget'::regtype); - - 注意以这种方式测试一个非模式限定的类型名没什么意义 — 如果该名称完全能被识别,它必须是可见的。 +注意,用这种方式测试不带模式限定的类型名并没有太大意义:只要该名称能够被识别,它就必然可见。 @@ -1218,6 +1165,26 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); + + + + pg_basetype + + pg_basetype ( regtype ) + regtype + + + 返回由类型 OID 标识的域的基础类型 OID。如果参数是非域类型的 OID,则原样返回该参数。如果参数不是有效的类型 OID,则返回 NULL。如果存在域依赖链,则递归查找,直到找到基础类型。 + + + 假设执行了CREATE DOMAIN mytext AS text: + + + pg_basetype('mytext'::regtype) + text + + + @@ -1264,7 +1231,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); 返回一组记录,描述存在于PostgreSQL系统目录中的外键关系。 fktable 列包含引用目录的名称,fkcols列包含引用列的名称。 类似地,pktable列包含被引用目录的名称,而pkcols列包含被引用列的名称。 - 如果is_array为真,则最后一个引用列是一个数组,其每个元素都应该与引用目录中的某个条目匹配。 + 如果is_array为真,则最后一个引用列是一个数组,其每个元素都应该与被引用目录中的某个条目匹配。 如果is_opt为真,则允许引用列包含零而不是有效引用。 @@ -1278,7 +1245,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 重构为了约束的创建命令。(这是一个反编译的重构,而不是命令的原始文本。) + 重建约束的创建命令。(这是反编译重建的结果,并非命令的原始文本。) @@ -1291,8 +1258,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 反编译存储在系统目录中的表达式的内部形式,例如列的默认值。 - 如果表达式可能包含变量,则指定它们所指向的关系的OID作为第二个参数;如果没有预期的变量,传递0就可以了。 + 反编译存储在系统目录中的表达式的内部形式,例如列的默认值。如果表达式可能包含 Var 节点,请将它们所引用的关系的 OID 指定为第二个参数;如果预计不含 Var 节点,传入零即可。 @@ -1305,8 +1271,8 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 重构为了函数或过程的创建命令。(这是一个反编译的重构,而不是命令的原始文本。) - 结果是一个完整的CREATE OR REPLACE FUNCTIONCREATE OR REPLACE PROCEDURE语句。 + 重建函数或过程的创建命令。(这是反编译重建的结果,并非命令的原始文本。) + 结果是一条完整的CREATE OR REPLACE FUNCTIONCREATE OR REPLACE PROCEDURE语句。 @@ -1319,7 +1285,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 重新构造函数或过程的参数列表,以其在 CREATE FUNCTION里面需要出现的形式(包括默认值)。 + 重建函数或过程的参数列表,采用其在CREATE FUNCTION中应有的形式(包括默认值)。 @@ -1332,7 +1298,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 重新构造标识函数或过程所需的参数列表,以其应出现在ALTER FUNCTION等命令中的形式。这个表单省略默认值。 + 重建标识函数或过程所需的参数列表,采用其在ALTER FUNCTION等命令中应有的形式。这种形式省略默认值。 @@ -1345,7 +1311,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 重构函数的RETURNS子句,以其需要出现在CREATE FUNCTION中的形式。对于过程,返回NULL。 + 重建函数的RETURNS子句,采用其在CREATE FUNCTION中应有的形式。对于过程,返回NULL @@ -1358,7 +1324,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 重构针对索引的创建命令。(这是一个反编译的重构,而不是命令的原始文本。)如果提供了column而且不为零,则只重构该列的定义。 + 重建索引的创建命令。(这是反编译重建的结果,并非命令的原始文本。)如果提供了column而且不为零,则只重建该列的定义。 @@ -1376,11 +1342,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); baredesc text ) - 返回一组描述服务器识别的SQL关键字的记录。word列包含关键字。 - catcode列包含一个类别代码:U表示无保留关键字,C表示可以是列名的关键字,T表示可以是类型或函数名的关键字,或者R表示完全保留关键字。 - 如果关键字可以在SELECT列表中用作bare列标签,则barelabel列包含true,或者false,如果它只能在AS之后使用。 - catdesc列包含可能本地化字符串,描述关键字的类别。 - baredesc列包含可能本地化的字符串,描述关键字的列标签状态。 + 返回描述服务器所识别 SQL 关键字的一组记录。word列包含关键字。catcode列包含类别代码:U表示非保留关键字,C表示可用作列名的关键字,T表示可用作类型名或函数名的关键字,R表示完全保留的关键字。如果关键字可以在SELECT列表中用作列标签,barelabel列为true;如果只能在AS之后使用,则为falsecatdesc列包含描述关键字类别的字符串,该字符串可能已被本地化。baredesc列包含描述关键字列标签状态的字符串,该字符串可能已被本地化。 @@ -1392,8 +1354,20 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 重构分区约束的定义。 - (这是反编译得到的重构结果,而不是命令的原始文本。) + 重建分区约束的定义。(这是反编译重建的结果,并非命令的原始文本。) + + + + + + + pg_get_partkeydef + + pg_get_partkeydef ( table oid ) + text + + + 重建分区表的分区键定义,采用其在CREATE TABLEPARTITION BY子句中的形式。(这是反编译重建的结果,并非命令的原始文本。) @@ -1406,7 +1380,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text - 重构针对规则的创建命令。(这是一个反编译的重构,而不是命令的原始文本。) + 重建规则的创建命令。(这是反编译重建的结果,并非命令的原始文本。) @@ -1421,15 +1395,15 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); 返回与列相关联的序列名称,如果没有序列与该列相关联则返回NULL。 如果列是标识列,则关联序列是在内部为该列创建的序列。 - 对于使用一种串行类型(serial, smallserial, bigserial)创建的列,它是为该串行列定义创建的序列。 + 对于使用一种 serial 类型(serial, smallserial, bigserial)创建的列,它是为该 serial 列定义创建的序列。 在后一种情况下,可以使用ALTER SEQUENCE OWNED BY修改或删除关联。 - (这个函数可能应该被称为pg_get_owned_sequence;它的当前名称反映了它在历史上曾与串行类型的列一起使用。) + (这个函数可能应该被称为pg_get_owned_sequence;它的当前名称反映了它在历史上曾与 serial 类型的列一起使用。) 第一个参数是具有可选模式的表名,第二个参数是列名。 由于第一个参数可能包含模式名和表名,因此按照通常的SQL规则解析它,这意味着默认情况下它是小写的。 第二个参数只是一个列名,按照字面来处理,因此保留了它的大小写。结果经过了适当的格式化,可以传递给序列函数(参见)。 - 典型的用法是读取序列的当前值以获取标识或串行列,示例如下: + 典型用法是读取标识列或 serial 列所用序列的当前值,例如: SELECT currval(pg_get_serial_sequence('sometable', 'id')); @@ -1445,7 +1419,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); text - 重构针对扩展统计对象的创建命令。(这是一个反编译的重构,而不是命令的原始文本。) + 重建扩展统计对象的创建命令。(这是反编译重建的结果,并非命令的原始文本。) @@ -1458,7 +1432,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); text - 重构针对触发器的创建命令。(这是一个反编译的重构,而不是命令的原始文本。) + 重建触发器的创建命令。(这是反编译重建的结果,并非命令的原始文本。) @@ -1484,7 +1458,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); text - 重构针对视图或物化视图的SELECT命令。(这是一个反编译的重构,而不是命令的原始文本。) + 重建定义视图或物化视图的SELECT命令。(这是反编译重建的结果,并非命令的原始文本。) @@ -1494,8 +1468,8 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); text - 重构针对视图或物化视图的底层SELECT命令。(这是一个反编译的重构,而不是命令的原始文本。) - 在这种形式的函数中,总是启用美观打印,并对长行进行换行,以尽量使它们小于指定的列数。 + 重建定义视图或物化视图的SELECT命令。(这是反编译重建的结果,并非命令的原始文本。) + 这种形式始终启用美化输出,并将长行折行,尽量使每行长度小于指定列数。 @@ -1505,7 +1479,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); text - 根据视图的文本名称而不是它的OID,重构针对视图或物化视图的底层SELECT命令。(这是弃用;请使用OID变体。) + 根据视图的文本名称而不是其 OID,重建定义视图或物化视图的SELECT命令。(此形式已弃用;请使用 OID 变体。) @@ -1518,7 +1492,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); boolean - 测试一个索引列是否具有命名属性。列出了常用索引列属性。 + 测试一个索引列是否具有指定名称的属性。列出了常用索引列属性。 (注意,扩展访问方法可以为其索引定义额外的属性名。) 如果属性名未知或不适用于特定对象,或者OID或列号不能识别有效的对象,则返回NULL @@ -1533,7 +1507,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); boolean - 测试一个索引是否具有命名属性。列出了常用的索引属性。 + 测试一个索引是否具有指定名称的属性。列出了常用的索引属性。 (注意,扩展访问方法可以为其索引定义额外的属性名。) 如果属性名未知或不适用于特定对象,或者OID不能识别有效的对象,则返回NULL @@ -1548,7 +1522,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); boolean - 测试索引访问方法是否具有命名属性。访问方法属性如所示。 + 测试索引访问方法是否具有指定名称的属性。访问方法属性如所示。 如果属性名未知或不适用于特定对象,或者OID不能识别有效的对象,则返回NULL @@ -1577,9 +1551,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); text[] - 返回与给定GUC相关联的标志数组,如果不存在则返回NULL。 - 如果GUC存在但没有要显示的标志,则结果为空数组。 - 仅公开列出在中最有用的标志。 + 返回与给定 GUC 关联的标志数组;如果该 GUC 不存在,则返回NULL。如果 GUC 存在但没有要显示的标志,则结果为空数组。此函数仅公开中列出的最有用的标志。 @@ -1592,9 +1564,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); setof oid - 返回具有存储在指定表空间中的对象的数据库的OIDs集。 - 如果这个函数返回了任何行,那么表空间就不是空的,且不能被删除。 - 要识别填充表空间的特定对象,需要连接到由pg_tablespace_databases标识的数据库,并查询它们的pg_class目录。 + 返回在指定表空间中存储了对象的数据库 OID 集合。如果此函数返回任何行,则说明该表空间不为空,不能删除。要查看存放在该表空间中的具体对象,需要连接到pg_tablespace_databases标识的数据库,并查询它们的pg_class系统目录。 @@ -1620,23 +1590,11 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); regtype - 返回传递值给它的数据类型的OID。这对于故障排除或动态构造SQL查询很有帮助。 - 函数声明为返回regtype,它是一个OID别名类型(see ); - 这意味着,为了比较,它与OID相同,但显示为类型名。 + 返回所传入值的数据类型的 OID。这有助于排查问题或动态构造 SQL 查询。函数声明的返回类型是regtype,它是一种 OID 别名类型(参见);这意味着它在比较时与 OID 相同,但显示为类型名。 - 例如: - -SELECT pg_typeof(33); - pg_typeof ------------ - integer - -SELECT typlen FROM pg_type WHERE oid = pg_typeof(33); - typlen --------- - 4 - + pg_typeof(33) + integer @@ -1649,8 +1607,9 @@ SELECT typlen FROM pg_type WHERE oid = pg_typeof(33); text - 返回传递值给它的排序规则的名称。如果需要,该值会被引号括起来,并使用模式限定。 - 如果没有为参数表达式派生排序规则,则返回NULL。如果参数不是可排序数据类型,则会引发错误。 + 返回传入值的排序规则名称。必要时会为返回的名称加上引号和模式限定。 + 如果无法为参数表达式推导出排序规则,则返回NULL。 + 如果参数不属于支持排序规则的数据类型,则报错。 COLLATION FOR ('foo'::text) @@ -1672,7 +1631,7 @@ SELECT typlen FROM pg_type WHERE oid = pg_typeof(33); 将文本关系名转换为它的OID。通过将字符串类型转换为regclass可以得到类似的结果(参见); - 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。 @@ -1699,8 +1658,8 @@ SELECT typlen FROM pg_type WHERE oid = pg_typeof(33); regcollation - 将文本排序规则名称转换为它的OID。通过将字符串类型转换为regcollation(参见)可以得到类似的结果; - 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 将文本排序规则名称转换为它的OID。通过将字符串类型转换为regcollation(参见)可以得到类似的结果; + 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。 @@ -1713,8 +1672,8 @@ SELECT typlen FROM pg_type WHERE oid = pg_typeof(33); regnamespace - 将文本模式名转换为它的OID。通过将字符串转换为regnamespace类型(参见)可以得到类似的结果; - 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 将文本模式名转换为它的OID。通过将字符串转换为regnamespace类型(参见)可以得到类似的结果; + 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。 @@ -1727,8 +1686,8 @@ SELECT typlen FROM pg_type WHERE oid = pg_typeof(33); regoper - 将文本操作符名称转换为它的OID。通过将字符串类型转换为regoper(参见)可以得到类似的结果; - 但是,如果找不到名称或名称有多义性,该函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 将文本操作符名称转换为它的OID。通过将字符串类型转换为regoper(参见)可以得到类似的结果; + 但是,如果找不到名称或名称有多义性,该函数将返回NULL而不会抛出错误。 @@ -1741,8 +1700,8 @@ SELECT typlen FROM pg_type WHERE oid = pg_typeof(33); regoperator - 将文本操作符名称(带有参数类型)转换为其OID。通过将字符串转换为regoperator类型(参见节)可以得到类似的结果; - 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 将文本操作符名称(带有参数类型)转换为其OID。通过将字符串转换为regoperator类型(参见节)可以得到类似的结果; + 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。 @@ -1755,8 +1714,8 @@ SELECT typlen FROM pg_type WHERE oid = pg_typeof(33); regproc - 将文本函数或过程名转换为其OID。通过将字符串转换为regproc类型(参见)可以得到类似的结果; - 但是,如果找不到名称或名称有多义性,该函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 将文本函数或过程名转换为其OID。通过将字符串转换为regproc类型(参见)可以得到类似的结果; + 但是,如果找不到名称或名称有多义性,该函数将返回NULL而不会抛出错误。 @@ -1770,7 +1729,7 @@ SELECT typlen FROM pg_type WHERE oid = pg_typeof(33); 将文本函数或过程名(带有参数类型)转换为其OID。通过将字符串类型转换为regprocedure可以得到类似的结果(参见); - 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。 @@ -1784,12 +1743,12 @@ SELECT typlen FROM pg_type WHERE oid = pg_typeof(33); 将文本角色名转换为它的OID。通过将字符串类型转换为regrole可以得到类似的结果(参见); - 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。 - + to_regtype @@ -1797,8 +1756,26 @@ SELECT typlen FROM pg_type WHERE oid = pg_typeof(33); regtype - 将文本类型名转换为它的OID。通过将字符串类型转换为regtype可以得到类似的结果(参见); - 但是,如果没有找到名称,这个函数将返回NULL而不会抛出错误。与强制转换不同的是,它不接受数字OID作为输入。 + 解析文本字符串,从中提取可能的类型名,并将该名称转换为类型 OID。字符串中的语法错误会导致报错;但如果字符串是语法有效的类型名,只是在系统目录中找不到该类型,结果就是 NULL。将字符串转换为 regtype 类型也能得到类似的结果(参见 ),区别在于类型转换会在找不到名称时报错。 + + + + + + to_regtypemod + + to_regtypemod ( text ) + integer + + + 解析文本字符串,从中提取可能的类型名称,并转换其类型修饰符(如果有)。字符串中的语法错误会引发错误;但如果字符串是语法有效的类型名称,只是在系统目录中找不到,则结果为NULL。如果没有类型修饰符,则结果为-1。 + + + to_regtypemod可以与结合,为生成适当的输入,从而将表示类型名称的字符串转换为规范形式。 + + + format_type(to_regtype('varchar(32)'), to_regtypemod('varchar(32)')) + character varying(32) @@ -1806,10 +1783,10 @@ SELECT typlen FROM pg_type WHERE oid = pg_typeof(33); - 大多数重构(反编译)数据库对象的函数都有一个可选的 pretty标志,如果为true,结果将被pretty-printed。 - 美观打印会抑制不必要的圆括号,并为易读性增加空格。 - 美观打印的格式可读性更好,但是默认格式更有可能被PostgreSQL的未来版本以同样的方式解释; - 因此,避免为转储目的使用美观打印的输出。为pretty参数传递false会产生与省略参数相同的结果。 + 大多数重建(反编译)数据库对象的函数都有一个可选的pretty标志;若为true,则对结果进行美化输出。 + 美化输出会省略不必要的圆括号,并增加空白以提高可读性。 + 美化后的格式更易读,但默认格式更有可能被PostgreSQL的未来版本以同样的方式解释,因此用于转储时应避免美化输出。 + 为pretty参数传入false与省略该参数的结果相同。 @@ -1858,19 +1835,20 @@ SELECT typlen FROM pg_type WHERE oid = pg_typeof(33); distance_orderable - 列能否通过一个distance操作符(例如ORDER BY col <-> constant)有序地扫描? + + 能否按距离操作符的结果有序地扫描该列,例如ORDER BY col <-> constant returnable - 列值是否可以通过一次只用索引扫描返回? + 列值是否可以通过一次仅索引扫描返回? search_array - 列是否天然支持col = ANY(array)搜索? + 列是否原生支持col = ANY(array)搜索? @@ -1885,7 +1863,7 @@ SELECT typlen FROM pg_type WHERE oid = pg_typeof(33);
- 索引性质 + 索引属性 @@ -1926,7 +1904,7 @@ SELECT typlen FROM pg_type WHERE oid = pg_typeof(33);
- 索引访问方法性质 + 索引访问方法属性 @@ -1987,15 +1965,20 @@ SELECT typlen FROM pg_type WHERE oid = pg_typeof(33); EXPLAIN - 带有此标志的参数包含在EXPLAIN (SETTINGS)命令中。 + 带有此标志的参数会在EXPLAIN (SETTINGS)命令的输出中显示。 NO_SHOW_ALL - 具有此标志的参数将被排除在SHOW ALL命令之外。 + 带有此标志的参数不会在SHOW ALL命令的输出中显示。 + NO_RESET + 带有此标志的参数不支持RESET命令。 + + + NO_RESET_ALL 具有此标志的参数将被排除在RESET ALL命令之外。 @@ -2019,16 +2002,15 @@ SELECT typlen FROM pg_type WHERE oid = pg_typeof(33); - 对象信息和定位函数 + 对象信息和寻址函数 - 列出了与数据库对象 - 标识和定位有关的函数。 + 列出了与数据库对象标识和寻址有关的函数。
- 对象信息和定位函数 + 对象信息和寻址函数 @@ -2044,6 +2026,19 @@ SELECT typlen FROM pg_type WHERE oid = pg_typeof(33); + + + + pg_get_acl + + pg_get_acl ( classid oid, objid oid, objsubid integer ) + aclitem[] + + + 返回由系统目录 OID、对象 OID 和子对象 ID 指定的数据库对象的ACL。对于未定义的对象,此函数返回NULL值。 + + + @@ -2053,9 +2048,7 @@ SELECT typlen FROM pg_type WHERE oid = pg_typeof(33); text - 返回由目录OID、对象OID和子对象ID(例如表中的列号)标识的数据库对象的文本描述;当引用整个对象时,子对象ID为0)。 - 这个描述是人类可读的,并且可以根据服务器配置进行翻译。这对于决定pg_depend目录中引用的对象的标识特别有用。 - 此函数对于未定义的对象返回NULL值 + 返回数据库对象的文本描述,对象由系统目录 OID、对象 OID 和子对象 ID 指定(例如表中的列号;引用整个对象时,子对象 ID 为零)。该描述供人阅读,并可能根据服务器配置被翻译。这对于确定pg_depend系统目录中所引用对象的标识尤其有用。对于未定义的对象,此函数返回NULL @@ -2072,13 +2065,7 @@ SELECT typlen FROM pg_type WHERE oid = pg_typeof(33); identitytext ) - 返回包含足够信息的行以唯一标识由目录OID、对象OID和子对象ID指定的数据库对象。 - 这些信息是为了机器可读的,永远不会被翻译。 - type标识数据库对象的类型; - schema是对象所属的模式名,NULL表示不属于模式的对象类型; - name是对象的名称,如果有必要,用引号括起来,如果名称(随着模式名称,如果相关)足以唯一地标识对象,否则为NULL; - identity是完整的对象标识,其精确格式依赖于对象类型,格式中的每个名称都是模式限定的,并在必要时用引号括起来。 - 未定义的对象由NULL值标识。 + 返回一行,其中包含足以唯一标识数据库对象的信息,该对象由系统目录 OID、对象 OID 和子对象 ID 指定。这些信息供机器读取,永远不会被翻译。type标识数据库对象的类型;schema是对象所属的模式名,对于不属于模式的对象类型则为NULL;如果对象名(以及适用时的模式名)足以唯一标识该对象,name就是对象名,并在必要时加引号,否则为NULLidentity是完整的对象标识,其具体格式取决于对象类型,格式中的每个名称都会根据需要加上模式限定和引号。未定义的对象以NULL值标识。 @@ -2094,10 +2081,7 @@ SELECT typlen FROM pg_type WHERE oid = pg_typeof(33); object_argstext[] ) - 返回包含足够信息的行以唯一标识由目录OID、对象OID和子对象ID指定的数据库对象。 - 返回的信息独立于当前服务器,也就是说,它可以用于标识另一个服务器中具有相同名称的对象。 - type标识数据库对象的类型;object_namesobject_args是文本数组,它们一起构成对对象的引用。 - 这三个值可以传递给pg_get_object_address以获得对象的内部地址。 + 返回一行,其中包含足以唯一标识数据库对象的信息,该对象由系统目录 OID、对象 OID 和子对象 ID 指定。返回的信息与当前服务器无关,也就是说,它也能用于标识另一台服务器上名称相同的对象。type标识数据库对象的类型;object_namesobject_args是文本数组,共同构成对该对象的引用。将这三个值传给pg_get_object_address可以获得对象的内部地址。 @@ -2113,18 +2097,37 @@ SELECT typlen FROM pg_type WHERE oid = pg_typeof(33); objsubidinteger ) - 返回包含足够信息的行以唯一标识由类型代码、对象名称和参数数组指定的数据库对象。 - 返回的值将在系统目录中使用,例如pg_depend; - 它们可以传递给其他系统函数,比如 pg_describe_objectpg_identify_object。 - classid是包含该对象的系统目录的OID;objid是对象本身的OID, objsubid是子对象的ID,如果没有则为零。 - 这个函数是pg_identify_object_as_address的反向函数。 - 未定义的对象以NULL值标识。 + 返回一行,其中包含足以唯一标识数据库对象的信息,该对象由类型代码、对象名称数组和参数数组指定。返回的值就是pg_depend等系统目录中使用的值;它们可以传给pg_describe_objectpg_identify_object等其他系统函数。classid是包含该对象的系统目录的 OID;objid是对象自身的 OID;objsubid是子对象 ID,没有子对象时为零。此函数执行pg_identify_object_as_address的逆操作。未定义的对象以NULL值标识。
+ + pg_get_acl可用于检索和检查与数据库对象关联的权限,而无需查看特定目录。 + 例如,若要检索当前数据库中对象上已授予的全部权限: + +postgres=# SELECT + (pg_identify_object(s.classid,s.objid,s.objsubid)).*, + pg_catalog.pg_get_acl(s.classid,s.objid,s.objsubid) AS acl +FROM pg_catalog.pg_shdepend AS s +JOIN pg_catalog.pg_database AS d + ON d.datname = current_database() AND + d.oid = s.dbid +JOIN pg_catalog.pg_authid AS a + ON a.oid = s.refobjid AND + s.refclassid = 'pg_authid'::regclass +WHERE s.deptype = 'a'; +-[ RECORD 1 ]----------------------------------------- +type | table +schema | public +name | testtab +identity | public.testtab +acl | {postgres=arwdDxtm/postgres,foo=r/postgres} + + + @@ -2137,7 +2140,7 @@ SELECT typlen FROM pg_type WHERE oid = pg_typeof(33); - 中展示的函数抽取注释,注释是由命令在以前存储的。如果对指定参数找不到注释,则返回空值。 + 中的函数用于提取此前通过命令存储的注释。如果找不到与指定参数对应的注释,则返回空值。 @@ -2167,7 +2170,7 @@ SELECT typlen FROM pg_type WHERE oid = pg_typeof(33); text - 返回表列的注释,该注释由该表的OID和列号指定。(obj_description不能用于表的列,因为列没有自己的oid。) + 返回表列的注释,列由所属表的 OID 和列号指定。(obj_description不能用于表列,因为列没有自身的 OID。) @@ -2180,8 +2183,7 @@ SELECT typlen FROM pg_type WHERE oid = pg_typeof(33); text - 返回OID指定的数据库对象的注释和包含该对象的系统目录的名称。 - 例如,obj_description(123456, 'pg_class')将检索OID为123456的表的注释。 + 返回数据库对象的注释,对象由其 OID 和所在系统目录的名称指定。例如,obj_description(123456, 'pg_class')会获取 OID 为 123456 的表的注释。 @@ -2191,8 +2193,7 @@ SELECT typlen FROM pg_type WHERE oid = pg_typeof(33); text - 返回仅由其OID指定的数据库对象的注释。 - 这个已被弃用(deprecated)因为无法保证oid在不同的系统目录中是唯一的;因此,可能会返回错误的注释。 + 返回仅由其 OID 指定的数据库对象的注释。此形式已弃用,因为无法保证 OID 在不同系统目录之间唯一,因而可能返回错误的注释。 @@ -2205,9 +2206,7 @@ SELECT typlen FROM pg_type WHERE oid = pg_typeof(33); text - 返回共享数据库对象的注释,该对象由其OID和包含的系统编目的名称指定。 - 这与obj_description类似,只是它用于检索共享对象(也就是数据库、角色和表空间)上的注释。 - 有些系统编目对每个集簇中的所有数据库都是全局的,其中对象的描述也全局存储。 + 返回共享数据库对象的注释,对象由其 OID 和所在系统目录的名称指定。此函数与obj_description类似,但用于获取共享对象(即数据库、角色和表空间)的注释。有些系统目录由数据库集簇中的所有数据库全局共享,其中对象的描述也全局存储。 @@ -2343,6 +2342,32 @@ SELECT typlen FROM pg_type WHERE oid = pg_typeof(33); + + + + age + + age ( xid ) + integer + + + 返回给定事务 ID 与当前事务计数器之间的事务数。 + + + + + + + mxid_age + + mxid_age ( xid ) + integer + + + 返回给定多事务 ID 与当前多事务计数器之间的多事务 ID 数。 + + + @@ -2352,7 +2377,7 @@ SELECT typlen FROM pg_type WHERE oid = pg_typeof(33); xid8 - 返回当前事务的ID。如果当前事务还没有一个ID(因为它还没有执行任何数据库更新),它将分配一个新的事务。 + 返回当前事务的ID。如果当前事务还没有一个ID(因为它还没有执行任何数据库更新),它将分配一个新的事务 ID;详见。如果在子事务中执行,它将返回顶层事务的ID;详见 @@ -2365,8 +2390,7 @@ SELECT typlen FROM pg_type WHERE oid = pg_typeof(33); xid8 - 返回当前事务的ID,如果还没有分配ID则返回NULL。 - (如果事务可能是只读的,最好使用这种变体,以避免不必要地消耗XID。) + 返回当前事务的 ID;如果尚未分配 ID,则返回NULL。(如果事务本来可能是只读的,最好使用此变体,以免不必要地消耗 XID。)如果在子事务中执行,则返回顶层事务 ID。 @@ -2379,10 +2403,7 @@ SELECT typlen FROM pg_type WHERE oid = pg_typeof(33); text - 报告最近的事务的提交状态。如果事务为最近的,系统会保留事务的提交状态,则结果是 in progresscommittedaborted。 - 如果该事务的时间足够久,并且系统中没有对该事务的引用,而且提交状态信息已经被丢弃,则结果为NULL。 - 应用可以使用此函数,例如,确定在进行COMMIT时,应用程序和数据库服务器断开连接后,它们的事务是已提交还是中止。 - 注意,准备好的事务报告为in progress的事务;如果应用需要确定一个事务ID是否属于一个准备好的事务,则必须检查pg_prepared_xacts。 + 报告近期事务的提交状态。只要事务足够新,系统仍保留其提交状态,结果就为in progresscommittedaborted。如果事务已足够旧,系统中不再有对它的引用,且提交状态信息已被丢弃,则返回NULL。例如,在COMMIT进行过程中应用与数据库服务器断开连接时,应用可以用此函数判断事务是提交了还是中止了。注意,预备事务被报告为in progress;如果需要确定某个事务 ID 是否为预备事务,应用必须检查pg_prepared_xacts @@ -2395,7 +2416,7 @@ SELECT typlen FROM pg_type WHERE oid = pg_typeof(33); pg_snapshot - 返回当前snapshot,显示哪些事务 ID正在进行中的数据结构。 + 返回当前快照,即显示哪些事务 ID 正在进行中的数据结构。快照中只包含顶层事务 ID,不显示子事务 ID;详见 @@ -2447,8 +2468,7 @@ SELECT typlen FROM pg_type WHERE oid = pg_typeof(33); boolean - 根据此快照,给定的事务ID是否可见(visible)(也就是说,它是否在快照拍摄之前完成)? - 注意,这个函数不会给出子事务ID的正确答案。 + 根据此快照,给定的事务 ID 是否可见(即该事务是否在生成快照之前完成)?注意,此函数无法为子事务 ID(subxid)给出正确结果;详见 @@ -2496,7 +2516,7 @@ SELECT typlen FROM pg_type WHERE oid = pg_typeof(33); 内部事务 ID 类型xid是 32 位宽,每 40 亿个事务就会回卷一次(wrap around)。 - 但是,中所示的函数中,除了agemxid_agepg_get_multixact_memberspg_get_multixact_stats之外,使用的是 64 位类型xid8,它在一次安装的生命周期内不会回卷,必要时可以通过强制转换将其转换为xid;详见。 + 但是,中所示的函数中,除了agemxid_agepg_get_multixact_memberspg_get_multixact_stats之外,使用的是 64 位类型xid8,它在一次安装的生命周期内不会回卷,必要时可以通过类型转换将其转换为xid;详见。 数据类型pg_snapshot存储特定时刻事务ID可见性的信息。 其组成如所描述。pg_snapshot的文本表示形式是xmin:xmax:xip_list。 例如10:20:10,14,15表示xmin=10, xmax=20, xip_list=10, 14, 15。 @@ -2523,21 +2543,22 @@ SELECT typlen FROM pg_type WHERE oid = pg_typeof(33); xmin - 仍然处于活动状态的最低事务ID。所有小于xmin的事务 ID要么提交且可见,要么回滚并死亡。 + 仍然处于活动状态的最小事务 ID。所有小于xmin的事务 ID 要么已经提交且可见,要么已经回滚而失效。 xmax - 比最高完成的事务ID还高出一个值。所有大于或等于xmax的事务 ID到快照时还没有完成,因此不可见。 + 已完成事务中的最大事务 ID 加一。所有大于或等于xmax的事务 ID 在生成快照时尚未完成,因此不可见。 xip_list - 快照时正在进行的事务。一个事务ID为xmin <= X < xmax且不在快照时已经完成的列表中,因此根据其提交状态,该事务ID要么是可见的,要么是死的。此列表不包括子事务的事务 ID。 + 生成快照时正在进行的事务。满足xmin <= X < + xmax且不在此列表中的事务 ID 在生成快照时已经完成,因此根据其提交状态,要么可见,要么失效。此列表不包含子事务的事务 ID(subxid)。 @@ -2682,8 +2703,7 @@ SELECT typlen FROM pg_type WHERE oid = pg_typeof(33); 已提交事务信息函数 - 中的函数提供了关于过去的事务何时被提交的信息。 - 它们只在启用配置选项时提供有用的数据,并且只针对在启用该选项后提交的事务。 + 中的函数提供过去事务的提交时间信息。只有启用配置选项后,这些函数才会提供有用的数据,并且只针对启用该选项之后提交的事务。提交时间戳信息会在 vacuum 过程中定期清理。
@@ -2728,7 +2748,7 @@ SELECT typlen FROM pg_type WHERE oid = pg_typeof(33); roidentoid) - 返回事务的提交时间戳和复制起源。 + 返回事务的提交时间戳和复制源。 @@ -2744,7 +2764,7 @@ SELECT typlen FROM pg_type WHERE oid = pg_typeof(33); roidentoid ) - 返回最近提交的事务的事务ID、提交时间戳和复制源头。 + 返回最近提交事务的事务 ID、提交时间戳和复制源。 @@ -2758,9 +2778,7 @@ SELECT typlen FROM pg_type WHERE oid = pg_typeof(33); 控制数据函数 - 中所展示的函数能打印initdb期间初始化的信息,例如目录版本。 - 它们也能显示有关预写式日志和检查点处理的信息。这些信息是集簇范围内的,不与任何特定的一个数据库相关。 - 这些函数提供大致相同的信息,对于同一种来源,就像应用。 + 中的函数显示在initdb期间初始化的信息,例如系统目录版本。它们也显示有关预写式日志和检查点处理的信息。这些信息适用于整个数据库集簇,而非某个特定数据库。这些函数与应用程序从相同来源提供大部分相同的信息。
@@ -2790,7 +2808,7 @@ SELECT typlen FROM pg_type WHERE oid = pg_typeof(33); record - 返回有关当前检查点状态的信息, 如 所展示。 + 返回有关当前检查点状态的信息, 如 所展示。 @@ -2829,7 +2847,7 @@ SELECT typlen FROM pg_type WHERE oid = pg_typeof(33); record - 返回有关恢复状态的信息,如 所展示。 + 返回有关恢复状态的信息,如 所展示。 @@ -3061,6 +3079,10 @@ SELECT typlen FROM pg_type WHERE oid = pg_typeof(33); integer + + default_char_signedness + boolean +
@@ -3133,6 +3155,8 @@ SELECT typlen FROM pg_type WHERE oid = pg_typeof(33); + + @@ -3248,7 +3272,7 @@ SELECT typlen FROM pg_type WHERE oid = pg_typeof(33); WAL 记录修改过。每一行中,如果is_limit_block 为 true,则表示以下两种情况之一:(a) 该关系分支在相关 WAL 记录范围内 被截断到relblocknumber给出的长度;或者 (b) 该关系分支在 - 相关 WAL 记录范围内被创建或删除;在这些情况下, + 相关 WAL 记录范围内被创建或删除;在创建或删除的情况下, relblocknumber将为零。 @@ -3299,7 +3323,7 @@ SELECT typlen FROM pg_type WHERE oid = pg_typeof(33); 获取对象 DDL 函数 - 中显示的函数会重构各种全局数据库对象的 DDL 语句。每个函数返回一组文本行,每行一条 SQL 语句。(这是一个反编译重构,而不是命令的原始文本。) + 中显示的函数会重建各种全局数据库对象的 DDL 语句。每个函数返回一组文本行,每行一条 SQL 语句。(这是反编译重建的结果,并非命令的原始文本。) @@ -3333,10 +3357,10 @@ SELECT typlen FROM pg_type WHERE oid = pg_typeof(33); setof text - 重构指定数据库的CREATE + 重建指定数据库的CREATE DATABASE语句,随后返回用于连接数上限、模板状态和配置设置的 ALTER DATABASE语句。 - 每条语句作为单独一行返回。当pretty为 true 时,对输出进行美观打印。 + 每条语句作为单独一行返回。当pretty为 true 时,启用美化输出。 当owner为 false 时,省略OWNER子句。 当tablespace为 false 时,省略TABLESPACE子句。 @@ -3355,10 +3379,10 @@ SELECT typlen FROM pg_type WHERE oid = pg_typeof(33); setof text - 重构给定角色的CREATE ROLE + 重建给定角色的CREATE ROLE 语句以及任何ALTER ROLE ... SET 语句。每条语句作为单独一行返回。密码信息绝不会包含在输出中。 - 当pretty为 true 时,对输出进行美观打印。 + 当pretty为 true 时,启用美化输出。 当memberships为 false 时,省略用于角色成员关系的 GRANT语句。 @@ -3386,10 +3410,10 @@ SELECT typlen FROM pg_type WHERE oid = pg_typeof(33); setof text - 重构指定表空间(按 OID 或名称指定)的CREATE + 重建指定表空间(按 OID 或名称指定)的CREATE TABLESPACE语句。如果该表空间设置了选项,还会返回一条 ALTER TABLESPACE ... SET语句。 - 每条语句作为单独一行返回。当pretty为 true 时,对输出进行美观打印。 + 每条语句作为单独一行返回。当pretty为 true 时,启用美化输出。 当owner为 false 时,省略OWNER子句。 diff --git a/zh/20/func/func-json.sgml b/zh/20/func/func-json.sgml index ab49d5c8..9ad50b12 100644 --- a/zh/20/func/func-json.sgml +++ b/zh/20/func/func-json.sgml @@ -6,9 +6,13 @@ JSON函数和操作符 + + SQL/JSON + 函数和表达式 + - 本节描述: + 本节描述: @@ -18,14 +22,50 @@ - SQL/JSON路径语言 + SQL/JSON 路径语言 + + + + + SQL/JSON 查询函数 - 要了解有关SQL/JSON标准的更多信息,请参阅。有关PostgreSQL中支持的JSON类型的详细信息,见 。 + 为了在 SQL 环境中为 JSON 数据类型提供原生支持,PostgreSQL 实现了 + SQL/JSON 数据模型。该模型由项序列组成。每个项可以保存 SQL 标量值, + 以及额外的 SQL/JSON null 值,还可以保存使用 JSON 数组和对象的复合数据结构。该模型是 JSON 规范 + RFC 7159 中隐含数据模型的形式化表示。 + + + + SQL/JSON 允许你将 JSON 数据与常规 SQL 数据一同处理,并提供事务支持,包括: + + + + + 将 JSON 数据上传到数据库,并将其作为字符或二进制字符串存储在常规 SQL 列中。 + + + + + 从关系数据生成 JSON 对象和数组。 + + + + + 使用 SQL/JSON 查询函数和 SQL/JSON 路径语言表达式查询 JSON 数据。 + + + + + + + 要了解有关 SQL/JSON 标准的更多信息,请参阅。有关 + PostgreSQL 中支持的 JSON 类型的详细信息,见 + @@ -180,14 +220,13 @@ - 如果JSON输入没有匹配请求的正确结构,字段/元素/路径提取操作符返回NULL,而不是失败;例如,如果不存在这样的键或数组元素。 + 如果 JSON 输入没有匹配请求的正确结构,字段/元素/路径提取操作符会返回 NULL,而不是失败;例如,如果不存在这样的键或数组元素。 - 还有一些操作符仅适用于jsonb,如表所示。 - 第描述了如何使用这些操作符来有效地搜索索引的jsonb数据。 - + 还有一些操作符仅适用于jsonb,如所示。介绍了如何使用这些操作符有效地搜索已建立索引的jsonb数据。 +
@@ -262,7 +301,7 @@ boolean - 文本数组中的字符串是否作为顶级键或数组元素存在? + 文本数组中的任一字符串是否作为顶级键或数组元素存在? '{"a":1, "b":2, "c":3}'::jsonb ?| array['b', 'd'] @@ -294,7 +333,7 @@ 连接两个数组将生成一个包含每个输入的所有元素的数组。 连接两个对象将生成一个包含它们键的并集的对象,当存在重复的键时取第二个对象的值。 所有其他情况都通过将非数组输入转换为单元素数组来处理,然后按照两个数组的方式进行处理。 - 不递归操作:只有顶级数组或对象结构被合并。 + 不递归操作:只有顶级数组或对象结构会被合并。 '["a", "b"]'::jsonb || '["a", "d"]'::jsonb @@ -313,7 +352,7 @@ [{"a": "b"}, 42] - 要将一个数组作为单个条目附加到另一个数组中,请将其包装在另一个数组附加层中,例如: + 要将一个数组作为单个元素追加到另一个数组中,请先在它外面再包装一层数组,例如: '[1, 2]'::jsonb || jsonb_build_array('[3, 4]'::jsonb) @@ -387,7 +426,7 @@ boolean - JSON路径是否为指定的JSON值返回任何项? + JSON 路径是否为指定的 JSON 值返回任何项?(这只适用于 SQL 标准 JSON 路径表达式,不适用于谓词检查表达式,因为后者总是返回一个值。) '{"a":[1,2,3,4,5]}'::jsonb @? '$.a[*] ? (@ > 2)' @@ -401,7 +440,7 @@ boolean - 返回指定JSON值的JSON路径谓词检查的结果。只考虑结果的第一项。如果结果不是布尔值,则返回NULL。 + 返回对指定 JSON 值进行 JSON 路径谓词检查的结果。(这只适用于谓词检查表达式,不适用于 SQL 标准 JSON 路径表达式,因为如果路径结果不是单个布尔值,就会返回NULL。) '{"a":[1,2,3,4,5]}'::jsonb @@ '$.a[*] > 2' @@ -415,15 +454,13 @@ - jsonpath操作符@?@@抑制以下错误:缺少对象字段或数组元素,意外的JSON项目类型,日期时间和数字错误。 - 还可以告诉以下描述的与jsonpath相关的函数来抑制这些类型的错误。 - 在搜索不同结构的JSON文档集合时,此行为可能会有所帮助。 + jsonpath操作符@?@@会抑制以下错误:缺少对象字段或数组元素、JSON 项类型不符合预期,以及日期时间和数值错误。下文介绍的jsonpath相关函数也可以设置为抑制这些类型的错误。在搜索结构各异的 JSON 文档集合时,这一行为可能很有用。 - 显示可用于构造jsonjsonb值的函数。 - + 列出了可用于构造jsonjsonb值的函数。表中的某些函数具有RETURNING子句,用于指定返回的数据类型。该类型必须是jsonjsonbbytea、字符串类型(textcharvarchar),或者可以转换为json的类型。默认返回json类型。 +
@@ -462,14 +499,14 @@ jsonb - 将任何SQL值转换为jsonjsonb。数组和组合递归地转换为数组和对象(多维数组在JSON中变成数组的数组)。 - 否则,如果存在从SQL数据类型到json的类型转换,则类型转换函数将用于执行转换; + 将任何SQL值转换为jsonjsonb。数组和复合值递归地转换为数组和对象(多维数组在JSON中变成数组的数组)。 + 否则,如果存在从SQL数据类型到json的类型转换,则类型转换函数将用于执行转换; - 例如,扩展有一个从hstorejson的转换,这样通过json创建函数转换的hstore值将被表示为json对象,而不是原始字符串值 + 例如,扩展有一个从hstorejson的类型转换,因此通过 JSON 创建函数转换的hstore值将表示为 JSON 对象,而不是基本的字符串值。 - 否则,将生成一个标量json值。对于除数字、布尔值或空值之外的任何标量,将使用文本表示,并根据需要进行转义,使其成为有效的JSON字符串值。 + 否则,将生成一个标量 JSON 值。对于除数字、布尔值或空值之外的任何标量,将使用文本表示,并根据需要进行转义,使其成为有效的JSON字符串值。 to_json('Fred said "Hi."'::text) @@ -477,7 +514,7 @@ to_jsonb(row(42, 'Fred said "Hi."'::text)) - {"f1":42,"f2":"Fred said \"Hi.\""} + {"f1": 42, "f2": "Fred said \"Hi.\""} @@ -519,7 +556,7 @@ RETURNING data_type FORMAT JSON ENCODING UTF8 ) - 根据一系列value_expression参数或query_expression的结果构造 JSON 数组;后者必须是只返回一列的 SELECT 查询。如果指定ABSENT ON NULL,则忽略 NULL 值。使用query_expression时始终如此。如果查询未返回任何行,则返回空 JSON 数组。 + 从一系列value_expression参数或query_expression的结果构造 JSON 数组;后者必须是返回单列的 SELECT 查询。如果指定了ABSENT ON NULL,则忽略 NULL 值。使用query_expression时始终如此。如果查询不返回任何行,则返回空 JSON 数组。 json_array(1,true,json '{"a":null}') @@ -540,7 +577,7 @@ json - 将SQL组合值转换为JSON对象。该行为与to_json相同,只是如果可选boolean参数为真,换行符将在顶级元素之间添加。 + 将SQL 复合值转换为JSON对象。该行为与to_json相同,只是如果可选boolean参数为真,换行符将在顶级元素之间添加。 row_to_json(row(1,'foo')) @@ -589,7 +626,7 @@ 根据可变参数列表构建一个JSON对象。按照惯例,参数列表由交替的键和值组成。 - 关键参数强制转换为文本;值参数按照to_jsonto_jsonb进行转换。 + 键参数会被强制转换为文本;值参数则按照to_jsonto_jsonb进行转换。 json_build_object('foo', 1, 2, row(3,'bar')) @@ -597,6 +634,25 @@ + + + json_object + json_object ( + { key_expression { VALUE | ':' } + value_expression FORMAT JSON ENCODING UTF8 }, ... + { NULL | ABSENT } ON NULL + { WITH | WITHOUT } UNIQUE KEYS + RETURNING data_type FORMAT JSON ENCODING UTF8 ) + + + 根据给定的所有键值对构造 JSON 对象;如果没有给出键值对,则构造空对象。key_expression是定义JSON键的标量表达式,会被转换为text类型。它不能为NULL,其类型也不能具有到json的类型转换。如果指定了WITH UNIQUE KEYS,则key_expression不能重复。如果指定了ABSENT ON NULL,则value_expression求值为NULL的键值对会从输出中省略;如果指定了NULL ON NULL或省略了该子句,则保留该键,并将其值设为NULL。 + + + json_object('code' VALUE 'P123', 'title': 'Jaws') + {"code" : "P123", "title" : "Jaws"} + + + @@ -613,8 +669,7 @@ jsonb - 从文本数组构建JSON对象。该数组必须有两个维度,一个维度的成员数为偶数,在这种情况下,它们被视为交替的键/值对; - 另一个维度的成员数为二维,每个内部数组恰好有两个元素,它们被视为键/值对。所有值都转换为JSON字符串。 + 从文本数组构造 JSON 对象。该数组必须是一维且包含偶数个成员,此时将成员按交替的键/值对处理;或者是二维数组,且每个内部数组恰好有两个元素,将这两个元素作为一个键/值对。所有值都转换为 JSON 字符串。 json_object('{a, 1, b, "def", c, 3.5}') @@ -635,17 +690,144 @@ jsonb - 这种形式的json_object从单独的文本数组中成对地获取键和值。否则,它与单参数形式相同。 + 这种形式的json_object从单独的文本数组中成对地获取键和值。除此之外,它与单参数形式相同。 json_object('{a,b}', '{1,2}') {"a": "1", "b": "2"} + + + + json 构造器 + json ( + expression + FORMAT JSON ENCODING UTF8 + { WITH | WITHOUT } UNIQUE KEYS ) + json + + + 将给定的textbytea字符串表达式(采用 UTF8 编码)转换为 JSON 值。如果expression为 NULL,则返回SQL空值。如果指定了WITH UNIQUE,则expression不能包含重复的对象键。 + + + json('{"a":123, "b":[true,"foo"], "a":"bar"}') + {"a":123, "b":[true,"foo"], "a":"bar"} + + + + + + + json_scalar + json_scalar ( expression ) + + + 将给定的 SQL 标量值转换为 JSON 标量值。如果输入为 NULL,则返回SQL空值。如果输入是数字或布尔值,则返回相应的 JSON 数字或布尔值。对于其他值,则返回 JSON 字符串。 + + + json_scalar(123.45) + 123.45 + + + json_scalar(CURRENT_TIMESTAMP) + "2022-05-10T10:51:04.62128-04:00" + + + + + + json_serialize ( + expression FORMAT JSON ENCODING UTF8 + RETURNING data_type FORMAT JSON ENCODING UTF8 ) + + + 将 SQL/JSON 表达式转换为字符或二进制字符串。expression可以是任意 JSON 类型、任意字符串类型,或采用 UTF8 编码的bytea RETURNING中使用的返回类型可以是任意字符串类型或bytea,默认为text。 + + + json_serialize('{ "a" : 1 } ' RETURNING bytea) + \x7b20226122203a2031207d20 + +
+ + 详细介绍了用于测试 JSON 的 SQL/JSON 功能。 + + + + SQL/JSON 测试函数 + + + + + 函数签名 + + + 描述 + + + 示例 + + + + + + + IS JSON + expression IS NOT JSON + { VALUE | SCALAR | ARRAY | OBJECT } + { WITH | WITHOUT } UNIQUE KEYS + + + 该谓词测试 expression 是否可以解析为 JSON,也可以指定具体类型。 + 如果指定 SCALARARRAYOBJECT, + 则测试 JSON 是否属于该特定类型。如果指定 WITH UNIQUE KEYS, + 则 expression 中的任意对象还会被检查是否存在重复键。 + + + +SELECT js, + js IS JSON "json?", + js IS JSON SCALAR "scalar?", + js IS JSON OBJECT "object?", + js IS JSON ARRAY "array?" +FROM (VALUES + ('123'), ('"abc"'), ('{"a": "b"}'), ('[1,2]'),('abc')) foo(js); + js | json? | scalar? | object? | array? +------------+-------+---------+---------+-------- + 123 | t | t | f | f + "abc" | t | t | f | f + {"a": "b"} | t | f | t | f + [1,2] | t | f | f | t + abc | f | f | f | f + + + + +SELECT js, + js IS JSON OBJECT "object?", + js IS JSON ARRAY "array?", + js IS JSON ARRAY WITH UNIQUE KEYS "array w. UK?", + js IS JSON ARRAY WITHOUT UNIQUE KEYS "array w/o UK?" +FROM (VALUES ('[{"a":"1"}, + {"b":"2","b":"3"}]')) foo(js); +-[ RECORD 1 ]-+-------------------- +js | [{"a":"1"}, + + | {"b":"2","b":"3"}] +object? | f +array? | t +array w. UK? | f +array w/o UK? | t + + + + + +
+ 显示可用于处理jsonjsonb值的函数。 @@ -922,48 +1104,48 @@ anyelement - 将顶级 JSON 对象展开为具有 base 参数复合类型的行。JSON 对象将被扫描,查找名称与输出行类型列名匹配的字段,并将其值插入到输出行的对应列中。 - (不对应任何输出列名的字段将被忽略。)在典型用法中,base 的值仅为 NULL,这意味着任何不匹配对象字段的输出列都会被填充为 null。 - 但是,如果base不为NULL,那么它包含的值将用于不匹配的列。 + 将顶级 JSON 对象展开为一个行,其复合类型与base参数相同。系统会扫描该 JSON 对象,查找名称与输出行类型列名匹配的字段,并将其值插入输出中的对应列。 + (不对应任何输出列名的字段会被忽略。)在典型用法中,base的值就是NULL,这意味着凡是不匹配对象字段的输出列都会被填充为空值。 + 但是,如果base不是NULL,那么其中包含的值将用于那些不匹配的列。 - 要将JSON值转换为输出列的SQL类型,需要按次序应用以下规则: + 要将 JSON 值转换为输出列的 SQL 类型,需要依次应用以下规则: - 在所有情况下,JSON空值都会转换为SQL空值。 + 在所有情况下,JSON 空值都会转换为 SQL 空值。 - 如果输出列的类型是jsonjsonb,则会精确地重制JSON值。 + 如果输出列的类型是jsonjsonb,则 JSON 值会被原样保留。 - 如果输出列是复合(行)类型,且JSON值是JSON对象,则该对象的字段将转换为输出行类型的列,通过这些规则的递归应用程序。 + 如果输出列是复合(行)类型,且 JSON 值是 JSON 对象,则该对象的字段会通过递归应用这些规则,被转换为输出行类型的各列。 - 同样,如果输出列是数组类型,而JSON值是JSON数组,则通过这些规则的递归应用程序将JSON数组的元素转换为输出数组的元素。 + 同样,如果输出列是数组类型,而 JSON 值是 JSON 数组,则会通过递归应用这些规则,把 JSON 数组的元素转换为输出数组的元素。 - 否则,如果JSON值是字符串,则将字符串的内容提供给输入转换函数,用以确定列的数据类型。 + 否则,如果 JSON 值是字符串,则会把该字符串的内容送入该列数据类型的输入转换函数。 - 否则,JSON值的普通文本表示将被提供给输入转换函数,以确定列的数据类型。 + 否则,JSON 值的普通文本表示会被送入该列数据类型的输入转换函数。 - 虽然下面的示例使用一个常量JSON值,典型的用法是在查询的FROM子句中从另一个表侧面地引用jsonjsonb列。 - 在FROM子句中编写json_populate_record是一种很好的实践,因为提取的所有列都可以使用,而不需要重复的函数调用。 + 虽然下面的示例使用的是常量 JSON 值,但典型用法是在查询的FROM子句中,以横向方式引用另一个表中的jsonjsonb列。 + 把json_populate_record写在FROM子句中是一种良好实践,因为这样抽取出的所有列都可以直接使用,而不需要重复调用函数。 CREATE TYPE subrowtype AS (d int, e text); @@ -990,9 +1172,7 @@ boolean - 用于测试jsonb_populate_record。如果对于给定的输入 JSON 对象, - jsonb_populate_record调用能够无错误完成,即输入有效,则返回 - true;否则返回false。 + 用于测试jsonb_populate_record的函数。对于给定的输入 JSON 对象,如果jsonb_populate_record能够无错误地完成,即该输入有效,则返回true;否则返回false CREATE TYPE jsb_char2 AS (a char(2)); @@ -1048,8 +1228,7 @@ ERROR: value too long for type character(2) setof anyelement - 将对象的顶级 JSON 数组展开为一组具有 base 参数复合类型的行。 - 对于json[b]_populate_record,将如上所述处理JSON数组的每个元素。 + 将由对象组成的顶级 JSON 数组展开为一组行,其复合类型与base参数相同。JSON 数组中的每个元素都按照上文对json[b]_populate_record的说明进行处理。 CREATE TYPE twoints AS (a int, b int); @@ -1118,8 +1297,8 @@ ERROR: value too long for type character(2) 将顶级JSON对象数组展开为一组由AS子句定义的复合类型的行。 - (与所有返回record的函数一样,调用查询必须使用AS子句显式定义记录的结构。) - 对于json[b]_populate_record,将如上所述处理JSON数组的每个元素。 + (与所有返回record的函数一样,调用查询必须使用AS子句显式定义记录的结构。) + JSON 数组中的每个元素都按照上文对json[b]_populate_record的说明进行处理。 SELECT * FROM json_to_recordset('[{"a":1,"b":"foo"}, {"a":"2","c":"bar"}]') AS x(a int, b text) @@ -1145,7 +1324,7 @@ ERROR: value too long for type character(2) 返回target,将path指定的项替换为new_value, 如果create_if_missing为真(此为默认值)并且path指定的项不存在,则添加new_value。 路径中的所有前面步骤都必须存在,否则将不加改变地返回target。 - 与面向路径操作符一样,负整数出现在JSON数组末尾的path计数中。 + 与面向路径的操作符一样,path中的负整数从 JSON 数组末尾计数。 如果最后一个路径步骤是超出范围的数组索引,并且create_if_missing为真,那么如果索引为负,新值将添加到数组的开头,如果索引为正,则添加到数组的结尾。 @@ -1192,8 +1371,8 @@ ERROR: value too long for type character(2) 如果path指派的项是一个数组元素,如果 insert_after为假(此为默认值),则new_value将被插入到该项之前,如果 insert_after为真则在该项之后。 如果由path指派的项是一个对象字段,则只在对象不包含该键时才插入 new_value。 路径中的所有前面步骤都必须存在,否则将不加改变地返回target。 - 与面向路径操作符一样,负整数出现在JSON数组末尾的 path计数中。 - 如果最后一个路径步骤是超出范围的数组下标,则如果下标为负,则将新值添加到数组的开头;如果下标为正,则将新值添加到数组的结尾。 + 与面向路径的操作符一样,path中的负整数从 JSON 数组末尾计数。 + 如果最后一个路径步骤是超出范围的数组下标,那么当下标为负时,新值会被添加到数组开头;当下标为正时,新值会被添加到数组末尾。 jsonb_insert('{"a": [0,1,2]}', '{a, 1}', '"new_value"') @@ -1242,7 +1421,7 @@ ERROR: value too long for type character(2) boolean - 检查JSON路径是否返回指定JSON值的任何项。如果指定了vars参数,则它必须是一个JSON对象,并且它的字段提供要替换到jsonpath表达式中的名称值。 + 检查 JSON 路径是否为指定的 JSON 值返回任何项。(这只对 SQL 标准 JSON 路径表达式有用,而不适用于谓词检查表达式,因为后者总是返回一个值。)如果指定了vars参数,则它必须是一个 JSON 对象,并且它的字段提供要替换到jsonpath表达式中的具名值。 如果指定了silent参数并为true,函数会抑制与@?@@操作符相同的错误。 @@ -1260,8 +1439,7 @@ ERROR: value too long for type character(2) boolean - 返回指定JSON值的JSON路径谓词检查的结果。只有结果的第一项被考虑在内。 - 如果结果不是布尔值,则返回NULL。可选的varssilent参数的作用与jsonb_path_exists相同。 + 返回指定 JSON 值的 JSON 路径谓词检查的 SQL 布尔结果。(这只对谓词检查表达式有用,而不适用于 SQL 标准 JSON 路径表达式,因为如果路径结果不是单个布尔值,它将失败或返回NULL。)可选的varssilent参数的作用与jsonb_path_exists相同。 jsonb_path_match('{"a":[1,2,3,4,5]}', 'exists($.a[*] ? (@ >= $min && @ <= $max))', '{"min":2, "max":4}') @@ -1278,7 +1456,7 @@ ERROR: value too long for type character(2) setof jsonb - 为指定的JSON值返回由JSON路径返回的所有JSON项。可选的varssilent参数的作用与jsonb_path_exists相同。 + 为指定的 JSON 值返回由 JSON 路径返回的所有 JSON 项。对于 SQL 标准 JSON 路径表达式,它返回从target中选出的 JSON 值。对于谓词检查表达式,它返回谓词检查的结果:truefalsenull。可选的varssilent参数的作用与jsonb_path_exists相同。 SELECT * FROM jsonb_path_query('{"a":[1,2,3,4,5]}', '$.a[*] ? (@ >= $min && @ <= $max)', '{"min":2, "max":4}') @@ -1302,7 +1480,7 @@ ERROR: value too long for type character(2) jsonb - 以JSON数组的形式返回由JSON路径为指定的JSON值返回的所有JSON项。可选的varssilent参数的作用与jsonb_path_exists相同。 + 以JSON数组的形式返回由JSON路径为指定的JSON值返回的所有JSON项。参数与jsonb_path_query相同。 jsonb_path_query_array('{"a":[1,2,3,4,5]}', '$.a[*] ? (@ >= $min && @ <= $max)', '{"min":2, "max":4}') @@ -1320,7 +1498,7 @@ ERROR: value too long for type character(2) 为指定的JSON值返回由JSON路径返回的第一个JSON项。如果没有结果则返回NULL。 - 可选的varssilent参数的作用与 jsonb_path_exists相同。 + 参数与jsonb_path_query相同。 jsonb_path_query_first('{"a":[1,2,3,4,5]}', '$.a[*] ? (@ >= $min && @ <= $max)', '{"min":2, "max":4}') @@ -1384,7 +1562,7 @@ ERROR: value too long for type character(2) text - 将给定的JSON值转换为精美打印的,缩进的文本。 + 将给定的 JSON 值转换为经过美化并带有缩进的文本。 jsonb_pretty('[{"f1":1,"f2":null}, 2]') @@ -1417,8 +1595,8 @@ ERROR: value too long for type character(2) text - 以文本字符串形式返回顶级JSON值的类型。可能的类型有object, array,string, number,boolean, 和 null。 - (null的结果不应该与SQL NULL 混淆;参见示例。) + 以文本字符串形式返回顶级JSON值的类型。可能的类型有objectarraystringnumberbooleannull。 + (null 的结果不应与 SQL NULL 混淆;参见示例。) json_typeof('-123.4') @@ -1447,14 +1625,15 @@ ERROR: value too long for type character(2) - SQL/JSON路径表达式指定了要从JSON数据中检索的项目,类似于SQL访问XML时使用的XPath表达式。 + SQL/JSON路径表达式指定了要从JSON数据中检索的项,类似于访问 XML 内容时使用的 XPath 表达式。 在PostgreSQL中,路径表达式作为jsonpath数据类型实现,可以使用中描述的任何元素。 JSON 查询函数和操作符会将给定的路径表达式传递给路径引擎进行求值。 如果表达式与被查询的JSON数据匹配,则返回相应的JSON项或项集。 - 路径表达式是用SQL/JSON路径语言编写的,也可以包括算术表达式和函数。 + 如果没有匹配项,则根据所用函数返回NULLfalse或抛出错误。 + 路径表达式是用SQL/JSON路径语言编写的,也可以包括算术表达式和函数。 @@ -1463,15 +1642,13 @@ ERROR: value too long for type character(2) - 要引用正在查询的JSON值(context item项),在路径表达式中使用$变量。 - 它后面可以跟着一个或多个accessor operators,这些操作符在JSON结构中逐级向下检索上下文项的子项。 - 后面的每个操作符处理前一个求值步骤的结果。 - + 要引用正在查询的 JSON 值(上下文项),请在路径表达式中使用$变量。路径的第一个元素必须始终是$。它后面可以跟一个或多个访问操作符,沿 JSON 结构逐层向下获取上下文项的子项。每个访问操作符都处理上一步求值的结果,为每个输入项产生零个、一个或多个输出项。 + - 例如,假设你有一些你想要解析的来自GPS跟踪器的JSON数据,例如: + 例如,假设你有一些来自 GPS 跟踪器、想要解析的 JSON 数据,如下所示: -{ +SELECT '{ "track": { "segments": [ { @@ -1486,12 +1663,13 @@ ERROR: value too long for type character(2) } ] } -} +}' AS json \gset - + (可以将上述示例复制粘贴到psql中,为后续示例做好准备。此后,psql会将:'json'展开为一个包含该 JSON 值、且已正确加上引号的字符串常量。) + - 为了检索可用的轨迹段,你需要使用.key访问操作符来向下浏览周边的JSON对象: + 要获取可用的轨迹段,需要使用.key访问操作符,逐层访问外围的 JSON 对象: => SELECT jsonb_path_query(:'json', '$.track.segments'); jsonb_path_query @@ -1501,7 +1679,7 @@ ERROR: value too long for type character(2) - 要检索数组的内容,通常使用[*]操作符。例如,下面的路径将返回所有可用轨迹段的位置坐标: + 要检索数组的内容,通常使用[*]操作符。例如,下面的路径将返回所有可用轨迹段的位置坐标: => SELECT jsonb_path_query(:'json', '$.track.segments[*].location'); jsonb_path_query @@ -1525,7 +1703,7 @@ ERROR: value too long for type character(2) 每个路径求值步骤的结果可以由中列出的一个或多个jsonpath操作符和方法来处理。 - 每个方法名之前必须有一个点。例如,你可以得到一个数组的大小: + 每个方法名之前必须有一个点。例如,你可以得到一个数组的大小: => SELECT jsonb_path_query(:'json', '$.track.segments.size()'); jsonb_path_query @@ -1536,19 +1714,17 @@ ERROR: value too long for type character(2) - 在定义路径时,还可以使用一个或多个与SQL中的WHERE子句类似的filter expressions。 - 过滤器表达式以问号开头,并在圆括号中提供条件: - - + 路径还可以包含过滤表达式,其作用类似于 SQL 中的WHERE子句。过滤表达式以问号开头,并在圆括号中提供条件: + ? (condition) - - + + - 过滤表达式必须在它们应该应用的路径求值步骤之后写入。该步骤的结果将被筛选,以只包括满足所提供条件的那些项。 + 过滤表达式必须在它们应该应用的路径求值步骤之后指定。该步骤的结果会经过过滤,只保留满足给定条件的项。 SQL/JSON定义了三值逻辑,因此条件可以是 true, false,或 unknownunknown值发挥与SQL NULL相同的角色,可以使用IS UNKNOWN谓词进行测试。 - 进一步的路径求值步骤只使用筛选器表达式返回true的那些项。 + 进一步的路径求值步骤只使用过滤表达式返回true的那些项。 @@ -1557,7 +1733,7 @@ ERROR: value too long for type character(2) - 例如,假设你想要检索所有高于130的心率值。你可以使用下面的表达式来实现这一点: + 例如,假设你想要检索所有高于130的心率值。你可以使用下面的表达式来实现这一点: => SELECT jsonb_path_query(:'json', '$.track.segments[*].HR ? (@ > 130)'); jsonb_path_query @@ -1567,7 +1743,7 @@ ERROR: value too long for type character(2) - 为了获得具有这些值的片段的开始时间,必须在返回开始时间之前过滤掉不相关的片段,所以过滤表达式应用于上一步,条件中使用的路径不同: + 为了获得具有这些值的轨迹段的开始时间,必须先过滤掉不相关的轨迹段,再返回开始时间。因此,过滤表达式应用于上一步,条件中使用的路径也不同: => SELECT jsonb_path_query(:'json', '$.track.segments[*] ? (@.HR > 130)."start time"'); jsonb_path_query @@ -1577,7 +1753,7 @@ ERROR: value too long for type character(2) - 如果需要,可以按顺序使用几个过滤器表达式。例如,下面的表达式选择所有包含有相关坐标和高心率值的位置的段的开始时间: + 如有需要,可以依次使用多个过滤表达式。例如,下面的表达式选择位置坐标符合要求且心率较高的所有轨迹段的开始时间: => SELECT jsonb_path_query(:'json', '$.track.segments[*] ? (@.location[1] < 13.4) ? (@.HR > 130)."start time"'); jsonb_path_query @@ -1587,7 +1763,7 @@ ERROR: value too long for type character(2) - 也允许在不同嵌套层级中使用过滤器表达式。下面的示例首先根据位置筛选所有的片段,然后返回这些片段的高心率值,如果适用的话: + 也可以在不同嵌套层级使用过滤表达式。下面的示例先按位置筛选所有轨迹段,再返回这些轨迹段中的高心率值(如果存在): => SELECT jsonb_path_query(:'json', '$.track.segments[*] ? (@.location[1] < 13.4).HR ? (@ > 130)'); jsonb_path_query @@ -1597,15 +1773,14 @@ ERROR: value too long for type character(2) - 你也可以在彼此之间嵌套过滤器表达式: + 还可以将过滤表达式相互嵌套。如果轨迹包含任何具有高心率值的轨迹段,下面的示例返回轨迹的大小,否则返回空序列: => SELECT jsonb_path_query(:'json', '$.track ? (exists(@.segments[*] ? (@.HR > 130))).segments.size()'); jsonb_path_query ------------------ 2 - 如果包含任何具有高心率值的片段,则该表达式返回轨迹的大小,否则返回空序列。 - + 与 SQL 标准的偏差 @@ -1654,46 +1829,41 @@ ERROR: value too long for type character(2) 当查询JSON数据时,路径表达式可能与实际的JSON数据结构不匹配。 - 试图访问不存在的对象成员或数组元素会导致结构错误。SQL/JSON路径表达式有两种处理结构错误的模式: + 试图访问不存在的对象成员或数组元素会导致结构错误。SQL/JSON路径表达式有两种处理结构错误的模式: - 不严格的(lax)(默认)—路径引擎隐式地将查询的数据适配到指定的路径。任何剩余的结构错误都将被抑制并转换为空SQL/JSON序列。 - + 宽松模式(lax,默认)—路径引擎隐式地将被查询的数据适配到指定路径。凡是无法按下文所述方式修复的结构错误都会被抑制,产生的结果是不匹配。 + - - 严格的(strict) —如果发生了结构错误,则会引发错误。 - + 严格模式(strict)— 如果发生结构错误,就会引发错误。 - 如果JSON数据不符合期望的模式,不严格的(lax)模式有助于匹配JSON文档结构和路径表达式。 - 如果操作不匹配特定操作的要求,可以自动将其包装为SQL/JSON数组,也可以在执行该操作之前将其元素转换为SQL/JSON序列来解包装。 - 此外,比较操作符会自动以lax模式打开它们的操作数,因此你可以开包即用的就能比较SQL/JSON数组。 - 大小为1的数组被认为等于它的唯一元素。只有在以下情况下才不会自动展开: + 如果 JSON 数据不符合预期模式,宽松模式有助于使 JSON 文档结构与路径表达式相匹配。如果操作数不满足某个操作的要求,可以在执行该操作之前自动将其包装为 SQL/JSON 数组,或通过将其元素转换为 SQL/JSON 序列来解包。此外,在宽松模式下,比较操作符会自动解包其操作数,因此可以直接比较 SQL/JSON 数组。大小为 1 的数组被视为等于其唯一元素。以下情况不会自动解包: - 路径表达式包含type()size()方法,它们分别返回数组中的元素类型和数量。 + 路径表达式包含type()size()方法,它们分别返回类型和数组中的元素数量。 - 查询的JSON数据包含嵌套的数组。在本例中,只有最外层的数组被打开,而所有内部数组保持不变。 - 因此,隐式展开在每个路径求值步骤中只能向下进行一级。 + 查询的JSON数据包含嵌套的数组。在本例中,只有最外层的数组被解包,而所有内部数组保持不变。 + 因此,隐式解包在每个路径求值步骤中只能向下进行一级。 - 例如,查询上面列出的GPS数据时,使用不严格的(lax)模式就无需关注片段存储在数组中这一细节: + 例如,查询上面列出的GPS数据时,使用宽松模式就无需关注轨迹段存储在数组中这一细节: => SELECT jsonb_path_query(:'json', 'lax $.track.segments.location'); jsonb_path_query @@ -1704,12 +1874,12 @@ ERROR: value too long for type character(2) - 在严格的(strict)模式中,指定的路径必须与查询的JSON文档的结构完全匹配才能返回SQL/JSON项,因此使用该路径表达式会导致错误。 + 在严格模式下,指定的路径必须与查询的JSON文档的结构完全匹配,因此使用该路径表达式会导致错误。 => SELECT jsonb_path_query(:'json', 'strict $.track.segments.location'); ERROR: jsonpath member accessor can only be applied to an object - 要得到与不严格的(lax)模式相同的结果,你必须显式地打开segments数组: + 要得到与宽松模式相同的结果,你必须显式地解包segments数组: => SELECT jsonb_path_query(:'json', 'strict $.track.segments[*].location'); jsonb_path_query @@ -1720,8 +1890,8 @@ ERROR: jsonpath member accessor can only be applied to an object - .**访问器在使用lax模式时可能导致令人惊讶的结果。 - 例如,下面的查询选择每个HR值两次: + .**访问器在宽松模式下可能产生意外结果。 + 例如,下面的查询选择每个HR值两次: => SELECT jsonb_path_query(:'json', 'lax $.**.HR'); jsonb_path_query @@ -1731,10 +1901,10 @@ ERROR: jsonpath member accessor can only be applied to an object 73 135 - 发生这个,是因为.**访问器会全部选择segments数组和它的每个元素。 - 而当使用lax模式时,.HR访问器会自动打开数组。 + 这是因为.**访问器既选择segments数组,又选择它的每个元素。 + 而在宽松模式下,.HR访问器会自动解包数组。 为了避免意外的结果,我们建议仅在严格模式下使用.**访问器。 - 下面的查询选择每个HR值仅一次: + 下面的查询选择每个HR值仅一次: => SELECT jsonb_path_query(:'json', 'strict $.**.HR'); jsonb_path_query @@ -1745,7 +1915,7 @@ ERROR: jsonpath member accessor can only be applied to an object - 数组的自动展开也可能产生意外结果。下面的示例选择所有 location 数组: + 数组解包也可能产生意外结果。请看下面这个选取所有location数组的示例: => SELECT jsonb_path_query(:'json', 'lax $.track.segments[*].location'); jsonb_path_query @@ -1754,7 +1924,7 @@ ERROR: jsonpath member accessor can only be applied to an object [47.706, 13.2635] (2 rows) - 结果如预期一样返回完整数组。但应用过滤表达式会使数组自动展开,以便逐项求值,只返回与表达式匹配的项: + 它会如预期那样返回完整数组。但应用过滤表达式时,数组会被解包,以便对每个元素求值,最终只返回匹配该表达式的元素: => SELECT jsonb_path_query(:'json', 'lax $.track.segments[*].location ?(@[*] > 15)'); jsonb_path_query @@ -1763,7 +1933,7 @@ ERROR: jsonpath member accessor can only be applied to an object 47.706 (2 rows) - 尽管路径表达式选择的是完整数组,结果仍然如此。使用严格模式可以重新得到完整数组: + 尽管路径表达式选取的是完整数组,结果仍然如此。使用严格模式可以恢复选取数组的行为: => SELECT jsonb_path_query(:'json', 'strict $.track.segments[*].location ?(@[*] > 15)'); jsonb_path_query @@ -1781,8 +1951,7 @@ ERROR: jsonpath member accessor can only be applied to an object SQL/JSON 路径操作符和方法 - 显示了jsonpath中可用的操作符和方法。 - 请注意,虽然一元操作符和方法可以应用于由前一个路径步骤产生的多个值,二元操作符(加法等)只能应用于单个值。 + 列出了jsonpath中可用的操作符和方法。请注意,一元操作符和方法可以应用于前一个路径步骤产生的多个值,而二元操作符(加法等)只能应用于单个值。在宽松模式下,对数组应用方法时,会对数组中的每个值执行该方法。例外是.type().size(),它们作用于数组本身。 @@ -1854,7 +2023,7 @@ ERROR: jsonpath member accessor can only be applied to an object number - 否定;与减法不同,它可以迭代多个值 + 取负;与减法不同,可以遍历多个值。 jsonb_path_query_array('{"x": [2,3,4]}', '- $.x') @@ -1896,7 +2065,7 @@ ERROR: jsonpath member accessor can only be applied to an object number - 模数 (余数) + 取模(余数) jsonb_path_query('[32]', '$[0] % 10') @@ -1932,6 +2101,38 @@ ERROR: jsonpath member accessor can only be applied to an object + + + value . boolean() + boolean + + + 将 JSON 布尔值、数字或字符串转换为布尔值。 + + + jsonb_path_query_array('[1, "yes", false]', '$[*].boolean()') + [true, true, false] + + + + + + value . string() + string + + + 将 JSON 布尔值、数字、字符串或日期时间转换为字符串值。 + + + jsonb_path_query_array('[1.23, "xyz", false]', '$[*].string()') + ["1.23", "xyz", "false"] + + + jsonb_path_query('"2023-08-15 12:34:56"', '$.timestamp().string()') + "2023-08-15T12:34:56" + + + value . double() @@ -1988,11 +2189,67 @@ ERROR: jsonpath member accessor can only be applied to an object + + + value . bigint() + bigint + + + 将 JSON 数字或字符串转换为大整数值。 + + + jsonb_path_query('{"len": "9876543219"}', '$.len.bigint()') + 9876543219 + + + + + + value . decimal( [ precision [ , scale ] ] ) + decimal + + + 将 JSON 数字或字符串转换为经过舍入的十进制数值(precisionscale必须为整数值)。 + + + jsonb_path_query('1234.5678', '$.decimal(6, 2)') + 1234.57 + + + + + + value . integer() + integer + + + 将 JSON 数字或字符串转换为整数值。 + + + jsonb_path_query('{"len": "12345"}', '$.len.integer()') + 12345 + + + + + + value . number() + numeric + + + 将 JSON 数字或字符串转换为数值。 + + + jsonb_path_query('{"len": "123.45"}', '$.len.number()') + 123.45 + + + string . datetime() datetime_type - (see note) + (见注) 从字符串转换过来的日期/时间值 @@ -2007,7 +2264,7 @@ ERROR: jsonpath member accessor can only be applied to an object string . datetime(template) datetime_type - (see note) + (见注) 使用指定的to_timestamp模板从字符串转换过来的日期/时间值 @@ -2017,6 +2274,148 @@ ERROR: jsonpath member accessor can only be applied to an object ["12:30:00", "18:40:00"] + + string . date() + date + + + 将字符串转换为日期值。 + + + jsonb_path_query('"2023-08-15"', '$.date()') + "2023-08-15" + + + + + + string . time() + time without time zone + + + 将字符串转换为不带时区的时间值。 + + + jsonb_path_query('"12:34:56"', '$.time()') + "12:34:56" + + + + + + string . time(precision) + time without time zone + + + 将字符串转换为不带时区的时间值,并将秒的小数部分调整到给定精度。 + + + jsonb_path_query('"12:34:56.789"', '$.time(2)') + "12:34:56.79" + + + + + + string . time_tz() + time with time zone + + + 将字符串转换为带时区的时间值。 + + + jsonb_path_query('"12:34:56 +05:30"', '$.time_tz()') + "12:34:56+05:30" + + + + + + string . time_tz(precision) + time with time zone + + + 将字符串转换为带时区的时间值,并将秒的小数部分调整到给定精度。 + + + jsonb_path_query('"12:34:56.789 +05:30"', '$.time_tz(2)') + "12:34:56.79+05:30" + + + + + + string . timestamp() + timestamp without time zone + + + 将字符串转换为不带时区的时间戳值。 + + + jsonb_path_query('"2023-08-15 12:34:56"', '$.timestamp()') + "2023-08-15T12:34:56" + + + + + + string . timestamp(precision) + timestamp without time zone + + + 将字符串转换为不带时区的时间戳值,并将秒的小数部分调整到给定精度。 + + + jsonb_path_query('"2023-08-15 12:34:56.789"', '$.timestamp(2)') + "2023-08-15T12:34:56.79" + + + + + + string . timestamp_tz() + timestamp with time zone + + + 将字符串转换为带时区的时间戳值。 + + + jsonb_path_query('"2023-08-15 12:34:56 +05:30"', '$.timestamp_tz()') + "2023-08-15T12:34:56+05:30" + + + + + + + + string . timestamp_tz(precision) + timestamp with time zone + + + 将字符串转换为带时区的时间戳值,并将秒的小数部分调整到给定精度。 + + + jsonb_path_query('"2023-08-15 12:34:56.789 +05:30"', '$.timestamp_tz(2)') + "2023-08-15T12:34:56.79+05:30" + + + + + + object . keyvalue() + array + + + 对象的键值对,表示为包含三个字段的对象数组:"key""value",和"id";"id"是键值对所归属对象的唯一标识符 + + + jsonb_path_query_array('{"x": "20", "y": 32}', '$.keyvalue()') + [{"id": 0, "key": "x", "value": "20"}, {"id": 0, "key": "y", "value": 32}] + + + + string . lower() string @@ -2143,22 +2542,6 @@ ERROR: jsonpath member accessor can only be applied to an object "trim" - - - - - - object . keyvalue() - array - - - 对象的键值对,表示为包含三个字段的对象数组:"key""value",和"id";"id"是键值对所归属对象的唯一标识符 - - - jsonb_path_query_array('{"x": "20", "y": 32}', '$.keyvalue()') - [{"id": 0, "key": "x", "value": "20"}, {"id": 0, "key": "y", "value": 32}] - -
@@ -2172,7 +2555,7 @@ ERROR: jsonpath member accessor can only be applied to an object datetime()方法依次尝试将其输入字符串与date, timetz, time,timestamptz, 和 timestamp的ISO格式进行匹配。 - 它在第一个匹配格式时停止,并发出相应的数据类型。 + 它在第一个匹配格式时停止,并返回相应数据类型的值。 @@ -2180,26 +2563,26 @@ ERROR: jsonpath member accessor can only be applied to an object - datetime()datetime(template)方法使用与to_timestamp SQL函数相同的解析规则(see ),但有三个例外。 + datetime()datetime(template)方法使用与to_timestamp SQL函数相同的解析规则(参见),但有三个例外。 首先,这些方法不允许不匹配的模板模式。 - 其次,模板字符串中只允许以下分隔符:减号、句点、solidus(斜杠)、逗号、撇号、分号、冒号和空格。 + 其次,模板字符串中只允许以下分隔符:减号、句点、斜杠、逗号、撇号、分号、冒号和空格。 第三,模板字符串中的分隔符必须与输入字符串完全匹配。 - 如果需要比较不同的日期/时间类型,则应用隐式转换。 + 如果需要比较不同的日期/时间类型,则应用隐式类型转换。 date值可以转换为timestamptimestamptz, timestamp可以转换为timestamptz, time可以转换为timetz。 - 但是,除了第一个转换外,其他所有转换都依赖于当前设置,因此只能在时区感知的jsonpath函数中执行。 + 但是,除了第一个转换外,其他所有转换都依赖于当前设置,因此只能在时区感知的jsonpath函数中执行。类似地,其他将字符串转换为日期/时间类型的日期/时间相关方法也会进行这种转换,这可能涉及当前的设置。因此,这些转换同样只能在时区感知的jsonpath函数中执行。 - 显示了适用的过滤器表达式元素。 + 显示了可用的过滤表达式元素。 - <type>jsonpath</type> 过滤器表达式元素 + <type>jsonpath</type> 过滤表达式元素 @@ -2348,7 +2731,7 @@ ERROR: jsonpath member accessor can only be applied to an object value - JSON常数null(注意,与SQL不同,与null比较可以正常工作) + JSON 常量null(注意,与SQL不同,与null比较可以正常工作) jsonb_path_query('[{"name": "Mary", "job": null}, {"name": "Michael", "job": "driver"}]', '$[*] ? (@.job == null) .name') @@ -2418,7 +2801,7 @@ ERROR: jsonpath member accessor can only be applied to an object boolean - 测试第一个操作数是否与第二个操作数给出的正则表达式匹配,可选使用由一串flag字符描述的修改(参见)。 + 测试第一个操作数是否与第二个操作数给出的正则表达式匹配;可以用一串flag标志字符调整匹配行为(参见)。 jsonb_path_query_array('["abc", "abd", "aBdC", "abdacb", "babc"]', '$[*] ? (@ like_regex "^ab.*c")') @@ -2474,31 +2857,28 @@ ERROR: jsonpath member accessor can only be applied to an object LIKE_REGEX - in SQL/JSON + 用于 SQL/JSON - - SQL/JSON路径表达式允许通过like_regex过滤器将文本匹配为正则表达式。 - 例如,下面的SQL/JSON路径查询将不区分大小写地匹配以英语元音开头的数组中的所有字符串: - + SQL/JSON 路径表达式允许使用like_regex过滤器,将文本与正则表达式进行匹配。例如,以下 SQL/JSON 路径查询会以不区分大小写的方式,匹配数组中所有以英语元音字母开头的字符串: $[*] ? (@ like_regex "^[aeiou]" flag "i") - 可选的flag字符串可以包括一个或多个字符i用于不区分大小写的匹配,m允许^$在换行时匹配,s允许.匹配换行符,q引用整个模式(将行为简化为一个简单的子字符串匹配)。 + 可选的flag字符串可以包括一个或多个字符i用于不区分大小写的匹配,m允许^$在换行时匹配,s允许.匹配换行符,q将整个模式按字面量处理(将行为简化为一个简单的子字符串匹配)。 SQL/JSON标准借用了来自LIKE_REGEX操作符的正则表达式定义,其使用了XQuery标准。 PostgreSQL目前不支持LIKE_REGEX操作符。因此,like_regex过滤器是使用中描述的POSIX正则表达式引擎来实现的。 - 这导致了与标准SQL/JSON行为的各种细微差异,这在中进行了分类。 - 但是请注意,这里描述的标志字母不兼容并不适用于SQL/JSON,因为它将XQuery标志字母翻译为符合POSIX引擎的预期。 + 这导致了与标准SQL/JSON行为的各种细微差异,这些差异列在中。 + 但是请注意,这里描述的标志字母不兼容并不适用于SQL/JSON,因为 SQL/JSON 会将 XQuery 标志字母转换为 POSIX 引擎所预期的形式。 - 请记住,like_regex的模式参数是一个JSON路径字符串文字,根据给出的规则编写。 - 这特别意味着在正则表达式中要使用的任何反斜杠都必须加倍。例如,匹配只包含数字的根文档的字符串值: + 请记住,like_regex的模式参数是一个JSON 路径字符串字面量,根据给出的规则编写。 + 这特别意味着在正则表达式中要使用的任何反斜杠都必须加倍。例如,匹配根文档中仅包含数字的字符串值: $.* ? (@ like_regex "^\\d+$") @@ -2818,18 +3198,18 @@ DETAIL: Missing "]" after array dimensions. 列。这些列可以通过一个看起来与顶层 COLUMNS 子句类似的 COLUMNS 子句来指定。由 NESTED COLUMNS 构造的行称为子行,它们会与父 - COLUMNS 子句中指定的列所构造的行联接, + COLUMNS 子句中指定的列所构造的行连接, 从而得到最终视图中的行。子列自身也可以包含 NESTED PATH 说明,因此可以提取位于任意嵌套层级中的数据。 在同一层级上由多个 NESTED PATH 生成的列彼此视为 - 兄弟,它们在与父行联接后的行通过 + 兄弟,它们在与父行连接后的行通过 UNION 进行组合。 - 由 JSON_TABLE 生成的行会与生成它们的行进行横向联接, + 由 JSON_TABLE 生成的行会与生成它们的行进行横向连接, 因此你无需显式地将构造出来的视图与保存 JSON - 数据的原始表进行联接。 + 数据的原始表进行连接。 @@ -2982,9 +3362,8 @@ JSON_TABLE ( 该值对应于将 PATH 表达式应用到行模式后是否产生任何值。 - 指定的 type 应当具有从 - boolean 类型进行强制转换的能力。 - + 应当存在从boolean到指定type的类型转换。 + 你还可以选择使用 ON ERROR 来指定: 当 JSON 路径求值期间发生错误,或者将 SQL/JSON 值强制转换为指定类型时发生错误时, @@ -3254,7 +3633,7 @@ SELECT jt.* FROM 下面是在上述查询基础上的修改版本,用来展示如何使用 NESTED PATH 填充 title 和 director - 列,并说明它们如何与父列 id 和 kind 联接: + 列,并说明它们如何与父列 id 和 kind 连接: SELECT jt.* FROM diff --git a/zh/20/func/func-logical.sgml b/zh/20/func/func-logical.sgml index 527a4ece..d157c6e3 100644 --- a/zh/20/func/func-logical.sgml +++ b/zh/20/func/func-logical.sgml @@ -3,20 +3,17 @@ 逻辑操作符 - operator - logical + 操作符 + 逻辑 - Boolean - operators - operators, logical + 布尔 + 操作符 + 操作符,逻辑 - - 常用的逻辑操作符有: - - + 可以使用以下常见逻辑操作符: AND(操作符) @@ -29,15 +26,15 @@ - conjunction + 合取 - disjunction + 析取 - negation + 否定 @@ -46,9 +43,7 @@ NOT boolean boolean - SQL使用三值的逻辑系统,包括真、假和nullnull表示未知。观察下面的真值表: - - + SQL使用由真、假和null构成的三值逻辑系统,其中null表示未知。请看下面的真值表: diff --git a/zh/20/func/func-matching.sgml b/zh/20/func/func-matching.sgml index a980022a..98abeabd 100644 --- a/zh/20/func/func-matching.sgml +++ b/zh/20/func/func-matching.sgml @@ -3,11 +3,11 @@ 模式匹配 - pattern matching + 模式匹配 - PostgreSQL提供了三种独立的实现模式匹配的方法:SQL LIKE操作符、更近一些的SIMILAR TO操作符(SQL:1999 里添加进来的)和POSIX-风格的正则表达式。除了这些基本的这个串匹配这个模式吗?操作符外,还有一些函数可用于提取或替换匹配子串并在匹配位置分离一个串。 + PostgreSQL提供了三种独立的模式匹配方法:传统的SQL LIKE操作符、较新的SIMILAR TO操作符(在 SQL:1999 中加入),以及POSIX风格的正则表达式。除了用于判断这个字符串是否匹配这个模式?的基本操作符外,还提供了提取或替换匹配子字符串、在匹配位置分割字符串的函数。 @@ -20,25 +20,20 @@ - 虽然大部分的正则表达式搜索都能被很快地执行,但是正则表达式仍可能被 - 人为地弄成需要任意长的时间和任意量的内存进行处理。要当心从不怀好意 - 的来源接受正则表达式搜索模式。如果必须这样做,建议加上语句超时限制。 + 虽然大多数正则表达式搜索都能很快完成,但特意构造的正则表达式可能需要任意长的处理时间和任意多的内存。接受来自恶意来源的正则表达式搜索模式时应当谨慎。如果必须这样做,建议设置语句超时。 - 使用SIMILAR TO模式的搜索具有同样的安全性危险, - 因为SIMILAR TO提供了很多和 - POSIX-风格正则表达式相同的能力。 + 使用SIMILAR TO模式进行搜索具有同样的安全风险,因为SIMILAR TO提供了许多与POSIX风格正则表达式相同的能力。 - LIKE搜索比其他两种选项简单得多,因此在使用 - 不怀好意的模式来源时要更安全些。 + LIKE搜索比另外两种方法简单得多,因此,当模式可能来自恶意来源时,使用它更安全。 - SIMILAR TOPOSIX-风格正则表达式不支持非确定性排序规则。如果需要的话,可以使用LIKE或在表达式中应用不同的排序规则来绕过这个限制。 + SIMILAR TOPOSIX 风格的正则表达式不支持非确定性排序规则。如有需要,可以使用 LIKE,或对表达式应用不同的排序规则来绕过这一限制。 @@ -58,7 +53,11 @@ - 如果pattern不包含百分号或者下划线,那么该模式只代表它本身的串;这时候LIKE的行为就象等号操作符。在pattern里的下划线 (_)代表(匹配)任何单个字符; 而一个百分号(%)匹配任何零或更多个字符的序列。 + 如果pattern不包含百分号或下划线,那么该模式只表示它 + 本身的字符串;在这种情况下,LIKE的行为就像等号操作符。 + pattern中的下划线(_)代表 + (匹配)任意单个字符;百分号(%)匹配任意由零个或多个 + 字符组成的序列。 @@ -72,18 +71,36 @@ - LIKE模式匹配总是覆盖整个串。因此,要匹配在串内任何位置的序列,该模式必须以百分号开头和结尾。 + LIKE 模式匹配支持非确定性排序规则(参见 ),例如不区分大小写的排序规则,或忽略标点符号的排序规则。因此,使用不区分大小写的排序规则时,可以得到: + +'AbC' LIKE 'abc' COLLATE case_insensitive true +'AbC' LIKE 'a%' COLLATE case_insensitive true + +对于忽略某些字符,或更一般地将不同长度的字符串视为相等的排序规则,语义会稍显复杂。考虑以下示例: + +'.foo.' LIKE 'foo' COLLATE ign_punct true +'.foo.' LIKE 'f_o' COLLATE ign_punct true +'.foo.' LIKE '_oo' COLLATE ign_punct false + +匹配时会把模式划分为通配符序列和非通配符字符串(通配符为 _%)。例如,模式 f_o 被划分为 f, _, o,模式 _oo 被划分为 _, oo。如果输入字符串能以某种方式划分,使通配符分别匹配一个字符或任意数量的字符,且非通配符片段在所用排序规则下相等,则输入字符串与模式匹配。例如,'.foo.' LIKE 'f_o' COLLATE ign_punct 为真,因为可以把 .foo. 划分为 .f, o, o.;此时 '.f' = 'f' COLLATE ign_punct'o' 匹配通配符 _,且 'o.' = 'o' COLLATE ign_punct。但 '.foo.' LIKE '_oo' COLLATE ign_punct 为假,因为无法将 .foo. 划分为首个字符匹配任意字符、而剩余字符串与 oo 比较相等的形式。(注意,单字符通配符始终恰好匹配一个字符,与排序规则无关。因此,在此示例中,_ 会匹配 .,但输入字符串的其余部分无法匹配模式的其余部分。) - 要匹配文本的下划线或者百分号,而不是匹配其它字符, 在pattern里相应的字符必须 前导转义字符。缺省的转义字符是反斜线,但是你可以用ESCAPE子句指定一个不同的转义字符。 要匹配转义字符本身,写两个转义字符。 + LIKE模式匹配总是覆盖整个字符串。因此,如果想要匹配字符串内 + 任意位置上的一个序列,该模式就必须以百分号开头并以百分号结尾。 + + + + 要匹配字面量下划线或百分号而不是把它们当作通配符, + pattern中相应的字符前面必须带有转义字符。 + 默认的转义字符是反斜线,但也可以使用ESCAPE子句选择其他 + 转义字符。要匹配转义字符本身,请写两个转义字符。 - 请注意反斜线在串文本里已经有特殊含义了,所以如果你写一个 包含反斜线的模式常量,那你就要在 SQL 语句里写两个反斜线。 因此,写一个匹配单个反斜线的模式实际上要在语句里写四个反斜线。 你可以通过用 ESCAPE 选择一个不同的转义字符 来避免这样;这样反斜线就不再是 LIKE 的特殊字符了。 但仍然是字符文本分析器的特殊字符,所以你还是需要两个反斜线。) - 我们也可以通过写ESCAPE ''的方式不选择转义字符,这样可以有效地禁用转义机制,但是没有办法关闭下划线和百分号在模式中的特殊含义。 + 也可以通过写 ESCAPE '' 来选择不使用转义字符。这会禁用转义机制,从而无法关闭模式中下划线和百分号的特殊含义。 @@ -92,7 +109,7 @@ - 关键字ILIKE可以用于替换LIKE,它令该匹配根据活动区域成为大小写无关。(但这不支持非确定性排序规则。)这个不属于SQL标准而是一个PostgreSQL扩展。 + 可以用关键字 ILIKE 代替 LIKE,使匹配根据当前区域设置忽略大小写。(但它不支持非确定性排序规则。)这不属于 SQL 标准,而是 PostgreSQL 的扩展。 @@ -103,14 +120,11 @@ - 短语LIKEILIKENOT LIKE,和 NOT ILIKEPostgreSQL语法中通常被视为操作符; - 例如,它们可以用于expression operator的任何(subquery)构造,尽管这里不能包含ESCAPE子句。 - 在某些晦涩难懂的情况下,可能需要用底层操作符名称替代。 + 在 PostgreSQL 语法中,LIKEILIKENOT LIKENOT ILIKE 通常被当作操作符;例如,它们可以用于 expression operator ANY (subquery) 构造,但其中不能包含 ESCAPE 子句。在某些不常见的情况下,可能需要改用底层操作符名称。 - 另请参阅以^@开头的操作符和相应的starts_with()函数, - 在需要简单匹配字符串开头的情况下非常有用。 + 另请参见用于匹配字符串开头的操作符 ^@ 和相应的 starts_with() 函数,它们适用于只需匹配字符串开头的情况。 @@ -119,8 +133,8 @@ <function>SIMILAR TO</function>正则表达式 - regular expression - + 正则表达式 + @@ -137,13 +151,11 @@ - SIMILAR TO操作符根据自己的模式是否匹配给定串而返回真或者假。 - 它和LIKE非常类似,只不过它使用 SQL 标准定义的正则表达式理解模式。 - SQL 正则表达式是在LIKE标记和普通的(POSIX)正则表达式标记的奇怪的杂交。 + SIMILAR TO操作符根据其模式是否匹配给定字符串返回真或假。它与LIKE非常相似,但使用 SQL 标准定义的正则表达式来解释模式。SQL 正则表达式是LIKE表示法与普通(POSIX)正则表达式表示法的一种奇特结合。 - 类似LIKESIMILAR TO操作符只有在它的模式匹配整个串的时候才能成功;这一点和普通的 正则表达式的行为不同,在普通的正则表达式里,模式匹配串的任意部分。 和LIKE类似的地方还有,SIMILAR TO使用_%作为分别代表任意单个字符和任意串的通配符(这些可以比得上 POSIX 正则表达式里的..*)。 + 与LIKE类似,SIMILAR TO操作符只有在其模式匹配整个字符串时才算成功;这一点不同于普通正则表达式,后者可以匹配字符串的任意部分。与LIKE相同,SIMILAR TO也使用_%作为通配符,分别匹配任意单个字符和任意字符串(分别类似于 POSIX 正则表达式中的..*)。 @@ -211,8 +223,7 @@ - 另一个非标准扩展是,在转义字符后面跟着一个字母或数字提供了对为POSIX正则表达式定义的转义序列的访问;参见下面的 - ,和 。 + 另一个非标准扩展是在转义字符后跟一个字母或数字,以使用 POSIX 正则表达式定义的转义序列;参见下文的 @@ -228,19 +239,19 @@ - 带有三个参数的substring函数可以提取匹配SQL正则表达式模式的子字符串。 该函数可以按照标准SQL99语法编写。 + 带有三个参数的substring函数可以提取匹配 SQL 正则表达式模式的子字符串。该函数可以按照标准 SQL 语法书写: substring(string SIMILAR pattern ESCAPE escape-character) - 或使用现在废除的 SQL:1999 语法: + 也可以使用现已过时的 SQL:1999 语法: substring(string FROM pattern FOR escape-character) - 或作为一个普通的三参数函数: + 或写成普通的三参数函数: substring(string, pattern, escape-character) - 与SIMILAR TO一样,指定的模式必须与整个数据字符串匹配,否则函数失败并返回空值。 为了表示匹配的数据子字符串的模式中,模式中应该包含两个转义字符的出现,并在后面加上一个双引号(")。 匹配成功后,将返回与这些分隔符之间的模式部分匹配的文本。 + 与SIMILAR TO一样,指定的模式必须匹配整个数据字符串,否则函数失败并返回空值。为了指明要提取的子字符串所对应的模式部分,模式中应包含两个分隔符,每个分隔符都由转义字符后跟双引号(")组成。匹配成功时,返回与这两个分隔符之间的模式部分匹配的文本。 @@ -248,7 +259,7 @@ substring(string, pattern, - 作为对SQL标准的扩展,PostgreSQL只允许有一个转义双引号分隔符,在这种情况下,第三个正则表达式被视为空;或者没有分隔符,在这种情况下,第一个和第三个正则表达式被视为空。 + 作为对SQL标准的扩展,PostgreSQL允许仅有一个转义双引号分隔符,在这种情况下,第三个正则表达式被视为空;或者没有分隔符,在这种情况下,第一个和第三个正则表达式被视为空。 @@ -265,8 +276,8 @@ substring('foobar' SIMILAR '#"o_b#"%' ESCAPE '#') NULLPOSIX正则表达式 - regular expression - pattern matching + 正则表达式 + 模式匹配 @@ -321,7 +332,7 @@ substring('foobar' SIMILAR '#"o_b#"%' ESCAPE '#') NULLboolean - 字符串匹配正则表达式,大小写敏感 + 字符串匹配正则表达式,区分大小写 'thomas' ~ 't.*ma' @@ -335,7 +346,7 @@ substring('foobar' SIMILAR '#"o_b#"%' ESCAPE '#') NULLboolean - 字符串匹配正则表达式,大小写不敏感 + 字符串匹配正则表达式,不区分大小写 'thomas' ~* 'T.*ma' @@ -349,7 +360,7 @@ substring('foobar' SIMILAR '#"o_b#"%' ESCAPE '#') NULLboolean - 字符串不匹配正则表达式,大小写敏感 + 字符串不匹配正则表达式,区分大小写 'thomas' !~ 't.*max' @@ -363,7 +374,7 @@ substring('foobar' SIMILAR '#"o_b#"%' ESCAPE '#') NULLboolean - 字符串不匹配正则表达式,大小写不敏感 + 字符串不匹配正则表达式,不区分大小写 'thomas' !~* 'T.*ma' @@ -375,11 +386,11 @@ substring('foobar' SIMILAR '#"o_b#"%' ESCAPE '#') NULL - POSIX正则表达式提供了比LIKESIMILAR TO操作符更强大的含义。许多 Unix 工具,例如grep -Esedawk使用一种与我们这里描述的类似的模式匹配语言。 + POSIX正则表达式提供了比LIKESIMILAR TO操作符更强大的模式匹配方式。许多 Unix 工具,例如grep -Esedawk,都使用与这里描述的模式匹配语言相似的语言。 - 正则表达式是一个字符序列,它是定义一个串集合 (一个正则集)的缩写。 如果一个串是正则表达式描述的正则集中的一员时, 我们就说这个串匹配该正则表达式。 和LIKE一样,模式字符准确地匹配串字符, 除非在正则表达式语言里有特殊字符 — 不过正则表达式用的 特殊字符和LIKE用的不同。 和LIKE模式不一样的是,正则表达式允许匹配串里的任何位置,除非该正则表达式显式地挂接在串的开头或者结尾。 + 正则表达式是一个字符序列,是定义一组字符串(一个正则集)的简写。如果字符串属于正则表达式描述的正则集,就称该字符串匹配此正则表达式。与LIKE一样,模式中的字符精确匹配字符串中的字符,除非该模式字符在正则表达式语言中有特殊含义 — 但正则表达式使用的特殊字符与LIKE不同。与LIKE模式不同,正则表达式可以匹配字符串中的任意位置,除非显式将其锚定到字符串开头或末尾。 @@ -463,9 +474,9 @@ substring('foobar' SIMILAR '#"o_b#"%' ESCAPE '#') NULLstring from pattern) text substring(string, pattern) text - (使用from的语法符合 SQL 标准,但 PostgreSQL 也允许使用逗号。) - 如果没有匹配它返回空值,否则就是匹配模式的文本中的第一部分。 - 但是如果该模式包含任何圆括号,那么将返回匹配第一对子表达式(对应第一个左圆括号的) 的文本。 + (使用from的语法符合 SQL 标准,但PostgreSQL也允许使用逗号。) + 如果没有匹配它返回空值,否则返回文本中首次匹配模式的那部分内容。 + 但是如果该模式包含任何圆括号,那么将返回匹配第一个圆括号子表达式(左圆括号最先出现的那个)的文本。 如果你想在表达式里使用圆括号而又不想导致这个例外,那么你可以在整个表达式外边放上一对圆括号。 如果你需要在想抽取的子表达式前有圆括号,参阅中描述的非捕获性圆括号。 @@ -499,7 +510,7 @@ regexp_count(string, pattern - 一些示例: + 一些示例: regexp_count('ABCABCAXYaxy', 'A.') 3 regexp_count('ABCABCAXYaxy', 'A.', 1, 'i') 4 @@ -514,7 +525,7 @@ regexp_count('ABCABCAXYaxy', 'A.', 1, 'i') 4 - regexp_instr函数返回字符串中第N个匹配项的起始或结束位置,如果没有这样的匹配项则返回零。 + regexp_instr函数返回 POSIX 正则表达式模式在字符串中第N个匹配项的起始或结束位置,如果没有这样的匹配项则返回零。 它的语法为: regexp_instr(string, pattern , start , N , endoption , flags , subexpr ) integer @@ -524,17 +535,17 @@ regexp_instr(string, patternendoption参数或将其指定为0,则函数返回匹配项的第一个字符的位置。否则,endoption 必须为1,函数返回匹配项后面字符的位置。 flags参数是一个可选的文本字符串,包含零个或多个单字母标志,可以改变函数的行为。支持的标志在中描述。 - 对于包含括号子表达式的模式,subexpr是一个整数,表示感兴趣的子表达式:结果标识与该子表达式匹配的子字符串的位置。 - 子表达式按其前导括号的顺序编号。 - 当省略或将subexpr指定为零时,结果标识整个匹配的位置,而不考虑括号子表达式。 + 对于包含圆括号子表达式的模式,subexpr是一个整数,表示感兴趣的子表达式:结果标识与该子表达式匹配的子字符串的位置。 + 子表达式按其左圆括号的顺序编号。 + 当省略或将subexpr指定为零时,结果标识整个匹配的位置,而不考虑圆括号子表达式。 - 一些示例: + 一些示例: regexp_instr('number of your street, town zip, FR', '[^,]+', 1, 2) 23 -regexp_instr('ABCDEFGHI', '(c..)(...)', 1, 1, 0, 'i', 2) +regexp_instr(string=>'ABCDEFGHI', pattern=>'(c..)(...)', start=>1, "N"=>1, endoption=>0, flags=>'i', subexpr=>2) 6 @@ -559,7 +570,7 @@ regexp_like(string, pattern - 一些示例: + 一些示例: regexp_like('Hello World', 'world') false regexp_like('Hello World', 'world', 'i') true @@ -574,19 +585,19 @@ regexp_like('Hello World', 'world', 'i') true - regexp_match函数返回一个文本数组,其中包含与POSIX正则表达式模式对字符串的第一个匹配的子字符串。它的语法为: + regexp_match函数返回一个文本数组,包含字符串首次匹配 POSIX 正则表达式模式时匹配的子字符串。它的语法为: regexp_match(string, pattern , flags ) text[] 如果没有匹配,结果为NULL。 - 如果找到匹配,并且pattern不包含括号子表达式,则结果是包含与整个模式匹配的子字符串的单元素文本数组。 - 如果找到匹配,并且pattern包含括号子表达式,则结果是一个文本数组,其中第n个元素是匹配 - pattern的第n个括号子表达式的子字符串(不包括非捕获括号;详情见)。 + 如果找到匹配,并且pattern不包含圆括号子表达式,则结果是包含与整个模式匹配的子字符串的单元素文本数组。 + 如果找到匹配,并且pattern包含圆括号子表达式,则结果是一个文本数组,其中第n个元素是匹配 + pattern的第n个圆括号子表达式的子字符串(不包括非捕获括号;详情见)。 flags参数是一个可选的文本字符串,其中包含零个或多个单个字母标志,用于更改函数的行为。支持的标志在中描述。 - 一些示例: + 一些示例: SELECT regexp_match('foobarbequebaz', 'bar.*que'); regexp_match @@ -605,10 +616,10 @@ SELECT regexp_match('foobarbequebaz', '(bar)(beque)'); - 在通常情况下,当您只想要整个匹配的子字符串或NULL表示没有匹配时, + 在通常情况下,当你只想要整个匹配的子字符串或NULL表示没有匹配时, 最好的解决方案是使用regexp_substr()。 然而,在PostgreSQL版本15及以上版本中才存在 - regexp_substr()。在旧版本中工作时,您可以提取 + regexp_substr()。在旧版本中工作时,你可以提取 regexp_match()结果的第一个元素,例如: SELECT (regexp_match('foobarbequebaz', 'bar.*que'))[1]; @@ -662,11 +673,11 @@ SELECT regexp_matches('foobarbequebazilbarfbonk', '(b[^b]+)(b[^b]+)', 'g'); - 在大部分情况下,regexp_matches()应该与g标志一起使用,因为如果只是想要第一个匹配,使用regexp_match()会更加简单高效。不过,regexp_match()仅存在于PostgreSQL版本10以及更高的版本中。当在较老的版本中使用时,一种常用的技巧是把regexp_matches()调用放在子选择中,例如: + 在大部分情况下,regexp_matches()应该与g标志一起使用,因为如果只是想要第一个匹配,使用regexp_match()会更加简单高效。不过,regexp_match()仅存在于PostgreSQL版本10以及更高的版本中。当在较老的版本中使用时,一种常用的技巧是把regexp_matches()调用放在子查询中,例如: SELECT col1, (SELECT regexp_matches(col2, '(bar)(beque)')) FROM tab; - 如果有一个匹配,则这个语句会产生一个文本数组,否则返回NULL,这和regexp_match()的做法一样。如果没有子选择,这个查询对于没有匹配的表行根本不会产生输出,显然那不是想要的行为。 + 如果有一个匹配,则这个语句会产生一个文本数组,否则返回NULL,这和regexp_match()的做法一样。如果没有子查询,这个查询对于没有匹配的表行根本不会产生输出,这通常不是预期行为。 @@ -678,30 +689,16 @@ SELECT col1, (SELECT regexp_matches(col2, '(bar)(beque)')) FROM tab; - regexp_replace函数提供了对匹配POSIX正则表达式模式的子字符串进行替换的功能。 - 它的语法为: + regexp_replace函数将匹配 POSIX 正则表达式模式的子字符串替换为新文本。它的语法为: regexp_replace(string, pattern, replacement , flags ) text regexp_replace(string, pattern, replacement, start , N , flags ) text - 如果pattern没有匹配到string字符串, - 则返回未更改的string字符串。如果有匹配,则返回带有 - replacement字符串替换匹配子字符串的string字符串。 - replacement字符串可以包含\n, - 其中n为1至9,表示应插入与模式的第n个括号子表达式匹配的源子字符串, - 也可以包含\&表示应插入与整个模式匹配的子字符串。 - 如果需要在替换文本中放置一个字面上的反斜杠,则写\\。 - 在string中搜索pattern, - 通常从字符串的开头开始,但如果提供了start参数,则从该字符索引开始。 - 默认情况下,只替换模式的第一个匹配项。 - 如果指定了N且大于零,则替换模式的第N个匹配项。 - 如果给出了g标志,或者指定了N且为零,则在start位置或之后的所有匹配项都将被替换。 (当指定了N时,g标志将被忽略。) - flags参数是一个可选的文本字符串,包含零个或多个单字母标志,用于更改函数的行为。 - 支持的标志(尽管不包括g)在中描述。 +如果没有匹配pattern的内容,则原样返回源字符串string。如果有匹配,则返回将匹配的子字符串替换为replacement后的stringreplacement字符串可以包含\n,其中n为 1 至 9,表示插入与模式中第n个圆括号子表达式匹配的源子字符串;也可以包含\&,表示插入与整个模式匹配的子字符串。要在替换文本中放入字面的反斜线,应写成\\。在string中搜索pattern时,通常从字符串开头开始;如果提供了start参数,则从该字符索引开始。默认只替换模式的第一个匹配项。如果指定了N且其值大于零,则替换模式的第N个匹配项。如果给出g标志,或指定了N且其值为零,则替换start位置及其后的所有匹配项。(指定N时,g标志会被忽略。)flags参数是可选的文本字符串,可包含零个或多个单字母标志,用于改变函数行为。支持的标志(不包括g)在中介绍。 - 一些示例: + 一些示例: regexp_replace('foobarbaz', 'b..', 'X') fooXbaz @@ -711,7 +708,7 @@ regexp_replace('foobarbaz', 'b(..)', 'X\1Y', 'g') fooXarYXazY regexp_replace('A PostgreSQL function', 'a|e|i|o|u', 'X', 1, 0, 'i') X PXstgrXSQL fXnctXXn -regexp_replace('A PostgreSQL function', 'a|e|i|o|u', 'X', 1, 3, 'i') +regexp_replace(string=>'A PostgreSQL function', pattern=>'a|e|i|o|u', replacement=>'X', start=>1, "N"=>3, flags=>'i') A PostgrXSQL function @@ -724,11 +721,11 @@ regexp_replace('A PostgreSQL function', 'a|e|i|o|u', 'X', 1, 3, 'i') - regexp_split_to_table把一个 POSIX 正则表达式模式当作一个定界符来分离一个串。它的语法形式是: + regexp_split_to_table把一个 POSIX 正则表达式模式当作一个定界符来分割字符串。它的语法形式是: regexp_split_to_table(string, pattern , flags ) setof text -如果没有与pattern的匹配,该函数返回string。如果有至少有一个匹配,对每一个匹配它都返回从上一个匹配的末尾(或者串的开头)到这次匹配开头之间的文本。当没有更多匹配时,它返回从上一次匹配的末尾到串末尾之间的文本。flags参数是一个可选的文本串,它包含零个或更多单字母标志,这些标识可以改变该函数的行为。regexp_split_to_table能支持的标志在中描述。 +如果没有与pattern的匹配,该函数返回string。如果至少有一个匹配,对每一个匹配它都返回从上一个匹配的末尾(或者串的开头)到这次匹配开头之间的文本。当没有更多匹配时,它返回从上一次匹配的末尾到串末尾之间的文本。flags参数是一个可选的文本串,它包含零个或更多单字母标志,这些标志可以改变该函数的行为。regexp_split_to_table能支持的标志在中描述。 @@ -773,8 +770,8 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; 正如最后一个示例所示,regexp_split_to_table会忽略出现在字符串开头或结尾 - 或紧跟在前一个匹配项之后的零长度匹配。这与其他regexp函数实现的 - 严格的regexp匹配定义相矛盾,但在实践中通常是最方便的行为。 + 或紧跟在前一个匹配项之后的零长度匹配。这与其他正则表达式函数实现的 + 严格的正则表达式匹配定义相矛盾,但在实践中通常是最方便的行为。 其他软件系统如Perl使用类似的定义。 @@ -822,17 +819,17 @@ regexp_substr(string, patternN,则返回模式的第N次匹配, 否则返回第一次匹配。参数flags是一个可选文本字符串, 包含零个或多个单字母标志,可以改变函数的行为。支持的标志在中描述。 - 对于包含括号子表达式的模式,subexpr是一个整数, + 对于包含圆括号子表达式的模式,subexpr是一个整数, 表示感兴趣的子表达式:结果是与该子表达式匹配的子字符串。 - 子表达式按其前导括号的顺序编号。 - 当省略或为零时,subexpr的结果是整个匹配,而不考虑括号子表达式。 + 子表达式按其左圆括号的顺序编号。 + 当subexpr省略或为零时,结果是整个匹配,而不考虑圆括号子表达式。 - 一些示例: + 一些示例: regexp_substr('number of your street, town zip, FR', '[^,]+', 1, 2) - 城镇 邮编 + town zip regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) FGH @@ -869,7 +866,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 一个量化原子是一个原子, 后面可能跟着一个量词。没有量词的时候,它匹配一个原子, 有量词的时候,它可以匹配若干个原子。一个原子可以是在里面显示的任何可能。 可能的量词和它们的含义在里显示。 + 一个量化原子是一个原子,后面可以跟一个量词。没有量词时,匹配一次原子所匹配的内容;有量词时,按量词指定的次数匹配原子所匹配的内容。原子可以是列出的任何一种形式。可用量词及其含义见 @@ -897,12 +894,12 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) (re) - (其中re是任何正则表达式) 匹配一个对re的匹配,匹配将为可能的报告被记下 + (其中re是任意正则表达式)匹配re所匹配的内容,并记录该匹配,以备输出结果 (?:re) - 同上,但是匹配不会为了报告而被记下 (一个非捕获圆括号集) (只对 ARE) + 同上,但不记录匹配结果(非捕获圆括号;仅适用于 ARE) @@ -917,17 +914,17 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) \k - (其中k是一个非字母数字字符) 匹配一个被当作普通字符看待的特定字符, 例如,\\匹配一个反斜线字符 + (其中k既不是字母也不是数字)把该字符视为普通字符并匹配它,例如,\\匹配反斜线字符 \c - 其中c是一个字母数字 (可能跟着其它字符),它是一个转义, 参阅(仅对 ARE; 在 ERE 和 BRE 中,它匹配c + 其中c是字母或数字(后面可能还有其他字符),这是一个转义,参见(仅适用于 ARE;在 ERE 和 BRE 中,它匹配c { - 如果后面跟着一个字符,而不是数字, 那么就匹配左花括弧{;如果跟着一个数字, 那么它是range的开始(见下文) + 如果后面跟着非数字字符,则匹配左花括号{;如果后面跟着数字,则是bound的开头(见下文) @@ -1033,7 +1030,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 非贪婪的量词(只在 ARE 中可用)匹配对应的正常 (贪婪)模式,区别是它寻找最少的匹配,而不是最多的匹配。详见。 + 非贪婪量词(仅适用于 ARE)与对应的普通(贪婪)量词匹配相同的可能内容,但优先选择最少的匹配次数,而不是最多的匹配次数。详见 @@ -1064,39 +1061,39 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) ^ - 串开头的匹配 + 在字符串开头匹配 $ - 串末尾的匹配 + 在字符串末尾匹配 (?=re) - 在某个位置上,如果从该位置开始的子串能够匹配re,则匹配正向先行断言(仅对 ARE) + 正向先行断言在这样的位置匹配:存在从该位置开始且匹配re的子字符串(仅适用于 ARE) (?!re) - 在某个位置上,如果从该位置开始的子串不能匹配re,则匹配负向先行断言(仅对 ARE) + 负向先行断言在这样的位置匹配:不存在任何从该位置开始且匹配re的子字符串(仅适用于 ARE) (?<=re) - 在某个位置上,如果以该位置结束的某个子串能够匹配re,则匹配正向后行断言(仅对 ARE) + 正向后行断言在这样的位置匹配:存在以该位置结束且匹配re的子字符串(仅适用于 ARE) (?<!re) - 在某个位置上,如果以该位置结束的任何子串都不能匹配re,则匹配负向后行断言(仅对 ARE) + 负向后行断言在这样的位置匹配:不存在任何以该位置结束且匹配re的子字符串(仅适用于 ARE)
- Lookahead 和 lookbehind 约束不能包含反向引用 (参阅),并且其中的所有圆括号 都被认为是非捕获的。 + 先行和后行约束不能包含反向引用(参见),其中的所有圆括号都视为非捕获圆括号。
@@ -1105,11 +1102,11 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) 方括号表达式 - 方括号表达式是一个包围在[]中的字符列表。它通常匹配列表中的任意单个字符(但见下文)。 如果列表以^开头,它匹配任意单个在该列表参与部分中的字符。如果该列表中两个字符用-隔开, 那它就是那两个字符(包括在内)之间的所有字符范围的缩写,例如,在ASCII[0-9]匹配任何十进制数字。两个范围共享一个端点是非法的,例如,a-c-e。范围与字符集关系密切, 可移植的程序应该避免依靠它们。 + 方括号表达式是用[]括起来的字符列表。通常,它匹配列表中的任意单个字符(但请参见下文)。如果列表以^开头,则匹配任意在列表剩余部分中的单个字符。如果列表中的两个字符用-分隔,则表示排序序列中这两个字符之间的完整字符范围(包含两个端点);例如,ASCII中的[0-9]匹配任意十进制数字。两个范围共享一个端点是不合法的,例如a-c-e。范围高度依赖排序序列,因此可移植程序应避免依赖它们。 - 想在列表中包含文本],可以让它做列表的首字符(如果使用了^,需要放在其后)。 想在列表中包含文本-,可以让它做列表的首字符或者尾字符,或者一个范围的第二个端点。 想在列表中把文本-当做范围的起点, 把它用[..]包围起来,这样它就成为一个排序元素(见下文)。 除了这些字符本身、一些用[的组合(见下段)以及转义(只在 ARE 中有效)以外,所有其它特殊字符 在方括号表达式里都失去它们的特殊含义。特别是,在 ERE 和 BRE 规则下\不是特殊的, 但在 ARE 里,它是特殊的(引入一个转义)。 + 想在列表中包含字面字符],可以让它做列表的首字符(如果使用了^,需要放在其后)。 想在列表中包含字面字符-,可以让它做列表的首字符或者尾字符,或者一个范围的第二个端点。 想在列表中把字面字符-当做范围的起点, 把它用[..]包围起来,这样它就成为一个排序元素(见下文)。 除了这些字符本身、一些用[的组合(见下段)以及转义(只在 ARE 中有效)以外,所有其它特殊字符 在方括号表达式里都失去它们的特殊含义。特别是,在 ERE 和 BRE 规则下\不是特殊的, 但在 ARE 里,它是特殊的(引入一个转义)。 @@ -1124,30 +1121,11 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 在方括号表达式里,包围在[==]里的排序元素是一个等价类, 代表等效于那一个的所有排序元素的字符序列,包括它本身(如果没有其它等效排序元素,那么就好象封装定界符是[..])。例如,如果o^是一个等价类的成员,那么[[=o=]][[=^=]][o^]都是同义的。一个等价类不能是一个范围的端点。 + 在方括号表达式里,包围在[==]里的排序元素是一个等价类, 代表等效于那一个的所有排序元素的字符序列,包括它本身(如果没有其它等效排序元素,那么就好像封装定界符是[..])。例如,如果o^是一个等价类的成员,那么[[=o=]][[=^=]][o^]都是同义的。一个等价类不能是一个范围的端点。 - 在方括号表达式里,在[::]里面封装的字符类的名字代表属于该类的所有字符的列表。 - 字符类不能作为范围的端点使用。 - POSIX标准定义了这些字符类的名称: - alnum (字符和数字), - alpha (字符), - blank (空格和制表符tab), - cntrl (控制符), - digit (数位数), - graph (空格除外可打印字符), - lower (小写字母), - print (包含空格可打印字符), - punct (标点符号), - space (空白), - upper (大写字母), - 和 xdigit (十六进制数). - 对于7位ASCII字符集中的字符来说,这些标准字符类的行为在不同平台上一般是一致的。 - 一个给定的非 ASCII 字符是否被认为属于这些类别中的一个,取决于正则表达式函数或操作符所使用的排序规则(见),或者在默认情况下取决于数据库的LC_CTYPE locale 设置(见)。 - 非ASCII字符的分类在不同的平台上会有不同的分类,即使是在类似命名的locale中也是如此。 - (但C locale从不认为任何非ASCII字符属于上述任何一类)。 - 除了这些标准字符类之外,PostgreSQL定义了word字符类,等同于alnum加上下划线(_), 以及ascii字符类,它完全包含7位ASCII字符集。 + 在方括号表达式中,用[::]括起来的字符类名称表示属于该类的所有字符。字符类不能作为范围的端点。POSIX标准定义了以下字符类名称:alnum(字母和数字)、alpha(字母)、blank(空格和制表符)、cntrl(控制字符)、digit(数字)、graph(空格以外的可打印字符)、lower(小写字母)、print(包括空格的可打印字符)、punct(标点符号)、space(任意空白字符)、upper(大写字母)和xdigit(十六进制数字)。对于 7 位 ASCII 字符集中的字符,这些标准字符类在各平台上的行为通常一致。给定的非 ASCII 字符是否属于其中某个类,取决于正则表达式函数或操作符使用的排序规则(参见),默认则取决于数据库的LC_CTYPE区域设置(参见)。即使区域设置名称相似,非 ASCII 字符的分类也可能因平台而异。(但C区域设置不会将任何非 ASCII 字符归入这些类。)除了这些标准字符类,PostgreSQL还定义了word字符类,即alnum加上下划线(_),以及恰好包含 7 位 ASCII 字符集的ascii字符类。 @@ -1164,11 +1142,11 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) 正则表达式转义 - 转义是以\开头,后面跟着一个字母数字字符的特殊序列。 转义有好几种变体:字符输入转义、字符类简写转义、约束转义以及反向引用。在 ARE 里, 如果一个\后面跟着一个字母数字,但是并未组成一个合法的转义, 那么它是非法的。在 ERE 中没有转义:在方括号表达式之外,一个后面跟着字母数字字符的\只是表示该字符是一个普通的字符,而且在一个方括号表达式里,\是一个普通的字符(后者实际上在 ERE 和 ARE 不兼容)。 + 转义是以\开头,后面跟着一个字母或数字字符的特殊序列。 转义有好几种变体:字符输入转义、字符类简写转义、约束转义以及反向引用。在 ARE 里, 如果一个\后面跟着一个字母或数字,但是并未组成一个合法的转义, 那么它是非法的。在 ERE 中没有转义:在方括号表达式之外,一个后面跟着字母或数字字符的\只是表示该字符是一个普通的字符,而且在一个方括号表达式里,\是一个普通的字符(后者是 ERE 与 ARE 之间唯一的实际不兼容之处)。 - 字符输入转义用于便于我们在 RE 中声明那些不可打印的或其他习惯的字符。它们显示在中。 + 字符输入转义便于在 RE 中指定不可打印或其他不便输入的字符,见 @@ -1176,13 +1154,13 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 约束转义是一个约束,如果满足特定的条件,它匹配该空串。它们显示在中。 + 约束转义是以转义形式书写的约束,在满足特定条件时匹配空字符串,见 - 反向引用\n)匹配数字\n指定的被前面的圆括号子表达式匹配的同一个串 (参阅)。 + 反向引用\n)匹配前面编号为n的圆括号子表达式所匹配的同一字符串 (参阅)。 例如, ([bc])\1匹配bb或者cc, 但是不匹配bc或者cb。 - RE 中子表达式必须完全在反向引用前面。子表达式以它们的先导圆括号的顺序编号。 + RE 中子表达式必须完全在反向引用前面。子表达式以它们的左圆括号的顺序编号。 非捕获圆括号并不定义子表达式。 反向引用仅考虑被引用的子表达式匹配的字符串字符,而不考虑其中包含的任何约束。 例如,(^\d)\1 将匹配 22。 @@ -1229,7 +1207,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) \e - 排序序列名为ESC的字符,如果无法做到该字符为八进制值 033 + 排序序列名称为ESC的字符;若不存在这样的字符,则使用八进制值为033的字符 @@ -1239,7 +1217,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) \n - 新行,和 C 中一样 + 换行符,与 C 中相同 @@ -1367,7 +1345,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 类-缩写转义也适用于括号表达式,尽管上面显示的定义在该上下文中在语法上并不完全有效。 + 字符类简写转义也适用于括号表达式,尽管上面显示的定义在该上下文中在语法上并不完全有效。 例如,[a-c\d] 等同于 [a-c[:digit:]] @@ -1412,7 +1390,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) \Y - 只在一个词的不是开头或末尾的点上匹配 + 只在不属于单词开头或末尾的位置匹配 @@ -1424,7 +1402,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 一个词被定义成在上面[[:<:]][[:>:]]中的声明。在方括号表达式里,约束转义是非法的。 + 单词的定义与上文[[:<:]][[:>:]]的说明相同。方括号表达式中不允许使用约束转义。 @@ -1433,9 +1411,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - - @@ -1448,12 +1424,12 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) \m - (其中m是一个非零位)一个到第m个子表达式的反向引用 + (其中m是一个非零数字)一个到第m个子表达式的反向引用 \mnn - (其中m是一个非零位,并且nn是一些更多的位,并且十六进制值mnn不超过目前能看到的封闭捕获圆括号的数目)一个到第mnn个子表达式的反向引用 + (其中m是一个非零数字,并且nn是后续的若干数字,并且十进制值mnn不大于此前已出现的捕获右圆括号数)一个到第mnn个子表达式的反向引用 @@ -1462,7 +1438,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 在八进制字符输入转义和反向引用之间有一个历史继承的歧义存在,这个歧义是 通过下面的启发式规则解决的,像上面描述地那样。前导零总是表示这是一个八进制转义。 而单个非零数字,如果没有跟着任何其它位,那么总是被认为反向引用。 一个多位的非零开头的序列也被认为是反向引用,只要它出现在合适的子表达式后面 (也就是说,在反向引用的合法范围中的数),否则就被认为是一个八进制。 + 八进制字符输入转义与反向引用之间存在固有歧义,按上文提到的启发式规则解决:前导零始终表示八进制转义。单个非零数字,如果后面没有其他数字,始终视为反向引用。不以零开头的多位数字序列,如果前面已有相应的子表达式(即该数字在反向引用的合法范围内),则视为反向引用,否则视为八进制转义。 @@ -1476,11 +1452,11 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 如果一个 RE 以***:开头,那么剩下的 RE 都被当作 ARE(这在PostgreSQL中通常是无效的,因为 RE 被假定为 ARE,但是如果 ERE 或 BRE 模式通过flags参数被指定为一个正则表达式函数时,它确实能产生效果)。如果一个 RE 以***=开头, 那么剩下的 RE 被当作一个文本串,所有的字符都被认为是一个普通字符。 + RE 可以以两种特殊的引导前缀之一开头。如果 RE 以***:开头,余下部分就被视为 ARE。(这在PostgreSQL中通常没有影响,因为 RE 默认被视为 ARE;但如果通过正则表达式函数的flags参数指定了 ERE 或 BRE 模式,它就会产生影响。)如果 RE 以***=开头,余下部分就作为按字面解释的字符串处理,所有字符都视为普通字符。 - 一个 ARE 可以以嵌入选项开头:一个序列(?xyz)(这里的xyz是一个或多个字母字符)声明影响剩余 RE 的选项。 这些选项覆盖任何前面判断的选项 — 特别地,它们可以覆盖一个正则表达式操作符隐含的大小写敏感的行为,或者覆盖flags参数中的正则表达式函数。可用的选项字母在中显示。注意这些同样的选项字母也被用在正则表达式函数的flags参数中。 + 一个 ARE 可以以嵌入选项开头:一个序列(?xyz)(这里的xyz是一个或多个字母字符)声明影响剩余 RE 的选项。 这些选项覆盖任何先前确定的选项 — 特别地,它们可以覆盖一个正则表达式操作符隐含的大小写敏感的行为,或者覆盖正则表达式函数的flags参数所指定的选项。可用的选项字母在中显示。注意这些同样的选项字母也被用在正则表达式函数的flags参数中。
@@ -1529,32 +1505,32 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) n - 新行敏感的匹配(见 + 换行敏感的匹配(见 p - 部分新行敏感的匹配(见 + 部分换行敏感的匹配(见 q - RE的剩余部分是一个文字(quoted)串,全部是普通字符 + RE 的剩余部分按字面(加引号)解释,所有字符都视为普通字符 s - 非新行敏感的匹配(默认) + 非换行敏感的匹配(默认) t - 紧语法(默认,见下文) + 紧凑语法(默认;见下文) w - 逆部分新行敏感(怪异)的匹配(见 + 逆部分换行敏感(怪异)的匹配(见 @@ -1566,16 +1542,16 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2)
- 嵌入选项在)终止序列时发生作用。它们只在 ARE 的开始处起作用 (在任何可能存在的***:控制器后面)。 + 嵌入选项从结束该序列的)处开始生效。它们只能出现在 ARE 的开头(如果存在***:引导前缀,则位于该前缀之后)。 - 除了通常的()RE 语法(这种情况下所有字符都有效), 还有一种扩展语法,可以通过声明嵌入的x选项获得。在扩展语法里,RE 中的空白字符被忽略,就像那些在#和其后的新行(或 RE 的末尾)之间的字符一样。这样就允许我们给一个复杂的 RE 分段和注释。不过这个基本规则有三种例外: + 除了通常的紧凑 RE 语法(其中所有字符都有意义)之外,还有一种扩展语法,可以通过指定嵌入的x选项来使用。在扩展语法中,RE 中的空白字符会被忽略,同样被忽略的还有#与其后的换行符(或 RE 末尾)之间的所有字符。这使得复杂的 RE 可以分段并添加注释。此基本规则有三个例外: - 空白字符或前置了\#将被保留 + 空白字符或 # 的前面若有 \,该字符就会被保留。 @@ -1590,14 +1566,14 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 为了这个目的,空白是空格、制表符、新行以及任何属于 whitespace 字符类的字符。 + 在这里,空白字符包括空格、制表符、换行符,以及属于space字符类的任何字符。 - 最后,在 ARE 里,方括号表达式外面,序列(?#ttt)(其中ttt是任意不包含一个))的文本)是一个注释, 它被完全忽略。同样,这样的东西是不允许出现在多字符符号的字符中间的,例如 (?:。这种注释更像是一种历史产物而不是一种有用的设施,并且它们的使用已经被废弃;请使用扩展语法来替代。 + 最后,在 ARE 里,方括号表达式外面,序列(?#ttt)(其中ttt是任意不包含一个)的文本)是一个注释, 它被完全忽略。同样,这样的东西是不允许出现在多字符符号的字符中间的,例如 (?:。这种注释更像是一种历史产物而不是一种有用的设施,并且它们的使用已经被废弃;请使用扩展语法来替代。
- 如果声明了一个初始的***=控制器,那么所有这些元语法扩展都不能使用,因为这样表示把用户输入当作一个文字串而不是 RE 对待。 + 如果指定了开头的***=引导前缀,那么这些元语法扩展都不能使用,因为这表示把用户输入作为按字面解释的字符串,而非 RE 处理。 @@ -1614,7 +1590,7 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) - 大多数原子以及所有约束,都没有贪婪属性(因为它们毕竟无法匹配个数变化的文本)。 + 大多数原子以及所有约束,都没有贪婪属性(因为它们毕竟无法匹配长度不定的文本)。 @@ -1666,7 +1642,7 @@ SELECT SUBSTRING('XY1234Z', 'Y*?([0-9]{1,3})');
- 简而言之,如果一个 RE 同时包含贪婪和非贪婪的子表达式,那么总的匹配长度要么是尽可能长,要么是尽可能短,这取决于给整个 RE 赋予的属性。给子表达式赋予的属性只影响在这个匹配里,各个子表达式之间相互允许吃掉的多少。 + 简而言之,如果一个 RE 同时包含贪婪和非贪婪的子表达式,那么总的匹配长度要么是尽可能长,要么是尽可能短,这取决于给整个 RE 赋予的属性。给子表达式赋予的属性只影响在这个匹配里,各个子表达式相对于其他子表达式能吃掉多少内容。 @@ -1700,23 +1676,23 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 如果声明了大小写无关的匹配,那么效果就好像所有大小写区别在字母表中消失了。如果在多个情况中一个字母以一个普通字符的形式出现在方括号表达式外面,那么它实际上被转换成 一个包含大小写的方括号表达式,也就是说,x 变成 [xX]。 如果它出现在一个方括号表达式里面,那么它的所有大小写的同族都被加入 方括号表达式中,也就是说,x变成[xX]。当它出现在一个方括号表达式内时,它的所有大小写副本都被加入到方括号表达式中,例如, [x]会变成[xX],而[^x]会变成[^xX]。 + 如果指定不区分大小写的匹配,其效果近似于字母表中的所有大小写差别都消失了。当存在大小写形式的字母作为普通字符出现在方括号表达式之外时,实际上会转换为包含其大小写形式的方括号表达式,例如x变成[xX]。当它出现在方括号表达式内部时,其所有大小写形式都会加入该表达式,例如[x]变成[xX][^x]变成[^xX] 如果指定了换行敏感的匹配,.和使用^的方括号表达式 将永远不会匹配换行字符(这样,匹配就不会跨越行,除非 RE 显式地包含了换行)并且^$除了分别匹配串开头和结尾之外,还将分别匹配换行后面和前面的空串。 但是 ARE 转义\A\Z仍然匹配串的开头和结尾。 - 此外,字符类缩写符\D\W将匹配换行,而无论这种模式如何。 + 此外,字符类简写\D\W将匹配换行,而无论这种模式如何。 (在PostgreSQL 14之前,它们在换行敏感模式下不匹配换行。 写入[^[:digit:]][^[:word:]]以获取旧的行为。) - 如果指定了部分新行敏感的匹配,那么它影响.和方括号表达式, 这个时候和新行敏感的匹配一样,但是不影响^$。 + 如果指定了部分换行敏感的匹配,那么它影响.和方括号表达式, 这个时候和换行敏感的匹配一样,但是不影响^$ - 如果指定了逆新行敏感匹配,那么它影响^$,其作用和在新行敏感的匹配里一样,但是不影响.和方括号表达式。这个并不是很有用,只是为了满足对称性而提供的。 + 如果指定了逆部分换行敏感匹配,那么它影响^$,其作用和在换行敏感的匹配里一样,但是不影响.和方括号表达式。这个并不是很有用,只是为了满足对称性而提供的。 @@ -1729,11 +1705,11 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}');
- ARE 实际上和 POSIX ERE 不兼容的唯一的特性是在方括号表达式里\并不失去它特殊的含义。所有其它 ARE 特性都使用在 POSIX ERE 里面是非法或者是未定义、未声明效果的语法;指示器的***就是在 POSIX 的 BRE 和 ERE 之外的语法。 + ARE 与 POSIX ERE 实际不兼容的唯一特性是:\在方括号表达式中不会失去特殊含义。其他所有 ARE 特性所使用的语法,在 POSIX ERE 中都是非法的,或其效果未定义或未指定;引导前缀的***语法同样不属于 POSIX 的 BRE 或 ERE 语法。 - 许多 ARE 扩展都是从 Perl 那里借来的(但是有些被做了修改来清理它们),以及一些 Perl 里没有出现的扩展。要注意的不兼容性包括\b\B、对结尾的新行缺乏特别的处理、对那些被新行敏感匹配的东西附加的补齐方括号表达式、在 lookahead/lookbehind 约束里对圆括号和反向引用的限制以及最长/最短 匹配(而不是第一匹配)的语义。 + 许多 ARE 扩展借鉴自 Perl,但其中一些经过了整理和修改,也未实现少数 Perl 扩展。需要注意的不兼容之处包括\b\B、不对末尾换行符作特殊处理、取反的方括号表达式也受换行敏感匹配影响、先行和后行约束中对圆括号及反向引用的限制,以及采用最长或最短匹配而非首次匹配的语义。 @@ -1742,7 +1718,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); 基本正则表达式 - BREs 在几个方面和 ERE 不太一样。在 BRE 中,|+?都是普通字符并且没有与它们功能等价的东西。范围的定界符是\{\}, 因为 {}本身是普通字符。嵌套的子表达式的圆括号是\(\),因为()自身是普通字符。除非在 RE 开头或者是圆括号子表达式开头,^都是一个普通字符。 除非在 RE 结尾或者是圆括号子表达式的结尾,$是一个普通字符。如果*出现在 RE 开头或者是圆括号封装的子表达式开头 (前面可能有^),那么它是个普通字符。最后,可以用单数字的反向引用,\<\>分别是[[:<:]][[:>:]]的同义词;在 BRE 中没有其它可用的转义。 + BRE 在几个方面和 ERE 不太一样。在 BRE 中,|+?都是普通字符并且没有与它们功能等价的东西。范围的定界符是\{\},而{}本身是普通字符。嵌套的子表达式的圆括号是\(\),而()自身是普通字符。除非在 RE 开头或者是圆括号子表达式开头,^都是一个普通字符。 除非在 RE 结尾或者是圆括号子表达式的结尾,$是一个普通字符。如果*出现在 RE 开头或者是圆括号封装的子表达式开头 (前面可能有^),那么它是个普通字符。最后,可以用单数字的反向引用,\<\>分别是[[:<:]][[:>:]]的同义词;在 BRE 中没有其它可用的转义。 @@ -1798,7 +1774,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); SQL标准 - PostgreSQL + PostgreSQL @@ -1855,16 +1831,13 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 使用\p{UnicodeProperty}或其反义\P{UnicodeProperty}来定义XQuery字符类元素是不被支持的。 + 使用\p{UnicodeProperty}或其取反形式\P{UnicodeProperty}来定义XQuery字符类元素是不被支持的。 - POSIX解释字符类,如\w - (参见) - 根据当前区域设置(你可以通过将COLLATE子句附加到操作符或函数上来控制)。 - XQuery通过参考Unicode字符属性来指定这些类别,因此只有遵循Unicode规则的区域设置才能获得等效行为。 + POSIX 根据当前区域设置解释\w等字符类(参见);你可以通过为操作符或函数附加COLLATE子句来控制该区域设置。XQuery 根据 Unicode 字符属性定义这些类,因此只有使用遵循 Unicode 规则的区域设置时,才能得到等效行为。 @@ -1877,10 +1850,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - 在描述的字符输入转义中 - 中, - XQuery仅支持\n\r, - 和\t。 + 在描述的字符输入转义中,XQuery 仅支持 \n\r\t @@ -1892,7 +1862,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); - XQuery没有前瞻或后顾约束,也没有在中描述的任何约束转义。 + XQuery没有先行或后行约束,也没有在中描述的任何约束转义。 @@ -1912,7 +1882,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); XQuery的s(允许点匹配换行符) 和m(允许^ - 和$匹配换行符)标志提供 + 和$在换行处匹配)标志提供 与POSIX的npw标志相同的行为,但它们 匹配POSIX的sm标志的行为。 diff --git a/zh/20/func/func-math.sgml b/zh/20/func/func-math.sgml index 56ec8a13..7180193a 100644 --- a/zh/20/func/func-math.sgml +++ b/zh/20/func/func-math.sgml @@ -3,12 +3,12 @@ 数学函数和操作符 - PostgreSQL为很多类型提供了数学操作符。对于那些没有标准数学表达的类型(如日期/时间类型),我们将在后续小节中描述实际的行为。 + PostgreSQL为很多类型提供了数学操作符。对于那些没有标准数学惯例的类型(如日期/时间类型),我们将在后续小节中描述实际的行为。 - 显示了可用于标准数字类型的数学操作符。 - 除非另有说明, 显示为可接受 numeric_type 的操作符对所有的 smallintintegerbigintnumericrealdouble precision类型都可用。 + 显示了可用于标准数值类型的数学操作符。 + 除非另有说明, 显示为可接受 numeric_type 的操作符对所有的 smallintintegerbigintnumericrealdouble precision类型都可用。 显示为可接受 integral_type 的操作符对 smallintintegerbigint类型是可用的。 除了特别说明之处,操作符的每种形式都返回与其参数相同的数据类型。 涉及多个参数数据类型的调用, 例如 integer + numeric,可通过使用这些列表中稍后出现的类型来解析。 @@ -56,7 +56,7 @@ numeric_type - 一元加(无操作) + 一元正号(不执行操作) + 3.5 @@ -84,7 +84,7 @@ numeric_type - 否定 + 取负 - (-4) @@ -112,7 +112,7 @@ numeric_type - 除(对于整型,除法将结果截断为零) + 除法(对于整数类型,除法将结果向零截断) 5.0 / 2 @@ -152,14 +152,14 @@ double precision - 指数 + 求幂 2 ^ 3 8 - 不像典型的数学实践,多次使用 ^ 将会默认从左到右关联: + 与通常的数学惯例不同,多次使用^时默认从左到右结合: 2 ^ 3 ^ 3 @@ -219,7 +219,7 @@ integral_type - 按位与(AND) + 按位与 91 & 15 @@ -233,7 +233,7 @@ integral_type - 按位或(OR) + 按位或 32 | 3 @@ -247,7 +247,7 @@ integral_type - 按位异或(exclusive OR) + 按位异或 17 # 5 @@ -261,7 +261,7 @@ integral_type - 按位求反(NOT) + 按位非 ~1 @@ -304,9 +304,9 @@ 显示了可用的数学函数。 许多这样的函数以多种具有不同的参数类型的形式提供。 - 除非注明,任何给定形式的函数都返回与其参数相同的数据类型;跨类型情况的解决方法与上述对操作符的解释相同。 - 使用double precision数据的函数大多是在主机系统的C库上实现的; - 因此,边界情况下的准确性和行为会因主机系统的区别而不同。 + 除非注明,任何给定形式的函数都返回与其参数相同的数据类型;跨类型情况的解决方法与上述对操作符的解释相同。 + 使用double precision数据的函数大多是在主机系统的C库上实现的; + 因此,精度和边界情况下的行为可能因主机系统而异。 @@ -437,7 +437,7 @@ numeric - y/x 的整数商(截断为零位) + y/x 的整数商(向零截断) div(9, 4) @@ -445,27 +445,6 @@ - - - - exp - - exp ( numeric ) - numeric - - - exp ( double precision ) - double precision - - - 指数 (e 的给定次方) - - - exp(1.0) - 2.7182818284590452 - - - @@ -500,6 +479,27 @@ + + + + exp + + exp ( numeric ) + numeric + + + exp ( double precision ) + double precision + + + 指数函数(e的给定次幂) + + + exp(1.0) + 2.7182818284590452 + + + @@ -701,7 +701,7 @@ integer - 精确表示所提供值所需的最小刻度(小数位数) + 精确表示给定值所需的最少小数位数 min_scale(8.4100) @@ -798,7 +798,7 @@ double precision - 四舍五入到最近的整数。 + 舍入到最接近的整数。 对于numeric,遇到恰好位于中点的情况时按远离零的方向舍入。 对于double precision,中点取舍规则取决于平台,但舍入到最接近的偶数是最常见的规则。 @@ -835,7 +835,7 @@ integer - 参数的刻度(小数点后的位数) + 参数的小数位数(小数部分的十进制位数) scale(8.4100) @@ -894,7 +894,7 @@ numeric - 通过删除尾数部分的零来降低值的刻度(小数位数) + 通过移除尾随零来减少值的小数位数 trim_scale(8.4100) @@ -915,7 +915,7 @@ double precision - 截断整数 (向零靠近) + 向零截断为整数 trunc(42.8) @@ -933,7 +933,7 @@ numeric - 截断 vs 位小数位置的数字 + 将v截断到s位小数 trunc(42.4382, 2) @@ -1026,6 +1026,55 @@ + + + + random + + random ( min integer, max integer ) + integer + + + random ( min bigint, max bigint ) + bigint + + + random ( min numeric, max numeric ) + numeric + + + 返回范围min <= x <= max内的随机值。对于numeric类型,结果的小数位数与minmax中小数位数较多者相同。 + + + random(1, 10) + 7 + + + random(-0.499, 0.499) + 0.347 + + + + + + + random_normal + + + random_normal ( + mean double precision + , stddev double precision ) + double precision + + + 从具有给定参数的正态分布中返回一个随机值;mean默认为 0.0,stddev默认为 1.0。 + + + random_normal(0.0, 1.0) + 0.051285419 + + + @@ -1035,7 +1084,7 @@ void - 为后续的random()调用设置种子;参数必须在-1.0和1.0之间,包括边界值 + 为后续的random()random_normal()调用设置种子;参数必须在-1.0和1.0之间,包括边界值 setseed(0.12345) @@ -1047,7 +1096,7 @@ - 在中列出的random()random_normal()函数使用同一个确定性伪随机数生成器。 + 在中列出的random()random_normal()函数使用确定性伪随机数生成器。 它速度快,但不适用于加密应用;请参阅模块以获取更安全的替代方案。 如果调用setseed(),则当前会话中后续对这些函数的调用结果序列可以通过使用相同参数重新发出setseed()来重复。 在同一会话中没有任何先前的setseed()调用时,首次调用这些函数中的任何一个都会从平台相关的随机位源获取种子。 @@ -1360,7 +1409,7 @@ - 另一种使用以角度度量的角的方法是使用早前展示的单位转换函数radians()degrees()。不过,使用基于角度的三角函数更好,因为这类方法能避免sind(30)等特殊情况下的舍入偏差。 + 另一种使用以角度度量的角的方法是使用早前展示的单位转换函数radians()degrees()。不过,使用基于角度的三角函数更好,因为这类方法能避免sind(30)等特殊情况下的舍入误差。 @@ -1433,7 +1482,7 @@ double precision - 双曲切线 + 双曲正切 tanh(1) @@ -1484,7 +1533,7 @@ double precision - 反双曲切线 + 反双曲正切 atanh(0.5) diff --git a/zh/20/func/func-net.sgml b/zh/20/func/func-net.sgml index 3b586187..2684c44e 100644 --- a/zh/20/func/func-net.sgml +++ b/zh/20/func/func-net.sgml @@ -9,8 +9,8 @@ 任何cidr 值都可以隐式地转换到inet;因此,下面在inet上操作的操作符和函数也可以在cidr值上工作。 - (对于inetcidr有单独的函数,这是因为这两种情况的行为应该是不同的。) - 此外,它允许将inet值转换为cidr。 + (如果inetcidr各有单独的函数,是因为这两种情况下的行为应当不同。) + 此外,也允许将inet值转换为cidr。 当这样做的时候,子网掩码右边的任何位都被静默地置零,以创建一个有效的cidr值。 @@ -41,8 +41,8 @@ boolean - 子网是否严格包含在子网中?这个操作符和后续的四个操作符测试子网包含情况。 - 它们只考虑两个地址的网络部分(忽略网络掩码右侧的任何位),并确定一个网络与另一个网络相同或者是相同的子网。 + 子网是否严格包含在另一个子网中?这个操作符和后续四个操作符测试子网包含关系。 + 它们只考虑两个地址的网络部分(忽略网络掩码右侧的所有位),并判断一个网络是否与另一个网络相同,或是另一个网络的子网。 inet '192.168.1.5' << inet '192.168.1/24' @@ -64,7 +64,7 @@ boolean - 子网是否包含或等于子网? + 子网是否被包含于或等于子网? inet '192.168.1/24' <<= inet '192.168.1/24' @@ -124,7 +124,7 @@ inet - 计算位 NOT. + 计算按位非。 ~ inet '192.168.1.6' @@ -138,7 +138,7 @@ inet - 计算位 AND. + 计算按位与。 inet '192.168.1.6' & inet '0.0.0.255' @@ -152,7 +152,7 @@ inet - 计算位 OR. + 计算按位或。 inet '192.168.1.6' | inet '0.0.0.255' @@ -253,9 +253,8 @@ text - 创建缩写的文本显示格式。 - (结果与inet输出函数产生的结果相同;只有在与显式转换为text的结果相比时它才算是缩写形式, - 由于历史原因,它永远不会抑制子网掩码部分。) + 创建文本形式的缩写显示格式。 + (结果与inet输出函数产生的结果相同;只有与显式类型转换为text的结果相比时,才称为缩写形式。由于历史原因,后一种转换从不省略网络掩码部分。) abbrev(inet '10.1.0.0/32') @@ -269,7 +268,7 @@ text - 创建缩写的文本显示格式。(缩写包括在子网掩码的右侧删除所有零字节;更多的示例请见 。) + 创建文本形式的缩写显示格式。(缩写形式会省略网络掩码右侧值为零的字节;更多示例见。) abbrev(cidr '10.1.0.0/16') @@ -388,7 +387,7 @@ integer - 以比特位返回子网掩码长度。 + 返回子网掩码长度,以位为单位。 masklen(inet '192.168.1.5/24') @@ -490,7 +489,7 @@ MAC地址类型, macaddrmacaddr8,支持中所示的常用比较操作符以及中所示的特殊函数。 - 此外,它们支持位元逻辑操作符~, &| (NOT, AND 和 OR),就像上面对IP地址所示的那样。 + 此外,它们支持按位逻辑操作符~&|(非、与和或),就像上面对IP地址所示的那样。
@@ -554,7 +553,7 @@ macaddr8 - 将地址的第7位设置为1,创建所谓的modified EUI-64,用于包含在IPv6地址中。 + 将地址的第 7 位设置为 1,生成所谓的修订 EUI-64 格式,以便用于 IPv6 地址。 macaddr8_set7bit(macaddr8 '00:34:56:ab:cd:ef') diff --git a/zh/20/func/func-range.sgml b/zh/20/func/func-range.sgml index 5ebd5e1b..261b977e 100644 --- a/zh/20/func/func-range.sgml +++ b/zh/20/func/func-range.sgml @@ -126,7 +126,7 @@ boolean - 第一个范围是否严格符合第二个(范围)? + 第一个范围是否严格地在第二个(范围)的右边? int8range(50,60) >> int8range(20,30) @@ -210,7 +210,7 @@ anyrange - 计算范围的差异。第二个范围必须不能包含在第一个(范围)中,以使差异不是一个单一的范围。 + 计算范围的差集。第二个范围不能被包含在第一个范围中而导致差集无法表示为单个范围。 int8range(5,15) - int8range(10,20) @@ -304,7 +304,7 @@ boolean - 第一个多范围是否被第二个所包括? + 第一个多范围是否被第二个所包含? '{[2,4)}'::int4multirange <@ '{[1,7)}'::int4multirange @@ -318,7 +318,7 @@ boolean - 多范围是否被范围所包括。 + 多范围是否被范围所包含? '{[2,4)}'::int4multirange <@ int4range(1,7) @@ -332,7 +332,7 @@ boolean - 范围是否被多范围所包括? + 范围是否被多范围所包含? int4range(2,4) <@ '{[1,7)}'::int4multirange @@ -430,7 +430,7 @@ boolean - 范围是否完全的在多范围左边? + 范围是否完全在多范围左边? int8range(1,10) << '{[100,110)}'::int8multirange @@ -472,7 +472,7 @@ boolean - 范围是否完全在多范围右边。 + 范围是否完全在多范围右边? int8range(50,60) >> '{[20,30)}'::int8multirange @@ -640,7 +640,7 @@ anymultirange - 计算多范围的差异。 + 计算多范围的差集。 '{[5,20)}'::int8multirange - '{[10,15)}'::int8multirange @@ -652,21 +652,21 @@
- 当涉及一个空范围或多范围时,左部/右部/相邻操作符总是返回假;即一个空范围被认为不在任何其他范围前面或者后面。 + 涉及空范围或空多范围时,左侧、右侧和相邻操作符总是返回假;也就是说,空范围不被视为位于任何其他范围之前或之后。 - 在其他地方,空范围和多范围被视为添加标识:与空值的任何交集都是它自己。 - 任何减去空值的都是它自己。 - 空的多范围与空的范围具有完全相同的点。 + 在其他运算中,空范围和空多范围被视为加法单位元:任何值与空值求并集,结果仍是该值本身。 + 任何值减去空值,结果也仍是该值本身。 + 空多范围与空范围具有完全相同的点。 每个范围都包含空范围。 每个多范围包含任意多个空范围。 - 范围交集和差异操作符将失败,如果结果范围需要包含两个不相交的子范围,因为这样的范围无法表示。 - 还有用于求交集和差集的单独操作符,它们接受多范围参数并返回多范围,即使参数彼此不相交也不会失败。 - 因此,如果需要对可能不相交的范围进行交集或差异操作,你可以通过首先将范围转换为多范围来避免错误。 + 如果结果范围需要包含两个不相交的子范围,范围并集和差集操作符会失败,因为这样的范围无法表示。 + 另有接受多范围参数并返回多范围的并集和差集操作符,即使参数彼此不相交,也不会失败。 + 因此,如果需要对可能不相交的范围求并集或差集,可以先将范围转换为多范围来避免错误。 @@ -704,7 +704,7 @@ anyelement - 提取范围的下界(如果范围为空或下界为无限,则为NULL)。 + 提取范围的下界(如果范围为空或没有下界,则返回NULL)。 lower(numrange(1.1,2.2)) @@ -721,7 +721,7 @@ anyelement - 提取范围的上限(如果范围为空或上限为无限,则为NULL)。 + 提取范围的上界(如果范围为空或没有上界,则返回NULL)。 upper(numrange(1.1,2.2)) @@ -789,7 +789,7 @@ boolean - 范围的下界是无限的吗? + 范围是否没有下界?(下界为-Infinity时返回假。) lower_inf('(,)'::daterange) @@ -806,7 +806,7 @@ boolean - 范围的上界是无限的吗? + 范围是否没有上界?(上界为Infinity时返回假。) upper_inf('(,)'::daterange) @@ -884,7 +884,7 @@ anyelement - 提取多范围的下界 (NULL 如果多范围为空或下界为无穷的)。 + 提取多范围的下界(如果多范围为空或没有下界,则返回NULL)。 lower('{[1.1,2.2)}'::nummultirange) @@ -901,7 +901,7 @@ anyelement - 提取多范围的上界 (NULL 如果多范围为空或上界为无穷的)。 + 提取多范围的上界(如果多范围为空或没有上界,则返回NULL)。 upper('{[1.1,2.2)}'::nummultirange) @@ -935,7 +935,7 @@ boolean - 多范围的下界是否包括? + 多范围的下界是否包含在内? lower_inc('{[1.1,2.2)}'::nummultirange) @@ -952,7 +952,7 @@ boolean - 多范围的上界是否包括? + 多范围的上界是否包含在内? upper_inc('{[1.1,2.2)}'::nummultirange) @@ -969,7 +969,7 @@ boolean - 多范围的下界是无限的么? + 多范围是否没有下界?(下界为-Infinity时返回假。) lower_inf('{(,)}'::datemultirange) @@ -986,7 +986,7 @@ boolean - 多范围的上界是无限的么? + 多范围是否没有上界?(上界为Infinity时返回假。) upper_inf('{(,)}'::datemultirange) @@ -1014,7 +1014,7 @@ - multirange (function) + multirange(函数) multirange ( anyrange ) anymultirange @@ -1032,14 +1032,13 @@ unnest - for multirange + 用于多范围 unnest ( anymultirange ) setof anyrange - 扩展多范围为一组范围。 - 范围按存储顺序读出(升序)。 + 将多范围按升序展开为一组范围。 unnest('{[1,2), [3,4)}'::int4multirange) @@ -1072,6 +1071,6 @@ - lower_incupper_inclower_inf、 和 upper_inf 函数对空范围(empty range)或多范围都返回假(false)。 + lower_incupper_inclower_infupper_inf 函数对空范围或空多范围都返回假。 diff --git a/zh/20/func/func-sequence.sgml b/zh/20/func/func-sequence.sgml index bec3b90c..6d678118 100644 --- a/zh/20/func/func-sequence.sgml +++ b/zh/20/func/func-sequence.sgml @@ -3,11 +3,11 @@ 序列操作函数 - sequence + 序列 - 本节描述对序列对象进行操作的函数,也称为序列生成器或简称序列。 + 本节描述用于操作序列对象(也称为序列生成器,或简称序列)的函数。 序列对象是使用创建的特殊单行表。 序列对象通常用于为表中的行生成惟一标识符。在中列出的序列函数,提供了简单的、多用户安全方法,用于从序列对象中获取连续的序列值。 @@ -39,12 +39,12 @@ bigint - 将序列对象推进到下一个值并返回该值。这是自动完成的:即使多个会话并发地执行nextval,每个会话也会安全地接收到不同的序列值。 - 如果序列对象是用默认形参创建的,则连续的nextval调用将返回以1开始的连续值。 + 将序列对象推进到下一个值并返回该值。这个操作是原子的:即使多个会话并发地执行nextval,每个会话也会安全地接收到不同的序列值。 + 如果序列对象是用默认参数创建的,则连续的nextval调用将返回以1开始的连续值。 其他行为可以通过在命令中使用适当的参数获得。 - 这个函数需要USAGEUPDATE权限在序列上。 + 这个函数需要序列上的USAGEUPDATE权限。 @@ -57,16 +57,16 @@ bigint - 设置序列对象的当前值,以及可选的它的is_called标志。 + 设置序列对象的当前值,并可选地设置其is_called标志。 双参数形式将序列的last_value字段设置为指定的值,并将其is_called字段设置为true,意味着下一个nextval将在返回值之前推进序列。 currval将报告的值也设置为指定的值。在三参数形式中,is_called可以设置为truefalsetrue与双参数形式具有相同的效果。 - 如果设置为false,下一个nextval将返回指定的值,序列推进从下面的nextval开始。 - 而且,currval报告的值在这种情况下不会改变。例如, + 如果设置为false,下一个nextval将返回指定的值,序列推进从再下一次调用nextval开始。 + 而且,currval报告的值在这种情况下不会改变。例如: -SELECT setval('myseq', 42); Next nextval will return 43 +SELECT setval('myseq', 42); 下一次 nextval 将返回 43 SELECT setval('myseq', 42, true); 同上 -SELECT setval('myseq', 42, false); Next nextval will return 42 +SELECT setval('myseq', 42, false); 下一次 nextval 将返回 42 setval返回的结果就是它的第二个参数的值。 @@ -84,8 +84,7 @@ SELECT setval('myseq', 42, false); Next nextvalbigint
- 返回nextval在当前会话中为该序列最近获取的值。(如果在这个会话中没有为这个序列调用nextval会报告错误。) - 因为它返回的是一个会话本地值,所以它给出了一个可预测的答案,即自当前会话以来,其他会话是否执行了nextval。 + 返回当前会话中最近一次针对该序列调用nextval所获得的值。(如果当前会话从未针对该序列调用过nextval,则会报错。)由于返回的是会话局部值,无论其他会话是否在当前会话调用之后执行过nextval,结果都是可预测的。 这个函数需要序列上的USAGESELECT权限。 @@ -162,8 +161,6 @@ SELECT setval('myseq', 42, false); Next nextval - 序列函数所要操作的序列由regclass参数指定,该参数只是pg_class系统目录中序列的OID。 - 你不必手工查找OID,不过,因为regclass数据类型的输入转换器将为您完成这项工作。 - 详见 + 序列函数所要操作的序列由regclass参数指定,该参数就是序列在pg_class系统目录中的 OID。不过,不必手动查找 OID,因为regclass数据类型的输入转换器会完成这项工作。详见 diff --git a/zh/20/func/func-srf.sgml b/zh/20/func/func-srf.sgml index fa113ebd..f51b14b9 100644 --- a/zh/20/func/func-srf.sgml +++ b/zh/20/func/func-srf.sgml @@ -8,13 +8,13 @@ - 本节描述那些可能返回多于一行的函数。目前这个类中被使用最广泛的是级数生成函数, 如所述。其他更特殊的集合返回函数在本手册的其他地方描述。 - 组合多集合返回函数的方法可见。 + 本节描述那些可能返回多于一行的函数。目前这个类中被使用最广泛的是序列生成函数, 如所述。其他更特殊的集合返回函数在本手册的其他地方描述。 + 组合多个集合返回函数的方法可见 - 级数生成函数 + 序列生成函数 @@ -70,9 +70,7 @@
- 当step为正时,如果start大于stop则返回零行。 - 相反,当step为负时,如果start小于stop则返回零行。 - 如果任何输入为NULL也会返回零行。step为零是一个错误。下面是一些示例: + 当step为正数时,如果start大于stop,则返回零行。反之,当step为负数时,如果start小于stop,则返回零行。如果任一输入为NULL,也返回零行。如果step为零,则会报错。下面是一些示例: SELECT * FROM generate_series(2,4); generate_series @@ -103,7 +101,7 @@ SELECT generate_series(1.1, 4, 1.3); 3.7 (3 rows) --- this example relies on the date-plus-integer operator: +-- 此示例使用日期加整数的操作符: SELECT current_date + s.a AS dates FROM generate_series(0,14,7) AS s(a); dates ------------ @@ -127,7 +125,7 @@ SELECT * FROM generate_series('2008-03-01 00:00'::timestamp, 2008-03-04 08:00:00 (9 rows) --- 此示例假定 TimeZone 设置为 UTC;注意 DST 转换: +-- 此示例假定 TimeZone 设为 UTC;请注意夏令时(DST)切换: SELECT * FROM generate_series('2001-10-22 00:00 -04:00'::timestamptz, '2001-11-01 00:00 -05:00'::timestamptz, '1 day'::interval, 'America/New_York'); @@ -175,7 +173,7 @@ SELECT * FROM generate_series('2001-10-22 00:00 -04:00'::timestamptz, setof integer - 生成一个包含给定数组第dim维度的有效下标的序列。 + 生成一个包含给定数组第dim维的有效下标的序列。 @@ -185,7 +183,7 @@ SELECT * FROM generate_series('2001-10-22 00:00 -04:00'::timestamptz, setof integer
- 生成一个包含给定数组第dim维度的有效下标的序列。当reverse为真时,以相反的顺序返回序列。 + 生成一个包含给定数组第dim维的有效下标的序列。当reverse为真时,以相反的顺序返回序列。 @@ -194,9 +192,9 @@ SELECT * FROM generate_series('2001-10-22 00:00 -04:00'::timestamptz, generate_subscripts是一个快捷函数,它为给定数组的指定维度生成一组合法的下标。 - 对于不具有请求维度的数组返回零行,对于任何输入为NULL数组也返回零行。下面是一些示例: + 如果数组不具有所请求的维度,或者任一输入为NULL,则返回零行。下面是一些示例: --- basic usage: +-- 基本用法: SELECT generate_subscripts('{NULL,1,NULL,2}'::int[], 1) AS s; s --- @@ -206,8 +204,8 @@ SELECT generate_subscripts('{NULL,1,NULL,2}'::int[], 1) AS s; 4 (4 rows) --- presenting an array, the subscript and the subscripted --- value requires a subquery: +-- 展示数组、下标和下标对应的值 +-- 需要使用子查询: SELECT * FROM arrays; a -------------------- @@ -226,7 +224,7 @@ FROM (SELECT generate_subscripts(a, 1) AS s, a FROM arrays) foo; {100,200,300} | 3 | 300 (5 rows) --- unnest a 2D array: +-- 展开二维数组: CREATE OR REPLACE FUNCTION unnest2(anyarray) RETURNS SETOF anyelement AS $$ SELECT $1[i][j] @@ -246,15 +244,13 @@ SELECT * FROM unnest2(ARRAY[[1,2],[3,4]]); - ordinality + 序号 - 当FROM子句中的函数以WITH ORDINALITY作为后缀时,将在函数的输出列上附加一个bigint列,该列从1开始,函数输出的每一行加1。 - 这在 unnest()等集合返回函数的情况下最有用。 - + 当FROM子句中的函数后面加上WITH ORDINALITY时,一个bigint列会追加到函数的输出列中,其值从 1 开始,对函数输出的每一行递增 1。这种方式对集合返回函数尤其有用,例如unnest() --- set returning function WITH ORDINALITY: +-- 集合返回函数与 WITH ORDINALITY: SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); ls | n -----------------+---- diff --git a/zh/20/func/func-statistics.sgml b/zh/20/func/func-statistics.sgml index 84bb82be..1b226986 100644 --- a/zh/20/func/func-statistics.sgml +++ b/zh/20/func/func-statistics.sgml @@ -3,12 +3,12 @@ 统计信息函数 - function - statistics + 函数 + 统计信息 - PostgreSQL提供了一个函数来检查使用CREATE STATISTICS命令定义的复杂统计。 + PostgreSQL提供了一个函数来检查使用CREATE STATISTICS命令定义的复杂统计信息。 @@ -24,7 +24,7 @@ - pg_mcv_list_items返回一组记录,描述存储在多列MCV列表中的所有项目。它返回以下列: + pg_mcv_list_items返回一组记录,描述存储在多列MCV列表中的所有项目。它返回以下列: @@ -60,7 +60,7 @@ base_frequency double precision - MCV项目的基本频率 + MCV项目的基础频率 @@ -68,7 +68,7 @@ - pg_mcv_list_items函数可以这样使用: + pg_mcv_list_items函数可以这样使用: SELECT m.* FROM pg_statistic_ext join pg_statistic_ext_data on (oid = stxoid), diff --git a/zh/20/func/func-string.sgml b/zh/20/func/func-string.sgml index 09fa4340..ac23ac09 100644 --- a/zh/20/func/func-string.sgml +++ b/zh/20/func/func-string.sgml @@ -7,7 +7,7 @@ 这里的字符串包括charactercharacter varyingtext类型的值。 除非另有说明,这些函数和操作符都声明为接受并返回text类型。 它们也可互换地接受character varying参数。 - 在应用函数或操作符之前,character类型的值会先转换为text,因此会去除其尾随空格。 + 在应用函数或操作符之前,character类型的值会先转换为text,因此会去除 character 值的尾随空格。 @@ -18,7 +18,7 @@ 字符串串接操作符(||)将接受非字符串输入,只要至少一个输入是一种字符串类型,如所示。 - 对于其他情况,向text插入一个显式强制,可用于接受非字符串输入。 + 对于其他情况,可以添加到text的显式强制转换,以接受非字符串输入。 @@ -46,14 +46,14 @@ - character string - concatenation + 字符串 + 串接 text || text text - 连接两个字符串。 + 串接两个字符串。 'Post' || 'greSQL' @@ -71,8 +71,8 @@ text - 将非字符串输入转换为文本,然后将两个字符串串联在一起。 - (非字符串输入不能为数组类型,因为这将在||操作符的数组中造成歧义。如果你想连接一个数组的文本相等的,请显式地将其转换为text 。) + 将非字符串输入转换为文本,然后将两个字符串串接起来。 + (非字符串输入不能是数组类型,因为那样会与数组的||操作符产生歧义。如果要串接数组的文本表示,请显式地将其转换为text。) 'Value: ' || 42 @@ -83,17 +83,35 @@ - normalized + btrim + + btrim ( string text + , characters text ) + text + + + 从string的开头和结尾移除仅由characters中字符(默认为空格)组成的最长字符串。 + + + btrim('xyxtrimyyx', 'xyz') + trim + + + + + + + 规范化 - Unicode normalization + Unicode 规范化 text IS NOT form NORMALIZED boolean - 检查字符串是否在指定的 Unicode 规范化表单中。 - 可选的form关键词指定表单:NFC (默认的), NFD, NFKC, 或 NFKD。 + 检查字符串是否处于指定的 Unicode 规范化形式中。 + 可选的form关键字指定形式:NFC(默认)、NFDNFKCNFKD。 只有在服务器编码为UTF8时,才能使用此表达式。 请注意,使用这个表达式检查规范化通常比规范化可能已经规范化的字符串要快。 @@ -126,13 +144,13 @@ char_length - character string - length + 字符串 + 长度 - length + 长度 字符串 - character string, length + 字符串,长度 char_length ( text ) integer @@ -162,7 +180,7 @@ text - 根据数据库的语言环境规则,将字符串转换为全部小写。 + 根据数据库的区域设置规则,将字符串转换为全部小写。 lower('TOM') @@ -170,22 +188,57 @@ + + + + lpad + + lpad ( string text, + length integer + , fill text ) + text + + + 在string前面添加字符fill(默认为空格),将其填充到长度length。如果string已经长于length,则从右侧截断。 + + + lpad('hi', 5, 'xy') + xyxhi + + + + + + + ltrim + + ltrim ( string text + , characters text ) + text + + + 从string的开头移除仅由characters中字符(默认为空格)组成的最长字符串。 + + + ltrim('zzzytest', 'xyz') + test + + + normalize - Unicode normalization + Unicode 规范化 normalize ( text , form ) text - 将字符串转换为指定的Unicode规范化形式。 - 可选的form关键字指定了如下形式:NFC (the default),NFDNFKC,或NFKD。 - 该函数只能在服务器编码为UTF8时使用。 + 将字符串转换为指定的 Unicode 规范化形式。可选的 form 关键字指定如下形式:NFC(默认值)、NFDNFKCNFKD。该函数只能在服务器编码为 UTF8 时使用。 normalize(U&'\0061\0308bc', NFC) @@ -236,8 +289,7 @@ text - 替换stringstart字符开始的子串,并用newsubstring扩展到count字符。 - 如果省略了count,则默认为newsubstring的长度。 + 用newsubstring替换string中从第start个字符开始、长度为count个字符的子字符串。如果省略count,则默认为newsubstring的长度。 overlay('Txxxxas' PLACING 'hom' FROM 2 FOR 4) @@ -254,7 +306,7 @@ integer - 返回string中指定的substring的第一个起始索引,如果不存在则返回零,。 + 返回substringstring中首次出现的位置;如果不存在则返回零。 position('om' IN 'Thomas') @@ -262,6 +314,43 @@ + + + + rpad + + rpad ( string text, + length integer + , fill text ) + text + + + 在string后面追加字符fill(默认为空格),将其填充到长度length。如果string已经长于length,则截断它。 + + + rpad('hi', 5, 'xy') + hixyx + + + + + + + rtrim + + rtrim ( string text + , characters text ) + text + + + 从string的结尾移除仅由characters中字符(默认为空格)组成的最长字符串。 + + + rtrim('testxxzx', 'xyz') + test + + + @@ -271,9 +360,7 @@ text - 如果已指定,提取stringstart字符开始的子串, - 并且在count字符后停止。如果已指定的话。 - 提供至少一个startcount中的至少一个。 + 提取string的子字符串:若指定了起始位置,则从第start个字符开始;若指定了长度,则在提取count个字符后停止。startcount至少需要指定一个。 substring('Thomas' FROM 2 FOR 3) @@ -292,10 +379,10 @@ substring ( string text FROM pattern text ) - text + text - 提取匹配POSIX正则表达式的第一个子字符串; 参见 。 + 提取匹配 POSIX 正则表达式的第一个子字符串;参见 substring('Thomas' FROM '...$') @@ -313,8 +400,8 @@ text - 提取匹配 SQL 正则表达式的第一个字串;参见 。 - 第一种形式自从SQL:2003被指定,第二种形式仅在SQL:1999中,并应认为是废弃的。 + 提取匹配 SQL 正则表达式的第一个子字符串;参见 。 + 第一种形式自 SQL:2003 起由标准规定;第二种形式只出现在 SQL:1999 中,应视为已过时。 substring('Thomas' SIMILAR '%#"o_a#"_' ESCAPE '#') @@ -357,6 +444,19 @@ + + + + unicode_assigned + + unicode_assigned ( text ) + boolean + + + 如果字符串中的所有字符都是已分配的 Unicode 码点,则返回true;否则返回false。此函数只能在服务器编码为UTF8时使用。 + + + @@ -366,7 +466,7 @@ text - 根据数据库的定位规则,将字符串转换为所有大写。 + 根据数据库的区域设置规则,将字符串转换为全部大写。 upper('tom') @@ -433,7 +533,7 @@ integer - 返回参数的第一个字符的数字代码。在UTF8编码中,返回该字符的Unicode代码点。 + 返回参数的第一个字符的数字代码。在UTF8编码中,返回该字符的Unicode 码点。 在其他多字节编码中,该参数必须是一个ASCII字符。 @@ -442,23 +542,7 @@ - - - - btrim - - btrim ( string text - , characters text ) - text - - - 从string的开头或结尾删除最长的只包含characters(默认是一个空格)的字符串 - - - btrim('xyxtrimyyx', 'xyz') - trim - - + @@ -469,7 +553,7 @@ text - 返回给定代码的字符。在UTF8编码中该参数被视作一个Unicode代码点。 + 返回给定代码的字符。在UTF8编码中该参数被视作一个Unicode 码点。 在其他多字节编码中该参数必须指定一个ASCII字符。 chr(0) 字符不被允许,因为文本数据类型不能存储这种字符。 @@ -485,11 +569,11 @@ concat concat ( val1 "any" - [, val2 "any" [, ...] ] ) + , val2 "any" , ... ) text - 连接所有参数的文本表示。空参数被忽略。 + 串接所有参数的文本表示。NULL 参数被忽略。 concat('abcde', 2, NULL, 22) @@ -504,11 +588,11 @@ concat_ws ( sep text, val1 "any" - [, val2 "any" [, ...] ] ) + , val2 "any" , ... ) text - 用分隔符连接除第一个参数外的所有参数。第一个参数用作分隔符字符串,不应为NULL。其他NULL参数将被忽略。 + 用分隔符串接除第一个参数外的所有参数。第一个参数用作分隔符字符串,不应为NULL。其他NULL参数将被忽略。 concat_ws(',', 'abcde', 2, NULL, 22) @@ -522,7 +606,7 @@ format format ( formatstr text - [, formatarg "any" [, ...] ] ) + , formatarg "any" , ... ) text @@ -543,21 +627,43 @@ initcap ( text ) text - - 将每个单词的第一个字母转换为大写(如果该字母是双字母,且区域设置为ICUbuiltin PG_UNICODE_FAST,则转换为标题大小写),其余字母转换为小写。使用libcbuiltin区域设置提供者时,单词是由非字母数字字符分隔的字母数字字符序列;使用 ICU 区域设置提供者时,单词按ICU 的 u_strToTitle 函数划分。 + 将每个单词的第一个字母转换为大写(如果该字母是二合字母,且区域设置为ICUbuiltin PG_UNICODE_FAST,则转换为标题大小写),其余字母转换为小写。使用libcbuiltin区域设置提供者时,单词是由非字母数字字符分隔的字母数字字符序列;使用 ICU 区域设置提供者时,单词按ICU 的 u_strToTitle 函数划分。 - 这个函数主要用于方便显示。由于区域设置提供者之间以及不同 ICU 版本之间存在差异,不应依赖具体的转换结果。如果需要特定的单词边界规则,建议编写自定义函数。 - initcap('hi THOMAS') Hi Thomas + + + + casefold + + casefold ( text ) + text + + + 根据排序规则对输入字符串执行大小写折叠。大小写折叠与大小写转换类似,但其目的是方便字符串的不区分大小写匹配,而大小写转换的目的是将字符串转换为特定的大小写形式。此函数只能在服务器编码为UTF8时使用。 + + + 通常,大小写折叠只是将字符转换为小写,但不同排序规则可能存在例外。例如,某些字符具有两种以上的小写变体,或者会折叠为大写。 + + + 大小写折叠可能改变字符串的长度。例如,在PG_UNICODE_FAST排序规则中,ß(U+00DF)会折叠为ss。 + + + casefold可用于 Unicode 默认无大小写匹配。它并不总能保留输入字符串的规范化形式(参见)。 + + + libc提供者不支持大小写折叠,因此casefold相同。 + + + @@ -585,7 +691,7 @@ text - 以字符串返回第一个 n 字符,或在 n 为负时, 返回最后 |n| 个字符之外的全部字符。 + 返回字符串最左侧的 n 个字符;如果 n 为负,则返回除最后 |n| 个字符之外的全部字符。 left('abcde', 2) @@ -610,43 +716,9 @@ - - - - lpad - - lpad ( string text, - length integer - , fill text ) - text - - - 将string扩展为长度length,通过前置字符fill(默认空格)。 - 如果string已经超过length那么它将被截断(在右侧)。 - - - lpad('hi', 5, 'xy') - xyxhi - - - - - - ltrim - - ltrim ( string text - , characters text ) - text - - - 从string开始删除包含characters(默认空格)中仅包含字符的最长字符串。 - - - ltrim('zzzytest', 'xyz') - test - - + + @@ -671,14 +743,14 @@ parse_ident parse_ident ( qualified_identifier text - [, strict_mode boolean DEFAULT true ] ) + , strict_mode boolean DEFAULT true ) text[] - 将qualified_identifier拆分为一个标识符数组,删除单个标识符的任何引用。 + 将qualified_identifier拆分为一个标识符数组,去除各个标识符的引号。 默认情况下,最后一个标识符之后的额外字符被视为错误;但是,如果第二个参数为false,则忽略这些额外的字符。 (这种行为对于解析类似函数的对象的名称有作用。) - 请注意,此函数不会截断超长标识符。如果你想截断,你可以把结果给到name[]。 + 请注意,此函数不会截断超长标识符。如果你想截断,你可以将结果转换为name[] parse_ident('"SomeSchema".someTable') @@ -712,9 +784,7 @@ text - 返回适合引用的给定字符串,作为SQL语句字符串中的标识符。 - 只有在必要的情况下才添加引号(例如,如果字符串包含非标识符字符或将被大小写折叠)。 - 嵌入的引号被适当地加双引号。参见。 + 为给定字符串添加适当的引号并返回,使其可用作SQL语句字符串中的标识符。仅在必要时(即字符串包含不能用于标识符的字符,或会发生大小写折叠时)添加引号。内嵌的引号会被适当地双写。另见 quote_ident('Foo bar') @@ -731,9 +801,7 @@ text - 返回在SQL语句字符串中适当引用的给定字符串,用作字符串文字使用。 - 嵌入式单引号和反斜线适当的翻倍(转双引号或双斜线)。 - 请注意,quote_literal在参数为 null 时返回 null;如果这个参数可能为空,quote_nullable通常更合适。另请参阅。 + 为给定字符串添加适当的引号并返回,使其可用作SQL语句字符串中的字符串字面量。内嵌的单引号和反斜杠会被适当地双写。注意,quote_literal在输入为 null 时返回 null;如果参数可能为 null,quote_nullable通常更合适。另见 quote_literal(E'O\'Reilly') @@ -747,8 +815,7 @@ text - 将给定的值转换为文本,然后将其作为字面量引用。 - 内嵌的单引号和反斜杠被适当地翻倍。 + 将给定值转换为文本,然后作为字面量加引号。内嵌的单引号和反斜杠会被适当地双写。 quote_literal(42.5) @@ -765,8 +832,7 @@ text - 返回在SQL语句字符串中适当引用的给定字符串文字;或者,如果参数为null,则返回NULL。 - 内嵌的单引号和反斜杠被适当地翻倍。参见。 + 为给定字符串添加适当的引号并返回,使其可用作SQL语句字符串中的字符串字面量;如果参数为 null,则返回NULL。内嵌的单引号和反斜杠会被适当地双写。另见 quote_nullable(NULL) @@ -780,8 +846,7 @@ text - 将给定值转换为文本,然后将其作为字面量引用;或者,如果参数为null,则返回NULL。 - 内嵌的单引号和反斜杠被适当地翻倍。 + 将给定值转换为文本,然后作为字面量加引号;如果参数为 null,则返回NULL。内嵌的单引号和反斜杠会被适当地双写。 quote_nullable(42.5) @@ -795,8 +860,8 @@ regexp_count regexp_count ( string text, pattern text - [, start integer - [, flags text ] ] ) + , start integer + , flags text ) integer @@ -814,15 +879,15 @@ regexp_instr regexp_instr ( string text, pattern text - [, start integer - [, N integer - [, endoption integer - [, flags text - [, subexpr integer ] ] ] ] ] ) + , start integer + , N integer + , endoption integer + , flags text + , subexpr integer ) integer - 返回string中第N个匹配项的POSIX正则表达式pattern出现的位置,如果没有这样的匹配项,则返回零;参见。 + 返回 POSIX 正则表达式patternstring中第N次匹配的位置;如果没有这样的匹配,则返回零。参见 regexp_instr('ABCDEF', 'c(.)(..)', 1, 1, 0, 'i') @@ -840,7 +905,7 @@ regexp_like regexp_like ( string text, pattern text - [, flags text ] ) + , flags text ) boolean @@ -857,11 +922,11 @@ regexp_match - regexp_match ( string text, pattern text [, flags text ] ) + regexp_match ( string text, pattern text , flags text ) text[] - 返回第一个匹配的POSIX正则表达式patternstring中的子字符串;参见。 + 返回 POSIX 正则表达式patternstring的第一次匹配中的子字符串;参见 regexp_match('foobarbequebaz', '(bar)(beque)') @@ -874,12 +939,11 @@ regexp_matches - regexp_matches ( string text, pattern text [, flags text ] ) + regexp_matches ( string text, pattern text , flags text ) setof text[] - 返回第一个匹配的 POSIX 正则表达式patternstring中的子字符串,或者如果使用了g标志,则返回所有匹配的子字符串; - 参见。 + 返回 POSIX 正则表达式patternstring的第一次匹配中的子字符串;如果使用g标志,则返回所有匹配中的子字符串。参见 regexp_matches('foobarbequebaz', 'ba.', 'g') @@ -897,8 +961,7 @@ regexp_replace regexp_replace ( string text, pattern text, replacement text - [, start integer ] - [, flags text ] ) + , flags text ) text @@ -913,17 +976,21 @@ regexp_replace ( string text, pattern text, replacement text, - start integer, - N integer - [, flags text ] ) + start integer + , N integer + , flags text ) text - 替换字符串中第N个与 POSIX 正则表达式pattern匹配的子字符串,如果N为零,则替换所有匹配项;参见。 + 替换第N个与 POSIX 正则表达式pattern匹配的子字符串;如果N为零,则替换所有这样的匹配。搜索从string的第start个字符开始。如果省略N,则默认为 1。参见 regexp_replace('Thomas', '.', 'X', 3, 2) ThoXas + + + regexp_replace(string=>'hello world', pattern=>'l', replacement=>'XX', start=>1, "N"=>2) + helXXo world @@ -932,7 +999,7 @@ regexp_split_to_array - regexp_split_to_array ( string text, pattern text [, flags text ] ) + regexp_split_to_array ( string text, pattern text , flags text ) text[] @@ -949,7 +1016,7 @@ regexp_split_to_table - regexp_split_to_table ( string text, pattern text [, flags text ] ) + regexp_split_to_table ( string text, pattern text , flags text ) setof text @@ -971,15 +1038,14 @@ regexp_substr regexp_substr ( string text, pattern text - [, start integer - [, N integer - [, flags text - [, subexpr integer ] ] ] ] ) + , start integer + , N integer + , flags text + , subexpr integer ) text - 返回string中与第N个出现的POSIX正则表达式pattern匹配的子字符串, - 如果没有这样的匹配,则返回NULL;参见。 + 返回string中 POSIX 正则表达式pattern的第N次匹配对应的子字符串;如果没有这样的匹配,则返回NULL。参见 regexp_substr('ABCDEF', 'c(.)(..)', 1, 1, 'i') @@ -1019,7 +1085,7 @@ text - 将string 中当前的子串from替换为子串to。 + 将string中所有出现的子字符串from替换为子字符串to replace('abcdefabcdef', 'cd', 'XX') @@ -1054,7 +1120,7 @@ text - 返回字符串中的最后n个字符,或者在n>为负时,返回除了前面的|n|字符之外的所有字符。 + 返回字符串中的最后n个字符;如果n为负数,则返回除前 |n| 个字符之外的全部字符。 right('abcde', 2) @@ -1062,43 +1128,9 @@ - - - - rpad - - rpad ( string text, - length integer - , fill text ) - text - - - 扩展 string 到长度 length,通过追加fill 字符(默认为空格). - 如果string 已经比 length 长,则截断它。 - - - rpad('hi', 5, 'xy') - hixyx - - - - - - rtrim - - rtrim ( string text - , characters text ) - text - - - 从string末尾删除包含characters(默认为空格)中仅包含字符的最长字符串。 - - - rtrim('testxxzx', 'xyz') - test - - + + @@ -1111,7 +1143,7 @@ text - 在delimiter出现时拆分string,并且返回第n个字段(从一计数),或者当n为负数时,返回|n|'th-from-last 字段。 + 在出现delimiter时拆分string,并返回第n个字段(从一开始计数);如果n为负数,则返回倒数第 |n| 个字段。 split_part('abc~@~def~@~ghi', '~@~', 2) @@ -1195,8 +1227,7 @@ integer - 返回在string中指定的substring的第一个起始索引,如果不存在则为零。 - (与(substringstring中的)位置相同,但是请注意反转的参数顺序) + 返回substringstring中首次出现的位置;如果不存在则返回零。(与position(substring in string)相同,但请注意参数顺序相反。) strpos('high', 'ig') @@ -1213,8 +1244,7 @@ text - 提取stringstart字符开始的子字符串,并扩展count字符,如果指定了的话。 - (与 子字符串(stringstart 开始计数 count)相同。) + 提取string中从第start个字符开始的子字符串;若指定了长度,则提取count个字符。(与substring(string from start for count)相同。) substr('alphabet', 3) @@ -1245,10 +1275,7 @@ text - 将string从另一个编码中转换为ASCII,该编码可按名称或编号标识。 - 如果encoding被省略,则假定数据库编码(这在实践中是唯一有用的案例)。转换主要包括降音。 - 转换仅支持来自 LATIN1LATIN2LATIN9、 和 WIN1250 的编码. - (其他请参见 模块, 更灵活的解决方案。) + 将string从其他编码转换为ASCII,源编码可以用名称或编号指定。如果省略encoding,则使用数据库编码(实际上,这也是唯一有用的情况)。转换主要是去除重音符号。只支持从LATIN1LATIN2LATIN9WIN1250编码转换。(另一种更灵活的解决方案参见模块。) to_ascii('Karél') @@ -1256,6 +1283,31 @@ + + + + to_bin + + to_bin ( integer ) + text + + + to_bin ( bigint ) + text + + + 将数字转换为等价的二进制补码表示。 + + + to_bin(2147483647) + 1111111111111111111111111111111 + + + to_bin(-1234) + 11111111111111111111101100101110 + + + @@ -1269,11 +1321,40 @@ text - 将数字转换为其相应的十六进制表示形式。 + 将数字转换为等价的十六进制补码表示。 to_hex(2147483647) 7fffffff + + + to_hex(-1234) + fffffb2e + + + + + + + to_oct + + to_oct ( integer ) + text + + + to_oct ( bigint ) + text + + + 将数字转换为等价的八进制补码表示。 + + + to_oct(2147483647) + 17777777777 + + + to_oct(-1234) + 37777775456 @@ -1289,7 +1370,7 @@ string中与from集合中匹配的每个字符替换为to集合中相应的字符。 - 如果from长于tofrom中出现的额外字符被删除。 + 如果from长于to,输入中出现的from中的额外字符会被删除。 translate('12345', '143', 'ax') @@ -1306,18 +1387,18 @@ text - 计算参数中的转义Unicode字符。 + 解析参数中转义的 Unicode 字符。 Unicode字符可以被指定为\XXXX (4个十六进制数字),\+XXXXXX(6个十六进制数字),\uXXXX(4个十六进制数字),或\UXXXXXXXX (8个十六进制数字)。 要指定反斜杠,请写入两个反斜杠。 - 所有其他字符都是按字面意义的。 + 所有其他字符均按字面解释。 - 如果服务器编码不是UTF-8,由这些转义序列之一标识的Unicode编码点将被转换为实际的服务器编码;如果不可能,则会报告错误。 + 如果服务器编码不是 UTF-8,由这些转义序列之一标识的 Unicode 码点将被转换为实际的服务器编码;如果无法转换,则会报告错误。 - 这个函数提供了一个(非标准的)替代到Unicode转义的字符串常量(参见)。 + 此函数提供了带 Unicode 转义的字符串常量的另一种(非标准)写法(参见)。 @@ -1335,12 +1416,12 @@ - concatconcat_wsformat函数是可变的,因此可以把要串接或格式化的值作为一个标记了VARIADIC关键字的数组进行传递(见)。 - 数组的元素被当作函数的独立普通参数一样处理。如果可变数组参数为 NULL,concatconcat_ws返回 NULL,但format把 NULL 当作一个零元素数组。 + concatconcat_wsformat是可变参数函数,因此可以把要串接或格式化的值作为一个标记了VARIADIC关键字的数组进行传递(见)。 + 数组的元素被当作函数的独立普通参数一样处理。如果可变参数数组为 NULL,concatconcat_ws返回 NULL,但format把 NULL 当作一个零元素数组。 - 还可以参阅中的string_agg,以及中的字符串和bytea类型之间转换的功能。 + 还可以参阅中的聚合函数string_agg,以及中的字符串和bytea类型之间转换的函数。 @@ -1356,24 +1437,24 @@ -format(formatstr text [, formatarg "any" [, ...] ]) +format(formatstr text , formatarg "any" , ... ) - formatstr是一个格式字符串,它指定了结果应该如何被格式化。格式字符串中的文本被直接复制到结果中,除了使用格式说明符的地方。格式说明符在字符串中扮演着占位符的角色,它定义后续的函数参数如何被格式化及插入到结果中。每一个formatarg参数会被根据其数据类型的常规输出规则转换为文本,并接着根据格式说明符被格式化和插入到结果字符串中。 + formatstr是指定结果格式的字符串。格式字符串中的文本会直接复制到结果中,但格式说明符所在的位置除外。格式说明符充当字符串中的占位符,定义如何格式化后续函数参数并将其插入结果。每个formatarg参数都按照其数据类型通常的输出规则转换为文本,再根据格式说明符进行格式化并插入结果字符串。 - 格式说明符由一个%字符开始并且有这样的形式 + 格式说明符以%字符开头,格式如下: %[position][flags][width]type - 其中的各组件域是: + 其中各组成字段为: position(可选) - 一个形式为n$的字符串,其中n是要打印的参数的索引。索引 1 表示formatstr之后的第一个参数。如果position被忽略,默认会使用序列中的下一个参数。 + 一个形式为n$的字符串,其中n是要打印的参数的索引。索引 1 表示formatstr之后的第一个参数。如果position被省略,默认会使用序列中的下一个参数。 @@ -1381,9 +1462,7 @@ flags(可选) - - 控制格式说明符的输出如何被格式化的附加选项。当前唯一支持的标志是一个负号(-),它将导致格式说明符的输出会被左对齐(left-justified)。除非width域也被指定,否者这个域不会产生任何效果。 - + 用于控制格式说明符输出格式的附加选项。目前唯一支持的标志是减号(-),它使格式说明符的输出左对齐。只有同时指定了width字段时,它才有效。 @@ -1395,8 +1474,8 @@ - 如果宽度来自于一个函数参数,则参数在被格式说明符的值使用之前就被消耗掉了。如果宽度参数是负值,结果会在长度为abs(width)的域中被左对齐(如果-标志被指定)。 - + 如果宽度来自一个函数参数,会先使用该宽度参数,再使用作为格式说明符值的参数。如果宽度参数为负数,结果会在长度为abs(width)的字段中左对齐(如同指定了-标志)。 +
@@ -1413,12 +1492,12 @@
- I将参数值视作 SQL 标识符,并在必要时用双写引号包围它。如果参数为空,将会是一个错误(等效于quote_ident)。 + I将参数值视作 SQL 标识符,并在必要时用双引号包围它。如果参数为 null,则会报错(等效于quote_ident)。 - L将参数值引用为 SQL 文字。一个空值将被显示为不带引号的字符串NULL(等效于quote_nullable)。 + L将参数值作为 SQL 字面量加引号。null 值显示为不带引号的字符串NULL(等效于quote_nullable)。 @@ -1429,13 +1508,10 @@ - 除了以上所述的格式说明符之外,要输出一个文字形式的%字符,可以使用特殊序列%%。 + 除了以上所述的格式说明符之外,要输出一个字面形式的%字符,可以使用特殊序列%% - - 下面有一些基本的格式转换的示例: - - + 下面是一些基本格式转换的示例: SELECT format('Hello %s', 'World'); 结果:Hello World @@ -1446,14 +1522,11 @@ SELECT format('INSERT INTO %I VALUES(%L)', 'Foo bar', E'O\'Reilly'); 结果:INSERT INTO "Foo bar" VALUES('O''Reilly') SELECT format('INSERT INTO %I VALUES(%L)', 'locations', 'C:\Program Files'); -结果:INSERT INTO locations VALUES(E'C:\\Program Files') +结果:INSERT INTO locations VALUES('C:\Program Files') - - 下面是使用width域和-标志的示例: - - + 下面是使用width字段和-标志的示例: SELECT format('|%10s|', 'foo'); 结果:| foo| @@ -1474,10 +1547,7 @@ SELECT format('|%-*s|', -10, 'foo'); - - 这些示例展示了position域的示例: - - + 这些示例展示了如何使用position字段: SELECT format('Testing %3$s, %2$s, %1$s', 'one', 'two', 'three'); 结果:Testing three, two, one @@ -1489,10 +1559,8 @@ SELECT format('|%1$*2$s|', 'foo', 10, 'bar'); - - 不同于标准的 C 函数sprintfPostgreSQLformat函数允许将带有或者不带有position域的格式说明符被混在同一个格式字符串中。一个不带有position域的格式说明符总是使用最后一个被消耗的参数的下一个参数。另外,format函数不要求所有函数参数都被用在格式字符串中。例如: - - + 不同于标准 C 函数sprintf, + PostgreSQLformat函数允许在同一个格式字符串中,混合使用带有或不带有position字段的格式说明符。不带position字段的格式说明符,总是使用最后一个已使用参数之后的下一个参数。此外,format函数不要求格式字符串使用全部函数参数。例如: SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); 结果:Testing three, two, three diff --git a/zh/20/func/func-subquery.sgml b/zh/20/func/func-subquery.sgml index b636ac5a..0053355d 100644 --- a/zh/20/func/func-subquery.sgml +++ b/zh/20/func/func-subquery.sgml @@ -27,11 +27,11 @@ - subquery + 子查询 - 本节描述PostgreSQL中可用的SQL兼容的子查询表达式。所有本节中成文的表达式都返回布尔值(真/假)结果。 + 本节描述PostgreSQL中可用的SQL兼容的子查询表达式。本节介绍的所有表达式形式都返回布尔值(真/假)结果。 @@ -46,7 +46,7 @@ EXISTS (subquery) - 子查询可以引用来自周围的查询的变量,这些变量在该子查询的任何一次计算中都起常量的作用。 + 子查询可以引用外层查询的变量,这些变量在该子查询的任何一次计算中都起常量的作用。 @@ -58,7 +58,7 @@ EXISTS (subquery) - 下面这个简单的示例类似在col2上的一次内联接,但是它为每个 tab1的行生成最多一个输出,即使存在多个匹配tab2的行也如此∶ + 下面这个简单的示例类似在col2上的一次内连接,但是它为每个 tab1的行最多生成一行输出,即使存在多个匹配tab2的行也如此: SELECT col1 FROM tab1 @@ -75,15 +75,15 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 右手边是一个圆括弧括起来的子查询, 它必须正好只返回一个列。左手边表达式将被计算并与子查询结果逐行进行比较。 如果找到任何等于子查询行的情况,那么IN的结果就是。 如果没有找到相等行,那么结果是(包括子查询没有返回任何行的情况)。 + 右手边是一个圆括号括起来的子查询,它必须恰好返回一列。左手边表达式会被求值,并与子查询结果逐行比较。如果找到任意相等的子查询行,那么IN的结果就是。如果没有找到相等行,那么结果就是(包括子查询不返回任何行的情况)。 - 请注意如果左手边表达式得到空值,或者没有相等的右手边值, 并且至少有一个右手边行得到空值,那么IN结构的结果将是空值,而不是假。这个行为是遵照 SQL 处理空值的一般规则的。 + 请注意,如果左侧表达式得到空值,或者右侧没有相等的值且至少有一行得到空值,则IN结构的结果将是空值,而不是假。这符合 SQL 对空值布尔组合的一般规则。 - 和EXISTS一样,假设子查询将被完成运行完全是不明智的。 + 和EXISTS一样,假定子查询一定会完整运行并不明智。 @@ -91,7 +91,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 这种形式的IN的左手边是一个行构造器, 如中所述。 右手边是一个圆括弧子查询,它必须返回和左手边返回的行中表达式所构成的完全一样多的列。 左手边表达式将被计算并与子查询结果逐行进行比较。如果找到任意相等的子查询行,则IN的结果为。如果没有找到相等行, 那么结果为(包括子查询不返回行的情况)。 + 这种形式的IN左手边是一个行构造器,如中所述。右手边是一个圆括号括起来的子查询,它必须返回与左手边行中表达式数量完全相同的列数。左手边表达式会被求值,并与子查询结果逐行比较。如果找到任意相等的子查询行,则IN的结果为。如果没有找到相等行,那么结果为(包括子查询不返回任何行的情况)。 @@ -107,15 +107,15 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 右手边是一个用圆括弧包围的子查询,它必须返回正好一个列。左手边表达式将被计算并与子查询结果逐行进行比较。 如果只找到不相等的子查询行(包括子查询不返回行的情况),那么NOT IN的结果是。 如果找到任何相等行,则结果为。 + 右手边是一个圆括号括起来的子查询,它必须恰好返回一列。左手边表达式会被求值,并与子查询结果逐行比较。如果只找到不相等的子查询行(包括子查询不返回任何行的情况),那么NOT IN的结果是。如果找到任何相等行,则结果为 - 请注意如果左手边表达式得到空值,或者没有相等的右手边值, 并且至少有一个右手边行得到空值,那么NOT IN结构的结果将是空值,而不是真。这个行为是遵照 SQL 处理空值的一般规则的。 + 请注意,如果左侧表达式得到空值,或者右侧没有相等的值且至少有一行得到空值,则NOT IN结构的结果将是空值,而不是真。这符合 SQL 对空值布尔组合的一般规则。 - 和EXISTS一样,假设子查询将被完成运行完全是不明智的。 + 和EXISTS一样,假定子查询一定会完整运行并不明智。 @@ -123,7 +123,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 这种形式的NOT IN的左手边是一个行构造器, 如中所述。 右手边是一个圆括弧子查询,它必须返回和左手边返回的行中表达式所构成的完全一样多的列。 左手边表达式将被计算并与子查询结果逐行进行比较。如果找到不等于子查询行的行,则NOT IN的结果为。如果找到相等行, 那么结果为(包括子查询不返回行的情况)。 + 这种形式的NOT IN左侧是一个行构造器,如中所述。右侧是一个用圆括号括起来的子查询,必须返回与左侧行中表达式数量完全相同的列数。对左侧表达式求值后,将其按行与子查询结果的每一行比较。如果只找到不相等的子查询行(包括子查询不返回任何行的情况),则NOT IN的结果为。如果找到任何相等行,则结果为 @@ -141,7 +141,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 这种形式的右侧是一个用括号括起来的子查询,它必须恰好返回一列。左侧表达式会被求值,并使用给定的 operator 与子查询结果的每一行进行比较。如果得到任何真值结果,那么ANY的结果就是。如果没有找到真值结果,那么结果是(包括子查询没有返回任何行的情况)。 + 这种形式的右侧是一个用括号括起来的子查询,它必须恰好返回一列。左侧表达式会被求值,并使用给定的 operator 与子查询结果的每一行进行比较。该操作符必须产生布尔结果。如果得到任何真值结果,那么ANY的结果就是。如果没有找到真值结果,那么结果是(包括子查询没有返回任何行的情况)。 @@ -149,11 +149,11 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 请注意如果没有任何成功并且至少有一个右手边行为该操作符结果生成空值, 那么ANY结构的结果将是空值,而不是假。 这个行为是遵照 SQL 处理空值布尔组合的一般规则制定的。 + 请注意,如果没有任何比较返回真,并且至少有一个右侧行的操作符结果为空值,则ANY结构的结果将是空值,而不是假。这符合 SQL 对空值布尔组合的一般规则。 - 和EXISTS一样,假设子查询将被完成运行完全是不明智的。 + 和EXISTS一样,假定子查询一定会完整运行并不明智。 @@ -162,7 +162,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 这种形式的左侧是一个行构造器,如所述。右侧是一个用括号括起来的子查询,它必须返回与左侧行中表达式数量完全相同的列数。左侧表达式会被求值,并使用给定的operator与子查询结果的每一行逐行比较。如果比较对任何子查询行返回真,则ANY的结果为。如果比较对每一个子查询行都返回假,则结果为(包括子查询不返回行的情况)。如果比较对任何行都不返回真,并且至少有一次比较返回 NULL,则结果为 NULL。 + 这种形式的ANY左侧是一个行构造器,如所述。右侧是一个用括号括起来的子查询,它必须返回与左侧行中表达式数量完全相同的列数。左侧表达式会被求值,并使用给定的operator与子查询结果的每一行逐行比较。如果比较对任何子查询行返回真,则ANY的结果为。如果比较对每一个子查询行都返回假,则结果为(包括子查询不返回行的情况)。如果比较对任何行都不返回真,并且至少有一次比较返回 NULL,则结果为 NULL。 @@ -178,7 +178,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 这种形式的 ALL 右侧是一个用括号括起来的子查询,它必须只返回一列。左侧表达式会被求值,并使用给定的 operator 与子查询结果的每一行进行比较。该操作符必须产生布尔结果。如果所有行都得到真(包括子查询没有返回任何行的情况),ALL 的结果就是。如果发现任何假值结果,结果就是。如果比较对任何行都不返回假,并且至少有一次比较返回 NULL,则结果为 NULL。 + 右侧是一个用圆括号括起来的子查询,必须恰好返回一列。左侧表达式会被求值,并使用给定的operator与子查询结果的每一行进行比较。该操作符必须产生布尔结果。如果所有行都得到真(包括子查询不返回任何行的情况),则ALL的结果为。如果得到任何假值结果,则结果为。如果与任何子查询行的比较都不返回假,并且至少有一次比较返回 NULL,则结果为 NULL。 @@ -186,7 +186,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 和EXISTS一样,假设子查询将被完成运行完全是不明智的。 + 和EXISTS一样,假定子查询一定会完整运行并不明智。 @@ -216,7 +216,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - 左手边是一个行构造器,如所述。 右手边是一个圆括弧括起来的子查询,该查询必须返回和左手边行中表达式数目完全一样的列。 另外,该子查询不能返回超过一行的数量(如果它返回零行,那么结果就是空值)。 左手边被计算并逐行与右手边的子查询结果行比较。 + 左侧是一个行构造器,如所述。右侧是一个用圆括号括起来的子查询,必须返回与左侧行中表达式数量完全相同的列数。此外,该子查询不能返回超过一行;如果它返回零行,则结果为空值。对左侧求值后,将所得的行与子查询返回的唯一一行进行比较。 diff --git a/zh/20/func/func-textsearch.sgml b/zh/20/func/func-textsearch.sgml index 71cd8c73..4a3f705a 100644 --- a/zh/20/func/func-textsearch.sgml +++ b/zh/20/func/func-textsearch.sgml @@ -3,7 +3,7 @@ 文本搜索函数和操作符 - 全文搜索 + 全文检索 函数和操作符 @@ -16,7 +16,7 @@ 以及 - 总结了为全文搜索提供的函数和操作符。PostgreSQL的文本搜索功能的详细解释可参考。 + 总结了为全文检索提供的函数和操作符。PostgreSQL的文本搜索功能的详细解释可参考 @@ -72,23 +72,7 @@ - - - tsvector @@@ tsquery - boolean - - - tsquery @@@ tsvector - boolean - - - 这是@@已弃用的同义词。 - - - to_tsvector('fat cats ate rats') @@@ to_tsquery('cat & rat') - t - - + @@ -96,11 +80,11 @@ tsvector - 连接两个tsvector。如果两个输入都包含词素位置,则相应地调整第二个输入的位置。 + 连接两个tsvector。如果两个输入都包含词位位置,则相应地调整第二个输入的位置。 'a:1 b:2'::tsvector || 'c:1 d:2 b:3'::tsvector - 'a':1'b':2,5'c':3'd':4 + 'a':1 'b':2,5 'c':3 'd':4 @@ -138,7 +122,7 @@ tsquery - 否定tsquery,生成一个与输入查询不匹配的匹配文档的查询。 + 对tsquery取反,生成匹配那些不满足输入查询的文档的查询。 !! 'cat'::tsquery @@ -152,7 +136,7 @@ tsquery - 构造一个短语查询,如果两个输入查询在连续的词素上匹配,该查询将进行匹配。 + 构造一个短语查询;当两个输入查询分别匹配相邻的词位时,该查询匹配。 to_tsquery('fat') <-> to_tsquery('rat') @@ -166,7 +150,7 @@ boolean - 第一个tsquery包含了第二个吗?(这只考虑出现在一个查询中的所有词素是否出现在另一个查询中,忽略了组合操作符。) + 第一个tsquery包含了第二个吗?(这只考虑出现在一个查询中的所有词位是否出现在另一个查询中,忽略了组合操作符。) 'cat'::tsquery @> 'cat & rat'::tsquery @@ -180,7 +164,7 @@ boolean - 第一个tsquery包含在第二个中吗?(这只考虑出现在一个查询中的所有词素是否出现在另一个查询中,而忽略了组合操作符。) + 第一个tsquery包含在第二个中吗?(这只考虑出现在一个查询中的所有词位是否出现在另一个查询中,而忽略了组合操作符。) 'cat'::tsquery <@ 'cat & rat'::tsquery @@ -197,7 +181,7 @@ 除了这些专用操作符之外, 中所示的常用比较操作符也适用于tsvectortsquery类型。 - 它们对于文本搜索不是很有用,但是允许使用。例如,建在这些类型列上的唯一索引。 + 这些操作符对文本搜索用处不大,但可以用于其他用途,例如在这些类型的列上建立唯一索引。
@@ -231,7 +215,7 @@ 将文本字符串数组转换为tsvector。 - 给定的字符串被直接用作词元,不经过进一步处理。数组元素不得为空字符串 + 给定的字符串被直接用作词位,不经过进一步处理。数组元素不得为空字符串 或NULL @@ -302,8 +286,7 @@ tsquery - 将文本转换为tsquery,根据指定的或默认配置对单词进行标准化。 - 字符串中的任何标点符号都会被忽略(它不决定查询操作符)。结果查询匹配文本中包含所有非停止词的文档。 + 将文本转换为tsquery,根据指定的或默认配置对单词进行正规化。字符串中的任何标点符号都会被忽略(它们不决定查询操作符)。生成的查询匹配包含文本中所有非停用词的文档。 plainto_tsquery('english', 'The Fat Rats') @@ -322,8 +305,8 @@ tsquery - 将文本转换为tsquery,根据指定的或默认配置对单词进行标准化。 - 字符串中的任何标点符号都会被忽略(它不决定查询操作符)。结果查询匹配包含文本中所有非停止词的短语。 + 将文本转换为tsquery,根据指定的或默认配置对单词进行正规化。 + 字符串中的任何标点符号都会被忽略(它不决定查询操作符)。结果查询匹配包含文本中所有非停用词的短语。 phraseto_tsquery('english', 'The Fat Rats') @@ -346,8 +329,7 @@ tsquery - 将文本转换为tsquery,根据指定的或默认配置对单词进行标准化。引用的单词序列被转换为短语测试。 - or一词被理解为产生OR操作符,而破折号产生NOT操作符;其他标点符号被忽略。这类似于一些常见的网络搜索工具的行为。 + 将文本转换为tsquery,根据指定的或默认配置对单词进行正规化。带引号的单词序列被转换为短语测试。or一词产生 OR 操作符,短横线产生 NOT 操作符;其他标点符号会被忽略。这类似于一些常见网络搜索工具的行为。 websearch_to_tsquery('english', '"fat rat" or cat dog') @@ -393,14 +375,13 @@ setweight - 为特定词元设置权重 + 为特定词位设置权重 setweight ( vector tsvector, weight "char", lexemes text[] ) tsvector - 为vector中列出的lexemes赋予指定的weight。 - lexemes中的字符串被视为词元,不经过进一步处理。不匹配vector中任何词元的字符串将被忽略。 + 为vector中列在lexemes内的元素赋予指定的weightlexemes中的字符串按原样用作词位,不经过进一步处理。不匹配vector中任何词位的字符串将被忽略。 setweight('fat:2,4 cat:3 rat:5,6B'::tsvector, 'A', '{cat,rat}') @@ -436,7 +417,7 @@ tsquery - 将文本转换为tsquery,根据指定的或默认配置对单词进行标准化。单词必须由有效的tsquery操作符组合。 + 将文本转换为tsquery,根据指定的或默认配置对单词进行正规化。单词必须由有效的tsquery操作符组合。 to_tsquery('english', 'The & Fat & Rats') @@ -455,7 +436,7 @@ tsvector - 将文本转换为tsvector,根据指定的或默认配置对单词进行标准化。结果中包含位置信息。 + 将文本转换为tsvector,根据指定的或默认配置对单词进行正规化。结果中包含位置信息。 to_tsvector('english', 'The Fat Rats') @@ -477,9 +458,7 @@ tsvector - 将JSON文档中的每个字符串值转换为tsvector,根据指定的或默认配置对单词进行标准化。 - 然后将结果按文档顺序连接起来以产生输出。位置信息就像在每对字符串值之间存在一个停止词一样生成。 - (注意,当输入为jsonb时,JSON对象的字段的document order取决于实现;请观察这些示例中的差异。) + 将 JSON 文档中的每个字符串值转换为tsvector,根据指定的或默认配置对单词进行正规化。然后将结果按文档顺序连接起来以产生输出。生成位置信息时,视为每对字符串值之间存在一个停用词。(注意,当输入为jsonb时,JSON 对象字段的文档顺序取决于具体实现;请注意这些示例中的差异。) to_tsvector('english', '{"aa": "The Fat Rats", "b": "dog"}'::json) @@ -513,15 +492,15 @@ tsvector - 选择filter请求的JSON文档中的每个项,并将每个项转换为tsvector,根据指定的或默认配置对单词进行标准化。 - 然后将结果按文档顺序连接起来以产生输出。位置信息就像在每对选定的项目之间存在一个停止词一样生成。 - (注意,当输入为jsonb时,JSON对象字段的document order取决于实现。) - filter必须是一个jsonb数组,其中包含0个或多个关键字: + 选择filter请求的JSON文档中的每个项,并将每个项转换为tsvector,根据指定的或默认配置对单词进行正规化。 + 然后将结果按文档顺序连接起来以产生输出。位置信息就像在每对选定的项目之间存在一个停用词一样生成。 + (注意,当输入为jsonb时,JSON对象字段的文档顺序取决于实现。) + filter必须是一个jsonb数组,其中包含0个或多个关键字: "string"(包括所有字符串值), "numeric"(包括所有数值), "boolean"(包括所有布尔值), "key"(包括所有键),或 - "all"(包括以上所有关键字)。 + "all"(包括以上所有内容)。 作为一种特殊情况,该filter也可以是这些关键字之一的简单JSON值。 @@ -543,8 +522,8 @@ tsvector - 从vector中删除给定的lexeme的任何出现。 - lexeme字符串被视为原样的词元,不经过进一步处理。 + 从vector中删除给定的lexeme的所有出现。 + lexeme字符串被视为原样的词位,不经过进一步处理。 ts_delete('fat:2,4 cat:3 rat:5A'::tsvector, 'fat') @@ -558,9 +537,7 @@ tsvector - 从vector中删除lexemes中的任何出现。 - lexemes中的字符串被视为词元,不经过进一步处理。 - 不匹配vector中任何词元的字符串将被忽略。 + 从vector中删除lexemes所列词位的所有出现。lexemes中的字符串按原样用作词位,不经过进一步处理。不匹配vector中任何词位的字符串将被忽略。 ts_delete('fat:2,4 cat:3 rat:5A'::tsvector, ARRAY['fat','rat']) @@ -598,9 +575,7 @@ text - 以缩写形式显示documentquery的匹配项,该匹配项必须是原始文本,而不是tsvector。 - 在匹配查询之前,文档中的单词将根据指定的或默认的配置进行规范化。 - 中讨论了该函数的使用,还描述了可用的options。 + 以缩略形式显示querydocument中的匹配项;后者必须是原始文本,不能是tsvector。在匹配查询之前,文档中的单词将根据指定的或默认配置进行正规化。中讨论了该函数的使用,还描述了可用的options ts_headline('The fat cat ate the rat.', 'cat') @@ -626,8 +601,7 @@ text - 以缩写形式显示匹配JSONdocument中字符串值中的query。 - 更多细节请参阅 。 + 以缩略形式显示query在 JSON document字符串值中的匹配项。更多细节请参见 ts_headline('{"cat":"raining cats and dogs"}'::jsonb, 'cat') @@ -705,8 +679,7 @@ tsquery - 根据目标替换部分query,并替换通过执行SELECT命令获得的查询。 - 详情参见。 + 根据执行SELECT命令得到的目标和替换项,替换query中的相应部分。详情参见 SELECT ts_rewrite('a & b'::tsquery, 'SELECT t,s FROM aliases') @@ -737,7 +710,7 @@ tsquery - 构造一个短语查询,用于搜索query1query2的匹配项,这些匹配项恰好出现在distance词位之间。 + 构造一个短语查询,用于搜索query1query2的匹配项,其匹配位置恰好相距distance个词位。 tsquery_phrase(to_tsquery('fat'), to_tsquery('cat'), 10) @@ -766,7 +739,7 @@ unnest - for tsvector + 用于 tsvector unnest ( tsvector ) setof record @@ -796,7 +769,7 @@ - 所有接受一个可选的regconfig参数的文本搜索函数在该参数被忽略时,使用由指定的配置。 + 所有接受一个可选的regconfig参数的文本搜索函数在省略该参数时,会使用由指定的配置。 @@ -843,7 +816,7 @@ lexemes text[] ) - 根据指定的或默认的文本搜索配置从document中提取和标准化标记,并返回关于每个标记是如何处理的信息。 + 根据指定的或默认的文本搜索配置从document中提取和正规化词元,并返回关于每个词元是如何处理的信息。 详情参见 @@ -861,8 +834,7 @@ text[] - 如果字典知道输入标记,则返回替换词位数组;如果字典知道标记,但它是停止词,则返回空数组;如果它不是已知词,则返回NULL。 - 详情参见。 + 如果词典识别输入词元,则返回由替换词位组成的数组;如果词典识别该词元,但它是停用词,则返回空数组;如果词典无法识别该词元,则返回NULL。详情参见 ts_lexize('english_stem', 'stars') @@ -882,7 +854,7 @@ token text ) - 使用命名的解析器从document中提取标记。详情参见。 + 使用指定名称的解析器从document中提取词元。详情参见 ts_parse('default', 'foo - bar') @@ -899,7 +871,7 @@ token text ) - 使用 OID 指定的解析器从document中提取标记。 + 使用 OID 指定的解析器从document中提取词元。 详情参见 @@ -920,7 +892,7 @@ description text ) - 返回一个表,该表描述命名解析器可以识别的每种类型的标记。详情参见。 + 返回一个表,该表描述指定名称的解析器可以识别的每种类型的词元。详情参见 ts_token_type('default') @@ -937,7 +909,7 @@ description text ) - 返回一个表,该表描述 OID 指定的解析器可以识别的每种标记类型。详情参见。 + 返回一个表,该表描述 OID 指定的解析器可以识别的每种词元类型。详情参见 ts_token_type(3722) @@ -958,7 +930,7 @@ nentry integer ) - 执行sqlquery,该查询必须返回单个tsvector列,并返回数据中每个不同词元的统计信息。 + 执行sqlquery,该查询必须返回单个tsvector列,并返回数据中每个不同词位的统计信息。 详情参见 diff --git a/zh/20/func/func-trigger.sgml b/zh/20/func/func-trigger.sgml index 0aaece25..dc20b4ef 100644 --- a/zh/20/func/func-trigger.sgml +++ b/zh/20/func/func-trigger.sgml @@ -42,7 +42,7 @@ trigger - 阻止不做事的更新操作。详见下文。 + 抑制不改变数据的更新操作。详见下文。 CREATE TRIGGER ... suppress_redundant_updates_trigger() @@ -58,8 +58,7 @@ trigger - 自动从相关的纯文本文档列更新tsvector列。 - 要使用的文本搜索配置是以名称指定为触发器参数。详情请参见。 + 根据关联的纯文本文档列自动更新tsvector列。所用的全文检索配置以名称形式指定为触发器参数。详见 CREATE TRIGGER ... tsvector_update_trigger(tsvcol, 'pg_catalog.swedish', title, body) @@ -75,8 +74,7 @@ trigger - 自动从相关的纯文本文档列更新tsvector列。 - 要使用的文本搜索配置取自表的regconfig列。详情请参见。 + 根据关联的纯文本文档列自动更新tsvector列。所用的全文检索配置取自表的regconfig列。详见 CREATE TRIGGER ... tsvector_update_trigger_column(tsvcol, tsconfigcol, title, body) @@ -93,22 +91,14 @@ - 理想的情况下,你应该避免运行实际上并没有改变记录中数据的更新。 - 冗余更新会花费大量不必要的时间,尤其是如果有大量索引要改变, 并将最终不得不清理被死亡行占用的空间。 - 但是,在客户端代码中检测这种情况并不总是容易的,甚至不可能做到。 而写表达式来检测它们容易产生错误。 - 作为替代,使用suppress_redundant_updates_trigger可以跳过不改变数据的更新。 但是,你需要小心使用它。 - 触发器需要很短但不能忽略的时间来处理每条记录,所以如果受更新影响的大多数记录确实变化了,此触发器的使用将使更新比平均水平运行得更慢。 + 理想情况下,应避免执行实际上不会改变记录中数据的更新。冗余更新会耗费大量不必要的时间,尤其是在需要修改许多索引时;它们还会使死行占用空间,最终需要通过清理回收。但是,在客户端代码中检测这种情况并不总是容易,甚至可能无法做到,而编写用于检测的表达式也容易出错。另一种办法是使用suppress_redundant_updates_trigger,跳过不改变数据的更新。但使用时应当谨慎。此触发器处理每条记录的耗时虽小,却不可忽略,因此如果更新涉及的大多数记录确实会改变,使用此触发器反而会增加更新的平均耗时。 - suppress_redundant_updates_trigger函数可以像这样添加到表中: - + 该suppress_redundant_updates_trigger函数可以按如下方式添加到表中: CREATE TRIGGER z_min_update BEFORE UPDATE ON tablename FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); - - 在大多数情况下,你需要为每一行最后触发这个触发器,这样它就不会覆盖可能希望更改该行的其他触发器。 - 请记住,触发器是按照名称顺序触发的,你将为此选择一个触发器名称,该名称位于表中可能存在的任何其他触发器的名称之后。 - (因此在示例中使用了z前缀。) +大多数情况下,需要让该触发器对每一行最后触发,以免覆盖其他可能修改该行的触发器的效果。由于触发器按名称顺序触发,应选择一个排序位于表上其他所有触发器名称之后的名称。(这就是示例中使用z前缀的原因。) diff --git a/zh/20/func/func-uuid.sgml b/zh/20/func/func-uuid.sgml index 2bd00cf1..fcbed931 100644 --- a/zh/20/func/func-uuid.sgml +++ b/zh/20/func/func-uuid.sgml @@ -2,7 +2,7 @@ UUID 函数 - + UUID 生成 @@ -166,8 +166,7 @@
- PostgreSQL也为 UUID 提供了 - 中展示的常用比较操作符。 + PostgreSQL也为 UUID 提供了中展示的常用比较操作符。 关于PostgreSQLuuid数据类型的细节,请参见 diff --git a/zh/20/func/func-window.sgml b/zh/20/func/func-window.sgml index d0d73ebb..c55d42c9 100644 --- a/zh/20/func/func-window.sgml +++ b/zh/20/func/func-window.sgml @@ -17,7 +17,7 @@ - 除了这些函数之外,任何内置的或用户定义的普通聚合(例如非有序集或假想集聚合)都可以作为窗口函数使用;关于内置聚合的列表,参见。 + 除了这些函数之外,任何内置的或用户定义的普通聚合(即不属于有序集或假想集聚合)都可以作为窗口函数使用;关于内置聚合的列表,参见。 聚合函数只有在调用后带有OVER子句时才作为窗口函数;否则,它们就是普通聚合,并为整个结果集返回一行。 @@ -48,7 +48,7 @@ bigint
- 返回其分区内的当前行数,从1开始计数。 + 返回当前行在其分区内的编号,从 1 开始计数。 @@ -61,7 +61,7 @@ bigint
- 返回当前行的排名,包含间隔;即同等行组中第一行的row_number。 + 返回当前行的排名,允许空缺;即同等行组中第一行的row_number @@ -74,7 +74,7 @@ bigint
- 返回当前行的排名,不包括间隔;这个功能有效地计数同等行组。 + 返回当前行的排名,没有空缺;此函数实际上对同等行组进行计数。 @@ -113,7 +113,7 @@ integer
- 返回一个从1到参数值的整数,并将分区划分为尽可能相等的值。 + 返回从 1 到参数值的整数,将分区尽可能均等地划分。 @@ -128,9 +128,7 @@ anycompatible
- 返回分区中在当前行之前offset行的value;如果没有这样的行,则返回default(必须与value相兼容的类型)。 - offsetdefault都是针对当前行求值的。 - 如果省略,offset默认为1,defaultNULL。 + 返回在分区内当前行之前offset行处计算的value;如果没有这样的行,则返回default(其类型必须与value兼容)。offsetdefault都针对当前行求值。如果省略,offset默认为 1,default默认为NULL @@ -145,10 +143,7 @@ anycompatible
- 返回分区中在当前行之后offset行的value; - 如果没有这样的行,则返回default(必须与value兼容的类型)。 - offsetdefault都是针对当前行求值的。 - 如果省略,offset默认为1,defaultNULL。 + 返回在分区内当前行之后offset行处计算的value;如果没有这样的行,则返回default(其类型必须与value兼容)。offsetdefault都针对当前行求值。如果省略,offset默认为 1,default默认为NULL @@ -203,14 +198,14 @@ 注意first_valuelast_valuenth_value只考虑窗口帧内的行,它默认情况下包含从分区的开始行直到当前行的最后一个同等行。 这对last_value可能不会给出有用的结果,有时对nth_value也一样。 - 你可以通过向OVER子句增加一个合适的帧声明(RANGEGROUPS)来重定义帧。 + 你可以通过向OVER子句增加一个合适的帧声明(RANGEROWSGROUPS)来重定义帧。 关于帧声明的更多信息请参考 当一个聚合函数被用作窗口函数时,它将在当前行的窗口帧内的行上聚合。 - 一个使用ORDER BY和默认窗口帧定义的聚合产生一种运行时求和类型的行为,这可能是或者不是想要的结果。 - 为了获取在整个分区上的聚合,忽略ORDER BY或者使用ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING。 + 一个使用ORDER BY和默认窗口帧定义的聚合产生一种累计求和类型的行为,这可能是或者不是想要的结果。 + 为了获取在整个分区上的聚合,省略ORDER BY或者使用ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING。 其它窗口帧声明可以用来获得其它的效果。 diff --git a/zh/20/func/func-xml.sgml b/zh/20/func/func-xml.sgml index b2f675fe..28e7e31f 100644 --- a/zh/20/func/func-xml.sgml +++ b/zh/20/func/func-xml.sgml @@ -458,7 +458,7 @@ SELECT xmlexists('//town[text() = ''Toronto'']' PASSING BY VALUE 'T
- 示例: + 示例: - 示例: + 示例: test', ARRAY[ARRAY['my', 'http://example.com']]); @@ -575,7 +575,7 @@ SELECT xpath('//mydefns:b/text()', 'test - 示例: + 示例: test', ARRAY[ARRAY['my', 'http://example.com']]); @@ -627,8 +627,8 @@ SELECT xpath_exists('/my:a/text()', 'test - document_expression提供了上下文。row_expression的项。 - 它必须是一个格式良好的XML文档;不接受片段/森林。BY REFBY VALUE子句 如上文所讨论的那样,被接受但被忽略了,正如在中所讨论的。 + document_expressionrow_expression提供上下文项。 + 它必须是一个良构的 XML 文档;不接受内容片段或森林。BY REFBY VALUE子句会被接受,但会被忽略,如中所述。 @@ -677,7 +677,7 @@ SELECT xpath_exists('/my:a/text()', 'test - 一个XML元素的字符串值是字符串值的协整,按文档的顺序。该元素中包含的所有文本节点及其子节点。字符串 元素的值是一个没有下级文本节点的元素的值是一个 空字符串(不是NULL)。任何xsi:nil属性都会被忽略。请注意,两个非文本之间的text()节点只用空格,而两个非文本 元素,并且保留了text()上的前导白格。节点不被扁平化。XPath 1.0中的string函数可以参考XPath 1.0中的 定义其他XML节点类型和非XML值的字符串值的规则。 + 一个 XML 元素的字符串值,是该元素及其所有后代中包含的文本节点按文档顺序拼接而成的字符串。没有后代文本节点的元素,其字符串值为空字符串(不是 NULL)。所有 xsi:nil 属性都会被忽略。注意,两个非文本元素之间仅含空白的 text() 节点会被保留,text() 节点的前导空白也不会被折叠。其他 XML 节点类型及非 XML 值的字符串值定义规则,可参考 XPath 1.0 的 string 函数。 @@ -697,7 +697,7 @@ SELECT xpath_exists('/my:a/text()', 'test - 示例: + 示例: - 下面的示例展示了多个text()节点的连接,列名作为XPath过滤器的使用,以及对空格、XML注释和处理指令的处理: + 下面的示例展示了多个text()节点的连接,列名作为XPath过滤器的使用,以及对空格、XML注释和处理指令的处理: NOTIFY channel hash table.", - "chinese": "等待访问 NOTIFY 通道哈希表。" - }, - { - "english": "Waiting to read or update shared Wait-for-LSN state.", - "chinese": "等待读取或更新共享的 LSN 等待状态。" - }, - { - "english": "Waiting for commit delay before WAL flush.", - "chinese": "等待 WAL 刷盘前的提交延迟。" - }, - { - "english": "\n ArchiverMain\n Waiting in main loop of archiver process.\n ", - "chinese": "\n ArchiverMain\n 在归档进程的主循环中等待。\n " - }, - { - "english": "\n AutovacuumMain\n Waiting in main loop of autovacuum launcher process.\n ", - "chinese": "\n AutovacuumMain\n 在自动清理启动过程的主循环中等待。\n " - }, - { - "english": "\n BgwriterHibernate\n Waiting in background writer process, hibernating.\n ", - "chinese": "\n BgwriterHibernate\n 在后台写入器中等待,休眠状态。\n " - }, - { - "english": "\n BgwriterMain\n Waiting in main loop of background writer process.\n ", - "chinese": "\n BgwriterMain\n 在后台写入器主循环中等待。\n " - }, - { - "english": "\n CheckpointerMain\n Waiting in main loop of checkpointer process.\n ", - "chinese": "\n CheckpointerMain\n 在检查点进程的主循环中等待。\n " - }, - { - "english": "\n LogicalApplyMain\n Waiting in main loop of logical replication apply process.\n ", - "chinese": "\n LogicalApplyMain\n 在逻辑复制应用进程的主循环中等待。\n " - }, - { - "english": "\n LogicalLauncherMain\n Waiting in main loop of logical replication launcher process.\n ", - "chinese": "\n LogicalLauncherMain\n 在逻辑复制启动器进程的主循环中等待。\n " - }, - { - "english": "\n RecoveryWalStream\n Waiting in main loop of startup process for WAL to arrive, during streaming recovery.\n ", - "chinese": "\n RecoveryWalStream\n 流恢复期间,在启动进程主循环等待WAL到达。\n " - }, - { - "english": "\n SysloggerMain\n Waiting in main loop of syslogger process.\n ", - "chinese": "\n SysloggerMain\n 在 syslogger 进程的主循环中等待。\n " - }, - { - "english": "\n WalReceiverMain\n Waiting in main loop of WAL receiver process.\n ", - "chinese": "\n WalReceiverMain\n 在WAL 接收进程的主循环中等待。\n " - }, - { - "english": "\n WalSenderMain\n Waiting in main loop of WAL sender process.\n ", - "chinese": "\n WalSenderMain\n 在 WAL 发送进程的主循环中等待。\n " - }, - { - "english": "\n WalWriterMain\n Waiting in main loop of WAL writer process.\n ", - "chinese": "\n WalWriterMain\n 在WAL写入进程的主循环中等待。\n " - }, - { - "english": "\n ClientRead\n Waiting to read data from the client.\n ", - "chinese": "\n ClientRead\n 等待从客户端读取数据。\n " - }, - { - "english": "\n ClientWrite\n Waiting to write data to the client.\n ", - "chinese": "\n ClientWrite\n 等待写入数据到客户端。\n " - }, - { - "english": "\n GssOpenServer\n Waiting to read data from the client while establishing a GSSAPI session.\n ", - "chinese": "\n GssOpenServer\n 在建立GSSAPI会话时等待从客户端读取数据。\n " - }, - { - "english": "\n LibpqwalreceiverConnect\n Waiting in WAL receiver to establish connection to remote server.\n ", - "chinese": "\n LibpqwalreceiverConnect\n 在WAL 接收进程等待与远程服务器建立连接。\n " - }, - { - "english": "\n LibpqwalreceiverReceive\n Waiting in WAL receiver to receive data from remote server.\n ", - "chinese": "\n LibpqwalreceiverReceive\n 在WAL 接收进程中等待从远程服务器接收数据。\n " - }, - { - "english": "\n SslOpenServer\n Waiting for SSL while attempting connection.\n ", - "chinese": "\n SslOpenServer\n 在尝试连接时等待SSL。\n " - }, - { - "english": "\n WalSenderWaitForWal\n Waiting for WAL to be flushed in WAL sender process.\n ", - "chinese": "\n WalSenderWaitForWal\n 在 WAL 发送进程中等待 WAL 被刷新。\n " - }, - { - "english": "\n WalSenderWriteData\n Waiting for any activity when processing replies from WAL receiver in WAL sender process.\n ", - "chinese": "\n WalSenderWriteData\n 在 WAL 发送进程中处理 WAL 接收进程的回复时,等待任何活动。\n " - }, - { - "english": "\n Extension\n Waiting in an extension.\n ", - "chinese": "\n Extension\n 在扩展中等待。\n " - }, - { - "english": "\n BasebackupRead\n Waiting for base backup to read from a file.\n ", - "chinese": "\n BasebackupRead\n 等待基础备份从文件中读取。\n " - }, - { - "english": "\n BasebackupSync\n Waiting for data written by a base backup to reach durable storage.\n ", - "chinese": "\n BasebackupSync\n 等待由基础备份写入的数据达到持久存储。\n " - }, - { - "english": "\n BasebackupWrite\n Waiting for base backup to write to a file.\n ", - "chinese": "\n BasebackupWrite\n 等待基础备份写入文件。\n " - }, - { - "english": "\n BuffileRead\n Waiting for a read from a buffered file.\n ", - "chinese": "\n BuffileRead\n 等待从缓冲文件中读取。\n " - }, - { - "english": "\n BuffileTruncate\n Waiting for a buffered file to be truncated.\n ", - "chinese": "\n BuffileTruncate\n 等待一个缓冲文件被截断。\n " - }, - { - "english": "\n BuffileWrite\n Waiting for a write to a buffered file.\n ", - "chinese": "\n BuffileWrite\n 等待对缓冲文件的写入。\n " - }, - { - "english": "\n ControlFileRead\n Waiting for a read from the pg_control file.\n ", - "chinese": "\n ControlFileRead\n 等待读取pg_control文件。\n " - }, - { - "english": "\n ControlFileSync\n Waiting for the pg_control file to reach durable storage.\n ", - "chinese": "\n ControlFileSync\n 等待pg_control文件到达持久存储。\n " - }, - { - "english": "\n ControlFileSyncUpdate\n Waiting for an update to the pg_control file to reach durable storage.\n ", - "chinese": "\n ControlFileSyncUpdate\n 等待更新pg_control文件以达到持久存储。\n " - }, - { - "english": "\n ControlFileWrite\n Waiting for a write to the pg_control file.\n ", - "chinese": "\n ControlFileWrite\n 等待写入pg_control文件。\n " - }, - { - "english": "\n ControlFileWriteUpdate\n Waiting for a write to update the pg_control file.\n ", - "chinese": "\n ControlFileWriteUpdate\n 等待写入更新pg_control文件。\n " - }, - { - "english": "\n CopyFileRead\n Waiting for a read during a file copy operation.\n ", - "chinese": "\n CopyFileRead\n 在文件复制操作期间等待读取。\n " - }, - { - "english": "\n CopyFileWrite\n Waiting for a write during a file copy operation.\n ", - "chinese": "\n CopyFileWrite\n 在文件拷贝操作期间等待写入。\n " - }, - { - "english": "\n DataFileExtend\n Waiting for a relation data file to be extended.\n ", - "chinese": "\n DataFileExtend\n 等待关系数据文件被扩展。\n " - }, - { - "english": "\n DataFileFlush\n Waiting for a relation data file to reach durable storage.\n ", - "chinese": "\n DataFileFlush\n 等待关系数据文件达到持久存储。\n " - }, - { - "english": "\n DataFileImmediateSync\n Waiting for an immediate synchronization of a relation data file to durable storage.\n ", - "chinese": "\n DataFileImmediateSync\n 等待关系数据文件到持久存储的立即同步。\n " - }, - { - "english": "\n DataFilePrefetch\n Waiting for an asynchronous prefetch from a relation data file.\n ", - "chinese": "\n DataFilePrefetch\n 等待关系数据文件的异步预取。\n " - }, - { - "english": "\n DataFileRead\n Waiting for a read from a relation data file.\n ", - "chinese": "\n DataFileRead\n 等待对关系数据文件的读取。\n " - }, - { - "english": "\n DataFileSync\n Waiting for changes to a relation data file to reach durable storage.\n ", - "chinese": "\n DataFileSync\n 等待对关系数据文件的更改达到持久存储。\n " - }, - { - "english": "\n DataFileTruncate\n Waiting for a relation data file to be truncated.\n ", - "chinese": "\n DataFileTruncate\n 等待关系数据文件被截断。\n " - }, - { - "english": "\n DataFileWrite\n Waiting for a write to a relation data file.\n ", - "chinese": "\n DataFileWrite\n 等待对关系数据文件的写入。\n " - }, - { - "english": "\n DsmFillZeroWrite\n Waiting to fill a dynamic shared memory backing file with zeroes.\n ", - "chinese": "\n DsmFillZeroWrite\n 等待用零填充动态共享内存备份(backing)文件。\n " - }, - { - "english": "\n LockFileAddtodatadirRead\n Waiting for a read while adding a line to the data directory lock file.\n ", - "chinese": "\n LockFileAddtodatadirRead\n 在向数据目录锁文件中添加一行时等待读取。\n " - }, - { - "english": "\n LockFileAddtodatadirSync\n Waiting for data to reach durable storage while adding a line to the data directory lock file.\n ", - "chinese": "\n LockFileAddtodatadirSync\n 等待数据到达持久存储,同时向数据目录锁文件添加一行。\n " - }, - { - "english": "\n LockFileAddtodatadirWrite\n Waiting for a write while adding a line to the data directory lock file.\n ", - "chinese": "\n LockFileAddtodatadirWrite\n 在向数据目录锁文件中添加一行时等待写操作。\n " - }, - { - "english": "\n LockFileCreateRead\n Waiting to read while creating the data directory lock file.\n ", - "chinese": "\n LockFileCreateRead\n 创建数据目录锁文件时等待读取。\n " - }, - { - "english": "\n LockFileCreateSync\n Waiting for data to reach durable storage while creating the data directory lock file.\n ", - "chinese": "\n LockFileCreateSync\n 在创建数据目录锁文件时等待数据到达持久存储。\n " - }, - { - "english": "\n LockFileCreateWrite\n Waiting for a write while creating the data directory lock file.\n ", - "chinese": "\n LockFileCreateWrite\n 在创建数据目录锁文件时等待写操作。\n " - }, - { - "english": "\n LockFileRecheckdatadirRead\n Waiting for a read during recheck of the data directory lock file.\n ", - "chinese": "\n LockFileRecheckdatadirRead\n 在重新检查数据目录锁文件期间等待读取。\n " - }, - { - "english": "\n LogicalRewriteCheckpointSync\n Waiting for logical rewrite mappings to reach durable storage during a checkpoint.\n ", - "chinese": "\n LogicalRewriteCheckpointSync\n 等待逻辑重写映射到在检查点到达持久存储。\n " - }, - { - "english": "\n LogicalRewriteMappingSync\n Waiting for mapping data to reach durable storage during a logical rewrite.\n ", - "chinese": "\n LogicalRewriteMappingSync\n 在逻辑重写期间等待映射数据到达持久存储\n " - }, - { - "english": "\n LogicalRewriteMappingWrite\n Waiting for a write of mapping data during a logical rewrite.\n ", - "chinese": "\n LogicalRewriteMappingWrite\n 在逻辑重写期间等待映射数据的写入。\n " - }, - { - "english": "\n LogicalRewriteSync\n Waiting for logical rewrite mappings to reach durable storage.\n ", - "chinese": "\n LogicalRewriteSync\n 等待逻辑重写映射到达持久存储。\n " - }, - { - "english": "\n LogicalRewriteTruncate\n Waiting for truncate of mapping data during a logical rewrite.\n ", - "chinese": "\n LogicalRewriteTruncate\n 等待在逻辑重写期间截断映射数据。\n " - }, - { - "english": "\n LogicalRewriteWrite\n Waiting for a write of logical rewrite mappings.\n ", - "chinese": "\n LogicalRewriteWrite\n 等待逻辑重写映射的写入。\n " - }, - { - "english": "\n RelationMapRead\n Waiting for a read of the relation map file.\n ", - "chinese": "\n RelationMapRead\n 等待关系映射文件的读取。\n " - }, - { - "english": "\n RelationMapWrite\n Waiting for a write to the relation map file.\n ", - "chinese": "\n RelationMapWrite\n 等待对关系映射文件的写入。\n " - }, - { - "english": "\n ReorderBufferRead\n Waiting for a read during reorder buffer management.\n ", - "chinese": "\n ReorderBufferRead\n 在重新排序缓冲区管理期间等待读取。\n " - }, - { - "english": "\n ReorderBufferWrite\n Waiting for a write during reorder buffer management.\n ", - "chinese": "\n ReorderBufferWrite\n 在重新排序缓冲区管理期间等待写操作。\n " - }, - { - "english": "\n ReorderLogicalMappingRead\n Waiting for a read of a logical mapping during reorder buffer management.\n ", - "chinese": "\n ReorderLogicalMappingRead\n 在重新排序缓冲区管理期间等待读取逻辑映射。\n " - }, - { - "english": "\n ReplicationSlotRead\n Waiting for a read from a replication slot control file.\n ", - "chinese": "\n ReplicationSlotRead\n 等待从复制槽控制文件读取。\n " - }, - { - "english": "\n ReplicationSlotRestoreSync\n Waiting for a replication slot control file to reach durable storage while restoring it to memory.\n ", - "chinese": "\n ReplicationSlotRestoreSync\n 等待复制槽控制文件到达持久存储,同时将其恢复到内存中。\n " - }, - { - "english": "\n ReplicationSlotSync\n Waiting for a replication slot control file to reach durable storage.\n ", - "chinese": "\n ReplicationSlotSync\n 等待复制槽控制文件到达持久存储。\n " - }, - { - "english": "\n ReplicationSlotWrite\n Waiting for a write to a replication slot control file.\n ", - "chinese": "\n ReplicationSlotWrite\n 等待对复制槽控制文件的写入。\n " - }, - { - "english": "\n SlruFlushSync\n Waiting for SLRU data to reach durable storage during a checkpoint or database shutdown.\n ", - "chinese": "\n SlruFlushSync\n 在检查点或数据库关闭期间等待SLRU数据到达持久存储。\n " - }, - { - "english": "\n SlruRead\n Waiting for a read of an SLRU page.\n ", - "chinese": "\n SlruRead\n 等待读取SLRU页面。\n " - }, - { - "english": "\n SlruSync\n Waiting for SLRU data to reach durable storage following a page write.\n ", - "chinese": "\n SlruSync\n 在写页面后等待SLRU数据到达持久存储。\n " - }, - { - "english": "\n SlruWrite\n Waiting for a write of an SLRU page.\n ", - "chinese": "\n SlruWrite\n 等待SLRU页面的写入。\n " - }, - { - "english": "\n SnapbuildRead\n Waiting for a read of a serialized historical catalog snapshot.\n ", - "chinese": "\n SnapbuildRead\n 等待读取序列化的历史目录快照。\n " - }, - { - "english": "\n SnapbuildSync\n Waiting for a serialized historical catalog snapshot to reach durable storage.\n ", - "chinese": "\n SnapbuildSync\n 等待序列化历史目录快照到达持久存储。\n " - }, - { - "english": "\n SnapbuildWrite\n Waiting for a write of a serialized historical catalog snapshot.\n ", - "chinese": "\n SnapbuildWrite\n 等待串行历史目录快照的写入。\n " - }, - { - "english": "\n TimelineHistoryFileSync\n Waiting for a timeline history file received via streaming replication to reach durable storage.\n ", - "chinese": "\n TimelineHistoryFileSync\n 等待通过流复制接收的时间线历史文件到达持久存储。\n " - }, - { - "english": "\n TimelineHistoryFileWrite\n Waiting for a write of a timeline history file received via streaming replication.\n ", - "chinese": "\n TimelineHistoryFileWrite\n 等待通过流复制接收的时间线历史文件的写入。\n " - }, - { - "english": "\n TimelineHistoryRead\n Waiting for a read of a timeline history file.\n ", - "chinese": "\n TimelineHistoryRead\n 等待读取时间线历史文件。\n " - }, - { - "english": "\n TimelineHistorySync\n Waiting for a newly created timeline history file to reach durable storage.\n ", - "chinese": "\n TimelineHistorySync\n 等待新创建的时间线历史文件到达持久存储。\n " - }, - { - "english": "\n TimelineHistoryWrite\n Waiting for a write of a newly created timeline history file.\n ", - "chinese": "\n TimelineHistoryWrite\n 等待写入新创建的时间线历史文件。\n " - }, - { - "english": "\n TwophaseFileRead\n Waiting for a read of a two phase state file.\n ", - "chinese": "\n TwophaseFileRead\n 等待读取两阶段状态文件。\n " - }, - { - "english": "\n TwophaseFileSync\n Waiting for a two phase state file to reach durable storage.\n ", - "chinese": "\n TwophaseFileSync\n 等待两阶段状态文件到达持久存储。\n " - }, - { - "english": "\n TwophaseFileWrite\n Waiting for a write of a two phase state file.\n ", - "chinese": "\n TwophaseFileWrite\n 等待对两阶段状态文件的写入。\n " - }, - { - "english": "\n VersionFileSync\n Waiting for the version file to reach durable storage while creating a database.\n ", - "chinese": "\n VersionFileSync\n 等待版本文件达到持久存储,同时创建数据库。\n " - }, - { - "english": "\n VersionFileWrite\n Waiting for the version file to be written while creating a database.\n ", - "chinese": "\n VersionFileWrite\n 在创建数据库时等待版本文件被写入。\n " - }, - { - "english": "\n WalsenderTimelineHistoryRead\n Waiting for a read from a timeline history file during a walsender timeline command.\n ", - "chinese": "\n WalsenderTimelineHistoryRead\n 在walsender时间线命令期间等待从时间线历史文件读取。\n " - }, - { - "english": "\n WalBootstrapSync\n Waiting for WAL to reach durable storage during bootstrapping.\n ", - "chinese": "\n WalBootstrapSync\n 在引导过程中等待WAL达到持久存储。\n " - }, - { - "english": "\n WalBootstrapWrite\n Waiting for a write of a WAL page during bootstrapping.\n ", - "chinese": "\n WalBootstrapWrite\n 在引导过程中等待WAL页面的写入。\n " - }, - { - "english": "\n WalCopyRead\n Waiting for a read when creating a new WAL segment by copying an existing one.\n ", - "chinese": "\n WalCopyRead\n 通过复制一个已有WAL段来创建一个新的WAL段时等待读取。\n " - }, - { - "english": "\n WalCopySync\n Waiting for a new WAL segment created by copying an existing one to reach durable storage.\n ", - "chinese": "\n WalCopySync\n 等待通过复制一个已有WAL段到持久存储来创建一个新的WAL段。\n " - }, - { - "english": "\n WalCopyWrite\n Waiting for a write when creating a new WAL segment by copying an existing one.\n ", - "chinese": "\n WalCopyWrite\n 通过复制一个已有WAL段来创建一个新的WAL段时等待写入。\n " - }, - { - "english": "\n WalInitSync\n Waiting for a newly initialized WAL file to reach durable storage.\n ", - "chinese": "\n WalInitSync\n 等待一个新初始化的WAL文件到持久存储。\n " - }, - { - "english": "\n WalInitWrite\n Waiting for a write while initializing a new WAL file.\n ", - "chinese": "\n WalInitWrite\n 在初始化一个新的WAL文件时等待写入。\n " - }, - { - "english": "\n WalRead\n Waiting for a read from a WAL file.\n ", - "chinese": "\n WalRead\n 等待WAL文件的读取。\n " - }, - { - "english": "\n WalSync\n Waiting for a WAL file to reach durable storage.\n ", - "chinese": "\n WalSync\n 等待WAL文件到达持久存储。\n " - }, - { - "english": "\n WalSyncMethodAssign\n Waiting for data to reach durable storage while assigning a new WAL sync method.\n ", - "chinese": "\n WalSyncMethodAssign\n 等待数据到达持久存储,同时分配一个新的WAL同步方法。\n " - }, - { - "english": "\n WalWrite\n Waiting for a write to a WAL file.\n ", - "chinese": "\n WalWrite\n 等待WAL缓冲区写入磁盘。\n " - }, - { - "english": "\n AppendReady\n Waiting for subplan nodes of an Append plan node to be ready.\n ", - "chinese": "\n AppendReady\n 等待 Append 计划节点的子计划节点准备好。\n " - }, - { - "english": "\n ArchiveCleanupCommand\n Waiting for to complete.\n ", - "chinese": "\n ArchiveCleanupCommand\n 等待完成。\n " - }, - { - "english": "\n ArchiveCommand\n Waiting for to complete.\n ", - "chinese": "\n ArchiveCommand\n 等待完成。\n " - }, - { - "english": "\n BackendTermination\n Waiting for the termination of another backend.\n ", - "chinese": "\n BackendTermination\n 等待另一个后端终止。\n " - }, - { - "english": "\n BackupWaitWalArchive\n Waiting for WAL files required for a backup to be successfully archived.\n ", - "chinese": "\n BackupWaitWalArchive\n 等待备份所需的WAL文件成功归档。\n " - }, - { - "english": "\n BgworkerShutdown\n Waiting for background worker to shut down.\n ", - "chinese": "\n BgworkerShutdown\n 等待后台工作进程关闭。\n " - }, - { - "english": "\n BgworkerStartup\n Waiting for background worker to start up.\n ", - "chinese": "\n BgworkerStartup\n 等待后台工作进程启动。\n " - }, - { - "english": "\n BtreePage\n Waiting for the page number needed to continue a parallel B-tree scan to become available.\n ", - "chinese": "\n BtreePage\n 正等待继续并行B-树扫描所需的页号变得可用。\n " - }, - { - "english": "\n BufferIo\n Waiting for buffer I/O to complete.\n ", - "chinese": "\n BufferIo\n 等待缓冲I/O结束。\n " - }, - { - "english": "\n CheckpointDone\n Waiting for a checkpoint to complete.\n ", - "chinese": "\n CheckpointDone\n 等待检查点完成。\n " - }, - { - "english": "\n CheckpointStart\n Waiting for a checkpoint to start.\n ", - "chinese": "\n CheckpointStart\n 等待检查点开始。\n " - }, - { - "english": "\n ExecuteGather\n Waiting for activity from a child process while executing a Gather plan node.\n ", - "chinese": "\n ExecuteGather\n 在执行Gather 计划节点时,等待子进程的活动。\n " - }, - { - "english": "\n HashBatchAllocate\n Waiting for an elected Parallel Hash participant to allocate a hash table.\n ", - "chinese": "\n HashBatchAllocate\n 等待一个选定的并行哈希参与者分配哈希表。\n " - }, - { - "english": "\n HashBatchElect\n Waiting to elect a Parallel Hash participant to allocate a hash table.\n ", - "chinese": "\n HashBatchElect\n 等待选择一个并行哈希参与者来分配哈希表。\n " - }, - { - "english": "\n HashBatchLoad\n Waiting for other Parallel Hash participants to finish loading a hash table.\n ", - "chinese": "\n HashBatchLoad\n 等待其他并行哈希参与者完成哈希表的加载。\n " - }, - { - "english": "\n HashBuildAllocate\n Waiting for an elected Parallel Hash participant to allocate the initial hash table.\n ", - "chinese": "\n HashBuildAllocate\n 等待一个选定的并行哈希参与者分配初始哈希表。\n " - }, - { - "english": "\n HashBuildElect\n Waiting to elect a Parallel Hash participant to allocate the initial hash table.\n ", - "chinese": "\n HashBuildElect\n 等待选择一个并行哈希参与者来分配初始哈希表。\n " - }, - { - "english": "\n HashBuildHashInner\n Waiting for other Parallel Hash participants to finish hashing the inner relation.\n ", - "chinese": "\n HashBuildHashInner\n 等待其他并行哈希参与者完成内部关系的散列。\n " - }, - { - "english": "\n HashBuildHashOuter\n Waiting for other Parallel Hash participants to finish partitioning the outer relation.\n ", - "chinese": "\n HashBuildHashOuter\n 等待其他Parallel 哈希参与者完成对外部关系的分区。\n " - }, - { - "english": "\n HashGrowBatchesDecide\n Waiting to elect a Parallel Hash participant to decide on future batch growth.\n ", - "chinese": "\n HashGrowBatchesDecide\n 等待选择一个并行哈希参与者来决定未来的批处理增长。\n " - }, - { - "english": "\n HashGrowBatchesElect\n Waiting to elect a Parallel Hash participant to allocate more batches.\n ", - "chinese": "\n HashGrowBatchesElect\n 等待选择一个Parallel 哈希参与者来分配更多批处理。\n " - }, - { - "english": "\n HashGrowBatchesFinish\n Waiting for an elected Parallel Hash participant to decide on future batch growth.\n ", - "chinese": "\n HashGrowBatchesFinish\n 等待当选的平行散列参与者决定未来的批量增长。\n " - }, - { - "english": "\n HashGrowBatchesRepartition\n Waiting for other Parallel Hash participants to finish repartitioning.\n ", - "chinese": "\n HashGrowBatchesRepartition\n 等待一个选定的并行哈希参与者决定未来的批处理增长。\n " - }, - { - "english": "\n HashGrowBucketsElect\n Waiting to elect a Parallel Hash participant to allocate more buckets.\n ", - "chinese": "\n HashGrowBucketsElect\n 等待选择一个并行哈希参与者来分配更多的buckets。\n " - }, - { - "english": "\n HashGrowBucketsReinsert\n Waiting for other Parallel Hash participants to finish inserting tuples into new buckets.\n ", - "chinese": "\n HashGrowBucketsReinsert\n 等待其他Parallel 哈希参与者完成将元组插入到新buckets中。\n " - }, - { - "english": "\n LogicalSyncData\n Waiting for a logical replication remote server to send data for initial table synchronization.\n ", - "chinese": "\n LogicalSyncData\n 等待逻辑复制远程服务器发送用于初始表同步的数据。\n " - }, - { - "english": "\n LogicalSyncStateChange\n Waiting for a logical replication remote server to change state.\n ", - "chinese": "\n LogicalSyncStateChange\n 等待逻辑复制远程服务器更改状态。\n " - }, - { - "english": "\n MessageQueueInternal\n Waiting for another process to be attached to a shared message queue.\n ", - "chinese": "\n MessageQueueInternal\n 等待另一个进程附加到共享消息队列。\n " - }, - { - "english": "\n MessageQueuePutMessage\n Waiting to write a protocol message to a shared message queue.\n ", - "chinese": "\n MessageQueuePutMessage\n 等待将协议消息写入共享消息队列。\n " - }, - { - "english": "\n MessageQueueReceive\n Waiting to receive bytes from a shared message queue.\n ", - "chinese": "\n MessageQueueReceive\n 等待从共享消息队列接收字节。\n " - }, - { - "english": "\n MessageQueueSend\n Waiting to send bytes to a shared message queue.\n ", - "chinese": "\n MessageQueueSend\n 等待将字节发送到共享消息队列。\n " - }, - { - "english": "\n ParallelBitmapScan\n Waiting for parallel bitmap scan to become initialized.\n ", - "chinese": "\n ParallelBitmapScan\n 等待并行位图扫描被初始化。\n " - }, - { - "english": "\n ParallelCreateIndexScan\n Waiting for parallel CREATE INDEX workers to finish heap scan.\n ", - "chinese": "\n ParallelCreateIndexScan\n 等待并行CREATE INDEX 工作进程完成堆扫描。\n " - }, - { - "english": "\n ParallelFinish\n Waiting for parallel workers to finish computing.\n ", - "chinese": "\n ParallelFinish\n 等待并行工作人员完成计算。\n " - }, - { - "english": "\n ProcarrayGroupUpdate\n Waiting for the group leader to clear the transaction ID at transaction end.\n ", - "chinese": "\n ProcarrayGroupUpdate\n 等待组领导在并行操作结束时清除事务ID。\n " - }, - { - "english": "\n ProcSignalBarrier\n Waiting for a barrier event to be processed by all backends.\n ", - "chinese": "\n ProcSignalBarrier\n 等待屏障事件被所有后端处理。\n " - }, - { - "english": "\n Promote\n Waiting for standby promotion.\n ", - "chinese": "\n Promote\n 等待备库提升。\n " - }, - { - "english": "\n RecoveryConflictSnapshot\n Waiting for recovery conflict resolution for a vacuum cleanup.\n ", - "chinese": "\n RecoveryConflictSnapshot\n 等待vacuum清理的恢复冲突解决。\n " - }, - { - "english": "\n RecoveryConflictTablespace\n Waiting for recovery conflict resolution for dropping a tablespace.\n ", - "chinese": "\n RecoveryConflictTablespace\n 等待恢复冲突解决删除表空间。\n " - }, - { - "english": "\n RecoveryEndCommand\n Waiting for to complete.\n ", - "chinese": "\n RecoveryEndCommand\n 等待完成。\n " - }, - { - "english": "\n RecoveryPause\n Waiting for recovery to be resumed.\n ", - "chinese": "\n RecoveryPause\n 等待恢复继续进行。\n " - }, - { - "english": "\n ReplicationOriginDrop\n Waiting for a replication origin to become inactive so it can be dropped.\n ", - "chinese": "\n ReplicationOriginDrop\n 等待复制源变为非活动状态,以便可以删除它。\n " - }, - { - "english": "\n ReplicationSlotDrop\n Waiting for a replication slot to become inactive so it can be dropped.\n ", - "chinese": "\n ReplicationSlotDrop\n 等待复制槽变为非活动状态,以便可以删除它。\n " - }, - { - "english": "\n RestoreCommand\n Waiting for to complete.\n ", - "chinese": "\n RestoreCommand\n 等待完成。\n " - }, - { - "english": "\n SafeSnapshot\n Waiting to obtain a valid snapshot for a READ ONLY DEFERRABLE transaction.\n ", - "chinese": "\n SafeSnapshot\n 等待获取READ ONLY DEFERRABLE事务的有效快照。\n " - }, - { - "english": "\n SyncRep\n Waiting to read or update information about the state of synchronous replication.\n ", - "chinese": "\n SyncRep\n 等待读取或更新有关同步复制状态的信息。\n " - }, - { - "english": "\n WalReceiverExit\n Waiting for the WAL receiver to exit.\n ", - "chinese": "\n WalReceiverExit\n 等待WAL 接收进程退出。\n " - }, - { - "english": "\n WalReceiverWaitStart\n Waiting for startup process to send initial data for streaming replication.\n ", - "chinese": "\n WalReceiverWaitStart\n 等待启动进程为流复制发送初始数据。\n " - }, - { - "english": "\n XactGroupUpdate\n Waiting for the group leader to update transaction status at transaction end.\n ", - "chinese": "\n XactGroupUpdate\n 等待分组组长在并行操作结束时更新事务状态。\n " - }, - { - "english": "\n advisory\n Waiting to acquire an advisory user lock.\n ", - "chinese": "\n advisory\n 等待获得一个建议用户锁。\n " - }, - { - "english": "\n extend\n Waiting to extend a relation.\n ", - "chinese": "\n extend\n 等待扩展一个关系。\n " - }, - { - "english": "\n frozenid\n Waiting to update pg_database.datfrozenxid and pg_database.datminmxid.\n ", - "chinese": "\n frozenid\n 等待升级 pg_database.datfrozenxid\n 和 pg_database.datminmxid.\n " - }, - { - "english": "\n object\n Waiting to acquire a lock on a non-relation database object.\n ", - "chinese": "\n object\n 等待获取非关系数据库对象上的锁。\n " - }, - { - "english": "\n page\n Waiting to acquire a lock on a page of a relation.\n ", - "chinese": "\n page\n 等待获取一个关系页面上的锁。\n " - }, - { - "english": "\n relation\n Waiting to acquire a lock on a relation.\n ", - "chinese": "\n relation\n 等待获得一个关系的锁。\n " - }, - { - "english": "\n spectoken\n Waiting to acquire a speculative insertion lock.\n ", - "chinese": "\n spectoken\n 等待获取推测的插入锁。\n " - }, - { - "english": "\n transactionid\n Waiting for a transaction to finish.\n ", - "chinese": "\n transactionid\n 等待事务完成。\n " - }, - { - "english": "\n tuple\n Waiting to acquire a lock on a tuple.\n ", - "chinese": "\n tuple\n 等待获取元组上的锁。\n " - }, - { - "english": "\n userlock\n Waiting to acquire a user lock.\n ", - "chinese": "\n userlock\n 等待获取用户锁。\n " - }, - { - "english": "\n virtualxid\n Waiting to acquire a virtual transaction ID lock; see .\n ", - "chinese": "\n virtualxid\n 等待获取虚拟事务ID锁。\n " - }, - { - "english": "\n AddinShmemInit\n Waiting to manage an extension's space allocation in shared memory.\n ", - "chinese": "\n AddinShmemInit\n 等待管理共享内存中的扩展空间分配。\n " - }, - { - "english": "\n AutoFile\n Waiting to update the postgresql.auto.conf file.\n ", - "chinese": "\n AutoFile\n 等待更新postgresql.auto.conf文件。\n " - }, - { - "english": "\n Autovacuum\n Waiting to read or update the current state of autovacuum workers.\n ", - "chinese": "\n Autovacuum\n 等待读取或更新自动清理工作进程的当前状态。\n " - }, - { - "english": "\n AutovacuumSchedule\n Waiting to ensure that a table selected for autovacuum still needs vacuuming.\n ", - "chinese": "\n AutovacuumSchedule\n 等待确保选择为自动清理的表仍然需要清理。\n " - }, - { - "english": "\n BackgroundWorker\n Waiting to read or update background worker state.\n ", - "chinese": "\n BackgroundWorker\n 等待读取或更新后台工作进程状态。\n " - }, - { - "english": "\n BtreeVacuum\n Waiting to read or update vacuum-related information for a B-tree index.\n ", - "chinese": "\n BtreeVacuum\n 等待读取或更新B-树索引的清理相关信息。\n " - }, - { - "english": "\n BufferMapping\n Waiting to associate a data block with a buffer in the buffer pool.\n ", - "chinese": "\n BufferMapping\n 等待将数据块与缓冲池中的缓冲区关联。\n " - }, - { - "english": "\n CheckpointerComm\n Waiting to manage fsync requests.\n ", - "chinese": "\n CheckpointerComm\n 等待管理fsync请求。\n " - }, - { - "english": "\n CommitTs\n Waiting to read or update the last value set for a transaction commit timestamp.\n ", - "chinese": "\n CommitTs\n 等待读取或更新事务提交时间戳的最后一个值集。\n " - }, - { - "english": "\n CommitTsBuffer\n Waiting for I/O on a commit timestamp SLRU buffer.\n ", - "chinese": "\n CommitTsBuffer\n 在提交时间戳SLRU缓冲区上等待I/O。\n " - }, - { - "english": "\n CommitTsSLRU\n Waiting to access the commit timestamp SLRU cache.\n ", - "chinese": "\n CommitTsSLRU\n 等待访问提交时间戳SLRU缓存。\n " - }, - { - "english": "\n ControlFile\n Waiting to read or update the pg_control file or create a new WAL file.\n ", - "chinese": "\n ControlFile\n 等待读取或更新pg_control文件或创建一个新的WAL文件。\n " - }, - { - "english": "\n DynamicSharedMemoryControl\n Waiting to read or update dynamic shared memory allocation information.\n ", - "chinese": "\n DynamicSharedMemoryControl\n 等待读取或更新动态共享内存分配信息。\n " - }, - { - "english": "\n LockFastPath\n Waiting to read or update a process' fast-path lock information.\n ", - "chinese": "\n LockFastPath\n 等待读取或更新进程的快速路径锁信息。\n " - }, - { - "english": "\n LockManager\n Waiting to read or update information about heavyweight locks.\n ", - "chinese": "\n LockManager\n 等待读取或更新关于heavyweight锁。\n " - }, - { - "english": "\n LogicalRepWorker\n Waiting to read or update the state of logical replication workers.\n ", - "chinese": "\n LogicalRepWorker\n 等待读取或更新逻辑复制工作器的状态。\n " - }, - { - "english": "\n MultiXactGen\n Waiting to read or update shared multixact state.\n ", - "chinese": "\n MultiXactGen\n 等待读取或更新共享的multixact状态。\n " - }, - { - "english": "\n MultiXactMemberBuffer\n Waiting for I/O on a multixact member SLRU buffer.\n ", - "chinese": "\n MultiXactMemberBuffer\n 在multixact成员SLRU缓冲区上等待I/O。\n " - }, - { - "english": "\n MultiXactMemberSLRU\n Waiting to access the multixact member SLRU cache.\n ", - "chinese": "\n MultiXactMemberSLRU\n 等待访问multixact成员SLRU缓存。\n " - }, - { - "english": "\n MultiXactOffsetBuffer\n Waiting for I/O on a multixact offset SLRU buffer.\n ", - "chinese": "\n MultiXactOffsetBuffer\n 在multixact 偏移 SLRU缓冲区上等待I/O。\n " - }, - { - "english": "\n MultiXactOffsetSLRU\n Waiting to access the multixact offset SLRU cache.\n ", - "chinese": "\n MultiXactOffsetSLRU\n 等待访问multixact 偏移 SLRU缓存。\n " - }, - { - "english": "\n MultiXactTruncation\n Waiting to read or truncate multixact information.\n ", - "chinese": "\n MultiXactTruncation\n 等待读取或截断multixact信息。\n " - }, - { - "english": "\n NotifyBuffer\n Waiting for I/O on a NOTIFY message SLRU buffer.\n ", - "chinese": "\n NotifyBuffer\n NOTIFY 消息 SLRU缓冲区上等待I/O。\n " - }, - { - "english": "\n NotifyQueue\n Waiting to read or update NOTIFY messages.\n ", - "chinese": "\n NotifyQueue\n 等待读取或更新NOTIFY 消息。\n " - }, - { - "english": "\n NotifyQueueTail\n Waiting to update limit on NOTIFY message storage.\n ", - "chinese": "\n NotifyQueueTail\n 等待NOTIFY消息存储上的更新限制。\n " - }, - { - "english": "\n NotifySLRU\n Waiting to access the NOTIFY message SLRU cache.\n ", - "chinese": "\n NotifySLRU\n 等待访问NOTIFY消息SLRU缓存。\n " - }, - { - "english": "\n OidGen\n Waiting to allocate a new OID.\n ", - "chinese": "\n OidGen\n 等待分配一个新的OID。\n " - }, - { - "english": "\n ParallelAppend\n Waiting to choose the next subplan during Parallel Append plan execution.\n ", - "chinese": "\n ParallelAppend\n 在并行附加计划执行期间等待选择下一个子计划。\n " - }, - { - "english": "\n ParallelHashJoin\n Waiting to synchronize workers during Parallel Hash Join plan execution.\n ", - "chinese": "\n ParallelHashJoin\n 在并行哈希连接计划执行期间等待同步工作器。\n " - }, - { - "english": "\n ParallelQueryDSA\n Waiting for parallel query dynamic shared memory allocation.\n ", - "chinese": "\n ParallelQueryDSA\n 等待并行查询动态共享内存分配。\n " - }, - { - "english": "\n PerSessionDSA\n Waiting for parallel query dynamic shared memory allocation.\n ", - "chinese": "\n PerSessionDSA\n 等待并行查询动态共享内存分配。\n " - }, - { - "english": "\n PerSessionRecordType\n Waiting to access a parallel query's information about composite types.\n ", - "chinese": "\n PerSessionRecordType\n 等待访问有关复合类型的并行查询信息。\n " - }, - { - "english": "\n PerSessionRecordTypmod\n Waiting to access a parallel query's information about type modifiers that identify anonymous record types.\n ", - "chinese": "\n PerSessionRecordTypmod\n 等待访问有关标识匿名记录类型的类型修饰符的并行查询信息。\n " - }, - { - "english": "\n PerXactPredicateList\n Waiting to access the list of predicate locks held by the current serializable transaction during a parallel query.\n ", - "chinese": "\n PerXactPredicateList\n 在并行查询期间等待访问当前可串行化事务持有的谓词锁列表。\n " - }, - { - "english": "\n PgStatsData\n Waiting for shared memory stats data access.\n ", - "chinese": "\n PgStatsData\n 等待共享内存统计数据访问\n " - }, - { - "english": "\n PgStatsDSA\n Waiting for stats dynamic shared memory allocator access.\n ", - "chinese": "\n PgStatsDSA\n 等待统计动态共享内存分配器访问\n " - }, - { - "english": "\n PgStatsHash\n Waiting for stats shared memory hash table access.\n ", - "chinese": "\n PgStatsHash\n 等待统计共享内存哈希表访问\n " + "english": "Code Targets", + "chinese": "代码构建目标" }, { - "english": "\n PredicateLockManager\n Waiting to access predicate lock information used by serializable transactions.\n ", - "chinese": "\n PredicateLockManager\n 等待访问可串行化事务使用的谓词锁信息。\n " + "english": "Developer Targets", + "chinese": "开发目标" }, { - "english": "\n ProcArray\n Waiting to access the shared per-process data structures (typically, to get a snapshot or report a session's transaction ID).\n ", - "chinese": "\n ProcArray\n 等待访问每个进程共享的数据结构(通常情况,是获取快照或报告会话的事务ID)。\n " + "english": "Documentation Targets", + "chinese": "文档构建目标" }, { - "english": "\n RelationMapping\n Waiting to read or update a pg_filenode.map file (used to track the filenode assignments of certain system catalogs).\n ", - "chinese": "\n RelationMapping\n 等待读取或更新pg_filenode.map文件(用于跟踪某些系统目录的文件节点分配)。\n " + "english": "Installation Targets", + "chinese": "安装目标" }, { - "english": "\n RelCacheInit\n Waiting to read or update a pg_internal.init relation cache initialization file.\n ", - "chinese": "\n RelCacheInit\n 等待读取或更新pg_internal.init关系缓存初始化文件。\n " + "english": "Other Targets", + "chinese": "其他目标" }, { - "english": "\n ReplicationOrigin\n Waiting to create, drop or use a replication origin.\n ", - "chinese": "\n ReplicationOrigin\n 等待创建、删除或使用复制源。\n " + "english": "Build everything other than documentation", + "chinese": "构建文档以外的所有内容" }, { - "english": "\n ReplicationOriginState\n Waiting to read or update the progress of one replication origin.\n ", - "chinese": "\n ReplicationOriginState\n 等待读取或更新一个复制源的进度。\n " + "english": "Build backend and related modules", + "chinese": "构建后端及相关模块" }, { - "english": "\n ReplicationSlotAllocation\n Waiting to allocate or free a replication slot.\n ", - "chinese": "\n ReplicationSlotAllocation\n 等待分配或释放复制槽。\n " + "english": "Build frontend binaries", + "chinese": "构建前端二进制程序" }, { - "english": "\n ReplicationSlotControl\n Waiting to read or update replication slot state.\n ", - "chinese": "\n ReplicationSlotControl\n 等待读取或更新复制槽状态。\n " + "english": "Build contrib modules", + "chinese": "构建 contrib 模块" }, { - "english": "\n ReplicationSlotIO\n Waiting for I/O on a replication slot.\n ", - "chinese": "\n ReplicationSlotIO\n 在复制槽上等待I/O。\n " + "english": "Build procedural languages", + "chinese": "构建过程语言" }, { - "english": "\n SerialBuffer\n Waiting for I/O on a serializable transaction conflict SLRU buffer.\n ", - "chinese": "\n SerialBuffer\n 在可串行化事务冲突的SLRU缓冲区上等待I/O。\n " + "english": "Rewrite catalog data files into standard format", + "chinese": "将系统目录数据文件改写为标准格式" }, { - "english": "\n SerializableFinishedList\n Waiting to access the list of finished serializable transactions.\n ", - "chinese": "\n SerializableFinishedList\n 等待访问已完成的可串行化事务列表。\n " + "english": "Expand all data files to include defaults", + "chinese": "展开所有数据文件以包含默认值" }, { - "english": "\n SerializablePredicateList\n Waiting to access the list of predicate locks held by serializable transactions.\n ", - "chinese": "\n SerializablePredicateList\n 等待访问可串行化事务持有的谓词锁列表。\n " - }, - { - "english": "\n SerializableXactHash\n Waiting to read or update information about serializable transactions.\n ", - "chinese": "\n SerializableXactHash\n 等待读取或更新关于可串行化事务的信息。\n " - }, - { - "english": "\n SerialSLRU\n Waiting to access the serializable transaction conflict SLRU cache.\n ", - "chinese": "\n SerialSLRU\n 等待访问可串行化事务冲突SLRU缓存。\n " - }, - { - "english": "\n SharedTidBitmap\n Waiting to access a shared TID bitmap during a parallel bitmap index scan.\n ", - "chinese": "\n SharedTidBitmap\n 在并行位图索引扫描期间等待访问共享的TID位图。\n " - }, - { - "english": "\n SharedTupleStore\n Waiting to access a shared tuple store during parallel query.\n ", - "chinese": "\n SharedTupleStore\n 在并行查询期间等待访问共享元组存储。\n " - }, - { - "english": "\n ShmemIndex\n Waiting to find or allocate space in shared memory.\n ", - "chinese": "\n ShmemIndex\n 等待在共享内存中找到或分配空间。\n " - }, - { - "english": "\n SInvalRead\n Waiting to retrieve messages from the shared catalog invalidation queue.\n ", - "chinese": "\n SInvalRead\n 等待从共享目录失效队列中检索消息。\n " - }, - { - "english": "\n SInvalWrite\n Waiting to add a message to the shared catalog invalidation queue.\n ", - "chinese": "\n SInvalWrite\n 等待向共享编目失效队列添加消息。\n " - }, - { - "english": "\n SubtransBuffer\n Waiting for I/O on a sub-transaction SLRU buffer.\n ", - "chinese": "\n SubtransBuffer\n 在子事务SLRU缓冲区上等待I/O。\n " + "english": "Update Unicode data to new version", + "chinese": "将 Unicode 数据更新到新版本" }, { - "english": "\n SubtransSLRU\n Waiting to access the sub-transaction SLRU cache.\n ", - "chinese": "\n SubtransSLRU\n 等待访问子事务SLRU缓存。\n " + "english": "Check that all headers compile standalone", + "chinese": "检查所有头文件能否独立编译" }, { - "english": "\n SyncScan\n Waiting to select the starting location of a synchronized table scan.\n ", - "chinese": "\n SyncScan\n 等待选择同步表扫描的起始位置。\n " + "english": "Check that all headers compile as C++", + "chinese": "检查所有头文件能否作为 C++ 编译" }, { - "english": "\n TablespaceCreate\n Waiting to create or drop a tablespace.\n ", - "chinese": "\n TablespaceCreate\n 等待创建或删除表空间。\n " + "english": "Build documentation in multi-page HTML format", + "chinese": "构建多页 HTML 格式的文档" }, { - "english": "\n TwoPhaseState\n Waiting to read or update the state of prepared transactions.\n ", - "chinese": "\n TwoPhaseState\n 等待读取或更新已准备事务的状态。\n " + "english": "Build documentation in man page format", + "chinese": "构建手册页格式的文档" }, { - "english": "\n WALBufMapping\n Waiting to replace a page in WAL buffers.\n ", - "chinese": "\n WALBufMapping\n 等待在WAL缓冲区中替换一个页面。\n " + "english": "Build documentation in multi-page HTML and man page format", + "chinese": "构建多页 HTML 和手册页格式的文档" }, { - "english": "\n WALInsert\n Waiting to insert WAL data into a memory buffer.\n ", - "chinese": "\n WALInsert\n 等待将WAL数据插入内存缓冲区。\n " + "english": "Build documentation in PDF format, with A4 pages", + "chinese": "构建 A4 页面大小的 PDF 格式文档" }, { - "english": "\n WALWrite\n Waiting for WAL buffers to be written to disk.\n ", - "chinese": "\n WALWrite\n 等待WAL缓冲区写入磁盘。\n " + "english": "Build documentation in PDF format, with US letter pages", + "chinese": "构建 US letter 页面大小的 PDF 格式文档" }, { - "english": "\n WrapLimitsVacuum\n Waiting to update limits on transaction id and multixact consumption.\n ", - "chinese": "\n WrapLimitsVacuum\n 等待更新事务 ID和multixact消费的限制。\n " + "english": "Build documentation in single-page HTML format", + "chinese": "构建单页 HTML 格式的文档" }, { - "english": "\n XactBuffer\n Waiting for I/O on a transaction status SLRU buffer.\n ", - "chinese": "\n XactBuffer\n 在事务状态的SLRU缓冲区上等待I/O。\n " + "english": "Build documentation in all supported formats", + "chinese": "构建所有支持格式的文档" }, { - "english": "\n XactSLRU\n Waiting to access the transaction status SLRU cache.\n ", - "chinese": "\n XactSLRU\n 等待访问事务状态的SLRU缓存。\n " + "english": "Install postgres, excluding documentation", + "chinese": "安装 postgres,不包括文档" }, { - "english": "\n XactTruncation\n Waiting to execute pg_xact_status or update the oldest transaction ID available to it.\n ", - "chinese": "\n XactTruncation\n 等待执行pg_xact_status或更新它可用的最早的事务ID。\n " + "english": "Install documentation in multi-page HTML and man page formats", + "chinese": "安装多页 HTML 和手册页格式的文档" }, { - "english": "\n XidGen\n Waiting to allocate a new transaction ID.\n ", - "chinese": "\n XidGen\n 等待分配新的事务ID。\n " + "english": "Install documentation in multi-page HTML format", + "chinese": "安装多页 HTML 格式的文档" }, { - "english": "\n BaseBackupThrottle\n Waiting during base backup when throttling activity.\n ", - "chinese": "\n BaseBackupThrottle\n 当有限流活动时在基础备份期间等待。\n " + "english": "Install documentation in man page format", + "chinese": "安装手册页格式的文档" }, { - "english": "\n CheckpointWriteDelay\n Waiting between writes while performing a checkpoint.\n ", - "chinese": "\n CheckpointWriteDelay\n 在执行检查点时写入之间的等待时间。\n " + "english": "Like \"install\", but installed files are not displayed", + "chinese": "与“install”相同,但不显示安装的文件" }, { - "english": "\n PgSleep\n Waiting due to a call to pg_sleep or a sibling function.\n ", - "chinese": "\n PgSleep\n 由于调用pg_sleep或同类函数而等待。\n " + "english": "Install postgres, including multi-page HTML and man page documentation", + "chinese": "安装 postgres,包括多页 HTML 和手册页格式的文档" }, { - "english": "\n RecoveryApplyDelay\n Waiting to apply WAL during recovery because of a delay setting.\n ", - "chinese": "\n RecoveryApplyDelay\n 由于延迟设置,在恢复期间等待应用WAL。\n " + "english": "Remove installed files", + "chinese": "删除已安装的文件" }, { - "english": "\n RecoveryRetrieveRetryInterval\n Waiting during recovery when WAL data is not available from any source (pg_wal, archive or stream).\n ", - "chinese": "\n RecoveryRetrieveRetryInterval\n 当WAL数据无法从任何来源(pg_wal、归档或流复制)获得时,在恢复期间等待。\n " + "english": "Remove all build products", + "chinese": "删除所有构建产物" }, { - "english": "\n RegisterSyncRequest\n Waiting while sending synchronization requests to the checkpointer, because the request queue is full.\n ", - "chinese": "\n RegisterSyncRequest\n 在发送同步请求到检查点程序时等待,因为请求队列已满。\n " + "english": "Run all enabled tests (including contrib)", + "chinese": "运行所有已启用的测试(包括 contrib)" }, { - "english": "\n VacuumDelay\n Waiting in a cost-based vacuum delay point.\n ", - "chinese": "\n VacuumDelay\n 在一个基于代价的清理延迟点。\n " + "english": "Build everything, including documentation", + "chinese": "构建所有内容,包括文档" }, { - "english": "\n VacuumTruncate\n Waiting to acquire an exclusive lock to truncate off any empty pages at the end of a table vacuumed.\n ", - "chinese": "\n VacuumTruncate\n 等待获取独占锁以截断被清理的表末尾的空页面。\n " - }, + "english": "List important targets", + "chinese": "列出重要的目标" + } + ] + }, + "wait_event_types.sgml": { + "input_sha256": "aa18f04f3af562ced7fcb585793d95c1d130aa777d2a7c1e1a66a19b1f56b46e", + "output_sha256": "2e4c8c0693d087cfb0ab37a88e6fac4690a6e98a72b2b077142617ed1b144fb8", + "edits": [ { - "english": "\n Wait Events of Type <literal>Activity</literal>\n \n \n \n Activity Wait Event\n Description\n \n \n\n ", - "chinese": "
\n\n <literal>Activity</literal>类型的等待事件\n \n \n\n \n Activity 等待事件\n 描述\n \n \n\n " + "english": "
\n Wait Events of Type <literal>Activity</literal>\n \n \n \n Activity Wait Event\n Description\n \n \n\n \n \n ArchiverMain\n Waiting in main loop of archiver process.\n \n \n AutovacuumMain\n Waiting in main loop of autovacuum launcher process.\n \n \n BgwriterHibernate\n Waiting in background writer process, hibernating.\n \n \n BgwriterMain\n Waiting in main loop of background writer process.\n \n \n CheckpointerMain\n Waiting in main loop of checkpointer process.\n \n \n CheckpointerShutdown\n Waiting for checkpointer process to be terminated.\n \n \n IoWorkerMain\n Waiting in main loop of IO Worker process.\n \n \n LogicalApplyMain\n Waiting in main loop of logical replication apply process.\n \n \n LogicalLauncherMain\n Waiting in main loop of logical replication launcher process.\n \n \n LogicalParallelApplyMain\n Waiting in main loop of logical replication parallel apply process.\n \n \n RecoveryWalStream\n Waiting in main loop of startup process for WAL to arrive, during streaming recovery.\n \n \n ReplicationSlotsyncMain\n Waiting in main loop of slot synchronization.\n \n \n ReplicationSlotsyncShutdown\n Waiting for slot sync worker to shut down.\n \n \n SysloggerMain\n Waiting in main loop of syslogger process.\n \n \n WalReceiverMain\n Waiting in main loop of WAL receiver process.\n \n \n WalSenderMain\n Waiting in main loop of WAL sender process.\n \n \n WalSummarizerWal\n Waiting in WAL summarizer for more WAL to be generated.\n \n \n WalWriterMain\n Waiting in main loop of WAL writer process.\n \n \n \n
", + "chinese": "\n\n <literal>Activity</literal>类型的等待事件\n \n \n\n \n Activity 等待事件\n 描述\n \n \n\n \n \n ArchiverMain\n 在归档进程的主循环中等待。\n \n \n AutovacuumMain\n 在自动清理启动进程的主循环中等待。\n \n \n BgwriterHibernate\n 在后台写入器进程中休眠等待。\n \n \n BgwriterMain\n 在后台写入器主循环中等待。\n \n \n CheckpointerMain\n 在检查点进程的主循环中等待。\n \n \n CheckpointerShutdown\n 等待检查点进程终止。\n \n \n IoWorkerMain\n 在 I/O 工作进程的主循环中等待。\n \n \n LogicalApplyMain\n 在逻辑复制应用进程的主循环中等待。\n \n \n LogicalLauncherMain\n 在逻辑复制启动器进程的主循环中等待。\n \n \n LogicalParallelApplyMain\n 在逻辑复制并行应用进程的主循环中等待。\n \n \n RecoveryWalStream\n 在流恢复期间,在启动进程的主循环中等待 WAL 到达。\n \n \n ReplicationSlotsyncMain\n 在复制槽同步的主循环中等待。\n \n \n ReplicationSlotsyncShutdown\n 等待复制槽同步工作进程关闭。\n \n \n SysloggerMain\n 在 syslogger 进程的主循环中等待。\n \n \n WalReceiverMain\n 在 WAL 接收进程的主循环中等待。\n \n \n WalSenderMain\n 在 WAL 发送进程的主循环中等待。\n \n \n WalSummarizerWal\n 在 WAL 汇总进程中等待生成更多 WAL。\n \n \n WalWriterMain\n 在 WAL 写入进程的主循环中等待。\n \n \n \n
" }, { - "english": "\n Wait Events of Type <literal>Buffer</literal>\n \n \n \n Buffer Wait Event\n Description\n \n \n\n ", - "chinese": "
\n <literal>Buffer</literal> 类型的等待事件\n \n \n \n Buffer 等待事件\n 描述\n \n \n\n " + "english": "
\n Wait Events of Type <literal>Buffer</literal>\n \n \n \n Buffer Wait Event\n Description\n \n \n\n \n \n BufferCleanup\n Waiting to acquire an exclusive pin on a buffer. Buffer pin waits can be protracted if another process holds an open cursor that last read data from the buffer in question.\n \n \n BufferExclusive\n Waiting to acquire an exclusive lock on a buffer.\n \n \n BufferShared\n Waiting to acquire a shared lock on a buffer.\n \n \n BufferShareExclusive\n Waiting to acquire a share exclusive lock on a buffer.\n \n \n \n
", + "chinese": "\n <literal>Buffer</literal> 类型的等待事件\n \n \n \n Buffer 等待事件\n 描述\n \n \n\n \n \n BufferCleanup\n 等待获得缓冲区上的独占钉住。如果另一个进程持有尚未关闭的游标,且该游标最近一次读取的数据来自该缓冲区,缓冲区钉住等待可能会持续较长时间。\n \n \n BufferExclusive\n 等待获取缓冲区上的排他锁。\n \n \n BufferShared\n 等待获取缓冲区上的共享锁。\n \n \n BufferShareExclusive\n 等待获取缓冲区上的共享排他锁。\n \n \n \n
" }, { - "english": "\n Wait Events of Type <literal>Client</literal>\n \n \n \n Client Wait Event\n Description\n \n \n\n ", - "chinese": "
\n\n <literal>Client</literal>类型的等待事件\n \n \n\n \n Client 等待事件\n 描述\n \n \n\n " + "english": "
\n Wait Events of Type <literal>Client</literal>\n \n \n \n Client Wait Event\n Description\n \n \n\n \n \n ClientRead\n Waiting to read data from the client.\n \n \n ClientWrite\n Waiting to write data to the client.\n \n \n GssOpenServer\n Waiting to read data from the client while establishing a GSSAPI session.\n \n \n LibpqwalreceiverConnect\n Waiting in WAL receiver to establish connection to remote server.\n \n \n LibpqwalreceiverReceive\n Waiting in WAL receiver to receive data from remote server.\n \n \n SslOpenServer\n Waiting for SSL while attempting connection.\n \n \n WaitForStandbyConfirmation\n Waiting for WAL to be received and flushed by the physical standby.\n \n \n WalSenderWaitForWal\n Waiting for WAL to be flushed in WAL sender process.\n \n \n WalSenderWriteData\n Waiting for any activity when processing replies from WAL receiver in WAL sender process.\n \n \n \n
", + "chinese": "\n\n <literal>Client</literal>类型的等待事件\n \n \n\n \n Client 等待事件\n 描述\n \n \n\n \n \n ClientRead\n 等待从客户端读取数据。\n \n \n ClientWrite\n 等待写入数据到客户端。\n \n \n GssOpenServer\n 在建立GSSAPI会话时等待从客户端读取数据。\n \n \n LibpqwalreceiverConnect\n 在 WAL 接收进程中等待与远程服务器建立连接。\n \n \n LibpqwalreceiverReceive\n 在 WAL 接收进程中等待从远程服务器接收数据。\n \n \n SslOpenServer\n 在尝试连接时等待SSL。\n \n \n WaitForStandbyConfirmation\n 等待物理备库接收 WAL 并将其刷盘。\n \n \n WalSenderWaitForWal\n 在 WAL 发送进程中等待 WAL 刷盘。\n \n \n WalSenderWriteData\n 在 WAL 发送进程中处理 WAL 接收进程的回复时,等待任何活动。\n \n \n \n
" }, { - "english": "\n Wait Events of Type <literal>Extension</literal>\n \n \n \n Extension Wait Event\n Description\n \n \n\n ", - "chinese": "
\n\n <literal>Extension</literal>类型的等待事件\n \n \n\n \n Extension 等待事件\n 描述\n \n \n\n " + "english": "
\n Wait Events of Type <literal>Extension</literal>\n \n \n \n Extension Wait Event\n Description\n \n \n\n \n \n Extension\n Waiting in an extension.\n \n \n \n
", + "chinese": "\n\n <literal>Extension</literal>类型的等待事件\n \n \n\n \n Extension 等待事件\n 描述\n \n \n\n \n \n Extension\n 在扩展中等待。\n \n \n \n
" }, { - "english": "\n Wait Events of Type <literal>Io</literal>\n \n \n \n IO Wait Event\n Description\n \n \n\n ", - "chinese": "
\n\n <literal>IO</literal>类型的等待事件\n \n \n\n \n IO 等待事件\n 描述\n \n \n\n " + "english": "
\n Wait Events of Type <literal>Io</literal>\n \n \n \n IO Wait Event\n Description\n \n \n\n \n \n AioIoCompletion\n Waiting for another process to complete IO.\n \n \n AioIoUringExecution\n Waiting for IO execution via io_uring.\n \n \n AioIoUringSubmit\n Waiting for IO submission via io_uring.\n \n \n BasebackupRead\n Waiting for base backup to read from a file.\n \n \n BasebackupSync\n Waiting for data written by a base backup to reach durable storage.\n \n \n BasebackupWrite\n Waiting for base backup to write to a file.\n \n \n BuffileRead\n Waiting for a read from a buffered file.\n \n \n BuffileTruncate\n Waiting for a buffered file to be truncated.\n \n \n BuffileWrite\n Waiting for a write to a buffered file.\n \n \n ControlFileRead\n Waiting for a read from the pg_control file.\n \n \n ControlFileSync\n Waiting for the pg_control file to reach durable storage.\n \n \n ControlFileSyncUpdate\n Waiting for an update to the pg_control file to reach durable storage.\n \n \n ControlFileWrite\n Waiting for a write to the pg_control file.\n \n \n ControlFileWriteUpdate\n Waiting for a write to update the pg_control file.\n \n \n CopyFileCopy\n Waiting for a file copy operation.\n \n \n CopyFileRead\n Waiting for a read during a file copy operation.\n \n \n CopyFileWrite\n Waiting for a write during a file copy operation.\n \n \n CopyFromRead\n Waiting to read data from a pipe, a file or a program during COPY FROM.\n \n \n CopyToWrite\n Waiting to write data to a pipe, a file or a program during COPY TO.\n \n \n DataFileExtend\n Waiting for a relation data file to be extended.\n \n \n DataFileFlush\n Waiting for a relation data file to reach durable storage.\n \n \n DataFileImmediateSync\n Waiting for an immediate synchronization of a relation data file to durable storage.\n \n \n DataFilePrefetch\n Waiting for an asynchronous prefetch from a relation data file.\n \n \n DataFileRead\n Waiting for a read from a relation data file.\n \n \n DataFileSync\n Waiting for changes to a relation data file to reach durable storage.\n \n \n DataFileTruncate\n Waiting for a relation data file to be truncated.\n \n \n DataFileWrite\n Waiting for a write to a relation data file.\n \n \n DsmAllocate\n Waiting for a dynamic shared memory segment to be allocated.\n \n \n DsmFillZeroWrite\n Waiting to fill a dynamic shared memory backing file with zeroes.\n \n \n LockFileAddtodatadirRead\n Waiting for a read while adding a line to the data directory lock file.\n \n \n LockFileAddtodatadirSync\n Waiting for data to reach durable storage while adding a line to the data directory lock file.\n \n \n LockFileAddtodatadirWrite\n Waiting for a write while adding a line to the data directory lock file.\n \n \n LockFileCreateRead\n Waiting to read while creating the data directory lock file.\n \n \n LockFileCreateSync\n Waiting for data to reach durable storage while creating the data directory lock file.\n \n \n LockFileCreateWrite\n Waiting for a write while creating the data directory lock file.\n \n \n LockFileRecheckdatadirRead\n Waiting for a read during recheck of the data directory lock file.\n \n \n LogicalRewriteCheckpointSync\n Waiting for logical rewrite mappings to reach durable storage during a checkpoint.\n \n \n LogicalRewriteMappingSync\n Waiting for mapping data to reach durable storage during a logical rewrite.\n \n \n LogicalRewriteMappingWrite\n Waiting for a write of mapping data during a logical rewrite.\n \n \n LogicalRewriteSync\n Waiting for logical rewrite mappings to reach durable storage.\n \n \n LogicalRewriteTruncate\n Waiting for truncate of mapping data during a logical rewrite.\n \n \n LogicalRewriteWrite\n Waiting for a write of logical rewrite mappings.\n \n \n RelationMapRead\n Waiting for a read of the relation map file.\n \n \n RelationMapReplace\n Waiting for durable replacement of a relation map file.\n \n \n RelationMapWrite\n Waiting for a write to the relation map file.\n \n \n ReorderBufferRead\n Waiting for a read during reorder buffer management.\n \n \n ReorderBufferWrite\n Waiting for a write during reorder buffer management.\n \n \n ReorderLogicalMappingRead\n Waiting for a read of a logical mapping during reorder buffer management.\n \n \n ReplicationSlotRead\n Waiting for a read from a replication slot control file.\n \n \n ReplicationSlotRestoreSync\n Waiting for a replication slot control file to reach durable storage while restoring it to memory.\n \n \n ReplicationSlotSync\n Waiting for a replication slot control file to reach durable storage.\n \n \n ReplicationSlotWrite\n Waiting for a write to a replication slot control file.\n \n \n SlruFlushSync\n Waiting for SLRU data to reach durable storage during a checkpoint or database shutdown.\n \n \n SlruRead\n Waiting for a read of an SLRU page.\n \n \n SlruSync\n Waiting for SLRU data to reach durable storage following a page write.\n \n \n SlruWrite\n Waiting for a write of an SLRU page.\n \n \n SnapbuildRead\n Waiting for a read of a serialized historical catalog snapshot.\n \n \n SnapbuildSync\n Waiting for a serialized historical catalog snapshot to reach durable storage.\n \n \n SnapbuildWrite\n Waiting for a write of a serialized historical catalog snapshot.\n \n \n TimelineHistoryFileSync\n Waiting for a timeline history file received via streaming replication to reach durable storage.\n \n \n TimelineHistoryFileWrite\n Waiting for a write of a timeline history file received via streaming replication.\n \n \n TimelineHistoryRead\n Waiting for a read of a timeline history file.\n \n \n TimelineHistorySync\n Waiting for a newly created timeline history file to reach durable storage.\n \n \n TimelineHistoryWrite\n Waiting for a write of a newly created timeline history file.\n \n \n TwophaseFileRead\n Waiting for a read of a two phase state file.\n \n \n TwophaseFileSync\n Waiting for a two phase state file to reach durable storage.\n \n \n TwophaseFileWrite\n Waiting for a write of a two phase state file.\n \n \n VersionFileSync\n Waiting for the version file to reach durable storage while creating a database.\n \n \n VersionFileWrite\n Waiting for the version file to be written while creating a database.\n \n \n WalsenderTimelineHistoryRead\n Waiting for a read from a timeline history file during a walsender timeline command.\n \n \n WalBootstrapSync\n Waiting for WAL to reach durable storage during bootstrapping.\n \n \n WalBootstrapWrite\n Waiting for a write of a WAL page during bootstrapping.\n \n \n WalCopyRead\n Waiting for a read when creating a new WAL segment by copying an existing one.\n \n \n WalCopySync\n Waiting for a new WAL segment created by copying an existing one to reach durable storage.\n \n \n WalCopyWrite\n Waiting for a write when creating a new WAL segment by copying an existing one.\n \n \n WalInitSync\n Waiting for a newly initialized WAL file to reach durable storage.\n \n \n WalInitWrite\n Waiting for a write while initializing a new WAL file.\n \n \n WalRead\n Waiting for a read from a WAL file.\n \n \n WalSummaryRead\n Waiting for a read from a WAL summary file.\n \n \n WalSummaryWrite\n Waiting for a write to a WAL summary file.\n \n \n WalSync\n Waiting for a WAL file to reach durable storage.\n \n \n WalSyncMethodAssign\n Waiting for data to reach durable storage while assigning a new WAL sync method.\n \n \n WalWrite\n Waiting for a write to a WAL file.\n \n \n \n
", + "chinese": "\n\n <literal>Io</literal>类型的等待事件\n \n \n\n \n IO 等待事件\n 描述\n \n \n\n \n \n AioIoCompletion\n 等待另一个进程完成 I/O。\n \n \n AioIoUringExecution\n 等待通过 io_uring 执行 I/O。\n \n \n AioIoUringSubmit\n 等待通过 io_uring 提交 I/O。\n \n \n BasebackupRead\n 等待基础备份从文件中读取。\n \n \n BasebackupSync\n 等待基础备份写入的数据同步到持久存储。\n \n \n BasebackupWrite\n 等待基础备份写入文件。\n \n \n BuffileRead\n 等待从缓冲文件中读取。\n \n \n BuffileTruncate\n 等待一个缓冲文件被截断。\n \n \n BuffileWrite\n 等待对缓冲文件的写入。\n \n \n ControlFileRead\n 等待读取pg_control文件。\n \n \n ControlFileSync\n 等待 pg_control 文件同步到持久存储。\n \n \n ControlFileSyncUpdate\n 等待对 pg_control 文件的更新同步到持久存储。\n \n \n ControlFileWrite\n 等待写入pg_control文件。\n \n \n ControlFileWriteUpdate\n 等待写入以更新 pg_control 文件。\n \n \n CopyFileCopy\n 等待文件复制操作。\n \n \n CopyFileRead\n 在文件复制操作期间等待读取。\n \n \n CopyFileWrite\n 在文件复制操作期间等待写入。\n \n \n CopyFromRead\n 在 COPY FROM 期间等待从管道、文件或程序读取数据。\n \n \n CopyToWrite\n 在 COPY TO 期间等待向管道、文件或程序写入数据。\n \n \n DataFileExtend\n 等待关系数据文件被扩展。\n \n \n DataFileFlush\n 等待关系数据文件同步到持久存储。\n \n \n DataFileImmediateSync\n 等待关系数据文件立即同步到持久存储。\n \n \n DataFilePrefetch\n 等待关系数据文件的异步预取。\n \n \n DataFileRead\n 等待对关系数据文件的读取。\n \n \n DataFileSync\n 等待对关系数据文件的更改同步到持久存储。\n \n \n DataFileTruncate\n 等待关系数据文件被截断。\n \n \n DataFileWrite\n 等待对关系数据文件的写入。\n \n \n DsmAllocate\n 等待分配动态共享内存段。\n \n \n DsmFillZeroWrite\n 等待用零填充动态共享内存的后备文件。\n \n \n LockFileAddtodatadirRead\n 在向数据目录锁文件中添加一行时等待读取。\n \n \n LockFileAddtodatadirSync\n 在向数据目录锁文件中添加一行时,等待数据同步到持久存储。\n \n \n LockFileAddtodatadirWrite\n 在向数据目录锁文件中添加一行时等待写操作。\n \n \n LockFileCreateRead\n 创建数据目录锁文件时等待读取。\n \n \n LockFileCreateSync\n 在创建数据目录锁文件时,等待数据同步到持久存储。\n \n \n LockFileCreateWrite\n 在创建数据目录锁文件时等待写操作。\n \n \n LockFileRecheckdatadirRead\n 在重新检查数据目录锁文件期间等待读取。\n \n \n LogicalRewriteCheckpointSync\n 在检查点期间等待逻辑重写映射同步到持久存储。\n \n \n LogicalRewriteMappingSync\n 在逻辑重写期间等待映射数据同步到持久存储。\n \n \n LogicalRewriteMappingWrite\n 在逻辑重写期间等待映射数据的写入。\n \n \n LogicalRewriteSync\n 等待逻辑重写映射同步到持久存储。\n \n \n LogicalRewriteTruncate\n 在逻辑重写期间等待截断映射数据。\n \n \n LogicalRewriteWrite\n 等待逻辑重写映射的写入。\n \n \n RelationMapRead\n 等待关系映射文件的读取。\n \n \n RelationMapReplace\n 等待关系映射文件的替换结果同步到持久存储。\n \n \n RelationMapWrite\n 等待对关系映射文件的写入。\n \n \n ReorderBufferRead\n 在重排序缓冲区管理期间等待读取。\n \n \n ReorderBufferWrite\n 在重排序缓冲区管理期间等待写入。\n \n \n ReorderLogicalMappingRead\n 在重排序缓冲区管理期间等待读取逻辑映射。\n \n \n ReplicationSlotRead\n 等待从复制槽控制文件读取。\n \n \n ReplicationSlotRestoreSync\n 在将复制槽控制文件恢复到内存期间,等待该文件同步到持久存储。\n \n \n ReplicationSlotSync\n 等待复制槽控制文件同步到持久存储。\n \n \n ReplicationSlotWrite\n 等待对复制槽控制文件的写入。\n \n \n SlruFlushSync\n 在检查点或数据库关闭期间,等待 SLRU 数据同步到持久存储。\n \n \n SlruRead\n 等待读取SLRU页面。\n \n \n SlruSync\n 在页面写入后等待 SLRU 数据同步到持久存储。\n \n \n SlruWrite\n 等待SLRU页面的写入。\n \n \n SnapbuildRead\n 等待读取序列化的历史系统目录快照。\n \n \n SnapbuildSync\n 等待序列化的历史系统目录快照同步到持久存储。\n \n \n SnapbuildWrite\n 等待写入序列化的历史系统目录快照。\n \n \n TimelineHistoryFileSync\n 等待通过流复制接收的时间线历史文件同步到持久存储。\n \n \n TimelineHistoryFileWrite\n 等待通过流复制接收的时间线历史文件的写入。\n \n \n TimelineHistoryRead\n 等待读取时间线历史文件。\n \n \n TimelineHistorySync\n 等待新创建的时间线历史文件同步到持久存储。\n \n \n TimelineHistoryWrite\n 等待写入新创建的时间线历史文件。\n \n \n TwophaseFileRead\n 等待读取两阶段状态文件。\n \n \n TwophaseFileSync\n 等待两阶段状态文件同步到持久存储。\n \n \n TwophaseFileWrite\n 等待对两阶段状态文件的写入。\n \n \n VersionFileSync\n 在创建数据库时,等待版本文件同步到持久存储。\n \n \n VersionFileWrite\n 在创建数据库时等待版本文件被写入。\n \n \n WalsenderTimelineHistoryRead\n 在 WAL 发送进程执行时间线命令期间,等待从时间线历史文件读取。\n \n \n WalBootstrapSync\n 在引导过程中等待 WAL 同步到持久存储。\n \n \n WalBootstrapWrite\n 在引导过程中等待WAL页面的写入。\n \n \n WalCopyRead\n 通过复制一个已有WAL段来创建一个新的WAL段时等待读取。\n \n \n WalCopySync\n 等待通过复制现有 WAL 段创建的新 WAL 段同步到持久存储。\n \n \n WalCopyWrite\n 通过复制一个已有WAL段来创建一个新的WAL段时等待写入。\n \n \n WalInitSync\n 等待新初始化的 WAL 文件同步到持久存储。\n \n \n WalInitWrite\n 在初始化一个新的WAL文件时等待写入。\n \n \n WalRead\n 等待WAL文件的读取。\n \n \n WalSummaryRead\n 等待从 WAL 汇总文件读取。\n \n \n WalSummaryWrite\n 等待写入 WAL 汇总文件。\n \n \n WalSync\n 等待 WAL 文件同步到持久存储。\n \n \n WalSyncMethodAssign\n 在设置新的 WAL 同步方法时,等待数据同步到持久存储。\n \n \n WalWrite\n 等待写入 WAL 文件。\n \n \n \n
" }, { - "english": "\n Wait Events of Type <literal>Ipc</literal>\n \n \n \n IPC Wait Event\n Description\n \n \n\n ", - "chinese": "
\n\n <literal>IPC</literal>类型的等待事件\n \n \n\n \n IPC 等待事件\n 描述\n \n \n\n " + "english": "
\n Wait Events of Type <literal>Ipc</literal>\n \n \n \n IPC Wait Event\n Description\n \n \n\n \n \n AppendReady\n Waiting for subplan nodes of an Append plan node to be ready.\n \n \n ArchiveCleanupCommand\n Waiting for to complete.\n \n \n ArchiveCommand\n Waiting for to complete.\n \n \n BackendTermination\n Waiting for the termination of another backend.\n \n \n BackupWaitWalArchive\n Waiting for WAL files required for a backup to be successfully archived.\n \n \n BgworkerShutdown\n Waiting for background worker to shut down.\n \n \n BgworkerStartup\n Waiting for background worker to start up.\n \n \n BtreePage\n Waiting for the page number needed to continue a parallel B-tree scan to become available.\n \n \n BufferIo\n Waiting for buffer I/O to complete.\n \n \n CheckpointDelayComplete\n Waiting for a backend that blocks a checkpoint from completing.\n \n \n CheckpointDelayStart\n Waiting for a backend that blocks a checkpoint from starting.\n \n \n CheckpointDone\n Waiting for a checkpoint to complete.\n \n \n CheckpointStart\n Waiting for a checkpoint to start.\n \n \n ChecksumEnableStartcondition\n Waiting for data checksums enabling to start.\n \n \n ChecksumEnableTemptableWait\n Waiting for temporary tables to be dropped for data checksums to be enabled.\n \n \n ExecuteGather\n Waiting for activity from a child process while executing a Gather plan node.\n \n \n HashBatchAllocate\n Waiting for an elected Parallel Hash participant to allocate a hash table.\n \n \n HashBatchElect\n Waiting to elect a Parallel Hash participant to allocate a hash table.\n \n \n HashBatchLoad\n Waiting for other Parallel Hash participants to finish loading a hash table.\n \n \n HashBuildAllocate\n Waiting for an elected Parallel Hash participant to allocate the initial hash table.\n \n \n HashBuildElect\n Waiting to elect a Parallel Hash participant to allocate the initial hash table.\n \n \n HashBuildHashInner\n Waiting for other Parallel Hash participants to finish hashing the inner relation.\n \n \n HashBuildHashOuter\n Waiting for other Parallel Hash participants to finish partitioning the outer relation.\n \n \n HashGrowBatchesDecide\n Waiting to elect a Parallel Hash participant to decide on future batch growth.\n \n \n HashGrowBatchesElect\n Waiting to elect a Parallel Hash participant to allocate more batches.\n \n \n HashGrowBatchesFinish\n Waiting for an elected Parallel Hash participant to decide on future batch growth.\n \n \n HashGrowBatchesReallocate\n Waiting for an elected Parallel Hash participant to allocate more batches.\n \n \n HashGrowBatchesRepartition\n Waiting for other Parallel Hash participants to finish repartitioning.\n \n \n HashGrowBucketsElect\n Waiting to elect a Parallel Hash participant to allocate more buckets.\n \n \n HashGrowBucketsReallocate\n Waiting for an elected Parallel Hash participant to finish allocating more buckets.\n \n \n HashGrowBucketsReinsert\n Waiting for other Parallel Hash participants to finish inserting tuples into new buckets.\n \n \n LogicalApplySendData\n Waiting for a logical replication leader apply process to send data to a parallel apply process.\n \n \n LogicalParallelApplyStateChange\n Waiting for a logical replication parallel apply process to change state.\n \n \n LogicalSyncData\n Waiting for a logical replication remote server to send data for initial table synchronization.\n \n \n LogicalSyncStateChange\n Waiting for a logical replication remote server to change state.\n \n \n MessageQueueInternal\n Waiting for another process to be attached to a shared message queue.\n \n \n MessageQueuePutMessage\n Waiting to write a protocol message to a shared message queue.\n \n \n MessageQueueReceive\n Waiting to receive bytes from a shared message queue.\n \n \n MessageQueueSend\n Waiting to send bytes to a shared message queue.\n \n \n MultixactCreation\n Waiting for a multixact creation to complete.\n \n \n ParallelBitmapScan\n Waiting for parallel bitmap scan to become initialized.\n \n \n ParallelCreateIndexScan\n Waiting for parallel CREATE INDEX workers to finish heap scan.\n \n \n ParallelFinish\n Waiting for parallel workers to finish computing.\n \n \n ProcarrayGroupUpdate\n Waiting for the group leader to clear the transaction ID at transaction end.\n \n \n ProcSignalBarrier\n Waiting for a barrier event to be processed by all backends.\n \n \n Promote\n Waiting for standby promotion.\n \n \n RecoveryConflictSnapshot\n Waiting for recovery conflict resolution for a vacuum cleanup.\n \n \n RecoveryConflictTablespace\n Waiting for recovery conflict resolution for dropping a tablespace.\n \n \n RecoveryEndCommand\n Waiting for to complete.\n \n \n RecoveryPause\n Waiting for recovery to be resumed.\n \n \n RepackWorkerExport\n Waiting for decoding worker to export a new output file.\n \n \n ReplicationOriginDrop\n Waiting for a replication origin to become inactive so it can be dropped.\n \n \n ReplicationSlotDrop\n Waiting for a replication slot to become inactive so it can be dropped.\n \n \n RestoreCommand\n Waiting for to complete.\n \n \n SafeSnapshot\n Waiting to obtain a valid snapshot for a READ ONLY DEFERRABLE transaction.\n \n \n SyncRep\n Waiting for confirmation from a remote server during synchronous replication.\n \n \n WaitForWalFlush\n Waiting for WAL flush to reach a target LSN on a primary or standby.\n \n \n WaitForWalReplay\n Waiting for WAL replay to reach a target LSN on a standby.\n \n \n WaitForWalWrite\n Waiting for WAL write to reach a target LSN on a standby.\n \n \n WalReceiverExit\n Waiting for the WAL receiver to exit.\n \n \n WalReceiverUpstreamCatchup\n Waiting for upstream server WAL flush position to catch up to requested start point.\n \n \n WalReceiverWaitStart\n Waiting for startup process to send initial data for streaming replication.\n \n \n WalSummaryReady\n Waiting for a new WAL summary to be generated.\n \n \n XactGroupUpdate\n Waiting for the group leader to update transaction status at transaction end.\n \n \n \n
", + "chinese": "\n\n <literal>Ipc</literal>类型的等待事件\n \n \n\n \n IPC 等待事件\n 描述\n \n \n\n \n \n AppendReady\n 等待 Append 计划节点的子计划节点准备好。\n \n \n ArchiveCleanupCommand\n 等待完成。\n \n \n ArchiveCommand\n 等待完成。\n \n \n BackendTermination\n 等待另一个后端终止。\n \n \n BackupWaitWalArchive\n 等待备份所需的WAL文件成功归档。\n \n \n BgworkerShutdown\n 等待后台工作进程关闭。\n \n \n BgworkerStartup\n 等待后台工作进程启动。\n \n \n BtreePage\n 等待继续并行 B-树扫描所需的页号变得可用。\n \n \n BufferIo\n 等待缓冲区 I/O 完成。\n \n \n CheckpointDelayComplete\n 等待阻碍检查点完成的后端。\n \n \n CheckpointDelayStart\n 等待阻碍检查点开始的后端。\n \n \n CheckpointDone\n 等待检查点完成。\n \n \n CheckpointStart\n 等待检查点开始。\n \n \n ChecksumEnableStartcondition\n 等待开始启用数据校验和。\n \n \n ChecksumEnableTemptableWait\n 等待临时表被删除,以便启用数据校验和。\n \n \n ExecuteGather\n 在执行 Gather 计划节点时,等待子进程的活动。\n \n \n HashBatchAllocate\n 等待选出的 Parallel Hash 参与者分配哈希表。\n \n \n HashBatchElect\n 等待选出负责分配哈希表的 Parallel Hash 参与者。\n \n \n HashBatchLoad\n 等待其他 Parallel Hash 参与者完成哈希表的加载。\n \n \n HashBuildAllocate\n 等待选出的 Parallel Hash 参与者分配初始哈希表。\n \n \n HashBuildElect\n 等待选出负责分配初始哈希表的 Parallel Hash 参与者。\n \n \n HashBuildHashInner\n 等待其他 Parallel Hash 参与者完成对内层关系的哈希处理。\n \n \n HashBuildHashOuter\n 等待其他 Parallel Hash 参与者完成对外层关系的分区。\n \n \n HashGrowBatchesDecide\n 等待选出负责决定后续批次增长的 Parallel Hash 参与者。\n \n \n HashGrowBatchesElect\n 等待选出负责分配更多批次的 Parallel Hash 参与者。\n \n \n HashGrowBatchesFinish\n 等待选出的 Parallel Hash 参与者决定后续的批次增长。\n \n \n HashGrowBatchesReallocate\n 等待选出的 Parallel Hash 参与者分配更多批次。\n \n \n HashGrowBatchesRepartition\n 等待其他 Parallel Hash 参与者完成重新分区。\n \n \n HashGrowBucketsElect\n 等待选出负责分配更多桶的 Parallel Hash 参与者。\n \n \n HashGrowBucketsReallocate\n 等待选出的 Parallel Hash 参与者完成更多桶的分配。\n \n \n HashGrowBucketsReinsert\n 等待其他 Parallel Hash 参与者完成向新桶插入元组。\n \n \n LogicalApplySendData\n 等待逻辑复制领导者应用进程向并行应用进程发送数据。\n \n \n LogicalParallelApplyStateChange\n 等待逻辑复制并行应用进程改变状态。\n \n \n LogicalSyncData\n 等待逻辑复制远程服务器发送用于初始表同步的数据。\n \n \n LogicalSyncStateChange\n 等待逻辑复制远程服务器更改状态。\n \n \n MessageQueueInternal\n 等待另一个进程附加到共享消息队列。\n \n \n MessageQueuePutMessage\n 等待将协议消息写入共享消息队列。\n \n \n MessageQueueReceive\n 等待从共享消息队列接收字节。\n \n \n MessageQueueSend\n 等待将字节发送到共享消息队列。\n \n \n MultixactCreation\n 等待多事务创建完成。\n \n \n ParallelBitmapScan\n 等待并行位图扫描完成初始化。\n \n \n ParallelCreateIndexScan\n 等待并行 CREATE INDEX 工作进程完成堆扫描。\n \n \n ParallelFinish\n 等待并行工作进程完成计算。\n \n \n ProcarrayGroupUpdate\n 等待组领导者在事务结束时清除事务 ID。\n \n \n ProcSignalBarrier\n 等待屏障事件被所有后端处理。\n \n \n Promote\n 等待备库提升。\n \n \n RecoveryConflictSnapshot\n 等待解决清理操作引发的恢复冲突。\n \n \n RecoveryConflictTablespace\n 等待解决删除表空间引发的恢复冲突。\n \n \n RecoveryEndCommand\n 等待完成。\n \n \n RecoveryPause\n 等待恢复继续进行。\n \n \n RepackWorkerExport\n 等待解码工作进程导出新的输出文件。\n \n \n ReplicationOriginDrop\n 等待复制源变为非活动状态,以便可以删除它。\n \n \n ReplicationSlotDrop\n 等待复制槽变为非活动状态,以便可以删除它。\n \n \n RestoreCommand\n 等待完成。\n \n \n SafeSnapshot\n 等待获取READ ONLY DEFERRABLE事务的有效快照。\n \n \n SyncRep\n 在同步复制期间等待来自远程服务器的确认。\n \n \n WaitForWalFlush\n 等待主库或备库上的 WAL 刷盘达到目标 LSN。\n \n \n WaitForWalReplay\n 等待备库上的 WAL 重放达到目标 LSN。\n \n \n WaitForWalWrite\n 等待备库上的 WAL 写入达到目标 LSN。\n \n \n WalReceiverExit\n 等待WAL 接收进程退出。\n \n \n WalReceiverUpstreamCatchup\n 等待上游服务器的 WAL 刷盘位置追上请求的起始点。\n \n \n WalReceiverWaitStart\n 等待启动进程为流复制发送初始数据。\n \n \n WalSummaryReady\n 等待生成新的 WAL 汇总。\n \n \n XactGroupUpdate\n 等待组领导者在事务结束时更新事务状态。\n \n \n \n
" }, { - "english": "\n Wait Events of Type <literal>Lock</literal>\n \n \n \n Lock Wait Event\n Description\n \n \n\n ", - "chinese": "
\n\n <literal>Lock</literal>类型的等待事件\n \n \n\n \n Lock 等待事件\n 描述\n \n \n\n " + "english": "
\n Wait Events of Type <literal>Lock</literal>\n \n \n \n Lock Wait Event\n Description\n \n \n\n \n \n advisory\n Waiting to acquire an advisory user lock.\n \n \n applytransaction\n Waiting to acquire a lock on a remote transaction being applied by a logical replication subscriber.\n \n \n extend\n Waiting to extend a relation.\n \n \n frozenid\n Waiting to update pg_database.datfrozenxid and pg_database.datminmxid.\n \n \n object\n Waiting to acquire a lock on a non-relation database object.\n \n \n page\n Waiting to acquire a lock on a page of a relation.\n \n \n relation\n Waiting to acquire a lock on a relation.\n \n \n spectoken\n Waiting to acquire a speculative insertion lock.\n \n \n transactionid\n Waiting for a transaction to finish.\n \n \n tuple\n Waiting to acquire a lock on a tuple.\n \n \n userlock\n Waiting to acquire a user lock.\n \n \n virtualxid\n Waiting to acquire a virtual transaction ID lock; see .\n \n \n \n
", + "chinese": "\n\n <literal>Lock</literal>类型的等待事件\n \n \n\n \n Lock 等待事件\n 描述\n \n \n\n \n \n advisory\n 等待获取用户咨询锁。\n \n \n applytransaction\n 等待获取逻辑复制订阅者正在应用的远程事务上的锁。\n \n \n extend\n 等待扩展一个关系。\n \n \n frozenid\n 等待更新 pg_database.datfrozenxidpg_database.datminmxid\n \n \n object\n 等待获取非关系数据库对象上的锁。\n \n \n page\n 等待获取一个关系页面上的锁。\n \n \n relation\n 等待获取关系上的锁。\n \n \n spectoken\n 等待获取推测插入锁。\n \n \n transactionid\n 等待事务完成。\n \n \n tuple\n 等待获取元组上的锁。\n \n \n userlock\n 等待获取用户锁。\n \n \n virtualxid\n 等待获取虚拟事务 ID 锁;参见 \n \n \n \n
" }, { - "english": "\n Wait Events of Type <literal>Lwlock</literal>\n \n \n \n LWLock Wait Event\n Description\n \n \n\n ", - "chinese": "
\n\n <literal>LWLock</literal>类型的等待事件\n \n \n\n \n LWLock 等待事件\n 描述\n \n \n\n " + "english": "
\n Wait Events of Type <literal>Lwlock</literal>\n \n \n \n LWLock Wait Event\n Description\n \n \n\n \n \n AddinShmemInit\n Waiting to manage an extension's space allocation in shared memory.\n \n \n AioUringCompletion\n Waiting for another process to complete IO via io_uring.\n \n \n AioWorkerControl\n Waiting to update AIO worker information.\n \n \n AioWorkerSubmissionQueue\n Waiting to access AIO worker submission queue.\n \n \n AutoFile\n Waiting to update the postgresql.auto.conf file.\n \n \n Autovacuum\n Waiting to read or update the current state of autovacuum workers.\n \n \n AutovacuumSchedule\n Waiting to ensure that a table selected for autovacuum still needs vacuuming.\n \n \n BackgroundWorker\n Waiting to read or update background worker state.\n \n \n BtreeVacuum\n Waiting to read or update vacuum-related information for a B-tree index.\n \n \n BufferMapping\n Waiting to associate a data block with a buffer in the buffer pool.\n \n \n CheckpointerComm\n Waiting to manage fsync requests.\n \n \n CommitTs\n Waiting to read or update the last value set for a transaction commit timestamp.\n \n \n CommitTsBuffer\n Waiting for I/O on a commit timestamp SLRU buffer.\n \n \n CommitTsSLRU\n Waiting to access the commit timestamp SLRU cache.\n \n \n ControlFile\n Waiting to read or update the pg_control file or create a new WAL file.\n \n \n DataChecksumsWorker\n Waiting for data checksums worker.\n \n \n DSMRegistry\n Waiting to read or update the dynamic shared memory registry.\n \n \n DSMRegistryDSA\n Waiting to access dynamic shared memory registry's dynamic shared memory allocator.\n \n \n DSMRegistryHash\n Waiting to access dynamic shared memory registry's shared hash table.\n \n \n DynamicSharedMemoryControl\n Waiting to read or update dynamic shared memory allocation information.\n \n \n InjectionPoint\n Waiting to read or update information related to injection points.\n \n \n LockFastPath\n Waiting to read or update a process' fast-path lock information.\n \n \n LockManager\n Waiting to read or update information about heavyweight locks.\n \n \n LogicalDecodingControl\n Waiting to read or update logical decoding status information.\n \n \n LogicalRepLauncherDSA\n Waiting to access logical replication launcher's dynamic shared memory allocator.\n \n \n LogicalRepLauncherHash\n Waiting to access logical replication launcher's shared hash table.\n \n \n LogicalRepWorker\n Waiting to read or update the state of logical replication workers.\n \n \n MultiXactGen\n Waiting to read or update shared multixact state.\n \n \n MultiXactMemberBuffer\n Waiting for I/O on a multixact member SLRU buffer.\n \n \n MultiXactMemberSLRU\n Waiting to access the multixact member SLRU cache.\n \n \n MultiXactOffsetBuffer\n Waiting for I/O on a multixact offset SLRU buffer.\n \n \n MultiXactOffsetSLRU\n Waiting to access the multixact offset SLRU cache.\n \n \n MultiXactTruncation\n Waiting to read or truncate multixact information.\n \n \n NotifyBuffer\n Waiting for I/O on a NOTIFY message SLRU buffer.\n \n \n NotifyChannelHash\n Waiting to access the NOTIFY channel hash table.\n \n \n NotifyQueue\n Waiting to read or update NOTIFY messages.\n \n \n NotifyQueueTail\n Waiting to update limit on NOTIFY message storage.\n \n \n NotifySLRU\n Waiting to access the NOTIFY message SLRU cache.\n \n \n OidGen\n Waiting to allocate a new OID.\n \n \n ParallelAppend\n Waiting to choose the next subplan during Parallel Append plan execution.\n \n \n ParallelBtreeScan\n Waiting to synchronize workers during Parallel B-tree scan plan execution.\n \n \n ParallelHashJoin\n Waiting to synchronize workers during Parallel Hash Join plan execution.\n \n \n ParallelQueryDSA\n Waiting for parallel query dynamic shared memory allocation.\n \n \n ParallelVacuumDSA\n Waiting for parallel vacuum dynamic shared memory allocation.\n \n \n PerSessionDSA\n Waiting for parallel query dynamic shared memory allocation.\n \n \n PerSessionRecordType\n Waiting to access a parallel query's information about composite types.\n \n \n PerSessionRecordTypmod\n Waiting to access a parallel query's information about type modifiers that identify anonymous record types.\n \n \n PerXactPredicateList\n Waiting to access the list of predicate locks held by the current serializable transaction during a parallel query.\n \n \n PgStatsData\n Waiting for shared memory stats data access.\n \n \n PgStatsDSA\n Waiting for stats dynamic shared memory allocator access.\n \n \n PgStatsHash\n Waiting for stats shared memory hash table access.\n \n \n PredicateLockManager\n Waiting to access predicate lock information used by serializable transactions.\n \n \n ProcArray\n Waiting to access the shared per-process data structures (typically, to get a snapshot or report a session's transaction ID).\n \n \n RelationMapping\n Waiting to read or update a pg_filenode.map file (used to track the filenode assignments of certain system catalogs).\n \n \n RelCacheInit\n Waiting to read or update a pg_internal.init relation cache initialization file.\n \n \n ReplicationOrigin\n Waiting to create, drop or use a replication origin.\n \n \n ReplicationOriginState\n Waiting to read or update the progress of one replication origin.\n \n \n ReplicationSlotAllocation\n Waiting to allocate or free a replication slot.\n \n \n ReplicationSlotControl\n Waiting to read or update replication slot state.\n \n \n ReplicationSlotIO\n Waiting for I/O on a replication slot.\n \n \n SerialBuffer\n Waiting for I/O on a serializable transaction conflict SLRU buffer.\n \n \n SerialControl\n Waiting to read or update shared pg_serial state.\n \n \n SerializableFinishedList\n Waiting to access the list of finished serializable transactions.\n \n \n SerializablePredicateList\n Waiting to access the list of predicate locks held by serializable transactions.\n \n \n SerializableXactHash\n Waiting to read or update information about serializable transactions.\n \n \n SerialSLRU\n Waiting to access the serializable transaction conflict SLRU cache.\n \n \n SharedTidBitmap\n Waiting to access a shared TID bitmap during a parallel bitmap index scan.\n \n \n SharedTupleStore\n Waiting to access a shared tuple store during parallel query.\n \n \n ShmemIndex\n Waiting to find or allocate space in shared memory.\n \n \n SInvalRead\n Waiting to retrieve messages from the shared catalog invalidation queue.\n \n \n SInvalWrite\n Waiting to add a message to the shared catalog invalidation queue.\n \n \n SubtransBuffer\n Waiting for I/O on a sub-transaction SLRU buffer.\n \n \n SubtransSLRU\n Waiting to access the sub-transaction SLRU cache.\n \n \n SyncRep\n Waiting to read or update information about the state of synchronous replication.\n \n \n SyncScan\n Waiting to select the starting location of a synchronized table scan.\n \n \n TablespaceCreate\n Waiting to create or drop a tablespace.\n \n \n TwoPhaseState\n Waiting to read or update the state of prepared transactions.\n \n \n WaitEventCustom\n Waiting to read or update custom wait events information.\n \n \n WaitLSN\n Waiting to read or update shared Wait-for-LSN state.\n \n \n WALBufMapping\n Waiting to replace a page in WAL buffers.\n \n \n WALInsert\n Waiting to insert WAL data into a memory buffer.\n \n \n WALSummarizer\n Waiting to read or update WAL summarization state.\n \n \n WALWrite\n Waiting for WAL buffers to be written to disk.\n \n \n WrapLimitsVacuum\n Waiting to update limits on transaction id and multixact consumption.\n \n \n XactBuffer\n Waiting for I/O on a transaction status SLRU buffer.\n \n \n XactSLRU\n Waiting to access the transaction status SLRU cache.\n \n \n XactTruncation\n Waiting to execute pg_xact_status or update the oldest transaction ID available to it.\n \n \n XidGen\n Waiting to allocate a new transaction ID.\n \n \n \n
", + "chinese": "\n\n <literal>Lwlock</literal>类型的等待事件\n \n \n\n \n LWLock 等待事件\n 描述\n \n \n\n \n \n AddinShmemInit\n 等待管理扩展在共享内存中的空间分配。\n \n \n AioUringCompletion\n 等待另一个进程通过 io_uring 完成 I/O。\n \n \n AioWorkerControl\n 等待更新 AIO 工作进程信息。\n \n \n AioWorkerSubmissionQueue\n 等待访问 AIO 工作进程的提交队列。\n \n \n AutoFile\n 等待更新postgresql.auto.conf文件。\n \n \n Autovacuum\n 等待读取或更新自动清理工作进程的当前状态。\n \n \n AutovacuumSchedule\n 等待确认选中进行自动清理的表是否仍需清理。\n \n \n BackgroundWorker\n 等待读取或更新后台工作进程状态。\n \n \n BtreeVacuum\n 等待读取或更新B-树索引的清理相关信息。\n \n \n BufferMapping\n 等待将数据块与缓冲池中的缓冲区关联。\n \n \n CheckpointerComm\n 等待管理fsync请求。\n \n \n CommitTs\n 等待读取或更新最近设置的事务提交时间戳值。\n \n \n CommitTsBuffer\n 在提交时间戳SLRU缓冲区上等待I/O。\n \n \n CommitTsSLRU\n 等待访问提交时间戳SLRU缓存。\n \n \n ControlFile\n 等待读取或更新pg_control文件或创建一个新的WAL文件。\n \n \n DataChecksumsWorker\n 等待数据校验和工作进程。\n \n \n DSMRegistry\n 等待读取或更新动态共享内存注册表。\n \n \n DSMRegistryDSA\n 等待访问动态共享内存注册表的动态共享内存分配器。\n \n \n DSMRegistryHash\n 等待访问动态共享内存注册表的共享哈希表。\n \n \n DynamicSharedMemoryControl\n 等待读取或更新动态共享内存分配信息。\n \n \n InjectionPoint\n 等待读取或更新注入点相关信息。\n \n \n LockFastPath\n 等待读取或更新进程的快速路径锁信息。\n \n \n LockManager\n 等待读取或更新有关重量级锁的信息。\n \n \n LogicalDecodingControl\n 等待读取或更新逻辑解码状态信息。\n \n \n LogicalRepLauncherDSA\n 等待访问逻辑复制启动进程的动态共享内存分配器。\n \n \n LogicalRepLauncherHash\n 等待访问逻辑复制启动进程的共享哈希表。\n \n \n LogicalRepWorker\n 等待读取或更新逻辑复制工作进程的状态。\n \n \n MultiXactGen\n 等待读取或更新共享的多事务状态。\n \n \n MultiXactMemberBuffer\n 等待多事务成员 SLRU 缓冲区上的 I/O。\n \n \n MultiXactMemberSLRU\n 等待访问多事务成员 SLRU 缓存。\n \n \n MultiXactOffsetBuffer\n 等待多事务偏移量 SLRU 缓冲区上的 I/O。\n \n \n MultiXactOffsetSLRU\n 等待访问多事务偏移量 SLRU 缓存。\n \n \n MultiXactTruncation\n 等待读取或截断多事务信息。\n \n \n NotifyBuffer\n NOTIFY 消息 SLRU缓冲区上等待I/O。\n \n \n NotifyChannelHash\n 等待访问 NOTIFY 通道哈希表。\n \n \n NotifyQueue\n 等待读取或更新NOTIFY 消息。\n \n \n NotifyQueueTail\n 等待更新 NOTIFY 消息存储的限制。\n \n \n NotifySLRU\n 等待访问NOTIFY消息SLRU缓存。\n \n \n OidGen\n 等待分配一个新的OID。\n \n \n ParallelAppend\n 在 Parallel Append 计划执行期间等待选择下一个子计划。\n \n \n ParallelBtreeScan\n 在并行 B-树扫描计划执行期间等待同步工作进程。\n \n \n ParallelHashJoin\n 在 Parallel Hash Join 计划执行期间等待同步工作进程。\n \n \n ParallelQueryDSA\n 等待并行查询动态共享内存分配。\n \n \n ParallelVacuumDSA\n 等待为并行清理分配动态共享内存。\n \n \n PerSessionDSA\n 等待并行查询动态共享内存分配。\n \n \n PerSessionRecordType\n 等待访问并行查询中有关复合类型的信息。\n \n \n PerSessionRecordTypmod\n 等待访问并行查询中用于标识匿名记录类型的类型修饰符信息。\n \n \n PerXactPredicateList\n 在并行查询期间等待访问当前可串行化事务持有的谓词锁列表。\n \n \n PgStatsData\n 等待访问共享内存中的统计数据。\n \n \n PgStatsDSA\n 等待访问统计信息的动态共享内存分配器。\n \n \n PgStatsHash\n 等待访问统计信息的共享内存哈希表。\n \n \n PredicateLockManager\n 等待访问可串行化事务使用的谓词锁信息。\n \n \n ProcArray\n 等待访问各进程的共享数据结构(通常是为了获取快照或报告会话的事务 ID)。\n \n \n RelationMapping\n 等待读取或更新pg_filenode.map文件(用于跟踪某些系统目录的文件节点分配)。\n \n \n RelCacheInit\n 等待读取或更新pg_internal.init关系缓存初始化文件。\n \n \n ReplicationOrigin\n 等待创建、删除或使用复制源。\n \n \n ReplicationOriginState\n 等待读取或更新一个复制源的进度。\n \n \n ReplicationSlotAllocation\n 等待分配或释放复制槽。\n \n \n ReplicationSlotControl\n 等待读取或更新复制槽状态。\n \n \n ReplicationSlotIO\n 在复制槽上等待I/O。\n \n \n SerialBuffer\n 在可串行化事务冲突的SLRU缓冲区上等待I/O。\n \n \n SerialControl\n 等待读取或更新共享的 pg_serial 状态。\n \n \n SerializableFinishedList\n 等待访问已完成的可串行化事务列表。\n \n \n SerializablePredicateList\n 等待访问可串行化事务持有的谓词锁列表。\n \n \n SerializableXactHash\n 等待读取或更新关于可串行化事务的信息。\n \n \n SerialSLRU\n 等待访问可串行化事务冲突SLRU缓存。\n \n \n SharedTidBitmap\n 在并行位图索引扫描期间等待访问共享的TID位图。\n \n \n SharedTupleStore\n 在并行查询期间等待访问共享元组存储。\n \n \n ShmemIndex\n 等待在共享内存中找到或分配空间。\n \n \n SInvalRead\n 等待从共享系统目录失效队列中取出消息。\n \n \n SInvalWrite\n 等待向共享系统目录失效队列添加消息。\n \n \n SubtransBuffer\n 在子事务SLRU缓冲区上等待I/O。\n \n \n SubtransSLRU\n 等待访问子事务SLRU缓存。\n \n \n SyncRep\n 等待读取或更新有关同步复制状态的信息。\n \n \n SyncScan\n 等待选择同步表扫描的起始位置。\n \n \n TablespaceCreate\n 等待创建或删除表空间。\n \n \n TwoPhaseState\n 等待读取或更新预备事务的状态。\n \n \n WaitEventCustom\n 等待读取或更新自定义等待事件信息。\n \n \n WaitLSN\n 等待读取或更新共享的 LSN 等待状态。\n \n \n WALBufMapping\n 等待在WAL缓冲区中替换一个页面。\n \n \n WALInsert\n 等待将WAL数据插入内存缓冲区。\n \n \n WALSummarizer\n 等待读取或更新 WAL 汇总状态。\n \n \n WALWrite\n 等待WAL缓冲区写入磁盘。\n \n \n WrapLimitsVacuum\n 等待更新事务 ID 和多事务消耗量的限制。\n \n \n XactBuffer\n 在事务状态的SLRU缓冲区上等待I/O。\n \n \n XactSLRU\n 等待访问事务状态的SLRU缓存。\n \n \n XactTruncation\n 等待执行pg_xact_status或更新它可用的最早的事务ID。\n \n \n XidGen\n 等待分配新的事务ID。\n \n \n \n
" }, { - "english": "\n Wait Events of Type <literal>Timeout</literal>\n \n \n \n Timeout Wait Event\n Description\n \n \n\n ", - "chinese": "
\n\n <literal>Timeout</literal>类型的等待事件\n \n \n\n \n Timeout 等待事件\n 描述\n \n \n\n " + "english": "
\n Wait Events of Type <literal>Timeout</literal>\n \n \n \n Timeout Wait Event\n Description\n \n \n\n \n \n BaseBackupThrottle\n Waiting during base backup when throttling activity.\n \n \n CheckpointWriteDelay\n Waiting between writes while performing a checkpoint.\n \n \n CommitDelay\n Waiting for commit delay before WAL flush.\n \n \n PgSleep\n Waiting due to a call to pg_sleep or a sibling function.\n \n \n RecoveryApplyDelay\n Waiting to apply WAL during recovery because of a delay setting.\n \n \n RecoveryRetrieveRetryInterval\n Waiting during recovery when WAL data is not available from any source (pg_wal, archive or stream).\n \n \n RegisterSyncRequest\n Waiting while sending synchronization requests to the checkpointer, because the request queue is full.\n \n \n SpinDelay\n Waiting while acquiring a contended spinlock.\n \n \n VacuumDelay\n Waiting in a cost-based vacuum delay point.\n \n \n VacuumTruncate\n Waiting to acquire an exclusive lock to truncate off any empty pages at the end of a table vacuumed.\n \n \n WalSummarizerError\n Waiting after a WAL summarizer error.\n \n \n \n
", + "chinese": "\n\n <literal>Timeout</literal>类型的等待事件\n \n \n\n \n Timeout 等待事件\n 描述\n \n \n\n \n \n BaseBackupThrottle\n 在基础备份期间因限流而等待。\n \n \n CheckpointWriteDelay\n 在执行检查点时,在各次写入之间等待。\n \n \n CommitDelay\n 等待 WAL 刷盘前的提交延迟。\n \n \n PgSleep\n 由于调用pg_sleep或同类函数而等待。\n \n \n RecoveryApplyDelay\n 由于延迟设置,在恢复期间等待应用WAL。\n \n \n RecoveryRetrieveRetryInterval\n 当WAL数据无法从任何来源(pg_wal、归档或流复制)获得时,在恢复期间等待。\n \n \n RegisterSyncRequest\n 向检查点进程发送同步请求时,因请求队列已满而等待。\n \n \n SpinDelay\n 在获取有竞争的自旋锁时等待。\n \n \n VacuumDelay\n 在基于代价的清理延迟点等待。\n \n \n VacuumTruncate\n 等待获取独占锁以截断被清理的表末尾的空页面。\n \n \n WalSummarizerError\n 在 WAL 汇总进程出错后等待。\n \n \n \n
" } ] } diff --git a/zh/20/gin.sgml b/zh/20/gin.sgml index d96ea757..1b83d342 100644 --- a/zh/20/gin.sgml +++ b/zh/20/gin.sgml @@ -53,7 +53,7 @@ 内置操作符类 - PostgreSQL 核心发布包含 + PostgreSQL 核心发行版包含 所示的 GIN 操作符类。 (在 中描述的一些可选模块还提供额外的 GIN 操作符类。) @@ -152,7 +152,7 @@ 给定一个要建立索引的项,返回一个用 palloc 分配的键数组。返回键的数量必须存入 *nkeys。如果任一键可以为 null,还要另外 palloc 一个包含 *nkeysbool 字段的数组,将其地址存入 - *nullFlags,并按需设置这些空值标志。如果所有键都非空, + *nullFlags,并按需设置这些空值标志。如果所有键都不是 null, *nullFlags 可以保持为 NULL(其初始值)。 如果该项不包含任何键,则返回值可以为 NULL
@@ -172,7 +172,7 @@ query 的数据类型,以及应采用何种方法提取键值。返回键的数量必须存入 *nkeys。如果任一键可以为 null,还要另外 palloc 一个包含 *nkeysbool 字段的数组,将其地址存入 - *nullFlags,并按需设置这些空值标志。如果所有键都非空, + *nullFlags,并按需设置这些空值标志。如果所有键都不是 null, *nullFlags 可以保持为 NULL(其初始值)。 如果 query 不包含任何键,则返回值可以为 NULL
@@ -185,7 +185,7 @@ 被设置为 GIN_SEARCH_MODE_INCLUDE_EMPTY,则除至少包含一个匹配键的项之外, 完全不含任何键的项也会被视为候选匹配。(例如,该模式对于实现是子集操作符很有用。) 若 *searchMode 被设置为 GIN_SEARCH_MODE_ALL, - 则索引中所有非空项都会被视为候选匹配,无论它们是否匹配任一返回键。 + 则索引中所有非 null 项都会被视为候选匹配,无论它们是否匹配任一返回键。 (该模式比前两种选择慢得多,因为它基本上需要扫描整个索引;但为了正确处理某些边界情况, 可能有此必要。在大多数情况下都需要此模式的操作符,大概并不适合作为 GIN 操作符类的候选。)用于设置该模式的符号定义在 @@ -218,7 +218,7 @@ 操作符类还必须提供一个函数,用于检查被索引项是否匹配查询。它有两种形式:布尔型 consistent 函数,以及三值型 triConsistent 函数。 triConsistent 覆盖了两者的功能,因此仅提供 triConsistent - 就已经足够。不过,如果布尔变体的计算明显更便宜,那么同时提供两者会更有利。 + 就已经足够。不过,如果布尔变体的计算代价明显更低,那么同时提供两者可能更有利。 若只提供布尔变体,则一些依赖于在取回所有键之前先排除索引项的优化将被禁用。 @@ -233,10 +233,10 @@ 该函数无法直接访问被索引项的值,因为 GIN 并不显式存储项。 它所能利用的是这样一种信息:从查询中提取出的哪些键值出现在给定的被索引项中。 check 数组长度为 nkeys,这与先前针对该 - query 数据由 extractQuery 返回的键数量相同。 + query datum 由 extractQuery 返回的键数量相同。 如果被索引项包含相应查询键,则 check 数组中的对应元素为 true; 也就是说,如果 check[i] == true,则 extractQuery - 结果数组中的第 i 个键存在于该被索引项中。传入原始 query 数据值, + 结果数组中的第 i 个键存在于该被索引项中。传入原始 query datum, 是为了让 consistent 方法在需要时可以查看它;同样也会传入先前由 extractQuery 返回的 queryKeys[]nullFlags[] 数组。extra_data 则是 @@ -274,7 +274,7 @@ 而 GIN_MAYBE 表示该键是否存在尚不确定。存在 GIN_MAYBE 值时,只有当无论索引项是否包含对应查询键,该项都确定匹配时,函数才应返回 GIN_TRUE。同样,只有当无论是否包含 GIN_MAYBE 键, - 该项都确定不匹配时,函数才必须返回 GIN_FALSE。如果结果依赖于 + 该项都确定不匹配时,函数才能返回 GIN_FALSE。如果结果依赖于 GIN_MAYBE 条目,也就是说,无法根据已知的查询键确认或否定匹配, 则函数必须返回 GIN_MAYBE
@@ -306,7 +306,7 @@ 或者,如果操作符类没有提供 compare 方法,GIN 将查找该索引键数据类型的默认 B-树操作符类,并使用其比较函数。建议在仅面向单一数据类型的 - GIN 操作符类中显式指定比较函数,因为查找 B-树操作符类会消耗少量周期。 + GIN 操作符类中显式指定比较函数,因为查找 B-树操作符类会消耗少量处理器周期。 不过,多态 GIN 操作符类(例如 array_ops)通常无法指定单一比较函数。
@@ -376,8 +376,8 @@ 在内部,一个 GIN 索引包含一个基于键构建的 B-树索引,其中每个键都是一个或多个被索引项中的某个元素 - (例如数组成员),而叶子页中的每个元组要么包含一个指向堆指针 B-树的指针(posting tree), - 要么在列表足够小、能够连同键值一起放入单个索引元组时,直接包含一个简单的堆指针列表(posting list)。 + (例如数组成员),而叶子页中的每个元组要么包含一个指向堆指针 B-树的指针(倒排树), + 要么在列表足够小、能够连同键值一起放入单个索引元组时,直接包含一个简单的堆指针列表(倒排列表)。 展示了 GIN 索引的这些组成部分。 @@ -424,7 +424,7 @@
- 如果一致的响应时间比更新速度更重要,可以通过关闭 GIN 索引的 + 如果稳定的响应时间比更新速度更重要,可以通过关闭 GIN 索引的 fastupdate 存储参数来禁用待处理列表机制。详见 @@ -463,7 +463,7 @@ 当为 GIN 启用 fastupdate 时 (详见 ),这种代价会比未启用时小一些。 - 但对于非常大的更新,最好仍然是删除并重建索引。 + 但对于非常大的更新,删除并重建索引仍然可能是最佳选择。
@@ -531,7 +531,7 @@ GIN 假定可索引操作符是严格的。这意味着,当项值为 null 时, 根本不会对其调用 extractValue(而是自动创建一个占位符索引项); 当查询值为 null 时,也不会调用 extractQuery(而是认为该查询不可满足)。 - 不过要注意,非空组合项或查询值内部包含的 null 键值仍然受支持。 + 不过要注意,非 null 的组合项或查询值内部包含的 null 键值仍然受支持。
@@ -539,7 +539,7 @@ 示例 - PostgreSQL 核心发布包含前面在 + PostgreSQL 核心发行版包含前面在 中展示过的 GIN 操作符类。 下列 contrib 模块也包含 GIN 操作符类: diff --git a/zh/20/gist.sgml b/zh/20/gist.sgml index 271fd40d..47d1dfd1 100644 --- a/zh/20/gist.sgml +++ b/zh/20/gist.sgml @@ -4,7 +4,7 @@ GiST 索引 - index + 索引 GiST @@ -211,7 +211,7 @@ CREATE INDEX ON my_table USING GIST (my_inet_column inet_ops); - 这种可扩展性不应与其他标准搜索树在可处理数据方面的可扩展性相混淆。例如,PostgreSQL支持可扩展的 B-树和哈希索引。这意味着你可以用PostgreSQL在任意数据类型上构建 B-树或哈希索引。但 B-树只支持范围谓词(<=>),而哈希索引只支持等值查询。 + 这种可扩展性不应与其他标准搜索树在可处理数据方面的可扩展性相混淆。例如,PostgreSQL支持可扩展的 B-树和 hash 索引。这意味着你可以用PostgreSQL在任意数据类型上构建 B-树或 hash 索引。但 B-树只支持范围谓词(<=>),而 hash 索引只支持等值查询。 @@ -264,15 +264,14 @@ my_consistent(PG_FUNCTION_ARGS) bool retval; /* - * determine return value as a function of strategy, key and query. + * 根据 strategy、key 和 query 确定返回值。 * - * Use GIST_LEAF(entry) to know where you're called in the index tree, - * which comes handy when supporting the = operator for example (you could - * check for non empty union() in non-leaf nodes and equality in leaf - * nodes). + * 使用 GIST_LEAF(entry) 判断当前调用位于索引树的哪个位置。 + * 例如,支持 = 操作符时这很有用(可以在非叶节点检查 + * union() 是否非空,在叶节点检查是否相等)。 */ - *recheck = true; /* or false if check is exact */ + *recheck = true; /* 如果检查是精确的,则为 false */ PG_RETURN_BOOL(retval); } @@ -366,7 +365,7 @@ my_union(PG_FUNCTION_ARGS) - 如果被索引的数据类型与存储在索引中的数据类型不同,可以使用CREATE OPERATOR CLASS命令的STORAGE选项来定义索引中存储的数据类型。不过要注意,STORAGE数据类型只用于定义索引项的物理属性(它们的typlentypbyvaltypalign属性)。索引数据值中实际存放什么,由compressdecompress方法控制,只要存放的数据满足这些属性即可。只要叶子键与更高层索引页上的键都满足STORAGE数据类型,compress就可以为叶子键和其他键生成不同表示形式。 + 如果被索引的数据类型与存储在索引中的数据类型不同,可以使用CREATE OPERATOR CLASS命令的STORAGE选项来定义索引中存储的数据类型。不过要注意,STORAGE数据类型只用于定义索引项的物理属性(它们的typlentypbyvaltypalign属性)。索引 datum 中实际存放什么,由compressdecompress方法控制,只要存放的 datum 满足这些属性即可。只要叶子键与更高层索引页上的键都满足STORAGE数据类型,compress就可以为叶子键和其他键生成不同表示形式。 @@ -392,10 +391,10 @@ my_compress(PG_FUNCTION_ARGS) if (entry->leafkey) { - /* replace entry->key with a compressed version */ + /* 将 entry->key 替换为压缩后的形式 */ compressed_data_type *compressed_data = palloc_object(compressed_data_type); - /* fill *compressed_data from entry->key ... */ + /* 根据 entry->key 填充 *compressed_data ... */ retval = palloc_object(GISTENTRY); gistentryinit(*retval, PointerGetDatum(compressed_data), @@ -403,7 +402,7 @@ my_compress(PG_FUNCTION_ARGS) } else { - /* typically we needn't do anything with non-leaf entries */ + /* 通常无需对非叶项做任何处理 */ retval = entry; } @@ -466,7 +465,7 @@ my_decompress(PG_FUNCTION_ARGS) CREATE OR REPLACE FUNCTION my_penalty(internal, internal, internal) RETURNS internal AS 'MODULE_PATHNAME' -LANGUAGE C STRICT; -- in some cases penalty functions need not be strict +LANGUAGE C STRICT; -- 某些情况下 penalty 函数不必是严格函数 而 C 模块中的对应代码则可以遵循如下框架: @@ -488,7 +487,7 @@ my_penalty(PG_FUNCTION_ARGS) } - 出于历史原因,penalty函数并不是直接返回一个float结果;相反,它必须把该值存储到第三个参数指示的位置。返回值本身会被忽略,不过通常会返回该参数的地址。 + 出于历史原因,penalty函数并不是直接返回一个float结果;相反,它必须把该值存储到第三个参数指示的位置。返回值本身会被忽略,不过通常会返回该参数所指向的地址。 @@ -549,7 +548,7 @@ my_picksplit(PG_FUNCTION_ARGS) unionL = NULL; unionR = NULL; - /* Initialize the raw entry vector. */ + /* 初始化原始项向量。 */ raw_entryvec = (GISTENTRY **) malloc(entryvec->n * sizeof(void *)); for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) raw_entryvec[i] = &(entryvec->vector[i]); @@ -562,9 +561,9 @@ my_picksplit(PG_FUNCTION_ARGS) Assert(tmp_union != NULL); /* - * Choose where to put the index entries and update unionL and unionR - * accordingly. Append the entries to either v->spl_left or - * v->spl_right, and care about the counters. + * 选择索引项的存放位置,并相应更新 unionL 和 unionR。 + * 将项追加到 v->spl_left 或 v->spl_right, + * 同时更新计数器。 */ if (my_choice_is_left(unionL, curl, unionR, curr)) @@ -581,7 +580,7 @@ my_picksplit(PG_FUNCTION_ARGS) else { /* - * Same on the right + * 对右侧执行相同操作 */ } } @@ -635,7 +634,7 @@ my_same(PG_FUNCTION_ARGS) } - 出于历史原因,same函数并不是直接返回一个布尔结果;相反,它必须把该标志存储到第三个参数指示的位置。返回值本身会被忽略,不过通常会返回该参数的地址。 + 出于历史原因,same函数并不是直接返回一个布尔结果;相反,它必须把该标志存储到第三个参数指示的位置。返回值本身会被忽略,不过通常会返回该参数所指向的地址。
@@ -676,7 +675,7 @@ my_distance(PG_FUNCTION_ARGS) double retval; /* - * determine return value as a function of strategy, key and query. + * 根据 strategy、key 和 query 确定返回值。 */ PG_RETURN_FLOAT8(retval); @@ -687,11 +686,11 @@ my_distance(PG_FUNCTION_ARGS) - 在确定距离时允许有一定近似,只要结果永不大于该项的实际距离即可。因此,例如在几何应用中,到外包盒的距离通常就足够了。对于内部树节点,返回的距离不能大于其任一子节点的距离。如果返回的距离不精确,函数必须将*recheck设为 true。(对内部树节点则不必这样做;对它们总是假定计算结果不精确。)在这种情况下,执行器会在从堆中取出元组后计算准确距离,并在必要时重新排序这些元组。 + 在确定距离时允许有一定近似,只要结果永不大于该项的实际距离即可。因此,例如在几何应用中,到包围盒的距离通常就足够了。对于内部树节点,返回的距离不能大于其任一子节点的距离。如果返回的距离不精确,函数必须将*recheck设为 true。(对内部树节点则不必这样做;对它们总是假定计算结果不精确。)在这种情况下,执行器会在从堆中取出元组后计算准确距离,并在必要时重新排序这些元组。 - 如果距离函数对任何叶节点都返回*recheck = true,原始排序操作符的返回类型必须是float8float4,且距离函数的结果值必须能与原始排序操作符的结果进行比较,因为执行器会同时使用距离函数结果和重新计算得到的排序操作符结果进行排序。否则,距离函数的结果值可以是任意有限的float8值,只要这些结果值的相对顺序与排序操作符返回的顺序一致即可。(无穷大和负无穷在内部用于处理空值等情况,因此不建议distance函数返回这些值。) + 如果距离函数对任意一个叶节点返回*recheck = true,原始排序操作符的返回类型必须是float8float4,且距离函数的结果值必须能与原始排序操作符的结果进行比较,因为执行器会同时使用距离函数结果和重新计算得到的排序操作符结果进行排序。否则,距离函数的结果值可以是任意有限的float8值,只要这些结果值的相对顺序与排序操作符返回的顺序一致即可。(无穷大和负无穷在内部用于处理空值等情况,因此不建议distance函数返回这些值。)
@@ -735,10 +734,10 @@ my_fetch(PG_FUNCTION_ARGS) fetched_data = palloc_object(fetched_data_type); /* - * Convert 'fetched_data' into a Datum of the original datatype. + * 将 'fetched_data' 转换为原始数据类型的 Datum。 */ - /* fill *retval from fetched_data. */ + /* 根据 fetched_data 填充 *retval。 */ gistentryinit(*retval, PointerGetDatum(converted_datum), entry->rel, entry->page, entry->offset, FALSE); @@ -789,26 +788,26 @@ typedef enum MyEnumType typedef struct { - int32 vl_len_; /* varlena header (do not touch directly!) */ - int int_param; /* integer parameter */ - double real_param; /* real parameter */ - MyEnumType enum_param; /* enum parameter */ - int str_param; /* string parameter */ + int32 vl_len_; /* varlena 首部(不要直接操作!) */ + int int_param; /* 整数参数 */ + double real_param; /* 实数参数 */ + MyEnumType enum_param; /* 枚举参数 */ + int str_param; /* 字符串参数 */ } MyOptionsStruct; -/* String representation of enum values */ +/* 枚举值的字符串表示 */ static relopt_enum_elt_def myEnumValues[] = { {"on", MY_ENUM_ON}, {"off", MY_ENUM_OFF}, {"auto", MY_ENUM_AUTO}, - {(const char *) NULL} /* list terminator */ + {(const char *) NULL} /* 列表终止项 */ }; static char *str_param_default = "default"; /* - * Sample validator: checks that string is not longer than 8 bytes. + * 验证器示例:检查字符串长度不超过 8 字节。 */ static void validate_my_string_relopt(const char *value) @@ -820,7 +819,7 @@ validate_my_string_relopt(const char *value) } /* - * Sample filler: switches characters to lower case. + * 填充函数示例:将字符转换为小写。 */ static Size fill_my_string_relopt(const char *value, void *ptr) @@ -873,10 +872,9 @@ my_compress(PG_FUNCTION_ARGS) char *str_param = str_param_default; /* - * Normally, when opclass contains 'options' method, then options are always - * passed to support functions. However, if you add 'options' method to - * existing opclass, previously defined indexes have no options, so the - * check is required. + * 通常,操作符类包含 'options' 方法时,总会把选项传给支持函数。 + * 但是,如果把 'options' 方法添加到已有操作符类中, + * 先前定义的索引没有选项,因此需要进行检查。 */ if (PG_HAS_OPCLASS_OPTIONS()) { @@ -888,7 +886,7 @@ my_compress(PG_FUNCTION_ARGS) str_param = GET_STRING_RELOPTION(options, str_param); } - /* the rest implementation of support function */ + /* 支持函数的其余实现 */ } @@ -932,7 +930,7 @@ PG_FUNCTION_INFO_V1(my_sortsupport); static int my_fastcmp(Datum x, Datum y, SortSupport ssup) { - /* establish order between x and y by computing some sorting value z */ + /* 通过计算某个排序值 z 来确定 x 和 y 的顺序 */ int z1 = ComputeSpatialCode(x); int z2 = ComputeSpatialCode(y); @@ -957,7 +955,7 @@ my_sortsupport(PG_FUNCTION_ARGS) translate_cmptype - 给定一个来自src/include/access/cmptype.hCompareType值,返回该操作符类用于匹配功能的策略号。如果该操作符类没有匹配策略,函数应返回InvalidStrategy。 + 给定一个来自src/include/access/cmptype.hCompareType值,返回该操作符类中具有相应功能的策略号。如果该操作符类没有匹配策略,函数应返回InvalidStrategy @@ -1011,7 +1009,7 @@ my_translate_cmptype(PG_FUNCTION_ARGS) - PostgreSQL提供了一个翻译函数:gist_translate_cmptype_common,用于使用RT*StrategyNumber常量的操作符类。btree_gist扩展又定义了第二个翻译函数gist_translate_cmptype_btree,用于使用BT*StrategyNumber常量的操作符类。 + PostgreSQL提供了一个转换函数:gist_translate_cmptype_common,用于使用RT*StrategyNumber常量的操作符类。btree_gist扩展又定义了第二个转换函数gist_translate_cmptype_btree,用于使用BT*StrategyNumber常量的操作符类。 @@ -1030,7 +1028,7 @@ my_translate_cmptype(PG_FUNCTION_ARGS) GiST 索引构建方法 - 构建 GiST 索引最简单的方法就是把所有项逐个插入。这对于大型索引往往很慢,因为如果索引元组分散在整个索引中,而索引又大到无法放入缓存,就需要大量随机 I/O。PostgreSQL支持两种用于 GiST 索引初始构建的替代方法:sortedbuffered模式。 + 构建 GiST 索引最简单的方法就是把所有项逐个插入。这对于大型索引往往很慢,因为如果索引元组分散在整个索引中,而索引又大到无法放入缓存,就需要大量随机 I/O。PostgreSQL支持两种用于 GiST 索引初始构建的替代方法:排序缓冲模式。 @@ -1076,7 +1074,7 @@ my_translate_cmptype(PG_FUNCTION_ARGS) hstore - 用于存储 (key, value) 对的模块 + 用于存储(键,值)对的模块 diff --git a/zh/20/glossary.sgml b/zh/20/glossary.sgml index 93aea05c..fb11c047 100644 --- a/zh/20/glossary.sgml +++ b/zh/20/glossary.sgml @@ -396,7 +396,7 @@ 客户端(进程) - 任何进程,可能是远程的,通过连接到某个 + 任何进程,可能是远程的,通过连接到某个 实例来建立 会话, 以与一个数据库交互。 @@ -877,7 +877,7 @@ 一台通过网络与其他计算机通信的计算机。这个术语有时被用作 服务器的同义词。 - 它也用来指客户端进程运行所在的计算机。 + 它也用来指客户端进程运行所在的计算机。 @@ -961,7 +961,7 @@ 实例处理 DBMS 的所有关键特性: 对文件和共享内存的读写访问、保证 ACID 属性、 - 与客户端进程的连接、 + 与客户端进程连接、 权限验证、崩溃恢复、复制等。 @@ -1057,7 +1057,7 @@ - 逻辑复制集簇 + 逻辑复制集群 一组发布者实例和订阅者实例,其中发布者实例把变更复制到订阅者实例。 @@ -1211,7 +1211,7 @@ - 当它用于指代查询中的 + 当它用于指代查询中的 窗口函数时, 分区是一种用户定义的准则,用来标识 查询结果集中哪些相邻的 diff --git a/zh/20/hash.sgml b/zh/20/hash.sgml index 49f4fdf6..0a5f55de 100644 --- a/zh/20/hash.sgml +++ b/zh/20/hash.sgml @@ -1,11 +1,11 @@ -哈希索引 +Hash 索引 索引 - 哈希 + Hash @@ -13,51 +13,51 @@ PostgreSQL - 提供了持久化的磁盘哈希索引实现,并且完全支持崩溃恢复。任何数据类型都可以使用哈希索引,包括那些没有明确定义线性顺序的数据类型。哈希索引只存储被索引数据的哈希值,因此对被索引数据列的大小没有限制。 + 提供了持久化的磁盘 hash 索引实现,并且完全支持崩溃恢复。任何数据类型都可以使用 hash 索引,包括那些没有明确定义线性顺序的数据类型。Hash 索引只存储被索引数据的 hash 值,因此对被索引数据列的大小没有限制。 - 哈希索引仅支持单列索引,也不支持唯一性检查。 + Hash 索引仅支持单列索引,也不支持唯一性检查。 - 哈希索引仅支持=操作符,因此指定范围操作的 WHERE 子句无法利用哈希索引。 + Hash 索引仅支持=操作符,因此指定范围操作的 WHERE 子句无法利用 hash 索引。 - 每个哈希索引元组只存储 4 字节的哈希值,而不存储实际的列值。因此,在为 UUID、URL 等较长的数据项建立索引时,哈希索引可能比 B-树小得多。由于没有列值,所有哈希索引扫描也都是有损的。哈希索引可以参与位图索引扫描和反向扫描。 + 每个 hash 索引元组只存储 4 字节的 hash 值,而不存储实际的列值。因此,在为 UUID、URL 等较长的数据项建立索引时,hash 索引可能比 B-树小得多。由于没有列值,所有 hash 索引扫描也都是有损的。Hash 索引可以参与位图索引扫描和反向扫描。 - 哈希索引最适合于在较大表上执行等值扫描、且以 SELECT 和 UPDATE 为主的工作负载。在 B-树索引中,搜索必须沿树向下直到找到叶页。在拥有数百万行的表中,这种向下遍历会增加访问数据的时间。在哈希索引中,与叶页对应的页称为桶页。相比之下,哈希索引允许直接访问桶页,因此可能减少大表中的索引访问时间。这种“逻辑 I/O”的减少,在索引/数据大于 shared_buffers/RAM 时会更加明显。 + Hash 索引最适合于在较大表上执行等值扫描、且以 SELECT 和 UPDATE 为主的工作负载。在 B-树索引中,搜索必须沿树向下直到找到叶页。在拥有数百万行的表中,这种向下遍历会增加访问数据的时间。在 hash 索引中,与叶页对应的页称为桶页。相比之下,hash 索引允许直接访问桶页,因此可能减少大表中的索引访问时间。这种“逻辑 I/O”的减少,在索引/数据大于 shared_buffers/RAM 时会更加明显。 - 哈希索引在设计上能够应对哈希值分布不均的情况。如果哈希值分布均匀,那么直接访问桶页的效果很好。当插入导致桶页填满时,额外的溢出页就会链接到该特定桶页上,从而在局部扩展用于存放匹配该哈希值的索引元组的空间。查询期间扫描某个哈希桶时,需要遍历其全部溢出页。因此,对于某些数据,不平衡的哈希索引在所需块访问次数方面实际上可能比 B-树更差。 + Hash 索引在设计上能够应对 hash 值分布不均的情况。如果 hash 值分布均匀,那么直接访问桶页的效果很好。当插入导致桶页填满时,额外的溢出页就会链接到该特定桶页上,从而在局部扩展用于存放匹配该 hash 值的索引元组的空间。查询期间扫描某个 hash 桶时,需要遍历其全部溢出页。因此,对于某些数据,不平衡的 hash 索引在所需块访问次数方面实际上可能比 B-树更差。 - 由于会出现这些溢出情况,可以说哈希索引最适合用于唯一值、近乎唯一值,或者每个哈希桶中行数较少的数据。 + 由于会出现这些溢出情况,可以说 hash 索引最适合用于唯一值、近乎唯一值,或者每个 hash 桶中行数较少的数据。 避免问题的一种可能办法,是使用部分索引条件把高度非唯一的值排除在索引之外,但这在很多情况下可能并不适用。 - 与 B-树一样,哈希索引也会执行简单的索引元组删除。这是一种延迟维护操作,用于删除那些已知可以安全删除的索引元组(即其项标识符的 LP_DEAD 位已经被设置的那些元组)。如果插入操作发现页上没有可用空间,我们会尝试通过移除死索引元组来避免创建新的溢出页。如果该页当时已被钉住,就无法执行移除。死索引指针也会在 VACUUM 期间被删除。 + 与 B-树一样,hash 索引也会执行简单的索引元组删除。这是一种延迟维护操作,用于删除那些已知可以安全删除的索引元组(即其项标识符的 LP_DEAD 位已经被设置的那些元组)。如果插入操作发现页上没有可用空间,我们会尝试通过移除死索引元组来避免创建新的溢出页。如果该页当时已被钉住,就无法执行移除。死索引指针也会在 VACUUM 期间被删除。 - 如果可能,VACUUM 还会尝试将索引元组压缩到尽可能少的溢出页上,以最小化溢出链。 + 如果可能,VACUUM 还会尝试将索引元组集中存放在尽可能少的溢出页上,以最小化溢出链。 如果某个溢出页变为空页,该溢出页就可以被回收并在其他桶中重用,不过我们从不将它们返还给操作系统。 - 目前除了使用 REINDEX 重建哈希索引之外,还没有缩小哈希索引的方法。 + 目前除了使用 REINDEX 重建 hash 索引之外,还没有缩小 hash 索引的方法。 同样也没有减少桶数量的方法。 - 随着被索引行数的增长,哈希索引可能会扩展桶页数量。哈希键到桶号的映射经过选择,使得索引能够增量扩展。当需要向索引中添加一个新桶时,恰好只需要“拆分”一个现有桶,并根据更新后的键到桶号映射,将其中一部分元组转移到新桶。 + 随着被索引行数的增长,Hash 索引可能会扩展桶页数量。hash 键到桶号的映射经过选择,使得索引能够增量扩展。当需要向索引中添加一个新桶时,恰好只需要“拆分”一个现有桶,并根据更新后的键到桶号映射,将其中一部分元组转移到新桶。 - 这种扩展是在前台进行的,因此可能会增加用户插入操作的执行时间。因此,哈希索引可能不适合行数快速增长的表。 + 这种扩展是在前台进行的,因此可能会增加用户插入操作的执行时间。因此,hash 索引可能不适合行数快速增长的表。 @@ -66,7 +66,7 @@ 实现 - 哈希索引中有四种页:元页(第零页),其中包含静态分配的控制信息;主桶页;溢出页;以及位图页,后者用于跟踪已被释放且可供重用的溢出页。在寻址时,位图页被视为溢出页的一个子集。 + hash 索引中有四种页:元页(第零页),其中包含静态分配的控制信息;主桶页;溢出页;以及位图页,后者用于跟踪已被释放且可供重用的溢出页。在寻址时,位图页被视为溢出页的一个子集。 @@ -74,15 +74,15 @@ - 主桶页和溢出页是独立分配的,因为任何一个给定索引相对于其桶数,可能需要更多或更少的溢出页。哈希代码使用了一组颇有意思的寻址规则,以支持可变数量的溢出页,同时又不必在主桶页创建后再移动它们。 + 主桶页和溢出页是独立分配的,因为任何一个给定索引相对于其桶数,可能需要更多或更少的溢出页。hash 实现代码使用了一组颇有意思的寻址规则,以支持可变数量的溢出页,同时又不必在主桶页创建后再移动它们。 - 被索引表中的每一行,都由哈希索引中的单个索引元组表示。哈希索引元组存储在桶页中,如果存在溢出页,也会存储在溢出页中。为了加快搜索速度,我们将任一索引页中的索引项按哈希码排序,从而可以在索引页内使用二分查找。但请注意,并不假定同一桶中不同索引页之间的哈希码具有任何相对顺序。 + 被索引表中的每一行,都由 hash 索引中的单个索引元组表示。Hash 索引元组存储在桶页中,如果存在溢出页,也会存储在溢出页中。为了加快搜索速度,我们将任一索引页中的索引项按 hash 码排序,从而可以在索引页内使用二分查找。但请注意,并不假定同一桶中不同索引页之间的 hash 码具有任何相对顺序。 - 用于扩展哈希索引的桶拆分算法过于复杂,这里不再展开说明;但在src/backend/access/hash/README中有更详细的描述。该拆分算法具备崩溃安全性,如果未能成功完成,可以重新启动。 + 用于扩展 hash 索引的桶拆分算法过于复杂,这里不再展开说明;但在src/backend/access/hash/README中有更详细的描述。该拆分算法具备崩溃安全性,如果未能成功完成,可以重新启动。 diff --git a/zh/20/high-availability.sgml b/zh/20/high-availability.sgml index dec68970..005990d6 100644 --- a/zh/20/high-availability.sgml +++ b/zh/20/high-availability.sgml @@ -19,7 +19,7 @@ - 某些方案通过只允许一台服务器修改数据来处理同步。能够修改数据的服务器称为读/写、主库(master)主库(primary)服务器。跟踪主库变更的服务器称为备库。只能在被提升为主库之后才能连接的备库称为温备,而能够接受连接并提供只读查询的备库称为热备。 + 某些方案通过只允许一台服务器修改数据来处理同步。能够修改数据的服务器称为读/写、主库(master)主库(primary)服务器。跟踪主库变更的服务器称为备库(standby)备库(secondary)。只能在被提升为主库之后才能连接的备库称为温备,而能够接受连接并提供只读查询的备库称为热备 @@ -102,7 +102,7 @@ protocol to make nodes agree on a serializable transactional order. - 基于触发器的主库-备库复制 + 基于触发器的主备复制 @@ -238,7 +238,7 @@ protocol to make nodes agree on a serializable transactional order. - 主库无额外负载 + 主库无额外开销 @@ -354,7 +354,7 @@ protocol to make nodes agree on a serializable transactional order. - 连续归档可用于创建一种高可用性(HA)集簇配置,其中有一个或多个备库随时准备在主库失效时接管操作。这种能力通常称为温备日志传送。 + 持续归档可用于创建一种高可用性(HA)集簇配置,其中有一个或多个备库随时准备在主库失效时接管操作。这种能力通常称为温备日志传送 @@ -534,7 +534,7 @@ archive_cleanup_command = 'pg_archivecleanup /path/to/archive "%r"' 认证 - 正确设置复制访问权限非常重要,因为从 WAL 流中很容易提取出需要权限才能访问的信息,因此必须确保只有受信任的用户才能读取它。备库必须以具有 REPLICATION 权限的账户或超级用户身份向主库认证。建议专门创建一个具有 REPLICATIONLOGIN 权限的用户账户用于复制。虽然 REPLICATION 权限的权限很高,但它并不允许用户修改主系统上的任何数据,而 SUPERUSER 权限则允许。 + 正确设置复制访问权限非常重要,因为从 WAL 流中很容易提取出需要权限才能访问的信息,因此必须确保只有受信任的用户才能读取它。备库必须以具有 REPLICATION 权限的账户或超级用户身份向主库认证。建议专门创建一个具有 REPLICATIONLOGIN 权限的用户账户用于复制。虽然 REPLICATION 权限很高,但它并不允许用户修改主系统上的任何数据,而 SUPERUSER 权限则允许。 @@ -565,7 +565,7 @@ primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass' 流复制的一个重要健康指标,是主库上已经生成但尚未在备库上应用的 WAL 记录量。你可以通过比较主库上的当前 WAL 写入位置和备库收到的最后一个 WAL 位置来计算这种滞后。这些位置分别可以用主库上的 pg_current_wal_lsn 和备库上的 pg_last_wal_receive_lsn 取得(详见 )。备库上的最后一个 WAL 接收位置也会显示在 WAL 接收进程的进程状态中,即通过 ps 命令显示的状态(详见 )。 - 你可以通过 pg_stat_replication 视图取得 WAL 发送进程列表。pg_current_wal_lsn 与该视图的 sent_lsn 字段之间存在较大差异,可能表示主库负载很重;而 sent_lsn 与备库上的 pg_last_wal_receive_lsn 之间存在较大差异,则可能表示网络延迟,或者备库负载很重。 + 你可以通过 pg_stat_replication 视图取得 WAL 发送进程列表。pg_current_wal_lsn 与该视图的 sent_lsn 字段之间存在较大差异,可能表示主库负载很重;而 sent_lsn 与备库上的 pg_last_wal_receive_lsn 之间存在差异,则可能表示网络延迟,或者备库负载很重。 在热备上,WAL 接收进程的状态可以通过 @@ -583,13 +583,13 @@ primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass' 流复制 - 复制槽提供了一种自动化方法,以确保主库不会删除 WAL 段,直到所有备库/订阅者都已经接收了它们,无论是物理接收还是逻辑接收;并且即使备库断开连接,主库也不会删除可能在物理副本上导致恢复冲突的行。 + 复制槽提供了一种自动化方法,以确保主库不会删除 WAL 段,直到所有备库/订阅者都已经接收了它们,无论是物理接收还是逻辑接收;并且即使备库断开连接,主库也不会删除那些一旦删除就可能在物理副本上导致恢复冲突的行。 如果不使用复制槽,也可以通过阻止旧的 WAL 段被移除,或者通过把这些段保存到归档中。这些方法的一个缺点是,它们通常会保留多于实际所需数量的 WAL 段,而复制槽只会保留已知确实需要的段数。 - 类似地,如果不配合物理复制槽单独使用 ,它虽然能防止相关的行被清理而避免因清理产生的问题,但在物理复制备库未连接的那段时间内并不能提供保护。 + 类似地,如果不配合物理复制槽单独使用 ,它虽然能防止相关的行被清理移除,但在物理复制备库未连接的那段时间内并不能提供保护。 @@ -693,7 +693,7 @@ primary_slot_name = 'node_a_slot' - 只读事务和事务回滚不需要等待备库的回应。子事务提交也不需要等待备库响应,只有顶层提交才需要等待。数据装载或索引构建等长时间运行的动作,不会一直等到最终提交消息。所有两阶段提交操作都需要等待提交,包括 prepare 和 commit。 + 只读事务和事务回滚不需要等待备库的回应。子事务提交也不需要等待备库响应,只有顶层提交才需要等待。数据装载或索引构建等长时间运行的动作,直到最终提交时才会等待。所有两阶段提交操作都需要等待提交,包括准备和提交两个阶段。 @@ -708,7 +708,7 @@ primary_slot_name = 'node_a_slot' - 当提交记录已经在主库上写入磁盘之后,WAL 记录就会被发送到备库。每当新的一批 WAL 数据被写入磁盘时,备库就会发送回复消息,除非备库上的wal_receiver_status_interval被设置为零。如果synchronous_commit被设置为remote_apply,那么备库会在提交记录被重放时发送回复消息,从而使该事务变得可见。如果根据主库上的synchronous_standby_names设置,该备库被选为同步备库,那么它发出的回复会与其他同步备库的回复一起,用于决定何时释放那些正在等待确认提交记录已被收到的事务。这些参数允许管理员指定哪些备库应作为同步备库。注意,同步复制的配置主要在主库上进行。被命名的备库必须直接连接到主库;主库并不知道使用级联复制的下游备库。 + 当提交记录已经在主库上写入磁盘之后,WAL 记录就会被发送到备库。每当新的一批 WAL 数据被写入磁盘时,备库就会发送回复消息,除非备库上的wal_receiver_status_interval被设置为零。如果synchronous_commit被设置为remote_apply,那么备库会在提交记录被重放、该事务变得可见时发送回复消息。如果根据主库上的synchronous_standby_names设置,该备库被选为同步备库,那么它发出的回复会与其他同步备库的回复一起,用于决定何时释放那些正在等待确认提交记录已被收到的事务。这些参数允许管理员指定哪些备库应作为同步备库。注意,同步复制的配置主要在主库上进行。被命名的备库必须直接连接到主库;主库并不知道使用级联复制的下游备库。 @@ -742,14 +742,14 @@ synchronous_standby_names = 'FIRST 2 (s1, s2, s3)' 在这个例子中,如果四台备库s1s2s3s4都在运行,则s1s2会被选为同步备库,因为它们的名字在备库名称列表中出现得更早。s3是潜在的同步备库,当s1s2中的任意一台失效时,它就会接替其角色。由于s4的名称不在列表中,因此它是异步备库。 - ANY方法指定基于法定人数的同步复制,使事务提交等待,直到它们的 WAL 记录被复制到列表中所要求数量的同步备库中的至少这么多台。 + ANY方法指定基于法定人数的同步复制,使事务提交等待,直到它们的 WAL 记录被复制到列表中至少所要求数量的同步备库。 基于法定人数的多同步备库的synchronous_standby_names示例如下: synchronous_standby_names = 'ANY 2 (s1, s2, s3)' - 在这个例子中,如果四台备库s1s2s3s4都在运行,事务提交将等待来自s1s2s3中的任意两台备库的回复。由于s4的名字不在列表中,因此它是异步备库。 + 在这个例子中,如果四台备库s1s2s3s4都在运行,事务提交将等待来自s1s2s3中的至少任意两台备库的回复。由于s4的名字不在列表中,因此它是异步备库。 备库的同步状态可以通过pg_stat_replication视图查看。 @@ -772,7 +772,7 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' - 通过在应用级别(在主库上)指定同步复制选项,我们可以只对最重要的变更提供同步复制,而不会拖慢整体工作负载。应用级别选项是让高性能应用获得同步复制收益的一种重要而实用的工具。 + 通过在应用级别(在主库上)指定同步复制选项,我们可以只对最重要的变更提供同步复制,而不会拖慢大部分工作负载。应用级别选项是让高性能应用获得同步复制收益的一种重要而实用的工具。 @@ -805,7 +805,7 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' - 如果主库在提交正等待确认时重启,这些等待中的事务会在主库恢复后被标记为已完全提交。无法确定在主库崩溃时,所有备库是否已经收到全部尚未处理的 WAL 数据。因此,某些事务可能不会在备库上显示为已提交,即使它们在主库上显示为已提交。我们所提供的保证是:只有在确认 WAL 数据已经被所有同步备库安全接收之后,应用才会收到事务成功提交的显式确认。 + 如果主库在提交正等待确认时重启,这些等待中的事务会在主库恢复后被标记为已完全提交。无法确定在主库崩溃时,所有备库是否已经收到全部待传送的 WAL 数据。因此,某些事务可能不会在备库上显示为已提交,即使它们在主库上显示为已提交。我们所提供的保证是:只有在确认 WAL 数据已经被所有同步备库安全接收之后,应用才会收到事务成功提交的显式确认。 @@ -900,7 +900,7 @@ postgres=# WAIT FOR LSN '0/306EE20'; - 一旦故障切换到备库,系统中就只剩下一台服务器在运行。这被称为退化状态。原来的备库现在成为主库,而原来的主库已经停机,并且可能持续停机。要恢复到正常运行状态,就必须重新创建一台备库:要么在原主库恢复后在其上重建,要么在第三台可能是全新的服务器上重建。在大型集簇上,可以使用工具来加快这一过程。一旦完成,就可以认为主库和备库已经交换了角色。有些人会选择使用第三台服务器,在新的备库重建完成之前为新的主库提供备份,但显然这会让系统配置和操作流程更加复杂。 + 一旦故障切换到备库,系统中就只剩下一台服务器在运行。这被称为退化状态。原来的备库现在成为主库,而原来的主库已经停机,并且可能持续停机。要恢复到正常运行状态,就必须重新创建一台备库:要么在原主库恢复后在其上重建,要么在第三台可能是全新的服务器上重建。在大型集簇上,可以使用工具来加快这一过程。一旦完成,就可以认为主库和备库已经交换了角色。有些人会选择使用第三台服务器,在新的备库重建完成之前为新的主库提供后备支持,但显然这会让系统配置和操作流程更加复杂。 @@ -963,7 +963,7 @@ postgres=# WAIT FOR LSN '0/306EE20'; - 事务管理命令: + 事务管理命令: @@ -977,7 +977,7 @@ postgres=# WAIT FOR LSN '0/306EE20'; - EXCEPTION块或其他内部子事务 + EXCEPTION块和其他内部子事务 @@ -1017,7 +1017,7 @@ postgres=# WAIT FOR LSN '0/306EE20'; 数据操纵语言(DML):INSERTUPDATEDELETEMERGECOPY FROM、 - TRUNCATE。请注意,恢复期间不存在任何允许执行触发器的动作。这个限制甚至适用于临时表,因为不分配事务 ID 就无法读取或写入表行,而这在热备环境中目前是不可能的。 + TRUNCATE。请注意,恢复期间不存在任何允许执行触发器的动作。这个限制甚至适用于临时表,因为不分配事务 ID 就无法读取或写入表行,而目前热备环境中无法分配事务 ID。 @@ -1052,13 +1052,13 @@ postgres=# WAIT FOR LSN '0/306EE20'; - BEGIN READ WRITE, + BEGIN READ WRITESTART TRANSACTION READ WRITE - SET TRANSACTION READ WRITE, + SET TRANSACTION READ WRITESET SESSION CHARACTERISTICS AS TRANSACTION READ WRITE @@ -1074,7 +1074,7 @@ postgres=# WAIT FOR LSN '0/306EE20'; 两阶段提交命令:PREPARE TRANSACTIONCOMMIT PREPAREDROLLBACK PREPARED, - 因为即使是只读事务,在 prepare 阶段(两阶段提交的第一阶段)也需要写入 WAL。 + 因为即使是只读事务,在准备阶段(两阶段提交的第一阶段)也需要写入 WAL。 @@ -1162,24 +1162,22 @@ postgres=# WAIT FOR LSN '0/306EE20'; - 一旦max_standby_archive_delaymax_standby_streaming_delay指定的延迟被超越,冲突查询将被取消。这通常仅导致一个取消错误,尽管在重放一个DROP DATABASE的情况下整个冲突会话都将被中断。另外,如果冲突发生在一个被空闲事务持有的锁上,该冲突会话会被中断(这种行为可能在未来被改变)。 + 一旦max_standby_archive_delaymax_standby_streaming_delay指定的延迟被超越,冲突查询将被取消。这通常仅导致一个取消错误,尽管在重放一个DROP DATABASE的情况下整个冲突会话都将被终止。另外,如果冲突发生在一个被空闲事务持有的锁上,该冲突会话会被终止(这种行为可能在未来被改变)。 - - 被取消的查询可能会立即被重试(当然是在开始一个新的事务后)。因为查询取消依赖于 WAL 记录被重放的本质,如果一个被取消的查询被再次执行,它可能会很好地成功完成。 - + 被取消的查询可以立即重试(当然,要先开始一个新事务)。由于查询取消取决于正在重放的 WAL 记录的性质,被取消的查询再次执行时完全可能成功。 - 记住延迟参数是从 WAL 数据被备库收到后流逝的时间。因此,留给备库上任何一个查询的宽限期从不会超过延迟参数,并且如果备库已经由于等待之前的查询完成而落后或者因为过重的更新负载而无法跟上主库,宽限期可能会更少。 + 请记住,延迟参数要与备库收到 WAL 数据之后经过的时间进行比较。因此,留给备库上任何一个查询的宽限期从不会超过延迟参数,并且如果备库已经由于等待之前的查询完成而落后或者因为过重的更新负载而无法跟上主库,宽限期可能会更少。 - 备库查询与 WAL 重放发生冲突的最常见原因是过早清理。正常情况下,当没有事务需要看到旧行版本时,PostgreSQL允许清理这些旧行版本,以保证按照 MVCC 规则得到正确的数据可见性。不过,这条规则只能应用于在主库上执行的事务。因此,主库上的清理有可能移除某个备库事务仍然可见的行版本。 + 备库查询与 WAL 重放发生冲突的最常见原因是过早清理。正常情况下,当不再有事务需要看到旧行版本来保证符合 MVCC 规则的数据可见性时,PostgreSQL允许清理这些旧行版本。不过,这条规则只能应用于在主库上执行的事务。因此,主库上的清理有可能移除某个备库事务仍然可见的行版本。 行版本清理并不是与备库查询发生冲突的唯一潜在原因。所有仅索引扫描(包括在备库上运行的那些)都必须使用一个MVCC快照,它与可见性映射一致。因此,每当VACUUM在可见性映射中把某个页面标记为全可见,而该页面中包含一行或多行对所有备库查询都不可见的数据时,就必须产生冲突。所以,即使针对一个没有更新或删除任何需要清理行的表执行VACUUM,也可能导致冲突。 + linkend="vacuum-for-visibility-map">在可见性映射中把某个页面标记为全可见,而该页面中包含并非对所有备库查询都可见的一行或多行数据时,就必须产生冲突。所以,即使针对一个没有需要清理的已更新或已删除行的表执行VACUUM,也可能导致冲突。 @@ -1282,7 +1280,7 @@ HINT: You can then restart the server after making the necessary configuration - 主库上写出的事务状态 "hint bits" 不会被 WAL 记录,因此备库上的数据很可能会再次写出这些提示位。这样一来,即使所有用户都是只读的,备库仍然会执行磁盘写操作;不过数据值本身并不会发生变化。用户仍然会写出大型排序临时文件,并重新生成 relcache 信息文件,因此在热备模式下,数据库没有任何部分是真正只读的。还要注意,使用dblink模块写入远程数据库,以及借助 PL 函数执行其他数据库外部操作,依然是可能的,即使该事务在本地是只读的。 + 主库上写出的事务状态“提示位” 不会被 WAL 记录,因此备库上的数据很可能会再次写出这些提示位。这样一来,即使所有用户都是只读的,备库仍然会执行磁盘写操作;不过数据值本身并不会发生变化。用户仍然会写出大型排序临时文件,并重新生成 relcache 信息文件,因此在热备模式下,数据库没有任何部分是真正只读的。还要注意,使用dblink模块写入远程数据库,以及借助 PL 函数执行其他数据库外部操作,依然是可能的,即使该事务在本地是只读的。 @@ -1291,7 +1289,7 @@ HINT: You can then restart the server after making the necessary configuration - 数据定义语言:例如 CREATE INDEX + 数据定义语言(DDL):例如 CREATE INDEX diff --git a/zh/20/images/fixup-svg.xsl b/zh/20/images/fixup-svg.xsl index d6c46b36..cf7169bb 100644 --- a/zh/20/images/fixup-svg.xsl +++ b/zh/20/images/fixup-svg.xsl @@ -32,6 +32,11 @@ Fix stroke="transparent" attribute, which is invalid SVG. none + + + 'Alibaba PuHuiTi 3.0',serif + + diff --git a/zh/20/images/gin.gv b/zh/20/images/gin.gv index 097e9102..b8e26542 100644 --- a/zh/20/images/gin.gv +++ b/zh/20/images/gin.gv @@ -1,11 +1,12 @@ digraph "gin" { layout=dot; - node [label="", shape=box, style=filled, fillcolor=gray, width=1.4]; + fontname="Alibaba PuHuiTi 3.0"; + node [fontname="Alibaba PuHuiTi 3.0", label="", shape=box, style=filled, fillcolor=gray, width=1.4]; - m1 [label="meta page"]; + m1 [label="元页"]; subgraph cluster01 { - label="entry tree"; + label="键项树"; subgraph egroup1 { rank=same; e1; @@ -27,13 +28,13 @@ digraph "gin" { e4 -> e8; e4 -> e9; - e6 [fillcolor=green, label="posting list"]; - e8 [fillcolor=green, label="posting list"]; - e9 [fillcolor=green, label="posting list"]; + e6 [fillcolor=green, label="倒排列表"]; + e8 [fillcolor=green, label="倒排列表"]; + e9 [fillcolor=green, label="倒排列表"]; } subgraph cluster02 { - label="posting tree"; + label="倒排树"; subgraph pgroup1 { rank=same; p1; @@ -45,22 +46,22 @@ digraph "gin" { p1 -> p2; p1 -> p3; - p2 [fillcolor=green, label="heap ptr"]; - p3 [fillcolor=green, label="heap ptr"]; + p2 [fillcolor=green, label="堆指针"]; + p3 [fillcolor=green, label="堆指针"]; } subgraph cluster03 { - label="posting tree"; + label="倒排树"; subgraph pgroup3 { rank=same; p4; } - p4 [fillcolor=green, label="heap ptr"]; + p4 [fillcolor=green, label="堆指针"]; } subgraph cluster04 { - label="posting tree"; + label="倒排树"; subgraph pgroup4 { rank=same; p5; @@ -72,12 +73,12 @@ digraph "gin" { p5 -> p6; p5 -> p7; - p6 [fillcolor=green, label="heap ptr"]; - p7 [fillcolor=green, label="heap ptr"]; + p6 [fillcolor=green, label="堆指针"]; + p7 [fillcolor=green, label="堆指针"]; } subgraph cluster05 { - label="pending list"; + label="待处理列表"; node [style=filled, fillcolor=red]; n1 -> n2 -> n3 -> n4; } diff --git a/zh/20/images/gin.svg b/zh/20/images/gin.svg index 04fe85ba..79cf14a9 100644 --- a/zh/20/images/gin.svg +++ b/zh/20/images/gin.svg @@ -9,33 +9,33 @@ cluster01 -entry tree +键项树 cluster02 -posting tree +倒排树 cluster03 -posting tree +倒排树 cluster04 -posting tree +倒排树 cluster05 -pending list +待处理列表 m1 -meta page +元页 @@ -113,7 +113,7 @@ e6 -posting list +倒排列表 @@ -142,7 +142,7 @@ e8 -posting list +倒排列表 @@ -154,7 +154,7 @@ e9 -posting list +倒排列表 @@ -195,7 +195,7 @@ p4 -heap ptr +堆指针 @@ -224,7 +224,7 @@ p2 -heap ptr +堆指针 @@ -236,7 +236,7 @@ p3 -heap ptr +堆指针 @@ -254,7 +254,7 @@ p6 -heap ptr +堆指针 @@ -266,7 +266,7 @@ p7 -heap ptr +堆指针 diff --git a/zh/20/images/temporal-isolation.svg b/zh/20/images/temporal-isolation.svg index 9bde2fc9..690b3e29 100644 --- a/zh/20/images/temporal-isolation.svg +++ b/zh/20/images/temporal-isolation.svg @@ -32,16 +32,16 @@ - 会话 1 + 会话 1 UPDATE; - 等待…… + 等待…… BEGIN; BEGIN; - 会话 2 + 会话 2 UPDATE; COMMIT; COMMIT; - ……继续 - 重新检查 + ……继续 + 重新检查 diff --git a/zh/20/indexam.sgml b/zh/20/indexam.sgml index fbadeb80..41e661ed 100644 --- a/zh/20/indexam.sgml +++ b/zh/20/indexam.sgml @@ -21,7 +21,7 @@ - 索引本质上是从一些数据键值到行版本(元组)在索引父表中的元组标识符TID)的映射。一个 TID 由块号以及该块中的项号组成(见 元组标识符(TIDs)的映射。一个 TID 由块号以及该块中的项号组成(见 )。这些信息足以从表中取出某个特定的行版本。索引并不直接知道在 MVCC 之下同一逻辑行可能会存在多个现存版本;对索引来说,每个元组都是一个独立对象,需要它自己的索引条目。因此,对一行的更新总会为该行创建全新的索引条目,即使键值并未改变也是如此。(HOT 元组是这一说法的例外;但索引同样不直接处理它们。)当死元组自身被回收时(通过清理),它们对应的索引条目也会被回收。 @@ -44,89 +44,89 @@ typedef struct IndexAmRoutine NodeTag type; /* - * Total number of strategies (operators) by which we can traverse/search - * this AM. Zero if AM does not have a fixed set of strategy assignments. + * 可用于遍历或搜索此 AM 的策略(操作符)总数。 + * 如果 AM 没有固定的一组策略分配,则为零。 */ uint16 amstrategies; - /* total number of support functions that this AM uses */ + /* 此 AM 使用的支持函数总数 */ uint16 amsupport; - /* opclass options support function number or 0 */ + /* 操作符类选项支持函数编号,或为 0 */ uint16 amoptsprocnum; - /* does AM support ORDER BY indexed column's value? */ + /* AM 是否支持按被索引列的值进行 ORDER BY? */ bool amcanorder; - /* does AM support ORDER BY result of an operator on indexed column? */ + /* AM 是否支持按被索引列上操作符的结果进行 ORDER BY? */ bool amcanorderbyop; - /* does AM support hashing using API consistent with the hash AM? */ + /* AM 是否支持使用与 hash AM 一致的 API 进行哈希? */ bool amcanhash; - /* do operators within an opfamily have consistent equality semantics? */ + /* 操作符族内的操作符是否具有一致的相等语义? */ bool amconsistentequality; - /* do operators within an opfamily have consistent ordering semantics? */ + /* 操作符族内的操作符是否具有一致的排序语义? */ bool amconsistentordering; - /* does AM support backward scanning? */ + /* AM 是否支持反向扫描? */ bool amcanbackward; - /* does AM support UNIQUE indexes? */ + /* AM 是否支持 UNIQUE 索引? */ bool amcanunique; - /* does AM support multi-column indexes? */ + /* AM 是否支持多列索引? */ bool amcanmulticol; - /* does AM require scans to have a constraint on the first index column? */ + /* AM 是否要求扫描必须约束第一个索引列? */ bool amoptionalkey; - /* does AM handle ScalarArrayOpExpr quals? */ + /* AM 是否处理 ScalarArrayOpExpr 限定条件? */ bool amsearcharray; - /* does AM handle IS NULL/IS NOT NULL quals? */ + /* AM 是否处理 IS NULL/IS NOT NULL 限定条件? */ bool amsearchnulls; - /* can index storage data type differ from column data type? */ + /* 索引存储数据类型是否可以不同于列数据类型? */ bool amstorage; - /* can an index of this type be clustered on? */ + /* 是否可以按此类型的索引进行聚簇? */ bool amclusterable; - /* does AM handle predicate locks? */ + /* AM 是否处理谓词锁? */ bool ampredlocks; - /* does AM support parallel scan? */ + /* AM 是否支持并行扫描? */ bool amcanparallel; - /* does AM support parallel build? */ + /* AM 是否支持并行构建? */ bool amcanbuildparallel; - /* does AM support columns included with clause INCLUDE? */ + /* AM 是否支持由 INCLUDE 子句包含的列? */ bool amcaninclude; - /* does AM use maintenance_work_mem? */ + /* AM 是否使用 maintenance_work_mem? */ bool amusemaintenanceworkmem; - /* does AM summarize tuples, with at least all tuples in the block - * summarized in one summary */ + /* AM 是否对元组进行摘要,且一个摘要至少涵盖 + * 块中的所有元组? */ bool amsummarizing; - /* OR of parallel vacuum flags */ + /* 并行清理标志的 OR 组合 */ uint8 amparallelvacuumoptions; - /* type of data stored in index, or InvalidOid if variable */ + /* 索引中存储的数据类型;如果可变,则为 InvalidOid */ Oid amkeytype; - /* interface functions */ + /* 接口函数 */ ambuild_function ambuild; ambuildempty_function ambuildempty; aminsert_function aminsert; - aminsertcleanup_function aminsertcleanup; /* can be NULL */ + aminsertcleanup_function aminsertcleanup; /* 可以为 NULL */ ambulkdelete_function ambulkdelete; amvacuumcleanup_function amvacuumcleanup; - amcanreturn_function amcanreturn; /* can be NULL */ + amcanreturn_function amcanreturn; /* 可以为 NULL */ amcostestimate_function amcostestimate; - amgettreeheight_function amgettreeheight; /* can be NULL */ + amgettreeheight_function amgettreeheight; /* 可以为 NULL */ amoptions_function amoptions; - amproperty_function amproperty; /* can be NULL */ - ambuildphasename_function ambuildphasename; /* can be NULL */ + amproperty_function amproperty; /* 可以为 NULL */ + ambuildphasename_function ambuildphasename; /* 可以为 NULL */ amvalidate_function amvalidate; - amadjustmembers_function amadjustmembers; /* can be NULL */ + amadjustmembers_function amadjustmembers; /* 可以为 NULL */ ambeginscan_function ambeginscan; amrescan_function amrescan; - amgettuple_function amgettuple; /* can be NULL */ - amgetbitmap_function amgetbitmap; /* can be NULL */ + amgettuple_function amgettuple; /* 可以为 NULL */ + amgetbitmap_function amgetbitmap; /* 可以为 NULL */ amendscan_function amendscan; - ammarkpos_function ammarkpos; /* can be NULL */ - amrestrpos_function amrestrpos; /* can be NULL */ + ammarkpos_function ammarkpos; /* 可以为 NULL */ + amrestrpos_function amrestrpos; /* 可以为 NULL */ - /* interface functions to support parallel index scans */ - amestimateparallelscan_function amestimateparallelscan; /* can be NULL */ - aminitparallelscan_function aminitparallelscan; /* can be NULL */ - amparallelrescan_function amparallelrescan; /* can be NULL */ + /* 支持并行索引扫描的接口函数 */ + amestimateparallelscan_function amestimateparallelscan; /* 可以为 NULL */ + aminitparallelscan_function aminitparallelscan; /* 可以为 NULL */ + amparallelrescan_function amparallelrescan; /* 可以为 NULL */ - /* interface functions to support planning */ - amtranslate_strategy_function amtranslatestrategy; /* can be NULL */ - amtranslate_cmptype_function amtranslatecmptype; /* can be NULL */ + /* 支持规划的接口函数 */ + amtranslate_strategy_function amtranslatestrategy; /* 可以为 NULL */ + amtranslate_cmptype_function amtranslatecmptype; /* 可以为 NULL */ } IndexAmRoutine; @@ -148,7 +148,7 @@ typedef struct IndexAmRoutine - amsummarizing 标志指示该访问方法是否会对被索引元组做摘要,并且摘要粒度至少达到每个块一个摘要。不指向单个元组,而是指向块范围(例如 BRIN)的访问方法,可能允许继续使用 HOT 优化。这不适用于索引谓词中引用的属性,对这类属性的更新总会禁用 HOT。 + amsummarizing 标志指示该访问方法是否会对被索引元组做摘要,并且摘要粒度至少为一个块。不指向单个元组,而是指向块范围(例如 BRIN)的访问方法,可能允许继续使用 HOT 优化。这不适用于索引谓词中引用的属性,对这类属性的更新总会禁用 HOT @@ -215,7 +215,7 @@ void aminsertcleanup (Relation indexRelation, IndexInfo *indexInfo); - 清理由 indexInfo->ii_AmCache 在连续插入之间维护的状态。如果这些数据需要额外的清理步骤(例如释放已钉住的缓冲区),而仅释放内存还不够,那么这个函数就很有用。 + 清理在 indexInfo->ii_AmCache 中跨连续插入维护的状态。如果这些数据需要额外的清理步骤(例如释放已钉住的缓冲区),而仅释放内存还不够,那么这个函数就很有用。 @@ -226,7 +226,7 @@ ambulkdelete (IndexVacuumInfo *info, IndexBulkDeleteCallback callback, void *callback_state); - 从索引中删除元组。这是一个批量删除操作,通常应通过扫描整个索引并检查每个条目是否应被删除来实现。必须调用传入的 callback 函数,其调用形式为 callback(TID, callback_state) returns bool,以确定由其引用 TID 标识的某个索引条目是否应删除。该函数必须返回 NULL,或者返回一个通过 palloc 分配的结构体,其中包含此次删除操作影响的统计信息。如果不需要向 amvacuumcleanup 传递信息,返回 NULL 也是可以的。 + 从索引中删除元组。这是一个批量删除操作,旨在通过扫描整个索引并检查每个条目是否应被删除来实现。必须调用传入的 callback 函数,其调用形式为 callback(TID, callback_state) returns bool,以确定由其引用 TID 标识的某个索引条目是否应删除。该函数必须返回 NULL,或者返回一个通过 palloc 分配的结构体,其中包含此次删除操作影响的统计信息。如果不需要向 amvacuumcleanup 传递信息,返回 NULL 也是可以的。 @@ -251,8 +251,7 @@ amvacuumcleanup (IndexVacuumInfo *info, bool amcanreturn (Relation indexRelation, int attno); - 检查索引是否能够在给定列上支持 仅索引扫描,做法是返回该列原始的被索引值。属性编号从 1 开始,也就是说第一列的 attno 为 1。若支持则返回真,否则返回假。如果支持包含列,这个函数应始终对包含列返回真,因为不能取回的包含列几乎没有意义。如果访问方法根本不支持仅索引扫描,那么它的 IndexAmRoutine 结构体中的 amcanreturn 字段可以设为 NULL。 + 检查索引能否通过返回给定列原始的被索引值,在该列上支持 仅索引扫描。属性编号从 1 开始,也就是说第一列的 attno 为 1。若支持则返回真,否则返回假。如果支持包含列,这个函数应始终对包含列返回真,因为不能取回的包含列几乎没有意义。如果访问方法根本不支持仅索引扫描,那么它的 IndexAmRoutine 结构体中的 amcanreturn 字段可以设为 NULL。 @@ -267,7 +266,7 @@ amcostestimate (PlannerInfo *root, double *indexCorrelation, double *indexPages); - 估计一次索引扫描的开销。该函数将在后面的 中详细讨论。 + 估计一次索引扫描的代价。该函数将在后面的 中详细讨论。 @@ -275,7 +274,7 @@ amcostestimate (PlannerInfo *root, int amgettreeheight (Relation rel); - 计算树形索引的高度。这一信息会通过 path->indexinfo->tree_height 提供给 amcostestimate 函数,可用于支持开销估计。其结果不会在其他地方使用,因此这个函数实际上也可以用来计算索引上任何一种适合装入整数、且开销估计函数可能想知道的数据。如果计算代价较高,把结果缓存到 RelationData.rd_amcache 中可能会有用。 + 计算树形索引的高度。这一信息会通过 path->indexinfo->tree_height 提供给 amcostestimate 函数,可用于支持代价估算。其结果不会在其他地方使用,因此这个函数实际上也可以用来计算索引上任何一种适合装入整数、且代价估算函数可能想知道的数据。如果计算代价较高,把结果缓存到 RelationData.rd_amcache 中可能会有用。 @@ -284,7 +283,7 @@ bytea * amoptions (ArrayType *reloptions, bool validate); - 解析并验证索引的 reloptions 数组。只有当该索引存在非空的 reloptions 数组时才会调用此函数。reloptions 是一个 text 数组,其中的条目形如 name=value。该函数应构造一个 bytea 值,并将其复制到索引 relcache 条目的 rd_options 字段中。这个 bytea 值中的数据内容由访问方法自行定义;大多数标准访问方法使用结构体 StdRdOptions。当 validate 为真时,若存在未识别选项或无效取值,函数应报告合适的错误消息;当 validate 为假时,无效条目应被静默忽略。(当装载已存储在 pg_catalog 中的选项时,validate 为假;此时只有在访问方法改变了选项规则时才可能发现无效条目,而忽略过时条目是合适的。)如果希望采用默认行为,返回 NULL 也是可以的。 + 解析并验证索引的 reloptions 数组。只有当该索引存在非 NULL 的 reloptions 数组时才会调用此函数。reloptions 是一个 text 数组,其中的条目形如 name=value。该函数应构造一个 bytea 值,并将其复制到索引 relcache 条目的 rd_options 字段中。这个 bytea 值中的数据内容由访问方法自行定义;大多数标准访问方法使用结构体 StdRdOptions。当 validate 为真时,若存在未识别选项或无效取值,函数应报告合适的错误消息;当 validate 为假时,无效条目应被静默忽略。(当装载已存储在 pg_catalog 中的选项时,validate 为假;此时只有在访问方法改变了选项规则时才可能发现无效条目,而忽略过时条目是合适的。)如果希望采用默认行为,返回 NULL 也是可以的。 @@ -298,7 +297,7 @@ amproperty (Oid index_oid, int attno, - 支持排序操作符的访问方法应当实现 AMPROP_DISTANCE_ORDERABLE 属性测试,因为核心代码不知道如何完成该测试,只会返回 NULL。若实现成本低于打开索引并调用 amcanreturn(这正是核心代码的默认行为),那么实现 AMPROP_RETURNABLE 测试也可能是有利的。对于其他所有标准属性,默认行为应当已经足够。 + 支持排序操作符的访问方法应当实现 AMPROP_DISTANCE_ORDERABLE 属性测试,因为核心代码不知道如何完成该测试,只会返回 NULL。若完成该测试的代价低于打开索引并调用 amcanreturn(这正是核心代码的默认行为),那么实现 AMPROP_RETURNABLE 测试也可能是有利的。对于其他所有标准属性,默认行为应当已经足够。 @@ -360,11 +359,11 @@ bool amgettuple (IndexScanDesc scan, ScanDirection direction); - 在给定扫描中取出下一个元组,并按给定方向移动(在索引中向前或向后)。若成功取得元组则返回真;若不再有匹配元组则返回假。在返回真时,元组的 TID 会存入 scan 结构体中。请注意,成功仅表示索引中存在一个匹配扫描键的条目,并不表示该元组一定仍然存在于堆中,或者一定能通过调用者的快照测试。成功时,amgettuple 还必须把 scan->xs_recheck 设为真或假。假表示可以确定该索引条目匹配扫描键;真表示这一点并不确定,因此在取到堆元组后必须根据扫描键所代表的条件重新检查它。这一机制支持有损索引操作符。请注意,重检只会扩展到扫描条件;部分索引谓词(如果有)永远不会由 amgettuple 的调用者重新检查。 + 在给定扫描中取出下一个元组,并按给定方向移动(在索引中向前或向后)。若成功取得元组则返回真;若不再有匹配元组则返回假。在返回真时,元组的 TID 会存入 scan 结构体中。请注意,成功仅表示索引中存在一个匹配扫描键的条目,并不表示该元组一定仍然存在于堆中,或者一定能通过调用者的快照测试。成功时,amgettuple 还必须把 scan->xs_recheck 设为真或假。假表示可以确定该索引条目匹配扫描键;真表示这一点并不确定,因此在取到堆元组后必须根据扫描键所代表的条件重新检查它。这一机制支持有损索引操作符。请注意,重检只针对扫描条件;部分索引谓词(如果有)永远不会由 amgettuple 的调用者重新检查。 - 如果索引支持 仅索引扫描(即其任一列上 amcanreturn 返回真),那么成功时 AM 还必须检查 scan->xs_want_itup;若其为真,就必须返回该索引条目的原始被索引数据。对于 amcanreturn 返回假的列,可以把其值作为 NULL 返回。数据可以通过以下两种形式之一返回:一种是把 IndexTuple 指针存入 scan->xs_itup,其元组描述符为 scan->xs_itupdesc;另一种是把 HeapTuple 指针存入 scan->xs_hitup,其元组描述符为 scan->xs_hitupdesc。(当重建出的数据可能装不进 IndexTuple 时,应使用后一种格式。)无论采用哪种形式,指针所引用数据的管理责任都在访问方法一侧。对这份数据的有效性必须至少保持到该扫描下一次调用 amgettupleamrescanamendscan 为止。 + 如果索引支持 仅索引扫描(即其至少一列上 amcanreturn 返回真),那么成功时 AM 还必须检查 scan->xs_want_itup;若其为真,就必须返回该索引条目的原始被索引数据。对于 amcanreturn 返回假的列,可以把其值作为 NULL 返回。数据可以通过以下两种形式之一返回:一种是把 IndexTuple 指针存入 scan->xs_itup,其元组描述符为 scan->xs_itupdesc;另一种是把 HeapTuple 指针存入 scan->xs_hitup,其元组描述符为 scan->xs_hitupdesc。(当重建出的数据可能装不进 IndexTuple 时,应使用后一种格式。)无论采用哪种形式,指针所引用数据的管理责任都在访问方法一侧。这份数据必须至少保持有效,直到该扫描下一次调用 amgettupleamrescanamendscan @@ -377,7 +376,7 @@ int64 amgetbitmap (IndexScanDesc scan, TIDBitmap *tbm); - 取出给定扫描中的所有元组,并将其加入调用者提供的 TIDBitmap 中(也就是把这组元组 ID 与位图中已有的集合做 OR)。返回值是取得的元组数量(这可能只是近似计数,例如某些 AM 不会检测重复项)。在把元组 ID 插入位图时,amgetbitmap 可以指出某些具体的元组 ID 需要重新检查扫描条件。这类似于 amgettuplexs_recheck 输出参数。注意:在当前实现中,对这一特性的支持与位图自身的有损存储支持混在一起,因此调用者会对可重检元组同时重新检查扫描条件和部分索引谓词(如果有)。不过,这并不一定永远如此。amgetbitmapamgettuple 不能在同一次索引扫描中同时使用;使用 amgetbitmap 时还有其他限制,详见 。 + 取出给定扫描中的所有元组,并将其加入调用者提供的 TIDBitmap 中(也就是把这组元组 ID 与位图中已有的集合做 OR)。返回值是取得的元组数量(这可能只是近似计数,例如某些 AM 不会检测重复项)。在把元组 ID 插入位图时,amgetbitmap 可以指出某些具体的元组 ID 需要重新检查扫描条件。这类似于 amgettuplexs_recheck 输出参数。注意:在当前实现中,对这一特性的支持与位图自身的有损存储支持混在一起,因此调用者会对需要重检的元组同时重新检查扫描条件和部分索引谓词(如果有)。不过,这并不一定永远如此。amgetbitmapamgettuple 不能在同一次索引扫描中同时使用;使用 amgetbitmap 时还有其他限制,详见 @@ -389,7 +388,7 @@ amgetbitmap (IndexScanDesc scan, void amendscan (IndexScanDesc scan); - 结束一次扫描并释放资源。scan 结构体本身不应被释放,但访问方法内部获取的任何锁或 pin,以及由 ambeginscan 和其他扫描相关函数分配的其他内存,都必须被释放。 + 结束一次扫描并释放资源。scan 结构体本身不应被释放,但必须释放访问方法内部获取的所有锁、解除所有钉住状态,并释放由 ambeginscan 和其他扫描相关函数分配的其他内存。 @@ -524,7 +523,7 @@ amtranslatecmptype (CompareType cmptype, Oid opfamily, Oid opcintype); - 除了使用 amgettuple 外,索引扫描也可以使用 amgetbitmap,在一次调用中取出所有元组。与 amgettuple 相比,这通常明显更高效,因为它可以避免访问方法内部的反复加锁和解锁。原则上,amgetbitmap 应具有与重复调用 amgettuple 相同的效果,但为了简化实现,我们施加了若干限制。首先,amgetbitmap 一次性返回全部元组,因此不支持标记或恢复扫描位置。其次,元组是通过一个位图返回的,没有特定顺序,这也是为什么 amgetbitmap 不带 direction 参数的原因。(这种扫描也永远不会提供排序操作符。)此外,使用 amgetbitmap 时也没有仅索引扫描的支持,因为没有办法返回索引元组的内容。最后,amgetbitmap 不保证对返回的元组做任何锁定,其影响见 。 + 除了使用 amgettuple 外,索引扫描也可以使用 amgetbitmap,在一次调用中取出所有元组。与 amgettuple 相比,这可能明显更高效,因为它可以避免访问方法内部的反复加锁和解锁。原则上,amgetbitmap 应具有与重复调用 amgettuple 相同的效果,但为了简化实现,我们施加了若干限制。首先,amgetbitmap 一次性返回全部元组,因此不支持标记或恢复扫描位置。其次,元组是通过一个位图返回的,没有特定顺序,这也是为什么 amgetbitmap 不带 direction 参数的原因。(这种扫描也永远不会提供排序操作符。)此外,使用 amgetbitmap 时也没有仅索引扫描的支持,因为没有办法返回索引元组的内容。最后,amgetbitmap 不保证对返回的元组做任何锁定,其影响见 @@ -541,7 +540,7 @@ amtranslatecmptype (CompareType cmptype, Oid opfamily, Oid opcintype); - 构建一种支持并发更新的索引类型,通常需要对所需行为进行大量而细致的分析。对于 B-树和哈希索引类型,可以阅读 src/backend/access/nbtree/READMEsrc/backend/access/hash/README 中涉及的设计决策。 + 构建一种支持并发更新的索引类型,通常需要对所需行为进行大量而细致的分析。对于 B-树和 hash 索引类型,可以阅读 src/backend/access/nbtree/READMEsrc/backend/access/hash/README 中涉及的设计决策。 @@ -560,12 +559,12 @@ amtranslatecmptype (CompareType cmptype, Oid opfamily, Oid opcintype); - 索引扫描必须在保存 amgettuple 最近一次返回条目的索引页面上维护一个 pin,而 ambulkdelete 不能从被其他后端钉住的页面中删除条目。下面会解释为什么需要这条规则。 + 索引扫描必须在保存 amgettuple 最近一次返回条目的索引页面上保持钉住状态,而 ambulkdelete 不能从被其他后端钉住的页面中删除条目。下面会解释为什么需要这条规则。 - 如果没有第三条规则,索引读取者就有可能在某个索引条目被 VACUUM 删除之前先看到它,然后在对应的堆条目已被 VACUUM 删除之后才到达那里。如果读取者到达时,该项号仍未被重新使用,就不会造成严重问题,因为空项槽位会被 heap_fetch() 忽略。但如果第三个后端已经把这个项槽位重新用作别的东西呢?在使用 MVCC 兼容快照时不会有问题,因为该槽位的新占用者一定太新,无法通过快照测试。然而,对于非 MVCC 兼容的快照(例如 SnapshotAny),就可能错误地接受并返回一行实际上并不匹配扫描键的数据。我们可以要求在所有情况下都对堆行重新检查扫描键,以防范这种情形,但那样代价太高。于是,我们改为把索引页面上的 pin 作为一种代理,表示读取者可能仍处于从索引条目前往匹配堆条目的飞行中。让 ambulkdelete 在这种 pin 上阻塞,能够保证 VACUUM 不会在读取者处理完之前删除对应的堆条目。这种方案运行时开销很小,只有在真正发生冲突的少数情况下才会增加阻塞开销。 + 如果没有第三条规则,索引读取者就有可能在某个索引条目被 VACUUM 删除之前先看到它,然后在对应的堆条目已被 VACUUM 删除之后才到达那里。如果读取者到达时,该项号仍未被重新使用,就不会造成严重问题,因为空项槽位会被 heap_fetch() 忽略。但如果第三个后端已经把这个项槽位重新用作别的东西呢?在使用 MVCC 兼容快照时不会有问题,因为该槽位的新占用者一定太新,无法通过快照测试。然而,对于非 MVCC 兼容的快照(例如 SnapshotAny),就可能错误地接受并返回一行实际上并不匹配扫描键的数据。我们可以要求在所有情况下都对堆行重新检查扫描键,以防范这种情形,但那样代价太高。于是,我们改为把索引页面的钉住状态作为一种代理,表示读取者从索引条目到匹配堆条目的访问过程可能仍在进行中。让 ambulkdelete 因这种钉住状态而阻塞,能够保证 VACUUM 不会在读取者处理完之前删除对应的堆条目。这种方案运行时开销很小,只有在真正发生冲突的少数情况下才会增加阻塞开销。 @@ -573,7 +572,7 @@ amtranslatecmptype (CompareType cmptype, Oid opfamily, Oid opcintype); - 在 amgetbitmap 索引扫描中,访问方法不会在任何返回的元组上保留索引 pin。因此,只有把这种扫描与 MVCC 兼容的快照一起使用才是安全的。 + 在 amgetbitmap 索引扫描中,访问方法不会为任何返回的元组保持索引页面的钉住状态。因此,只有把这种扫描与 MVCC 兼容的快照一起使用才是安全的。 @@ -612,7 +611,7 @@ amtranslatecmptype (CompareType cmptype, Oid opfamily, Oid opcintype); - 此外,在按照上述规则报告唯一性违背之前,访问方法必须立即重新检查正在插入那一行的存活性。如果它已经是提交后死亡的状态,就不应报告违背。(这种情况不会出现在插入由当前事务刚创建的行这一普通场景中,但在 CREATE UNIQUE INDEX CONCURRENTLY 期间却可能发生。) + 此外,就在按照上述规则报告唯一性违背之前,访问方法必须重新检查正在插入那一行的存活性。如果它已经是提交后死亡的状态,就不应报告违背。(这种情况不会出现在插入由当前事务刚创建的行这一普通场景中,但在 CREATE UNIQUE INDEX CONCURRENTLY 期间却可能发生。) @@ -620,7 +619,7 @@ amtranslatecmptype (CompareType cmptype, Oid opfamily, Oid opcintype); - 如果唯一约束是可延迟的,情况会更复杂:我们需要能够为新行插入一个索引条目,但把任何唯一性违背错误延迟到语句结束时甚至更晚才报告。为了避免对索引进行不必要的重复搜索,索引访问方法应在初始插入期间执行一次初步唯一性检查。如果这表明确实不存在冲突的存活元组,那么事情就结束了。否则,我们会安排在真正强制约束时再做一次重检。若在重检时,插入的元组与另外某个具有相同键值的元组都仍然存活,就必须报告错误。(注意,就此用途而言,存活实际上是指索引条目 HOT 链中的任一元组是存活的。)为实现这一点,传给 aminsert 函数的 checkUnique 参数会取以下值之一: + 如果唯一约束是可延迟的,情况会更复杂:我们需要能够为新行插入一个索引条目,但把任何唯一性违背错误延迟到语句结束时甚至更晚才报告。为了避免对索引进行不必要的重复搜索,索引访问方法应在初始插入期间执行一次初步唯一性检查。如果这表明确实不存在冲突的存活元组,那么事情就结束了。否则,我们会安排在真正强制约束时再做一次重检。若在重检时,插入的元组与另外某个具有相同键值的元组都仍然存活,就必须报告错误。(注意,就此用途而言,存活实际上是指索引条目 HOT 链中至少有一个元组是存活的。)为实现这一点,传给 aminsert 函数的 checkUnique 参数会取以下值之一: @@ -657,10 +656,10 @@ amtranslatecmptype (CompareType cmptype, Oid opfamily, Oid opcintype); - 索引开销估计函数 + 索引代价估算函数 - amcostestimate 函数会收到描述某种可能索引扫描方式的信息,其中包括已经确定可用于该索引的 WHERE 子句和 ORDER BY 子句列表。它必须返回访问该索引的开销估计,以及 WHERE 子句的选择率(也就是在索引扫描期间将从父表中检索出的行所占比例)。对于简单情况,开销估计器几乎所有工作都可以通过调用优化器中的标准例程来完成;之所以提供 amcostestimate 函数,是为了让索引访问方法能够提供与索引类型有关的专门知识,以便在可能时改进标准估计。 + amcostestimate 函数会收到描述某种可能索引扫描方式的信息,其中包括已经确定可用于该索引的 WHERE 子句和 ORDER BY 子句列表。它必须返回访问该索引的代价估算,以及 WHERE 子句选择率的估计值(也就是在索引扫描期间将从父表中检索出的行所占比例)。对于简单情况,代价估算器几乎所有工作都可以通过调用优化器中的标准例程来完成;之所以提供 amcostestimate 函数,是为了让索引访问方法能够提供与索引类型有关的专门知识,以便在可能时改进标准估计。 @@ -694,7 +693,7 @@ amcostestimate (PlannerInfo *root, path - 当前正在考虑的索引访问路径。除开销和选择率字段外,其余字段都有效。 + 当前正在考虑的索引访问路径。除代价和选择率字段外,其余字段都有效。 @@ -703,7 +702,7 @@ amcostestimate (PlannerInfo *root, loop_count - 在开销估计中应计入的索引扫描重复次数。当考虑在嵌套循环连接内部使用参数化扫描时,这个参数通常会大于 1。请注意,开销估计仍应只针对一次扫描;更大的 loop_count 只表示可以适当考虑多次扫描之间的一些缓存效应。 + 在代价估算中应计入的索引扫描重复次数。当考虑在嵌套循环连接内部使用参数化扫描时,这个参数通常会大于 1。请注意,代价估算仍应只针对一次扫描;更大的 loop_count 只表示可以适当考虑多次扫描之间的一些缓存效应。 @@ -718,7 +717,7 @@ amcostestimate (PlannerInfo *root, *indexStartupCost - 设为索引启动处理的开销。 + 设为索引启动处理的代价。 @@ -727,7 +726,7 @@ amcostestimate (PlannerInfo *root, *indexTotalCost - 设为索引处理的总开销。 + 设为索引处理的总代价。 @@ -762,19 +761,19 @@ amcostestimate (PlannerInfo *root, - 请注意,开销估计函数必须用 C 编写,而不能用 SQL 或任何可用的过程语言,因为它们必须访问规划器/优化器的内部数据结构。 + 请注意,代价估算函数必须用 C 编写,而不能用 SQL 或任何可用的过程语言,因为它们必须访问规划器/优化器的内部数据结构。 - 索引访问开销应使用 src/backend/optimizer/path/costsize.c 所采用的参数来计算:顺序磁盘块读取的开销为 seq_page_cost,非顺序读取的开销为 random_page_cost,处理一条索引行的开销通常应取为 cpu_index_tuple_cost。此外,在索引处理期间调用的任何比较操作符(特别是对 indexquals 本身的求值)都应计入适当倍数的 cpu_operator_cost。 + 索引访问代价应使用 src/backend/optimizer/path/costsize.c 所采用的参数来计算:顺序磁盘块读取的代价为 seq_page_cost,非顺序读取的代价为 random_page_cost,处理一条索引行的代价通常应取为 cpu_index_tuple_cost。此外,在索引处理期间调用的任何比较操作符(特别是对 indexquals 本身的求值)都应计入适当倍数的 cpu_operator_cost - 访问开销应包括与扫描索引本身有关的全部磁盘和 CPU 开销,但包括取出或处理由索引标识出的父表行的开销。 + 访问代价应包括与扫描索引本身有关的全部磁盘和 CPU 代价,但包括取出或处理由索引标识出的父表行的代价。 - 启动开销是整个扫描总开销中必须在开始取第一行之前先付出的那一部分。对大多数索引来说,这可以视为零;但启动开销较高的索引类型可能希望把它设为非零。 + 启动代价是整个扫描总代价中必须在开始取第一行之前先付出的那一部分。对大多数索引来说,这可以视为零;但启动代价较高的索引类型可能希望把它设为非零。 @@ -782,7 +781,7 @@ amcostestimate (PlannerInfo *root, - indexCorrelation 应设为索引顺序与表顺序之间的相关性(范围从 -1.0 到 1.0)。该值用于调整从父表取行开销的估计。 + indexCorrelation 应设为索引顺序与表顺序之间的相关性(范围从 -1.0 到 1.0)。该值用于调整从父表取行代价的估计。 @@ -794,9 +793,9 @@ amcostestimate (PlannerInfo *root, - 开销估计 + 代价估算 - 一个典型的开销估计器会按如下步骤进行: + 一个典型的代价估算器会按如下步骤进行: @@ -825,14 +824,14 @@ amcostestimate (PlannerInfo *root, - 计算索引访问开销。一个通用估计器可能会这样做: + 计算索引访问代价。一个通用估计器可能会这样做: /* - * Our generic assumption is that the index pages will be read - * sequentially, so they cost seq_page_cost each, not random_page_cost. - * Also, we charge for evaluation of the indexquals at each index row. - * All the costs are assumed to be paid incrementally during the scan. + * 通用假设是索引页面将按顺序读取, + * 因此每页代价为 seq_page_cost,而非 random_page_cost。 + * 此外,还要计入在每个索引行上对 indexquals 求值的代价。 + * 假定所有代价都在扫描过程中逐步付出。 */ cost_qual_eval(&index_qual_cost, path->indexquals, root); *indexStartupCost = index_qual_cost.startup; @@ -852,7 +851,7 @@ cost_qual_eval(&index_qual_cost, path->indexquals, root); - 开销估计器函数的示例可在 src/backend/utils/adt/selfuncs.c 中找到。 + 代价估算器函数的示例可在 src/backend/utils/adt/selfuncs.c 中找到。 diff --git a/zh/20/indices.sgml b/zh/20/indices.sgml index 26ae688a..ad4c56a7 100644 --- a/zh/20/indices.sgml +++ b/zh/20/indices.sgml @@ -31,7 +31,7 @@ SELECT content FROM test1 WHERE id = constant; - 大多数非小说类书籍也采用了类似的方法:读者经常查找的术语和概念会被收集到书末按字母顺序排列的索引中。感兴趣的读者可以相对快速地浏览索引并翻到相应页面,而不必通读整本书才能找到自己感兴趣的内容。正如作者需要预判读者可能查找哪些条目一样,数据库程序员也需要预见哪些索引会有用。 + 大多数非虚构类书籍也采用了类似的方法:读者经常查找的术语和概念会被收集到书末按字母顺序排列的索引中。感兴趣的读者可以相对快速地浏览索引并翻到相应页面,而不必通读整本书才能找到自己感兴趣的内容。正如作者需要预判读者可能查找哪些条目一样,数据库程序员也需要预见哪些索引会有用。 @@ -71,7 +71,7 @@ CREATE INDEX test1_id_index ON test1 (id); comparison-value operator indexed-column - 那么如果原始operator有一个可交换操作符,并且该操作符属于该索引的操作符类,就可以把它翻转成可索引的形式。 + 那么如果原始operator有一个交换子操作符,并且该操作符属于该索引的操作符类,就可以把它翻转成可索引的形式。 @@ -100,12 +100,12 @@ CREATE INDEX name ON table B-树 - index + 索引 B-树 B-树 - index + 索引 @@ -133,12 +133,12 @@ CREATE INDEX name ON table Hash - index + 索引 hash hash - index + 索引 @@ -154,12 +154,12 @@ CREATE INDEX name ON table GiST - index + 索引 GiST GiST - index + 索引 @@ -178,7 +178,7 @@ CREATE INDEX name ON table SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10; ]]> - 这会找出距离给定目标点最近的十个地点。是否能做到这一点,同样取决于所使用的具体操作符类。在中,可以按这种方式使用的操作符列在Ordering Operators这一列中。 + 这会找出距离给定目标点最近的十个地点。是否能做到这一点,同样取决于所使用的具体操作符类。在中,可以按这种方式使用的操作符列在排序操作符这一列中。 @@ -186,12 +186,12 @@ SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10; SP-GiST - index + 索引 SP-GiST SP-GiST - index + 索引 @@ -205,7 +205,7 @@ SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10; - 与 GiST 一样,SP-GiST 支持最近邻搜索。对于支持距离排序的 SP-GiST 操作符类,相应操作符列在Ordering Operators列中。 + 与 GiST 一样,SP-GiST 支持最近邻搜索。对于支持距离排序的 SP-GiST 操作符类,相应操作符列在排序操作符列中。 @@ -213,12 +213,12 @@ SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10; GIN - index + 索引 GIN GIN - index + 索引 @@ -240,12 +240,12 @@ SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10; BRIN - index + 索引 BRIN BRIN - index + 索引 @@ -265,8 +265,8 @@ SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10; 多列索引 - index - multicolumn + 索引 + 多列 @@ -293,7 +293,7 @@ CREATE INDEX test2_mm_idx ON test2 (major, minor); - 多列 B-树索引可以用于涉及索引任意列子集的查询条件,但当对前导(最左)列存在约束时,索引效率最高。精确的规则是:对前导列的等值约束,再加上第一个没有等值约束列上的任意不等约束,总会被用来限制被扫描的索引范围。这些列右侧列上的约束会在索引中进行检查,因此总能减少访问表本体的次数,但不一定会减少必须扫描的索引范围。如果 B-树索引扫描能够有效应用跳过扫描优化,那么它在通过反复的索引搜索遍历索引时,会利用每一列约束。这可能减少需要读取的索引部分,即便一个或多个列(位于查询谓词中最低有效索引列之前)缺少常规的等值约束。跳过扫描的工作方式是内部生成一个动态的等值约束,使其匹配索引列中的每个可能值(不过这只适用于某个列缺少来自查询谓词的等值约束,且生成的约束能够与查询谓词中较后列的约束联合使用时)。 + 多列 B-树索引可以用于涉及索引任意列子集的查询条件,但当对前导(最左)列存在约束时,索引效率最高。精确的规则是:对前导列的等值约束,再加上第一个没有等值约束列上的任意不等约束,总会被用来限制被扫描的索引范围。这些列右侧列上的约束会在索引中进行检查,因此总能减少访问表本体的次数,但不一定会减少必须扫描的索引范围。如果 B-树索引扫描能够有效应用跳过扫描优化,那么它在通过反复的索引搜索遍历索引时,会利用每一列约束。这可能减少需要读取的索引部分,即便一个或多个列(位于查询谓词所涉及的最右侧索引列之前)缺少常规的等值约束。跳过扫描的工作方式是内部生成一个动态的等值约束,使其匹配索引列中的每个可能值(不过这只适用于某个列缺少来自查询谓词的等值约束,且生成的约束能够与查询谓词中较后列的约束联合使用时)。 @@ -309,11 +309,11 @@ CREATE INDEX test2_mm_idx ON test2 (major, minor); - 多列 GIN 索引可以用于涉及索引任意列子集的查询条件。与 B-树或 GiST 不同,无论查询条件使用的是哪一列索引列,GIN 的索引搜索效果都一样。 + 多列 GIN 索引可以用于涉及索引任意列子集的查询条件。与 B-树或 GiST 不同,无论查询条件使用的是哪些索引列,GIN 的索引搜索效果都一样。 - 多列 BRIN 索引可以用于涉及索引任意列子集的查询条件。和 GIN 一样、不同于 B-树或 GiST,无论查询条件使用的是哪一列索引列,索引搜索效果都一样。在单个表上使用多个 BRIN 索引,而不是使用一个多列 BRIN 索引的唯一理由,是需要不同的pages_per_range存储参数。 + 多列 BRIN 索引可以用于涉及索引任意列子集的查询条件。和 GIN 一样、不同于 B-树或 GiST,无论查询条件使用的是哪些索引列,索引搜索效果都一样。在单个表上使用多个 BRIN 索引,而不是使用一个多列 BRIN 索引的唯一理由,是需要不同的pages_per_range存储参数。 @@ -330,8 +330,8 @@ CREATE INDEX test2_mm_idx ON test2 (major, minor); 索引和<literal>ORDER BY</literal> - index - and ORDER BY + 索引 + ORDER BY @@ -339,7 +339,7 @@ CREATE INDEX test2_mm_idx ON test2 (major, minor); - 规划器在满足ORDER BY要求时,会考虑两种方案:扫描一个与该要求匹配的可用索引,或者按物理顺序扫描表再显式排序。对于需要扫描表中很大一部分内容的查询,显式排序通常会比使用索引更快,因为它遵循顺序访问模式,需要的磁盘 I/O 更少。只有在只需取出少量行时,索引才更有价值。一个重要的特例是ORDER BYLIMIT n组合使用:显式排序必须处理所有数据才能找出最前面的n行,而如果有一个与ORDER BY匹配的索引,就可以直接取回前n行,而完全不必扫描剩余数据。 + 规划器在满足ORDER BY要求时,会考虑两种方案:扫描一个与该要求匹配的可用索引,或者按物理顺序扫描表再显式排序。对于需要扫描表中很大一部分内容的查询,显式排序通常会比使用索引更快,因为它遵循顺序访问模式,需要的磁盘 I/O 更少。只需取出少量行时,索引更有价值。一个重要的特例是ORDER BYLIMIT n组合使用:显式排序必须处理所有数据才能找出最前面的n行,而如果有一个与ORDER BY匹配的索引,就可以直接取回前n行,而完全不必扫描剩余数据。 @@ -369,12 +369,12 @@ CREATE INDEX test3_desc_index ON test3 (id DESC NULLS LAST); 组合多个索引 - index - combining multiple indexes + 索引 + 组合多个索引 - bitmap scan + 位图扫描 @@ -391,7 +391,7 @@ CREATE INDEX test3_desc_index ON test3 (id DESC NULLS LAST); - 除了最简单的应用之外,通常会有多种可能有用的索引组合,数据库开发者必须权衡决定提供哪些索引。有时多列索引最好,但有时创建独立索引并依赖索引组合功能会更合适。例如,如果你的工作负载包含一组查询:有时只涉及列x,有时只涉及列y,有时同时涉及两列,那么你可以选择分别在xy上创建两个独立索引,并依赖索引组合来处理同时使用两列的查询。你也可以创建一个(x, y)上的多列索引。对于同时涉及两列的查询,这个索引通常会比索引组合更高效,但正如中所讨论的,它对于只涉及y的查询就没那么有用了。具体能有多大用处,取决于 B-树索引跳过扫描优化的效果;如果x的非重复值不超过几百个,跳过扫描会让针对特定y值的搜索仍然具有相当不错的效率。再加上一个(x, y)上的多列索引和一个单独的y索引,也可能工作得相当好。对于只涉及x的查询,多列索引也可以使用,但它会比单独的x索引更大,因此更慢。最后一种选择是同时创建这三个索引,但这大概只有在该表被搜索的频率远高于被更新的频率,并且三类查询都很常见时才合理。如果其中一种查询远没有另外两种常见,那么你大概只需创建最适合常见查询类型的两个索引即可。 + 除了最简单的应用之外,通常会有多种可能有用的索引组合,数据库开发者必须权衡决定提供哪些索引。有时多列索引最好,但有时创建独立索引并依赖索引组合功能会更合适。例如,如果你的工作负载包含一组查询:有时只涉及列x,有时只涉及列y,有时同时涉及两列,那么你可以选择分别在xy上创建两个独立索引,并依赖索引组合来处理同时使用两列的查询。你也可以创建一个(x, y)上的多列索引。对于同时涉及两列的查询,这个索引通常会比索引组合更高效,但正如中所讨论的,它对于只涉及y的查询就没那么有用了。具体能有多大用处,取决于 B-树索引跳过扫描优化的效果;如果x的非重复值不超过几百个,跳过扫描会让针对特定y值的搜索仍然具有相当不错的效率。将一个(x, y)上的多列索引和一个单独的y索引组合使用,也可能工作得相当好。对于只涉及x的查询,多列索引也可以使用,但它会比单独的x索引更大,因此更慢。最后一种选择是同时创建这三个索引,但这大概只有在该表被搜索的频率远高于被更新的频率,并且三类查询都很常见时才合理。如果其中一种查询远没有另外两种常见,那么你大概只需创建最适合常见查询类型的两个索引即可。 @@ -401,8 +401,8 @@ CREATE INDEX test3_desc_index ON test3 (id DESC NULLS LAST); 唯一索引 - index - unique + 索引 + 唯一 @@ -433,8 +433,8 @@ CREATE UNIQUE INDEX name ON table表达式索引 - index - on expressions + 索引 + 基于表达式 @@ -481,8 +481,8 @@ CREATE INDEX people_names ON people ((first_name || ' ' || last_name)); 部分索引 - index - partial + 索引 + 部分 @@ -490,7 +490,7 @@ CREATE INDEX people_names ON people ((first_name || ' ' || last_name)); - 使用部分索引的一个主要原因是避免索引常见值。由于搜索常见值的查询(即占全部表行百分之几以上的值)反正也不会使用索引,因此完全没有必要把这些行保留在索引里。这会减小索引尺寸,从而加快那些确实会使用该索引的查询。它也会加快很多表更新操作,因为索引并不需要在所有情况下都更新。展示了这种思路的一种可能应用。 + 使用部分索引的一个主要原因是避免索引常见值。由于搜索常见值(即占全部表行百分之几以上的值)的查询反正也不会使用索引,因此完全没有必要把这些行保留在索引里。这会减小索引尺寸,从而加快那些确实会使用该索引的查询。它也会加快很多表更新操作,因为索引并不需要在所有情况下都更新。展示了这种思路的一种可能应用。 @@ -578,7 +578,7 @@ SELECT * FROM orders WHERE order_nr = 3501; - 也说明了:索引列和谓词中使用的列不必一致。PostgreSQL支持带任意谓词的部分索引,只要其中只涉及正在建立索引的那张表的列。不过要记住,谓词必须与那些希望从该索引受益的查询中使用的条件相匹配。更准确地说,只有当系统能够识别出查询的WHERE条件在数学上蕴含该索引的谓词时,部分索引才能用于该查询。PostgreSQL并没有一个复杂的定理证明器,来识别那些写法不同但数学上等价的表达式。(不仅构建这样一个通用定理证明器极其困难,而且它很可能也会慢到失去实际用途。)系统可以识别简单的不等式蕴含,例如x < 1蕴含x < 2;否则,谓词条件必须与查询WHERE条件的某一部分完全匹配,否则索引不会被识别为可用。匹配发生在查询规划阶段,而不是运行时。因此,参数化查询子句无法与部分索引配合工作。例如,一个带参数的预备查询可能写成x < ?,而对于参数的所有可能取值,它都不可能蕴含x < 2。 + 也说明了:索引列和谓词中使用的列不必一致。PostgreSQL支持带任意谓词的部分索引,只要其中只涉及正在建立索引的那张表的列。不过要记住,谓词必须与那些希望从该索引受益的查询中使用的条件相匹配。更准确地说,只有当系统能够识别出查询的WHERE条件在数学上蕴含该索引的谓词时,部分索引才能用于该查询。PostgreSQL并没有一个复杂的定理证明器,来识别那些写法不同但数学上等价的表达式。(不仅构建这样一个通用定理证明器极其困难,而且它很可能也会慢到失去实际用途。)系统可以识别简单的不等式蕴含,例如x < 1蕴含x < 2;否则,谓词条件必须与查询WHERE条件的某一部分完全匹配,否则索引不会被识别为可用。匹配发生在查询规划阶段,而不是运行时。因此,参数化查询子句无法与部分索引配合工作。例如,一个带参数的预备查询可能写成x < ?,而它无法保证在参数的所有可能取值下都蕴含x < 2 @@ -590,7 +590,7 @@ SELECT * FROM orders WHERE order_nr = 3501; 建立一个部分唯一索引 - 假设我们有一张描述测试结果的表。我们希望确保对于给定的subjecttarget组合,只有一条成功记录,但可以有任意多条失败记录。实现方法之一如下: + 假设我们有一张描述测试结果的表。我们希望确保对于给定的测试对象和目标组合,只有一条成功记录,但可以有任意多条失败记录。实现方法之一如下: CREATE TABLE tests ( subject text, @@ -671,7 +671,7 @@ CREATE INDEX mytable_cat_data ON mytable (category, data); - PostgreSQL中的所有索引都是二级索引,也就是说,每个索引都与表的主数据区分开存储(在PostgreSQL术语中,这个主数据区称为表的)。这意味着,在普通索引扫描中,每次取回一行都需要同时从索引和堆中取数据。此外,尽管满足某个可索引WHERE条件的索引项通常在索引中彼此接近,但它们引用的表行却可能分布在堆中的任何位置。因此,索引扫描的堆访问部分会涉及大量对堆的随机访问,这可能很慢,尤其是在传统旋转介质上。(正如中所述,位图扫描试图通过按排序顺序进行堆访问来缓解这项成本,但那也只能缓解到一定程度。) + PostgreSQL中的所有索引都是二级索引,也就是说,每个索引都与表的主数据区分开存储(在PostgreSQL术语中,这个主数据区称为表的)。这意味着,在普通索引扫描中,每次取回一行都需要同时从索引和堆中取数据。此外,尽管满足某个可索引WHERE条件的索引项通常在索引中彼此接近,但它们引用的表行却可能分布在堆中的任何位置。因此,索引扫描的堆访问部分会涉及大量对堆的随机访问,这可能很慢,尤其是在传统旋转介质上。(正如中所述,位图扫描试图通过按排序顺序进行堆访问来缓解这项代价,但那也只能缓解到一定程度。) @@ -686,7 +686,7 @@ CREATE INDEX mytable_cat_data ON mytable (category, data); - 查询只能引用存储在索引中的列。例如,给定一个表,它有列xyz,而索引建立在xy上,那么下面这些查询可以使用仅索引扫描: + 查询只能引用存储在索引中的列。例如,假设某个表的xy列上有一个索引,且该表还有一列z,那么下面这些查询可以使用仅索引扫描: SELECT x, y FROM tab WHERE x = 'key'; SELECT x FROM tab WHERE x = 'key' AND y < 42; @@ -713,7 +713,7 @@ SELECT x FROM tab WHERE x = 'key' AND z < 42; INCLUDE - in index definitions + 在索引定义中 为了有效利用仅索引扫描特性,你可以选择创建一个覆盖索引,也就是专门设计来包含某一类高频查询所需列的索引。由于查询通常需要取回的列不止是用于搜索的那些列,PostgreSQL允许你创建一种索引,其中某些列只是负载,而不是搜索键的一部分。这是通过添加一个INCLUDE子句列出这些额外列来实现的。例如,如果你经常运行如下查询: @@ -735,7 +735,7 @@ CREATE UNIQUE INDEX tab_x_y ON tab(x) INCLUDE (y); - 向索引中添加非键负载列时,明智的做法是保持保守,尤其是宽列。如果某个索引元组超过该索引类型允许的最大尺寸,数据插入就会失败。无论如何,非键列都会复制索引对应表中的数据并让索引膨胀,因此可能拖慢搜索。另外请记住,除非表变化足够缓慢,以至于仅索引扫描很可能无需访问堆,否则把负载列包含在索引中并没有太大意义。如果反正必须访问堆元组,那么顺便从那里取出该列的值也不会增加额外成本。其他限制包括:当前不支持把表达式作为包含列;并且当前只有 B-树、GiST 和 SP-GiST 索引支持包含列。 + 向索引中添加非键负载列时,明智的做法是保持保守,尤其是宽列。如果某个索引元组超过该索引类型允许的最大尺寸,数据插入就会失败。无论如何,非键列都会复制索引对应表中的数据并让索引膨胀,因此可能拖慢搜索。另外请记住,除非表变化足够缓慢,以至于仅索引扫描很可能无需访问堆,否则把负载列包含在索引中并没有太大意义。如果反正必须访问堆元组,那么顺便从那里取出该列的值也不会增加额外代价。其他限制包括:当前不支持把表达式作为包含列;并且当前只有 B-树、GiST 和 SP-GiST 索引支持包含列。 @@ -781,11 +781,11 @@ SELECT target FROM tests WHERE subject = 'some-subject' AND success; 操作符类和操作符族 - operator class + 操作符类 - operator family + 操作符族 @@ -903,8 +903,8 @@ CREATE INDEX test1c_content_y_index ON test1c (content COLLATE "y"); 检查索引使用情况 - index - examining usage + 索引 + 检查使用情况 diff --git a/zh/20/information_schema.sgml b/zh/20/information_schema.sgml index 41e10104..941045dc 100644 --- a/zh/20/information_schema.sgml +++ b/zh/20/information_schema.sgml @@ -388,7 +388,7 @@ collation_catalog sql_identifier - 包含此属性排序规则的数据库名(总是当前数据库),如果默认或者该属性的数据类型不可排序则为空 + 包含该属性排序规则的数据库名称(总是当前数据库);如果使用默认排序规则,或该属性的数据类型不支持排序规则,则为 null。 @@ -397,7 +397,7 @@ collation_schema sql_identifier - 包含此属性排序规则的模式名,如果默认或者该属性的数据类型不可排序则为空 + 包含该属性排序规则的模式名称;如果使用默认排序规则,或该属性的数据类型不支持排序规则,则为 null。 @@ -406,7 +406,7 @@ collation_name sql_identifier - 该属性排序规则的名称,如果默认或者该属性的数据类型不可排序则为空 + 该属性排序规则的名称;如果使用默认排序规则,或该属性的数据类型不支持排序规则,则为 null。 @@ -1626,7 +1626,7 @@ collation_catalog sql_identifier - 包含此属性排序规则的数据库名(总是当前数据库),如果默认或者该属性的数据类型不可排序则为空 + 包含该列排序规则的数据库名称(总是当前数据库);如果使用默认排序规则,或该列的数据类型不支持排序规则,则为 null。 @@ -1635,7 +1635,7 @@ collation_schema sql_identifier - 该列的包含排序规则的模式名,如果默认或者该列的数据类型不可排序则为空 + 包含该列排序规则的模式名称;如果使用默认排序规则,或该列的数据类型不支持排序规则,则为 null。 @@ -1644,7 +1644,7 @@ collation_name sql_identifier - 该列的排序规则的名称,如果默认或者该列的数据类型不可排序则为空 + 该列排序规则的名称;如果使用默认排序规则,或该列的数据类型不支持排序规则,则为 null。 @@ -2385,7 +2385,7 @@ collation_catalog sql_identifier - 包含此域排序规则的数据库名(总是当前数据库),如果默认或者该域的数据类型不可排序则为空 + 包含该域排序规则的数据库名称(总是当前数据库);如果使用默认排序规则,或该域的数据类型不支持排序规则,则为 null。 @@ -2394,7 +2394,7 @@ collation_schema sql_identifier - 包含此域排序规则的模式名,如果默认或者该域的数据类型不可排序则为空 + 包含该域排序规则的模式名称;如果使用默认排序规则,或该域的数据类型不支持排序规则,则为 null。 @@ -2403,7 +2403,7 @@ collation_name sql_identifier - 该域排序规则的名称,如果默认或者该域的数据类型不可排序则为空 + 该域排序规则的名称;如果使用默认排序规则,或该域的数据类型不支持排序规则,则为 null。 @@ -2558,7 +2558,7 @@ <literal>element_types</literal> - 视图element_types包含数组元素的数据类型描述符。当一个表列、复合类型属性、域、函数参数或函数返回值被定义为一种数组类型,相应的信息模式视图只在列data_type中包含ARRAY。要获得该数组元素类型的信息,你可以连接该相应的视图和这个视图。例如,要显示一个表的列及其数据类型和数组元素类型,你可以: + 视图element_types包含数组元素的数据类型描述符。当一个表列、复合类型属性、域、函数参数或函数返回值被定义为一种数组类型时,相应的信息模式视图只在列data_type中包含ARRAY。要获得该数组元素类型的信息,你可以连接该相应的视图和这个视图。例如,要显示一个表的列及其数据类型和数组元素类型(如果适用),你可以: SELECT c.column_name, c.data_type, e.data_type AS element_type FROM information_schema.columns c LEFT JOIN information_schema.element_types e @@ -2689,7 +2689,7 @@ ORDER BY c.ordinal_position; collation_catalog sql_identifier - 包含元素类型排序规则的数据库名称(总是当前数据库), 如果默认或该元素的数据类型是不可排序的则为空 + 包含该元素类型排序规则的数据库名称(总是当前数据库);如果使用默认排序规则,或该元素类型不支持排序规则,则为 null。 @@ -2698,7 +2698,7 @@ ORDER BY c.ordinal_position; collation_schema sql_identifier - 包含元素类型排序规则的模式名称, 如果默认或该元素的数据类型是不可排序的则为空 + 包含该元素类型排序规则的模式名称;如果使用默认排序规则,或该元素类型不支持排序规则,则为 null。 @@ -2707,7 +2707,7 @@ ORDER BY c.ordinal_position; collation_name sql_identifier - 元素类型的排序规则名, 如果默认或该元素的数据类型是不可排序的则为空 + 该元素类型排序规则的名称;如果使用默认排序规则,或该元素类型不支持排序规则,则为 null。 @@ -7145,7 +7145,7 @@ ORDER BY c.ordinal_position; - SQL 了解两种用户定义类型:结构类型(在PostgreSQL中也称为复合类型)以及 distinct type(PostgreSQL 尚未实现)。为兼顾将来,请使用列user_defined_type_category来区分它们。其他用户定义类型,如基类型和枚举(两者都是PostgreSQL的扩展),不会在这里显示。域的相关信息见。 + SQL 中有两种用户定义类型:结构类型(在PostgreSQL中也称为复合类型)以及独立类型(distinct type,PostgreSQL 尚未实现)。为兼顾将来,请使用列user_defined_type_category来区分它们。其他用户定义类型,如基础类型和枚举(两者都是PostgreSQL的扩展),不会在这里显示。域的相关信息见 @@ -7877,7 +7877,7 @@ ORDER BY c.ordinal_position; check_optioncharacter_data - CASCADEDLOCAL 如果视图上有CHECK OPTION 定义,如果没有则为NONE。 + CASCADEDLOCAL 如果视图上有CHECK OPTION 定义,如果没有则为NONE diff --git a/zh/20/installation.sgml b/zh/20/installation.sgml index a362a739..9c310938 100644 --- a/zh/20/installation.sgml +++ b/zh/20/installation.sgml @@ -4,7 +4,7 @@ 从源代码安装 - installation + 安装 @@ -360,7 +360,7 @@ 使用 Autoconf 和 Make 进行构建和安装 - 简短版本 + 简要说明 @@ -377,7 +377,7 @@ su - postgres /usr/local/pgsql/bin/createdb test /usr/local/pgsql/bin/psql test - 较长版本见本其余部分。 + 详细说明见本的其余部分。 @@ -605,7 +605,7 @@ build-postgresql: <filename>configure</filename> 选项 - 配置选项 + configure 选项 @@ -1029,7 +1029,7 @@ build-postgresql: ,使用 OSSP UUID library + url="http://www.ossp.org/pkg/lib/uuid/">OSSP UUID 库 @@ -1092,13 +1092,7 @@ build-postgresql: 这一特性要求 libxml2 2.6.23 或更高版本。 - - 为了检测所需的编译器和链接器选项,如果系统已安装 - pkg-config 且知道 libxml2,PostgreSQL - 会查询 pkg-config。否则,如果找得到由 libxml2 - 安装的 xml2-config 程序,就会使用它。 - 优先使用 pkg-config,因为它能更好地处理多架构安装。 - + 为检测所需的编译器和链接器选项,PostgreSQL 会查询 pkg-config,前提是已安装该程序且其中有 libxml2 的信息。否则,如果找到 libxml2 安装的 xml2-config 程序,就会使用它。优先使用 pkg-config,因为它能更好地处理多架构安装。 如果 libxml2 安装在不常见的位置,你可以设置与 @@ -1140,7 +1134,7 @@ build-postgresql: - 反功能 + 禁用特性 本节描述的选项允许禁用某些默认会构建的 @@ -1285,8 +1279,7 @@ build-postgresql: - 不在 PostgreSQL 的可执行文件中标记, - 使其在运行时到安装的库目录中搜索共享库(见 )。 + 不在 PostgreSQL 的可执行文件中添加指示其到安装的库目录中搜索共享库的标记(见 )。 在大多数平台上,这种标记使用库目录的绝对路径,因此如果你之后移动安装位置, 它就没有帮助了。不过这样一来,你就需要通过其他方式让可执行文件找到共享库。 通常这要求配置操作系统的动态链接器搜索该库目录;更多细节见 @@ -1303,7 +1296,7 @@ build-postgresql: 杂项 - 调整默认端口号 相当常见, + 使用 调整默认端口号相当常见, 尤其是在测试性构建中。本节中的其他选项只推荐给高级用户。 @@ -1338,10 +1331,10 @@ build-postgresql: - 设置 segment size,单位为 GB。 + 设置 段大小,单位为 GB。 大表会被分成多个操作系统文件,每个文件的大小等于段大小。 这可以避免很多平台上的文件大小限制问题。默认段大小 1GB 在所有支持的平台上 - 都是安全的。如果你的操作系统支持 largefile + 都是安全的。如果你的操作系统支持 大文件 (如今大多数都支持),你可以使用更大的段大小。 这有助于减少处理超大表时消耗的文件描述符数量。 但请注意不要选择超出你的平台和打算使用的文件系统所支持的值。 @@ -1357,7 +1350,7 @@ build-postgresql: - 设置 block size,单位为 KB。 + 设置 块大小,单位为 KB。 这是表内部存储和 I/O 的单位。默认值 8KB 适合大多数场景, 但在特殊情况下,其他取值也可能有用。 该值必须是 1 到 32(KB)之间的 2 的幂。 @@ -1371,7 +1364,7 @@ build-postgresql: - 设置 WAL block size,单位为 KB。 + 设置 WAL 块大小,单位为 KB。 这是 WAL 日志内部存储和 I/O 的单位。默认值 8KB 适合大多数场景, 但在特殊情况下,其他取值也可能有用。 该值必须是 1 到 64(KB)之间的 2 的幂。 @@ -1421,11 +1414,11 @@ build-postgresql: - 在服务器中启用 assertion 检查,用于测试许多 - 不应该发生的条件。这对代码开发非常有价值,但这些测试会显著拖慢 + 在服务器中启用 断言 检查,用于测试许多 + 不可能发生的条件。这对代码开发非常有价值,但这些测试可能会显著拖慢 服务器速度。此外,启用这些测试并不一定会增强服务器稳定性! 断言检查并未按严重程度分类,因此即使某个 bug 相对无害,只要触发了断言失败, - 仍可能导致服务器重启。该选项不建议用于生产环境,但如果你在做开发工作 + 仍会导致服务器重启。该选项不建议用于生产环境,但如果你在做开发工作 或运行测试版,就应当启用它。 @@ -1470,7 +1463,7 @@ build-postgresql: 如果使用 GCC,所有程序和库都会被编译成可进行性能分析的形式。 - 后端退出时,会创建一个子目录,其中包含带有 profile 数据的 + 后端退出时,会创建一个子目录,其中包含带有性能分析数据的 gmon.out 文件。 该选项只适用于 GCC,并且仅在开发工作中使用。 @@ -1542,7 +1535,7 @@ build-postgresql: <filename>configure</filename> 环境变量 - configure environment variables + configure 环境变量 @@ -1609,7 +1602,7 @@ build-postgresql: 在使用 --with-llvm 编译时, - 用于处理源代码以内联的 clang 程序路径 + 用于处理源代码以进行内联的 clang 程序路径 @@ -1813,7 +1806,7 @@ build-postgresql: 使用 Meson 构建和安装 - 简短版本 + 简要说明 @@ -1831,7 +1824,7 @@ su - postgres /usr/local/pgsql/bin/createdb test /usr/local/pgsql/bin/psql test - 较长版本见本其余部分。 + 详细说明见本的其余部分。 @@ -2381,7 +2374,7 @@ ninja install ,使用 OSSP UUID library + url="http://www.ossp.org/pkg/lib/uuid/">OSSP UUID 库 @@ -2469,7 +2462,7 @@ ninja install - 反功能 + 禁用特性 @@ -2525,7 +2518,7 @@ ninja install 设置这个选项,可以覆盖所有 auto 特性的取值 (也就是那些在找到所需软件时会自动启用的特性)。 - 当你想一次性禁用或启用所有 optional 特性, + 当你想一次性禁用或启用所有 可选 特性, 而不必逐个手工设置时,这会很有用。 该参数的默认值是 auto。 @@ -2651,9 +2644,8 @@ ninja install - 该选项默认值是 true。如果设为 false,则不会在 - PostgreSQL 的可执行文件中标记, - 使其在运行时到安装的库目录中搜索共享库(见 )。 + 该选项默认值是 true。如果设为 false,则不在 + PostgreSQL 的可执行文件中添加指示其到安装的库目录中搜索共享库的标记(见 )。 在大多数平台上,这种标记使用库目录的绝对路径,因此如果你之后移动安装位置, 它就没有帮助了。不过这样一来,你就需要通过其他方式让可执行文件找到共享库。 通常这要求配置操作系统的动态链接器搜索该库目录;更多细节见 @@ -2754,10 +2746,10 @@ ninja install - 设置 segment size,单位为 GB。 + 设置 段大小,单位为 GB。 大表会被分成多个操作系统文件,每个文件的大小等于段大小。 这可以避免很多平台上的文件大小限制问题。默认段大小 1GB 在所有支持的平台上 - 都是安全的。如果你的操作系统支持 largefile + 都是安全的。如果你的操作系统支持 大文件 (如今大多数都支持),你可以使用更大的段大小。 这有助于减少处理超大表时消耗的文件描述符数量。 但请注意不要选择超出你的平台和打算使用的文件系统所支持的值。 @@ -2771,7 +2763,7 @@ ninja install - 设置 block size,单位为 KB。 + 设置 块大小,单位为 KB。 这是表内部存储和 I/O 的单位。默认值 8KB 适合大多数场景, 但在特殊情况下,其他取值也可能有用。 该值必须是 1 到 32(KB)之间的 2 的幂。 @@ -2783,7 +2775,7 @@ ninja install - 设置 WAL block size,单位为 KB。 + 设置 WAL 块大小,单位为 KB。 这是 WAL 日志内部存储和 I/O 的单位。默认值 8KB 适合大多数场景, 但在特殊情况下,其他取值也可能有用。 该值必须是 1 到 64(KB)之间的 2 的幂。 @@ -2869,11 +2861,11 @@ ninja install - 在服务器中启用 assertion 检查,用于测试许多 - 不应该发生的条件。这对代码开发非常有价值,但这些测试会显著拖慢 + 在服务器中启用 断言 检查,用于测试许多 + 不可能发生的条件。这对代码开发非常有价值,但这些测试会显著拖慢 服务器速度。此外,启用这些测试并不一定会增强服务器稳定性! 断言检查并未按严重程度分类,因此即使某个 bug 相对无害,只要触发了断言失败, - 仍可能导致服务器重启。该选项不建议用于生产环境,但如果你在做开发工作 + 仍会导致服务器重启。该选项不建议用于生产环境,但如果你在做开发工作 或运行测试版,就应当启用它。 @@ -2894,10 +2886,10 @@ ninja install - 启用额外测试套件;这些测试默认不会运行,因为它们不适合在多用户系统上运行、 + 启用额外测试套件;这些测试默认不会运行,因为它们在多用户系统上运行不安全、 需要特殊软件,或者资源消耗较大。该参数是以空白分隔的测试名称列表。 详见 。如果在运行测试时设置了 - PG_TEST_EXTRA 环境变量,那么它会覆盖这个构建时选项。 + PG_TEST_EXTRA 环境变量,那么它会覆盖这个配置阶段的选项。 @@ -3197,7 +3189,7 @@ export MANPATH export OBJECT_MODE=64 meson setup ... - 如果不这样做,通常会看到 ar 报告文件具有错误的对象文件模式。 + 如果不这样做,通常会看到 ar 报告文件具有错误的目标文件模式。 @@ -3235,14 +3227,14 @@ meson setup ... 不支持 adduser 命令;请使用 Windows 中相应的 - 用户管理应用。除此之外,跳过这一步即可。 + 用户管理应用。也可以跳过这一步。 不支持 su 命令;请在 Windows 上使用 ssh 来模拟 su。 - 除此之外,跳过这一步即可。 + 也可以跳过这一步。 @@ -3273,16 +3265,11 @@ meson setup ... - - 并行回归测试(make check)可能会因为 - listen() backlog 队列溢出而产生伪造的回归测试失败, - 进而导致连接拒绝错误或挂起。你可以像下面这样使用 make 变量 - MAX_CONNECTIONS 来限制连接数: + 并行回归测试(make check)可能因 listen() 的待处理连接队列溢出而误报回归测试失败;队列溢出会导致连接被拒绝的错误或挂起。可以使用 make 变量 MAX_CONNECTIONS 限制连接数,方法如下: make MAX_CONNECTIONS=5 check - (在某些系统上,同时连接数大致最多可达到 10 个。) - +(在某些系统上,并发连接数最高可达约 10 个。) @@ -3355,7 +3342,7 @@ xcrun --show-sdk-path macOS 的 - System Integrity Protection(SIP)特性会破坏 + 系统完整性保护(SIP)特性会破坏 make check,因为它会阻止把所需的 DYLD_LIBRARY_PATH 设置传递给被测试的可执行文件。 你可以通过在 make check 之前先执行 @@ -3419,10 +3406,10 @@ xcrun --show-sdk-path - configure 抱怨测试程序失败 + configure 报告测试程序失败 - 如果 configure 抱怨某个测试程序失败, + 如果 configure 报告某个测试程序失败, 这多半是因为运行时链接器找不到某些库,通常是 libz、libreadline, 或其他非标准库如 libssl。要把它指向正确位置,请在 configure 命令行中设置环境变量 LDFLAGS, @@ -3436,8 +3423,6 @@ configure ... LDFLAGS="-R /usr/sfw/lib:/opt/sfw/lib:/usr/local/lib" - - 使用 DTrace 跟踪 PostgreSQL diff --git a/zh/20/libpq.sgml b/zh/20/libpq.sgml index 62588223..888bf6e1 100644 --- a/zh/20/libpq.sgml +++ b/zh/20/libpq.sgml @@ -41,7 +41,7 @@ - 如果不可信用户能够访问一个没有采用模式的安全使用方式的数据库,那么每个会话开始时都应从search_path中移除公开可写的模式。可以把参数关键词options设置为-csearch_path=。也可以在连接后发出PQexec(conn, "SELECT pg_catalog.set_config('search_path', '', false)")。这种考虑并非专门针对libpq;它适用于每一种可执行任意 SQL 命令的接口。 + 如果不受信任的用户能够访问一个没有采用模式的安全使用方式的数据库,那么每个会话开始时都应从search_path中移除公开可写的模式。可以把参数关键词options设置为-csearch_path=。也可以在连接后发出PQexec(conn, "SELECT pg_catalog.set_config('search_path', '', false)")。这种考虑并非专门针对libpq;它适用于每一种可执行任意 SQL 命令的接口。 @@ -180,7 +180,7 @@ PGconn *PQsetdb(char *pghost, PQconnectStartParamsPQconnectStartParams PQconnectStartPQconnectStart - PQconnectPollPQconnectPoll + PQconnectPollPQconnectPoll nonblocking connection @@ -214,7 +214,7 @@ PostgresPollingStatusType PQconnectPoll(PGconn *conn); - hostaddrhost参数必须被合适地使用,以防止做DNS查询。详见中这些参数的文档。 + 必须正确使用 hostaddr 参数,以避免执行 DNS 查询。详细信息请参见中该参数的说明。 @@ -289,11 +289,12 @@ PostgresPollingStatusType PQconnectPoll(PGconn *conn); - - CONNECTION_SETENV + + + CONNECTION_GSS_STARTUP - 协商环境驱动的参数设置。 + 协商 GSS 加密。 @@ -307,6 +308,15 @@ PostgresPollingStatusType PQconnectPoll(PGconn *conn); + + CONNECTION_CHECK_STANDBY + + + 检查连接的服务器是否处于备用模式。 + + + + CONNECTION_CONSUME @@ -347,6 +357,38 @@ switch(PQstatus(conn)) + + PQsocketPollPQsocketPoll + + + 非阻塞连接 + 轮询通过取得的连接底层套接字描述符。此函数主要用于逐步执行文档中描述的连接过程。 + +typedef int64_t pg_usec_time_t; + +int PQsocketPoll(int sock, int forRead, int forWrite, + pg_usec_time_t end_time); + + + + + 此函数对文件描述符进行轮询,并可选择设置超时。如果forRead非零,则在套接字可读时结束。如果forWrite非零,则在套接字可写时结束。 + + + + 超时由end_time指定,它表示停止等待的时刻,以自 Unix 纪元以来的微秒数表示(即time_t乘以一百万)。如果end_time-1,则无限等待。如果 end_time0(或任何早于当前时刻的时间),则立即超时(不阻塞)。将所需的微秒数加到的结果上,即可方便地计算超时值。注意,底层系统调用的精度可能低于微秒,因此实际延迟可能不精确。 + + + + 如果满足指定条件,函数返回大于0的值;如果发生超时,返回0;如果发生错误,返回-1。可以通过检查errno(3)的值获取错误信息。如果forReadforWrite都为零,函数会立即返回超时指示。 + + + + PQsocketPoll根据平台使用poll(2)select(2)实现。更多信息请参见poll(2)中的POLLINPOLLOUT,或select(2)中的readfdswritefds。 + + + + PQconndefaultsPQconndefaults @@ -779,7 +821,7 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname 参数关键词 - 目前被识别的参数关键字包括: + 目前被识别的参数关键字包括: @@ -951,9 +993,7 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname 服务器必须请求 MD5 哈希密码认证。 - - 对 MD5 加密密码的支持已被废弃,并将在未来的PostgreSQL版本中移除。关于迁移到其他密码类型的细节,请参见。 - + 对 MD5 加密密码的支持已弃用,并将在PostgreSQL的未来版本中移除。迁移到其他密码类型的详细信息见 @@ -1057,7 +1097,7 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname - 指定连接开始时发送到服务器的命令行选项。例如,将其设置为-c geqo=off会把会话的geqo参数值设为off。 + 指定连接开始时发送到服务器的命令行选项。例如,将其设置为-c geqo=off--geqo=off会把会话的geqo参数值设为off。 此字符串中的空格被视为分隔命令行参数,除非用反斜杠(\)转义;写\\表示字面上的反斜杠。 有关可用选项的详细讨论,请参阅 @@ -1515,12 +1555,20 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname sslrootcert - - 这个参数指定一个包含SSL证书颁发机构(CA)证书的文件名。 - 如果文件存在,服务器的证书将被验证是否由这些机构之一签名。 - 默认值是~/.postgresql/root.crt。 + 此参数指定包含 SSL 证书颁发机构(CA)证书的文件名。如果文件存在,则会验证服务器证书是否由这些机构之一签名。默认值为~/.postgresql/root.crt + + 也可以指定特殊值system,此时会加载 SSL 实现提供的受信任 CA 根证书。这些根证书的确切位置因 SSL 实现和平台而异。对于OpenSSL,还可以通过SSL_CERT_DIRSSL_CERT_FILE环境变量进一步修改这些位置。 + + + + 使用sslrootcert=system时,默认的sslmode会改为verify-full,任何较弱的设置都会引发错误。在大多数情况下,任何人都很容易为其控制的主机名获取受系统信任的证书,因此verify-ca及所有更弱的模式都无法发挥作用。 + + + 特殊值system优先于同名的本地证书文件。如果遇到这种情况,请改用其他路径,例如sslrootcert=./system。 + + @@ -1624,7 +1672,7 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname 这个参数指定该连接允许的最低协议版本。默认情况下,允许使用 libpq所支持的任何 PostgreSQL协议版本, - 目前即3.0。如果服务器至少不支持这一协议版本, + 目前即3.0。如果服务器不支持此协议版本或更高版本, 则连接将被关闭。 @@ -1646,7 +1694,7 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname 但如果连接字符串指定了依赖更高协议版本的特性,则会使用 libpq支持的最新版本。如果服务器不支持客户端请求的协议版本, 连接会自动降级为服务器支持的较低次版本协议。连接尝试完成后, - 你可以使用PQfullProtocolVersion()来确定 + 你可以使用来确定 最终协商得到的确切协议版本。 @@ -1703,7 +1751,7 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname scram_client_key - 以 Base64 编码的 SCRAM client key。外部数据包装器或类似中间件可以利用它启用透传式 SCRAM 认证。一个实现示例见。普通用户或客户端应用不应直接指定它。 + 以 Base64 编码的 SCRAM 客户端密钥。外部数据包装器或类似中间件可以利用它启用透传式 SCRAM 认证。一个实现示例见。普通用户或客户端应用不应直接指定它。 @@ -1712,7 +1760,7 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname scram_server_key - 以 Base64 编码的 SCRAM server key。外部数据包装器或类似中间件可以利用它启用透传式 SCRAM 认证。一个实现示例见。普通用户或客户端应用不应直接指定它。 + 以 Base64 编码的 SCRAM 服务器密钥。外部数据包装器或类似中间件可以利用它启用透传式 SCRAM 认证。一个实现示例见。普通用户或客户端应用不应直接指定它。 @@ -1980,7 +2028,7 @@ char *PQpass(const PGconn *conn); 将返回连接参数中指定的密码,如果连接参数中没有密码并且能从密码文件中得到密码,则它将返回得到的密码。 - 在后一种情况中,如果连接参数中指定了多个主机,在连接被建立之前都不能依赖的结果。连接的状态可以用函数检查。 + 在后一种情况中,如果连接参数中指定了多个主机,在连接被建立之前都不能依赖的结果。连接的状态可以用函数检查。 @@ -2134,19 +2182,15 @@ PGTransactionStatusType PQtransactionStatus(const PGconn *conn); - 查找服务器的一个当前参数设置。 + 查找服务器某个参数的当前设置。 const char *PQparameterStatus(const PGconn *conn, const char *paramName); - 某一参数值会被服务器在连接开始或值改变时自动报告。可以被用来询问这些设置。它为已知的参数返回当前值,为未知的参数返回NULL。 + 服务器会在连接启动时,以及某些参数值发生变化时,自动报告这些参数值。可用于查询这些设置。如果已知该参数,则返回其当前值;如果未知,则返回NULL - - - - 当前版本报告的参数包括: @@ -2166,16 +2210,29 @@ const char *PQparameterStatus(const PGconn *conn, const char *paramName); standard_conforming_strings TimeZone - (default_transaction_read_onlyin_hot_standby在 14 以前的版本中不被报告;scram_iterations在 16 以前的版本中不被报告;search_path在 18 以前的版本中不被报告。) - 注意 server_version 和 - server_encoding在启动之后无法改变。 - 此外,从 9.5 及更高版本开始,integer_datetimes总是 - on,而从 19 及更高版本开始, - standard_conforming_strings总是on。 + (14 之前的版本不报告 default_transaction_read_onlyin_hot_standby;16 之前的版本不报告 scram_iterations;18 之前的版本不报告 search_path。) + 注意,server_versionserver_encoding 在启动后不能改变。此外,integer_datetimes 在 9.5 及以后的版本中始终为 onstandard_conforming_strings 在 19 及以后的版本中始终为 on - 尽管被返回的指针被声明成const,它事实上指向与PGconn结构体相关的可变存储。假定该指针在存储之间保持有效是不明智的。 + 返回的指针虽然被声明为const,但实际上指向与PGconn结构体关联的可变存储。不能假定该指针在执行其他查询后仍然有效。 + + + + + + PQfullProtocolVersionPQfullProtocolVersion + + + + 查询正在使用的前端/后端协议。 + +int PQfullProtocolVersion(const PGconn *conn); + + 应用程序可以使用此函数确定是否支持某些功能。结果由服务器的协议主版本号乘以 10000,再加上次版本号组成。例如,版本 3.2 返回 30002,版本 4.0 返回 40000。如果连接无效,则返回零。PostgreSQL服务器 7.4 及更高版本支持 3.0 协议。 + + + 连接启动完成后,协议版本不会改变,但在连接重置期间,理论上可能改变。 @@ -2185,13 +2242,11 @@ const char *PQparameterStatus(const PGconn *conn, const char *paramName); - 询问所使用的 前端/后端协议。 + 查询前端/后端协议的主版本号。 int PQprotocolVersion(const PGconn *conn); - 应用可能希望用这个函数来确定某些特性是否被支持。当前,可能值是3(3.0 协议)或零(连接损坏)。 - 协议版本在连接启动完成后将不会改变,但是理论上在连接重置期间是可以改变的。 - 3.0 协议被PostgreSQL 7.4 或以后的服务器版本所支持。 + 与 不同,此函数仅返回正在使用的协议主版本号,但从 7.4 起的更多 libpq 版本均支持它。目前可能的值为 3(协议 3.0)或零(连接异常)。在 14.0 之前的版本中,libpq 还可能返回 2(协议 2.0)。 @@ -2310,6 +2365,22 @@ int PQconnectionUsedPassword(const PGconn *conn); + + + PQconnectionUsedGSSAPIPQconnectionUsedGSSAPI + + + 如果连接的认证方法使用了 GSSAPI,则返回真(1);否则返回假(0)。 + +int PQconnectionUsedGSSAPI(const PGconn *conn); + + + + + 此函数可用于检测连接是否使用 GSSAPI 进行了认证。 + + + @@ -2394,6 +2465,14 @@ const char *PQsslAttribute(const PGconn *conn, const char *attribute_name); + + alpn + + + TLS 应用层协议协商(ALPN)扩展选定的应用协议。libpq 唯一支持的协议是 postgresql,因此该属性主要用于检查服务器是否支持 ALPN。如果未使用 ALPN,则为空字符串。 + + + @@ -2410,13 +2489,16 @@ const char *PQsslAttribute(const PGconn *conn, const char *attribute_name); PQsslAttributeNamesPQsslAttributeNames - - 返回可用的SSL属性名称数组。 - 数组以NULL指针结尾。 + 返回可用于 PQsslAttribute() 的 SSL 属性名称数组。数组以 NULL 指针结尾。 const char * const * PQsslAttributeNames(const PGconn *conn); + + + + + 如果 conn 为 NULL,则返回默认 SSL 库可用的属性;如果 libpq 编译时未启用任何 SSL 支持,则返回空列表。如果 conn 不为 NULL,则返回该连接所用 SSL 库可用的属性;如果连接未加密,则返回空列表。 @@ -2596,7 +2678,7 @@ PGresult *PQexecParams(PGconn *conn, paramTypes[] - 通过 OID 指定要赋予给参数符号的数据类型。如果paramTypesNULL或者该数组中任何特定元素为零,服务器会用对待未知类型文字串的方式为参数符号推测一种数据类型。 + 通过 OID 指定要赋予给参数符号的数据类型。如果paramTypesNULL或者该数组中任何特定元素为零,服务器会用对待未指定类型的字符串字面量的方式为参数符号推测一种数据类型。 @@ -2690,10 +2772,10 @@ PGresult *PQprepare(PGconn *conn, 该函数从query串创建一个名为stmtName的预备语句,该串必须包含一个单一 SQL 命令。 stmtName可以是""来创建一个未命名语句,在这种情况下任何已存在未命名语句将被自动替换。 - 如果语句名称已经在当前会话中被定义,则是一种错误。如果使用了任何参数,它们在查询中以$1$2等引用。 + 否则,如果语句名称已经在当前会话中被定义,则是一种错误。如果使用了任何参数,它们在查询中以$1$2等引用。 nParams是参数的个数,其类型在数组paramTypes[]中被预先指定(当nParams为零时,该数组指针可以是NULL)。 paramTypes[]通过 OID 指定要赋予给参数符号的数据类型。 - 如果paramTypesNULL或者该数组中任何特定元素为零,服务器会用对待未知类型文字串的方式为参数符号推测一种数据类型。 + 如果paramTypesNULL或者该数组中任何特定元素为零,服务器会用对待未指定类型的字符串字面量的方式为参数符号推测一种数据类型。 还有,查询能够使用编号高于nParams的参数符号,它们的数据类型也会被自动推测(找出推测出的数据类型的方法见)。 @@ -2706,7 +2788,6 @@ PGresult *PQprepare(PGconn *conn, 用于的预备语句也能通过执行 SQL 语句来创建。 - 还有,尽管没有libpq函数来删除一个预备语句,SQL 语句可被用于此目的。 @@ -2954,13 +3035,21 @@ ExecStatusType PQresultStatus(const PGresult *res); - + + PGRES_TUPLES_CHUNK + + + PGresult包含当前命令返回的若干结果元组。此状态仅在为查询选择了分块模式时出现(参见)。元组数不会超过传递给的上限。 + + + + + PGRES_PIPELINE_SYNC - PGresult表示管道模式中的同步点,由请求。 - 此状态仅在选择管道模式时发生。 - + PGresult 表示管道模式中的同步点,由 请求。此状态仅在已选择管道模式时出现。 + @@ -3103,7 +3192,7 @@ char *PQresultErrorField(const PGresult *res, int fieldcode); PG_DIAG_MESSAGE_DETAIL - 细节:一个可选的次级错误消息,它携带了关于问题的等多细节。可能有多行。 + 细节:一个可选的次级错误消息,它携带了关于问题的更多细节。可能有多行。 @@ -3121,7 +3210,7 @@ char *PQresultErrorField(const PGresult *res, int fieldcode); PG_DIAG_STATEMENT_POSITION - 包含一个十进制整数的字符串,它表示一个错误游标位置,该位置是原始语句字符串的索引。第一个字符的索引是 1,位置以字符计算而不是以及字节计算。 + 包含一个十进制整数的字符串,它表示一个错误游标位置,该位置是原始语句字符串的索引。第一个字符的索引是 1,位置以字符计算而不是以字节计算。 @@ -3915,8 +4004,8 @@ unsigned char *PQescapeByteaConn(PGconn *conn, - 当某些字节值被用作一个SQL语句中的bytea文字的一部分时,它们必须被转义。 - 转义使用十六进制编码或反斜线转义的字节。详见。 + 当某些字节值被用作一个SQL语句中的bytea字面量的一部分时,它们必须被转义。 + 使用十六进制编码或反斜杠转义来转义这些字节。详见 @@ -3966,7 +4055,8 @@ unsigned char *PQescapeBytea(const unsigned char *from, - 将二进制数据的一个字符串表示转换成二进制数据 — 它是的逆向函数。当检索文本格式的bytea数据时,需要这个函数,但检索二进制个事时则不需要它。 + 将二进制数据的字符串表示转换为二进制数据,这是的逆操作。 + 以文本格式取得bytea数据时需要此操作;以二进制格式取得时则不需要。 unsigned char *PQunescapeBytea(const unsigned char *from, size_t *to_length); @@ -3974,14 +4064,15 @@ unsigned char *PQunescapeBytea(const unsigned char *from, size_t *to_length); - from参数指向一个字符串,例如被应用到一个bytea列上所返回的。 - 把这个串表示转换成它的二进制表示。 - 它返回一个指向用malloc()分配的缓冲区的指针,在错误时返回NULL,并且把缓冲区的尺寸放在to_length中。 - 当结果不再需要时,它必须使用释放。 + from参数指向一个字符串,例如对bytea列调用时返回的字符串。 + 将这个字符串表示转换为二进制表示。 + 它返回指向通过malloc()分配的缓冲区的指针,出错时返回NULL,并将缓冲区大小存入to_length。 + 不再需要结果时,必须使用释放它。 - 这种转换并不完全是PQescapeBytea的逆函数,因为当从PQgetvalue接收到字符串时,我们并不能期待它被转义。特别地这意味着不需要考虑字符串引用,并且因此也不需要一个参数。 + 此转换并不完全是的逆操作,因为从收到的字符串并非经过转义的形式。 + 具体而言,这意味着无需考虑字符串引号,因此也不需要PGconn参数。 @@ -4030,26 +4121,17 @@ unsigned char *PQunescapeBytea(const unsigned char *from, size_t *to_length); - - 不喜欢这些限制的应用程序可以使用构建自的底层函数: - 。 - 还有 - , - , - , - , - , - 以及 - , - 它们可以与配合使用,分别复制 - , - , - , - , - , - 和 - - 的功能。 + 如果应用程序不希望受到这些限制,可以改用构成的底层函数:。此外,还有, + , + , + , + , + ,以及,它们可以与配合使用,分别实现以下函数的功能:, + , + , + , + , + ,以及 @@ -4224,15 +4306,16 @@ int PQsendClosePortal(PGconn *conn, const char *portalName); - 等待来自先前的、 + 等待先前的 、 - 或 - - 调用的下一个结果,并返回它。 - 当命令完成且不会再有更多结果时,将返回空指针。 + 、 + 、 + 、 + 或 + 调用产生的下一个结果,并返回该结果。当命令执行完毕且不再有其他结果时,返回空指针。 PGresult *PQgetResult(PGconn *conn); @@ -4336,7 +4419,7 @@ int PQisBusy(PGconn *conn); 一个使用/的客户端也可以尝试取消一个正在被服务器处理的命令,见。 - 但是,不管的返回值是什么,应用都必须继续使用进行正常的结果读取序列。一次成功的取消只会导致命令比不取消时更快终止。 + 但是,不管的返回值是什么,应用都必须继续使用进行正常的结果读取序列。一次成功的取消只会导致命令比不取消时更快终止。 @@ -4499,68 +4582,42 @@ int PQflush(PGconn *conn); - 发出查询 - 进入管道模式后,应用程序使用或其姊妹函数来分派请求。 - 这些请求在客户端排队,直到刷新到服务器端;当使用建立管道中的同步点时,或者调用时,会发生这种情况。 - 函数在管道模式下也可以工作。 - 结果处理如下所述。 + 进入管道模式后,应用程序使用 或其处理预备查询的对应函数 发送请求。这些请求在客户端排队,直到发送到服务器;使用 在管道中建立同步点,或调用 时会发送它们。函数 、&zwsp;、&zwsp;、&zwsp; 也可用于管道模式。结果处理方式见下文。 - 服务器执行语句,并返回结果,按客户端发送它们的顺序。 - 服务器将立即开始执行管道中的命令,不等待管道的结束。 - 注意,结果被缓冲在服务器端;当使用PQpipelineSync建立同步点时,或者PQsendFlushRequest被调用时,服务器会刷新该缓冲区。 - 如果任何语句遇到错误,服务器将中止当前事务,并且不执行队列中的任何后续命令,直到下一个同步点;对于每一个这样的命令都会产生一个PGRES_PIPELINE_ABORTED结果。 - (即使管道中的命令将回滚事务,依然如此。) - 查询处理在同步点之后恢复。 + 服务器按客户端发送的顺序执行语句并返回结果。服务器会立即开始执行管道中的命令,无需等待管道结束。结果会缓存在服务器端;使用 PQpipelineSyncPQsendPipelineSync 建立同步点,或调用 PQsendFlushRequest 时,服务器会发送该缓冲区中的数据。如果任何语句发生错误,服务器会中止当前事务,并停止执行队列中的后续命令,直到下一个同步点;每条被跳过的命令都会产生一个 PGRES_PIPELINE_ABORTED 结果。(即使管道中的命令会回滚事务,也仍然如此。)到达同步点后,查询处理恢复。 - 一个操作依赖于前一个操作的结果是没问题的; - 例如,一个查询可以定义一个同一管道中的下一个查询将用到的表。 - 类似地,应用可以创建一个命名的预备语句,并在同一管道中与后续语句一起执行它。 + 一个操作可以依赖先前操作的结果;例如,一个查询可以定义一张表,供同一管道中的下一个查询使用。类似地,应用程序可以创建命名的预备语句,并通过同一管道中后续的语句执行它。 - 处理结果 - 为了在管道中处理一个查询的结果,应用重复调用PQgetResult并处理每个结果,直到PQgetResult返回空。 - 可以再次使用PQgetResult检索管道中下一个查询的结果,并且循环重复 - 应用像通常一样处理单个语句结果。 - 当管道中所有查询的结果都返回时,PQgetResult返回一个结果,其包含状态值PGRES_PIPELINE_SYNC。 - - - - 客户端可以选择延迟结果处理,直到完整的管道被发送,或者与管道中发送的更多的查询交错在一起;参见。 + 要处理管道中一个查询的结果,应用程序应重复调用 PQgetResult 并处理每个结果,直到 PQgetResult 返回空指针。然后再次调用 PQgetResult 获取管道中下一个查询的结果,重复这一过程。应用程序按通常方式处理各条语句的结果。当管道中所有查询的结果都已返回时,PQgetResult 会返回一个包含状态值 PGRES_PIPELINE_SYNC 的结果。 - 要进入单行模式,在使用PQgetResult检索结果之前调用PQsetSingleRowMode。 - 此模式选择仅对当前处理的查询有效。 - 有关使用PQsetSingleRowMode的更多信息,请参阅。 + 客户端可以等到整条管道发送完毕后再处理结果,也可以在继续发送管道中的查询时交错处理结果;参见 - PQgetResult行为与普通异步处理相同,除了它可能包含新的PGresult类型PGRES_PIPELINE_SYNCPGRES_PIPELINE_ABORTED。 - 对于每个在管道中相应的点的PQpipelineSyncPGRES_PIPELINE_SYNC确定报告一次。 - PGRES_PIPELINE_ABORTED在第一个错误和所有后续结果的正常查询结果中发出,直到下一个PGRES_PIPELINE_SYNC;参见。 + PQgetResult 的行为与普通异步处理相同,只是返回结果可能具有新的 PGresult 类型 PGRES_PIPELINE_SYNCPGRES_PIPELINE_ABORTED。对于每次 PQpipelineSyncPQsendPipelineSync 调用,都会在管道中的对应位置恰好报告一次 PGRES_PIPELINE_SYNC。对于第一个错误及其后的所有结果,会用 PGRES_PIPELINE_ABORTED 代替正常查询结果,直到下一个 PGRES_PIPELINE_SYNC;参见 - PQisBusyPQconsumeInput、等正常操作,在处理管道结果时。 - 特别是,在管道中间调用PQisBusy 时,如果到目前为止发出的所有查询的结果都已被消耗,则返回0。 + PQisBusyPQconsumeInput 等函数在处理管道结果时照常工作。特别地,在管道处理过程中调用 PQisBusy 时,如果到目前为止已发出查询的所有结果均已被消费,则返回 0。 - libpq不向应用提供有关当前正在处理的查询的任何信息(除了PQgetResult返回空,以表示我们开始返回下一个查询的结果)。 - 应用必须保持跟踪它发送查询的顺序,以将它们与相应的结果相关联。 - 应用通常会为此使用状态机或FIFO队列。 + libpq 不向应用程序提供当前正在处理哪个查询的信息(除了 PQgetResult 返回空指针,表示开始返回下一个查询的结果)。应用程序必须跟踪查询的发送顺序,以便将查询与对应结果关联起来。应用程序通常会使用状态机或 FIFO 队列实现这一点。 @@ -4607,7 +4664,7 @@ int PQflush(PGconn *conn); 客户端应用通常应该维护一个尚未分派的工作队列和一个已分派但尚未处理结果的工作队列。 当套接字是可写时,它将可以分派更多的工作。 当套接字是可读时,它将读取结果并处理它们,将它们匹配到相应结果队列中的下一个条目。 - 基于可用内存,来自套接字的结果将被经常读取:这里不需要等到管道结束才读取结果。 + 基于可用内存,来自套接字的结果将被经常读取:这里不需要等到管道结束才读取结果。 管道将范围涵盖到工作的逻辑单元,通常(但不是必然)每个管道一个事务。 在管道之间,不需要退出管道模式再重新进入管道模式,也不需要等待一个管道结束后再发送下一个。 @@ -4638,7 +4695,7 @@ PGpipelineStatus PQpipelineStatus(const PGconn *conn); - PQpipelineStatus 可以返回下列值中的一个: + PQpipelineStatus 可以返回下列值中的一个: @@ -4782,8 +4839,8 @@ int PQsendFlushRequest(PGconn *conn); - 当PQpipelineSync被调用的结果,或者在非管道模式下的任何请求时,服务器自动刷新它的输出缓冲区;这个函数用于使得服务器在不建立同步点的情况下以管道模式刷新其输出缓冲区。 - 请注意,请求不是自身能自动刷新到服务器;如果需要时使用PQflush。 + 当PQpipelineSync被调用的结果,或者在非管道模式下的任何请求时,服务器自动刷新它的输出缓冲区;这个函数用于使得服务器在不建立同步点的情况下以管道模式刷新其输出缓冲区。 + 请注意,请求不是自身能自动刷新到服务器;如果需要时使用PQflush @@ -4803,7 +4860,7 @@ int PQsendFlushRequest(PGconn *conn); 当服务器比较远,即网络延迟(ping time)高的时候,管道模式最有用,以及在许多小操作正在快速连续执行的时候。 当每个查询的执行时间是客户端/服务器往返时间的许多倍时,使用管道命令的优势通常会更少。 - 不用管道模式,在往返时间为300毫秒的服务器上运行一个100条语句的操作,仅网络延迟就需要30秒;使用管道,等待来自服务器的结果可能只消耗仅仅0.3秒。 + 不用管道模式,在往返时间为300毫秒的服务器上运行一个100条语句的操作,仅网络延迟就需要30秒;使用管道,等待来自服务器的结果可能只消耗仅仅0.3秒。 @@ -4814,7 +4871,7 @@ int PQsendFlushRequest(PGconn *conn); 当来自一个操作的信息需要客户端产生下一个操作时,管道模式是没有用的。 在这种情况下,客户机将不得不引入一个同步点,并等待完整的客户端/服务器往返以获取它需要的结果。 但是,通常可以调整客户端设计以交换服务器端所需的信息。 - 读-修改-写循环是非常好的选择;例如: + 读-修改-写循环是非常好的选择;例如: BEGIN; SELECT x FROM mytable WHERE id = 42 FOR UPDATE; @@ -4823,7 +4880,7 @@ SELECT x FROM mytable WHERE id = 42 FOR UPDATE; UPDATE mytable SET x = 3 WHERE id = 42; COMMIT; - 可以更有效地开展以下工作: + 可以更有效地开展以下工作: UPDATE mytable SET x = x + 1 WHERE id = 42; @@ -4840,12 +4897,12 @@ UPDATE mytable SET x = x + 1 WHERE id = 42; libpq - single-row mode + 单行模式 libpq - chunked mode + 分块模式 @@ -5225,22 +5282,23 @@ void PQfreeCancel(PGcancel *cancel); - 请求服务器放弃当前命令的处理。 + 的一个已弃用且不安全的变体,但可以在信号处理程序中安全调用。 int PQcancel(PGcancel *cancel, char *errbuf, int errbufsize); + - 返回值为 1 表示取消请求成功发送,为 0 表示未成功发送。如果未成功发送,errbuf将填充解释性错误消息。errbuf必须是大小为errbufsize的字符数组(推荐大小为 256 字节)。 + 仅因向后兼容而保留,应改用 唯一的优势在于:当 errbuf 是信号处理程序中的局部变量时,可以在信号处理程序中安全调用它。不过,通常认为这一优势不足以抵消该函数的安全问题。 - 取消请求成功分派并不保证一定会产生效果。如果取消成功,当前命令会提前终止并返回错误结果;如果取消失败(例如服务器已经处理完该命令),则不会有任何可见结果。 + 对于 而言,PGcancel 对象是只读的,因此也可以从与操作 PGconn 对象的线程不同的线程中调用它。 - 如果errbuf是信号处理程序中的局部变量,则可以安全地从信号处理程序中调用。对于而言,PGcancel对象是只读的,因此也可以从与操作PGconn对象的线程不同的线程中调用。 + 的返回值为 1 表示取消请求成功发送,为 0 表示未成功发送。如果未成功发送,errbuf 将填充解释性错误消息。errbuf 必须是大小为 errbufsize 的字符数组(推荐大小为 256 字节)。 @@ -5252,14 +5310,19 @@ int PQcancel(PGcancel *cancel, char *errbuf, int errbufsize); - 的一个已废弃变体。 + 的一个已弃用且不安全的变体。 int PQrequestCancel(PGconn *conn); + - 请求服务器放弃当前命令的处理。它直接作用于PGconn对象,失败时会把错误消息存储到PGconn对象中(可通过获取)。虽然功能相同,但这种方法在多线程程序或信号处理程序中并不安全,因为它可能覆盖PGconn中的错误消息,从而破坏当前连接上正在进行的操作。 + 仅因向后兼容而保留,应改用 。与 相比,使用 没有任何优势。 + + + + 请求服务器放弃当前命令的处理。它直接作用于 PGconn 对象,失败时会把错误消息存储到 PGconn 对象中(可通过 获取)。虽然功能相同,但这种方法在多线程程序或信号处理程序中并不安全,因为它可能覆盖 PGconn 中的错误消息,从而破坏当前连接上正在进行的操作。 @@ -5513,7 +5576,7 @@ int PQgetCopyData(PGconn *conn, 当async为真时(非零),将不会阻塞等待输入; 如果COPY仍在处理过程中并且没有可用的完整行,那么它将返回零 (在这种情况下等待读准备好,然后在再次调用之前,调用)。 - 当async为假(零)时,PQgetCopyData将阻塞,直到数据可用或者操作完成。 + 当async为假(零)时,将阻塞,直到数据可用或者操作完成。 @@ -5813,7 +5876,7 @@ void PQtrace(PGconn *conn, FILE *stream); - 每行包括:一个可选的时间戳,一个方向指示器(F表示从客户端到服务器的消息或B表示从服务器到客户端的消息),消息长度、消息类型、和消息内容。 + 每行包括:一个可选的时间戳,一个方向指示器(F表示从客户端到服务器的消息或B表示从服务器到客户端的消息),消息长度、消息类型、和消息内容。 非消息内容字段(时间戳、方向、长度和消息类型)由一个制表符分隔。 消息内容用空格分隔。 协议字符串用双引号括起来,而用作数据值的字符串用单引号括起来。 @@ -5987,7 +6050,7 @@ PGresult *PQchangePassword(PGconn *conn, const char *user, const char *passwd); char *PQencryptPassword(const char *passwd, const char *user); - 的一个较老的已经被废弃的版本。其差别是不要求一个连接对象,并且总是用md5作为加密算法。 + 的旧版本,现已弃用。其差别是不需要连接对象,并且总是用md5作为加密算法。 @@ -6007,11 +6070,12 @@ PGresult *PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status); 这是libpq内部用于分配并初始化一个空PGresult对象的函数。 - 如果不能分配内存,那么这个函数返回NULL。 - 它也是可以对外使用的,因为一些应用认为它可以用于产生结果对象(特别是带有错误状态的对象)本身。 - 如果conn非空,并且status表示一个错误,那么指定连接的当前错误消息会被复制到PGresult中。 - 如果conn非空,那么连接中的任何已注册事件过程也会被复制到PGresult中(它们不会获得PGEVT_RESULTCREATE调用,但会看到)。 - 注意在该对象上最终应该调用,正如对libpq本身返回的PGresult对象所作的那样。 + 如果无法分配内存,此函数返回NULL。 + 将它导出供外部调用,是因为一些应用需要自行生成结果对象,特别是带有错误状态的对象。 + 如果conn非空,并且status表示错误,指定连接的当前错误消息会被复制到PGresult中。 + 此外,如果conn非空,连接中注册的所有事件过程也会被复制到PGresult中。 + (这些过程不会收到PGEVT_RESULTCREATE调用,但可参见。) + 注意,最终应对该对象调用,就像处理libpq自身返回的PGresult一样。 @@ -6191,6 +6255,23 @@ int PQlibVersion(void); + + PQgetCurrentTimeUSecPQgetCurrentTimeUSec + + + + 获取当前时间,以自 Unix 纪元以来的微秒数表示(即time_t乘以一百万)。 + +pg_usec_time_t PQgetCurrentTimeUSec(void); + + + + + 此函数主要用于计算供使用的超时值。 + + + + @@ -6371,8 +6452,8 @@ typedef struct - 结果创建事件是响应任何生成结果的查询执行函数而触发的,包括 - 。此事件只会在结果成功创建后触发。 + 任何生成结果的查询执行函数都会触发结果创建事件,其中包括。 + 只有成功创建结果后才会触发该事件。 typedef struct @@ -6382,11 +6463,9 @@ typedef struct } PGEventResultCreate; - 当接收到PGEVT_RESULTCREATE事件时, - 应将evtInfo指针转换为 - PGEventResultCreate *。 - conn是用于生成结果的连接。 - 这是初始化需要与结果关联的任何instanceData的理想位置。 + 收到PGEVT_RESULTCREATE事件时,应将evtInfo指针转换为PGEventResultCreate *。 + 其中,conn是用于生成结果的连接。 + 这是初始化需要与结果关联的instanceData的理想位置。 如果事件过程失败(返回零),那么该事件过程将在结果的剩余生命周期内被忽略; 也就是说,它将不会接收到针对此结果或从中复制的结果的 PGEVT_RESULTCOPYPGEVT_RESULTDESTROY事件。 @@ -6756,6 +6835,15 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough) + + + + PGSSLNEGOTIATION + + PGSSLNEGOTIATION的行为与连接参数相同。 + + + @@ -6824,6 +6912,15 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough) + + + + PGREQUIREAUTH + + PGREQUIREAUTH的行为与连接参数相同。 + + + @@ -6934,6 +7031,15 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough) + + + + PGSSLCERTMODE + + PGSSLCERTMODE的行为与连接参数相同。 + + + @@ -7044,6 +7150,15 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough) + + + + PGGSSDELEGATION + + PGGSSDELEGATION的行为与连接参数相同。 + + + @@ -7077,6 +7192,33 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough) + + + PGLOADBALANCEHOSTS + + PGLOADBALANCEHOSTS的行为与连接参数相同。 + + + + + + + PGMINPROTOCOLVERSION + + PGMINPROTOCOLVERSION的行为与连接参数相同。 + + + + + + + PGMAXPROTOCOLVERSION + + PGMAXPROTOCOLVERSION的行为与连接参数相同。 + + + + PGOAUTHCAFILE @@ -7161,20 +7303,15 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough) - 用户的主目录中的文件.pgpass可以包含密码, - 如果连接需要密码(且未指定其他密码)。在Microsoft Windows中, - 该文件的名称为%APPDATA%\postgresql\pgpass.conf - (其中%APPDATA%指用户配置文件中的应用数据子目录)。 - 或者,可以使用连接参数 - 或环境变量PGPASSFILE指定要使用的密码文件。 - + 用户主目录中的.pgpass文件可保存密码,供连接需要密码且尚未通过其他方式指定密码时使用。在 Unix 系统上,该目录可由HOME环境变量指定;如果未定义该变量,则使用有效用户的主目录。在 Microsoft Windows 上,文件名为%APPDATA%\postgresql\pgpass.conf(其中%APPDATA%指用户配置文件中的应用数据子目录)。也可以通过连接参数或环境变量PGPASSFILE指定要使用的密码文件。 + 这个文件应该包含下列格式的行: hostname:port:database:username:password - (你可以向该文件增加一个提醒:把上面的行复制到该文件并且在前面加上#)。前四个域的每一个都可以是文字值或者匹配任何东西的*。第一个匹配当前连接参数的行中的密码域将被使用(因此,在使用通配符时把更特殊的项放在前面)。如果一个条目需要包含:或者\,用\对该字符转义。如果指定了host连接参数,主机名字段会被匹配到host,否则如果指定了hostaddr参数则匹配到hostaddr,如果两者都没有给出,则会搜索主机名localhost。当连接是一个Unix域套接字连接并且host参数匹配libpq的默认套接字目录路径时,也会搜索主机名localhost。在一台备库上,值为replication的数据库字段匹配连接到主库的流复制连接。否则数据库字段的用途有限,因为用户对同一个集簇中的所有数据库都有相同的密码。 + (你可以向该文件增加一个提醒:把上面的行复制到该文件并且在前面加上#)。前四个字段的每一个都可以是字面值或者匹配任何东西的*。第一个匹配当前连接参数的行中的密码字段将被使用(因此,在使用通配符时把更特殊的项放在前面)。如果一个条目需要包含:或者\,用\对该字符转义。如果指定了host连接参数,主机名字段会被匹配到host,否则如果指定了hostaddr参数则匹配到hostaddr,如果两者都没有给出,则会搜索主机名localhost。当连接是一个Unix域套接字连接并且host参数匹配libpq的默认套接字目录路径时,也会搜索主机名localhost。在一台备库上,值为replication的数据库字段匹配连接到主库的流复制连接。否则数据库字段的用途有限,因为用户对同一个集簇中的所有数据库都有相同的密码。 @@ -7603,16 +7740,14 @@ ldap://ldap.acme.com/cn=dbserver,cn=hosts?pgconnectinfo?base?(objectclass=*) - SSL 库初始化 - 如果您的应用程序初始化libssl和/或libcrypto库,并且libpq - 构建时带有SSL支持,您应该调用告诉libpq - libssl和/或libcrypto库已被您的应用程序初始化,以便 - libpq不会再初始化这些库。 - 但是,当使用OpenSSL版本1.1.0或更高版本时,重复初始化不再成问题。 - + 需要兼容旧版 PostgreSQL、使用 OpenSSL 1.0.2 或更早版本的应用程序,需要在使用 SSL 库之前初始化它。自行初始化 libssl 和/或 libcrypto 库的应用程序应调用 ,告知 libpq 这些库已由应用程序初始化,使 libpq 不再初始化它们。不过,使用 OpenSSL 1.1.0 或更高版本时无需这样做,因为重复初始化已不再造成问题。 + + + 有关这些函数的用法,请参阅目标 PostgreSQL 版本的文档。 + @@ -7621,44 +7756,35 @@ ldap://ldap.acme.com/cn=dbserver,cn=hosts?pgconnectinfo?base?(objectclass=*) - 允许应用选择要初始化哪个安全性库。 + 允许应用程序选择要初始化的安全库。 void PQinitOpenSSL(int do_ssl, int do_crypto); - - - 当do_ssl是非零时,libpq将在第一次打开数据库连接前初始化OpenSSL库。 - 当do_crypto是非零时,libcrypto库将被初始化。 - 默认情况下(如果没有调用),两个库都会被初始化。 - 当 SSL 支持没有被编译时,这个函数也存在但是什么也不做。 - 如果你的应用使用并且初始化OpenSSL或者它的底层libcrypto库,你必须在第一次打开数据库连接前以合适的非零参数调用这个函数。 - 同时要确保在打开一个数据库连接前已经完成了初始化。 + 此函数已弃用,仅为向后兼容而保留,不执行任何操作。 PQinitSSLPQinitSSL - - 允许应用选择要初始化哪个安全性库。 + 允许应用程序选择要初始化的安全库。 void PQinitSSL(int do_ssl); + - 这个函数等效于PQinitOpenSSL(do_ssl, do_ssl)。 - 这对于要么初始化OpenSSL以及libcrypto要么都不初始化的应用足够用了。 + 此函数等价于 PQinitOpenSSL(do_ssl, do_ssl)。此函数已弃用,仅为向后兼容而保留,不执行任何操作。 - PostgreSQL 8.0 就存在了, - 而直到PostgreSQL 8.4 才被加入,因此可能对那些需要与旧版本libpq一起工作的应用来说更合适。 + 为向后兼容而保留,但从 PostgreSQL 18 起已不再需要。PostgreSQL 8.0 起就已存在,而 是在 PostgreSQL 8.4 中加入的,因此对于需要兼容旧版本 libpq 的应用程序, 可能更合适。 @@ -8018,8 +8144,8 @@ PGOAUTHDEBUG=UNSAFE:http,call-count 危险选项与安全选项 在线程化程序中的行为 - threads - with libpq + 线程 + 用于 libpq diff --git a/zh/20/localize-generated.py b/zh/20/localize-generated.py index 831638fd..545b0425 100644 --- a/zh/20/localize-generated.py +++ b/zh/20/localize-generated.py @@ -1,9 +1,9 @@ #!/usr/bin/env python3 -"""Apply only PG18.6-to-PG20 changed generated descriptions after regeneration. +"""Apply reviewed Chinese translations after regenerating the pinned PG20 input. Keep upstream generators and inputs intact. Each input/output is hash-bound; -unchanged descriptions retain the inherited generated English. The map is -reviewed source; generated SGML stays in the isolated build workspace. +the map is the maintained translation source, including the complete wait-event +tables. Generated SGML stays in the isolated build workspace. """ import hashlib import json diff --git a/zh/20/logical-replication.sgml b/zh/20/logical-replication.sgml index d7ec6981..02d05600 100644 --- a/zh/20/logical-replication.sgml +++ b/zh/20/logical-replication.sgml @@ -239,7 +239,7 @@ 如前所述,每个(活动)订阅都使用远端(发布侧)的一个逻辑复制槽。 - 额外的表同步槽通常是临时的,由系统内部创建用于执行初始表同步,在不再需要时 + 额外的表同步槽通常只会短暂存在,由系统内部创建用于执行初始表同步,在不再需要时 自动删除。这些表同步槽的名称是自动生成的: pg_%u_sync_%u_%llu (参数分别为:订阅 oid、 @@ -431,7 +431,7 @@ 注意在常规复制阶段会使用相应的 publish 操作。 这意味着发布 pub2pub3a 不会复制 - INSERT。另外,发布 pub3b 只会复制与其 + INSERT。另外,发布 pub3b 只会复制与 pub3b 的 行过滤器匹配的数据。现在订阅端数据如下: /* sub # */ SELECT * FROM t1; @@ -626,7 +626,7 @@ HINT: To initiate replication, you must manually create the replication slot, e - 要确认某个订阅对应的备库确实已做好故障切换准备,请按下列步骤验证该订阅需要的 + 要确认备库确实已为某个订阅端做好故障切换准备,请按下列步骤验证该订阅端需要的 所有逻辑复制槽都已同步到备库: @@ -695,7 +695,7 @@ HINT: To initiate replication, you must manually create the replication slot, e 上述步骤中的前两步针对的是 PostgreSQL 订阅端。 - 建议在每次故障切换后,都在将由目标备库服务的各个订阅节点上执行这两步,以获得完整的复制槽 + 建议在每个将于故障切换后由指定备库提供服务的订阅端节点上执行这两步,以获得完整的复制槽 列表,然后在第 3 步中统一验证故障切换就绪状态。 非 PostgreSQL 订阅端则可使用其自身方法识别各自订阅使用的复制槽。 @@ -1588,7 +1588,7 @@ Included in publications: 序列同步工作进程,并在序列同步完成后退出。 - 启动序列同步工作进程的数量受 + 能否启动序列同步工作进程受 max_sync_workers_per_subscription 配置项限制。 @@ -2017,7 +2017,7 @@ DETAIL: detailed_explanation[: 解决方法可以是修改订阅端上的数据或权限,使其不再与传入变更冲突;也可以跳过与 - 现有数据冲突的事务。当冲突导致错误时,复制不会继续,逻辑复制工作者会向订阅端 + 现有数据冲突的事务。当冲突导致错误时,复制不会继续,逻辑复制工作进程会向订阅端 的服务器日志输出如下消息: ERROR: conflict detected on relation "public.test": conflict=insert_exists @@ -2029,8 +2029,8 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER (在上述示例中分别是 LSN 0/014C0378 和复制源 pg_16395)。 可以使用 ALTER SUBSCRIPTION ... SKIP - 并提供 finish LSN(即 LSN 0/014C0378)来跳过产生冲突的事务。这个 finish LSN - 可以是该事务在发布端提交或准备完成时的 LSN。或者,也可以调用 + 并提供 完成 LSN(即 LSN 0/014C0378)来跳过产生冲突的事务。这个 完成 LSN + 可以是该事务在发布端提交或预备时的 LSN。或者,也可以调用 pg_replication_origin_advance() 函数来跳过该事务。 在使用此函数之前,需要暂时禁用订阅,可以使用 @@ -2039,7 +2039,7 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER disable_on_error 选项。然后,可以使用 pg_replication_origin_advance() 函数, 传入 node_name(即 pg_16395) - 以及 finish LSN 的下一个 LSN(即 0/014C0379)。当前各复制源的位置可以在 + 以及 完成 LSN 的下一个 LSN(即 0/014C0379)。当前各复制源的位置可以在 pg_replication_origin_status 系统视图中查看。 请注意,跳过整个事务也会跳过那些本来可能不违反任何约束的变更,这很容易导致 @@ -2054,10 +2054,10 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER streaming - 模式为 parallel 时,失败事务的 finish LSN 可能不会被记录。 + 模式为 parallel 时,失败事务的 完成 LSN 可能不会被记录。 这种情况下,可能需要把 streaming 模式改为 on 或 - off,并再次触发相同的冲突,以便将失败事务的 finish LSN - 写入服务器日志。关于 finish LSN 的用法,请参见 + off,并再次触发相同的冲突,以便将失败事务的 完成 LSN + 写入服务器日志。关于 完成 LSN 的用法,请参见 ALTER SUBSCRIPTION ... SKIP @@ -2075,9 +2075,9 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER 数据库模式和 DDL 命令不会被复制。初始模式可以手工使用 pg_dump --schema-only 复制。之后的模式更改需要手工保持同步。 (不过请注意,两端的模式其实不需要绝对一致。)当活动数据库中的模式定义发生变化时, - 逻辑复制仍然具有一定鲁棒性:如果发布端修改了模式,而复制数据开始到达订阅端时 + 逻辑复制仍然能够稳健运行:如果发布端修改了模式,而复制数据开始到达订阅端时 与表模式不匹配,复制就会报错,直到模式被更新。在很多情况下,可以通过先在订阅端 - 应用增量式的模式变更来避免间歇性错误。 + 应用仅添加内容的模式变更来避免间歇性错误。 @@ -2142,7 +2142,7 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER 对已发布表使用 REPLICA IDENTITY FULL 时,需要注意:如果表中包含某些数据类型的属性(例如 point 或 box),而这些类型 - 没有 B-tree 或 Hash 的默认操作符类,那么 UPDATE 和 + 没有 B-树 或 Hash 的默认操作符类,那么 UPDATEDELETE 操作就无法在订阅端应用。不过,可以通过确保该表具有 主键或已定义复制标识来规避这一限制。 @@ -2184,9 +2184,9 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER 初始快照 对现有订阅表中的初始数据,会取快照并由一种特殊应用进程的并行实例来复制。 - 这些特殊的应用进程是为每张待同步表启动的专用表同步工作者。每个表同步进程 + 这些特殊的应用进程是为每张待同步表启动的专用表同步工作进程。每个表同步进程 都会创建自己的复制槽,并复制现有数据。复制一完成,该表内容就会对其他后端可见。 - 现有数据复制完成后,工作者会进入同步模式,通过标准逻辑复制流式发送在初始数据 + 现有数据复制完成后,工作进程会进入同步模式,通过标准逻辑复制流式发送在初始数据 复制期间发生的任何变更,使该表与主应用进程达到同步状态。在这一同步阶段, 变更会按照它们在发布端发生的顺序被应用和提交。同步完成后,该表的复制控制权 会交还给主应用进程,之后复制将照常继续。 @@ -2200,8 +2200,8 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER - 如果表同步工作者在复制期间失败,应用工作者会检测到这一失败,并重新启动表同步 - 工作者以继续同步过程。这种行为确保了瞬时错误不会永久破坏复制配置。另见 + 如果表同步工作进程在复制期间失败,应用工作进程会检测到这一失败,并重新启动表同步 + 工作进程以继续同步过程。这种行为确保了瞬时错误不会永久破坏复制配置。另见 wal_retrieve_retry_interval @@ -2221,14 +2221,14 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER 与订阅相关的监控信息可在 pg_stat_subscription - 中查看。这个视图为每个订阅工作者包含一行。一个订阅根据其状态,可能有零个或多个 - 活跃的订阅工作者。 + 中查看。这个视图为每个订阅工作进程包含一行。一个订阅根据其状态,可能有零个或多个 + 活跃的订阅工作进程。 通常,一个已启用的订阅会有一个应用进程在运行。被禁用的订阅或已崩溃的订阅在这个 视图中将没有任何行。如果某张表的初始数据同步正在进行,则还会有针对这些正在同步 - 的表的额外工作者。并且,如果使用 + 的表的额外工作进程。并且,如果使用 streaming 并以并行方式应用事务,则还可能出现额外的并行应用工作进程。 @@ -2317,14 +2317,14 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER - 在订阅端,订阅所有者的权限会在每个事务应用时重新检查。如果某个工作者正在应用 + 在订阅端,订阅所有者的权限会在每个事务应用时重新检查。如果某个工作进程正在应用 事务时,订阅的所有权被并发事务更改,那么当前事务的应用仍会继续使用旧所有者的 权限。 - 配置参数 + 配置设置 逻辑复制需要设置若干配置选项。这些选项只在复制的一侧生效。 @@ -2380,7 +2380,7 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER max_logical_replication_workers - 必须至少设置为订阅数量(用于主应用工作进程),再加上并行应用工作进程、 + 必须至少设置为订阅数量(用于领导者应用工作进程),再加上并行应用工作进程、 表同步工作进程和序列同步工作进程的预留。 @@ -2395,7 +2395,7 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER max_sync_workers_per_subscription - 控制订阅初始化或新增表时,可以并行同步多少张表。序列同步还需要一个额外工作者。 + 控制订阅初始化或新增表时,可以并行同步多少张表。序列同步还需要一个额外工作进程。 @@ -2521,8 +2521,8 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER - 旧订阅端中所有订阅表应处于 i(initialize) - 或 r(ready)状态。 + 旧订阅端中所有订阅表应处于 i(初始化) + 或 r(就绪)状态。 可通过检查 pg_subscription_rel.srsubstate 验证。 @@ -2545,8 +2545,8 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER - 如果存在启用了 retain_dead_tuples 的订阅,新集簇中保留复制槽 - pg_conflict_detection 不能存在。此外,新集簇上的 + 如果存在启用了 retain_dead_tuples 的订阅,新集簇中不能存在保留的复制槽 + pg_conflict_detection。此外,新集簇上的 wal_level 必须设置为 replicalogical diff --git a/zh/20/logicaldecoding.sgml b/zh/20/logicaldecoding.sgml index 7c53100c..c1df90aa 100644 --- a/zh/20/logicaldecoding.sgml +++ b/zh/20/logicaldecoding.sgml @@ -271,7 +271,7 @@ postgres=# SELECT * from pg_logical_slot_get_changes('regression_slot', NULL, NU 需要各个进程之间的同步,因此可保证系统范围内的一致性。反之,如果 wal_level 设为 replica,并且最后 一个逻辑复制槽被删除或失效,则逻辑解码会自动停用。请注意,这种停用可能 - 需要一些时间,因为它是由 检查点进程异步完成的。 + 需要一些时间,因为它是由检查点进程异步完成的。 @@ -394,7 +394,7 @@ postgres=# SELECT * from pg_logical_slot_get_changes('regression_slot', NULL, NU 中列出的槽,向逻辑订阅者发送更改时仍然会有一定延迟。使用 synchronized_standby_slots 时,主库在与 synchronized_standby_slots 中指定的物理复制槽相关联 - 的备库确认已接收到截至主库最新刷写位置的 WAL 之前,不会完全关闭。 + 的备库确认已接收到截至主库最新刷盘位置的 WAL 之前,不会完全关闭。 @@ -575,8 +575,7 @@ DETAIL: Synchronization could lead to data loss, because the remote slot needs 版本 2 在服务器版本 14 及以上受支持;当 - streaming 设置为 on 以流式传 - 输大型进行中事务时,必须使用该版本。 + streaming 设置为 on 以流式传输大型进行中事务时,必须使用该版本。 版本 3 在服务器版本 15 及以上受支持;当启用 @@ -594,9 +593,7 @@ DETAIL: Synchronization could lead to data loss, because the remote slot needs publication_names (string) - 一个以逗号分隔的 发布名称列表,用于订阅。各个 - 发布名称按标准对象名处理,并可在需要时按同样方式加引号。 - 至少需要一个 发布名称。 + 要订阅的发布名称列表,以逗号分隔。各个发布名称按标准对象名处理,可按需加引号。至少需要一个发布名称。 @@ -626,13 +623,11 @@ DETAIL: Synchronization could lead to data loss, because the remote slot needs streaming (enum) - 启用对进行中事务的流式传输。有效值为 off(默 - 认)、onparallel。 + 启用对进行中事务的流式传输。有效值为 off(默认)、onparallel 当设置为 off 时, - pgoutput 会先完整解码一个事务,再将其整体发 - 送。该模式适用于任何协议版本。 + pgoutput 会先完整解码一个事务,再将其整体发送。该模式适用于任何协议版本。 当设置为 on 时, @@ -641,8 +636,7 @@ DETAIL: Synchronization could lead to data loss, because the remote slot needs 当设置为 parallel 时, - pgoutput 会流式传输大型进行中事务,并在某些消 - 息中额外发送信息,以支持并行处理。这要求协议版本为 4 或更高。 + pgoutput 会流式传输大型进行中事务,并在某些消息中额外发送信息,以支持并行处理。这要求协议版本为 4 或更高。 diff --git a/zh/20/maintenance.sgml b/zh/20/maintenance.sgml index f161f400..ee781fa9 100644 --- a/zh/20/maintenance.sgml +++ b/zh/20/maintenance.sgml @@ -382,11 +382,11 @@ 如果一个表正在积累全部可见但尚未全部冻结的页面,普通清理可能会选择扫描这些本可跳过的页面, 以尝试冻结它们。这样可以减少下一次激进扫描必须扫描的页面数。这类页面称为 - 积极扫描页。通过增大 ,可以调整积极扫描, - 使其尝试冻结更多全部可见页面。即使积极扫描已将全部可见但未全部冻结页面的数量降到最低, - 大多数表仍然需要周期性地进行激进扫描。不过,任何成功被积极冻结的页面在激进扫描时都可以跳过, - 因此积极冻结可以尽量减小激进扫描的开销。 + 急切扫描页。通过增大 ,可以调整急切扫描, + 使其尝试冻结更多全部可见页面。即使急切扫描已将全部可见但未全部冻结页面的数量降到最低, + 大多数表仍然需要周期性地进行激进扫描。不过,任何成功被急切冻结的页面在激进扫描时都可以跳过, + 因此急切冻结可以尽量减小激进扫描的开销。 @@ -402,7 +402,7 @@ 一个表在不被清理的情况下所能维持的最长时间,是最后一次激进扫描时的 vacuum_freeze_min_age 值从 20 亿事务中扣除后的结果。 如果超过这个时间仍不清理,就可能导致数据丢失。为了确保不会发生这种情况, - 任何可能包含未冻结行且其 XID 早于配置参数 所指定年龄的表,都会触发自动清理。 (即使自动清理已被禁用,也会如此。) @@ -491,11 +491,10 @@ SELECT datname, age(datfrozenxid) FROM pg_database; 虽然 VACUUM 主要扫描自上次清理以来被修改过的页面, - 但它也可能为了冻结它们而积极扫描某些全部可见但未全部冻结的页面; + 但它也可能为了冻结它们而急切扫描某些全部可见但未全部冻结的页面; 不过,只有当表中每一个可能包含未冻结 XID 的页面都被扫描时, relfrozenxid 才会被推进。当 - relfrozenxid 比 - vacuum_freeze_table_age 旧、使用了 VACUUM 的 + relfrozenxid的年龄超过vacuum_freeze_table_age个事务、使用了 VACUUMFREEZE 选项,或者所有尚未全部冻结的页面碰巧都需要清理以移除死行版本时, 就会发生这种情况。当 VACUUM 扫描了表中每个尚未全部冻结的页面时, 它应把 age(relfrozenxid) 设为略高于所用 @@ -595,22 +594,22 @@ HINT: Execute a database-wide VACUUM in that database. 多事务(multitransaction,MultiXact) IDMXID)用于支持多个事务对行加锁。由于元组头中用于存储锁信息的空间有限, 当有多个事务同时锁定一行时,这些信息会被编码为一个多事务 ID, - 简称 multixact ID。某个特定 multixact ID 包含哪些事务 ID 的信息, + 简称 multixact ID。某个特定 多事务 ID 包含哪些事务 ID 的信息, 会单独存放在 pg_multixact 子目录中,而元组头的 - xmax 字段中只出现 multixact ID。和事务 ID 一样, - multixact ID 也是以 32 位计数器及其对应存储实现的,因此同样需要仔细处理老化管理、 - 存储清理和回卷问题。还有一个单独的存储区域保存每个 multixact 的成员列表, + xmax 字段中只出现 多事务 ID。和事务 ID 一样, + 多事务 ID 也是以 32 位计数器及其对应存储实现的,因此同样需要仔细处理老化管理、 + 存储清理和回卷问题。还有一个单独的存储区域保存每个 多事务 的成员列表, 它也使用 32 位计数器,因此同样必须被管理。 中介绍的系统函数 pg_get_multixact_members() - 可用于检查与某个 multixact ID 关联的事务 ID。 + 可用于检查与某个 多事务 ID 关联的事务 ID。 每当 VACUUM 扫描表的任何部分时,它都会把遇到的、早于 - 的任何 multixact ID 替换为另一个值,该值可能是零值、单个事务 ID,或者更新的 multixact ID。 + 的任何 多事务 ID 替换为另一个值,该值可能是零值、单个事务 ID,或者更新的 多事务 ID。 对于每个表,pg_class.relminmxid - 保存该表任何元组中仍可能出现的最老 multixact ID。如果这个值早于 + 保存该表任何元组中仍可能出现的最老 多事务 ID。如果这个值早于 ,就会强制执行一次激进扫描。 正如上一节所述,激进扫描意味着只有那些已知为全部冻结的页面才会被跳过。 可以对 pg_class.relminmxid @@ -620,7 +619,7 @@ HINT: Execute a database-wide VACUUM in that database. 无论出于何种原因而发生,激进的 VACUUM保证 能够推进表的 relminmxid。最终,随着所有数据库中的所有表都被扫描, - 并推进其最老的 multixact 值,较老 multixact 的磁盘存储就可以被移除。 + 并推进其最老的 多事务 值,较老 多事务 的磁盘存储就可以被移除。 @@ -628,11 +627,11 @@ HINT: Execute a database-wide VACUUM in that database. - 作为一项安全措施,对于 多事务 年龄大于 的任何表,都会进行一次激进清理扫描。 - 此外,如果创建的 多事务 成员条目数量超过大约 20 亿个 + 此外,如果创建的多事务成员条目数量超过大约 20 亿个 (在 pg_multixact/members 目录中占用大约 10GB), - 就会更频繁地对所有表进行激进清理扫描,从 多事务 年龄最老的表开始。 + 就会更频繁地对所有表进行激进清理扫描,从多事务年龄最老的表开始。 即使自动清理名义上被禁用,这两类激进扫描也都会发生。 当条目数量达到大约 40 亿个 (在 pg_multixact/members 目录中占用大约 20GB)时, @@ -651,7 +650,7 @@ HINT: Execute a database-wide VACUUM in that database. 311740299 | 2785241176 | 13926205880 | 2 | 13 GB (1 row) - 该输出显示一个 多事务 活动明显的系统:大约 3.12 亿个 多事务 ID, + 该输出显示一个多事务活动明显的系统:大约 3.12 亿个 多事务 ID, 以及大约 28 亿个成员条目,占用 13 GB 存储空间。 如果 num_mxids 激增,可能表示多个会话正在运行带有外键检查的 UPDATE 语句、并发的 SELECT FOR SHARE @@ -673,11 +672,11 @@ HINT: Execute a database-wide VACUUM in that database. - 如果没有可能出现在 multixact 中,那么正在运行的事务和预备事务都可以忽略。 + 如果没有可能出现在 多事务 中,那么正在运行的事务和预备事务都可以忽略。 - 与事务 ID 回卷不同,复制槽不会直接阻止 multixact 清理。 - 因此,删除陈旧的复制槽通常与解决 multixact ID 回卷问题无关。 + 与事务 ID 回卷不同,复制槽不会直接阻止 多事务 清理。 + 因此,删除陈旧的复制槽通常与解决 多事务 ID 回卷问题无关。 MXID 信息不会直接出现在诸如 pg_stat_activity 这样的系统视图中; @@ -734,7 +733,7 @@ HINT: Execute a database-wide VACUUM in that database. - 对于 relfrozenxid 值早于 + 对于 relfrozenxid值的年龄超过 个事务的表,总是会执行清理 (这也适用于那些通过存储参数修改了冻结最大年龄的表,见下文)。 否则,如果自上次 VACUUM 以来已经失效的元组数超过了 @@ -773,7 +772,7 @@ vacuum insert threshold = vacuum base insert threshold + vacuum insert scale fac 因为这会让元组在更早的清理中被冻结。过时元组数和插入元组数取自累积统计系统; 这是一个由每次 UPDATEDELETEINSERT 操作更新的最终一致计数。如果该表的 - relfrozenxid 值早于 + relfrozenxid值的年龄超过 vacuum_freeze_table_age 个事务,就会执行一次激进扫描, 以冻结旧元组并推进 relfrozenxid @@ -838,15 +837,15 @@ analyze threshold = analyze base threshold + analyze scale factor * number of tu 自动清理分两步决定处理对象:首先选择一个数据库,然后选择该数据库中的表。 - 自动清理启动器进程会优先处理有事务 ID 或 多事务 ID 回卷风险的数据库, + 自动清理启动器进程会优先处理有事务 ID 或多事务 ID 回卷风险的数据库, 否则就选择最久未被处理的数据库。作为例外,它会跳过自上次统计信息重置以来没有连接 或没有活动的数据库,除非它们有回卷风险。 - 在数据库内部,自动清理工作进程会构建一个需要 清理或分析 的表列表, + 在数据库内部,自动清理工作进程会构建一个需要清理或分析的表列表, 并使用一个评分系统对其排序。它通过取若干分量评分中的最大值来为每个表打分, - 这些分量反映了对 清理或分析 重要的各种标准。各分量如下: + 这些分量反映了对清理或分析重要的各种标准。各分量如下: @@ -867,10 +866,10 @@ analyze threshold = analyze base threshold + analyze scale factor * number of tu 多事务 ID 分量衡量表的 pg_class.relminmxid - 字段按 多事务 数计算的年龄,并与 + 字段按多事务数计算的年龄,并与 比较。此外, 一旦年龄超过 , - 或者已创建的 多事务 成员条目数量超过大约 20 亿条 + 或者已创建的多事务成员条目数量超过大约 20 亿条 (见 ), 该分量会大幅增加。该分量的最终值可通过 调整。注意, @@ -932,7 +931,7 @@ analyze threshold = analyze base threshold + analyze scale factor * number of tu VACUUM 可以使用后台工作进程并行执行索引清理(index vacuuming)和索引收尾清理(index cleanup)阶段 (各个清理阶段的细节请参见 )。 - 并行度由该关系上支持并行清理 的索引数量决定。对于手工 VACUUM, + 并行度由该关系上支持并行清理的索引数量决定。对于手工 VACUUM, 如果指定了 PARALLEL 选项,则受该选项限制;此外还会进一步受 限制。对于自动清理, 这受表的 限制(如果指定), @@ -1093,7 +1092,7 @@ pg_ctl start | rotatelogs /var/log/pgsql_log 86400 不过,在很多系统上,syslog 并不十分可靠, 尤其是在日志消息很大时;它可能恰恰在你最需要消息的时候截断或丢弃它们。 此外,在 Linux 上, - syslog 会把每条消息都刷新到磁盘,导致性能较差。 + syslog 会把每条消息都刷盘,导致性能较差。 (你可以在 syslog 配置文件的文件名开头使用一个 - 来禁用同步。) diff --git a/zh/20/monitoring.sgml b/zh/20/monitoring.sgml index ea04da0f..84fbe1ac 100644 --- a/zh/20/monitoring.sgml +++ b/zh/20/monitoring.sgml @@ -87,15 +87,15 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - 累计统计系统 + 累积统计系统 - statistics + 统计信息 PostgreSQL累积统计系统支持收集和报告有关服务器活动的信息。 - 目前,对表和索引的访问以磁盘块和单个行的术语进行计数。每个表中的总行数, + 目前,对表和索引的访问分别以磁盘块和单行计数。每个表中的总行数, 以及每个表的清理和分析操作的信息也被计数。如果启用,对用户定义函数的调用 和每个函数中花费的总时间也会被计数。 @@ -107,7 +107,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - 统计收集配置 + 统计信息收集配置 由于收集统计信息会增加查询执行的开销,因此可以配置系统是否收集信息。这由通常在postgresql.conf中设置的配置参数控制(有关设置配置参数的详细信息,请参阅)。 @@ -160,11 +160,11 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - 另一个重要的观点是,当服务器进程被要求显示任何累积的统计信息时,在默认配置中,访问的值会被缓存直到当前事务结束。因此,只要您继续当前事务,统计信息将显示静态信息。类似地,当在事务中首次请求任何当前会话的查询信息时,会收集关于所有会话当前查询的信息,并且相同的信息将在整个事务中显示。这是一个特性,而不是一个错误,因为它允许您在统计信息上执行多个查询并将结果相关联,而不必担心数字在您眼前发生变化。 + 另一个重要的观点是,当服务器进程被要求显示任何累积的统计信息时,在默认配置中,访问的值会被缓存直到当前事务结束。因此,只要你继续当前事务,统计信息将显示静态信息。类似地,当在事务中首次请求这类当前查询信息时,会收集关于所有会话当前查询的信息,并且相同的信息将在整个事务中显示。这是一个特性,而不是一个错误,因为它允许你在统计信息上执行多个查询并将结果相关联,而不必担心数字在你眼前发生变化。 - 在交互式分析统计信息或使用昂贵的查询时,访问各个统计信息之间的时间差可能导致缓存统计信息中出现显著的偏差。为了最小化偏差,可以将stats_fetch_consistency设置为snapshot,但这会增加用于缓存不需要的统计数据的内存使用量。相反,如果已知统计信息只被访问一次,那么缓存访问的统计信息是不必要的,可以通过将stats_fetch_consistency设置为none来避免。 + 在交互式分析统计信息或使用开销较大的查询时,访问各个统计信息之间的时间差可能导致缓存统计信息中出现显著的偏差。为了最小化偏差,可以将stats_fetch_consistency设置为snapshot,但这会增加用于缓存不需要的统计数据的内存使用量。相反,如果已知统计信息只被访问一次,那么缓存访问的统计信息是不必要的,可以通过将stats_fetch_consistency设置为none来避免。 - 您可以调用pg_stat_clear_snapshot()来丢弃当前事务的统计快照或缓存的值(如果有)。下一次使用统计信息时(在快照模式下),将会创建一个新的快照,或者(在缓存模式下)将访问的统计信息缓存起来。 + 你可以调用pg_stat_clear_snapshot()来丢弃当前事务的统计快照或缓存的值(如果有)。下一次使用统计信息时(在快照模式下),将会创建一个新的快照,或者(在缓存模式下)将访问的统计信息缓存起来。 @@ -176,11 +176,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 相反,它们在事务期间持续更新。 - - 动态统计视图中显示的一些信息在中受到安全限制。 - 普通用户只能查看关于他们自己会话的所有信息(属于他们是成员的角色的会话)。在关于其他会话的行中,许多列将为空。 - 但是,请注意,所有用户都可以看到会话的存在以及其一般属性,如会话用户和数据库。超级用户和具有内置角色pg_read_all_stats权限的角色(另请参阅)可以查看所有会话的所有信息。 - + 所列动态统计视图中的一些信息受到安全限制。普通用户只能查看其自身会话的全部信息(包括属于其所加入角色的会话)。对于其他会话的行,许多列将为空值。不过,会话的存在及其一般属性(例如会话用户和数据库)对所有用户都可见。超级用户和具有内置角色pg_read_all_stats权限的角色可以查看所有会话的全部信息。
@@ -215,7 +211,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser pg_stat_wal_receiverpg_stat_wal_receiver - 只有一行,显示有关 WAL 接收进程从其连接服务器接收到的统计信息。有关详细信息,请参阅pg_stat_wal_receiver。 + 只有一行,显示 WAL 接收进程从其所连接服务器接收数据的统计信息。有关详细信息,请参阅pg_stat_wal_receiver @@ -327,42 +323,70 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - + pg_stat_bgwriterpg_stat_bgwriter 只有一行,显示有关后台写入器活动的信息。有关详细信息,请参阅pg_stat_bgwriter - + pg_stat_checkpointerpg_stat_checkpointer 只有一行,显示有关检查点进程活动的信息。有关详细信息,请参阅pg_stat_checkpointer - + + pg_stat_databasepg_stat_database + 每个数据库一行,显示数据库范围的统计信息。有关详细信息,请参阅pg_stat_database。 + + + + + pg_stat_database_conflictspg_stat_database_conflicts + 每个数据库一行,显示数据库范围内因备库上的恢复冲突而导致查询被取消的统计信息。有关详细信息,请参阅pg_stat_database_conflicts + + + pg_stat_iopg_stat_io 对于每种后端类型、上下文和目标对象的组合各有一行,包含集簇范围的 I/O 统计信息。有关详细信息,请参阅pg_stat_io - - pg_stat_walpg_stat_wal - 只有一行,显示有关 WAL 活动的统计信息。有关详细信息,请参阅pg_stat_wal。 + + pg_stat_kind_infopg_stat_kind_info + + 每个已注册的统计信息类型一行,显示各类型的信息。详见pg_stat_kind_info - - pg_stat_databasepg_stat_database - 每个数据库一行,显示数据库范围的统计信息。有关详细信息,请参阅pg_stat_database。 - + + pg_stat_lockpg_stat_lock + 每种锁类型一行,显示集簇范围的锁统计信息。有关详细信息,请参阅pg_stat_lock。 + - - pg_stat_database_conflictspg_stat_database_conflicts - 每个数据库一行,显示数据库范围内因备库上的恢复冲突而导致查询被取消的统计信息。有关详细信息,请参阅pg_stat_database_conflicts + + pg_stat_replication_slotspg_stat_replication_slots + 每个复制槽一行,显示有关复制槽使用情况的统计信息。有关详细信息,请参阅pg_stat_replication_slots - + + pg_stat_slrupg_stat_slru + 每个 SLRU 一行,显示操作统计信息。有关详细信息,请参阅pg_stat_slru + + + + pg_stat_subscription_statspg_stat_subscription_stats + 每个订阅一行,显示有关错误和冲突的统计信息。有关详细信息,请参阅pg_stat_subscription_stats + + + + pg_stat_walpg_stat_wal + 只有一行,显示有关 WAL 活动的统计信息。有关详细信息,请参阅pg_stat_wal。 + + + + pg_stat_all_tablespg_stat_all_tables 当前数据库中每个表一行,显示有关访问指定表的统计信息。详见 @@ -370,134 +394,106 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - + pg_stat_sys_tablespg_stat_sys_tables pg_stat_all_tables一样,但只显示系统表。 - + pg_stat_user_tablespg_stat_user_tables pg_stat_all_tables一样,但只显示用户表。 - + pg_stat_xact_all_tablespg_stat_xact_all_tables - pg_stat_all_tables相似,但计数动作只在当前事务内发生(还没有被包括在pg_stat_all_tables和相关视图中)。用于生存和死亡行数量的列以及清理和分析动作在此视图中不出现。 + pg_stat_all_tables 相似,但只统计当前事务中截至目前执行的操作(这些操作尚计入 pg_stat_all_tables 及相关视图)。此视图不包含存活行和死行数量以及清理、分析操作的列。 - + pg_stat_xact_sys_tablespg_stat_xact_sys_tables pg_stat_xact_all_tables一样,但只显示系统表。 - + pg_stat_xact_user_tablespg_stat_xact_user_tables pg_stat_xact_all_tables一样,但只显示用户表。 - + pg_stat_autovacuum_scorespg_stat_autovacuum_scores 当前数据库中的每个表一行,显示该表当前的自动清理评分。有关详细信息,请参阅pg_stat_autovacuum_scores - + pg_stat_all_indexespg_stat_all_indexes 当前数据库中的每个索引一行,显示有关访问该特定索引的统计信息。有关详细信息,请参阅pg_stat_all_indexes - + pg_stat_sys_indexespg_stat_sys_indexes pg_stat_all_indexes一样,但只显示系统表上的索引。 - + pg_stat_user_indexespg_stat_user_indexes pg_stat_all_indexes一样,但只显示用户表上的索引。 - + + pg_stat_user_functionspg_stat_user_functions + 每个被跟踪的函数一行,显示有关该函数执行的统计信息。有关详细信息,请参阅pg_stat_user_functions + + + + pg_stat_xact_user_functionspg_stat_xact_user_functions + pg_stat_user_functions相似,但是只统计在当前事务期间的调用(还没有被包括在pg_stat_user_functions中)。 + + + pg_statio_all_tablespg_statio_all_tables 当前数据库中的每个表一行,显示有关访问该特定表的 I/O 统计信息。有关详细信息,请参阅pg_statio_all_tables - + pg_statio_sys_tablespg_statio_sys_tables pg_statio_all_tables一样,但只显示系统表。 - + pg_statio_user_tablespg_statio_user_tables pg_statio_all_tables一样,但只显示用户表。 - + pg_statio_all_indexespg_statio_all_indexes 当前数据库中的每个索引一行,显示有关访问该特定索引的 I/O 统计信息。有关详细信息,请参阅pg_statio_all_indexes - + pg_statio_sys_indexespg_statio_sys_indexes pg_statio_all_indexes一样,但只显示系统表上的索引。 - + pg_statio_user_indexespg_statio_user_indexes pg_statio_all_indexes一样,但只显示用户表上的索引。 - + pg_statio_all_sequencespg_statio_all_sequences 当前数据库中的每个序列一行,显示有关访问该特定序列的 I/O 统计信息。有关详细信息,请参阅pg_statio_all_sequences - + pg_statio_sys_sequencespg_statio_sys_sequences pg_statio_all_sequences一样,但只显示系统序列(目前没有定义系统序列,因此这个视图总是为空)。 - + pg_statio_user_sequencespg_statio_user_sequences pg_statio_all_sequences一样,但只显示用户序列。 - - pg_stat_user_functionspg_stat_user_functions - 每个被跟踪的函数一行,显示有关该函数执行的统计信息。有关详细信息,请参阅pg_stat_user_functions - - - - pg_stat_xact_user_functionspg_stat_xact_user_functions - pg_stat_user_functions相似,但是只统计在当前事务期间的调用(还没有被包括在pg_stat_user_functions中)。 - - - - pg_stat_slrupg_stat_slru - 每个 SLRU 一行,显示操作统计信息。有关详细信息,请参阅pg_stat_slru - - - - pg_stat_kind_infopg_stat_kind_info - - 每个已注册的统计信息类型一行,显示各类型的信息。详见pg_stat_kind_info。 - - - - - pg_stat_lockpg_stat_lock - 每种锁类型一行,显示集簇范围的锁统计信息。有关详细信息,请参阅pg_stat_lock。 - - - - - pg_stat_replication_slotspg_stat_replication_slots - 每个复制槽一行,显示有关复制槽使用情况的统计信息。有关详细信息,请参阅pg_stat_replication_slots - - - - pg_stat_subscription_statspg_stat_subscription_stats - 每个订阅一行,显示有关错误和冲突的统计信息。有关详细信息,请参阅pg_stat_subscription_stats - -
@@ -573,7 +569,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser leader_pid integer
- 如果该进程是并行查询工作进程,则为并行组领导者的进程 ID;如果该进程是并行应用工作进程,则为领导应用工作进程的进程 ID。NULL 表示该进程是并行组领导者或领导应用工作进程,或者不参与任何并行操作。 + 如果该进程是并行查询工作进程,则为并行组领导者的进程 ID;如果该进程是并行应用工作进程,则为领导者应用工作进程的进程 ID。NULL 表示该进程是并行组领导者或领导者应用工作进程,或者不参与任何并行操作。 @@ -609,7 +605,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser client_addr inet
- 连接到这个后端的客户端的 IP 地址。如果这个字段为空,它表示客户端通过服务器机器上的一个 Unix 套接字连接或者这是一个内部进程,如自动清理。 + 连接到这个后端的客户端的 IP 地址。如果这个字段为空值,它表示客户端通过服务器机器上的一个 Unix 套接字连接或者这是一个内部进程,如自动清理。 @@ -628,7 +624,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser client_port integer
- 客户端用于与此后端通信的TCP端口号,如果使用Unix套接字,则为-1。如果该字段为空,它表示这是一个内部服务器进程。 + 客户端用于与此后端通信的TCP端口号,如果使用Unix套接字,则为-1。如果该字段为空值,它表示这是一个内部服务器进程。 @@ -646,8 +642,8 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser xact_start timestamp with time zone
- 这个进程的当前事务被启动的时间,如果没有活动事务则为空。 - 如果当前查询是它的第一个事务,这一列等于query_start列。 + 这个进程的当前事务被启动的时间,如果没有活动事务则为空值。 + 如果当前查询是其事务中的第一个查询,这一列等于query_start列。 @@ -674,7 +670,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser wait_event_type text - 后端正在等待的事件类型(如果有);否则为NULL。请参阅。 + 后端正在等待的事件类型(如果有);否则为空值。请参阅 @@ -683,7 +679,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser wait_event text - 如果此后端当前正在等待,则返回等待事件名称,否则为NULL。请参阅。 + 如果此后端当前正在等待,则返回等待事件名称,否则为空值。请参阅 @@ -691,44 +687,29 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser state text - - 这个后端的当前总体状态。可能的值为: - + 该后端当前的总体状态。可能的值为: - starting: 后端正处于初始启动阶段。客户端认证在此阶段执行。 + starting: 后端正处于初始启动阶段。客户端认证在此阶段执行。 - - active: 后端正在执行一个查询。 - + active:后端正在执行一个查询。 - - idle: 后端正在等待一个新的客户端命令。 - + idle:后端正在等待新的客户端命令。 - - idle in transaction: 后端在一个事务中,但是当前没有正在执行一个查询。 - + idle in transaction:后端处于事务中,但当前没有执行查询。 - - idle in transaction (aborted): 这个状态与 - idle in transaction相似,除了在该事务中的一个语句导致了一个错误。 - + idle in transaction (aborted):该状态与idle in transaction类似,但事务中的某个语句导致了错误。 - - fastpath function call: 后端正在执行一个 fast-path 函数。 - + fastpath function call:后端正在执行一个快速路径函数。 - - disabled: 如果在这个后端中被禁用,则报告这个状态。 - + disabled:如果在此后端中禁用了,就会报告此状态。 @@ -738,9 +719,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser backend_xid xid - - 这个后端的顶层事务 ID,如果存在。 - + 这个后端的顶层事务 ID(如果存在);请参阅 @@ -748,7 +727,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser backend_xmin xid - 当前后端的xmin范围。 + 当前后端的xmin视界。 @@ -760,7 +739,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser 这个后端的最近查询的标识符。 如果stateactive,这个字段显示当前正在执行的查询的标识符。 在所有其他状态,它显示执行的最后一个查询的标识符。 - 默认不计算查询标识符,因此该字段将为空,除非启用参数或配置了计算查询标识符的第三方模块。 + 默认不计算查询标识符,因此该字段将为空值,除非启用参数或配置了计算查询标识符的第三方模块。 @@ -907,7 +886,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser - wait_eventstate列彼此独立。如果某个后端处于active状态,它既可能正在等待某个事件,也可能没有等待。如果状态为activewait_event非空,就意味着某个查询正在执行,但在系统中的某处被阻塞了。为将报告开销保持在较低水平,系统不会尝试为某个后端同步活动数据的不同方面。因此,视图各列之间可能暂时存在不一致。 + wait_eventstate列彼此独立。如果某个后端处于active状态,它可能正在等待(waiting)某个事件,也可能没有等待。如果状态为activewait_event非空,就意味着某个查询正在执行,但在系统中的某处被阻塞了。为将报告开销保持在较低水平,系统不会尝试为某个后端同步活动数据的不同方面。因此,视图各列之间可能暂时存在不一致。 @@ -959,7 +938,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser IO - 服务器进程正在等待一个I/O操作完成。wait_event将识别特定的等待点;参见。 + 服务器进程正在等待一个 I/O 操作完成。wait_event将识别特定的等待点;参见 @@ -971,17 +950,14 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser Lock - 服务器进程正在等待一个重量级锁。重量级锁,也称为锁管理器锁或简单锁,主要保护表等SQL可见对象。 + 服务器进程正在等待一个重量级锁。重量级锁,也称为锁管理器锁或简称为锁,主要保护表等SQL可见对象。 然而,它们也用于确保某些内部操作的互斥,例如关系扩展。wait_event将识别等待的锁的类型;参见 LWLock - 服务器进程正在等待一个轻量级锁。大多数这样的锁保护共享内存中的特定数据结构。 - wait_event将包含标识轻量级锁用途的名称。 - (有些锁有特定的名称;其他锁是一组锁的一部分,每个锁具有类似的目的。)参见。 - + 服务器进程正在等待一个轻量级锁。大多数这样的锁保护共享内存中的某个特定数据结构。wait_event将包含标识该轻量级锁用途的名称。(有些锁具有专门的名称,另一些锁属于一组用途相似的锁。)参见 @@ -995,15 +971,10 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser &wait_event_types; - - - 扩展可以将ExtensionInjectionPointLWLock 事件添加到所示的列表中。 - - - 这里是一个查看等待事件的示例: + 以下示例展示如何查看等待事件: SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event IS NOT NULL; @@ -1027,6 +998,13 @@ description | Waiting for a newly initialized WAL file to reach durable storage + + + + 扩展可以将ExtensionInjectionPointLWLock 事件添加到所示的列表中。 + + + @@ -1101,7 +1079,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage 连接到这个 WAL 发送进程的客户端的 IP 地址。 - 如果这个域为空,它表示该客户端通过服务器机器上的一个Unix 套接字连接。 + 如果这个字段为空值,它表示该客户端通过服务器机器上的一个Unix 套接字连接。 @@ -1139,7 +1117,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage 报告的该备库的xmin视界。 - 如果使用了复制槽(此时备库的 xmin 显示在 pg_replication_slots 中),或禁用了 hot_standby_feedback,则此字段为空。 + 如果使用了复制槽(此时备库的 xmin 显示在 pg_replication_slots 中),或禁用了 hot_standby_feedback,则此字段为空值。 @@ -1153,27 +1131,27 @@ description | Waiting for a newly initialized WAL file to reach durable storage - startup: 此 WAL 发送进程正在启动。 + startup: 此 WAL 发送进程正在启动。 - catchup: 与此 WAL 发送进程连接的备库正在赶上主库。 + catchup: 与此 WAL 发送进程连接的备库正在赶上主库。 - streaming: 在其连接的备库赶上主库之后,此 WAL 发送进程正在流式传输更改。 + streaming: 在其连接的备库赶上主库之后,此 WAL 发送进程正在流式传输更改。 - backup: 此 WAL 发送进程正在发送一个备份。 + backup: 此 WAL 发送进程正在发送一个备份。 - stopping: 此 WAL 发送进程正在停止。 + stopping: 此 WAL 发送进程正在停止。 @@ -1220,30 +1198,21 @@ description | Waiting for a newly initialized WAL file to reach durable storage write_lag interval - - 从本地刷写最近的 WAL,到收到该备库已写入该 WAL(但尚未刷盘或应用)的通知之间经过的时间。 - 如果该服务器被配置为同步备库,可用此值衡量在提交时 synchronous_commit 级别 remote_write 所导致的延迟。 - + 从在本地将最近的 WAL 刷盘,到收到该备库已写入该 WAL(但尚未刷盘或应用)的通知之间经过的时间。如果该服务器被配置为同步备库,可用此值衡量在提交时synchronous_commit级别remote_write所导致的延迟。 flush_lag interval - - 从本地刷写最近的 WAL,到收到该备库已写入并刷写该 WAL(但尚未应用)的通知之间经过的时间。 - 如果该服务器被配置为同步备库,可用此值衡量在提交时 synchronous_commit 级别 on 所导致的延迟。 - + 从在本地将最近的 WAL 刷盘,到收到该备库已写入该 WAL 并将其刷盘(但尚未应用)的通知之间经过的时间。如果该服务器被配置为同步备库,可用此值衡量在提交时synchronous_commit级别on所导致的延迟。 replay_lag interval - - 从本地刷写最近的 WAL,到收到该备库已写入、刷写并应用该 WAL 的通知之间经过的时间。 - 如果该服务器被配置为同步备库,可用此值衡量在提交时 synchronous_commit 级别 remote_apply 所导致的延迟。 - + 从在本地将最近的 WAL 刷盘,到收到该备库已写入该 WAL、将其刷盘并应用的通知之间经过的时间。如果该服务器被配置为同步备库,可用此值衡量在提交时synchronous_commit级别remote_apply所导致的延迟。 @@ -1265,22 +1234,22 @@ description | Waiting for a newly initialized WAL file to reach durable storage - async: 该备库是异步的。 + async: 该备库是异步的。 - potential: 该备库当前是异步的,但在当前同步备库失效时可能变为同步的。 + potential: 该备库当前是异步的,但在当前某个同步备库失效时可能变为同步的。 - sync: 该备库是同步的。 + sync: 该备库是同步的。 - quorum: 该备库被作为法定人数同步复制候选备库。 + quorum: 该备库被作为法定人数同步复制候选备库。 @@ -1289,7 +1258,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - reply_time 带时区的时间戳 + reply_time timestamp with time zone 从备库收到的最后一条回复消息的发送时间 @@ -1300,17 +1269,17 @@ description | Waiting for a newly initialized WAL file to reach durable storage - pg_stat_replication视图中报告的滞后时间,是最近的 WAL 被写入、刷写和重放,以及发送端获知这些操作完成所花费时间的度量。如果远程服务器被配置为同步备库,这些时间表示各个同步提交级别带来或可能带来的提交延迟。对于异步备库,replay_lag列是最近事务对查询变得可见所需延迟时间的近似值。如果备库已经完全追上发送服务器且没有新的 WAL 活动,系统会在短时间内继续显示最近测得的滞后时间,随后显示为 NULL。 + pg_stat_replication视图中报告的滞后时间,是最近的 WAL 被写入、刷盘和重放,以及发送端获知这些操作完成所花费时间的度量。如果远程服务器被配置为同步备库,这些时间表示各个同步提交级别带来或可能带来的提交延迟。对于异步备库,replay_lag列是最近事务对查询变得可见所需延迟时间的近似值。如果备库已经完全追上发送服务器且没有新的 WAL 活动,系统会在短时间内继续显示最近测得的滞后时间,随后显示为 空值。 - 对于物理复制,滞后时间会自动测量。逻辑解码插件可以选择发出跟踪消息;如果没有这样做,跟踪机制会将滞后显示为 NULL。 + 对于物理复制,滞后时间会自动测量。逻辑解码插件可以选择发出跟踪消息;如果没有这样做,跟踪机制会将滞后显示为 空值。 - 报告出的滞后时间并不是根据当前重放速率预测该备库还需多久才能追上发送服务器。在持续生成新 WAL 时,那样的系统可能会显示相近的时间;但当发送端空闲时,就会显示不同的值。特别是当备库已经完全追上时,pg_stat_replication显示的是写入、刷写和重放最近报告的 WAL 位置所花费的时间,而不是某些用户可能预期的零。这样做符合为最近写事务测量同步提交和事务可见性延迟的目的。为减少用户因预期另一种滞后模型而产生的混淆,在一个已完全重放且处于空闲状态的系统上,lag 列会在较短时间后恢复为 NULL。监控系统应自行决定将这种情况表示为缺失数据、零,还是继续显示最近一次已知值。 + 报告出的滞后时间并不是根据当前重放速率预测该备库还需多久才能追上发送服务器。在持续生成新 WAL 时,那样的系统可能会显示相近的时间;但当发送端空闲时,就会显示不同的值。特别是当备库已经完全追上时,pg_stat_replication显示的是写入、刷盘和重放最近报告的 WAL 位置所花费的时间,而不是某些用户可能预期的零。这样做符合为最近写事务测量同步提交和事务可见性延迟的目的。为减少用户因预期另一种滞后模型而产生的混淆,在一个已完全重放且处于空闲状态的系统上,滞后列会在较短时间后恢复为 空值。监控系统应自行决定将这种情况表示为缺失数据、零,还是继续显示最近一次已知值。 @@ -1349,19 +1318,14 @@ description | Waiting for a newly initialized WAL file to reach durable storage slot_name text - - 唯一的,复制槽的集簇范围标识符 - + 复制槽在整个集簇范围内的唯一标识符 spill_txns bigint - - 当逻辑解码在解码来自WAL的更改时所使用的内存超过logical_decoding_work_mem,溢出到磁盘的事务数。 - 顶级事务和子事务的计数器都是递增的。 - + 当逻辑解码从 WAL 解码更改时所使用的内存超过logical_decoding_work_mem后,溢出到磁盘的事务数。顶层事务和子事务都会使此计数器递增。 @@ -1369,7 +1333,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage spill_count bigint - 在为该槽位解码来自WAL的更改时,事务溢出到磁盘的次数。 + 在为该槽解码来自WAL的更改时,事务溢出到磁盘的次数。 此计数器在每次事务被溢出时递增,并且同一事务可能被溢出多次。 @@ -1378,20 +1342,14 @@ description | Waiting for a newly initialized WAL file to reach durable storage spill_bytes bigint - - 在对来自WAL的更改执行解码时,已解码的事务数据溢出到磁盘的数量。 - 这个和其他溢出计数器可用于测量逻辑解码期间发生的I/O,并且允许调优logical_decoding_work_mem。 - + 为此槽从 WAL 解码更改时,溢出到磁盘的已解码事务数据量。此计数器及其他溢出计数器可用于衡量逻辑解码期间发生的 I/O,并用于调优logical_decoding_work_mem stream_txns bigint - - 在逻辑解码在解码来自该槽位的WAL更改的时候,所使用的内存超过logical_decoding_work_mem之后,流式传输到解码输出插件的正在进行的事务数。 - 流式传输仅对顶级事务有效(子事务不能独立进行流式传输),因此子事务的计数器不会增加。 - + 当逻辑解码为此槽从 WAL 解码更改时所使用的内存超过logical_decoding_work_mem后,流式传输到解码输出插件的进行中事务数。流式传输仅适用于顶层事务(子事务不能单独进行流式传输),因此子事务不会使此计数器递增。 @@ -1399,7 +1357,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage stream_countbigint - 在为该槽位解码来自WAL的更改时,将正在进行的事务流式传输到解码输出插件的次数。 + 在为该槽解码来自WAL的更改时,将进行中事务流式传输到解码输出插件的次数。 此计数器在每次事务流式传输时递增,并且同一事务可能被流式传输多次。 @@ -1409,8 +1367,8 @@ description | Waiting for a newly initialized WAL file to reach durable storage stream_bytesbigint - 在为该槽位解码来自WAL的更改时,为将正在进行的事务流式传输到解码输出插件而解码的事务数据的数量。 - 这个和针对此槽位的其他流式传输计数器可用于调优logical_decoding_work_mem。 + 在为该槽解码来自WAL的更改时,为将进行中事务流式传输到解码输出插件而解码的事务数据量。 + 这个和针对此槽的其他流式传输计数器可用于调优logical_decoding_work_mem @@ -1431,7 +1389,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage 针对此槽的,发送到解码输出插件的已解码事务数。 - 这只计算顶级事务,对子事务不会增加。 + 这只计算顶层事务,对子事务不会增加。 注意,这包括流式传输和/或溢出的事务。 @@ -1441,7 +1399,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage total_bytesbigint - 在对此槽位的WAL进行解码时,为将事务发送到解码输出插件而解码的事务数据量。 + 在为此槽从 WAL 解码更改时,为将事务发送到解码输出插件而解码的事务数据量。 注意这包括流式传输和/或溢出的数据。 @@ -1471,9 +1429,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage stats_reset timestamp with time zone - - 这些统计最后重置的时间 - + 这些统计信息上次被重置的时间 @@ -1488,9 +1444,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage pg_stat_wal_receiver - - pg_stat_wal_receiver事务只包含一行,它显示了从 WAL 接收进程所连接的服务器得到的有关该接收进程的统计信息。 - + pg_stat_wal_receiver视图只包含一行,显示 WAL 接收进程从其所连接服务器接收数据的统计信息。 @@ -1515,7 +1469,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage pidinteger - WAL 接收进程的进程ID + WAL 接收进程的进程 ID @@ -1565,7 +1519,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage receive_start_lsnpg_lsn - WAL 接收进程启动时使用的第一个写前日志位置 + WAL 接收进程启动时使用的第一个预写式日志位置 @@ -1574,7 +1528,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage receive_start_tliinteger - WAL 接收进程启动时使用的第一个时间线数字 + WAL 接收进程启动时使用的第一个时间线编号 @@ -1583,7 +1537,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage written_lsnpg_lsn - 已经接收并写入磁盘的最后一个预写式日志位置,但没有刷入。这不能用于数据完整性检查。 + 已经接收并写入磁盘的最后一个预写式日志位置,但尚未刷盘。此字段不应用于数据完整性检查。 @@ -1592,7 +1546,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage flushed_lsnpg_lsn - 已经接收并刷入到磁盘的最后一个预写式日志位置,该字段的初始值是启动WAL 接收进程时使用的第一个日志位置 + 已经接收并刷入到磁盘的最后一个预写式日志位置,该字段的初始值是启动 WAL 接收进程时使用的第一个日志位置 @@ -1601,7 +1555,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage received_tliinteger - 接收并刷入到磁盘的最后一个预写式日志位置的时间线数字,该字段的初始值为启动WAL 接收进程时使用的第一个日志位置的时间线数字 + 接收并刷入到磁盘的最后一个预写式日志位置的时间线编号,该字段的初始值为启动 WAL 接收进程时使用的第一个日志位置的时间线编号 @@ -1646,7 +1600,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage slot_nametext - 这个WAL 接收进程使用的复制槽的名称 + 这个 WAL 接收进程使用的复制槽的名称 @@ -1655,8 +1609,8 @@ description | Waiting for a newly initialized WAL file to reach durable storage sender_hosttext - 这个WAL 接收进程连接到的PostgreSQL实例的主机。 - 这可以是主机名、IP地址,或者目录路径,如果连接是通过Unix套接字进行的。(路径的情况可以区分,因为它总是以/开头的绝对路径。) + 这个 WAL 接收进程连接到的PostgreSQL实例的主机。 + 这可以是主机名、IP地址,或者目录路径,如果连接是通过Unix套接字进行的。(路径的情况可以区分,因为它总是以/开头的绝对路径。) @@ -1665,7 +1619,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage sender_portinteger - 这个WAL 接收进程连接的PostgreSQL实例的端口号。 + 这个 WAL 接收进程连接的PostgreSQL实例的端口号。 @@ -1674,7 +1628,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage conninfotext - 这个WAL 接收进程使用的连接字符串,对安全敏感的字段进行了模糊处理。 + 这个 WAL 接收进程使用的连接字符串,对安全敏感的字段进行了模糊处理。 @@ -1760,8 +1714,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage replay_end_tliinteger - 当前正在重放的 WAL 记录所在的时间线。当没有正在主动重放的记录时, - 等于last_replayed_tli。 + 当前正在重放的 WAL 记录所在的时间线。如果当前没有正在重放的记录,则等于last_replayed_tli @@ -1780,7 +1733,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage 启动进程观察到重放已经追上从流复制接收的最新 WAL 块的时间。 - 用于恢复冲突计时和重放/应用延迟诊断。如果尚未接收到流式 WAL,或无法获得该时间,则为 NULL。 + 用于恢复冲突计时和重放/应用延迟诊断。如果尚未接收到流式 WAL,或无法获得该时间,则为空值。 @@ -1794,17 +1747,17 @@ description | Waiting for a newly initialized WAL file to reach durable storage - not paused: 恢复正在正常进行。 + not paused: 恢复正在正常进行。 - pause requested: 已经请求暂停,但恢复尚未真正暂停。 + pause requested: 已经请求暂停,但恢复尚未真正暂停。 - paused: 恢复已暂停。 + paused: 恢复已暂停。 @@ -1853,9 +1806,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage stats_reset timestamp with time zone - - 这些统计数据上次重置的时间 - + 这些统计信息上次被重置的时间 @@ -1930,9 +1881,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage wal_distance int - - 预取器向前查看多少字节 - + 预取器向前查看的字节数 @@ -1941,9 +1890,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage block_distance int - - 预取器正在查看多少个块之前 - + 预取器向前查看的块数 @@ -1952,9 +1899,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage io_depth int - - 已启动但尚未完成的预取数量 - + 已启动但尚未确认完成的预取数量 @@ -1997,7 +1942,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + subname name @@ -2006,7 +1951,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + worker_type text @@ -2015,7 +1960,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + pid integer @@ -2024,68 +1969,69 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + leader_pid integer - 如果此进程是并行应用工作进程,则为主应用工作进程的进程 ID;如果此进程是主应用工作进程、表同步工作进程或序列同步工作进程,则为 NULL + 如果此进程是并行应用工作进程,则为领导者应用工作进程的进程 ID;如果此进程是领导者应用工作进程、表同步工作进程或序列同步工作进程,则为 NULL - + relid oid - 该工作进程正在同步的关系的 OID;主应用工作进程、并行应用工作进程和序列同步工作进程则为 NULL + 该工作进程正在同步的关系的 OID;对于领导者应用工作进程、并行应用工作进程和序列同步工作进程,则为空值 - + received_lsn pg_lsn - 接收到的最后一个预写式日志位置,该字段的初始值为0;并行应用工作进程和序列同步工作进程则为 NULL - + 接收到的最后一个预写式日志位置,该字段的初始值为 0;对于并行应用工作进程和序列同步工作进程,则为 NULL + - + last_msg_send_time timestamp with time zone - 从源 WAL 发送进程收到的最后一条消息的发送时间;并行应用工作进程和序列同步工作进程则为 NULL - + 从源 WAL 发送进程收到的最后一条消息的发送时间;对于并行应用工作进程和序列同步工作进程,则为 NULL + - + last_msg_receipt_time timestamp with time zone - 从源 WAL 发送进程收到的最后一条消息的接收时间;并行应用工作进程和序列同步工作进程则为 NULL - + 从源 WAL 发送进程收到的最后一条消息的接收时间;对于并行应用工作进程和序列同步工作进程,则为 NULL + - + latest_end_lsn pg_lsn - 向源 WAL 发送进程报告的最后一个预写式日志位置;并行应用工作进程和序列同步工作进程则为 NULL - + 向源 WAL 发送进程报告的最后一个预写式日志位置;对于并行应用工作进程和序列同步工作进程,则为 NULL + - + latest_end_time timestamp with time zone - 向 源 WAL 发送进程报告最后一个预写式日志位置的时间;并行应用工作进程和序列同步工作进程则为 NULL - + 向源 WAL 发送进程报告最后一个预写式日志位置的时间;对于并行应用工作进程和序列同步工作进程,则为 NULL + +
@@ -2144,7 +2090,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage apply_error_count bigint - 应用更改时发生错误的次数 + 应用更改时发生错误的次数。请注意,导致应用错误的任何冲突都会同时计入 apply_error_count 和对应的冲突计数(例如 confl_*)。 @@ -2244,9 +2190,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage stats_reset timestamp with time zone - - 这些统计数据最后一次重置的时间 - + 这些统计信息上次被重置的时间 @@ -2307,7 +2251,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage version text - 使用SSL的版本,如果此连接上没有使用SSL则为NULL + 使用SSL的版本,如果此连接上没有使用SSL则为空值 @@ -2316,7 +2260,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage cipher text - 正在使用的SSL密码的名称,如果此连接上没有使用SSL则为NULL + 正在使用的SSL 密码套件的名称,如果此连接上没有使用SSL则为空值 @@ -2325,7 +2269,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage bits integer - 使用的加密算法中的位数,如果此连接上没有使用SSL则为NULL + 使用的加密算法中的位数,如果此连接上没有使用SSL则为空值 @@ -2334,8 +2278,8 @@ description | Waiting for a newly initialized WAL file to reach durable storage client_dn text - 区别名称(DN,Distinguished Name)字段与使用的客户端证书,如果没有提供客户端证书或在此连接上没有使用SSL,则为NULL。 - 如果DN字段长于NAMEDATALEN(标准构建中为64个字符),则该字段将被截断。 + 所用客户端证书中的区别名称(DN,Distinguished Name)字段,如果没有提供客户端证书或在此连接上没有使用SSL,则为空值。 + 如果DN字段长于NAMEDATALEN(标准构建中为64个字符),则该字段将被截断。 @@ -2344,8 +2288,8 @@ description | Waiting for a newly initialized WAL file to reach durable storage client_serial numeric - 客户端证书的序列号,如果没有提供客户端证书或在此连接上没有使用SSL,则为NULL。 - 证书序列号和证书颁发者的组合唯一标识一个证书(除非颁发者错误地重用序列号)。 + 客户端证书的序列号,如果没有提供客户端证书或在此连接上没有使用SSL,则为空值。 + 证书序列号和证书颁发者的组合唯一标识一个证书(除非颁发者错误地重用序列号)。 @@ -2354,7 +2298,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage issuer_dn text - 客户端证书颁发者的区别名称(DN,Distinguished Name),如果没有提供客户端证书或在此连接上没有使用SSL,则为NULL。该字段像client_dn一样被截断。 + 客户端证书颁发者的区别名称(DN,Distinguished Name),如果没有提供客户端证书或在此连接上没有使用SSL,则为空值。该字段像client_dn一样被截断。 @@ -2372,7 +2316,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage pg_stat_gssapi视图将包含每一个后端一个行,显示该连接上的GSSAPI使用情况。 - 它可以加入到pg_stat_activitypg_stat_replication上的pid列,获取更多关于连接的详细信息。 + 可以通过pid列将它与pg_stat_activitypg_stat_replication连接,获取更多关于连接的详细信息。 @@ -2416,8 +2360,8 @@ description | Waiting for a newly initialized WAL file to reach durable storage principaltext - 用于验证此连接的主体,如果未使用GSSAPI对此连接进行认证,则为NULL。 - 如果主体长度超过NAMEDATALEN(标准构建中为64个字符),则该字段被截断。 + 用于认证此连接的主体,如果未使用GSSAPI对此连接进行认证,则为空值。 + 如果主体长度超过NAMEDATALEN(标准构建中为64个字符),则该字段被截断。 @@ -2531,9 +2475,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage stats_reset timestamp with time zone - - 这些统计数据最后一次重置的时间 - + 这些统计信息上次被重置的时间 @@ -2583,7 +2525,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage backend_typetext - 后端类型(例如后台工作进程、autovacuum 工作进程)。有关 backend_type 的更多信息,请参阅pg_stat_activity。某些 backend_type 不会累计 I/O 操作统计信息,因此不会出现在该视图中。 + 后端类型(例如后台工作进程、自动清理工作进程)。有关 backend_type 的更多信息,请参阅pg_stat_activity。某些 backend_type 不会累积 I/O 操作统计信息,因此不会出现在该视图中。 @@ -2595,7 +2537,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage I/O 操作的目标对象。可能的值有: - + @@ -2613,6 +2555,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage + @@ -2637,7 +2580,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - vacuum:对永久关系执行 vacuum 和 analyze 时,在共享缓冲区之外执行的 I/O 操作。临时表 vacuum 与其他临时表 I/O 操作共用同一本地缓冲池,因此会在 contextnormal 时跟踪。 + vacuum:对永久关系执行清理和分析 时,在共享缓冲区之外执行的 I/O 操作。临时表清理 与其他临时表 I/O 操作共用同一本地缓冲池,因此会在 contextnormal 时跟踪。 @@ -2839,9 +2782,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage stats_reset timestamp with time zone - - 这些统计信息上次被重置的时间。 - + 这些统计信息上次被重置的时间。 @@ -2853,7 +2794,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - 此外,某些 I/O 操作永远不会由某些后端类型执行,或者永远不会针对某些 I/O 对象和/或在某些 I/O 上下文中执行。这些单元格会是 NULL。例如,临时表不会执行 fsync,因此当 objecttemp relation 时,fsyncs 将为 NULL。又如,后台写入器不会执行读取,因此当 backend_typebackground writer 时,reads 将为 NULL。 + 此外,某些 I/O 操作永远不会由某些后端类型执行,或者永远不会针对某些 I/O 对象和/或在某些 I/O 上下文中执行。这些单元格会是空值。例如,临时表不会执行 fsync,因此当 objecttemp relation 时,fsyncs 将为空值。又如,后台写入器不会执行读取,因此当 backend_typebackground writer 时,reads 将为空值。 @@ -2870,7 +2811,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - 客户端后端依赖检查点进程确保数据持久化到永久存储。客户端后端出现大量 fsyncs 可能表明共享缓冲区或检查点进程配置不当。有关配置检查点进程的更多信息,请参阅。 + 客户端后端依赖检查点进程确保数据持久化到永久存储。client backend出现大量 fsyncs 可能表明共享缓冲区或检查点进程配置不当。有关配置检查点进程的更多信息,请参阅 @@ -3041,7 +2982,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage waits bigint - 由于冲突锁而必须等待的这种锁类型的次数。只有在等待超过 后成功获得锁时才会递增。 + 此类型的锁因与其他锁冲突而必须等待的次数。只有在等待超过 后成功获得锁时才会递增。 @@ -3073,9 +3014,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage stats_reset timestamp with time zone - - 这些统计信息上次被重置的时间。 - + 这些统计信息上次被重置的时间。 @@ -3140,9 +3079,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage stats_reset timestamp with time zone - - 这些统计信息上次被重置的时间 - + 这些统计信息上次被重置的时间 @@ -3270,9 +3207,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage stats_reset timestamp with time zone - - 这些统计信息上次被重置的时间 - + 这些统计信息上次被重置的时间 @@ -3336,7 +3271,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage wal_bytes numeric - 生成的WAL总数,以字节计 + 生成的 WAL 总量,以字节计 @@ -3354,56 +3289,23 @@ description | Waiting for a newly initialized WAL file to reach durable storage wal_buffers_full bigint - 因为缓冲区已满,WAL数据被写入磁盘的次数 + 因为 WAL 缓冲区已满,WAL 数据被写入磁盘的次数 - - - wal_write bigint - - - 通过XLogWrite请求,WAL缓冲区被写入到磁盘的次数。 - 有关内部WAL函数XLogWrite的更多信息,请参见。 - - - - - wal_sync bigint - - - 通过issue_xlog_fsync 请求将WAL文件同步到磁盘的次数(如果onfdatasync, fsyncfsync_writethrough,否则为零)。 - 有关内部WAL函数issue_xlog_fsync的更多信息,参见。 - - - - - wal_write_time double precision - - - 通过XLogWrite请求将WAL缓冲区写入磁盘所消耗的总时间,以毫秒计(如果是启用的,否则为零)。 - 这包括当wal_sync_methodopen_datasyncopen_sync时的同步时间。 - - - - - wal_sync_time double precision - - - 通过issue_xlog_fsync请求将WAL文件同步到磁盘所消耗的总时间,以毫秒计(如果 track_wal_io_timing 被启用,fsync is on, 和 wal_sync_methodfdatasync, fsyncfsync_writethrough, 否则为零). - - + + + + stats_reset timestamp with time zone - - 这些统计数据最后一次重置的时间 - + 这些统计信息上次被重置的时间 @@ -3449,7 +3351,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + datname name @@ -3458,17 +3360,17 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + numbackends integer 当前连接到此数据库的后端数,对于共享对象则为NULL。 - 这是该视图中唯一返回反映当前状态的值的列;所有其他列返回自上次重置以来累积的值。 + 这是该视图中唯一返回反映当前状态的值的列;所有其他列返回自上次重置以来累积的值。 - + xact_commit bigint @@ -3477,7 +3379,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + xact_rollback bigint @@ -3486,7 +3388,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + blks_read bigint @@ -3495,7 +3397,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + blks_hit bigint @@ -3504,7 +3406,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + tup_returned bigint @@ -3513,7 +3415,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + tup_fetched bigint @@ -3522,7 +3424,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + tup_inserted bigint @@ -3531,7 +3433,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + tup_updated bigint @@ -3540,7 +3442,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + tup_deleted bigint @@ -3549,7 +3451,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + conflicts bigint @@ -3558,7 +3460,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + temp_files bigint @@ -3567,7 +3469,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + temp_bytes bigint @@ -3576,7 +3478,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + deadlocks bigint @@ -3585,7 +3487,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + checksum_failures bigint @@ -3594,7 +3496,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + checksum_last_failure timestamp with time zone @@ -3603,7 +3505,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + blk_read_time double precision @@ -3612,7 +3514,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + blk_write_time double precision @@ -3621,25 +3523,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - - - parallel_workers_to_launch bigint - - - 计划由该数据库上的查询启动的并行工作进程数 - - - - - - parallel_workers_launched bigint - - - 由该数据库上的查询启动的并行工作进程数 - - - - + session_time double precision @@ -3648,7 +3532,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + active_time double precision @@ -3657,7 +3541,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + idle_in_transaction_time double precision @@ -3666,7 +3550,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + sessions bigint @@ -3675,7 +3559,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + sessions_abandoned bigint @@ -3684,7 +3568,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + sessions_fatal bigint @@ -3693,7 +3577,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + sessions_killed bigint @@ -3702,7 +3586,25 @@ description | Waiting for a newly initialized WAL file to reach durable storage - + + + parallel_workers_to_launch bigint + + + 计划由该数据库上的查询启动的并行工作进程数 + + + + + + parallel_workers_launched bigint + + + 由该数据库上的查询启动的并行工作进程数 + + + + stats_reset timestamp with time zone @@ -3710,6 +3612,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage 这些统计数据最后一次重置的时间 +
@@ -3796,7 +3699,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage confl_bufferpin bigint - 此数据库中由于固定缓冲区而被取消的查询数 + 此数据库中由于缓冲区被钉住而被取消的查询数 @@ -3912,7 +3815,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage seq_tup_read bigint - 连续扫描获取的实时行数 + 顺序扫描获取的存活行数 @@ -3939,7 +3842,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage idx_tup_fetch bigint - 索引扫描获取的实时行数 + 索引扫描获取的存活行数 @@ -3956,9 +3859,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage n_tup_upd bigint - - 更新的行数(包括HOT更新的行) - + 更新的总行数。(包括计入n_tup_hot_updn_tup_newpage_upd的行更新,以及其余非HOT更新。) @@ -3974,9 +3875,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage n_tup_hot_upd bigint - - HOT更新的行数(即,不需要单独的索引更新) - + 进行HOT 更新的行数。这些更新不需要在索引中存储后继版本。 @@ -3984,7 +3883,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage n_tup_newpage_upd bigint - 更新的行数,其中后继版本转到新的堆页,留下一个原始版本,其t_ctid字段指向不同的堆页。这些始终是非 HOT 更新。 + 更新的行数,其中后继版本转到的堆页,留下一个原始版本,其t_ctid字段指向不同的堆页。这些始终是非 HOT 更新。 @@ -4019,9 +3918,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage n_ins_since_vacuum bigint - - 自上次清理此表以来插入的行的估计数量 - + 自上次清理此表以来插入的行的估计数量(不计VACUUM FULL @@ -4029,7 +3926,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage last_vacuum timestamp with time zone - 最后一次手动清理这个表(不包括VACUUM FULL) + 最后一次手动清理这个表的时间(不包括VACUUM FULL @@ -4047,7 +3944,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage last_analyze timestamp with time zone - 上一次手动分析这个表 + 上一次手动分析这个表的时间 @@ -4056,7 +3953,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage last_autoanalyze timestamp with time zone - 自动清理守护进程最后一次分析这个表 + 自动清理守护进程最后一次分析这个表的时间 @@ -4065,7 +3962,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage vacuum_count bigint - 这个表被手动清理的次数(VACUUM FULL不计数) + 这个表被手动清理的次数(VACUUM FULL不计数) @@ -4101,7 +3998,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage total_vacuum_time double precision - 手动 VACUUM 此表所花费的总时间,以毫秒计(不包括 VACUUM FULL)。(这包括由于基于成本的延迟而睡眠的时间。) + 手动清理此表所花费的总时间,以毫秒计(不包括 VACUUM FULL)。(这包括由于基于代价的延迟而睡眠的时间。) @@ -4110,7 +4007,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage total_autovacuum_time double precision - 自动清理守护进程对该表执行 VACUUM 所花费的总时间,以毫秒计。(这包括由于基于成本的延迟而睡眠的时间。) + 自动清理守护进程清理该表 所花费的总时间,以毫秒计。(这包括由于基于代价的延迟而睡眠的时间。) @@ -4119,7 +4016,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage total_analyze_time double precision - 手动分析该表所花费的总时间,以毫秒计。(这包括由于基于成本的延迟而睡眠的时间。) + 手动分析该表所花费的总时间,以毫秒计。(这包括由于基于代价的延迟而睡眠的时间。) @@ -4128,7 +4025,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage total_autoanalyze_time double precision - 自动清理守护进程分析该表所花费的总时间,以毫秒计。(这包括由于基于成本的延迟而睡眠的时间。) + 自动清理守护进程分析该表所花费的总时间,以毫秒计。(这包括由于基于代价的延迟而睡眠的时间。) @@ -4395,7 +4292,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage idx_tup_fetch bigint - 使用此索引进行简单索引扫描获取的活动表行数 + 使用此索引进行简单索引扫描获取的存活表行数 @@ -4412,16 +4309,25 @@ description | Waiting for a newly initialized WAL file to reach durable storage - 索引可以被简单索引扫描、位图索引扫描以及优化器使用。在一次位图扫描中,多个索引的输出可以被通过 AND 或 OR 规则组合,因此当使用一次位图扫描时难以将取得的个体堆行与特定的索引关联起来。因此,一次位图扫描会增加它使用的索引的pg_stat_all_indexes.idx_tup_read计数,并且为每个表增加pg_stat_all_tables.idx_tup_fetch计数,但是它不影响pg_stat_all_indexes.idx_tup_fetch。如果所提供的常量值不在优化器统计信息记录的范围之内,优化器也会访问索引来检查,因为优化器统计信息可能已经“不新鲜”了。 + 索引可以被简单索引扫描、位图索引扫描以及优化器使用。在一次位图扫描中,多个索引的输出可以被通过 AND 或 OR 规则组合,因此当使用一次位图扫描时难以将取得的个体堆行与特定的索引关联起来。因此,一次位图扫描会增加它使用的索引的pg_stat_all_indexes.idx_tup_read计数,并且为该表增加pg_stat_all_tables.idx_tup_fetch计数,但是它不影响pg_stat_all_indexes.idx_tup_fetch。如果所提供的常量值不在优化器统计信息记录的范围之内,优化器也会访问索引来检查,因为优化器统计信息可能已经过时。 - 即使不用位图扫描,idx_tup_readidx_tup_fetch计数也可能不同,因为idx_tup_read统计从该索引取得的索引项而idx_tup_fetch统计从表取得的活着的行。如果使用该索引取得了任何死亡行或还未提交的行,或者如果通过一次只用索引扫描的方式避免了任何堆获取,后者将较小。 + 即使不用位图扫描,idx_tup_readidx_tup_fetch计数也可能不同,因为idx_tup_read统计从该索引取得的索引项而idx_tup_fetch统计从表取得的存活行。如果使用该索引取得了任何死亡行或还未提交的行,或者如果通过一次仅索引扫描的方式避免了任何堆获取,后者将较小。 + + 索引扫描在一次执行中有时会进行多次索引搜索。每次索引搜索都会递增pg_stat_all_indexes.idx_scan,因此索引扫描计数可能显著超过索引扫描执行器节点的总执行次数。 + 使用某些SQL构造来搜索与列表或数组中的多个标量值之一匹配的行时,可能出现这种情况(参见)。使用column_name = value1 OR column_name = value2 ...构造的查询也可能如此,但前提是优化器将该构造转换为等价的多值数组表示。同样,当 B-树索引扫描使用跳跃扫描优化时,每次将扫描位置移至下一个可能包含匹配元组的索引叶子页,都会进行一次索引搜索(参见)。 + + + + EXPLAIN ANALYZE会输出每个索引扫描节点执行的索引搜索总次数。有关展示其工作方式的示例,请参见 + + @@ -4521,7 +4427,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage toast_blks_read bigint - 从这个表的TOAST表中读取的磁盘块的数量(如果有的话) + 从这个表的TOAST表中读取的磁盘块的数量(如果有的话) @@ -4530,7 +4436,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage toast_blks_hit bigint - 这个表的TOAST表中的缓冲区命中数(如果有的话) + 这个表的TOAST表中的缓冲区命中数(如果有的话) @@ -4539,7 +4445,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage tidx_blks_read bigint - 从这个表的TOAST表索引中读取的磁盘块的数量(如果有的话) + 从这个表的TOAST表索引中读取的磁盘块的数量(如果有的话) @@ -4548,15 +4454,13 @@ description | Waiting for a newly initialized WAL file to reach durable storage tidx_blks_hit bigint - 这个表的TOAST表索引中的缓冲区命中数(如果有的话) + 这个表的TOAST表索引中的缓冲区命中数(如果有的话) stats_reset timestamp with time zone - - 这些统计信息上次被重置的时间 - + 这些统计信息上次被重置的时间 @@ -4661,9 +4565,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage stats_reset timestamp with time zone - - 这些统计信息上次被重置的时间 - + 这些统计信息上次被重置的时间 @@ -4749,9 +4651,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage stats_reset timestamp with time zone - - 这些统计信息上次被重置的时间 - + 这些统计信息上次被重置的时间 @@ -4847,9 +4747,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage stats_reset timestamp with time zone - - 这些统计数据最后一次重置的时间 - + 这些统计信息上次被重置的时间 @@ -4870,10 +4768,9 @@ description | Waiting for a newly initialized WAL file to reach durable storage pg_stat_slru - - PostgreSQL通过SLRU(simple least-recently-used,简单的最近-最少-使用)缓存访问某些磁盘上的信息。 - pg_stat_slru视图将为每个被跟踪的SLRU缓存包含一行,显示关于访问缓存页面的统计信息。 - + PostgreSQL通过SLRU简单最近最少使用)缓存访问某些磁盘上的信息。pg_stat_slru视图将为每个被跟踪的 SLRU 缓存包含一行,显示关于访问缓存页面的统计信息。 + + 对于核心服务器中的每个SLRU缓存,都有一个以_buffers为后缀的配置参数来控制其大小。 @@ -4916,7 +4813,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage blks_hitbigint - 已经在SLRU中的磁盘块被发现的次数,因此不需要读取(这只包括SLRU中的命中,而不是操作系统的文件系统缓存) + 已经在SLRU中的磁盘块被发现的次数,因此不需要读取(这只包括SLRU中的命中,而不是操作系统的文件系统缓存) @@ -4952,7 +4849,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage flushesbigint - 此SLRU的脏数据刷新数 + 此SLRU的脏数据刷盘次数 @@ -4961,7 +4858,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage truncatesbigint - 这个SLRU的截断数 + 这个SLRU的截断次数 @@ -4969,9 +4866,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage stats_reset timestamp with time zone - - 这些统计数据最后一次重置的时间 - + 这些统计信息上次被重置的时间 @@ -4991,7 +4886,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage - 与累积统计系统相关的其他功能在中列出。 + 与累积统计系统相关的其他函数在中列出。
@@ -5035,7 +4930,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage 返回指定进程 ID 的后端的 I/O 统计信息。输出字段与 pg_stat_io 视图中的字段完全相同。 - 该函数不会返回检查点进程、后台写入器、启动进程和 自动清理启动器的 I/O 统计信息,因为这些统计信息已经在 pg_stat_io 视图中可见,而且每种都只有一个。 + 该函数不返回检查点进程、后台写入器、启动进程和自动清理启动器的 I/O 统计信息,因为这些统计信息已显示在 pg_stat_io 视图中,而且每种进程都只有一个。 @@ -5094,7 +4989,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage timestamp with time zone - 返回当前统计快照的时间戳,如果没有统计快照则返回NULL。如果在事务中第一次访问累积统计信息时将快照设置为stats_fetch_consistencysnapshot。 + 返回当前统计快照的时间戳;如果尚未获取统计快照,则返回 NULL。如果 stats_fetch_consistency 设置为 snapshot,则会在事务中第一次访问累积统计信息时获取快照。 @@ -5107,11 +5002,9 @@ description | Waiting for a newly initialized WAL file to reach durable storage void - 将当前数据库中的单个索引,或集簇中所有数据库共享的单个索引的统计信息重置为零。 + 将单个索引的统计信息重置为零;该索引可以位于当前数据库中,也可以由集簇中的所有数据库共享。 - - 默认情况下,此函数仅限超级用户使用,但可以向其他用户授予 EXECUTE 权限来运行此函数。 - + 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 @@ -5166,9 +5059,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage 将当前数据库的所有统计计数器重置为零。 - - 默认情况下该函数仅限于超级用户,但是其他用户可以被授予EXECUTE来运行此函数。 - + 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 @@ -5176,51 +5067,70 @@ description | Waiting for a newly initialized WAL file to reach durable storage pg_stat_reset_shared - pg_stat_reset_shared ( text ) + pg_stat_reset_shared ( [ target text DEFAULT NULL ] ) void - 根据参数将一些集簇范围的统计计数器重置为零。参数可以是lock,用于重置在pg_stat_lock视图中显示的所有计数器,或bgwriter, - 用于重置在pg_stat_bgwriter视图中显示的所有计数器, - archiver,用于重置在pg_stat_archiver视图中显示的所有计数器, - wal,用于重置在pg_stat_wal视图中显示的所有计数器, - 或recovery_prefetch,用于重置在pg_stat_recovery_prefetch视图中显示的所有计数器。 + 根据参数将一些集簇范围的统计计数器重置为零。target 可以是: + + + archiver:重置 pg_stat_archiver 视图中显示的所有计数器。 + + + bgwriter:重置 pg_stat_bgwriter 视图中显示的所有计数器。 + + + checkpointer:重置 pg_stat_checkpointer 视图中显示的所有计数器。 + + + io:重置 pg_stat_io 视图中显示的所有计数器。 + + + lock:重置 pg_stat_lock 视图中显示的所有计数器。 + + + recovery_prefetch:重置 pg_stat_recovery_prefetch 视图中显示的所有计数器。 + + + slru:重置 pg_stat_slru 视图中显示的所有计数器。 + + + wal:重置 pg_stat_wal 视图中显示的所有计数器。 + + + NULL 或未指定:重置上述所有视图中的所有计数器。 + + - - 默认情况下,此函数仅限超级用户使用,但可以授予其他用户EXECUTE权限来运行该函数。 - + 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 - pg_stat_reset_backend_stats + pg_stat_reset_single_table_counters - pg_stat_reset_backend_stats ( integer ) + pg_stat_reset_single_table_counters ( oid ) void - 将指定进程 ID 的单个后端进程的统计信息重置为零。 + 将单个表的统计信息重置为零;该对象可以位于当前数据库中,也可以由集簇中的所有数据库共享。它也可以重置当前数据库中单个序列或物化视图的统计信息。 - - 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 - + 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 - pg_stat_reset_single_table_counters + pg_stat_reset_backend_stats - pg_stat_reset_single_table_counters ( oid ) + pg_stat_reset_backend_stats ( integer ) void - 将当前数据库中的单个表,或集簇中所有数据库共享的单个表的统计信息重置为零。它还会重置当前数据库中单个序列或物化视图的统计信息。 + 将指定进程 ID 的单个后端进程的统计信息重置为零。 - - 默认情况下,此函数仅限超级用户使用,但可以授予其他用户EXECUTE权限来运行该函数。 - + 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 @@ -5234,9 +5144,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage 将当前数据库中单个函数的统计信息重置为零。 - - 默认情况下该函数仅限于超级用户,但是其他用户可以被授予EXECUTE来运行此函数。 - + 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 @@ -5244,19 +5152,13 @@ description | Waiting for a newly initialized WAL file to reach durable storage pg_stat_reset_slru - pg_stat_reset_slru ( text ) + pg_stat_reset_slru ( [ target text DEFAULT NULL ] ) void - 将单个SLRU缓存或集簇中所有SLRU的统计信息重置为零。 - 如果该参数为NULL,则所有SLRU缓存的pg_stat_slru视图中显示的计数器将被重置。 - 参数可以是CommitTsMultiXactMemberMultiXactOffsetNotify、 - SerialSubtrans、 或Xact中的一个,以便只重置该条目的计数器。 - 如果参数是other(或实际上,任何无法识别的名称),那么所有其他SLRU缓存的计数器,如扩展定义的缓存,将被重置。 + 将单个 SLRU 缓存或集簇中所有 SLRU 的统计信息重置为零。如果 targetNULL 或未指定,则重置 pg_stat_slru 视图中所有 SLRU 缓存的全部计数器。参数可以为 commit_timestamp、&zwsp;multixact_member、&zwsp;multixact_offset、&zwsp;notify、&zwsp;serializable、&zwsp;subtransactiontransaction 中的一个,以便只重置对应条目的计数器。如果参数为 other(实际上,任何无法识别的名称都可以),则重置其他所有 SLRU 缓存的计数器,例如扩展定义的缓存。 - - 默认情况下该函数仅限于超级用户,但是其他用户可以被授予EXECUTE来运行此函数。 - + 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 @@ -5271,9 +5173,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage 重置由参数定义的复制槽的统计信息。 如果参数为NULL,则重置所有复制槽的统计信息。 - - 该函数默认仅限于超级用户,但可以授予其他用户EXECUTE权限来运行该函数。 - + 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 @@ -5288,9 +5188,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage 重置pg_stat_subscription_stats视图中显示的单个订阅的统计信息为零。 如果参数是NULL,则重置所有订阅的统计信息。 - - 默认情况下,此函数仅限超级用户使用,但其他用户可以被授予EXECUTE权限来运行该函数。 - + 默认情况下,此函数仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该函数。 @@ -5306,17 +5204,18 @@ description | Waiting for a newly initialized WAL file to reach durable storage - pg_stat_get_activitypg_stat_activity视图的底层函数, - 它返回一个行集合,其中包含有关每个后端进程所有可用的信息。有时只获得该信息的一个子集可能会更方便。 - 在那些情况中,可以使用一组更老的针对每个后端的统计访问函数,这些显示在中。 - 这些访问函数使用一个后端 ID 号,范围从 1 到当前活动后端数目。 - 函数pg_stat_get_backend_idset提供了一种方便的方法为每个活动后端产生一行来调用这些函数。 - 例如,要显示PID以及所有后端当前的查询: + pg_stat_get_activitypg_stat_activity 视图的底层函数, + 返回一组记录,其中包含有关每个后端进程的全部可用信息。有时只获取其中一部分信息会更方便。 + 在这种情况下,可以使用另一组针对每个后端的统计信息访问函数,见 。 + 这些访问函数使用会话的后端 ID 号,它是一个值较小的非负整数(>= 0),与任何并发会话的后端 ID 都不同, + 但会话退出后,其 ID 可立即被重新使用。后端 ID 的用途之一是标识会话的临时模式(如果有)。 + 函数 pg_stat_get_backend_idset 提供了一种便捷的方法,可列出所有活动后端的 ID 号来调用这些函数。 + 例如,要显示所有后端的 PID 和当前查询: -SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - pg_stat_get_backend_activity(s.backendid) AS query - FROM (SELECT pg_stat_get_backend_idset() AS backendid) AS s; +SELECT pg_stat_get_backend_pid(backendid) AS pid, + pg_stat_get_backend_activity(backendid) AS query +FROM pg_stat_get_backend_idset() AS backendid; @@ -5338,19 +5237,6 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - - - - pg_stat_get_backend_idset - - pg_stat_get_backend_idset () - setof integer - - - 返回当前活动后端ID号的集合(从1到活动后端数)。 - - - @@ -5370,7 +5256,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, pg_stat_get_backend_activity_start pg_stat_get_backend_activity_start ( integer ) - 有时区的时间戳 + timestamp with time zone 返回后端最近一次查询开始的时间。 @@ -5416,6 +5302,19 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, + + + + pg_stat_get_backend_idset + + pg_stat_get_backend_idset () + setof integer + + + 返回当前活动后端 ID 号的集合。 + + + @@ -5435,11 +5334,9 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, pg_stat_get_backend_start pg_stat_get_backend_start ( integer ) - 有时区的时间戳 + timestamp with time zone - - 返回该进程开始的时间。 - + 返回该进程开始的时间。 @@ -5471,28 +5368,28 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - pg_stat_get_backend_wait_event_type + pg_stat_get_backend_wait_event - pg_stat_get_backend_wait_event_type ( integer ) + pg_stat_get_backend_wait_event ( integer ) text - 如果后端当前正在等待,则返回等待事件类型名称,否则返回NULL。 - 请参阅。 + 如果后端当前正在等待,则返回等待事件名称,否则为空值。 + 请参阅 - pg_stat_get_backend_wait_event + pg_stat_get_backend_wait_event_type - pg_stat_get_backend_wait_event ( integer ) + pg_stat_get_backend_wait_event_type ( integer ) text - 如果后端当前正在等待,则返回等待事件名称,否则为NULL。 - 请参阅。 + 如果后端当前正在等待,则返回等待事件类型名称,否则返回空值。 + 请参阅 @@ -5502,7 +5399,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, pg_stat_get_backend_xact_start pg_stat_get_backend_xact_start ( integer ) - 有时区的时间戳 + timestamp with time zone 返回后端当前事务开始的时间。 @@ -5520,23 +5417,23 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, 查看锁 - lock - monitoring + + 监控 - 监控数据库活动的另外一个有用的工具是pg_locks系统表。这样就允许数据库管理员查看在锁管理器里面未解决的锁的信息。例如,这个功能可以被用于: + 监控数据库活动的另外一个有用的工具是pg_locks系统表。这样就允许数据库管理员查看锁管理器中当前存在的锁的信息。例如,这个功能可以被用于: - 查看当前所有未解决的锁、在一个特定数据库中的关系上所有的锁、在一个特定关系上所有的锁,或者由一个特定PostgreSQL会话持有的所有的锁。 + 查看当前存在的所有锁、在一个特定数据库中的关系上所有的锁、在一个特定关系上所有的锁,或者由一个特定PostgreSQL会话持有的所有的锁。 - 判断当前数据库中带有最多未授予锁的关系(它很可能是数据库客户端的竞争源)。 + 判断当前数据库中带有最多未授予锁的关系(它可能是数据库客户端之间的竞争来源)。 @@ -5703,7 +5600,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, delay_time double precision - 因基于成本的延迟而睡眠的总时间(参见),以毫秒计(如果启用了 ,否则为零)。 + 因基于代价的延迟而睡眠的总时间(参见),以毫秒计(如果启用了 ,否则为零)。 @@ -5756,14 +5653,14 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, acquiring sample rows - 该命令当前正在扫描relid给出的表以获得样例行。 + 该命令当前正在扫描relid给出的表以获得样本行。 acquiring inherited sample rows - 该命令当前正在扫描子表以获得样例行。列child_tables_total,child_tables_done, + 该命令当前正在扫描子表以获得样本行。列child_tables_totalchild_tables_done、 和current_child_table_relid包含此阶段的进度信息。 @@ -5771,14 +5668,14 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, computing statistics - 该命令从表扫描期间获得的样例行计算统计信息。 + 该命令从表扫描期间获得的样本行计算统计信息。 computing extended statistics - 该命令从表扫描期间获得的样例行计算扩展统计信息。 + 该命令从表扫描期间获得的样本行计算扩展统计信息。 @@ -5794,29 +5691,25 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - - 注意当在分区表上运行ANALYZE时,它的所有分区也会被递归分析。 - 在这种情况下,首先报告父表的ANALYZE进度,收集它的继承统计信息,然后是每个分区的(继承统计信息)。 - + 请注意,当在分区表上运行ANALYZE且未指定ONLY关键字时,其所有分区也会被递归分析。在这种情况下,会先报告父表的ANALYZE进度,并收集其继承统计信息,随后再报告每个分区的进度。 - + - CREATE INDEX 进度报告 + CLUSTER 进度报告 - pg_stat_progress_create_index + pg_stat_progress_cluster - 每当运行CREATE INDEXREINDEX时,pg_stat_progress_create_index视图将包含当前正在创建索引的每个后端的一行。 - 下面的表描述了将要报告的信息,并提供了关于如何解释它的信息。 + 每当REPACKCLUSTERVACUUM FULL运行时,为向后兼容而保留的pg_stat_progress_cluster视图将为每个当前正在运行这些命令之一的后端包含一行。下面的表格描述了将被报告的信息,并提供了关于如何解释这些信息的信息。 -
+
- <structname>pg_stat_progress_create_index</structname> 视图 + <structname>pg_stat_progress_cluster</structname> 视图 @@ -5864,16 +5757,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, relidoid - 正在创建索引的表的OID。 - - - - - - index_relid oid - - - 正在创建或重建索引的OID。在非并发 CREATE INDEX的时候,此为 0。 + 正在聚簇的表的OID。 @@ -5882,8 +5766,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, commandtext - 在运行的命令: CREATE INDEX,CREATE INDEX CONCURRENTLY, - REINDEX, 或 REINDEX CONCURRENTLY. + 正在运行的命令。CLUSTERVACUUM FULL。由于此视图仅为向后兼容而存在,它会将任何REPACK命令映射为这两种命令之一。 @@ -5892,176 +5775,526 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, phasetext - 索引创建的当前处理阶段。 参见 。 - - - - - - lockers_total bigint - - - 在适用的情况下,需要等待的储物柜总数 - - - - - - lockers_done bigint - - - 已经等待的储物柜数量。 - - - - - - current_locker_pid bigint - - - 目前正在等待的储物柜的进程ID。 + 当前处理阶段。参见 - blocks_total bigint + cluster_index_relid oid - 本阶段要处理的区块总数。 + 如果正在使用索引对表进行扫描,这就是正在使用的索引的OID;否则为0。 - blocks_done bigint + heap_tuples_scanned bigint - 当前阶段已经处理的区块数量。 + 扫描的堆元组数。 + 该计数器仅在阶段为seq scanning heapindex scanning heap + 或 writing new heap 时才会递增。 - tuples_total bigint + heap_tuples_written bigint - 当前阶段要处理的元组总数。 + 写入的堆元组的数量。这个计数器只有在阶段为seq scanning heapindex scanning heap + 或 writing new heap时才会递增。 - tuples_done bigint + heap_blks_total bigint - 在当前阶段已经处理的元组数量。 + 表中的堆块总数。 这个数字以seq scanning heap开始时的数量为准。 - partitions_total bigint + heap_blks_scanned bigint - 在分区表上创建索引时,该列被设置为要在其上创建索引的分区总数。 - 在REINDEX期间,此字段为0。 + 扫描的堆块数量。该计数器仅在阶段为seq scanning heap时才会递增。 - partitions_done bigint + index_rebuild_count bigint - 当在分区表上创建索引时,该列被设置为在其上建立索引的分区数。 - 在REINDEX期间,此字段为0。 + 已重建的索引数。该计数器仅在rebuilding index阶段时才会递增。
- +
- CREATE INDEX 的阶段 + CLUSTER 和 VACUUM FULL 阶段 - + 阶段 描述 - - - 初始化 - - CREATE INDEXREINDEX正在准备创建索引。 这个阶段预计会非常短暂。 - - + - - 构建前等待读写器 - - CREATE INDEX CONCURRENTLYREINDEX CONCURRENTLY正在等待有可能看到表的写锁的事务完成。 当不在并发模式时,这个阶段会被跳过。lockers_totallockers_donecurrent_locker_pid 列包含了这个阶段的进度信息。 + + initializing + + 命令正在准备开始扫描堆。这个阶段预计会非常短暂。 - + - - 新建索引 - - 索引是由访问方法专用代码建立的。 在这一阶段,支持进度报告的访问方法填写自己的进度数据,子阶段在这一栏中表示。 通常情况下,blocks_totalblocks_done将包含进度数据,也可能包含tuples_totaltuples_done。 - - + + seq scanning heap + + 该命令目前采用顺序扫描的方式对表进行扫描。 + + - - 在验证前等待读写器 - - CREATE INDEX CONCURRENTLYREINDEX CONCURRENTLY正在等待有可能写入表的事务完成写锁的事务。当不在并发模式时,这个阶段会被跳过。lockers_totallockers_donecurrent_locker_pid 列包含了这个阶段的进度信息。 - - + + index scanning heap + + CLUSTER目前正在使用索引扫描表。 + + - - 索引验证:扫描索引 - - CREATE INDEX CONCURRENTLY正在扫描索引,搜索需要验证的元组。如果不是并发模式,则会跳过此阶段。列 blocks_total(设为索引总大小)和 blocks_done 包含该阶段的进度信息。 - - + + sorting tuples + + CLUSTER目前正在对元组进行排序。 + + + + + writing new heap + + CLUSTER目前正在写入新的堆。 + + + + + swapping relation files + + 目前,该命令正在将新建立的文件调换到位。 + + + + + rebuilding index + + 该命令目前正在重建一个索引。 + + + + + performing final cleanup + + 该命令正在执行最后的清理工作。 当此阶段完成后,CLUSTERVACUUM FULL将结束。 + + + + +
+ + + + + COPY 进度报告 + + + pg_stat_progress_copy + + + + 当COPY正在运行时,pg_stat_progress_copy视图会为每个当前正在执行COPY命令的后端包含一行。下表描述了会报告哪些信息,以及应如何解释这些信息。 + + + + + <structname>pg_stat_progress_copy</structname> 视图 + + + + + + 列类型 + + + 描述 + + + + + + + + + pid integer + + + 后端的进程ID。 + + + + + + datid oid + + + 后端连接到的数据库的OID。 + + + + + + datname name + + + 后端连接到的数据库的名称。 + + + + + + relid oid + + + 执行COPY命令的表的OID。 + 如果从SELECT查询中复制,它被设置为0。 + + + + + + command text + + + 正在运行的命令: COPY FROMCOPY TO。 + + + + + + type text + + 读取或写入数据的 I/O 类型:FILEPROGRAMPIPE(用于COPY FROM STDINCOPY TO STDOUT),或CALLBACK(例如在逻辑复制的初始表同步期间使用)。 + + + + + bytes_processed bigint + + + 已经被COPY命令处理的字节数。 + + + + + + bytes_total bigint + + + COPY FROM命令的源文件大小,以字节计。 + 如果不可用则设置为0。 + + + + + + tuples_processed bigint + + + 已经被COPY命令处理的元组数。 + + + + + + tuples_excluded bigint + + + 没有处理的元组数,因为它们被COPY命令的WHERE子句所排除。 + + + + + + tuples_skipped bigint + + + 因包含格式错误的数据而被跳过的元组数。只有当 ON_ERROR 指定为 ignore 时,此计数器才会递增。 + + + + +
+
+ + + + CREATE INDEX 进度报告 + + + pg_stat_progress_create_index + + + + 每当运行CREATE INDEXREINDEX时,pg_stat_progress_create_index视图将包含当前正在创建索引的每个后端的一行。 + 下面的表描述了将要报告的信息,并提供了关于如何解释它的信息。 + + + + + <structname>pg_stat_progress_create_index</structname> 视图 + + + + + + 列类型 + + + 描述 + + + + + + + + + pid integer + + 正在创建索引的后端的进程 ID。 + + + + + datid oid + + + 后端连接到的数据库的OID。 + + + + + + datname name + + + 后端连接到的数据库的名称。 + + + + + + relid oid + + + 正在创建索引的表的OID。 + + + + + + index_relid oid + + + 正在创建或重建索引的OID。在非并发 CREATE INDEX的时候,此为 0。 + + + + + + command text + + + 具体命令类型: CREATE INDEXCREATE INDEX CONCURRENTLY、 + REINDEXREINDEX CONCURRENTLY。 + + + + + + phase text + + + 索引创建的当前处理阶段。 参见 。 + + + + + + lockers_total bigint + + 在适用的情况下,需要等待的持锁进程总数。 + + + + + lockers_done bigint + + 已完成等待的持锁进程数量。 + + + + + current_locker_pid bigint + + 当前正在等待的持锁进程的进程 ID。 + + + + + blocks_total bigint + + + 本阶段要处理的块总数。 + + + + + + blocks_done bigint + + + 当前阶段已经处理的块数量。 + + + + + + tuples_total bigint + + + 当前阶段要处理的元组总数。 + + + + + + tuples_done bigint + + + 在当前阶段已经处理的元组数量。 + + + + + + partitions_total bigint + + 要创建或附加索引的分区总数,包括直接分区和间接分区。在REINDEX期间,或索引未分区时,此值为0 + + + + + partitions_done bigint + + 已创建或附加索引的分区数量,包括直接分区和间接分区。在REINDEX期间,或索引未分区时,此值为0 + + + +
+ + + + CREATE INDEX 阶段 + + + + + + + 阶段 + 描述 + + + + + + initializing + + CREATE INDEXREINDEX正在准备创建索引。 这个阶段预计会非常短暂。 + + + + + waiting for writers before build + + CREATE INDEX CONCURRENTLYREINDEX CONCURRENTLY正在等待持有写锁且可能看到该表的事务结束。 当不在并发模式时,这个阶段会被跳过。lockers_totallockers_donecurrent_locker_pid 列包含了这个阶段的进度信息。 + + + + + building index + + 索引是由访问方法专用代码建立的。 在这一阶段,支持进度报告的访问方法填写自己的进度数据,子阶段在这一栏中表示。 通常情况下,blocks_totalblocks_done将包含进度数据,tuples_totaltuples_done也可能包含进度数据。 + + - 索引验证:排序元组 + waiting for writers before validation + + CREATE INDEX CONCURRENTLYREINDEX CONCURRENTLY正在等待持有写锁且可能写入该表的事务结束。当不在并发模式时,这个阶段会被跳过。lockers_totallockers_donecurrent_locker_pid 列包含了这个阶段的进度信息。 + + + + + index validation: scanning index + + CREATE INDEX CONCURRENTLY正在扫描索引,搜索需要验证的元组。如果不是并发模式,则会跳过此阶段。列 blocks_total(设为索引总大小)和 blocks_done 包含该阶段的进度信息。 + + + + + index validation: sorting tuples CREATE INDEX CONCURRENTLY正在对索引扫描阶段的输出进行排序。 - 索引验证:扫描表 + index validation: scanning table CREATE INDEX CONCURRENTLY正在扫描表,以验证前两个阶段收集的索引元组。如果不是并发模式,则会跳过此阶段。blocks_total 列(设为表总大小)和 blocks_done 列包含该阶段的进度信息。 - 等待旧照 + waiting for old snapshots CREATE INDEX CONCURRENTLYREINDEX CONCURRENTLY正在等待可能看到表的事务释放快照。 当不处于并发模式时,这个阶段会被跳过。 lockers_totallockers_donecurrent_locker_pid 列包含了这个阶段的进度信息。 - 标记 dead之前等待readers + waiting for readers before marking dead REINDEX CONCURRENTLY等待表上有读锁的事务完成后,再将旧索引标记为死索引。当不在并发模式时,这个阶段被跳过。lockers_totallockers_donecurrent_locker_pid 列包含了这个阶段的进度信息。 - 在 dropping之前等待readers + waiting for readers before dropping REINDEX CONCURRENTLY等待表上有读锁的事务完成后,再丢弃旧索引。当不在并发模式时,这个阶段被跳过。列 lockers_totallockers_donecurrent_locker_pid包含了这个阶段的进度信息。 @@ -6157,7 +6390,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, repack_index_relid oid - 如果正使用索引扫描表,这里就是所用索引的 OID;否则为零。 + 如果正在使用索引对表进行扫描,这就是正在使用的索引的OID;否则为0。 @@ -6204,7 +6437,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, heap_blks_totalbigint - 表中的堆块总数。 这个数字是在seq scanning heap的开始时报告的。 + 表中的堆块总数。 这个数字以seq scanning heap开始时的数量为准。 @@ -6222,7 +6455,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, index_rebuild_countbigint - 已重建的索引数。该计数器仅在重建索引阶段时才会递增。 + 已重建的索引数。该计数器仅在rebuilding index阶段时才会递增。 @@ -6250,8 +6483,8 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, seq scanning heap - 命令正在使用顺序扫描扫描表。 - + 该命令目前采用顺序扫描的方式对表进行扫描。 + index scanning heap @@ -6280,14 +6513,14 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, swapping relation files - 命令正在把新构建的文件交换到位。 - + 目前,该命令正在将新建立的文件调换到位。 + rebuilding index - 命令正在重建一个索引。 - + 该命令目前正在重建一个索引。 + performing final cleanup @@ -6362,388 +6595,170 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, relid oid - 被vacuum的表的OID。 - - - - - - phase text - - - vacuum的当前处理阶段。参见 。 - - - - - - heap_blks_total bigint - - - 该表中堆块的总数。这个数字在扫描开始时报告,之后增加的块将不会(并且不需要)被这个VACUUM访问。 - - - - - - heap_blks_scanned bigint - - - 被扫描的堆块数量。由于visibility map被用来优化扫描,一些块将被跳过而不做检查, - 被跳过的块会被包括在这个总数中,因此当清理完成时这个数字最终将会等于heap_blks_total。 - 仅当处于扫描堆阶段时这个计数器才会前进。 - - - - - - heap_blks_vacuumed bigint - - - 被清理的堆块数量。除非表没有索引,这个计数器仅在处于清理堆阶段时才会前进。 - 不包含死亡元组的块会被跳过,因此这个计数器可能有时会向前跳跃一个比较大的增量。 - - - - - - index_vacuum_count bigint - - - 已完成的索引清理周期数。 - - - - - - max_dead_tuple_bytes bigint - - - 在需要执行索引清理周期之前可存储的死亡元组数据量,取决于。 - - - - - - dead_tuple_bytes bigint - - - 自上一个索引清理周期以来收集到的死亡元组数据量。 - - - - - - num_dead_item_ids bigint - - - 自上一个索引清理周期以来收集到的死项标识符数量。 - - - - - - indexes_total bigint - - - 将要执行 vacuum 或清理的索引总数。该数字会在 vacuuming indexescleaning up indexes 阶段开始时报告。 - - - - - - indexes_processed bigint - - - 已处理的索引数量。该计数器只会在 vacuuming indexescleaning up indexes 阶段推进。 - - - - - - delay_time double precision - - - 因基于成本的延迟而睡眠的总时间(参见),以毫秒计(如果启用了 ,否则为零)。这包括任何相关并行工作进程的睡眠时间;不过,并行工作进程最多每秒才会上报一次自己的睡眠时间,因此该值可能略有滞后。 - - - - mode text - - - 当前 VACUUM 操作所处的模式。有关每种模式的详细信息请参见 。可能的值有: - - - - normal:执行标准清理,既不需要以 激进模式运行,也不处于 失效保护模式。 - - - - - aggressive:执行 激进清理,必须扫描所有未标记为 全部冻结的页面。 决定何时需要 激进清理。 - - - - - failsafe:清理 已进入 失效保护模式,只执行避免事务 ID 或 多事务 ID 回卷失败所需的最少工作。 决定何时进入 失效保护模式。清理 可能一开始就处于该模式,或者运行过程中切换到该模式;mode 列的值在操作期间可能从其他模式变为 failsafe。 - - - - - - - - - started_by text - - - 说明当前 VACUUM 操作是由什么触发的。可能的值有: - - - - manual:由显式的 VACUUM 命令启动。 - - - - - autovacuum:由自动清理工作进程启动。自动清理工作进程执行的清理 可能会因锁冲突而被中断。 - - - - - autovacuum_wraparound:由自动清理工作进程为防止事务 ID 或 多事务 ID 回卷而启动。用于回卷保护的清理 不会因锁冲突而中断。 - - - - - - - - - -
- - - - VACUUM的阶段 - - - - - - - 阶段 - 描述 - - - - - - - 初始化 - - VACUUM正在准备开始扫描堆。这个阶段应该很简短。 - - - - - 扫描堆 - - VACUUM正在扫描堆。如果需要,它将会对每个页面进行修建以及碎片整理,并且可能会执行冻结动作。heap_blks_scanned列可以用来监控扫描的进度。 - - - - - 清理索引 - - VACUUM当前正在清理索引。 - 如果一个表拥有索引,那么每次清理时这个阶段会在堆扫描完成后至少发生一次。 - 如果不足以存放找到的死亡元组(或者, 在autovacuum情况下,如果设置了) ,则每次清理时会多次清理索引。 - - - - - 清理堆 - - VACUUM当前正在清理堆。清理堆与扫描堆不是同一个概念,清理堆发生在每一次清理索引的实例之后。如果heap_blks_scanned小于heap_blks_total,系统将在这个阶段完成之后回去扫描堆;否则,系统将在这个阶段完成后开始清理索引。 - - - - - 清除索引 - - VACUUM当前正在清除索引。这个阶段发生在堆被完全扫描并且对堆和索引的所有清理都已经完成以后。 - - - - - 截断堆 - - VACUUM正在截断堆,以便把关系尾部的空页面返还给操作系统。这个阶段发生在清除完索引之后。 - - - - - 执行最终清理 - - VACUUM正在执行最终清理。在此阶段,VACUUM将清理空闲空间映射, - 更新pg_class中的统计信息,并向累积统计系统报告统计信息。当此阶段完成时, - VACUUM将结束。 - - - - -
- -
- - - - CLUSTER 进度报告 - - - pg_stat_progress_cluster - - - - 每当REPACKCLUSTERVACUUM FULL运行时,为向后兼容而保留的pg_stat_progress_cluster视图将为每个当前正在运行这些命令之一的后端包含一行。下面的表格描述了将被报告的信息,并提供了关于如何解释这些信息的信息。 - - - - - <structname>pg_stat_progress_cluster</structname> 视图 - - - - - - 列类型 - - - 描述 + 正在清理的表的OID。 - - - - pid integer + phase text - 后端的进程ID。 + 清理的当前处理阶段。参见 - datid oid + heap_blks_total bigint - 后端连接到的数据库的OID。 + 该表中堆块的总数。这个数字以扫描开始时的数量为准,之后增加的块将不会(并且不需要)被这个VACUUM访问。 - datname name + heap_blks_scanned bigint - 后端连接到的数据库的名称。 + 被扫描的堆块数量。由于可见性映射被用来优化扫描,一些块将被跳过而不做检查, + 被跳过的块会被包括在这个总数中,因此当清理完成时这个数字最终将会等于heap_blks_total。 + 仅当处于scanning heap阶段时这个计数器才会前进。 - relid oid + heap_blks_vacuumed bigint - 被集群的表的OID。 + 被清理的堆块数量。除非表没有索引,这个计数器仅在处于vacuuming heap阶段时才会前进。 + 不包含死亡元组的块会被跳过,因此这个计数器可能有时会向前跳跃一个比较大的增量。 - command text + index_vacuum_count bigint - 正在运行的命令。CLUSTERVACUUM FULL。由于此视图仅为向后兼容而存在,它会将任何REPACK命令映射为这两种命令之一。 + 已完成的索引清理周期数。 - phase text + max_dead_tuple_bytes bigint - 当前处理阶段。参见。 + 在需要执行索引清理周期之前可存储的死亡元组数据量,取决于 - cluster_index_relid oid + dead_tuple_bytes bigint - 如果正在使用索引对表进行扫描,这就是正在使用的索引的OID;否则为0。 + 自上一个索引清理周期以来收集到的死亡元组数据量。 - heap_tuples_scanned bigint + num_dead_item_ids bigint - 扫描的堆元组数。 - 该计数器仅在阶段为seq scanning heapindex scanning heap - 或 writing new heap 时才会递增。 + 自上一个索引清理周期以来收集到的死项标识符数量。 - heap_tuples_written bigint + indexes_total bigint - 写入的堆元组的数量。这个计数器只有在阶段为seq scanning heap,index scanning heap - 或 writing new heap时才会前进。 + 将要执行清理或收尾清理的索引总数。该数字会在 vacuuming indexescleaning up indexes 阶段开始时报告。 - heap_blks_total bigint + indexes_processed bigint - 表中的堆块总数。 这个数字是在seq scanning heap的开始时报告的。 + 已处理的索引数量。该计数器只会在 vacuuming indexescleaning up indexes 阶段推进。 - heap_blks_scanned bigint + delay_time double precision - 扫描的堆块数量。该计数器仅在阶段为seq scanning heap时才会递增。 + 因基于代价的延迟而睡眠的总时间(参见),以毫秒计(如果启用了 ,否则为零)。这包括任何相关并行工作进程的睡眠时间;不过,并行工作进程最多每秒才会上报一次自己的睡眠时间,因此该值可能略有滞后。 + + + + mode text + + + 当前 VACUUM 操作所处的模式。有关每种模式的详细信息请参见 。可能的值有: + + + + normal:执行标准清理,既不需要以激进模式运行,也不处于失效保护模式。 + + + + + aggressive:执行激进清理,必须扫描所有未标记为全部冻结的页面。 决定何时需要激进清理。 + + + + + failsafe:清理已进入失效保护模式,只执行避免事务 ID 或多事务 ID 回卷失败所需的最少工作。 决定何时进入失效保护模式。清理可能一开始就处于该模式,或者运行过程中切换到该模式;mode 列的值在操作期间可能从其他模式变为 failsafe。 + + + - index_rebuild_count bigint + started_by text - 已重建的索引数。该计数器仅在重建索引阶段时才会递增。 + 说明当前 VACUUM 操作是由什么触发的。可能的值有: + + + + manual:由显式的 VACUUM 命令启动。 + + + + + autovacuum:由自动清理工作进程启动。自动清理工作进程执行的清理可能会因锁冲突而被中断。 + + + + + autovacuum_wraparound:由自动清理工作进程为防止事务 ID 或多事务 ID 回卷而启动。用于回卷保护的清理不会因锁冲突而中断。 + + + + +
- +
- CLUSTER 和 VACUUM FULL 阶段 + VACUUM 阶段 @@ -6758,66 +6773,58 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - 初始化 - - 该命令准备开始扫描堆栈。 这个阶段预计会非常短暂。 - - - - - seq扫描堆 + initializing - 该命令目前采用顺序扫描的方式对表进行扫描。 + VACUUM正在准备开始扫描堆。这个阶段应该很简短。 - 索引扫描堆 + scanning heap - CLUSTER目前正在使用索引扫描表。 + VACUUM正在扫描堆。如果需要,它将会对每个页面进行剪枝以及碎片整理,并且可能会执行冻结动作。heap_blks_scanned列可以用来监控扫描的进度。 - 元组排序 - - CLUSTER目前正在对元组进行排序。 - + vacuuming indexes + VACUUM当前正在清理索引。如果表有索引,每次清理都会在堆扫描完成后至少执行一次此阶段。如果(或者,对于自动清理,已设置的)不足以存储找到的死亡元组数量,则每次清理可能多次执行此阶段。 - 新写入堆 + vacuuming heap - CLUSTER目前正在编写新的堆。 + VACUUM当前正在清理堆。清理堆与扫描堆不是同一个概念,清理堆发生在每次索引清理之后。如果heap_blks_scanned小于heap_blks_total,系统将在这个阶段完成之后回去扫描堆;否则,系统将在这个阶段完成后开始索引收尾清理。 - 交换关系文件 + cleaning up indexes - 目前,该命令正在将新建立的文件调换到位。 + VACUUM当前正在进行索引收尾清理。这个阶段发生在堆被完全扫描并且对堆和索引的所有清理都已经完成以后。 - 重建索引 + truncating heap - 该命令目前正在重建一个索引。 + VACUUM正在截断堆,以便把关系尾部的空页面返还给操作系统。这个阶段发生在索引收尾清理完成之后。 - 清理 + performing final cleanup - 该命令正在执行最后的清理工作。 当此阶段完成后,CLUSTERVACUUM FULL将结束。 + VACUUM正在执行最终清理。在此阶段,VACUUM将清理空闲空间映射, + 更新pg_class中的统计信息,并向累积统计系统报告统计信息。当此阶段完成时, + VACUUM将结束。
-
- + 基础备份进度报告 @@ -6875,7 +6882,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, 将被流式传输的数据总量。该值在streaming database files阶段开始时进行估算并报告。 注意,这只是一个近似值,因为数据库可能会在streaming database files阶段期间发生变化,而 WAL 日志也可能在稍后的备份阶段被包含进来。 一旦流式传输的数据量超过了估计的总大小,该值始终与backup_streamed相同。 - 如果在pg_basebackup中禁用估算(也就是说,指定了--no-estimate-size选项),这为NULL。 + 如果在pg_basebackup中禁用估算(也就是说,指定了--no-estimate-size选项),这为NULL。 @@ -6941,7 +6948,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - 等待检查点完成 + waiting for checkpoint to finish WAL 发送进程当前正在执行pg_backup_start以准备进行基础备份,并等待备份起始检查点完成。 @@ -6962,7 +6969,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - 等待wal归档完成 + waiting for wal archiving to finish WAL发送进程当前正在执行pg_backup_stop以完成备份, 并等待基础备份所需的所有 WAL 文件成功归档。 @@ -6983,7 +6990,11 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - + + + + + 数据校验和进度报告 @@ -7062,7 +7073,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, databases_total bigint - 将要处理的数据库总数。只有在启用数据校验和时,启动器进程才会设置这个值; + 将要处理的数据库总数。启用数据校验和时,只有启动器进程的这个值会被设置; 否则该值为 NULL @@ -7074,7 +7085,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, databases_done bigint - 已处理的数据库数量。只有在启用数据校验和时,启动器进程才会设置这个值; + 已处理的数据库数量。启用数据校验和时,只有启动器进程的这个值会被设置; 否则该值为 NULL @@ -7174,143 +7185,6 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - - - - - COPY 进度报告 - - - pg_stat_progress_copy - - - - 当COPY正在运行时,pg_stat_progress_copy视图会为每个当前正在执行COPY命令的后端包含一行。下表描述了会报告哪些信息,以及应如何解释这些信息。 - - - - - <structname>pg_stat_progress_copy</structname> 视图 - - - - - - 列类型 - - - 描述 - - - - - - - - - pid integer - - - 后端的进程ID。 - - - - - - datid oid - - - 后端连接到的数据库的OID。 - - - - - - datname name - - - 后端连接到的数据库的名称。 - - - - - - relid oid - - - 执行COPY命令的表的OID。 - 如果从SELECT查询中复制,它被设置为0。 - - - - - - command text - - - 正在运行的命令: COPY FROM, 或 COPY TO。 - - - - - - type text - - - 数据被读取或写入的io类型:FILE, PROGRAM, PIPE (对于COPY FROM STDINCOPY TO STDOUT),或 CALLBACK(例如在逻辑复制中初始表同步期间使用)。 - - - - - - bytes_processed bigint - - - 已经被COPY命令处理的字节数。 - - - - - - bytes_total bigint - - - COPY FROM命令的源文件大小,以字节计。 - 如果不可用则设置为0。 - - - - - - tuples_processed bigint - - - 已经被COPY命令处理的元组数。 - - - - - - tuples_excluded bigint - - - 没有处理的元组数,因为它们被COPY命令的WHERE子句所排除。 - - - - - - tuples_skipped bigint - - - 因包含格式错误的数据而被跳过的元组数。只有当 ON_ERROR 指定为 ignore 时,此计数器才会递增。 - - - - -
-
- @@ -7336,7 +7210,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, - 动态追踪的编译 + 为动态追踪编译 默认情况下,探针是不可用的,因此你将需要显式地告诉配置脚本让探针在PostgreSQL中可用。要包括 DTrace 支持,在配置时指定。更多信息请见。 @@ -7348,7 +7222,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, 内置探针 - 如所示,源代码中提供了一些标准探针。显式了在探针中使用的类型。当然,可以增加更多探针来增强PostgreSQL的可观测性。 + 如所示,源代码中提供了一些标准探针。显示了在探针中使用的类型。当然,可以增加更多探针来增强PostgreSQL的可观测性。 @@ -7384,13 +7258,13 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, transaction-abort (LocalTransactionId) - 当一个事务失败完成时触发的探针。arg0 是事务 ID。 + 当一个事务失败结束时触发的探针。arg0 是事务 ID。 query-start (const char *) - 当一个查询的处理被开始时触发的探针。arg0 是查询字符串。 + 当一个查询的处理开始时触发的探针。arg0 是查询字符串。 @@ -7402,7 +7276,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, query-parse-start (const char *) - 当一个查询的解析被开始时触发的探针。arg0 是查询字符串。 + 当一个查询的解析开始时触发的探针。arg0 是查询字符串。 @@ -7414,7 +7288,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, query-rewrite-start (const char *) - 当一个查询的重写被开始时触发的探针。arg0 是查询字符串。 + 当一个查询的重写开始时触发的探针。arg0 是查询字符串。 @@ -7426,7 +7300,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, query-plan-start () - 当一个查询的规划被开始时触发的探针。 + 当一个查询的规划开始时触发的探针。 @@ -7438,7 +7312,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, query-execute-start () - 当一个查询的执行被开始时触发的探针。 + 当一个查询的执行开始时触发的探针。 @@ -7456,19 +7330,19 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, checkpoint-start (int) - 当一个检查点被开始时触发的探针。arg0 传递位标志来区分不同的检查点类型,例如关闭(shutdown)、立即(immediate)或强制(force)。 + 当一个检查点开始时触发的探针。arg0 传递位标志来区分不同的检查点类型,例如关闭(shutdown)、立即(immediate)或强制(force)。 checkpoint-done (int, int, int, int, int) - 当一个检查点完成时触发的探针(检查点处理过程中序列中列出的下一个触发的探针)。arg0 是要写的缓冲区数量。arg1 是缓冲区的总数。arg2、arg3 和 arg4 分别包含了增加、删除和循环回收的 WAL 文件的数量。 + 当一个检查点完成时触发的探针(下面列出的探针会在检查点处理过程中依次触发)。arg0 是已写入的缓冲区数量。arg1 是缓冲区的总数。arg2、arg3 和 arg4 分别包含了增加、删除和循环回收的 WAL 文件的数量。 clog-checkpoint-start (bool) - 当一个检查点的 CLOG 部分被开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 + 当一个检查点的 CLOG 部分开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 @@ -7480,7 +7354,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, subtrans-checkpoint-start (bool) - 当一个检查点的 SUBTRANS 部分被开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 + 当一个检查点的 SUBTRANS 部分开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 @@ -7492,7 +7366,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, multixact-checkpoint-start (bool) - 当一个检查点的 MultiXact 部分被开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 + 当一个检查点的 MultiXact 部分开始时触发的探针。arg0 为真表示正常检查点,为假表示关闭检查点。 @@ -7504,7 +7378,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, buffer-checkpoint-start (int) - 当一个检查点的写缓冲区部分被开始时触发的探针。arg0 传递位标志来区分不同的检查点类型,例如关闭(shutdown)、立即(immediate)或强制(force)。 + 当一个检查点的写缓冲区部分开始时触发的探针。arg0 传递位标志来区分不同的检查点类型,例如关闭(shutdown)、立即(immediate)或强制(force)。 @@ -7540,7 +7414,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, twophase-checkpoint-start () - 当一个检查点的两阶段部分被开始时触发的探针。 + 当一个检查点的两阶段部分开始时触发的探针。 @@ -7549,22 +7423,54 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, 当一个检查点的两阶段部分完成时触发的探针。 + + buffer-extend-start + (ForkNumber, BlockNumber, Oid, Oid, Oid, int, unsigned int) + 当关系扩展开始时触发的探针。 + arg0 包含要扩展的分支。arg1、arg2 和 arg3 包含用于标识该关系的 + 表空间、数据库和关系 OID。对于本地缓冲区,arg4 是创建临时关系的后端 ID; + 对于共享缓冲区,则为 INVALID_PROC_NUMBER(-1)。 + arg5 是调用者希望扩展的块数。 + + + + buffer-extend-done + (ForkNumber, BlockNumber, Oid, Oid, Oid, int, unsigned int, BlockNumber) + 当关系扩展完成时触发的探针。 + arg0 包含要扩展的分支。arg1、arg2 和 arg3 包含用于标识该关系的 + 表空间、数据库和关系 OID。对于本地缓冲区,arg4 是创建临时关系的后端 ID; + 对于共享缓冲区,则为 INVALID_PROC_NUMBER(-1)。 + arg5 是关系实际扩展的块数;由于资源限制,该值可能小于 + buffer-extend-start中的数量。arg6 包含第一个新块的 + BlockNumber。 + + buffer-read-start - (ForkNumber, BlockNumber, Oid, Oid, Oid, int, bool) - 当一次缓冲区读被开始时触发的探针。arg0 和 arg1 包含该页的分叉号和块号(如果这是一次关系扩展请求,arg1 为 -1)。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是 InvalidBackendId(-1)。arg6 为真表示一次关系扩展请求,为假表示正常读。 + (ForkNumber, BlockNumber, Oid, Oid, Oid, int) + 当缓冲区读取开始时触发的探针。 + arg0 和 arg1 包含该页的分支号和块号。 + arg2、arg3 和 arg4 包含用于标识该关系的表空间、数据库和关系 OID。 + 对于本地缓冲区,arg5 是创建临时关系的后端 ID;对于共享缓冲区, + 则为 INVALID_PROC_NUMBER(-1)。 + buffer-read-done - (ForkNumber, BlockNumber, Oid, Oid, Oid, int, bool, bool) - 当一次缓冲区读完成时触发的探针。arg0 和 arg1 包含该页的分叉号和块号(如果这是一次关系扩展请求,arg1 现在包含新增加块的块号)。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是 InvalidBackendId(-1)。arg6 为真表示一次关系扩展请求,为假表示正常读。arg7 为真表示在池中找到该缓冲区,为假表示没有找到。 + (ForkNumber, BlockNumber, Oid, Oid, Oid, int, bool) + 当缓冲区读取完成时触发的探针。 + arg0 和 arg1 包含该页的分支号和块号。 + arg2、arg3 和 arg4 包含用于标识该关系的表空间、数据库和关系 OID。 + 对于本地缓冲区,arg5 是创建临时关系的后端 ID;对于共享缓冲区, + 则为 INVALID_PROC_NUMBER(-1)。 + 如果在缓冲池中找到了该缓冲区,arg6 为真;否则为假。 buffer-flush-start (ForkNumber, BlockNumber, Oid, Oid, Oid) - 在发出对一个共享缓冲区的任意写请求之前触发的探针。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。 + 在发出对一个共享缓冲区的任意写请求之前触发的探针。arg0 和 arg1 包含该页的分支号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。 @@ -7573,17 +7479,9 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, 当一个写请求完成时触发的探针(注意这只反映传递数据给内核的时间,它通常并没有实际地被写入到磁盘)。参数和buffer-flush-start的相同。 - - buffer-write-dirty-start - (ForkNumber, BlockNumber, Oid, Oid, Oid) - 当一个服务器进程开始写一个脏缓冲区时触发的探针(如果这经常发生,表示太小,或需要调整后台写入器的控制参数)。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。 - - - buffer-write-dirty-done - (ForkNumber, BlockNumber, Oid, Oid, Oid) - 当一次脏缓冲区写完成时触发的探针。参数与buffer-write-dirty-start相同。 - + + wal-buffer-write-dirty-start @@ -7594,13 +7492,13 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, wal-buffer-write-dirty-done () - 当一次脏 WAL 缓冲区完成时触发的探针。 + 当一次脏 WAL 缓冲区写入完成时触发的探针。 wal-insert (unsigned char, unsigned char) - 当一个 WAL 记录被插入时触发的探针。arg0 是该记录的资源管理者(rmid)。arg1 包含 info 标志。 + 当一个 WAL 记录被插入时触发的探针。arg0 是该记录的资源管理器(rmid)。arg1 包含 info 标志。 @@ -7612,31 +7510,31 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, smgr-md-read-start (ForkNumber, BlockNumber, Oid, Oid, Oid, int) - 当开始从一个关系读取一块时触发的探针。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。 + 当开始从一个关系读取一块时触发的探针。arg0 和 arg1 包含该页的分支号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是INVALID_PROC_NUMBER(-1)。 smgr-md-read-done (ForkNumber, BlockNumber, Oid, Oid, Oid, int, ssize_t, size_t) - 当一次块读取完成时触发的探针。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。arg6 是实际读取的字节数,而 arg7 是请求读取的字节数(如果两者不同就意味着麻烦)。 + 当一次块读取完成时触发的探针。arg0 和 arg1 包含该页的分支号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是INVALID_PROC_NUMBER(-1)。arg6 是实际读取的字节数,而 arg7 是请求读取的字节数(如果两者不同,则表示发生了短读)。 smgr-md-write-start (ForkNumber, BlockNumber, Oid, Oid, Oid, int) - 当开始向一个关系中写入一个块时触发的探针。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。 + 当开始向一个关系中写入一个块时触发的探针。arg0 和 arg1 包含该页的分支号和块号。arg2、arg3 和 arg4 包含表空间、数据库和关系 OID 用以识别该关系。对一个本地缓冲区,arg5 是创建临时关系的后端的 ID;对于一个共享缓冲区,arg5 是INVALID_PROC_NUMBER(-1)。 smgr-md-write-done (ForkNumber, BlockNumber, Oid, Oid, Oid, int, ssize_t, size_t) - 当一个块写操作完成时触发的探针。arg0 和 arg1 包含该页的分叉号和块号。arg2、arg3和arg4 包含表空间、数据库和关系 OID来标识该关系。对于一个本地缓冲区,arg5 是创建临时关系的后端 ID;对于一个共享缓冲区,arg5 是InvalidBackendId(-1)。arg6 是实际写的字节数,而 arg7 是要求写的字节数(如果这两者不同,则意味着麻烦)。 + 当一个块写操作完成时触发的探针。arg0 和 arg1 包含该页的分支号和块号。arg2、arg3和arg4 包含表空间、数据库和关系 OID来标识该关系。对于一个本地缓冲区,arg5 是创建临时关系的后端 ID;对于一个共享缓冲区,arg5 是INVALID_PROC_NUMBER(-1)。arg6 是实际写的字节数,而 arg7 是要求写的字节数(如果这两者不同,则表示发生了短写)。 sort-start (int, bool, int, int, bool, int) - 当一次排序操作开始时触发的探针。arg0 指示是堆排序、索引排序或数据排序。arg1 为真表示强制唯一值。arg2 是键列数。arg3 是允许使用的工作内存大小(以千字节计)。如果要求随机访问排序结果,则 arg4 为真。arg5 为 0 时表示串行,为 1 时表示并行工作进程,为 2 时表示并行领导者。 + 当一次排序操作开始时触发的探针。arg0 指示是堆排序、索引排序或 datum 排序。arg1 为真表示强制唯一值。arg2 是键列数。arg3 是允许使用的工作内存大小(以千字节计)。如果要求随机访问排序结果,则 arg4 为真。arg5 为 0 时表示串行,为 1 时表示并行工作进程,为 2 时表示并行领导者。 @@ -7650,7 +7548,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, (char *, LWLockMode) 当成功获得一个 LWLock 时触发的探针。 arg0 是该 LWLock 所在的切片(Tranche)。 - arg1 所请求的锁模式,是排他或共享。 + arg1 是所请求的锁模式,是排他或共享。 @@ -7665,34 +7563,34 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, (char *, LWLockMode) 当一个 LWLock不是当即可用并且一个服务器进程因此开始等待该锁变为可用时触发的探针。 arg0 是该 LWLock 所在的切片(Tranche)。 - arg1 请求的锁模式,是排他或共享。 + arg1 是所请求的锁模式,是排他或共享。 lwlock-wait-done (char *, LWLockMode) 当一个进程从对一个 LWLock 的等待中被释放时(它实际还没有得到该锁)时触发的探针。arg0 是该 LWLock 所在的切片(Tranche)。 - arg1 所请求的锁模式,是排他或共享。 + arg1 是所请求的锁模式,是排他或共享。 lwlock-condacquire (char *, LWLockMode) 当调用者指定无需等待而成功获得一个 LWLock 时触发的探针。arg0 是该 LWLock 所在的切片(Tranche)。 - arg1 所请求的锁模式,是排他或共享。 + arg1 是所请求的锁模式,是排他或共享。 lwlock-condacquire-fail (char *, LWLockMode) 当调用者指定无需等待而没有成功获得一个 LWLock 时触发的探针。arg0 是该 LWLock 所在的切片(Tranche)。 - arg1 所请求的锁模式,是排他或共享。 + arg1 是所请求的锁模式,是排他或共享。 lock-wait-start (unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, LOCKMODE) - 当一个重量级锁(lmgr锁)的请求由于锁不可用开始等待时触发的探针。arg0 到 arg3 是标识被锁定对象的标签域。arg4 指示被锁对象的类型。arg5 表示被请求的锁类型。 + 当一个重量级锁(lmgr锁)的请求由于锁不可用开始等待时触发的探针。arg0 到 arg3 是标识被锁定对象的标签字段。arg4 指示被锁对象的类型。arg5 表示被请求的锁类型。 @@ -7713,7 +7611,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid,
- 定义用在探针参数中的类型 + 探针参数中使用的已定义类型 @@ -7807,7 +7705,7 @@ Total time (ns) 2312105013 - 你应该记住,DTrace 脚本需要细心地编写和调试,否则被收集的追踪信息可能会毫无意义。在大部分发现问题的情况中,它就是发生问题的部件,而不是底层系统。当讨论使用动态追踪发现的信息时,一定要附上使用的脚本以便其也被检查和讨论。 + 你应该记住,DTrace 脚本需要细心地编写和调试,否则被收集的追踪信息可能会毫无意义。在大多数发现问题的情况下,出错的是插桩,而不是底层系统。当讨论使用动态追踪发现的信息时,一定要附上使用的脚本以便其也被检查和讨论。 @@ -7823,7 +7721,7 @@ Total time (ns) 2312105013 - 决定探针名称以及探针可用的数据 + 决定探针名称以及要通过探针提供的数据 @@ -7837,7 +7735,7 @@ Total time (ns) 2312105013 - 如果pg_trace.h还不存在于包含该探针点的模块中,包括它,并且在源代码中期望的位置插入TRACE_POSTGRESQL探针宏 + 如果pg_trace.h尚未被包含该探针点的模块引用,则将它包含进来,并且在源代码中期望的位置插入TRACE_POSTGRESQL探针宏 @@ -7873,14 +7771,14 @@ Total time (ns) 2312105013 probe transaction__start(LocalTransactionId); - 注意探针名字中双下划线的使用。在一个使用探针的 DTrace 脚本中,双下划线需要被替换为一个连字符,因此 ,对用户而言transaction-start是文档名。 + 注意探针名字中双下划线的使用。在一个使用探针的 DTrace 脚本中,双下划线需要被替换为一个连字符,因此,文档中应向用户说明的名称是transaction-start - 在编译时,transaction__start被转换成一个宏调用TRACE_POSTGRESQL_TRANSACTION_START(注意这里是单下划线),可以通过包括头文件pg_trace.h获得。将宏调用加入到源代码中的合适位置。在这种情况下,看起来类似: + 在编译时,transaction__start被转换成一个名为TRACE_POSTGRESQL_TRANSACTION_START的宏(注意这里是单下划线),可以通过包含头文件pg_trace.h获得。将宏调用加入到源代码中的合适位置。在这种情况下,看起来类似: TRACE_POSTGRESQL_TRANSACTION_START(vxid.localTransactionId); @@ -7917,7 +7815,7 @@ TRACE_POSTGRESQL_TRANSACTION_START(vxid.localTransactionId); - 在大多数平台上,如果用编译了PostgreSQL,无论何时当控制经过一个追踪宏时,都会评估该宏的参数,即使没有进行追踪也会这样做。通常不需要担心你是否只在报告一些局部变量的值。但是要注意不要将开销大的函数调用放入参数中。如果你需要这样做,考虑通过检查追踪是否真的被启用来保护该宏: + 在大多数平台上,如果用编译了PostgreSQL,无论何时当控制经过一个追踪宏时,都会对该宏的参数求值,即使没有进行追踪也会这样做。如果只是报告少数局部变量的值,通常无需担心这一点。但是要注意不要将开销大的函数调用放入参数中。如果你需要这样做,考虑通过检查追踪是否真的被启用来保护该宏: if (TRACE_POSTGRESQL_TRANSACTION_START_ENABLED()) @@ -7958,7 +7856,7 @@ if (TRACE_POSTGRESQL_TRANSACTION_START_ENABLED()) - 在最近执行过 VACUUMANALYZE 的数据库上使用 psql,你可以发出查询来查看任意表的磁盘使用情况: + 在最近进行过清理或分析 的数据库上使用 psql,你可以发出查询来查看任意表的磁盘使用情况: SELECT pg_relation_filepath(oid), relpages FROM pg_class WHERE relname = 'customer'; diff --git a/zh/20/mvcc.sgml b/zh/20/mvcc.sgml index 1fbd5a13..af144998 100644 --- a/zh/20/mvcc.sgml +++ b/zh/20/mvcc.sgml @@ -4,7 +4,7 @@ 并发控制 - concurrency + 并发 @@ -15,7 +15,7 @@ 介绍 - Multiversion Concurrency Control + 多版本并发控制 @@ -23,7 +23,7 @@ - Serializable Snapshot Isolation + 可串行化快照隔离 @@ -50,7 +50,7 @@ 事务隔离 - transaction isolation + 事务隔离 @@ -68,7 +68,7 @@ 脏读 - dirty read + 脏读 @@ -80,7 +80,7 @@ 不可重复读 - nonrepeatable read + 不可重复读 @@ -92,7 +92,7 @@ 幻读 - phantom read + 幻读 @@ -104,7 +104,7 @@ 串行化异常 - serialization anomaly + 串行化异常 @@ -117,7 +117,7 @@ - transaction isolation level + 事务隔离级别 SQL 标准以及 PostgreSQL 实现的事务隔离级别见 @@ -244,12 +244,12 @@ 读已提交隔离级别 - transaction isolation level - read committed + 事务隔离级别 + 读已提交 - read committed + 读已提交 @@ -341,7 +341,7 @@ COMMIT; 在读已提交模式下,更复杂的用法可能产生不理想的结果。例如,考虑一个 - DELETE 命令,它所处理的数据会被另一个命令同时加入和移出其筛选条件。 + DELETE 命令,另一个命令正在修改数据,使某些行开始满足其筛选条件、另一些行不再满足。 假设 website 是一个有两行的表,其中 website.hits 分别等于 910: @@ -349,7 +349,7 @@ COMMIT; BEGIN; UPDATE website SET hits = hits + 1; --- run from another session: DELETE FROM website WHERE hits = 10; +-- 从另一个会话运行: DELETE FROM website WHERE hits = 10; COMMIT; @@ -377,12 +377,12 @@ COMMIT; 可重复读隔离级别 - transaction isolation level - repeatable read + 事务隔离级别 + 可重复读 - repeatable read + 可重复读 @@ -435,9 +435,7 @@ ERROR: could not serialize access due to concurrent update 可重复读模式提供了严格的保证,即每个事务都看到数据库的一个完全稳定的视图。 不过,这个视图并不一定总能与同一级别并发事务的某种串行(一次一个)执行保持一致。 - 例如,即使该级别上的只读事务可能看到一条控制记录被更新,表明某个批处理已经完成, - 但它并不一定能看到作为该批处理逻辑组成部分的某条明细记录, - 因为它读到的是控制记录的较早版本。如果不仔细使用显式锁来阻塞冲突事务, + 例如,即使是该级别的只读事务,也可能看到一条表明某批次已完成的控制记录,却看不到逻辑上属于该批次的某条明细记录,因为创建该明细记录的事务读取了控制记录的较早版本。如果不仔细使用显式锁来阻塞冲突事务, 试图依靠运行在这一隔离级别的事务来强制业务规则,往往无法正确工作。 @@ -445,7 +443,7 @@ ERROR: could not serialize access due to concurrent update 可重复读隔离级别是通过一种技术实现的,这种技术在学术数据库文献中以及某些其他数据库产品中被称为 快照隔离。与使用会降低并发性的传统加锁技术的系统相比, 其行为和性能可能会表现出差异。有些其他系统甚至把可重复读和快照隔离作为两个行为不同的独立隔离级别提供。 - 用来区分这两种技术的允许现象,直到 SQL 标准制定之后才被数据库研究人员正式定义,因此超出了本手册的范围。 + 用来区分这两种技术的允许现象,直到 SQL 标准制定之后才被数据库研究人员正式定义,并且超出了本手册的范围。 完整讨论请参阅 @@ -461,20 +459,20 @@ ERROR: could not serialize access due to concurrent update 可串行化隔离级别 - transaction isolation level - serializable + 事务隔离级别 + 可串行化 - serializable + 可串行化 - predicate locking + 谓词锁 - serialization anomaly + 串行化异常 @@ -487,48 +485,30 @@ ERROR: could not serialize access due to concurrent update 一旦检测到可能导致串行化异常的条件,就会触发串行化失败 - - 例如,考虑一张表 mytab,其初始内容为: - + 例如,考虑表mytab,它最初包含以下内容: class | value -------+------- 1 | 10 1 | 20 2 | 100 2 | 200 - - 假设可串行化事务 A 计算: - +假设可串行化事务 A 执行以下计算: SELECT SUM(value) FROM mytab WHERE class = 1; - - 然后将结果(30)作为一条新行的 value 插入,并把 - class 设为 2。与此同时,可串行化事务 B 计算: - +然后将结果(30)作为新行的value插入,且该行满足class = 2。与此同时,可串行化事务 B 执行以下计算: SELECT SUM(value) FROM mytab WHERE class = 2; - - 并得到结果 300,再把它插入为一条新行,其 - class1。然后两个事务都尝试提交。 - 如果任一事务是在可重复读隔离级别下运行,则二者都可以提交; - 但由于不存在与该结果一致的串行执行顺序,使用可串行化事务时将允许其中一个事务提交, - 并按如下消息回滚另一个事务: - - +得到结果 300,并将它插入一个新行,该行满足class = 1。然后两个事务都尝试提交。如果任一事务运行在可重复读隔离级别,两个事务都可以提交;但由于不存在与该结果一致的串行执行顺序,使用可串行化事务时,只会允许一个事务提交,另一个则会被回滚,并收到以下消息: ERROR: could not serialize access due to read/write dependencies among transactions - - - 这是因为,如果 A 先于 B 执行,B 算出的和将是 330 而不是 300; - 反过来,另一种顺序也会使 A 算出不同的和。 - +这是因为,如果 A 在 B 之前执行,B 算出的总和应该是 330,而不是 300;同样,按另一种顺序执行,A 算出的总和也会不同。 当依赖可串行化事务来防止异常时,重要的是:从永久用户表读取的任何数据,在读取它的事务成功提交之前, - 都不应视为有效。即使对于只读事务也是如此;唯一的例外是可推迟只读事务中读取的数据, + 都不应视为有效。即使对于只读事务也是如此;唯一的例外是可延迟只读事务中读取的数据, 它一经读出就可视为有效,因为这种事务会等到能够获取一个保证不存在此类问题的快照后才开始读取数据。 在所有其他情况下,应用不能依赖后来被中止事务中读到的结果;相反,应重试事务直到成功。 - 为了保证真正的可串行化,PostgreSQL 使用了谓词锁, + 为了保证真正的可串行性,PostgreSQL 使用了谓词锁, 也就是说,系统会保留一些锁,以便判断某个写操作如果先发生,是否会影响并发事务先前读取的结果。 在 PostgreSQL 中,这些锁不会造成任何阻塞,因此会参与形成死锁。 它们用于识别并标记并发可串行化事务之间的依赖关系,而这些依赖在某些组合下可能导致串行化异常。 @@ -550,7 +530,7 @@ ERROR: could not serialize access due to read/write dependencies among transact - 持续使用可串行化事务可以简化开发。任何一组成功提交的并发可串行化事务,都保证与把它们一次一个运行的效果相同;这意味着,如果你能够证明某个事务在单独运行时会做正确的事,那么即使不了解其他事务会做什么,也可以相信它在任何可串行化事务的混合执行中也会做正确的事,否则它就不会成功提交。重要的是,采用这种技术的环境应当有一套通用机制来处理串行化失败(其 SQLSTATE 值总是 40001),因为很难准确预测究竟哪些事务会对读/写依赖关系有贡献,并因此需要被回滚来防止串行化异常。监视读/写依赖关系会带来开销,被串行化失败中止的事务重新启动也会带来开销;但在把这些开销与显式锁以及 SELECT FOR UPDATESELECT FOR SHARE 所涉及的成本和阻塞进行权衡之后,可串行化事务在某些环境中仍然是性能最佳的选择。 + 统一采用可串行化事务可以简化开发。任何一组成功提交的并发可串行化事务,都保证与把它们一次一个运行的效果相同;这意味着,如果你能够证明某个事务在单独运行时会做正确的事,那么即使不了解其他事务会做什么,也可以相信它在任何可串行化事务的混合执行中也会做正确的事,否则它就不会成功提交。重要的是,采用这种技术的环境应当有一套通用机制来处理串行化失败(其 SQLSTATE 值总是 40001),因为很难准确预测究竟哪些事务会对读/写依赖关系有贡献,并因此需要被回滚来防止串行化异常。监视读/写依赖关系会带来开销,被串行化失败中止的事务重新启动也会带来开销;但在把这些开销与显式锁以及 SELECT FOR UPDATESELECT FOR SHARE 所涉及的成本和阻塞进行权衡之后,可串行化事务在某些环境中仍然是性能最佳的选择。 @@ -594,7 +574,7 @@ ERROR: could not serialize access due to read/write dependencies among transact - 当系统因谓词锁表内存不足而被迫把多个页级谓词锁合并为单个关系级谓词锁时,串行化失败的比例可能会上升。你可以通过增加 来避免这种情况。 + 当系统因谓词锁表内存不足而被迫把多个页级谓词锁合并为单个关系级谓词锁时,串行化失败的比例可能会上升。你可以通过增加 和/或 来避免这种情况。 @@ -618,7 +598,7 @@ ERROR: could not serialize access due to read/write dependencies among transact 显式锁定 - lock + @@ -722,7 +702,7 @@ ERROR: could not serialize access due to read/write dependencies among transact CREATE STATISTICSCOMMENT ONREINDEX CONCURRENTLY, 以及某些 ALTER INDEX - 和 ALTER TABLE 变体会获取这种锁 + 和 ALTER TABLE 变体获取这种锁 (有关详细信息,请参阅这些命令的文档)。 @@ -1008,7 +988,7 @@ ERROR: could not serialize access due to read/write dependencies among transact - 行为与 FOR SHARE 类似,不过锁更弱:SELECT FOR UPDATE 会被阻塞,但 SELECT FOR NO KEY UPDATE 不会。键共享锁会阻塞其他事务执行会修改键值的 DELETEUPDATE,但不会阻塞其他 UPDATE,也不会阻止 SELECT FOR NO KEY UPDATESELECT FOR SHARESELECT FOR KEY SHARE。 + 行为与 FOR SHARE 类似,不过锁更弱:SELECT FOR UPDATE 会被阻塞,但 SELECT FOR NO KEY UPDATE 不会。键共享锁会阻塞其他事务执行 DELETE 或任何会修改键值的 UPDATE,但不会阻塞其他 UPDATE,也不会阻止 SELECT FOR NO KEY UPDATESELECT FOR SHARESELECT FOR KEY SHARE @@ -1086,7 +1066,7 @@ ERROR: could not serialize access due to read/write dependencies among transact 死锁 - deadlock + 死锁 @@ -1129,12 +1109,12 @@ UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 22222; 咨询锁 - advisory lock + 咨询锁 - lock - advisory + + 咨询 @@ -1166,12 +1146,12 @@ UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 22222; 在某些使用咨询锁的方法中,特别是涉及显式排序和 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(id) FROM foo WHERE id = 12345; -- 可以 +SELECT pg_advisory_lock(id) FROM foo WHERE id > 12345 LIMIT 100; -- 危险! SELECT pg_advisory_lock(q.id) FROM ( SELECT id FROM foo WHERE id > 12345 LIMIT 100 -) q; -- ok +) q; -- 可以 在上面的查询中,第二种形式是危险的,因为不能保证在执行加锁函数之前先应用 LIMIT。 这可能导致获取了一些应用并未预期的锁,因此应用也不会去释放它们(直到会话结束)。 @@ -1189,12 +1169,12 @@ SELECT pg_advisory_lock(q.id) FROM 应用级别的数据一致性检查 - 在读已提交事务下,想要通过业务规则强制数据一致性非常困难,因为数据视图会随每条语句而变化, + 用读已提交事务强制执行有关数据完整性的业务规则非常困难,因为数据视图会随每条语句而变化, 而且一旦发生写冲突,即使是单条语句也未必局限于该语句自己的快照。 - 虽然可重复读事务在整个执行期间都具有稳定的数据视图,但在使用 MVCC 快照进行数据一致性检查时,还存在一个微妙问题,即所谓的读/写冲突。如果一个事务写入数据,而并发事务试图读取相同的数据(无论是在写入之前还是之后),它都看不到另一个事务的工作。于是,读取者看起来就像是先执行的一方,而不管究竟是谁先启动,也不管谁先提交。如果事情只停留在这一步,就没有问题;但如果读取者还写入了数据,而这些数据又被另一个并发事务读取,那么现在就会有一个事务看起来像是在前面提到的任一事务之前执行。如果看起来最后执行的事务实际上最先提交,就很容易在事务执行顺序图中形成一个环。一旦出现这样的环,不借助额外机制,一致性检查就无法正确工作。 + 虽然可重复读事务在整个执行期间都具有稳定的数据视图,但在使用 MVCC 快照进行数据一致性检查时,还存在一个微妙问题,即所谓的读/写冲突。如果一个事务写入数据,而并发事务试图读取相同的数据(无论是在写入之前还是之后),它都看不到另一个事务的工作。于是,读取者看起来就像是先执行的一方,而不管究竟是谁先启动,也不管谁先提交。如果事情只停留在这一步,就没有问题;但如果读取者还写入了数据,而这些数据又被另一个并发事务读取,那么现在就会有一个事务看起来像是在前面提到的任一事务之前执行。如果看起来最后执行的事务实际上最先提交,就很容易在事务执行顺序图中形成一个环。一旦出现这样的环,不借助额外机制,完整性检查就无法正确工作。 @@ -1211,7 +1191,7 @@ SELECT pg_advisory_lock(q.id) FROM - 使用这种技术时,如果应用软件通过某个框架运行,并由该框架自动重试因串行化错误而回滚的事务,就可以避免给应用程序员带来不必要的负担。把 default_transaction_isolation 设置为 serializable 可能是个好主意。通过在触发器中检查事务隔离级别来采取某些措施,以确保不会因为疏忽或为了绕过完整性检查而使用其他事务隔离级别,也是明智的。 + 使用这种技术时,如果应用软件通过某个框架运行,并由该框架自动重试因串行化失败而回滚的事务,就可以避免给应用程序员带来不必要的负担。把 default_transaction_isolation 设置为 serializable 可能是个好主意。通过在触发器中检查事务隔离级别来采取某些措施,以确保不会因为疏忽或为了绕过完整性检查而使用其他事务隔离级别,也是明智的。 @@ -1228,7 +1208,7 @@ SELECT pg_advisory_lock(q.id) FROM - 使用显式锁定强制一致性 + 使用显式阻塞锁强制一致性 当存在非可串行化写入时,要确保某一行当前仍然有效,并保护它不受并发更新影响, @@ -1251,7 +1231,7 @@ SELECT pg_advisory_lock(q.id) FROM 在非可串行化的 MVCC 环境下,全局有效性检查需要额外考虑。 - 例如,一个银行应用可能希望检查一个表中的所有收入总和等于另一个表中的所有支出总和, + 例如,一个银行应用可能希望检查一个表中的贷方金额总和等于另一个表中的借方金额总和, 而这两个表都在被活跃更新。在读已提交模式下,比较两个连续的 SELECT sum(...) 命令的结果并不可靠,因为第二个查询很可能会包含第一个查询没有统计到的事务提交结果。 在单个可重复读事务中完成这两次求和,只能准确反映在该可重复读事务开始之前已提交事务的效果 @@ -1279,10 +1259,10 @@ SELECT pg_advisory_lock(q.id) FROM 串行化失败处理 - serialization failure + 串行化失败 - retryable error + 可重试错误 @@ -1319,7 +1299,7 @@ SELECT pg_advisory_lock(q.id) FROM 重试事务并不保证重试后的事务一定能够完成;可能需要多次重试。 在争用非常激烈的情况下,完成一个事务可能需要尝试很多次。 - 如果涉及相互冲突的已准备事务,那么在已准备事务提交或回滚之前,可能根本无法取得进展。 + 如果涉及相互冲突的预备事务,那么在预备事务提交或回滚之前,可能根本无法取得进展。 @@ -1351,8 +1331,8 @@ SELECT pg_advisory_lock(q.id) FROM 锁定和索引 - index - locks + 索引 + @@ -1365,7 +1345,7 @@ SELECT pg_advisory_lock(q.id) FROM - 读写访问使用短期的页级共享/排他锁。每个索引行在被取出或插入之后,锁都会立即释放。这些索引类型在不存在死锁条件的前提下提供了最高的并发性。 + 读写访问使用短期的页级共享/排他锁。每个索引行在被取出或插入之后,锁都会立即释放。这些索引类型提供最高的并发性,并且不会产生死锁。 @@ -1387,7 +1367,7 @@ SELECT pg_advisory_lock(q.id) FROM - 读写访问使用短期的页级共享/排他锁。每个索引行在被取出或插入之后,锁都会立即释放。但要注意,插入一个 GIN 索引值通常会导致每行产生多个索引键插入,因此 GIN 可能为了插入单个值而做大量工作。 + 读写访问使用短期的页级共享/排他锁。每个索引行在被取出或插入之后,锁都会立即释放。但要注意,插入一个使用 GIN 索引的值通常会导致每行产生多个索引键插入,因此 GIN 可能为了插入单个值而做大量工作。 diff --git a/zh/20/oauth-validators.sgml b/zh/20/oauth-validators.sgml index ae667751..713ac140 100644 --- a/zh/20/oauth-validators.sgml +++ b/zh/20/oauth-validators.sgml @@ -92,7 +92,7 @@ 也可以通过部署架构的带外知识在没有显式作用域的情况下完成客户端授权, - 但这样会把用户排除在环路之外, + 但这样会让用户无法参与授权过程, 用户将无法发现部署错误,而此类错误也可能被静默利用。 如果不提示用户授予额外作用域, 则对数据库的访问必须被严格限制为仅允许受信任客户端 @@ -195,7 +195,7 @@ 模块必须保持可被信号中断, 这样服务器才能正确处理认证超时和来自 pg_ctl 的停机信号。 - 例如,套接字上的阻塞调用通常应替换为可无竞争地同时处理 + 例如,套接字上的阻塞调用通常应替换为能够在没有竞争条件的情况下同时处理 套接字事件与中断的代码(见 WaitLatchOrSocket()WaitEventSetWait() 等), 且长时间运行的循环应定期调用 @@ -219,15 +219,15 @@ 文档 - 验证器实现应记录针对每个终端用户向服务器报告的认证 ID 的内容和格式, + 验证器实现应在文档中说明针对每个终端用户向服务器报告的认证 ID 的内容和格式, 因为 DBA 可能需要据此构造 pg_ident 映射。 (例如,它是邮箱地址?组织 ID 号?还是 UUID?) - 还应记录该模块在 + 还应在文档中说明该模块在 delegate_ident_mapping=1 模式下是否可安全使用, 以及为此需要哪些额外配置。 如果实现提供了自定义 HBA 选项, - 这些选项的名称和语法也应当记录。 + 也应在文档中说明这些选项的名称和语法。 @@ -246,7 +246,7 @@ 不过,OAuth 本身就是授权框架, 令牌也可能携带用户权限信息。 例如,令牌可能包含用户所属组织组的信息, - 或列出用户可承担的角色, + 或列出用户可使用的角色, 将这些信息复制到每台服务器的本地用户名映射中可能并不理想。 @@ -425,8 +425,8 @@ typedef void (*ValidatorShutdownCB) (ValidatorModuleState *state); PostgreSQL 19 开始,验证器实现可以定义供 pg_hba.conf 内使用的自定义选项。这些选项会 - 以 - validator.option 的形式提供给用户。 + 以 validator.option 的形式 + 提供给用户。 注册和获取自定义选项的 API 如下所述。 @@ -509,7 +509,7 @@ const char *GetOAuthHBAOption(const ValidatorModuleState *state, - 服务器在重新载入配置时无法检查选项名和值。pg_hba.conf 中任何未注册的选项都会导致连接失败。因此,每个模块都有责任按需记录并验证选项值的语法。 + 服务器在重新载入配置时无法检查选项名和值。pg_hba.conf 中任何未注册的选项都会导致连接失败。因此,每个模块都有责任按需在文档中说明并验证选项值的语法。 如果模块在 validate_cb 期间发现无效的选项值,建议通过将 diff --git a/zh/20/oid2name.sgml b/zh/20/oid2name.sgml index 24e82560..eb8ff4a3 100644 --- a/zh/20/oid2name.sgml +++ b/zh/20/oid2name.sgml @@ -8,7 +8,7 @@ oid2name 1 - Application + 应用程序 diff --git a/zh/20/pageinspect.sgml b/zh/20/pageinspect.sgml index 2574679e..1e9e9419 100644 --- a/zh/20/pageinspect.sgml +++ b/zh/20/pageinspect.sgml @@ -370,20 +370,20 @@ test=# SELECT itemoffset, ctid, itemlen, nulls, vars, data, dead, htid, tids[0:2 13 | (16,8292) | 616 | f | f | 2f 00 00 00 00 00 00 00 | f | (4,17) | {"(4,17)","(4,21)"} (13 rows) - 这是一个 B-树叶页。所有指向表的元组恰好都是 posting list 元组(它们总共存储了 100 个 6 字节的 TID)。此外,在itemoffset 编号 1 处还有一个high key元组。这个示例中,ctid用于存储每个元组的编码信息,不过叶页元组通常会直接在ctid字段中存储一个堆 TID。tids是作为 posting list 存储的 TID 列表。 + 这是一个 B-树叶页。所有指向表的元组恰好都是倒排列表元组(每个都存储了 100 个 6 字节的 TID)。此外,在itemoffset 编号 1 处还有一个高键元组。这个示例中,ctid用于存储每个元组的编码信息,不过叶页元组通常会直接在ctid字段中存储一个堆 TID。tids是作为倒排列表存储的 TID 列表。 在内部页(此处未显示)中,ctid的块号部分是一个downlink(下行链接),也就是该索引中另一页的块号。ctid的偏移部分(第二个数字)存储着关于该元组的编码信息,例如实际存在的列数(后缀截断可能移除了不需要的后缀列)。被截断的列被视为具有minus infinity值。 - htid显示该元组的堆 TID,而不考虑底层元组表示形式。这个值可能与ctid相同,也可能是从 posting list 元组以及内部页元组所使用的替代表示中解码出来的。内部页中的元组通常会把实现层面的堆 TID 列截断掉,这会表现为htid值为 NULL。 + htid显示该元组的堆 TID,而不考虑底层元组表示形式。这个值可能与ctid相同,也可能是从倒排列表元组以及内部页元组所使用的替代表示中解码出来的。内部页中的元组通常会把实现层面的堆 TID 列截断掉,这会表现为htid值为 NULL。 - 请注意,任何非最右页(即btpo_next字段值非零的页面)的第一项都是该页的high key,这意味着它的data充当该页上所有项的上界,而它的ctid字段并不指向另一个块。另外,在内部页上,第一个真正的数据项(第一个不是high key的项)一定会把所有列都截断掉,因此其data字段中没有实际值。不过,这样的项在其ctid字段中确实有一个有效的下行链接。 + 请注意,任何非最右页(即btpo_next字段值非零的页面)的第一项都是该页的高键,这意味着它的data充当该页上所有项的上界,而它的ctid字段并不指向另一个块。另外,在内部页上,第一个真正的数据项(第一个不是高键的项)一定会把所有列都截断掉,因此其data字段中没有实际值。不过,这样的项在其ctid字段中确实有一个有效的下行链接。 - 关于 B-树索引结构的更多细节,参见。关于去重和 posting list 的更多细节,参见。关于去重和倒排列表的更多细节,参见 diff --git a/zh/20/parallel.sgml b/zh/20/parallel.sgml index d6f7fc7c..71ca3952 100644 --- a/zh/20/parallel.sgml +++ b/zh/20/parallel.sgml @@ -227,7 +227,7 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%'; - Parallel Append + 并行追加 每当 PostgreSQL 需要将来自多个源的行合并成一个结果集时,它就会使用 AppendMergeAppend 计划节点。这种情况常见于实现 UNION ALL 或扫描分区表时。这样的节点和其他任何计划中的情形一样,也可以用于并行计划。不过,在并行计划中,规划器也可能改用 Parallel Append 节点。 @@ -305,7 +305,7 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%'; - 如果函数或聚合会写数据库、修改事务状态(而不是通过子事务进行错误恢复)、访问序列,或者对设置做持久更改,那么它们必须标记为 PARALLEL UNSAFE。类似地,如果函数访问临时表、客户端连接状态、游标、预备语句,或者系统无法在工作进程之间同步的各种后端本地状态,那么它必须标记为 PARALLEL RESTRICTED。例如,setseedrandom 就因为最后一个原因而属于并行受限。 + 如果函数或聚合会写数据库、修改事务状态(使用子事务进行错误恢复的情况除外)、访问序列,或者对设置做持久更改,那么它们必须标记为 PARALLEL UNSAFE。类似地,如果函数访问临时表、客户端连接状态、游标、预备语句,或者系统无法在工作进程之间同步的各种后端本地状态,那么它必须标记为 PARALLEL RESTRICTED。例如,setseedrandom 就因为最后一个原因而属于并行受限。 diff --git a/zh/20/perform.sgml b/zh/20/perform.sgml index 62d16183..2f40a10c 100644 --- a/zh/20/perform.sgml +++ b/zh/20/perform.sgml @@ -866,9 +866,9 @@ EXPLAIN ANALYZE SELECT * FROM tenk1 WHERE unique1 < 100 AND unique2 > 9000 of the planner - + - 单列统计信息 + <anchor id="zh18-auto-perform-sect2-1" xreflabel="单列统计信息"/>单列统计信息 如上一节所见,查询规划器需要估计查询将检索多少行,才能对查询计划做出良好选择。本节简要介绍系统用于这些估计的统计信息。 @@ -1003,9 +1003,9 @@ WHERE tablename = 'road'; 下面的小节介绍当前支持的扩展统计信息类型。 - + - 函数依赖 + <anchor id="zh18-auto-perform-sect3-1" xreflabel="函数依赖"/>函数依赖 最简单的一类扩展统计信息跟踪函数依赖,这是数据库范式定义中使用的概念。如果知道列a的值就足以确定列b的值,也就是说,不存在两行具有相同的a值却拥有不同的b值,那么就称列b函数依赖于列a。在完全规范化的数据库中,函数依赖应当只存在于主键和超键上。不过在实践中,很多数据集出于各种原因并未完全规范化,常见情形之一就是为了性能而有意进行反规范化。即使在完全规范化的数据库中,某些列之间也可能存在部分相关性,这可以表现为部分函数依赖。 @@ -1056,9 +1056,9 @@ dep | [ + 在为涉及函数依赖列的查询计算选择度时,规划器会使用依赖系数来调整针对条件的选择度估计,这样就不会产生低估。 - + - 函数依赖的限制 + <anchor id="zh18-auto-perform-sect4-1" xreflabel="函数依赖的限制"/>函数依赖的限制 当前只有在考虑简单等值条件(将列与常量值比较)和具有常量值的IN @@ -1084,9 +1084,9 @@ SELECT * FROM zipcodes WHERE city = 'San Francisco' AND zip = '90210'; - + - 多元可区分值计数 + <anchor id="zh18-auto-perform-sect3-2" xreflabel="多元可区分值计数"/>多元可区分值计数 单列统计信息存储每一列中可区分值的数量。在组合多个列(例如GROUP BY a, b)时,如果规划器只有单列统计数据,则对可区分值数量的估计常常会错误,导致选择不好的计划。 @@ -1149,9 +1149,9 @@ nd | [ + - + - 多元 MCV 列表 + <anchor id="zh18-auto-perform-sect3-3" xreflabel="多元 MCV 列表"/>多元 MCV 列表 另一类按列存储的统计信息是高频值列表。这允许对单列做出非常准确的估计,但对于同时涉及多个列条件的查询,仍可能产生显著误差。 diff --git a/zh/20/pgcrypto.sgml b/zh/20/pgcrypto.sgml index 146f27f9..98a12e76 100644 --- a/zh/20/pgcrypto.sgml +++ b/zh/20/pgcrypto.sgml @@ -254,17 +254,17 @@ gen_salt(type text [, iter_count integer ]) returns text - type参数指定哈希算法。 + type参数指定 hash 算法。 接受的类型有:desxdesmd5bfsha256cryptsha512crypt。 最后两种即 sha256cryptsha512crypt, - 是现代的、基于 SHA-2 的密码哈希。 + 是现代的、基于 SHA-2 的密码 hash。 iter_count参数允许用户为支持该参数的算法指定迭代次数。 - 次数越高,密码哈希所需时间越长,从而破解它所需时间也越长。 - 不过,如果次数过高,计算一个哈希可能需要数年时间 — 这显然不切实际。 + 次数越高,对密码进行 hash 所需的时间越长,从而破解它所需时间也越长。 + 不过,如果次数过高,计算一个 hash 可能需要数年时间 — 这显然不切实际。 若省略iter_count参数,则使用默认迭代次数。 允许的iter_count值取决于算法,如所示。 @@ -308,12 +308,12 @@ gen_salt(type text [, iter_count integer ]) returns text - 为了选择合适的迭代次数,可以考虑原始 DES crypt 在当时硬件上的设计速度是每秒 4 次哈希。 - 低于每秒 4 次哈希可能会影响可用性,而高于每秒 100 次哈希则很可能过快。 + 为了选择合适的迭代次数,可以考虑原始 DES crypt 在当时硬件上的设计速度是每秒 4 次 hash。 + 低于每秒 4 次 hash 可能会影响可用性,而高于每秒 100 次 hash 则很可能过快。 - 概述了不同哈希算法之间的相对速度差异。 + 概述了不同 hash 算法之间的相对速度差异。 该表展示了在 8 字符密码上尝试所有字符组合所需的时间,假定密码只包含小写字母, 或者包含大小写字母和数字。在crypt-bf条目中, 斜杠后的数字是gen_saltiter_count参数值。 @@ -322,17 +322,17 @@ gen_salt(type text [, iter_count integer ]) returns text sha256cryptsha512crypt而言, 默认的iter_count5000 对现代硬件来说被认为过低, - 但可以调高以生成更强的密码哈希。除此之外, + 但可以调高以生成更强的密码 hash。除此之外, sha256cryptsha512crypt都被认为是安全的。
- 哈希算法速度 + Hash 算法速度 算法 - 每秒哈希次数 + 每秒 hash 次数 针对[a-z] 针对[A-Za-z0-9] 相对于md5 hash的耗时倍数 diff --git a/zh/20/pgdoccn-notes.sgml b/zh/20/pgdoccn-notes.sgml new file mode 100644 index 00000000..c0a43731 --- /dev/null +++ b/zh/20/pgdoccn-notes.sgml @@ -0,0 +1 @@ + diff --git a/zh/20/plhandler.sgml b/zh/20/plhandler.sgml index 38562e46..4048d572 100644 --- a/zh/20/plhandler.sgml +++ b/zh/20/plhandler.sgml @@ -17,11 +17,11 @@ - 调用处理器与其他函数一样被调用:它会接收一个指向 FunctionCallInfoBaseData struct 的指针,其中包含参数值以及被调用函数的相关信息;同时它还应返回一个 Datum 结果(如果希望返回 SQL 空值结果,还可以设置 isnull 字段,也就是 FunctionCallInfoBaseData 结构体中的该字段)。调用处理器与普通被调函数之间的区别在于,flinfo->fn_oid 字段在 FunctionCallInfoBaseData 结构体中保存的是实际要调用函数的 OID,而不是调用处理器本身的 OID。调用处理器必须使用这个字段来判定要执行哪个函数。另外,传入的参数列表是按照目标函数而不是调用处理器的声明来设置的。 + 调用处理器与其他函数一样被调用:它会接收一个指向 FunctionCallInfoBaseData struct 的指针,其中包含参数值以及被调用函数的相关信息;同时它还应返回一个 Datum 结果(如果希望返回 SQL 空值结果,还需要设置 isnull 字段,也就是 FunctionCallInfoBaseData 结构体中的该字段)。调用处理器与普通被调函数之间的区别在于,flinfo->fn_oid 字段在 FunctionCallInfoBaseData 结构体中保存的是实际要调用函数的 OID,而不是调用处理器本身的 OID。调用处理器必须使用这个字段来判定要执行哪个函数。另外,传入的参数列表是按照目标函数而不是调用处理器的声明来设置的。 - 调用处理器必须从系统目录 pg_proc 中取出该函数的条目,并分析被调用函数的参数类型和返回类型。该函数的 AS 子句可在其 CREATE FUNCTION 命令对应的 prosrc 列里找到,也就是 pg_proc 行中的该列。这里通常是一段过程语言源文本,但理论上也可以是其他内容,例如某个文件的路径名,或者任何能详细告诉调用处理器该做什么的信息。 + 调用处理器必须从系统目录 pg_proc 中取出该函数的条目,并分析被调用函数的参数类型和返回类型。该函数的 CREATE FUNCTION 命令中的 AS 子句内容,保存在 pg_proc 对应行的 prosrc 列中。这里通常是一段过程语言源文本,但理论上也可以是其他内容,例如某个文件的路径名,或者任何能详细告诉调用处理器该做什么的信息。 @@ -46,7 +46,7 @@ 验证器函数通常应遵循 参数:如果它被关闭,就应跳过任何开销高昂或依赖上下文的检查。如果该语言允许在编译时执行代码,验证器还必须抑制会诱发此类执行的检查。特别是,pg_dump 会关闭这个参数,这样它就可以装载过程语言函数,而不必担心函数体对其他数据库对象的副作用或依赖关系。(正因为有这一要求,调用处理器不应假设验证器已经完整检查了函数。提供验证器的目的,并不是让调用处理器省略检查,而是在 CREATE FUNCTION 命令中存在明显错误时立即通知用户。)虽然究竟检查哪些内容主要由验证器函数自行决定,但要注意,核心 CREATE FUNCTION 代码只会执行附加到函数上的 SET 子句,前提是 check_function_bodies 打开。因此,当 check_function_bodies 关闭时,那些结果可能受 GUC 参数影响的检查肯定都应跳过,以避免在恢复转储时出现虚假的失败。 + linkend="guc-check-function-bodies"/> 参数:如果它被关闭,就应跳过任何开销高昂或依赖上下文的检查。如果该语言允许在编译时执行代码,验证器还必须抑制会诱发此类执行的检查。特别是,pg_dump 会关闭这个参数,这样它就可以装载过程语言函数,而不必担心副作用或函数体对其他数据库对象的依赖关系。(正因为有这一要求,调用处理器不应假设验证器已经完整检查了函数。提供验证器的目的,并不是让调用处理器省略检查,而是在 CREATE FUNCTION 命令中存在明显错误时立即通知用户。)虽然究竟检查哪些内容主要由验证器函数自行决定,但要注意,只有在 check_function_bodies 打开时,核心 CREATE FUNCTION 代码才会执行函数附带的 SET 子句。因此,当 check_function_bodies 关闭时,那些结果可能受 GUC 参数影响的检查肯定都应跳过,以避免在恢复转储时出现虚假的失败。 diff --git a/zh/20/plperl.sgml b/zh/20/plperl.sgml index 48f1908f..f8d4b4ef 100644 --- a/zh/20/plperl.sgml +++ b/zh/20/plperl.sgml @@ -13,7 +13,7 @@ - PL/Perl 是一种可载入的过程语言,它允许使用 + PL/Perl 是一种可加载的过程语言,它允许使用 Perl 编程语言编写 PostgreSQL 函数和过程。 @@ -32,8 +32,7 @@ - 如果把该语言安装到 template1 中,之后创建的所有 - 数据库都会自动安装该语言。 + 如果把某种语言安装到template1中,之后创建的所有数据库都会自动安装该语言。 @@ -57,9 +56,9 @@ CREATE FUNCTION funcname (argument-types) RETURNS return-type --- function attributes can go here +-- 函数属性可以写在这里 AS $$ - # PL/Perl function body goes here + # PL/Perl 函数体写在这里 $$ LANGUAGE plperl; @@ -78,7 +77,7 @@ $$ LANGUAGE plperl; DO $$ - # PL/Perl code + # PL/Perl 代码 $$ LANGUAGE plperl; @@ -136,15 +135,14 @@ $$ LANGUAGE plperl; 如果一个 SQL 空值空值in PL/Perl被传给一个函数,在 - Perl 中该参数值将呈现为undefined。上述函数定义对于 - 空输入的行为并不理想(实际上,它会把它们当作零)。我们可以在函数 + sortas="PL/Perl">在 PL/Perl 中被传给一个函数,在 + Perl 中该参数值将呈现为未定义。上述函数定义对于 + 空值输入的行为并不理想(实际上,它会把它们当作零)。我们可以在函数 定义中添加 STRICT,让 PostgreSQL 采取更合理的做法:如果传入空值, - 函数将根本不会被调用,而是自动返回空结果。另一种方式是在函数体中 + 函数将根本不会被调用,而是自动返回空值结果。另一种方式是在函数体中 检查未定义输入。例如,假设我们希望在 - perl_max 的两个参数中一个为空、另一个非空时, - 返回非空参数而不是空值: + perl_max 的两个参数中一个为空值、另一个非空值时,返回非空值参数而不是空值: CREATE FUNCTION perl_max (integer, integer) RETURNS integer AS $$ @@ -186,7 +184,7 @@ $$ LANGUAGE plperl; bool_plperl 扩展提供了合适的转换。要使用它, 请先安装该扩展: -CREATE EXTENSION bool_plperl; -- or bool_plperlu for PL/PerlU +CREATE EXTENSION bool_plperl; -- 对于 PL/PerlU,则使用 bool_plperlu 然后对接收或返回 bool 的 PL/Perl 函数使用 TRANSFORM 函数属性,例如: @@ -199,7 +197,7 @@ AS $$ $$ LANGUAGE plperl; 应用该转换后,Perl 会将 bool 参数视为 - 1 或空值,从而能正确表示真或假。如果函数结果类型为 + 1 或空字符串,从而能正确表示真或假。如果函数结果类型为 bool,则其真或假取决于 Perl 是否会将返回值求值为真。 对函数内部执行的 SPI 查询,其布尔查询参数和结果也会进行类似的转换 ()。 @@ -232,12 +230,12 @@ CREATE OR REPLACE FUNCTION concat_array_elements(text[]) RETURNS TEXT AS $$ my $result = ""; return undef if (!defined $arg); - # as an array reference + # 作为数组引用 for (@$arg) { $result .= $_; } - # also works as a string + # 也可以作为字符串使用 $result .= $arg; return $result; @@ -248,7 +246,8 @@ SELECT concat_array_elements(ARRAY['PL','/','Perl']); - 多维数组会以所有 Perl 程序员都熟悉的方式,表示为对低维数组引用的引用。 + 多维数组按 Perl 程序员熟悉的方式表示为指向较低维数组的引用, + 而这些数组的元素又是引用。 @@ -357,11 +356,11 @@ SELECT * FROM perl_set(); 如果希望在代码中使用 strict 编译指示,可以有几种 选择。对于临时的全局用法,可以 SET - plperl.use_strict 为 true。这会影响后续编译的 + plperl.use_strict 为真。这会影响后续编译的 PL/Perl 函数,但不会影响当前会话中已经编译的 函数。对于永久的全局用法,可以在 postgresql.conf 文件中将 - plperl.use_strict 设为 true。 + plperl.use_strict 设为真。 @@ -417,7 +416,7 @@ use strict; spi_exec_query(query [, limit]) spi_exec_query - in PL/Perl + 在 PL/Perl 中 @@ -503,7 +502,7 @@ SELECT * FROM test_munge(); spi_query(command) spi_query - in PL/Perl + 在 PL/Perl 中 @@ -511,7 +510,7 @@ SELECT * FROM test_munge(); spi_fetchrow(cursor) spi_fetchrow - in PL/Perl + 在 PL/Perl 中 @@ -519,7 +518,7 @@ SELECT * FROM test_munge(); spi_cursor_close(cursor) spi_cursor_close - in PL/Perl + 在 PL/Perl 中 @@ -539,7 +538,7 @@ CREATE OR REPLACE FUNCTION lotsa_md5 (INTEGER) RETURNS SETOF foo_type AS $$ my $file = '/usr/share/dict/words'; my $t = localtime; elog(NOTICE, "opening file $file at $t" ); - open my $fh, '<', $file # ooh, it's a file access! + open my $fh, '<', $file # 注意,这里访问了文件! or elog(ERROR, "cannot open $file for reading: $!"); my @words = <$fh>; close $fh; @@ -579,7 +578,7 @@ SELECT * FROM lotsa_md5(500); spi_prepare(command, argument types) spi_prepare - in PL/Perl + 在 PL/Perl 中 @@ -587,7 +586,7 @@ SELECT * FROM lotsa_md5(500); spi_query_prepared(plan, arguments) spi_query_prepared - in PL/Perl + 在 PL/Perl 中 @@ -595,7 +594,7 @@ SELECT * FROM lotsa_md5(500); spi_exec_prepared(plan [, attributes], arguments) spi_exec_prepared - in PL/Perl + 在 PL/Perl 中 @@ -603,7 +602,7 @@ SELECT * FROM lotsa_md5(500); spi_freeplan(plan) spi_freeplan - in PL/Perl + 在 PL/Perl 中 @@ -612,7 +611,7 @@ SELECT * FROM lotsa_md5(500); spi_preparespi_query_preparedspi_exec_preparedspi_freeplan - 提供相同的功能,但用于预处理查询。spi_prepare + 提供相同的功能,但用于预备查询。spi_prepare 接受一个带编号参数占位符($1、$2 等)的查询字符串,以及参数类型的 字符串列表: @@ -631,7 +630,7 @@ $plan = spi_prepare('SELECT * FROM test WHERE id > $1 AND name = $2', - 预处理查询的优点在于,一个准备好的计划可以用于多次查询执行。当计划 + 预备查询的优点在于,一个准备好的计划可以用于多次查询执行。当计划 不再需要时,可以用 spi_freeplan 将其释放: CREATE OR REPLACE FUNCTION init() RETURNS VOID AS $$ @@ -708,7 +707,7 @@ SELECT release_hosts_query(); spi_commit() spi_commit - in PL/Perl + 在 PL/Perl 中 @@ -716,7 +715,7 @@ SELECT release_hosts_query(); spi_rollback() spi_rollback - in PL/Perl + 在 PL/Perl 中 @@ -756,7 +755,7 @@ CALL transaction_test1(); - PL/Perl 中的工具函数 + PL/Perl 中的辅助函数 @@ -765,7 +764,7 @@ CALL transaction_test1(); elog(level, msg) elog - in PL/Perl + 在 PL/Perl 中 @@ -791,7 +790,7 @@ CALL transaction_test1(); quote_literal(string) quote_literal - in PL/Perl + 在 PL/Perl 中 @@ -812,7 +811,7 @@ CALL transaction_test1(); quote_nullable(string) quote_nullable - in PL/Perl + 在 PL/Perl 中 @@ -831,7 +830,7 @@ CALL transaction_test1(); quote_ident(string) quote_ident - in PL/Perl + 在 PL/Perl 中 @@ -850,7 +849,7 @@ CALL transaction_test1(); decode_bytea(string) decode_bytea - in PL/Perl + 在 PL/Perl 中 @@ -868,7 +867,7 @@ CALL transaction_test1(); encode_bytea(string) encode_bytea - in PL/Perl + 在 PL/Perl 中 @@ -885,7 +884,7 @@ CALL transaction_test1(); encode_array_literal(array) encode_array_literal - in PL/Perl + 在 PL/Perl 中 @@ -908,7 +907,7 @@ CALL transaction_test1(); encode_typed_literal(value, typename) encode_typed_literal - in PL/Perl + 在 PL/Perl 中 @@ -926,7 +925,7 @@ CALL transaction_test1(); encode_array_constructor(array) encode_array_constructor - in PL/Perl + 在 PL/Perl 中 @@ -947,7 +946,7 @@ CALL transaction_test1(); looks_like_number(string) looks_like_number - in PL/Perl + 在 PL/Perl 中 @@ -967,7 +966,7 @@ CALL transaction_test1(); is_array_ref(argument) is_array_ref - in PL/Perl + 在 PL/Perl 中 @@ -1025,9 +1024,9 @@ CREATE OR REPLACE FUNCTION myfuncs() RETURNS void AS $$ }; $$ LANGUAGE plperl; -SELECT myfuncs(); /* initializes the function */ +SELECT myfuncs(); /* 初始化函数 */ -/* Set up a function that uses the quote function */ +/* 创建一个使用加引号函数的函数 */ CREATE OR REPLACE FUNCTION use_quote(TEXT) RETURNS text AS $$ my $text_to_quote = shift; @@ -1042,11 +1041,9 @@ $$ LANGUAGE plperl; - 出于安全原因,PL/Perl 会为某个 SQL 角色调用的函数在该角色专用的独立 - Perl 解释器中执行。这可以防止一个用户意外或恶意地干扰另一个用户的 + 出于安全原因,PL/Perl 会在每个 SQL 角色各自独立的 Perl 解释器中执行该角色调用的函数。这可以防止一个用户意外或恶意地干扰另一个用户的 PL/Perl 函数行为。每个这样的解释器都有自己的 - %_SHARED 变量值和其他全局状态。因此,只有在两个 - PL/Perl 函数都由同一 SQL 角色执行时,它们才会共享 + %_SHARED 变量值和其他全局状态。因此,当且仅当两个 PL/Perl 函数都由同一 SQL 角色执行时,它们才会共享 %_SHARED 的值。在某些应用中,一个会话可能会在多个 SQL 角色下执行代码(通过 SECURITY DEFINER 函数、 使用 SET ROLE 等),这时可能需要显式采取措施, @@ -1059,29 +1056,29 @@ $$ LANGUAGE plperl; - 可信与不可信的 PL/Perl + 受信任与不受信任的 PL/Perl - trusted + 受信任的 PL/Perl 通常,PL/Perl 会被安装为一种名为 plperl 的 - 可信编程语言。在这种设置下,为了保持安全性,某些 Perl + 受信任的编程语言。在这种设置下,为了保持安全性,某些 Perl 操作会被禁用。一般来说,受限制的是那些与环境交互的操作,包括文件句柄 操作、requireuse (针对外部模块)。它无法像 C 函数那样访问数据库服务器进程的内部, - 也无法以服务器进程的权限获取操作系统级访问。因此,可以允许任何无权限 + 也无法以服务器进程的权限获取操作系统级访问。因此,可以允许任何无特权 的数据库用户使用这种语言。 - 可信 PL/Perl 依赖 Perl 的 Opcode 模块来维持安全性。 + 受信任的 PL/Perl 依赖 Perl 的 Opcode 模块来维持安全性。 Perl 的 文档 - 指出,该模块对于可信 PL/Perl 这一使用场景并不有效。若你的安全需求 + 指出,该模块对于受信任的 PL/Perl 这一使用场景并不有效。若你的安全需求 不能接受该警告中的不确定性,请考虑执行 REVOKE USAGE ON LANGUAGE plperl FROM PUBLIC @@ -1105,16 +1102,16 @@ $$ LANGUAGE plperl; 有时需要编写不受这些限制的 Perl 函数。例如,可能需要一个能发送邮件的 Perl 函数。为处理这类情况,也可以把 PL/Perl 安装成一种 - 不可信语言(通常称为 + 不受信任的语言(通常称为 PL/PerlUPL/PerlU)。 在这种情况下,完整的 Perl 语言都可用。安装该语言时,使用语言名 - plperlu 就会选择不可信的 PL/Perl 变体。 + plperlu 就会选择不受信任的 PL/Perl 变体。 PL/PerlU 函数的编写者必须注意,函数不能被 用于任何非预期用途,因为它能够执行以数据库管理员身份登录的用户所能 - 做的任何事情。请注意,数据库系统只允许数据库超级用户用不可信语言创建 + 做的任何事情。请注意,数据库系统只允许数据库超级用户用不受信任的语言创建 函数。 @@ -1249,7 +1246,7 @@ $$ LANGUAGE plperl; $_TD->{relname} - 触发该触发器的表名。该字段已废弃,并且可能会在未来版本中移除。 + 触发该触发器的表名。该字段已弃用,并且可能会在未来版本中移除。 请改用 $_TD->{table_name}。 @@ -1328,12 +1325,12 @@ CREATE TABLE test ( CREATE OR REPLACE FUNCTION valid_id() RETURNS trigger AS $$ if (($_TD->{new}{i} >= 100) || ($_TD->{new}{i} <= 0)) { - return "SKIP"; # skip INSERT/UPDATE command + return "SKIP"; # 跳过 INSERT/UPDATE 命令 } elsif ($_TD->{new}{v} ne "immortal") { $_TD->{new}{v} .= "(modified by trigger)"; - return "MODIFY"; # modify row and execute INSERT/UPDATE command + return "MODIFY"; # 修改行并执行 INSERT/UPDATE 命令 } else { - return; # execute INSERT/UPDATE command + return; # 执行 INSERT/UPDATE 命令 } $$ LANGUAGE plperl; @@ -1490,7 +1487,7 @@ DO 'elog(WARNING, join ", ", sort keys %INC)' LANGUAGE plperl; 也会发生。这是在 plperl.on_init 完成的任何初始化 之后进行的。执行这段代码时 SPI 函数不可用。 plperl.on_plperl_init 中的 Perl 代码是在对解释器 - 进行锁定之后执行的,因此只能执行可信操作。 + 进行锁定之后执行的,因此只能执行受信任的操作。 diff --git a/zh/20/plpgsql.sgml b/zh/20/plpgsql.sgml index 59ffe06f..166a2616 100644 --- a/zh/20/plpgsql.sgml +++ b/zh/20/plpgsql.sgml @@ -144,7 +144,7 @@ CREATE FUNCTION somefunc(integer, text) RETURNS integer AS 'function body text' LANGUAGE plpgsql; - 就 CREATE FUNCTION 而言,函数体目前只是一个字符串字面量。编写函数体时,通常最好使用美元引用(见 ),而不是普通的单引号语法。如果不使用美元引用,函数体中的任何单引号或反斜线都必须通过双写进行转义。本章几乎所有示例的函数体都使用了美元引用。 + 就 CREATE FUNCTION 而言,函数体只是一个字符串字面量。编写函数体时,通常最好使用美元引用(见 ),而不是普通的单引号语法。如果不使用美元引用,函数体中的任何单引号或反斜线都必须通过双写进行转义。本章几乎所有示例的函数体都使用了美元引用。 @@ -340,7 +340,7 @@ $$ LANGUAGE plpgsql; - 当 PL/pgSQL 函数声明了输出参数时,输出参数也会像普通输入参数一样获得 $n 名称和可选别名。输出参数本质上是一个初始值为 NULL 的变量,应在函数执行期间给它赋值。该参数的最终值就是返回值。例如,sales-tax 的示例也可以这样写: + 当 PL/pgSQL 函数声明了输出参数时,输出参数也会像普通输入参数一样获得 $n 名称和可选别名。输出参数本质上是一个初始值为 NULL 的变量,应在函数执行期间给它赋值。该参数的最终值就是返回值。例如,销售税的示例也可以这样写: CREATE FUNCTION sales_tax(subtotal real, OUT tax real) AS $$ @@ -465,7 +465,7 @@ $$ LANGUAGE plpgsql; SELECT add_three_values(1, 2, 4.7); - 可以正常工作,并会自动把整数输入提升为 numeric。如果使用 anyelement,则必须手工把这三个输入转换成同一类型。 + 可以正常工作,并会自动把整数输入提升为 numeric。如果使用 anyelement,则必须手工把这三个输入转换成同一类型。 @@ -516,7 +516,7 @@ user_id users.user_id%TYPE; user_ids users.user_id%TYPE[]; user_ids users.user_id%TYPE ARRAY[4]; -- 等价于上面一行 - 与声明数组表列时一样,写多个方括号还是写具体数组维度都无关紧要:PostgreSQL 会把同一元素类型的所有数组都视为同一种类型,而不考虑维度数。(见 。) + 与声明数组表列时一样,写多对方括号还是写具体数组维度都无关紧要:PostgreSQL 会把同一元素类型的所有数组都视为同一种类型,而不考虑维度数。(见 。) @@ -594,12 +594,12 @@ SELECT merge_fields(t.*) FROM table1 t WHERE ... ; <application>PL/pgSQL</application>变量的排序规则 - collation - in PL/pgSQL + 排序规则 + 在 PL/pgSQL 中 - 当 PL/pgSQL 函数具有一个或多个可排序数据类型参数时,每次函数调用都会根据分配给实际参数的排序规则确定出一个排序规则,如 所述。如果该排序规则能成功确定出来(即参数之间的隐式排序规则没有冲突),那么所有可排序参数都会被视为隐式带有该排序规则。这会影响函数中那些受排序规则影响的操作。例如,考虑 + 当 PL/pgSQL 函数具有一个或多个支持排序规则的数据类型参数时,每次函数调用都会根据分配给实际参数的排序规则确定出一个排序规则,如 所述。如果该排序规则能成功确定出来(即参数之间的隐式排序规则没有冲突),那么所有支持排序规则的参数都会被视为隐式带有该排序规则。这会影响函数中那些受排序规则影响的操作。例如,考虑 CREATE FUNCTION less_than(a text, b text) RETURNS boolean AS $$ @@ -616,7 +616,7 @@ SELECT less_than(text_field_1, text_field_2 COLLATE "C") FROM table1; - 此外,确定出的排序规则也会被视为任何可排序数据类型局部变量的排序规则。因此,即使把这个函数写成下面这样,其行为也不会有任何不同: + 此外,确定出的排序规则也会被视为任何支持排序规则的数据类型局部变量的排序规则。因此,即使把这个函数写成下面这样,其行为也不会有任何不同: CREATE FUNCTION less_than(a text, b text) RETURNS boolean AS $$ @@ -631,11 +631,11 @@ $$ LANGUAGE plpgsql; - 如果函数没有可排序数据类型的参数,或者无法为它们确定共同排序规则,那么参数和局部变量将使用其数据类型的默认排序规则(通常是数据库默认排序规则,但对于域类型变量也可能不同)。 + 如果函数没有支持排序规则的数据类型的参数,或者无法为它们确定共同排序规则,那么参数和局部变量将使用其数据类型的默认排序规则(通常是数据库默认排序规则,但对于域类型变量也可能不同)。 - 通过在可排序数据类型局部变量的声明中加入 COLLATE 选项,可以为其指定不同的排序规则,例如 + 通过在支持排序规则的数据类型局部变量的声明中加入 COLLATE 选项,可以为其指定不同的排序规则,例如 DECLARE @@ -666,7 +666,7 @@ $$ LANGUAGE plpgsql; 表达式 - PL/pgSQL语句中使用的所有表达式都会由服务器的主SQL执行器处理。例如,当你写下这样一条PL/pgSQL语句时: + PL/pgSQL 语句中使用的所有表达式都会由服务器的主 SQL 执行器处理。例如,当写下这样一条 PL/pgSQL 语句时: IF expression THEN ... @@ -674,7 +674,7 @@ IF expression THEN ... SELECT expression - 来计算该表达式。如中详细讨论的那样,在构造该SELECT命令时,PL/pgSQL变量名的每一次出现都会被替换成查询参数。这使得该SELECT的查询计划只需准备一次,然后就能在后续以不同变量值求值时重用。因此,表达式第一次被使用时,实际发生的事情本质上相当于执行了一条PREPARE命令。例如,如果已经声明了两个整数变量xy,并写下 + 来计算该表达式。如 中详细讨论的那样,在构造该 SELECT 命令时,PL/pgSQL 变量名的每一次出现都会被替换成查询参数。这使得该 SELECT 的查询计划只需准备一次,然后就能在后续以不同变量值求值时重用。因此,表达式第一次被使用时,实际发生的事情本质上相当于执行了一条 PREPARE 命令。例如,如果已经声明了两个整数变量 xy,并写下 IF x < y THEN ... @@ -682,7 +682,7 @@ IF x < y THEN ... PREPARE statement_name(integer, integer) AS SELECT $1 < $2; - 然后,在每次执行IF语句时,这条预备语句都会以当前PL/pgSQL变量值作为参数值被EXECUTE。通常这些细节对PL/pgSQL用户并不重要,但在诊断问题时了解它们会很有帮助。更多信息见。 + 然后,在每次执行 IF 语句时,这条预备语句都会以当前 PL/pgSQL 变量值作为参数值由 EXECUTE 执行。通常这些细节对 PL/pgSQL 用户并不重要,但在诊断问题时了解它们会很有帮助。更多信息见 @@ -699,7 +699,7 @@ PREPARE statement_name(integer, integer) AS SELECT $1 基本语句 - 在这一节和接下来的小节中,我们会描述PL/pgSQL能明确理解的所有语句类型。任何不被识别为这些语句类型之一的被假定为是一个 SQL 命令,并且会被发送给主数据库引擎执行,具体如中所述。 + 在这一节和接下来的小节中,我们会描述 PL/pgSQL 能明确理解的所有语句类型。任何不被识别为这些语句类型之一的语句都被视为 SQL 命令,并会被发送给主数据库引擎执行,具体如 中所述。 @@ -715,8 +715,7 @@ PREPARE statement_name(integer, integer) AS SELECT $1 SELECT命令被发送到主数据库引擎的方式计算。 该表达式必须得到一个单一值(如果该变量是一个行或记录变量, 它可能是一个行值)。该目标变量可以是一个简单变量( - 可以选择用一个块名限定)、一个行或记录变量的域或是一个简单 - 变量或域的数组的元素或者数组的切片。 + 可以选择用一个块名限定)、行或记录目标的字段,或者数组目标的元素或切片。 等号(=)可以被用来代替 PL/SQL-兼容的 := @@ -758,7 +757,7 @@ INSERT INTO mytable VALUES (1,'one'), (2,'two'); 如果命令返回行(例如 SELECT,或者带 RETURNINGINSERT/UPDATE/DELETE/MERGE),有两种方式处理。 - 当命令最多返回一行,或者你只关心第一行的输出时,像往常一样编写命令,但要添加一个INTO子句来捕获输出,如中所述。为了处理所有的输出行,把命令写成FOR循环的数据源,如 中所述。 + 当命令最多返回一行,或者只关心第一行的输出时,可照常编写该命令,但要添加一个 INTO 子句来捕获输出,如 中所述。要处理所有输出行,可将该命令写成 FOR 循环的数据源,如 中所述。 @@ -766,29 +765,29 @@ INSERT INTO mytable VALUES (1,'one'), (2,'two'); - PL/pgSQL变量值可以自动插入到可优化的SQL命令中,这些命令包括SELECTINSERTUPDATEDELETEMERGE以及某些包含其中之一的实用程序命令,比如EXPLAINCREATE TABLE ... AS SELECT。在这些命令中,命令文本中出现的任何PL/pgSQL变量名都会被查询参数替换,然后变量的当前值会在运行时作为参数值提供。这与前面描述的表达式处理完全相同;详情请参见。 + PL/pgSQL 变量值可以自动插入可优化的 SQL 命令中,这些命令包括 SELECTINSERTUPDATEDELETEMERGE 以及某些包含其中之一的工具命令,比如 EXPLAINCREATE TABLE ... AS SELECT。在这些命令中,命令文本中出现的任何 PL/pgSQL 变量名都会被查询参数替换,然后变量的当前值会在运行时作为参数值提供。这与前面描述的表达式处理完全相同;详情请参见 - 当以这种方式执行一个可优化的 SQL 命令时,如中讨论的,PL/pgSQL会为该命令缓存并重用执行计划。 + 当以这种方式执行一个可优化的 SQL 命令时,如中讨论的,PL/pgSQL可能会为该命令缓存并重用执行计划。 - 不可优化的SQL命令(也称为实用命令)不能够接受查询参数。 所以自动替换PL/pgSQL的变量在这类命令中不起作用。 要在从PL/pgSQL执行的实用程序命令中包含非常量文本,你必须将实用程序命令构建为一个字符串,然后EXECUTE它,如中所讨论的。 + 不可优化的 SQL 命令(也称为工具命令)不能接受查询参数。因此,自动替换 PL/pgSQL 变量在这类命令中不起作用。要在从 PL/pgSQL 执行的工具命令中包含非常量文本,必须将工具命令构建为一个字符串,然后用 EXECUTE 执行它,如 中所讨论的。 - EXECUTE也必须使用,如果你想以某种其他方式修改命令,而不是提供数据值,例如改变表名。 + 如果想通过其他方式修改命令,而不只是提供数据值,例如改变表名,也必须使用 EXECUTE - 有时候计算一个表达式或SELECT查询但抛弃其结果是有用的,例如调用一个有副作用但是没有有用的结果值的函数。在PL/pgSQL中要这样做,可使用PERFORM语句: + 有时需要计算一个表达式或 SELECT 查询但丢弃其结果,例如调用一个有副作用但没有有用结果值的函数。要在 PL/pgSQL 中这样做,可使用 PERFORM 语句: PERFORM query; - 这会执行query并且丢弃掉结果。以写一个SQL SELECT命令相同的方式写该query,并且将初始的关键词SELECT替换为PERFORM。对于WITH查询,使用PERFORM并且接着把该查询放在圆括号中(在这种情况中,该查询只能返回一行)。PL/pgSQL变量将被替换到该查询中,正如上面描述的查询,并且计划被以相同的方式被缓存。还有,如果该查询产生至少一行,特殊变量FOUND会被设置为真,而如果它不产生行则设置为假(见)。 + 这会执行 query 并丢弃结果。query 的写法与 SQL SELECT 命令相同,只需把开头的关键词 SELECT 替换为 PERFORM。对于 WITH 查询,使用 PERFORM 并将该查询放在圆括号中(在这种情况下,该查询只能返回一行)。PL/pgSQL 变量会像上文所述那样替换到查询中,计划也会以相同方式缓存。此外,如果该查询产生至少一行,特殊变量 FOUND 会被设置为真;如果不产生行,则设置为假(见 )。 @@ -812,12 +811,12 @@ PERFORM create_mv('cs_session_page_requests_mv', my_query); SELECT INTO - in PL/pgSQL + 在 PL/pgSQL 中 RETURNING INTO - in PL/pgSQL + 在 PL/pgSQL 中 @@ -842,7 +841,7 @@ MERGE ... RETURNING expressions INTO STRICT - 如果一个行变量或一个变量列表被用作目标,该命令的结果列必须完全匹配该结果的结构,包括数量和数据类型,否则会发生一个运行时错误。当一个记录变量是目标时,它会自动地把自身配置成命令的结果列组成的行类型。 + 如果一个行变量或一个变量列表被用作目标,该命令的结果列必须完全匹配该目标的结构,包括数量和数据类型,否则会发生一个运行时错误。当一个记录变量是目标时,它会自动地把自身配置成命令的结果列组成的行类型。 @@ -850,7 +849,7 @@ MERGE ... RETURNING expressions INTO STRICT - 如果STRICT没有在INTO子句中被指定,那么target将被设置为该命令返回的第一个行,或者在该命令不返回行时设置为空(注意除非使用了ORDER BY,否则第一行的界定并不清楚)。第一行之后的任何结果行都会被抛弃。你可以检查特殊的FOUND变量(见)来确定是否返回了一行: + 如果STRICT没有在INTO子句中被指定,那么target将被设置为该命令返回的第一个行,或者在该命令不返回行时设置为空值(注意除非使用了ORDER BY,否则第一行的界定并不清楚)。第一行之后的任何结果行都会被抛弃。你可以检查特殊的FOUND变量(见)来确定是否返回了一行: SELECT * INTO myrec FROM emp WHERE empname = myname; @@ -879,7 +878,7 @@ END; - 如果为函数启用了print_strict_params,那么当由于不满足STRICT要求而抛出错误时,错误消息的DETAIL部分将包含传给该命令的参数信息。你可以通过设置plpgsql.print_strict_params来修改所有函数的print_strict_params设置,不过只有此后重新编译的函数才会受影响。也可以通过编译器选项按函数启用它,例如: + 如果为函数启用了print_strict_params,那么当由于不满足STRICT要求而抛出错误时,错误消息的DETAIL部分将包含传给该命令的参数信息。你可以通过设置plpgsql.print_strict_params来修改所有函数的print_strict_params设置,不过该设置只会影响此后编译的函数。也可以通过编译器选项按函数启用它,例如: CREATE FUNCTION get_userid(username text) RETURNS int AS $$ @@ -915,33 +914,31 @@ CONTEXT: PL/pgSQL function get_userid(text) line 6 at SQL statement 执行动态命令 - 很多时候你将想要在PL/pgSQL函数中产生动态命令,也就是每次执行中会涉及到不同表或不同数据类型的命令。PL/pgSQL通常对于命令所做的缓存计划尝试(如中讨论)在这种情境下无法工作。要处理这一类问题,需要提供EXECUTE语句: + 很多时候你将想要在PL/pgSQL函数中产生动态命令,也就是每次执行中会涉及到不同表或不同数据类型的命令。PL/pgSQL通常对于命令所做的缓存计划尝试(如中讨论)在这种情境下无法工作。要处理这一类问题,提供了EXECUTE语句: EXECUTE command-string INTO STRICT target USING expression , ... ; - 其中command-string是一个能得到一个包含要被执行命令字符串(类型text)的表达式。可选的target是一个记录变量、一个行变量或者一个逗号分隔的简单变量以及记录/行域的列表,该命令的结果将存储在其中。可选的USING表达式提供要被插入到该命令中的值。 + 其中command-string是一个能得到一个包含要被执行命令字符串(类型text)的表达式。可选的target是一个记录变量、一个行变量或者一个逗号分隔的简单变量以及记录/行字段的列表,该命令的结果将存储在其中。可选的USING表达式提供要被插入到该命令中的值。 在计算得到的命令字符串中,不会做PL/pgSQL变量的替换。任何所需的变量值必须在命令字符串被构造时被插入其中,或者你可以使用下面描述的参数。 - - 还有,对于通过EXECUTE执行的命令不会有计划被缓存。该命令反而在每次运行时都会被做计划。因此,该命令字符串可以在执行不同表和列上动作的函数中被动态创建。 - + 此外,通过 EXECUTE 执行的命令不会缓存计划,而是在每次运行该语句时重新规划。因此,可以在函数中动态构造命令字符串,对不同的表和列执行操作。 - INTO子句指定一个返回行的 SQL 命令的结果应该被赋值到哪里。如果提供了一个行或变量列表,它必须完全匹配查询命令结果的结构(当一个记录变量被提供时,它会自动把它自己配置为匹配结果结构)。如果返回多个行,只有第一个行会被赋值给INTO变量。如果没有返回行,NULL 会被赋值给INTO变量。如果没有指定INTO变量,该查询结果会被抛弃。 + INTO子句指定一个返回行的 SQL 命令的结果应该被赋值到哪里。如果提供了一个行变量或变量列表,它必须完全匹配查询命令结果的结构(当一个记录变量被提供时,它会自动把它自己配置为匹配结果结构)。如果返回多个行,只有第一个行会被赋值给INTO变量。如果没有返回行,NULL 会被赋值给INTO变量。如果没有指定INTO子句,该查询结果会被抛弃。 - 如果给出了STRICT选项,除非该查询刚好产生一行,否则将会报告一个错误。 + 如果给出了STRICT选项,除非该命令刚好产生一行,否则将会报告一个错误。 - 命令字符串可以使用参数值,它们在命令中用$1$2等引用。这些符号引用在USING子句中提供的值。这种方法常常更适合于把数据值作为文本插入到命令字符串中:它避免了将该值转换为文本以及转换回来的运行时负荷,并且它更不容易被 SQL 注入攻击,因为不需要引用或转义。一个示例是: + 命令字符串可以使用参数值,它们在命令中用$1$2等引用。这些符号引用在USING子句中提供的值。这种方法通常比把数据值作为文本插入命令字符串更可取:它避免了将该值转换为文本以及转换回来的运行时负荷,并且它更不容易被 SQL 注入攻击,因为不需要引用或转义。一个示例是: EXECUTE 'SELECT count(*) FROM mytable WHERE inserted_by = $1 AND inserted <= $2' INTO c @@ -959,25 +956,25 @@ EXECUTE 'SELECT count(*) FROM ' USING checked_user, checked_date; 一种更干净的方法是使用format()的 - %I规范,插入自带引号的表名或者列名: + %I 格式说明符,插入表名或列名并自动为其加上引号: EXECUTE format('SELECT count(*) FROM %I ' 'WHERE inserted_by = $1 AND inserted <= $2', tabname) INTO c USING checked_user, checked_date; - (此示例依赖于隐式连接由换行符分隔的字符串文字的 SQL 规则) + (此示例依赖于隐式连接由换行符分隔的字符串字面量的 SQL 规则) 参数符号的另一个限制是它们仅适用于可优化的SQL命令 (SELECT, INSERT, UPDATE, DELETE, MERGE以及包含其中一个的某些命令)。 - 在其他语句类型(通称为实用程序语句)中,即使它们只是数据值,您也必须以文本方式插入值。 + 在其他语句类型(通称为工具语句)中,即使它们只是数据值,你也必须以文本方式插入值。 - 在上面第一个示例中,带有一个简单的常量命令字符串和一些USING参数的EXECUTE命令在功能上等效于直接用PL/pgSQL写的命令,并且允许自动发生PL/pgSQL变量替换。重要的不同之处在于,EXECUTE会在每一次执行时根据当前的参数值重新计划该命令,而PL/pgSQL则是创建一个通用计划并且将其缓存以便重用。在最佳计划强依赖于参数值的情况中,使用EXECUTE来明确地保证不会选择一个通用计划是很有帮助的。 + 在上面第一个示例中,带有一个简单的常量命令字符串和一些USING参数的EXECUTE命令在功能上等效于直接用PL/pgSQL写的命令,并且允许自动发生PL/pgSQL变量替换。重要的不同之处在于,EXECUTE会在每一次执行时根据当前的参数值重新计划该命令,而PL/pgSQL则可能创建一个通用计划并且将其缓存以便重用。在最佳计划强依赖于参数值的情况中,使用EXECUTE来明确地保证不会选择一个通用计划是很有帮助的。 @@ -985,10 +982,7 @@ EXECUTE format('SELECT count(*) FROM %I ' - - - PL/pgSQL中的EXECUTE语句与EXECUTE PostgreSQL服务器支持的 SQL 语句无关。服务器的EXECUTE语句不能直接在PL/pgSQL函数中使用(并且也没有必要)。 - + PL/pgSQLEXECUTE 语句与 PostgreSQL 服务器支持的 SQL EXECUTE 语句无关。服务器的 EXECUTE 语句不能直接用于 PL/pgSQL 函数中(也没有这个必要)。 @@ -1052,19 +1046,19 @@ EXECUTE 'UPDATE tbl SET ' || ' WHERE key = ' || quote_nullable(keyvalue); - 如果正在处理的参数值可能为空,那么通常应该用quote_nullable来代替quote_literal。 + 如果正在处理的参数值可能为空值,那么通常应该用quote_nullable来代替quote_literal - 通常,必须小心地确保查询中的空值不会递送意料之外的结果。例如如果keyvalue为空,下面的WHERE子句 + 通常,必须小心地确保查询中的空值不会产生意料之外的结果。例如如果keyvalue为空值,下面的WHERE子句 'WHERE key = ' || quote_nullable(keyvalue) - 永远不会成功,因为在=操作符中使用空操作数得到的结果总是为空。如果想让空和一个普通键值一样工作,你应该将上面的命令重写成 + 永远不会成功,因为在=操作符中使用空值操作数得到的结果总是空值。如果想让空值像普通键值一样工作,你应该将上面的命令重写成 'WHERE key IS NOT DISTINCT FROM ' || quote_nullable(keyvalue) - (目前,IS NOT DISTINCT FROM的处理效率不如=,因此只有在非常必要时才这样做。关于空和IS DISTINCT的详细信息请见)。 + (目前,IS NOT DISTINCT FROM的处理效率不如=,因此只有在非常必要时才这样做。关于空值和IS DISTINCT的详细信息请见)。 @@ -1077,7 +1071,7 @@ EXECUTE 'UPDATE tbl SET ' || '$$ WHERE key = ' || quote_literal(keyvalue); - 因为如果newvalue的内容碰巧含有$$,那么这段代码就会出问题。同样的缺点可能适用于你选择的任何其他美元符号引用定界符。因此,要想安全地引用事先不知道的文本,必须恰当地使用quote_literalquote_nullablequote_ident。 + 因为如果newvalue的内容碰巧含有$$,那么这段代码就会出问题。同样的问题也适用于你选择的任何其他美元符号引用定界符。因此,要想安全地引用事先不知道的文本,必须恰当地使用quote_literalquote_nullablequote_ident @@ -1116,7 +1110,7 @@ EXECUTE format('UPDATE tbl SET %I = $1 WHERE key = $2', colname) GET CURRENT DIAGNOSTICS variable { = | := } item , ... ; - 这条命令允许检索系统状态指示符。CURRENT是一个噪声词(另见中的GET STACKED DIAGNOSTICS)。每个item是一个关键字, 它标识一个要被赋予给指定变量的状态值(变量应具有正确的数据类型来接收状态值)。中展示了当前可用的状态项。冒号等号(:=)可以被用来取代 SQL 标准的=符号。例如: + 这条命令允许检索系统状态指示符。CURRENT是一个噪声词(另见中的GET STACKED DIAGNOSTICS)。每个item是一个关键字, 它标识一个要被赋予给指定variable的状态值(变量应具有正确的数据类型来接收状态值)。中展示了当前可用的状态项。冒号等号(:=)可以被用来取代 SQL 标准的=符号。例如: GET DIAGNOSTICS integer_var = ROW_COUNT; @@ -1161,13 +1155,13 @@ GET DIAGNOSTICS integer_var = ROW_COUNT; 第二种确定命令效果的方法是检查名为FOUND的特殊变量,类型为boolean。 - 在每次PL/pgSQL函数调用中,FOUND都是以 false 开头。 + 在每次PL/pgSQL函数调用中,FOUND的初始值都是 false。 它由以下类型的语句设置: - SELECT INTO语句在分配行时将FOUND设置为true, + SELECT INTO语句在为目标赋上一行值时将FOUND设置为true, 如果没有返回行则设置为false。 @@ -1199,7 +1193,7 @@ GET DIAGNOSTICS integer_var = ROW_COUNT; FORFOREACH语句在迭代一次或多次时将 FOUND设置为true,否则设置为false。 - 当循环退出时,FOUND被设置为这种方式; + 当循环退出时,FOUND会按上述方式设置; 在循环执行过程中,FOUND不会被循环语句修改, 尽管它可能会被循环体内的其他语句执行修改。 @@ -1295,7 +1289,7 @@ RETURN expression; - 如果函数返回的是标量类型,表达式结果会自动转换为函数的返回类型。但如果要返回一个组合(行)值,你必须写出一个恰好生成所需列集合的表达式。这可能需要显式类型转换。 + 如果函数返回的是标量类型,表达式结果会按照赋值部分的说明自动转换为函数的返回类型。但如果要返回一个复合(行)值,你必须写出一个恰好生成所需列集合的表达式。这可能需要显式类型转换。 @@ -1307,7 +1301,7 @@ RETURN expression; - 一个函数的返回值不能是未定义。如果控制到达了函数最顶层的块而没有碰到一个RETURN语句,那么会发生一个运行时错误。不过,这个限制不适用于带输出参数的函数以及返回void的函数。在这些情况中,如果顶层的块结束,将自动执行一个RETURN语句。 + 一个函数的返回值不能是未定义。如果控制到达了函数最顶层块的末尾而没有碰到一个RETURN语句,那么会发生一个运行时错误。不过,这个限制不适用于带输出参数的函数以及返回void的函数。在这些情况中,如果顶层的块结束,将自动执行一个RETURN语句。 @@ -1331,12 +1325,12 @@ RETURN (1, 2, 'three'::text); -- 必须把列类型转换成正确的类型 RETURN NEXT - in PL/pgSQL + 在 PL/pgSQL 中 RETURN QUERY - in PL/pgSQL + 在 PL/pgSQL 中 @@ -1346,7 +1340,7 @@ RETURN QUERY EXECUTE command-string < - 当 PL/pgSQL 函数被声明为返回 SETOF sometype 时,返回过程会略有不同。在这种情况下,要返回的各个项通过一系列 RETURN NEXTRETURN QUERY 命令指定,最后再用一个不带参数的 RETURN 命令表明函数已经执行完毕。RETURN NEXT 可用于标量和组合数据类型;对于组合结果类型,会返回完整的结果RETURN QUERY 会把查询执行结果追加到函数的结果集中。在同一个集合返回函数中,RETURN NEXTRETURN QUERY 可以自由混用,此时它们的结果会被串接起来。 + 当 PL/pgSQL 函数被声明为返回 SETOF sometype 时,返回过程会略有不同。在这种情况下,要返回的各个项通过一系列 RETURN NEXTRETURN QUERY 命令指定,最后再用一个不带参数的 RETURN 命令表明函数已经执行完毕。RETURN NEXT 可用于标量和复合数据类型;对于复合结果类型,会返回完整的结果RETURN QUERY 会把查询执行结果追加到函数的结果集中。在同一个集合返回函数中,RETURN NEXTRETURN QUERY 可以自由混用,此时它们的结果会被串接起来。 @@ -1511,7 +1505,7 @@ END IF; - IF-THEN语句是IF的最简单形式。 如果条件为真,在THENEND IF之间的语句将被执行。否则,将忽略它们。 + IF-THEN语句是IF的最简单形式。 如果条件为真,在THENEND IF之间的语句将被执行。否则,将忽略它们。 @@ -1594,7 +1588,7 @@ ELSIF number > 0 THEN ELSIF number < 0 THEN result := 'negative'; ELSE - -- 嗯,唯一的其他可能性是数字为空 + -- 嗯,唯一的其他可能性是 number 为 null result := 'NULL'; END IF; @@ -1690,9 +1684,7 @@ END CASE; - - 这种形式的CASEIF-THEN-ELSIF完全等价,唯一的区别是:如果省略了ELSE子句,CASE会报错,而不是简单地什么也不做。 - + 这种形式的CASEIF-THEN-ELSIF完全等价,唯一的区别是:如果执行到被省略的ELSE子句,就会报错,而不是简单地什么也不做。 @@ -1702,12 +1694,12 @@ END CASE; 简单循环 - loop + 循环 在 PL/pgSQL 中 - 使用LOOPEXITCONTINUEWHILEFORFOREACH语句,你可以安排PL/pgSQL重复一系列命令。 + 使用LOOPEXITCONTINUEWHILEFORFOREACH语句,你可以安排PL/pgSQL函数重复一系列命令。 @@ -1862,22 +1854,22 @@ END LOOP label ; - 这种形式的FOR会创建一个在一个整数范围上迭代的循环。变量name会自动定义为类型integer并且只在循环内存在(任何该变量名的现有定义在此循环内都将被忽略)。给出范围上下界的两个表达式在进入循环的时候计算一次。如果没有指定BY子句,迭代步长为 1,否则步长是BY中指定的值,该值也只在循环进入时计算一次。如果指定了REVERSE,那么在每次迭代后步长值会被减除而不是增加。 + 这种形式的FOR会创建一个在一个整数范围上迭代的循环。变量name会自动定义为类型integer并且只在循环内存在(任何该变量名的现有定义在此循环内都将被忽略)。给出范围上下界的两个表达式在进入循环的时候计算一次。如果没有指定BY子句,迭代步长为 1,否则步长是BY中指定的值,该值也只在循环进入时计算一次。如果指定了REVERSE,那么在每次迭代后会减去步长,而不是加上步长。 整数FOR循环的一些示例: FOR i IN 1..10 LOOP - -- 我在循环中将取值 1,2,3,4,5,6,7,8,9,10 + -- i 在循环中将取值 1,2,3,4,5,6,7,8,9,10 END LOOP; FOR i IN REVERSE 10..1 LOOP - -- 我在循环中将取值 10,9,8,7,6,5,4,3,2,1 + -- i 在循环中将取值 10,9,8,7,6,5,4,3,2,1 END LOOP; FOR i IN REVERSE 10..1 BY 2 LOOP - -- 我在循环中将取值 10,8,6,4,2 + -- i 在循环中将取值 10,8,6,4,2 END LOOP; @@ -1941,7 +1933,7 @@ $$ LANGUAGE plpgsql; - 在这类 FOR 语句中使用的 query,可以是任何向调用者返回行的 SQL 命令:最常见的是 SELECT,但也可以是带 RETURNING 子句的 INSERTUPDATEDELETEMERGE。某些实用程序命令,如 EXPLAIN,也可以用于此处。 + 在这类 FOR 语句中使用的 query,可以是任何向调用者返回行的 SQL 命令:最常见的是 SELECT,但也可以是带 RETURNING 子句的 INSERTUPDATEDELETEMERGE。某些工具命令,如 EXPLAIN,也可以用于此处。 @@ -1956,7 +1948,7 @@ FOR target IN EXECUTE text_expressionstatements END LOOP label ; - 这个示例类似前面的形式,只不过源查询被指定为一个字符串表达式,在每次进入FOR循环时都会计算它并且重新计划。这允许程序员在一个预先计划好了的命令的速度和一个动态命令的灵活性之间进行选择,就像一个纯EXECUTE语句那样。在使用EXECUTE时,可以通过USING将参数值插入到动态命令中。 + 这个示例类似前面的形式,只不过源查询被指定为一个字符串表达式,在每次进入FOR循环时都会计算它并且重新计划。这允许程序员在一个预先计划好了的命令的速度和一个动态命令的灵活性之间进行选择,就像一个纯EXECUTE语句那样。与EXECUTE一样,可以通过USING将参数值插入到动态命令中。 @@ -1969,7 +1961,7 @@ END LOOP label ; 遍历数组 - FOREACH循环很像FOR循环,但它不是遍历 SQL 查询返回的行,而是遍历数组值的元素。(一般来说,FOREACH用于遍历组合值表达式的组成部分;未来还可能加入遍历数组以外其他组合值的变体。)用于遍历数组的FOREACH语句如下: + FOREACH循环很像FOR循环,但它不是遍历 SQL 查询返回的行,而是遍历数组值的元素。(一般来说,FOREACH用于遍历复合值表达式的组成部分;未来还可能加入遍历数组以外其他复合值的变体。)用于遍历数组的FOREACH语句如下: <<label>> @@ -1997,7 +1989,7 @@ END; $$ LANGUAGE plpgsql; - 元素会按存储顺序访问,而不管数组有多少维。尽管target通常只是单个变量,但在遍历组合值(记录)数组时,它也可以是一个变量列表。在这种情况下,每个数组元素都会按组合值的连续列给这些变量赋值。 + 元素会按存储顺序访问,而不管数组有多少维。尽管target通常只是单个变量,但在遍历复合值(记录)数组时,它也可以是一个变量列表。在这种情况下,每个数组元素都会按复合值的连续列给这些变量赋值。 @@ -2030,8 +2022,8 @@ NOTICE: row = {10,11,12} 捕获错误 - exceptions - in PL/pgSQL + 异常 + 在 PL/pgSQL 中 @@ -2054,7 +2046,7 @@ END; - 如果没有发生错误,这种形式的块只是简单地执行所有statements, 并且接着控制转到END之后的下一个语句。但是如果在statements内发生了一个错误,则会放弃对statements的进一步处理,然后控制会转到EXCEPTION列表。系统会在列表中寻找匹配所发生错误的第一个condition。如果找到一个匹配,则执行对应的handler_statements,并且接着把控制转到END之后的下一个语句。如果没有找到匹配,该错误就会传播出去,就好像根本没有EXCEPTION一样:错误可以被一个带有EXCEPTION的闭合块捕捉,如果没有EXCEPTION则中止该函数的处理。 + 如果没有发生错误,这种形式的块只是简单地执行所有statements, 并且接着控制转到END之后的下一个语句。但是如果在statements内发生了一个错误,则会放弃对statements的进一步处理,然后控制会转到EXCEPTION列表。系统会在列表中寻找匹配所发生错误的第一个condition。如果找到一个匹配,则执行对应的handler_statements,并且接着把控制转到END之后的下一个语句。如果没有找到匹配,该错误就会传播出去,就好像根本没有EXCEPTION一样:错误可以被一个带有EXCEPTION的外围块捕捉,如果没有这样的块则中止该函数的处理。 @@ -2091,7 +2083,7 @@ END; - 进入和退出一个包含EXCEPTION子句的块要比不包含EXCEPTION的块开销大的多。因此,只在必要的时候使用EXCEPTION。 + 进入和退出一个包含EXCEPTION子句的块要比不包含该子句的块开销大得多。因此,只在必要的时候使用EXCEPTION @@ -2118,9 +2110,9 @@ BEGIN IF found THEN RETURN; END IF; - -- 不在这里,那么尝试插入该键 + -- 该键不存在,因此尝试插入 -- 如果其他某人并发地插入同一个键, - -- 我们可能得到一个唯一键失败 + -- 就可能发生违反唯一约束的错误 BEGIN INSERT INTO db(a,b) VALUES (key, data); RETURN; @@ -2159,7 +2151,7 @@ SELECT merge_db(1, 'dennis'); GET STACKED DIAGNOSTICS variable { = | := } item , ... ; - 每个item是一个关键词,它标识一个被赋予给指定变量(应该具有接收该值的正确数据类型)的状态值。中显示了当前可用的状态项。 + 每个item是一个关键词,它标识一个被赋予给指定variable(应该具有接收该值的正确数据类型)的状态值。中显示了当前可用的状态项。
@@ -2271,7 +2263,7 @@ END; 获得执行位置信息 - GET DIAGNOSTICS(之前在中描述)命令检索有关当前执行状态的信息(反之上文讨论的GET STACKED DIAGNOSTICS命令会把有关执行状态的信息报告成一个以前的错误)。它的PG_CONTEXT状态项可用于标识当前执行位置。状态项PG_CONTEXT将返回一个文本字符串,其中有描述该调用栈的多行文本。第一行会指向当前函数以及当前正在执行GET DIAGNOSTICS的命令。第二行及其后的行表示调用栈中更上层的调用函数。例如: + GET DIAGNOSTICS(之前在中描述)命令检索有关当前执行状态的信息(反之上文讨论的GET STACKED DIAGNOSTICS命令报告先前发生错误时的执行状态信息)。它的PG_CONTEXT状态项可用于标识当前执行位置。状态项PG_CONTEXT将返回一个文本字符串,其中包含一行或多行描述该调用栈的文本。第一行会指向当前函数以及当前正在执行的GET DIAGNOSTICS命令。第二行及其后的行表示调用栈中更上层的调用函数。例如: CREATE OR REPLACE FUNCTION outer_func() RETURNS integer AS $$ @@ -2315,7 +2307,7 @@ CONTEXT: PL/pgSQL function outer_func() line 3 at RETURN 游标 - cursor + 游标 在 PL/pgSQL 中 @@ -2347,7 +2339,7 @@ DECLARE - 当游标查询使用 FOR UPDATE/SHARE 时,不能使用 SCROLL 选项。此外,对于涉及易失函数的查询,最好使用 NO SCROLLSCROLL 的实现假定重新读取查询输出会得到一致的结果,而易失函数并不满足这一假设。 + 当游标查询使用 FOR UPDATE/SHARE 时,不能使用 SCROLL 选项。此外,对于涉及易失函数的查询,最好使用 NO SCROLLSCROLL 的实现假定重新读取查询输出会得到一致的结果,而易失函数可能无法满足这一假设。 @@ -2372,7 +2364,7 @@ DECLARE - 打开游标会创建一个称为 portal 的服务器内部数据结构,它保存游标查询的执行状态。portal 具有一个名称,在其存在期间该名称在会话内必须唯一。默认情况下,PL/pgSQL 会为其创建的每个 portal 分配唯一名称。不过,如果你给游标变量赋一个非空字符串值,该字符串会被用作 portal 名称。这个特性可用于中描述的用法。 + 打开游标会创建一个称为 portal 的服务器内部数据结构,它保存游标查询的执行状态。portal 具有一个名称,在其存在期间该名称在会话内必须唯一。默认情况下,PL/pgSQL 会为其创建的每个 portal 分配唯一名称。不过,如果你给游标变量赋一个非 NULL 的字符串值,该字符串会被用作 portal 名称。这个特性可用于中描述的用法。 @@ -2498,7 +2490,7 @@ FETCH direction { FROM | IN } RELATIVE countFORWARD或者 BACKWARD。 - 省略direction和指定NEXT是一样的。在使用count的形式中,count可以是任意的整数值表达式(与SQL命令FETCH不一样,FETCH仅允许整数常量)。除非游标被使用SCROLL选项声明或打开,否则要求反向移动的direction值很可能会失败。 + 省略direction和指定NEXT是一样的。在使用count的形式中,count可以是任意的整数值表达式(与SQL命令FETCH不一样,后者仅允许整数常量)。除非游标被使用SCROLL选项声明或打开,否则要求反向移动的direction值很可能会失败。 @@ -2586,13 +2578,13 @@ CLOSE curs1; - 游标使用的 portal 名称既可以由程序员指定,也可以自动生成。要指定 portal 名称,只需在打开refcursor变量之前给它赋一个字符串值。OPEN会把该refcursor变量的字符串值用作底层 portal 的名称。不过,如果refcursor变量为 null,OPEN就会自动生成一个与任何现有 portal 都不冲突的名称,并把它赋回给refcursor变量。 + 游标使用的 portal 名称既可以由程序员指定,也可以自动生成。要指定 portal 名称,只需在打开refcursor变量之前给它赋一个字符串值。OPEN会把该refcursor变量的字符串值用作底层 portal 的名称。不过,如果refcursor变量为 null(这是默认值),OPEN就会自动生成一个与任何现有 portal 都不冲突的名称,并把它赋回给refcursor变量。 - 在 PostgreSQL 16 之前,已绑定游标变量会被初始化为其自身名称,而不是保持为空,因此默认情况下底层 portal 名称与游标变量名相同。之所以改动,是因为该行为在不同函数里同名游标之间带来了过高的名称冲突风险。 + 在 PostgreSQL 16 之前,已绑定游标变量会被初始化为其自身名称,而不是保持为 NULL,因此默认情况下底层 portal 名称与游标变量名相同。之所以改动,是因为该行为在不同函数里同名游标之间带来了过高的名称冲突风险。 @@ -2726,7 +2718,7 @@ CALL transaction_test1(); 连锁的事务 - 在 PL/pgSQL + 在 PL/pgSQL 中 @@ -2739,7 +2731,7 @@ CALL transaction_test1(); - PL/pgSQL 不支持保存点(SAVEPOINT/ROLLBACK TO SAVEPOINT/RELEASE SAVEPOINT)。保存点的典型用法可以用带异常处理器的代码块替代(见)。在内部,实现为带异常处理器的代码块会形成一个子事务,这意味着在这类代码块内部不能结束事务。 + PL/pgSQL 不支持保存点(SAVEPOINT/ROLLBACK TO SAVEPOINT/RELEASE SAVEPOINT)。保存点的典型用法可以用带异常处理器的代码块替代(见)。带异常处理器的代码块在内部会形成一个子事务,这意味着在这类代码块内部不能结束事务。 @@ -2786,23 +2778,19 @@ CALL transaction_test2(); 在 PL/pgSQL 中 - - 使用RAISE语句报告消息以及抛出错误。 - - + 使用RAISE语句报告消息和抛出错误。 RAISE level 'format' , expression , ... USING option { = | := } expression , ... ; RAISE level condition_name USING option { = | := } expression , ... ; RAISE level SQLSTATE 'sqlstate' USING option { = | := } expression , ... ; RAISE level USING option { = | := } expression , ... ; RAISE ; - - - level选项指定了错误的严重性。允许的级别有DEBUGLOGINFONOTICE, WARNING以及EXCEPTION,默认级别是EXCEPTIONEXCEPTION会抛出一个错误(通常会中止当前事务)。其他级别仅仅是产生不同优先级的消息。不管一个特定优先级的消息是被报告给客户端、还是写到服务器日志、亦或是二者同时都做,这都由配置变量控制。详见。 - +其中,level选项指定错误的严重程度。允许的级别为DEBUG, + LOGINFO, + NOTICEWARNING以及EXCEPTION,其中EXCEPTION是默认值。EXCEPTION会抛出错误(通常会中止当前事务);其他级别只会生成不同优先级的消息。特定优先级的消息是报告给客户端、写入服务器日志,还是两者都做,由配置变量控制。更多信息见中的说明。 在第一种语法变体中,在level之后(如果有),写一个format字符串 - (必须是一个简单的字符串文字,而不是一个表达式)。格式字符串指定要报告的错误消息文本。 + (必须是一个简单的字符串字面量,而不是一个表达式)。格式字符串指定要报告的错误消息文本。 格式字符串后跟要插入到消息中的可选参数表达式。 在格式字符串中,%将被下一个可选参数的值的字符串表示替换。写 %%以发出一个字面上的%。 @@ -2845,7 +2833,7 @@ RAISE WARNING SQLSTATE '22012'; DETAIL - 提供一个错误的细节消息。 + 提供错误的详细信息。 @@ -2876,9 +2864,7 @@ RAISE WARNING SQLSTATE '22012'; - - 这个示例将用给定的错误消息和提示中止事务: - + 这个例子会中止事务,并给出指定的错误消息和提示: RAISE EXCEPTION 'Nonexistent ID --> %', user_id USING HINT = 'Please check your user ID'; @@ -2890,9 +2876,8 @@ RAISE EXCEPTION 'Nonexistent ID --> %', user_id RAISE 'Duplicate user ID: %', user_id USING ERRCODE = 'unique_violation'; RAISE 'Duplicate user ID: %', user_id USING ERRCODE = '23505'; - - + 另一种得到前面示例相同结果的方式是: RAISE unique_violation USING MESSAGE = 'Duplicate user ID: ' || user_id; @@ -2923,7 +2908,7 @@ RAISE unique_violation USING MESSAGE = 'Duplicate user ID: ' || user_id; - 当用 SQLSTATE 代码指定错误代码时,你并不受限于预定义错误代码,而是可以选择任何由五位数字和/或大写 ASCII 字母构成的错误代码,唯一不能使用的是 00000。我们建议尽量避免抛出以三个零结尾的错误代码,因为这些是类别代码,只能用于捕获整个类别。 + 当用 SQLSTATE 代码指定错误代码时,你并不受限于预定义错误代码,而是可以选择任何由五位数字和/或大写 ASCII 字母构成的错误代码,唯一不能使用的是 00000。我们建议尽量避免抛出以三个零结尾的错误代码,因为这些是类别代码,只能通过捕获整个类别来捕获这类错误。 @@ -2935,12 +2920,12 @@ RAISE unique_violation USING MESSAGE = 'Duplicate user ID: ' || user_id; ASSERT - in PL/pgSQL + 在 PL/pgSQL 中 - assertions - in PL/pgSQL + 断言 + 在 PL/pgSQL 中 @@ -2957,15 +2942,14 @@ ASSERT condition , condition是一个布尔 表达式,它被期望总是计算为真。如果确实如此, - ASSERT语句不会再做什么。但如果结果是假 - 或者空,那么将发生一个ASSERT_FAILURE异常(如果在计算 + ASSERT语句不会再做什么。但如果结果是假或者空值,那么将发生一个ASSERT_FAILURE异常(如果在计算 condition时发生错误, 它会被报告为一个普通错误)。 如果提供了可选的message, - 它是一个结果(如果非空)被用来替换默认错误消息文本 + 它是一个结果(如果不为 NULL)被用来替换默认错误消息文本 assertion failed的表达式(如果 condition失败)。 message表达式在 @@ -2998,7 +2982,7 @@ ASSERT condition , - PL/pgSQL可以被用来在数据更改或者数据库事件上定义触发器函数。触发器函数用CREATE FUNCTION命令创建,它被声明为一个没有参数并且返回类型为trigger(对于数据更改触发器)或者event_trigger(对于数据库事件触发器)的函数。名为PG_something的特殊局部变量将被自动创建用以描述触发该调用的条件。 + PL/pgSQL可以被用来在数据更改或者数据库事件上定义触发器函数。触发器函数用CREATE FUNCTION命令创建,它被声明为一个没有参数并且返回类型为trigger(对于数据更改触发器)或者event_trigger(对于数据库事件触发器)的函数。名为TG_something的特殊局部变量将被自动创建用以描述触发该调用的条件。 @@ -3009,10 +2993,7 @@ ASSERT condition , 数据更改触发器被声明为一个没有参数并且返回类型为trigger的函数。注意,如下所述,即便该函数准备接收一些在CREATE TRIGGER中指定的参数 — 这类参数通过TG_ARGV传递,也必须把它声明为没有参数。 - - 当一个PL/pgSQL函数当做触发器调用时,在顶层块会自动创建一些特殊变量。它们是: - - + 当一个PL/pgSQL函数作为触发器被调用时,会在顶层块中自动创建一些特殊变量。它们是: NEW record @@ -3132,11 +3113,11 @@ ASSERT condition , - INSTEAD OF触发器(总是行级触发器,并且可能只被用于视图)能够返回空来表示它们没有执行任何更新,并且对该行剩余的操作可以被跳过(即后续的触发器不会被引发,并且该行不会被计入外围INSERT/UPDATE/DELETE的行影响状态中)。否则一个非空值应该被返回用以表示该触发器执行了所请求的操作。对于INSERTUPDATE操作,返回值应该是NEW,触发器函数可能对它进行了修改来支持INSERT RETURNINGUPDATE RETURNING(这也将影响被传递给任何后续触发器的行值,或者被传递给带有ON CONFLICT DO UPDATEINSERT语句中一个特殊的EXCLUDED别名引用)。对于DELETE操作,返回值应该是OLD。 + INSTEAD OF触发器(总是行级触发器,并且只能用于视图)能够返回 null 来表示它们没有执行任何更新,并且对该行剩余的操作应被跳过(即后续的触发器不会被引发,并且该行不会被计入外围INSERT/UPDATE/DELETE的行影响状态中)。否则应该返回一个非 null 值用以表示该触发器执行了所请求的操作。对于INSERTUPDATE操作,返回值应该是NEW,触发器函数可能对它进行了修改来支持INSERT RETURNINGUPDATE RETURNING(这也将影响被传递给任何后续触发器的行值,或者被传递给带有ON CONFLICT DO UPDATEINSERT语句中一个特殊的EXCLUDED别名引用)。对于DELETE操作,返回值应该是OLD - 一个AFTER行级触发器或一个BEFOREAFTER语句级触发器的返回值总是会被忽略,它可能也是空。不过,任何这些类型的触发器可能仍会通过抛出一个错误来中止整个操作。 + 一个AFTER行级触发器或一个BEFOREAFTER语句级触发器的返回值总是会被忽略,因此也可以返回 null。不过,任何这些类型的触发器可能仍会通过抛出一个错误来中止整个操作。 @@ -3310,11 +3291,10 @@ INSTEAD OF INSERT OR UPDATE OR DELETE ON emp_view - - 一个 <application>PL/pgSQL</application> 用于维护汇总表的触发器函数 + 一个用于维护汇总表的 <application>PL/pgSQL</application> 触发器函数 - 这里详述的模式有一部分是基于 Ralph Kimball 所作的数据仓工具包中的Grocery Store示例。 + 这里详述的模式有一部分是基于 Ralph Kimball 所作的数据仓库工具包中的Grocery Store示例。 @@ -3457,7 +3437,7 @@ SELECT * FROM sales_summary_bytime; 使用过渡表审计 - 这个示例产生和相同的结果,但并未使用一个为每一行都触发的触发器,而是在把相关信息收集到一个过渡表中之后用了一个只为每个语句引发一次的触发器。当调用语句修改了很多行时,这种方法明显比行触发器方法快。注意我们必须为每一种事件建立一个单独的触发器声明,因为每种情况的REFERENCING子句必须不同。但是这并不能阻止我们使用单一的触发器函数(实际上,使用三个单独的函数会更好,因为可以避免在TG_OP上的运行时测试)。 + 这个示例产生和相同的结果,但并未使用一个为每一行都触发的触发器,而是在把相关信息收集到一个过渡表中之后用了一个只为每个语句引发一次的触发器。当调用语句修改了很多行时,这种方法可能显著快于行触发器方法。注意我们必须为每一种事件建立一个单独的触发器声明,因为每种情况的REFERENCING子句必须不同。但是这并不能阻止我们使用单一的触发器函数(实际上,使用三个单独的函数可能会更好,因为可以避免在TG_OP上的运行时测试)。 @@ -3519,10 +3499,7 @@ CREATE TRIGGER emp_audit_del PL/pgSQL可以被用来定义事件触发器。PostgreSQL要求一个可以作为事件触发器调用的函数必须被声明为没有参数并且返回类型为event_trigger - - 当一个PL/pgSQL函数被作为一个事件触发器调用,在顶层块中会自动创建一些特殊变量。它们是: - - + 当一个PL/pgSQL函数作为事件触发器被调用时,会在顶层块中自动创建一些特殊变量。它们是: TG_EVENT text @@ -3573,9 +3550,7 @@ CREATE EVENT TRIGGER snitch ON ddl_command_start EXECUTE FUNCTION snitch(); <application>PL/pgSQL</application> 内部机制 - - 这一节讨论了一些PL/pgSQL用户应该知道的一些重要的实现细节。 - + 本节讨论一些实现细节,了解这些细节对 PL/pgSQL 用户通常很重要。 @@ -3653,7 +3628,7 @@ CREATE FUNCTION stamp_user(id int, comment text) RETURNS void AS $$ END; $$ LANGUAGE plpgsql; - 在UPDATE命令中,curtimecomment以及id将引用该函数的变量和参数,不管users有没有这些名称的列。注意,我们不得不在WHERE子句中对users.id的引用加以限定,以便让它引用表列。但是我们不需要在UPDATE列表中把对comment的引用限定为一个目标,因为语法上那必须是users的一列。我们可以用下面的方式写一个相同的不依赖于variable_conflict设置的函数: + 在UPDATE命令中,curtimecomment以及id将引用该函数的变量和参数,不管users有没有这些名称的列。注意,我们不得不在WHERE子句中对users.id的引用加以限定,以便让它引用表列。但是我们不需要对UPDATE列表中作为目标的comment引用加以限定,因为语法上那必须是users的一列。我们可以用下面的方式写一个相同的不依赖于variable_conflict设置的函数: CREATE FUNCTION stamp_user(id int, comment text) RETURNS void AS $$ <<fn>> @@ -3672,7 +3647,7 @@ $$ LANGUAGE plpgsql; - 目前,变量替换只在 SELECTINSERTUPDATEDELETEMERGE 以及包含其中之一的命令中生效(例如 EXPLAINCREATE TABLE ... AS SELECT),因为主 SQL 引擎只允许在这些命令中使用查询参数。若要在其他语句类型(统称为实用语句)中使用非常量名称或值,就必须把该实用语句构造为字符串,再用 EXECUTE 执行。 + 目前,变量替换只在 SELECTINSERTUPDATEDELETEMERGE 以及包含其中之一的命令中生效(例如 EXPLAINCREATE TABLE ... AS SELECT),因为主 SQL 引擎只允许在这些命令中使用查询参数。若要在其他语句类型(统称为工具语句)中使用非常量名称或值,就必须把该工具语句构造为字符串,再用 EXECUTE 执行。 @@ -3694,7 +3669,7 @@ $$ LANGUAGE plpgsql; - PL/pgSQL(更准确地说,是 SPI 管理器)还会尝试缓存与某个预备语句相关的执行计划。如果没有使用缓存计划,那么每次执行该语句时都会生成新的执行计划,而当前参数值(也就是 PL/pgSQL 变量值)可用于优化所选计划。如果该语句没有参数,或者会被执行很多次,SPI 管理器就会考虑创建一个不依赖具体参数值的通用计划,并将其缓存起来供重复使用。通常只有在执行计划对其中引用的 PL/pgSQL 变量值不太敏感时,才会这样做。如果执行计划对参数值非常敏感,那么每次重新生成计划总体上反而更划算。关于预备语句的行为,详见 。 + PL/pgSQL(更准确地说,是 SPI 管理器)还可以尝试缓存与某个预备语句相关的执行计划。如果没有使用缓存计划,那么每次执行该语句时都会生成新的执行计划,而当前参数值(也就是 PL/pgSQL 变量值)可用于优化所选计划。如果该语句没有参数,或者会被执行很多次,SPI 管理器就会考虑创建一个不依赖具体参数值的通用计划,并将其缓存起来供重复使用。通常只有在执行计划对其中引用的 PL/pgSQL 变量值不太敏感时,才会这样做。如果执行计划对参数值非常敏感,那么每次重新生成计划总体上反而更划算。关于预备语句的行为,详见 @@ -3743,7 +3718,7 @@ $$ LANGUAGE plpgsql; - 在logfunc2中,PostgreSQL的主解析器不知道应该把'now'解释成什么类型,因此返回一个text类型的数据值,其中包含字符串now。在确定对本地变量curtime的赋值时,PL/pgSQL解释器通过调用用于该转换的textouttimestamp_in函数,把这个字符串转换为timestamp类型。因此,计算得到的时间戳会按程序员预期在每次执行时更新。虽然这恰好能得到预期结果,但效率并不高,因此使用now()函数仍然是更好的主意。 + 在logfunc2中,PostgreSQL的主解析器不知道应该把'now'解释成什么类型,因此返回一个text类型的数据值,其中包含字符串now。在随后给局部变量curtime赋值时,PL/pgSQL解释器通过调用用于该转换的textouttimestamp_in函数,把这个字符串转换为timestamp类型。因此,计算得到的时间戳会按程序员预期在每次执行时更新。虽然这恰好能得到预期结果,但效率并不高,因此使用now()函数仍然是更好的主意。 @@ -3772,7 +3747,7 @@ $$ LANGUAGE plpgsql; - 另一种开发PL/pgSQL的好方法,是使用有助于过程语言开发的 GUI 数据库访问工具。这类工具的一个例子是pgAdmin,当然也有其他工具。它们通常提供一些方便的特性,例如转义单引号,以及让重新创建和调试函数变得更容易。 + 另一种使用PL/pgSQL进行开发的好方法,是使用有助于过程语言开发的 GUI 数据库访问工具。这类工具的一个例子是pgAdmin,当然也有其他工具。它们通常提供一些方便的特性,例如转义单引号,以及让重新创建和调试函数变得更容易。 @@ -3780,7 +3755,7 @@ $$ LANGUAGE plpgsql; 引号的处理 - 一个PL/pgSQL函数的代码在一个CREATE FUNCTION中被指定为一个字符串。如果你用通常的方式把该字符串写在单引号中间,那么该函数体中的任何单引号都必须被双写;同样任何反斜线也必须被双写(假定使用了转义字符串语法)。双写引号最多有点冗长,并且在更复杂的情况中代码会变得完全无法理解,因为你很容易发现你需要半打或者更多相邻的引号。我们推荐你转而把函数体写成一个美元引用的字符串(见)。在美元引用方法中,你从不需要双写任何引号。但是要注意为你需要的每一层嵌套选择一个不同的美元引用定界符。例如,你可能把CREATE FUNCTION命令写成: + 一个PL/pgSQL函数的代码在一个CREATE FUNCTION中被指定为一个字符串字面量。如果你用通常的方式把该字符串写在单引号中间,那么该函数体中的任何单引号都必须被双写;同样任何反斜线也必须被双写(假定使用了转义字符串语法)。双写引号本身就很繁琐,并且在更复杂的情况中代码会变得完全无法理解,因为你很容易发现你需要半打或者更多相邻的引号。我们推荐你转而把函数体写成一个美元引用的字符串(见)。在美元引用方法中,你从不需要双写任何引号。但是要注意为你需要的每一层嵌套选择一个不同的美元引用定界符。例如,你可能把CREATE FUNCTION命令写成: CREATE OR REPLACE FUNCTION testfunc(integer) RETURNS integer AS $PROC$ .... @@ -3817,7 +3792,7 @@ CREATE FUNCTION foo() RETURNS integer AS ' - 用于函数体内的字符串,例如: + 用于函数体内的字符串字面量,例如: a_output := ''Blah''; SELECT * FROM users WHERE f_name=''foobar''; @@ -3827,7 +3802,7 @@ SELECT * FROM users WHERE f_name=''foobar''; a_output := 'Blah'; SELECT * FROM users WHERE f_name='foobar'; - 这恰好就是PL/pgSQL在两种情况中会看到的。 + 这恰好就是PL/pgSQL解析器在两种情况中会看到的。 @@ -3850,7 +3825,7 @@ a_output := a_output || '' AND name LIKE ''''foobar'''' AND xyz'' a_output := a_output || $$ AND name LIKE 'foobar' AND xyz$$ - 要小心在这周围的任何美元引用定界符不只是$$。 + 要小心在这周围的任何美元引用定界符都不能是$$ @@ -3883,7 +3858,7 @@ a_output := a_output || $$ AND name LIKE 'foobar'$$ - 当你想在一个字符串常量(占 8 个引号)中有两个单引号时并且这会挨着该字符串常量的末尾(另外 2 个)。如果你正在写一个产生其他函数的函数(如中),你将很可能只需要这种。例如: + 当字符串常量中需要两个单引号(这需要 8 个引号),而且它们紧邻该字符串常量的末尾(还需 2 个引号)时。通常只有在编写生成其他函数的函数时(如所示),才会需要这种写法。例如: a_output := a_output || '' IF v_'' || referrer_keys.kind || '' LIKE '''''''''' @@ -3925,9 +3900,7 @@ a_output := a_output || $$ IF v_$$ || referrer_keys.kind || $$ LIKE '$$ 因此建议你在一个单独的开发环境中进行测试。 - - 根据需要设置 plpgsql.extra_warningsplpgsql.extra_errors,适当情况下,在开发和/或测试环境中可以设置为 "all"。 - + 建议在开发和/或测试环境中,根据需要将 plpgsql.extra_warningsplpgsql.extra_errors 设置为 "all" 这些额外的检查通过配置变量plpgsql.extra_warnings来启用警告, @@ -4041,18 +4014,16 @@ HINT: Make sure the query returns the exact list of columns. - PL/pgSQL与 PL/SQL 在许多方面都非常类似。它是一种块结构的、命令式的语言并且所有变量必须先被声明。赋值、循环和条件则很类似。在从PL/SQLPL/pgSQL移植时必须记住一些事情: - - + PL/pgSQL在许多方面都与 PL/SQL 类似。它是一种具有块结构的命令式语言,所有变量都必须声明。赋值、循环和条件语句也都很相似。在从PL/SQL移植到PL/pgSQL时,应当记住以下主要差异: - 如果一个 SQL 命令中使用的名字可能是一个表的列名或者是对一个函数中变量的引用,那么PL/SQL会将它当作一个列名。默认情况下, PL/pgSQL会抛出名称模糊的错误, 你可以指定plpgsql.variable_conflict=use_column来改变这一行为以匹配PL/SQL。如中所述。通常最好是首先避免这种歧义,但如果不得不移植依赖于该行为的大量代码,那么设置variable_conflict将是最好的方案。 + 如果一个 SQL 命令中使用的名字可能是一个表的列名或者是对一个函数中变量的引用,那么PL/SQL会将它当作一个列名。默认情况下, PL/pgSQL会抛出名称有歧义的错误, 你可以指定plpgsql.variable_conflict=use_column来改变这一行为以匹配PL/SQL。如中所述。通常最好是首先避免这种歧义,但如果不得不移植依赖于该行为的大量代码,那么设置variable_conflict可能是最好的方案。 - 在PostgreSQL中,函数体必须写成字符串文本。因此你需要使用美元符引用或者转义函数体中的单引号(见)。 + 在PostgreSQL中,函数体必须写成字符串字面量。因此你需要使用美元符引用或者转义函数体中的单引号(见)。 @@ -4142,13 +4113,13 @@ show errors; - 在PostgreSQL中,函数体被认为是一个字符串,所以你需要使用引号或者美元符号包围它。这代替了Oracle 方法中的用于终止的/。 + 在PostgreSQL中,函数体被认为是一个字符串字面量,所以你需要使用引号或者美元引用定界符包围它。这代替了Oracle 方法中的用于终止的/ - 在PostgreSQL中没有show errors命令, 并且也不需要这个命令,因为错误是自动报告的。 + 在PostgreSQL中没有show errors命令, 并且也不需要这个命令,因为错误是自动报告的。 @@ -4180,9 +4151,7 @@ $$ LANGUAGE plpgsql; 从<application>PL/SQL</application>移植一个创建另一个函数的函数到<application>PL/pgSQL</application> - - 下面的过程从一个SELECT语句抓取行,并且为了效率而构建一个带有IF语句中结果的大型函数。 - + 下面的过程从 SELECT 语句读取行,并将结果写入 IF 语句,从而构造一个大型函数,以提高效率。 这是 Oracle 版本: @@ -4213,8 +4182,7 @@ show errors; - - 这里是PostgreSQL的版本: + 下面是这个函数的最终移植结果,目标数据库为PostgreSQL CREATE OR REPLACE PROCEDURE cs_update_referrer_type_proc() AS $func$ DECLARE @@ -4247,9 +4215,7 @@ BEGIN EXECUTE func_cmd; END; $func$ LANGUAGE plpgsql; - - 请注意,这里先单独构造了函数体,再通过 quote_literal 传入,以便把其中的引号正确双写。之所以需要这种技术,是因为我们无法安全地使用美元引用来定义新函数:我们并不确切知道会从 referrer_key.key_string 字段插入什么字符串。(这里假定 referrer_key.kind 始终可信地只会是 hostdomainurl,但 referrer_key.key_string 可能是任意内容,尤其可能包含美元符号。)实际上,这个函数比 Oracle 原版还有改进,因为当 referrer_key.key_stringreferrer_key.referrer_type 中包含引号时,它也不会生成无效代码。 - +注意,这里单独构造函数体,然后将其传给quote_literal,使其中的每个引号都变成两个。这种技术是必需的,因为不能安全地使用美元引用来定义新函数:我们无法确定会插入什么字符串,其来源是referrer_key.key_string字段。(这里假定referrer_key.kind可信,其值总是hostdomainurl,但是referrer_key.key_string可能是任何内容,尤其可能包含美元符号。)这个函数实际上改进了 Oracle 原版:当referrer_key.key_stringreferrer_key.referrer_type中包含引号时,它也不会生成有问题的代码。 @@ -4269,7 +4235,7 @@ $func$ LANGUAGE plpgsql; CREATE OR REPLACE PROCEDURE cs_parse_url( v_url IN VARCHAR2, - v_host OUT VARCHAR2, -- 这将被传回去 + v_host OUT VARCHAR2, -- 这个值将被返回 v_path OUT VARCHAR2, -- 这个也是 v_query OUT VARCHAR2) -- 还有这个 IS @@ -4312,9 +4278,9 @@ show errors; CREATE OR REPLACE FUNCTION cs_parse_url( v_url IN VARCHAR, - v_host OUT VARCHAR, -- 这将被传递回去 + v_host OUT VARCHAR, -- 这个值将被返回 v_path OUT VARCHAR, -- 这个也是 - v_query OUT VARCHAR) -- 以及这个 + v_query OUT VARCHAR) -- 还有这个 AS $$ DECLARE a_pos1 INTEGER; @@ -4357,7 +4323,7 @@ SELECT * FROM cs_parse_url('http://foobar.com/query.cgi?baz'); - 展示了如何移植一个使用了多种 Oracle 特性的过程。 + 展示了如何移植一个使用了多种 Oracle 专属特性的过程。 @@ -4397,7 +4363,7 @@ show errors - 这是我们如何将这个过程移植到PL/pgSQL: + 下面展示了如何将这个过程移植到PL/pgSQL CREATE OR REPLACE PROCEDURE cs_create_job(v_job_id integer) AS $$ @@ -4472,7 +4438,7 @@ EXCEPTION END; - 如果你正在移植一个以这种方式使用SAVEPOINTROLLBACK TO的 Oracle 过程,工作会比较简单:只要忽略SAVEPOINTROLLBACK TO即可。如果你的 Oracle 过程以不同方式使用SAVEPOINTROLLBACK TO,那就需要认真思考了。 + 如果你正在移植一个以这种方式使用SAVEPOINTROLLBACK TO的 Oracle 过程,工作会比较简单:只要省略SAVEPOINTROLLBACK TO即可。如果你的 Oracle 过程以不同方式使用SAVEPOINTROLLBACK TO,那就需要认真思考了。 @@ -4489,11 +4455,11 @@ END; 优化 <application>PL/pgSQL</application> 函数 - PostgreSQL提供了两种函数创建修饰符来优化执行:volatility(对于给定的相同参数,函数是否总是返回相同的结果)以及strictness (如果任何参数为空,函数是否返回空)。详见参考页。 + PostgreSQL提供了两种函数创建修饰符来优化执行:volatility(对于给定的相同参数,函数是否总是返回相同的结果)以及strictness (如果任何参数为空值,函数是否返回空值)。详见参考页。 - 在利用这些优化属性时,你的CREATE FUNCTION语句应该看起来像这样: + 在利用这些优化属性时,你的CREATE FUNCTION语句可能像这样: CREATE FUNCTION foo(...) RETURNS integer AS $$ diff --git a/zh/20/plpython.sgml b/zh/20/plpython.sgml index bd461c1c..faf153b9 100644 --- a/zh/20/plpython.sgml +++ b/zh/20/plpython.sgml @@ -45,7 +45,7 @@ CREATE FUNCTION funcname (argument-list) RETURNS return-type AS $$ - # PL/Python function body + # PL/Python 函数体 $$ LANGUAGE plpython3u; @@ -85,7 +85,7 @@ def __plpython_procedure_pymax_23456(): CREATE FUNCTION pystrip(x text) RETURNS text AS $$ - x = x.strip() # error + x = x.strip() # 错误 return x $$ LANGUAGE plpython3u; @@ -95,7 +95,7 @@ CREATE FUNCTION pystrip(x text) RETURNS text AS $$ global x - x = x.strip() # ok now + x = x.strip() # 现在可以正常工作 return x $$ LANGUAGE plpython3u; @@ -216,7 +216,7 @@ $$ LANGUAGE plpython3u; 如果把 SQL 空值空值在 PL/Python 中传给函数,参数值在 Python 中会显示为None。例如,中展示的pymax定义在处理空输入时就会返回错误结果。我们可以在函数定义中添加STRICT,让PostgreSQL做出更合理的处理:如果传入空值,函数根本不会被调用,而是自动返回空结果。另一种办法是在函数体中检查空输入: + sortas="PL/Python">在 PL/Python 中传给函数,参数值在 Python 中会显示为None。例如,中展示的pymax定义在处理空值输入时就会返回错误结果。我们可以在函数定义中添加STRICT,让PostgreSQL做出更合理的处理:如果传入空值,函数根本不会被调用,而是自动返回空值结果。另一种办法是在函数体中检查空值输入: CREATE FUNCTION pymax (a integer, b integer) @@ -329,21 +329,21 @@ CREATE TYPE named_value AS ( ); - 组合结果可以按以下形式返回: + 复合结果可以按以下形式返回: 序列类型(元组或列表,但不能是集合,因为集合不可通过索引访问) - 返回的序列对象必须包含与组合结果类型字段数相同的项。索引为 0 的项会赋给复合类型的第一个字段,索引为 1 的项赋给第二个字段,依此类推。例如: + 返回的序列对象必须包含与复合结果类型字段数相同的项。索引为 0 的项会赋给复合类型的第一个字段,索引为 1 的项赋给第二个字段,依此类推。例如: CREATE FUNCTION make_pair (name text, value integer) RETURNS named_value AS $$ return ( name, value ) - # or alternatively, as list: return [ name, value ] + # 也可以使用列表: return [ name, value ] $$ LANGUAGE plpython3u; @@ -391,7 +391,7 @@ AS $$ self.value = v return named_value(name, value) - # or simply + # 或者简写为 class nv: pass nv.name = name nv.value = value @@ -452,8 +452,8 @@ CREATE TYPE greeting AS ( CREATE FUNCTION greet (how text) RETURNS SETOF greeting AS $$ - # return tuple containing lists as composite types - # all other combinations work also + # 返回包含列表的元组,以列表表示复合类型 + # 其他组合方式也都可用 return ( [ how, "World" ], [ how, "PostgreSQL" ], [ how, "PL/Python" ] ) $$ LANGUAGE plpython3u; @@ -511,7 +511,7 @@ $$ LANGUAGE plpython3u; - 也支持带OUT参数的返回集函数(使用RETURNS SETOF record)。例如: + 也支持带OUT参数的集合返回函数(使用RETURNS SETOF record)。例如: CREATE FUNCTION multiout_simple_setof(n integer, OUT integer, OUT integer) RETURNS SETOF record AS $$ return [(1, 2)] * n @@ -546,7 +546,7 @@ SELECT * FROM multiout_simple_setof(3); DO $$ - # PL/Python code + # PL/Python 代码 $$ LANGUAGE plpython3u; @@ -859,7 +859,7 @@ CREATE FUNCTION usesavedplan() RETURNS trigger AS $$ else: plan = plpy.prepare("SELECT 1") SD["plan"] = plan - # rest of function + # 函数的其余部分 $$ LANGUAGE plpython3u; @@ -876,11 +876,11 @@ $$ LANGUAGE plpython3u; - 游标对象提供fetch方法,它接受一个整数参数并返回结果对象。每次调用fetch,返回对象都会包含下一批行,数量不会超过该参数值。一旦所有行都已取完,fetch就会开始返回空结果对象。游标对象还提供迭代器接口,每次产生一行,直到所有行为止。以这种方式获取的数据不会作为结果对象返回,而是以字典形式返回,每个字典对应一行结果。 + 游标对象提供fetch方法,它接受一个整数参数并返回结果对象。每次调用fetch,返回对象都会包含下一批行,数量不会超过该参数值。一旦所有行都已取完,fetch就会开始返回空结果对象。游标对象还提供迭代器接口,每次产生一行,直到取完所有行。以这种方式获取的数据不会作为结果对象返回,而是以字典形式返回,每个字典对应一行结果。 - 下面示例展示了如何处理大表中的数据: + 下面示例展示了处理大表中数据的两种方式: CREATE FUNCTION count_odd_iterator() RETURNS integer AS $$ odd = 0 @@ -906,7 +906,7 @@ $$ LANGUAGE plpython3u; CREATE FUNCTION count_odd_prepared() RETURNS integer AS $$ odd = 0 plan = plpy.prepare("SELECT num FROM largetable WHERE num % $1 <> 0", ["integer"]) -rows = list(plpy.cursor(plan, [2])) # or: = list(plan.cursor([2])) +rows = list(plpy.cursor(plan, [2])) # 或者:= list(plan.cursor([2])) return len(rows) $$ LANGUAGE plpython3u; @@ -1059,7 +1059,7 @@ CALL transaction_test1(); - 实用函数 + 辅助函数 plpy模块还提供以下函数: @@ -1113,7 +1113,7 @@ PL/Python function "raise_custom_exception" - 另一组实用函数是plpy.quote_literal(string)plpy.quote_nullable(string)以及plpy.quote_ident(string)。它们等价于中描述的内置引用函数。在构造临时查询时,这些函数很有用。中动态 SQL 的一个 PL/Python 等价写法如下: + 另一组辅助函数是plpy.quote_literal(string)plpy.quote_nullable(string)以及plpy.quote_ident(string)。它们等价于中描述的内置加引号函数。在构造临时查询时,这些函数很有用。中动态 SQL 的一个 PL/Python 等价写法如下: plpy.execute("UPDATE tbl SET %s = %s WHERE key = %s" % ( plpy.quote_ident(colname), diff --git a/zh/20/pltcl.sgml b/zh/20/pltcl.sgml index 9c78fe04..06178f8f 100644 --- a/zh/20/pltcl.sgml +++ b/zh/20/pltcl.sgml @@ -13,7 +13,7 @@ - PL/Tcl 是一种适用于 PostgreSQL 数据库系统的可载入的过程语言,它允许使用 Tcl 语言 来编写 PostgreSQL 函数和过程。 + PL/Tcl 是一种适用于 PostgreSQL 数据库系统的可加载的过程语言,它允许使用 Tcl 语言 来编写 PostgreSQL 函数和过程。 @@ -54,7 +54,7 @@ CREATE FUNCTION funcname (argument-types) RETURNS return-type AS $$ - # PL/Tcl function body + # PL/Tcl 函数体 $$ LANGUAGE pltcl; @@ -75,11 +75,11 @@ CREATE FUNCTION tcl_max(integer, integer) RETURNS integer AS $$ $$ LANGUAGE pltcl STRICT; - 注意STRICT子句,它让我们不必考虑空输入值:如果传入的是空值,函数根本不会被调用,而是会自动返回空结果。 + 注意STRICT子句,它让我们不必考虑空值输入:如果传入的是空值,函数根本不会被调用,而是会自动返回空值结果。 - 在非严格函数中,如果某个参数的实际值为空,对应的$n变量会被设置为空串。要检测某个特定参数是否为空,可使用函数argisnull。例如,假设我们希望在tcl_max的两个参数中一个为空、一个非空时返回非空参数,而不是返回空值: + 在非严格函数中,如果某个参数的实际值为空值,对应的$n变量会被设置为空串。要检测某个特定参数是否为空值,可使用函数argisnull。例如,假设我们希望在tcl_max的两个参数中一个为空值、一个非空值时返回非空值参数,而不是返回空值: CREATE FUNCTION tcl_max(integer, integer) RETURNS integer AS $$ @@ -99,7 +99,7 @@ $$ LANGUAGE pltcl; - 复合类型参数会作为 Tcl 数组传递给函数。数组元素名就是该复合类型的属性名。如果传入行中的某个属性为 NULL,它就不会出现在数组中。下面是一个示例: + 复合类型参数会作为 Tcl 数组传递给函数。数组元素名就是该复合类型的属性名。如果传入行中的某个属性为空值,它就不会出现在数组中。下面是一个示例: CREATE TABLE employee ( @@ -185,7 +185,7 @@ $$ LANGUAGE pltcl; PL/Tcl 中的数据值 - 提供给 PL/Tcl 函数代码的参数值,只是将输入参数转换成文本形式(就像用SELECT语句将它们显示出来一样)。反过来,returnreturn_next命令会接受任何字符串,只要它是该函数声明结果类型或组合结果类型中指定列的可接受输入格式。 + 提供给 PL/Tcl 函数代码的参数值,只是将输入参数转换成文本形式(就像用SELECT语句将它们显示出来一样)。反过来,returnreturn_next命令会接受任何字符串,只要它是该函数声明结果类型或复合结果类型中指定列的可接受输入格式。 @@ -195,8 +195,8 @@ $$ LANGUAGE pltcl; PL/Tcl 中的全局数据 - global data - in PL/Tcl + 全局数据 + 在 PL/Tcl 中 @@ -234,7 +234,7 @@ $$ LANGUAGE pltcl; - 执行以字符串形式给出的 SQL 命令。命令出错时会引发错误。否则,spi_exec的返回值是该命令处理的行数(选出、插入、更新或删除的行),如果命令是实用程序语句则返回零。此外,如果命令是SELECT语句,则所选列的值会按下文所述放入 Tcl 变量中。 + 执行以字符串形式给出的 SQL 命令。命令出错时会引发错误。否则,spi_exec的返回值是该命令处理的行数(选出、插入、更新或删除的行),如果命令是工具语句则返回零。此外,如果命令是SELECT语句,则所选列的值会按下文所述放入 Tcl 变量中。 @@ -275,7 +275,7 @@ spi_exec -array C "SELECT * FROM pg_class" { - 如果查询结果中的某一列为空,则对应的目标变量会被unset,而不是被设值。 + 如果查询结果中的某一列为空值,则对应的目标变量会被unset,而不是被设值。 @@ -287,7 +287,7 @@ spi_exec -array C "SELECT * FROM pg_class" { 准备并保存一个查询计划以供后续执行。保存的计划会在当前会话的整个生命周期内保留。 准备查询 - 在PL/Tcl中 + 在 PL/Tcl 中 @@ -317,7 +317,7 @@ spi_exec -array C "SELECT * FROM pg_class" { 可选的-nulls值是由空格和'n'字符组成的字符串,用来告诉spi_execp哪些参数是空值。 - 如果给出,它的长度必须与value-list完全相同。如果未给出,则所有参数值都视为非空。 + 如果给出,它的长度必须与value-list完全相同。如果未给出,则所有参数值都视为非空值。 @@ -331,7 +331,7 @@ spi_exec -array C "SELECT * FROM pg_class" { CREATE FUNCTION t1_count(integer, integer) RETURNS integer AS $$ if {![ info exists GD(plan) ]} { - # prepare the saved plan on the first call + # 在首次调用时准备并保存计划 set GD(plan) [ spi_prepare \ "SELECT count(*) AS cnt FROM t1 WHERE num >= \$1 AND num <= \$2" \ [ list int4 int4 ] ] @@ -367,7 +367,7 @@ $$ LANGUAGE pltcl; 将给定字符串中的所有单引号和反斜杠字符都加倍。 - 这可用于安全地引用那些要插入到传给spi_execspi_prepare的 SQL 命令中的字符串。 + 这可用于安全地为那些要插入到传给spi_execspi_prepare的 SQL 命令中的字符串加引号。 例如,考虑如下 SQL 命令字符串: @@ -393,7 +393,7 @@ SELECT 'doesn''t' AS ret "SELECT '[ quote $val ]' AS ret" - spi_execp的一个优点是,你不必像这样对参数值做引用,因为这些参数永远不会作为 SQL 命令字符串的一部分被解析。 + spi_execp的一个优点是,你不必像这样给参数值加引号,因为这些参数永远不会作为 SQL 命令字符串的一部分被解析。 @@ -404,7 +404,7 @@ SELECT 'doesn''t' AS ret elog level msg elog - 在PL/Tcl中 + 在 PL/Tcl 中 @@ -436,8 +436,8 @@ SELECT 'doesn''t' AS ret PL/Tcl 中的触发器函数 - trigger - in PL/Tcl + 触发器 + 在 PL/Tcl 中 @@ -525,7 +525,7 @@ SELECT 'doesn''t' AS ret $NEW - 对于INSERTUPDATE动作,这是一个包含新表行值的关联数组;对于DELETE则为空。该数组以列名为索引。值为 NULL 的列不会出现在数组中。对于语句级触发器,不会设置这个变量。 + 对于INSERTUPDATE动作,这是一个包含新表行值的关联数组;对于DELETE则为空。该数组以列名为索引。值为空值的列不会出现在数组中。对于语句级触发器,不会设置这个变量。 @@ -534,7 +534,7 @@ SELECT 'doesn''t' AS ret $OLD - 对于UPDATEDELETE动作,这是一个包含旧表行值的关联数组;对于INSERT则为空。该数组以列名为索引。值为 NULL 的列不会出现在数组中。对于语句级触发器,不会设置这个变量。 + 对于UPDATEDELETE动作,这是一个包含旧表行值的关联数组;对于INSERT则为空。该数组以列名为索引。值为空值的列不会出现在数组中。对于语句级触发器,不会设置这个变量。 @@ -598,8 +598,8 @@ CREATE TRIGGER trig_mytab_modcount BEFORE INSERT OR UPDATE ON mytab PL/Tcl 中的事件触发器函数 - event trigger - in PL/Tcl + 事件触发器 + 在 PL/Tcl 中 @@ -615,7 +615,7 @@ CREATE TRIGGER trig_mytab_modcount BEFORE INSERT OR UPDATE ON mytab $TG_event - 触发器因其而被触发的事件名称。 + 该触发器所针对的事件名称。 @@ -624,7 +624,7 @@ CREATE TRIGGER trig_mytab_modcount BEFORE INSERT OR UPDATE ON mytab $TG_tag - 触发器因其而被触发的命令标签。 + 该触发器所针对的命令标签。 @@ -632,7 +632,7 @@ CREATE TRIGGER trig_mytab_modcount BEFORE INSERT OR UPDATE ON mytab - 事件触发器函数的返回值会被忽略。 + 触发器函数的返回值会被忽略。 @@ -653,8 +653,8 @@ CREATE EVENT TRIGGER tcl_a_snitch ON ddl_command_start EXECUTE FUNCTION tclsnitc PL/Tcl 中的错误处理 - exceptions - in PL/Tcl + 异常 + 在 PL/Tcl 中 @@ -682,9 +682,9 @@ if {[catch { spi_exec $sql_command }]} { if {[lindex $::errorCode 0] == "POSTGRES"} { array set errorArray $::errorCode if {$errorArray(condition) == "undefined_table"} { - # deal with missing table + # 处理表不存在的情况 } else { - # deal with some other type of SQL error + # 处理其他类型的 SQL 错误 } } } @@ -698,8 +698,8 @@ if {[catch { spi_exec $sql_command }]} { PL/Tcl 中的显式子事务 - subtransactions - in PL/Tcl + 子事务 + 在 PL/Tcl 中 @@ -797,7 +797,7 @@ CALL transaction_test1(); pltcl.start_proc (string) - pltcl.start_proc configuration parameter + pltcl.start_proc 配置参数 @@ -825,7 +825,7 @@ CALL transaction_test1(); pltclu.start_proc (string) - pltclu.start_proc configuration parameter + pltclu.start_proc 配置参数 diff --git a/zh/20/postgres-fdw.sgml b/zh/20/postgres-fdw.sgml index a703657a..e7b2e76a 100644 --- a/zh/20/postgres-fdw.sgml +++ b/zh/20/postgres-fdw.sgml @@ -38,7 +38,7 @@ - 对于每个需要被允许访问各外部服务器的数据库用户,使用 + 对于每个需要获准访问各个外部服务器的数据库用户,使用 创建用户映射。将要使用的 远程用户名和密码指定为用户映射的 userpassword 选项。 @@ -56,7 +56,7 @@ - 现在,只需从外部表执行 SELECT,即可访问其底层远程表中 + 现在,只需对外部表执行 SELECT,即可访问其底层远程表中 存储的数据。也可以使用 INSERTUPDATEDELETECOPYTRUNCATE 修改远程表。 @@ -121,8 +121,7 @@ application_name 可以出现在连接选项和 - 中的任一处,或同时出现在 - 二者中。 + 中的任一处,或同时出现在二者中。 如果两者都存在,postgres_fdw.application_name 会覆盖连接设置。与 libpq 不同, postgres_fdw 允许 application_name @@ -251,7 +250,7 @@ OPTIONS (ADD password_required 'false'); - fdw_startup_cost (floating point) + fdw_startup_cost (浮点数) 该选项可为外部服务器指定,是一个浮点值,会被加到该服务器上任何 @@ -262,7 +261,7 @@ OPTIONS (ADD password_required 'false'); - fdw_tuple_cost (floating point) + fdw_tuple_cost (浮点数) 该选项可为外部服务器指定,是一个浮点值,用作该服务器上外部表扫描的 @@ -338,8 +337,6 @@ OPTIONS (ADD password_required 'false'); - - @@ -363,7 +360,7 @@ OPTIONS (ADD password_required 'false'); 该选项是一个以逗号分隔的 PostgreSQL 扩展 名称列表,这些扩展必须在本地和远程服务器上都已安装且版本兼容。 - 属于列出扩展且为 immutable 的函数和操作符,将被视为可下推到远程服务器 + 属于列出扩展且不可变的函数和操作符,将被视为可下推到远程服务器 执行。该选项只能为外部服务器指定,不能按表指定。 @@ -405,7 +402,7 @@ OPTIONS (ADD password_required 'false'); - 该选项也适用于向外部表执行 COPY。在这种情况下, + 该选项也适用于向外部表复制数据。在这种情况下, postgres_fdw 实际一次复制的行数会以与插入场景 类似的方式确定,但由于 COPY 命令的实现限制, 最多只能为 1000 行。 @@ -597,8 +594,7 @@ OPTIONS (ADD password_required 'false'); COLLATE 选项。默认值为 true。 如果远程服务器的排序规则名称集合与本地服务器不同,则可能需要关闭此 选项;如果远程服务器运行在不同操作系统上,这种情况尤其可能发生。 - 不过,如果这样做,导入表列的排序规则极有可能与底层数据不匹配, - 从而导致查询行为异常。 + 不过,如果这样做,导入表列的排序规则就存在与底层数据不匹配的严重风险,从而导致查询行为异常。 @@ -693,7 +689,7 @@ OPTIONS (ADD password_required 'false'); 该选项控制 postgres_fdw 在连接到外部服务器时 是否使用 SCRAM 透传认证。该选项可为外部服务器或用户映射指定。 用户映射的设置会覆盖外部服务器的设置。使用 SCRAM 透传认证时, - postgres_fdw 使用 SCRAM 哈希后的凭据,而不是 + postgres_fdw 使用经 SCRAM Hash 处理的凭据,而不是 明文用户密码连接远程服务器。这样可以避免在 PostgreSQL 系统目录中 存储明文用户密码。 @@ -726,13 +722,13 @@ OPTIONS (ADD password_required 'false'); 运行 postgres_fdw 的服务器与远程服务器, 必须针对用于在 postgres_fdw 上认证到外部 - 服务器的该用户,拥有完全相同的 SCRAM secret(加密密码) + 服务器的该用户,拥有完全相同的 SCRAM 凭据(加密密码) (盐值和迭代次数都必须相同,而不仅仅是密码相同)。 因而,如果要建立到多个主机的 FDW 连接,例如用于分区外部表或分片, - 则所有主机都必须为相关用户保存完全相同的 SCRAM secret。 + 则所有主机都必须为相关用户保存完全相同的 SCRAM 凭据。 @@ -1001,8 +997,7 @@ CREATE SUBSCRIPTION my_subscription SERVER subscription_server PUBLICATION testp - 请注意,postgres_fdw 当前不支持将远程事务预备为 - 两阶段提交。 + 请注意,postgres_fdw 当前不支持为两阶段提交预备远程事务。 @@ -1013,9 +1008,9 @@ CREATE SUBSCRIPTION my_subscription SERVER subscription_server PUBLICATION testp postgres_fdw 会尽力优化远程查询,以减少从外部 服务器传输的数据量。这是通过将查询的 WHERE 子句发送到 远程服务器执行,以及不获取当前查询不需要的表列来实现的。为降低查询被 - 错误执行的风险,除非 WHERE 子句仅使用内置数据类型、 - 操作符和函数,或属于外部服务器 extensions 选项列出的 - 扩展,否则不会将其发送到远程服务器。这类子句中的操作符和函数还必须是 + 错误执行的风险,只有当 WHERE 子句使用的所有数据类型、 + 操作符和函数都是内置的,或属于外部服务器 extensions + 选项列出的扩展时,才会将该子句发送到远程服务器。这类子句中的操作符和函数还必须是 IMMUTABLE。对于 UPDATEDELETE 查询,postgres_fdw 会在 查询中不存在无法发送到远程服务器的 WHERE 子句、没有 @@ -1169,7 +1164,7 @@ CREATE SUBSCRIPTION my_subscription SERVER subscription_server PUBLICATION testp postgres_fdw.application_name (string) - postgres_fdw.application_name configuration parameter + postgres_fdw.application_name 配置参数 @@ -1183,7 +1178,7 @@ CREATE SUBSCRIPTION my_subscription SERVER subscription_server PUBLICATION testp postgres_fdw.application_name 可以是任意长度的任意 字符串,甚至可以包含非 ASCII 字符。不过,当它被传递并作为外部服务器中 的 application_name 使用时,请注意它会被截断到少于 - NAMEDATALEN 个字符。所有不可打印 ASCII 字符都会被 + NAMEDATALEN 个字符。除可打印 ASCII 字符以外的所有字符都会被 替换为C 风格的十六进制转义。 有关细节见 。 @@ -1237,7 +1232,7 @@ CREATE SUBSCRIPTION my_subscription SERVER subscription_server PUBLICATION testp %% - 字面值 % + 字面字符 % diff --git a/zh/20/protocol.sgml b/zh/20/protocol.sgml index bc09ecd2..52f82551 100644 --- a/zh/20/protocol.sgml +++ b/zh/20/protocol.sgml @@ -310,9 +310,7 @@ 前端现在必须发送一个 PasswordMessage,其中包含密码;该密码先与用户名一起经过 MD5 加密,再使用 AuthenticationMD5Password 消息中指定的 4 字节随机盐重新加密。如果密码正确,服务器响应 AuthenticationOk;否则响应 ErrorResponse。实际的 PasswordMessage 可以用 SQL 计算:concat('md5', md5(concat(md5(concat(password, username)), random-salt)))。(请记住 md5() 函数返回的是十六进制字符串。) - - 对 MD5 加密密码的支持已弃用,并将在未来版本 PostgreSQL 中移除。关于迁移到其他密码类型,请参阅 。 - + 对 MD5 加密密码的支持已弃用,并将在PostgreSQL的未来版本中移除。迁移到其他密码类型的详细信息见 @@ -915,7 +913,7 @@ SELCT 1/0; - 目前,系统会为以下参数发送 ParameterStatus: + 目前,会为一组固定的参数生成 ParameterStatus,参数如下: application_name client_encoding @@ -933,10 +931,8 @@ SELCT 1/0; standard_conforming_strings TimeZone - (default_transaction_read_onlyin_hot_standby 在 14 之前不报告; - scram_iterations 在 16 之前不报告; - search_path 在 18 之前不报告。) - 注意 server_versionserver_encodinginteger_datetimes 是启动后不可更改的伪参数。未来该集合可能变化,甚至可能变为可配置。因此,前端应忽略其不理解或不关心的 ParameterStatus。 + (14 之前的版本不报告 default_transaction_read_onlyin_hot_standby;16 之前的版本不报告 scram_iterations;18 之前的版本不报告 search_path。) + 注意,server_versionserver_encodinginteger_datetimes 是启动后不能改变的伪参数。这组参数将来可能变化,甚至可能变为可配置。因此,前端应直接忽略其不理解或不关心的参数的 ParameterStatus。 @@ -1451,7 +1447,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" CREATE_REPLICATION_SLOT slot_name [ TEMPORARY ] { PHYSICAL | LOGICAL output_plugin } [ ( option [, ...] ) ] - 创建复制槽 + CREATE_REPLICATION_SLOT @@ -1509,15 +1505,6 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - - FAILOVER [ boolean ] - - - 若为 true,则该复制槽会同步到备库,从而在故障切换后恢复逻辑复制。默认值为 false。 - - - - RESERVE_WAL [ boolean ] @@ -1534,13 +1521,14 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" SNAPSHOT { 'export' | 'use' | 'nothing' } - - 决定在逻辑复制槽初始化期间如何处理所创建的快照。'export' - 这是默认选项,将导出快照供其他会话使用。此选项不能在事务内使用。 - 'use'将为执行命令的当前事务使用快照。此选项必须在事务中使用, - 并且CREATE_REPLICATION_SLOT必须是在该事务中运行的第一个命令。 - 最后,'nothing'将像往常一样仅用于逻辑解码使用快照,但不会执行其他操作。 - + 决定如何处理初始化逻辑复制槽时创建的快照。默认选项 'export' 会导出快照供其他会话使用,此选项不能在事务内使用。'use' 会将快照用于执行该命令的当前事务;此选项必须在事务内使用,且 CREATE_REPLICATION_SLOT 必须是该事务中执行的第一条命令。最后,'nothing' 只会像平常一样将快照用于逻辑解码,不会对其执行其他操作。 + + + + + FAILOVER [ boolean ] + + 若为 true,则允许该复制槽同步到备库,以便在故障切换后恢复逻辑复制。默认值为 false。 @@ -1571,7 +1559,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" snapshot_name (text) - 该命令导出的快照标识符。该快照在此连接上执行下一条命令之前,或复制连接关闭之前有效。如果所创建的是物理复制槽,则为 null。 + 该命令导出的快照标识符。该快照在此连接上执行下一条命令之前,或复制连接关闭之前有效。如果所创建的是物理复制槽,则为空值。 @@ -1580,7 +1568,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" output_plugin (text) - 新建复制槽所使用的输出插件名称。如果所创建的是物理复制槽,则为 null。 + 新建复制槽所使用的输出插件名称。如果所创建的是物理复制槽,则为空值。 @@ -2222,7 +2210,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 指示服务器开始流式传输基本备份。 + 指示服务器开始流式传输基础备份。 在备份开始之前,系统将自动进入备份模式,并在备份完成后退出备份模式。 接受以下选项: @@ -2233,7 +2221,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" 设置备份的标签。如果未指定,则将使用base backup作为备份标签。 - 标签的引用规则与标准SQL字符串相同。 + 标签的引号使用规则与标准SQL字符串相同。 @@ -2273,11 +2261,11 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 如果设置为true,则请求生成进度报告所需的信息。这将在每个表空间的头部发送一个近似大小, + 如果设置为true,则请求生成进度报告所需的信息。这将在每个表空间的首部发送一个近似大小, 可用于计算流式传输的进度。这是通过在传输开始之前先枚举所有文件大小来计算的, 可能会对性能产生负面影响。特别是,在流式传输数据之前可能需要更长的时间。 由于备份期间数据库文件可能会发生变化,因此大小仅为近似值, - 在近似值和实际文件发送之间可能会增长或缩小。默认值为false。 + 在估算与实际发送文件之间的这段时间里可能会增长或缩小。默认值为false。 @@ -2287,7 +2275,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 设置在基本备份开始时执行的检查点类型。默认值为spread。 + 设置在基础备份开始时执行的检查点类型。默认值为spread @@ -2296,9 +2284,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" WAL [ boolean ] - - 如果设置为true,则在备份中包含必要的WAL段。这将包括在开始和停止备份之间的所有文件在基本目录tar文件的pg_wal目录中。默认值为false。 - + 如果设置为 true,则在备份中包含必要的 WAL 段。这会把开始备份到停止备份之间的所有文件放入基础目录 tar 文件内的pg_wal目录中。默认值为 false。 @@ -2386,7 +2372,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 如果为true,则在进行基本备份时验证校验和(如果已启用)。如果为false,则跳过此步骤。默认值为true。 + 如果为true,则在进行基础备份时验证校验和(如果已启用)。如果为false,则跳过此步骤。默认值为true。 @@ -2401,7 +2387,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" 除了可能包含的任何WAL文件。它还存储每个文件的大小、最后修改时间, 以及可选的校验和。 值为force-encode会强制对所有文件名进行十六进制编码; - 否则,仅对文件名为非UTF8八位序列的文件执行此类型的编码。 + 否则,仅对文件名为非 UTF8 字节序列的文件执行此类型的编码。 force-encode主要用于测试目的,以确保读取备份清单的客户端 能够处理这种情况。为了与之前的版本兼容,默认值为MANIFEST 'no' @@ -2443,14 +2429,14 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" 第二个普通结果集中的每个表空间都有一行。 - 这一行中的字段是: + 这一行中的字段是: spcoid (oid) - 表空间的OID,如果是基本目录则为null。 + 表空间的OID,如果是基础目录则为null。 @@ -2459,7 +2445,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" spclocation (text) - 表空间目录的完整路径,如果是基本目录则为null。 + 表空间目录的完整路径,如果是基础目录则为null。 @@ -2483,7 +2469,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - new archive (B) + 新归档 (B) @@ -2515,7 +2501,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 对于主数据目录,使用空字符串。对于其他表空间,使用从创建此归档的目录的完整路径。 + 对于主数据目录,使用空字符串。对于其他表空间,使用创建此归档所用目录的完整路径。 @@ -2525,7 +2511,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - manifest (B) + 清单 (B) @@ -2574,7 +2560,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - progress report (B) + 进度报告 (B) @@ -2632,13 +2618,11 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - - 不记录 WAL 的关系(Unlogged表),除了需要在恢复时重新创建(空的)不记录 WAL 的关系的init fork。 - + 不记录 WAL 的关系,但不包括恢复时重新创建(空的)不记录 WAL 的关系所需的初始化分支。 - pg_wal,包括子目录。如果备份包含WAL文件,则将包含pg_wal的合成版本,但它只包含备份工作所需的文件,而不包含其余内容。 + pg_wal,包括子目录。如果备份包含WAL文件,则将包含pg_wal的合成版本,但它只包含使备份可用所需的文件,而不包含其余内容。 @@ -2651,7 +2635,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 除了常规文件和目录之外的文件,如符号链接(除了上述列出的目录之外的符号链接)以及特殊设备和操作系统文件,将被跳过。(pg_tblspc中的符号链接将被保留。) + 除了普通文件和目录之外的文件,如符号链接(除了上述列出的目录之外的符号链接)以及特殊设备和操作系统文件,将被跳过。(pg_tblspc中的符号链接将被保留。) @@ -2681,14 +2665,12 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 逻辑复制参数 + 逻辑流复制参数 START_REPLICATION命令可以向指定复制槽关联的逻辑解码输出插件传递选项。标准(pgoutput)插件接受的选项见 - - 在上述命令中,若参数类型为 boolean,可省略 value 部分;省略等同于指定 TRUE。 - + @@ -3535,58 +3517,48 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - CancelRequest (F) - Int32 - - 消息内容的长度(以字节为单位),包括其自身。 + 消息内容的长度,以字节为单位,包括此长度字段本身。 - Int32(80877102) - - 取消请求代码。该值被选择为在最高的16位中包含1234,在最低的16位中包含5678。 - (为避免混淆,此代码不得与任何协议版本号相同。) + 取消请求代码。此值的最高 16 位为 1234,最低 16 位为 5678。(为避免混淆,此代码不能与任何协议版本号相同。) - Int32 - - 目标后端的进程ID。 + 目标后端的进程 ID。 - - Int32 + Byten - - 目标后端的 secret key。该字段长度由消息总长度决定并延伸至消息末尾,最大长度为 256 字节。 + 目标后端的密钥。此字段延伸至消息末尾,其范围由长度字段确定。密钥最长为 256 字节。 - 在协议 3.2 之前,secret key 固定为 4 字节。 - + 在协议版本 3.2 之前,密钥始终为 4 字节长。 + @@ -5667,7 +5639,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 严重性: 字段内容为ERROR, FATAL, 或 + 严重性: 字段内容为ERROR, FATAL, 或 PANIC (在错误消息中), 或 WARNING, NOTICE, DEBUG, INFO, 或 LOG (在通知消息中), @@ -5681,7 +5653,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 严重性:字段内容为ERRORFATAL或 + 严重性:字段内容为ERRORFATALPANIC(在错误消息中),或WARNINGNOTICEDEBUGINFOLOG(在通知消息中)。 这与S字段相同,只是内容不会被本地化。仅在由PostgreSQL版本9.6 @@ -5705,7 +5677,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 消息: 主要的人类可读错误消息。 + 消息: 主要的人类可读错误消息。 这应该准确但简洁(通常一行)。 总是存在。 @@ -5727,7 +5699,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 提示: 关于问题应该怎么做的一个可选建议。 + 提示: 关于问题应该怎么做的一个可选建议。 这意在与细节不同,它提供建议(可能不合适)而不是硬性事实。 可能会跨越多行。 @@ -5761,7 +5733,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 内部查询: 一个失败的内部生成命令的文本。 + 内部查询: 一个失败的内部生成命令的文本。 例如,这可能是由PL/pgSQL函数发出的SQL查询。 @@ -5794,7 +5766,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 表名: 如果错误与特定表相关联,则为表的名称。(有关表模式名称的名称,请参考模式名称字段。) + 表名: 如果错误与特定表相关联,则为表的名称。(有关表模式名称的名称,请参考模式名称字段。) @@ -5804,7 +5776,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 列名: 如果错误与特定表列相关联,则为列的名称。(请参考模式和表名字段以识别表。) + 列名: 如果错误与特定表列相关联,则为列的名称。(请参考模式和表名字段以识别表。) @@ -5814,7 +5786,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 数据类型名称: 如果错误与特定数据类型相关联,则为数据类型的名称。 + 数据类型名称: 如果错误与特定数据类型相关联,则为数据类型的名称。 (有关数据类型模式的名称,请参阅模式名称字段。) @@ -5825,7 +5797,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 约束名称: 如果错误与特定约束相关联,则为约束的名称。请参考上面列出的字段,了解相关表或域。 + 约束名称: 如果错误与特定约束相关联,则为约束的名称。请参考上面列出的字段,了解相关表或域。 (为此,即使索引不是使用约束语法创建的,也将其视为约束。) @@ -5836,7 +5808,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 文件: 报告错误的源代码位置的文件名。 + 文件: 报告错误的源代码位置的文件名。 @@ -5974,7 +5946,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 标志; 逻辑解码消息是非事务性的时为0,是事务性的时为1。 + 标志; 逻辑解码消息是非事务性的时为0,是事务性的时为1。 @@ -6048,7 +6020,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 标志; 目前未使用。 + 标志; 目前未使用。 @@ -6746,7 +6718,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 标志; 目前未使用。 + 标志; 目前未使用。 @@ -6824,6 +6796,27 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" + + Int64 (XLogRecPtr) + + + 中止操作的 LSN,仅当 streaming 设置为 parallel 时出现。 + 此字段从协议版本 4 起可用。 + + + + + + Int64 (TimestampTz) + + + 事务的中止时间戳,仅当 streaming 设置为 parallel 时出现。 + 该值为自 PostgreSQL 纪元(2000-01-01)以来的微秒数。 + 此字段从协议版本 4 起可用。 + + + + @@ -6930,7 +6923,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 标志; 目前未使用。 + 标志; 目前未使用。 @@ -7015,7 +7008,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 标志; 目前未使用。 + 标志; 目前未使用。 @@ -7100,7 +7093,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 标志; 目前未使用。 + 标志; 目前未使用。 @@ -7196,7 +7189,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 标志; 目前未使用。 + 标志; 目前未使用。 @@ -7356,76 +7349,36 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" - 自协议2.0以来的变化总结 + 自协议 2.0 以来的变更总结 - 本节为那些试图将现有客户端库更新到协议3.0的开发人员提供了一个快速变更清单。 + 本节提供一份简要的变更清单,供准备将现有客户端库更新到协议 3.0 的开发者参考。 - - 初始启动数据包使用灵活的字符串列表格式,而不是固定格式。请注意,现在可以直接在启动数据包中指定运行时参数的会话默认值。 - (实际上,以前可以使用options字段来做到这一点,但考虑到options的有限宽度以及缺乏引用值中空格的任何方法,这并不是一种非常安全的技术。) - + 初始启动包采用灵活的字符串列表格式,取代了固定格式。注意,运行时参数的会话默认值现在可以直接在启动包中指定。(实际上,以前也能通过 options 字段实现,但由于 options 的宽度有限,且无法用引号保护值中的空白字符,这种方法并不稳妥。) - - 所有消息现在都在消息类型字节后面立即跟着长度计数(除了启动数据包,它们没有类型字节)。另外请注意,PasswordMessage现在有一个类型字节。 - + 现在,所有消息都在消息类型字节之后紧跟一个长度计数(启动包除外,它没有类型字节)。另请注意,PasswordMessage 现在也有类型字节。 - - ErrorResponse和NoticeResponse('E'和'N') - 消息现在包含多个字段,客户端代码可以从中组装出所需级别的错误消息。请注意, - 单个字段通常不会以换行符结尾,而在旧协议中发送的单个字符串总是以换行符结尾。 - + ErrorResponse 和 NoticeResponse('E' 和 'N')消息现在包含多个字段,客户端代码可以利用这些字段组合出所需详细程度的错误消息。注意,各字段通常不会以换行符结束,而旧协议发送的单个字符串总是以换行符结束。 - - ReadyForQuery('Z')消息包括事务状态指示器。 - + ReadyForQuery('Z')消息包含一个事务状态指示器。 - - 二进制行和数据行消息类型之间的区别已经消失;单个数据行消息类型用于以所有格式返回数据。 - 请注意,DataRow的布局已更改,以使其更容易解析。 - 此外,二进制值的表示已更改:它不再直接与服务器的内部表示形式绑定。 - + BinaryRow 与 DataRow 消息类型不再有区别;单一的 DataRow 消息类型用于返回所有格式的数据。注意,DataRow 的布局已经改变,使其更容易解析。另外,二进制值的表示方式也已改变,不再直接取决于服务器内部的表示方式。 - - 有一个新的扩展查询子协议,它增加了前端消息类型Parse、Bind、Execute、Describe、Close、Flush和Sync, - 以及后端消息类型ParseComplete、BindComplete、PortalSuspended、ParameterDescription、NoData和CloseComplete。 - 现有客户端不必关心这个子协议,但利用它可能会提高性能或功能。 - + 新增了扩展查询子协议,其中增加了前端消息类型 Parse、Bind、Execute、Describe、Close、Flush 和 Sync,以及后端消息类型 ParseComplete、BindComplete、PortalSuspended、ParameterDescription、NoData 和 CloseComplete。现有客户端不必关注这个子协议,但使用它可能有助于改善性能或功能。 - - COPY数据现在封装到CopyData和CopyDone消息中。在COPY期间有一种明确定义的错误恢复方式。 - 特殊的\.最后一行不再需要,并且在COPY OUT期间不发送。 - (在文本模式的COPY IN期间仍然被识别为终止符,但在CSV模式中不会被识别。文本模式中的这种行为已弃用,并且最终可能会被移除。)支持二进制COPY。 - CopyInResponse和CopyOutResponse消息包括指示列数和每列格式的字段。 - + COPY 数据现在封装在 CopyData 和 CopyDone 消息中。COPY 期间的错误恢复已有明确定义的方法。不再需要特殊的最后一行 \.COPY OUT 期间也不再发送它。(在文本模式的 COPY IN 期间仍会将它识别为终止符,但在 CSV 模式中不会。文本模式的这种行为已弃用,将来可能会被移除。)现已支持二进制 COPY。CopyInResponse 和 CopyOutResponse 消息包含了表示列数及各列格式的字段。 - - FunctionCall和FunctionCallResponse消息的布局已更改。 - FunctionCall现在可以支持将NULL参数传递给函数。它还可以处理以文本或二进制格式传递参数和检索结果。 - 不再需要考虑FunctionCall可能存在安全漏洞,因为它不提供对内部服务器数据表示的直接访问。 - + FunctionCall 和 FunctionCallResponse 消息的布局已经改变。FunctionCall 现在支持向函数传递 NULL 参数,也可以使用文本或二进制格式传递参数和取得结果。由于它不再提供对服务器内部数据表示的直接访问,因此也不再有理由将 FunctionCall 视为潜在的安全漏洞。 - - 后端在连接启动期间向客户端库发送ParameterStatus('S')消息,以传达其认为对客户端库有趣的所有参数。 - 随后,每当这些参数中任何一个的活动值发生变化时,都会发送ParameterStatus消息。 - + 在连接启动期间,后端会为其认为客户端库关注的所有参数发送 ParameterStatus('S')消息。之后,只要这些参数中任何一个的当前值发生变化,就会发送一条 ParameterStatus 消息。 - - RowDescription('T')消息携带了描述行的每列的新表OID和列号字段。它还显示了每列的格式代码。 - + RowDescription('T')消息针对所描述行中的每一列,增加了表 OID 和列编号字段,并显示各列的格式代码。 - - CursorResponse('P')消息不再由后端生成。 - + 后端不再生成 CursorResponse('P')消息。 - - NotificationResponse('A')消息有一个额外的字符串字段,可以携带一个有效负载字符串, - 从NOTIFY事件发送者传递过来。 - + NotificationResponse('A')消息增加了一个字符串字段,可以携带 NOTIFY 事件发送者传来的载荷字符串。 - - EmptyQueryResponse('I')消息曾包含一个空字符串参数;现已移除。 - + EmptyQueryResponse('I')消息以前包含一个空字符串参数,现在已将其移除。 diff --git a/zh/20/queries.sgml b/zh/20/queries.sgml index fae0b5d8..8f994922 100644 --- a/zh/20/queries.sgml +++ b/zh/20/queries.sgml @@ -515,7 +515,7 @@ FROM (VALUES ('anne', 'smith'), ('bob', 'jones'), ('joe', 'blow')) - 表函数是那些生成行集合的函数,这些行可以由基本数据类型(标量类型)组成,也可以由复合数据类型(表行)组成。它们在查询的FROM子句中用法类似于表、视图或子查询。表函数返回的列可以像表、视图或子查询的列一样,出现在SELECTJOINWHERE子句中。 + 表函数是那些生成行集合的函数,这些行可以由基础类型(标量类型)组成,也可以由复合数据类型(表行)组成。它们在查询的FROM子句中用法类似于表、视图或子查询。表函数返回的列可以像表、视图或子查询的列一样,出现在SELECTJOINWHERE子句中。 @@ -553,7 +553,7 @@ UNNEST( array_expression , ... - 如果没有提供列的别名,那么对于一个返回基数据类型的函数,列名也与该函数 + 如果没有提供列的别名,那么对于一个返回基础类型的函数,列名也与该函数 名相同。对于一个返回复合类型的函数,结果列会从该类型的属性得到名称。 diff --git a/zh/20/rangetypes.sgml b/zh/20/rangetypes.sgml index f60e0af7..68409fa3 100644 --- a/zh/20/rangetypes.sgml +++ b/zh/20/rangetypes.sgml @@ -209,7 +209,7 @@ SELECT '{[3,7), [8,9)}'::int4multirange; 构造范围和多范围 - 每种范围类型都有一个与范围类型同名的构造函数。使用构造函数通常比书写范围文字常量更方便,因为这样无需对界限值进行额外引用。构造函数接受两个或三个参数。两个参数的形式构造标准形式的范围(下界包含,上界排除),而三个参数的形式则按第三个参数指定的界限形式构造范围。第三个参数必须是下列字符串之一: + 每种范围类型都有一个与范围类型同名的构造函数。使用构造函数通常比书写范围字面量更方便,因为这样无需为界限值额外加引号。构造函数接受两个或三个参数。两个参数的形式构造标准形式的范围(下界包含,上界排除),而三个参数的形式则按第三个参数指定的界限形式构造范围。第三个参数必须是下列字符串之一: ()(][)或者 diff --git a/zh/20/ref/abort.sgml b/zh/20/ref/abort.sgml index 95835c70..caed1f42 100644 --- a/zh/20/ref/abort.sgml +++ b/zh/20/ref/abort.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ABORT 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/alter_aggregate.sgml b/zh/20/ref/alter_aggregate.sgml index 7b06c41d..1a69b43c 100644 --- a/zh/20/ref/alter_aggregate.sgml +++ b/zh/20/ref/alter_aggregate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER AGGREGATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/alter_collation.sgml b/zh/20/ref/alter_collation.sgml index 85fd5517..c8273dd3 100644 --- a/zh/20/ref/alter_collation.sgml +++ b/zh/20/ref/alter_collation.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER COLLATION 7 - SQL - Language Statements + SQL - 语言语句 @@ -102,7 +102,7 @@ ALTER COLLATION name SET SCHEMA new_sche 注解 - 创建排序规则对象时,该排序规则的提供者特定版本会记录在系统目录中。 + 创建排序规则对象时,会在系统目录中记录由提供程序确定的排序规则版本。 使用该排序规则时,会将当前版本与记录的版本进行比较;如果二者不匹 配,就会发出警告,例如: diff --git a/zh/20/ref/alter_conversion.sgml b/zh/20/ref/alter_conversion.sgml index d6c8e82c..613b3ec3 100644 --- a/zh/20/ref/alter_conversion.sgml +++ b/zh/20/ref/alter_conversion.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER CONVERSION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/alter_database.sgml b/zh/20/ref/alter_database.sgml index 41dcd0fe..3cd8b071 100644 --- a/zh/20/ref/alter_database.sgml +++ b/zh/20/ref/alter_database.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER DATABASE 7 - SQL - Language Statements + SQL - 语言语句 @@ -90,9 +90,7 @@ ALTER DATABASE name RESET ALL allowconn - - 如果为假,则没有人能连接到这个数据库。 - + 如果为 false,则任何人都不能连接到该数据库。 @@ -109,7 +107,7 @@ ALTER DATABASE name RESET ALL istemplate - 如果为真,则任何具有CREATEDB权限的用户都可以从这个数据库克隆。如果为假,则只有超级用户或者该数据库的拥有者可以克隆它。 + 如果为 true,则任何具有 CREATEDB 权限的用户都可以克隆该数据库;如果为 false,则只有超级用户或该数据库的拥有者可以克隆它。 diff --git a/zh/20/ref/alter_default_privileges.sgml b/zh/20/ref/alter_default_privileges.sgml index 2fca3f17..87446d98 100644 --- a/zh/20/ref/alter_default_privileges.sgml +++ b/zh/20/ref/alter_default_privileges.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER DEFAULT PRIVILEGES 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/alter_domain.sgml b/zh/20/ref/alter_domain.sgml index a0fe964c..95aaee6c 100644 --- a/zh/20/ref/alter_domain.sgml +++ b/zh/20/ref/alter_domain.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER DOMAIN 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/alter_event_trigger.sgml b/zh/20/ref/alter_event_trigger.sgml index 326f30e1..b9407346 100644 --- a/zh/20/ref/alter_event_trigger.sgml +++ b/zh/20/ref/alter_event_trigger.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER EVENT TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -58,7 +58,7 @@ ALTER EVENT TRIGGER name RENAME TO new_owner - 该事件触发器的新拥有者的用户名。 + 该事件触发器的新所有者的用户名。 @@ -94,7 +94,7 @@ ALTER EVENT TRIGGER name RENAME TO - 另见 + 参见 diff --git a/zh/20/ref/alter_extension.sgml b/zh/20/ref/alter_extension.sgml index 9471390f..3ceae003 100644 --- a/zh/20/ref/alter_extension.sgml +++ b/zh/20/ref/alter_extension.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER EXTENSION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/alter_foreign_data_wrapper.sgml b/zh/20/ref/alter_foreign_data_wrapper.sgml index 4b26cdbb..d3f027df 100644 --- a/zh/20/ref/alter_foreign_data_wrapper.sgml +++ b/zh/20/ref/alter_foreign_data_wrapper.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER FOREIGN DATA WRAPPER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/alter_foreign_table.sgml b/zh/20/ref/alter_foreign_table.sgml index 347dbe94..2f44d4e5 100644 --- a/zh/20/ref/alter_foreign_table.sgml +++ b/zh/20/ref/alter_foreign_table.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER FOREIGN TABLE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/alter_function.sgml b/zh/20/ref/alter_function.sgml index 5de95078..5c9bc999 100644 --- a/zh/20/ref/alter_function.sgml +++ b/zh/20/ref/alter_function.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation ALTER FUNCTION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/alter_group.sgml b/zh/20/ref/alter_group.sgml index 6f8814dc..cf493632 100644 --- a/zh/20/ref/alter_group.sgml +++ b/zh/20/ref/alter_group.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER GROUP 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/alter_index.sgml b/zh/20/ref/alter_index.sgml index 06134114..978d61e1 100644 --- a/zh/20/ref/alter_index.sgml +++ b/zh/20/ref/alter_index.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER INDEX 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/alter_language.sgml b/zh/20/ref/alter_language.sgml index 7af98f20..000fe499 100644 --- a/zh/20/ref/alter_language.sgml +++ b/zh/20/ref/alter_language.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER LANGUAGE 7 - SQL - Language Statements + SQL - 语言语句 @@ -31,8 +31,8 @@ ALTER [ PROCEDURAL ] LANGUAGE name OWNER TO { ALTER LANGUAGE更改一种过程语言的定义。 - 目前唯一的功能是重命名该语言或为其指定新的拥有者。 - 要使用ALTER LANGUAGE,你必须是超级用户或者该语言的拥有者。 + 目前唯一的功能是重命名该语言或为其指定新的所有者。 + 要使用ALTER LANGUAGE,你必须是超级用户或者该语言的所有者。 @@ -62,7 +62,7 @@ ALTER [ PROCEDURAL ] LANGUAGE name OWNER TO { new_owner - 该语言的新拥有者 + 该语言的新所有者 diff --git a/zh/20/ref/alter_large_object.sgml b/zh/20/ref/alter_large_object.sgml index ad3f61f7..be30f848 100644 --- a/zh/20/ref/alter_large_object.sgml +++ b/zh/20/ref/alter_large_object.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER LARGE OBJECT 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/alter_materialized_view.sgml b/zh/20/ref/alter_materialized_view.sgml index 71ac3ade..2ef84a4c 100644 --- a/zh/20/ref/alter_materialized_view.sgml +++ b/zh/20/ref/alter_materialized_view.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER MATERIALIZED VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/alter_opclass.sgml b/zh/20/ref/alter_opclass.sgml index b1872b37..a2228963 100644 --- a/zh/20/ref/alter_opclass.sgml +++ b/zh/20/ref/alter_opclass.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER OPERATOR CLASS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/alter_operator.sgml b/zh/20/ref/alter_operator.sgml index 9537f8e9..0e908cac 100644 --- a/zh/20/ref/alter_operator.sgml +++ b/zh/20/ref/alter_operator.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER OPERATOR 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/alter_opfamily.sgml b/zh/20/ref/alter_opfamily.sgml index a0b755c2..de22efe2 100644 --- a/zh/20/ref/alter_opfamily.sgml +++ b/zh/20/ref/alter_opfamily.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER OPERATOR FAMILY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/alter_policy.sgml b/zh/20/ref/alter_policy.sgml index 30e5b6e0..e8f525cf 100644 --- a/zh/20/ref/alter_policy.sgml +++ b/zh/20/ref/alter_policy.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER POLICY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/alter_procedure.sgml b/zh/20/ref/alter_procedure.sgml index 22e333e4..2a38515b 100644 --- a/zh/20/ref/alter_procedure.sgml +++ b/zh/20/ref/alter_procedure.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER PROCEDURE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/alter_publication.sgml b/zh/20/ref/alter_publication.sgml index 124890d0..4393a83b 100644 --- a/zh/20/ref/alter_publication.sgml +++ b/zh/20/ref/alter_publication.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER PUBLICATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/alter_role.sgml b/zh/20/ref/alter_role.sgml index 6c719424..0f2402d9 100644 --- a/zh/20/ref/alter_role.sgml +++ b/zh/20/ref/alter_role.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation ALTER ROLE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/alter_routine.sgml b/zh/20/ref/alter_routine.sgml index 4fc3e18d..79191e1e 100644 --- a/zh/20/ref/alter_routine.sgml +++ b/zh/20/ref/alter_routine.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER ROUTINE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/alter_rule.sgml b/zh/20/ref/alter_rule.sgml index 9449d787..9397274c 100644 --- a/zh/20/ref/alter_rule.sgml +++ b/zh/20/ref/alter_rule.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER RULE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/alter_schema.sgml b/zh/20/ref/alter_schema.sgml index 2baf518d..13df793e 100644 --- a/zh/20/ref/alter_schema.sgml +++ b/zh/20/ref/alter_schema.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER SCHEMA 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/alter_sequence.sgml b/zh/20/ref/alter_sequence.sgml index 6638d40b..e200e719 100644 --- a/zh/20/ref/alter_sequence.sgml +++ b/zh/20/ref/alter_sequence.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER SEQUENCE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/alter_server.sgml b/zh/20/ref/alter_server.sgml index 5d870833..b3481a8a 100644 --- a/zh/20/ref/alter_server.sgml +++ b/zh/20/ref/alter_server.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER SERVER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/alter_statistics.sgml b/zh/20/ref/alter_statistics.sgml index 315ff6b7..561ca100 100644 --- a/zh/20/ref/alter_statistics.sgml +++ b/zh/20/ref/alter_statistics.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER STATISTICS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/alter_subscription.sgml b/zh/20/ref/alter_subscription.sgml index 6e4ce840..704f2cb8 100644 --- a/zh/20/ref/alter_subscription.sgml +++ b/zh/20/ref/alter_subscription.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER SUBSCRIPTION 7 - SQL - Language Statements + SQL - 语言语句 @@ -340,9 +340,7 @@ ALTER SUBSCRIPTION name RENAME TO < 跳过应用远端事务的所有更改。如果传入数据违反任何约束,逻辑复制会停止,直到问题解决。 通过使用ALTER SUBSCRIPTION ... SKIP命令,逻辑复制工作进程会跳过 - 该事务中的所有数据修改操作。若订阅者上启用了 - two_phase, - 则此选项对因在订阅者上启用该参数而已经预备的事务没有作用。逻辑复制工作进程成功跳过该事务或完成一个事务后, + 该事务中的所有数据修改操作。此选项对因在订阅者上启用 two_phase 而已经预备的事务没有作用。逻辑复制工作进程成功跳过该事务或完成一个事务后, LSN(存储在pg_subscription.subskiplsn中) 会被清除。有关逻辑复制冲突的详细信息,请参见 。 diff --git a/zh/20/ref/alter_system.sgml b/zh/20/ref/alter_system.sgml index d352cb3c..cfa6dbe4 100644 --- a/zh/20/ref/alter_system.sgml +++ b/zh/20/ref/alter_system.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER SYSTEM 7 - SQL - Language Statements + SQL - 语言语句 @@ -87,8 +87,7 @@ ALTER SYSTEM RESET ALL - 对于某些接受列表的参数,带引号的值会生成带双引号的输出,以保留空 - 格和逗号;对于另一些参数,则必须在单引号字符串内部使用双引号才能 + 对于某些接受列表的参数,带引号的值会生成带双引号的输出,以保留空白和逗号;对于另一些参数,则必须在单引号字符串内部使用双引号才能 达到这种效果。 diff --git a/zh/20/ref/alter_table.sgml b/zh/20/ref/alter_table.sgml index 8e42a830..f1811d9b 100644 --- a/zh/20/ref/alter_table.sgml +++ b/zh/20/ref/alter_table.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TABLE 7 - SQL - Language Statements + SQL - 语言语句 @@ -1025,7 +1025,7 @@ WITH ( MODULUS numeric_literal, REM - 若要强制立即回收已删除列所占的空间,可以执行任何一种会导致整表重写的ALTER TABLE形式。这样会重新构造每一行,并用空值替换被删除的列。 + 若要强制立即回收已删除列所占的空间,可以执行任何一种会导致整表重写的ALTER TABLE形式。这样会重建每一行,并用空值替换被删除的列。 diff --git a/zh/20/ref/alter_tablespace.sgml b/zh/20/ref/alter_tablespace.sgml index f0297481..7369ec94 100644 --- a/zh/20/ref/alter_tablespace.sgml +++ b/zh/20/ref/alter_tablespace.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TABLESPACE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/alter_trigger.sgml b/zh/20/ref/alter_trigger.sgml index 9fc49c8b..874811aa 100644 --- a/zh/20/ref/alter_trigger.sgml +++ b/zh/20/ref/alter_trigger.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -127,7 +127,7 @@ ALTER TRIGGER emp_stamp ON emp DEPENDS ON EXTENSION emplib; - 另见 + 参见 diff --git a/zh/20/ref/alter_tsconfig.sgml b/zh/20/ref/alter_tsconfig.sgml index 7ae05dd5..891dce66 100644 --- a/zh/20/ref/alter_tsconfig.sgml +++ b/zh/20/ref/alter_tsconfig.sgml @@ -13,7 +13,7 @@ PostgreSQL documentation ALTER TEXT SEARCH CONFIGURATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/alter_tsdictionary.sgml b/zh/20/ref/alter_tsdictionary.sgml index 9679697e..163d788b 100644 --- a/zh/20/ref/alter_tsdictionary.sgml +++ b/zh/20/ref/alter_tsdictionary.sgml @@ -13,7 +13,7 @@ PostgreSQL documentation ALTER TEXT SEARCH DICTIONARY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/alter_tsparser.sgml b/zh/20/ref/alter_tsparser.sgml index 525064c9..0844cb0a 100644 --- a/zh/20/ref/alter_tsparser.sgml +++ b/zh/20/ref/alter_tsparser.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TEXT SEARCH PARSER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/alter_tstemplate.sgml b/zh/20/ref/alter_tstemplate.sgml index fa4157f9..a3eec599 100644 --- a/zh/20/ref/alter_tstemplate.sgml +++ b/zh/20/ref/alter_tstemplate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER TEXT SEARCH TEMPLATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/alter_type.sgml b/zh/20/ref/alter_type.sgml index 58063799..6c1bc805 100644 --- a/zh/20/ref/alter_type.sgml +++ b/zh/20/ref/alter_type.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation ALTER TYPE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/alter_user.sgml b/zh/20/ref/alter_user.sgml index 362b5518..5a4f5dd4 100644 --- a/zh/20/ref/alter_user.sgml +++ b/zh/20/ref/alter_user.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER USER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/alter_user_mapping.sgml b/zh/20/ref/alter_user_mapping.sgml index 6bbeffc6..b1fc6606 100644 --- a/zh/20/ref/alter_user_mapping.sgml +++ b/zh/20/ref/alter_user_mapping.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER USER MAPPING 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/alter_view.sgml b/zh/20/ref/alter_view.sgml index 020f864b..63fcb79e 100644 --- a/zh/20/ref/alter_view.sgml +++ b/zh/20/ref/alter_view.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ALTER VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/analyze.sgml b/zh/20/ref/analyze.sgml index 27da7fc7..7e13498c 100644 --- a/zh/20/ref/analyze.sgml +++ b/zh/20/ref/analyze.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ANALYZE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/begin.sgml b/zh/20/ref/begin.sgml index 2343e66c..fc8fb312 100644 --- a/zh/20/ref/begin.sgml +++ b/zh/20/ref/begin.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation BEGIN 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/call.sgml b/zh/20/ref/call.sgml index 4a12245b..7dca6405 100644 --- a/zh/20/ref/call.sgml +++ b/zh/20/ref/call.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CALL 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/checkpoint.sgml b/zh/20/ref/checkpoint.sgml index a90266e9..f6279811 100644 --- a/zh/20/ref/checkpoint.sgml +++ b/zh/20/ref/checkpoint.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CHECKPOINT 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/close.sgml b/zh/20/ref/close.sgml index 53c793c4..788e2c9a 100644 --- a/zh/20/ref/close.sgml +++ b/zh/20/ref/close.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation CLOSE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/cluster.sgml b/zh/20/ref/cluster.sgml index af15b96b..15a8e05b 100644 --- a/zh/20/ref/cluster.sgml +++ b/zh/20/ref/cluster.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CLUSTER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/clusterdb.sgml b/zh/20/ref/clusterdb.sgml index fd83c9ba..ada12058 100644 --- a/zh/20/ref/clusterdb.sgml +++ b/zh/20/ref/clusterdb.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation clusterdb 1 - Application + 应用程序 diff --git a/zh/20/ref/comment.sgml b/zh/20/ref/comment.sgml index cfcb029d..fc470d3c 100644 --- a/zh/20/ref/comment.sgml +++ b/zh/20/ref/comment.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation COMMENT 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/commit.sgml b/zh/20/ref/commit.sgml index e054c42a..f1412973 100644 --- a/zh/20/ref/commit.sgml +++ b/zh/20/ref/commit.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation COMMIT 7 - SQL - Language Statements + SQL - 语言语句 @@ -54,7 +54,7 @@ COMMIT [ WORK | TRANSACTION ] [ AND [ NO ] CHAIN ] 参数 - chained transactions + 链式事务 diff --git a/zh/20/ref/commit_prepared.sgml b/zh/20/ref/commit_prepared.sgml index dcdba873..734b2833 100644 --- a/zh/20/ref/commit_prepared.sgml +++ b/zh/20/ref/commit_prepared.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation COMMIT PREPARED 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/copy.sgml b/zh/20/ref/copy.sgml index efbfb664..243af10a 100644 --- a/zh/20/ref/copy.sgml +++ b/zh/20/ref/copy.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation COPY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/create_access_method.sgml b/zh/20/ref/create_access_method.sgml index d4cb6d2c..7f2d9d8e 100644 --- a/zh/20/ref/create_access_method.sgml +++ b/zh/20/ref/create_access_method.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE ACCESS METHOD 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/create_aggregate.sgml b/zh/20/ref/create_aggregate.sgml index cc350683..e5bc4a3f 100644 --- a/zh/20/ref/create_aggregate.sgml +++ b/zh/20/ref/create_aggregate.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation CREATE AGGREGATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/create_cast.sgml b/zh/20/ref/create_cast.sgml index 1e2c9275..94e78f9e 100644 --- a/zh/20/ref/create_cast.sgml +++ b/zh/20/ref/create_cast.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation CREATE CAST 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/create_collation.sgml b/zh/20/ref/create_collation.sgml index 6bb3f7ab..4177c026 100644 --- a/zh/20/ref/create_collation.sgml +++ b/zh/20/ref/create_collation.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE COLLATION 7 - SQL - Language Statements + SQL - 语言语句 @@ -130,7 +130,7 @@ CREATE COLLATION [ IF NOT EXISTS ] name FROM - 指定与该排序规则关联的区域设置服务所使用的提供者。可能的值是 + 指定与该排序规则关联的区域设置服务所使用的提供程序。可能的值是 builtinicuICU (如果服务器在构建时启用了 ICU 支持)或libc。 @@ -154,7 +154,7 @@ CREATE COLLATION [ IF NOT EXISTS ] name FROM - 非确定性排序规则仅受 ICU 提供者支持。 + 非确定性排序规则仅受 ICU 提供程序支持。 @@ -238,14 +238,14 @@ CREATE COLLATION french (locale = 'fr_FR.utf8'); - 使用 ICU 提供者并采用德语电话簿排序顺序创建一种排序规则: + 使用 ICU 提供程序并采用德语电话簿排序顺序创建一种排序规则: CREATE COLLATION german_phonebook (provider = icu, locale = 'de-u-co-phonebk'); - 使用 ICU 提供者、基于 ICU 根区域设置并带有自定义规则创建一种排序规 + 使用 ICU 提供程序、基于 ICU 根区域设置并带有自定义规则创建一种排序规 则: diff --git a/zh/20/ref/create_conversion.sgml b/zh/20/ref/create_conversion.sgml index da83218a..3fcb4447 100644 --- a/zh/20/ref/create_conversion.sgml +++ b/zh/20/ref/create_conversion.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE CONVERSION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/create_database.sgml b/zh/20/ref/create_database.sgml index 0aaa9268..f03ba746 100644 --- a/zh/20/ref/create_database.sgml +++ b/zh/20/ref/create_database.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE DATABASE 7 - SQL - Language Statements + SQL - 语言语句 @@ -359,7 +359,7 @@ CREATE DATABASE nameLC_CTYPE)兼容。如果区域设置为 C (或等价的 POSIX),则允许所有编码;但对于其他区域设置,只有一种编码能够正常工作。(不过,在 Windows 上,UTF-8 编码可与任何区域设置一起使用。) CREATE DATABASE 允许超级用户不考虑区域设置而指定 - SQL_ASCII 编码,但这种选择已被废弃;如果数据库中存储了与该区域设置不兼容编码的数据,字符串函数的行为可能会出错。 + SQL_ASCII 编码,但这种选择已弃用;如果数据库中存储了与该区域设置不兼容编码的数据,字符串函数的行为可能会出错。 @@ -409,7 +409,7 @@ CREATE DATABASE music TEMPLATE template0; 在这个示例中,如果指定的区域设置与 template1 中的不同, - 则必须使用 TEMPLATE template0 子句。(如果并不不同, + 则必须使用 TEMPLATE template0 子句。(如果相同, 那么显式指定区域设置就是多余的。) diff --git a/zh/20/ref/create_domain.sgml b/zh/20/ref/create_domain.sgml index 905dd30d..420bbf83 100644 --- a/zh/20/ref/create_domain.sgml +++ b/zh/20/ref/create_domain.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE DOMAIN 7 - SQL - Language Statements + SQL - 语言语句 @@ -86,7 +86,7 @@ CREATE DOMAIN name [ AS ] 该域的可选排序规则。如果未指定排序规则,则该域的排序规则行为与其 底层数据类型相同。如果指定了COLLATE,则底层 - 类型必须是一种可排序数据类型。 + 类型必须是一种支持排序规则的数据类型。 diff --git a/zh/20/ref/create_event_trigger.sgml b/zh/20/ref/create_event_trigger.sgml index 0d45c2be..32448118 100644 --- a/zh/20/ref/create_event_trigger.sgml +++ b/zh/20/ref/create_event_trigger.sgml @@ -13,7 +13,7 @@ PostgreSQL documentation CREATE EVENT TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -44,7 +44,7 @@ CREATE EVENT TRIGGER name CREATE EVENT TRIGGER创建一个新的事件触发器。 每当指定的事件发生,并且与该触发器关联的WHEN条件(如果有)得到 满足时,就会执行该触发器函数。有关事件触发器的一般性介绍,见 - 。创建事件触发器的用户将成为其拥有者。 + 。创建事件触发器的用户将成为其所有者。 @@ -83,8 +83,7 @@ CREATE EVENT TRIGGER name - 用于过滤事件的变量名称。这使得可以将触发器限定为只在支持该变量的部 - 分情形下触发。当前唯一支持的 + 用于过滤事件的变量名称。这样可以将触发器限定为只在原本支持的部分情形下触发。当前唯一支持的 filter_variableTAG @@ -194,7 +193,7 @@ CREATE EVENT TRIGGER abort_ddl ON ddl_command_start - 另见 + 参见 diff --git a/zh/20/ref/create_extension.sgml b/zh/20/ref/create_extension.sgml index 1503df25..b503bb90 100644 --- a/zh/20/ref/create_extension.sgml +++ b/zh/20/ref/create_extension.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE EXTENSION 7 - SQL - Language Statements + SQL - 语言语句 @@ -167,7 +167,7 @@ CREATE EXTENSION [ IF NOT EXISTS ] extension_name 会在之后执行编写粗心的扩展脚本时实施攻击,使该用户获得超级用户权限。 不过,只有当特洛伊木马对象在脚本执行期间位于 search_path 中时,它们才会构成危险;这意味着它们 - 位于扩展的安装目标模式中,或位于它所依赖的某个扩展所属的模式中。 + 位于扩展的安装目标模式中,或位于它所依赖的某个扩展的目标模式中。 因此,处理那些脚本尚未经过仔细审查的扩展时,一个经验法则是: 只把它们安装到从未向任何不受信任用户授予、而且今后也不会授予 CREATE 权限的模式中。它们所依赖的任何扩展也应如此。 diff --git a/zh/20/ref/create_foreign_data_wrapper.sgml b/zh/20/ref/create_foreign_data_wrapper.sgml index eb417496..f09b8c3e 100644 --- a/zh/20/ref/create_foreign_data_wrapper.sgml +++ b/zh/20/ref/create_foreign_data_wrapper.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE FOREIGN DATA WRAPPER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/create_foreign_table.sgml b/zh/20/ref/create_foreign_table.sgml index e4ae4325..004c9ddf 100644 --- a/zh/20/ref/create_foreign_table.sgml +++ b/zh/20/ref/create_foreign_table.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE FOREIGN TABLE 7 - SQL - Language Statements + SQL - 语言语句 @@ -143,9 +143,7 @@ WITH ( MODULUS numeric_literal, REM COLLATE collation - - COLLATE子句为该列(必须是一种可排序数据类型)指定一个排序规则。如果未指定,则使用该列数据类型的默认排序规则。 - + COLLATE子句为列指定排序规则(该列必须属于支持排序规则的数据类型)。如果未指定,则使用列数据类型的默认排序规则。 diff --git a/zh/20/ref/create_function.sgml b/zh/20/ref/create_function.sgml index a6af5265..1ce28a1c 100644 --- a/zh/20/ref/create_function.sgml +++ b/zh/20/ref/create_function.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation CREATE FUNCTION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/create_group.sgml b/zh/20/ref/create_group.sgml index 92d125e8..40345c02 100644 --- a/zh/20/ref/create_group.sgml +++ b/zh/20/ref/create_group.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE GROUP 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/create_index.sgml b/zh/20/ref/create_index.sgml index d09e0c68..f18c655b 100644 --- a/zh/20/ref/create_index.sgml +++ b/zh/20/ref/create_index.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation CREATE INDEX 7 - SQL - Language Statements + SQL - 语言语句 @@ -57,7 +57,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] PostgreSQL提供了索引方法 - B-树、哈希、GiST、SP-GiST、GIN 以及 BRIN。用户也可以定义自己的索引 + B-树、hash、GiST、SP-GiST、GIN 以及 BRIN。用户也可以定义自己的索引 方法,但这相当复杂。 @@ -123,7 +123,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] 对于临时表,CREATE INDEX始终是非并发的, - 因为没有其他会话可以访问它们,而且非并发创建索引的成本更低。 + 因为没有其他会话可以访问它们,而且非并发创建索引的代价更低。 @@ -376,7 +376,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - B-树、哈希、GiST 和 SP-GiST 索引方法都接受以下参数: + B-树、hash、GiST 和 SP-GiST 索引方法都接受以下参数: @@ -566,7 +566,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - 定义当在下一页范围检测到插入时,是否为前一页范围排队执行一次提要操作 + 定义当在下一页范围检测到插入时,是否为前一页范围排队执行一次范围摘要操作 (详见)。 默认值为off @@ -580,8 +580,8 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] 并发构建索引 - index - building concurrently + 索引 + 并发构建 diff --git a/zh/20/ref/create_language.sgml b/zh/20/ref/create_language.sgml index fca9e159..5d737764 100644 --- a/zh/20/ref/create_language.sgml +++ b/zh/20/ref/create_language.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE LANGUAGE 7 - SQL - Language Statements + SQL - 语言语句 @@ -96,7 +96,7 @@ CREATE [ OR REPLACE ] [ TRUSTED ] [ PROCEDURAL ] LANGUAGE name - - FOR ALL TABLES - - - 将该发布标记为复制数据库中所有表的更改,包括未来创建的表。 - EXCEPT子句中列出的表会被排除在发布之外。 - - - - FOR TABLES IN SCHEMA @@ -182,6 +172,16 @@ CREATE PUBLICATION name + + FOR ALL TABLES + + + 将该发布标记为复制数据库中所有表的更改,包括未来创建的表。 + EXCEPT子句中列出的表会被排除在发布之外。 + + + + FOR ALL SEQUENCES diff --git a/zh/20/ref/create_role.sgml b/zh/20/ref/create_role.sgml index 1a777c5c..eac8aca1 100644 --- a/zh/20/ref/create_role.sgml +++ b/zh/20/ref/create_role.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE ROLE 7 - SQL - Language Statements + SQL - 语言语句 @@ -234,11 +234,7 @@ in sync when changing the above synopsis! 再将其改用其他格式加密)。这样便可在转储/恢复期间重新装载已加密的密码。 - - 对 MD5 加密密码的支持已被弃用,并将在未来的 - PostgreSQL版本中移除。关于迁移到其他密码类型 - 的细节,参见。 - + 对 MD5 加密密码的支持已弃用,并将在PostgreSQL的未来版本中移除。迁移到其他密码类型的详细信息见 diff --git a/zh/20/ref/create_rule.sgml b/zh/20/ref/create_rule.sgml index 6d1486c9..e8b37c6d 100644 --- a/zh/20/ref/create_rule.sgml +++ b/zh/20/ref/create_rule.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE RULE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/create_schema.sgml b/zh/20/ref/create_schema.sgml index f74ebbf1..a726fdd7 100644 --- a/zh/20/ref/create_schema.sgml +++ b/zh/20/ref/create_schema.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE SCHEMA 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/create_sequence.sgml b/zh/20/ref/create_sequence.sgml index 4b0e544f..4f4f9e4e 100644 --- a/zh/20/ref/create_sequence.sgml +++ b/zh/20/ref/create_sequence.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation CREATE SEQUENCE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/create_server.sgml b/zh/20/ref/create_server.sgml index afcad655..763ba3a7 100644 --- a/zh/20/ref/create_server.sgml +++ b/zh/20/ref/create_server.sgml @@ -13,7 +13,7 @@ PostgreSQL documentation CREATE SERVER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/create_statistics.sgml b/zh/20/ref/create_statistics.sgml index 271c5813..4f019e9c 100644 --- a/zh/20/ref/create_statistics.sgml +++ b/zh/20/ref/create_statistics.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE STATISTICS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/create_subscription.sgml b/zh/20/ref/create_subscription.sgml index 824aa964..62cc8bc7 100644 --- a/zh/20/ref/create_subscription.sgml +++ b/zh/20/ref/create_subscription.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE SUBSCRIPTION 7 - SQL - Language Statements + SQL - 语言语句 @@ -304,7 +304,7 @@ CREATE SUBSCRIPTION subscription_nameparallel,表示如果有可用的并行应用工作进程, 接收到的更改会直接通过其中之一应用。如果没有空闲的并行应用工作进程 可以处理流式事务,那么这些更改会写入临时文件,并在事务提交后再应用。 - 注意,如果并行应用工作进程中发生错误,远端事务的 finish LSN + 注意,如果并行应用工作进程中发生错误,远端事务的 完成 LSN 可能不会记录到服务器日志中。此参数对序列没有影响。 diff --git a/zh/20/ref/create_table.sgml b/zh/20/ref/create_table.sgml index a1e0d11c..bff35863 100644 --- a/zh/20/ref/create_table.sgml +++ b/zh/20/ref/create_table.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation CREATE TABLE 7 - SQL - Language Statements + SQL - 语言语句 @@ -86,7 +86,7 @@ COMPRESSION compression_method [ ON DELETE referential_action ] [ ON UPDATE referential_action ] } [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ] [ ENFORCED | NOT ENFORCED ] -and table_constraint is: +table_constraint为: [ CONSTRAINT constraint_name ] { CHECK ( expression ) [ NO INHERIT ] | @@ -99,28 +99,28 @@ COMPRESSION compression_method class="parameter">referential_action ] [ ON UPDATE referential_action ] } [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ] [ ENFORCED | NOT ENFORCED ] -and like_option is: +like_option为: { INCLUDING | EXCLUDING } { COMMENTS | COMPRESSION | CONSTRAINTS | DEFAULTS | GENERATED | IDENTITY | INDEXES | STATISTICS | STORAGE | ALL } -and partition_bound_spec is: +partition_bound_spec为: IN ( partition_bound_expr [, ...] ) | FROM ( { partition_bound_expr | MINVALUE | MAXVALUE } [, ...] ) TO ( { partition_bound_expr | MINVALUE | MAXVALUE } [, ...] ) | WITH ( MODULUS numeric_literal, REMAINDER numeric_literal ) -index_parameters (用于 UNIQUEPRIMARY KEYEXCLUDE 约束) 为: +index_parameters (用于 UNIQUEPRIMARY KEYEXCLUDE 约束)为: [ INCLUDE ( column_name [, ... ] ) ] [ WITH ( storage_parameter [= value] [, ... ] ) ] [ USING INDEX TABLESPACE tablespace_name ] -exclude_element (用于 EXCLUDE 约束) 为: +exclude_element (用于 EXCLUDE 约束)为: { column_name | ( expression ) } [ COLLATE collation ] [ opclass [ ( opclass_parameter = value [, ... ] ) ] ] [ ASC | DESC ] [ NULLS { FIRST | LAST } ] -referential_action (用于 FOREIGN KEY/REFERENCES 约束) 为: +referential_action (用于 FOREIGN KEY/REFERENCES 约束)为: { NO ACTION | RESTRICT | CASCADE | SET NULL [ ( column_name [, ... ] ) ] | SET DEFAULT [ ( column_name [, ... ] ) ] } @@ -171,7 +171,7 @@ WITH ( MODULUS numeric_literal, REM - TEMPORARY or TEMP + TEMPORARYTEMP @@ -186,7 +186,7 @@ WITH ( MODULUS numeric_literal, REM - 可以在 TEMPORARYTEMP 前写 GLOBALLOCAL。这在当前的 PostgreSQL 中没有区别,而且已废弃;见下文 。 + 可以在 TEMPORARYTEMP 前写 GLOBALLOCAL。这在当前的 PostgreSQL 中没有区别,而且已弃用;见下文 @@ -238,7 +238,7 @@ WITH ( MODULUS numeric_literal, REM - 类型化表的列名和数据类型始终与其派生类型相同,因此不能再指定额外的列。但 CREATE TABLE 命令仍可为该表添加默认值和约束,并指定存储参数。 + 类型化表的列名和数据类型始终与其所基于的类型相同,因此不能再指定额外的列。但 CREATE TABLE 命令仍可为该表添加默认值和约束,并指定存储参数。 @@ -269,10 +269,7 @@ WITH ( MODULUS numeric_literal, REM COLLATE collation - - COLLATE 子句为该列(必须是一种可排序数据类型)赋予一个排序规则。 - 如果没有指定,将使用该列数据类型的默认排序规则。 - + COLLATE子句为列指定排序规则(该列必须属于支持排序规则的数据类型)。如果未指定,则使用列数据类型的默认排序规则。 @@ -281,7 +278,7 @@ WITH ( MODULUS numeric_literal, REM STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN | DEFAULT } TOAST - per-column storage settings + 逐列存储设置 @@ -440,13 +437,13 @@ WITH ( MODULUS numeric_literal, REM 还要注意,某些元素类型(如 timestamp)具有 - "infinity" 的概念,那只是另一种可存储的值。这不同于 + “无穷大” 的概念,那只是另一种可存储的值。这不同于 MINVALUEMAXVALUE,后两者并非可存储 的实际值,而只是表示值无界的方式。MAXVALUE 可以视为大于任何 - 其他值,包括 "infinity";MINVALUE 可以视为小于任何 - 其他值,包括 "minus infinity"。因此,范围 + 其他值,包括 “无穷大”;MINVALUE 可以视为小于任何 + 其他值,包括 “负无穷大”。因此,范围 FROM ('infinity') TO (MAXVALUE) 并不是空范围;它只允许存储 - 一个值 — "infinity"。 + 一个值 — “无穷大”。 @@ -564,7 +561,7 @@ WITH ( MODULUS numeric_literal, REM INCLUDING GENERATED - 会复制被复制列定义中的生成表达式以及 STORED/VIRTUAL 的选择。默认情况下,新列将是常规基表列。 + 会复制被复制列定义中的生成表达式以及 STORED/VIRTUAL 的选择。默认情况下,新列将是普通基础列。 @@ -677,7 +674,7 @@ WITH ( MODULUS numeric_literal, REM - 一个被标记为NO INHERIT的约束将不会传播到子表。 + 标记为 NO INHERIT 的约束不会传播到子表。 @@ -704,7 +701,7 @@ WITH ( MODULUS numeric_literal, REM - GENERATED ALWAYS AS ( generation_expr ) [ STORED | VIRTUAL ]generated column + GENERATED ALWAYS AS ( generation_expr ) [ STORED | VIRTUAL ]生成列 @@ -816,7 +813,7 @@ WITH ( MODULUS numeric_literal, REM 可选的 INCLUDE 子句会向该索引添加一个或多个仅作为 - payload 的列:对这些列不强制唯一性,而且该索引也不能据此 + 载荷 的列:对这些列不强制唯一性,而且该索引也不能据此 进行搜索。不过,它们可以通过仅索引扫描取回。注意,尽管约束不在包含列上 强制执行,它仍然依赖于这些列。因此,对这类列执行某些操作(例如 DROP COLUMN)可能导致约束和索引被级联删除。 @@ -863,7 +860,7 @@ WITH ( MODULUS numeric_literal, REM 可选的 INCLUDE 子句会向该索引添加一个或多个仅作为 - payload 的列:对这些列不强制唯一性,而且该索引也不能据此 + 载荷 的列:对这些列不强制唯一性,而且该索引也不能据此 进行搜索。不过,它们可以通过仅索引扫描取回。注意,尽管约束不在包含列上 强制执行,它仍然依赖于这些列。因此,对这类列执行某些操作(例如 DROP COLUMN)可能导致约束和索引被级联删除。 @@ -899,7 +896,7 @@ WITH ( MODULUS numeric_literal, REM 访问方法必须支持 amgettuple(见 );目前这意味着不能使用 GIN。 虽然允许,但在排他约束上使用 B-树或 hash 索引意义不大,因为它们做不到 - 比普通唯一约束更好的事情。因此,实践中访问方法几乎总会是 + 比普通唯一约束更好的事情。因此,实践中访问方法总是 GiSTSP-GiST @@ -959,7 +956,7 @@ WITH ( MODULUS numeric_literal, REM - 对于每一对引用列和被引用列,如果它们属于可排序数据类型,则两者的排序规 + 对于每一对引用列和被引用列,如果它们属于支持排序规则的数据类型,则两者的排序规 则要么都必须是确定性的,要么必须完全相同。这样可以确保两列对“相等”具 有一致的定义。 @@ -1062,10 +1059,7 @@ WITH ( MODULUS numeric_literal, REM - - 如果被引用列经常发生变化,那么最好在引用列上添加一个索引,以便更高效地 - 执行与该外键约束相关的引用动作。 - + 如果被引用列经常变化,可以考虑在引用列上添加索引,使与外键约束关联的引用操作能够更高效地执行。 @@ -1109,7 +1103,7 @@ WITH ( MODULUS numeric_literal, REM NOT ENFORCED - 当约束为 ENFORCED 时,数据库系统会在适当时机检查该约束(按需要在每条语句后或事务结束时),这是默认行为。若约束为 NOT ENFORCED,数据库系统将不再检查该约束,改由应用代码保证约束成立。对于不影响结果正确性的优化决策,数据库系统仍可能假定数据满足该约束。 + 当约束为 ENFORCED 时,数据库系统会在适当时机检查该约束(按需要在每条语句后或事务结束时),以确保约束成立。这是默认行为。若约束为 NOT ENFORCED,数据库系统将不再检查该约束,改由应用代码保证约束成立。对于不影响结果正确性的优化决策,数据库系统仍可能假定数据满足该约束。 @@ -1241,7 +1235,7 @@ WITH ( MODULUS numeric_literal, REM 存储参数 - storage parameters + 存储参数 @@ -1263,7 +1257,7 @@ WITH ( MODULUS numeric_literal, REM fillfactor (integer) - fillfactor storage parameter + fillfactor 存储参数 @@ -1285,7 +1279,7 @@ WITH ( MODULUS numeric_literal, REM toast_tuple_target (integer) - toast_tuple_target storage parameter + toast_tuple_target 存储参数 @@ -1293,7 +1287,7 @@ WITH ( MODULUS numeric_literal, REM toast_tuple_target 指定在尝试压缩和/或将长列值移入 TOAST 表之前所需的最小元组长度,同时也是一旦开始 TOAST 化后试图将长度 - 缩减到的目标长度。这会影响标记为 External(用于移动)、Main(用于压缩) + 缩减到其以下的目标长度。这会影响标记为 External(用于移动)、Main(用于压缩) 或 Extended(用于两者)的列,并且只适用于新元组。对现有行没有影响。默认 情况下,该参数被设置为至少允许每个块容纳 4 个元组,在默认块大小下即为 2040 字节。有效值介于 128 字节与(块大小减去页头)之间,默认上限为 @@ -1308,13 +1302,13 @@ WITH ( MODULUS numeric_literal, REM parallel_workers (integer) - parallel_workers storage parameter + parallel_workers 存储参数 - 该参数设置在对该表执行并行扫描时可用于辅助扫描的工作进程数量。若未设置, + 该参数设置在对该表执行并行扫描时用于辅助扫描的工作进程数量。若未设置, 系统会根据关系大小决定一个值。规划器或使用并行扫描的实用命令实际选择的 工作进程数量可能更少,例如可能受 设置所限。 @@ -1326,7 +1320,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_enabled, toast.autovacuum_enabled (boolean) - autovacuum_enabled storage parameter + autovacuum_enabled 存储参数 @@ -1349,7 +1343,7 @@ WITH ( MODULUS numeric_literal, REM vacuum_index_cleanup, toast.vacuum_index_cleanup (enum) - vacuum_index_cleanup storage parameter + vacuum_index_cleanup 存储参数 @@ -1373,7 +1367,7 @@ WITH ( MODULUS numeric_literal, REM vacuum_truncate, toast.vacuum_truncate (boolean) vacuum_truncate - storage parameter + 存储参数 @@ -1404,7 +1398,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_vacuum_threshold, toast.autovacuum_vacuum_threshold (integer) autovacuum_vacuum_threshold - storage parameter + 存储参数 @@ -1419,7 +1413,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_vacuum_max_threshold, toast.autovacuum_vacuum_max_threshold (integer) autovacuum_vacuum_max_threshold - storage parameter + 存储参数 @@ -1434,7 +1428,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_vacuum_scale_factor, toast.autovacuum_vacuum_scale_factor (floating point) autovacuum_vacuum_scale_factor - storage parameter + 存储参数 @@ -1450,7 +1444,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_vacuum_insert_threshold, toast.autovacuum_vacuum_insert_threshold (integer) autovacuum_vacuum_insert_threshold - storage parameter + 存储参数 @@ -1467,7 +1461,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_vacuum_insert_scale_factor, toast.autovacuum_vacuum_insert_scale_factor (floating point) autovacuum_vacuum_insert_scale_factor - storage parameter + 存储参数 @@ -1483,7 +1477,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_analyze_threshold (integer) autovacuum_analyze_threshold - storage parameter + 存储参数 @@ -1499,7 +1493,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_analyze_scale_factor (floating point) autovacuum_analyze_scale_factor - storage parameter + 存储参数 @@ -1515,7 +1509,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_vacuum_cost_delay, toast.autovacuum_vacuum_cost_delay (floating point) autovacuum_vacuum_cost_delay - storage parameter + 存储参数 @@ -1531,7 +1525,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_vacuum_cost_limit, toast.autovacuum_vacuum_cost_limit (integer) autovacuum_vacuum_cost_limit - storage parameter + 存储参数 @@ -1546,7 +1540,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_freeze_min_age, toast.autovacuum_freeze_min_age (integer) - autovacuum_freeze_min_age storage parameter + autovacuum_freeze_min_age 存储参数 @@ -1564,7 +1558,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_freeze_max_age, toast.autovacuum_freeze_max_age (integer) autovacuum_freeze_max_age - storage parameter + 存储参数 @@ -1581,7 +1575,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_freeze_table_age, toast.autovacuum_freeze_table_age (integer) - autovacuum_freeze_table_age storage parameter + autovacuum_freeze_table_age 存储参数 @@ -1596,7 +1590,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_multixact_freeze_min_age, toast.autovacuum_multixact_freeze_min_age (integer) - autovacuum_multixact_freeze_min_age storage parameter + autovacuum_multixact_freeze_min_age 存储参数 @@ -1615,7 +1609,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_multixact_freeze_max_age, toast.autovacuum_multixact_freeze_max_age (integer) autovacuum_multixact_freeze_max_age - storage parameter + 存储参数 @@ -1633,7 +1627,7 @@ WITH ( MODULUS numeric_literal, REM autovacuum_multixact_freeze_table_age, toast.autovacuum_multixact_freeze_table_age (integer) - autovacuum_multixact_freeze_table_age storage parameter + autovacuum_multixact_freeze_table_age 存储参数 @@ -1649,7 +1643,7 @@ WITH ( MODULUS numeric_literal, REM log_autovacuum_min_duration, toast.log_autovacuum_min_duration (integer) log_autovacuum_min_duration - storage parameter + 存储参数 @@ -1678,7 +1672,7 @@ WITH ( MODULUS numeric_literal, REM vacuum_max_eager_freeze_failure_rate, toast.vacuum_max_eager_freeze_failure_rate (floating point) vacuum_max_eager_freeze_failure_rate - storage parameter + 存储参数 @@ -1692,7 +1686,7 @@ WITH ( MODULUS numeric_literal, REM user_catalog_table (boolean) - user_catalog_table storage parameter + user_catalog_table 存储参数 @@ -1714,7 +1708,7 @@ WITH ( MODULUS numeric_literal, REM 注解 - PostgreSQL为每一个唯一约束和主键约束创建一个索引来强制唯一性。因此,没有必要显式地为主键列创建一个索引(详见)。 + PostgreSQL为每一个唯一约束和主键约束自动创建一个索引来强制唯一性。因此,没有必要显式地为主键列创建一个索引(详见)。 @@ -2144,9 +2138,9 @@ CREATE TABLE cities_partdef NULL 约束(实际上并不是约束)是 - PostgreSQL 对 SQL 标准的扩展;它也被其他一些数 - 据库系统采纳,以便兼容(以及与对称的 NOT NULL 约束保持一 - 致)。由于它本来就是任意列的默认值,所以它的存在只是噪声。 + PostgreSQL 对 SQL 标准的扩展;提供它是为了 + 与其他一些数据库系统兼容(以及与 NOT NULL 约束保持 + 对称)。由于它本来就是任意列的默认情况,所以它的存在只是噪声。 @@ -2176,12 +2170,12 @@ CREATE TABLE cities_partdef - 零列表 + 零列的表 PostgreSQL 允许创建没有列的表(例如 CREATE TABLE foo();)。这是对 SQL 标准的扩展,标准不允许 - 零列表。零列表本身并不十分有用,但若禁止它们,就会让 + 零列的表。零列的表本身并不十分有用,但若禁止它们,就会让 ALTER TABLE DROP COLUMN 出现奇怪的特殊情况,因此忽略这 一规范限制看起来更整洁。 @@ -2194,7 +2188,7 @@ CREATE TABLE cities_partdef PostgreSQL 允许一个表拥有多个标识列。 该标准指定一个表最多只能有一个标识列。 - 这主要是为了给模式更改或迁移提供更大的灵活性。 + 放宽这一限制主要是为了给模式更改或迁移提供更大的灵活性。 请注意,INSERT 命令仅支持一个适用于整个语句的覆盖子 句,因此对行为不同的多个标识列支持并不好。 @@ -2247,8 +2241,7 @@ CREATE TABLE cities_partdef 类型化表 - 类型化表实现了 SQL 标准的一个子集。按照标准,类型化表除了具有与底层组合 - 类型相对应的列之外,还应有一个额外的自引用列。 + 类型化表实现了 SQL 标准的一个子集。按照标准,类型化表除了具有与底层复合类型相对应的列之外,还应有一个额外的自引用列PostgreSQL 不显式支持自引用列。 diff --git a/zh/20/ref/create_table_as.sgml b/zh/20/ref/create_table_as.sgml index c4380b1d..74ed70c0 100644 --- a/zh/20/ref/create_table_as.sgml +++ b/zh/20/ref/create_table_as.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation CREATE TABLE AS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/create_tablespace.sgml b/zh/20/ref/create_tablespace.sgml index 32b0dbb1..88106ccd 100644 --- a/zh/20/ref/create_tablespace.sgml +++ b/zh/20/ref/create_tablespace.sgml @@ -13,7 +13,7 @@ PostgreSQL documentation CREATE TABLESPACE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/create_transform.sgml b/zh/20/ref/create_transform.sgml index 247e6a0f..ecea2c1e 100644 --- a/zh/20/ref/create_transform.sgml +++ b/zh/20/ref/create_transform.sgml @@ -13,7 +13,7 @@ PostgreSQL documentation CREATE TRANSFORM 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/create_trigger.sgml b/zh/20/ref/create_trigger.sgml index d3d58161..fcc7f155 100644 --- a/zh/20/ref/create_trigger.sgml +++ b/zh/20/ref/create_trigger.sgml @@ -11,13 +11,13 @@ PostgreSQL documentation 过渡表 - ephemeral named relation + 临时命名关系 CREATE TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -70,7 +70,7 @@ CREATE [ OR REPLACE ] [ CONSTRAINT ] TRIGGER name UPDATEDELETE之前); 也可以在该操作完成之后引发(即在检查约束以及完成 INSERTUPDATE或 - DELETE之后);或者改为执行该操作 + DELETE之后);或者取代该操作执行 (用于视图上的插入、更新或删除)。如果触发器在事件之前引发,或者改为取代该事件执行, 则它可以跳过对当前行的操作,或者修改待插入的行 (仅适用于INSERTUPDATE操作)。 @@ -178,7 +178,7 @@ CREATE [ OR REPLACE ] [ CONSTRAINT ] TRIGGER name 调整其引发时机。约束触发器必须是普通表(不是外部表)上的 AFTER ROW 触发器。它们既可以在导致触发事件的语句结束时引发, 也可以在包含它的事务结束时引发;后一种情况称为延迟。 - 也可以使用SET CONSTRAINTS强制挂起的延迟触发立即引发。 + 也可以使用SET CONSTRAINTS强制尚待执行的延迟触发器立即引发。 约束触发器应当在其所实现的约束遭到违反时抛出异常。 @@ -403,7 +403,7 @@ UPDATE OF column_name1 [, column_name2CREATE TRIGGER的语法中,关键字 FUNCTIONPROCEDURE 是等价的, 但无论如何,被引用的对象都必须是函数而不是过程。 - 这里使用 PROCEDURE 关键字只是出于历史原因,并且已被废弃。 + 这里使用 PROCEDURE 关键字只是出于历史原因,并且已被弃用。 diff --git a/zh/20/ref/create_tsconfig.sgml b/zh/20/ref/create_tsconfig.sgml index 52c43127..52970b36 100644 --- a/zh/20/ref/create_tsconfig.sgml +++ b/zh/20/ref/create_tsconfig.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TEXT SEARCH CONFIGURATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/create_tsdictionary.sgml b/zh/20/ref/create_tsdictionary.sgml index 7a06b430..c45a7240 100644 --- a/zh/20/ref/create_tsdictionary.sgml +++ b/zh/20/ref/create_tsdictionary.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TEXT SEARCH DICTIONARY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/create_tsparser.sgml b/zh/20/ref/create_tsparser.sgml index d0c11ba5..358152ce 100644 --- a/zh/20/ref/create_tsparser.sgml +++ b/zh/20/ref/create_tsparser.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TEXT SEARCH PARSER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/create_tstemplate.sgml b/zh/20/ref/create_tstemplate.sgml index 947b18b9..702233e4 100644 --- a/zh/20/ref/create_tstemplate.sgml +++ b/zh/20/ref/create_tstemplate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE TEXT SEARCH TEMPLATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/create_type.sgml b/zh/20/ref/create_type.sgml index 45a4d93a..879d0a86 100644 --- a/zh/20/ref/create_type.sgml +++ b/zh/20/ref/create_type.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation CREATE TYPE 7 - SQL - Language Statements + SQL - 语言语句 @@ -96,7 +96,7 @@ CREATE TYPE name 复合类型 - 第一种形式的CREATE TYPE创建复合类型。组合 + 第一种形式的CREATE TYPE创建复合类型。复合 类型由属性名和数据类型列表指定。如果某个属性的数据类型支持排序规 则,还可以指定该属性的排序规则。复合类型本质上与表的行类型相同, 但如果目的只是定义一种类型,使用CREATE TYPE @@ -322,7 +322,7 @@ CREATE TYPE name 数才知道,但仍有若干内部表示属性必须向 PostgreSQL声明。其中最重要的是 internallength。 - 基础数据类型可以是定长的,此时internallength为正整数;也可 以是变长的,此时将internallength设为 @@ -427,7 +427,7 @@ CREATE TYPE name collatable为真,则 该类型的列定义和表达式可以通过COLLATE子句携 带排序规则信息。是否实际使用这些排序规则信息取决于操作该类型的函 - 数实现;仅仅把类型标记为 collatable 并不会自动实现这一点。 + 数实现;仅仅把类型标记为支持排序规则并不会自动实现这一点。 @@ -876,7 +876,7 @@ CREATE TYPE float8_range AS RANGE (subtype = float8, subtype_diff = float8mi); - 这个示例创建基础数据类型box,然后在表定义中使用它: + 这个示例创建基础类型box,然后在表定义中使用它: CREATE TYPE box; diff --git a/zh/20/ref/create_user.sgml b/zh/20/ref/create_user.sgml index fe0be7fc..b5eb5a87 100644 --- a/zh/20/ref/create_user.sgml +++ b/zh/20/ref/create_user.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE USER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/create_user_mapping.sgml b/zh/20/ref/create_user_mapping.sgml index fe556318..1abe6abd 100644 --- a/zh/20/ref/create_user_mapping.sgml +++ b/zh/20/ref/create_user_mapping.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation CREATE USER MAPPING 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/create_view.sgml b/zh/20/ref/create_view.sgml index c312b669..2d75ebf5 100644 --- a/zh/20/ref/create_view.sgml +++ b/zh/20/ref/create_view.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation CREATE VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/createdb.sgml b/zh/20/ref/createdb.sgml index 554d7377..0a70cb6a 100644 --- a/zh/20/ref/createdb.sgml +++ b/zh/20/ref/createdb.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation createdb 1 - Application + 应用程序 diff --git a/zh/20/ref/createuser.sgml b/zh/20/ref/createuser.sgml index 0451cadd..eba45357 100644 --- a/zh/20/ref/createuser.sgml +++ b/zh/20/ref/createuser.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation createuser 1 - Application + 应用程序 @@ -139,7 +139,7 @@ PostgreSQL documentation - (已废弃) + (已弃用) diff --git a/zh/20/ref/deallocate.sgml b/zh/20/ref/deallocate.sgml index 27b9da86..6dea341e 100644 --- a/zh/20/ref/deallocate.sgml +++ b/zh/20/ref/deallocate.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation DEALLOCATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/declare.sgml b/zh/20/ref/declare.sgml index ed389e4d..9276a0e3 100644 --- a/zh/20/ref/declare.sgml +++ b/zh/20/ref/declare.sgml @@ -22,7 +22,7 @@ PostgreSQL documentation DECLARE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/delete.sgml b/zh/20/ref/delete.sgml index a1ddcc15..8d3e2b7a 100644 --- a/zh/20/ref/delete.sgml +++ b/zh/20/ref/delete.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DELETE 7 - SQL - Language Statements + SQL - 语言语句 @@ -159,9 +159,8 @@ DELETE FROM [ ONLY ] table_name [ * start_time - 在时态删除中要更改的最早时间(含)。这必须是与 - range_column_name中的 - 范围基类型匹配的值。这里的 NULL 值表示删除的起点没有下界(与范围类型一样)。 + 时态删除中要更改的最早时间(含)。这必须是与 + range_column_name所对应范围的基础类型匹配的值。此处的 NULL 值表示删除的起点没有下界(与范围类型一样)。 @@ -170,9 +169,8 @@ DELETE FROM [ ONLY ] table_name [ * end_time - 在时态删除中要更改的最晚时间(不含)。这必须是与 - range_column_name中的 - 范围基类型匹配的值。这里的 NULL 值表示删除的终点没有上界(与范围类型一样)。 + 时态删除中要更改的最晚时间(不含)。这必须是与 + range_column_name所对应范围的基础类型匹配的值。此处的 NULL 值表示删除的终点没有上界(与范围类型一样)。 diff --git a/zh/20/ref/discard.sgml b/zh/20/ref/discard.sgml index 29d4ea8d..f6572252 100644 --- a/zh/20/ref/discard.sgml +++ b/zh/20/ref/discard.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DISCARD 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/do.sgml b/zh/20/ref/do.sgml index 2ea6566a..cdbf189e 100644 --- a/zh/20/ref/do.sgml +++ b/zh/20/ref/do.sgml @@ -15,7 +15,7 @@ PostgreSQL documentation DO 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/drop_access_method.sgml b/zh/20/ref/drop_access_method.sgml index 407ec4cd..646100e1 100644 --- a/zh/20/ref/drop_access_method.sgml +++ b/zh/20/ref/drop_access_method.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP ACCESS METHOD 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/drop_aggregate.sgml b/zh/20/ref/drop_aggregate.sgml index 1c8a1122..9fd7ea4b 100644 --- a/zh/20/ref/drop_aggregate.sgml +++ b/zh/20/ref/drop_aggregate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP AGGREGATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/drop_cast.sgml b/zh/20/ref/drop_cast.sgml index 73860e3c..5e330ae0 100644 --- a/zh/20/ref/drop_cast.sgml +++ b/zh/20/ref/drop_cast.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP CAST 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/drop_collation.sgml b/zh/20/ref/drop_collation.sgml index b90849fc..b10b3206 100644 --- a/zh/20/ref/drop_collation.sgml +++ b/zh/20/ref/drop_collation.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP COLLATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/drop_conversion.sgml b/zh/20/ref/drop_conversion.sgml index b63d1291..35009708 100644 --- a/zh/20/ref/drop_conversion.sgml +++ b/zh/20/ref/drop_conversion.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP CONVERSION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/drop_database.sgml b/zh/20/ref/drop_database.sgml index 9bbd949f..10817b69 100644 --- a/zh/20/ref/drop_database.sgml +++ b/zh/20/ref/drop_database.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP DATABASE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/drop_domain.sgml b/zh/20/ref/drop_domain.sgml index d43f95c6..b292b189 100644 --- a/zh/20/ref/drop_domain.sgml +++ b/zh/20/ref/drop_domain.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP DOMAIN 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/drop_event_trigger.sgml b/zh/20/ref/drop_event_trigger.sgml index 80020f78..f4f0053f 100644 --- a/zh/20/ref/drop_event_trigger.sgml +++ b/zh/20/ref/drop_event_trigger.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP EVENT TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -30,7 +30,7 @@ DROP EVENT TRIGGER [ IF EXISTS ] name DROP EVENT TRIGGER移除一个现有的事件触发器。 - 要执行此命令,当前用户必须是该事件触发器的拥有者。 + 要执行此命令,当前用户必须是该事件触发器的所有者。 @@ -99,7 +99,7 @@ DROP EVENT TRIGGER snitch; - 另见 + 参见 diff --git a/zh/20/ref/drop_extension.sgml b/zh/20/ref/drop_extension.sgml index 5eb04c04..ccccb0b1 100644 --- a/zh/20/ref/drop_extension.sgml +++ b/zh/20/ref/drop_extension.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP EXTENSION 7 - SQL - Language Statements + SQL - 语言语句 @@ -59,8 +59,8 @@ DROP EXTENSION [ IF EXISTS ] name [ name - 已安装扩展的名称。 - + 一个已安装扩展的名称。 + @@ -95,7 +95,7 @@ DROP EXTENSION [ IF EXISTS ] name [ DROP EXTENSION hstore; - 如果数据库中正在使用hstore的任何对象, + 如果数据库中使用了hstore的任何对象, 例如某些表具有hstore类型的列,则该命令会失败。 加上CASCADE选项可以强制一并移除这些依赖对象。 diff --git a/zh/20/ref/drop_foreign_data_wrapper.sgml b/zh/20/ref/drop_foreign_data_wrapper.sgml index 9902c875..6f781f31 100644 --- a/zh/20/ref/drop_foreign_data_wrapper.sgml +++ b/zh/20/ref/drop_foreign_data_wrapper.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP FOREIGN DATA WRAPPER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/drop_foreign_table.sgml b/zh/20/ref/drop_foreign_table.sgml index 0b4d0bbd..c420e4ba 100644 --- a/zh/20/ref/drop_foreign_table.sgml +++ b/zh/20/ref/drop_foreign_table.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP FOREIGN TABLE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/drop_function.sgml b/zh/20/ref/drop_function.sgml index 32e1de58..f80cc1d8 100644 --- a/zh/20/ref/drop_function.sgml +++ b/zh/20/ref/drop_function.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP FUNCTION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/drop_group.sgml b/zh/20/ref/drop_group.sgml index f43389ca..4ee8fc55 100644 --- a/zh/20/ref/drop_group.sgml +++ b/zh/20/ref/drop_group.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP GROUP 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/drop_index.sgml b/zh/20/ref/drop_index.sgml index b65b810b..d7f892d9 100644 --- a/zh/20/ref/drop_index.sgml +++ b/zh/20/ref/drop_index.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP INDEX 7 - SQL - Language Statements + SQL - 语言语句 @@ -57,7 +57,7 @@ DROP INDEX [ CONCURRENTLY ] [ IF EXISTS ] name 对于临时表,DROP INDEX始终是非并发的, - 因为没有其他会话可以访问它们,而且非并发删除索引的成本更低。 + 因为没有其他会话可以访问它们,而且非并发删除索引的代价更低。 @@ -66,7 +66,7 @@ DROP INDEX [ CONCURRENTLY ] [ IF EXISTS ] nameIF EXISTS - 如果该索引不存在,则不要抛出错误。这种情况下会发出一个提示。 + 如果该索引不存在,则不要抛出错误。这种情况下会发出一条提示。 diff --git a/zh/20/ref/drop_language.sgml b/zh/20/ref/drop_language.sgml index 9696f612..8fb4de3f 100644 --- a/zh/20/ref/drop_language.sgml +++ b/zh/20/ref/drop_language.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP LANGUAGE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/drop_materialized_view.sgml b/zh/20/ref/drop_materialized_view.sgml index f3682552..71ad4326 100644 --- a/zh/20/ref/drop_materialized_view.sgml +++ b/zh/20/ref/drop_materialized_view.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP MATERIALIZED VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/drop_opclass.sgml b/zh/20/ref/drop_opclass.sgml index c3dd2e74..9d67dc64 100644 --- a/zh/20/ref/drop_opclass.sgml +++ b/zh/20/ref/drop_opclass.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP OPERATOR CLASS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/drop_operator.sgml b/zh/20/ref/drop_operator.sgml index 3cfb069c..19e93d4e 100644 --- a/zh/20/ref/drop_operator.sgml +++ b/zh/20/ref/drop_operator.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP OPERATOR 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/drop_opfamily.sgml b/zh/20/ref/drop_opfamily.sgml index 8e7097f9..06223045 100644 --- a/zh/20/ref/drop_opfamily.sgml +++ b/zh/20/ref/drop_opfamily.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP OPERATOR FAMILY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/drop_owned.sgml b/zh/20/ref/drop_owned.sgml index 2bc659bf..3ec24e66 100644 --- a/zh/20/ref/drop_owned.sgml +++ b/zh/20/ref/drop_owned.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP OWNED 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/drop_policy.sgml b/zh/20/ref/drop_policy.sgml index ee64ffa0..a939a688 100644 --- a/zh/20/ref/drop_policy.sgml +++ b/zh/20/ref/drop_policy.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP POLICY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/drop_procedure.sgml b/zh/20/ref/drop_procedure.sgml index 178e6684..19708931 100644 --- a/zh/20/ref/drop_procedure.sgml +++ b/zh/20/ref/drop_procedure.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP PROCEDURE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/drop_publication.sgml b/zh/20/ref/drop_publication.sgml index 6bc4bf59..048c1756 100644 --- a/zh/20/ref/drop_publication.sgml +++ b/zh/20/ref/drop_publication.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP PUBLICATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/drop_role.sgml b/zh/20/ref/drop_role.sgml index 6f3dd022..9fbfa99e 100644 --- a/zh/20/ref/drop_role.sgml +++ b/zh/20/ref/drop_role.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP ROLE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/drop_routine.sgml b/zh/20/ref/drop_routine.sgml index 4f2be77f..db15d5d2 100644 --- a/zh/20/ref/drop_routine.sgml +++ b/zh/20/ref/drop_routine.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP ROUTINE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/drop_rule.sgml b/zh/20/ref/drop_rule.sgml index ddb561f4..2968d946 100644 --- a/zh/20/ref/drop_rule.sgml +++ b/zh/20/ref/drop_rule.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP RULE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/drop_schema.sgml b/zh/20/ref/drop_schema.sgml index 9f622df3..94843c9a 100644 --- a/zh/20/ref/drop_schema.sgml +++ b/zh/20/ref/drop_schema.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP SCHEMA 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/drop_sequence.sgml b/zh/20/ref/drop_sequence.sgml index 4ba78640..586d3038 100644 --- a/zh/20/ref/drop_sequence.sgml +++ b/zh/20/ref/drop_sequence.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP SEQUENCE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/drop_server.sgml b/zh/20/ref/drop_server.sgml index d4156fa5..e9af0d8a 100644 --- a/zh/20/ref/drop_server.sgml +++ b/zh/20/ref/drop_server.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP SERVER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/drop_statistics.sgml b/zh/20/ref/drop_statistics.sgml index 3120dc06..4773bfa8 100644 --- a/zh/20/ref/drop_statistics.sgml +++ b/zh/20/ref/drop_statistics.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP STATISTICS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/drop_subscription.sgml b/zh/20/ref/drop_subscription.sgml index 190ad362..8dac35fa 100644 --- a/zh/20/ref/drop_subscription.sgml +++ b/zh/20/ref/drop_subscription.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP SUBSCRIPTION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/drop_table.sgml b/zh/20/ref/drop_table.sgml index a2634c54..bdfbabf4 100644 --- a/zh/20/ref/drop_table.sgml +++ b/zh/20/ref/drop_table.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TABLE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/drop_tablespace.sgml b/zh/20/ref/drop_tablespace.sgml index c8b09e59..a31fd70f 100644 --- a/zh/20/ref/drop_tablespace.sgml +++ b/zh/20/ref/drop_tablespace.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TABLESPACE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/drop_transform.sgml b/zh/20/ref/drop_transform.sgml index be84b60c..09a3c9c7 100644 --- a/zh/20/ref/drop_transform.sgml +++ b/zh/20/ref/drop_transform.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TRANSFORM 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/drop_trigger.sgml b/zh/20/ref/drop_trigger.sgml index 1f85cf41..160a5ebd 100644 --- a/zh/20/ref/drop_trigger.sgml +++ b/zh/20/ref/drop_trigger.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TRIGGER 7 - SQL - Language Statements + SQL - 语言语句 @@ -30,7 +30,7 @@ DROP TRIGGER [ IF EXISTS ] name ON DROP TRIGGER移除一个现有触发器的定义。 - 要执行此命令,当前用户必须是定义该触发器的表的拥有者。 + 要执行此命令,当前用户必须是定义该触发器的表的所有者。 @@ -109,7 +109,7 @@ DROP TRIGGER if_dist_exists ON films; - 另见 + 参见 diff --git a/zh/20/ref/drop_tsconfig.sgml b/zh/20/ref/drop_tsconfig.sgml index 2a7cdc52..ea139802 100644 --- a/zh/20/ref/drop_tsconfig.sgml +++ b/zh/20/ref/drop_tsconfig.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TEXT SEARCH CONFIGURATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/drop_tsdictionary.sgml b/zh/20/ref/drop_tsdictionary.sgml index 1eb24189..316c5d00 100644 --- a/zh/20/ref/drop_tsdictionary.sgml +++ b/zh/20/ref/drop_tsdictionary.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TEXT SEARCH DICTIONARY 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/drop_tsparser.sgml b/zh/20/ref/drop_tsparser.sgml index 0cfa7acd..a65f47be 100644 --- a/zh/20/ref/drop_tsparser.sgml +++ b/zh/20/ref/drop_tsparser.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TEXT SEARCH PARSER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/drop_tstemplate.sgml b/zh/20/ref/drop_tstemplate.sgml index 282231c5..fa1faab0 100644 --- a/zh/20/ref/drop_tstemplate.sgml +++ b/zh/20/ref/drop_tstemplate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TEXT SEARCH TEMPLATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/drop_type.sgml b/zh/20/ref/drop_type.sgml index dab5bfa0..2f139da5 100644 --- a/zh/20/ref/drop_type.sgml +++ b/zh/20/ref/drop_type.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP TYPE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/drop_user.sgml b/zh/20/ref/drop_user.sgml index 00d1d5f4..2e61d6ef 100644 --- a/zh/20/ref/drop_user.sgml +++ b/zh/20/ref/drop_user.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP USER 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/drop_user_mapping.sgml b/zh/20/ref/drop_user_mapping.sgml index 2a79a65b..d23b0a16 100644 --- a/zh/20/ref/drop_user_mapping.sgml +++ b/zh/20/ref/drop_user_mapping.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP USER MAPPING 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/drop_view.sgml b/zh/20/ref/drop_view.sgml index 4feb47e5..8f995245 100644 --- a/zh/20/ref/drop_view.sgml +++ b/zh/20/ref/drop_view.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation DROP VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/dropdb.sgml b/zh/20/ref/dropdb.sgml index 70ad776f..10f79ed2 100644 --- a/zh/20/ref/dropdb.sgml +++ b/zh/20/ref/dropdb.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation dropdb 1 - Application + 应用程序 diff --git a/zh/20/ref/dropuser.sgml b/zh/20/ref/dropuser.sgml index 55aa53fa..3cdd48c0 100644 --- a/zh/20/ref/dropuser.sgml +++ b/zh/20/ref/dropuser.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation dropuser 1 - Application + 应用程序 diff --git a/zh/20/ref/ecpg-ref.sgml b/zh/20/ref/ecpg-ref.sgml index 002b8ef1..506be589 100644 --- a/zh/20/ref/ecpg-ref.sgml +++ b/zh/20/ref/ecpg-ref.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ecpg 1 - Application + 应用程序 diff --git a/zh/20/ref/end.sgml b/zh/20/ref/end.sgml index d042a740..10947ab0 100644 --- a/zh/20/ref/end.sgml +++ b/zh/20/ref/end.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation END 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/execute.sgml b/zh/20/ref/execute.sgml index 2aed0669..5e7274ff 100644 --- a/zh/20/ref/execute.sgml +++ b/zh/20/ref/execute.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation EXECUTE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/explain.sgml b/zh/20/ref/explain.sgml index 6f9ef9a5..f56f4dab 100644 --- a/zh/20/ref/explain.sgml +++ b/zh/20/ref/explain.sgml @@ -21,7 +21,7 @@ PostgreSQL documentation EXPLAIN 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/fetch.sgml b/zh/20/ref/fetch.sgml index 71c12406..9ab88c49 100644 --- a/zh/20/ref/fetch.sgml +++ b/zh/20/ref/fetch.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation FETCH 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/grant.sgml b/zh/20/ref/grant.sgml index 7ad79ac6..9520aada 100644 --- a/zh/20/ref/grant.sgml +++ b/zh/20/ref/grant.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation GRANT 7 - SQL - Language Statements + SQL - 语言语句 @@ -102,7 +102,7 @@ GRANT role_name [, ...] TO role_specification ] -where role_specification can be: +其中role_specification可以是: [ GROUP ] role_name | PUBLIC diff --git a/zh/20/ref/import_foreign_schema.sgml b/zh/20/ref/import_foreign_schema.sgml index 6e912201..1957d60a 100644 --- a/zh/20/ref/import_foreign_schema.sgml +++ b/zh/20/ref/import_foreign_schema.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation IMPORT FOREIGN SCHEMA 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/initdb.sgml b/zh/20/ref/initdb.sgml index bfbbc806..20797adc 100644 --- a/zh/20/ref/initdb.sgml +++ b/zh/20/ref/initdb.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation initdb 1 - Application + 应用程序 @@ -210,7 +210,7 @@ PostgreSQL documentation - 当使用 ICU 提供程序时,指定 ICU 区域设置 ID。区域设置支持见 + 当使用 ICU 提供程序时,指定 ICU 区域设置。区域设置支持见 diff --git a/zh/20/ref/insert.sgml b/zh/20/ref/insert.sgml index 56f71f22..99e76331 100644 --- a/zh/20/ref/insert.sgml +++ b/zh/20/ref/insert.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation INSERT 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/listen.sgml b/zh/20/ref/listen.sgml index 0a7c6e23..421010d0 100644 --- a/zh/20/ref/listen.sgml +++ b/zh/20/ref/listen.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation LISTEN 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/load.sgml b/zh/20/ref/load.sgml index bb0adb7c..89bdb114 100644 --- a/zh/20/ref/load.sgml +++ b/zh/20/ref/load.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation LOAD 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/lock.sgml b/zh/20/ref/lock.sgml index bc45eec4..fce3ac96 100644 --- a/zh/20/ref/lock.sgml +++ b/zh/20/ref/lock.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation LOCK 7 - SQL - Language Statements + SQL - 语言语句 @@ -55,7 +55,7 @@ LOCK [ TABLE ] [ ONLY ] name [ * ] 因为SHARE锁模式与写入者获取的ROW EXCLUSIVE锁冲突, 而LOCK TABLE name IN SHARE MODE - 语句会一直等待,直到任何并发持有ROW EXCLUSIVE模式锁的事务提交或回滚。 + 语句会一直等待,直到所有并发持有ROW EXCLUSIVE模式锁的事务提交或回滚。 因此,一旦获得该锁,就不存在尚未提交的写入;而且在释放该锁之前,也不会有新的写入开始。 @@ -166,9 +166,7 @@ LOCK [ TABLE ] [ ONLY ] name [ * ] 这些模式名称通常应理解为:用户打算在被锁定的表中获取行级锁。 此外,ROW EXCLUSIVE模式本身也是一种可共享的表锁。 请记住,就LOCK TABLE而言,所有锁模式的语义完全相同, - 差别只在于哪些模式彼此冲突。关于如何获取真正的行级锁,请参阅 - 文档中的和 - 。 + 差别只在于哪些模式彼此冲突。关于如何获取真正的行级锁,请参阅 (后者位于文档中)。 diff --git a/zh/20/ref/merge.sgml b/zh/20/ref/merge.sgml index 4c108efd..bd32bf3b 100644 --- a/zh/20/ref/merge.sgml +++ b/zh/20/ref/merge.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation MERGE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/move.sgml b/zh/20/ref/move.sgml index e90c1b88..961359c8 100644 --- a/zh/20/ref/move.sgml +++ b/zh/20/ref/move.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation MOVE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/notify.sgml b/zh/20/ref/notify.sgml index 502baccc..a9f72d29 100644 --- a/zh/20/ref/notify.sgml +++ b/zh/20/ref/notify.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation NOTIFY 7 - SQL - Language Statements + SQL - 语言语句 @@ -88,7 +88,7 @@ NOTIFY channel [ , 注解 - 系统中有一个队列,用来保存那些已经发送但尚未被所有监听会话处理的通知。如果这个队列被塞满,那么调用NOTIFY的事务会在提交时失败。该队列非常大(标准安装中为 8GB),几乎足以满足所有用例。不过,如果某个会话执行了LISTEN后又长时间停留在一个事务里,就无法进行清理。一旦队列占用超过一半,你就会在日志文件中看到警告,指出究竟是哪个会话阻碍了清理。在这种情况下,应确保该会话结束其当前事务,以便清理能够继续进行。 + 系统中有一个队列,用来保存那些已经发送但尚未被所有监听会话处理的通知。如果这个队列被塞满,那么调用NOTIFY的事务会在提交时失败。该队列非常大(标准安装中为 8GB),几乎足以满足所有用例。不过,如果某个会话执行了LISTEN后又长时间停留在一个事务里,就无法进行清理。一旦队列占用达到一半,你就会在日志文件中看到警告,指出究竟是哪个会话阻碍了清理。在这种情况下,应确保该会话结束其当前事务,以便清理能够继续进行。 函数pg_notification_queue_usage返回当前被待处理通知占用的队列比例。详见。 diff --git a/zh/20/ref/pg_amcheck.sgml b/zh/20/ref/pg_amcheck.sgml index 855c42dd..55a6e2b7 100644 --- a/zh/20/ref/pg_amcheck.sgml +++ b/zh/20/ref/pg_amcheck.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_amcheck 1 - Application + 应用程序 diff --git a/zh/20/ref/pg_basebackup.sgml b/zh/20/ref/pg_basebackup.sgml index 30bc6a72..59006623 100644 --- a/zh/20/ref/pg_basebackup.sgml +++ b/zh/20/ref/pg_basebackup.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation pg_basebackup 1 - Application + 应用程序 @@ -80,7 +80,7 @@ PostgreSQL documentation - 备份所需的所有 WAL 记录都必须包含足够的全页写入, + 备份所需的所有 WAL 记录都必须包含足够的整页写入, 因此必须在主库上启用full_page_writes @@ -217,7 +217,7 @@ PostgreSQL documentation - 目前,此选项仅适用于 plain 输出格式;如果选择了 tar 格式,则会被忽略。 + 目前,此选项仅适用于 普通文件 输出格式;如果选择了 tar 格式,则会被忽略。 @@ -227,7 +227,7 @@ PostgreSQL documentation - 设置写入 WAL(预写式日志)文件的目录。默认情况下,WAL 文件会放在目标目录的pg_wal子目录中,但此选项可用于将其放在其他位置。waldir必须是绝对路径。与主目标目录一样,waldir不必事先存在,但如果存在则必须为空。只有当备份采用 plain 格式时,才能指定此选项。 + 设置写入 WAL(预写式日志)文件的目录。默认情况下,WAL 文件会放在目标目录的pg_wal子目录中,但此选项可用于将其放在其他位置。waldir必须是绝对路径。与主目标目录一样,waldir不必事先存在,但如果存在则必须为空。只有当备份采用 普通文件 格式时,才能指定此选项。 @@ -319,7 +319,7 @@ PostgreSQL documentation - 当 tar 格式配合gziplz4zstd使用时,所有 tar 文件名都会分别自动加上.gz.lz4.zst后缀。使用 plain 格式时,不能指定客户端压缩,但仍可以请求服务器端压缩。这样做时,服务器会先压缩备份再传输,而客户端会对其进行解压并提取。 + 当 tar 格式配合gziplz4zstd使用时,所有 tar 文件名都会分别自动加上.gz.lz4.zst后缀。使用 普通文件 格式时,不能指定客户端压缩,但仍可以请求服务器端压缩。这样做时,服务器会先压缩备份再传输,而客户端会对其进行解压并提取。 @@ -379,7 +379,7 @@ PostgreSQL documentation - 请注意,无论如何表空间目录都不会被清理。 + 请注意,无论是否使用此选项,表空间目录都不会被清理。 @@ -427,7 +427,7 @@ PostgreSQL documentation - 此选项只能与-X stream一起使用。它会使 WAL 流式传输使用指定的复制槽。如果此基础备份打算用作使用复制槽的流复制备库,那么该备库应使用与相同的复制槽名称。这样可以确保主库在基础备份结束与新备库开始流复制之间的这段时间内,不会移除任何必需的 WAL 数据。 + 此选项只能与-X stream一起使用。它会使 WAL 流式传输使用指定的复制槽。如果此基础备份打算用作使用复制槽的流复制备库,那么该备库应将同一个复制槽名称用作的值。这样可以确保主库在基础备份结束与新备库开始流复制之间的这段时间内,不会移除任何必需的 WAL 数据。 @@ -444,10 +444,10 @@ PostgreSQL documentation - 设置为fsync(默认)时,pg_basebackup会递归打开并同步备份目录中的所有文件。使用 plain 格式时,查找文件会跟随 WAL 目录和各已配置表空间的符号链接。 + 设置为fsync(默认)时,pg_basebackup会递归打开并同步备份目录中的所有文件。使用 普通文件 格式时,查找文件会跟随 WAL 目录和各已配置表空间的符号链接。 - 在 Linux 上,也可以使用syncfs,让操作系统同步包含备份目录的整个文件系统。使用 plain 格式时,pg_basebackup还会同步包含 WAL 文件和各表空间的文件系统。关于使用syncfs时需要注意的限制,见。 + 在 Linux 上,也可以使用syncfs,让操作系统同步包含备份目录的整个文件系统。使用 普通文件 格式时,pg_basebackup还会同步包含 WAL 文件和各表空间的文件系统。关于使用syncfs时需要注意的事项,见 使用时,此选项无效。 @@ -479,7 +479,7 @@ PostgreSQL documentation - 对于希望验证备份未被篡改的用户,使用 SHA 哈希函数可以为每个文件提供具有密码学安全性的摘要;而 CRC-32C 算法提供的校验和计算速度要快得多,虽然它很适合发现由于意外改动造成的错误,但并不能抵御恶意修改。请注意,要想对能够访问备份的攻击者形成防护,备份清单就需要安全地保存在其他地方,或者以其他方式确认自备份完成后未被修改。 + 对于希望验证备份未被篡改的用户,使用 SHA hash 函数可以为每个文件提供具有密码学安全性的摘要;而 CRC-32C 算法提供的校验和计算速度要快得多,虽然它很适合发现由于意外改动造成的错误,但并不能抵御恶意修改。请注意,要想对能够访问备份的攻击者形成防护,备份清单就需要安全地保存在其他地方,或者以其他方式确认自备份完成后未被修改。 @@ -691,7 +691,7 @@ PostgreSQL documentation - 注意 + 注解 在备份开始时,需要在源服务器上执行一次检查点。这可能需要一些时间(尤其是在未使用--checkpoint=fast选项时);在此期间,pg_basebackup看起来会处于空闲状态。 @@ -702,7 +702,7 @@ PostgreSQL documentation - 在 plain 格式中,除非使用了--tablespace-mapping选项,否则表空间会备份到其在源服务器上的相同路径。如果不使用此选项,那么当表空间正在使用时,就无法在与服务器相同的主机上执行 plain 格式的基础备份,因为备份将不得不写入与原始表空间相同的目录位置。 + 在 普通文件 格式中,除非使用了--tablespace-mapping选项,否则表空间会备份到其在源服务器上的相同路径。如果不使用此选项,那么当表空间正在使用时,就无法在与服务器相同的主机上执行 普通文件 格式的基础备份,因为备份将不得不写入与原始表空间相同的目录位置。 @@ -762,7 +762,7 @@ PostgreSQL documentation - 参见 + 另见 diff --git a/zh/20/ref/pg_checksums.sgml b/zh/20/ref/pg_checksums.sgml index 8945066d..907181c8 100644 --- a/zh/20/ref/pg_checksums.sgml +++ b/zh/20/ref/pg_checksums.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_checksums 1 - Application + 应用程序 diff --git a/zh/20/ref/pg_combinebackup.sgml b/zh/20/ref/pg_combinebackup.sgml index 5ae1aa14..c9ebcedf 100644 --- a/zh/20/ref/pg_combinebackup.sgml +++ b/zh/20/ref/pg_combinebackup.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_combinebackup 1 - Application + 应用程序 @@ -239,18 +239,18 @@ PostgreSQL documentation 当设置为fsync(这是默认值)时, pg_combinebackup会递归打开并同步备份目录中的所有文件。 - 使用 plain 格式时,搜索文件时会跟随 WAL 目录和每个已配置表空间的符号链接。 + 使用 普通文件 格式时,搜索文件时会跟随 WAL 目录和每个已配置表空间的符号链接。 在 Linux 上,也可以改用syncfs, 让操作系统同步包含备份目录的整个文件系统。 - 使用 plain 格式时,pg_combinebackup + 使用 普通文件 格式时,pg_combinebackup 还会同步包含 WAL 文件和各表空间的文件系统。 关于使用syncfs时需要注意的事项,请参见 - 当使用时,此选项无效。 + 使用时,此选项无效。 @@ -302,15 +302,11 @@ PostgreSQL documentation 环境 - 与多数PostgreSQL工具一样, - 本工具使用libpq支持的环境变量 - (参见)。 + 与大多数其他PostgreSQL工具一样,此工具也使用libpq支持的环境变量(见)。 - 环境变量PG_COLOR指定诊断消息是否使用颜色。 - 可选值为alwaysauto和 - never。 + 环境变量PG_COLOR指定是否在诊断消息中使用颜色。可能的值为alwaysautonever diff --git a/zh/20/ref/pg_config-ref.sgml b/zh/20/ref/pg_config-ref.sgml index 565638d9..b157f24c 100644 --- a/zh/20/ref/pg_config-ref.sgml +++ b/zh/20/ref/pg_config-ref.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation pg_config 1 - Application + 应用程序 diff --git a/zh/20/ref/pg_controldata.sgml b/zh/20/ref/pg_controldata.sgml index dd9429eb..931e4111 100644 --- a/zh/20/ref/pg_controldata.sgml +++ b/zh/20/ref/pg_controldata.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_controldata 1 - Application + 应用程序 diff --git a/zh/20/ref/pg_createsubscriber.sgml b/zh/20/ref/pg_createsubscriber.sgml index 02ff6ce1..5cec6c71 100644 --- a/zh/20/ref/pg_createsubscriber.sgml +++ b/zh/20/ref/pg_createsubscriber.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_createsubscriber 1 - Application + 应用程序 @@ -207,7 +207,7 @@ PostgreSQL documentation - 等待恢复结束的最大秒数。设为 0 表示禁用。 + 等待恢复结束的最大秒数。设为 0 表示禁用超时限制。 默认值为 0。 @@ -357,7 +357,7 @@ PostgreSQL documentation - 注意 + 注解 前置条件 @@ -449,7 +449,7 @@ PostgreSQL documentation 若缺少必需 WAL 文件,复制可能失败。 - 为避免该问题,源服务器应将 + 为避免该问题,源服务器必须将 设置为-1, 以确保必需 WAL 文件不会被提前移除。 @@ -504,9 +504,9 @@ PostgreSQL documentation 它指定了恢复将推进到的预写式日志位置的 LSN()。 它还将promote指定为服务器在达到恢复目标后应执行的动作。 - 为了避免恢复过程中出现意外行为,还会添加其他恢复参数,例如在达到一致状态后就结束恢复 - (实际上 WAL 应继续应用到复制起始位置)以及因多个恢复目标而导致失败。 + 还会添加其他恢复参数,以避免恢复过程中出现意外行为, + 例如一达到一致状态就结束恢复(WAL 应继续应用到复制起始位置),或者因指定多个恢复目标而失败。 当服务器退出备库模式并接受读写事务时,该步骤结束。 如果设置了选项,而恢复在给定秒数内没有结束, pg_createsubscriber就会终止。 diff --git a/zh/20/ref/pg_ctl-ref.sgml b/zh/20/ref/pg_ctl-ref.sgml index 6085da56..801cbc55 100644 --- a/zh/20/ref/pg_ctl-ref.sgml +++ b/zh/20/ref/pg_ctl-ref.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation pg_ctl 1 - Application + 应用程序 diff --git a/zh/20/ref/pg_dump.sgml b/zh/20/ref/pg_dump.sgml index 5f2e393b..539ffbb7 100644 --- a/zh/20/ref/pg_dump.sgml +++ b/zh/20/ref/pg_dump.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_dump 1 - Application + 应用程序 diff --git a/zh/20/ref/pg_dumpall.sgml b/zh/20/ref/pg_dumpall.sgml index 5202b582..2257b420 100644 --- a/zh/20/ref/pg_dumpall.sgml +++ b/zh/20/ref/pg_dumpall.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_dumpall 1 - Application + 应用程序 diff --git a/zh/20/ref/pg_isready.sgml b/zh/20/ref/pg_isready.sgml index 2e93dde1..a09f7745 100644 --- a/zh/20/ref/pg_isready.sgml +++ b/zh/20/ref/pg_isready.sgml @@ -13,7 +13,7 @@ PostgreSQL documentation pg_isready 1 - Application + 应用程序 diff --git a/zh/20/ref/pg_receivewal.sgml b/zh/20/ref/pg_receivewal.sgml index 3c9e580a..bf520c28 100644 --- a/zh/20/ref/pg_receivewal.sgml +++ b/zh/20/ref/pg_receivewal.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation pg_receivewal 1 - Application + 应用程序 diff --git a/zh/20/ref/pg_recvlogical.sgml b/zh/20/ref/pg_recvlogical.sgml index 6fcce028..b1fd09ae 100644 --- a/zh/20/ref/pg_recvlogical.sgml +++ b/zh/20/ref/pg_recvlogical.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation pg_recvlogical 1 - Application + 应用程序 @@ -155,7 +155,7 @@ PostgreSQL documentation - 启用后会将该槽同步到备库。此选项只能与 一起指定。 + 允许将该槽同步到备库。此选项只能与 一起指定。 @@ -181,7 +181,7 @@ PostgreSQL documentation 指定pg_recvlogical应当以多高的频率发起fsync()调用, - 以确保输出文件被安全地刷入磁盘。默认值为 10 秒。 + 以确保输出文件安全刷盘。默认值为 10 秒。 @@ -250,8 +250,7 @@ PostgreSQL documentation 创建该槽时,使用指定的逻辑解码输出插件。参见, 了解 PostgreSQL 提供的插件信息。默认值是 - 。 - 如果该槽已经存在,则此选项不起作用。 + 。如果该槽已经存在,则此选项不起作用。 diff --git a/zh/20/ref/pg_resetwal.sgml b/zh/20/ref/pg_resetwal.sgml index 8a26892e..7d1b42b7 100644 --- a/zh/20/ref/pg_resetwal.sgml +++ b/zh/20/ref/pg_resetwal.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_resetwal 1 - Application + 应用程序 diff --git a/zh/20/ref/pg_restore.sgml b/zh/20/ref/pg_restore.sgml index 828bfd0d..a3e9aebe 100644 --- a/zh/20/ref/pg_restore.sgml +++ b/zh/20/ref/pg_restore.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_restore 1 - Application + 应用程序 diff --git a/zh/20/ref/pg_rewind.sgml b/zh/20/ref/pg_rewind.sgml index cfa4a057..a6960401 100644 --- a/zh/20/ref/pg_rewind.sgml +++ b/zh/20/ref/pg_rewind.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation pg_rewind 1 - Application + 应用程序 diff --git a/zh/20/ref/pg_verifybackup.sgml b/zh/20/ref/pg_verifybackup.sgml index 68ca0ec6..8cb2f638 100644 --- a/zh/20/ref/pg_verifybackup.sgml +++ b/zh/20/ref/pg_verifybackup.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_verifybackup 1 - Application + 应用程序 @@ -32,7 +32,7 @@ PostgreSQL documentation pg_verifybackup用于依据服务器在备份时生成的 backup_manifest,检查使用 pg_basebackup获取的数据库集簇备份的完整性。备份 - 既可以采用“plain”格式,也可以采用“tar”格式;其中也包括使用 + 既可以采用“普通文件”格式,也可以采用“tar”格式;其中也包括使用 pg_basebackup支持的任意算法压缩的 tar 格 式备份。 @@ -40,8 +40,7 @@ PostgreSQL documentation 需要注意,pg_verifybackup执行的验证并未、也 不可能涵盖运行中的服务器在尝试使用该备份时会执行的每一项检查。即使使 - 用了此工具,你仍应进行测试恢复,并确认生成的数据库按预期工作且包含正 - 确的数据。不过,pg_verifybackup能够检测出 + 用了此工具,你仍应进行测试恢复,并确认生成的数据库按预期工作且看起来包含正确的数据。不过,pg_verifybackup能够检测出 许多因存储问题或用户错误而常见的问题。 @@ -139,9 +138,7 @@ PostgreSQL documentation tar - 备份由 tar 文件组成,这些文件可以经过压缩。有效的备份包括名为 - base.tar的主数据目录、名为 - pg_wal.tar的 WAL 文件,以及每个表空间 + 备份由 tar 文件组成,这些文件可以经过压缩。有效的备份包括存放在 base.tar文件中的主数据目录、存放在 pg_wal.tar中的 WAL 文件,以及每个表空间 对应的单独 tar 文件,这些文件以该表空间的 OID 命名。如果备份 被压缩,则会在每个文件名末尾追加相应的压缩扩展名。 @@ -236,9 +233,9 @@ PostgreSQL documentation - 还提供下列其他选项: + 其他选项也可用: - + @@ -269,7 +266,7 @@ PostgreSQL documentation 示例 - 要在mydbserver上创建服务器的基础备份,并验证该备 + 要为位于mydbserver的服务器创建基础备份,并验证该备 份的完整性: $ pg_basebackup -h mydbserver -D /usr/local/pgsql/data @@ -278,7 +275,7 @@ PostgreSQL documentation - 要在mydbserver上创建服务器的基础备份,将备份清单 + 要为位于mydbserver的服务器创建基础备份,将备份清单 移到备份目录之外的位置,然后验证该备份: $ pg_basebackup -h mydbserver -D /usr/local/pgsql/backup1234 diff --git a/zh/20/ref/pg_waldump.sgml b/zh/20/ref/pg_waldump.sgml index 17ee0bdd..b340b451 100644 --- a/zh/20/ref/pg_waldump.sgml +++ b/zh/20/ref/pg_waldump.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_waldump 1 - Application + 应用程序 diff --git a/zh/20/ref/pg_walsummary.sgml b/zh/20/ref/pg_walsummary.sgml index 747fae88..3baf10c8 100644 --- a/zh/20/ref/pg_walsummary.sgml +++ b/zh/20/ref/pg_walsummary.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_walsummary 1 - Application + 应用程序 @@ -41,11 +41,11 @@ PostgreSQL documentation WAL 汇总文件按表空间 OID、关系 OID 以及关系分支(fork)建立索引。 对于每个关系分支,它都存储该文件所汇总范围内被 WAL 修改的块列表。 - 它还可以存储一个limit block: + 它还可以存储一个界限块: 如果该关系分支在相关 WAL 范围内被创建或截断,则其值为 0; 否则,其值为该关系分支被截断后的最短长度。 如果该关系分支在相关 WAL 范围内未被创建、删除或截断, - 则 limit block 未定义,或者为无穷大,本工具不会打印它。 + 则 界限块 未定义,或者为无穷大,本工具不会打印它。 @@ -117,9 +117,7 @@ PostgreSQL documentation 环境 - 环境变量PG_COLOR用于指定是否在诊断消息中使用颜色。 - 可能的值为alwaysauto和 - never。 + 环境变量PG_COLOR指定是否在诊断消息中使用颜色。可能的值为alwaysautonever diff --git a/zh/20/ref/pgarchivecleanup.sgml b/zh/20/ref/pgarchivecleanup.sgml index d9007b70..047ee635 100644 --- a/zh/20/ref/pgarchivecleanup.sgml +++ b/zh/20/ref/pgarchivecleanup.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_archivecleanup 1 - Application + 应用程序 diff --git a/zh/20/ref/pgbench.sgml b/zh/20/ref/pgbench.sgml index 39033000..17817b32 100644 --- a/zh/20/ref/pgbench.sgml +++ b/zh/20/ref/pgbench.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation pgbench 1 - Application + 应用程序 @@ -1705,7 +1705,7 @@ SELECT 4 AS four \; SELECT 5 AS five \aset greatest ( number , ... ) - double 如果任何参数是双精度的,否则 integer + 若任一参数为 double,则为 double,否则为 integer 选择参数中的最大值。 @@ -1775,7 +1775,7 @@ SELECT 4 AS four \; SELECT 5 AS five \aset least ( number , ... ) - double 如果任何参数是双精度的,否则 integer + 若任一参数为 double,则为 double,否则为 integer 选择参数中的最小值。 @@ -2636,7 +2636,7 @@ PGOPTIONS='-c default_table_access_method=wuzza' 安全性 - 如果不可信用户能够访问尚未采用模式的安全使用方式的数据库,就不要在该数据库中运行pgbenchpgbench使用非限定名称,并且不会更改搜索路径。 + 如果不受信任的用户能够访问尚未采用模式的安全使用方式的数据库,就不要在该数据库中运行pgbenchpgbench使用非限定名称,并且不会更改搜索路径。 diff --git a/zh/20/ref/pgtestfsync.sgml b/zh/20/ref/pgtestfsync.sgml index 86e69b30..6055bccf 100644 --- a/zh/20/ref/pgtestfsync.sgml +++ b/zh/20/ref/pgtestfsync.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_test_fsync 1 - Application + 应用程序 diff --git a/zh/20/ref/pgtesttiming.sgml b/zh/20/ref/pgtesttiming.sgml index c5741049..1365f82a 100644 --- a/zh/20/ref/pgtesttiming.sgml +++ b/zh/20/ref/pgtesttiming.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_test_timing 1 - Application + 应用程序 diff --git a/zh/20/ref/pgupgrade.sgml b/zh/20/ref/pgupgrade.sgml index cdcf983b..c3fa58e2 100644 --- a/zh/20/ref/pgupgrade.sgml +++ b/zh/20/ref/pgupgrade.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation pg_upgrade 1 - Application + 应用程序 @@ -40,7 +40,7 @@ PostgreSQL documentation pg_upgrade(以前称为 pg_migrator)允许将存储在 PostgreSQL 数据文件中的数据升级到更新的 PostgreSQL主版本,而无需执行主版本升级通常所需的数据转储/恢复, - 例如从 12.14 升级到 13.10,或从 14.9 升级到 15.5。它不用于次版本升级, + 例如从 12.14 升级到 13.10,或从 14.9 升级到 15.5。次版本升级不需要使用它, 例如从 12.7 升级到 12.8 或从 14.1 升级到 14.5。 @@ -340,7 +340,7 @@ PostgreSQL documentation 这里不介绍升级 - 逻辑复制集簇 + 逻辑复制集群 的步骤;详见 diff --git a/zh/20/ref/postgres-ref.sgml b/zh/20/ref/postgres-ref.sgml index b62740d6..a2e9456b 100644 --- a/zh/20/ref/postgres-ref.sgml +++ b/zh/20/ref/postgres-ref.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation postgres 1 - Application + 应用程序 @@ -532,7 +532,7 @@ PostgreSQL documentation - 表明另一台服务器已经在运行的失败消息 + 表明另一个服务器已经在运行的失败消息 应仔细检查,例如可根据你的系统使用下面的命令: $ ps ax | grep postgres @@ -721,7 +721,7 @@ PostgreSQL documentation - 参见 + 另见 , diff --git a/zh/20/ref/prepare.sgml b/zh/20/ref/prepare.sgml index 6c456821..20228fb4 100644 --- a/zh/20/ref/prepare.sgml +++ b/zh/20/ref/prepare.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation PREPARE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/prepare_transaction.sgml b/zh/20/ref/prepare_transaction.sgml index 10d018b0..75776dab 100644 --- a/zh/20/ref/prepare_transaction.sgml +++ b/zh/20/ref/prepare_transaction.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation PREPARE TRANSACTION 7 - SQL - Language Statements + SQL - 语言语句 @@ -72,7 +72,7 @@ PREPARE TRANSACTION transaction_id - 当前不允许将执行过以下任一操作的事务置为预备状态:涉及临时表或会话临时命名空间的操作、创建任何WITH HOLD游标,或执行过LISTENUNLISTENNOTIFY。这些特性与当前会话绑定得过于紧密,因此在要进入预备状态的事务中没有意义。 + 当前不允许对执行过以下任一操作的事务执行PREPARE:涉及临时表或会话临时命名空间的操作、创建任何WITH HOLD游标,或执行过LISTENUNLISTENNOTIFY。这些特性与当前会话绑定得过于紧密,因此在要进入预备状态的事务中没有意义。 diff --git a/zh/20/ref/psql-ref.sgml b/zh/20/ref/psql-ref.sgml index 8190d0d7..c9f3d88d 100644 --- a/zh/20/ref/psql-ref.sgml +++ b/zh/20/ref/psql-ref.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation psql 1 - Application + 应用程序 @@ -534,7 +534,7 @@ testdb=> - 如果不可信用户能够访问尚未采用模式的安全使用方式的数据库,请在会话开始时从search_path中移除所有公众可写的 schema。可以在连接字符串中加入options=-csearch_path=,或者在执行其他 SQL 命令之前发出SELECT pg_catalog.set_config('search_path', '', false)。这种考虑并非psql特有;它适用于任何执行任意 SQL 命令的接口。 + 如果不受信任的用户能够访问尚未采用模式的安全使用方式的数据库,请在会话开始时从search_path中移除所有公众可写的模式。可以在连接字符串中加入options=-csearch_path=,或者在执行其他 SQL 命令之前发出SELECT pg_catalog.set_config('search_path', '', false)。这种考虑并非psql特有;它适用于任何执行任意 SQL 命令的接口。 @@ -587,7 +587,7 @@ testdb=> - 定义了以下元命令: + 定义了以下元命令: @@ -686,7 +686,7 @@ INSERT INTO tbls1 VALUES ($1, $2) \parse stmt1 - 示例: + 示例: => \c mydb myuser host.dom 6432 @@ -1658,11 +1658,7 @@ CREATE INDEX - 生成的查询按照返回的行的顺序执行,并在每行内从左到右执行,如果有多个列。NULL字段将被忽略。生成的查询文字 - 直接发送到服务器进行处理,因此它们不能是psql元命令,也不能包含psql - 变量引用。如果任何单个查询失败,剩余查询的执行将继续,除非设置了ON_ERROR_STOP。每个查询的执行 - 都受ECHO处理的影响。(通常在使用\gexec时,将ECHO设置为 - allqueries是明智的。)查询记录、单步模式、计时和其他查询执行功能也适用于每个生成的查询。 + 生成的查询按照返回行的顺序执行;如果有多列,则在每行内从左到右执行。NULL 字段会被忽略。生成的查询按原样发送到服务器进行处理,因此不能是psql元命令,也不能包含psql变量引用。如果某个查询失败,仍会继续执行其余查询,除非设置了ON_ERROR_STOP。每个查询的执行都受ECHO处理的影响。(通常,在使用\gexec时,适宜将ECHO设为allqueries。)查询日志、单步模式、计时及其他查询执行功能也适用于每个生成的查询。 如果当前查询缓冲区为空,则重新执行最近发送的查询。 @@ -1902,7 +1898,7 @@ SELECT - 将文件存储到一个PostgreSQL大对象中。可选地,它将给定的注释与对象关联起来。例如: + 将文件存储到一个PostgreSQL大对象中。可选地,它将给定的注释与对象关联起来。例如: foo=> \lo_import '/home/peter/pictures/photo.xcf' 'a picture of me' lo_import 152801 @@ -2048,7 +2044,7 @@ SELECT $1 \parse stmt1 - 可调整打印选项有: + 可调整打印选项有: border @@ -2166,7 +2162,7 @@ SELECT $1 \parse stmt1 允许使用唯一缩写。 - aligned格式是标准的、人类可读的、格式良好的文本输出;这是默认设置。 + aligned格式是标准的、适合人阅读且排版整齐的文本输出;这是默认格式。 unaligned格式将一行中的所有列写在一行上,由当前活动的字段分隔符分隔。这对于创建可能被其他程序读取的输出很有用,例如,制表符分隔或逗号分隔格式。然而,如果字段分隔符字符出现在列的值中,则不会被特殊处理;因此,CSV格式可能更适合这些目的。 @@ -3356,12 +3352,12 @@ bar <acronym>SQL</acronym> 中插入变量 - psql变量的一个关键特性是可以把它们替换(插入)到常规SQL语句中,也可以把它们作为元命令的参数。此外,psql还提供了功能来确保被用作 SQL 文字和标识符的变量值会被正确地引用。插入一个值而不需要加引用的语法是在变量名前面加上一个冒号(:)。例如, + psql变量的一个关键特性是可以把它们替换(插入)到常规SQL语句中,也可以把它们作为元命令的参数。此外,psql还提供了功能来确保被用作 SQL 字面量和标识符的变量值会被正确地加引号。插入一个值而不加引号的语法是在变量名前面加上一个冒号(:)。例如, testdb=> \set foo 'my_table' testdb=> SELECT * FROM :foo; - 将查询表my_table。注意这可能会不安全:该变量的值会被按字面拷贝,因此它可能包含不平衡的引号甚至反斜线命令。必须确保把它放在那里是有意义的。 + 将查询表 my_table。注意这可能会不安全:该变量的值会被按字面拷贝,因此它可能包含不平衡的引号甚至反斜线命令。必须确保把它放在那里是有意义的。 diff --git a/zh/20/ref/reassign_owned.sgml b/zh/20/ref/reassign_owned.sgml index cad7631c..0d000d23 100644 --- a/zh/20/ref/reassign_owned.sgml +++ b/zh/20/ref/reassign_owned.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation REASSIGN OWNED 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/refresh_materialized_view.sgml b/zh/20/ref/refresh_materialized_view.sgml index 2ccb7ac0..7d0fed7a 100644 --- a/zh/20/ref/refresh_materialized_view.sgml +++ b/zh/20/ref/refresh_materialized_view.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation REFRESH MATERIALIZED VIEW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/reindex.sgml b/zh/20/ref/reindex.sgml index 5f43ac70..e64fd049 100644 --- a/zh/20/ref/reindex.sgml +++ b/zh/20/ref/reindex.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation REINDEX 7 - SQL - Language Statements + SQL - 语言语句 @@ -304,7 +304,7 @@ REINDEX [ ( option [, ...] ) ] { DA 当对分区索引或分区表执行带TABLESPACE子句的 REINDEX时,只有叶分区的表空间引用会被更新。由于 - 分区索引本身不会更新,建议另外对相应的分区表单独执行 + 分区索引本身不会更新,建议另外对这些分区索引单独执行 ALTER TABLE ONLY,以便后续附加的任何新分区都继承 新表空间。如果命令失败,可能不会把所有索引都移动到新表空间。重新运行 该命令将重建所有叶分区,并把先前未处理的索引移动到新表空间。 @@ -322,8 +322,8 @@ REINDEX [ ( option [, ...] ) ] { DA 并发重建索引 - index - rebuilding concurrently + 索引 + 并发重建 diff --git a/zh/20/ref/reindexdb.sgml b/zh/20/ref/reindexdb.sgml index fd1f2c08..09b3ccd6 100644 --- a/zh/20/ref/reindexdb.sgml +++ b/zh/20/ref/reindexdb.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation reindexdb 1 - Application + 应用程序 diff --git a/zh/20/ref/release_savepoint.sgml b/zh/20/ref/release_savepoint.sgml index 59f96e68..ca94cc38 100644 --- a/zh/20/ref/release_savepoint.sgml +++ b/zh/20/ref/release_savepoint.sgml @@ -10,13 +10,13 @@ PostgreSQL documentation 保存点 - releasing + 释放 RELEASE SAVEPOINT 7 - SQL - Language Statements + SQL - 语言语句 @@ -99,7 +99,7 @@ BEGIN; SAVEPOINT sp2; INSERT INTO table1 VALUES (3); RELEASE SAVEPOINT sp2; - INSERT INTO table1 VALUES (4))); -- generates an error + INSERT INTO table1 VALUES (4))); -- 产生错误 在这个例子中,应用程序请求释放保存点sp2,值 3 是在其中插入的。 这样会把该插入操作的事务上下文改为sp1。 diff --git a/zh/20/ref/repack.sgml b/zh/20/ref/repack.sgml index caac60df..57549a0d 100644 --- a/zh/20/ref/repack.sgml +++ b/zh/20/ref/repack.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation REPACK 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/reset.sgml b/zh/20/ref/reset.sgml index e8aeae8c..5e249ff9 100644 --- a/zh/20/ref/reset.sgml +++ b/zh/20/ref/reset.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation RESET 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/revoke.sgml b/zh/20/ref/revoke.sgml index 72ab2378..291980bb 100644 --- a/zh/20/ref/revoke.sgml +++ b/zh/20/ref/revoke.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation REVOKE 7 - SQL - Language Statements + SQL - 语言语句 @@ -131,7 +131,7 @@ REVOKE [ { ADMIN | INHERIT | SET } OPTION FOR ] [ GRANTED BY role_specification ] [ CASCADE | RESTRICT ] -where role_specification can be: +其中role_specification可以是: [ GROUP ] role_name | PUBLIC diff --git a/zh/20/ref/rollback.sgml b/zh/20/ref/rollback.sgml index d1c8fdd2..1a91b03e 100644 --- a/zh/20/ref/rollback.sgml +++ b/zh/20/ref/rollback.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ROLLBACK 7 - SQL - Language Statements + SQL - 语言语句 @@ -37,7 +37,7 @@ ROLLBACK [ WORK | TRANSACTION ] [ AND [ NO ] CHAIN ] 参数 - chained transactions + 链式事务 diff --git a/zh/20/ref/rollback_prepared.sgml b/zh/20/ref/rollback_prepared.sgml index 7ffe1af8..7438d9cc 100644 --- a/zh/20/ref/rollback_prepared.sgml +++ b/zh/20/ref/rollback_prepared.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation ROLLBACK PREPARED 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/rollback_to.sgml b/zh/20/ref/rollback_to.sgml index 843a612e..d5d8c0e0 100644 --- a/zh/20/ref/rollback_to.sgml +++ b/zh/20/ref/rollback_to.sgml @@ -10,13 +10,13 @@ PostgreSQL documentation 保存点 - rolling back + 回滚 ROLLBACK TO SAVEPOINT 7 - SQL - Language Statements + SQL - 语言语句 @@ -73,8 +73,8 @@ ROLLBACK [ WORK | TRANSACTION ] TO [ SAVEPOINT ] savepoint_name 就保存点而言,游标带有一些非事务性的行为。凡是在某个保存点内打开的游标, 在回滚该保存点时都会被关闭。如果先前打开的游标在某个随后又被回滚的保存点内受到了 - FETCHMOVE命令的影响,那么该游标会保留在这些命令使其指向的位置上 - (也就是说,由FETCHMOVE引起的游标移动不会被回滚)。 + FETCHMOVE命令的影响,那么该游标会保留在FETCH使其指向的位置上 + (也就是说,由FETCH引起的游标移动不会被回滚)。 关闭游标同样不会因回滚而撤销。不过,如果游标查询导致了其他副作用(例如该查询调用的 易变函数带来的副作用),且这些副作用发生在后来被回滚的保存点期间,那么它们 被回滚。如果某个游标的执行导致事务中止,该游标会进入不可执行状态, diff --git a/zh/20/ref/savepoint.sgml b/zh/20/ref/savepoint.sgml index fdca4151..5f9bea25 100644 --- a/zh/20/ref/savepoint.sgml +++ b/zh/20/ref/savepoint.sgml @@ -10,13 +10,13 @@ PostgreSQL documentation 保存点 - defining + 定义 SAVEPOINT 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/security_label.sgml b/zh/20/ref/security_label.sgml index fc969a4a..9c2b13d0 100644 --- a/zh/20/ref/security_label.sgml +++ b/zh/20/ref/security_label.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SECURITY LABEL 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/select.sgml b/zh/20/ref/select.sgml index de609be9..390e3107 100644 --- a/zh/20/ref/select.sgml +++ b/zh/20/ref/select.sgml @@ -21,7 +21,7 @@ PostgreSQL documentation SELECT 7 - SQL - Language Statements + SQL - 语言语句 @@ -1481,7 +1481,7 @@ SELECT * FROM (SELECT * FROM mytable FOR UPDATE) ss ORDER BY column1; REPEATABLE READSERIALIZABLE事务隔离级别下, - 这将导致序列化失败(带有SQLSTATE'40001'), + 这将导致串行化失败(SQLSTATE'40001'), 因此在这些隔离级别下不可能接收到无序的行。 diff --git a/zh/20/ref/select_into.sgml b/zh/20/ref/select_into.sgml index cb933f09..7bf13eab 100644 --- a/zh/20/ref/select_into.sgml +++ b/zh/20/ref/select_into.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SELECT INTO 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/set.sgml b/zh/20/ref/set.sgml index e9a70105..f91f51a0 100644 --- a/zh/20/ref/set.sgml +++ b/zh/20/ref/set.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SET 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/set_constraints.sgml b/zh/20/ref/set_constraints.sgml index 53d0c7a0..e5588db7 100644 --- a/zh/20/ref/set_constraints.sgml +++ b/zh/20/ref/set_constraints.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SET CONSTRAINTS 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/set_role.sgml b/zh/20/ref/set_role.sgml index ed65dec8..c32755be 100644 --- a/zh/20/ref/set_role.sgml +++ b/zh/20/ref/set_role.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SET ROLE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/set_session_auth.sgml b/zh/20/ref/set_session_auth.sgml index e520dd49..e7692edc 100644 --- a/zh/20/ref/set_session_auth.sgml +++ b/zh/20/ref/set_session_auth.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SET SESSION AUTHORIZATION 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/set_transaction.sgml b/zh/20/ref/set_transaction.sgml index ca7f3e50..8b3470a9 100644 --- a/zh/20/ref/set_transaction.sgml +++ b/zh/20/ref/set_transaction.sgml @@ -26,7 +26,7 @@ PostgreSQL documentation SET TRANSACTION 7 - SQL - Language Statements + SQL - 语言语句 @@ -66,7 +66,7 @@ SET SESSION CHARACTERISTICS AS TRANSACTION transa - 一个事务的隔离级别决定当其他事务并行运行时该事务能看见什么数据: + 一个事务的隔离级别决定当其他事务并发运行时该事务能看见什么数据: @@ -137,7 +137,7 @@ SET SESSION CHARACTERISTICS AS TRANSACTION transa 事务属性才会生效。当为一个事务同时选择这三个属性时,该事务在 首次获取其快照时可能会阻塞;在此之后,它便可以运行,而无需承担普通 SERIALIZABLE事务的常规开销,也不会有促成 - 序列化失败或因序列化失败而被取消的风险。这种模式非常适合长时间运行的 + 串行化失败或因串行化失败而被取消的风险。这种模式非常适合长时间运行的 报表或备份。 diff --git a/zh/20/ref/show.sgml b/zh/20/ref/show.sgml index 3b4be6bd..81bd6a80 100644 --- a/zh/20/ref/show.sgml +++ b/zh/20/ref/show.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation SHOW 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/start_transaction.sgml b/zh/20/ref/start_transaction.sgml index 57a74b2f..5026fa70 100644 --- a/zh/20/ref/start_transaction.sgml +++ b/zh/20/ref/start_transaction.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation START TRANSACTION 7 - SQL - Language Statements + SQL - 语言语句 @@ -64,15 +64,16 @@ START TRANSACTION [ transaction_mode - DEFERRABLE 这一 - transaction_mode 是 - PostgreSQL语言扩展。 + DEFERRABLE + transaction_mode + 是PostgreSQL的一种语言扩展。 SQL 标准要求在连续的transaction_modes之间有逗号, - 但出于历史原因PostgreSQL允许省略逗号。 + 但出于历史原因, + PostgreSQL允许省略逗号。 diff --git a/zh/20/ref/truncate.sgml b/zh/20/ref/truncate.sgml index 19dcc221..35cd8db0 100644 --- a/zh/20/ref/truncate.sgml +++ b/zh/20/ref/truncate.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation TRUNCATE 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/unlisten.sgml b/zh/20/ref/unlisten.sgml index 5e73e99e..6b52f1af 100644 --- a/zh/20/ref/unlisten.sgml +++ b/zh/20/ref/unlisten.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation UNLISTEN 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/update.sgml b/zh/20/ref/update.sgml index f34ccafc..5b531c9a 100644 --- a/zh/20/ref/update.sgml +++ b/zh/20/ref/update.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation UPDATE 7 - SQL - Language Statements + SQL - 语言语句 @@ -389,12 +389,12 @@ UPDATE count 在被移动的行上并发执行UPDATE或 - DELETE时,有可能收到序列化失败错误。假设会话 1 - 正在更新某个分区键,与此同时,一个对该行可见的并发会话 2 对该行 + DELETE时,有可能收到串行化失败错误。假设会话 1 + 正在对某个分区键执行UPDATE,与此同时,一个能够看到该行的并发会话 2 对该行 执行UPDATEDELETE操作。在 这种情况下,会话 2 的UPDATE或 - DELETE将检测到行移动,并引发序列化失败错误 - (其 SQLSTATE 代码始终为'40001')。如果发生 + DELETE将检测到行移动,并引发串行化失败错误 + (其 SQLSTATE 代码始终为'40001')。如果发生 这种情况,应用程序可能需要重试事务。在表未分区或没有发生行移动 的通常情况下,会话 2 会识别出新更新的那一行,并在这个新行版本上执行 UPDATE/DELETE。 diff --git a/zh/20/ref/vacuum.sgml b/zh/20/ref/vacuum.sgml index 1c8a00d0..d46aa496 100644 --- a/zh/20/ref/vacuum.sgml +++ b/zh/20/ref/vacuum.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation VACUUM 7 - SQL - Language Statements + SQL - 语言语句 @@ -76,7 +76,7 @@ VACUUM [ ( option [, ...] ) ] [ 。 - 如需禁用该功能,可以使用PARALLEL选项并将并行工作者数指定为零。 + 如需禁用该功能,可以使用PARALLEL选项并将并行工作进程数指定为零。 VACUUM FULL会把表的全部内容重写到一个没有额外空闲空间的新磁盘文件中, 从而让未使用的空间能够返还给操作系统。这种形式要慢得多,并且在处理每个表时都需要 ACCESS EXCLUSIVE锁。 @@ -87,18 +87,7 @@ VACUUM [ ( option [, ...] ) ] [ 参数 - - FULL - - - 该选项已弃用,它会使VACUUM的行为类似于不带 - USING INDEX子句的REPACK。 - 这种表压实方法比VACUUM耗时长得多,并且会独占锁定该表。 - 这种方法还需要额外的磁盘空间,因为它会写出该表的一个新副本,并且在操作完成之前 - 不会释放旧副本。通常,只有当需要从表内回收大量空间时才应使用这种方法。 - - - + FREEZE @@ -227,7 +216,7 @@ VACUUM [ ( option [, ...] ) ] [ PARALLEL - 指定可用于的最大并行工作者数, + 指定可用于的最大并行工作进程数, 其数量还会进一步受到的限制。 此选项不能与FULL选项一起使用。 @@ -278,7 +267,20 @@ VACUUM [ ( option [, ...] ) ] [ - + + FULL + + + 该选项已弃用,它会使VACUUM的行为类似于不带 + USING INDEX子句的REPACK。 + 这种表压实方法比VACUUM耗时长得多,并且会独占锁定该表。 + 这种方法还需要额外的磁盘空间,因为它会写出该表的一个新副本,并且在操作完成之前 + 不会释放旧副本。通常,只有当需要从表内回收大量空间时才应使用这种方法。 + + + + + boolean @@ -369,7 +371,7 @@ VACUUM [ ( option [, ...] ) ] [ - 我们建议定期对所有数据库执行清理,以移除死行。PostgreSQL提供了一个autovacuum机制, + 我们建议定期对所有数据库执行清理,以移除死行。PostgreSQL提供了一个自动清理(autovacuum)机制, 可以自动执行常规清理维护。有关自动与手动清理的更多信息,参见 @@ -387,8 +389,8 @@ VACUUM [ ( option [, ...] ) ] [ VACUUM会显著增加 I/O 流量,这可能导致其他活动会话性能变差。 - 因此,有时建议使用基于代价的清理延迟特性。对于并行清理,每个工作者的睡眠时长 - 都与该工作者完成的工作量成比例。详见。 + 因此,有时建议使用基于代价的清理延迟特性。对于并行清理,每个工作进程的睡眠时长 + 都与该工作进程完成的工作量成比例。详见 @@ -404,7 +406,7 @@ VACUUM [ ( option [, ...] ) ] [ 示例 - 清理单个表onek,对其执行优化器分析,并打印清理和分析的详细信息: + 清理单个表onek,对其进行分析以供优化器使用,并打印清理和分析的详细信息: VACUUM (VERBOSE, ANALYZE) onek; diff --git a/zh/20/ref/vacuumdb.sgml b/zh/20/ref/vacuumdb.sgml index 348c1f08..c271f8ee 100644 --- a/zh/20/ref/vacuumdb.sgml +++ b/zh/20/ref/vacuumdb.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation vacuumdb 1 - Application + 应用程序 @@ -132,8 +132,8 @@ PostgreSQL documentation - 指定给定一次 缓冲区访问策略(Buffer Access Strategy) - 环形缓冲区大小,供 vacuumdb 调用使用。这个大小用于计算将作为该策略一部分被重用的共享缓冲区数量。参见 + 为一次给定的 vacuumdb 调用指定缓冲区访问策略(Buffer Access Strategy) + 环形缓冲区大小。这个大小用于计算将作为该策略一部分被重用的共享缓冲区数量。参见 @@ -196,7 +196,7 @@ PostgreSQL documentation - 积极地冻结元组。 + 激进地冻结元组。 @@ -234,12 +234,12 @@ PostgreSQL documentation - 仅对 multixact ID 年龄至少为 mxid_age - 的表执行清理或分析命令。此设置可用于优先处理表,以防止 multixact ID 回卷 + 仅对 多事务 ID 年龄至少为 mxid_age + 的表执行清理或分析命令。此设置可用于优先处理表,以防止 多事务 ID 回卷 (见 )。 - 就此选项而言,一个关系的 multixact ID 年龄,是其主关系及其关联的 + 就此选项而言,一个关系的 多事务 ID 年龄,是其主关系及其关联的 TOAST 表(如果存在)年龄中的较大者。由于 vacuumdb 发出的命令在必要时也会处理该关系的 TOAST 表,因此无需单独考虑它。 diff --git a/zh/20/ref/values.sgml b/zh/20/ref/values.sgml index 458c8597..8d6337a9 100644 --- a/zh/20/ref/values.sgml +++ b/zh/20/ref/values.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation VALUES 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/ref/wait_for.sgml b/zh/20/ref/wait_for.sgml index ad7ca8b7..d591e04a 100644 --- a/zh/20/ref/wait_for.sgml +++ b/zh/20/ref/wait_for.sgml @@ -11,7 +11,7 @@ PostgreSQL documentation WAIT FOR 7 - SQL - Language Statements + SQL - 语言语句 diff --git a/zh/20/runtime.sgml b/zh/20/runtime.sgml index 6bcaf64f..a4025dac 100644 --- a/zh/20/runtime.sgml +++ b/zh/20/runtime.sgml @@ -17,7 +17,7 @@ <productname>PostgreSQL</productname>用户账户 - postgres user + postgres 用户 @@ -47,7 +47,7 @@ - 在做任何事情之前,必须先在磁盘上初始化一个数据库存储区域。我们把它称为数据库集簇。(SQL 标准使用术语 catalog cluster。)数据库集簇是由一个正在运行的数据库服务器实例管理的一组数据库。初始化之后,数据库集簇中会包含一个名为postgres的数据库,作为供工具、用户和第三方应用使用的默认数据库。数据库服务器本身并不要求该postgres数据库存在,但许多外部工具程序都假定它存在。初始化期间,集簇中还会创建另外两个数据库,名为template1template0。顾名思义,它们会作为后续新建数据库的模板;不应将它们用于实际工作。(关于在集簇中创建新数据库的信息,见。) + 在做任何事情之前,必须先在磁盘上初始化一个数据库存储区域。我们把它称为数据库集簇。(SQL 标准使用术语目录集簇(catalog cluster)。)数据库集簇是由一个正在运行的数据库服务器实例管理的一组数据库。初始化之后,数据库集簇中会包含一个名为postgres的数据库,作为供工具、用户和第三方应用使用的默认数据库。数据库服务器本身并不要求该postgres数据库存在,但许多外部工具程序都假定它存在。初始化期间,集簇中还会创建另外两个数据库,名为template1template0。顾名思义,它们会作为后续新建数据库的模板;不应将它们用于实际工作。(关于在集簇中创建新数据库的信息,见。) @@ -112,9 +112,7 @@ postgres$ initdb -D /usr/local/pgsql/data 另外,指定,以避免使用默认的trust认证方式;或者在运行initdb之后、首次启动服务器之前修改生成的pg_hba.conf文件。(其他合理方法包括使用peer认证,或使用文件系统权限限制连接。更多信息见。) - - initdb还会为数据库集簇初始化默认区域设置locale。通常,它只是采用环境中的区域设置,并将其应用到新初始化的数据库。你也可以为数据库指定不同的区域设置;更多信息见。该数据库集簇内部使用的默认排序顺序由initdb设定。虽然你可以创建采用不同排序顺序的新数据库,但initdb创建的模板数据库所使用的排序顺序,若不删除并重建它们就无法更改。使用非CPOSIX区域设置还会带来性能影响,因此第一次就做出正确选择很重要。 - + initdb 还会初始化数据库集簇的默认区域设置区域设置。通常,它会直接采用环境中的区域设置,并将其应用于初始化的数据库。可以为数据库指定不同的区域设置;更多信息见 。特定数据库集簇中使用的默认排序顺序由 initdb 设置,虽然你可以使用不同的排序顺序创建新数据库,但 initdb 创建的模板数据库所使用的顺序,只有删除并重建这些数据库才能更改。使用 CPOSIX 以外的区域设置还会影响性能。因此,一开始就作出正确选择很重要。 initdb还会为数据库集簇设置默认字符集编码。通常应选择与区域设置相匹配的字符集编码。详见。 @@ -162,9 +160,7 @@ postgres$ initdb -D /usr/local/pgsql/data 对于在PostgreSQL中使用NFS,唯一硬性要求是文件系统必须使用hard选项挂载。使用hard选项时,如果出现网络问题,进程可能会无限期地挂起,因此这种配置需要配套谨慎的监控措施。soft选项会在网络问题出现时中断系统调用,但PostgreSQL不会重试以这种方式被中断的系统调用,因此任何此类中断都会导致报告 I/O 错误。 - - 没有必要使用sync挂载选项。async选项的行为已经足够,因为PostgreSQL会在适当的时候发出fsync调用来刷新写缓存。(这和它在本地文件系统上的工作方式类似。)但是,强烈建议在支持该选项的NFS服务器端系统上使用sync导出选项(主要是 Linux)。否则,NFS 客户端上的fsync或等效操作实际上并不能保证数据到达服务器上的持久存储,这可能导致类似于将参数设为关闭时那样的损坏。这些挂载和导出选项的默认值在不同厂商和版本间并不相同,因此无论如何都建议检查它们,并且最好显式指定,以避免歧义。 - + 没有必要使用 sync 挂载选项。async 选项的行为已经足够,因为 PostgreSQL 会在适当的时候发出 fsync 调用将写缓存刷盘。(这和它在本地文件系统上的工作方式类似。)但是,强烈建议在支持该选项的 NFS 服务器端系统上使用 sync 导出选项(主要是 Linux)。否则,NFS 客户端上的 fsync 或等效操作实际上并不能保证数据到达服务器上的持久存储,这可能导致类似于将参数 设为关闭时那样的损坏。这些挂载和导出选项的默认值在不同厂商和版本间并不相同,因此无论如何都建议检查它们,并且最好显式指定,以避免歧义。 在某些情况下,可以通过 NFS 或更底层的协议(例如 iSCSI)访问外部存储产品。在后一种情况下,存储会表现为块设备,可以在其上创建任意可用的文件系统。这种方式或许能让 DBA 不必应对 NFS 的某些特性,但当然,管理远程存储的复杂性会转移到其他层面。 @@ -215,7 +211,7 @@ pg_ctl start -l logfile - 通常,你会希望在计算机启动时就启动数据库服务器。booting启动服务器时自动启动脚本依赖于操作系统。PostgreSQLcontrib/start-scripts 目录中附带了一些示例脚本。安装这些脚本需要 root 权限。 + 通常,你会希望在计算机启动时就启动数据库服务器。引导期间启动服务器自动启动脚本依赖于操作系统。PostgreSQLcontrib/start-scripts 目录中附带了一些示例脚本。安装这些脚本需要 root 权限。 @@ -232,14 +228,14 @@ su postgres -c 'pg_ctl start -D /usr/local/pgsql/data -l serverlog' 对于FreeBSD,请查看PostgreSQL源码发布包中的contrib/start-scripts/freebsd文件。 - FreeBSDstart script + FreeBSD启动脚本 OpenBSD上,把以下内容加入/etc/rc.local: - OpenBSDstart script + OpenBSD启动脚本 if [ -x /usr/local/pgsql/bin/pg_ctl -a -x /usr/local/pgsql/bin/postgres ]; then su -l postgres -c '/usr/local/pgsql/bin/pg_ctl start -s -l /var/postgresql/log -D /usr/local/pgsql/data' @@ -252,7 +248,7 @@ fi Linux系统上,可以把 - Linuxstart script + Linux启动脚本 /usr/local/pgsql/bin/pg_ctl start -l logfile -D /usr/local/pgsql/data @@ -292,14 +288,14 @@ WantedBy=multi-user.target NetBSD上,可根据偏好使用FreeBSDLinux的启动脚本。 - NetBSDstart script + NetBSD启动脚本 Solaris上,创建一个名为/etc/init.d/postgresql的文件,其中包含以下内容: - Solarisstart script + Solaris启动脚本 su - postgres -c "/usr/local/pgsql/bin/pg_ctl start -l logfile -D /usr/local/pgsql/data" @@ -396,7 +392,7 @@ psql: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: No such 管理内核资源 - PostgreSQL有时会耗尽操作系统的各种资源限制,尤其是在同一系统上运行多个服务器副本,或在非常大型的安装环境中时更是如此。本节解释PostgreSQL使用的内核资源,以及你可以采取哪些步骤来解决与内核资源消耗相关的问题。 + PostgreSQL有时会达到操作系统的各种资源上限,尤其是在同一系统上运行多个服务器实例,或在非常大型的安装环境中时更是如此。本节解释PostgreSQL使用的内核资源,以及你可以采取哪些步骤来解决与内核资源消耗相关的问题。 @@ -420,7 +416,7 @@ psql: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: No such - System V IPC 功能通常受系统范围的分配限制约束。当PostgreSQL超出这些限制之一时,服务器会拒绝启动,并留下带有指导性的错误消息,说明问题所在以及应如何处理(另见)。相关内核参数在不同系统上的命名基本一致,给出了概览;不过,设置它们的方法却各不相同。下面给出一些平台上的建议。 + System V IPC 功能通常受系统范围的分配限制约束。当PostgreSQL超出这些限制之一时,服务器会拒绝启动,并应留下带有指导性的错误消息,说明问题所在以及应如何处理(另见)。相关内核参数在不同系统上的命名基本一致,给出了概览;不过,设置它们的方法却各不相同。下面给出一些平台上的建议。
@@ -445,7 +441,7 @@ psql: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: No such SHMMAX 共享内存段的最大尺寸(字节) - 至少 1kB,但是默认值通常要高一些 + 至少 1kB,但是默认值通常高得多 @@ -508,8 +504,8 @@ psql: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: No such
- PostgreSQL要求少量字节的 System V 共享内存(在 64 位平台上通常是 48 字节)用于每一个服务器拷贝。在大多数现代操作系统上,这个量很容易得到。 - 但是,如果你运行了很多个服务器副本,或者显式配置服务器以使用大量 System V 共享内存(参见 ), + PostgreSQL要求少量字节的 System V 共享内存(在 64 位平台上通常是 48 字节)用于每一个服务器实例。在大多数现代操作系统上,这个量很容易得到。 + 但是,如果你运行了很多个服务器实例,或者显式配置服务器以使用大量 System V 共享内存(参见 ), 可能需要增加SHMALL(系统范围内 System V 共享内存的总量)。注意在很多系统上SHMALL是以页面而不是字节来度量。 @@ -518,14 +514,14 @@ psql: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: No such
- 当使用 System V 信号量时,PostgreSQL会为每个允许连接()、每个允许自动清理工作进程()、每个允许 WAL 发送进程()、每个允许后台进程()等分配一个信号量,按 16 个一组。运行期计算参数会报告所需信号量数;可在启动服务器前用如下命令查看: + 当使用 System V 信号量时,PostgreSQL会为每个允许连接()、每个允许自动清理工作进程()、每个允许 WAL 发送进程()、每个允许后台进程()等分配一个信号量,按 16 个一组。运行期计算参数会报告所需信号量数;可在启动服务器前用如下postgres命令查看: $ postgres -D $PGDATA -C num_os_semaphores - 每组 16 个信号量还包含第 17 个信号量,用于存放magic number,以检测与其他应用信号量集合的冲突。系统最大信号量数由 SEMMNS 设定,因此至少应为 num_os_semaphores 加上每组 16 个所需信号量的一个附加量(见中的公式)。SEMMNI决定系统中同一时刻可存在的信号量集合数上限,因此至少应为 ceil(num_os_semaphores / 16)。降低允许连接数是对通常带有误导措辞设备上没有剩余空间(来自semget)这类失败的临时缓解手段。 + 每组 16 个信号量还包含第 17 个信号量,用于存放魔数,以检测与其他应用信号量集合的冲突。系统最大信号量数由 SEMMNS 设定,因此至少应为 num_os_semaphores 加上每组 16 个所需信号量的一个附加量(见中的公式)。SEMMNI决定系统中同一时刻可存在的信号量集合数上限,因此至少应为 ceil(num_os_semaphores / 16)。降低允许连接数是对通常带有误导措辞No space left on device(来自semget)这类失败的临时缓解手段。 @@ -533,7 +529,7 @@ $ postgres -D $PGDATA -C num_os_semaphores - 与semaphore undo有关的其他各种设置,如SEMMNUSEMUME,不会影响PostgreSQL。 + 与信号量撤销有关的其他各种设置,如SEMMNUSEMUME,不会影响PostgreSQL @@ -551,9 +547,7 @@ $ postgres -D $PGDATA -C num_os_semaphores 对于 SHMMAX 之类的参数,通常不需要任何特殊配置,因为看起来系统已经配置为允许将所有内存都用作共享内存。这类配置也常用于其他数据库,例如 DB/2 - - 不过,可能需要修改全局 ulimit 信息,位于 /etc/security/limits,因为文件大小(fsize)和文件数(nofiles)的默认硬限制可能过低。 - + 不过,可能需要修改 /etc/security/limits 中的全局 ulimit 信息,因为文件大小(fsize)和文件数量(nofiles)的默认硬限制可能过低。 @@ -647,7 +641,7 @@ $ postgres -D $PGDATA -C num_os_semaphores - 共享内存大小设置可以通过sysctl界面更改。例如,允许 16 GB: + 共享内存大小设置可以通过sysctl接口更改。例如,允许 16 GB: $ sysctl -w kernel.shmmax=17179869184 $ sysctl -w kernel.shmall=4194304 @@ -685,9 +679,7 @@ kern.sysv.shmall=1024 SHMMAX 只能设置为 4096 的倍数。 - - 在这个平台上,SHMALL以 4kB 的页面度量。 - + 在这个平台上,SHMALL 以 4 kB 的页为单位。 SHMMNI 之外,其他设置都可以使用 sysctl 动态更改。不过,最好还是通过/etc/sysctl.conf设置你希望使用的值,这样重启后仍能保留。 @@ -702,7 +694,7 @@ kern.sysv.shmall=1024 - 默认的共享内存和信号量设置对于大多数 PostgreSQL 应用通常已经足够。Solaris 现在将SHMMAX的默认值设为系统 RAM 的四分之一。要进一步调整这一设置,可使用与postgres用户关联的项目设置。例如,以root运行下列命令: + 默认的共享内存和信号量设置对于大多数 PostgreSQL 应用通常已经足够。Solaris 将SHMMAX的默认值设为系统 RAM 的四分之一。要进一步调整这一设置,可使用与postgres用户关联的项目设置。例如,以root运行下列命令: projadd -c "PostgreSQL DB User" -K "project.max-shm-memory=(privileged,8GB,deny)" -U postgres -G postgres user.postgres @@ -752,7 +744,7 @@ WARNING: could not remove shared memory segment "/PostgreSQL.1450751626": No su - 用户注销可能会作为维护作业的一部分发生,也可能在管理员以postgres用户或类似名称登录时手工触发,因此通常很难彻底防止。 + 用户注销可能会作为维护作业的一部分发生,也可能在管理员以postgres用户登录或执行类似操作时手工触发,因此通常很难彻底防止。 @@ -833,7 +825,7 @@ default:\ Linux 内存过量分配 - memory overcommit + 内存过量分配 @@ -841,7 +833,7 @@ default:\ - overcommit + 过量分配 @@ -861,7 +853,7 @@ Out of Memory: Killed process 12345 (postgres). - 如果导致系统耗尽内存的正是PostgreSQL自身,那么你可以通过调整配置来避免该问题。在某些情况下,调低与内存相关的配置参数会有帮助,尤其是shared_bufferswork_memhash_mem_multiplier。在其他情况下,允许数据库服务器接受过多连接也可能导致这一问题。很多时候,更好的做法是减小max_connections,并转而使用外部连接池软件。 + 如果导致系统耗尽内存的正是PostgreSQL自身,那么你可以通过调整配置来避免该问题。在某些情况下,调低与内存相关的配置参数会有帮助,尤其是shared_bufferswork_memhash_mem_multiplier。在其他情况下,允许数据库服务器接受过多连接也可能导致这一问题。很多时候,更好的做法可能是减小max_connections,并转而使用外部连接池软件。 @@ -873,17 +865,25 @@ sysctl -w vm.overcommit_memory=2 - 另一种方法可在修改或不修改 vm.overcommit_memory 的情况下使用:把 PostgreSQL 主进程的 OOM score adjustment 值设为 -1000,从而保证它不会成为 OOM 杀手的目标。最简单的做法是在 PostgreSQL 启动脚本中、调用 postgres 之前执行以下命令: + 另一种方法可在修改或不修改 vm.overcommit_memory 的情况下使用: + 把 postmaster 进程专属的OOM 评分调整值设为 -1000, + 从而保证它不会成为 OOM 杀手的目标。最简单的做法是在 PostgreSQL + 启动脚本中、调用 postgres 之前执行: echo -1000 > /proc/self/oom_score_adj - 请注意,这个操作必须以 root 身份完成,否则不会生效。因此,最容易放置该操作的位置是由 root 拥有的启动脚本。如果这样做,你还应该在调用 postgres 之前,在启动脚本中设置这些环境变量: + 请注意,这个操作必须以 root 身份完成,否则不会生效;因此,由 root 拥有的启动脚本是最容易执行该操作的位置。 + 如果这样做,还应在调用 postgres 之前,在启动脚本中设置以下环境变量: export PG_OOM_ADJUST_FILE=/proc/self/oom_score_adj export PG_OOM_ADJUST_VALUE=0 - 这些设置会使 postgres 子进程以默认值零的 OOM score adjustment 运行,因此 OOM 杀手在需要时仍可将它们作为目标。如果你希望子进程使用其他 OOM score adjustment 值,也可以为 PG_OOM_ADJUST_VALUE 指定其他数值(也可省略,此时默认为零)。如果不设置 PG_OOM_ADJUST_FILE,子进程就会和主进程使用相同的 OOM score adjustment,这并不明智,因为这样做的目的正是为了确保主进程拥有优先保护设置。 - + 这些设置会使 postmaster 子进程以常规的 OOM 评分调整值零运行,以便 OOM 杀手在需要时仍可将它们作为目标。 + 如果希望子进程以其他 OOM 评分调整值运行,也可以为 PG_OOM_ADJUST_VALUE 指定其他值。 + (也可以省略 PG_OOM_ADJUST_VALUE,此时默认为零。) + 如果不设置 PG_OOM_ADJUST_FILE,子进程就会和 postmaster 使用相同的 OOM 评分调整值, + 这并不明智,因为这样做的目的正是确保 postmaster 获得优先保护。 +
@@ -923,8 +923,9 @@ $ cat /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages - 你可能还需要授予数据库服务器的操作系统用户使用大页的权限,例如通过sysctl设置vm.hugetlb_shm_group,以及/或者授予其使用ulimit -l锁定内存的权限。 - + 可能还需要通过 sysctl 设置 vm.hugetlb_shm_group, + 授予数据库服务器的操作系统用户使用大页的权限,以及/或者通过 ulimit -l 授予其锁定内存的权限。 + PostgreSQL对大页的默认行为是:只要可能就使用它们,采用系统默认的大页大小;如果失败,则回退到普通页面。要强制使用大页,可以在postgresql.conf中将设为on。请注意,在这种设置下,如果没有足够的大页可用,PostgreSQL将无法启动。 @@ -946,7 +947,7 @@ $ cat /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages - 有几种关闭数据库服务器的方法。在后台,它们都简化为向主管 postgres 进程发送信号。 + 有几种关闭数据库服务器的方法。这些方法在内部都是向主管 postgres 进程发送信号。 @@ -988,7 +989,7 @@ $ cat /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepagesSIGQUIT并等待它们终止。 如果有任何进程在 5 秒内未终止,它们将被发送SIGKILL。 一旦所有子进程退出,主管服务器进程将立即退出,而不进行正常的数据库关闭处理。 - 这会导致下次启动时通过回放 WAL 日志执行恢复。仅建议在紧急情况下使用。 + 这会导致下次启动时通过重放 WAL 日志执行恢复。仅建议在紧急情况下使用。 @@ -1004,10 +1005,7 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` - - 最好不要使用SIGKILL关闭服务器。这样做将会阻止服务器释放共享内存和信号量。 - 此外,使用SIGKILL杀掉postgres进程时,postgres不会有机会将信号传播到它的子进程,所以可能也必须手工杀掉单个的子进程。 - + 最好不要使用 SIGKILL 关闭服务器。这样做会阻止服务器释放共享内存和信号量。此外,SIGKILL 会终止 postgres 进程,使其没有机会将信号转发给子进程,因此可能还需要手动逐个终止子进程。 @@ -1020,12 +1018,12 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`升级 PostgreSQL 集簇 - upgrading + 升级 - version - compatibility + 版本 + 兼容性 @@ -1045,7 +1043,7 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` - 新的主版本通常还会引入一些用户可见的不兼容变化,因此应用程序可能也需要做出修改。所有用户可见的变化都列在发行说明()中;请特别留意标为Migration的小节。虽然你可以从一个主版本直接升级到另一个主版本,而不必逐个升级中间版本,但仍应阅读所有中间版本的主版本发行说明。 + 新的主版本通常还会引入一些用户可见的不兼容变化,因此应用程序可能也需要做出修改。所有用户可见的变化都列在发行说明()中;请特别留意标为迁移(Migration)的小节。虽然你可以从一个主版本直接升级到另一个主版本,而不必逐个升级中间版本,但仍应阅读所有中间版本的主版本发行说明。 @@ -1104,7 +1102,7 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` - 这涉及以后端函数 API 为代表的变更,该 API 使用 C 语言编写。这类变更会影响那些深入引用服务器内部后端函数的代码。 + 这涉及使用 C 语言编写的后端函数 API 的变更。这类变更会影响那些深入引用服务器内部后端函数的代码。 @@ -1116,7 +1114,7 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`通过pg_dumpall升级数据 - 一种升级方法是从某个主版本的PostgreSQL导出数据,再在另一个版本中恢复。要这样做,必须使用逻辑备份工具,例如pg_dumpall;文件系统级备份方法不起作用。(系统中有相应检查,会阻止你在不兼容版本的PostgreSQL上使用某个数据目录,因此即便误用错误版本的服务器去启动某个数据目录,通常也不会造成太大损害。) + 一种升级方法是从某个主版本的PostgreSQL转储数据,再在另一个版本中恢复。要这样做,必须使用逻辑备份工具,例如pg_dumpall;文件系统级备份方法不起作用。(系统中有相应检查,会阻止你在不兼容版本的PostgreSQL上使用某个数据目录,因此即便误用错误版本的服务器去启动某个数据目录,通常也不会造成太大损害。) @@ -1131,13 +1129,13 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` - 如果是在制作备份,请确认数据库此时没有正在进行更新。这不会影响备份的一致性,但那些变更当然不会包含在备份中。必要时,可修改/usr/local/pgsql/data/pg_hba.conf中的访问权限(或采用等效方法),禁止除你之外的其他人访问数据库。有关访问控制的更多信息见。 + 如果是在制作备份,请确认数据库此时没有正在进行更新。更新操作不会影响备份的完整性,但那些变更当然不会包含在备份中。必要时,可修改/usr/local/pgsql/data/pg_hba.conf(或等效文件)中的访问权限,禁止除你之外的其他人访问数据库。有关访问控制的更多信息见 pg_dumpall - use during upgrade + 在升级期间使用 要备份整个数据库安装,请输入: @@ -1158,7 +1156,7 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` pg_ctl stop - 在那些会自动启动PostgreSQL的系统上,可能已经有某个启动脚本能完成同样的工作。例如,在Red Hat Linux系统上,也许下面这条命令就可以: + 在那些会在开机时自动启动PostgreSQL的系统上,可能已经有某个启动脚本能完成同样的工作。例如,在Red Hat Linux系统上,也许下面这条命令就可以: /etc/rc.d/init.d/postgresql stop @@ -1213,12 +1211,9 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` - - 最后,使用新的psql从备份恢复数据: - + 最后,使用以下命令从备份恢复数据: /usr/local/pgsql/bin/psql -d postgres -f outputfile - - 这里务必使用新的psql。 +这里应使用新版 psql @@ -1249,7 +1244,7 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 通过复制升级数据 - 也可以使用逻辑复制方法,创建一个运行较新版本PostgreSQL的备库。之所以可行,是因为逻辑复制支持不同主版本PostgreSQL之间进行复制。该备库可以与旧服务器部署在同一台机器上,也可以部署在不同机器上。一旦它与主库(运行旧版本PostgreSQL)同步,就可以切换主备角色,让备库提升为主库,并关闭旧的数据库实例。这种切换通常只会带来几秒钟的停机时间。 + 也可以使用逻辑复制方法,创建一个运行较新版本PostgreSQL的备库。之所以可行,是因为逻辑复制支持不同主版本PostgreSQL之间进行复制。该备库可以与旧服务器部署在同一台机器上,也可以部署在不同机器上。一旦它与主库(运行旧版本PostgreSQL)同步,就可以切换主备角色,让备库提升为主库,并关闭旧的数据库实例。这种切换使升级只需几秒钟的停机时间。 @@ -1283,17 +1278,14 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 - 要防止 SSL 欺骗,服务器必须配置为仅接受 hostssl 连接(),并且具备 SSL 密钥和证书文件()。TCP 客户端必须使用 sslmode=verify-caverify-full 连接,并安装适当的根证书文件()。另外,也可使用 SSL 实现定义的系统 CA 池(system CA pool),即设置 sslrootcert=system;出于安全考虑,此时会强制使用 sslmode=verify-full,因为获得由公共 CA 签发的证书通常并不困难。 + 要通过 SSL 防止服务器欺骗,服务器必须配置为仅接受 hostssl 连接(),并且具备 SSL 密钥和证书文件()。TCP 客户端必须使用 sslmode=verify-caverify-full 连接,并安装适当的根证书文件()。另外,也可使用 SSL 实现定义的系统 CA 池,即设置 sslrootcert=system;出于安全考虑,此时会强制使用 sslmode=verify-full,因为获得由公共 CA 签发的证书通常并不困难。 在网络上使用 scram-sha-256 密码认证时,为防止服务器欺骗,应确保通过 SSL 连接服务器,并使用上一段描述的任一防欺骗方法。此外,libpq 中的 SCRAM 实现无法保护整个认证交换过程,但使用连接参数 channel_binding=require 可对服务器欺骗提供一定缓解。攻击者若用伪造服务器拦截 SCRAM 交换,可能通过离线分析推导出客户端哈希密码。 - - 要防止 GSSAPI 欺骗,必须将服务器配置为仅接受hostgssenc连接 () 并对它们使用gss认证。 - TCP 客户端则必须使用 gssencmode=require 发起连接。 - + 要通过 GSSAPI 防止服务器欺骗,服务器必须配置为仅接受 hostgssenc 连接(),并对这些连接使用 gss 认证。TCP 客户端必须使用 gssencmode=require 连接。
@@ -1305,7 +1297,7 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 - PostgreSQL提供了多个层次的加密,并在防止数据因数据库服务器被盗、不可靠的管理员或不安全网络等原因而泄露方面提供了很高的灵活性。对于医疗记录、金融交易等敏感数据,加密也可能是合规要求的一部分。 + PostgreSQL提供了多个层次的加密,并在防止数据因数据库服务器被盗、不诚实的管理员或不安全网络等原因而泄露方面提供了很高的灵活性。为了保护医疗记录、金融交易等敏感数据,也可能需要使用加密。 @@ -1320,9 +1312,7 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 - - 对 MD5 加密密码的支持已弃用,并将在未来版本的 PostgreSQL 中移除。迁移到其他密码类型的细节见 。 - + 对 MD5 加密密码的支持已弃用,并将在PostgreSQL的未来版本中移除。迁移到其他密码类型的详细信息见 @@ -1445,7 +1435,7 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 - 如果私钥受密码保护,服务器会提示输入该密码,并在输入之前不会启动。默认情况下,使用密码会禁用无需重启服务器即可更改 SSL 配置的能力,不过参见。此外,在 Windows 上完全无法使用带密码保护的私钥。 + 如果私钥受口令保护,服务器会提示输入该口令,并在输入之前不会启动。默认情况下,使用口令会禁用无需重启服务器即可更改 SSL 配置的能力,不过参见。此外,在 Windows 上完全无法使用带口令保护的私钥。 @@ -1472,7 +1462,7 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 - 使用NULL-SHANULL-MD5密码套件,可以在几乎没有加密开销的情况下完成认证。不过,中间人仍然能够读取并转发客户端与服务器之间的通信。此外,与认证的开销相比,加密开销本身通常很小。基于这些原因,不建议使用 NULL 密码套件。 + 使用NULL-SHANULL-MD5密码套件,可以在没有加密开销的情况下完成认证。不过,中间人仍然能够读取并转发客户端与服务器之间的通信。此外,与认证的开销相比,加密开销本身很小。基于这些原因,不建议使用 NULL 密码套件。 @@ -1785,9 +1775,7 @@ psql -h localhost -p 63333 postgres 对数据库服务器来说,它看到的是来自主机foo.com上用户joelocalhost绑定地址的连接,并将应用为该用户到该绑定地址所配置的认证方式。请注意,服务器不会认为这是 SSL 加密连接,因为实际上SSH服务器与PostgreSQL服务器之间并没有加密。不过这通常不会带来额外安全风险,因为两者位于同一台机器上。 - - 要让这条隧道建立成功,你必须能够像建立终端会话那样,通过sshjoe@foo.com身份连接。 - + 要让这条隧道建立成功,你必须有权通过 sshjoe@foo.com 身份连接,就像尝试使用 ssh 创建终端会话一样。 你也可以把端口转发设成这样: diff --git a/zh/20/spgist.sgml b/zh/20/spgist.sgml index 35430a86..ea4d1790 100644 --- a/zh/20/spgist.sgml +++ b/zh/20/spgist.sgml @@ -4,7 +4,7 @@ SP-GiST 索引 - index + 索引 SP-GiST @@ -12,7 +12,7 @@ 简介 - SP-GiST 是 space-partitioned GiST + SP-GiST 是空间分区 GiST 的缩写。SP-GiST 支持分区搜索树,这使得开发多种不同的 非平衡数据结构成为可能,例如四叉树、k-d 树以及基数树(trie)。这些结构 的共同特征是,它们会反复将搜索空间划分为不必等大的分区。与这种划分规则良 @@ -49,7 +49,7 @@ 内置操作符类 - 核心 PostgreSQL 发行版包含了 + PostgreSQL 核心发行版包含了 SP-GiST 操作符类,如 所示。 @@ -232,11 +232,11 @@ - SP-GiST 核心代码会处理空项。虽然 - SP-GiST 索引确实会为被索引列中的空值存储项,但这一 - 点对索引操作符类代码是隐藏的:不会有空的索引项或搜索条件传递给操作符类 - 方法。(这里假定 SP-GiST 操作符是严格的,因此对空 - 值不可能成功。)因此,这里不再进一步讨论空值。 + SP-GiST 核心代码负责处理值为 null 的索引项。虽然 + SP-GiST 索引会为被索引列中的 null 值存储索引项, + 但索引操作符类代码看不到这些项:值为 null 的索引项或搜索条件绝不会传给 + 操作符类方法。(这里假定 SP-GiST 操作符是严格的, + 因此对 null 值不可能返回真。)所以这里不再讨论 null 值。 @@ -286,8 +286,8 @@ typedef struct spgConfigOut Oid prefixType; /* 内部元组前缀的数据类型 */ Oid labelType; /* 内部元组结点标签的数据类型 */ Oid leafType; /* 叶子元组值的数据类型 */ - bool canReturnData; /* 操作符类能重构原始数据 */ - bool longValuesOK; /* 操作符类能处理值 > 1 页 */ + bool canReturnData; /* 操作符类能重建原始数据 */ + bool longValuesOK; /* 操作符类能处理大小 > 1 页的值 */ } spgConfigOut; @@ -314,7 +314,7 @@ typedef struct spgConfigOut 类型与操作符类的输入类型相同,这也是最常见的情况。)出于向后兼容的原 因,config 方法也可以将 leafType 设为其他值,并且该值将被使用; - 但这已被废弃,因为这样会导致目录中对索引内容的标识不正确。此外,也允 + 但这已被弃用,因为这样会导致目录中对索引内容的标识不正确。此外,也允 许不初始化 leafType(即保持为零);这会 被解释为使用从 opckeytype 派生的索引存 储类型。 @@ -354,7 +354,7 @@ typedef struct spgChooseIn int level; /* 当前层级(从零开始计) */ /* 来自当前内部元组的数据 */ - bool allTheSame; /* 元组被标记为 all-the-same? */ + bool allTheSame; /* 元组被标记为全部相同? */ bool hasPrefix; /* 元组有前缀? */ Datum prefixDatum; /* 如果有,前缀值 */ int nNodes; /* 内部元组中的结点数 */ @@ -594,14 +594,14 @@ typedef struct spgInnerConsistentIn int nkeys; /* scankeys 数组的长度 */ int norderbys; /* orderbys 数组的长度 */ - Datum reconstructedValue; /* 在父元组处重构的值 */ + Datum reconstructedValue; /* 在父元组处重建的值 */ void *traversalValue; /* 操作符类特定的遍历值 */ MemoryContext traversalMemoryContext; /* 将新的遍历值放在这里 */ int level; /* 当前层级(从零开始计) */ bool returnData; /* 必须返回原始数据? */ /* 来自当前内部元组的数据 */ - bool allTheSame; /* 元组被标记为 all-the-same? */ + bool allTheSame; /* 元组被标记为全部相同? */ bool hasPrefix; /* 元组有前缀? */ Datum prefixDatum; /* 如果有,前缀值 */ int nNodes; /* 内部元组中的结点数 */ @@ -613,7 +613,7 @@ typedef struct spgInnerConsistentOut int nNodes; /* 需要访问的子结点数 */ int *nodeNumbers; /* 它们在结点数组中的索引 */ int *levelAdds; /* 对每个结点层级增加这么多 */ - Datum *reconstructedValues; /* 关联的重构值 */ + Datum *reconstructedValues; /* 关联的重建值 */ void **traversalValues; /* 操作符类特定的遍历值 */ double **distances; /* 关联距离 */ } spgInnerConsistentOut; @@ -624,7 +624,7 @@ typedef struct spgInnerConsistentOut 用 AND 组合 — 只有满足全部条件的索引项才是我们关心的。(注 意, nkeys = 0 表示所有索引项都满足该查 - 询。)通常 consistent 函数只关心每个数组元素的 + 询。)通常一致性检查函数只关心每个数组元素的 sk_strategysk_argument 字段,它们分别给出可索引操 作符和比较值。特别地,无需检查 sk_flags @@ -641,9 +641,8 @@ typedef struct spgInnerConsistentOut 遍历值(见下文)的内存上下文。level 是 当前内部元组的层级,根层为零。如果本查询需要重建数据,则 returnDatatrue; - 只有在 config 函数声明了 - canReturnData 时才会如此。若当前内部元组 - 被标记为 all-the-same,则 + 只有在 config 函数将 canReturnData 设为真时才会如此。若当前内部元组 + 被标记为 全部相同,则 allTheSame 为真;在这种情况下,所有结点 都具有相同的标签(如果有),因此要么全部匹配该查询,要么全部不匹配 (参见 )。若当前内部元组包 @@ -663,8 +662,7 @@ typedef struct spgInnerConsistentOut 非必然如此,所以这里使用数组。)如果需要值重建,则将 reconstructedValues 设为一个数组,其中包 含为每个待访问子结点重建的值;否则,将 - reconstructedValues 保持为 NULL。重构 - 值假定具有 spgConfigOut.leafType + reconstructedValues 保持为 NULL。重建的值假定具有 spgConfigOut.leafType 类型。(不过,由于核心系统除了可能复制它们以外不会对其做任何处理,只 要它们具有与 leafType 相同的 typlentypbyval 属性就足 @@ -713,7 +711,7 @@ typedef struct spgLeafConsistentIn int nkeys; /* scankeys 数组的长度 */ int norderbys; /* orderbys 数组的长度 */ - Datum reconstructedValue; /* 在父元组处重构的值 */ + Datum reconstructedValue; /* 在父元组处重建的值 */ void *traversalValue; /* 操作符类特定的遍历值 */ int level; /* 当前层级(从零开始计) */ bool returnData; /* 必须返回原始数据? */ @@ -723,7 +721,7 @@ typedef struct spgLeafConsistentIn typedef struct spgLeafConsistentOut { - Datum leafValue; /* 重构出的原始数据(如果有) */ + Datum leafValue; /* 重建出的原始数据(如果有) */ bool recheck; /* 如果必须重新检查操作符则设为真 */ bool recheckDistances; /* 如果必须重新检查距离则设为真 */ double *distances; /* 关联距离 */ @@ -734,7 +732,7 @@ typedef struct spgLeafConsistentOut scankeys 数组描述索引搜索条件。这些条件 用 AND 组合在一起 — 只有满足全部条件的索引项才满足该查询。(注 意 nkeys = 0 表示所有索引项都满足该查 - 询。)通常 consistent 函数只关心每个数组元素的 + 询。)通常一致性检查函数只关心每个数组元素的 sk_strategysk_argument 字段,它们分别给出可索引操 作符和比较值。特别地,无需检查 sk_flags @@ -750,8 +748,7 @@ typedef struct spgLeafConsistentOut NULL。level 是当前叶子元组的层级,根层为 零。如果本查询需要重建数据,则 returnDatatrue; - 只有在 config 函数声明了 - canReturnData 时才会如此。 + 只有在 config 函数将 canReturnData 设为真时才会如此。 leafDatum 是当前叶子元组中存储的、类型为 spgConfigOut.leafType 的键值。 @@ -844,7 +841,7 @@ LANGUAGE C STRICT; - 如果被索引列属于可应用排序规则的数据类型,则索引排序规则会通过标准的 + 如果被索引列属于支持排序规则的数据类型,则索引排序规则会通过标准的 PG_GET_COLLATION() 机制传递给所有支持方法。 @@ -922,7 +919,7 @@ LANGUAGE C STRICT; - <quote>All-the-Same</quote> 内部元组 + <quote>全部相同</quote>的内部元组 picksplit 无法把提供的叶子值划分为至少两个结点 diff --git a/zh/20/spi.sgml b/zh/20/spi.sgml index b936625d..d662d01a 100644 --- a/zh/20/spi.sgml +++ b/zh/20/spi.sgml @@ -76,7 +76,7 @@ int SPI_connect_ext(int options) SPI_connect 会为某次 C 函数调用打开到 SPI 管理器 的连接。如果要通过 SPI 执行命令,就必须调用此函数。不过,有些 SPI - 实用函数可以在未连接的 C 函数中调用。 + 辅助函数可以在未连接的 C 函数中调用。 @@ -291,16 +291,16 @@ SPI_execute("INSERT INTO foo SELECT * FROM bar RETURNING *", false, 5); typedef struct SPITupleTable { - /* Public members */ - TupleDesc tupdesc; /* tuple descriptor */ - HeapTuple *vals; /* array of tuples */ - uint64 numvals; /* number of valid tuples */ - - /* Private members, not intended for external callers */ - uint64 alloced; /* allocated length of vals array */ - MemoryContext tuptabcxt; /* memory context of result table */ - slist_node next; /* link for internal bookkeeping */ - SubTransactionId subid; /* subxact in which tuptable was created */ + /* 公共成员 */ + TupleDesc tupdesc; /* 元组描述符 */ + HeapTuple *vals; /* 元组数组 */ + uint64 numvals; /* 有效元组数 */ + + /* 私有成员,不供外部调用者使用 */ + uint64 alloced; /* vals 数组的已分配长度 */ + MemoryContext tuptabcxt; /* 结果表的内存上下文 */ + slist_node next; /* 用于内部管理的链接 */ + SubTransactionId subid; /* 创建 tuptable 的子事务 */ } SPITupleTable; SPI 调用者可以使用 tupdesc、 @@ -471,7 +471,7 @@ typedef struct SPITupleTable - 发生错误时,则返回下列负值之一: + 出错时,返回以下负值之一: @@ -521,7 +521,7 @@ typedef struct SPITupleTable SPI_ERROR_UNCONNECTED - 从未连接的 C 函数中调用 + 如果从一个未连接的 C 函数中调用 @@ -534,9 +534,9 @@ typedef struct SPITupleTable 所有 SPI 查询执行函数都会设置 SPI_processed 和 - SPI_tuptable(只设置指针,而不会复制结构体内容)。如果 + SPI_tuptable(只设置指针,而不更改结构体内容)。如果 需要在后续调用之后继续访问 SPI_execute 或其他查询 - 执行函数的结果表,请把这两个全局变量保存到本地 C 函数变量中。 + 执行函数的结果表,请把这两个全局变量保存到 C 函数的局部变量中。 @@ -581,7 +581,7 @@ int SPI_exec(const char * command, long count< const char * command - 包含要执行命令的字符串 + 包含待执行命令的字符串 @@ -590,7 +590,7 @@ int SPI_exec(const char * command, long count< long count - 要返回的最大行数,或者用0表示没有限制 + 要返回的最大行数,或者用 0 表示不限制 @@ -821,7 +821,7 @@ int SPI_execute_with_args(const char *command, SPI_execute_plan 达到类似效果。不过,使用本函数 时,查询计划总会针对所提供的具体参数值进行定制。对于一次性查询执行,应 优先选择本函数。如果同一条命令要用许多不同参数重复执行,则两种方式孰快 - 取决于重新计划的代价与定制计划收益之间的权衡。 + 取决于重新规划的代价与定制计划收益之间的权衡。 @@ -876,9 +876,9 @@ int SPI_execute_with_args(const char *command, 如果 nullsNULL,则 - SPI_execute_with_args 会假定没有参数为 NULL。 - 否则,如果对应参数值非 NULL,则 nulls 数组中 - 的对应项应为 ' ';如果对应参数值为 NULL,则 + SPI_execute_with_args 会假定没有参数为空值。 + 否则,如果对应参数值非空值,则 nulls 数组中 + 的对应项应为 ' ';如果对应参数值为空值,则 对应项应为 'n'。(后一种情况下,对应 values 项中的实际值无关紧要。)注意, nulls 不是文本字符串,而只是一个数组,因此不 @@ -932,7 +932,7 @@ int SPI_execute_with_args(const char *command, SPI_prepare - 准备一个语句,但不执行它 + 准备一个语句,但暂不执行 @@ -1011,8 +1011,7 @@ SPIPlanPtr SPI_prepare(const char * command, int 返回值 - SPI_prepare 返回一个指向非空 SPIPlan - 的指针,它是表示预备语句的不透明结构体。发生错误时会返回 + SPI_prepare 返回一个非空指针,指向表示预备语句的不透明结构体 SPIPlan。发生错误时会返回 NULL,并将 SPI_result 设为 SPI_execute 所使用的那些错误码之一;但如果 commandNULL,或者 @@ -1031,17 +1030,16 @@ SPIPlanPtr SPI_prepare(const char * command, int SPI_execute_plan 在最初几次使用时会根据提供的参数 值生成定制计划。当同一个预备语句被使用足够多次之后, SPI_execute_plan 会构建一个通用计划;如果它的代价 - 没有比定制计划高出太多,就会开始改用通用计划,而不是每次都重新计划。如 + 没有比定制计划高出太多,就会开始改用通用计划,而不是每次都重新规划。如 果这种默认行为不合适,可以把 CURSOR_OPT_GENERIC_PLANCURSOR_OPT_CUSTOM_PLAN 标志传给 SPI_prepare_cursor,分别强制使用通用计划或定制计划。 - 尽管预备语句的主要目的在于避免重复进行解析分析和计划,但只要语句中使用 + 尽管预备语句的主要目的在于避免重复进行解析分析和规划,但只要语句中使用 的数据库对象自上次使用该预备语句以来发生了定义性(DDL)变更, - PostgreSQL 就会在再次使用前强制重新分析并重 - 新计划该语句。此外,如果 的值在两次 + PostgreSQL 就会在再次使用前强制重新分析并重新规划该语句。此外,如果 的值在两次 使用之间发生变化,该语句也会基于新的 search_path 重 新解析。(后一种行为是从 PostgreSQL 9.3 开 始引入的。)有关预备语句行为的更多信息,请参见 @@ -1101,7 +1099,7 @@ SPIPlanPtr SPI_prepare_cursor(const char * command, int < - 此函数现已废弃,推荐改用 SPI_prepare_extended。 + 此函数现已弃用,推荐改用 SPI_prepare_extended @@ -1131,7 +1129,7 @@ SPIPlanPtr SPI_prepare_cursor(const char * command, int < Oid * argtypes - 指向数组的指针,该数组包含参数数据类型的 + 一个数组指针,它指向的数组包含参数的数据类型的 OID @@ -1200,7 +1198,7 @@ SPIPlanPtr SPI_prepare_extended(const char * command, SPI_prepare_extended 为指定命令创建并返回一个预备语 句,但并不执行该命令。它相当于 SPI_prepare,并额外 - 允许调用者指定选项,以控制外部参数引用的解析,以及查询解析和计划的其他 + 允许调用者指定选项,以控制外部参数引用的解析,以及查询解析和规划的其他 方面。 @@ -1240,7 +1238,7 @@ SPIPlanPtr SPI_prepare_extended(const char * command, ParserSetupHook parserSetup - 语法分析器钩子设置函数 + 解析器钩子设置函数 @@ -1318,7 +1316,7 @@ SPIPlanPtr SPI_prepare_params(const char * command, - 此函数现已废弃,推荐改用 SPI_prepare_extended。 + 此函数现已弃用,推荐改用 SPI_prepare_extended @@ -1339,7 +1337,7 @@ SPIPlanPtr SPI_prepare_params(const char * command, ParserSetupHook parserSetup - 语法分析器钩子设置函数 + 解析器钩子设置函数 @@ -1554,8 +1552,8 @@ bool SPI_is_cursor_plan(SPIPlanPtr plan) 返回值 - 如果 plan 能产生游标,则返回 - true;如果不能,则返回 false,并将 + 返回 truefalse,表示 + plan 能否产生游标,同时将 SPI_result 设为零。如果无法确定答案(例如 planNULL 或无效,或者在 未连接到 SPI 时调用),则会将 SPI_result 设为合适 @@ -1627,15 +1625,14 @@ int SPI_execute_plan(SPIPlanPtr plan, const Datum * - 如果nullsNULL, - 那么SPI_execute_plan会假设没有参数 - 为空值。否则,如果对应的参数值为非空, - nulls - 数组的每一个项都应该是' ';如果对应参数值为空, - nulls数组的项应为'n'(在后 - 面的情况中,对应的values项中的值没有 - 关系)。注意nulls不是一个文本字符串, - 它只是一个数组:它不需要一个'\0'终止符。 + 如果 nullsNULL,则 + SPI_execute_plan 会假定没有参数为空值。 + 否则,如果对应参数值非空值,则 nulls 数组中 + 的对应项应为 ' ';如果对应参数值为空值,则 + 对应项应为 'n'。(后一种情况下,对应 + values 项中的实际值无关紧要。)注意, + nulls 不是文本字符串,而只是一个数组,因此不 + 需要 '\0' 终止符。 @@ -1708,7 +1705,7 @@ int SPI_execute_plan(SPIPlanPtr plan, const Datum * SPI_execute_plan_extended - 执行一个由SPI_prepare准备的语句 + 执行由 SPI_prepare 准备好的语句 @@ -1793,8 +1790,9 @@ int SPI_execute_plan_extended(SPIPlanPtr plan, bool allow_nonatomic - true 允许以非原子方式执行 CALL 与 DO 语句 - (但除非向 SPI_connect_ext 传入了 + true 允许以非原子方式执行 CALL + 和 DO 语句(但除非向 + SPI_connect_ext 传入了 SPI_OPT_NONATOMIC 标志,否则该字段会被忽略) @@ -1814,7 +1812,7 @@ int SPI_execute_plan_extended(SPIPlanPtr plan, uint64 tcount - 要返回的最大行数,或者用0表示没有限制 + 要返回的最大行数,或者用 0 表示不限制 @@ -1899,7 +1897,7 @@ int SPI_execute_plan_with_paramlist(SPIPlanPtr plan, - 此函数现已废弃,推荐改用 SPI_execute_plan_extended。 + 此函数现已弃用,推荐改用 SPI_execute_plan_extended @@ -1936,7 +1934,7 @@ int SPI_execute_plan_with_paramlist(SPIPlanPtr plan, long count - 要返回的最大行数,或者用0表示没有限制 + 要返回的最大行数,或者用 0 表示不限制 @@ -2020,15 +2018,14 @@ int SPI_execp(SPIPlanPtr plan, const Datum * v - 如果nullsNULL, - 那么SPI_execp会假设没有参数 - 为空值。否则,如果对应的参数值为非空, - nulls - 数组的每一个项都应该是' ';如果对应参数值为空, - nulls数组的项应为'n'(在后 - 面的情况中,对应的values项中的值没有 - 关系)。注意nulls不是一个文本字符串, - 它只是一个数组:它不需要一个'\0'终止符。 + 如果 nullsNULL,则 + SPI_execp 会假定没有参数为空值。 + 否则,如果对应参数值非空值,则 nulls 数组中 + 的对应项应为 ' ';如果对应参数值为空值,则 + 对应项应为 'n'。(后一种情况下,对应 + values 项中的实际值无关紧要。)注意, + nulls 不是文本字符串,而只是一个数组,因此不 + 需要 '\0' 终止符。 @@ -2037,7 +2034,7 @@ int SPI_execp(SPIPlanPtr plan, const Datum * v long count - 要返回的最大行数,或者用0表示没有限制 + 要返回的最大行数,或者用 0 表示不限制 @@ -2145,15 +2142,14 @@ Portal SPI_cursor_open(const char * name, SPIPlanPtr - 如果nullsNULL, - 那么SPI_cursor_open会假设没有参数 - 为空值。否则,如果对应的参数值为非空, - nulls - 数组的每一个项都应该是' ';如果对应参数值为空, - nulls数组的项应为'n'(在后 - 面的情况中,对应的values项中的值没有 - 关系)。注意nulls不是一个文本字符串, - 它只是一个数组:它不需要一个'\0'终止符。 + 如果 nullsNULL,则 + SPI_cursor_open 会假定没有参数为空值。 + 否则,如果对应参数值非空值,则 nulls 数组中 + 的对应项应为 ' ';如果对应参数值为空值,则 + 对应项应为 'n'。(后一种情况下,对应 + values 项中的实际值无关紧要。)注意, + nulls 不是文本字符串,而只是一个数组,因此不 + 需要 '\0' 终止符。 @@ -2214,11 +2210,10 @@ Portal SPI_cursor_open_with_args(const char *name, - 对于一次性的查询执行,这个函数应该比 - SPI_prepare_cursor加上其后的 - SPI_cursor_open更好。如果相同的命令 - 要被用很多不同的参数执行,哪种方法更快就要取决于重做计划的 - 代价与定制计划带来的好处之间谁更有利。 + 对于一次性查询执行,应优先使用此函数,而不是先调用 + SPI_prepare_cursor 再调用 + SPI_cursor_open。如果同一条命令要用许多不同参数执行, + 哪种方法更快取决于重新规划的代价与定制计划收益之间的权衡。 @@ -2227,7 +2222,7 @@ Portal SPI_cursor_open_with_args(const char *name, - 此函数现已废弃,推荐改用 SPI_cursor_parse_open, + 此函数现已弃用,推荐改用 SPI_cursor_parse_open, 它提供了等价的功能,并使用更现代的查询参数处理 API。 @@ -2267,8 +2262,8 @@ Portal SPI_cursor_open_with_args(const char *name, Oid * argtypes - 一个长度为nargs的数组, - 包含参数的数据类型的OID + 一个长度为 nargs 的数组,包含参数数据类型的 + OID @@ -2277,8 +2272,7 @@ Portal SPI_cursor_open_with_args(const char *name, Datum * values - 一个长度为nargs的数组, - 包含实际的参数值 + 一个长度为 nargs 的数组,包含实际参数值 @@ -2287,20 +2281,19 @@ Portal SPI_cursor_open_with_args(const char *name, const char * nulls - 一个长度为nargs的数组, - 描述哪些参数为空值 + 一个长度为 nargs 的数组,用于描述哪些参数为 + 空值 - 如果nullsNULL, - 那么SPI_cursor_open_with_args会假设没有参数 - 为空值。否则,如果对应的参数值为非空, - nulls - 数组的每一个项都应该是' ';如果对应参数值为空, - nulls数组的项应为'n'(在后 - 面的情况中,对应的values项中的值没有 - 关系)。注意nulls不是一个文本字符串, - 它只是一个数组:它不需要一个'\0'终止符。 + 如果 nullsNULL,则 + SPI_cursor_open_with_args 会假定没有参数为空值。 + 否则,如果对应参数值非空值,则 nulls 数组中 + 的对应项应为 ' ';如果对应参数值为空值,则 + 对应项应为 'n'。(后一种情况下,对应 + values 项中的实际值无关紧要。)注意, + nulls 不是文本字符串,而只是一个数组,因此不 + 需要 '\0' 终止符。 @@ -2437,7 +2430,7 @@ Portal SPI_cursor_open_with_paramlist(const char *name, SPI_cursor_parse_open - 使用查询字符串和参数设置游标 + 使用查询字符串和参数建立游标 @@ -2463,7 +2456,7 @@ Portal SPI_cursor_parse_open(const char *name, 对于一次性查询执行,推荐优先使用此函数,而不是 SPI_prepare_cursorSPI_cursor_open_with_paramlist 的组合。如果同一条命 - 令要用很多不同参数执行,两种方法孰快则取决于重新计划的代价与定制计划带 + 令要用很多不同参数执行,两种方法孰快则取决于重新规划的代价与定制计划带 来的收益之间的权衡。 @@ -2700,7 +2693,7 @@ void SPI_cursor_fetch(Portal portal, bool forw 如果该游标的计划不是用CURSOR_OPT_SCROLL - 选项创建的,向后获取会失败。 + 选项创建的,向后获取可能失败。 @@ -2774,7 +2767,7 @@ void SPI_cursor_move(Portal portal, bool forwa 如果该游标的计划不是用CURSOR_OPT_SCROLL - 选项创建的,向后移动会失败。 + 选项创建的,向后移动可能失败。 @@ -2870,8 +2863,7 @@ void SPI_scroll_cursor_fetch(Portal portal, FetchDirectio 如果该游标的计划不是用CURSOR_OPT_SCROLL - 选项创建的,除FETCH_FORWARD之外的方向值会 - 失败。 + 选项创建的,除FETCH_FORWARD之外的方向值可能失败。 @@ -2968,8 +2960,7 @@ void SPI_scroll_cursor_move(Portal portal, FetchDirection 如果该游标的计划不是用CURSOR_OPT_SCROLL - 选项创建的,除FETCH_FORWARD之外的方向值会 - 失败。 + 选项创建的,除FETCH_FORWARD之外的方向值可能失败。 @@ -3191,8 +3182,8 @@ SPIPlanPtr SPI_saveplan(SPIPlanPtr plan) SPI_register_relation - ephemeral named relation - registering with SPI + 临时命名关系 + 向 SPI 注册 @@ -3216,7 +3207,7 @@ int SPI_register_relation(EphemeralNamedRelation enr) SPI_register_relation 使一个带有相关信息的临时命名关 - 系对通过当前 SPI 连接计划和执行的查询可用。 + 系对通过当前 SPI 连接规划和执行的查询可用。 @@ -3254,7 +3245,7 @@ int SPI_register_relation(EphemeralNamedRelation enr) - 在出错时,会返回下列负值之一: + 出错时,返回以下负值之一: @@ -3296,8 +3287,8 @@ int SPI_register_relation(EphemeralNamedRelation enr) SPI_unregister_relation - ephemeral named relation - unregistering from SPI + 临时命名关系 + 从 SPI 注销 @@ -3344,7 +3335,7 @@ int SPI_unregister_relation(const char * name) 返回值 - 如果该命令的执行成功,则会返回下列(非负)值: + 如果该命令的执行成功,则将返回下列(非负)值: @@ -3359,7 +3350,7 @@ int SPI_unregister_relation(const char * name) - 出现错误时,会返回下列负值之一: + 出错时,返回以下负值之一: @@ -3399,13 +3390,13 @@ int SPI_unregister_relation(const char * name) SPI_register_trigger_data - ephemeral named relation - registering with SPI + 临时命名关系 + 向 SPI 注册 - transition tables - implementation in PLs + 过渡表 + 在 PL 中实现 @@ -3429,8 +3420,8 @@ int SPI_register_trigger_data(TriggerData *tdata) SPI_register_trigger_data 使触发器捕获的所有临时关系 - 都能在通过当前 SPI 连接计划和执行的查询中使用。目前,这指的是通过 - REFERENCING OLD/NEW TABLE AS ... 子句定义、并由 + 都能在通过当前 SPI 连接规划和执行的查询中使用。目前,这指的是由带有 + REFERENCING OLD/NEW TABLE AS ... 子句的 AFTER 触发器捕获的过渡表。PL 触发器处理函数应在建 立 SPI 连接后调用此函数。 @@ -3456,7 +3447,7 @@ int SPI_register_trigger_data(TriggerData *tdata) 返回值 - 如果命令的执行成功,则会返回下列(非负)值: + 如果该命令的执行成功,则将返回下列(非负)值: @@ -3471,7 +3462,7 @@ int SPI_register_trigger_data(TriggerData *tdata) - 出现错误时,会返回下列负值之一: + 出错时,返回以下负值之一: @@ -3728,7 +3719,7 @@ char * SPI_getvalue(HeapTuple row, TupleDesc r 返回值 - 列值;如果该列为 NULL、colnumber 超出范围 + 列值;如果该列为空值、colnumber 超出范围 (SPI_result 被设置为 SPI_ERROR_NOATTRIBUTE)或者没有输出函数 可用(SPI_result 被设置为 @@ -3820,8 +3811,8 @@ Datum SPI_getbinval(HeapTuple row, TupleDesc r 返回值 - 返回该列的二进制值。如果该列为 NULL,则 - isnull 指向的变量会被设为 true,否则设为 false。 + 返回该列的二进制值。如果该列为空值,则 + isnull 指向的变量会被设为真,否则设为假。 @@ -3857,7 +3848,7 @@ char * SPI_gettype(TupleDesc rowdesc, int coln SPI_gettype返回该指定列的数据类型名称 - 的拷贝(当你不再需要该拷贝后,可以使用pfree + 的副本(当你不再需要该副本后,可以使用pfree 释放它)。 @@ -3989,7 +3980,7 @@ char * SPI_getrelname(Relation rel) SPI_getrelname返回该指定关系的名称 - 的拷贝(当你不再需要该拷贝后,可以使用pfree + 的副本(当你不再需要该副本后,可以使用pfree 释放它)。 @@ -4082,7 +4073,7 @@ char * SPI_getnspname(Relation rel) SPI_result_code_string - 将结果代码表示为字符串 + 返回错误码的字符串表示 @@ -4096,7 +4087,7 @@ const char * SPI_result_code_string(int code); SPI_result_code_string 返回各种 SPI 函数返回的,或 - 存放在 SPI_result 中的结果代码的字符串表示。 + 存放在 SPI_result 中的结果码的字符串表示。 @@ -4108,7 +4099,7 @@ const char * SPI_result_code_string(int code); int code - 结果代码 + 结果码 @@ -4119,7 +4110,7 @@ const char * SPI_result_code_string(int code); 返回值 - 结果代码的字符串表示。 + 结果码的字符串表示。 @@ -4131,8 +4122,8 @@ const char * SPI_result_code_string(int code); - memory context - in SPI + 内存上下文 + 在 SPI 中 PostgreSQL内存上下文 中分配内存。内存上下文为管理那些在许多不同位置创建、且生命周期各不相同 @@ -4157,7 +4148,7 @@ const char * SPI_result_code_string(int code); 办法是用 SPI_palloc 为返回对象分配内存。 SPI_palloc上层执行器上下文中分配 内存,也就是调用 SPI_connect 时的当前内存上下文; - 这正是从 C 函数返回值最合适的上下文。本节介绍的其他几个实用函数同样会返 + 这正是从 C 函数返回值最合适的上下文。本节介绍的其他几个辅助函数同样会返 回在上层执行器上下文中创建的对象。 @@ -4165,7 +4156,7 @@ const char * SPI_result_code_string(int code); 调用 SPI_connect 时,会把该 C 函数的私有上下文 (由 SPI_connect 创建)设为当前上下文。所有通过 pallocrepalloc 或 SPI - 实用函数分配的内存(本节另有说明的除外)都位于这个上下文中。当 C 函数通 + 辅助函数分配的内存(本节另有说明的除外)都位于这个上下文中。当 C 函数通 过 SPI_finish 与 SPI 管理器断开连接时,当前上下文 会恢复为上层执行器上下文,而在该 C 函数内存上下文中分配的所有内存都会被 释放,之后就不能再使用。 @@ -4360,7 +4351,7 @@ void SPI_pfree(void * pointer) SPI_copytuple - 在上层执行器上下文中创建一行的拷贝 + 在上层执行器上下文中创建一行的副本 @@ -4393,7 +4384,7 @@ HeapTuple SPI_copytuple(HeapTuple row) HeapTuple row - 要拷贝的行 + 要复制的行 @@ -4404,7 +4395,7 @@ HeapTuple SPI_copytuple(HeapTuple row) 返回值 - 拷贝后的行;出错时返回 NULL + 复制后的行;出错时返回 NULL (错误指示见 SPI_result @@ -4460,7 +4451,7 @@ HeapTupleHeader SPI_returntuple(HeapTuple row, TupleDesc HeapTuple row - 要拷贝的行 + 要复制的行 @@ -4469,7 +4460,7 @@ HeapTupleHeader SPI_returntuple(HeapTuple row, TupleDesc TupleDesc rowdesc - 行描述符(若要获得最佳缓存效果,大多数情况下应每次都传入同一个描述符) + 行描述符(若要获得最佳缓存效果,每次都传入同一个描述符) @@ -4480,7 +4471,7 @@ HeapTupleHeader SPI_returntuple(HeapTuple row, TupleDesc 返回值 - 指向拷贝后行的 HeapTupleHeader;出错时返回 + 指向复制后行的 HeapTupleHeader;出错时返回 NULL(错误指示见 SPI_result @@ -4582,13 +4573,14 @@ HeapTuple SPI_modifytuple(Relation rel, HeapTuple - 如果nullsNULL,那么 - SPI_modifytuple假定没有新值为空值。否则, - 如果对应的新值为非空,nulls数组的每一项都应 - 该是' ',而如果对应的新值为空值则为'n'(在 - 后一种情况中,对应的values项中的新值无关紧 - 要)。注意nulls不是一个文本字符串,只是一个 - 数组:它不需要一个'\0'终止符。 + 如果 nullsNULL,则 + SPI_modifytuple 会假定没有新值为空值。 + 否则,如果对应新值非空值,则 nulls 数组中 + 的对应项应为 ' ';如果对应新值为空值,则 + 对应项应为 'n'。(后一种情况下,对应 + values 项中的实际值无关紧要。)注意, + nulls 不是文本字符串,而只是一个数组,因此不 + 需要 '\0' 终止符。 @@ -4667,7 +4659,7 @@ void SPI_freetuple(HeapTuple row) SPI_freetuple释放之前在上层执行器上下文中 - 分配的一个行。 + 分配的一行。 @@ -4965,7 +4957,7 @@ void SPI_start_transaction(void) - 数据改变的可见性 + 数据更改的可见性 下列规则决定了使用 SPI 的函数(以及其他任何 C 函数)中数据更改的可见 diff --git a/zh/20/stylesheet-speedup-common.xsl b/zh/20/stylesheet-speedup-common.xsl index e3fb582a..403f350c 100644 --- a/zh/20/stylesheet-speedup-common.xsl +++ b/zh/20/stylesheet-speedup-common.xsl @@ -95,6 +95,6 @@ -en +zh_cn diff --git a/zh/20/syntax.sgml b/zh/20/syntax.sgml index 298738f7..f05b1225 100644 --- a/zh/20/syntax.sgml +++ b/zh/20/syntax.sgml @@ -21,7 +21,7 @@ 词法结构 - token + 词元 @@ -29,7 +29,7 @@ - 一个词元可以是关键词标识符带引号的标识符文字值(或常量),或者特殊字符符号。词元通常由空白(空格、制表符、换行)分隔,但如果不存在歧义,则不必如此(一般只有特殊字符与其他类型的词元相邻时才会这样)。 + 一个词元可以是关键词标识符带引号的标识符字面量(或常量),或者特殊字符符号。词元通常由空白(空格、制表符、换行)分隔,但如果不存在歧义,则不必如此(一般只有特殊字符与其他类型的词元相邻时才会这样)。 @@ -58,18 +58,18 @@ INSERT INTO MY_TABLE VALUES (3, 'hi there'); 标识符和关键词 - identifier - syntax of + 标识符 + 语法 - name - syntax of + 名称 + 语法 - key word - syntax of + 关键词 + 语法 @@ -83,7 +83,7 @@ INSERT INTO MY_TABLE VALUES (3, 'hi there'); - identifierlength + 标识符长度 系统对标识符最多只使用 NAMEDATALEN-1 个字节;在命令中可以写更长的名称,但它们会被截断。默认情况下, NAMEDATALEN 为 64,因此标识符的最大长度是 63 字节。如果这个限制有问题,可以通过修改 src/include/pg_config_manual.h 中的 NAMEDATALEN 常量来提高。 @@ -91,8 +91,8 @@ INSERT INTO MY_TABLE VALUES (3, 'hi there'); - case sensitivity - of SQL commands + 大小写敏感性 + SQL 命令 关键词和未加引号的标识符不区分大小写。因此: @@ -110,8 +110,8 @@ UPDATE my_table SET a = 5; - quotation marks - and identifiers + 引号 + 与标识符 还有第二类标识符:定界标识符带引号的标识符。它通过把任意字符序列括在双引号中形成(")。 定界标识符始终是标识符,绝不会是关键词。因此,"select" 可以用来引用名为 select 的列或表,而不加引号的 select 会被视为关键词,因此在期望表名或列名的位置使用时会导致解析错误。这个示例可以用带引号的标识符写成: @@ -133,7 +133,7 @@ UPDATE "my_table" SET "a" = 5; Unicode 转义 - in identifiers + 在标识符中 @@ -177,7 +177,7 @@ U&"d!0061t!+000061" UESCAPE '!' 常量 - constant + 常量 @@ -188,19 +188,15 @@ U&"d!0061t!+000061" UESCAPE '!' 字符串常量 - character string - constant + 字符串 + 常量 - - - quotation marks + + 引号 转义 - SQL 中的字符串常量是由单引号括起的任意字符序列,例如 - 'This is a string'。要在字符串常量中包含单引号字符,请写两个相邻的单引号,例如 - 'Dianne''s horse'。注意,这与双引号字符("不同 - + SQL 中的字符串常量是由单引号(')括起的任意字符序列,例如 'This is a string'。要在字符串常量中包含单引号字符,请写两个相邻的单引号,例如 'Dianne''s horse'。注意,这不同于双引号字符(")。 两个只由空白及至少一个新行分隔的字符串常量会被连接在一起,并且将作为一个写在一起的字符串常量来对待。例如: @@ -302,7 +298,7 @@ SELECT 'foo' 'bar'; 你有责任确保自己创建出的字节序列,特别是在使用八进制或十六进制转义时,能够在服务器字符集编码中组成合法字符。一个有用的替代方案是使用 Unicode 转义或替代的 Unicode 转义语法,如中所述;这样服务器会检查字符转换是否可行。 - + 编码为零的字符不能出现在字符串常量中。 @@ -314,7 +310,7 @@ SELECT 'foo' 'bar'; Unicode 转义 - in string constants + 在字符串常量中 @@ -351,14 +347,14 @@ U&'d!0061t!+000061' UESCAPE '!' 如果服务器编码不是 UTF-8,则由这些转义序列之一标识的 Unicode 代码点会被转换为实际的服务器编码;如果无法转换,则会报告错误。 - + 美元引用的字符串常量 - dollar quoting + 美元引用 @@ -401,8 +397,8 @@ $function$ 位串常量 - bit string - constant + 位串 + 常量 @@ -422,8 +418,8 @@ $function$ 数字常量 - number - constant + 数字 + 常量 @@ -500,12 +496,12 @@ $function$ - 为数字常量最初指定的数据类型,只是类型解析算法的起点。在大多数情况下,常量会根据上下文被自动强制转换成最合适的类型。必要时,你可以通过类型转换强制把一个数值解释为特定的数据类型。type cast + 为数字常量最初指定的数据类型,只是类型解析算法的起点。在大多数情况下,常量会根据上下文被自动强制转换成最合适的类型。必要时,你可以通过类型转换强制把一个数值解释为特定的数据类型。类型转换 例如,可以通过下面的写法强制把一个数值当作类型 realfloat4)处理: -REAL '1.23' -- string style -1.23::REAL -- PostgreSQL (historical) style +REAL '1.23' -- 字符串形式 +1.23::REAL -- PostgreSQL(历史)形式 这些实际上只是下面将要讨论的一般类型转换记法的特例。 @@ -516,8 +512,8 @@ REAL '1.23' -- string style 其他类型的常量 - data type - constant + 数据类型 + 常量 @@ -543,7 +539,7 @@ CAST ( 'string' AS type ) - 如中所述,::CAST() 以及函数调用语法也可以用来指定任意表达式的运行时类型转换。为避免语法歧义,type 'string' 语法只能用来指定简单字面常量的类型。该语法的另一个限制是不能用于数组类型;要指定数组常量的类型,请使用 ::CAST()。 + 如中所述,::CAST() 以及函数调用语法也可以用来指定任意表达式的运行时类型转换。为避免语法歧义,type 'string' 语法只能用来指定简单字面常量的类型。type 'string' 语法的另一个限制是不能用于数组类型;要指定数组常量的类型,请使用 ::CAST() @@ -556,8 +552,8 @@ CAST ( 'string' AS type ) 操作符 - operator - syntax + 操作符 + 语法 @@ -607,7 +603,7 @@ CAST ( 'string' AS type ) - 圆括号(())具有它们通常的含义,用来分组表达式并且强制优先。在某些情况中,圆括号被要求作为一个特定 SQL 命令的固定语法的一部分。 + 圆括号(())具有它们通常的含义,用来对表达式分组并确定运算优先级。在某些情况中,圆括号被要求作为一个特定 SQL 命令的固定语法的一部分。 @@ -625,7 +621,7 @@ CAST ( 'string' AS type ) - 分号(;)结束一个 SQL 命令。它不能出现在一个命令中间的任何位置,除了在一个字符串常量中或者一个被引用的标识符中。 + 分号(;)结束一个 SQL 命令。它不能出现在一个命令中间的任何位置,除了在一个字符串常量中或者一个带引号的标识符中。 @@ -637,7 +633,7 @@ CAST ( 'string' AS type ) - 星号(*)在某些上下文中用来表示表行或组合值的所有字段。当它被用作聚合函数的参数时,还有一种特殊含义,即该聚合不需要任何显式参数。 + 星号(*)在某些上下文中用来表示表行或复合值的所有字段。当它被用作聚合函数的参数时,还有一种特殊含义,即该聚合不需要任何显式参数。 @@ -655,22 +651,22 @@ CAST ( 'string' AS type ) 注释 - comment - in SQL + 注释 + 在 SQL 中 注释是一串以双连字符开始并延伸到行尾的字符,例如: --- This is a standard SQL comment +-- 这是一条标准 SQL 注释 另外,也可以使用 C 风格注释块: -/* multiline comment - * with nesting: /* nested block comment */ +/* 多行注释 + * 包含嵌套:/* 嵌套块注释 */ */ 这里该注释开始于/*并且延伸到匹配出现的*/。这些注释块可按照 SQL 标准中指定的方式嵌套,但和 C 中不同。这样我们可以注释掉一大段可能包含注释块的代码。 @@ -685,8 +681,8 @@ CAST ( 'string' AS type ) 操作符优先级 - operator - precedence + 操作符 + 优先级 @@ -730,7 +726,7 @@ CAST ( 'string' AS type ) + - - 一元加、一元减 + 一元正号、一元负号 @@ -748,13 +744,13 @@ CAST ( 'string' AS type ) ^ - 指数 + 求幂 * / % - 乘、除、模 + 乘、除、取模 @@ -766,7 +762,7 @@ CAST ( 'string' AS type ) (任意其他操作符) - 所有其他本地以及用户定义的操作符 + 所有其他内置以及用户定义的操作符 @@ -823,18 +819,7 @@ SELECT 3 OPERATOR(pg_catalog.+) 4; - - 版本 9.5 之前的PostgreSQL使用的操作符优先级 - 规则略有不同。特别是,<=>= - 和<>习惯于被当作普通操作符,IS - 测试习惯于具有较高的优先级。并且在一些认为NOT比 - BETWEEN优先级高的情况下,NOT BETWEEN - 和相关的结构的行为不一致。为了更好地兼容 SQL 标准并且减少对 - 逻辑上等价的结构不一致的处理,这些规则也得到了修改。在大部分情况下, - 这些变化不会导致行为上的变化,或者可能会产生no such operator - 错误,但可以通过增加圆括号解决。不过在一些极端情况中,查询可能在 - 没有被报告解析错误的情况下发生行为的改变。 - + PostgreSQL 9.5 之前的版本使用的操作符优先级规则略有不同。特别是,<=>=<> 过去被当作普通操作符;IS 测试过去具有较高的优先级;而 NOT BETWEEN 和相关结构的处理不一致,在某些情况下被认为具有 NOT 而不是 BETWEEN 的优先级。为了更好地符合 SQL 标准,并减少对逻辑等价结构的不一致处理造成的困惑,这些规则得到了修改。在大部分情况下,这些变化不会导致行为变化,或者可能会产生 no such operator 错误,但可以通过增加圆括号解决。不过在一些极端情况下,查询可能在没有报告任何解析错误的情况下改变行为。 @@ -1527,7 +1512,7 @@ SELECT * FROM tbl WHERE a COLLATE "C" > 'foo'; SELECT * FROM tbl WHERE (a > 'foo') COLLATE "C"; - 因为它尝试把一个排序规则应用到>操作符的结果,而它的数据类型是非可排序数据类型boolean。 + 因为它尝试把一个排序规则应用到>操作符的结果,而它的数据类型是不支持排序规则的数据类型boolean。 diff --git a/zh/20/system-views.sgml b/zh/20/system-views.sgml index 1d703754..c1e40f9c 100644 --- a/zh/20/system-views.sgml +++ b/zh/20/system-views.sgml @@ -1394,7 +1394,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; address text - 主机名或IP地址,或者allsamehostsamenet之一,对于本地连接为空 + 主机名或IP地址,或者allsamehostsamenet之一,对于本地连接为 NULL @@ -1403,7 +1403,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; netmask text - IP地址掩码,如果不适用则为空 + IP地址掩码,如果不适用则为 NULL @@ -1621,7 +1621,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; (参考 pg_tablespace.spcname) - 包含索引的表空间名(如果是数据库的默认值则为空) + 包含索引的表空间名(如果是数据库的默认值则为 NULL) @@ -1630,7 +1630,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; indexdef text - 索引定义(重构出的 命令) + 索引定义(重建出的 命令) @@ -1664,8 +1664,8 @@ AND c1.path[c2.level] = c2.path[c2.level]; 以及一般的数据库对象(由类OID和对象OID标识, 与pg_descriptionpg_depend中的方式相同)。 - 此外,扩展关系的权限被表示为一个单独的可锁定对象,以及更新 - pg_database.datfrozenxid 的更新权限。 + 此外,扩展关系的权利被表示为单独的可锁定对象,更新 + pg_database.datfrozenxid的权利也是如此。 此外,还可以对具有用户定义含义的数字施加咨询锁。 @@ -1712,7 +1712,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; (参考 pg_database.oid) - 锁目标存在的数据库的OID,如果目标是一个共享对象则为0,如果目标是一个事务ID则为空 + 锁目标存在的数据库的OID,如果目标是一个共享对象则为0,如果目标是一个事务ID则为 NULL @@ -1722,7 +1722,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; (参考 pg_class.oid) - 作为锁目标的关系的OID,如果目标不是一个关系或者只是关系的一部分则此列为空 + 作为锁目标的关系的OID,如果目标既不是关系,也不是关系的一部分则此列为 NULL @@ -1731,7 +1731,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; page int4 - 作为锁目标的页在关系中的页号,如果目标不是一个关系页或元组则此列为空 + 作为锁目标的页在关系中的页号,如果目标不是一个关系页或元组则此列为 NULL @@ -1740,7 +1740,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; tuple int2 - 作为锁目标的元组在页中的元组号,如果目标不是一个元组则此列为空 + 作为锁目标的元组在页中的元组号,如果目标不是一个元组则此列为 NULL @@ -1749,7 +1749,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; virtualxid text - 锁定目标事务的虚拟 ID,如果目标不是虚拟事务 ID,则为空;见 + 锁定目标事务的虚拟 ID,如果目标不是虚拟事务 ID,则为 NULL;见 @@ -1759,7 +1759,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; transactionid xid - 锁定目标事务的标识,如果目标不是事务 ID,则为空; + 锁定目标事务的标识,如果目标不是事务 ID,则为 NULL; @@ -1769,7 +1769,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; (参考 pg_class.oid) - 包含锁目标的系统目录的OID,如果目标不是一个普通数据库对象则此列为空 + 包含锁目标的系统目录的OID,如果目标不是一个普通数据库对象则此列为 NULL @@ -1779,7 +1779,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; (参考任意 OID 列) - 锁目标在它的系统目录中的OID,如果目标不是一个普通数据库对象则为空 + 锁目标在它的系统目录中的OID,如果目标不是一个普通数据库对象则为 NULL @@ -1788,7 +1788,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; objsubid int2 - 锁的目标列号(classidobjid指表本身),如果目标是某种其他普通数据库对象则此列为0,如果目标不是一个普通数据库对象则此列为空 + 锁的目标列号(classidobjid指表本身),如果目标是某种其他普通数据库对象则此列为0,如果目标不是一个普通数据库对象则此列为 NULL @@ -1806,7 +1806,7 @@ AND c1.path[c2.level] = c2.path[c2.level]; pid int4 - 保持这个锁或者正在等待这个锁的服务器进程的PID,如果此锁被一个预备事务所持有则此列为空 + 保持这个锁或者正在等待这个锁的服务器进程的PID,如果此锁被一个预备事务所持有则此列为 NULL @@ -1842,8 +1842,8 @@ AND c1.path[c2.level] = c2.path[c2.level]; waitstart timestamptz - 服务器进程开始等待该锁的时间;如果锁已被授予则为空。 - 注意,在开始等待之后,即使grantedfalse,该值在极短时间内也可能仍为空。 + 服务器进程开始等待该锁的时间;如果锁已被授予则为 NULL。 + 注意,在开始等待之后,即使grantedfalse,该值在极短时间内也可能仍为 NULL。 @@ -1875,8 +1875,8 @@ AND c1.path[c2.level] = c2.path[c2.level]; 咨询锁可以在由单个 bigint 值或两个整数值组成的键上获取。 - 一个bigint键在classid列中显示其高阶半部分, - 在objid列中显示其低阶半部分,并且objsubid等于1。 + 一个bigint键在classid列中显示其高位半部分, + 在objid列中显示其低位半部分,并且objsubid等于1。 可以使用表达式(classid::bigint << 32) | objid::bigint重新组装原始bigint值。 整数键在classid列中显示第一个键,在objid列中显示第二个键, 并且 objsubid 等于 2。键的实际含义由用户自行决定。咨询锁在每个数据库内都是本地的, @@ -1925,15 +1925,15 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx pg_locks视图显示来自常规锁管理器和谓词锁管理器的数据,这两个是独立的系统; - 此外,常规锁管理器将其锁分为常规锁和fast-path锁(见)。 + 此外,常规锁管理器将其锁分为常规锁和快速路径锁(见)。 不能保证这些数据完全一致。 当查询该视图时, - fast-path 锁的数据(具有fastpath = true) + 快速路径锁的数据(具有fastpath = true) 从每个后端逐个收集,而不会冻结整个锁管理器的状态,因此在收集信息时可能会发生锁的获取或释放。 但请注意,这些锁已知不会与当前放置的任何其他锁发生冲突。 - 在查询所有后端的 fast-path 锁后,剩余的常规锁管理器将作为一个单元被锁定,并且所有剩余锁的一致快照将作为一个原子操作收集。 + 在查询所有后端的快速路径锁后,剩余的常规锁管理器将作为一个单元被锁定,并且所有剩余锁的一致快照将作为一个原子操作收集。 解锁常规锁管理器后,谓词锁管理器类似地被锁定,并且所有谓词锁将作为一个原子操作收集。 - 因此,除了 fast-path 锁外,每个锁管理器将提供一致的结果集,但由于我们不同时锁定两个锁管理器,因此在询问常规锁管理器后和在询问谓词锁管理器前,可能会发生锁的获取或释放。 + 因此,除了快速路径锁外,每个锁管理器将提供一致的结果集,但由于我们不同时锁定两个锁管理器,因此在询问常规锁管理器后和在询问谓词锁管理器前,可能会发生锁的获取或释放。 @@ -2009,7 +2009,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx (参考 pg_tablespace.spcname) - 包含物化视图的表空间名(如使用数据库默认表空间则为空) + 包含物化视图的表空间名(如使用数据库默认表空间则为 NULL) @@ -2036,7 +2036,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx definition text - 物化视图的定义(一个重构的查询) + 物化视图的定义(一个重建的查询) @@ -2227,7 +2227,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx 该预备语句返回列的类型,以 regtype 数组形式表示。该数组中某个元素对应的 OID 可以通过将 - regtype 值转换为 oid 获得。如果预备语句不提供结果(例如 DML 语句),则该字段为空。 + regtype 值转换为 oid 获得。如果预备语句不提供结果(例如 DML 语句),则该字段为 NULL。 @@ -2702,7 +2702,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx confirmed_flush_lsn pg_lsn - 逻辑槽消费者已确认接收到数据的地址(LSN)。在此 LSN 之前提交的事务所对应的数据将不再可用。物理槽为 NULL。 + 逻辑槽消费者已确认接收的数据所到达的地址(LSN)。在此 LSN 之前提交的事务所对应的数据将不再可用。物理槽为 NULL @@ -2765,7 +2765,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx inactive_since timestamptz - 槽变为不活动的时间。如果该槽当前正在被流式传输,则为 NULL。如果该槽变为无效,该值将不再更新。对于从主库同步而来的备库逻辑槽(其 synced 字段为 true),inactive_since 表示槽同步(参见 )最近一次停止的时间。如果该槽始终保持同步,则为 NULL。这有助于跟踪备库上的槽同步何时被中断。 + 槽变为不活动的时间。如果当前正在从该槽流式传输数据,则为 NULL。如果该槽变为无效,该值将不再更新。对于从主库同步而来的备库逻辑槽(其 synced 字段为 true),inactive_since 表示槽同步(参见 )最近一次停止的时间。如果该槽始终保持同步,则为 NULL。这有助于跟踪备库上的槽同步何时被中断。 @@ -2825,7 +2825,9 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx 如果这是一个从主库同步而来的逻辑槽则为真。在热备上,synced 列为真的槽既不能用于逻辑解码,也不能手工删除。该列在主库上的值没有意义;主库上该列默认对所有槽都为假,但也可能(如果是由已提升的备库遗留)为真。 - + + + slotsync_skip_reasontext @@ -2839,7 +2841,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - wal_not_flushed表示备库尚未刷出与故障转移槽保留位置对应的 WAL。 + wal_not_flushed表示备库尚未将与故障切换槽保留位置对应的 WAL 刷盘。 @@ -2856,8 +2858,6 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx - - @@ -2872,7 +2872,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx 视图pg_roles提供数据库角色的信息。它本质上是 - pg_authid 的公开可读视图,并将密码字段清空。 + pg_authid 的公开可读视图,并隐藏密码字段。 @@ -2958,7 +2958,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx rolconnlimitint4 - 对于可以登录的角色,本列设置该角色可以同时发起最大连接数。-1表示无限制。 + 对于可以登录的角色,本列设置该角色能够建立的最大并发连接数。-1 表示无限制。 @@ -2976,7 +2976,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx rolvaliduntiltimestamptz - 密码过期时间(只用于密码认证),如果永不过期则为空 + 密码过期时间(仅用于密码认证);不设过期时间时为 NULL @@ -3074,7 +3074,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx definitiontext - 规则定义(创建命令的重构) + 规则定义(重建的创建命令) @@ -3160,7 +3160,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx (参考 pg_namespace.oid) - 如果适用,为此对象的命名空间 OID;否则为空。 + 如果适用,为此对象的命名空间 OID;否则为 NULL。 @@ -3467,7 +3467,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx min_valtext - 参数的最小允许值(对非数值参数为空) + 参数的最小允许值(对非数值参数为 NULL) @@ -3476,7 +3476,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx max_valtext - 参数的最大允许值(对非数值参数为空) + 参数的最大允许值(对非数值参数为 NULL) @@ -3485,7 +3485,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx enumvalstext[] - 枚举参数的允许值(对非枚举参数为空) + 枚举参数的允许值(对非枚举参数为 NULL) @@ -3673,7 +3673,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx 这个名称源于该表不应向公众开放读取,因为它包含密码。 pg_user - 是 pg_shadow 的公开可读视图,并将密码字段清空。 + 是 pg_shadow 的公开可读视图,并隐藏密码字段。
@@ -4032,7 +4032,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx null_fracfloat4 - 列项中为空的比例 + 列项中为 NULL 的比例 @@ -4060,7 +4060,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx most_common_valsanyarray - 列中高频值的一个列表(如果没有任何一个值看起来比其他值更常用,此列为空) + 列中高频值的一个列表(如果没有任何一个值看起来比其他值更常用,此列为 NULL) @@ -4069,7 +4069,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx most_common_freqsfloat4[] - 高频值的频率列表,即每一个高频值的出现次数除以总行数(如果most_common_vals为空,则此列为空) + 高频值的频率列表,即每一个高频值的出现次数除以总行数(如果most_common_vals为 NULL,则此列为 NULL) @@ -4078,7 +4078,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx histogram_boundsanyarray - 将列值划分成大小接近的组的值列表。如果存在most_common_vals,其中的值会被直方图计算所忽略(如果列类型没有一个<操作符或者most_common_vals等于整个值集合,则此列为空) + 将列值划分成大小接近的组的值列表。如果存在most_common_vals,其中的值会被直方图计算所忽略(如果列类型没有一个<操作符或者most_common_vals等于整个值集合,则此列为 NULL) @@ -4087,7 +4087,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx correlationfloat4 - 物理行顺序和列值逻辑顺序之间的统计关联。其范围从-1到+1。当值接近-1或+1时,在列上的一个索引扫描被认为比值接近0时的代价更低,因为这种情况减少了对磁盘的随机访问(如果列数据类型不具有一个<操作符,则此列为空) + 物理行顺序和列值逻辑顺序之间的统计关联。其范围从-1到+1。当值接近-1或+1时,在列上的一个索引扫描被认为比值接近0时的代价更低,因为这种情况减少了对磁盘的随机访问(如果列数据类型不具有一个<操作符,则此列为 NULL) @@ -4096,7 +4096,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx most_common_elemsanyarray - 在列值中,最经常出现的非空元素列表(对标量类型为空) + 在列值中,最经常出现的非空元素列表(对标量类型为 NULL) @@ -4106,7 +4106,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx 最常用元素值的频度列表,即含有至少一个给定值实例的行的分数。 - 在每个元素的频度之后有二至三个附加值,它们是每个元素频度的最小和最大值,以及可选的空元素的频度(如果most_common_elems为空,则此列为空) + 在每个元素的频度之后有二至三个附加值,它们是每个元素频度的最小和最大值,以及可选的空元素的频度(如果most_common_elems为 NULL,则此列为 NULL) @@ -4115,7 +4115,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx elem_count_histogramfloat4[] - 在列值中可区分非空元素值计数的一个直方图,后面跟随可区分非空元素的平均数(对于标量类型为空) + 在列值中可区分非空元素值计数的一个直方图,后面跟随可区分非空元素的平均数(对于标量类型为 NULL) @@ -4124,7 +4124,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx range_length_histogramanyarray - 范围类型列中非空且非 NULL 的范围值长度直方图。(对非范围类型为空。) + 范围类型列中非空且非 NULL 的范围值长度直方图。(非范围类型为 null。) 该直方图使用范围函数 subtype_diff 计算,而不考虑范围边界是否包含端点。 @@ -4136,7 +4136,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx range_empty_frac float4 - 列项中值为空范围的比例。(对非范围类型为空。) + 列项中值为空范围的比例。(非范围类型为 null。) @@ -4145,10 +4145,10 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx range_bounds_histogramanyarray - 非空且非 NULL 的范围值下界和上界的直方图。(对非范围类型为空。) + 非空且非 NULL 的范围值下界和上界的直方图。(非范围类型为 null。) - 这两个直方图表示为单个数组列,其中下半部分表示下界的直方图,上半部分表示上界的直方图。 + 这两个直方图表示为一个范围数组,其中各范围的下界表示下界直方图,上界表示上界直方图。 @@ -4334,7 +4334,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx most_common_valstext[] - 列中值的最常见组合的列表(如果没有组合看上去比其它的更常见,则为空。) + 列中值的最常见组合的列表(如果没有组合看上去比其它的更常见,则为 NULL。) @@ -4343,7 +4343,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx most_common_val_nullsbool[] - 值最常见组合的NULL标志的列表(当most_common_vals是空值时,为空。) + 值最常见组合的NULL标志的列表(当most_common_vals为 NULL 时,为 NULL。) @@ -4352,7 +4352,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx most_common_freqsfloat8[] - 最常见组合的频率的列表,即每个出现的数量除以行的总数(当most_common_vals是空值时,为空) + 最常见组合的频率的列表,即每个出现的数量除以行的总数(当most_common_vals为 NULL 时,为 NULL) @@ -4361,7 +4361,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx most_common_base_freqsfloat8[] - 最常见组合的基本频率的列表,即每个值频率的乘积。(当most_common_vals是空值时,为空。) + 最常见组合的基本频率的列表,即每个值频率的乘积。(当most_common_vals为 NULL 时,为 NULL。) @@ -4506,7 +4506,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx null_fracfloat4 - 表达式条目为空的比例 + 表达式条目为 NULL 的比例 @@ -4534,7 +4534,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx most_common_valsanyarray - 表达式中高频值的列表(如果没有值看起来比任何其他值更常见则为空) + 表达式中高频值的列表(如果没有值看起来比任何其他值更常见则为 NULL) @@ -4543,7 +4543,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx most_common_freqsfloat4[] - 高频值的频率列表,即每一个高频值的出现次数除以总行数(如果most_common_vals为空,则此列为空) + 高频值的频率列表,即每一个高频值的出现次数除以总行数(如果most_common_vals为 NULL,则此列为 NULL) @@ -4552,7 +4552,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx histogram_boundsanyarray - 将表达式的值划分成大小接近的组的值列表。如果存在most_common_vals,其中的值会被直方图计算所忽略(如果表达式的数据类型没有一个<操作符或者most_common_vals等于整个值集合,则此列为空) + 将表达式的值划分成大小接近的组的值列表。如果存在most_common_vals,其中的值会被直方图计算所忽略(如果表达式的数据类型没有一个<操作符或者most_common_vals等于整个值集合,则此列为 NULL) @@ -4561,7 +4561,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx correlationfloat4 - 物理行顺序和表达式值逻辑顺序之间的统计关联。其范围从-1到+1。当值接近-1或+1时,在表达式上的一个索引扫描被认为比值接近0时的代价更低,因为这种情况减少了对磁盘的随机访问(如果表达式的数据类型不具有一个<操作符,则此列为空) + 物理行顺序和表达式值逻辑顺序之间的统计关联。其范围从-1到+1。当值接近-1或+1时,在表达式上的一个索引扫描被认为比值接近0时的代价更低,因为这种情况减少了对磁盘的随机访问(如果表达式的数据类型不具有一个<操作符,则此列为 NULL) @@ -4570,7 +4570,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx most_common_elemsanyarray - 与表达式的值一起最常出现的非空元素值的列表。(标量类型时为空) + 与表达式的值一起最常出现的非空元素值的列表。(标量类型时为 NULL) @@ -4580,7 +4580,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx 最常用元素值的频度列表,即含有至少一个给定值实例的行的分数。 - 在每个元素的频度之后有二至三个附加值,它们是每个元素频度的最小和最大值,以及可选的空元素的频度(如果most_common_elems为空,则此列为空) + 在每个元素的频度之后有二至三个附加值,它们是每个元素频度的最小和最大值,以及可选的空元素的频度(如果most_common_elems为 NULL,则此列为 NULL) @@ -4589,7 +4589,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx elem_count_histogramfloat4[] - 表达式值的不同非空元素值的计数的直方图,后面跟着不同非空元素的平均数量。(标量类型时为空) + 表达式值的不同非空元素值的计数的直方图,后面跟着不同非空元素的平均数量。(标量类型时为 NULL) @@ -4617,7 +4617,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx range_bounds_histogram anyarray - 非空且非 NULL 的范围值下界和上界的直方图。(对非范围类型为空。) + 非空且非 NULL 的范围值下界和上界的直方图。(对非范围类型为 NULL。) 这两个直方图表示为单个数组列,其中下半部分表示下界的直方图,上半部分表示上界的直方图。 @@ -4699,7 +4699,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx (参考 pg_tablespace.spcname) - 包含该表的表空间名称(如果使用数据库的默认表空间,此列为空) + 包含该表的表空间名称(如果使用数据库的默认表空间,此列为 NULL) @@ -4896,7 +4896,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx 视图pg_user提供数据库用户的信息。它本质上是 - pg_shadow 的公开可读视图,并将密码字段清空。 + pg_shadow 的公开可读视图,并隐藏密码字段。
@@ -5174,7 +5174,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx definitiontext - 视图定义(一个重构的查询) + 视图定义(一个重建的查询) diff --git a/zh/20/textsearch.sgml b/zh/20/textsearch.sgml index efaefa7c..93284080 100644 --- a/zh/20/textsearch.sgml +++ b/zh/20/textsearch.sgml @@ -2099,7 +2099,7 @@ ALTER TEXT SEARCH CONFIGURATION russian 分类词典示例 - 考虑简单的天文词库 thesaurus_astro,其中包含一些天文单词组合: + 考虑简单的天文词库 thesaurus_astro,其中包含一些天文单词组合: supernovae stars : sn @@ -2583,7 +2583,7 @@ ts_debug( config re - 以下是一个简单的示例: + 以下是一个简单的示例: SELECT * FROM ts_debug('english', 'a fat cat sat on a mat - it ate a fat rats'); diff --git a/zh/20/trigger.sgml b/zh/20/trigger.sgml index db88b051..d36feb55 100644 --- a/zh/20/trigger.sgml +++ b/zh/20/trigger.sgml @@ -4,7 +4,7 @@ 触发器 - trigger + 触发器 @@ -125,7 +125,7 @@ - 在执行 MERGE 命令时,对于该命令动作中指定的事件,无论该动作最终是否实际执行,语句级 + 在执行 MERGE 命令时,对于 MERGE 命令的动作中指定的事件,无论该动作最终是否实际执行,语句级 BEFOREAFTER 触发器都会触发。这与更新零行的 UPDATE 语句相同:尽管没有行被更新,语句级触发器仍会触发。只有在某行确实被更新、插入或删除时,行级触发器才会触发。因此,完全可能出现这样的情况:某类动作的语句级触发器已经触发,而同类动作的行级触发器却一个也没有触发。 @@ -174,8 +174,7 @@ 生成列还有一些额外注意事项。 - generated columnin - triggers + 生成列在触发器中 存储型生成列会在 BEFORE 触发器之后、AFTER 触发器之前计算。因此,可以在 AFTER 触发器中检查生成值。在 BEFORE 触发器中,OLD 行如预期那样包含旧的 @@ -186,7 +185,7 @@ - 如果在同一关系上的同一事件为其定义了多个触发器,它们会按触发器名称的字母顺序触发。对于 BEFOREINSTEAD OF + 如果为同一关系上的同一事件定义了多个触发器,它们会按触发器名称的字母顺序触发。对于 BEFOREINSTEAD OF 触发器,每个触发器返回的、可能已经被修改过的行都会成为下一个触发器的输入。如果任何一个 BEFOREINSTEAD OF 触发器返回 NULL,则会放弃对该行执行该操作,并且后续触发器(针对该行)都不会再触发。 @@ -196,7 +195,7 @@ 条件,不过这个特性对它们用处不大。)在 BEFORE 触发器中, WHEN 条件就在函数即将执行或本会执行之前求值,因此使用 WHEN 与在触发器函数开头测试同样的条件并无实质差别。不过,在 - AFTER 触发器中,WHEN 条件会在行更改发生后立即求值,并决定是否要在语句末尾将一个事件排入队列以触发该触发器。因此,当 AFTER 触发器的 WHEN + AFTER 触发器中,WHEN 条件会在行更改发生后立即求值,并决定是否要将一个事件排入队列,以便在语句末尾触发该触发器。因此,当 AFTER 触发器的 WHEN 条件不返回真时,就不必排队该事件,也不必在语句末尾重新取出该行。如果触发器只需要针对少数几行触发,这会让修改大量行的语句显著加快。 INSTEAD OF 触发器不支持 WHEN 条件。 @@ -222,8 +221,8 @@ - trigger - arguments for trigger functions + 触发器 + 触发器函数的参数 在定义触发器时,可以为它指定参数。在触发器定义中包含参数,是为了让需求相似的不同触发器能够调用同一个函数。举例来说,可以有一个通用触发器函数,它接受两个列名作为参数,把当前用户写入其中一个列,把当前时间戳写入另一个列。只要编写得当,这个触发器函数就应独立于它所作用的具体表。因此,同一个函数可用于任何具有适当列的表上的 INSERT 事件,例如自动跟踪某个事务表中记录的创建。如果把它定义成 UPDATE 触发器,还可以用来跟踪最近更新事件。 @@ -306,13 +305,13 @@ 用 C 编写触发器函数 - trigger - in C + 触发器 + 在 C 中 - transition tables - referencing from C trigger + 过渡表 + 从 C 触发器中引用 @@ -324,7 +323,7 @@ - 当函数由触发器管理器调用时,不会向它传递任何普通参数,但会传递一个指向 TriggerData 结构体的 context 指针。C 函数可以通过执行下列宏来检查自己是否由触发器管理器调用: + 当函数由触发器管理器调用时,不会向它传递任何普通参数,但会传递一个指向 TriggerData 结构体的 上下文 指针。C 函数可以通过执行下列宏来检查自己是否由触发器管理器调用: CALLED_AS_TRIGGER(fcinfo) @@ -383,7 +382,7 @@ typedef struct TriggerData TRIGGER_FIRED_BEFORE(tg_event) - 如果触发器在操作之前触发,则返回 true。 + 如果触发器在操作之前触发,则返回真。 @@ -392,7 +391,7 @@ typedef struct TriggerData TRIGGER_FIRED_AFTER(tg_event) - 如果触发器在操作之后触发,则返回 true。 + 如果触发器在操作之后触发,则返回真。 @@ -401,7 +400,7 @@ typedef struct TriggerData TRIGGER_FIRED_INSTEAD(tg_event) - 如果触发器是取代该操作而触发,则返回 true。 + 如果触发器是取代该操作而触发,则返回真。 @@ -410,7 +409,7 @@ typedef struct TriggerData TRIGGER_FIRED_FOR_ROW(tg_event) - 如果触发器是因行级事件触发,则返回 true。 + 如果触发器是因行级事件触发,则返回真。 @@ -419,7 +418,7 @@ typedef struct TriggerData TRIGGER_FIRED_FOR_STATEMENT(tg_event) - 如果触发器是因语句级事件触发,则返回 true。 + 如果触发器是因语句级事件触发,则返回真。 @@ -428,7 +427,7 @@ typedef struct TriggerData TRIGGER_FIRED_BY_INSERT(tg_event) - 如果触发器是由 INSERT 命令触发,则返回 true。 + 如果触发器是由 INSERT 命令触发,则返回真。 @@ -437,7 +436,7 @@ typedef struct TriggerData TRIGGER_FIRED_BY_UPDATE(tg_event) - 如果触发器是由 UPDATE 命令触发,则返回 true。 + 如果触发器是由 UPDATE 命令触发,则返回真。 @@ -446,7 +445,7 @@ typedef struct TriggerData TRIGGER_FIRED_BY_DELETE(tg_event) - 如果触发器是由 DELETE 命令触发,则返回 true。 + 如果触发器是由 DELETE 命令触发,则返回真。 @@ -455,7 +454,7 @@ typedef struct TriggerData TRIGGER_FIRED_BY_TRUNCATE(tg_event) - 如果触发器是由 TRUNCATE 命令触发,则返回 true。 + 如果触发器是由 TRUNCATE 命令触发,则返回真。 @@ -614,16 +613,16 @@ typedef struct Trigger - 一个完整的触发器实例 + 一个完整的触发器示例 这里给出一个非常简单的、用 C 编写的触发器函数示例。(用过程语言编写的触发器示例可见各过程语言的文档。) - 如果某条命令试图向列 x 中插入空值,函数 - trigf 就会报告表 ttest - 中的行数,并跳过实际操作。(这样,这个触发器就起到了非空约束的作用,但不会中止事务。) + 函数 trigf 会报告表 ttest 中的行数, + 并在命令试图向列 x 中插入空值时跳过实际操作。 + (这样,这个触发器就起到了非空约束的作用,但不会中止事务。) diff --git a/zh/20/typeconv.sgml b/zh/20/typeconv.sgml index dd5b0f4e..761439b8 100644 --- a/zh/20/typeconv.sgml +++ b/zh/20/typeconv.sgml @@ -30,7 +30,7 @@ -PostgreSQL扫描器/解析器将词法元素分成五个基本类别:整数、非整数数字、字符串、标识符和关键字。大多数非数值类型的常量会先被归类为字符串。SQL语言定义允许用字符串指定类型名,而PostgreSQL可以利用这一机制让解析器从一开始就沿着正确的路径处理。例如,查询: +PostgreSQL扫描器/解析器将词法元素分成五个基本类别:整数、非整数数字、字符串、标识符和关键字。大多数非数值类型的常量会先被归类为字符串。SQL语言定义允许给字符串指定类型名,而PostgreSQL可以利用这一机制让解析器从一开始就沿着正确的路径处理。例如,查询: SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; @@ -41,7 +41,7 @@ SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; (1 row) -包含两个文字常量,它们的类型分别是textpoint。如果没有为某个字符串文字指定类型,那么它最初会被赋予占位类型unknown,并在后文所述的后续阶段解析。 +包含两个字面量,它们的类型分别是textpoint。如果没有为某个字符串字面量指定类型,那么它最初会被赋予占位类型unknown,并在后文所述的后续阶段解析。 @@ -166,11 +166,11 @@ SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; -检查是否存在一个恰好接受输入参数类型的操作符。如果存在(在被考虑的操作符集合中至多只有一个精确匹配),就使用它。若通过限定名调用(这种情况并不常见)某个允许不可信用户创建对象的模式中的操作符,而又缺少精确匹配,就会带来安全隐患 +检查是否存在一个恰好接受输入参数类型的操作符。如果存在(在被考虑的操作符集合中至多只有一个精确匹配),就使用它。若通过限定名调用(这种情况并不常见)某个允许不受信任的用户创建对象的模式中的操作符,而又缺少精确匹配,就会带来安全隐患 - 对于未带模式限定的名称,不会出现这种隐患,因为包含允许不可信用户创建对象的模式的搜索路径不是一种模式的安全使用方式。 + 对于未带模式限定的名称,不会出现这种隐患,因为包含允许不受信任的用户创建对象的模式的搜索路径不是一种模式的安全使用方式。 。在这种情况下,应通过对参数进行类型转换来强制获得精确匹配。 @@ -186,7 +186,7 @@ SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; -如果二元操作符调用的一个参数是unknown类型,而另一个是域类型,则接着检查是否存在两边都恰好接受该域基类型的操作符;如果有,就使用它。 +如果二元操作符调用的一个参数是unknown类型,而另一个是域类型,则接着检查是否存在两边都恰好接受该域基础类型的操作符;如果有,就使用它。 @@ -201,13 +201,13 @@ SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; -丢弃那些输入类型不匹配,且也无法通过隐式类型转换实现匹配的候选操作符。为此,假定unknown文字可以转换为任何类型。如果只剩一个候选操作符,就使用它;否则继续下一步。 +丢弃那些输入类型不匹配,且也无法通过隐式类型转换实现匹配的候选操作符。为此,假定unknown字面量可以转换为任何类型。如果只剩一个候选操作符,就使用它;否则继续下一步。 -如果任何输入参数是域类型,则在后续所有步骤中都把它当作该域的基类型。这样可以确保在解决操作符歧义时,域的行为与其基类型一致。 +如果任何输入参数是域类型,则在后续所有步骤中都把它当作该域的基础类型。这样可以确保在解决操作符歧义时,域的行为与其基础类型一致。 @@ -219,13 +219,13 @@ SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; -遍历所有候选操作符,保留那些在需要类型转换的最多位置上接受首选类型(属于输入数据类型的类型分类)的候选项。如果没有候选项接受首选类型,则保留全部候选项。如果只剩一个候选操作符,就使用它;否则继续下一步。 +遍历所有候选操作符,在需要类型转换的位置上,保留接受首选类型(属于输入数据类型的类型分类)的位置数最多的候选项。如果没有候选项接受首选类型,则保留全部候选项。如果只剩一个候选操作符,就使用它;否则继续下一步。 -如果有任何输入参数是unknown,就检查剩余候选操作符在这些参数位置上接受哪些类型分类。在每个位置上,如果有任何候选项接受string分类,就选择该分类。(这种偏向字符串的做法是合适的,因为unknown类型的文字看起来像字符串。)否则,如果所有剩余候选项都接受同一种类型分类,就选择该分类;否则失败,因为在缺少更多线索的情况下无法推断出正确选择。然后丢弃不接受所选类型分类的候选项。此外,如果有任何候选项接受该分类中的首选类型,就丢弃在该参数上接受非首选类型的候选项。如果没有候选项通过这些测试,则保留全部候选项。如果只剩一个候选操作符,就使用它;否则继续下一步。 +如果有任何输入参数是unknown,就检查剩余候选操作符在这些参数位置上接受哪些类型分类。在每个位置上,如果有任何候选项接受string分类,就选择该分类。(这种偏向字符串的做法是合适的,因为unknown类型的字面量看起来像字符串。)否则,如果所有剩余候选项都接受同一种类型分类,就选择该分类;否则失败,因为在缺少更多线索的情况下无法推断出正确选择。然后丢弃不接受所选类型分类的候选项。此外,如果有任何候选项接受该分类中的首选类型,就丢弃在该参数上接受非首选类型的候选项。如果没有候选项通过这些测试,则保留全部候选项。如果只剩一个候选操作符,就使用它;否则继续下一步。 @@ -273,7 +273,7 @@ SELECT |/ CAST(40 AS double precision) AS "square root of 40"; -一个只有一个未指定参数的例子: +一个参数未指定类型的例子: SELECT text 'abc' || 'def' AS "text and unknown"; @@ -301,7 +301,7 @@ SELECT 'abc' || 'def' AS "unspecified"; -这里对使用哪种类型没有初始提示,因为查询中没有指定任何类型。因此,解析器会查找所有候选操作符,并发现既有接受字符串分类输入的候选项,也有接受位串分类输入的候选项。由于在可用时优先选择字符串分类,所以会选中该分类,再使用字符串的首选类型text作为解析这些unknown类型文字的具体类型。 +这里对使用哪种类型没有初始提示,因为查询中没有指定任何类型。因此,解析器会查找所有候选操作符,并发现既有接受字符串分类输入的候选项,也有接受位串分类输入的候选项。由于在可用时优先选择字符串分类,所以会选中该分类,再使用字符串的首选类型text作为解析这些unknown类型字面量的具体类型。 @@ -318,7 +318,7 @@ SELECT @ '-4.5' AS "abs"; 4.5 (1 row) -这里,系统在应用所选操作符之前,已经把unknown类型文字隐式解析为float8。我们可以验证使用的确实是float8,而不是其他类型: +这里,系统在应用所选操作符之前,已经把unknown类型字面量隐式解析为float8。我们可以验证使用的确实是float8,而不是其他类型: SELECT @ '-4.5e500' AS "abs"; @@ -352,7 +352,7 @@ SELECT ~ CAST('20' AS int8) AS "negation"; 数组包含操作符类型解析 -下面是另一个解析一边已知、一边未知输入的操作符的例子: +下面是另一个解析带有一个已知类型输入和一个未知类型输入的操作符的例子: SELECT ARRAY[1, 2] <@ '{1,2,3}' AS "is subset"; @@ -361,7 +361,7 @@ SELECT ARRAY[1, 2] <@ '{1,2,3}' AS "is subset"; t (1 row) -PostgreSQL操作符目录中为中缀操作符<@定义了多个条目,但左侧能够接受整数数组的只有两种:数组包含(anyarray <@ anyarray)和范围包含(anyelement <@ anyrange)。由于这些多态伪类型(见)都不被视为首选类型,解析器无法据此消除歧义。不过,告诉它可以假定unknown类型文字与另一输入具有相同类型,也就是整数数组。这样两个操作符中只有一个能够匹配,因此会选择数组包含。(如果选中范围包含,就会报错,因为该字符串的格式并不是合法的范围文字。) +PostgreSQL操作符目录中为中缀操作符<@定义了多个条目,但左侧能够接受整数数组的只有两种:数组包含(anyarray <@ anyarray)和范围包含(anyelement <@ anyrange)。由于这些多态伪类型(见)都不被视为首选类型,解析器无法据此消除歧义。不过,要求它假定unknown类型字面量与另一输入具有相同类型,也就是整数数组。这样两个操作符中只有一个能够匹配,因此会选择数组包含。(如果选中范围包含,就会报错,因为该字符串的格式并不是合法的范围字面量。) @@ -370,7 +370,7 @@ SELECT ARRAY[1, 2] <@ '{1,2,3}' AS "is subset"; 域类型上的自定义操作符 -用户有时会尝试声明只适用于某个域类型的操作符。这是可行的,但远没有看上去那样有用,因为操作符解析规则被设计成优先选择作用于域基类型的操作符。考虑下面的例子: +用户有时会尝试声明只适用于某个域类型的操作符。这是可行的,但远没有看上去那样有用,因为操作符解析规则被设计成优先选择作用于域基础类型的操作符。考虑下面的例子: CREATE DOMAIN mytext AS text CHECK(...); CREATE FUNCTION mytext_eq_text (mytext, text) RETURNS boolean AS ...; @@ -379,11 +379,11 @@ CREATE TABLE mytable (val mytext); SELECT * FROM mytable WHERE val = 'foo'; -这个查询不会使用自定义操作符。解析器首先会检查是否存在mytext = mytext操作符(),但并不存在;然后它会考虑该域的基类型text,并检查是否存在text = text操作符(),而这是存在的;于是它会把unknown类型的文字解析为text,并使用text = text操作符。要让自定义操作符被使用,唯一的方法是显式地对该文字做类型转换: +这个查询不会使用自定义操作符。解析器首先会检查是否存在mytext = mytext操作符(),但并不存在;然后它会考虑该域的基础类型text,并检查是否存在text = text操作符(),而这是存在的;于是它会把unknown类型的字面量解析为text,并使用text = text操作符。要让自定义操作符被使用,唯一的方法是显式地对该字面量做类型转换: SELECT * FROM mytable WHERE val = text 'foo'; -这样就会根据精确匹配规则立即找到mytext = text操作符。如果解析过程进入最佳匹配规则,它们会主动排斥作用于域类型的操作符。如果不是这样,这类操作符会导致过多的操作符歧义失败,因为类型转换规则总是把域视为可以转换到其基类型或从其基类型转换而来,因此域操作符会在所有与基类型上同名操作符相同的场景中都被视为可用。 +这样就会根据精确匹配规则立即找到mytext = text操作符。如果解析过程进入最佳匹配规则,它们会主动排斥作用于域类型的操作符。如果不是这样,这类操作符会导致过多的操作符歧义失败,因为类型转换规则总是把域视为可以转换到其基础类型或从其基础类型转换而来,因此域操作符会在所有与基础类型上同名操作符相同的场景中都被视为可用。 @@ -422,27 +422,27 @@ SELECT * FROM mytable WHERE val = text 'foo'; -如果函数声明了一个VARIADIC数组参数,而调用时没有使用VARIADIC关键字,则把该函数视为其数组参数按需要被其元素类型的一个或多个出现所替换,以匹配该调用。扩展之后,该函数的有效参数类型可能与某个非VARIADIC函数完全相同。在这种情况下,使用搜索路径中较早出现的函数;如果两个函数位于同一模式,则优先选择非VARIADIC函数。 +如果函数声明了一个VARIADIC数组参数,而调用时没有使用VARIADIC关键字,则把数组参数视为一个或多个其元素类型的参数,个数按匹配该调用的需要确定。扩展之后,该函数的有效参数类型可能与某个非VARIADIC函数完全相同。在这种情况下,使用搜索路径中较早出现的函数;如果两个函数位于同一模式,则优先选择非VARIADIC函数。 -通过限定名调用某个允许不可信用户创建对象的模式中找到的可变参数函数时,会带来安全隐患 +通过限定名调用某个允许不受信任的用户创建对象的模式中找到的可变参数函数时,会带来安全隐患 - 对于未带模式限定的名称,不会出现这种隐患,因为包含允许不可信用户创建对象的模式的搜索路径不是一种模式的安全使用方式。 + 对于未带模式限定的名称,不会出现这种隐患,因为包含允许不受信任的用户创建对象的模式的搜索路径不是一种模式的安全使用方式。 - 。恶意用户可以借此劫持调用,并以你的身份执行任意 SQL 函数。改为使用带有VARIADIC关键字的调用可以绕过这一隐患。对于填充VARIADIC "any"参数的调用,往往没有包含VARIADIC关键字的等价写法。要安全地发出这类调用,该函数所在模式必须只允许可信用户创建对象。 + 。恶意用户可以借此劫持调用,并以你的身份执行任意 SQL 函数。改为使用带有VARIADIC关键字的调用可以绕过这一隐患。对于填充VARIADIC "any"参数的调用,往往没有包含VARIADIC关键字的等价写法。要安全地发出这类调用,该函数所在模式必须只允许受信任的用户创建对象。 -带有参数默认值的函数,被认为可以匹配任何省略了零个或多个可默认参数位置的调用。如果不止一个这样的函数能匹配某个调用,则使用搜索路径中最早出现的那一个。如果同一模式中存在两个或更多这样的函数,并且它们在未使用默认值的参数位置上的参数类型相同(如果它们具有不同的可默认参数集合,这种情况是可能的),系统就无法判断该偏好哪一个;如果找不到更好的匹配,就会报有歧义的函数调用错误。 +带有参数默认值的函数,被认为可以匹配任何省略了零个或多个可使用默认值的参数位置的调用。如果不止一个这样的函数能匹配某个调用,则使用搜索路径中最早出现的那一个。如果同一模式中存在两个或更多这样的函数,并且它们在未使用默认值的参数位置上的参数类型相同(如果它们具有不同的带有默认值的参数集合,这种情况是可能的),系统就无法判断该偏好哪一个;如果找不到更好的匹配,就会报有歧义的函数调用错误。 -通过限定名调用某个允许不可信用户创建对象的模式中的任意函数时,会带来可用性隐患。恶意用户可以用现有函数的名字创建一个新函数,复制该函数的参数,并附加带有默认值的新参数。这样就会阻止对原始函数的新调用。为避免这种隐患,应把函数放在只允许可信用户创建对象的模式中。 +通过限定名调用某个允许不受信任的用户创建对象的模式中的任意函数时,会带来可用性隐患。恶意用户可以用现有函数的名字创建一个新函数,复制该函数的参数,并附加带有默认值的新参数。这样就会阻止对原始函数的新调用。为避免这种隐患,应把函数放在只允许受信任的用户创建对象的模式中。 @@ -451,14 +451,14 @@ SELECT * FROM mytable WHERE val = text 'foo'; -检查是否存在一个恰好接受输入参数类型的函数。如果存在(在被考虑的函数集合中至多只有一个精确匹配),就使用它。若通过限定名调用某个允许不可信用户创建对象的模式中的函数,而又缺少精确匹配,就会带来安全隐患。在这种情况下,应通过对参数进行类型转换来强制获得精确匹配。(涉及unknown的情况在这一步永远找不到匹配。) +检查是否存在一个恰好接受输入参数类型的函数。如果存在(在被考虑的函数集合中至多只有一个精确匹配),就使用它。若通过限定名调用某个允许不受信任的用户创建对象的模式中的函数,而又缺少精确匹配,就会带来安全隐患。在这种情况下,应通过对参数进行类型转换来强制获得精确匹配。(涉及unknown的情况在这一步永远找不到匹配。) -如果没有找到精确匹配,就检查该函数调用是否看起来像一种特殊的类型转换请求。这种情况发生在:函数调用只有一个参数,且函数名与某个数据类型的(内部)名称相同。此外,函数参数必须是unknown类型文字,或者是一种能够进行二进制强制转换到该命名数据类型的类型,或者是一种可以通过应用其 I/O 函数转换为该命名数据类型的类型(也就是说,该转换要么转到某种标准字符串类型,要么从某种标准字符串类型转来)。满足这些条件时,该函数调用会被当作一种CAST形式。 +如果没有找到精确匹配,就检查该函数调用是否看起来像一种特殊的类型转换请求。这种情况发生在:函数调用只有一个参数,且函数名与某个数据类型的(内部)名称相同。此外,函数参数必须是unknown类型字面量,或者是一种可以二进制强制转换为该命名数据类型的类型,或者是一种可以通过应用其 I/O 函数转换为该命名数据类型的类型(也就是说,该转换要么转到某种标准字符串类型,要么从某种标准字符串类型转来)。满足这些条件时,该函数调用会被当作一种CAST形式。 之所以有这一步,是为了在不存在实际类型转换函数的情况下仍支持函数风格的类型转换写法。如果存在类型转换函数,按惯例它会以其输出类型命名,因此无需为此设置特殊情况。更多说明见。 @@ -475,13 +475,13 @@ SELECT * FROM mytable WHERE val = text 'foo'; -丢弃那些输入类型不匹配,且也无法通过隐式类型转换实现匹配的候选函数。为此,假定unknown文字可以转换为任何类型。如果只剩一个候选函数,就使用它;否则继续下一步。 +丢弃那些输入类型不匹配,且也无法通过隐式类型转换实现匹配的候选函数。为此,假定unknown字面量可以转换为任何类型。如果只剩一个候选函数,就使用它;否则继续下一步。 -如果任何输入参数是域类型,则在后续所有步骤中都把它当作该域的基类型。这样可以确保在解决函数歧义时,域的行为与其基类型一致。 +如果任何输入参数是域类型,则在后续所有步骤中都把它当作该域的基础类型。这样可以确保在解决函数歧义时,域的行为与其基础类型一致。 @@ -493,13 +493,13 @@ SELECT * FROM mytable WHERE val = text 'foo'; -遍历所有候选函数,保留那些在需要类型转换的最多位置上接受首选类型(属于输入数据类型的类型分类)的候选项。如果没有候选项接受首选类型,则保留全部候选项。如果只剩一个候选函数,就使用它;否则继续下一步。 +遍历所有候选函数,在需要类型转换的位置上,保留接受首选类型(属于输入数据类型的类型分类)的位置数最多的候选项。如果没有候选项接受首选类型,则保留全部候选项。如果只剩一个候选函数,就使用它;否则继续下一步。 -如果有任何输入参数是unknown,就检查剩余候选函数在这些参数位置上接受哪些类型分类。在每个位置上,如果有任何候选项接受string分类,就选择该分类。(这种偏向字符串的做法是合适的,因为unknown类型的文字看起来像字符串。)否则,如果所有剩余候选项都接受同一种类型分类,就选择该分类;否则失败,因为在缺少更多线索的情况下无法推断出正确选择。然后丢弃不接受所选类型分类的候选项。此外,如果有任何候选项接受该分类中的首选类型,就丢弃在该参数上接受非首选类型的候选项。如果没有候选项通过这些测试,则保留全部候选项。如果只剩一个候选函数,就使用它;否则继续下一步。 +如果有任何输入参数是unknown,就检查剩余候选函数在这些参数位置上接受哪些类型分类。在每个位置上,如果有任何候选项接受string分类,就选择该分类。(这种偏向字符串的做法是合适的,因为unknown类型的字面量看起来像字符串。)否则,如果所有剩余候选项都接受同一种类型分类,就选择该分类;否则失败,因为在缺少更多线索的情况下无法推断出正确选择。然后丢弃不接受所选类型分类的候选项。此外,如果有任何候选项接受该分类中的首选类型,就丢弃在该参数上接受非首选类型的候选项。如果没有候选项通过这些测试,则保留全部候选项。如果只剩一个候选函数,就使用它;否则继续下一步。 @@ -680,7 +680,7 @@ SELECT substr(CAST (1234 AS text), 3); -否则,尝试把表达式转换为目标类型。如果这两种类型之间在pg_cast目录中登记了赋值类型转换(见),就可以这样做。另一种情况是,如果表达式是unknown类型文字,则会把文字字符串的内容送入目标类型的输入转换例程。 +否则,尝试把表达式转换为目标类型。如果这两种类型之间在pg_cast目录中登记了赋值类型转换(见),就可以这样做。另一种情况是,如果表达式是unknown类型字面量,则会把字符串字面量的内容送入目标类型的输入转换例程。 @@ -713,7 +713,7 @@ SELECT v, octet_length(v) FROM vv; -这里实际发生的是,两个unknown类型文字默认都被解析为text,从而使||操作符被解析为text的连接操作。然后,操作符得到的text结果被转换为bpcharblank-padded char,即character数据类型的内部名称),以匹配目标列类型。(由于从textbpchar的转换是二进制可强制转换的,这一步不会插入任何真实的函数调用。)最后,系统目录中找到尺寸调整函数bpchar(bpchar, integer, boolean),并把它应用到操作符结果以及存储列长度上。这个特定于类型的函数会执行所需的长度检查并补齐填充空格。 +这里实际发生的是,两个unknown类型字面量默认都被解析为text,从而使||操作符被解析为text的连接操作。然后,操作符得到的text结果被转换为bpchar用空格填充的字符,blank-padded char,即character数据类型的内部名称),以匹配目标列类型。(由于从textbpchar的转换是二进制可强制转换的,这一步不会插入任何真实的函数调用。)最后,系统从系统目录中找到尺寸调整函数bpchar(bpchar, integer, boolean),并把它应用到操作符结果以及存储列长度上。这个特定于类型的函数会执行所需的长度检查并补齐填充空格。 @@ -770,10 +770,10 @@ SQL 的UNION结构必须让可能不同的类型彼此匹配 -如果任何输入是域类型,则在后续所有步骤中都把它当作该域的基类型。 +如果任何输入是域类型,则在后续所有步骤中都把它当作该域的基础类型。 - 这在某种程度上类似于操作符和函数对域输入的处理方式;只要用户确保所有输入都隐式或显式地正好属于该域类型,这种行为就能让域类型在UNION或类似结构中得以保留。否则,就会使用该域的基类型。 + 这在某种程度上类似于操作符和函数对域输入的处理方式;只要用户确保所有输入都隐式或显式地正好属于该域类型,这种行为就能让域类型在UNION或类似结构中得以保留。否则,就会使用该域的基础类型。 @@ -832,7 +832,7 @@ SELECT text 'a' AS "text" UNION SELECT 'b'; b (2 rows) -这里,unknown类型文字'b'会被解析为text类型。 +这里,unknown类型字面量'b'会被解析为text类型。 @@ -850,7 +850,7 @@ SELECT 1.2 AS "numeric" UNION SELECT 1; 1.2 (2 rows) -文字常量1.2的类型是numeric,而integer1可以隐式转换为numeric,因此使用该类型。 +字面量1.2的类型是numeric,而integer1可以隐式转换为numeric,因此使用该类型。 @@ -905,17 +905,17 @@ ERROR: UNION types text and integer cannot be matched -前面各节给出的规则会为 SQL 查询中的所有表达式分配非unknown的数据类型,唯一的例外是作为SELECT命令简单输出列出现的未指定类型文字常量。例如,在 +前面各节给出的规则会为 SQL 查询中的所有表达式分配非unknown的数据类型,唯一的例外是作为SELECT命令简单输出列出现的未指定类型字面量。例如,在 SELECT 'Hello World'; -中,没有任何信息能够表明这个字符串文字应该视为哪种类型。在这种情况下,PostgreSQL会退回到把该文字解析为text类型。 +中,没有任何信息能够表明这个字符串字面量应该视为哪种类型。在这种情况下,PostgreSQL会退回到把该字面量解析为text类型。 -当SELECTUNION(或INTERSECTEXCEPT)结构的一端,或者出现在INSERT ... SELECT中时,这条规则不适用,因为前面各节给出的规则具有更高优先级。在前一种情况下,未指定类型文字的类型可以从UNION的另一侧取得;在后一种情况下,则从目标列取得。 +当SELECTUNION(或INTERSECTEXCEPT)结构的一端,或者出现在INSERT ... SELECT中时,这条规则不适用,因为前面各节给出的规则具有更高优先级。在前一种情况下,未指定类型字面量的类型可以从UNION的另一侧取得;在后一种情况下,则从目标列取得。 @@ -925,7 +925,7 @@ SELECT 'Hello World'; - 在PostgreSQL 10 之前,这条规则并不存在,SELECT输出列表中的未指定类型文字会被保留为unknown类型。这会带来各种不良后果,因此后来做了修改。 + 在PostgreSQL 10 之前,这条规则并不存在,SELECT输出列表中的未指定类型字面量会被保留为unknown类型。这会带来各种不良后果,因此后来做了修改。 diff --git a/zh/20/user-manag.sgml b/zh/20/user-manag.sgml index 52011ada..122c7f28 100644 --- a/zh/20/user-manag.sgml +++ b/zh/20/user-manag.sgml @@ -312,12 +312,12 @@ ALTER TABLE bobs_table OWNER TO alice; - 一旦有价值的对象都已转移给新拥有者,被删除角色所拥有的其余对象即可使用DROP OWNED命令删除。同样,由于该命令不能访问其他数据库中的对象,因此必须在包含该角色所拥有对象的每个数据库中运行它。另外,DROP + 一旦有价值的对象都已转移给新拥有者,待删除角色所拥有的其余对象即可使用DROP OWNED命令删除。同样,由于该命令不能访问其他数据库中的对象,因此必须在包含该角色所拥有对象的每个数据库中运行它。另外,DROP OWNED不会删除整个数据库或表空间,因此如果该角色拥有任何尚未转移给新拥有者的数据库或表空间,就必须手工删除它们。 - DROP OWNED还会负责移除授予目标角色、但不属于它自身对象的任何权限。由于REASSIGN OWNED不会处理这类对象,所以通常需要同时运行REASSIGN OWNEDDROP OWNED(按这个顺序!),才能完整移除待删除角色的依赖关系。 + DROP OWNED还会负责移除目标角色在其他角色所拥有的对象上获授的所有权限。由于REASSIGN OWNED不会处理这类对象,所以通常需要同时运行REASSIGN OWNEDDROP OWNED(按这个顺序!),才能完整移除待删除角色的依赖关系。 @@ -356,7 +356,7 @@ GRANT pg_signal_backend TO admin_user; - 授予这些角色时应当谨慎,确保它们只在需要时使用,并理解这些角色会授予对敏感信息的访问。 + 授予这些角色时应当谨慎,确保它们只在需要时使用,并理解这些角色会授予对需要特权才能访问的信息的访问。 @@ -422,7 +422,7 @@ GRANT pg_signal_backend TO admin_user; pg_read_all_settings允许读取所有配置变量,即使是那些通常仅对超级用户可见的变量。 - pg_read_all_stats允许读取所有 pg_stat_* 视图,并使用各种与统计信息相关的扩展,即使是那些通常仅对超级用户可见的扩展。 + pg_read_all_stats允许读取所有 pg_stat_* 视图,并使用各种与统计信息相关的扩展,包括通常仅对超级用户可见的内容。 pg_stat_scan_tables允许执行可能在表上持有ACCESS SHARE锁并持续较长时间的监控函数(例如pgrowlocks(text),见扩展)。 @@ -449,7 +449,7 @@ GRANT pg_signal_backend TO admin_user; pg_execute_server_program - 这些角色旨在允许管理员创建受信任但非超级用户的角色,使其能够以数据库运行所用操作系统用户的身份访问文件并在数据库服务器上运行程序。它们在直接访问文件时会绕过所有数据库级权限检查,并且可被用来获得超级用户级别的访问能力。因此,向用户授予这些角色时必须极其谨慎。 + 这些角色旨在让管理员能够使受信任但非超级用户的角色能够以数据库运行所用操作系统用户的身份访问文件并在数据库服务器上运行程序。它们在直接访问文件时会绕过所有数据库级权限检查,并且可被用来获得超级用户级别的访问能力。因此,向用户授予这些角色时必须极其谨慎。 pg_read_server_files允许使用COPY和其他文件访问函数,从服务器上数据库可访问的任何位置读取文件。 @@ -498,7 +498,7 @@ GRANT pg_signal_backend TO admin_user; 函数安全性 - 函数、触发器和行级安全策略允许用户把代码插入后端服务器,而其他用户可能会无意中执行这些代码。因此,这些机制使用户能够相对容易地对其他用户实施特洛伊木马攻击。最强的保护方式是严格控制谁能定义对象。如果这不可行,则应编写只引用拥有者可信对象的查询,并从search_path中移除任何允许不受信任用户创建对象的模式。 + 函数、触发器和行级安全策略允许用户把代码插入后端服务器,而其他用户可能会无意中执行这些代码。因此,这些机制使用户能够相对容易地对其他用户实施特洛伊木马攻击。最强的保护方式是严格控制谁能定义对象。如果这不可行,则应编写只引用拥有者可信的对象的查询,并从search_path中移除任何允许不受信任用户创建对象的模式。 diff --git a/zh/20/vacuumlo.sgml b/zh/20/vacuumlo.sgml index 9e80b19f..cc2c04f5 100644 --- a/zh/20/vacuumlo.sgml +++ b/zh/20/vacuumlo.sgml @@ -8,7 +8,7 @@ vacuumlo 1 - Application + 应用程序 diff --git a/zh/20/wal.sgml b/zh/20/wal.sgml index b3a4b39c..33ce9fea 100644 --- a/zh/20/wal.sgml +++ b/zh/20/wal.sgml @@ -526,9 +526,9 @@ 检查点检查点 是事务序列中的一些点,在这些点上可以保证堆和索引数据文件已经用检查点之前写入 - 的全部信息进行了更新。执行检查点时,所有脏数据页都会刷写到磁盘,并向 WAL - 文件写入一条特殊的检查点记录。(更改记录此前已经刷入 WAL - 文件。)如果发生崩溃,崩溃恢复过程会查看最新的检查点记录,以确定应该从 WAL + 的全部信息进行了更新。执行检查点时,所有脏数据页都会刷盘,并向 WAL + 文件写入一条特殊的检查点记录。(更改记录此前已写入 WAL + 文件并刷盘。)如果发生崩溃,崩溃恢复过程会查看最新的检查点记录,以确定应该从 WAL 的哪个位置(称为重做记录)开始执行 REDO。该点之前对数据文件所做的任何更改 都保证已经在磁盘上。因此,检查点之后,位于包含重做记录的段之前的 WAL 段不再需要, 可以被回收或删除。(若正在执行 WAL 归档,则这些 WAL 段必 @@ -556,7 +556,7 @@ 减小 checkpoint_timeout 和/或 max_wal_size 会让检查点更频繁地发生。这样可以加快崩溃后 - 恢复,因为需要重做的工作更少。不过,这必须与更频繁刷写脏数据页所增加的成本 + 恢复,因为需要重做的工作更少。不过,这必须与更频繁地将脏数据页刷盘所增加的成本 权衡。如果设置了 (默认就是如此), 还要考虑另一个因素。为了保证数据页一致性,每个检查点之后对某个数据页的首次 修改,都会导致把整页内容写入日志。在这种情况下,更短的检查点间隔会增加输出到 @@ -583,7 +583,7 @@ I/O 速率,使检查点在给定比例的 checkpoint_timeout 秒数 经过时完成,或者在 max_wal_size 即将超出之前完成,以较早 者为准。使用默认值 0.9 时,可以预期 PostgreSQL - 会在下一次计划检查点开始前稍早完成每个检查点(大约在检查点间隔的 90% 时)。 + 会在下一次计划检查点开始前稍早完成每个检查点(耗时约为上一次检查点持续时间的 90%)。 这样能尽可能摊平 I/O,从而使检查点 I/O 负载在整个检查点间隔内保持稳定。这样 做的缺点是,延长检查点会影响恢复时间,因为需要保留更多 WAL 段以备恢复时 使用。关心恢复耗时的用户,可能希望减小 @@ -599,7 +599,7 @@ 在 Linux 和 POSIX 平台上, - 允许在检查点写出的操作系统页面达到可配置的字节数后,强制把它们刷到磁盘。 + 允许在检查点写出的操作系统页面达到可配置的字节数后,强制将它们刷盘。 否则,这些页面可能会停留在操作系统页缓存中,从而在检查点末尾发出 fsync 时引发停顿。这个设置通常有助于降低事务延迟,但也可能 对性能产生不利影响,尤其是在工作负载大于 @@ -637,7 +637,7 @@ 在归档恢复或备库模式下,服务器会周期性地执行 重启点重启点, - 其行为类似于正常运行时的检查点:服务器会强制把自身状态写盘,更新 + 其行为类似于正常运行时的检查点:服务器会强制将其所有状态刷盘,更新 pg_control 文件,以表明已经处理过的 WAL 数据无需再次 扫描,然后回收 pg_wal 目录中的旧 WAL 段文件。重启点的 执行频率不会高于主库上的检查点,因为重启点只能在检查点记录处执行。重启点既 @@ -680,7 +680,7 @@ 快。更糟的是,写 WAL 缓冲区还可能迫使系统创建新的 WAL 段, 这会花费更多时间。正常情况下,WAL 缓冲区应由 XLogFlush 请求负责写出并刷盘; - 该请求大多发生在事务提交时,以确保事务记录被刷入持久存储。在 WAL 输出量很高 + 该请求大多发生在事务提交时,以确保事务记录已刷盘至持久存储。在 WAL 输出量很高 的系统上,XLogFlush 请求可能不够频繁,无法避免 XLogInsertRecord 自己去执行写出。在这种系统上,应增加 WAL 缓冲区的数量,具体做法是修改参数 @@ -693,7 +693,7 @@ 参数 定义了组提交的领导者进程在 XLogFlush 内部获取锁之后会睡眠多少微秒,在此期间,组提 交的追随者会排队跟在领导者后面。这一延迟允许其他服务器进程把自己的提交记录添 - 加到 WAL 缓冲区中,以便它们都能由领导者最终执行的同步操作一并刷出。如果没有 + 加到 WAL 缓冲区中,以便它们都能由领导者最终执行的同步操作一并刷盘。如果没有 启用 ,或者当前处于活跃事务中的其他会话少于 个,就不会发生睡眠;这样可以避免在其他 会话不太可能很快提交时还去睡眠。请注意,在某些平台上,休眠请求的分辨率是 @@ -722,8 +722,7 @@ commit_delay 设为 0(默认值)时,仍然可能出现一种组 - 提交,但每个组只会包含那些恰好在前一次刷盘操作(若有)进行期间,到达“需要刷 - 出其提交记录”这一点的会话。客户端数量更高时,往往会出现一种 + 提交,但每个组只会包含那些恰好在前一次刷盘操作(若有)进行期间,到达“需要将其提交记录刷盘”这一点的会话。客户端数量更高时,往往会出现一种 gangway effect,以至于即使 commit_delay 为 0,组提交的效果也会变得很显著,因此显式设置 commit_delay 的帮助反而会变小。只有在以下两种条件同时 @@ -736,9 +735,9 @@ 参数 决定 PostgreSQL 将如何请求内核把 - WAL 更新强制刷到磁盘。就可靠性而言,所有选项应当都是相同 + WAL 更新强制刷盘。就可靠性而言,所有选项应当都是相同 的;例外是 fsync_writethrough,它有时能够在其他选项做不 - 到时强制刷新磁盘缓存。不过,具体哪个选项速度最快则高度依赖平台。可以使用 + 到时强制将磁盘缓存中的数据刷盘。不过,具体哪个选项速度最快则高度依赖平台。可以使用 程序测试不同选项的速度。请注意,如果 fsync 已被关闭,那么这个参数就没有意义。 diff --git a/zh/20/xaggr.sgml b/zh/20/xaggr.sgml index b46b119e..d7ef45aa 100644 --- a/zh/20/xaggr.sgml +++ b/zh/20/xaggr.sgml @@ -43,11 +43,11 @@ SELECT sum(a) FROM test_complex; - 如果没有非空输入值,上述sum定义将返回零(即初始状态值)。也许我们更希望在这种情况下返回空值 — SQL 标准要求sum这样做。实现这一点只需省略initcond短语,使初始状态值为空。通常这意味着sfunc需要检查输入的状态值是否为空。但对于sum以及maxmin这类其他简单聚合,只需把第一个非空输入值放入状态变量,然后从第二个非空输入值开始应用转移函数即可。如果初始状态值为空,并且转移函数被标记为strict(即不会对空输入调用),PostgreSQL会自动这样做。 + 如果没有非空输入值,上述sum定义将返回零(即初始状态值)。也许我们更希望在这种情况下返回空值 — SQL 标准要求sum这样做。实现这一点只需省略initcond短语,使初始状态值为空值。通常这意味着sfunc需要检查输入的状态值是否为空值。但对于sum以及maxmin这类其他简单聚合,只需把第一个非空输入值放入状态变量,然后从第二个非空输入值开始应用转移函数即可。如果初始状态值为空值,并且转移函数被标记为strict(即不会对空值输入调用),PostgreSQL会自动这样做。 - strict转移函数的另一项默认行为是,只要遇到空输入值,就会保留先前的状态值不变。因此,空值会被忽略。如果你需要对空输入采用其他行为,就不要把转移函数声明为 strict,而应在函数代码中自行检测空输入并完成所需处理。 + strict转移函数的另一项默认行为是,只要遇到空值输入,就会保留先前的状态值不变。因此,空值会被忽略。如果你需要对空值输入采用其他行为,就不要把转移函数声明为 strict,而应在函数代码中自行检测空值输入并完成所需处理。 @@ -72,7 +72,7 @@ CREATE AGGREGATE avg (float8) - SQL 中的聚合函数调用允许使用DISTINCTORDER BY选项,以控制哪些行会传递给聚合的转移函数,以及传递顺序。这些选项是在后台实现的,并不是聚合支持函数需要关心的事情。 + SQL 中的聚合函数调用允许使用DISTINCTORDER BY选项,以控制哪些行会传递给聚合的转移函数,以及传递顺序。这些选项由系统在内部实现,并不是聚合支持函数需要关心的事情。 @@ -292,7 +292,7 @@ SELECT percentile_disc(0.5) WITHIN GROUP (ORDER BY income) FROM households; - 与普通聚合不同,有序集聚合的输入行排序不是在幕后完成的,而是由聚合的支持函数负责。典型的实现方法是在聚合的状态值中保存一个tuplesort对象的引用,把输入行送入该对象,然后在最终函数中完成排序并读出数据。这样的设计使最终函数可以执行特殊操作,例如向待排序数据中注入额外的假想行。普通聚合通常可以使用由PL/pgSQL或其他 PL 语言编写的支持函数来实现,但有序集聚合通常必须用 C 编写,因为它们的状态值无法定义为任何 SQL 数据类型。(在上面的示例中,注意状态值被声明为internal类型,这很典型。)另外,由于最终函数执行了排序,之后就不可能再通过再次执行转移函数来继续加入输入行。这意味着最终函数不是READ_ONLY;在CREATE AGGREGATE中,必须将其声明为READ_WRITE,或者如果额外的最终函数调用能够利用已经排好序的状态,则声明为SHAREABLE。 + 与普通聚合不同,有序集聚合的输入行排序不是由系统在内部完成的,而是由聚合的支持函数负责。典型的实现方法是在聚合的状态值中保存一个tuplesort对象的引用,把输入行送入该对象,然后在最终函数中完成排序并读出数据。这样的设计使最终函数可以执行特殊操作,例如向待排序数据中注入额外的假想行。普通聚合通常可以使用由PL/pgSQL或其他 PL 语言编写的支持函数来实现,但有序集聚合通常必须用 C 编写,因为它们的状态值无法定义为任何 SQL 数据类型。(在上面的示例中,注意状态值被声明为internal类型,这很典型。)另外,由于最终函数执行了排序,之后就不可能再通过再次执行转移函数来继续加入输入行。这意味着最终函数不是READ_ONLY;在CREATE AGGREGATE中,必须将其声明为READ_WRITE,或者如果额外的最终函数调用能够利用已经排好序的状态,则声明为SHAREABLE @@ -366,7 +366,7 @@ if (AggCheckCallContext(fcinfo, NULL)) - AggCheckCallContext的第二个参数可用于取得保存聚合状态值的内存上下文。这对于希望把扩展对象(见)用作状态值的转移函数很有用。第一次调用时,转移函数应返回一个扩展对象,其内存上下文是聚合状态上下文的子上下文;之后的调用则持续返回同一个扩展对象。示例见array_append()。(array_append()并不是任何内置聚合的转移函数,但它的写法保证了在用作自定义聚合的转移函数时也能高效工作。) + AggCheckCallContext的第二个参数可用于取得保存聚合状态值的内存上下文。这对于希望把展开对象(见)用作状态值的转移函数很有用。第一次调用时,转移函数应返回一个展开对象,其内存上下文是聚合状态上下文的子上下文;之后的调用则持续返回同一个展开对象。示例见array_append()。(array_append()并不是任何内置聚合的转移函数,但它的写法保证了在用作自定义聚合的转移函数时也能高效工作。) diff --git a/zh/20/xfunc.sgml b/zh/20/xfunc.sgml index ad84e791..9565bf32 100644 --- a/zh/20/xfunc.sgml +++ b/zh/20/xfunc.sgml @@ -4,8 +4,8 @@ 用户定义的函数 - function - user-defined + 函数 + 用户定义的 @@ -36,15 +36,15 @@ - 每一类函数可以采用基本类型、复合类型或者它们的组合作为参数。此外,每一类函数可以返回一个基本类型或一个复合类型。函数也能被定义成返回基本类型或复合类型值的集合。 + 每一类函数可以采用基础类型、复合类型或者它们的组合作为参数。此外,每一类函数可以返回一个基础类型或一个复合类型。函数也能被定义成返回基础类型或复合类型值的集合。 - 很多类函数可以接受或者返回特定的伪类型(例如,多态类型),但是可用的功能会变化。详情可以参考每一种函数的描述。 + 很多类函数可以接受或者返回特定的伪类型(例如,多态类型),但是可用的功能因函数类别而异。详情可以参考每一种函数的描述。 - 定义SQL函数最容易,因此我们将从讨论SQL函数开始。大部分SQL函数的概念也能用到其他类型的函数上。 + 定义SQL函数最容易,因此我们将从讨论它们开始。大部分SQL函数的概念也能用到其他类型的函数上。 @@ -57,8 +57,8 @@ 用户定义的过程 - procedure - user-defined + 过程 + 用户定义的 @@ -101,7 +101,7 @@ - 函数和过程一起构成了例程routine。 + 函数和过程统称为例程例程。 有ALTER ROUTINEDROP ROUTINE这样的命令可以操作函数和过程而不需要知道它们是哪一种。 不过,要注意没有CREATE ROUTINE命令。 @@ -113,7 +113,7 @@ 函数 用户定义的 - in SQL + 在 SQL 中 @@ -139,7 +139,7 @@ DELETEMERGE),以及其他 SQL 命令。(在 SQL 函数中不能使用事务控制命令,例如 COMMITSAVEPOINT,也不能使用某些 - 实用命令,例如 VACUUM。)不过,最后一条命令必须是 + 工具命令,例如 VACUUM。)不过,最后一条命令必须是 SELECT,或者带有 RETURNING 子句,并返回与函数声明返回类型相符的结果。或者,如果你想定义一个执行动作 但没有有用返回值的 SQL 函数,也可以把它定义为返回 void。 @@ -171,7 +171,7 @@ CREATE PROCEDURE clean_emp() AS ' CALL clean_emp(); - 在像这样的简单情况中,函数与过程返回void的差异主要是风格上面的。 + 在像这样的简单情况中,返回void的函数与过程之间的差异主要是风格上面的。 不过,过程还提供了函数所没有的额外能力,例如事务控制。 此外,过程是 SQL 标准的一部分,而返回void则是 PostgreSQL 扩展。 @@ -226,10 +226,10 @@ INSERT INTO $1 VALUES (42); - 基本类型上的<acronym>SQL</acronym>函数 + 基础类型上的<acronym>SQL</acronym>函数 - 最简单的 SQL 函数没有参数,只是返回一个基本类型,例如 + 最简单的 SQL 函数没有参数,只是返回一个基础类型,例如 integer @@ -255,7 +255,7 @@ SELECT one(); - 定义接受基本类型参数的 SQL 函数也几乎同样容易: + 定义接受基础类型参数的 SQL 函数也几乎同样容易: CREATE FUNCTION add_em(x integer, y integer) RETURNS integer AS $$ @@ -393,17 +393,17 @@ SELECT name, double_salary(emp.*) AS dream 注意这里用 $1.salary 语法来选取参数行值中的一个字段。 还要注意,调用时的 SELECT 命令使用 - table_name.* 将表的当前整行取作一个组合值。该表行也可以仅用表名来引用: + table_name.* 将表的当前整行取作一个复合值。该表行也可以仅用表名来引用: SELECT name, double_salary(emp) AS dream FROM emp WHERE emp.cubicle ~= point '(2,1)'; - 但这种用法已被废弃,因为它很容易让人混淆(关于表行组合值这两种记法的更多细节,见)。 + 但这种用法已被弃用,因为它很容易让人混淆(关于表行复合值这两种记法的更多细节,见)。 - 有时候即时构造一个组合参数会很方便。这可以用ROW构造器完成。 + 有时候即时构造一个复合参数值会很方便。这可以用ROW构造器完成。 例如,我们可以调整被传递给函数的数据: SELECT name, double_salary(ROW(name, salary*1.1, age, cubicle)) AS dream @@ -432,7 +432,7 @@ $$ LANGUAGE SQL; - 查询中的选择列表顺序必须与列在复合类型中出现的顺序完全相同。(正如我们上面所做的那样,命名列与系统无关。) + 查询中的选择列表顺序必须与列在复合类型中出现的顺序完全相同。(系统不考虑像上面这样指定的列名。) @@ -444,7 +444,7 @@ ERROR: return type mismatch in function declared to return emp DETAIL: Final statement returns text instead of point at column 4. - 与基本类型的情况一样,系统不会自动插入显式转换,只会插入隐式或赋值转换。 + 与基础类型的情况一样,系统不会自动插入显式转换,只会插入隐式或赋值转换。 @@ -461,7 +461,7 @@ $$ LANGUAGE SQL; 这里我们写了一个只返回单列、且该列具有正确复合类型的 SELECT。 在这种场景下,这样写并不见得更好,但在某些情况下会很方便 - — 例如,需要通过调用另一个返回目标组合值的函数来计算结果时。 + — 例如,需要通过调用另一个返回目标复合值的函数来计算结果时。 还有一种情况是,如果我们要编写的函数返回的是基于复合类型的域,而不是普通复合类型, 那么就必须写成返回单列的形式,因为没有办法让整行结果发生所需的强制转换。 @@ -526,7 +526,7 @@ SELECT name(new_emp()); - 另一种使用函数返回复合类型的方法是将结果传递给另一个接受正确行类型作为输入的函数: + 另一种使用函数返回复合类型的方法是将结果传递给另一个接受正确行类型作为输入的函数: CREATE FUNCTION getname(emp) RETURNS text AS $$ @@ -614,7 +614,7 @@ DROP FUNCTION sum_n_product (int, int); <acronym>SQL</acronym>有输出参数的过程 - procedures + 过程 输出参数 @@ -636,7 +636,7 @@ $$ LANGUAGE SQL; CALL tp1(17, 100.0, NULL); 如果你写的是其他内容,它必须是一个能够像输入参数那样被隐式强制转换成该参数声明类型的表达式。 - 注意,无论如何这样的表达式不会被评估。 + 不过要注意,这样的表达式不会被求值。 @@ -648,12 +648,12 @@ CALL tp1(17, 100.0, NULL); 带有可变数量参数的<acronym>SQL</acronym>函数 - function - variadic + 函数 + 可变参数 - variadic function + 可变参数函数 @@ -684,27 +684,27 @@ SELECT mleast(ARRAY[10, -1, 5, 4.4]); -- doesn't work - 有时候,能够把一个已经构造好的数组传给 variadic 函数会很有用,尤其是当一个 variadic 函数想把它的数组参数再传给另一个函数时。此外,在允许不受信任用户创建对象的模式中调用 variadic 函数时,这是唯一安全的方式,见。你可以在调用中指定VARIADIC来做到这一点: + 有时候,能够把一个已经构造好的数组传给可变参数函数会很有用,尤其是当一个可变参数函数想把它的数组参数再传给另一个函数时。此外,在允许不受信任用户创建对象的模式中调用可变参数函数时,这是唯一安全的方式,见。你可以在调用中指定VARIADIC来做到这一点: SELECT mleast(VARIADIC ARRAY[10, -1, 5, 4.4]); - 这样会阻止函数的 variadic 参数按其元素类型展开,从而让数组实参能够按常规方式匹配。VARIADIC 只能附加在函数调用的最后一个实参上。 + 这样会阻止函数的可变参数按其元素类型展开,从而让数组实参能够按常规方式匹配。VARIADIC 只能附加在函数调用的最后一个实参上。 - 在调用中指定VARIADIC也是向 variadic 函数传递空数组的唯一方式,例如: + 在调用中指定VARIADIC也是向可变参数函数传递空数组的唯一方式,例如: SELECT mleast(VARIADIC ARRAY[]::numeric[]); - 仅仅写成SELECT mleast()是行不通的,因为 variadic 参数必须匹配至少一个实参。(如果你希望允许这种调用,可以再定义一个同名且不带参数的函数mleast。) + 仅仅写成SELECT mleast()是行不通的,因为可变参数必须匹配至少一个实参。(如果你希望允许这种调用,可以再定义一个同名且不带参数的函数mleast。) - 从 variadic 参数派生出的数组元素参数会被视为没有自己的名字。这意味着除非你指定了 VARIADIC,否则不能使用命名参数来调用 variadic 函数()。例如,下面的调用是可行的: + 从可变参数派生出的数组元素参数会被视为没有自己的名字。这意味着除非你指定了 VARIADIC,否则不能使用命名参数来调用可变参数函数()。例如,下面的调用是可行的: SELECT mleast(VARIADIC arr => ARRAY[10, -1, 5, 4.4]); @@ -723,7 +723,7 @@ SELECT mleast(arr => ARRAY[10, -1, 5, 4.4]); 带有参数默认值的<acronym>SQL</acronym>函数 - function + 函数 参数的默认值 @@ -732,7 +732,7 @@ SELECT mleast(arr => ARRAY[10, -1, 5, 4.4]); 没有给出足够多的实参,就会插入默认值来弥补缺失的实参。由于参数只 能从实参列表的尾部开始被省略,在一个有默认值的参数之后的所有参数 都不得不也具有默认值(尽管使用命名参数记法可以允许放松这种限制, - 这种限制仍然会被强制以便位置参数记法能工作)。不管你是否使用它,这种能力都要求在某些用户不信任其他用户的数据中调用函数时做一些预防措施,见。 + 这种限制仍然会被强制以便位置参数记法能工作)。不管你是否使用它,这种能力都要求在某些用户不信任其他用户的数据库中调用函数时做一些预防措施,见 @@ -775,13 +775,13 @@ ERROR: function foo() does not exist 所有的 SQL 函数都可以被用在查询的FROM子句中,但是 - 对于返回复合类型的函数特别有用。如果函数被定义为返回一种基本类型, + 对于返回复合类型的函数特别有用。如果函数被定义为返回一种基础类型, 该表函数会产生一个单列表。如果该函数被定义为返回一种复合类型,该 表函数会为该复合类型的每一个属性产生一列。 - 以下是一个示例: + 以下是一个示例: CREATE TABLE foo (fooid int, foosubid int, fooname text); @@ -814,8 +814,8 @@ SELECT *, upper(fooname) FROM getfoo(1) AS t1; 返回集合的<acronym>SQL</acronym>函数 - function - with SETOF + 函数 + 使用 SETOF @@ -948,7 +948,7 @@ SELECT x, generate_series(1,5) AS g FROM tab; SELECT x, g FROM tab, LATERAL generate_series(1,5) AS g; - 这会是完全一样的,除了在这个特别的示例中,规划器会选择把g放在嵌套循环连接的外侧,因为gtab没有实际的横向依赖。那会导致一种不同的输出行顺序。选择列表中的集合返回函数总是会被计算,就好像它们在FROM子句剩余部分的嵌套循环连接的内侧一样,因此在考虑来自FROM子句的下一行之前,这些函数会运行到完成。 + 这会是完全一样的,除了在这个特别的示例中,规划器可以选择把g放在嵌套循环连接的外侧,因为gtab没有实际的横向依赖。那会导致一种不同的输出行顺序。选择列表中的集合返回函数总是会被计算,就好像它们在FROM子句剩余部分的嵌套循环连接的内侧一样,因此在考虑来自FROM子句的下一行之前,这些函数会运行到完成。 @@ -968,7 +968,7 @@ SELECT srf1(srf2(x), srf3(y)), srf4(srf5(z)) FROM tab; SELECT x, CASE WHEN x > 0 THEN generate_series(1, 5) ELSE 0 END FROM tab; - 看起来这个语句应该产生满足x > 0的输入行的五次重复,以及不满足的行的一次重复。但实际上,由于在CASE表达时被计算前,generate_series(1, 5)会被运行在一个隐式的LATERAL FROM项中,它会为每个输入行产生五次重复。为了减少混乱,这类情况会产生一个解析时错误。 + 看起来这个语句应该产生满足x > 0的输入行的五次重复,以及不满足的行的一次重复。但实际上,由于在CASE表达式被计算前,generate_series(1, 5)会被运行在一个隐式的LATERAL FROM项中,它会为每个输入行产生五次重复。为了减少混乱,这类情况会产生一个解析时错误。 @@ -984,11 +984,11 @@ SELECT x, CASE WHEN x > 0 THEN generate_series(1, 5) ELSE 0 END FROM tab; 在 PostgreSQL 10 之前,除非多个集合返回函数始终产生相同数量的行,否则把它们放在同一个选择列表中的行为并不合理。 否则,得到的输出行数会是这些集合返回函数各自产生行数的最小公倍数。 此外,嵌套的集合返回函数也不像上文所描述的那样工作;相反,一个集合返回函数至多只能有一个集合返回参数, - 并且每一层嵌套都会独立运行。再加上过去还允许条件执行(即在 CASE 等结构内部使用集合返回函数), + 并且每一组嵌套的集合返回函数都会独立运行。再加上过去还允许条件执行(即在 CASE 等结构内部使用集合返回函数), 事情就更加复杂了。 如果你要编写需要在旧版 PostgreSQL 上运行的查询,建议使用 LATERAL 语法, 因为这样在不同版本之间能够得到一致的结果。 - 如果你的查询依赖于集合返回函数的条件执行,可以把条件判断移动到自定义集合返回函数内部来修复。例如, + 如果你的查询依赖于集合返回函数的条件执行,或许可以把条件判断移动到自定义集合返回函数内部来修复。例如, SELECT x, CASE WHEN y > 0 THEN generate_series(1, z) ELSE 5 END FROM tab; @@ -1006,7 +1006,7 @@ END$$ LANGUAGE plpgsql; SELECT x, case_generate_series(y > 0, 1, z, 5) FROM tab; - 这种写法在所有版本的 PostgreSQL 中都能正常工作。 + 这种写法在所有版本的 PostgreSQL 中的行为都相同。 @@ -1015,7 +1015,7 @@ SELECT x, case_generate_series(y > 0, 1, z, 5) FROM tab; 返回<literal>TABLE</literal>的<acronym>SQL</acronym>函数 - function + 函数 RETURNS TABLE @@ -1064,10 +1064,9 @@ SELECT make_array(1, 2) AS intarray, make_array('a'::text, 'b') AS textarray; 注意类型转换'a'::text的使用是为了指定该参数的类型 - 是text。如果该参数只是一个字符串这就是必须的,因为 + 是text。如果该参数只是一个字符串字面量,这就是必须的,因为 否则它会被当作unknown类型,并且 - unknown的数组也不是一种合法的类型。如果没有改类型 - 类型转换,将得到这样的错误: + unknown的数组也不是一种合法的类型。如果没有该类型转换,将得到这样的错误: ERROR: could not determine polymorphic type because input has type unknown @@ -1138,7 +1137,7 @@ SELECT * FROM dup(22); - 多态也可以用于 variadic 函数。例如: + 多态也可以用于可变参数函数。例如: CREATE FUNCTION anyleast (VARIADIC anyarray) RETURNS anyelement AS $$ SELECT min($1[i]) FROM generate_subscripts($1, 1) g(i); @@ -1173,14 +1172,14 @@ SELECT concat_values('|', 1, 4, 2); 带有排序规则的<acronym>SQL</acronym>函数 - collation - in SQL functions + 排序规则 + 在 SQL 函数中 - 当一个 SQL 函数有一个或多个可设定排序规则的数据类型参数时,会按 - 中的说明,为每次函数调用确定一个排序规则。 - 如果能够成功确定(也就是说,参数之间不存在隐式排序规则冲突),那么所有可设定排序规则的参数都会被视为隐式带有该排序规则。 + 当一个 SQL 函数有一个或多个支持排序规则的数据类型参数时,会按 + 中的说明,根据分配给实参的排序规则,为每次函数调用确定一个排序规则。 + 如果能够成功确定(也就是说,参数之间不存在隐式排序规则冲突),那么所有支持排序规则的参数都会被视为隐式带有该排序规则。 这会影响函数中对排序规则敏感的操作的行为。例如,使用上文的 anyleast 函数时, SELECT anyleast('abc'::text, 'ABC'); @@ -1200,7 +1199,7 @@ CREATE FUNCTION anyleast (VARIADIC anyarray) RETURNS anyelement AS $$ SELECT min($1[i] COLLATE "en_US") FROM generate_subscripts($1, 1) g(i); $$ LANGUAGE SQL; - 但请注意,如果把它用于不可设定排序规则的数据类型,就会抛出错误。 + 但请注意,如果把它用于不支持排序规则的数据类型,就会抛出错误。 @@ -1209,7 +1208,7 @@ $$ LANGUAGE SQL; - 这种可设定排序规则参数的行为,可以看作是仅适用于文本数据类型的一种受限多态形式。 + 这种支持排序规则的参数的行为,可以看作是仅适用于文本数据类型的一种受限多态形式。 @@ -1218,13 +1217,13 @@ $$ LANGUAGE SQL; 函数重载 - overloading - functions + 重载 + 函数 可以用同样的 SQL 名称定义多于一个函数,只要它们的参数不同即可。 - 换句话说,函数名可以被重载。不管你是否使用它,这种能力都要求在某些用户不信任其他用户的数据中调用函数时做一些预防措施,见。当一个查询 + 换句话说,函数名可以被重载。不管你是否使用它,这种能力都要求在某些用户不信任其他用户的数据库中调用函数时采取安全预防措施,见。当一个查询 被执行时,服务器将从数据类型和所提供的参数个数来决定要调用哪个 函数。重载也可用来模拟具有可变参数个数(最大个数有限)的函数。 @@ -1251,10 +1250,10 @@ CREATE FUNCTION test(smallint, double precision) RETURNS ... - 另一类可能的冲突发生在 variadic 函数和非 variadic 函数之间。例如,可以同时创建 + 另一类可能的冲突发生在可变参数函数和非可变参数函数之间。例如,可以同时创建 foo(numeric)foo(VARIADIC numeric[])。 这时,对于只提供一个 numeric 参数的调用(例如 foo(10.1)),就不清楚该匹配哪个函数。 - 规则是:优先使用在搜索路径中出现较早的那个函数;如果两者位于同一模式中,则优先使用非 variadic 函数。 + 规则是:优先使用在搜索路径中出现较早的那个函数;如果两者位于同一模式中,则优先使用非可变参数函数。 @@ -1281,8 +1280,8 @@ CREATE FUNCTION test(int, int) RETURNS int 函数易变性分类 - volatility - functions + 易变性 + 函数 VOLATILE @@ -1304,7 +1303,7 @@ CREATE FUNCTION test(int, int) RETURNS int 一个VOLATILE函数可以做任何事情,包括修改数据库。在 使用相同的参数连续调用时,它能返回不同的结果。优化器不会对这类函 - 数的行为做任何假定。对于在每一行都需要 volatile 函数值的查询,函数都会被重新求值。 + 数的行为做任何假定。使用易变函数的查询会在需要该函数值的每一行上重新对它求值。 @@ -1352,8 +1351,7 @@ CREATE FUNCTION test(int, int) RETURNS int 在考虑先规划然后立即执行的简单交互式查询时,在STABLEIMMUTABLE分类间的区别相对较小:一个函数是在规划时只 执行一次还是在查询执行开始期间只执行一次没有太大关系。但是如果计划 - 被保存下来然后在后面被重用,区别就大了。如果在不允许过早把一个函数 - 变成规划期间的一个常数时把它标记为IMMUTABLE,会导致 + 被保存下来然后在后面被重用,区别就大了。如果把一个实际上并非不可变的函数标记为IMMUTABLE,就可能在规划期间过早将它折叠成常量,导致 在后续重用该计划时继续使用陈旧的值。在使用预备语句,或使用会缓存执行计划的函数语言(如 PL/pgSQL)时,这会带来严重问题。 @@ -1421,7 +1419,7 @@ CREATE FUNCTION test(int, int) RETURNS int 内部函数 - functioninternal + 函数内部 内部函数由 C 编写并且已经被静态链接到PostgreSQL @@ -1459,9 +1457,9 @@ CREATE FUNCTION square_root(double precision) RETURNS double precision C 语言函数 - function - user-defined - in C + 函数 + 用户定义的 + 在 C 中 @@ -1485,17 +1483,17 @@ CREATE FUNCTION square_root(double precision) RETURNS double precision - 在一个会话中第一次调用一个特定可载入对象文件中的用户定义函数时, - 动态载入器会把那个对象文件载入到内存以便该函数被调用。因此用户 + 在一个会话中第一次调用一个特定可载入目标文件中的用户定义函数时, + 动态载入器会把那个目标文件载入到内存以便该函数被调用。因此用户 定义的 C 函数的CREATE FUNCTION必须 - 为该函数指定两块信息:可载入对象文件的名称,以及要在该对象文件中 + 为该函数指定两块信息:可载入目标文件的名称,以及要在该目标文件中 调用的特定函数的 C 名称(链接符号)。如果没有显式指定 C 名称,则 它被假定为和 SQL 函数名相同。 下面的算法被用来基于CREATE FUNCTION - 命令中给定的名称来定位共享对象文件: + 命令中给定的名称来定位共享目标文件: @@ -1554,20 +1552,20 @@ CREATE FUNCTION square_root(double precision) RETURNS double precision PostgreSQL不会自动编译 C 函数。在 - 从CREATE FUNCTION命令中引用对象文件 + 从CREATE FUNCTION命令中引用目标文件 之前,它必须先被编译好。更多信息请见 - magic block + 魔数块 PG_MODULE_MAGIC - 为确保动态装载的对象文件不会被加载到不兼容的服务器中,PostgreSQL 会检查该文件是否包含内容正确的magic block。这样服务器就能检测出明显的不兼容情况,例如代码是针对另一个 PostgreSQL 主版本编译的。要加入 magic block,请在模块某一个(且只能一个)源文件中,在包含头文件 fmgr.h 之后写入: + 为确保动态装载的目标文件不会被加载到不兼容的服务器中,PostgreSQL 会检查该文件是否包含内容正确的魔数块。这样服务器就能检测出明显的不兼容情况,例如代码是针对另一个 PostgreSQL 主版本编译的。要加入魔数块,请在模块某一个(且只能一个)源文件中,在包含头文件 fmgr.h 之后写入: PG_MODULE_MAGIC; @@ -1592,9 +1590,9 @@ PG_MODULE_MAGIC_EXT( - 在第一次使用之后,动态载入对象文件会保留在内存中。在同一个会话中, + 在第一次使用之后,动态载入目标文件会保留在内存中。在同一个会话中, 后续对该文件中函数的调用只需付出一次很小的符号表查找开销。如果需要 - 强制重新载入一个对象文件(例如在重新编译之后),就需要开启一个新的会话。 + 强制重新载入一个目标文件(例如在重新编译之后),就需要开启一个新的会话。 @@ -1613,7 +1611,7 @@ PG_MODULE_MAGIC_EXT( - C 语言函数中的基本类型 + C 语言函数中的基础类型 数据类型 @@ -1622,16 +1620,16 @@ PG_MODULE_MAGIC_EXT( 要了解如何编写 C 语言函数,你需要了解 - PostgreSQL如何在内部表达基本数据类型 + PostgreSQL如何在内部表达基础类型 以及如何与函数传递它们。在内部, - PostgreSQL把基本类型视为一块内存数据块。 + PostgreSQL把基础类型视为一块内存数据块。 你为该类型定义的用户自定义函数,决定了 PostgreSQL 如何操作它。 也就是说,PostgreSQL 只负责把数据存到磁盘、再从磁盘取回, 而数据的输入、处理和输出则依赖你定义的这些函数。 - 基本类型可以有三种内部格式之一: + 基础类型可以有三种内部格式之一: @@ -1695,10 +1693,9 @@ typedef struct 最后,所有变长类型必须也以引用的方式传递。所有变长类型必须用一个 - 正好 4 字节的不透明长度域开始,该域会由SET_VARSIZE - 设置,绝不要直接设置该域!所有要被存储在该类型中的数据必须在内存 - 中接着该长度域的后面存储。长度域包含该结构体的总长度,也就是包括长 - 度域本身的尺寸。 + 正好 4 字节的不透明长度字段开始,该字段会由SET_VARSIZE + 设置,绝不要直接设置该字段!所有要被存储在该类型中的数据必须在内存 + 中接着该长度字段的后面存储。长度字段包含该结构体的总长度,也就是包括长度字段本身的尺寸。 @@ -1748,16 +1745,16 @@ memcpy(destination->data, buffer, 40); VARHDRSZsizeof(int32)一样, - 但是用宏VARHDRSZ来引用变长类型的载荷的 + 但是用宏VARHDRSZ来引用变长类型的额外开销的 尺寸被认为是比较好的风格。还有,必须 - 使用SET_VARSIZE函数来设置长度域,而不是用 + 使用SET_VARSIZE函数来设置长度字段,而不是用 简单的赋值来设置。 展示了 PostgreSQL 中许多内置 SQL 数据类型所对应的 C 类型。 - Defined In列给出了需要包含的头文件,以获取类型定义。 + 定义文件列给出了需要包含的头文件,以获取类型定义。 (实际的定义可能位于所列文件包含的其他文件中。建议用户坚持使用已定义的接口。) 请注意,在服务器代码的任何源文件中,都应该始终首先包含postgres.h, 因为它声明了很多你反正都会用到的内容,而且先包含其他头文件可能会带来可移植性问题。 @@ -1933,8 +1930,7 @@ memcpy(destination->data, buffer, 40);
- 现在我们已经复习了基本类型所有可能的结构,现在可以展示一些 - 真实函数的示例了。 + 了解了基础类型所有可能的结构后,就可以看一些实际函数示例。 @@ -1942,7 +1938,7 @@ memcpy(destination->data, buffer, 40); 版本 1 的调用约定 - 版本-1 的调用规范依赖于宏来降低传参数和结果的复杂度。版本-1 函数的 + 版本-1 的调用约定依赖于宏来降低传参数和结果的复杂度。版本-1 函数的 C 声明总是: Datum funcname(PG_FUNCTION_ARGS) @@ -1954,11 +1950,11 @@ PG_FUNCTION_INFO_V1(funcname); 必须出现在同一个源文件中(按惯例会正好写在该函数本身之前)。 这种宏调用不是internal语言函数所需要的,因为 PostgreSQL会假定所有内部函数都使用 - 版本-1 规范。不过,对于动态载入函数是必需的。 + 版本-1 调用约定。不过,对于动态载入函数是必需的。 - 在版本-1 函数中,每一个实参都使用对应于该参数数据类型的PG_GETARG_xxx()宏取得。(在非严格的函数中,需要使用PG_ARGISNULL()对参数是否为空提前做检查;见下文。)结果要用对应于返回类型的PG_RETURN_xxx()宏返回。PG_GETARG_xxx()的参数是要取得的函数参数的编号,从零开始计。PG_RETURN_xxx()的参数是实际要返回的值。 + 在版本-1 函数中,每一个实参都使用对应于该参数数据类型的PG_GETARG_xxx()宏取得。(在非严格的函数中,需要使用PG_ARGISNULL()对参数是否为空值提前做检查;见下文。)结果要用对应于返回类型的PG_RETURN_xxx()宏返回。PG_GETARG_xxx()的参数是要取得的函数参数的编号,从零开始计。PG_RETURN_xxx()的参数是实际要返回的值。 @@ -2141,11 +2137,11 @@ CREATE FUNCTION t_starts_with(text, text) RETURNS boolean - 注意我们已经把函数指定为strict,这意味着如果有任何输入值为空,系统应该自动假定得到空结果。通过这种做法,我们避免在函数代码中检查空值输入。如果不这样做,我们必须使用PG_ARGISNULL()明确地检查空值输入。 + 注意我们已经把函数指定为strict,这意味着如果有任何输入值为空值,系统应该自动假定结果为空值。通过这种做法,我们避免在函数代码中检查空值输入。如果不这样做,我们必须使用PG_ARGISNULL()明确地检查空值输入。 - 宏PG_ARGISNULL(n)允许一个函数测试是否每一个输入为空(当然,只需要在没有声明为strict的函数中这样做)。和PG_GETARG_xxx()宏一样,输入参数也是从零开始计数。注意应该在验证了一个参数不是空之后才执行PG_GETARG_xxx()。要返回一个空结果,应执行PG_RETURN_NULL(),它对严格的以及非严格的函数都有用。 + 宏PG_ARGISNULL(n)允许一个函数测试是否每一个输入为空值(当然,只需要在没有声明为strict的函数中这样做)。和PG_GETARG_xxx()宏一样,输入参数也是从零开始计数。注意应该在验证了一个参数不是空值之后才执行PG_GETARG_xxx()。要返回空值结果,应执行PG_RETURN_NULL(),它对严格的以及非严格的函数都有用。 @@ -2153,11 +2149,11 @@ CREATE FUNCTION t_starts_with(text, text) RETURNS boolean - 在版本-1接口中提供的其他选项是PG_GETARG_xxx()宏的两个变种。其中的第一种是PG_GETARG_xxx_COPY(),它确保返回的指定参数的拷贝可以被安全地写入(通常的宏有时会返回一个指向表中物理存储的值,它不能被写入。使用PG_GETARG_xxx_COPY()宏可以保证得到一个可写的结果)。第二种变种PG_GETARG_xxx_SLICE()宏有三个参数。第一个是函数参数的编号(如上文)。第二个和第三个是要被返回的段的偏移量和长度。偏移量从零开始计算,而负值的长度则表示要求返回该值的剩余部分。当大型值的存储类型为external时,这些宏提供了访问这些大型值的更有效的方法(列的存储类型可以使用ALTER TABLE tablename ALTER COLUMN colname SET STORAGE storagetype来指定。storagetypeplainexternalextended或者main)。 + 在版本-1接口中提供的其他选项是PG_GETARG_xxx()宏的两个变种。其中的第一种是PG_GETARG_xxx_COPY(),它确保返回的指定参数的拷贝可以被安全地写入(通常的宏有时会返回一个指向表中物理存储值的指针,不能写入该值。使用PG_GETARG_xxx_COPY()宏可以保证得到一个可写的结果)。第二种变种PG_GETARG_xxx_SLICE()宏有三个参数。第一个是函数参数的编号(如上文)。第二个和第三个是要被返回的段的偏移量和长度。偏移量从零开始计算,而负值的长度则表示要求返回该值的剩余部分。当大型值的存储类型为external时,这些宏提供了访问这些大型值的部分内容的更有效方法(列的存储类型可以使用ALTER TABLE tablename ALTER COLUMN colname SET STORAGE storagetype来指定。storagetypeplainexternalextended或者main)。 - 最后,版本-1 的函数调用规范可以返回集合结果()、实现触发器函数()和过程语言调用处理器()。更多细节 + 最后,版本-1 的函数调用约定可以返回集合结果()、实现触发器函数()和过程语言调用处理器()。更多细节 可见源代码发布中的src/backend/utils/fmgr/README @@ -2168,10 +2164,10 @@ CREATE FUNCTION t_starts_with(text, text) RETURNS boolean 在开始更高级的话题之前,我们应该讨论一下用于 PostgreSQL C 语言函数的编码规则。 - 虽然可以把不是 C 编写的函数载入到 - PostgreSQL中,这通常是很困难的, + 虽然有可能把不是 C 编写的函数载入到 + PostgreSQL中,但即使能够做到,通常也很困难, 因为其他语言(例如 C++、FORTRAN 或者 Pascal)通常不会遵循和 C - 相同的调用规范。也就是说,其他语言不会以同样的方式在函数之间传递 + 相同的调用约定。也就是说,其他语言不会以同样的方式在函数之间传递 参数以及返回值。由于这个原因,我们会假定你的 C 语言函数确实是用 C 编写的。 @@ -2183,7 +2179,7 @@ CREATE FUNCTION t_starts_with(text, text) RETURNS boolean 使用 pg_config - --includedir-serverpg_configwith user-defined C functions + --includedir-serverpg_config用于用户定义的 C 函数 查出 PostgreSQL 服务器头文件在你的系统上(或你的用户将要运行的系统上)安装于何处。 @@ -2196,7 +2192,7 @@ CREATE FUNCTION t_starts_with(text, text) RETURNS boolean - 记得按照中的说明,为你的共享库定义一个magic block。 + 记得按照中的说明,为你的共享库定义一个魔数块 @@ -2222,7 +2218,7 @@ CREATE FUNCTION t_starts_with(text, text) RETURNS boolean - 对象文件中定义的符号名不能彼此冲突,也不能与 + 目标文件中定义的符号名不能彼此冲突,也不能与 PostgreSQL 服务器可执行文件中定义的符号冲突。如果你收到这类错误消息,就必须重命名相关函数或变量。 @@ -2305,7 +2301,7 @@ CREATE FUNCTION t_starts_with(text, text) RETURNS boolean - 但请注意,服务器中有很多部分并不是作为公开可消费的 API 来设计和维护的(而且在大多数情况下,其真实边界也并不清晰)。如果这些部分出现紧急需求,对它们的修改自然会比对那些边界清楚且广泛使用的接口做修改时,更少考虑扩展代码的兼容性。 + 但请注意,服务器中有很多部分并不是作为可公开使用的 API 来设计和维护的(而且在大多数情况下,其真实边界也并不清晰)。如果这些部分出现紧急需求,对它们的修改自然会比对那些边界清楚且广泛使用的接口做修改时,更少考虑扩展代码的兼容性。 @@ -2321,10 +2317,10 @@ CREATE FUNCTION t_starts_with(text, text) RETURNS boolean 复合类型没有像 C 结构体那样的固定布局。复合类型的实例可能包含 - 空值域。此外,继承层次中的复合类型可能具有和同一继承层次中 - 其他成员不同的域。因此, + 空值字段。此外,继承层次中的复合类型可能具有和同一继承层次中 + 其他成员不同的字段。因此, PostgreSQL提供了函数接口 - 来访问 C 的复合类型的域。 + 以便从 C 访问复合类型的字段。 @@ -2336,7 +2332,7 @@ SELECT name, c_overpaid(emp, 1500) AS overpaid WHERE name = 'Bill' OR name = 'Sam'; - 如果使用版本-1的调用规范,我们可以定义 + 如果使用版本-1的调用约定,我们可以定义 c_overpaid为: 也有GetAttributeByNum函数,它可以用目标属性 - 的属性号而不是属性名来选择目标属性。 + 的列号而不是属性名来选择目标属性。 @@ -2395,14 +2391,14 @@ CREATE FUNCTION c_overpaid(emp, integer) RETURNS boolean 要从 C 语言函数中返回一行或一个复合类型值,可以使用一套特殊的 API, - 它通过一组宏和函数隐藏了构造组合数据类型时的大部分复杂性。要使用这套 API,源文件中必须包含: + 它通过一组宏和函数隐藏了构造复合数据类型时的大部分复杂性。要使用这套 API,源文件中必须包含: #include "funcapi.h" - 构造组合数据值(下文简称元组)有两种方式: + 构造复合数据值(下文简称元组)有两种方式: 一种是从 Datum 值数组构造,另一种是从 C 字符串数组构造,这些字符串会传给该元组各列数据类型的输入转换函数。 无论采用哪种方式,首先都需要获取或构造描述该元组结构的 TupleDesc。 处理 Datum 时,需要把 TupleDesc 传给 BlessTupleDesc,然后为每一行调用 heap_form_tuple。 @@ -2411,13 +2407,13 @@ CREATE FUNCTION c_overpaid(emp, integer) RETURNS boolean - 有一些辅助函数可以用来设置所需的 TupleDesc。在大多数返回组合值的函数中,推荐的做法是调用: + 有一些辅助函数可以用来设置所需的 TupleDesc。在大多数返回复合值的函数中,推荐的做法是调用: TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc) - 传入与调用函数本身相同的 fcinfo 结构体(这当然要求使用版本 1 调用约定)。 + 传入调用函数本身收到的同一个 fcinfo 结构体(这当然要求使用版本 1 调用约定)。 resultTypeId 可以指定为 NULL,也可以指定为一个本地变量的地址,用于接收函数结果类型的 OID。 resultTupleDesc 应当是一个本地 TupleDesc 变量的地址。 检查返回结果是否为 TYPEFUNC_COMPOSITE;如果是,resultTupleDesc 就会被填入所需的 TupleDesc。 @@ -2436,7 +2432,7 @@ TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, get_call_result_type有一个兄弟 get_expr_result_type,它被用来解析被表示为一棵表达式 - 树的函数调用的输出类型。在尝试确定来自函数外部的结果类型时可以用它。 + 树的函数调用的输出类型。在尝试从函数自身外部确定结果类型时可以用它。 也有一个get_func_result_type,当只有函数的 OID 可用时 可以用它。不过这些函数无法处理被声明为返回record的 函数,并且get_func_result_type无法解析多态类型,因此你 @@ -2445,22 +2441,22 @@ TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, - 更早、现在已被废弃的获取TupleDesc的函数有: + 更早、现在已被弃用的获取TupleDesc的函数有: TupleDesc RelationNameGetTupleDesc(const char *relname) - 它可以为一个提到的关系的行类型得到TupleDesc, + 它可以为一个指定名称的关系的行类型得到TupleDesc, 还有: TupleDesc TypeGetTupleDesc(Oid typeoid, List *colaliases) 可以基于一个类型 OID 得到TupleDesc。这可以被用来 - 为一种基础或者复合类型获得TupleDesc。不过,对于 + 为一种基本或者复合类型获得TupleDesc。不过,对于 返回record的函数它不起作用,并且它无法解析多态类型。 - 一旦有了一个TupleDesc,如果计划处理 Datum可以调用: + 一旦有了一个TupleDesc,如果计划处理 Datum,可以调用: TupleDesc BlessTupleDesc(TupleDesc tupdesc) @@ -2470,7 +2466,7 @@ AttInMetadata *TupleDescGetAttInMetadata(TupleDesc tupdesc) 如果正在编写一个返回集合的函数,你可以把这些函数的结果保存在 FuncCallContext结构体中 — 分别使用 - tuple_desc或者attinmeta域。 + tuple_desc或者attinmeta字段。 @@ -2490,8 +2486,7 @@ HeapTuple BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values) values是一个 C 字符串数组,每一个元素是返回行 的一个属性。每一个 C 字符串应该是该属性数据类型的输入函数所期望 的格式。为了对一个属性返回空值,values数组中对 - 应的指针应该被设置为NULL。对于你返回的每一行都将 - 再次调用这个函数。 + 应的指针应该被设置为NULL。对于你返回的每一行都需要再次调用这个函数。 @@ -2526,13 +2521,13 @@ HeapTupleGetDatum(HeapTuple tuple) 使用 ValuePerCall 模式时,重要的是要记住查询不能保证运行完成; 也就是说,由于诸如LIMIT之类的选项, - 执行程序可能会在获取所有行之前停止调用 set-returning 函数。 + 执行器可能会在获取所有行之前停止调用集合返回函数。 这意味着在最后一次调用中执行清理活动是不安全的,因为这可能永远不会发生。 对于需要访问外部资源(例如文件描述符)的函数,建议使用 Materialize 模式。 - 本节的其余部分记录了一组使用 ValuePerCall 模式的 SRF 常用(尽管不是必须使用)的帮助程序宏。 + 本节的其余部分记录了一组使用 ValuePerCall 模式的 SRF 常用(尽管不是必须使用)的辅助宏。 有关 Materialize 模式的其他详细信息可以在src/backend/utils/fmgr/README中找到。 此外,PostgreSQL源代码分发中的contrib 模块包含许多使用 ValuePerCall 和 Materialize 模式的 SRF 示例。 @@ -2541,7 +2536,7 @@ HeapTupleGetDatum(HeapTuple tuple) 要使用此处描述的 ValuePerCall 支持宏,请包含funcapi.h。 这些宏与结构体FuncCallContext一起使用,该结构体包含需要跨调用保存的状态。 - 在调用 SRF 中,fcinfo->flinfo->fn_extra用于在调用之间保存 + 在使用这些宏的 SRF 中,fcinfo->flinfo->fn_extra用于在调用之间保存 指向FuncCallContext的指针。 宏在第一次使用时自动填充该字段,并期望在后续使用中找到相同的指针。 @@ -2574,7 +2569,7 @@ typedef struct FuncCallContext /* * 可选:指向包含属性类型输入元数据的结构的指针 * - * attinmeta 被用在返回元组(即组合数据类型)时,在返回基本数据类型 + * attinmeta 被用在返回元组(即复合数据类型)时,在返回基础类型 * 时不会使用。只有想用BuildTupleFromCStrings()创建返回元组时才需要它。 */ AttInMetadata *attinmeta; @@ -2591,7 +2586,7 @@ typedef struct FuncCallContext /* * 可选:指向包含元组描述的结构的指针 * - * tuple_desc 被用在返回元组(即组合数据类型)时,并且只有在用 + * tuple_desc 被用在返回元组(即复合数据类型)时,并且只有在用 * heap_form_tuple() 而不是 BuildTupleFromCStrings() 构建元组时才需要它。 * 注意这里存储的 TupleDesc 指针通常已经被先运行过 BlessTupleDesc()。 */ @@ -2695,7 +2690,7 @@ my_set_returning_function(PG_FUNCTION_ARGS) else { /* 这里已经完成了项的返回,所以只报告事实。 */ - /* (不要将清理代码放在这里的。) */ + /* (不要将清理代码放在这里。) */ SRF_RETURN_DONE(funcctx); } } @@ -2775,7 +2770,7 @@ retcomposite(PG_FUNCTION_ARGS) /* 构建一个元组 */ tuple = BuildTupleFromCStrings(attinmeta, values); - /* 将元组转换为数据 */ + /* 将元组转换为 datum */ result = HeapTupleGetDatum(tuple); /* 清理(这实际上并不是必要的) */ @@ -2831,10 +2826,10 @@ CREATE OR REPLACE FUNCTION retcomposite(IN integer, IN integer, fcinfo->flinfo访问。参数argnum则是从零 开始计。get_call_result_type也可被用作 get_fn_expr_rettype的一种替代品。还有 - get_fn_expr_variadic,它可以被用来找出 variadic 参数 + get_fn_expr_variadic,它可以被用来找出可变参数 是否已经被合并到了一个数组中。这主要用于 VARIADIC "any"函数,因为对于接收普通数组类型的 - variadic 函数来说总是会发生这类合并。 + 可变参数函数来说总是会发生这类合并。 @@ -2902,7 +2897,7 @@ CREATE FUNCTION make_array(anyelement) RETURNS anyarray 它与 anyelement 类似,但不会要求不同的 "any" 参数必须是同一种类型,也不会帮助确定函数的结果类型。 C 语言函数还可以把最后一个参数声明为 VARIADIC "any"。 这可以匹配一个或多个任意类型的实参(不必是同一种类型)。 - 这些参数不会像普通 variadic 函数那样被收集成一个数组,而是会单独传给函数。 + 这些参数不会像普通可变参数函数那样被收集成一个数组,而是会单独传给函数。 使用这种特性时,必须结合 PG_NARGS() 宏以及前面介绍的方法来确定实参的个数和类型。 此外,这种函数的用户也可能希望在函数调用中使用 VARIADIC 关键字,以便让函数把数组元素当作独立参数处理。 如果希望支持这种行为,函数本身就必须在使用 get_fn_expr_variadic 检测到实参被标记为 VARIADIC 后自行实现它。 @@ -3315,9 +3310,9 @@ extern PgStat_Kind pgstat_register_kind(PgStat_Kind kind, - 如果从 C++ 代码调用后端函数,确定 C++ 调用栈值包含传统 C 风格 + 如果从 C++ 代码调用后端函数,确定 C++ 调用栈只包含传统 C 风格 的数据结构(POD)。这是必要的,因为后端错误会 - 产生远距离的longjmp(),它无法正确的退回具有非 + 产生远距离的longjmp(),它无法正确地展开具有非 POD 对象的 C++ 调用栈。 @@ -3336,8 +3331,8 @@ extern PgStat_Kind pgstat_register_kind(PgStat_Kind kind, 函数优化信息 - optimization information - for functions + 优化信息 + 用于函数 @@ -3377,11 +3372,11 @@ supportfn(internal) returns internal - 聚合函数调用也可以在规划期间被简化。例如,已知x不为空时,可以将COUNT(x)替换为COUNT(*)。这可以通过实现SupportRequestSimplifyAggref请求类型的支持函数来完成。查询解析树中每出现一次目标聚合,就会调用该支持函数。如果它发现该调用可以被替换,就可以构建并返回一个新节点(通常是另一个聚合调用),同时保持传入的节点不变。与SupportRequestSimplify一样,支持函数有责任确保替换结果与目标聚合的正常执行等价。 + 聚合函数调用也可以在规划期间被简化。例如,已知x不为空值时,可以将COUNT(x)替换为COUNT(*)。这可以通过实现SupportRequestSimplifyAggref请求类型的支持函数来完成。查询解析树中每出现一次目标聚合,就会调用该支持函数。如果它发现该调用可以被替换,就可以构建并返回一个新节点(通常是另一个聚合调用),同时保持传入的节点不变。与SupportRequestSimplify一样,支持函数有责任确保替换结果与目标聚合的正常执行等价。 - 对于返回 boolean 的目标函数,估计使用该函数的 WHERE 子句会筛选出多少行通常很有用。这可以通过实现 SupportRequestSelectivity 请求类型的支持函数来完成。 + 对于返回 boolean 的目标函数,估计使用该函数的 WHERE 子句筛选出的行所占的比例通常很有用。这可以通过实现 SupportRequestSelectivity 请求类型的支持函数来完成。 diff --git a/zh/20/xindex.sgml b/zh/20/xindex.sgml index 425c94d8..112b38c4 100644 --- a/zh/20/xindex.sgml +++ b/zh/20/xindex.sgml @@ -4,8 +4,8 @@ 索引扩展接口 - index - for user-defined data type + 索引 + 用于用户定义的数据类型 @@ -27,7 +27,7 @@ - 索引方法的例程并不直接知道它将处理哪些数据类型。相反,一个操作符类operator class标识了索引方法在处理特定数据类型时需要使用的那组操作。之所以称为操作符类,是因为它指定的一项内容就是可与索引一起使用的 WHERE 子句操作符集合(也就是能被转换成索引扫描条件的操作符)。操作符类还可以指定索引方法内部操作所需的一些支持函数,但这些函数并不直接对应任何可与索引一起使用的 WHERE 子句操作符。 + 索引方法的例程并不直接知道它将处理哪些数据类型。相反,一个操作符类操作符类标识了索引方法在处理特定数据类型时需要使用的那组操作。之所以称为操作符类,是因为它指定的一项内容就是可与索引一起使用的 WHERE 子句操作符集合(也就是能被转换成索引扫描条件的操作符)。操作符类还可以指定索引方法内部操作所需的一些支持函数,但这些函数并不直接对应任何可与索引一起使用的 WHERE 子句操作符。 @@ -355,7 +355,7 @@ - 返回可由 C 调用的 skip 支持函数地址(可选) + 返回可由 C 调用的跳跃支持函数地址(可选) 6 @@ -385,7 +385,7 @@ - 给定一个 64 位 salt,计算一个键的 64 位哈希值;如果 salt 为 0,结果的低 32 位必须与函数 1 计算出的值一致(可选) + 给定一个 64 位盐值,计算一个键的 64 位哈希值;如果盐值为 0,结果的低 32 位必须与函数 1 计算出的值一致(可选) 2 @@ -558,7 +558,7 @@ compare - 比较两个键,并返回一个小于零、等于零或大于零的整数,以表示第一个键是小于、等于还是大于第二个键 + 比较两个键,并返回一个小于零、等于零或大于零的整数,用以表示第一个键是小于、等于还是大于第二个键 1 @@ -732,7 +732,7 @@ CREATE OPERATOR < ( restrict = scalarltsel, join = scalarltjoinsel ); - 指定正确的交换子和求反器操作符很重要,同样也要指定合适的限制选择度函数和连接选择度函数,否则优化器将无法有效地利用索引。 + 指定正确的交换子和求反器操作符很重要,同样也要指定合适的限制选择率函数和连接选择率函数,否则优化器将无法有效地利用索引。 @@ -811,7 +811,7 @@ CREATE OPERATOR CLASS complex_abs_ops - 为了满足这些需求,PostgreSQL使用操作符族operator family这一概念。一个操作符族包含一个或多个操作符类,还可以包含属于整个族、但不属于族中任何单一类的可索引操作符及其相应的支持函数。我们称这样的操作符和函数在该族中是松散的,而不是绑定在某个特定类中。通常,每个操作符类只包含单一数据类型的操作符,而跨数据类型操作符则作为操作符族中的松散成员存在。 + 为了满足这些需求,PostgreSQL使用操作符族操作符族这一概念。一个操作符族包含一个或多个操作符类,还可以包含属于整个族、但不属于族中任何单一类的可索引操作符及其相应的支持函数。我们称这样的操作符和函数在该族中是松散的,而不是绑定在某个特定类中。通常,每个操作符类只包含单一数据类型的操作符,而跨数据类型操作符则作为操作符族中的松散成员存在。 @@ -931,7 +931,7 @@ ALTER OPERATOR FAMILY integer_ops USING btree ADD - 要构建一个多数据类型的哈希操作符族,必须为该族支持的每一种数据类型创建相互兼容的哈希支持函数。这里的兼容性是指:对任意两个被该族中的等值操作符视为相等的值,这些函数都保证返回相同的哈希码,即使这两个值属于不同类型也是如此。当这些类型具有不同的物理表示时,这通常难以实现,但在某些情况下可以做到。此外,将该操作符族中一种数据类型的值通过隐式或二进制强制转换转换成该族中另一种数据类型时,不应改变所计算出的哈希值。注意,每种数据类型只有一个支持函数,而不是每个等值操作符一个。建议让操作符族保持完整,也就是说,对每一种数据类型组合都提供一个等值操作符。每个操作符类只应包含其数据类型对应的非跨数据类型等值操作符和支持函数。 + 要构建一个多数据类型的哈希操作符族,必须为该族支持的每一种数据类型创建相互兼容的哈希支持函数。这里的兼容性是指:对任意两个被该族中的等值操作符视为相等的值,这些函数都保证返回相同的哈希码,即使这两个值属于不同类型也是如此。当这些类型具有不同的物理表示时,这通常难以实现,但在某些情况下可以做到。此外,将该操作符族中一种数据类型的值通过隐式或二进制强制转换转为该族中另一种数据类型时,不得改变所计算出的哈希值。注意,每种数据类型只有一个支持函数,而不是每个等值操作符一个。建议让操作符族保持完整,也就是说,对每一种数据类型组合都提供一个等值操作符。每个操作符类只应包含其数据类型对应的非跨数据类型等值操作符和支持函数。 @@ -944,7 +944,7 @@ ALTER OPERATOR FAMILY integer_ops USING btree ADD - 在 PostgreSQL 8.3 之前,并没有操作符族这一概念,因此任何打算与索引一起使用的跨数据类型操作符都必须直接绑定到该索引的操作符类中。虽然这种做法仍然有效,但已经废弃,因为它会使索引的依赖关系过于宽泛,而且当两种数据类型都在同一操作符族中拥有操作符时,规划器能更有效地处理跨数据类型比较。 + 在 PostgreSQL 8.3 之前,并没有操作符族这一概念,因此任何打算与索引一起使用的跨数据类型操作符都必须直接绑定到该索引的操作符类中。虽然这种做法仍然有效,但已被弃用,因为它会使索引的依赖关系过于宽泛,而且当两种数据类型都在同一操作符族中拥有操作符时,规划器能更有效地处理跨数据类型比较。 @@ -953,7 +953,7 @@ ALTER OPERATOR FAMILY integer_ops USING btree ADD 系统对操作符类的依赖 - ordering operator + 排序操作符 @@ -961,7 +961,7 @@ ALTER OPERATOR FAMILY integer_ops USING btree ADD - 特别地,ORDER BYDISTINCT等 SQL 特性要求对值的比较和排序。为了在用户定义的数据类型上实现这些特性,PostgreSQL会为数据类型查找默认 B-树操作符类。这个操作符类的equals成员定义了用于GROUP BYDISTINCT的值的等值概念,而该操作符类施加的排序顺序定义了默认的ORDER BY顺序。 + 特别地,ORDER BYDISTINCT等 SQL 特性要求对值的比较和排序。为了在用户定义的数据类型上实现这些特性,PostgreSQL会为数据类型查找默认 B-树操作符类。这个操作符类的相等成员定义了用于GROUP BYDISTINCT的值的等值概念,而该操作符类施加的排序顺序定义了默认的ORDER BY顺序。 @@ -987,11 +987,11 @@ SELECT * FROM mytable ORDER BY somecol USING ~<~; - 用户定义类型的数组比较也依赖于该类型默认 B-树操作符类所定义的语义。如果没有默认 B-树操作符类,但有默认的哈希操作符类,则支持数组相等比较,但不支持顺序比较。 + 用户定义类型的数组比较也依赖于该类型默认 B-树操作符类所定义的语义。如果没有默认 B-树操作符类,但有默认的哈希操作符类,则支持数组相等比较,但不支持排序比较。 - 另一种需要更多数据类型相关知识的 SQL 特性,是窗口函数中的 RANGE offset PRECEDING/FOLLOWING 框架选项(见)。对于下面这样的查询 + 另一种需要更多数据类型相关知识的 SQL 特性,是窗口函数中的 RANGE offset PRECEDING/FOLLOWING 帧选项(见)。对于下面这样的查询 SELECT sum(x) OVER (ORDER BY x RANGE BETWEEN 5 PRECEDING AND 10 FOLLOWING) FROM mytable; @@ -1026,7 +1026,7 @@ SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10; - 搜索操作符必须返回布尔结果,而排序操作符通常返回其他类型的结果,例如表示距离的浮点数或数值。这种类型通常不同于被索引的数据类型。为了避免对不同数据类型行为作硬编码假设,在定义排序操作符时,必须指定一个 B-树操作符族,用来说明结果数据类型的排序顺序。正如上一节所述,B-树操作符族定义了 PostgreSQL 的顺序概念,因此这是一种自然的表示方式。由于点的 <-> 操作符返回 float8,因此可以在创建操作符类时这样指定它: + 搜索操作符必须返回布尔结果,而排序操作符通常返回其他类型的结果,例如用于表示距离的 float 或 numeric。这种类型通常不同于被索引的数据类型。为了避免对不同数据类型行为作硬编码假设,在定义排序操作符时,必须指定一个 B-树操作符族,用来说明结果数据类型的排序顺序。正如上一节所述,B-树操作符族定义了 PostgreSQL 的顺序概念,因此这是一种自然的表示方式。由于点的 <-> 操作符返回 float8,因此可以在创建操作符类时这样指定它: (point, point) FOR ORDER BY float_ops ]]> @@ -1039,7 +1039,7 @@ OPERATOR 15 <-> (point, point) FOR ORDER BY float_ops 操作符类的特殊特性 - 还有两个操作符类的特殊特性我们尚未讨论,主要是因为它们对最常用的索引方法并不太有用。 + 还有两个操作符类的特殊特性我们尚未讨论,主要是因为它们对最常用的索引方法没有用处。 @@ -1060,7 +1060,7 @@ CREATE OPERATOR CLASS polygon_ops STORAGE box; - 目前,只有 GiST、SP-GiST、GIN 和 BRIN 索引方法支持与列数据类型不同的 STORAGE 类型。GiST 的 compressdecompress 支持例程在使用 STORAGE 时必须处理数据类型转换。SP-GiST 同样需要 compress 支持函数在存储类型不同时完成转换;如果某个 SP-GiST 操作符类还支持取回数据,那么反向转换必须由 consistent 函数处理。在 GIN 中,STORAGE 类型标识key值的类型,它通常不同于被索引列的类型 — 例如,整数数组列上的某个操作符类,其键值可能只是整数。GIN 的 extractValueextractQuery 支持例程负责从被索引值中提取键。BRIN 与 GIN 类似:STORAGE 类型标识被存储的摘要值类型,而操作符类的支持过程负责正确解释这些摘要值。 + 目前,只有 GiST、SP-GiST、GIN 和 BRIN 索引方法支持与列数据类型不同的 STORAGE 类型。GiST 的 compressdecompress 支持例程在使用 STORAGE 时必须处理数据类型转换。SP-GiST 同样需要 compress 支持函数在存储类型不同时完成转换;如果某个 SP-GiST 操作符类还支持取回数据,那么反向转换必须由 consistent 函数处理。在 GIN 中,STORAGE 类型标识值的类型,它通常不同于被索引列的类型 — 例如,整数数组列上的某个操作符类,其键值可能只是整数。GIN 的 extractValueextractQuery 支持例程负责从被索引值中提取键。BRIN 与 GIN 类似:STORAGE 类型标识被存储的摘要值类型,而操作符类的支持函数负责正确解释这些摘要值。 diff --git a/zh/20/xml2.sgml b/zh/20/xml2.sgml index 1324ffd4..f3f40587 100644 --- a/zh/20/xml2.sgml +++ b/zh/20/xml2.sgml @@ -90,7 +90,7 @@ 对文档执行该查询,并将结果包在 XML 标签中。如果结果包含多个值,输出将类似于: <toptag> -<itemtag>Value 1 which could be an XML fragment</itemtag> +<itemtag>Value 1(可以是 XML 片段)</itemtag> <itemtag>Value 2....</itemtag> </toptag> @@ -173,7 +173,7 @@ xpath_table(text key, text document, text relation, text xpaths, text criteria) key - key 字段的名称 — 这只是一个作为输出表第一列使用的字段,也就是说,它用于标识每个输出行来自哪条记录(关于多个值,见下文注释) + 字段的名称 — 这只是一个作为输出表第一列使用的字段,也就是说,它用于标识每个输出行来自哪条记录(关于多个值,见下文注释) @@ -238,7 +238,7 @@ xpath_table('article_id', 'date_entered > ''2003-01-01'' ') AS t(article_id integer, author text, page_count integer, title text); - AS 子句定义了输出表中各列的名称和类型。第一列是 key 字段,其余各列对应 XPath 查询。如果 XPath 查询多于结果列,多出的查询将被忽略。如果结果列多于 XPath 查询,多出的列将为 NULL。 + AS 子句定义了输出表中各列的名称和类型。第一列是 字段,其余各列对应 XPath 查询。如果 XPath 查询多于结果列,多出的查询将被忽略。如果结果列多于 XPath 查询,多出的列将为 NULL。 @@ -267,7 +267,7 @@ WHERE t.author_id = p.person_id; - 在某些情况下,用户会知道某个 XPath 查询只会返回单个结果(例如唯一文档标识符)— 如果它与返回多个结果的 XPath 查询一起使用,这个单值结果只会出现在结果的第一行。解决办法是把 key 字段作为与一个更简单的 XPath 查询结果进行连接的条件之一。例如: + 在某些情况下,用户会知道某个 XPath 查询只会返回单个结果(例如唯一文档标识符)— 如果它与返回多个结果的 XPath 查询一起使用,这个单值结果只会出现在结果的第一行。解决办法是把键字段作为与一个更简单的 XPath 查询结果进行连接的条件之一。例如: CREATE TABLE test ( diff --git a/zh/20/xoper.sgml b/zh/20/xoper.sgml index a3b58216..3fe219da 100644 --- a/zh/20/xoper.sgml +++ b/zh/20/xoper.sgml @@ -164,10 +164,10 @@ SELECT (a + b) AS c FROM test_complex; <literal>RESTRICT</literal> - 如果给出 RESTRICT 子句,它指定该操作符的限制选择度估 + 如果给出 RESTRICT 子句,它指定该操作符的限制选择率估 算函数。(注意,这里是函数名,而不是操作符名。) RESTRICT 子句只对返回 boolean 的二元操 - 作符有意义。限制选择度估算器的作用,是针对当前操作符和某个特定常量值, + 作符有意义。限制选择率估算器的作用,是针对当前操作符和某个特定常量值, 猜测一张表中有多少比例的行会满足如下形式的 WHERE 子句条件: @@ -179,9 +179,9 @@ column OP constant - 编写新的限制选择度估算函数远远超出了本章的范围,不过幸运的是,对于你自 + 编写新的限制选择率估算函数远远超出了本章的范围,不过幸运的是,对于你自 己的很多操作符,通常都可以直接使用系统提供的某个标准估算器。标准的限制 - 选择度估算器如下: + 选择率估算器如下: eqsel 用于 = neqsel 用于 <> @@ -193,7 +193,7 @@ column OP constant - 对于选择度非常高或非常低的操作符,即使它们实际上并不是真正的相等或不等 + 对于选择率非常高或非常低的操作符,即使它们实际上并不是真正的相等或不等 比较,你也常常可以勉强使用 eqselneqsel。例如,几何类型中的近似相等操作符就使用 eqsel,其依据是它们通常只会匹配表中很小一部分项。 @@ -212,7 +212,7 @@ column OP constant - 另一个有用的内置选择度估算函数是 matchingsel。只要 + 另一个有用的内置选择率估算函数是 matchingsel。只要 已为输入数据类型收集了标准的 MCV 和/或直方图统计信息,它几乎就适用于任 何二元操作符。它的默认估计值被设定为 eqsel 所用默认 估计值的两倍,因此最适合那些比相等比较稍微宽松一些的比较操作符。(或者 @@ -222,7 +222,7 @@ column OP constant src/backend/utils/adt/geo_selfuncs.c 中,还为几 - 何操作符提供了其他选择度估算函数:areasel、 + 何操作符提供了其他选择率估算函数:areaselpositionselcontsel。截至 目前,这些函数都还只是桩实现,但你也许仍会想使用它们(或者更好的是,改 进它们)。 @@ -233,9 +233,9 @@ column OP constant <literal>JOIN</literal> - 如果给出 JOIN 子句,它指定该操作符的连接选择度估算函 + 如果给出 JOIN 子句,它指定该操作符的连接选择率估算函 数。(注意,这里是函数名,而不是操作符名。)JOIN 子 - 句只对返回 boolean 的二元操作符有意义。连接选择度估算器的 + 句只对返回 boolean 的二元操作符有意义。连接选择率估算器的 作用,是针对当前操作符,猜测两张表中有多少比例的行对会满足如下形式的 WHERE 子句条件: @@ -246,7 +246,7 @@ table1.column1 OP table2.column2 - 与前面一样,本章不会尝试解释如何编写连接选择度估算函数,而只是建议你在 + 与前面一样,本章不会尝试解释如何编写连接选择率估算函数,而只是建议你在 适用时使用某个标准估算器: eqjoinsel 用于 = @@ -305,7 +305,7 @@ table1.column1 OP table2.column2 一个可参与哈希连接的操作符,必须拥有一个交换子(如果两侧操作数数据类型 - 相同,则可以是它自身;如果不同,则应是相关的相等操作符),并且该交换子 + 相同,则为它自身;如果不同,则应是相关的相等操作符),并且该交换子 也必须出现在同一个操作符族中。否则,在使用该操作符时可能会发生规划器错 误。另外,对于支持多种数据类型的哈希操作符族,最好(虽然并非严格必需) 为每一种数据类型组合都提供相等操作符;这样可以获得更好的优化效果。 @@ -342,7 +342,7 @@ table1.column1 OP table2.column2 - 归并连接的基本思想,是先把左表和右表分别排序,然后并行扫描它们。因此, + 归并连接的基本思想,是先把左表和右表分别排序,然后同步扫描它们。因此, 两种数据类型都必须能够被完全排序,而连接操作符必须只能在那对值位于排序 次序中同一位置时才成功。实际效果上,这意味着连接操作符 必须表现得像相等比较一样。不过,只要两种不同的数据类型在逻辑上兼容,也 @@ -362,7 +362,7 @@ table1.column1 OP table2.column2 一个可参与归并连接的操作符,必须拥有一个交换子(如果两侧操作数数据类型 - 相同,则可以是它自身;如果不同,则应是相关的相等操作符),并且该交换子 + 相同,则为它自身;如果不同,则应是相关的相等操作符),并且该交换子 也必须出现在同一个操作符族中。否则,在使用该操作符时可能会发生规划器错 误。另外,对于支持多种数据类型的 btree 操作符族,最 好(虽然并非严格必需)为每一种数据类型组合都提供相等操作符;这样可以获 diff --git a/zh/20/xplang.sgml b/zh/20/xplang.sgml index 9075d7b6..0590ea2d 100644 --- a/zh/20/xplang.sgml +++ b/zh/20/xplang.sgml @@ -183,7 +183,7 @@ CREATE TRUSTED LANGUAGE plperl 在默认的PostgreSQL安装中, PL/pgSQL语言的调用处理器会被构建并安装到 - library目录中;此外, + 目录中;此外, PL/pgSQL语言本身也安装在所有数据库中。如 果在构建时配置了Tcl支持,那么 PL/TclPL/TclU diff --git a/zh/20/xtypes.sgml b/zh/20/xtypes.sgml index f5ee6199..7ffd6b18 100644 --- a/zh/20/xtypes.sgml +++ b/zh/20/xtypes.sgml @@ -218,7 +218,7 @@ CREATE TYPE complex ( 如果数据类型的内部表示是可变长度的,则这种内部表示必须遵循可变长度数 据的标准布局:前四个字节必须是一个从不直接访问的char[4] 字段(惯例上命名为vl_len_)。必须使用 - SET_VARSIZE()宏在该字段中存储该值的总大小(包括 + SET_VARSIZE()宏在该字段中存储该 datum 的总大小(包括 长度字段本身),并使用VARSIZE()取回它。(这些宏 之所以存在,是因为长度字段可能会随平台不同而采用编码形式。) @@ -260,7 +260,7 @@ CREATE TYPE complex ( PG_DETOAST_DATUM_PACKED(通常通过定义 GETARG_DATATYPE_PP宏来隐藏),并使用 VARSIZE_ANY_EXHDRVARDATA_ANY - 宏访问一个可能采用打包形式的值。再次注意,即使数据类型定义指定了 + 宏访问一个可能采用打包形式的 datum。再次注意,即使数据类型定义指定了 对齐方式,这些宏返回的数据也不是对齐的。如果对齐很重要,就必须使用常 规的PG_DETOAST_DATUM接口。 @@ -271,8 +271,7 @@ CREATE TYPE complex ( 较旧的代码常把vl_len_声明为 int32字段,而不是char[4]字段。只要结构体定 义中还有其他至少按int32对齐的字段,这样做是可以的。但 - 在处理可能未对齐的值时使用这种结构体定义就很危险;编译器可能据此假定该 - 值实际上是对齐的,从而在对齐要求严格的体系结构上导致核心转储。 + 在处理可能未对齐的 datum 时使用这种结构体定义就很危险;编译器可能据此假定该 datum 实际上是对齐的,从而在对齐要求严格的体系结构上导致核心转储。